From 5ff0cfa7365613146156978947076c7c79b71b4f Mon Sep 17 00:00:00 2001 From: Git User Date: Fri, 18 Aug 2017 12:27:00 -0700 Subject: [PATCH 0001/1645] Initial empty repository -- GitLab From 8e2277f79f0fa54d5dc505881025ea27ecd6be6b Mon Sep 17 00:00:00 2001 From: Asish Bhattacharya Date: Thu, 20 Jul 2017 18:31:55 +0530 Subject: [PATCH 0002/1645] audio-lnx: Initial change for techpack of audio drivers. Add snapshot for audio drivers for SDM targets. The code is migrated from msm-4.9 kernel at the below cutoff - (74ff856e8d6: "net: ipc_router: Add dynamic enable/disable wakeup source feature") This changes are done for new techpack addition for audio kernel. Migrate all audio kernel drivers to this techpack. Change-Id: I33d580af3ba86a5cb777583efc5d4cdaf2882d93 Signed-off-by: Asish Bhattacharya --- Makefile | 23 + NOTICE | 24 + drivers/Makefile | 7 + drivers/base/Makefile | 2 + drivers/base/regmap/Makefile | 2 + drivers/base/regmap/internal.h | 1 + drivers/base/regmap/regmap-swr.c | 216 + drivers/mfd/Makefile | 8 + drivers/mfd/msm-cdc-pinctrl.c | 253 + drivers/mfd/msm-cdc-supply.c | 456 + drivers/mfd/wcd9335-regmap.c | 1611 ++ drivers/mfd/wcd9335-tables.c | 1325 ++ drivers/mfd/wcd934x-regmap.c | 1957 ++ drivers/mfd/wcd934x-tables.c | 2155 +++ drivers/mfd/wcd9xxx-core-init.c | 55 + drivers/mfd/wcd9xxx-core.c | 1714 ++ drivers/mfd/wcd9xxx-irq.c | 853 + drivers/mfd/wcd9xxx-regmap.h | 68 + drivers/mfd/wcd9xxx-rst.c | 443 + drivers/mfd/wcd9xxx-slimslave.c | 584 + drivers/mfd/wcd9xxx-utils.c | 1198 ++ drivers/misc/Makefile | 5 + drivers/misc/qcom/Kconfig | 19 + drivers/misc/qcom/Makefile | 1 + drivers/misc/qcom/qdsp6v2/Makefile | 6 + drivers/misc/qcom/qdsp6v2/aac_in.c | 709 + drivers/misc/qcom/qdsp6v2/amrnb_in.c | 402 + drivers/misc/qcom/qdsp6v2/amrwb_in.c | 400 + drivers/misc/qcom/qdsp6v2/audio_aac.c | 474 + drivers/misc/qcom/qdsp6v2/audio_alac.c | 435 + drivers/misc/qcom/qdsp6v2/audio_amrnb.c | 226 + drivers/misc/qcom/qdsp6v2/audio_amrwb.c | 231 + drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c | 397 + drivers/misc/qcom/qdsp6v2/audio_ape.c | 359 + drivers/misc/qcom/qdsp6v2/audio_evrc.c | 184 + drivers/misc/qcom/qdsp6v2/audio_g711alaw.c | 396 + drivers/misc/qcom/qdsp6v2/audio_g711mlaw.c | 396 + .../misc/qcom/qdsp6v2/audio_hwacc_effects.c | 778 + drivers/misc/qcom/qdsp6v2/audio_mp3.c | 188 + drivers/misc/qcom/qdsp6v2/audio_multi_aac.c | 523 + drivers/misc/qcom/qdsp6v2/audio_qcelp.c | 191 + drivers/misc/qcom/qdsp6v2/audio_utils.c | 954 + drivers/misc/qcom/qdsp6v2/audio_utils.h | 114 + drivers/misc/qcom/qdsp6v2/audio_utils_aio.c | 2142 +++ drivers/misc/qcom/qdsp6v2/audio_utils_aio.h | 232 + drivers/misc/qcom/qdsp6v2/audio_wma.c | 345 + drivers/misc/qcom/qdsp6v2/audio_wmapro.c | 418 + drivers/misc/qcom/qdsp6v2/evrc_in.c | 410 + drivers/misc/qcom/qdsp6v2/g711alaw_in.c | 382 + drivers/misc/qcom/qdsp6v2/g711mlaw_in.c | 385 + drivers/misc/qcom/qdsp6v2/q6audio_common.h | 37 + drivers/misc/qcom/qdsp6v2/q6audio_v2.c | 106 + drivers/misc/qcom/qdsp6v2/q6audio_v2_aio.c | 223 + drivers/misc/qcom/qdsp6v2/qcelp_in.c | 410 + drivers/misc/qcom/qdsp6v2/ultrasound/Makefile | 2 + drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c | 1467 ++ drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.h | 130 + drivers/misc/qcom/qdsp6v2/ultrasound/usf.c | 2465 +++ .../misc/qcom/qdsp6v2/ultrasound/usfcdev.c | 422 + .../misc/qcom/qdsp6v2/ultrasound/usfcdev.h | 28 + drivers/pinctrl/Makefile | 2 + drivers/pinctrl/core.h | 1 + drivers/pinctrl/pinctrl-utils.h | 1 + drivers/pinctrl/qcom/Makefile | 3 + drivers/pinctrl/qcom/pinctrl-lpi.c | 647 + drivers/pinctrl/qcom/pinctrl-wcd.c | 435 + drivers/soc/Makefile | 5 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/qdsp6v2/Makefile | 8 + drivers/soc/qcom/qdsp6v2/adsp-loader.c | 316 + drivers/soc/qcom/qdsp6v2/apr.c | 976 + drivers/soc/qcom/qdsp6v2/apr_tal_glink.c | 451 + drivers/soc/qcom/qdsp6v2/apr_v2.c | 67 + drivers/soc/qcom/qdsp6v2/apr_v3.c | 65 + drivers/soc/qcom/qdsp6v2/audio_notifier.c | 636 + drivers/soc/qcom/qdsp6v2/audio_pdr.c | 147 + drivers/soc/qcom/qdsp6v2/audio_ssr.c | 66 + drivers/soc/qcom/qdsp6v2/cdsp-loader.c | 280 + drivers/soc/qcom/qdsp6v2/msm_audio_ion.c | 853 + drivers/soundwire/Kconfig | 17 + drivers/soundwire/Makefile | 5 + drivers/soundwire/soundwire.c | 1032 + drivers/soundwire/swr-wcd-ctrl.c | 1880 ++ drivers/soundwire/swr-wcd-ctrl.h | 106 + drivers/soundwire/swrm_registers.h | 204 + include/Kbuild | 2 + include/linux/avtimer_kernel.h | 24 + include/linux/mfd/msm-cdc-pinctrl.h | 49 + include/linux/mfd/msm-cdc-supply.h | 48 + include/linux/mfd/wcd9335/irq.h | 55 + include/linux/mfd/wcd9335/registers.h | 1348 ++ include/linux/mfd/wcd934x/irq.h | 56 + include/linux/mfd/wcd934x/registers.h | 1848 ++ include/linux/mfd/wcd9xxx/core.h | 440 + include/linux/mfd/wcd9xxx/pdata.h | 197 + include/linux/mfd/wcd9xxx/wcd9xxx-irq.h | 37 + include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h | 119 + include/linux/mfd/wcd9xxx/wcd9xxx-utils.h | 40 + include/linux/qdsp6v2/apr.h | 190 + include/linux/qdsp6v2/apr_tal.h | 90 + include/linux/qdsp6v2/apr_us.h | 193 + include/linux/qdsp6v2/audio_notifier.h | 105 + include/linux/qdsp6v2/audio_pdr.h | 101 + include/linux/qdsp6v2/audio_ssr.h | 78 + include/linux/qdsp6v2/dsp_debug.h | 22 + include/linux/qdsp6v2/rtac.h | 99 + include/linux/qdsp6v2/usf.h | 298 + include/linux/soundwire/soundwire.h | 312 + include/linux/soundwire/swr-wcd.h | 35 + include/sound/apr_audio-v2.h | 10683 +++++++++++ include/sound/apr_audio.h | 1931 ++ include/sound/audio_cal_utils.h | 102 + include/sound/audio_calibration.h | 41 + include/sound/cpe_cmi.h | 492 + include/sound/cpe_core.h | 179 + include/sound/cpe_err.h | 166 + include/sound/msm-audio-effects-q6-v2.h | 55 + include/sound/msm-dai-q6-v2.h | 92 + include/sound/msm-slim-dma.h | 44 + include/sound/q6adm-v2.h | 187 + include/sound/q6afe-v2.h | 371 + include/sound/q6asm-v2.h | 686 + include/sound/q6audio-v2.h | 36 + include/sound/q6core.h | 159 + include/sound/q6lsm.h | 338 + include/uapi/Kbuild | 6 + include/uapi/linux/Kbuild | 19 + include/uapi/linux/avtimer.h | 10 + include/uapi/linux/msm_audio.h | 475 + include/uapi/linux/msm_audio_aac.h | 76 + include/uapi/linux/msm_audio_ac3.h | 41 + include/uapi/linux/msm_audio_alac.h | 24 + include/uapi/linux/msm_audio_amrnb.h | 34 + include/uapi/linux/msm_audio_amrwb.h | 18 + include/uapi/linux/msm_audio_amrwbplus.h | 18 + include/uapi/linux/msm_audio_ape.h | 26 + include/uapi/linux/msm_audio_calibration.h | 719 + include/uapi/linux/msm_audio_g711.h | 17 + include/uapi/linux/msm_audio_g711_dec.h | 16 + include/uapi/linux/msm_audio_mvs.h | 155 + include/uapi/linux/msm_audio_qcp.h | 37 + include/uapi/linux/msm_audio_sbc.h | 36 + include/uapi/linux/msm_audio_voicememo.h | 66 + include/uapi/linux/msm_audio_wma.h | 33 + include/uapi/linux/msm_audio_wmapro.h | 22 + include/uapi/sound/Kbuild | 8 + include/uapi/sound/audio_effects.h | 361 + include/uapi/sound/audio_slimslave.h | 18 + include/uapi/sound/devdep_params.h | 56 + include/uapi/sound/lsm_params.h | 200 + include/uapi/sound/msmcal-hwdep.h | 23 + include/uapi/sound/voice_params.h | 14 + include/uapi/sound/wcd-dsp-glink.h | 60 + sound/Makefile | 4 + sound/soc/codecs/Makefile | 26 + sound/soc/codecs/audio-ext-clk-up.c | 626 + sound/soc/codecs/audio-ext-clk-up.h | 20 + sound/soc/codecs/audio-ext-clk.c | 348 + sound/soc/codecs/msm_stub.c | 88 + sound/soc/codecs/sdm660_cdc/Kconfig | 5 + sound/soc/codecs/sdm660_cdc/Makefile | 2 + sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c | 4683 +++++ sound/soc/codecs/sdm660_cdc/msm-analog-cdc.h | 240 + sound/soc/codecs/sdm660_cdc/msm-cdc-common.h | 67 + sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c | 2189 +++ sound/soc/codecs/sdm660_cdc/msm-digital-cdc.h | 91 + sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.c | 413 + sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.h | 34 + .../codecs/sdm660_cdc/sdm660-cdc-registers.h | 603 + sound/soc/codecs/sdm660_cdc/sdm660-regmap.c | 611 + sound/soc/codecs/wcd-dsp-mgr.c | 1253 ++ sound/soc/codecs/wcd-dsp-utils.c | 221 + sound/soc/codecs/wcd-dsp-utils.h | 51 + sound/soc/codecs/wcd-mbhc-adc.c | 1020 + sound/soc/codecs/wcd-mbhc-adc.h | 35 + sound/soc/codecs/wcd-mbhc-legacy.c | 975 + sound/soc/codecs/wcd-mbhc-legacy.h | 26 + sound/soc/codecs/wcd-mbhc-v2-api.h | 60 + sound/soc/codecs/wcd-mbhc-v2.c | 2074 ++ sound/soc/codecs/wcd-mbhc-v2.h | 592 + sound/soc/codecs/wcd-spi-registers.h | 43 + sound/soc/codecs/wcd-spi.c | 1535 ++ sound/soc/codecs/wcd9335.c | 14178 ++++++++++++++ sound/soc/codecs/wcd9335.h | 166 + sound/soc/codecs/wcd934x/Makefile | 6 + sound/soc/codecs/wcd934x/wcd934x-dsd.c | 772 + sound/soc/codecs/wcd934x/wcd934x-dsd.h | 97 + sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c | 1369 ++ sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.h | 119 + sound/soc/codecs/wcd934x/wcd934x-mbhc.c | 1098 ++ sound/soc/codecs/wcd934x/wcd934x-mbhc.h | 84 + sound/soc/codecs/wcd934x/wcd934x-routing.h | 1171 ++ sound/soc/codecs/wcd934x/wcd934x.c | 9938 ++++++++++ sound/soc/codecs/wcd934x/wcd934x.h | 158 + sound/soc/codecs/wcd9xxx-common-v2.c | 1367 ++ sound/soc/codecs/wcd9xxx-common-v2.h | 236 + sound/soc/codecs/wcd9xxx-resmgr-v2.c | 693 + sound/soc/codecs/wcd9xxx-resmgr-v2.h | 93 + sound/soc/codecs/wcd9xxx-soc-init.c | 45 + sound/soc/codecs/wcd_cmi_api.h | 43 + sound/soc/codecs/wcd_cpe_core.c | 4579 +++++ sound/soc/codecs/wcd_cpe_core.h | 226 + sound/soc/codecs/wcd_cpe_services.c | 2990 +++ sound/soc/codecs/wcd_cpe_services.h | 179 + sound/soc/codecs/wcdcal-hwdep.c | 226 + sound/soc/codecs/wcdcal-hwdep.h | 40 + sound/soc/codecs/wsa881x-analog.c | 1446 ++ sound/soc/codecs/wsa881x-analog.h | 50 + sound/soc/codecs/wsa881x-irq.c | 610 + sound/soc/codecs/wsa881x-irq.h | 82 + sound/soc/codecs/wsa881x-registers-analog.h | 206 + sound/soc/codecs/wsa881x-registers.h | 178 + sound/soc/codecs/wsa881x-regmap-analog.c | 499 + sound/soc/codecs/wsa881x-regmap.c | 266 + sound/soc/codecs/wsa881x-tables-analog.c | 171 + sound/soc/codecs/wsa881x-tables.c | 171 + sound/soc/codecs/wsa881x-temp-sensor.c | 149 + sound/soc/codecs/wsa881x-temp-sensor.h | 39 + sound/soc/codecs/wsa881x.c | 1439 ++ sound/soc/codecs/wsa881x.h | 34 + sound/soc/msm/Kconfig | 283 + sound/soc/msm/Makefile | 39 + sound/soc/msm/device_event.h | 20 + sound/soc/msm/msm-audio-pinctrl.c | 316 + sound/soc/msm/msm-audio-pinctrl.h | 43 + sound/soc/msm/msm-cpe-lsm.c | 3342 ++++ sound/soc/msm/msm-dai-fe.c | 2690 +++ sound/soc/msm/msm-pcm-hostless.c | 82 + sound/soc/msm/msm8996.c | 4006 ++++ sound/soc/msm/msm8998.c | 7481 ++++++++ sound/soc/msm/qdsp6v2/Makefile | 19 + sound/soc/msm/qdsp6v2/adsp_err.c | 167 + sound/soc/msm/qdsp6v2/audio_cal_utils.c | 1030 + sound/soc/msm/qdsp6v2/audio_calibration.c | 636 + sound/soc/msm/qdsp6v2/audio_slimslave.c | 177 + .../soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c | 1378 ++ sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c | 4541 +++++ sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c | 551 + sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c | 8253 ++++++++ sound/soc/msm/qdsp6v2/msm-dai-slim.c | 664 + sound/soc/msm/qdsp6v2/msm-dai-stub-v2.c | 394 + sound/soc/msm/qdsp6v2/msm-dolby-common.h | 267 + sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h | 86 + sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c | 2317 +++ sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h | 124 + sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c | 357 + sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.h | 41 + sound/soc/msm/qdsp6v2/msm-lsm-client.c | 2414 +++ sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c | 922 + sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h | 49 + sound/soc/msm/qdsp6v2/msm-pcm-dtmf-v2.c | 596 + sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c | 1553 ++ sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c | 801 + sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c | 1136 ++ sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c | 1884 ++ sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h | 130 + .../soc/msm/qdsp6v2/msm-pcm-routing-devdep.c | 139 + .../soc/msm/qdsp6v2/msm-pcm-routing-devdep.h | 35 + sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c | 15765 ++++++++++++++++ sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h | 486 + sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c | 781 + sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.h | 42 + sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c | 1715 ++ sound/soc/msm/qdsp6v2/msm-qti-pp-config.c | 1407 ++ sound/soc/msm/qdsp6v2/msm-qti-pp-config.h | 54 + .../qdsp6v2/msm-transcode-loopback-q6-v2.c | 971 + sound/soc/msm/qdsp6v2/q6adm.c | 4860 +++++ sound/soc/msm/qdsp6v2/q6afe.c | 7150 +++++++ sound/soc/msm/qdsp6v2/q6asm.c | 9396 +++++++++ sound/soc/msm/qdsp6v2/q6audio-v2.c | 807 + sound/soc/msm/qdsp6v2/q6core.c | 853 + sound/soc/msm/qdsp6v2/q6lsm.c | 2173 +++ sound/soc/msm/qdsp6v2/q6voice.c | 8661 +++++++++ sound/soc/msm/qdsp6v2/q6voice.h | 1900 ++ sound/soc/msm/qdsp6v2/rtac.c | 1924 ++ sound/soc/msm/sdm660-common.c | 3210 ++++ sound/soc/msm/sdm660-common.h | 125 + sound/soc/msm/sdm660-ext-dai-links.c | 2038 ++ sound/soc/msm/sdm660-external.c | 1869 ++ sound/soc/msm/sdm660-external.h | 54 + sound/soc/msm/sdm660-internal.c | 3149 +++ sound/soc/msm/sdm660-internal.h | 32 + sound/soc/msm/sdm845.c | 6951 +++++++ 283 files changed, 250571 insertions(+) create mode 100644 Makefile create mode 100644 NOTICE create mode 100644 drivers/Makefile create mode 100644 drivers/base/Makefile create mode 100644 drivers/base/regmap/Makefile create mode 120000 drivers/base/regmap/internal.h create mode 100644 drivers/base/regmap/regmap-swr.c create mode 100644 drivers/mfd/Makefile create mode 100644 drivers/mfd/msm-cdc-pinctrl.c create mode 100644 drivers/mfd/msm-cdc-supply.c create mode 100644 drivers/mfd/wcd9335-regmap.c create mode 100644 drivers/mfd/wcd9335-tables.c create mode 100644 drivers/mfd/wcd934x-regmap.c create mode 100644 drivers/mfd/wcd934x-tables.c create mode 100644 drivers/mfd/wcd9xxx-core-init.c create mode 100644 drivers/mfd/wcd9xxx-core.c create mode 100644 drivers/mfd/wcd9xxx-irq.c create mode 100644 drivers/mfd/wcd9xxx-regmap.h create mode 100644 drivers/mfd/wcd9xxx-rst.c create mode 100644 drivers/mfd/wcd9xxx-slimslave.c create mode 100644 drivers/mfd/wcd9xxx-utils.c create mode 100644 drivers/misc/Makefile create mode 100644 drivers/misc/qcom/Kconfig create mode 100644 drivers/misc/qcom/Makefile create mode 100644 drivers/misc/qcom/qdsp6v2/Makefile create mode 100644 drivers/misc/qcom/qdsp6v2/aac_in.c create mode 100644 drivers/misc/qcom/qdsp6v2/amrnb_in.c create mode 100644 drivers/misc/qcom/qdsp6v2/amrwb_in.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_aac.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_alac.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_amrnb.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_amrwb.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_ape.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_evrc.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_g711alaw.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_g711mlaw.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_mp3.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_multi_aac.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_qcelp.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_utils.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_utils.h create mode 100644 drivers/misc/qcom/qdsp6v2/audio_utils_aio.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_utils_aio.h create mode 100644 drivers/misc/qcom/qdsp6v2/audio_wma.c create mode 100644 drivers/misc/qcom/qdsp6v2/audio_wmapro.c create mode 100644 drivers/misc/qcom/qdsp6v2/evrc_in.c create mode 100644 drivers/misc/qcom/qdsp6v2/g711alaw_in.c create mode 100644 drivers/misc/qcom/qdsp6v2/g711mlaw_in.c create mode 100644 drivers/misc/qcom/qdsp6v2/q6audio_common.h create mode 100644 drivers/misc/qcom/qdsp6v2/q6audio_v2.c create mode 100644 drivers/misc/qcom/qdsp6v2/q6audio_v2_aio.c create mode 100644 drivers/misc/qcom/qdsp6v2/qcelp_in.c create mode 100644 drivers/misc/qcom/qdsp6v2/ultrasound/Makefile create mode 100644 drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c create mode 100644 drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.h create mode 100644 drivers/misc/qcom/qdsp6v2/ultrasound/usf.c create mode 100644 drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.c create mode 100644 drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.h create mode 100644 drivers/pinctrl/Makefile create mode 120000 drivers/pinctrl/core.h create mode 120000 drivers/pinctrl/pinctrl-utils.h create mode 100644 drivers/pinctrl/qcom/Makefile create mode 100644 drivers/pinctrl/qcom/pinctrl-lpi.c create mode 100644 drivers/pinctrl/qcom/pinctrl-wcd.c create mode 100644 drivers/soc/Makefile create mode 100644 drivers/soc/qcom/Makefile create mode 100644 drivers/soc/qcom/qdsp6v2/Makefile create mode 100644 drivers/soc/qcom/qdsp6v2/adsp-loader.c create mode 100644 drivers/soc/qcom/qdsp6v2/apr.c create mode 100644 drivers/soc/qcom/qdsp6v2/apr_tal_glink.c create mode 100644 drivers/soc/qcom/qdsp6v2/apr_v2.c create mode 100644 drivers/soc/qcom/qdsp6v2/apr_v3.c create mode 100644 drivers/soc/qcom/qdsp6v2/audio_notifier.c create mode 100644 drivers/soc/qcom/qdsp6v2/audio_pdr.c create mode 100644 drivers/soc/qcom/qdsp6v2/audio_ssr.c create mode 100644 drivers/soc/qcom/qdsp6v2/cdsp-loader.c create mode 100644 drivers/soc/qcom/qdsp6v2/msm_audio_ion.c create mode 100644 drivers/soundwire/Kconfig create mode 100644 drivers/soundwire/Makefile create mode 100644 drivers/soundwire/soundwire.c create mode 100644 drivers/soundwire/swr-wcd-ctrl.c create mode 100644 drivers/soundwire/swr-wcd-ctrl.h create mode 100644 drivers/soundwire/swrm_registers.h create mode 100644 include/Kbuild create mode 100644 include/linux/avtimer_kernel.h create mode 100644 include/linux/mfd/msm-cdc-pinctrl.h create mode 100644 include/linux/mfd/msm-cdc-supply.h create mode 100644 include/linux/mfd/wcd9335/irq.h create mode 100644 include/linux/mfd/wcd9335/registers.h create mode 100644 include/linux/mfd/wcd934x/irq.h create mode 100644 include/linux/mfd/wcd934x/registers.h create mode 100644 include/linux/mfd/wcd9xxx/core.h create mode 100644 include/linux/mfd/wcd9xxx/pdata.h create mode 100644 include/linux/mfd/wcd9xxx/wcd9xxx-irq.h create mode 100644 include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h create mode 100644 include/linux/mfd/wcd9xxx/wcd9xxx-utils.h create mode 100644 include/linux/qdsp6v2/apr.h create mode 100644 include/linux/qdsp6v2/apr_tal.h create mode 100644 include/linux/qdsp6v2/apr_us.h create mode 100644 include/linux/qdsp6v2/audio_notifier.h create mode 100644 include/linux/qdsp6v2/audio_pdr.h create mode 100644 include/linux/qdsp6v2/audio_ssr.h create mode 100644 include/linux/qdsp6v2/dsp_debug.h create mode 100644 include/linux/qdsp6v2/rtac.h create mode 100644 include/linux/qdsp6v2/usf.h create mode 100644 include/linux/soundwire/soundwire.h create mode 100644 include/linux/soundwire/swr-wcd.h create mode 100644 include/sound/apr_audio-v2.h create mode 100644 include/sound/apr_audio.h create mode 100644 include/sound/audio_cal_utils.h create mode 100644 include/sound/audio_calibration.h create mode 100644 include/sound/cpe_cmi.h create mode 100644 include/sound/cpe_core.h create mode 100644 include/sound/cpe_err.h create mode 100644 include/sound/msm-audio-effects-q6-v2.h create mode 100644 include/sound/msm-dai-q6-v2.h create mode 100644 include/sound/msm-slim-dma.h create mode 100644 include/sound/q6adm-v2.h create mode 100644 include/sound/q6afe-v2.h create mode 100644 include/sound/q6asm-v2.h create mode 100644 include/sound/q6audio-v2.h create mode 100644 include/sound/q6core.h create mode 100644 include/sound/q6lsm.h create mode 100644 include/uapi/Kbuild create mode 100644 include/uapi/linux/Kbuild create mode 100644 include/uapi/linux/avtimer.h create mode 100644 include/uapi/linux/msm_audio.h create mode 100644 include/uapi/linux/msm_audio_aac.h create mode 100644 include/uapi/linux/msm_audio_ac3.h create mode 100644 include/uapi/linux/msm_audio_alac.h create mode 100644 include/uapi/linux/msm_audio_amrnb.h create mode 100644 include/uapi/linux/msm_audio_amrwb.h create mode 100644 include/uapi/linux/msm_audio_amrwbplus.h create mode 100644 include/uapi/linux/msm_audio_ape.h create mode 100644 include/uapi/linux/msm_audio_calibration.h create mode 100644 include/uapi/linux/msm_audio_g711.h create mode 100644 include/uapi/linux/msm_audio_g711_dec.h create mode 100644 include/uapi/linux/msm_audio_mvs.h create mode 100644 include/uapi/linux/msm_audio_qcp.h create mode 100644 include/uapi/linux/msm_audio_sbc.h create mode 100644 include/uapi/linux/msm_audio_voicememo.h create mode 100644 include/uapi/linux/msm_audio_wma.h create mode 100644 include/uapi/linux/msm_audio_wmapro.h create mode 100644 include/uapi/sound/Kbuild create mode 100644 include/uapi/sound/audio_effects.h create mode 100644 include/uapi/sound/audio_slimslave.h create mode 100644 include/uapi/sound/devdep_params.h create mode 100644 include/uapi/sound/lsm_params.h create mode 100644 include/uapi/sound/msmcal-hwdep.h create mode 100644 include/uapi/sound/voice_params.h create mode 100644 include/uapi/sound/wcd-dsp-glink.h create mode 100644 sound/Makefile create mode 100644 sound/soc/codecs/Makefile create mode 100644 sound/soc/codecs/audio-ext-clk-up.c create mode 100644 sound/soc/codecs/audio-ext-clk-up.h create mode 100644 sound/soc/codecs/audio-ext-clk.c create mode 100644 sound/soc/codecs/msm_stub.c create mode 100644 sound/soc/codecs/sdm660_cdc/Kconfig create mode 100644 sound/soc/codecs/sdm660_cdc/Makefile create mode 100644 sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c create mode 100644 sound/soc/codecs/sdm660_cdc/msm-analog-cdc.h create mode 100644 sound/soc/codecs/sdm660_cdc/msm-cdc-common.h create mode 100644 sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c create mode 100644 sound/soc/codecs/sdm660_cdc/msm-digital-cdc.h create mode 100644 sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.c create mode 100644 sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.h create mode 100644 sound/soc/codecs/sdm660_cdc/sdm660-cdc-registers.h create mode 100644 sound/soc/codecs/sdm660_cdc/sdm660-regmap.c create mode 100644 sound/soc/codecs/wcd-dsp-mgr.c create mode 100644 sound/soc/codecs/wcd-dsp-utils.c create mode 100644 sound/soc/codecs/wcd-dsp-utils.h create mode 100644 sound/soc/codecs/wcd-mbhc-adc.c create mode 100644 sound/soc/codecs/wcd-mbhc-adc.h create mode 100644 sound/soc/codecs/wcd-mbhc-legacy.c create mode 100644 sound/soc/codecs/wcd-mbhc-legacy.h create mode 100644 sound/soc/codecs/wcd-mbhc-v2-api.h create mode 100644 sound/soc/codecs/wcd-mbhc-v2.c create mode 100644 sound/soc/codecs/wcd-mbhc-v2.h create mode 100644 sound/soc/codecs/wcd-spi-registers.h create mode 100644 sound/soc/codecs/wcd-spi.c create mode 100644 sound/soc/codecs/wcd9335.c create mode 100644 sound/soc/codecs/wcd9335.h create mode 100644 sound/soc/codecs/wcd934x/Makefile create mode 100644 sound/soc/codecs/wcd934x/wcd934x-dsd.c create mode 100644 sound/soc/codecs/wcd934x/wcd934x-dsd.h create mode 100644 sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c create mode 100644 sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.h create mode 100644 sound/soc/codecs/wcd934x/wcd934x-mbhc.c create mode 100644 sound/soc/codecs/wcd934x/wcd934x-mbhc.h create mode 100644 sound/soc/codecs/wcd934x/wcd934x-routing.h create mode 100644 sound/soc/codecs/wcd934x/wcd934x.c create mode 100644 sound/soc/codecs/wcd934x/wcd934x.h create mode 100644 sound/soc/codecs/wcd9xxx-common-v2.c create mode 100644 sound/soc/codecs/wcd9xxx-common-v2.h create mode 100644 sound/soc/codecs/wcd9xxx-resmgr-v2.c create mode 100644 sound/soc/codecs/wcd9xxx-resmgr-v2.h create mode 100644 sound/soc/codecs/wcd9xxx-soc-init.c create mode 100644 sound/soc/codecs/wcd_cmi_api.h create mode 100644 sound/soc/codecs/wcd_cpe_core.c create mode 100644 sound/soc/codecs/wcd_cpe_core.h create mode 100644 sound/soc/codecs/wcd_cpe_services.c create mode 100644 sound/soc/codecs/wcd_cpe_services.h create mode 100644 sound/soc/codecs/wcdcal-hwdep.c create mode 100644 sound/soc/codecs/wcdcal-hwdep.h create mode 100644 sound/soc/codecs/wsa881x-analog.c create mode 100644 sound/soc/codecs/wsa881x-analog.h create mode 100644 sound/soc/codecs/wsa881x-irq.c create mode 100644 sound/soc/codecs/wsa881x-irq.h create mode 100644 sound/soc/codecs/wsa881x-registers-analog.h create mode 100644 sound/soc/codecs/wsa881x-registers.h create mode 100644 sound/soc/codecs/wsa881x-regmap-analog.c create mode 100644 sound/soc/codecs/wsa881x-regmap.c create mode 100644 sound/soc/codecs/wsa881x-tables-analog.c create mode 100644 sound/soc/codecs/wsa881x-tables.c create mode 100644 sound/soc/codecs/wsa881x-temp-sensor.c create mode 100644 sound/soc/codecs/wsa881x-temp-sensor.h create mode 100644 sound/soc/codecs/wsa881x.c create mode 100644 sound/soc/codecs/wsa881x.h create mode 100644 sound/soc/msm/Kconfig create mode 100644 sound/soc/msm/Makefile create mode 100644 sound/soc/msm/device_event.h create mode 100644 sound/soc/msm/msm-audio-pinctrl.c create mode 100644 sound/soc/msm/msm-audio-pinctrl.h create mode 100644 sound/soc/msm/msm-cpe-lsm.c create mode 100644 sound/soc/msm/msm-dai-fe.c create mode 100644 sound/soc/msm/msm-pcm-hostless.c create mode 100644 sound/soc/msm/msm8996.c create mode 100644 sound/soc/msm/msm8998.c create mode 100644 sound/soc/msm/qdsp6v2/Makefile create mode 100644 sound/soc/msm/qdsp6v2/adsp_err.c create mode 100644 sound/soc/msm/qdsp6v2/audio_cal_utils.c create mode 100644 sound/soc/msm/qdsp6v2/audio_calibration.c create mode 100644 sound/soc/msm/qdsp6v2/audio_slimslave.c create mode 100644 sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c create mode 100644 sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c create mode 100644 sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c create mode 100644 sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c create mode 100644 sound/soc/msm/qdsp6v2/msm-dai-slim.c create mode 100644 sound/soc/msm/qdsp6v2/msm-dai-stub-v2.c create mode 100644 sound/soc/msm/qdsp6v2/msm-dolby-common.h create mode 100644 sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h create mode 100644 sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c create mode 100644 sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h create mode 100644 sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c create mode 100644 sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.h create mode 100644 sound/soc/msm/qdsp6v2/msm-lsm-client.c create mode 100644 sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c create mode 100644 sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h create mode 100644 sound/soc/msm/qdsp6v2/msm-pcm-dtmf-v2.c create mode 100644 sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c create mode 100644 sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c create mode 100644 sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c create mode 100644 sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c create mode 100644 sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h create mode 100644 sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.c create mode 100644 sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.h create mode 100644 sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c create mode 100644 sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h create mode 100644 sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c create mode 100644 sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.h create mode 100644 sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c create mode 100644 sound/soc/msm/qdsp6v2/msm-qti-pp-config.c create mode 100644 sound/soc/msm/qdsp6v2/msm-qti-pp-config.h create mode 100644 sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c create mode 100644 sound/soc/msm/qdsp6v2/q6adm.c create mode 100644 sound/soc/msm/qdsp6v2/q6afe.c create mode 100644 sound/soc/msm/qdsp6v2/q6asm.c create mode 100644 sound/soc/msm/qdsp6v2/q6audio-v2.c create mode 100644 sound/soc/msm/qdsp6v2/q6core.c create mode 100644 sound/soc/msm/qdsp6v2/q6lsm.c create mode 100644 sound/soc/msm/qdsp6v2/q6voice.c create mode 100644 sound/soc/msm/qdsp6v2/q6voice.h create mode 100644 sound/soc/msm/qdsp6v2/rtac.c create mode 100644 sound/soc/msm/sdm660-common.c create mode 100644 sound/soc/msm/sdm660-common.h create mode 100644 sound/soc/msm/sdm660-ext-dai-links.c create mode 100644 sound/soc/msm/sdm660-external.c create mode 100644 sound/soc/msm/sdm660-external.h create mode 100644 sound/soc/msm/sdm660-internal.c create mode 100644 sound/soc/msm/sdm660-internal.h create mode 100644 sound/soc/msm/sdm845.c diff --git a/Makefile b/Makefile new file mode 100644 index 000000000000..b8428deb5c05 --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +# auto-detect subdirs +ifeq ($(CONFIG_ARCH_SDM845), y) +include $(srctree)/techpack/audio/config/sdm845auto.conf +export +endif + +# Use USERINCLUDE when you must reference the UAPI directories only. +USERINCLUDE += \ + -I$(srctree)/techpack/audio/include/uapi \ + +# Use LINUXINCLUDE when you must reference the include/ directory. +# Needed to be compatible with the O= option +LINUXINCLUDE += \ + -I$(srctree)/techpack/audio/include/uapi \ + -I$(srctree)/techpack/audio/include + +ifeq ($(CONFIG_ARCH_SDM845), y) +LINUXINCLUDE += \ + -include $(srctree)/techpack/audio/config/sdm845autoconf.h +endif + +obj-y += drivers/ +obj-y += sound/ diff --git a/NOTICE b/NOTICE new file mode 100644 index 000000000000..9ad222017a76 --- /dev/null +++ b/NOTICE @@ -0,0 +1,24 @@ +Copyright (c) 2009-2017, The Linux Foundation. All rights reserved. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2 and +only version 2 as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +________________________________________ + +Copyright (C) 2008 Google, Inc. +Copyright (C) 2008 HTC Corporation +Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. + +This software is licensed under the terms of the GNU General Public +License version 2, as published by the Free Software Foundation, and +may be copied, distributed, and modified under those terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. diff --git a/drivers/Makefile b/drivers/Makefile new file mode 100644 index 000000000000..b48069c04d47 --- /dev/null +++ b/drivers/Makefile @@ -0,0 +1,7 @@ + +obj-y += mfd/ +obj-y += misc/ +obj-y += soc/ +obj-y += soundwire/ +obj-y += base/ +obj-y += pinctrl/ diff --git a/drivers/base/Makefile b/drivers/base/Makefile new file mode 100644 index 000000000000..76e50f9816bf --- /dev/null +++ b/drivers/base/Makefile @@ -0,0 +1,2 @@ + +obj-y += regmap/ diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile new file mode 100644 index 000000000000..a23e35ed8459 --- /dev/null +++ b/drivers/base/regmap/Makefile @@ -0,0 +1,2 @@ + +obj-$(CONFIG_REGMAP_SWR) += regmap-swr.o diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h new file mode 120000 index 000000000000..e163b7862be6 --- /dev/null +++ b/drivers/base/regmap/internal.h @@ -0,0 +1 @@ +../../../../../drivers/base/regmap/internal.h \ No newline at end of file diff --git a/drivers/base/regmap/regmap-swr.c b/drivers/base/regmap/regmap-swr.c new file mode 100644 index 000000000000..be1eb00ad876 --- /dev/null +++ b/drivers/base/regmap/regmap-swr.c @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +static int regmap_swr_gather_write(void *context, + const void *reg, size_t reg_size, + const void *val, size_t val_len) +{ + struct device *dev = context; + struct swr_device *swr = to_swr_device(dev); + struct regmap *map = dev_get_regmap(dev, NULL); + size_t addr_bytes; + size_t val_bytes; + int i, ret = 0; + u16 reg_addr = 0; + u8 *value; + + if (map == NULL) { + dev_err(dev, "%s: regmap is NULL\n", __func__); + return -EINVAL; + } + addr_bytes = map->format.reg_bytes; + if (swr == NULL) { + dev_err(dev, "%s: swr device is NULL\n", __func__); + return -EINVAL; + } + if (reg_size != addr_bytes) { + dev_err(dev, "%s: reg size %zd bytes not supported\n", + __func__, reg_size); + return -EINVAL; + } + reg_addr = *(u16 *)reg; + val_bytes = map->format.val_bytes; + /* val_len = val_bytes * val_count */ + for (i = 0; i < (val_len / val_bytes); i++) { + value = (u8 *)val + (val_bytes * i); + ret = swr_write(swr, swr->dev_num, (reg_addr + i), value); + if (ret < 0) { + dev_err(dev, "%s: write reg 0x%x failed, err %d\n", + __func__, (reg_addr + i), ret); + break; + } + } + return ret; +} + +static int regmap_swr_raw_multi_reg_write(void *context, const void *data, + size_t count) +{ + struct device *dev = context; + struct swr_device *swr = to_swr_device(dev); + struct regmap *map = dev_get_regmap(dev, NULL); + size_t addr_bytes; + size_t val_bytes; + size_t pad_bytes; + size_t num_regs; + int i = 0; + int ret = 0; + u16 *reg; + u8 *val; + u8 *buf; + + if (swr == NULL) { + dev_err(dev, "%s: swr device is NULL\n", __func__); + return -EINVAL; + } + + if (map == NULL) { + dev_err(dev, "%s: regmap is NULL\n", __func__); + return -EINVAL; + } + + addr_bytes = map->format.reg_bytes; + val_bytes = map->format.val_bytes; + pad_bytes = map->format.pad_bytes; + + if (addr_bytes + val_bytes + pad_bytes == 0) { + dev_err(dev, "%s: sum of addr, value and pad is 0\n", __func__); + return -EINVAL; + } + num_regs = count / (addr_bytes + val_bytes + pad_bytes); + + reg = kcalloc(num_regs, sizeof(u16), GFP_KERNEL); + if (!reg) + return -ENOMEM; + + val = kcalloc(num_regs, sizeof(u8), GFP_KERNEL); + if (!val) { + ret = -ENOMEM; + goto mem_fail; + } + + buf = (u8 *)data; + for (i = 0; i < num_regs; i++) { + reg[i] = *(u16 *)buf; + buf += (map->format.reg_bytes + map->format.pad_bytes); + val[i] = *buf; + buf += map->format.val_bytes; + } + ret = swr_bulk_write(swr, swr->dev_num, reg, val, num_regs); + if (ret) + dev_err(dev, "%s: multi reg write failed\n", __func__); + + kfree(val); +mem_fail: + kfree(reg); + return ret; +} + +static int regmap_swr_write(void *context, const void *data, size_t count) +{ + struct device *dev = context; + struct regmap *map = dev_get_regmap(dev, NULL); + size_t addr_bytes; + size_t val_bytes; + size_t pad_bytes; + + if (map == NULL) { + dev_err(dev, "%s: regmap is NULL\n", __func__); + return -EINVAL; + } + addr_bytes = map->format.reg_bytes; + val_bytes = map->format.val_bytes; + pad_bytes = map->format.pad_bytes; + + WARN_ON(count < addr_bytes); + + if (count > (addr_bytes + val_bytes + pad_bytes)) + return regmap_swr_raw_multi_reg_write(context, data, count); + else + return regmap_swr_gather_write(context, data, addr_bytes, + (data + addr_bytes), + (count - addr_bytes)); +} + +static int regmap_swr_read(void *context, + const void *reg, size_t reg_size, + void *val, size_t val_size) +{ + struct device *dev = context; + struct swr_device *swr = to_swr_device(dev); + struct regmap *map = dev_get_regmap(dev, NULL); + size_t addr_bytes; + int ret = 0; + u16 reg_addr = 0; + + if (map == NULL) { + dev_err(dev, "%s: regmap is NULL\n", __func__); + return -EINVAL; + } + addr_bytes = map->format.reg_bytes; + if (swr == NULL) { + dev_err(dev, "%s: swr is NULL\n", __func__); + return -EINVAL; + } + if (reg_size != addr_bytes) { + dev_err(dev, "%s: register size %zd bytes not supported\n", + __func__, reg_size); + return -EINVAL; + } + reg_addr = *(u16 *)reg; + ret = swr_read(swr, swr->dev_num, reg_addr, val, val_size); + if (ret < 0) + dev_err(dev, "%s: codec reg 0x%x read failed %d\n", + __func__, reg_addr, ret); + return ret; +} + +static struct regmap_bus regmap_swr = { + .write = regmap_swr_write, + .gather_write = regmap_swr_gather_write, + .read = regmap_swr_read, + .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, + .val_format_endian_default = REGMAP_ENDIAN_NATIVE, +}; + +struct regmap *__regmap_init_swr(struct swr_device *swr, + const struct regmap_config *config, + struct lock_class_key *lock_key, + const char *lock_name) +{ + return __regmap_init(&swr->dev, ®map_swr, &swr->dev, config, + lock_key, lock_name); +} +EXPORT_SYMBOL(__regmap_init_swr); + +struct regmap *__devm_regmap_init_swr(struct swr_device *swr, + const struct regmap_config *config, + struct lock_class_key *lock_key, + const char *lock_name) +{ + return __devm_regmap_init(&swr->dev, ®map_swr, &swr->dev, config, + lock_key, lock_name); +} +EXPORT_SYMBOL(__devm_regmap_init_swr); + +MODULE_LICENSE("GPL v2"); diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile new file mode 100644 index 000000000000..745691af1673 --- /dev/null +++ b/drivers/mfd/Makefile @@ -0,0 +1,8 @@ +wcd-core-objs := wcd9xxx-rst.o wcd9xxx-core-init.o \ + wcd9xxx-core.o wcd9xxx-irq.o \ + wcd9xxx-slimslave.o wcd9xxx-utils.o \ + wcd934x-regmap.o wcd934x-tables.o \ + wcd9335-regmap.o wcd9335-tables.o \ + msm-cdc-pinctrl.o msm-cdc-supply.o +obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd-core.o + diff --git a/drivers/mfd/msm-cdc-pinctrl.c b/drivers/mfd/msm-cdc-pinctrl.c new file mode 100644 index 000000000000..859a75f93bb5 --- /dev/null +++ b/drivers/mfd/msm-cdc-pinctrl.c @@ -0,0 +1,253 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct msm_cdc_pinctrl_info { + struct pinctrl *pinctrl; + struct pinctrl_state *pinctrl_active; + struct pinctrl_state *pinctrl_sleep; + int gpio; + bool state; +}; + +static struct msm_cdc_pinctrl_info *msm_cdc_pinctrl_get_gpiodata( + struct device_node *np) +{ + struct platform_device *pdev; + struct msm_cdc_pinctrl_info *gpio_data; + + if (!np) { + pr_err("%s: device node is null\n", __func__); + return NULL; + } + + pdev = of_find_device_by_node(np); + if (!pdev) { + pr_err("%s: platform device not found!\n", __func__); + return NULL; + } + + gpio_data = dev_get_drvdata(&pdev->dev); + if (!gpio_data) + dev_err(&pdev->dev, "%s: cannot find cdc gpio info\n", + __func__); + + return gpio_data; +} + +/* + * msm_cdc_get_gpio_state: select pinctrl sleep state + * @np: pointer to struct device_node + * + * Returns error code for failure and GPIO value on success + */ +int msm_cdc_get_gpio_state(struct device_node *np) +{ + struct msm_cdc_pinctrl_info *gpio_data; + int value = -EINVAL; + + gpio_data = msm_cdc_pinctrl_get_gpiodata(np); + if (!gpio_data) + return value; + + if (gpio_is_valid(gpio_data->gpio)) + value = gpio_get_value_cansleep(gpio_data->gpio); + + return value; +} +EXPORT_SYMBOL(msm_cdc_get_gpio_state); + +/* + * msm_cdc_pinctrl_select_sleep_state: select pinctrl sleep state + * @np: pointer to struct device_node + * + * Returns error code for failure + */ +int msm_cdc_pinctrl_select_sleep_state(struct device_node *np) +{ + struct msm_cdc_pinctrl_info *gpio_data; + + gpio_data = msm_cdc_pinctrl_get_gpiodata(np); + if (!gpio_data) + return -EINVAL; + + if (!gpio_data->pinctrl_sleep) { + pr_err("%s: pinctrl sleep state is null\n", __func__); + return -EINVAL; + } + gpio_data->state = false; + + return pinctrl_select_state(gpio_data->pinctrl, + gpio_data->pinctrl_sleep); +} +EXPORT_SYMBOL(msm_cdc_pinctrl_select_sleep_state); + +/* + * msm_cdc_pinctrl_select_active_state: select pinctrl active state + * @np: pointer to struct device_node + * + * Returns error code for failure + */ +int msm_cdc_pinctrl_select_active_state(struct device_node *np) +{ + struct msm_cdc_pinctrl_info *gpio_data; + + gpio_data = msm_cdc_pinctrl_get_gpiodata(np); + if (!gpio_data) + return -EINVAL; + + if (!gpio_data->pinctrl_active) { + pr_err("%s: pinctrl active state is null\n", __func__); + return -EINVAL; + } + gpio_data->state = true; + + return pinctrl_select_state(gpio_data->pinctrl, + gpio_data->pinctrl_active); +} +EXPORT_SYMBOL(msm_cdc_pinctrl_select_active_state); + +/* + * msm_cdc_pinctrl_get_state: get curren pinctrl state + * @np: pointer to struct device_node + * + * Returns 0 for sleep state, 1 for active state + */ +bool msm_cdc_pinctrl_get_state(struct device_node *np) +{ + struct msm_cdc_pinctrl_info *gpio_data; + + gpio_data = msm_cdc_pinctrl_get_gpiodata(np); + if (!gpio_data) + return -EINVAL; + + return gpio_data->state; +} +EXPORT_SYMBOL(msm_cdc_pinctrl_get_state); + +static int msm_cdc_pinctrl_probe(struct platform_device *pdev) +{ + int ret = 0; + struct msm_cdc_pinctrl_info *gpio_data; + + gpio_data = devm_kzalloc(&pdev->dev, + sizeof(struct msm_cdc_pinctrl_info), + GFP_KERNEL); + if (!gpio_data) + return -ENOMEM; + + gpio_data->pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR_OR_NULL(gpio_data->pinctrl)) { + dev_err(&pdev->dev, "%s: Cannot get cdc gpio pinctrl:%ld\n", + __func__, PTR_ERR(gpio_data->pinctrl)); + ret = PTR_ERR(gpio_data->pinctrl); + goto err_pctrl_get; + } + + gpio_data->pinctrl_active = pinctrl_lookup_state( + gpio_data->pinctrl, "aud_active"); + if (IS_ERR_OR_NULL(gpio_data->pinctrl_active)) { + dev_err(&pdev->dev, "%s: Cannot get aud_active pinctrl state:%ld\n", + __func__, PTR_ERR(gpio_data->pinctrl_active)); + ret = PTR_ERR(gpio_data->pinctrl_active); + goto err_lookup_state; + } + + gpio_data->pinctrl_sleep = pinctrl_lookup_state( + gpio_data->pinctrl, "aud_sleep"); + if (IS_ERR_OR_NULL(gpio_data->pinctrl_sleep)) { + dev_err(&pdev->dev, "%s: Cannot get aud_sleep pinctrl state:%ld\n", + __func__, PTR_ERR(gpio_data->pinctrl_sleep)); + ret = PTR_ERR(gpio_data->pinctrl_sleep); + goto err_lookup_state; + } + /* skip setting to sleep state for LPI_TLMM GPIOs */ + if (!of_property_read_bool(pdev->dev.of_node, "qcom,lpi-gpios")) { + /* Set pinctrl state to aud_sleep by default */ + ret = pinctrl_select_state(gpio_data->pinctrl, + gpio_data->pinctrl_sleep); + if (ret) + dev_err(&pdev->dev, "%s: set cdc gpio sleep state fail: %d\n", + __func__, ret); + } + + gpio_data->gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,cdc-rst-n-gpio", 0); + if (gpio_is_valid(gpio_data->gpio)) { + ret = gpio_request(gpio_data->gpio, "MSM_CDC_RESET"); + if (ret) { + dev_err(&pdev->dev, "%s: Failed to request gpio %d\n", + __func__, gpio_data->gpio); + goto err_lookup_state; + } + } + + dev_set_drvdata(&pdev->dev, gpio_data); + return 0; + +err_lookup_state: + devm_pinctrl_put(gpio_data->pinctrl); +err_pctrl_get: + devm_kfree(&pdev->dev, gpio_data); + return ret; +} + +static int msm_cdc_pinctrl_remove(struct platform_device *pdev) +{ + struct msm_cdc_pinctrl_info *gpio_data; + + gpio_data = dev_get_drvdata(&pdev->dev); + + if (gpio_data && gpio_data->pinctrl) + devm_pinctrl_put(gpio_data->pinctrl); + + devm_kfree(&pdev->dev, gpio_data); + + return 0; +} + +static const struct of_device_id msm_cdc_pinctrl_match[] = { + {.compatible = "qcom,msm-cdc-pinctrl"}, + {} +}; + +static struct platform_driver msm_cdc_pinctrl_driver = { + .driver = { + .name = "msm-cdc-pinctrl", + .owner = THIS_MODULE, + .of_match_table = msm_cdc_pinctrl_match, + }, + .probe = msm_cdc_pinctrl_probe, + .remove = msm_cdc_pinctrl_remove, +}; + +int msm_cdc_pinctrl_drv_init(void) +{ + return platform_driver_register(&msm_cdc_pinctrl_driver); +} + +void msm_cdc_pinctrl_drv_exit(void) +{ + platform_driver_unregister(&msm_cdc_pinctrl_driver); +} +MODULE_DESCRIPTION("MSM CODEC pin control platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/mfd/msm-cdc-supply.c b/drivers/mfd/msm-cdc-supply.c new file mode 100644 index 000000000000..9c7ebf78a00e --- /dev/null +++ b/drivers/mfd/msm-cdc-supply.c @@ -0,0 +1,456 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define CODEC_DT_MAX_PROP_SIZE 40 + +static int msm_cdc_dt_parse_vreg_info(struct device *dev, + struct cdc_regulator *cdc_vreg, + const char *name, bool is_ond) +{ + char prop_name[CODEC_DT_MAX_PROP_SIZE]; + struct device_node *regulator_node = NULL; + const __be32 *prop; + int len, rc; + u32 prop_val; + + /* Parse supply name */ + snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "%s-supply", name); + + regulator_node = of_parse_phandle(dev->of_node, prop_name, 0); + if (!regulator_node) { + dev_err(dev, "%s: Looking up %s property in node %s failed", + __func__, prop_name, dev->of_node->full_name); + rc = -EINVAL; + goto done; + } + cdc_vreg->name = name; + cdc_vreg->ondemand = is_ond; + + /* Parse supply - voltage */ + snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "qcom,%s-voltage", name); + prop = of_get_property(dev->of_node, prop_name, &len); + if (!prop || (len != (2 * sizeof(__be32)))) { + dev_err(dev, "%s: %s %s property\n", __func__, + prop ? "invalid format" : "no", prop_name); + rc = -EINVAL; + goto done; + } else { + cdc_vreg->min_uV = be32_to_cpup(&prop[0]); + cdc_vreg->max_uV = be32_to_cpup(&prop[1]); + } + + /* Parse supply - current */ + snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "qcom,%s-current", name); + rc = of_property_read_u32(dev->of_node, prop_name, &prop_val); + if (rc) { + dev_err(dev, "%s: Looking up %s property in node %s failed", + __func__, prop_name, dev->of_node->full_name); + goto done; + } + cdc_vreg->optimum_uA = prop_val; + + dev_info(dev, "%s: %s: vol=[%d %d]uV, curr=[%d]uA, ond %d\n", + __func__, cdc_vreg->name, cdc_vreg->min_uV, cdc_vreg->max_uV, + cdc_vreg->optimum_uA, cdc_vreg->ondemand); + +done: + return rc; +} + +static int msm_cdc_parse_supplies(struct device *dev, + struct cdc_regulator *cdc_reg, + const char *sup_list, int sup_cnt, + bool is_ond) +{ + int idx, rc = 0; + const char *name = NULL; + + for (idx = 0; idx < sup_cnt; idx++) { + rc = of_property_read_string_index(dev->of_node, sup_list, idx, + &name); + if (rc) { + dev_err(dev, "%s: read string %s[%d] error (%d)\n", + __func__, sup_list, idx, rc); + goto done; + } + + dev_dbg(dev, "%s: Found cdc supply %s as part of %s\n", + __func__, name, sup_list); + + rc = msm_cdc_dt_parse_vreg_info(dev, &cdc_reg[idx], name, + is_ond); + if (rc) { + dev_err(dev, "%s: parse %s vreg info failed (%d)\n", + __func__, name, rc); + goto done; + } + } + +done: + return rc; +} + +static int msm_cdc_check_supply_param(struct device *dev, + struct cdc_regulator *cdc_vreg, + int num_supplies) +{ + if (!dev) { + pr_err("%s: device is NULL\n", __func__); + return -ENODEV; + } + + if (!cdc_vreg || (num_supplies <= 0)) { + dev_err(dev, "%s: supply check failed: vreg: %pK, num_supplies: %d\n", + __func__, cdc_vreg, num_supplies); + return -EINVAL; + } + + return 0; +} + +/* + * msm_cdc_disable_static_supplies: + * Disable codec static supplies + * + * @dev: pointer to codec device + * @supplies: pointer to regulator bulk data + * @cdc_vreg: pointer to platform regulator data + * @num_supplies: number of supplies + * + * Return error code if supply disable is failed + */ +int msm_cdc_disable_static_supplies(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies) +{ + int rc, i; + + if ((!dev) || (!supplies) || (!cdc_vreg)) { + pr_err("%s: either dev or supplies or cdc_vreg is NULL\n", + __func__); + return -EINVAL; + } + /* input parameter validation */ + rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies); + if (rc) + return rc; + + for (i = 0; i < num_supplies; i++) { + if (cdc_vreg[i].ondemand) + continue; + + rc = regulator_disable(supplies[i].consumer); + if (rc) + dev_err(dev, "%s: failed to disable supply %s, err:%d\n", + __func__, supplies[i].supply, rc); + else + dev_dbg(dev, "%s: disabled regulator %s\n", + __func__, supplies[i].supply); + } + + return rc; +} +EXPORT_SYMBOL(msm_cdc_disable_static_supplies); + +/* + * msm_cdc_release_supplies: + * Release codec power supplies + * + * @dev: pointer to codec device + * @supplies: pointer to regulator bulk data + * @cdc_vreg: pointer to platform regulator data + * @num_supplies: number of supplies + * + * Return error code if supply disable is failed + */ +int msm_cdc_release_supplies(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies) +{ + int rc = 0; + int i; + + if ((!dev) || (!supplies) || (!cdc_vreg)) { + pr_err("%s: either dev or supplies or cdc_vreg is NULL\n", + __func__); + return -EINVAL; + } + /* input parameter validation */ + rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies); + if (rc) + return rc; + + msm_cdc_disable_static_supplies(dev, supplies, cdc_vreg, + num_supplies); + for (i = 0; i < num_supplies; i++) { + if (regulator_count_voltages(supplies[i].consumer) < 0) + continue; + + regulator_set_voltage(supplies[i].consumer, 0, + cdc_vreg[i].max_uV); + regulator_set_load(supplies[i].consumer, 0); + devm_regulator_put(supplies[i].consumer); + supplies[i].consumer = NULL; + } + devm_kfree(dev, supplies); + + return rc; +} +EXPORT_SYMBOL(msm_cdc_release_supplies); + +/* + * msm_cdc_enable_static_supplies: + * Enable codec static supplies + * + * @dev: pointer to codec device + * @supplies: pointer to regulator bulk data + * @cdc_vreg: pointer to platform regulator data + * @num_supplies: number of supplies + * + * Return error code if supply enable is failed + */ +int msm_cdc_enable_static_supplies(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies) +{ + int rc, i; + + if ((!dev) || (!supplies) || (!cdc_vreg)) { + pr_err("%s: either dev or supplies or cdc_vreg is NULL\n", + __func__); + return -EINVAL; + } + /* input parameter validation */ + rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies); + if (rc) + return rc; + + for (i = 0; i < num_supplies; i++) { + if (cdc_vreg[i].ondemand) + continue; + + rc = regulator_enable(supplies[i].consumer); + if (rc) { + dev_err(dev, "%s: failed to enable supply %s, rc: %d\n", + __func__, supplies[i].supply, rc); + break; + } + } + + while (rc && i--) + if (!cdc_vreg[i].ondemand) + regulator_disable(supplies[i].consumer); + + return rc; +} +EXPORT_SYMBOL(msm_cdc_enable_static_supplies); + +/* + * msm_cdc_init_supplies: + * Initialize codec static supplies with regulator get + * + * @dev: pointer to codec device + * @supplies: pointer to regulator bulk data + * @cdc_vreg: pointer to platform regulator data + * @num_supplies: number of supplies + * + * Return error code if supply init is failed + */ +int msm_cdc_init_supplies(struct device *dev, + struct regulator_bulk_data **supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies) +{ + struct regulator_bulk_data *vsup; + int rc; + int i; + + if (!dev || !cdc_vreg) { + pr_err("%s: device pointer or dce_vreg is NULL\n", + __func__); + return -EINVAL; + } + /* input parameter validation */ + rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies); + if (rc) + return rc; + + vsup = devm_kcalloc(dev, num_supplies, + sizeof(struct regulator_bulk_data), + GFP_KERNEL); + if (!vsup) + return -ENOMEM; + + for (i = 0; i < num_supplies; i++) { + if (!cdc_vreg[i].name) { + dev_err(dev, "%s: supply name not defined\n", + __func__); + rc = -EINVAL; + goto err_supply; + } + vsup[i].supply = cdc_vreg[i].name; + } + + rc = devm_regulator_bulk_get(dev, num_supplies, vsup); + if (rc) { + dev_err(dev, "%s: failed to get supplies (%d)\n", + __func__, rc); + goto err_supply; + } + + /* Set voltage and current on regulators */ + for (i = 0; i < num_supplies; i++) { + if (regulator_count_voltages(vsup[i].consumer) < 0) + continue; + + rc = regulator_set_voltage(vsup[i].consumer, + cdc_vreg[i].min_uV, + cdc_vreg[i].max_uV); + if (rc) { + dev_err(dev, "%s: set regulator voltage failed for %s, err:%d\n", + __func__, vsup[i].supply, rc); + goto err_set_supply; + } + rc = regulator_set_load(vsup[i].consumer, + cdc_vreg[i].optimum_uA); + if (rc < 0) { + dev_err(dev, "%s: set regulator optimum mode failed for %s, err:%d\n", + __func__, vsup[i].supply, rc); + goto err_set_supply; + } + } + + *supplies = vsup; + + return 0; + +err_set_supply: + for (i = 0; i < num_supplies; i++) + devm_regulator_put(vsup[i].consumer); +err_supply: + devm_kfree(dev, vsup); + return rc; +} +EXPORT_SYMBOL(msm_cdc_init_supplies); + +/* + * msm_cdc_get_power_supplies: + * Get codec power supplies from device tree. + * Allocate memory to hold regulator data for + * all power supplies. + * + * @dev: pointer to codec device + * @cdc_vreg: pointer to codec regulator + * @total_num_supplies: total number of supplies read from DT + * + * Return error code if supply disable is failed + */ +int msm_cdc_get_power_supplies(struct device *dev, + struct cdc_regulator **cdc_vreg, + int *total_num_supplies) +{ + const char *static_prop_name = "qcom,cdc-static-supplies"; + const char *ond_prop_name = "qcom,cdc-on-demand-supplies"; + const char *cp_prop_name = "qcom,cdc-cp-supplies"; + int static_sup_cnt = 0; + int ond_sup_cnt = 0; + int cp_sup_cnt = 0; + int num_supplies = 0; + struct cdc_regulator *cdc_reg; + int rc; + + if (!dev) { + pr_err("%s: device pointer is NULL\n", __func__); + return -EINVAL; + } + static_sup_cnt = of_property_count_strings(dev->of_node, + static_prop_name); + if (static_sup_cnt < 0) { + dev_err(dev, "%s: Failed to get static supplies(%d)\n", + __func__, static_sup_cnt); + rc = static_sup_cnt; + goto err_supply_cnt; + } + ond_sup_cnt = of_property_count_strings(dev->of_node, ond_prop_name); + if (ond_sup_cnt < 0) + ond_sup_cnt = 0; + + cp_sup_cnt = of_property_count_strings(dev->of_node, + cp_prop_name); + if (cp_sup_cnt < 0) + cp_sup_cnt = 0; + + num_supplies = static_sup_cnt + ond_sup_cnt + cp_sup_cnt; + if (num_supplies <= 0) { + dev_err(dev, "%s: supply count is 0 or negative\n", __func__); + rc = -EINVAL; + goto err_supply_cnt; + } + + cdc_reg = devm_kcalloc(dev, num_supplies, + sizeof(struct cdc_regulator), + GFP_KERNEL); + if (!cdc_reg) { + rc = -ENOMEM; + goto err_mem_alloc; + } + + rc = msm_cdc_parse_supplies(dev, cdc_reg, static_prop_name, + static_sup_cnt, false); + if (rc) { + dev_err(dev, "%s: failed to parse static supplies(%d)\n", + __func__, rc); + goto err_sup; + } + + rc = msm_cdc_parse_supplies(dev, &cdc_reg[static_sup_cnt], + ond_prop_name, ond_sup_cnt, + true); + if (rc) { + dev_err(dev, "%s: failed to parse demand supplies(%d)\n", + __func__, rc); + goto err_sup; + } + + rc = msm_cdc_parse_supplies(dev, + &cdc_reg[static_sup_cnt + ond_sup_cnt], + cp_prop_name, cp_sup_cnt, true); + if (rc) { + dev_err(dev, "%s: failed to parse cp supplies(%d)\n", + __func__, rc); + goto err_sup; + } + + *cdc_vreg = cdc_reg; + *total_num_supplies = num_supplies; + + return 0; + +err_sup: + devm_kfree(dev, cdc_reg); +err_supply_cnt: +err_mem_alloc: + return rc; +} +EXPORT_SYMBOL(msm_cdc_get_power_supplies); diff --git a/drivers/mfd/wcd9335-regmap.c b/drivers/mfd/wcd9335-regmap.c new file mode 100644 index 000000000000..1762374418c0 --- /dev/null +++ b/drivers/mfd/wcd9335-regmap.c @@ -0,0 +1,1611 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include "wcd9xxx-regmap.h" + +static const struct reg_sequence wcd9335_1_x_defaults[] = { + { WCD9335_CODEC_RPM_CLK_GATE, 0x03, 0x00 }, + { WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN, 0x1f, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0, 0x00, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x00, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_RX0_INP_CFG, 0x00, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_RX1_INP_CFG, 0x00, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_RX2_INP_CFG, 0x00, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_RX3_INP_CFG, 0x00, 0x00 }, + { WCD9335_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD, 0x14, 0x00 }, + { WCD9335_CPE_SS_SS_ERROR_INT_MASK, 0x3f, 0x00 }, + { WCD9335_SOC_MAD_AUDIO_IIR_CTL_VAL, 0x00, 0x00 }, + { WCD9335_BIAS_VBG_FINE_ADJ, 0x55, 0x00 }, + { WCD9335_SIDO_SIDO_CCL_2, 0x6c, 0x00 }, + { WCD9335_SIDO_SIDO_CCL_3, 0x2d, 0x00 }, + { WCD9335_SIDO_SIDO_CCL_8, 0x6c, 0x00 }, + { WCD9335_SIDO_SIDO_CCL_10, 0x6c, 0x00 }, + { WCD9335_SIDO_SIDO_DRIVER_2, 0x77, 0x00 }, + { WCD9335_SIDO_SIDO_DRIVER_3, 0x77, 0x00 }, + { WCD9335_SIDO_SIDO_TEST_2, 0x00, 0x00 }, + { WCD9335_MBHC_ZDET_ANA_CTL, 0x00, 0x00 }, + { WCD9335_MBHC_FSM_DEBUG, 0xc0, 0x00 }, + { WCD9335_TX_1_2_ATEST_REFCTL, 0x08, 0x00 }, + { WCD9335_TX_3_4_ATEST_REFCTL, 0x08, 0x00 }, + { WCD9335_TX_5_6_ATEST_REFCTL, 0x08, 0x00 }, + { WCD9335_FLYBACK_VNEG_CTRL_1, 0x67, 0x00 }, + { WCD9335_FLYBACK_VNEG_CTRL_4, 0x5f, 0x00 }, + { WCD9335_FLYBACK_VNEG_CTRL_9, 0x50, 0x00 }, + { WCD9335_FLYBACK_VNEG_DAC_CTRL_1, 0x65, 0x00 }, + { WCD9335_FLYBACK_VNEG_DAC_CTRL_4, 0x40, 0x00 }, + { WCD9335_RX_BIAS_HPH_PA, 0xaa, 0x00 }, + { WCD9335_RX_BIAS_HPH_LOWPOWER, 0x62, 0x00 }, + { WCD9335_HPH_PA_CTL2, 0x40, 0x00 }, + { WCD9335_HPH_L_EN, 0x00, 0x00 }, + { WCD9335_HPH_R_EN, 0x00, 0x00 }, + { WCD9335_HPH_R_ATEST, 0x50, 0x00 }, + { WCD9335_HPH_RDAC_LDO_CTL, 0x00, 0x00 }, + { WCD9335_CDC_TX0_TX_PATH_CFG0, 0x00, 0x00 }, + { WCD9335_CDC_TX0_TX_PATH_CFG1, 0x00, 0x00 }, + { WCD9335_CDC_TX0_TX_PATH_SEC2, 0x00, 0x00 }, + { WCD9335_CDC_TX0_TX_PATH_SEC3, 0x0c, 0x00 }, + { WCD9335_CDC_TX1_TX_PATH_CFG0, 0x00, 0x00 }, + { WCD9335_CDC_TX1_TX_PATH_CFG1, 0x00, 0x00 }, + { WCD9335_CDC_TX1_TX_PATH_SEC2, 0x00, 0x00 }, + { WCD9335_CDC_TX1_TX_PATH_SEC3, 0x0c, 0x00 }, + { WCD9335_CDC_TX2_TX_PATH_CFG0, 0x00, 0x00 }, + { WCD9335_CDC_TX3_TX_PATH_CFG0, 0x00, 0x00 }, + { WCD9335_CDC_TX4_TX_PATH_CFG0, 0x00, 0x00 }, + { WCD9335_CDC_TX5_TX_PATH_CFG0, 0x00, 0x00 }, + { WCD9335_CDC_TX6_TX_PATH_CFG0, 0x00, 0x00 }, + { WCD9335_CDC_TX7_TX_PATH_CFG0, 0x00, 0x00 }, + { WCD9335_CDC_TX8_TX_PATH_CFG0, 0x00, 0x00 }, + { WCD9335_CDC_TX2_TX_PATH_CFG1, 0x00, 0x00 }, + { WCD9335_CDC_TX3_TX_PATH_CFG1, 0x00, 0x00 }, + { WCD9335_CDC_TX4_TX_PATH_CFG1, 0x00, 0x00 }, + { WCD9335_CDC_TX5_TX_PATH_CFG1, 0x00, 0x00 }, + { WCD9335_CDC_TX6_TX_PATH_CFG1, 0x00, 0x00 }, + { WCD9335_CDC_TX7_TX_PATH_CFG1, 0x00, 0x00 }, + { WCD9335_CDC_TX8_TX_PATH_CFG1, 0x00, 0x00 }, + { WCD9335_CDC_TX2_TX_PATH_SEC2, 0x00, 0x00 }, + { WCD9335_CDC_TX3_TX_PATH_SEC2, 0x00, 0x00 }, + { WCD9335_CDC_TX4_TX_PATH_SEC2, 0x00, 0x00 }, + { WCD9335_CDC_TX5_TX_PATH_SEC2, 0x00, 0x00 }, + { WCD9335_CDC_TX6_TX_PATH_SEC2, 0x00, 0x00 }, + { WCD9335_CDC_TX7_TX_PATH_SEC2, 0x00, 0x00 }, + { WCD9335_CDC_TX8_TX_PATH_SEC2, 0x00, 0x00 }, + { WCD9335_CDC_TX2_TX_PATH_SEC3, 0x0c, 0x00 }, + { WCD9335_CDC_TX3_TX_PATH_SEC3, 0x0c, 0x00 }, + { WCD9335_CDC_TX4_TX_PATH_SEC3, 0x0c, 0x00 }, + { WCD9335_CDC_TX5_TX_PATH_SEC3, 0x0c, 0x00 }, + { WCD9335_CDC_TX6_TX_PATH_SEC3, 0x0c, 0x00 }, + { WCD9335_CDC_TX7_TX_PATH_SEC3, 0x0c, 0x00 }, + { WCD9335_CDC_TX8_TX_PATH_SEC3, 0x0c, 0x00 }, + { WCD9335_CDC_COMPANDER1_CTL7, 0x0c, 0x00 }, + { WCD9335_CDC_COMPANDER2_CTL7, 0x0c, 0x00 }, + { WCD9335_CDC_COMPANDER3_CTL7, 0x0c, 0x00 }, + { WCD9335_CDC_COMPANDER4_CTL7, 0x0c, 0x00 }, + { WCD9335_CDC_COMPANDER5_CTL7, 0x0c, 0x00 }, + { WCD9335_CDC_COMPANDER6_CTL7, 0x0c, 0x00 }, + { WCD9335_CDC_COMPANDER7_CTL7, 0x0c, 0x00 }, + { WCD9335_CDC_COMPANDER8_CTL7, 0x0c, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_CFG1, 0x04, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 0x0e, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_SEC1, 0x00, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_MIX_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_CFG1, 0x04, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 0x0e, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_SEC1, 0x00, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_MIX_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_CFG1, 0x04, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 0x0e, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_SEC1, 0x00, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_MIX_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_CFG1, 0x04, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 0x0e, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_SEC1, 0x00, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_MIX_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_CFG1, 0x04, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 0x0e, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_SEC1, 0x00, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_MIX_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_CFG1, 0x04, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 0x0e, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_SEC1, 0x00, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_MIX_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_CFG1, 0x04, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 0x0e, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_SEC1, 0x00, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_MIX_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_CFG1, 0x04, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 0x0e, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_SEC1, 0x00, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_CFG1, 0x04, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 0x0e, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_SEC0, 0x00, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_SEC1, 0x00, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, 0x00, 0x00 }, + { WCD9335_SPLINE_SRC0_CLK_RST_CTL_0, 0x00, 0x00 }, + { WCD9335_SPLINE_SRC1_CLK_RST_CTL_0, 0x00, 0x00 }, + { WCD9335_SPLINE_SRC2_CLK_RST_CTL_0, 0x00, 0x00 }, + { WCD9335_SPLINE_SRC3_CLK_RST_CTL_0, 0x00, 0x00 }, + { WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00, 0x00 }, + { WCD9335_TEST_DEBUG_NPL_DLY_TEST_1, 0x00, 0x00 }, + { WCD9335_TEST_DEBUG_NPL_DLY_TEST_2, 0x00, 0x00 }, +}; + +static const struct reg_sequence wcd9335_2_0_defaults[] = { + { WCD9335_CODEC_RPM_CLK_GATE, 0x07, 0x00 }, + { WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN, 0x3f, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0, 0x01, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x10, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_RX0_INP_CFG, 0x08, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_RX1_INP_CFG, 0x08, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_RX2_INP_CFG, 0x08, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_RX3_INP_CFG, 0x08, 0x00 }, + { WCD9335_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD, 0x13, 0x00 }, + { WCD9335_CPE_SS_SS_ERROR_INT_MASK, 0xff, 0x00 }, + { WCD9335_SOC_MAD_AUDIO_IIR_CTL_VAL, 0x40, 0x00 }, + { WCD9335_BIAS_VBG_FINE_ADJ, 0xc5, 0x00 }, + { WCD9335_SIDO_SIDO_CCL_2, 0x92, 0x00 }, + { WCD9335_SIDO_SIDO_CCL_3, 0x35, 0x00 }, + { WCD9335_SIDO_SIDO_CCL_8, 0x6e, 0x00 }, + { WCD9335_SIDO_SIDO_CCL_10, 0x6e, 0x00 }, + { WCD9335_SIDO_SIDO_DRIVER_2, 0x55, 0x00 }, + { WCD9335_SIDO_SIDO_DRIVER_3, 0x55, 0x00 }, + { WCD9335_SIDO_SIDO_TEST_2, 0x0f, 0x00 }, + { WCD9335_MBHC_ZDET_ANA_CTL, 0x0f, 0x00 }, + { WCD9335_TX_1_2_ATEST_REFCTL, 0x0a, 0x00 }, + { WCD9335_TX_3_4_ATEST_REFCTL, 0x0a, 0x00 }, + { WCD9335_TX_5_6_ATEST_REFCTL, 0x0a, 0x00 }, + { WCD9335_FLYBACK_VNEG_CTRL_1, 0xeb, 0x00 }, + { WCD9335_FLYBACK_VNEG_CTRL_4, 0x7f, 0x00 }, + { WCD9335_FLYBACK_VNEG_CTRL_9, 0x64, 0x00 }, + { WCD9335_FLYBACK_VNEG_DAC_CTRL_1, 0xed, 0x00 }, + { WCD9335_RX_BIAS_HPH_PA, 0x9a, 0x00 }, + { WCD9335_RX_BIAS_HPH_LOWPOWER, 0x82, 0x00 }, + { WCD9335_HPH_PA_CTL2, 0x50, 0x00 }, + { WCD9335_HPH_L_EN, 0x80, 0x00 }, + { WCD9335_HPH_R_EN, 0x80, 0x00 }, + { WCD9335_HPH_R_ATEST, 0x54, 0x00 }, + { WCD9335_HPH_RDAC_LDO_CTL, 0x33, 0x00 }, + { WCD9335_CDC_TX0_TX_PATH_CFG0, 0x10, 0x00 }, + { WCD9335_CDC_TX0_TX_PATH_CFG1, 0x02, 0x00 }, + { WCD9335_CDC_TX0_TX_PATH_SEC2, 0x01, 0x00 }, + { WCD9335_CDC_TX0_TX_PATH_SEC3, 0x3c, 0x00 }, + { WCD9335_CDC_TX1_TX_PATH_CFG0, 0x10, 0x00 }, + { WCD9335_CDC_TX1_TX_PATH_CFG1, 0x02, 0x00 }, + { WCD9335_CDC_TX1_TX_PATH_SEC2, 0x01, 0x00 }, + { WCD9335_CDC_TX1_TX_PATH_SEC3, 0x3c, 0x00 }, + { WCD9335_CDC_TX2_TX_PATH_CFG0, 0x10, 0x00 }, + { WCD9335_CDC_TX3_TX_PATH_CFG0, 0x10, 0x00 }, + { WCD9335_CDC_TX4_TX_PATH_CFG0, 0x10, 0x00 }, + { WCD9335_CDC_TX5_TX_PATH_CFG0, 0x10, 0x00 }, + { WCD9335_CDC_TX6_TX_PATH_CFG0, 0x10, 0x00 }, + { WCD9335_CDC_TX7_TX_PATH_CFG0, 0x10, 0x00 }, + { WCD9335_CDC_TX8_TX_PATH_CFG0, 0x10, 0x00 }, + { WCD9335_CDC_TX2_TX_PATH_CFG1, 0x02, 0x00 }, + { WCD9335_CDC_TX3_TX_PATH_CFG1, 0x02, 0x00 }, + { WCD9335_CDC_TX4_TX_PATH_CFG1, 0x02, 0x00 }, + { WCD9335_CDC_TX5_TX_PATH_CFG1, 0x02, 0x00 }, + { WCD9335_CDC_TX6_TX_PATH_CFG1, 0x02, 0x00 }, + { WCD9335_CDC_TX7_TX_PATH_CFG1, 0x02, 0x00 }, + { WCD9335_CDC_TX8_TX_PATH_CFG1, 0x02, 0x00 }, + { WCD9335_CDC_TX2_TX_PATH_SEC2, 0x01, 0x00 }, + { WCD9335_CDC_TX3_TX_PATH_SEC2, 0x01, 0x00 }, + { WCD9335_CDC_TX4_TX_PATH_SEC2, 0x01, 0x00 }, + { WCD9335_CDC_TX5_TX_PATH_SEC2, 0x01, 0x00 }, + { WCD9335_CDC_TX6_TX_PATH_SEC2, 0x01, 0x00 }, + { WCD9335_CDC_TX7_TX_PATH_SEC2, 0x01, 0x00 }, + { WCD9335_CDC_TX8_TX_PATH_SEC2, 0x01, 0x00 }, + { WCD9335_CDC_TX2_TX_PATH_SEC3, 0x3c, 0x00 }, + { WCD9335_CDC_TX3_TX_PATH_SEC3, 0x3c, 0x00 }, + { WCD9335_CDC_TX4_TX_PATH_SEC3, 0x3c, 0x00 }, + { WCD9335_CDC_TX5_TX_PATH_SEC3, 0x3c, 0x00 }, + { WCD9335_CDC_TX6_TX_PATH_SEC3, 0x3c, 0x00 }, + { WCD9335_CDC_TX7_TX_PATH_SEC3, 0x3c, 0x00 }, + { WCD9335_CDC_TX8_TX_PATH_SEC3, 0x3c, 0x00 }, + { WCD9335_CDC_COMPANDER1_CTL7, 0x08, 0x00 }, + { WCD9335_CDC_COMPANDER2_CTL7, 0x08, 0x00 }, + { WCD9335_CDC_COMPANDER3_CTL7, 0x08, 0x00 }, + { WCD9335_CDC_COMPANDER4_CTL7, 0x08, 0x00 }, + { WCD9335_CDC_COMPANDER5_CTL7, 0x08, 0x00 }, + { WCD9335_CDC_COMPANDER6_CTL7, 0x08, 0x00 }, + { WCD9335_CDC_COMPANDER7_CTL7, 0x08, 0x00 }, + { WCD9335_CDC_COMPANDER8_CTL7, 0x08, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_CFG1, 0x44, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 0x1e, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_SEC0, 0xfc, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_SEC1, 0x08, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_MIX_SEC0, 0x08, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_CFG1, 0x44, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 0x1e, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_SEC0, 0xfc, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_SEC1, 0x08, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_MIX_SEC0, 0x08, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_CFG1, 0x44, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 0x1e, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_SEC0, 0xfc, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_SEC1, 0x08, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_MIX_SEC0, 0x08, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_CFG1, 0x44, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 0x1e, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_SEC0, 0xfc, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_SEC1, 0x08, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_MIX_SEC0, 0x08, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_CFG1, 0x44, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 0x1e, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_SEC0, 0xfc, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_SEC1, 0x08, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_MIX_SEC0, 0x08, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_CFG1, 0x44, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 0x1e, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_SEC0, 0xfc, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_SEC1, 0x08, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_MIX_SEC0, 0x08, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_CFG1, 0x44, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 0x1e, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_SEC0, 0xfc, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_SEC1, 0x08, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_MIX_SEC0, 0x08, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_CFG1, 0x44, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 0x1e, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_SEC0, 0xfc, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_SEC1, 0x08, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, 0x08, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_CFG1, 0x44, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 0x1e, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_SEC0, 0xfc, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_SEC1, 0x08, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, 0x08, 0x00 }, + { WCD9335_SPLINE_SRC0_CLK_RST_CTL_0, 0x20, 0x00 }, + { WCD9335_SPLINE_SRC1_CLK_RST_CTL_0, 0x20, 0x00 }, + { WCD9335_SPLINE_SRC2_CLK_RST_CTL_0, 0x20, 0x00 }, + { WCD9335_SPLINE_SRC3_CLK_RST_CTL_0, 0x20, 0x00 }, + { WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x0c, 0x00 }, + { WCD9335_TEST_DEBUG_NPL_DLY_TEST_1, 0x10, 0x00 }, + { WCD9335_TEST_DEBUG_NPL_DLY_TEST_2, 0x60, 0x00 }, + { WCD9335_DATA_HUB_NATIVE_FIFO_SYNC, 0x00, 0x00 }, + { WCD9335_DATA_HUB_NATIVE_FIFO_STATUS, 0x00, 0x00 }, + { WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD, 0x60, 0x00 }, + { WCD9335_CPE_SS_TX_PP_CFG, 0x3C, 0x00 }, + { WCD9335_CPE_SS_SVA_CFG, 0x00, 0x00 }, + { WCD9335_MBHC_FSM_STATUS, 0x00, 0x00 }, + { WCD9335_FLYBACK_CTRL_1, 0x45, 0x00 }, + { WCD9335_CDC_TX0_TX_PATH_SEC7, 0x25, 0x00 }, + { WCD9335_SPLINE_SRC0_STATUS, 0x00, 0x00 }, + { WCD9335_SPLINE_SRC1_STATUS, 0x00, 0x00 }, + { WCD9335_SPLINE_SRC2_STATUS, 0x00, 0x00 }, + { WCD9335_SPLINE_SRC3_STATUS, 0x00, 0x00 }, + { WCD9335_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT, 0x00, 0x00 }, +}; + +static const struct reg_default wcd9335_defaults[] = { + /* Page #0 registers */ + { WCD9335_PAGE0_PAGE_REGISTER, 0x00 }, + { WCD9335_CODEC_RPM_CLK_BYPASS, 0x00 }, + { WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x00 }, + { WCD9335_CODEC_RPM_RST_CTL, 0x00 }, + { WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x07 }, + { WCD9335_CODEC_RPM_PWR_CPE_DEEPSLP_1, 0x00 }, + { WCD9335_CODEC_RPM_PWR_CPE_DEEPSLP_2, 0x00 }, + { WCD9335_CODEC_RPM_PWR_CPE_DEEPSLP_3, 0x00 }, + { WCD9335_CODEC_RPM_PWR_CPE_IRAM_SHUTDOWN, 0x01 }, + { WCD9335_CODEC_RPM_PWR_CPE_DRAM0_SHUTDOWN_1, 0xff }, + { WCD9335_CODEC_RPM_PWR_CPE_DRAM0_SHUTDOWN_2, 0xff }, + { WCD9335_CODEC_RPM_INT_MASK, 0x3f }, + { WCD9335_CODEC_RPM_INT_STATUS, 0x00 }, + { WCD9335_CODEC_RPM_INT_CLEAR, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE1, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE2, 0x07 }, + { WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE3, 0x01 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_TEST0, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_TEST1, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT1, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT2, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT3, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT4, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT5, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT6, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT7, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT8, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT9, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT10, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT11, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT12, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT13, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT14, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT15, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO, 0x0d }, + { WCD9335_CHIP_TIER_CTRL_I2C_SLAVE_ID_1, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_I2C_SLAVE_ID_2, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_I2C_SLAVE_ID_3, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL, 0xCC }, + { WCD9335_CHIP_TIER_CTRL_I2C_ACTIVE, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_PROC1_MON_CTL, 0x06 }, + { WCD9335_CHIP_TIER_CTRL_PROC1_MON_STATUS, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_PROC1_MON_CNT_MSB, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_PROC1_MON_CNT_LSB, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_PROC2_MON_CTL, 0x06 }, + { WCD9335_CHIP_TIER_CTRL_PROC2_MON_STATUS, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_PROC2_MON_CNT_MSB, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_PROC2_MON_CNT_LSB, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_PROC3_MON_CTL, 0x06 }, + { WCD9335_CHIP_TIER_CTRL_PROC3_MON_STATUS, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_PROC3_MON_CNT_MSB, 0x00 }, + { WCD9335_CHIP_TIER_CTRL_PROC3_MON_CNT_LSB, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL, 0x0c }, + { WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL, 0x0c }, + { WCD9335_DATA_HUB_DATA_HUB_I2S_CLK, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_RX4_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_RX5_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_RX6_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_RX7_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_SB_TX0_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_SB_TX1_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_SB_TX2_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_SB_TX3_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_SB_TX4_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_SB_TX5_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_SB_TX6_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_SB_TX7_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_SB_TX8_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_SB_TX9_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_SB_TX10_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_SB_TX11_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_SB_TX14_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_SB_TX15_INP_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG, 0x00 }, + { WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG, 0x00 }, + { WCD9335_INTR_CFG, 0x00 }, + { WCD9335_INTR_CLR_COMMIT, 0x00 }, + { WCD9335_INTR_PIN1_MASK0, 0xff }, + { WCD9335_INTR_PIN1_MASK1, 0xff }, + { WCD9335_INTR_PIN1_MASK2, 0xff }, + { WCD9335_INTR_PIN1_MASK3, 0xff }, + { WCD9335_INTR_PIN1_STATUS0, 0x00 }, + { WCD9335_INTR_PIN1_STATUS1, 0x00 }, + { WCD9335_INTR_PIN1_STATUS2, 0x00 }, + { WCD9335_INTR_PIN1_STATUS3, 0x00 }, + { WCD9335_INTR_PIN1_CLEAR0, 0x00 }, + { WCD9335_INTR_PIN1_CLEAR1, 0x00 }, + { WCD9335_INTR_PIN1_CLEAR2, 0x00 }, + { WCD9335_INTR_PIN1_CLEAR3, 0x00 }, + { WCD9335_INTR_PIN2_MASK0, 0xff }, + { WCD9335_INTR_PIN2_MASK1, 0xff }, + { WCD9335_INTR_PIN2_MASK2, 0xff }, + { WCD9335_INTR_PIN2_MASK3, 0xff }, + { WCD9335_INTR_PIN2_STATUS0, 0x00 }, + { WCD9335_INTR_PIN2_STATUS1, 0x00 }, + { WCD9335_INTR_PIN2_STATUS2, 0x00 }, + { WCD9335_INTR_PIN2_STATUS3, 0x00 }, + { WCD9335_INTR_PIN2_CLEAR0, 0x00 }, + { WCD9335_INTR_PIN2_CLEAR1, 0x00 }, + { WCD9335_INTR_PIN2_CLEAR2, 0x00 }, + { WCD9335_INTR_PIN2_CLEAR3, 0x00 }, + { WCD9335_INTR_LEVEL0, 0x03 }, + { WCD9335_INTR_LEVEL1, 0xe0 }, + { WCD9335_INTR_LEVEL2, 0x10 }, + { WCD9335_INTR_LEVEL3, 0x80 }, + { WCD9335_INTR_BYPASS0, 0x00 }, + { WCD9335_INTR_BYPASS1, 0x00 }, + { WCD9335_INTR_BYPASS2, 0x00 }, + { WCD9335_INTR_BYPASS3, 0x00 }, + { WCD9335_INTR_SET0, 0x00 }, + { WCD9335_INTR_SET1, 0x00 }, + { WCD9335_INTR_SET2, 0x00 }, + { WCD9335_INTR_SET3, 0x00 }, + /* Page #1 registers */ + { WCD9335_PAGE1_PAGE_REGISTER, 0x00 }, + { WCD9335_CPE_FLL_USER_CTL_0, 0x71 }, + { WCD9335_CPE_FLL_USER_CTL_1, 0x34 }, + { WCD9335_CPE_FLL_USER_CTL_2, 0x0b }, + { WCD9335_CPE_FLL_USER_CTL_3, 0x02 }, + { WCD9335_CPE_FLL_USER_CTL_4, 0x04 }, + { WCD9335_CPE_FLL_USER_CTL_5, 0x02 }, + { WCD9335_CPE_FLL_USER_CTL_6, 0x64 }, + { WCD9335_CPE_FLL_USER_CTL_7, 0x00 }, + { WCD9335_CPE_FLL_USER_CTL_8, 0x94 }, + { WCD9335_CPE_FLL_USER_CTL_9, 0x70 }, + { WCD9335_CPE_FLL_L_VAL_CTL_0, 0x40 }, + { WCD9335_CPE_FLL_L_VAL_CTL_1, 0x00 }, + { WCD9335_CPE_FLL_DSM_FRAC_CTL_0, 0x00 }, + { WCD9335_CPE_FLL_DSM_FRAC_CTL_1, 0xff }, + { WCD9335_CPE_FLL_CONFIG_CTL_0, 0x6b }, + { WCD9335_CPE_FLL_CONFIG_CTL_1, 0x05 }, + { WCD9335_CPE_FLL_CONFIG_CTL_2, 0x08 }, + { WCD9335_CPE_FLL_CONFIG_CTL_3, 0x00 }, + { WCD9335_CPE_FLL_CONFIG_CTL_4, 0x10 }, + { WCD9335_CPE_FLL_TEST_CTL_0, 0x00 }, + { WCD9335_CPE_FLL_TEST_CTL_1, 0x00 }, + { WCD9335_CPE_FLL_TEST_CTL_2, 0x00 }, + { WCD9335_CPE_FLL_TEST_CTL_3, 0x00 }, + { WCD9335_CPE_FLL_TEST_CTL_4, 0x00 }, + { WCD9335_CPE_FLL_TEST_CTL_5, 0x00 }, + { WCD9335_CPE_FLL_TEST_CTL_6, 0x00 }, + { WCD9335_CPE_FLL_TEST_CTL_7, 0x33 }, + { WCD9335_CPE_FLL_FREQ_CTL_0, 0x00 }, + { WCD9335_CPE_FLL_FREQ_CTL_1, 0x00 }, + { WCD9335_CPE_FLL_FREQ_CTL_2, 0x00 }, + { WCD9335_CPE_FLL_FREQ_CTL_3, 0x00 }, + { WCD9335_CPE_FLL_SSC_CTL_0, 0x00 }, + { WCD9335_CPE_FLL_SSC_CTL_1, 0x00 }, + { WCD9335_CPE_FLL_SSC_CTL_2, 0x00 }, + { WCD9335_CPE_FLL_SSC_CTL_3, 0x00 }, + { WCD9335_CPE_FLL_FLL_MODE, 0x20 }, + { WCD9335_CPE_FLL_STATUS_0, 0x00 }, + { WCD9335_CPE_FLL_STATUS_1, 0x00 }, + { WCD9335_CPE_FLL_STATUS_2, 0x00 }, + { WCD9335_CPE_FLL_STATUS_3, 0x00 }, + { WCD9335_I2S_FLL_USER_CTL_0, 0x41 }, + { WCD9335_I2S_FLL_USER_CTL_1, 0x94 }, + { WCD9335_I2S_FLL_USER_CTL_2, 0x08 }, + { WCD9335_I2S_FLL_USER_CTL_3, 0x02 }, + { WCD9335_I2S_FLL_USER_CTL_4, 0x04 }, + { WCD9335_I2S_FLL_USER_CTL_5, 0x02 }, + { WCD9335_I2S_FLL_USER_CTL_6, 0x40 }, + { WCD9335_I2S_FLL_USER_CTL_7, 0x00 }, + { WCD9335_I2S_FLL_USER_CTL_8, 0x5f }, + { WCD9335_I2S_FLL_USER_CTL_9, 0x02 }, + { WCD9335_I2S_FLL_L_VAL_CTL_0, 0x40 }, + { WCD9335_I2S_FLL_L_VAL_CTL_1, 0x00 }, + { WCD9335_I2S_FLL_DSM_FRAC_CTL_0, 0x00 }, + { WCD9335_I2S_FLL_DSM_FRAC_CTL_1, 0xff }, + { WCD9335_I2S_FLL_CONFIG_CTL_0, 0x6b }, + { WCD9335_I2S_FLL_CONFIG_CTL_1, 0x05 }, + { WCD9335_I2S_FLL_CONFIG_CTL_2, 0x08 }, + { WCD9335_I2S_FLL_CONFIG_CTL_3, 0x00 }, + { WCD9335_I2S_FLL_CONFIG_CTL_4, 0x30 }, + { WCD9335_I2S_FLL_TEST_CTL_0, 0x80 }, + { WCD9335_I2S_FLL_TEST_CTL_1, 0x00 }, + { WCD9335_I2S_FLL_TEST_CTL_2, 0x00 }, + { WCD9335_I2S_FLL_TEST_CTL_3, 0x00 }, + { WCD9335_I2S_FLL_TEST_CTL_4, 0x00 }, + { WCD9335_I2S_FLL_TEST_CTL_5, 0x00 }, + { WCD9335_I2S_FLL_TEST_CTL_6, 0x00 }, + { WCD9335_I2S_FLL_TEST_CTL_7, 0xff }, + { WCD9335_I2S_FLL_FREQ_CTL_0, 0x00 }, + { WCD9335_I2S_FLL_FREQ_CTL_1, 0x00 }, + { WCD9335_I2S_FLL_FREQ_CTL_2, 0x00 }, + { WCD9335_I2S_FLL_FREQ_CTL_3, 0x00 }, + { WCD9335_I2S_FLL_SSC_CTL_0, 0x00 }, + { WCD9335_I2S_FLL_SSC_CTL_1, 0x00 }, + { WCD9335_I2S_FLL_SSC_CTL_2, 0x00 }, + { WCD9335_I2S_FLL_SSC_CTL_3, 0x00 }, + { WCD9335_I2S_FLL_FLL_MODE, 0x00 }, + { WCD9335_I2S_FLL_STATUS_0, 0x00 }, + { WCD9335_I2S_FLL_STATUS_1, 0x00 }, + { WCD9335_I2S_FLL_STATUS_2, 0x00 }, + { WCD9335_I2S_FLL_STATUS_3, 0x00 }, + { WCD9335_SB_FLL_USER_CTL_0, 0x41 }, + { WCD9335_SB_FLL_USER_CTL_1, 0x94 }, + { WCD9335_SB_FLL_USER_CTL_2, 0x08 }, + { WCD9335_SB_FLL_USER_CTL_3, 0x02 }, + { WCD9335_SB_FLL_USER_CTL_4, 0x04 }, + { WCD9335_SB_FLL_USER_CTL_5, 0x02 }, + { WCD9335_SB_FLL_USER_CTL_6, 0x40 }, + { WCD9335_SB_FLL_USER_CTL_7, 0x00 }, + { WCD9335_SB_FLL_USER_CTL_8, 0x5e }, + { WCD9335_SB_FLL_USER_CTL_9, 0x01 }, + { WCD9335_SB_FLL_L_VAL_CTL_0, 0x40 }, + { WCD9335_SB_FLL_L_VAL_CTL_1, 0x00 }, + { WCD9335_SB_FLL_DSM_FRAC_CTL_0, 0x00 }, + { WCD9335_SB_FLL_DSM_FRAC_CTL_1, 0xff }, + { WCD9335_SB_FLL_CONFIG_CTL_0, 0x6b }, + { WCD9335_SB_FLL_CONFIG_CTL_1, 0x05 }, + { WCD9335_SB_FLL_CONFIG_CTL_2, 0x08 }, + { WCD9335_SB_FLL_CONFIG_CTL_3, 0x00 }, + { WCD9335_SB_FLL_CONFIG_CTL_4, 0x10 }, + { WCD9335_SB_FLL_TEST_CTL_0, 0x00 }, + { WCD9335_SB_FLL_TEST_CTL_1, 0x00 }, + { WCD9335_SB_FLL_TEST_CTL_2, 0x00 }, + { WCD9335_SB_FLL_TEST_CTL_3, 0x00 }, + { WCD9335_SB_FLL_TEST_CTL_4, 0x00 }, + { WCD9335_SB_FLL_TEST_CTL_5, 0x00 }, + { WCD9335_SB_FLL_TEST_CTL_6, 0x00 }, + { WCD9335_SB_FLL_TEST_CTL_7, 0xff }, + { WCD9335_SB_FLL_FREQ_CTL_0, 0x00 }, + { WCD9335_SB_FLL_FREQ_CTL_1, 0x00 }, + { WCD9335_SB_FLL_FREQ_CTL_2, 0x00 }, + { WCD9335_SB_FLL_FREQ_CTL_3, 0x00 }, + { WCD9335_SB_FLL_SSC_CTL_0, 0x00 }, + { WCD9335_SB_FLL_SSC_CTL_1, 0x00 }, + { WCD9335_SB_FLL_SSC_CTL_2, 0x00 }, + { WCD9335_SB_FLL_SSC_CTL_3, 0x00 }, + { WCD9335_SB_FLL_FLL_MODE, 0x00 }, + { WCD9335_SB_FLL_STATUS_0, 0x00 }, + { WCD9335_SB_FLL_STATUS_1, 0x00 }, + { WCD9335_SB_FLL_STATUS_2, 0x00 }, + { WCD9335_SB_FLL_STATUS_3, 0x00 }, + /* Page #2 registers */ + { WCD9335_PAGE2_PAGE_REGISTER, 0x00 }, + { WCD9335_CPE_SS_MEM_PTR_0, 0x00 }, + { WCD9335_CPE_SS_MEM_PTR_1, 0x00 }, + { WCD9335_CPE_SS_MEM_PTR_2, 0x00 }, + { WCD9335_CPE_SS_MEM_CTRL, 0x08 }, + { WCD9335_CPE_SS_MEM_BANK_0, 0x00 }, + { WCD9335_CPE_SS_MEM_BANK_1, 0x00 }, + { WCD9335_CPE_SS_MEM_BANK_2, 0x00 }, + { WCD9335_CPE_SS_MEM_BANK_3, 0x00 }, + { WCD9335_CPE_SS_MEM_BANK_4, 0x00 }, + { WCD9335_CPE_SS_MEM_BANK_5, 0x00 }, + { WCD9335_CPE_SS_MEM_BANK_6, 0x00 }, + { WCD9335_CPE_SS_MEM_BANK_7, 0x00 }, + { WCD9335_CPE_SS_MEM_BANK_8, 0x00 }, + { WCD9335_CPE_SS_MEM_BANK_9, 0x00 }, + { WCD9335_CPE_SS_MEM_BANK_10, 0x00 }, + { WCD9335_CPE_SS_MEM_BANK_11, 0x00 }, + { WCD9335_CPE_SS_MEM_BANK_12, 0x00 }, + { WCD9335_CPE_SS_MEM_BANK_13, 0x00 }, + { WCD9335_CPE_SS_MEM_BANK_14, 0x00 }, + { WCD9335_CPE_SS_MEM_BANK_15, 0x00 }, + { WCD9335_CPE_SS_INBOX1_TRG, 0x00 }, + { WCD9335_CPE_SS_INBOX2_TRG, 0x00 }, + { WCD9335_CPE_SS_INBOX1_0, 0x00 }, + { WCD9335_CPE_SS_INBOX1_1, 0x00 }, + { WCD9335_CPE_SS_INBOX1_2, 0x00 }, + { WCD9335_CPE_SS_INBOX1_3, 0x00 }, + { WCD9335_CPE_SS_INBOX1_4, 0x00 }, + { WCD9335_CPE_SS_INBOX1_5, 0x00 }, + { WCD9335_CPE_SS_INBOX1_6, 0x00 }, + { WCD9335_CPE_SS_INBOX1_7, 0x00 }, + { WCD9335_CPE_SS_INBOX1_8, 0x00 }, + { WCD9335_CPE_SS_INBOX1_9, 0x00 }, + { WCD9335_CPE_SS_INBOX1_10, 0x00 }, + { WCD9335_CPE_SS_INBOX1_11, 0x00 }, + { WCD9335_CPE_SS_INBOX1_12, 0x00 }, + { WCD9335_CPE_SS_INBOX1_13, 0x00 }, + { WCD9335_CPE_SS_INBOX1_14, 0x00 }, + { WCD9335_CPE_SS_INBOX1_15, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_0, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_1, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_2, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_3, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_4, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_5, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_6, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_7, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_8, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_9, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_10, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_11, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_12, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_13, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_14, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_15, 0x00 }, + { WCD9335_CPE_SS_INBOX2_0, 0x00 }, + { WCD9335_CPE_SS_INBOX2_1, 0x00 }, + { WCD9335_CPE_SS_INBOX2_2, 0x00 }, + { WCD9335_CPE_SS_INBOX2_3, 0x00 }, + { WCD9335_CPE_SS_INBOX2_4, 0x00 }, + { WCD9335_CPE_SS_INBOX2_5, 0x00 }, + { WCD9335_CPE_SS_INBOX2_6, 0x00 }, + { WCD9335_CPE_SS_INBOX2_7, 0x00 }, + { WCD9335_CPE_SS_INBOX2_8, 0x00 }, + { WCD9335_CPE_SS_INBOX2_9, 0x00 }, + { WCD9335_CPE_SS_INBOX2_10, 0x00 }, + { WCD9335_CPE_SS_INBOX2_11, 0x00 }, + { WCD9335_CPE_SS_INBOX2_12, 0x00 }, + { WCD9335_CPE_SS_INBOX2_13, 0x00 }, + { WCD9335_CPE_SS_INBOX2_14, 0x00 }, + { WCD9335_CPE_SS_INBOX2_15, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_0, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_1, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_2, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_3, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_4, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_5, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_6, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_7, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_8, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_9, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_10, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_11, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_12, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_13, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_14, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_15, 0x00 }, + { WCD9335_CPE_SS_OUTBOX1_ACK, 0x00 }, + { WCD9335_CPE_SS_OUTBOX2_ACK, 0x00 }, + { WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x3c }, + { WCD9335_CPE_SS_US_BUF_INT_PERIOD, 0x60 }, + { WCD9335_CPE_SS_CFG, 0x41 }, + { WCD9335_CPE_SS_US_EC_MUX_CFG, 0x00 }, + { WCD9335_CPE_SS_MAD_CTL, 0x00 }, + { WCD9335_CPE_SS_CPAR_CTL, 0x00 }, + { WCD9335_CPE_SS_DMIC0_CTL, 0x00 }, + { WCD9335_CPE_SS_DMIC1_CTL, 0x00 }, + { WCD9335_CPE_SS_DMIC2_CTL, 0x00 }, + { WCD9335_CPE_SS_DMIC_CFG, 0x80 }, + { WCD9335_CPE_SS_CPAR_CFG, 0x00 }, + { WCD9335_CPE_SS_WDOG_CFG, 0x01 }, + { WCD9335_CPE_SS_BACKUP_INT, 0x00 }, + { WCD9335_CPE_SS_STATUS, 0x00 }, + { WCD9335_CPE_SS_CPE_OCD_CFG, 0x00 }, + { WCD9335_CPE_SS_SS_ERROR_INT_STATUS, 0x00 }, + { WCD9335_CPE_SS_SS_ERROR_INT_CLEAR, 0x00 }, + { WCD9335_SOC_MAD_MAIN_CTL_1, 0x00 }, + { WCD9335_SOC_MAD_MAIN_CTL_2, 0x00 }, + { WCD9335_SOC_MAD_AUDIO_CTL_1, 0x00 }, + { WCD9335_SOC_MAD_AUDIO_CTL_2, 0x00 }, + { WCD9335_SOC_MAD_AUDIO_CTL_3, 0x00 }, + { WCD9335_SOC_MAD_AUDIO_CTL_4, 0x00 }, + { WCD9335_SOC_MAD_AUDIO_CTL_5, 0x00 }, + { WCD9335_SOC_MAD_AUDIO_CTL_6, 0x00 }, + { WCD9335_SOC_MAD_AUDIO_CTL_7, 0x00 }, + { WCD9335_SOC_MAD_AUDIO_CTL_8, 0x00 }, + { WCD9335_SOC_MAD_AUDIO_IIR_CTL_PTR, 0x00 }, + { WCD9335_SOC_MAD_ULTR_CTL_1, 0x00 }, + { WCD9335_SOC_MAD_ULTR_CTL_2, 0x00 }, + { WCD9335_SOC_MAD_ULTR_CTL_3, 0x00 }, + { WCD9335_SOC_MAD_ULTR_CTL_4, 0x00 }, + { WCD9335_SOC_MAD_ULTR_CTL_5, 0x00 }, + { WCD9335_SOC_MAD_ULTR_CTL_6, 0x00 }, + { WCD9335_SOC_MAD_ULTR_CTL_7, 0x00 }, + { WCD9335_SOC_MAD_BEACON_CTL_1, 0x00 }, + { WCD9335_SOC_MAD_BEACON_CTL_2, 0x00 }, + { WCD9335_SOC_MAD_BEACON_CTL_3, 0x00 }, + { WCD9335_SOC_MAD_BEACON_CTL_4, 0x00 }, + { WCD9335_SOC_MAD_BEACON_CTL_5, 0x00 }, + { WCD9335_SOC_MAD_BEACON_CTL_6, 0x00 }, + { WCD9335_SOC_MAD_BEACON_CTL_7, 0x00 }, + { WCD9335_SOC_MAD_BEACON_CTL_8, 0x00 }, + { WCD9335_SOC_MAD_BEACON_IIR_CTL_PTR, 0x00 }, + { WCD9335_SOC_MAD_BEACON_IIR_CTL_VAL, 0x00 }, + { WCD9335_SOC_MAD_INP_SEL, 0x00 }, + /* Page #6 registers */ + { WCD9335_PAGE6_PAGE_REGISTER, 0x00 }, + { WCD9335_ANA_BIAS, 0x00 }, + { WCD9335_ANA_CLK_TOP, 0x00 }, + { WCD9335_ANA_RCO, 0x30 }, + { WCD9335_ANA_BUCK_VOUT_A, 0xb4 }, + { WCD9335_ANA_BUCK_VOUT_D, 0xb4 }, + { WCD9335_ANA_BUCK_CTL, 0x00 }, + { WCD9335_ANA_BUCK_STATUS, 0xe0 }, + { WCD9335_ANA_RX_SUPPLIES, 0x00 }, + { WCD9335_ANA_HPH, 0x00 }, + { WCD9335_ANA_EAR, 0x00 }, + { WCD9335_ANA_LO_1_2, 0x00 }, + { WCD9335_ANA_LO_3_4, 0x00 }, + { WCD9335_ANA_MAD_SETUP, 0x81 }, + { WCD9335_ANA_AMIC1, 0x20 }, + { WCD9335_ANA_AMIC2, 0x00 }, + { WCD9335_ANA_AMIC3, 0x20 }, + { WCD9335_ANA_AMIC4, 0x00 }, + { WCD9335_ANA_AMIC5, 0x20 }, + { WCD9335_ANA_AMIC6, 0x00 }, + { WCD9335_ANA_MBHC_MECH, 0x39 }, + { WCD9335_ANA_MBHC_ELECT, 0x08 }, + { WCD9335_ANA_MBHC_ZDET, 0x00 }, + { WCD9335_ANA_MBHC_RESULT_1, 0x00 }, + { WCD9335_ANA_MBHC_RESULT_2, 0x00 }, + { WCD9335_ANA_MBHC_RESULT_3, 0x00 }, + { WCD9335_ANA_MBHC_BTN0, 0x00 }, + { WCD9335_ANA_MBHC_BTN1, 0x10 }, + { WCD9335_ANA_MBHC_BTN2, 0x20 }, + { WCD9335_ANA_MBHC_BTN3, 0x30 }, + { WCD9335_ANA_MBHC_BTN4, 0x40 }, + { WCD9335_ANA_MBHC_BTN5, 0x50 }, + { WCD9335_ANA_MBHC_BTN6, 0x60 }, + { WCD9335_ANA_MBHC_BTN7, 0x70 }, + { WCD9335_ANA_MICB1, 0x10 }, + { WCD9335_ANA_MICB2, 0x10 }, + { WCD9335_ANA_MICB2_RAMP, 0x00 }, + { WCD9335_ANA_MICB3, 0x10 }, + { WCD9335_ANA_MICB4, 0x10 }, + { WCD9335_ANA_VBADC, 0x00 }, + { WCD9335_BIAS_CTL, 0x28 }, + { WCD9335_CLOCK_TEST_CTL, 0x00 }, + { WCD9335_RCO_CTRL_1, 0x44 }, + { WCD9335_RCO_CTRL_2, 0x44 }, + { WCD9335_RCO_CAL, 0x00 }, + { WCD9335_RCO_CAL_1, 0x00 }, + { WCD9335_RCO_CAL_2, 0x00 }, + { WCD9335_RCO_TEST_CTRL, 0x00 }, + { WCD9335_RCO_CAL_OUT_1, 0x00 }, + { WCD9335_RCO_CAL_OUT_2, 0x00 }, + { WCD9335_RCO_CAL_OUT_3, 0x00 }, + { WCD9335_RCO_CAL_OUT_4, 0x00 }, + { WCD9335_RCO_CAL_OUT_5, 0x00 }, + { WCD9335_SIDO_SIDO_MODE_1, 0x84 }, + { WCD9335_SIDO_SIDO_MODE_2, 0xfe }, + { WCD9335_SIDO_SIDO_MODE_3, 0xf6 }, + { WCD9335_SIDO_SIDO_MODE_4, 0x56 }, + { WCD9335_SIDO_SIDO_VCL_1, 0x00 }, + { WCD9335_SIDO_SIDO_VCL_2, 0x6c }, + { WCD9335_SIDO_SIDO_VCL_3, 0x44 }, + { WCD9335_SIDO_SIDO_CCL_1, 0x57 }, + { WCD9335_SIDO_SIDO_CCL_4, 0x61 }, + { WCD9335_SIDO_SIDO_CCL_5, 0x6d }, + { WCD9335_SIDO_SIDO_CCL_6, 0x60 }, + { WCD9335_SIDO_SIDO_CCL_7, 0x6f }, + { WCD9335_SIDO_SIDO_CCL_9, 0x6e }, + { WCD9335_SIDO_SIDO_FILTER_1, 0x92 }, + { WCD9335_SIDO_SIDO_FILTER_2, 0x54 }, + { WCD9335_SIDO_SIDO_DRIVER_1, 0x77 }, + { WCD9335_SIDO_SIDO_CAL_CODE_EXT_1, 0x9c }, + { WCD9335_SIDO_SIDO_CAL_CODE_EXT_2, 0x82 }, + { WCD9335_SIDO_SIDO_CAL_CODE_OUT_1, 0x00 }, + { WCD9335_SIDO_SIDO_CAL_CODE_OUT_2, 0x00 }, + { WCD9335_SIDO_SIDO_TEST_1, 0x00 }, + { WCD9335_MBHC_CTL_1, 0x32 }, + { WCD9335_MBHC_CTL_2, 0x01 }, + { WCD9335_MBHC_PLUG_DETECT_CTL, 0x69 }, + { WCD9335_MBHC_ZDET_RAMP_CTL, 0x00 }, + { WCD9335_MBHC_TEST_CTL, 0x00 }, + { WCD9335_VBADC_SUBBLOCK_EN, 0xfe }, + { WCD9335_VBADC_IBIAS_FE, 0x54 }, + { WCD9335_VBADC_BIAS_ADC, 0x51 }, + { WCD9335_VBADC_FE_CTRL, 0x1c }, + { WCD9335_VBADC_ADC_REF, 0x20 }, + { WCD9335_VBADC_ADC_IO, 0x80 }, + { WCD9335_VBADC_ADC_SAR, 0xff }, + { WCD9335_VBADC_DEBUG, 0x00 }, + { WCD9335_VBADC_ADC_DOUTMSB, 0x00 }, + { WCD9335_VBADC_ADC_DOUTLSB, 0x00 }, + { WCD9335_LDOH_MODE, 0x2b }, + { WCD9335_LDOH_BIAS, 0x68 }, + { WCD9335_LDOH_STB_LOADS, 0x00 }, + { WCD9335_LDOH_SLOWRAMP, 0x50 }, + { WCD9335_MICB1_TEST_CTL_1, 0x1a }, + { WCD9335_MICB1_TEST_CTL_2, 0x18 }, + { WCD9335_MICB1_TEST_CTL_3, 0xa4 }, + { WCD9335_MICB2_TEST_CTL_1, 0x1a }, + { WCD9335_MICB2_TEST_CTL_2, 0x18 }, + { WCD9335_MICB2_TEST_CTL_3, 0x24 }, + { WCD9335_MICB3_TEST_CTL_1, 0x1a }, + { WCD9335_MICB3_TEST_CTL_2, 0x18 }, + { WCD9335_MICB3_TEST_CTL_3, 0xa4 }, + { WCD9335_MICB4_TEST_CTL_1, 0x1a }, + { WCD9335_MICB4_TEST_CTL_2, 0x18 }, + { WCD9335_MICB4_TEST_CTL_3, 0xa4 }, + { WCD9335_TX_COM_ADC_VCM, 0x39 }, + { WCD9335_TX_COM_BIAS_ATEST, 0xc0 }, + { WCD9335_TX_COM_ADC_INT1_IB, 0x6f }, + { WCD9335_TX_COM_ADC_INT2_IB, 0x4f }, + { WCD9335_TX_COM_TXFE_DIV_CTL, 0x2e }, + { WCD9335_TX_COM_TXFE_DIV_START, 0x00 }, + { WCD9335_TX_COM_TXFE_DIV_STOP_9P6M, 0xc7 }, + { WCD9335_TX_COM_TXFE_DIV_STOP_12P288M, 0xff }, + { WCD9335_TX_1_2_TEST_EN, 0xcc }, + { WCD9335_TX_1_2_ADC_IB, 0x09 }, + { WCD9335_TX_1_2_TEST_CTL, 0x38 }, + { WCD9335_TX_1_2_TEST_BLK_EN, 0xff }, + { WCD9335_TX_1_2_TXFE_CLKDIV, 0x00 }, + { WCD9335_TX_1_2_SAR1_ERR, 0x00 }, + { WCD9335_TX_1_2_SAR2_ERR, 0x00 }, + { WCD9335_TX_3_4_TEST_EN, 0xcc }, + { WCD9335_TX_3_4_ADC_IB, 0x09 }, + { WCD9335_TX_3_4_TEST_CTL, 0x38 }, + { WCD9335_TX_3_4_TEST_BLK_EN, 0xff }, + { WCD9335_TX_3_4_TXFE_CLKDIV, 0x00 }, + { WCD9335_TX_3_4_SAR1_ERR, 0x00 }, + { WCD9335_TX_3_4_SAR2_ERR, 0x00 }, + { WCD9335_TX_5_6_TEST_EN, 0xcc }, + { WCD9335_TX_5_6_ADC_IB, 0x09 }, + { WCD9335_TX_5_6_TEST_CTL, 0x38 }, + { WCD9335_TX_5_6_TEST_BLK_EN, 0xff }, + { WCD9335_TX_5_6_TXFE_CLKDIV, 0x00 }, + { WCD9335_TX_5_6_SAR1_ERR, 0x00 }, + { WCD9335_TX_5_6_SAR2_ERR, 0x00 }, + { WCD9335_CLASSH_MODE_1, 0x40 }, + { WCD9335_CLASSH_MODE_2, 0x3a }, + { WCD9335_CLASSH_MODE_3, 0x00 }, + { WCD9335_CLASSH_CTRL_VCL_1, 0x70 }, + { WCD9335_CLASSH_CTRL_VCL_2, 0xa2 }, + { WCD9335_CLASSH_CTRL_CCL_1, 0x51 }, + { WCD9335_CLASSH_CTRL_CCL_2, 0x80 }, + { WCD9335_CLASSH_CTRL_CCL_3, 0x80 }, + { WCD9335_CLASSH_CTRL_CCL_4, 0x51 }, + { WCD9335_CLASSH_CTRL_CCL_5, 0x00 }, + { WCD9335_CLASSH_BUCK_TMUX_A_D, 0x00 }, + { WCD9335_CLASSH_BUCK_SW_DRV_CNTL, 0x77 }, + { WCD9335_CLASSH_SPARE, 0x00 }, + { WCD9335_FLYBACK_EN, 0x4e }, + { WCD9335_FLYBACK_VNEG_CTRL_2, 0x45 }, + { WCD9335_FLYBACK_VNEG_CTRL_3, 0x74 }, + { WCD9335_FLYBACK_VNEG_CTRL_5, 0x83 }, + { WCD9335_FLYBACK_VNEG_CTRL_6, 0x98 }, + { WCD9335_FLYBACK_VNEG_CTRL_7, 0xa9 }, + { WCD9335_FLYBACK_VNEG_CTRL_8, 0x68 }, + { WCD9335_FLYBACK_VNEG_DAC_CTRL_2, 0x50 }, + { WCD9335_FLYBACK_VNEG_DAC_CTRL_3, 0xa6 }, + { WCD9335_FLYBACK_TEST_CTL, 0x00 }, + { WCD9335_RX_AUX_SW_CTL, 0x00 }, + { WCD9335_RX_PA_AUX_IN_CONN, 0x00 }, + { WCD9335_RX_TIMER_DIV, 0x74 }, + { WCD9335_RX_OCP_CTL, 0x1f }, + { WCD9335_RX_OCP_COUNT, 0x77 }, + { WCD9335_RX_BIAS_EAR_DAC, 0xa0 }, + { WCD9335_RX_BIAS_EAR_AMP, 0xaa }, + { WCD9335_RX_BIAS_HPH_LDO, 0xa9 }, + { WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8a }, + { WCD9335_RX_BIAS_HPH_RDAC_LDO, 0x88 }, + { WCD9335_RX_BIAS_HPH_CNP1, 0x86 }, + { WCD9335_RX_BIAS_DIFFLO_PA, 0x80 }, + { WCD9335_RX_BIAS_DIFFLO_REF, 0x88 }, + { WCD9335_RX_BIAS_DIFFLO_LDO, 0x88 }, + { WCD9335_RX_BIAS_SELO_DAC_PA, 0xa8 }, + { WCD9335_RX_BIAS_BUCK_RST, 0x08 }, + { WCD9335_RX_BIAS_BUCK_VREF_ERRAMP, 0x44 }, + { WCD9335_RX_BIAS_FLYB_ERRAMP, 0x40 }, + { WCD9335_RX_BIAS_FLYB_BUFF, 0xaa }, + { WCD9335_RX_BIAS_FLYB_MID_RST, 0x44 }, + { WCD9335_HPH_L_STATUS, 0x04 }, + { WCD9335_HPH_R_STATUS, 0x04 }, + { WCD9335_HPH_CNP_EN, 0x80 }, + { WCD9335_HPH_CNP_WG_CTL, 0xda }, + { WCD9335_HPH_CNP_WG_TIME, 0x15 }, + { WCD9335_HPH_OCP_CTL, 0x28 }, + { WCD9335_HPH_AUTO_CHOP, 0x12 }, + { WCD9335_HPH_CHOP_CTL, 0x83 }, + { WCD9335_HPH_PA_CTL1, 0x46 }, + { WCD9335_HPH_L_TEST, 0x00 }, + { WCD9335_HPH_L_ATEST, 0x50 }, + { WCD9335_HPH_R_TEST, 0x00 }, + { WCD9335_HPH_RDAC_CLK_CTL1, 0x99 }, + { WCD9335_HPH_RDAC_CLK_CTL2, 0x9b }, + { WCD9335_HPH_RDAC_CHOP_CLK_LP_CTL, 0x00 }, + { WCD9335_HPH_REFBUFF_UHQA_CTL, 0xa8 }, + { WCD9335_HPH_REFBUFF_LP_CTL, 0x00 }, + { WCD9335_HPH_L_DAC_CTL, 0x00 }, + { WCD9335_HPH_R_DAC_CTL, 0x00 }, + { WCD9335_EAR_EN_REG, 0x60 }, + { WCD9335_EAR_CMBUFF, 0x0d }, + { WCD9335_EAR_ICTL, 0x40 }, + { WCD9335_EAR_EN_DBG_CTL, 0x00 }, + { WCD9335_EAR_CNP, 0xe0 }, + { WCD9335_EAR_DAC_CTL_ATEST, 0x00 }, + { WCD9335_EAR_STATUS_REG, 0x04 }, + { WCD9335_EAR_OUT_SHORT, 0x00 }, + { WCD9335_DIFF_LO_MISC, 0x03 }, + { WCD9335_DIFF_LO_LO2_COMPANDER, 0x00 }, + { WCD9335_DIFF_LO_LO1_COMPANDER, 0x00 }, + { WCD9335_DIFF_LO_COMMON, 0x40 }, + { WCD9335_DIFF_LO_BYPASS_EN, 0x00 }, + { WCD9335_DIFF_LO_CNP, 0x20 }, + { WCD9335_DIFF_LO_CORE_OUT_PROG, 0x00 }, + { WCD9335_DIFF_LO_LDO_OUT_PROG, 0x00 }, + { WCD9335_DIFF_LO_COM_SWCAP_REFBUF_FREQ, 0x9b }, + { WCD9335_DIFF_LO_COM_PA_FREQ, 0xb0 }, + { WCD9335_DIFF_LO_RESERVED_REG, 0x60 }, + { WCD9335_DIFF_LO_LO1_STATUS_1, 0x00 }, + { WCD9335_DIFF_LO_LO1_STATUS_2, 0x00 }, + { WCD9335_SE_LO_COM1, 0x80 }, + { WCD9335_SE_LO_COM2, 0x04 }, + { WCD9335_SE_LO_LO3_GAIN, 0x20 }, + { WCD9335_SE_LO_LO3_CTRL, 0x04 }, + { WCD9335_SE_LO_LO4_GAIN, 0x20 }, + { WCD9335_SE_LO_LO4_CTRL, 0x04 }, + { WCD9335_SE_LO_LO3_STATUS, 0x00 }, + { WCD9335_SE_LO_LO4_STATUS, 0x00 }, + /* Page #10 registers */ + { WCD9335_PAGE10_PAGE_REGISTER, 0x00 }, + { WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x00 }, + { WCD9335_CDC_ANC0_MODE_1_CTL, 0x00 }, + { WCD9335_CDC_ANC0_MODE_2_CTL, 0x00 }, + { WCD9335_CDC_ANC0_FF_SHIFT, 0x00 }, + { WCD9335_CDC_ANC0_FB_SHIFT, 0x00 }, + { WCD9335_CDC_ANC0_LPF_FF_A_CTL, 0x00 }, + { WCD9335_CDC_ANC0_LPF_FF_B_CTL, 0x00 }, + { WCD9335_CDC_ANC0_LPF_FB_CTL, 0x00 }, + { WCD9335_CDC_ANC0_SMLPF_CTL, 0x00 }, + { WCD9335_CDC_ANC0_DCFLT_SHIFT_CTL, 0x00 }, + { WCD9335_CDC_ANC0_IIR_ADAPT_CTL, 0x00 }, + { WCD9335_CDC_ANC0_IIR_COEFF_1_CTL, 0x00 }, + { WCD9335_CDC_ANC0_IIR_COEFF_2_CTL, 0x00 }, + { WCD9335_CDC_ANC0_FF_A_GAIN_CTL, 0x00 }, + { WCD9335_CDC_ANC0_FF_B_GAIN_CTL, 0x00 }, + { WCD9335_CDC_ANC0_FB_GAIN_CTL, 0x00 }, + { WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x00 }, + { WCD9335_CDC_ANC1_MODE_1_CTL, 0x00 }, + { WCD9335_CDC_ANC1_MODE_2_CTL, 0x00 }, + { WCD9335_CDC_ANC1_FF_SHIFT, 0x00 }, + { WCD9335_CDC_ANC1_FB_SHIFT, 0x00 }, + { WCD9335_CDC_ANC1_LPF_FF_A_CTL, 0x00 }, + { WCD9335_CDC_ANC1_LPF_FF_B_CTL, 0x00 }, + { WCD9335_CDC_ANC1_LPF_FB_CTL, 0x00 }, + { WCD9335_CDC_ANC1_SMLPF_CTL, 0x00 }, + { WCD9335_CDC_ANC1_DCFLT_SHIFT_CTL, 0x00 }, + { WCD9335_CDC_ANC1_IIR_ADAPT_CTL, 0x00 }, + { WCD9335_CDC_ANC1_IIR_COEFF_1_CTL, 0x00 }, + { WCD9335_CDC_ANC1_IIR_COEFF_2_CTL, 0x00 }, + { WCD9335_CDC_ANC1_FF_A_GAIN_CTL, 0x00 }, + { WCD9335_CDC_ANC1_FF_B_GAIN_CTL, 0x00 }, + { WCD9335_CDC_ANC1_FB_GAIN_CTL, 0x00 }, + { WCD9335_CDC_TX0_TX_PATH_CTL, 0x04 }, + { WCD9335_CDC_TX0_TX_VOL_CTL, 0x00 }, + { WCD9335_CDC_TX0_TX_PATH_192_CTL, 0x00 }, + { WCD9335_CDC_TX0_TX_PATH_192_CFG, 0x00 }, + { WCD9335_CDC_TX0_TX_PATH_SEC0, 0x00 }, + { WCD9335_CDC_TX0_TX_PATH_SEC1, 0x00 }, + { WCD9335_CDC_TX0_TX_PATH_SEC4, 0x20 }, + { WCD9335_CDC_TX0_TX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_TX0_TX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_TX1_TX_PATH_CTL, 0x04 }, + { WCD9335_CDC_TX1_TX_VOL_CTL, 0x00 }, + { WCD9335_CDC_TX1_TX_PATH_192_CTL, 0x00 }, + { WCD9335_CDC_TX1_TX_PATH_192_CFG, 0x00 }, + { WCD9335_CDC_TX1_TX_PATH_SEC0, 0x00 }, + { WCD9335_CDC_TX1_TX_PATH_SEC1, 0x00 }, + { WCD9335_CDC_TX1_TX_PATH_SEC4, 0x20 }, + { WCD9335_CDC_TX1_TX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_TX1_TX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_TX2_TX_PATH_CTL, 0x04 }, + { WCD9335_CDC_TX2_TX_VOL_CTL, 0x00 }, + { WCD9335_CDC_TX2_TX_PATH_192_CTL, 0x00 }, + { WCD9335_CDC_TX2_TX_PATH_192_CFG, 0x00 }, + { WCD9335_CDC_TX2_TX_PATH_SEC0, 0x00 }, + { WCD9335_CDC_TX2_TX_PATH_SEC1, 0x00 }, + { WCD9335_CDC_TX2_TX_PATH_SEC4, 0x20 }, + { WCD9335_CDC_TX2_TX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_TX2_TX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_TX3_TX_PATH_CTL, 0x04 }, + { WCD9335_CDC_TX3_TX_VOL_CTL, 0x00 }, + { WCD9335_CDC_TX3_TX_PATH_192_CTL, 0x00 }, + { WCD9335_CDC_TX3_TX_PATH_192_CFG, 0x00 }, + { WCD9335_CDC_TX3_TX_PATH_SEC0, 0x00 }, + { WCD9335_CDC_TX3_TX_PATH_SEC1, 0x00 }, + { WCD9335_CDC_TX3_TX_PATH_SEC4, 0x20 }, + { WCD9335_CDC_TX3_TX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_TX3_TX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_TX4_TX_PATH_CTL, 0x04 }, + { WCD9335_CDC_TX4_TX_VOL_CTL, 0x00 }, + { WCD9335_CDC_TX4_TX_PATH_192_CTL, 0x00 }, + { WCD9335_CDC_TX4_TX_PATH_192_CFG, 0x00 }, + { WCD9335_CDC_TX4_TX_PATH_SEC0, 0x00 }, + { WCD9335_CDC_TX4_TX_PATH_SEC1, 0x00 }, + { WCD9335_CDC_TX4_TX_PATH_SEC4, 0x20 }, + { WCD9335_CDC_TX4_TX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_TX4_TX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_TX5_TX_PATH_CTL, 0x04 }, + { WCD9335_CDC_TX5_TX_VOL_CTL, 0x00 }, + { WCD9335_CDC_TX5_TX_PATH_192_CTL, 0x00 }, + { WCD9335_CDC_TX5_TX_PATH_192_CFG, 0x00 }, + { WCD9335_CDC_TX5_TX_PATH_SEC0, 0x00 }, + { WCD9335_CDC_TX5_TX_PATH_SEC1, 0x00 }, + { WCD9335_CDC_TX5_TX_PATH_SEC4, 0x20 }, + { WCD9335_CDC_TX5_TX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_TX5_TX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_TX6_TX_PATH_CTL, 0x04 }, + { WCD9335_CDC_TX6_TX_VOL_CTL, 0x00 }, + { WCD9335_CDC_TX6_TX_PATH_192_CTL, 0x00 }, + { WCD9335_CDC_TX6_TX_PATH_192_CFG, 0x00 }, + { WCD9335_CDC_TX6_TX_PATH_SEC0, 0x00 }, + { WCD9335_CDC_TX6_TX_PATH_SEC1, 0x00 }, + { WCD9335_CDC_TX6_TX_PATH_SEC4, 0x20 }, + { WCD9335_CDC_TX6_TX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_TX6_TX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_TX7_TX_PATH_CTL, 0x04 }, + { WCD9335_CDC_TX7_TX_VOL_CTL, 0x00 }, + { WCD9335_CDC_TX7_TX_PATH_192_CTL, 0x00 }, + { WCD9335_CDC_TX7_TX_PATH_192_CFG, 0x00 }, + { WCD9335_CDC_TX7_TX_PATH_SEC0, 0x00 }, + { WCD9335_CDC_TX7_TX_PATH_SEC1, 0x00 }, + { WCD9335_CDC_TX7_TX_PATH_SEC4, 0x20 }, + { WCD9335_CDC_TX7_TX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_TX7_TX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_TX8_TX_PATH_CTL, 0x04 }, + { WCD9335_CDC_TX8_TX_VOL_CTL, 0x00 }, + { WCD9335_CDC_TX8_TX_PATH_192_CTL, 0x00 }, + { WCD9335_CDC_TX8_TX_PATH_192_CFG, 0x00 }, + { WCD9335_CDC_TX8_TX_PATH_SEC0, 0x00 }, + { WCD9335_CDC_TX8_TX_PATH_SEC1, 0x00 }, + { WCD9335_CDC_TX8_TX_PATH_SEC4, 0x20 }, + { WCD9335_CDC_TX8_TX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_TX8_TX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x02 }, + { WCD9335_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x00 }, + { WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x02 }, + { WCD9335_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x00 }, + { WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x02 }, + { WCD9335_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x00 }, + { WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x02 }, + { WCD9335_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x00 }, + /* Page #11 registers */ + { WCD9335_PAGE11_PAGE_REGISTER, 0x00 }, + { WCD9335_CDC_COMPANDER1_CTL0, 0x60 }, + { WCD9335_CDC_COMPANDER1_CTL1, 0xdb }, + { WCD9335_CDC_COMPANDER1_CTL2, 0xff }, + { WCD9335_CDC_COMPANDER1_CTL3, 0x35 }, + { WCD9335_CDC_COMPANDER1_CTL4, 0xff }, + { WCD9335_CDC_COMPANDER1_CTL5, 0x00 }, + { WCD9335_CDC_COMPANDER1_CTL6, 0x01 }, + { WCD9335_CDC_COMPANDER2_CTL0, 0x60 }, + { WCD9335_CDC_COMPANDER2_CTL1, 0xdb }, + { WCD9335_CDC_COMPANDER2_CTL2, 0xff }, + { WCD9335_CDC_COMPANDER2_CTL3, 0x35 }, + { WCD9335_CDC_COMPANDER2_CTL4, 0xff }, + { WCD9335_CDC_COMPANDER2_CTL5, 0x00 }, + { WCD9335_CDC_COMPANDER2_CTL6, 0x01 }, + { WCD9335_CDC_COMPANDER3_CTL0, 0x60 }, + { WCD9335_CDC_COMPANDER3_CTL1, 0xdb }, + { WCD9335_CDC_COMPANDER3_CTL2, 0xff }, + { WCD9335_CDC_COMPANDER3_CTL3, 0x35 }, + { WCD9335_CDC_COMPANDER3_CTL4, 0xff }, + { WCD9335_CDC_COMPANDER3_CTL5, 0x00 }, + { WCD9335_CDC_COMPANDER3_CTL6, 0x01 }, + { WCD9335_CDC_COMPANDER4_CTL0, 0x60 }, + { WCD9335_CDC_COMPANDER4_CTL1, 0xdb }, + { WCD9335_CDC_COMPANDER4_CTL2, 0xff }, + { WCD9335_CDC_COMPANDER4_CTL3, 0x35 }, + { WCD9335_CDC_COMPANDER4_CTL4, 0xff }, + { WCD9335_CDC_COMPANDER4_CTL5, 0x00 }, + { WCD9335_CDC_COMPANDER4_CTL6, 0x01 }, + { WCD9335_CDC_COMPANDER5_CTL0, 0x60 }, + { WCD9335_CDC_COMPANDER5_CTL1, 0xdb }, + { WCD9335_CDC_COMPANDER5_CTL2, 0xff }, + { WCD9335_CDC_COMPANDER5_CTL3, 0x35 }, + { WCD9335_CDC_COMPANDER5_CTL4, 0xff }, + { WCD9335_CDC_COMPANDER5_CTL5, 0x00 }, + { WCD9335_CDC_COMPANDER5_CTL6, 0x01 }, + { WCD9335_CDC_COMPANDER6_CTL0, 0x60 }, + { WCD9335_CDC_COMPANDER6_CTL1, 0xdb }, + { WCD9335_CDC_COMPANDER6_CTL2, 0xff }, + { WCD9335_CDC_COMPANDER6_CTL3, 0x35 }, + { WCD9335_CDC_COMPANDER6_CTL4, 0xff }, + { WCD9335_CDC_COMPANDER6_CTL5, 0x00 }, + { WCD9335_CDC_COMPANDER6_CTL6, 0x01 }, + { WCD9335_CDC_COMPANDER7_CTL0, 0x60 }, + { WCD9335_CDC_COMPANDER7_CTL1, 0xdb }, + { WCD9335_CDC_COMPANDER7_CTL2, 0xff }, + { WCD9335_CDC_COMPANDER7_CTL3, 0x35 }, + { WCD9335_CDC_COMPANDER7_CTL4, 0xff }, + { WCD9335_CDC_COMPANDER7_CTL5, 0x00 }, + { WCD9335_CDC_COMPANDER7_CTL6, 0x01 }, + { WCD9335_CDC_COMPANDER8_CTL0, 0x60 }, + { WCD9335_CDC_COMPANDER8_CTL1, 0xdb }, + { WCD9335_CDC_COMPANDER8_CTL2, 0xff }, + { WCD9335_CDC_COMPANDER8_CTL3, 0x35 }, + { WCD9335_CDC_COMPANDER8_CTL4, 0xff }, + { WCD9335_CDC_COMPANDER8_CTL5, 0x00 }, + { WCD9335_CDC_COMPANDER8_CTL6, 0x01 }, + { WCD9335_CDC_RX0_RX_PATH_CTL, 0x04 }, + { WCD9335_CDC_RX0_RX_PATH_CFG0, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_CFG2, 0x8f }, + { WCD9335_CDC_RX0_RX_VOL_CTL, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_MIX_CTL, 0x04 }, + { WCD9335_CDC_RX0_RX_VOL_MIX_CTL, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_SEC2, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_SEC3, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_SEC7, 0x00 }, + { WCD9335_CDC_RX0_RX_PATH_MIX_SEC1, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_CTL, 0x04 }, + { WCD9335_CDC_RX1_RX_PATH_CFG0, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_CFG2, 0x8f }, + { WCD9335_CDC_RX1_RX_VOL_CTL, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_MIX_CTL, 0x04 }, + { WCD9335_CDC_RX1_RX_VOL_MIX_CTL, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_SEC2, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_SEC3, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_SEC4, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_SEC7, 0x00 }, + { WCD9335_CDC_RX1_RX_PATH_MIX_SEC1, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_CTL, 0x04 }, + { WCD9335_CDC_RX2_RX_PATH_CFG0, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_CFG2, 0x8f }, + { WCD9335_CDC_RX2_RX_VOL_CTL, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_MIX_CTL, 0x04 }, + { WCD9335_CDC_RX2_RX_VOL_MIX_CTL, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_SEC2, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_SEC3, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_SEC4, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_SEC7, 0x00 }, + { WCD9335_CDC_RX2_RX_PATH_MIX_SEC1, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_CTL, 0x04 }, + { WCD9335_CDC_RX3_RX_PATH_CFG0, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_CFG2, 0x8f }, + { WCD9335_CDC_RX3_RX_VOL_CTL, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_MIX_CTL, 0x04 }, + { WCD9335_CDC_RX3_RX_VOL_MIX_CTL, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_SEC2, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_SEC3, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_SEC7, 0x00 }, + { WCD9335_CDC_RX3_RX_PATH_MIX_SEC1, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_CTL, 0x04 }, + { WCD9335_CDC_RX4_RX_PATH_CFG0, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_CFG2, 0x8f }, + { WCD9335_CDC_RX4_RX_VOL_CTL, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_MIX_CTL, 0x04 }, + { WCD9335_CDC_RX4_RX_VOL_MIX_CTL, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_SEC2, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_SEC3, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_SEC7, 0x00 }, + { WCD9335_CDC_RX4_RX_PATH_MIX_SEC1, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_CTL, 0x04 }, + { WCD9335_CDC_RX5_RX_PATH_CFG0, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_CFG2, 0x8f }, + { WCD9335_CDC_RX5_RX_VOL_CTL, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_MIX_CTL, 0x04 }, + { WCD9335_CDC_RX5_RX_VOL_MIX_CTL, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_SEC2, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_SEC3, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_SEC7, 0x00 }, + { WCD9335_CDC_RX5_RX_PATH_MIX_SEC1, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_CTL, 0x04 }, + { WCD9335_CDC_RX6_RX_PATH_CFG0, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_CFG2, 0x8f }, + { WCD9335_CDC_RX6_RX_VOL_CTL, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_MIX_CTL, 0x04 }, + { WCD9335_CDC_RX6_RX_VOL_MIX_CTL, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_SEC2, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_SEC3, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_SEC7, 0x00 }, + { WCD9335_CDC_RX6_RX_PATH_MIX_SEC1, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_CTL, 0x04 }, + { WCD9335_CDC_RX7_RX_PATH_CFG0, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_CFG2, 0x8f }, + { WCD9335_CDC_RX7_RX_VOL_CTL, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_MIX_CTL, 0x04 }, + { WCD9335_CDC_RX7_RX_VOL_MIX_CTL, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_SEC2, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_SEC3, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_SEC7, 0x00 }, + { WCD9335_CDC_RX7_RX_PATH_MIX_SEC1, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_CTL, 0x04 }, + { WCD9335_CDC_RX8_RX_PATH_CFG0, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_CFG2, 0x8f }, + { WCD9335_CDC_RX8_RX_VOL_CTL, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_MIX_CTL, 0x04 }, + { WCD9335_CDC_RX8_RX_VOL_MIX_CTL, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_SEC2, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_SEC3, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_SEC5, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_SEC6, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_SEC7, 0x00 }, + { WCD9335_CDC_RX8_RX_PATH_MIX_SEC1, 0x00 }, + /* Page #12 registers */ + { WCD9335_PAGE12_PAGE_REGISTER, 0x00 }, + { WCD9335_CDC_CLSH_CRC, 0x00 }, + { WCD9335_CDC_CLSH_DLY_CTRL, 0x03 }, + { WCD9335_CDC_CLSH_DECAY_CTRL, 0x02 }, + { WCD9335_CDC_CLSH_HPH_V_PA, 0x1c }, + { WCD9335_CDC_CLSH_EAR_V_PA, 0x39 }, + { WCD9335_CDC_CLSH_HPH_V_HD, 0x0c }, + { WCD9335_CDC_CLSH_EAR_V_HD, 0x0c }, + { WCD9335_CDC_CLSH_K1_MSB, 0x01 }, + { WCD9335_CDC_CLSH_K1_LSB, 0x00 }, + { WCD9335_CDC_CLSH_K2_MSB, 0x00 }, + { WCD9335_CDC_CLSH_K2_LSB, 0x80 }, + { WCD9335_CDC_CLSH_IDLE_CTRL, 0x00 }, + { WCD9335_CDC_CLSH_IDLE_HPH, 0x00 }, + { WCD9335_CDC_CLSH_IDLE_EAR, 0x00 }, + { WCD9335_CDC_CLSH_TEST0, 0x07 }, + { WCD9335_CDC_CLSH_TEST1, 0x00 }, + { WCD9335_CDC_CLSH_OVR_VREF, 0x00 }, + { WCD9335_CDC_BOOST0_BOOST_PATH_CTL, 0x00 }, + { WCD9335_CDC_BOOST0_BOOST_CTL, 0xb2 }, + { WCD9335_CDC_BOOST0_BOOST_CFG1, 0x00 }, + { WCD9335_CDC_BOOST0_BOOST_CFG2, 0x00 }, + { WCD9335_CDC_BOOST1_BOOST_PATH_CTL, 0x00 }, + { WCD9335_CDC_BOOST1_BOOST_CTL, 0xb2 }, + { WCD9335_CDC_BOOST1_BOOST_CFG1, 0x00 }, + { WCD9335_CDC_BOOST1_BOOST_CFG2, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_WR_DATA_0, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_WR_DATA_1, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_WR_DATA_2, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_WR_DATA_3, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_WR_ADDR_1, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_WR_ADDR_2, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_WR_ADDR_3, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_RD_ADDR_0, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_RD_ADDR_1, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_RD_ADDR_2, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_RD_ADDR_3, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_RD_DATA_0, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_RD_DATA_1, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_RD_DATA_2, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_RD_DATA_3, 0x00 }, + { WCD9335_SWR_AHB_BRIDGE_ACCESS_CFG, 0x0f }, + { WCD9335_SWR_AHB_BRIDGE_ACCESS_STATUS, 0x03 }, + { WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x00 }, + { WCD9335_CDC_VBAT_VBAT_CFG, 0x0a }, + { WCD9335_CDC_VBAT_VBAT_ADC_CAL1, 0x00 }, + { WCD9335_CDC_VBAT_VBAT_ADC_CAL2, 0x00 }, + { WCD9335_CDC_VBAT_VBAT_ADC_CAL3, 0x04 }, + { WCD9335_CDC_VBAT_VBAT_PK_EST1, 0xe0 }, + { WCD9335_CDC_VBAT_VBAT_PK_EST2, 0x01 }, + { WCD9335_CDC_VBAT_VBAT_PK_EST3, 0x40 }, + { WCD9335_CDC_VBAT_VBAT_RF_PROC1, 0x2a }, + { WCD9335_CDC_VBAT_VBAT_RF_PROC2, 0x86 }, + { WCD9335_CDC_VBAT_VBAT_TAC1, 0x70 }, + { WCD9335_CDC_VBAT_VBAT_TAC2, 0x18 }, + { WCD9335_CDC_VBAT_VBAT_TAC3, 0x18 }, + { WCD9335_CDC_VBAT_VBAT_TAC4, 0x03 }, + { WCD9335_CDC_VBAT_VBAT_GAIN_UPD1, 0x01 }, + { WCD9335_CDC_VBAT_VBAT_GAIN_UPD2, 0x00 }, + { WCD9335_CDC_VBAT_VBAT_GAIN_UPD3, 0x64 }, + { WCD9335_CDC_VBAT_VBAT_GAIN_UPD4, 0x01 }, + { WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x00 }, + { WCD9335_CDC_VBAT_VBAT_GAIN_UPD_MON, 0x00 }, + { WCD9335_CDC_VBAT_VBAT_GAIN_MON_VAL, 0x00 }, + { WCD9335_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL, 0x04 }, + { WCD9335_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1, 0x00 }, + { WCD9335_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL, 0x04 }, + { WCD9335_CDC_SIDETONE_SRC1_ST_SRC_PATH_CFG1, 0x00 }, + /* Page #13 registers */ + { WCD9335_PAGE13_PAGE_REGISTER, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG0, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG1, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG2, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG3, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG4, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_ANC_CFG0, 0x00 }, + { WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 0x00 }, + { WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3, 0x00 }, + { WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 0x00 }, + { WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 0x00 }, + { WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 0x00 }, + { WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3, 0x00 }, + { WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x00 }, + { WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL, 0x00 }, + { WCD9335_CDC_PROX_DETECT_PROX_CTL, 0x08 }, + { WCD9335_CDC_PROX_DETECT_PROX_POLL_PERIOD0, 0x00 }, + { WCD9335_CDC_PROX_DETECT_PROX_POLL_PERIOD1, 0x4b }, + { WCD9335_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB, 0x00 }, + { WCD9335_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB, 0x00 }, + { WCD9335_CDC_PROX_DETECT_PROX_STATUS, 0x00 }, + { WCD9335_CDC_PROX_DETECT_PROX_TEST_CTRL, 0x00 }, + { WCD9335_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB, 0x00 }, + { WCD9335_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB, 0x00 }, + { WCD9335_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD, 0x00 }, + { WCD9335_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR0_IIR_PATH_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR0_IIR_CTL, 0x40 }, + { WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR1_IIR_PATH_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B5_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B6_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B7_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B8_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR1_IIR_CTL, 0x40 }, + { WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR1_IIR_COEF_B1_CTL, 0x00 }, + { WCD9335_CDC_SIDETONE_IIR1_IIR_COEF_B2_CTL, 0x00 }, + { WCD9335_CDC_TOP_TOP_CFG0, 0x00 }, + { WCD9335_CDC_TOP_TOP_CFG1, 0x00 }, + { WCD9335_CDC_TOP_TOP_CFG2, 0x00 }, + { WCD9335_CDC_TOP_TOP_CFG3, 0x18 }, + { WCD9335_CDC_TOP_TOP_CFG4, 0x00 }, + { WCD9335_CDC_TOP_TOP_CFG5, 0x00 }, + { WCD9335_CDC_TOP_TOP_CFG6, 0x00 }, + { WCD9335_CDC_TOP_TOP_CFG7, 0x00 }, + { WCD9335_CDC_TOP_HPHL_COMP_WR_LSB, 0x00 }, + { WCD9335_CDC_TOP_HPHL_COMP_WR_MSB, 0x00 }, + { WCD9335_CDC_TOP_HPHL_COMP_LUT, 0x00 }, + { WCD9335_CDC_TOP_HPHL_COMP_RD_LSB, 0x00 }, + { WCD9335_CDC_TOP_HPHL_COMP_RD_MSB, 0x00 }, + { WCD9335_CDC_TOP_HPHR_COMP_WR_LSB, 0x00 }, + { WCD9335_CDC_TOP_HPHR_COMP_WR_MSB, 0x00 }, + { WCD9335_CDC_TOP_HPHR_COMP_LUT, 0x00 }, + { WCD9335_CDC_TOP_HPHR_COMP_RD_LSB, 0x00 }, + { WCD9335_CDC_TOP_HPHR_COMP_RD_MSB, 0x00 }, + { WCD9335_CDC_TOP_DIFFL_COMP_WR_LSB, 0x00 }, + { WCD9335_CDC_TOP_DIFFL_COMP_WR_MSB, 0x00 }, + { WCD9335_CDC_TOP_DIFFL_COMP_LUT, 0x00 }, + { WCD9335_CDC_TOP_DIFFL_COMP_RD_LSB, 0x00 }, + { WCD9335_CDC_TOP_DIFFL_COMP_RD_MSB, 0x00 }, + { WCD9335_CDC_TOP_DIFFR_COMP_WR_LSB, 0x00 }, + { WCD9335_CDC_TOP_DIFFR_COMP_WR_MSB, 0x00 }, + { WCD9335_CDC_TOP_DIFFR_COMP_LUT, 0x00 }, + { WCD9335_CDC_TOP_DIFFR_COMP_RD_LSB, 0x00 }, + { WCD9335_CDC_TOP_DIFFR_COMP_RD_MSB, 0x00 }, + /* Page #0x80 registers */ + { WCD9335_PAGE80_PAGE_REGISTER, 0x00 }, + { WCD9335_TLMM_BIST_MODE_PINCFG, 0x00 }, + { WCD9335_TLMM_RF_PA_ON_PINCFG, 0x00 }, + { WCD9335_TLMM_INTR1_PINCFG, 0x00 }, + { WCD9335_TLMM_INTR2_PINCFG, 0x00 }, + { WCD9335_TLMM_SWR_DATA_PINCFG, 0x00 }, + { WCD9335_TLMM_SWR_CLK_PINCFG, 0x00 }, + { WCD9335_TLMM_SLIMBUS_DATA2_PINCFG, 0x00 }, + { WCD9335_TLMM_I2C_CLK_PINCFG, 0x00 }, + { WCD9335_TLMM_I2C_DATA_PINCFG, 0x00 }, + { WCD9335_TLMM_I2S_RX_SD0_PINCFG, 0x00 }, + { WCD9335_TLMM_I2S_RX_SD1_PINCFG, 0x00 }, + { WCD9335_TLMM_I2S_RX_SCK_PINCFG, 0x00 }, + { WCD9335_TLMM_I2S_RX_WS_PINCFG, 0x00 }, + { WCD9335_TLMM_I2S_TX_SD0_PINCFG, 0x00 }, + { WCD9335_TLMM_I2S_TX_SD1_PINCFG, 0x00 }, + { WCD9335_TLMM_I2S_TX_SCK_PINCFG, 0x00 }, + { WCD9335_TLMM_I2S_TX_WS_PINCFG, 0x00 }, + { WCD9335_TLMM_DMIC1_CLK_PINCFG, 0x00 }, + { WCD9335_TLMM_DMIC1_DATA_PINCFG, 0x00 }, + { WCD9335_TLMM_DMIC2_CLK_PINCFG, 0x00 }, + { WCD9335_TLMM_DMIC2_DATA_PINCFG, 0x00 }, + { WCD9335_TLMM_DMIC3_CLK_PINCFG, 0x00 }, + { WCD9335_TLMM_DMIC3_DATA_PINCFG, 0x00 }, + { WCD9335_TLMM_JTDI_PINCFG, 0x00 }, + { WCD9335_TLMM_JTDO_PINCFG, 0x00 }, + { WCD9335_TLMM_JTMS_PINCFG, 0x00 }, + { WCD9335_TLMM_JTCK_PINCFG, 0x00 }, + { WCD9335_TLMM_JTRST_PINCFG, 0x00 }, + { WCD9335_TEST_DEBUG_PIN_CTL_OE_0, 0x00 }, + { WCD9335_TEST_DEBUG_PIN_CTL_OE_1, 0x00 }, + { WCD9335_TEST_DEBUG_PIN_CTL_OE_2, 0x00 }, + { WCD9335_TEST_DEBUG_PIN_CTL_OE_3, 0x00 }, + { WCD9335_TEST_DEBUG_PIN_CTL_DATA_0, 0x00 }, + { WCD9335_TEST_DEBUG_PIN_CTL_DATA_1, 0x00 }, + { WCD9335_TEST_DEBUG_PIN_CTL_DATA_2, 0x00 }, + { WCD9335_TEST_DEBUG_PIN_CTL_DATA_3, 0x00 }, + { WCD9335_TEST_DEBUG_PAD_DRVCTL, 0x00 }, + { WCD9335_TEST_DEBUG_PIN_STATUS, 0x00 }, + { WCD9335_TEST_DEBUG_MEM_CTRL, 0x00 }, + { WCD9335_TEST_DEBUG_DEBUG_BUS_SEL, 0x00 }, + { WCD9335_TEST_DEBUG_DEBUG_JTAG, 0x00 }, + { WCD9335_TEST_DEBUG_DEBUG_EN_1, 0x00 }, + { WCD9335_TEST_DEBUG_DEBUG_EN_2, 0x00 }, + { WCD9335_TEST_DEBUG_DEBUG_EN_3, 0x00 }, +}; + +/* + * wcd9335_regmap_register_patch: Update register defaults based on version + * @regmap: handle to wcd9xxx regmap + * @version: wcd9335 version + * + * Returns error code in case of failure or 0 for success + */ +int wcd9335_regmap_register_patch(struct regmap *regmap, int version) +{ + int rc; + + if (!regmap) { + pr_err("%s: regmap struct is NULL\n", __func__); + return -EINVAL; + } + + switch (version) { + case TASHA_VERSION_1_0: + case TASHA_VERSION_1_1: + regcache_cache_only(regmap, true); + rc = regmap_multi_reg_write(regmap, wcd9335_1_x_defaults, + ARRAY_SIZE(wcd9335_1_x_defaults)); + regcache_cache_only(regmap, false); + break; + case TASHA_VERSION_2_0: + regcache_cache_only(regmap, true); + rc = regmap_multi_reg_write(regmap, wcd9335_2_0_defaults, + ARRAY_SIZE(wcd9335_2_0_defaults)); + regcache_cache_only(regmap, false); + break; + default: + pr_err("%s: unknown version: %d\n", __func__, version); + rc = -EINVAL; + break; + } + + return rc; +} +EXPORT_SYMBOL(wcd9335_regmap_register_patch); + +static bool wcd9335_is_readable_register(struct device *dev, unsigned int reg) +{ + u8 pg_num, reg_offset; + const u8 *reg_tbl = NULL; + + /* + * Get the page number from MSB of codec register. If its 0x80, assign + * the corresponding page index PAGE_0x80. + */ + pg_num = reg >> 0x8; + if (pg_num == 0x80) + pg_num = PAGE_0X80; + else if (pg_num >= 0xE) + return false; + + reg_tbl = wcd9335_reg[pg_num]; + reg_offset = reg & 0xFF; + + if (reg_tbl) + return reg_tbl[reg_offset]; + else + return false; +} + +static bool wcd9335_is_volatile_register(struct device *dev, unsigned int reg) +{ + /* + * registers from 0x000 to 0x0FF are volatile because + * this space contains registers related to interrupt + * status, mask etc + */ + if (reg < 0x100) + return true; + + /* IIR Coeff registers are not cacheable */ + if ((reg >= WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL) && + (reg <= WCD9335_CDC_SIDETONE_IIR1_IIR_COEF_B2_CTL)) + return true; + + if ((reg >= WCD9335_CDC_ANC0_IIR_COEFF_1_CTL) && + (reg <= WCD9335_CDC_ANC0_FB_GAIN_CTL)) + return true; + + if ((reg >= WCD9335_CDC_ANC1_IIR_COEFF_1_CTL) && + (reg <= WCD9335_CDC_ANC1_FB_GAIN_CTL)) + return true; + /* + * CPE inbox and outbox registers are volatile + * since they can be updated in the codec hardware + * to indicate CPE status + */ + if (reg >= WCD9335_CPE_SS_MEM_PTR_0 && + reg <= WCD9335_CPE_SS_OUTBOX2_ACK) + return true; + + if (reg >= WCD9335_RCO_CAL_OUT_1 && + reg <= WCD9335_RCO_CAL_OUT_5) + return true; + + switch (reg) { + case WCD9335_CPE_SS_INBOX1_TRG: + case WCD9335_CPE_SS_INBOX2_TRG: + case WCD9335_SWR_AHB_BRIDGE_WR_DATA_0: + case WCD9335_SWR_AHB_BRIDGE_WR_DATA_1: + case WCD9335_SWR_AHB_BRIDGE_WR_DATA_2: + case WCD9335_SWR_AHB_BRIDGE_WR_DATA_3: + case WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0: + case WCD9335_SWR_AHB_BRIDGE_WR_ADDR_1: + case WCD9335_SWR_AHB_BRIDGE_WR_ADDR_2: + case WCD9335_SWR_AHB_BRIDGE_WR_ADDR_3: + case WCD9335_SWR_AHB_BRIDGE_RD_DATA_0: + case WCD9335_SWR_AHB_BRIDGE_RD_DATA_1: + case WCD9335_SWR_AHB_BRIDGE_RD_DATA_2: + case WCD9335_SWR_AHB_BRIDGE_RD_DATA_3: + case WCD9335_SWR_AHB_BRIDGE_RD_ADDR_0: + case WCD9335_SWR_AHB_BRIDGE_RD_ADDR_1: + case WCD9335_SWR_AHB_BRIDGE_RD_ADDR_2: + case WCD9335_SWR_AHB_BRIDGE_RD_ADDR_3: + case WCD9335_ANA_BIAS: + case WCD9335_ANA_CLK_TOP: + case WCD9335_ANA_RCO: + case WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL: + case WCD9335_ANA_MBHC_RESULT_3: + case WCD9335_ANA_MBHC_RESULT_2: + case WCD9335_ANA_MBHC_RESULT_1: + case WCD9335_ANA_MBHC_MECH: + case WCD9335_ANA_MBHC_ELECT: + case WCD9335_ANA_MBHC_ZDET: + case WCD9335_ANA_MICB2: + case WCD9335_CPE_SS_SS_ERROR_INT_STATUS: + case WCD9335_CPE_SS_SS_ERROR_INT_MASK: + case WCD9335_CPE_SS_SS_ERROR_INT_CLEAR: + case WCD9335_CPE_SS_STATUS: + case WCD9335_CPE_SS_BACKUP_INT: + case WCD9335_CPE_SS_CFG: + case WCD9335_SOC_MAD_MAIN_CTL_1: + case WCD9335_SOC_MAD_AUDIO_CTL_3: + case WCD9335_SOC_MAD_AUDIO_CTL_4: + case WCD9335_FLYBACK_EN: + case WCD9335_ANA_RX_SUPPLIES: + case WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL: + case WCD9335_SIDO_SIDO_CCL_2: + case WCD9335_SIDO_SIDO_CCL_4: + case WCD9335_DATA_HUB_NATIVE_FIFO_STATUS: + case WCD9335_MBHC_FSM_STATUS: + case WCD9335_SPLINE_SRC0_STATUS: + case WCD9335_SPLINE_SRC1_STATUS: + case WCD9335_SPLINE_SRC2_STATUS: + case WCD9335_SPLINE_SRC3_STATUS: + case WCD9335_SIDO_SIDO_TEST_2: + case WCD9335_SIDO_SIDO_CCL_8: + case WCD9335_BIAS_VBG_FINE_ADJ: + case WCD9335_VBADC_ADC_DOUTMSB: + case WCD9335_VBADC_ADC_DOUTLSB: + case WCD9335_CDC_VBAT_VBAT_GAIN_MON_VAL: + case WCD9335_ANA_BUCK_CTL: + return true; + default: + return false; + } +} + +struct regmap_config wcd9335_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wcd9335_defaults, + .num_reg_defaults = ARRAY_SIZE(wcd9335_defaults), + .max_register = WCD9335_MAX_REGISTER, + .volatile_reg = wcd9335_is_volatile_register, + .readable_reg = wcd9335_is_readable_register, + .can_multi_write = true, +}; diff --git a/drivers/mfd/wcd9335-tables.c b/drivers/mfd/wcd9335-tables.c new file mode 100644 index 000000000000..f5c32efe76ef --- /dev/null +++ b/drivers/mfd/wcd9335-tables.c @@ -0,0 +1,1325 @@ +/* + * Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#define WCD9335_REG(reg) ((reg) & 0xFF) + +const u8 wcd9335_page0_reg_readable[WCD9335_PAGE_SIZE] = { + [WCD9335_REG(WCD9335_PAGE0_PAGE_REGISTER)] = 1, + [WCD9335_REG(WCD9335_CODEC_RPM_CLK_BYPASS)] = 1, + [WCD9335_REG(WCD9335_CODEC_RPM_CLK_GATE)] = 1, + [WCD9335_REG(WCD9335_CODEC_RPM_CLK_MCLK_CFG)] = 1, + [WCD9335_REG(WCD9335_CODEC_RPM_RST_CTL)] = 1, + [WCD9335_REG(WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL)] = 1, + [WCD9335_REG(WCD9335_CODEC_RPM_PWR_CPE_DEEPSLP_1)] = 1, + [WCD9335_REG(WCD9335_CODEC_RPM_PWR_CPE_DEEPSLP_2)] = 1, + [WCD9335_REG(WCD9335_CODEC_RPM_PWR_CPE_DEEPSLP_3)] = 1, + [WCD9335_REG(WCD9335_CODEC_RPM_PWR_CPE_IRAM_SHUTDOWN)] = 1, + [WCD9335_REG(WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN)] = 1, + [WCD9335_REG(WCD9335_CODEC_RPM_PWR_CPE_DRAM0_SHUTDOWN_1)] = 1, + [WCD9335_REG(WCD9335_CODEC_RPM_PWR_CPE_DRAM0_SHUTDOWN_2)] = 1, + [WCD9335_REG(WCD9335_CODEC_RPM_INT_MASK)] = 1, + [WCD9335_REG(WCD9335_CODEC_RPM_INT_STATUS)] = 1, + [WCD9335_REG(WCD9335_CODEC_RPM_INT_CLEAR)] = 0, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE1)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE2)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE3)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_CTL)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_TEST0)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_TEST1)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT1)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT2)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT3)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT4)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT5)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT6)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT7)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT8)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT9)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT10)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT11)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT12)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT13)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT14)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT15)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_I2C_SLAVE_ID_1)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_I2C_SLAVE_ID_2)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_I2C_SLAVE_ID_3)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_I2C_ACTIVE)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_PROC1_MON_CTL)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_PROC1_MON_STATUS)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_PROC1_MON_CNT_MSB)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_PROC1_MON_CNT_LSB)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_PROC2_MON_CTL)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_PROC2_MON_STATUS)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_PROC2_MON_CNT_MSB)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_PROC2_MON_CNT_LSB)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_PROC3_MON_CTL)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_PROC3_MON_STATUS)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_PROC3_MON_CNT_MSB)] = 1, + [WCD9335_REG(WCD9335_CHIP_TIER_CTRL_PROC3_MON_CNT_LSB)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_I2S_CLK)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_RX0_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_RX1_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_RX2_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_RX3_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_RX4_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_RX5_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_RX6_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_RX7_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_SB_TX0_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_SB_TX1_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_SB_TX2_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_SB_TX3_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_SB_TX4_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_SB_TX5_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_SB_TX6_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_SB_TX7_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_SB_TX8_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_SB_TX9_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_SB_TX10_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_SB_TX11_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_SB_TX14_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_SB_TX15_INP_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_NATIVE_FIFO_SYNC)] = 1, + [WCD9335_REG(WCD9335_DATA_HUB_NATIVE_FIFO_STATUS)] = 1, + [WCD9335_REG(WCD9335_INTR_CFG)] = 1, + [WCD9335_REG(WCD9335_INTR_CLR_COMMIT)] = 0, + [WCD9335_REG(WCD9335_INTR_PIN1_MASK0)] = 1, + [WCD9335_REG(WCD9335_INTR_PIN1_MASK1)] = 1, + [WCD9335_REG(WCD9335_INTR_PIN1_MASK2)] = 1, + [WCD9335_REG(WCD9335_INTR_PIN1_MASK3)] = 1, + [WCD9335_REG(WCD9335_INTR_PIN1_STATUS0)] = 1, + [WCD9335_REG(WCD9335_INTR_PIN1_STATUS1)] = 1, + [WCD9335_REG(WCD9335_INTR_PIN1_STATUS2)] = 1, + [WCD9335_REG(WCD9335_INTR_PIN1_STATUS3)] = 1, + [WCD9335_REG(WCD9335_INTR_PIN1_CLEAR0)] = 0, + [WCD9335_REG(WCD9335_INTR_PIN1_CLEAR1)] = 0, + [WCD9335_REG(WCD9335_INTR_PIN1_CLEAR2)] = 0, + [WCD9335_REG(WCD9335_INTR_PIN1_CLEAR3)] = 0, + [WCD9335_REG(WCD9335_INTR_PIN2_MASK0)] = 1, + [WCD9335_REG(WCD9335_INTR_PIN2_MASK1)] = 1, + [WCD9335_REG(WCD9335_INTR_PIN2_MASK2)] = 1, + [WCD9335_REG(WCD9335_INTR_PIN2_MASK3)] = 1, + [WCD9335_REG(WCD9335_INTR_PIN2_STATUS0)] = 1, + [WCD9335_REG(WCD9335_INTR_PIN2_STATUS1)] = 1, + [WCD9335_REG(WCD9335_INTR_PIN2_STATUS2)] = 1, + [WCD9335_REG(WCD9335_INTR_PIN2_STATUS3)] = 1, + [WCD9335_REG(WCD9335_INTR_PIN2_CLEAR0)] = 0, + [WCD9335_REG(WCD9335_INTR_PIN2_CLEAR1)] = 0, + [WCD9335_REG(WCD9335_INTR_PIN2_CLEAR2)] = 0, + [WCD9335_REG(WCD9335_INTR_PIN2_CLEAR3)] = 0, + [WCD9335_REG(WCD9335_INTR_LEVEL0)] = 1, + [WCD9335_REG(WCD9335_INTR_LEVEL1)] = 1, + [WCD9335_REG(WCD9335_INTR_LEVEL2)] = 1, + [WCD9335_REG(WCD9335_INTR_LEVEL3)] = 1, + [WCD9335_REG(WCD9335_INTR_BYPASS0)] = 1, + [WCD9335_REG(WCD9335_INTR_BYPASS1)] = 1, + [WCD9335_REG(WCD9335_INTR_BYPASS2)] = 1, + [WCD9335_REG(WCD9335_INTR_BYPASS3)] = 1, + [WCD9335_REG(WCD9335_INTR_SET0)] = 1, + [WCD9335_REG(WCD9335_INTR_SET1)] = 1, + [WCD9335_REG(WCD9335_INTR_SET2)] = 1, + [WCD9335_REG(WCD9335_INTR_SET3)] = 1, +}; + +const u8 wcd9335_page1_reg_readable[WCD9335_PAGE_SIZE] = { + [WCD9335_REG(WCD9335_PAGE1_PAGE_REGISTER)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_USER_CTL_0)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_USER_CTL_1)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_USER_CTL_2)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_USER_CTL_3)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_USER_CTL_4)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_USER_CTL_5)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_USER_CTL_6)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_USER_CTL_7)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_USER_CTL_8)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_USER_CTL_9)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_L_VAL_CTL_0)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_L_VAL_CTL_1)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_DSM_FRAC_CTL_0)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_DSM_FRAC_CTL_1)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_CONFIG_CTL_0)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_CONFIG_CTL_1)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_CONFIG_CTL_2)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_CONFIG_CTL_3)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_CONFIG_CTL_4)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_TEST_CTL_0)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_TEST_CTL_1)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_TEST_CTL_2)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_TEST_CTL_3)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_TEST_CTL_4)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_TEST_CTL_5)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_TEST_CTL_6)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_TEST_CTL_7)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_FREQ_CTL_0)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_FREQ_CTL_1)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_FREQ_CTL_2)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_FREQ_CTL_3)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_SSC_CTL_0)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_SSC_CTL_1)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_SSC_CTL_2)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_SSC_CTL_3)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_FLL_MODE)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_STATUS_0)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_STATUS_1)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_STATUS_2)] = 1, + [WCD9335_REG(WCD9335_CPE_FLL_STATUS_3)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_USER_CTL_0)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_USER_CTL_1)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_USER_CTL_2)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_USER_CTL_3)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_USER_CTL_4)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_USER_CTL_5)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_USER_CTL_6)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_USER_CTL_7)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_USER_CTL_8)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_USER_CTL_9)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_L_VAL_CTL_0)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_L_VAL_CTL_1)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_DSM_FRAC_CTL_0)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_DSM_FRAC_CTL_1)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_CONFIG_CTL_0)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_CONFIG_CTL_1)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_CONFIG_CTL_2)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_CONFIG_CTL_3)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_CONFIG_CTL_4)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_TEST_CTL_0)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_TEST_CTL_1)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_TEST_CTL_2)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_TEST_CTL_3)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_TEST_CTL_4)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_TEST_CTL_5)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_TEST_CTL_6)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_TEST_CTL_7)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_FREQ_CTL_0)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_FREQ_CTL_1)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_FREQ_CTL_2)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_FREQ_CTL_3)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_SSC_CTL_0)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_SSC_CTL_1)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_SSC_CTL_2)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_SSC_CTL_3)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_FLL_MODE)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_STATUS_0)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_STATUS_1)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_STATUS_2)] = 1, + [WCD9335_REG(WCD9335_I2S_FLL_STATUS_3)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_USER_CTL_0)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_USER_CTL_1)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_USER_CTL_2)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_USER_CTL_3)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_USER_CTL_4)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_USER_CTL_5)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_USER_CTL_6)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_USER_CTL_7)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_USER_CTL_8)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_USER_CTL_9)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_L_VAL_CTL_0)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_L_VAL_CTL_1)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_DSM_FRAC_CTL_0)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_DSM_FRAC_CTL_1)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_CONFIG_CTL_0)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_CONFIG_CTL_1)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_CONFIG_CTL_2)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_CONFIG_CTL_3)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_CONFIG_CTL_4)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_TEST_CTL_0)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_TEST_CTL_1)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_TEST_CTL_2)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_TEST_CTL_3)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_TEST_CTL_4)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_TEST_CTL_5)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_TEST_CTL_6)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_TEST_CTL_7)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_FREQ_CTL_0)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_FREQ_CTL_1)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_FREQ_CTL_2)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_FREQ_CTL_3)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_SSC_CTL_0)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_SSC_CTL_1)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_SSC_CTL_2)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_SSC_CTL_3)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_FLL_MODE)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_STATUS_0)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_STATUS_1)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_STATUS_2)] = 1, + [WCD9335_REG(WCD9335_SB_FLL_STATUS_3)] = 1, +}; + +const u8 wcd9335_page2_reg_readable[WCD9335_PAGE_SIZE] = { + [WCD9335_REG(WCD9335_PAGE2_PAGE_REGISTER)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_PTR_0)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_PTR_1)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_PTR_2)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_CTRL)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_BANK_0)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_BANK_1)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_BANK_2)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_BANK_3)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_BANK_4)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_BANK_5)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_BANK_6)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_BANK_7)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_BANK_8)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_BANK_9)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_BANK_10)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_BANK_11)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_BANK_12)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_BANK_13)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_BANK_14)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MEM_BANK_15)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_TRG)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_TRG)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_0)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_1)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_2)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_3)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_4)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_5)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_6)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_7)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_8)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_9)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_10)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_11)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_12)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_13)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_14)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX1_15)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_0)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_1)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_2)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_3)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_4)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_5)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_6)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_7)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_8)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_9)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_10)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_11)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_12)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_13)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_14)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_15)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_0)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_1)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_2)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_3)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_4)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_5)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_6)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_7)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_8)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_9)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_10)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_11)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_12)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_13)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_14)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_INBOX2_15)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_0)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_1)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_2)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_3)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_4)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_5)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_6)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_7)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_8)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_9)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_10)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_11)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_12)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_13)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_14)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_15)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX1_ACK)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_OUTBOX2_ACK)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_EC_BUF_INT_PERIOD)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_US_BUF_INT_PERIOD)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_CFG)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_US_EC_MUX_CFG)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_MAD_CTL)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_CPAR_CTL)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_TX_PP_CFG)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_DMIC0_CTL)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_DMIC1_CTL)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_DMIC2_CTL)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_DMIC_CFG)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_SVA_CFG)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_CPAR_CFG)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_WDOG_CFG)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_BACKUP_INT)] = 0, + [WCD9335_REG(WCD9335_CPE_SS_STATUS)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_CPE_OCD_CFG)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_SS_ERROR_INT_MASK)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_SS_ERROR_INT_STATUS)] = 1, + [WCD9335_REG(WCD9335_CPE_SS_SS_ERROR_INT_CLEAR)] = 0, + [WCD9335_REG(WCD9335_SOC_MAD_MAIN_CTL_1)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_MAIN_CTL_2)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_AUDIO_CTL_1)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_AUDIO_CTL_2)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_AUDIO_CTL_3)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_AUDIO_CTL_4)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_AUDIO_CTL_5)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_AUDIO_CTL_6)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_AUDIO_CTL_7)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_AUDIO_CTL_8)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_AUDIO_IIR_CTL_PTR)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_AUDIO_IIR_CTL_VAL)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_ULTR_CTL_1)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_ULTR_CTL_2)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_ULTR_CTL_3)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_ULTR_CTL_4)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_ULTR_CTL_5)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_ULTR_CTL_6)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_ULTR_CTL_7)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_BEACON_CTL_1)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_BEACON_CTL_2)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_BEACON_CTL_3)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_BEACON_CTL_4)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_BEACON_CTL_5)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_BEACON_CTL_6)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_BEACON_CTL_7)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_BEACON_CTL_8)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_BEACON_IIR_CTL_PTR)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_BEACON_IIR_CTL_VAL)] = 1, + [WCD9335_REG(WCD9335_SOC_MAD_INP_SEL)] = 1, +}; + +const u8 wcd9335_page6_reg_readable[WCD9335_PAGE_SIZE] = { + [WCD9335_REG(WCD9335_PAGE6_PAGE_REGISTER)] = 1, + [WCD9335_REG(WCD9335_ANA_BIAS)] = 1, + [WCD9335_REG(WCD9335_ANA_CLK_TOP)] = 1, + [WCD9335_REG(WCD9335_ANA_RCO)] = 1, + [WCD9335_REG(WCD9335_ANA_BUCK_VOUT_A)] = 1, + [WCD9335_REG(WCD9335_ANA_BUCK_VOUT_D)] = 1, + [WCD9335_REG(WCD9335_ANA_BUCK_CTL)] = 1, + [WCD9335_REG(WCD9335_ANA_BUCK_STATUS)] = 1, + [WCD9335_REG(WCD9335_ANA_RX_SUPPLIES)] = 1, + [WCD9335_REG(WCD9335_ANA_HPH)] = 1, + [WCD9335_REG(WCD9335_ANA_EAR)] = 1, + [WCD9335_REG(WCD9335_ANA_LO_1_2)] = 1, + [WCD9335_REG(WCD9335_ANA_LO_3_4)] = 1, + [WCD9335_REG(WCD9335_ANA_MAD_SETUP)] = 1, + [WCD9335_REG(WCD9335_ANA_AMIC1)] = 1, + [WCD9335_REG(WCD9335_ANA_AMIC2)] = 1, + [WCD9335_REG(WCD9335_ANA_AMIC3)] = 1, + [WCD9335_REG(WCD9335_ANA_AMIC4)] = 1, + [WCD9335_REG(WCD9335_ANA_AMIC5)] = 1, + [WCD9335_REG(WCD9335_ANA_AMIC6)] = 1, + [WCD9335_REG(WCD9335_ANA_MBHC_MECH)] = 1, + [WCD9335_REG(WCD9335_ANA_MBHC_ELECT)] = 1, + [WCD9335_REG(WCD9335_ANA_MBHC_ZDET)] = 1, + [WCD9335_REG(WCD9335_ANA_MBHC_RESULT_1)] = 1, + [WCD9335_REG(WCD9335_ANA_MBHC_RESULT_2)] = 1, + [WCD9335_REG(WCD9335_ANA_MBHC_RESULT_3)] = 1, + [WCD9335_REG(WCD9335_ANA_MBHC_BTN0)] = 1, + [WCD9335_REG(WCD9335_ANA_MBHC_BTN1)] = 1, + [WCD9335_REG(WCD9335_ANA_MBHC_BTN2)] = 1, + [WCD9335_REG(WCD9335_ANA_MBHC_BTN3)] = 1, + [WCD9335_REG(WCD9335_ANA_MBHC_BTN4)] = 1, + [WCD9335_REG(WCD9335_ANA_MBHC_BTN5)] = 1, + [WCD9335_REG(WCD9335_ANA_MBHC_BTN6)] = 1, + [WCD9335_REG(WCD9335_ANA_MBHC_BTN7)] = 1, + [WCD9335_REG(WCD9335_ANA_MICB1)] = 1, + [WCD9335_REG(WCD9335_ANA_MICB2)] = 1, + [WCD9335_REG(WCD9335_ANA_MICB2_RAMP)] = 1, + [WCD9335_REG(WCD9335_ANA_MICB3)] = 1, + [WCD9335_REG(WCD9335_ANA_MICB4)] = 1, + [WCD9335_REG(WCD9335_ANA_VBADC)] = 1, + [WCD9335_REG(WCD9335_BIAS_CTL)] = 1, + [WCD9335_REG(WCD9335_BIAS_VBG_FINE_ADJ)] = 1, + [WCD9335_REG(WCD9335_CLOCK_TEST_CTL)] = 1, + [WCD9335_REG(WCD9335_RCO_CTRL_1)] = 1, + [WCD9335_REG(WCD9335_RCO_CTRL_2)] = 1, + [WCD9335_REG(WCD9335_RCO_CAL)] = 1, + [WCD9335_REG(WCD9335_RCO_CAL_1)] = 1, + [WCD9335_REG(WCD9335_RCO_CAL_2)] = 1, + [WCD9335_REG(WCD9335_RCO_TEST_CTRL)] = 1, + [WCD9335_REG(WCD9335_RCO_CAL_OUT_1)] = 1, + [WCD9335_REG(WCD9335_RCO_CAL_OUT_2)] = 1, + [WCD9335_REG(WCD9335_RCO_CAL_OUT_3)] = 1, + [WCD9335_REG(WCD9335_RCO_CAL_OUT_4)] = 1, + [WCD9335_REG(WCD9335_RCO_CAL_OUT_5)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_MODE_1)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_MODE_2)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_MODE_3)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_MODE_4)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_VCL_1)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_VCL_2)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_VCL_3)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_CCL_1)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_CCL_2)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_CCL_3)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_CCL_4)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_CCL_5)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_CCL_6)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_CCL_7)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_CCL_8)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_CCL_9)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_CCL_10)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_FILTER_1)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_FILTER_2)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_DRIVER_1)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_DRIVER_2)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_DRIVER_3)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_CAL_CODE_EXT_1)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_CAL_CODE_EXT_2)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_CAL_CODE_OUT_1)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_CAL_CODE_OUT_2)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_TEST_1)] = 1, + [WCD9335_REG(WCD9335_SIDO_SIDO_TEST_2)] = 1, + [WCD9335_REG(WCD9335_MBHC_CTL_1)] = 1, + [WCD9335_REG(WCD9335_MBHC_CTL_2)] = 1, + [WCD9335_REG(WCD9335_MBHC_PLUG_DETECT_CTL)] = 1, + [WCD9335_REG(WCD9335_MBHC_ZDET_ANA_CTL)] = 1, + [WCD9335_REG(WCD9335_MBHC_ZDET_RAMP_CTL)] = 1, + [WCD9335_REG(WCD9335_MBHC_FSM_DEBUG)] = 1, + [WCD9335_REG(WCD9335_MBHC_TEST_CTL)] = 1, + [WCD9335_REG(WCD9335_VBADC_SUBBLOCK_EN)] = 1, + [WCD9335_REG(WCD9335_VBADC_IBIAS_FE)] = 1, + [WCD9335_REG(WCD9335_VBADC_BIAS_ADC)] = 1, + [WCD9335_REG(WCD9335_VBADC_FE_CTRL)] = 1, + [WCD9335_REG(WCD9335_VBADC_ADC_REF)] = 1, + [WCD9335_REG(WCD9335_VBADC_ADC_IO)] = 1, + [WCD9335_REG(WCD9335_VBADC_ADC_SAR)] = 1, + [WCD9335_REG(WCD9335_VBADC_DEBUG)] = 1, + [WCD9335_REG(WCD9335_VBADC_ADC_DOUTMSB)] = 1, + [WCD9335_REG(WCD9335_VBADC_ADC_DOUTLSB)] = 1, + [WCD9335_REG(WCD9335_LDOH_MODE)] = 1, + [WCD9335_REG(WCD9335_LDOH_BIAS)] = 1, + [WCD9335_REG(WCD9335_LDOH_STB_LOADS)] = 1, + [WCD9335_REG(WCD9335_LDOH_SLOWRAMP)] = 1, + [WCD9335_REG(WCD9335_MICB1_TEST_CTL_1)] = 1, + [WCD9335_REG(WCD9335_MICB1_TEST_CTL_2)] = 1, + [WCD9335_REG(WCD9335_MICB1_TEST_CTL_3)] = 1, + [WCD9335_REG(WCD9335_MICB2_TEST_CTL_1)] = 1, + [WCD9335_REG(WCD9335_MICB2_TEST_CTL_2)] = 1, + [WCD9335_REG(WCD9335_MICB2_TEST_CTL_3)] = 1, + [WCD9335_REG(WCD9335_MICB3_TEST_CTL_1)] = 1, + [WCD9335_REG(WCD9335_MICB3_TEST_CTL_2)] = 1, + [WCD9335_REG(WCD9335_MICB3_TEST_CTL_3)] = 1, + [WCD9335_REG(WCD9335_MICB4_TEST_CTL_1)] = 1, + [WCD9335_REG(WCD9335_MICB4_TEST_CTL_2)] = 1, + [WCD9335_REG(WCD9335_MICB4_TEST_CTL_3)] = 1, + [WCD9335_REG(WCD9335_TX_COM_ADC_VCM)] = 1, + [WCD9335_REG(WCD9335_TX_COM_BIAS_ATEST)] = 1, + [WCD9335_REG(WCD9335_TX_COM_ADC_INT1_IB)] = 1, + [WCD9335_REG(WCD9335_TX_COM_ADC_INT2_IB)] = 1, + [WCD9335_REG(WCD9335_TX_COM_TXFE_DIV_CTL)] = 1, + [WCD9335_REG(WCD9335_TX_COM_TXFE_DIV_START)] = 1, + [WCD9335_REG(WCD9335_TX_COM_TXFE_DIV_STOP_9P6M)] = 1, + [WCD9335_REG(WCD9335_TX_COM_TXFE_DIV_STOP_12P288M)] = 1, + [WCD9335_REG(WCD9335_TX_1_2_TEST_EN)] = 1, + [WCD9335_REG(WCD9335_TX_1_2_ADC_IB)] = 1, + [WCD9335_REG(WCD9335_TX_1_2_ATEST_REFCTL)] = 1, + [WCD9335_REG(WCD9335_TX_1_2_TEST_CTL)] = 1, + [WCD9335_REG(WCD9335_TX_1_2_TEST_BLK_EN)] = 1, + [WCD9335_REG(WCD9335_TX_1_2_TXFE_CLKDIV)] = 1, + [WCD9335_REG(WCD9335_TX_1_2_SAR1_ERR)] = 1, + [WCD9335_REG(WCD9335_TX_1_2_SAR2_ERR)] = 1, + [WCD9335_REG(WCD9335_TX_3_4_TEST_EN)] = 1, + [WCD9335_REG(WCD9335_TX_3_4_ADC_IB)] = 1, + [WCD9335_REG(WCD9335_TX_3_4_ATEST_REFCTL)] = 1, + [WCD9335_REG(WCD9335_TX_3_4_TEST_CTL)] = 1, + [WCD9335_REG(WCD9335_TX_3_4_TEST_BLK_EN)] = 1, + [WCD9335_REG(WCD9335_TX_3_4_TXFE_CLKDIV)] = 1, + [WCD9335_REG(WCD9335_TX_3_4_SAR1_ERR)] = 1, + [WCD9335_REG(WCD9335_TX_3_4_SAR2_ERR)] = 1, + [WCD9335_REG(WCD9335_TX_5_6_TEST_EN)] = 1, + [WCD9335_REG(WCD9335_TX_5_6_ADC_IB)] = 1, + [WCD9335_REG(WCD9335_TX_5_6_ATEST_REFCTL)] = 1, + [WCD9335_REG(WCD9335_TX_5_6_TEST_CTL)] = 1, + [WCD9335_REG(WCD9335_TX_5_6_TEST_BLK_EN)] = 1, + [WCD9335_REG(WCD9335_TX_5_6_TXFE_CLKDIV)] = 1, + [WCD9335_REG(WCD9335_TX_5_6_SAR1_ERR)] = 1, + [WCD9335_REG(WCD9335_TX_5_6_SAR2_ERR)] = 1, + [WCD9335_REG(WCD9335_CLASSH_MODE_1)] = 1, + [WCD9335_REG(WCD9335_CLASSH_MODE_2)] = 1, + [WCD9335_REG(WCD9335_CLASSH_MODE_3)] = 1, + [WCD9335_REG(WCD9335_CLASSH_CTRL_VCL_1)] = 1, + [WCD9335_REG(WCD9335_CLASSH_CTRL_VCL_2)] = 1, + [WCD9335_REG(WCD9335_CLASSH_CTRL_CCL_1)] = 1, + [WCD9335_REG(WCD9335_CLASSH_CTRL_CCL_2)] = 1, + [WCD9335_REG(WCD9335_CLASSH_CTRL_CCL_3)] = 1, + [WCD9335_REG(WCD9335_CLASSH_CTRL_CCL_4)] = 1, + [WCD9335_REG(WCD9335_CLASSH_CTRL_CCL_5)] = 1, + [WCD9335_REG(WCD9335_CLASSH_BUCK_TMUX_A_D)] = 1, + [WCD9335_REG(WCD9335_CLASSH_BUCK_SW_DRV_CNTL)] = 1, + [WCD9335_REG(WCD9335_CLASSH_SPARE)] = 1, + [WCD9335_REG(WCD9335_FLYBACK_EN)] = 1, + [WCD9335_REG(WCD9335_FLYBACK_VNEG_CTRL_1)] = 1, + [WCD9335_REG(WCD9335_FLYBACK_VNEG_CTRL_2)] = 1, + [WCD9335_REG(WCD9335_FLYBACK_VNEG_CTRL_3)] = 1, + [WCD9335_REG(WCD9335_FLYBACK_VNEG_CTRL_4)] = 1, + [WCD9335_REG(WCD9335_FLYBACK_VNEG_CTRL_5)] = 1, + [WCD9335_REG(WCD9335_FLYBACK_VNEG_CTRL_6)] = 1, + [WCD9335_REG(WCD9335_FLYBACK_VNEG_CTRL_7)] = 1, + [WCD9335_REG(WCD9335_FLYBACK_VNEG_CTRL_8)] = 1, + [WCD9335_REG(WCD9335_FLYBACK_VNEG_CTRL_9)] = 1, + [WCD9335_REG(WCD9335_FLYBACK_VNEG_DAC_CTRL_1)] = 1, + [WCD9335_REG(WCD9335_FLYBACK_VNEG_DAC_CTRL_2)] = 1, + [WCD9335_REG(WCD9335_FLYBACK_VNEG_DAC_CTRL_3)] = 1, + [WCD9335_REG(WCD9335_FLYBACK_VNEG_DAC_CTRL_4)] = 1, + [WCD9335_REG(WCD9335_FLYBACK_TEST_CTL)] = 1, + [WCD9335_REG(WCD9335_RX_AUX_SW_CTL)] = 1, + [WCD9335_REG(WCD9335_RX_PA_AUX_IN_CONN)] = 1, + [WCD9335_REG(WCD9335_RX_TIMER_DIV)] = 1, + [WCD9335_REG(WCD9335_RX_OCP_CTL)] = 1, + [WCD9335_REG(WCD9335_RX_OCP_COUNT)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_EAR_DAC)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_EAR_AMP)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_HPH_LDO)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_HPH_PA)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_HPH_RDAC_LDO)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_HPH_CNP1)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_HPH_LOWPOWER)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_DIFFLO_PA)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_DIFFLO_REF)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_DIFFLO_LDO)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_SELO_DAC_PA)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_BUCK_RST)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_BUCK_VREF_ERRAMP)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_FLYB_ERRAMP)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_FLYB_BUFF)] = 1, + [WCD9335_REG(WCD9335_RX_BIAS_FLYB_MID_RST)] = 1, + [WCD9335_REG(WCD9335_HPH_L_STATUS)] = 1, + [WCD9335_REG(WCD9335_HPH_R_STATUS)] = 1, + [WCD9335_REG(WCD9335_HPH_CNP_EN)] = 1, + [WCD9335_REG(WCD9335_HPH_CNP_WG_CTL)] = 1, + [WCD9335_REG(WCD9335_HPH_CNP_WG_TIME)] = 1, + [WCD9335_REG(WCD9335_HPH_OCP_CTL)] = 1, + [WCD9335_REG(WCD9335_HPH_AUTO_CHOP)] = 1, + [WCD9335_REG(WCD9335_HPH_CHOP_CTL)] = 1, + [WCD9335_REG(WCD9335_HPH_PA_CTL1)] = 1, + [WCD9335_REG(WCD9335_HPH_PA_CTL2)] = 1, + [WCD9335_REG(WCD9335_HPH_L_EN)] = 1, + [WCD9335_REG(WCD9335_HPH_L_TEST)] = 1, + [WCD9335_REG(WCD9335_HPH_L_ATEST)] = 1, + [WCD9335_REG(WCD9335_HPH_R_EN)] = 1, + [WCD9335_REG(WCD9335_HPH_R_TEST)] = 1, + [WCD9335_REG(WCD9335_HPH_R_ATEST)] = 1, + [WCD9335_REG(WCD9335_HPH_RDAC_CLK_CTL1)] = 1, + [WCD9335_REG(WCD9335_HPH_RDAC_CLK_CTL2)] = 1, + [WCD9335_REG(WCD9335_HPH_RDAC_LDO_CTL)] = 1, + [WCD9335_REG(WCD9335_HPH_RDAC_CHOP_CLK_LP_CTL)] = 1, + [WCD9335_REG(WCD9335_HPH_REFBUFF_UHQA_CTL)] = 1, + [WCD9335_REG(WCD9335_HPH_REFBUFF_LP_CTL)] = 1, + [WCD9335_REG(WCD9335_HPH_L_DAC_CTL)] = 1, + [WCD9335_REG(WCD9335_HPH_R_DAC_CTL)] = 1, + [WCD9335_REG(WCD9335_EAR_EN_REG)] = 1, + [WCD9335_REG(WCD9335_EAR_CMBUFF)] = 1, + [WCD9335_REG(WCD9335_EAR_ICTL)] = 1, + [WCD9335_REG(WCD9335_EAR_EN_DBG_CTL)] = 1, + [WCD9335_REG(WCD9335_EAR_CNP)] = 1, + [WCD9335_REG(WCD9335_EAR_DAC_CTL_ATEST)] = 1, + [WCD9335_REG(WCD9335_EAR_STATUS_REG)] = 1, + [WCD9335_REG(WCD9335_EAR_OUT_SHORT)] = 1, + [WCD9335_REG(WCD9335_DIFF_LO_MISC)] = 1, + [WCD9335_REG(WCD9335_DIFF_LO_LO2_COMPANDER)] = 1, + [WCD9335_REG(WCD9335_DIFF_LO_LO1_COMPANDER)] = 1, + [WCD9335_REG(WCD9335_DIFF_LO_COMMON)] = 1, + [WCD9335_REG(WCD9335_DIFF_LO_BYPASS_EN)] = 1, + [WCD9335_REG(WCD9335_DIFF_LO_CNP)] = 1, + [WCD9335_REG(WCD9335_DIFF_LO_CORE_OUT_PROG)] = 1, + [WCD9335_REG(WCD9335_DIFF_LO_LDO_OUT_PROG)] = 1, + [WCD9335_REG(WCD9335_DIFF_LO_COM_SWCAP_REFBUF_FREQ)] = 1, + [WCD9335_REG(WCD9335_DIFF_LO_COM_PA_FREQ)] = 1, + [WCD9335_REG(WCD9335_DIFF_LO_RESERVED_REG)] = 1, + [WCD9335_REG(WCD9335_DIFF_LO_LO1_STATUS_1)] = 1, + [WCD9335_REG(WCD9335_DIFF_LO_LO1_STATUS_2)] = 1, + [WCD9335_REG(WCD9335_SE_LO_COM1)] = 1, + [WCD9335_REG(WCD9335_SE_LO_COM2)] = 1, + [WCD9335_REG(WCD9335_SE_LO_LO3_GAIN)] = 1, + [WCD9335_REG(WCD9335_SE_LO_LO3_CTRL)] = 1, + [WCD9335_REG(WCD9335_SE_LO_LO4_GAIN)] = 1, + [WCD9335_REG(WCD9335_SE_LO_LO4_CTRL)] = 1, + [WCD9335_REG(WCD9335_SE_LO_LO3_STATUS)] = 1, + [WCD9335_REG(WCD9335_SE_LO_LO4_STATUS)] = 1, +}; + +const u8 wcd9335_page10_reg_readable[WCD9335_PAGE_SIZE] = { + [WCD9335_REG(WCD9335_PAGE10_PAGE_REGISTER)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC0_CLK_RESET_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC0_MODE_1_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC0_MODE_2_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC0_FF_SHIFT)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC0_FB_SHIFT)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC0_LPF_FF_A_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC0_LPF_FF_B_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC0_LPF_FB_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC0_SMLPF_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC0_DCFLT_SHIFT_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC0_IIR_ADAPT_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC0_IIR_COEFF_1_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC0_IIR_COEFF_2_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC0_FF_A_GAIN_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC0_FF_B_GAIN_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC0_FB_GAIN_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC1_CLK_RESET_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC1_MODE_1_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC1_MODE_2_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC1_FF_SHIFT)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC1_FB_SHIFT)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC1_LPF_FF_A_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC1_LPF_FF_B_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC1_LPF_FB_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC1_SMLPF_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC1_DCFLT_SHIFT_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC1_IIR_ADAPT_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC1_IIR_COEFF_1_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC1_IIR_COEFF_2_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC1_FF_A_GAIN_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC1_FF_B_GAIN_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_ANC1_FB_GAIN_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX0_TX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX0_TX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX0_TX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX0_TX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX0_TX_PATH_192_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX0_TX_PATH_192_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_TX0_TX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX0_TX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX0_TX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_TX0_TX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_TX0_TX_PATH_SEC4)] = 1, + [WCD9335_REG(WCD9335_CDC_TX0_TX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_TX0_TX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_TX0_TX_PATH_SEC7)] = 1, + [WCD9335_REG(WCD9335_CDC_TX1_TX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX1_TX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX1_TX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX1_TX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX1_TX_PATH_192_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX1_TX_PATH_192_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_TX1_TX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX1_TX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX1_TX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_TX1_TX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_TX1_TX_PATH_SEC4)] = 1, + [WCD9335_REG(WCD9335_CDC_TX1_TX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_TX1_TX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_TX2_TX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX2_TX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX2_TX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX2_TX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX2_TX_PATH_192_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX2_TX_PATH_192_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_TX2_TX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX2_TX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX2_TX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_TX2_TX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_TX2_TX_PATH_SEC4)] = 1, + [WCD9335_REG(WCD9335_CDC_TX2_TX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_TX2_TX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_TX3_TX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX3_TX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX3_TX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX3_TX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX3_TX_PATH_192_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX3_TX_PATH_192_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_TX3_TX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX3_TX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX3_TX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_TX3_TX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_TX3_TX_PATH_SEC4)] = 1, + [WCD9335_REG(WCD9335_CDC_TX3_TX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_TX3_TX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_TX4_TX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX4_TX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX4_TX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX4_TX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX4_TX_PATH_192_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX4_TX_PATH_192_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_TX4_TX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX4_TX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX4_TX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_TX4_TX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_TX4_TX_PATH_SEC4)] = 1, + [WCD9335_REG(WCD9335_CDC_TX4_TX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_TX4_TX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_TX5_TX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX5_TX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX5_TX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX5_TX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX5_TX_PATH_192_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX5_TX_PATH_192_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_TX5_TX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX5_TX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX5_TX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_TX5_TX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_TX5_TX_PATH_SEC4)] = 1, + [WCD9335_REG(WCD9335_CDC_TX5_TX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_TX5_TX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_TX6_TX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX6_TX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX6_TX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX6_TX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX6_TX_PATH_192_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX6_TX_PATH_192_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_TX6_TX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX6_TX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX6_TX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_TX6_TX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_TX6_TX_PATH_SEC4)] = 1, + [WCD9335_REG(WCD9335_CDC_TX6_TX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_TX6_TX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_TX7_TX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX7_TX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX7_TX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX7_TX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX7_TX_PATH_192_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX7_TX_PATH_192_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_TX7_TX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX7_TX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX7_TX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_TX7_TX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_TX7_TX_PATH_SEC4)] = 1, + [WCD9335_REG(WCD9335_CDC_TX7_TX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_TX7_TX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_TX8_TX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX8_TX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX8_TX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX8_TX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX8_TX_PATH_192_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX8_TX_PATH_192_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_TX8_TX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX8_TX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX8_TX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_TX8_TX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_TX8_TX_PATH_SEC4)] = 1, + [WCD9335_REG(WCD9335_CDC_TX8_TX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_TX8_TX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX9_SPKR_PROT_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX10_SPKR_PROT_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX11_SPKR_PROT_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TX12_SPKR_PROT_PATH_CFG0)] = 1, +}; + +const u8 wcd9335_page11_reg_readable[WCD9335_PAGE_SIZE] = { + [WCD9335_REG(WCD9335_PAGE11_PAGE_REGISTER)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER1_CTL0)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER1_CTL1)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER1_CTL2)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER1_CTL3)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER1_CTL4)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER1_CTL5)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER1_CTL6)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER1_CTL7)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER2_CTL0)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER2_CTL1)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER2_CTL2)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER2_CTL3)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER2_CTL4)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER2_CTL5)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER2_CTL6)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER2_CTL7)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER3_CTL0)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER3_CTL1)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER3_CTL2)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER3_CTL3)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER3_CTL4)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER3_CTL5)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER3_CTL6)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER3_CTL7)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER4_CTL0)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER4_CTL1)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER4_CTL2)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER4_CTL3)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER4_CTL4)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER4_CTL5)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER4_CTL6)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER4_CTL7)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER5_CTL0)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER5_CTL1)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER5_CTL2)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER5_CTL3)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER5_CTL4)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER5_CTL5)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER5_CTL6)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER5_CTL7)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER6_CTL0)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER6_CTL1)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER6_CTL2)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER6_CTL3)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER6_CTL4)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER6_CTL5)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER6_CTL6)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER6_CTL7)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER7_CTL0)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER7_CTL1)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER7_CTL2)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER7_CTL3)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER7_CTL4)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER7_CTL5)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER7_CTL6)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER7_CTL7)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER8_CTL0)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER8_CTL1)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER8_CTL2)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER8_CTL3)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER8_CTL4)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER8_CTL5)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER8_CTL6)] = 1, + [WCD9335_REG(WCD9335_CDC_COMPANDER8_CTL7)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_PATH_CFG2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_PATH_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_PATH_MIX_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_VOL_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_PATH_SEC7)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_PATH_MIX_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX0_RX_PATH_MIX_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_PATH_CFG2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_PATH_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_PATH_MIX_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_VOL_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_PATH_SEC4)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_PATH_SEC7)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_PATH_MIX_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX1_RX_PATH_MIX_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_PATH_CFG2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_PATH_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_PATH_MIX_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_VOL_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_PATH_SEC4)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_PATH_SEC7)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_PATH_MIX_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX2_RX_PATH_MIX_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_PATH_CFG2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_PATH_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_PATH_MIX_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_VOL_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_PATH_SEC7)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_PATH_MIX_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX3_RX_PATH_MIX_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_PATH_CFG2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_PATH_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_PATH_MIX_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_VOL_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_PATH_SEC7)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_PATH_MIX_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX4_RX_PATH_MIX_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_PATH_CFG2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_PATH_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_PATH_MIX_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_VOL_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_PATH_SEC7)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_PATH_MIX_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX5_RX_PATH_MIX_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_PATH_CFG2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_PATH_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_PATH_MIX_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_VOL_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_PATH_SEC7)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_PATH_MIX_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX6_RX_PATH_MIX_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_PATH_CFG2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_PATH_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_PATH_MIX_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_VOL_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_PATH_SEC7)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_PATH_MIX_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX7_RX_PATH_MIX_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_PATH_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_PATH_CFG2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_VOL_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_PATH_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_PATH_MIX_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_VOL_MIX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_PATH_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_PATH_SEC1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_PATH_SEC2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_PATH_SEC3)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_PATH_SEC5)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_PATH_SEC6)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_PATH_SEC7)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_PATH_MIX_SEC0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX8_RX_PATH_MIX_SEC1)] = 1, +}; + +const u8 wcd9335_page12_reg_readable[WCD9335_PAGE_SIZE] = { + [WCD9335_REG(WCD9335_PAGE12_PAGE_REGISTER)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_CRC)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_DLY_CTRL)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_DECAY_CTRL)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_HPH_V_PA)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_EAR_V_PA)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_HPH_V_HD)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_EAR_V_HD)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_K1_MSB)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_K1_LSB)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_K2_MSB)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_K2_LSB)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_IDLE_CTRL)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_IDLE_HPH)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_IDLE_EAR)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_TEST0)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_TEST1)] = 1, + [WCD9335_REG(WCD9335_CDC_CLSH_OVR_VREF)] = 1, + [WCD9335_REG(WCD9335_CDC_BOOST0_BOOST_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_BOOST0_BOOST_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_BOOST0_BOOST_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_BOOST0_BOOST_CFG2)] = 1, + [WCD9335_REG(WCD9335_CDC_BOOST1_BOOST_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_BOOST1_BOOST_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_BOOST1_BOOST_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_BOOST1_BOOST_CFG2)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_WR_DATA_0)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_WR_DATA_1)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_WR_DATA_2)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_WR_DATA_3)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_WR_ADDR_1)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_WR_ADDR_2)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_WR_ADDR_3)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_RD_ADDR_0)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_RD_ADDR_1)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_RD_ADDR_2)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_RD_ADDR_3)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_RD_DATA_0)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_RD_DATA_1)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_RD_DATA_2)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_RD_DATA_3)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_ACCESS_CFG)] = 1, + [WCD9335_REG(WCD9335_SWR_AHB_BRIDGE_ACCESS_STATUS)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_CFG)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_ADC_CAL1)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_ADC_CAL2)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_ADC_CAL3)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_PK_EST1)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_PK_EST2)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_PK_EST3)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_RF_PROC1)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_RF_PROC2)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_TAC1)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_TAC2)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_TAC3)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_TAC4)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_GAIN_UPD1)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_GAIN_UPD2)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_GAIN_UPD3)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_GAIN_UPD4)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_DEBUG1)] = 1, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_GAIN_UPD_MON)] = 0, + [WCD9335_REG(WCD9335_CDC_VBAT_VBAT_GAIN_MON_VAL)] = 1, + [WCD9335_REG(WCD9335_SPLINE_SRC0_CLK_RST_CTL_0)] = 1, + [WCD9335_REG(WCD9335_SPLINE_SRC0_STATUS)] = 1, + [WCD9335_REG(WCD9335_SPLINE_SRC1_CLK_RST_CTL_0)] = 1, + [WCD9335_REG(WCD9335_SPLINE_SRC1_STATUS)] = 1, + [WCD9335_REG(WCD9335_SPLINE_SRC2_CLK_RST_CTL_0)] = 1, + [WCD9335_REG(WCD9335_SPLINE_SRC2_STATUS)] = 1, + [WCD9335_REG(WCD9335_SPLINE_SRC3_CLK_RST_CTL_0)] = 1, + [WCD9335_REG(WCD9335_SPLINE_SRC3_STATUS)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_SRC1_ST_SRC_PATH_CFG1)] = 1, +}; + +const u8 wcd9335_page13_reg_readable[WCD9335_PAGE_SIZE] = { + [WCD9335_REG(WCD9335_PAGE13_PAGE_REGISTER)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG2)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG3)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG4)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_ANC_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3)] = 1, + [WCD9335_REG(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2)] = 1, + [WCD9335_REG(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3)] = 1, + [WCD9335_REG(WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL)] = 1, + [WCD9335_REG(WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL)] = 1, + [WCD9335_REG(WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL)] = 1, + [WCD9335_REG(WCD9335_CDC_PROX_DETECT_PROX_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_PROX_DETECT_PROX_POLL_PERIOD0)] = 1, + [WCD9335_REG(WCD9335_CDC_PROX_DETECT_PROX_POLL_PERIOD1)] = 1, + [WCD9335_REG(WCD9335_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB)] = 1, + [WCD9335_REG(WCD9335_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB)] = 1, + [WCD9335_REG(WCD9335_CDC_PROX_DETECT_PROX_STATUS)] = 1, + [WCD9335_REG(WCD9335_CDC_PROX_DETECT_PROX_TEST_CTRL)] = 1, + [WCD9335_REG(WCD9335_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB)] = 1, + [WCD9335_REG(WCD9335_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB)] = 1, + [WCD9335_REG(WCD9335_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD)] = 1, + [WCD9335_REG(WCD9335_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD)] = 1, + [WCD9335_REG(WCD9335_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR0_IIR_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR0_IIR_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR1_IIR_PATH_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B5_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B6_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B7_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B8_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR1_IIR_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR1_IIR_COEF_B1_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_SIDETONE_IIR1_IIR_COEF_B2_CTL)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_TOP_CFG0)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_TOP_CFG1)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_TOP_CFG2)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_TOP_CFG3)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_TOP_CFG4)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_TOP_CFG5)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_TOP_CFG6)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_TOP_CFG7)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_HPHL_COMP_WR_LSB)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_HPHL_COMP_WR_MSB)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_HPHL_COMP_LUT)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_HPHL_COMP_RD_LSB)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_HPHL_COMP_RD_MSB)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_HPHR_COMP_WR_LSB)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_HPHR_COMP_WR_MSB)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_HPHR_COMP_LUT)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_HPHR_COMP_RD_LSB)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_HPHR_COMP_RD_MSB)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_DIFFL_COMP_WR_LSB)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_DIFFL_COMP_WR_MSB)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_DIFFL_COMP_LUT)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_DIFFL_COMP_RD_LSB)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_DIFFL_COMP_RD_MSB)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_DIFFR_COMP_WR_LSB)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_DIFFR_COMP_WR_MSB)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_DIFFR_COMP_LUT)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_DIFFR_COMP_RD_LSB)] = 1, + [WCD9335_REG(WCD9335_CDC_TOP_DIFFR_COMP_RD_MSB)] = 1, +}; + +const u8 wcd9335_page_0x80_reg_readable[WCD9335_PAGE_SIZE] = { + [WCD9335_REG(WCD9335_PAGE80_PAGE_REGISTER)] = 1, + [WCD9335_REG(WCD9335_TLMM_BIST_MODE_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_RF_PA_ON_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_INTR1_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_INTR2_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_SWR_DATA_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_SWR_CLK_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_SLIMBUS_DATA2_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_I2C_CLK_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_I2C_DATA_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_I2S_RX_SD0_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_I2S_RX_SD1_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_I2S_RX_SCK_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_I2S_RX_WS_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_I2S_TX_SD0_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_I2S_TX_SD1_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_I2S_TX_SCK_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_I2S_TX_WS_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_DMIC1_CLK_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_DMIC1_DATA_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_DMIC2_CLK_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_DMIC2_DATA_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_DMIC3_CLK_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_DMIC3_DATA_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_JTDI_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_JTDO_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_JTMS_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_JTCK_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TLMM_JTRST_PINCFG)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_PIN_CTL_OE_0)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_PIN_CTL_OE_1)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_PIN_CTL_OE_2)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_PIN_CTL_OE_3)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_PIN_CTL_DATA_0)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_PIN_CTL_DATA_1)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_PIN_CTL_DATA_2)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_PIN_CTL_DATA_3)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_PAD_DRVCTL)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_PIN_STATUS)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_NPL_DLY_TEST_1)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_NPL_DLY_TEST_2)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_MEM_CTRL)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_DEBUG_BUS_SEL)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_DEBUG_JTAG)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_DEBUG_EN_1)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_DEBUG_EN_2)] = 1, + [WCD9335_REG(WCD9335_TEST_DEBUG_DEBUG_EN_3)] = 1, +}; + +const u8 *wcd9335_reg[WCD9335_NUM_PAGES] = { + [PAGE_0] = wcd9335_page0_reg_readable, + [PAGE_1] = wcd9335_page1_reg_readable, + [PAGE_2] = wcd9335_page2_reg_readable, + [PAGE_6] = wcd9335_page6_reg_readable, + [PAGE_10] = wcd9335_page10_reg_readable, + [PAGE_11] = wcd9335_page11_reg_readable, + [PAGE_12] = wcd9335_page12_reg_readable, + [PAGE_13] = wcd9335_page13_reg_readable, + [PAGE_0X80] = wcd9335_page_0x80_reg_readable, +}; diff --git a/drivers/mfd/wcd934x-regmap.c b/drivers/mfd/wcd934x-regmap.c new file mode 100644 index 000000000000..27249eeec013 --- /dev/null +++ b/drivers/mfd/wcd934x-regmap.c @@ -0,0 +1,1957 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include "wcd9xxx-regmap.h" + + +static const struct reg_sequence wcd934x_1_1_defaults[] = { + { WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE0, 0x01 }, + { WCD934X_BIAS_VBG_FINE_ADJ, 0x75 }, + { WCD934X_HPH_REFBUFF_LP_CTL, 0x0E }, + { WCD934X_EAR_DAC_CTL_ATEST, 0x08 }, + { WCD934X_SIDO_NEW_VOUT_A_STARTUP, 0x17 }, + { WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, 0x40 }, + { WCD934X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x81 }, + { WCD934X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x81 }, +}; + +static const struct reg_default wcd934x_defaults[] = { + { WCD934X_PAGE0_PAGE_REGISTER, 0x00 }, + { WCD934X_CODEC_RPM_CLK_BYPASS, 0x00 }, + { WCD934X_CODEC_RPM_CLK_GATE, 0x1f }, + { WCD934X_CODEC_RPM_CLK_MCLK_CFG, 0x00 }, + { WCD934X_CODEC_RPM_CLK_MCLK2_CFG, 0x02 }, + { WCD934X_CODEC_RPM_I2S_DSD_CLK_SEL, 0x00 }, + { WCD934X_CODEC_RPM_RST_CTL, 0x00 }, + { WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x04 }, + { WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE0, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE1, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE2, 0x08 }, + { WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE3, 0x01 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_CTL, 0x10 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_TEST0, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_TEST1, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT0, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT1, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT2, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT3, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT4, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT5, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT6, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT7, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT8, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT9, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT10, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT11, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT12, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT13, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT14, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT15, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_EFUSE_STATUS, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO, 0x0d }, + { WCD934X_CHIP_TIER_CTRL_I2C_SLAVE_ID_1, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_I2C_SLAVE_ID_2, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_I2C_SLAVE_ID_3, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL, 0xcc }, + { WCD934X_CHIP_TIER_CTRL_SLNQ_WAIT_STATE_CTL, 0xcc }, + { WCD934X_CHIP_TIER_CTRL_I2C_ACTIVE, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_ALT_FUNC_EN, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_GPIO_CTL_OE, 0x00 }, + { WCD934X_CHIP_TIER_CTRL_GPIO_CTL_DATA, 0x00 }, + { WCD934X_DATA_HUB_RX0_CFG, 0x00 }, + { WCD934X_DATA_HUB_RX1_CFG, 0x00 }, + { WCD934X_DATA_HUB_RX2_CFG, 0x00 }, + { WCD934X_DATA_HUB_RX3_CFG, 0x00 }, + { WCD934X_DATA_HUB_RX4_CFG, 0x00 }, + { WCD934X_DATA_HUB_RX5_CFG, 0x00 }, + { WCD934X_DATA_HUB_RX6_CFG, 0x00 }, + { WCD934X_DATA_HUB_RX7_CFG, 0x00 }, + { WCD934X_DATA_HUB_SB_TX0_INP_CFG, 0x00 }, + { WCD934X_DATA_HUB_SB_TX1_INP_CFG, 0x00 }, + { WCD934X_DATA_HUB_SB_TX2_INP_CFG, 0x00 }, + { WCD934X_DATA_HUB_SB_TX3_INP_CFG, 0x00 }, + { WCD934X_DATA_HUB_SB_TX4_INP_CFG, 0x00 }, + { WCD934X_DATA_HUB_SB_TX5_INP_CFG, 0x00 }, + { WCD934X_DATA_HUB_SB_TX6_INP_CFG, 0x00 }, + { WCD934X_DATA_HUB_SB_TX7_INP_CFG, 0x00 }, + { WCD934X_DATA_HUB_SB_TX8_INP_CFG, 0x00 }, + { WCD934X_DATA_HUB_SB_TX9_INP_CFG, 0x00 }, + { WCD934X_DATA_HUB_SB_TX10_INP_CFG, 0x00 }, + { WCD934X_DATA_HUB_SB_TX11_INP_CFG, 0x00 }, + { WCD934X_DATA_HUB_SB_TX13_INP_CFG, 0x00 }, + { WCD934X_DATA_HUB_SB_TX14_INP_CFG, 0x00 }, + { WCD934X_DATA_HUB_SB_TX15_INP_CFG, 0x00 }, + { WCD934X_DATA_HUB_I2S_TX0_CFG, 0x00 }, + { WCD934X_DATA_HUB_I2S_TX1_0_CFG, 0x00 }, + { WCD934X_DATA_HUB_I2S_TX1_1_CFG, 0x00 }, + { WCD934X_DATA_HUB_I2S_0_CTL, 0x0c }, + { WCD934X_DATA_HUB_I2S_1_CTL, 0x0c }, + { WCD934X_DATA_HUB_I2S_2_CTL, 0x0c }, + { WCD934X_DATA_HUB_I2S_3_CTL, 0x0c }, + { WCD934X_DATA_HUB_I2S_CLKSRC_CTL, 0x00 }, + { WCD934X_DATA_HUB_I2S_COMMON_CTL, 0x00 }, + { WCD934X_DATA_HUB_I2S_0_TDM_CTL, 0x00 }, + { WCD934X_DATA_HUB_I2S_STATUS, 0x00 }, + { WCD934X_DMA_RDMA_CTL_0, 0x00 }, + { WCD934X_DMA_CH_2_3_CFG_RDMA_0, 0xff }, + { WCD934X_DMA_CH_0_1_CFG_RDMA_0, 0xff }, + { WCD934X_DMA_RDMA_CTL_1, 0x00 }, + { WCD934X_DMA_CH_2_3_CFG_RDMA_1, 0xff }, + { WCD934X_DMA_CH_0_1_CFG_RDMA_1, 0xff }, + { WCD934X_DMA_RDMA_CTL_2, 0x00 }, + { WCD934X_DMA_CH_2_3_CFG_RDMA_2, 0xff }, + { WCD934X_DMA_CH_0_1_CFG_RDMA_2, 0xff }, + { WCD934X_DMA_RDMA_CTL_3, 0x00 }, + { WCD934X_DMA_CH_2_3_CFG_RDMA_3, 0xff }, + { WCD934X_DMA_CH_0_1_CFG_RDMA_3, 0xff }, + { WCD934X_DMA_RDMA_CTL_4, 0x00 }, + { WCD934X_DMA_CH_2_3_CFG_RDMA_4, 0xff }, + { WCD934X_DMA_CH_0_1_CFG_RDMA_4, 0xff }, + { WCD934X_DMA_RDMA4_PRT_CFG, 0x00 }, + { WCD934X_DMA_RDMA_SBTX0_7_CFG, 0x00 }, + { WCD934X_DMA_RDMA_SBTX8_11_CFG, 0x00 }, + { WCD934X_DMA_WDMA_CTL_0, 0x00 }, + { WCD934X_DMA_CH_4_5_CFG_WDMA_0, 0x00 }, + { WCD934X_DMA_CH_2_3_CFG_WDMA_0, 0x00 }, + { WCD934X_DMA_CH_0_1_CFG_WDMA_0, 0x00 }, + { WCD934X_DMA_WDMA_CTL_1, 0x00 }, + { WCD934X_DMA_CH_4_5_CFG_WDMA_1, 0x00 }, + { WCD934X_DMA_CH_2_3_CFG_WDMA_1, 0x00 }, + { WCD934X_DMA_CH_0_1_CFG_WDMA_1, 0x00 }, + { WCD934X_DMA_WDMA_CTL_2, 0x00 }, + { WCD934X_DMA_CH_4_5_CFG_WDMA_2, 0x00 }, + { WCD934X_DMA_CH_2_3_CFG_WDMA_2, 0x00 }, + { WCD934X_DMA_CH_0_1_CFG_WDMA_2, 0x00 }, + { WCD934X_DMA_WDMA_CTL_3, 0x00 }, + { WCD934X_DMA_CH_4_5_CFG_WDMA_3, 0x00 }, + { WCD934X_DMA_CH_2_3_CFG_WDMA_3, 0x00 }, + { WCD934X_DMA_CH_0_1_CFG_WDMA_3, 0x00 }, + { WCD934X_DMA_WDMA_CTL_4, 0x00 }, + { WCD934X_DMA_CH_4_5_CFG_WDMA_4, 0x00 }, + { WCD934X_DMA_CH_2_3_CFG_WDMA_4, 0x00 }, + { WCD934X_DMA_CH_0_1_CFG_WDMA_4, 0x00 }, + { WCD934X_DMA_WDMA0_PRT_CFG, 0x00 }, + { WCD934X_DMA_WDMA3_PRT_CFG, 0x00 }, + { WCD934X_DMA_WDMA4_PRT0_3_CFG, 0x00 }, + { WCD934X_DMA_WDMA4_PRT4_7_CFG, 0x00 }, + { WCD934X_PAGE1_PAGE_REGISTER, 0x00 }, + { WCD934X_CPE_FLL_USER_CTL_0, 0x71 }, + { WCD934X_CPE_FLL_USER_CTL_1, 0x34 }, + { WCD934X_CPE_FLL_USER_CTL_2, 0x0b }, + { WCD934X_CPE_FLL_USER_CTL_3, 0x02 }, + { WCD934X_CPE_FLL_USER_CTL_4, 0x04 }, + { WCD934X_CPE_FLL_USER_CTL_5, 0x02 }, + { WCD934X_CPE_FLL_USER_CTL_6, 0x6e }, + { WCD934X_CPE_FLL_USER_CTL_7, 0x00 }, + { WCD934X_CPE_FLL_USER_CTL_8, 0x94 }, + { WCD934X_CPE_FLL_USER_CTL_9, 0x50 }, + { WCD934X_CPE_FLL_L_VAL_CTL_0, 0x53 }, + { WCD934X_CPE_FLL_L_VAL_CTL_1, 0x00 }, + { WCD934X_CPE_FLL_DSM_FRAC_CTL_0, 0x00 }, + { WCD934X_CPE_FLL_DSM_FRAC_CTL_1, 0xff }, + { WCD934X_CPE_FLL_CONFIG_CTL_0, 0x6b }, + { WCD934X_CPE_FLL_CONFIG_CTL_1, 0x05 }, + { WCD934X_CPE_FLL_CONFIG_CTL_2, 0x08 }, + { WCD934X_CPE_FLL_CONFIG_CTL_3, 0x00 }, + { WCD934X_CPE_FLL_CONFIG_CTL_4, 0x10 }, + { WCD934X_CPE_FLL_TEST_CTL_0, 0x80 }, + { WCD934X_CPE_FLL_TEST_CTL_1, 0x00 }, + { WCD934X_CPE_FLL_TEST_CTL_2, 0x00 }, + { WCD934X_CPE_FLL_TEST_CTL_3, 0x00 }, + { WCD934X_CPE_FLL_TEST_CTL_4, 0x00 }, + { WCD934X_CPE_FLL_TEST_CTL_5, 0x00 }, + { WCD934X_CPE_FLL_TEST_CTL_6, 0x00 }, + { WCD934X_CPE_FLL_TEST_CTL_7, 0x33 }, + { WCD934X_CPE_FLL_FREQ_CTL_0, 0x00 }, + { WCD934X_CPE_FLL_FREQ_CTL_1, 0x00 }, + { WCD934X_CPE_FLL_FREQ_CTL_2, 0x00 }, + { WCD934X_CPE_FLL_FREQ_CTL_3, 0x00 }, + { WCD934X_CPE_FLL_SSC_CTL_0, 0x00 }, + { WCD934X_CPE_FLL_SSC_CTL_1, 0x00 }, + { WCD934X_CPE_FLL_SSC_CTL_2, 0x00 }, + { WCD934X_CPE_FLL_SSC_CTL_3, 0x00 }, + { WCD934X_CPE_FLL_FLL_MODE, 0x20 }, + { WCD934X_CPE_FLL_STATUS_0, 0x00 }, + { WCD934X_CPE_FLL_STATUS_1, 0x00 }, + { WCD934X_CPE_FLL_STATUS_2, 0x00 }, + { WCD934X_CPE_FLL_STATUS_3, 0x00 }, + { WCD934X_I2S_FLL_USER_CTL_0, 0x41 }, + { WCD934X_I2S_FLL_USER_CTL_1, 0x94 }, + { WCD934X_I2S_FLL_USER_CTL_2, 0x08 }, + { WCD934X_I2S_FLL_USER_CTL_3, 0x02 }, + { WCD934X_I2S_FLL_USER_CTL_4, 0x04 }, + { WCD934X_I2S_FLL_USER_CTL_5, 0x02 }, + { WCD934X_I2S_FLL_USER_CTL_6, 0x40 }, + { WCD934X_I2S_FLL_USER_CTL_7, 0x00 }, + { WCD934X_I2S_FLL_USER_CTL_8, 0x5f }, + { WCD934X_I2S_FLL_USER_CTL_9, 0x02 }, + { WCD934X_I2S_FLL_L_VAL_CTL_0, 0x40 }, + { WCD934X_I2S_FLL_L_VAL_CTL_1, 0x00 }, + { WCD934X_I2S_FLL_DSM_FRAC_CTL_0, 0x00 }, + { WCD934X_I2S_FLL_DSM_FRAC_CTL_1, 0xff }, + { WCD934X_I2S_FLL_CONFIG_CTL_0, 0x6b }, + { WCD934X_I2S_FLL_CONFIG_CTL_1, 0x05 }, + { WCD934X_I2S_FLL_CONFIG_CTL_2, 0x08 }, + { WCD934X_I2S_FLL_CONFIG_CTL_3, 0x00 }, + { WCD934X_I2S_FLL_CONFIG_CTL_4, 0x30 }, + { WCD934X_I2S_FLL_TEST_CTL_0, 0x80 }, + { WCD934X_I2S_FLL_TEST_CTL_1, 0x00 }, + { WCD934X_I2S_FLL_TEST_CTL_2, 0x00 }, + { WCD934X_I2S_FLL_TEST_CTL_3, 0x00 }, + { WCD934X_I2S_FLL_TEST_CTL_4, 0x00 }, + { WCD934X_I2S_FLL_TEST_CTL_5, 0x00 }, + { WCD934X_I2S_FLL_TEST_CTL_6, 0x00 }, + { WCD934X_I2S_FLL_TEST_CTL_7, 0xff }, + { WCD934X_I2S_FLL_FREQ_CTL_0, 0x00 }, + { WCD934X_I2S_FLL_FREQ_CTL_1, 0x00 }, + { WCD934X_I2S_FLL_FREQ_CTL_2, 0x00 }, + { WCD934X_I2S_FLL_FREQ_CTL_3, 0x00 }, + { WCD934X_I2S_FLL_SSC_CTL_0, 0x00 }, + { WCD934X_I2S_FLL_SSC_CTL_1, 0x00 }, + { WCD934X_I2S_FLL_SSC_CTL_2, 0x00 }, + { WCD934X_I2S_FLL_SSC_CTL_3, 0x00 }, + { WCD934X_I2S_FLL_FLL_MODE, 0x00 }, + { WCD934X_I2S_FLL_STATUS_0, 0x00 }, + { WCD934X_I2S_FLL_STATUS_1, 0x00 }, + { WCD934X_I2S_FLL_STATUS_2, 0x00 }, + { WCD934X_I2S_FLL_STATUS_3, 0x00 }, + { WCD934X_SB_FLL_USER_CTL_0, 0x41 }, + { WCD934X_SB_FLL_USER_CTL_1, 0x94 }, + { WCD934X_SB_FLL_USER_CTL_2, 0x08 }, + { WCD934X_SB_FLL_USER_CTL_3, 0x02 }, + { WCD934X_SB_FLL_USER_CTL_4, 0x04 }, + { WCD934X_SB_FLL_USER_CTL_5, 0x02 }, + { WCD934X_SB_FLL_USER_CTL_6, 0x40 }, + { WCD934X_SB_FLL_USER_CTL_7, 0x00 }, + { WCD934X_SB_FLL_USER_CTL_8, 0x5e }, + { WCD934X_SB_FLL_USER_CTL_9, 0x01 }, + { WCD934X_SB_FLL_L_VAL_CTL_0, 0x40 }, + { WCD934X_SB_FLL_L_VAL_CTL_1, 0x00 }, + { WCD934X_SB_FLL_DSM_FRAC_CTL_0, 0x00 }, + { WCD934X_SB_FLL_DSM_FRAC_CTL_1, 0xff }, + { WCD934X_SB_FLL_CONFIG_CTL_0, 0x6b }, + { WCD934X_SB_FLL_CONFIG_CTL_1, 0x05 }, + { WCD934X_SB_FLL_CONFIG_CTL_2, 0x08 }, + { WCD934X_SB_FLL_CONFIG_CTL_3, 0x00 }, + { WCD934X_SB_FLL_CONFIG_CTL_4, 0x10 }, + { WCD934X_SB_FLL_TEST_CTL_0, 0x00 }, + { WCD934X_SB_FLL_TEST_CTL_1, 0x00 }, + { WCD934X_SB_FLL_TEST_CTL_2, 0x00 }, + { WCD934X_SB_FLL_TEST_CTL_3, 0x00 }, + { WCD934X_SB_FLL_TEST_CTL_4, 0x00 }, + { WCD934X_SB_FLL_TEST_CTL_5, 0x00 }, + { WCD934X_SB_FLL_TEST_CTL_6, 0x00 }, + { WCD934X_SB_FLL_TEST_CTL_7, 0xff }, + { WCD934X_SB_FLL_FREQ_CTL_0, 0x00 }, + { WCD934X_SB_FLL_FREQ_CTL_1, 0x00 }, + { WCD934X_SB_FLL_FREQ_CTL_2, 0x00 }, + { WCD934X_SB_FLL_FREQ_CTL_3, 0x00 }, + { WCD934X_SB_FLL_SSC_CTL_0, 0x00 }, + { WCD934X_SB_FLL_SSC_CTL_1, 0x00 }, + { WCD934X_SB_FLL_SSC_CTL_2, 0x00 }, + { WCD934X_SB_FLL_SSC_CTL_3, 0x00 }, + { WCD934X_SB_FLL_FLL_MODE, 0x00 }, + { WCD934X_SB_FLL_STATUS_0, 0x00 }, + { WCD934X_SB_FLL_STATUS_1, 0x00 }, + { WCD934X_SB_FLL_STATUS_2, 0x00 }, + { WCD934X_SB_FLL_STATUS_3, 0x00 }, + { WCD934X_PAGE2_PAGE_REGISTER, 0x00 }, + { WCD934X_CPE_SS_CPE_CTL, 0x05 }, + { WCD934X_CPE_SS_PWR_SYS_PSTATE_CTL_0, 0x01 }, + { WCD934X_CPE_SS_PWR_SYS_PSTATE_CTL_1, 0x00 }, + { WCD934X_CPE_SS_PWR_CPEFLL_CTL, 0x02 }, + { WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, 0xff }, + { WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, 0x0f }, + { WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_OVERRIDE, 0x00 }, + { WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0, 0xff }, + { WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1, 0xff }, + { WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2, 0xff }, + { WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3, 0xff }, + { WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_4, 0xff }, + { WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_5, 0xff }, + { WCD934X_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN, 0x07 }, + { WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL, 0x00 }, + { WCD934X_CPE_SS_SOC_SW_COLLAPSE_OVERRIDE_CTL, 0x20 }, + { WCD934X_CPE_SS_SOC_SW_COLLAPSE_OVERRIDE_CTL1, 0x00 }, + { WCD934X_CPE_SS_US_BUF_INT_PERIOD, 0x60 }, + { WCD934X_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD, 0x13 }, + { WCD934X_CPE_SS_SVA_CFG, 0x41 }, + { WCD934X_CPE_SS_US_CFG, 0x00 }, + { WCD934X_CPE_SS_MAD_CTL, 0x00 }, + { WCD934X_CPE_SS_CPAR_CTL, 0x00 }, + { WCD934X_CPE_SS_DMIC0_CTL, 0x00 }, + { WCD934X_CPE_SS_DMIC1_CTL, 0x00 }, + { WCD934X_CPE_SS_DMIC2_CTL, 0x00 }, + { WCD934X_CPE_SS_DMIC_CFG, 0x80 }, + { WCD934X_CPE_SS_CPAR_CFG, 0x00 }, + { WCD934X_CPE_SS_WDOG_CFG, 0x01 }, + { WCD934X_CPE_SS_BACKUP_INT, 0x00 }, + { WCD934X_CPE_SS_STATUS, 0x00 }, + { WCD934X_CPE_SS_CPE_OCD_CFG, 0x00 }, + { WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, 0xff }, + { WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, 0x3f }, + { WCD934X_CPE_SS_SS_ERROR_INT_MASK_1A, 0xff }, + { WCD934X_CPE_SS_SS_ERROR_INT_MASK_1B, 0x3f }, + { WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0A, 0x00 }, + { WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0B, 0x00 }, + { WCD934X_CPE_SS_SS_ERROR_INT_STATUS_1A, 0x00 }, + { WCD934X_CPE_SS_SS_ERROR_INT_STATUS_1B, 0x00 }, + { WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_0A, 0x00 }, + { WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_0B, 0x00 }, + { WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_1A, 0x00 }, + { WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_1B, 0x00 }, + { WCD934X_SOC_MAD_MAIN_CTL_1, 0x00 }, + { WCD934X_SOC_MAD_MAIN_CTL_2, 0x00 }, + { WCD934X_SOC_MAD_AUDIO_CTL_1, 0x00 }, + { WCD934X_SOC_MAD_AUDIO_CTL_2, 0x00 }, + { WCD934X_SOC_MAD_AUDIO_CTL_3, 0x00 }, + { WCD934X_SOC_MAD_AUDIO_CTL_4, 0x00 }, + { WCD934X_SOC_MAD_AUDIO_CTL_5, 0x00 }, + { WCD934X_SOC_MAD_AUDIO_CTL_6, 0x00 }, + { WCD934X_SOC_MAD_AUDIO_CTL_7, 0x00 }, + { WCD934X_SOC_MAD_AUDIO_CTL_8, 0x00 }, + { WCD934X_SOC_MAD_AUDIO_IIR_CTL_PTR, 0x00 }, + { WCD934X_SOC_MAD_AUDIO_IIR_CTL_VAL, 0x40 }, + { WCD934X_SOC_MAD_ULTR_CTL_1, 0x00 }, + { WCD934X_SOC_MAD_ULTR_CTL_2, 0x00 }, + { WCD934X_SOC_MAD_ULTR_CTL_3, 0x00 }, + { WCD934X_SOC_MAD_ULTR_CTL_4, 0x00 }, + { WCD934X_SOC_MAD_ULTR_CTL_5, 0x00 }, + { WCD934X_SOC_MAD_ULTR_CTL_6, 0x00 }, + { WCD934X_SOC_MAD_ULTR_CTL_7, 0x00 }, + { WCD934X_SOC_MAD_BEACON_CTL_1, 0x00 }, + { WCD934X_SOC_MAD_BEACON_CTL_2, 0x00 }, + { WCD934X_SOC_MAD_BEACON_CTL_3, 0x00 }, + { WCD934X_SOC_MAD_BEACON_CTL_4, 0x00 }, + { WCD934X_SOC_MAD_BEACON_CTL_5, 0x00 }, + { WCD934X_SOC_MAD_BEACON_CTL_6, 0x00 }, + { WCD934X_SOC_MAD_BEACON_CTL_7, 0x00 }, + { WCD934X_SOC_MAD_BEACON_CTL_8, 0x00 }, + { WCD934X_SOC_MAD_BEACON_IIR_CTL_PTR, 0x00 }, + { WCD934X_SOC_MAD_BEACON_IIR_CTL_VAL, 0x00 }, + { WCD934X_SOC_MAD_INP_SEL, 0x00 }, + { WCD934X_PAGE4_PAGE_REGISTER, 0x00 }, + { WCD934X_INTR_CFG, 0x00 }, + { WCD934X_INTR_CLR_COMMIT, 0x00 }, + { WCD934X_INTR_PIN1_MASK0, 0xff }, + { WCD934X_INTR_PIN1_MASK1, 0xff }, + { WCD934X_INTR_PIN1_MASK2, 0xff }, + { WCD934X_INTR_PIN1_MASK3, 0xff }, + { WCD934X_INTR_PIN1_STATUS0, 0x00 }, + { WCD934X_INTR_PIN1_STATUS1, 0x00 }, + { WCD934X_INTR_PIN1_STATUS2, 0x00 }, + { WCD934X_INTR_PIN1_STATUS3, 0x00 }, + { WCD934X_INTR_PIN1_CLEAR0, 0x00 }, + { WCD934X_INTR_PIN1_CLEAR1, 0x00 }, + { WCD934X_INTR_PIN1_CLEAR2, 0x00 }, + { WCD934X_INTR_PIN1_CLEAR3, 0x00 }, + { WCD934X_INTR_PIN2_MASK3, 0xff }, + { WCD934X_INTR_PIN2_STATUS3, 0x00 }, + { WCD934X_INTR_PIN2_CLEAR3, 0x00 }, + { WCD934X_INTR_CPESS_SUMRY_MASK2, 0xff }, + { WCD934X_INTR_CPESS_SUMRY_MASK3, 0xff }, + { WCD934X_INTR_CPESS_SUMRY_STATUS2, 0x00 }, + { WCD934X_INTR_CPESS_SUMRY_STATUS3, 0x00 }, + { WCD934X_INTR_CPESS_SUMRY_CLEAR2, 0x00 }, + { WCD934X_INTR_CPESS_SUMRY_CLEAR3, 0x00 }, + { WCD934X_INTR_LEVEL0, 0x03 }, + { WCD934X_INTR_LEVEL1, 0xe0 }, + { WCD934X_INTR_LEVEL2, 0x94 }, + { WCD934X_INTR_LEVEL3, 0x80 }, + { WCD934X_INTR_BYPASS0, 0x00 }, + { WCD934X_INTR_BYPASS1, 0x00 }, + { WCD934X_INTR_BYPASS2, 0x00 }, + { WCD934X_INTR_BYPASS3, 0x00 }, + { WCD934X_INTR_SET0, 0x00 }, + { WCD934X_INTR_SET1, 0x00 }, + { WCD934X_INTR_SET2, 0x00 }, + { WCD934X_INTR_SET3, 0x00 }, + { WCD934X_INTR_CODEC_MISC_MASK, 0x7f }, + { WCD934X_INTR_CODEC_MISC_STATUS, 0x00 }, + { WCD934X_INTR_CODEC_MISC_CLEAR, 0x00 }, + { WCD934X_PAGE5_PAGE_REGISTER, 0x00 }, + { WCD934X_SLNQ_DIG_DEVICE, 0x49 }, + { WCD934X_SLNQ_DIG_REVISION, 0x01 }, + { WCD934X_SLNQ_DIG_H_COMMAND, 0x00 }, + { WCD934X_SLNQ_DIG_NUMBER_OF_BYTE_MSB, 0x00 }, + { WCD934X_SLNQ_DIG_NUMBER_OF_BYTE_LSB, 0x00 }, + { WCD934X_SLNQ_DIG_MASTER_ADDRESS_MSB, 0x00 }, + { WCD934X_SLNQ_DIG_MASTER_ADDRESS_LSB, 0x00 }, + { WCD934X_SLNQ_DIG_SLAVE_ADDRESS_MSB, 0x00 }, + { WCD934X_SLNQ_DIG_SLAVE_ADDRESS_LSB, 0x00 }, + { WCD934X_SLNQ_DIG_TIMER0_INTERRUPT_MSB, 0x40 }, + { WCD934X_SLNQ_DIG_TIMER0_INTERRUPT_LSB, 0x00 }, + { WCD934X_SLNQ_DIG_TIMER1_INTERRUPT_MSB, 0x40 }, + { WCD934X_SLNQ_DIG_TIMER1_INTERRUPT_LSB, 0x00 }, + { WCD934X_SLNQ_DIG_TIMER2_INTERRUPT_MSB, 0x40 }, + { WCD934X_SLNQ_DIG_TIMER2_INTERRUPT_LSB, 0x00 }, + { WCD934X_SLNQ_DIG_COMM_CTL, 0x00 }, + { WCD934X_SLNQ_DIG_FRAME_CTRL, 0x01 }, + { WCD934X_SLNQ_DIG_PDM_2ND_DATA_CH1_2, 0x77 }, + { WCD934X_SLNQ_DIG_PDM_2ND_DATA_CH3_4, 0x77 }, + { WCD934X_SLNQ_DIG_PDM_2ND_DATA_CH5, 0x70 }, + { WCD934X_SLNQ_DIG_SW_EVENT_RD, 0x00 }, + { WCD934X_SLNQ_DIG_SW_EVENT_CTRL, 0x00 }, + { WCD934X_SLNQ_DIG_PDM_SELECT_1, 0x12 }, + { WCD934X_SLNQ_DIG_PDM_SELECT_2, 0x34 }, + { WCD934X_SLNQ_DIG_PDM_SELECT_3, 0x55 }, + { WCD934X_SLNQ_DIG_PDM_SAMPLING_FREQ, 0x01 }, + { WCD934X_SLNQ_DIG_PDM_DC_CONVERSION_CTL, 0x00 }, + { WCD934X_SLNQ_DIG_PDM_DC_CONVERSION_SEL, 0x11 }, + { WCD934X_SLNQ_DIG_PDM_DC_CONV_CHA_MSB, 0x00 }, + { WCD934X_SLNQ_DIG_PDM_DC_CONV_CHA_LSB, 0x00 }, + { WCD934X_SLNQ_DIG_PDM_DC_CONV_CHB_MSB, 0x00 }, + { WCD934X_SLNQ_DIG_PDM_DC_CONV_CHB_LSB, 0x00 }, + { WCD934X_SLNQ_DIG_RAM_CNTRL, 0x01 }, + { WCD934X_SLNQ_DIG_SRAM_BANK, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_0, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_1, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_2, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_3, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_4, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_5, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_6, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_7, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_8, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_9, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_A, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_B, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_C, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_D, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_E, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_F, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_10, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_11, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_12, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_13, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_14, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_15, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_16, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_17, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_18, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_19, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_1A, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_1B, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_1C, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_1D, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_1E, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_1F, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_20, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_21, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_22, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_23, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_24, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_25, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_26, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_27, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_28, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_29, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_2A, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_2B, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_2C, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_2D, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_2E, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_2F, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_30, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_31, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_32, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_33, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_34, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_35, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_36, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_37, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_38, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_39, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_3A, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_3B, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_3C, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_3D, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_3E, 0x00 }, + { WCD934X_SLNQ_DIG_SRAM_BYTE_3F, 0x00 }, + { WCD934X_SLNQ_DIG_TOP_CTRL1, 0x00 }, + { WCD934X_SLNQ_DIG_TOP_CTRL2, 0x00 }, + { WCD934X_SLNQ_DIG_PDM_CTRL, 0x00 }, + { WCD934X_SLNQ_DIG_PDM_MUTE_CTRL, 0x20 }, + { WCD934X_SLNQ_DIG_DEC_BYPASS_CTRL, 0x00 }, + { WCD934X_SLNQ_DIG_DEC_BYPASS_STATUS, 0x00 }, + { WCD934X_SLNQ_DIG_DEC_BYPASS_FS, 0x00 }, + { WCD934X_SLNQ_DIG_DEC_BYPASS_IN_SEL, 0x00 }, + { WCD934X_SLNQ_DIG_GPOUT_ENABLE, 0x00 }, + { WCD934X_SLNQ_DIG_GPOUT_VAL, 0x00 }, + { WCD934X_SLNQ_DIG_ANA_INTERRUPT_MASK, 0x00 }, + { WCD934X_SLNQ_DIG_ANA_INTERRUPT_STATUS, 0x00 }, + { WCD934X_SLNQ_DIG_ANA_INTERRUPT_CLR, 0x00 }, + { WCD934X_SLNQ_DIG_IP_TESTING, 0x00 }, + { WCD934X_SLNQ_DIG_INTERRUPT_CNTRL, 0x0f }, + { WCD934X_SLNQ_DIG_INTERRUPT_CNT, 0x00 }, + { WCD934X_SLNQ_DIG_INTERRUPT_CNT_MSB, 0xff }, + { WCD934X_SLNQ_DIG_INTERRUPT_CNT_LSB, 0xff }, + { WCD934X_SLNQ_DIG_INTERRUPT_MASK0, 0xff }, + { WCD934X_SLNQ_DIG_INTERRUPT_MASK1, 0xff }, + { WCD934X_SLNQ_DIG_INTERRUPT_MASK2, 0xff }, + { WCD934X_SLNQ_DIG_INTERRUPT_MASK3, 0xff }, + { WCD934X_SLNQ_DIG_INTERRUPT_MASK4, 0x1f }, + { WCD934X_SLNQ_DIG_INTERRUPT_STATUS0, 0x00 }, + { WCD934X_SLNQ_DIG_INTERRUPT_STATUS1, 0x00 }, + { WCD934X_SLNQ_DIG_INTERRUPT_STATUS2, 0x00 }, + { WCD934X_SLNQ_DIG_INTERRUPT_STATUS3, 0x00 }, + { WCD934X_SLNQ_DIG_INTERRUPT_STATUS4, 0x00 }, + { WCD934X_SLNQ_DIG_INTERRUPT_CLR0, 0x00 }, + { WCD934X_SLNQ_DIG_INTERRUPT_CLR1, 0x00 }, + { WCD934X_SLNQ_DIG_INTERRUPT_CLR2, 0x00 }, + { WCD934X_SLNQ_DIG_INTERRUPT_CLR3, 0x00 }, + { WCD934X_SLNQ_DIG_INTERRUPT_CLR4, 0x00 }, + { WCD934X_ANA_PAGE_REGISTER, 0x00 }, + { WCD934X_ANA_BIAS, 0x00 }, + { WCD934X_ANA_RCO, 0x00 }, + { WCD934X_ANA_PAGE6_SPARE2, 0x00 }, + { WCD934X_ANA_PAGE6_SPARE3, 0x00 }, + { WCD934X_ANA_BUCK_CTL, 0x00 }, + { WCD934X_ANA_BUCK_STATUS, 0x00 }, + { WCD934X_ANA_RX_SUPPLIES, 0x00 }, + { WCD934X_ANA_HPH, 0x0c }, + { WCD934X_ANA_EAR, 0x00 }, + { WCD934X_ANA_LO_1_2, 0x3c }, + { WCD934X_ANA_MAD_SETUP, 0x01 }, + { WCD934X_ANA_AMIC1, 0x20 }, + { WCD934X_ANA_AMIC2, 0x00 }, + { WCD934X_ANA_AMIC3, 0x20 }, + { WCD934X_ANA_AMIC4, 0x00 }, + { WCD934X_ANA_MBHC_MECH, 0x39 }, + { WCD934X_ANA_MBHC_ELECT, 0x08 }, + { WCD934X_ANA_MBHC_ZDET, 0x00 }, + { WCD934X_ANA_MBHC_RESULT_1, 0x00 }, + { WCD934X_ANA_MBHC_RESULT_2, 0x00 }, + { WCD934X_ANA_MBHC_RESULT_3, 0x00 }, + { WCD934X_ANA_MBHC_BTN0, 0x00 }, + { WCD934X_ANA_MBHC_BTN1, 0x10 }, + { WCD934X_ANA_MBHC_BTN2, 0x20 }, + { WCD934X_ANA_MBHC_BTN3, 0x30 }, + { WCD934X_ANA_MBHC_BTN4, 0x40 }, + { WCD934X_ANA_MBHC_BTN5, 0x50 }, + { WCD934X_ANA_MBHC_BTN6, 0x60 }, + { WCD934X_ANA_MBHC_BTN7, 0x70 }, + { WCD934X_ANA_MICB1, 0x10 }, + { WCD934X_ANA_MICB2, 0x10 }, + { WCD934X_ANA_MICB2_RAMP, 0x00 }, + { WCD934X_ANA_MICB3, 0x10 }, + { WCD934X_ANA_MICB4, 0x10 }, + { WCD934X_ANA_VBADC, 0x00 }, + { WCD934X_BIAS_CTL, 0x28 }, + { WCD934X_BIAS_VBG_FINE_ADJ, 0x65 }, + { WCD934X_RCO_CTRL_1, 0x44 }, + { WCD934X_RCO_CTRL_2, 0x48 }, + { WCD934X_RCO_CAL, 0x00 }, + { WCD934X_RCO_CAL_1, 0x00 }, + { WCD934X_RCO_CAL_2, 0x00 }, + { WCD934X_RCO_TEST_CTRL, 0x00 }, + { WCD934X_RCO_CAL_OUT_1, 0x00 }, + { WCD934X_RCO_CAL_OUT_2, 0x00 }, + { WCD934X_RCO_CAL_OUT_3, 0x00 }, + { WCD934X_RCO_CAL_OUT_4, 0x00 }, + { WCD934X_RCO_CAL_OUT_5, 0x00 }, + { WCD934X_SIDO_MODE_1, 0x84 }, + { WCD934X_SIDO_MODE_2, 0xfe }, + { WCD934X_SIDO_MODE_3, 0xf6 }, + { WCD934X_SIDO_MODE_4, 0x56 }, + { WCD934X_SIDO_VCL_1, 0x00 }, + { WCD934X_SIDO_VCL_2, 0x6c }, + { WCD934X_SIDO_VCL_3, 0x44 }, + { WCD934X_SIDO_CCL_1, 0x57 }, + { WCD934X_SIDO_CCL_2, 0x92 }, + { WCD934X_SIDO_CCL_3, 0x35 }, + { WCD934X_SIDO_CCL_4, 0x61 }, + { WCD934X_SIDO_CCL_5, 0x6d }, + { WCD934X_SIDO_CCL_6, 0x60 }, + { WCD934X_SIDO_CCL_7, 0x6f }, + { WCD934X_SIDO_CCL_8, 0x6f }, + { WCD934X_SIDO_CCL_9, 0x6e }, + { WCD934X_SIDO_CCL_10, 0x26 }, + { WCD934X_SIDO_FILTER_1, 0x92 }, + { WCD934X_SIDO_FILTER_2, 0x54 }, + { WCD934X_SIDO_DRIVER_1, 0x77 }, + { WCD934X_SIDO_DRIVER_2, 0x55 }, + { WCD934X_SIDO_DRIVER_3, 0x55 }, + { WCD934X_SIDO_CAL_CODE_EXT_1, 0x9c }, + { WCD934X_SIDO_CAL_CODE_EXT_2, 0x82 }, + { WCD934X_SIDO_CAL_CODE_OUT_1, 0x00 }, + { WCD934X_SIDO_CAL_CODE_OUT_2, 0x00 }, + { WCD934X_SIDO_TEST_1, 0x00 }, + { WCD934X_SIDO_TEST_2, 0x00 }, + { WCD934X_MBHC_CTL_CLK, 0x30 }, + { WCD934X_MBHC_CTL_ANA, 0x00 }, + { WCD934X_MBHC_CTL_SPARE_1, 0x00 }, + { WCD934X_MBHC_CTL_SPARE_2, 0x00 }, + { WCD934X_MBHC_CTL_BCS, 0x00 }, + { WCD934X_MBHC_STATUS_SPARE_1, 0x00 }, + { WCD934X_MBHC_TEST_CTL, 0x00 }, + { WCD934X_VBADC_SUBBLOCK_EN, 0xde }, + { WCD934X_VBADC_IBIAS_FE, 0x58 }, + { WCD934X_VBADC_BIAS_ADC, 0x51 }, + { WCD934X_VBADC_FE_CTRL, 0x1c }, + { WCD934X_VBADC_ADC_REF, 0x20 }, + { WCD934X_VBADC_ADC_IO, 0x80 }, + { WCD934X_VBADC_ADC_SAR, 0xff }, + { WCD934X_VBADC_DEBUG, 0x00 }, + { WCD934X_LDOH_MODE, 0x2b }, + { WCD934X_LDOH_BIAS, 0x68 }, + { WCD934X_LDOH_STB_LOADS, 0x00 }, + { WCD934X_LDOH_SLOWRAMP, 0x50 }, + { WCD934X_MICB1_TEST_CTL_1, 0x1a }, + { WCD934X_MICB1_TEST_CTL_2, 0x18 }, + { WCD934X_MICB1_TEST_CTL_3, 0xa4 }, + { WCD934X_MICB2_TEST_CTL_1, 0x1a }, + { WCD934X_MICB2_TEST_CTL_2, 0x18 }, + { WCD934X_MICB2_TEST_CTL_3, 0xa4 }, + { WCD934X_MICB3_TEST_CTL_1, 0x1a }, + { WCD934X_MICB3_TEST_CTL_2, 0x18 }, + { WCD934X_MICB3_TEST_CTL_3, 0xa4 }, + { WCD934X_MICB4_TEST_CTL_1, 0x1a }, + { WCD934X_MICB4_TEST_CTL_2, 0x18 }, + { WCD934X_MICB4_TEST_CTL_3, 0xa4 }, + { WCD934X_TX_COM_ADC_VCM, 0x39 }, + { WCD934X_TX_COM_BIAS_ATEST, 0xc0 }, + { WCD934X_TX_COM_ADC_INT1_IB, 0x6f }, + { WCD934X_TX_COM_ADC_INT2_IB, 0x4f }, + { WCD934X_TX_COM_TXFE_DIV_CTL, 0x2e }, + { WCD934X_TX_COM_TXFE_DIV_START, 0x00 }, + { WCD934X_TX_COM_TXFE_DIV_STOP_9P6M, 0xc7 }, + { WCD934X_TX_COM_TXFE_DIV_STOP_12P288M, 0xff }, + { WCD934X_TX_1_2_TEST_EN, 0xcc }, + { WCD934X_TX_1_2_ADC_IB, 0x09 }, + { WCD934X_TX_1_2_ATEST_REFCTL, 0x0a }, + { WCD934X_TX_1_2_TEST_CTL, 0x38 }, + { WCD934X_TX_1_2_TEST_BLK_EN, 0xff }, + { WCD934X_TX_1_2_TXFE_CLKDIV, 0x00 }, + { WCD934X_TX_1_2_SAR1_ERR, 0x00 }, + { WCD934X_TX_1_2_SAR2_ERR, 0x00 }, + { WCD934X_TX_3_4_TEST_EN, 0xcc }, + { WCD934X_TX_3_4_ADC_IB, 0x09 }, + { WCD934X_TX_3_4_ATEST_REFCTL, 0x0a }, + { WCD934X_TX_3_4_TEST_CTL, 0x38 }, + { WCD934X_TX_3_4_TEST_BLK_EN, 0xff }, + { WCD934X_TX_3_4_TXFE_CLKDIV, 0x00 }, + { WCD934X_TX_3_4_SAR1_ERR, 0x00 }, + { WCD934X_TX_3_4_SAR2_ERR, 0x00 }, + { WCD934X_CLASSH_MODE_1, 0x40 }, + { WCD934X_CLASSH_MODE_2, 0x3a }, + { WCD934X_CLASSH_MODE_3, 0x00 }, + { WCD934X_CLASSH_CTRL_VCL_1, 0x70 }, + { WCD934X_CLASSH_CTRL_VCL_2, 0x82 }, + { WCD934X_CLASSH_CTRL_CCL_1, 0x31 }, + { WCD934X_CLASSH_CTRL_CCL_2, 0x80 }, + { WCD934X_CLASSH_CTRL_CCL_3, 0x80 }, + { WCD934X_CLASSH_CTRL_CCL_4, 0x51 }, + { WCD934X_CLASSH_CTRL_CCL_5, 0x00 }, + { WCD934X_CLASSH_BUCK_TMUX_A_D, 0x00 }, + { WCD934X_CLASSH_BUCK_SW_DRV_CNTL, 0x77 }, + { WCD934X_CLASSH_SPARE, 0x00 }, + { WCD934X_FLYBACK_EN, 0x4e }, + { WCD934X_FLYBACK_VNEG_CTRL_1, 0x0b }, + { WCD934X_FLYBACK_VNEG_CTRL_2, 0x45 }, + { WCD934X_FLYBACK_VNEG_CTRL_3, 0x74 }, + { WCD934X_FLYBACK_VNEG_CTRL_4, 0x7f }, + { WCD934X_FLYBACK_VNEG_CTRL_5, 0x83 }, + { WCD934X_FLYBACK_VNEG_CTRL_6, 0x98 }, + { WCD934X_FLYBACK_VNEG_CTRL_7, 0xa9 }, + { WCD934X_FLYBACK_VNEG_CTRL_8, 0x68 }, + { WCD934X_FLYBACK_VNEG_CTRL_9, 0x64 }, + { WCD934X_FLYBACK_VNEGDAC_CTRL_1, 0xed }, + { WCD934X_FLYBACK_VNEGDAC_CTRL_2, 0xf0 }, + { WCD934X_FLYBACK_VNEGDAC_CTRL_3, 0xa6 }, + { WCD934X_FLYBACK_CTRL_1, 0x65 }, + { WCD934X_FLYBACK_TEST_CTL, 0x00 }, + { WCD934X_RX_AUX_SW_CTL, 0x00 }, + { WCD934X_RX_PA_AUX_IN_CONN, 0x00 }, + { WCD934X_RX_TIMER_DIV, 0x32 }, + { WCD934X_RX_OCP_CTL, 0x1f }, + { WCD934X_RX_OCP_COUNT, 0x77 }, + { WCD934X_RX_BIAS_EAR_DAC, 0xa0 }, + { WCD934X_RX_BIAS_EAR_AMP, 0xaa }, + { WCD934X_RX_BIAS_HPH_LDO, 0xa9 }, + { WCD934X_RX_BIAS_HPH_PA, 0xaa }, + { WCD934X_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8a }, + { WCD934X_RX_BIAS_HPH_RDAC_LDO, 0x88 }, + { WCD934X_RX_BIAS_HPH_CNP1, 0x82 }, + { WCD934X_RX_BIAS_HPH_LOWPOWER, 0x82 }, + { WCD934X_RX_BIAS_DIFFLO_PA, 0x80 }, + { WCD934X_RX_BIAS_DIFFLO_REF, 0x88 }, + { WCD934X_RX_BIAS_DIFFLO_LDO, 0x88 }, + { WCD934X_RX_BIAS_SELO_DAC_PA, 0xa8 }, + { WCD934X_RX_BIAS_BUCK_RST, 0x08 }, + { WCD934X_RX_BIAS_BUCK_VREF_ERRAMP, 0x44 }, + { WCD934X_RX_BIAS_FLYB_ERRAMP, 0x40 }, + { WCD934X_RX_BIAS_FLYB_BUFF, 0xaa }, + { WCD934X_RX_BIAS_FLYB_MID_RST, 0x14 }, + { WCD934X_HPH_L_STATUS, 0x04 }, + { WCD934X_HPH_R_STATUS, 0x04 }, + { WCD934X_HPH_CNP_EN, 0x80 }, + { WCD934X_HPH_CNP_WG_CTL, 0x9a }, + { WCD934X_HPH_CNP_WG_TIME, 0x14 }, + { WCD934X_HPH_OCP_CTL, 0x28 }, + { WCD934X_HPH_AUTO_CHOP, 0x16 }, + { WCD934X_HPH_CHOP_CTL, 0x83 }, + { WCD934X_HPH_PA_CTL1, 0x46 }, + { WCD934X_HPH_PA_CTL2, 0x50 }, + { WCD934X_HPH_L_EN, 0x80 }, + { WCD934X_HPH_L_TEST, 0xe0 }, + { WCD934X_HPH_L_ATEST, 0x50 }, + { WCD934X_HPH_R_EN, 0x80 }, + { WCD934X_HPH_R_TEST, 0xe0 }, + { WCD934X_HPH_R_ATEST, 0x54 }, + { WCD934X_HPH_RDAC_CLK_CTL1, 0x99 }, + { WCD934X_HPH_RDAC_CLK_CTL2, 0x9b }, + { WCD934X_HPH_RDAC_LDO_CTL, 0x33 }, + { WCD934X_HPH_RDAC_CHOP_CLK_LP_CTL, 0x00 }, + { WCD934X_HPH_REFBUFF_UHQA_CTL, 0xa8 }, + { WCD934X_HPH_REFBUFF_LP_CTL, 0x0a }, + { WCD934X_HPH_L_DAC_CTL, 0x00 }, + { WCD934X_HPH_R_DAC_CTL, 0x00 }, + { WCD934X_EAR_EN_REG, 0x60 }, + { WCD934X_EAR_CMBUFF, 0x05 }, + { WCD934X_EAR_ICTL, 0x40 }, + { WCD934X_EAR_EN_DBG_CTL, 0x00 }, + { WCD934X_EAR_CNP, 0xe0 }, + { WCD934X_EAR_DAC_CTL_ATEST, 0x00 }, + { WCD934X_EAR_STATUS_REG, 0x04 }, + { WCD934X_EAR_EAR_MISC, 0x28 }, + { WCD934X_DIFF_LO_MISC, 0x03 }, + { WCD934X_DIFF_LO_LO2_COMPANDER, 0x00 }, + { WCD934X_DIFF_LO_LO1_COMPANDER, 0x00 }, + { WCD934X_DIFF_LO_COMMON, 0x40 }, + { WCD934X_DIFF_LO_BYPASS_EN, 0x00 }, + { WCD934X_DIFF_LO_CNP, 0x20 }, + { WCD934X_DIFF_LO_CORE_OUT_PROG, 0xa0 }, + { WCD934X_DIFF_LO_LDO_OUT_PROG, 0x00 }, + { WCD934X_DIFF_LO_COM_SWCAP_REFBUF_FREQ, 0x8b }, + { WCD934X_DIFF_LO_COM_PA_FREQ, 0xb0 }, + { WCD934X_DIFF_LO_RESERVED_REG, 0x60 }, + { WCD934X_DIFF_LO_LO1_STATUS_1, 0x00 }, + { WCD934X_DIFF_LO_LO1_STATUS_2, 0x00 }, + { WCD934X_ANA_NEW_PAGE_REGISTER, 0x00 }, + { WCD934X_HPH_NEW_ANA_HPH2, 0x00 }, + { WCD934X_HPH_NEW_ANA_HPH3, 0x00 }, + { WCD934X_SLNQ_ANA_EN, 0x02 }, + { WCD934X_SLNQ_ANA_STATUS, 0x00 }, + { WCD934X_SLNQ_ANA_LDO_CONFIG, 0xea }, + { WCD934X_SLNQ_ANA_LDO_OCP_CONFIG, 0x95 }, + { WCD934X_SLNQ_ANA_TX_LDO_CONFIG, 0xb6 }, + { WCD934X_SLNQ_ANA_TX_DRV_CONFIG, 0x26 }, + { WCD934X_SLNQ_ANA_RX_CONFIG_1, 0x64 }, + { WCD934X_SLNQ_ANA_RX_CONFIG_2, 0x40 }, + { WCD934X_SLNQ_ANA_PLL_ENABLES, 0x00 }, + { WCD934X_SLNQ_ANA_PLL_PRESET, 0x08 }, + { WCD934X_SLNQ_ANA_PLL_STATUS, 0x00 }, + { WCD934X_CLK_SYS_PLL_ENABLES, 0x00 }, + { WCD934X_CLK_SYS_PLL_PRESET, 0x00 }, + { WCD934X_CLK_SYS_PLL_STATUS, 0x00 }, + { WCD934X_CLK_SYS_MCLK_PRG, 0x00 }, + { WCD934X_CLK_SYS_MCLK2_PRG1, 0x00 }, + { WCD934X_CLK_SYS_MCLK2_PRG2, 0x00 }, + { WCD934X_CLK_SYS_XO_PRG, 0x00 }, + { WCD934X_CLK_SYS_XO_CAP_XTP, 0x00 }, + { WCD934X_CLK_SYS_XO_CAP_XTM, 0x00 }, + { WCD934X_BOOST_BST_EN_DLY, 0x40 }, + { WCD934X_BOOST_CTRL_ILIM, 0x9c }, + { WCD934X_BOOST_VOUT_SETTING, 0xca }, + { WCD934X_SIDO_NEW_VOUT_A_STARTUP, 0x05 }, + { WCD934X_SIDO_NEW_VOUT_D_STARTUP, 0x0d }, + { WCD934X_SIDO_NEW_VOUT_D_FREQ1, 0x07 }, + { WCD934X_SIDO_NEW_VOUT_D_FREQ2, 0x00 }, + { WCD934X_MBHC_NEW_ELECT_REM_CLAMP_CTL, 0x00 }, + { WCD934X_MBHC_NEW_CTL_1, 0x02 }, + { WCD934X_MBHC_NEW_CTL_2, 0x05 }, + { WCD934X_MBHC_NEW_PLUG_DETECT_CTL, 0xe9 }, + { WCD934X_MBHC_NEW_ZDET_ANA_CTL, 0x0f }, + { WCD934X_MBHC_NEW_ZDET_RAMP_CTL, 0x00 }, + { WCD934X_MBHC_NEW_FSM_STATUS, 0x00 }, + { WCD934X_MBHC_NEW_ADC_RESULT, 0x00 }, + { WCD934X_TX_NEW_AMIC_4_5_SEL, 0x00 }, + { WCD934X_VBADC_NEW_ADC_MODE, 0x10 }, + { WCD934X_VBADC_NEW_ADC_DOUTMSB, 0x00 }, + { WCD934X_VBADC_NEW_ADC_DOUTLSB, 0x00 }, + { WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, 0x00 }, + { WCD934X_HPH_NEW_INT_RDAC_HD2_CTL, 0xa0 }, + { WCD934X_HPH_NEW_INT_RDAC_VREF_CTL, 0x10 }, + { WCD934X_HPH_NEW_INT_RDAC_OVERRIDE_CTL, 0x00 }, + { WCD934X_HPH_NEW_INT_RDAC_MISC1, 0x00 }, + { WCD934X_HPH_NEW_INT_PA_MISC1, 0x22 }, + { WCD934X_HPH_NEW_INT_PA_MISC2, 0x00 }, + { WCD934X_HPH_NEW_INT_PA_RDAC_MISC, 0x00 }, + { WCD934X_HPH_NEW_INT_HPH_TIMER1, 0xfe }, + { WCD934X_HPH_NEW_INT_HPH_TIMER2, 0x02 }, + { WCD934X_HPH_NEW_INT_HPH_TIMER3, 0x4e }, + { WCD934X_HPH_NEW_INT_HPH_TIMER4, 0x54 }, + { WCD934X_HPH_NEW_INT_PA_RDAC_MISC2, 0x00 }, + { WCD934X_HPH_NEW_INT_PA_RDAC_MISC3, 0x00 }, + { WCD934X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI, 0x62 }, + { WCD934X_RX_NEW_INT_HPH_RDAC_BIAS_ULP, 0x01 }, + { WCD934X_RX_NEW_INT_HPH_RDAC_LDO_LP, 0x11 }, + { WCD934X_SLNQ_INT_ANA_INT_LDO_TEST, 0x0d }, + { WCD934X_SLNQ_INT_ANA_INT_LDO_DEBUG_1, 0x85 }, + { WCD934X_SLNQ_INT_ANA_INT_LDO_DEBUG_2, 0xb4 }, + { WCD934X_SLNQ_INT_ANA_INT_TX_LDO_TEST, 0x16 }, + { WCD934X_SLNQ_INT_ANA_INT_TX_DRV_TEST, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_RX_TEST, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_RX_TEST_STATUS, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_RX_DEBUG_1, 0x50 }, + { WCD934X_SLNQ_INT_ANA_INT_RX_DEBUG_2, 0x04 }, + { WCD934X_SLNQ_INT_ANA_INT_CLK_CTRL, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_RESERVED_1, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_RESERVED_2, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_PLL_POST_DIV_REG0, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_PLL_POST_DIV_REG1, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_PLL_REF_DIV_REG0, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_PLL_REF_DIV_REG1, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_PLL_FILTER_REG0, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_PLL_FILTER_REG1, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_PLL_L_VAL, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_PLL_M_VAL, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_PLL_N_VAL, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_PLL_TEST_REG0, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_PLL_PFD_CP_DSM_PROG, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_PLL_VCO_PROG, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_PLL_TEST_REG1, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_PLL_LDO_LOCK_CFG, 0x00 }, + { WCD934X_SLNQ_INT_ANA_INT_PLL_DIG_LOCK_DET_CFG, 0x00 }, + { WCD934X_CLK_SYS_INT_POST_DIV_REG0, 0x00 }, + { WCD934X_CLK_SYS_INT_POST_DIV_REG1, 0x00 }, + { WCD934X_CLK_SYS_INT_REF_DIV_REG0, 0x00 }, + { WCD934X_CLK_SYS_INT_REF_DIV_REG1, 0x00 }, + { WCD934X_CLK_SYS_INT_FILTER_REG0, 0x00 }, + { WCD934X_CLK_SYS_INT_FILTER_REG1, 0x00 }, + { WCD934X_CLK_SYS_INT_PLL_L_VAL, 0x00 }, + { WCD934X_CLK_SYS_INT_PLL_M_VAL, 0x00 }, + { WCD934X_CLK_SYS_INT_PLL_N_VAL, 0x00 }, + { WCD934X_CLK_SYS_INT_TEST_REG0, 0x00 }, + { WCD934X_CLK_SYS_INT_PFD_CP_DSM_PROG, 0x00 }, + { WCD934X_CLK_SYS_INT_VCO_PROG, 0x00 }, + { WCD934X_CLK_SYS_INT_TEST_REG1, 0x00 }, + { WCD934X_CLK_SYS_INT_LDO_LOCK_CFG, 0x00 }, + { WCD934X_CLK_SYS_INT_DIG_LOCK_DET_CFG, 0x00 }, + { WCD934X_CLK_SYS_INT_CLK_TEST1, 0x00 }, + { WCD934X_CLK_SYS_INT_CLK_TEST2, 0x00 }, + { WCD934X_CLK_SYS_INT_CLK_TEST3, 0x00 }, + { WCD934X_CLK_SYS_INT_XO_TEST1, 0x98 }, + { WCD934X_CLK_SYS_INT_XO_TEST2, 0x00 }, + { WCD934X_BOOST_INT_VCOMP_HYST, 0x02 }, + { WCD934X_BOOST_INT_VLOOP_FILTER, 0xef }, + { WCD934X_BOOST_INT_CTRL_IDELTA, 0xa8 }, + { WCD934X_BOOST_INT_CTRL_ILIM_STARTUP, 0x17 }, + { WCD934X_BOOST_INT_CTRL_MIN_ONTIME, 0x5f }, + { WCD934X_BOOST_INT_CTRL_MAX_ONTIME, 0x88 }, + { WCD934X_BOOST_INT_CTRL_TIMING, 0x0a }, + { WCD934X_BOOST_INT_TMUX_A_D, 0x00 }, + { WCD934X_BOOST_INT_SW_DRV_CNTL, 0xf8 }, + { WCD934X_BOOST_INT_SPARE1, 0x00 }, + { WCD934X_BOOST_INT_SPARE2, 0x00 }, + { WCD934X_SIDO_NEW_INT_RAMP_STATUS, 0x00 }, + { WCD934X_SIDO_NEW_INT_SPARE_1, 0x00 }, + { WCD934X_SIDO_NEW_INT_DEBUG_VOUT_SETTING_A, 0x64 }, + { WCD934X_SIDO_NEW_INT_DEBUG_VOUT_SETTING_D, 0x40 }, + { WCD934X_SIDO_NEW_INT_RAMP_INC_WAIT, 0x24 }, + { WCD934X_SIDO_NEW_INT_DYNAMIC_IPEAK_CTL, 0x09 }, + { WCD934X_SIDO_NEW_INT_RAMP_IBLEED_CTL, 0x7d }, + { WCD934X_SIDO_NEW_INT_DEBUG_CPROVR_TEST, 0x00 }, + { WCD934X_SIDO_NEW_INT_RAMP_CTL_A, 0x14 }, + { WCD934X_SIDO_NEW_INT_RAMP_CTL_D, 0x14 }, + { WCD934X_SIDO_NEW_INT_RAMP_TIMEOUT_PERIOD, 0x33 }, + { WCD934X_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING1, 0x3f }, + { WCD934X_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING2, 0x74 }, + { WCD934X_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING3, 0x33 }, + { WCD934X_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL1, 0x1d }, + { WCD934X_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL2, 0x0a }, + { WCD934X_MBHC_NEW_INT_SLNQ_HPF, 0x50 }, + { WCD934X_MBHC_NEW_INT_SLNQ_REF, 0x24 }, + { WCD934X_MBHC_NEW_INT_SLNQ_COMP, 0x50 }, + { WCD934X_MBHC_NEW_INT_SPARE_2, 0x00 }, + { WCD934X_PAGE10_PAGE_REGISTER, 0x00 }, + { WCD934X_CDC_ANC0_CLK_RESET_CTL, 0x00 }, + { WCD934X_CDC_ANC0_MODE_1_CTL, 0x00 }, + { WCD934X_CDC_ANC0_MODE_2_CTL, 0x00 }, + { WCD934X_CDC_ANC0_FF_SHIFT, 0x00 }, + { WCD934X_CDC_ANC0_FB_SHIFT, 0x00 }, + { WCD934X_CDC_ANC0_LPF_FF_A_CTL, 0x00 }, + { WCD934X_CDC_ANC0_LPF_FF_B_CTL, 0x00 }, + { WCD934X_CDC_ANC0_LPF_FB_CTL, 0x00 }, + { WCD934X_CDC_ANC0_SMLPF_CTL, 0x00 }, + { WCD934X_CDC_ANC0_DCFLT_SHIFT_CTL, 0x00 }, + { WCD934X_CDC_ANC0_IIR_ADAPT_CTL, 0x00 }, + { WCD934X_CDC_ANC0_IIR_COEFF_1_CTL, 0x00 }, + { WCD934X_CDC_ANC0_IIR_COEFF_2_CTL, 0x00 }, + { WCD934X_CDC_ANC0_FF_A_GAIN_CTL, 0x00 }, + { WCD934X_CDC_ANC0_FF_B_GAIN_CTL, 0x00 }, + { WCD934X_CDC_ANC0_FB_GAIN_CTL, 0x00 }, + { WCD934X_CDC_ANC0_RC_COMMON_CTL, 0x00 }, + { WCD934X_CDC_ANC0_FIFO_COMMON_CTL, 0x88 }, + { WCD934X_CDC_ANC0_RC0_STATUS_FMIN_CNTR, 0x00 }, + { WCD934X_CDC_ANC0_RC1_STATUS_FMIN_CNTR, 0x00 }, + { WCD934X_CDC_ANC0_RC0_STATUS_FMAX_CNTR, 0x00 }, + { WCD934X_CDC_ANC0_RC1_STATUS_FMAX_CNTR, 0x00 }, + { WCD934X_CDC_ANC0_STATUS_FIFO, 0x00 }, + { WCD934X_CDC_ANC1_CLK_RESET_CTL, 0x00 }, + { WCD934X_CDC_ANC1_MODE_1_CTL, 0x00 }, + { WCD934X_CDC_ANC1_MODE_2_CTL, 0x00 }, + { WCD934X_CDC_ANC1_FF_SHIFT, 0x00 }, + { WCD934X_CDC_ANC1_FB_SHIFT, 0x00 }, + { WCD934X_CDC_ANC1_LPF_FF_A_CTL, 0x00 }, + { WCD934X_CDC_ANC1_LPF_FF_B_CTL, 0x00 }, + { WCD934X_CDC_ANC1_LPF_FB_CTL, 0x00 }, + { WCD934X_CDC_ANC1_SMLPF_CTL, 0x00 }, + { WCD934X_CDC_ANC1_DCFLT_SHIFT_CTL, 0x00 }, + { WCD934X_CDC_ANC1_IIR_ADAPT_CTL, 0x00 }, + { WCD934X_CDC_ANC1_IIR_COEFF_1_CTL, 0x00 }, + { WCD934X_CDC_ANC1_IIR_COEFF_2_CTL, 0x00 }, + { WCD934X_CDC_ANC1_FF_A_GAIN_CTL, 0x00 }, + { WCD934X_CDC_ANC1_FF_B_GAIN_CTL, 0x00 }, + { WCD934X_CDC_ANC1_FB_GAIN_CTL, 0x00 }, + { WCD934X_CDC_ANC1_RC_COMMON_CTL, 0x00 }, + { WCD934X_CDC_ANC1_FIFO_COMMON_CTL, 0x88 }, + { WCD934X_CDC_ANC1_RC0_STATUS_FMIN_CNTR, 0x00 }, + { WCD934X_CDC_ANC1_RC1_STATUS_FMIN_CNTR, 0x00 }, + { WCD934X_CDC_ANC1_RC0_STATUS_FMAX_CNTR, 0x00 }, + { WCD934X_CDC_ANC1_RC1_STATUS_FMAX_CNTR, 0x00 }, + { WCD934X_CDC_ANC1_STATUS_FIFO, 0x00 }, + { WCD934X_CDC_TX0_TX_PATH_CTL, 0x04 }, + { WCD934X_CDC_TX0_TX_PATH_CFG0, 0x10 }, + { WCD934X_CDC_TX0_TX_PATH_CFG1, 0x03 }, + { WCD934X_CDC_TX0_TX_VOL_CTL, 0x00 }, + { WCD934X_CDC_TX0_TX_PATH_192_CTL, 0x00 }, + { WCD934X_CDC_TX0_TX_PATH_192_CFG, 0x00 }, + { WCD934X_CDC_TX0_TX_PATH_SEC0, 0x00 }, + { WCD934X_CDC_TX0_TX_PATH_SEC1, 0x00 }, + { WCD934X_CDC_TX0_TX_PATH_SEC2, 0x01 }, + { WCD934X_CDC_TX0_TX_PATH_SEC3, 0x3c }, + { WCD934X_CDC_TX0_TX_PATH_SEC4, 0x20 }, + { WCD934X_CDC_TX0_TX_PATH_SEC5, 0x00 }, + { WCD934X_CDC_TX0_TX_PATH_SEC6, 0x00 }, + { WCD934X_CDC_TX0_TX_PATH_SEC7, 0x25 }, + { WCD934X_CDC_TX1_TX_PATH_CTL, 0x04 }, + { WCD934X_CDC_TX1_TX_PATH_CFG0, 0x10 }, + { WCD934X_CDC_TX1_TX_PATH_CFG1, 0x03 }, + { WCD934X_CDC_TX1_TX_VOL_CTL, 0x00 }, + { WCD934X_CDC_TX1_TX_PATH_192_CTL, 0x00 }, + { WCD934X_CDC_TX1_TX_PATH_192_CFG, 0x00 }, + { WCD934X_CDC_TX1_TX_PATH_SEC0, 0x00 }, + { WCD934X_CDC_TX1_TX_PATH_SEC1, 0x00 }, + { WCD934X_CDC_TX1_TX_PATH_SEC2, 0x01 }, + { WCD934X_CDC_TX1_TX_PATH_SEC3, 0x3c }, + { WCD934X_CDC_TX1_TX_PATH_SEC4, 0x20 }, + { WCD934X_CDC_TX1_TX_PATH_SEC5, 0x00 }, + { WCD934X_CDC_TX1_TX_PATH_SEC6, 0x00 }, + { WCD934X_CDC_TX2_TX_PATH_CTL, 0x04 }, + { WCD934X_CDC_TX2_TX_PATH_CFG0, 0x10 }, + { WCD934X_CDC_TX2_TX_PATH_CFG1, 0x03 }, + { WCD934X_CDC_TX2_TX_VOL_CTL, 0x00 }, + { WCD934X_CDC_TX2_TX_PATH_192_CTL, 0x00 }, + { WCD934X_CDC_TX2_TX_PATH_192_CFG, 0x00 }, + { WCD934X_CDC_TX2_TX_PATH_SEC0, 0x00 }, + { WCD934X_CDC_TX2_TX_PATH_SEC1, 0x00 }, + { WCD934X_CDC_TX2_TX_PATH_SEC2, 0x01 }, + { WCD934X_CDC_TX2_TX_PATH_SEC3, 0x3c }, + { WCD934X_CDC_TX2_TX_PATH_SEC4, 0x20 }, + { WCD934X_CDC_TX2_TX_PATH_SEC5, 0x00 }, + { WCD934X_CDC_TX2_TX_PATH_SEC6, 0x00 }, + { WCD934X_CDC_TX3_TX_PATH_CTL, 0x04 }, + { WCD934X_CDC_TX3_TX_PATH_CFG0, 0x10 }, + { WCD934X_CDC_TX3_TX_PATH_CFG1, 0x03 }, + { WCD934X_CDC_TX3_TX_VOL_CTL, 0x00 }, + { WCD934X_CDC_TX3_TX_PATH_192_CTL, 0x00 }, + { WCD934X_CDC_TX3_TX_PATH_192_CFG, 0x00 }, + { WCD934X_CDC_TX3_TX_PATH_SEC0, 0x00 }, + { WCD934X_CDC_TX3_TX_PATH_SEC1, 0x00 }, + { WCD934X_CDC_TX3_TX_PATH_SEC2, 0x01 }, + { WCD934X_CDC_TX3_TX_PATH_SEC3, 0x3c }, + { WCD934X_CDC_TX3_TX_PATH_SEC4, 0x20 }, + { WCD934X_CDC_TX3_TX_PATH_SEC5, 0x00 }, + { WCD934X_CDC_TX3_TX_PATH_SEC6, 0x00 }, + { WCD934X_CDC_TX4_TX_PATH_CTL, 0x04 }, + { WCD934X_CDC_TX4_TX_PATH_CFG0, 0x10 }, + { WCD934X_CDC_TX4_TX_PATH_CFG1, 0x03 }, + { WCD934X_CDC_TX4_TX_VOL_CTL, 0x00 }, + { WCD934X_CDC_TX4_TX_PATH_192_CTL, 0x00 }, + { WCD934X_CDC_TX4_TX_PATH_192_CFG, 0x00 }, + { WCD934X_CDC_TX4_TX_PATH_SEC0, 0x00 }, + { WCD934X_CDC_TX4_TX_PATH_SEC1, 0x00 }, + { WCD934X_CDC_TX4_TX_PATH_SEC2, 0x01 }, + { WCD934X_CDC_TX4_TX_PATH_SEC3, 0x3c }, + { WCD934X_CDC_TX4_TX_PATH_SEC4, 0x20 }, + { WCD934X_CDC_TX4_TX_PATH_SEC5, 0x00 }, + { WCD934X_CDC_TX4_TX_PATH_SEC6, 0x00 }, + { WCD934X_CDC_TX5_TX_PATH_CTL, 0x04 }, + { WCD934X_CDC_TX5_TX_PATH_CFG0, 0x10 }, + { WCD934X_CDC_TX5_TX_PATH_CFG1, 0x03 }, + { WCD934X_CDC_TX5_TX_VOL_CTL, 0x00 }, + { WCD934X_CDC_TX5_TX_PATH_192_CTL, 0x00 }, + { WCD934X_CDC_TX5_TX_PATH_192_CFG, 0x00 }, + { WCD934X_CDC_TX5_TX_PATH_SEC0, 0x00 }, + { WCD934X_CDC_TX5_TX_PATH_SEC1, 0x00 }, + { WCD934X_CDC_TX5_TX_PATH_SEC2, 0x01 }, + { WCD934X_CDC_TX5_TX_PATH_SEC3, 0x3c }, + { WCD934X_CDC_TX5_TX_PATH_SEC4, 0x20 }, + { WCD934X_CDC_TX5_TX_PATH_SEC5, 0x00 }, + { WCD934X_CDC_TX5_TX_PATH_SEC6, 0x00 }, + { WCD934X_CDC_TX6_TX_PATH_CTL, 0x04 }, + { WCD934X_CDC_TX6_TX_PATH_CFG0, 0x10 }, + { WCD934X_CDC_TX6_TX_PATH_CFG1, 0x03 }, + { WCD934X_CDC_TX6_TX_VOL_CTL, 0x00 }, + { WCD934X_CDC_TX6_TX_PATH_192_CTL, 0x00 }, + { WCD934X_CDC_TX6_TX_PATH_192_CFG, 0x00 }, + { WCD934X_CDC_TX6_TX_PATH_SEC0, 0x00 }, + { WCD934X_CDC_TX6_TX_PATH_SEC1, 0x00 }, + { WCD934X_CDC_TX6_TX_PATH_SEC2, 0x01 }, + { WCD934X_CDC_TX6_TX_PATH_SEC3, 0x3c }, + { WCD934X_CDC_TX6_TX_PATH_SEC4, 0x20 }, + { WCD934X_CDC_TX6_TX_PATH_SEC5, 0x00 }, + { WCD934X_CDC_TX6_TX_PATH_SEC6, 0x00 }, + { WCD934X_CDC_TX7_TX_PATH_CTL, 0x04 }, + { WCD934X_CDC_TX7_TX_PATH_CFG0, 0x10 }, + { WCD934X_CDC_TX7_TX_PATH_CFG1, 0x03 }, + { WCD934X_CDC_TX7_TX_VOL_CTL, 0x00 }, + { WCD934X_CDC_TX7_TX_PATH_192_CTL, 0x00 }, + { WCD934X_CDC_TX7_TX_PATH_192_CFG, 0x00 }, + { WCD934X_CDC_TX7_TX_PATH_SEC0, 0x00 }, + { WCD934X_CDC_TX7_TX_PATH_SEC1, 0x00 }, + { WCD934X_CDC_TX7_TX_PATH_SEC2, 0x01 }, + { WCD934X_CDC_TX7_TX_PATH_SEC3, 0x3c }, + { WCD934X_CDC_TX7_TX_PATH_SEC4, 0x20 }, + { WCD934X_CDC_TX7_TX_PATH_SEC5, 0x00 }, + { WCD934X_CDC_TX7_TX_PATH_SEC6, 0x00 }, + { WCD934X_CDC_TX8_TX_PATH_CTL, 0x04 }, + { WCD934X_CDC_TX8_TX_PATH_CFG0, 0x10 }, + { WCD934X_CDC_TX8_TX_PATH_CFG1, 0x03 }, + { WCD934X_CDC_TX8_TX_VOL_CTL, 0x00 }, + { WCD934X_CDC_TX8_TX_PATH_192_CTL, 0x00 }, + { WCD934X_CDC_TX8_TX_PATH_192_CFG, 0x00 }, + { WCD934X_CDC_TX8_TX_PATH_SEC0, 0x00 }, + { WCD934X_CDC_TX8_TX_PATH_SEC1, 0x00 }, + { WCD934X_CDC_TX8_TX_PATH_SEC2, 0x01 }, + { WCD934X_CDC_TX8_TX_PATH_SEC3, 0x3c }, + { WCD934X_CDC_TX8_TX_PATH_SEC4, 0x20 }, + { WCD934X_CDC_TX8_TX_PATH_SEC5, 0x00 }, + { WCD934X_CDC_TX8_TX_PATH_SEC6, 0x00 }, + { WCD934X_CDC_TX9_SPKR_PROT_PATH_CTL, 0x02 }, + { WCD934X_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x00 }, + { WCD934X_CDC_TX10_SPKR_PROT_PATH_CTL, 0x02 }, + { WCD934X_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x00 }, + { WCD934X_CDC_TX11_SPKR_PROT_PATH_CTL, 0x02 }, + { WCD934X_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x00 }, + { WCD934X_CDC_TX12_SPKR_PROT_PATH_CTL, 0x02 }, + { WCD934X_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x00 }, + { WCD934X_PAGE11_PAGE_REGISTER, 0x00 }, + { WCD934X_CDC_COMPANDER1_CTL0, 0x60 }, + { WCD934X_CDC_COMPANDER1_CTL1, 0xdb }, + { WCD934X_CDC_COMPANDER1_CTL2, 0xff }, + { WCD934X_CDC_COMPANDER1_CTL3, 0x35 }, + { WCD934X_CDC_COMPANDER1_CTL4, 0xff }, + { WCD934X_CDC_COMPANDER1_CTL5, 0x00 }, + { WCD934X_CDC_COMPANDER1_CTL6, 0x01 }, + { WCD934X_CDC_COMPANDER1_CTL7, 0x08 }, + { WCD934X_CDC_COMPANDER2_CTL0, 0x60 }, + { WCD934X_CDC_COMPANDER2_CTL1, 0xdb }, + { WCD934X_CDC_COMPANDER2_CTL2, 0xff }, + { WCD934X_CDC_COMPANDER2_CTL3, 0x35 }, + { WCD934X_CDC_COMPANDER2_CTL4, 0xff }, + { WCD934X_CDC_COMPANDER2_CTL5, 0x00 }, + { WCD934X_CDC_COMPANDER2_CTL6, 0x01 }, + { WCD934X_CDC_COMPANDER2_CTL7, 0x08 }, + { WCD934X_CDC_COMPANDER3_CTL0, 0x60 }, + { WCD934X_CDC_COMPANDER3_CTL1, 0xdb }, + { WCD934X_CDC_COMPANDER3_CTL2, 0xff }, + { WCD934X_CDC_COMPANDER3_CTL3, 0x35 }, + { WCD934X_CDC_COMPANDER3_CTL4, 0xff }, + { WCD934X_CDC_COMPANDER3_CTL5, 0x00 }, + { WCD934X_CDC_COMPANDER3_CTL6, 0x01 }, + { WCD934X_CDC_COMPANDER3_CTL7, 0x08 }, + { WCD934X_CDC_COMPANDER4_CTL0, 0x60 }, + { WCD934X_CDC_COMPANDER4_CTL1, 0xdb }, + { WCD934X_CDC_COMPANDER4_CTL2, 0xff }, + { WCD934X_CDC_COMPANDER4_CTL3, 0x35 }, + { WCD934X_CDC_COMPANDER4_CTL4, 0xff }, + { WCD934X_CDC_COMPANDER4_CTL5, 0x00 }, + { WCD934X_CDC_COMPANDER4_CTL6, 0x01 }, + { WCD934X_CDC_COMPANDER4_CTL7, 0x08 }, + { WCD934X_CDC_COMPANDER7_CTL0, 0x60 }, + { WCD934X_CDC_COMPANDER7_CTL1, 0xdb }, + { WCD934X_CDC_COMPANDER7_CTL2, 0xff }, + { WCD934X_CDC_COMPANDER7_CTL3, 0x35 }, + { WCD934X_CDC_COMPANDER7_CTL4, 0xff }, + { WCD934X_CDC_COMPANDER7_CTL5, 0x00 }, + { WCD934X_CDC_COMPANDER7_CTL6, 0x01 }, + { WCD934X_CDC_COMPANDER7_CTL7, 0x08 }, + { WCD934X_CDC_COMPANDER8_CTL0, 0x60 }, + { WCD934X_CDC_COMPANDER8_CTL1, 0xdb }, + { WCD934X_CDC_COMPANDER8_CTL2, 0xff }, + { WCD934X_CDC_COMPANDER8_CTL3, 0x35 }, + { WCD934X_CDC_COMPANDER8_CTL4, 0xff }, + { WCD934X_CDC_COMPANDER8_CTL5, 0x00 }, + { WCD934X_CDC_COMPANDER8_CTL6, 0x01 }, + { WCD934X_CDC_COMPANDER8_CTL7, 0x08 }, + { WCD934X_CDC_RX0_RX_PATH_CTL, 0x04 }, + { WCD934X_CDC_RX0_RX_PATH_CFG0, 0x00 }, + { WCD934X_CDC_RX0_RX_PATH_CFG1, 0x64 }, + { WCD934X_CDC_RX0_RX_PATH_CFG2, 0x8f }, + { WCD934X_CDC_RX0_RX_VOL_CTL, 0x00 }, + { WCD934X_CDC_RX0_RX_PATH_MIX_CTL, 0x04 }, + { WCD934X_CDC_RX0_RX_PATH_MIX_CFG, 0x7e }, + { WCD934X_CDC_RX0_RX_VOL_MIX_CTL, 0x00 }, + { WCD934X_CDC_RX0_RX_PATH_SEC0, 0xfc }, + { WCD934X_CDC_RX0_RX_PATH_SEC1, 0x08 }, + { WCD934X_CDC_RX0_RX_PATH_SEC2, 0x00 }, + { WCD934X_CDC_RX0_RX_PATH_SEC3, 0x00 }, + { WCD934X_CDC_RX0_RX_PATH_SEC5, 0x00 }, + { WCD934X_CDC_RX0_RX_PATH_SEC6, 0x00 }, + { WCD934X_CDC_RX0_RX_PATH_SEC7, 0x00 }, + { WCD934X_CDC_RX0_RX_PATH_MIX_SEC0, 0x08 }, + { WCD934X_CDC_RX0_RX_PATH_MIX_SEC1, 0x00 }, + { WCD934X_CDC_RX0_RX_PATH_DSMDEM_CTL, 0x00 }, + { WCD934X_CDC_RX1_RX_PATH_CTL, 0x04 }, + { WCD934X_CDC_RX1_RX_PATH_CFG0, 0x00 }, + { WCD934X_CDC_RX1_RX_PATH_CFG1, 0x64 }, + { WCD934X_CDC_RX1_RX_PATH_CFG2, 0x8f }, + { WCD934X_CDC_RX1_RX_VOL_CTL, 0x00 }, + { WCD934X_CDC_RX1_RX_PATH_MIX_CTL, 0x04 }, + { WCD934X_CDC_RX1_RX_PATH_MIX_CFG, 0x7e }, + { WCD934X_CDC_RX1_RX_VOL_MIX_CTL, 0x00 }, + { WCD934X_CDC_RX1_RX_PATH_SEC0, 0xfc }, + { WCD934X_CDC_RX1_RX_PATH_SEC1, 0x08 }, + { WCD934X_CDC_RX1_RX_PATH_SEC2, 0x00 }, + { WCD934X_CDC_RX1_RX_PATH_SEC3, 0x00 }, + { WCD934X_CDC_RX1_RX_PATH_SEC4, 0x00 }, + { WCD934X_CDC_RX1_RX_PATH_SEC5, 0x00 }, + { WCD934X_CDC_RX1_RX_PATH_SEC6, 0x00 }, + { WCD934X_CDC_RX1_RX_PATH_SEC7, 0x00 }, + { WCD934X_CDC_RX1_RX_PATH_MIX_SEC0, 0x08 }, + { WCD934X_CDC_RX1_RX_PATH_MIX_SEC1, 0x00 }, + { WCD934X_CDC_RX1_RX_PATH_DSMDEM_CTL, 0x00 }, + { WCD934X_CDC_RX2_RX_PATH_CTL, 0x04 }, + { WCD934X_CDC_RX2_RX_PATH_CFG0, 0x00 }, + { WCD934X_CDC_RX2_RX_PATH_CFG1, 0x64 }, + { WCD934X_CDC_RX2_RX_PATH_CFG2, 0x8f }, + { WCD934X_CDC_RX2_RX_VOL_CTL, 0x00 }, + { WCD934X_CDC_RX2_RX_PATH_MIX_CTL, 0x04 }, + { WCD934X_CDC_RX2_RX_PATH_MIX_CFG, 0x7e }, + { WCD934X_CDC_RX2_RX_VOL_MIX_CTL, 0x00 }, + { WCD934X_CDC_RX2_RX_PATH_SEC0, 0xfc }, + { WCD934X_CDC_RX2_RX_PATH_SEC1, 0x08 }, + { WCD934X_CDC_RX2_RX_PATH_SEC2, 0x00 }, + { WCD934X_CDC_RX2_RX_PATH_SEC3, 0x00 }, + { WCD934X_CDC_RX2_RX_PATH_SEC4, 0x00 }, + { WCD934X_CDC_RX2_RX_PATH_SEC5, 0x00 }, + { WCD934X_CDC_RX2_RX_PATH_SEC6, 0x00 }, + { WCD934X_CDC_RX2_RX_PATH_SEC7, 0x00 }, + { WCD934X_CDC_RX2_RX_PATH_MIX_SEC0, 0x08 }, + { WCD934X_CDC_RX2_RX_PATH_MIX_SEC1, 0x00 }, + { WCD934X_CDC_RX2_RX_PATH_DSMDEM_CTL, 0x00 }, + { WCD934X_CDC_RX3_RX_PATH_CTL, 0x04 }, + { WCD934X_CDC_RX3_RX_PATH_CFG0, 0x00 }, + { WCD934X_CDC_RX3_RX_PATH_CFG1, 0x64 }, + { WCD934X_CDC_RX3_RX_PATH_CFG2, 0x8f }, + { WCD934X_CDC_RX3_RX_VOL_CTL, 0x00 }, + { WCD934X_CDC_RX3_RX_PATH_MIX_CTL, 0x04 }, + { WCD934X_CDC_RX3_RX_PATH_MIX_CFG, 0x7e }, + { WCD934X_CDC_RX3_RX_VOL_MIX_CTL, 0x00 }, + { WCD934X_CDC_RX3_RX_PATH_SEC0, 0xfc }, + { WCD934X_CDC_RX3_RX_PATH_SEC1, 0x08 }, + { WCD934X_CDC_RX3_RX_PATH_SEC2, 0x00 }, + { WCD934X_CDC_RX3_RX_PATH_SEC3, 0x00 }, + { WCD934X_CDC_RX3_RX_PATH_SEC5, 0x00 }, + { WCD934X_CDC_RX3_RX_PATH_SEC6, 0x00 }, + { WCD934X_CDC_RX3_RX_PATH_SEC7, 0x00 }, + { WCD934X_CDC_RX3_RX_PATH_MIX_SEC0, 0x08 }, + { WCD934X_CDC_RX3_RX_PATH_MIX_SEC1, 0x00 }, + { WCD934X_CDC_RX3_RX_PATH_DSMDEM_CTL, 0x00 }, + { WCD934X_CDC_RX4_RX_PATH_CTL, 0x04 }, + { WCD934X_CDC_RX4_RX_PATH_CFG0, 0x00 }, + { WCD934X_CDC_RX4_RX_PATH_CFG1, 0x64 }, + { WCD934X_CDC_RX4_RX_PATH_CFG2, 0x8f }, + { WCD934X_CDC_RX4_RX_VOL_CTL, 0x00 }, + { WCD934X_CDC_RX4_RX_PATH_MIX_CTL, 0x04 }, + { WCD934X_CDC_RX4_RX_PATH_MIX_CFG, 0x7e }, + { WCD934X_CDC_RX4_RX_VOL_MIX_CTL, 0x00 }, + { WCD934X_CDC_RX4_RX_PATH_SEC0, 0xfc }, + { WCD934X_CDC_RX4_RX_PATH_SEC1, 0x08 }, + { WCD934X_CDC_RX4_RX_PATH_SEC2, 0x00 }, + { WCD934X_CDC_RX4_RX_PATH_SEC3, 0x00 }, + { WCD934X_CDC_RX4_RX_PATH_SEC5, 0x00 }, + { WCD934X_CDC_RX4_RX_PATH_SEC6, 0x00 }, + { WCD934X_CDC_RX4_RX_PATH_SEC7, 0x00 }, + { WCD934X_CDC_RX4_RX_PATH_MIX_SEC0, 0x08 }, + { WCD934X_CDC_RX4_RX_PATH_MIX_SEC1, 0x00 }, + { WCD934X_CDC_RX4_RX_PATH_DSMDEM_CTL, 0x00 }, + { WCD934X_CDC_RX7_RX_PATH_CTL, 0x04 }, + { WCD934X_CDC_RX7_RX_PATH_CFG0, 0x00 }, + { WCD934X_CDC_RX7_RX_PATH_CFG1, 0x64 }, + { WCD934X_CDC_RX7_RX_PATH_CFG2, 0x8f }, + { WCD934X_CDC_RX7_RX_VOL_CTL, 0x00 }, + { WCD934X_CDC_RX7_RX_PATH_MIX_CTL, 0x04 }, + { WCD934X_CDC_RX7_RX_PATH_MIX_CFG, 0x7e }, + { WCD934X_CDC_RX7_RX_VOL_MIX_CTL, 0x00 }, + { WCD934X_CDC_RX7_RX_PATH_SEC0, 0x04 }, + { WCD934X_CDC_RX7_RX_PATH_SEC1, 0x08 }, + { WCD934X_CDC_RX7_RX_PATH_SEC2, 0x00 }, + { WCD934X_CDC_RX7_RX_PATH_SEC3, 0x00 }, + { WCD934X_CDC_RX7_RX_PATH_SEC5, 0x00 }, + { WCD934X_CDC_RX7_RX_PATH_SEC6, 0x00 }, + { WCD934X_CDC_RX7_RX_PATH_SEC7, 0x00 }, + { WCD934X_CDC_RX7_RX_PATH_MIX_SEC0, 0x08 }, + { WCD934X_CDC_RX7_RX_PATH_MIX_SEC1, 0x00 }, + { WCD934X_CDC_RX7_RX_PATH_DSMDEM_CTL, 0x00 }, + { WCD934X_CDC_RX8_RX_PATH_CTL, 0x04 }, + { WCD934X_CDC_RX8_RX_PATH_CFG0, 0x00 }, + { WCD934X_CDC_RX8_RX_PATH_CFG1, 0x64 }, + { WCD934X_CDC_RX8_RX_PATH_CFG2, 0x8f }, + { WCD934X_CDC_RX8_RX_VOL_CTL, 0x00 }, + { WCD934X_CDC_RX8_RX_PATH_MIX_CTL, 0x04 }, + { WCD934X_CDC_RX8_RX_PATH_MIX_CFG, 0x7e }, + { WCD934X_CDC_RX8_RX_VOL_MIX_CTL, 0x00 }, + { WCD934X_CDC_RX8_RX_PATH_SEC0, 0x04 }, + { WCD934X_CDC_RX8_RX_PATH_SEC1, 0x08 }, + { WCD934X_CDC_RX8_RX_PATH_SEC2, 0x00 }, + { WCD934X_CDC_RX8_RX_PATH_SEC3, 0x00 }, + { WCD934X_CDC_RX8_RX_PATH_SEC5, 0x00 }, + { WCD934X_CDC_RX8_RX_PATH_SEC6, 0x00 }, + { WCD934X_CDC_RX8_RX_PATH_SEC7, 0x00 }, + { WCD934X_CDC_RX8_RX_PATH_MIX_SEC0, 0x08 }, + { WCD934X_CDC_RX8_RX_PATH_MIX_SEC1, 0x00 }, + { WCD934X_CDC_RX8_RX_PATH_DSMDEM_CTL, 0x00 }, + { WCD934X_PAGE12_PAGE_REGISTER, 0x00 }, + { WCD934X_CDC_CLSH_CRC, 0x00 }, + { WCD934X_CDC_CLSH_DLY_CTRL, 0x03 }, + { WCD934X_CDC_CLSH_DECAY_CTRL, 0x02 }, + { WCD934X_CDC_CLSH_HPH_V_PA, 0x1c }, + { WCD934X_CDC_CLSH_EAR_V_PA, 0x39 }, + { WCD934X_CDC_CLSH_HPH_V_HD, 0x0c }, + { WCD934X_CDC_CLSH_EAR_V_HD, 0x0c }, + { WCD934X_CDC_CLSH_K1_MSB, 0x01 }, + { WCD934X_CDC_CLSH_K1_LSB, 0x00 }, + { WCD934X_CDC_CLSH_K2_MSB, 0x00 }, + { WCD934X_CDC_CLSH_K2_LSB, 0x80 }, + { WCD934X_CDC_CLSH_IDLE_CTRL, 0x00 }, + { WCD934X_CDC_CLSH_IDLE_HPH, 0x00 }, + { WCD934X_CDC_CLSH_IDLE_EAR, 0x00 }, + { WCD934X_CDC_CLSH_TEST0, 0x07 }, + { WCD934X_CDC_CLSH_TEST1, 0x00 }, + { WCD934X_CDC_CLSH_OVR_VREF, 0x00 }, + { WCD934X_CDC_BOOST0_BOOST_PATH_CTL, 0x00 }, + { WCD934X_CDC_BOOST0_BOOST_CTL, 0xb2 }, + { WCD934X_CDC_BOOST0_BOOST_CFG1, 0x00 }, + { WCD934X_CDC_BOOST0_BOOST_CFG2, 0x00 }, + { WCD934X_CDC_BOOST1_BOOST_PATH_CTL, 0x00 }, + { WCD934X_CDC_BOOST1_BOOST_CTL, 0xb2 }, + { WCD934X_CDC_BOOST1_BOOST_CFG1, 0x00 }, + { WCD934X_CDC_BOOST1_BOOST_CFG2, 0x00 }, + { WCD934X_CDC_VBAT_VBAT_PATH_CTL, 0x00 }, + { WCD934X_CDC_VBAT_VBAT_CFG, 0x1a }, + { WCD934X_CDC_VBAT_VBAT_ADC_CAL1, 0x00 }, + { WCD934X_CDC_VBAT_VBAT_ADC_CAL2, 0x00 }, + { WCD934X_CDC_VBAT_VBAT_ADC_CAL3, 0x04 }, + { WCD934X_CDC_VBAT_VBAT_PK_EST1, 0xe0 }, + { WCD934X_CDC_VBAT_VBAT_PK_EST2, 0x01 }, + { WCD934X_CDC_VBAT_VBAT_PK_EST3, 0x40 }, + { WCD934X_CDC_VBAT_VBAT_RF_PROC1, 0x2a }, + { WCD934X_CDC_VBAT_VBAT_RF_PROC2, 0x86 }, + { WCD934X_CDC_VBAT_VBAT_TAC1, 0x70 }, + { WCD934X_CDC_VBAT_VBAT_TAC2, 0x18 }, + { WCD934X_CDC_VBAT_VBAT_TAC3, 0x18 }, + { WCD934X_CDC_VBAT_VBAT_TAC4, 0x03 }, + { WCD934X_CDC_VBAT_VBAT_GAIN_UPD1, 0x01 }, + { WCD934X_CDC_VBAT_VBAT_GAIN_UPD2, 0x00 }, + { WCD934X_CDC_VBAT_VBAT_GAIN_UPD3, 0x64 }, + { WCD934X_CDC_VBAT_VBAT_GAIN_UPD4, 0x01 }, + { WCD934X_CDC_VBAT_VBAT_DEBUG1, 0x00 }, + { WCD934X_CDC_VBAT_VBAT_GAIN_UPD_MON, 0x00 }, + { WCD934X_CDC_VBAT_VBAT_GAIN_MON_VAL, 0x00 }, + { WCD934X_CDC_VBAT_VBAT_BAN, 0x0c }, + { WCD934X_MIXING_ASRC0_CLK_RST_CTL, 0x00 }, + { WCD934X_MIXING_ASRC0_CTL0, 0x00 }, + { WCD934X_MIXING_ASRC0_CTL1, 0x00 }, + { WCD934X_MIXING_ASRC0_FIFO_CTL, 0xa8 }, + { WCD934X_MIXING_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00 }, + { WCD934X_MIXING_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00 }, + { WCD934X_MIXING_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00 }, + { WCD934X_MIXING_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00 }, + { WCD934X_MIXING_ASRC0_STATUS_FIFO, 0x00 }, + { WCD934X_MIXING_ASRC1_CLK_RST_CTL, 0x00 }, + { WCD934X_MIXING_ASRC1_CTL0, 0x00 }, + { WCD934X_MIXING_ASRC1_CTL1, 0x00 }, + { WCD934X_MIXING_ASRC1_FIFO_CTL, 0xa8 }, + { WCD934X_MIXING_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00 }, + { WCD934X_MIXING_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00 }, + { WCD934X_MIXING_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00 }, + { WCD934X_MIXING_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00 }, + { WCD934X_MIXING_ASRC1_STATUS_FIFO, 0x00 }, + { WCD934X_MIXING_ASRC2_CLK_RST_CTL, 0x00 }, + { WCD934X_MIXING_ASRC2_CTL0, 0x00 }, + { WCD934X_MIXING_ASRC2_CTL1, 0x00 }, + { WCD934X_MIXING_ASRC2_FIFO_CTL, 0xa8 }, + { WCD934X_MIXING_ASRC2_STATUS_FMIN_CNTR_LSB, 0x00 }, + { WCD934X_MIXING_ASRC2_STATUS_FMIN_CNTR_MSB, 0x00 }, + { WCD934X_MIXING_ASRC2_STATUS_FMAX_CNTR_LSB, 0x00 }, + { WCD934X_MIXING_ASRC2_STATUS_FMAX_CNTR_MSB, 0x00 }, + { WCD934X_MIXING_ASRC2_STATUS_FIFO, 0x00 }, + { WCD934X_MIXING_ASRC3_CLK_RST_CTL, 0x00 }, + { WCD934X_MIXING_ASRC3_CTL0, 0x00 }, + { WCD934X_MIXING_ASRC3_CTL1, 0x00 }, + { WCD934X_MIXING_ASRC3_FIFO_CTL, 0xa8 }, + { WCD934X_MIXING_ASRC3_STATUS_FMIN_CNTR_LSB, 0x00 }, + { WCD934X_MIXING_ASRC3_STATUS_FMIN_CNTR_MSB, 0x00 }, + { WCD934X_MIXING_ASRC3_STATUS_FMAX_CNTR_LSB, 0x00 }, + { WCD934X_MIXING_ASRC3_STATUS_FMAX_CNTR_MSB, 0x00 }, + { WCD934X_MIXING_ASRC3_STATUS_FIFO, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_WR_DATA_0, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_WR_DATA_1, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_WR_DATA_2, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_WR_DATA_3, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_WR_ADDR_0, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_WR_ADDR_1, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_WR_ADDR_2, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_WR_ADDR_3, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_RD_ADDR_0, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_RD_ADDR_1, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_RD_ADDR_2, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_RD_ADDR_3, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_RD_DATA_0, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_RD_DATA_1, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_RD_DATA_2, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_RD_DATA_3, 0x00 }, + { WCD934X_SWR_AHB_BRIDGE_ACCESS_CFG, 0x0f }, + { WCD934X_SWR_AHB_BRIDGE_ACCESS_STATUS, 0x03 }, + { WCD934X_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL, 0x04 }, + { WCD934X_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1, 0x00 }, + { WCD934X_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL, 0x04 }, + { WCD934X_CDC_SIDETONE_SRC1_ST_SRC_PATH_CFG1, 0x00 }, + { WCD934X_SIDETONE_ASRC0_CLK_RST_CTL, 0x00 }, + { WCD934X_SIDETONE_ASRC0_CTL0, 0x00 }, + { WCD934X_SIDETONE_ASRC0_CTL1, 0x00 }, + { WCD934X_SIDETONE_ASRC0_FIFO_CTL, 0xa8 }, + { WCD934X_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00 }, + { WCD934X_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00 }, + { WCD934X_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00 }, + { WCD934X_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00 }, + { WCD934X_SIDETONE_ASRC0_STATUS_FIFO, 0x00 }, + { WCD934X_SIDETONE_ASRC1_CLK_RST_CTL, 0x00 }, + { WCD934X_SIDETONE_ASRC1_CTL0, 0x00 }, + { WCD934X_SIDETONE_ASRC1_CTL1, 0x00 }, + { WCD934X_SIDETONE_ASRC1_FIFO_CTL, 0xa8 }, + { WCD934X_SIDETONE_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00 }, + { WCD934X_SIDETONE_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00 }, + { WCD934X_SIDETONE_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00 }, + { WCD934X_SIDETONE_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00 }, + { WCD934X_SIDETONE_ASRC1_STATUS_FIFO, 0x00 }, + { WCD934X_EC_REF_HQ0_EC_REF_HQ_PATH_CTL, 0x00 }, + { WCD934X_EC_REF_HQ0_EC_REF_HQ_CFG0, 0x01 }, + { WCD934X_EC_REF_HQ1_EC_REF_HQ_PATH_CTL, 0x00 }, + { WCD934X_EC_REF_HQ1_EC_REF_HQ_CFG0, 0x01 }, + { WCD934X_EC_ASRC0_CLK_RST_CTL, 0x00 }, + { WCD934X_EC_ASRC0_CTL0, 0x00 }, + { WCD934X_EC_ASRC0_CTL1, 0x00 }, + { WCD934X_EC_ASRC0_FIFO_CTL, 0xa8 }, + { WCD934X_EC_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00 }, + { WCD934X_EC_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00 }, + { WCD934X_EC_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00 }, + { WCD934X_EC_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00 }, + { WCD934X_EC_ASRC0_STATUS_FIFO, 0x00 }, + { WCD934X_EC_ASRC1_CLK_RST_CTL, 0x00 }, + { WCD934X_EC_ASRC1_CTL0, 0x00 }, + { WCD934X_EC_ASRC1_CTL1, 0x00 }, + { WCD934X_EC_ASRC1_FIFO_CTL, 0xa8 }, + { WCD934X_EC_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00 }, + { WCD934X_EC_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00 }, + { WCD934X_EC_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00 }, + { WCD934X_EC_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00 }, + { WCD934X_EC_ASRC1_STATUS_FIFO, 0x00 }, + { WCD934X_PAGE13_PAGE_REGISTER, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG0, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG1, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG0, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG1, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG0, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG1, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG0, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG1, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG0, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG1, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG0, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG1, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG0, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG1, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG0, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG1, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG2, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG3, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG4, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_ANC_CFG0, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 0x00 }, + { WCD934X_CDC_RX_INP_MUX_EC_REF_HQ_CFG0, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 0x00 }, + { WCD934X_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3, 0x00 }, + { WCD934X_CDC_IF_ROUTER_TX_MUX_CFG0, 0x00 }, + { WCD934X_CDC_IF_ROUTER_TX_MUX_CFG1, 0x00 }, + { WCD934X_CDC_IF_ROUTER_TX_MUX_CFG2, 0x00 }, + { WCD934X_CDC_IF_ROUTER_TX_MUX_CFG3, 0x00 }, + { WCD934X_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x00 }, + { WCD934X_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x0c }, + { WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL, 0x00 }, + { WCD934X_CDC_CLK_RST_CTRL_DSD_CONTROL, 0x00 }, + { WCD934X_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL, 0x0f }, + { WCD934X_CDC_CLK_RST_CTRL_GFM_CONTROL, 0x00 }, + { WCD934X_CDC_PROX_DETECT_PROX_CTL, 0x08 }, + { WCD934X_CDC_PROX_DETECT_PROX_POLL_PERIOD0, 0x00 }, + { WCD934X_CDC_PROX_DETECT_PROX_POLL_PERIOD1, 0x4b }, + { WCD934X_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB, 0x00 }, + { WCD934X_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB, 0x00 }, + { WCD934X_CDC_PROX_DETECT_PROX_STATUS, 0x00 }, + { WCD934X_CDC_PROX_DETECT_PROX_TEST_CTRL, 0x00 }, + { WCD934X_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB, 0x00 }, + { WCD934X_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB, 0x00 }, + { WCD934X_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD, 0x00 }, + { WCD934X_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD, 0x00 }, + { WCD934X_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR0_IIR_PATH_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR0_IIR_CTL, 0x40 }, + { WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR1_IIR_PATH_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B5_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B6_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B7_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B8_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR1_IIR_CTL, 0x40 }, + { WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR1_IIR_COEF_B1_CTL, 0x00 }, + { WCD934X_CDC_SIDETONE_IIR1_IIR_COEF_B2_CTL, 0x00 }, + { WCD934X_CDC_TOP_TOP_CFG0, 0x00 }, + { WCD934X_CDC_TOP_TOP_CFG1, 0x00 }, + { WCD934X_CDC_TOP_TOP_CFG7, 0x00 }, + { WCD934X_CDC_TOP_HPHL_COMP_WR_LSB, 0x00 }, + { WCD934X_CDC_TOP_HPHL_COMP_WR_MSB, 0x00 }, + { WCD934X_CDC_TOP_HPHL_COMP_LUT, 0x00 }, + { WCD934X_CDC_TOP_HPHL_COMP_RD_LSB, 0x00 }, + { WCD934X_CDC_TOP_HPHL_COMP_RD_MSB, 0x00 }, + { WCD934X_CDC_TOP_HPHR_COMP_WR_LSB, 0x00 }, + { WCD934X_CDC_TOP_HPHR_COMP_WR_MSB, 0x00 }, + { WCD934X_CDC_TOP_HPHR_COMP_LUT, 0x00 }, + { WCD934X_CDC_TOP_HPHR_COMP_RD_LSB, 0x00 }, + { WCD934X_CDC_TOP_HPHR_COMP_RD_MSB, 0x00 }, + { WCD934X_CDC_TOP_DIFFL_COMP_WR_LSB, 0x00 }, + { WCD934X_CDC_TOP_DIFFL_COMP_WR_MSB, 0x00 }, + { WCD934X_CDC_TOP_DIFFL_COMP_LUT, 0x00 }, + { WCD934X_CDC_TOP_DIFFL_COMP_RD_LSB, 0x00 }, + { WCD934X_CDC_TOP_DIFFL_COMP_RD_MSB, 0x00 }, + { WCD934X_CDC_TOP_DIFFR_COMP_WR_LSB, 0x00 }, + { WCD934X_CDC_TOP_DIFFR_COMP_WR_MSB, 0x00 }, + { WCD934X_CDC_TOP_DIFFR_COMP_LUT, 0x00 }, + { WCD934X_CDC_TOP_DIFFR_COMP_RD_LSB, 0x00 }, + { WCD934X_CDC_TOP_DIFFR_COMP_RD_MSB, 0x00 }, + { WCD934X_CDC_DSD0_PATH_CTL, 0x00 }, + { WCD934X_CDC_DSD0_CFG0, 0x00 }, + { WCD934X_CDC_DSD0_CFG1, 0x00 }, + { WCD934X_CDC_DSD0_CFG2, 0x42 }, + { WCD934X_CDC_DSD0_CFG3, 0x00 }, + { WCD934X_CDC_DSD0_CFG4, 0x02 }, + { WCD934X_CDC_DSD0_CFG5, 0x00 }, + { WCD934X_CDC_DSD1_PATH_CTL, 0x00 }, + { WCD934X_CDC_DSD1_CFG0, 0x00 }, + { WCD934X_CDC_DSD1_CFG1, 0x00 }, + { WCD934X_CDC_DSD1_CFG2, 0x42 }, + { WCD934X_CDC_DSD1_CFG3, 0x00 }, + { WCD934X_CDC_DSD1_CFG4, 0x02 }, + { WCD934X_CDC_DSD1_CFG5, 0x00 }, + { WCD934X_CDC_RX_IDLE_DET_PATH_CTL, 0x00 }, + { WCD934X_CDC_RX_IDLE_DET_CFG0, 0x07 }, + { WCD934X_CDC_RX_IDLE_DET_CFG1, 0x3c }, + { WCD934X_CDC_RX_IDLE_DET_CFG2, 0x00 }, + { WCD934X_CDC_RX_IDLE_DET_CFG3, 0x00 }, + { WCD934X_PAGE14_PAGE_REGISTER, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_CLK_RST_CTL, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_CTL, 0x09 }, + { WCD934X_CDC_RATE_EST0_RE_PULSE_SUPR_CTL, 0x06 }, + { WCD934X_CDC_RATE_EST0_RE_TIMER, 0x01 }, + { WCD934X_CDC_RATE_EST0_RE_BW_SW, 0x20 }, + { WCD934X_CDC_RATE_EST0_RE_THRESH, 0xa0 }, + { WCD934X_CDC_RATE_EST0_RE_STATUS, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_CTRL, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_TIMER2, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW1, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW2, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW3, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW4, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW5, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW1, 0x08 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW2, 0x07 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW3, 0x05 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW4, 0x05 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW5, 0x05 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW1, 0x08 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW2, 0x07 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW3, 0x05 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW4, 0x05 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW5, 0x05 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW1, 0x03 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW2, 0x03 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW3, 0x03 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW4, 0x03 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW5, 0x03 }, + { WCD934X_CDC_RATE_EST0_RE_RMAX_DIAG, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_RMIN_DIAG, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_PH_DET, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_DIAG_CLR, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_MB_SW_STATE, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_MAST_DIAG_STATE, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_RATE_OUT_7_0, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_RATE_OUT_15_8, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_RATE_OUT_23_16, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_RATE_OUT_31_24, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_RATE_OUT_39_32, 0x00 }, + { WCD934X_CDC_RATE_EST0_RE_RATE_OUT_40_43, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_CLK_RST_CTL, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_CTL, 0x09 }, + { WCD934X_CDC_RATE_EST1_RE_PULSE_SUPR_CTL, 0x06 }, + { WCD934X_CDC_RATE_EST1_RE_TIMER, 0x01 }, + { WCD934X_CDC_RATE_EST1_RE_BW_SW, 0x20 }, + { WCD934X_CDC_RATE_EST1_RE_THRESH, 0xa0 }, + { WCD934X_CDC_RATE_EST1_RE_STATUS, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_CTRL, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_TIMER2, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW1, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW2, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW3, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW4, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW5, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW1, 0x08 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW2, 0x07 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW3, 0x05 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW4, 0x05 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW5, 0x05 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW1, 0x08 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW2, 0x07 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW3, 0x05 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW4, 0x05 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW5, 0x05 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW1, 0x03 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW2, 0x03 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW3, 0x03 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW4, 0x03 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW5, 0x03 }, + { WCD934X_CDC_RATE_EST1_RE_RMAX_DIAG, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_RMIN_DIAG, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_PH_DET, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_DIAG_CLR, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_MB_SW_STATE, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_MAST_DIAG_STATE, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_RATE_OUT_7_0, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_RATE_OUT_15_8, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_RATE_OUT_23_16, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_RATE_OUT_31_24, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_RATE_OUT_39_32, 0x00 }, + { WCD934X_CDC_RATE_EST1_RE_RATE_OUT_40_43, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_CLK_RST_CTL, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_CTL, 0x09 }, + { WCD934X_CDC_RATE_EST2_RE_PULSE_SUPR_CTL, 0x06 }, + { WCD934X_CDC_RATE_EST2_RE_TIMER, 0x01 }, + { WCD934X_CDC_RATE_EST2_RE_BW_SW, 0x20 }, + { WCD934X_CDC_RATE_EST2_RE_THRESH, 0xa0 }, + { WCD934X_CDC_RATE_EST2_RE_STATUS, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_CTRL, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_TIMER2, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW1, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW2, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW3, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW4, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW5, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW1, 0x08 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW2, 0x07 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW3, 0x05 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW4, 0x05 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW5, 0x05 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW1, 0x08 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW2, 0x07 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW3, 0x05 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW4, 0x05 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW5, 0x05 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW1, 0x03 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW2, 0x03 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW3, 0x03 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW4, 0x03 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW5, 0x03 }, + { WCD934X_CDC_RATE_EST2_RE_RMAX_DIAG, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_RMIN_DIAG, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_PH_DET, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_DIAG_CLR, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_MB_SW_STATE, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_MAST_DIAG_STATE, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_RATE_OUT_7_0, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_RATE_OUT_15_8, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_RATE_OUT_23_16, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_RATE_OUT_31_24, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_RATE_OUT_39_32, 0x00 }, + { WCD934X_CDC_RATE_EST2_RE_RATE_OUT_40_43, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_CLK_RST_CTL, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_CTL, 0x09 }, + { WCD934X_CDC_RATE_EST3_RE_PULSE_SUPR_CTL, 0x06 }, + { WCD934X_CDC_RATE_EST3_RE_TIMER, 0x01 }, + { WCD934X_CDC_RATE_EST3_RE_BW_SW, 0x20 }, + { WCD934X_CDC_RATE_EST3_RE_THRESH, 0xa0 }, + { WCD934X_CDC_RATE_EST3_RE_STATUS, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_CTRL, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_TIMER2, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW1, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW2, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW3, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW4, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW5, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW1, 0x08 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW2, 0x07 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW3, 0x05 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW4, 0x05 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW5, 0x05 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW1, 0x08 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW2, 0x07 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW3, 0x05 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW4, 0x05 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW5, 0x05 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW1, 0x03 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW2, 0x03 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW3, 0x03 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW4, 0x03 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW5, 0x03 }, + { WCD934X_CDC_RATE_EST3_RE_RMAX_DIAG, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_RMIN_DIAG, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_PH_DET, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_DIAG_CLR, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_MB_SW_STATE, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_MAST_DIAG_STATE, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_RATE_OUT_7_0, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_RATE_OUT_15_8, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_RATE_OUT_23_16, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_RATE_OUT_31_24, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_RATE_OUT_39_32, 0x00 }, + { WCD934X_CDC_RATE_EST3_RE_RATE_OUT_40_43, 0x00 }, + { WCD934X_PAGE15_PAGE_REGISTER, 0x00 }, + { WCD934X_SPLINE_SRC0_CLK_RST_CTL_0, 0x20 }, + { WCD934X_SPLINE_SRC0_STATUS, 0x00 }, + { WCD934X_SPLINE_SRC1_CLK_RST_CTL_0, 0x20 }, + { WCD934X_SPLINE_SRC1_STATUS, 0x00 }, + { WCD934X_SPLINE_SRC2_CLK_RST_CTL_0, 0x20 }, + { WCD934X_SPLINE_SRC2_STATUS, 0x00 }, + { WCD934X_SPLINE_SRC3_CLK_RST_CTL_0, 0x20 }, + { WCD934X_SPLINE_SRC3_STATUS, 0x00 }, + { WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG0, 0x11 }, + { WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG1, 0x20 }, + { WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG2, 0x00 }, + { WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG3, 0x08 }, + { WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG0, 0x11 }, + { WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG1, 0x20 }, + { WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG2, 0x00 }, + { WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG3, 0x08 }, + { WCD934X_CDC_DEBUG_SPLINE_SRC_DEBUG_CFG0, 0x00 }, + { WCD934X_CDC_DEBUG_SPLINE_SRC_DEBUG_CFG1, 0x00 }, + { WCD934X_CDC_DEBUG_RC_RE_ASRC_DEBUG_CFG0, 0x00 }, + { WCD934X_CDC_DEBUG_ANC0_RC0_FIFO_CTL, 0x4c }, + { WCD934X_CDC_DEBUG_ANC0_RC1_FIFO_CTL, 0x4c }, + { WCD934X_CDC_DEBUG_ANC1_RC0_FIFO_CTL, 0x4c }, + { WCD934X_CDC_DEBUG_ANC1_RC1_FIFO_CTL, 0x4c }, + { WCD934X_CDC_DEBUG_ANC_RC_RST_DBG_CNTR, 0x00 }, + { WCD934X_PAGE80_PAGE_REGISTER, 0x00 }, + { WCD934X_CODEC_CPR_WR_DATA_0, 0x00 }, + { WCD934X_CODEC_CPR_WR_DATA_1, 0x00 }, + { WCD934X_CODEC_CPR_WR_DATA_2, 0x00 }, + { WCD934X_CODEC_CPR_WR_DATA_3, 0x00 }, + { WCD934X_CODEC_CPR_WR_ADDR_0, 0x00 }, + { WCD934X_CODEC_CPR_WR_ADDR_1, 0x00 }, + { WCD934X_CODEC_CPR_WR_ADDR_2, 0x00 }, + { WCD934X_CODEC_CPR_WR_ADDR_3, 0x00 }, + { WCD934X_CODEC_CPR_RD_ADDR_0, 0x00 }, + { WCD934X_CODEC_CPR_RD_ADDR_1, 0x00 }, + { WCD934X_CODEC_CPR_RD_ADDR_2, 0x00 }, + { WCD934X_CODEC_CPR_RD_ADDR_3, 0x00 }, + { WCD934X_CODEC_CPR_RD_DATA_0, 0x00 }, + { WCD934X_CODEC_CPR_RD_DATA_1, 0x00 }, + { WCD934X_CODEC_CPR_RD_DATA_2, 0x00 }, + { WCD934X_CODEC_CPR_RD_DATA_3, 0x00 }, + { WCD934X_CODEC_CPR_ACCESS_CFG, 0x0f }, + { WCD934X_CODEC_CPR_ACCESS_STATUS, 0x03 }, + { WCD934X_CODEC_CPR_NOM_CX_VDD, 0xb4 }, + { WCD934X_CODEC_CPR_SVS_CX_VDD, 0x5c }, + { WCD934X_CODEC_CPR_SVS2_CX_VDD, 0x40 }, + { WCD934X_CODEC_CPR_NOM_MX_VDD, 0xb4 }, + { WCD934X_CODEC_CPR_SVS_MX_VDD, 0xb4 }, + { WCD934X_CODEC_CPR_SVS2_MX_VDD, 0xa0 }, + { WCD934X_CODEC_CPR_SVS2_MIN_CX_VDD, 0x28 }, + { WCD934X_CODEC_CPR_MAX_SVS2_STEP, 0x08 }, + { WCD934X_CODEC_CPR_CTL, 0x00 }, + { WCD934X_CODEC_CPR_SW_MODECHNG_STATUS, 0x00 }, + { WCD934X_CODEC_CPR_SW_MODECHNG_START, 0x00 }, + { WCD934X_CODEC_CPR_CPR_STATUS, 0x00 }, + { WCD934X_PAGE128_PAGE_REGISTER, 0x00 }, + { WCD934X_TLMM_BIST_MODE_PINCFG, 0x00 }, + { WCD934X_TLMM_RF_PA_ON_PINCFG, 0x00 }, + { WCD934X_TLMM_INTR1_PINCFG, 0x00 }, + { WCD934X_TLMM_INTR2_PINCFG, 0x00 }, + { WCD934X_TLMM_SWR_DATA_PINCFG, 0x00 }, + { WCD934X_TLMM_SWR_CLK_PINCFG, 0x00 }, + { WCD934X_TLMM_I2S_2_SCK_PINCFG, 0x00 }, + { WCD934X_TLMM_SLIMBUS_DATA1_PINCFG, 0x00 }, + { WCD934X_TLMM_SLIMBUS_DATA2_PINCFG, 0x00 }, + { WCD934X_TLMM_SLIMBUS_CLK_PINCFG, 0x00 }, + { WCD934X_TLMM_I2C_CLK_PINCFG, 0x00 }, + { WCD934X_TLMM_I2C_DATA_PINCFG, 0x00 }, + { WCD934X_TLMM_I2S_0_RX_PINCFG, 0x00 }, + { WCD934X_TLMM_I2S_0_TX_PINCFG, 0x00 }, + { WCD934X_TLMM_I2S_0_SCK_PINCFG, 0x00 }, + { WCD934X_TLMM_I2S_0_WS_PINCFG, 0x00 }, + { WCD934X_TLMM_I2S_1_RX_PINCFG, 0x00 }, + { WCD934X_TLMM_I2S_1_TX_PINCFG, 0x00 }, + { WCD934X_TLMM_I2S_1_SCK_PINCFG, 0x00 }, + { WCD934X_TLMM_I2S_1_WS_PINCFG, 0x00 }, + { WCD934X_TLMM_DMIC1_CLK_PINCFG, 0x00 }, + { WCD934X_TLMM_DMIC1_DATA_PINCFG, 0x00 }, + { WCD934X_TLMM_DMIC2_CLK_PINCFG, 0x00 }, + { WCD934X_TLMM_DMIC2_DATA_PINCFG, 0x00 }, + { WCD934X_TLMM_DMIC3_CLK_PINCFG, 0x00 }, + { WCD934X_TLMM_DMIC3_DATA_PINCFG, 0x00 }, + { WCD934X_TLMM_JTCK_PINCFG, 0x00 }, + { WCD934X_TLMM_GPIO1_PINCFG, 0x00 }, + { WCD934X_TLMM_GPIO2_PINCFG, 0x00 }, + { WCD934X_TLMM_GPIO3_PINCFG, 0x00 }, + { WCD934X_TLMM_GPIO4_PINCFG, 0x00 }, + { WCD934X_TLMM_SPI_S_CSN_PINCFG, 0x00 }, + { WCD934X_TLMM_SPI_S_CLK_PINCFG, 0x00 }, + { WCD934X_TLMM_SPI_S_DOUT_PINCFG, 0x00 }, + { WCD934X_TLMM_SPI_S_DIN_PINCFG, 0x00 }, + { WCD934X_TLMM_BA_N_PINCFG, 0x00 }, + { WCD934X_TLMM_GPIO0_PINCFG, 0x00 }, + { WCD934X_TLMM_I2S_2_RX_PINCFG, 0x00 }, + { WCD934X_TLMM_I2S_2_WS_PINCFG, 0x00 }, + { WCD934X_TEST_DEBUG_PIN_CTL_OE_0, 0x00 }, + { WCD934X_TEST_DEBUG_PIN_CTL_OE_1, 0x00 }, + { WCD934X_TEST_DEBUG_PIN_CTL_OE_2, 0x00 }, + { WCD934X_TEST_DEBUG_PIN_CTL_OE_3, 0x00 }, + { WCD934X_TEST_DEBUG_PIN_CTL_OE_4, 0x00 }, + { WCD934X_TEST_DEBUG_PIN_CTL_DATA_0, 0x00 }, + { WCD934X_TEST_DEBUG_PIN_CTL_DATA_1, 0x00 }, + { WCD934X_TEST_DEBUG_PIN_CTL_DATA_2, 0x00 }, + { WCD934X_TEST_DEBUG_PIN_CTL_DATA_3, 0x00 }, + { WCD934X_TEST_DEBUG_PIN_CTL_DATA_4, 0x00 }, + { WCD934X_TEST_DEBUG_PAD_DRVCTL_0, 0x00 }, + { WCD934X_TEST_DEBUG_PAD_DRVCTL_1, 0x00 }, + { WCD934X_TEST_DEBUG_PIN_STATUS, 0x00 }, + { WCD934X_TEST_DEBUG_NPL_DLY_TEST_1, 0x10 }, + { WCD934X_TEST_DEBUG_NPL_DLY_TEST_2, 0x60 }, + { WCD934X_TEST_DEBUG_MEM_CTRL, 0x00 }, + { WCD934X_TEST_DEBUG_DEBUG_BUS_SEL, 0x00 }, + { WCD934X_TEST_DEBUG_DEBUG_JTAG, 0x00 }, + { WCD934X_TEST_DEBUG_DEBUG_EN_1, 0x00 }, + { WCD934X_TEST_DEBUG_DEBUG_EN_2, 0x00 }, + { WCD934X_TEST_DEBUG_DEBUG_EN_3, 0x00 }, + { WCD934X_TEST_DEBUG_DEBUG_EN_4, 0x00 }, + { WCD934X_TEST_DEBUG_DEBUG_EN_5, 0x00 }, + { WCD934X_TEST_DEBUG_ANA_DTEST_DIR, 0x00 }, + { WCD934X_TEST_DEBUG_PAD_INP_DISABLE_0, 0x00 }, + { WCD934X_TEST_DEBUG_PAD_INP_DISABLE_1, 0x00 }, + { WCD934X_TEST_DEBUG_PAD_INP_DISABLE_2, 0x00 }, + { WCD934X_TEST_DEBUG_PAD_INP_DISABLE_3, 0x00 }, + { WCD934X_TEST_DEBUG_PAD_INP_DISABLE_4, 0x00 }, + { WCD934X_TEST_DEBUG_SYSMEM_CTRL, 0x00 }, + { WCD934X_TEST_DEBUG_SOC_SW_PWR_SEQ_DELAY, 0x00 }, + { WCD934X_TEST_DEBUG_LVAL_NOM_LOW, 0x96 }, + { WCD934X_TEST_DEBUG_LVAL_NOM_HIGH, 0x00 }, + { WCD934X_TEST_DEBUG_LVAL_SVS_SVS2_LOW, 0x53 }, + { WCD934X_TEST_DEBUG_LVAL_SVS_SVS2_HIGH, 0x00 }, + { WCD934X_TEST_DEBUG_SPI_SLAVE_CHAR, 0x00 }, + { WCD934X_TEST_DEBUG_CODEC_DIAGS, 0x00 }, +}; + +/* + * wcd934x_regmap_register_patch: Update register defaults based on version + * @regmap: handle to wcd9xxx regmap + * @version: wcd934x version + * + * Returns error code in case of failure or 0 for success + */ +int wcd934x_regmap_register_patch(struct regmap *regmap, int revision) +{ + int rc = 0; + + if (!regmap) { + pr_err("%s: regmap struct is NULL\n", __func__); + return -EINVAL; + } + + switch (revision) { + case TAVIL_VERSION_1_1: + case TAVIL_VERSION_WCD9340_1_1: + case TAVIL_VERSION_WCD9341_1_1: + regcache_cache_only(regmap, true); + rc = regmap_multi_reg_write(regmap, wcd934x_1_1_defaults, + ARRAY_SIZE(wcd934x_1_1_defaults)); + regcache_cache_only(regmap, false); + break; + } + + return rc; +} +EXPORT_SYMBOL(wcd934x_regmap_register_patch); + +static bool wcd934x_is_readable_register(struct device *dev, unsigned int reg) +{ + u8 pg_num, reg_offset; + const u8 *reg_tbl = NULL; + + /* + * Get the page number from MSB of codec register. If its 0x80, assign + * the corresponding page index PAGE_0x80. + */ + pg_num = reg >> 0x8; + if (pg_num == 0x80) + pg_num = WCD934X_PAGE_0X80; + else if (pg_num == 0x50) + pg_num = WCD934X_PAGE_0x50; + else if (pg_num > 0xF) + return false; + + reg_tbl = wcd934x_reg[pg_num]; + reg_offset = reg & 0xFF; + + if (reg_tbl && reg_tbl[reg_offset]) + return true; + else + return false; +} + +static bool wcd934x_is_volatile_register(struct device *dev, unsigned int reg) +{ + u8 pg_num, reg_offset; + const u8 *reg_tbl = NULL; + + pg_num = reg >> 0x8; + if (pg_num == 0x80) + pg_num = WCD934X_PAGE_0X80; + else if (pg_num == 0x50) + pg_num = WCD934X_PAGE_0x50; + else if (pg_num > 0xF) + return false; + + reg_tbl = wcd934x_reg[pg_num]; + reg_offset = reg & 0xFF; + + if (reg_tbl && reg_tbl[reg_offset] == WCD934X_READ) + return true; + + /* IIR Coeff registers are not cacheable */ + if ((reg >= WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL) && + (reg <= WCD934X_CDC_SIDETONE_IIR1_IIR_COEF_B2_CTL)) + return true; + + if ((reg >= WCD934X_CDC_ANC0_IIR_COEFF_1_CTL) && + (reg <= WCD934X_CDC_ANC0_FB_GAIN_CTL)) + return true; + + if ((reg >= WCD934X_CDC_ANC1_IIR_COEFF_1_CTL) && + (reg <= WCD934X_CDC_ANC1_FB_GAIN_CTL)) + return true; + + if ((reg >= WCD934X_CODEC_CPR_WR_DATA_0) && + (reg <= WCD934X_CODEC_CPR_RD_DATA_3)) + return true; + + /* + * Need to mark volatile for registers that are writable but + * only few bits are read-only + */ + switch (reg) { + case WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL: + case WCD934X_CPE_SS_PWR_SYS_PSTATE_CTL_0: + case WCD934X_CPE_SS_PWR_SYS_PSTATE_CTL_1: + case WCD934X_CPE_SS_CPAR_CTL: + case WCD934X_CPE_SS_STATUS: + case WCD934X_CODEC_RPM_RST_CTL: + case WCD934X_SIDO_NEW_VOUT_A_STARTUP: + case WCD934X_SIDO_NEW_VOUT_D_STARTUP: + case WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL: + case WCD934X_ANA_MBHC_MECH: + case WCD934X_ANA_MBHC_ELECT: + case WCD934X_ANA_MBHC_ZDET: + case WCD934X_ANA_MICB2: + case WCD934X_CODEC_RPM_CLK_MCLK_CFG: + case WCD934X_CLK_SYS_MCLK_PRG: + case WCD934X_CHIP_TIER_CTRL_EFUSE_CTL: + case WCD934X_ANA_BIAS: + case WCD934X_ANA_BUCK_CTL: + case WCD934X_ANA_RCO: + case WCD934X_CDC_CLK_RST_CTRL_MCLK_CONTROL: + case WCD934X_CODEC_RPM_CLK_GATE: + case WCD934X_BIAS_VBG_FINE_ADJ: + case WCD934X_CODEC_CPR_SVS_CX_VDD: + case WCD934X_CODEC_CPR_SVS2_CX_VDD: + case WCD934X_CDC_CLK_RST_CTRL_FS_CNT_CONTROL: + return true; + } + + return false; +} + +struct regmap_config wcd934x_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wcd934x_defaults, + .num_reg_defaults = ARRAY_SIZE(wcd934x_defaults), + .max_register = WCD934X_MAX_REGISTER, + .volatile_reg = wcd934x_is_volatile_register, + .readable_reg = wcd934x_is_readable_register, + .can_multi_write = true, +}; diff --git a/drivers/mfd/wcd934x-tables.c b/drivers/mfd/wcd934x-tables.c new file mode 100644 index 000000000000..db963d08b66e --- /dev/null +++ b/drivers/mfd/wcd934x-tables.c @@ -0,0 +1,2155 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#define WCD934X_REG(reg) ((reg) & 0xFF) + +const u8 wcd934x_page0_reg_access[WCD934X_PAGE_SIZE] = { + [WCD934X_REG(WCD934X_PAGE0_PAGE_REGISTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_RPM_CLK_BYPASS)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_RPM_CLK_GATE)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_RPM_CLK_MCLK_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_RPM_CLK_MCLK2_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_RPM_I2S_DSD_CLK_SEL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_RPM_RST_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE0)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE1)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE2)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE3)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_TEST0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_TEST1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT0)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT1)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT2)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT3)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT4)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT5)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT6)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT7)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT8)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT9)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT10)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT11)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT12)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT13)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT14)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT15)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_EFUSE_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO)] = + WCD934X_READ, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_I2C_SLAVE_ID_1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_I2C_SLAVE_ID_2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_I2C_SLAVE_ID_3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_SLNQ_WAIT_STATE_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_I2C_ACTIVE)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_ALT_FUNC_EN)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_GPIO_CTL_OE)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CHIP_TIER_CTRL_GPIO_CTL_DATA)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_RX0_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_RX1_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_RX2_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_RX3_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_RX4_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_RX5_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_RX6_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_RX7_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_SB_TX0_INP_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_SB_TX1_INP_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_SB_TX2_INP_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_SB_TX3_INP_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_SB_TX4_INP_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_SB_TX5_INP_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_SB_TX6_INP_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_SB_TX7_INP_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_SB_TX8_INP_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_SB_TX9_INP_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_SB_TX10_INP_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_SB_TX11_INP_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_SB_TX13_INP_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_SB_TX14_INP_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_SB_TX15_INP_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_I2S_TX0_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_I2S_TX1_0_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_I2S_TX1_1_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_I2S_0_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_I2S_1_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_I2S_2_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_I2S_3_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_I2S_CLKSRC_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_I2S_COMMON_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_I2S_0_TDM_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DATA_HUB_I2S_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_DMA_RDMA_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_2_3_CFG_RDMA_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_0_1_CFG_RDMA_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_RDMA_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_2_3_CFG_RDMA_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_0_1_CFG_RDMA_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_RDMA_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_2_3_CFG_RDMA_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_0_1_CFG_RDMA_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_RDMA_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_2_3_CFG_RDMA_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_0_1_CFG_RDMA_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_RDMA_CTL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_2_3_CFG_RDMA_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_0_1_CFG_RDMA_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_RDMA4_PRT_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_RDMA_SBTX0_7_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_RDMA_SBTX8_11_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_WDMA_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_4_5_CFG_WDMA_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_2_3_CFG_WDMA_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_0_1_CFG_WDMA_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_WDMA_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_4_5_CFG_WDMA_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_2_3_CFG_WDMA_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_0_1_CFG_WDMA_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_WDMA_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_4_5_CFG_WDMA_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_2_3_CFG_WDMA_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_0_1_CFG_WDMA_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_WDMA_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_4_5_CFG_WDMA_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_2_3_CFG_WDMA_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_0_1_CFG_WDMA_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_WDMA_CTL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_4_5_CFG_WDMA_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_2_3_CFG_WDMA_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_CH_0_1_CFG_WDMA_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_WDMA0_PRT_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_WDMA3_PRT_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_WDMA4_PRT0_3_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DMA_WDMA4_PRT4_7_CFG)] = WCD934X_READ_WRITE, +}; + +const u8 wcd934x_page1_reg_access[WCD934X_PAGE_SIZE] = { + [WCD934X_REG(WCD934X_PAGE1_PAGE_REGISTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_USER_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_USER_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_USER_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_USER_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_USER_CTL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_USER_CTL_5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_USER_CTL_6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_USER_CTL_7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_USER_CTL_8)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_USER_CTL_9)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_L_VAL_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_L_VAL_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_DSM_FRAC_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_DSM_FRAC_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_CONFIG_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_CONFIG_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_CONFIG_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_CONFIG_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_CONFIG_CTL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_TEST_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_TEST_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_TEST_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_TEST_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_TEST_CTL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_TEST_CTL_5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_TEST_CTL_6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_TEST_CTL_7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_FREQ_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_FREQ_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_FREQ_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_FREQ_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_SSC_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_SSC_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_SSC_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_SSC_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_FLL_MODE)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_FLL_STATUS_0)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CPE_FLL_STATUS_1)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CPE_FLL_STATUS_2)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CPE_FLL_STATUS_3)] = WCD934X_READ, + [WCD934X_REG(WCD934X_I2S_FLL_USER_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_USER_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_USER_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_USER_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_USER_CTL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_USER_CTL_5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_USER_CTL_6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_USER_CTL_7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_USER_CTL_8)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_USER_CTL_9)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_L_VAL_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_L_VAL_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_DSM_FRAC_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_DSM_FRAC_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_CONFIG_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_CONFIG_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_CONFIG_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_CONFIG_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_CONFIG_CTL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_TEST_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_TEST_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_TEST_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_TEST_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_TEST_CTL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_TEST_CTL_5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_TEST_CTL_6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_TEST_CTL_7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_FREQ_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_FREQ_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_FREQ_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_FREQ_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_SSC_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_SSC_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_SSC_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_SSC_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_FLL_MODE)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_I2S_FLL_STATUS_0)] = WCD934X_READ, + [WCD934X_REG(WCD934X_I2S_FLL_STATUS_1)] = WCD934X_READ, + [WCD934X_REG(WCD934X_I2S_FLL_STATUS_2)] = WCD934X_READ, + [WCD934X_REG(WCD934X_I2S_FLL_STATUS_3)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SB_FLL_USER_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_USER_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_USER_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_USER_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_USER_CTL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_USER_CTL_5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_USER_CTL_6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_USER_CTL_7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_USER_CTL_8)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_USER_CTL_9)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_L_VAL_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_L_VAL_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_DSM_FRAC_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_DSM_FRAC_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_CONFIG_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_CONFIG_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_CONFIG_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_CONFIG_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_CONFIG_CTL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_TEST_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_TEST_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_TEST_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_TEST_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_TEST_CTL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_TEST_CTL_5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_TEST_CTL_6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_TEST_CTL_7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_FREQ_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_FREQ_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_FREQ_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_FREQ_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_SSC_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_SSC_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_SSC_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_SSC_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_FLL_MODE)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SB_FLL_STATUS_0)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SB_FLL_STATUS_1)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SB_FLL_STATUS_2)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SB_FLL_STATUS_3)] = WCD934X_READ, +}; + +const u8 wcd934x_page2_reg_access[WCD934X_PAGE_SIZE] = { + [WCD934X_REG(WCD934X_PAGE2_PAGE_REGISTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_CPE_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_PWR_SYS_PSTATE_CTL_0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_PWR_SYS_PSTATE_CTL_1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_PWR_CPEFLL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_OVERRIDE)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_SOC_SW_COLLAPSE_OVERRIDE_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_SOC_SW_COLLAPSE_OVERRIDE_CTL1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_US_BUF_INT_PERIOD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_SVA_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_US_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_MAD_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_CPAR_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_DMIC0_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_DMIC1_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_DMIC2_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_DMIC_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_CPAR_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_WDOG_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_BACKUP_INT)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_STATUS)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_CPE_OCD_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_SS_ERROR_INT_MASK_1A)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_SS_ERROR_INT_MASK_1B)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0A)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0B)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CPE_SS_SS_ERROR_INT_STATUS_1A)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CPE_SS_SS_ERROR_INT_STATUS_1B)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_0A)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_0B)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_1A)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_1B)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_MAIN_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_MAIN_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_AUDIO_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_AUDIO_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_AUDIO_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_AUDIO_CTL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_AUDIO_CTL_5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_AUDIO_CTL_6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_AUDIO_CTL_7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_AUDIO_CTL_8)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_AUDIO_IIR_CTL_PTR)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_AUDIO_IIR_CTL_VAL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_ULTR_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_ULTR_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_ULTR_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_ULTR_CTL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_ULTR_CTL_5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_ULTR_CTL_6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_ULTR_CTL_7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_BEACON_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_BEACON_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_BEACON_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_BEACON_CTL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_BEACON_CTL_5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_BEACON_CTL_6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_BEACON_CTL_7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_BEACON_CTL_8)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_BEACON_IIR_CTL_PTR)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_BEACON_IIR_CTL_VAL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SOC_MAD_INP_SEL)] = WCD934X_READ_WRITE, +}; + +const u8 wcd934x_page4_reg_access[WCD934X_PAGE_SIZE] = { + [WCD934X_REG(WCD934X_PAGE4_PAGE_REGISTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_CLR_COMMIT)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_INTR_PIN1_MASK0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_PIN1_MASK1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_PIN1_MASK2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_PIN1_MASK3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_PIN1_STATUS0)] = WCD934X_READ, + [WCD934X_REG(WCD934X_INTR_PIN1_STATUS1)] = WCD934X_READ, + [WCD934X_REG(WCD934X_INTR_PIN1_STATUS2)] = WCD934X_READ, + [WCD934X_REG(WCD934X_INTR_PIN1_STATUS3)] = WCD934X_READ, + [WCD934X_REG(WCD934X_INTR_PIN1_CLEAR0)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_INTR_PIN1_CLEAR1)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_INTR_PIN1_CLEAR2)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_INTR_PIN1_CLEAR3)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_INTR_PIN2_MASK3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_PIN2_STATUS3)] = WCD934X_READ, + [WCD934X_REG(WCD934X_INTR_PIN2_CLEAR3)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_INTR_CPESS_SUMRY_MASK2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_CPESS_SUMRY_MASK3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_CPESS_SUMRY_STATUS2)] = WCD934X_READ, + [WCD934X_REG(WCD934X_INTR_CPESS_SUMRY_STATUS3)] = WCD934X_READ, + [WCD934X_REG(WCD934X_INTR_CPESS_SUMRY_CLEAR2)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_INTR_CPESS_SUMRY_CLEAR3)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_INTR_LEVEL0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_LEVEL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_LEVEL2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_LEVEL3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_BYPASS0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_BYPASS1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_BYPASS2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_BYPASS3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_SET0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_SET1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_SET2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_SET3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_CODEC_MISC_MASK)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_INTR_CODEC_MISC_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_INTR_CODEC_MISC_CLEAR)] = WCD934X_WRITE, +}; + +const u8 wcd934x_page5_reg_access[WCD934X_PAGE_SIZE] = { + [WCD934X_REG(WCD934X_PAGE5_PAGE_REGISTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_DEVICE)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SLNQ_DIG_REVISION)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SLNQ_DIG_H_COMMAND)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_NUMBER_OF_BYTE_MSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_NUMBER_OF_BYTE_LSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_MASTER_ADDRESS_MSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_MASTER_ADDRESS_LSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SLAVE_ADDRESS_MSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SLAVE_ADDRESS_LSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_TIMER0_INTERRUPT_MSB)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_TIMER0_INTERRUPT_LSB)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_TIMER1_INTERRUPT_MSB)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_TIMER1_INTERRUPT_LSB)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_TIMER2_INTERRUPT_MSB)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_TIMER2_INTERRUPT_LSB)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_COMM_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_FRAME_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_PDM_2ND_DATA_CH1_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_PDM_2ND_DATA_CH3_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_PDM_2ND_DATA_CH5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SW_EVENT_RD)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SLNQ_DIG_SW_EVENT_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_PDM_SELECT_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_PDM_SELECT_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_PDM_SELECT_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_PDM_SAMPLING_FREQ)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_PDM_DC_CONVERSION_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_PDM_DC_CONVERSION_SEL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_PDM_DC_CONV_CHA_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SLNQ_DIG_PDM_DC_CONV_CHA_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SLNQ_DIG_PDM_DC_CONV_CHB_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SLNQ_DIG_PDM_DC_CONV_CHB_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SLNQ_DIG_RAM_CNTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BANK)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_8)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_9)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_A)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_B)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_C)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_D)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_E)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_F)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_10)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_11)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_12)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_13)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_14)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_15)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_16)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_17)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_18)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_19)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_1A)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_1B)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_1C)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_1D)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_1E)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_1F)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_20)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_21)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_22)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_23)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_24)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_25)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_26)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_27)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_28)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_29)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_2A)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_2B)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_2C)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_2D)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_2E)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_2F)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_30)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_31)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_32)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_33)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_34)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_35)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_36)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_37)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_38)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_39)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_3A)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_3B)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_3C)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_3D)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_3E)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_SRAM_BYTE_3F)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_TOP_CTRL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_TOP_CTRL2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_PDM_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_PDM_MUTE_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_DEC_BYPASS_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_DEC_BYPASS_STATUS)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_DEC_BYPASS_FS)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_DEC_BYPASS_IN_SEL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_GPOUT_ENABLE)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_GPOUT_VAL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_ANA_INTERRUPT_MASK)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_ANA_INTERRUPT_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SLNQ_DIG_ANA_INTERRUPT_CLR)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_IP_TESTING)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_CNTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_CNT)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_CNT_MSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_CNT_LSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_MASK0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_MASK1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_MASK2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_MASK3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_MASK4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_STATUS0)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_STATUS1)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_STATUS2)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_STATUS3)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_STATUS4)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_CLR0)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_CLR1)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_CLR2)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_CLR3)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_SLNQ_DIG_INTERRUPT_CLR4)] = WCD934X_WRITE, +}; + +const u8 wcd934x_page6_reg_access[WCD934X_PAGE_SIZE] = { + [WCD934X_REG(WCD934X_ANA_PAGE_REGISTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_BIAS)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_RCO)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_PAGE6_SPARE2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_PAGE6_SPARE3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_BUCK_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_BUCK_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_ANA_RX_SUPPLIES)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_HPH)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_EAR)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_LO_1_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MAD_SETUP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_AMIC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_AMIC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_AMIC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_AMIC4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MBHC_MECH)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MBHC_ELECT)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MBHC_ZDET)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MBHC_RESULT_1)] = WCD934X_READ, + [WCD934X_REG(WCD934X_ANA_MBHC_RESULT_2)] = WCD934X_READ, + [WCD934X_REG(WCD934X_ANA_MBHC_RESULT_3)] = WCD934X_READ, + [WCD934X_REG(WCD934X_ANA_MBHC_BTN0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MBHC_BTN1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MBHC_BTN2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MBHC_BTN3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MBHC_BTN4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MBHC_BTN5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MBHC_BTN6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MBHC_BTN7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MICB1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MICB2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MICB2_RAMP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MICB3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_MICB4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_ANA_VBADC)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_BIAS_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_BIAS_VBG_FINE_ADJ)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RCO_CTRL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RCO_CTRL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RCO_CAL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RCO_CAL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RCO_CAL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RCO_TEST_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RCO_CAL_OUT_1)] = WCD934X_READ, + [WCD934X_REG(WCD934X_RCO_CAL_OUT_2)] = WCD934X_READ, + [WCD934X_REG(WCD934X_RCO_CAL_OUT_3)] = WCD934X_READ, + [WCD934X_REG(WCD934X_RCO_CAL_OUT_4)] = WCD934X_READ, + [WCD934X_REG(WCD934X_RCO_CAL_OUT_5)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SIDO_MODE_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_MODE_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_MODE_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_MODE_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_VCL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_VCL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_VCL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_CCL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_CCL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_CCL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_CCL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_CCL_5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_CCL_6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_CCL_7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_CCL_8)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_CCL_9)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_CCL_10)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_FILTER_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_FILTER_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_DRIVER_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_DRIVER_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_DRIVER_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_CAL_CODE_EXT_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_CAL_CODE_EXT_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_CAL_CODE_OUT_1)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SIDO_CAL_CODE_OUT_2)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SIDO_TEST_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_TEST_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_CTL_CLK)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_CTL_ANA)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_CTL_SPARE_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_CTL_SPARE_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_CTL_BCS)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_STATUS_SPARE_1)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MBHC_TEST_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_VBADC_SUBBLOCK_EN)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_VBADC_IBIAS_FE)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_VBADC_BIAS_ADC)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_VBADC_FE_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_VBADC_ADC_REF)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_VBADC_ADC_IO)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_VBADC_ADC_SAR)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_VBADC_DEBUG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_LDOH_MODE)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_LDOH_BIAS)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_LDOH_STB_LOADS)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_LDOH_SLOWRAMP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MICB1_TEST_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MICB1_TEST_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MICB1_TEST_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MICB2_TEST_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MICB2_TEST_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MICB2_TEST_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MICB3_TEST_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MICB3_TEST_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MICB3_TEST_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MICB4_TEST_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MICB4_TEST_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MICB4_TEST_CTL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_COM_ADC_VCM)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_COM_BIAS_ATEST)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_COM_ADC_INT1_IB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_COM_ADC_INT2_IB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_COM_TXFE_DIV_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_COM_TXFE_DIV_START)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_COM_TXFE_DIV_STOP_9P6M)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_COM_TXFE_DIV_STOP_12P288M)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_1_2_TEST_EN)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_1_2_ADC_IB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_1_2_ATEST_REFCTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_1_2_TEST_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_1_2_TEST_BLK_EN)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_1_2_TXFE_CLKDIV)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_1_2_SAR1_ERR)] = WCD934X_READ, + [WCD934X_REG(WCD934X_TX_1_2_SAR2_ERR)] = WCD934X_READ, + [WCD934X_REG(WCD934X_TX_3_4_TEST_EN)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_3_4_ADC_IB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_3_4_ATEST_REFCTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_3_4_TEST_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_3_4_TEST_BLK_EN)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_3_4_TXFE_CLKDIV)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TX_3_4_SAR1_ERR)] = WCD934X_READ, + [WCD934X_REG(WCD934X_TX_3_4_SAR2_ERR)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CLASSH_MODE_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLASSH_MODE_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLASSH_MODE_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLASSH_CTRL_VCL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLASSH_CTRL_VCL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLASSH_CTRL_CCL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLASSH_CTRL_CCL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLASSH_CTRL_CCL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLASSH_CTRL_CCL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLASSH_CTRL_CCL_5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLASSH_BUCK_TMUX_A_D)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLASSH_BUCK_SW_DRV_CNTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLASSH_SPARE)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_FLYBACK_EN)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_FLYBACK_VNEG_CTRL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_FLYBACK_VNEG_CTRL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_FLYBACK_VNEG_CTRL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_FLYBACK_VNEG_CTRL_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_FLYBACK_VNEG_CTRL_5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_FLYBACK_VNEG_CTRL_6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_FLYBACK_VNEG_CTRL_7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_FLYBACK_VNEG_CTRL_8)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_FLYBACK_VNEG_CTRL_9)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_FLYBACK_VNEGDAC_CTRL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_FLYBACK_VNEGDAC_CTRL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_FLYBACK_VNEGDAC_CTRL_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_FLYBACK_CTRL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_FLYBACK_TEST_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_AUX_SW_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_PA_AUX_IN_CONN)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_TIMER_DIV)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_OCP_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_OCP_COUNT)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_EAR_DAC)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_EAR_AMP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_HPH_LDO)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_HPH_PA)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_HPH_RDACBUFF_CNP2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_HPH_RDAC_LDO)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_HPH_CNP1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_HPH_LOWPOWER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_DIFFLO_PA)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_DIFFLO_REF)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_DIFFLO_LDO)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_SELO_DAC_PA)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_BUCK_RST)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_BUCK_VREF_ERRAMP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_FLYB_ERRAMP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_FLYB_BUFF)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_BIAS_FLYB_MID_RST)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_L_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_HPH_R_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_HPH_CNP_EN)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_CNP_WG_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_CNP_WG_TIME)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_OCP_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_AUTO_CHOP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_CHOP_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_PA_CTL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_PA_CTL2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_L_EN)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_L_TEST)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_L_ATEST)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_R_EN)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_R_TEST)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_R_ATEST)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_RDAC_CLK_CTL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_RDAC_CLK_CTL2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_RDAC_LDO_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_RDAC_CHOP_CLK_LP_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_REFBUFF_UHQA_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_REFBUFF_LP_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_L_DAC_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_R_DAC_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EAR_EN_REG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EAR_CMBUFF)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EAR_ICTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EAR_EN_DBG_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EAR_CNP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EAR_DAC_CTL_ATEST)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EAR_STATUS_REG)] = WCD934X_READ, + [WCD934X_REG(WCD934X_EAR_EAR_MISC)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DIFF_LO_MISC)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DIFF_LO_LO2_COMPANDER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DIFF_LO_LO1_COMPANDER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DIFF_LO_COMMON)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DIFF_LO_BYPASS_EN)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DIFF_LO_CNP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DIFF_LO_CORE_OUT_PROG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DIFF_LO_LDO_OUT_PROG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DIFF_LO_COM_SWCAP_REFBUF_FREQ)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DIFF_LO_COM_PA_FREQ)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DIFF_LO_RESERVED_REG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_DIFF_LO_LO1_STATUS_1)] = WCD934X_READ, + [WCD934X_REG(WCD934X_DIFF_LO_LO1_STATUS_2)] = WCD934X_READ, +}; + +const u8 wcd934x_page7_reg_access[WCD934X_PAGE_SIZE] = { + [WCD934X_REG(WCD934X_ANA_NEW_PAGE_REGISTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_NEW_ANA_HPH2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_NEW_ANA_HPH3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_ANA_EN)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_ANA_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SLNQ_ANA_LDO_CONFIG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_ANA_LDO_OCP_CONFIG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_ANA_TX_LDO_CONFIG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_ANA_TX_DRV_CONFIG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_ANA_RX_CONFIG_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_ANA_RX_CONFIG_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_ANA_PLL_ENABLES)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_ANA_PLL_PRESET)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_ANA_PLL_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CLK_SYS_PLL_ENABLES)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_PLL_PRESET)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_PLL_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CLK_SYS_MCLK_PRG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_MCLK2_PRG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_MCLK2_PRG2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_XO_PRG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_XO_CAP_XTP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_XO_CAP_XTM)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_BOOST_BST_EN_DLY)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_BOOST_CTRL_ILIM)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_BOOST_VOUT_SETTING)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_VOUT_A_STARTUP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_VOUT_D_STARTUP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_VOUT_D_FREQ1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_VOUT_D_FREQ2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_NEW_ELECT_REM_CLAMP_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_NEW_CTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_NEW_CTL_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_NEW_PLUG_DETECT_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_NEW_ZDET_ANA_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_NEW_ZDET_RAMP_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_NEW_FSM_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MBHC_NEW_ADC_RESULT)] = WCD934X_READ, + [WCD934X_REG(WCD934X_TX_NEW_AMIC_4_5_SEL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_VBADC_NEW_ADC_MODE)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_VBADC_NEW_ADC_DOUTMSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_VBADC_NEW_ADC_DOUTLSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_NEW_INT_RDAC_HD2_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_NEW_INT_RDAC_VREF_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_NEW_INT_RDAC_OVERRIDE_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_NEW_INT_RDAC_MISC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_NEW_INT_PA_MISC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_NEW_INT_PA_MISC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_NEW_INT_PA_RDAC_MISC)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_NEW_INT_HPH_TIMER1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_NEW_INT_HPH_TIMER2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_NEW_INT_HPH_TIMER3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_NEW_INT_HPH_TIMER4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_NEW_INT_PA_RDAC_MISC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_HPH_NEW_INT_PA_RDAC_MISC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_NEW_INT_HPH_RDAC_BIAS_ULP)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_RX_NEW_INT_HPH_RDAC_LDO_LP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_LDO_TEST)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_LDO_DEBUG_1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_LDO_DEBUG_2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_TX_LDO_TEST)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_TX_DRV_TEST)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_RX_TEST)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_RX_TEST_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_RX_DEBUG_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_RX_DEBUG_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_CLK_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_RESERVED_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_RESERVED_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_PLL_POST_DIV_REG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_PLL_POST_DIV_REG1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_PLL_REF_DIV_REG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_PLL_REF_DIV_REG1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_PLL_FILTER_REG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_PLL_FILTER_REG1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_PLL_L_VAL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_PLL_M_VAL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_PLL_N_VAL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_PLL_TEST_REG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_PLL_PFD_CP_DSM_PROG)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_PLL_VCO_PROG)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_PLL_TEST_REG1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_PLL_LDO_LOCK_CFG)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SLNQ_INT_ANA_INT_PLL_DIG_LOCK_DET_CFG)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_POST_DIV_REG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_POST_DIV_REG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_REF_DIV_REG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_REF_DIV_REG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_FILTER_REG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_FILTER_REG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_PLL_L_VAL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_PLL_M_VAL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_PLL_N_VAL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_TEST_REG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_PFD_CP_DSM_PROG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_VCO_PROG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_TEST_REG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_LDO_LOCK_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_DIG_LOCK_DET_CFG)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_CLK_TEST1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_CLK_TEST2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_CLK_TEST3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_XO_TEST1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CLK_SYS_INT_XO_TEST2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_BOOST_INT_VCOMP_HYST)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_BOOST_INT_VLOOP_FILTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_BOOST_INT_CTRL_IDELTA)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_BOOST_INT_CTRL_ILIM_STARTUP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_BOOST_INT_CTRL_MIN_ONTIME)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_BOOST_INT_CTRL_MAX_ONTIME)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_BOOST_INT_CTRL_TIMING)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_BOOST_INT_TMUX_A_D)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_BOOST_INT_SW_DRV_CNTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_BOOST_INT_SPARE1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_BOOST_INT_SPARE2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_INT_RAMP_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SIDO_NEW_INT_SPARE_1)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SIDO_NEW_INT_DEBUG_VOUT_SETTING_A)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_INT_DEBUG_VOUT_SETTING_D)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_INT_RAMP_INC_WAIT)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_INT_DYNAMIC_IPEAK_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_INT_RAMP_IBLEED_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_INT_DEBUG_CPROVR_TEST)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_INT_RAMP_CTL_A)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_INT_RAMP_CTL_D)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_INT_RAMP_TIMEOUT_PERIOD)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_NEW_INT_SLNQ_HPF)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_NEW_INT_SLNQ_REF)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_NEW_INT_SLNQ_COMP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MBHC_NEW_INT_SPARE_2)] = WCD934X_READ_WRITE, + +}; + +const u8 wcd934x_page10_reg_access[WCD934X_PAGE_SIZE] = { + [WCD934X_REG(WCD934X_PAGE10_PAGE_REGISTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_CLK_RESET_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_MODE_1_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_MODE_2_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_FF_SHIFT)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_FB_SHIFT)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_LPF_FF_A_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_LPF_FF_B_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_LPF_FB_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_SMLPF_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_DCFLT_SHIFT_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_IIR_ADAPT_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_IIR_COEFF_1_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_IIR_COEFF_2_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_FF_A_GAIN_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_FF_B_GAIN_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_FB_GAIN_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_RC_COMMON_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_FIFO_COMMON_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC0_RC0_STATUS_FMIN_CNTR)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_ANC0_RC1_STATUS_FMIN_CNTR)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_ANC0_RC0_STATUS_FMAX_CNTR)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_ANC0_RC1_STATUS_FMAX_CNTR)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_ANC0_STATUS_FIFO)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_ANC1_CLK_RESET_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_MODE_1_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_MODE_2_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_FF_SHIFT)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_FB_SHIFT)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_LPF_FF_A_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_LPF_FF_B_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_LPF_FB_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_SMLPF_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_DCFLT_SHIFT_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_IIR_ADAPT_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_IIR_COEFF_1_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_IIR_COEFF_2_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_FF_A_GAIN_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_FF_B_GAIN_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_FB_GAIN_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_RC_COMMON_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_FIFO_COMMON_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_ANC1_RC0_STATUS_FMIN_CNTR)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_ANC1_RC1_STATUS_FMIN_CNTR)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_ANC1_RC0_STATUS_FMAX_CNTR)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_ANC1_RC1_STATUS_FMAX_CNTR)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_ANC1_STATUS_FIFO)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_TX0_TX_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX0_TX_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX0_TX_PATH_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX0_TX_VOL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX0_TX_PATH_192_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX0_TX_PATH_192_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX0_TX_PATH_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX0_TX_PATH_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX0_TX_PATH_SEC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX0_TX_PATH_SEC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX0_TX_PATH_SEC4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX0_TX_PATH_SEC5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX0_TX_PATH_SEC6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX0_TX_PATH_SEC7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX1_TX_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX1_TX_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX1_TX_PATH_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX1_TX_VOL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX1_TX_PATH_192_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX1_TX_PATH_192_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX1_TX_PATH_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX1_TX_PATH_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX1_TX_PATH_SEC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX1_TX_PATH_SEC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX1_TX_PATH_SEC4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX1_TX_PATH_SEC5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX1_TX_PATH_SEC6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX2_TX_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX2_TX_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX2_TX_PATH_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX2_TX_VOL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX2_TX_PATH_192_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX2_TX_PATH_192_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX2_TX_PATH_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX2_TX_PATH_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX2_TX_PATH_SEC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX2_TX_PATH_SEC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX2_TX_PATH_SEC4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX2_TX_PATH_SEC5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX2_TX_PATH_SEC6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX3_TX_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX3_TX_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX3_TX_PATH_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX3_TX_VOL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX3_TX_PATH_192_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX3_TX_PATH_192_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX3_TX_PATH_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX3_TX_PATH_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX3_TX_PATH_SEC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX3_TX_PATH_SEC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX3_TX_PATH_SEC4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX3_TX_PATH_SEC5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX3_TX_PATH_SEC6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX4_TX_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX4_TX_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX4_TX_PATH_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX4_TX_VOL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX4_TX_PATH_192_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX4_TX_PATH_192_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX4_TX_PATH_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX4_TX_PATH_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX4_TX_PATH_SEC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX4_TX_PATH_SEC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX4_TX_PATH_SEC4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX4_TX_PATH_SEC5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX4_TX_PATH_SEC6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX5_TX_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX5_TX_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX5_TX_PATH_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX5_TX_VOL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX5_TX_PATH_192_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX5_TX_PATH_192_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX5_TX_PATH_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX5_TX_PATH_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX5_TX_PATH_SEC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX5_TX_PATH_SEC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX5_TX_PATH_SEC4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX5_TX_PATH_SEC5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX5_TX_PATH_SEC6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX6_TX_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX6_TX_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX6_TX_PATH_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX6_TX_VOL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX6_TX_PATH_192_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX6_TX_PATH_192_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX6_TX_PATH_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX6_TX_PATH_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX6_TX_PATH_SEC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX6_TX_PATH_SEC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX6_TX_PATH_SEC4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX6_TX_PATH_SEC5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX6_TX_PATH_SEC6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX7_TX_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX7_TX_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX7_TX_PATH_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX7_TX_VOL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX7_TX_PATH_192_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX7_TX_PATH_192_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX7_TX_PATH_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX7_TX_PATH_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX7_TX_PATH_SEC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX7_TX_PATH_SEC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX7_TX_PATH_SEC4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX7_TX_PATH_SEC5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX7_TX_PATH_SEC6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX8_TX_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX8_TX_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX8_TX_PATH_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX8_TX_VOL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX8_TX_PATH_192_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX8_TX_PATH_192_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX8_TX_PATH_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX8_TX_PATH_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX8_TX_PATH_SEC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX8_TX_PATH_SEC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX8_TX_PATH_SEC4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX8_TX_PATH_SEC5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX8_TX_PATH_SEC6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX9_SPKR_PROT_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX9_SPKR_PROT_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX10_SPKR_PROT_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX10_SPKR_PROT_PATH_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX11_SPKR_PROT_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX11_SPKR_PROT_PATH_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX12_SPKR_PROT_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX12_SPKR_PROT_PATH_CFG0)] = + WCD934X_READ_WRITE, +}; + +const u8 wcd934x_page11_reg_access[WCD934X_PAGE_SIZE] = { + [WCD934X_REG(WCD934X_PAGE11_PAGE_REGISTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER1_CTL0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER1_CTL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER1_CTL2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER1_CTL3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER1_CTL4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER1_CTL5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER1_CTL6)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_COMPANDER1_CTL7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER2_CTL0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER2_CTL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER2_CTL2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER2_CTL3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER2_CTL4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER2_CTL5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER2_CTL6)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_COMPANDER2_CTL7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER3_CTL0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER3_CTL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER3_CTL2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER3_CTL3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER3_CTL4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER3_CTL5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER3_CTL6)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_COMPANDER3_CTL7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER4_CTL0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER4_CTL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER4_CTL2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER4_CTL3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER4_CTL4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER4_CTL5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER4_CTL6)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_COMPANDER4_CTL7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER7_CTL0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER7_CTL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER7_CTL2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER7_CTL3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER7_CTL4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER7_CTL5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER7_CTL6)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_COMPANDER7_CTL7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER8_CTL0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER8_CTL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER8_CTL2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER8_CTL3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER8_CTL4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER8_CTL5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_COMPANDER8_CTL6)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_COMPANDER8_CTL7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_PATH_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_PATH_CFG2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_VOL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_PATH_MIX_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_PATH_MIX_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_VOL_MIX_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_PATH_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_PATH_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_PATH_SEC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_PATH_SEC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_PATH_SEC5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_PATH_SEC6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_PATH_SEC7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_PATH_MIX_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_PATH_MIX_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX0_RX_PATH_DSMDEM_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_CFG2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_VOL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_MIX_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_MIX_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_VOL_MIX_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_SEC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_SEC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_SEC4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_SEC5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_SEC6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_SEC7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_MIX_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_MIX_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX1_RX_PATH_DSMDEM_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_CFG2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_VOL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_MIX_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_MIX_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_VOL_MIX_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_SEC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_SEC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_SEC4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_SEC5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_SEC6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_SEC7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_MIX_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_MIX_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX2_RX_PATH_DSMDEM_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_PATH_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_PATH_CFG2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_VOL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_PATH_MIX_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_PATH_MIX_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_VOL_MIX_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_PATH_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_PATH_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_PATH_SEC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_PATH_SEC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_PATH_SEC5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_PATH_SEC6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_PATH_SEC7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_PATH_MIX_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_PATH_MIX_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX3_RX_PATH_DSMDEM_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_PATH_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_PATH_CFG2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_VOL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_PATH_MIX_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_PATH_MIX_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_VOL_MIX_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_PATH_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_PATH_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_PATH_SEC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_PATH_SEC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_PATH_SEC5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_PATH_SEC6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_PATH_SEC7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_PATH_MIX_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_PATH_MIX_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX4_RX_PATH_DSMDEM_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_PATH_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_PATH_CFG2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_VOL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_PATH_MIX_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_PATH_MIX_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_VOL_MIX_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_PATH_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_PATH_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_PATH_SEC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_PATH_SEC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_PATH_SEC5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_PATH_SEC6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_PATH_SEC7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_PATH_MIX_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_PATH_MIX_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX7_RX_PATH_DSMDEM_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_PATH_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_PATH_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_PATH_CFG2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_VOL_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_PATH_MIX_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_PATH_MIX_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_VOL_MIX_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_PATH_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_PATH_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_PATH_SEC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_PATH_SEC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_PATH_SEC5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_PATH_SEC6)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_PATH_SEC7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_PATH_MIX_SEC0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_PATH_MIX_SEC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX8_RX_PATH_DSMDEM_CTL)] = WCD934X_READ_WRITE, +}; + +const u8 wcd934x_page12_reg_access[WCD934X_PAGE_SIZE] = { + [WCD934X_REG(WCD934X_PAGE12_PAGE_REGISTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_CRC)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_DLY_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_DECAY_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_HPH_V_PA)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_EAR_V_PA)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_HPH_V_HD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_EAR_V_HD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_K1_MSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_K1_LSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_K2_MSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_K2_LSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_IDLE_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_IDLE_HPH)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_IDLE_EAR)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_TEST0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_TEST1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLSH_OVR_VREF)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_BOOST0_BOOST_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_BOOST0_BOOST_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_BOOST0_BOOST_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_BOOST0_BOOST_CFG2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_BOOST1_BOOST_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_BOOST1_BOOST_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_BOOST1_BOOST_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_BOOST1_BOOST_CFG2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_ADC_CAL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_ADC_CAL2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_ADC_CAL3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_PK_EST1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_PK_EST2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_PK_EST3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_RF_PROC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_RF_PROC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_TAC1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_TAC2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_TAC3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_TAC4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_GAIN_UPD1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_GAIN_UPD2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_GAIN_UPD3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_GAIN_UPD4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_DEBUG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_GAIN_UPD_MON)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_GAIN_MON_VAL)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_VBAT_VBAT_BAN)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC0_CLK_RST_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC0_CTL0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC0_CTL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC0_FIFO_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC0_STATUS_FMIN_CNTR_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC0_STATUS_FMIN_CNTR_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC0_STATUS_FMAX_CNTR_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC0_STATUS_FMAX_CNTR_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC0_STATUS_FIFO)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC1_CLK_RST_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC1_CTL0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC1_CTL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC1_FIFO_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC1_STATUS_FMIN_CNTR_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC1_STATUS_FMIN_CNTR_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC1_STATUS_FMAX_CNTR_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC1_STATUS_FMAX_CNTR_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC1_STATUS_FIFO)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC2_CLK_RST_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC2_CTL0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC2_CTL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC2_FIFO_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC2_STATUS_FMIN_CNTR_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC2_STATUS_FMIN_CNTR_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC2_STATUS_FMAX_CNTR_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC2_STATUS_FMAX_CNTR_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC2_STATUS_FIFO)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC3_CLK_RST_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC3_CTL0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC3_CTL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC3_FIFO_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_MIXING_ASRC3_STATUS_FMIN_CNTR_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC3_STATUS_FMIN_CNTR_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC3_STATUS_FMAX_CNTR_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC3_STATUS_FMAX_CNTR_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_MIXING_ASRC3_STATUS_FIFO)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_WR_DATA_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_WR_DATA_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_WR_DATA_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_WR_DATA_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_WR_ADDR_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_WR_ADDR_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_WR_ADDR_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_WR_ADDR_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_RD_ADDR_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_RD_ADDR_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_RD_ADDR_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_RD_ADDR_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_RD_DATA_0)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_RD_DATA_1)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_RD_DATA_2)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_RD_DATA_3)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_ACCESS_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SWR_AHB_BRIDGE_ACCESS_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_SRC1_ST_SRC_PATH_CFG1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDETONE_ASRC0_CLK_RST_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDETONE_ASRC0_CTL0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDETONE_ASRC0_CTL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDETONE_ASRC0_FIFO_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB)] = + WCD934X_READ, + [WCD934X_REG(WCD934X_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB)] = + WCD934X_READ, + [WCD934X_REG(WCD934X_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB)] = + WCD934X_READ, + [WCD934X_REG(WCD934X_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB)] = + WCD934X_READ, + [WCD934X_REG(WCD934X_SIDETONE_ASRC0_STATUS_FIFO)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SIDETONE_ASRC1_CLK_RST_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDETONE_ASRC1_CTL0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDETONE_ASRC1_CTL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDETONE_ASRC1_FIFO_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SIDETONE_ASRC1_STATUS_FMIN_CNTR_LSB)] = + WCD934X_READ, + [WCD934X_REG(WCD934X_SIDETONE_ASRC1_STATUS_FMIN_CNTR_MSB)] = + WCD934X_READ, + [WCD934X_REG(WCD934X_SIDETONE_ASRC1_STATUS_FMAX_CNTR_LSB)] = + WCD934X_READ, + [WCD934X_REG(WCD934X_SIDETONE_ASRC1_STATUS_FMAX_CNTR_MSB)] = + WCD934X_READ, + [WCD934X_REG(WCD934X_SIDETONE_ASRC1_STATUS_FIFO)] = WCD934X_READ, + [WCD934X_REG(WCD934X_EC_REF_HQ0_EC_REF_HQ_PATH_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EC_REF_HQ0_EC_REF_HQ_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EC_REF_HQ1_EC_REF_HQ_PATH_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EC_REF_HQ1_EC_REF_HQ_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EC_ASRC0_CLK_RST_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EC_ASRC0_CTL0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EC_ASRC0_CTL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EC_ASRC0_FIFO_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EC_ASRC0_STATUS_FMIN_CNTR_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_EC_ASRC0_STATUS_FMIN_CNTR_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_EC_ASRC0_STATUS_FMAX_CNTR_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_EC_ASRC0_STATUS_FMAX_CNTR_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_EC_ASRC0_STATUS_FIFO)] = WCD934X_READ, + [WCD934X_REG(WCD934X_EC_ASRC1_CLK_RST_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EC_ASRC1_CTL0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EC_ASRC1_CTL1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EC_ASRC1_FIFO_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_EC_ASRC1_STATUS_FMIN_CNTR_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_EC_ASRC1_STATUS_FMIN_CNTR_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_EC_ASRC1_STATUS_FMAX_CNTR_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_EC_ASRC1_STATUS_FMAX_CNTR_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_EC_ASRC1_STATUS_FIFO)] = WCD934X_READ, +}; + +const u8 wcd934x_page13_reg_access[WCD934X_PAGE_SIZE] = { + [WCD934X_REG(WCD934X_PAGE13_PAGE_REGISTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_ANC_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_INP_MUX_EC_REF_HQ_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX5_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX6_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX7_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX8_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX10_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX11_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX12_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TX_INP_MUX_ADC_MUX13_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLK_RST_CTRL_MCLK_CONTROL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLK_RST_CTRL_FS_CNT_CONTROL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLK_RST_CTRL_DSD_CONTROL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_CLK_RST_CTRL_GFM_CONTROL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_PROX_DETECT_PROX_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_PROX_DETECT_PROX_POLL_PERIOD0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_PROX_DETECT_PROX_POLL_PERIOD1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_PROX_DETECT_PROX_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_PROX_DETECT_PROX_TEST_CTRL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD)] = + WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD)] = + WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR0_IIR_PATH_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR0_IIR_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR1_IIR_PATH_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B5_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B6_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B7_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B8_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR1_IIR_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR1_IIR_COEF_B1_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_SIDETONE_IIR1_IIR_COEF_B2_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TOP_TOP_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TOP_TOP_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TOP_TOP_CFG7)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TOP_HPHL_COMP_WR_LSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TOP_HPHL_COMP_WR_MSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TOP_HPHL_COMP_LUT)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TOP_HPHL_COMP_RD_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_TOP_HPHL_COMP_RD_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_TOP_HPHR_COMP_WR_LSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TOP_HPHR_COMP_WR_MSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TOP_HPHR_COMP_LUT)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TOP_HPHR_COMP_RD_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_TOP_HPHR_COMP_RD_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_TOP_DIFFL_COMP_WR_LSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TOP_DIFFL_COMP_WR_MSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TOP_DIFFL_COMP_LUT)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TOP_DIFFL_COMP_RD_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_TOP_DIFFL_COMP_RD_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_TOP_DIFFR_COMP_WR_LSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TOP_DIFFR_COMP_WR_MSB)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TOP_DIFFR_COMP_LUT)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_TOP_DIFFR_COMP_RD_LSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_TOP_DIFFR_COMP_RD_MSB)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_DSD0_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DSD0_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DSD0_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DSD0_CFG2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DSD0_CFG3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DSD0_CFG4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DSD0_CFG5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DSD1_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DSD1_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DSD1_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DSD1_CFG2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DSD1_CFG3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DSD1_CFG4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DSD1_CFG5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_IDLE_DET_PATH_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_IDLE_DET_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_IDLE_DET_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_IDLE_DET_CFG2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RX_IDLE_DET_CFG3)] = WCD934X_READ_WRITE, +}; + +const u8 wcd934x_page14_reg_access[WCD934X_PAGE_SIZE] = { + [WCD934X_REG(WCD934X_PAGE14_PAGE_REGISTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_CLK_RST_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_PULSE_SUPR_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_TIMER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_BW_SW)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_THRESH)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_TIMER2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_RMAX_DIAG)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_RMIN_DIAG)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_PH_DET)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_DIAG_CLR)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_MB_SW_STATE)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_MAST_DIAG_STATE)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_RATE_OUT_7_0)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_RATE_OUT_15_8)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_RATE_OUT_23_16)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_RATE_OUT_31_24)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_RATE_OUT_39_32)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST0_RE_RATE_OUT_40_43)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_CLK_RST_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_PULSE_SUPR_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_TIMER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_BW_SW)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_THRESH)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_TIMER2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_RMAX_DIAG)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_RMIN_DIAG)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_PH_DET)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_DIAG_CLR)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_MB_SW_STATE)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_MAST_DIAG_STATE)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_RATE_OUT_7_0)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_RATE_OUT_15_8)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_RATE_OUT_23_16)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_RATE_OUT_31_24)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_RATE_OUT_39_32)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST1_RE_RATE_OUT_40_43)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_CLK_RST_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_PULSE_SUPR_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_TIMER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_BW_SW)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_THRESH)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_TIMER2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_RMAX_DIAG)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_RMIN_DIAG)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_PH_DET)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_DIAG_CLR)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_MB_SW_STATE)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_MAST_DIAG_STATE)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_RATE_OUT_7_0)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_RATE_OUT_15_8)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_RATE_OUT_23_16)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_RATE_OUT_31_24)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_RATE_OUT_39_32)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST2_RE_RATE_OUT_40_43)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_CLK_RST_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_PULSE_SUPR_CTL)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_TIMER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_BW_SW)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_THRESH)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_TIMER2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW5)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_RMAX_DIAG)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_RMIN_DIAG)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_PH_DET)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_DIAG_CLR)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_MB_SW_STATE)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_MAST_DIAG_STATE)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_RATE_OUT_7_0)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_RATE_OUT_15_8)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_RATE_OUT_23_16)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_RATE_OUT_31_24)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_RATE_OUT_39_32)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_RATE_EST3_RE_RATE_OUT_40_43)] = WCD934X_READ, +}; + +const u8 wcd934x_page15_reg_access[WCD934X_PAGE_SIZE] = { + [WCD934X_REG(WCD934X_PAGE15_PAGE_REGISTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SPLINE_SRC0_CLK_RST_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SPLINE_SRC0_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SPLINE_SRC1_CLK_RST_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SPLINE_SRC1_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SPLINE_SRC2_CLK_RST_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SPLINE_SRC2_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_SPLINE_SRC3_CLK_RST_CTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_SPLINE_SRC3_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG2)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG2)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DEBUG_SPLINE_SRC_DEBUG_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DEBUG_SPLINE_SRC_DEBUG_CFG1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DEBUG_RC_RE_ASRC_DEBUG_CFG0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DEBUG_ANC0_RC0_FIFO_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DEBUG_ANC0_RC1_FIFO_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DEBUG_ANC1_RC0_FIFO_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DEBUG_ANC1_RC1_FIFO_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CDC_DEBUG_ANC_RC_RST_DBG_CNTR)] = + WCD934X_READ_WRITE, +}; + +const u8 wcd934x_page_0x50_reg_access[WCD934X_PAGE_SIZE] = { + [WCD934X_REG(WCD934X_PAGE80_PAGE_REGISTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_WR_DATA_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_WR_DATA_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_WR_DATA_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_WR_DATA_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_WR_ADDR_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_WR_ADDR_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_WR_ADDR_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_WR_ADDR_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_RD_ADDR_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_RD_ADDR_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_RD_ADDR_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_RD_ADDR_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_RD_DATA_0)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CODEC_CPR_RD_DATA_1)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CODEC_CPR_RD_DATA_2)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CODEC_CPR_RD_DATA_3)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CODEC_CPR_ACCESS_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_ACCESS_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CODEC_CPR_NOM_CX_VDD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_SVS_CX_VDD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_SVS2_CX_VDD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_NOM_MX_VDD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_SVS_MX_VDD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_SVS2_MX_VDD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_SVS2_MIN_CX_VDD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_MAX_SVS2_STEP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_SW_MODECHNG_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CODEC_CPR_SW_MODECHNG_START)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_CPR_STATUS)] = WCD934X_READ_WRITE, +}; + +const u8 wcd934x_page_0x80_reg_access[WCD934X_PAGE_SIZE] = { + [WCD934X_REG(WCD934X_PAGE80_PAGE_REGISTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_WR_DATA_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_WR_DATA_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_WR_DATA_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_WR_DATA_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_WR_ADDR_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_WR_ADDR_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_WR_ADDR_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_WR_ADDR_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_RD_ADDR_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_RD_ADDR_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_RD_ADDR_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_RD_ADDR_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_RD_DATA_0)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CODEC_CPR_RD_DATA_1)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CODEC_CPR_RD_DATA_2)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CODEC_CPR_RD_DATA_3)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CODEC_CPR_ACCESS_CFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_ACCESS_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CODEC_CPR_NOM_CX_VDD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_SVS_CX_VDD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_SVS2_CX_VDD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_NOM_MX_VDD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_SVS_MX_VDD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_SVS2_MX_VDD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_SVS2_MIN_CX_VDD)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_MAX_SVS2_STEP)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_CTL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_SW_MODECHNG_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_CODEC_CPR_SW_MODECHNG_START)] = WCD934X_WRITE, + [WCD934X_REG(WCD934X_CODEC_CPR_CPR_STATUS)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_PAGE128_PAGE_REGISTER)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_BIST_MODE_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_RF_PA_ON_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_INTR1_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_INTR2_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_SWR_DATA_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_SWR_CLK_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_I2S_2_SCK_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_SLIMBUS_DATA1_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_SLIMBUS_DATA2_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_SLIMBUS_CLK_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_I2C_CLK_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_I2C_DATA_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_I2S_0_RX_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_I2S_0_TX_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_I2S_0_SCK_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_I2S_0_WS_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_I2S_1_RX_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_I2S_1_TX_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_I2S_1_SCK_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_I2S_1_WS_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_DMIC1_CLK_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_DMIC1_DATA_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_DMIC2_CLK_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_DMIC2_DATA_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_DMIC3_CLK_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_DMIC3_DATA_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_JTCK_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_GPIO1_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_GPIO2_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_GPIO3_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_GPIO4_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_SPI_S_CSN_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_SPI_S_CLK_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_SPI_S_DOUT_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_SPI_S_DIN_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_BA_N_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_GPIO0_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_I2S_2_RX_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TLMM_I2S_2_WS_PINCFG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PIN_CTL_OE_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PIN_CTL_OE_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PIN_CTL_OE_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PIN_CTL_OE_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PIN_CTL_OE_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PIN_CTL_DATA_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PIN_CTL_DATA_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PIN_CTL_DATA_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PIN_CTL_DATA_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PIN_CTL_DATA_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PAD_DRVCTL_0)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PAD_DRVCTL_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PIN_STATUS)] = WCD934X_READ, + [WCD934X_REG(WCD934X_TEST_DEBUG_NPL_DLY_TEST_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_NPL_DLY_TEST_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_MEM_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_DEBUG_BUS_SEL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_DEBUG_JTAG)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_DEBUG_EN_1)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_DEBUG_EN_2)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_DEBUG_EN_3)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_DEBUG_EN_4)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_DEBUG_EN_5)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_ANA_DTEST_DIR)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PAD_INP_DISABLE_0)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PAD_INP_DISABLE_1)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PAD_INP_DISABLE_2)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PAD_INP_DISABLE_3)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_PAD_INP_DISABLE_4)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_SYSMEM_CTRL)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_SOC_SW_PWR_SEQ_DELAY)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_LVAL_NOM_LOW)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_LVAL_NOM_HIGH)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_LVAL_SVS_SVS2_LOW)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_LVAL_SVS_SVS2_HIGH)] = + WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_SPI_SLAVE_CHAR)] = WCD934X_READ_WRITE, + [WCD934X_REG(WCD934X_TEST_DEBUG_CODEC_DIAGS)] = WCD934X_READ, +}; + +const u8 * const wcd934x_reg[WCD934X_NUM_PAGES] = { + [WCD934X_PAGE_0] = wcd934x_page0_reg_access, + [WCD934X_PAGE_1] = wcd934x_page1_reg_access, + [WCD934X_PAGE_2] = wcd934x_page2_reg_access, + [WCD934X_PAGE_4] = wcd934x_page4_reg_access, + [WCD934X_PAGE_5] = wcd934x_page5_reg_access, + [WCD934X_PAGE_6] = wcd934x_page6_reg_access, + [WCD934X_PAGE_7] = wcd934x_page7_reg_access, + [WCD934X_PAGE_10] = wcd934x_page10_reg_access, + [WCD934X_PAGE_11] = wcd934x_page11_reg_access, + [WCD934X_PAGE_12] = wcd934x_page12_reg_access, + [WCD934X_PAGE_13] = wcd934x_page13_reg_access, + [WCD934X_PAGE_14] = wcd934x_page14_reg_access, + [WCD934X_PAGE_15] = wcd934x_page15_reg_access, + [WCD934X_PAGE_0x50] = wcd934x_page_0x50_reg_access, + [WCD934X_PAGE_0X80] = wcd934x_page_0x80_reg_access, +}; diff --git a/drivers/mfd/wcd9xxx-core-init.c b/drivers/mfd/wcd9xxx-core-init.c new file mode 100644 index 000000000000..7f933990682d --- /dev/null +++ b/drivers/mfd/wcd9xxx-core-init.c @@ -0,0 +1,55 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + +#define NUM_DRIVERS_REG_RET 3 + +static int __init wcd9xxx_core_init(void) +{ + int ret[NUM_DRIVERS_REG_RET] = {0}; + int i = 0; + + ret[0] = msm_cdc_pinctrl_drv_init(); + if (ret[0]) + pr_err("%s: Failed init pinctrl drv: %d\n", __func__, ret[0]); + + ret[1] = wcd9xxx_irq_drv_init(); + if (ret[1]) + pr_err("%s: Failed init irq drv: %d\n", __func__, ret[1]); + + ret[2] = wcd9xxx_init(); + if (ret[2]) + pr_err("%s: Failed wcd core drv: %d\n", __func__, ret[2]); + + for (i = 0; i < NUM_DRIVERS_REG_RET; i++) { + if (ret[i]) + return ret[i]; + } + + return 0; +} +module_init(wcd9xxx_core_init); + +static void __exit wcd9xxx_core_exit(void) +{ + wcd9xxx_exit(); + wcd9xxx_irq_drv_exit(); + msm_cdc_pinctrl_drv_exit(); +} +module_exit(wcd9xxx_core_exit); + +MODULE_DESCRIPTION("WCD9XXX CODEC core init driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c new file mode 100644 index 000000000000..b373acb11005 --- /dev/null +++ b/drivers/mfd/wcd9xxx-core.c @@ -0,0 +1,1714 @@ +/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcd9xxx-regmap.h" + +#define WCD9XXX_REGISTER_START_OFFSET 0x800 +#define WCD9XXX_SLIM_RW_MAX_TRIES 3 +#define SLIMBUS_PRESENT_TIMEOUT 100 + +#define MAX_WCD9XXX_DEVICE 4 +#define WCD9XXX_I2C_GSBI_SLAVE_ID "3-000d" +#define WCD9XXX_I2C_TOP_SLAVE_ADDR 0x0d +#define WCD9XXX_ANALOG_I2C_SLAVE_ADDR 0x77 +#define WCD9XXX_DIGITAL1_I2C_SLAVE_ADDR 0x66 +#define WCD9XXX_DIGITAL2_I2C_SLAVE_ADDR 0x55 +#define WCD9XXX_I2C_TOP_LEVEL 0 +#define WCD9XXX_I2C_ANALOG 1 +#define WCD9XXX_I2C_DIGITAL_1 2 +#define WCD9XXX_I2C_DIGITAL_2 3 + +/* + * Number of return values needs to be checked for each + * registration of Slimbus of I2C bus for each codec + */ +#define NUM_WCD9XXX_REG_RET 4 + +#define SLIM_USR_MC_REPEAT_CHANGE_VALUE 0x0 +#define SLIM_REPEAT_WRITE_MAX_SLICE 16 +#define REG_BYTES 2 +#define VAL_BYTES 1 +#define WCD9XXX_PAGE_NUM(reg) (((reg) >> 8) & 0xff) +#define WCD9XXX_PAGE_SIZE 256 + +struct wcd9xxx_i2c { + struct i2c_client *client; + struct i2c_msg xfer_msg[2]; + struct mutex xfer_lock; + int mod_id; +}; + +static struct regmap_config wcd9xxx_base_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .can_multi_write = true, +}; + +static struct regmap_config wcd9xxx_i2c_base_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .can_multi_write = false, + .use_single_rw = true, +}; + +static u8 wcd9xxx_pgd_la; +static u8 wcd9xxx_inf_la; + +static const int wcd9xxx_cdc_types[] = { + [WCD9XXX] = WCD9XXX, + [WCD9330] = WCD9330, + [WCD9335] = WCD9335, + [WCD934X] = WCD934X, +}; + +static const struct of_device_id wcd9xxx_of_match[] = { + { .compatible = "qcom,tasha-i2c-pgd", + .data = (void *)&wcd9xxx_cdc_types[WCD9335]}, + { .compatible = "qcom,wcd9xxx-i2c", + .data = (void *)&wcd9xxx_cdc_types[WCD9330]}, + { } +}; +MODULE_DEVICE_TABLE(of, wcd9xxx_of_match); + +static int wcd9xxx_slim_device_up(struct slim_device *sldev); +static int wcd9xxx_slim_device_down(struct slim_device *sldev); + +struct wcd9xxx_i2c wcd9xxx_modules[MAX_WCD9XXX_DEVICE]; + +static int wcd9xxx_slim_multi_reg_write(struct wcd9xxx *wcd9xxx, + const void *data, size_t count) +{ + unsigned int reg; + struct device *dev; + u8 val[WCD9XXX_PAGE_SIZE]; + int ret = 0; + int i = 0; + int n = 0; + unsigned int page_num; + size_t num_regs = (count / (REG_BYTES + VAL_BYTES)); + struct wcd9xxx_reg_val *bulk_reg; + u8 *buf; + + dev = wcd9xxx->dev; + if (!data) { + dev_err(dev, "%s: data is NULL\n", __func__); + return -EINVAL; + } + if (num_regs == 0) + return -EINVAL; + + bulk_reg = kzalloc(num_regs * (sizeof(struct wcd9xxx_reg_val)), + GFP_KERNEL); + if (!bulk_reg) + return -ENOMEM; + + buf = (u8 *)data; + reg = *(u16 *)buf; + page_num = WCD9XXX_PAGE_NUM(reg); + for (i = 0, n = 0; n < num_regs; i++, n++) { + reg = *(u16 *)buf; + if (page_num != WCD9XXX_PAGE_NUM(reg)) { + ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, + i, false); + page_num = WCD9XXX_PAGE_NUM(reg); + i = 0; + } + buf += REG_BYTES; + val[i] = *buf; + buf += VAL_BYTES; + bulk_reg[i].reg = reg; + bulk_reg[i].buf = &val[i]; + bulk_reg[i].bytes = 1; + } + ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, + i, false); + if (ret) + dev_err(dev, "%s: error writing bulk regs\n", + __func__); + + kfree(bulk_reg); + return ret; +} + +/* + * wcd9xxx_interface_reg_read: Read slim interface registers + * + * @wcd9xxx: Pointer to wcd9xxx structure + * @reg: register adderss + * + * Returns register value in success and negative error code in case of failure + */ +int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg) +{ + u8 val; + int ret; + + mutex_lock(&wcd9xxx->io_lock); + ret = wcd9xxx->read_dev(wcd9xxx, reg, 1, (void *)&val, + true); + if (ret < 0) + dev_err(wcd9xxx->dev, "%s: Codec read 0x%x failed\n", + __func__, reg); + else + dev_dbg(wcd9xxx->dev, "%s: Read 0x%02x from 0x%x\n", + __func__, val, reg); + + mutex_unlock(&wcd9xxx->io_lock); + + if (ret < 0) + return ret; + else + return val; +} +EXPORT_SYMBOL(wcd9xxx_interface_reg_read); + +/* + * wcd9xxx_interface_reg_write: Write slim interface registers + * + * @wcd9xxx: Pointer to wcd9xxx structure + * @reg: register adderss + * @val: value of the register to be written + * + * Returns 0 for success and negative error code in case of failure + */ +int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg, + u8 val) +{ + int ret; + + mutex_lock(&wcd9xxx->io_lock); + ret = wcd9xxx->write_dev(wcd9xxx, reg, 1, (void *)&val, true); + dev_dbg(wcd9xxx->dev, "%s: Write %02x to 0x%x ret(%d)\n", + __func__, val, reg, ret); + mutex_unlock(&wcd9xxx->io_lock); + + return ret; +} +EXPORT_SYMBOL(wcd9xxx_interface_reg_write); + +static int wcd9xxx_slim_read_device(struct wcd9xxx *wcd9xxx, unsigned short reg, + int bytes, void *dest, bool interface) +{ + int ret; + struct slim_ele_access msg; + int slim_read_tries = WCD9XXX_SLIM_RW_MAX_TRIES; + + msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg; + msg.num_bytes = bytes; + msg.comp = NULL; + + if (!wcd9xxx->dev_up) { + dev_dbg_ratelimited( + wcd9xxx->dev, "%s: No read allowed. dev_up = %d\n", + __func__, wcd9xxx->dev_up); + return 0; + } + + while (1) { + mutex_lock(&wcd9xxx->xfer_lock); + ret = slim_request_val_element(interface ? + wcd9xxx->slim_slave : wcd9xxx->slim, + &msg, dest, bytes); + mutex_unlock(&wcd9xxx->xfer_lock); + if (likely(ret == 0) || (--slim_read_tries == 0)) + break; + usleep_range(5000, 5100); + } + + if (ret) + dev_err(wcd9xxx->dev, "%s: Error, Codec read failed (%d)\n", + __func__, ret); + + return ret; +} + +/* + * Interface specifies whether the write is to the interface or general + * registers. + */ +static int wcd9xxx_slim_write_device(struct wcd9xxx *wcd9xxx, + unsigned short reg, int bytes, void *src, bool interface) +{ + int ret; + struct slim_ele_access msg; + int slim_write_tries = WCD9XXX_SLIM_RW_MAX_TRIES; + + msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg; + msg.num_bytes = bytes; + msg.comp = NULL; + + if (!wcd9xxx->dev_up) { + dev_dbg_ratelimited( + wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n", + __func__, wcd9xxx->dev_up); + return 0; + } + + while (1) { + mutex_lock(&wcd9xxx->xfer_lock); + ret = slim_change_val_element(interface ? + wcd9xxx->slim_slave : wcd9xxx->slim, + &msg, src, bytes); + mutex_unlock(&wcd9xxx->xfer_lock); + if (likely(ret == 0) || (--slim_write_tries == 0)) + break; + usleep_range(5000, 5100); + } + + if (ret) + pr_err("%s: Error, Codec write failed (%d)\n", __func__, ret); + + return ret; +} + +static int wcd9xxx_slim_get_allowed_slice(struct wcd9xxx *wcd9xxx, + int bytes) +{ + int allowed_sz = bytes; + + if (likely(bytes == SLIM_REPEAT_WRITE_MAX_SLICE)) + allowed_sz = 16; + else if (bytes >= 12) + allowed_sz = 12; + else if (bytes >= 8) + allowed_sz = 8; + else if (bytes >= 6) + allowed_sz = 6; + else if (bytes >= 4) + allowed_sz = 4; + else + allowed_sz = bytes; + + return allowed_sz; +} + +/* + * wcd9xxx_slim_write_repeat: Write the same register with multiple values + * @wcd9xxx: handle to wcd core + * @reg: register to be written + * @bytes: number of bytes to be written to reg + * @src: buffer with data content to be written to reg + * This API will write reg with bytes from src in a single slimbus + * transaction. All values from 1 to 16 are supported by this API. + */ +int wcd9xxx_slim_write_repeat(struct wcd9xxx *wcd9xxx, unsigned short reg, + int bytes, void *src) +{ + int ret = 0, bytes_to_write = bytes, bytes_allowed; + struct slim_ele_access slim_msg; + + mutex_lock(&wcd9xxx->io_lock); + if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X) { + ret = wcd9xxx_page_write(wcd9xxx, ®); + if (ret) + goto done; + } + + slim_msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg; + slim_msg.comp = NULL; + + if (unlikely(bytes > SLIM_REPEAT_WRITE_MAX_SLICE)) { + dev_err(wcd9xxx->dev, "%s: size %d not supported\n", + __func__, bytes); + ret = -EINVAL; + goto done; + } + + if (!wcd9xxx->dev_up) { + dev_dbg_ratelimited( + wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n", + __func__, wcd9xxx->dev_up); + ret = 0; + goto done; + } + + while (bytes_to_write > 0) { + bytes_allowed = wcd9xxx_slim_get_allowed_slice(wcd9xxx, + bytes_to_write); + + slim_msg.num_bytes = bytes_allowed; + mutex_lock(&wcd9xxx->xfer_lock); + ret = slim_user_msg(wcd9xxx->slim, wcd9xxx->slim->laddr, + SLIM_MSG_MT_DEST_REFERRED_USER, + SLIM_USR_MC_REPEAT_CHANGE_VALUE, + &slim_msg, src, bytes_allowed); + mutex_unlock(&wcd9xxx->xfer_lock); + + if (ret) { + dev_err(wcd9xxx->dev, "%s: failed, ret = %d\n", + __func__, ret); + break; + } + + bytes_to_write = bytes_to_write - bytes_allowed; + src = ((u8 *)src) + bytes_allowed; + } + +done: + mutex_unlock(&wcd9xxx->io_lock); + + return ret; +} +EXPORT_SYMBOL(wcd9xxx_slim_write_repeat); + +/* + * wcd9xxx_slim_reserve_bw: API to reserve the slimbus bandwidth + * @wcd9xxx: Handle to the wcd9xxx core + * @bw_ops: value of the bandwidth that is requested + * @commit: Flag to indicate if bandwidth change is to be committed + * right away + */ +int wcd9xxx_slim_reserve_bw(struct wcd9xxx *wcd9xxx, + u32 bw_ops, bool commit) +{ + if (!wcd9xxx || !wcd9xxx->slim) { + pr_err("%s: Invalid handle to %s\n", + __func__, + (!wcd9xxx) ? "wcd9xxx" : "slim_device"); + return -EINVAL; + } + + return slim_reservemsg_bw(wcd9xxx->slim, bw_ops, commit); +} +EXPORT_SYMBOL(wcd9xxx_slim_reserve_bw); + +/* + * wcd9xxx_slim_bulk_write: API to write multiple registers with one descriptor + * @wcd9xxx: Handle to the wcd9xxx core + * @wcd9xxx_reg_val: structure holding register and values to be written + * @size: Indicates number of messages to be written with one descriptor + * @is_interface: Indicates whether the register is for slim interface or for + * general registers. + * @return: returns 0 if success or error information to the caller in case + * of failure. + */ +int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx, + struct wcd9xxx_reg_val *bulk_reg, + unsigned int size, bool is_interface) +{ + int ret, i; + struct slim_val_inf *msgs; + unsigned short reg; + + if (!bulk_reg || !size || !wcd9xxx) { + pr_err("%s: Invalid parameters\n", __func__); + return -EINVAL; + } + + if (!wcd9xxx->dev_up) { + dev_dbg_ratelimited( + wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n", + __func__, wcd9xxx->dev_up); + return 0; + } + + msgs = kzalloc(size * (sizeof(struct slim_val_inf)), GFP_KERNEL); + if (!msgs) { + ret = -ENOMEM; + goto mem_fail; + } + + mutex_lock(&wcd9xxx->io_lock); + reg = bulk_reg->reg; + for (i = 0; i < size; i++) { + msgs[i].start_offset = WCD9XXX_REGISTER_START_OFFSET + + (bulk_reg->reg & 0xFF); + msgs[i].num_bytes = bulk_reg->bytes; + msgs[i].wbuf = bulk_reg->buf; + bulk_reg++; + } + ret = wcd9xxx_page_write(wcd9xxx, ®); + if (ret) { + pr_err("%s: Page write error for reg: 0x%x\n", + __func__, reg); + goto err; + } + + ret = slim_bulk_msg_write(is_interface ? + wcd9xxx->slim_slave : wcd9xxx->slim, + SLIM_MSG_MT_CORE, + SLIM_MSG_MC_CHANGE_VALUE, msgs, size, + NULL, NULL); + if (ret) + pr_err("%s: Error, Codec bulk write failed (%d)\n", + __func__, ret); + /* 100 usec sleep is needed as per HW requirement */ + usleep_range(100, 110); +err: + mutex_unlock(&wcd9xxx->io_lock); + kfree(msgs); +mem_fail: + return ret; +} +EXPORT_SYMBOL(wcd9xxx_slim_bulk_write); + +static int wcd9xxx_num_irq_regs(const struct wcd9xxx *wcd9xxx) +{ + return (wcd9xxx->codec_type->num_irqs / 8) + + ((wcd9xxx->codec_type->num_irqs % 8) ? 1 : 0); +} + +static int wcd9xxx_regmap_init_cache(struct wcd9xxx *wcd9xxx) +{ + struct regmap_config *regmap_config; + int rc; + + regmap_config = wcd9xxx_get_regmap_config(wcd9xxx->type); + if (!regmap_config) { + dev_err(wcd9xxx->dev, "regmap config is not defined\n"); + return -EINVAL; + } + + rc = regmap_reinit_cache(wcd9xxx->regmap, regmap_config); + if (rc != 0) { + dev_err(wcd9xxx->dev, "%s:Failed to reinit register cache: %d\n", + __func__, rc); + } + + return rc; +} + +static int wcd9xxx_device_init(struct wcd9xxx *wcd9xxx) +{ + int ret = 0, i; + struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; + regmap_patch_fptr regmap_apply_patch = NULL; + + mutex_init(&wcd9xxx->io_lock); + mutex_init(&wcd9xxx->xfer_lock); + mutex_init(&wcd9xxx->reset_lock); + + ret = wcd9xxx_bringup(wcd9xxx->dev); + if (ret) { + ret = -EPROBE_DEFER; + goto err_bring_up; + } + + wcd9xxx->codec_type = devm_kzalloc(wcd9xxx->dev, + sizeof(struct wcd9xxx_codec_type), GFP_KERNEL); + if (!wcd9xxx->codec_type) { + ret = -ENOMEM; + goto err_bring_up; + } + ret = wcd9xxx_get_codec_info(wcd9xxx->dev); + if (ret) { + ret = -EPROBE_DEFER; + goto fail_cdc_fill; + } + wcd9xxx->version = wcd9xxx->codec_type->version; + if (!wcd9xxx->codec_type->dev || !wcd9xxx->codec_type->size) + goto fail_cdc_fill; + + core_res->parent = wcd9xxx; + core_res->dev = wcd9xxx->dev; + core_res->intr_table = wcd9xxx->codec_type->intr_tbl; + core_res->intr_table_size = wcd9xxx->codec_type->intr_tbl_size; + + for (i = 0; i < WCD9XXX_INTR_REG_MAX; i++) + wcd9xxx->core_res.intr_reg[i] = + wcd9xxx->codec_type->intr_reg[i]; + + wcd9xxx_core_res_init(&wcd9xxx->core_res, + wcd9xxx->codec_type->num_irqs, + wcd9xxx_num_irq_regs(wcd9xxx), + wcd9xxx->regmap); + + if (wcd9xxx_core_irq_init(&wcd9xxx->core_res)) + goto err; + + ret = wcd9xxx_regmap_init_cache(wcd9xxx); + if (ret) + goto err_irq; + + regmap_apply_patch = wcd9xxx_get_regmap_reg_patch( + wcd9xxx->type); + if (regmap_apply_patch) { + ret = regmap_apply_patch(wcd9xxx->regmap, + wcd9xxx->version); + if (ret) + dev_err(wcd9xxx->dev, + "Failed to register patch: %d\n", ret); + } + + ret = mfd_add_devices(wcd9xxx->dev, -1, wcd9xxx->codec_type->dev, + wcd9xxx->codec_type->size, NULL, 0, NULL); + if (ret != 0) { + dev_err(wcd9xxx->dev, "Failed to add children: %d\n", ret); + goto err_irq; + } + + ret = device_init_wakeup(wcd9xxx->dev, true); + if (ret) { + dev_err(wcd9xxx->dev, "Device wakeup init failed: %d\n", ret); + goto err_irq; + } + + return ret; +err_irq: + wcd9xxx_irq_exit(&wcd9xxx->core_res); +fail_cdc_fill: + devm_kfree(wcd9xxx->dev, wcd9xxx->codec_type); + wcd9xxx->codec_type = NULL; +err: + wcd9xxx_bringdown(wcd9xxx->dev); + wcd9xxx_core_res_deinit(&wcd9xxx->core_res); +err_bring_up: + mutex_destroy(&wcd9xxx->io_lock); + mutex_destroy(&wcd9xxx->xfer_lock); + mutex_destroy(&wcd9xxx->reset_lock); + return ret; +} + +static void wcd9xxx_device_exit(struct wcd9xxx *wcd9xxx) +{ + device_init_wakeup(wcd9xxx->dev, false); + wcd9xxx_irq_exit(&wcd9xxx->core_res); + wcd9xxx_bringdown(wcd9xxx->dev); + wcd9xxx_reset_low(wcd9xxx->dev); + wcd9xxx_core_res_deinit(&wcd9xxx->core_res); + mutex_destroy(&wcd9xxx->io_lock); + mutex_destroy(&wcd9xxx->xfer_lock); + mutex_destroy(&wcd9xxx->reset_lock); + if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS) + slim_remove_device(wcd9xxx->slim_slave); +} + + +#ifdef CONFIG_DEBUG_FS +struct wcd9xxx *debugCodec; + +static struct dentry *debugfs_wcd9xxx_dent; +static struct dentry *debugfs_peek; +static struct dentry *debugfs_poke; +static struct dentry *debugfs_power_state; +static struct dentry *debugfs_reg_dump; + +static unsigned char read_data; + +static int codec_debug_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static int get_parameters(char *buf, long int *param1, int num_of_par) +{ + char *token; + int base, cnt; + + token = strsep(&buf, " "); + + for (cnt = 0; cnt < num_of_par; cnt++) { + if (token != NULL) { + if ((token[1] == 'x') || (token[1] == 'X')) + base = 16; + else + base = 10; + + if (kstrtoul(token, base, ¶m1[cnt]) != 0) + return -EINVAL; + + token = strsep(&buf, " "); + } else + return -EINVAL; + } + return 0; +} + +static ssize_t wcd9xxx_slimslave_reg_show(char __user *ubuf, size_t count, + loff_t *ppos) +{ + int i, reg_val, len; + ssize_t total = 0; + char tmp_buf[25]; /* each line is 12 bytes but 25 for margin of error */ + + for (i = (int) *ppos / 12; i <= SLIM_MAX_REG_ADDR; i++) { + reg_val = wcd9xxx_interface_reg_read(debugCodec, i); + len = snprintf(tmp_buf, sizeof(tmp_buf), + "0x%.3x: 0x%.2x\n", i, reg_val); + + if ((total + len) >= count - 1) + break; + if (copy_to_user((ubuf + total), tmp_buf, len)) { + pr_err("%s: fail to copy reg dump\n", __func__); + total = -EFAULT; + goto copy_err; + } + *ppos += len; + total += len; + } + +copy_err: + return total; +} + +static ssize_t codec_debug_read(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + char lbuf[8]; + char *access_str = file->private_data; + ssize_t ret_cnt; + + if (*ppos < 0 || !count) + return -EINVAL; + + if (!strcmp(access_str, "slimslave_peek")) { + snprintf(lbuf, sizeof(lbuf), "0x%x\n", read_data); + ret_cnt = simple_read_from_buffer(ubuf, count, ppos, lbuf, + strnlen(lbuf, 7)); + } else if (!strcmp(access_str, "slimslave_reg_dump")) { + ret_cnt = wcd9xxx_slimslave_reg_show(ubuf, count, ppos); + } else { + pr_err("%s: %s not permitted to read\n", __func__, access_str); + ret_cnt = -EPERM; + } + + return ret_cnt; +} + +static void wcd9xxx_set_reset_pin_state(struct wcd9xxx *wcd9xxx, + struct wcd9xxx_pdata *pdata, + bool active) +{ + if (wcd9xxx->wcd_rst_np) { + if (active) + msm_cdc_pinctrl_select_active_state( + wcd9xxx->wcd_rst_np); + else + msm_cdc_pinctrl_select_sleep_state( + wcd9xxx->wcd_rst_np); + + return; + } else if (gpio_is_valid(wcd9xxx->reset_gpio)) { + gpio_direction_output(wcd9xxx->reset_gpio, + (active == true ? 1 : 0)); + } +} + +static int codec_debug_process_cdc_power(char *lbuf) +{ + long int param; + int rc; + struct wcd9xxx_pdata *pdata; + + if (wcd9xxx_get_intf_type() != WCD9XXX_INTERFACE_TYPE_SLIMBUS) { + pr_err("%s: CODEC is not in SLIMBUS mode\n", __func__); + rc = -EPERM; + goto error_intf; + } + + rc = get_parameters(lbuf, ¶m, 1); + + if (likely(!rc)) { + pdata = debugCodec->slim->dev.platform_data; + if (param == 0) { + wcd9xxx_slim_device_down(debugCodec->slim); + msm_cdc_disable_static_supplies(debugCodec->dev, + debugCodec->supplies, + pdata->regulator, + pdata->num_supplies); + wcd9xxx_set_reset_pin_state(debugCodec, pdata, false); + } else if (param == 1) { + msm_cdc_enable_static_supplies(debugCodec->dev, + debugCodec->supplies, + pdata->regulator, + pdata->num_supplies); + usleep_range(1000, 2000); + wcd9xxx_set_reset_pin_state(debugCodec, pdata, false); + usleep_range(1000, 2000); + wcd9xxx_set_reset_pin_state(debugCodec, pdata, true); + usleep_range(1000, 2000); + wcd9xxx_slim_device_up(debugCodec->slim); + } else { + pr_err("%s: invalid command %ld\n", __func__, param); + } + } + +error_intf: + return rc; +} + +static ssize_t codec_debug_write(struct file *filp, + const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char *access_str = filp->private_data; + char lbuf[32]; + int rc; + long int param[5]; + + if (cnt > sizeof(lbuf) - 1) + return -EINVAL; + + rc = copy_from_user(lbuf, ubuf, cnt); + if (rc) + return -EFAULT; + + lbuf[cnt] = '\0'; + + if (!strcmp(access_str, "slimslave_poke")) { + /* write */ + rc = get_parameters(lbuf, param, 2); + if ((param[0] <= 0x3FF) && (param[1] <= 0xFF) && + (rc == 0)) + wcd9xxx_interface_reg_write(debugCodec, param[0], + param[1]); + else + rc = -EINVAL; + } else if (!strcmp(access_str, "slimslave_peek")) { + /* read */ + rc = get_parameters(lbuf, param, 1); + if ((param[0] <= 0x3FF) && (rc == 0)) + read_data = wcd9xxx_interface_reg_read(debugCodec, + param[0]); + else + rc = -EINVAL; + } else if (!strcmp(access_str, "power_state")) { + rc = codec_debug_process_cdc_power(lbuf); + } + + if (rc == 0) + rc = cnt; + else + pr_err("%s: rc = %d\n", __func__, rc); + + return rc; +} + +static const struct file_operations codec_debug_ops = { + .open = codec_debug_open, + .write = codec_debug_write, + .read = codec_debug_read +}; +#endif + +static struct wcd9xxx_i2c *wcd9xxx_i2c_get_device_info(struct wcd9xxx *wcd9xxx, + u16 reg) +{ + u16 mask = 0x0f00; + int value = 0; + struct wcd9xxx_i2c *wcd9xxx_i2c = NULL; + + if (wcd9xxx->type == WCD9335) { + wcd9xxx_i2c = &wcd9xxx_modules[0]; + } else { + value = ((reg & mask) >> 8) & 0x000f; + switch (value) { + case 0: + wcd9xxx_i2c = &wcd9xxx_modules[0]; + break; + case 1: + wcd9xxx_i2c = &wcd9xxx_modules[1]; + break; + case 2: + wcd9xxx_i2c = &wcd9xxx_modules[2]; + break; + case 3: + wcd9xxx_i2c = &wcd9xxx_modules[3]; + break; + + default: + break; + } + } + return wcd9xxx_i2c; +} + +static int wcd9xxx_i2c_write_device(struct wcd9xxx *wcd9xxx, u16 reg, u8 *value, + u32 bytes) +{ + + struct i2c_msg *msg; + int ret = 0; + u8 reg_addr = 0; + u8 data[bytes + 1]; + struct wcd9xxx_i2c *wcd9xxx_i2c; + + wcd9xxx_i2c = wcd9xxx_i2c_get_device_info(wcd9xxx, reg); + if (wcd9xxx_i2c == NULL || wcd9xxx_i2c->client == NULL) { + pr_err("failed to get device info\n"); + return -ENODEV; + } + reg_addr = (u8)reg; + msg = &wcd9xxx_i2c->xfer_msg[0]; + msg->addr = wcd9xxx_i2c->client->addr; + msg->len = bytes + 1; + msg->flags = 0; + data[0] = reg; + data[1] = *value; + msg->buf = data; + ret = i2c_transfer(wcd9xxx_i2c->client->adapter, + wcd9xxx_i2c->xfer_msg, 1); + /* Try again if the write fails */ + if (ret != 1) { + ret = i2c_transfer(wcd9xxx_i2c->client->adapter, + wcd9xxx_i2c->xfer_msg, 1); + if (ret != 1) { + pr_err("failed to write the device\n"); + return ret; + } + } + pr_debug("write success register = %x val = %x\n", reg, data[1]); + return 0; +} + + +static int wcd9xxx_i2c_read_device(struct wcd9xxx *wcd9xxx, unsigned short reg, + int bytes, unsigned char *dest) +{ + struct i2c_msg *msg; + int ret = 0; + u8 reg_addr = 0; + struct wcd9xxx_i2c *wcd9xxx_i2c; + u8 i = 0; + + wcd9xxx_i2c = wcd9xxx_i2c_get_device_info(wcd9xxx, reg); + if (wcd9xxx_i2c == NULL || wcd9xxx_i2c->client == NULL) { + pr_err("failed to get device info\n"); + return -ENODEV; + } + for (i = 0; i < bytes; i++) { + reg_addr = (u8)reg++; + msg = &wcd9xxx_i2c->xfer_msg[0]; + msg->addr = wcd9xxx_i2c->client->addr; + msg->len = 1; + msg->flags = 0; + msg->buf = ®_addr; + + msg = &wcd9xxx_i2c->xfer_msg[1]; + msg->addr = wcd9xxx_i2c->client->addr; + msg->len = 1; + msg->flags = I2C_M_RD; + msg->buf = dest++; + ret = i2c_transfer(wcd9xxx_i2c->client->adapter, + wcd9xxx_i2c->xfer_msg, 2); + + /* Try again if read fails first time */ + if (ret != 2) { + ret = i2c_transfer(wcd9xxx_i2c->client->adapter, + wcd9xxx_i2c->xfer_msg, 2); + if (ret != 2) { + pr_err("failed to read wcd9xxx register\n"); + return ret; + } + } + } + return 0; +} + +int wcd9xxx_i2c_read(struct wcd9xxx *wcd9xxx, unsigned short reg, + int bytes, void *dest, bool interface_reg) +{ + return wcd9xxx_i2c_read_device(wcd9xxx, reg, bytes, dest); +} + +int wcd9xxx_i2c_write(struct wcd9xxx *wcd9xxx, unsigned short reg, + int bytes, void *src, bool interface_reg) +{ + return wcd9xxx_i2c_write_device(wcd9xxx, reg, src, bytes); +} + +static int wcd9xxx_i2c_get_client_index(struct i2c_client *client, + int *wcd9xx_index) +{ + int ret = 0; + + switch (client->addr) { + case WCD9XXX_I2C_TOP_SLAVE_ADDR: + *wcd9xx_index = WCD9XXX_I2C_TOP_LEVEL; + break; + case WCD9XXX_ANALOG_I2C_SLAVE_ADDR: + *wcd9xx_index = WCD9XXX_I2C_ANALOG; + break; + case WCD9XXX_DIGITAL1_I2C_SLAVE_ADDR: + *wcd9xx_index = WCD9XXX_I2C_DIGITAL_1; + break; + case WCD9XXX_DIGITAL2_I2C_SLAVE_ADDR: + *wcd9xx_index = WCD9XXX_I2C_DIGITAL_2; + break; + default: + ret = -EINVAL; + break; + } + return ret; +} + +static int wcd9xxx_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct wcd9xxx *wcd9xxx = NULL; + struct wcd9xxx_pdata *pdata = NULL; + int val = 0; + int ret = 0; + int wcd9xx_index = 0; + struct device *dev; + int intf_type; + const struct of_device_id *of_id; + + intf_type = wcd9xxx_get_intf_type(); + + pr_debug("%s: interface status %d\n", __func__, intf_type); + if (intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) { + dev_dbg(&client->dev, "%s:Codec is detected in slimbus mode\n", + __func__); + return -ENODEV; + } else if (intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { + ret = wcd9xxx_i2c_get_client_index(client, &wcd9xx_index); + if (ret != 0) + dev_err(&client->dev, "%s: I2C set codec I2C\n" + "client failed\n", __func__); + else { + dev_err(&client->dev, "%s:probe for other slaves\n" + "devices of codec I2C slave Addr = %x\n", + __func__, client->addr); + wcd9xxx_modules[wcd9xx_index].client = client; + } + return ret; + } else if (intf_type == WCD9XXX_INTERFACE_TYPE_PROBING) { + dev = &client->dev; + if (client->dev.of_node) { + dev_dbg(&client->dev, "%s:Platform data\n" + "from device tree\n", __func__); + pdata = wcd9xxx_populate_dt_data(&client->dev); + if (!pdata) { + dev_err(&client->dev, + "%s: Fail to obtain pdata from device tree\n", + __func__); + ret = -EINVAL; + goto fail; + } + client->dev.platform_data = pdata; + } else { + dev_dbg(&client->dev, "%s:Platform data from\n" + "board file\n", __func__); + pdata = client->dev.platform_data; + } + wcd9xxx = devm_kzalloc(&client->dev, sizeof(struct wcd9xxx), + GFP_KERNEL); + if (!wcd9xxx) { + ret = -ENOMEM; + goto fail; + } + + if (!pdata) { + dev_dbg(&client->dev, "no platform data?\n"); + ret = -EINVAL; + goto fail; + } + wcd9xxx->type = WCD9XXX; + if (client->dev.of_node) { + of_id = of_match_device(wcd9xxx_of_match, &client->dev); + if (of_id) { + wcd9xxx->type = *((int *)of_id->data); + dev_info(&client->dev, "%s: codec type is %d\n", + __func__, wcd9xxx->type); + } + } else { + dev_info(&client->dev, "%s: dev.of_node is NULL, default to WCD9XXX\n", + __func__); + wcd9xxx->type = WCD9XXX; + } + wcd9xxx->regmap = wcd9xxx_regmap_init(&client->dev, + &wcd9xxx_i2c_base_regmap_config); + if (IS_ERR(wcd9xxx->regmap)) { + ret = PTR_ERR(wcd9xxx->regmap); + dev_err(&client->dev, "%s: Failed to allocate register map: %d\n", + __func__, ret); + goto err_codec; + } + wcd9xxx->reset_gpio = pdata->reset_gpio; + wcd9xxx->wcd_rst_np = pdata->wcd_rst_np; + + if (!wcd9xxx->wcd_rst_np) { + pdata->use_pinctrl = false; + dev_err(&client->dev, "%s: pinctrl not used for rst_n\n", + __func__); + goto err_codec; + } + + if (i2c_check_functionality(client->adapter, + I2C_FUNC_I2C) == 0) { + dev_dbg(&client->dev, "can't talk I2C?\n"); + ret = -EIO; + goto fail; + } + dev_set_drvdata(&client->dev, wcd9xxx); + wcd9xxx->dev = &client->dev; + wcd9xxx->dev_up = true; + if (client->dev.of_node) + wcd9xxx->mclk_rate = pdata->mclk_rate; + + wcd9xxx->num_of_supplies = pdata->num_supplies; + ret = msm_cdc_init_supplies(wcd9xxx->dev, &wcd9xxx->supplies, + pdata->regulator, + pdata->num_supplies); + if (!wcd9xxx->supplies) { + dev_err(wcd9xxx->dev, "%s: Cannot init wcd supplies\n", + __func__); + goto err_codec; + } + ret = msm_cdc_enable_static_supplies(wcd9xxx->dev, + wcd9xxx->supplies, + pdata->regulator, + pdata->num_supplies); + if (ret) { + dev_err(wcd9xxx->dev, "%s: wcd static supply enable failed!\n", + __func__); + goto err_codec; + } + /* For WCD9335, it takes about 600us for the Vout_A and + * Vout_D to be ready after BUCK_SIDO is powered up\ + * SYS_RST_N shouldn't be pulled high during this time + */ + if (wcd9xxx->type == WCD9335) + usleep_range(600, 650); + else + usleep_range(5, 10); + + ret = wcd9xxx_reset(wcd9xxx->dev); + if (ret) { + pr_err("%s: Resetting Codec failed\n", __func__); + goto err_supplies; + } + + ret = wcd9xxx_i2c_get_client_index(client, &wcd9xx_index); + if (ret != 0) { + pr_err("%s:Set codec I2C client failed\n", __func__); + goto err_supplies; + } + + wcd9xxx_modules[wcd9xx_index].client = client; + wcd9xxx->read_dev = wcd9xxx_i2c_read; + wcd9xxx->write_dev = wcd9xxx_i2c_write; + if (!wcd9xxx->dev->of_node) + wcd9xxx_assign_irq(&wcd9xxx->core_res, + pdata->irq, pdata->irq_base); + + ret = wcd9xxx_device_init(wcd9xxx); + if (ret) { + pr_err("%s: error, initializing device failed (%d)\n", + __func__, ret); + goto err_device_init; + } + + ret = wcd9xxx_i2c_read(wcd9xxx, WCD9XXX_A_CHIP_STATUS, 1, + &val, 0); + if (ret < 0) + pr_err("%s: failed to read the wcd9xxx status (%d)\n", + __func__, ret); + if (val != wcd9xxx->codec_type->i2c_chip_status) + pr_err("%s: unknown chip status 0x%x\n", __func__, val); + + wcd9xxx_set_intf_type(WCD9XXX_INTERFACE_TYPE_I2C); + + return ret; + } + + pr_err("%s: I2C probe in wrong state\n", __func__); + + +err_device_init: + wcd9xxx_reset_low(wcd9xxx->dev); +err_supplies: + msm_cdc_release_supplies(wcd9xxx->dev, wcd9xxx->supplies, + pdata->regulator, + pdata->num_supplies); + pdata->regulator = NULL; + pdata->num_supplies = 0; +err_codec: + devm_kfree(&client->dev, wcd9xxx); + dev_set_drvdata(&client->dev, NULL); +fail: + return ret; +} + +static int wcd9xxx_i2c_remove(struct i2c_client *client) +{ + struct wcd9xxx *wcd9xxx; + struct wcd9xxx_pdata *pdata = client->dev.platform_data; + + wcd9xxx = dev_get_drvdata(&client->dev); + msm_cdc_release_supplies(wcd9xxx->dev, wcd9xxx->supplies, + pdata->regulator, + pdata->num_supplies); + wcd9xxx_device_exit(wcd9xxx); + dev_set_drvdata(&client->dev, NULL); + return 0; +} + +static int wcd9xxx_dt_parse_slim_interface_dev_info(struct device *dev, + struct slim_device *slim_ifd) +{ + int ret = 0; + struct property *prop; + + ret = of_property_read_string(dev->of_node, "qcom,cdc-slim-ifd", + &slim_ifd->name); + if (ret) { + dev_err(dev, "Looking up %s property in node %s failed", + "qcom,cdc-slim-ifd-dev", dev->of_node->full_name); + return -ENODEV; + } + prop = of_find_property(dev->of_node, + "qcom,cdc-slim-ifd-elemental-addr", NULL); + if (!prop) { + dev_err(dev, "Looking up %s property in node %s failed", + "qcom,cdc-slim-ifd-elemental-addr", + dev->of_node->full_name); + return -ENODEV; + } else if (prop->length != 6) { + dev_err(dev, "invalid codec slim ifd addr. addr length = %d\n", + prop->length); + return -ENODEV; + } + memcpy(slim_ifd->e_addr, prop->value, 6); + + return 0; +} + +static int wcd9xxx_slim_get_laddr(struct slim_device *sb, + const u8 *e_addr, u8 e_len, u8 *laddr) +{ + int ret; + const unsigned long timeout = jiffies + + msecs_to_jiffies(SLIMBUS_PRESENT_TIMEOUT); + + do { + ret = slim_get_logical_addr(sb, e_addr, e_len, laddr); + if (!ret) + break; + /* Give SLIMBUS time to report present and be ready. */ + usleep_range(1000, 1100); + pr_debug_ratelimited("%s: retyring get logical addr\n", + __func__); + } while time_before(jiffies, timeout); + + return ret; +} + +static int wcd9xxx_slim_probe(struct slim_device *slim) +{ + struct wcd9xxx *wcd9xxx; + struct wcd9xxx_pdata *pdata; + const struct slim_device_id *device_id; + int ret = 0; + int intf_type; + + intf_type = wcd9xxx_get_intf_type(); + + wcd9xxx = devm_kzalloc(&slim->dev, sizeof(struct wcd9xxx), + GFP_KERNEL); + if (!wcd9xxx) { + ret = -ENOMEM; + goto err; + } + + if (!slim) { + ret = -EINVAL; + goto err; + } + + if (intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { + dev_dbg(&slim->dev, "%s:Codec is detected in I2C mode\n", + __func__); + ret = -ENODEV; + goto err; + } + if (slim->dev.of_node) { + dev_info(&slim->dev, "Platform data from device tree\n"); + pdata = wcd9xxx_populate_dt_data(&slim->dev); + if (!pdata) { + dev_err(&slim->dev, + "%s: Fail to obtain pdata from device tree\n", + __func__); + ret = -EINVAL; + goto err; + } + + ret = wcd9xxx_dt_parse_slim_interface_dev_info(&slim->dev, + &pdata->slimbus_slave_device); + if (ret) { + dev_err(&slim->dev, "Error, parsing slim interface\n"); + devm_kfree(&slim->dev, pdata); + ret = -EINVAL; + goto err; + } + slim->dev.platform_data = pdata; + + } else { + dev_info(&slim->dev, "Platform data from board file\n"); + pdata = slim->dev.platform_data; + } + + if (!pdata) { + dev_err(&slim->dev, "Error, no platform data\n"); + ret = -EINVAL; + goto err; + } + + if (!slim->ctrl) { + dev_err(&slim->dev, "%s: Error, no SLIMBUS control data\n", + __func__); + ret = -EINVAL; + goto err_codec; + } + device_id = slim_get_device_id(slim); + if (!device_id) { + dev_err(&slim->dev, "%s: Error, no device id\n", __func__); + ret = -EINVAL; + goto err; + } + + wcd9xxx->type = device_id->driver_data; + dev_info(&slim->dev, "%s: probing for wcd type: %d, name: %s\n", + __func__, wcd9xxx->type, device_id->name); + + /* wcd9xxx members init */ + wcd9xxx->multi_reg_write = wcd9xxx_slim_multi_reg_write; + wcd9xxx->slim = slim; + slim_set_clientdata(slim, wcd9xxx); + wcd9xxx->reset_gpio = pdata->reset_gpio; + wcd9xxx->dev = &slim->dev; + wcd9xxx->mclk_rate = pdata->mclk_rate; + wcd9xxx->dev_up = true; + wcd9xxx->wcd_rst_np = pdata->wcd_rst_np; + + wcd9xxx->regmap = wcd9xxx_regmap_init(&slim->dev, + &wcd9xxx_base_regmap_config); + if (IS_ERR(wcd9xxx->regmap)) { + ret = PTR_ERR(wcd9xxx->regmap); + dev_err(&slim->dev, "%s: Failed to allocate register map: %d\n", + __func__, ret); + goto err_codec; + } + + if (!wcd9xxx->wcd_rst_np) { + pdata->use_pinctrl = false; + dev_err(&slim->dev, "%s: pinctrl not used for rst_n\n", + __func__); + goto err_codec; + } + + wcd9xxx->num_of_supplies = pdata->num_supplies; + ret = msm_cdc_init_supplies(&slim->dev, &wcd9xxx->supplies, + pdata->regulator, + pdata->num_supplies); + if (!wcd9xxx->supplies) { + dev_err(wcd9xxx->dev, "%s: Cannot init wcd supplies\n", + __func__); + goto err_codec; + } + ret = msm_cdc_enable_static_supplies(wcd9xxx->dev, + wcd9xxx->supplies, + pdata->regulator, + pdata->num_supplies); + if (ret) { + dev_err(wcd9xxx->dev, "%s: wcd static supply enable failed!\n", + __func__); + goto err_codec; + } + + /* + * For WCD9335, it takes about 600us for the Vout_A and + * Vout_D to be ready after BUCK_SIDO is powered up. + * SYS_RST_N shouldn't be pulled high during this time + */ + if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X) + usleep_range(600, 650); + else + usleep_range(5, 10); + + ret = wcd9xxx_reset(&slim->dev); + if (ret) { + dev_err(&slim->dev, "%s: Resetting Codec failed\n", __func__); + goto err_supplies; + } + + ret = wcd9xxx_slim_get_laddr(wcd9xxx->slim, wcd9xxx->slim->e_addr, + ARRAY_SIZE(wcd9xxx->slim->e_addr), + &wcd9xxx->slim->laddr); + if (ret) { + dev_err(&slim->dev, "%s: failed to get slimbus %s logical address: %d\n", + __func__, wcd9xxx->slim->name, ret); + goto err_reset; + } + wcd9xxx->read_dev = wcd9xxx_slim_read_device; + wcd9xxx->write_dev = wcd9xxx_slim_write_device; + wcd9xxx_pgd_la = wcd9xxx->slim->laddr; + wcd9xxx->slim_slave = &pdata->slimbus_slave_device; + if (!wcd9xxx->dev->of_node) + wcd9xxx_assign_irq(&wcd9xxx->core_res, + pdata->irq, pdata->irq_base); + + ret = slim_add_device(slim->ctrl, wcd9xxx->slim_slave); + if (ret) { + dev_err(&slim->dev, "%s: error, adding SLIMBUS device failed\n", + __func__); + goto err_reset; + } + + ret = wcd9xxx_slim_get_laddr(wcd9xxx->slim_slave, + wcd9xxx->slim_slave->e_addr, + ARRAY_SIZE(wcd9xxx->slim_slave->e_addr), + &wcd9xxx->slim_slave->laddr); + if (ret) { + dev_err(&slim->dev, "%s: failed to get slimbus %s logical address: %d\n", + __func__, wcd9xxx->slim->name, ret); + goto err_slim_add; + } + wcd9xxx_inf_la = wcd9xxx->slim_slave->laddr; + wcd9xxx_set_intf_type(WCD9XXX_INTERFACE_TYPE_SLIMBUS); + + ret = wcd9xxx_device_init(wcd9xxx); + if (ret) { + dev_err(&slim->dev, "%s: error, initializing device failed (%d)\n", + __func__, ret); + goto err_slim_add; + } +#ifdef CONFIG_DEBUG_FS + debugCodec = wcd9xxx; + + debugfs_wcd9xxx_dent = debugfs_create_dir + ("wcd9xxx_core", 0); + if (!IS_ERR(debugfs_wcd9xxx_dent)) { + debugfs_peek = debugfs_create_file("slimslave_peek", + S_IFREG | 0444, debugfs_wcd9xxx_dent, + (void *) "slimslave_peek", &codec_debug_ops); + + debugfs_poke = debugfs_create_file("slimslave_poke", + S_IFREG | 0444, debugfs_wcd9xxx_dent, + (void *) "slimslave_poke", &codec_debug_ops); + + debugfs_power_state = debugfs_create_file("power_state", + S_IFREG | 0444, debugfs_wcd9xxx_dent, + (void *) "power_state", &codec_debug_ops); + + debugfs_reg_dump = debugfs_create_file("slimslave_reg_dump", + S_IFREG | 0444, debugfs_wcd9xxx_dent, + (void *) "slimslave_reg_dump", &codec_debug_ops); + } +#endif + + return ret; + +err_slim_add: + slim_remove_device(wcd9xxx->slim_slave); +err_reset: + wcd9xxx_reset_low(wcd9xxx->dev); +err_supplies: + msm_cdc_release_supplies(wcd9xxx->dev, wcd9xxx->supplies, + pdata->regulator, + pdata->num_supplies); +err_codec: + slim_set_clientdata(slim, NULL); +err: + devm_kfree(&slim->dev, wcd9xxx); + return ret; +} +static int wcd9xxx_slim_remove(struct slim_device *pdev) +{ + struct wcd9xxx *wcd9xxx; + struct wcd9xxx_pdata *pdata = pdev->dev.platform_data; + +#ifdef CONFIG_DEBUG_FS + debugfs_remove_recursive(debugfs_wcd9xxx_dent); +#endif + wcd9xxx = slim_get_devicedata(pdev); + wcd9xxx_deinit_slimslave(wcd9xxx); + slim_remove_device(wcd9xxx->slim_slave); + msm_cdc_release_supplies(wcd9xxx->dev, wcd9xxx->supplies, + pdata->regulator, + pdata->num_supplies); + wcd9xxx_device_exit(wcd9xxx); + slim_set_clientdata(pdev, NULL); + return 0; +} + +static int wcd9xxx_device_up(struct wcd9xxx *wcd9xxx) +{ + int ret = 0; + struct wcd9xxx_core_resource *wcd9xxx_res = &wcd9xxx->core_res; + + dev_info(wcd9xxx->dev, "%s: codec bring up\n", __func__); + wcd9xxx_bringup(wcd9xxx->dev); + ret = wcd9xxx_irq_init(wcd9xxx_res); + if (ret) { + pr_err("%s: wcd9xx_irq_init failed : %d\n", __func__, ret); + } else { + if (wcd9xxx->post_reset) + ret = wcd9xxx->post_reset(wcd9xxx); + } + return ret; +} + +static int wcd9xxx_slim_device_reset(struct slim_device *sldev) +{ + int ret; + struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev); + + if (!wcd9xxx) { + pr_err("%s: wcd9xxx is NULL\n", __func__); + return -EINVAL; + } + + dev_info(wcd9xxx->dev, "%s: device reset, dev_up = %d\n", + __func__, wcd9xxx->dev_up); + if (wcd9xxx->dev_up) + return 0; + + mutex_lock(&wcd9xxx->reset_lock); + ret = wcd9xxx_reset(wcd9xxx->dev); + if (ret) + dev_err(wcd9xxx->dev, "%s: Resetting Codec failed\n", __func__); + mutex_unlock(&wcd9xxx->reset_lock); + + return ret; +} + +static int wcd9xxx_slim_device_up(struct slim_device *sldev) +{ + struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev); + int ret = 0; + + if (!wcd9xxx) { + pr_err("%s: wcd9xxx is NULL\n", __func__); + return -EINVAL; + } + dev_info(wcd9xxx->dev, "%s: slim device up, dev_up = %d\n", + __func__, wcd9xxx->dev_up); + if (wcd9xxx->dev_up) + return 0; + + wcd9xxx->dev_up = true; + + mutex_lock(&wcd9xxx->reset_lock); + ret = wcd9xxx_device_up(wcd9xxx); + mutex_unlock(&wcd9xxx->reset_lock); + + return ret; +} + +static int wcd9xxx_slim_device_down(struct slim_device *sldev) +{ + struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev); + + if (!wcd9xxx) { + pr_err("%s: wcd9xxx is NULL\n", __func__); + return -EINVAL; + } + + dev_info(wcd9xxx->dev, "%s: device down, dev_up = %d\n", + __func__, wcd9xxx->dev_up); + if (!wcd9xxx->dev_up) + return 0; + + wcd9xxx->dev_up = false; + + mutex_lock(&wcd9xxx->reset_lock); + if (wcd9xxx->dev_down) + wcd9xxx->dev_down(wcd9xxx); + wcd9xxx_irq_exit(&wcd9xxx->core_res); + wcd9xxx_reset_low(wcd9xxx->dev); + mutex_unlock(&wcd9xxx->reset_lock); + + return 0; +} + +static int wcd9xxx_slim_resume(struct slim_device *sldev) +{ + struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev); + + return wcd9xxx_core_res_resume(&wcd9xxx->core_res); +} + +static int wcd9xxx_i2c_resume(struct device *dev) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(dev); + + if (wcd9xxx) + return wcd9xxx_core_res_resume(&wcd9xxx->core_res); + else + return 0; +} + +static int wcd9xxx_slim_suspend(struct slim_device *sldev, pm_message_t pmesg) +{ + struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev); + + return wcd9xxx_core_res_suspend(&wcd9xxx->core_res, pmesg); +} + +static int wcd9xxx_i2c_suspend(struct device *dev) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(dev); + pm_message_t pmesg = {0}; + + if (wcd9xxx) + return wcd9xxx_core_res_suspend(&wcd9xxx->core_res, pmesg); + else + return 0; +} + +static const struct slim_device_id wcd_slim_device_id[] = { + {"sitar-slim", 0}, + {"sitar1p1-slim", 0}, + {"tabla-slim", 0}, + {"tabla2x-slim", 0}, + {"taiko-slim-pgd", 0}, + {"tapan-slim-pgd", 0}, + {"tomtom-slim-pgd", WCD9330}, + {"tasha-slim-pgd", WCD9335}, + {"tavil-slim-pgd", WCD934X}, + {} +}; + +static struct slim_driver wcd_slim_driver = { + .driver = { + .name = "wcd-slim", + .owner = THIS_MODULE, + }, + .probe = wcd9xxx_slim_probe, + .remove = wcd9xxx_slim_remove, + .id_table = wcd_slim_device_id, + .resume = wcd9xxx_slim_resume, + .suspend = wcd9xxx_slim_suspend, + .device_up = wcd9xxx_slim_device_up, + .reset_device = wcd9xxx_slim_device_reset, + .device_down = wcd9xxx_slim_device_down, +}; + +static struct i2c_device_id wcd9xxx_id_table[] = { + {"wcd9xxx-i2c", WCD9XXX_I2C_TOP_LEVEL}, + {"wcd9xxx-i2c", WCD9XXX_I2C_ANALOG}, + {"wcd9xxx-i2c", WCD9XXX_I2C_DIGITAL_1}, + {"wcd9xxx-i2c", WCD9XXX_I2C_DIGITAL_2}, + {} +}; + +static struct i2c_device_id tasha_id_table[] = { + {"tasha-i2c-pgd", WCD9XXX_I2C_TOP_LEVEL}, + {} +}; + +static struct i2c_device_id tabla_id_table[] = { + {"tabla top level", WCD9XXX_I2C_TOP_LEVEL}, + {"tabla analog", WCD9XXX_I2C_ANALOG}, + {"tabla digital1", WCD9XXX_I2C_DIGITAL_1}, + {"tabla digital2", WCD9XXX_I2C_DIGITAL_2}, + {} +}; +MODULE_DEVICE_TABLE(i2c, tabla_id_table); + +static const struct dev_pm_ops wcd9xxx_i2c_pm_ops = { + .suspend = wcd9xxx_i2c_suspend, + .resume = wcd9xxx_i2c_resume, +}; + +static struct i2c_driver tabla_i2c_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "tabla-i2c-core", + .pm = &wcd9xxx_i2c_pm_ops, + }, + .id_table = tabla_id_table, + .probe = wcd9xxx_i2c_probe, + .remove = wcd9xxx_i2c_remove, +}; + +static struct i2c_driver wcd9xxx_i2c_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "wcd9xxx-i2c-core", + .pm = &wcd9xxx_i2c_pm_ops, + }, + .id_table = wcd9xxx_id_table, + .probe = wcd9xxx_i2c_probe, + .remove = wcd9xxx_i2c_remove, +}; + +static struct i2c_driver wcd9335_i2c_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "tasha-i2c-core", + .pm = &wcd9xxx_i2c_pm_ops, + }, + .id_table = tasha_id_table, + .probe = wcd9xxx_i2c_probe, + .remove = wcd9xxx_i2c_remove, +}; + +int wcd9xxx_init(void) +{ + int ret[NUM_WCD9XXX_REG_RET] = {0}; + int i = 0; + + wcd9xxx_set_intf_type(WCD9XXX_INTERFACE_TYPE_PROBING); + + ret[0] = i2c_add_driver(&tabla_i2c_driver); + if (ret[0]) + pr_err("%s: Failed to add the tabla2x I2C driver: %d\n", + __func__, ret[0]); + + ret[1] = i2c_add_driver(&wcd9xxx_i2c_driver); + if (ret[1]) + pr_err("%s: Failed to add the wcd9xxx I2C driver: %d\n", + __func__, ret[1]); + + ret[2] = i2c_add_driver(&wcd9335_i2c_driver); + if (ret[2]) + pr_err("%s: Failed to add the wcd9335 I2C driver: %d\n", + __func__, ret[2]); + + ret[3] = slim_driver_register(&wcd_slim_driver); + if (ret[3]) + pr_err("%s: Failed to register wcd SB driver: %d\n", + __func__, ret[3]); + + for (i = 0; i < NUM_WCD9XXX_REG_RET; i++) { + if (ret[i]) + return ret[i]; + } + + return 0; +} + +void wcd9xxx_exit(void) +{ + wcd9xxx_set_intf_type(WCD9XXX_INTERFACE_TYPE_PROBING); + + i2c_del_driver(&tabla_i2c_driver); + i2c_del_driver(&wcd9xxx_i2c_driver); + i2c_del_driver(&wcd9335_i2c_driver); + slim_driver_unregister(&wcd_slim_driver); +} + +MODULE_DESCRIPTION("Codec core driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/mfd/wcd9xxx-irq.c b/drivers/mfd/wcd9xxx-irq.c new file mode 100644 index 000000000000..092f44632e1b --- /dev/null +++ b/drivers/mfd/wcd9xxx-irq.c @@ -0,0 +1,853 @@ +/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BYTE_BIT_MASK(nr) (1UL << ((nr) % BITS_PER_BYTE)) +#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE) + +#define WCD9XXX_SYSTEM_RESUME_TIMEOUT_MS 100 + +#ifndef NO_IRQ +#define NO_IRQ (-1) +#endif + +#ifdef CONFIG_OF +struct wcd9xxx_irq_drv_data { + struct irq_domain *domain; + int irq; +}; +#endif + +static int virq_to_phyirq( + struct wcd9xxx_core_resource *wcd9xxx_res, int virq); +static int phyirq_to_virq( + struct wcd9xxx_core_resource *wcd9xxx_res, int irq); +static unsigned int wcd9xxx_irq_get_upstream_irq( + struct wcd9xxx_core_resource *wcd9xxx_res); +static void wcd9xxx_irq_put_upstream_irq( + struct wcd9xxx_core_resource *wcd9xxx_res); +static int wcd9xxx_map_irq( + struct wcd9xxx_core_resource *wcd9xxx_res, int irq); + +static void wcd9xxx_irq_lock(struct irq_data *data) +{ + struct wcd9xxx_core_resource *wcd9xxx_res = + irq_data_get_irq_chip_data(data); + mutex_lock(&wcd9xxx_res->irq_lock); +} + +static void wcd9xxx_irq_sync_unlock(struct irq_data *data) +{ + struct wcd9xxx_core_resource *wcd9xxx_res = + irq_data_get_irq_chip_data(data); + int i; + + if ((ARRAY_SIZE(wcd9xxx_res->irq_masks_cur) > + WCD9XXX_MAX_IRQ_REGS) || + (ARRAY_SIZE(wcd9xxx_res->irq_masks_cache) > + WCD9XXX_MAX_IRQ_REGS)) { + pr_err("%s: Array Size out of bound\n", __func__); + return; + } + if (!wcd9xxx_res->wcd_core_regmap) { + pr_err("%s: Codec core regmap not defined\n", + __func__); + return; + } + + for (i = 0; i < ARRAY_SIZE(wcd9xxx_res->irq_masks_cur); i++) { + /* If there's been a change in the mask write it back + * to the hardware. + */ + if (wcd9xxx_res->irq_masks_cur[i] != + wcd9xxx_res->irq_masks_cache[i]) { + + wcd9xxx_res->irq_masks_cache[i] = + wcd9xxx_res->irq_masks_cur[i]; + regmap_write(wcd9xxx_res->wcd_core_regmap, + wcd9xxx_res->intr_reg[WCD9XXX_INTR_MASK_BASE] + i, + wcd9xxx_res->irq_masks_cur[i]); + } + } + + mutex_unlock(&wcd9xxx_res->irq_lock); +} + +static void wcd9xxx_irq_enable(struct irq_data *data) +{ + struct wcd9xxx_core_resource *wcd9xxx_res = + irq_data_get_irq_chip_data(data); + int wcd9xxx_irq = virq_to_phyirq(wcd9xxx_res, data->irq); + int byte = BIT_BYTE(wcd9xxx_irq); + int size = ARRAY_SIZE(wcd9xxx_res->irq_masks_cur); + + if ((byte < size) && (byte >= 0)) { + wcd9xxx_res->irq_masks_cur[byte] &= + ~(BYTE_BIT_MASK(wcd9xxx_irq)); + } else { + pr_err("%s: Array size is %d but index is %d: Out of range\n", + __func__, size, byte); + } +} + +static void wcd9xxx_irq_disable(struct irq_data *data) +{ + struct wcd9xxx_core_resource *wcd9xxx_res = + irq_data_get_irq_chip_data(data); + int wcd9xxx_irq = virq_to_phyirq(wcd9xxx_res, data->irq); + int byte = BIT_BYTE(wcd9xxx_irq); + int size = ARRAY_SIZE(wcd9xxx_res->irq_masks_cur); + + if ((byte < size) && (byte >= 0)) { + wcd9xxx_res->irq_masks_cur[byte] + |= BYTE_BIT_MASK(wcd9xxx_irq); + } else { + pr_err("%s: Array size is %d but index is %d: Out of range\n", + __func__, size, byte); + } +} + +static void wcd9xxx_irq_ack(struct irq_data *data) +{ + int wcd9xxx_irq = 0; + struct wcd9xxx_core_resource *wcd9xxx_res = + irq_data_get_irq_chip_data(data); + + if (wcd9xxx_res == NULL) { + pr_err("%s: wcd9xxx_res is NULL\n", __func__); + return; + } + wcd9xxx_irq = virq_to_phyirq(wcd9xxx_res, data->irq); + pr_debug("%s: IRQ_ACK called for WCD9XXX IRQ: %d\n", + __func__, wcd9xxx_irq); +} + +static void wcd9xxx_irq_mask(struct irq_data *d) +{ + /* do nothing but required as linux calls irq_mask without NULL check */ +} + +static struct irq_chip wcd9xxx_irq_chip = { + .name = "wcd9xxx", + .irq_bus_lock = wcd9xxx_irq_lock, + .irq_bus_sync_unlock = wcd9xxx_irq_sync_unlock, + .irq_disable = wcd9xxx_irq_disable, + .irq_enable = wcd9xxx_irq_enable, + .irq_mask = wcd9xxx_irq_mask, + .irq_ack = wcd9xxx_irq_ack, +}; + +bool wcd9xxx_lock_sleep( + struct wcd9xxx_core_resource *wcd9xxx_res) +{ + enum wcd9xxx_pm_state os; + + /* + * wcd9xxx_{lock/unlock}_sleep will be called by wcd9xxx_irq_thread + * and its subroutines only motly. + * but btn0_lpress_fn is not wcd9xxx_irq_thread's subroutine and + * It can race with wcd9xxx_irq_thread. + * So need to embrace wlock_holders with mutex. + * + * If system didn't resume, we can simply return false so codec driver's + * IRQ handler can return without handling IRQ. + * As interrupt line is still active, codec will have another IRQ to + * retry shortly. + */ + mutex_lock(&wcd9xxx_res->pm_lock); + if (wcd9xxx_res->wlock_holders++ == 0) { + pr_debug("%s: holding wake lock\n", __func__); + pm_qos_update_request(&wcd9xxx_res->pm_qos_req, + msm_cpuidle_get_deep_idle_latency()); + pm_stay_awake(wcd9xxx_res->dev); + } + mutex_unlock(&wcd9xxx_res->pm_lock); + + if (!wait_event_timeout(wcd9xxx_res->pm_wq, + ((os = wcd9xxx_pm_cmpxchg(wcd9xxx_res, + WCD9XXX_PM_SLEEPABLE, + WCD9XXX_PM_AWAKE)) == + WCD9XXX_PM_SLEEPABLE || + (os == WCD9XXX_PM_AWAKE)), + msecs_to_jiffies( + WCD9XXX_SYSTEM_RESUME_TIMEOUT_MS))) { + pr_warn("%s: system didn't resume within %dms, s %d, w %d\n", + __func__, + WCD9XXX_SYSTEM_RESUME_TIMEOUT_MS, wcd9xxx_res->pm_state, + wcd9xxx_res->wlock_holders); + wcd9xxx_unlock_sleep(wcd9xxx_res); + return false; + } + wake_up_all(&wcd9xxx_res->pm_wq); + return true; +} +EXPORT_SYMBOL(wcd9xxx_lock_sleep); + +void wcd9xxx_unlock_sleep( + struct wcd9xxx_core_resource *wcd9xxx_res) +{ + mutex_lock(&wcd9xxx_res->pm_lock); + if (--wcd9xxx_res->wlock_holders == 0) { + pr_debug("%s: releasing wake lock pm_state %d -> %d\n", + __func__, wcd9xxx_res->pm_state, WCD9XXX_PM_SLEEPABLE); + /* + * if wcd9xxx_lock_sleep failed, pm_state would be still + * WCD9XXX_PM_ASLEEP, don't overwrite + */ + if (likely(wcd9xxx_res->pm_state == WCD9XXX_PM_AWAKE)) + wcd9xxx_res->pm_state = WCD9XXX_PM_SLEEPABLE; + pm_qos_update_request(&wcd9xxx_res->pm_qos_req, + PM_QOS_DEFAULT_VALUE); + pm_relax(wcd9xxx_res->dev); + } + mutex_unlock(&wcd9xxx_res->pm_lock); + wake_up_all(&wcd9xxx_res->pm_wq); +} +EXPORT_SYMBOL(wcd9xxx_unlock_sleep); + +void wcd9xxx_nested_irq_lock(struct wcd9xxx_core_resource *wcd9xxx_res) +{ + mutex_lock(&wcd9xxx_res->nested_irq_lock); +} + +void wcd9xxx_nested_irq_unlock(struct wcd9xxx_core_resource *wcd9xxx_res) +{ + mutex_unlock(&wcd9xxx_res->nested_irq_lock); +} + + +static void wcd9xxx_irq_dispatch(struct wcd9xxx_core_resource *wcd9xxx_res, + struct intr_data *irqdata) +{ + int irqbit = irqdata->intr_num; + + if (!wcd9xxx_res->wcd_core_regmap) { + pr_err("%s: codec core regmap not defined\n", + __func__); + return; + } + + if (irqdata->clear_first) { + wcd9xxx_nested_irq_lock(wcd9xxx_res); + regmap_write(wcd9xxx_res->wcd_core_regmap, + wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLEAR_BASE] + + BIT_BYTE(irqbit), + BYTE_BIT_MASK(irqbit)); + + if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) + regmap_write(wcd9xxx_res->wcd_core_regmap, + wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLR_COMMIT], + 0x02); + handle_nested_irq(phyirq_to_virq(wcd9xxx_res, irqbit)); + wcd9xxx_nested_irq_unlock(wcd9xxx_res); + } else { + wcd9xxx_nested_irq_lock(wcd9xxx_res); + handle_nested_irq(phyirq_to_virq(wcd9xxx_res, irqbit)); + regmap_write(wcd9xxx_res->wcd_core_regmap, + wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLEAR_BASE] + + BIT_BYTE(irqbit), + BYTE_BIT_MASK(irqbit)); + if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) + regmap_write(wcd9xxx_res->wcd_core_regmap, + wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLR_COMMIT], + 0x02); + + wcd9xxx_nested_irq_unlock(wcd9xxx_res); + } +} + +static irqreturn_t wcd9xxx_irq_thread(int irq, void *data) +{ + int ret; + int i; + struct intr_data irqdata; + char linebuf[128]; + static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 1); + struct wcd9xxx_core_resource *wcd9xxx_res = data; + int num_irq_regs = wcd9xxx_res->num_irq_regs; + u8 status[4], status1[4] = {0}, unmask_status[4] = {0}; + + if (unlikely(wcd9xxx_lock_sleep(wcd9xxx_res) == false)) { + dev_err(wcd9xxx_res->dev, "Failed to hold suspend\n"); + return IRQ_NONE; + } + + if (!wcd9xxx_res->wcd_core_regmap) { + dev_err(wcd9xxx_res->dev, + "%s: Codec core regmap not supplied\n", + __func__); + goto err_disable_irq; + } + + memset(status, 0, sizeof(status)); + ret = regmap_bulk_read(wcd9xxx_res->wcd_core_regmap, + wcd9xxx_res->intr_reg[WCD9XXX_INTR_STATUS_BASE], + status, num_irq_regs); + + if (ret < 0) { + dev_err(wcd9xxx_res->dev, + "Failed to read interrupt status: %d\n", ret); + goto err_disable_irq; + } + /* + * If status is 0 return without clearing. + * status contains: HW status - masked interrupts + * status1 contains: unhandled interrupts - masked interrupts + * unmasked_status contains: unhandled interrupts + */ + if (unlikely(!memcmp(status, status1, sizeof(status)))) { + pr_debug("%s: status is 0\n", __func__); + wcd9xxx_unlock_sleep(wcd9xxx_res); + return IRQ_HANDLED; + } + + /* + * Copy status to unmask_status before masking, otherwise SW may miss + * to clear masked interrupt in corner case. + */ + memcpy(unmask_status, status, sizeof(unmask_status)); + + /* Apply masking */ + for (i = 0; i < num_irq_regs; i++) + status[i] &= ~wcd9xxx_res->irq_masks_cur[i]; + + memcpy(status1, status, sizeof(status1)); + + /* Find out which interrupt was triggered and call that interrupt's + * handler function + * + * Since codec has only one hardware irq line which is shared by + * codec's different internal interrupts, so it's possible master irq + * handler dispatches multiple nested irq handlers after breaking + * order. Dispatch interrupts in the order that is maintained by + * the interrupt table. + */ + for (i = 0; i < wcd9xxx_res->intr_table_size; i++) { + irqdata = wcd9xxx_res->intr_table[i]; + if (status[BIT_BYTE(irqdata.intr_num)] & + BYTE_BIT_MASK(irqdata.intr_num)) { + wcd9xxx_irq_dispatch(wcd9xxx_res, &irqdata); + status1[BIT_BYTE(irqdata.intr_num)] &= + ~BYTE_BIT_MASK(irqdata.intr_num); + unmask_status[BIT_BYTE(irqdata.intr_num)] &= + ~BYTE_BIT_MASK(irqdata.intr_num); + } + } + + /* + * As a failsafe if unhandled irq is found, clear it to prevent + * interrupt storm. + * Note that we can say there was an unhandled irq only when no irq + * handled by nested irq handler since Taiko supports qdsp as irqs' + * destination for few irqs. Therefore driver shouldn't clear pending + * irqs when few handled while few others not. + */ + if (unlikely(!memcmp(status, status1, sizeof(status)))) { + if (__ratelimit(&ratelimit)) { + pr_warn("%s: Unhandled irq found\n", __func__); + hex_dump_to_buffer(status, sizeof(status), 16, 1, + linebuf, sizeof(linebuf), false); + pr_warn("%s: status0 : %s\n", __func__, linebuf); + hex_dump_to_buffer(status1, sizeof(status1), 16, 1, + linebuf, sizeof(linebuf), false); + pr_warn("%s: status1 : %s\n", __func__, linebuf); + } + /* + * unmask_status contains unhandled interrupts, hence clear all + * unhandled interrupts. + */ + ret = regmap_bulk_write(wcd9xxx_res->wcd_core_regmap, + wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLEAR_BASE], + unmask_status, num_irq_regs); + if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) + regmap_write(wcd9xxx_res->wcd_core_regmap, + wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLR_COMMIT], + 0x02); + } + wcd9xxx_unlock_sleep(wcd9xxx_res); + + return IRQ_HANDLED; + +err_disable_irq: + dev_err(wcd9xxx_res->dev, + "Disable irq %d\n", wcd9xxx_res->irq); + + disable_irq_wake(wcd9xxx_res->irq); + disable_irq_nosync(wcd9xxx_res->irq); + wcd9xxx_unlock_sleep(wcd9xxx_res); + return IRQ_NONE; +} + +/** + * wcd9xxx_free_irq + * + * @wcd9xxx_res: pointer to core resource + * irq: irq number + * @data: data pointer + * + */ +void wcd9xxx_free_irq(struct wcd9xxx_core_resource *wcd9xxx_res, + int irq, void *data) +{ + free_irq(phyirq_to_virq(wcd9xxx_res, irq), data); +} +EXPORT_SYMBOL(wcd9xxx_free_irq); + +/** + * wcd9xxx_enable_irq + * + * @wcd9xxx_res: pointer to core resource + * irq: irq number + * + */ +void wcd9xxx_enable_irq(struct wcd9xxx_core_resource *wcd9xxx_res, int irq) +{ + if (wcd9xxx_res->irq) + enable_irq(phyirq_to_virq(wcd9xxx_res, irq)); +} +EXPORT_SYMBOL(wcd9xxx_enable_irq); + +/** + * wcd9xxx_disable_irq + * + * @wcd9xxx_res: pointer to core resource + * irq: irq number + * + */ +void wcd9xxx_disable_irq(struct wcd9xxx_core_resource *wcd9xxx_res, int irq) +{ + if (wcd9xxx_res->irq) + disable_irq_nosync(phyirq_to_virq(wcd9xxx_res, irq)); +} +EXPORT_SYMBOL(wcd9xxx_disable_irq); + +/** + * wcd9xxx_disable_irq_sync + * + * @wcd9xxx_res: pointer to core resource + * irq: irq number + * + */ +void wcd9xxx_disable_irq_sync( + struct wcd9xxx_core_resource *wcd9xxx_res, int irq) +{ + if (wcd9xxx_res->irq) + disable_irq(phyirq_to_virq(wcd9xxx_res, irq)); +} +EXPORT_SYMBOL(wcd9xxx_disable_irq_sync); + +static int wcd9xxx_irq_setup_downstream_irq( + struct wcd9xxx_core_resource *wcd9xxx_res) +{ + int irq, virq, ret; + + pr_debug("%s: enter\n", __func__); + + for (irq = 0; irq < wcd9xxx_res->num_irqs; irq++) { + /* Map OF irq */ + virq = wcd9xxx_map_irq(wcd9xxx_res, irq); + pr_debug("%s: irq %d -> %d\n", __func__, irq, virq); + if (virq == NO_IRQ) { + pr_err("%s, No interrupt specifier for irq %d\n", + __func__, irq); + return NO_IRQ; + } + + ret = irq_set_chip_data(virq, wcd9xxx_res); + if (ret) { + pr_err("%s: Failed to configure irq %d (%d)\n", + __func__, irq, ret); + return ret; + } + + if (wcd9xxx_res->irq_level_high[irq]) + irq_set_chip_and_handler(virq, &wcd9xxx_irq_chip, + handle_level_irq); + else + irq_set_chip_and_handler(virq, &wcd9xxx_irq_chip, + handle_edge_irq); + + irq_set_nested_thread(virq, 1); + } + + pr_debug("%s: leave\n", __func__); + + return 0; +} + +/** + * wcd9xxx_irq_init + * + * @wcd9xxx_res: pointer to core resource + * + * Returns 0 on success, appropriate error code otherwise + */ +int wcd9xxx_irq_init(struct wcd9xxx_core_resource *wcd9xxx_res) +{ + int i, ret; + u8 irq_level[wcd9xxx_res->num_irq_regs]; + struct irq_domain *domain; + struct device_node *pnode; + + mutex_init(&wcd9xxx_res->irq_lock); + mutex_init(&wcd9xxx_res->nested_irq_lock); + + pnode = of_irq_find_parent(wcd9xxx_res->dev->of_node); + if (unlikely(!pnode)) + return -EINVAL; + + domain = irq_find_host(pnode); + if (unlikely(!domain)) + return -EINVAL; + + wcd9xxx_res->domain = domain; + + wcd9xxx_res->irq = wcd9xxx_irq_get_upstream_irq(wcd9xxx_res); + if (!wcd9xxx_res->irq) { + pr_warn("%s: irq driver is not yet initialized\n", __func__); + mutex_destroy(&wcd9xxx_res->irq_lock); + mutex_destroy(&wcd9xxx_res->nested_irq_lock); + return -EPROBE_DEFER; + } + pr_debug("%s: probed irq %d\n", __func__, wcd9xxx_res->irq); + + /* Setup downstream IRQs */ + ret = wcd9xxx_irq_setup_downstream_irq(wcd9xxx_res); + if (ret) { + pr_err("%s: Failed to setup downstream IRQ\n", __func__); + wcd9xxx_irq_put_upstream_irq(wcd9xxx_res); + mutex_destroy(&wcd9xxx_res->irq_lock); + mutex_destroy(&wcd9xxx_res->nested_irq_lock); + return ret; + } + + /* All other wcd9xxx interrupts are edge triggered */ + wcd9xxx_res->irq_level_high[0] = true; + + /* mask all the interrupts */ + memset(irq_level, 0, wcd9xxx_res->num_irq_regs); + for (i = 0; i < wcd9xxx_res->num_irqs; i++) { + wcd9xxx_res->irq_masks_cur[BIT_BYTE(i)] |= BYTE_BIT_MASK(i); + wcd9xxx_res->irq_masks_cache[BIT_BYTE(i)] |= BYTE_BIT_MASK(i); + irq_level[BIT_BYTE(i)] |= + wcd9xxx_res->irq_level_high[i] << (i % BITS_PER_BYTE); + } + + if (!wcd9xxx_res->wcd_core_regmap) { + dev_err(wcd9xxx_res->dev, + "%s: Codec core regmap not defined\n", + __func__); + ret = -EINVAL; + goto fail_irq_init; + } + + for (i = 0; i < wcd9xxx_res->num_irq_regs; i++) { + /* Initialize interrupt mask and level registers */ + regmap_write(wcd9xxx_res->wcd_core_regmap, + wcd9xxx_res->intr_reg[WCD9XXX_INTR_LEVEL_BASE] + i, + irq_level[i]); + regmap_write(wcd9xxx_res->wcd_core_regmap, + wcd9xxx_res->intr_reg[WCD9XXX_INTR_MASK_BASE] + i, + wcd9xxx_res->irq_masks_cur[i]); + } + + ret = request_threaded_irq(wcd9xxx_res->irq, NULL, wcd9xxx_irq_thread, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "wcd9xxx", wcd9xxx_res); + if (ret != 0) + dev_err(wcd9xxx_res->dev, "Failed to request IRQ %d: %d\n", + wcd9xxx_res->irq, ret); + else { + ret = enable_irq_wake(wcd9xxx_res->irq); + if (ret) + dev_err(wcd9xxx_res->dev, + "Failed to set wake interrupt on IRQ %d: %d\n", + wcd9xxx_res->irq, ret); + if (ret) + free_irq(wcd9xxx_res->irq, wcd9xxx_res); + } + + if (ret) + goto fail_irq_init; + + return ret; + +fail_irq_init: + dev_err(wcd9xxx_res->dev, + "%s: Failed to init wcd9xxx irq\n", __func__); + wcd9xxx_irq_put_upstream_irq(wcd9xxx_res); + mutex_destroy(&wcd9xxx_res->irq_lock); + mutex_destroy(&wcd9xxx_res->nested_irq_lock); + return ret; +} +EXPORT_SYMBOL(wcd9xxx_irq_init); + +int wcd9xxx_request_irq(struct wcd9xxx_core_resource *wcd9xxx_res, + int irq, irq_handler_t handler, + const char *name, void *data) +{ + int virq; + + virq = phyirq_to_virq(wcd9xxx_res, irq); + + return request_threaded_irq(virq, NULL, handler, IRQF_TRIGGER_RISING, + name, data); +} +EXPORT_SYMBOL(wcd9xxx_request_irq); + +void wcd9xxx_irq_exit(struct wcd9xxx_core_resource *wcd9xxx_res) +{ + dev_dbg(wcd9xxx_res->dev, "%s: Cleaning up irq %d\n", __func__, + wcd9xxx_res->irq); + + if (wcd9xxx_res->irq) { + disable_irq_wake(wcd9xxx_res->irq); + free_irq(wcd9xxx_res->irq, wcd9xxx_res); + wcd9xxx_res->irq = 0; + wcd9xxx_irq_put_upstream_irq(wcd9xxx_res); + } + mutex_destroy(&wcd9xxx_res->irq_lock); + mutex_destroy(&wcd9xxx_res->nested_irq_lock); +} + +#ifndef CONFIG_OF +static int phyirq_to_virq( + struct wcd9xxx_core_resource *wcd9xxx_res, + int offset) +{ + return wcd9xxx_res->irq_base + offset; +} + +static int virq_to_phyirq( + struct wcd9xxx_core_resource *wcd9xxx_res, + int virq) +{ + return virq - wcd9xxx_res->irq_base; +} + +static unsigned int wcd9xxx_irq_get_upstream_irq( + struct wcd9xxx_core_resource *wcd9xxx_res) +{ + return wcd9xxx_res->irq; +} + +static void wcd9xxx_irq_put_upstream_irq( + struct wcd9xxx_core_resource *wcd9xxx_res) +{ + /* Do nothing */ +} + +static int wcd9xxx_map_irq( + struct wcd9xxx_core_resource *wcd9xxx_core_res, int irq) +{ + return phyirq_to_virq(wcd9xxx_core_res, irq); +} +#else +static struct wcd9xxx_irq_drv_data * +wcd9xxx_irq_add_domain(struct device_node *node, + struct device_node *parent) +{ + struct wcd9xxx_irq_drv_data *data = NULL; + + pr_debug("%s: node %s, node parent %s\n", __func__, + node->name, node->parent->name); + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return NULL; + + /* + * wcd9xxx_intc interrupt controller supports N to N irq mapping with + * single cell binding with irq numbers(offsets) only. + * Use irq_domain_simple_ops that has irq_domain_simple_map and + * irq_domain_xlate_onetwocell. + */ + data->domain = irq_domain_add_linear(node, WCD9XXX_MAX_NUM_IRQS, + &irq_domain_simple_ops, data); + if (!data->domain) { + kfree(data); + return NULL; + } + + return data; +} + +static struct wcd9xxx_irq_drv_data * +wcd9xxx_get_irq_drv_d(const struct wcd9xxx_core_resource *wcd9xxx_res) +{ + struct irq_domain *domain; + + domain = wcd9xxx_res->domain; + + if (domain) + return domain->host_data; + else + return NULL; +} + +static int phyirq_to_virq(struct wcd9xxx_core_resource *wcd9xxx_res, int offset) +{ + struct wcd9xxx_irq_drv_data *data; + + data = wcd9xxx_get_irq_drv_d(wcd9xxx_res); + if (!data) { + pr_warn("%s: not registered to interrupt controller\n", + __func__); + return -EINVAL; + } + return irq_linear_revmap(data->domain, offset); +} + +static int virq_to_phyirq(struct wcd9xxx_core_resource *wcd9xxx_res, int virq) +{ + struct irq_data *irq_data = irq_get_irq_data(virq); + + if (unlikely(!irq_data)) { + pr_err("%s: irq_data is NULL", __func__); + return -EINVAL; + } + return irq_data->hwirq; +} + +static unsigned int wcd9xxx_irq_get_upstream_irq( + struct wcd9xxx_core_resource *wcd9xxx_res) +{ + struct wcd9xxx_irq_drv_data *data; + + data = wcd9xxx_get_irq_drv_d(wcd9xxx_res); + if (!data) { + pr_err("%s: interrupt controller is not registered\n", + __func__); + return 0; + } + + /* Make sure data is updated before return. */ + rmb(); + return data->irq; +} + +static void wcd9xxx_irq_put_upstream_irq( + struct wcd9xxx_core_resource *wcd9xxx_res) +{ + wcd9xxx_res->domain = NULL; +} + +static int wcd9xxx_map_irq(struct wcd9xxx_core_resource *wcd9xxx_res, int irq) +{ + return of_irq_to_resource(wcd9xxx_res->dev->of_node, irq, NULL); +} + +static int wcd9xxx_irq_probe(struct platform_device *pdev) +{ + int irq, dir_apps_irq = -EINVAL; + struct wcd9xxx_irq_drv_data *data; + struct device_node *node = pdev->dev.of_node; + int ret = -EINVAL; + + irq = of_get_named_gpio(node, "qcom,gpio-connect", 0); + if (!gpio_is_valid(irq)) + dir_apps_irq = platform_get_irq_byname(pdev, "wcd_irq"); + + if (!gpio_is_valid(irq) && dir_apps_irq < 0) { + dev_err(&pdev->dev, "TLMM connect gpio not found\n"); + return -EPROBE_DEFER; + } + if (dir_apps_irq > 0) { + irq = dir_apps_irq; + } else { + irq = gpio_to_irq(irq); + if (irq < 0) { + dev_err(&pdev->dev, "Unable to configure irq\n"); + return irq; + } + } + dev_dbg(&pdev->dev, "%s: virq = %d\n", __func__, irq); + data = wcd9xxx_irq_add_domain(node, node->parent); + if (!data) { + pr_err("%s: irq_add_domain failed\n", __func__); + return -EINVAL; + } + data->irq = irq; + + /* Make sure irq is saved before return. */ + wmb(); + ret = 0; + + return ret; +} + +static int wcd9xxx_irq_remove(struct platform_device *pdev) +{ + struct irq_domain *domain; + struct wcd9xxx_irq_drv_data *data; + + domain = irq_find_host(pdev->dev.of_node); + if (unlikely(!domain)) { + pr_err("%s: domain is NULL", __func__); + return -EINVAL; + } + data = (struct wcd9xxx_irq_drv_data *)domain->host_data; + data->irq = 0; + + /* Make sure irq variable is updated in data, before irq removal. */ + wmb(); + irq_domain_remove(data->domain); + kfree(data); + domain->host_data = NULL; + + return 0; +} + +static const struct of_device_id of_match[] = { + { .compatible = "qcom,wcd9xxx-irq" }, + { } +}; + +static struct platform_driver wcd9xxx_irq_driver = { + .probe = wcd9xxx_irq_probe, + .remove = wcd9xxx_irq_remove, + .driver = { + .name = "wcd9xxx_intc", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(of_match), + }, +}; + +int wcd9xxx_irq_drv_init(void) +{ + return platform_driver_register(&wcd9xxx_irq_driver); +} + +void wcd9xxx_irq_drv_exit(void) +{ + platform_driver_unregister(&wcd9xxx_irq_driver); +} +#endif /* CONFIG_OF */ diff --git a/drivers/mfd/wcd9xxx-regmap.h b/drivers/mfd/wcd9xxx-regmap.h new file mode 100644 index 000000000000..f44e8b1cf532 --- /dev/null +++ b/drivers/mfd/wcd9xxx-regmap.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _WCD9XXX_REGMAP_ +#define _WCD9XXX_REGMAP_ + +#include +#include + +typedef int (*regmap_patch_fptr)(struct regmap *, int); + +extern struct regmap_config wcd934x_regmap_config; +extern int wcd934x_regmap_register_patch(struct regmap *regmap, + int version); + +extern struct regmap_config wcd9335_regmap_config; +extern int wcd9335_regmap_register_patch(struct regmap *regmap, + int version); + +static inline struct regmap_config *wcd9xxx_get_regmap_config(int type) +{ + struct regmap_config *regmap_config; + + switch (type) { + case WCD934X: + regmap_config = &wcd934x_regmap_config; + break; + case WCD9335: + regmap_config = &wcd9335_regmap_config; + break; + default: + regmap_config = NULL; + break; + }; + + return regmap_config; +} + +static inline regmap_patch_fptr wcd9xxx_get_regmap_reg_patch(int type) +{ + regmap_patch_fptr apply_patch; + + switch (type) { + case WCD9335: + apply_patch = wcd9335_regmap_register_patch; + break; + case WCD934X: + apply_patch = wcd934x_regmap_register_patch; + break; + default: + apply_patch = NULL; + break; + } + + return apply_patch; +} + +#endif diff --git a/drivers/mfd/wcd9xxx-rst.c b/drivers/mfd/wcd9xxx-rst.c new file mode 100644 index 000000000000..c8e0b348254a --- /dev/null +++ b/drivers/mfd/wcd9xxx-rst.c @@ -0,0 +1,443 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* wcd9335 interrupt table */ +static const struct intr_data wcd9335_intr_table[] = { + {WCD9XXX_IRQ_SLIMBUS, false}, + {WCD9335_IRQ_MBHC_SW_DET, true}, + {WCD9335_IRQ_MBHC_BUTTON_PRESS_DET, true}, + {WCD9335_IRQ_MBHC_BUTTON_RELEASE_DET, true}, + {WCD9335_IRQ_MBHC_ELECT_INS_REM_DET, true}, + {WCD9335_IRQ_MBHC_ELECT_INS_REM_LEG_DET, true}, + {WCD9335_IRQ_FLL_LOCK_LOSS, false}, + {WCD9335_IRQ_HPH_PA_CNPL_COMPLETE, false}, + {WCD9335_IRQ_HPH_PA_CNPR_COMPLETE, false}, + {WCD9335_IRQ_EAR_PA_CNP_COMPLETE, false}, + {WCD9335_IRQ_LINE_PA1_CNP_COMPLETE, false}, + {WCD9335_IRQ_LINE_PA2_CNP_COMPLETE, false}, + {WCD9335_IRQ_LINE_PA3_CNP_COMPLETE, false}, + {WCD9335_IRQ_LINE_PA4_CNP_COMPLETE, false}, + {WCD9335_IRQ_HPH_PA_OCPL_FAULT, false}, + {WCD9335_IRQ_HPH_PA_OCPR_FAULT, false}, + {WCD9335_IRQ_EAR_PA_OCP_FAULT, false}, + {WCD9335_IRQ_SOUNDWIRE, false}, + {WCD9335_IRQ_VDD_DIG_RAMP_COMPLETE, false}, + {WCD9335_IRQ_RCO_ERROR, false}, + {WCD9335_IRQ_SVA_ERROR, false}, + {WCD9335_IRQ_MAD_AUDIO, false}, + {WCD9335_IRQ_MAD_BEACON, false}, + {WCD9335_IRQ_SVA_OUTBOX1, true}, + {WCD9335_IRQ_SVA_OUTBOX2, true}, + {WCD9335_IRQ_MAD_ULTRASOUND, false}, + {WCD9335_IRQ_VBAT_ATTACK, false}, + {WCD9335_IRQ_VBAT_RESTORE, false}, +}; + +static const struct intr_data wcd934x_intr_table[] = { + {WCD9XXX_IRQ_SLIMBUS, false}, + {WCD934X_IRQ_MBHC_SW_DET, true}, + {WCD934X_IRQ_MBHC_BUTTON_PRESS_DET, true}, + {WCD934X_IRQ_MBHC_BUTTON_RELEASE_DET, true}, + {WCD934X_IRQ_MBHC_ELECT_INS_REM_DET, true}, + {WCD934X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, true}, + {WCD934X_IRQ_MISC, false}, + {WCD934X_IRQ_HPH_PA_CNPL_COMPLETE, false}, + {WCD934X_IRQ_HPH_PA_CNPR_COMPLETE, false}, + {WCD934X_IRQ_EAR_PA_CNP_COMPLETE, false}, + {WCD934X_IRQ_LINE_PA1_CNP_COMPLETE, false}, + {WCD934X_IRQ_LINE_PA2_CNP_COMPLETE, false}, + {WCD934X_IRQ_SLNQ_ANALOG_ERROR, false}, + {WCD934X_IRQ_RESERVED_3, false}, + {WCD934X_IRQ_HPH_PA_OCPL_FAULT, false}, + {WCD934X_IRQ_HPH_PA_OCPR_FAULT, false}, + {WCD934X_IRQ_EAR_PA_OCP_FAULT, false}, + {WCD934X_IRQ_SOUNDWIRE, false}, + {WCD934X_IRQ_VDD_DIG_RAMP_COMPLETE, false}, + {WCD934X_IRQ_RCO_ERROR, false}, + {WCD934X_IRQ_CPE_ERROR, false}, + {WCD934X_IRQ_MAD_AUDIO, false}, + {WCD934X_IRQ_MAD_BEACON, false}, + {WCD934X_IRQ_CPE1_INTR, true}, + {WCD934X_IRQ_RESERVED_4, false}, + {WCD934X_IRQ_MAD_ULTRASOUND, false}, + {WCD934X_IRQ_VBAT_ATTACK, false}, + {WCD934X_IRQ_VBAT_RESTORE, false}, +}; + +/* + * wcd9335_bring_down: Bringdown WCD Codec + * + * @wcd9xxx: Pointer to wcd9xxx structure + * + * Returns 0 for success or negative error code for failure + */ +static int wcd9335_bring_down(struct wcd9xxx *wcd9xxx) +{ + if (!wcd9xxx || !wcd9xxx->regmap) + return -EINVAL; + + regmap_write(wcd9xxx->regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x04); + + return 0; +} + +/* + * wcd9335_bring_up: Bringup WCD Codec + * + * @wcd9xxx: Pointer to the wcd9xxx structure + * + * Returns 0 for success or negative error code for failure + */ +static int wcd9335_bring_up(struct wcd9xxx *wcd9xxx) +{ + int ret = 0; + int val, byte0; + struct regmap *wcd_regmap; + + if (!wcd9xxx) + return -EINVAL; + + if (!wcd9xxx->regmap) { + dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null!\n", + __func__); + return -EINVAL; + } + wcd_regmap = wcd9xxx->regmap; + + regmap_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0, &val); + regmap_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0, &byte0); + + if ((val < 0) || (byte0 < 0)) { + dev_err(wcd9xxx->dev, "%s: tasha codec version detection fail!\n", + __func__); + return -EINVAL; + } + if ((val & 0x80) && (byte0 == 0x0)) { + dev_info(wcd9xxx->dev, "%s: wcd9335 codec version is v1.1\n", + __func__); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01); + regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_2, 0xFC); + regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_4, 0x21); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x5); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x7); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x3); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3); + } else if (byte0 == 0x1) { + dev_info(wcd9xxx->dev, "%s: wcd9335 codec version is v2.0\n", + __func__); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01); + regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_TEST_2, 0x00); + regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_8, 0x6F); + regmap_write(wcd_regmap, WCD9335_BIAS_VBG_FINE_ADJ, 0x65); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x5); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x7); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x3); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3); + } else if ((byte0 == 0) && (!(val & 0x80))) { + dev_info(wcd9xxx->dev, "%s: wcd9335 codec version is v1.0\n", + __func__); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01); + regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_2, 0xFC); + regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_4, 0x21); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x3); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3); + } else { + dev_err(wcd9xxx->dev, "%s: tasha codec version unknown\n", + __func__); + ret = -EINVAL; + } + + return ret; +} + +/* + * wcd9335_get_cdc_info: Get codec specific information + * + * @wcd9xxx: pointer to wcd9xxx structure + * @wcd_type: pointer to wcd9xxx_codec_type structure + * + * Returns 0 for success or negative error code for failure + */ +static int wcd9335_get_cdc_info(struct wcd9xxx *wcd9xxx, + struct wcd9xxx_codec_type *wcd_type) +{ + u16 id_minor, id_major; + struct regmap *wcd_regmap; + int rc, val, version = 0; + + if (!wcd9xxx || !wcd_type) + return -EINVAL; + + if (!wcd9xxx->regmap) { + dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null!\n", + __func__); + return -EINVAL; + } + wcd_regmap = wcd9xxx->regmap; + + rc = regmap_bulk_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0, + (u8 *)&id_minor, sizeof(u16)); + if (rc) + return -EINVAL; + + rc = regmap_bulk_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE2, + (u8 *)&id_major, sizeof(u16)); + if (rc) + return -EINVAL; + + dev_info(wcd9xxx->dev, "%s: wcd9xxx chip id major 0x%x, minor 0x%x\n", + __func__, id_major, id_minor); + + /* Version detection */ + if (id_major == TASHA_MAJOR) { + regmap_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0, + &val); + version = ((u8)val & 0x80) >> 7; + } else if (id_major == TASHA2P0_MAJOR) + version = 2; + else + dev_err(wcd9xxx->dev, "%s: wcd9335 version unknown (major 0x%x, minor 0x%x)\n", + __func__, id_major, id_minor); + + /* Fill codec type info */ + wcd_type->id_major = id_major; + wcd_type->id_minor = id_minor; + wcd_type->num_irqs = WCD9335_NUM_IRQS; + wcd_type->version = version; + wcd_type->slim_slave_type = WCD9XXX_SLIM_SLAVE_ADDR_TYPE_1; + wcd_type->i2c_chip_status = 0x01; + wcd_type->intr_tbl = wcd9335_intr_table; + wcd_type->intr_tbl_size = ARRAY_SIZE(wcd9335_intr_table); + + wcd_type->intr_reg[WCD9XXX_INTR_STATUS_BASE] = + WCD9335_INTR_PIN1_STATUS0; + wcd_type->intr_reg[WCD9XXX_INTR_CLEAR_BASE] = + WCD9335_INTR_PIN1_CLEAR0; + wcd_type->intr_reg[WCD9XXX_INTR_MASK_BASE] = + WCD9335_INTR_PIN1_MASK0; + wcd_type->intr_reg[WCD9XXX_INTR_LEVEL_BASE] = + WCD9335_INTR_LEVEL0; + wcd_type->intr_reg[WCD9XXX_INTR_CLR_COMMIT] = + WCD9335_INTR_CLR_COMMIT; + + return rc; +} + +/* + * wcd934x_bring_down: Bringdown WCD Codec + * + * @wcd9xxx: Pointer to wcd9xxx structure + * + * Returns 0 for success or negative error code for failure + */ +static int wcd934x_bring_down(struct wcd9xxx *wcd9xxx) +{ + if (!wcd9xxx || !wcd9xxx->regmap) + return -EINVAL; + + regmap_write(wcd9xxx->regmap, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x04); + + return 0; +} + +/* + * wcd934x_bring_up: Bringup WCD Codec + * + * @wcd9xxx: Pointer to the wcd9xxx structure + * + * Returns 0 for success or negative error code for failure + */ +static int wcd934x_bring_up(struct wcd9xxx *wcd9xxx) +{ + struct regmap *wcd_regmap; + + if (!wcd9xxx) + return -EINVAL; + + if (!wcd9xxx->regmap) { + dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null!\n", + __func__); + return -EINVAL; + } + wcd_regmap = wcd9xxx->regmap; + + regmap_write(wcd_regmap, WCD934X_CODEC_RPM_RST_CTL, 0x01); + regmap_write(wcd_regmap, WCD934X_SIDO_NEW_VOUT_A_STARTUP, 0x19); + regmap_write(wcd_regmap, WCD934X_SIDO_NEW_VOUT_D_STARTUP, 0x15); + /* Add 1msec delay for VOUT to settle */ + usleep_range(1000, 1100); + regmap_write(wcd_regmap, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5); + regmap_write(wcd_regmap, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7); + regmap_write(wcd_regmap, WCD934X_CODEC_RPM_RST_CTL, 0x3); + regmap_write(wcd_regmap, WCD934X_CODEC_RPM_RST_CTL, 0x7); + regmap_write(wcd_regmap, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3); + + return 0; +} + +/* + * wcd934x_get_cdc_info: Get codec specific information + * + * @wcd9xxx: pointer to wcd9xxx structure + * @wcd_type: pointer to wcd9xxx_codec_type structure + * + * Returns 0 for success or negative error code for failure + */ +static int wcd934x_get_cdc_info(struct wcd9xxx *wcd9xxx, + struct wcd9xxx_codec_type *wcd_type) +{ + u16 id_minor, id_major; + struct regmap *wcd_regmap; + int rc, version = -1; + + if (!wcd9xxx || !wcd_type) + return -EINVAL; + + if (!wcd9xxx->regmap) { + dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null\n", __func__); + return -EINVAL; + } + wcd_regmap = wcd9xxx->regmap; + + rc = regmap_bulk_read(wcd_regmap, WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE0, + (u8 *)&id_minor, sizeof(u16)); + if (rc) + return -EINVAL; + + rc = regmap_bulk_read(wcd_regmap, WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE2, + (u8 *)&id_major, sizeof(u16)); + if (rc) + return -EINVAL; + + dev_info(wcd9xxx->dev, "%s: wcd9xxx chip id major 0x%x, minor 0x%x\n", + __func__, id_major, id_minor); + + if (id_major != TAVIL_MAJOR) + goto version_unknown; + + /* + * As fine version info cannot be retrieved before tavil probe. + * Assign coarse versions for possible future use before tavil probe. + */ + if (id_minor == cpu_to_le16(0)) + version = TAVIL_VERSION_1_0; + else if (id_minor == cpu_to_le16(0x01)) + version = TAVIL_VERSION_1_1; + +version_unknown: + if (version < 0) + dev_err(wcd9xxx->dev, "%s: wcd934x version unknown\n", + __func__); + + /* Fill codec type info */ + wcd_type->id_major = id_major; + wcd_type->id_minor = id_minor; + wcd_type->num_irqs = WCD934X_NUM_IRQS; + wcd_type->version = version; + wcd_type->slim_slave_type = WCD9XXX_SLIM_SLAVE_ADDR_TYPE_1; + wcd_type->i2c_chip_status = 0x01; + wcd_type->intr_tbl = wcd934x_intr_table; + wcd_type->intr_tbl_size = ARRAY_SIZE(wcd934x_intr_table); + + wcd_type->intr_reg[WCD9XXX_INTR_STATUS_BASE] = + WCD934X_INTR_PIN1_STATUS0; + wcd_type->intr_reg[WCD9XXX_INTR_CLEAR_BASE] = + WCD934X_INTR_PIN1_CLEAR0; + wcd_type->intr_reg[WCD9XXX_INTR_MASK_BASE] = + WCD934X_INTR_PIN1_MASK0; + wcd_type->intr_reg[WCD9XXX_INTR_LEVEL_BASE] = + WCD934X_INTR_LEVEL0; + wcd_type->intr_reg[WCD9XXX_INTR_CLR_COMMIT] = + WCD934X_INTR_CLR_COMMIT; + + return rc; +} + +codec_bringdown_fn wcd9xxx_bringdown_fn(int type) +{ + codec_bringdown_fn cdc_bdown_fn; + + switch (type) { + case WCD934X: + cdc_bdown_fn = wcd934x_bring_down; + break; + case WCD9335: + cdc_bdown_fn = wcd9335_bring_down; + break; + default: + cdc_bdown_fn = NULL; + break; + } + + return cdc_bdown_fn; +} + +codec_bringup_fn wcd9xxx_bringup_fn(int type) +{ + codec_bringup_fn cdc_bup_fn; + + switch (type) { + case WCD934X: + cdc_bup_fn = wcd934x_bring_up; + break; + case WCD9335: + cdc_bup_fn = wcd9335_bring_up; + break; + default: + cdc_bup_fn = NULL; + break; + } + + return cdc_bup_fn; +} + +codec_type_fn wcd9xxx_get_codec_info_fn(int type) +{ + codec_type_fn cdc_type_fn; + + switch (type) { + case WCD934X: + cdc_type_fn = wcd934x_get_cdc_info; + break; + case WCD9335: + cdc_type_fn = wcd9335_get_cdc_info; + break; + default: + cdc_type_fn = NULL; + break; + } + + return cdc_type_fn; +} + diff --git a/drivers/mfd/wcd9xxx-slimslave.c b/drivers/mfd/wcd9xxx-slimslave.c new file mode 100644 index 000000000000..a99ad5a2f9c8 --- /dev/null +++ b/drivers/mfd/wcd9xxx-slimslave.c @@ -0,0 +1,584 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include + +struct wcd9xxx_slim_sch { + u16 rx_port_ch_reg_base; + u16 port_tx_cfg_reg_base; + u16 port_rx_cfg_reg_base; +}; + +static struct wcd9xxx_slim_sch sh_ch; + +static int wcd9xxx_alloc_slim_sh_ch(struct wcd9xxx *wcd9xxx, + u8 wcd9xxx_pgd_la, u32 cnt, + struct wcd9xxx_ch *channels, u32 path); + +static int wcd9xxx_dealloc_slim_sh_ch(struct slim_device *slim, + u32 cnt, struct wcd9xxx_ch *channels); + +static int wcd9xxx_configure_ports(struct wcd9xxx *wcd9xxx) +{ + if (wcd9xxx->codec_type->slim_slave_type == + WCD9XXX_SLIM_SLAVE_ADDR_TYPE_0) { + sh_ch.rx_port_ch_reg_base = 0x180; + sh_ch.port_rx_cfg_reg_base = 0x040; + sh_ch.port_tx_cfg_reg_base = 0x040; + } else { + sh_ch.rx_port_ch_reg_base = + 0x180 - (TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS * 4); + sh_ch.port_rx_cfg_reg_base = + 0x040 - TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS; + sh_ch.port_tx_cfg_reg_base = 0x050; + } + + return 0; +} + +/** + * wcd9xxx_init_slimslave + * + * @wcd9xxx: pointer to wcd9xxx struct + * @wcd9xxx_pgd_la: pgd_la value + * @tx_num: tx number + * @rx_num: rx number + * @tx_slot: pointer to tx slot + * @rx_slot: pointer to rx slot + * + * Returns 0 on success, appropriate error code otherwise + */ +int wcd9xxx_init_slimslave(struct wcd9xxx *wcd9xxx, u8 wcd9xxx_pgd_la, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot) +{ + int ret = 0; + int i; + + ret = wcd9xxx_configure_ports(wcd9xxx); + if (ret) { + pr_err("%s: Failed to configure register address offset\n", + __func__); + goto err; + } + + if (!rx_num || rx_num > wcd9xxx->num_rx_port) { + pr_err("%s: invalid rx num %d\n", __func__, rx_num); + return -EINVAL; + } + if (wcd9xxx->rx_chs) { + wcd9xxx->num_rx_port = rx_num; + for (i = 0; i < rx_num; i++) { + wcd9xxx->rx_chs[i].ch_num = rx_slot[i]; + INIT_LIST_HEAD(&wcd9xxx->rx_chs[i].list); + } + ret = wcd9xxx_alloc_slim_sh_ch(wcd9xxx, wcd9xxx_pgd_la, + wcd9xxx->num_rx_port, + wcd9xxx->rx_chs, + SLIM_SINK); + if (ret) { + pr_err("%s: Failed to alloc %d rx slimbus channels\n", + __func__, wcd9xxx->num_rx_port); + kfree(wcd9xxx->rx_chs); + wcd9xxx->rx_chs = NULL; + wcd9xxx->num_rx_port = 0; + } + } else { + pr_err("Not able to allocate memory for %d slimbus rx ports\n", + wcd9xxx->num_rx_port); + } + + if (!tx_num || tx_num > wcd9xxx->num_tx_port) { + pr_err("%s: invalid tx num %d\n", __func__, tx_num); + return -EINVAL; + } + if (wcd9xxx->tx_chs) { + wcd9xxx->num_tx_port = tx_num; + for (i = 0; i < tx_num; i++) { + wcd9xxx->tx_chs[i].ch_num = tx_slot[i]; + INIT_LIST_HEAD(&wcd9xxx->tx_chs[i].list); + } + ret = wcd9xxx_alloc_slim_sh_ch(wcd9xxx, wcd9xxx_pgd_la, + wcd9xxx->num_tx_port, + wcd9xxx->tx_chs, + SLIM_SRC); + if (ret) { + pr_err("%s: Failed to alloc %d tx slimbus channels\n", + __func__, wcd9xxx->num_tx_port); + kfree(wcd9xxx->tx_chs); + wcd9xxx->tx_chs = NULL; + wcd9xxx->num_tx_port = 0; + } + } else { + pr_err("Not able to allocate memory for %d slimbus tx ports\n", + wcd9xxx->num_tx_port); + } + return 0; +err: + return ret; +} +EXPORT_SYMBOL(wcd9xxx_init_slimslave); + +int wcd9xxx_deinit_slimslave(struct wcd9xxx *wcd9xxx) +{ + if (wcd9xxx->num_rx_port) { + wcd9xxx_dealloc_slim_sh_ch(wcd9xxx->slim, + wcd9xxx->num_rx_port, + wcd9xxx->rx_chs); + wcd9xxx->num_rx_port = 0; + } + if (wcd9xxx->num_tx_port) { + wcd9xxx_dealloc_slim_sh_ch(wcd9xxx->slim, + wcd9xxx->num_tx_port, + wcd9xxx->tx_chs); + wcd9xxx->num_tx_port = 0; + } + return 0; +} + + +static int wcd9xxx_alloc_slim_sh_ch(struct wcd9xxx *wcd9xxx, + u8 wcd9xxx_pgd_la, u32 cnt, + struct wcd9xxx_ch *channels, u32 path) +{ + int ret = 0; + u32 ch_idx; + + /* The slimbus channel allocation seem take longer time + * so do the allocation up front to avoid delay in start of + * playback + */ + pr_debug("%s: pgd_la[%d]\n", __func__, wcd9xxx_pgd_la); + for (ch_idx = 0; ch_idx < cnt; ch_idx++) { + ret = slim_get_slaveport(wcd9xxx_pgd_la, + channels[ch_idx].port, + &channels[ch_idx].sph, path); + pr_debug("%s: pgd_la[%d] channels[%d].port[%d]\n" + "channels[%d].sph[%d] path[%d]\n", + __func__, wcd9xxx_pgd_la, ch_idx, + channels[ch_idx].port, + ch_idx, channels[ch_idx].sph, path); + if (ret < 0) { + pr_err("%s: slave port failure id[%d] ret[%d]\n", + __func__, channels[ch_idx].ch_num, ret); + goto err; + } + + ret = slim_query_ch(wcd9xxx->slim, + channels[ch_idx].ch_num, + &channels[ch_idx].ch_h); + if (ret < 0) { + pr_err("%s: slim_query_ch failed ch-num[%d] ret[%d]\n", + __func__, channels[ch_idx].ch_num, ret); + goto err; + } + } +err: + return ret; +} + +static int wcd9xxx_dealloc_slim_sh_ch(struct slim_device *slim, + u32 cnt, struct wcd9xxx_ch *channels) +{ + int idx = 0; + int ret = 0; + /* slim_dealloc_ch */ + for (idx = 0; idx < cnt; idx++) { + ret = slim_dealloc_ch(slim, channels[idx].ch_h); + if (ret < 0) { + pr_err("%s: slim_dealloc_ch fail ret[%d] ch_h[%d]\n", + __func__, ret, channels[idx].ch_h); + } + } + return ret; +} + +/* Enable slimbus slave device for RX path */ +int wcd9xxx_cfg_slim_sch_rx(struct wcd9xxx *wcd9xxx, + struct list_head *wcd9xxx_ch_list, + unsigned int rate, unsigned int bit_width, + u16 *grph) +{ + u8 ch_cnt = 0; + u16 ch_h[SLIM_MAX_RX_PORTS] = {0}; + u8 payload = 0; + u16 codec_port = 0; + int ret; + struct slim_ch prop; + struct wcd9xxx_ch *rx; + int size = ARRAY_SIZE(ch_h); + + /* Configure slave interface device */ + + list_for_each_entry(rx, wcd9xxx_ch_list, list) { + payload |= 1 << rx->shift; + if (ch_cnt < size) { + ch_h[ch_cnt] = rx->ch_h; + ch_cnt++; + pr_debug("list ch->ch_h %d ch->sph %d\n", + rx->ch_h, rx->sph); + } else { + pr_err("%s: allocated channel number %u is out of max rangae %d\n", + __func__, ch_cnt, + size); + ret = EINVAL; + goto err; + } + } + pr_debug("%s: ch_cnt[%d] rate=%d WATER_MARK_VAL %d\n", + __func__, ch_cnt, rate, WATER_MARK_VAL); + /* slim_define_ch api */ + prop.prot = SLIM_AUTO_ISO; + if ((rate == 44100) || (rate == 88200) || (rate == 176400) || + (rate == 352800)) { + prop.baser = SLIM_RATE_11025HZ; + prop.ratem = (rate/11025); + } else { + prop.baser = SLIM_RATE_4000HZ; + prop.ratem = (rate/4000); + } + prop.dataf = SLIM_CH_DATAF_NOT_DEFINED; + prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE; + prop.sampleszbits = bit_width; + + pr_debug("Before slim_define_ch:\n" + "ch_cnt %d,ch_h[0] %d ch_h[1] %d, grph %d\n", + ch_cnt, ch_h[0], ch_h[1], *grph); + ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt, + true, grph); + if (ret < 0) { + pr_err("%s: slim_define_ch failed ret[%d]\n", + __func__, ret); + goto err; + } + + list_for_each_entry(rx, wcd9xxx_ch_list, list) { + codec_port = rx->port; + pr_debug("%s: codec_port %d rx 0x%p, payload %d\n" + "sh_ch.rx_port_ch_reg_base0 0x%x\n" + "sh_ch.port_rx_cfg_reg_base 0x%x\n", + __func__, codec_port, rx, payload, + sh_ch.rx_port_ch_reg_base, + sh_ch.port_rx_cfg_reg_base); + + /* look for the valid port range and chose the + * payload accordingly + */ + /* write to interface device */ + ret = wcd9xxx_interface_reg_write(wcd9xxx, + SB_PGD_RX_PORT_MULTI_CHANNEL_0( + sh_ch.rx_port_ch_reg_base, codec_port), + payload); + + if (ret < 0) { + pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n", + __func__, + SB_PGD_RX_PORT_MULTI_CHANNEL_0( + sh_ch.rx_port_ch_reg_base, codec_port), + payload, ret); + goto err; + } + /* configure the slave port for water mark and enable*/ + ret = wcd9xxx_interface_reg_write(wcd9xxx, + SB_PGD_PORT_CFG_BYTE_ADDR( + sh_ch.port_rx_cfg_reg_base, codec_port), + WATER_MARK_VAL); + if (ret < 0) { + pr_err("%s:watermark set failure for port[%d] ret[%d]", + __func__, codec_port, ret); + } + + ret = slim_connect_sink(wcd9xxx->slim, &rx->sph, 1, rx->ch_h); + if (ret < 0) { + pr_err("%s: slim_connect_sink failed ret[%d]\n", + __func__, ret); + goto err_close_slim_sch; + } + } + /* slim_control_ch */ + ret = slim_control_ch(wcd9xxx->slim, *grph, SLIM_CH_ACTIVATE, + true); + if (ret < 0) { + pr_err("%s: slim_control_ch failed ret[%d]\n", + __func__, ret); + goto err_close_slim_sch; + } + return 0; + +err_close_slim_sch: + /* release all acquired handles */ + wcd9xxx_close_slim_sch_rx(wcd9xxx, wcd9xxx_ch_list, *grph); +err: + return ret; +} +EXPORT_SYMBOL(wcd9xxx_cfg_slim_sch_rx); + +/* Enable slimbus slave device for RX path */ +int wcd9xxx_cfg_slim_sch_tx(struct wcd9xxx *wcd9xxx, + struct list_head *wcd9xxx_ch_list, + unsigned int rate, unsigned int bit_width, + u16 *grph) +{ + u16 ch_cnt = 0; + u16 payload = 0; + u16 ch_h[SLIM_MAX_TX_PORTS] = {0}; + u16 codec_port; + int ret = 0; + struct wcd9xxx_ch *tx; + int size = ARRAY_SIZE(ch_h); + + struct slim_ch prop; + + list_for_each_entry(tx, wcd9xxx_ch_list, list) { + payload |= 1 << tx->shift; + if (ch_cnt < size) { + ch_h[ch_cnt] = tx->ch_h; + ch_cnt++; + } else { + pr_err("%s: allocated channel number %u is out of max rangae %d\n", + __func__, ch_cnt, + size); + ret = EINVAL; + goto err; + } + } + + /* slim_define_ch api */ + prop.prot = SLIM_AUTO_ISO; + prop.baser = SLIM_RATE_4000HZ; + prop.dataf = SLIM_CH_DATAF_NOT_DEFINED; + prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE; + prop.ratem = (rate/4000); + prop.sampleszbits = bit_width; + ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt, + true, grph); + if (ret < 0) { + pr_err("%s: slim_define_ch failed ret[%d]\n", + __func__, ret); + goto err; + } + + pr_debug("%s: ch_cnt[%d] rate[%d] bitwidth[%u]\n", __func__, ch_cnt, + rate, bit_width); + list_for_each_entry(tx, wcd9xxx_ch_list, list) { + codec_port = tx->port; + pr_debug("%s: codec_port %d tx 0x%p, payload 0x%x\n", + __func__, codec_port, tx, payload); + /* write to interface device */ + ret = wcd9xxx_interface_reg_write(wcd9xxx, + SB_PGD_TX_PORT_MULTI_CHANNEL_0(codec_port), + payload & 0x00FF); + if (ret < 0) { + pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n", + __func__, + SB_PGD_TX_PORT_MULTI_CHANNEL_0(codec_port), + payload, ret); + goto err; + } + /* ports 8,9 */ + ret = wcd9xxx_interface_reg_write(wcd9xxx, + SB_PGD_TX_PORT_MULTI_CHANNEL_1(codec_port), + (payload & 0xFF00)>>8); + if (ret < 0) { + pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n", + __func__, + SB_PGD_TX_PORT_MULTI_CHANNEL_1(codec_port), + payload, ret); + goto err; + } + /* configure the slave port for water mark and enable*/ + ret = wcd9xxx_interface_reg_write(wcd9xxx, + SB_PGD_PORT_CFG_BYTE_ADDR( + sh_ch.port_tx_cfg_reg_base, codec_port), + WATER_MARK_VAL); + if (ret < 0) { + pr_err("%s:watermark set failure for port[%d] ret[%d]", + __func__, codec_port, ret); + } + + ret = slim_connect_src(wcd9xxx->slim, tx->sph, tx->ch_h); + + if (ret < 0) { + pr_err("%s: slim_connect_src failed ret[%d]\n", + __func__, ret); + goto err; + } + } + /* slim_control_ch */ + ret = slim_control_ch(wcd9xxx->slim, *grph, SLIM_CH_ACTIVATE, + true); + if (ret < 0) { + pr_err("%s: slim_control_ch failed ret[%d]\n", + __func__, ret); + goto err; + } + return 0; +err: + /* release all acquired handles */ + wcd9xxx_close_slim_sch_tx(wcd9xxx, wcd9xxx_ch_list, *grph); + return ret; +} +EXPORT_SYMBOL(wcd9xxx_cfg_slim_sch_tx); + +int wcd9xxx_close_slim_sch_rx(struct wcd9xxx *wcd9xxx, + struct list_head *wcd9xxx_ch_list, u16 grph) +{ + u32 sph[SLIM_MAX_RX_PORTS] = {0}; + int ch_cnt = 0; + int ret = 0; + struct wcd9xxx_ch *rx; + + list_for_each_entry(rx, wcd9xxx_ch_list, list) + sph[ch_cnt++] = rx->sph; + + pr_debug("%s ch_cht %d, sph[0] %d sph[1] %d\n", __func__, ch_cnt, + sph[0], sph[1]); + + /* slim_control_ch (REMOVE) */ + pr_debug("%s before slim_control_ch grph %d\n", __func__, grph); + ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_REMOVE, true); + if (ret < 0) { + pr_err("%s: slim_control_ch failed ret[%d]\n", __func__, ret); + goto err; + } +err: + return ret; +} +EXPORT_SYMBOL(wcd9xxx_close_slim_sch_rx); + +int wcd9xxx_close_slim_sch_tx(struct wcd9xxx *wcd9xxx, + struct list_head *wcd9xxx_ch_list, + u16 grph) +{ + u32 sph[SLIM_MAX_TX_PORTS] = {0}; + int ret = 0; + int ch_cnt = 0; + struct wcd9xxx_ch *tx; + + pr_debug("%s\n", __func__); + list_for_each_entry(tx, wcd9xxx_ch_list, list) + sph[ch_cnt++] = tx->sph; + + pr_debug("%s ch_cht %d, sph[0] %d sph[1] %d\n", + __func__, ch_cnt, sph[0], sph[1]); + /* slim_control_ch (REMOVE) */ + ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_REMOVE, true); + if (ret < 0) { + pr_err("%s: slim_control_ch failed ret[%d]\n", + __func__, ret); + goto err; + } +err: + return ret; +} +EXPORT_SYMBOL(wcd9xxx_close_slim_sch_tx); + +int wcd9xxx_get_slave_port(unsigned int ch_num) +{ + int ret = 0; + + ret = (ch_num - BASE_CH_NUM); + pr_debug("%s: ch_num[%d] slave port[%d]\n", __func__, ch_num, ret); + if (ret < 0) { + pr_err("%s: Error:- Invalid slave port found = %d\n", + __func__, ret); + return -EINVAL; + } + return ret; +} +EXPORT_SYMBOL(wcd9xxx_get_slave_port); + +int wcd9xxx_disconnect_port(struct wcd9xxx *wcd9xxx, + struct list_head *wcd9xxx_ch_list, u16 grph) +{ + u32 sph[SLIM_MAX_TX_PORTS + SLIM_MAX_RX_PORTS] = {0}; + int ch_cnt = 0; + int ret = 0; + struct wcd9xxx_ch *slim_ch; + + list_for_each_entry(slim_ch, wcd9xxx_ch_list, list) + sph[ch_cnt++] = slim_ch->sph; + + /* slim_disconnect_port */ + ret = slim_disconnect_ports(wcd9xxx->slim, sph, ch_cnt); + if (ret < 0) { + pr_err("%s: slim_disconnect_ports failed ret[%d]\n", + __func__, ret); + } + return ret; +} +EXPORT_SYMBOL(wcd9xxx_disconnect_port); + +/* This function is called with mutex acquired */ +int wcd9xxx_rx_vport_validation(u32 port_id, + struct list_head *codec_dai_list) +{ + struct wcd9xxx_ch *ch; + int ret = 0; + + pr_debug("%s: port_id %u\n", __func__, port_id); + + list_for_each_entry(ch, + codec_dai_list, list) { + pr_debug("%s: ch->port %u\n", __func__, ch->port); + if (ch->port == port_id) { + ret = -EINVAL; + break; + } + } + return ret; +} +EXPORT_SYMBOL(wcd9xxx_rx_vport_validation); + + +/* This function is called with mutex acquired */ +int wcd9xxx_tx_vport_validation(u32 table, u32 port_id, + struct wcd9xxx_codec_dai_data *codec_dai, + u32 num_codec_dais) +{ + struct wcd9xxx_ch *ch; + int ret = 0; + u32 index; + unsigned long vtable = table; + u32 size = sizeof(table) * BITS_PER_BYTE; + + pr_debug("%s: vtable 0x%lx port_id %u size %d\n", __func__, + vtable, port_id, size); + for_each_set_bit(index, &vtable, size) { + if (index < num_codec_dais) { + list_for_each_entry(ch, + &codec_dai[index].wcd9xxx_ch_list, + list) { + pr_debug("%s: index %u ch->port %u vtable 0x%lx\n", + __func__, index, ch->port, + vtable); + if (ch->port == port_id) { + pr_err("%s: TX%u is used by AIF%u_CAP Mixer\n", + __func__, port_id + 1, + (index + 1)/2); + ret = -EINVAL; + break; + } + } + } else { + pr_err("%s: Invalid index %d of codec dai", + __func__, index); + ret = -EINVAL; + } + if (ret) + break; + } + return ret; +} +EXPORT_SYMBOL(wcd9xxx_tx_vport_validation); diff --git a/drivers/mfd/wcd9xxx-utils.c b/drivers/mfd/wcd9xxx-utils.c new file mode 100644 index 000000000000..8d3d4ad4bbb5 --- /dev/null +++ b/drivers/mfd/wcd9xxx-utils.c @@ -0,0 +1,1198 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define REG_BYTES 2 +#define VAL_BYTES 1 +/* + * Page Register Address that APP Proc uses to + * access WCD9335 Codec registers is identified + * as 0x00 + */ +#define PAGE_REG_ADDR 0x00 + +static enum wcd9xxx_intf_status wcd9xxx_intf = -1; + +static struct mfd_cell tavil_devs[] = { + { + .name = "qcom-wcd-pinctrl", + .of_compatible = "qcom,wcd-pinctrl", + }, + { + .name = "tavil_codec", + }, +}; + +static struct mfd_cell tasha_devs[] = { + { + .name = "tasha_codec", + }, +}; + +static struct mfd_cell tomtom_devs[] = { + { + .name = "tomtom_codec", + }, +}; + +static int wcd9xxx_read_of_property_u32(struct device *dev, const char *name, + u32 *val) +{ + int rc = 0; + + rc = of_property_read_u32(dev->of_node, name, val); + if (rc) + dev_err(dev, "%s: Looking up %s property in node %s failed", + __func__, name, dev->of_node->full_name); + + return rc; +} + +static void wcd9xxx_dt_parse_micbias_info(struct device *dev, + struct wcd9xxx_micbias_setting *mb) +{ + u32 prop_val; + int rc; + + if (of_find_property(dev->of_node, "qcom,cdc-micbias-ldoh-v", NULL)) { + rc = wcd9xxx_read_of_property_u32(dev, + "qcom,cdc-micbias-ldoh-v", + &prop_val); + if (!rc) + mb->ldoh_v = (u8)prop_val; + } + + /* MB1 */ + if (of_find_property(dev->of_node, "qcom,cdc-micbias-cfilt1-mv", + NULL)) { + rc = wcd9xxx_read_of_property_u32(dev, + "qcom,cdc-micbias-cfilt1-mv", + &prop_val); + if (!rc) + mb->cfilt1_mv = prop_val; + + rc = wcd9xxx_read_of_property_u32(dev, + "qcom,cdc-micbias1-cfilt-sel", + &prop_val); + if (!rc) + mb->bias1_cfilt_sel = (u8)prop_val; + + } else if (of_find_property(dev->of_node, "qcom,cdc-micbias1-mv", + NULL)) { + rc = wcd9xxx_read_of_property_u32(dev, + "qcom,cdc-micbias1-mv", + &prop_val); + if (!rc) + mb->micb1_mv = prop_val; + } else { + dev_info(dev, "%s: Micbias1 DT property not found\n", + __func__); + } + + /* MB2 */ + if (of_find_property(dev->of_node, "qcom,cdc-micbias-cfilt2-mv", + NULL)) { + rc = wcd9xxx_read_of_property_u32(dev, + "qcom,cdc-micbias-cfilt2-mv", + &prop_val); + if (!rc) + mb->cfilt2_mv = prop_val; + + rc = wcd9xxx_read_of_property_u32(dev, + "qcom,cdc-micbias2-cfilt-sel", + &prop_val); + if (!rc) + mb->bias2_cfilt_sel = (u8)prop_val; + + } else if (of_find_property(dev->of_node, "qcom,cdc-micbias2-mv", + NULL)) { + rc = wcd9xxx_read_of_property_u32(dev, + "qcom,cdc-micbias2-mv", + &prop_val); + if (!rc) + mb->micb2_mv = prop_val; + } else { + dev_info(dev, "%s: Micbias2 DT property not found\n", + __func__); + } + + /* MB3 */ + if (of_find_property(dev->of_node, "qcom,cdc-micbias-cfilt3-mv", + NULL)) { + rc = wcd9xxx_read_of_property_u32(dev, + "qcom,cdc-micbias-cfilt3-mv", + &prop_val); + if (!rc) + mb->cfilt3_mv = prop_val; + + rc = wcd9xxx_read_of_property_u32(dev, + "qcom,cdc-micbias3-cfilt-sel", + &prop_val); + if (!rc) + mb->bias3_cfilt_sel = (u8)prop_val; + + } else if (of_find_property(dev->of_node, "qcom,cdc-micbias3-mv", + NULL)) { + rc = wcd9xxx_read_of_property_u32(dev, + "qcom,cdc-micbias3-mv", + &prop_val); + if (!rc) + mb->micb3_mv = prop_val; + } else { + dev_info(dev, "%s: Micbias3 DT property not found\n", + __func__); + } + + /* MB4 */ + if (of_find_property(dev->of_node, "qcom,cdc-micbias4-cfilt-sel", + NULL)) { + rc = wcd9xxx_read_of_property_u32(dev, + "qcom,cdc-micbias4-cfilt-sel", + &prop_val); + if (!rc) + mb->bias4_cfilt_sel = (u8)prop_val; + + } else if (of_find_property(dev->of_node, "qcom,cdc-micbias4-mv", + NULL)) { + rc = wcd9xxx_read_of_property_u32(dev, + "qcom,cdc-micbias4-mv", + &prop_val); + if (!rc) + mb->micb4_mv = prop_val; + } else { + dev_info(dev, "%s: Micbias4 DT property not found\n", + __func__); + } + + mb->bias1_cap_mode = + (of_property_read_bool(dev->of_node, "qcom,cdc-micbias1-ext-cap") ? + MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); + mb->bias2_cap_mode = + (of_property_read_bool(dev->of_node, "qcom,cdc-micbias2-ext-cap") ? + MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); + mb->bias3_cap_mode = + (of_property_read_bool(dev->of_node, "qcom,cdc-micbias3-ext-cap") ? + MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); + mb->bias4_cap_mode = + (of_property_read_bool(dev->of_node, "qcom,cdc-micbias4-ext-cap") ? + MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); + + mb->bias2_is_headset_only = + of_property_read_bool(dev->of_node, + "qcom,cdc-micbias2-headset-only"); + + /* Print micbias info */ + dev_dbg(dev, "%s: ldoh_v %u cfilt1_mv %u cfilt2_mv %u cfilt3_mv %u", + __func__, (u32)mb->ldoh_v, (u32)mb->cfilt1_mv, + (u32)mb->cfilt2_mv, (u32)mb->cfilt3_mv); + + dev_dbg(dev, "%s: micb1_mv %u micb2_mv %u micb3_mv %u micb4_mv %u", + __func__, mb->micb1_mv, mb->micb2_mv, + mb->micb3_mv, mb->micb4_mv); + + dev_dbg(dev, "%s: bias1_cfilt_sel %u bias2_cfilt_sel %u\n", + __func__, (u32)mb->bias1_cfilt_sel, (u32)mb->bias2_cfilt_sel); + + dev_dbg(dev, "%s: bias3_cfilt_sel %u bias4_cfilt_sel %u\n", + __func__, (u32)mb->bias3_cfilt_sel, (u32)mb->bias4_cfilt_sel); + + dev_dbg(dev, "%s: bias1_ext_cap %d bias2_ext_cap %d\n", + __func__, mb->bias1_cap_mode, mb->bias2_cap_mode); + + dev_dbg(dev, "%s: bias3_ext_cap %d bias4_ext_cap %d\n", + __func__, mb->bias3_cap_mode, mb->bias4_cap_mode); + + dev_dbg(dev, "%s: bias2_is_headset_only %d\n", + __func__, mb->bias2_is_headset_only); +} + +/* + * wcd9xxx_validate_dmic_sample_rate: + * Given the dmic_sample_rate and mclk rate, validate the + * dmic_sample_rate. If dmic rate is found to be invalid, + * assign the dmic rate as undefined, so individual codec + * drivers can use their own defaults + * @dev: the device for which the dmic is to be configured + * @dmic_sample_rate: The input dmic_sample_rate + * @mclk_rate: The input codec mclk rate + * @dmic_rate_type: String to indicate the type of dmic sample + * rate, used for debug/error logging. + */ +static u32 wcd9xxx_validate_dmic_sample_rate(struct device *dev, + u32 dmic_sample_rate, u32 mclk_rate, + const char *dmic_rate_type) +{ + u32 div_factor; + + if (dmic_sample_rate == WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED || + mclk_rate % dmic_sample_rate != 0) + goto undefined_rate; + + div_factor = mclk_rate / dmic_sample_rate; + + switch (div_factor) { + case 2: + case 3: + case 4: + case 8: + case 16: + /* Valid dmic DIV factors */ + dev_dbg(dev, "%s: DMIC_DIV = %u, mclk_rate = %u\n", + __func__, div_factor, mclk_rate); + break; + case 6: + /* + * DIV 6 is valid for both 9.6MHz and 12.288MHz + * MCLK on Tavil. Older codecs support DIV6 only + * for 12.288MHz MCLK. + */ + if ((mclk_rate == WCD9XXX_MCLK_CLK_9P6HZ) && + (of_device_is_compatible(dev->of_node, + "qcom,tavil-slim-pgd"))) + dev_dbg(dev, "%s: DMIC_DIV = %u, mclk_rate = %u\n", + __func__, div_factor, mclk_rate); + else if (mclk_rate != WCD9XXX_MCLK_CLK_12P288MHZ) + goto undefined_rate; + break; + default: + /* Any other DIV factor is invalid */ + goto undefined_rate; + } + + return dmic_sample_rate; + +undefined_rate: + dev_dbg(dev, "%s: Invalid %s = %d, for mclk %d\n", + __func__, dmic_rate_type, dmic_sample_rate, mclk_rate); + dmic_sample_rate = WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED; + + return dmic_sample_rate; +} + +/* + * wcd9xxx_populate_dt_data: + * Parse device tree properties for the given codec device + * + * @dev: pointer to codec device + * + * Returns pointer to the platform data resulting from parsing + * device tree. + */ +struct wcd9xxx_pdata *wcd9xxx_populate_dt_data(struct device *dev) +{ + struct wcd9xxx_pdata *pdata; + u32 dmic_sample_rate = WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED; + u32 mad_dmic_sample_rate = WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED; + u32 ecpp_dmic_sample_rate = WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED; + u32 dmic_clk_drive = WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED; + u32 prop_val; + int rc = 0; + + if (!dev || !dev->of_node) + return NULL; + + pdata = devm_kzalloc(dev, sizeof(struct wcd9xxx_pdata), + GFP_KERNEL); + if (!pdata) + return NULL; + + /* Parse power supplies */ + msm_cdc_get_power_supplies(dev, &pdata->regulator, + &pdata->num_supplies); + if (!pdata->regulator || (pdata->num_supplies <= 0)) { + dev_err(dev, "%s: no power supplies defined for codec\n", + __func__); + goto err_power_sup; + } + + /* Parse micbias info */ + wcd9xxx_dt_parse_micbias_info(dev, &pdata->micbias); + + pdata->wcd_rst_np = of_parse_phandle(dev->of_node, + "qcom,wcd-rst-gpio-node", 0); + if (!pdata->wcd_rst_np) { + dev_err(dev, "%s: Looking up %s property in node %s failed\n", + __func__, "qcom,wcd-rst-gpio-node", + dev->of_node->full_name); + goto err_parse_dt_prop; + } + + if (!(wcd9xxx_read_of_property_u32(dev, "qcom,cdc-mclk-clk-rate", + &prop_val))) + pdata->mclk_rate = prop_val; + + if (pdata->mclk_rate != WCD9XXX_MCLK_CLK_9P6HZ && + pdata->mclk_rate != WCD9XXX_MCLK_CLK_12P288MHZ) { + dev_err(dev, "%s: Invalid mclk_rate = %u\n", __func__, + pdata->mclk_rate); + goto err_parse_dt_prop; + } + + if (!(wcd9xxx_read_of_property_u32(dev, "qcom,cdc-dmic-sample-rate", + &prop_val))) + dmic_sample_rate = prop_val; + + pdata->dmic_sample_rate = wcd9xxx_validate_dmic_sample_rate(dev, + dmic_sample_rate, + pdata->mclk_rate, + "audio_dmic_rate"); + if (!(wcd9xxx_read_of_property_u32(dev, "qcom,cdc-mad-dmic-rate", + &prop_val))) + mad_dmic_sample_rate = prop_val; + + pdata->mad_dmic_sample_rate = wcd9xxx_validate_dmic_sample_rate(dev, + mad_dmic_sample_rate, + pdata->mclk_rate, + "mad_dmic_rate"); + + if (of_find_property(dev->of_node, "qcom,cdc-ecpp-dmic-rate", NULL)) { + rc = wcd9xxx_read_of_property_u32(dev, + "qcom,cdc-ecpp-dmic-rate", + &prop_val); + if (!rc) + ecpp_dmic_sample_rate = prop_val; + } + + pdata->ecpp_dmic_sample_rate = wcd9xxx_validate_dmic_sample_rate(dev, + ecpp_dmic_sample_rate, + pdata->mclk_rate, + "ecpp_dmic_rate"); + + if (!(of_property_read_u32(dev->of_node, + "qcom,cdc-dmic-clk-drv-strength", + &prop_val))) { + dmic_clk_drive = prop_val; + + if (dmic_clk_drive != 2 && dmic_clk_drive != 4 && + dmic_clk_drive != 8 && dmic_clk_drive != 16) + dev_err(dev, "Invalid cdc-dmic-clk-drv-strength %d\n", + dmic_clk_drive); + } + + pdata->dmic_clk_drv = dmic_clk_drive; + + return pdata; + +err_parse_dt_prop: + devm_kfree(dev, pdata->regulator); + pdata->regulator = NULL; + pdata->num_supplies = 0; +err_power_sup: + devm_kfree(dev, pdata); + return NULL; +} +EXPORT_SYMBOL(wcd9xxx_populate_dt_data); + +static bool is_wcd9xxx_reg_power_down(struct wcd9xxx *wcd9xxx, u16 rreg) +{ + bool ret = false; + int i; + struct wcd9xxx_power_region *wcd9xxx_pwr; + + if (!wcd9xxx) + return ret; + + for (i = 0; i < WCD9XXX_MAX_PWR_REGIONS; i++) { + wcd9xxx_pwr = wcd9xxx->wcd9xxx_pwr[i]; + if (!wcd9xxx_pwr) + continue; + if (((wcd9xxx_pwr->pwr_collapse_reg_min == 0) && + (wcd9xxx_pwr->pwr_collapse_reg_max == 0)) || + (wcd9xxx_pwr->power_state == + WCD_REGION_POWER_COLLAPSE_REMOVE)) + ret = false; + else if (((wcd9xxx_pwr->power_state == + WCD_REGION_POWER_DOWN) || + (wcd9xxx_pwr->power_state == + WCD_REGION_POWER_COLLAPSE_BEGIN)) && + (rreg >= wcd9xxx_pwr->pwr_collapse_reg_min) && + (rreg <= wcd9xxx_pwr->pwr_collapse_reg_max)) + ret = true; + } + return ret; +} + +/* + * wcd9xxx_page_write: + * Retrieve page number from register and + * write that page number to the page address. + * Called under io_lock acquisition. + * + * @wcd9xxx: pointer to wcd9xxx + * @reg: Register address from which page number is retrieved + * + * Returns 0 for success and negative error code for failure. + */ +int wcd9xxx_page_write(struct wcd9xxx *wcd9xxx, unsigned short *reg) +{ + int ret = 0; + unsigned short c_reg, reg_addr; + u8 pg_num, prev_pg_num; + + if (wcd9xxx->type != WCD9335 && wcd9xxx->type != WCD934X) + return ret; + + c_reg = *reg; + pg_num = c_reg >> 8; + reg_addr = c_reg & 0xff; + if (wcd9xxx->prev_pg_valid) { + prev_pg_num = wcd9xxx->prev_pg; + if (prev_pg_num != pg_num) { + ret = wcd9xxx->write_dev( + wcd9xxx, PAGE_REG_ADDR, 1, + (void *) &pg_num, false); + if (ret < 0) + pr_err("page write error, pg_num: 0x%x\n", + pg_num); + else { + wcd9xxx->prev_pg = pg_num; + dev_dbg(wcd9xxx->dev, "%s: Page 0x%x Write to 0x00\n", + __func__, pg_num); + } + } + } else { + ret = wcd9xxx->write_dev( + wcd9xxx, PAGE_REG_ADDR, 1, (void *) &pg_num, + false); + if (ret < 0) + pr_err("page write error, pg_num: 0x%x\n", pg_num); + else { + wcd9xxx->prev_pg = pg_num; + wcd9xxx->prev_pg_valid = true; + dev_dbg(wcd9xxx->dev, "%s: Page 0x%x Write to 0x00\n", + __func__, pg_num); + } + } + *reg = reg_addr; + return ret; +} +EXPORT_SYMBOL(wcd9xxx_page_write); + +static int regmap_bus_read(void *context, const void *reg, size_t reg_size, + void *val, size_t val_size) +{ + struct device *dev = context; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(dev); + unsigned short c_reg, rreg; + int ret, i; + + if (!wcd9xxx) { + dev_err(dev, "%s: wcd9xxx is NULL\n", __func__); + return -EINVAL; + } + if (!reg || !val) { + dev_err(dev, "%s: reg or val is NULL\n", __func__); + return -EINVAL; + } + + if (reg_size != REG_BYTES) { + dev_err(dev, "%s: register size %zd bytes, not supported\n", + __func__, reg_size); + return -EINVAL; + } + + mutex_lock(&wcd9xxx->io_lock); + c_reg = *(u16 *)reg; + rreg = c_reg; + + if (is_wcd9xxx_reg_power_down(wcd9xxx, rreg)) { + ret = 0; + for (i = 0; i < val_size; i++) + ((u8 *)val)[i] = 0; + goto err; + } + ret = wcd9xxx_page_write(wcd9xxx, &c_reg); + if (ret) + goto err; + ret = wcd9xxx->read_dev(wcd9xxx, c_reg, val_size, val, false); + if (ret < 0) + dev_err(dev, "%s: Codec read failed (%d), reg: 0x%x, size:%zd\n", + __func__, ret, rreg, val_size); + else { + for (i = 0; i < val_size; i++) + dev_dbg(dev, "%s: Read 0x%02x from 0x%x\n", + __func__, ((u8 *)val)[i], rreg + i); + } +err: + mutex_unlock(&wcd9xxx->io_lock); + + return ret; +} + +static int regmap_bus_gather_write(void *context, + const void *reg, size_t reg_size, + const void *val, size_t val_size) +{ + struct device *dev = context; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(dev); + unsigned short c_reg, rreg; + int ret, i; + + if (!wcd9xxx) { + dev_err(dev, "%s: wcd9xxx is NULL\n", __func__); + return -EINVAL; + } + if (!reg || !val) { + dev_err(dev, "%s: reg or val is NULL\n", __func__); + return -EINVAL; + } + if (reg_size != REG_BYTES) { + dev_err(dev, "%s: register size %zd bytes, not supported\n", + __func__, reg_size); + return -EINVAL; + } + mutex_lock(&wcd9xxx->io_lock); + c_reg = *(u16 *)reg; + rreg = c_reg; + + if (is_wcd9xxx_reg_power_down(wcd9xxx, rreg)) { + ret = 0; + goto err; + } + ret = wcd9xxx_page_write(wcd9xxx, &c_reg); + if (ret) + goto err; + + for (i = 0; i < val_size; i++) + dev_dbg(dev, "Write %02x to 0x%x\n", ((u8 *)val)[i], + rreg + i); + + ret = wcd9xxx->write_dev(wcd9xxx, c_reg, val_size, (void *) val, + false); + if (ret < 0) + dev_err(dev, "%s: Codec write failed (%d), reg:0x%x, size:%zd\n", + __func__, ret, rreg, val_size); + +err: + mutex_unlock(&wcd9xxx->io_lock); + return ret; +} + +static int regmap_bus_write(void *context, const void *data, size_t count) +{ + struct device *dev = context; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(dev); + + if (!wcd9xxx) + return -EINVAL; + + WARN_ON(count < REG_BYTES); + + if (count > (REG_BYTES + VAL_BYTES)) { + if (wcd9xxx->multi_reg_write) + return wcd9xxx->multi_reg_write(wcd9xxx, + data, count); + } else + return regmap_bus_gather_write(context, data, REG_BYTES, + data + REG_BYTES, + count - REG_BYTES); + + dev_err(dev, "%s: bus multi reg write failure\n", __func__); + + return -EINVAL; +} + +static struct regmap_bus regmap_bus_config = { + .write = regmap_bus_write, + .gather_write = regmap_bus_gather_write, + .read = regmap_bus_read, + .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, + .val_format_endian_default = REGMAP_ENDIAN_NATIVE, +}; + +/* + * wcd9xxx_regmap_init: + * Initialize wcd9xxx register map + * + * @dev: pointer to wcd device + * @config: pointer to register map config + * + * Returns pointer to regmap structure for success + * or NULL in case of failure. + */ +struct regmap *wcd9xxx_regmap_init(struct device *dev, + const struct regmap_config *config) +{ + return devm_regmap_init(dev, ®map_bus_config, dev, config); +} +EXPORT_SYMBOL(wcd9xxx_regmap_init); + +/* + * wcd9xxx_reset: + * Reset wcd9xxx codec + * + * @dev: pointer to wcd device + * + * Returns 0 for success or negative error code in case of failure + */ +int wcd9xxx_reset(struct device *dev) +{ + struct wcd9xxx *wcd9xxx; + int rc; + int value; + + if (!dev) + return -ENODEV; + + wcd9xxx = dev_get_drvdata(dev); + if (!wcd9xxx) + return -EINVAL; + + if (!wcd9xxx->wcd_rst_np) { + dev_err(dev, "%s: reset gpio device node not specified\n", + __func__); + return -EINVAL; + } + + value = msm_cdc_pinctrl_get_state(wcd9xxx->wcd_rst_np); + if (value > 0) { + wcd9xxx->avoid_cdc_rstlow = 1; + return 0; + } + + rc = msm_cdc_pinctrl_select_sleep_state(wcd9xxx->wcd_rst_np); + if (rc) { + dev_err(dev, "%s: wcd sleep state request fail!\n", + __func__); + return rc; + } + + /* 20ms sleep required after pulling the reset gpio to LOW */ + msleep(20); + + rc = msm_cdc_pinctrl_select_active_state(wcd9xxx->wcd_rst_np); + if (rc) { + dev_err(dev, "%s: wcd active state request fail!\n", + __func__); + return rc; + } + msleep(20); + + return rc; +} +EXPORT_SYMBOL(wcd9xxx_reset); + +/* + * wcd9xxx_reset_low: + * Pull the wcd9xxx codec reset_n to low + * + * @dev: pointer to wcd device + * + * Returns 0 for success or negative error code in case of failure + */ +int wcd9xxx_reset_low(struct device *dev) +{ + struct wcd9xxx *wcd9xxx; + int rc; + + if (!dev) + return -ENODEV; + + wcd9xxx = dev_get_drvdata(dev); + if (!wcd9xxx) + return -EINVAL; + + if (!wcd9xxx->wcd_rst_np) { + dev_err(dev, "%s: reset gpio device node not specified\n", + __func__); + return -EINVAL; + } + if (wcd9xxx->avoid_cdc_rstlow) { + wcd9xxx->avoid_cdc_rstlow = 0; + dev_dbg(dev, "%s: avoid pull down of reset GPIO\n", __func__); + return 0; + } + + rc = msm_cdc_pinctrl_select_sleep_state(wcd9xxx->wcd_rst_np); + if (rc) + dev_err(dev, "%s: wcd sleep state request fail!\n", + __func__); + + return rc; +} +EXPORT_SYMBOL(wcd9xxx_reset_low); + +/* + * wcd9xxx_bringup: + * Toggle reset analog and digital cores of wcd9xxx codec + * + * @dev: pointer to wcd device + * + * Returns 0 for success or negative error code in case of failure + */ +int wcd9xxx_bringup(struct device *dev) +{ + struct wcd9xxx *wcd9xxx; + int rc; + codec_bringup_fn cdc_bup_fn; + + if (!dev) + return -ENODEV; + + wcd9xxx = dev_get_drvdata(dev); + if (!wcd9xxx) + return -EINVAL; + + cdc_bup_fn = wcd9xxx_bringup_fn(wcd9xxx->type); + if (!cdc_bup_fn) { + dev_err(dev, "%s: Codec bringup fn NULL!\n", + __func__); + return -EINVAL; + } + rc = cdc_bup_fn(wcd9xxx); + if (rc) + dev_err(dev, "%s: Codec bringup error, rc: %d\n", + __func__, rc); + + return rc; +} +EXPORT_SYMBOL(wcd9xxx_bringup); + +/* + * wcd9xxx_bringup: + * Set analog and digital cores of wcd9xxx codec in reset state + * + * @dev: pointer to wcd device + * + * Returns 0 for success or negative error code in case of failure + */ +int wcd9xxx_bringdown(struct device *dev) +{ + struct wcd9xxx *wcd9xxx; + int rc; + codec_bringdown_fn cdc_bdown_fn; + + if (!dev) + return -ENODEV; + + wcd9xxx = dev_get_drvdata(dev); + if (!wcd9xxx) + return -EINVAL; + + cdc_bdown_fn = wcd9xxx_bringdown_fn(wcd9xxx->type); + if (!cdc_bdown_fn) { + dev_err(dev, "%s: Codec bring down fn NULL!\n", + __func__); + return -EINVAL; + } + rc = cdc_bdown_fn(wcd9xxx); + if (rc) + dev_err(dev, "%s: Codec bring down error, rc: %d\n", + __func__, rc); + + return rc; +} +EXPORT_SYMBOL(wcd9xxx_bringdown); + +/* + * wcd9xxx_get_codec_info: + * Fill codec specific information like interrupts, version + * + * @dev: pointer to wcd device + * + * Returns 0 for success or negative error code in case of failure + */ +int wcd9xxx_get_codec_info(struct device *dev) +{ + struct wcd9xxx *wcd9xxx; + int rc; + codec_type_fn cdc_type_fn; + struct wcd9xxx_codec_type *cinfo; + + if (!dev) + return -ENODEV; + + wcd9xxx = dev_get_drvdata(dev); + if (!wcd9xxx) + return -EINVAL; + + cdc_type_fn = wcd9xxx_get_codec_info_fn(wcd9xxx->type); + if (!cdc_type_fn) { + dev_err(dev, "%s: Codec fill type fn NULL!\n", + __func__); + return -EINVAL; + } + + cinfo = wcd9xxx->codec_type; + if (!cinfo) + return -EINVAL; + + rc = cdc_type_fn(wcd9xxx, cinfo); + if (rc) { + dev_err(dev, "%s: Codec type fill failed, rc:%d\n", + __func__, rc); + return rc; + + } + + switch (wcd9xxx->type) { + case WCD934X: + cinfo->dev = tavil_devs; + cinfo->size = ARRAY_SIZE(tavil_devs); + break; + case WCD9335: + cinfo->dev = tasha_devs; + cinfo->size = ARRAY_SIZE(tasha_devs); + break; + case WCD9330: + cinfo->dev = tomtom_devs; + cinfo->size = ARRAY_SIZE(tomtom_devs); + break; + default: + cinfo->dev = NULL; + cinfo->size = 0; + break; + } + + return rc; +} +EXPORT_SYMBOL(wcd9xxx_get_codec_info); + +/* + * wcd9xxx_core_irq_init: + * Initialize wcd9xxx codec irq instance + * + * @wcd9xxx_core_res: pointer to wcd core resource + * + * Returns 0 for success or negative error code in case of failure + */ +int wcd9xxx_core_irq_init( + struct wcd9xxx_core_resource *wcd9xxx_core_res) +{ + int ret = 0; + + if (!wcd9xxx_core_res) + return -EINVAL; + + if (wcd9xxx_core_res->irq != 1) { + ret = wcd9xxx_irq_init(wcd9xxx_core_res); + if (ret) + pr_err("IRQ initialization failed\n"); + } + + return ret; +} +EXPORT_SYMBOL(wcd9xxx_core_irq_init); + +/* + * wcd9xxx_assign_irq: + * Assign irq and irq_base to wcd9xxx core resource + * + * @wcd9xxx_core_res: pointer to wcd core resource + * @irq: irq number + * @irq_base: base irq number + * + * Returns 0 for success or negative error code in case of failure + */ +int wcd9xxx_assign_irq( + struct wcd9xxx_core_resource *wcd9xxx_core_res, + unsigned int irq, + unsigned int irq_base) +{ + if (!wcd9xxx_core_res) + return -EINVAL; + + wcd9xxx_core_res->irq = irq; + wcd9xxx_core_res->irq_base = irq_base; + + return 0; +} +EXPORT_SYMBOL(wcd9xxx_assign_irq); + +/* + * wcd9xxx_core_res_init: + * Initialize wcd core resource instance + * + * @wcd9xxx_core_res: pointer to wcd core resource + * @num_irqs: number of irqs for wcd9xxx core + * @num_irq_regs: number of irq registers + * @wcd_regmap: pointer to the wcd register map + * + * Returns 0 for success or negative error code in case of failure + */ +int wcd9xxx_core_res_init( + struct wcd9xxx_core_resource *wcd9xxx_core_res, + int num_irqs, int num_irq_regs, struct regmap *wcd_regmap) +{ + if (!wcd9xxx_core_res || !wcd_regmap) + return -EINVAL; + + mutex_init(&wcd9xxx_core_res->pm_lock); + wcd9xxx_core_res->wlock_holders = 0; + wcd9xxx_core_res->pm_state = WCD9XXX_PM_SLEEPABLE; + init_waitqueue_head(&wcd9xxx_core_res->pm_wq); + pm_qos_add_request(&wcd9xxx_core_res->pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + PM_QOS_DEFAULT_VALUE); + + wcd9xxx_core_res->num_irqs = num_irqs; + wcd9xxx_core_res->num_irq_regs = num_irq_regs; + wcd9xxx_core_res->wcd_core_regmap = wcd_regmap; + + pr_info("%s: num_irqs = %d, num_irq_regs = %d\n", + __func__, wcd9xxx_core_res->num_irqs, + wcd9xxx_core_res->num_irq_regs); + + return 0; +} +EXPORT_SYMBOL(wcd9xxx_core_res_init); + +/* + * wcd9xxx_core_res_deinit: + * Deinit wcd core resource instance + * + * @wcd9xxx_core_res: pointer to wcd core resource + */ +void wcd9xxx_core_res_deinit(struct wcd9xxx_core_resource *wcd9xxx_core_res) +{ + if (!wcd9xxx_core_res) + return; + + pm_qos_remove_request(&wcd9xxx_core_res->pm_qos_req); + mutex_destroy(&wcd9xxx_core_res->pm_lock); +} +EXPORT_SYMBOL(wcd9xxx_core_res_deinit); + +/* + * wcd9xxx_pm_cmpxchg: + * Check old state and exchange with pm new state + * if old state matches with current state + * + * @wcd9xxx_core_res: pointer to wcd core resource + * @o: pm old state + * @n: pm new state + * + * Returns old state + */ +enum wcd9xxx_pm_state wcd9xxx_pm_cmpxchg( + struct wcd9xxx_core_resource *wcd9xxx_core_res, + enum wcd9xxx_pm_state o, + enum wcd9xxx_pm_state n) +{ + enum wcd9xxx_pm_state old; + + if (!wcd9xxx_core_res) + return o; + + mutex_lock(&wcd9xxx_core_res->pm_lock); + old = wcd9xxx_core_res->pm_state; + if (old == o) + wcd9xxx_core_res->pm_state = n; + mutex_unlock(&wcd9xxx_core_res->pm_lock); + + return old; +} +EXPORT_SYMBOL(wcd9xxx_pm_cmpxchg); + +/* + * wcd9xxx_core_res_suspend: + * Suspend callback function for wcd9xxx core + * + * @wcd9xxx_core_res: pointer to wcd core resource + * @pm_message_t: pm message + * + * Returns 0 for success or negative error code for failure/busy + */ +int wcd9xxx_core_res_suspend( + struct wcd9xxx_core_resource *wcd9xxx_core_res, + pm_message_t pmesg) +{ + int ret = 0; + + pr_debug("%s: enter\n", __func__); + /* + * pm_qos_update_request() can be called after this suspend chain call + * started. thus suspend can be called while lock is being held + */ + mutex_lock(&wcd9xxx_core_res->pm_lock); + if (wcd9xxx_core_res->pm_state == WCD9XXX_PM_SLEEPABLE) { + pr_debug("%s: suspending system, state %d, wlock %d\n", + __func__, wcd9xxx_core_res->pm_state, + wcd9xxx_core_res->wlock_holders); + wcd9xxx_core_res->pm_state = WCD9XXX_PM_ASLEEP; + } else if (wcd9xxx_core_res->pm_state == WCD9XXX_PM_AWAKE) { + /* + * unlock to wait for pm_state == WCD9XXX_PM_SLEEPABLE + * then set to WCD9XXX_PM_ASLEEP + */ + pr_debug("%s: waiting to suspend system, state %d, wlock %d\n", + __func__, wcd9xxx_core_res->pm_state, + wcd9xxx_core_res->wlock_holders); + mutex_unlock(&wcd9xxx_core_res->pm_lock); + if (!(wait_event_timeout(wcd9xxx_core_res->pm_wq, + wcd9xxx_pm_cmpxchg(wcd9xxx_core_res, + WCD9XXX_PM_SLEEPABLE, + WCD9XXX_PM_ASLEEP) == + WCD9XXX_PM_SLEEPABLE, + HZ))) { + pr_debug("%s: suspend failed state %d, wlock %d\n", + __func__, wcd9xxx_core_res->pm_state, + wcd9xxx_core_res->wlock_holders); + ret = -EBUSY; + } else { + pr_debug("%s: done, state %d, wlock %d\n", __func__, + wcd9xxx_core_res->pm_state, + wcd9xxx_core_res->wlock_holders); + } + mutex_lock(&wcd9xxx_core_res->pm_lock); + } else if (wcd9xxx_core_res->pm_state == WCD9XXX_PM_ASLEEP) { + pr_warn("%s: system is already suspended, state %d, wlock %dn", + __func__, wcd9xxx_core_res->pm_state, + wcd9xxx_core_res->wlock_holders); + } + mutex_unlock(&wcd9xxx_core_res->pm_lock); + + return ret; +} +EXPORT_SYMBOL(wcd9xxx_core_res_suspend); + +/* + * wcd9xxx_core_res_resume: + * Resume callback function for wcd9xxx core + * + * @wcd9xxx_core_res: pointer to wcd core resource + * + * Returns 0 for success or negative error code for failure/busy + */ +int wcd9xxx_core_res_resume( + struct wcd9xxx_core_resource *wcd9xxx_core_res) +{ + int ret = 0; + + pr_debug("%s: enter\n", __func__); + mutex_lock(&wcd9xxx_core_res->pm_lock); + if (wcd9xxx_core_res->pm_state == WCD9XXX_PM_ASLEEP) { + pr_debug("%s: resuming system, state %d, wlock %d\n", __func__, + wcd9xxx_core_res->pm_state, + wcd9xxx_core_res->wlock_holders); + wcd9xxx_core_res->pm_state = WCD9XXX_PM_SLEEPABLE; + } else { + pr_warn("%s: system is already awake, state %d wlock %d\n", + __func__, wcd9xxx_core_res->pm_state, + wcd9xxx_core_res->wlock_holders); + } + mutex_unlock(&wcd9xxx_core_res->pm_lock); + wake_up_all(&wcd9xxx_core_res->pm_wq); + + return ret; +} +EXPORT_SYMBOL(wcd9xxx_core_res_resume); + +/* + * wcd9xxx_get_intf_type: + * Get interface type of wcd9xxx core + * + * Returns interface type + */ +enum wcd9xxx_intf_status wcd9xxx_get_intf_type(void) +{ + return wcd9xxx_intf; +} +EXPORT_SYMBOL(wcd9xxx_get_intf_type); + +/* + * wcd9xxx_set_intf_type: + * Set interface type of wcd9xxx core + * + */ +void wcd9xxx_set_intf_type(enum wcd9xxx_intf_status intf_status) +{ + wcd9xxx_intf = intf_status; +} +EXPORT_SYMBOL(wcd9xxx_set_intf_type); + +/* + * wcd9xxx_set_power_state: set power state for the region + * @wcd9xxx: handle to wcd core + * @state: power state to be set + * @region: region index + * + * Returns error code in case of failure or 0 for success + */ +int wcd9xxx_set_power_state(struct wcd9xxx *wcd9xxx, + enum codec_power_states state, + enum wcd_power_regions region) +{ + if (!wcd9xxx) { + pr_err("%s: wcd9xxx is NULL\n", __func__); + return -EINVAL; + } + + if ((region < 0) || (region >= WCD9XXX_MAX_PWR_REGIONS)) { + dev_err(wcd9xxx->dev, "%s: region index %d out of bounds\n", + __func__, region); + return -EINVAL; + } + if (!wcd9xxx->wcd9xxx_pwr[region]) { + dev_err(wcd9xxx->dev, "%s: memory not created for region: %d\n", + __func__, region); + return -EINVAL; + } + mutex_lock(&wcd9xxx->io_lock); + wcd9xxx->wcd9xxx_pwr[region]->power_state = state; + mutex_unlock(&wcd9xxx->io_lock); + + return 0; +} +EXPORT_SYMBOL(wcd9xxx_set_power_state); + +/* + * wcd9xxx_get_current_power_state: Get power state of the region + * @wcd9xxx: handle to wcd core + * @region: region index + * + * Returns current power state of the region or error code for failure + */ +int wcd9xxx_get_current_power_state(struct wcd9xxx *wcd9xxx, + enum wcd_power_regions region) +{ + int state; + + if (!wcd9xxx) { + pr_err("%s: wcd9xxx is NULL\n", __func__); + return -EINVAL; + } + + if ((region < 0) || (region >= WCD9XXX_MAX_PWR_REGIONS)) { + dev_err(wcd9xxx->dev, "%s: region index %d out of bounds\n", + __func__, region); + return -EINVAL; + } + if (!wcd9xxx->wcd9xxx_pwr[region]) { + dev_err(wcd9xxx->dev, "%s: memory not created for region: %d\n", + __func__, region); + return -EINVAL; + } + + mutex_lock(&wcd9xxx->io_lock); + state = wcd9xxx->wcd9xxx_pwr[region]->power_state; + mutex_unlock(&wcd9xxx->io_lock); + + return state; +} +EXPORT_SYMBOL(wcd9xxx_get_current_power_state); diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile new file mode 100644 index 000000000000..f00d59de9db2 --- /dev/null +++ b/drivers/misc/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for misc devices that really don't fit anywhere else. +# + +obj-y += qcom/ diff --git a/drivers/misc/qcom/Kconfig b/drivers/misc/qcom/Kconfig new file mode 100644 index 000000000000..e8a79605f361 --- /dev/null +++ b/drivers/misc/qcom/Kconfig @@ -0,0 +1,19 @@ +config MSM_QDSP6V2_CODECS + bool "Audio QDSP6V2 APR support" + select SND_SOC_QDSP6V2 + help + Enable Audio codecs with APR IPC protocol support between + application processor and QDSP6 for B-family. APR is + used by audio driver to configure QDSP6's + ASM, ADM and AFE. + +config MSM_ULTRASOUND + bool "QDSP6V2 HW Ultrasound support" + select SND_SOC_QDSP6V2 + help + Enable HW Ultrasound support in QDSP6V2. + QDSP6V2 can support HW encoder & decoder and + ultrasound processing. It will enable + ultrasound data paths between + HW and services, calculating input events + upon the ultrasound data. diff --git a/drivers/misc/qcom/Makefile b/drivers/misc/qcom/Makefile new file mode 100644 index 000000000000..120bdddcbc84 --- /dev/null +++ b/drivers/misc/qcom/Makefile @@ -0,0 +1 @@ +obj-y += qdsp6v2/ diff --git a/drivers/misc/qcom/qdsp6v2/Makefile b/drivers/misc/qcom/qdsp6v2/Makefile new file mode 100644 index 000000000000..90a123adbb7f --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_MSM_QDSP6V2_CODECS) += aac_in.o qcelp_in.o evrc_in.o amrnb_in.o g711mlaw_in.o g711alaw_in.o audio_utils.o +obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_wma.o audio_wmapro.o audio_aac.o audio_multi_aac.o audio_alac.o audio_ape.o audio_utils_aio.o +obj-$(CONFIG_MSM_QDSP6V2_CODECS) += q6audio_v2.o q6audio_v2_aio.o +obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_g711mlaw.o audio_g711alaw.o +obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_mp3.o audio_amrnb.o audio_amrwb.o audio_amrwbplus.o audio_evrc.o audio_qcelp.o amrwb_in.o audio_hwacc_effects.o +obj-$(CONFIG_MSM_ULTRASOUND) += ultrasound/ diff --git a/drivers/misc/qcom/qdsp6v2/aac_in.c b/drivers/misc/qcom/qdsp6v2/aac_in.c new file mode 100644 index 000000000000..c0828dc6d1bc --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/aac_in.c @@ -0,0 +1,709 @@ +/* + * Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "audio_utils.h" + + +/* Buffer with meta*/ +#define PCM_BUF_SIZE (4096 + sizeof(struct meta_in)) + +/* Maximum 5 frames in buffer with meta */ +#define FRAME_SIZE (1 + ((1536+sizeof(struct meta_out_dsp)) * 5)) + +#define AAC_FORMAT_ADTS 65535 + +#define MAX_SAMPLE_RATE_384K 384000 + +static long aac_in_ioctl_shared(struct file *file, unsigned int cmd, void *arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + int cnt = 0; + + switch (cmd) { + case AUDIO_START: { + struct msm_audio_aac_enc_config *enc_cfg; + struct msm_audio_aac_config *aac_config; + uint32_t aac_mode = AAC_ENC_MODE_AAC_LC; + + enc_cfg = audio->enc_cfg; + aac_config = audio->codec_cfg; + /* ENCODE CFG (after new set of API's are published )bharath*/ + pr_debug("%s:session id %d: default buf alloc[%d]\n", __func__, + audio->ac->session, audio->buf_alloc); + if (audio->enabled == 1) { + pr_info("%s:AUDIO_START already over\n", __func__); + rc = 0; + break; + } + + if (audio->opened) { + rc = audio_in_buf_alloc(audio); + if (rc < 0) { + pr_err("%s:session id %d: buffer allocation failed\n", + __func__, audio->ac->session); + break; + } + } else { + if (audio->feedback == NON_TUNNEL_MODE) { + pr_debug("%s: starting in non_tunnel mode", + __func__); + rc = q6asm_open_read_write(audio->ac, + FORMAT_MPEG4_AAC, FORMAT_LINEAR_PCM); + if (rc < 0) { + pr_err("%s:open read write failed\n", + __func__); + break; + } + } + if (audio->feedback == TUNNEL_MODE) { + pr_debug("%s: starting in tunnel mode", + __func__); + rc = q6asm_open_read(audio->ac, + FORMAT_MPEG4_AAC); + + if (rc < 0) { + pr_err("%s:open read failed\n", + __func__); + break; + } + } + audio->stopped = 0; + } + + pr_debug("%s:sbr_ps_flag = %d, sbr_flag = %d\n", __func__, + aac_config->sbr_ps_on_flag, aac_config->sbr_on_flag); + if (aac_config->sbr_ps_on_flag) + aac_mode = AAC_ENC_MODE_EAAC_P; + else if (aac_config->sbr_on_flag) + aac_mode = AAC_ENC_MODE_AAC_P; + else + aac_mode = AAC_ENC_MODE_AAC_LC; + + rc = q6asm_enc_cfg_blk_aac(audio->ac, + audio->buf_cfg.frames_per_buf, + enc_cfg->sample_rate, + enc_cfg->channels, + enc_cfg->bit_rate, + aac_mode, + enc_cfg->stream_format); + if (rc < 0) { + pr_err("%s:session id %d: cmd media format block failed\n", + __func__, audio->ac->session); + break; + } + if (audio->feedback == NON_TUNNEL_MODE) { + rc = q6asm_media_format_block_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + if (rc < 0) { + pr_err("%s:session id %d: media format block failed\n", + __func__, audio->ac->session); + break; + } + } + rc = audio_in_enable(audio); + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("%s:session id %d: Audio Start procedure failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + while (cnt++ < audio->str_cfg.buffer_count) + q6asm_read(audio->ac); + pr_debug("%s:session id %d: AUDIO_START success enable[%d]\n", + __func__, audio->ac->session, audio->enabled); + break; + } + case AUDIO_STOP: { + pr_debug("%s:session id %d: Rxed AUDIO_STOP\n", __func__, + audio->ac->session); + rc = audio_in_disable(audio); + if (rc < 0) { + pr_err("%s:session id %d: Audio Stop procedure failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + break; + } + case AUDIO_GET_AAC_ENC_CONFIG: { + struct msm_audio_aac_enc_config *cfg; + struct msm_audio_aac_enc_config *enc_cfg; + + cfg = (struct msm_audio_aac_enc_config *)arg; + if (cfg == NULL) { + pr_err("%s: NULL config pointer for %s\n", + __func__, "AUDIO_GET_AAC_CONFIG"); + rc = -EINVAL; + break; + } + memset(cfg, 0, sizeof(*cfg)); + enc_cfg = audio->enc_cfg; + if (enc_cfg->channels == CH_MODE_MONO) + cfg->channels = 1; + else + cfg->channels = 2; + + cfg->sample_rate = enc_cfg->sample_rate; + cfg->bit_rate = enc_cfg->bit_rate; + switch (enc_cfg->stream_format) { + case 0x00: + cfg->stream_format = AUDIO_AAC_FORMAT_ADTS; + break; + case 0x01: + cfg->stream_format = AUDIO_AAC_FORMAT_LOAS; + break; + case 0x02: + cfg->stream_format = AUDIO_AAC_FORMAT_ADIF; + break; + default: + case 0x03: + cfg->stream_format = AUDIO_AAC_FORMAT_RAW; + } + pr_debug("%s:session id %d: Get-aac-cfg: format=%d sr=%d bitrate=%d\n", + __func__, audio->ac->session, + cfg->stream_format, cfg->sample_rate, cfg->bit_rate); + break; + } + case AUDIO_SET_AAC_ENC_CONFIG: { + struct msm_audio_aac_enc_config *cfg; + struct msm_audio_aac_enc_config *enc_cfg; + uint32_t min_bitrate, max_bitrate; + + cfg = (struct msm_audio_aac_enc_config *)arg; + if (cfg == NULL) { + pr_err("%s: NULL config pointer for %s\n", + "AUDIO_SET_AAC_ENC_CONFIG", __func__); + rc = -EINVAL; + break; + } + enc_cfg = audio->enc_cfg; + pr_debug("%s:session id %d: Set-aac-cfg: stream=%d\n", __func__, + audio->ac->session, cfg->stream_format); + + switch (cfg->stream_format) { + case AUDIO_AAC_FORMAT_ADTS: + enc_cfg->stream_format = 0x00; + break; + case AUDIO_AAC_FORMAT_LOAS: + enc_cfg->stream_format = 0x01; + break; + case AUDIO_AAC_FORMAT_ADIF: + enc_cfg->stream_format = 0x02; + break; + case AUDIO_AAC_FORMAT_RAW: + enc_cfg->stream_format = 0x03; + break; + default: + pr_err("%s:session id %d: unsupported AAC format %d\n", + __func__, audio->ac->session, + cfg->stream_format); + rc = -EINVAL; + break; + } + + if (cfg->channels == 1) { + cfg->channels = CH_MODE_MONO; + } else if (cfg->channels == 2) { + cfg->channels = CH_MODE_STEREO; + } else { + rc = -EINVAL; + break; + } + + if (cfg->sample_rate > MAX_SAMPLE_RATE_384K) { + pr_err("%s: ERROR: invalid sample rate = %u", + __func__, cfg->sample_rate); + rc = -EINVAL; + break; + } + + min_bitrate = ((cfg->sample_rate)*(cfg->channels))/2; + /* This calculation should be based on AAC mode. But we cannot + * get AAC mode in this setconfig. min_bitrate's logical max + * value is 24000. So if min_bitrate is higher than 24000, + * choose 24000. + */ + if (min_bitrate > 24000) + min_bitrate = 24000; + max_bitrate = 6*(cfg->sample_rate)*(cfg->channels); + if (max_bitrate > 192000) + max_bitrate = 192000; + if ((cfg->bit_rate < min_bitrate) || + (cfg->bit_rate > max_bitrate)) { + pr_err("%s: bitrate permissible: max=%d, min=%d\n", + __func__, max_bitrate, min_bitrate); + pr_err("%s: ERROR in setting bitrate = %d\n", + __func__, cfg->bit_rate); + rc = -EINVAL; + break; + } + enc_cfg->sample_rate = cfg->sample_rate; + enc_cfg->channels = cfg->channels; + enc_cfg->bit_rate = cfg->bit_rate; + pr_debug("%s:session id %d: Set-aac-cfg:SR= 0x%x ch=0x%x bitrate=0x%x, format(adts/raw) = %d\n", + __func__, audio->ac->session, enc_cfg->sample_rate, + enc_cfg->channels, enc_cfg->bit_rate, + enc_cfg->stream_format); + break; + } + case AUDIO_SET_AAC_CONFIG: { + struct msm_audio_aac_config *aac_cfg; + struct msm_audio_aac_config *audio_aac_cfg; + struct msm_audio_aac_enc_config *enc_cfg; + + enc_cfg = audio->enc_cfg; + audio_aac_cfg = audio->codec_cfg; + aac_cfg = (struct msm_audio_aac_config *)arg; + + if (aac_cfg == NULL) { + pr_err("%s: NULL config pointer %s\n", + __func__, "AUDIO_SET_AAC_CONFIG"); + rc = -EINVAL; + break; + } + pr_debug("%s:session id %d: AUDIO_SET_AAC_CONFIG: sbr_flag = %d sbr_ps_flag = %d\n", + __func__, audio->ac->session, aac_cfg->sbr_on_flag, + aac_cfg->sbr_ps_on_flag); + audio_aac_cfg->sbr_on_flag = aac_cfg->sbr_on_flag; + audio_aac_cfg->sbr_ps_on_flag = aac_cfg->sbr_ps_on_flag; + if ((audio_aac_cfg->sbr_on_flag == 1) || + (audio_aac_cfg->sbr_ps_on_flag == 1)) { + if (enc_cfg->sample_rate < 24000) { + pr_err("%s: ERROR in setting samplerate = %d\n", + __func__, enc_cfg->sample_rate); + rc = -EINVAL; + break; + } + } + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + } + return rc; +} + +static long aac_in_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: + case AUDIO_STOP: { + rc = aac_in_ioctl_shared(file, cmd, NULL); + break; + } + case AUDIO_GET_AAC_ENC_CONFIG: { + struct msm_audio_aac_enc_config cfg; + + rc = aac_in_ioctl_shared(file, cmd, &cfg); + if (rc) { + pr_err("%s:AUDIO_GET_AAC_ENC_CONFIG failed. rc=%d\n", + __func__, rc); + break; + } + if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) { + pr_err("%s: copy_to_user for AUDIO_GET_AAC_ENC_CONFIG failed\n", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_AAC_ENC_CONFIG: { + struct msm_audio_aac_enc_config cfg; + + if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) { + pr_err("%s: copy_from_user for AUDIO_SET_AAC_ENC_CONFIG failed\n", + __func__); + rc = -EFAULT; + break; + } + rc = aac_in_ioctl_shared(file, cmd, &cfg); + if (rc) + pr_err("%s:AUDIO_SET_AAC_ENC_CONFIG failed. rc=%d\n", + __func__, rc); + break; + } + case AUDIO_GET_AAC_CONFIG: { + if (copy_to_user((void *)arg, &audio->codec_cfg, + sizeof(struct msm_audio_aac_config))) { + pr_err("%s: copy_to_user for AUDIO_GET_AAC_CONFIG failed\n", + __func__); + rc = -EFAULT; + break; + } + break; + } + case AUDIO_SET_AAC_CONFIG: { + struct msm_audio_aac_config aac_cfg; + + if (copy_from_user(&aac_cfg, (void *)arg, + sizeof(struct msm_audio_aac_config))) { + pr_err("%s: copy_to_user for AUDIO_SET_CONFIG failed\n", + __func__); + rc = -EFAULT; + break; + } + rc = aac_in_ioctl_shared(file, cmd, &aac_cfg); + if (rc) + pr_err("%s:AUDIO_SET_AAC_CONFIG failed. rc=%d\n", + __func__, rc); + break; + } + default: + pr_err("%s: Unknown ioctl cmd=%d\n", __func__, cmd); + rc = -EINVAL; + } + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_audio_aac_enc_config32 { + u32 channels; + u32 sample_rate; + u32 bit_rate; + u32 stream_format; +}; + +struct msm_audio_aac_config32 { + s16 format; + u16 audio_object; + u16 ep_config; /* 0 ~ 3 useful only obj = ERLC */ + u16 aac_section_data_resilience_flag; + u16 aac_scalefactor_data_resilience_flag; + u16 aac_spectral_data_resilience_flag; + u16 sbr_on_flag; + u16 sbr_ps_on_flag; + u16 dual_mono_mode; + u16 channel_configuration; + u16 sample_rate; +}; + +enum { + AUDIO_SET_AAC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_aac_config32), + AUDIO_GET_AAC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_aac_config32), + AUDIO_SET_AAC_ENC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+3), struct msm_audio_aac_enc_config32), + AUDIO_GET_AAC_ENC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+4), struct msm_audio_aac_enc_config32) +}; + +static long aac_in_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: + case AUDIO_STOP: { + rc = aac_in_ioctl_shared(file, cmd, NULL); + break; + } + case AUDIO_GET_AAC_ENC_CONFIG_32: { + struct msm_audio_aac_enc_config cfg; + struct msm_audio_aac_enc_config32 cfg_32; + + memset(&cfg_32, 0, sizeof(cfg_32)); + + cmd = AUDIO_GET_AAC_ENC_CONFIG; + rc = aac_in_ioctl_shared(file, cmd, &cfg); + if (rc) { + pr_err("%s:AUDIO_GET_AAC_ENC_CONFIG_32 failed. Rc= %d\n", + __func__, rc); + break; + } + cfg_32.channels = cfg.channels; + cfg_32.sample_rate = cfg.sample_rate; + cfg_32.bit_rate = cfg.bit_rate; + cfg_32.stream_format = cfg.stream_format; + if (copy_to_user((void *)arg, &cfg_32, sizeof(cfg_32))) { + pr_err("%s: copy_to_user for AUDIO_GET_AAC_ENC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_AAC_ENC_CONFIG_32: { + struct msm_audio_aac_enc_config cfg; + struct msm_audio_aac_enc_config32 cfg_32; + + if (copy_from_user(&cfg_32, (void *)arg, sizeof(cfg_32))) { + pr_err("%s: copy_from_user for AUDIO_GET_AAC_ENC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + cfg.channels = cfg_32.channels; + cfg.sample_rate = cfg_32.sample_rate; + cfg.bit_rate = cfg_32.bit_rate; + cfg.stream_format = cfg_32.stream_format; + /* The command should be converted from 32 bit to normal + * before the shared ioctl is called as shared ioctl + * can process only normal commands + */ + cmd = AUDIO_SET_AAC_ENC_CONFIG; + rc = aac_in_ioctl_shared(file, cmd, &cfg); + if (rc) + pr_err("%s:AUDIO_SET_AAC_ENC_CONFIG_32 failed. rc=%d\n", + __func__, rc); + break; + } + case AUDIO_GET_AAC_CONFIG_32: { + struct msm_audio_aac_config *aac_config; + struct msm_audio_aac_config32 aac_config_32; + + aac_config = (struct msm_audio_aac_config *)audio->codec_cfg; + aac_config_32.format = aac_config->format; + aac_config_32.audio_object = aac_config->audio_object; + aac_config_32.ep_config = aac_config->ep_config; + aac_config_32.aac_section_data_resilience_flag = + aac_config->aac_section_data_resilience_flag; + aac_config_32.aac_scalefactor_data_resilience_flag = + aac_config->aac_scalefactor_data_resilience_flag; + aac_config_32.aac_spectral_data_resilience_flag = + aac_config->aac_spectral_data_resilience_flag; + aac_config_32.sbr_on_flag = aac_config->sbr_on_flag; + aac_config_32.sbr_ps_on_flag = aac_config->sbr_ps_on_flag; + aac_config_32.dual_mono_mode = aac_config->dual_mono_mode; + aac_config_32.channel_configuration = + aac_config->channel_configuration; + aac_config_32.sample_rate = aac_config->sample_rate; + + if (copy_to_user((void *)arg, &aac_config_32, + sizeof(aac_config_32))) { + pr_err("%s: copy_to_user for AUDIO_GET_AAC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + break; + } + case AUDIO_SET_AAC_CONFIG_32: { + struct msm_audio_aac_config aac_cfg; + struct msm_audio_aac_config32 aac_cfg_32; + + if (copy_from_user(&aac_cfg_32, (void *)arg, + sizeof(aac_cfg_32))) { + pr_err("%s: copy_from_user for AUDIO_SET_AAC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + aac_cfg.format = aac_cfg_32.format; + aac_cfg.audio_object = aac_cfg_32.audio_object; + aac_cfg.ep_config = aac_cfg_32.ep_config; + aac_cfg.aac_section_data_resilience_flag = + aac_cfg_32.aac_section_data_resilience_flag; + aac_cfg.aac_scalefactor_data_resilience_flag = + aac_cfg_32.aac_scalefactor_data_resilience_flag; + aac_cfg.aac_spectral_data_resilience_flag = + aac_cfg_32.aac_spectral_data_resilience_flag; + aac_cfg.sbr_on_flag = aac_cfg_32.sbr_on_flag; + aac_cfg.sbr_ps_on_flag = aac_cfg_32.sbr_ps_on_flag; + aac_cfg.dual_mono_mode = aac_cfg_32.dual_mono_mode; + aac_cfg.channel_configuration = + aac_cfg_32.channel_configuration; + aac_cfg.sample_rate = aac_cfg_32.sample_rate; + + cmd = AUDIO_SET_AAC_CONFIG; + rc = aac_in_ioctl_shared(file, cmd, &aac_cfg); + if (rc) + pr_err("%s:AUDIO_SET_AAC_CONFIG failed. Rc= %d\n", + __func__, rc); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d\n", __func__, cmd); + rc = -EINVAL; + } + return rc; +} +#else +#define aac_in_compat_ioctl NULL +#endif + +static int aac_in_open(struct inode *inode, struct file *file) +{ + struct q6audio_in *audio = NULL; + struct msm_audio_aac_enc_config *enc_cfg; + struct msm_audio_aac_config *aac_config; + int rc = 0; + + audio = kzalloc(sizeof(struct q6audio_in), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + + /* Allocate memory for encoder config param */ + audio->enc_cfg = kzalloc(sizeof(struct msm_audio_aac_enc_config), + GFP_KERNEL); + if (audio->enc_cfg == NULL) { + kfree(audio); + return -ENOMEM; + } + enc_cfg = audio->enc_cfg; + + audio->codec_cfg = kzalloc(sizeof(struct msm_audio_aac_config), + GFP_KERNEL); + if (audio->codec_cfg == NULL) { + kfree(audio->enc_cfg); + kfree(audio); + return -ENOMEM; + } + aac_config = audio->codec_cfg; + + mutex_init(&audio->lock); + mutex_init(&audio->read_lock); + mutex_init(&audio->write_lock); + spin_lock_init(&audio->dsp_lock); + init_waitqueue_head(&audio->read_wait); + init_waitqueue_head(&audio->write_wait); + + /* Settings will be re-config at AUDIO_SET_CONFIG, + * but at least we need to have initial config + */ + audio->str_cfg.buffer_size = FRAME_SIZE; + audio->str_cfg.buffer_count = FRAME_NUM; + audio->min_frame_size = 1536; + audio->max_frames_per_buf = 5; + enc_cfg->sample_rate = 8000; + enc_cfg->channels = 1; + enc_cfg->bit_rate = 16000; + enc_cfg->stream_format = 0x00;/* 0:ADTS, 3:RAW */ + audio->buf_cfg.meta_info_enable = 0x01; + audio->buf_cfg.frames_per_buf = 0x01; + audio->pcm_cfg.buffer_count = PCM_BUF_COUNT; + audio->pcm_cfg.buffer_size = PCM_BUF_SIZE; + aac_config->format = AUDIO_AAC_FORMAT_ADTS; + aac_config->audio_object = AUDIO_AAC_OBJECT_LC; + aac_config->sbr_on_flag = 0; + aac_config->sbr_ps_on_flag = 0; + aac_config->channel_configuration = 1; + + audio->ac = q6asm_audio_client_alloc((app_cb)q6asm_in_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("%s: Could not allocate memory for audio client\n", + __func__); + kfree(audio->enc_cfg); + kfree(audio->codec_cfg); + kfree(audio); + return -ENOMEM; + } + /* open aac encoder in tunnel mode */ + audio->buf_cfg.frames_per_buf = 0x01; + + if ((file->f_mode & FMODE_WRITE) && + (file->f_mode & FMODE_READ)) { + audio->feedback = NON_TUNNEL_MODE; + rc = q6asm_open_read_write(audio->ac, FORMAT_MPEG4_AAC, + FORMAT_LINEAR_PCM); + + if (rc < 0) { + pr_err("%s:session id %d: NT Open failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + audio->buf_cfg.meta_info_enable = 0x01; + pr_info("%s:session id %d: NT mode encoder success\n", __func__, + audio->ac->session); + } else if (!(file->f_mode & FMODE_WRITE) && + (file->f_mode & FMODE_READ)) { + audio->feedback = TUNNEL_MODE; + rc = q6asm_open_read(audio->ac, FORMAT_MPEG4_AAC); + + if (rc < 0) { + pr_err("%s:session id %d: Tunnel Open failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + /* register for tx overflow (valid for tunnel mode only) */ + rc = q6asm_reg_tx_overflow(audio->ac, 0x01); + if (rc < 0) { + pr_err("%s:session id %d: TX Overflow registration failed rc=%d\n", + __func__, + audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + audio->buf_cfg.meta_info_enable = 0x00; + pr_info("%s:session id %d: T mode encoder success\n", __func__, + audio->ac->session); + } else { + pr_err("%s:session id %d: Unexpected mode\n", __func__, + audio->ac->session); + rc = -EACCES; + goto fail; + } + audio->opened = 1; + audio->reset_event = false; + atomic_set(&audio->in_count, PCM_BUF_COUNT); + atomic_set(&audio->out_count, 0x00); + audio->enc_compat_ioctl = aac_in_compat_ioctl; + audio->enc_ioctl = aac_in_ioctl; + file->private_data = audio; + + pr_info("%s:session id %d: success\n", __func__, audio->ac->session); + return 0; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio->enc_cfg); + kfree(audio->codec_cfg); + kfree(audio); + return rc; +} + +static const struct file_operations audio_in_fops = { + .owner = THIS_MODULE, + .open = aac_in_open, + .release = audio_in_release, + .read = audio_in_read, + .write = audio_in_write, + .unlocked_ioctl = audio_in_ioctl, + .compat_ioctl = audio_in_compat_ioctl +}; + +struct miscdevice audio_aac_in_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_aac_in", + .fops = &audio_in_fops, +}; + +static int __init aac_in_init(void) +{ + return misc_register(&audio_aac_in_misc); +} +device_initcall(aac_in_init); diff --git a/drivers/misc/qcom/qdsp6v2/amrnb_in.c b/drivers/misc/qcom/qdsp6v2/amrnb_in.c new file mode 100644 index 000000000000..b24764cf9516 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/amrnb_in.c @@ -0,0 +1,402 @@ +/* + * Copyright (c) 2010-2012, 2014, 2016-2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "audio_utils.h" + +/* Buffer with meta*/ +#define PCM_BUF_SIZE (4096 + sizeof(struct meta_in)) + +/* Maximum 10 frames in buffer with meta */ +#define FRAME_SIZE (1 + ((32+sizeof(struct meta_out_dsp)) * 10)) + +static long amrnb_in_ioctl_shared(struct file *file, + unsigned int cmd, void *arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + int cnt = 0; + + switch (cmd) { + case AUDIO_START: { + struct msm_audio_amrnb_enc_config_v2 *enc_cfg; + + enc_cfg = audio->enc_cfg; + pr_debug("%s:session id %d: default buf alloc[%d]\n", __func__, + audio->ac->session, audio->buf_alloc); + if (audio->enabled == 1) { + pr_info("%s:AUDIO_START already over\n", __func__); + rc = 0; + break; + } + rc = audio_in_buf_alloc(audio); + if (rc < 0) { + pr_err("%s:session id %d: buffer allocation failed\n", + __func__, audio->ac->session); + break; + } + + rc = q6asm_enc_cfg_blk_amrnb(audio->ac, + audio->buf_cfg.frames_per_buf, + enc_cfg->band_mode, + enc_cfg->dtx_enable); + + if (rc < 0) { + pr_err("%s:session id %d: cmd amrnb media format block failed\n", + __func__, audio->ac->session); + break; + } + if (audio->feedback == NON_TUNNEL_MODE) { + rc = q6asm_media_format_block_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + + if (rc < 0) { + pr_err("%s:session id %d: media format block failed\n", + __func__, audio->ac->session); + break; + } + } + pr_debug("%s:session id %d: AUDIO_START enable[%d]\n", + __func__, audio->ac->session, + audio->enabled); + rc = audio_in_enable(audio); + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("%s:session id %d: Audio Start procedure failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + while (cnt++ < audio->str_cfg.buffer_count) + q6asm_read(audio->ac); /* Push buffer to DSP */ + rc = 0; + pr_debug("%s:session id %d: AUDIO_START success enable[%d]\n", + __func__, audio->ac->session, audio->enabled); + break; + } + case AUDIO_STOP: { + pr_debug("%s:AUDIO_STOP\n", __func__); + rc = audio_in_disable(audio); + if (rc < 0) { + pr_err("%s:session id %d: Audio Stop procedure failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + break; + } + case AUDIO_SET_AMRNB_ENC_CONFIG_V2: { + struct msm_audio_amrnb_enc_config_v2 *cfg; + struct msm_audio_amrnb_enc_config_v2 *enc_cfg; + + cfg = (struct msm_audio_amrnb_enc_config_v2 *)arg; + if (cfg == NULL) { + pr_err("%s: NULL config pointer for %s\n", + __func__, + "AUDIO_SET_AMRNB_ENC_CONFIG_V2"); + rc = -EINVAL; + break; + } + + enc_cfg = audio->enc_cfg; + if (cfg->band_mode > 8 || + cfg->band_mode < 1) { + pr_err("%s:session id %d: invalid band mode\n", + __func__, audio->ac->session); + rc = -EINVAL; + break; + } + /* AMR NB encoder accepts values between 0-7 + * while openmax provides value between 1-8 + * as per spec + */ + enc_cfg->band_mode = (cfg->band_mode - 1); + enc_cfg->dtx_enable = (cfg->dtx_enable ? 1 : 0); + enc_cfg->frame_format = 0; + pr_debug("%s:session id %d: band_mode = 0x%x dtx_enable=0x%x\n", + __func__, audio->ac->session, + enc_cfg->band_mode, enc_cfg->dtx_enable); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + } + return rc; +} + +static long amrnb_in_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: + case AUDIO_STOP: { + rc = amrnb_in_ioctl_shared(file, cmd, NULL); + break; + } + case AUDIO_GET_AMRNB_ENC_CONFIG_V2: { + if (copy_to_user((void *)arg, audio->enc_cfg, + sizeof(struct msm_audio_amrnb_enc_config_v2))) { + pr_err("%s: copy_to_user for AUDIO_GET_AMRNB_ENC_CONFIG_V2 failed\n", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_AMRNB_ENC_CONFIG_V2: { + struct msm_audio_amrnb_enc_config_v2 cfg; + + if (copy_from_user(&cfg, (void *) arg, + sizeof(cfg))) { + pr_err("%s: copy_from_user for AUDIO_SET_AMRNB_ENC_CONFIG_V2 failed\n", + __func__); + rc = -EFAULT; + break; + } + rc = amrnb_in_ioctl_shared(file, cmd, &cfg); + if (rc) + pr_err("%s: AUDIO_SET_AMRNB_ENC_CONFIG_V2 failed. rc=%d\n", + __func__, rc); + break; + } + default: + pr_err("%s: Unknown ioctl cmd=%d", __func__, cmd); + rc = -EINVAL; + } + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_audio_amrnb_enc_config_v2_32 { + u32 band_mode; + u32 dtx_enable; + u32 frame_format; +}; + +enum { + AUDIO_GET_AMRNB_ENC_CONFIG_V2_32 = _IOW(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+2), + struct msm_audio_amrnb_enc_config_v2_32), + AUDIO_SET_AMRNB_ENC_CONFIG_V2_32 = _IOR(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+3), + struct msm_audio_amrnb_enc_config_v2_32) +}; + +static long amrnb_in_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: + case AUDIO_STOP: { + rc = amrnb_in_ioctl_shared(file, cmd, NULL); + break; + } + case AUDIO_GET_AMRNB_ENC_CONFIG_V2_32: { + struct msm_audio_amrnb_enc_config_v2 *amrnb_config; + struct msm_audio_amrnb_enc_config_v2_32 amrnb_config_32; + + memset(&amrnb_config_32, 0, sizeof(amrnb_config_32)); + + amrnb_config = + (struct msm_audio_amrnb_enc_config_v2 *)audio->enc_cfg; + amrnb_config_32.band_mode = amrnb_config->band_mode; + amrnb_config_32.dtx_enable = amrnb_config->dtx_enable; + amrnb_config_32.frame_format = amrnb_config->frame_format; + + if (copy_to_user((void *)arg, &amrnb_config_32, + sizeof(amrnb_config_32))) { + pr_err("%s: copy_to_user for AUDIO_GET_AMRNB_ENC_CONFIG_V2_32 failed", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_AMRNB_ENC_CONFIG_V2_32: { + struct msm_audio_amrnb_enc_config_v2_32 cfg_32; + + if (copy_from_user(&cfg_32, (void *) arg, + sizeof(cfg_32))) { + pr_err("%s: copy_from_user for AUDIO_SET_AMRNB_ENC_CONFIG_V2_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + cmd = AUDIO_SET_AMRNB_ENC_CONFIG_V2; + rc = amrnb_in_ioctl_shared(file, cmd, &cfg_32); + if (rc) + pr_err("%s:AUDIO_SET_AMRNB_ENC_CONFIG_V2 failed rc= %d\n", + __func__, rc); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + } + return rc; +} +#else +#define amrnb_in_compat_ioctl NULL +#endif + +static int amrnb_in_open(struct inode *inode, struct file *file) +{ + struct q6audio_in *audio = NULL; + struct msm_audio_amrnb_enc_config_v2 *enc_cfg; + int rc = 0; + + audio = kzalloc(sizeof(struct q6audio_in), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + + /* Allocate memory for encoder config param */ + audio->enc_cfg = kzalloc(sizeof(struct msm_audio_amrnb_enc_config_v2), + GFP_KERNEL); + if (audio->enc_cfg == NULL) { + kfree(audio); + return -ENOMEM; + } + enc_cfg = audio->enc_cfg; + + mutex_init(&audio->lock); + mutex_init(&audio->read_lock); + mutex_init(&audio->write_lock); + spin_lock_init(&audio->dsp_lock); + init_waitqueue_head(&audio->read_wait); + init_waitqueue_head(&audio->write_wait); + + /* Settings will be re-config at AUDIO_SET_CONFIG, + * but at least we need to have initial config + */ + audio->str_cfg.buffer_size = FRAME_SIZE; + audio->str_cfg.buffer_count = FRAME_NUM; + audio->min_frame_size = 32; + audio->max_frames_per_buf = 10; + audio->pcm_cfg.buffer_size = PCM_BUF_SIZE; + audio->pcm_cfg.buffer_count = PCM_BUF_COUNT; + enc_cfg->band_mode = 7; + enc_cfg->dtx_enable = 0; + audio->pcm_cfg.channel_count = 1; + audio->pcm_cfg.sample_rate = 8000; + audio->buf_cfg.meta_info_enable = 0x01; + audio->buf_cfg.frames_per_buf = 0x01; + + audio->ac = q6asm_audio_client_alloc((app_cb)q6asm_in_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("%s: Could not allocate memory for audio client\n", + __func__); + kfree(audio->enc_cfg); + kfree(audio); + return -ENOMEM; + } + + /* open amrnb encoder in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && + (file->f_mode & FMODE_READ)) { + audio->feedback = NON_TUNNEL_MODE; + rc = q6asm_open_read_write(audio->ac, FORMAT_AMRNB, + FORMAT_LINEAR_PCM); + if (rc < 0) { + pr_err("%s:session id %d: NT mode Open failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + pr_info("%s:session id %d: NT mode encoder success\n", + __func__, audio->ac->session); + } else if (!(file->f_mode & FMODE_WRITE) && + (file->f_mode & FMODE_READ)) { + audio->feedback = TUNNEL_MODE; + rc = q6asm_open_read(audio->ac, FORMAT_AMRNB); + if (rc < 0) { + pr_err("%s:session id %d: T mode Open failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + /* register for tx overflow (valid for tunnel mode only) */ + rc = q6asm_reg_tx_overflow(audio->ac, 0x01); + if (rc < 0) { + pr_err("%s:session id %d: TX Overflow registration failed rc=%d\n", + __func__, audio->ac->session, + rc); + rc = -ENODEV; + goto fail; + } + pr_info("%s:session id %d: T mode encoder success\n", + __func__, audio->ac->session); + } else { + pr_err("%s:session id %d: Unexpected mode\n", __func__, + audio->ac->session); + rc = -EACCES; + goto fail; + } + + audio->opened = 1; + atomic_set(&audio->in_count, PCM_BUF_COUNT); + atomic_set(&audio->out_count, 0x00); + audio->enc_compat_ioctl = amrnb_in_compat_ioctl; + audio->enc_ioctl = amrnb_in_ioctl; + file->private_data = audio; + + pr_info("%s:session id %d: success\n", __func__, audio->ac->session); + return 0; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio->enc_cfg); + kfree(audio); + return rc; +} + +static const struct file_operations audio_in_fops = { + .owner = THIS_MODULE, + .open = amrnb_in_open, + .release = audio_in_release, + .read = audio_in_read, + .write = audio_in_write, + .unlocked_ioctl = audio_in_ioctl, + .compat_ioctl = audio_in_compat_ioctl +}; + +struct miscdevice audio_amrnb_in_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_amrnb_in", + .fops = &audio_in_fops, +}; + +static int __init amrnb_in_init(void) +{ + return misc_register(&audio_amrnb_in_misc); +} + +device_initcall(amrnb_in_init); diff --git a/drivers/misc/qcom/qdsp6v2/amrwb_in.c b/drivers/misc/qcom/qdsp6v2/amrwb_in.c new file mode 100644 index 000000000000..77b4be54f10b --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/amrwb_in.c @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2011-2012, 2014, 2016-2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "audio_utils.h" + +/* Buffer with meta*/ +#define PCM_BUF_SIZE (4096 + sizeof(struct meta_in)) + +/* Maximum 10 frames in buffer with meta */ +#define FRAME_SIZE (1 + ((61+sizeof(struct meta_out_dsp)) * 10)) + +static long amrwb_in_ioctl_shared(struct file *file, + unsigned int cmd, void *arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + int cnt = 0; + + switch (cmd) { + case AUDIO_START: { + struct msm_audio_amrwb_enc_config *enc_cfg; + + enc_cfg = audio->enc_cfg; + pr_debug("%s:session id %d: default buf alloc[%d]\n", __func__, + audio->ac->session, audio->buf_alloc); + if (audio->enabled == 1) { + pr_info("%s:AUDIO_START already over\n", __func__); + rc = 0; + break; + } + rc = audio_in_buf_alloc(audio); + if (rc < 0) { + pr_err("%s:session id %d: buffer allocation failed\n", + __func__, audio->ac->session); + break; + } + + rc = q6asm_enc_cfg_blk_amrwb(audio->ac, + audio->buf_cfg.frames_per_buf, + enc_cfg->band_mode, + enc_cfg->dtx_enable); + + if (rc < 0) { + pr_err("%s:session id %d: cmd amrwb media format block failed\n", + __func__, audio->ac->session); + break; + } + if (audio->feedback == NON_TUNNEL_MODE) { + rc = q6asm_media_format_block_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + + if (rc < 0) { + pr_err("%s:session id %d: media format block failed\n", + __func__, audio->ac->session); + break; + } + } + pr_debug("%s:session id %d: AUDIO_START enable[%d]\n", + __func__, audio->ac->session, + audio->enabled); + rc = audio_in_enable(audio); + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("%s:session id %d: Audio Start procedure failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + while (cnt++ < audio->str_cfg.buffer_count) + q6asm_read(audio->ac); /* Push buffer to DSP */ + rc = 0; + pr_debug("%s:session id %d: AUDIO_START success enable[%d]\n", + __func__, audio->ac->session, audio->enabled); + break; + } + case AUDIO_STOP: { + pr_debug("%s:AUDIO_STOP\n", __func__); + rc = audio_in_disable(audio); + if (rc < 0) { + pr_err("%s:session id %d: Audio Stop procedure failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + break; + } + case AUDIO_SET_AMRWB_ENC_CONFIG: { + struct msm_audio_amrwb_enc_config *cfg; + struct msm_audio_amrwb_enc_config *enc_cfg; + + enc_cfg = audio->enc_cfg; + cfg = (struct msm_audio_amrwb_enc_config *)arg; + if (cfg == NULL) { + pr_err("%s: NULL config pointer for %s\n", + __func__, "AUDIO_SET_AMRWB_ENC_CONFIG"); + rc = -EINVAL; + break; + } + + if (cfg->band_mode > 8) { + pr_err("%s:session id %d: invalid band mode\n", + __func__, audio->ac->session); + rc = -EINVAL; + break; + } + /* ToDo: AMR WB encoder accepts values between 0-8 + * while openmax provides value between 9-17 + * as per spec + */ + enc_cfg->band_mode = cfg->band_mode; + enc_cfg->dtx_enable = (cfg->dtx_enable ? 1 : 0); + /* Currently DSP does not support different frameformat */ + enc_cfg->frame_format = 0; + pr_debug("%s:session id %d: band_mode = 0x%x dtx_enable=0x%x\n", + __func__, audio->ac->session, + enc_cfg->band_mode, enc_cfg->dtx_enable); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + } + return rc; +} + +static long amrwb_in_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: + case AUDIO_STOP: { + rc = amrwb_in_ioctl_shared(file, cmd, NULL); + break; + } + case AUDIO_GET_AMRWB_ENC_CONFIG: { + if (copy_to_user((void *)arg, audio->enc_cfg, + sizeof(struct msm_audio_amrwb_enc_config))) + pr_err("%s: copy_to_user for AUDIO_GET_AMRWB_ENC_CONFIG failed\n", + __func__); + rc = -EFAULT; + break; + } + case AUDIO_SET_AMRWB_ENC_CONFIG: { + struct msm_audio_amrwb_enc_config cfg; + + if (copy_from_user(&cfg, (void *) arg, + sizeof(cfg))) { + pr_err("%s: copy_from_user for AUDIO_SET_AMRWB_ENC_CONFIG failed\n", + __func__); + rc = -EFAULT; + break; + } + rc = amrwb_in_ioctl_shared(file, cmd, &cfg); + if (rc) + pr_err("%s:AUDIO_SET_AAC_ENC_CONFIG failed. rc=%d\n", + __func__, rc); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + } + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_audio_amrwb_enc_config_32 { + u32 band_mode; + u32 dtx_enable; + u32 frame_format; +}; + +enum { + AUDIO_GET_AMRWB_ENC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+0), + struct msm_audio_amrwb_enc_config_32), + AUDIO_SET_AMRWB_ENC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+1), + struct msm_audio_amrwb_enc_config_32) +}; + +static long amrwb_in_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: + case AUDIO_STOP: { + rc = amrwb_in_ioctl_shared(file, cmd, NULL); + break; + } + case AUDIO_GET_AMRWB_ENC_CONFIG_32: { + struct msm_audio_amrwb_enc_config *amrwb_config; + struct msm_audio_amrwb_enc_config_32 amrwb_config_32; + + memset(&amrwb_config_32, 0, sizeof(amrwb_config_32)); + + amrwb_config = + (struct msm_audio_amrwb_enc_config *)audio->enc_cfg; + amrwb_config_32.band_mode = amrwb_config->band_mode; + amrwb_config_32.dtx_enable = amrwb_config->dtx_enable; + amrwb_config_32.frame_format = amrwb_config->frame_format; + + if (copy_to_user((void *)arg, &amrwb_config_32, + sizeof(struct msm_audio_amrwb_enc_config_32))) { + pr_err("%s: copy_to_user for AUDIO_GET_AMRWB_ENC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_AMRWB_ENC_CONFIG_32: { + struct msm_audio_amrwb_enc_config cfg_32; + + if (copy_from_user(&cfg_32, (void *) arg, + sizeof(cfg_32))) { + pr_err("%s: copy_from_user for AUDIO_SET_AMRWB_ENC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + cmd = AUDIO_SET_AMRWB_ENC_CONFIG; + rc = amrwb_in_ioctl_shared(file, cmd, &cfg_32); + if (rc) + pr_err("%s:AUDIO_SET_AAC_ENC_CONFIG failed. rc=%d\n", + __func__, rc); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + } + return rc; +} +#else +#define amrwb_in_compat_ioctl NULL +#endif + +static int amrwb_in_open(struct inode *inode, struct file *file) +{ + struct q6audio_in *audio = NULL; + struct msm_audio_amrwb_enc_config *enc_cfg; + int rc = 0; + + audio = kzalloc(sizeof(struct q6audio_in), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + + /* Allocate memory for encoder config param */ + audio->enc_cfg = kzalloc(sizeof(struct msm_audio_amrwb_enc_config), + GFP_KERNEL); + if (audio->enc_cfg == NULL) { + kfree(audio); + return -ENOMEM; + } + enc_cfg = audio->enc_cfg; + + mutex_init(&audio->lock); + mutex_init(&audio->read_lock); + mutex_init(&audio->write_lock); + spin_lock_init(&audio->dsp_lock); + init_waitqueue_head(&audio->read_wait); + init_waitqueue_head(&audio->write_wait); + + /* Settings will be re-config at AUDIO_SET_CONFIG, + * but at least we need to have initial config + */ + audio->str_cfg.buffer_size = FRAME_SIZE; + audio->str_cfg.buffer_count = FRAME_NUM; + audio->min_frame_size = 32; + audio->max_frames_per_buf = 10; + audio->pcm_cfg.buffer_size = PCM_BUF_SIZE; + audio->pcm_cfg.buffer_count = PCM_BUF_COUNT; + enc_cfg->band_mode = 8; + enc_cfg->dtx_enable = 0; + audio->pcm_cfg.channel_count = 1; + audio->pcm_cfg.sample_rate = 16000; + audio->buf_cfg.meta_info_enable = 0x01; + audio->buf_cfg.frames_per_buf = 0x01; + + audio->ac = q6asm_audio_client_alloc((app_cb)q6asm_in_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("%s:audio[%pK]: Could not allocate memory for audio client\n", + __func__, audio); + kfree(audio->enc_cfg); + kfree(audio); + return -ENOMEM; + } + + /* open amrwb encoder in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && + (file->f_mode & FMODE_READ)) { + audio->feedback = NON_TUNNEL_MODE; + rc = q6asm_open_read_write(audio->ac, FORMAT_AMRWB, + FORMAT_LINEAR_PCM); + if (rc < 0) { + pr_err("%s:session id %d: NT mode Open failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + pr_info("%s:session id %d: NT mode encoder success\n", + __func__, audio->ac->session); + } else if (!(file->f_mode & FMODE_WRITE) && + (file->f_mode & FMODE_READ)) { + audio->feedback = TUNNEL_MODE; + rc = q6asm_open_read(audio->ac, FORMAT_AMRWB); + if (rc < 0) { + pr_err("%s:session id %d: T mode Open failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + /* register for tx overflow (valid for tunnel mode only) */ + rc = q6asm_reg_tx_overflow(audio->ac, 0x01); + if (rc < 0) { + pr_err("%s:session id %d: TX Overflow registration failed rc=%d\n", + __func__, audio->ac->session, + rc); + rc = -ENODEV; + goto fail; + } + pr_info("%s:session id %d: T mode encoder success\n", + __func__, audio->ac->session); + } else { + pr_err("%s:session id %d: Unexpected mode\n", __func__, + audio->ac->session); + rc = -EACCES; + goto fail; + } + + audio->opened = 1; + atomic_set(&audio->in_count, PCM_BUF_COUNT); + atomic_set(&audio->out_count, 0x00); + audio->enc_compat_ioctl = amrwb_in_compat_ioctl; + audio->enc_ioctl = amrwb_in_ioctl; + file->private_data = audio; + + pr_info("%s:session id %d: success\n", __func__, audio->ac->session); + return 0; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio->enc_cfg); + kfree(audio); + return rc; +} + +static const struct file_operations audio_in_fops = { + .owner = THIS_MODULE, + .open = amrwb_in_open, + .release = audio_in_release, + .read = audio_in_read, + .write = audio_in_write, + .unlocked_ioctl = audio_in_ioctl, + .compat_ioctl = audio_in_compat_ioctl +}; + +struct miscdevice audio_amrwb_in_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_amrwb_in", + .fops = &audio_in_fops, +}; + +static int __init amrwb_in_init(void) +{ + return misc_register(&audio_amrwb_in_misc); +} + +device_initcall(amrwb_in_init); diff --git a/drivers/misc/qcom/qdsp6v2/audio_aac.c b/drivers/misc/qcom/qdsp6v2/audio_aac.c new file mode 100644 index 000000000000..0f371fd1aa48 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_aac.c @@ -0,0 +1,474 @@ +/* aac audio output device + * + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include "audio_utils_aio.h" + +#define AUDIO_AAC_DUAL_MONO_INVALID -1 +#define PCM_BUFSZ_MIN_AAC ((8*1024) + sizeof(struct dec_meta_out)) + +static struct miscdevice audio_aac_misc; +static struct ws_mgr audio_aac_ws_mgr; + +#ifdef CONFIG_DEBUG_FS +static const struct file_operations audio_aac_debug_fops = { + .read = audio_aio_debug_read, + .open = audio_aio_debug_open, +}; +#endif + +static long audio_ioctl_shared(struct file *file, unsigned int cmd, + void *arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + struct asm_aac_cfg aac_cfg; + struct msm_audio_aac_config *aac_config; + uint32_t sbr_ps = 0x00; + + pr_debug("%s: AUDIO_START session_id[%d]\n", __func__, + audio->ac->session); + if (audio->feedback == NON_TUNNEL_MODE) { + /* Configure PCM output block */ + rc = q6asm_enc_cfg_blk_pcm(audio->ac, 0, 0); + if (rc < 0) { + pr_err("pcm output block config failed\n"); + break; + } + } + /* turn on both sbr and ps */ + rc = q6asm_enable_sbrps(audio->ac, sbr_ps); + if (rc < 0) + pr_err("sbr-ps enable failed\n"); + aac_config = (struct msm_audio_aac_config *)audio->codec_cfg; + if (aac_config->sbr_ps_on_flag) + aac_cfg.aot = AAC_ENC_MODE_EAAC_P; + else if (aac_config->sbr_on_flag) + aac_cfg.aot = AAC_ENC_MODE_AAC_P; + else + aac_cfg.aot = AAC_ENC_MODE_AAC_LC; + + switch (aac_config->format) { + case AUDIO_AAC_FORMAT_ADTS: + aac_cfg.format = 0x00; + break; + case AUDIO_AAC_FORMAT_LOAS: + aac_cfg.format = 0x01; + break; + case AUDIO_AAC_FORMAT_ADIF: + aac_cfg.format = 0x02; + break; + default: + case AUDIO_AAC_FORMAT_RAW: + aac_cfg.format = 0x03; + } + aac_cfg.ep_config = aac_config->ep_config; + aac_cfg.section_data_resilience = + aac_config->aac_section_data_resilience_flag; + aac_cfg.scalefactor_data_resilience = + aac_config->aac_scalefactor_data_resilience_flag; + aac_cfg.spectral_data_resilience = + aac_config->aac_spectral_data_resilience_flag; + aac_cfg.ch_cfg = audio->pcm_cfg.channel_count; + if (audio->feedback == TUNNEL_MODE) { + aac_cfg.sample_rate = aac_config->sample_rate; + aac_cfg.ch_cfg = aac_config->channel_configuration; + } else { + aac_cfg.sample_rate = audio->pcm_cfg.sample_rate; + aac_cfg.ch_cfg = audio->pcm_cfg.channel_count; + } + + pr_debug("%s:format=%x aot=%d ch=%d sr=%d\n", + __func__, aac_cfg.format, + aac_cfg.aot, aac_cfg.ch_cfg, + aac_cfg.sample_rate); + + /* Configure Media format block */ + rc = q6asm_media_format_block_aac(audio->ac, &aac_cfg); + if (rc < 0) { + pr_err("cmd media format block failed\n"); + break; + } + rc = audio_aio_enable(audio); + audio->eos_rsp = 0; + audio->eos_flag = 0; + if (!rc) { + rc = enable_volume_ramp(audio); + if (rc < 0) { + pr_err("%s: Failed to enable volume ramp\n", + __func__); + } + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("Audio Start procedure failed rc=%d\n", rc); + break; + } + pr_info("%s: AUDIO_START sessionid[%d]enable[%d]\n", __func__, + audio->ac->session, + audio->enabled); + if (audio->stopped == 1) + audio->stopped = 0; + break; + } + case AUDIO_SET_AAC_CONFIG: { + struct msm_audio_aac_config *aac_config; + uint16_t sce_left = 1, sce_right = 2; + + pr_debug("%s: AUDIO_SET_AAC_CONFIG\n", __func__); + aac_config = (struct msm_audio_aac_config *)arg; + if (aac_config == NULL) { + pr_err("%s: Invalid config pointer\n", __func__); + rc = -EINVAL; + break; + } + memcpy(audio->codec_cfg, aac_config, + sizeof(struct msm_audio_aac_config)); + /* PL_PR is 0 only need to check PL_SR */ + if (aac_config->dual_mono_mode > + AUDIO_AAC_DUAL_MONO_PL_SR) { + pr_err("%s:Invalid dual_mono mode =%d\n", __func__, + aac_config->dual_mono_mode); + } else { + /* convert the data from user into sce_left + * and sce_right based on the definitions + */ + pr_debug("%s: modify dual_mono mode =%d\n", __func__, + aac_config->dual_mono_mode); + switch (aac_config->dual_mono_mode) { + case AUDIO_AAC_DUAL_MONO_PL_PR: + sce_left = 1; + sce_right = 1; + break; + case AUDIO_AAC_DUAL_MONO_SL_SR: + sce_left = 2; + sce_right = 2; + break; + case AUDIO_AAC_DUAL_MONO_SL_PR: + sce_left = 2; + sce_right = 1; + break; + case AUDIO_AAC_DUAL_MONO_PL_SR: + default: + sce_left = 1; + sce_right = 2; + break; + } + rc = q6asm_cfg_dual_mono_aac(audio->ac, + sce_left, sce_right); + if (rc < 0) + pr_err("%s:asm cmd dualmono failed rc=%d\n", + __func__, rc); + } + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + break; + } + return rc; +} + +static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + case AUDIO_GET_AAC_CONFIG: { + if (copy_to_user((void *)arg, audio->codec_cfg, + sizeof(struct msm_audio_aac_config))) { + pr_err("%s: copy_to_user for AUDIO_GET_AAC_CONFIG failed\n", + __func__); + rc = -EFAULT; + break; + } + break; + } + case AUDIO_SET_AAC_CONFIG: { + struct msm_audio_aac_config aac_config; + + pr_debug("%s: AUDIO_SET_AAC_CONFIG\n", __func__); + if (copy_from_user(&aac_config, (void *)arg, + sizeof(aac_config))) { + pr_err("%s: copy_from_user for AUDIO_SET_AAC_CONFIG failed\n", + __func__); + rc = -EFAULT; + break; + } + rc = audio_ioctl_shared(file, cmd, &aac_config); + if (rc) + pr_err("%s:AUDIO_SET_AAC_CONFIG failed. Rc= %d\n", + __func__, rc); + break; + } + default: { + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); + rc = audio->codec_ioctl(file, cmd, arg); + if (rc) + pr_err("%s[%pK]:Failed in utils_ioctl: %d\n", + __func__, audio, rc); + } + } + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_audio_aac_config32 { + s16 format; + u16 audio_object; + u16 ep_config; /* 0 ~ 3 useful only obj = ERLC */ + u16 aac_section_data_resilience_flag; + u16 aac_scalefactor_data_resilience_flag; + u16 aac_spectral_data_resilience_flag; + u16 sbr_on_flag; + u16 sbr_ps_on_flag; + u16 dual_mono_mode; + u16 channel_configuration; + u16 sample_rate; +}; + +enum { + AUDIO_SET_AAC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_aac_config32), + AUDIO_GET_AAC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_aac_config32) +}; + +static long audio_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + case AUDIO_GET_AAC_CONFIG_32: { + struct msm_audio_aac_config *aac_config; + struct msm_audio_aac_config32 aac_config_32; + + aac_config = (struct msm_audio_aac_config *)audio->codec_cfg; + aac_config_32.format = aac_config->format; + aac_config_32.audio_object = aac_config->audio_object; + aac_config_32.ep_config = aac_config->ep_config; + aac_config_32.aac_section_data_resilience_flag = + aac_config->aac_section_data_resilience_flag; + aac_config_32.aac_scalefactor_data_resilience_flag = + aac_config->aac_scalefactor_data_resilience_flag; + aac_config_32.aac_spectral_data_resilience_flag = + aac_config->aac_spectral_data_resilience_flag; + aac_config_32.sbr_on_flag = aac_config->sbr_on_flag; + aac_config_32.sbr_ps_on_flag = aac_config->sbr_ps_on_flag; + aac_config_32.dual_mono_mode = aac_config->dual_mono_mode; + aac_config_32.channel_configuration = + aac_config->channel_configuration; + aac_config_32.sample_rate = aac_config->sample_rate; + + if (copy_to_user((void *)arg, &aac_config_32, + sizeof(aac_config_32))) { + pr_err("%s: copy_to_user for AUDIO_GET_AAC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + break; + } + case AUDIO_SET_AAC_CONFIG_32: { + struct msm_audio_aac_config aac_config; + struct msm_audio_aac_config32 aac_config_32; + + pr_debug("%s: AUDIO_SET_AAC_CONFIG\n", __func__); + if (copy_from_user(&aac_config_32, (void *)arg, + sizeof(aac_config_32))) { + pr_err("%s: copy_from_user for AUDIO_SET_AAC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + aac_config.format = aac_config_32.format; + aac_config.audio_object = aac_config_32.audio_object; + aac_config.ep_config = aac_config_32.ep_config; + aac_config.aac_section_data_resilience_flag = + aac_config_32.aac_section_data_resilience_flag; + aac_config.aac_scalefactor_data_resilience_flag = + aac_config_32.aac_scalefactor_data_resilience_flag; + aac_config.aac_spectral_data_resilience_flag = + aac_config_32.aac_spectral_data_resilience_flag; + aac_config.sbr_on_flag = aac_config_32.sbr_on_flag; + aac_config.sbr_ps_on_flag = aac_config_32.sbr_ps_on_flag; + aac_config.dual_mono_mode = aac_config_32.dual_mono_mode; + aac_config.channel_configuration = + aac_config_32.channel_configuration; + aac_config.sample_rate = aac_config_32.sample_rate; + + cmd = AUDIO_SET_AAC_CONFIG; + rc = audio_ioctl_shared(file, cmd, &aac_config); + if (rc) + pr_err("%s:AUDIO_SET_AAC_CONFIG failed. Rc= %d\n", + __func__, rc); + break; + } + default: { + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); + rc = audio->codec_compat_ioctl(file, cmd, arg); + if (rc) + pr_err("%s[%pK]:Failed in utils_ioctl: %d\n", + __func__, audio, rc); + } + } + return rc; +} +#else +#define audio_compat_ioctl NULL +#endif + +static int audio_open(struct inode *inode, struct file *file) +{ + struct q6audio_aio *audio = NULL; + int rc = 0; + struct msm_audio_aac_config *aac_config = NULL; + +#ifdef CONFIG_DEBUG_FS + /* 4 bytes represents decoder number, 1 byte for terminate string */ + char name[sizeof "msm_aac_" + 5]; +#endif + audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + + audio->codec_cfg = kzalloc(sizeof(struct msm_audio_aac_config), + GFP_KERNEL); + if (audio->codec_cfg == NULL) { + kfree(audio); + return -ENOMEM; + } + aac_config = audio->codec_cfg; + + /* Settings will be re-config at AUDIO_SET_CONFIG, + * but at least we need to have initial config + */ + audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN_AAC; + audio->miscdevice = &audio_aac_misc; + audio->wakelock_voted = false; + audio->audio_ws_mgr = &audio_aac_ws_mgr; + aac_config->dual_mono_mode = AUDIO_AAC_DUAL_MONO_INVALID; + + audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("Could not allocate memory for audio client\n"); + kfree(audio->codec_cfg); + kfree(audio); + return -ENOMEM; + } + rc = audio_aio_open(audio, file); + if (rc < 0) { + pr_err("%s: audio_aio_open rc=%d\n", + __func__, rc); + goto fail; + } + /* open in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) { + rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM, + FORMAT_MPEG4_AAC); + if (rc < 0) { + pr_err("NT mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = NON_TUNNEL_MODE; + /* open AAC decoder, expected frames is always 1 + * audio->buf_cfg.frames_per_buf = 0x01; + */ + audio->buf_cfg.meta_info_enable = 0x01; + } else if ((file->f_mode & FMODE_WRITE) && + !(file->f_mode & FMODE_READ)) { + rc = q6asm_open_write(audio->ac, FORMAT_MPEG4_AAC); + if (rc < 0) { + pr_err("T mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = TUNNEL_MODE; + audio->buf_cfg.meta_info_enable = 0x00; + } else { + pr_err("Not supported mode\n"); + rc = -EACCES; + goto fail; + } + +#ifdef CONFIG_DEBUG_FS + snprintf(name, sizeof(name), "msm_aac_%04x", audio->ac->session); + audio->dentry = debugfs_create_file(name, S_IFREG | 0444, + NULL, (void *)audio, + &audio_aac_debug_fops); + + if (IS_ERR(audio->dentry)) + pr_debug("debugfs_create_file failed\n"); +#endif + pr_info("%s:aacdec success mode[%d]session[%d]\n", __func__, + audio->feedback, + audio->ac->session); + return rc; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio->codec_cfg); + kfree(audio); + return rc; +} + +static const struct file_operations audio_aac_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_aio_release, + .unlocked_ioctl = audio_ioctl, + .fsync = audio_aio_fsync, + .compat_ioctl = audio_compat_ioctl +}; + +static struct miscdevice audio_aac_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_aac", + .fops = &audio_aac_fops, +}; + +static int __init audio_aac_init(void) +{ + int ret = misc_register(&audio_aac_misc); + + if (ret == 0) + device_init_wakeup(audio_aac_misc.this_device, true); + audio_aac_ws_mgr.ref_cnt = 0; + mutex_init(&audio_aac_ws_mgr.ws_lock); + + return ret; +} + +device_initcall(audio_aac_init); diff --git a/drivers/misc/qcom/qdsp6v2/audio_alac.c b/drivers/misc/qcom/qdsp6v2/audio_alac.c new file mode 100644 index 000000000000..d0b86c684808 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_alac.c @@ -0,0 +1,435 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include "audio_utils_aio.h" + +static struct miscdevice audio_alac_misc; +static struct ws_mgr audio_alac_ws_mgr; + +static const struct file_operations audio_alac_debug_fops = { + .read = audio_aio_debug_read, + .open = audio_aio_debug_open, +}; + +static struct dentry *config_debugfs_create_file(const char *name, void *data) +{ + return debugfs_create_file(name, S_IFREG | 0444, + NULL, (void *)data, &audio_alac_debug_fops); +} + +static int alac_channel_map(u8 *channel_mapping, uint32_t channels); + +static long audio_ioctl_shared(struct file *file, unsigned int cmd, + void *arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + struct asm_alac_cfg alac_cfg; + struct msm_audio_alac_config *alac_config; + u8 channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL]; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + + if (alac_channel_map(channel_mapping, + audio->pcm_cfg.channel_count)) { + pr_err("%s: setting channel map failed %d\n", + __func__, audio->pcm_cfg.channel_count); + } + + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, + audio, audio->ac->session); + if (audio->feedback == NON_TUNNEL_MODE) { + /* Configure PCM output block */ + rc = q6asm_enc_cfg_blk_pcm_v2(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count, + 16, /*bits per sample*/ + false, false, channel_mapping); + if (rc < 0) { + pr_err("pcm output block config failed\n"); + break; + } + } + alac_config = (struct msm_audio_alac_config *)audio->codec_cfg; + alac_cfg.frame_length = alac_config->frameLength; + alac_cfg.compatible_version = alac_config->compatVersion; + alac_cfg.bit_depth = alac_config->bitDepth; + alac_cfg.pb = alac_config->pb; + alac_cfg.mb = alac_config->mb; + alac_cfg.kb = alac_config->kb; + alac_cfg.num_channels = alac_config->channelCount; + alac_cfg.max_run = alac_config->maxRun; + alac_cfg.max_frame_bytes = alac_config->maxSize; + alac_cfg.avg_bit_rate = alac_config->averageBitRate; + alac_cfg.sample_rate = alac_config->sampleRate; + alac_cfg.channel_layout_tag = alac_config->channelLayout; + pr_debug("%s: frame_length %d compatible_version %d bit_depth %d pb %d mb %d kb %d num_channels %d max_run %d max_frame_bytes %d avg_bit_rate %d sample_rate %d channel_layout_tag %d\n", + __func__, alac_config->frameLength, + alac_config->compatVersion, + alac_config->bitDepth, alac_config->pb, + alac_config->mb, alac_config->kb, + alac_config->channelCount, alac_config->maxRun, + alac_config->maxSize, + alac_config->averageBitRate, + alac_config->sampleRate, + alac_config->channelLayout); + /* Configure Media format block */ + rc = q6asm_media_format_block_alac(audio->ac, &alac_cfg, + audio->ac->stream_id); + if (rc < 0) { + pr_err("cmd media format block failed\n"); + break; + } + rc = audio_aio_enable(audio); + audio->eos_rsp = 0; + audio->eos_flag = 0; + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("Audio Start procedure failed rc=%d\n", rc); + break; + } + pr_debug("AUDIO_START success enable[%d]\n", audio->enabled); + if (audio->stopped == 1) + audio->stopped = 0; + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + break; + } + return rc; +} + +static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + case AUDIO_GET_ALAC_CONFIG: { + if (copy_to_user((void *)arg, audio->codec_cfg, + sizeof(struct msm_audio_alac_config))) { + pr_err("%s:copy_to_user for AUDIO_GET_ALAC_CONFIG failed\n", + __func__); + rc = -EFAULT; + break; + } + break; + } + case AUDIO_SET_ALAC_CONFIG: { + if (copy_from_user(audio->codec_cfg, (void *)arg, + sizeof(struct msm_audio_alac_config))) { + pr_err("%s:copy_from_user for AUDIO_SET_ALAC_CONFIG failed\n", + __func__); + rc = -EFAULT; + break; + } + break; + } + default: { + rc = audio->codec_ioctl(file, cmd, arg); + if (rc) + pr_err("Failed in utils_ioctl: %d\n", rc); + break; + } + } + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_audio_alac_config_32 { + u32 frameLength; + u8 compatVersion; + u8 bitDepth; + u8 pb; + u8 mb; + u8 kb; + u8 channelCount; + u16 maxRun; + u32 maxSize; + u32 averageBitRate; + u32 sampleRate; + u32 channelLayout; +}; + +enum { + AUDIO_GET_ALAC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_alac_config_32), + AUDIO_SET_ALAC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_alac_config_32) +}; + +static long audio_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + case AUDIO_GET_ALAC_CONFIG_32: { + struct msm_audio_alac_config *alac_config; + struct msm_audio_alac_config_32 alac_config_32; + + memset(&alac_config_32, 0, sizeof(alac_config_32)); + + alac_config = (struct msm_audio_alac_config *)audio->codec_cfg; + alac_config_32.frameLength = alac_config->frameLength; + alac_config_32.compatVersion = + alac_config->compatVersion; + alac_config_32.bitDepth = alac_config->bitDepth; + alac_config_32.pb = alac_config->pb; + alac_config_32.mb = alac_config->mb; + alac_config_32.kb = alac_config->kb; + alac_config_32.channelCount = alac_config->channelCount; + alac_config_32.maxRun = alac_config->maxRun; + alac_config_32.maxSize = alac_config->maxSize; + alac_config_32.averageBitRate = alac_config->averageBitRate; + alac_config_32.sampleRate = alac_config->sampleRate; + alac_config_32.channelLayout = alac_config->channelLayout; + + if (copy_to_user((void *)arg, &alac_config_32, + sizeof(alac_config_32))) { + pr_err("%s: copy_to_user for GET_ALAC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + break; + } + case AUDIO_SET_ALAC_CONFIG_32: { + struct msm_audio_alac_config *alac_config; + struct msm_audio_alac_config_32 alac_config_32; + + if (copy_from_user(&alac_config_32, (void *)arg, + sizeof(alac_config_32))) { + pr_err("%s: copy_from_user for SET_ALAC_CONFIG_32 failed\n" + , __func__); + rc = -EFAULT; + break; + } + alac_config = (struct msm_audio_alac_config *)audio->codec_cfg; + alac_config->frameLength = alac_config_32.frameLength; + alac_config->compatVersion = + alac_config_32.compatVersion; + alac_config->bitDepth = alac_config_32.bitDepth; + alac_config->pb = alac_config_32.pb; + alac_config->mb = alac_config_32.mb; + alac_config->kb = alac_config_32.kb; + alac_config->channelCount = alac_config_32.channelCount; + alac_config->maxRun = alac_config_32.maxRun; + alac_config->maxSize = alac_config_32.maxSize; + alac_config->averageBitRate = alac_config_32.averageBitRate; + alac_config->sampleRate = alac_config_32.sampleRate; + alac_config->channelLayout = alac_config_32.channelLayout; + + break; + } + default: { + rc = audio->codec_compat_ioctl(file, cmd, arg); + if (rc) + pr_err("Failed in utils_ioctl: %d\n", rc); + break; + } + } + return rc; +} +#else +#define audio_compat_ioctl NULL +#endif + +static int audio_open(struct inode *inode, struct file *file) +{ + struct q6audio_aio *audio = NULL; + int rc = 0; + + /* 4 bytes represents decoder number, 1 byte for terminate string */ + char name[sizeof "msm_alac_" + 5]; + + audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL); + if (!audio) + return -ENOMEM; + + audio->codec_cfg = kzalloc(sizeof(struct msm_audio_alac_config), + GFP_KERNEL); + if (!audio->codec_cfg) { + kfree(audio); + return -ENOMEM; + } + + audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN; + audio->miscdevice = &audio_alac_misc; + audio->wakelock_voted = false; + audio->audio_ws_mgr = &audio_alac_ws_mgr; + + audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("Could not allocate memory for audio client\n"); + kfree(audio->codec_cfg); + kfree(audio); + return -ENOMEM; + } + rc = audio_aio_open(audio, file); + if (rc < 0) { + pr_err("%s: audio_aio_open rc=%d\n", + __func__, rc); + goto fail; + } + /* open in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) { + rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM, + FORMAT_ALAC); + if (rc < 0) { + pr_err("NT mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = NON_TUNNEL_MODE; + /* open ALAC decoder, expected frames is always 1*/ + audio->buf_cfg.frames_per_buf = 0x01; + audio->buf_cfg.meta_info_enable = 0x01; + } else if ((file->f_mode & FMODE_WRITE) && + !(file->f_mode & FMODE_READ)) { + rc = q6asm_open_write(audio->ac, FORMAT_ALAC); + if (rc < 0) { + pr_err("T mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = TUNNEL_MODE; + audio->buf_cfg.meta_info_enable = 0x00; + } else { + pr_err("Not supported mode\n"); + rc = -EACCES; + goto fail; + } + + snprintf(name, sizeof(name), "msm_alac_%04x", audio->ac->session); + audio->dentry = config_debugfs_create_file(name, (void *)audio); + + if (IS_ERR_OR_NULL(audio->dentry)) + pr_debug("debugfs_create_file failed\n"); + pr_debug("%s:alacdec success mode[%d]session[%d]\n", __func__, + audio->feedback, + audio->ac->session); + return rc; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio->codec_cfg); + kfree(audio); + return rc; +} + +static int alac_channel_map(u8 *channel_mapping, uint32_t channels) +{ + u8 *lchannel_mapping; + + lchannel_mapping = channel_mapping; + pr_debug("%s: channels passed: %d\n", __func__, channels); + if (channels == 1) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + } else if (channels == 2) { + lchannel_mapping[0] = PCM_CHANNEL_FL; + lchannel_mapping[1] = PCM_CHANNEL_FR; + } else if (channels == 3) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FL; + lchannel_mapping[2] = PCM_CHANNEL_FR; + } else if (channels == 4) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FL; + lchannel_mapping[2] = PCM_CHANNEL_FR; + lchannel_mapping[3] = PCM_CHANNEL_CS; + } else if (channels == 5) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FL; + lchannel_mapping[2] = PCM_CHANNEL_FR; + lchannel_mapping[3] = PCM_CHANNEL_LS; + lchannel_mapping[4] = PCM_CHANNEL_RS; + } else if (channels == 6) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FL; + lchannel_mapping[2] = PCM_CHANNEL_FR; + lchannel_mapping[3] = PCM_CHANNEL_LS; + lchannel_mapping[4] = PCM_CHANNEL_RS; + lchannel_mapping[5] = PCM_CHANNEL_LFE; + } else if (channels == 7) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FL; + lchannel_mapping[2] = PCM_CHANNEL_FR; + lchannel_mapping[3] = PCM_CHANNEL_LS; + lchannel_mapping[4] = PCM_CHANNEL_RS; + lchannel_mapping[5] = PCM_CHANNEL_CS; + lchannel_mapping[6] = PCM_CHANNEL_LFE; + } else if (channels == 8) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FLC; + lchannel_mapping[2] = PCM_CHANNEL_FRC; + lchannel_mapping[3] = PCM_CHANNEL_FL; + lchannel_mapping[4] = PCM_CHANNEL_FR; + lchannel_mapping[5] = PCM_CHANNEL_LS; + lchannel_mapping[6] = PCM_CHANNEL_RS; + lchannel_mapping[7] = PCM_CHANNEL_LFE; + } else { + pr_err("%s: ERROR.unsupported num_ch = %u\n", + __func__, channels); + return -EINVAL; + } + return 0; +} + +static const struct file_operations audio_alac_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_aio_release, + .unlocked_ioctl = audio_ioctl, + .fsync = audio_aio_fsync, + .compat_ioctl = audio_compat_ioctl +}; + +static struct miscdevice audio_alac_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_alac", + .fops = &audio_alac_fops, +}; + +static int __init audio_alac_init(void) +{ + int ret = misc_register(&audio_alac_misc); + + if (ret == 0) + device_init_wakeup(audio_alac_misc.this_device, true); + audio_alac_ws_mgr.ref_cnt = 0; + mutex_init(&audio_alac_ws_mgr.ws_lock); + + return ret; +} + +device_initcall(audio_alac_init); diff --git a/drivers/misc/qcom/qdsp6v2/audio_amrnb.c b/drivers/misc/qcom/qdsp6v2/audio_amrnb.c new file mode 100644 index 000000000000..950098be9b95 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_amrnb.c @@ -0,0 +1,226 @@ +/* amrnb audio output device + * + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include "audio_utils_aio.h" + +static struct miscdevice audio_amrnb_misc; +static struct ws_mgr audio_amrnb_ws_mgr; + +#ifdef CONFIG_DEBUG_FS +static const struct file_operations audio_amrnb_debug_fops = { + .read = audio_aio_debug_read, + .open = audio_aio_debug_open, +}; +#endif + +static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, + audio, audio->ac->session); + if (audio->feedback == NON_TUNNEL_MODE) { + /* Configure PCM output block */ + rc = q6asm_enc_cfg_blk_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + if (rc < 0) { + pr_err("pcm output block config failed\n"); + break; + } + } + + rc = audio_aio_enable(audio); + audio->eos_rsp = 0; + audio->eos_flag = 0; + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("Audio Start procedure failed rc=%d\n", rc); + break; + } + pr_debug("AUDIO_START success enable[%d]\n", audio->enabled); + if (audio->stopped == 1) + audio->stopped = 0; + break; + } + default: + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); + rc = audio->codec_ioctl(file, cmd, arg); + } + return rc; +} + +static long audio_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, + audio, audio->ac->session); + if (audio->feedback == NON_TUNNEL_MODE) { + /* Configure PCM output block */ + rc = q6asm_enc_cfg_blk_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + if (rc < 0) { + pr_err("%s: pcm output block config failed rc=%d\n", + __func__, rc); + break; + } + } + + rc = audio_aio_enable(audio); + audio->eos_rsp = 0; + audio->eos_flag = 0; + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("%s: Audio Start procedure failed rc=%d\n", + __func__, rc); + break; + } + pr_debug("AUDIO_START success enable[%d]\n", audio->enabled); + if (audio->stopped == 1) + audio->stopped = 0; + break; + } + default: + pr_debug("%s[%pK]: Calling compat ioctl\n", __func__, audio); + rc = audio->codec_compat_ioctl(file, cmd, arg); + } + return rc; +} + + +static int audio_open(struct inode *inode, struct file *file) +{ + struct q6audio_aio *audio = NULL; + int rc = 0; + +#ifdef CONFIG_DEBUG_FS + /* 4 bytes represents decoder number, 1 byte for terminate string */ + char name[sizeof "msm_amrnb_" + 5]; +#endif + audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + + audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN; + audio->miscdevice = &audio_amrnb_misc; + audio->wakelock_voted = false; + audio->audio_ws_mgr = &audio_amrnb_ws_mgr; + + audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("Could not allocate memory for audio client\n"); + kfree(audio); + return -ENOMEM; + } + rc = audio_aio_open(audio, file); + if (rc < 0) { + pr_err("%s: audio_aio_open rc=%d\n", + __func__, rc); + goto fail; + } + /* open in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) { + rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM, + FORMAT_AMRNB); + if (rc < 0) { + pr_err("NT mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = NON_TUNNEL_MODE; + audio->buf_cfg.frames_per_buf = 0x01; + audio->buf_cfg.meta_info_enable = 0x01; + } else if ((file->f_mode & FMODE_WRITE) && + !(file->f_mode & FMODE_READ)) { + rc = q6asm_open_write(audio->ac, FORMAT_AMRNB); + if (rc < 0) { + pr_err("T mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = TUNNEL_MODE; + audio->buf_cfg.meta_info_enable = 0x00; + } else { + pr_err("Not supported mode\n"); + rc = -EACCES; + goto fail; + } + +#ifdef CONFIG_DEBUG_FS + snprintf(name, sizeof(name), "msm_amrnb_%04x", audio->ac->session); + audio->dentry = debugfs_create_file(name, S_IFREG | 0444, + NULL, (void *)audio, + &audio_amrnb_debug_fops); + + if (IS_ERR(audio->dentry)) + pr_debug("debugfs_create_file failed\n"); +#endif + pr_info("%s:amrnb decoder open success, session_id = %d\n", __func__, + audio->ac->session); + return rc; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio); + return rc; +} + +static const struct file_operations audio_amrnb_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_aio_release, + .unlocked_ioctl = audio_ioctl, + .fsync = audio_aio_fsync, + .compat_ioctl = audio_compat_ioctl, +}; + +static struct miscdevice audio_amrnb_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_amrnb", + .fops = &audio_amrnb_fops, +}; + +static int __init audio_amrnb_init(void) +{ + int ret = misc_register(&audio_amrnb_misc); + + if (ret == 0) + device_init_wakeup(audio_amrnb_misc.this_device, true); + audio_amrnb_ws_mgr.ref_cnt = 0; + mutex_init(&audio_amrnb_ws_mgr.ws_lock); + + return ret; +} + +device_initcall(audio_amrnb_init); diff --git a/drivers/misc/qcom/qdsp6v2/audio_amrwb.c b/drivers/misc/qcom/qdsp6v2/audio_amrwb.c new file mode 100644 index 000000000000..cb5db0d61ecd --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_amrwb.c @@ -0,0 +1,231 @@ +/* amrwb audio output device + * + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include "audio_utils_aio.h" + +static struct miscdevice audio_amrwb_misc; +static struct ws_mgr audio_amrwb_ws_mgr; + +#ifdef CONFIG_DEBUG_FS +static const struct file_operations audio_amrwb_debug_fops = { + .read = audio_aio_debug_read, + .open = audio_aio_debug_open, +}; +#endif + +static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, + audio, audio->ac->session); + if (audio->feedback == NON_TUNNEL_MODE) { + /* Configure PCM output block */ + rc = q6asm_enc_cfg_blk_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + if (rc < 0) { + pr_err("pcm output block config failed\n"); + break; + } + } + + rc = audio_aio_enable(audio); + audio->eos_rsp = 0; + audio->eos_flag = 0; + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("Audio Start procedure failed rc=%d\n", rc); + break; + } + pr_debug("%s: AUDIO_START sessionid[%d]enable[%d]\n", __func__, + audio->ac->session, + audio->enabled); + if (audio->stopped == 1) + audio->stopped = 0; + break; + } + default: + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); + rc = audio->codec_ioctl(file, cmd, arg); + } + return rc; +} + +static long audio_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, + audio, audio->ac->session); + if (audio->feedback == NON_TUNNEL_MODE) { + /* Configure PCM output block */ + rc = q6asm_enc_cfg_blk_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + if (rc < 0) { + pr_err("%s: pcm output block config failed rc=%d\n", + __func__, rc); + break; + } + } + + rc = audio_aio_enable(audio); + audio->eos_rsp = 0; + audio->eos_flag = 0; + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("%s: Audio Start procedure failed rc=%d\n", + __func__, rc); + break; + } + pr_debug("%s: AUDIO_START sessionid[%d]enable[%d]\n", __func__, + audio->ac->session, + audio->enabled); + if (audio->stopped == 1) + audio->stopped = 0; + break; + } + default: + pr_debug("%s[%pK]: Calling compat ioctl\n", __func__, audio); + rc = audio->codec_compat_ioctl(file, cmd, arg); + } + return rc; +} + +static int audio_open(struct inode *inode, struct file *file) +{ + struct q6audio_aio *audio = NULL; + int rc = 0; + +#ifdef CONFIG_DEBUG_FS + /* 4 bytes represents decoder number, 1 byte for terminate string */ + char name[sizeof "msm_amrwb_" + 5]; +#endif + audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + + audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN; + audio->miscdevice = &audio_amrwb_misc; + audio->wakelock_voted = false; + audio->audio_ws_mgr = &audio_amrwb_ws_mgr; + + audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("Could not allocate memory for audio client\n"); + kfree(audio); + return -ENOMEM; + } + rc = audio_aio_open(audio, file); + if (rc < 0) { + pr_err("%s: audio_aio_open rc=%d\n", + __func__, rc); + goto fail; + } + + /* open in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) { + rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM, + FORMAT_AMRWB); + if (rc < 0) { + pr_err("NT mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = NON_TUNNEL_MODE; + audio->buf_cfg.frames_per_buf = 0x01; + audio->buf_cfg.meta_info_enable = 0x01; + } else if ((file->f_mode & FMODE_WRITE) && + !(file->f_mode & FMODE_READ)) { + rc = q6asm_open_write(audio->ac, FORMAT_AMRWB); + if (rc < 0) { + pr_err("T mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = TUNNEL_MODE; + audio->buf_cfg.meta_info_enable = 0x00; + } else { + pr_err("Not supported mode\n"); + rc = -EACCES; + goto fail; + } + +#ifdef CONFIG_DEBUG_FS + snprintf(name, sizeof(name), "msm_amrwb_%04x", audio->ac->session); + audio->dentry = debugfs_create_file(name, S_IFREG | 0444, + NULL, (void *)audio, + &audio_amrwb_debug_fops); + + if (IS_ERR(audio->dentry)) + pr_debug("debugfs_create_file failed\n"); +#endif + pr_info("%s: AMRWB dec success mode[%d]session[%d]\n", __func__, + audio->feedback, + audio->ac->session); + return 0; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio); + return rc; +} + +static const struct file_operations audio_amrwb_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_aio_release, + .unlocked_ioctl = audio_ioctl, + .fsync = audio_aio_fsync, + .compat_ioctl = audio_compat_ioctl, +}; + +static struct miscdevice audio_amrwb_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_amrwb", + .fops = &audio_amrwb_fops, +}; + +static int __init audio_amrwb_init(void) +{ + int ret = misc_register(&audio_amrwb_misc); + + if (ret == 0) + device_init_wakeup(audio_amrwb_misc.this_device, true); + audio_amrwb_ws_mgr.ref_cnt = 0; + mutex_init(&audio_amrwb_ws_mgr.ws_lock); + + return ret; +} + +device_initcall(audio_amrwb_init); diff --git a/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c b/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c new file mode 100644 index 000000000000..458a80c4c5bf --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c @@ -0,0 +1,397 @@ +/* amr-wbplus audio output device + * + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include "audio_utils_aio.h" + +static struct miscdevice audio_amrwbplus_misc; +static struct ws_mgr audio_amrwbplus_ws_mgr; + +#ifdef CONFIG_DEBUG_FS +static const struct file_operations audio_amrwbplus_debug_fops = { + .read = audio_aio_debug_read, + .open = audio_aio_debug_open, +}; +static void config_debug_fs(struct q6audio_aio *audio) +{ + if (audio != NULL) { + char name[sizeof("msm_amrwbplus_") + 5]; + + snprintf(name, sizeof(name), "msm_amrwbplus_%04x", + audio->ac->session); + audio->dentry = debugfs_create_file(name, S_IFREG | 0444, + NULL, (void *)audio, + &audio_amrwbplus_debug_fops); + if (IS_ERR(audio->dentry)) + pr_debug("debugfs_create_file failed\n"); + } +} +#else +static void config_debug_fs(struct q6audio_aio *audio) +{ +} +#endif + +static long audio_ioctl_shared(struct file *file, unsigned int cmd, + void *arg) +{ + struct asm_amrwbplus_cfg q6_amrwbplus_cfg; + struct msm_audio_amrwbplus_config_v2 *amrwbplus_drv_config; + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: + pr_err("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, + audio, audio->ac->session); + if (audio->feedback == NON_TUNNEL_MODE) { + /* Configure PCM output block */ + rc = q6asm_enc_cfg_blk_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + if (rc < 0) { + pr_err("pcm output block config failed\n"); + break; + } + } + amrwbplus_drv_config = + (struct msm_audio_amrwbplus_config_v2 *)audio->codec_cfg; + + q6_amrwbplus_cfg.size_bytes = + amrwbplus_drv_config->size_bytes; + q6_amrwbplus_cfg.version = + amrwbplus_drv_config->version; + q6_amrwbplus_cfg.num_channels = + amrwbplus_drv_config->num_channels; + q6_amrwbplus_cfg.amr_band_mode = + amrwbplus_drv_config->amr_band_mode; + q6_amrwbplus_cfg.amr_dtx_mode = + amrwbplus_drv_config->amr_dtx_mode; + q6_amrwbplus_cfg.amr_frame_fmt = + amrwbplus_drv_config->amr_frame_fmt; + q6_amrwbplus_cfg.amr_lsf_idx = + amrwbplus_drv_config->amr_lsf_idx; + + rc = q6asm_media_format_block_amrwbplus(audio->ac, + &q6_amrwbplus_cfg); + if (rc < 0) { + pr_err("q6asm_media_format_block_amrwb+ failed...\n"); + break; + } + rc = audio_aio_enable(audio); + audio->eos_rsp = 0; + audio->eos_flag = 0; + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("Audio Start procedure failed rc=%d\n", rc); + break; + } + pr_debug("%s:AUDIO_START sessionid[%d]enable[%d]\n", __func__, + audio->ac->session, + audio->enabled); + if (audio->stopped == 1) + audio->stopped = 0; + + break; + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + break; + } + return rc; +} + +static long audio_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + case AUDIO_GET_AMRWBPLUS_CONFIG_V2: { + if ((audio) && (arg) && (audio->codec_cfg)) { + if (copy_to_user((void *)arg, audio->codec_cfg, + sizeof(struct msm_audio_amrwbplus_config_v2))) { + rc = -EFAULT; + pr_err("%s: copy_to_user for AUDIO_GET_AMRWBPLUS_CONFIG_V2 failed\n", + __func__); + break; + } + } else { + pr_err("%s: wb+ config v2 invalid parameters\n" + , __func__); + rc = -EFAULT; + break; + } + break; + } + case AUDIO_SET_AMRWBPLUS_CONFIG_V2: { + if ((audio) && (arg) && (audio->codec_cfg)) { + if (copy_from_user(audio->codec_cfg, (void *)arg, + sizeof(struct msm_audio_amrwbplus_config_v2))) { + rc = -EFAULT; + pr_err("%s: copy_from_user for AUDIO_SET_AMRWBPLUS_CONFIG_V2 failed\n", + __func__); + break; + } + } else { + pr_err("%s: wb+ config invalid parameters\n", + __func__); + rc = -EFAULT; + break; + } + break; + } + default: { + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); + rc = audio->codec_ioctl(file, cmd, arg); + break; + } + } + return rc; +} +#ifdef CONFIG_COMPAT +struct msm_audio_amrwbplus_config_v2_32 { + u32 size_bytes; + u32 version; + u32 num_channels; + u32 amr_band_mode; + u32 amr_dtx_mode; + u32 amr_frame_fmt; + u32 amr_lsf_idx; +}; + +enum { + AUDIO_GET_AMRWBPLUS_CONFIG_V2_32 = _IOR(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+2), + struct msm_audio_amrwbplus_config_v2_32), + AUDIO_SET_AMRWBPLUS_CONFIG_V2_32 = _IOW(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+3), + struct msm_audio_amrwbplus_config_v2_32) +}; + +static long audio_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + case AUDIO_GET_AMRWBPLUS_CONFIG_V2_32: { + if (audio && arg && (audio->codec_cfg)) { + struct msm_audio_amrwbplus_config_v2 *amrwbplus_config; + struct msm_audio_amrwbplus_config_v2_32 + amrwbplus_config_32; + + memset(&amrwbplus_config_32, 0, + sizeof(amrwbplus_config_32)); + + amrwbplus_config = + (struct msm_audio_amrwbplus_config_v2 *) + audio->codec_cfg; + amrwbplus_config_32.size_bytes = + amrwbplus_config->size_bytes; + amrwbplus_config_32.version = + amrwbplus_config->version; + amrwbplus_config_32.num_channels = + amrwbplus_config->num_channels; + amrwbplus_config_32.amr_band_mode = + amrwbplus_config->amr_band_mode; + amrwbplus_config_32.amr_dtx_mode = + amrwbplus_config->amr_dtx_mode; + amrwbplus_config_32.amr_frame_fmt = + amrwbplus_config->amr_frame_fmt; + amrwbplus_config_32.amr_lsf_idx = + amrwbplus_config->amr_lsf_idx; + + if (copy_to_user((void *)arg, &amrwbplus_config_32, + sizeof(amrwbplus_config_32))) { + rc = -EFAULT; + pr_err("%s: copy_to_user for AUDIO_GET_AMRWBPLUS_CONFIG_V2_32 failed\n" + , __func__); + } + } else { + pr_err("%s: wb+ Get config v2 invalid parameters\n" + , __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_AMRWBPLUS_CONFIG_V2_32: { + if ((audio) && (arg) && (audio->codec_cfg)) { + struct msm_audio_amrwbplus_config_v2 *amrwbplus_config; + struct msm_audio_amrwbplus_config_v2_32 + amrwbplus_config_32; + + if (copy_from_user(&amrwbplus_config_32, (void *)arg, + sizeof(struct msm_audio_amrwbplus_config_v2_32))) { + rc = -EFAULT; + pr_err("%s: copy_from_user for AUDIO_SET_AMRWBPLUS_CONFIG_V2_32 failed\n" + , __func__); + break; + } + amrwbplus_config = + (struct msm_audio_amrwbplus_config_v2 *) + audio->codec_cfg; + amrwbplus_config->size_bytes = + amrwbplus_config_32.size_bytes; + amrwbplus_config->version = + amrwbplus_config_32.version; + amrwbplus_config->num_channels = + amrwbplus_config_32.num_channels; + amrwbplus_config->amr_band_mode = + amrwbplus_config_32.amr_band_mode; + amrwbplus_config->amr_dtx_mode = + amrwbplus_config_32.amr_dtx_mode; + amrwbplus_config->amr_frame_fmt = + amrwbplus_config_32.amr_frame_fmt; + amrwbplus_config->amr_lsf_idx = + amrwbplus_config_32.amr_lsf_idx; + } else { + pr_err("%s: wb+ config invalid parameters\n", + __func__); + rc = -EFAULT; + } + break; + } + default: { + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); + rc = audio->codec_compat_ioctl(file, cmd, arg); + break; + } + } + return rc; +} +#else +#define audio_compat_ioctl NULL +#endif + +static int audio_open(struct inode *inode, struct file *file) +{ + struct q6audio_aio *audio = NULL; + int rc = 0; + + audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + + audio->codec_cfg = + kzalloc(sizeof(struct msm_audio_amrwbplus_config_v2), GFP_KERNEL); + if (audio->codec_cfg == NULL) { + kfree(audio); + return -ENOMEM; + } + audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN; + audio->miscdevice = &audio_amrwbplus_misc; + audio->wakelock_voted = false; + audio->audio_ws_mgr = &audio_amrwbplus_ws_mgr; + + audio->ac = + q6asm_audio_client_alloc((app_cb) q6_audio_cb, (void *)audio); + + if (!audio->ac) { + pr_err("Could not allocate memory for audio client\n"); + kfree(audio->codec_cfg); + kfree(audio); + return -ENOMEM; + } + rc = audio_aio_open(audio, file); + if (rc < 0) { + pr_err("%s: audio_aio_open rc=%d\n", + __func__, rc); + goto fail; + } + + /* open in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) { + rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM, + FORMAT_AMR_WB_PLUS); + if (rc < 0) { + pr_err("amrwbplus NT mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = NON_TUNNEL_MODE; + audio->buf_cfg.frames_per_buf = 0x01; + audio->buf_cfg.meta_info_enable = 0x01; + } else if ((file->f_mode & FMODE_WRITE) && + !(file->f_mode & FMODE_READ)) { + rc = q6asm_open_write(audio->ac, FORMAT_AMR_WB_PLUS); + if (rc < 0) { + pr_err("wb+ T mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = TUNNEL_MODE; + audio->buf_cfg.meta_info_enable = 0x00; + } else { + pr_err("audio_amrwbplus Not supported mode\n"); + rc = -EACCES; + goto fail; + } + + config_debug_fs(audio); + pr_debug("%s: AMRWBPLUS dec success mode[%d]session[%d]\n", __func__, + audio->feedback, + audio->ac->session); + return 0; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio->codec_cfg); + kfree(audio); + return rc; +} + +static const struct file_operations audio_amrwbplus_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_aio_release, + .unlocked_ioctl = audio_ioctl, + .fsync = audio_aio_fsync, + .compat_ioctl = audio_compat_ioctl +}; + +static struct miscdevice audio_amrwbplus_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_amrwbplus", + .fops = &audio_amrwbplus_fops, +}; + +static int __init audio_amrwbplus_init(void) +{ + int ret = misc_register(&audio_amrwbplus_misc); + + if (ret == 0) + device_init_wakeup(audio_amrwbplus_misc.this_device, true); + audio_amrwbplus_ws_mgr.ref_cnt = 0; + mutex_init(&audio_amrwbplus_ws_mgr.ws_lock); + + return ret; +} + +device_initcall(audio_amrwbplus_init); diff --git a/drivers/misc/qcom/qdsp6v2/audio_ape.c b/drivers/misc/qcom/qdsp6v2/audio_ape.c new file mode 100644 index 000000000000..d7dc0648aeda --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_ape.c @@ -0,0 +1,359 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include "audio_utils_aio.h" + +static struct miscdevice audio_ape_misc; +static struct ws_mgr audio_ape_ws_mgr; + +static const struct file_operations audio_ape_debug_fops = { + .read = audio_aio_debug_read, + .open = audio_aio_debug_open, +}; +static struct dentry *config_debugfs_create_file(const char *name, void *data) +{ + return debugfs_create_file(name, S_IFREG | 0444, + NULL, (void *)data, &audio_ape_debug_fops); +} + +static long audio_ioctl_shared(struct file *file, unsigned int cmd, + void *arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + struct asm_ape_cfg ape_cfg; + struct msm_audio_ape_config *ape_config; + + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, + audio, audio->ac->session); + if (audio->feedback == NON_TUNNEL_MODE) { + /* Configure PCM output block */ + rc = q6asm_enc_cfg_blk_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + if (rc < 0) { + pr_err("pcm output block config failed\n"); + break; + } + } + ape_config = (struct msm_audio_ape_config *)audio->codec_cfg; + ape_cfg.compatible_version = ape_config->compatibleVersion; + ape_cfg.compression_level = ape_config->compressionLevel; + ape_cfg.format_flags = ape_config->formatFlags; + ape_cfg.blocks_per_frame = ape_config->blocksPerFrame; + ape_cfg.final_frame_blocks = ape_config->finalFrameBlocks; + ape_cfg.total_frames = ape_config->totalFrames; + ape_cfg.bits_per_sample = ape_config->bitsPerSample; + ape_cfg.num_channels = ape_config->numChannels; + ape_cfg.sample_rate = ape_config->sampleRate; + ape_cfg.seek_table_present = ape_config->seekTablePresent; + pr_debug("%s: compatibleVersion %d compressionLevel %d formatFlags %d blocksPerFrame %d finalFrameBlocks %d totalFrames %d bitsPerSample %d numChannels %d sampleRate %d seekTablePresent %d\n", + __func__, ape_config->compatibleVersion, + ape_config->compressionLevel, + ape_config->formatFlags, + ape_config->blocksPerFrame, + ape_config->finalFrameBlocks, + ape_config->totalFrames, + ape_config->bitsPerSample, + ape_config->numChannels, + ape_config->sampleRate, + ape_config->seekTablePresent); + /* Configure Media format block */ + rc = q6asm_media_format_block_ape(audio->ac, &ape_cfg, + audio->ac->stream_id); + if (rc < 0) { + pr_err("cmd media format block failed\n"); + break; + } + rc = audio_aio_enable(audio); + audio->eos_rsp = 0; + audio->eos_flag = 0; + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("Audio Start procedure failed rc=%d\n", rc); + break; + } + pr_debug("AUDIO_START success enable[%d]\n", audio->enabled); + if (audio->stopped == 1) + audio->stopped = 0; + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + break; + } + return rc; +} + +static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + case AUDIO_GET_APE_CONFIG: { + if (copy_to_user((void *)arg, audio->codec_cfg, + sizeof(struct msm_audio_ape_config))) { + pr_err("%s:copy_to_user for AUDIO_GET_APE_CONFIG failed\n", + __func__); + rc = -EFAULT; + break; + } + break; + } + case AUDIO_SET_APE_CONFIG: { + if (copy_from_user(audio->codec_cfg, (void *)arg, + sizeof(struct msm_audio_ape_config))) { + pr_err("%s:copy_from_user for AUDIO_SET_APE_CONFIG failed\n", + __func__); + rc = -EFAULT; + break; + } + break; + } + default: { + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); + rc = audio->codec_ioctl(file, cmd, arg); + if (rc) + pr_err("Failed in utils_ioctl: %d\n", rc); + break; + } + } + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_audio_ape_config_32 { + u16 compatibleVersion; + u16 compressionLevel; + u32 formatFlags; + u32 blocksPerFrame; + u32 finalFrameBlocks; + u32 totalFrames; + u16 bitsPerSample; + u16 numChannels; + u32 sampleRate; + u32 seekTablePresent; + +}; + +enum { + AUDIO_GET_APE_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_ape_config_32), + AUDIO_SET_APE_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_ape_config_32) +}; + +static long audio_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + case AUDIO_GET_APE_CONFIG_32: { + struct msm_audio_ape_config *ape_config; + struct msm_audio_ape_config_32 ape_config_32; + + memset(&ape_config_32, 0, sizeof(ape_config_32)); + + ape_config = (struct msm_audio_ape_config *)audio->codec_cfg; + ape_config_32.compatibleVersion = ape_config->compatibleVersion; + ape_config_32.compressionLevel = + ape_config->compressionLevel; + ape_config_32.formatFlags = ape_config->formatFlags; + ape_config_32.blocksPerFrame = ape_config->blocksPerFrame; + ape_config_32.finalFrameBlocks = ape_config->finalFrameBlocks; + ape_config_32.totalFrames = ape_config->totalFrames; + ape_config_32.bitsPerSample = ape_config->bitsPerSample; + ape_config_32.numChannels = ape_config->numChannels; + ape_config_32.sampleRate = ape_config->sampleRate; + ape_config_32.seekTablePresent = ape_config->seekTablePresent; + + if (copy_to_user((void *)arg, &ape_config_32, + sizeof(ape_config_32))) { + pr_err("%s: copy_to_user for GET_APE_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + break; + } + case AUDIO_SET_APE_CONFIG_32: { + struct msm_audio_ape_config *ape_config; + struct msm_audio_ape_config_32 ape_config_32; + + if (copy_from_user(&ape_config_32, (void *)arg, + sizeof(ape_config_32))) { + pr_err("%s: copy_from_user for SET_APE_CONFIG_32 failed\n" + , __func__); + rc = -EFAULT; + break; + } + ape_config = (struct msm_audio_ape_config *)audio->codec_cfg; + ape_config->compatibleVersion = ape_config_32.compatibleVersion; + ape_config->compressionLevel = + ape_config_32.compressionLevel; + ape_config->formatFlags = ape_config_32.formatFlags; + ape_config->blocksPerFrame = ape_config_32.blocksPerFrame; + ape_config->finalFrameBlocks = ape_config_32.finalFrameBlocks; + ape_config->totalFrames = ape_config_32.totalFrames; + ape_config->bitsPerSample = ape_config_32.bitsPerSample; + ape_config->numChannels = ape_config_32.numChannels; + ape_config->sampleRate = ape_config_32.sampleRate; + ape_config->seekTablePresent = ape_config_32.seekTablePresent; + + break; + } + default: { + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); + rc = audio->codec_compat_ioctl(file, cmd, arg); + if (rc) + pr_err("Failed in utils_ioctl: %d\n", rc); + break; + } + } + return rc; +} +#else +#define audio_compat_ioctl NULL +#endif + +static int audio_open(struct inode *inode, struct file *file) +{ + struct q6audio_aio *audio = NULL; + int rc = 0; + + /* 4 bytes represents decoder number, 1 byte for terminate string */ + char name[sizeof "msm_ape_" + 5]; + + audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL); + if (!audio) + return -ENOMEM; + + audio->codec_cfg = kzalloc(sizeof(struct msm_audio_ape_config), + GFP_KERNEL); + if (!audio->codec_cfg) { + kfree(audio); + return -ENOMEM; + } + + audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN; + audio->miscdevice = &audio_ape_misc; + audio->wakelock_voted = false; + audio->audio_ws_mgr = &audio_ape_ws_mgr; + + audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("Could not allocate memory for audio client\n"); + kfree(audio->codec_cfg); + kfree(audio); + return -ENOMEM; + } + rc = audio_aio_open(audio, file); + if (rc < 0) { + pr_err("%s: audio_aio_open rc=%d\n", + __func__, rc); + goto fail; + } + /* open in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) { + rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM, + FORMAT_APE); + if (rc < 0) { + pr_err("NT mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = NON_TUNNEL_MODE; + /* open APE decoder, expected frames is always 1*/ + audio->buf_cfg.frames_per_buf = 0x01; + audio->buf_cfg.meta_info_enable = 0x01; + } else if ((file->f_mode & FMODE_WRITE) && + !(file->f_mode & FMODE_READ)) { + rc = q6asm_open_write(audio->ac, FORMAT_APE); + if (rc < 0) { + pr_err("T mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = TUNNEL_MODE; + audio->buf_cfg.meta_info_enable = 0x00; + } else { + pr_err("Not supported mode\n"); + rc = -EACCES; + goto fail; + } + + snprintf(name, sizeof(name), "msm_ape_%04x", audio->ac->session); + audio->dentry = config_debugfs_create_file(name, (void *)audio); + + if (IS_ERR_OR_NULL(audio->dentry)) + pr_debug("debugfs_create_file failed\n"); + pr_debug("%s:apedec success mode[%d]session[%d]\n", __func__, + audio->feedback, + audio->ac->session); + return rc; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio->codec_cfg); + kfree(audio); + return rc; +} + +static const struct file_operations audio_ape_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_aio_release, + .unlocked_ioctl = audio_ioctl, + .fsync = audio_aio_fsync, + .compat_ioctl = audio_compat_ioctl +}; + +static struct miscdevice audio_ape_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_ape", + .fops = &audio_ape_fops, +}; + +static int __init audio_ape_init(void) +{ + int ret = misc_register(&audio_ape_misc); + + if (ret == 0) + device_init_wakeup(audio_ape_misc.this_device, true); + audio_ape_ws_mgr.ref_cnt = 0; + mutex_init(&audio_ape_ws_mgr.ws_lock); + + return ret; +} + +device_initcall(audio_ape_init); diff --git a/drivers/misc/qcom/qdsp6v2/audio_evrc.c b/drivers/misc/qcom/qdsp6v2/audio_evrc.c new file mode 100644 index 000000000000..87762319b013 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_evrc.c @@ -0,0 +1,184 @@ +/* evrc audio output device + * + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "audio_utils_aio.h" + +static struct miscdevice audio_evrc_misc; +static struct ws_mgr audio_evrc_ws_mgr; + +#ifdef CONFIG_DEBUG_FS +static const struct file_operations audio_evrc_debug_fops = { + .read = audio_aio_debug_read, + .open = audio_aio_debug_open, +}; +#endif + +static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, + audio, audio->ac->session); + if (audio->feedback == NON_TUNNEL_MODE) { + /* Configure PCM output block */ + rc = q6asm_enc_cfg_blk_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + if (rc < 0) { + pr_err("pcm output block config failed\n"); + break; + } + } + + rc = audio_aio_enable(audio); + audio->eos_rsp = 0; + audio->eos_flag = 0; + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("Audio Start procedure failed rc=%d\n", rc); + break; + } + pr_debug("%s: AUDIO_START sessionid[%d]enable[%d]\n", __func__, + audio->ac->session, + audio->enabled); + if (audio->stopped == 1) + audio->stopped = 0; + break; + } + default: + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); + rc = audio->codec_ioctl(file, cmd, arg); + } + return rc; +} + +static int audio_open(struct inode *inode, struct file *file) +{ + struct q6audio_aio *audio = NULL; + int rc = 0; + +#ifdef CONFIG_DEBUG_FS + /* 4 bytes represents decoder number, 1 byte for terminate string */ + char name[sizeof "msm_evrc_" + 5]; +#endif + audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + + /* Settings will be re-config at AUDIO_SET_CONFIG, + * but at least we need to have initial config + */ + audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN; + audio->miscdevice = &audio_evrc_misc; + audio->wakelock_voted = false; + audio->audio_ws_mgr = &audio_evrc_ws_mgr; + + audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("Could not allocate memory for audio client\n"); + kfree(audio); + return -ENOMEM; + } + rc = audio_aio_open(audio, file); + if (rc < 0) { + pr_err("%s: audio_aio_open rc=%d\n", + __func__, rc); + goto fail; + } + + /* open in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) { + rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM, + FORMAT_EVRC); + if (rc < 0) { + pr_err("NT mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = NON_TUNNEL_MODE; + audio->buf_cfg.frames_per_buf = 0x01; + audio->buf_cfg.meta_info_enable = 0x01; + } else if ((file->f_mode & FMODE_WRITE) && + !(file->f_mode & FMODE_READ)) { + rc = q6asm_open_write(audio->ac, FORMAT_EVRC); + if (rc < 0) { + pr_err("T mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = TUNNEL_MODE; + audio->buf_cfg.meta_info_enable = 0x00; + } else { + pr_err("Not supported mode\n"); + rc = -EACCES; + goto fail; + } + +#ifdef CONFIG_DEBUG_FS + snprintf(name, sizeof(name), "msm_evrc_%04x", audio->ac->session); + audio->dentry = debugfs_create_file(name, S_IFREG | 0444, + NULL, (void *)audio, + &audio_evrc_debug_fops); + + if (IS_ERR(audio->dentry)) + pr_debug("debugfs_create_file failed\n"); +#endif + pr_info("%s:dec success mode[%d]session[%d]\n", __func__, + audio->feedback, + audio->ac->session); + return rc; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio); + return rc; +} + +static const struct file_operations audio_evrc_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_aio_release, + .unlocked_ioctl = audio_ioctl, + .fsync = audio_aio_fsync, +}; + +static struct miscdevice audio_evrc_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_evrc", + .fops = &audio_evrc_fops, +}; + +static int __init audio_evrc_init(void) +{ + int ret = misc_register(&audio_evrc_misc); + + if (ret == 0) + device_init_wakeup(audio_evrc_misc.this_device, true); + audio_evrc_ws_mgr.ref_cnt = 0; + mutex_init(&audio_evrc_ws_mgr.ws_lock); + + return ret; +} + +device_initcall(audio_evrc_init); diff --git a/drivers/misc/qcom/qdsp6v2/audio_g711alaw.c b/drivers/misc/qcom/qdsp6v2/audio_g711alaw.c new file mode 100644 index 000000000000..24f87e4bd1a6 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_g711alaw.c @@ -0,0 +1,396 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include "audio_utils_aio.h" + +static struct miscdevice audio_g711alaw_misc; +static struct ws_mgr audio_g711_ws_mgr; + +static const struct file_operations audio_g711_debug_fops = { + .read = audio_aio_debug_read, + .open = audio_aio_debug_open, +}; + +static struct dentry *config_debugfs_create_file(const char *name, void *data) +{ + return debugfs_create_file(name, S_IFREG | 0444, + NULL, (void *)data, &audio_g711_debug_fops); +} + +static int g711_channel_map(u8 *channel_mapping, uint32_t channels); + +static long audio_ioctl_shared(struct file *file, unsigned int cmd, + void *arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + struct asm_g711_dec_cfg g711_dec_cfg; + struct msm_audio_g711_dec_config *g711_dec_config; + u8 channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL]; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + memset(&g711_dec_cfg, 0, sizeof(g711_dec_cfg)); + + if (g711_channel_map(channel_mapping, + audio->pcm_cfg.channel_count)) { + pr_err("%s: setting channel map failed %d\n", + __func__, audio->pcm_cfg.channel_count); + } + + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, + audio, audio->ac->session); + if (audio->feedback == NON_TUNNEL_MODE) { + /* Configure PCM output block */ + rc = q6asm_enc_cfg_blk_pcm_v2(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count, + 16, /*bits per sample*/ + false, false, channel_mapping); + if (rc < 0) { + pr_err("%s: pcm output block config failed rc=%d\n", + __func__, rc); + break; + } + } + g711_dec_config = + (struct msm_audio_g711_dec_config *)audio->codec_cfg; + g711_dec_cfg.sample_rate = g711_dec_config->sample_rate; + /* Configure Media format block */ + rc = q6asm_media_format_block_g711(audio->ac, &g711_dec_cfg, + audio->ac->stream_id); + if (rc < 0) { + pr_err("%s: cmd media format block failed rc=%d\n", + __func__, rc); + break; + } + rc = audio_aio_enable(audio); + audio->eos_rsp = 0; + audio->eos_flag = 0; + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("%s: Audio Start procedure failed rc=%d\n", + __func__, rc); + break; + } + pr_debug("%s: AUDIO_START success enable[%d]\n", + __func__, audio->enabled); + if (audio->stopped == 1) + audio->stopped = 0; + break; + } + default: + pr_debug("%s: Unknown ioctl cmd = %d", __func__, cmd); + break; + } + return rc; +} + +static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + case AUDIO_GET_G711_DEC_CONFIG: { + if (copy_to_user((void *)arg, audio->codec_cfg, + sizeof(struct msm_audio_g711_dec_config))) { + pr_err("%s: copy_to_user for AUDIO_GET_G711_DEC_CONFIG failed\n", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_G711_DEC_CONFIG: { + if (copy_from_user(audio->codec_cfg, (void *)arg, + sizeof(struct msm_audio_g711_dec_config))) { + pr_err("%s: copy_from_user for AUDIO_SET_G711_DEC_CONFIG failed\n", + __func__); + rc = -EFAULT; + } + break; + } + default: { + rc = audio->codec_ioctl(file, cmd, arg); + if (rc) + pr_err("%s: Failed in audio_aio_ioctl: %d cmd=%d\n", + __func__, rc, cmd); + break; + } + } + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_audio_g711_dec_config_32 { + u32 sample_rate; +}; + +enum { + AUDIO_SET_G711_DEC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_g711_dec_config_32), + AUDIO_GET_G711_DEC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_g711_dec_config_32) +}; + +static long audio_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + case AUDIO_GET_G711_DEC_CONFIG_32: { + struct msm_audio_g711_dec_config *g711_dec_config; + struct msm_audio_g711_dec_config_32 g711_dec_config_32; + + memset(&g711_dec_config_32, 0, sizeof(g711_dec_config_32)); + + g711_dec_config = + (struct msm_audio_g711_dec_config *)audio->codec_cfg; + g711_dec_config_32.sample_rate = g711_dec_config->sample_rate; + + if (copy_to_user((void *)arg, &g711_dec_config_32, + sizeof(g711_dec_config_32))) { + pr_err("%s: copy_to_user for AUDIO_GET_G711_DEC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_G711_DEC_CONFIG_32: { + struct msm_audio_g711_dec_config *g711_dec_config; + struct msm_audio_g711_dec_config_32 g711_dec_config_32; + + memset(&g711_dec_config_32, 0, sizeof(g711_dec_config_32)); + + if (copy_from_user(&g711_dec_config_32, (void *)arg, + sizeof(g711_dec_config_32))) { + pr_err("%s: copy_from_user for AUDIO_SET_G711_DEC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + + g711_dec_config = + (struct msm_audio_g711_dec_config *)audio->codec_cfg; + g711_dec_config->sample_rate = g711_dec_config_32.sample_rate; + + break; + } + default: { + rc = audio->codec_compat_ioctl(file, cmd, arg); + if (rc) + pr_err("%s: Failed in audio_aio_compat_ioctl: %d cmd=%d\n", + __func__, rc, cmd); + break; + } + } + return rc; +} +#else +#define audio_compat_ioctl NULL +#endif + +static int audio_open(struct inode *inode, struct file *file) +{ + struct q6audio_aio *audio = NULL; + int rc = 0; + /* 4 bytes represents decoder number, 1 byte for terminate string */ + char name[sizeof "msm_g711_" + 5]; + + audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL); + + if (!audio) + return -ENOMEM; + audio->codec_cfg = kzalloc(sizeof(struct msm_audio_g711_dec_config), + GFP_KERNEL); + if (!audio->codec_cfg) { + kfree(audio); + return -ENOMEM; + } + + audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN; + audio->miscdevice = &audio_g711alaw_misc; + audio->wakelock_voted = false; + audio->audio_ws_mgr = &audio_g711_ws_mgr; + + init_waitqueue_head(&audio->event_wait); + + audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("%s: Could not allocate memory for audio client\n", + __func__); + kfree(audio->codec_cfg); + kfree(audio); + return -ENOMEM; + } + rc = audio_aio_open(audio, file); + if (rc < 0) { + pr_err("%s: audio_aio_open rc=%d\n", + __func__, rc); + goto fail; + } + /* open in T/NT mode */ /*foramt:G711_ALAW*/ + if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) { + rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM, + FORMAT_G711_ALAW_FS); + if (rc < 0) { + pr_err("%s: NT mode Open failed rc=%d\n", __func__, rc); + goto fail; + } + audio->feedback = NON_TUNNEL_MODE; + /* open G711 decoder, expected frames is always 1*/ + audio->buf_cfg.frames_per_buf = 0x01; + audio->buf_cfg.meta_info_enable = 0x01; + } else if ((file->f_mode & FMODE_WRITE) && + !(file->f_mode & FMODE_READ)) { + rc = q6asm_open_write(audio->ac, FORMAT_G711_ALAW_FS); + if (rc < 0) { + pr_err("%s: T mode Open failed rc=%d\n", __func__, rc); + goto fail; + } + audio->feedback = TUNNEL_MODE; + audio->buf_cfg.meta_info_enable = 0x00; + } else { + pr_err("%s: %d mode is not supported mode\n", + __func__, file->f_mode); + rc = -EACCES; + goto fail; + } + + snprintf(name, sizeof(name), "msm_g711_%04x", audio->ac->session); + audio->dentry = config_debugfs_create_file(name, (void *)audio); + + if (IS_ERR_OR_NULL(audio->dentry)) + pr_debug("%s: debugfs_create_file failed\n", __func__); + pr_debug("%s: g711dec success mode[%d]session[%d]\n", __func__, + audio->feedback, + audio->ac->session); + return rc; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio->codec_cfg); + kfree(audio); + return rc; +} + +static int g711_channel_map(u8 *channel_mapping, uint32_t channels) +{ + u8 *lchannel_mapping; + + lchannel_mapping = channel_mapping; + pr_debug("%s: channels passed: %d\n", __func__, channels); + if (channels == 1) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + } else if (channels == 2) { + lchannel_mapping[0] = PCM_CHANNEL_FL; + lchannel_mapping[1] = PCM_CHANNEL_FR; + } else if (channels == 3) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FL; + lchannel_mapping[2] = PCM_CHANNEL_FR; + } else if (channels == 4) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FL; + lchannel_mapping[2] = PCM_CHANNEL_FR; + lchannel_mapping[3] = PCM_CHANNEL_CS; + } else if (channels == 5) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FL; + lchannel_mapping[2] = PCM_CHANNEL_FR; + lchannel_mapping[3] = PCM_CHANNEL_LS; + lchannel_mapping[4] = PCM_CHANNEL_RS; + } else if (channels == 6) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FL; + lchannel_mapping[2] = PCM_CHANNEL_FR; + lchannel_mapping[3] = PCM_CHANNEL_LS; + lchannel_mapping[4] = PCM_CHANNEL_RS; + lchannel_mapping[5] = PCM_CHANNEL_LFE; + } else if (channels == 7) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FL; + lchannel_mapping[2] = PCM_CHANNEL_FR; + lchannel_mapping[3] = PCM_CHANNEL_LS; + lchannel_mapping[4] = PCM_CHANNEL_RS; + lchannel_mapping[5] = PCM_CHANNEL_CS; + lchannel_mapping[6] = PCM_CHANNEL_LFE; + } else if (channels == 8) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FLC; + lchannel_mapping[2] = PCM_CHANNEL_FRC; + lchannel_mapping[3] = PCM_CHANNEL_FL; + lchannel_mapping[4] = PCM_CHANNEL_FR; + lchannel_mapping[5] = PCM_CHANNEL_LS; + lchannel_mapping[6] = PCM_CHANNEL_RS; + lchannel_mapping[7] = PCM_CHANNEL_LFE; + } else { + pr_err("%s: ERROR.unsupported num_ch = %u\n", + __func__, channels); + return -EINVAL; + } + return 0; +} + +static const struct file_operations audio_g711_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_aio_release, + .unlocked_ioctl = audio_ioctl, + .compat_ioctl = audio_compat_ioctl, + .fsync = audio_aio_fsync, +}; + +static struct miscdevice audio_g711alaw_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_g711alaw", + .fops = &audio_g711_fops, +}; + +static int __init audio_g711alaw_init(void) +{ + int ret = misc_register(&audio_g711alaw_misc); + + if (ret == 0) + device_init_wakeup(audio_g711alaw_misc.this_device, true); + audio_g711_ws_mgr.ref_cnt = 0; + mutex_init(&audio_g711_ws_mgr.ws_lock); + + return ret; +} +static void __exit audio_g711alaw_exit(void) +{ + misc_deregister(&audio_g711alaw_misc); + mutex_destroy(&audio_g711_ws_mgr.ws_lock); +} + +device_initcall(audio_g711alaw_init); +__exitcall(audio_g711alaw_exit); diff --git a/drivers/misc/qcom/qdsp6v2/audio_g711mlaw.c b/drivers/misc/qcom/qdsp6v2/audio_g711mlaw.c new file mode 100644 index 000000000000..10d368011931 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_g711mlaw.c @@ -0,0 +1,396 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include "audio_utils_aio.h" + +static struct miscdevice audio_g711mlaw_misc; +static struct ws_mgr audio_g711_ws_mgr; + +static const struct file_operations audio_g711_debug_fops = { + .read = audio_aio_debug_read, + .open = audio_aio_debug_open, +}; + +static struct dentry *config_debugfs_create_file(const char *name, void *data) +{ + return debugfs_create_file(name, S_IFREG | 0444, + NULL, (void *)data, &audio_g711_debug_fops); +} + +static int g711_channel_map(u8 *channel_mapping, uint32_t channels); + +static long audio_ioctl_shared(struct file *file, unsigned int cmd, + void *arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + struct asm_g711_dec_cfg g711_dec_cfg; + struct msm_audio_g711_dec_config *g711_dec_config; + u8 channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL]; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + memset(&g711_dec_cfg, 0, sizeof(g711_dec_cfg)); + + if (g711_channel_map(channel_mapping, + audio->pcm_cfg.channel_count)) { + pr_err("%s: setting channel map failed %d\n", + __func__, audio->pcm_cfg.channel_count); + } + + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, + audio, audio->ac->session); + if (audio->feedback == NON_TUNNEL_MODE) { + /* Configure PCM output block */ + rc = q6asm_enc_cfg_blk_pcm_v2(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count, + 16, /*bits per sample*/ + false, false, channel_mapping); + if (rc < 0) { + pr_err("%s: pcm output block config failed rc=%d\n", + __func__, rc); + break; + } + } + g711_dec_config = + (struct msm_audio_g711_dec_config *)audio->codec_cfg; + g711_dec_cfg.sample_rate = g711_dec_config->sample_rate; + /* Configure Media format block */ + rc = q6asm_media_format_block_g711(audio->ac, &g711_dec_cfg, + audio->ac->stream_id); + if (rc < 0) { + pr_err("%s: cmd media format block failed rc=%d\n", + __func__, rc); + break; + } + rc = audio_aio_enable(audio); + audio->eos_rsp = 0; + audio->eos_flag = 0; + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("%s: Audio Start procedure failed rc=%d\n", + __func__, rc); + break; + } + pr_debug("%s: AUDIO_START success enable[%d]\n", + __func__, audio->enabled); + if (audio->stopped == 1) + audio->stopped = 0; + break; + } + default: + pr_debug("%s: Unknown ioctl cmd = %d", __func__, cmd); + break; + } + return rc; +} + +static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + case AUDIO_GET_G711_DEC_CONFIG: { + if (copy_to_user((void *)arg, audio->codec_cfg, + sizeof(struct msm_audio_g711_dec_config))) { + pr_err("%s: AUDIO_GET_G711_DEC_CONFIG failed\n", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_G711_DEC_CONFIG: { + if (copy_from_user(audio->codec_cfg, (void *)arg, + sizeof(struct msm_audio_g711_dec_config))) { + pr_err("%s: AUDIO_SET_G711_DEC_CONFIG failed\n", + __func__); + rc = -EFAULT; + } + break; + } + default: { + rc = audio->codec_ioctl(file, cmd, arg); + if (rc) + pr_err("%s: Failed in audio_aio_ioctl: %d cmd=%d\n", + __func__, rc, cmd); + break; + } + } + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_audio_g711_dec_config_32 { + u32 sample_rate; +}; + +enum { + AUDIO_SET_G711_DEC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_g711_dec_config_32), + AUDIO_GET_G711_DEC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_g711_dec_config_32) +}; + +static long audio_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + case AUDIO_GET_G711_DEC_CONFIG_32: { + struct msm_audio_g711_dec_config *g711_dec_config; + struct msm_audio_g711_dec_config_32 g711_dec_config_32; + + memset(&g711_dec_config_32, 0, sizeof(g711_dec_config_32)); + + g711_dec_config = + (struct msm_audio_g711_dec_config *)audio->codec_cfg; + g711_dec_config_32.sample_rate = g711_dec_config->sample_rate; + + if (copy_to_user((void *)arg, &g711_dec_config_32, + sizeof(g711_dec_config_32))) { + pr_err("%s: copy_to_user for AUDIO_GET_G711_DEC_CONFIG failed\n", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_G711_DEC_CONFIG_32: { + struct msm_audio_g711_dec_config *g711_dec_config; + struct msm_audio_g711_dec_config_32 g711_dec_config_32; + + memset(&g711_dec_config_32, 0, sizeof(g711_dec_config_32)); + + if (copy_from_user(&g711_dec_config_32, (void *)arg, + sizeof(g711_dec_config_32))) { + pr_err("%s: copy_from_user for AUDIO_SET_G711_DEC_CONFIG failed\n", + __func__); + rc = -EFAULT; + break; + } + g711_dec_config = + (struct msm_audio_g711_dec_config *)audio->codec_cfg; + g711_dec_config->sample_rate = g711_dec_config_32.sample_rate; + + break; + } + default: { + rc = audio->codec_compat_ioctl(file, cmd, arg); + if (rc) + pr_err("%s: Failed in audio_aio_compat_ioctl: %d cmd=%d\n", + __func__, rc, cmd); + break; + } + } + return rc; +} +#else +#define audio_compat_ioctl NULL +#endif + +static int audio_open(struct inode *inode, struct file *file) +{ + struct q6audio_aio *audio = NULL; + int rc = 0; + /* 4 bytes represents decoder number, 1 byte for terminate string */ + char name[sizeof "msm_g711_" + 5]; + + audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL); + + if (!audio) + return -ENOMEM; + audio->codec_cfg = kzalloc(sizeof(struct msm_audio_g711_dec_config), + GFP_KERNEL); + if (!audio->codec_cfg) { + kfree(audio); + return -ENOMEM; + } + + audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN; + audio->miscdevice = &audio_g711mlaw_misc; + audio->wakelock_voted = false; + audio->audio_ws_mgr = &audio_g711_ws_mgr; + + init_waitqueue_head(&audio->event_wait); + + audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("%s: Could not allocate memory for audio client\n", + __func__); + kfree(audio->codec_cfg); + kfree(audio); + return -ENOMEM; + } + rc = audio_aio_open(audio, file); + if (rc < 0) { + pr_err("%s: audio_aio_open rc=%d\n", + __func__, rc); + goto fail; + } + /* open in T/NT mode */ /*foramt:G711_ALAW*/ + if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) { + rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM, + FORMAT_G711_MLAW_FS); + if (rc < 0) { + pr_err("%s: NT mode Open failed rc=%d\n", __func__, rc); + goto fail; + } + audio->feedback = NON_TUNNEL_MODE; + /* open G711 decoder, expected frames is always 1*/ + audio->buf_cfg.frames_per_buf = 0x01; + audio->buf_cfg.meta_info_enable = 0x01; + } else if ((file->f_mode & FMODE_WRITE) && + !(file->f_mode & FMODE_READ)) { + rc = q6asm_open_write(audio->ac, FORMAT_G711_MLAW_FS); + if (rc < 0) { + pr_err("%s: T mode Open failed rc=%d\n", __func__, rc); + goto fail; + } + audio->feedback = TUNNEL_MODE; + audio->buf_cfg.meta_info_enable = 0x00; + } else { + pr_err("%s: %d mode is not supported\n", __func__, + file->f_mode); + rc = -EACCES; + goto fail; + } + + snprintf(name, sizeof(name), "msm_g711_%04x", audio->ac->session); + audio->dentry = config_debugfs_create_file(name, (void *)audio); + + if (IS_ERR_OR_NULL(audio->dentry)) + pr_debug("%s: debugfs_create_file failed\n", __func__); + pr_debug("%s: g711dec success mode[%d]session[%d]\n", __func__, + audio->feedback, + audio->ac->session); + return rc; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio->codec_cfg); + kfree(audio); + return rc; +} + +static int g711_channel_map(u8 *channel_mapping, uint32_t channels) +{ + u8 *lchannel_mapping; + + lchannel_mapping = channel_mapping; + pr_debug("%s: channels passed: %d\n", __func__, channels); + if (channels == 1) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + } else if (channels == 2) { + lchannel_mapping[0] = PCM_CHANNEL_FL; + lchannel_mapping[1] = PCM_CHANNEL_FR; + } else if (channels == 3) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FL; + lchannel_mapping[2] = PCM_CHANNEL_FR; + } else if (channels == 4) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FL; + lchannel_mapping[2] = PCM_CHANNEL_FR; + lchannel_mapping[3] = PCM_CHANNEL_CS; + } else if (channels == 5) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FL; + lchannel_mapping[2] = PCM_CHANNEL_FR; + lchannel_mapping[3] = PCM_CHANNEL_LS; + lchannel_mapping[4] = PCM_CHANNEL_RS; + } else if (channels == 6) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FL; + lchannel_mapping[2] = PCM_CHANNEL_FR; + lchannel_mapping[3] = PCM_CHANNEL_LS; + lchannel_mapping[4] = PCM_CHANNEL_RS; + lchannel_mapping[5] = PCM_CHANNEL_LFE; + } else if (channels == 7) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FL; + lchannel_mapping[2] = PCM_CHANNEL_FR; + lchannel_mapping[3] = PCM_CHANNEL_LS; + lchannel_mapping[4] = PCM_CHANNEL_RS; + lchannel_mapping[5] = PCM_CHANNEL_CS; + lchannel_mapping[6] = PCM_CHANNEL_LFE; + } else if (channels == 8) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + lchannel_mapping[1] = PCM_CHANNEL_FLC; + lchannel_mapping[2] = PCM_CHANNEL_FRC; + lchannel_mapping[3] = PCM_CHANNEL_FL; + lchannel_mapping[4] = PCM_CHANNEL_FR; + lchannel_mapping[5] = PCM_CHANNEL_LS; + lchannel_mapping[6] = PCM_CHANNEL_RS; + lchannel_mapping[7] = PCM_CHANNEL_LFE; + } else { + pr_err("%s: ERROR.unsupported num_ch = %u\n", + __func__, channels); + return -EINVAL; + } + return 0; +} + +static const struct file_operations audio_g711_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_aio_release, + .unlocked_ioctl = audio_ioctl, + .compat_ioctl = audio_compat_ioctl, + .fsync = audio_aio_fsync, +}; + +static struct miscdevice audio_g711mlaw_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_g711mlaw", + .fops = &audio_g711_fops, +}; + +static int __init audio_g711mlaw_init(void) +{ + int ret = misc_register(&audio_g711mlaw_misc); + + if (ret == 0) + device_init_wakeup(audio_g711mlaw_misc.this_device, true); + audio_g711_ws_mgr.ref_cnt = 0; + mutex_init(&audio_g711_ws_mgr.ws_lock); + + return ret; +} + +static void __exit audio_g711mlaw_exit(void) +{ + misc_deregister(&audio_g711mlaw_misc); + mutex_destroy(&audio_g711_ws_mgr.ws_lock); +} + +device_initcall(audio_g711mlaw_init); +__exitcall(audio_g711mlaw_exit); diff --git a/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c b/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c new file mode 100644 index 000000000000..b8972e3d8b6e --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c @@ -0,0 +1,778 @@ +/* + * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "q6audio_common.h" +#include "audio_utils_aio.h" +#include + +#define MAX_CHANNELS_SUPPORTED 8 +#define WAIT_TIMEDOUT_DURATION_SECS 1 + +struct q6audio_effects { + wait_queue_head_t read_wait; + wait_queue_head_t write_wait; + + struct audio_client *ac; + struct msm_hwacc_effects_config config; + + struct mutex lock; + + atomic_t in_count; + atomic_t out_count; + + int opened; + int started; + int buf_alloc; + struct msm_nt_eff_all_config audio_effects; +}; + +static void audio_effects_init_pp(struct audio_client *ac) +{ + int ret = 0; + struct asm_softvolume_params softvol = { + .period = SOFT_VOLUME_PERIOD, + .step = SOFT_VOLUME_STEP, + .rampingcurve = SOFT_VOLUME_CURVE_LINEAR, + }; + + if (!ac) { + pr_err("%s: audio client null to init pp\n", __func__); + return; + } + ret = q6asm_set_softvolume_v2(ac, &softvol, + SOFT_VOLUME_INSTANCE_1); + if (ret < 0) + pr_err("%s: Send SoftVolume Param failed ret=%d\n", + __func__, ret); +} + +static void audio_effects_deinit_pp(struct audio_client *ac) +{ + if (!ac) { + pr_err("%s: audio client null to deinit pp\n", __func__); + return; + } +} + +static void audio_effects_event_handler(uint32_t opcode, uint32_t token, + uint32_t *payload, void *priv) +{ + struct q6audio_effects *effects; + + if (!payload || !priv) { + pr_err("%s: invalid data to handle events, payload: %pK, priv: %pK\n", + __func__, payload, priv); + return; + } + + effects = (struct q6audio_effects *)priv; + switch (opcode) { + case ASM_DATA_EVENT_WRITE_DONE_V2: { + atomic_inc(&effects->out_count); + wake_up(&effects->write_wait); + break; + } + case ASM_DATA_EVENT_READ_DONE_V2: { + atomic_inc(&effects->in_count); + wake_up(&effects->read_wait); + break; + } + case APR_BASIC_RSP_RESULT: { + pr_debug("%s: APR_BASIC_RSP_RESULT Cmd[0x%x] Status[0x%x]\n", + __func__, payload[0], payload[1]); + switch (payload[0]) { + case ASM_SESSION_CMD_RUN_V2: + pr_debug("ASM_SESSION_CMD_RUN_V2\n"); + break; + default: + pr_debug("%s: Payload = [0x%x] stat[0x%x]\n", + __func__, payload[0], payload[1]); + break; + } + break; + } + default: + pr_debug("%s: Unhandled Event 0x%x token = 0x%x\n", + __func__, opcode, token); + break; + } +} + +static int audio_effects_shared_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_effects *effects = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + pr_debug("%s: AUDIO_START\n", __func__); + + mutex_lock(&effects->lock); + + rc = q6asm_open_read_write_v2(effects->ac, + FORMAT_LINEAR_PCM, + FORMAT_MULTI_CHANNEL_LINEAR_PCM, + effects->config.meta_mode_enabled, + effects->config.output.bits_per_sample, + true /*overwrite topology*/, + ASM_STREAM_POSTPROC_TOPO_ID_HPX_MASTER); + if (rc < 0) { + pr_err("%s: Open failed for hw accelerated effects:rc=%d\n", + __func__, rc); + rc = -EINVAL; + mutex_unlock(&effects->lock); + goto ioctl_fail; + } + effects->opened = 1; + + pr_debug("%s: dec buf size: %d, num_buf: %d, enc buf size: %d, num_buf: %d\n", + __func__, effects->config.output.buf_size, + effects->config.output.num_buf, + effects->config.input.buf_size, + effects->config.input.num_buf); + rc = q6asm_audio_client_buf_alloc_contiguous(IN, effects->ac, + effects->config.output.buf_size, + effects->config.output.num_buf); + if (rc < 0) { + pr_err("%s: Write buffer Allocation failed rc = %d\n", + __func__, rc); + rc = -ENOMEM; + mutex_unlock(&effects->lock); + goto ioctl_fail; + } + atomic_set(&effects->in_count, effects->config.input.num_buf); + rc = q6asm_audio_client_buf_alloc_contiguous(OUT, effects->ac, + effects->config.input.buf_size, + effects->config.input.num_buf); + if (rc < 0) { + pr_err("%s: Read buffer Allocation failed rc = %d\n", + __func__, rc); + rc = -ENOMEM; + mutex_unlock(&effects->lock); + goto readbuf_fail; + } + atomic_set(&effects->out_count, effects->config.output.num_buf); + effects->buf_alloc = 1; + + pr_debug("%s: enc: sample_rate: %d, num_channels: %d\n", + __func__, effects->config.input.sample_rate, + effects->config.input.num_channels); + rc = q6asm_enc_cfg_blk_pcm(effects->ac, + effects->config.input.sample_rate, + effects->config.input.num_channels); + if (rc < 0) { + pr_err("%s: pcm read block config failed\n", __func__); + rc = -EINVAL; + mutex_unlock(&effects->lock); + goto cfg_fail; + } + pr_debug("%s: dec: sample_rate: %d, num_channels: %d, bit_width: %d\n", + __func__, effects->config.output.sample_rate, + effects->config.output.num_channels, + effects->config.output.bits_per_sample); + rc = q6asm_media_format_block_pcm_format_support( + effects->ac, effects->config.output.sample_rate, + effects->config.output.num_channels, + effects->config.output.bits_per_sample); + if (rc < 0) { + pr_err("%s: pcm write format block config failed\n", + __func__); + rc = -EINVAL; + mutex_unlock(&effects->lock); + goto cfg_fail; + } + + audio_effects_init_pp(effects->ac); + + rc = q6asm_run(effects->ac, 0x00, 0x00, 0x00); + if (!rc) + effects->started = 1; + else { + effects->started = 0; + pr_err("%s: ASM run state failed\n", __func__); + } + mutex_unlock(&effects->lock); + break; + } + case AUDIO_EFFECTS_WRITE: { + char *bufptr = NULL; + uint32_t idx = 0; + uint32_t size = 0; + + mutex_lock(&effects->lock); + + if (!effects->started) { + rc = -EFAULT; + mutex_unlock(&effects->lock); + goto ioctl_fail; + } + + rc = wait_event_timeout(effects->write_wait, + atomic_read(&effects->out_count), + WAIT_TIMEDOUT_DURATION_SECS * HZ); + if (!rc) { + pr_err("%s: write wait_event_timeout\n", __func__); + rc = -EFAULT; + mutex_unlock(&effects->lock); + goto ioctl_fail; + } + if (!atomic_read(&effects->out_count)) { + pr_err("%s: pcm stopped out_count 0\n", __func__); + rc = -EFAULT; + mutex_unlock(&effects->lock); + goto ioctl_fail; + } + + bufptr = q6asm_is_cpu_buf_avail(IN, effects->ac, &size, &idx); + if (bufptr) { + if ((effects->config.buf_cfg.output_len > size) || + copy_from_user(bufptr, (void *)arg, + effects->config.buf_cfg.output_len)) { + rc = -EFAULT; + mutex_unlock(&effects->lock); + goto ioctl_fail; + } + rc = q6asm_write(effects->ac, + effects->config.buf_cfg.output_len, + 0, 0, NO_TIMESTAMP); + if (rc < 0) { + rc = -EFAULT; + mutex_unlock(&effects->lock); + goto ioctl_fail; + } + atomic_dec(&effects->out_count); + } else { + pr_err("%s: AUDIO_EFFECTS_WRITE: Buffer dropped\n", + __func__); + } + mutex_unlock(&effects->lock); + break; + } + case AUDIO_EFFECTS_READ: { + char *bufptr = NULL; + uint32_t idx = 0; + uint32_t size = 0; + + mutex_lock(&effects->lock); + + if (!effects->started) { + rc = -EFAULT; + mutex_unlock(&effects->lock); + goto ioctl_fail; + } + + atomic_set(&effects->in_count, 0); + + q6asm_read_v2(effects->ac, effects->config.buf_cfg.input_len); + /* Read might fail initially, don't error out */ + if (rc < 0) + pr_err("%s: read failed\n", __func__); + + rc = wait_event_timeout(effects->read_wait, + atomic_read(&effects->in_count), + WAIT_TIMEDOUT_DURATION_SECS * HZ); + if (!rc) { + pr_err("%s: read wait_event_timeout\n", __func__); + rc = -EFAULT; + mutex_unlock(&effects->lock); + goto ioctl_fail; + } + if (!atomic_read(&effects->in_count)) { + pr_err("%s: pcm stopped in_count 0\n", __func__); + rc = -EFAULT; + mutex_unlock(&effects->lock); + goto ioctl_fail; + } + + bufptr = q6asm_is_cpu_buf_avail(OUT, effects->ac, &size, &idx); + if (bufptr) { + if (!((void *)arg)) { + rc = -EFAULT; + mutex_unlock(&effects->lock); + goto ioctl_fail; + } + if ((effects->config.buf_cfg.input_len > size) || + copy_to_user((void *)arg, bufptr, + effects->config.buf_cfg.input_len)) { + rc = -EFAULT; + mutex_unlock(&effects->lock); + goto ioctl_fail; + } + } + mutex_unlock(&effects->lock); + break; + } + default: + pr_err("%s: Invalid effects config module\n", __func__); + rc = -EINVAL; + break; + } +ioctl_fail: + return rc; +readbuf_fail: + q6asm_audio_client_buf_free_contiguous(IN, + effects->ac); + return rc; +cfg_fail: + q6asm_audio_client_buf_free_contiguous(IN, + effects->ac); + q6asm_audio_client_buf_free_contiguous(OUT, + effects->ac); + effects->buf_alloc = 0; + return rc; +} + +static long audio_effects_set_pp_param(struct q6audio_effects *effects, + long *values) +{ + int rc = 0; + int effects_module = values[0]; + + switch (effects_module) { + case VIRTUALIZER_MODULE: + pr_debug("%s: VIRTUALIZER_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top( + effects_module, effects->ac->topology)) + msm_audio_effects_virtualizer_handler( + effects->ac, + &(effects->audio_effects.virtualizer), + (long *)&values[1]); + break; + case REVERB_MODULE: + pr_debug("%s: REVERB_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top( + effects_module, effects->ac->topology)) + msm_audio_effects_reverb_handler(effects->ac, + &(effects->audio_effects.reverb), + (long *)&values[1]); + break; + case BASS_BOOST_MODULE: + pr_debug("%s: BASS_BOOST_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top( + effects_module, effects->ac->topology)) + msm_audio_effects_bass_boost_handler( + effects->ac, + &(effects->audio_effects.bass_boost), + (long *)&values[1]); + break; + case PBE_MODULE: + pr_debug("%s: PBE_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top( + effects_module, effects->ac->topology)) + msm_audio_effects_pbe_handler( + effects->ac, + &(effects->audio_effects.pbe), + (long *)&values[1]); + break; + case EQ_MODULE: + pr_debug("%s: EQ_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top( + effects_module, effects->ac->topology)) + msm_audio_effects_popless_eq_handler( + effects->ac, + &(effects->audio_effects.equalizer), + (long *)&values[1]); + break; + case SOFT_VOLUME_MODULE: + pr_debug("%s: SA PLUS VOLUME_MODULE\n", __func__); + msm_audio_effects_volume_handler_v2(effects->ac, + &(effects->audio_effects.saplus_vol), + (long *)&values[1], SOFT_VOLUME_INSTANCE_1); + break; + case SOFT_VOLUME2_MODULE: + pr_debug("%s: TOPOLOGY SWITCH VOLUME MODULE\n", + __func__); + if (msm_audio_effects_is_effmodule_supp_in_top( + effects_module, effects->ac->topology)) + msm_audio_effects_volume_handler_v2(effects->ac, + &(effects->audio_effects.topo_switch_vol), + (long *)&values[1], SOFT_VOLUME_INSTANCE_2); + break; + default: + pr_err("%s: Invalid effects config module\n", __func__); + rc = -EINVAL; + } + return rc; +} + +static long audio_effects_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_effects *effects = file->private_data; + int rc = 0; + long argvalues[MAX_PP_PARAMS_SZ] = {0}; + + switch (cmd) { + case AUDIO_SET_EFFECTS_CONFIG: { + pr_debug("%s: AUDIO_SET_EFFECTS_CONFIG\n", __func__); + mutex_lock(&effects->lock); + memset(&effects->config, 0, sizeof(effects->config)); + if (copy_from_user(&effects->config, (void *)arg, + sizeof(effects->config))) { + pr_err("%s: copy from user for AUDIO_SET_EFFECTS_CONFIG failed\n", + __func__); + rc = -EFAULT; + } + pr_debug("%s: write buf_size: %d, num_buf: %d, sample_rate: %d, channel: %d\n", + __func__, effects->config.output.buf_size, + effects->config.output.num_buf, + effects->config.output.sample_rate, + effects->config.output.num_channels); + pr_debug("%s: read buf_size: %d, num_buf: %d, sample_rate: %d, channel: %d\n", + __func__, effects->config.input.buf_size, + effects->config.input.num_buf, + effects->config.input.sample_rate, + effects->config.input.num_channels); + mutex_unlock(&effects->lock); + break; + } + case AUDIO_EFFECTS_SET_BUF_LEN: { + mutex_lock(&effects->lock); + if (copy_from_user(&effects->config.buf_cfg, (void *)arg, + sizeof(effects->config.buf_cfg))) { + pr_err("%s: copy from user for AUDIO_EFFECTS_SET_BUF_LEN failed\n", + __func__); + rc = -EFAULT; + } + pr_debug("%s: write buf len: %d, read buf len: %d\n", + __func__, effects->config.buf_cfg.output_len, + effects->config.buf_cfg.input_len); + mutex_unlock(&effects->lock); + break; + } + case AUDIO_EFFECTS_GET_BUF_AVAIL: { + struct msm_hwacc_buf_avail buf_avail; + + buf_avail.input_num_avail = atomic_read(&effects->in_count); + buf_avail.output_num_avail = atomic_read(&effects->out_count); + mutex_lock(&effects->lock); + pr_debug("%s: write buf avail: %d, read buf avail: %d\n", + __func__, buf_avail.output_num_avail, + buf_avail.input_num_avail); + if (copy_to_user((void *)arg, &buf_avail, + sizeof(buf_avail))) { + pr_err("%s: copy to user for AUDIO_EFFECTS_GET_NUM_BUF_AVAIL failed\n", + __func__); + rc = -EFAULT; + } + mutex_unlock(&effects->lock); + break; + } + case AUDIO_EFFECTS_SET_PP_PARAMS: { + mutex_lock(&effects->lock); + if (copy_from_user(argvalues, (void *)arg, + MAX_PP_PARAMS_SZ*sizeof(long))) { + pr_err("%s: copy from user for pp params failed\n", + __func__); + mutex_unlock(&effects->lock); + return -EFAULT; + } + rc = audio_effects_set_pp_param(effects, argvalues); + mutex_unlock(&effects->lock); + break; + } + default: + pr_debug("%s: Calling shared ioctl\n", __func__); + rc = audio_effects_shared_ioctl(file, cmd, arg); + break; + } + if (rc) + pr_err("%s: cmd 0x%x failed\n", __func__, cmd); + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_hwacc_data_config32 { + __u32 buf_size; + __u32 num_buf; + __u32 num_channels; + __u8 channel_map[MAX_CHANNELS_SUPPORTED]; + __u32 sample_rate; + __u32 bits_per_sample; +}; + +struct msm_hwacc_buf_cfg32 { + __u32 input_len; + __u32 output_len; +}; + +struct msm_hwacc_buf_avail32 { + __u32 input_num_avail; + __u32 output_num_avail; +}; + +struct msm_hwacc_effects_config32 { + struct msm_hwacc_data_config32 input; + struct msm_hwacc_data_config32 output; + struct msm_hwacc_buf_cfg32 buf_cfg; + __u32 meta_mode_enabled; + __u32 overwrite_topology; + __s32 topology; +}; + +enum { + AUDIO_SET_EFFECTS_CONFIG32 = _IOW(AUDIO_IOCTL_MAGIC, 99, + struct msm_hwacc_effects_config32), + AUDIO_EFFECTS_SET_BUF_LEN32 = _IOW(AUDIO_IOCTL_MAGIC, 100, + struct msm_hwacc_buf_cfg32), + AUDIO_EFFECTS_GET_BUF_AVAIL32 = _IOW(AUDIO_IOCTL_MAGIC, 101, + struct msm_hwacc_buf_avail32), + AUDIO_EFFECTS_WRITE32 = _IOW(AUDIO_IOCTL_MAGIC, 102, compat_uptr_t), + AUDIO_EFFECTS_READ32 = _IOWR(AUDIO_IOCTL_MAGIC, 103, compat_uptr_t), + AUDIO_EFFECTS_SET_PP_PARAMS32 = _IOW(AUDIO_IOCTL_MAGIC, 104, + compat_uptr_t), + AUDIO_START32 = _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned int), +}; + +static long audio_effects_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_effects *effects = file->private_data; + int rc = 0, i; + + switch (cmd) { + case AUDIO_SET_EFFECTS_CONFIG32: { + struct msm_hwacc_effects_config32 config32; + struct msm_hwacc_effects_config *config = &effects->config; + + mutex_lock(&effects->lock); + memset(&effects->config, 0, sizeof(effects->config)); + if (copy_from_user(&config32, (void *)arg, + sizeof(config32))) { + pr_err("%s: copy to user for AUDIO_SET_EFFECTS_CONFIG failed\n", + __func__); + rc = -EFAULT; + mutex_unlock(&effects->lock); + break; + } + config->input.buf_size = config32.input.buf_size; + config->input.num_buf = config32.input.num_buf; + config->input.num_channels = config32.input.num_channels; + config->input.sample_rate = config32.input.sample_rate; + config->input.bits_per_sample = config32.input.bits_per_sample; + config->input.buf_size = config32.input.buf_size; + for (i = 0; i < MAX_CHANNELS_SUPPORTED; i++) + config->input.channel_map[i] = + config32.input.channel_map[i]; + config->output.buf_size = config32.output.buf_size; + config->output.num_buf = config32.output.num_buf; + config->output.num_channels = config32.output.num_channels; + config->output.sample_rate = config32.output.sample_rate; + config->output.bits_per_sample = + config32.output.bits_per_sample; + config->output.buf_size = config32.output.buf_size; + for (i = 0; i < MAX_CHANNELS_SUPPORTED; i++) + config->output.channel_map[i] = + config32.output.channel_map[i]; + config->buf_cfg.input_len = config32.buf_cfg.input_len; + config->buf_cfg.output_len = config32.buf_cfg.output_len; + config->meta_mode_enabled = config32.meta_mode_enabled; + config->overwrite_topology = config32.overwrite_topology; + config->topology = config32.topology; + pr_debug("%s: write buf_size: %d, num_buf: %d, sample_rate: %d, channels: %d\n", + __func__, effects->config.output.buf_size, + effects->config.output.num_buf, + effects->config.output.sample_rate, + effects->config.output.num_channels); + pr_debug("%s: read buf_size: %d, num_buf: %d, sample_rate: %d, channels: %d\n", + __func__, effects->config.input.buf_size, + effects->config.input.num_buf, + effects->config.input.sample_rate, + effects->config.input.num_channels); + mutex_unlock(&effects->lock); + break; + } + case AUDIO_EFFECTS_SET_BUF_LEN32: { + struct msm_hwacc_buf_cfg32 buf_cfg32; + struct msm_hwacc_effects_config *config = &effects->config; + + mutex_lock(&effects->lock); + if (copy_from_user(&buf_cfg32, (void *)arg, + sizeof(buf_cfg32))) { + pr_err("%s: copy from user for AUDIO_EFFECTS_SET_BUF_LEN failed\n", + __func__); + rc = -EFAULT; + mutex_unlock(&effects->lock); + break; + } + config->buf_cfg.input_len = buf_cfg32.input_len; + config->buf_cfg.output_len = buf_cfg32.output_len; + pr_debug("%s: write buf len: %d, read buf len: %d\n", + __func__, effects->config.buf_cfg.output_len, + effects->config.buf_cfg.input_len); + mutex_unlock(&effects->lock); + break; + } + case AUDIO_EFFECTS_GET_BUF_AVAIL32: { + struct msm_hwacc_buf_avail32 buf_avail; + + memset(&buf_avail, 0, sizeof(buf_avail)); + + mutex_lock(&effects->lock); + buf_avail.input_num_avail = atomic_read(&effects->in_count); + buf_avail.output_num_avail = atomic_read(&effects->out_count); + pr_debug("%s: write buf avail: %d, read buf avail: %d\n", + __func__, buf_avail.output_num_avail, + buf_avail.input_num_avail); + if (copy_to_user((void *)arg, &buf_avail, + sizeof(buf_avail))) { + pr_err("%s: copy to user for AUDIO_EFFECTS_GET_NUM_BUF_AVAIL failed\n", + __func__); + rc = -EFAULT; + } + mutex_unlock(&effects->lock); + break; + } + case AUDIO_EFFECTS_SET_PP_PARAMS32: { + long argvalues[MAX_PP_PARAMS_SZ] = {0}; + int argvalues32[MAX_PP_PARAMS_SZ] = {0}; + + mutex_lock(&effects->lock); + if (copy_from_user(argvalues32, (void *)arg, + MAX_PP_PARAMS_SZ*sizeof(int))) { + pr_err("%s: copy from user failed for pp params\n", + __func__); + mutex_unlock(&effects->lock); + return -EFAULT; + } + for (i = 0; i < MAX_PP_PARAMS_SZ; i++) + argvalues[i] = argvalues32[i]; + + rc = audio_effects_set_pp_param(effects, argvalues); + mutex_unlock(&effects->lock); + break; + } + case AUDIO_START32: { + rc = audio_effects_shared_ioctl(file, AUDIO_START, arg); + break; + } + case AUDIO_EFFECTS_WRITE32: { + rc = audio_effects_shared_ioctl(file, AUDIO_EFFECTS_WRITE, arg); + break; + } + case AUDIO_EFFECTS_READ32: { + rc = audio_effects_shared_ioctl(file, AUDIO_EFFECTS_READ, arg); + break; + } + default: + pr_debug("%s: unhandled ioctl\n", __func__); + rc = -EINVAL; + break; + } + return rc; +} +#endif + +static int audio_effects_release(struct inode *inode, struct file *file) +{ + struct q6audio_effects *effects = file->private_data; + int rc = 0; + + if (!effects) { + pr_err("%s: effect is NULL\n", __func__); + return -EINVAL; + } + if (effects->opened) { + rc = wait_event_timeout(effects->write_wait, + atomic_read(&effects->out_count), + WAIT_TIMEDOUT_DURATION_SECS * HZ); + if (!rc) + pr_err("%s: write wait_event_timeout failed\n", + __func__); + rc = wait_event_timeout(effects->read_wait, + atomic_read(&effects->in_count), + WAIT_TIMEDOUT_DURATION_SECS * HZ); + if (!rc) + pr_err("%s: read wait_event_timeout failed\n", + __func__); + rc = q6asm_cmd(effects->ac, CMD_CLOSE); + if (rc < 0) + pr_err("%s[%pK]:Failed to close the session rc=%d\n", + __func__, effects, rc); + effects->opened = 0; + effects->started = 0; + + audio_effects_deinit_pp(effects->ac); + } + + if (effects->buf_alloc) { + q6asm_audio_client_buf_free_contiguous(IN, effects->ac); + q6asm_audio_client_buf_free_contiguous(OUT, effects->ac); + } + q6asm_audio_client_free(effects->ac); + + mutex_destroy(&effects->lock); + kfree(effects); + + pr_debug("%s: close session success\n", __func__); + return rc; +} + +static int audio_effects_open(struct inode *inode, struct file *file) +{ + struct q6audio_effects *effects; + int rc = 0; + + effects = kzalloc(sizeof(struct q6audio_effects), GFP_KERNEL); + if (!effects) + return -ENOMEM; + + effects->ac = q6asm_audio_client_alloc( + (app_cb)audio_effects_event_handler, + (void *)effects); + if (!effects->ac) { + pr_err("%s: Could not allocate memory for audio client\n", + __func__); + kfree(effects); + return -ENOMEM; + } + + init_waitqueue_head(&effects->read_wait); + init_waitqueue_head(&effects->write_wait); + mutex_init(&effects->lock); + + effects->opened = 0; + effects->started = 0; + effects->buf_alloc = 0; + file->private_data = effects; + pr_debug("%s: open session success\n", __func__); + return rc; +} + +static const struct file_operations audio_effects_fops = { + .owner = THIS_MODULE, + .open = audio_effects_open, + .release = audio_effects_release, + .unlocked_ioctl = audio_effects_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = audio_effects_compat_ioctl, +#endif +}; + +struct miscdevice audio_effects_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_hweffects", + .fops = &audio_effects_fops, +}; + +static int __init audio_effects_init(void) +{ + return misc_register(&audio_effects_misc); +} + +device_initcall(audio_effects_init); +MODULE_DESCRIPTION("Audio hardware accelerated effects driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/qcom/qdsp6v2/audio_mp3.c b/drivers/misc/qcom/qdsp6v2/audio_mp3.c new file mode 100644 index 000000000000..0b10c7a83677 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_mp3.c @@ -0,0 +1,188 @@ +/* mp3 audio output device + * + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "audio_utils_aio.h" + +static struct miscdevice audio_mp3_misc; +static struct ws_mgr audio_mp3_ws_mgr; + +#ifdef CONFIG_DEBUG_FS +static const struct file_operations audio_mp3_debug_fops = { + .read = audio_aio_debug_read, + .open = audio_aio_debug_open, +}; +#endif + +static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, + audio, audio->ac->session); + if (audio->feedback == NON_TUNNEL_MODE) { + /* Configure PCM output block */ + rc = q6asm_enc_cfg_blk_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + if (rc < 0) { + pr_err("pcm output block config failed\n"); + break; + } + } + + rc = audio_aio_enable(audio); + audio->eos_rsp = 0; + audio->eos_flag = 0; + if (!rc) { + rc = enable_volume_ramp(audio); + if (rc < 0) { + pr_err("%s: Failed to enable volume ramp\n", + __func__); + } + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("Audio Start procedure failed rc=%d\n", rc); + break; + } + pr_info("%s: AUDIO_START sessionid[%d]enable[%d]\n", __func__, + audio->ac->session, + audio->enabled); + if (audio->stopped == 1) + audio->stopped = 0; + break; + } + default: + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); + rc = audio->codec_ioctl(file, cmd, arg); + } + return rc; +} + +static int audio_open(struct inode *inode, struct file *file) +{ + struct q6audio_aio *audio = NULL; + int rc = 0; + +#ifdef CONFIG_DEBUG_FS + /* 4 bytes represents decoder number, 1 byte for terminate string */ + char name[sizeof "msm_mp3_" + 5]; +#endif + audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + + audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN; + audio->miscdevice = &audio_mp3_misc; + audio->wakelock_voted = false; + audio->audio_ws_mgr = &audio_mp3_ws_mgr; + + audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("Could not allocate memory for audio client\n"); + kfree(audio); + return -ENOMEM; + } + rc = audio_aio_open(audio, file); + if (rc < 0) { + pr_err("%s: audio_aio_open rc=%d\n", + __func__, rc); + goto fail; + } + + /* open in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) { + rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM, + FORMAT_MP3); + if (rc < 0) { + pr_err("NT mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = NON_TUNNEL_MODE; + /* open MP3 decoder, expected frames is always 1 + * audio->buf_cfg.frames_per_buf = 0x01; + */ + audio->buf_cfg.meta_info_enable = 0x01; + } else if ((file->f_mode & FMODE_WRITE) && + !(file->f_mode & FMODE_READ)) { + rc = q6asm_open_write(audio->ac, FORMAT_MP3); + if (rc < 0) { + pr_err("T mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = TUNNEL_MODE; + audio->buf_cfg.meta_info_enable = 0x00; + } else { + pr_err("Not supported mode\n"); + rc = -EACCES; + goto fail; + } + +#ifdef CONFIG_DEBUG_FS + snprintf(name, sizeof(name), "msm_mp3_%04x", audio->ac->session); + audio->dentry = debugfs_create_file(name, S_IFREG | 0444, + NULL, (void *)audio, + &audio_mp3_debug_fops); + + if (IS_ERR(audio->dentry)) + pr_debug("debugfs_create_file failed\n"); +#endif + pr_info("%s:mp3dec success mode[%d]session[%d]\n", __func__, + audio->feedback, + audio->ac->session); + return rc; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio); + return rc; +} + +static const struct file_operations audio_mp3_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_aio_release, + .unlocked_ioctl = audio_ioctl, + .fsync = audio_aio_fsync, +}; + +static struct miscdevice audio_mp3_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_mp3", + .fops = &audio_mp3_fops, +}; + +static int __init audio_mp3_init(void) +{ + int ret = misc_register(&audio_mp3_misc); + + if (ret == 0) + device_init_wakeup(audio_mp3_misc.this_device, true); + audio_mp3_ws_mgr.ref_cnt = 0; + mutex_init(&audio_mp3_ws_mgr.ws_lock); + + return ret; +} + +device_initcall(audio_mp3_init); diff --git a/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c b/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c new file mode 100644 index 000000000000..01c3dc5ada58 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c @@ -0,0 +1,523 @@ +/* aac audio output device + * + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include "audio_utils_aio.h" + +#define AUDIO_AAC_DUAL_MONO_INVALID -1 + + +/* Default number of pre-allocated event packets */ +#define PCM_BUFSZ_MIN_AACM ((8*1024) + sizeof(struct dec_meta_out)) +static struct miscdevice audio_multiaac_misc; +static struct ws_mgr audio_multiaac_ws_mgr; + +#ifdef CONFIG_DEBUG_FS +static const struct file_operations audio_aac_debug_fops = { + .read = audio_aio_debug_read, + .open = audio_aio_debug_open, +}; +#endif + +static long audio_ioctl_shared(struct file *file, unsigned int cmd, + void *arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + struct asm_aac_cfg aac_cfg; + struct msm_audio_aac_config *aac_config; + uint32_t sbr_ps = 0x00; + + aac_config = (struct msm_audio_aac_config *)audio->codec_cfg; + if (audio->feedback == TUNNEL_MODE) { + aac_cfg.sample_rate = aac_config->sample_rate; + aac_cfg.ch_cfg = aac_config->channel_configuration; + } else { + aac_cfg.sample_rate = audio->pcm_cfg.sample_rate; + aac_cfg.ch_cfg = audio->pcm_cfg.channel_count; + } + pr_debug("%s: AUDIO_START session_id[%d]\n", __func__, + audio->ac->session); + if (audio->feedback == NON_TUNNEL_MODE) { + /* Configure PCM output block */ + rc = q6asm_enc_cfg_blk_pcm_native(audio->ac, + aac_cfg.sample_rate, + aac_cfg.ch_cfg); + if (rc < 0) { + pr_err("pcm output block config failed\n"); + break; + } + } + /* turn on both sbr and ps */ + rc = q6asm_enable_sbrps(audio->ac, sbr_ps); + if (rc < 0) + pr_err("sbr-ps enable failed\n"); + if (aac_config->sbr_ps_on_flag) + aac_cfg.aot = AAC_ENC_MODE_EAAC_P; + else if (aac_config->sbr_on_flag) + aac_cfg.aot = AAC_ENC_MODE_AAC_P; + else + aac_cfg.aot = AAC_ENC_MODE_AAC_LC; + + switch (aac_config->format) { + case AUDIO_AAC_FORMAT_ADTS: + aac_cfg.format = 0x00; + break; + case AUDIO_AAC_FORMAT_LOAS: + aac_cfg.format = 0x01; + break; + case AUDIO_AAC_FORMAT_ADIF: + aac_cfg.format = 0x02; + break; + default: + case AUDIO_AAC_FORMAT_RAW: + aac_cfg.format = 0x03; + } + aac_cfg.ep_config = aac_config->ep_config; + aac_cfg.section_data_resilience = + aac_config->aac_section_data_resilience_flag; + aac_cfg.scalefactor_data_resilience = + aac_config->aac_scalefactor_data_resilience_flag; + aac_cfg.spectral_data_resilience = + aac_config->aac_spectral_data_resilience_flag; + + pr_debug("%s:format=%x aot=%d ch=%d sr=%d\n", + __func__, aac_cfg.format, + aac_cfg.aot, aac_cfg.ch_cfg, + aac_cfg.sample_rate); + + /* Configure Media format block */ + rc = q6asm_media_format_block_multi_aac(audio->ac, &aac_cfg); + if (rc < 0) { + pr_err("cmd media format block failed\n"); + break; + } + rc = q6asm_set_encdec_chan_map(audio->ac, 2); + if (rc < 0) { + pr_err("%s: cmd set encdec_chan_map failed\n", + __func__); + break; + } + rc = audio_aio_enable(audio); + audio->eos_rsp = 0; + audio->eos_flag = 0; + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("Audio Start procedure failed rc=%d\n", rc); + break; + } + pr_info("%s: AUDIO_START sessionid[%d]enable[%d]\n", __func__, + audio->ac->session, + audio->enabled); + if (audio->stopped == 1) + audio->stopped = 0; + break; + } + case AUDIO_SET_AAC_CONFIG: { + struct msm_audio_aac_config *aac_config; + uint16_t sce_left = 1, sce_right = 2; + + if (arg == NULL) { + pr_err("%s: NULL config pointer\n", __func__); + rc = -EINVAL; + break; + } + memcpy(audio->codec_cfg, arg, + sizeof(struct msm_audio_aac_config)); + aac_config = audio->codec_cfg; + if (aac_config->dual_mono_mode > + AUDIO_AAC_DUAL_MONO_PL_SR) { + pr_err("%s:AUDIO_SET_AAC_CONFIG: Invalid dual_mono mode =%d\n", + __func__, aac_config->dual_mono_mode); + } else { + /* convert the data from user into sce_left + * and sce_right based on the definitions + */ + pr_debug("%s: AUDIO_SET_AAC_CONFIG: modify dual_mono mode =%d\n", + __func__, aac_config->dual_mono_mode); + switch (aac_config->dual_mono_mode) { + case AUDIO_AAC_DUAL_MONO_PL_PR: + sce_left = 1; + sce_right = 1; + break; + case AUDIO_AAC_DUAL_MONO_SL_SR: + sce_left = 2; + sce_right = 2; + break; + case AUDIO_AAC_DUAL_MONO_SL_PR: + sce_left = 2; + sce_right = 1; + break; + case AUDIO_AAC_DUAL_MONO_PL_SR: + default: + sce_left = 1; + sce_right = 2; + break; + } + rc = q6asm_cfg_dual_mono_aac(audio->ac, + sce_left, sce_right); + if (rc < 0) + pr_err("%s: asm cmd dualmono failed rc=%d\n", + __func__, rc); + } break; + break; + } + case AUDIO_SET_AAC_MIX_CONFIG: { + u32 *mix_coeff = (u32 *)arg; + + if (!arg) { + pr_err("%s: Invalid param for %s\n", + __func__, "AUDIO_SET_AAC_MIX_CONFIG"); + rc = -EINVAL; + break; + } + pr_debug("%s, AUDIO_SET_AAC_MIX_CONFIG", __func__); + pr_debug("%s, value of coeff = %d", + __func__, *mix_coeff); + q6asm_cfg_aac_sel_mix_coef(audio->ac, *mix_coeff); + if (rc < 0) + pr_err("%s asm aac_sel_mix_coef failed rc=%d\n", + __func__, rc); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + break; + } + return rc; +} + +static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + case AUDIO_GET_AAC_CONFIG: { + if (copy_to_user((void *)arg, audio->codec_cfg, + sizeof(struct msm_audio_aac_config))) { + pr_err("%s: copy_to_user for AUDIO_GET_AAC_CONFIG failed\n" + , __func__); + rc = -EFAULT; + break; + } + break; + } + case AUDIO_SET_AAC_CONFIG: { + struct msm_audio_aac_config aac_config; + + if (copy_from_user(&aac_config, (void *)arg, + sizeof(aac_config))) { + pr_err("%s: copy_from_user for AUDIO_SET_AAC_CONFIG failed\n" + , __func__); + rc = -EFAULT; + } + rc = audio_ioctl_shared(file, cmd, &aac_config); + if (rc) + pr_err("%s:AUDIO_SET_AAC_CONFIG failed. Rc= %d\n", + __func__, rc); + break; + } + case AUDIO_SET_AAC_MIX_CONFIG: { + u32 mix_config; + + pr_debug("%s, AUDIO_SET_AAC_MIX_CONFIG", __func__); + if (copy_from_user(&mix_config, (void *)arg, + sizeof(u32))) { + pr_err("%s: copy_from_user for AUDIO_SET_AAC_MIX_CONFIG failed\n", + __func__); + rc = -EFAULT; + break; + } + rc = audio_ioctl_shared(file, cmd, &mix_config); + if (rc) + pr_err("%s:AUDIO_SET_AAC_CONFIG failed. Rc= %d\n", + __func__, rc); + break; + } + default: { + pr_debug("Calling utils ioctl\n"); + rc = audio->codec_ioctl(file, cmd, arg); + } + } + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_audio_aac_config32 { + s16 format; + u16 audio_object; + u16 ep_config; /* 0 ~ 3 useful only obj = ERLC */ + u16 aac_section_data_resilience_flag; + u16 aac_scalefactor_data_resilience_flag; + u16 aac_spectral_data_resilience_flag; + u16 sbr_on_flag; + u16 sbr_ps_on_flag; + u16 dual_mono_mode; + u16 channel_configuration; + u16 sample_rate; +}; + +enum { + AUDIO_SET_AAC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_aac_config32), + AUDIO_GET_AAC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_aac_config32), +}; + +static long audio_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + case AUDIO_GET_AAC_CONFIG_32: { + struct msm_audio_aac_config *aac_config; + struct msm_audio_aac_config32 aac_config_32; + + memset(&aac_config_32, 0, sizeof(aac_config_32)); + + aac_config = (struct msm_audio_aac_config *)audio->codec_cfg; + aac_config_32.format = aac_config->format; + aac_config_32.audio_object = aac_config->audio_object; + aac_config_32.ep_config = aac_config->ep_config; + aac_config_32.aac_section_data_resilience_flag = + aac_config->aac_section_data_resilience_flag; + aac_config_32.aac_scalefactor_data_resilience_flag = + aac_config->aac_scalefactor_data_resilience_flag; + aac_config_32.aac_spectral_data_resilience_flag = + aac_config->aac_spectral_data_resilience_flag; + aac_config_32.sbr_on_flag = aac_config->sbr_on_flag; + aac_config_32.sbr_ps_on_flag = aac_config->sbr_ps_on_flag; + aac_config_32.dual_mono_mode = aac_config->dual_mono_mode; + aac_config_32.channel_configuration = + aac_config->channel_configuration; + aac_config_32.sample_rate = aac_config->sample_rate; + + if (copy_to_user((void *)arg, &aac_config_32, + sizeof(aac_config_32))) { + pr_err("%s: copy_to_user for AUDIO_GET_AAC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + break; + } + case AUDIO_SET_AAC_CONFIG_32: { + struct msm_audio_aac_config aac_config; + struct msm_audio_aac_config32 aac_config_32; + + pr_debug("%s: AUDIO_SET_AAC_CONFIG\n", __func__); + if (copy_from_user(&aac_config_32, (void *)arg, + sizeof(aac_config_32))) { + pr_err( + "%s: copy_from_user for AUDIO_SET_AAC_CONFIG_32 failed", + __func__); + rc = -EFAULT; + break; + } + aac_config.format = aac_config_32.format; + aac_config.audio_object = aac_config_32.audio_object; + aac_config.ep_config = aac_config_32.ep_config; + aac_config.aac_section_data_resilience_flag = + aac_config_32.aac_section_data_resilience_flag; + aac_config.aac_scalefactor_data_resilience_flag = + aac_config_32.aac_scalefactor_data_resilience_flag; + aac_config.aac_spectral_data_resilience_flag = + aac_config_32.aac_spectral_data_resilience_flag; + aac_config.sbr_on_flag = aac_config_32.sbr_on_flag; + aac_config.sbr_ps_on_flag = aac_config_32.sbr_ps_on_flag; + aac_config.dual_mono_mode = aac_config_32.dual_mono_mode; + aac_config.channel_configuration = + aac_config_32.channel_configuration; + aac_config.sample_rate = aac_config_32.sample_rate; + + cmd = AUDIO_SET_AAC_CONFIG; + rc = audio_ioctl_shared(file, cmd, &aac_config); + if (rc) + pr_err("%s:AUDIO_SET_AAC_CONFIG failed. rc= %d\n", + __func__, rc); + break; + } + case AUDIO_SET_AAC_MIX_CONFIG: { + u32 mix_config; + + pr_debug("%s, AUDIO_SET_AAC_MIX_CONFIG\n", __func__); + if (copy_from_user(&mix_config, (void *)arg, + sizeof(u32))) { + pr_err("%s: copy_from_user for AUDIO_SET_AAC_MIX_CONFIG failed\n" + , __func__); + rc = -EFAULT; + break; + } + rc = audio_ioctl_shared(file, cmd, &mix_config); + if (rc) + pr_err("%s:AUDIO_SET_AAC_CONFIG failed. Rc= %d\n", + __func__, rc); + break; + } + default: { + pr_debug("Calling utils ioctl\n"); + rc = audio->codec_compat_ioctl(file, cmd, arg); + } + } + return rc; +} +#else +#define audio_compat_ioctl NULL +#endif + +static int audio_open(struct inode *inode, struct file *file) +{ + struct q6audio_aio *audio = NULL; + int rc = 0; + struct msm_audio_aac_config *aac_config = NULL; + +#ifdef CONFIG_DEBUG_FS + /* 4 bytes represents decoder number, 1 byte for terminate string */ + char name[sizeof "msm_multi_aac_" + 5]; +#endif + audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + + audio->codec_cfg = kzalloc(sizeof(struct msm_audio_aac_config), + GFP_KERNEL); + if (audio->codec_cfg == NULL) { + kfree(audio); + return -ENOMEM; + } + + aac_config = audio->codec_cfg; + + audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN_AACM; + audio->miscdevice = &audio_multiaac_misc; + audio->wakelock_voted = false; + audio->audio_ws_mgr = &audio_multiaac_ws_mgr; + aac_config->dual_mono_mode = AUDIO_AAC_DUAL_MONO_INVALID; + + audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("Could not allocate memory for audio client\n"); + kfree(audio->codec_cfg); + kfree(audio); + return -ENOMEM; + } + rc = audio_aio_open(audio, file); + if (rc < 0) { + pr_err("%s: audio_aio_open rc=%d\n", + __func__, rc); + goto fail; + } + + /* open in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) { + rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM, + FORMAT_MPEG4_MULTI_AAC); + if (rc < 0) { + pr_err("NT mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = NON_TUNNEL_MODE; + /* open AAC decoder, expected frames is always 1 + * audio->buf_cfg.frames_per_buf = 0x01; + */ + audio->buf_cfg.meta_info_enable = 0x01; + } else if ((file->f_mode & FMODE_WRITE) && + !(file->f_mode & FMODE_READ)) { + rc = q6asm_open_write(audio->ac, FORMAT_MPEG4_MULTI_AAC); + if (rc < 0) { + pr_err("T mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = TUNNEL_MODE; + audio->buf_cfg.meta_info_enable = 0x00; + } else { + pr_err("Not supported mode\n"); + rc = -EACCES; + goto fail; + } + +#ifdef CONFIG_DEBUG_FS + snprintf(name, sizeof(name), "msm_multi_aac_%04x", audio->ac->session); + audio->dentry = debugfs_create_file(name, S_IFREG | 0444, + NULL, (void *)audio, + &audio_aac_debug_fops); + + if (IS_ERR(audio->dentry)) + pr_debug("debugfs_create_file failed\n"); +#endif + pr_info("%s:AAC 5.1 Decoder OPEN success mode[%d]session[%d]\n", + __func__, audio->feedback, audio->ac->session); + return rc; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio->codec_cfg); + kfree(audio); + return rc; +} + +static const struct file_operations audio_aac_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_aio_release, + .unlocked_ioctl = audio_ioctl, + .fsync = audio_aio_fsync, + .compat_ioctl = audio_compat_ioctl +}; + +static struct miscdevice audio_multiaac_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_multi_aac", + .fops = &audio_aac_fops, +}; + +static int __init audio_aac_init(void) +{ + int ret = misc_register(&audio_multiaac_misc); + + if (ret == 0) + device_init_wakeup(audio_multiaac_misc.this_device, true); + audio_multiaac_ws_mgr.ref_cnt = 0; + mutex_init(&audio_multiaac_ws_mgr.ws_lock); + + return ret; +} + +device_initcall(audio_aac_init); diff --git a/drivers/misc/qcom/qdsp6v2/audio_qcelp.c b/drivers/misc/qcom/qdsp6v2/audio_qcelp.c new file mode 100644 index 000000000000..8f2511c40b03 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_qcelp.c @@ -0,0 +1,191 @@ +/* qcelp(v13k) audio output device + * + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "audio_utils_aio.h" + +#define FRAME_SIZE_DEC_QCELP ((32) + sizeof(struct dec_meta_in)) + +static struct miscdevice audio_qcelp_misc; +static struct ws_mgr audio_qcelp_ws_mgr; + +#ifdef CONFIG_DEBUG_FS +static const struct file_operations audio_qcelp_debug_fops = { + .read = audio_aio_debug_read, + .open = audio_aio_debug_open, +}; +#endif + +static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, + audio, audio->ac->session); + if (audio->feedback == NON_TUNNEL_MODE) { + /* Configure PCM output block */ + rc = q6asm_enc_cfg_blk_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + if (rc < 0) { + pr_err("pcm output block config failed\n"); + break; + } + } + + rc = audio_aio_enable(audio); + audio->eos_rsp = 0; + audio->eos_flag = 0; + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("Audio Start procedure failed rc=%d\n", rc); + break; + } + pr_debug("%s: AUDIO_START sessionid[%d]enable[%d]\n", __func__, + audio->ac->session, + audio->enabled); + if (audio->stopped == 1) + audio->stopped = 0; + break; + } + default: + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); + rc = audio->codec_ioctl(file, cmd, arg); + } + return rc; +} + +static int audio_open(struct inode *inode, struct file *file) +{ + struct q6audio_aio *audio = NULL; + int rc = 0; + +#ifdef CONFIG_DEBUG_FS + /* 4 bytes represents decoder number, 1 byte for terminate string */ + char name[sizeof "msm_qcelp_" + 5]; +#endif + audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + + /* Settings will be re-config at AUDIO_SET_CONFIG, + * but at least we need to have initial config + */ + audio->str_cfg.buffer_size = FRAME_SIZE_DEC_QCELP; + audio->str_cfg.buffer_count = FRAME_NUM; + audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN; + audio->pcm_cfg.buffer_count = PCM_BUF_COUNT; + audio->pcm_cfg.sample_rate = 8000; + audio->pcm_cfg.channel_count = 1; + audio->miscdevice = &audio_qcelp_misc; + audio->wakelock_voted = false; + audio->audio_ws_mgr = &audio_qcelp_ws_mgr; + + audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("Could not allocate memory for audio client\n"); + kfree(audio); + return -ENOMEM; + } + rc = audio_aio_open(audio, file); + if (rc < 0) { + pr_err("%s: audio_aio_open rc=%d\n", + __func__, rc); + goto fail; + } + + /* open in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) { + rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM, + FORMAT_V13K); + if (rc < 0) { + pr_err("NT mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = NON_TUNNEL_MODE; + audio->buf_cfg.frames_per_buf = 0x01; + audio->buf_cfg.meta_info_enable = 0x01; + } else if ((file->f_mode & FMODE_WRITE) && + !(file->f_mode & FMODE_READ)) { + rc = q6asm_open_write(audio->ac, FORMAT_V13K); + if (rc < 0) { + pr_err("T mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = TUNNEL_MODE; + audio->buf_cfg.meta_info_enable = 0x00; + } else { + pr_err("Not supported mode\n"); + rc = -EACCES; + goto fail; + } + +#ifdef CONFIG_DEBUG_FS + snprintf(name, sizeof(name), "msm_qcelp_%04x", audio->ac->session); + audio->dentry = debugfs_create_file(name, S_IFREG | 0444, + NULL, (void *)audio, + &audio_qcelp_debug_fops); + + if (IS_ERR(audio->dentry)) + pr_debug("debugfs_create_file failed\n"); +#endif + pr_info("%s:dec success mode[%d]session[%d]\n", __func__, + audio->feedback, + audio->ac->session); + return 0; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio); + return rc; +} + +static const struct file_operations audio_qcelp_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_aio_release, + .unlocked_ioctl = audio_ioctl, + .fsync = audio_aio_fsync, +}; + +static struct miscdevice audio_qcelp_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_qcelp", + .fops = &audio_qcelp_fops, +}; + +static int __init audio_qcelp_init(void) +{ + int ret = misc_register(&audio_qcelp_misc); + + if (ret == 0) + device_init_wakeup(audio_qcelp_misc.this_device, true); + audio_qcelp_ws_mgr.ref_cnt = 0; + mutex_init(&audio_qcelp_ws_mgr.ws_lock); + + return ret; +} + +device_initcall(audio_qcelp_init); diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils.c b/drivers/misc/qcom/qdsp6v2/audio_utils.c new file mode 100644 index 000000000000..15ee9f51a7d8 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_utils.c @@ -0,0 +1,954 @@ +/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "audio_utils.h" + +/* + * Define maximum buffer size. Below values are chosen considering the higher + * values used among all native drivers. + */ +#define MAX_FRAME_SIZE 1536 +#define MAX_FRAMES 5 +#define META_SIZE (sizeof(struct meta_out_dsp)) +#define MAX_BUFFER_SIZE (1 + ((MAX_FRAME_SIZE + META_SIZE) * MAX_FRAMES)) + +static int audio_in_pause(struct q6audio_in *audio) +{ + int rc; + + rc = q6asm_cmd(audio->ac, CMD_PAUSE); + if (rc < 0) + pr_err("%s:session id %d: pause cmd failed rc=%d\n", __func__, + audio->ac->session, rc); + + return rc; +} + +static int audio_in_flush(struct q6audio_in *audio) +{ + int rc; + + pr_debug("%s:session id %d: flush\n", __func__, audio->ac->session); + /* Flush if session running */ + if (audio->enabled) { + /* Implicitly issue a pause to the encoder before flushing */ + rc = audio_in_pause(audio); + if (rc < 0) { + pr_err("%s:session id %d: pause cmd failed rc=%d\n", + __func__, audio->ac->session, rc); + return rc; + } + + rc = q6asm_cmd(audio->ac, CMD_FLUSH); + if (rc < 0) { + pr_err("%s:session id %d: flush cmd failed rc=%d\n", + __func__, audio->ac->session, rc); + return rc; + } + /* 2nd arg: 0 -> run immediately + * 3rd arg: 0 -> msw_ts, + * 4th arg: 0 ->lsw_ts + */ + q6asm_run(audio->ac, 0x00, 0x00, 0x00); + pr_debug("Rerun the session\n"); + } + audio->rflush = 1; + audio->wflush = 1; + memset(audio->out_frame_info, 0, sizeof(audio->out_frame_info)); + wake_up(&audio->read_wait); + /* get read_lock to ensure no more waiting read thread */ + mutex_lock(&audio->read_lock); + audio->rflush = 0; + mutex_unlock(&audio->read_lock); + wake_up(&audio->write_wait); + /* get write_lock to ensure no more waiting write thread */ + mutex_lock(&audio->write_lock); + audio->wflush = 0; + mutex_unlock(&audio->write_lock); + pr_debug("%s:session id %d: in_bytes %d\n", __func__, + audio->ac->session, atomic_read(&audio->in_bytes)); + pr_debug("%s:session id %d: in_samples %d\n", __func__, + audio->ac->session, atomic_read(&audio->in_samples)); + atomic_set(&audio->in_bytes, 0); + atomic_set(&audio->in_samples, 0); + atomic_set(&audio->out_count, 0); + return 0; +} + +/* must be called with audio->lock held */ +int audio_in_enable(struct q6audio_in *audio) +{ + if (audio->enabled) + return 0; + + /* 2nd arg: 0 -> run immediately + * 3rd arg: 0 -> msw_ts, + * 4th arg: 0 ->lsw_ts + */ + return q6asm_run(audio->ac, 0x00, 0x00, 0x00); +} + +/* must be called with audio->lock held */ +int audio_in_disable(struct q6audio_in *audio) +{ + int rc = 0; + + if (!audio->stopped) { + audio->enabled = 0; + audio->opened = 0; + pr_debug("%s:session id %d: inbytes[%d] insamples[%d]\n", + __func__, audio->ac->session, + atomic_read(&audio->in_bytes), + atomic_read(&audio->in_samples)); + + rc = q6asm_cmd(audio->ac, CMD_CLOSE); + if (rc < 0) + pr_err("%s:session id %d: Failed to close the session rc=%d\n", + __func__, audio->ac->session, + rc); + audio->stopped = 1; + memset(audio->out_frame_info, 0, + sizeof(audio->out_frame_info)); + wake_up(&audio->read_wait); + wake_up(&audio->write_wait); + } + pr_debug("%s:session id %d: enabled[%d]\n", __func__, + audio->ac->session, audio->enabled); + return rc; +} + +int audio_in_buf_alloc(struct q6audio_in *audio) +{ + int rc = 0; + + switch (audio->buf_alloc) { + case NO_BUF_ALLOC: + if (audio->feedback == NON_TUNNEL_MODE) { + rc = q6asm_audio_client_buf_alloc(IN, + audio->ac, + ALIGN_BUF_SIZE(audio->pcm_cfg.buffer_size), + audio->pcm_cfg.buffer_count); + if (rc < 0) { + pr_err("%s:session id %d: Buffer Alloc failed\n", + __func__, + audio->ac->session); + rc = -ENOMEM; + break; + } + audio->buf_alloc |= BUF_ALLOC_IN; + } + rc = q6asm_audio_client_buf_alloc(OUT, audio->ac, + ALIGN_BUF_SIZE(audio->str_cfg.buffer_size), + audio->str_cfg.buffer_count); + if (rc < 0) { + pr_err("%s:session id %d: Buffer Alloc failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENOMEM; + break; + } + audio->buf_alloc |= BUF_ALLOC_OUT; + break; + case BUF_ALLOC_IN: + rc = q6asm_audio_client_buf_alloc(OUT, audio->ac, + ALIGN_BUF_SIZE(audio->str_cfg.buffer_size), + audio->str_cfg.buffer_count); + if (rc < 0) { + pr_err("%s:session id %d: Buffer Alloc failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENOMEM; + break; + } + audio->buf_alloc |= BUF_ALLOC_OUT; + break; + case BUF_ALLOC_OUT: + if (audio->feedback == NON_TUNNEL_MODE) { + rc = q6asm_audio_client_buf_alloc(IN, audio->ac, + ALIGN_BUF_SIZE(audio->pcm_cfg.buffer_size), + audio->pcm_cfg.buffer_count); + if (rc < 0) { + pr_err("%s:session id %d: Buffer Alloc failed\n", + __func__, + audio->ac->session); + rc = -ENOMEM; + break; + } + audio->buf_alloc |= BUF_ALLOC_IN; + } + break; + default: + pr_debug("%s:session id %d: buf[%d]\n", __func__, + audio->ac->session, audio->buf_alloc); + } + + return rc; +} + +int audio_in_set_config(struct file *file, + struct msm_audio_config *cfg) +{ + int rc = 0; + struct q6audio_in *audio = file->private_data; + + if (audio->feedback != NON_TUNNEL_MODE) { + pr_err("%s:session id %d: Not sufficient permission to change the record mode\n", + __func__, audio->ac->session); + rc = -EACCES; + goto ret; + } + if ((cfg->buffer_count > PCM_BUF_COUNT) || + (cfg->buffer_count == 1)) + cfg->buffer_count = PCM_BUF_COUNT; + + audio->pcm_cfg.buffer_count = cfg->buffer_count; + audio->pcm_cfg.buffer_size = cfg->buffer_size; + audio->pcm_cfg.channel_count = cfg->channel_count; + audio->pcm_cfg.sample_rate = cfg->sample_rate; + if (audio->opened && audio->feedback == NON_TUNNEL_MODE) { + rc = q6asm_audio_client_buf_alloc(IN, audio->ac, + ALIGN_BUF_SIZE(audio->pcm_cfg.buffer_size), + audio->pcm_cfg.buffer_count); + if (rc < 0) { + pr_err("%s:session id %d: Buffer Alloc failed\n", + __func__, audio->ac->session); + rc = -ENOMEM; + goto ret; + } + } + audio->buf_alloc |= BUF_ALLOC_IN; + rc = 0; + pr_debug("%s:session id %d: AUDIO_SET_CONFIG %d %d\n", __func__, + audio->ac->session, audio->pcm_cfg.buffer_count, + audio->pcm_cfg.buffer_size); +ret: + return rc; +} +/* ------------------- device --------------------- */ +static long audio_in_ioctl_shared(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_FLUSH: { + /* Make sure we're stopped and we wake any threads + * that might be blocked holding the read_lock. + * While audio->stopped read threads will always + * exit immediately. + */ + rc = audio_in_flush(audio); + if (rc < 0) + pr_err("%s:session id %d: Flush Fail rc=%d\n", + __func__, audio->ac->session, rc); + else { /* Register back the flushed read buffer with DSP */ + int cnt = 0; + + while (cnt++ < audio->str_cfg.buffer_count) + q6asm_read(audio->ac); /* Push buffer to DSP */ + pr_debug("register the read buffer\n"); + } + break; + } + case AUDIO_PAUSE: { + pr_debug("%s:session id %d: AUDIO_PAUSE\n", __func__, + audio->ac->session); + if (audio->enabled) + audio_in_pause(audio); + break; + } + case AUDIO_GET_SESSION_ID: { + if (copy_to_user((void *) arg, &audio->ac->session, + sizeof(u16))) { + pr_err("%s: copy_to_user for AUDIO_GET_SESSION_ID failed\n", + __func__); + rc = -EFAULT; + } + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + } + return rc; +} + +long audio_in_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + if (cmd == AUDIO_GET_STATS) { + struct msm_audio_stats stats; + + memset(&stats, 0, sizeof(stats)); + stats.byte_count = atomic_read(&audio->in_bytes); + stats.sample_count = atomic_read(&audio->in_samples); + if (copy_to_user((void *) arg, &stats, sizeof(stats))) + return -EFAULT; + return rc; + } + + mutex_lock(&audio->lock); + switch (cmd) { + case AUDIO_FLUSH: + case AUDIO_PAUSE: + case AUDIO_GET_SESSION_ID: + rc = audio_in_ioctl_shared(file, cmd, arg); + break; + case AUDIO_GET_STREAM_CONFIG: { + struct msm_audio_stream_config cfg; + + memset(&cfg, 0, sizeof(cfg)); + cfg.buffer_size = audio->str_cfg.buffer_size; + cfg.buffer_count = audio->str_cfg.buffer_count; + if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) + rc = -EFAULT; + pr_debug("%s:session id %d: AUDIO_GET_STREAM_CONFIG %d %d\n", + __func__, audio->ac->session, cfg.buffer_size, + cfg.buffer_count); + break; + } + case AUDIO_SET_STREAM_CONFIG: { + struct msm_audio_stream_config cfg; + + if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) { + pr_err("%s: copy_from_user for AUDIO_SET_STREAM_CONFIG failed\n" + , __func__); + rc = -EFAULT; + break; + } + /* Minimum single frame size, + * but with in maximum frames number + */ + if ((cfg.buffer_size < (audio->min_frame_size + + sizeof(struct meta_out_dsp))) || + (cfg.buffer_count < FRAME_NUM)) { + rc = -EINVAL; + break; + } + if (cfg.buffer_size > MAX_BUFFER_SIZE) { + rc = -EINVAL; + break; + } + audio->str_cfg.buffer_size = cfg.buffer_size; + audio->str_cfg.buffer_count = cfg.buffer_count; + if (audio->opened) { + rc = q6asm_audio_client_buf_alloc(OUT, audio->ac, + ALIGN_BUF_SIZE(audio->str_cfg.buffer_size), + audio->str_cfg.buffer_count); + if (rc < 0) { + pr_err("%s: session id %d: Buffer Alloc failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENOMEM; + break; + } + } + audio->buf_alloc |= BUF_ALLOC_OUT; + rc = 0; + pr_debug("%s:session id %d: AUDIO_SET_STREAM_CONFIG %d %d\n", + __func__, audio->ac->session, + audio->str_cfg.buffer_size, + audio->str_cfg.buffer_count); + break; + } + case AUDIO_SET_BUF_CFG: { + struct msm_audio_buf_cfg cfg; + + if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) { + rc = -EFAULT; + break; + } + if ((audio->feedback == NON_TUNNEL_MODE) && + !cfg.meta_info_enable) { + rc = -EFAULT; + break; + } + + /* Restrict the num of frames per buf to coincide with + * default buf size + */ + if (cfg.frames_per_buf > audio->max_frames_per_buf) { + rc = -EFAULT; + break; + } + audio->buf_cfg.meta_info_enable = cfg.meta_info_enable; + audio->buf_cfg.frames_per_buf = cfg.frames_per_buf; + pr_debug("%s:session id %d: Set-buf-cfg: meta[%d] framesperbuf[%d]\n", + __func__, + audio->ac->session, cfg.meta_info_enable, + cfg.frames_per_buf); + break; + } + case AUDIO_GET_BUF_CFG: { + pr_debug("%s:session id %d: Get-buf-cfg: meta[%d] framesperbuf[%d]\n", + __func__, + audio->ac->session, audio->buf_cfg.meta_info_enable, + audio->buf_cfg.frames_per_buf); + + if (copy_to_user((void *)arg, &audio->buf_cfg, + sizeof(struct msm_audio_buf_cfg))) + rc = -EFAULT; + break; + } + case AUDIO_GET_CONFIG: { + if (copy_to_user((void *)arg, &audio->pcm_cfg, + sizeof(struct msm_audio_config))) + rc = -EFAULT; + break; + + } + case AUDIO_SET_CONFIG: { + struct msm_audio_config cfg; + + if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) { + pr_err("%s: copy_from_user for AUDIO_SET_CONFIG failed\n", + __func__); + rc = -EFAULT; + break; + } + rc = audio_in_set_config(file, &cfg); + break; + } + default: + /* call codec specific ioctl */ + rc = audio->enc_ioctl(file, cmd, arg); + } + mutex_unlock(&audio->lock); + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_audio_stats32 { + u32 byte_count; + u32 sample_count; + u32 unused[2]; +}; + +struct msm_audio_stream_config32 { + u32 buffer_size; + u32 buffer_count; +}; + +struct msm_audio_config32 { + u32 buffer_size; + u32 buffer_count; + u32 channel_count; + u32 sample_rate; + u32 type; + u32 meta_field; + u32 bits; + u32 unused[3]; +}; + +struct msm_audio_buf_cfg32 { + u32 meta_info_enable; + u32 frames_per_buf; +}; + +enum { + AUDIO_GET_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, 3, + struct msm_audio_config32), + AUDIO_SET_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, 4, + struct msm_audio_config32), + AUDIO_GET_STATS_32 = _IOR(AUDIO_IOCTL_MAGIC, 5, + struct msm_audio_stats32), + AUDIO_SET_STREAM_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, 80, + struct msm_audio_stream_config32), + AUDIO_GET_STREAM_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, 81, + struct msm_audio_stream_config32), + AUDIO_SET_BUF_CFG_32 = _IOW(AUDIO_IOCTL_MAGIC, 94, + struct msm_audio_buf_cfg32), + AUDIO_GET_BUF_CFG_32 = _IOW(AUDIO_IOCTL_MAGIC, 93, + struct msm_audio_buf_cfg32), +}; + +long audio_in_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + if (cmd == AUDIO_GET_STATS_32) { + struct msm_audio_stats32 stats_32; + + memset(&stats_32, 0, sizeof(stats_32)); + stats_32.byte_count = atomic_read(&audio->in_bytes); + stats_32.sample_count = atomic_read(&audio->in_samples); + if (copy_to_user((void *) arg, &stats_32, sizeof(stats_32))) { + pr_err("%s: copy_to_user failed for AUDIO_GET_STATS_32\n", + __func__); + return -EFAULT; + } + return rc; + } + + mutex_lock(&audio->lock); + switch (cmd) { + case AUDIO_FLUSH: + case AUDIO_PAUSE: + case AUDIO_GET_SESSION_ID: + rc = audio_in_ioctl_shared(file, cmd, arg); + break; + case AUDIO_GET_STREAM_CONFIG_32: { + struct msm_audio_stream_config32 cfg_32; + + memset(&cfg_32, 0, sizeof(cfg_32)); + cfg_32.buffer_size = audio->str_cfg.buffer_size; + cfg_32.buffer_count = audio->str_cfg.buffer_count; + if (copy_to_user((void *)arg, &cfg_32, sizeof(cfg_32))) { + pr_err("%s: Copy to user failed\n", __func__); + rc = -EFAULT; + } + pr_debug("%s:session id %d: AUDIO_GET_STREAM_CONFIG %d %d\n", + __func__, audio->ac->session, + cfg_32.buffer_size, + cfg_32.buffer_count); + break; + } + case AUDIO_SET_STREAM_CONFIG_32: { + struct msm_audio_stream_config32 cfg_32; + struct msm_audio_stream_config cfg; + + if (copy_from_user(&cfg_32, (void *)arg, sizeof(cfg_32))) { + pr_err("%s: copy_from_user for AUDIO_SET_STREAM_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + cfg.buffer_size = cfg_32.buffer_size; + cfg.buffer_count = cfg_32.buffer_count; + /* Minimum single frame size, + * but with in maximum frames number + */ + if ((cfg.buffer_size < (audio->min_frame_size + + sizeof(struct meta_out_dsp))) || + (cfg.buffer_count < FRAME_NUM)) { + rc = -EINVAL; + break; + } + audio->str_cfg.buffer_size = cfg.buffer_size; + audio->str_cfg.buffer_count = cfg.buffer_count; + if (audio->opened) { + rc = q6asm_audio_client_buf_alloc(OUT, audio->ac, + ALIGN_BUF_SIZE(audio->str_cfg.buffer_size), + audio->str_cfg.buffer_count); + if (rc < 0) { + pr_err("%s: session id %d:\n", + __func__, audio->ac->session); + pr_err("Buffer Alloc failed rc=%d\n", rc); + rc = -ENOMEM; + break; + } + } + audio->buf_alloc |= BUF_ALLOC_OUT; + pr_debug("%s:session id %d: AUDIO_SET_STREAM_CONFIG %d %d\n", + __func__, audio->ac->session, + audio->str_cfg.buffer_size, + audio->str_cfg.buffer_count); + break; + } + case AUDIO_SET_BUF_CFG_32: { + struct msm_audio_buf_cfg32 cfg_32; + struct msm_audio_buf_cfg cfg; + + if (copy_from_user(&cfg_32, (void *)arg, sizeof(cfg_32))) { + pr_err("%s: copy_from_user for AUDIO_SET_BUG_CFG_32 failed", + __func__); + rc = -EFAULT; + break; + } + cfg.meta_info_enable = cfg_32.meta_info_enable; + cfg.frames_per_buf = cfg_32.frames_per_buf; + + if ((audio->feedback == NON_TUNNEL_MODE) && + !cfg.meta_info_enable) { + rc = -EFAULT; + break; + } + + /* Restrict the num of frames per buf to coincide with + * default buf size + */ + if (cfg.frames_per_buf > audio->max_frames_per_buf) { + rc = -EFAULT; + break; + } + audio->buf_cfg.meta_info_enable = cfg.meta_info_enable; + audio->buf_cfg.frames_per_buf = cfg.frames_per_buf; + pr_debug("%s:session id %d: Set-buf-cfg: meta[%d] framesperbuf[%d]\n", + __func__, audio->ac->session, cfg.meta_info_enable, + cfg.frames_per_buf); + break; + } + case AUDIO_GET_BUF_CFG_32: { + struct msm_audio_buf_cfg32 cfg_32; + + pr_debug("%s:session id %d: Get-buf-cfg: meta[%d] framesperbuf[%d]\n", + __func__, + audio->ac->session, audio->buf_cfg.meta_info_enable, + audio->buf_cfg.frames_per_buf); + cfg_32.meta_info_enable = audio->buf_cfg.meta_info_enable; + cfg_32.frames_per_buf = audio->buf_cfg.frames_per_buf; + + if (copy_to_user((void *)arg, &cfg_32, + sizeof(struct msm_audio_buf_cfg32))) { + pr_err("%s: Copy to user failed\n", __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_GET_CONFIG_32: { + struct msm_audio_config32 cfg_32; + + memset(&cfg_32, 0, sizeof(cfg_32)); + cfg_32.buffer_size = audio->pcm_cfg.buffer_size; + cfg_32.buffer_count = audio->pcm_cfg.buffer_count; + cfg_32.channel_count = audio->pcm_cfg.channel_count; + cfg_32.sample_rate = audio->pcm_cfg.sample_rate; + cfg_32.type = audio->pcm_cfg.type; + cfg_32.meta_field = audio->pcm_cfg.meta_field; + cfg_32.bits = audio->pcm_cfg.bits; + + if (copy_to_user((void *)arg, &cfg_32, + sizeof(struct msm_audio_config32))) { + pr_err("%s: Copy to user failed\n", __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_CONFIG_32: { + struct msm_audio_config32 cfg_32; + struct msm_audio_config cfg; + + if (copy_from_user(&cfg_32, (void *)arg, sizeof(cfg_32))) { + pr_err("%s: copy_from_user for AUDIO_SET_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + cfg.buffer_size = cfg_32.buffer_size; + cfg.buffer_count = cfg_32.buffer_count; + cfg.channel_count = cfg_32.channel_count; + cfg.sample_rate = cfg_32.sample_rate; + cfg.type = cfg_32.type; + cfg.meta_field = cfg_32.meta_field; + cfg.bits = cfg_32.bits; + rc = audio_in_set_config(file, &cfg); + break; + } + default: + /* call codec specific ioctl */ + rc = audio->enc_compat_ioctl(file, cmd, arg); + } + mutex_unlock(&audio->lock); + return rc; +} +#endif + +ssize_t audio_in_read(struct file *file, + char __user *buf, + size_t count, loff_t *pos) +{ + struct q6audio_in *audio = file->private_data; + const char __user *start = buf; + unsigned char *data; + uint32_t offset = 0; + uint32_t size = 0; + int rc = 0; + uint32_t idx; + struct meta_out_dsp meta; + uint32_t bytes_to_copy = 0; + uint32_t mfield_size = (audio->buf_cfg.meta_info_enable == 0) ? 0 : + (sizeof(unsigned char) + + (sizeof(struct meta_out_dsp)*(audio->buf_cfg.frames_per_buf))); + + memset(&meta, 0, sizeof(meta)); + pr_debug("%s:session id %d: read - %zd\n", __func__, audio->ac->session, + count); + if (audio->reset_event) + return -ENETRESET; + + if (!audio->enabled) + return -EFAULT; + mutex_lock(&audio->read_lock); + while (count > 0) { + rc = wait_event_interruptible( + audio->read_wait, + ((atomic_read(&audio->out_count) > 0) || + (audio->stopped) || + audio->rflush || audio->eos_rsp || + audio->event_abort)); + + if (audio->event_abort) { + rc = -EIO; + break; + } + + + if (rc < 0) + break; + + if ((audio->stopped && !(atomic_read(&audio->out_count))) || + audio->rflush) { + pr_debug("%s:session id %d: driver in stop state or flush,No more buf to read", + __func__, + audio->ac->session); + rc = 0;/* End of File */ + break; + } + if (!(atomic_read(&audio->out_count)) && + (audio->eos_rsp == 1) && + (count >= (sizeof(unsigned char) + + sizeof(struct meta_out_dsp)))) { + unsigned char num_of_frames; + + pr_info("%s:session id %d: eos %d at output\n", + __func__, audio->ac->session, audio->eos_rsp); + if (buf != start) + break; + num_of_frames = 0xFF; + if (copy_to_user(buf, &num_of_frames, + sizeof(unsigned char))) { + rc = -EFAULT; + break; + } + buf += sizeof(unsigned char); + meta.frame_size = 0xFFFF; + meta.encoded_pcm_samples = 0xFFFF; + meta.msw_ts = 0x00; + meta.lsw_ts = 0x00; + meta.nflags = AUD_EOS_SET; + audio->eos_rsp = 0; + if (copy_to_user(buf, &meta, sizeof(meta))) { + rc = -EFAULT; + break; + } + buf += sizeof(meta); + break; + } + data = (unsigned char *)q6asm_is_cpu_buf_avail(OUT, audio->ac, + &size, &idx); + if ((count >= (size + mfield_size)) && data) { + if (audio->buf_cfg.meta_info_enable) { + if (copy_to_user(buf, + &audio->out_frame_info[idx][0], + sizeof(unsigned char))) { + rc = -EFAULT; + break; + } + bytes_to_copy = + (size + audio->out_frame_info[idx][1]); + /* Number of frames information copied */ + buf += sizeof(unsigned char); + count -= sizeof(unsigned char); + } else { + offset = audio->out_frame_info[idx][1]; + bytes_to_copy = size; + } + + pr_debug("%s:session id %d: offset=%d nr of frames= %d\n", + __func__, audio->ac->session, + audio->out_frame_info[idx][1], + audio->out_frame_info[idx][0]); + + if (copy_to_user(buf, &data[offset], bytes_to_copy)) { + rc = -EFAULT; + break; + } + count -= bytes_to_copy; + buf += bytes_to_copy; + } else { + pr_err("%s:session id %d: short read data[%pK] bytesavail[%d]bytesrequest[%zd]\n", + __func__, + audio->ac->session, + data, size, count); + } + atomic_dec(&audio->out_count); + q6asm_read(audio->ac); + break; + } + mutex_unlock(&audio->read_lock); + + pr_debug("%s:session id %d: read: %zd bytes\n", __func__, + audio->ac->session, (buf-start)); + if (buf > start) + return buf - start; + return rc; +} + +static int extract_meta_info(char *buf, unsigned long *msw_ts, + unsigned long *lsw_ts, unsigned int *flags) +{ + struct meta_in *meta = (struct meta_in *)buf; + *msw_ts = meta->ntimestamp.highpart; + *lsw_ts = meta->ntimestamp.lowpart; + *flags = meta->nflags; + return 0; +} + +ssize_t audio_in_write(struct file *file, + const char __user *buf, + size_t count, loff_t *pos) +{ + struct q6audio_in *audio = file->private_data; + const char __user *start = buf; + size_t xfer = 0; + char *cpy_ptr; + int rc = 0; + unsigned char *data; + uint32_t size = 0; + uint32_t idx = 0; + uint32_t nflags = 0; + unsigned long msw_ts = 0; + unsigned long lsw_ts = 0; + uint32_t mfield_size = (audio->buf_cfg.meta_info_enable == 0) ? 0 : + sizeof(struct meta_in); + + pr_debug("%s:session id %d: to write[%zd]\n", __func__, + audio->ac->session, count); + if (audio->reset_event) + return -ENETRESET; + + if (!audio->enabled) + return -EFAULT; + mutex_lock(&audio->write_lock); + + while (count > 0) { + rc = wait_event_interruptible(audio->write_wait, + ((atomic_read(&audio->in_count) > 0) || + (audio->stopped) || + (audio->wflush) || (audio->event_abort))); + + if (audio->event_abort) { + rc = -EIO; + break; + } + + if (rc < 0) + break; + if (audio->stopped || audio->wflush) { + pr_debug("%s: session id %d: stop or flush\n", __func__, + audio->ac->session); + rc = -EBUSY; + break; + } + /* if no PCM data, might have only eos buffer + * such case do not hold cpu buffer + */ + if ((buf == start) && (count == mfield_size)) { + char eos_buf[sizeof(struct meta_in)]; + /* Processing beginning of user buffer */ + if (copy_from_user(eos_buf, buf, mfield_size)) { + rc = -EFAULT; + break; + } + /* Check if EOS flag is set and buffer has + * contains just meta field + */ + extract_meta_info(eos_buf, &msw_ts, &lsw_ts, + &nflags); + buf += mfield_size; + /* send the EOS and return */ + pr_debug("%s:session id %d: send EOS 0x%8x\n", + __func__, + audio->ac->session, nflags); + break; + } + data = (unsigned char *)q6asm_is_cpu_buf_avail(IN, audio->ac, + &size, &idx); + if (!data) { + pr_debug("%s:session id %d: No buf available\n", + __func__, audio->ac->session); + continue; + } + cpy_ptr = data; + if (audio->buf_cfg.meta_info_enable) { + if (buf == start) { + /* Processing beginning of user buffer */ + if (copy_from_user(cpy_ptr, buf, mfield_size)) { + rc = -EFAULT; + break; + } + /* Check if EOS flag is set and buffer has + * contains just meta field + */ + extract_meta_info(cpy_ptr, &msw_ts, &lsw_ts, + &nflags); + buf += mfield_size; + count -= mfield_size; + } else { + pr_debug("%s:session id %d: continuous buffer\n", + __func__, audio->ac->session); + } + } + xfer = (count > (audio->pcm_cfg.buffer_size)) ? + (audio->pcm_cfg.buffer_size) : count; + + if (copy_from_user(cpy_ptr, buf, xfer)) { + rc = -EFAULT; + break; + } + rc = q6asm_write(audio->ac, xfer, msw_ts, lsw_ts, 0x00); + if (rc < 0) { + rc = -EFAULT; + break; + } + atomic_dec(&audio->in_count); + count -= xfer; + buf += xfer; + } + mutex_unlock(&audio->write_lock); + pr_debug("%s:session id %d: eos_condition 0x%x buf[0x%pK] start[0x%pK]\n", + __func__, audio->ac->session, + nflags, buf, start); + if (nflags & AUD_EOS_SET) { + rc = q6asm_cmd(audio->ac, CMD_EOS); + pr_info("%s:session id %d: eos %d at input\n", __func__, + audio->ac->session, audio->eos_rsp); + } + pr_debug("%s:session id %d: Written %zd Avail Buf[%d]", __func__, + audio->ac->session, (buf - start - mfield_size), + atomic_read(&audio->in_count)); + if (!rc) { + if (buf > start) + return buf - start; + } + return rc; +} + +int audio_in_release(struct inode *inode, struct file *file) +{ + struct q6audio_in *audio = file->private_data; + + pr_info("%s: session id %d\n", __func__, audio->ac->session); + mutex_lock(&audio->lock); + audio_in_disable(audio); + q6asm_audio_client_free(audio->ac); + mutex_unlock(&audio->lock); + kfree(audio->enc_cfg); + kfree(audio->codec_cfg); + kfree(audio); + return 0; +} diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils.h b/drivers/misc/qcom/qdsp6v2/audio_utils.h new file mode 100644 index 000000000000..f5517d833621 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_utils.h @@ -0,0 +1,114 @@ +/* Copyright (c) 2010-2015, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include "q6audio_common.h" + +#define FRAME_NUM (8) + +#define PCM_BUF_COUNT (2) + +#define AUD_EOS_SET 0x01 +#define TUNNEL_MODE 0x0000 +#define NON_TUNNEL_MODE 0x0001 + +#define NO_BUF_ALLOC 0x00 +#define BUF_ALLOC_IN 0x01 +#define BUF_ALLOC_OUT 0x02 +#define BUF_ALLOC_INOUT 0x03 +#define ALIGN_BUF_SIZE(size) ((size + 4095) & (~4095)) + +struct timestamp { + u32 lowpart; + u32 highpart; +} __packed; + +struct meta_in { + unsigned short offset; + struct timestamp ntimestamp; + unsigned int nflags; +} __packed; + +struct meta_out_dsp { + u32 offset_to_frame; + u32 frame_size; + u32 encoded_pcm_samples; + u32 msw_ts; + u32 lsw_ts; + u32 nflags; +} __packed; + +struct meta_out { + unsigned char num_of_frames; + struct meta_out_dsp meta_out_dsp[]; +} __packed; + +struct q6audio_in { + spinlock_t dsp_lock; + atomic_t in_bytes; + atomic_t in_samples; + + struct mutex lock; + struct mutex read_lock; + struct mutex write_lock; + wait_queue_head_t read_wait; + wait_queue_head_t write_wait; + + struct audio_client *ac; + struct msm_audio_stream_config str_cfg; + void *enc_cfg; + struct msm_audio_buf_cfg buf_cfg; + struct msm_audio_config pcm_cfg; + void *codec_cfg; + + /* number of buffers available to read/write */ + atomic_t in_count; + atomic_t out_count; + + /* first idx: num of frames per buf, second idx: offset to frame */ + uint32_t out_frame_info[FRAME_NUM][2]; + int eos_rsp; + int opened; + int enabled; + int stopped; + int event_abort; + int feedback; /* Flag indicates whether used + * in Non Tunnel mode + */ + int rflush; + int wflush; + int buf_alloc; + uint16_t min_frame_size; + uint16_t max_frames_per_buf; + bool reset_event; + long (*enc_ioctl)(struct file *, unsigned int, unsigned long); + long (*enc_compat_ioctl)(struct file *, unsigned int, unsigned long); +}; + +int audio_in_enable(struct q6audio_in *audio); +int audio_in_disable(struct q6audio_in *audio); +int audio_in_buf_alloc(struct q6audio_in *audio); +long audio_in_ioctl(struct file *file, + unsigned int cmd, unsigned long arg); +#ifdef CONFIG_COMPAT +long audio_in_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg); +#else +#define audio_in_compat_ioctl NULL +#endif +ssize_t audio_in_read(struct file *file, char __user *buf, + size_t count, loff_t *pos); +ssize_t audio_in_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos); +int audio_in_release(struct inode *inode, struct file *file); +int audio_in_set_config(struct file *file, struct msm_audio_config *cfg); diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c new file mode 100644 index 000000000000..80f6e57e4699 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c @@ -0,0 +1,2142 @@ +/* Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "audio_utils_aio.h" +#ifdef CONFIG_USE_DEV_CTRL_VOLUME +#include +#endif /*CONFIG_USE_DEV_CTRL_VOLUME*/ +#ifdef CONFIG_DEBUG_FS +int audio_aio_debug_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +ssize_t audio_aio_debug_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + const int debug_bufmax = 4096; + static char buffer[4096]; + int n = 0; + struct q6audio_aio *audio = file->private_data; + + mutex_lock(&audio->lock); + n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); + n += scnprintf(buffer + n, debug_bufmax - n, + "enabled %d\n", audio->enabled); + n += scnprintf(buffer + n, debug_bufmax - n, + "stopped %d\n", audio->stopped); + n += scnprintf(buffer + n, debug_bufmax - n, + "feedback %d\n", audio->feedback); + mutex_unlock(&audio->lock); + /* Following variables are only useful for debugging when + * when playback halts unexpectedly. Thus, no mutual exclusion + * enforced + */ + n += scnprintf(buffer + n, debug_bufmax - n, + "wflush %d\n", audio->wflush); + n += scnprintf(buffer + n, debug_bufmax - n, + "rflush %d\n", audio->rflush); + n += scnprintf(buffer + n, debug_bufmax - n, + "inqueue empty %d\n", list_empty(&audio->in_queue)); + n += scnprintf(buffer + n, debug_bufmax - n, + "outqueue empty %d\n", list_empty(&audio->out_queue)); + buffer[n] = 0; + return simple_read_from_buffer(buf, count, ppos, buffer, n); +} +#endif + +static long audio_aio_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); +#ifdef CONFIG_COMPAT +static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); +#else +#define audio_aio_compat_ioctl NULL +#endif +int insert_eos_buf(struct q6audio_aio *audio, + struct audio_aio_buffer_node *buf_node) +{ + struct dec_meta_out *eos_buf = buf_node->kvaddr; + + pr_debug("%s[%pK]:insert_eos_buf\n", __func__, audio); + eos_buf->num_of_frames = 0xFFFFFFFF; + eos_buf->meta_out_dsp[0].offset_to_frame = 0x0; + eos_buf->meta_out_dsp[0].nflags = AUDIO_DEC_EOS_SET; + return sizeof(struct dec_meta_out) + + sizeof(eos_buf->meta_out_dsp[0]); +} + +/* Routine which updates read buffers of driver/dsp, + * for flush operation as DSP output might not have proper + * value set + */ +static int insert_meta_data_flush(struct q6audio_aio *audio, + struct audio_aio_buffer_node *buf_node) +{ + struct dec_meta_out *meta_data = buf_node->kvaddr; + + meta_data->num_of_frames = 0x0; + meta_data->meta_out_dsp[0].offset_to_frame = 0x0; + meta_data->meta_out_dsp[0].nflags = 0x0; + return sizeof(struct dec_meta_out) + + sizeof(meta_data->meta_out_dsp[0]); +} + +static int audio_aio_ion_lookup_vaddr(struct q6audio_aio *audio, void *addr, + unsigned long len, + struct audio_aio_ion_region **region) +{ + struct audio_aio_ion_region *region_elt; + + int match_count = 0; + + *region = NULL; + + /* returns physical address or zero */ + list_for_each_entry(region_elt, &audio->ion_region_queue, list) { + if (addr >= region_elt->vaddr && + addr < region_elt->vaddr + region_elt->len && + addr + len <= region_elt->vaddr + region_elt->len && + addr + len > addr) { + /* to avoid integer addition overflow */ + + /* offset since we could pass vaddr inside a registered + * ion buffer + */ + + match_count++; + if (!*region) + *region = region_elt; + } + } + + if (match_count > 1) { + pr_err("%s[%pK]:multiple hits for vaddr %pK, len %ld\n", + __func__, audio, addr, len); + list_for_each_entry(region_elt, &audio->ion_region_queue, + list) { + if (addr >= region_elt->vaddr && + addr < region_elt->vaddr + region_elt->len && + addr + len <= region_elt->vaddr + region_elt->len && + addr + len > addr) + pr_err("\t%s[%pK]:%pK, %ld --> %pK\n", + __func__, audio, + region_elt->vaddr, + region_elt->len, + ®ion_elt->paddr); + } + } + + return *region ? 0 : -1; +} + +static phys_addr_t audio_aio_ion_fixup(struct q6audio_aio *audio, void *addr, + unsigned long len, int ref_up, void **kvaddr) +{ + struct audio_aio_ion_region *region; + phys_addr_t paddr; + int ret; + + ret = audio_aio_ion_lookup_vaddr(audio, addr, len, ®ion); + if (ret) { + pr_err("%s[%pK]:lookup (%pK, %ld) failed\n", + __func__, audio, addr, len); + return 0; + } + if (ref_up) + region->ref_cnt++; + else + region->ref_cnt--; + pr_debug("%s[%pK]:found region %pK ref_cnt %d\n", + __func__, audio, region, region->ref_cnt); + paddr = region->paddr + (addr - region->vaddr); + /* provide kernel virtual address for accessing meta information */ + if (kvaddr) + *kvaddr = (void *) (region->kvaddr + (addr - region->vaddr)); + return paddr; +} + +static int audio_aio_pause(struct q6audio_aio *audio) +{ + int rc = -EINVAL; + + pr_debug("%s[%pK], enabled = %d\n", __func__, audio, + audio->enabled); + if (audio->enabled) { + rc = q6asm_cmd(audio->ac, CMD_PAUSE); + if (rc < 0) + pr_err("%s[%pK]: pause cmd failed rc=%d\n", + __func__, audio, rc); + + if (rc == 0) { + /* Send suspend only if pause was successful */ + rc = q6asm_cmd(audio->ac, CMD_SUSPEND); + if (rc < 0) + pr_err("%s[%pK]: suspend cmd failed rc=%d\n", + __func__, audio, rc); + } else + pr_err("%s[%pK]: not sending suspend since pause failed\n", + __func__, audio); + + } else + pr_err("%s[%pK]: Driver not enabled\n", __func__, audio); + return rc; +} + +static int audio_aio_flush(struct q6audio_aio *audio) +{ + int rc = 0; + + if (audio->enabled) { + /* Implicitly issue a pause to the decoder before flushing if + * it is not in pause state + */ + if (!(audio->drv_status & ADRV_STATUS_PAUSE)) { + rc = audio_aio_pause(audio); + if (rc < 0) + pr_err("%s[%pK}: pause cmd failed rc=%d\n", + __func__, audio, + rc); + else + audio->drv_status |= ADRV_STATUS_PAUSE; + } + rc = q6asm_cmd(audio->ac, CMD_FLUSH); + if (rc < 0) + pr_err("%s[%pK]: flush cmd failed rc=%d\n", + __func__, audio, rc); + /* Not in stop state, reenable the stream */ + if (audio->stopped == 0) { + rc = audio_aio_enable(audio); + if (rc) + pr_err("%s[%pK]:audio re-enable failed\n", + __func__, audio); + else { + audio->enabled = 1; + if (audio->drv_status & ADRV_STATUS_PAUSE) + audio->drv_status &= ~ADRV_STATUS_PAUSE; + } + } + } + pr_debug("%s[%pK]:in_bytes %d\n", + __func__, audio, atomic_read(&audio->in_bytes)); + pr_debug("%s[%pK]:in_samples %d\n", + __func__, audio, atomic_read(&audio->in_samples)); + atomic_set(&audio->in_bytes, 0); + atomic_set(&audio->in_samples, 0); + return rc; +} + +static int audio_aio_outport_flush(struct q6audio_aio *audio) +{ + int rc; + + rc = q6asm_cmd(audio->ac, CMD_OUT_FLUSH); + if (rc < 0) + pr_err("%s[%pK}: output port flush cmd failed rc=%d\n", + __func__, audio, rc); + return rc; +} + +/* Write buffer to DSP / Handle Ack from DSP */ +void audio_aio_async_write_ack(struct q6audio_aio *audio, uint32_t token, + uint32_t *payload) +{ + unsigned long flags; + union msm_audio_event_payload event_payload; + struct audio_aio_buffer_node *used_buf; + + /* No active flush in progress */ + if (audio->wflush) + return; + + spin_lock_irqsave(&audio->dsp_lock, flags); + if (list_empty(&audio->out_queue)) { + pr_warn("%s: ignore unexpected event from dsp\n", __func__); + spin_unlock_irqrestore(&audio->dsp_lock, flags); + return; + } + used_buf = list_first_entry(&audio->out_queue, + struct audio_aio_buffer_node, list); + if (token == used_buf->token) { + list_del(&used_buf->list); + spin_unlock_irqrestore(&audio->dsp_lock, flags); + pr_debug("%s[%pK]:consumed buffer\n", __func__, audio); + event_payload.aio_buf = used_buf->buf; + audio_aio_post_event(audio, AUDIO_EVENT_WRITE_DONE, + event_payload); + kfree(used_buf); + if (list_empty(&audio->out_queue) && + (audio->drv_status & ADRV_STATUS_FSYNC)) { + pr_debug("%s[%pK]: list is empty, reached EOS in Tunnel\n", + __func__, audio); + wake_up(&audio->write_wait); + } + } else { + pr_err("%s[%pK]:expected=%x ret=%x\n", + __func__, audio, used_buf->token, token); + spin_unlock_irqrestore(&audio->dsp_lock, flags); + } +} + +/* ------------------- device --------------------- */ +void audio_aio_async_out_flush(struct q6audio_aio *audio) +{ + struct audio_aio_buffer_node *buf_node; + struct list_head *ptr, *next; + union msm_audio_event_payload payload; + unsigned long flags; + + pr_debug("%s[%pK}\n", __func__, audio); + /* EOS followed by flush, EOS response not guranteed, free EOS i/p + * buffer + */ + spin_lock_irqsave(&audio->dsp_lock, flags); + + if (audio->eos_flag && (audio->eos_write_payload.aio_buf.buf_addr)) { + pr_debug("%s[%pK]: EOS followed by flush received,acknowledge eos i/p buffer immediately\n", + __func__, audio); + audio_aio_post_event(audio, AUDIO_EVENT_WRITE_DONE, + audio->eos_write_payload); + memset(&audio->eos_write_payload, 0, + sizeof(union msm_audio_event_payload)); + } + spin_unlock_irqrestore(&audio->dsp_lock, flags); + list_for_each_safe(ptr, next, &audio->out_queue) { + buf_node = list_entry(ptr, struct audio_aio_buffer_node, list); + list_del(&buf_node->list); + payload.aio_buf = buf_node->buf; + audio_aio_post_event(audio, AUDIO_EVENT_WRITE_DONE, payload); + kfree(buf_node); + pr_debug("%s[%pK]: Propagate WRITE_DONE during flush\n", + __func__, audio); + } +} + +void audio_aio_async_in_flush(struct q6audio_aio *audio) +{ + struct audio_aio_buffer_node *buf_node; + struct list_head *ptr, *next; + union msm_audio_event_payload payload; + + pr_debug("%s[%pK]\n", __func__, audio); + list_for_each_safe(ptr, next, &audio->in_queue) { + buf_node = list_entry(ptr, struct audio_aio_buffer_node, list); + list_del(&buf_node->list); + /* Forcefull send o/p eos buffer after flush, if no eos response + * received by dsp even after sending eos command + */ + if ((audio->eos_rsp != 1) && audio->eos_flag) { + pr_debug("%s[%pK]: send eos on o/p buffer during flush\n", + __func__, audio); + payload.aio_buf = buf_node->buf; + payload.aio_buf.data_len = + insert_eos_buf(audio, buf_node); + audio->eos_flag = 0; + } else { + payload.aio_buf = buf_node->buf; + payload.aio_buf.data_len = + insert_meta_data_flush(audio, buf_node); + } + audio_aio_post_event(audio, AUDIO_EVENT_READ_DONE, payload); + kfree(buf_node); + pr_debug("%s[%pK]: Propagate READ_DONE during flush\n", + __func__, audio); + } +} + +int audio_aio_enable(struct q6audio_aio *audio) +{ + /* 2nd arg: 0 -> run immediately + * 3rd arg: 0 -> msw_ts, + * 4th arg: 0 ->lsw_ts + */ + return q6asm_run(audio->ac, 0x00, 0x00, 0x00); +} + +int audio_aio_disable(struct q6audio_aio *audio) +{ + int rc = 0; + + if (audio->opened) { + audio->enabled = 0; + audio->opened = 0; + pr_debug("%s[%pK]: inbytes[%d] insamples[%d]\n", __func__, + audio, atomic_read(&audio->in_bytes), + atomic_read(&audio->in_samples)); + /* Close the session */ + rc = q6asm_cmd(audio->ac, CMD_CLOSE); + if (rc < 0) + pr_err("%s[%pK]:Failed to close the session rc=%d\n", + __func__, audio, rc); + audio->stopped = 1; + wake_up(&audio->write_wait); + wake_up(&audio->cmd_wait); + } + pr_debug("%s[%pK]:enabled[%d]\n", __func__, audio, audio->enabled); + return rc; +} + +void audio_aio_reset_ion_region(struct q6audio_aio *audio) +{ + struct audio_aio_ion_region *region; + struct list_head *ptr, *next; + + list_for_each_safe(ptr, next, &audio->ion_region_queue) { + region = list_entry(ptr, struct audio_aio_ion_region, list); + list_del(®ion->list); + msm_audio_ion_free_legacy(audio->client, region->handle); + kfree(region); + } +} + +void audio_aio_reset_event_queue(struct q6audio_aio *audio) +{ + unsigned long flags; + struct audio_aio_event *drv_evt; + struct list_head *ptr, *next; + + spin_lock_irqsave(&audio->event_queue_lock, flags); + list_for_each_safe(ptr, next, &audio->event_queue) { + drv_evt = list_first_entry(&audio->event_queue, + struct audio_aio_event, list); + list_del(&drv_evt->list); + kfree(drv_evt); + } + list_for_each_safe(ptr, next, &audio->free_event_queue) { + drv_evt = list_first_entry(&audio->free_event_queue, + struct audio_aio_event, list); + list_del(&drv_evt->list); + kfree(drv_evt); + } + spin_unlock_irqrestore(&audio->event_queue_lock, flags); +} + +static void audio_aio_unmap_ion_region(struct q6audio_aio *audio) +{ + struct audio_aio_ion_region *region; + struct list_head *ptr, *next; + int rc = -EINVAL; + + pr_debug("%s[%pK]:\n", __func__, audio); + list_for_each_safe(ptr, next, &audio->ion_region_queue) { + region = list_entry(ptr, struct audio_aio_ion_region, list); + if (region != NULL) { + pr_debug("%s[%pK]: phy_address = 0x%pK\n", + __func__, audio, ®ion->paddr); + rc = q6asm_memory_unmap(audio->ac, + region->paddr, IN); + if (rc < 0) + pr_err("%s[%pK]: memory unmap failed\n", + __func__, audio); + } + } +} + +#ifdef CONFIG_USE_DEV_CTRL_VOLUME + +static void audio_aio_listner(u32 evt_id, union auddev_evt_data *evt_payload, + void *private_data) +{ + struct q6audio_aio *audio = (struct q6audio_aio *) private_data; + int rc = 0; + + switch (evt_id) { + case AUDDEV_EVT_STREAM_VOL_CHG: + audio->volume = evt_payload->session_vol; + pr_debug("%s[%pK]: AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d, enabled = %d\n", + __func__, audio, audio->volume, audio->enabled); + if (audio->enabled == 1) { + if (audio->ac) { + rc = q6asm_set_volume(audio->ac, audio->volume); + if (rc < 0) { + pr_err("%s[%pK]: Send Volume command failed rc=%d\n", + __func__, audio, rc); + } + } + } + break; + default: + pr_err("%s[%pK]:ERROR:wrong event\n", __func__, audio); + break; + } +} + +int register_volume_listener(struct q6audio_aio *audio) +{ + int rc = 0; + + audio->device_events = AUDDEV_EVT_STREAM_VOL_CHG; + audio->drv_status &= ~ADRV_STATUS_PAUSE; + + rc = auddev_register_evt_listner(audio->device_events, + AUDDEV_CLNT_DEC, + audio->ac->session, + audio_aio_listner, + (void *)audio); + if (rc < 0) { + pr_err("%s[%pK]: Event listener failed\n", __func__, audio); + rc = -EACCES; + } + return rc; +} +void unregister_volume_listener(struct q6audio_aio *audio) +{ + auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->ac->session); +} + +int enable_volume_ramp(struct q6audio_aio *audio) +{ + int rc = 0; + struct asm_softpause_params softpause; + struct asm_softvolume_params softvol; + + if (audio->ac == NULL) + return -EINVAL; + pr_debug("%s[%pK]\n", __func__, audio); + softpause.enable = SOFT_PAUSE_ENABLE; + softpause.period = SOFT_PAUSE_PERIOD; + softpause.step = SOFT_PAUSE_STEP; + softpause.rampingcurve = SOFT_PAUSE_CURVE_LINEAR; + + softvol.period = SOFT_VOLUME_PERIOD; + softvol.step = SOFT_VOLUME_STEP; + softvol.rampingcurve = SOFT_VOLUME_CURVE_LINEAR; + + if (softpause.rampingcurve == SOFT_PAUSE_CURVE_LINEAR) + softpause.step = SOFT_PAUSE_STEP_LINEAR; + if (softvol.rampingcurve == SOFT_VOLUME_CURVE_LINEAR) + softvol.step = SOFT_VOLUME_STEP_LINEAR; + rc = q6asm_set_volume(audio->ac, audio->volume); + if (rc < 0) { + pr_err("%s: Send Volume command failed rc=%d\n", + __func__, rc); + return rc; + } + rc = q6asm_set_softpause(audio->ac, &softpause); + if (rc < 0) { + pr_err("%s: Send SoftPause Param failed rc=%d\n", + __func__, rc); + return rc; + } + rc = q6asm_set_softvolume(audio->ac, &softvol); + if (rc < 0) { + pr_err("%s: Send SoftVolume Param failed rc=%d\n", + __func__, rc); + return rc; + } + /* disable mute by default */ + rc = q6asm_set_mute(audio->ac, 0); + if (rc < 0) { + pr_err("%s: Send mute command failed rc=%d\n", + __func__, rc); + return rc; + } + return rc; +} + +#else /*CONFIG_USE_DEV_CTRL_VOLUME*/ +int register_volume_listener(struct q6audio_aio *audio) +{ + return 0;/* do nothing */ +} +void unregister_volume_listener(struct q6audio_aio *audio) +{ + return;/* do nothing */ +} +int enable_volume_ramp(struct q6audio_aio *audio) +{ + return 0; /* do nothing */ +} +#endif /*CONFIG_USE_DEV_CTRL_VOLUME*/ + +int audio_aio_release(struct inode *inode, struct file *file) +{ + struct q6audio_aio *audio = file->private_data; + + pr_debug("%s[%pK]\n", __func__, audio); + mutex_lock(&audio->lock); + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); + audio->wflush = 1; + if (audio->wakelock_voted && + (audio->audio_ws_mgr != NULL) && + (audio->miscdevice != NULL)) { + audio->wakelock_voted = false; + mutex_lock(&audio->audio_ws_mgr->ws_lock); + if ((audio->audio_ws_mgr->ref_cnt > 0) && + (--audio->audio_ws_mgr->ref_cnt == 0)) { + pm_relax(audio->miscdevice->this_device); + } + mutex_unlock(&audio->audio_ws_mgr->ws_lock); + } + if (audio->enabled) + audio_aio_flush(audio); + audio->wflush = 0; + audio->drv_ops.out_flush(audio); + audio->drv_ops.in_flush(audio); + audio_aio_disable(audio); + audio_aio_unmap_ion_region(audio); + audio_aio_reset_ion_region(audio); + msm_audio_ion_client_destroy(audio->client); + audio->event_abort = 1; + wake_up(&audio->event_wait); + audio_aio_reset_event_queue(audio); + q6asm_audio_client_free(audio->ac); + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); + mutex_unlock(&audio->lock); + mutex_destroy(&audio->lock); + mutex_destroy(&audio->read_lock); + mutex_destroy(&audio->write_lock); + mutex_destroy(&audio->get_event_lock); + unregister_volume_listener(audio); + +#ifdef CONFIG_DEBUG_FS + debugfs_remove(audio->dentry); +#endif + kfree(audio->codec_cfg); + kfree(audio); + return 0; +} + +int audio_aio_fsync(struct file *file, loff_t start, loff_t end, int datasync) +{ + int rc = 0; + struct q6audio_aio *audio = file->private_data; + + if (!audio->enabled || audio->feedback) + return -EINVAL; + + /* Blocking client sends more data */ + mutex_lock(&audio->lock); + audio->drv_status |= ADRV_STATUS_FSYNC; + mutex_unlock(&audio->lock); + + pr_debug("%s[%pK]:\n", __func__, audio); + + audio->eos_rsp = 0; + + pr_debug("%s[%pK]Wait for write done from DSP\n", __func__, audio); + rc = wait_event_interruptible(audio->write_wait, + (list_empty(&audio->out_queue)) || + audio->wflush || audio->stopped); + + if (audio->stopped || audio->wflush) { + pr_debug("%s[%pK]: Audio Flushed or Stopped,this is not EOS\n" + , __func__, audio); + audio->wflush = 0; + rc = -EBUSY; + } + + if (rc < 0) { + pr_err("%s[%pK]: wait event for list_empty failed, rc = %d\n", + __func__, audio, rc); + goto done; + } + + rc = q6asm_cmd(audio->ac, CMD_EOS); + pr_debug("%s[%pK]: EOS cmd sent to DSP\n", __func__, audio); + + if (rc < 0) + pr_err("%s[%pK]: q6asm_cmd failed, rc = %d", + __func__, audio, rc); + + pr_debug("%s[%pK]: wait for RENDERED_EOS from DSP\n" + , __func__, audio); + rc = wait_event_interruptible(audio->write_wait, + (audio->eos_rsp || audio->wflush || + audio->stopped)); + + if (rc < 0) { + pr_err("%s[%pK]: wait event for eos_rsp failed, rc = %d\n", + __func__, audio, rc); + goto done; + } + + if (audio->stopped || audio->wflush) { + audio->wflush = 0; + pr_debug("%s[%pK]: Audio Flushed or Stopped,this is not EOS\n" + , __func__, audio); + rc = -EBUSY; + } + + if (audio->eos_rsp == 1) + pr_debug("%s[%pK]: EOS\n", __func__, audio); + + +done: + mutex_lock(&audio->lock); + audio->drv_status &= ~ADRV_STATUS_FSYNC; + mutex_unlock(&audio->lock); + + return rc; +} + +static int audio_aio_events_pending(struct q6audio_aio *audio) +{ + unsigned long flags; + int empty; + + spin_lock_irqsave(&audio->event_queue_lock, flags); + empty = !list_empty(&audio->event_queue); + spin_unlock_irqrestore(&audio->event_queue_lock, flags); + return empty || audio->event_abort || audio->reset_event; +} + +static long audio_aio_process_event_req_common(struct q6audio_aio *audio, + struct msm_audio_event *usr_evt) +{ + long rc; + struct audio_aio_event *drv_evt = NULL; + int timeout; + unsigned long flags; + + timeout = usr_evt->timeout_ms; + + if (timeout > 0) { + rc = wait_event_interruptible_timeout(audio->event_wait, + audio_aio_events_pending + (audio), + msecs_to_jiffies + (timeout)); + if (rc == 0) + return -ETIMEDOUT; + } else { + rc = wait_event_interruptible(audio->event_wait, + audio_aio_events_pending(audio)); + } + if (rc < 0) + return rc; + + if (audio->reset_event) { + audio->reset_event = false; + pr_err("In SSR, post ENETRESET err\n"); + return -ENETRESET; + } + + if (audio->event_abort) { + audio->event_abort = 0; + return -ENODEV; + } + + rc = 0; + + spin_lock_irqsave(&audio->event_queue_lock, flags); + if (!list_empty(&audio->event_queue)) { + drv_evt = list_first_entry(&audio->event_queue, + struct audio_aio_event, list); + list_del(&drv_evt->list); + } + if (drv_evt) { + usr_evt->event_type = drv_evt->event_type; + usr_evt->event_payload = drv_evt->payload; + list_add_tail(&drv_evt->list, &audio->free_event_queue); + } else { + pr_err("%s[%pK]:Unexpected path\n", __func__, audio); + spin_unlock_irqrestore(&audio->event_queue_lock, flags); + return -EPERM; + } + spin_unlock_irqrestore(&audio->event_queue_lock, flags); + + if (drv_evt->event_type == AUDIO_EVENT_WRITE_DONE) { + pr_debug("%s[%pK]:posted AUDIO_EVENT_WRITE_DONE to user\n", + __func__, audio); + mutex_lock(&audio->write_lock); + audio_aio_ion_fixup(audio, drv_evt->payload.aio_buf.buf_addr, + drv_evt->payload.aio_buf.buf_len, 0, 0); + mutex_unlock(&audio->write_lock); + } else if (drv_evt->event_type == AUDIO_EVENT_READ_DONE) { + pr_debug("%s[%pK]:posted AUDIO_EVENT_READ_DONE to user\n", + __func__, audio); + mutex_lock(&audio->read_lock); + audio_aio_ion_fixup(audio, drv_evt->payload.aio_buf.buf_addr, + drv_evt->payload.aio_buf.buf_len, 0, 0); + mutex_unlock(&audio->read_lock); + } + + /* Some read buffer might be held up in DSP,release all + * Once EOS indicated + */ + if (audio->eos_rsp && !list_empty(&audio->in_queue)) { + pr_debug("%s[%pK]:Send flush command to release read buffers held up in DSP\n", + __func__, audio); + mutex_lock(&audio->lock); + audio_aio_flush(audio); + mutex_unlock(&audio->lock); + } + + return rc; +} + +static long audio_aio_process_event_req(struct q6audio_aio *audio, + void __user *arg) +{ + long rc; + struct msm_audio_event usr_evt; + + if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event))) { + pr_err("%s: copy_from_user failed\n", __func__); + return -EFAULT; + } + + rc = audio_aio_process_event_req_common(audio, &usr_evt); + + if (copy_to_user(arg, &usr_evt, sizeof(usr_evt))) { + pr_err("%s: copy_to_user failed\n", __func__); + rc = -EFAULT; + } + return rc; +} + +#ifdef CONFIG_COMPAT + +struct msm_audio_aio_buf32 { + compat_uptr_t buf_addr; + u32 buf_len; + u32 data_len; + compat_uptr_t private_data; + u16 mfield_sz; /*only useful for data has meta field */ +}; + +struct msm_audio_bitstream_info32 { + u32 codec_type; + u32 chan_info; + u32 sample_rate; + u32 bit_stream_info; + u32 bit_rate; + u32 unused[3]; +}; + +struct msm_audio_bitstream_error_info32 { + u32 dec_id; + u32 err_msg_indicator; + u32 err_type; +}; + +union msm_audio_event_payload32 { + struct msm_audio_aio_buf32 aio_buf; + struct msm_audio_bitstream_info32 stream_info; + struct msm_audio_bitstream_error_info32 error_info; + s32 reserved; +}; + +struct msm_audio_event32 { + s32 event_type; + s32 timeout_ms; + union msm_audio_event_payload32 event_payload; +}; + +static long audio_aio_process_event_req_compat(struct q6audio_aio *audio, + void __user *arg) +{ + long rc; + struct msm_audio_event32 usr_evt_32; + struct msm_audio_event usr_evt; + memset(&usr_evt, 0, sizeof(struct msm_audio_event)); + + if (copy_from_user(&usr_evt_32, arg, + sizeof(struct msm_audio_event32))) { + pr_err("%s: copy_from_user failed\n", __func__); + return -EFAULT; + } + usr_evt.timeout_ms = usr_evt_32.timeout_ms; + + rc = audio_aio_process_event_req_common(audio, &usr_evt); + if (rc < 0) { + pr_err("%s: audio process event failed, rc = %ld", + __func__, rc); + return rc; + } + + usr_evt_32.event_type = usr_evt.event_type; + switch (usr_evt_32.event_type) { + case AUDIO_EVENT_SUSPEND: + case AUDIO_EVENT_RESUME: + case AUDIO_EVENT_WRITE_DONE: + case AUDIO_EVENT_READ_DONE: + usr_evt_32.event_payload.aio_buf.buf_addr = + ptr_to_compat(usr_evt.event_payload.aio_buf.buf_addr); + usr_evt_32.event_payload.aio_buf.buf_len = + usr_evt.event_payload.aio_buf.buf_len; + usr_evt_32.event_payload.aio_buf.data_len = + usr_evt.event_payload.aio_buf.data_len; + usr_evt_32.event_payload.aio_buf.private_data = + ptr_to_compat(usr_evt.event_payload.aio_buf.private_data); + usr_evt_32.event_payload.aio_buf.mfield_sz = + usr_evt.event_payload.aio_buf.mfield_sz; + break; + case AUDIO_EVENT_STREAM_INFO: + usr_evt_32.event_payload.stream_info.codec_type = + usr_evt.event_payload.stream_info.codec_type; + usr_evt_32.event_payload.stream_info.chan_info = + usr_evt.event_payload.stream_info.chan_info; + usr_evt_32.event_payload.stream_info.sample_rate = + usr_evt.event_payload.stream_info.sample_rate; + usr_evt_32.event_payload.stream_info.bit_stream_info = + usr_evt.event_payload.stream_info.bit_stream_info; + usr_evt_32.event_payload.stream_info.bit_rate = + usr_evt.event_payload.stream_info.bit_rate; + break; + case AUDIO_EVENT_BITSTREAM_ERROR_INFO: + usr_evt_32.event_payload.error_info.dec_id = + usr_evt.event_payload.error_info.dec_id; + usr_evt_32.event_payload.error_info.err_msg_indicator = + usr_evt.event_payload.error_info.err_msg_indicator; + usr_evt_32.event_payload.error_info.err_type = + usr_evt.event_payload.error_info.err_type; + break; + default: + pr_debug("%s: unknown audio event type = %d rc = %ld", + __func__, usr_evt_32.event_type, rc); + return rc; + } + if (copy_to_user(arg, &usr_evt_32, sizeof(usr_evt_32))) { + pr_err("%s: copy_to_user failed\n", __func__); + rc = -EFAULT; + } + return rc; +} +#endif + +static int audio_aio_ion_check(struct q6audio_aio *audio, + void *vaddr, unsigned long len) +{ + struct audio_aio_ion_region *region_elt; + struct audio_aio_ion_region t = {.vaddr = vaddr, .len = len }; + + list_for_each_entry(region_elt, &audio->ion_region_queue, list) { + if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) || + OVERLAPS(region_elt, &t)) { + pr_err("%s[%pK]:region (vaddr %pK len %ld) clashes with registered region (vaddr %pK paddr %pK len %ld)\n", + __func__, audio, vaddr, len, + region_elt->vaddr, + ®ion_elt->paddr, region_elt->len); + return -EINVAL; + } + } + + return 0; +} + +static int audio_aio_ion_add(struct q6audio_aio *audio, + struct msm_audio_ion_info *info) +{ + ion_phys_addr_t paddr = 0; + size_t len = 0; + struct audio_aio_ion_region *region; + int rc = -EINVAL; + struct ion_handle *handle = NULL; + unsigned long ionflag; + void *kvaddr = NULL; + + pr_debug("%s[%pK]:\n", __func__, audio); + region = kmalloc(sizeof(*region), GFP_KERNEL); + + if (!region) { + rc = -ENOMEM; + goto end; + } + + rc = msm_audio_ion_import_legacy("Audio_Dec_Client", audio->client, + &handle, info->fd, &ionflag, + 0, &paddr, &len, &kvaddr); + if (rc) { + pr_err("%s: msm audio ion alloc failed\n", __func__); + goto import_error; + } + + rc = audio_aio_ion_check(audio, info->vaddr, len); + if (rc < 0) { + pr_err("%s: audio_aio_ion_check failed\n", __func__); + goto ion_error; + } + + region->handle = handle; + region->vaddr = info->vaddr; + region->fd = info->fd; + region->paddr = paddr; + region->kvaddr = kvaddr; + region->len = len; + region->ref_cnt = 0; + pr_debug("%s[%pK]:add region paddr %pK vaddr %pK, len %lu kvaddr %pK\n", + __func__, audio, + ®ion->paddr, region->vaddr, region->len, + region->kvaddr); + list_add_tail(®ion->list, &audio->ion_region_queue); + rc = q6asm_memory_map(audio->ac, paddr, IN, len, 1); + if (rc < 0) { + pr_err("%s[%pK]: memory map failed\n", __func__, audio); + goto mmap_error; + } else { + goto end; + } +mmap_error: + list_del(®ion->list); +ion_error: + msm_audio_ion_free_legacy(audio->client, handle); +import_error: + kfree(region); +end: + return rc; +} + +static int audio_aio_ion_remove(struct q6audio_aio *audio, + struct msm_audio_ion_info *info) +{ + struct audio_aio_ion_region *region; + struct list_head *ptr, *next; + int rc = -EINVAL; + + pr_debug("%s[%pK]:info fd %d vaddr %pK\n", + __func__, audio, info->fd, info->vaddr); + + list_for_each_safe(ptr, next, &audio->ion_region_queue) { + region = list_entry(ptr, struct audio_aio_ion_region, list); + + if ((region->fd == info->fd) && + (region->vaddr == info->vaddr)) { + if (region->ref_cnt) { + pr_debug("%s[%pK]:region %pK in use ref_cnt %d\n", + __func__, audio, region, + region->ref_cnt); + break; + } + pr_debug("%s[%pK]:remove region fd %d vaddr %pK\n", + __func__, audio, info->fd, info->vaddr); + rc = q6asm_memory_unmap(audio->ac, + region->paddr, IN); + if (rc < 0) + pr_err("%s[%pK]: memory unmap failed\n", + __func__, audio); + + list_del(®ion->list); + msm_audio_ion_free_legacy(audio->client, + region->handle); + kfree(region); + rc = 0; + break; + } + } + + return rc; +} + +static int audio_aio_async_write(struct q6audio_aio *audio, + struct audio_aio_buffer_node *buf_node) +{ + int rc; + struct audio_client *ac; + struct audio_aio_write_param param; + + if (!audio || !buf_node) { + pr_err("%s NULL pointer audio=[0x%pK], buf_node=[0x%pK]\n", + __func__, audio, buf_node); + return -EINVAL; + } + pr_debug("%s[%pK]: Send write buff %pK phy %pK len %d meta_enable = %d\n", + __func__, audio, buf_node, &buf_node->paddr, + buf_node->buf.data_len, + audio->buf_cfg.meta_info_enable); + pr_debug("%s[%pK]: flags = 0x%x\n", __func__, audio, + buf_node->meta_info.meta_in.nflags); + + ac = audio->ac; + /* Offset with appropriate meta */ + if (audio->feedback) { + /* Non Tunnel mode */ + param.paddr = buf_node->paddr + sizeof(struct dec_meta_in); + param.len = buf_node->buf.data_len - sizeof(struct dec_meta_in); + } else { + /* Tunnel mode */ + param.paddr = buf_node->paddr; + param.len = buf_node->buf.data_len; + } + param.msw_ts = buf_node->meta_info.meta_in.ntimestamp.highpart; + param.lsw_ts = buf_node->meta_info.meta_in.ntimestamp.lowpart; + param.flags = buf_node->meta_info.meta_in.nflags; + /* If no meta_info enaled, indicate no time stamp valid */ + if (!audio->buf_cfg.meta_info_enable) + param.flags = 0xFF00; + + if (buf_node->meta_info.meta_in.nflags & AUDIO_DEC_EOF_SET) + param.flags |= AUDIO_DEC_EOF_SET; + + param.uid = ac->session; + /* Read command will populate session id as token */ + buf_node->token = ac->session; + rc = q6asm_async_write(ac, ¶m); + if (rc < 0) + pr_err("%s[%pK]:failed\n", __func__, audio); + return rc; +} + +void audio_aio_post_event(struct q6audio_aio *audio, int type, + union msm_audio_event_payload payload) +{ + struct audio_aio_event *e_node = NULL; + unsigned long flags; + + spin_lock_irqsave(&audio->event_queue_lock, flags); + + if (!list_empty(&audio->free_event_queue)) { + e_node = list_first_entry(&audio->free_event_queue, + struct audio_aio_event, list); + list_del(&e_node->list); + } else { + e_node = kmalloc(sizeof(struct audio_aio_event), GFP_ATOMIC); + if (!e_node) { + spin_unlock_irqrestore(&audio->event_queue_lock, flags); + return; + } + } + + e_node->event_type = type; + e_node->payload = payload; + + list_add_tail(&e_node->list, &audio->event_queue); + spin_unlock_irqrestore(&audio->event_queue_lock, flags); + wake_up(&audio->event_wait); +} + +static int audio_aio_async_read(struct q6audio_aio *audio, + struct audio_aio_buffer_node *buf_node) +{ + struct audio_client *ac; + struct audio_aio_read_param param; + int rc; + + pr_debug("%s[%pK]: Send read buff %pK phy %pK len %d\n", + __func__, audio, buf_node, + &buf_node->paddr, buf_node->buf.buf_len); + ac = audio->ac; + /* Provide address so driver can append nr frames information */ + param.paddr = buf_node->paddr + + sizeof(struct dec_meta_out); + param.len = buf_node->buf.buf_len - + sizeof(struct dec_meta_out); + param.uid = ac->session; + /* Write command will populate session_id as token */ + buf_node->token = ac->session; + rc = q6asm_async_read(ac, ¶m); + if (rc < 0) + pr_err("%s[%pK]:failed\n", __func__, audio); + return rc; +} + +static int audio_aio_buf_add_shared(struct q6audio_aio *audio, u32 dir, + struct audio_aio_buffer_node *buf_node) +{ + unsigned long flags; + int ret = 0; + + pr_debug("%s[%pK]:node %pK dir %x buf_addr %pK buf_len %d data_len %d\n", + __func__, audio, buf_node, dir, buf_node->buf.buf_addr, + buf_node->buf.buf_len, buf_node->buf.data_len); + buf_node->paddr = audio_aio_ion_fixup(audio, buf_node->buf.buf_addr, + buf_node->buf.buf_len, 1, + &buf_node->kvaddr); + if (dir) { + /* write */ + if (!buf_node->paddr || + (buf_node->paddr & 0x1) || + (!audio->feedback && !buf_node->buf.data_len)) { + kfree(buf_node); + return -EINVAL; + } + extract_meta_out_info(audio, buf_node, 1); + /* Not a EOS buffer */ + if (!(buf_node->meta_info.meta_in.nflags & AUDIO_DEC_EOS_SET)) { + spin_lock_irqsave(&audio->dsp_lock, flags); + ret = audio_aio_async_write(audio, buf_node); + /* EOS buffer handled in driver */ + list_add_tail(&buf_node->list, &audio->out_queue); + spin_unlock_irqrestore(&audio->dsp_lock, flags); + } else if (buf_node->meta_info.meta_in.nflags + & AUDIO_DEC_EOS_SET) { + if (!audio->wflush) { + pr_debug("%s[%pK]:Send EOS cmd at i/p\n", + __func__, audio); + /* Driver will forcefully post writedone event + * once eos ack recived from DSP + */ + audio->eos_write_payload.aio_buf = + buf_node->buf; + audio->eos_flag = 1; + audio->eos_rsp = 0; + q6asm_cmd(audio->ac, CMD_EOS); + kfree(buf_node); + } else { /* Flush in progress, send back i/p + * EOS buffer as is + */ + union msm_audio_event_payload event_payload; + + event_payload.aio_buf = buf_node->buf; + audio_aio_post_event(audio, + AUDIO_EVENT_WRITE_DONE, + event_payload); + kfree(buf_node); + } + } + } else { + /* read */ + if (!buf_node->paddr || + (buf_node->paddr & 0x1) || + (buf_node->buf.buf_len < PCM_BUFSZ_MIN)) { + kfree(buf_node); + return -EINVAL; + } + /* No EOS reached */ + if (!audio->eos_rsp) { + spin_lock_irqsave(&audio->dsp_lock, flags); + ret = audio_aio_async_read(audio, buf_node); + /* EOS buffer handled in driver */ + list_add_tail(&buf_node->list, &audio->in_queue); + spin_unlock_irqrestore(&audio->dsp_lock, flags); + } + /* EOS reached at input side fake all upcoming read buffer to + * indicate the same + */ + else { + union msm_audio_event_payload event_payload; + + event_payload.aio_buf = buf_node->buf; + event_payload.aio_buf.data_len = + insert_eos_buf(audio, buf_node); + pr_debug("%s[%pK]: propagate READ_DONE as EOS done\n", + __func__, audio); + audio_aio_post_event(audio, AUDIO_EVENT_READ_DONE, + event_payload); + kfree(buf_node); + } + } + return ret; +} +#ifdef CONFIG_COMPAT +static int audio_aio_buf_add_compat(struct q6audio_aio *audio, u32 dir, + void __user *arg) +{ + struct audio_aio_buffer_node *buf_node; + struct msm_audio_aio_buf32 aio_buf_32; + + buf_node = kzalloc(sizeof(*buf_node), GFP_KERNEL); + + if (!buf_node) + return -ENOMEM; + + if (copy_from_user(&aio_buf_32, arg, sizeof(aio_buf_32))) { + kfree(buf_node); + pr_err("%s: copy_from_user failed\n", __func__); + return -EFAULT; + } + + buf_node->buf.buf_addr = compat_ptr(aio_buf_32.buf_addr); + buf_node->buf.buf_len = aio_buf_32.buf_len; + buf_node->buf.data_len = aio_buf_32.data_len; + buf_node->buf.private_data = compat_ptr(aio_buf_32.private_data); + buf_node->buf.mfield_sz = aio_buf_32.mfield_sz; + + return audio_aio_buf_add_shared(audio, dir, buf_node); +} +#endif + +static int audio_aio_buf_add(struct q6audio_aio *audio, u32 dir, + void __user *arg) +{ + struct audio_aio_buffer_node *buf_node; + + buf_node = kzalloc(sizeof(*buf_node), GFP_KERNEL); + + if (!buf_node) + return -ENOMEM; + + if (copy_from_user(&buf_node->buf, arg, sizeof(buf_node->buf))) { + kfree(buf_node); + pr_err("%s: copy_from_user failed\n", __func__); + return -EFAULT; + } + + return audio_aio_buf_add_shared(audio, dir, buf_node); +} + +void audio_aio_ioport_reset(struct q6audio_aio *audio) +{ + if (audio->drv_status & ADRV_STATUS_AIO_INTF) { + /* If fsync is in progress, make sure + * return value of fsync indicates + * abort due to flush + */ + if (audio->drv_status & ADRV_STATUS_FSYNC) { + pr_debug("%s[%pK]:fsync in progress\n", + __func__, audio); + audio->drv_ops.out_flush(audio); + } else + audio->drv_ops.out_flush(audio); + if (audio->feedback == NON_TUNNEL_MODE) + audio->drv_ops.in_flush(audio); + } +} + +int audio_aio_open(struct q6audio_aio *audio, struct file *file) +{ + int rc = 0; + int i; + struct audio_aio_event *e_node = NULL; + struct list_head *ptr, *next; + + /* Settings will be re-config at AUDIO_SET_CONFIG, + * but at least we need to have initial config + */ + audio->str_cfg.buffer_size = FRAME_SIZE; + audio->str_cfg.buffer_count = FRAME_NUM; + audio->pcm_cfg.buffer_count = PCM_BUF_COUNT; + audio->pcm_cfg.sample_rate = 48000; + audio->pcm_cfg.channel_count = 2; + + /* Only AIO interface */ + if (file->f_flags & O_NONBLOCK) { + pr_debug("%s[%pK]:set to aio interface\n", __func__, audio); + audio->drv_status |= ADRV_STATUS_AIO_INTF; + audio->drv_ops.out_flush = audio_aio_async_out_flush; + audio->drv_ops.in_flush = audio_aio_async_in_flush; + q6asm_set_io_mode(audio->ac, ASYNC_IO_MODE); + } else { + pr_err("%s[%pK]:SIO interface not supported\n", + __func__, audio); + rc = -EACCES; + goto fail; + } + + /* Initialize all locks of audio instance */ + mutex_init(&audio->lock); + mutex_init(&audio->read_lock); + mutex_init(&audio->write_lock); + mutex_init(&audio->get_event_lock); + spin_lock_init(&audio->dsp_lock); + spin_lock_init(&audio->event_queue_lock); + init_waitqueue_head(&audio->cmd_wait); + init_waitqueue_head(&audio->write_wait); + init_waitqueue_head(&audio->event_wait); + INIT_LIST_HEAD(&audio->out_queue); + INIT_LIST_HEAD(&audio->in_queue); + INIT_LIST_HEAD(&audio->ion_region_queue); + INIT_LIST_HEAD(&audio->free_event_queue); + INIT_LIST_HEAD(&audio->event_queue); + + audio->drv_ops.out_flush(audio); + audio->opened = 1; + audio->reset_event = false; + file->private_data = audio; + audio->codec_ioctl = audio_aio_ioctl; + audio->codec_compat_ioctl = audio_aio_compat_ioctl; + for (i = 0; i < AUDIO_EVENT_NUM; i++) { + e_node = kmalloc(sizeof(struct audio_aio_event), GFP_KERNEL); + if (e_node) + list_add_tail(&e_node->list, &audio->free_event_queue); + else { + rc = -ENOMEM; + goto cleanup; + } + } + audio->client = msm_audio_ion_client_create("Audio_Dec_Client"); + if (IS_ERR_OR_NULL(audio->client)) { + pr_err("Unable to create ION client\n"); + rc = -ENOMEM; + goto cleanup; + } + pr_debug("Ion client create in audio_aio_open %pK", audio->client); + + rc = register_volume_listener(audio); + if (rc < 0) + goto ion_cleanup; + + return 0; +ion_cleanup: + msm_audio_ion_client_destroy(audio->client); + audio->client = NULL; +cleanup: + list_for_each_safe(ptr, next, &audio->free_event_queue) { + e_node = list_first_entry(&audio->free_event_queue, + struct audio_aio_event, list); + list_del(&e_node->list); + kfree(e_node); + } +fail: + return rc; +} + +static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_ABORT_GET_EVENT: { + audio->event_abort = 1; + wake_up(&audio->event_wait); + break; + } + case AUDIO_OUTPORT_FLUSH: { + pr_debug("%s[%pK]:AUDIO_OUTPORT_FLUSH\n", __func__, audio); + mutex_lock(&audio->read_lock); + rc = audio_aio_outport_flush(audio); + if (rc < 0) { + pr_err("%s[%pK]: AUDIO_OUTPORT_FLUSH failed\n", + __func__, audio); + rc = -EINTR; + } + mutex_unlock(&audio->read_lock); + break; + } + case AUDIO_STOP: { + pr_debug("%s[%pK]: AUDIO_STOP session_id[%d]\n", __func__, + audio, audio->ac->session); + mutex_lock(&audio->lock); + audio->stopped = 1; + rc = audio_aio_flush(audio); + if (rc < 0) { + pr_err("%s[%pK]:Audio Stop procedure failed rc=%d\n", + __func__, audio, rc); + mutex_unlock(&audio->lock); + break; + } + audio->enabled = 0; + audio->drv_status &= ~ADRV_STATUS_PAUSE; + if (audio->drv_status & ADRV_STATUS_FSYNC) { + pr_debug("%s[%pK] Waking up the audio_aio_fsync\n", + __func__, audio); + wake_up(&audio->write_wait); + } + mutex_unlock(&audio->lock); + break; + } + case AUDIO_PAUSE: { + pr_debug("%s[%pK]:AUDIO_PAUSE %ld\n", __func__, audio, arg); + mutex_lock(&audio->lock); + if (arg == 1) { + rc = audio_aio_pause(audio); + if (rc < 0) { + pr_err("%s[%pK]: pause FAILED rc=%d\n", + __func__, audio, rc); + mutex_unlock(&audio->lock); + break; + } + audio->drv_status |= ADRV_STATUS_PAUSE; + } else if (arg == 0) { + if (audio->drv_status & ADRV_STATUS_PAUSE) { + rc = audio_aio_enable(audio); + if (rc) + pr_err("%s[%pK]: audio enable failed\n", + __func__, audio); + else { + audio->drv_status &= ~ADRV_STATUS_PAUSE; + audio->enabled = 1; + } + } + } + mutex_unlock(&audio->lock); + break; + } + case AUDIO_FLUSH: { + pr_debug("%s[%pK]: AUDIO_FLUSH sessionid[%d]\n", __func__, + audio, audio->ac->session); + mutex_lock(&audio->lock); + audio->rflush = 1; + audio->wflush = 1; + if (audio->drv_status & ADRV_STATUS_FSYNC) { + pr_debug("%s[%pK] Waking up the audio_aio_fsync\n", + __func__, audio); + wake_up(&audio->write_wait); + } + /* Flush DSP */ + rc = audio_aio_flush(audio); + /* Flush input / Output buffer in software*/ + audio_aio_ioport_reset(audio); + if (rc < 0) { + pr_err("%s[%pK]:AUDIO_FLUSH interrupted\n", + __func__, audio); + rc = -EINTR; + } else { + audio->rflush = 0; + if (audio->drv_status & ADRV_STATUS_FSYNC) + wake_up(&audio->write_wait); + else + audio->wflush = 0; + + } + audio->eos_flag = 0; + audio->eos_rsp = 0; + mutex_unlock(&audio->lock); + break; + } + case AUDIO_GET_SESSION_ID: { + mutex_lock(&audio->lock); + if (copy_to_user((void *)arg, &audio->ac->session, + sizeof(u16))) { + pr_err("%s: copy_to_user for AUDIO_GET_SESSION_ID failed\n", + __func__); + rc = -EFAULT; + } + mutex_unlock(&audio->lock); + break; + } + case AUDIO_PM_AWAKE: { + if ((audio->audio_ws_mgr == NULL) || + (audio->miscdevice == NULL)) { + pr_err("%s[%pK]: invalid ws_mgr or miscdevice", + __func__, audio); + rc = -EACCES; + break; + } + pr_debug("%s[%pK]:AUDIO_PM_AWAKE\n", __func__, audio); + mutex_lock(&audio->lock); + if (!audio->wakelock_voted) { + audio->wakelock_voted = true; + mutex_lock(&audio->audio_ws_mgr->ws_lock); + if (audio->audio_ws_mgr->ref_cnt++ == 0) + pm_stay_awake(audio->miscdevice->this_device); + mutex_unlock(&audio->audio_ws_mgr->ws_lock); + } + mutex_unlock(&audio->lock); + break; + } + case AUDIO_PM_RELAX: { + if ((audio->audio_ws_mgr == NULL) || + (audio->miscdevice == NULL)) { + pr_err("%s[%pK]: invalid ws_mgr or miscdevice", + __func__, audio); + rc = -EACCES; + break; + } + pr_debug("%s[%pK]:AUDIO_PM_RELAX\n", __func__, audio); + mutex_lock(&audio->lock); + if (audio->wakelock_voted) { + audio->wakelock_voted = false; + mutex_lock(&audio->audio_ws_mgr->ws_lock); + if ((audio->audio_ws_mgr->ref_cnt > 0) && + (--audio->audio_ws_mgr->ref_cnt == 0)) { + pm_relax(audio->miscdevice->this_device); + } + mutex_unlock(&audio->audio_ws_mgr->ws_lock); + } + mutex_unlock(&audio->lock); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + } + return rc; + + +} + +static long audio_aio_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_ABORT_GET_EVENT: + case AUDIO_OUTPORT_FLUSH: + case AUDIO_STOP: + case AUDIO_PAUSE: + case AUDIO_FLUSH: + case AUDIO_GET_SESSION_ID: + case AUDIO_PM_AWAKE: + case AUDIO_PM_RELAX: + rc = audio_aio_shared_ioctl(file, cmd, arg); + break; + case AUDIO_GET_STATS: { + struct msm_audio_stats stats; + uint64_t timestamp; + + memset(&stats, 0, sizeof(struct msm_audio_stats)); + stats.byte_count = atomic_read(&audio->in_bytes); + stats.sample_count = atomic_read(&audio->in_samples); + rc = q6asm_get_session_time(audio->ac, ×tamp); + if (rc >= 0) + memcpy(&stats.unused[0], ×tamp, sizeof(timestamp)); + else + pr_debug("Error while getting timestamp\n"); + if (copy_to_user((void *)arg, &stats, sizeof(stats))) { + pr_err("%s: copy_frm_user for AUDIO_GET_STATS failed\n", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_GET_EVENT: { + pr_debug("%s[%pK]:AUDIO_GET_EVENT\n", __func__, audio); + if (mutex_trylock(&audio->get_event_lock)) { + rc = audio_aio_process_event_req(audio, + (void __user *)arg); + mutex_unlock(&audio->get_event_lock); + } else + rc = -EBUSY; + break; + } + case AUDIO_ASYNC_WRITE: { + mutex_lock(&audio->write_lock); + if (audio->drv_status & ADRV_STATUS_FSYNC) + rc = -EBUSY; + else { + if (audio->enabled) + rc = audio_aio_buf_add(audio, 1, + (void __user *)arg); + else + rc = -EPERM; + } + mutex_unlock(&audio->write_lock); + break; + } + case AUDIO_ASYNC_READ: { + mutex_lock(&audio->read_lock); + if (audio->feedback) + rc = audio_aio_buf_add(audio, 0, + (void __user *)arg); + else + rc = -EPERM; + mutex_unlock(&audio->read_lock); + break; + } + + case AUDIO_GET_STREAM_CONFIG: { + struct msm_audio_stream_config cfg; + + mutex_lock(&audio->lock); + memset(&cfg, 0, sizeof(cfg)); + cfg.buffer_size = audio->str_cfg.buffer_size; + cfg.buffer_count = audio->str_cfg.buffer_count; + pr_debug("%s[%pK]:GET STREAM CFG %d %d\n", + __func__, audio, cfg.buffer_size, cfg.buffer_count); + if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) { + pr_err( + "%s: copy_to_user for AUDIO_GET_STREAM_CONFIG failed\n", + __func__); + rc = -EFAULT; + } + mutex_unlock(&audio->lock); + break; + } + case AUDIO_SET_STREAM_CONFIG: { + struct msm_audio_stream_config cfg; + + pr_debug("%s[%pK]:SET STREAM CONFIG\n", __func__, audio); + mutex_lock(&audio->lock); + if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) { + pr_err( + "%s: copy_from_user for AUDIO_SET_STREAM_CONFIG failed\n", + __func__); + rc = -EFAULT; + mutex_unlock(&audio->lock); + break; + } + audio->str_cfg.buffer_size = FRAME_SIZE; + audio->str_cfg.buffer_count = FRAME_NUM; + rc = 0; + mutex_unlock(&audio->lock); + break; + } + case AUDIO_GET_CONFIG: { + struct msm_audio_config cfg; + + mutex_lock(&audio->lock); + if (copy_to_user((void *)arg, &audio->pcm_cfg, sizeof(cfg))) { + pr_err( + "%s: copy_to_user for AUDIO_GET_CONFIG failed\n", + __func__); + rc = -EFAULT; + } + mutex_unlock(&audio->lock); + break; + } + case AUDIO_SET_CONFIG: { + struct msm_audio_config config; + + pr_err("%s[%pK]:AUDIO_SET_CONFIG\n", __func__, audio); + mutex_lock(&audio->lock); + if (copy_from_user(&config, (void *)arg, sizeof(config))) { + pr_err( + "%s: copy_from_user for AUDIO_SET_CONFIG failed\n", + __func__); + rc = -EFAULT; + mutex_unlock(&audio->lock); + break; + } + if (audio->feedback != NON_TUNNEL_MODE) { + pr_err("%s[%pK]:Not sufficient permission to change the playback mode\n", + __func__, audio); + rc = -EACCES; + mutex_unlock(&audio->lock); + break; + } + if ((config.buffer_count > PCM_BUF_COUNT) || + (config.buffer_count == 1)) + config.buffer_count = PCM_BUF_COUNT; + + if (config.buffer_size < PCM_BUFSZ_MIN) + config.buffer_size = PCM_BUFSZ_MIN; + + audio->pcm_cfg.buffer_count = config.buffer_count; + audio->pcm_cfg.buffer_size = config.buffer_size; + audio->pcm_cfg.channel_count = config.channel_count; + audio->pcm_cfg.sample_rate = config.sample_rate; + rc = 0; + mutex_unlock(&audio->lock); + break; + } + case AUDIO_SET_BUF_CFG: { + struct msm_audio_buf_cfg cfg; + + mutex_lock(&audio->lock); + if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) { + pr_err( + "%s: copy_from_user for AUDIO_GET_BUF CONFIG failed\n", + __func__); + rc = -EFAULT; + mutex_unlock(&audio->lock); + break; + } + if ((audio->feedback == NON_TUNNEL_MODE) && + !cfg.meta_info_enable) { + rc = -EFAULT; + mutex_unlock(&audio->lock); + break; + } + + audio->buf_cfg.meta_info_enable = cfg.meta_info_enable; + pr_debug("%s[%pK]:session id %d: Set-buf-cfg: meta[%d]", + __func__, audio, + audio->ac->session, cfg.meta_info_enable); + mutex_unlock(&audio->lock); + break; + } + case AUDIO_GET_BUF_CFG: { + pr_debug("%s[%pK]:session id %d: Get-buf-cfg: meta[%d] framesperbuf[%d]\n", + __func__, audio, + audio->ac->session, audio->buf_cfg.meta_info_enable, + audio->buf_cfg.frames_per_buf); + + mutex_lock(&audio->lock); + if (copy_to_user((void *)arg, &audio->buf_cfg, + sizeof(struct msm_audio_buf_cfg))) { + pr_err( + "%s: copy_to_user for AUDIO_GET_BUF_CONFIG failed\n", + __func__); + rc = -EFAULT; + } + mutex_unlock(&audio->lock); + break; + } + case AUDIO_REGISTER_ION: { + struct msm_audio_ion_info info; + + pr_debug("%s[%pK]:AUDIO_REGISTER_ION\n", __func__, audio); + mutex_lock(&audio->lock); + if (copy_from_user(&info, (void *)arg, sizeof(info))) { + pr_err( + "%s: copy_from_user for AUDIO_REGISTER_ION failed\n", + __func__); + rc = -EFAULT; + } else { + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); + rc = audio_aio_ion_add(audio, &info); + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); + } + mutex_unlock(&audio->lock); + break; + } + case AUDIO_DEREGISTER_ION: { + struct msm_audio_ion_info info; + + mutex_lock(&audio->lock); + pr_debug("%s[%pK]:AUDIO_DEREGISTER_ION\n", __func__, audio); + if (copy_from_user(&info, (void *)arg, sizeof(info))) { + pr_err( + "%s: copy_from_user for AUDIO_DEREGISTER_ION failed\n", + __func__); + rc = -EFAULT; + } else { + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); + rc = audio_aio_ion_remove(audio, &info); + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); + } + mutex_unlock(&audio->lock); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + } + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_audio_stream_config32 { + u32 buffer_size; + u32 buffer_count; +}; + +struct msm_audio_stats32 { + u32 byte_count; + u32 sample_count; + u32 unused[2]; +}; + +struct msm_audio_config32 { + u32 buffer_size; + u32 buffer_count; + u32 channel_count; + u32 sample_rate; + u32 type; + u32 meta_field; + u32 bits; + u32 unused[3]; +}; + +struct msm_audio_buf_cfg32 { + u32 meta_info_enable; + u32 frames_per_buf; +}; + +struct msm_audio_ion_info32 { + int fd; + compat_uptr_t vaddr; +}; + +enum { + AUDIO_GET_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, 3, + struct msm_audio_config32), + AUDIO_SET_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, 4, + struct msm_audio_config32), + AUDIO_GET_STATS_32 = _IOR(AUDIO_IOCTL_MAGIC, 5, + struct msm_audio_stats32), + AUDIO_GET_EVENT_32 = _IOR(AUDIO_IOCTL_MAGIC, 13, + struct msm_audio_event32), + AUDIO_ASYNC_WRITE_32 = _IOW(AUDIO_IOCTL_MAGIC, 17, + struct msm_audio_aio_buf32), + AUDIO_ASYNC_READ_32 = _IOW(AUDIO_IOCTL_MAGIC, 18, + struct msm_audio_aio_buf32), + AUDIO_SET_STREAM_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, 80, + struct msm_audio_stream_config32), + AUDIO_GET_STREAM_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, 81, + struct msm_audio_stream_config32), + AUDIO_GET_BUF_CFG_32 = _IOW(AUDIO_IOCTL_MAGIC, 93, + struct msm_audio_buf_cfg32), + AUDIO_SET_BUF_CFG_32 = _IOW(AUDIO_IOCTL_MAGIC, 94, + struct msm_audio_buf_cfg32), + AUDIO_REGISTER_ION_32 = _IOW(AUDIO_IOCTL_MAGIC, 97, + struct msm_audio_ion_info32), + AUDIO_DEREGISTER_ION_32 = _IOW(AUDIO_IOCTL_MAGIC, 98, + struct msm_audio_ion_info32), +}; + +static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_ABORT_GET_EVENT: + case AUDIO_OUTPORT_FLUSH: + case AUDIO_STOP: + case AUDIO_PAUSE: + case AUDIO_FLUSH: + case AUDIO_GET_SESSION_ID: + case AUDIO_PM_AWAKE: + case AUDIO_PM_RELAX: + rc = audio_aio_shared_ioctl(file, cmd, arg); + break; + case AUDIO_GET_STATS_32: { + struct msm_audio_stats32 stats; + uint64_t timestamp; + + memset(&stats, 0, sizeof(struct msm_audio_stats32)); + stats.byte_count = atomic_read(&audio->in_bytes); + stats.sample_count = atomic_read(&audio->in_samples); + rc = q6asm_get_session_time(audio->ac, ×tamp); + if (rc >= 0) + memcpy(&stats.unused[0], ×tamp, sizeof(timestamp)); + else + pr_debug("Error while getting timestamp\n"); + if (copy_to_user((void *)arg, &stats, sizeof(stats))) { + pr_err( + "%s: copy_to_user for AUDIO_GET_STATS_32 failed\n", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_GET_EVENT_32: { + pr_debug("%s[%pK]:AUDIO_GET_EVENT\n", __func__, audio); + if (mutex_trylock(&audio->get_event_lock)) { + rc = audio_aio_process_event_req_compat(audio, + (void __user *)arg); + mutex_unlock(&audio->get_event_lock); + } else + rc = -EBUSY; + break; + } + case AUDIO_ASYNC_WRITE_32: { + mutex_lock(&audio->write_lock); + if (audio->drv_status & ADRV_STATUS_FSYNC) + rc = -EBUSY; + else { + if (audio->enabled) + rc = audio_aio_buf_add_compat(audio, 1, + (void __user *)arg); + else + rc = -EPERM; + } + mutex_unlock(&audio->write_lock); + break; + } + case AUDIO_ASYNC_READ_32: { + mutex_lock(&audio->read_lock); + if (audio->feedback) + rc = audio_aio_buf_add_compat(audio, 0, + (void __user *)arg); + else + rc = -EPERM; + mutex_unlock(&audio->read_lock); + break; + } + + case AUDIO_GET_STREAM_CONFIG_32: { + struct msm_audio_stream_config32 cfg; + + mutex_lock(&audio->lock); + memset(&cfg, 0, sizeof(cfg)); + cfg.buffer_size = audio->str_cfg.buffer_size; + cfg.buffer_count = audio->str_cfg.buffer_count; + pr_debug("%s[%pK]:GET STREAM CFG %d %d\n", + __func__, audio, cfg.buffer_size, cfg.buffer_count); + if (copy_to_user((void *)arg, &cfg, sizeof(cfg))) { + pr_err("%s: copy_to_user for AUDIO_GET_STREAM_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + } + mutex_unlock(&audio->lock); + break; + } + case AUDIO_SET_STREAM_CONFIG_32: { + struct msm_audio_stream_config32 cfg_32; + struct msm_audio_stream_config cfg; + + pr_debug("%s[%pK]:SET STREAM CONFIG\n", __func__, audio); + mutex_lock(&audio->lock); + if (copy_from_user(&cfg_32, (void *)arg, sizeof(cfg_32))) { + pr_err("%s: copy_from_user for AUDIO_SET_STREAM_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + mutex_unlock(&audio->lock); + break; + } + cfg.buffer_size = cfg_32.buffer_size; + cfg.buffer_count = cfg_32.buffer_count; + + audio->str_cfg.buffer_size = FRAME_SIZE; + audio->str_cfg.buffer_count = FRAME_NUM; + rc = 0; + mutex_unlock(&audio->lock); + break; + } + case AUDIO_GET_CONFIG_32: { + struct msm_audio_config32 cfg_32; + + mutex_lock(&audio->lock); + memset(&cfg_32, 0, sizeof(cfg_32)); + cfg_32.buffer_size = audio->pcm_cfg.buffer_size; + cfg_32.buffer_count = audio->pcm_cfg.buffer_count; + cfg_32.channel_count = audio->pcm_cfg.channel_count; + cfg_32.sample_rate = audio->pcm_cfg.sample_rate; + cfg_32.type = audio->pcm_cfg.type; + cfg_32.meta_field = audio->pcm_cfg.meta_field; + cfg_32.bits = audio->pcm_cfg.bits; + + if (copy_to_user((void *)arg, &cfg_32, sizeof(cfg_32))) { + pr_err("%s: copy_to_user for AUDIO_GET_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + } + mutex_unlock(&audio->lock); + break; + } + case AUDIO_SET_CONFIG_32: { + struct msm_audio_config config; + struct msm_audio_config32 config_32; + + mutex_lock(&audio->lock); + + if (audio->feedback != NON_TUNNEL_MODE) { + pr_err("%s[%pK]:Not sufficient permission to change the playback mode\n", + __func__, audio); + rc = -EACCES; + mutex_unlock(&audio->lock); + break; + } + pr_err("%s[%pK]:AUDIO_SET_CONFIG\n", __func__, audio); + if (copy_from_user(&config_32, (void *)arg, + sizeof(config_32))) { + pr_err("%s: copy_from_user for AUDIO_SET_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + mutex_unlock(&audio->lock); + break; + } + config.buffer_size = config_32.buffer_size; + config.buffer_count = config_32.buffer_count; + config.channel_count = config_32.channel_count; + config.sample_rate = config_32.sample_rate; + config.type = config_32.type; + config.meta_field = config_32.meta_field; + config.bits = config_32.bits; + + if ((config.buffer_count > PCM_BUF_COUNT) || + (config.buffer_count == 1)) + config.buffer_count = PCM_BUF_COUNT; + + if (config.buffer_size < PCM_BUFSZ_MIN) + config.buffer_size = PCM_BUFSZ_MIN; + + audio->pcm_cfg.buffer_count = config.buffer_count; + audio->pcm_cfg.buffer_size = config.buffer_size; + audio->pcm_cfg.channel_count = config.channel_count; + audio->pcm_cfg.sample_rate = config.sample_rate; + rc = 0; + mutex_unlock(&audio->lock); + break; + } + case AUDIO_SET_BUF_CFG_32: { + struct msm_audio_buf_cfg cfg; + struct msm_audio_buf_cfg32 cfg_32; + + mutex_lock(&audio->lock); + if (copy_from_user(&cfg_32, (void *)arg, sizeof(cfg_32))) { + pr_err("%s: copy_from_user for AUDIO_SET_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + mutex_unlock(&audio->lock); + break; + } + cfg.meta_info_enable = cfg_32.meta_info_enable; + cfg.frames_per_buf = cfg_32.frames_per_buf; + + if ((audio->feedback == NON_TUNNEL_MODE) && + !cfg.meta_info_enable) { + rc = -EFAULT; + mutex_unlock(&audio->lock); + break; + } + + audio->buf_cfg.meta_info_enable = cfg.meta_info_enable; + pr_debug("%s[%pK]:session id %d: Set-buf-cfg: meta[%d]", + __func__, audio, + audio->ac->session, cfg.meta_info_enable); + mutex_unlock(&audio->lock); + break; + } + case AUDIO_GET_BUF_CFG_32: { + struct msm_audio_buf_cfg32 cfg_32; + + pr_debug("%s[%pK]:session id %d: Get-buf-cfg: meta[%d] framesperbuf[%d]\n", + __func__, audio, + audio->ac->session, audio->buf_cfg.meta_info_enable, + audio->buf_cfg.frames_per_buf); + mutex_lock(&audio->lock); + memset(&cfg_32, 0, sizeof(cfg_32)); + cfg_32.meta_info_enable = audio->buf_cfg.meta_info_enable; + cfg_32.frames_per_buf = audio->buf_cfg.frames_per_buf; + if (copy_to_user((void *)arg, &cfg_32, + sizeof(struct msm_audio_buf_cfg32))) { + pr_err("%s: copy_to_user for AUDIO_GET_BUF_CFG_32 failed\n", + __func__); + rc = -EFAULT; + } + mutex_unlock(&audio->lock); + break; + } + case AUDIO_REGISTER_ION_32: { + struct msm_audio_ion_info32 info_32; + struct msm_audio_ion_info info; + + pr_debug("%s[%pK]:AUDIO_REGISTER_ION\n", __func__, audio); + mutex_lock(&audio->lock); + if (copy_from_user(&info_32, (void *)arg, sizeof(info_32))) { + pr_err("%s: copy_from_user for AUDIO_REGISTER_ION_32 failed\n", + __func__); + rc = -EFAULT; + } else { + info.fd = info_32.fd; + info.vaddr = compat_ptr(info_32.vaddr); + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); + rc = audio_aio_ion_add(audio, &info); + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); + } + mutex_unlock(&audio->lock); + break; + } + case AUDIO_DEREGISTER_ION_32: { + struct msm_audio_ion_info32 info_32; + struct msm_audio_ion_info info; + + mutex_lock(&audio->lock); + pr_debug("%s[%pK]:AUDIO_DEREGISTER_ION\n", __func__, audio); + if (copy_from_user(&info_32, (void *)arg, sizeof(info_32))) { + pr_err("%s: copy_from_user for AUDIO_DEREGISTER_ION_32 failed\n", + __func__); + rc = -EFAULT; + } else { + info.fd = info_32.fd; + info.vaddr = compat_ptr(info_32.vaddr); + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); + rc = audio_aio_ion_remove(audio, &info); + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); + } + mutex_unlock(&audio->lock); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + } + return rc; +} +#endif diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.h b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.h new file mode 100644 index 000000000000..82374f9a17a9 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.h @@ -0,0 +1,232 @@ +/* Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "q6audio_common.h" + +#define TUNNEL_MODE 0x0000 +#define NON_TUNNEL_MODE 0x0001 + +#define ADRV_STATUS_AIO_INTF 0x00000001 /* AIO interface */ +#define ADRV_STATUS_FSYNC 0x00000008 +#define ADRV_STATUS_PAUSE 0x00000010 +#define AUDIO_DEC_EOS_SET 0x00000001 +#define AUDIO_DEC_EOF_SET 0x00000010 +#define AUDIO_EVENT_NUM 10 + +#define __CONTAINS(r, v, l) ({ \ + typeof(r) __r = r; \ + typeof(v) __v = v; \ + typeof(v) __e = __v + l; \ + int res = ((__v >= __r->vaddr) && \ + (__e <= __r->vaddr + __r->len)); \ + res; \ +}) + +#define CONTAINS(r1, r2) ({ \ + typeof(r2) __r2 = r2; \ + __CONTAINS(r1, __r2->vaddr, __r2->len); \ +}) + +#define IN_RANGE(r, v) ({ \ + typeof(r) __r = r; \ + typeof(v) __vv = v; \ + int res = ((__vv >= __r->vaddr) && \ + (__vv < (__r->vaddr + __r->len))); \ + res; \ +}) + +#define OVERLAPS(r1, r2) ({ \ + typeof(r1) __r1 = r1; \ + typeof(r2) __r2 = r2; \ + typeof(__r2->vaddr) __v = __r2->vaddr; \ + typeof(__v) __e = __v + __r2->len - 1; \ + int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e)); \ + res; \ +}) + +struct timestamp { + u32 lowpart; + u32 highpart; +} __packed; + +struct meta_out_dsp { + u32 offset_to_frame; + u32 frame_size; + u32 encoded_pcm_samples; + u32 msw_ts; + u32 lsw_ts; + u32 nflags; +} __packed; + +struct dec_meta_in { + unsigned char reserved[18]; + unsigned short offset; + struct timestamp ntimestamp; + unsigned int nflags; +} __packed; + +struct dec_meta_out { + unsigned int reserved[7]; + unsigned int num_of_frames; + struct meta_out_dsp meta_out_dsp[]; +} __packed; + +/* General meta field to store meta info locally */ +union meta_data { + struct dec_meta_out meta_out; + struct dec_meta_in meta_in; +} __packed; + +/* per device wakeup source manager */ +struct ws_mgr { + struct mutex ws_lock; + uint32_t ref_cnt; +}; + +#define PCM_BUF_COUNT (2) +/* Buffer with meta */ +#define PCM_BUFSZ_MIN ((4*1024) + sizeof(struct dec_meta_out)) + +/* FRAME_NUM must be a power of two */ +#define FRAME_NUM (2) +#define FRAME_SIZE ((4*1536) + sizeof(struct dec_meta_in)) + +struct audio_aio_ion_region { + struct list_head list; + struct ion_handle *handle; + int fd; + void *vaddr; + phys_addr_t paddr; + void *kvaddr; + unsigned long len; + unsigned int ref_cnt; +}; + +struct audio_aio_event { + struct list_head list; + int event_type; + union msm_audio_event_payload payload; +}; + +struct audio_aio_buffer_node { + struct list_head list; + struct msm_audio_aio_buf buf; + unsigned long paddr; + uint32_t token; + void *kvaddr; + union meta_data meta_info; +}; + +struct q6audio_aio; +struct audio_aio_drv_operations { + void (*out_flush)(struct q6audio_aio *); + void (*in_flush)(struct q6audio_aio *); +}; + +struct q6audio_aio { + atomic_t in_bytes; + atomic_t in_samples; + + struct msm_audio_stream_config str_cfg; + struct msm_audio_buf_cfg buf_cfg; + struct msm_audio_config pcm_cfg; + void *codec_cfg; + + struct audio_client *ac; + + struct mutex lock; + struct mutex read_lock; + struct mutex write_lock; + struct mutex get_event_lock; + wait_queue_head_t cmd_wait; + wait_queue_head_t write_wait; + wait_queue_head_t event_wait; + spinlock_t dsp_lock; + spinlock_t event_queue_lock; + + struct miscdevice *miscdevice; + uint32_t wakelock_voted; + struct ws_mgr *audio_ws_mgr; + +#ifdef CONFIG_DEBUG_FS + struct dentry *dentry; +#endif + struct list_head out_queue; /* queue to retain output buffers */ + struct list_head in_queue; /* queue to retain input buffers */ + struct list_head free_event_queue; + struct list_head event_queue; + struct list_head ion_region_queue; /* protected by lock */ + struct ion_client *client; + struct audio_aio_drv_operations drv_ops; + union msm_audio_event_payload eos_write_payload; + uint32_t device_events; + uint16_t volume; + uint32_t drv_status; + int event_abort; + int eos_rsp; + int eos_flag; + int opened; + int enabled; + int stopped; + int feedback; + int rflush; /* Read flush */ + int wflush; /* Write flush */ + bool reset_event; + long (*codec_ioctl)(struct file *, unsigned int, unsigned long); + long (*codec_compat_ioctl)(struct file *, unsigned int, unsigned long); +}; + +void audio_aio_async_write_ack(struct q6audio_aio *audio, uint32_t token, + uint32_t *payload); + +void audio_aio_async_read_ack(struct q6audio_aio *audio, uint32_t token, + uint32_t *payload); + +int insert_eos_buf(struct q6audio_aio *audio, + struct audio_aio_buffer_node *buf_node); + +void extract_meta_out_info(struct q6audio_aio *audio, + struct audio_aio_buffer_node *buf_node, int dir); + +int audio_aio_open(struct q6audio_aio *audio, struct file *file); +int audio_aio_enable(struct q6audio_aio *audio); +void audio_aio_post_event(struct q6audio_aio *audio, int type, + union msm_audio_event_payload payload); +int audio_aio_release(struct inode *inode, struct file *file); +int audio_aio_fsync(struct file *file, loff_t start, loff_t end, int datasync); +void audio_aio_async_out_flush(struct q6audio_aio *audio); +void audio_aio_async_in_flush(struct q6audio_aio *audio); +void audio_aio_ioport_reset(struct q6audio_aio *audio); +int enable_volume_ramp(struct q6audio_aio *audio); +#ifdef CONFIG_DEBUG_FS +int audio_aio_debug_open(struct inode *inode, struct file *file); +ssize_t audio_aio_debug_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos); +#endif diff --git a/drivers/misc/qcom/qdsp6v2/audio_wma.c b/drivers/misc/qcom/qdsp6v2/audio_wma.c new file mode 100644 index 000000000000..e35334a3313a --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_wma.c @@ -0,0 +1,345 @@ +/* wma audio output device + * + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include "audio_utils_aio.h" + +static struct miscdevice audio_wma_misc; +static struct ws_mgr audio_wma_ws_mgr; + +#ifdef CONFIG_DEBUG_FS +static const struct file_operations audio_wma_debug_fops = { + .read = audio_aio_debug_read, + .open = audio_aio_debug_open, +}; +#endif + +static long audio_ioctl_shared(struct file *file, unsigned int cmd, + void *arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + struct asm_wma_cfg wma_cfg; + struct msm_audio_wma_config_v2 *wma_config; + + pr_debug("%s[%pK]: AUDIO_START session_id[%d]\n", __func__, + audio, audio->ac->session); + if (audio->feedback == NON_TUNNEL_MODE) { + /* Configure PCM output block */ + rc = q6asm_enc_cfg_blk_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + if (rc < 0) { + pr_err("pcm output block config failed\n"); + break; + } + } + wma_config = (struct msm_audio_wma_config_v2 *)audio->codec_cfg; + wma_cfg.format_tag = wma_config->format_tag; + wma_cfg.ch_cfg = wma_config->numchannels; + wma_cfg.sample_rate = wma_config->samplingrate; + wma_cfg.avg_bytes_per_sec = wma_config->avgbytespersecond; + wma_cfg.block_align = wma_config->block_align; + wma_cfg.valid_bits_per_sample = + wma_config->validbitspersample; + wma_cfg.ch_mask = wma_config->channelmask; + wma_cfg.encode_opt = wma_config->encodeopt; + /* Configure Media format block */ + rc = q6asm_media_format_block_wma(audio->ac, &wma_cfg, + audio->ac->stream_id); + if (rc < 0) { + pr_err("cmd media format block failed\n"); + break; + } + rc = audio_aio_enable(audio); + audio->eos_rsp = 0; + audio->eos_flag = 0; + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("Audio Start procedure failed rc=%d\n", rc); + break; + } + pr_debug("AUDIO_START success enable[%d]\n", audio->enabled); + if (audio->stopped == 1) + audio->stopped = 0; + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + break; + } + return rc; +} + +static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + case AUDIO_GET_WMA_CONFIG_V2: { + if (copy_to_user((void *)arg, audio->codec_cfg, + sizeof(struct msm_audio_wma_config_v2))) { + pr_err("%s:copy_to_user for AUDIO_SET_WMA_CONFIG_V2 failed\n", + __func__); + rc = -EFAULT; + break; + } + break; + } + case AUDIO_SET_WMA_CONFIG_V2: { + if (copy_from_user(audio->codec_cfg, (void *)arg, + sizeof(struct msm_audio_wma_config_v2))) { + pr_err("%s:copy_from_user for AUDIO_SET_WMA_CONFIG_V2 failed\n", + __func__); + rc = -EFAULT; + break; + } + break; + } + default: { + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); + rc = audio->codec_ioctl(file, cmd, arg); + if (rc) + pr_err("Failed in utils_ioctl: %d\n", rc); + break; + } + } + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_audio_wma_config_v2_32 { + u16 format_tag; + u16 numchannels; + u32 samplingrate; + u32 avgbytespersecond; + u16 block_align; + u16 validbitspersample; + u32 channelmask; + u16 encodeopt; +}; + +enum { + AUDIO_GET_WMA_CONFIG_V2_32 = _IOR(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+2), struct msm_audio_wma_config_v2_32), + AUDIO_SET_WMA_CONFIG_V2_32 = _IOW(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+3), struct msm_audio_wma_config_v2_32) +}; + +static long audio_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + case AUDIO_GET_WMA_CONFIG_V2_32: { + struct msm_audio_wma_config_v2 *wma_config; + struct msm_audio_wma_config_v2_32 wma_config_32; + + memset(&wma_config_32, 0, sizeof(wma_config_32)); + + wma_config = (struct msm_audio_wma_config_v2 *)audio->codec_cfg; + wma_config_32.format_tag = wma_config->format_tag; + wma_config_32.numchannels = wma_config->numchannels; + wma_config_32.samplingrate = wma_config->samplingrate; + wma_config_32.avgbytespersecond = wma_config->avgbytespersecond; + wma_config_32.block_align = wma_config->block_align; + wma_config_32.validbitspersample = + wma_config->validbitspersample; + wma_config_32.channelmask = wma_config->channelmask; + wma_config_32.encodeopt = wma_config->encodeopt; + if (copy_to_user((void *)arg, &wma_config_32, + sizeof(wma_config_32))) { + pr_err("%s: copy_to_user for GET_WMA_CONFIG_V2_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + break; + } + case AUDIO_SET_WMA_CONFIG_V2_32: { + struct msm_audio_wma_config_v2 *wma_config; + struct msm_audio_wma_config_v2_32 wma_config_32; + + if (copy_from_user(&wma_config_32, (void *)arg, + sizeof(wma_config_32))) { + pr_err("%s: copy_from_user for SET_WMA_CONFIG_V2_32 failed\n" + , __func__); + rc = -EFAULT; + break; + } + wma_config = (struct msm_audio_wma_config_v2 *)audio->codec_cfg; + wma_config->format_tag = wma_config_32.format_tag; + wma_config->numchannels = wma_config_32.numchannels; + wma_config->samplingrate = wma_config_32.samplingrate; + wma_config->avgbytespersecond = wma_config_32.avgbytespersecond; + wma_config->block_align = wma_config_32.block_align; + wma_config->validbitspersample = + wma_config_32.validbitspersample; + wma_config->channelmask = wma_config_32.channelmask; + wma_config->encodeopt = wma_config_32.encodeopt; + break; + } + default: { + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); + rc = audio->codec_compat_ioctl(file, cmd, arg); + if (rc) + pr_err("Failed in utils_ioctl: %d\n", rc); + break; + } + } + return rc; +} +#else +#define audio_compat_ioctl NULL +#endif + +static int audio_open(struct inode *inode, struct file *file) +{ + struct q6audio_aio *audio = NULL; + int rc = 0; + +#ifdef CONFIG_DEBUG_FS + /* 4 bytes represents decoder number, 1 byte for terminate string */ + char name[sizeof "msm_wma_" + 5]; +#endif + audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + + audio->codec_cfg = kzalloc(sizeof(struct msm_audio_wma_config_v2), + GFP_KERNEL); + if (audio->codec_cfg == NULL) { + kfree(audio); + return -ENOMEM; + } + + audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN; + audio->miscdevice = &audio_wma_misc; + audio->wakelock_voted = false; + audio->audio_ws_mgr = &audio_wma_ws_mgr; + + audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("Could not allocate memory for audio client\n"); + kfree(audio->codec_cfg); + kfree(audio); + return -ENOMEM; + } + rc = audio_aio_open(audio, file); + if (rc < 0) { + pr_err("%s: audio_aio_open rc=%d\n", + __func__, rc); + goto fail; + } + /* open in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) { + rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM, + FORMAT_WMA_V9); + if (rc < 0) { + pr_err("NT mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = NON_TUNNEL_MODE; + /* open WMA decoder, expected frames is always 1*/ + audio->buf_cfg.frames_per_buf = 0x01; + audio->buf_cfg.meta_info_enable = 0x01; + } else if ((file->f_mode & FMODE_WRITE) && + !(file->f_mode & FMODE_READ)) { + rc = q6asm_open_write(audio->ac, FORMAT_WMA_V9); + if (rc < 0) { + pr_err("T mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = TUNNEL_MODE; + audio->buf_cfg.meta_info_enable = 0x00; + } else { + pr_err("Not supported mode\n"); + rc = -EACCES; + goto fail; + } + +#ifdef CONFIG_DEBUG_FS + snprintf(name, sizeof(name), "msm_wma_%04x", audio->ac->session); + audio->dentry = debugfs_create_file(name, S_IFREG | 0444, + NULL, (void *)audio, + &audio_wma_debug_fops); + + if (IS_ERR(audio->dentry)) + pr_debug("debugfs_create_file failed\n"); +#endif + pr_info("%s:wmadec success mode[%d]session[%d]\n", __func__, + audio->feedback, + audio->ac->session); + return rc; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio->codec_cfg); + kfree(audio); + return rc; +} + +static const struct file_operations audio_wma_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_aio_release, + .unlocked_ioctl = audio_ioctl, + .fsync = audio_aio_fsync, + .compat_ioctl = audio_compat_ioctl +}; + +static struct miscdevice audio_wma_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_wma", + .fops = &audio_wma_fops, +}; + +static int __init audio_wma_init(void) +{ + int ret = misc_register(&audio_wma_misc); + + if (ret == 0) + device_init_wakeup(audio_wma_misc.this_device, true); + audio_wma_ws_mgr.ref_cnt = 0; + mutex_init(&audio_wma_ws_mgr.ws_lock); + + return ret; +} + +device_initcall(audio_wma_init); diff --git a/drivers/misc/qcom/qdsp6v2/audio_wmapro.c b/drivers/misc/qcom/qdsp6v2/audio_wmapro.c new file mode 100644 index 000000000000..3cb9db15f872 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/audio_wmapro.c @@ -0,0 +1,418 @@ +/* wmapro audio output device + * + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include "audio_utils_aio.h" + +static struct miscdevice audio_wmapro_misc; +static struct ws_mgr audio_wmapro_ws_mgr; + +#ifdef CONFIG_DEBUG_FS +static const struct file_operations audio_wmapro_debug_fops = { + .read = audio_aio_debug_read, + .open = audio_aio_debug_open, +}; +#endif + +static long audio_ioctl_shared(struct file *file, unsigned int cmd, + void *arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: { + struct asm_wmapro_cfg wmapro_cfg; + struct msm_audio_wmapro_config *wmapro_config; + + pr_debug("%s: AUDIO_START session_id[%d]\n", __func__, + audio->ac->session); + if (audio->feedback == NON_TUNNEL_MODE) { + /* Configure PCM output block */ + rc = q6asm_enc_cfg_blk_pcm_v2(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count, + 16, /* bits per sample */ + true, /* use default channel map */ + true, /* use back channel map flavor */ + NULL); + if (rc < 0) { + pr_err("pcm output block config failed\n"); + break; + } + } + wmapro_config = (struct msm_audio_wmapro_config *) + audio->codec_cfg; + if ((wmapro_config->formattag == 0x162) || + (wmapro_config->formattag == 0x163) || + (wmapro_config->formattag == 0x166) || + (wmapro_config->formattag == 0x167)) { + wmapro_cfg.format_tag = wmapro_config->formattag; + } else { + pr_err("%s:AUDIO_START failed: formattag = %d\n", + __func__, wmapro_config->formattag); + rc = -EINVAL; + break; + } + if (wmapro_config->numchannels > 0) { + wmapro_cfg.ch_cfg = wmapro_config->numchannels; + } else { + pr_err("%s:AUDIO_START failed: channels = %d\n", + __func__, wmapro_config->numchannels); + rc = -EINVAL; + break; + } + if (wmapro_config->samplingrate > 0) { + wmapro_cfg.sample_rate = wmapro_config->samplingrate; + } else { + pr_err("%s:AUDIO_START failed: sample_rate = %d\n", + __func__, wmapro_config->samplingrate); + rc = -EINVAL; + break; + } + wmapro_cfg.avg_bytes_per_sec = + wmapro_config->avgbytespersecond; + if ((wmapro_config->asfpacketlength <= 13376) || + (wmapro_config->asfpacketlength > 0)) { + wmapro_cfg.block_align = + wmapro_config->asfpacketlength; + } else { + pr_err("%s:AUDIO_START failed: block_align = %d\n", + __func__, wmapro_config->asfpacketlength); + rc = -EINVAL; + break; + } + if ((wmapro_config->validbitspersample == 16) || + (wmapro_config->validbitspersample == 24)) { + wmapro_cfg.valid_bits_per_sample = + wmapro_config->validbitspersample; + } else { + pr_err("%s:AUDIO_START failed: bitspersample = %d\n", + __func__, wmapro_config->validbitspersample); + rc = -EINVAL; + break; + } + wmapro_cfg.ch_mask = wmapro_config->channelmask; + wmapro_cfg.encode_opt = wmapro_config->encodeopt; + wmapro_cfg.adv_encode_opt = + wmapro_config->advancedencodeopt; + wmapro_cfg.adv_encode_opt2 = + wmapro_config->advancedencodeopt2; + /* Configure Media format block */ + rc = q6asm_media_format_block_wmapro(audio->ac, &wmapro_cfg, + audio->ac->stream_id); + if (rc < 0) { + pr_err("cmd media format block failed\n"); + break; + } + rc = audio_aio_enable(audio); + audio->eos_rsp = 0; + audio->eos_flag = 0; + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("Audio Start procedure failed rc=%d\n", rc); + break; + } + pr_debug("AUDIO_START success enable[%d]\n", audio->enabled); + if (audio->stopped == 1) + audio->stopped = 0; + break; + } + default: + pr_err("%s: Unknown ioctl cmd %d\n", __func__, cmd); + rc = -EINVAL; + break; + } + return rc; +} + +static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_GET_WMAPRO_CONFIG: { + if (copy_to_user((void *)arg, audio->codec_cfg, + sizeof(struct msm_audio_wmapro_config))) { + pr_err("%s: copy_to_user for AUDIO_GET_WMAPRO_CONFIG failed\n", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_WMAPRO_CONFIG: { + if (copy_from_user(audio->codec_cfg, (void *)arg, + sizeof(struct msm_audio_wmapro_config))) { + pr_err("%s: copy_from_user for AUDIO_SET_WMAPRO_CONFIG_V2 failed\n", + __func__); + rc = -EFAULT; + break; + } + break; + } + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + default: { + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); + rc = audio->codec_ioctl(file, cmd, arg); + if (rc) + pr_err("Failed in utils_ioctl: %d\n", rc); + break; + } + } + return rc; +} + +#ifdef CONFIG_COMPAT + +struct msm_audio_wmapro_config32 { + u16 armdatareqthr; + u8 validbitspersample; + u8 numchannels; + u16 formattag; + u32 samplingrate; + u32 avgbytespersecond; + u16 asfpacketlength; + u32 channelmask; + u16 encodeopt; + u16 advancedencodeopt; + u32 advancedencodeopt2; +}; + +enum { + AUDIO_GET_WMAPRO_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_wmapro_config32), + AUDIO_SET_WMAPRO_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_wmapro_config32) +}; + +static long audio_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct q6audio_aio *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_GET_WMAPRO_CONFIG_32: { + struct msm_audio_wmapro_config *wmapro_config; + struct msm_audio_wmapro_config32 wmapro_config_32; + + memset(&wmapro_config_32, 0, sizeof(wmapro_config_32)); + + wmapro_config = + (struct msm_audio_wmapro_config *)audio->codec_cfg; + wmapro_config_32.armdatareqthr = wmapro_config->armdatareqthr; + wmapro_config_32.validbitspersample = + wmapro_config->validbitspersample; + wmapro_config_32.numchannels = wmapro_config->numchannels; + wmapro_config_32.formattag = wmapro_config->formattag; + wmapro_config_32.samplingrate = wmapro_config->samplingrate; + wmapro_config_32.avgbytespersecond = + wmapro_config->avgbytespersecond; + wmapro_config_32.asfpacketlength = + wmapro_config->asfpacketlength; + wmapro_config_32.channelmask = wmapro_config->channelmask; + wmapro_config_32.encodeopt = wmapro_config->encodeopt; + wmapro_config_32.advancedencodeopt = + wmapro_config->advancedencodeopt; + wmapro_config_32.advancedencodeopt2 = + wmapro_config->advancedencodeopt2; + + if (copy_to_user((void *)arg, &wmapro_config_32, + sizeof(struct msm_audio_wmapro_config32))) { + pr_err("%s: copy_to_user for AUDIO_GET_WMAPRO_CONFIG_V2_32 failed\n", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_WMAPRO_CONFIG_32: { + struct msm_audio_wmapro_config *wmapro_config; + struct msm_audio_wmapro_config32 wmapro_config_32; + + if (copy_from_user(&wmapro_config_32, (void *)arg, + sizeof(struct msm_audio_wmapro_config32))) { + pr_err( + "%s: copy_from_user for AUDIO_SET_WMAPRO_CONFG_V2_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + wmapro_config = + (struct msm_audio_wmapro_config *)audio->codec_cfg; + wmapro_config->armdatareqthr = wmapro_config_32.armdatareqthr; + wmapro_config->validbitspersample = + wmapro_config_32.validbitspersample; + wmapro_config->numchannels = wmapro_config_32.numchannels; + wmapro_config->formattag = wmapro_config_32.formattag; + wmapro_config->samplingrate = wmapro_config_32.samplingrate; + wmapro_config->avgbytespersecond = + wmapro_config_32.avgbytespersecond; + wmapro_config->asfpacketlength = + wmapro_config_32.asfpacketlength; + wmapro_config->channelmask = wmapro_config_32.channelmask; + wmapro_config->encodeopt = wmapro_config_32.encodeopt; + wmapro_config->advancedencodeopt = + wmapro_config_32.advancedencodeopt; + wmapro_config->advancedencodeopt2 = + wmapro_config_32.advancedencodeopt2; + break; + } + case AUDIO_START: { + rc = audio_ioctl_shared(file, cmd, (void *)arg); + break; + } + default: { + pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); + rc = audio->codec_compat_ioctl(file, cmd, arg); + if (rc) + pr_err("Failed in utils_ioctl: %d\n", rc); + break; + } + } + return rc; +} +#else +#define audio_compat_ioctl NULL +#endif + +static int audio_open(struct inode *inode, struct file *file) +{ + struct q6audio_aio *audio = NULL; + int rc = 0; + +#ifdef CONFIG_DEBUG_FS + /* 4 bytes represents decoder number, 1 byte for terminate string */ + char name[sizeof "msm_wmapro_" + 5]; +#endif + audio = kzalloc(sizeof(struct q6audio_aio), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + + audio->codec_cfg = kzalloc(sizeof(struct msm_audio_wmapro_config), + GFP_KERNEL); + if (audio->codec_cfg == NULL) { + kfree(audio); + return -ENOMEM; + } + + + audio->pcm_cfg.buffer_size = PCM_BUFSZ_MIN; + audio->miscdevice = &audio_wmapro_misc; + audio->wakelock_voted = false; + audio->audio_ws_mgr = &audio_wmapro_ws_mgr; + + audio->ac = q6asm_audio_client_alloc((app_cb) q6_audio_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("Could not allocate memory for audio client\n"); + kfree(audio->codec_cfg); + kfree(audio); + return -ENOMEM; + } + + rc = audio_aio_open(audio, file); + if (rc < 0) { + pr_err("%s: audio_aio_open rc=%d\n", + __func__, rc); + goto fail; + } + /* open in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && (file->f_mode & FMODE_READ)) { + rc = q6asm_open_read_write(audio->ac, FORMAT_LINEAR_PCM, + FORMAT_WMA_V10PRO); + if (rc < 0) { + pr_err("NT mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = NON_TUNNEL_MODE; + /* open WMA decoder, expected frames is always 1*/ + audio->buf_cfg.frames_per_buf = 0x01; + audio->buf_cfg.meta_info_enable = 0x01; + } else if ((file->f_mode & FMODE_WRITE) && + !(file->f_mode & FMODE_READ)) { + rc = q6asm_open_write(audio->ac, FORMAT_WMA_V10PRO); + if (rc < 0) { + pr_err("T mode Open failed rc=%d\n", rc); + rc = -ENODEV; + goto fail; + } + audio->feedback = TUNNEL_MODE; + audio->buf_cfg.meta_info_enable = 0x00; + } else { + pr_err("Not supported mode\n"); + rc = -EACCES; + goto fail; + } + +#ifdef CONFIG_DEBUG_FS + snprintf(name, sizeof(name), "msm_wmapro_%04x", audio->ac->session); + audio->dentry = debugfs_create_file(name, S_IFREG | 0444, + NULL, (void *)audio, + &audio_wmapro_debug_fops); + + if (IS_ERR(audio->dentry)) + pr_debug("debugfs_create_file failed\n"); +#endif + pr_info("%s:wmapro decoder open success, session_id = %d\n", __func__, + audio->ac->session); + return rc; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio->codec_cfg); + kfree(audio); + return rc; +} + +static const struct file_operations audio_wmapro_fops = { + .owner = THIS_MODULE, + .open = audio_open, + .release = audio_aio_release, + .unlocked_ioctl = audio_ioctl, + .fsync = audio_aio_fsync, + .compat_ioctl = audio_compat_ioctl +}; + +static struct miscdevice audio_wmapro_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_wmapro", + .fops = &audio_wmapro_fops, +}; + +static int __init audio_wmapro_init(void) +{ + int ret = misc_register(&audio_wmapro_misc); + + if (ret == 0) + device_init_wakeup(audio_wmapro_misc.this_device, true); + audio_wmapro_ws_mgr.ref_cnt = 0; + mutex_init(&audio_wmapro_ws_mgr.ws_lock); + + return ret; +} + +device_initcall(audio_wmapro_init); diff --git a/drivers/misc/qcom/qdsp6v2/evrc_in.c b/drivers/misc/qcom/qdsp6v2/evrc_in.c new file mode 100644 index 000000000000..e30271dd8102 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/evrc_in.c @@ -0,0 +1,410 @@ +/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "audio_utils.h" + +/* Buffer with meta*/ +#define PCM_BUF_SIZE (4096 + sizeof(struct meta_in)) + +/* Maximum 10 frames in buffer with meta */ +#define FRAME_SIZE (1 + ((23+sizeof(struct meta_out_dsp)) * 10)) + +static long evrc_in_ioctl_shared(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + int cnt = 0; + + switch (cmd) { + case AUDIO_START: { + struct msm_audio_evrc_enc_config *enc_cfg; + + enc_cfg = audio->enc_cfg; + pr_debug("%s:session id %d: default buf alloc[%d]\n", __func__, + audio->ac->session, audio->buf_alloc); + if (audio->enabled == 1) { + pr_info("%s:AUDIO_START already over\n", __func__); + rc = 0; + break; + } + rc = audio_in_buf_alloc(audio); + if (rc < 0) { + pr_err("%s:session id %d: buffer allocation failed\n", + __func__, audio->ac->session); + break; + } + + /* rate_modulation_cmd set to zero + * currently not configurable from user space + */ + rc = q6asm_enc_cfg_blk_evrc(audio->ac, + audio->buf_cfg.frames_per_buf, + enc_cfg->min_bit_rate, + enc_cfg->max_bit_rate, 0); + + if (rc < 0) { + pr_err("%s:session id %d: cmd evrc media format block failed\n", + __func__, audio->ac->session); + break; + } + if (audio->feedback == NON_TUNNEL_MODE) { + rc = q6asm_media_format_block_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + + if (rc < 0) { + pr_err("%s:session id %d: media format block failed\n", + __func__, audio->ac->session); + break; + } + } + pr_debug("%s:session id %d: AUDIO_START enable[%d]\n", + __func__, audio->ac->session, audio->enabled); + rc = audio_in_enable(audio); + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("%s:session id %d: Audio Start procedure failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + while (cnt++ < audio->str_cfg.buffer_count) + q6asm_read(audio->ac); /* Push buffer to DSP */ + rc = 0; + pr_debug("%s:session id %d: AUDIO_START success enable[%d]\n", + __func__, audio->ac->session, audio->enabled); + break; + } + case AUDIO_STOP: { + pr_debug("%s:session id %d: AUDIO_STOP\n", __func__, + audio->ac->session); + rc = audio_in_disable(audio); + if (rc < 0) { + pr_err("%s:session id %d: Audio Stop procedure failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + break; + } + case AUDIO_SET_EVRC_ENC_CONFIG: { + struct msm_audio_evrc_enc_config *cfg; + struct msm_audio_evrc_enc_config *enc_cfg; + + enc_cfg = audio->enc_cfg; + cfg = (struct msm_audio_evrc_enc_config *)arg; + if (cfg == NULL) { + pr_err("%s: NULL config pointer for %s\n", + __func__, "AUDIO_SET_EVRC_ENC_CONFIG"); + rc = -EINVAL; + break; + } + if (cfg->min_bit_rate > 4 || + cfg->min_bit_rate < 1 || + (cfg->min_bit_rate == 2)) { + pr_err("%s:session id %d: invalid min bitrate\n", + __func__, audio->ac->session); + rc = -EINVAL; + break; + } + if (cfg->max_bit_rate > 4 || + cfg->max_bit_rate < 1 || + (cfg->max_bit_rate == 2)) { + pr_err("%s:session id %d: invalid max bitrate\n", + __func__, audio->ac->session); + rc = -EINVAL; + break; + } + enc_cfg->min_bit_rate = cfg->min_bit_rate; + enc_cfg->max_bit_rate = cfg->max_bit_rate; + pr_debug("%s:session id %d: min_bit_rate= 0x%x max_bit_rate=0x%x\n", + __func__, + audio->ac->session, enc_cfg->min_bit_rate, + enc_cfg->max_bit_rate); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + } + return rc; +} + +static long evrc_in_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: + case AUDIO_STOP: { + rc = evrc_in_ioctl_shared(file, cmd, arg); + break; + } + case AUDIO_GET_EVRC_ENC_CONFIG: { + if (copy_to_user((void *)arg, audio->enc_cfg, + sizeof(struct msm_audio_evrc_enc_config))) { + pr_err("%s: copy_to_user for AUDIO_GET_EVRC_ENC_CONFIG failed\n", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_EVRC_ENC_CONFIG: { + struct msm_audio_evrc_enc_config cfg; + + if (copy_from_user(&cfg, (void *) arg, + sizeof(struct msm_audio_evrc_enc_config))) { + pr_err("%s: copy_from_user for AUDIO_SET_EVRC_ENC_CONFIG failed\n", + __func__); + rc = -EFAULT; + break; + } + rc = evrc_in_ioctl_shared(file, cmd, (unsigned long)&cfg); + if (rc) + pr_err("%s:AUDIO_SET_EVRC_ENC_CONFIG failed. rc= %d\n", + __func__, rc); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + } + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_audio_evrc_enc_config32 { + u32 cdma_rate; + u32 min_bit_rate; + u32 max_bit_rate; +}; + +enum { + AUDIO_SET_EVRC_ENC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, + 2, struct msm_audio_evrc_enc_config32), + AUDIO_GET_EVRC_ENC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, + 3, struct msm_audio_evrc_enc_config32) +}; + +static long evrc_in_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: + case AUDIO_STOP: { + rc = evrc_in_ioctl_shared(file, cmd, arg); + break; + } + case AUDIO_GET_EVRC_ENC_CONFIG_32: { + struct msm_audio_evrc_enc_config32 cfg_32; + struct msm_audio_evrc_enc_config *enc_cfg; + + memset(&cfg_32, 0, sizeof(cfg_32)); + + enc_cfg = audio->enc_cfg; + cfg_32.cdma_rate = enc_cfg->cdma_rate; + cfg_32.min_bit_rate = enc_cfg->min_bit_rate; + cfg_32.max_bit_rate = enc_cfg->max_bit_rate; + + if (copy_to_user((void *)arg, &cfg_32, + sizeof(cfg_32))) { + pr_err("%s: copy_to_user for AUDIO_GET_EVRC_ENC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_EVRC_ENC_CONFIG_32: { + struct msm_audio_evrc_enc_config cfg; + struct msm_audio_evrc_enc_config32 cfg_32; + + if (copy_from_user(&cfg_32, (void *) arg, + sizeof(cfg_32))) { + pr_err("%s: copy_from_user for AUDIO_SET_EVRC_ENC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + cfg.cdma_rate = cfg_32.cdma_rate; + cfg.min_bit_rate = cfg_32.min_bit_rate; + cfg.max_bit_rate = cfg_32.max_bit_rate; + cmd = AUDIO_SET_EVRC_ENC_CONFIG; + rc = evrc_in_ioctl_shared(file, cmd, (unsigned long)&cfg); + if (rc) + pr_err("%s:AUDIO_SET_EVRC_ENC_CONFIG failed. rc= %d\n", + __func__, rc); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + } + return rc; +} +#else +#define evrc_in_compat_ioctl NULL +#endif + +static int evrc_in_open(struct inode *inode, struct file *file) +{ + struct q6audio_in *audio = NULL; + struct msm_audio_evrc_enc_config *enc_cfg; + int rc = 0; + + audio = kzalloc(sizeof(struct q6audio_in), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + + /* Allocate memory for encoder config param */ + audio->enc_cfg = kzalloc(sizeof(struct msm_audio_evrc_enc_config), + GFP_KERNEL); + if (audio->enc_cfg == NULL) { + kfree(audio); + return -ENOMEM; + } + enc_cfg = audio->enc_cfg; + mutex_init(&audio->lock); + mutex_init(&audio->read_lock); + mutex_init(&audio->write_lock); + spin_lock_init(&audio->dsp_lock); + init_waitqueue_head(&audio->read_wait); + init_waitqueue_head(&audio->write_wait); + + /* Settings will be re-config at AUDIO_SET_CONFIG, + * but at least we need to have initial config + */ + audio->str_cfg.buffer_size = FRAME_SIZE; + audio->str_cfg.buffer_count = FRAME_NUM; + audio->min_frame_size = 23; + audio->max_frames_per_buf = 10; + audio->pcm_cfg.buffer_size = PCM_BUF_SIZE; + audio->pcm_cfg.buffer_count = PCM_BUF_COUNT; + enc_cfg->min_bit_rate = 4; + enc_cfg->max_bit_rate = 4; + audio->pcm_cfg.channel_count = 1; + audio->pcm_cfg.sample_rate = 8000; + audio->buf_cfg.meta_info_enable = 0x01; + audio->buf_cfg.frames_per_buf = 0x01; + audio->event_abort = 0; + + audio->ac = q6asm_audio_client_alloc((app_cb)q6asm_in_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("%s: Could not allocate memory for audio client\n", + __func__); + kfree(audio->enc_cfg); + kfree(audio); + return -ENOMEM; + } + + /* open evrc encoder in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && + (file->f_mode & FMODE_READ)) { + audio->feedback = NON_TUNNEL_MODE; + rc = q6asm_open_read_write(audio->ac, FORMAT_EVRC, + FORMAT_LINEAR_PCM); + if (rc < 0) { + pr_err("%s:session id %d: NT mode Open failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + pr_info("%s:session id %d: NT mode encoder success\n", + __func__, audio->ac->session); + } else if (!(file->f_mode & FMODE_WRITE) && + (file->f_mode & FMODE_READ)) { + audio->feedback = TUNNEL_MODE; + rc = q6asm_open_read(audio->ac, FORMAT_EVRC); + if (rc < 0) { + pr_err("%s:session id %d: T mode Open failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + /* register for tx overflow (valid for tunnel mode only) */ + rc = q6asm_reg_tx_overflow(audio->ac, 0x01); + if (rc < 0) { + pr_err("%s:session id %d: TX Overflow registration failed rc=%d\n", + __func__, + audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + pr_info("%s:session id %d: T mode encoder success\n", __func__, + audio->ac->session); + } else { + pr_err("%s:session id %d: Unexpected mode\n", __func__, + audio->ac->session); + rc = -EACCES; + goto fail; + } + + audio->opened = 1; + audio->reset_event = false; + atomic_set(&audio->in_count, PCM_BUF_COUNT); + atomic_set(&audio->out_count, 0x00); + audio->enc_compat_ioctl = evrc_in_compat_ioctl; + audio->enc_ioctl = evrc_in_ioctl; + file->private_data = audio; + + pr_info("%s:session id %d: success\n", __func__, audio->ac->session); + return 0; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio->enc_cfg); + kfree(audio); + return rc; +} + +static const struct file_operations audio_in_fops = { + .owner = THIS_MODULE, + .open = evrc_in_open, + .release = audio_in_release, + .read = audio_in_read, + .write = audio_in_write, + .unlocked_ioctl = audio_in_ioctl, + .compat_ioctl = audio_in_compat_ioctl +}; + +struct miscdevice audio_evrc_in_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_evrc_in", + .fops = &audio_in_fops, +}; + +static int __init evrc_in_init(void) +{ + return misc_register(&audio_evrc_in_misc); +} + +device_initcall(evrc_in_init); diff --git a/drivers/misc/qcom/qdsp6v2/g711alaw_in.c b/drivers/misc/qcom/qdsp6v2/g711alaw_in.c new file mode 100644 index 000000000000..bc8c0a36a825 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/g711alaw_in.c @@ -0,0 +1,382 @@ +/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "audio_utils.h" + +/* Buffer with meta*/ +#define PCM_BUF_SIZE (4096 + sizeof(struct meta_in)) + +/* Maximum 10 frames in buffer with meta */ +#define FRAME_SIZE (1 + ((320+sizeof(struct meta_out_dsp)) * 10)) +static long g711_in_ioctl_shared(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + int cnt = 0; + + switch (cmd) { + case AUDIO_START: { + struct msm_audio_g711_enc_config *enc_cfg; + + enc_cfg = (struct msm_audio_g711_enc_config *)audio->enc_cfg; + pr_debug("%s:session id %d: default buf alloc[%d]\n", __func__, + audio->ac->session, audio->buf_alloc); + if (audio->enabled == 1) { + rc = 0; + break; + } + rc = audio_in_buf_alloc(audio); + if (rc < 0) { + pr_err("%s:session id %d: buffer allocation failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + pr_debug("%s: sample rate %d", __func__, enc_cfg->sample_rate); + rc = q6asm_enc_cfg_blk_g711(audio->ac, + audio->buf_cfg.frames_per_buf, + enc_cfg->sample_rate); + + if (rc < 0) { + pr_err("%s:session id %d: cmd g711 media format block failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + if (audio->feedback == NON_TUNNEL_MODE) { + rc = q6asm_media_format_block_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + + if (rc < 0) { + pr_err("%s:session id %d: media format block failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + } + pr_debug("%s:session id %d: AUDIO_START enable[%d]\n", __func__, + audio->ac->session, audio->enabled); + rc = audio_in_enable(audio); + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("%s:session id %d: Audio Start procedure failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + while (cnt++ < audio->str_cfg.buffer_count) + q6asm_read(audio->ac); /* Push buffer to DSP */ + rc = 0; + pr_debug("%s:session id %d: AUDIO_START success enable[%d]\n", + __func__, audio->ac->session, audio->enabled); + break; + } + case AUDIO_STOP: { + pr_debug("%s:session id %d: AUDIO_STOP\n", __func__, + audio->ac->session); + rc = audio_in_disable(audio); + if (rc < 0) { + pr_err("%s:session id %d: Audio Stop procedure failed rc=%d\n", + __func__, audio->ac->session, + rc); + break; + } + break; + } + case AUDIO_SET_G711_ENC_CONFIG: { + struct msm_audio_g711_enc_config *cfg; + struct msm_audio_g711_enc_config *enc_cfg; + + enc_cfg = (struct msm_audio_g711_enc_config *)audio->enc_cfg; + + cfg = (struct msm_audio_g711_enc_config *)arg; + if (cfg == NULL) { + pr_err("%s: NULL config pointer\n", __func__); + rc = -EINVAL; + break; + } + if (cfg->sample_rate != 8000 && + cfg->sample_rate != 16000) { + pr_err("%s:session id %d: invalid sample rate\n", + __func__, audio->ac->session); + rc = -EINVAL; + break; + } + enc_cfg->sample_rate = cfg->sample_rate; + pr_debug("%s:session id %d: sample_rate= 0x%x", + __func__, + audio->ac->session, enc_cfg->sample_rate); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -ENOIOCTLCMD; + } + return rc; +} + +static long g711_in_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: + case AUDIO_STOP: { + rc = g711_in_ioctl_shared(file, cmd, arg); + break; + } + case AUDIO_GET_G711_ENC_CONFIG: { + if (copy_to_user((void *)arg, audio->enc_cfg, + sizeof(struct msm_audio_g711_enc_config))) { + pr_err( + "%s: copy_to_user for AUDIO_GET_g711_ENC_CONFIG failed", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_G711_ENC_CONFIG: { + struct msm_audio_g711_enc_config cfg; + + if (copy_from_user(&cfg, (void *) arg, + sizeof(cfg))) { + pr_err( + "%s: copy_from_user for AUDIO_GET_G711_ENC_CONFIG failed", + __func__); + rc = -EFAULT; + break; + } + rc = g711_in_ioctl_shared(file, cmd, (unsigned long)&cfg); + if (rc) + pr_err("%s:AUDIO_GET_G711_ENC_CONFIG failed. Rc= %d\n", + __func__, rc); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -ENOIOCTLCMD; + } + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_audio_g711_enc_config32 { + uint32_t sample_rate; +}; + +enum { + AUDIO_SET_G711_ENC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_g711_enc_config32), + AUDIO_GET_G711_ENC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_g711_enc_config32) +}; + +static long g711_in_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: + case AUDIO_STOP: { + rc = g711_in_ioctl_shared(file, cmd, arg); + break; + } + case AUDIO_GET_G711_ENC_CONFIG_32: { + struct msm_audio_g711_enc_config32 cfg_32; + struct msm_audio_g711_enc_config32 *enc_cfg; + + enc_cfg = (struct msm_audio_g711_enc_config32 *)audio->enc_cfg; + cfg_32.sample_rate = enc_cfg->sample_rate; + if (copy_to_user((void *)arg, &cfg_32, + sizeof(cfg_32))) { + pr_err("%s: copy_to_user for AUDIO_GET_G711_ENC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_G711_ENC_CONFIG_32: { + struct msm_audio_g711_enc_config32 cfg_32; + struct msm_audio_g711_enc_config32 cfg; + + if (copy_from_user(&cfg_32, (void *) arg, + sizeof(cfg_32))) { + pr_err("%s: copy_from_user for AUDIO_SET_G711_ENC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + cfg.sample_rate = cfg_32.sample_rate; + cmd = AUDIO_SET_G711_ENC_CONFIG; + rc = g711_in_ioctl_shared(file, cmd, (unsigned long)&cfg); + if (rc) + pr_err("%s:AUDIO_SET_G711_ENC_CONFIG failed. rc= %d\n", + __func__, rc); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -ENOIOCTLCMD; + } + return rc; +} +#else +#define g711_in_compat_ioctl NULL +#endif + +static int g711_in_open(struct inode *inode, struct file *file) +{ + struct q6audio_in *audio = NULL; + struct msm_audio_g711_enc_config *enc_cfg; + int rc = 0; + + audio = kzalloc(sizeof(struct q6audio_in), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + /* Allocate memory for encoder config param */ + audio->enc_cfg = kzalloc(sizeof(struct msm_audio_g711_enc_config), + GFP_KERNEL); + if (audio->enc_cfg == NULL) { + kfree(audio); + return -ENOMEM; + } + enc_cfg = audio->enc_cfg; + + mutex_init(&audio->lock); + mutex_init(&audio->read_lock); + mutex_init(&audio->write_lock); + spin_lock_init(&audio->dsp_lock); + init_waitqueue_head(&audio->read_wait); + init_waitqueue_head(&audio->write_wait); + + /* + * Settings will be re-config at AUDIO_SET_CONFIG, + * but at least we need to have initial config + */ + audio->str_cfg.buffer_size = FRAME_SIZE; + audio->str_cfg.buffer_count = FRAME_NUM; + audio->min_frame_size = 320; + audio->max_frames_per_buf = 10; + audio->pcm_cfg.buffer_size = PCM_BUF_SIZE; + audio->pcm_cfg.buffer_count = PCM_BUF_COUNT; + enc_cfg->sample_rate = 8000; + audio->pcm_cfg.channel_count = 1; + audio->pcm_cfg.sample_rate = 8000; + audio->buf_cfg.meta_info_enable = 0x01; + audio->buf_cfg.frames_per_buf = 0x01; + audio->event_abort = 0; + + audio->ac = q6asm_audio_client_alloc((app_cb)q6asm_in_cb, + (void *)audio); + + if (!audio->ac) { + kfree(audio->enc_cfg); + kfree(audio); + return -ENOMEM; + } + + /* open g711 encoder in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && + (file->f_mode & FMODE_READ)) { + audio->feedback = NON_TUNNEL_MODE; + rc = q6asm_open_read_write(audio->ac, FORMAT_G711_ALAW_FS, + FORMAT_LINEAR_PCM); + if (rc < 0) { + pr_err("%s:session id %d: NT mode Open failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + } else if (!(file->f_mode & FMODE_WRITE) && + (file->f_mode & FMODE_READ)) { + audio->feedback = TUNNEL_MODE; + rc = q6asm_open_read(audio->ac, FORMAT_G711_ALAW_FS); + if (rc < 0) { + pr_err("%s:session id %d: T mode Open failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + /* register for tx overflow (valid for tunnel mode only) */ + rc = q6asm_reg_tx_overflow(audio->ac, 0x01); + if (rc < 0) { + pr_err("%s:session id %d: TX Overflow registration failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + } else { + pr_err("%s:session id %d: Unexpected mode\n", __func__, + audio->ac->session); + rc = -EACCES; + goto fail; + } + + audio->opened = 1; + audio->reset_event = false; + atomic_set(&audio->in_count, PCM_BUF_COUNT); + atomic_set(&audio->out_count, 0x00); + audio->enc_compat_ioctl = g711_in_compat_ioctl; + audio->enc_ioctl = g711_in_ioctl; + file->private_data = audio; + + pr_info("%s:session id %d: success\n", __func__, audio->ac->session); + return 0; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio->enc_cfg); + kfree(audio); + return rc; +} + +static const struct file_operations audio_in_fops = { + .owner = THIS_MODULE, + .open = g711_in_open, + .release = audio_in_release, + .read = audio_in_read, + .write = audio_in_write, + .unlocked_ioctl = audio_in_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = audio_in_compat_ioctl, +#endif +}; + +struct miscdevice audio_g711alaw_in_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_g711alaw_in", + .fops = &audio_in_fops, +}; + +static int __init g711alaw_in_init(void) +{ + return misc_register(&audio_g711alaw_in_misc); +} + +device_initcall(g711alaw_in_init); diff --git a/drivers/misc/qcom/qdsp6v2/g711mlaw_in.c b/drivers/misc/qcom/qdsp6v2/g711mlaw_in.c new file mode 100644 index 000000000000..b92c44957377 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/g711mlaw_in.c @@ -0,0 +1,385 @@ +/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "audio_utils.h" + +#ifdef CONFIG_COMPAT +#undef PROC_ADD +#endif +/* Buffer with meta*/ +#define PCM_BUF_SIZE (4096 + sizeof(struct meta_in)) + +/* Maximum 10 frames in buffer with meta */ +#define FRAME_SIZE (1 + ((320+sizeof(struct meta_out_dsp)) * 10)) +static long g711_in_ioctl_shared(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + int cnt = 0; + + switch (cmd) { + case AUDIO_START: { + struct msm_audio_g711_enc_config *enc_cfg; + + enc_cfg = (struct msm_audio_g711_enc_config *)audio->enc_cfg; + pr_debug("%s:session id %d: default buf alloc[%d]\n", __func__, + audio->ac->session, audio->buf_alloc); + if (audio->enabled == 1) { + rc = 0; + break; + } + rc = audio_in_buf_alloc(audio); + if (rc < 0) { + pr_err("%s:session id %d: buffer allocation failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + pr_debug("%s: sample rate %d", __func__, enc_cfg->sample_rate); + rc = q6asm_enc_cfg_blk_g711(audio->ac, + audio->buf_cfg.frames_per_buf, + enc_cfg->sample_rate); + + if (rc < 0) { + pr_err("%s:session id %d: cmd g711 media format block failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + if (audio->feedback == NON_TUNNEL_MODE) { + rc = q6asm_media_format_block_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + + if (rc < 0) { + pr_err("%s:session id %d: media format block failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + } + pr_debug("%s:session id %d: AUDIO_START enable[%d]\n", __func__, + audio->ac->session, audio->enabled); + rc = audio_in_enable(audio); + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("%s:session id %d: Audio Start procedure failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + while (cnt++ < audio->str_cfg.buffer_count) + q6asm_read(audio->ac); /* Push buffer to DSP */ + rc = 0; + pr_debug("%s:session id %d: AUDIO_START success enable[%d]\n", + __func__, audio->ac->session, audio->enabled); + break; + } + case AUDIO_STOP: { + pr_debug("%s:session id %d: AUDIO_STOP\n", __func__, + audio->ac->session); + rc = audio_in_disable(audio); + if (rc < 0) { + pr_err("%s:session id %d: Audio Stop procedure failed rc=%d\n", + __func__, audio->ac->session, + rc); + break; + } + break; + } + case AUDIO_SET_G711_ENC_CONFIG: { + struct msm_audio_g711_enc_config *cfg; + struct msm_audio_g711_enc_config *enc_cfg; + + enc_cfg = (struct msm_audio_g711_enc_config *)audio->enc_cfg; + + cfg = (struct msm_audio_g711_enc_config *)arg; + if (cfg == NULL) { + pr_err("%s: NULL config pointer\n", __func__); + rc = -EINVAL; + break; + } + if (cfg->sample_rate != 8000 && + cfg->sample_rate != 16000) { + pr_err("%s:session id %d: invalid sample rate\n", + __func__, audio->ac->session); + rc = -EINVAL; + break; + } + enc_cfg->sample_rate = cfg->sample_rate; + pr_debug("%s:session id %d: sample_rate= 0x%x", + __func__, + audio->ac->session, enc_cfg->sample_rate); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -ENOIOCTLCMD; + } + return rc; +} + +static long g711_in_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: + case AUDIO_STOP: { + rc = g711_in_ioctl_shared(file, cmd, arg); + break; + } + case AUDIO_GET_G711_ENC_CONFIG: { + if (copy_to_user((void *)arg, audio->enc_cfg, + sizeof(struct msm_audio_g711_enc_config))) { + pr_err( + "%s: copy_to_user for AUDIO_GET_g711_ENC_CONFIG failed", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_G711_ENC_CONFIG: { + struct msm_audio_g711_enc_config cfg; + + if (copy_from_user(&cfg, (void *) arg, + sizeof(cfg))) { + pr_err( + "%s: copy_from_user for AUDIO_GET_G711_ENC_CONFIG failed", + __func__); + rc = -EFAULT; + break; + } + rc = g711_in_ioctl_shared(file, cmd, (unsigned long)&cfg); + if (rc) + pr_err("%s:AUDIO_GET_G711_ENC_CONFIG failed. Rc= %d\n", + __func__, rc); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -ENOIOCTLCMD; + } + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_audio_g711_enc_config32 { + uint32_t sample_rate; +}; + +enum { + AUDIO_SET_G711_ENC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_g711_enc_config32), + AUDIO_GET_G711_ENC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_g711_enc_config32) +}; + +static long g711_in_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: + case AUDIO_STOP: { + rc = g711_in_ioctl_shared(file, cmd, arg); + break; + } + case AUDIO_GET_G711_ENC_CONFIG_32: { + struct msm_audio_g711_enc_config32 cfg_32; + struct msm_audio_g711_enc_config32 *enc_cfg; + + enc_cfg = (struct msm_audio_g711_enc_config32 *)audio->enc_cfg; + cfg_32.sample_rate = enc_cfg->sample_rate; + if (copy_to_user((void *)arg, &cfg_32, + sizeof(cfg_32))) { + pr_err("%s: copy_to_user for AUDIO_GET_G711_ENC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_G711_ENC_CONFIG_32: { + struct msm_audio_g711_enc_config32 cfg_32; + struct msm_audio_g711_enc_config32 cfg; + + if (copy_from_user(&cfg_32, (void *) arg, + sizeof(cfg_32))) { + pr_err("%s: copy_from_user for AUDIO_SET_G711_ENC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + cfg.sample_rate = cfg_32.sample_rate; + cmd = AUDIO_SET_G711_ENC_CONFIG; + rc = g711_in_ioctl_shared(file, cmd, (unsigned long)&cfg); + if (rc) + pr_err("%s:AUDIO_SET_G711_ENC_CONFIG failed. rc= %d\n", + __func__, rc); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -ENOIOCTLCMD; + } + return rc; +} +#else +#define g711_in_compat_ioctl NULL +#endif + +static int g711_in_open(struct inode *inode, struct file *file) +{ + struct q6audio_in *audio = NULL; + struct msm_audio_g711_enc_config *enc_cfg; + int rc = 0; + + audio = kzalloc(sizeof(struct q6audio_in), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + /* Allocate memory for encoder config param */ + audio->enc_cfg = kzalloc(sizeof(struct msm_audio_g711_enc_config), + GFP_KERNEL); + if (audio->enc_cfg == NULL) { + kfree(audio); + return -ENOMEM; + } + enc_cfg = audio->enc_cfg; + + mutex_init(&audio->lock); + mutex_init(&audio->read_lock); + mutex_init(&audio->write_lock); + spin_lock_init(&audio->dsp_lock); + init_waitqueue_head(&audio->read_wait); + init_waitqueue_head(&audio->write_wait); + + /* + * Settings will be re-config at AUDIO_SET_CONFIG, + * but at least we need to have initial config + */ + audio->str_cfg.buffer_size = FRAME_SIZE; + audio->str_cfg.buffer_count = FRAME_NUM; + audio->min_frame_size = 320; + audio->max_frames_per_buf = 10; + audio->pcm_cfg.buffer_size = PCM_BUF_SIZE; + audio->pcm_cfg.buffer_count = PCM_BUF_COUNT; + enc_cfg->sample_rate = 8000; + audio->pcm_cfg.channel_count = 1; + audio->pcm_cfg.sample_rate = 8000; + audio->buf_cfg.meta_info_enable = 0x01; + audio->buf_cfg.frames_per_buf = 0x01; + audio->event_abort = 0; + + audio->ac = q6asm_audio_client_alloc((app_cb)q6asm_in_cb, + (void *)audio); + + if (!audio->ac) { + kfree(audio->enc_cfg); + kfree(audio); + return -ENOMEM; + } + + /* open g711 encoder in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && + (file->f_mode & FMODE_READ)) { + audio->feedback = NON_TUNNEL_MODE; + rc = q6asm_open_read_write(audio->ac, FORMAT_G711_MLAW_FS, + FORMAT_LINEAR_PCM); + if (rc < 0) { + pr_err("%s:session id %d: NT mode Open failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + } else if (!(file->f_mode & FMODE_WRITE) && + (file->f_mode & FMODE_READ)) { + audio->feedback = TUNNEL_MODE; + rc = q6asm_open_read(audio->ac, FORMAT_G711_MLAW_FS); + if (rc < 0) { + pr_err("%s:session id %d: T mode Open failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + /* register for tx overflow (valid for tunnel mode only) */ + rc = q6asm_reg_tx_overflow(audio->ac, 0x01); + if (rc < 0) { + pr_err("%s:session id %d: TX Overflow registration failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + } else { + pr_err("%s:session id %d: Unexpected mode\n", __func__, + audio->ac->session); + rc = -EACCES; + goto fail; + } + + audio->opened = 1; + audio->reset_event = false; + atomic_set(&audio->in_count, PCM_BUF_COUNT); + atomic_set(&audio->out_count, 0x00); + audio->enc_compat_ioctl = g711_in_compat_ioctl; + audio->enc_ioctl = g711_in_ioctl; + file->private_data = audio; + + pr_info("%s:session id %d: success\n", __func__, audio->ac->session); + return 0; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio->enc_cfg); + kfree(audio); + return rc; +} + +static const struct file_operations audio_in_fops = { + .owner = THIS_MODULE, + .open = g711_in_open, + .release = audio_in_release, + .read = audio_in_read, + .write = audio_in_write, + .unlocked_ioctl = audio_in_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = audio_in_compat_ioctl, +#endif +}; + +struct miscdevice audio_g711mlaw_in_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_g711mlaw_in", + .fops = &audio_in_fops, +}; + +static int __init g711mlaw_in_init(void) +{ + return misc_register(&audio_g711mlaw_in_misc); +} + +device_initcall(g711mlaw_in_init); diff --git a/drivers/misc/qcom/qdsp6v2/q6audio_common.h b/drivers/misc/qcom/qdsp6v2/q6audio_common.h new file mode 100644 index 000000000000..49b88b793cc3 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/q6audio_common.h @@ -0,0 +1,37 @@ +/* Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + + +/* For Decoders */ +#ifndef __Q6_AUDIO_COMMON_H__ +#define __Q6_AUDIO_COMMON_H__ + +#include +#include + + +void q6_audio_cb(uint32_t opcode, uint32_t token, + uint32_t *payload, void *priv); + +void audio_aio_cb(uint32_t opcode, uint32_t token, + uint32_t *payload, void *audio); + + +/* For Encoders */ +void q6asm_in_cb(uint32_t opcode, uint32_t token, + uint32_t *payload, void *priv); + +void audio_in_get_dsp_frames(void *audio, + uint32_t token, uint32_t *payload); + +#endif /*__Q6_AUDIO_COMMON_H__*/ diff --git a/drivers/misc/qcom/qdsp6v2/q6audio_v2.c b/drivers/misc/qcom/qdsp6v2/q6audio_v2.c new file mode 100644 index 000000000000..ea3113217281 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/q6audio_v2.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2012-2013, 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "audio_utils.h" + +void q6asm_in_cb(uint32_t opcode, uint32_t token, + uint32_t *payload, void *priv) +{ + struct q6audio_in *audio = (struct q6audio_in *)priv; + unsigned long flags; + + pr_debug("%s:session id %d: opcode[0x%x]\n", __func__, + audio->ac->session, opcode); + + spin_lock_irqsave(&audio->dsp_lock, flags); + switch (opcode) { + case ASM_DATA_EVENT_READ_DONE_V2: + audio_in_get_dsp_frames(audio, token, payload); + break; + case ASM_DATA_EVENT_WRITE_DONE_V2: + atomic_inc(&audio->in_count); + wake_up(&audio->write_wait); + break; + case ASM_DATA_EVENT_RENDERED_EOS: + audio->eos_rsp = 1; + wake_up(&audio->read_wait); + break; + case ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2: + break; + case ASM_SESSION_EVENTX_OVERFLOW: + pr_err("%s:session id %d: ASM_SESSION_EVENT_TX_OVERFLOW\n", + __func__, audio->ac->session); + break; + case RESET_EVENTS: + pr_debug("%s:received RESET EVENTS\n", __func__); + audio->enabled = 0; + audio->stopped = 1; + audio->event_abort = 1; + audio->reset_event = true; + wake_up(&audio->read_wait); + wake_up(&audio->write_wait); + break; + default: + pr_debug("%s:session id %d: Ignore opcode[0x%x]\n", __func__, + audio->ac->session, opcode); + break; + } + spin_unlock_irqrestore(&audio->dsp_lock, flags); +} + +void audio_in_get_dsp_frames(void *priv, + uint32_t token, uint32_t *payload) +{ + struct q6audio_in *audio = (struct q6audio_in *)priv; + uint32_t index; + + index = q6asm_get_buf_index_from_token(token); + pr_debug("%s:session id %d: index=%d nr frames=%d offset[%d]\n", + __func__, audio->ac->session, token, payload[9], + payload[5]); + pr_debug("%s:session id %d: timemsw=%d lsw=%d\n", __func__, + audio->ac->session, payload[7], payload[6]); + pr_debug("%s:session id %d: uflags=0x%8x uid=0x%8x\n", __func__, + audio->ac->session, payload[8], payload[10]); + pr_debug("%s:session id %d: enc_framesotal_size=0x%8x\n", __func__, + audio->ac->session, payload[4]); + + /* Ensure the index is within max array size: FRAME_NUM */ + if (index >= FRAME_NUM) { + pr_err("%s: Invalid index %d\n", + __func__, index); + return; + } + + audio->out_frame_info[index][0] = payload[9]; + audio->out_frame_info[index][1] = payload[5]; + + /* statistics of read */ + atomic_add(payload[4], &audio->in_bytes); + atomic_add(payload[9], &audio->in_samples); + + if (atomic_read(&audio->out_count) <= audio->str_cfg.buffer_count) { + atomic_inc(&audio->out_count); + wake_up(&audio->read_wait); + } +} diff --git a/drivers/misc/qcom/qdsp6v2/q6audio_v2_aio.c b/drivers/misc/qcom/qdsp6v2/q6audio_v2_aio.c new file mode 100644 index 000000000000..9f764587888b --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/q6audio_v2_aio.c @@ -0,0 +1,223 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "audio_utils_aio.h" + +void q6_audio_cb(uint32_t opcode, uint32_t token, + uint32_t *payload, void *priv) +{ + struct q6audio_aio *audio = (struct q6audio_aio *)priv; + + pr_debug("%s:opcode = %x token = 0x%x\n", __func__, opcode, token); + switch (opcode) { + case ASM_DATA_EVENT_WRITE_DONE_V2: + case ASM_DATA_EVENT_READ_DONE_V2: + case ASM_DATA_EVENT_RENDERED_EOS: + case ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2: + case ASM_STREAM_CMD_SET_ENCDEC_PARAM: + case ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY: + case ASM_DATA_EVENT_ENC_SR_CM_CHANGE_NOTIFY: + case RESET_EVENTS: + audio_aio_cb(opcode, token, payload, audio); + break; + default: + pr_debug("%s:Unhandled event = 0x%8x\n", __func__, opcode); + break; + } +} + +void audio_aio_cb(uint32_t opcode, uint32_t token, + uint32_t *payload, void *priv/*struct q6audio_aio *audio*/) +{ + struct q6audio_aio *audio = (struct q6audio_aio *)priv; + union msm_audio_event_payload e_payload; + + switch (opcode) { + case ASM_DATA_EVENT_WRITE_DONE_V2: + pr_debug("%s[%pK]:ASM_DATA_EVENT_WRITE_DONE token = 0x%x\n", + __func__, audio, token); + audio_aio_async_write_ack(audio, token, payload); + break; + case ASM_DATA_EVENT_READ_DONE_V2: + pr_debug("%s[%pK]:ASM_DATA_EVENT_READ_DONE token = 0x%x\n", + __func__, audio, token); + audio_aio_async_read_ack(audio, token, payload); + break; + case ASM_DATA_EVENT_RENDERED_EOS: + /* EOS Handle */ + pr_debug("%s[%pK]:ASM_DATA_CMDRSP_EOS\n", __func__, audio); + if (audio->feedback) { /* Non-Tunnel mode */ + audio->eos_rsp = 1; + /* propagate input EOS i/p buffer, + * after receiving DSP acknowledgment + */ + if (audio->eos_flag && + (audio->eos_write_payload.aio_buf.buf_addr)) { + audio_aio_post_event(audio, + AUDIO_EVENT_WRITE_DONE, + audio->eos_write_payload); + memset(&audio->eos_write_payload, 0, + sizeof(union msm_audio_event_payload)); + audio->eos_flag = 0; + } + } else { /* Tunnel mode */ + audio->eos_rsp = 1; + wake_up(&audio->write_wait); + wake_up(&audio->cmd_wait); + } + break; + case ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2: + case ASM_STREAM_CMD_SET_ENCDEC_PARAM: + pr_debug("%s[%pK]:payload0[%x] payloa1d[%x]opcode= 0x%x\n", + __func__, audio, payload[0], payload[1], opcode); + break; + case ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY: + case ASM_DATA_EVENT_ENC_SR_CM_CHANGE_NOTIFY: + pr_debug("%s[%pK]: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, payload[0]-sr = %d, payload[1]-chl = %d, payload[2] = %d, payload[3] = %d\n", + __func__, audio, payload[0], + payload[1], payload[2], payload[3]); + + pr_debug("%s[%pK]: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, sr(prev) = %d, chl(prev) = %d,", + __func__, audio, audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + + audio->pcm_cfg.sample_rate = payload[0]; + audio->pcm_cfg.channel_count = payload[1] & 0xFFFF; + e_payload.stream_info.chan_info = audio->pcm_cfg.channel_count; + e_payload.stream_info.sample_rate = audio->pcm_cfg.sample_rate; + audio_aio_post_event(audio, AUDIO_EVENT_STREAM_INFO, e_payload); + break; + case RESET_EVENTS: + pr_err("%s: Received opcode:0x%x\n", __func__, opcode); + audio->stopped = 1; + audio->reset_event = true; + wake_up(&audio->event_wait); + break; + default: + break; + } +} + +void extract_meta_out_info(struct q6audio_aio *audio, + struct audio_aio_buffer_node *buf_node, int dir) +{ + struct dec_meta_out *meta_data = buf_node->kvaddr; + uint32_t temp; + + if (dir) { /* input buffer - Write */ + if (audio->buf_cfg.meta_info_enable) + memcpy(&buf_node->meta_info.meta_in, + (char *)buf_node->kvaddr, sizeof(struct dec_meta_in)); + else + memset(&buf_node->meta_info.meta_in, + 0, sizeof(struct dec_meta_in)); + pr_debug("%s[%pK]:i/p: msw_ts %d lsw_ts %d nflags 0x%8x\n", + __func__, audio, + buf_node->meta_info.meta_in.ntimestamp.highpart, + buf_node->meta_info.meta_in.ntimestamp.lowpart, + buf_node->meta_info.meta_in.nflags); + } else { /* output buffer - Read */ + memcpy((char *)buf_node->kvaddr, + &buf_node->meta_info.meta_out, + sizeof(struct dec_meta_out)); + meta_data->meta_out_dsp[0].nflags = 0x00000000; + temp = meta_data->meta_out_dsp[0].msw_ts; + meta_data->meta_out_dsp[0].msw_ts = + meta_data->meta_out_dsp[0].lsw_ts; + meta_data->meta_out_dsp[0].lsw_ts = temp; + + pr_debug("%s[%pK]:o/p: msw_ts %d lsw_ts %d nflags 0x%8x, num_frames = %d\n", + __func__, audio, + ((struct dec_meta_out *)buf_node->kvaddr)-> + meta_out_dsp[0].msw_ts, + ((struct dec_meta_out *)buf_node->kvaddr)-> + meta_out_dsp[0].lsw_ts, + ((struct dec_meta_out *)buf_node->kvaddr)-> + meta_out_dsp[0].nflags, + ((struct dec_meta_out *)buf_node->kvaddr)->num_of_frames); + } +} + +/* Read buffer from DSP / Handle Ack from DSP */ +void audio_aio_async_read_ack(struct q6audio_aio *audio, uint32_t token, + uint32_t *payload) +{ + unsigned long flags; + union msm_audio_event_payload event_payload; + struct audio_aio_buffer_node *filled_buf; + + pr_debug("%s\n", __func__); + + /* No active flush in progress */ + if (audio->rflush) + return; + + /* Statistics of read */ + atomic_add(payload[4], &audio->in_bytes); + atomic_add(payload[9], &audio->in_samples); + + spin_lock_irqsave(&audio->dsp_lock, flags); + if (list_empty(&audio->in_queue)) { + spin_unlock_irqrestore(&audio->dsp_lock, flags); + pr_warn("%s unexpected ack from dsp\n", __func__); + return; + } + filled_buf = list_first_entry(&audio->in_queue, + struct audio_aio_buffer_node, list); + + pr_debug("%s token: 0x[%x], filled_buf->token: 0x[%x]", + __func__, token, filled_buf->token); + if (token == (filled_buf->token)) { + list_del(&filled_buf->list); + spin_unlock_irqrestore(&audio->dsp_lock, flags); + event_payload.aio_buf = filled_buf->buf; + /* Read done Buffer due to flush/normal condition + * after EOS event, so append EOS buffer + */ + if (audio->eos_rsp == 0x1) { + event_payload.aio_buf.data_len = + insert_eos_buf(audio, filled_buf); + /* Reset flag back to indicate eos intimated */ + audio->eos_rsp = 0; + } else { + filled_buf->meta_info.meta_out.num_of_frames + = payload[9]; + event_payload.aio_buf.data_len = payload[4] + + payload[5] + sizeof(struct dec_meta_out); + pr_debug("%s[%pK]:nr of frames 0x%8x len=%d\n", + __func__, audio, + filled_buf->meta_info.meta_out.num_of_frames, + event_payload.aio_buf.data_len); + extract_meta_out_info(audio, filled_buf, 0); + audio->eos_rsp = 0; + } + pr_debug("%s, posting read done to the app here\n", __func__); + audio_aio_post_event(audio, AUDIO_EVENT_READ_DONE, + event_payload); + kfree(filled_buf); + } else { + pr_err("%s[%pK]:expected=%x ret=%x\n", + __func__, audio, filled_buf->token, token); + spin_unlock_irqrestore(&audio->dsp_lock, flags); + } +} diff --git a/drivers/misc/qcom/qdsp6v2/qcelp_in.c b/drivers/misc/qcom/qdsp6v2/qcelp_in.c new file mode 100644 index 000000000000..da5520f75a62 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/qcelp_in.c @@ -0,0 +1,410 @@ +/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "audio_utils.h" + +/* Buffer with meta*/ +#define PCM_BUF_SIZE (4096 + sizeof(struct meta_in)) + +/* Maximum 10 frames in buffer with meta */ +#define FRAME_SIZE (1 + ((35+sizeof(struct meta_out_dsp)) * 10)) + +static long qcelp_in_ioctl_shared(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + int cnt = 0; + + switch (cmd) { + case AUDIO_START: { + struct msm_audio_qcelp_enc_config *enc_cfg; + + enc_cfg = audio->enc_cfg; + pr_debug("%s:session id %d: default buf alloc[%d]\n", __func__, + audio->ac->session, audio->buf_alloc); + if (audio->enabled == 1) { + pr_info("%s:AUDIO_START already over\n", __func__); + rc = 0; + break; + } + rc = audio_in_buf_alloc(audio); + if (rc < 0) { + pr_err("%s:session id %d: buffer allocation failed\n", + __func__, audio->ac->session); + break; + } + + /* reduced_rate_level, rate_modulation_cmd set to zero + * currently not configurable from user space + */ + rc = q6asm_enc_cfg_blk_qcelp(audio->ac, + audio->buf_cfg.frames_per_buf, + enc_cfg->min_bit_rate, + enc_cfg->max_bit_rate, 0, 0); + + if (rc < 0) { + pr_err("%s:session id %d: cmd qcelp media format block failed\n", + __func__, audio->ac->session); + break; + } + if (audio->feedback == NON_TUNNEL_MODE) { + rc = q6asm_media_format_block_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); + + if (rc < 0) { + pr_err("%s:session id %d: media format block failed\n", + __func__, audio->ac->session); + break; + } + } + pr_debug("%s:session id %d: AUDIO_START enable[%d]\n", __func__, + audio->ac->session, audio->enabled); + rc = audio_in_enable(audio); + if (!rc) { + audio->enabled = 1; + } else { + audio->enabled = 0; + pr_err("%s:session id %d: Audio Start procedure failed rc=%d\n", + __func__, audio->ac->session, rc); + break; + } + while (cnt++ < audio->str_cfg.buffer_count) + q6asm_read(audio->ac); /* Push buffer to DSP */ + rc = 0; + pr_debug("%s:session id %d: AUDIO_START success enable[%d]\n", + __func__, audio->ac->session, audio->enabled); + break; + } + case AUDIO_STOP: { + pr_debug("%s:session id %d: AUDIO_STOP\n", __func__, + audio->ac->session); + rc = audio_in_disable(audio); + if (rc < 0) { + pr_err("%s:session id %d: Audio Stop procedure failed rc=%d\n", + __func__, audio->ac->session, + rc); + break; + } + break; + } + case AUDIO_SET_QCELP_ENC_CONFIG: { + struct msm_audio_qcelp_enc_config *cfg; + struct msm_audio_qcelp_enc_config *enc_cfg; + + enc_cfg = audio->enc_cfg; + cfg = (struct msm_audio_qcelp_enc_config *)arg; + if (cfg == NULL) { + pr_err("%s: NULL config pointer\n", __func__); + rc = -EINVAL; + break; + } + if (cfg->min_bit_rate > 4 || + cfg->min_bit_rate < 1) { + pr_err("%s:session id %d: invalid min bitrate\n", + __func__, audio->ac->session); + rc = -EINVAL; + break; + } + if (cfg->max_bit_rate > 4 || + cfg->max_bit_rate < 1) { + pr_err("%s:session id %d: invalid max bitrate\n", + __func__, audio->ac->session); + rc = -EINVAL; + break; + } + enc_cfg->cdma_rate = cfg->cdma_rate; + enc_cfg->min_bit_rate = cfg->min_bit_rate; + enc_cfg->max_bit_rate = cfg->max_bit_rate; + pr_debug("%s:session id %d: min_bit_rate= 0x%x max_bit_rate=0x%x\n", + __func__, + audio->ac->session, enc_cfg->min_bit_rate, + enc_cfg->max_bit_rate); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + } + return rc; +} + +static long qcelp_in_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: + case AUDIO_STOP: { + rc = qcelp_in_ioctl_shared(file, cmd, arg); + break; + } + case AUDIO_GET_QCELP_ENC_CONFIG: { + if (copy_to_user((void *)arg, audio->enc_cfg, + sizeof(struct msm_audio_qcelp_enc_config))) { + pr_err( + "%s: copy_to_user for AUDIO_GET_QCELP_ENC_CONFIG failed", + __func__); + rc = -EFAULT; + } + break; + } + case AUDIO_SET_QCELP_ENC_CONFIG: { + struct msm_audio_qcelp_enc_config cfg; + + if (copy_from_user(&cfg, (void *) arg, + sizeof(cfg))) { + pr_err( + "%s: copy_from_user for AUDIO_SET_QCELP_ENC_CONFIG failed", + __func__); + rc = -EFAULT; + break; + } + rc = qcelp_in_ioctl_shared(file, cmd, (unsigned long)&cfg); + if (rc) + pr_err("%s:AUDIO_SET_QCELP_ENC_CONFIG failed. Rc= %d\n", + __func__, rc); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + } + return rc; +} + +#ifdef CONFIG_COMPAT +struct msm_audio_qcelp_enc_config32 { + u32 cdma_rate; + u32 min_bit_rate; + u32 max_bit_rate; +}; + +enum { + AUDIO_SET_QCELP_ENC_CONFIG_32 = _IOW(AUDIO_IOCTL_MAGIC, + 0, struct msm_audio_qcelp_enc_config32), + AUDIO_GET_QCELP_ENC_CONFIG_32 = _IOR(AUDIO_IOCTL_MAGIC, + 1, struct msm_audio_qcelp_enc_config32) +}; + +static long qcelp_in_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6audio_in *audio = file->private_data; + int rc = 0; + + switch (cmd) { + case AUDIO_START: + case AUDIO_STOP: { + rc = qcelp_in_ioctl_shared(file, cmd, arg); + break; + } + case AUDIO_GET_QCELP_ENC_CONFIG_32: { + struct msm_audio_qcelp_enc_config32 cfg_32; + struct msm_audio_qcelp_enc_config *enc_cfg; + + memset(&cfg_32, 0, sizeof(cfg_32)); + + enc_cfg = (struct msm_audio_qcelp_enc_config *)audio->enc_cfg; + cfg_32.cdma_rate = enc_cfg->cdma_rate; + cfg_32.min_bit_rate = enc_cfg->min_bit_rate; + cfg_32.max_bit_rate = enc_cfg->max_bit_rate; + if (copy_to_user((void *)arg, &cfg_32, + sizeof(cfg_32))) { + pr_err("%s: copy_to_user for AUDIO_GET_QCELP_ENC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; +} + break; + } + case AUDIO_SET_QCELP_ENC_CONFIG_32: { + struct msm_audio_qcelp_enc_config32 cfg_32; + struct msm_audio_qcelp_enc_config cfg; + + if (copy_from_user(&cfg_32, (void *) arg, + sizeof(cfg_32))) { + pr_err("%s: copy_from_user for AUDIO_SET_QCELP_ENC_CONFIG_32 failed\n", + __func__); + rc = -EFAULT; + break; + } + cfg.cdma_rate = cfg_32.cdma_rate; + cfg.min_bit_rate = cfg_32.min_bit_rate; + cfg.max_bit_rate = cfg_32.max_bit_rate; + cmd = AUDIO_SET_QCELP_ENC_CONFIG; + rc = qcelp_in_ioctl_shared(file, cmd, (unsigned long)&cfg); + if (rc) + pr_err("%s:AUDIO_SET_QCELP_ENC_CONFIG failed. rc= %d\n", + __func__, rc); + break; + } + default: + pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + rc = -EINVAL; + } + return rc; +} +#else +#define qcelp_in_compat_ioctl NULL +#endif + +static int qcelp_in_open(struct inode *inode, struct file *file) +{ + struct q6audio_in *audio = NULL; + struct msm_audio_qcelp_enc_config *enc_cfg; + int rc = 0; + + audio = kzalloc(sizeof(struct q6audio_in), GFP_KERNEL); + + if (audio == NULL) + return -ENOMEM; + + /* Allocate memory for encoder config param */ + audio->enc_cfg = kzalloc(sizeof(struct msm_audio_qcelp_enc_config), + GFP_KERNEL); + if (audio->enc_cfg == NULL) { + kfree(audio); + return -ENOMEM; + } + enc_cfg = audio->enc_cfg; + + mutex_init(&audio->lock); + mutex_init(&audio->read_lock); + mutex_init(&audio->write_lock); + spin_lock_init(&audio->dsp_lock); + init_waitqueue_head(&audio->read_wait); + init_waitqueue_head(&audio->write_wait); + + /* Settings will be re-config at AUDIO_SET_CONFIG, + * but at least we need to have initial config + */ + audio->str_cfg.buffer_size = FRAME_SIZE; + audio->str_cfg.buffer_count = FRAME_NUM; + audio->min_frame_size = 35; + audio->max_frames_per_buf = 10; + audio->pcm_cfg.buffer_size = PCM_BUF_SIZE; + audio->pcm_cfg.buffer_count = PCM_BUF_COUNT; + enc_cfg->min_bit_rate = 4; + enc_cfg->max_bit_rate = 4; + audio->pcm_cfg.channel_count = 1; + audio->pcm_cfg.sample_rate = 8000; + audio->buf_cfg.meta_info_enable = 0x01; + audio->buf_cfg.frames_per_buf = 0x01; + audio->event_abort = 0; + + audio->ac = q6asm_audio_client_alloc((app_cb)q6asm_in_cb, + (void *)audio); + + if (!audio->ac) { + pr_err("%s: Could not allocate memory for audio client\n", + __func__); + kfree(audio->enc_cfg); + kfree(audio); + return -ENOMEM; + } + + /* open qcelp encoder in T/NT mode */ + if ((file->f_mode & FMODE_WRITE) && + (file->f_mode & FMODE_READ)) { + audio->feedback = NON_TUNNEL_MODE; + rc = q6asm_open_read_write(audio->ac, FORMAT_V13K, + FORMAT_LINEAR_PCM); + if (rc < 0) { + pr_err("%s:session id %d: NT mode Open failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + pr_info("%s:session id %d: NT mode encoder success\n", __func__, + audio->ac->session); + } else if (!(file->f_mode & FMODE_WRITE) && + (file->f_mode & FMODE_READ)) { + audio->feedback = TUNNEL_MODE; + rc = q6asm_open_read(audio->ac, FORMAT_V13K); + if (rc < 0) { + pr_err("%s:session id %d: T mode Open failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + /* register for tx overflow (valid for tunnel mode only) */ + rc = q6asm_reg_tx_overflow(audio->ac, 0x01); + if (rc < 0) { + pr_err("%s:session id %d: TX Overflow registration failed rc=%d\n", + __func__, audio->ac->session, rc); + rc = -ENODEV; + goto fail; + } + pr_info("%s:session id %d: T mode encoder success\n", __func__, + audio->ac->session); + } else { + pr_err("%s:session id %d: Unexpected mode\n", __func__, + audio->ac->session); + rc = -EACCES; + goto fail; + } + + audio->opened = 1; + audio->reset_event = false; + atomic_set(&audio->in_count, PCM_BUF_COUNT); + atomic_set(&audio->out_count, 0x00); + audio->enc_compat_ioctl = qcelp_in_compat_ioctl; + audio->enc_ioctl = qcelp_in_ioctl; + file->private_data = audio; + + pr_info("%s:session id %d: success\n", __func__, audio->ac->session); + return 0; +fail: + q6asm_audio_client_free(audio->ac); + kfree(audio->enc_cfg); + kfree(audio); + return rc; +} + +static const struct file_operations audio_in_fops = { + .owner = THIS_MODULE, + .open = qcelp_in_open, + .release = audio_in_release, + .read = audio_in_read, + .write = audio_in_write, + .unlocked_ioctl = audio_in_ioctl, + .compat_ioctl = audio_in_compat_ioctl +}; + +struct miscdevice audio_qcelp_in_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_qcelp_in", + .fops = &audio_in_fops, +}; + +static int __init qcelp_in_init(void) +{ + return misc_register(&audio_qcelp_in_misc); +} + +device_initcall(qcelp_in_init); diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/Makefile b/drivers/misc/qcom/qdsp6v2/ultrasound/Makefile new file mode 100644 index 000000000000..41f614aa4eb3 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/ultrasound/Makefile @@ -0,0 +1,2 @@ +ccflags-y := -I$(src)/.. +obj-$(CONFIG_MSM_ULTRASOUND) += usf.o usfcdev.o q6usm.o diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c b/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c new file mode 100644 index 000000000000..f20f335be3cb --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c @@ -0,0 +1,1467 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "q6usm.h" + +#define ADSP_MEMORY_MAP_SHMEM8_4K_POOL 3 + +#define MEM_4K_OFFSET 4095 +#define MEM_4K_MASK 0xfffff000 + +#define USM_SESSION_MAX 0x02 /* aDSP:USM limit */ + +#define READDONE_IDX_STATUS 0 + +#define WRITEDONE_IDX_STATUS 0 + +/* Standard timeout in the asynchronous ops */ +#define Q6USM_TIMEOUT_JIFFIES (1*HZ) /* 1 sec */ + +static DEFINE_MUTEX(session_lock); + +static struct us_client *session[USM_SESSION_MAX]; +static int32_t q6usm_mmapcallback(struct apr_client_data *data, void *priv); +static int32_t q6usm_callback(struct apr_client_data *data, void *priv); +static void q6usm_add_hdr(struct us_client *usc, struct apr_hdr *hdr, + uint32_t pkt_size, bool cmd_flg); + +struct usm_mmap { + atomic_t ref_cnt; + atomic_t cmd_state; + wait_queue_head_t cmd_wait; + void *apr; + int mem_handle; +}; + +static struct usm_mmap this_mmap; + +static void q6usm_add_mmaphdr(struct apr_hdr *hdr, + uint32_t pkt_size, bool cmd_flg, u32 token) +{ + hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + hdr->src_port = 0; + hdr->dest_port = 0; + if (cmd_flg) { + hdr->token = token; + atomic_set(&this_mmap.cmd_state, 1); + } + hdr->pkt_size = pkt_size; +} + +static int q6usm_memory_map(phys_addr_t buf_add, int dir, uint32_t bufsz, + uint32_t bufcnt, uint32_t session, uint32_t *mem_handle) +{ + struct usm_cmd_memory_map_region mem_region_map; + int rc = 0; + + if (this_mmap.apr == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + + q6usm_add_mmaphdr(&mem_region_map.hdr, + sizeof(struct usm_cmd_memory_map_region), true, + ((session << 8) | dir)); + + mem_region_map.hdr.opcode = USM_CMD_SHARED_MEM_MAP_REGION; + mem_region_map.mempool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL; + + mem_region_map.num_regions = 1; + mem_region_map.flags = 0; + + mem_region_map.shm_addr_lsw = lower_32_bits(buf_add); + mem_region_map.shm_addr_msw = + msm_audio_populate_upper_32_bits(buf_add); + mem_region_map.mem_size_bytes = bufsz * bufcnt; + + rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_region_map); + if (rc < 0) { + pr_err("%s: mem_map op[0x%x]rc[%d]\n", + __func__, mem_region_map.hdr.opcode, rc); + rc = -EINVAL; + goto fail_cmd; + } + + rc = wait_event_timeout(this_mmap.cmd_wait, + (atomic_read(&this_mmap.cmd_state) == 0), + Q6USM_TIMEOUT_JIFFIES); + if (!rc) { + rc = -ETIME; + pr_err("%s: timeout. waited for memory_map\n", __func__); + } else { + *mem_handle = this_mmap.mem_handle; + rc = 0; + } +fail_cmd: + return rc; +} + +int q6usm_memory_unmap(phys_addr_t buf_add, int dir, uint32_t session, + uint32_t mem_handle) +{ + struct usm_cmd_memory_unmap_region mem_unmap; + int rc = 0; + + if (this_mmap.apr == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + + q6usm_add_mmaphdr(&mem_unmap.hdr, + sizeof(struct usm_cmd_memory_unmap_region), true, + ((session << 8) | dir)); + mem_unmap.hdr.opcode = USM_CMD_SHARED_MEM_UNMAP_REGION; + mem_unmap.mem_map_handle = mem_handle; + + rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_unmap); + if (rc < 0) { + pr_err("%s: mem_unmap op[0x%x] rc[%d]\n", + __func__, mem_unmap.hdr.opcode, rc); + goto fail_cmd; + } + + rc = wait_event_timeout(this_mmap.cmd_wait, + (atomic_read(&this_mmap.cmd_state) == 0), + Q6USM_TIMEOUT_JIFFIES); + if (!rc) { + rc = -ETIME; + pr_err("%s: timeout. waited for memory_unmap\n", __func__); + } else + rc = 0; +fail_cmd: + return rc; +} + +static int q6usm_session_alloc(struct us_client *usc) +{ + int ind = 0; + + mutex_lock(&session_lock); + for (ind = 0; ind < USM_SESSION_MAX; ++ind) { + if (!session[ind]) { + session[ind] = usc; + mutex_unlock(&session_lock); + ++ind; /* session id: 0 reserved */ + pr_debug("%s: session[%d] was allocated\n", + __func__, ind); + return ind; + } + } + mutex_unlock(&session_lock); + return -ENOMEM; +} + +static void q6usm_session_free(struct us_client *usc) +{ + /* Session index was incremented during allocation */ + uint16_t ind = (uint16_t)usc->session - 1; + + pr_debug("%s: to free session[%d]\n", __func__, ind); + if (ind < USM_SESSION_MAX) { + mutex_lock(&session_lock); + session[ind] = NULL; + mutex_unlock(&session_lock); + } +} + +static int q6usm_us_client_buf_free(unsigned int dir, + struct us_client *usc) +{ + struct us_port_data *port; + int rc = 0; + + if ((usc == NULL) || + ((dir != IN) && (dir != OUT))) + return -EINVAL; + + mutex_lock(&usc->cmd_lock); + port = &usc->port[dir]; + if (port == NULL) { + mutex_unlock(&usc->cmd_lock); + return -EINVAL; + } + + if (port->data == NULL) { + mutex_unlock(&usc->cmd_lock); + return 0; + } + + rc = q6usm_memory_unmap(port->phys, dir, usc->session, + *((uint32_t *)port->ext)); + pr_debug("%s: data[%pK]phys[%llx][%pK]\n", __func__, + (void *)port->data, (u64)port->phys, (void *)&port->phys); + + msm_audio_ion_free(port->client, port->handle); + + port->data = NULL; + port->phys = 0; + port->buf_size = 0; + port->buf_cnt = 0; + port->client = NULL; + port->handle = NULL; + + mutex_unlock(&usc->cmd_lock); + return rc; +} + +int q6usm_us_param_buf_free(unsigned int dir, + struct us_client *usc) +{ + struct us_port_data *port; + int rc = 0; + + if ((usc == NULL) || + ((dir != IN) && (dir != OUT))) + return -EINVAL; + + mutex_lock(&usc->cmd_lock); + port = &usc->port[dir]; + if (port == NULL) { + mutex_unlock(&usc->cmd_lock); + return -EINVAL; + } + + if (port->param_buf == NULL) { + mutex_unlock(&usc->cmd_lock); + return 0; + } + + rc = q6usm_memory_unmap(port->param_phys, dir, usc->session, + *((uint32_t *)port->param_buf_mem_handle)); + pr_debug("%s: data[%pK]phys[%llx][%pK]\n", __func__, + (void *)port->param_buf, (u64)port->param_phys, + (void *)&port->param_phys); + + msm_audio_ion_free(port->param_client, port->param_handle); + + port->param_buf = NULL; + port->param_phys = 0; + port->param_buf_size = 0; + port->param_client = NULL; + port->param_handle = NULL; + + mutex_unlock(&usc->cmd_lock); + return rc; +} + +void q6usm_us_client_free(struct us_client *usc) +{ + int loopcnt = 0; + struct us_port_data *port; + uint32_t *p_mem_handle = NULL; + + if ((usc == NULL) || + !(usc->session)) + return; + + for (loopcnt = 0; loopcnt <= OUT; ++loopcnt) { + port = &usc->port[loopcnt]; + if (port->data == NULL) + continue; + pr_debug("%s: loopcnt = %d\n", __func__, loopcnt); + q6usm_us_client_buf_free(loopcnt, usc); + q6usm_us_param_buf_free(loopcnt, usc); + } + q6usm_session_free(usc); + apr_deregister(usc->apr); + + pr_debug("%s: APR De-Register\n", __func__); + + if (atomic_read(&this_mmap.ref_cnt) <= 0) { + pr_err("%s: APR Common Port Already Closed\n", __func__); + goto done; + } + + atomic_dec(&this_mmap.ref_cnt); + if (atomic_read(&this_mmap.ref_cnt) == 0) { + apr_deregister(this_mmap.apr); + pr_debug("%s: APR De-Register common port\n", __func__); + } + +done: + p_mem_handle = (uint32_t *)usc->port[IN].ext; + kfree(p_mem_handle); + kfree(usc); + pr_debug("%s:\n", __func__); +} + +struct us_client *q6usm_us_client_alloc( + void (*cb)(uint32_t, uint32_t, uint32_t *, void *), + void *priv) +{ + struct us_client *usc; + uint32_t *p_mem_handle = NULL; + int n; + int lcnt = 0; + + usc = kzalloc(sizeof(struct us_client), GFP_KERNEL); + if (usc == NULL) + return NULL; + + p_mem_handle = kzalloc(sizeof(uint32_t) * 4, GFP_KERNEL); + if (p_mem_handle == NULL) { + kfree(usc); + return NULL; + } + + n = q6usm_session_alloc(usc); + if (n <= 0) + goto fail_session; + usc->session = n; + usc->cb = cb; + usc->priv = priv; + usc->apr = apr_register("ADSP", "USM", + (apr_fn)q6usm_callback, + ((usc->session) << 8 | 0x0001), + usc); + + if (usc->apr == NULL) { + pr_err("%s: Registration with APR failed\n", __func__); + goto fail; + } + pr_debug("%s: Registering the common port with APR\n", __func__); + if (atomic_read(&this_mmap.ref_cnt) == 0) { + this_mmap.apr = apr_register("ADSP", "USM", + (apr_fn)q6usm_mmapcallback, + 0x0FFFFFFFF, &this_mmap); + if (this_mmap.apr == NULL) { + pr_err("%s: USM port registration failed\n", + __func__); + goto fail; + } + } + + atomic_inc(&this_mmap.ref_cnt); + init_waitqueue_head(&usc->cmd_wait); + mutex_init(&usc->cmd_lock); + for (lcnt = 0; lcnt <= OUT; ++lcnt) { + mutex_init(&usc->port[lcnt].lock); + spin_lock_init(&usc->port[lcnt].dsp_lock); + usc->port[lcnt].ext = (void *)p_mem_handle++; + usc->port[lcnt].param_buf_mem_handle = (void *)p_mem_handle++; + pr_err("%s: usc->port[%d].ext=%pK;\n", + __func__, lcnt, usc->port[lcnt].ext); + } + atomic_set(&usc->cmd_state, 0); + + return usc; +fail: + kfree(p_mem_handle); + q6usm_us_client_free(usc); + return NULL; +fail_session: + kfree(p_mem_handle); + kfree(usc); + return NULL; +} + +int q6usm_us_client_buf_alloc(unsigned int dir, + struct us_client *usc, + unsigned int bufsz, + unsigned int bufcnt) +{ + int rc = 0; + struct us_port_data *port = NULL; + unsigned int size = bufsz*bufcnt; + size_t len; + + if ((usc == NULL) || + ((dir != IN) && (dir != OUT)) || (size == 0) || + (usc->session <= 0 || usc->session > USM_SESSION_MAX)) { + pr_err("%s: wrong parameters: size=%d; bufcnt=%d\n", + __func__, size, bufcnt); + return -EINVAL; + } + + mutex_lock(&usc->cmd_lock); + + port = &usc->port[dir]; + + /* The size to allocate should be multiple of 4K bytes */ + size = PAGE_ALIGN(size); + + rc = msm_audio_ion_alloc("ultrasound_client", + &port->client, &port->handle, + size, &port->phys, + &len, &port->data); + + if (rc) { + pr_err("%s: US ION allocation failed, rc = %d\n", + __func__, rc); + mutex_unlock(&usc->cmd_lock); + return -ENOMEM; + } + + port->buf_cnt = bufcnt; + port->buf_size = bufsz; + pr_debug("%s: data[%pK]; phys[%llx]; [%pK]\n", __func__, + (void *)port->data, + (u64)port->phys, + (void *)&port->phys); + + rc = q6usm_memory_map(port->phys, dir, size, 1, usc->session, + (uint32_t *)port->ext); + if (rc < 0) { + pr_err("%s: CMD Memory_map failed\n", __func__); + mutex_unlock(&usc->cmd_lock); + q6usm_us_client_buf_free(dir, usc); + q6usm_us_param_buf_free(dir, usc); + } else { + mutex_unlock(&usc->cmd_lock); + rc = 0; + } + + return rc; +} + +int q6usm_us_param_buf_alloc(unsigned int dir, + struct us_client *usc, + unsigned int bufsz) +{ + int rc = 0; + struct us_port_data *port = NULL; + unsigned int size = bufsz; + size_t len; + + if ((usc == NULL) || + ((dir != IN) && (dir != OUT)) || + (usc->session <= 0 || usc->session > USM_SESSION_MAX)) { + pr_err("%s: wrong parameters: direction=%d, bufsz=%d\n", + __func__, dir, bufsz); + return -EINVAL; + } + + mutex_lock(&usc->cmd_lock); + + port = &usc->port[dir]; + + if (bufsz == 0) { + pr_debug("%s: bufsz=0, get/set param commands are forbidden\n", + __func__); + port->param_buf = NULL; + mutex_unlock(&usc->cmd_lock); + return rc; + } + + /* The size to allocate should be multiple of 4K bytes */ + size = PAGE_ALIGN(size); + + rc = msm_audio_ion_alloc("ultrasound_client", + &port->param_client, &port->param_handle, + size, &port->param_phys, + &len, &port->param_buf); + + if (rc) { + pr_err("%s: US ION allocation failed, rc = %d\n", + __func__, rc); + mutex_unlock(&usc->cmd_lock); + return -ENOMEM; + } + + port->param_buf_size = bufsz; + pr_debug("%s: param_buf[%pK]; param_phys[%llx]; [%pK]\n", __func__, + (void *)port->param_buf, + (u64)port->param_phys, + (void *)&port->param_phys); + + rc = q6usm_memory_map(port->param_phys, (IN | OUT), size, 1, + usc->session, (uint32_t *)port->param_buf_mem_handle); + if (rc < 0) { + pr_err("%s: CMD Memory_map failed\n", __func__); + mutex_unlock(&usc->cmd_lock); + q6usm_us_client_buf_free(dir, usc); + q6usm_us_param_buf_free(dir, usc); + } else { + mutex_unlock(&usc->cmd_lock); + rc = 0; + } + + return rc; +} + +static int32_t q6usm_mmapcallback(struct apr_client_data *data, void *priv) +{ + uint32_t token; + uint32_t *payload = data->payload; + + pr_debug("%s: ptr0[0x%x]; ptr1[0x%x]; opcode[0x%x]\n", + __func__, payload[0], payload[1], data->opcode); + pr_debug("%s: token[0x%x]; payload_size[%d]; src[%d]; dest[%d];\n", + __func__, data->token, data->payload_size, + data->src_port, data->dest_port); + + if (data->opcode == APR_BASIC_RSP_RESULT) { + /* status field check */ + if (payload[1]) { + pr_err("%s: wrong response[%d] on cmd [%d]\n", + __func__, payload[1], payload[0]); + } else { + token = data->token; + switch (payload[0]) { + case USM_CMD_SHARED_MEM_UNMAP_REGION: + if (atomic_read(&this_mmap.cmd_state)) { + atomic_set(&this_mmap.cmd_state, 0); + wake_up(&this_mmap.cmd_wait); + } + /* fallthrough */ + case USM_CMD_SHARED_MEM_MAP_REGION: + /* For MEM_MAP, additional answer is waited, */ + /* therfore, no wake-up here */ + pr_debug("%s: cmd[0x%x]; result[0x%x]\n", + __func__, payload[0], payload[1]); + break; + default: + pr_debug("%s: wrong command[0x%x]\n", + __func__, payload[0]); + break; + } + } + } else { + if (data->opcode == USM_CMDRSP_SHARED_MEM_MAP_REGION) { + this_mmap.mem_handle = payload[0]; + pr_debug("%s: memory map handle = 0x%x", + __func__, payload[0]); + if (atomic_read(&this_mmap.cmd_state)) { + atomic_set(&this_mmap.cmd_state, 0); + wake_up(&this_mmap.cmd_wait); + } + } + } + return 0; +} + + +static int32_t q6usm_callback(struct apr_client_data *data, void *priv) +{ + struct us_client *usc = (struct us_client *)priv; + unsigned long dsp_flags; + uint32_t *payload = data->payload; + uint32_t token = data->token; + uint32_t opcode = Q6USM_EVENT_UNDEF; + + if (usc == NULL) { + pr_err("%s: client info is NULL\n", __func__); + return -EINVAL; + } + + if (data->opcode == APR_BASIC_RSP_RESULT) { + /* status field check */ + if (payload[1]) { + pr_err("%s: wrong response[%d] on cmd [%d]\n", + __func__, payload[1], payload[0]); + if (usc->cb) + usc->cb(data->opcode, token, + (uint32_t *)data->payload, usc->priv); + } else { + switch (payload[0]) { + case USM_SESSION_CMD_RUN: + case USM_STREAM_CMD_CLOSE: + if (token != usc->session) { + pr_err("%s: wrong token[%d]", + __func__, token); + break; + } + case USM_STREAM_CMD_OPEN_READ: + case USM_STREAM_CMD_OPEN_WRITE: + case USM_STREAM_CMD_SET_ENC_PARAM: + case USM_DATA_CMD_MEDIA_FORMAT_UPDATE: + case USM_SESSION_CMD_SIGNAL_DETECT_MODE: + case USM_STREAM_CMD_SET_PARAM: + case USM_STREAM_CMD_GET_PARAM: + if (atomic_read(&usc->cmd_state)) { + atomic_set(&usc->cmd_state, 0); + wake_up(&usc->cmd_wait); + } + if (usc->cb) + usc->cb(data->opcode, token, + (uint32_t *)data->payload, + usc->priv); + break; + default: + break; + } + } + return 0; + } + + switch (data->opcode) { + case RESET_EVENTS: { + pr_err("%s: Reset event is received: %d %d\n", + __func__, + data->reset_event, + data->reset_proc); + + opcode = RESET_EVENTS; + + apr_reset(this_mmap.apr); + this_mmap.apr = NULL; + + apr_reset(usc->apr); + usc->apr = NULL; + + break; + } + + + case USM_DATA_EVENT_READ_DONE: { + struct us_port_data *port = &usc->port[OUT]; + + opcode = Q6USM_EVENT_READ_DONE; + spin_lock_irqsave(&port->dsp_lock, dsp_flags); + if (payload[READDONE_IDX_STATUS]) { + pr_err("%s: wrong READDONE[%d]; token[%d]\n", + __func__, + payload[READDONE_IDX_STATUS], + token); + token = USM_WRONG_TOKEN; + spin_unlock_irqrestore(&port->dsp_lock, + dsp_flags); + break; + } + + if (port->expected_token != token) { + u32 cpu_buf = port->cpu_buf; + + pr_err("%s: expected[%d] != token[%d]\n", + __func__, port->expected_token, token); + pr_debug("%s: dsp_buf=%d; cpu_buf=%d;\n", + __func__, port->dsp_buf, cpu_buf); + + token = USM_WRONG_TOKEN; + /* To prevent data handle continiue */ + port->expected_token = USM_WRONG_TOKEN; + spin_unlock_irqrestore(&port->dsp_lock, + dsp_flags); + break; + } /* port->expected_token != data->token */ + + port->expected_token = token + 1; + if (port->expected_token == port->buf_cnt) + port->expected_token = 0; + + /* gap support */ + if (port->expected_token != port->cpu_buf) { + port->dsp_buf = port->expected_token; + token = port->dsp_buf; /* for callback */ + } else + port->dsp_buf = token; + + spin_unlock_irqrestore(&port->dsp_lock, dsp_flags); + break; + } /* case USM_DATA_EVENT_READ_DONE */ + + case USM_DATA_EVENT_WRITE_DONE: { + struct us_port_data *port = &usc->port[IN]; + + opcode = Q6USM_EVENT_WRITE_DONE; + if (payload[WRITEDONE_IDX_STATUS]) { + pr_err("%s: wrong WRITEDONE_IDX_STATUS[%d]\n", + __func__, + payload[WRITEDONE_IDX_STATUS]); + break; + } + + spin_lock_irqsave(&port->dsp_lock, dsp_flags); + port->dsp_buf = token + 1; + if (port->dsp_buf == port->buf_cnt) + port->dsp_buf = 0; + spin_unlock_irqrestore(&port->dsp_lock, dsp_flags); + + break; + } /* case USM_DATA_EVENT_WRITE_DONE */ + + case USM_SESSION_EVENT_SIGNAL_DETECT_RESULT: { + pr_debug("%s: US detect result: result=%d", + __func__, + payload[0]); + opcode = Q6USM_EVENT_SIGNAL_DETECT_RESULT; + + break; + } /* case USM_SESSION_EVENT_SIGNAL_DETECT_RESULT */ + + default: + return 0; + + } /* switch */ + + if (usc->cb) + usc->cb(opcode, token, + data->payload, usc->priv); + + return 0; +} + +uint32_t q6usm_get_virtual_address(int dir, + struct us_client *usc, + struct vm_area_struct *vms) +{ + uint32_t ret = 0xffffffff; + + if (vms && (usc != NULL) && ((dir == IN) || (dir == OUT))) { + struct us_port_data *port = &usc->port[dir]; + int size = PAGE_ALIGN(port->buf_size * port->buf_cnt); + struct audio_buffer ab; + + ab.phys = port->phys; + ab.data = port->data; + ab.used = 1; + ab.size = size; + ab.actual_size = size; + ab.handle = port->handle; + ab.client = port->client; + + ret = msm_audio_ion_mmap(&ab, vms); + + } + return ret; +} + +static void q6usm_add_hdr(struct us_client *usc, struct apr_hdr *hdr, + uint32_t pkt_size, bool cmd_flg) +{ + mutex_lock(&usc->cmd_lock); + hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(sizeof(struct apr_hdr)), + APR_PKT_VER); + hdr->src_svc = ((struct apr_svc *)usc->apr)->id; + hdr->src_domain = APR_DOMAIN_APPS; + hdr->dest_svc = APR_SVC_USM; + hdr->dest_domain = APR_DOMAIN_ADSP; + hdr->src_port = (usc->session << 8) | 0x0001; + hdr->dest_port = (usc->session << 8) | 0x0001; + if (cmd_flg) { + hdr->token = usc->session; + atomic_set(&usc->cmd_state, 1); + } + hdr->pkt_size = pkt_size; + mutex_unlock(&usc->cmd_lock); +} + +static uint32_t q6usm_ext2int_format(uint32_t ext_format) +{ + uint32_t int_format = INVALID_FORMAT; + + switch (ext_format) { + case FORMAT_USPS_EPOS: + int_format = US_POINT_EPOS_FORMAT_V2; + break; + case FORMAT_USRAW: + int_format = US_RAW_FORMAT_V2; + break; + case FORMAT_USPROX: + int_format = US_PROX_FORMAT_V4; + break; + case FORMAT_USGES_SYNC: + int_format = US_GES_SYNC_FORMAT; + break; + case FORMAT_USRAW_SYNC: + int_format = US_RAW_SYNC_FORMAT; + break; + default: + pr_err("%s: Invalid format[%d]\n", __func__, ext_format); + break; + } + + return int_format; +} + +int q6usm_open_read(struct us_client *usc, + uint32_t format) +{ + uint32_t int_format = INVALID_FORMAT; + int rc = 0x00; + struct usm_stream_cmd_open_read open; + + if ((usc == NULL) || (usc->apr == NULL)) { + pr_err("%s: client or its apr is NULL\n", __func__); + return -EINVAL; + } + + pr_debug("%s: session[%d]", __func__, usc->session); + + q6usm_add_hdr(usc, &open.hdr, sizeof(open), true); + open.hdr.opcode = USM_STREAM_CMD_OPEN_READ; + open.src_endpoint = 0; /* AFE */ + open.pre_proc_top = 0; /* No preprocessing required */ + + int_format = q6usm_ext2int_format(format); + if (int_format == INVALID_FORMAT) + return -EINVAL; + + open.uMode = STREAM_PRIORITY_NORMAL; + open.format = int_format; + + rc = apr_send_pkt(usc->apr, (uint32_t *) &open); + if (rc < 0) { + pr_err("%s: open failed op[0x%x]rc[%d]\n", + __func__, open.hdr.opcode, rc); + goto fail_cmd; + } + rc = wait_event_timeout(usc->cmd_wait, + (atomic_read(&usc->cmd_state) == 0), + Q6USM_TIMEOUT_JIFFIES); + if (!rc) { + rc = -ETIME; + pr_err("%s: timeout, waited for OPEN_READ rc[%d]\n", + __func__, rc); + goto fail_cmd; + } else + rc = 0; +fail_cmd: + return rc; +} + + +int q6usm_enc_cfg_blk(struct us_client *usc, struct us_encdec_cfg *us_cfg) +{ + uint32_t int_format = INVALID_FORMAT; + struct usm_stream_cmd_encdec_cfg_blk enc_cfg_obj; + struct usm_stream_cmd_encdec_cfg_blk *enc_cfg = &enc_cfg_obj; + int rc = 0; + uint32_t total_cfg_size = + sizeof(struct usm_stream_cmd_encdec_cfg_blk); + uint32_t round_params_size = 0; + uint8_t is_allocated = 0; + + + if ((usc == NULL) || (us_cfg == NULL)) { + pr_err("%s: wrong input", __func__); + return -EINVAL; + } + + int_format = q6usm_ext2int_format(us_cfg->format_id); + if (int_format == INVALID_FORMAT) { + pr_err("%s: wrong input format[%d]", + __func__, us_cfg->format_id); + return -EINVAL; + } + + /* Transparent configuration data is after enc_cfg */ + /* Integer number of u32s is required */ + round_params_size = ((us_cfg->params_size + 3)/4) * 4; + if (round_params_size > USM_MAX_CFG_DATA_SIZE) { + /* Dynamic allocated encdec_cfg_blk is required */ + /* static part use */ + round_params_size -= USM_MAX_CFG_DATA_SIZE; + total_cfg_size += round_params_size; + enc_cfg = kzalloc(total_cfg_size, GFP_KERNEL); + if (enc_cfg == NULL) { + pr_err("%s: enc_cfg[%d] allocation failed\n", + __func__, total_cfg_size); + return -ENOMEM; + } + is_allocated = 1; + } else + round_params_size = 0; + + q6usm_add_hdr(usc, &enc_cfg->hdr, total_cfg_size, true); + + enc_cfg->hdr.opcode = USM_STREAM_CMD_SET_ENC_PARAM; + enc_cfg->param_id = USM_PARAM_ID_ENCDEC_ENC_CFG_BLK; + enc_cfg->param_size = sizeof(struct usm_encode_cfg_blk)+ + round_params_size; + enc_cfg->enc_blk.frames_per_buf = 1; + enc_cfg->enc_blk.format_id = int_format; + enc_cfg->enc_blk.cfg_size = sizeof(struct usm_cfg_common)+ + USM_MAX_CFG_DATA_SIZE + + round_params_size; + memcpy(&(enc_cfg->enc_blk.cfg_common), &(us_cfg->cfg_common), + sizeof(struct usm_cfg_common)); + + /* Transparent data copy */ + memcpy(enc_cfg->enc_blk.transp_data, us_cfg->params, + us_cfg->params_size); + pr_debug("%s: cfg_size[%d], params_size[%d]\n", + __func__, + enc_cfg->enc_blk.cfg_size, + us_cfg->params_size); + pr_debug("%s: params[%d,%d,%d,%d, %d,%d,%d,%d]\n", + __func__, + enc_cfg->enc_blk.transp_data[0], + enc_cfg->enc_blk.transp_data[1], + enc_cfg->enc_blk.transp_data[2], + enc_cfg->enc_blk.transp_data[3], + enc_cfg->enc_blk.transp_data[4], + enc_cfg->enc_blk.transp_data[5], + enc_cfg->enc_blk.transp_data[6], + enc_cfg->enc_blk.transp_data[7] + ); + pr_debug("%s: srate:%d, ch=%d, bps= %d;\n", + __func__, enc_cfg->enc_blk.cfg_common.sample_rate, + enc_cfg->enc_blk.cfg_common.ch_cfg, + enc_cfg->enc_blk.cfg_common.bits_per_sample); + pr_debug("dmap:[0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x]; dev_id=0x%x\n", + enc_cfg->enc_blk.cfg_common.data_map[0], + enc_cfg->enc_blk.cfg_common.data_map[1], + enc_cfg->enc_blk.cfg_common.data_map[2], + enc_cfg->enc_blk.cfg_common.data_map[3], + enc_cfg->enc_blk.cfg_common.data_map[4], + enc_cfg->enc_blk.cfg_common.data_map[5], + enc_cfg->enc_blk.cfg_common.data_map[6], + enc_cfg->enc_blk.cfg_common.data_map[7], + enc_cfg->enc_blk.cfg_common.dev_id); + + rc = apr_send_pkt(usc->apr, (uint32_t *) enc_cfg); + if (rc < 0) { + pr_err("%s:Comamnd open failed\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(usc->cmd_wait, + (atomic_read(&usc->cmd_state) == 0), + Q6USM_TIMEOUT_JIFFIES); + if (!rc) { + rc = -ETIME; + pr_err("%s: timeout opcode[0x%x]\n", + __func__, enc_cfg->hdr.opcode); + } else + rc = 0; + +fail_cmd: + if (is_allocated == 1) + kfree(enc_cfg); + + return rc; +} + +int q6usm_dec_cfg_blk(struct us_client *usc, struct us_encdec_cfg *us_cfg) +{ + + uint32_t int_format = INVALID_FORMAT; + struct usm_stream_media_format_update dec_cfg_obj; + struct usm_stream_media_format_update *dec_cfg = &dec_cfg_obj; + + int rc = 0; + uint32_t total_cfg_size = sizeof(struct usm_stream_media_format_update); + uint32_t round_params_size = 0; + uint8_t is_allocated = 0; + + + if ((usc == NULL) || (us_cfg == NULL)) { + pr_err("%s: wrong input", __func__); + return -EINVAL; + } + + int_format = q6usm_ext2int_format(us_cfg->format_id); + if (int_format == INVALID_FORMAT) { + pr_err("%s: wrong input format[%d]", + __func__, us_cfg->format_id); + return -EINVAL; + } + + /* Transparent configuration data is after enc_cfg */ + /* Integer number of u32s is required */ + round_params_size = ((us_cfg->params_size + 3)/4) * 4; + if (round_params_size > USM_MAX_CFG_DATA_SIZE) { + /* Dynamic allocated encdec_cfg_blk is required */ + /* static part use */ + round_params_size -= USM_MAX_CFG_DATA_SIZE; + total_cfg_size += round_params_size; + dec_cfg = kzalloc(total_cfg_size, GFP_KERNEL); + if (dec_cfg == NULL) { + pr_err("%s:dec_cfg[%d] allocation failed\n", + __func__, total_cfg_size); + return -ENOMEM; + } + is_allocated = 1; + } else { /* static transp_data is enough */ + round_params_size = 0; + } + + q6usm_add_hdr(usc, &dec_cfg->hdr, total_cfg_size, true); + + dec_cfg->hdr.opcode = USM_DATA_CMD_MEDIA_FORMAT_UPDATE; + dec_cfg->format_id = int_format; + dec_cfg->cfg_size = sizeof(struct usm_cfg_common) + + USM_MAX_CFG_DATA_SIZE + + round_params_size; + memcpy(&(dec_cfg->cfg_common), &(us_cfg->cfg_common), + sizeof(struct usm_cfg_common)); + /* Transparent data copy */ + memcpy(dec_cfg->transp_data, us_cfg->params, us_cfg->params_size); + pr_debug("%s: cfg_size[%d], params_size[%d]; parambytes[%d,%d,%d,%d]\n", + __func__, + dec_cfg->cfg_size, + us_cfg->params_size, + dec_cfg->transp_data[0], + dec_cfg->transp_data[1], + dec_cfg->transp_data[2], + dec_cfg->transp_data[3] + ); + + rc = apr_send_pkt(usc->apr, (uint32_t *) dec_cfg); + if (rc < 0) { + pr_err("%s:Comamnd open failed\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(usc->cmd_wait, + (atomic_read(&usc->cmd_state) == 0), + Q6USM_TIMEOUT_JIFFIES); + if (!rc) { + rc = -ETIME; + pr_err("%s: timeout opcode[0x%x]\n", + __func__, dec_cfg->hdr.opcode); + } else + rc = 0; + +fail_cmd: + if (is_allocated == 1) + kfree(dec_cfg); + + return rc; +} + +int q6usm_open_write(struct us_client *usc, + uint32_t format) +{ + int rc = 0; + uint32_t int_format = INVALID_FORMAT; + struct usm_stream_cmd_open_write open; + + if ((usc == NULL) || (usc->apr == NULL)) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + + pr_debug("%s: session[%d]", __func__, usc->session); + + q6usm_add_hdr(usc, &open.hdr, sizeof(open), true); + open.hdr.opcode = USM_STREAM_CMD_OPEN_WRITE; + + int_format = q6usm_ext2int_format(format); + if (int_format == INVALID_FORMAT) { + pr_err("%s: wrong format[%d]", __func__, format); + return -EINVAL; + } + + open.format = int_format; + + rc = apr_send_pkt(usc->apr, (uint32_t *) &open); + if (rc < 0) { + pr_err("%s:open failed op[0x%x]rc[%d]\n", + __func__, open.hdr.opcode, rc); + goto fail_cmd; + } + rc = wait_event_timeout(usc->cmd_wait, + (atomic_read(&usc->cmd_state) == 0), + Q6USM_TIMEOUT_JIFFIES); + if (!rc) { + rc = -ETIME; + pr_err("%s:timeout. waited for OPEN_WRITR rc[%d]\n", + __func__, rc); + goto fail_cmd; + } else + rc = 0; + +fail_cmd: + return rc; +} + +int q6usm_run(struct us_client *usc, uint32_t flags, + uint32_t msw_ts, uint32_t lsw_ts) +{ + struct usm_stream_cmd_run run; + int rc = 0; + + if ((usc == NULL) || (usc->apr == NULL)) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + q6usm_add_hdr(usc, &run.hdr, sizeof(run), true); + + run.hdr.opcode = USM_SESSION_CMD_RUN; + run.flags = flags; + run.msw_ts = msw_ts; + run.lsw_ts = lsw_ts; + + rc = apr_send_pkt(usc->apr, (uint32_t *) &run); + if (rc < 0) { + pr_err("%s: Commmand run failed[%d]\n", __func__, rc); + goto fail_cmd; + } + + rc = wait_event_timeout(usc->cmd_wait, + (atomic_read(&usc->cmd_state) == 0), + Q6USM_TIMEOUT_JIFFIES); + if (!rc) { + rc = -ETIME; + pr_err("%s: timeout. waited for run success rc[%d]\n", + __func__, rc); + } else + rc = 0; + +fail_cmd: + return rc; +} + + + +int q6usm_read(struct us_client *usc, uint32_t read_ind) +{ + struct usm_stream_cmd_read read; + struct us_port_data *port = NULL; + int rc = 0; + u32 read_counter = 0; + u32 loop_ind = 0; + u64 buf_addr = 0; + + if ((usc == NULL) || (usc->apr == NULL)) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + port = &usc->port[OUT]; + + if (read_ind > port->buf_cnt) { + pr_err("%s: wrong read_ind[%d]\n", + __func__, read_ind); + return -EINVAL; + } + if (read_ind == port->cpu_buf) { + pr_err("%s: no free region\n", __func__); + return 0; + } + + if (read_ind > port->cpu_buf) { /* 1 range */ + read_counter = read_ind - port->cpu_buf; + } else { /* 2 ranges */ + read_counter = (port->buf_cnt - port->cpu_buf) + read_ind; + } + + q6usm_add_hdr(usc, &read.hdr, sizeof(read), false); + + read.hdr.opcode = USM_DATA_CMD_READ; + read.buf_size = port->buf_size; + buf_addr = (u64)(port->phys) + port->buf_size * (port->cpu_buf); + read.buf_addr_lsw = lower_32_bits(buf_addr); + read.buf_addr_msw = msm_audio_populate_upper_32_bits(buf_addr); + read.mem_map_handle = *((uint32_t *)(port->ext)); + + for (loop_ind = 0; loop_ind < read_counter; ++loop_ind) { + u32 temp_cpu_buf = port->cpu_buf; + + buf_addr = (u64)(port->phys) + + port->buf_size * (port->cpu_buf); + read.buf_addr_lsw = lower_32_bits(buf_addr); + read.buf_addr_msw = msm_audio_populate_upper_32_bits(buf_addr); + read.seq_id = port->cpu_buf; + read.hdr.token = port->cpu_buf; + read.counter = 1; + + ++(port->cpu_buf); + if (port->cpu_buf == port->buf_cnt) + port->cpu_buf = 0; + + rc = apr_send_pkt(usc->apr, (uint32_t *) &read); + + if (rc < 0) { + port->cpu_buf = temp_cpu_buf; + + pr_err("%s:read op[0x%x]rc[%d]\n", + __func__, read.hdr.opcode, rc); + break; + } + + rc = 0; + } /* bufs loop */ + + return rc; +} + +int q6usm_write(struct us_client *usc, uint32_t write_ind) +{ + int rc = 0; + struct usm_stream_cmd_write cmd_write; + struct us_port_data *port = NULL; + u32 current_dsp_buf = 0; + u64 buf_addr = 0; + + if ((usc == NULL) || (usc->apr == NULL)) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + port = &usc->port[IN]; + + current_dsp_buf = port->dsp_buf; + /* free region, caused by new dsp_buf report from DSP, */ + /* can be only extended */ + if (port->cpu_buf >= current_dsp_buf) { + /* 2 -part free region, including empty buffer */ + if ((write_ind <= port->cpu_buf) && + (write_ind > current_dsp_buf)) { + pr_err("%s: wrong w_ind[%d]; d_buf=%d; c_buf=%d\n", + __func__, write_ind, + current_dsp_buf, port->cpu_buf); + return -EINVAL; + } + } else { + /* 1 -part free region */ + if ((write_ind <= port->cpu_buf) || + (write_ind > current_dsp_buf)) { + pr_err("%s: wrong w_ind[%d]; d_buf=%d; c_buf=%d\n", + __func__, write_ind, + current_dsp_buf, port->cpu_buf); + return -EINVAL; + } + } + + q6usm_add_hdr(usc, &cmd_write.hdr, sizeof(cmd_write), false); + + cmd_write.hdr.opcode = USM_DATA_CMD_WRITE; + cmd_write.buf_size = port->buf_size; + buf_addr = (u64)(port->phys) + port->buf_size * (port->cpu_buf); + cmd_write.buf_addr_lsw = lower_32_bits(buf_addr); + cmd_write.buf_addr_msw = msm_audio_populate_upper_32_bits(buf_addr); + cmd_write.mem_map_handle = *((uint32_t *)(port->ext)); + cmd_write.res0 = 0; + cmd_write.res1 = 0; + cmd_write.res2 = 0; + + while (port->cpu_buf != write_ind) { + u32 temp_cpu_buf = port->cpu_buf; + + buf_addr = (u64)(port->phys) + + port->buf_size * (port->cpu_buf); + cmd_write.buf_addr_lsw = lower_32_bits(buf_addr); + cmd_write.buf_addr_msw = + msm_audio_populate_upper_32_bits(buf_addr); + cmd_write.seq_id = port->cpu_buf; + cmd_write.hdr.token = port->cpu_buf; + + ++(port->cpu_buf); + if (port->cpu_buf == port->buf_cnt) + port->cpu_buf = 0; + + rc = apr_send_pkt(usc->apr, (uint32_t *) &cmd_write); + + if (rc < 0) { + port->cpu_buf = temp_cpu_buf; + pr_err("%s:write op[0x%x];rc[%d];cpu_buf[%d]\n", + __func__, cmd_write.hdr.opcode, + rc, port->cpu_buf); + break; + } + + rc = 0; + } + + return rc; +} + +bool q6usm_is_write_buf_full(struct us_client *usc, uint32_t *free_region) +{ + struct us_port_data *port = NULL; + u32 cpu_buf = 0; + + if ((usc == NULL) || !free_region) { + pr_err("%s: input data wrong\n", __func__); + return false; + } + port = &usc->port[IN]; + cpu_buf = port->cpu_buf + 1; + if (cpu_buf == port->buf_cnt) + cpu_buf = 0; + + *free_region = port->dsp_buf; + + return cpu_buf == *free_region; +} + +int q6usm_cmd(struct us_client *usc, int cmd) +{ + struct apr_hdr hdr; + int rc = 0; + atomic_t *state; + + if ((usc == NULL) || (usc->apr == NULL)) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + q6usm_add_hdr(usc, &hdr, sizeof(hdr), true); + switch (cmd) { + case CMD_CLOSE: + hdr.opcode = USM_STREAM_CMD_CLOSE; + state = &usc->cmd_state; + break; + + default: + pr_err("%s:Invalid format[%d]\n", __func__, cmd); + goto fail_cmd; + } + + rc = apr_send_pkt(usc->apr, (uint32_t *) &hdr); + if (rc < 0) { + pr_err("%s: Command 0x%x failed\n", __func__, hdr.opcode); + goto fail_cmd; + } + rc = wait_event_timeout(usc->cmd_wait, (atomic_read(state) == 0), + Q6USM_TIMEOUT_JIFFIES); + if (!rc) { + rc = -ETIME; + pr_err("%s:timeout. waited for response opcode[0x%x]\n", + __func__, hdr.opcode); + } else + rc = 0; +fail_cmd: + return rc; +} + +int q6usm_set_us_detection(struct us_client *usc, + struct usm_session_cmd_detect_info *detect_info, + uint16_t detect_info_size) +{ + int rc = 0; + + if ((usc == NULL) || + (detect_info_size == 0) || + (detect_info == NULL)) { + pr_err("%s: wrong input: usc=0x%pK, inf_size=%d; info=0x%pK", + __func__, + usc, + detect_info_size, + detect_info); + return -EINVAL; + } + + q6usm_add_hdr(usc, &detect_info->hdr, detect_info_size, true); + + detect_info->hdr.opcode = USM_SESSION_CMD_SIGNAL_DETECT_MODE; + + rc = apr_send_pkt(usc->apr, (uint32_t *)detect_info); + if (rc < 0) { + pr_err("%s:Comamnd signal detect failed\n", __func__); + return -EINVAL; + } + rc = wait_event_timeout(usc->cmd_wait, + (atomic_read(&usc->cmd_state) == 0), + Q6USM_TIMEOUT_JIFFIES); + if (!rc) { + rc = -ETIME; + pr_err("%s: CMD_SIGNAL_DETECT_MODE: timeout=%d\n", + __func__, Q6USM_TIMEOUT_JIFFIES); + } else + rc = 0; + + return rc; +} + +int q6usm_set_us_stream_param(int dir, struct us_client *usc, + uint32_t module_id, uint32_t param_id, uint32_t buf_size) +{ + int rc = 0; + struct usm_stream_cmd_set_param cmd_set_param; + struct us_port_data *port = NULL; + + if ((usc == NULL) || (usc->apr == NULL)) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + port = &usc->port[dir]; + + q6usm_add_hdr(usc, &cmd_set_param.hdr, sizeof(cmd_set_param), true); + + cmd_set_param.hdr.opcode = USM_STREAM_CMD_SET_PARAM; + cmd_set_param.buf_size = buf_size; + cmd_set_param.buf_addr_msw = + msm_audio_populate_upper_32_bits(port->param_phys); + cmd_set_param.buf_addr_lsw = lower_32_bits(port->param_phys); + cmd_set_param.mem_map_handle = + *((uint32_t *)(port->param_buf_mem_handle)); + cmd_set_param.module_id = module_id; + cmd_set_param.param_id = param_id; + cmd_set_param.hdr.token = 0; + + rc = apr_send_pkt(usc->apr, (uint32_t *) &cmd_set_param); + + if (rc < 0) { + pr_err("%s:write op[0x%x];rc[%d]\n", + __func__, cmd_set_param.hdr.opcode, rc); + } + + rc = wait_event_timeout(usc->cmd_wait, + (atomic_read(&usc->cmd_state) == 0), + Q6USM_TIMEOUT_JIFFIES); + if (!rc) { + rc = -ETIME; + pr_err("%s: CMD_SET_PARAM: timeout=%d\n", + __func__, Q6USM_TIMEOUT_JIFFIES); + } else + rc = 0; + + return rc; +} + +int q6usm_get_us_stream_param(int dir, struct us_client *usc, + uint32_t module_id, uint32_t param_id, uint32_t buf_size) +{ + int rc = 0; + struct usm_stream_cmd_get_param cmd_get_param; + struct us_port_data *port = NULL; + + if ((usc == NULL) || (usc->apr == NULL)) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + port = &usc->port[dir]; + + q6usm_add_hdr(usc, &cmd_get_param.hdr, sizeof(cmd_get_param), true); + + cmd_get_param.hdr.opcode = USM_STREAM_CMD_GET_PARAM; + cmd_get_param.buf_size = buf_size; + cmd_get_param.buf_addr_msw = + msm_audio_populate_upper_32_bits(port->param_phys); + cmd_get_param.buf_addr_lsw = lower_32_bits(port->param_phys); + cmd_get_param.mem_map_handle = + *((uint32_t *)(port->param_buf_mem_handle)); + cmd_get_param.module_id = module_id; + cmd_get_param.param_id = param_id; + cmd_get_param.hdr.token = 0; + + rc = apr_send_pkt(usc->apr, (uint32_t *) &cmd_get_param); + + if (rc < 0) { + pr_err("%s:write op[0x%x];rc[%d]\n", + __func__, cmd_get_param.hdr.opcode, rc); + } + + rc = wait_event_timeout(usc->cmd_wait, + (atomic_read(&usc->cmd_state) == 0), + Q6USM_TIMEOUT_JIFFIES); + if (!rc) { + rc = -ETIME; + pr_err("%s: CMD_GET_PARAM: timeout=%d\n", + __func__, Q6USM_TIMEOUT_JIFFIES); + } else + rc = 0; + + return rc; +} + +static int __init q6usm_init(void) +{ + pr_debug("%s\n", __func__); + init_waitqueue_head(&this_mmap.cmd_wait); + memset(session, 0, sizeof(session)); + return 0; +} + +device_initcall(q6usm_init); diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.h b/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.h new file mode 100644 index 000000000000..d45d1657c924 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.h @@ -0,0 +1,130 @@ +/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __Q6_USM_H__ +#define __Q6_USM_H__ + +#include + +#define Q6USM_EVENT_UNDEF 0 +#define Q6USM_EVENT_READ_DONE 1 +#define Q6USM_EVENT_WRITE_DONE 2 +#define Q6USM_EVENT_SIGNAL_DETECT_RESULT 3 + +/* cyclic buffer with 1 gap support */ +#define USM_MIN_BUF_CNT 3 + +#define FORMAT_USPS_EPOS 0x00000000 +#define FORMAT_USRAW 0x00000001 +#define FORMAT_USPROX 0x00000002 +#define FORMAT_USGES_SYNC 0x00000003 +#define FORMAT_USRAW_SYNC 0x00000004 +#define INVALID_FORMAT 0xffffffff + +#define IN 0x000 +#define OUT 0x001 + +#define USM_WRONG_TOKEN 0xffffffff +#define USM_UNDEF_TOKEN 0xfffffffe + +#define CMD_CLOSE 0x0004 + +/* bit 0:1 represents priority of stream */ +#define STREAM_PRIORITY_NORMAL 0x0000 +#define STREAM_PRIORITY_LOW 0x0001 +#define STREAM_PRIORITY_HIGH 0x0002 + +/* bit 4 represents META enable of encoded data buffer */ +#define BUFFER_META_ENABLE 0x0010 + +struct us_port_data { + dma_addr_t phys; + /* cyclic region of buffers with 1 gap */ + void *data; + /* number of buffers in the region */ + uint32_t buf_cnt; + /* size of buffer */ + size_t buf_size; + /* write index */ + uint32_t dsp_buf; + /* read index */ + uint32_t cpu_buf; + /* expected token from dsp */ + uint32_t expected_token; + /* read or write locks */ + struct mutex lock; + spinlock_t dsp_lock; + /* ION memory handle */ + struct ion_handle *handle; + /* ION memory client */ + struct ion_client *client; + /* extended parameters, related to q6 variants */ + void *ext; + /* physical address of parameter buffer */ + dma_addr_t param_phys; + /* buffer which stores the parameter data */ + void *param_buf; + /* size of parameter buffer */ + uint32_t param_buf_size; + /* parameter buffer memory handle */ + void *param_buf_mem_handle; + /* ION memory handle for parameter buffer */ + struct ion_handle *param_handle; + /* ION memory client for parameter buffer */ + struct ion_client *param_client; +}; + +struct us_client { + int session; + /* idx:1 out port, 0: in port*/ + struct us_port_data port[2]; + + struct apr_svc *apr; + struct mutex cmd_lock; + + atomic_t cmd_state; + atomic_t eos_state; + wait_queue_head_t cmd_wait; + + void (*cb)(uint32_t, uint32_t, uint32_t *, void *); + void *priv; +}; + +int q6usm_run(struct us_client *usc, uint32_t flags, + uint32_t msw_ts, uint32_t lsw_ts); +int q6usm_cmd(struct us_client *usc, int cmd); +int q6usm_us_client_buf_alloc(unsigned int dir, struct us_client *usc, + unsigned int bufsz, unsigned int bufcnt); +int q6usm_us_param_buf_alloc(unsigned int dir, struct us_client *usc, + unsigned int bufsz); +int q6usm_enc_cfg_blk(struct us_client *usc, struct us_encdec_cfg *us_cfg); +int q6usm_dec_cfg_blk(struct us_client *usc, struct us_encdec_cfg *us_cfg); +int q6usm_read(struct us_client *usc, uint32_t read_ind); +struct us_client *q6usm_us_client_alloc( + void (*cb)(uint32_t, uint32_t, uint32_t *, void *), + void *priv); +int q6usm_open_read(struct us_client *usc, uint32_t format); +void q6usm_us_client_free(struct us_client *usc); +uint32_t q6usm_get_virtual_address(int dir, struct us_client *usc, + struct vm_area_struct *vms); +int q6usm_open_write(struct us_client *usc, uint32_t format); +int q6usm_write(struct us_client *usc, uint32_t write_ind); +bool q6usm_is_write_buf_full(struct us_client *usc, uint32_t *free_region); +int q6usm_set_us_detection(struct us_client *usc, + struct usm_session_cmd_detect_info *detect_info, + uint16_t detect_info_size); +int q6usm_set_us_stream_param(int dir, struct us_client *usc, + uint32_t module_id, uint32_t param_id, uint32_t buf_size); +int q6usm_get_us_stream_param(int dir, struct us_client *usc, + uint32_t module_id, uint32_t param_id, uint32_t buf_size); + +#endif /* __Q6_USM_H__ */ diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/usf.c b/drivers/misc/qcom/qdsp6v2/ultrasound/usf.c new file mode 100644 index 000000000000..3da46b647002 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/ultrasound/usf.c @@ -0,0 +1,2465 @@ +/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "q6usm.h" +#include "usfcdev.h" + +/* The driver version*/ +#define DRV_VERSION "1.7.1" +#define USF_VERSION_ID 0x0171 + +/* Standard timeout in the asynchronous ops */ +#define USF_TIMEOUT_JIFFIES (1*HZ) /* 1 sec */ + +/* Undefined USF device */ +#define USF_UNDEF_DEV_ID 0xffff + +/* TX memory mapping flag */ +#define USF_VM_READ 1 +/* RX memory mapping flag */ +#define USF_VM_WRITE 2 + +/* Number of events, copied from the user space to kernel one */ +#define USF_EVENTS_PORTION_SIZE 20 + +/* Indexes in range definitions */ +#define MIN_IND 0 +#define MAX_IND 1 + +/* The coordinates indexes */ +#define X_IND 0 +#define Y_IND 1 +#define Z_IND 2 + +/* Shared memory limits */ +/* max_buf_size = (port_size(65535*2) * port_num(8) * group_size(3) */ +#define USF_MAX_BUF_SIZE 3145680 +#define USF_MAX_BUF_NUM 32 + +/* max size for buffer set from user space */ +#define USF_MAX_USER_BUF_SIZE 100000 + +/* Place for opreation result, received from QDSP6 */ +#define APR_RESULT_IND 1 + +/* Place for US detection result, received from QDSP6 */ +#define APR_US_DETECT_RESULT_IND 0 + +#define BITS_IN_BYTE 8 + +/* Time to stay awake after tx read event (e.g., proximity) */ +#define STAY_AWAKE_AFTER_READ_MSECS 3000 + +/* The driver states */ +enum usf_state_type { + USF_IDLE_STATE, + USF_OPENED_STATE, + USF_CONFIGURED_STATE, + USF_WORK_STATE, + USF_ADSP_RESTART_STATE, + USF_ERROR_STATE +}; + +/* The US detection status upon FW/HW based US detection results */ +enum usf_us_detect_type { + USF_US_DETECT_UNDEF, + USF_US_DETECT_YES, + USF_US_DETECT_NO +}; + +struct usf_xx_type { + /* Name of the client - event calculator */ + char client_name[USF_MAX_CLIENT_NAME_SIZE]; + /* The driver state in TX or RX direction */ + enum usf_state_type usf_state; + /* wait for q6 events mechanism */ + wait_queue_head_t wait; + /* IF with q6usm info */ + struct us_client *usc; + /* Q6:USM' Encoder/decoder configuration */ + struct us_encdec_cfg encdec_cfg; + /* Shared buffer (with Q6:USM) size */ + uint32_t buffer_size; + /* Number of the shared buffers (with Q6:USM) */ + uint32_t buffer_count; + /* Shared memory (Cyclic buffer with 1 gap) control */ + uint32_t new_region; + uint32_t prev_region; + /* Q6:USM's events handler */ + void (*cb)(uint32_t, uint32_t, uint32_t *, void *); + /* US detection result */ + enum usf_us_detect_type us_detect_type; + /* User's update info isn't acceptable */ + u8 user_upd_info_na; +}; + +struct usf_type { + /* TX device component configuration & control */ + struct usf_xx_type usf_tx; + /* RX device component configuration & control */ + struct usf_xx_type usf_rx; + /* Index into the opened device container */ + /* To prevent mutual usage of the same device */ + uint16_t dev_ind; + /* Event types, supported by device */ + uint16_t event_types; + /* The input devices are "input" module registered clients */ + struct input_dev *input_ifs[USF_MAX_EVENT_IND]; + /* Bitmap of types of events, conflicting to USF's ones */ + uint16_t conflicting_event_types; + /* Bitmap of types of events from devs, conflicting with USF */ + uint16_t conflicting_event_filters; + /* The requested buttons bitmap */ + uint16_t req_buttons_bitmap; + /* Mutex for exclusive operations (all public APIs) */ + struct mutex mutex; +}; + +struct usf_input_dev_type { + /* Input event type, supported by the input device */ + uint16_t event_type; + /* Input device name */ + const char *input_dev_name; + /* Input device registration function */ + int (*prepare_dev)(uint16_t, struct usf_type *, + struct us_input_info_type *, + const char *); + /* Input event notification function */ + void (*notify_event)(struct usf_type *, + uint16_t, + struct usf_event_type * + ); +}; + + +/* The MAX number of the supported devices */ +#define MAX_DEVS_NUMBER 1 + +/* + * code for a special button that is used to show/hide a + * hovering cursor in the input framework. Must be in + * sync with the button code definition in the framework + * (EventHub.h) + */ +#define BTN_USF_HOVERING_CURSOR 0x230 + +/* Supported buttons container */ +static const int s_button_map[] = { + BTN_STYLUS, + BTN_STYLUS2, + BTN_TOOL_PEN, + BTN_TOOL_RUBBER, + BTN_TOOL_FINGER, + BTN_USF_HOVERING_CURSOR +}; + +/* The opened devices container */ +static atomic_t s_opened_devs[MAX_DEVS_NUMBER]; + +static struct wakeup_source usf_wakeup_source; + +#define USF_NAME_PREFIX "usf_" +#define USF_NAME_PREFIX_SIZE 4 + + +static struct input_dev *allocate_dev(uint16_t ind, const char *name) +{ + struct input_dev *in_dev = input_allocate_device(); + + if (in_dev == NULL) { + pr_err("%s: input_allocate_device() failed\n", __func__); + } else { + /* Common part configuration */ + in_dev->name = name; + in_dev->phys = NULL; + in_dev->id.bustype = BUS_HOST; + in_dev->id.vendor = 0x0001; + in_dev->id.product = 0x0001; + in_dev->id.version = USF_VERSION_ID; + } + return in_dev; +} + +static int prepare_tsc_input_device(uint16_t ind, + struct usf_type *usf_info, + struct us_input_info_type *input_info, + const char *name) +{ + int i = 0; + + int num_buttons = min(ARRAY_SIZE(s_button_map), + sizeof(input_info->req_buttons_bitmap) * + BITS_IN_BYTE); + uint16_t max_buttons_bitmap = ((1 << ARRAY_SIZE(s_button_map)) - 1); + + struct input_dev *in_dev = allocate_dev(ind, name); + + if (in_dev == NULL) + return -ENOMEM; + + if (input_info->req_buttons_bitmap > max_buttons_bitmap) { + pr_err("%s: Requested buttons[%d] exceeds max buttons available[%d]\n", + __func__, + input_info->req_buttons_bitmap, + max_buttons_bitmap); + input_free_device(in_dev); + return -EINVAL; + } + + usf_info->input_ifs[ind] = in_dev; + usf_info->req_buttons_bitmap = + input_info->req_buttons_bitmap; + in_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + in_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + + for (i = 0; i < num_buttons; i++) + if (input_info->req_buttons_bitmap & (1 << i)) + in_dev->keybit[BIT_WORD(s_button_map[i])] |= + BIT_MASK(s_button_map[i]); + + input_set_abs_params(in_dev, ABS_X, + input_info->tsc_x_dim[MIN_IND], + input_info->tsc_x_dim[MAX_IND], + 0, 0); + input_set_abs_params(in_dev, ABS_Y, + input_info->tsc_y_dim[MIN_IND], + input_info->tsc_y_dim[MAX_IND], + 0, 0); + input_set_abs_params(in_dev, ABS_DISTANCE, + input_info->tsc_z_dim[MIN_IND], + input_info->tsc_z_dim[MAX_IND], + 0, 0); + + input_set_abs_params(in_dev, ABS_PRESSURE, + input_info->tsc_pressure[MIN_IND], + input_info->tsc_pressure[MAX_IND], + 0, 0); + + input_set_abs_params(in_dev, ABS_TILT_X, + input_info->tsc_x_tilt[MIN_IND], + input_info->tsc_x_tilt[MAX_IND], + 0, 0); + input_set_abs_params(in_dev, ABS_TILT_Y, + input_info->tsc_y_tilt[MIN_IND], + input_info->tsc_y_tilt[MAX_IND], + 0, 0); + + return 0; +} + +static int prepare_mouse_input_device(uint16_t ind, struct usf_type *usf_info, + struct us_input_info_type *input_info, + const char *name) +{ + struct input_dev *in_dev = allocate_dev(ind, name); + + if (in_dev == NULL) + return -ENOMEM; + + usf_info->input_ifs[ind] = in_dev; + in_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); + + in_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | + BIT_MASK(BTN_RIGHT) | + BIT_MASK(BTN_MIDDLE); + in_dev->relbit[0] = BIT_MASK(REL_X) | + BIT_MASK(REL_Y) | + BIT_MASK(REL_Z); + + return 0; +} + +static int prepare_keyboard_input_device( + uint16_t ind, + struct usf_type *usf_info, + struct us_input_info_type *input_info, + const char *name) +{ + struct input_dev *in_dev = allocate_dev(ind, name); + + if (in_dev == NULL) + return -ENOMEM; + + usf_info->input_ifs[ind] = in_dev; + in_dev->evbit[0] |= BIT_MASK(EV_KEY); + /* All keys are permitted */ + memset(in_dev->keybit, 0xff, sizeof(in_dev->keybit)); + + return 0; +} + +static void notify_tsc_event(struct usf_type *usf_info, + uint16_t if_ind, + struct usf_event_type *event) + +{ + int i = 0; + int num_buttons = min(ARRAY_SIZE(s_button_map), + sizeof(usf_info->req_buttons_bitmap) * + BITS_IN_BYTE); + + struct input_dev *input_if = usf_info->input_ifs[if_ind]; + struct point_event_type *pe = &(event->event_data.point_event); + + input_report_abs(input_if, ABS_X, pe->coordinates[X_IND]); + input_report_abs(input_if, ABS_Y, pe->coordinates[Y_IND]); + input_report_abs(input_if, ABS_DISTANCE, pe->coordinates[Z_IND]); + + input_report_abs(input_if, ABS_TILT_X, pe->inclinations[X_IND]); + input_report_abs(input_if, ABS_TILT_Y, pe->inclinations[Y_IND]); + + input_report_abs(input_if, ABS_PRESSURE, pe->pressure); + input_report_key(input_if, BTN_TOUCH, !!(pe->pressure)); + + for (i = 0; i < num_buttons; i++) { + uint16_t mask = (1 << i), + btn_state = !!(pe->buttons_state_bitmap & mask); + if (usf_info->req_buttons_bitmap & mask) + input_report_key(input_if, s_button_map[i], btn_state); + } + + input_sync(input_if); + + pr_debug("%s: TSC event: xyz[%d;%d;%d], incl[%d;%d], pressure[%d], buttons[%d]\n", + __func__, + pe->coordinates[X_IND], + pe->coordinates[Y_IND], + pe->coordinates[Z_IND], + pe->inclinations[X_IND], + pe->inclinations[Y_IND], + pe->pressure, + pe->buttons_state_bitmap); +} + +static void notify_mouse_event(struct usf_type *usf_info, + uint16_t if_ind, + struct usf_event_type *event) +{ + struct input_dev *input_if = usf_info->input_ifs[if_ind]; + struct mouse_event_type *me = &(event->event_data.mouse_event); + + input_report_rel(input_if, REL_X, me->rels[X_IND]); + input_report_rel(input_if, REL_Y, me->rels[Y_IND]); + input_report_rel(input_if, REL_Z, me->rels[Z_IND]); + + input_report_key(input_if, BTN_LEFT, + me->buttons_states & USF_BUTTON_LEFT_MASK); + input_report_key(input_if, BTN_MIDDLE, + me->buttons_states & USF_BUTTON_MIDDLE_MASK); + input_report_key(input_if, BTN_RIGHT, + me->buttons_states & USF_BUTTON_RIGHT_MASK); + + input_sync(input_if); + + pr_debug("%s: mouse event: dx[%d], dy[%d], buttons_states[%d]\n", + __func__, me->rels[X_IND], + me->rels[Y_IND], me->buttons_states); +} + +static void notify_key_event(struct usf_type *usf_info, + uint16_t if_ind, + struct usf_event_type *event) +{ + struct input_dev *input_if = usf_info->input_ifs[if_ind]; + struct key_event_type *ke = &(event->event_data.key_event); + + input_report_key(input_if, ke->key, ke->key_state); + input_sync(input_if); + pr_debug("%s: key event: key[%d], state[%d]\n", + __func__, + ke->key, + ke->key_state); + +} + +static struct usf_input_dev_type s_usf_input_devs[] = { + {USF_TSC_EVENT, "usf_tsc", + prepare_tsc_input_device, notify_tsc_event}, + {USF_TSC_PTR_EVENT, "usf_tsc_ptr", + prepare_tsc_input_device, notify_tsc_event}, + {USF_MOUSE_EVENT, "usf_mouse", + prepare_mouse_input_device, notify_mouse_event}, + {USF_KEYBOARD_EVENT, "usf_kb", + prepare_keyboard_input_device, notify_key_event}, + {USF_TSC_EXT_EVENT, "usf_tsc_ext", + prepare_tsc_input_device, notify_tsc_event}, +}; + +static void usf_rx_cb(uint32_t opcode, uint32_t token, + uint32_t *payload, void *priv) +{ + struct usf_xx_type *usf_xx = (struct usf_xx_type *) priv; + + if (usf_xx == NULL) { + pr_err("%s: the private data is NULL\n", __func__); + return; + } + + switch (opcode) { + case Q6USM_EVENT_WRITE_DONE: + wake_up(&usf_xx->wait); + break; + + case RESET_EVENTS: + pr_err("%s: received RESET_EVENTS\n", __func__); + usf_xx->usf_state = USF_ADSP_RESTART_STATE; + wake_up(&usf_xx->wait); + break; + + default: + break; + } +} + +static void usf_tx_cb(uint32_t opcode, uint32_t token, + uint32_t *payload, void *priv) +{ + struct usf_xx_type *usf_xx = (struct usf_xx_type *) priv; + + if (usf_xx == NULL) { + pr_err("%s: the private data is NULL\n", __func__); + return; + } + + switch (opcode) { + case Q6USM_EVENT_READ_DONE: + pr_debug("%s: acquiring %d msec wake lock\n", __func__, + STAY_AWAKE_AFTER_READ_MSECS); + __pm_wakeup_event(&usf_wakeup_source, + STAY_AWAKE_AFTER_READ_MSECS); + if (token == USM_WRONG_TOKEN) + usf_xx->usf_state = USF_ERROR_STATE; + usf_xx->new_region = token; + wake_up(&usf_xx->wait); + break; + + case Q6USM_EVENT_SIGNAL_DETECT_RESULT: + usf_xx->us_detect_type = (payload[APR_US_DETECT_RESULT_IND]) ? + USF_US_DETECT_YES : + USF_US_DETECT_NO; + + wake_up(&usf_xx->wait); + break; + + case APR_BASIC_RSP_RESULT: + if (payload[APR_RESULT_IND]) { + usf_xx->usf_state = USF_ERROR_STATE; + usf_xx->new_region = USM_WRONG_TOKEN; + wake_up(&usf_xx->wait); + } + break; + + case RESET_EVENTS: + pr_err("%s: received RESET_EVENTS\n", __func__); + usf_xx->usf_state = USF_ADSP_RESTART_STATE; + wake_up(&usf_xx->wait); + break; + + default: + break; + } +} + +static void release_xx(struct usf_xx_type *usf_xx) +{ + if (usf_xx != NULL) { + if (usf_xx->usc) { + q6usm_us_client_free(usf_xx->usc); + usf_xx->usc = NULL; + } + + if (usf_xx->encdec_cfg.params != NULL) { + kfree(usf_xx->encdec_cfg.params); + usf_xx->encdec_cfg.params = NULL; + } + } +} + +static void usf_disable(struct usf_xx_type *usf_xx) +{ + if (usf_xx != NULL) { + if ((usf_xx->usf_state != USF_IDLE_STATE) && + (usf_xx->usf_state != USF_OPENED_STATE)) { + (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE); + usf_xx->usf_state = USF_OPENED_STATE; + wake_up(&usf_xx->wait); + } + release_xx(usf_xx); + } +} + +static int config_xx(struct usf_xx_type *usf_xx, struct us_xx_info_type *config) +{ + int rc = 0; + uint16_t data_map_size = 0; + uint16_t min_map_size = 0; + + if ((usf_xx == NULL) || + (config == NULL)) + return -EINVAL; + + if ((config->buf_size == 0) || + (config->buf_size > USF_MAX_BUF_SIZE) || + (config->buf_num == 0) || + (config->buf_num > USF_MAX_BUF_NUM)) { + pr_err("%s: wrong params: buf_size=%d; buf_num=%d\n", + __func__, config->buf_size, config->buf_num); + return -EINVAL; + } + + data_map_size = sizeof(usf_xx->encdec_cfg.cfg_common.data_map); + min_map_size = min(data_map_size, config->port_cnt); + + if (config->client_name != NULL) { + if (strncpy_from_user(usf_xx->client_name, + (char __user *)config->client_name, + sizeof(usf_xx->client_name) - 1) < 0) { + pr_err("%s: get client name failed\n", __func__); + return -EINVAL; + } + } + + pr_debug("%s: name=%s; buf_size:%d; dev_id:0x%x; sample_rate:%d\n", + __func__, usf_xx->client_name, config->buf_size, + config->dev_id, config->sample_rate); + + pr_debug("%s: buf_num:%d; format:%d; port_cnt:%d; data_size=%d\n", + __func__, config->buf_num, config->stream_format, + config->port_cnt, config->params_data_size); + + pr_debug("%s: id[0]=%d, id[1]=%d, id[2]=%d, id[3]=%d, id[4]=%d,\n", + __func__, + config->port_id[0], + config->port_id[1], + config->port_id[2], + config->port_id[3], + config->port_id[4]); + + pr_debug("id[5]=%d, id[6]=%d, id[7]=%d\n", + config->port_id[5], + config->port_id[6], + config->port_id[7]); + + /* q6usm allocation & configuration */ + usf_xx->buffer_size = config->buf_size; + usf_xx->buffer_count = config->buf_num; + usf_xx->encdec_cfg.cfg_common.bits_per_sample = + config->bits_per_sample; + usf_xx->encdec_cfg.cfg_common.sample_rate = config->sample_rate; + /* AFE port e.g. AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX */ + usf_xx->encdec_cfg.cfg_common.dev_id = config->dev_id; + + usf_xx->encdec_cfg.cfg_common.ch_cfg = config->port_cnt; + memcpy((void *)&usf_xx->encdec_cfg.cfg_common.data_map, + (void *)config->port_id, + min_map_size); + + usf_xx->encdec_cfg.format_id = config->stream_format; + usf_xx->encdec_cfg.params_size = config->params_data_size; + usf_xx->user_upd_info_na = 1; /* it's used in US_GET_TX_UPDATE */ + + if (config->params_data_size > 0) { /* transparent data copy */ + usf_xx->encdec_cfg.params = kzalloc(config->params_data_size, + GFP_KERNEL); + /* False memory leak here - pointer in packed struct + * is undetected by kmemleak tool + */ + kmemleak_ignore(usf_xx->encdec_cfg.params); + if (usf_xx->encdec_cfg.params == NULL) { + pr_err("%s: params memory alloc[%d] failure\n", + __func__, + config->params_data_size); + return -ENOMEM; + } + rc = copy_from_user(usf_xx->encdec_cfg.params, + (uint8_t __user *)config->params_data, + config->params_data_size); + if (rc) { + pr_err("%s: transparent data copy failure\n", + __func__); + kfree(usf_xx->encdec_cfg.params); + usf_xx->encdec_cfg.params = NULL; + return -EFAULT; + } + pr_debug("%s: params_size[%d]; params[%d,%d,%d,%d, %d]\n", + __func__, + config->params_data_size, + usf_xx->encdec_cfg.params[0], + usf_xx->encdec_cfg.params[1], + usf_xx->encdec_cfg.params[2], + usf_xx->encdec_cfg.params[3], + usf_xx->encdec_cfg.params[4] + ); + } + + usf_xx->usc = q6usm_us_client_alloc(usf_xx->cb, (void *)usf_xx); + if (!usf_xx->usc) { + pr_err("%s: Could not allocate q6usm client\n", __func__); + rc = -EFAULT; + } + + return rc; +} + +static bool usf_match(uint16_t event_type_ind, struct input_dev *dev) +{ + bool rc = false; + + rc = (event_type_ind < MAX_EVENT_TYPE_NUM) && + ((dev->name == NULL) || + strcmp(dev->name, USF_NAME_PREFIX)); + pr_debug("%s: name=[%s]; rc=%d\n", + __func__, dev->name, rc); + + return rc; +} + +static bool usf_register_conflicting_events(uint16_t event_types) +{ + bool rc = true; + uint16_t ind = 0; + uint16_t mask = 1; + + for (ind = 0; ind < MAX_EVENT_TYPE_NUM; ++ind) { + if (event_types & mask) { + rc = usfcdev_register(ind, usf_match); + if (!rc) + break; + } + mask = mask << 1; + } + + return rc; +} + +static void usf_unregister_conflicting_events(uint16_t event_types) +{ + uint16_t ind = 0; + uint16_t mask = 1; + + for (ind = 0; ind < MAX_EVENT_TYPE_NUM; ++ind) { + if (event_types & mask) + usfcdev_unregister(ind); + mask = mask << 1; + } +} + +static void usf_set_event_filters(struct usf_type *usf, uint16_t event_filters) +{ + uint16_t ind = 0; + uint16_t mask = 1; + + if (usf->conflicting_event_filters != event_filters) { + for (ind = 0; ind < MAX_EVENT_TYPE_NUM; ++ind) { + if (usf->conflicting_event_types & mask) + usfcdev_set_filter(ind, event_filters&mask); + mask = mask << 1; + } + usf->conflicting_event_filters = event_filters; + } +} + +static int register_input_device(struct usf_type *usf_info, + struct us_input_info_type *input_info) +{ + int rc = 0; + bool ret = true; + uint16_t ind = 0; + + if ((usf_info == NULL) || + (input_info == NULL) || + !(input_info->event_types & USF_ALL_EVENTS)) { + pr_err("%s: wrong input parameter(s)\n", __func__); + return -EINVAL; + } + + for (ind = 0; ind < USF_MAX_EVENT_IND; ++ind) { + if (usf_info->input_ifs[ind] != NULL) { + pr_err("%s: input_if[%d] is already allocated\n", + __func__, ind); + return -EFAULT; + } + if ((input_info->event_types & + s_usf_input_devs[ind].event_type) && + s_usf_input_devs[ind].prepare_dev) { + rc = (*s_usf_input_devs[ind].prepare_dev)( + ind, + usf_info, + input_info, + s_usf_input_devs[ind].input_dev_name); + if (rc) + return rc; + + rc = input_register_device(usf_info->input_ifs[ind]); + if (rc) { + pr_err("%s: input_reg_dev() failed; rc=%d\n", + __func__, rc); + input_free_device(usf_info->input_ifs[ind]); + usf_info->input_ifs[ind] = NULL; + } else { + usf_info->event_types |= + s_usf_input_devs[ind].event_type; + pr_debug("%s: input device[%s] was registered\n", + __func__, + s_usf_input_devs[ind].input_dev_name); + } + } /* supported event */ + } /* event types loop */ + + ret = usf_register_conflicting_events( + input_info->conflicting_event_types); + if (ret) + usf_info->conflicting_event_types = + input_info->conflicting_event_types; + + return 0; +} + + +static void handle_input_event(struct usf_type *usf_info, + uint16_t event_counter, + struct usf_event_type __user *event) +{ + uint16_t ind = 0; + uint16_t events_num = 0; + struct usf_event_type usf_events[USF_EVENTS_PORTION_SIZE]; + int rc = 0; + + if ((usf_info == NULL) || + (event == NULL) || (!event_counter)) { + return; + } + + while (event_counter > 0) { + if (event_counter > USF_EVENTS_PORTION_SIZE) { + events_num = USF_EVENTS_PORTION_SIZE; + event_counter -= USF_EVENTS_PORTION_SIZE; + } else { + events_num = event_counter; + event_counter = 0; + } + rc = copy_from_user(usf_events, + (struct usf_event_type __user *)event, + events_num * sizeof(struct usf_event_type)); + if (rc) { + pr_err("%s: copy upd_rx_info from user; rc=%d\n", + __func__, rc); + return; + } + for (ind = 0; ind < events_num; ++ind) { + struct usf_event_type *p_event = &usf_events[ind]; + uint16_t if_ind = p_event->event_type_ind; + + if ((if_ind >= USF_MAX_EVENT_IND) || + (usf_info->input_ifs[if_ind] == NULL)) + continue; /* event isn't supported */ + + if (s_usf_input_devs[if_ind].notify_event) + (*s_usf_input_devs[if_ind].notify_event)( + usf_info, + if_ind, + p_event); + } /* loop in the portion */ + } /* all events loop */ +} + +static int usf_start_tx(struct usf_xx_type *usf_xx) +{ + int rc = q6usm_run(usf_xx->usc, 0, 0, 0); + + pr_debug("%s: tx: q6usm_run; rc=%d\n", __func__, rc); + if (!rc) { + if (usf_xx->buffer_count >= USM_MIN_BUF_CNT) { + /* supply all buffers */ + rc = q6usm_read(usf_xx->usc, + usf_xx->buffer_count); + pr_debug("%s: q6usm_read[%d]\n", + __func__, rc); + + if (rc) + pr_err("%s: buf read failed", + __func__); + else + usf_xx->usf_state = + USF_WORK_STATE; + } else + usf_xx->usf_state = + USF_WORK_STATE; + } + + return rc; +} /* usf_start_tx */ + +static int usf_start_rx(struct usf_xx_type *usf_xx) +{ + int rc = q6usm_run(usf_xx->usc, 0, 0, 0); + + pr_debug("%s: rx: q6usm_run; rc=%d\n", + __func__, rc); + if (!rc) + usf_xx->usf_state = USF_WORK_STATE; + + return rc; +} /* usf_start_rx */ + +static int __usf_set_us_detection(struct usf_type *usf, + struct us_detect_info_type *detect_info) +{ + uint32_t timeout = 0; + struct usm_session_cmd_detect_info *p_allocated_memory = NULL; + struct usm_session_cmd_detect_info usm_detect_info; + struct usm_session_cmd_detect_info *p_usm_detect_info = + &usm_detect_info; + uint32_t detect_info_size = sizeof(struct usm_session_cmd_detect_info); + struct usf_xx_type *usf_xx = &usf->usf_tx; + int rc = 0; + + if (detect_info->us_detector != US_DETECT_FW) { + pr_err("%s: unsupported detector: %d\n", + __func__, detect_info->us_detector); + return -EINVAL; + } + + if ((detect_info->params_data_size != 0) && + (detect_info->params_data != NULL)) { + uint8_t *p_data = NULL; + + detect_info_size += detect_info->params_data_size; + p_allocated_memory = kzalloc(detect_info_size, GFP_KERNEL); + if (p_allocated_memory == NULL) { + pr_err("%s: detect_info[%d] allocation failed\n", + __func__, detect_info_size); + return -ENOMEM; + } + p_usm_detect_info = p_allocated_memory; + p_data = (uint8_t *)p_usm_detect_info + + sizeof(struct usm_session_cmd_detect_info); + + rc = copy_from_user(p_data, + (uint8_t __user *)(detect_info->params_data), + detect_info->params_data_size); + if (rc) { + pr_err("%s: copy params from user; rc=%d\n", + __func__, rc); + kfree(p_allocated_memory); + return -EFAULT; + } + p_usm_detect_info->algorithm_cfg_size = + detect_info->params_data_size; + } else + usm_detect_info.algorithm_cfg_size = 0; + + p_usm_detect_info->detect_mode = detect_info->us_detect_mode; + p_usm_detect_info->skip_interval = detect_info->skip_time; + + usf_xx->us_detect_type = USF_US_DETECT_UNDEF; + + rc = q6usm_set_us_detection(usf_xx->usc, + p_usm_detect_info, + detect_info_size); + if (rc || (detect_info->detect_timeout == USF_NO_WAIT_TIMEOUT)) { + kfree(p_allocated_memory); + return rc; + } + + /* Get US detection result */ + if (detect_info->detect_timeout == USF_INFINITIVE_TIMEOUT) { + rc = wait_event_interruptible(usf_xx->wait, + (usf_xx->us_detect_type != + USF_US_DETECT_UNDEF) || + (usf_xx->usf_state == + USF_ADSP_RESTART_STATE)); + } else { + if (detect_info->detect_timeout == USF_DEFAULT_TIMEOUT) + timeout = USF_TIMEOUT_JIFFIES; + else + timeout = detect_info->detect_timeout * HZ; + } + rc = wait_event_interruptible_timeout(usf_xx->wait, + (usf_xx->us_detect_type != + USF_US_DETECT_UNDEF) || + (usf_xx->usf_state == + USF_ADSP_RESTART_STATE), timeout); + + /* In the case of aDSP restart, "no US" is assumed */ + if (usf_xx->usf_state == USF_ADSP_RESTART_STATE) + rc = -EFAULT; + + /* In the case of timeout, "no US" is assumed */ + if (rc < 0) + pr_err("%s: Getting US detection failed rc[%d]\n", + __func__, rc); + else { + usf->usf_rx.us_detect_type = usf->usf_tx.us_detect_type; + detect_info->is_us = + (usf_xx->us_detect_type == USF_US_DETECT_YES); + } + + kfree(p_allocated_memory); + + return rc; +} /* __usf_set_us_detection */ + +static int usf_set_us_detection(struct usf_type *usf, unsigned long arg) +{ + struct us_detect_info_type detect_info; + + int rc = copy_from_user(&detect_info, + (struct us_detect_info_type __user *) arg, + sizeof(detect_info)); + + if (rc) { + pr_err("%s: copy detect_info from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + if (detect_info.params_data_size > USF_MAX_USER_BUF_SIZE) { + pr_err("%s: user buffer size exceeds maximum\n", + __func__); + return -EFAULT; + } + + rc = __usf_set_us_detection(usf, &detect_info); + if (rc < 0) { + pr_err("%s: set us detection failed; rc=%d\n", + __func__, rc); + return rc; + } + + rc = copy_to_user((void __user *)arg, + &detect_info, + sizeof(detect_info)); + if (rc) { + pr_err("%s: copy detect_info to user; rc=%d\n", + __func__, rc); + rc = -EFAULT; + } + + return rc; +} /* usf_set_us_detection */ + +static int __usf_set_tx_info(struct usf_type *usf, + struct us_tx_info_type *config_tx) +{ + struct usf_xx_type *usf_xx = &usf->usf_tx; + int rc = 0; + + usf_xx->new_region = USM_UNDEF_TOKEN; + usf_xx->prev_region = USM_UNDEF_TOKEN; + usf_xx->cb = usf_tx_cb; + + init_waitqueue_head(&usf_xx->wait); + + if (config_tx->us_xx_info.client_name != NULL) { + int res = strncpy_from_user( + usf_xx->client_name, + (char __user *)(config_tx->us_xx_info.client_name), + sizeof(usf_xx->client_name)-1); + if (res < 0) { + pr_err("%s: get client name failed\n", + __func__); + return -EINVAL; + } + } + + rc = config_xx(usf_xx, &(config_tx->us_xx_info)); + if (rc) + return rc; + + rc = q6usm_open_read(usf_xx->usc, + usf_xx->encdec_cfg.format_id); + if (rc) + return rc; + + rc = q6usm_us_client_buf_alloc(OUT, usf_xx->usc, + usf_xx->buffer_size, + usf_xx->buffer_count); + if (rc) { + (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE); + return rc; + } + + rc = q6usm_us_param_buf_alloc(OUT, usf_xx->usc, + config_tx->us_xx_info.max_get_set_param_buf_size); + if (rc) { + (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE); + return rc; + } + + rc = q6usm_enc_cfg_blk(usf_xx->usc, + &usf_xx->encdec_cfg); + if (!rc && + (config_tx->input_info.event_types != USF_NO_EVENT)) { + rc = register_input_device(usf, + &(config_tx->input_info)); + } + + if (rc) + (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE); + else + usf_xx->usf_state = USF_CONFIGURED_STATE; + + return rc; +} /* __usf_set_tx_info */ + +static int usf_set_tx_info(struct usf_type *usf, unsigned long arg) +{ + struct us_tx_info_type config_tx; + + int rc = copy_from_user(&config_tx, + (struct us_tx_info_type __user *) arg, + sizeof(config_tx)); + + if (rc) { + pr_err("%s: copy config_tx from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + if (config_tx.us_xx_info.params_data_size > USF_MAX_USER_BUF_SIZE) { + pr_err("%s: user buffer size exceeds maximum\n", + __func__); + return -EFAULT; + } + + return __usf_set_tx_info(usf, &config_tx); +} /* usf_set_tx_info */ + +static int __usf_set_rx_info(struct usf_type *usf, + struct us_rx_info_type *config_rx) +{ + struct usf_xx_type *usf_xx = &usf->usf_rx; + int rc = 0; + + usf_xx->new_region = USM_UNDEF_TOKEN; + usf_xx->prev_region = USM_UNDEF_TOKEN; + + usf_xx->cb = usf_rx_cb; + + rc = config_xx(usf_xx, &(config_rx->us_xx_info)); + if (rc) + return rc; + + rc = q6usm_open_write(usf_xx->usc, + usf_xx->encdec_cfg.format_id); + if (rc) + return rc; + + rc = q6usm_us_client_buf_alloc( + IN, + usf_xx->usc, + usf_xx->buffer_size, + usf_xx->buffer_count); + if (rc) { + (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE); + return rc; + } + + rc = q6usm_us_param_buf_alloc(IN, usf_xx->usc, + config_rx->us_xx_info.max_get_set_param_buf_size); + if (rc) { + (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE); + return rc; + } + + rc = q6usm_dec_cfg_blk(usf_xx->usc, + &usf_xx->encdec_cfg); + if (rc) + (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE); + else { + init_waitqueue_head(&usf_xx->wait); + usf_xx->usf_state = USF_CONFIGURED_STATE; + } + + return rc; +} /* __usf_set_rx_info */ + +static int usf_set_rx_info(struct usf_type *usf, unsigned long arg) +{ + struct us_rx_info_type config_rx; + + int rc = copy_from_user(&config_rx, + (struct us_rx_info_type __user *) arg, + sizeof(config_rx)); + + if (rc) { + pr_err("%s: copy config_rx from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + if (config_rx.us_xx_info.params_data_size > USF_MAX_USER_BUF_SIZE) { + pr_err("%s: user buffer size exceeds maximum\n", + __func__); + return -EFAULT; + } + + return __usf_set_rx_info(usf, &config_rx); +} /* usf_set_rx_info */ + +static int __usf_get_tx_update(struct usf_type *usf, + struct us_tx_update_info_type *upd_tx_info) +{ + unsigned long prev_jiffies = 0; + uint32_t timeout = 0; + struct usf_xx_type *usf_xx = &usf->usf_tx; + int rc = 0; + + if (!usf_xx->user_upd_info_na) { + usf_set_event_filters(usf, upd_tx_info->event_filters); + handle_input_event(usf, + upd_tx_info->event_counter, + upd_tx_info->event); + + /* Release available regions */ + rc = q6usm_read(usf_xx->usc, + upd_tx_info->free_region); + if (rc) + return rc; + } else + usf_xx->user_upd_info_na = 0; + + /* Get data ready regions */ + if (upd_tx_info->timeout == USF_INFINITIVE_TIMEOUT) { + rc = wait_event_interruptible(usf_xx->wait, + (usf_xx->prev_region != + usf_xx->new_region) || + (usf_xx->usf_state != + USF_WORK_STATE)); + } else { + if (upd_tx_info->timeout == USF_NO_WAIT_TIMEOUT) + rc = (usf_xx->prev_region != usf_xx->new_region); + else { + prev_jiffies = jiffies; + if (upd_tx_info->timeout == USF_DEFAULT_TIMEOUT) { + timeout = USF_TIMEOUT_JIFFIES; + rc = wait_event_timeout( + usf_xx->wait, + (usf_xx->prev_region != + usf_xx->new_region) || + (usf_xx->usf_state != + USF_WORK_STATE), + timeout); + } else { + timeout = upd_tx_info->timeout * HZ; + rc = wait_event_interruptible_timeout( + usf_xx->wait, + (usf_xx->prev_region != + usf_xx->new_region) || + (usf_xx->usf_state != + USF_WORK_STATE), + timeout); + } + } + if (!rc) { + pr_debug("%s: timeout. prev_j=%lu; j=%lu\n", + __func__, prev_jiffies, jiffies); + pr_debug("%s: timeout. prev=%d; new=%d\n", + __func__, usf_xx->prev_region, + usf_xx->new_region); + pr_debug("%s: timeout. free_region=%d;\n", + __func__, upd_tx_info->free_region); + if (usf_xx->prev_region == + usf_xx->new_region) { + pr_err("%s:read data: timeout\n", + __func__); + return -ETIME; + } + } + } + + if ((usf_xx->usf_state != USF_WORK_STATE) || + (rc == -ERESTARTSYS)) { + pr_err("%s: Get ready region failure; state[%d]; rc[%d]\n", + __func__, usf_xx->usf_state, rc); + return -EINTR; + } + + upd_tx_info->ready_region = usf_xx->new_region; + usf_xx->prev_region = upd_tx_info->ready_region; + + if (upd_tx_info->ready_region == USM_WRONG_TOKEN) { + pr_err("%s: TX path corrupted; prev=%d\n", + __func__, usf_xx->prev_region); + return -EIO; + } + + return rc; +} /* __usf_get_tx_update */ + +static int usf_get_tx_update(struct usf_type *usf, unsigned long arg) +{ + struct us_tx_update_info_type upd_tx_info; + + int rc = copy_from_user(&upd_tx_info, + (struct us_tx_update_info_type __user *) arg, + sizeof(upd_tx_info)); + + if (rc < 0) { + pr_err("%s: copy upd_tx_info from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + rc = __usf_get_tx_update(usf, &upd_tx_info); + if (rc < 0) { + pr_err("%s: get tx update failed; rc=%d\n", + __func__, rc); + return rc; + } + + rc = copy_to_user((void __user *)arg, + &upd_tx_info, + sizeof(upd_tx_info)); + if (rc) { + pr_err("%s: copy upd_tx_info to user; rc=%d\n", + __func__, rc); + rc = -EFAULT; + } + + return rc; +} /* usf_get_tx_update */ + +static int __usf_set_rx_update(struct usf_xx_type *usf_xx, + struct us_rx_update_info_type *upd_rx_info) +{ + int rc = 0; + + /* Send available data regions */ + if (upd_rx_info->ready_region != + usf_xx->buffer_count) { + rc = q6usm_write( + usf_xx->usc, + upd_rx_info->ready_region); + if (rc) + return rc; + } + + /* Get free regions */ + rc = wait_event_timeout( + usf_xx->wait, + !q6usm_is_write_buf_full( + usf_xx->usc, + &(upd_rx_info->free_region)) || + (usf_xx->usf_state == USF_IDLE_STATE), + USF_TIMEOUT_JIFFIES); + + if (!rc) { + rc = -ETIME; + pr_err("%s:timeout. wait for write buf not full\n", + __func__); + } else { + if (usf_xx->usf_state != + USF_WORK_STATE) { + pr_err("%s: RX: state[%d]\n", + __func__, + usf_xx->usf_state); + rc = -EINTR; + } + } + + return rc; +} /* __usf_set_rx_update */ + +static int usf_set_rx_update(struct usf_xx_type *usf_xx, unsigned long arg) +{ + struct us_rx_update_info_type upd_rx_info; + + int rc = copy_from_user(&upd_rx_info, + (struct us_rx_update_info_type __user *) arg, + sizeof(upd_rx_info)); + + if (rc) { + pr_err("%s: copy upd_rx_info from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + rc = __usf_set_rx_update(usf_xx, &upd_rx_info); + if (rc < 0) { + pr_err("%s: set rx update failed; rc=%d\n", + __func__, rc); + return rc; + } + + rc = copy_to_user((void __user *)arg, + &upd_rx_info, + sizeof(upd_rx_info)); + if (rc) { + pr_err("%s: copy rx_info to user; rc=%d\n", + __func__, rc); + rc = -EFAULT; + } + + return rc; +} /* usf_set_rx_update */ + +static void usf_release_input(struct usf_type *usf) +{ + uint16_t ind = 0; + + usf_unregister_conflicting_events( + usf->conflicting_event_types); + usf->conflicting_event_types = 0; + for (ind = 0; ind < USF_MAX_EVENT_IND; ++ind) { + if (usf->input_ifs[ind] == NULL) + continue; + input_unregister_device(usf->input_ifs[ind]); + usf->input_ifs[ind] = NULL; + pr_debug("%s input_unregister_device[%s]\n", + __func__, + s_usf_input_devs[ind].input_dev_name); + } +} /* usf_release_input */ + +static int usf_stop_tx(struct usf_type *usf) +{ + struct usf_xx_type *usf_xx = &usf->usf_tx; + + usf_release_input(usf); + usf_disable(usf_xx); + + return 0; +} /* usf_stop_tx */ + +static int __usf_get_version(struct us_version_info_type *version_info) +{ + int rc = 0; + + if (version_info->buf_size < sizeof(DRV_VERSION)) { + pr_err("%s: buf_size (%d) < version string size (%zu)\n", + __func__, version_info->buf_size, sizeof(DRV_VERSION)); + return -EINVAL; + } + + rc = copy_to_user((void __user *)(version_info->pbuf), + DRV_VERSION, + sizeof(DRV_VERSION)); + if (rc) { + pr_err("%s: copy to version_info.pbuf; rc=%d\n", + __func__, rc); + rc = -EFAULT; + } + + return rc; +} /* __usf_get_version */ + +static int usf_get_version(unsigned long arg) +{ + struct us_version_info_type version_info; + + int rc = copy_from_user(&version_info, + (struct us_version_info_type __user *) arg, + sizeof(version_info)); + + if (rc) { + pr_err("%s: copy version_info from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + rc = __usf_get_version(&version_info); + if (rc < 0) { + pr_err("%s: get version failed; rc=%d\n", + __func__, rc); + return rc; + } + + rc = copy_to_user((void __user *)arg, + &version_info, + sizeof(version_info)); + if (rc) { + pr_err("%s: copy version_info to user; rc=%d\n", + __func__, rc); + rc = -EFAULT; + } + + return rc; +} /* usf_get_version */ + +static int __usf_set_stream_param(struct usf_xx_type *usf_xx, + struct us_stream_param_type *set_stream_param, + int dir) +{ + struct us_client *usc = usf_xx->usc; + struct us_port_data *port; + int rc = 0; + + if (usc == NULL) { + pr_err("%s: usc is null\n", + __func__); + return -EFAULT; + } + + port = &usc->port[dir]; + if (port == NULL) { + pr_err("%s: port is null\n", + __func__); + return -EFAULT; + } + + if (port->param_buf == NULL) { + pr_err("%s: parameter buffer is null\n", + __func__); + return -EFAULT; + } + + if (set_stream_param->buf_size > port->param_buf_size) { + pr_err("%s: buf_size (%d) > maximum buf size (%d)\n", + __func__, set_stream_param->buf_size, + port->param_buf_size); + return -EINVAL; + } + + if (set_stream_param->buf_size == 0) { + pr_err("%s: buf_size is 0\n", __func__); + return -EINVAL; + } + + rc = copy_from_user(port->param_buf, + (uint8_t __user *) set_stream_param->pbuf, + set_stream_param->buf_size); + if (rc) { + pr_err("%s: copy param buf from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + rc = q6usm_set_us_stream_param(dir, usc, set_stream_param->module_id, + set_stream_param->param_id, + set_stream_param->buf_size); + if (rc) { + pr_err("%s: q6usm_set_us_stream_param failed; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + return rc; +} + +static int usf_set_stream_param(struct usf_xx_type *usf_xx, + unsigned long arg, int dir) +{ + struct us_stream_param_type set_stream_param; + int rc = 0; + + rc = copy_from_user(&set_stream_param, + (struct us_stream_param_type __user *) arg, + sizeof(set_stream_param)); + + if (rc) { + pr_err("%s: copy set_stream_param from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + return __usf_set_stream_param(usf_xx, &set_stream_param, dir); +} /* usf_set_stream_param */ + +static int __usf_get_stream_param(struct usf_xx_type *usf_xx, + struct us_stream_param_type *get_stream_param, + int dir) +{ + struct us_client *usc = usf_xx->usc; + struct us_port_data *port; + int rc = 0; + + if (usc == NULL) { + pr_err("%s: us_client is null\n", + __func__); + return -EFAULT; + } + + port = &usc->port[dir]; + + if (port->param_buf == NULL) { + pr_err("%s: parameter buffer is null\n", + __func__); + return -EFAULT; + } + + if (get_stream_param->buf_size > port->param_buf_size) { + pr_err("%s: buf_size (%d) > maximum buf size (%d)\n", + __func__, get_stream_param->buf_size, + port->param_buf_size); + return -EINVAL; + } + + if (get_stream_param->buf_size == 0) { + pr_err("%s: buf_size is 0\n", __func__); + return -EINVAL; + } + + rc = q6usm_get_us_stream_param(dir, usc, get_stream_param->module_id, + get_stream_param->param_id, + get_stream_param->buf_size); + if (rc) { + pr_err("%s: q6usm_get_us_stream_param failed; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + rc = copy_to_user((uint8_t __user *) get_stream_param->pbuf, + port->param_buf, + get_stream_param->buf_size); + if (rc) { + pr_err("%s: copy param buf to user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + return rc; +} + +static int usf_get_stream_param(struct usf_xx_type *usf_xx, + unsigned long arg, int dir) +{ + struct us_stream_param_type get_stream_param; + int rc = 0; + + rc = copy_from_user(&get_stream_param, + (struct us_stream_param_type __user *) arg, + sizeof(get_stream_param)); + + if (rc) { + pr_err("%s: copy get_stream_param from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + return __usf_get_stream_param(usf_xx, &get_stream_param, dir); +} /* usf_get_stream_param */ + +static long __usf_ioctl(struct usf_type *usf, + unsigned int cmd, + unsigned long arg) +{ + + int rc = 0; + struct usf_xx_type *usf_xx = NULL; + + switch (cmd) { + case US_START_TX: { + usf_xx = &usf->usf_tx; + if (usf_xx->usf_state == USF_CONFIGURED_STATE) + rc = usf_start_tx(usf_xx); + else { + pr_err("%s: start_tx: wrong state[%d]\n", + __func__, + usf_xx->usf_state); + return -EBADFD; + } + break; + } + + case US_START_RX: { + usf_xx = &usf->usf_rx; + if (usf_xx->usf_state == USF_CONFIGURED_STATE) + rc = usf_start_rx(usf_xx); + else { + pr_err("%s: start_rx: wrong state[%d]\n", + __func__, + usf_xx->usf_state); + return -EBADFD; + } + break; + } + + case US_SET_TX_INFO: { + usf_xx = &usf->usf_tx; + if (usf_xx->usf_state == USF_OPENED_STATE) + rc = usf_set_tx_info(usf, arg); + else { + pr_err("%s: set_tx_info: wrong state[%d]\n", + __func__, + usf_xx->usf_state); + return -EBADFD; + } + + break; + } /* US_SET_TX_INFO */ + + case US_SET_RX_INFO: { + usf_xx = &usf->usf_rx; + if (usf_xx->usf_state == USF_OPENED_STATE) + rc = usf_set_rx_info(usf, arg); + else { + pr_err("%s: set_rx_info: wrong state[%d]\n", + __func__, + usf_xx->usf_state); + return -EBADFD; + } + + break; + } /* US_SET_RX_INFO */ + + case US_GET_TX_UPDATE: { + struct usf_xx_type *usf_xx = &usf->usf_tx; + + if (usf_xx->usf_state == USF_WORK_STATE) + rc = usf_get_tx_update(usf, arg); + else { + pr_err("%s: get_tx_update: wrong state[%d]\n", __func__, + usf_xx->usf_state); + rc = -EBADFD; + } + break; + } /* US_GET_TX_UPDATE */ + + case US_SET_RX_UPDATE: { + struct usf_xx_type *usf_xx = &usf->usf_rx; + + if (usf_xx->usf_state == USF_WORK_STATE) + rc = usf_set_rx_update(usf_xx, arg); + else { + pr_err("%s: set_rx_update: wrong state[%d]\n", + __func__, + usf_xx->usf_state); + rc = -EBADFD; + } + break; + } /* US_SET_RX_UPDATE */ + + case US_STOP_TX: { + usf_xx = &usf->usf_tx; + if ((usf_xx->usf_state == USF_WORK_STATE) + || (usf_xx->usf_state == USF_ADSP_RESTART_STATE)) + rc = usf_stop_tx(usf); + else { + pr_err("%s: stop_tx: wrong state[%d]\n", + __func__, + usf_xx->usf_state); + return -EBADFD; + } + break; + } /* US_STOP_TX */ + + case US_STOP_RX: { + usf_xx = &usf->usf_rx; + if ((usf_xx->usf_state == USF_WORK_STATE) + || (usf_xx->usf_state == USF_ADSP_RESTART_STATE)) + usf_disable(usf_xx); + else { + pr_err("%s: stop_rx: wrong state[%d]\n", + __func__, + usf_xx->usf_state); + return -EBADFD; + } + break; + } /* US_STOP_RX */ + + case US_SET_DETECTION: { + struct usf_xx_type *usf_xx = &usf->usf_tx; + + if (usf_xx->usf_state == USF_WORK_STATE) + rc = usf_set_us_detection(usf, arg); + else { + pr_err("%s: set us detection: wrong state[%d]\n", + __func__, + usf_xx->usf_state); + rc = -EBADFD; + } + break; + } /* US_SET_DETECTION */ + + case US_GET_VERSION: { + rc = usf_get_version(arg); + break; + } /* US_GET_VERSION */ + + case US_SET_TX_STREAM_PARAM: { + rc = usf_set_stream_param(&usf->usf_tx, arg, OUT); + break; + } /* US_SET_TX_STREAM_PARAM */ + + case US_GET_TX_STREAM_PARAM: { + rc = usf_get_stream_param(&usf->usf_tx, arg, OUT); + break; + } /* US_GET_TX_STREAM_PARAM */ + + case US_SET_RX_STREAM_PARAM: { + rc = usf_set_stream_param(&usf->usf_rx, arg, IN); + break; + } /* US_SET_RX_STREAM_PARAM */ + + case US_GET_RX_STREAM_PARAM: { + rc = usf_get_stream_param(&usf->usf_rx, arg, IN); + break; + } /* US_GET_RX_STREAM_PARAM */ + + default: + pr_err("%s: unsupported IOCTL command [%d]\n", + __func__, + cmd); + rc = -ENOTTY; + break; + } + + if (rc && + ((cmd == US_SET_TX_INFO) || + (cmd == US_SET_RX_INFO))) + release_xx(usf_xx); + + return rc; +} /* __usf_ioctl */ + +static long usf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct usf_type *usf = file->private_data; + int rc = 0; + + mutex_lock(&usf->mutex); + rc = __usf_ioctl(usf, cmd, arg); + mutex_unlock(&usf->mutex); + + return rc; +} /* usf_ioctl */ + +#ifdef CONFIG_COMPAT + +#define US_SET_TX_INFO32 _IOW(USF_IOCTL_MAGIC, 0, \ + struct us_tx_info_type32) +#define US_GET_TX_UPDATE32 _IOWR(USF_IOCTL_MAGIC, 2, \ + struct us_tx_update_info_type32) +#define US_SET_RX_INFO32 _IOW(USF_IOCTL_MAGIC, 3, \ + struct us_rx_info_type32) +#define US_SET_RX_UPDATE32 _IOWR(USF_IOCTL_MAGIC, 4, \ + struct us_rx_update_info_type32) +#define US_SET_DETECTION32 _IOWR(USF_IOCTL_MAGIC, 8, \ + struct us_detect_info_type32) +#define US_GET_VERSION32 _IOWR(USF_IOCTL_MAGIC, 9, \ + struct us_version_info_type32) +#define US_SET_TX_STREAM_PARAM32 _IOW(USF_IOCTL_MAGIC, 10, \ + struct us_stream_param_type32) +#define US_GET_TX_STREAM_PARAM32 _IOWR(USF_IOCTL_MAGIC, 11, \ + struct us_stream_param_type32) +#define US_SET_RX_STREAM_PARAM32 _IOW(USF_IOCTL_MAGIC, 12, \ + struct us_stream_param_type32) +#define US_GET_RX_STREAM_PARAM32 _IOWR(USF_IOCTL_MAGIC, 13, \ + struct us_stream_param_type32) + +/* Info structure common for TX and RX */ +struct us_xx_info_type32 { +/* Input: general info */ +/* Name of the client - event calculator, ptr to char */ + const compat_uptr_t client_name; +/* Selected device identification, accepted in the kernel's CAD */ + uint32_t dev_id; +/* 0 - point_epos type; (e.g. 1 - gr_mmrd) */ + uint32_t stream_format; +/* Required sample rate in Hz */ + uint32_t sample_rate; +/* Size of a buffer (bytes) for US data transfer between the module and USF */ + uint32_t buf_size; +/* Number of the buffers for the US data transfer */ + uint16_t buf_num; +/* Number of the microphones (TX) or speakers(RX) */ + uint16_t port_cnt; +/* Microphones(TX) or speakers(RX) indexes in their enumeration */ + uint8_t port_id[USF_MAX_PORT_NUM]; +/* Bits per sample 16 or 32 */ + uint16_t bits_per_sample; +/* Input: Transparent info for encoder in the LPASS */ +/* Parameters data size in bytes */ + uint16_t params_data_size; +/* Pointer to the parameters, ptr to uint8_t */ + compat_uptr_t params_data; +/* Max size of buffer for get and set parameter */ + uint32_t max_get_set_param_buf_size; +}; + +struct us_tx_info_type32 { +/* Common info. This struct includes ptr and therefore the 32 version */ + struct us_xx_info_type32 us_xx_info; +/* Info specific for TX. This struct doesn't include long or ptr + * and therefore no 32 version + */ + struct us_input_info_type input_info; +}; + +struct us_tx_update_info_type32 { +/* Input general: */ +/* Number of calculated events */ + uint16_t event_counter; +/* Calculated events or NULL, ptr to struct usf_event_type */ + compat_uptr_t event; +/* Pointer (read index) to the end of available region */ +/* in the shared US data memory */ + uint32_t free_region; +/* Time (sec) to wait for data or special values: */ +/* USF_NO_WAIT_TIMEOUT, USF_INFINITIVE_TIMEOUT, USF_DEFAULT_TIMEOUT */ + uint32_t timeout; +/* Events (from conflicting devs) to be disabled/enabled */ + uint16_t event_filters; + +/* Input transparent data: */ +/* Parameters size */ + uint16_t params_data_size; +/* Pointer to the parameters, ptr to uint8_t */ + compat_uptr_t params_data; +/* Output parameters: */ +/* Pointer (write index) to the end of ready US data region */ +/* in the shared memory */ + uint32_t ready_region; +}; + +struct us_rx_info_type32 { + /* Common info */ + struct us_xx_info_type32 us_xx_info; + /* Info specific for RX*/ +}; + +struct us_rx_update_info_type32 { +/* Input general: */ +/* Pointer (write index) to the end of ready US data region */ +/* in the shared memory */ + uint32_t ready_region; +/* Input transparent data: */ +/* Parameters size */ + uint16_t params_data_size; +/* pPointer to the parameters, ptr to uint8_t */ + compat_uptr_t params_data; +/* Output parameters: */ +/* Pointer (read index) to the end of available region */ +/* in the shared US data memory */ + uint32_t free_region; +}; + +struct us_detect_info_type32 { +/* US detection place (HW|FW) */ +/* NA in the Active and OFF states */ + enum us_detect_place_enum us_detector; +/* US detection mode */ + enum us_detect_mode_enum us_detect_mode; +/* US data dropped during this time (msec) */ + uint32_t skip_time; +/* Transparent data size */ + uint16_t params_data_size; +/* Pointer to the transparent data, ptr to uint8_t */ + compat_uptr_t params_data; +/* Time (sec) to wait for US presence event */ + uint32_t detect_timeout; +/* Out parameter: US presence */ + bool is_us; +}; + +struct us_version_info_type32 { +/* Size of memory for the version string */ + uint16_t buf_size; +/* Pointer to the memory for the version string, ptr to char */ + compat_uptr_t pbuf; +}; + +struct us_stream_param_type32 { +/* Id of module */ + uint32_t module_id; +/* Id of parameter */ + uint32_t param_id; +/* Size of memory of the parameter buffer */ + uint32_t buf_size; +/* Pointer to the memory of the parameter buffer */ + compat_uptr_t pbuf; +}; + +static void usf_compat_xx_info_type(struct us_xx_info_type32 *us_xx_info32, + struct us_xx_info_type *us_xx_info) +{ + int i = 0; + + us_xx_info->client_name = compat_ptr(us_xx_info32->client_name); + us_xx_info->dev_id = us_xx_info32->dev_id; + us_xx_info->stream_format = us_xx_info32->stream_format; + us_xx_info->sample_rate = us_xx_info32->sample_rate; + us_xx_info->buf_size = us_xx_info32->buf_size; + us_xx_info->buf_num = us_xx_info32->buf_num; + us_xx_info->port_cnt = us_xx_info32->port_cnt; + for (i = 0; i < USF_MAX_PORT_NUM; i++) + us_xx_info->port_id[i] = us_xx_info32->port_id[i]; + us_xx_info->bits_per_sample = us_xx_info32->bits_per_sample; + us_xx_info->params_data_size = us_xx_info32->params_data_size; + us_xx_info->params_data = compat_ptr(us_xx_info32->params_data); + us_xx_info->max_get_set_param_buf_size = + us_xx_info32->max_get_set_param_buf_size; +} + +static int usf_set_tx_info32(struct usf_type *usf, unsigned long arg) +{ + struct us_tx_info_type32 config_tx32; + struct us_tx_info_type config_tx; + + int rc = copy_from_user(&config_tx32, + (struct us_tx_info_type32 __user *) arg, + sizeof(config_tx32)); + + if (rc) { + pr_err("%s: copy config_tx from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + memset(&config_tx, 0, sizeof(config_tx)); + usf_compat_xx_info_type(&(config_tx32.us_xx_info), + &(config_tx.us_xx_info)); + config_tx.input_info = config_tx32.input_info; + + return __usf_set_tx_info(usf, &config_tx); +} /* usf_set_tx_info 32*/ + +static int usf_set_rx_info32(struct usf_type *usf, unsigned long arg) +{ + struct us_rx_info_type32 config_rx32; + struct us_rx_info_type config_rx; + + int rc = copy_from_user(&config_rx32, + (struct us_rx_info_type32 __user *) arg, + sizeof(config_rx32)); + + if (rc) { + pr_err("%s: copy config_rx from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + memset(&config_rx, 0, sizeof(config_rx)); + usf_compat_xx_info_type(&(config_rx32.us_xx_info), + &(config_rx.us_xx_info)); + + return __usf_set_rx_info(usf, &config_rx); +} /* usf_set_rx_info32 */ + +static int usf_get_tx_update32(struct usf_type *usf, unsigned long arg) +{ + struct us_tx_update_info_type32 upd_tx_info32; + struct us_tx_update_info_type upd_tx_info; + + int rc = copy_from_user(&upd_tx_info32, + (struct us_tx_update_info_type32 __user *) arg, + sizeof(upd_tx_info32)); + + if (rc) { + pr_err("%s: copy upd_tx_info32 from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + memset(&upd_tx_info, 0, sizeof(upd_tx_info)); + upd_tx_info.event_counter = upd_tx_info32.event_counter; + upd_tx_info.event = compat_ptr(upd_tx_info32.event); + upd_tx_info.free_region = upd_tx_info32.free_region; + upd_tx_info.timeout = upd_tx_info32.timeout; + upd_tx_info.event_filters = upd_tx_info32.event_filters; + upd_tx_info.params_data_size = upd_tx_info32.params_data_size; + upd_tx_info.params_data = compat_ptr(upd_tx_info32.params_data); + upd_tx_info.ready_region = upd_tx_info32.ready_region; + + rc = __usf_get_tx_update(usf, &upd_tx_info); + if (rc < 0) { + pr_err("%s: get tx update failed; rc=%d\n", + __func__, rc); + return rc; + } + + /* Update only the fields that were changed */ + upd_tx_info32.ready_region = upd_tx_info.ready_region; + + rc = copy_to_user((void __user *)arg, &upd_tx_info32, + sizeof(upd_tx_info32)); + if (rc) { + pr_err("%s: copy upd_tx_info32 to user; rc=%d\n", + __func__, rc); + rc = -EFAULT; + } + + return rc; +} /* usf_get_tx_update */ + +static int usf_set_rx_update32(struct usf_xx_type *usf_xx, unsigned long arg) +{ + struct us_rx_update_info_type32 upd_rx_info32; + struct us_rx_update_info_type upd_rx_info; + + int rc = copy_from_user(&upd_rx_info32, + (struct us_rx_update_info_type32 __user *) arg, + sizeof(upd_rx_info32)); + + if (rc) { + pr_err("%s: copy upd_rx_info32 from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + memset(&upd_rx_info, 0, sizeof(upd_rx_info)); + upd_rx_info.ready_region = upd_rx_info32.ready_region; + upd_rx_info.params_data_size = upd_rx_info32.params_data_size; + upd_rx_info.params_data = compat_ptr(upd_rx_info32.params_data); + upd_rx_info.free_region = upd_rx_info32.free_region; + + rc = __usf_set_rx_update(usf_xx, &upd_rx_info); + if (rc < 0) { + pr_err("%s: set rx update failed; rc=%d\n", + __func__, rc); + return rc; + } + + /* Update only the fields that were changed */ + upd_rx_info32.free_region = upd_rx_info.free_region; + + rc = copy_to_user((void __user *)arg, + &upd_rx_info32, + sizeof(upd_rx_info32)); + if (rc) { + pr_err("%s: copy rx_info32 to user; rc=%d\n", + __func__, rc); + rc = -EFAULT; + } + + return rc; +} /* usf_set_rx_update32 */ + +static int usf_set_us_detection32(struct usf_type *usf, unsigned long arg) +{ + struct us_detect_info_type32 detect_info32; + struct us_detect_info_type detect_info; + + int rc = copy_from_user(&detect_info32, + (struct us_detect_info_type32 __user *) arg, + sizeof(detect_info32)); + + if (rc) { + pr_err("%s: copy detect_info32 from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + if (detect_info32.params_data_size > USF_MAX_USER_BUF_SIZE) { + pr_err("%s: user buffer size exceeds maximum\n", + __func__); + return -EFAULT; + } + + memset(&detect_info, 0, sizeof(detect_info)); + detect_info.us_detector = detect_info32.us_detector; + detect_info.us_detect_mode = detect_info32.us_detect_mode; + detect_info.skip_time = detect_info32.skip_time; + detect_info.params_data_size = detect_info32.params_data_size; + detect_info.params_data = compat_ptr(detect_info32.params_data); + detect_info.detect_timeout = detect_info32.detect_timeout; + detect_info.is_us = detect_info32.is_us; + + rc = __usf_set_us_detection(usf, &detect_info); + if (rc < 0) { + pr_err("%s: set us detection failed; rc=%d\n", + __func__, rc); + return rc; + } + + /* Update only the fields that were changed */ + detect_info32.is_us = detect_info.is_us; + + rc = copy_to_user((void __user *)arg, + &detect_info32, + sizeof(detect_info32)); + if (rc) { + pr_err("%s: copy detect_info32 to user; rc=%d\n", + __func__, rc); + rc = -EFAULT; + } + + return rc; +} /* usf_set_us_detection32 */ + +static int usf_get_version32(unsigned long arg) +{ + struct us_version_info_type32 version_info32; + struct us_version_info_type version_info; + + int rc = copy_from_user(&version_info32, + (struct us_version_info_type32 __user *) arg, + sizeof(version_info32)); + + if (rc) { + pr_err("%s: copy version_info32 from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + memset(&version_info, 0, sizeof(version_info)); + version_info.buf_size = version_info32.buf_size; + version_info.pbuf = compat_ptr(version_info32.pbuf); + + rc = __usf_get_version(&version_info); + if (rc < 0) { + pr_err("%s: get version failed; rc=%d\n", + __func__, rc); + return rc; + } + + /* None of the fields were changed */ + + rc = copy_to_user((void __user *)arg, + &version_info32, + sizeof(version_info32)); + if (rc) { + pr_err("%s: copy version_info32 to user; rc=%d\n", + __func__, rc); + rc = -EFAULT; + } + + return rc; +} /* usf_get_version32 */ + +static int usf_set_stream_param32(struct usf_xx_type *usf_xx, + unsigned long arg, int dir) +{ + struct us_stream_param_type32 set_stream_param32; + struct us_stream_param_type set_stream_param; + int rc = 0; + + rc = copy_from_user(&set_stream_param32, + (struct us_stream_param_type32 __user *) arg, + sizeof(set_stream_param32)); + + if (rc) { + pr_err("%s: copy set_stream_param from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + memset(&set_stream_param, 0, sizeof(set_stream_param)); + set_stream_param.module_id = set_stream_param32.module_id; + set_stream_param.param_id = set_stream_param32.param_id; + set_stream_param.buf_size = set_stream_param32.buf_size; + set_stream_param.pbuf = compat_ptr(set_stream_param32.pbuf); + + return __usf_set_stream_param(usf_xx, &set_stream_param, dir); +} /* usf_set_stream_param32 */ + +static int usf_get_stream_param32(struct usf_xx_type *usf_xx, + unsigned long arg, int dir) +{ + struct us_stream_param_type32 get_stream_param32; + struct us_stream_param_type get_stream_param; + int rc = 0; + + rc = copy_from_user(&get_stream_param32, + (struct us_stream_param_type32 __user *) arg, + sizeof(get_stream_param32)); + + if (rc) { + pr_err("%s: copy get_stream_param from user; rc=%d\n", + __func__, rc); + return -EFAULT; + } + + memset(&get_stream_param, 0, sizeof(get_stream_param)); + get_stream_param.module_id = get_stream_param32.module_id; + get_stream_param.param_id = get_stream_param32.param_id; + get_stream_param.buf_size = get_stream_param32.buf_size; + get_stream_param.pbuf = compat_ptr(get_stream_param32.pbuf); + + return __usf_get_stream_param(usf_xx, &get_stream_param, dir); +} /* usf_get_stream_param32 */ + +static long __usf_compat_ioctl(struct usf_type *usf, + unsigned int cmd, + unsigned long arg) +{ + int rc = 0; + struct usf_xx_type *usf_xx = NULL; + + switch (cmd) { + case US_START_TX: + case US_START_RX: + case US_STOP_TX: + case US_STOP_RX: { + return __usf_ioctl(usf, cmd, arg); + } + + case US_SET_TX_INFO32: { + usf_xx = &usf->usf_tx; + if (usf_xx->usf_state == USF_OPENED_STATE) + rc = usf_set_tx_info32(usf, arg); + else { + pr_err("%s: set_tx_info32: wrong state[%d]\n", + __func__, + usf_xx->usf_state); + return -EBADFD; + } + + break; + } /* US_SET_TX_INFO32 */ + + case US_SET_RX_INFO32: { + usf_xx = &usf->usf_rx; + if (usf_xx->usf_state == USF_OPENED_STATE) + rc = usf_set_rx_info32(usf, arg); + else { + pr_err("%s: set_rx_info32: wrong state[%d]\n", + __func__, + usf_xx->usf_state); + return -EBADFD; + } + + break; + } /* US_SET_RX_INFO32 */ + + case US_GET_TX_UPDATE32: { + struct usf_xx_type *usf_xx = &usf->usf_tx; + + if (usf_xx->usf_state == USF_WORK_STATE) + rc = usf_get_tx_update32(usf, arg); + else { + pr_err("%s: get_tx_update32: wrong state[%d]\n", + __func__, + usf_xx->usf_state); + rc = -EBADFD; + } + break; + } /* US_GET_TX_UPDATE32 */ + + case US_SET_RX_UPDATE32: { + struct usf_xx_type *usf_xx = &usf->usf_rx; + + if (usf_xx->usf_state == USF_WORK_STATE) + rc = usf_set_rx_update32(usf_xx, arg); + else { + pr_err("%s: set_rx_update: wrong state[%d]\n", + __func__, + usf_xx->usf_state); + rc = -EBADFD; + } + break; + } /* US_SET_RX_UPDATE32 */ + + case US_SET_DETECTION32: { + struct usf_xx_type *usf_xx = &usf->usf_tx; + + if (usf_xx->usf_state == USF_WORK_STATE) + rc = usf_set_us_detection32(usf, arg); + else { + pr_err("%s: set us detection: wrong state[%d]\n", + __func__, + usf_xx->usf_state); + rc = -EBADFD; + } + break; + } /* US_SET_DETECTION32 */ + + case US_GET_VERSION32: { + rc = usf_get_version32(arg); + break; + } /* US_GET_VERSION32 */ + + case US_SET_TX_STREAM_PARAM32: { + rc = usf_set_stream_param32(&usf->usf_tx, arg, OUT); + break; + } /* US_SET_TX_STREAM_PARAM32 */ + + case US_GET_TX_STREAM_PARAM32: { + rc = usf_get_stream_param32(&usf->usf_tx, arg, OUT); + break; + } /* US_GET_TX_STREAM_PARAM32 */ + + case US_SET_RX_STREAM_PARAM32: { + rc = usf_set_stream_param32(&usf->usf_rx, arg, IN); + break; + } /* US_SET_RX_STREAM_PARAM32 */ + + case US_GET_RX_STREAM_PARAM32: { + rc = usf_get_stream_param32(&usf->usf_rx, arg, IN); + break; + } /* US_GET_RX_STREAM_PARAM32 */ + + default: + pr_err("%s: unsupported IOCTL command [%d]\n", + __func__, + cmd); + rc = -ENOTTY; + break; + } + + if (rc && + ((cmd == US_SET_TX_INFO) || + (cmd == US_SET_RX_INFO))) + release_xx(usf_xx); + + return rc; +} /* __usf_compat_ioctl */ + +static long usf_compat_ioctl(struct file *file, + unsigned int cmd, + unsigned long arg) +{ + struct usf_type *usf = file->private_data; + int rc = 0; + + mutex_lock(&usf->mutex); + rc = __usf_compat_ioctl(usf, cmd, arg); + mutex_unlock(&usf->mutex); + + return rc; +} /* usf_compat_ioctl */ +#endif /* CONFIG_COMPAT */ + +static int usf_mmap(struct file *file, struct vm_area_struct *vms) +{ + struct usf_type *usf = file->private_data; + int dir = OUT; + struct usf_xx_type *usf_xx = &usf->usf_tx; + int rc = 0; + + mutex_lock(&usf->mutex); + if (vms->vm_flags & USF_VM_WRITE) { /* RX buf mapping */ + dir = IN; + usf_xx = &usf->usf_rx; + } + rc = q6usm_get_virtual_address(dir, usf_xx->usc, vms); + mutex_unlock(&usf->mutex); + + return rc; +} + +static uint16_t add_opened_dev(int minor) +{ + uint16_t ind = 0; + + for (ind = 0; ind < MAX_DEVS_NUMBER; ++ind) { + if (minor == atomic_cmpxchg(&s_opened_devs[ind], 0, minor)) { + pr_err("%s: device %d is already opened\n", + __func__, minor); + return USF_UNDEF_DEV_ID; + } else { + pr_debug("%s: device %d is added; ind=%d\n", + __func__, minor, ind); + return ind; + } + } + + pr_err("%s: there is no place for device %d\n", + __func__, minor); + return USF_UNDEF_DEV_ID; +} + +static int usf_open(struct inode *inode, struct file *file) +{ + struct usf_type *usf = NULL; + uint16_t dev_ind = 0; + int minor = MINOR(inode->i_rdev); + + dev_ind = add_opened_dev(minor); + if (dev_ind == USF_UNDEF_DEV_ID) + return -EBUSY; + + usf = kzalloc(sizeof(struct usf_type), GFP_KERNEL); + if (usf == NULL) + return -ENOMEM; + + wakeup_source_init(&usf_wakeup_source, "usf"); + + file->private_data = usf; + usf->dev_ind = dev_ind; + + usf->usf_tx.usf_state = USF_OPENED_STATE; + usf->usf_rx.usf_state = USF_OPENED_STATE; + + usf->usf_tx.us_detect_type = USF_US_DETECT_UNDEF; + usf->usf_rx.us_detect_type = USF_US_DETECT_UNDEF; + + mutex_init(&usf->mutex); + + pr_debug("%s:usf in open\n", __func__); + return 0; +} + +static int usf_release(struct inode *inode, struct file *file) +{ + struct usf_type *usf = file->private_data; + + pr_debug("%s: release entry\n", __func__); + + mutex_lock(&usf->mutex); + usf_release_input(usf); + + usf_disable(&usf->usf_tx); + usf_disable(&usf->usf_rx); + + atomic_set(&s_opened_devs[usf->dev_ind], 0); + + wakeup_source_trash(&usf_wakeup_source); + mutex_unlock(&usf->mutex); + mutex_destroy(&usf->mutex); + kfree(usf); + pr_debug("%s: release exit\n", __func__); + return 0; +} + +extern long usf_compat_ioctl(struct file *file, + unsigned int cmd, + unsigned long arg); + +static const struct file_operations usf_fops = { + .owner = THIS_MODULE, + .open = usf_open, + .release = usf_release, + .unlocked_ioctl = usf_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = usf_compat_ioctl, +#endif /* CONFIG_COMPAT */ + .mmap = usf_mmap, +}; + +static struct miscdevice usf_misc[MAX_DEVS_NUMBER] = { + { + .minor = MISC_DYNAMIC_MINOR, + .name = "usf1", + .fops = &usf_fops, + }, +}; + +static int __init usf_init(void) +{ + int rc = 0; + uint16_t ind = 0; + + pr_debug("%s: USF SW version %s.\n", __func__, DRV_VERSION); + pr_debug("%s: Max %d devs registration\n", __func__, MAX_DEVS_NUMBER); + + for (ind = 0; ind < MAX_DEVS_NUMBER; ++ind) { + rc = misc_register(&usf_misc[ind]); + if (rc) { + pr_err("%s: misc_register() failed ind=%d; rc = %d\n", + __func__, ind, rc); + break; + } + } + + return rc; +} + +device_initcall(usf_init); + +MODULE_DESCRIPTION("Ultrasound framework driver"); diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.c b/drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.c new file mode 100644 index 000000000000..6b8aae01ec53 --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.c @@ -0,0 +1,422 @@ +/* Copyright (c) 2012-2013, 2016-2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "usfcdev.h" + +#define UNDEF_ID 0xffffffff +#define SLOT_CMD_ID 0 +#define MAX_RETRIES 10 + +enum usdev_event_status { + USFCDEV_EVENT_ENABLED, + USFCDEV_EVENT_DISABLING, + USFCDEV_EVENT_DISABLED, +}; + +struct usfcdev_event { + bool (*match_cb)(uint16_t, struct input_dev *dev); + bool registered_event; + bool interleaved; + enum usdev_event_status event_status; +}; +static struct usfcdev_event s_usfcdev_events[MAX_EVENT_TYPE_NUM]; + +struct usfcdev_input_command { + unsigned int type; + unsigned int code; + unsigned int value; +}; + +static long s_usf_pid; + +static bool usfcdev_filter(struct input_handle *handle, + unsigned int type, unsigned int code, int value); +static bool usfcdev_match(struct input_handler *handler, + struct input_dev *dev); +static int usfcdev_connect(struct input_handler *handler, + struct input_dev *dev, + const struct input_device_id *id); +static void usfcdev_disconnect(struct input_handle *handle); + +static const struct input_device_id usfc_tsc_ids[] = { + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | + INPUT_DEVICE_ID_MATCH_KEYBIT | + INPUT_DEVICE_ID_MATCH_ABSBIT, + .evbit = { BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY) }, + .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, + /* assumption: ABS_X & ABS_Y are in the same long */ + .absbit = { [BIT_WORD(ABS_X)] = BIT_MASK(ABS_X) | + BIT_MASK(ABS_Y) }, + }, + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | + INPUT_DEVICE_ID_MATCH_KEYBIT | + INPUT_DEVICE_ID_MATCH_ABSBIT, + .evbit = { BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY) }, + .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, + /* assumption: MT_.._X & MT_.._Y are in the same long */ + .absbit = { [BIT_WORD(ABS_MT_POSITION_X)] = + BIT_MASK(ABS_MT_POSITION_X) | + BIT_MASK(ABS_MT_POSITION_Y) }, + }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(input, usfc_tsc_ids); + +static struct input_handler s_usfc_handlers[MAX_EVENT_TYPE_NUM] = { + { /* TSC handler */ + .filter = usfcdev_filter, + .match = usfcdev_match, + .connect = usfcdev_connect, + .disconnect = usfcdev_disconnect, + /* .minor can be used as index in the container, */ + /* because .fops isn't supported */ + .minor = TSC_EVENT_TYPE_IND, + .name = "usfc_tsc_handler", + .id_table = usfc_tsc_ids, + }, +}; + +/* + * For each event type, there are a number conflicting devices (handles) + * The first registered device (primary) is real TSC device; it's mandatory + * Optionally, later registered devices are simulated ones. + * They are dynamically managed + * The primary device's handles are stored in the below static array + */ +static struct input_handle s_usfc_primary_handles[MAX_EVENT_TYPE_NUM] = { + { /* TSC handle */ + .handler = &s_usfc_handlers[TSC_EVENT_TYPE_IND], + .name = "usfc_tsc_handle", + }, +}; + +static struct usfcdev_input_command initial_clear_cmds[] = { + {EV_ABS, ABS_PRESSURE, 0}, + {EV_KEY, BTN_TOUCH, 0}, +}; + +static struct usfcdev_input_command slot_clear_cmds[] = { + {EV_ABS, ABS_MT_SLOT, 0}, + {EV_ABS, ABS_MT_TRACKING_ID, UNDEF_ID}, +}; + +static struct usfcdev_input_command no_filter_cmds[] = { + {EV_ABS, ABS_MT_SLOT, 0}, + {EV_ABS, ABS_MT_TRACKING_ID, UNDEF_ID}, + {EV_SYN, SYN_REPORT, 0}, +}; + +static bool usfcdev_match(struct input_handler *handler, struct input_dev *dev) +{ + bool rc = false; + int ind = handler->minor; + + pr_debug("%s: name=[%s]; ind=%d\n", __func__, dev->name, ind); + + if (s_usfcdev_events[ind].registered_event && + s_usfcdev_events[ind].match_cb) { + rc = (*s_usfcdev_events[ind].match_cb)((uint16_t)ind, dev); + pr_debug("%s: [%s]; rc=%d\n", __func__, dev->name, rc); + } + return rc; +} + +static int usfcdev_connect(struct input_handler *handler, struct input_dev *dev, + const struct input_device_id *id) +{ + int ret = 0; + uint16_t ind = handler->minor; + struct input_handle *usfc_handle = NULL; + + if (s_usfc_primary_handles[ind].dev == NULL) { + pr_debug("%s: primary device; ind=%d\n", + __func__, + ind); + usfc_handle = &s_usfc_primary_handles[ind]; + } else { + pr_debug("%s: secondary device; ind=%d\n", + __func__, + ind); + usfc_handle = kzalloc(sizeof(struct input_handle), + GFP_KERNEL); + if (!usfc_handle) + return -ENOMEM; + + usfc_handle->handler = &s_usfc_handlers[ind]; + usfc_handle->name = s_usfc_primary_handles[ind].name; + } + usfc_handle->dev = dev; + ret = input_register_handle(usfc_handle); + pr_debug("%s: name=[%s]; ind=%d; dev=0x%pK\n", + __func__, + dev->name, + ind, + usfc_handle->dev); + if (ret) + pr_err("%s: input_register_handle[%d] failed: ret=%d\n", + __func__, + ind, + ret); + else { + ret = input_open_device(usfc_handle); + if (ret) { + pr_err("%s: input_open_device[%d] failed: ret=%d\n", + __func__, + ind, + ret); + input_unregister_handle(usfc_handle); + } else + pr_debug("%s: device[%d] is opened\n", + __func__, + ind); + } + + return ret; +} + +static void usfcdev_disconnect(struct input_handle *handle) +{ + int ind = handle->handler->minor; + + input_close_device(handle); + input_unregister_handle(handle); + pr_debug("%s: handle[%d], name=[%s] is disconnected\n", + __func__, + ind, + handle->dev->name); + if (s_usfc_primary_handles[ind].dev == handle->dev) + s_usfc_primary_handles[ind].dev = NULL; + else + kfree(handle); +} + +static bool usfcdev_filter(struct input_handle *handle, + unsigned int type, unsigned int code, int value) +{ + uint16_t i = 0; + uint16_t ind = (uint16_t)handle->handler->minor; + bool rc = (s_usfcdev_events[ind].event_status != USFCDEV_EVENT_ENABLED); + + if (s_usf_pid == sys_getpid()) { + /* Pass events from usfcdev driver */ + rc = false; + pr_debug("%s: event_type=%d; type=%d; code=%d; val=%d", + __func__, + ind, + type, + code, + value); + } else if (s_usfcdev_events[ind].event_status == + USFCDEV_EVENT_DISABLING) { + uint32_t u_value = value; + + s_usfcdev_events[ind].interleaved = true; + /* Pass events for freeing slots from TSC driver */ + for (i = 0; i < ARRAY_SIZE(no_filter_cmds); ++i) { + if ((no_filter_cmds[i].type == type) && + (no_filter_cmds[i].code == code) && + (no_filter_cmds[i].value <= u_value)) { + rc = false; + pr_debug("%s: no_filter_cmds[%d]; %d", + __func__, + i, + no_filter_cmds[i].value); + break; + } + } + } + + return rc; +} + +bool usfcdev_register( + uint16_t event_type_ind, + bool (*match_cb)(uint16_t, struct input_dev *dev)) +{ + int ret = 0; + bool rc = false; + + if ((event_type_ind >= MAX_EVENT_TYPE_NUM) || !match_cb) { + pr_err("%s: wrong input: event_type_ind=%d; match_cb=0x%pK\n", + __func__, + event_type_ind, + match_cb); + return false; + } + + if (s_usfcdev_events[event_type_ind].registered_event) { + pr_info("%s: handler[%d] was already registered\n", + __func__, + event_type_ind); + return true; + } + + s_usfcdev_events[event_type_ind].registered_event = true; + s_usfcdev_events[event_type_ind].match_cb = match_cb; + s_usfcdev_events[event_type_ind].event_status = USFCDEV_EVENT_ENABLED; + ret = input_register_handler(&s_usfc_handlers[event_type_ind]); + if (!ret) { + rc = true; + pr_debug("%s: handler[%d] was registered\n", + __func__, + event_type_ind); + } else { + s_usfcdev_events[event_type_ind].registered_event = false; + s_usfcdev_events[event_type_ind].match_cb = NULL; + pr_err("%s: handler[%d] registration failed: ret=%d\n", + __func__, + event_type_ind, + ret); + } + + return rc; +} + +void usfcdev_unregister(uint16_t event_type_ind) +{ + if (event_type_ind >= MAX_EVENT_TYPE_NUM) { + pr_err("%s: wrong input: event_type_ind=%d\n", + __func__, + event_type_ind); + return; + } + if (s_usfcdev_events[event_type_ind].registered_event) { + input_unregister_handler(&s_usfc_handlers[event_type_ind]); + pr_debug("%s: handler[%d] was unregistered\n", + __func__, + event_type_ind); + s_usfcdev_events[event_type_ind].registered_event = false; + s_usfcdev_events[event_type_ind].match_cb = NULL; + s_usfcdev_events[event_type_ind].event_status = + USFCDEV_EVENT_ENABLED; + + } +} + +static inline void usfcdev_send_cmd( + struct input_dev *dev, + struct usfcdev_input_command cmd) +{ + input_event(dev, cmd.type, cmd.code, cmd.value); +} + +static void usfcdev_clean_dev(uint16_t event_type_ind) +{ + struct input_dev *dev = NULL; + int i; + int j; + int retries = 0; + + if (event_type_ind >= MAX_EVENT_TYPE_NUM) { + pr_err("%s: wrong input: event_type_ind=%d\n", + __func__, + event_type_ind); + return; + } + /* Only primary device must exist */ + dev = s_usfc_primary_handles[event_type_ind].dev; + if (dev == NULL) { + pr_err("%s: NULL primary device\n", + __func__); + return; + } + + for (i = 0; i < ARRAY_SIZE(initial_clear_cmds); i++) + usfcdev_send_cmd(dev, initial_clear_cmds[i]); + input_sync(dev); + + /* Send commands to free all slots */ + for (i = 0; i < dev->mt->num_slots; i++) { + s_usfcdev_events[event_type_ind].interleaved = false; + if (input_mt_get_value(&dev->mt->slots[i], + ABS_MT_TRACKING_ID) < 0) { + pr_debug("%s: skipping slot %d", + __func__, i); + continue; + } + slot_clear_cmds[SLOT_CMD_ID].value = i; + for (j = 0; j < ARRAY_SIZE(slot_clear_cmds); j++) + usfcdev_send_cmd(dev, slot_clear_cmds[j]); + + if (s_usfcdev_events[event_type_ind].interleaved) { + pr_debug("%s: interleaved(%d): slot(%d)", + __func__, i, dev->mt->slot); + if (retries++ < MAX_RETRIES) { + --i; + continue; + } + pr_warn("%s: index(%d) reached max retires", + __func__, i); + } + + retries = 0; + input_sync(dev); + } +} + +bool usfcdev_set_filter(uint16_t event_type_ind, bool filter) +{ + bool rc = true; + + if (event_type_ind >= MAX_EVENT_TYPE_NUM) { + pr_err("%s: wrong input: event_type_ind=%d\n", + __func__, + event_type_ind); + return false; + } + + if (s_usfcdev_events[event_type_ind].registered_event) { + + pr_debug("%s: event_type[%d]; filter=%d\n", + __func__, + event_type_ind, + filter + ); + if (filter) { + s_usfcdev_events[event_type_ind].event_status = + USFCDEV_EVENT_DISABLING; + s_usf_pid = sys_getpid(); + usfcdev_clean_dev(event_type_ind); + s_usfcdev_events[event_type_ind].event_status = + USFCDEV_EVENT_DISABLED; + } else + s_usfcdev_events[event_type_ind].event_status = + USFCDEV_EVENT_ENABLED; + } else { + pr_err("%s: event_type[%d] isn't registered\n", + __func__, + event_type_ind); + rc = false; + } + + return rc; +} + +static int __init usfcdev_init(void) +{ + return 0; +} + +device_initcall(usfcdev_init); + +MODULE_DESCRIPTION("Handle of events from devices, conflicting with USF"); diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.h b/drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.h new file mode 100644 index 000000000000..03b62c5ec83c --- /dev/null +++ b/drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.h @@ -0,0 +1,28 @@ +/* Copyright (c) 2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __USFCDEV_H__ +#define __USFCDEV_H__ + +#include + +/* TSC event type index in the containers of the handlers & handles */ +#define TSC_EVENT_TYPE_IND 0 +/* Number of supported event types to be filtered */ +#define MAX_EVENT_TYPE_NUM 1 + +bool usfcdev_register( + uint16_t event_type_ind, + bool (*match_cb)(uint16_t, struct input_dev *dev)); +void usfcdev_unregister(uint16_t event_type_ind); +bool usfcdev_set_filter(uint16_t event_type_ind, bool filter); +#endif /* __USFCDEV_H__ */ diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile new file mode 100644 index 000000000000..0e0c511e18d9 --- /dev/null +++ b/drivers/pinctrl/Makefile @@ -0,0 +1,2 @@ + +obj-y += qcom/ diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h new file mode 120000 index 000000000000..2b68c81aa5d3 --- /dev/null +++ b/drivers/pinctrl/core.h @@ -0,0 +1 @@ +../../../../drivers/pinctrl/core.h \ No newline at end of file diff --git a/drivers/pinctrl/pinctrl-utils.h b/drivers/pinctrl/pinctrl-utils.h new file mode 120000 index 000000000000..3303afdf9f46 --- /dev/null +++ b/drivers/pinctrl/pinctrl-utils.h @@ -0,0 +1 @@ +../../../../drivers/pinctrl/pinctrl-utils.h \ No newline at end of file diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile new file mode 100644 index 000000000000..cd1b749ae5ee --- /dev/null +++ b/drivers/pinctrl/qcom/Makefile @@ -0,0 +1,3 @@ + +obj-$(CONFIG_PINCTRL_WCD) += pinctrl-wcd.o +obj-$(CONFIG_PINCTRL_LPI) += pinctrl-lpi.o diff --git a/drivers/pinctrl/qcom/pinctrl-lpi.c b/drivers/pinctrl/qcom/pinctrl-lpi.c new file mode 100644 index 000000000000..fedd5f0aee22 --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-lpi.c @@ -0,0 +1,647 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../core.h" +#include "../pinctrl-utils.h" + +#define LPI_ADDRESS_SIZE 0xC000 + +#define LPI_GPIO_REG_VAL_CTL 0x00 +#define LPI_GPIO_REG_DIR_CTL 0x04 + +#define LPI_GPIO_REG_PULL_SHIFT 0x0 +#define LPI_GPIO_REG_PULL_MASK 0x3 + +#define LPI_GPIO_REG_FUNCTION_SHIFT 0x2 +#define LPI_GPIO_REG_FUNCTION_MASK 0x3C + +#define LPI_GPIO_REG_OUT_STRENGTH_SHIFT 0x6 +#define LPI_GPIO_REG_OUT_STRENGTH_MASK 0x1C0 + +#define LPI_GPIO_REG_OE_SHIFT 0x9 +#define LPI_GPIO_REG_OE_MASK 0x200 + +#define LPI_GPIO_REG_DIR_SHIFT 0x1 +#define LPI_GPIO_REG_DIR_MASK 0x2 + +#define LPI_GPIO_BIAS_DISABLE 0x0 +#define LPI_GPIO_PULL_DOWN 0x1 +#define LPI_GPIO_KEEPER 0x2 +#define LPI_GPIO_PULL_UP 0x3 + +#define LPI_GPIO_FUNC_GPIO "gpio" +#define LPI_GPIO_FUNC_FUNC1 "func1" +#define LPI_GPIO_FUNC_FUNC2 "func2" +#define LPI_GPIO_FUNC_FUNC3 "func3" +#define LPI_GPIO_FUNC_FUNC4 "func4" +#define LPI_GPIO_FUNC_FUNC5 "func5" + +static bool lpi_dev_up; + +/* The index of each function in lpi_gpio_functions[] array */ +enum lpi_gpio_func_index { + LPI_GPIO_FUNC_INDEX_GPIO = 0x00, + LPI_GPIO_FUNC_INDEX_FUNC1 = 0x01, + LPI_GPIO_FUNC_INDEX_FUNC2 = 0x02, + LPI_GPIO_FUNC_INDEX_FUNC3 = 0x03, + LPI_GPIO_FUNC_INDEX_FUNC4 = 0x04, + LPI_GPIO_FUNC_INDEX_FUNC5 = 0x05, +}; + +/** + * struct lpi_gpio_pad - keep current GPIO settings + * @offset: Nth GPIO in supported GPIOs. + * @output_enabled: Set to true if GPIO output logic is enabled. + * @value: value of a pin + * @base: Address base of LPI GPIO PAD. + * @pullup: Constant current which flow through GPIO output buffer. + * @strength: No, Low, Medium, High + * @function: See lpi_gpio_functions[] + */ +struct lpi_gpio_pad { + u16 offset; + bool output_enabled; + bool value; + char __iomem *base; + unsigned int pullup; + unsigned int strength; + unsigned int function; +}; + +struct lpi_gpio_state { + struct device *dev; + struct pinctrl_dev *ctrl; + struct gpio_chip chip; + char __iomem *base; +}; + +static const char *const lpi_gpio_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", + "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", + "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", + "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", + "gpio29", "gpio30", "gpio31", +}; + +static const u32 lpi_offset[] = { + 0x00000000, + 0x00001000, + 0x00002000, + 0x00002010, + 0x00003000, + 0x00003010, + 0x00004000, + 0x00004010, + 0x00005000, + 0x00005010, + 0x00005020, + 0x00005030, + 0x00006000, + 0x00006010, + 0x00007000, + 0x00007010, + 0x00005040, + 0x00005050, + 0x00008000, + 0x00008010, + 0x00008020, + 0x00008030, + 0x00008040, + 0x00008050, + 0x00008060, + 0x00008070, + 0x00009000, + 0x00009010, + 0x0000A000, + 0x0000A010, + 0x0000B000, + 0x0000B010, +}; + +static const char *const lpi_gpio_functions[] = { + [LPI_GPIO_FUNC_INDEX_GPIO] = LPI_GPIO_FUNC_GPIO, + [LPI_GPIO_FUNC_INDEX_FUNC1] = LPI_GPIO_FUNC_FUNC1, + [LPI_GPIO_FUNC_INDEX_FUNC2] = LPI_GPIO_FUNC_FUNC2, + [LPI_GPIO_FUNC_INDEX_FUNC3] = LPI_GPIO_FUNC_FUNC3, + [LPI_GPIO_FUNC_INDEX_FUNC4] = LPI_GPIO_FUNC_FUNC4, + [LPI_GPIO_FUNC_INDEX_FUNC5] = LPI_GPIO_FUNC_FUNC5, +}; + +static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr) +{ + int ret; + + if (!lpi_dev_up) { + pr_err_ratelimited("%s: ADSP is down due to SSR, return\n", + __func__); + return 0; + } + + ret = ioread32(pad->base + pad->offset + addr); + if (ret < 0) + pr_err("%s: read 0x%x failed\n", __func__, addr); + + return ret; +} + +static int lpi_gpio_write(struct lpi_gpio_pad *pad, unsigned int addr, + unsigned int val) +{ + if (!lpi_dev_up) { + pr_err_ratelimited("%s: ADSP is down due to SSR, return\n", + __func__); + return 0; + } + + iowrite32(val, pad->base + pad->offset + addr); + return 0; +} + +static int lpi_gpio_get_groups_count(struct pinctrl_dev *pctldev) +{ + /* Every PIN is a group */ + return pctldev->desc->npins; +} + +static const char *lpi_gpio_get_group_name(struct pinctrl_dev *pctldev, + unsigned int pin) +{ + return pctldev->desc->pins[pin].name; +} + +static int lpi_gpio_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int pin, + const unsigned int **pins, + unsigned int *num_pins) +{ + *pins = &pctldev->desc->pins[pin].number; + *num_pins = 1; + return 0; +} + +static const struct pinctrl_ops lpi_gpio_pinctrl_ops = { + .get_groups_count = lpi_gpio_get_groups_count, + .get_group_name = lpi_gpio_get_group_name, + .get_group_pins = lpi_gpio_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_group, + .dt_free_map = pinctrl_utils_free_map, +}; + +static int lpi_gpio_get_functions_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(lpi_gpio_functions); +} + +static const char *lpi_gpio_get_function_name(struct pinctrl_dev *pctldev, + unsigned int function) +{ + return lpi_gpio_functions[function]; +} + +static int lpi_gpio_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int function, + const char *const **groups, + unsigned *const num_qgroups) +{ + *groups = lpi_gpio_groups; + *num_qgroups = pctldev->desc->npins; + return 0; +} + +static int lpi_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int function, + unsigned int pin) +{ + struct lpi_gpio_pad *pad; + unsigned int val; + + pad = pctldev->desc->pins[pin].drv_data; + + pad->function = function; + + val = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL); + val &= ~(LPI_GPIO_REG_FUNCTION_MASK); + val |= pad->function << LPI_GPIO_REG_FUNCTION_SHIFT; + lpi_gpio_write(pad, LPI_GPIO_REG_VAL_CTL, val); + return 0; +} + +static const struct pinmux_ops lpi_gpio_pinmux_ops = { + .get_functions_count = lpi_gpio_get_functions_count, + .get_function_name = lpi_gpio_get_function_name, + .get_function_groups = lpi_gpio_get_function_groups, + .set_mux = lpi_gpio_set_mux, +}; + +static int lpi_config_get(struct pinctrl_dev *pctldev, + unsigned int pin, unsigned long *config) +{ + unsigned int param = pinconf_to_config_param(*config); + struct lpi_gpio_pad *pad; + unsigned int arg; + + pad = pctldev->desc->pins[pin].drv_data; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + arg = pad->pullup = LPI_GPIO_BIAS_DISABLE; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + arg = pad->pullup == LPI_GPIO_PULL_DOWN; + break; + case PIN_CONFIG_BIAS_BUS_HOLD: + arg = pad->pullup = LPI_GPIO_KEEPER; + break; + case PIN_CONFIG_BIAS_PULL_UP: + arg = pad->pullup == LPI_GPIO_PULL_UP; + break; + case PIN_CONFIG_INPUT_ENABLE: + case PIN_CONFIG_OUTPUT: + arg = pad->output_enabled; + break; + default: + return -EINVAL; + } + + *config = pinconf_to_config_packed(param, arg); + return 0; +} + +static unsigned int lpi_drive_to_regval(u32 arg) +{ + return (arg/2 - 1); +} + +static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int nconfs) +{ + struct lpi_gpio_pad *pad; + unsigned int param, arg; + int i, ret = 0, val; + + pad = pctldev->desc->pins[pin].drv_data; + + for (i = 0; i < nconfs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + dev_dbg(pctldev->dev, "%s: param: %d arg: %d pin: %d\n", + __func__, param, arg, pin); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + pad->pullup = LPI_GPIO_BIAS_DISABLE; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + pad->pullup = LPI_GPIO_PULL_DOWN; + break; + case PIN_CONFIG_BIAS_BUS_HOLD: + pad->pullup = LPI_GPIO_KEEPER; + break; + case PIN_CONFIG_BIAS_PULL_UP: + pad->pullup = LPI_GPIO_PULL_UP; + break; + case PIN_CONFIG_INPUT_ENABLE: + pad->output_enabled = false; + break; + case PIN_CONFIG_OUTPUT: + pad->output_enabled = true; + pad->value = arg; + break; + case PIN_CONFIG_DRIVE_STRENGTH: + pad->strength = arg; + break; + default: + ret = -EINVAL; + goto done; + } + } + + val = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL); + val &= ~(LPI_GPIO_REG_PULL_MASK | LPI_GPIO_REG_OUT_STRENGTH_MASK | + LPI_GPIO_REG_OE_MASK); + val |= pad->pullup << LPI_GPIO_REG_PULL_SHIFT; + val |= lpi_drive_to_regval(pad->strength) << + LPI_GPIO_REG_OUT_STRENGTH_SHIFT; + if (pad->output_enabled) + val |= pad->value << LPI_GPIO_REG_OE_SHIFT; + + lpi_gpio_write(pad, LPI_GPIO_REG_VAL_CTL, val); + lpi_gpio_write(pad, LPI_GPIO_REG_DIR_CTL, + pad->output_enabled << LPI_GPIO_REG_DIR_SHIFT); +done: + return ret; +} + +static const struct pinconf_ops lpi_gpio_pinconf_ops = { + .is_generic = true, + .pin_config_group_get = lpi_config_get, + .pin_config_group_set = lpi_config_set, +}; + +static int lpi_gpio_direction_input(struct gpio_chip *chip, unsigned int pin) +{ + struct lpi_gpio_state *state = gpiochip_get_data(chip); + unsigned long config; + + config = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1); + + return lpi_config_set(state->ctrl, pin, &config, 1); +} + +static int lpi_gpio_direction_output(struct gpio_chip *chip, + unsigned int pin, int val) +{ + struct lpi_gpio_state *state = gpiochip_get_data(chip); + unsigned long config; + + config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, val); + + return lpi_config_set(state->ctrl, pin, &config, 1); +} + +static int lpi_gpio_get(struct gpio_chip *chip, unsigned int pin) +{ + struct lpi_gpio_state *state = gpiochip_get_data(chip); + struct lpi_gpio_pad *pad; + int value; + + pad = state->ctrl->desc->pins[pin].drv_data; + + value = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL); + return value; +} + +static void lpi_gpio_set(struct gpio_chip *chip, unsigned int pin, int value) +{ + struct lpi_gpio_state *state = gpiochip_get_data(chip); + unsigned long config; + + config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, value); + + lpi_config_set(state->ctrl, pin, &config, 1); +} + +static int lpi_notifier_service_cb(struct notifier_block *this, + unsigned long opcode, void *ptr) +{ + static bool initial_boot = true; + + pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); + + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + if (initial_boot) { + initial_boot = false; + break; + } + lpi_dev_up = false; + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (initial_boot) + initial_boot = false; + lpi_dev_up = true; + break; + default: + break; + } + return NOTIFY_OK; +} + +static struct notifier_block service_nb = { + .notifier_call = lpi_notifier_service_cb, + .priority = -INT_MAX, +}; + +#ifdef CONFIG_DEBUG_FS +#include + +static unsigned int lpi_regval_to_drive(u32 val) +{ + return (val + 1) * 2; +} + +static void lpi_gpio_dbg_show_one(struct seq_file *s, + struct pinctrl_dev *pctldev, + struct gpio_chip *chip, + unsigned int offset, + unsigned int gpio) +{ + struct pinctrl_pin_desc pindesc; + struct lpi_gpio_pad *pad; + unsigned int func; + int is_out; + int drive; + int pull; + u32 ctl_reg; + + static const char * const pulls[] = { + "no pull", + "pull down", + "keeper", + "pull up" + }; + + pctldev = pctldev ? : to_gpio_state(chip)->ctrl; + pindesc = pctldev->desc->pins[offset]; + pad = pctldev->desc->pins[offset].drv_data; + ctl_reg = lpi_gpio_read(pad, LPI_GPIO_REG_DIR_CTL); + is_out = (ctl_reg & LPI_GPIO_REG_DIR_MASK) >> LPI_GPIO_REG_DIR_SHIFT; + ctl_reg = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL); + + func = (ctl_reg & LPI_GPIO_REG_FUNCTION_MASK) >> + LPI_GPIO_REG_FUNCTION_SHIFT; + drive = (ctl_reg & LPI_GPIO_REG_OUT_STRENGTH_MASK) >> + LPI_GPIO_REG_OUT_STRENGTH_SHIFT; + pull = (ctl_reg & LPI_GPIO_REG_PULL_MASK) >> LPI_GPIO_REG_PULL_SHIFT; + + seq_printf(s, " %-8s: %-3s %d", + pindesc.name, is_out ? "out" : "in", func); + seq_printf(s, " %dmA", lpi_regval_to_drive(drive)); + seq_printf(s, " %s", pulls[pull]); +} + +static void lpi_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) +{ + unsigned int gpio = chip->base; + unsigned int i; + + for (i = 0; i < chip->ngpio; i++, gpio++) { + lpi_gpio_dbg_show_one(s, NULL, chip, i, gpio); + seq_puts(s, "\n"); + } +} + +#else +#define lpi_gpio_dbg_show NULL +#endif + +static const struct gpio_chip lpi_gpio_template = { + .direction_input = lpi_gpio_direction_input, + .direction_output = lpi_gpio_direction_output, + .get = lpi_gpio_get, + .set = lpi_gpio_set, + .request = gpiochip_generic_request, + .free = gpiochip_generic_free, + .dbg_show = lpi_gpio_dbg_show, +}; + +static int lpi_pinctrl_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct pinctrl_pin_desc *pindesc; + struct pinctrl_desc *pctrldesc; + struct lpi_gpio_pad *pad, *pads; + struct lpi_gpio_state *state; + int ret, npins, i; + char __iomem *lpi_base; + u32 reg; + + ret = of_property_read_u32(dev->of_node, "reg", ®); + if (ret < 0) { + dev_err(dev, "missing base address\n"); + return ret; + } + + ret = of_property_read_u32(dev->of_node, "qcom,num-gpios", &npins); + if (ret < 0) + return ret; + + WARN_ON(npins > ARRAY_SIZE(lpi_gpio_groups)); + + state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); + if (!state) + return -ENOMEM; + + platform_set_drvdata(pdev, state); + + state->dev = &pdev->dev; + + pindesc = devm_kcalloc(dev, npins, sizeof(*pindesc), GFP_KERNEL); + if (!pindesc) + return -ENOMEM; + + pads = devm_kcalloc(dev, npins, sizeof(*pads), GFP_KERNEL); + if (!pads) + return -ENOMEM; + + pctrldesc = devm_kzalloc(dev, sizeof(*pctrldesc), GFP_KERNEL); + if (!pctrldesc) + return -ENOMEM; + + pctrldesc->pctlops = &lpi_gpio_pinctrl_ops; + pctrldesc->pmxops = &lpi_gpio_pinmux_ops; + pctrldesc->confops = &lpi_gpio_pinconf_ops; + pctrldesc->owner = THIS_MODULE; + pctrldesc->name = dev_name(dev); + pctrldesc->pins = pindesc; + pctrldesc->npins = npins; + + lpi_base = devm_ioremap(dev, reg, LPI_ADDRESS_SIZE); + if (lpi_base == NULL) { + dev_err(dev, "%s devm_ioremap failed\n", __func__); + return -ENOMEM; + } + + state->base = lpi_base; + + for (i = 0; i < npins; i++, pindesc++) { + pad = &pads[i]; + pindesc->drv_data = pad; + pindesc->number = i; + pindesc->name = lpi_gpio_groups[i]; + + pad->base = lpi_base; + pad->offset = lpi_offset[i]; + } + + state->chip = lpi_gpio_template; + state->chip.parent = dev; + state->chip.base = -1; + state->chip.ngpio = npins; + state->chip.label = dev_name(dev); + state->chip.of_gpio_n_cells = 2; + state->chip.can_sleep = false; + + state->ctrl = devm_pinctrl_register(dev, pctrldesc, state); + if (IS_ERR(state->ctrl)) + return PTR_ERR(state->ctrl); + + ret = gpiochip_add_data(&state->chip, state); + if (ret) { + dev_err(state->dev, "can't add gpio chip\n"); + goto err_chip; + } + + ret = gpiochip_add_pin_range(&state->chip, dev_name(dev), 0, 0, npins); + if (ret) { + dev_err(dev, "failed to add pin range\n"); + goto err_range; + } + + lpi_dev_up = true; + ret = audio_notifier_register("lpi_tlmm", AUDIO_NOTIFIER_ADSP_DOMAIN, + &service_nb); + if (ret < 0) { + pr_err("%s: Audio notifier register failed ret = %d\n", + __func__, ret); + goto err_range; + } + + return 0; + +err_range: + gpiochip_remove(&state->chip); +err_chip: + return ret; +} + +static int lpi_pinctrl_remove(struct platform_device *pdev) +{ + struct lpi_gpio_state *state = platform_get_drvdata(pdev); + + gpiochip_remove(&state->chip); + return 0; +} + +static const struct of_device_id lpi_pinctrl_of_match[] = { + { .compatible = "qcom,lpi-pinctrl" }, /* Generic */ + { }, +}; + +MODULE_DEVICE_TABLE(of, lpi_pinctrl_of_match); + +static struct platform_driver lpi_pinctrl_driver = { + .driver = { + .name = "qcom-lpi-pinctrl", + .of_match_table = lpi_pinctrl_of_match, + }, + .probe = lpi_pinctrl_probe, + .remove = lpi_pinctrl_remove, +}; + +module_platform_driver(lpi_pinctrl_driver); + +MODULE_DESCRIPTION("QTI LPI GPIO pin control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/qcom/pinctrl-wcd.c b/drivers/pinctrl/qcom/pinctrl-wcd.c new file mode 100644 index 000000000000..2cc68a0c6743 --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-wcd.c @@ -0,0 +1,435 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../core.h" +#include "../pinctrl-utils.h" + +#define WCD_REG_DIR_CTL WCD934X_CHIP_TIER_CTRL_GPIO_CTL_OE +#define WCD_REG_VAL_CTL WCD934X_CHIP_TIER_CTRL_GPIO_CTL_DATA +#define WCD_GPIO_PULL_UP 1 +#define WCD_GPIO_PULL_DOWN 2 +#define WCD_GPIO_BIAS_DISABLE 3 +#define WCD_GPIO_STRING_LEN 20 + +/** + * struct wcd_gpio_pad - keep current GPIO settings + * @offset: offset of gpio. + * @is_valid: Set to false, when GPIO in high Z state. + * @value: value of a pin + * @output_enabled: Set to true if GPIO is output and false if it is input + * @pullup: Constant current which flow through GPIO output buffer. + * @strength: Drive strength of a pin + */ +struct wcd_gpio_pad { + u16 offset; + bool is_valid; + bool value; + bool output_enabled; + unsigned int pullup; + unsigned int strength; +}; + +struct wcd_gpio_priv { + struct device *dev; + struct regmap *map; + struct pinctrl_dev *ctrl; + struct gpio_chip chip; +}; + +static int wcd_gpio_read(struct wcd_gpio_priv *priv_data, + struct wcd_gpio_pad *pad, unsigned int addr) +{ + unsigned int val; + int ret; + + ret = regmap_read(priv_data->map, addr, &val); + if (ret < 0) + dev_err(priv_data->dev, "%s: read 0x%x failed\n", + __func__, addr); + else + ret = (val >> pad->offset); + + return ret; +} + +static int wcd_gpio_write(struct wcd_gpio_priv *priv_data, + struct wcd_gpio_pad *pad, unsigned int addr, + unsigned int val) +{ + int ret; + + ret = regmap_update_bits(priv_data->map, addr, (1 << pad->offset), + val << pad->offset); + if (ret < 0) + dev_err(priv_data->dev, "write 0x%x failed\n", addr); + + return ret; +} + +static int wcd_get_groups_count(struct pinctrl_dev *pctldev) +{ + return pctldev->desc->npins; +} + +static const char *wcd_get_group_name(struct pinctrl_dev *pctldev, + unsigned int pin) +{ + return pctldev->desc->pins[pin].name; +} + +static int wcd_get_group_pins(struct pinctrl_dev *pctldev, unsigned int pin, + const unsigned int **pins, unsigned int *num_pins) +{ + *pins = &pctldev->desc->pins[pin].number; + *num_pins = 1; + return 0; +} + +static const struct pinctrl_ops wcd_pinctrl_ops = { + .get_groups_count = wcd_get_groups_count, + .get_group_name = wcd_get_group_name, + .get_group_pins = wcd_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_group, + .dt_free_map = pinctrl_utils_free_map, +}; + +static int wcd_config_get(struct pinctrl_dev *pctldev, + unsigned int pin, unsigned long *config) +{ + unsigned int param = pinconf_to_config_param(*config); + struct wcd_gpio_pad *pad; + unsigned int arg; + + pad = pctldev->desc->pins[pin].drv_data; + + switch (param) { + case PIN_CONFIG_BIAS_PULL_DOWN: + arg = pad->pullup == WCD_GPIO_PULL_DOWN; + break; + case PIN_CONFIG_BIAS_DISABLE: + arg = pad->pullup = WCD_GPIO_BIAS_DISABLE; + break; + case PIN_CONFIG_BIAS_PULL_UP: + arg = pad->pullup == WCD_GPIO_PULL_UP; + break; + case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + arg = !pad->is_valid; + break; + case PIN_CONFIG_INPUT_ENABLE: + arg = pad->output_enabled; + break; + case PIN_CONFIG_OUTPUT: + arg = pad->value; + break; + default: + return -EINVAL; + } + + *config = pinconf_to_config_packed(param, arg); + return 0; +} + +static int wcd_config_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int nconfs) +{ + struct wcd_gpio_priv *priv_data = pinctrl_dev_get_drvdata(pctldev); + struct wcd_gpio_pad *pad; + unsigned int param, arg; + int i, ret; + + pad = pctldev->desc->pins[pin].drv_data; + + for (i = 0; i < nconfs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + dev_dbg(priv_data->dev, "%s: param: %d arg: %d", + __func__, param, arg); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + pad->pullup = WCD_GPIO_BIAS_DISABLE; + break; + case PIN_CONFIG_BIAS_PULL_UP: + pad->pullup = WCD_GPIO_PULL_UP; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + pad->pullup = WCD_GPIO_PULL_DOWN; + break; + case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + pad->is_valid = false; + break; + case PIN_CONFIG_INPUT_ENABLE: + pad->output_enabled = false; + break; + case PIN_CONFIG_OUTPUT: + pad->output_enabled = true; + pad->value = arg; + break; + case PIN_CONFIG_DRIVE_STRENGTH: + pad->strength = arg; + break; + default: + ret = -EINVAL; + goto done; + } + } + + if (pad->output_enabled) { + ret = wcd_gpio_write(priv_data, pad, WCD_REG_DIR_CTL, + pad->output_enabled); + if (ret < 0) + goto done; + ret = wcd_gpio_write(priv_data, pad, WCD_REG_VAL_CTL, + pad->value); + } else + ret = wcd_gpio_write(priv_data, pad, WCD_REG_DIR_CTL, + pad->output_enabled); +done: + return ret; +} + +static const struct pinconf_ops wcd_pinconf_ops = { + .is_generic = true, + .pin_config_group_get = wcd_config_get, + .pin_config_group_set = wcd_config_set, +}; + +static int wcd_gpio_direction_input(struct gpio_chip *chip, unsigned int pin) +{ + struct wcd_gpio_priv *priv_data = gpiochip_get_data(chip); + unsigned long config; + + config = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1); + + return wcd_config_set(priv_data->ctrl, pin, &config, 1); +} + +static int wcd_gpio_direction_output(struct gpio_chip *chip, + unsigned int pin, int val) +{ + struct wcd_gpio_priv *priv_data = gpiochip_get_data(chip); + unsigned long config; + + config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, val); + + return wcd_config_set(priv_data->ctrl, pin, &config, 1); +} + +static int wcd_gpio_get(struct gpio_chip *chip, unsigned int pin) +{ + struct wcd_gpio_priv *priv_data = gpiochip_get_data(chip); + struct wcd_gpio_pad *pad; + int value; + + pad = priv_data->ctrl->desc->pins[pin].drv_data; + + if (!pad->is_valid) + return -EINVAL; + + value = wcd_gpio_read(priv_data, pad, WCD_REG_VAL_CTL); + return value; +} + +static void wcd_gpio_set(struct gpio_chip *chip, unsigned int pin, int value) +{ + struct wcd_gpio_priv *priv_data = gpiochip_get_data(chip); + unsigned long config; + + config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, value); + + wcd_config_set(priv_data->ctrl, pin, &config, 1); +} + +static const struct gpio_chip wcd_gpio_chip = { + .direction_input = wcd_gpio_direction_input, + .direction_output = wcd_gpio_direction_output, + .get = wcd_gpio_get, + .set = wcd_gpio_set, +}; + +static int wcd_pinctrl_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct pinctrl_pin_desc *pindesc; + struct pinctrl_desc *pctrldesc; + struct wcd_gpio_pad *pad, *pads; + struct wcd_gpio_priv *priv_data; + int ret, i, j; + u32 npins; + char **name; + + ret = of_property_read_u32(dev->of_node, "qcom,num-gpios", &npins); + if (ret) { + dev_err(dev, "%s: Looking up %s property in node %s failed\n", + __func__, "qcom,num-gpios", dev->of_node->full_name); + ret = -EINVAL; + goto err_priv_alloc; + } + if (!npins) { + dev_err(dev, "%s: no.of pins are 0\n", __func__); + ret = -EINVAL; + goto err_priv_alloc; + } + + priv_data = devm_kzalloc(dev, sizeof(*priv_data), GFP_KERNEL); + if (!priv_data) { + ret = -ENOMEM; + goto err_priv_alloc; + } + + priv_data->dev = dev; + priv_data->map = dev_get_regmap(dev->parent, NULL); + if (!priv_data->map) { + dev_err(dev, "%s: failed to get regmap\n", __func__); + ret = -EINVAL; + goto err_regmap; + } + + pindesc = devm_kcalloc(dev, npins, sizeof(*pindesc), GFP_KERNEL); + if (!pindesc) { + ret = -ENOMEM; + goto err_pinsec_alloc; + } + + pads = devm_kcalloc(dev, npins, sizeof(*pads), GFP_KERNEL); + if (!pads) { + ret = -ENOMEM; + goto err_pads_alloc; + } + + pctrldesc = devm_kzalloc(dev, sizeof(*pctrldesc), GFP_KERNEL); + if (!pctrldesc) { + ret = -ENOMEM; + goto err_pinctrl_alloc; + } + + pctrldesc->pctlops = &wcd_pinctrl_ops; + pctrldesc->confops = &wcd_pinconf_ops; + pctrldesc->owner = THIS_MODULE; + pctrldesc->name = dev_name(dev); + pctrldesc->pins = pindesc; + pctrldesc->npins = npins; + + name = devm_kcalloc(dev, npins, sizeof(char *), GFP_KERNEL); + if (!name) { + ret = -ENOMEM; + goto err_name_alloc; + } + for (i = 0; i < npins; i++, pindesc++) { + name[i] = devm_kzalloc(dev, sizeof(char) * WCD_GPIO_STRING_LEN, + GFP_KERNEL); + if (!name[i]) { + ret = -ENOMEM; + goto err_pin; + } + pad = &pads[i]; + pindesc->drv_data = pad; + pindesc->number = i; + snprintf(name[i], (WCD_GPIO_STRING_LEN - 1), "gpio%d", (i+1)); + pindesc->name = name[i]; + pad->offset = i; + pad->is_valid = true; + } + + priv_data->chip = wcd_gpio_chip; + priv_data->chip.parent = dev; + priv_data->chip.base = -1; + priv_data->chip.ngpio = npins; + priv_data->chip.label = dev_name(dev); + priv_data->chip.of_gpio_n_cells = 2; + priv_data->chip.can_sleep = false; + + priv_data->ctrl = devm_pinctrl_register(dev, pctrldesc, priv_data); + if (IS_ERR(priv_data->ctrl)) { + dev_err(dev, "%s: failed to register to pinctrl\n", __func__); + ret = PTR_ERR(priv_data->ctrl); + goto err_pin; + } + + ret = gpiochip_add_data(&priv_data->chip, priv_data); + if (ret) { + dev_err(dev, "%s: can't add gpio chip\n", __func__); + goto err_pin; + } + + ret = gpiochip_add_pin_range(&priv_data->chip, dev_name(dev), 0, 0, + npins); + if (ret) { + dev_err(dev, "%s: failed to add pin range\n", __func__); + goto err_range; + } + platform_set_drvdata(pdev, priv_data); + + return 0; + +err_range: + gpiochip_remove(&priv_data->chip); +err_pin: + for (j = 0; j < i; j++) + devm_kfree(dev, name[j]); + devm_kfree(dev, name); +err_name_alloc: + devm_kfree(dev, pctrldesc); +err_pinctrl_alloc: + devm_kfree(dev, pads); +err_pads_alloc: + devm_kfree(dev, pindesc); +err_pinsec_alloc: +err_regmap: + devm_kfree(dev, priv_data); +err_priv_alloc: + return ret; +} + +static int wcd_pinctrl_remove(struct platform_device *pdev) +{ + struct wcd_gpio_priv *priv_data = platform_get_drvdata(pdev); + + gpiochip_remove(&priv_data->chip); + + return 0; +} + +static const struct of_device_id wcd_pinctrl_of_match[] = { + { .compatible = "qcom,wcd-pinctrl" }, + { }, +}; + +MODULE_DEVICE_TABLE(of, wcd_pinctrl_of_match); + +static struct platform_driver wcd_pinctrl_driver = { + .driver = { + .name = "qcom-wcd-pinctrl", + .of_match_table = wcd_pinctrl_of_match, + }, + .probe = wcd_pinctrl_probe, + .remove = wcd_pinctrl_remove, +}; + +module_platform_driver(wcd_pinctrl_driver); + +MODULE_DESCRIPTION("Qualcomm Technologies, Inc WCD GPIO pin control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile new file mode 100644 index 000000000000..ae8ffae4cbc3 --- /dev/null +++ b/drivers/soc/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the Linux Kernel SOC specific device drivers. +# + +obj-y += qcom/ diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile new file mode 100644 index 000000000000..33e8a12f7890 --- /dev/null +++ b/drivers/soc/qcom/Makefile @@ -0,0 +1 @@ +obj-y += qdsp6v2/ diff --git a/drivers/soc/qcom/qdsp6v2/Makefile b/drivers/soc/qcom/qdsp6v2/Makefile new file mode 100644 index 000000000000..9fdd63a45857 --- /dev/null +++ b/drivers/soc/qcom/qdsp6v2/Makefile @@ -0,0 +1,8 @@ +obj-$(CONFIG_MSM_QDSP6_APRV2_GLINK) += apr.o apr_v2.o apr_tal_glink.o +obj-$(CONFIG_MSM_QDSP6_APRV3_GLINK) += apr.o apr_v3.o apr_tal_glink.o +obj-$(CONFIG_SND_SOC_MSM_QDSP6V2_INTF) += msm_audio_ion.o +obj-$(CONFIG_MSM_ADSP_LOADER) += adsp-loader.o +obj-$(CONFIG_MSM_QDSP6_SSR) += audio_ssr.o +obj-$(CONFIG_MSM_QDSP6_PDR) += audio_pdr.o +obj-$(CONFIG_MSM_QDSP6_NOTIFIER) += audio_notifier.o +obj-$(CONFIG_MSM_CDSP_LOADER) += cdsp-loader.o diff --git a/drivers/soc/qcom/qdsp6v2/adsp-loader.c b/drivers/soc/qcom/qdsp6v2/adsp-loader.c new file mode 100644 index 000000000000..d90267e01505 --- /dev/null +++ b/drivers/soc/qcom/qdsp6v2/adsp-loader.c @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2012-2014, 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define Q6_PIL_GET_DELAY_MS 100 +#define BOOT_CMD 1 +#define IMAGE_UNLOAD_CMD 0 + +static ssize_t adsp_boot_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count); + +struct adsp_loader_private { + void *pil_h; + struct kobject *boot_adsp_obj; + struct attribute_group *attr_group; +}; + +static struct kobj_attribute adsp_boot_attribute = + __ATTR(boot, 0220, NULL, adsp_boot_store); + +static struct attribute *attrs[] = { + &adsp_boot_attribute.attr, + NULL, +}; + +static struct work_struct adsp_ldr_work; +static struct platform_device *adsp_private; +static void adsp_loader_unload(struct platform_device *pdev); + +static void adsp_load_fw(struct work_struct *adsp_ldr_work) +{ + struct platform_device *pdev = adsp_private; + struct adsp_loader_private *priv = NULL; + + const char *adsp_dt = "qcom,adsp-state"; + int rc = 0; + u32 adsp_state; + const char *img_name; + + if (!pdev) { + dev_err(&pdev->dev, "%s: Platform device null\n", __func__); + goto fail; + } + + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, + "%s: Device tree information missing\n", __func__); + goto fail; + } + + rc = of_property_read_u32(pdev->dev.of_node, adsp_dt, &adsp_state); + if (rc) { + dev_err(&pdev->dev, + "%s: ADSP state = %x\n", __func__, adsp_state); + goto fail; + } + + rc = of_property_read_string(pdev->dev.of_node, + "qcom,proc-img-to-load", + &img_name); + + if (rc) { + dev_dbg(&pdev->dev, + "%s: loading default image ADSP\n", __func__); + goto load_adsp; + } + if (!strcmp(img_name, "modem")) { + /* adsp_state always returns "0". So load modem image based on + * apr_modem_state to prevent loading of image twice + */ + adsp_state = apr_get_modem_state(); + if (adsp_state == APR_SUBSYS_DOWN) { + priv = platform_get_drvdata(pdev); + if (!priv) { + dev_err(&pdev->dev, + " %s: Private data get failed\n", __func__); + goto fail; + } + + priv->pil_h = subsystem_get("modem"); + if (IS_ERR(priv->pil_h)) { + dev_err(&pdev->dev, "%s: pil get failed,\n", + __func__); + goto fail; + } + + /* Set the state of the ADSP in APR driver */ + apr_set_modem_state(APR_SUBSYS_LOADED); + } else if (adsp_state == APR_SUBSYS_LOADED) { + dev_dbg(&pdev->dev, + "%s: MDSP state = %x\n", __func__, adsp_state); + } + + dev_dbg(&pdev->dev, "%s: Q6/MDSP image is loaded\n", __func__); + return; + } +load_adsp: + { + adsp_state = apr_get_q6_state(); + if (adsp_state == APR_SUBSYS_DOWN) { + priv = platform_get_drvdata(pdev); + if (!priv) { + dev_err(&pdev->dev, + " %s: Private data get failed\n", __func__); + goto fail; + } + + priv->pil_h = subsystem_get("adsp"); + if (IS_ERR(priv->pil_h)) { + dev_err(&pdev->dev, "%s: pil get failed,\n", + __func__); + goto fail; + } + + /* Set the state of the ADSP in APR driver */ + apr_set_q6_state(APR_SUBSYS_LOADED); + } else if (adsp_state == APR_SUBSYS_LOADED) { + dev_dbg(&pdev->dev, + "%s: ADSP state = %x\n", __func__, adsp_state); + } + + dev_dbg(&pdev->dev, "%s: Q6/ADSP image is loaded\n", __func__); + return; + } +fail: + dev_err(&pdev->dev, "%s: Q6 image loading failed\n", __func__); +} + +static void adsp_loader_do(struct platform_device *pdev) +{ + schedule_work(&adsp_ldr_work); +} + +static ssize_t adsp_boot_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + int boot = 0; + + if (sscanf(buf, "%du", &boot) != 1) { + pr_err("%s: failed to read boot info from string\n", __func__); + return -EINVAL; + } + + if (boot == BOOT_CMD) { + pr_debug("%s: going to call adsp_loader_do\n", __func__); + adsp_loader_do(adsp_private); + } else if (boot == IMAGE_UNLOAD_CMD) { + pr_debug("%s: going to call adsp_unloader\n", __func__); + adsp_loader_unload(adsp_private); + } + return count; +} + +static void adsp_loader_unload(struct platform_device *pdev) +{ + struct adsp_loader_private *priv = NULL; + + priv = platform_get_drvdata(pdev); + + if (!priv) + return; + + if (priv->pil_h) { + dev_dbg(&pdev->dev, "%s: calling subsystem put\n", __func__); + subsystem_put(priv->pil_h); + priv->pil_h = NULL; + } +} + +static int adsp_loader_init_sysfs(struct platform_device *pdev) +{ + int ret = -EINVAL; + struct adsp_loader_private *priv = NULL; + + adsp_private = NULL; + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) { + ret = -ENOMEM; + return ret; + } + + platform_set_drvdata(pdev, priv); + + priv->pil_h = NULL; + priv->boot_adsp_obj = NULL; + priv->attr_group = devm_kzalloc(&pdev->dev, + sizeof(*(priv->attr_group)), + GFP_KERNEL); + if (!priv->attr_group) { + ret = -ENOMEM; + goto error_return; + } + + priv->attr_group->attrs = attrs; + + priv->boot_adsp_obj = kobject_create_and_add("boot_adsp", kernel_kobj); + if (!priv->boot_adsp_obj) { + dev_err(&pdev->dev, "%s: sysfs create and add failed\n", + __func__); + ret = -ENOMEM; + goto error_return; + } + + ret = sysfs_create_group(priv->boot_adsp_obj, priv->attr_group); + if (ret) { + dev_err(&pdev->dev, "%s: sysfs create group failed %d\n", + __func__, ret); + goto error_return; + } + + adsp_private = pdev; + + return 0; + +error_return: + + if (priv->boot_adsp_obj) { + kobject_del(priv->boot_adsp_obj); + priv->boot_adsp_obj = NULL; + } + + return ret; +} + +static int adsp_loader_remove(struct platform_device *pdev) +{ + struct adsp_loader_private *priv = NULL; + + priv = platform_get_drvdata(pdev); + + if (!priv) + return 0; + + if (priv->pil_h) { + subsystem_put(priv->pil_h); + priv->pil_h = NULL; + } + + if (priv->boot_adsp_obj) { + sysfs_remove_group(priv->boot_adsp_obj, priv->attr_group); + kobject_del(priv->boot_adsp_obj); + priv->boot_adsp_obj = NULL; + } + + return 0; +} + +static int adsp_loader_probe(struct platform_device *pdev) +{ + int ret = adsp_loader_init_sysfs(pdev); + + if (ret != 0) { + dev_err(&pdev->dev, "%s: Error in initing sysfs\n", __func__); + return ret; + } + + INIT_WORK(&adsp_ldr_work, adsp_load_fw); + + return 0; +} + +static const struct of_device_id adsp_loader_dt_match[] = { + { .compatible = "qcom,adsp-loader" }, + { } +}; +MODULE_DEVICE_TABLE(of, adsp_loader_dt_match); + +static struct platform_driver adsp_loader_driver = { + .driver = { + .name = "adsp-loader", + .owner = THIS_MODULE, + .of_match_table = adsp_loader_dt_match, + }, + .probe = adsp_loader_probe, + .remove = adsp_loader_remove, +}; + +static int __init adsp_loader_init(void) +{ + return platform_driver_register(&adsp_loader_driver); +} +module_init(adsp_loader_init); + +static void __exit adsp_loader_exit(void) +{ + platform_driver_unregister(&adsp_loader_driver); +} +module_exit(adsp_loader_exit); + +MODULE_DESCRIPTION("ADSP Loader module"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/soc/qcom/qdsp6v2/apr.c b/drivers/soc/qcom/qdsp6v2/apr.c new file mode 100644 index 000000000000..e45f61eee58c --- /dev/null +++ b/drivers/soc/qcom/qdsp6v2/apr.c @@ -0,0 +1,976 @@ +/* Copyright (c) 2010-2014, 2016-2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define APR_PKT_IPC_LOG_PAGE_CNT 2 + +static struct apr_q6 q6; +static struct apr_client client[APR_DEST_MAX][APR_CLIENT_MAX]; +static void *apr_pkt_ctx; +static wait_queue_head_t dsp_wait; +static wait_queue_head_t modem_wait; +static bool is_modem_up; +static bool is_initial_boot; +/* Subsystem restart: QDSP6 data, functions */ +static struct workqueue_struct *apr_reset_workqueue; +static void apr_reset_deregister(struct work_struct *work); +static void dispatch_event(unsigned long code, uint16_t proc); +struct apr_reset_work { + void *handle; + struct work_struct work; +}; + +static bool apr_cf_debug; + +#ifdef CONFIG_DEBUG_FS +static struct dentry *debugfs_apr_debug; +static ssize_t apr_debug_write(struct file *filp, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + char cmd; + + if (copy_from_user(&cmd, ubuf, 1)) + return -EFAULT; + + apr_cf_debug = (cmd == '1') ? true : false; + + return cnt; +} + +static const struct file_operations apr_debug_ops = { + .write = apr_debug_write, +}; +#endif + +#define APR_PKT_INFO(x...) \ +do { \ + if (apr_pkt_ctx) \ + ipc_log_string(apr_pkt_ctx, ": "x); \ +} while (0) + + +struct apr_svc_table { + char name[64]; + int idx; + int id; + int client_id; +}; + +static const struct apr_svc_table svc_tbl_qdsp6[] = { + { + .name = "AFE", + .idx = 0, + .id = APR_SVC_AFE, + .client_id = APR_CLIENT_AUDIO, + }, + { + .name = "ASM", + .idx = 1, + .id = APR_SVC_ASM, + .client_id = APR_CLIENT_AUDIO, + }, + { + .name = "ADM", + .idx = 2, + .id = APR_SVC_ADM, + .client_id = APR_CLIENT_AUDIO, + }, + { + .name = "CORE", + .idx = 3, + .id = APR_SVC_ADSP_CORE, + .client_id = APR_CLIENT_AUDIO, + }, + { + .name = "TEST", + .idx = 4, + .id = APR_SVC_TEST_CLIENT, + .client_id = APR_CLIENT_AUDIO, + }, + { + .name = "MVM", + .idx = 5, + .id = APR_SVC_ADSP_MVM, + .client_id = APR_CLIENT_AUDIO, + }, + { + .name = "CVS", + .idx = 6, + .id = APR_SVC_ADSP_CVS, + .client_id = APR_CLIENT_AUDIO, + }, + { + .name = "CVP", + .idx = 7, + .id = APR_SVC_ADSP_CVP, + .client_id = APR_CLIENT_AUDIO, + }, + { + .name = "USM", + .idx = 8, + .id = APR_SVC_USM, + .client_id = APR_CLIENT_AUDIO, + }, + { + .name = "VIDC", + .idx = 9, + .id = APR_SVC_VIDC, + }, + { + .name = "LSM", + .idx = 10, + .id = APR_SVC_LSM, + .client_id = APR_CLIENT_AUDIO, + }, +}; + +static struct apr_svc_table svc_tbl_voice[] = { + { + .name = "VSM", + .idx = 0, + .id = APR_SVC_VSM, + .client_id = APR_CLIENT_VOICE, + }, + { + .name = "VPM", + .idx = 1, + .id = APR_SVC_VPM, + .client_id = APR_CLIENT_VOICE, + }, + { + .name = "MVS", + .idx = 2, + .id = APR_SVC_MVS, + .client_id = APR_CLIENT_VOICE, + }, + { + .name = "MVM", + .idx = 3, + .id = APR_SVC_MVM, + .client_id = APR_CLIENT_VOICE, + }, + { + .name = "CVS", + .idx = 4, + .id = APR_SVC_CVS, + .client_id = APR_CLIENT_VOICE, + }, + { + .name = "CVP", + .idx = 5, + .id = APR_SVC_CVP, + .client_id = APR_CLIENT_VOICE, + }, + { + .name = "SRD", + .idx = 6, + .id = APR_SVC_SRD, + .client_id = APR_CLIENT_VOICE, + }, + { + .name = "TEST", + .idx = 7, + .id = APR_SVC_TEST_CLIENT, + .client_id = APR_CLIENT_VOICE, + }, +}; + +enum apr_subsys_state apr_get_modem_state(void) +{ + return atomic_read(&q6.modem_state); +} + +void apr_set_modem_state(enum apr_subsys_state state) +{ + atomic_set(&q6.modem_state, state); +} + +enum apr_subsys_state apr_cmpxchg_modem_state(enum apr_subsys_state prev, + enum apr_subsys_state new) +{ + return atomic_cmpxchg(&q6.modem_state, prev, new); +} + +static void apr_modem_down(unsigned long opcode) +{ + apr_set_modem_state(APR_SUBSYS_DOWN); + dispatch_event(opcode, APR_DEST_MODEM); +} + +static void apr_modem_up(void) +{ + if (apr_cmpxchg_modem_state(APR_SUBSYS_DOWN, APR_SUBSYS_UP) == + APR_SUBSYS_DOWN) + wake_up(&modem_wait); + is_modem_up = 1; +} + +enum apr_subsys_state apr_get_q6_state(void) +{ + return atomic_read(&q6.q6_state); +} +EXPORT_SYMBOL(apr_get_q6_state); + +int apr_set_q6_state(enum apr_subsys_state state) +{ + pr_debug("%s: setting adsp state %d\n", __func__, state); + if (state < APR_SUBSYS_DOWN || state > APR_SUBSYS_LOADED) + return -EINVAL; + atomic_set(&q6.q6_state, state); + return 0; +} +EXPORT_SYMBOL(apr_set_q6_state); + +enum apr_subsys_state apr_cmpxchg_q6_state(enum apr_subsys_state prev, + enum apr_subsys_state new) +{ + return atomic_cmpxchg(&q6.q6_state, prev, new); +} + +static void apr_adsp_down(unsigned long opcode) +{ + apr_set_q6_state(APR_SUBSYS_DOWN); + dispatch_event(opcode, APR_DEST_QDSP6); +} + +static void apr_adsp_up(void) +{ + if (apr_cmpxchg_q6_state(APR_SUBSYS_DOWN, APR_SUBSYS_LOADED) == + APR_SUBSYS_DOWN) + wake_up(&dsp_wait); +} + +int apr_wait_for_device_up(int dest_id) +{ + int rc = -1; + + if (dest_id == APR_DEST_MODEM) + rc = wait_event_interruptible_timeout(modem_wait, + (apr_get_modem_state() == APR_SUBSYS_UP), + (1 * HZ)); + else if (dest_id == APR_DEST_QDSP6) + rc = wait_event_interruptible_timeout(dsp_wait, + (apr_get_q6_state() == APR_SUBSYS_UP), + (1 * HZ)); + else + pr_err("%s: unknown dest_id %d\n", __func__, dest_id); + /* returns left time */ + return rc; +} + +int apr_load_adsp_image(void) +{ + int rc = 0; + + mutex_lock(&q6.lock); + if (apr_get_q6_state() == APR_SUBSYS_UP) { + q6.pil = subsystem_get("adsp"); + if (IS_ERR(q6.pil)) { + rc = PTR_ERR(q6.pil); + pr_err("APR: Unable to load q6 image, error:%d\n", rc); + } else { + apr_set_q6_state(APR_SUBSYS_LOADED); + pr_debug("APR: Image is loaded, stated\n"); + } + } else if (apr_get_q6_state() == APR_SUBSYS_LOADED) { + pr_debug("APR: q6 image already loaded\n"); + } else { + pr_debug("APR: cannot load state %d\n", apr_get_q6_state()); + } + mutex_unlock(&q6.lock); + return rc; +} + +struct apr_client *apr_get_client(int dest_id, int client_id) +{ + return &client[dest_id][client_id]; +} + +int apr_send_pkt(void *handle, uint32_t *buf) +{ + struct apr_svc *svc = handle; + struct apr_client *clnt; + struct apr_hdr *hdr; + uint16_t dest_id; + uint16_t client_id; + uint16_t w_len; + int rc; + unsigned long flags; + + if (!handle || !buf) { + pr_err("APR: Wrong parameters\n"); + return -EINVAL; + } + if (svc->need_reset) { + pr_err("apr: send_pkt service need reset\n"); + return -ENETRESET; + } + + if ((svc->dest_id == APR_DEST_QDSP6) && + (apr_get_q6_state() != APR_SUBSYS_LOADED)) { + pr_err("%s: Still dsp is not Up\n", __func__); + return -ENETRESET; + } else if ((svc->dest_id == APR_DEST_MODEM) && + (apr_get_modem_state() == APR_SUBSYS_DOWN)) { + pr_err("apr: Still Modem is not Up\n"); + return -ENETRESET; + } + + spin_lock_irqsave(&svc->w_lock, flags); + dest_id = svc->dest_id; + client_id = svc->client_id; + clnt = &client[dest_id][client_id]; + + if (!client[dest_id][client_id].handle) { + pr_err("APR: Still service is not yet opened\n"); + spin_unlock_irqrestore(&svc->w_lock, flags); + return -EINVAL; + } + hdr = (struct apr_hdr *)buf; + + hdr->src_domain = APR_DOMAIN_APPS; + hdr->src_svc = svc->id; + hdr->dest_domain = svc->dest_domain; + hdr->dest_svc = svc->id; + + if (unlikely(apr_cf_debug)) { + APR_PKT_INFO( + "Tx: src_addr[0x%X] dest_addr[0x%X] opcode[0x%X] token[0x%X]", + (hdr->src_domain << 8) | hdr->src_svc, + (hdr->dest_domain << 8) | hdr->dest_svc, hdr->opcode, + hdr->token); + } + + rc = apr_tal_write(clnt->handle, buf, + (struct apr_pkt_priv *)&svc->pkt_owner, + hdr->pkt_size); + if (rc >= 0) { + w_len = rc; + if (w_len != hdr->pkt_size) { + pr_err("%s: Unable to write whole APR pkt successfully: %d\n", + __func__, rc); + rc = -EINVAL; + } + } else { + pr_err("%s: Write APR pkt failed with error %d\n", + __func__, rc); + } + spin_unlock_irqrestore(&svc->w_lock, flags); + + return rc; +} + +int apr_pkt_config(void *handle, struct apr_pkt_cfg *cfg) +{ + struct apr_svc *svc = (struct apr_svc *)handle; + uint16_t dest_id; + uint16_t client_id; + struct apr_client *clnt; + + if (!handle) { + pr_err("%s: Invalid handle\n", __func__); + return -EINVAL; + } + + if (svc->need_reset) { + pr_err("%s: service need reset\n", __func__); + return -ENETRESET; + } + + svc->pkt_owner = cfg->pkt_owner; + dest_id = svc->dest_id; + client_id = svc->client_id; + clnt = &client[dest_id][client_id]; + + return apr_tal_rx_intents_config(clnt->handle, + cfg->intents.num_of_intents, cfg->intents.size); +} + +struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn, + uint32_t src_port, void *priv) +{ + struct apr_client *clnt; + int client_id = 0; + int svc_idx = 0; + int svc_id = 0; + int dest_id = 0; + int domain_id = 0; + int temp_port = 0; + struct apr_svc *svc = NULL; + int rc = 0; + bool can_open_channel = true; + + if (!dest || !svc_name || !svc_fn) + return NULL; + + if (!strcmp(dest, "ADSP")) + domain_id = APR_DOMAIN_ADSP; + else if (!strcmp(dest, "MODEM")) { + /* Don't request for SMD channels if destination is MODEM, + * as these channels are no longer used and these clients + * are to listen only for MODEM SSR events + */ + can_open_channel = false; + domain_id = APR_DOMAIN_MODEM; + } else { + pr_err("APR: wrong destination\n"); + goto done; + } + + dest_id = apr_get_dest_id(dest); + + if (dest_id == APR_DEST_QDSP6) { + if (apr_get_q6_state() != APR_SUBSYS_LOADED) { + pr_err("%s: adsp not up\n", __func__); + return NULL; + } + pr_debug("%s: adsp Up\n", __func__); + } else if (dest_id == APR_DEST_MODEM) { + if (apr_get_modem_state() == APR_SUBSYS_DOWN) { + if (is_modem_up) { + pr_err("%s: modem shutdown due to SSR, ret", + __func__); + return NULL; + } + pr_debug("%s: Wait for modem to bootup\n", __func__); + rc = apr_wait_for_device_up(APR_DEST_MODEM); + if (rc == 0) { + pr_err("%s: Modem is not Up\n", __func__); + return NULL; + } + } + pr_debug("%s: modem Up\n", __func__); + } + + if (apr_get_svc(svc_name, domain_id, &client_id, &svc_idx, &svc_id)) { + pr_err("%s: apr_get_svc failed\n", __func__); + goto done; + } + + clnt = &client[dest_id][client_id]; + mutex_lock(&clnt->m_lock); + if (!clnt->handle && can_open_channel) { + clnt->handle = apr_tal_open(client_id, dest_id, + APR_DL_SMD, apr_cb_func, NULL); + if (!clnt->handle) { + svc = NULL; + pr_err("APR: Unable to open handle\n"); + mutex_unlock(&clnt->m_lock); + goto done; + } + } + mutex_unlock(&clnt->m_lock); + svc = &clnt->svc[svc_idx]; + mutex_lock(&svc->m_lock); + clnt->id = client_id; + if (svc->need_reset) { + mutex_unlock(&svc->m_lock); + pr_err("APR: Service needs reset\n"); + goto done; + } + svc->id = svc_id; + svc->dest_id = dest_id; + svc->client_id = client_id; + svc->dest_domain = domain_id; + svc->pkt_owner = APR_PKT_OWNER_DRIVER; + + if (src_port != 0xFFFFFFFF) { + temp_port = ((src_port >> 8) * 8) + (src_port & 0xFF); + pr_debug("port = %d t_port = %d\n", src_port, temp_port); + if (temp_port >= APR_MAX_PORTS || temp_port < 0) { + pr_err("APR: temp_port out of bounds\n"); + mutex_unlock(&svc->m_lock); + return NULL; + } + if (!svc->svc_cnt) + clnt->svc_cnt++; + svc->port_cnt++; + svc->port_fn[temp_port] = svc_fn; + svc->port_priv[temp_port] = priv; + svc->svc_cnt++; + } else { + if (!svc->fn) { + if (!svc->svc_cnt) + clnt->svc_cnt++; + svc->fn = svc_fn; + svc->priv = priv; + svc->svc_cnt++; + } + } + + mutex_unlock(&svc->m_lock); +done: + return svc; +} + + +void apr_cb_func(void *buf, int len, void *priv) +{ + struct apr_client_data data; + struct apr_client *apr_client; + struct apr_svc *c_svc; + struct apr_hdr *hdr; + uint16_t hdr_size; + uint16_t msg_type; + uint16_t ver; + uint16_t src; + uint16_t svc; + uint16_t clnt; + int i; + int temp_port = 0; + uint32_t *ptr; + + pr_debug("APR2: len = %d\n", len); + ptr = buf; + pr_debug("\n*****************\n"); + for (i = 0; i < len/4; i++) + pr_debug("%x ", ptr[i]); + pr_debug("\n"); + pr_debug("\n*****************\n"); + + if (!buf || len <= APR_HDR_SIZE) { + pr_err("APR: Improper apr pkt received:%pK %d\n", buf, len); + return; + } + hdr = buf; + + ver = hdr->hdr_field; + ver = (ver & 0x000F); + if (ver > APR_PKT_VER + 1) { + pr_err("APR: Wrong version: %d\n", ver); + return; + } + + hdr_size = hdr->hdr_field; + hdr_size = ((hdr_size & 0x00F0) >> 0x4) * 4; + if (hdr_size < APR_HDR_SIZE) { + pr_err("APR: Wrong hdr size:%d\n", hdr_size); + return; + } + + if (hdr->pkt_size < APR_HDR_SIZE) { + pr_err("APR: Wrong paket size\n"); + return; + } + msg_type = hdr->hdr_field; + msg_type = (msg_type >> 0x08) & 0x0003; + if (msg_type >= APR_MSG_TYPE_MAX && msg_type != APR_BASIC_RSP_RESULT) { + pr_err("APR: Wrong message type: %d\n", msg_type); + return; + } + + if (hdr->src_domain >= APR_DOMAIN_MAX || + hdr->dest_domain >= APR_DOMAIN_MAX || + hdr->src_svc >= APR_SVC_MAX || + hdr->dest_svc >= APR_SVC_MAX) { + pr_err("APR: Wrong APR header\n"); + return; + } + + svc = hdr->dest_svc; + if (hdr->src_domain == APR_DOMAIN_MODEM) { + if (svc == APR_SVC_MVS || svc == APR_SVC_MVM || + svc == APR_SVC_CVS || svc == APR_SVC_CVP || + svc == APR_SVC_TEST_CLIENT) + clnt = APR_CLIENT_VOICE; + else { + pr_err("APR: Wrong svc :%d\n", svc); + return; + } + } else if (hdr->src_domain == APR_DOMAIN_ADSP) { + if (svc == APR_SVC_AFE || svc == APR_SVC_ASM || + svc == APR_SVC_VSM || svc == APR_SVC_VPM || + svc == APR_SVC_ADM || svc == APR_SVC_ADSP_CORE || + svc == APR_SVC_USM || + svc == APR_SVC_TEST_CLIENT || svc == APR_SVC_ADSP_MVM || + svc == APR_SVC_ADSP_CVS || svc == APR_SVC_ADSP_CVP || + svc == APR_SVC_LSM) + clnt = APR_CLIENT_AUDIO; + else if (svc == APR_SVC_VIDC) + clnt = APR_CLIENT_AUDIO; + else { + pr_err("APR: Wrong svc :%d\n", svc); + return; + } + } else { + pr_err("APR: Pkt from wrong source: %d\n", hdr->src_domain); + return; + } + + src = apr_get_data_src(hdr); + if (src == APR_DEST_MAX) + return; + + pr_debug("src =%d clnt = %d\n", src, clnt); + apr_client = &client[src][clnt]; + for (i = 0; i < APR_SVC_MAX; i++) + if (apr_client->svc[i].id == svc) { + pr_debug("%d\n", apr_client->svc[i].id); + c_svc = &apr_client->svc[i]; + break; + } + + if (i == APR_SVC_MAX) { + pr_err("APR: service is not registered\n"); + return; + } + pr_debug("svc_idx = %d\n", i); + pr_debug("%x %x %x %pK %pK\n", c_svc->id, c_svc->dest_id, + c_svc->client_id, c_svc->fn, c_svc->priv); + data.payload_size = hdr->pkt_size - hdr_size; + data.opcode = hdr->opcode; + data.src = src; + data.src_port = hdr->src_port; + data.dest_port = hdr->dest_port; + data.token = hdr->token; + data.msg_type = msg_type; + data.payload = NULL; + if (data.payload_size > 0) + data.payload = (char *)hdr + hdr_size; + + if (unlikely(apr_cf_debug)) { + if (hdr->opcode == APR_BASIC_RSP_RESULT && data.payload) { + uint32_t *ptr = data.payload; + + APR_PKT_INFO( + "Rx: src_addr[0x%X] dest_addr[0x%X] opcode[0x%X] token[0x%X] rc[0x%X]", + (hdr->src_domain << 8) | hdr->src_svc, + (hdr->dest_domain << 8) | hdr->dest_svc, + hdr->opcode, hdr->token, ptr[1]); + } else { + APR_PKT_INFO( + "Rx: src_addr[0x%X] dest_addr[0x%X] opcode[0x%X] token[0x%X]", + (hdr->src_domain << 8) | hdr->src_svc, + (hdr->dest_domain << 8) | hdr->dest_svc, hdr->opcode, + hdr->token); + } + } + + temp_port = ((data.dest_port >> 8) * 8) + (data.dest_port & 0xFF); + pr_debug("port = %d t_port = %d\n", data.src_port, temp_port); + if (c_svc->port_cnt && c_svc->port_fn[temp_port]) + c_svc->port_fn[temp_port](&data, c_svc->port_priv[temp_port]); + else if (c_svc->fn) + c_svc->fn(&data, c_svc->priv); + else + pr_err("APR: Rxed a packet for NULL callback\n"); +} + +int apr_get_svc(const char *svc_name, int domain_id, int *client_id, + int *svc_idx, int *svc_id) +{ + int i; + int size; + struct apr_svc_table *tbl; + int ret = 0; + + if (domain_id == APR_DOMAIN_ADSP) { + tbl = (struct apr_svc_table *)&svc_tbl_qdsp6; + size = ARRAY_SIZE(svc_tbl_qdsp6); + } else { + tbl = (struct apr_svc_table *)&svc_tbl_voice; + size = ARRAY_SIZE(svc_tbl_voice); + } + + for (i = 0; i < size; i++) { + if (!strcmp(svc_name, tbl[i].name)) { + *client_id = tbl[i].client_id; + *svc_idx = tbl[i].idx; + *svc_id = tbl[i].id; + break; + } + } + + pr_debug("%s: svc_name = %s c_id = %d domain_id = %d\n", + __func__, svc_name, *client_id, domain_id); + if (i == size) { + pr_err("%s: APR: Wrong svc name %s\n", __func__, svc_name); + ret = -EINVAL; + } + + return ret; +} + +static void apr_reset_deregister(struct work_struct *work) +{ + struct apr_svc *handle = NULL; + struct apr_reset_work *apr_reset = + container_of(work, struct apr_reset_work, work); + + handle = apr_reset->handle; + pr_debug("%s:handle[%pK]\n", __func__, handle); + apr_deregister(handle); + kfree(apr_reset); +} + +int apr_deregister(void *handle) +{ + struct apr_svc *svc = handle; + struct apr_client *clnt; + uint16_t dest_id; + uint16_t client_id; + + if (!handle) + return -EINVAL; + + mutex_lock(&svc->m_lock); + if (!svc->svc_cnt) { + pr_err("%s: svc already deregistered. svc = %pK\n", + __func__, svc); + mutex_unlock(&svc->m_lock); + return -EINVAL; + } + + dest_id = svc->dest_id; + client_id = svc->client_id; + clnt = &client[dest_id][client_id]; + + if (svc->svc_cnt > 0) { + if (svc->port_cnt) + svc->port_cnt--; + svc->svc_cnt--; + if (!svc->svc_cnt) { + client[dest_id][client_id].svc_cnt--; + pr_debug("%s: service is reset %pK\n", __func__, svc); + } + } + + if (!svc->svc_cnt) { + svc->priv = NULL; + svc->id = 0; + svc->fn = NULL; + svc->dest_id = 0; + svc->client_id = 0; + svc->need_reset = 0x0; + } + if (client[dest_id][client_id].handle && + !client[dest_id][client_id].svc_cnt) { + apr_tal_close(client[dest_id][client_id].handle); + client[dest_id][client_id].handle = NULL; + } + mutex_unlock(&svc->m_lock); + + return 0; +} + +void apr_reset(void *handle) +{ + struct apr_reset_work *apr_reset_worker = NULL; + + if (!handle) + return; + pr_debug("%s: handle[%pK]\n", __func__, handle); + + if (apr_reset_workqueue == NULL) { + pr_err("%s: apr_reset_workqueue is NULL\n", __func__); + return; + } + + apr_reset_worker = kzalloc(sizeof(struct apr_reset_work), + GFP_ATOMIC); + + if (apr_reset_worker == NULL) { + pr_err("%s: mem failure\n", __func__); + return; + } + + apr_reset_worker->handle = handle; + INIT_WORK(&apr_reset_worker->work, apr_reset_deregister); + queue_work(apr_reset_workqueue, &apr_reset_worker->work); +} + +/* Dispatch the Reset events to Modem and audio clients */ +static void dispatch_event(unsigned long code, uint16_t proc) +{ + struct apr_client *apr_client; + struct apr_client_data data; + struct apr_svc *svc; + uint16_t clnt; + int i, j; + + data.opcode = RESET_EVENTS; + data.reset_event = code; + + /* Service domain can be different from the processor */ + data.reset_proc = apr_get_reset_domain(proc); + + clnt = APR_CLIENT_AUDIO; + apr_client = &client[proc][clnt]; + for (i = 0; i < APR_SVC_MAX; i++) { + mutex_lock(&apr_client->svc[i].m_lock); + if (apr_client->svc[i].fn) { + apr_client->svc[i].need_reset = 0x1; + apr_client->svc[i].fn(&data, apr_client->svc[i].priv); + } + if (apr_client->svc[i].port_cnt) { + svc = &(apr_client->svc[i]); + svc->need_reset = 0x1; + for (j = 0; j < APR_MAX_PORTS; j++) + if (svc->port_fn[j]) + svc->port_fn[j](&data, + svc->port_priv[j]); + } + mutex_unlock(&apr_client->svc[i].m_lock); + } + + clnt = APR_CLIENT_VOICE; + apr_client = &client[proc][clnt]; + for (i = 0; i < APR_SVC_MAX; i++) { + mutex_lock(&apr_client->svc[i].m_lock); + if (apr_client->svc[i].fn) { + apr_client->svc[i].need_reset = 0x1; + apr_client->svc[i].fn(&data, apr_client->svc[i].priv); + } + if (apr_client->svc[i].port_cnt) { + svc = &(apr_client->svc[i]); + svc->need_reset = 0x1; + for (j = 0; j < APR_MAX_PORTS; j++) + if (svc->port_fn[j]) + svc->port_fn[j](&data, + svc->port_priv[j]); + } + mutex_unlock(&apr_client->svc[i].m_lock); + } +} + +static int apr_notifier_service_cb(struct notifier_block *this, + unsigned long opcode, void *data) +{ + struct audio_notifier_cb_data *cb_data = data; + + if (cb_data == NULL) { + pr_err("%s: Callback data is NULL!\n", __func__); + goto done; + } + + pr_debug("%s: Service opcode 0x%lx, domain %d\n", + __func__, opcode, cb_data->domain); + + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + /* + * Use flag to ignore down notifications during + * initial boot. There is no benefit from error + * recovery notifications during initial boot + * up since everything is expected to be down. + */ + if (is_initial_boot) { + is_initial_boot = false; + break; + } + if (cb_data->domain == AUDIO_NOTIFIER_MODEM_DOMAIN) + apr_modem_down(opcode); + else + apr_adsp_down(opcode); + break; + case AUDIO_NOTIFIER_SERVICE_UP: + is_initial_boot = false; + if (cb_data->domain == AUDIO_NOTIFIER_MODEM_DOMAIN) + apr_modem_up(); + else + apr_adsp_up(); + break; + default: + break; + } +done: + return NOTIFY_OK; +} + +static struct notifier_block adsp_service_nb = { + .notifier_call = apr_notifier_service_cb, + .priority = 0, +}; + +static struct notifier_block modem_service_nb = { + .notifier_call = apr_notifier_service_cb, + .priority = 0, +}; + +static int __init apr_init(void) +{ + int i, j, k; + + for (i = 0; i < APR_DEST_MAX; i++) + for (j = 0; j < APR_CLIENT_MAX; j++) { + mutex_init(&client[i][j].m_lock); + for (k = 0; k < APR_SVC_MAX; k++) { + mutex_init(&client[i][j].svc[k].m_lock); + spin_lock_init(&client[i][j].svc[k].w_lock); + } + } + apr_set_subsys_state(); + mutex_init(&q6.lock); + apr_reset_workqueue = create_singlethread_workqueue("apr_driver"); + if (!apr_reset_workqueue) + return -ENOMEM; + + apr_pkt_ctx = ipc_log_context_create(APR_PKT_IPC_LOG_PAGE_CNT, + "apr", 0); + if (!apr_pkt_ctx) + pr_err("%s: Unable to create ipc log context\n", __func__); + + is_initial_boot = true; + subsys_notif_register("apr_adsp", AUDIO_NOTIFIER_ADSP_DOMAIN, + &adsp_service_nb); + subsys_notif_register("apr_modem", AUDIO_NOTIFIER_MODEM_DOMAIN, + &modem_service_nb); + + return 0; +} +device_initcall(apr_init); + +static int __init apr_late_init(void) +{ + int ret = 0; + + init_waitqueue_head(&dsp_wait); + init_waitqueue_head(&modem_wait); + + return ret; +} +late_initcall(apr_late_init); + +#ifdef CONFIG_DEBUG_FS +static int __init apr_debug_init(void) +{ + debugfs_apr_debug = debugfs_create_file("msm_apr_debug", + S_IFREG | 0444, NULL, NULL, + &apr_debug_ops); + return 0; +} +device_initcall(apr_debug_init); +#endif diff --git a/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c b/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c new file mode 100644 index 000000000000..fc7f63f1cae1 --- /dev/null +++ b/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c @@ -0,0 +1,451 @@ +/* + * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define APR_MAXIMUM_NUM_OF_RETRIES 2 + +struct apr_tx_buf { + struct apr_pkt_priv pkt_priv; + char buf[APR_MAX_BUF]; +}; + +struct link_state { + uint32_t dest; + void *handle; + enum glink_link_state link_state; + wait_queue_head_t wait; +}; + +static struct link_state link_state[APR_DEST_MAX]; + +static char *svc_names[APR_DEST_MAX][APR_CLIENT_MAX] = { + { + "apr_audio_svc", + "apr_voice_svc", + }, + { + "apr_audio_svc", + "apr_voice_svc", + }, +}; + +static struct apr_svc_ch_dev + apr_svc_ch[APR_DL_MAX][APR_DEST_MAX][APR_CLIENT_MAX]; + +static struct apr_tx_buf *apr_alloc_buf(int len) +{ + + if (len > APR_MAX_BUF) { + pr_err("%s: buf too large [%d]\n", __func__, len); + return ERR_PTR(-EINVAL); + } + + return kzalloc(sizeof(struct apr_tx_buf), GFP_ATOMIC); +} + +static void apr_free_buf(const void *ptr) +{ + + struct apr_pkt_priv *apr_pkt_priv = (struct apr_pkt_priv *)ptr; + struct apr_tx_buf *tx_buf; + + if (!apr_pkt_priv) { + pr_err("%s: Invalid apr_pkt_priv\n", __func__); + return; + } + + if (apr_pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER) { + tx_buf = container_of((void *)apr_pkt_priv, + struct apr_tx_buf, pkt_priv); + pr_debug("%s: Freeing buffer %pK", __func__, tx_buf); + kfree(tx_buf); + } +} + + +static int __apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data, + struct apr_pkt_priv *pkt_priv, int len) +{ + int rc = 0; + unsigned long flags; + + spin_lock_irqsave(&apr_ch->w_lock, flags); + rc = glink_tx(apr_ch->handle, pkt_priv, data, len, GLINK_TX_ATOMIC); + spin_unlock_irqrestore(&apr_ch->w_lock, flags); + + if (rc) + pr_err("%s: glink_tx failed, rc[%d]\n", __func__, rc); + else + rc = len; + + return rc; +} + +int apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data, + struct apr_pkt_priv *pkt_priv, int len) +{ + int rc = 0, retries = 0; + void *pkt_data = NULL; + struct apr_tx_buf *tx_buf = NULL; + struct apr_pkt_priv *pkt_priv_ptr = pkt_priv; + + if (!apr_ch->handle || !pkt_priv) + return -EINVAL; + + if (pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER) { + tx_buf = apr_alloc_buf(len); + if (IS_ERR_OR_NULL(tx_buf)) { + rc = -EINVAL; + goto exit; + } + memcpy(tx_buf->buf, data, len); + memcpy(&tx_buf->pkt_priv, pkt_priv, sizeof(tx_buf->pkt_priv)); + pkt_priv_ptr = &tx_buf->pkt_priv; + pkt_data = tx_buf->buf; + } else { + pkt_data = data; + } + + do { + if (rc == -EAGAIN) + udelay(50); + + rc = __apr_tal_write(apr_ch, pkt_data, pkt_priv_ptr, len); + } while (rc == -EAGAIN && retries++ < APR_MAXIMUM_NUM_OF_RETRIES); + + if (rc < 0) { + pr_err("%s: Unable to send the packet, rc:%d\n", __func__, rc); + if (pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER) + kfree(tx_buf); + } +exit: + return rc; +} + +void apr_tal_notify_rx(void *handle, const void *priv, const void *pkt_priv, + const void *ptr, size_t size) +{ + struct apr_svc_ch_dev *apr_ch = (struct apr_svc_ch_dev *)priv; + unsigned long flags; + + if (!apr_ch || !ptr) { + pr_err("%s: Invalid apr_ch or ptr\n", __func__); + return; + } + + pr_debug("%s: Rx packet received\n", __func__); + + spin_lock_irqsave(&apr_ch->r_lock, flags); + if (apr_ch->func) + apr_ch->func((void *)ptr, size, (void *)pkt_priv); + spin_unlock_irqrestore(&apr_ch->r_lock, flags); + glink_rx_done(apr_ch->handle, ptr, true); +} + +static void apr_tal_notify_tx_abort(void *handle, const void *priv, + const void *pkt_priv) +{ + pr_debug("%s: tx_abort received for pkt_priv:%pK\n", + __func__, pkt_priv); + apr_free_buf(pkt_priv); +} + +void apr_tal_notify_tx_done(void *handle, const void *priv, + const void *pkt_priv, const void *ptr) +{ + pr_debug("%s: tx_done received for pkt_priv:%pK\n", + __func__, pkt_priv); + apr_free_buf(pkt_priv); +} + +bool apr_tal_notify_rx_intent_req(void *handle, const void *priv, + size_t req_size) +{ + struct apr_svc_ch_dev *apr_ch = (struct apr_svc_ch_dev *)priv; + + if (!apr_ch) { + pr_err("%s: Invalid apr_ch\n", __func__); + return false; + } + + pr_err("%s: No rx intents queued, unable to receive\n", __func__); + return false; +} + +static void apr_tal_notify_remote_rx_intent(void *handle, const void *priv, + size_t size) +{ + struct apr_svc_ch_dev *apr_ch = (struct apr_svc_ch_dev *)priv; + + if (!apr_ch) { + pr_err("%s: Invalid apr_ch\n", __func__); + return; + } + /* + * This is to make sure that the far end has queued at least one intent + * before we attmpt any IPC. A simple bool flag is used here instead of + * a counter, as the far end is required to guarantee intent + * availability for all use cases once the channel is fully opened. + */ + pr_debug("%s: remote queued an intent\n", __func__); + apr_ch->if_remote_intent_ready = true; + wake_up(&apr_ch->wait); +} + +void apr_tal_notify_state(void *handle, const void *priv, unsigned int event) +{ + struct apr_svc_ch_dev *apr_ch = (struct apr_svc_ch_dev *)priv; + + if (!apr_ch) { + pr_err("%s: Invalid apr_ch\n", __func__); + return; + } + + apr_ch->channel_state = event; + pr_info("%s: Channel state[%d]\n", __func__, event); + + if (event == GLINK_CONNECTED) + wake_up(&apr_ch->wait); +} + +int apr_tal_rx_intents_config(struct apr_svc_ch_dev *apr_ch, + int num_of_intents, uint32_t size) +{ + int i; + int rc; + + if (!apr_ch || !num_of_intents || !size) { + pr_err("%s: Invalid parameter\n", __func__); + return -EINVAL; + } + + for (i = 0; i < num_of_intents; i++) { + rc = glink_queue_rx_intent(apr_ch->handle, apr_ch, size); + if (rc) { + pr_err("%s: Failed to queue rx intent, iteration[%d]\n", + __func__, i); + break; + } + } + + return rc; +} + +struct apr_svc_ch_dev *apr_tal_open(uint32_t clnt, uint32_t dest, uint32_t dl, + apr_svc_cb_fn func, void *priv) +{ + int rc; + struct glink_open_config open_cfg; + struct apr_svc_ch_dev *apr_ch; + + if ((clnt >= APR_CLIENT_MAX) || (dest >= APR_DEST_MAX) || + (dl >= APR_DL_MAX)) { + pr_err("%s: Invalid params, clnt:%d, dest:%d, dl:%d\n", + __func__, clnt, dest, dl); + return NULL; + } + + apr_ch = &apr_svc_ch[dl][dest][clnt]; + mutex_lock(&apr_ch->m_lock); + if (apr_ch->handle) { + pr_err("%s: This channel is already opened\n", __func__); + rc = -EBUSY; + goto unlock; + } + + if (link_state[dest].link_state != GLINK_LINK_STATE_UP) { + rc = wait_event_timeout(link_state[dest].wait, + link_state[dest].link_state == GLINK_LINK_STATE_UP, + msecs_to_jiffies(APR_OPEN_TIMEOUT_MS)); + if (rc == 0) { + pr_err("%s: Open timeout, dest:%d\n", __func__, dest); + rc = -ETIMEDOUT; + goto unlock; + } + pr_debug("%s: Wakeup done, dest:%d\n", __func__, dest); + } + + memset(&open_cfg, 0, sizeof(struct glink_open_config)); + open_cfg.options = GLINK_OPT_INITIAL_XPORT; + if (dest == APR_DEST_MODEM) + open_cfg.edge = "mpss"; + else + open_cfg.edge = "lpass"; + + open_cfg.name = svc_names[dest][clnt]; + open_cfg.notify_rx = apr_tal_notify_rx; + open_cfg.notify_tx_done = apr_tal_notify_tx_done; + open_cfg.notify_state = apr_tal_notify_state; + open_cfg.notify_rx_intent_req = apr_tal_notify_rx_intent_req; + open_cfg.notify_remote_rx_intent = apr_tal_notify_remote_rx_intent; + open_cfg.notify_tx_abort = apr_tal_notify_tx_abort; + open_cfg.priv = apr_ch; + open_cfg.transport = "smem"; + + apr_ch->channel_state = GLINK_REMOTE_DISCONNECTED; + apr_ch->handle = glink_open(&open_cfg); + if (IS_ERR_OR_NULL(apr_ch->handle)) { + pr_err("%s: glink_open failed %s\n", __func__, + svc_names[dest][clnt]); + apr_ch->handle = NULL; + rc = -EINVAL; + goto unlock; + } + + rc = wait_event_timeout(apr_ch->wait, + (apr_ch->channel_state == GLINK_CONNECTED), 5 * HZ); + if (rc == 0) { + pr_err("%s: TIMEOUT for OPEN event\n", __func__); + rc = -ETIMEDOUT; + goto close_link; + } + + /* + * Remote intent is not required for GLINK <--> SMD IPC, so this is + * designed not to fail the open call. + */ + rc = wait_event_timeout(apr_ch->wait, + apr_ch->if_remote_intent_ready, 5 * HZ); + if (rc == 0) + pr_err("%s: TIMEOUT for remote intent readiness\n", __func__); + + rc = apr_tal_rx_intents_config(apr_ch, APR_DEFAULT_NUM_OF_INTENTS, + APR_MAX_BUF); + if (rc) { + pr_err("%s: Unable to queue intents\n", __func__); + goto close_link; + } + + apr_ch->func = func; + apr_ch->priv = priv; + +close_link: + if (rc) { + glink_close(apr_ch->handle); + apr_ch->handle = NULL; + } +unlock: + mutex_unlock(&apr_ch->m_lock); + + return rc ? NULL : apr_ch; +} + +int apr_tal_close(struct apr_svc_ch_dev *apr_ch) +{ + int rc; + + if (!apr_ch || !apr_ch->handle) { + rc = -EINVAL; + goto exit; + } + + mutex_lock(&apr_ch->m_lock); + rc = glink_close(apr_ch->handle); + apr_ch->handle = NULL; + apr_ch->func = NULL; + apr_ch->priv = NULL; + apr_ch->if_remote_intent_ready = false; + mutex_unlock(&apr_ch->m_lock); +exit: + return rc; +} + +static void apr_tal_link_state_cb(struct glink_link_state_cb_info *cb_info, + void *priv) +{ + uint32_t dest; + + if (!cb_info) { + pr_err("%s: Invalid cb_info\n", __func__); + return; + } + + if (!strcmp(cb_info->edge, "mpss")) + dest = APR_DEST_MODEM; + else if (!strcmp(cb_info->edge, "lpass")) + dest = APR_DEST_QDSP6; + else { + pr_err("%s:Unknown edge[%s]\n", __func__, cb_info->edge); + return; + } + + pr_info("%s: edge[%s] link state[%d]\n", __func__, cb_info->edge, + cb_info->link_state); + + link_state[dest].link_state = cb_info->link_state; + if (link_state[dest].link_state == GLINK_LINK_STATE_UP) + wake_up(&link_state[dest].wait); +} + +static struct glink_link_info mpss_link_info = { + .transport = "smem", + .edge = "mpss", + .glink_link_state_notif_cb = apr_tal_link_state_cb, +}; + +static struct glink_link_info lpass_link_info = { + .transport = "smem", + .edge = "lpass", + .glink_link_state_notif_cb = apr_tal_link_state_cb, +}; + +static int __init apr_tal_init(void) +{ + int i, j, k; + + for (i = 0; i < APR_DL_MAX; i++) { + for (j = 0; j < APR_DEST_MAX; j++) { + for (k = 0; k < APR_CLIENT_MAX; k++) { + init_waitqueue_head(&apr_svc_ch[i][j][k].wait); + spin_lock_init(&apr_svc_ch[i][j][k].w_lock); + spin_lock_init(&apr_svc_ch[i][j][k].r_lock); + mutex_init(&apr_svc_ch[i][j][k].m_lock); + } + } + } + + for (i = 0; i < APR_DEST_MAX; i++) + init_waitqueue_head(&link_state[i].wait); + + link_state[APR_DEST_MODEM].link_state = GLINK_LINK_STATE_DOWN; + link_state[APR_DEST_MODEM].handle = + glink_register_link_state_cb(&mpss_link_info, NULL); + if (!link_state[APR_DEST_MODEM].handle) + pr_err("%s: Unable to register mpss link state\n", __func__); + + link_state[APR_DEST_QDSP6].link_state = GLINK_LINK_STATE_DOWN; + link_state[APR_DEST_QDSP6].handle = + glink_register_link_state_cb(&lpass_link_info, NULL); + if (!link_state[APR_DEST_QDSP6].handle) + pr_err("%s: Unable to register lpass link state\n", __func__); + + return 0; +} +device_initcall(apr_tal_init); diff --git a/drivers/soc/qcom/qdsp6v2/apr_v2.c b/drivers/soc/qcom/qdsp6v2/apr_v2.c new file mode 100644 index 000000000000..4ddf39b1a097 --- /dev/null +++ b/drivers/soc/qcom/qdsp6v2/apr_v2.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +enum apr_subsys_state apr_get_subsys_state(void) +{ + return apr_get_q6_state(); +} + +void apr_set_subsys_state(void) +{ + apr_set_q6_state(APR_SUBSYS_DOWN); + apr_set_modem_state(APR_SUBSYS_UP); +} + +uint16_t apr_get_data_src(struct apr_hdr *hdr) +{ + if (hdr->src_domain == APR_DOMAIN_MODEM) + return APR_DEST_MODEM; + else if (hdr->src_domain == APR_DOMAIN_ADSP) + return APR_DEST_QDSP6; + + pr_err("APR: Pkt from wrong source: %d\n", hdr->src_domain); + return APR_DEST_MAX; /*RETURN INVALID VALUE*/ +} + +int apr_get_dest_id(char *dest) +{ + if (!strcmp(dest, "ADSP")) + return APR_DEST_QDSP6; + else + return APR_DEST_MODEM; +} + +void subsys_notif_register(char *client_name, int domain, + struct notifier_block *nb) +{ + int ret; + + ret = audio_notifier_register(client_name, domain, nb); + if (ret < 0) + pr_err("%s: Audio notifier register failed for domain %d ret = %d\n", + __func__, domain, ret); +} + +uint16_t apr_get_reset_domain(uint16_t proc) +{ + return proc; +} diff --git a/drivers/soc/qcom/qdsp6v2/apr_v3.c b/drivers/soc/qcom/qdsp6v2/apr_v3.c new file mode 100644 index 000000000000..2bfc518841c9 --- /dev/null +++ b/drivers/soc/qcom/qdsp6v2/apr_v3.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEST_ID APR_DEST_MODEM + +enum apr_subsys_state apr_get_subsys_state(void) +{ + return apr_get_modem_state(); +} + +void apr_set_subsys_state(void) +{ + apr_set_modem_state(APR_SUBSYS_DOWN); +} + +uint16_t apr_get_data_src(struct apr_hdr *hdr) +{ + return DEST_ID; +} + +int apr_get_dest_id(char *dest) +{ + return DEST_ID; +} + +void subsys_notif_register(char *client_name, int domain, + struct notifier_block *nb) +{ + int ret; + + if (domain != AUDIO_NOTIFIER_MODEM_DOMAIN) { + pr_debug("%s: Unused domain %d not registering with notifier\n", + __func__, domain); + return; + } + + ret = audio_notifier_register(client_name, domain, nb); + if (ret < 0) + pr_err("%s: Audio notifier register failed for domain %d ret = %d\n", + __func__, domain, ret); +} + +uint16_t apr_get_reset_domain(uint16_t proc) +{ + return APR_DEST_QDSP6; +} diff --git a/drivers/soc/qcom/qdsp6v2/audio_notifier.c b/drivers/soc/qcom/qdsp6v2/audio_notifier.c new file mode 100644 index 000000000000..2320fea6e891 --- /dev/null +++ b/drivers/soc/qcom/qdsp6v2/audio_notifier.c @@ -0,0 +1,636 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Audio states internal to notifier. Client */ +/* used states defined in audio_notifier.h */ +/* for AUDIO_NOTIFIER_SERVICE_DOWN & UP */ +#define NO_SERVICE -2 +#define UNINIT_SERVICE -1 + +/* + * Used for each client registered with audio notifier + */ +struct client_data { + struct list_head list; + /* Notifier block given by client */ + struct notifier_block *nb; + char client_name[20]; + int service; + int domain; +}; + +/* + * Used for each service and domain combination + * Tracks information specific to the underlying + * service. + */ +struct service_info { + const char name[20]; + int domain_id; + int state; + void *handle; + /* Notifier block registered to service */ + struct notifier_block *nb; + /* Used to determine when to register and deregister service */ + int num_of_clients; + /* List of all clients registered to the service and domain */ + struct srcu_notifier_head client_nb_list; +}; + +static int audio_notifer_ssr_adsp_cb(struct notifier_block *this, + unsigned long opcode, void *data); +static int audio_notifer_ssr_modem_cb(struct notifier_block *this, + unsigned long opcode, void *data); +static int audio_notifer_pdr_adsp_cb(struct notifier_block *this, + unsigned long opcode, void *data); + +static struct notifier_block notifier_ssr_adsp_nb = { + .notifier_call = audio_notifer_ssr_adsp_cb, + .priority = 0, +}; + +static struct notifier_block notifier_ssr_modem_nb = { + .notifier_call = audio_notifer_ssr_modem_cb, + .priority = 0, +}; + +static struct notifier_block notifier_pdr_adsp_nb = { + .notifier_call = audio_notifer_pdr_adsp_cb, + .priority = 0, +}; + +static struct service_info service_data[AUDIO_NOTIFIER_MAX_SERVICES] + [AUDIO_NOTIFIER_MAX_DOMAINS] = { + + {{ + .name = "SSR_ADSP", + .domain_id = AUDIO_SSR_DOMAIN_ADSP, + .state = AUDIO_NOTIFIER_SERVICE_DOWN, + .nb = ¬ifier_ssr_adsp_nb + }, + { + .name = "SSR_MODEM", + .domain_id = AUDIO_SSR_DOMAIN_MODEM, + .state = AUDIO_NOTIFIER_SERVICE_DOWN, + .nb = ¬ifier_ssr_modem_nb + } }, + + {{ + .name = "PDR_ADSP", + .domain_id = AUDIO_PDR_DOMAIN_ADSP, + .state = UNINIT_SERVICE, + .nb = ¬ifier_pdr_adsp_nb + }, + { /* PDR MODEM service not enabled */ + .name = "INVALID", + .state = NO_SERVICE, + .nb = NULL + } } +}; + +/* Master list of all audio notifier clients */ +struct list_head client_list; +struct mutex notifier_mutex; + +static int audio_notifer_get_default_service(int domain) +{ + int service = NO_SERVICE; + + /* initial service to connect per domain */ + switch (domain) { + case AUDIO_NOTIFIER_ADSP_DOMAIN: + service = AUDIO_NOTIFIER_PDR_SERVICE; + break; + case AUDIO_NOTIFIER_MODEM_DOMAIN: + service = AUDIO_NOTIFIER_SSR_SERVICE; + break; + } + + return service; +} + +static void audio_notifer_disable_service(int service) +{ + int i; + + for (i = 0; i < AUDIO_NOTIFIER_MAX_DOMAINS; i++) + service_data[service][i].state = NO_SERVICE; +} + +static bool audio_notifer_is_service_enabled(int service) +{ + int i; + + for (i = 0; i < AUDIO_NOTIFIER_MAX_DOMAINS; i++) + if (service_data[service][i].state != NO_SERVICE) + return true; + return false; +} + +static void audio_notifer_init_service(int service) +{ + int i; + + for (i = 0; i < AUDIO_NOTIFIER_MAX_DOMAINS; i++) { + if (service_data[service][i].state == UNINIT_SERVICE) + service_data[service][i].state = + AUDIO_NOTIFIER_SERVICE_DOWN; + } +} + +static int audio_notifer_reg_service(int service, int domain) +{ + void *handle; + int ret = 0; + int curr_state = AUDIO_NOTIFIER_SERVICE_DOWN; + + switch (service) { + case AUDIO_NOTIFIER_SSR_SERVICE: + handle = audio_ssr_register( + service_data[service][domain].domain_id, + service_data[service][domain].nb); + break; + case AUDIO_NOTIFIER_PDR_SERVICE: + handle = audio_pdr_service_register( + service_data[service][domain].domain_id, + service_data[service][domain].nb, &curr_state); + + if (curr_state == SERVREG_NOTIF_SERVICE_STATE_UP_V01) + curr_state = AUDIO_NOTIFIER_SERVICE_UP; + else + curr_state = AUDIO_NOTIFIER_SERVICE_DOWN; + break; + default: + pr_err("%s: Invalid service %d\n", + __func__, service); + ret = -EINVAL; + goto done; + } + if (IS_ERR_OR_NULL(handle)) { + pr_err("%s: handle is incorrect for service %s\n", + __func__, service_data[service][domain].name); + ret = -EINVAL; + goto done; + } + service_data[service][domain].state = curr_state; + service_data[service][domain].handle = handle; + + pr_info("%s: service %s is in use\n", + __func__, service_data[service][domain].name); + pr_debug("%s: service %s has current state %d, handle 0x%pK\n", + __func__, service_data[service][domain].name, + service_data[service][domain].state, + service_data[service][domain].handle); +done: + return ret; +} + +static int audio_notifer_dereg_service(int service, int domain) +{ + int ret; + + switch (service) { + case AUDIO_NOTIFIER_SSR_SERVICE: + ret = audio_ssr_deregister( + service_data[service][domain].handle, + service_data[service][domain].nb); + break; + case AUDIO_NOTIFIER_PDR_SERVICE: + ret = audio_pdr_service_deregister( + service_data[service][domain].handle, + service_data[service][domain].nb); + break; + default: + pr_err("%s: Invalid service %d\n", + __func__, service); + ret = -EINVAL; + goto done; + } + if (ret < 0) { + pr_err("%s: deregister failed for service %s, ret %d\n", + __func__, service_data[service][domain].name, ret); + goto done; + } + + pr_debug("%s: service %s with handle 0x%pK deregistered\n", + __func__, service_data[service][domain].name, + service_data[service][domain].handle); + + service_data[service][domain].state = AUDIO_NOTIFIER_SERVICE_DOWN; + service_data[service][domain].handle = NULL; +done: + return ret; +} + +static int audio_notifer_reg_client_service(struct client_data *client_data, + int service) +{ + int ret = 0; + int domain = client_data->domain; + struct audio_notifier_cb_data data; + + switch (service) { + case AUDIO_NOTIFIER_SSR_SERVICE: + case AUDIO_NOTIFIER_PDR_SERVICE: + if (service_data[service][domain].num_of_clients == 0) + ret = audio_notifer_reg_service(service, domain); + break; + default: + pr_err("%s: Invalid service for client %s, service %d, domain %d\n", + __func__, client_data->client_name, service, domain); + ret = -EINVAL; + goto done; + } + + if (ret < 0) { + pr_err("%s: service registration failed on service %s for client %s\n", + __func__, service_data[service][domain].name, + client_data->client_name); + goto done; + } + + client_data->service = service; + srcu_notifier_chain_register( + &service_data[service][domain].client_nb_list, + client_data->nb); + service_data[service][domain].num_of_clients++; + + pr_debug("%s: registered client %s on service %s, current state 0x%x\n", + __func__, client_data->client_name, + service_data[service][domain].name, + service_data[service][domain].state); + + /* + * PDR registration returns current state + * Force callback of client with current state for PDR + */ + if (client_data->service == AUDIO_NOTIFIER_PDR_SERVICE) { + data.service = service; + data.domain = domain; + (void)client_data->nb->notifier_call(client_data->nb, + service_data[service][domain].state, &data); + } +done: + return ret; +} + +static int audio_notifer_reg_client(struct client_data *client_data) +{ + int ret = 0; + int service; + int domain = client_data->domain; + + service = audio_notifer_get_default_service(domain); + if (service < 0) { + pr_err("%s: service %d is incorrect\n", __func__, service); + ret = -EINVAL; + goto done; + } + + /* Search through services to find a valid one to register client on. */ + for (; service >= 0; service--) { + /* If a service is not initialized, wait for it to come up. */ + if (service_data[service][domain].state == UNINIT_SERVICE) + goto done; + /* Skip unsupported service and domain combinations. */ + if (service_data[service][domain].state < 0) + continue; + /* Only register clients who have not acquired a service. */ + if (client_data->service != NO_SERVICE) + continue; + + /* + * Only register clients, who have not acquired a service, on + * the best available service for their domain. Uninitialized + * services will try to register all of their clients after + * they initialize correctly or will disable their service and + * register clients on the next best avaialable service. + */ + pr_debug("%s: register client %s on service %s", + __func__, client_data->client_name, + service_data[service][domain].name); + + ret = audio_notifer_reg_client_service(client_data, service); + if (ret < 0) + pr_err("%s: client %s failed to register on service %s", + __func__, client_data->client_name, + service_data[service][domain].name); + } + +done: + return ret; +} + +static int audio_notifer_dereg_client(struct client_data *client_data) +{ + int ret = 0; + int service = client_data->service; + int domain = client_data->domain; + + switch (client_data->service) { + case AUDIO_NOTIFIER_SSR_SERVICE: + case AUDIO_NOTIFIER_PDR_SERVICE: + if (service_data[service][domain].num_of_clients == 1) + ret = audio_notifer_dereg_service(service, domain); + break; + case NO_SERVICE: + goto done; + default: + pr_err("%s: Invalid service for client %s, service %d\n", + __func__, client_data->client_name, + client_data->service); + ret = -EINVAL; + goto done; + } + + if (ret < 0) { + pr_err("%s: deregister failed for client %s on service %s, ret %d\n", + __func__, client_data->client_name, + service_data[service][domain].name, ret); + goto done; + } + + ret = srcu_notifier_chain_unregister(&service_data[service][domain]. + client_nb_list, client_data->nb); + if (ret < 0) { + pr_err("%s: srcu_notifier_chain_unregister failed, ret %d\n", + __func__, ret); + goto done; + } + + pr_debug("%s: deregistered client %s on service %s\n", + __func__, client_data->client_name, + service_data[service][domain].name); + + client_data->service = NO_SERVICE; + if (service_data[service][domain].num_of_clients > 0) + service_data[service][domain].num_of_clients--; +done: + return ret; +} + +static void audio_notifer_reg_all_clients(void) +{ + struct list_head *ptr, *next; + struct client_data *client_data; + int ret; + + list_for_each_safe(ptr, next, &client_list) { + client_data = list_entry(ptr, struct client_data, list); + + ret = audio_notifer_reg_client(client_data); + if (ret < 0) + pr_err("%s: audio_notifer_reg_client failed for client %s, ret %d\n", + __func__, client_data->client_name, + ret); + } +} + +static int audio_notifer_pdr_callback(struct notifier_block *this, + unsigned long opcode, void *data) +{ + pr_debug("%s: Audio PDR framework state 0x%lx\n", + __func__, opcode); + mutex_lock(¬ifier_mutex); + if (opcode == AUDIO_PDR_FRAMEWORK_DOWN) + audio_notifer_disable_service(AUDIO_NOTIFIER_PDR_SERVICE); + else + audio_notifer_init_service(AUDIO_NOTIFIER_PDR_SERVICE); + + audio_notifer_reg_all_clients(); + mutex_unlock(¬ifier_mutex); + return 0; +} + +static struct notifier_block pdr_nb = { + .notifier_call = audio_notifer_pdr_callback, + .priority = 0, +}; + +static int audio_notifer_convert_opcode(unsigned long opcode, + unsigned long *notifier_opcode) +{ + int ret = 0; + + switch (opcode) { + case SUBSYS_BEFORE_SHUTDOWN: + case SERVREG_NOTIF_SERVICE_STATE_DOWN_V01: + *notifier_opcode = AUDIO_NOTIFIER_SERVICE_DOWN; + break; + case SUBSYS_AFTER_POWERUP: + case SERVREG_NOTIF_SERVICE_STATE_UP_V01: + *notifier_opcode = AUDIO_NOTIFIER_SERVICE_UP; + break; + default: + pr_debug("%s: Unused opcode 0x%lx\n", __func__, opcode); + ret = -EINVAL; + } + + return ret; +} + +static int audio_notifer_service_cb(unsigned long opcode, + int service, int domain) +{ + int ret = 0; + unsigned long notifier_opcode; + struct audio_notifier_cb_data data; + + if (audio_notifer_convert_opcode(opcode, ¬ifier_opcode) < 0) + goto done; + + data.service = service; + data.domain = domain; + + pr_debug("%s: service %s, opcode 0x%lx\n", + __func__, service_data[service][domain].name, notifier_opcode); + + mutex_lock(¬ifier_mutex); + + service_data[service][domain].state = notifier_opcode; + ret = srcu_notifier_call_chain(&service_data[service][domain]. + client_nb_list, notifier_opcode, &data); + if (ret < 0) + pr_err("%s: srcu_notifier_call_chain returned %d, service %s, opcode 0x%lx\n", + __func__, ret, service_data[service][domain].name, + notifier_opcode); + + mutex_unlock(¬ifier_mutex); +done: + return NOTIFY_OK; +} + +static int audio_notifer_pdr_adsp_cb(struct notifier_block *this, + unsigned long opcode, void *data) +{ + return audio_notifer_service_cb(opcode, + AUDIO_NOTIFIER_PDR_SERVICE, + AUDIO_NOTIFIER_ADSP_DOMAIN); +} + +static int audio_notifer_ssr_adsp_cb(struct notifier_block *this, + unsigned long opcode, void *data) +{ + if (opcode == SUBSYS_BEFORE_SHUTDOWN) + audio_ssr_send_nmi(data); + + return audio_notifer_service_cb(opcode, + AUDIO_NOTIFIER_SSR_SERVICE, + AUDIO_NOTIFIER_ADSP_DOMAIN); +} + +static int audio_notifer_ssr_modem_cb(struct notifier_block *this, + unsigned long opcode, void *data) +{ + return audio_notifer_service_cb(opcode, + AUDIO_NOTIFIER_SSR_SERVICE, + AUDIO_NOTIFIER_MODEM_DOMAIN); +} + +int audio_notifier_deregister(char *client_name) +{ + int ret = 0; + int ret2; + struct list_head *ptr, *next; + struct client_data *client_data; + + if (client_name == NULL) { + pr_err("%s: client_name is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + mutex_lock(¬ifier_mutex); + list_for_each_safe(ptr, next, &client_list) { + client_data = list_entry(ptr, struct client_data, list); + if (!strcmp(client_name, client_data->client_name)) { + ret2 = audio_notifer_dereg_client(client_data); + if (ret2 < 0) { + pr_err("%s: audio_notifer_dereg_client failed, ret %d\n, service %d, domain %d", + __func__, ret2, client_data->service, + client_data->domain); + ret = ret2; + continue; + } + list_del(&client_data->list); + kfree(client_data); + } + } + mutex_unlock(¬ifier_mutex); +done: + return ret; +} +EXPORT_SYMBOL(audio_notifier_deregister); + +int audio_notifier_register(char *client_name, int domain, + struct notifier_block *nb) +{ + int ret; + struct client_data *client_data; + + if (client_name == NULL) { + pr_err("%s: client_name is NULL\n", __func__); + ret = -EINVAL; + goto done; + } else if (nb == NULL) { + pr_err("%s: Notifier block is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + client_data = kmalloc(sizeof(*client_data), GFP_KERNEL); + if (client_data == NULL) { + ret = -ENOMEM; + goto done; + } + INIT_LIST_HEAD(&client_data->list); + client_data->nb = nb; + strlcpy(client_data->client_name, client_name, + sizeof(client_data->client_name)); + client_data->service = NO_SERVICE; + client_data->domain = domain; + + mutex_lock(¬ifier_mutex); + ret = audio_notifer_reg_client(client_data); + if (ret < 0) { + mutex_unlock(¬ifier_mutex); + pr_err("%s: audio_notifer_reg_client for client %s failed ret = %d\n", + __func__, client_data->client_name, + ret); + kfree(client_data); + goto done; + } + list_add_tail(&client_data->list, &client_list); + mutex_unlock(¬ifier_mutex); +done: + return ret; +} +EXPORT_SYMBOL(audio_notifier_register); + +static int __init audio_notifier_subsys_init(void) +{ + int i, j; + + mutex_init(¬ifier_mutex); + INIT_LIST_HEAD(&client_list); + for (i = 0; i < AUDIO_NOTIFIER_MAX_SERVICES; i++) { + for (j = 0; j < AUDIO_NOTIFIER_MAX_DOMAINS; j++) { + if (service_data[i][j].state <= NO_SERVICE) + continue; + + srcu_init_notifier_head( + &service_data[i][j].client_nb_list); + } + } + + return 0; +} +subsys_initcall(audio_notifier_subsys_init); + +static int __init audio_notifier_init(void) +{ + int ret; + + ret = audio_pdr_register(&pdr_nb); + if (ret < 0) { + pr_debug("%s: PDR register failed, ret = %d, disable service\n", + __func__, ret); + audio_notifer_disable_service(AUDIO_NOTIFIER_PDR_SERVICE); + } + + /* Do not return error since PDR enablement is not critical */ + return 0; +} +module_init(audio_notifier_init); + +static int __init audio_notifier_late_init(void) +{ + /* + * If pdr registration failed, register clients on next service + * Do in late init to ensure that SSR subsystem is initialized + */ + mutex_lock(¬ifier_mutex); + if (!audio_notifer_is_service_enabled(AUDIO_NOTIFIER_PDR_SERVICE)) + audio_notifer_reg_all_clients(); + + mutex_unlock(¬ifier_mutex); + return 0; +} +late_initcall(audio_notifier_late_init); diff --git a/drivers/soc/qcom/qdsp6v2/audio_pdr.c b/drivers/soc/qcom/qdsp6v2/audio_pdr.c new file mode 100644 index 000000000000..449d19a80b3e --- /dev/null +++ b/drivers/soc/qcom/qdsp6v2/audio_pdr.c @@ -0,0 +1,147 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +static struct pd_qmi_client_data audio_pdr_services[AUDIO_PDR_DOMAIN_MAX] = { + { /* AUDIO_PDR_DOMAIN_ADSP */ + .client_name = "audio_pdr_adsp", + .service_name = "avs/audio" + } +}; + +struct srcu_notifier_head audio_pdr_cb_list; + +static int audio_pdr_locator_callback(struct notifier_block *this, + unsigned long opcode, void *data) +{ + unsigned long pdr_state = AUDIO_PDR_FRAMEWORK_DOWN; + + if (opcode == LOCATOR_DOWN) { + pr_debug("%s: Service %s is down!", __func__, + audio_pdr_services[AUDIO_PDR_DOMAIN_ADSP]. + service_name); + goto done; + } + + memcpy(&audio_pdr_services, data, + sizeof(audio_pdr_services[AUDIO_PDR_DOMAIN_ADSP])); + if (audio_pdr_services[AUDIO_PDR_DOMAIN_ADSP].total_domains == 1) { + pr_debug("%s: Service %s, returned total domains %d, ", + __func__, + audio_pdr_services[AUDIO_PDR_DOMAIN_ADSP].service_name, + audio_pdr_services[AUDIO_PDR_DOMAIN_ADSP]. + total_domains); + pdr_state = AUDIO_PDR_FRAMEWORK_UP; + goto done; + } else + pr_err("%s: Service %s returned invalid total domains %d", + __func__, + audio_pdr_services[AUDIO_PDR_DOMAIN_ADSP].service_name, + audio_pdr_services[AUDIO_PDR_DOMAIN_ADSP]. + total_domains); +done: + srcu_notifier_call_chain(&audio_pdr_cb_list, pdr_state, NULL); + return NOTIFY_OK; +} + +static struct notifier_block audio_pdr_locator_nb = { + .notifier_call = audio_pdr_locator_callback, + .priority = 0, +}; + +int audio_pdr_register(struct notifier_block *nb) +{ + if (nb == NULL) { + pr_err("%s: Notifier block is NULL\n", __func__); + return -EINVAL; + } + return srcu_notifier_chain_register(&audio_pdr_cb_list, nb); +} +EXPORT_SYMBOL(audio_pdr_register); + +void *audio_pdr_service_register(int domain_id, + struct notifier_block *nb, int *curr_state) +{ + void *handle; + + if ((domain_id < 0) || + (domain_id >= AUDIO_PDR_DOMAIN_MAX)) { + pr_err("%s: Invalid service ID %d\n", __func__, domain_id); + return ERR_PTR(-EINVAL); + } + + handle = service_notif_register_notifier( + audio_pdr_services[domain_id].domain_list[0].name, + audio_pdr_services[domain_id].domain_list[0].instance_id, + nb, curr_state); + if (IS_ERR_OR_NULL(handle)) { + pr_err("%s: Failed to register for service %s, instance %d\n", + __func__, + audio_pdr_services[domain_id].domain_list[0].name, + audio_pdr_services[domain_id].domain_list[0]. + instance_id); + } + return handle; +} +EXPORT_SYMBOL(audio_pdr_service_register); + +int audio_pdr_service_deregister(void *service_handle, + struct notifier_block *nb) +{ + int ret; + + if (service_handle == NULL) { + pr_err("%s: service handle is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + ret = service_notif_unregister_notifier( + service_handle, nb); + if (ret < 0) + pr_err("%s: Failed to deregister service ret %d\n", + __func__, ret); +done: + return ret; +} +EXPORT_SYMBOL(audio_pdr_service_deregister); + +static int __init audio_pdr_subsys_init(void) +{ + srcu_init_notifier_head(&audio_pdr_cb_list); + return 0; +} +subsys_initcall(audio_pdr_subsys_init); + +static int __init audio_pdr_late_init(void) +{ + int ret; + + ret = get_service_location( + audio_pdr_services[AUDIO_PDR_DOMAIN_ADSP].client_name, + audio_pdr_services[AUDIO_PDR_DOMAIN_ADSP].service_name, + &audio_pdr_locator_nb); + if (ret < 0) { + pr_err("%s get_service_location failed ret %d\n", + __func__, ret); + srcu_notifier_call_chain(&audio_pdr_cb_list, + AUDIO_PDR_FRAMEWORK_DOWN, NULL); + } + + return ret; +} +late_initcall(audio_pdr_late_init); diff --git a/drivers/soc/qcom/qdsp6v2/audio_ssr.c b/drivers/soc/qcom/qdsp6v2/audio_ssr.c new file mode 100644 index 000000000000..a66fb2a63fae --- /dev/null +++ b/drivers/soc/qcom/qdsp6v2/audio_ssr.c @@ -0,0 +1,66 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +#define SCM_Q6_NMI_CMD 0x1 + +static char *audio_ssr_domains[] = { + "adsp", + "modem" +}; + +void *audio_ssr_register(int domain_id, struct notifier_block *nb) +{ + if ((domain_id < 0) || + (domain_id >= AUDIO_SSR_DOMAIN_MAX)) { + pr_err("%s: Invalid service ID %d\n", __func__, domain_id); + return ERR_PTR(-EINVAL); + } + + return subsys_notif_register_notifier( + audio_ssr_domains[domain_id], nb); +} +EXPORT_SYMBOL(audio_ssr_register); + +int audio_ssr_deregister(void *handle, struct notifier_block *nb) +{ + return subsys_notif_unregister_notifier(handle, nb); +} +EXPORT_SYMBOL(audio_ssr_deregister); + +void audio_ssr_send_nmi(void *ssr_cb_data) +{ + struct notif_data *data = (struct notif_data *)ssr_cb_data; + struct scm_desc desc; + + if (data && data->crashed) { + /* Send NMI to QDSP6 via an SCM call. */ + if (!is_scm_armv8()) { + scm_call_atomic1(SCM_SVC_UTIL, + SCM_Q6_NMI_CMD, 0x1); + } else { + desc.args[0] = 0x1; + desc.arginfo = SCM_ARGS(1); + scm_call2_atomic(SCM_SIP_FNID(SCM_SVC_UTIL, + SCM_Q6_NMI_CMD), &desc); + } + /* The write should go through before q6 is shutdown */ + mb(); + pr_debug("%s: Q6 NMI was sent.\n", __func__); + } +} +EXPORT_SYMBOL(audio_ssr_send_nmi); diff --git a/drivers/soc/qcom/qdsp6v2/cdsp-loader.c b/drivers/soc/qcom/qdsp6v2/cdsp-loader.c new file mode 100644 index 000000000000..70977d36f0c9 --- /dev/null +++ b/drivers/soc/qcom/qdsp6v2/cdsp-loader.c @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2012-2014, 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define BOOT_CMD 1 +#define IMAGE_UNLOAD_CMD 0 + +#define CDSP_SUBSYS_DOWN 0 +#define CDSP_SUBSYS_LOADED 1 + +static ssize_t cdsp_boot_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count); + +struct cdsp_loader_private { + void *pil_h; + struct kobject *boot_cdsp_obj; + struct attribute_group *attr_group; +}; + +static struct kobj_attribute cdsp_boot_attribute = + __ATTR(boot, 0220, NULL, cdsp_boot_store); + +static struct attribute *attrs[] = { + &cdsp_boot_attribute.attr, + NULL, +}; + +static u32 cdsp_state = CDSP_SUBSYS_DOWN; +static struct platform_device *cdsp_private; +static struct work_struct cdsp_ldr_work; +static void cdsp_loader_unload(struct platform_device *pdev); + +static void cdsp_load_fw(struct work_struct *cdsp_ldr_work) +{ + struct platform_device *pdev = cdsp_private; + struct cdsp_loader_private *priv = NULL; + + int rc = 0; + const char *img_name; + + if (!pdev) { + dev_err(&pdev->dev, "%s: Platform device null\n", __func__); + goto fail; + } + + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, + "%s: Device tree information missing\n", __func__); + + goto fail; + } + + rc = of_property_read_string(pdev->dev.of_node, + "qcom,proc-img-to-load", + &img_name); + if (rc) + goto fail; + + if (!strcmp(img_name, "cdsp")) { + /* cdsp_state always returns "0".*/ + if (cdsp_state == CDSP_SUBSYS_DOWN) { + priv = platform_get_drvdata(pdev); + if (!priv) { + dev_err(&pdev->dev, + " %s: Private data get failed\n", __func__); + goto fail; + } + + priv->pil_h = subsystem_get("cdsp"); + if (IS_ERR(priv->pil_h)) { + dev_err(&pdev->dev, "%s: pil get failed,\n", + __func__); + goto fail; + } + + /* Set the state of the CDSP.*/ + cdsp_state = CDSP_SUBSYS_LOADED; + } else if (cdsp_state == CDSP_SUBSYS_LOADED) { + dev_dbg(&pdev->dev, + "%s: CDSP state = %x\n", __func__, cdsp_state); + } + + dev_dbg(&pdev->dev, "%s: CDSP image is loaded\n", __func__); + return; + } + +fail: + dev_err(&pdev->dev, "%s: CDSP image loading failed\n", __func__); +} + +static void cdsp_loader_do(struct platform_device *pdev) +{ + schedule_work(&cdsp_ldr_work); +} + +static ssize_t cdsp_boot_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + int boot = 0, ret = 0; + + ret = sscanf(buf, "%du", &boot); + + if (ret != 1) + pr_debug("%s: invalid arguments for cdsp_loader.\n", __func__); + + if (boot == BOOT_CMD) { + pr_debug("%s: going to call cdsp_loader_do\n", __func__); + cdsp_loader_do(cdsp_private); + } else if (boot == IMAGE_UNLOAD_CMD) { + pr_debug("%s: going to call cdsp_unloader\n", __func__); + cdsp_loader_unload(cdsp_private); + } + return count; +} + +static void cdsp_loader_unload(struct platform_device *pdev) +{ + struct cdsp_loader_private *priv = NULL; + + priv = platform_get_drvdata(pdev); + + if (!priv) + return; + + if (priv->pil_h) { + dev_dbg(&pdev->dev, "%s: calling subsystem put\n", __func__); + subsystem_put(priv->pil_h); + priv->pil_h = NULL; + } +} + +static int cdsp_loader_init_sysfs(struct platform_device *pdev) +{ + int ret = -EINVAL; + struct cdsp_loader_private *priv = NULL; + + cdsp_private = NULL; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) { + ret = -ENOMEM; + return ret; + } + + platform_set_drvdata(pdev, priv); + + priv->pil_h = NULL; + priv->boot_cdsp_obj = NULL; + priv->attr_group = devm_kzalloc(&pdev->dev, + sizeof(*(priv->attr_group)), + GFP_KERNEL); + if (!priv->attr_group) { + dev_err(&pdev->dev, "%s: malloc attr_group failed\n", + __func__); + ret = -ENOMEM; + goto error_return; + } + + priv->attr_group->attrs = attrs; + + priv->boot_cdsp_obj = kobject_create_and_add("boot_cdsp", kernel_kobj); + if (!priv->boot_cdsp_obj) { + dev_err(&pdev->dev, "%s: sysfs create and add failed\n", + __func__); + ret = -ENOMEM; + goto error_return; + } + + ret = sysfs_create_group(priv->boot_cdsp_obj, priv->attr_group); + if (ret) { + dev_err(&pdev->dev, "%s: sysfs create group failed %d\n", + __func__, ret); + goto error_return; + } + + cdsp_private = pdev; + + return 0; + +error_return: + + if (priv->boot_cdsp_obj) { + kobject_del(priv->boot_cdsp_obj); + priv->boot_cdsp_obj = NULL; + } + + return ret; +} + +static int cdsp_loader_remove(struct platform_device *pdev) +{ + struct cdsp_loader_private *priv = NULL; + + priv = platform_get_drvdata(pdev); + + if (!priv) + return 0; + + if (priv->pil_h) { + subsystem_put(priv->pil_h); + priv->pil_h = NULL; + } + + if (priv->boot_cdsp_obj) { + sysfs_remove_group(priv->boot_cdsp_obj, priv->attr_group); + kobject_del(priv->boot_cdsp_obj); + priv->boot_cdsp_obj = NULL; + } + + return 0; +} + +static int cdsp_loader_probe(struct platform_device *pdev) +{ + int ret = cdsp_loader_init_sysfs(pdev); + + if (ret != 0) { + dev_err(&pdev->dev, "%s: Error in initing sysfs\n", __func__); + return ret; + } + + INIT_WORK(&cdsp_ldr_work, cdsp_load_fw); + + return 0; +} + +static const struct of_device_id cdsp_loader_dt_match[] = { + { .compatible = "qcom,cdsp-loader" }, + { } +}; +MODULE_DEVICE_TABLE(of, cdsp_loader_dt_match); + +static struct platform_driver cdsp_loader_driver = { + .driver = { + .name = "cdsp-loader", + .owner = THIS_MODULE, + .of_match_table = cdsp_loader_dt_match, + }, + .probe = cdsp_loader_probe, + .remove = cdsp_loader_remove, +}; + +static int __init cdsp_loader_init(void) +{ + return platform_driver_register(&cdsp_loader_driver); +} +module_init(cdsp_loader_init); + +static void __exit cdsp_loader_exit(void) +{ + platform_driver_unregister(&cdsp_loader_driver); +} +module_exit(cdsp_loader_exit); + +MODULE_DESCRIPTION("CDSP Loader module"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c b/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c new file mode 100644 index 000000000000..2f14c744cd89 --- /dev/null +++ b/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c @@ -0,0 +1,853 @@ +/* + * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MSM_AUDIO_ION_PROBED (1 << 0) + +#define MSM_AUDIO_ION_PHYS_ADDR(alloc_data) \ + alloc_data->table->sgl->dma_address + +#define MSM_AUDIO_ION_VA_START 0x10000000 +#define MSM_AUDIO_ION_VA_LEN 0x0FFFFFFF + +#define MSM_AUDIO_SMMU_SID_OFFSET 32 + +struct msm_audio_ion_private { + bool smmu_enabled; + bool audioheap_enabled; + struct device *cb_dev; + struct dma_iommu_mapping *mapping; + u8 device_status; + struct list_head alloc_list; + struct mutex list_mutex; + u64 smmu_sid_bits; + u32 smmu_version; +}; + +struct msm_audio_alloc_data { + struct ion_client *client; + struct ion_handle *handle; + size_t len; + struct dma_buf *dma_buf; + struct dma_buf_attachment *attach; + struct sg_table *table; + struct list_head list; +}; + +static struct msm_audio_ion_private msm_audio_ion_data = {0,}; + +static int msm_audio_ion_get_phys(struct ion_client *client, + struct ion_handle *handle, + ion_phys_addr_t *addr, size_t *len); + +static int msm_audio_dma_buf_map(struct ion_client *client, + struct ion_handle *handle, + ion_phys_addr_t *addr, size_t *len); + +static int msm_audio_dma_buf_unmap(struct ion_client *client, + struct ion_handle *handle); + +static void msm_audio_ion_add_allocation( + struct msm_audio_ion_private *msm_audio_ion_data, + struct msm_audio_alloc_data *alloc_data) +{ + /* + * Since these APIs can be invoked by multiple + * clients, there is need to make sure the list + * of allocations is always protected + */ + mutex_lock(&(msm_audio_ion_data->list_mutex)); + list_add_tail(&(alloc_data->list), + &(msm_audio_ion_data->alloc_list)); + mutex_unlock(&(msm_audio_ion_data->list_mutex)); +} + +int msm_audio_ion_alloc(const char *name, struct ion_client **client, + struct ion_handle **handle, size_t bufsz, + ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr) +{ + int rc = -EINVAL; + unsigned long err_ion_ptr = 0; + + if ((msm_audio_ion_data.smmu_enabled == true) && + !(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { + pr_debug("%s:probe is not done, deferred\n", __func__); + return -EPROBE_DEFER; + } + if (!name || !client || !handle || !paddr || !vaddr + || !bufsz || !pa_len) { + pr_err("%s: Invalid params\n", __func__); + return -EINVAL; + } + *client = msm_audio_ion_client_create(name); + if (IS_ERR_OR_NULL((void *)(*client))) { + pr_err("%s: ION create client for AUDIO failed\n", __func__); + goto err; + } + + *handle = ion_alloc(*client, bufsz, SZ_4K, + ION_HEAP(ION_AUDIO_HEAP_ID), 0); + if (IS_ERR_OR_NULL((void *) (*handle))) { + if (msm_audio_ion_data.smmu_enabled == true) { + pr_debug("system heap is used"); + msm_audio_ion_data.audioheap_enabled = 0; + *handle = ion_alloc(*client, bufsz, SZ_4K, + ION_HEAP(ION_SYSTEM_HEAP_ID), 0); + } + if (IS_ERR_OR_NULL((void *) (*handle))) { + if (IS_ERR((void *)(*handle))) + err_ion_ptr = PTR_ERR((int *)(*handle)); + pr_err("%s:ION alloc fail err ptr=%ld, smmu_enabled=%d\n", + __func__, err_ion_ptr, msm_audio_ion_data.smmu_enabled); + rc = -ENOMEM; + goto err_ion_client; + } + } else { + pr_debug("audio heap is used"); + msm_audio_ion_data.audioheap_enabled = 1; + } + + rc = msm_audio_ion_get_phys(*client, *handle, paddr, pa_len); + if (rc) { + pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", + __func__, rc); + goto err_ion_handle; + } + + *vaddr = ion_map_kernel(*client, *handle); + if (IS_ERR_OR_NULL((void *)*vaddr)) { + pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); + goto err_ion_handle; + } + pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, + *vaddr, bufsz); + + if (bufsz != 0) { + pr_debug("%s: memset to 0 %pK %zd\n", __func__, *vaddr, bufsz); + memset((void *)*vaddr, 0, bufsz); + } + + return rc; + +err_ion_handle: + ion_free(*client, *handle); +err_ion_client: + msm_audio_ion_client_destroy(*client); + *handle = NULL; + *client = NULL; +err: + return rc; +} +EXPORT_SYMBOL(msm_audio_ion_alloc); + +int msm_audio_ion_import(const char *name, struct ion_client **client, + struct ion_handle **handle, int fd, + unsigned long *ionflag, size_t bufsz, + ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr) +{ + int rc = 0; + + if ((msm_audio_ion_data.smmu_enabled == true) && + !(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { + pr_debug("%s:probe is not done, deferred\n", __func__); + return -EPROBE_DEFER; + } + + if (!name || !client || !handle || !paddr || !vaddr || !pa_len) { + pr_err("%s: Invalid params\n", __func__); + rc = -EINVAL; + goto err; + } + + *client = msm_audio_ion_client_create(name); + if (IS_ERR_OR_NULL((void *)(*client))) { + pr_err("%s: ION create client for AUDIO failed\n", __func__); + rc = -EINVAL; + goto err; + } + + /* name should be audio_acdb_client or Audio_Dec_Client, + * bufsz should be 0 and fd shouldn't be 0 as of now + */ + *handle = ion_import_dma_buf_fd(*client, fd); + pr_debug("%s: DMA Buf name=%s, fd=%d handle=%pK\n", __func__, + name, fd, *handle); + if (IS_ERR_OR_NULL((void *) (*handle))) { + pr_err("%s: ion import dma buffer failed\n", + __func__); + rc = -EINVAL; + goto err_destroy_client; + } + + if (ionflag != NULL) { + rc = ion_handle_get_flags(*client, *handle, ionflag); + if (rc) { + pr_err("%s: could not get flags for the handle\n", + __func__); + goto err_ion_handle; + } + } + + rc = msm_audio_ion_get_phys(*client, *handle, paddr, pa_len); + if (rc) { + pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", + __func__, rc); + goto err_ion_handle; + } + + *vaddr = ion_map_kernel(*client, *handle); + if (IS_ERR_OR_NULL((void *)*vaddr)) { + pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); + rc = -ENOMEM; + goto err_ion_handle; + } + pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, + *vaddr, bufsz); + + return 0; + +err_ion_handle: + ion_free(*client, *handle); +err_destroy_client: + msm_audio_ion_client_destroy(*client); + *client = NULL; + *handle = NULL; +err: + return rc; +} + +int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle) +{ + if (!client || !handle) { + pr_err("%s Invalid params\n", __func__); + return -EINVAL; + } + if (msm_audio_ion_data.smmu_enabled) + msm_audio_dma_buf_unmap(client, handle); + + ion_unmap_kernel(client, handle); + + ion_free(client, handle); + msm_audio_ion_client_destroy(client); + return 0; +} +EXPORT_SYMBOL(msm_audio_ion_free); + +int msm_audio_ion_mmap(struct audio_buffer *ab, + struct vm_area_struct *vma) +{ + struct sg_table *table; + unsigned long addr = vma->vm_start; + unsigned long offset = vma->vm_pgoff * PAGE_SIZE; + struct scatterlist *sg; + unsigned int i; + struct page *page; + int ret; + + pr_debug("%s\n", __func__); + + table = ion_sg_table(ab->client, ab->handle); + + if (IS_ERR(table)) { + pr_err("%s: Unable to get sg_table from ion: %ld\n", + __func__, PTR_ERR(table)); + return PTR_ERR(table); + } else if (!table) { + pr_err("%s: sg_list is NULL\n", __func__); + return -EINVAL; + } + + /* uncached */ + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + + /* We need to check if a page is associated with this sg list because: + * If the allocation came from a carveout we currently don't have + * pages associated with carved out memory. This might change in the + * future and we can remove this check and the else statement. + */ + page = sg_page(table->sgl); + if (page) { + pr_debug("%s: page is NOT null\n", __func__); + for_each_sg(table->sgl, sg, table->nents, i) { + unsigned long remainder = vma->vm_end - addr; + unsigned long len = sg->length; + + page = sg_page(sg); + + if (offset >= len) { + offset -= len; + continue; + } else if (offset) { + page += offset / PAGE_SIZE; + len -= offset; + offset = 0; + } + len = min(len, remainder); + pr_debug("vma=%pK, addr=%x len=%ld vm_start=%x vm_end=%x vm_page_prot=%lu\n", + vma, (unsigned int)addr, len, + (unsigned int)vma->vm_start, + (unsigned int)vma->vm_end, + (unsigned long)vma->vm_page_prot.pgprot); + remap_pfn_range(vma, addr, page_to_pfn(page), len, + vma->vm_page_prot); + addr += len; + if (addr >= vma->vm_end) + return 0; + } + } else { + ion_phys_addr_t phys_addr; + size_t phys_len; + size_t va_len = 0; + + pr_debug("%s: page is NULL\n", __func__); + ret = ion_phys(ab->client, ab->handle, &phys_addr, &phys_len); + if (ret) { + pr_err("%s: Unable to get phys address from ION buffer: %d\n" + , __func__, ret); + return ret; + } + pr_debug("phys=%pKK len=%zd\n", &phys_addr, phys_len); + pr_debug("vma=%pK, vm_start=%x vm_end=%x vm_pgoff=%ld vm_page_prot=%lu\n", + vma, (unsigned int)vma->vm_start, + (unsigned int)vma->vm_end, vma->vm_pgoff, + (unsigned long)vma->vm_page_prot.pgprot); + va_len = vma->vm_end - vma->vm_start; + if ((offset > phys_len) || (va_len > phys_len-offset)) { + pr_err("wrong offset size %ld, lens= %zd, va_len=%zd\n", + offset, phys_len, va_len); + return -EINVAL; + } + ret = remap_pfn_range(vma, vma->vm_start, + __phys_to_pfn(phys_addr) + vma->vm_pgoff, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); + } + return 0; +} + + +bool msm_audio_ion_is_smmu_available(void) +{ + return msm_audio_ion_data.smmu_enabled; +} + +/* move to static section again */ +struct ion_client *msm_audio_ion_client_create(const char *name) +{ + struct ion_client *pclient = NULL; + + pclient = msm_ion_client_create(name); + return pclient; +} + + +void msm_audio_ion_client_destroy(struct ion_client *client) +{ + pr_debug("%s: client = %pK smmu_enabled = %d\n", __func__, + client, msm_audio_ion_data.smmu_enabled); + + ion_client_destroy(client); +} + +int msm_audio_ion_import_legacy(const char *name, struct ion_client *client, + struct ion_handle **handle, int fd, + unsigned long *ionflag, size_t bufsz, + ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr) +{ + int rc = 0; + + if (!name || !client || !handle || !paddr || !vaddr || !pa_len) { + pr_err("%s: Invalid params\n", __func__); + rc = -EINVAL; + goto err; + } + /* client is already created for legacy and given + * name should be audio_acdb_client or Audio_Dec_Client, + * bufsz should be 0 and fd shouldn't be 0 as of now + */ + *handle = ion_import_dma_buf_fd(client, fd); + pr_debug("%s: DMA Buf name=%s, fd=%d handle=%pK\n", __func__, + name, fd, *handle); + if (IS_ERR_OR_NULL((void *)(*handle))) { + pr_err("%s: ion import dma buffer failed\n", + __func__); + rc = -EINVAL; + goto err; + } + + if (ionflag != NULL) { + rc = ion_handle_get_flags(client, *handle, ionflag); + if (rc) { + pr_err("%s: could not get flags for the handle\n", + __func__); + rc = -EINVAL; + goto err_ion_handle; + } + } + + rc = msm_audio_ion_get_phys(client, *handle, paddr, pa_len); + if (rc) { + pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", + __func__, rc); + rc = -EINVAL; + goto err_ion_handle; + } + + /*Need to add condition SMMU enable or not */ + *vaddr = ion_map_kernel(client, *handle); + if (IS_ERR_OR_NULL((void *)*vaddr)) { + pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); + rc = -EINVAL; + goto err_ion_handle; + } + + if (bufsz != 0) + memset((void *)*vaddr, 0, bufsz); + + return 0; + +err_ion_handle: + ion_free(client, *handle); +err: + return rc; +} + +int msm_audio_ion_free_legacy(struct ion_client *client, + struct ion_handle *handle) +{ + if (msm_audio_ion_data.smmu_enabled) + msm_audio_dma_buf_unmap(client, handle); + + ion_unmap_kernel(client, handle); + + ion_free(client, handle); + /* no client_destrody in legacy*/ + return 0; +} + +int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op) +{ + unsigned long ionflag = 0; + int rc = 0; + int msm_cache_ops = 0; + + if (!abuff) { + pr_err("%s: Invalid params: %pK\n", __func__, abuff); + return -EINVAL; + } + rc = ion_handle_get_flags(abuff->client, abuff->handle, + &ionflag); + if (rc) { + pr_err("ion_handle_get_flags failed: %d\n", rc); + goto cache_op_failed; + } + + /* has to be CACHED */ + if (ION_IS_CACHED(ionflag)) { + /* ION_IOC_INV_CACHES or ION_IOC_CLEAN_CACHES */ + msm_cache_ops = cache_op; + rc = msm_ion_do_cache_op(abuff->client, + abuff->handle, + (unsigned long *) abuff->data, + (unsigned long)abuff->size, + msm_cache_ops); + if (rc) { + pr_err("cache operation failed %d\n", rc); + goto cache_op_failed; + } + } +cache_op_failed: + return rc; +} + + +static int msm_audio_dma_buf_map(struct ion_client *client, + struct ion_handle *handle, + ion_phys_addr_t *addr, size_t *len) +{ + + struct msm_audio_alloc_data *alloc_data; + struct device *cb_dev; + int rc = 0; + + cb_dev = msm_audio_ion_data.cb_dev; + + /* Data required per buffer mapping */ + alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL); + if (!alloc_data) + return -ENOMEM; + + /* Get the ION handle size */ + ion_handle_get_size(client, handle, len); + + alloc_data->client = client; + alloc_data->handle = handle; + alloc_data->len = *len; + + /* Get the dma_buf handle from ion_handle */ + alloc_data->dma_buf = ion_share_dma_buf(client, handle); + if (IS_ERR(alloc_data->dma_buf)) { + rc = PTR_ERR(alloc_data->dma_buf); + dev_err(cb_dev, + "%s: Fail to get dma_buf handle, rc = %d\n", + __func__, rc); + goto err_dma_buf; + } + + /* Attach the dma_buf to context bank device */ + alloc_data->attach = dma_buf_attach(alloc_data->dma_buf, + cb_dev); + if (IS_ERR(alloc_data->attach)) { + rc = PTR_ERR(alloc_data->attach); + dev_err(cb_dev, + "%s: Fail to attach dma_buf to CB, rc = %d\n", + __func__, rc); + goto err_attach; + } + + /* + * Get the scatter-gather list. + * There is no info as this is a write buffer or + * read buffer, hence the request is bi-directional + * to accommodate both read and write mappings. + */ + alloc_data->table = dma_buf_map_attachment(alloc_data->attach, + DMA_BIDIRECTIONAL); + if (IS_ERR(alloc_data->table)) { + rc = PTR_ERR(alloc_data->table); + dev_err(cb_dev, + "%s: Fail to map attachment, rc = %d\n", + __func__, rc); + goto err_map_attach; + } + + rc = dma_map_sg(cb_dev, alloc_data->table->sgl, + alloc_data->table->nents, + DMA_BIDIRECTIONAL); + if (rc != alloc_data->table->nents) { + dev_err(cb_dev, + "%s: Fail to map SG, rc = %d, nents = %d\n", + __func__, rc, alloc_data->table->nents); + goto err_map_sg; + } + /* Make sure not to return rc from dma_map_sg, as it can be nonzero */ + rc = 0; + + /* physical address from mapping */ + *addr = MSM_AUDIO_ION_PHYS_ADDR(alloc_data); + + msm_audio_ion_add_allocation(&msm_audio_ion_data, + alloc_data); + return rc; + +err_map_sg: + dma_buf_unmap_attachment(alloc_data->attach, + alloc_data->table, + DMA_BIDIRECTIONAL); +err_map_attach: + dma_buf_detach(alloc_data->dma_buf, + alloc_data->attach); +err_attach: + dma_buf_put(alloc_data->dma_buf); + +err_dma_buf: + kfree(alloc_data); + + return rc; +} + +static int msm_audio_dma_buf_unmap(struct ion_client *client, + struct ion_handle *handle) +{ + int rc = 0; + struct msm_audio_alloc_data *alloc_data = NULL; + struct list_head *ptr, *next; + struct device *cb_dev = msm_audio_ion_data.cb_dev; + bool found = false; + + /* + * Though list_for_each_safe is delete safe, lock + * should be explicitly acquired to avoid race condition + * on adding elements to the list. + */ + mutex_lock(&(msm_audio_ion_data.list_mutex)); + list_for_each_safe(ptr, next, + &(msm_audio_ion_data.alloc_list)) { + + alloc_data = list_entry(ptr, struct msm_audio_alloc_data, + list); + + if (alloc_data->handle == handle && + alloc_data->client == client) { + found = true; + dma_unmap_sg(cb_dev, + alloc_data->table->sgl, + alloc_data->table->nents, + DMA_BIDIRECTIONAL); + + dma_buf_unmap_attachment(alloc_data->attach, + alloc_data->table, + DMA_BIDIRECTIONAL); + + dma_buf_detach(alloc_data->dma_buf, + alloc_data->attach); + + dma_buf_put(alloc_data->dma_buf); + + list_del(&(alloc_data->list)); + kfree(alloc_data); + break; + } + } + mutex_unlock(&(msm_audio_ion_data.list_mutex)); + + if (!found) { + dev_err(cb_dev, + "%s: cannot find allocation, ion_handle %pK, ion_client %pK", + __func__, handle, client); + rc = -EINVAL; + } + + return rc; +} + +static int msm_audio_ion_get_phys(struct ion_client *client, + struct ion_handle *handle, + ion_phys_addr_t *addr, size_t *len) +{ + int rc = 0; + + pr_debug("%s: smmu_enabled = %d\n", __func__, + msm_audio_ion_data.smmu_enabled); + + if (msm_audio_ion_data.smmu_enabled) { + rc = msm_audio_dma_buf_map(client, handle, addr, len); + if (rc) { + pr_err("%s: failed to map DMA buf, err = %d\n", + __func__, rc); + goto err; + } + /* Append the SMMU SID information to the IOVA address */ + *addr |= msm_audio_ion_data.smmu_sid_bits; + } else { + rc = ion_phys(client, handle, addr, len); + } + + pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc); +err: + return rc; +} + +static int msm_audio_smmu_init(struct device *dev) +{ + struct dma_iommu_mapping *mapping; + int ret; + + mapping = arm_iommu_create_mapping(&platform_bus_type, + MSM_AUDIO_ION_VA_START, + MSM_AUDIO_ION_VA_LEN); + if (IS_ERR(mapping)) + return PTR_ERR(mapping); + + ret = arm_iommu_attach_device(dev, mapping); + if (ret) { + dev_err(dev, "%s: Attach failed, err = %d\n", + __func__, ret); + goto fail_attach; + } + + msm_audio_ion_data.cb_dev = dev; + msm_audio_ion_data.mapping = mapping; + INIT_LIST_HEAD(&msm_audio_ion_data.alloc_list); + mutex_init(&(msm_audio_ion_data.list_mutex)); + + return 0; + +fail_attach: + arm_iommu_release_mapping(mapping); + return ret; +} + +static const struct of_device_id msm_audio_ion_dt_match[] = { + { .compatible = "qcom,msm-audio-ion" }, + { } +}; +MODULE_DEVICE_TABLE(of, msm_audio_ion_dt_match); + + +u32 msm_audio_ion_get_smmu_sid_mode32(void) +{ + if (msm_audio_ion_data.smmu_enabled) + return upper_32_bits(msm_audio_ion_data.smmu_sid_bits); + else + return 0; +} + +u32 msm_audio_populate_upper_32_bits(ion_phys_addr_t pa) +{ + if (sizeof(ion_phys_addr_t) == sizeof(u32)) + return msm_audio_ion_get_smmu_sid_mode32(); + else + return upper_32_bits(pa); +} + +static int msm_audio_ion_probe(struct platform_device *pdev) +{ + int rc = 0; + const char *msm_audio_ion_dt = "qcom,smmu-enabled"; + const char *msm_audio_ion_smmu = "qcom,smmu-version"; + const char *msm_audio_ion_smmu_sid_mask = "qcom,smmu-sid-mask"; + bool smmu_enabled; + enum apr_subsys_state q6_state; + struct device *dev = &pdev->dev; + + if (dev->of_node == NULL) { + dev_err(dev, + "%s: device tree is not found\n", + __func__); + msm_audio_ion_data.smmu_enabled = 0; + return 0; + } + + smmu_enabled = of_property_read_bool(dev->of_node, + msm_audio_ion_dt); + msm_audio_ion_data.smmu_enabled = smmu_enabled; + + if (smmu_enabled) { + rc = of_property_read_u32(dev->of_node, + msm_audio_ion_smmu, + &msm_audio_ion_data.smmu_version); + if (rc) { + dev_err(dev, + "%s: qcom,smmu_version missing in DT node\n", + __func__); + return rc; + } + dev_dbg(dev, "%s: SMMU version is (%d)", __func__, + msm_audio_ion_data.smmu_version); + q6_state = apr_get_q6_state(); + if (q6_state == APR_SUBSYS_DOWN) { + dev_dbg(dev, + "defering %s, adsp_state %d\n", + __func__, q6_state); + return -EPROBE_DEFER; + } + dev_dbg(dev, "%s: adsp is ready\n", __func__); + } + + dev_dbg(dev, "%s: SMMU is %s\n", __func__, + (smmu_enabled) ? "Enabled" : "Disabled"); + + if (smmu_enabled) { + u64 smmu_sid = 0; + u64 smmu_sid_mask = 0; + struct of_phandle_args iommuspec; + + /* Get SMMU SID information from Devicetree */ + rc = of_property_read_u64(dev->of_node, + msm_audio_ion_smmu_sid_mask, + &smmu_sid_mask); + if (rc) { + dev_err(dev, + "%s: qcom,smmu-sid-mask missing in DT node, using default\n", + __func__); + smmu_sid_mask = 0xFFFFFFFFFFFFFFFF; + } + rc = of_parse_phandle_with_args(dev->of_node, "iommus", + "#iommu-cells", 0, &iommuspec); + if (rc) + dev_err(dev, "%s: could not get smmu SID, ret = %d\n", + __func__, rc); + else + smmu_sid = (iommuspec.args[0] & smmu_sid_mask); + + msm_audio_ion_data.smmu_sid_bits = + smmu_sid << MSM_AUDIO_SMMU_SID_OFFSET; + + if (msm_audio_ion_data.smmu_version == 0x2) { + rc = msm_audio_smmu_init(dev); + } else { + dev_err(dev, "%s: smmu version invalid %d\n", + __func__, msm_audio_ion_data.smmu_version); + rc = -EINVAL; + } + if (rc) + dev_err(dev, "%s: smmu init failed, err = %d\n", + __func__, rc); + } + + if (!rc) + msm_audio_ion_data.device_status |= MSM_AUDIO_ION_PROBED; + + return rc; +} + +static int msm_audio_ion_remove(struct platform_device *pdev) +{ + struct dma_iommu_mapping *mapping; + struct device *audio_cb_dev; + + mapping = msm_audio_ion_data.mapping; + audio_cb_dev = msm_audio_ion_data.cb_dev; + + if (audio_cb_dev && mapping) { + arm_iommu_detach_device(audio_cb_dev); + arm_iommu_release_mapping(mapping); + } + + msm_audio_ion_data.smmu_enabled = 0; + msm_audio_ion_data.device_status = 0; + return 0; +} + +static struct platform_driver msm_audio_ion_driver = { + .driver = { + .name = "msm-audio-ion", + .owner = THIS_MODULE, + .of_match_table = msm_audio_ion_dt_match, + }, + .probe = msm_audio_ion_probe, + .remove = msm_audio_ion_remove, +}; + +static int __init msm_audio_ion_init(void) +{ + return platform_driver_register(&msm_audio_ion_driver); +} +module_init(msm_audio_ion_init); + +static void __exit msm_audio_ion_exit(void) +{ + platform_driver_unregister(&msm_audio_ion_driver); +} +module_exit(msm_audio_ion_exit); + +MODULE_DESCRIPTION("MSM Audio ION module"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/soundwire/Kconfig b/drivers/soundwire/Kconfig new file mode 100644 index 000000000000..e1ca532c22f5 --- /dev/null +++ b/drivers/soundwire/Kconfig @@ -0,0 +1,17 @@ +# +# SOUNDWIRE driver configuration +# +menuconfig SOUNDWIRE + bool "Soundwire support" + help + Soundwire is a two wire interface for audio to connect + simple peripheral components in mobile devices. + +if SOUNDWIRE +config SOUNDWIRE_WCD_CTRL + depends on WCD9XXX_CODEC_CORE + tristate "QTI WCD CODEC Soundwire controller" + default n + help + Select driver for QTI's Soundwire Master Component. +endif diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile new file mode 100644 index 000000000000..53acff15c4c4 --- /dev/null +++ b/drivers/soundwire/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for kernel soundwire framework. +# +obj-$(CONFIG_SOUNDWIRE) += soundwire.o +obj-$(CONFIG_SOUNDWIRE_WCD_CTRL) += swr-wcd-ctrl.o diff --git a/drivers/soundwire/soundwire.c b/drivers/soundwire/soundwire.c new file mode 100644 index 000000000000..f0c7aa9ac01f --- /dev/null +++ b/drivers/soundwire/soundwire.c @@ -0,0 +1,1032 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct boardinfo { + struct list_head list; + struct swr_boardinfo board_info; +}; + +static LIST_HEAD(board_list); +static LIST_HEAD(swr_master_list); +static DEFINE_MUTEX(board_lock); +static DEFINE_IDR(master_idr); +static DEFINE_MUTEX(swr_lock); + +static struct device_type swr_dev_type; + +#define SOUNDWIRE_NAME_SIZE 32 + +static void swr_master_put(struct swr_master *master) +{ + if (master) + put_device(&master->dev); +} + +static struct swr_master *swr_master_get(struct swr_master *master) +{ + if (!master || !get_device(&master->dev)) + return NULL; + return master; +} + +static void swr_dev_release(struct device *dev) +{ + struct swr_device *swr_dev = to_swr_device(dev); + struct swr_master *master; + + if (!swr_dev) + return; + master = swr_dev->master; + if (!master) + return; + mutex_lock(&master->mlock); + list_del_init(&swr_dev->dev_list); + mutex_unlock(&master->mlock); + swr_master_put(swr_dev->master); + kfree(swr_dev); +} + +/** + * swr_remove_device - remove a soundwire device + * @swr_dev: soundwire device to remove + * + * Remove a soundwire device. Go through the soundwire + * device list that master has and remove swr_dev from + * it. + */ +void swr_remove_device(struct swr_device *swr_dev) +{ + struct swr_device *swr_dev_loop, *safe; + + list_for_each_entry_safe(swr_dev_loop, safe, + &swr_dev->master->devices, + dev_list) { + if (swr_dev == swr_dev_loop) + list_del(&swr_dev_loop->dev_list); + } +} +EXPORT_SYMBOL(swr_remove_device); + +/** + * swr_new_device - instantiate a new soundwire device + * @master: Controller to which device is connected + * @info: Describes the soundwire device + * Context: can sleep + * + * Create a soundwire device. Binding is handled through driver model + * probe/remove methods. A driver may be bound to this device when + * the function gets returned. + * + * Returns a soundwire new device or NULL + */ +struct swr_device *swr_new_device(struct swr_master *master, + struct swr_boardinfo const *info) +{ + int result; + struct swr_device *swr; + + if (!master || !swr_master_get(master)) { + pr_err("%s: master is NULL\n", __func__); + return NULL; + } + + swr = kzalloc(sizeof(*swr), GFP_KERNEL); + if (!swr) { + put_device(&master->dev); + return NULL; + } + swr->master = master; + swr->addr = info->addr; + strlcpy(swr->name, info->name, sizeof(swr->name)); + swr->dev.type = &swr_dev_type; + swr->dev.parent = &master->dev; + swr->dev.bus = &soundwire_type; + swr->dev.release = swr_dev_release; + swr->dev.of_node = info->of_node; + mutex_lock(&master->mlock); + list_add_tail(&swr->dev_list, &master->devices); + mutex_unlock(&master->mlock); + + dev_set_name(&swr->dev, "%s.%lx", swr->name, swr->addr); + result = device_register(&swr->dev); + if (result) { + dev_err(&master->dev, "device [%s] register failed err %d\n", + swr->name, result); + goto err_out; + } + dev_dbg(&master->dev, "Device [%s] registered with bus id %s\n", + swr->name, dev_name(&swr->dev)); + return swr; + +err_out: + dev_dbg(&master->dev, "Failed to register swr device %s at 0x%lx %d\n", + swr->name, swr->addr, result); + swr_master_put(master); + kfree(swr); + return NULL; +} +EXPORT_SYMBOL(swr_new_device); + +/** + * of_register_swr_devices - register child devices on to the soundwire bus + * @master: pointer to soundwire master device + * + * Registers a soundwire device for each child node of master node which has + * a "swr-devid" property + * + */ +int of_register_swr_devices(struct swr_master *master) +{ + struct swr_device *swr; + struct device_node *node; + + if (!master->dev.of_node) + return -EINVAL; + + for_each_available_child_of_node(master->dev.of_node, node) { + struct swr_boardinfo info = {}; + u64 addr; + + dev_dbg(&master->dev, "of_swr:register %s\n", node->full_name); + + if (of_modalias_node(node, info.name, sizeof(info.name)) < 0) { + dev_err(&master->dev, "of_swr:modalias failure %s\n", + node->full_name); + continue; + } + if (of_property_read_u64(node, "reg", &addr)) { + dev_err(&master->dev, "of_swr:invalid reg %s\n", + node->full_name); + continue; + } + info.addr = addr; + info.of_node = of_node_get(node); + master->num_dev++; + swr = swr_new_device(master, &info); + if (!swr) { + dev_err(&master->dev, "of_swr: Register failed %s\n", + node->full_name); + of_node_put(node); + master->num_dev--; + continue; + } + } + return 0; +} +EXPORT_SYMBOL(of_register_swr_devices); + +/** + * swr_port_response - response from master to free the completed transaction + * @mstr: pointer to soundwire master device + * @tid: transaction id that indicates transaction to be freed. + * + * Master calls this function to free the compeleted transaction memory + */ +void swr_port_response(struct swr_master *mstr, u8 tid) +{ + struct swr_params *txn; + + txn = mstr->port_txn[tid]; + + if (txn == NULL) { + dev_err(&mstr->dev, "%s: transaction is already NULL\n", + __func__); + return; + } + mstr->port_txn[tid] = NULL; + kfree(txn); +} +EXPORT_SYMBOL(swr_port_response); + +/** + * swr_remove_from_group - remove soundwire slave devices from group + * @dev: pointer to the soundwire slave device + * dev_num: device number of the soundwire slave device + * + * Returns error code for failure and 0 for success + */ +int swr_remove_from_group(struct swr_device *dev, u8 dev_num) +{ + struct swr_master *master; + + if (!dev) + return -ENODEV; + + master = dev->master; + if (!master) + return -EINVAL; + + if (!dev->group_id) + return 0; + + if (master->gr_sid == dev_num) + return 0; + + if (master->remove_from_group && master->remove_from_group(master)) + dev_dbg(&master->dev, "%s: falling back to GROUP_NONE\n", + __func__); + + return 0; +} +EXPORT_SYMBOL(swr_remove_from_group); + +/** + * swr_slvdev_datapath_control - Enables/Disables soundwire slave device + * data path + * @dev: pointer to soundwire slave device + * @dev_num: device number of the soundwire slave device + * + * Returns error code for failure and 0 for success + */ +int swr_slvdev_datapath_control(struct swr_device *dev, u8 dev_num, + bool enable) +{ + struct swr_master *master; + + if (!dev) + return -ENODEV; + + master = dev->master; + if (!master) + return -EINVAL; + + if (dev->group_id) { + /* Broadcast */ + if (master->gr_sid != dev_num) { + if (!master->gr_sid) + master->gr_sid = dev_num; + else + return 0; + } + } + + if (master->slvdev_datapath_control) + master->slvdev_datapath_control(master, enable); + + return 0; +} +EXPORT_SYMBOL(swr_slvdev_datapath_control); + +/** + * swr_connect_port - enable soundwire slave port(s) + * @dev: pointer to soundwire slave device + * @port_id: logical port id(s) of soundwire slave device + * @num_port: number of slave device ports need to be enabled + * @ch_mask: channels for each port that needs to be enabled + * @ch_rate: rate at which each port/channels operate + * @num_ch: number of channels for each port + * + * soundwire slave device call swr_connect_port API to enable all/some of + * its ports and corresponding channels and channel rate. This API will + * call master connect_port callback function to calculate frame structure + * and enable master and slave ports + */ +int swr_connect_port(struct swr_device *dev, u8 *port_id, u8 num_port, + u8 *ch_mask, u32 *ch_rate, u8 *num_ch) +{ + u8 i = 0; + int ret = 0; + struct swr_params *txn = NULL; + struct swr_params **temp_txn = NULL; + struct swr_master *master = dev->master; + + if (!master) { + pr_err("%s: Master is NULL\n", __func__); + return -EINVAL; + } + if (num_port > SWR_MAX_DEV_PORT_NUM) { + dev_err(&master->dev, "%s: num_port %d exceeds max port %d\n", + __func__, num_port, SWR_MAX_DEV_PORT_NUM); + return -EINVAL; + } + + /* + * create "txn" to accommodate ports enablement of + * different slave devices calling swr_connect_port at the + * same time. Once master process the txn data, it calls + * swr_port_response() to free the transaction. Maximum + * of 256 transactions can be allocated. + */ + txn = kzalloc(sizeof(struct swr_params), GFP_KERNEL); + if (!txn) + return -ENOMEM; + + mutex_lock(&master->mlock); + for (i = 0; i < master->last_tid; i++) { + if (master->port_txn[i] == NULL) + break; + } + if (i >= master->last_tid) { + if (master->last_tid == 255) { + mutex_unlock(&master->mlock); + kfree(txn); + dev_err(&master->dev, "%s Max tid reached\n", + __func__); + return -ENOMEM; + } + temp_txn = krealloc(master->port_txn, + (i + 1) * sizeof(struct swr_params *), + GFP_KERNEL); + if (!temp_txn) { + mutex_unlock(&master->mlock); + kfree(txn); + dev_err(&master->dev, "%s Not able to allocate\n" + "master port transaction memory\n", + __func__); + return -ENOMEM; + } + master->port_txn = temp_txn; + master->last_tid++; + } + master->port_txn[i] = txn; + mutex_unlock(&master->mlock); + txn->tid = i; + + txn->dev_id = dev->dev_num; + txn->num_port = num_port; + for (i = 0; i < num_port; i++) { + txn->port_id[i] = port_id[i]; + txn->num_ch[i] = num_ch[i]; + txn->ch_rate[i] = ch_rate[i]; + txn->ch_en[i] = ch_mask[i]; + } + ret = master->connect_port(master, txn); + return ret; +} +EXPORT_SYMBOL(swr_connect_port); + +/** + * swr_disconnect_port - disable soundwire slave port(s) + * @dev: pointer to soundwire slave device + * @port_id: logical port id(s) of soundwire slave device + * @num_port: number of slave device ports need to be disabled + * + * soundwire slave device call swr_disconnect_port API to disable all/some of + * its ports. This API will call master disconnect_port callback function to + * disable master and slave port and (re)configure frame structure + */ +int swr_disconnect_port(struct swr_device *dev, u8 *port_id, u8 num_port) +{ + u8 i = 0; + int ret; + struct swr_params *txn = NULL; + struct swr_params **temp_txn = NULL; + struct swr_master *master = dev->master; + + if (!master) { + pr_err("%s: Master is NULL\n", __func__); + return -EINVAL; + } + + if (num_port > SWR_MAX_DEV_PORT_NUM) { + dev_err(&master->dev, "%s: num_port %d exceeds max port %d\n", + __func__, num_port, SWR_MAX_DEV_PORT_NUM); + return -EINVAL; + } + + txn = kzalloc(sizeof(struct swr_params), GFP_KERNEL); + if (!txn) + return -ENOMEM; + + mutex_lock(&master->mlock); + for (i = 0; i < master->last_tid; i++) { + if (master->port_txn[i] == NULL) + break; + } + if (i >= master->last_tid) { + if (master->last_tid == 255) { + mutex_unlock(&master->mlock); + kfree(txn); + dev_err(&master->dev, "%s Max tid reached\n", + __func__); + return -ENOMEM; + } + temp_txn = krealloc(master->port_txn, + (i + 1) * sizeof(struct swr_params *), + GFP_KERNEL); + if (!temp_txn) { + mutex_unlock(&master->mlock); + kfree(txn); + dev_err(&master->dev, "%s Not able to allocate\n" + "master port transaction memory\n", + __func__); + return -ENOMEM; + } + master->port_txn = temp_txn; + master->last_tid++; + } + master->port_txn[i] = txn; + mutex_unlock(&master->mlock); + txn->tid = i; + + txn->dev_id = dev->dev_num; + txn->num_port = num_port; + for (i = 0; i < num_port; i++) + txn->port_id[i] = port_id[i]; + ret = master->disconnect_port(master, txn); + return ret; +} +EXPORT_SYMBOL(swr_disconnect_port); + +/** + * swr_get_logical_dev_num - Get soundwire slave logical device number + * @dev: pointer to soundwire slave device + * @dev_id: physical device id of soundwire slave device + * @dev_num: pointer to logical device num of soundwire slave device + * + * This API will get the logical device number of soundwire slave device + */ +int swr_get_logical_dev_num(struct swr_device *dev, u64 dev_id, + u8 *dev_num) +{ + int ret = 0; + struct swr_master *master = dev->master; + + if (!master) { + pr_err("%s: Master is NULL\n", __func__); + return -EINVAL; + } + mutex_lock(&master->mlock); + ret = master->get_logical_dev_num(master, dev_id, dev_num); + if (ret) { + pr_err("%s: Error %d to get logical addr for device %llx\n", + __func__, ret, dev_id); + } + mutex_unlock(&master->mlock); + return ret; +} +EXPORT_SYMBOL(swr_get_logical_dev_num); + +/** + * swr_read - read soundwire slave device registers + * @dev: pointer to soundwire slave device + * @dev_num: logical device num of soundwire slave device + * @reg_addr: base register address that needs to be read + * @buf: pointer to store the values of registers from base address + * @len: length of the buffer + * + * This API will read the value of the register address from + * soundwire slave device + */ +int swr_read(struct swr_device *dev, u8 dev_num, u16 reg_addr, + void *buf, u32 len) +{ + struct swr_master *master = dev->master; + + if (!master) + return -EINVAL; + return master->read(master, dev_num, reg_addr, buf, len); +} +EXPORT_SYMBOL(swr_read); + +/** + * swr_bulk_write - write soundwire slave device registers + * @dev: pointer to soundwire slave device + * @dev_num: logical device num of soundwire slave device + * @reg_addr: register address of soundwire slave device + * @buf: contains value of register address + * @len: indicates number of registers + * + * This API will write the value of the register address to + * soundwire slave device + */ +int swr_bulk_write(struct swr_device *dev, u8 dev_num, void *reg, + const void *buf, size_t len) +{ + struct swr_master *master; + + if (!dev || !dev->master) + return -EINVAL; + + master = dev->master; + if (dev->group_id) { + if (master->gr_sid != dev_num) { + if (!master->gr_sid) + master->gr_sid = dev_num; + else + return 0; + } + dev_num = dev->group_id; + } + if (master->bulk_write) + return master->bulk_write(master, dev_num, reg, buf, len); + + return -EOPNOTSUPP; +} +EXPORT_SYMBOL(swr_bulk_write); + +/** + * swr_write - write soundwire slave device registers + * @dev: pointer to soundwire slave device + * @dev_num: logical device num of soundwire slave device + * @reg_addr: register address of soundwire slave device + * @buf: contains value of register address + * + * This API will write the value of the register address to + * soundwire slave device + */ +int swr_write(struct swr_device *dev, u8 dev_num, u16 reg_addr, + const void *buf) +{ + struct swr_master *master = dev->master; + + if (!master) + return -EINVAL; + + if (dev->group_id) { + if (master->gr_sid != dev_num) { + if (!master->gr_sid) + master->gr_sid = dev_num; + else + return 0; + } + dev_num = dev->group_id; + } + return master->write(master, dev_num, reg_addr, buf); +} +EXPORT_SYMBOL(swr_write); + +/** + * swr_device_up - Function to bringup the soundwire slave device + * @swr_dev: pointer to soundwire slave device + * Context: can sleep + * + * This API will be called by soundwire master to bringup the slave + * device. + */ +int swr_device_up(struct swr_device *swr_dev) +{ + struct device *dev; + const struct swr_driver *sdrv; + + if (!swr_dev) + return -EINVAL; + + dev = &swr_dev->dev; + sdrv = to_swr_driver(dev->driver); + if (!sdrv) + return 0; + + if (sdrv->device_up) + return sdrv->device_up(to_swr_device(dev)); + + return -ENODEV; +} +EXPORT_SYMBOL(swr_device_up); + +/** + * swr_device_down - Function to call soundwire slave device down + * @swr_dev: pointer to soundwire slave device + * Context: can sleep + * + * This API will be called by soundwire master to put slave device in + * shutdown state. + */ +int swr_device_down(struct swr_device *swr_dev) +{ + struct device *dev; + const struct swr_driver *sdrv; + + if (!swr_dev) + return -EINVAL; + + dev = &swr_dev->dev; + sdrv = to_swr_driver(dev->driver); + if (!sdrv) + return 0; + + if (sdrv->device_down) + return sdrv->device_down(to_swr_device(dev)); + + return -ENODEV; +} +EXPORT_SYMBOL(swr_device_down); + +/** + * swr_reset_device - reset soundwire slave device + * @swr_dev: pointer to soundwire slave device + * Context: can sleep + * + * This API will be called by soundwire master to reset the slave + * device when the slave device is not responding or in undefined + * state + */ +int swr_reset_device(struct swr_device *swr_dev) +{ + struct device *dev; + const struct swr_driver *sdrv; + + if (!swr_dev) + return -EINVAL; + + dev = &swr_dev->dev; + sdrv = to_swr_driver(dev->driver); + if (!sdrv) + return -EINVAL; + + if (sdrv->reset_device) + return sdrv->reset_device(to_swr_device(dev)); + + return -ENODEV; +} +EXPORT_SYMBOL(swr_reset_device); + +/** + * swr_set_device_group - Assign group id to the slave devices + * @swr_dev: pointer to soundwire slave device + * @id: group id to be assigned to slave device + * Context: can sleep + * + * This API will be called either from soundwire master or slave + * device to assign group id. + */ +int swr_set_device_group(struct swr_device *swr_dev, u8 id) +{ + struct swr_master *master; + + if (!swr_dev) + return -EINVAL; + + swr_dev->group_id = id; + master = swr_dev->master; + if (!id && master) + master->gr_sid = 0; + + return 0; +} +EXPORT_SYMBOL(swr_set_device_group); + +static int swr_drv_probe(struct device *dev) +{ + const struct swr_driver *sdrv = to_swr_driver(dev->driver); + + if (!sdrv) + return -EINVAL; + + if (sdrv->probe) + return sdrv->probe(to_swr_device(dev)); + return -ENODEV; +} + +static int swr_drv_remove(struct device *dev) +{ + const struct swr_driver *sdrv = to_swr_driver(dev->driver); + + if (!sdrv) + return -EINVAL; + + if (sdrv->remove) + return sdrv->remove(to_swr_device(dev)); + return -ENODEV; +} + +static void swr_drv_shutdown(struct device *dev) +{ + const struct swr_driver *sdrv = to_swr_driver(dev->driver); + + if (!sdrv) + return; + + if (sdrv->shutdown) + sdrv->shutdown(to_swr_device(dev)); +} + +/** + * swr_driver_register - register a soundwire driver + * @drv: the driver to register + * Context: can sleep + */ +int swr_driver_register(struct swr_driver *drv) +{ + drv->driver.bus = &soundwire_type; + if (drv->probe) + drv->driver.probe = swr_drv_probe; + if (drv->remove) + drv->driver.remove = swr_drv_remove; + + if (drv->shutdown) + drv->driver.shutdown = swr_drv_shutdown; + + return driver_register(&drv->driver); +} +EXPORT_SYMBOL(swr_driver_register); + +/** + * swr_driver_unregister - unregister a soundwire driver + * @drv: the driver to unregister + */ +void swr_driver_unregister(struct swr_driver *drv) +{ + if (drv) + driver_unregister(&drv->driver); +} +EXPORT_SYMBOL(swr_driver_unregister); + +static void swr_match_ctrl_to_boardinfo(struct swr_master *master, + struct swr_boardinfo *bi) +{ + struct swr_device *swr; + + if (master->bus_num != bi->bus_num) { + dev_dbg(&master->dev, + "%s: master# %d and bi# %d does not match\n", + __func__, master->bus_num, bi->bus_num); + return; + } + + swr = swr_new_device(master, bi); + if (!swr) + dev_err(&master->dev, "can't create new device for %s\n", + bi->swr_slave->name); +} + +/** + * swr_master_add_boarddevices - Add devices registered by board info + * @master: master to which these devices are to be added to. + * + * This API is called by master when it is up and running. If devices + * on a master were registered before master, this will make sure that + * they get probed when master is up. + */ +void swr_master_add_boarddevices(struct swr_master *master) +{ + struct boardinfo *bi; + + mutex_lock(&board_lock); + list_add_tail(&master->list, &swr_master_list); + list_for_each_entry(bi, &board_list, list) + swr_match_ctrl_to_boardinfo(master, &bi->board_info); + mutex_unlock(&board_lock); +} +EXPORT_SYMBOL(swr_master_add_boarddevices); + +static void swr_unregister_device(struct swr_device *swr) +{ + if (swr) + device_unregister(&swr->dev); +} + +static void swr_master_release(struct device *dev) +{ + struct swr_master *master = to_swr_master(dev); + + kfree(master); +} + +#define swr_master_attr_gr NULL +static struct device_type swr_master_type = { + .groups = swr_master_attr_gr, + .release = swr_master_release, +}; + +static int __unregister(struct device *dev, void *null) +{ + swr_unregister_device(to_swr_device(dev)); + return 0; +} + +/** + * swr_unregister_master - unregister soundwire master controller + * @master: the master being unregistered + * + * This API is called by master controller driver to unregister + * master controller that was registered by swr_register_master API. + */ +void swr_unregister_master(struct swr_master *master) +{ + int dummy; + struct swr_master *m_ctrl; + + mutex_lock(&swr_lock); + m_ctrl = idr_find(&master_idr, master->bus_num); + mutex_unlock(&swr_lock); + if (m_ctrl != master) + return; + + mutex_lock(&board_lock); + list_del(&master->list); + mutex_unlock(&board_lock); + + /* free bus id */ + mutex_lock(&swr_lock); + idr_remove(&master_idr, master->bus_num); + mutex_unlock(&swr_lock); + + dummy = device_for_each_child(&master->dev, NULL, __unregister); + device_unregister(&master->dev); +} +EXPORT_SYMBOL(swr_unregister_master); + +/** + * swr_register_master - register soundwire master controller + * @master: master to be registered + * + * This API will register master with the framework. master->bus_num + * is the desired number with which soundwire framework registers the + * master. + */ +int swr_register_master(struct swr_master *master) +{ + int id; + int status = 0; + + mutex_lock(&swr_lock); + id = idr_alloc(&master_idr, master, master->bus_num, + master->bus_num+1, GFP_KERNEL); + mutex_unlock(&swr_lock); + if (id < 0) + return id; + master->bus_num = id; + + /* Can't register until driver model init */ + if (WARN_ON(!soundwire_type.p)) { + status = -EAGAIN; + goto done; + } + + dev_set_name(&master->dev, "swr%u", master->bus_num); + master->dev.bus = &soundwire_type; + master->dev.type = &swr_master_type; + mutex_init(&master->mlock); + status = device_register(&master->dev); + if (status < 0) + goto done; + + INIT_LIST_HEAD(&master->devices); + pr_debug("%s: SWR master registered successfully %s\n", + __func__, dev_name(&master->dev)); + return 0; + +done: + idr_remove(&master_idr, master->bus_num); + return status; +} +EXPORT_SYMBOL(swr_register_master); + +#define swr_device_attr_gr NULL +#define swr_device_uevent NULL +static struct device_type swr_dev_type = { + .groups = swr_device_attr_gr, + .uevent = swr_device_uevent, + .release = swr_dev_release, +}; + +static const struct swr_device_id *swr_match(const struct swr_device_id *id, + const struct swr_device *swr_dev) +{ + while (id->name[0]) { + if (strcmp(swr_dev->name, id->name) == 0) + return id; + id++; + } + return NULL; +} + +static int swr_device_match(struct device *dev, struct device_driver *driver) +{ + struct swr_device *swr_dev; + struct swr_driver *drv = to_swr_driver(driver); + + if (!drv) + return -EINVAL; + + if (dev->type == &swr_dev_type) + swr_dev = to_swr_device(dev); + else + return 0; + if (drv->id_table) + return swr_match(drv->id_table, swr_dev) != NULL; + + if (driver->name) + return strcmp(swr_dev->name, driver->name) == 0; + return 0; +} +#ifdef CONFIG_PM_SLEEP +static int swr_legacy_suspend(struct device *dev, pm_message_t mesg) +{ + struct swr_device *swr_dev = NULL; + struct swr_driver *driver; + + if (dev->type == &swr_dev_type) + swr_dev = to_swr_device(dev); + + if (!swr_dev || !dev->driver) + return 0; + + driver = to_swr_driver(dev->driver); + if (!driver->suspend) + return 0; + + return driver->suspend(swr_dev, mesg); +} + +static int swr_legacy_resume(struct device *dev) +{ + struct swr_device *swr_dev = NULL; + struct swr_driver *driver; + + if (dev->type == &swr_dev_type) + swr_dev = to_swr_device(dev); + + if (!swr_dev || !dev->driver) + return 0; + + driver = to_swr_driver(dev->driver); + if (!driver->resume) + return 0; + + return driver->resume(swr_dev); +} + +static int swr_pm_suspend(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + if (pm) + return pm_generic_suspend(dev); + else + return swr_legacy_suspend(dev, PMSG_SUSPEND); +} + +static int swr_pm_resume(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + if (pm) + return pm_generic_resume(dev); + else + return swr_legacy_resume(dev); +} +#else +#define swr_pm_suspend NULL +#define swr_pm_resume NULL +#endif /*CONFIG_PM_SLEEP*/ + +static const struct dev_pm_ops soundwire_pm = { + .suspend = swr_pm_suspend, + .resume = swr_pm_resume, + SET_RUNTIME_PM_OPS( + pm_generic_suspend, + pm_generic_resume, + NULL + ) +}; + +struct device soundwire_dev = { + .init_name = "soundwire", +}; + +struct bus_type soundwire_type = { + .name = "soundwire", + .match = swr_device_match, + .pm = &soundwire_pm, +}; +EXPORT_SYMBOL(soundwire_type); + +static void __exit soundwire_exit(void) +{ + device_unregister(&soundwire_dev); + bus_unregister(&soundwire_type); +} + +static int __init soundwire_init(void) +{ + int retval; + + retval = bus_register(&soundwire_type); + if (!retval) + retval = device_register(&soundwire_dev); + + if (retval) + bus_unregister(&soundwire_type); + + return retval; +} +postcore_initcall(soundwire_init); +module_exit(soundwire_exit); + + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Soundwire module"); +MODULE_ALIAS("platform:soundwire"); diff --git a/drivers/soundwire/swr-wcd-ctrl.c b/drivers/soundwire/swr-wcd-ctrl.c new file mode 100644 index 000000000000..e338d582fa95 --- /dev/null +++ b/drivers/soundwire/swr-wcd-ctrl.c @@ -0,0 +1,1880 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "swrm_registers.h" +#include "swr-wcd-ctrl.h" + +#define SWR_BROADCAST_CMD_ID 0x0F +#define SWR_AUTO_SUSPEND_DELAY 3 /* delay in sec */ +#define SWR_DEV_ID_MASK 0xFFFFFFFF +#define SWR_REG_VAL_PACK(data, dev, id, reg) \ + ((reg) | ((id) << 16) | ((dev) << 20) | ((data) << 24)) + +/* pm runtime auto suspend timer in msecs */ +static int auto_suspend_timer = SWR_AUTO_SUSPEND_DELAY * 1000; +module_param(auto_suspend_timer, int, 0664); +MODULE_PARM_DESC(auto_suspend_timer, "timer for auto suspend"); + +static u8 mstr_ports[] = {100, 101, 102, 103, 104, 105, 106, 107}; +static u8 mstr_port_type[] = {SWR_DAC_PORT, SWR_COMP_PORT, SWR_BOOST_PORT, + SWR_DAC_PORT, SWR_COMP_PORT, SWR_BOOST_PORT, + SWR_VISENSE_PORT, SWR_VISENSE_PORT}; + +struct usecase uc[] = { + {0, 0, 0}, /* UC0: no ports */ + {1, 1, 2400}, /* UC1: Spkr */ + {1, 4, 600}, /* UC2: Compander */ + {1, 2, 300}, /* UC3: Smart Boost */ + {1, 2, 1200}, /* UC4: VI Sense */ + {4, 9, 4500}, /* UC5: Spkr + Comp + SB + VI */ + {8, 18, 9000}, /* UC6: 2*(Spkr + Comp + SB + VI) */ + {2, 2, 4800}, /* UC7: 2*Spkr */ + {2, 5, 3000}, /* UC8: Spkr + Comp */ + {4, 10, 6000}, /* UC9: 2*(Spkr + Comp) */ + {3, 7, 3300}, /* UC10: Spkr + Comp + SB */ + {6, 14, 6600}, /* UC11: 2*(Spkr + Comp + SB) */ + {2, 3, 2700}, /* UC12: Spkr + SB */ + {4, 6, 5400}, /* UC13: 2*(Spkr + SB) */ + {3, 5, 3900}, /* UC14: Spkr + SB + VI */ + {6, 10, 7800}, /* UC15: 2*(Spkr + SB + VI) */ + {2, 3, 3600}, /* UC16: Spkr + VI */ + {4, 6, 7200}, /* UC17: 2*(Spkr + VI) */ + {3, 7, 4200}, /* UC18: Spkr + Comp + VI */ + {6, 14, 8400}, /* UC19: 2*(Spkr + Comp + VI) */ +}; +#define MAX_USECASE ARRAY_SIZE(uc) + +struct port_params pp[MAX_USECASE][SWR_MSTR_PORT_LEN] = { + /* UC 0 */ + { + {0, 0, 0}, + }, + /* UC 1 */ + { + {7, 1, 0}, + }, + /* UC 2 */ + { + {31, 2, 0}, + }, + /* UC 3 */ + { + {63, 12, 31}, + }, + /* UC 4 */ + { + {15, 7, 0}, + }, + /* UC 5 */ + { + {7, 1, 0}, + {31, 2, 0}, + {63, 12, 31}, + {15, 7, 0}, + }, + /* UC 6 */ + { + {7, 1, 0}, + {31, 2, 0}, + {63, 12, 31}, + {15, 7, 0}, + {7, 6, 0}, + {31, 18, 0}, + {63, 13, 31}, + {15, 10, 0}, + }, + /* UC 7 */ + { + {7, 1, 0}, + {7, 6, 0}, + + }, + /* UC 8 */ + { + {7, 1, 0}, + {31, 2, 0}, + }, + /* UC 9 */ + { + {7, 1, 0}, + {31, 2, 0}, + {7, 6, 0}, + {31, 18, 0}, + }, + /* UC 10 */ + { + {7, 1, 0}, + {31, 2, 0}, + {63, 12, 31}, + }, + /* UC 11 */ + { + {7, 1, 0}, + {31, 2, 0}, + {63, 12, 31}, + {7, 6, 0}, + {31, 18, 0}, + {63, 13, 31}, + }, + /* UC 12 */ + { + {7, 1, 0}, + {63, 12, 31}, + }, + /* UC 13 */ + { + {7, 1, 0}, + {63, 12, 31}, + {7, 6, 0}, + {63, 13, 31}, + }, + /* UC 14 */ + { + {7, 1, 0}, + {63, 12, 31}, + {15, 7, 0}, + }, + /* UC 15 */ + { + {7, 1, 0}, + {63, 12, 31}, + {15, 7, 0}, + {7, 6, 0}, + {63, 13, 31}, + {15, 10, 0}, + }, + /* UC 16 */ + { + {7, 1, 0}, + {15, 7, 0}, + }, + /* UC 17 */ + { + {7, 1, 0}, + {15, 7, 0}, + {7, 6, 0}, + {15, 10, 0}, + }, + /* UC 18 */ + { + {7, 1, 0}, + {31, 2, 0}, + {15, 7, 0}, + }, + /* UC 19 */ + { + {7, 1, 0}, + {31, 2, 0}, + {15, 7, 0}, + {7, 6, 0}, + {31, 18, 0}, + {15, 10, 0}, + }, +}; + +enum { + SWR_NOT_PRESENT, /* Device is detached/not present on the bus */ + SWR_ATTACHED_OK, /* Device is attached */ + SWR_ALERT, /* Device alters master for any interrupts */ + SWR_RESERVED, /* Reserved */ +}; + +#define SWRM_MAX_PORT_REG 40 +#define SWRM_MAX_INIT_REG 8 + +#define SWR_MSTR_MAX_REG_ADDR 0x1740 +#define SWR_MSTR_START_REG_ADDR 0x00 +#define SWR_MSTR_MAX_BUF_LEN 32 +#define BYTES_PER_LINE 12 +#define SWR_MSTR_RD_BUF_LEN 8 +#define SWR_MSTR_WR_BUF_LEN 32 + +static void swrm_copy_data_port_config(struct swr_master *master, + u8 inactive_bank); +static struct swr_mstr_ctrl *dbgswrm; +static struct dentry *debugfs_swrm_dent; +static struct dentry *debugfs_peek; +static struct dentry *debugfs_poke; +static struct dentry *debugfs_reg_dump; +static unsigned int read_data; + + +static bool swrm_is_msm_variant(int val) +{ + return (val == SWRM_VERSION_1_3); +} + +static int swrm_debug_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static int get_parameters(char *buf, u32 *param1, int num_of_par) +{ + char *token; + int base, cnt; + + token = strsep(&buf, " "); + for (cnt = 0; cnt < num_of_par; cnt++) { + if (token) { + if ((token[1] == 'x') || (token[1] == 'X')) + base = 16; + else + base = 10; + + if (kstrtou32(token, base, ¶m1[cnt]) != 0) + return -EINVAL; + + token = strsep(&buf, " "); + } else + return -EINVAL; + } + return 0; +} + +static ssize_t swrm_reg_show(char __user *ubuf, size_t count, + loff_t *ppos) +{ + int i, reg_val, len; + ssize_t total = 0; + char tmp_buf[SWR_MSTR_MAX_BUF_LEN]; + + if (!ubuf || !ppos) + return 0; + + for (i = (((int) *ppos / BYTES_PER_LINE) + SWR_MSTR_START_REG_ADDR); + i <= SWR_MSTR_MAX_REG_ADDR; i += 4) { + reg_val = dbgswrm->read(dbgswrm->handle, i); + len = snprintf(tmp_buf, 25, "0x%.3x: 0x%.2x\n", i, reg_val); + if ((total + len) >= count - 1) + break; + if (copy_to_user((ubuf + total), tmp_buf, len)) { + pr_err("%s: fail to copy reg dump\n", __func__); + total = -EFAULT; + goto copy_err; + } + *ppos += len; + total += len; + } + +copy_err: + return total; +} + +static ssize_t swrm_debug_read(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + char lbuf[SWR_MSTR_RD_BUF_LEN]; + char *access_str; + ssize_t ret_cnt; + + if (!count || !file || !ppos || !ubuf) + return -EINVAL; + + access_str = file->private_data; + if (*ppos < 0) + return -EINVAL; + + if (!strcmp(access_str, "swrm_peek")) { + snprintf(lbuf, sizeof(lbuf), "0x%x\n", read_data); + ret_cnt = simple_read_from_buffer(ubuf, count, ppos, lbuf, + strnlen(lbuf, 7)); + } else if (!strcmp(access_str, "swrm_reg_dump")) { + ret_cnt = swrm_reg_show(ubuf, count, ppos); + } else { + pr_err("%s: %s not permitted to read\n", __func__, access_str); + ret_cnt = -EPERM; + } + return ret_cnt; +} + +static ssize_t swrm_debug_write(struct file *filp, + const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char lbuf[SWR_MSTR_WR_BUF_LEN]; + int rc; + u32 param[5]; + char *access_str; + + if (!filp || !ppos || !ubuf) + return -EINVAL; + + access_str = filp->private_data; + if (cnt > sizeof(lbuf) - 1) + return -EINVAL; + + rc = copy_from_user(lbuf, ubuf, cnt); + if (rc) + return -EFAULT; + + lbuf[cnt] = '\0'; + if (!strcmp(access_str, "swrm_poke")) { + /* write */ + rc = get_parameters(lbuf, param, 2); + if ((param[0] <= SWR_MSTR_MAX_REG_ADDR) && + (param[1] <= 0xFFFFFFFF) && + (rc == 0)) + rc = dbgswrm->write(dbgswrm->handle, param[0], + param[1]); + else + rc = -EINVAL; + } else if (!strcmp(access_str, "swrm_peek")) { + /* read */ + rc = get_parameters(lbuf, param, 1); + if ((param[0] <= SWR_MSTR_MAX_REG_ADDR) && (rc == 0)) + read_data = dbgswrm->read(dbgswrm->handle, param[0]); + else + rc = -EINVAL; + } + if (rc == 0) + rc = cnt; + else + pr_err("%s: rc = %d\n", __func__, rc); + + return rc; +} + +static const struct file_operations swrm_debug_ops = { + .open = swrm_debug_open, + .write = swrm_debug_write, + .read = swrm_debug_read, +}; + +static int swrm_set_ch_map(struct swr_mstr_ctrl *swrm, void *data) +{ + struct swr_mstr_port *pinfo = (struct swr_mstr_port *)data; + + swrm->mstr_port = kzalloc(sizeof(struct swr_mstr_port), GFP_KERNEL); + if (swrm->mstr_port == NULL) + return -ENOMEM; + swrm->mstr_port->num_port = pinfo->num_port; + swrm->mstr_port->port = kzalloc((pinfo->num_port * sizeof(u8)), + GFP_KERNEL); + if (!swrm->mstr_port->port) { + kfree(swrm->mstr_port); + swrm->mstr_port = NULL; + return -ENOMEM; + } + memcpy(swrm->mstr_port->port, pinfo->port, pinfo->num_port); + return 0; +} + +static bool swrm_is_port_en(struct swr_master *mstr) +{ + return !!(mstr->num_port); +} + +static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) +{ + if (!swrm->clk || !swrm->handle) + return -EINVAL; + + if (enable) { + swrm->clk(swrm->handle, true); + swrm->state = SWR_MSTR_UP; + } else { + swrm->clk(swrm->handle, false); + swrm->state = SWR_MSTR_DOWN; + } + return 0; +} + +static int swrm_get_port_config(struct swr_master *master) +{ + u32 ch_rate = 0; + u32 num_ch = 0; + int i, uc_idx; + u32 portcount = 0; + + for (i = 0; i < SWR_MSTR_PORT_LEN; i++) { + if (master->port[i].port_en) { + ch_rate += master->port[i].ch_rate; + num_ch += master->port[i].num_ch; + portcount++; + } + } + for (i = 0; i < ARRAY_SIZE(uc); i++) { + if ((uc[i].num_port == portcount) && + (uc[i].num_ch == num_ch) && + (uc[i].chrate == ch_rate)) { + uc_idx = i; + break; + } + } + + if (i >= ARRAY_SIZE(uc)) { + dev_err(&master->dev, + "%s: usecase port:%d, num_ch:%d, chrate:%d not found\n", + __func__, master->num_port, num_ch, ch_rate); + return -EINVAL; + } + for (i = 0; i < SWR_MSTR_PORT_LEN; i++) { + if (master->port[i].port_en) { + master->port[i].sinterval = pp[uc_idx][i].si; + master->port[i].offset1 = pp[uc_idx][i].off1; + master->port[i].offset2 = pp[uc_idx][i].off2; + } + } + return 0; +} + +static int swrm_get_master_port(u8 *mstr_port_id, u8 slv_port_id) +{ + int i; + + for (i = 0; i < SWR_MSTR_PORT_LEN; i++) { + if (mstr_ports[i] == slv_port_id) { + *mstr_port_id = i; + return 0; + } + } + return -EINVAL; +} + +static u32 swrm_get_packed_reg_val(u8 *cmd_id, u8 cmd_data, + u8 dev_addr, u16 reg_addr) +{ + u32 val; + u8 id = *cmd_id; + + if (id != SWR_BROADCAST_CMD_ID) { + if (id < 14) + id += 1; + else + id = 0; + *cmd_id = id; + } + val = SWR_REG_VAL_PACK(cmd_data, dev_addr, id, reg_addr); + + return val; +} + +static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, + u8 dev_addr, u8 cmd_id, u16 reg_addr, + u32 len) +{ + u32 val; + int ret = 0; + + val = swrm_get_packed_reg_val(&swrm->rcmd_id, len, dev_addr, reg_addr); + ret = swrm->write(swrm->handle, SWRM_CMD_FIFO_RD_CMD, val); + if (ret < 0) { + dev_err(swrm->dev, "%s: reg 0x%x write failed, err:%d\n", + __func__, val, ret); + goto err; + } + *cmd_data = swrm->read(swrm->handle, SWRM_CMD_FIFO_RD_FIFO_ADDR); + dev_dbg(swrm->dev, + "%s: reg: 0x%x, cmd_id: 0x%x, dev_id: 0x%x, cmd_data: 0x%x\n", + __func__, reg_addr, cmd_id, dev_addr, *cmd_data); +err: + return ret; +} + +static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data, + u8 dev_addr, u8 cmd_id, u16 reg_addr) +{ + u32 val; + int ret = 0; + + if (!cmd_id) + val = swrm_get_packed_reg_val(&swrm->wcmd_id, cmd_data, + dev_addr, reg_addr); + else + val = swrm_get_packed_reg_val(&cmd_id, cmd_data, + dev_addr, reg_addr); + + dev_dbg(swrm->dev, + "%s: reg: 0x%x, cmd_id: 0x%x, dev_id: 0x%x, cmd_data: 0x%x\n", + __func__, reg_addr, cmd_id, dev_addr, cmd_data); + ret = swrm->write(swrm->handle, SWRM_CMD_FIFO_WR_CMD, val); + if (ret < 0) { + dev_err(swrm->dev, "%s: reg 0x%x write failed, err:%d\n", + __func__, val, ret); + goto err; + } + if (cmd_id == 0xF) { + /* + * sleep for 10ms for MSM soundwire variant to allow broadcast + * command to complete. + */ + if (swrm_is_msm_variant(swrm->version)) + usleep_range(10000, 10100); + else + wait_for_completion_timeout(&swrm->broadcast, + (2 * HZ/10)); + } +err: + return ret; +} + +static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr, + void *buf, u32 len) +{ + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + int ret = 0; + int val; + u8 *reg_val = (u8 *)buf; + + if (!swrm) { + dev_err(&master->dev, "%s: swrm is NULL\n", __func__); + return -EINVAL; + } + + if (dev_num) + ret = swrm_cmd_fifo_rd_cmd(swrm, &val, dev_num, 0, reg_addr, + len); + else + val = swrm->read(swrm->handle, reg_addr); + + if (!ret) + *reg_val = (u8)val; + + pm_runtime_mark_last_busy(&swrm->pdev->dev); + + return ret; +} + +static int swrm_write(struct swr_master *master, u8 dev_num, u16 reg_addr, + const void *buf) +{ + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + int ret = 0; + u8 reg_val = *(u8 *)buf; + + if (!swrm) { + dev_err(&master->dev, "%s: swrm is NULL\n", __func__); + return -EINVAL; + } + + if (dev_num) + ret = swrm_cmd_fifo_wr_cmd(swrm, reg_val, dev_num, 0, reg_addr); + else + ret = swrm->write(swrm->handle, reg_addr, reg_val); + + pm_runtime_mark_last_busy(&swrm->pdev->dev); + + return ret; +} + +static int swrm_bulk_write(struct swr_master *master, u8 dev_num, void *reg, + const void *buf, size_t len) +{ + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + int ret = 0; + int i; + u32 *val; + u32 *swr_fifo_reg; + + if (!swrm || !swrm->handle) { + dev_err(&master->dev, "%s: swrm is NULL\n", __func__); + return -EINVAL; + } + if (len <= 0) + return -EINVAL; + + if (dev_num) { + swr_fifo_reg = kcalloc(len, sizeof(u32), GFP_KERNEL); + if (!swr_fifo_reg) { + ret = -ENOMEM; + goto err; + } + val = kcalloc(len, sizeof(u32), GFP_KERNEL); + if (!val) { + ret = -ENOMEM; + goto mem_fail; + } + + for (i = 0; i < len; i++) { + val[i] = swrm_get_packed_reg_val(&swrm->wcmd_id, + ((u8 *)buf)[i], + dev_num, + ((u16 *)reg)[i]); + swr_fifo_reg[i] = SWRM_CMD_FIFO_WR_CMD; + } + ret = swrm->bulk_write(swrm->handle, swr_fifo_reg, val, len); + if (ret) { + dev_err(&master->dev, "%s: bulk write failed\n", + __func__); + ret = -EINVAL; + } + } else { + dev_err(&master->dev, + "%s: No support of Bulk write for master regs\n", + __func__); + ret = -EINVAL; + goto err; + } + kfree(val); +mem_fail: + kfree(swr_fifo_reg); +err: + pm_runtime_mark_last_busy(&swrm->pdev->dev); + return ret; +} + +static u8 get_inactive_bank_num(struct swr_mstr_ctrl *swrm) +{ + return (swrm->read(swrm->handle, SWRM_MCP_STATUS) & + SWRM_MCP_STATUS_BANK_NUM_MASK) ? 0 : 1; +} + +static void enable_bank_switch(struct swr_mstr_ctrl *swrm, u8 bank, + u8 row, u8 col) +{ + swrm_cmd_fifo_wr_cmd(swrm, ((row << 3) | col), 0xF, 0xF, + SWRS_SCP_FRAME_CTRL_BANK(bank)); +} + +static struct swr_port_info *swrm_get_port(struct swr_master *master, + u8 port_id) +{ + int i; + struct swr_port_info *port = NULL; + + for (i = 0; i < SWR_MSTR_PORT_LEN; i++) { + port = &master->port[i]; + if (port->port_id == port_id) { + dev_dbg(&master->dev, "%s: port_id: %d, index: %d\n", + __func__, port_id, i); + return port; + } + } + + return NULL; +} + +static struct swr_port_info *swrm_get_avail_port(struct swr_master *master) +{ + int i; + struct swr_port_info *port = NULL; + + for (i = 0; i < SWR_MSTR_PORT_LEN; i++) { + port = &master->port[i]; + if (port->port_en) + continue; + + dev_dbg(&master->dev, "%s: port_id: %d, index: %d\n", + __func__, port->port_id, i); + return port; + } + + return NULL; +} + +static struct swr_port_info *swrm_get_enabled_port(struct swr_master *master, + u8 port_id) +{ + int i; + struct swr_port_info *port = NULL; + + for (i = 0; i < SWR_MSTR_PORT_LEN; i++) { + port = &master->port[i]; + if ((port->port_id == port_id) && (port->port_en == true)) + break; + } + if (i == SWR_MSTR_PORT_LEN) + port = NULL; + return port; +} + +static bool swrm_remove_from_group(struct swr_master *master) +{ + struct swr_device *swr_dev; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + bool is_removed = false; + + if (!swrm) + goto end; + + mutex_lock(&swrm->mlock); + if ((swrm->num_rx_chs > 1) && + (swrm->num_rx_chs == swrm->num_cfg_devs)) { + list_for_each_entry(swr_dev, &master->devices, + dev_list) { + swr_dev->group_id = SWR_GROUP_NONE; + master->gr_sid = 0; + } + is_removed = true; + } + mutex_unlock(&swrm->mlock); + +end: + return is_removed; +} + +static void swrm_cleanup_disabled_data_ports(struct swr_master *master, + u8 bank) +{ + u32 value; + struct swr_port_info *port; + int i; + int port_type; + struct swrm_mports *mport, *mport_next = NULL; + int port_disable_cnt = 0; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + + if (!swrm) { + pr_err("%s: swrm is null\n", __func__); + return; + } + + dev_dbg(swrm->dev, "%s: master num_port: %d\n", __func__, + master->num_port); + + mport = list_first_entry_or_null(&swrm->mport_list, + struct swrm_mports, + list); + if (!mport) { + dev_err(swrm->dev, "%s: list is empty\n", __func__); + return; + } + + for (i = 0; i < master->num_port; i++) { + port = swrm_get_port(master, mstr_ports[mport->id]); + if (!port || port->ch_en) + goto inc_loop; + + port_disable_cnt++; + port_type = mstr_port_type[mport->id]; + value = ((port->ch_en) + << SWRM_DP_PORT_CTRL_EN_CHAN_SHFT); + value |= ((port->offset2) + << SWRM_DP_PORT_CTRL_OFFSET2_SHFT); + value |= ((port->offset1) + << SWRM_DP_PORT_CTRL_OFFSET1_SHFT); + value |= port->sinterval; + + swrm->write(swrm->handle, + SWRM_DP_PORT_CTRL_BANK((mport->id+1), bank), + value); + swrm_cmd_fifo_wr_cmd(swrm, 0x00, port->dev_id, 0x00, + SWRS_DP_CHANNEL_ENABLE_BANK(port_type, bank)); + + dev_dbg(swrm->dev, "%s: mport :%d, reg: 0x%x, val: 0x%x\n", + __func__, mport->id, + (SWRM_DP_PORT_CTRL_BANK((mport->id+1), bank)), value); + +inc_loop: + mport_next = list_next_entry(mport, list); + if (port && !port->ch_en) { + list_del(&mport->list); + kfree(mport); + } + if (!mport_next) { + dev_err(swrm->dev, "%s: end of list\n", __func__); + break; + } + mport = mport_next; + } + master->num_port -= port_disable_cnt; + + dev_dbg(swrm->dev, "%s:disable ports: %d, active ports (rem): %d\n", + __func__, port_disable_cnt, master->num_port); +} + +static void swrm_slvdev_datapath_control(struct swr_master *master, + bool enable) +{ + u8 bank; + u32 value, n_col; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK | + SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK | + SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_BMSK); + u8 inactive_bank; + + if (!swrm) { + pr_err("%s: swrm is null\n", __func__); + return; + } + + bank = get_inactive_bank_num(swrm); + + dev_dbg(swrm->dev, "%s: enable: %d, cfg_devs: %d\n", + __func__, enable, swrm->num_cfg_devs); + + if (enable) { + /* set Row = 48 and col = 16 */ + n_col = SWR_MAX_COL; + } else { + /* + * Do not change to 48x2 if number of channels configured + * as stereo and if disable datapath is called for the + * first slave device + */ + if (swrm->num_cfg_devs > 0) + n_col = SWR_MAX_COL; + else + n_col = SWR_MIN_COL; + + /* + * All ports are already disabled, no need to perform + * bank-switch and copy operation. This case can arise + * when speaker channels are enabled in stereo mode with + * BROADCAST and disabled in GROUP_NONE + */ + if (master->num_port == 0) + return; + } + + value = swrm->read(swrm->handle, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank)); + value &= (~mask); + value |= ((0 << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | + (n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) | + (0 << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT)); + swrm->write(swrm->handle, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value); + + dev_dbg(swrm->dev, "%s: regaddr: 0x%x, value: 0x%x\n", __func__, + SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value); + + enable_bank_switch(swrm, bank, SWR_MAX_ROW, n_col); + + inactive_bank = bank ? 0 : 1; + if (enable) + swrm_copy_data_port_config(master, inactive_bank); + else + swrm_cleanup_disabled_data_ports(master, inactive_bank); + + if (!swrm_is_port_en(master)) { + dev_dbg(&master->dev, "%s: pm_runtime auto suspend triggered\n", + __func__); + pm_runtime_mark_last_busy(&swrm->pdev->dev); + pm_runtime_put_autosuspend(&swrm->pdev->dev); + } +} + +static void swrm_apply_port_config(struct swr_master *master) +{ + u8 bank; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + + if (!swrm) { + pr_err("%s: Invalid handle to swr controller\n", + __func__); + return; + } + + bank = get_inactive_bank_num(swrm); + dev_dbg(swrm->dev, "%s: enter bank: %d master_ports: %d\n", + __func__, bank, master->num_port); + + + swrm_cmd_fifo_wr_cmd(swrm, 0x01, 0xF, 0x00, + SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(bank)); + + swrm_copy_data_port_config(master, bank); +} + +static void swrm_copy_data_port_config(struct swr_master *master, u8 bank) +{ + u32 value; + struct swr_port_info *port; + int i; + int port_type; + struct swrm_mports *mport; + u32 reg[SWRM_MAX_PORT_REG]; + u32 val[SWRM_MAX_PORT_REG]; + int len = 0; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + + if (!swrm) { + pr_err("%s: swrm is null\n", __func__); + return; + } + + dev_dbg(swrm->dev, "%s: master num_port: %d\n", __func__, + master->num_port); + + mport = list_first_entry_or_null(&swrm->mport_list, + struct swrm_mports, + list); + if (!mport) { + dev_err(swrm->dev, "%s: list is empty\n", __func__); + return; + } + for (i = 0; i < master->num_port; i++) { + + port = swrm_get_enabled_port(master, mstr_ports[mport->id]); + if (!port) + continue; + port_type = mstr_port_type[mport->id]; + if (!port->dev_id || (port->dev_id > master->num_dev)) { + dev_dbg(swrm->dev, "%s: invalid device id = %d\n", + __func__, port->dev_id); + continue; + } + value = ((port->ch_en) + << SWRM_DP_PORT_CTRL_EN_CHAN_SHFT); + value |= ((port->offset2) + << SWRM_DP_PORT_CTRL_OFFSET2_SHFT); + value |= ((port->offset1) + << SWRM_DP_PORT_CTRL_OFFSET1_SHFT); + value |= port->sinterval; + + reg[len] = SWRM_DP_PORT_CTRL_BANK((mport->id+1), bank); + val[len++] = value; + + dev_dbg(swrm->dev, "%s: mport :%d, reg: 0x%x, val: 0x%x\n", + __func__, mport->id, + (SWRM_DP_PORT_CTRL_BANK((mport->id+1), bank)), value); + + reg[len] = SWRM_CMD_FIFO_WR_CMD; + val[len++] = SWR_REG_VAL_PACK(port->ch_en, port->dev_id, 0x00, + SWRS_DP_CHANNEL_ENABLE_BANK(port_type, bank)); + + reg[len] = SWRM_CMD_FIFO_WR_CMD; + val[len++] = SWR_REG_VAL_PACK(port->sinterval, + port->dev_id, 0x00, + SWRS_DP_SAMPLE_CONTROL_1_BANK(port_type, bank)); + + reg[len] = SWRM_CMD_FIFO_WR_CMD; + val[len++] = SWR_REG_VAL_PACK(port->offset1, + port->dev_id, 0x00, + SWRS_DP_OFFSET_CONTROL_1_BANK(port_type, bank)); + + if (port_type != 0) { + reg[len] = SWRM_CMD_FIFO_WR_CMD; + val[len++] = SWR_REG_VAL_PACK(port->offset2, + port->dev_id, 0x00, + SWRS_DP_OFFSET_CONTROL_2_BANK(port_type, + bank)); + } + mport = list_next_entry(mport, list); + if (!mport) { + dev_err(swrm->dev, "%s: end of list\n", __func__); + break; + } + } + swrm->bulk_write(swrm->handle, reg, val, len); +} + +static int swrm_connect_port(struct swr_master *master, + struct swr_params *portinfo) +{ + int i; + struct swr_port_info *port; + int ret = 0; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + struct swrm_mports *mport; + struct list_head *ptr, *next; + + dev_dbg(&master->dev, "%s: enter\n", __func__); + if (!portinfo) + return -EINVAL; + + if (!swrm) { + dev_err(&master->dev, + "%s: Invalid handle to swr controller\n", + __func__); + return -EINVAL; + } + + mutex_lock(&swrm->mlock); + if (!swrm_is_port_en(master)) + pm_runtime_get_sync(&swrm->pdev->dev); + + for (i = 0; i < portinfo->num_port; i++) { + mport = kzalloc(sizeof(struct swrm_mports), GFP_KERNEL); + if (!mport) { + ret = -ENOMEM; + goto mem_fail; + } + ret = swrm_get_master_port(&mport->id, + portinfo->port_id[i]); + if (ret < 0) { + dev_err(&master->dev, + "%s: mstr portid for slv port %d not found\n", + __func__, portinfo->port_id[i]); + goto port_fail; + } + port = swrm_get_avail_port(master); + if (!port) { + dev_err(&master->dev, + "%s: avail ports not found!\n", __func__); + goto port_fail; + } + list_add(&mport->list, &swrm->mport_list); + port->dev_id = portinfo->dev_id; + port->port_id = portinfo->port_id[i]; + port->num_ch = portinfo->num_ch[i]; + port->ch_rate = portinfo->ch_rate[i]; + port->ch_en = portinfo->ch_en[i]; + port->port_en = true; + dev_dbg(&master->dev, + "%s: mstr port %d, slv port %d ch_rate %d num_ch %d\n", + __func__, mport->id, port->port_id, port->ch_rate, + port->num_ch); + } + master->num_port += portinfo->num_port; + if (master->num_port >= SWR_MSTR_PORT_LEN) + master->num_port = SWR_MSTR_PORT_LEN; + + swrm_get_port_config(master); + swr_port_response(master, portinfo->tid); + swrm->num_cfg_devs += 1; + dev_dbg(&master->dev, "%s: cfg_devs: %d, rx_chs: %d\n", + __func__, swrm->num_cfg_devs, swrm->num_rx_chs); + if (swrm->num_rx_chs > 1) { + if (swrm->num_rx_chs == swrm->num_cfg_devs) + swrm_apply_port_config(master); + } else { + swrm_apply_port_config(master); + } + mutex_unlock(&swrm->mlock); + return 0; + +port_fail: + kfree(mport); +mem_fail: + list_for_each_safe(ptr, next, &swrm->mport_list) { + mport = list_entry(ptr, struct swrm_mports, list); + for (i = 0; i < portinfo->num_port; i++) { + if (portinfo->port_id[i] == mstr_ports[mport->id]) { + port = swrm_get_port(master, + portinfo->port_id[i]); + if (port) + port->ch_en = false; + list_del(&mport->list); + kfree(mport); + break; + } + } + } + mutex_unlock(&swrm->mlock); + return ret; +} + +static int swrm_disconnect_port(struct swr_master *master, + struct swr_params *portinfo) +{ + int i; + struct swr_port_info *port; + u8 bank; + u32 value; + int ret = 0; + u8 mport_id = 0; + int port_type = 0; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + + if (!swrm) { + dev_err(&master->dev, + "%s: Invalid handle to swr controller\n", + __func__); + return -EINVAL; + } + + if (!portinfo) { + dev_err(&master->dev, "%s: portinfo is NULL\n", __func__); + return -EINVAL; + } + mutex_lock(&swrm->mlock); + bank = get_inactive_bank_num(swrm); + for (i = 0; i < portinfo->num_port; i++) { + ret = swrm_get_master_port(&mport_id, + portinfo->port_id[i]); + if (ret < 0) { + dev_err(&master->dev, + "%s: mstr portid for slv port %d not found\n", + __func__, portinfo->port_id[i]); + mutex_unlock(&swrm->mlock); + return -EINVAL; + } + port = swrm_get_enabled_port(master, portinfo->port_id[i]); + if (!port) { + dev_dbg(&master->dev, "%s: port %d already disabled\n", + __func__, portinfo->port_id[i]); + continue; + } + port_type = mstr_port_type[mport_id]; + port->dev_id = portinfo->dev_id; + port->port_en = false; + port->ch_en = 0; + value = port->ch_en << SWRM_DP_PORT_CTRL_EN_CHAN_SHFT; + value |= (port->offset2 << SWRM_DP_PORT_CTRL_OFFSET2_SHFT); + value |= (port->offset1 << SWRM_DP_PORT_CTRL_OFFSET1_SHFT); + value |= port->sinterval; + + + swrm->write(swrm->handle, + SWRM_DP_PORT_CTRL_BANK((mport_id+1), bank), + value); + swrm_cmd_fifo_wr_cmd(swrm, 0x00, port->dev_id, 0x00, + SWRS_DP_CHANNEL_ENABLE_BANK(port_type, bank)); + } + + swr_port_response(master, portinfo->tid); + swrm->num_cfg_devs -= 1; + dev_dbg(&master->dev, "%s: cfg_devs: %d, rx_chs: %d, active ports: %d\n", + __func__, swrm->num_cfg_devs, swrm->num_rx_chs, + master->num_port); + mutex_unlock(&swrm->mlock); + + return 0; +} + +static int swrm_check_slave_change_status(struct swr_mstr_ctrl *swrm, + int status, u8 *devnum) +{ + int i; + int new_sts = status; + int ret = SWR_NOT_PRESENT; + + if (status != swrm->slave_status) { + for (i = 0; i < (swrm->master.num_dev + 1); i++) { + if ((status & SWRM_MCP_SLV_STATUS_MASK) != + (swrm->slave_status & SWRM_MCP_SLV_STATUS_MASK)) { + ret = (status & SWRM_MCP_SLV_STATUS_MASK); + *devnum = i; + break; + } + status >>= 2; + swrm->slave_status >>= 2; + } + swrm->slave_status = new_sts; + } + return ret; +} + +static irqreturn_t swr_mstr_interrupt(int irq, void *dev) +{ + struct swr_mstr_ctrl *swrm = dev; + u32 value, intr_sts; + int status, chg_sts, i; + u8 devnum = 0; + int ret = IRQ_HANDLED; + + pm_runtime_get_sync(&swrm->pdev->dev); + intr_sts = swrm->read(swrm->handle, SWRM_INTERRUPT_STATUS); + intr_sts &= SWRM_INTERRUPT_STATUS_RMSK; + for (i = 0; i < SWRM_INTERRUPT_MAX; i++) { + value = intr_sts & (1 << i); + if (!value) + continue; + + swrm->write(swrm->handle, SWRM_INTERRUPT_CLEAR, value); + switch (value) { + case SWRM_INTERRUPT_STATUS_SLAVE_PEND_IRQ: + dev_dbg(swrm->dev, "SWR slave pend irq\n"); + break; + case SWRM_INTERRUPT_STATUS_NEW_SLAVE_ATTACHED: + dev_dbg(swrm->dev, "SWR new slave attached\n"); + break; + case SWRM_INTERRUPT_STATUS_CHANGE_ENUM_SLAVE_STATUS: + status = swrm->read(swrm->handle, SWRM_MCP_SLV_STATUS); + if (status == swrm->slave_status) { + dev_dbg(swrm->dev, + "%s: No change in slave status: %d\n", + __func__, status); + break; + } + chg_sts = swrm_check_slave_change_status(swrm, status, + &devnum); + switch (chg_sts) { + case SWR_NOT_PRESENT: + dev_dbg(swrm->dev, "device %d got detached\n", + devnum); + break; + case SWR_ATTACHED_OK: + dev_dbg(swrm->dev, "device %d got attached\n", + devnum); + break; + case SWR_ALERT: + dev_dbg(swrm->dev, + "device %d has pending interrupt\n", + devnum); + break; + } + break; + case SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET: + dev_err_ratelimited(swrm->dev, "SWR bus clash detected\n"); + break; + case SWRM_INTERRUPT_STATUS_RD_FIFO_OVERFLOW: + dev_dbg(swrm->dev, "SWR read FIFO overflow\n"); + break; + case SWRM_INTERRUPT_STATUS_RD_FIFO_UNDERFLOW: + dev_dbg(swrm->dev, "SWR read FIFO underflow\n"); + break; + case SWRM_INTERRUPT_STATUS_WR_CMD_FIFO_OVERFLOW: + dev_dbg(swrm->dev, "SWR write FIFO overflow\n"); + break; + case SWRM_INTERRUPT_STATUS_CMD_ERROR: + value = swrm->read(swrm->handle, SWRM_CMD_FIFO_STATUS); + dev_err_ratelimited(swrm->dev, + "SWR CMD error, fifo status 0x%x, flushing fifo\n", + value); + swrm->write(swrm->handle, SWRM_CMD_FIFO_CMD, 0x1); + break; + case SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION: + dev_dbg(swrm->dev, "SWR Port collision detected\n"); + break; + case SWRM_INTERRUPT_STATUS_READ_EN_RD_VALID_MISMATCH: + dev_dbg(swrm->dev, "SWR read enable valid mismatch\n"); + break; + case SWRM_INTERRUPT_STATUS_SPECIAL_CMD_ID_FINISHED: + complete(&swrm->broadcast); + dev_dbg(swrm->dev, "SWR cmd id finished\n"); + break; + case SWRM_INTERRUPT_STATUS_NEW_SLAVE_AUTO_ENUM_FINISHED: + break; + case SWRM_INTERRUPT_STATUS_AUTO_ENUM_FAILED: + break; + case SWRM_INTERRUPT_STATUS_AUTO_ENUM_TABLE_IS_FULL: + break; + case SWRM_INTERRUPT_STATUS_BUS_RESET_FINISHED: + complete(&swrm->reset); + break; + case SWRM_INTERRUPT_STATUS_CLK_STOP_FINISHED: + break; + default: + dev_err_ratelimited(swrm->dev, "SWR unknown interrupt\n"); + ret = IRQ_NONE; + break; + } + } + pm_runtime_mark_last_busy(&swrm->pdev->dev); + pm_runtime_put_autosuspend(&swrm->pdev->dev); + return ret; +} + +static int swrm_get_device_status(struct swr_mstr_ctrl *swrm, u8 devnum) +{ + u32 val; + + swrm->slave_status = swrm->read(swrm->handle, SWRM_MCP_SLV_STATUS); + val = (swrm->slave_status >> (devnum * 2)); + val &= SWRM_MCP_SLV_STATUS_MASK; + return val; +} + +static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, + u8 *dev_num) +{ + int i; + u64 id = 0; + int ret = -EINVAL; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(mstr); + + if (!swrm) { + pr_err("%s: Invalid handle to swr controller\n", + __func__); + return ret; + } + + pm_runtime_get_sync(&swrm->pdev->dev); + for (i = 1; i < (mstr->num_dev + 1); i++) { + id = ((u64)(swrm->read(swrm->handle, + SWRM_ENUMERATOR_SLAVE_DEV_ID_2(i))) << 32); + id |= swrm->read(swrm->handle, + SWRM_ENUMERATOR_SLAVE_DEV_ID_1(i)); + if ((id & SWR_DEV_ID_MASK) == dev_id) { + if (swrm_get_device_status(swrm, i) == 0x01) { + *dev_num = i; + ret = 0; + } else { + dev_err(swrm->dev, "%s: device is not ready\n", + __func__); + } + goto found; + } + } + dev_err(swrm->dev, "%s: device id 0x%llx does not match with 0x%llx\n", + __func__, id, dev_id); +found: + pm_runtime_mark_last_busy(&swrm->pdev->dev); + pm_runtime_put_autosuspend(&swrm->pdev->dev); + return ret; +} +static int swrm_master_init(struct swr_mstr_ctrl *swrm) +{ + int ret = 0; + u32 val; + u8 row_ctrl = SWR_MAX_ROW; + u8 col_ctrl = SWR_MIN_COL; + u8 ssp_period = 1; + u8 retry_cmd_num = 3; + u32 reg[SWRM_MAX_INIT_REG]; + u32 value[SWRM_MAX_INIT_REG]; + int len = 0; + + /* Clear Rows and Cols */ + val = ((row_ctrl << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | + (col_ctrl << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) | + (ssp_period << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT)); + + reg[len] = SWRM_MCP_FRAME_CTRL_BANK_ADDR(0); + value[len++] = val; + + /* Set Auto enumeration flag */ + reg[len] = SWRM_ENUMERATOR_CFG_ADDR; + value[len++] = 1; + + /* Mask soundwire interrupts */ + reg[len] = SWRM_INTERRUPT_MASK_ADDR; + value[len++] = 0x1FFFD; + + /* Configure No pings */ + val = swrm->read(swrm->handle, SWRM_MCP_CFG_ADDR); + val &= ~SWRM_MCP_CFG_MAX_NUM_OF_CMD_NO_PINGS_BMSK; + val |= (0x1f << SWRM_MCP_CFG_MAX_NUM_OF_CMD_NO_PINGS_SHFT); + reg[len] = SWRM_MCP_CFG_ADDR; + value[len++] = val; + + /* Configure number of retries of a read/write cmd */ + val = (retry_cmd_num << SWRM_CMD_FIFO_CFG_NUM_OF_CMD_RETRY_SHFT); + reg[len] = SWRM_CMD_FIFO_CFG_ADDR; + value[len++] = val; + + /* Set IRQ to PULSE */ + reg[len] = SWRM_COMP_CFG_ADDR; + value[len++] = 0x02; + + reg[len] = SWRM_COMP_CFG_ADDR; + value[len++] = 0x03; + + reg[len] = SWRM_INTERRUPT_CLEAR; + value[len++] = 0x08; + + swrm->bulk_write(swrm->handle, reg, value, len); + + return ret; +} + +static int swrm_probe(struct platform_device *pdev) +{ + struct swr_mstr_ctrl *swrm; + struct swr_ctrl_platform_data *pdata; + int ret; + + /* Allocate soundwire master driver structure */ + swrm = kzalloc(sizeof(struct swr_mstr_ctrl), GFP_KERNEL); + if (!swrm) { + ret = -ENOMEM; + goto err_memory_fail; + } + swrm->dev = &pdev->dev; + swrm->pdev = pdev; + platform_set_drvdata(pdev, swrm); + swr_set_ctrl_data(&swrm->master, swrm); + pdata = dev_get_platdata(&pdev->dev); + if (!pdata) { + dev_err(&pdev->dev, "%s: pdata from parent is NULL\n", + __func__); + ret = -EINVAL; + goto err_pdata_fail; + } + swrm->handle = (void *)pdata->handle; + if (!swrm->handle) { + dev_err(&pdev->dev, "%s: swrm->handle is NULL\n", + __func__); + ret = -EINVAL; + goto err_pdata_fail; + } + swrm->read = pdata->read; + if (!swrm->read) { + dev_err(&pdev->dev, "%s: swrm->read is NULL\n", + __func__); + ret = -EINVAL; + goto err_pdata_fail; + } + swrm->write = pdata->write; + if (!swrm->write) { + dev_err(&pdev->dev, "%s: swrm->write is NULL\n", + __func__); + ret = -EINVAL; + goto err_pdata_fail; + } + swrm->bulk_write = pdata->bulk_write; + if (!swrm->bulk_write) { + dev_err(&pdev->dev, "%s: swrm->bulk_write is NULL\n", + __func__); + ret = -EINVAL; + goto err_pdata_fail; + } + swrm->clk = pdata->clk; + if (!swrm->clk) { + dev_err(&pdev->dev, "%s: swrm->clk is NULL\n", + __func__); + ret = -EINVAL; + goto err_pdata_fail; + } + swrm->reg_irq = pdata->reg_irq; + if (!swrm->reg_irq) { + dev_err(&pdev->dev, "%s: swrm->reg_irq is NULL\n", + __func__); + ret = -EINVAL; + goto err_pdata_fail; + } + swrm->master.read = swrm_read; + swrm->master.write = swrm_write; + swrm->master.bulk_write = swrm_bulk_write; + swrm->master.get_logical_dev_num = swrm_get_logical_dev_num; + swrm->master.connect_port = swrm_connect_port; + swrm->master.disconnect_port = swrm_disconnect_port; + swrm->master.slvdev_datapath_control = swrm_slvdev_datapath_control; + swrm->master.remove_from_group = swrm_remove_from_group; + swrm->master.dev.parent = &pdev->dev; + swrm->master.dev.of_node = pdev->dev.of_node; + swrm->master.num_port = 0; + swrm->num_enum_slaves = 0; + swrm->rcmd_id = 0; + swrm->wcmd_id = 0; + swrm->slave_status = 0; + swrm->num_rx_chs = 0; + swrm->state = SWR_MSTR_RESUME; + init_completion(&swrm->reset); + init_completion(&swrm->broadcast); + mutex_init(&swrm->mlock); + INIT_LIST_HEAD(&swrm->mport_list); + mutex_init(&swrm->reslock); + + ret = swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, + SWR_IRQ_REGISTER); + if (ret) { + dev_err(&pdev->dev, "%s: IRQ register failed ret %d\n", + __func__, ret); + goto err_irq_fail; + } + + ret = swr_register_master(&swrm->master); + if (ret) { + dev_err(&pdev->dev, "%s: error adding swr master\n", __func__); + goto err_mstr_fail; + } + + /* Add devices registered with board-info as the + * controller will be up now + */ + swr_master_add_boarddevices(&swrm->master); + mutex_lock(&swrm->mlock); + swrm_clk_request(swrm, true); + ret = swrm_master_init(swrm); + if (ret < 0) { + dev_err(&pdev->dev, + "%s: Error in master Initializaiton, err %d\n", + __func__, ret); + mutex_unlock(&swrm->mlock); + goto err_mstr_fail; + } + swrm->version = swrm->read(swrm->handle, SWRM_COMP_HW_VERSION); + + mutex_unlock(&swrm->mlock); + + if (pdev->dev.of_node) + of_register_swr_devices(&swrm->master); + + dbgswrm = swrm; + debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0); + if (!IS_ERR(debugfs_swrm_dent)) { + debugfs_peek = debugfs_create_file("swrm_peek", + S_IFREG | 0444, debugfs_swrm_dent, + (void *) "swrm_peek", &swrm_debug_ops); + + debugfs_poke = debugfs_create_file("swrm_poke", + S_IFREG | 0444, debugfs_swrm_dent, + (void *) "swrm_poke", &swrm_debug_ops); + + debugfs_reg_dump = debugfs_create_file("swrm_reg_dump", + S_IFREG | 0444, debugfs_swrm_dent, + (void *) "swrm_reg_dump", + &swrm_debug_ops); + } + pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + pm_runtime_mark_last_busy(&pdev->dev); + + return 0; +err_mstr_fail: + swrm->reg_irq(swrm->handle, swr_mstr_interrupt, + swrm, SWR_IRQ_FREE); +err_irq_fail: +err_pdata_fail: + kfree(swrm); +err_memory_fail: + return ret; +} + +static int swrm_remove(struct platform_device *pdev) +{ + struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); + + swrm->reg_irq(swrm->handle, swr_mstr_interrupt, + swrm, SWR_IRQ_FREE); + if (swrm->mstr_port) { + kfree(swrm->mstr_port->port); + swrm->mstr_port->port = NULL; + kfree(swrm->mstr_port); + swrm->mstr_port = NULL; + } + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + swr_unregister_master(&swrm->master); + mutex_destroy(&swrm->mlock); + mutex_destroy(&swrm->reslock); + kfree(swrm); + return 0; +} + +static int swrm_clk_pause(struct swr_mstr_ctrl *swrm) +{ + u32 val; + + dev_dbg(swrm->dev, "%s: state: %d\n", __func__, swrm->state); + swrm->write(swrm->handle, SWRM_INTERRUPT_MASK_ADDR, 0x1FDFD); + val = swrm->read(swrm->handle, SWRM_MCP_CFG_ADDR); + val |= SWRM_MCP_CFG_BUS_CLK_PAUSE_BMSK; + swrm->write(swrm->handle, SWRM_MCP_CFG_ADDR, val); + swrm->state = SWR_MSTR_PAUSE; + + return 0; +} + +#ifdef CONFIG_PM +static int swrm_runtime_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); + int ret = 0; + struct swr_master *mstr = &swrm->master; + struct swr_device *swr_dev; + + dev_dbg(dev, "%s: pm_runtime: resume, state:%d\n", + __func__, swrm->state); + mutex_lock(&swrm->reslock); + if ((swrm->state == SWR_MSTR_PAUSE) || + (swrm->state == SWR_MSTR_DOWN)) { + if (swrm->state == SWR_MSTR_DOWN) { + if (swrm_clk_request(swrm, true)) + goto exit; + } + list_for_each_entry(swr_dev, &mstr->devices, dev_list) { + ret = swr_device_up(swr_dev); + if (ret) { + dev_err(dev, + "%s: failed to wakeup swr dev %d\n", + __func__, swr_dev->dev_num); + swrm_clk_request(swrm, false); + goto exit; + } + } + swrm->write(swrm->handle, SWRM_COMP_SW_RESET, 0x01); + swrm->write(swrm->handle, SWRM_COMP_SW_RESET, 0x01); + swrm_master_init(swrm); + } +exit: + pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer); + mutex_unlock(&swrm->reslock); + return ret; +} + +static int swrm_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); + int ret = 0; + struct swr_master *mstr = &swrm->master; + struct swr_device *swr_dev; + + dev_dbg(dev, "%s: pm_runtime: suspend state: %d\n", + __func__, swrm->state); + mutex_lock(&swrm->reslock); + if ((swrm->state == SWR_MSTR_RESUME) || + (swrm->state == SWR_MSTR_UP)) { + if (swrm_is_port_en(&swrm->master)) { + dev_dbg(dev, "%s ports are enabled\n", __func__); + ret = -EBUSY; + goto exit; + } + swrm_clk_pause(swrm); + swrm->write(swrm->handle, SWRM_COMP_CFG_ADDR, 0x00); + list_for_each_entry(swr_dev, &mstr->devices, dev_list) { + ret = swr_device_down(swr_dev); + if (ret) { + dev_err(dev, + "%s: failed to shutdown swr dev %d\n", + __func__, swr_dev->dev_num); + goto exit; + } + } + swrm_clk_request(swrm, false); + } +exit: + mutex_unlock(&swrm->reslock); + return ret; +} +#endif /* CONFIG_PM */ + +static int swrm_device_down(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); + int ret = 0; + struct swr_master *mstr = &swrm->master; + struct swr_device *swr_dev; + + dev_dbg(dev, "%s: swrm state: %d\n", __func__, swrm->state); + mutex_lock(&swrm->reslock); + if ((swrm->state == SWR_MSTR_RESUME) || + (swrm->state == SWR_MSTR_UP)) { + list_for_each_entry(swr_dev, &mstr->devices, dev_list) { + ret = swr_device_down(swr_dev); + if (ret) + dev_err(dev, + "%s: failed to shutdown swr dev %d\n", + __func__, swr_dev->dev_num); + } + dev_dbg(dev, "%s: Shutting down SWRM\n", __func__); + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + pm_runtime_enable(dev); + swrm_clk_request(swrm, false); + } + mutex_unlock(&swrm->reslock); + return ret; +} + +/** + * swrm_wcd_notify - parent device can notify to soundwire master through + * this function + * @pdev: pointer to platform device structure + * @id: command id from parent to the soundwire master + * @data: data from parent device to soundwire master + */ +int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) +{ + struct swr_mstr_ctrl *swrm; + int ret = 0; + struct swr_master *mstr; + struct swr_device *swr_dev; + + if (!pdev) { + pr_err("%s: pdev is NULL\n", __func__); + return -EINVAL; + } + swrm = platform_get_drvdata(pdev); + if (!swrm) { + dev_err(&pdev->dev, "%s: swrm is NULL\n", __func__); + return -EINVAL; + } + mstr = &swrm->master; + + switch (id) { + case SWR_CH_MAP: + if (!data) { + dev_err(swrm->dev, "%s: data is NULL\n", __func__); + ret = -EINVAL; + } else { + ret = swrm_set_ch_map(swrm, data); + } + break; + case SWR_DEVICE_DOWN: + dev_dbg(swrm->dev, "%s: swr master down called\n", __func__); + mutex_lock(&swrm->mlock); + if ((swrm->state == SWR_MSTR_PAUSE) || + (swrm->state == SWR_MSTR_DOWN)) + dev_dbg(swrm->dev, "%s: SWR master is already Down: %d\n", + __func__, swrm->state); + else + swrm_device_down(&pdev->dev); + mutex_unlock(&swrm->mlock); + break; + case SWR_DEVICE_UP: + dev_dbg(swrm->dev, "%s: swr master up called\n", __func__); + mutex_lock(&swrm->mlock); + mutex_lock(&swrm->reslock); + if ((swrm->state == SWR_MSTR_RESUME) || + (swrm->state == SWR_MSTR_UP)) { + dev_dbg(swrm->dev, "%s: SWR master is already UP: %d\n", + __func__, swrm->state); + } else { + pm_runtime_mark_last_busy(&pdev->dev); + mutex_unlock(&swrm->reslock); + pm_runtime_get_sync(&pdev->dev); + mutex_lock(&swrm->reslock); + list_for_each_entry(swr_dev, &mstr->devices, dev_list) { + ret = swr_reset_device(swr_dev); + if (ret) { + dev_err(swrm->dev, + "%s: failed to reset swr device %d\n", + __func__, swr_dev->dev_num); + swrm_clk_request(swrm, false); + } + } + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_put_autosuspend(&pdev->dev); + } + mutex_unlock(&swrm->reslock); + mutex_unlock(&swrm->mlock); + break; + case SWR_SET_NUM_RX_CH: + if (!data) { + dev_err(swrm->dev, "%s: data is NULL\n", __func__); + ret = -EINVAL; + } else { + mutex_lock(&swrm->mlock); + swrm->num_rx_chs = *(int *)data; + if ((swrm->num_rx_chs > 1) && !swrm->num_cfg_devs) { + list_for_each_entry(swr_dev, &mstr->devices, + dev_list) { + ret = swr_set_device_group(swr_dev, + SWR_BROADCAST); + if (ret) + dev_err(swrm->dev, + "%s: set num ch failed\n", + __func__); + } + } else { + list_for_each_entry(swr_dev, &mstr->devices, + dev_list) { + ret = swr_set_device_group(swr_dev, + SWR_GROUP_NONE); + if (ret) + dev_err(swrm->dev, + "%s: set num ch failed\n", + __func__); + } + } + mutex_unlock(&swrm->mlock); + } + break; + default: + dev_err(swrm->dev, "%s: swr master unknown id %d\n", + __func__, id); + break; + } + return ret; +} +EXPORT_SYMBOL(swrm_wcd_notify); + +#ifdef CONFIG_PM_SLEEP +static int swrm_suspend(struct device *dev) +{ + int ret = -EBUSY; + struct platform_device *pdev = to_platform_device(dev); + struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); + + dev_dbg(dev, "%s: system suspend, state: %d\n", __func__, swrm->state); + if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) { + ret = swrm_runtime_suspend(dev); + if (!ret) { + /* + * Synchronize runtime-pm and system-pm states: + * At this point, we are already suspended. If + * runtime-pm still thinks its active, then + * make sure its status is in sync with HW + * status. The three below calls let the + * runtime-pm know that we are suspended + * already without re-invoking the suspend + * callback + */ + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + pm_runtime_enable(dev); + } + } + if (ret == -EBUSY) { + /* + * There is a possibility that some audio stream is active + * during suspend. We dont want to return suspend failure in + * that case so that display and relevant components can still + * go to suspend. + * If there is some other error, then it should be passed-on + * to system level suspend + */ + ret = 0; + } + return ret; +} + +static int swrm_resume(struct device *dev) +{ + int ret = 0; + struct platform_device *pdev = to_platform_device(dev); + struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); + + dev_dbg(dev, "%s: system resume, state: %d\n", __func__, swrm->state); + if (!pm_runtime_enabled(dev) || !pm_runtime_suspend(dev)) { + ret = swrm_runtime_resume(dev); + if (!ret) { + pm_runtime_mark_last_busy(dev); + pm_request_autosuspend(dev); + } + } + return ret; +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops swrm_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS( + swrm_suspend, + swrm_resume + ) + SET_RUNTIME_PM_OPS( + swrm_runtime_suspend, + swrm_runtime_resume, + NULL + ) +}; + +static const struct of_device_id swrm_dt_match[] = { + { + .compatible = "qcom,swr-wcd", + }, + {} +}; + +static struct platform_driver swr_mstr_driver = { + .probe = swrm_probe, + .remove = swrm_remove, + .driver = { + .name = SWR_WCD_NAME, + .owner = THIS_MODULE, + .pm = &swrm_dev_pm_ops, + .of_match_table = swrm_dt_match, + }, +}; + +static int __init swrm_init(void) +{ + return platform_driver_register(&swr_mstr_driver); +} +subsys_initcall(swrm_init); + +static void __exit swrm_exit(void) +{ + platform_driver_unregister(&swr_mstr_driver); +} +module_exit(swrm_exit); + + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("WCD SoundWire Controller"); +MODULE_ALIAS("platform:swr-wcd"); diff --git a/drivers/soundwire/swr-wcd-ctrl.h b/drivers/soundwire/swr-wcd-ctrl.h new file mode 100644 index 000000000000..b7a3edac3e00 --- /dev/null +++ b/drivers/soundwire/swr-wcd-ctrl.h @@ -0,0 +1,106 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SWR_WCD_CTRL_H +#define _SWR_WCD_CTRL_H +#include +#include + +#define SWR_MAX_ROW 0 /* Rows = 48 */ +#define SWR_MAX_COL 7 /* Cols = 16 */ +#define SWR_MIN_COL 0 /* Cols = 2 */ + +#define SWR_WCD_NAME "swr-wcd" + +#define SWR_MSTR_PORT_LEN 8 /* Number of master ports */ + +#define SWRM_VERSION_1_0 0x01010000 +#define SWRM_VERSION_1_2 0x01030000 +#define SWRM_VERSION_1_3 0x01040000 + +enum { + SWR_MSTR_PAUSE, + SWR_MSTR_RESUME, + SWR_MSTR_UP, + SWR_MSTR_DOWN, +}; + +enum { + SWR_IRQ_FREE, + SWR_IRQ_REGISTER, +}; + +enum { + SWR_DAC_PORT, + SWR_COMP_PORT, + SWR_BOOST_PORT, + SWR_VISENSE_PORT, +}; + +struct usecase { + u8 num_port; + u8 num_ch; + u32 chrate; +}; + +struct port_params { + u8 si; + u8 off1; + u8 off2; +}; + +struct swrm_mports { + struct list_head list; + u8 id; +}; + +struct swr_ctrl_platform_data { + void *handle; /* holds priv data */ + int (*read)(void *handle, int reg); + int (*write)(void *handle, int reg, int val); + int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); + int (*clk)(void *handle, bool enable); + int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq, + void *data), void *swr_handle, int type); +}; + +struct swr_mstr_ctrl { + struct swr_master master; + struct device *dev; + struct resource *supplies; + struct clk *mclk; + struct completion reset; + struct completion broadcast; + struct mutex mlock; + struct mutex reslock; + u8 rcmd_id; + u8 wcmd_id; + void *handle; /* SWR Master handle from client for read and writes */ + int (*read)(void *handle, int reg); + int (*write)(void *handle, int reg, int val); + int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); + int (*clk)(void *handle, bool enable); + int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq, + void *data), void *swr_handle, int type); + int irq; + int version; + int num_enum_slaves; + int slave_status; + struct swr_mstr_port *mstr_port; + struct list_head mport_list; + int state; + struct platform_device *pdev; + int num_rx_chs; + u8 num_cfg_devs; +}; + +#endif /* _SWR_WCD_CTRL_H */ diff --git a/drivers/soundwire/swrm_registers.h b/drivers/soundwire/swrm_registers.h new file mode 100644 index 000000000000..50c3ecfdd47d --- /dev/null +++ b/drivers/soundwire/swrm_registers.h @@ -0,0 +1,204 @@ +/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SWRM_REGISTERS_H +#define _SWRM_REGISTERS_H + +#define SWRM_BASE_ADDRESS 0x00 + +#define SWRM_COMP_HW_VERSION SWRM_BASE_ADDRESS +#define SWRM_COMP_CFG_ADDR (SWRM_BASE_ADDRESS+0x00000004) +#define SWRM_COMP_CFG_RMSK 0x3 +#define SWRM_COMP_CFG_IRQ_LEVEL_OR_PULSE_BMSK 0x2 +#define SWRM_COMP_CFG_IRQ_LEVEL_OR_PULSE_SHFT 0x1 +#define SWRM_COMP_CFG_ENABLE_BMSK 0x1 +#define SWRM_COMP_CFG_ENABLE_SHFT 0x0 + +#define SWRM_COMP_SW_RESET (SWRM_BASE_ADDRESS+0x00000008) + +#define SWRM_COMP_PARAMS (SWRM_BASE_ADDRESS+0x100) +#define SWRM_COMP_PARAMS_DOUT_PORTS_MASK 0x0000001F +#define SWRM_COMP_PARAMS_DIN_PORTS_MASK 0x000003E0 +#define SWRM_COMP_PARAMS_WR_FIFO_DEPTH 0x00007C00 +#define SWRM_COMP_PARAMS_RD_FIFO_DEPTH 0x000F8000 +#define SWRM_COMP_PARAMS_AUTO_ENUM_SLAVES 0x00F00000 +#define SWRM_COMP_PARAMS_DATA_LANES 0x07000000 + + +#define SWRM_INTERRUPT_STATUS (SWRM_BASE_ADDRESS+0x00000200) +#define SWRM_INTERRUPT_STATUS_RMSK 0x1FFFD + +#define SWRM_INTERRUPT_STATUS_SLAVE_PEND_IRQ 0x1 +#define SWRM_INTERRUPT_STATUS_NEW_SLAVE_ATTACHED 0x2 +#define SWRM_INTERRUPT_STATUS_CHANGE_ENUM_SLAVE_STATUS 0x4 +#define SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET 0x8 +#define SWRM_INTERRUPT_STATUS_RD_FIFO_OVERFLOW 0x10 +#define SWRM_INTERRUPT_STATUS_RD_FIFO_UNDERFLOW 0x20 +#define SWRM_INTERRUPT_STATUS_WR_CMD_FIFO_OVERFLOW 0x40 +#define SWRM_INTERRUPT_STATUS_CMD_ERROR 0x80 +#define SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION 0x100 +#define SWRM_INTERRUPT_STATUS_READ_EN_RD_VALID_MISMATCH 0x200 +#define SWRM_INTERRUPT_STATUS_SPECIAL_CMD_ID_FINISHED 0x400 +#define SWRM_INTERRUPT_STATUS_NEW_SLAVE_AUTO_ENUM_FINISHED 0x800 +#define SWRM_INTERRUPT_STATUS_AUTO_ENUM_FAILED 0x1000 +#define SWRM_INTERRUPT_STATUS_AUTO_ENUM_TABLE_IS_FULL 0x2000 +#define SWRM_INTERRUPT_STATUS_BUS_RESET_FINISHED 0x4000 +#define SWRM_INTERRUPT_STATUS_CLK_STOP_FINISHED 0x8000 +#define SWRM_INTERRUPT_STATUS_ERROR_PORT_TEST 0x10000 + +#define SWRM_INTERRUPT_MASK_ADDR (SWRM_BASE_ADDRESS+0x00000204) +#define SWRM_INTERRUPT_MASK_RMSK 0x1FFFF + +#define SWRM_INTERRUPT_MASK_SLAVE_PEND_IRQ_BMSK 0x1 +#define SWRM_INTERRUPT_MASK_SLAVE_PEND_IRQ_SHFT 0x0 + +#define SWRM_INTERRUPT_MASK_NEW_SLAVE_ATTACHED_BMSK 0x2 +#define SWRM_INTERRUPT_MASK_NEW_SLAVE_ATTACHED_SHFT 0x1 + +#define SWRM_INTERRUPT_MASK_CHANGE_ENUM_SLAVE_STATUS_BMSK 0x4 +#define SWRM_INTERRUPT_MASK_CHANGE_ENUM_SLAVE_STATUS_SHFT 0x2 + +#define SWRM_INTERRUPT_MASK_MASTER_CLASH_DET_BMSK 0x8 +#define SWRM_INTERRUPT_MASK_MASTER_CLASH_DET_SHFT 0x3 + +#define SWRM_INTERRUPT_MASK_RD_FIFO_OVERFLOW_BMSK 0x10 +#define SWRM_INTERRUPT_MASK_RD_FIFO_OVERFLOW_SHFT 0x4 + +#define SWRM_INTERRUPT_MASK_RD_FIFO_UNDERFLOW_BMSK 0x20 +#define SWRM_INTERRUPT_MASK_RD_FIFO_UNDERFLOW_SHFT 0x5 + +#define SWRM_INTERRUPT_MASK_WR_CMD_FIFO_OVERFLOW_BMSK 0x40 +#define SWRM_INTERRUPT_MASK_WR_CMD_FIFO_OVERFLOW_SHFT 0x6 + +#define SWRM_INTERRUPT_MASK_CMD_ERROR_BMSK 0x80 +#define SWRM_INTERRUPT_MASK_CMD_ERROR_SHFT 0x7 + +#define SWRM_INTERRUPT_MASK_DOUT_PORT_COLLISION_BMSK 0x100 +#define SWRM_INTERRUPT_MASK_DOUT_PORT_COLLISION_SHFT 0x8 + +#define SWRM_INTERRUPT_MASK_READ_EN_RD_VALID_MISMATCH_BMSK 0x200 +#define SWRM_INTERRUPT_MASK_READ_EN_RD_VALID_MISMATCH_SHFT 0x9 + +#define SWRM_INTERRUPT_MASK_SPECIAL_CMD_ID_FINISHED_BMSK 0x400 +#define SWRM_INTERRUPT_MASK_SPECIAL_CMD_ID_FINISHED_SHFT 0xA + +#define SWRM_INTERRUPT_MASK_NEW_SLAVE_AUTO_ENUM_FINISHED_BMSK 0x800 +#define SWRM_INTERRUPT_MASK_NEW_SLAVE_AUTO_ENUM_FINISHED_SHFT 0xB + +#define SWRM_INTERRUPT_MASK_AUTO_ENUM_FAILED_BMSK 0x1000 +#define SWRM_INTERRUPT_MASK_AUTO_ENUM_FAILED_SHFT 0xC + +#define SWRM_INTERRUPT_MASK_AUTO_ENUM_TABLE_IS_FULL_BMSK 0x2000 +#define SWRM_INTERRUPT_MASK_AUTO_ENUM_TABLE_IS_FULL_SHFT 0xD + +#define SWRM_INTERRUPT_MASK_BUS_RESET_FINISHED_BMSK 0x4000 +#define SWRM_INTERRUPT_MASK_BUS_RESET_FINISHED_SHFT 0xE + +#define SWRM_INTERRUPT_MASK_CLK_STOP_FINISHED_BMSK 0x8000 +#define SWRM_INTERRUPT_MASK_CLK_STOP_FINISHED_SHFT 0xF + +#define SWRM_INTERRUPT_MASK_ERROR_PORT_TEST_BMSK 0x10000 +#define SWRM_INTERRUPT_MASK_ERROR_PORT_TEST_SHFT 0x10 + +#define SWRM_INTERRUPT_MAX 0x11 + +#define SWRM_INTERRUPT_CLEAR (SWRM_BASE_ADDRESS+0x00000208) + +#define SWRM_CMD_FIFO_WR_CMD (SWRM_BASE_ADDRESS + 0x00000300) +#define SWRM_CMD_FIFO_WR_CMD_MASK 0xFFFFFFFF +#define SWRM_CMD_FIFO_RD_CMD (SWRM_BASE_ADDRESS + 0x00000304) +#define SWRM_CMD_FIFO_RD_CMD_MASK 0xFFFFFFF +#define SWRM_CMD_FIFO_CMD (SWRM_BASE_ADDRESS + 0x00000308) +#define SWRM_CMD_FIFO_STATUS (SWRM_BASE_ADDRESS + 0x0000030C) + +#define SWRM_CMD_FIFO_STATUS_WR_CMD_FIFO_CNT_MASK 0x1F00 +#define SWRM_CMD_FIFO_STATUS_RD_CMD_FIFO_CNT_MASK 0x7C00000 + +#define SWRM_CMD_FIFO_CFG_ADDR (SWRM_BASE_ADDRESS+0x00000314) +#define SWRM_CMD_FIFO_CFG_NUM_OF_CMD_RETRY_BMSK 0x7 +#define SWRM_CMD_FIFO_CFG_NUM_OF_CMD_RETRY_SHFT 0x0 + +#define SWRM_CMD_FIFO_RD_FIFO_ADDR (SWRM_BASE_ADDRESS + 0x00000318) + +#define SWRM_ENUMERATOR_CFG_ADDR (SWRM_BASE_ADDRESS+0x00000500) +#define SWRM_ENUMERATOR_CFG_AUTO_ENUM_EN_BMSK 0x1 +#define SWRM_ENUMERATOR_CFG_AUTO_ENUM_EN_SHFT 0x0 + +#define SWRM_ENUMERATOR_SLAVE_DEV_ID_1(m) (SWRM_BASE_ADDRESS+0x530+0x8*m) +#define SWRM_ENUMERATOR_SLAVE_DEV_ID_2(m) (SWRM_BASE_ADDRESS+0x534+0x8*m) + +#define SWRM_MCP_FRAME_CTRL_BANK_ADDR(m) (SWRM_BASE_ADDRESS+0x101C+0x40*m) +#define SWRM_MCP_FRAME_CTRL_BANK_RMSK 0x00ff07ff +#define SWRM_MCP_FRAME_CTRL_BANK_SHFT 0 +#define SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_BMSK 0xff0000 +#define SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT 16 +#define SWRM_MCP_FRAME_CTRL_BANK_PHASE_BMSK 0xf800 +#define SWRM_MCP_FRAME_CTRL_BANK_PHASE_SHFT 11 +#define SWRM_MCP_FRAME_CTRL_BANK_CLK_DIV_VALUE_BMSK 0x700 +#define SWRM_MCP_FRAME_CTRL_BANK_CLK_DIV_VALUE_SHFT 8 +#define SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK 0xF8 +#define SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT 3 +#define SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK 0x7 +#define SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT 0 + +#define SWRM_MCP_BUS_CTRL_ADDR (SWRM_BASE_ADDRESS+0x00001044) +#define SWRM_MCP_BUS_CTRL_BUS_RESET_BMSK 0x1 +#define SWRM_MCP_BUS_CTRL_BUS_RESET_SHFT 0x0 +#define SWRM_MCP_BUS_CTRL_CLK_START_BMSK 0x2 +#define SWRM_MCP_BUS_CTRL_CLK_START_SHFT 0x1 + +#define SWRM_MCP_CFG_ADDR (SWRM_BASE_ADDRESS+0x00001048) +#define SWRM_MCP_CFG_MAX_NUM_OF_CMD_NO_PINGS_BMSK 0x3E0000 +#define SWRM_MCP_CFG_MAX_NUM_OF_CMD_NO_PINGS_SHFT 0x11 +#define SWRM_MCP_CFG_BUS_CLK_PAUSE_BMSK 0x02 + +#define SWRM_MCP_STATUS (SWRM_BASE_ADDRESS+0x104C) +#define SWRM_MCP_STATUS_BANK_NUM_MASK 0x01 + +#define SWRM_MCP_SLV_STATUS (SWRM_BASE_ADDRESS+0x1090) +#define SWRM_MCP_SLV_STATUS_MASK 0x03 + +#define SWRM_DP_PORT_CTRL_BANK(n, m) (SWRM_BASE_ADDRESS + \ + 0x00001124 + \ + 0x100*(n-1) + \ + 0x40*m) +#define SWRM_DP_PORT_CTRL_BANK_MASK 0xFFFFFFFF +#define SWRM_DP_PORT_CTRL_EN_CHAN_MASK 0xFF000000 +#define SWRM_DP_PORT_CTRL_EN_CHAN_SHFT 0x18 +#define SWRM_DP_PORT_CTRL_OFFSET2_SHFT 0x10 +#define SWRM_DP_PORT_CTRL_OFFSET1_SHFT 0x08 +#define SWRM_DP_PORT_CTRL_SAMPLE_INTERVAL 0x00 + +/* Soundwire Slave Register definition */ + +#define SWRS_BASE_ADDRESS 0x00 + +#define SWRS_DP_REG_OFFSET(port, bank) ((0x100*port)+(0x10*bank)) + +#define SWRS_DP_CHANNEL_ENABLE_BANK(n, m) (SWRS_BASE_ADDRESS + 0x120 + \ + SWRS_DP_REG_OFFSET(n, m)) +#define SWRS_DP_SAMPLE_CONTROL_1_BANK(n, m) (SWRS_BASE_ADDRESS + 0x122 + \ + SWRS_DP_REG_OFFSET(n, m)) +#define SWRS_DP_OFFSET_CONTROL_1_BANK(n, m) (SWRS_BASE_ADDRESS + 0x124 + \ + SWRS_DP_REG_OFFSET(n, m)) +#define SWRS_DP_OFFSET_CONTROL_2_BANK(n, m) (SWRS_BASE_ADDRESS + 0x125 + \ + SWRS_DP_REG_OFFSET(n, m)) +#define SWRS_DP_HCONTROL_BANK(n, m) (SWRS_BASE_ADDRESS + 0x126 + \ + SWRS_DP_REG_OFFSET(n, m)) +#define SWRS_DP_BLOCK_CONTROL_3_BANK(n, m) (SWRS_BASE_ADDRESS + 0x127 + \ + SWRS_DP_REG_OFFSET(n, m)) +#define SWRS_SCP_FRAME_CTRL_BANK(m) (SWRS_BASE_ADDRESS + 0x60 + \ + 0x10*m) +#define SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(m) (SWRS_BASE_ADDRESS + 0xE0 + \ + 0x10*m) + +#endif /* _SWRM_REGISTERS_H */ diff --git a/include/Kbuild b/include/Kbuild new file mode 100644 index 000000000000..bab1145bc7a7 --- /dev/null +++ b/include/Kbuild @@ -0,0 +1,2 @@ +# Top-level Makefile calls into asm-$(ARCH) +# List only non-arch directories below diff --git a/include/linux/avtimer_kernel.h b/include/linux/avtimer_kernel.h new file mode 100644 index 000000000000..e5a12559f1ba --- /dev/null +++ b/include/linux/avtimer_kernel.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _AVTIMER_H +#define _AVTIMER_H + +#include + +int avcs_core_open(void); +int avcs_core_disable_power_collapse(int disable);/* true or flase */ +int avcs_core_query_timer(uint64_t *avtimer_tick); + +#endif diff --git a/include/linux/mfd/msm-cdc-pinctrl.h b/include/linux/mfd/msm-cdc-pinctrl.h new file mode 100644 index 000000000000..7eabefb80e19 --- /dev/null +++ b/include/linux/mfd/msm-cdc-pinctrl.h @@ -0,0 +1,49 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MFD_CDC_PINCTRL_H_ +#define __MFD_CDC_PINCTRL_H_ + +#include +#include + +#if IS_ENABLED(CONFIG_MSM_CDC_PINCTRL) +extern int msm_cdc_pinctrl_select_sleep_state(struct device_node *np); +extern int msm_cdc_pinctrl_select_active_state(struct device_node *np); +extern bool msm_cdc_pinctrl_get_state(struct device_node *np); +extern int msm_cdc_get_gpio_state(struct device_node *np); +int msm_cdc_pinctrl_drv_init(void); +void msm_cdc_pinctrl_drv_exit(void); + +#else +int msm_cdc_pinctrl_select_sleep_state(struct device_node *np) +{ + return 0; +} +int msm_cdc_pinctrl_select_active_state(struct device_node *np) +{ + return 0; +} +int msm_cdc_get_gpio_state(struct device_node *np) +{ + return 0; +} +int msm_cdc_pinctrl_drv_init(void) +{ + return 0; +} +void msm_cdc_pinctrl_drv_exit(void) +{ +} +#endif + +#endif diff --git a/include/linux/mfd/msm-cdc-supply.h b/include/linux/mfd/msm-cdc-supply.h new file mode 100644 index 000000000000..b40f44b1f12f --- /dev/null +++ b/include/linux/mfd/msm-cdc-supply.h @@ -0,0 +1,48 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __CODEC_POWER_SUPPLY_H__ +#define __CODEC_POWER_SUPPLY_H__ + +#include +#include +#include + +struct cdc_regulator { + const char *name; + int min_uV; + int max_uV; + int optimum_uA; + bool ondemand; + struct regulator *regulator; +}; + +extern int msm_cdc_get_power_supplies(struct device *dev, + struct cdc_regulator **cdc_vreg, + int *total_num_supplies); +extern int msm_cdc_disable_static_supplies(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies); +extern int msm_cdc_release_supplies(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies); +extern int msm_cdc_enable_static_supplies(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies); +extern int msm_cdc_init_supplies(struct device *dev, + struct regulator_bulk_data **supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies); +#endif diff --git a/include/linux/mfd/wcd9335/irq.h b/include/linux/mfd/wcd9335/irq.h new file mode 100644 index 000000000000..c666d3144359 --- /dev/null +++ b/include/linux/mfd/wcd9335/irq.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __WCD9335_IRQ_H_ +#define __WCD9335_IRQ_H_ + +enum { + /* INTR_REG 0 */ + WCD9335_IRQ_FLL_LOCK_LOSS = 1, + WCD9335_IRQ_HPH_PA_OCPL_FAULT, + WCD9335_IRQ_HPH_PA_OCPR_FAULT, + WCD9335_IRQ_EAR_PA_OCP_FAULT, + WCD9335_IRQ_HPH_PA_CNPL_COMPLETE, + WCD9335_IRQ_HPH_PA_CNPR_COMPLETE, + WCD9335_IRQ_EAR_PA_CNP_COMPLETE, + /* INTR_REG 1 */ + WCD9335_IRQ_MBHC_SW_DET, + WCD9335_IRQ_MBHC_ELECT_INS_REM_DET, + WCD9335_IRQ_MBHC_BUTTON_PRESS_DET, + WCD9335_IRQ_MBHC_BUTTON_RELEASE_DET, + WCD9335_IRQ_MBHC_ELECT_INS_REM_LEG_DET, + WCD9335_IRQ_RESERVED_0, + WCD9335_IRQ_RESERVED_1, + WCD9335_IRQ_RESERVED_2, + /* INTR_REG 2 */ + WCD9335_IRQ_LINE_PA1_CNP_COMPLETE, + WCD9335_IRQ_LINE_PA2_CNP_COMPLETE, + WCD9335_IRQ_LINE_PA3_CNP_COMPLETE, + WCD9335_IRQ_LINE_PA4_CNP_COMPLETE, + WCD9335_IRQ_SOUNDWIRE, + WCD9335_IRQ_VDD_DIG_RAMP_COMPLETE, + WCD9335_IRQ_RCO_ERROR, + WCD9335_IRQ_SVA_ERROR, + /* INTR_REG 3 */ + WCD9335_IRQ_MAD_AUDIO, + WCD9335_IRQ_MAD_BEACON, + WCD9335_IRQ_MAD_ULTRASOUND, + WCD9335_IRQ_VBAT_ATTACK, + WCD9335_IRQ_VBAT_RESTORE, + WCD9335_IRQ_SVA_OUTBOX1, + WCD9335_IRQ_SVA_OUTBOX2, + WCD9335_NUM_IRQS, +}; + +#endif diff --git a/include/linux/mfd/wcd9335/registers.h b/include/linux/mfd/wcd9335/registers.h new file mode 100644 index 000000000000..c50430d4278f --- /dev/null +++ b/include/linux/mfd/wcd9335/registers.h @@ -0,0 +1,1348 @@ +/* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _WCD9335_REGISTERS_H +#define _WCD9335_REGISTERS_H + +#define WCD9335_PAGE_SIZE 256 +#define WCD9335_NUM_PAGES 256 + +extern const u8 *wcd9335_reg[WCD9335_NUM_PAGES]; + +enum { + PAGE_0 = 0, + PAGE_1, + PAGE_2, + PAGE_6 = 6, + PAGE_10 = 0xA, + PAGE_11, + PAGE_12, + PAGE_13, + PAGE_0X80, +}; + +/* Page-0 Registers */ +#define WCD9335_PAGE0_PAGE_REGISTER 0x0000 +#define WCD9335_CODEC_RPM_CLK_BYPASS 0x0001 +#define WCD9335_CODEC_RPM_CLK_GATE 0x0002 +#define WCD9335_CODEC_RPM_CLK_MCLK_CFG 0x0003 +#define WCD9335_CODEC_RPM_RST_CTL 0x0009 +#define WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL 0x0011 +#define WCD9335_CODEC_RPM_PWR_CPE_DEEPSLP_1 0x0012 +#define WCD9335_CODEC_RPM_PWR_CPE_DEEPSLP_2 0x0013 +#define WCD9335_CODEC_RPM_PWR_CPE_DEEPSLP_3 0x0014 +#define WCD9335_CODEC_RPM_PWR_CPE_IRAM_SHUTDOWN 0x0015 +#define WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN 0x0016 +#define WCD9335_CODEC_RPM_PWR_CPE_DRAM0_SHUTDOWN_1 0x0017 +#define WCD9335_CODEC_RPM_PWR_CPE_DRAM0_SHUTDOWN_2 0x0018 +#define WCD9335_CODEC_RPM_INT_MASK 0x001d +#define WCD9335_CODEC_RPM_INT_STATUS 0x001e +#define WCD9335_CODEC_RPM_INT_CLEAR 0x001f +#define WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0 0x0021 +#define WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE1 0x0022 +#define WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE2 0x0023 +#define WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE3 0x0024 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_CTL 0x0025 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_TEST0 0x0026 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_TEST1 0x0027 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0 0x0029 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT1 0x002a +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT2 0x002b +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT3 0x002c +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT4 0x002d +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT5 0x002e +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT6 0x002f +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT7 0x0030 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT8 0x0031 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT9 0x0032 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT10 0x0033 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT11 0x0034 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT12 0x0035 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT13 0x0036 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT14 0x0037 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT15 0x0038 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS 0x0039 +#define WCD9335_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO 0x003a +#define WCD9335_CHIP_TIER_CTRL_I2C_SLAVE_ID_1 0x003b +#define WCD9335_CHIP_TIER_CTRL_I2C_SLAVE_ID_2 0x003c +#define WCD9335_CHIP_TIER_CTRL_I2C_SLAVE_ID_3 0x003d +#define WCD9335_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL 0x003e +#define WCD9335_CHIP_TIER_CTRL_I2C_ACTIVE 0x003f +#define WCD9335_CHIP_TIER_CTRL_PROC1_MON_CTL 0x0041 +#define WCD9335_CHIP_TIER_CTRL_PROC1_MON_STATUS 0x0042 +#define WCD9335_CHIP_TIER_CTRL_PROC1_MON_CNT_MSB 0x0043 +#define WCD9335_CHIP_TIER_CTRL_PROC1_MON_CNT_LSB 0x0044 +#define WCD9335_CHIP_TIER_CTRL_PROC2_MON_CTL 0x0045 +#define WCD9335_CHIP_TIER_CTRL_PROC2_MON_STATUS 0x0046 +#define WCD9335_CHIP_TIER_CTRL_PROC2_MON_CNT_MSB 0x0047 +#define WCD9335_CHIP_TIER_CTRL_PROC2_MON_CNT_LSB 0x0048 +#define WCD9335_CHIP_TIER_CTRL_PROC3_MON_CTL 0x0049 +#define WCD9335_CHIP_TIER_CTRL_PROC3_MON_STATUS 0x004a +#define WCD9335_CHIP_TIER_CTRL_PROC3_MON_CNT_MSB 0x004b +#define WCD9335_CHIP_TIER_CTRL_PROC3_MON_CNT_LSB 0x004c +#define WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL 0x0051 +#define WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL 0x0052 +#define WCD9335_DATA_HUB_DATA_HUB_I2S_CLK 0x0053 +#define WCD9335_DATA_HUB_DATA_HUB_RX0_INP_CFG 0x0054 +#define WCD9335_DATA_HUB_DATA_HUB_RX1_INP_CFG 0x0055 +#define WCD9335_DATA_HUB_DATA_HUB_RX2_INP_CFG 0x0056 +#define WCD9335_DATA_HUB_DATA_HUB_RX3_INP_CFG 0x0057 +#define WCD9335_DATA_HUB_DATA_HUB_RX4_INP_CFG 0x0058 +#define WCD9335_DATA_HUB_DATA_HUB_RX5_INP_CFG 0x0059 +#define WCD9335_DATA_HUB_DATA_HUB_RX6_INP_CFG 0x005a +#define WCD9335_DATA_HUB_DATA_HUB_RX7_INP_CFG 0x005b +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX0_INP_CFG 0x0061 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX1_INP_CFG 0x0062 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX2_INP_CFG 0x0063 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX3_INP_CFG 0x0064 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX4_INP_CFG 0x0065 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX5_INP_CFG 0x0066 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX6_INP_CFG 0x0067 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX7_INP_CFG 0x0068 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX8_INP_CFG 0x0069 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX9_INP_CFG 0x006a +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX10_INP_CFG 0x006b +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX11_INP_CFG 0x006c +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG 0x006e +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX14_INP_CFG 0x006f +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX15_INP_CFG 0x0070 +#define WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG 0x0071 +#define WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG 0x0072 +#define WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG 0x0073 +#define WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG 0x0074 +#define WCD9335_DATA_HUB_NATIVE_FIFO_SYNC 0x0075 +#define WCD9335_DATA_HUB_NATIVE_FIFO_STATUS 0x007D +#define WCD9335_INTR_CFG 0x0081 +#define WCD9335_INTR_CLR_COMMIT 0x0082 +#define WCD9335_INTR_PIN1_MASK0 0x0089 +#define WCD9335_INTR_PIN1_MASK1 0x008a +#define WCD9335_INTR_PIN1_MASK2 0x008b +#define WCD9335_INTR_PIN1_MASK3 0x008c +#define WCD9335_INTR_PIN1_STATUS0 0x0091 +#define WCD9335_INTR_PIN1_STATUS1 0x0092 +#define WCD9335_INTR_PIN1_STATUS2 0x0093 +#define WCD9335_INTR_PIN1_STATUS3 0x0094 +#define WCD9335_INTR_PIN1_CLEAR0 0x0099 +#define WCD9335_INTR_PIN1_CLEAR1 0x009a +#define WCD9335_INTR_PIN1_CLEAR2 0x009b +#define WCD9335_INTR_PIN1_CLEAR3 0x009c +#define WCD9335_INTR_PIN2_MASK0 0x00a1 +#define WCD9335_INTR_PIN2_MASK1 0x00a2 +#define WCD9335_INTR_PIN2_MASK2 0x00a3 +#define WCD9335_INTR_PIN2_MASK3 0x00a4 +#define WCD9335_INTR_PIN2_STATUS0 0x00a9 +#define WCD9335_INTR_PIN2_STATUS1 0x00aa +#define WCD9335_INTR_PIN2_STATUS2 0x00ab +#define WCD9335_INTR_PIN2_STATUS3 0x00ac +#define WCD9335_INTR_PIN2_CLEAR0 0x00b1 +#define WCD9335_INTR_PIN2_CLEAR1 0x00b2 +#define WCD9335_INTR_PIN2_CLEAR2 0x00b3 +#define WCD9335_INTR_PIN2_CLEAR3 0x00b4 +#define WCD9335_INTR_LEVEL0 0x00e1 +#define WCD9335_INTR_LEVEL1 0x00e2 +#define WCD9335_INTR_LEVEL2 0x00e3 +#define WCD9335_INTR_LEVEL3 0x00e4 +#define WCD9335_INTR_BYPASS0 0x00e9 +#define WCD9335_INTR_BYPASS1 0x00ea +#define WCD9335_INTR_BYPASS2 0x00eb +#define WCD9335_INTR_BYPASS3 0x00ec +#define WCD9335_INTR_SET0 0x00f1 +#define WCD9335_INTR_SET1 0x00f2 +#define WCD9335_INTR_SET2 0x00f3 +#define WCD9335_INTR_SET3 0x00f4 + +/* Page-1 Registers */ +#define WCD9335_PAGE1_PAGE_REGISTER 0x0100 +#define WCD9335_CPE_FLL_USER_CTL_0 0x0101 +#define WCD9335_CPE_FLL_USER_CTL_1 0x0102 +#define WCD9335_CPE_FLL_USER_CTL_2 0x0103 +#define WCD9335_CPE_FLL_USER_CTL_3 0x0104 +#define WCD9335_CPE_FLL_USER_CTL_4 0x0105 +#define WCD9335_CPE_FLL_USER_CTL_5 0x0106 +#define WCD9335_CPE_FLL_USER_CTL_6 0x0107 +#define WCD9335_CPE_FLL_USER_CTL_7 0x0108 +#define WCD9335_CPE_FLL_USER_CTL_8 0x0109 +#define WCD9335_CPE_FLL_USER_CTL_9 0x010a +#define WCD9335_CPE_FLL_L_VAL_CTL_0 0x010b +#define WCD9335_CPE_FLL_L_VAL_CTL_1 0x010c +#define WCD9335_CPE_FLL_DSM_FRAC_CTL_0 0x010d +#define WCD9335_CPE_FLL_DSM_FRAC_CTL_1 0x010e +#define WCD9335_CPE_FLL_CONFIG_CTL_0 0x010f +#define WCD9335_CPE_FLL_CONFIG_CTL_1 0x0110 +#define WCD9335_CPE_FLL_CONFIG_CTL_2 0x0111 +#define WCD9335_CPE_FLL_CONFIG_CTL_3 0x0112 +#define WCD9335_CPE_FLL_CONFIG_CTL_4 0x0113 +#define WCD9335_CPE_FLL_TEST_CTL_0 0x0114 +#define WCD9335_CPE_FLL_TEST_CTL_1 0x0115 +#define WCD9335_CPE_FLL_TEST_CTL_2 0x0116 +#define WCD9335_CPE_FLL_TEST_CTL_3 0x0117 +#define WCD9335_CPE_FLL_TEST_CTL_4 0x0118 +#define WCD9335_CPE_FLL_TEST_CTL_5 0x0119 +#define WCD9335_CPE_FLL_TEST_CTL_6 0x011a +#define WCD9335_CPE_FLL_TEST_CTL_7 0x011b +#define WCD9335_CPE_FLL_FREQ_CTL_0 0x011c +#define WCD9335_CPE_FLL_FREQ_CTL_1 0x011d +#define WCD9335_CPE_FLL_FREQ_CTL_2 0x011e +#define WCD9335_CPE_FLL_FREQ_CTL_3 0x011f +#define WCD9335_CPE_FLL_SSC_CTL_0 0x0120 +#define WCD9335_CPE_FLL_SSC_CTL_1 0x0121 +#define WCD9335_CPE_FLL_SSC_CTL_2 0x0122 +#define WCD9335_CPE_FLL_SSC_CTL_3 0x0123 +#define WCD9335_CPE_FLL_FLL_MODE 0x0124 +#define WCD9335_CPE_FLL_STATUS_0 0x0125 +#define WCD9335_CPE_FLL_STATUS_1 0x0126 +#define WCD9335_CPE_FLL_STATUS_2 0x0127 +#define WCD9335_CPE_FLL_STATUS_3 0x0128 +#define WCD9335_I2S_FLL_USER_CTL_0 0x0141 +#define WCD9335_I2S_FLL_USER_CTL_1 0x0142 +#define WCD9335_I2S_FLL_USER_CTL_2 0x0143 +#define WCD9335_I2S_FLL_USER_CTL_3 0x0144 +#define WCD9335_I2S_FLL_USER_CTL_4 0x0145 +#define WCD9335_I2S_FLL_USER_CTL_5 0x0146 +#define WCD9335_I2S_FLL_USER_CTL_6 0x0147 +#define WCD9335_I2S_FLL_USER_CTL_7 0x0148 +#define WCD9335_I2S_FLL_USER_CTL_8 0x0149 +#define WCD9335_I2S_FLL_USER_CTL_9 0x014a +#define WCD9335_I2S_FLL_L_VAL_CTL_0 0x014b +#define WCD9335_I2S_FLL_L_VAL_CTL_1 0x014c +#define WCD9335_I2S_FLL_DSM_FRAC_CTL_0 0x014d +#define WCD9335_I2S_FLL_DSM_FRAC_CTL_1 0x014e +#define WCD9335_I2S_FLL_CONFIG_CTL_0 0x014f +#define WCD9335_I2S_FLL_CONFIG_CTL_1 0x0150 +#define WCD9335_I2S_FLL_CONFIG_CTL_2 0x0151 +#define WCD9335_I2S_FLL_CONFIG_CTL_3 0x0152 +#define WCD9335_I2S_FLL_CONFIG_CTL_4 0x0153 +#define WCD9335_I2S_FLL_TEST_CTL_0 0x0154 +#define WCD9335_I2S_FLL_TEST_CTL_1 0x0155 +#define WCD9335_I2S_FLL_TEST_CTL_2 0x0156 +#define WCD9335_I2S_FLL_TEST_CTL_3 0x0157 +#define WCD9335_I2S_FLL_TEST_CTL_4 0x0158 +#define WCD9335_I2S_FLL_TEST_CTL_5 0x0159 +#define WCD9335_I2S_FLL_TEST_CTL_6 0x015a +#define WCD9335_I2S_FLL_TEST_CTL_7 0x015b +#define WCD9335_I2S_FLL_FREQ_CTL_0 0x015c +#define WCD9335_I2S_FLL_FREQ_CTL_1 0x015d +#define WCD9335_I2S_FLL_FREQ_CTL_2 0x015e +#define WCD9335_I2S_FLL_FREQ_CTL_3 0x015f +#define WCD9335_I2S_FLL_SSC_CTL_0 0x0160 +#define WCD9335_I2S_FLL_SSC_CTL_1 0x0161 +#define WCD9335_I2S_FLL_SSC_CTL_2 0x0162 +#define WCD9335_I2S_FLL_SSC_CTL_3 0x0163 +#define WCD9335_I2S_FLL_FLL_MODE 0x0164 +#define WCD9335_I2S_FLL_STATUS_0 0x0165 +#define WCD9335_I2S_FLL_STATUS_1 0x0166 +#define WCD9335_I2S_FLL_STATUS_2 0x0167 +#define WCD9335_I2S_FLL_STATUS_3 0x0168 +#define WCD9335_SB_FLL_USER_CTL_0 0x0181 +#define WCD9335_SB_FLL_USER_CTL_1 0x0182 +#define WCD9335_SB_FLL_USER_CTL_2 0x0183 +#define WCD9335_SB_FLL_USER_CTL_3 0x0184 +#define WCD9335_SB_FLL_USER_CTL_4 0x0185 +#define WCD9335_SB_FLL_USER_CTL_5 0x0186 +#define WCD9335_SB_FLL_USER_CTL_6 0x0187 +#define WCD9335_SB_FLL_USER_CTL_7 0x0188 +#define WCD9335_SB_FLL_USER_CTL_8 0x0189 +#define WCD9335_SB_FLL_USER_CTL_9 0x018a +#define WCD9335_SB_FLL_L_VAL_CTL_0 0x018b +#define WCD9335_SB_FLL_L_VAL_CTL_1 0x018c +#define WCD9335_SB_FLL_DSM_FRAC_CTL_0 0x018d +#define WCD9335_SB_FLL_DSM_FRAC_CTL_1 0x018e +#define WCD9335_SB_FLL_CONFIG_CTL_0 0x018f +#define WCD9335_SB_FLL_CONFIG_CTL_1 0x0190 +#define WCD9335_SB_FLL_CONFIG_CTL_2 0x0191 +#define WCD9335_SB_FLL_CONFIG_CTL_3 0x0192 +#define WCD9335_SB_FLL_CONFIG_CTL_4 0x0193 +#define WCD9335_SB_FLL_TEST_CTL_0 0x0194 +#define WCD9335_SB_FLL_TEST_CTL_1 0x0195 +#define WCD9335_SB_FLL_TEST_CTL_2 0x0196 +#define WCD9335_SB_FLL_TEST_CTL_3 0x0197 +#define WCD9335_SB_FLL_TEST_CTL_4 0x0198 +#define WCD9335_SB_FLL_TEST_CTL_5 0x0199 +#define WCD9335_SB_FLL_TEST_CTL_6 0x019a +#define WCD9335_SB_FLL_TEST_CTL_7 0x019b +#define WCD9335_SB_FLL_FREQ_CTL_0 0x019c +#define WCD9335_SB_FLL_FREQ_CTL_1 0x019d +#define WCD9335_SB_FLL_FREQ_CTL_2 0x019e +#define WCD9335_SB_FLL_FREQ_CTL_3 0x019f +#define WCD9335_SB_FLL_SSC_CTL_0 0x01a0 +#define WCD9335_SB_FLL_SSC_CTL_1 0x01a1 +#define WCD9335_SB_FLL_SSC_CTL_2 0x01a2 +#define WCD9335_SB_FLL_SSC_CTL_3 0x01a3 +#define WCD9335_SB_FLL_FLL_MODE 0x01a4 +#define WCD9335_SB_FLL_STATUS_0 0x01a5 +#define WCD9335_SB_FLL_STATUS_1 0x01a6 +#define WCD9335_SB_FLL_STATUS_2 0x01a7 +#define WCD9335_SB_FLL_STATUS_3 0x01a8 + +/* Page-2 Registers */ +#define WCD9335_PAGE2_PAGE_REGISTER 0x0200 +#define WCD9335_CPE_SS_MEM_PTR_0 0x0201 +#define WCD9335_CPE_SS_MEM_PTR_1 0x0202 +#define WCD9335_CPE_SS_MEM_PTR_2 0x0203 +#define WCD9335_CPE_SS_MEM_CTRL 0x0205 +#define WCD9335_CPE_SS_MEM_BANK_0 0x0206 +#define WCD9335_CPE_SS_MEM_BANK_1 0x0207 +#define WCD9335_CPE_SS_MEM_BANK_2 0x0208 +#define WCD9335_CPE_SS_MEM_BANK_3 0x0209 +#define WCD9335_CPE_SS_MEM_BANK_4 0x020a +#define WCD9335_CPE_SS_MEM_BANK_5 0x020b +#define WCD9335_CPE_SS_MEM_BANK_6 0x020c +#define WCD9335_CPE_SS_MEM_BANK_7 0x020d +#define WCD9335_CPE_SS_MEM_BANK_8 0x020e +#define WCD9335_CPE_SS_MEM_BANK_9 0x020f +#define WCD9335_CPE_SS_MEM_BANK_10 0x0210 +#define WCD9335_CPE_SS_MEM_BANK_11 0x0211 +#define WCD9335_CPE_SS_MEM_BANK_12 0x0212 +#define WCD9335_CPE_SS_MEM_BANK_13 0x0213 +#define WCD9335_CPE_SS_MEM_BANK_14 0x0214 +#define WCD9335_CPE_SS_MEM_BANK_15 0x0215 +#define WCD9335_CPE_SS_INBOX1_TRG 0x0216 +#define WCD9335_CPE_SS_INBOX2_TRG 0x0217 +#define WCD9335_CPE_SS_INBOX1_0 0x0218 +#define WCD9335_CPE_SS_INBOX1_1 0x0219 +#define WCD9335_CPE_SS_INBOX1_2 0x021a +#define WCD9335_CPE_SS_INBOX1_3 0x021b +#define WCD9335_CPE_SS_INBOX1_4 0x021c +#define WCD9335_CPE_SS_INBOX1_5 0x021d +#define WCD9335_CPE_SS_INBOX1_6 0x021e +#define WCD9335_CPE_SS_INBOX1_7 0x021f +#define WCD9335_CPE_SS_INBOX1_8 0x0220 +#define WCD9335_CPE_SS_INBOX1_9 0x0221 +#define WCD9335_CPE_SS_INBOX1_10 0x0222 +#define WCD9335_CPE_SS_INBOX1_11 0x0223 +#define WCD9335_CPE_SS_INBOX1_12 0x0224 +#define WCD9335_CPE_SS_INBOX1_13 0x0225 +#define WCD9335_CPE_SS_INBOX1_14 0x0226 +#define WCD9335_CPE_SS_INBOX1_15 0x0227 +#define WCD9335_CPE_SS_OUTBOX1_0 0x0228 +#define WCD9335_CPE_SS_OUTBOX1_1 0x0229 +#define WCD9335_CPE_SS_OUTBOX1_2 0x022a +#define WCD9335_CPE_SS_OUTBOX1_3 0x022b +#define WCD9335_CPE_SS_OUTBOX1_4 0x022c +#define WCD9335_CPE_SS_OUTBOX1_5 0x022d +#define WCD9335_CPE_SS_OUTBOX1_6 0x022e +#define WCD9335_CPE_SS_OUTBOX1_7 0x022f +#define WCD9335_CPE_SS_OUTBOX1_8 0x0230 +#define WCD9335_CPE_SS_OUTBOX1_9 0x0231 +#define WCD9335_CPE_SS_OUTBOX1_10 0x0232 +#define WCD9335_CPE_SS_OUTBOX1_11 0x0233 +#define WCD9335_CPE_SS_OUTBOX1_12 0x0234 +#define WCD9335_CPE_SS_OUTBOX1_13 0x0235 +#define WCD9335_CPE_SS_OUTBOX1_14 0x0236 +#define WCD9335_CPE_SS_OUTBOX1_15 0x0237 +#define WCD9335_CPE_SS_INBOX2_0 0x0238 +#define WCD9335_CPE_SS_INBOX2_1 0x0239 +#define WCD9335_CPE_SS_INBOX2_2 0x023a +#define WCD9335_CPE_SS_INBOX2_3 0x023b +#define WCD9335_CPE_SS_INBOX2_4 0x023c +#define WCD9335_CPE_SS_INBOX2_5 0x023d +#define WCD9335_CPE_SS_INBOX2_6 0x023e +#define WCD9335_CPE_SS_INBOX2_7 0x023f +#define WCD9335_CPE_SS_INBOX2_8 0x0240 +#define WCD9335_CPE_SS_INBOX2_9 0x0241 +#define WCD9335_CPE_SS_INBOX2_10 0x0242 +#define WCD9335_CPE_SS_INBOX2_11 0x0243 +#define WCD9335_CPE_SS_INBOX2_12 0x0244 +#define WCD9335_CPE_SS_INBOX2_13 0x0245 +#define WCD9335_CPE_SS_INBOX2_14 0x0246 +#define WCD9335_CPE_SS_INBOX2_15 0x0247 +#define WCD9335_CPE_SS_OUTBOX2_0 0x0248 +#define WCD9335_CPE_SS_OUTBOX2_1 0x0249 +#define WCD9335_CPE_SS_OUTBOX2_2 0x024a +#define WCD9335_CPE_SS_OUTBOX2_3 0x024b +#define WCD9335_CPE_SS_OUTBOX2_4 0x024c +#define WCD9335_CPE_SS_OUTBOX2_5 0x024d +#define WCD9335_CPE_SS_OUTBOX2_6 0x024e +#define WCD9335_CPE_SS_OUTBOX2_7 0x024f +#define WCD9335_CPE_SS_OUTBOX2_8 0x0250 +#define WCD9335_CPE_SS_OUTBOX2_9 0x0251 +#define WCD9335_CPE_SS_OUTBOX2_10 0x0252 +#define WCD9335_CPE_SS_OUTBOX2_11 0x0253 +#define WCD9335_CPE_SS_OUTBOX2_12 0x0254 +#define WCD9335_CPE_SS_OUTBOX2_13 0x0255 +#define WCD9335_CPE_SS_OUTBOX2_14 0x0256 +#define WCD9335_CPE_SS_OUTBOX2_15 0x0257 +#define WCD9335_CPE_SS_OUTBOX1_ACK 0x0258 +#define WCD9335_CPE_SS_OUTBOX2_ACK 0x0259 +#define WCD9335_CPE_SS_EC_BUF_INT_PERIOD 0x025a +#define WCD9335_CPE_SS_US_BUF_INT_PERIOD 0x025b +#define WCD9335_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD 0x025c +#define WCD9335_CPE_SS_CFG 0x025d +#define WCD9335_CPE_SS_US_EC_MUX_CFG 0x025e +#define WCD9335_CPE_SS_MAD_CTL 0x025f +#define WCD9335_CPE_SS_CPAR_CTL 0x0260 +#define WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD 0x0261 +#define WCD9335_CPE_SS_TX_PP_CFG 0x0262 +#define WCD9335_CPE_SS_DMIC0_CTL 0x0263 +#define WCD9335_CPE_SS_DMIC1_CTL 0x0264 +#define WCD9335_CPE_SS_DMIC2_CTL 0x0265 +#define WCD9335_CPE_SS_DMIC_CFG 0x0266 +#define WCD9335_CPE_SS_SVA_CFG 0x0267 +#define WCD9335_CPE_SS_CPAR_CFG 0x0271 +#define WCD9335_CPE_SS_WDOG_CFG 0x0272 +#define WCD9335_CPE_SS_BACKUP_INT 0x0273 +#define WCD9335_CPE_SS_STATUS 0x0274 +#define WCD9335_CPE_SS_CPE_OCD_CFG 0x0275 +#define WCD9335_CPE_SS_SS_ERROR_INT_MASK 0x0276 +#define WCD9335_CPE_SS_SS_ERROR_INT_STATUS 0x0277 +#define WCD9335_CPE_SS_SS_ERROR_INT_CLEAR 0x0278 +#define WCD9335_SOC_MAD_MAIN_CTL_1 0x0281 +#define WCD9335_SOC_MAD_MAIN_CTL_2 0x0282 +#define WCD9335_SOC_MAD_AUDIO_CTL_1 0x0283 +#define WCD9335_SOC_MAD_AUDIO_CTL_2 0x0284 +#define WCD9335_SOC_MAD_AUDIO_CTL_3 0x0285 +#define WCD9335_SOC_MAD_AUDIO_CTL_4 0x0286 +#define WCD9335_SOC_MAD_AUDIO_CTL_5 0x0287 +#define WCD9335_SOC_MAD_AUDIO_CTL_6 0x0288 +#define WCD9335_SOC_MAD_AUDIO_CTL_7 0x0289 +#define WCD9335_SOC_MAD_AUDIO_CTL_8 0x028a +#define WCD9335_SOC_MAD_AUDIO_IIR_CTL_PTR 0x028b +#define WCD9335_SOC_MAD_AUDIO_IIR_CTL_VAL 0x028c +#define WCD9335_SOC_MAD_ULTR_CTL_1 0x028d +#define WCD9335_SOC_MAD_ULTR_CTL_2 0x028e +#define WCD9335_SOC_MAD_ULTR_CTL_3 0x028f +#define WCD9335_SOC_MAD_ULTR_CTL_4 0x0290 +#define WCD9335_SOC_MAD_ULTR_CTL_5 0x0291 +#define WCD9335_SOC_MAD_ULTR_CTL_6 0x0292 +#define WCD9335_SOC_MAD_ULTR_CTL_7 0x0293 +#define WCD9335_SOC_MAD_BEACON_CTL_1 0x0294 +#define WCD9335_SOC_MAD_BEACON_CTL_2 0x0295 +#define WCD9335_SOC_MAD_BEACON_CTL_3 0x0296 +#define WCD9335_SOC_MAD_BEACON_CTL_4 0x0297 +#define WCD9335_SOC_MAD_BEACON_CTL_5 0x0298 +#define WCD9335_SOC_MAD_BEACON_CTL_6 0x0299 +#define WCD9335_SOC_MAD_BEACON_CTL_7 0x029a +#define WCD9335_SOC_MAD_BEACON_CTL_8 0x029b +#define WCD9335_SOC_MAD_BEACON_IIR_CTL_PTR 0x029c +#define WCD9335_SOC_MAD_BEACON_IIR_CTL_VAL 0x029d +#define WCD9335_SOC_MAD_INP_SEL 0x029e + +/* Page-6 Registers */ +#define WCD9335_PAGE6_PAGE_REGISTER 0x0600 +#define WCD9335_ANA_BIAS 0x0601 +#define WCD9335_ANA_CLK_TOP 0x0602 +#define WCD9335_ANA_RCO 0x0603 +#define WCD9335_ANA_BUCK_VOUT_A 0x0604 +#define WCD9335_ANA_BUCK_VOUT_D 0x0605 +#define WCD9335_ANA_BUCK_CTL 0x0606 +#define WCD9335_ANA_BUCK_STATUS 0x0607 +#define WCD9335_ANA_RX_SUPPLIES 0x0608 +#define WCD9335_ANA_HPH 0x0609 +#define WCD9335_ANA_EAR 0x060a +#define WCD9335_ANA_LO_1_2 0x060b +#define WCD9335_ANA_LO_3_4 0x060c +#define WCD9335_ANA_MAD_SETUP 0x060d +#define WCD9335_ANA_AMIC1 0x060e +#define WCD9335_ANA_AMIC2 0x060f +#define WCD9335_ANA_AMIC3 0x0610 +#define WCD9335_ANA_AMIC4 0x0611 +#define WCD9335_ANA_AMIC5 0x0612 +#define WCD9335_ANA_AMIC6 0x0613 +#define WCD9335_ANA_MBHC_MECH 0x0614 +#define WCD9335_ANA_MBHC_ELECT 0x0615 +#define WCD9335_ANA_MBHC_ZDET 0x0616 +#define WCD9335_ANA_MBHC_RESULT_1 0x0617 +#define WCD9335_ANA_MBHC_RESULT_2 0x0618 +#define WCD9335_ANA_MBHC_RESULT_3 0x0619 +#define WCD9335_ANA_MBHC_BTN0 0x061a +#define WCD9335_ANA_MBHC_BTN1 0x061b +#define WCD9335_ANA_MBHC_BTN2 0x061c +#define WCD9335_ANA_MBHC_BTN3 0x061d +#define WCD9335_ANA_MBHC_BTN4 0x061e +#define WCD9335_ANA_MBHC_BTN5 0x061f +#define WCD9335_ANA_MBHC_BTN6 0x0620 +#define WCD9335_ANA_MBHC_BTN7 0x0621 +#define WCD9335_ANA_MICB1 0x0622 +#define WCD9335_ANA_MICB2 0x0623 +#define WCD9335_ANA_MICB2_RAMP 0x0624 +#define WCD9335_ANA_MICB3 0x0625 +#define WCD9335_ANA_MICB4 0x0626 +#define WCD9335_ANA_VBADC 0x0627 +#define WCD9335_BIAS_CTL 0x0628 +#define WCD9335_BIAS_VBG_FINE_ADJ 0x0629 +#define WCD9335_CLOCK_TEST_CTL 0x062d +#define WCD9335_RCO_CTRL_1 0x062e +#define WCD9335_RCO_CTRL_2 0x062f +#define WCD9335_RCO_CAL 0x0630 +#define WCD9335_RCO_CAL_1 0x0631 +#define WCD9335_RCO_CAL_2 0x0632 +#define WCD9335_RCO_TEST_CTRL 0x0633 +#define WCD9335_RCO_CAL_OUT_1 0x0634 +#define WCD9335_RCO_CAL_OUT_2 0x0635 +#define WCD9335_RCO_CAL_OUT_3 0x0636 +#define WCD9335_RCO_CAL_OUT_4 0x0637 +#define WCD9335_RCO_CAL_OUT_5 0x0638 +#define WCD9335_SIDO_SIDO_MODE_1 0x063a +#define WCD9335_SIDO_SIDO_MODE_2 0x063b +#define WCD9335_SIDO_SIDO_MODE_3 0x063c +#define WCD9335_SIDO_SIDO_MODE_4 0x063d +#define WCD9335_SIDO_SIDO_VCL_1 0x063e +#define WCD9335_SIDO_SIDO_VCL_2 0x063f +#define WCD9335_SIDO_SIDO_VCL_3 0x0640 +#define WCD9335_SIDO_SIDO_CCL_1 0x0641 +#define WCD9335_SIDO_SIDO_CCL_2 0x0642 +#define WCD9335_SIDO_SIDO_CCL_3 0x0643 +#define WCD9335_SIDO_SIDO_CCL_4 0x0644 +#define WCD9335_SIDO_SIDO_CCL_5 0x0645 +#define WCD9335_SIDO_SIDO_CCL_6 0x0646 +#define WCD9335_SIDO_SIDO_CCL_7 0x0647 +#define WCD9335_SIDO_SIDO_CCL_8 0x0648 +#define WCD9335_SIDO_SIDO_CCL_9 0x0649 +#define WCD9335_SIDO_SIDO_CCL_10 0x064a +#define WCD9335_SIDO_SIDO_FILTER_1 0x064b +#define WCD9335_SIDO_SIDO_FILTER_2 0x064c +#define WCD9335_SIDO_SIDO_DRIVER_1 0x064d +#define WCD9335_SIDO_SIDO_DRIVER_2 0x064e +#define WCD9335_SIDO_SIDO_DRIVER_3 0x064f +#define WCD9335_SIDO_SIDO_CAL_CODE_EXT_1 0x0650 +#define WCD9335_SIDO_SIDO_CAL_CODE_EXT_2 0x0651 +#define WCD9335_SIDO_SIDO_CAL_CODE_OUT_1 0x0652 +#define WCD9335_SIDO_SIDO_CAL_CODE_OUT_2 0x0653 +#define WCD9335_SIDO_SIDO_TEST_1 0x0654 +#define WCD9335_SIDO_SIDO_TEST_2 0x0655 +#define WCD9335_MBHC_CTL_1 0x0656 +#define WCD9335_MBHC_CTL_2 0x0657 +#define WCD9335_MBHC_PLUG_DETECT_CTL 0x0658 +#define WCD9335_MBHC_ZDET_ANA_CTL 0x0659 +#define WCD9335_MBHC_ZDET_RAMP_CTL 0x065a +#define WCD9335_MBHC_FSM_DEBUG 0x065b /* v1.x */ +#define WCD9335_MBHC_FSM_STATUS 0x065b /* v2.0 */ +#define WCD9335_MBHC_TEST_CTL 0x065c +#define WCD9335_VBADC_SUBBLOCK_EN 0x065d +#define WCD9335_VBADC_IBIAS_FE 0x065e +#define WCD9335_VBADC_BIAS_ADC 0x065f +#define WCD9335_VBADC_FE_CTRL 0x0660 +#define WCD9335_VBADC_ADC_REF 0x0661 +#define WCD9335_VBADC_ADC_IO 0x0662 +#define WCD9335_VBADC_ADC_SAR 0x0663 +#define WCD9335_VBADC_DEBUG 0x0664 +#define WCD9335_VBADC_ADC_DOUTMSB 0x0665 +#define WCD9335_VBADC_ADC_DOUTLSB 0x0666 +#define WCD9335_LDOH_MODE 0x0667 +#define WCD9335_LDOH_BIAS 0x0668 +#define WCD9335_LDOH_STB_LOADS 0x0669 +#define WCD9335_LDOH_SLOWRAMP 0x066a +#define WCD9335_MICB1_TEST_CTL_1 0x066b +#define WCD9335_MICB1_TEST_CTL_2 0x066c +#define WCD9335_MICB1_TEST_CTL_3 0x066d +#define WCD9335_MICB2_TEST_CTL_1 0x066e +#define WCD9335_MICB2_TEST_CTL_2 0x066f +#define WCD9335_MICB2_TEST_CTL_3 0x0670 +#define WCD9335_MICB3_TEST_CTL_1 0x0671 +#define WCD9335_MICB3_TEST_CTL_2 0x0672 +#define WCD9335_MICB3_TEST_CTL_3 0x0673 +#define WCD9335_MICB4_TEST_CTL_1 0x0674 +#define WCD9335_MICB4_TEST_CTL_2 0x0675 +#define WCD9335_MICB4_TEST_CTL_3 0x0676 +#define WCD9335_TX_COM_ADC_VCM 0x0677 +#define WCD9335_TX_COM_BIAS_ATEST 0x0678 +#define WCD9335_TX_COM_ADC_INT1_IB 0x0679 +#define WCD9335_TX_COM_ADC_INT2_IB 0x067a +#define WCD9335_TX_COM_TXFE_DIV_CTL 0x067b +#define WCD9335_TX_COM_TXFE_DIV_START 0x067c +#define WCD9335_TX_COM_TXFE_DIV_STOP_9P6M 0x067d +#define WCD9335_TX_COM_TXFE_DIV_STOP_12P288M 0x067e +#define WCD9335_TX_1_2_TEST_EN 0x067f +#define WCD9335_TX_1_2_ADC_IB 0x0680 +#define WCD9335_TX_1_2_ATEST_REFCTL 0x0681 +#define WCD9335_TX_1_2_TEST_CTL 0x0682 +#define WCD9335_TX_1_2_TEST_BLK_EN 0x0683 +#define WCD9335_TX_1_2_TXFE_CLKDIV 0x0684 +#define WCD9335_TX_1_2_SAR1_ERR 0x0685 +#define WCD9335_TX_1_2_SAR2_ERR 0x0686 +#define WCD9335_TX_3_4_TEST_EN 0x0687 +#define WCD9335_TX_3_4_ADC_IB 0x0688 +#define WCD9335_TX_3_4_ATEST_REFCTL 0x0689 +#define WCD9335_TX_3_4_TEST_CTL 0x068a +#define WCD9335_TX_3_4_TEST_BLK_EN 0x068b +#define WCD9335_TX_3_4_TXFE_CLKDIV 0x068c +#define WCD9335_TX_3_4_SAR1_ERR 0x068d +#define WCD9335_TX_3_4_SAR2_ERR 0x068e +#define WCD9335_TX_5_6_TEST_EN 0x068f +#define WCD9335_TX_5_6_ADC_IB 0x0690 +#define WCD9335_TX_5_6_ATEST_REFCTL 0x0691 +#define WCD9335_TX_5_6_TEST_CTL 0x0692 +#define WCD9335_TX_5_6_TEST_BLK_EN 0x0693 +#define WCD9335_TX_5_6_TXFE_CLKDIV 0x0694 +#define WCD9335_TX_5_6_SAR1_ERR 0x0695 +#define WCD9335_TX_5_6_SAR2_ERR 0x0696 +#define WCD9335_CLASSH_MODE_1 0x0697 +#define WCD9335_CLASSH_MODE_2 0x0698 +#define WCD9335_CLASSH_MODE_3 0x0699 +#define WCD9335_CLASSH_CTRL_VCL_1 0x069a +#define WCD9335_CLASSH_CTRL_VCL_2 0x069b +#define WCD9335_CLASSH_CTRL_CCL_1 0x069c +#define WCD9335_CLASSH_CTRL_CCL_2 0x069d +#define WCD9335_CLASSH_CTRL_CCL_3 0x069e +#define WCD9335_CLASSH_CTRL_CCL_4 0x069f +#define WCD9335_CLASSH_CTRL_CCL_5 0x06a0 +#define WCD9335_CLASSH_BUCK_TMUX_A_D 0x06a1 +#define WCD9335_CLASSH_BUCK_SW_DRV_CNTL 0x06a2 +#define WCD9335_CLASSH_SPARE 0x06a3 +#define WCD9335_FLYBACK_EN 0x06a4 +#define WCD9335_FLYBACK_VNEG_CTRL_1 0x06a5 +#define WCD9335_FLYBACK_VNEG_CTRL_2 0x06a6 +#define WCD9335_FLYBACK_VNEG_CTRL_3 0x06a7 +#define WCD9335_FLYBACK_VNEG_CTRL_4 0x06a8 +#define WCD9335_FLYBACK_VNEG_CTRL_5 0x06a9 +#define WCD9335_FLYBACK_VNEG_CTRL_6 0x06aa +#define WCD9335_FLYBACK_VNEG_CTRL_7 0x06ab +#define WCD9335_FLYBACK_VNEG_CTRL_8 0x06ac +#define WCD9335_FLYBACK_VNEG_CTRL_9 0x06ad +#define WCD9335_FLYBACK_VNEG_DAC_CTRL_1 0x06ae +#define WCD9335_FLYBACK_VNEG_DAC_CTRL_2 0x06af +#define WCD9335_FLYBACK_VNEG_DAC_CTRL_3 0x06b0 +#define WCD9335_FLYBACK_VNEG_DAC_CTRL_4 0x06b1 /* v1.x */ +#define WCD9335_FLYBACK_CTRL_1 0x06b1 /* v2.0 */ +#define WCD9335_FLYBACK_TEST_CTL 0x06b2 +#define WCD9335_RX_AUX_SW_CTL 0x06b3 +#define WCD9335_RX_PA_AUX_IN_CONN 0x06b4 +#define WCD9335_RX_TIMER_DIV 0x06b5 +#define WCD9335_RX_OCP_CTL 0x06b6 +#define WCD9335_RX_OCP_COUNT 0x06b7 +#define WCD9335_RX_BIAS_EAR_DAC 0x06b8 +#define WCD9335_RX_BIAS_EAR_AMP 0x06b9 +#define WCD9335_RX_BIAS_HPH_LDO 0x06ba +#define WCD9335_RX_BIAS_HPH_PA 0x06bb +#define WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2 0x06bc +#define WCD9335_RX_BIAS_HPH_RDAC_LDO 0x06bd +#define WCD9335_RX_BIAS_HPH_CNP1 0x06be +#define WCD9335_RX_BIAS_HPH_LOWPOWER 0x06bf +#define WCD9335_RX_BIAS_DIFFLO_PA 0x06c0 +#define WCD9335_RX_BIAS_DIFFLO_REF 0x06c1 +#define WCD9335_RX_BIAS_DIFFLO_LDO 0x06c2 +#define WCD9335_RX_BIAS_SELO_DAC_PA 0x06c3 +#define WCD9335_RX_BIAS_BUCK_RST 0x06c4 +#define WCD9335_RX_BIAS_BUCK_VREF_ERRAMP 0x06c5 +#define WCD9335_RX_BIAS_FLYB_ERRAMP 0x06c6 +#define WCD9335_RX_BIAS_FLYB_BUFF 0x06c7 +#define WCD9335_RX_BIAS_FLYB_MID_RST 0x06c8 +#define WCD9335_HPH_L_STATUS 0x06c9 +#define WCD9335_HPH_R_STATUS 0x06ca +#define WCD9335_HPH_CNP_EN 0x06cb +#define WCD9335_HPH_CNP_WG_CTL 0x06cc +#define WCD9335_HPH_CNP_WG_TIME 0x06cd +#define WCD9335_HPH_OCP_CTL 0x06ce +#define WCD9335_HPH_AUTO_CHOP 0x06cf +#define WCD9335_HPH_CHOP_CTL 0x06d0 +#define WCD9335_HPH_PA_CTL1 0x06d1 +#define WCD9335_HPH_PA_CTL2 0x06d2 +#define WCD9335_HPH_L_EN 0x06d3 +#define WCD9335_HPH_L_TEST 0x06d4 +#define WCD9335_HPH_L_ATEST 0x06d5 +#define WCD9335_HPH_R_EN 0x06d6 +#define WCD9335_HPH_R_TEST 0x06d7 +#define WCD9335_HPH_R_ATEST 0x06d8 +#define WCD9335_HPH_RDAC_CLK_CTL1 0x06d9 +#define WCD9335_HPH_RDAC_CLK_CTL2 0x06da +#define WCD9335_HPH_RDAC_LDO_CTL 0x06db +#define WCD9335_HPH_RDAC_CHOP_CLK_LP_CTL 0x06dc +#define WCD9335_HPH_REFBUFF_UHQA_CTL 0x06dd +#define WCD9335_HPH_REFBUFF_LP_CTL 0x06de +#define WCD9335_HPH_L_DAC_CTL 0x06df +#define WCD9335_HPH_R_DAC_CTL 0x06e0 +#define WCD9335_EAR_EN_REG 0x06e1 +#define WCD9335_EAR_CMBUFF 0x06e2 +#define WCD9335_EAR_ICTL 0x06e3 +#define WCD9335_EAR_EN_DBG_CTL 0x06e4 +#define WCD9335_EAR_CNP 0x06e5 +#define WCD9335_EAR_DAC_CTL_ATEST 0x06e6 +#define WCD9335_EAR_STATUS_REG 0x06e7 +#define WCD9335_EAR_OUT_SHORT 0x06e8 +#define WCD9335_DIFF_LO_MISC 0x06e9 +#define WCD9335_DIFF_LO_LO2_COMPANDER 0x06ea +#define WCD9335_DIFF_LO_LO1_COMPANDER 0x06eb +#define WCD9335_DIFF_LO_COMMON 0x06ec +#define WCD9335_DIFF_LO_BYPASS_EN 0x06ed +#define WCD9335_DIFF_LO_CNP 0x06ee +#define WCD9335_DIFF_LO_CORE_OUT_PROG 0x06ef +#define WCD9335_DIFF_LO_LDO_OUT_PROG 0x06f0 +#define WCD9335_DIFF_LO_COM_SWCAP_REFBUF_FREQ 0x06f1 +#define WCD9335_DIFF_LO_COM_PA_FREQ 0x06f2 +#define WCD9335_DIFF_LO_RESERVED_REG 0x06f3 +#define WCD9335_DIFF_LO_LO1_STATUS_1 0x06f4 +#define WCD9335_DIFF_LO_LO1_STATUS_2 0x06f5 +#define WCD9335_SE_LO_COM1 0x06f6 +#define WCD9335_SE_LO_COM2 0x06f7 +#define WCD9335_SE_LO_LO3_GAIN 0x06f8 +#define WCD9335_SE_LO_LO3_CTRL 0x06f9 +#define WCD9335_SE_LO_LO4_GAIN 0x06fa +#define WCD9335_SE_LO_LO4_CTRL 0x06fb +#define WCD9335_SE_LO_LO3_STATUS 0x06fe +#define WCD9335_SE_LO_LO4_STATUS 0x06ff + +/* Page-10 Registers */ +#define WCD9335_PAGE10_PAGE_REGISTER 0x0a00 +#define WCD9335_CDC_ANC0_CLK_RESET_CTL 0x0a01 +#define WCD9335_CDC_ANC0_MODE_1_CTL 0x0a02 +#define WCD9335_CDC_ANC0_MODE_2_CTL 0x0a03 +#define WCD9335_CDC_ANC0_FF_SHIFT 0x0a04 +#define WCD9335_CDC_ANC0_FB_SHIFT 0x0a05 +#define WCD9335_CDC_ANC0_LPF_FF_A_CTL 0x0a06 +#define WCD9335_CDC_ANC0_LPF_FF_B_CTL 0x0a07 +#define WCD9335_CDC_ANC0_LPF_FB_CTL 0x0a08 +#define WCD9335_CDC_ANC0_SMLPF_CTL 0x0a09 +#define WCD9335_CDC_ANC0_DCFLT_SHIFT_CTL 0x0a0a +#define WCD9335_CDC_ANC0_IIR_ADAPT_CTL 0x0a0b +#define WCD9335_CDC_ANC0_IIR_COEFF_1_CTL 0x0a0c +#define WCD9335_CDC_ANC0_IIR_COEFF_2_CTL 0x0a0d +#define WCD9335_CDC_ANC0_FF_A_GAIN_CTL 0x0a0e +#define WCD9335_CDC_ANC0_FF_B_GAIN_CTL 0x0a0f +#define WCD9335_CDC_ANC0_FB_GAIN_CTL 0x0a10 +#define WCD9335_CDC_ANC1_CLK_RESET_CTL 0x0a19 +#define WCD9335_CDC_ANC1_MODE_1_CTL 0x0a1a +#define WCD9335_CDC_ANC1_MODE_2_CTL 0x0a1b +#define WCD9335_CDC_ANC1_FF_SHIFT 0x0a1c +#define WCD9335_CDC_ANC1_FB_SHIFT 0x0a1d +#define WCD9335_CDC_ANC1_LPF_FF_A_CTL 0x0a1e +#define WCD9335_CDC_ANC1_LPF_FF_B_CTL 0x0a1f +#define WCD9335_CDC_ANC1_LPF_FB_CTL 0x0a20 +#define WCD9335_CDC_ANC1_SMLPF_CTL 0x0a21 +#define WCD9335_CDC_ANC1_DCFLT_SHIFT_CTL 0x0a22 +#define WCD9335_CDC_ANC1_IIR_ADAPT_CTL 0x0a23 +#define WCD9335_CDC_ANC1_IIR_COEFF_1_CTL 0x0a24 +#define WCD9335_CDC_ANC1_IIR_COEFF_2_CTL 0x0a25 +#define WCD9335_CDC_ANC1_FF_A_GAIN_CTL 0x0a26 +#define WCD9335_CDC_ANC1_FF_B_GAIN_CTL 0x0a27 +#define WCD9335_CDC_ANC1_FB_GAIN_CTL 0x0a28 +#define WCD9335_CDC_TX0_TX_PATH_CTL 0x0a31 +#define WCD9335_CDC_TX0_TX_PATH_CFG0 0x0a32 +#define WCD9335_CDC_TX0_TX_PATH_CFG1 0x0a33 +#define WCD9335_CDC_TX0_TX_VOL_CTL 0x0a34 +#define WCD9335_CDC_TX0_TX_PATH_192_CTL 0x0a35 +#define WCD9335_CDC_TX0_TX_PATH_192_CFG 0x0a36 +#define WCD9335_CDC_TX0_TX_PATH_SEC0 0x0a37 +#define WCD9335_CDC_TX0_TX_PATH_SEC1 0x0a38 +#define WCD9335_CDC_TX0_TX_PATH_SEC2 0x0a39 +#define WCD9335_CDC_TX0_TX_PATH_SEC3 0x0a3a +#define WCD9335_CDC_TX0_TX_PATH_SEC4 0x0a3b +#define WCD9335_CDC_TX0_TX_PATH_SEC5 0x0a3c +#define WCD9335_CDC_TX0_TX_PATH_SEC6 0x0a3d +#define WCD9335_CDC_TX0_TX_PATH_SEC7 0x0a3e +#define WCD9335_CDC_TX1_TX_PATH_CTL 0x0a41 +#define WCD9335_CDC_TX1_TX_PATH_CFG0 0x0a42 +#define WCD9335_CDC_TX1_TX_PATH_CFG1 0x0a43 +#define WCD9335_CDC_TX1_TX_VOL_CTL 0x0a44 +#define WCD9335_CDC_TX1_TX_PATH_192_CTL 0x0a45 +#define WCD9335_CDC_TX1_TX_PATH_192_CFG 0x0a46 +#define WCD9335_CDC_TX1_TX_PATH_SEC0 0x0a47 +#define WCD9335_CDC_TX1_TX_PATH_SEC1 0x0a48 +#define WCD9335_CDC_TX1_TX_PATH_SEC2 0x0a49 +#define WCD9335_CDC_TX1_TX_PATH_SEC3 0x0a4a +#define WCD9335_CDC_TX1_TX_PATH_SEC4 0x0a4b +#define WCD9335_CDC_TX1_TX_PATH_SEC5 0x0a4c +#define WCD9335_CDC_TX1_TX_PATH_SEC6 0x0a4d +#define WCD9335_CDC_TX2_TX_PATH_CTL 0x0a51 +#define WCD9335_CDC_TX2_TX_PATH_CFG0 0x0a52 +#define WCD9335_CDC_TX2_TX_PATH_CFG1 0x0a53 +#define WCD9335_CDC_TX2_TX_VOL_CTL 0x0a54 +#define WCD9335_CDC_TX2_TX_PATH_192_CTL 0x0a55 +#define WCD9335_CDC_TX2_TX_PATH_192_CFG 0x0a56 +#define WCD9335_CDC_TX2_TX_PATH_SEC0 0x0a57 +#define WCD9335_CDC_TX2_TX_PATH_SEC1 0x0a58 +#define WCD9335_CDC_TX2_TX_PATH_SEC2 0x0a59 +#define WCD9335_CDC_TX2_TX_PATH_SEC3 0x0a5a +#define WCD9335_CDC_TX2_TX_PATH_SEC4 0x0a5b +#define WCD9335_CDC_TX2_TX_PATH_SEC5 0x0a5c +#define WCD9335_CDC_TX2_TX_PATH_SEC6 0x0a5d +#define WCD9335_CDC_TX3_TX_PATH_CTL 0x0a61 +#define WCD9335_CDC_TX3_TX_PATH_CFG0 0x0a62 +#define WCD9335_CDC_TX3_TX_PATH_CFG1 0x0a63 +#define WCD9335_CDC_TX3_TX_VOL_CTL 0x0a64 +#define WCD9335_CDC_TX3_TX_PATH_192_CTL 0x0a65 +#define WCD9335_CDC_TX3_TX_PATH_192_CFG 0x0a66 +#define WCD9335_CDC_TX3_TX_PATH_SEC0 0x0a67 +#define WCD9335_CDC_TX3_TX_PATH_SEC1 0x0a68 +#define WCD9335_CDC_TX3_TX_PATH_SEC2 0x0a69 +#define WCD9335_CDC_TX3_TX_PATH_SEC3 0x0a6a +#define WCD9335_CDC_TX3_TX_PATH_SEC4 0x0a6b +#define WCD9335_CDC_TX3_TX_PATH_SEC5 0x0a6c +#define WCD9335_CDC_TX3_TX_PATH_SEC6 0x0a6d +#define WCD9335_CDC_TX4_TX_PATH_CTL 0x0a71 +#define WCD9335_CDC_TX4_TX_PATH_CFG0 0x0a72 +#define WCD9335_CDC_TX4_TX_PATH_CFG1 0x0a73 +#define WCD9335_CDC_TX4_TX_VOL_CTL 0x0a74 +#define WCD9335_CDC_TX4_TX_PATH_192_CTL 0x0a75 +#define WCD9335_CDC_TX4_TX_PATH_192_CFG 0x0a76 +#define WCD9335_CDC_TX4_TX_PATH_SEC0 0x0a77 +#define WCD9335_CDC_TX4_TX_PATH_SEC1 0x0a78 +#define WCD9335_CDC_TX4_TX_PATH_SEC2 0x0a79 +#define WCD9335_CDC_TX4_TX_PATH_SEC3 0x0a7a +#define WCD9335_CDC_TX4_TX_PATH_SEC4 0x0a7b +#define WCD9335_CDC_TX4_TX_PATH_SEC5 0x0a7c +#define WCD9335_CDC_TX4_TX_PATH_SEC6 0x0a7d +#define WCD9335_CDC_TX5_TX_PATH_CTL 0x0a81 +#define WCD9335_CDC_TX5_TX_PATH_CFG0 0x0a82 +#define WCD9335_CDC_TX5_TX_PATH_CFG1 0x0a83 +#define WCD9335_CDC_TX5_TX_VOL_CTL 0x0a84 +#define WCD9335_CDC_TX5_TX_PATH_192_CTL 0x0a85 +#define WCD9335_CDC_TX5_TX_PATH_192_CFG 0x0a86 +#define WCD9335_CDC_TX5_TX_PATH_SEC0 0x0a87 +#define WCD9335_CDC_TX5_TX_PATH_SEC1 0x0a88 +#define WCD9335_CDC_TX5_TX_PATH_SEC2 0x0a89 +#define WCD9335_CDC_TX5_TX_PATH_SEC3 0x0a8a +#define WCD9335_CDC_TX5_TX_PATH_SEC4 0x0a8b +#define WCD9335_CDC_TX5_TX_PATH_SEC5 0x0a8c +#define WCD9335_CDC_TX5_TX_PATH_SEC6 0x0a8d +#define WCD9335_CDC_TX6_TX_PATH_CTL 0x0a91 +#define WCD9335_CDC_TX6_TX_PATH_CFG0 0x0a92 +#define WCD9335_CDC_TX6_TX_PATH_CFG1 0x0a93 +#define WCD9335_CDC_TX6_TX_VOL_CTL 0x0a94 +#define WCD9335_CDC_TX6_TX_PATH_192_CTL 0x0a95 +#define WCD9335_CDC_TX6_TX_PATH_192_CFG 0x0a96 +#define WCD9335_CDC_TX6_TX_PATH_SEC0 0x0a97 +#define WCD9335_CDC_TX6_TX_PATH_SEC1 0x0a98 +#define WCD9335_CDC_TX6_TX_PATH_SEC2 0x0a99 +#define WCD9335_CDC_TX6_TX_PATH_SEC3 0x0a9a +#define WCD9335_CDC_TX6_TX_PATH_SEC4 0x0a9b +#define WCD9335_CDC_TX6_TX_PATH_SEC5 0x0a9c +#define WCD9335_CDC_TX6_TX_PATH_SEC6 0x0a9d +#define WCD9335_CDC_TX7_TX_PATH_CTL 0x0aa1 +#define WCD9335_CDC_TX7_TX_PATH_CFG0 0x0aa2 +#define WCD9335_CDC_TX7_TX_PATH_CFG1 0x0aa3 +#define WCD9335_CDC_TX7_TX_VOL_CTL 0x0aa4 +#define WCD9335_CDC_TX7_TX_PATH_192_CTL 0x0aa5 +#define WCD9335_CDC_TX7_TX_PATH_192_CFG 0x0aa6 +#define WCD9335_CDC_TX7_TX_PATH_SEC0 0x0aa7 +#define WCD9335_CDC_TX7_TX_PATH_SEC1 0x0aa8 +#define WCD9335_CDC_TX7_TX_PATH_SEC2 0x0aa9 +#define WCD9335_CDC_TX7_TX_PATH_SEC3 0x0aaa +#define WCD9335_CDC_TX7_TX_PATH_SEC4 0x0aab +#define WCD9335_CDC_TX7_TX_PATH_SEC5 0x0aac +#define WCD9335_CDC_TX7_TX_PATH_SEC6 0x0aad +#define WCD9335_CDC_TX8_TX_PATH_CTL 0x0ab1 +#define WCD9335_CDC_TX8_TX_PATH_CFG0 0x0ab2 +#define WCD9335_CDC_TX8_TX_PATH_CFG1 0x0ab3 +#define WCD9335_CDC_TX8_TX_VOL_CTL 0x0ab4 +#define WCD9335_CDC_TX8_TX_PATH_192_CTL 0x0ab5 +#define WCD9335_CDC_TX8_TX_PATH_192_CFG 0x0ab6 +#define WCD9335_CDC_TX8_TX_PATH_SEC0 0x0ab7 +#define WCD9335_CDC_TX8_TX_PATH_SEC1 0x0ab8 +#define WCD9335_CDC_TX8_TX_PATH_SEC2 0x0ab9 +#define WCD9335_CDC_TX8_TX_PATH_SEC3 0x0aba +#define WCD9335_CDC_TX8_TX_PATH_SEC4 0x0abb +#define WCD9335_CDC_TX8_TX_PATH_SEC5 0x0abc +#define WCD9335_CDC_TX8_TX_PATH_SEC6 0x0abd +#define WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL 0x0ac2 +#define WCD9335_CDC_TX9_SPKR_PROT_PATH_CFG0 0x0ac3 +#define WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL 0x0ac6 +#define WCD9335_CDC_TX10_SPKR_PROT_PATH_CFG0 0x0ac7 +#define WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL 0x0aca +#define WCD9335_CDC_TX11_SPKR_PROT_PATH_CFG0 0x0acb +#define WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL 0x0ace +#define WCD9335_CDC_TX12_SPKR_PROT_PATH_CFG0 0x0acf + +/* Page-11 Registers */ +#define WCD9335_PAGE11_PAGE_REGISTER 0x0b00 +#define WCD9335_CDC_COMPANDER1_CTL0 0x0b01 +#define WCD9335_CDC_COMPANDER1_CTL1 0x0b02 +#define WCD9335_CDC_COMPANDER1_CTL2 0x0b03 +#define WCD9335_CDC_COMPANDER1_CTL3 0x0b04 +#define WCD9335_CDC_COMPANDER1_CTL4 0x0b05 +#define WCD9335_CDC_COMPANDER1_CTL5 0x0b06 +#define WCD9335_CDC_COMPANDER1_CTL6 0x0b07 +#define WCD9335_CDC_COMPANDER1_CTL7 0x0b08 +#define WCD9335_CDC_COMPANDER2_CTL0 0x0b09 +#define WCD9335_CDC_COMPANDER2_CTL1 0x0b0a +#define WCD9335_CDC_COMPANDER2_CTL2 0x0b0b +#define WCD9335_CDC_COMPANDER2_CTL3 0x0b0c +#define WCD9335_CDC_COMPANDER2_CTL4 0x0b0d +#define WCD9335_CDC_COMPANDER2_CTL5 0x0b0e +#define WCD9335_CDC_COMPANDER2_CTL6 0x0b0f +#define WCD9335_CDC_COMPANDER2_CTL7 0x0b10 +#define WCD9335_CDC_COMPANDER3_CTL0 0x0b11 +#define WCD9335_CDC_COMPANDER3_CTL1 0x0b12 +#define WCD9335_CDC_COMPANDER3_CTL2 0x0b13 +#define WCD9335_CDC_COMPANDER3_CTL3 0x0b14 +#define WCD9335_CDC_COMPANDER3_CTL4 0x0b15 +#define WCD9335_CDC_COMPANDER3_CTL5 0x0b16 +#define WCD9335_CDC_COMPANDER3_CTL6 0x0b17 +#define WCD9335_CDC_COMPANDER3_CTL7 0x0b18 +#define WCD9335_CDC_COMPANDER4_CTL0 0x0b19 +#define WCD9335_CDC_COMPANDER4_CTL1 0x0b1a +#define WCD9335_CDC_COMPANDER4_CTL2 0x0b1b +#define WCD9335_CDC_COMPANDER4_CTL3 0x0b1c +#define WCD9335_CDC_COMPANDER4_CTL4 0x0b1d +#define WCD9335_CDC_COMPANDER4_CTL5 0x0b1e +#define WCD9335_CDC_COMPANDER4_CTL6 0x0b1f +#define WCD9335_CDC_COMPANDER4_CTL7 0x0b20 +#define WCD9335_CDC_COMPANDER5_CTL0 0x0b21 +#define WCD9335_CDC_COMPANDER5_CTL1 0x0b22 +#define WCD9335_CDC_COMPANDER5_CTL2 0x0b23 +#define WCD9335_CDC_COMPANDER5_CTL3 0x0b24 +#define WCD9335_CDC_COMPANDER5_CTL4 0x0b25 +#define WCD9335_CDC_COMPANDER5_CTL5 0x0b26 +#define WCD9335_CDC_COMPANDER5_CTL6 0x0b27 +#define WCD9335_CDC_COMPANDER5_CTL7 0x0b28 +#define WCD9335_CDC_COMPANDER6_CTL0 0x0b29 +#define WCD9335_CDC_COMPANDER6_CTL1 0x0b2a +#define WCD9335_CDC_COMPANDER6_CTL2 0x0b2b +#define WCD9335_CDC_COMPANDER6_CTL3 0x0b2c +#define WCD9335_CDC_COMPANDER6_CTL4 0x0b2d +#define WCD9335_CDC_COMPANDER6_CTL5 0x0b2e +#define WCD9335_CDC_COMPANDER6_CTL6 0x0b2f +#define WCD9335_CDC_COMPANDER6_CTL7 0x0b30 +#define WCD9335_CDC_COMPANDER7_CTL0 0x0b31 +#define WCD9335_CDC_COMPANDER7_CTL1 0x0b32 +#define WCD9335_CDC_COMPANDER7_CTL2 0x0b33 +#define WCD9335_CDC_COMPANDER7_CTL3 0x0b34 +#define WCD9335_CDC_COMPANDER7_CTL4 0x0b35 +#define WCD9335_CDC_COMPANDER7_CTL5 0x0b36 +#define WCD9335_CDC_COMPANDER7_CTL6 0x0b37 +#define WCD9335_CDC_COMPANDER7_CTL7 0x0b38 +#define WCD9335_CDC_COMPANDER8_CTL0 0x0b39 +#define WCD9335_CDC_COMPANDER8_CTL1 0x0b3a +#define WCD9335_CDC_COMPANDER8_CTL2 0x0b3b +#define WCD9335_CDC_COMPANDER8_CTL3 0x0b3c +#define WCD9335_CDC_COMPANDER8_CTL4 0x0b3d +#define WCD9335_CDC_COMPANDER8_CTL5 0x0b3e +#define WCD9335_CDC_COMPANDER8_CTL6 0x0b3f +#define WCD9335_CDC_COMPANDER8_CTL7 0x0b40 +#define WCD9335_CDC_RX0_RX_PATH_CTL 0x0b41 +#define WCD9335_CDC_RX0_RX_PATH_CFG0 0x0b42 +#define WCD9335_CDC_RX0_RX_PATH_CFG1 0x0b43 +#define WCD9335_CDC_RX0_RX_PATH_CFG2 0x0b44 +#define WCD9335_CDC_RX0_RX_VOL_CTL 0x0b45 +#define WCD9335_CDC_RX0_RX_PATH_MIX_CTL 0x0b46 +#define WCD9335_CDC_RX0_RX_PATH_MIX_CFG 0x0b47 +#define WCD9335_CDC_RX0_RX_VOL_MIX_CTL 0x0b48 +#define WCD9335_CDC_RX0_RX_PATH_SEC0 0x0b49 +#define WCD9335_CDC_RX0_RX_PATH_SEC1 0x0b4a +#define WCD9335_CDC_RX0_RX_PATH_SEC2 0x0b4b +#define WCD9335_CDC_RX0_RX_PATH_SEC3 0x0b4c +#define WCD9335_CDC_RX0_RX_PATH_SEC5 0x0b4e +#define WCD9335_CDC_RX0_RX_PATH_SEC6 0x0b4f +#define WCD9335_CDC_RX0_RX_PATH_SEC7 0x0b50 +#define WCD9335_CDC_RX0_RX_PATH_MIX_SEC0 0x0b51 +#define WCD9335_CDC_RX0_RX_PATH_MIX_SEC1 0x0b52 +#define WCD9335_CDC_RX1_RX_PATH_CTL 0x0b55 +#define WCD9335_CDC_RX1_RX_PATH_CFG0 0x0b56 +#define WCD9335_CDC_RX1_RX_PATH_CFG1 0x0b57 +#define WCD9335_CDC_RX1_RX_PATH_CFG2 0x0b58 +#define WCD9335_CDC_RX1_RX_VOL_CTL 0x0b59 +#define WCD9335_CDC_RX1_RX_PATH_MIX_CTL 0x0b5a +#define WCD9335_CDC_RX1_RX_PATH_MIX_CFG 0x0b5b +#define WCD9335_CDC_RX1_RX_VOL_MIX_CTL 0x0b5c +#define WCD9335_CDC_RX1_RX_PATH_SEC0 0x0b5d +#define WCD9335_CDC_RX1_RX_PATH_SEC1 0x0b5e +#define WCD9335_CDC_RX1_RX_PATH_SEC2 0x0b5f +#define WCD9335_CDC_RX1_RX_PATH_SEC3 0x0b60 +#define WCD9335_CDC_RX1_RX_PATH_SEC4 0x0b61 +#define WCD9335_CDC_RX1_RX_PATH_SEC5 0x0b62 +#define WCD9335_CDC_RX1_RX_PATH_SEC6 0x0b63 +#define WCD9335_CDC_RX1_RX_PATH_SEC7 0x0b64 +#define WCD9335_CDC_RX1_RX_PATH_MIX_SEC0 0x0b65 +#define WCD9335_CDC_RX1_RX_PATH_MIX_SEC1 0x0b66 +#define WCD9335_CDC_RX2_RX_PATH_CTL 0x0b69 +#define WCD9335_CDC_RX2_RX_PATH_CFG0 0x0b6a +#define WCD9335_CDC_RX2_RX_PATH_CFG1 0x0b6b +#define WCD9335_CDC_RX2_RX_PATH_CFG2 0x0b6c +#define WCD9335_CDC_RX2_RX_VOL_CTL 0x0b6d +#define WCD9335_CDC_RX2_RX_PATH_MIX_CTL 0x0b6e +#define WCD9335_CDC_RX2_RX_PATH_MIX_CFG 0x0b6f +#define WCD9335_CDC_RX2_RX_VOL_MIX_CTL 0x0b70 +#define WCD9335_CDC_RX2_RX_PATH_SEC0 0x0b71 +#define WCD9335_CDC_RX2_RX_PATH_SEC1 0x0b72 +#define WCD9335_CDC_RX2_RX_PATH_SEC2 0x0b73 +#define WCD9335_CDC_RX2_RX_PATH_SEC3 0x0b74 +#define WCD9335_CDC_RX2_RX_PATH_SEC4 0x0b75 +#define WCD9335_CDC_RX2_RX_PATH_SEC5 0x0b76 +#define WCD9335_CDC_RX2_RX_PATH_SEC6 0x0b77 +#define WCD9335_CDC_RX2_RX_PATH_SEC7 0x0b78 +#define WCD9335_CDC_RX2_RX_PATH_MIX_SEC0 0x0b79 +#define WCD9335_CDC_RX2_RX_PATH_MIX_SEC1 0x0b7a +#define WCD9335_CDC_RX3_RX_PATH_CTL 0x0b7d +#define WCD9335_CDC_RX3_RX_PATH_CFG0 0x0b7e +#define WCD9335_CDC_RX3_RX_PATH_CFG1 0x0b7f +#define WCD9335_CDC_RX3_RX_PATH_CFG2 0x0b80 +#define WCD9335_CDC_RX3_RX_VOL_CTL 0x0b81 +#define WCD9335_CDC_RX3_RX_PATH_MIX_CTL 0x0b82 +#define WCD9335_CDC_RX3_RX_PATH_MIX_CFG 0x0b83 +#define WCD9335_CDC_RX3_RX_VOL_MIX_CTL 0x0b84 +#define WCD9335_CDC_RX3_RX_PATH_SEC0 0x0b85 +#define WCD9335_CDC_RX3_RX_PATH_SEC1 0x0b86 +#define WCD9335_CDC_RX3_RX_PATH_SEC2 0x0b87 +#define WCD9335_CDC_RX3_RX_PATH_SEC3 0x0b88 +#define WCD9335_CDC_RX3_RX_PATH_SEC5 0x0b8a +#define WCD9335_CDC_RX3_RX_PATH_SEC6 0x0b8b +#define WCD9335_CDC_RX3_RX_PATH_SEC7 0x0b8c +#define WCD9335_CDC_RX3_RX_PATH_MIX_SEC0 0x0b8d +#define WCD9335_CDC_RX3_RX_PATH_MIX_SEC1 0x0b8e +#define WCD9335_CDC_RX4_RX_PATH_CTL 0x0b91 +#define WCD9335_CDC_RX4_RX_PATH_CFG0 0x0b92 +#define WCD9335_CDC_RX4_RX_PATH_CFG1 0x0b93 +#define WCD9335_CDC_RX4_RX_PATH_CFG2 0x0b94 +#define WCD9335_CDC_RX4_RX_VOL_CTL 0x0b95 +#define WCD9335_CDC_RX4_RX_PATH_MIX_CTL 0x0b96 +#define WCD9335_CDC_RX4_RX_PATH_MIX_CFG 0x0b97 +#define WCD9335_CDC_RX4_RX_VOL_MIX_CTL 0x0b98 +#define WCD9335_CDC_RX4_RX_PATH_SEC0 0x0b99 +#define WCD9335_CDC_RX4_RX_PATH_SEC1 0x0b9a +#define WCD9335_CDC_RX4_RX_PATH_SEC2 0x0b9b +#define WCD9335_CDC_RX4_RX_PATH_SEC3 0x0b9c +#define WCD9335_CDC_RX4_RX_PATH_SEC5 0x0b9e +#define WCD9335_CDC_RX4_RX_PATH_SEC6 0x0b9f +#define WCD9335_CDC_RX4_RX_PATH_SEC7 0x0ba0 +#define WCD9335_CDC_RX4_RX_PATH_MIX_SEC0 0x0ba1 +#define WCD9335_CDC_RX4_RX_PATH_MIX_SEC1 0x0ba2 +#define WCD9335_CDC_RX5_RX_PATH_CTL 0x0ba5 +#define WCD9335_CDC_RX5_RX_PATH_CFG0 0x0ba6 +#define WCD9335_CDC_RX5_RX_PATH_CFG1 0x0ba7 +#define WCD9335_CDC_RX5_RX_PATH_CFG2 0x0ba8 +#define WCD9335_CDC_RX5_RX_VOL_CTL 0x0ba9 +#define WCD9335_CDC_RX5_RX_PATH_MIX_CTL 0x0baa +#define WCD9335_CDC_RX5_RX_PATH_MIX_CFG 0x0bab +#define WCD9335_CDC_RX5_RX_VOL_MIX_CTL 0x0bac +#define WCD9335_CDC_RX5_RX_PATH_SEC0 0x0bad +#define WCD9335_CDC_RX5_RX_PATH_SEC1 0x0bae +#define WCD9335_CDC_RX5_RX_PATH_SEC2 0x0baf +#define WCD9335_CDC_RX5_RX_PATH_SEC3 0x0bb0 +#define WCD9335_CDC_RX5_RX_PATH_SEC5 0x0bb2 +#define WCD9335_CDC_RX5_RX_PATH_SEC6 0x0bb3 +#define WCD9335_CDC_RX5_RX_PATH_SEC7 0x0bb4 +#define WCD9335_CDC_RX5_RX_PATH_MIX_SEC0 0x0bb5 +#define WCD9335_CDC_RX5_RX_PATH_MIX_SEC1 0x0bb6 +#define WCD9335_CDC_RX6_RX_PATH_CTL 0x0bb9 +#define WCD9335_CDC_RX6_RX_PATH_CFG0 0x0bba +#define WCD9335_CDC_RX6_RX_PATH_CFG1 0x0bbb +#define WCD9335_CDC_RX6_RX_PATH_CFG2 0x0bbc +#define WCD9335_CDC_RX6_RX_VOL_CTL 0x0bbd +#define WCD9335_CDC_RX6_RX_PATH_MIX_CTL 0x0bbe +#define WCD9335_CDC_RX6_RX_PATH_MIX_CFG 0x0bbf +#define WCD9335_CDC_RX6_RX_VOL_MIX_CTL 0x0bc0 +#define WCD9335_CDC_RX6_RX_PATH_SEC0 0x0bc1 +#define WCD9335_CDC_RX6_RX_PATH_SEC1 0x0bc2 +#define WCD9335_CDC_RX6_RX_PATH_SEC2 0x0bc3 +#define WCD9335_CDC_RX6_RX_PATH_SEC3 0x0bc4 +#define WCD9335_CDC_RX6_RX_PATH_SEC5 0x0bc6 +#define WCD9335_CDC_RX6_RX_PATH_SEC6 0x0bc7 +#define WCD9335_CDC_RX6_RX_PATH_SEC7 0x0bc8 +#define WCD9335_CDC_RX6_RX_PATH_MIX_SEC0 0x0bc9 +#define WCD9335_CDC_RX6_RX_PATH_MIX_SEC1 0x0bca +#define WCD9335_CDC_RX7_RX_PATH_CTL 0x0bcd +#define WCD9335_CDC_RX7_RX_PATH_CFG0 0x0bce +#define WCD9335_CDC_RX7_RX_PATH_CFG1 0x0bcf +#define WCD9335_CDC_RX7_RX_PATH_CFG2 0x0bd0 +#define WCD9335_CDC_RX7_RX_VOL_CTL 0x0bd1 +#define WCD9335_CDC_RX7_RX_PATH_MIX_CTL 0x0bd2 +#define WCD9335_CDC_RX7_RX_PATH_MIX_CFG 0x0bd3 +#define WCD9335_CDC_RX7_RX_VOL_MIX_CTL 0x0bd4 +#define WCD9335_CDC_RX7_RX_PATH_SEC0 0x0bd5 +#define WCD9335_CDC_RX7_RX_PATH_SEC1 0x0bd6 +#define WCD9335_CDC_RX7_RX_PATH_SEC2 0x0bd7 +#define WCD9335_CDC_RX7_RX_PATH_SEC3 0x0bd8 +#define WCD9335_CDC_RX7_RX_PATH_SEC5 0x0bda +#define WCD9335_CDC_RX7_RX_PATH_SEC6 0x0bdb +#define WCD9335_CDC_RX7_RX_PATH_SEC7 0x0bdc +#define WCD9335_CDC_RX7_RX_PATH_MIX_SEC0 0x0bdd +#define WCD9335_CDC_RX7_RX_PATH_MIX_SEC1 0x0bde +#define WCD9335_CDC_RX8_RX_PATH_CTL 0x0be1 +#define WCD9335_CDC_RX8_RX_PATH_CFG0 0x0be2 +#define WCD9335_CDC_RX8_RX_PATH_CFG1 0x0be3 +#define WCD9335_CDC_RX8_RX_PATH_CFG2 0x0be4 +#define WCD9335_CDC_RX8_RX_VOL_CTL 0x0be5 +#define WCD9335_CDC_RX8_RX_PATH_MIX_CTL 0x0be6 +#define WCD9335_CDC_RX8_RX_PATH_MIX_CFG 0x0be7 +#define WCD9335_CDC_RX8_RX_VOL_MIX_CTL 0x0be8 +#define WCD9335_CDC_RX8_RX_PATH_SEC0 0x0be9 +#define WCD9335_CDC_RX8_RX_PATH_SEC1 0x0bea +#define WCD9335_CDC_RX8_RX_PATH_SEC2 0x0beb +#define WCD9335_CDC_RX8_RX_PATH_SEC3 0x0bec +#define WCD9335_CDC_RX8_RX_PATH_SEC5 0x0bee +#define WCD9335_CDC_RX8_RX_PATH_SEC6 0x0bef +#define WCD9335_CDC_RX8_RX_PATH_SEC7 0x0bf0 +#define WCD9335_CDC_RX8_RX_PATH_MIX_SEC0 0x0bf1 +#define WCD9335_CDC_RX8_RX_PATH_MIX_SEC1 0x0bf2 + +/* Page-12 Registers */ +#define WCD9335_PAGE12_PAGE_REGISTER 0x0c00 +#define WCD9335_CDC_CLSH_CRC 0x0c01 +#define WCD9335_CDC_CLSH_DLY_CTRL 0x0c02 +#define WCD9335_CDC_CLSH_DECAY_CTRL 0x0c03 +#define WCD9335_CDC_CLSH_HPH_V_PA 0x0c04 +#define WCD9335_CDC_CLSH_EAR_V_PA 0x0c05 +#define WCD9335_CDC_CLSH_HPH_V_HD 0x0c06 +#define WCD9335_CDC_CLSH_EAR_V_HD 0x0c07 +#define WCD9335_CDC_CLSH_K1_MSB 0x0c08 +#define WCD9335_CDC_CLSH_K1_LSB 0x0c09 +#define WCD9335_CDC_CLSH_K2_MSB 0x0c0a +#define WCD9335_CDC_CLSH_K2_LSB 0x0c0b +#define WCD9335_CDC_CLSH_IDLE_CTRL 0x0c0c +#define WCD9335_CDC_CLSH_IDLE_HPH 0x0c0d +#define WCD9335_CDC_CLSH_IDLE_EAR 0x0c0e +#define WCD9335_CDC_CLSH_TEST0 0x0c0f +#define WCD9335_CDC_CLSH_TEST1 0x0c10 +#define WCD9335_CDC_CLSH_OVR_VREF 0x0c11 +#define WCD9335_CDC_BOOST0_BOOST_PATH_CTL 0x0c19 +#define WCD9335_CDC_BOOST0_BOOST_CTL 0x0c1a +#define WCD9335_CDC_BOOST0_BOOST_CFG1 0x0c1b +#define WCD9335_CDC_BOOST0_BOOST_CFG2 0x0c1c +#define WCD9335_CDC_BOOST1_BOOST_PATH_CTL 0x0c21 +#define WCD9335_CDC_BOOST1_BOOST_CTL 0x0c22 +#define WCD9335_CDC_BOOST1_BOOST_CFG1 0x0c23 +#define WCD9335_CDC_BOOST1_BOOST_CFG2 0x0c24 +#define WCD9335_SWR_AHB_BRIDGE_WR_DATA_0 0x0c29 +#define WCD9335_SWR_AHB_BRIDGE_WR_DATA_1 0x0c2a +#define WCD9335_SWR_AHB_BRIDGE_WR_DATA_2 0x0c2b +#define WCD9335_SWR_AHB_BRIDGE_WR_DATA_3 0x0c2c +#define WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0 0x0c2d +#define WCD9335_SWR_AHB_BRIDGE_WR_ADDR_1 0x0c2e +#define WCD9335_SWR_AHB_BRIDGE_WR_ADDR_2 0x0c2f +#define WCD9335_SWR_AHB_BRIDGE_WR_ADDR_3 0x0c30 +#define WCD9335_SWR_AHB_BRIDGE_RD_ADDR_0 0x0c31 +#define WCD9335_SWR_AHB_BRIDGE_RD_ADDR_1 0x0c32 +#define WCD9335_SWR_AHB_BRIDGE_RD_ADDR_2 0x0c33 +#define WCD9335_SWR_AHB_BRIDGE_RD_ADDR_3 0x0c34 +#define WCD9335_SWR_AHB_BRIDGE_RD_DATA_0 0x0c35 +#define WCD9335_SWR_AHB_BRIDGE_RD_DATA_1 0x0c36 +#define WCD9335_SWR_AHB_BRIDGE_RD_DATA_2 0x0c37 +#define WCD9335_SWR_AHB_BRIDGE_RD_DATA_3 0x0c38 +#define WCD9335_SWR_AHB_BRIDGE_ACCESS_CFG 0x0c39 +#define WCD9335_SWR_AHB_BRIDGE_ACCESS_STATUS 0x0c3a +#define WCD9335_CDC_VBAT_VBAT_PATH_CTL 0x0c3d +#define WCD9335_CDC_VBAT_VBAT_CFG 0x0c3e +#define WCD9335_CDC_VBAT_VBAT_ADC_CAL1 0x0c3f +#define WCD9335_CDC_VBAT_VBAT_ADC_CAL2 0x0c40 +#define WCD9335_CDC_VBAT_VBAT_ADC_CAL3 0x0c41 +#define WCD9335_CDC_VBAT_VBAT_PK_EST1 0x0c42 +#define WCD9335_CDC_VBAT_VBAT_PK_EST2 0x0c43 +#define WCD9335_CDC_VBAT_VBAT_PK_EST3 0x0c44 +#define WCD9335_CDC_VBAT_VBAT_RF_PROC1 0x0c45 +#define WCD9335_CDC_VBAT_VBAT_RF_PROC2 0x0c46 +#define WCD9335_CDC_VBAT_VBAT_TAC1 0x0c47 +#define WCD9335_CDC_VBAT_VBAT_TAC2 0x0c48 +#define WCD9335_CDC_VBAT_VBAT_TAC3 0x0c49 +#define WCD9335_CDC_VBAT_VBAT_TAC4 0x0c4a +#define WCD9335_CDC_VBAT_VBAT_GAIN_UPD1 0x0c4b +#define WCD9335_CDC_VBAT_VBAT_GAIN_UPD2 0x0c4c +#define WCD9335_CDC_VBAT_VBAT_GAIN_UPD3 0x0c4d +#define WCD9335_CDC_VBAT_VBAT_GAIN_UPD4 0x0c4e +#define WCD9335_CDC_VBAT_VBAT_DEBUG1 0x0c4f +#define WCD9335_CDC_VBAT_VBAT_GAIN_UPD_MON 0x0c50 +#define WCD9335_CDC_VBAT_VBAT_GAIN_MON_VAL 0x0c51 +#define WCD9335_SPLINE_SRC0_CLK_RST_CTL_0 0x0c55 +#define WCD9335_SPLINE_SRC0_STATUS 0x0c56 +#define WCD9335_SPLINE_SRC1_CLK_RST_CTL_0 0x0c6d +#define WCD9335_SPLINE_SRC1_STATUS 0x0c6e +#define WCD9335_SPLINE_SRC2_CLK_RST_CTL_0 0x0c85 +#define WCD9335_SPLINE_SRC2_STATUS 0x0c86 +#define WCD9335_SPLINE_SRC3_CLK_RST_CTL_0 0x0c9d +#define WCD9335_SPLINE_SRC3_STATUS 0x0c9e +#define WCD9335_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL 0x0cb5 +#define WCD9335_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1 0x0cb6 +#define WCD9335_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL 0x0cb9 +#define WCD9335_CDC_SIDETONE_SRC1_ST_SRC_PATH_CFG1 0x0cba + +/* Page-13 Registers */ +#define WCD9335_PAGE13_PAGE_REGISTER 0x0d00 +#define WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0 0x0d01 +#define WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1 0x0d02 +#define WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0 0x0d03 +#define WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1 0x0d04 +#define WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0 0x0d05 +#define WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1 0x0d06 +#define WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0 0x0d07 +#define WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1 0x0d08 +#define WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0 0x0d09 +#define WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1 0x0d0a +#define WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0 0x0d0b +#define WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1 0x0d0c +#define WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0 0x0d0d +#define WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1 0x0d0e +#define WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0 0x0d0f +#define WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1 0x0d10 +#define WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0 0x0d11 +#define WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1 0x0d12 +#define WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG0 0x0d13 +#define WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG1 0x0d14 +#define WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG2 0x0d15 +#define WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG3 0x0d16 +#define WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG4 0x0d17 +#define WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0 0x0d18 +#define WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1 0x0d19 +#define WCD9335_CDC_RX_INP_MUX_ANC_CFG0 0x0d1a +#define WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0 0x0d1b +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 0x0d1d +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1 0x0d1e +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0 0x0d1f +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1 0x0d20 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0 0x0d21 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1 0x0d22 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0 0x0d23 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1 0x0d24 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 0x0d25 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0 0x0d26 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0 0x0d27 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0 0x0d28 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0 0x0d29 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0 0x0d2b +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0 0x0d2c +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0 0x0d2d +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0 0x0d2e +#define WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0 0x0d31 +#define WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1 0x0d32 +#define WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2 0x0d33 +#define WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3 0x0d34 +#define WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0 0x0d35 +#define WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1 0x0d36 +#define WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2 0x0d37 +#define WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3 0x0d38 +#define WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0 0x0d3a +#define WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1 0x0d3b +#define WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2 0x0d3c +#define WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3 0x0d3d +#define WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL 0x0d41 +#define WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL 0x0d42 +#define WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL 0x0d43 +#define WCD9335_CDC_PROX_DETECT_PROX_CTL 0x0d49 +#define WCD9335_CDC_PROX_DETECT_PROX_POLL_PERIOD0 0x0d4a +#define WCD9335_CDC_PROX_DETECT_PROX_POLL_PERIOD1 0x0d4b +#define WCD9335_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB 0x0d4c +#define WCD9335_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB 0x0d4d +#define WCD9335_CDC_PROX_DETECT_PROX_STATUS 0x0d4e +#define WCD9335_CDC_PROX_DETECT_PROX_TEST_CTRL 0x0d4f +#define WCD9335_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB 0x0d50 +#define WCD9335_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB 0x0d51 +#define WCD9335_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD 0x0d52 +#define WCD9335_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD 0x0d53 +#define WCD9335_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT 0x0d54 +#define WCD9335_CDC_SIDETONE_IIR0_IIR_PATH_CTL 0x0d55 +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL 0x0d56 +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL 0x0d57 +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL 0x0d58 +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL 0x0d59 +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL 0x0d5a +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL 0x0d5b +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL 0x0d5c +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL 0x0d5d +#define WCD9335_CDC_SIDETONE_IIR0_IIR_CTL 0x0d5e +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL 0x0d5f +#define WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL 0x0d60 +#define WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL 0x0d61 +#define WCD9335_CDC_SIDETONE_IIR1_IIR_PATH_CTL 0x0d65 +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL 0x0d66 +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL 0x0d67 +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL 0x0d68 +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL 0x0d69 +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B5_CTL 0x0d6a +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B6_CTL 0x0d6b +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B7_CTL 0x0d6c +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B8_CTL 0x0d6d +#define WCD9335_CDC_SIDETONE_IIR1_IIR_CTL 0x0d6e +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL 0x0d6f +#define WCD9335_CDC_SIDETONE_IIR1_IIR_COEF_B1_CTL 0x0d70 +#define WCD9335_CDC_SIDETONE_IIR1_IIR_COEF_B2_CTL 0x0d71 +#define WCD9335_CDC_TOP_TOP_CFG0 0x0d81 +#define WCD9335_CDC_TOP_TOP_CFG1 0x0d82 +#define WCD9335_CDC_TOP_TOP_CFG2 0x0d83 +#define WCD9335_CDC_TOP_TOP_CFG3 0x0d84 +#define WCD9335_CDC_TOP_TOP_CFG4 0x0d85 +#define WCD9335_CDC_TOP_TOP_CFG5 0x0d86 +#define WCD9335_CDC_TOP_TOP_CFG6 0x0d87 +#define WCD9335_CDC_TOP_TOP_CFG7 0x0d88 +#define WCD9335_CDC_TOP_HPHL_COMP_WR_LSB 0x0d89 +#define WCD9335_CDC_TOP_HPHL_COMP_WR_MSB 0x0d8a +#define WCD9335_CDC_TOP_HPHL_COMP_LUT 0x0d8b +#define WCD9335_CDC_TOP_HPHL_COMP_RD_LSB 0x0d8c +#define WCD9335_CDC_TOP_HPHL_COMP_RD_MSB 0x0d8d +#define WCD9335_CDC_TOP_HPHR_COMP_WR_LSB 0x0d8e +#define WCD9335_CDC_TOP_HPHR_COMP_WR_MSB 0x0d8f +#define WCD9335_CDC_TOP_HPHR_COMP_LUT 0x0d90 +#define WCD9335_CDC_TOP_HPHR_COMP_RD_LSB 0x0d91 +#define WCD9335_CDC_TOP_HPHR_COMP_RD_MSB 0x0d92 +#define WCD9335_CDC_TOP_DIFFL_COMP_WR_LSB 0x0d93 +#define WCD9335_CDC_TOP_DIFFL_COMP_WR_MSB 0x0d94 +#define WCD9335_CDC_TOP_DIFFL_COMP_LUT 0x0d95 +#define WCD9335_CDC_TOP_DIFFL_COMP_RD_LSB 0x0d96 +#define WCD9335_CDC_TOP_DIFFL_COMP_RD_MSB 0x0d97 +#define WCD9335_CDC_TOP_DIFFR_COMP_WR_LSB 0x0d98 +#define WCD9335_CDC_TOP_DIFFR_COMP_WR_MSB 0x0d99 +#define WCD9335_CDC_TOP_DIFFR_COMP_LUT 0x0d9a +#define WCD9335_CDC_TOP_DIFFR_COMP_RD_LSB 0x0d9b +#define WCD9335_CDC_TOP_DIFFR_COMP_RD_MSB 0x0d9c + +/* Page-0x80 Registers */ +#define WCD9335_PAGE80_PAGE_REGISTER 0x8000 +#define WCD9335_TLMM_BIST_MODE_PINCFG 0x8001 +#define WCD9335_TLMM_RF_PA_ON_PINCFG 0x8002 +#define WCD9335_TLMM_INTR1_PINCFG 0x8003 +#define WCD9335_TLMM_INTR2_PINCFG 0x8004 +#define WCD9335_TLMM_SWR_DATA_PINCFG 0x8005 +#define WCD9335_TLMM_SWR_CLK_PINCFG 0x8006 +#define WCD9335_TLMM_SLIMBUS_DATA2_PINCFG 0x8007 +#define WCD9335_TLMM_I2C_CLK_PINCFG 0x8008 +#define WCD9335_TLMM_I2C_DATA_PINCFG 0x8009 +#define WCD9335_TLMM_I2S_RX_SD0_PINCFG 0x800a +#define WCD9335_TLMM_I2S_RX_SD1_PINCFG 0x800b +#define WCD9335_TLMM_I2S_RX_SCK_PINCFG 0x800c +#define WCD9335_TLMM_I2S_RX_WS_PINCFG 0x800d +#define WCD9335_TLMM_I2S_TX_SD0_PINCFG 0x800e +#define WCD9335_TLMM_I2S_TX_SD1_PINCFG 0x800f +#define WCD9335_TLMM_I2S_TX_SCK_PINCFG 0x8010 +#define WCD9335_TLMM_I2S_TX_WS_PINCFG 0x8011 +#define WCD9335_TLMM_DMIC1_CLK_PINCFG 0x8012 +#define WCD9335_TLMM_DMIC1_DATA_PINCFG 0x8013 +#define WCD9335_TLMM_DMIC2_CLK_PINCFG 0x8014 +#define WCD9335_TLMM_DMIC2_DATA_PINCFG 0x8015 +#define WCD9335_TLMM_DMIC3_CLK_PINCFG 0x8016 +#define WCD9335_TLMM_DMIC3_DATA_PINCFG 0x8017 +#define WCD9335_TLMM_JTDI_PINCFG 0x8018 +#define WCD9335_TLMM_JTDO_PINCFG 0x8019 +#define WCD9335_TLMM_JTMS_PINCFG 0x801a +#define WCD9335_TLMM_JTCK_PINCFG 0x801b +#define WCD9335_TLMM_JTRST_PINCFG 0x801c +#define WCD9335_TEST_DEBUG_PIN_CTL_OE_0 0x8031 +#define WCD9335_TEST_DEBUG_PIN_CTL_OE_1 0x8032 +#define WCD9335_TEST_DEBUG_PIN_CTL_OE_2 0x8033 +#define WCD9335_TEST_DEBUG_PIN_CTL_OE_3 0x8034 +#define WCD9335_TEST_DEBUG_PIN_CTL_DATA_0 0x8035 +#define WCD9335_TEST_DEBUG_PIN_CTL_DATA_1 0x8036 +#define WCD9335_TEST_DEBUG_PIN_CTL_DATA_2 0x8037 +#define WCD9335_TEST_DEBUG_PIN_CTL_DATA_3 0x8038 +#define WCD9335_TEST_DEBUG_PAD_DRVCTL 0x8039 +#define WCD9335_TEST_DEBUG_PIN_STATUS 0x803a +#define WCD9335_TEST_DEBUG_NPL_DLY_TEST_1 0x803b +#define WCD9335_TEST_DEBUG_NPL_DLY_TEST_2 0x803c +#define WCD9335_TEST_DEBUG_MEM_CTRL 0x803d +#define WCD9335_TEST_DEBUG_DEBUG_BUS_SEL 0x8041 +#define WCD9335_TEST_DEBUG_DEBUG_JTAG 0x8042 +#define WCD9335_TEST_DEBUG_DEBUG_EN_1 0x8043 +#define WCD9335_TEST_DEBUG_DEBUG_EN_2 0x8044 +#define WCD9335_TEST_DEBUG_DEBUG_EN_3 0x8045 +#define WCD9335_MAX_REGISTER 0x80FF + +/* SLIMBUS Slave Registers */ +#define TASHA_SLIM_PGD_PORT_INT_EN0 (0x30) +#define TASHA_SLIM_PGD_PORT_INT_STATUS_RX_0 (0x34) +#define TASHA_SLIM_PGD_PORT_INT_STATUS_RX_1 (0x35) +#define TASHA_SLIM_PGD_PORT_INT_STATUS_TX_0 (0x36) +#define TASHA_SLIM_PGD_PORT_INT_STATUS_TX_1 (0x37) +#define TASHA_SLIM_PGD_PORT_INT_CLR_RX_0 (0x38) +#define TASHA_SLIM_PGD_PORT_INT_CLR_RX_1 (0x39) +#define TASHA_SLIM_PGD_PORT_INT_CLR_TX_0 (0x3A) +#define TASHA_SLIM_PGD_PORT_INT_CLR_TX_1 (0x3B) +#define TASHA_SLIM_PGD_PORT_INT_RX_SOURCE0 (0x60) +#define TASHA_SLIM_PGD_PORT_INT_TX_SOURCE0 (0x70) + +/* Macros for Packing Register Writes into a U32 */ +#define TASHA_PACKED_REG_SIZE sizeof(u32) + +#define TASHA_CODEC_PACK_ENTRY(reg, mask, val) ((val & 0xff)|\ + ((mask & 0xff) << 8)|((reg & 0xffff) << 16)) +#define TASHA_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \ + do { \ + ((reg) = ((packed >> 16) & (0xffff))); \ + ((mask) = ((packed >> 8) & (0xff))); \ + ((val) = ((packed) & (0xff))); \ + } while (0) +#endif diff --git a/include/linux/mfd/wcd934x/irq.h b/include/linux/mfd/wcd934x/irq.h new file mode 100644 index 000000000000..1a18be376eb1 --- /dev/null +++ b/include/linux/mfd/wcd934x/irq.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __WCD934X_IRQ_H_ +#define __WCD934X_IRQ_H_ + +enum { + /* INTR_REG 0 */ + WCD934X_IRQ_MISC = 1, + WCD934X_IRQ_HPH_PA_OCPL_FAULT, + WCD934X_IRQ_HPH_PA_OCPR_FAULT, + WCD934X_IRQ_EAR_PA_OCP_FAULT, + WCD934X_IRQ_HPH_PA_CNPL_COMPLETE, + WCD934X_IRQ_HPH_PA_CNPR_COMPLETE, + WCD934X_IRQ_EAR_PA_CNP_COMPLETE, + /* INTR_REG 1 */ + WCD934X_IRQ_MBHC_SW_DET, + WCD934X_IRQ_MBHC_ELECT_INS_REM_DET, + WCD934X_IRQ_MBHC_BUTTON_PRESS_DET, + WCD934X_IRQ_MBHC_BUTTON_RELEASE_DET, + WCD934X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, + WCD934X_IRQ_RESERVED_0, + WCD934X_IRQ_RESERVED_1, + WCD934X_IRQ_RESERVED_2, + /* INTR_REG 2 */ + WCD934X_IRQ_LINE_PA1_CNP_COMPLETE, + WCD934X_IRQ_LINE_PA2_CNP_COMPLETE, + WCD934X_IRQ_SLNQ_ANALOG_ERROR, + WCD934X_IRQ_RESERVED_3, + WCD934X_IRQ_SOUNDWIRE, + WCD934X_IRQ_VDD_DIG_RAMP_COMPLETE, + WCD934X_IRQ_RCO_ERROR, + WCD934X_IRQ_CPE_ERROR, + /* INTR_REG 3 */ + WCD934X_IRQ_MAD_AUDIO, + WCD934X_IRQ_MAD_BEACON, + WCD934X_IRQ_MAD_ULTRASOUND, + WCD934X_IRQ_VBAT_ATTACK, + WCD934X_IRQ_VBAT_RESTORE, + WCD934X_IRQ_CPE1_INTR, + WCD934X_IRQ_RESERVED_4, + WCD934X_IRQ_SLNQ_DIGITAL, + WCD934X_NUM_IRQS, +}; + +#endif diff --git a/include/linux/mfd/wcd934x/registers.h b/include/linux/mfd/wcd934x/registers.h new file mode 100644 index 000000000000..a824875096e4 --- /dev/null +++ b/include/linux/mfd/wcd934x/registers.h @@ -0,0 +1,1848 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _WCD934X_REGISTERS_H +#define _WCD934X_REGISTERS_H + +#define WCD934X_PAGE_SIZE 256 +#define WCD934X_NUM_PAGES 256 + +extern const u8 * const wcd934x_reg[WCD934X_NUM_PAGES]; + +enum { + WCD934X_PAGE_0 = 0, + WCD934X_PAGE_1, + WCD934X_PAGE_2, + WCD934X_PAGE_4 = 4, + WCD934X_PAGE_5, + WCD934X_PAGE_6, + WCD934X_PAGE_7, + WCD934X_PAGE_10 = 0xA, + WCD934X_PAGE_11, + WCD934X_PAGE_12, + WCD934X_PAGE_13, + WCD934X_PAGE_14, + WCD934X_PAGE_15, + WCD934X_PAGE_0x50, + WCD934X_PAGE_0X80, +}; + +enum { + WCD934X_WRITE = 0, + WCD934X_READ, + WCD934X_READ_WRITE, +}; + +/* Page-0 Registers */ +#define WCD934X_PAGE0_PAGE_REGISTER 0x0000 +#define WCD934X_CODEC_RPM_CLK_BYPASS 0x0001 +#define WCD934X_CODEC_RPM_CLK_GATE 0x0002 +#define WCD934X_CODEC_RPM_CLK_MCLK_CFG 0x0003 +#define WCD934X_CODEC_RPM_CLK_MCLK2_CFG 0x0004 +#define WCD934X_CODEC_RPM_I2S_DSD_CLK_SEL 0x0005 +#define WCD934X_CODEC_RPM_RST_CTL 0x0009 +#define WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL 0x0011 +#define WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE0 0x0021 +#define WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE1 0x0022 +#define WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE2 0x0023 +#define WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE3 0x0024 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_CTL 0x0025 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_TEST0 0x0026 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_TEST1 0x0027 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT0 0x0029 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT1 0x002a +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT2 0x002b +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT3 0x002c +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT4 0x002d +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT5 0x002e +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT6 0x002f +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT7 0x0030 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT8 0x0031 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT9 0x0032 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT10 0x0033 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT11 0x0034 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT12 0x0035 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT13 0x0036 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT14 0x0037 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT15 0x0038 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_STATUS 0x0039 +#define WCD934X_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO 0x003a +#define WCD934X_CHIP_TIER_CTRL_I2C_SLAVE_ID_1 0x003b +#define WCD934X_CHIP_TIER_CTRL_I2C_SLAVE_ID_2 0x003c +#define WCD934X_CHIP_TIER_CTRL_I2C_SLAVE_ID_3 0x003d +#define WCD934X_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL 0x003e +#define WCD934X_CHIP_TIER_CTRL_SLNQ_WAIT_STATE_CTL 0x003f +#define WCD934X_CHIP_TIER_CTRL_I2C_ACTIVE 0x0040 +#define WCD934X_CHIP_TIER_CTRL_ALT_FUNC_EN 0x0041 +#define WCD934X_CHIP_TIER_CTRL_GPIO_CTL_OE 0x0042 +#define WCD934X_CHIP_TIER_CTRL_GPIO_CTL_DATA 0x0043 +#define WCD934X_DATA_HUB_RX0_CFG 0x0051 +#define WCD934X_DATA_HUB_RX1_CFG 0x0052 +#define WCD934X_DATA_HUB_RX2_CFG 0x0053 +#define WCD934X_DATA_HUB_RX3_CFG 0x0054 +#define WCD934X_DATA_HUB_RX4_CFG 0x0055 +#define WCD934X_DATA_HUB_RX5_CFG 0x0056 +#define WCD934X_DATA_HUB_RX6_CFG 0x0057 +#define WCD934X_DATA_HUB_RX7_CFG 0x0058 +#define WCD934X_DATA_HUB_SB_TX0_INP_CFG 0x0061 +#define WCD934X_DATA_HUB_SB_TX1_INP_CFG 0x0062 +#define WCD934X_DATA_HUB_SB_TX2_INP_CFG 0x0063 +#define WCD934X_DATA_HUB_SB_TX3_INP_CFG 0x0064 +#define WCD934X_DATA_HUB_SB_TX4_INP_CFG 0x0065 +#define WCD934X_DATA_HUB_SB_TX5_INP_CFG 0x0066 +#define WCD934X_DATA_HUB_SB_TX6_INP_CFG 0x0067 +#define WCD934X_DATA_HUB_SB_TX7_INP_CFG 0x0068 +#define WCD934X_DATA_HUB_SB_TX8_INP_CFG 0x0069 +#define WCD934X_DATA_HUB_SB_TX9_INP_CFG 0x006a +#define WCD934X_DATA_HUB_SB_TX10_INP_CFG 0x006b +#define WCD934X_DATA_HUB_SB_TX11_INP_CFG 0x006c +#define WCD934X_DATA_HUB_SB_TX13_INP_CFG 0x006e +#define WCD934X_DATA_HUB_SB_TX14_INP_CFG 0x006f +#define WCD934X_DATA_HUB_SB_TX15_INP_CFG 0x0070 +#define WCD934X_DATA_HUB_I2S_TX0_CFG 0x0071 +#define WCD934X_DATA_HUB_I2S_TX1_0_CFG 0x0073 +#define WCD934X_DATA_HUB_I2S_TX1_1_CFG 0x0074 +#define WCD934X_DATA_HUB_I2S_0_CTL 0x0081 +#define WCD934X_DATA_HUB_I2S_1_CTL 0x0082 +#define WCD934X_DATA_HUB_I2S_2_CTL 0x0083 +#define WCD934X_DATA_HUB_I2S_3_CTL 0x0084 +#define WCD934X_DATA_HUB_I2S_CLKSRC_CTL 0x0085 +#define WCD934X_DATA_HUB_I2S_COMMON_CTL 0x0086 +#define WCD934X_DATA_HUB_I2S_0_TDM_CTL 0x0087 +#define WCD934X_DATA_HUB_I2S_STATUS 0x0088 +#define WCD934X_DMA_RDMA_CTL_0 0x0091 +#define WCD934X_DMA_CH_2_3_CFG_RDMA_0 0x0092 +#define WCD934X_DMA_CH_0_1_CFG_RDMA_0 0x0093 +#define WCD934X_DMA_RDMA_CTL_1 0x0094 +#define WCD934X_DMA_CH_2_3_CFG_RDMA_1 0x0095 +#define WCD934X_DMA_CH_0_1_CFG_RDMA_1 0x0096 +#define WCD934X_DMA_RDMA_CTL_2 0x0097 +#define WCD934X_DMA_CH_2_3_CFG_RDMA_2 0x0098 +#define WCD934X_DMA_CH_0_1_CFG_RDMA_2 0x0099 +#define WCD934X_DMA_RDMA_CTL_3 0x009A +#define WCD934X_DMA_CH_2_3_CFG_RDMA_3 0x009B +#define WCD934X_DMA_CH_0_1_CFG_RDMA_3 0x009C +#define WCD934X_DMA_RDMA_CTL_4 0x009D +#define WCD934X_DMA_CH_2_3_CFG_RDMA_4 0x009E +#define WCD934X_DMA_CH_0_1_CFG_RDMA_4 0x009F +#define WCD934X_DMA_RDMA4_PRT_CFG 0x00b1 +#define WCD934X_DMA_RDMA_SBTX0_7_CFG 0x00b9 +#define WCD934X_DMA_RDMA_SBTX8_11_CFG 0x00ba +#define WCD934X_DMA_WDMA_CTL_0 0x00c1 +#define WCD934X_DMA_CH_4_5_CFG_WDMA_0 0x00c2 +#define WCD934X_DMA_CH_2_3_CFG_WDMA_0 0x00c3 +#define WCD934X_DMA_CH_0_1_CFG_WDMA_0 0x00c4 +#define WCD934X_DMA_WDMA_CTL_1 0x00C6 +#define WCD934X_DMA_CH_4_5_CFG_WDMA_1 0x00C7 +#define WCD934X_DMA_CH_2_3_CFG_WDMA_1 0x00C8 +#define WCD934X_DMA_CH_0_1_CFG_WDMA_1 0x00C9 +#define WCD934X_DMA_WDMA_CTL_2 0x00CB +#define WCD934X_DMA_CH_4_5_CFG_WDMA_2 0x00CC +#define WCD934X_DMA_CH_2_3_CFG_WDMA_2 0x00CD +#define WCD934X_DMA_CH_0_1_CFG_WDMA_2 0x00CE +#define WCD934X_DMA_WDMA_CTL_3 0x00D0 +#define WCD934X_DMA_CH_4_5_CFG_WDMA_3 0x00D1 +#define WCD934X_DMA_CH_2_3_CFG_WDMA_3 0x00D2 +#define WCD934X_DMA_CH_0_1_CFG_WDMA_3 0x00D3 +#define WCD934X_DMA_WDMA_CTL_4 0x00D5 +#define WCD934X_DMA_CH_4_5_CFG_WDMA_4 0x00D6 +#define WCD934X_DMA_CH_2_3_CFG_WDMA_4 0x00D7 +#define WCD934X_DMA_CH_0_1_CFG_WDMA_4 0x00D8 +#define WCD934X_DMA_WDMA0_PRT_CFG 0x00E1 +#define WCD934X_DMA_WDMA3_PRT_CFG 0x00E2 +#define WCD934X_DMA_WDMA4_PRT0_3_CFG 0x00E3 +#define WCD934X_DMA_WDMA4_PRT4_7_CFG 0x00E4 +#define WCD934X_PAGE1_PAGE_REGISTER 0x0100 +#define WCD934X_CPE_FLL_USER_CTL_0 0x0101 +#define WCD934X_CPE_FLL_USER_CTL_1 0x0102 +#define WCD934X_CPE_FLL_USER_CTL_2 0x0103 +#define WCD934X_CPE_FLL_USER_CTL_3 0x0104 +#define WCD934X_CPE_FLL_USER_CTL_4 0x0105 +#define WCD934X_CPE_FLL_USER_CTL_5 0x0106 +#define WCD934X_CPE_FLL_USER_CTL_6 0x0107 +#define WCD934X_CPE_FLL_USER_CTL_7 0x0108 +#define WCD934X_CPE_FLL_USER_CTL_8 0x0109 +#define WCD934X_CPE_FLL_USER_CTL_9 0x010a +#define WCD934X_CPE_FLL_L_VAL_CTL_0 0x010b +#define WCD934X_CPE_FLL_L_VAL_CTL_1 0x010c +#define WCD934X_CPE_FLL_DSM_FRAC_CTL_0 0x010d +#define WCD934X_CPE_FLL_DSM_FRAC_CTL_1 0x010e +#define WCD934X_CPE_FLL_CONFIG_CTL_0 0x010f +#define WCD934X_CPE_FLL_CONFIG_CTL_1 0x0110 +#define WCD934X_CPE_FLL_CONFIG_CTL_2 0x0111 +#define WCD934X_CPE_FLL_CONFIG_CTL_3 0x0112 +#define WCD934X_CPE_FLL_CONFIG_CTL_4 0x0113 +#define WCD934X_CPE_FLL_TEST_CTL_0 0x0114 +#define WCD934X_CPE_FLL_TEST_CTL_1 0x0115 +#define WCD934X_CPE_FLL_TEST_CTL_2 0x0116 +#define WCD934X_CPE_FLL_TEST_CTL_3 0x0117 +#define WCD934X_CPE_FLL_TEST_CTL_4 0x0118 +#define WCD934X_CPE_FLL_TEST_CTL_5 0x0119 +#define WCD934X_CPE_FLL_TEST_CTL_6 0x011a +#define WCD934X_CPE_FLL_TEST_CTL_7 0x011b +#define WCD934X_CPE_FLL_FREQ_CTL_0 0x011c +#define WCD934X_CPE_FLL_FREQ_CTL_1 0x011d +#define WCD934X_CPE_FLL_FREQ_CTL_2 0x011e +#define WCD934X_CPE_FLL_FREQ_CTL_3 0x011f +#define WCD934X_CPE_FLL_SSC_CTL_0 0x0120 +#define WCD934X_CPE_FLL_SSC_CTL_1 0x0121 +#define WCD934X_CPE_FLL_SSC_CTL_2 0x0122 +#define WCD934X_CPE_FLL_SSC_CTL_3 0x0123 +#define WCD934X_CPE_FLL_FLL_MODE 0x0124 +#define WCD934X_CPE_FLL_STATUS_0 0x0125 +#define WCD934X_CPE_FLL_STATUS_1 0x0126 +#define WCD934X_CPE_FLL_STATUS_2 0x0127 +#define WCD934X_CPE_FLL_STATUS_3 0x0128 +#define WCD934X_I2S_FLL_USER_CTL_0 0x0141 +#define WCD934X_I2S_FLL_USER_CTL_1 0x0142 +#define WCD934X_I2S_FLL_USER_CTL_2 0x0143 +#define WCD934X_I2S_FLL_USER_CTL_3 0x0144 +#define WCD934X_I2S_FLL_USER_CTL_4 0x0145 +#define WCD934X_I2S_FLL_USER_CTL_5 0x0146 +#define WCD934X_I2S_FLL_USER_CTL_6 0x0147 +#define WCD934X_I2S_FLL_USER_CTL_7 0x0148 +#define WCD934X_I2S_FLL_USER_CTL_8 0x0149 +#define WCD934X_I2S_FLL_USER_CTL_9 0x014a +#define WCD934X_I2S_FLL_L_VAL_CTL_0 0x014b +#define WCD934X_I2S_FLL_L_VAL_CTL_1 0x014c +#define WCD934X_I2S_FLL_DSM_FRAC_CTL_0 0x014d +#define WCD934X_I2S_FLL_DSM_FRAC_CTL_1 0x014e +#define WCD934X_I2S_FLL_CONFIG_CTL_0 0x014f +#define WCD934X_I2S_FLL_CONFIG_CTL_1 0x0150 +#define WCD934X_I2S_FLL_CONFIG_CTL_2 0x0151 +#define WCD934X_I2S_FLL_CONFIG_CTL_3 0x0152 +#define WCD934X_I2S_FLL_CONFIG_CTL_4 0x0153 +#define WCD934X_I2S_FLL_TEST_CTL_0 0x0154 +#define WCD934X_I2S_FLL_TEST_CTL_1 0x0155 +#define WCD934X_I2S_FLL_TEST_CTL_2 0x0156 +#define WCD934X_I2S_FLL_TEST_CTL_3 0x0157 +#define WCD934X_I2S_FLL_TEST_CTL_4 0x0158 +#define WCD934X_I2S_FLL_TEST_CTL_5 0x0159 +#define WCD934X_I2S_FLL_TEST_CTL_6 0x015a +#define WCD934X_I2S_FLL_TEST_CTL_7 0x015b +#define WCD934X_I2S_FLL_FREQ_CTL_0 0x015c +#define WCD934X_I2S_FLL_FREQ_CTL_1 0x015d +#define WCD934X_I2S_FLL_FREQ_CTL_2 0x015e +#define WCD934X_I2S_FLL_FREQ_CTL_3 0x015f +#define WCD934X_I2S_FLL_SSC_CTL_0 0x0160 +#define WCD934X_I2S_FLL_SSC_CTL_1 0x0161 +#define WCD934X_I2S_FLL_SSC_CTL_2 0x0162 +#define WCD934X_I2S_FLL_SSC_CTL_3 0x0163 +#define WCD934X_I2S_FLL_FLL_MODE 0x0164 +#define WCD934X_I2S_FLL_STATUS_0 0x0165 +#define WCD934X_I2S_FLL_STATUS_1 0x0166 +#define WCD934X_I2S_FLL_STATUS_2 0x0167 +#define WCD934X_I2S_FLL_STATUS_3 0x0168 +#define WCD934X_SB_FLL_USER_CTL_0 0x0181 +#define WCD934X_SB_FLL_USER_CTL_1 0x0182 +#define WCD934X_SB_FLL_USER_CTL_2 0x0183 +#define WCD934X_SB_FLL_USER_CTL_3 0x0184 +#define WCD934X_SB_FLL_USER_CTL_4 0x0185 +#define WCD934X_SB_FLL_USER_CTL_5 0x0186 +#define WCD934X_SB_FLL_USER_CTL_6 0x0187 +#define WCD934X_SB_FLL_USER_CTL_7 0x0188 +#define WCD934X_SB_FLL_USER_CTL_8 0x0189 +#define WCD934X_SB_FLL_USER_CTL_9 0x018a +#define WCD934X_SB_FLL_L_VAL_CTL_0 0x018b +#define WCD934X_SB_FLL_L_VAL_CTL_1 0x018c +#define WCD934X_SB_FLL_DSM_FRAC_CTL_0 0x018d +#define WCD934X_SB_FLL_DSM_FRAC_CTL_1 0x018e +#define WCD934X_SB_FLL_CONFIG_CTL_0 0x018f +#define WCD934X_SB_FLL_CONFIG_CTL_1 0x0190 +#define WCD934X_SB_FLL_CONFIG_CTL_2 0x0191 +#define WCD934X_SB_FLL_CONFIG_CTL_3 0x0192 +#define WCD934X_SB_FLL_CONFIG_CTL_4 0x0193 +#define WCD934X_SB_FLL_TEST_CTL_0 0x0194 +#define WCD934X_SB_FLL_TEST_CTL_1 0x0195 +#define WCD934X_SB_FLL_TEST_CTL_2 0x0196 +#define WCD934X_SB_FLL_TEST_CTL_3 0x0197 +#define WCD934X_SB_FLL_TEST_CTL_4 0x0198 +#define WCD934X_SB_FLL_TEST_CTL_5 0x0199 +#define WCD934X_SB_FLL_TEST_CTL_6 0x019a +#define WCD934X_SB_FLL_TEST_CTL_7 0x019b +#define WCD934X_SB_FLL_FREQ_CTL_0 0x019c +#define WCD934X_SB_FLL_FREQ_CTL_1 0x019d +#define WCD934X_SB_FLL_FREQ_CTL_2 0x019e +#define WCD934X_SB_FLL_FREQ_CTL_3 0x019f +#define WCD934X_SB_FLL_SSC_CTL_0 0x01a0 +#define WCD934X_SB_FLL_SSC_CTL_1 0x01a1 +#define WCD934X_SB_FLL_SSC_CTL_2 0x01a2 +#define WCD934X_SB_FLL_SSC_CTL_3 0x01a3 +#define WCD934X_SB_FLL_FLL_MODE 0x01a4 +#define WCD934X_SB_FLL_STATUS_0 0x01a5 +#define WCD934X_SB_FLL_STATUS_1 0x01a6 +#define WCD934X_SB_FLL_STATUS_2 0x01a7 +#define WCD934X_SB_FLL_STATUS_3 0x01a8 +#define WCD934X_PAGE2_PAGE_REGISTER 0x0200 +#define WCD934X_CPE_SS_CPE_CTL 0x0201 +#define WCD934X_CPE_SS_PWR_SYS_PSTATE_CTL_0 0x0202 +#define WCD934X_CPE_SS_PWR_SYS_PSTATE_CTL_1 0x0203 +#define WCD934X_CPE_SS_PWR_CPEFLL_CTL 0x0204 +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0 0x0205 +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1 0x0206 +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_OVERRIDE 0x0207 +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0 0x0208 +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1 0x0209 +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2 0x020a +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3 0x020b +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_4 0x020c +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_5 0x020d +#define WCD934X_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN 0x020e +#define WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL 0x020f +#define WCD934X_CPE_SS_SOC_SW_COLLAPSE_OVERRIDE_CTL 0x0210 +#define WCD934X_CPE_SS_SOC_SW_COLLAPSE_OVERRIDE_CTL1 0x0211 +#define WCD934X_CPE_SS_US_BUF_INT_PERIOD 0x0212 +#define WCD934X_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD 0x0213 +#define WCD934X_CPE_SS_SVA_CFG 0x0214 +#define WCD934X_CPE_SS_US_CFG 0x0215 +#define WCD934X_CPE_SS_MAD_CTL 0x0216 +#define WCD934X_CPE_SS_CPAR_CTL 0x0217 +#define WCD934X_CPE_SS_DMIC0_CTL 0x0218 +#define WCD934X_CPE_SS_DMIC1_CTL 0x0219 +#define WCD934X_CPE_SS_DMIC2_CTL 0x021a +#define WCD934X_CPE_SS_DMIC_CFG 0x021b +#define WCD934X_CPE_SS_CPAR_CFG 0x021c +#define WCD934X_CPE_SS_WDOG_CFG 0x021d +#define WCD934X_CPE_SS_BACKUP_INT 0x021e +#define WCD934X_CPE_SS_STATUS 0x021f +#define WCD934X_CPE_SS_CPE_OCD_CFG 0x0220 +#define WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A 0x0221 +#define WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B 0x0222 +#define WCD934X_CPE_SS_SS_ERROR_INT_MASK_1A 0x0223 +#define WCD934X_CPE_SS_SS_ERROR_INT_MASK_1B 0x0224 +#define WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0A 0x0225 +#define WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0B 0x0226 +#define WCD934X_CPE_SS_SS_ERROR_INT_STATUS_1A 0x0227 +#define WCD934X_CPE_SS_SS_ERROR_INT_STATUS_1B 0x0228 +#define WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_0A 0x0229 +#define WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_0B 0x022a +#define WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_1A 0x022b +#define WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_1B 0x022c +#define WCD934X_SOC_MAD_MAIN_CTL_1 0x0281 +#define WCD934X_SOC_MAD_MAIN_CTL_2 0x0282 +#define WCD934X_SOC_MAD_AUDIO_CTL_1 0x0283 +#define WCD934X_SOC_MAD_AUDIO_CTL_2 0x0284 +#define WCD934X_SOC_MAD_AUDIO_CTL_3 0x0285 +#define WCD934X_SOC_MAD_AUDIO_CTL_4 0x0286 +#define WCD934X_SOC_MAD_AUDIO_CTL_5 0x0287 +#define WCD934X_SOC_MAD_AUDIO_CTL_6 0x0288 +#define WCD934X_SOC_MAD_AUDIO_CTL_7 0x0289 +#define WCD934X_SOC_MAD_AUDIO_CTL_8 0x028a +#define WCD934X_SOC_MAD_AUDIO_IIR_CTL_PTR 0x028b +#define WCD934X_SOC_MAD_AUDIO_IIR_CTL_VAL 0x028c +#define WCD934X_SOC_MAD_ULTR_CTL_1 0x028d +#define WCD934X_SOC_MAD_ULTR_CTL_2 0x028e +#define WCD934X_SOC_MAD_ULTR_CTL_3 0x028f +#define WCD934X_SOC_MAD_ULTR_CTL_4 0x0290 +#define WCD934X_SOC_MAD_ULTR_CTL_5 0x0291 +#define WCD934X_SOC_MAD_ULTR_CTL_6 0x0292 +#define WCD934X_SOC_MAD_ULTR_CTL_7 0x0293 +#define WCD934X_SOC_MAD_BEACON_CTL_1 0x0294 +#define WCD934X_SOC_MAD_BEACON_CTL_2 0x0295 +#define WCD934X_SOC_MAD_BEACON_CTL_3 0x0296 +#define WCD934X_SOC_MAD_BEACON_CTL_4 0x0297 +#define WCD934X_SOC_MAD_BEACON_CTL_5 0x0298 +#define WCD934X_SOC_MAD_BEACON_CTL_6 0x0299 +#define WCD934X_SOC_MAD_BEACON_CTL_7 0x029a +#define WCD934X_SOC_MAD_BEACON_CTL_8 0x029b +#define WCD934X_SOC_MAD_BEACON_IIR_CTL_PTR 0x029c +#define WCD934X_SOC_MAD_BEACON_IIR_CTL_VAL 0x029d +#define WCD934X_SOC_MAD_INP_SEL 0x029e +#define WCD934X_PAGE4_PAGE_REGISTER 0x0400 +#define WCD934X_INTR_CFG 0x0401 +#define WCD934X_INTR_CLR_COMMIT 0x0402 +#define WCD934X_INTR_PIN1_MASK0 0x0409 +#define WCD934X_INTR_PIN1_MASK1 0x040a +#define WCD934X_INTR_PIN1_MASK2 0x040b +#define WCD934X_INTR_PIN1_MASK3 0x040c +#define WCD934X_INTR_PIN1_STATUS0 0x0411 +#define WCD934X_INTR_PIN1_STATUS1 0x0412 +#define WCD934X_INTR_PIN1_STATUS2 0x0413 +#define WCD934X_INTR_PIN1_STATUS3 0x0414 +#define WCD934X_INTR_PIN1_CLEAR0 0x0419 +#define WCD934X_INTR_PIN1_CLEAR1 0x041a +#define WCD934X_INTR_PIN1_CLEAR2 0x041b +#define WCD934X_INTR_PIN1_CLEAR3 0x041c +#define WCD934X_INTR_PIN2_MASK3 0x0424 +#define WCD934X_INTR_PIN2_STATUS3 0x042c +#define WCD934X_INTR_PIN2_CLEAR3 0x0434 +#define WCD934X_INTR_CPESS_SUMRY_MASK2 0x043b +#define WCD934X_INTR_CPESS_SUMRY_MASK3 0x043c +#define WCD934X_INTR_CPESS_SUMRY_STATUS2 0x0443 +#define WCD934X_INTR_CPESS_SUMRY_STATUS3 0x0444 +#define WCD934X_INTR_CPESS_SUMRY_CLEAR2 0x044b +#define WCD934X_INTR_CPESS_SUMRY_CLEAR3 0x044c +#define WCD934X_INTR_LEVEL0 0x0461 +#define WCD934X_INTR_LEVEL1 0x0462 +#define WCD934X_INTR_LEVEL2 0x0463 +#define WCD934X_INTR_LEVEL3 0x0464 +#define WCD934X_INTR_BYPASS0 0x0469 +#define WCD934X_INTR_BYPASS1 0x046a +#define WCD934X_INTR_BYPASS2 0x046b +#define WCD934X_INTR_BYPASS3 0x046c +#define WCD934X_INTR_SET0 0x0471 +#define WCD934X_INTR_SET1 0x0472 +#define WCD934X_INTR_SET2 0x0473 +#define WCD934X_INTR_SET3 0x0474 +#define WCD934X_INTR_CODEC_MISC_MASK 0x04b1 +#define WCD934X_INTR_CODEC_MISC_STATUS 0x04b2 +#define WCD934X_INTR_CODEC_MISC_CLEAR 0x04b3 +#define WCD934X_PAGE5_PAGE_REGISTER 0x0500 +#define WCD934X_SLNQ_DIG_DEVICE 0x0501 +#define WCD934X_SLNQ_DIG_REVISION 0x0502 +#define WCD934X_SLNQ_DIG_H_COMMAND 0x0511 +#define WCD934X_SLNQ_DIG_NUMBER_OF_BYTE_MSB 0x0512 +#define WCD934X_SLNQ_DIG_NUMBER_OF_BYTE_LSB 0x0513 +#define WCD934X_SLNQ_DIG_MASTER_ADDRESS_MSB 0x0514 +#define WCD934X_SLNQ_DIG_MASTER_ADDRESS_LSB 0x0515 +#define WCD934X_SLNQ_DIG_SLAVE_ADDRESS_MSB 0x0516 +#define WCD934X_SLNQ_DIG_SLAVE_ADDRESS_LSB 0x0517 +#define WCD934X_SLNQ_DIG_TIMER0_INTERRUPT_MSB 0x0518 +#define WCD934X_SLNQ_DIG_TIMER0_INTERRUPT_LSB 0x0519 +#define WCD934X_SLNQ_DIG_TIMER1_INTERRUPT_MSB 0x051a +#define WCD934X_SLNQ_DIG_TIMER1_INTERRUPT_LSB 0x051b +#define WCD934X_SLNQ_DIG_TIMER2_INTERRUPT_MSB 0x051c +#define WCD934X_SLNQ_DIG_TIMER2_INTERRUPT_LSB 0x051d +#define WCD934X_SLNQ_DIG_COMM_CTL 0x0520 +#define WCD934X_SLNQ_DIG_FRAME_CTRL 0x0542 +#define WCD934X_SLNQ_DIG_PDM_2ND_DATA_CH1_2 0x055c +#define WCD934X_SLNQ_DIG_PDM_2ND_DATA_CH3_4 0x055d +#define WCD934X_SLNQ_DIG_PDM_2ND_DATA_CH5 0x055e +#define WCD934X_SLNQ_DIG_SW_EVENT_RD 0x0561 +#define WCD934X_SLNQ_DIG_SW_EVENT_CTRL 0x0562 +#define WCD934X_SLNQ_DIG_PDM_SELECT_1 0x0563 +#define WCD934X_SLNQ_DIG_PDM_SELECT_2 0x0564 +#define WCD934X_SLNQ_DIG_PDM_SELECT_3 0x0565 +#define WCD934X_SLNQ_DIG_PDM_SAMPLING_FREQ 0x0566 +#define WCD934X_SLNQ_DIG_PDM_DC_CONVERSION_CTL 0x0569 +#define WCD934X_SLNQ_DIG_PDM_DC_CONVERSION_SEL 0x056a +#define WCD934X_SLNQ_DIG_PDM_DC_CONV_CHA_MSB 0x056b +#define WCD934X_SLNQ_DIG_PDM_DC_CONV_CHA_LSB 0x056c +#define WCD934X_SLNQ_DIG_PDM_DC_CONV_CHB_MSB 0x056d +#define WCD934X_SLNQ_DIG_PDM_DC_CONV_CHB_LSB 0x056e +#define WCD934X_SLNQ_DIG_RAM_CNTRL 0x0571 +#define WCD934X_SLNQ_DIG_SRAM_BANK 0x0572 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_0 0x0573 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_1 0x0574 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_2 0x0575 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_3 0x0576 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_4 0x0577 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_5 0x0578 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_6 0x0579 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_7 0x057a +#define WCD934X_SLNQ_DIG_SRAM_BYTE_8 0x057b +#define WCD934X_SLNQ_DIG_SRAM_BYTE_9 0x057c +#define WCD934X_SLNQ_DIG_SRAM_BYTE_A 0x057d +#define WCD934X_SLNQ_DIG_SRAM_BYTE_B 0x057e +#define WCD934X_SLNQ_DIG_SRAM_BYTE_C 0x057f +#define WCD934X_SLNQ_DIG_SRAM_BYTE_D 0x0580 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_E 0x0581 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_F 0x0582 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_10 0x0583 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_11 0x0584 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_12 0x0585 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_13 0x0586 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_14 0x0587 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_15 0x0588 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_16 0x0589 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_17 0x058a +#define WCD934X_SLNQ_DIG_SRAM_BYTE_18 0x058b +#define WCD934X_SLNQ_DIG_SRAM_BYTE_19 0x058c +#define WCD934X_SLNQ_DIG_SRAM_BYTE_1A 0x058d +#define WCD934X_SLNQ_DIG_SRAM_BYTE_1B 0x058e +#define WCD934X_SLNQ_DIG_SRAM_BYTE_1C 0x058f +#define WCD934X_SLNQ_DIG_SRAM_BYTE_1D 0x0590 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_1E 0x0591 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_1F 0x0592 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_20 0x0593 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_21 0x0594 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_22 0x0595 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_23 0x0596 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_24 0x0597 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_25 0x0598 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_26 0x0599 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_27 0x059a +#define WCD934X_SLNQ_DIG_SRAM_BYTE_28 0x059b +#define WCD934X_SLNQ_DIG_SRAM_BYTE_29 0x059c +#define WCD934X_SLNQ_DIG_SRAM_BYTE_2A 0x059d +#define WCD934X_SLNQ_DIG_SRAM_BYTE_2B 0x059e +#define WCD934X_SLNQ_DIG_SRAM_BYTE_2C 0x059f +#define WCD934X_SLNQ_DIG_SRAM_BYTE_2D 0x05a0 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_2E 0x05a1 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_2F 0x05a2 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_30 0x05a3 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_31 0x05a4 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_32 0x05a5 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_33 0x05a6 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_34 0x05a7 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_35 0x05a8 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_36 0x05a9 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_37 0x05aa +#define WCD934X_SLNQ_DIG_SRAM_BYTE_38 0x05ab +#define WCD934X_SLNQ_DIG_SRAM_BYTE_39 0x05ac +#define WCD934X_SLNQ_DIG_SRAM_BYTE_3A 0x05ad +#define WCD934X_SLNQ_DIG_SRAM_BYTE_3B 0x05ae +#define WCD934X_SLNQ_DIG_SRAM_BYTE_3C 0x05af +#define WCD934X_SLNQ_DIG_SRAM_BYTE_3D 0x05b0 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_3E 0x05b1 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_3F 0x05b2 +#define WCD934X_SLNQ_DIG_TOP_CTRL1 0x05b3 +#define WCD934X_SLNQ_DIG_TOP_CTRL2 0x05b4 +#define WCD934X_SLNQ_DIG_PDM_CTRL 0x05b5 +#define WCD934X_SLNQ_DIG_PDM_MUTE_CTRL 0x05b6 +#define WCD934X_SLNQ_DIG_DEC_BYPASS_CTRL 0x05b7 +#define WCD934X_SLNQ_DIG_DEC_BYPASS_STATUS 0x05b8 +#define WCD934X_SLNQ_DIG_DEC_BYPASS_FS 0x05b9 +#define WCD934X_SLNQ_DIG_DEC_BYPASS_IN_SEL 0x05ba +#define WCD934X_SLNQ_DIG_GPOUT_ENABLE 0x05bb +#define WCD934X_SLNQ_DIG_GPOUT_VAL 0x05bc +#define WCD934X_SLNQ_DIG_ANA_INTERRUPT_MASK 0x05be +#define WCD934X_SLNQ_DIG_ANA_INTERRUPT_STATUS 0x05bf +#define WCD934X_SLNQ_DIG_ANA_INTERRUPT_CLR 0x05c0 +#define WCD934X_SLNQ_DIG_IP_TESTING 0x05c1 +#define WCD934X_SLNQ_DIG_INTERRUPT_CNTRL 0x05e3 +#define WCD934X_SLNQ_DIG_INTERRUPT_CNT 0x05e9 +#define WCD934X_SLNQ_DIG_INTERRUPT_CNT_MSB 0x05eb +#define WCD934X_SLNQ_DIG_INTERRUPT_CNT_LSB 0x05ec +#define WCD934X_SLNQ_DIG_INTERRUPT_MASK0 0x05f1 +#define WCD934X_SLNQ_DIG_INTERRUPT_MASK1 0x05f2 +#define WCD934X_SLNQ_DIG_INTERRUPT_MASK2 0x05f3 +#define WCD934X_SLNQ_DIG_INTERRUPT_MASK3 0x05f4 +#define WCD934X_SLNQ_DIG_INTERRUPT_MASK4 0x05f5 +#define WCD934X_SLNQ_DIG_INTERRUPT_STATUS0 0x05f6 +#define WCD934X_SLNQ_DIG_INTERRUPT_STATUS1 0x05f7 +#define WCD934X_SLNQ_DIG_INTERRUPT_STATUS2 0x05f8 +#define WCD934X_SLNQ_DIG_INTERRUPT_STATUS3 0x05f9 +#define WCD934X_SLNQ_DIG_INTERRUPT_STATUS4 0x05fa +#define WCD934X_SLNQ_DIG_INTERRUPT_CLR0 0x05fb +#define WCD934X_SLNQ_DIG_INTERRUPT_CLR1 0x05fc +#define WCD934X_SLNQ_DIG_INTERRUPT_CLR2 0x05fd +#define WCD934X_SLNQ_DIG_INTERRUPT_CLR3 0x05fe +#define WCD934X_SLNQ_DIG_INTERRUPT_CLR4 0x05ff +#define WCD934X_ANA_PAGE_REGISTER 0x0600 +#define WCD934X_ANA_BIAS 0x0601 +#define WCD934X_ANA_RCO 0x0603 +#define WCD934X_ANA_PAGE6_SPARE2 0x0604 +#define WCD934X_ANA_PAGE6_SPARE3 0x0605 +#define WCD934X_ANA_BUCK_CTL 0x0606 +#define WCD934X_ANA_BUCK_STATUS 0x0607 +#define WCD934X_ANA_RX_SUPPLIES 0x0608 +#define WCD934X_ANA_HPH 0x0609 +#define WCD934X_ANA_EAR 0x060a +#define WCD934X_ANA_LO_1_2 0x060b +#define WCD934X_ANA_MAD_SETUP 0x060d +#define WCD934X_ANA_AMIC1 0x060e +#define WCD934X_ANA_AMIC2 0x060f +#define WCD934X_ANA_AMIC3 0x0610 +#define WCD934X_ANA_AMIC4 0x0611 +#define WCD934X_ANA_MBHC_MECH 0x0614 +#define WCD934X_ANA_MBHC_ELECT 0x0615 +#define WCD934X_ANA_MBHC_ZDET 0x0616 +#define WCD934X_ANA_MBHC_RESULT_1 0x0617 +#define WCD934X_ANA_MBHC_RESULT_2 0x0618 +#define WCD934X_ANA_MBHC_RESULT_3 0x0619 +#define WCD934X_ANA_MBHC_BTN0 0x061a +#define WCD934X_ANA_MBHC_BTN1 0x061b +#define WCD934X_ANA_MBHC_BTN2 0x061c +#define WCD934X_ANA_MBHC_BTN3 0x061d +#define WCD934X_ANA_MBHC_BTN4 0x061e +#define WCD934X_ANA_MBHC_BTN5 0x061f +#define WCD934X_ANA_MBHC_BTN6 0x0620 +#define WCD934X_ANA_MBHC_BTN7 0x0621 +#define WCD934X_ANA_MICB1 0x0622 +#define WCD934X_ANA_MICB2 0x0623 +#define WCD934X_ANA_MICB2_RAMP 0x0624 +#define WCD934X_ANA_MICB3 0x0625 +#define WCD934X_ANA_MICB4 0x0626 +#define WCD934X_ANA_VBADC 0x0627 +#define WCD934X_BIAS_CTL 0x0628 +#define WCD934X_BIAS_VBG_FINE_ADJ 0x0629 +#define WCD934X_RCO_CTRL_1 0x062e +#define WCD934X_RCO_CTRL_2 0x062f +#define WCD934X_RCO_CAL 0x0630 +#define WCD934X_RCO_CAL_1 0x0631 +#define WCD934X_RCO_CAL_2 0x0632 +#define WCD934X_RCO_TEST_CTRL 0x0633 +#define WCD934X_RCO_CAL_OUT_1 0x0634 +#define WCD934X_RCO_CAL_OUT_2 0x0635 +#define WCD934X_RCO_CAL_OUT_3 0x0636 +#define WCD934X_RCO_CAL_OUT_4 0x0637 +#define WCD934X_RCO_CAL_OUT_5 0x0638 +#define WCD934X_SIDO_MODE_1 0x063a +#define WCD934X_SIDO_MODE_2 0x063b +#define WCD934X_SIDO_MODE_3 0x063c +#define WCD934X_SIDO_MODE_4 0x063d +#define WCD934X_SIDO_VCL_1 0x063e +#define WCD934X_SIDO_VCL_2 0x063f +#define WCD934X_SIDO_VCL_3 0x0640 +#define WCD934X_SIDO_CCL_1 0x0641 +#define WCD934X_SIDO_CCL_2 0x0642 +#define WCD934X_SIDO_CCL_3 0x0643 +#define WCD934X_SIDO_CCL_4 0x0644 +#define WCD934X_SIDO_CCL_5 0x0645 +#define WCD934X_SIDO_CCL_6 0x0646 +#define WCD934X_SIDO_CCL_7 0x0647 +#define WCD934X_SIDO_CCL_8 0x0648 +#define WCD934X_SIDO_CCL_9 0x0649 +#define WCD934X_SIDO_CCL_10 0x064a +#define WCD934X_SIDO_FILTER_1 0x064b +#define WCD934X_SIDO_FILTER_2 0x064c +#define WCD934X_SIDO_DRIVER_1 0x064d +#define WCD934X_SIDO_DRIVER_2 0x064e +#define WCD934X_SIDO_DRIVER_3 0x064f +#define WCD934X_SIDO_CAL_CODE_EXT_1 0x0650 +#define WCD934X_SIDO_CAL_CODE_EXT_2 0x0651 +#define WCD934X_SIDO_CAL_CODE_OUT_1 0x0652 +#define WCD934X_SIDO_CAL_CODE_OUT_2 0x0653 +#define WCD934X_SIDO_TEST_1 0x0654 +#define WCD934X_SIDO_TEST_2 0x0655 +#define WCD934X_MBHC_CTL_CLK 0x0656 +#define WCD934X_MBHC_CTL_ANA 0x0657 +#define WCD934X_MBHC_CTL_SPARE_1 0x0658 +#define WCD934X_MBHC_CTL_SPARE_2 0x0659 +#define WCD934X_MBHC_CTL_BCS 0x065a +#define WCD934X_MBHC_STATUS_SPARE_1 0x065b +#define WCD934X_MBHC_TEST_CTL 0x065c +#define WCD934X_VBADC_SUBBLOCK_EN 0x065d +#define WCD934X_VBADC_IBIAS_FE 0x065e +#define WCD934X_VBADC_BIAS_ADC 0x065f +#define WCD934X_VBADC_FE_CTRL 0x0660 +#define WCD934X_VBADC_ADC_REF 0x0661 +#define WCD934X_VBADC_ADC_IO 0x0662 +#define WCD934X_VBADC_ADC_SAR 0x0663 +#define WCD934X_VBADC_DEBUG 0x0664 +#define WCD934X_LDOH_MODE 0x0667 +#define WCD934X_LDOH_BIAS 0x0668 +#define WCD934X_LDOH_STB_LOADS 0x0669 +#define WCD934X_LDOH_SLOWRAMP 0x066a +#define WCD934X_MICB1_TEST_CTL_1 0x066b +#define WCD934X_MICB1_TEST_CTL_2 0x066c +#define WCD934X_MICB1_TEST_CTL_3 0x066d +#define WCD934X_MICB2_TEST_CTL_1 0x066e +#define WCD934X_MICB2_TEST_CTL_2 0x066f +#define WCD934X_MICB2_TEST_CTL_3 0x0670 +#define WCD934X_MICB3_TEST_CTL_1 0x0671 +#define WCD934X_MICB3_TEST_CTL_2 0x0672 +#define WCD934X_MICB3_TEST_CTL_3 0x0673 +#define WCD934X_MICB4_TEST_CTL_1 0x0674 +#define WCD934X_MICB4_TEST_CTL_2 0x0675 +#define WCD934X_MICB4_TEST_CTL_3 0x0676 +#define WCD934X_TX_COM_ADC_VCM 0x0677 +#define WCD934X_TX_COM_BIAS_ATEST 0x0678 +#define WCD934X_TX_COM_ADC_INT1_IB 0x0679 +#define WCD934X_TX_COM_ADC_INT2_IB 0x067a +#define WCD934X_TX_COM_TXFE_DIV_CTL 0x067b +#define WCD934X_TX_COM_TXFE_DIV_START 0x067c +#define WCD934X_TX_COM_TXFE_DIV_STOP_9P6M 0x067d +#define WCD934X_TX_COM_TXFE_DIV_STOP_12P288M 0x067e +#define WCD934X_TX_1_2_TEST_EN 0x067f +#define WCD934X_TX_1_2_ADC_IB 0x0680 +#define WCD934X_TX_1_2_ATEST_REFCTL 0x0681 +#define WCD934X_TX_1_2_TEST_CTL 0x0682 +#define WCD934X_TX_1_2_TEST_BLK_EN 0x0683 +#define WCD934X_TX_1_2_TXFE_CLKDIV 0x0684 +#define WCD934X_TX_1_2_SAR1_ERR 0x0685 +#define WCD934X_TX_1_2_SAR2_ERR 0x0686 +#define WCD934X_TX_3_4_TEST_EN 0x0687 +#define WCD934X_TX_3_4_ADC_IB 0x0688 +#define WCD934X_TX_3_4_ATEST_REFCTL 0x0689 +#define WCD934X_TX_3_4_TEST_CTL 0x068a +#define WCD934X_TX_3_4_TEST_BLK_EN 0x068b +#define WCD934X_TX_3_4_TXFE_CLKDIV 0x068c +#define WCD934X_TX_3_4_SAR1_ERR 0x068d +#define WCD934X_TX_3_4_SAR2_ERR 0x068e +#define WCD934X_CLASSH_MODE_1 0x0697 +#define WCD934X_CLASSH_MODE_2 0x0698 +#define WCD934X_CLASSH_MODE_3 0x0699 +#define WCD934X_CLASSH_CTRL_VCL_1 0x069a +#define WCD934X_CLASSH_CTRL_VCL_2 0x069b +#define WCD934X_CLASSH_CTRL_CCL_1 0x069c +#define WCD934X_CLASSH_CTRL_CCL_2 0x069d +#define WCD934X_CLASSH_CTRL_CCL_3 0x069e +#define WCD934X_CLASSH_CTRL_CCL_4 0x069f +#define WCD934X_CLASSH_CTRL_CCL_5 0x06a0 +#define WCD934X_CLASSH_BUCK_TMUX_A_D 0x06a1 +#define WCD934X_CLASSH_BUCK_SW_DRV_CNTL 0x06a2 +#define WCD934X_CLASSH_SPARE 0x06a3 +#define WCD934X_FLYBACK_EN 0x06a4 +#define WCD934X_FLYBACK_VNEG_CTRL_1 0x06a5 +#define WCD934X_FLYBACK_VNEG_CTRL_2 0x06a6 +#define WCD934X_FLYBACK_VNEG_CTRL_3 0x06a7 +#define WCD934X_FLYBACK_VNEG_CTRL_4 0x06a8 +#define WCD934X_FLYBACK_VNEG_CTRL_5 0x06a9 +#define WCD934X_FLYBACK_VNEG_CTRL_6 0x06aa +#define WCD934X_FLYBACK_VNEG_CTRL_7 0x06ab +#define WCD934X_FLYBACK_VNEG_CTRL_8 0x06ac +#define WCD934X_FLYBACK_VNEG_CTRL_9 0x06ad +#define WCD934X_FLYBACK_VNEGDAC_CTRL_1 0x06ae +#define WCD934X_FLYBACK_VNEGDAC_CTRL_2 0x06af +#define WCD934X_FLYBACK_VNEGDAC_CTRL_3 0x06b0 +#define WCD934X_FLYBACK_CTRL_1 0x06b1 +#define WCD934X_FLYBACK_TEST_CTL 0x06b2 +#define WCD934X_RX_AUX_SW_CTL 0x06b3 +#define WCD934X_RX_PA_AUX_IN_CONN 0x06b4 +#define WCD934X_RX_TIMER_DIV 0x06b5 +#define WCD934X_RX_OCP_CTL 0x06b6 +#define WCD934X_RX_OCP_COUNT 0x06b7 +#define WCD934X_RX_BIAS_EAR_DAC 0x06b8 +#define WCD934X_RX_BIAS_EAR_AMP 0x06b9 +#define WCD934X_RX_BIAS_HPH_LDO 0x06ba +#define WCD934X_RX_BIAS_HPH_PA 0x06bb +#define WCD934X_RX_BIAS_HPH_RDACBUFF_CNP2 0x06bc +#define WCD934X_RX_BIAS_HPH_RDAC_LDO 0x06bd +#define WCD934X_RX_BIAS_HPH_CNP1 0x06be +#define WCD934X_RX_BIAS_HPH_LOWPOWER 0x06bf +#define WCD934X_RX_BIAS_DIFFLO_PA 0x06c0 +#define WCD934X_RX_BIAS_DIFFLO_REF 0x06c1 +#define WCD934X_RX_BIAS_DIFFLO_LDO 0x06c2 +#define WCD934X_RX_BIAS_SELO_DAC_PA 0x06c3 +#define WCD934X_RX_BIAS_BUCK_RST 0x06c4 +#define WCD934X_RX_BIAS_BUCK_VREF_ERRAMP 0x06c5 +#define WCD934X_RX_BIAS_FLYB_ERRAMP 0x06c6 +#define WCD934X_RX_BIAS_FLYB_BUFF 0x06c7 +#define WCD934X_RX_BIAS_FLYB_MID_RST 0x06c8 +#define WCD934X_HPH_L_STATUS 0x06c9 +#define WCD934X_HPH_R_STATUS 0x06ca +#define WCD934X_HPH_CNP_EN 0x06cb +#define WCD934X_HPH_CNP_WG_CTL 0x06cc +#define WCD934X_HPH_CNP_WG_TIME 0x06cd +#define WCD934X_HPH_OCP_CTL 0x06ce +#define WCD934X_HPH_AUTO_CHOP 0x06cf +#define WCD934X_HPH_CHOP_CTL 0x06d0 +#define WCD934X_HPH_PA_CTL1 0x06d1 +#define WCD934X_HPH_PA_CTL2 0x06d2 +#define WCD934X_HPH_L_EN 0x06d3 +#define WCD934X_HPH_L_TEST 0x06d4 +#define WCD934X_HPH_L_ATEST 0x06d5 +#define WCD934X_HPH_R_EN 0x06d6 +#define WCD934X_HPH_R_TEST 0x06d7 +#define WCD934X_HPH_R_ATEST 0x06d8 +#define WCD934X_HPH_RDAC_CLK_CTL1 0x06d9 +#define WCD934X_HPH_RDAC_CLK_CTL2 0x06da +#define WCD934X_HPH_RDAC_LDO_CTL 0x06db +#define WCD934X_HPH_RDAC_CHOP_CLK_LP_CTL 0x06dc +#define WCD934X_HPH_REFBUFF_UHQA_CTL 0x06dd +#define WCD934X_HPH_REFBUFF_LP_CTL 0x06de +#define WCD934X_HPH_L_DAC_CTL 0x06df +#define WCD934X_HPH_R_DAC_CTL 0x06e0 +#define WCD934X_EAR_EN_REG 0x06e1 +#define WCD934X_EAR_CMBUFF 0x06e2 +#define WCD934X_EAR_ICTL 0x06e3 +#define WCD934X_EAR_EN_DBG_CTL 0x06e4 +#define WCD934X_EAR_CNP 0x06e5 +#define WCD934X_EAR_DAC_CTL_ATEST 0x06e6 +#define WCD934X_EAR_STATUS_REG 0x06e7 +#define WCD934X_EAR_EAR_MISC 0x06e8 +#define WCD934X_DIFF_LO_MISC 0x06e9 +#define WCD934X_DIFF_LO_LO2_COMPANDER 0x06ea +#define WCD934X_DIFF_LO_LO1_COMPANDER 0x06eb +#define WCD934X_DIFF_LO_COMMON 0x06ec +#define WCD934X_DIFF_LO_BYPASS_EN 0x06ed +#define WCD934X_DIFF_LO_CNP 0x06ee +#define WCD934X_DIFF_LO_CORE_OUT_PROG 0x06ef +#define WCD934X_DIFF_LO_LDO_OUT_PROG 0x06f0 +#define WCD934X_DIFF_LO_COM_SWCAP_REFBUF_FREQ 0x06f1 +#define WCD934X_DIFF_LO_COM_PA_FREQ 0x06f2 +#define WCD934X_DIFF_LO_RESERVED_REG 0x06f3 +#define WCD934X_DIFF_LO_LO1_STATUS_1 0x06f4 +#define WCD934X_DIFF_LO_LO1_STATUS_2 0x06f5 +#define WCD934X_ANA_NEW_PAGE_REGISTER 0x0700 +#define WCD934X_HPH_NEW_ANA_HPH2 0x0701 +#define WCD934X_HPH_NEW_ANA_HPH3 0x0702 +#define WCD934X_SLNQ_ANA_EN 0x0703 +#define WCD934X_SLNQ_ANA_STATUS 0x0704 +#define WCD934X_SLNQ_ANA_LDO_CONFIG 0x0705 +#define WCD934X_SLNQ_ANA_LDO_OCP_CONFIG 0x0706 +#define WCD934X_SLNQ_ANA_TX_LDO_CONFIG 0x0707 +#define WCD934X_SLNQ_ANA_TX_DRV_CONFIG 0x0708 +#define WCD934X_SLNQ_ANA_RX_CONFIG_1 0x0709 +#define WCD934X_SLNQ_ANA_RX_CONFIG_2 0x070a +#define WCD934X_SLNQ_ANA_PLL_ENABLES 0x070b +#define WCD934X_SLNQ_ANA_PLL_PRESET 0x070c +#define WCD934X_SLNQ_ANA_PLL_STATUS 0x070d +#define WCD934X_CLK_SYS_PLL_ENABLES 0x070e +#define WCD934X_CLK_SYS_PLL_PRESET 0x070f +#define WCD934X_CLK_SYS_PLL_STATUS 0x0710 +#define WCD934X_CLK_SYS_MCLK_PRG 0x0711 +#define WCD934X_CLK_SYS_MCLK2_PRG1 0x0712 +#define WCD934X_CLK_SYS_MCLK2_PRG2 0x0713 +#define WCD934X_CLK_SYS_XO_PRG 0x0714 +#define WCD934X_CLK_SYS_XO_CAP_XTP 0x0715 +#define WCD934X_CLK_SYS_XO_CAP_XTM 0x0716 +#define WCD934X_BOOST_BST_EN_DLY 0x0718 +#define WCD934X_BOOST_CTRL_ILIM 0x0719 +#define WCD934X_BOOST_VOUT_SETTING 0x071a +#define WCD934X_SIDO_NEW_VOUT_A_STARTUP 0x071b +#define WCD934X_SIDO_NEW_VOUT_D_STARTUP 0x071c +#define WCD934X_SIDO_NEW_VOUT_D_FREQ1 0x071d +#define WCD934X_SIDO_NEW_VOUT_D_FREQ2 0x071e +#define WCD934X_MBHC_NEW_ELECT_REM_CLAMP_CTL 0x071f +#define WCD934X_MBHC_NEW_CTL_1 0x0720 +#define WCD934X_MBHC_NEW_CTL_2 0x0721 +#define WCD934X_MBHC_NEW_PLUG_DETECT_CTL 0x0722 +#define WCD934X_MBHC_NEW_ZDET_ANA_CTL 0x0723 +#define WCD934X_MBHC_NEW_ZDET_RAMP_CTL 0x0724 +#define WCD934X_MBHC_NEW_FSM_STATUS 0x0725 +#define WCD934X_MBHC_NEW_ADC_RESULT 0x0726 +#define WCD934X_TX_NEW_AMIC_4_5_SEL 0x0727 +#define WCD934X_VBADC_NEW_ADC_MODE 0x072f +#define WCD934X_VBADC_NEW_ADC_DOUTMSB 0x0730 +#define WCD934X_VBADC_NEW_ADC_DOUTLSB 0x0731 +#define WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL 0x0732 +#define WCD934X_HPH_NEW_INT_RDAC_HD2_CTL 0x0733 +#define WCD934X_HPH_NEW_INT_RDAC_HD2_CTL_L 0x0733 +#define WCD934X_HPH_NEW_INT_RDAC_VREF_CTL 0x0734 +#define WCD934X_HPH_NEW_INT_RDAC_OVERRIDE_CTL 0x0735 +#define WCD934X_HPH_NEW_INT_RDAC_MISC1 0x0736 +#define WCD934X_HPH_NEW_INT_RDAC_HD2_CTL_R 0x0736 +#define WCD934X_HPH_NEW_INT_PA_MISC1 0x0737 +#define WCD934X_HPH_NEW_INT_PA_MISC2 0x0738 +#define WCD934X_HPH_NEW_INT_PA_RDAC_MISC 0x0739 +#define WCD934X_HPH_NEW_INT_HPH_TIMER1 0x073a +#define WCD934X_HPH_NEW_INT_HPH_TIMER2 0x073b +#define WCD934X_HPH_NEW_INT_HPH_TIMER3 0x073c +#define WCD934X_HPH_NEW_INT_HPH_TIMER4 0x073d +#define WCD934X_HPH_NEW_INT_PA_RDAC_MISC2 0x073e +#define WCD934X_HPH_NEW_INT_PA_RDAC_MISC3 0x073f +#define WCD934X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI 0x0745 +#define WCD934X_RX_NEW_INT_HPH_RDAC_BIAS_ULP 0x0746 +#define WCD934X_RX_NEW_INT_HPH_RDAC_LDO_LP 0x0747 +#define WCD934X_SLNQ_INT_ANA_INT_LDO_TEST 0x074b +#define WCD934X_SLNQ_INT_ANA_INT_LDO_DEBUG_1 0x074c +#define WCD934X_SLNQ_INT_ANA_INT_LDO_DEBUG_2 0x074d +#define WCD934X_SLNQ_INT_ANA_INT_TX_LDO_TEST 0x074e +#define WCD934X_SLNQ_INT_ANA_INT_TX_DRV_TEST 0x074f +#define WCD934X_SLNQ_INT_ANA_INT_RX_TEST 0x0750 +#define WCD934X_SLNQ_INT_ANA_INT_RX_TEST_STATUS 0x0751 +#define WCD934X_SLNQ_INT_ANA_INT_RX_DEBUG_1 0x0752 +#define WCD934X_SLNQ_INT_ANA_INT_RX_DEBUG_2 0x0753 +#define WCD934X_SLNQ_INT_ANA_INT_CLK_CTRL 0x0754 +#define WCD934X_SLNQ_INT_ANA_INT_RESERVED_1 0x0755 +#define WCD934X_SLNQ_INT_ANA_INT_RESERVED_2 0x0756 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_POST_DIV_REG0 0x0757 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_POST_DIV_REG1 0x0758 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_REF_DIV_REG0 0x0759 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_REF_DIV_REG1 0x075a +#define WCD934X_SLNQ_INT_ANA_INT_PLL_FILTER_REG0 0x075b +#define WCD934X_SLNQ_INT_ANA_INT_PLL_FILTER_REG1 0x075c +#define WCD934X_SLNQ_INT_ANA_INT_PLL_L_VAL 0x075d +#define WCD934X_SLNQ_INT_ANA_INT_PLL_M_VAL 0x075e +#define WCD934X_SLNQ_INT_ANA_INT_PLL_N_VAL 0x075f +#define WCD934X_SLNQ_INT_ANA_INT_PLL_TEST_REG0 0x0760 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_PFD_CP_DSM_PROG 0x0761 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_VCO_PROG 0x0762 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_TEST_REG1 0x0763 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_LDO_LOCK_CFG 0x0764 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_DIG_LOCK_DET_CFG 0x0765 +#define WCD934X_CLK_SYS_INT_POST_DIV_REG0 0x076c +#define WCD934X_CLK_SYS_INT_POST_DIV_REG1 0x076d +#define WCD934X_CLK_SYS_INT_REF_DIV_REG0 0x076e +#define WCD934X_CLK_SYS_INT_REF_DIV_REG1 0x076f +#define WCD934X_CLK_SYS_INT_FILTER_REG0 0x0770 +#define WCD934X_CLK_SYS_INT_FILTER_REG1 0x0771 +#define WCD934X_CLK_SYS_INT_PLL_L_VAL 0x0772 +#define WCD934X_CLK_SYS_INT_PLL_M_VAL 0x0773 +#define WCD934X_CLK_SYS_INT_PLL_N_VAL 0x0774 +#define WCD934X_CLK_SYS_INT_TEST_REG0 0x0775 +#define WCD934X_CLK_SYS_INT_PFD_CP_DSM_PROG 0x0776 +#define WCD934X_CLK_SYS_INT_VCO_PROG 0x0777 +#define WCD934X_CLK_SYS_INT_TEST_REG1 0x0778 +#define WCD934X_CLK_SYS_INT_LDO_LOCK_CFG 0x0779 +#define WCD934X_CLK_SYS_INT_DIG_LOCK_DET_CFG 0x077a +#define WCD934X_CLK_SYS_INT_CLK_TEST1 0x077b +#define WCD934X_CLK_SYS_INT_CLK_TEST2 0x077c +#define WCD934X_CLK_SYS_INT_CLK_TEST3 0x077d +#define WCD934X_CLK_SYS_INT_XO_TEST1 0x077e +#define WCD934X_CLK_SYS_INT_XO_TEST2 0x077f +#define WCD934X_BOOST_INT_VCOMP_HYST 0x0787 +#define WCD934X_BOOST_INT_VLOOP_FILTER 0x0788 +#define WCD934X_BOOST_INT_CTRL_IDELTA 0x0789 +#define WCD934X_BOOST_INT_CTRL_ILIM_STARTUP 0x078a +#define WCD934X_BOOST_INT_CTRL_MIN_ONTIME 0x078b +#define WCD934X_BOOST_INT_CTRL_MAX_ONTIME 0x078c +#define WCD934X_BOOST_INT_CTRL_TIMING 0x078d +#define WCD934X_BOOST_INT_TMUX_A_D 0x078e +#define WCD934X_BOOST_INT_SW_DRV_CNTL 0x078f +#define WCD934X_BOOST_INT_SPARE1 0x0790 +#define WCD934X_BOOST_INT_SPARE2 0x0791 +#define WCD934X_SIDO_NEW_INT_RAMP_STATUS 0x0796 +#define WCD934X_SIDO_NEW_INT_SPARE_1 0x0797 +#define WCD934X_SIDO_NEW_INT_DEBUG_VOUT_SETTING_A 0x0798 +#define WCD934X_SIDO_NEW_INT_DEBUG_VOUT_SETTING_D 0x0799 +#define WCD934X_SIDO_NEW_INT_RAMP_INC_WAIT 0x079a +#define WCD934X_SIDO_NEW_INT_DYNAMIC_IPEAK_CTL 0x079b +#define WCD934X_SIDO_NEW_INT_RAMP_IBLEED_CTL 0x079c +#define WCD934X_SIDO_NEW_INT_DEBUG_CPROVR_TEST 0x079d +#define WCD934X_SIDO_NEW_INT_RAMP_CTL_A 0x079e +#define WCD934X_SIDO_NEW_INT_RAMP_CTL_D 0x079f +#define WCD934X_SIDO_NEW_INT_RAMP_TIMEOUT_PERIOD 0x07a0 +#define WCD934X_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING1 0x07a1 +#define WCD934X_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING2 0x07a2 +#define WCD934X_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING3 0x07a3 +#define WCD934X_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL1 0x07a4 +#define WCD934X_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL2 0x07a5 +#define WCD934X_MBHC_NEW_INT_SLNQ_HPF 0x07af +#define WCD934X_MBHC_NEW_INT_SLNQ_REF 0x07b0 +#define WCD934X_MBHC_NEW_INT_SLNQ_COMP 0x07b1 +#define WCD934X_MBHC_NEW_INT_SPARE_2 0x07b2 +#define WCD934X_PAGE10_PAGE_REGISTER 0x0a00 +#define WCD934X_CDC_ANC0_CLK_RESET_CTL 0x0a01 +#define WCD934X_CDC_ANC0_MODE_1_CTL 0x0a02 +#define WCD934X_CDC_ANC0_MODE_2_CTL 0x0a03 +#define WCD934X_CDC_ANC0_FF_SHIFT 0x0a04 +#define WCD934X_CDC_ANC0_FB_SHIFT 0x0a05 +#define WCD934X_CDC_ANC0_LPF_FF_A_CTL 0x0a06 +#define WCD934X_CDC_ANC0_LPF_FF_B_CTL 0x0a07 +#define WCD934X_CDC_ANC0_LPF_FB_CTL 0x0a08 +#define WCD934X_CDC_ANC0_SMLPF_CTL 0x0a09 +#define WCD934X_CDC_ANC0_DCFLT_SHIFT_CTL 0x0a0a +#define WCD934X_CDC_ANC0_IIR_ADAPT_CTL 0x0a0b +#define WCD934X_CDC_ANC0_IIR_COEFF_1_CTL 0x0a0c +#define WCD934X_CDC_ANC0_IIR_COEFF_2_CTL 0x0a0d +#define WCD934X_CDC_ANC0_FF_A_GAIN_CTL 0x0a0e +#define WCD934X_CDC_ANC0_FF_B_GAIN_CTL 0x0a0f +#define WCD934X_CDC_ANC0_FB_GAIN_CTL 0x0a10 +#define WCD934X_CDC_ANC0_RC_COMMON_CTL 0x0a11 +#define WCD934X_CDC_ANC0_FIFO_COMMON_CTL 0x0a13 +#define WCD934X_CDC_ANC0_RC0_STATUS_FMIN_CNTR 0x0a14 +#define WCD934X_CDC_ANC0_RC1_STATUS_FMIN_CNTR 0x0a15 +#define WCD934X_CDC_ANC0_RC0_STATUS_FMAX_CNTR 0x0a16 +#define WCD934X_CDC_ANC0_RC1_STATUS_FMAX_CNTR 0x0a17 +#define WCD934X_CDC_ANC0_STATUS_FIFO 0x0a18 +#define WCD934X_CDC_ANC1_CLK_RESET_CTL 0x0a19 +#define WCD934X_CDC_ANC1_MODE_1_CTL 0x0a1a +#define WCD934X_CDC_ANC1_MODE_2_CTL 0x0a1b +#define WCD934X_CDC_ANC1_FF_SHIFT 0x0a1c +#define WCD934X_CDC_ANC1_FB_SHIFT 0x0a1d +#define WCD934X_CDC_ANC1_LPF_FF_A_CTL 0x0a1e +#define WCD934X_CDC_ANC1_LPF_FF_B_CTL 0x0a1f +#define WCD934X_CDC_ANC1_LPF_FB_CTL 0x0a20 +#define WCD934X_CDC_ANC1_SMLPF_CTL 0x0a21 +#define WCD934X_CDC_ANC1_DCFLT_SHIFT_CTL 0x0a22 +#define WCD934X_CDC_ANC1_IIR_ADAPT_CTL 0x0a23 +#define WCD934X_CDC_ANC1_IIR_COEFF_1_CTL 0x0a24 +#define WCD934X_CDC_ANC1_IIR_COEFF_2_CTL 0x0a25 +#define WCD934X_CDC_ANC1_FF_A_GAIN_CTL 0x0a26 +#define WCD934X_CDC_ANC1_FF_B_GAIN_CTL 0x0a27 +#define WCD934X_CDC_ANC1_FB_GAIN_CTL 0x0a28 +#define WCD934X_CDC_ANC1_RC_COMMON_CTL 0x0a29 +#define WCD934X_CDC_ANC1_FIFO_COMMON_CTL 0x0a2b +#define WCD934X_CDC_ANC1_RC0_STATUS_FMIN_CNTR 0x0a2c +#define WCD934X_CDC_ANC1_RC1_STATUS_FMIN_CNTR 0x0a2d +#define WCD934X_CDC_ANC1_RC0_STATUS_FMAX_CNTR 0x0a2e +#define WCD934X_CDC_ANC1_RC1_STATUS_FMAX_CNTR 0x0a2f +#define WCD934X_CDC_ANC1_STATUS_FIFO 0x0a30 +#define WCD934X_CDC_TX0_TX_PATH_CTL 0x0a31 +#define WCD934X_CDC_TX0_TX_PATH_CFG0 0x0a32 +#define WCD934X_CDC_TX0_TX_PATH_CFG1 0x0a33 +#define WCD934X_CDC_TX0_TX_VOL_CTL 0x0a34 +#define WCD934X_CDC_TX0_TX_PATH_192_CTL 0x0a35 +#define WCD934X_CDC_TX0_TX_PATH_192_CFG 0x0a36 +#define WCD934X_CDC_TX0_TX_PATH_SEC0 0x0a37 +#define WCD934X_CDC_TX0_TX_PATH_SEC1 0x0a38 +#define WCD934X_CDC_TX0_TX_PATH_SEC2 0x0a39 +#define WCD934X_CDC_TX0_TX_PATH_SEC3 0x0a3a +#define WCD934X_CDC_TX0_TX_PATH_SEC4 0x0a3b +#define WCD934X_CDC_TX0_TX_PATH_SEC5 0x0a3c +#define WCD934X_CDC_TX0_TX_PATH_SEC6 0x0a3d +#define WCD934X_CDC_TX0_TX_PATH_SEC7 0x0a3e +#define WCD934X_CDC_TX1_TX_PATH_CTL 0x0a41 +#define WCD934X_CDC_TX1_TX_PATH_CFG0 0x0a42 +#define WCD934X_CDC_TX1_TX_PATH_CFG1 0x0a43 +#define WCD934X_CDC_TX1_TX_VOL_CTL 0x0a44 +#define WCD934X_CDC_TX1_TX_PATH_192_CTL 0x0a45 +#define WCD934X_CDC_TX1_TX_PATH_192_CFG 0x0a46 +#define WCD934X_CDC_TX1_TX_PATH_SEC0 0x0a47 +#define WCD934X_CDC_TX1_TX_PATH_SEC1 0x0a48 +#define WCD934X_CDC_TX1_TX_PATH_SEC2 0x0a49 +#define WCD934X_CDC_TX1_TX_PATH_SEC3 0x0a4a +#define WCD934X_CDC_TX1_TX_PATH_SEC4 0x0a4b +#define WCD934X_CDC_TX1_TX_PATH_SEC5 0x0a4c +#define WCD934X_CDC_TX1_TX_PATH_SEC6 0x0a4d +#define WCD934X_CDC_TX2_TX_PATH_CTL 0x0a51 +#define WCD934X_CDC_TX2_TX_PATH_CFG0 0x0a52 +#define WCD934X_CDC_TX2_TX_PATH_CFG1 0x0a53 +#define WCD934X_CDC_TX2_TX_VOL_CTL 0x0a54 +#define WCD934X_CDC_TX2_TX_PATH_192_CTL 0x0a55 +#define WCD934X_CDC_TX2_TX_PATH_192_CFG 0x0a56 +#define WCD934X_CDC_TX2_TX_PATH_SEC0 0x0a57 +#define WCD934X_CDC_TX2_TX_PATH_SEC1 0x0a58 +#define WCD934X_CDC_TX2_TX_PATH_SEC2 0x0a59 +#define WCD934X_CDC_TX2_TX_PATH_SEC3 0x0a5a +#define WCD934X_CDC_TX2_TX_PATH_SEC4 0x0a5b +#define WCD934X_CDC_TX2_TX_PATH_SEC5 0x0a5c +#define WCD934X_CDC_TX2_TX_PATH_SEC6 0x0a5d +#define WCD934X_CDC_TX3_TX_PATH_CTL 0x0a61 +#define WCD934X_CDC_TX3_TX_PATH_CFG0 0x0a62 +#define WCD934X_CDC_TX3_TX_PATH_CFG1 0x0a63 +#define WCD934X_CDC_TX3_TX_VOL_CTL 0x0a64 +#define WCD934X_CDC_TX3_TX_PATH_192_CTL 0x0a65 +#define WCD934X_CDC_TX3_TX_PATH_192_CFG 0x0a66 +#define WCD934X_CDC_TX3_TX_PATH_SEC0 0x0a67 +#define WCD934X_CDC_TX3_TX_PATH_SEC1 0x0a68 +#define WCD934X_CDC_TX3_TX_PATH_SEC2 0x0a69 +#define WCD934X_CDC_TX3_TX_PATH_SEC3 0x0a6a +#define WCD934X_CDC_TX3_TX_PATH_SEC4 0x0a6b +#define WCD934X_CDC_TX3_TX_PATH_SEC5 0x0a6c +#define WCD934X_CDC_TX3_TX_PATH_SEC6 0x0a6d +#define WCD934X_CDC_TX4_TX_PATH_CTL 0x0a71 +#define WCD934X_CDC_TX4_TX_PATH_CFG0 0x0a72 +#define WCD934X_CDC_TX4_TX_PATH_CFG1 0x0a73 +#define WCD934X_CDC_TX4_TX_VOL_CTL 0x0a74 +#define WCD934X_CDC_TX4_TX_PATH_192_CTL 0x0a75 +#define WCD934X_CDC_TX4_TX_PATH_192_CFG 0x0a76 +#define WCD934X_CDC_TX4_TX_PATH_SEC0 0x0a77 +#define WCD934X_CDC_TX4_TX_PATH_SEC1 0x0a78 +#define WCD934X_CDC_TX4_TX_PATH_SEC2 0x0a79 +#define WCD934X_CDC_TX4_TX_PATH_SEC3 0x0a7a +#define WCD934X_CDC_TX4_TX_PATH_SEC4 0x0a7b +#define WCD934X_CDC_TX4_TX_PATH_SEC5 0x0a7c +#define WCD934X_CDC_TX4_TX_PATH_SEC6 0x0a7d +#define WCD934X_CDC_TX5_TX_PATH_CTL 0x0a81 +#define WCD934X_CDC_TX5_TX_PATH_CFG0 0x0a82 +#define WCD934X_CDC_TX5_TX_PATH_CFG1 0x0a83 +#define WCD934X_CDC_TX5_TX_VOL_CTL 0x0a84 +#define WCD934X_CDC_TX5_TX_PATH_192_CTL 0x0a85 +#define WCD934X_CDC_TX5_TX_PATH_192_CFG 0x0a86 +#define WCD934X_CDC_TX5_TX_PATH_SEC0 0x0a87 +#define WCD934X_CDC_TX5_TX_PATH_SEC1 0x0a88 +#define WCD934X_CDC_TX5_TX_PATH_SEC2 0x0a89 +#define WCD934X_CDC_TX5_TX_PATH_SEC3 0x0a8a +#define WCD934X_CDC_TX5_TX_PATH_SEC4 0x0a8b +#define WCD934X_CDC_TX5_TX_PATH_SEC5 0x0a8c +#define WCD934X_CDC_TX5_TX_PATH_SEC6 0x0a8d +#define WCD934X_CDC_TX6_TX_PATH_CTL 0x0a91 +#define WCD934X_CDC_TX6_TX_PATH_CFG0 0x0a92 +#define WCD934X_CDC_TX6_TX_PATH_CFG1 0x0a93 +#define WCD934X_CDC_TX6_TX_VOL_CTL 0x0a94 +#define WCD934X_CDC_TX6_TX_PATH_192_CTL 0x0a95 +#define WCD934X_CDC_TX6_TX_PATH_192_CFG 0x0a96 +#define WCD934X_CDC_TX6_TX_PATH_SEC0 0x0a97 +#define WCD934X_CDC_TX6_TX_PATH_SEC1 0x0a98 +#define WCD934X_CDC_TX6_TX_PATH_SEC2 0x0a99 +#define WCD934X_CDC_TX6_TX_PATH_SEC3 0x0a9a +#define WCD934X_CDC_TX6_TX_PATH_SEC4 0x0a9b +#define WCD934X_CDC_TX6_TX_PATH_SEC5 0x0a9c +#define WCD934X_CDC_TX6_TX_PATH_SEC6 0x0a9d +#define WCD934X_CDC_TX7_TX_PATH_CTL 0x0aa1 +#define WCD934X_CDC_TX7_TX_PATH_CFG0 0x0aa2 +#define WCD934X_CDC_TX7_TX_PATH_CFG1 0x0aa3 +#define WCD934X_CDC_TX7_TX_VOL_CTL 0x0aa4 +#define WCD934X_CDC_TX7_TX_PATH_192_CTL 0x0aa5 +#define WCD934X_CDC_TX7_TX_PATH_192_CFG 0x0aa6 +#define WCD934X_CDC_TX7_TX_PATH_SEC0 0x0aa7 +#define WCD934X_CDC_TX7_TX_PATH_SEC1 0x0aa8 +#define WCD934X_CDC_TX7_TX_PATH_SEC2 0x0aa9 +#define WCD934X_CDC_TX7_TX_PATH_SEC3 0x0aaa +#define WCD934X_CDC_TX7_TX_PATH_SEC4 0x0aab +#define WCD934X_CDC_TX7_TX_PATH_SEC5 0x0aac +#define WCD934X_CDC_TX7_TX_PATH_SEC6 0x0aad +#define WCD934X_CDC_TX8_TX_PATH_CTL 0x0ab1 +#define WCD934X_CDC_TX8_TX_PATH_CFG0 0x0ab2 +#define WCD934X_CDC_TX8_TX_PATH_CFG1 0x0ab3 +#define WCD934X_CDC_TX8_TX_VOL_CTL 0x0ab4 +#define WCD934X_CDC_TX8_TX_PATH_192_CTL 0x0ab5 +#define WCD934X_CDC_TX8_TX_PATH_192_CFG 0x0ab6 +#define WCD934X_CDC_TX8_TX_PATH_SEC0 0x0ab7 +#define WCD934X_CDC_TX8_TX_PATH_SEC1 0x0ab8 +#define WCD934X_CDC_TX8_TX_PATH_SEC2 0x0ab9 +#define WCD934X_CDC_TX8_TX_PATH_SEC3 0x0aba +#define WCD934X_CDC_TX8_TX_PATH_SEC4 0x0abb +#define WCD934X_CDC_TX8_TX_PATH_SEC5 0x0abc +#define WCD934X_CDC_TX8_TX_PATH_SEC6 0x0abd +#define WCD934X_CDC_TX9_SPKR_PROT_PATH_CTL 0x0ac2 +#define WCD934X_CDC_TX9_SPKR_PROT_PATH_CFG0 0x0ac3 +#define WCD934X_CDC_TX10_SPKR_PROT_PATH_CTL 0x0ac6 +#define WCD934X_CDC_TX10_SPKR_PROT_PATH_CFG0 0x0ac7 +#define WCD934X_CDC_TX11_SPKR_PROT_PATH_CTL 0x0aca +#define WCD934X_CDC_TX11_SPKR_PROT_PATH_CFG0 0x0acb +#define WCD934X_CDC_TX12_SPKR_PROT_PATH_CTL 0x0ace +#define WCD934X_CDC_TX12_SPKR_PROT_PATH_CFG0 0x0acf +#define WCD934X_PAGE11_PAGE_REGISTER 0x0b00 +#define WCD934X_CDC_COMPANDER1_CTL0 0x0b01 +#define WCD934X_CDC_COMPANDER1_CTL1 0x0b02 +#define WCD934X_CDC_COMPANDER1_CTL2 0x0b03 +#define WCD934X_CDC_COMPANDER1_CTL3 0x0b04 +#define WCD934X_CDC_COMPANDER1_CTL4 0x0b05 +#define WCD934X_CDC_COMPANDER1_CTL5 0x0b06 +#define WCD934X_CDC_COMPANDER1_CTL6 0x0b07 +#define WCD934X_CDC_COMPANDER1_CTL7 0x0b08 +#define WCD934X_CDC_COMPANDER2_CTL0 0x0b09 +#define WCD934X_CDC_COMPANDER2_CTL1 0x0b0a +#define WCD934X_CDC_COMPANDER2_CTL2 0x0b0b +#define WCD934X_CDC_COMPANDER2_CTL3 0x0b0c +#define WCD934X_CDC_COMPANDER2_CTL4 0x0b0d +#define WCD934X_CDC_COMPANDER2_CTL5 0x0b0e +#define WCD934X_CDC_COMPANDER2_CTL6 0x0b0f +#define WCD934X_CDC_COMPANDER2_CTL7 0x0b10 +#define WCD934X_CDC_COMPANDER3_CTL0 0x0b11 +#define WCD934X_CDC_COMPANDER3_CTL1 0x0b12 +#define WCD934X_CDC_COMPANDER3_CTL2 0x0b13 +#define WCD934X_CDC_COMPANDER3_CTL3 0x0b14 +#define WCD934X_CDC_COMPANDER3_CTL4 0x0b15 +#define WCD934X_CDC_COMPANDER3_CTL5 0x0b16 +#define WCD934X_CDC_COMPANDER3_CTL6 0x0b17 +#define WCD934X_CDC_COMPANDER3_CTL7 0x0b18 +#define WCD934X_CDC_COMPANDER4_CTL0 0x0b19 +#define WCD934X_CDC_COMPANDER4_CTL1 0x0b1a +#define WCD934X_CDC_COMPANDER4_CTL2 0x0b1b +#define WCD934X_CDC_COMPANDER4_CTL3 0x0b1c +#define WCD934X_CDC_COMPANDER4_CTL4 0x0b1d +#define WCD934X_CDC_COMPANDER4_CTL5 0x0b1e +#define WCD934X_CDC_COMPANDER4_CTL6 0x0b1f +#define WCD934X_CDC_COMPANDER4_CTL7 0x0b20 +#define WCD934X_CDC_COMPANDER7_CTL0 0x0b31 +#define WCD934X_CDC_COMPANDER7_CTL1 0x0b32 +#define WCD934X_CDC_COMPANDER7_CTL2 0x0b33 +#define WCD934X_CDC_COMPANDER7_CTL3 0x0b34 +#define WCD934X_CDC_COMPANDER7_CTL4 0x0b35 +#define WCD934X_CDC_COMPANDER7_CTL5 0x0b36 +#define WCD934X_CDC_COMPANDER7_CTL6 0x0b37 +#define WCD934X_CDC_COMPANDER7_CTL7 0x0b38 +#define WCD934X_CDC_COMPANDER8_CTL0 0x0b39 +#define WCD934X_CDC_COMPANDER8_CTL1 0x0b3a +#define WCD934X_CDC_COMPANDER8_CTL2 0x0b3b +#define WCD934X_CDC_COMPANDER8_CTL3 0x0b3c +#define WCD934X_CDC_COMPANDER8_CTL4 0x0b3d +#define WCD934X_CDC_COMPANDER8_CTL5 0x0b3e +#define WCD934X_CDC_COMPANDER8_CTL6 0x0b3f +#define WCD934X_CDC_COMPANDER8_CTL7 0x0b40 +#define WCD934X_CDC_RX0_RX_PATH_CTL 0x0b41 +#define WCD934X_CDC_RX0_RX_PATH_CFG0 0x0b42 +#define WCD934X_CDC_RX0_RX_PATH_CFG1 0x0b43 +#define WCD934X_CDC_RX0_RX_PATH_CFG2 0x0b44 +#define WCD934X_CDC_RX0_RX_VOL_CTL 0x0b45 +#define WCD934X_CDC_RX0_RX_PATH_MIX_CTL 0x0b46 +#define WCD934X_CDC_RX0_RX_PATH_MIX_CFG 0x0b47 +#define WCD934X_CDC_RX0_RX_VOL_MIX_CTL 0x0b48 +#define WCD934X_CDC_RX0_RX_PATH_SEC0 0x0b49 +#define WCD934X_CDC_RX0_RX_PATH_SEC1 0x0b4a +#define WCD934X_CDC_RX0_RX_PATH_SEC2 0x0b4b +#define WCD934X_CDC_RX0_RX_PATH_SEC3 0x0b4c +#define WCD934X_CDC_RX0_RX_PATH_SEC5 0x0b4e +#define WCD934X_CDC_RX0_RX_PATH_SEC6 0x0b4f +#define WCD934X_CDC_RX0_RX_PATH_SEC7 0x0b50 +#define WCD934X_CDC_RX0_RX_PATH_MIX_SEC0 0x0b51 +#define WCD934X_CDC_RX0_RX_PATH_MIX_SEC1 0x0b52 +#define WCD934X_CDC_RX0_RX_PATH_DSMDEM_CTL 0x0b53 +#define WCD934X_CDC_RX1_RX_PATH_CTL 0x0b55 +#define WCD934X_CDC_RX1_RX_PATH_CFG0 0x0b56 +#define WCD934X_CDC_RX1_RX_PATH_CFG1 0x0b57 +#define WCD934X_CDC_RX1_RX_PATH_CFG2 0x0b58 +#define WCD934X_CDC_RX1_RX_VOL_CTL 0x0b59 +#define WCD934X_CDC_RX1_RX_PATH_MIX_CTL 0x0b5a +#define WCD934X_CDC_RX1_RX_PATH_MIX_CFG 0x0b5b +#define WCD934X_CDC_RX1_RX_VOL_MIX_CTL 0x0b5c +#define WCD934X_CDC_RX1_RX_PATH_SEC0 0x0b5d +#define WCD934X_CDC_RX1_RX_PATH_SEC1 0x0b5e +#define WCD934X_CDC_RX1_RX_PATH_SEC2 0x0b5f +#define WCD934X_CDC_RX1_RX_PATH_SEC3 0x0b60 +#define WCD934X_CDC_RX1_RX_PATH_SEC4 0x0b61 +#define WCD934X_CDC_RX1_RX_PATH_SEC5 0x0b62 +#define WCD934X_CDC_RX1_RX_PATH_SEC6 0x0b63 +#define WCD934X_CDC_RX1_RX_PATH_SEC7 0x0b64 +#define WCD934X_CDC_RX1_RX_PATH_MIX_SEC0 0x0b65 +#define WCD934X_CDC_RX1_RX_PATH_MIX_SEC1 0x0b66 +#define WCD934X_CDC_RX1_RX_PATH_DSMDEM_CTL 0x0b67 +#define WCD934X_CDC_RX2_RX_PATH_CTL 0x0b69 +#define WCD934X_CDC_RX2_RX_PATH_CFG0 0x0b6a +#define WCD934X_CDC_RX2_RX_PATH_CFG1 0x0b6b +#define WCD934X_CDC_RX2_RX_PATH_CFG2 0x0b6c +#define WCD934X_CDC_RX2_RX_VOL_CTL 0x0b6d +#define WCD934X_CDC_RX2_RX_PATH_MIX_CTL 0x0b6e +#define WCD934X_CDC_RX2_RX_PATH_MIX_CFG 0x0b6f +#define WCD934X_CDC_RX2_RX_VOL_MIX_CTL 0x0b70 +#define WCD934X_CDC_RX2_RX_PATH_SEC0 0x0b71 +#define WCD934X_CDC_RX2_RX_PATH_SEC1 0x0b72 +#define WCD934X_CDC_RX2_RX_PATH_SEC2 0x0b73 +#define WCD934X_CDC_RX2_RX_PATH_SEC3 0x0b74 +#define WCD934X_CDC_RX2_RX_PATH_SEC4 0x0b75 +#define WCD934X_CDC_RX2_RX_PATH_SEC5 0x0b76 +#define WCD934X_CDC_RX2_RX_PATH_SEC6 0x0b77 +#define WCD934X_CDC_RX2_RX_PATH_SEC7 0x0b78 +#define WCD934X_CDC_RX2_RX_PATH_MIX_SEC0 0x0b79 +#define WCD934X_CDC_RX2_RX_PATH_MIX_SEC1 0x0b7a +#define WCD934X_CDC_RX2_RX_PATH_DSMDEM_CTL 0x0b7b +#define WCD934X_CDC_RX3_RX_PATH_CTL 0x0b7d +#define WCD934X_CDC_RX3_RX_PATH_CFG0 0x0b7e +#define WCD934X_CDC_RX3_RX_PATH_CFG1 0x0b7f +#define WCD934X_CDC_RX3_RX_PATH_CFG2 0x0b80 +#define WCD934X_CDC_RX3_RX_VOL_CTL 0x0b81 +#define WCD934X_CDC_RX3_RX_PATH_MIX_CTL 0x0b82 +#define WCD934X_CDC_RX3_RX_PATH_MIX_CFG 0x0b83 +#define WCD934X_CDC_RX3_RX_VOL_MIX_CTL 0x0b84 +#define WCD934X_CDC_RX3_RX_PATH_SEC0 0x0b85 +#define WCD934X_CDC_RX3_RX_PATH_SEC1 0x0b86 +#define WCD934X_CDC_RX3_RX_PATH_SEC2 0x0b87 +#define WCD934X_CDC_RX3_RX_PATH_SEC3 0x0b88 +#define WCD934X_CDC_RX3_RX_PATH_SEC5 0x0b8a +#define WCD934X_CDC_RX3_RX_PATH_SEC6 0x0b8b +#define WCD934X_CDC_RX3_RX_PATH_SEC7 0x0b8c +#define WCD934X_CDC_RX3_RX_PATH_MIX_SEC0 0x0b8d +#define WCD934X_CDC_RX3_RX_PATH_MIX_SEC1 0x0b8e +#define WCD934X_CDC_RX3_RX_PATH_DSMDEM_CTL 0x0b8f +#define WCD934X_CDC_RX4_RX_PATH_CTL 0x0b91 +#define WCD934X_CDC_RX4_RX_PATH_CFG0 0x0b92 +#define WCD934X_CDC_RX4_RX_PATH_CFG1 0x0b93 +#define WCD934X_CDC_RX4_RX_PATH_CFG2 0x0b94 +#define WCD934X_CDC_RX4_RX_VOL_CTL 0x0b95 +#define WCD934X_CDC_RX4_RX_PATH_MIX_CTL 0x0b96 +#define WCD934X_CDC_RX4_RX_PATH_MIX_CFG 0x0b97 +#define WCD934X_CDC_RX4_RX_VOL_MIX_CTL 0x0b98 +#define WCD934X_CDC_RX4_RX_PATH_SEC0 0x0b99 +#define WCD934X_CDC_RX4_RX_PATH_SEC1 0x0b9a +#define WCD934X_CDC_RX4_RX_PATH_SEC2 0x0b9b +#define WCD934X_CDC_RX4_RX_PATH_SEC3 0x0b9c +#define WCD934X_CDC_RX4_RX_PATH_SEC5 0x0b9e +#define WCD934X_CDC_RX4_RX_PATH_SEC6 0x0b9f +#define WCD934X_CDC_RX4_RX_PATH_SEC7 0x0ba0 +#define WCD934X_CDC_RX4_RX_PATH_MIX_SEC0 0x0ba1 +#define WCD934X_CDC_RX4_RX_PATH_MIX_SEC1 0x0ba2 +#define WCD934X_CDC_RX4_RX_PATH_DSMDEM_CTL 0x0ba3 +#define WCD934X_CDC_RX7_RX_PATH_CTL 0x0bcd +#define WCD934X_CDC_RX7_RX_PATH_CFG0 0x0bce +#define WCD934X_CDC_RX7_RX_PATH_CFG1 0x0bcf +#define WCD934X_CDC_RX7_RX_PATH_CFG2 0x0bd0 +#define WCD934X_CDC_RX7_RX_VOL_CTL 0x0bd1 +#define WCD934X_CDC_RX7_RX_PATH_MIX_CTL 0x0bd2 +#define WCD934X_CDC_RX7_RX_PATH_MIX_CFG 0x0bd3 +#define WCD934X_CDC_RX7_RX_VOL_MIX_CTL 0x0bd4 +#define WCD934X_CDC_RX7_RX_PATH_SEC0 0x0bd5 +#define WCD934X_CDC_RX7_RX_PATH_SEC1 0x0bd6 +#define WCD934X_CDC_RX7_RX_PATH_SEC2 0x0bd7 +#define WCD934X_CDC_RX7_RX_PATH_SEC3 0x0bd8 +#define WCD934X_CDC_RX7_RX_PATH_SEC5 0x0bda +#define WCD934X_CDC_RX7_RX_PATH_SEC6 0x0bdb +#define WCD934X_CDC_RX7_RX_PATH_SEC7 0x0bdc +#define WCD934X_CDC_RX7_RX_PATH_MIX_SEC0 0x0bdd +#define WCD934X_CDC_RX7_RX_PATH_MIX_SEC1 0x0bde +#define WCD934X_CDC_RX7_RX_PATH_DSMDEM_CTL 0x0bdf +#define WCD934X_CDC_RX8_RX_PATH_CTL 0x0be1 +#define WCD934X_CDC_RX8_RX_PATH_CFG0 0x0be2 +#define WCD934X_CDC_RX8_RX_PATH_CFG1 0x0be3 +#define WCD934X_CDC_RX8_RX_PATH_CFG2 0x0be4 +#define WCD934X_CDC_RX8_RX_VOL_CTL 0x0be5 +#define WCD934X_CDC_RX8_RX_PATH_MIX_CTL 0x0be6 +#define WCD934X_CDC_RX8_RX_PATH_MIX_CFG 0x0be7 +#define WCD934X_CDC_RX8_RX_VOL_MIX_CTL 0x0be8 +#define WCD934X_CDC_RX8_RX_PATH_SEC0 0x0be9 +#define WCD934X_CDC_RX8_RX_PATH_SEC1 0x0bea +#define WCD934X_CDC_RX8_RX_PATH_SEC2 0x0beb +#define WCD934X_CDC_RX8_RX_PATH_SEC3 0x0bec +#define WCD934X_CDC_RX8_RX_PATH_SEC5 0x0bee +#define WCD934X_CDC_RX8_RX_PATH_SEC6 0x0bef +#define WCD934X_CDC_RX8_RX_PATH_SEC7 0x0bf0 +#define WCD934X_CDC_RX8_RX_PATH_MIX_SEC0 0x0bf1 +#define WCD934X_CDC_RX8_RX_PATH_MIX_SEC1 0x0bf2 +#define WCD934X_CDC_RX8_RX_PATH_DSMDEM_CTL 0x0bf3 +#define WCD934X_PAGE12_PAGE_REGISTER 0x0c00 +#define WCD934X_CDC_CLSH_CRC 0x0c01 +#define WCD934X_CDC_CLSH_DLY_CTRL 0x0c02 +#define WCD934X_CDC_CLSH_DECAY_CTRL 0x0c03 +#define WCD934X_CDC_CLSH_HPH_V_PA 0x0c04 +#define WCD934X_CDC_CLSH_EAR_V_PA 0x0c05 +#define WCD934X_CDC_CLSH_HPH_V_HD 0x0c06 +#define WCD934X_CDC_CLSH_EAR_V_HD 0x0c07 +#define WCD934X_CDC_CLSH_K1_MSB 0x0c08 +#define WCD934X_CDC_CLSH_K1_LSB 0x0c09 +#define WCD934X_CDC_CLSH_K2_MSB 0x0c0a +#define WCD934X_CDC_CLSH_K2_LSB 0x0c0b +#define WCD934X_CDC_CLSH_IDLE_CTRL 0x0c0c +#define WCD934X_CDC_CLSH_IDLE_HPH 0x0c0d +#define WCD934X_CDC_CLSH_IDLE_EAR 0x0c0e +#define WCD934X_CDC_CLSH_TEST0 0x0c0f +#define WCD934X_CDC_CLSH_TEST1 0x0c10 +#define WCD934X_CDC_CLSH_OVR_VREF 0x0c11 +#define WCD934X_CDC_BOOST0_BOOST_PATH_CTL 0x0c19 +#define WCD934X_CDC_BOOST0_BOOST_CTL 0x0c1a +#define WCD934X_CDC_BOOST0_BOOST_CFG1 0x0c1b +#define WCD934X_CDC_BOOST0_BOOST_CFG2 0x0c1c +#define WCD934X_CDC_BOOST1_BOOST_PATH_CTL 0x0c21 +#define WCD934X_CDC_BOOST1_BOOST_CTL 0x0c22 +#define WCD934X_CDC_BOOST1_BOOST_CFG1 0x0c23 +#define WCD934X_CDC_BOOST1_BOOST_CFG2 0x0c24 +#define WCD934X_CDC_VBAT_VBAT_PATH_CTL 0x0c3d +#define WCD934X_CDC_VBAT_VBAT_CFG 0x0c3e +#define WCD934X_CDC_VBAT_VBAT_ADC_CAL1 0x0c3f +#define WCD934X_CDC_VBAT_VBAT_ADC_CAL2 0x0c40 +#define WCD934X_CDC_VBAT_VBAT_ADC_CAL3 0x0c41 +#define WCD934X_CDC_VBAT_VBAT_PK_EST1 0x0c42 +#define WCD934X_CDC_VBAT_VBAT_PK_EST2 0x0c43 +#define WCD934X_CDC_VBAT_VBAT_PK_EST3 0x0c44 +#define WCD934X_CDC_VBAT_VBAT_RF_PROC1 0x0c45 +#define WCD934X_CDC_VBAT_VBAT_RF_PROC2 0x0c46 +#define WCD934X_CDC_VBAT_VBAT_TAC1 0x0c47 +#define WCD934X_CDC_VBAT_VBAT_TAC2 0x0c48 +#define WCD934X_CDC_VBAT_VBAT_TAC3 0x0c49 +#define WCD934X_CDC_VBAT_VBAT_TAC4 0x0c4a +#define WCD934X_CDC_VBAT_VBAT_GAIN_UPD1 0x0c4b +#define WCD934X_CDC_VBAT_VBAT_GAIN_UPD2 0x0c4c +#define WCD934X_CDC_VBAT_VBAT_GAIN_UPD3 0x0c4d +#define WCD934X_CDC_VBAT_VBAT_GAIN_UPD4 0x0c4e +#define WCD934X_CDC_VBAT_VBAT_DEBUG1 0x0c4f +#define WCD934X_CDC_VBAT_VBAT_GAIN_UPD_MON 0x0c50 +#define WCD934X_CDC_VBAT_VBAT_GAIN_MON_VAL 0x0c51 +#define WCD934X_CDC_VBAT_VBAT_BAN 0x0c52 +#define WCD934X_MIXING_ASRC0_CLK_RST_CTL 0x0c55 +#define WCD934X_MIXING_ASRC0_CTL0 0x0c56 +#define WCD934X_MIXING_ASRC0_CTL1 0x0c57 +#define WCD934X_MIXING_ASRC0_FIFO_CTL 0x0c58 +#define WCD934X_MIXING_ASRC0_STATUS_FMIN_CNTR_LSB 0x0c59 +#define WCD934X_MIXING_ASRC0_STATUS_FMIN_CNTR_MSB 0x0c5a +#define WCD934X_MIXING_ASRC0_STATUS_FMAX_CNTR_LSB 0x0c5b +#define WCD934X_MIXING_ASRC0_STATUS_FMAX_CNTR_MSB 0x0c5c +#define WCD934X_MIXING_ASRC0_STATUS_FIFO 0x0c5d +#define WCD934X_MIXING_ASRC1_CLK_RST_CTL 0x0c61 +#define WCD934X_MIXING_ASRC1_CTL0 0x0c62 +#define WCD934X_MIXING_ASRC1_CTL1 0x0c63 +#define WCD934X_MIXING_ASRC1_FIFO_CTL 0x0c64 +#define WCD934X_MIXING_ASRC1_STATUS_FMIN_CNTR_LSB 0x0c65 +#define WCD934X_MIXING_ASRC1_STATUS_FMIN_CNTR_MSB 0x0c66 +#define WCD934X_MIXING_ASRC1_STATUS_FMAX_CNTR_LSB 0x0c67 +#define WCD934X_MIXING_ASRC1_STATUS_FMAX_CNTR_MSB 0x0c68 +#define WCD934X_MIXING_ASRC1_STATUS_FIFO 0x0c69 +#define WCD934X_MIXING_ASRC2_CLK_RST_CTL 0x0c6d +#define WCD934X_MIXING_ASRC2_CTL0 0x0c6e +#define WCD934X_MIXING_ASRC2_CTL1 0x0c6f +#define WCD934X_MIXING_ASRC2_FIFO_CTL 0x0c70 +#define WCD934X_MIXING_ASRC2_STATUS_FMIN_CNTR_LSB 0x0c71 +#define WCD934X_MIXING_ASRC2_STATUS_FMIN_CNTR_MSB 0x0c72 +#define WCD934X_MIXING_ASRC2_STATUS_FMAX_CNTR_LSB 0x0c73 +#define WCD934X_MIXING_ASRC2_STATUS_FMAX_CNTR_MSB 0x0c74 +#define WCD934X_MIXING_ASRC2_STATUS_FIFO 0x0c75 +#define WCD934X_MIXING_ASRC3_CLK_RST_CTL 0x0c79 +#define WCD934X_MIXING_ASRC3_CTL0 0x0c7a +#define WCD934X_MIXING_ASRC3_CTL1 0x0c7b +#define WCD934X_MIXING_ASRC3_FIFO_CTL 0x0c7c +#define WCD934X_MIXING_ASRC3_STATUS_FMIN_CNTR_LSB 0x0c7d +#define WCD934X_MIXING_ASRC3_STATUS_FMIN_CNTR_MSB 0x0c7e +#define WCD934X_MIXING_ASRC3_STATUS_FMAX_CNTR_LSB 0x0c7f +#define WCD934X_MIXING_ASRC3_STATUS_FMAX_CNTR_MSB 0x0c80 +#define WCD934X_MIXING_ASRC3_STATUS_FIFO 0x0c81 +#define WCD934X_SWR_AHB_BRIDGE_WR_DATA_0 0x0c85 +#define WCD934X_SWR_AHB_BRIDGE_WR_DATA_1 0x0c86 +#define WCD934X_SWR_AHB_BRIDGE_WR_DATA_2 0x0c87 +#define WCD934X_SWR_AHB_BRIDGE_WR_DATA_3 0x0c88 +#define WCD934X_SWR_AHB_BRIDGE_WR_ADDR_0 0x0c89 +#define WCD934X_SWR_AHB_BRIDGE_WR_ADDR_1 0x0c8a +#define WCD934X_SWR_AHB_BRIDGE_WR_ADDR_2 0x0c8b +#define WCD934X_SWR_AHB_BRIDGE_WR_ADDR_3 0x0c8c +#define WCD934X_SWR_AHB_BRIDGE_RD_ADDR_0 0x0c8d +#define WCD934X_SWR_AHB_BRIDGE_RD_ADDR_1 0x0c8e +#define WCD934X_SWR_AHB_BRIDGE_RD_ADDR_2 0x0c8f +#define WCD934X_SWR_AHB_BRIDGE_RD_ADDR_3 0x0c90 +#define WCD934X_SWR_AHB_BRIDGE_RD_DATA_0 0x0c91 +#define WCD934X_SWR_AHB_BRIDGE_RD_DATA_1 0x0c92 +#define WCD934X_SWR_AHB_BRIDGE_RD_DATA_2 0x0c93 +#define WCD934X_SWR_AHB_BRIDGE_RD_DATA_3 0x0c94 +#define WCD934X_SWR_AHB_BRIDGE_ACCESS_CFG 0x0c95 +#define WCD934X_SWR_AHB_BRIDGE_ACCESS_STATUS 0x0c96 +#define WCD934X_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL 0x0cb5 +#define WCD934X_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1 0x0cb6 +#define WCD934X_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL 0x0cb9 +#define WCD934X_CDC_SIDETONE_SRC1_ST_SRC_PATH_CFG1 0x0cba +#define WCD934X_SIDETONE_ASRC0_CLK_RST_CTL 0x0cbd +#define WCD934X_SIDETONE_ASRC0_CTL0 0x0cbe +#define WCD934X_SIDETONE_ASRC0_CTL1 0x0cbf +#define WCD934X_SIDETONE_ASRC0_FIFO_CTL 0x0cc0 +#define WCD934X_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB 0x0cc1 +#define WCD934X_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB 0x0cc2 +#define WCD934X_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB 0x0cc3 +#define WCD934X_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB 0x0cc4 +#define WCD934X_SIDETONE_ASRC0_STATUS_FIFO 0x0cc5 +#define WCD934X_SIDETONE_ASRC1_CLK_RST_CTL 0x0cc9 +#define WCD934X_SIDETONE_ASRC1_CTL0 0x0cca +#define WCD934X_SIDETONE_ASRC1_CTL1 0x0ccb +#define WCD934X_SIDETONE_ASRC1_FIFO_CTL 0x0ccc +#define WCD934X_SIDETONE_ASRC1_STATUS_FMIN_CNTR_LSB 0x0ccd +#define WCD934X_SIDETONE_ASRC1_STATUS_FMIN_CNTR_MSB 0x0cce +#define WCD934X_SIDETONE_ASRC1_STATUS_FMAX_CNTR_LSB 0x0ccf +#define WCD934X_SIDETONE_ASRC1_STATUS_FMAX_CNTR_MSB 0x0cd0 +#define WCD934X_SIDETONE_ASRC1_STATUS_FIFO 0x0cd1 +#define WCD934X_EC_REF_HQ0_EC_REF_HQ_PATH_CTL 0x0cd5 +#define WCD934X_EC_REF_HQ0_EC_REF_HQ_CFG0 0x0cd6 +#define WCD934X_EC_REF_HQ1_EC_REF_HQ_PATH_CTL 0x0cdd +#define WCD934X_EC_REF_HQ1_EC_REF_HQ_CFG0 0x0cde +#define WCD934X_EC_ASRC0_CLK_RST_CTL 0x0ce5 +#define WCD934X_EC_ASRC0_CTL0 0x0ce6 +#define WCD934X_EC_ASRC0_CTL1 0x0ce7 +#define WCD934X_EC_ASRC0_FIFO_CTL 0x0ce8 +#define WCD934X_EC_ASRC0_STATUS_FMIN_CNTR_LSB 0x0ce9 +#define WCD934X_EC_ASRC0_STATUS_FMIN_CNTR_MSB 0x0cea +#define WCD934X_EC_ASRC0_STATUS_FMAX_CNTR_LSB 0x0ceb +#define WCD934X_EC_ASRC0_STATUS_FMAX_CNTR_MSB 0x0cec +#define WCD934X_EC_ASRC0_STATUS_FIFO 0x0ced +#define WCD934X_EC_ASRC1_CLK_RST_CTL 0x0cf1 +#define WCD934X_EC_ASRC1_CTL0 0x0cf2 +#define WCD934X_EC_ASRC1_CTL1 0x0cf3 +#define WCD934X_EC_ASRC1_FIFO_CTL 0x0cf4 +#define WCD934X_EC_ASRC1_STATUS_FMIN_CNTR_LSB 0x0cf5 +#define WCD934X_EC_ASRC1_STATUS_FMIN_CNTR_MSB 0x0cf6 +#define WCD934X_EC_ASRC1_STATUS_FMAX_CNTR_LSB 0x0cf7 +#define WCD934X_EC_ASRC1_STATUS_FMAX_CNTR_MSB 0x0cf8 +#define WCD934X_EC_ASRC1_STATUS_FIFO 0x0cf9 +#define WCD934X_PAGE13_PAGE_REGISTER 0x0d00 +#define WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG0 0x0d01 +#define WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG1 0x0d02 +#define WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG0 0x0d03 +#define WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG1 0x0d04 +#define WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG0 0x0d05 +#define WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG1 0x0d06 +#define WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG0 0x0d07 +#define WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG1 0x0d08 +#define WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG0 0x0d09 +#define WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG1 0x0d0a +#define WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG0 0x0d0f +#define WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG1 0x0d10 +#define WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG0 0x0d11 +#define WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG1 0x0d12 +#define WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG0 0x0d13 +#define WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG1 0x0d14 +#define WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG2 0x0d15 +#define WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG3 0x0d16 +#define WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG4 0x0d17 +#define WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0 0x0d18 +#define WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1 0x0d19 +#define WCD934X_CDC_RX_INP_MUX_ANC_CFG0 0x0d1a +#define WCD934X_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0 0x0d1b +#define WCD934X_CDC_RX_INP_MUX_EC_REF_HQ_CFG0 0x0d1c +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0 0x0d1d +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1 0x0d1e +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG0 0x0d1f +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG1 0x0d20 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG0 0x0d21 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG1 0x0d22 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG0 0x0d23 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1 0x0d25 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 0x0d26 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX5_CFG0 0x0d27 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX6_CFG0 0x0d28 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX7_CFG0 0x0d29 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX8_CFG0 0x0d2a +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX10_CFG0 0x0d2b +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX11_CFG0 0x0d2c +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX12_CFG0 0x0d2d +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX13_CFG0 0x0d2e +#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0 0x0d31 +#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1 0x0d32 +#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2 0x0d33 +#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3 0x0d34 +#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0 0x0d35 +#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1 0x0d36 +#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2 0x0d37 +#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3 0x0d38 +#define WCD934X_CDC_IF_ROUTER_TX_MUX_CFG0 0x0d3a +#define WCD934X_CDC_IF_ROUTER_TX_MUX_CFG1 0x0d3b +#define WCD934X_CDC_IF_ROUTER_TX_MUX_CFG2 0x0d3c +#define WCD934X_CDC_IF_ROUTER_TX_MUX_CFG3 0x0d3d +#define WCD934X_CDC_CLK_RST_CTRL_MCLK_CONTROL 0x0d41 +#define WCD934X_CDC_CLK_RST_CTRL_FS_CNT_CONTROL 0x0d42 +#define WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL 0x0d43 +#define WCD934X_CDC_CLK_RST_CTRL_DSD_CONTROL 0x0d44 +#define WCD934X_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL 0x0d45 +#define WCD934X_CDC_CLK_RST_CTRL_GFM_CONTROL 0x0d46 +#define WCD934X_CDC_PROX_DETECT_PROX_CTL 0x0d49 +#define WCD934X_CDC_PROX_DETECT_PROX_POLL_PERIOD0 0x0d4a +#define WCD934X_CDC_PROX_DETECT_PROX_POLL_PERIOD1 0x0d4b +#define WCD934X_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB 0x0d4c +#define WCD934X_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB 0x0d4d +#define WCD934X_CDC_PROX_DETECT_PROX_STATUS 0x0d4e +#define WCD934X_CDC_PROX_DETECT_PROX_TEST_CTRL 0x0d4f +#define WCD934X_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB 0x0d50 +#define WCD934X_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB 0x0d51 +#define WCD934X_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD 0x0d52 +#define WCD934X_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD 0x0d53 +#define WCD934X_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT 0x0d54 +#define WCD934X_CDC_SIDETONE_IIR0_IIR_PATH_CTL 0x0d55 +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL 0x0d56 +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL 0x0d57 +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL 0x0d58 +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL 0x0d59 +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL 0x0d5a +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL 0x0d5b +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL 0x0d5c +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL 0x0d5d +#define WCD934X_CDC_SIDETONE_IIR0_IIR_CTL 0x0d5e +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL 0x0d5f +#define WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL 0x0d60 +#define WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL 0x0d61 +#define WCD934X_CDC_SIDETONE_IIR1_IIR_PATH_CTL 0x0d65 +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL 0x0d66 +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL 0x0d67 +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL 0x0d68 +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL 0x0d69 +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B5_CTL 0x0d6a +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B6_CTL 0x0d6b +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B7_CTL 0x0d6c +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B8_CTL 0x0d6d +#define WCD934X_CDC_SIDETONE_IIR1_IIR_CTL 0x0d6e +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL 0x0d6f +#define WCD934X_CDC_SIDETONE_IIR1_IIR_COEF_B1_CTL 0x0d70 +#define WCD934X_CDC_SIDETONE_IIR1_IIR_COEF_B2_CTL 0x0d71 +#define WCD934X_CDC_TOP_TOP_CFG0 0x0d81 +#define WCD934X_CDC_TOP_TOP_CFG1 0x0d82 +#define WCD934X_CDC_TOP_TOP_CFG7 0x0d88 +#define WCD934X_CDC_TOP_HPHL_COMP_WR_LSB 0x0d89 +#define WCD934X_CDC_TOP_HPHL_COMP_WR_MSB 0x0d8a +#define WCD934X_CDC_TOP_HPHL_COMP_LUT 0x0d8b +#define WCD934X_CDC_TOP_HPHL_COMP_RD_LSB 0x0d8c +#define WCD934X_CDC_TOP_HPHL_COMP_RD_MSB 0x0d8d +#define WCD934X_CDC_TOP_HPHR_COMP_WR_LSB 0x0d8e +#define WCD934X_CDC_TOP_HPHR_COMP_WR_MSB 0x0d8f +#define WCD934X_CDC_TOP_HPHR_COMP_LUT 0x0d90 +#define WCD934X_CDC_TOP_HPHR_COMP_RD_LSB 0x0d91 +#define WCD934X_CDC_TOP_HPHR_COMP_RD_MSB 0x0d92 +#define WCD934X_CDC_TOP_DIFFL_COMP_WR_LSB 0x0d93 +#define WCD934X_CDC_TOP_DIFFL_COMP_WR_MSB 0x0d94 +#define WCD934X_CDC_TOP_DIFFL_COMP_LUT 0x0d95 +#define WCD934X_CDC_TOP_DIFFL_COMP_RD_LSB 0x0d96 +#define WCD934X_CDC_TOP_DIFFL_COMP_RD_MSB 0x0d97 +#define WCD934X_CDC_TOP_DIFFR_COMP_WR_LSB 0x0d98 +#define WCD934X_CDC_TOP_DIFFR_COMP_WR_MSB 0x0d99 +#define WCD934X_CDC_TOP_DIFFR_COMP_LUT 0x0d9a +#define WCD934X_CDC_TOP_DIFFR_COMP_RD_LSB 0x0d9b +#define WCD934X_CDC_TOP_DIFFR_COMP_RD_MSB 0x0d9c +#define WCD934X_CDC_DSD0_PATH_CTL 0x0db1 +#define WCD934X_CDC_DSD0_CFG0 0x0db2 +#define WCD934X_CDC_DSD0_CFG1 0x0db3 +#define WCD934X_CDC_DSD0_CFG2 0x0db4 +#define WCD934X_CDC_DSD0_CFG3 0x0db5 +#define WCD934X_CDC_DSD0_CFG4 0x0db6 +#define WCD934X_CDC_DSD0_CFG5 0x0db7 +#define WCD934X_CDC_DSD1_PATH_CTL 0x0dc1 +#define WCD934X_CDC_DSD1_CFG0 0x0dc2 +#define WCD934X_CDC_DSD1_CFG1 0x0dc3 +#define WCD934X_CDC_DSD1_CFG2 0x0dc4 +#define WCD934X_CDC_DSD1_CFG3 0x0dc5 +#define WCD934X_CDC_DSD1_CFG4 0x0dc6 +#define WCD934X_CDC_DSD1_CFG5 0x0dc7 +#define WCD934X_CDC_RX_IDLE_DET_PATH_CTL 0x0dd1 +#define WCD934X_CDC_RX_IDLE_DET_CFG0 0x0dd2 +#define WCD934X_CDC_RX_IDLE_DET_CFG1 0x0dd3 +#define WCD934X_CDC_RX_IDLE_DET_CFG2 0x0dd4 +#define WCD934X_CDC_RX_IDLE_DET_CFG3 0x0dd5 +#define WCD934X_PAGE14_PAGE_REGISTER 0x0e00 +#define WCD934X_CDC_RATE_EST0_RE_CLK_RST_CTL 0x0e01 +#define WCD934X_CDC_RATE_EST0_RE_CTL 0x0e02 +#define WCD934X_CDC_RATE_EST0_RE_PULSE_SUPR_CTL 0x0e03 +#define WCD934X_CDC_RATE_EST0_RE_TIMER 0x0e04 +#define WCD934X_CDC_RATE_EST0_RE_BW_SW 0x0e05 +#define WCD934X_CDC_RATE_EST0_RE_THRESH 0x0e06 +#define WCD934X_CDC_RATE_EST0_RE_STATUS 0x0e07 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_CTRL 0x0e09 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_TIMER2 0x0e0c +#define WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW1 0x0e0d +#define WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW2 0x0e0e +#define WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW3 0x0e0f +#define WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW4 0x0e10 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW5 0x0e11 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW1 0x0e12 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW2 0x0e13 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW3 0x0e14 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW4 0x0e15 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW5 0x0e16 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW1 0x0e17 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW2 0x0e18 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW3 0x0e19 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW4 0x0e1a +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW5 0x0e1b +#define WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW1 0x0e1c +#define WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW2 0x0e1d +#define WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW3 0x0e1e +#define WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW4 0x0e1f +#define WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW5 0x0e20 +#define WCD934X_CDC_RATE_EST0_RE_RMAX_DIAG 0x0e21 +#define WCD934X_CDC_RATE_EST0_RE_RMIN_DIAG 0x0e22 +#define WCD934X_CDC_RATE_EST0_RE_PH_DET 0x0e23 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_CLR 0x0e24 +#define WCD934X_CDC_RATE_EST0_RE_MB_SW_STATE 0x0e25 +#define WCD934X_CDC_RATE_EST0_RE_MAST_DIAG_STATE 0x0e26 +#define WCD934X_CDC_RATE_EST0_RE_RATE_OUT_7_0 0x0e27 +#define WCD934X_CDC_RATE_EST0_RE_RATE_OUT_15_8 0x0e28 +#define WCD934X_CDC_RATE_EST0_RE_RATE_OUT_23_16 0x0e29 +#define WCD934X_CDC_RATE_EST0_RE_RATE_OUT_31_24 0x0e2a +#define WCD934X_CDC_RATE_EST0_RE_RATE_OUT_39_32 0x0e2b +#define WCD934X_CDC_RATE_EST0_RE_RATE_OUT_40_43 0x0e2c +#define WCD934X_CDC_RATE_EST1_RE_CLK_RST_CTL 0x0e31 +#define WCD934X_CDC_RATE_EST1_RE_CTL 0x0e32 +#define WCD934X_CDC_RATE_EST1_RE_PULSE_SUPR_CTL 0x0e33 +#define WCD934X_CDC_RATE_EST1_RE_TIMER 0x0e34 +#define WCD934X_CDC_RATE_EST1_RE_BW_SW 0x0e35 +#define WCD934X_CDC_RATE_EST1_RE_THRESH 0x0e36 +#define WCD934X_CDC_RATE_EST1_RE_STATUS 0x0e37 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_CTRL 0x0e39 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_TIMER2 0x0e3c +#define WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW1 0x0e3d +#define WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW2 0x0e3e +#define WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW3 0x0e3f +#define WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW4 0x0e40 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW5 0x0e41 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW1 0x0e42 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW2 0x0e43 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW3 0x0e44 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW4 0x0e45 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW5 0x0e46 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW1 0x0e47 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW2 0x0e48 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW3 0x0e49 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW4 0x0e4a +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW5 0x0e4b +#define WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW1 0x0e4c +#define WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW2 0x0e4d +#define WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW3 0x0e4e +#define WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW4 0x0e4f +#define WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW5 0x0e50 +#define WCD934X_CDC_RATE_EST1_RE_RMAX_DIAG 0x0e51 +#define WCD934X_CDC_RATE_EST1_RE_RMIN_DIAG 0x0e52 +#define WCD934X_CDC_RATE_EST1_RE_PH_DET 0x0e53 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_CLR 0x0e54 +#define WCD934X_CDC_RATE_EST1_RE_MB_SW_STATE 0x0e55 +#define WCD934X_CDC_RATE_EST1_RE_MAST_DIAG_STATE 0x0e56 +#define WCD934X_CDC_RATE_EST1_RE_RATE_OUT_7_0 0x0e57 +#define WCD934X_CDC_RATE_EST1_RE_RATE_OUT_15_8 0x0e58 +#define WCD934X_CDC_RATE_EST1_RE_RATE_OUT_23_16 0x0e59 +#define WCD934X_CDC_RATE_EST1_RE_RATE_OUT_31_24 0x0e5a +#define WCD934X_CDC_RATE_EST1_RE_RATE_OUT_39_32 0x0e5b +#define WCD934X_CDC_RATE_EST1_RE_RATE_OUT_40_43 0x0e5c +#define WCD934X_CDC_RATE_EST2_RE_CLK_RST_CTL 0x0e61 +#define WCD934X_CDC_RATE_EST2_RE_CTL 0x0e62 +#define WCD934X_CDC_RATE_EST2_RE_PULSE_SUPR_CTL 0x0e63 +#define WCD934X_CDC_RATE_EST2_RE_TIMER 0x0e64 +#define WCD934X_CDC_RATE_EST2_RE_BW_SW 0x0e65 +#define WCD934X_CDC_RATE_EST2_RE_THRESH 0x0e66 +#define WCD934X_CDC_RATE_EST2_RE_STATUS 0x0e67 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_CTRL 0x0e69 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_TIMER2 0x0e6c +#define WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW1 0x0e6d +#define WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW2 0x0e6e +#define WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW3 0x0e6f +#define WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW4 0x0e70 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW5 0x0e71 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW1 0x0e72 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW2 0x0e73 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW3 0x0e74 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW4 0x0e75 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW5 0x0e76 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW1 0x0e77 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW2 0x0e78 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW3 0x0e79 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW4 0x0e7a +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW5 0x0e7b +#define WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW1 0x0e7c +#define WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW2 0x0e7d +#define WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW3 0x0e7e +#define WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW4 0x0e7f +#define WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW5 0x0e80 +#define WCD934X_CDC_RATE_EST2_RE_RMAX_DIAG 0x0e81 +#define WCD934X_CDC_RATE_EST2_RE_RMIN_DIAG 0x0e82 +#define WCD934X_CDC_RATE_EST2_RE_PH_DET 0x0e83 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_CLR 0x0e84 +#define WCD934X_CDC_RATE_EST2_RE_MB_SW_STATE 0x0e85 +#define WCD934X_CDC_RATE_EST2_RE_MAST_DIAG_STATE 0x0e86 +#define WCD934X_CDC_RATE_EST2_RE_RATE_OUT_7_0 0x0e87 +#define WCD934X_CDC_RATE_EST2_RE_RATE_OUT_15_8 0x0e88 +#define WCD934X_CDC_RATE_EST2_RE_RATE_OUT_23_16 0x0e89 +#define WCD934X_CDC_RATE_EST2_RE_RATE_OUT_31_24 0x0e8a +#define WCD934X_CDC_RATE_EST2_RE_RATE_OUT_39_32 0x0e8b +#define WCD934X_CDC_RATE_EST2_RE_RATE_OUT_40_43 0x0e8c +#define WCD934X_CDC_RATE_EST3_RE_CLK_RST_CTL 0x0e91 +#define WCD934X_CDC_RATE_EST3_RE_CTL 0x0e92 +#define WCD934X_CDC_RATE_EST3_RE_PULSE_SUPR_CTL 0x0e93 +#define WCD934X_CDC_RATE_EST3_RE_TIMER 0x0e94 +#define WCD934X_CDC_RATE_EST3_RE_BW_SW 0x0e95 +#define WCD934X_CDC_RATE_EST3_RE_THRESH 0x0e96 +#define WCD934X_CDC_RATE_EST3_RE_STATUS 0x0e97 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_CTRL 0x0e99 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_TIMER2 0x0e9c +#define WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW1 0x0e9d +#define WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW2 0x0e9e +#define WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW3 0x0e9f +#define WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW4 0x0ea0 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW5 0x0ea1 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW1 0x0ea2 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW2 0x0ea3 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW3 0x0ea4 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW4 0x0ea5 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW5 0x0ea6 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW1 0x0ea7 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW2 0x0ea8 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW3 0x0ea9 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW4 0x0eaa +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW5 0x0eab +#define WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW1 0x0eac +#define WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW2 0x0ead +#define WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW3 0x0eae +#define WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW4 0x0eaf +#define WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW5 0x0eb0 +#define WCD934X_CDC_RATE_EST3_RE_RMAX_DIAG 0x0eb1 +#define WCD934X_CDC_RATE_EST3_RE_RMIN_DIAG 0x0eb2 +#define WCD934X_CDC_RATE_EST3_RE_PH_DET 0x0eb3 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_CLR 0x0eb4 +#define WCD934X_CDC_RATE_EST3_RE_MB_SW_STATE 0x0eb5 +#define WCD934X_CDC_RATE_EST3_RE_MAST_DIAG_STATE 0x0eb6 +#define WCD934X_CDC_RATE_EST3_RE_RATE_OUT_7_0 0x0eb7 +#define WCD934X_CDC_RATE_EST3_RE_RATE_OUT_15_8 0x0eb8 +#define WCD934X_CDC_RATE_EST3_RE_RATE_OUT_23_16 0x0eb9 +#define WCD934X_CDC_RATE_EST3_RE_RATE_OUT_31_24 0x0eba +#define WCD934X_CDC_RATE_EST3_RE_RATE_OUT_39_32 0x0ebb +#define WCD934X_CDC_RATE_EST3_RE_RATE_OUT_40_43 0x0ebc +#define WCD934X_PAGE15_PAGE_REGISTER 0x0f00 +#define WCD934X_SPLINE_SRC0_CLK_RST_CTL_0 0x0f01 +#define WCD934X_SPLINE_SRC0_STATUS 0x0f02 +#define WCD934X_SPLINE_SRC1_CLK_RST_CTL_0 0x0f19 +#define WCD934X_SPLINE_SRC1_STATUS 0x0f1a +#define WCD934X_SPLINE_SRC2_CLK_RST_CTL_0 0x0f31 +#define WCD934X_SPLINE_SRC2_STATUS 0x0f32 +#define WCD934X_SPLINE_SRC3_CLK_RST_CTL_0 0x0f49 +#define WCD934X_SPLINE_SRC3_STATUS 0x0f4a +#define WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG0 0x0fa1 +#define WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG1 0x0fa2 +#define WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG2 0x0fa3 +#define WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG3 0x0fa4 +#define WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG0 0x0fa5 +#define WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG1 0x0fa6 +#define WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG2 0x0fa7 +#define WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG3 0x0fa8 +#define WCD934X_CDC_DEBUG_SPLINE_SRC_DEBUG_CFG0 0x0fa9 +#define WCD934X_CDC_DEBUG_SPLINE_SRC_DEBUG_CFG1 0x0faa +#define WCD934X_CDC_DEBUG_RC_RE_ASRC_DEBUG_CFG0 0x0fab +#define WCD934X_CDC_DEBUG_ANC0_RC0_FIFO_CTL 0x0fac +#define WCD934X_CDC_DEBUG_ANC0_RC1_FIFO_CTL 0x0fad +#define WCD934X_CDC_DEBUG_ANC1_RC0_FIFO_CTL 0x0fae +#define WCD934X_CDC_DEBUG_ANC1_RC1_FIFO_CTL 0x0faf +#define WCD934X_CDC_DEBUG_ANC_RC_RST_DBG_CNTR 0x0fb0 +#define WCD934X_PAGE80_PAGE_REGISTER 0x5000 +#define WCD934X_CODEC_CPR_WR_DATA_0 0x5001 +#define WCD934X_CODEC_CPR_WR_DATA_1 0x5002 +#define WCD934X_CODEC_CPR_WR_DATA_2 0x5003 +#define WCD934X_CODEC_CPR_WR_DATA_3 0x5004 +#define WCD934X_CODEC_CPR_WR_ADDR_0 0x5005 +#define WCD934X_CODEC_CPR_WR_ADDR_1 0x5006 +#define WCD934X_CODEC_CPR_WR_ADDR_2 0x5007 +#define WCD934X_CODEC_CPR_WR_ADDR_3 0x5008 +#define WCD934X_CODEC_CPR_RD_ADDR_0 0x5009 +#define WCD934X_CODEC_CPR_RD_ADDR_1 0x500a +#define WCD934X_CODEC_CPR_RD_ADDR_2 0x500b +#define WCD934X_CODEC_CPR_RD_ADDR_3 0x500c +#define WCD934X_CODEC_CPR_RD_DATA_0 0x500d +#define WCD934X_CODEC_CPR_RD_DATA_1 0x500e +#define WCD934X_CODEC_CPR_RD_DATA_2 0x500f +#define WCD934X_CODEC_CPR_RD_DATA_3 0x5010 +#define WCD934X_CODEC_CPR_ACCESS_CFG 0x5011 +#define WCD934X_CODEC_CPR_ACCESS_STATUS 0x5012 +#define WCD934X_CODEC_CPR_NOM_CX_VDD 0x5021 +#define WCD934X_CODEC_CPR_SVS_CX_VDD 0x5022 +#define WCD934X_CODEC_CPR_SVS2_CX_VDD 0x5023 +#define WCD934X_CODEC_CPR_NOM_MX_VDD 0x5024 +#define WCD934X_CODEC_CPR_SVS_MX_VDD 0x5025 +#define WCD934X_CODEC_CPR_SVS2_MX_VDD 0x5026 +#define WCD934X_CODEC_CPR_SVS2_MIN_CX_VDD 0x5027 +#define WCD934X_CODEC_CPR_MAX_SVS2_STEP 0x5028 +#define WCD934X_CODEC_CPR_CTL 0x5029 +#define WCD934X_CODEC_CPR_SW_MODECHNG_STATUS 0x502a +#define WCD934X_CODEC_CPR_SW_MODECHNG_START 0x502b +#define WCD934X_CODEC_CPR_CPR_STATUS 0x502c +#define WCD934X_PAGE128_PAGE_REGISTER 0x8000 +#define WCD934X_TLMM_BIST_MODE_PINCFG 0x8001 +#define WCD934X_TLMM_RF_PA_ON_PINCFG 0x8002 +#define WCD934X_TLMM_INTR1_PINCFG 0x8003 +#define WCD934X_TLMM_INTR2_PINCFG 0x8004 +#define WCD934X_TLMM_SWR_DATA_PINCFG 0x8005 +#define WCD934X_TLMM_SWR_CLK_PINCFG 0x8006 +#define WCD934X_TLMM_I2S_2_SCK_PINCFG 0x8007 +#define WCD934X_TLMM_SLIMBUS_DATA1_PINCFG 0x8008 +#define WCD934X_TLMM_SLIMBUS_DATA2_PINCFG 0x8009 +#define WCD934X_TLMM_SLIMBUS_CLK_PINCFG 0x800a +#define WCD934X_TLMM_I2C_CLK_PINCFG 0x800b +#define WCD934X_TLMM_I2C_DATA_PINCFG 0x800c +#define WCD934X_TLMM_I2S_0_RX_PINCFG 0x800d +#define WCD934X_TLMM_I2S_0_TX_PINCFG 0x800e +#define WCD934X_TLMM_I2S_0_SCK_PINCFG 0x800f +#define WCD934X_TLMM_I2S_0_WS_PINCFG 0x8010 +#define WCD934X_TLMM_I2S_1_RX_PINCFG 0x8011 +#define WCD934X_TLMM_I2S_1_TX_PINCFG 0x8012 +#define WCD934X_TLMM_I2S_1_SCK_PINCFG 0x8013 +#define WCD934X_TLMM_I2S_1_WS_PINCFG 0x8014 +#define WCD934X_TLMM_DMIC1_CLK_PINCFG 0x8015 +#define WCD934X_TLMM_DMIC1_DATA_PINCFG 0x8016 +#define WCD934X_TLMM_DMIC2_CLK_PINCFG 0x8017 +#define WCD934X_TLMM_DMIC2_DATA_PINCFG 0x8018 +#define WCD934X_TLMM_DMIC3_CLK_PINCFG 0x8019 +#define WCD934X_TLMM_DMIC3_DATA_PINCFG 0x801a +#define WCD934X_TLMM_JTCK_PINCFG 0x801b +#define WCD934X_TLMM_GPIO1_PINCFG 0x801c +#define WCD934X_TLMM_GPIO2_PINCFG 0x801d +#define WCD934X_TLMM_GPIO3_PINCFG 0x801e +#define WCD934X_TLMM_GPIO4_PINCFG 0x801f +#define WCD934X_TLMM_SPI_S_CSN_PINCFG 0x8020 +#define WCD934X_TLMM_SPI_S_CLK_PINCFG 0x8021 +#define WCD934X_TLMM_SPI_S_DOUT_PINCFG 0x8022 +#define WCD934X_TLMM_SPI_S_DIN_PINCFG 0x8023 +#define WCD934X_TLMM_BA_N_PINCFG 0x8024 +#define WCD934X_TLMM_GPIO0_PINCFG 0x8025 +#define WCD934X_TLMM_I2S_2_RX_PINCFG 0x8026 +#define WCD934X_TLMM_I2S_2_WS_PINCFG 0x8027 +#define WCD934X_TEST_DEBUG_PIN_CTL_OE_0 0x8031 +#define WCD934X_TEST_DEBUG_PIN_CTL_OE_1 0x8032 +#define WCD934X_TEST_DEBUG_PIN_CTL_OE_2 0x8033 +#define WCD934X_TEST_DEBUG_PIN_CTL_OE_3 0x8034 +#define WCD934X_TEST_DEBUG_PIN_CTL_OE_4 0x8035 +#define WCD934X_TEST_DEBUG_PIN_CTL_DATA_0 0x8036 +#define WCD934X_TEST_DEBUG_PIN_CTL_DATA_1 0x8037 +#define WCD934X_TEST_DEBUG_PIN_CTL_DATA_2 0x8038 +#define WCD934X_TEST_DEBUG_PIN_CTL_DATA_3 0x8039 +#define WCD934X_TEST_DEBUG_PIN_CTL_DATA_4 0x803a +#define WCD934X_TEST_DEBUG_PAD_DRVCTL_0 0x803b +#define WCD934X_TEST_DEBUG_PAD_DRVCTL_1 0x803c +#define WCD934X_TEST_DEBUG_PIN_STATUS 0x803d +#define WCD934X_TEST_DEBUG_NPL_DLY_TEST_1 0x803e +#define WCD934X_TEST_DEBUG_NPL_DLY_TEST_2 0x803f +#define WCD934X_TEST_DEBUG_MEM_CTRL 0x8040 +#define WCD934X_TEST_DEBUG_DEBUG_BUS_SEL 0x8041 +#define WCD934X_TEST_DEBUG_DEBUG_JTAG 0x8042 +#define WCD934X_TEST_DEBUG_DEBUG_EN_1 0x8043 +#define WCD934X_TEST_DEBUG_DEBUG_EN_2 0x8044 +#define WCD934X_TEST_DEBUG_DEBUG_EN_3 0x8045 +#define WCD934X_TEST_DEBUG_DEBUG_EN_4 0x8046 +#define WCD934X_TEST_DEBUG_DEBUG_EN_5 0x8047 +#define WCD934X_TEST_DEBUG_ANA_DTEST_DIR 0x804a +#define WCD934X_TEST_DEBUG_PAD_INP_DISABLE_0 0x804b +#define WCD934X_TEST_DEBUG_PAD_INP_DISABLE_1 0x804c +#define WCD934X_TEST_DEBUG_PAD_INP_DISABLE_2 0x804d +#define WCD934X_TEST_DEBUG_PAD_INP_DISABLE_3 0x804e +#define WCD934X_TEST_DEBUG_PAD_INP_DISABLE_4 0x804f +#define WCD934X_TEST_DEBUG_SYSMEM_CTRL 0x8050 +#define WCD934X_TEST_DEBUG_SOC_SW_PWR_SEQ_DELAY 0x8051 +#define WCD934X_TEST_DEBUG_LVAL_NOM_LOW 0x8052 +#define WCD934X_TEST_DEBUG_LVAL_NOM_HIGH 0x8053 +#define WCD934X_TEST_DEBUG_LVAL_SVS_SVS2_LOW 0x8054 +#define WCD934X_TEST_DEBUG_LVAL_SVS_SVS2_HIGH 0x8055 +#define WCD934X_TEST_DEBUG_SPI_SLAVE_CHAR 0x8056 +#define WCD934X_TEST_DEBUG_CODEC_DIAGS 0x8057 +#define WCD934X_MAX_REGISTER 0x80FF + +/* SLIMBUS Slave Registers */ +#define WCD934X_SLIM_PGD_PORT_INT_RX_EN0 (0x30) +#define WCD934X_SLIM_PGD_PORT_INT_TX_EN0 (0x32) +#define WCD934X_SLIM_PGD_PORT_INT_STATUS_RX_0 (0x34) +#define WCD934X_SLIM_PGD_PORT_INT_STATUS_RX_1 (0x35) +#define WCD934X_SLIM_PGD_PORT_INT_STATUS_TX_0 (0x36) +#define WCD934X_SLIM_PGD_PORT_INT_STATUS_TX_1 (0x37) +#define WCD934X_SLIM_PGD_PORT_INT_CLR_RX_0 (0x38) +#define WCD934X_SLIM_PGD_PORT_INT_CLR_RX_1 (0x39) +#define WCD934X_SLIM_PGD_PORT_INT_CLR_TX_0 (0x3A) +#define WCD934X_SLIM_PGD_PORT_INT_CLR_TX_1 (0x3B) +#define WCD934X_SLIM_PGD_PORT_INT_RX_SOURCE0 (0x60) +#define WCD934X_SLIM_PGD_PORT_INT_TX_SOURCE0 (0x70) + +#endif diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h new file mode 100644 index 000000000000..b4c1be40ff31 --- /dev/null +++ b/include/linux/mfd/wcd9xxx/core.h @@ -0,0 +1,440 @@ +/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MFD_TABLA_CORE_H__ +#define __MFD_TABLA_CORE_H__ + +#include +#include +#include +#include +#include + +#define WCD9XXX_MAX_IRQ_REGS 4 +#define WCD9XXX_MAX_NUM_IRQS (WCD9XXX_MAX_IRQ_REGS * 8) +#define WCD9XXX_SLIM_NUM_PORT_REG 3 +#define TABLA_VERSION_1_0 0 +#define TABLA_VERSION_1_1 1 +#define TABLA_VERSION_2_0 2 +#define TABLA_IS_1_X(ver) \ + (((ver == TABLA_VERSION_1_0) || (ver == TABLA_VERSION_1_1)) ? 1 : 0) +#define TABLA_IS_2_0(ver) ((ver == TABLA_VERSION_2_0) ? 1 : 0) + +#define WCD9XXX_SUPPLY_BUCK_NAME "cdc-vdd-buck" + +#define SITAR_VERSION_1P0 0 +#define SITAR_VERSION_1P1 1 +#define SITAR_IS_1P0(ver) \ + ((ver == SITAR_VERSION_1P0) ? 1 : 0) +#define SITAR_IS_1P1(ver) \ + ((ver == SITAR_VERSION_1P1) ? 1 : 0) + +#define TAIKO_VERSION_1_0 1 +#define TAIKO_IS_1_0(ver) \ + ((ver == TAIKO_VERSION_1_0) ? 1 : 0) + +#define TAPAN_VERSION_1_0 0 +#define TAPAN_IS_1_0(ver) \ + ((ver == TAPAN_VERSION_1_0) ? 1 : 0) + +#define TOMTOM_VERSION_1_0 1 +#define TOMTOM_IS_1_0(ver) \ + ((ver == TOMTOM_VERSION_1_0) ? 1 : 0) + +#define TASHA_VERSION_1_0 0 +#define TASHA_VERSION_1_1 1 +#define TASHA_VERSION_2_0 2 + +#define TASHA_IS_1_0(wcd) \ + ((wcd->type == WCD9335 || wcd->type == WCD9326) ? \ + ((wcd->version == TASHA_VERSION_1_0) ? 1 : 0) : 0) + +#define TASHA_IS_1_1(wcd) \ + ((wcd->type == WCD9335 || wcd->type == WCD9326) ? \ + ((wcd->version == TASHA_VERSION_1_1) ? 1 : 0) : 0) + +#define TASHA_IS_2_0(wcd) \ + ((wcd->type == WCD9335 || wcd->type == WCD9326) ? \ + ((wcd->version == TASHA_VERSION_2_0) ? 1 : 0) : 0) + +/* + * As fine version info cannot be retrieved before tavil probe. + * Define three coarse versions for possible future use before tavil probe. + */ +#define TAVIL_VERSION_1_0 0 +#define TAVIL_VERSION_1_1 1 +#define TAVIL_VERSION_WCD9340_1_0 2 +#define TAVIL_VERSION_WCD9341_1_0 3 +#define TAVIL_VERSION_WCD9340_1_1 4 +#define TAVIL_VERSION_WCD9341_1_1 5 + +#define TAVIL_IS_1_0(wcd) \ + ((wcd->type == WCD934X) ? \ + ((wcd->version == TAVIL_VERSION_1_0 || \ + wcd->version == TAVIL_VERSION_WCD9340_1_0 || \ + wcd->version == TAVIL_VERSION_WCD9341_1_0) ? 1 : 0) : 0) +#define TAVIL_IS_1_1(wcd) \ + ((wcd->type == WCD934X) ? \ + ((wcd->version == TAVIL_VERSION_1_1 || \ + wcd->version == TAVIL_VERSION_WCD9340_1_1 || \ + wcd->version == TAVIL_VERSION_WCD9341_1_1) ? 1 : 0) : 0) +#define TAVIL_IS_WCD9340_1_0(wcd) \ + ((wcd->type == WCD934X) ? \ + ((wcd->version == TAVIL_VERSION_WCD9340_1_0) ? 1 : 0) : 0) +#define TAVIL_IS_WCD9341_1_0(wcd) \ + ((wcd->type == WCD934X) ? \ + ((wcd->version == TAVIL_VERSION_WCD9341_1_0) ? 1 : 0) : 0) +#define TAVIL_IS_WCD9340_1_1(wcd) \ + ((wcd->type == WCD934X) ? \ + ((wcd->version == TAVIL_VERSION_WCD9340_1_1) ? 1 : 0) : 0) +#define TAVIL_IS_WCD9341_1_1(wcd) \ + ((wcd->type == WCD934X) ? \ + ((wcd->version == TAVIL_VERSION_WCD9341_1_1) ? 1 : 0) : 0) + +#define IS_CODEC_TYPE(wcd, wcdtype) \ + ((wcd->type == wcdtype) ? true : false) +#define IS_CODEC_VERSION(wcd, wcdversion) \ + ((wcd->version == wcdversion) ? true : false) + +enum { + CDC_V_1_0, + CDC_V_1_1, + CDC_V_2_0, +}; + +enum codec_variant { + WCD9XXX, + WCD9330, + WCD9335, + WCD9326, + WCD934X, +}; + +enum wcd9xxx_slim_slave_addr_type { + WCD9XXX_SLIM_SLAVE_ADDR_TYPE_0, + WCD9XXX_SLIM_SLAVE_ADDR_TYPE_1, +}; + +enum wcd9xxx_pm_state { + WCD9XXX_PM_SLEEPABLE, + WCD9XXX_PM_AWAKE, + WCD9XXX_PM_ASLEEP, +}; + +enum { + WCD9XXX_INTR_STATUS_BASE = 0, + WCD9XXX_INTR_CLEAR_BASE, + WCD9XXX_INTR_MASK_BASE, + WCD9XXX_INTR_LEVEL_BASE, + WCD9XXX_INTR_CLR_COMMIT, + WCD9XXX_INTR_REG_MAX, +}; + +enum wcd9xxx_intf_status { + WCD9XXX_INTERFACE_TYPE_PROBING, + WCD9XXX_INTERFACE_TYPE_SLIMBUS, + WCD9XXX_INTERFACE_TYPE_I2C, +}; + +enum { + /* INTR_REG 0 */ + WCD9XXX_IRQ_SLIMBUS = 0, + WCD9XXX_IRQ_MBHC_REMOVAL, + WCD9XXX_IRQ_MBHC_SHORT_TERM, + WCD9XXX_IRQ_MBHC_PRESS, + WCD9XXX_IRQ_MBHC_RELEASE, + WCD9XXX_IRQ_MBHC_POTENTIAL, + WCD9XXX_IRQ_MBHC_INSERTION, + WCD9XXX_IRQ_BG_PRECHARGE, + /* INTR_REG 1 */ + WCD9XXX_IRQ_PA1_STARTUP, + WCD9XXX_IRQ_PA2_STARTUP, + WCD9XXX_IRQ_PA3_STARTUP, + WCD9XXX_IRQ_PA4_STARTUP, + WCD9306_IRQ_HPH_PA_OCPR_FAULT = WCD9XXX_IRQ_PA4_STARTUP, + WCD9XXX_IRQ_PA5_STARTUP, + WCD9XXX_IRQ_MICBIAS1_PRECHARGE, + WCD9306_IRQ_HPH_PA_OCPL_FAULT = WCD9XXX_IRQ_MICBIAS1_PRECHARGE, + WCD9XXX_IRQ_MICBIAS2_PRECHARGE, + WCD9XXX_IRQ_MICBIAS3_PRECHARGE, + /* INTR_REG 2 */ + WCD9XXX_IRQ_HPH_PA_OCPL_FAULT, + WCD9XXX_IRQ_HPH_PA_OCPR_FAULT, + WCD9XXX_IRQ_EAR_PA_OCPL_FAULT, + WCD9XXX_IRQ_HPH_L_PA_STARTUP, + WCD9XXX_IRQ_HPH_R_PA_STARTUP, + WCD9320_IRQ_EAR_PA_STARTUP, + WCD9306_IRQ_MBHC_JACK_SWITCH = WCD9320_IRQ_EAR_PA_STARTUP, + WCD9310_NUM_IRQS, + WCD9XXX_IRQ_RESERVED_0 = WCD9310_NUM_IRQS, + WCD9XXX_IRQ_RESERVED_1, + WCD9330_IRQ_SVASS_ERR_EXCEPTION = WCD9310_NUM_IRQS, + WCD9330_IRQ_MBHC_JACK_SWITCH, + /* INTR_REG 3 */ + WCD9XXX_IRQ_MAD_AUDIO, + WCD9XXX_IRQ_MAD_ULTRASOUND, + WCD9XXX_IRQ_MAD_BEACON, + WCD9XXX_IRQ_SPEAKER_CLIPPING, + WCD9320_IRQ_MBHC_JACK_SWITCH, + WCD9306_NUM_IRQS, + WCD9XXX_IRQ_VBAT_MONITOR_ATTACK = WCD9306_NUM_IRQS, + WCD9XXX_IRQ_VBAT_MONITOR_RELEASE, + WCD9XXX_NUM_IRQS, + /* WCD9330 INTR1_REG 3*/ + WCD9330_IRQ_SVASS_ENGINE = WCD9XXX_IRQ_MAD_AUDIO, + WCD9330_IRQ_MAD_AUDIO, + WCD9330_IRQ_MAD_ULTRASOUND, + WCD9330_IRQ_MAD_BEACON, + WCD9330_IRQ_SPEAKER1_CLIPPING, + WCD9330_IRQ_SPEAKER2_CLIPPING, + WCD9330_IRQ_VBAT_MONITOR_ATTACK, + WCD9330_IRQ_VBAT_MONITOR_RELEASE, + WCD9330_NUM_IRQS, + WCD9XXX_IRQ_RESERVED_2 = WCD9330_NUM_IRQS, +}; + +enum { + TABLA_NUM_IRQS = WCD9310_NUM_IRQS, + SITAR_NUM_IRQS = WCD9310_NUM_IRQS, + TAIKO_NUM_IRQS = WCD9XXX_NUM_IRQS, + TAPAN_NUM_IRQS = WCD9306_NUM_IRQS, + TOMTOM_NUM_IRQS = WCD9330_NUM_IRQS, +}; + +struct intr_data { + int intr_num; + bool clear_first; +}; + +struct wcd9xxx_core_resource { + struct mutex irq_lock; + struct mutex nested_irq_lock; + + enum wcd9xxx_pm_state pm_state; + struct mutex pm_lock; + /* pm_wq notifies change of pm_state */ + wait_queue_head_t pm_wq; + struct pm_qos_request pm_qos_req; + int wlock_holders; + + + /* holds the table of interrupts per codec */ + const struct intr_data *intr_table; + int intr_table_size; + unsigned int irq_base; + unsigned int irq; + u8 irq_masks_cur[WCD9XXX_MAX_IRQ_REGS]; + u8 irq_masks_cache[WCD9XXX_MAX_IRQ_REGS]; + bool irq_level_high[WCD9XXX_MAX_NUM_IRQS]; + int num_irqs; + int num_irq_regs; + u16 intr_reg[WCD9XXX_INTR_REG_MAX]; + struct regmap *wcd_core_regmap; + + /* Pointer to parent container data structure */ + void *parent; + + struct device *dev; + struct irq_domain *domain; +}; + +/* + * data structure for Slimbus and I2S channel. + * Some of fields are only used in smilbus mode + */ +struct wcd9xxx_ch { + u32 sph; /* share channel handle - slimbus only */ + u32 ch_num; /* + * vitrual channel number, such as 128 -144. + * apply for slimbus only + */ + u16 ch_h; /* chanel handle - slimbus only */ + u16 port; /* + * tabla port for RX and TX + * such as 0-9 for TX and 10 -16 for RX + * apply for both i2s and slimbus + */ + u16 shift; /* + * shift bit for RX and TX + * apply for both i2s and slimbus + */ + struct list_head list; /* + * channel link list + * apply for both i2s and slimbus + */ +}; + +struct wcd9xxx_codec_dai_data { + u32 rate; /* sample rate */ + u32 bit_width; /* sit width 16,24,32 */ + struct list_head wcd9xxx_ch_list; /* channel list */ + u16 grph; /* slimbus group handle */ + unsigned long ch_mask; + wait_queue_head_t dai_wait; + bool bus_down_in_recovery; +}; + +#define WCD9XXX_CH(xport, xshift) \ + {.port = xport, .shift = xshift} + +enum wcd9xxx_chipid_major { + TABLA_MAJOR = cpu_to_le16(0x100), + SITAR_MAJOR = cpu_to_le16(0x101), + TAIKO_MAJOR = cpu_to_le16(0x102), + TAPAN_MAJOR = cpu_to_le16(0x103), + TOMTOM_MAJOR = cpu_to_le16(0x105), + TASHA_MAJOR = cpu_to_le16(0x0), + TASHA2P0_MAJOR = cpu_to_le16(0x107), + TAVIL_MAJOR = cpu_to_le16(0x108), +}; + +enum codec_power_states { + WCD_REGION_POWER_COLLAPSE_REMOVE, + WCD_REGION_POWER_COLLAPSE_BEGIN, + WCD_REGION_POWER_DOWN, +}; + +enum wcd_power_regions { + WCD9XXX_DIG_CORE_REGION_1, + WCD9XXX_MAX_PWR_REGIONS, +}; + +struct wcd9xxx_codec_type { + u16 id_major; + u16 id_minor; + struct mfd_cell *dev; + int size; + int num_irqs; + int version; /* -1 to retrieve version from chip version register */ + enum wcd9xxx_slim_slave_addr_type slim_slave_type; + u16 i2c_chip_status; + const struct intr_data *intr_tbl; + int intr_tbl_size; + u16 intr_reg[WCD9XXX_INTR_REG_MAX]; +}; + +struct wcd9xxx_power_region { + enum codec_power_states power_state; + u16 pwr_collapse_reg_min; + u16 pwr_collapse_reg_max; +}; + +struct wcd9xxx { + struct device *dev; + struct slim_device *slim; + struct slim_device *slim_slave; + struct mutex io_lock; + struct mutex xfer_lock; + struct mutex reset_lock; + u8 version; + + int reset_gpio; + struct device_node *wcd_rst_np; + + int (*read_dev)(struct wcd9xxx *wcd9xxx, unsigned short reg, + int bytes, void *dest, bool interface_reg); + int (*write_dev)(struct wcd9xxx *wcd9xxx, unsigned short reg, + int bytes, void *src, bool interface_reg); + int (*multi_reg_write)(struct wcd9xxx *wcd9xxx, const void *data, + size_t count); + int (*dev_down)(struct wcd9xxx *wcd9xxx); + int (*post_reset)(struct wcd9xxx *wcd9xxx); + + void *ssr_priv; + bool dev_up; + + u32 num_of_supplies; + struct regulator_bulk_data *supplies; + + struct wcd9xxx_core_resource core_res; + + u16 id_minor; + u16 id_major; + + /* Slimbus or I2S port */ + u32 num_rx_port; + u32 num_tx_port; + struct wcd9xxx_ch *rx_chs; + struct wcd9xxx_ch *tx_chs; + u32 mclk_rate; + enum codec_variant type; + struct regmap *regmap; + + struct wcd9xxx_codec_type *codec_type; + bool prev_pg_valid; + u8 prev_pg; + u8 avoid_cdc_rstlow; + struct wcd9xxx_power_region *wcd9xxx_pwr[WCD9XXX_MAX_PWR_REGIONS]; +}; + +struct wcd9xxx_reg_val { + unsigned short reg; /* register address */ + u8 *buf; /* buffer to be written to reg. addr */ + int bytes; /* number of bytes to be written */ +}; + +int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg); +int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg, + u8 val); +int wcd9xxx_get_logical_addresses(u8 *pgd_la, u8 *inf_la); +int wcd9xxx_slim_write_repeat(struct wcd9xxx *wcd9xxx, unsigned short reg, + int bytes, void *src); +int wcd9xxx_slim_reserve_bw(struct wcd9xxx *wcd9xxx, + u32 bw_ops, bool commit); +int wcd9xxx_set_power_state(struct wcd9xxx *wcd9xxx, enum codec_power_states, + enum wcd_power_regions); +int wcd9xxx_get_current_power_state(struct wcd9xxx *wcd9xxx, + enum wcd_power_regions); + +int wcd9xxx_page_write(struct wcd9xxx *wcd9xxx, unsigned short *reg); + +int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx, + struct wcd9xxx_reg_val *bulk_reg, + unsigned int size, bool interface); + +extern int wcd9xxx_core_res_init( + struct wcd9xxx_core_resource *wcd9xxx_core_res, + int num_irqs, int num_irq_regs, struct regmap *wcd_regmap); + +extern void wcd9xxx_core_res_deinit( + struct wcd9xxx_core_resource *wcd9xxx_core_res); + +extern int wcd9xxx_core_res_suspend( + struct wcd9xxx_core_resource *wcd9xxx_core_res, + pm_message_t pmesg); + +extern int wcd9xxx_core_res_resume( + struct wcd9xxx_core_resource *wcd9xxx_core_res); + +extern int wcd9xxx_core_irq_init( + struct wcd9xxx_core_resource *wcd9xxx_core_res); + +extern int wcd9xxx_assign_irq(struct wcd9xxx_core_resource *wcd9xxx_core_res, + unsigned int irq, + unsigned int irq_base); + +extern enum wcd9xxx_intf_status wcd9xxx_get_intf_type(void); +extern void wcd9xxx_set_intf_type(enum wcd9xxx_intf_status); + +extern enum wcd9xxx_pm_state wcd9xxx_pm_cmpxchg( + struct wcd9xxx_core_resource *wcd9xxx_core_res, + enum wcd9xxx_pm_state o, + enum wcd9xxx_pm_state n); +static inline int __init wcd9xxx_irq_of_init(struct device_node *node, + struct device_node *parent) +{ + return 0; +} + +int wcd9xxx_init(void); +void wcd9xxx_exit(void); +#endif diff --git a/include/linux/mfd/wcd9xxx/pdata.h b/include/linux/mfd/wcd9xxx/pdata.h new file mode 100644 index 000000000000..f188e850b800 --- /dev/null +++ b/include/linux/mfd/wcd9xxx/pdata.h @@ -0,0 +1,197 @@ +/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MFD_WCD9XXX_PDATA_H__ + +#define __MFD_WCD9XXX_PDATA_H__ + +#include +#include + +#define MICBIAS_EXT_BYP_CAP 0x00 +#define MICBIAS_NO_EXT_BYP_CAP 0x01 + +#define SITAR_LDOH_1P95_V 0x0 +#define SITAR_LDOH_2P35_V 0x1 +#define SITAR_LDOH_2P75_V 0x2 +#define SITAR_LDOH_2P85_V 0x3 + +#define SITAR_CFILT1_SEL 0x0 +#define SITAR_CFILT2_SEL 0x1 +#define SITAR_CFILT3_SEL 0x2 + +#define WCD9XXX_LDOH_1P95_V 0x0 +#define WCD9XXX_LDOH_2P35_V 0x1 +#define WCD9XXX_LDOH_2P75_V 0x2 +#define WCD9XXX_LDOH_2P85_V 0x3 +#define WCD9XXX_LDOH_3P0_V 0x3 + +#define TABLA_LDOH_1P95_V 0x0 +#define TABLA_LDOH_2P35_V 0x1 +#define TABLA_LDOH_2P75_V 0x2 +#define TABLA_LDOH_2P85_V 0x3 + +#define TABLA_CFILT1_SEL 0x0 +#define TABLA_CFILT2_SEL 0x1 +#define TABLA_CFILT3_SEL 0x2 + +#define MAX_AMIC_CHANNEL 7 + +#define TABLA_OCP_300_MA 0x0 +#define TABLA_OCP_350_MA 0x2 +#define TABLA_OCP_365_MA 0x3 +#define TABLA_OCP_150_MA 0x4 +#define TABLA_OCP_190_MA 0x6 +#define TABLA_OCP_220_MA 0x7 + +#define TABLA_DCYCLE_255 0x0 +#define TABLA_DCYCLE_511 0x1 +#define TABLA_DCYCLE_767 0x2 +#define TABLA_DCYCLE_1023 0x3 +#define TABLA_DCYCLE_1279 0x4 +#define TABLA_DCYCLE_1535 0x5 +#define TABLA_DCYCLE_1791 0x6 +#define TABLA_DCYCLE_2047 0x7 +#define TABLA_DCYCLE_2303 0x8 +#define TABLA_DCYCLE_2559 0x9 +#define TABLA_DCYCLE_2815 0xA +#define TABLA_DCYCLE_3071 0xB +#define TABLA_DCYCLE_3327 0xC +#define TABLA_DCYCLE_3583 0xD +#define TABLA_DCYCLE_3839 0xE +#define TABLA_DCYCLE_4095 0xF + +#define WCD9XXX_MCLK_CLK_12P288MHZ 12288000 +#define WCD9XXX_MCLK_CLK_9P6HZ 9600000 + +/* Only valid for 9.6 MHz mclk */ +#define WCD9XXX_DMIC_SAMPLE_RATE_600KHZ 600000 +#define WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ 2400000 +#define WCD9XXX_DMIC_SAMPLE_RATE_3P2MHZ 3200000 +#define WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ 4800000 + +/* Only valid for 12.288 MHz mclk */ +#define WCD9XXX_DMIC_SAMPLE_RATE_768KHZ 768000 +#define WCD9XXX_DMIC_SAMPLE_RATE_2P048MHZ 2048000 +#define WCD9XXX_DMIC_SAMPLE_RATE_3P072MHZ 3072000 +#define WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ 4096000 +#define WCD9XXX_DMIC_SAMPLE_RATE_6P144MHZ 6144000 + +#define WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED 0 + +#define WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED 0 + +struct wcd9xxx_amic { + /*legacy mode, txfe_enable and txfe_buff take 7 input + * each bit represent the channel / TXFE number + * and numbered as below + * bit 0 = channel 1 / TXFE1_ENABLE / TXFE1_BUFF + * bit 1 = channel 2 / TXFE2_ENABLE / TXFE2_BUFF + * ... + * bit 7 = channel 7 / TXFE7_ENABLE / TXFE7_BUFF + */ + u8 legacy_mode:MAX_AMIC_CHANNEL; + u8 txfe_enable:MAX_AMIC_CHANNEL; + u8 txfe_buff:MAX_AMIC_CHANNEL; + u8 use_pdata:MAX_AMIC_CHANNEL; +}; + +/* Each micbias can be assigned to one of three cfilters + * Vbatt_min >= .15V + ldoh_v + * ldoh_v >= .15v + cfiltx_mv + * If ldoh_v = 1.95 160 mv < cfiltx_mv < 1800 mv + * If ldoh_v = 2.35 200 mv < cfiltx_mv < 2200 mv + * If ldoh_v = 2.75 240 mv < cfiltx_mv < 2600 mv + * If ldoh_v = 2.85 250 mv < cfiltx_mv < 2700 mv + */ + +struct wcd9xxx_micbias_setting { + u8 ldoh_v; + u32 cfilt1_mv; /* in mv */ + u32 cfilt2_mv; /* in mv */ + u32 cfilt3_mv; /* in mv */ + u32 micb1_mv; + u32 micb2_mv; + u32 micb3_mv; + u32 micb4_mv; + /* Different WCD9xxx series codecs may not + * have 4 mic biases. If a codec has fewer + * mic biases, some of these properties will + * not be used. + */ + u8 bias1_cfilt_sel; + u8 bias2_cfilt_sel; + u8 bias3_cfilt_sel; + u8 bias4_cfilt_sel; + u8 bias1_cap_mode; + u8 bias2_cap_mode; + u8 bias3_cap_mode; + u8 bias4_cap_mode; + bool bias2_is_headset_only; +}; + +struct wcd9xxx_ocp_setting { + unsigned int use_pdata:1; /* 0 - use sys default as recommended */ + unsigned int num_attempts:4; /* up to 15 attempts */ + unsigned int run_time:4; /* in duty cycle */ + unsigned int wait_time:4; /* in duty cycle */ + unsigned int hph_ocp_limit:3; /* Headphone OCP current limit */ +}; + +#define WCD9XXX_MAX_REGULATOR 9 +/* + * format : TABLA__CUR_MAX + * + * from Tabla objective spec + */ + +#define WCD9XXX_CDC_VDDA_CP_CUR_MAX 500000 +#define WCD9XXX_CDC_VDDA_RX_CUR_MAX 20000 +#define WCD9XXX_CDC_VDDA_TX_CUR_MAX 20000 +#define WCD9XXX_VDDIO_CDC_CUR_MAX 5000 + +#define WCD9XXX_VDDD_CDC_D_CUR_MAX 5000 +#define WCD9XXX_VDDD_CDC_A_CUR_MAX 5000 + +#define WCD9XXX_VDD_SPKDRV_NAME "cdc-vdd-spkdrv" +#define WCD9XXX_VDD_SPKDRV2_NAME "cdc-vdd-spkdrv-2" + +struct wcd9xxx_regulator { + const char *name; + int min_uV; + int max_uV; + int optimum_uA; + bool ondemand; + struct regulator *regulator; +}; + +struct wcd9xxx_pdata { + int irq; + int irq_base; + int num_irqs; + int reset_gpio; + struct device_node *wcd_rst_np; + struct wcd9xxx_amic amic_settings; + struct slim_device slimbus_slave_device; + struct wcd9xxx_micbias_setting micbias; + struct wcd9xxx_ocp_setting ocp; + struct cdc_regulator *regulator; + int num_supplies; + u32 mclk_rate; + u32 dmic_sample_rate; + u32 mad_dmic_sample_rate; + u32 ecpp_dmic_sample_rate; + u32 dmic_clk_drv; + u16 use_pinctrl; +}; + +#endif diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx-irq.h b/include/linux/mfd/wcd9xxx/wcd9xxx-irq.h new file mode 100644 index 000000000000..99ce60383cc2 --- /dev/null +++ b/include/linux/mfd/wcd9xxx/wcd9xxx-irq.h @@ -0,0 +1,37 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#ifndef __MFD_WCD9XXX_IRQ_H +#define __MFD_WCD9XXX_IRQ_H +bool wcd9xxx_lock_sleep(struct wcd9xxx_core_resource *wcd9xxx_res); +void wcd9xxx_unlock_sleep(struct wcd9xxx_core_resource *wcd9xxx_res); +void wcd9xxx_nested_irq_lock(struct wcd9xxx_core_resource *wcd9xxx_res); +void wcd9xxx_nested_irq_unlock(struct wcd9xxx_core_resource *wcd9xxx_res); +int wcd9xxx_request_irq(struct wcd9xxx_core_resource *wcd9xxx_res, int irq, + irq_handler_t handler, const char *name, void *data); + +void wcd9xxx_free_irq(struct wcd9xxx_core_resource *wcd9xxx_res, + int irq, void *data); +void wcd9xxx_enable_irq(struct wcd9xxx_core_resource *wcd9xxx_res, int irq); +void wcd9xxx_disable_irq(struct wcd9xxx_core_resource *wcd9xxx_res, + int irq); +void wcd9xxx_disable_irq_sync(struct wcd9xxx_core_resource *wcd9xxx_res, + int irq); + +int wcd9xxx_irq_init(struct wcd9xxx_core_resource *wcd9xxx_res); +void wcd9xxx_irq_exit(struct wcd9xxx_core_resource *wcd9xxx_res); +int wcd9xxx_irq_drv_init(void); +void wcd9xxx_irq_drv_exit(void); +#endif diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h b/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h new file mode 100644 index 000000000000..96fdb00a2e03 --- /dev/null +++ b/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h @@ -0,0 +1,119 @@ +/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __WCD9310_SLIMSLAVE_H_ +#define __WCD9310_SLIMSLAVE_H_ + +#include +#include + + +/* + * client is expected to give port ids in the range of + * 1-10 for pre Taiko Tx ports and 1-16 for Taiko + * 1-7 for pre Taiko Rx ports and 1-16 for Tako, + * we need to add offset for getting the absolute slave + * port id before configuring the HW + */ +#define TABLA_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS 10 +#define TAIKO_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS 16 + +#define SLIM_MAX_TX_PORTS TAIKO_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS + +#define TABLA_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS \ + TABLA_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS +#define TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS \ + TAIKO_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS + +#define TABLA_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS 7 +#define TAIKO_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS 13 + +#define SLIM_MAX_RX_PORTS TAIKO_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS + +#define SLIM_MAX_REG_ADDR (0x180 + 4 * (SLIM_MAX_RX_PORTS)) + +#define TABLA_SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID \ + TABLA_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS +#define TAIKO_SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID \ + TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS + +#define TABLA_SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID 16 +#define TAIKO_SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID 31 + +#define TABLA_SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID 9 +#define TAIKO_SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID 15 + +/* below details are taken from SLIMBUS slave SWI */ +#define SB_PGD_PORT_BASE 0x000 + +#define SB_PGD_PORT_CFG_BYTE_ADDR(offset, port_num) \ + (SB_PGD_PORT_BASE + offset + (1 * port_num)) + +#define SB_PGD_TX_PORT_MULTI_CHANNEL_0(port_num) \ + (SB_PGD_PORT_BASE + 0x100 + 4*port_num) +#define SB_PGD_TX_PORT_MULTI_CHANNEL_0_START_PORT_ID 0 +#define SB_PGD_TX_PORT_MULTI_CHANNEL_0_END_PORT_ID 7 + +#define SB_PGD_TX_PORT_MULTI_CHANNEL_1(port_num) \ + (SB_PGD_PORT_BASE + 0x101 + 4*port_num) +#define SB_PGD_TX_PORT_MULTI_CHANNEL_1_START_PORT_ID 8 + +#define SB_PGD_RX_PORT_MULTI_CHANNEL_0(offset, port_num) \ + (SB_PGD_PORT_BASE + offset + (4 * port_num)) + +/* slave port water mark level + * (0: 6bytes, 1: 9bytes, 2: 12 bytes, 3: 15 bytes) + */ +#define SLAVE_PORT_WATER_MARK_6BYTES 0 +#define SLAVE_PORT_WATER_MARK_9BYTES 1 +#define SLAVE_PORT_WATER_MARK_12BYTES 2 +#define SLAVE_PORT_WATER_MARK_15BYTES 3 +#define SLAVE_PORT_WATER_MARK_SHIFT 1 +#define SLAVE_PORT_ENABLE 1 +#define SLAVE_PORT_DISABLE 0 +#define WATER_MARK_VAL \ + ((SLAVE_PORT_WATER_MARK_12BYTES << SLAVE_PORT_WATER_MARK_SHIFT) | \ + (SLAVE_PORT_ENABLE)) +#define BASE_CH_NUM 128 + + +int wcd9xxx_init_slimslave(struct wcd9xxx *wcd9xxx, + u8 wcd9xxx_pgd_la, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot); + +int wcd9xxx_deinit_slimslave(struct wcd9xxx *wcd9xxx); + +int wcd9xxx_cfg_slim_sch_rx(struct wcd9xxx *wcd9xxx, + struct list_head *wcd9xxx_ch_list, + unsigned int rate, unsigned int bit_width, + u16 *grph); +int wcd9xxx_cfg_slim_sch_tx(struct wcd9xxx *wcd9xxx, + struct list_head *wcd9xxx_ch_list, + unsigned int rate, unsigned int bit_width, + u16 *grph); +int wcd9xxx_close_slim_sch_rx(struct wcd9xxx *wcd9xxx, + struct list_head *wcd9xxx_ch_list, u16 grph); +int wcd9xxx_close_slim_sch_tx(struct wcd9xxx *wcd9xxx, + struct list_head *wcd9xxx_ch_list, u16 grph); +int wcd9xxx_get_channel(struct wcd9xxx *wcd9xxx, + unsigned int *rx_ch, + unsigned int *tx_ch); +int wcd9xxx_get_slave_port(unsigned int ch_num); +int wcd9xxx_disconnect_port(struct wcd9xxx *wcd9xxx, + struct list_head *wcd9xxx_ch_list, u16 grph); +int wcd9xxx_rx_vport_validation(u32 port_id, + struct list_head *codec_dai_list); +int wcd9xxx_tx_vport_validation(u32 vtable, u32 port_id, + struct wcd9xxx_codec_dai_data *codec_dai, + u32 num_codec_dais); +#endif /* __WCD9310_SLIMSLAVE_H_ */ diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx-utils.h b/include/linux/mfd/wcd9xxx/wcd9xxx-utils.h new file mode 100644 index 000000000000..7a13dd19e8c0 --- /dev/null +++ b/include/linux/mfd/wcd9xxx/wcd9xxx-utils.h @@ -0,0 +1,40 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __WCD9XXX_UTILS_H__ +#define __WCD9XXX_UTILS_H__ + +#include +#include +#include +#include +#include + +struct wcd9xxx_pdata *wcd9xxx_populate_dt_data(struct device *dev); +int wcd9xxx_bringup(struct device *dev); +int wcd9xxx_bringdown(struct device *dev); +struct regmap *wcd9xxx_regmap_init(struct device *dev, + const struct regmap_config *config); +int wcd9xxx_reset(struct device *dev); +int wcd9xxx_reset_low(struct device *dev); +int wcd9xxx_get_codec_info(struct device *dev); + +typedef int (*codec_bringup_fn)(struct wcd9xxx *); +typedef int (*codec_bringdown_fn)(struct wcd9xxx *); +typedef int (*codec_type_fn)(struct wcd9xxx *, + struct wcd9xxx_codec_type *); + +codec_bringdown_fn wcd9xxx_bringdown_fn(int type); +codec_bringup_fn wcd9xxx_bringup_fn(int type); +codec_type_fn wcd9xxx_get_codec_info_fn(int type); + +#endif diff --git a/include/linux/qdsp6v2/apr.h b/include/linux/qdsp6v2/apr.h new file mode 100644 index 000000000000..29deb3ca5ac7 --- /dev/null +++ b/include/linux/qdsp6v2/apr.h @@ -0,0 +1,190 @@ +/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __APR_H_ +#define __APR_H_ + +#include +#include + +enum apr_subsys_state { + APR_SUBSYS_DOWN, + APR_SUBSYS_UP, + APR_SUBSYS_LOADED, +}; + +struct apr_q6 { + void *pil; + atomic_t q6_state; + atomic_t modem_state; + struct mutex lock; +}; + +struct apr_hdr { + uint16_t hdr_field; + uint16_t pkt_size; + uint8_t src_svc; + uint8_t src_domain; + uint16_t src_port; + uint8_t dest_svc; + uint8_t dest_domain; + uint16_t dest_port; + uint32_t token; + uint32_t opcode; +}; + +#define APR_HDR_LEN(hdr_len) ((hdr_len)/4) +#define APR_PKT_SIZE(hdr_len, payload_len) ((hdr_len) + (payload_len)) +#define APR_HDR_FIELD(msg_type, hdr_len, ver)\ + (((msg_type & 0x3) << 8) | ((hdr_len & 0xF) << 4) | (ver & 0xF)) + +#define APR_HDR_SIZE sizeof(struct apr_hdr) + +/* Version */ +#define APR_PKT_VER 0x0 + +/* Command and Response Types */ +#define APR_MSG_TYPE_EVENT 0x0 +#define APR_MSG_TYPE_CMD_RSP 0x1 +#define APR_MSG_TYPE_SEQ_CMD 0x2 +#define APR_MSG_TYPE_NSEQ_CMD 0x3 +#define APR_MSG_TYPE_MAX 0x04 + +/* APR Basic Response Message */ +#define APR_BASIC_RSP_RESULT 0x000110E8 +#define APR_RSP_ACCEPTED 0x000100BE + +/* Domain IDs */ +#define APR_DOMAIN_SIM 0x1 +#define APR_DOMAIN_PC 0x2 +#define APR_DOMAIN_MODEM 0x3 +#define APR_DOMAIN_ADSP 0x4 +#define APR_DOMAIN_APPS 0x5 +#define APR_DOMAIN_MAX 0x6 + +/* ADSP service IDs */ +#define APR_SVC_TEST_CLIENT 0x2 +#define APR_SVC_ADSP_CORE 0x3 +#define APR_SVC_AFE 0x4 +#define APR_SVC_VSM 0x5 +#define APR_SVC_VPM 0x6 +#define APR_SVC_ASM 0x7 +#define APR_SVC_ADM 0x8 +#define APR_SVC_ADSP_MVM 0x09 +#define APR_SVC_ADSP_CVS 0x0A +#define APR_SVC_ADSP_CVP 0x0B +#define APR_SVC_USM 0x0C +#define APR_SVC_LSM 0x0D +#define APR_SVC_VIDC 0x16 +#define APR_SVC_MAX 0x17 + +/* Modem Service IDs */ +#define APR_SVC_MVS 0x3 +#define APR_SVC_MVM 0x4 +#define APR_SVC_CVS 0x5 +#define APR_SVC_CVP 0x6 +#define APR_SVC_SRD 0x7 + +/* APR Port IDs */ +#define APR_MAX_PORTS 0x80 + +#define APR_NAME_MAX 0x40 + +#define RESET_EVENTS 0x000130D7 + +#define LPASS_RESTART_EVENT 0x1000 +#define LPASS_RESTART_READY 0x1001 + +struct apr_client_data { + uint16_t reset_event; + uint16_t reset_proc; + uint16_t payload_size; + uint16_t hdr_len; + uint16_t msg_type; + uint16_t src; + uint16_t dest_svc; + uint16_t src_port; + uint16_t dest_port; + uint32_t token; + uint32_t opcode; + void *payload; +}; + +typedef int32_t (*apr_fn)(struct apr_client_data *data, void *priv); + +struct apr_svc { + uint16_t id; + uint16_t dest_id; + uint16_t client_id; + uint16_t dest_domain; + uint8_t rvd; + uint8_t port_cnt; + uint8_t svc_cnt; + uint8_t need_reset; + apr_fn port_fn[APR_MAX_PORTS]; + void *port_priv[APR_MAX_PORTS]; + apr_fn fn; + void *priv; + struct mutex m_lock; + spinlock_t w_lock; + uint8_t pkt_owner; +}; + +struct apr_client { + uint8_t id; + uint8_t svc_cnt; + uint8_t rvd; + struct mutex m_lock; + struct apr_svc_ch_dev *handle; + struct apr_svc svc[APR_SVC_MAX]; +}; + +struct apr_rx_intents { + int num_of_intents; + uint32_t size; +}; + +struct apr_pkt_cfg { + uint8_t pkt_owner; + struct apr_rx_intents intents; +}; + +int apr_load_adsp_image(void); +struct apr_client *apr_get_client(int dest_id, int client_id); +int apr_wait_for_device_up(int dest_id); +int apr_get_svc(const char *svc_name, int dest_id, int *client_id, + int *svc_idx, int *svc_id); +void apr_cb_func(void *buf, int len, void *priv); +struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn, + uint32_t src_port, void *priv); +inline int apr_fill_hdr(void *handle, uint32_t *buf, uint16_t src_port, + uint16_t msg_type, uint16_t dest_port, + uint32_t token, uint32_t opcode, uint16_t len); + +int apr_send_pkt(void *handle, uint32_t *buf); +int apr_deregister(void *handle); +void subsys_notif_register(char *client_name, int domain, + struct notifier_block *nb); +int apr_get_dest_id(char *dest); +uint16_t apr_get_data_src(struct apr_hdr *hdr); +void change_q6_state(int state); +void q6audio_dsp_not_responding(void); +void apr_reset(void *handle); +enum apr_subsys_state apr_get_subsys_state(void); +enum apr_subsys_state apr_get_modem_state(void); +void apr_set_modem_state(enum apr_subsys_state state); +enum apr_subsys_state apr_get_q6_state(void); +int apr_set_q6_state(enum apr_subsys_state state); +void apr_set_subsys_state(void); +const char *apr_get_lpass_subsys_name(void); +uint16_t apr_get_reset_domain(uint16_t proc); +#endif diff --git a/include/linux/qdsp6v2/apr_tal.h b/include/linux/qdsp6v2/apr_tal.h new file mode 100644 index 000000000000..26d1a4c56ebc --- /dev/null +++ b/include/linux/qdsp6v2/apr_tal.h @@ -0,0 +1,90 @@ +/* Copyright (c) 2010-2011, 2016-2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __APR_TAL_H_ +#define __APR_TAL_H_ + +#include +#include +#include + +/* APR Client IDs */ +#define APR_CLIENT_AUDIO 0x0 +#define APR_CLIENT_VOICE 0x1 +#define APR_CLIENT_MAX 0x2 + +#define APR_DL_SMD 0 +#define APR_DL_MAX 1 + +#define APR_DEST_MODEM 0 +#define APR_DEST_QDSP6 1 +#define APR_DEST_MAX 2 + +#if defined(CONFIG_MSM_QDSP6_APRV2_GLINK) || \ + defined(CONFIG_MSM_QDSP6_APRV3_GLINK) +#define APR_MAX_BUF 512 +#else +#define APR_MAX_BUF 8092 +#endif + +#define APR_DEFAULT_NUM_OF_INTENTS 20 + +#define APR_OPEN_TIMEOUT_MS 5000 + +enum { + /* If client sets the pkt_owner to APR_PKT_OWNER_DRIVER, APR + * driver will allocate a buffer, where the user packet is + * copied into, for each and every single Tx transmission. + * The buffer is thereafter passed to underlying link layer + * and freed upon the notification received from the link layer + * that the packet has been consumed. + */ + APR_PKT_OWNER_DRIVER, + /* If client sets the pkt_owner to APR_PKT_OWNER_CLIENT, APR + * will pass the user packet memory address directly to underlying + * link layer. In this case it is the client's responsibility to + * make sure the packet is intact until being notified that the + * packet has been consumed. + */ + APR_PKT_OWNER_CLIENT, +}; + +struct apr_pkt_priv { + /* This property is only applicable for APR over Glink. + * It is ignored in APR over SMD cases. + */ + uint8_t pkt_owner; +}; + +typedef void (*apr_svc_cb_fn)(void *buf, int len, void *priv); +struct apr_svc_ch_dev *apr_tal_open(uint32_t svc, uint32_t dest, + uint32_t dl, apr_svc_cb_fn func, void *priv); +int apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data, + struct apr_pkt_priv *pkt_priv, int len); +int apr_tal_close(struct apr_svc_ch_dev *apr_ch); +int apr_tal_rx_intents_config(struct apr_svc_ch_dev *apr_ch, + int num_of_intents, uint32_t size); + + +struct apr_svc_ch_dev { + void *handle; + spinlock_t w_lock; + spinlock_t r_lock; + struct mutex m_lock; + apr_svc_cb_fn func; + wait_queue_head_t wait; + void *priv; + unsigned int channel_state; + bool if_remote_intent_ready; +}; + +#endif diff --git a/include/linux/qdsp6v2/apr_us.h b/include/linux/qdsp6v2/apr_us.h new file mode 100644 index 000000000000..9a6804a4d634 --- /dev/null +++ b/include/linux/qdsp6v2/apr_us.h @@ -0,0 +1,193 @@ +/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __APR_US_H__ +#define __APR_US_H__ + +#include + +/* ======================================================================= */ +/* Session Level commands */ + +#define USM_SESSION_CMD_RUN 0x00012306 +struct usm_stream_cmd_run { + struct apr_hdr hdr; + u32 flags; + u32 msw_ts; + u32 lsw_ts; +} __packed; + +/* Stream level commands */ +#define USM_STREAM_CMD_OPEN_READ 0x00012309 +struct usm_stream_cmd_open_read { + struct apr_hdr hdr; + u32 uMode; + u32 src_endpoint; + u32 pre_proc_top; + u32 format; +} __packed; + +#define USM_STREAM_CMD_OPEN_WRITE 0x00011271 +struct usm_stream_cmd_open_write { + struct apr_hdr hdr; + u32 format; +} __packed; + + +#define USM_STREAM_CMD_CLOSE 0x0001230A + +#define USM_STREAM_CMD_SET_PARAM 0x00012731 +struct usm_stream_cmd_set_param { + struct apr_hdr hdr; + u32 buf_addr_lsw; + u32 buf_addr_msw; + u32 mem_map_handle; + u32 buf_size; + u32 module_id; + u32 param_id; +} __packed; + +#define USM_STREAM_CMD_GET_PARAM 0x00012732 +struct usm_stream_cmd_get_param { + struct apr_hdr hdr; + u32 buf_addr_lsw; + u32 buf_addr_msw; + u32 mem_map_handle; + u32 buf_size; + u32 module_id; + u32 param_id; +} __packed; + +/* Encoder configuration definitions */ +#define USM_STREAM_CMD_SET_ENC_PARAM 0x0001230B +/* Decoder configuration definitions */ +#define USM_DATA_CMD_MEDIA_FORMAT_UPDATE 0x00011272 + +/* Encoder/decoder configuration block */ +#define USM_PARAM_ID_ENCDEC_ENC_CFG_BLK 0x0001230D + +/* Max number of static located ports (bytes) */ +#define USM_MAX_PORT_NUMBER 8 + +/* Max number of static located transparent data (bytes) */ +#define USM_MAX_CFG_DATA_SIZE 100 + +/* Parameter structures used in USM_STREAM_CMD_SET_ENCDEC_PARAM command */ +/* common declarations */ +struct usm_cfg_common { + u16 ch_cfg; + u16 bits_per_sample; + u32 sample_rate; + u32 dev_id; + u8 data_map[USM_MAX_PORT_NUMBER]; +} __packed; + +struct us_encdec_cfg { + u32 format_id; + struct usm_cfg_common cfg_common; + u16 params_size; + u8 *params; +} __packed; + +/* Start/stop US signal detection */ +#define USM_SESSION_CMD_SIGNAL_DETECT_MODE 0x00012719 + +struct usm_session_cmd_detect_info { + struct apr_hdr hdr; + u32 detect_mode; + u32 skip_interval; + u32 algorithm_cfg_size; +} __packed; + +/* US signal detection result */ +#define USM_SESSION_EVENT_SIGNAL_DETECT_RESULT 0x00012720 + +/* ======================================================================= */ +/* Session Level commands */ +#define USM_CMD_SHARED_MEM_MAP_REGION 0x00012728 +struct usm_cmd_memory_map_region { + struct apr_hdr hdr; + u16 mempool_id; + u16 num_regions; + u32 flags; + u32 shm_addr_lsw; + u32 shm_addr_msw; + u32 mem_size_bytes; +} __packed; + +#define USM_CMDRSP_SHARED_MEM_MAP_REGION 0x00012729 +struct usm_cmdrsp_memory_map_region { + u32 mem_map_handle; +} __packed; + +#define USM_CMD_SHARED_MEM_UNMAP_REGION 0x0001272A +struct usm_cmd_memory_unmap_region { + struct apr_hdr hdr; + u32 mem_map_handle; +} __packed; + +#define USM_DATA_CMD_READ 0x00012724 +struct usm_stream_cmd_read { + struct apr_hdr hdr; + u32 buf_addr_lsw; + u32 buf_addr_msw; + u32 mem_map_handle; + u32 buf_size; + u32 seq_id; + u32 counter; +} __packed; + +#define USM_DATA_EVENT_READ_DONE 0x00012725 + +#define USM_DATA_CMD_WRITE 0x00012726 +struct usm_stream_cmd_write { + struct apr_hdr hdr; + u32 buf_addr_lsw; + u32 buf_addr_msw; + u32 mem_map_handle; + u32 buf_size; + u32 seq_id; + u32 res0; + u32 res1; + u32 res2; +} __packed; + +#define USM_DATA_EVENT_WRITE_DONE 0x00012727 + +struct usm_stream_media_format_update { + struct apr_hdr hdr; + u32 format_id; + /* = sizeof(usm_cfg_common)+|transp_data| */ + u32 cfg_size; + struct usm_cfg_common cfg_common; + /* Transparent configuration data for specific encoder */ + u8 transp_data[USM_MAX_CFG_DATA_SIZE]; +} __packed; + +struct usm_encode_cfg_blk { + u32 frames_per_buf; + u32 format_id; + /* = sizeof(usm_cfg_common)+|transp_data| */ + u32 cfg_size; + struct usm_cfg_common cfg_common; + /* Transparent configuration data for specific encoder */ + u8 transp_data[USM_MAX_CFG_DATA_SIZE]; +} __packed; + +struct usm_stream_cmd_encdec_cfg_blk { + struct apr_hdr hdr; + u32 param_id; + u32 param_size; + struct usm_encode_cfg_blk enc_blk; +} __packed; + +#endif /* __APR_US_H__ */ diff --git a/include/linux/qdsp6v2/audio_notifier.h b/include/linux/qdsp6v2/audio_notifier.h new file mode 100644 index 000000000000..3587b49a05c6 --- /dev/null +++ b/include/linux/qdsp6v2/audio_notifier.h @@ -0,0 +1,105 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __AUDIO_NOTIFIER_H_ +#define __AUDIO_NOTIFIER_H_ + +/* State of the notifier domain */ +enum { + AUDIO_NOTIFIER_SERVICE_DOWN, + AUDIO_NOTIFIER_SERVICE_UP +}; + +/* Service order determines connection priority + * Highest number connected first + */ +enum { + AUDIO_NOTIFIER_SSR_SERVICE, + AUDIO_NOTIFIER_PDR_SERVICE, + AUDIO_NOTIFIER_MAX_SERVICES +}; + +enum { + AUDIO_NOTIFIER_ADSP_DOMAIN, + AUDIO_NOTIFIER_MODEM_DOMAIN, + AUDIO_NOTIFIER_MAX_DOMAINS +}; + +/* Structure populated in void *data of nb function + * callback used for audio_notifier_register + */ +struct audio_notifier_cb_data { + int service; + int domain; +}; + +#ifdef CONFIG_MSM_QDSP6_NOTIFIER + +/* + * Use audio_notifier_register to register any audio + * clients who need to be notified of a remote process. + * This API will determine and register the client with + * the best available subsystem (SSR or PDR) for that + * domain (Adsp or Modem). When an event is sent from that + * domain the notifier block callback function will be called. + * + * client_name - A unique user name defined by the client. + * If the same name is used for multiple calls each will + * be tracked & called back separately and a single call + * to deregister will delete them all. + * domain - Domain the client wants to get events from. + * AUDIO_NOTIFIER_ADSP_DOMAIN + * AUDIO_NOTIFIER_MODEM_DOMAIN + * *nb - Pointer to a notifier block. Provide a callback function + * to be notified of an even on that domain. + * + * nb_func(struct notifier_block *this, unsigned long opcode, void *data) + * this - pointer to own nb + * opcode - event from registered domain + * AUDIO_NOTIFIER_SERVICE_DOWN + * AUDIO_NOTIFIER_SERVICE_UP + * *data - pointer to struct audio_notifier_cb_data + * + * Returns: Success: 0 + * Error: -# + */ +int audio_notifier_register(char *client_name, int domain, + struct notifier_block *nb); + +/* + * Use audio_notifier_deregister to deregister the clients from + * all domains registered using audio_notifier_register that + * match the client name. + * + * client_name - Unique user name used in audio_notifier_register. + * Returns: Success: 0 + * Error: -# + */ +int audio_notifier_deregister(char *client_name); + +#else + +static inline int audio_notifier_register(char *client_name, int domain, + struct notifier_block *nb) +{ + return -ENODEV; +} + +static inline int audio_notifier_deregister(char *client_name) +{ + return 0; +} + +#endif /* CONFIG_MSM_QDSP6_PDR */ + +#endif diff --git a/include/linux/qdsp6v2/audio_pdr.h b/include/linux/qdsp6v2/audio_pdr.h new file mode 100644 index 000000000000..ebfd366b1e44 --- /dev/null +++ b/include/linux/qdsp6v2/audio_pdr.h @@ -0,0 +1,101 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __AUDIO_PDR_H_ +#define __AUDIO_PDR_H_ + +enum { + AUDIO_PDR_DOMAIN_ADSP, + AUDIO_PDR_DOMAIN_MAX +}; + +enum { + AUDIO_PDR_FRAMEWORK_DOWN, + AUDIO_PDR_FRAMEWORK_UP +}; + +#ifdef CONFIG_MSM_QDSP6_PDR + +/* + * Use audio_pdr_register to register with the PDR subsystem this + * should be done before module late init otherwise notification + * of the AUDIO_PDR_FRAMEWORK_UP cannot be guaranteed. + * + * *nb - Pointer to a notifier block. Provide a callback function + * to be notified once the PDR framework has been initialized. + * Callback will receive either the AUDIO_PDR_FRAMEWORK_DOWN + * or AUDIO_PDR_FRAMEWORK_UP ioctl depending on the state of + * the PDR framework. + * + * Returns: Success: 0 + * Failure: Error code + */ +int audio_pdr_register(struct notifier_block *nb); + +/* + * Use audio_pdr_service_register to register with a PDR service + * Function should be called after nb callback registered with + * audio_pdr_register has been called back with the + * AUDIO_PDR_FRAMEWORK_UP ioctl. + * + * domain_id - Domain to use, example: AUDIO_PDR_ADSP + * *nb - Pointer to a notifier block. Provide a callback function + * that will be notified of the state of the domain + * requested. The ioctls received by the callback are + * defined in service-notifier.h. + * + * Returns: Success: Client handle + * Failure: Pointer error code + */ +void *audio_pdr_service_register(int domain_id, + struct notifier_block *nb, int *curr_state); + +/* + * Use audio_pdr_service_deregister to deregister with a PDR + * service that was registered using the audio_pdr_service_register + * API. + * + * *service_handle - Service handle returned by audio_pdr_service_register + * *nb - Pointer to the notifier block. Used in the call to + * audio_pdr_service_register. + * + * Returns: Success: Client handle + * Failure: Error code + */ +int audio_pdr_service_deregister(void *service_handle, + struct notifier_block *nb); + +#else + +static inline int audio_pdr_register(struct notifier_block *nb) +{ + return -ENODEV; +} + + +static inline void *audio_pdr_service_register(int domain_id, + struct notifier_block *nb, + int *curr_state) +{ + return NULL; +} + +static inline int audio_pdr_service_deregister(void *service_handle, + struct notifier_block *nb) +{ + return 0; +} + +#endif /* CONFIG_MSM_QDSP6_PDR */ + +#endif diff --git a/include/linux/qdsp6v2/audio_ssr.h b/include/linux/qdsp6v2/audio_ssr.h new file mode 100644 index 000000000000..a807021ba7ca --- /dev/null +++ b/include/linux/qdsp6v2/audio_ssr.h @@ -0,0 +1,78 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __AUDIO_SSR_H_ +#define __AUDIO_SSR_H_ + +enum { + AUDIO_SSR_DOMAIN_ADSP, + AUDIO_SSR_DOMAIN_MODEM, + AUDIO_SSR_DOMAIN_MAX +}; + +#ifdef CONFIG_MSM_QDSP6_SSR + +/* + * Use audio_ssr_register to register with the SSR subsystem + * + * domain_id - Service to use, example: AUDIO_SSR_DOMAIN_ADSP + * *nb - Pointer to a notifier block. Provide a callback function + * to be notified of an event for that service. The ioctls + * used by the callback are defined in subsystem_notif.h. + * + * Returns: Success: Client handle + * Failure: Pointer error code + */ +void *audio_ssr_register(int domain_id, struct notifier_block *nb); + +/* + * Use audio_ssr_deregister to register with the SSR subsystem + * + * handle - Handle received from audio_ssr_register + * *nb - Pointer to a notifier block. Callback function + * Used from audio_ssr_register. + * + * Returns: Success: 0 + * Failure: Error code + */ +int audio_ssr_deregister(void *handle, struct notifier_block *nb); + + +/* + * Use audio_ssr_send_nmi to force a RAM dump on ADSP + * down event. + * + * *ssr_cb_data - *data received from notifier callback + */ +void audio_ssr_send_nmi(void *ssr_cb_data); + +#else + +static inline void *audio_ssr_register(int domain_id, + struct notifier_block *nb) +{ + return NULL; +} + +static inline int audio_ssr_deregister(void *handle, struct notifier_block *nb) +{ + return 0; +} + +static inline void audio_ssr_send_nmi(void *ssr_cb_data) +{ +} + +#endif /* CONFIG_MSM_QDSP6_SSR */ + +#endif diff --git a/include/linux/qdsp6v2/dsp_debug.h b/include/linux/qdsp6v2/dsp_debug.h new file mode 100644 index 000000000000..bc1cd9ec8743 --- /dev/null +++ b/include/linux/qdsp6v2/dsp_debug.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2010, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __DSP_DEBUG_H_ +#define __DSP_DEBUG_H_ + +typedef int (*dsp_state_cb)(int state); +int dsp_debug_register(dsp_state_cb ptr); + +#define DSP_STATE_CRASHED 0x0 +#define DSP_STATE_CRASH_DUMP_DONE 0x1 + +#endif diff --git a/include/linux/qdsp6v2/rtac.h b/include/linux/qdsp6v2/rtac.h new file mode 100644 index 000000000000..b6f4e56db7e7 --- /dev/null +++ b/include/linux/qdsp6v2/rtac.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2011, 2013-2015, 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __RTAC_H__ +#define __RTAC_H__ + +#include + +/* Voice Modes */ +#define RTAC_CVP 0 +#define RTAC_CVS 1 +#define RTAC_VOICE_MODES 2 + +#define RTAC_MAX_ACTIVE_DEVICES 4 +#define RTAC_MAX_ACTIVE_POPP 8 + +#define DEFAULT_APP_TYPE 0x00011130 + +enum { + ADM_RTAC_CAL, + ASM_RTAC_CAL, + VOICE_RTAC_CAL, + AFE_RTAC_CAL, + MAX_RTAC_BLOCKS +}; + +struct rtac_cal_mem_map_data { + uint32_t map_size; + uint32_t map_handle; + struct ion_client *ion_client; + struct ion_handle *ion_handle; +}; + +struct rtac_cal_data { + size_t size; + void *kvaddr; + phys_addr_t paddr; +}; + +struct rtac_cal_block_data { + struct rtac_cal_mem_map_data map_data; + struct rtac_cal_data cal_data; +}; + +struct rtac_popp_data { + uint32_t popp; + uint32_t popp_topology; + uint32_t app_type; +}; + +struct rtac_adm_data { + uint32_t topology_id; + uint32_t afe_topology; + uint32_t afe_port; + uint32_t copp; + uint32_t num_of_popp; + uint32_t app_type; + uint32_t acdb_dev_id; + struct rtac_popp_data popp[RTAC_MAX_ACTIVE_POPP]; +}; + +struct rtac_adm { + uint32_t num_of_dev; + struct rtac_adm_data device[RTAC_MAX_ACTIVE_DEVICES]; +}; + +void rtac_add_adm_device(u32 port_id, u32 copp_id, u32 path_id, u32 popp_id, + u32 app_type, u32 acdb_dev_id); +void rtac_remove_adm_device(u32 port_id, u32 copp_id); +void rtac_remove_popp_from_adm_devices(u32 popp_id); +void rtac_add_voice(u32 cvs_handle, u32 cvp_handle, u32 rx_afe_port, + u32 tx_afe_port, u32 rx_acdb_id, u32 tx_acdb_id, u32 session_id); +void rtac_remove_voice(u32 cvs_handle); +void rtac_set_adm_handle(void *handle); +bool rtac_make_adm_callback(uint32_t *payload, u32 payload_size); +void rtac_copy_adm_payload_to_user(void *payload, u32 payload_size); +void rtac_set_asm_handle(u32 session_id, void *handle); +bool rtac_make_asm_callback(u32 session_id, uint32_t *payload, + u32 payload_size); +void rtac_copy_asm_payload_to_user(void *payload, u32 payload_size); +void rtac_set_voice_handle(u32 mode, void *handle); +bool rtac_make_voice_callback(u32 mode, uint32_t *payload, u32 payload_size); +void rtac_copy_voice_payload_to_user(void *payload, u32 payload_size); +int rtac_clear_mapping(uint32_t cal_type); +bool rtac_make_afe_callback(uint32_t *payload, u32 payload_size); +void rtac_set_afe_handle(void *handle); +void get_rtac_adm_data(struct rtac_adm *adm_data); +void rtac_update_afe_topology(u32 port_id); +#endif diff --git a/include/linux/qdsp6v2/usf.h b/include/linux/qdsp6v2/usf.h new file mode 100644 index 000000000000..544b624c2cda --- /dev/null +++ b/include/linux/qdsp6v2/usf.h @@ -0,0 +1,298 @@ +/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __USF_H__ +#define __USF_H__ + +#include +#include + +#define USF_IOCTL_MAGIC 'U' + +#define US_SET_TX_INFO _IOW(USF_IOCTL_MAGIC, 0, \ + struct us_tx_info_type) +#define US_START_TX _IO(USF_IOCTL_MAGIC, 1) +#define US_GET_TX_UPDATE _IOWR(USF_IOCTL_MAGIC, 2, \ + struct us_tx_update_info_type) +#define US_SET_RX_INFO _IOW(USF_IOCTL_MAGIC, 3, \ + struct us_rx_info_type) +#define US_SET_RX_UPDATE _IOWR(USF_IOCTL_MAGIC, 4, \ + struct us_rx_update_info_type) +#define US_START_RX _IO(USF_IOCTL_MAGIC, 5) + +#define US_STOP_TX _IO(USF_IOCTL_MAGIC, 6) +#define US_STOP_RX _IO(USF_IOCTL_MAGIC, 7) + +#define US_SET_DETECTION _IOWR(USF_IOCTL_MAGIC, 8, \ + struct us_detect_info_type) + +#define US_GET_VERSION _IOWR(USF_IOCTL_MAGIC, 9, \ + struct us_version_info_type) + +#define US_SET_TX_STREAM_PARAM _IOW(USF_IOCTL_MAGIC, 10, \ + struct us_stream_param_type) +#define US_GET_TX_STREAM_PARAM _IOWR(USF_IOCTL_MAGIC, 11, \ + struct us_stream_param_type) +#define US_SET_RX_STREAM_PARAM _IOW(USF_IOCTL_MAGIC, 12, \ + struct us_stream_param_type) +#define US_GET_RX_STREAM_PARAM _IOWR(USF_IOCTL_MAGIC, 13, \ + struct us_stream_param_type) + +/* Special timeout values */ +#define USF_NO_WAIT_TIMEOUT 0x00000000 +/* Infinitive */ +#define USF_INFINITIVE_TIMEOUT 0xffffffff +/* Default value, used by the driver */ +#define USF_DEFAULT_TIMEOUT 0xfffffffe + +/* US detection place (HW|FW) */ +enum us_detect_place_enum { +/* US is detected in HW */ + US_DETECT_HW, +/* US is detected in FW */ + US_DETECT_FW +}; + +/* US detection mode */ +enum us_detect_mode_enum { +/* US detection is disabled */ + US_DETECT_DISABLED_MODE, +/* US detection is enabled in continue mode */ + US_DETECT_CONTINUE_MODE, +/* US detection is enabled in one shot mode */ + US_DETECT_SHOT_MODE +}; + +/* Encoder (TX), decoder (RX) supported US data formats */ +#define USF_POINT_EPOS_FORMAT 0 +#define USF_RAW_FORMAT 1 + +/* Indexes of event types, produced by the calculators */ +#define USF_TSC_EVENT_IND 0 +#define USF_TSC_PTR_EVENT_IND 1 +#define USF_MOUSE_EVENT_IND 2 +#define USF_KEYBOARD_EVENT_IND 3 +#define USF_TSC_EXT_EVENT_IND 4 +#define USF_MAX_EVENT_IND 5 + +/* Types of events, produced by the calculators */ +#define USF_NO_EVENT 0 +#define USF_TSC_EVENT (1 << USF_TSC_EVENT_IND) +#define USF_TSC_PTR_EVENT (1 << USF_TSC_PTR_EVENT_IND) +#define USF_MOUSE_EVENT (1 << USF_MOUSE_EVENT_IND) +#define USF_KEYBOARD_EVENT (1 << USF_KEYBOARD_EVENT_IND) +#define USF_TSC_EXT_EVENT (1 << USF_TSC_EXT_EVENT_IND) +#define USF_ALL_EVENTS (USF_TSC_EVENT |\ + USF_TSC_PTR_EVENT |\ + USF_MOUSE_EVENT |\ + USF_KEYBOARD_EVENT |\ + USF_TSC_EXT_EVENT) + +/* min, max array dimension */ +#define MIN_MAX_DIM 2 + +/* coordinates (x,y,z) array dimension */ +#define COORDINATES_DIM 3 + +/* tilts (x,y) array dimension */ +#define TILTS_DIM 2 + +/* Max size of the client name */ +#define USF_MAX_CLIENT_NAME_SIZE 20 + +/* Max number of the ports (mics/speakers) */ +#define USF_MAX_PORT_NUM 8 + +/* Info structure common for TX and RX */ +struct us_xx_info_type { +/* Input: general info */ +/* Name of the client - event calculator */ + const char __user *client_name; +/* Selected device identification, accepted in the kernel's CAD */ + uint32_t dev_id; +/* 0 - point_epos type; (e.g. 1 - gr_mmrd) */ + uint32_t stream_format; +/* Required sample rate in Hz */ + uint32_t sample_rate; +/* Size of a buffer (bytes) for US data transfer between the module and USF */ + uint32_t buf_size; +/* Number of the buffers for the US data transfer */ + uint16_t buf_num; +/* Number of the microphones (TX) or speakers(RX) */ + uint16_t port_cnt; +/* Microphones(TX) or speakers(RX) indexes in their enumeration */ + uint8_t port_id[USF_MAX_PORT_NUM]; +/* Bits per sample 16 or 32 */ + uint16_t bits_per_sample; +/* Input: Transparent info for encoder in the LPASS */ +/* Parameters data size in bytes */ + uint16_t params_data_size; +/* Pointer to the parameters */ + uint8_t __user *params_data; +/* Max size of buffer for get and set parameter */ + uint32_t max_get_set_param_buf_size; +}; + +struct us_input_info_type { + /* Touch screen dimensions: min & max;for input module */ + int tsc_x_dim[MIN_MAX_DIM]; + int tsc_y_dim[MIN_MAX_DIM]; + int tsc_z_dim[MIN_MAX_DIM]; + /* Touch screen tilt dimensions: min & max;for input module */ + int tsc_x_tilt[MIN_MAX_DIM]; + int tsc_y_tilt[MIN_MAX_DIM]; + /* Touch screen pressure limits: min & max; for input module */ + int tsc_pressure[MIN_MAX_DIM]; + /* The requested buttons bitmap */ + uint16_t req_buttons_bitmap; + /* Bitmap of types of events (USF_X_EVENT), produced by calculator */ + uint16_t event_types; + /* Bitmap of types of events from devs, conflicting with USF */ + uint16_t conflicting_event_types; +}; + +struct us_tx_info_type { + /* Common info */ + struct us_xx_info_type us_xx_info; + /* Info specific for TX*/ + struct us_input_info_type input_info; +}; + +struct us_rx_info_type { + /* Common info */ + struct us_xx_info_type us_xx_info; + /* Info specific for RX*/ +}; + +struct point_event_type { +/* Pen coordinates (x, y, z) in units, defined by */ + int coordinates[COORDINATES_DIM]; + /* {x;y} in transparent units */ + int inclinations[TILTS_DIM]; +/* [0-1023] (10bits); 0 - pen up */ + uint32_t pressure; +/* Bitmap for button state. 1 - down, 0 - up */ + uint16_t buttons_state_bitmap; +}; + +/* Mouse buttons, supported by USF */ +#define USF_BUTTON_LEFT_MASK 1 +#define USF_BUTTON_MIDDLE_MASK 2 +#define USF_BUTTON_RIGHT_MASK 4 +struct mouse_event_type { +/* The mouse relative movement (dX, dY, dZ) */ + int rels[COORDINATES_DIM]; +/* Bitmap of mouse buttons states: 1 - down, 0 - up; */ + uint16_t buttons_states; +}; + +struct key_event_type { +/* Calculated MS key- see input.h. */ + uint32_t key; +/* Keyboard's key state: 1 - down, 0 - up; */ + uint8_t key_state; +}; + +struct usf_event_type { +/* Event sequence number */ + uint32_t seq_num; +/* Event generation system time */ + uint32_t timestamp; +/* Destination input event type index (e.g. touch screen, mouse, key) */ + uint16_t event_type_ind; + union { + struct point_event_type point_event; + struct mouse_event_type mouse_event; + struct key_event_type key_event; + } event_data; +}; + +struct us_tx_update_info_type { +/* Input general: */ +/* Number of calculated events */ + uint16_t event_counter; +/* Calculated events or NULL */ + struct usf_event_type __user *event; +/* Pointer (read index) to the end of available region */ +/* in the shared US data memory */ + uint32_t free_region; +/* Time (sec) to wait for data or special values: */ +/* USF_NO_WAIT_TIMEOUT, USF_INFINITIVE_TIMEOUT, USF_DEFAULT_TIMEOUT */ + uint32_t timeout; +/* Events (from conflicting devs) to be disabled/enabled */ + uint16_t event_filters; + +/* Input transparent data: */ +/* Parameters size */ + uint16_t params_data_size; +/* Pointer to the parameters */ + uint8_t __user *params_data; +/* Output parameters: */ +/* Pointer (write index) to the end of ready US data region */ +/* in the shared memory */ + uint32_t ready_region; +}; + +struct us_rx_update_info_type { +/* Input general: */ +/* Pointer (write index) to the end of ready US data region */ +/* in the shared memory */ + uint32_t ready_region; +/* Input transparent data: */ +/* Parameters size */ + uint16_t params_data_size; +/* pPointer to the parameters */ + uint8_t __user *params_data; +/* Output parameters: */ +/* Pointer (read index) to the end of available region */ +/* in the shared US data memory */ + uint32_t free_region; +}; + +struct us_detect_info_type { +/* US detection place (HW|FW) */ +/* NA in the Active and OFF states */ + enum us_detect_place_enum us_detector; +/* US detection mode */ + enum us_detect_mode_enum us_detect_mode; +/* US data dropped during this time (msec) */ + uint32_t skip_time; +/* Transparent data size */ + uint16_t params_data_size; +/* Pointer to the transparent data */ + uint8_t __user *params_data; +/* Time (sec) to wait for US presence event */ + uint32_t detect_timeout; +/* Out parameter: US presence */ + bool is_us; +}; + +struct us_version_info_type { +/* Size of memory for the version string */ + uint16_t buf_size; +/* Pointer to the memory for the version string */ + char __user *pbuf; +}; + +struct us_stream_param_type { +/* Id of module */ + uint32_t module_id; +/* Id of parameter */ + uint32_t param_id; +/* Size of memory of the parameter buffer */ + uint32_t buf_size; +/* Pointer to the memory of the parameter buffer */ + uint8_t __user *pbuf; +}; + +#endif /* __USF_H__ */ diff --git a/include/linux/soundwire/soundwire.h b/include/linux/soundwire/soundwire.h new file mode 100644 index 000000000000..a60d78cbd32b --- /dev/null +++ b/include/linux/soundwire/soundwire.h @@ -0,0 +1,312 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _LINUX_SOUNDWIRE_H +#define _LINUX_SOUNDWIRE_H +#include +#include +#include + +extern struct bus_type soundwire_type; + +/* Soundwire supports max. of 8 channels per port */ +#define SWR_MAX_CHANNEL_NUM 8 +/* Soundwire supports max. of 14 ports on each device */ +#define SWR_MAX_DEV_PORT_NUM 14 +/* Maximum number of slave devices that a master can control */ +#define SWR_MAX_DEV_NUM 11 +/* Maximum number of ports on master so that it can accommodate all the port + * configurations of all devices + */ +#define SWR_MAX_MSTR_PORT_NUM (SWR_MAX_DEV_NUM * SWR_MAX_DEV_PORT_NUM) + +/* Indicates soundwire devices group information */ +enum { + SWR_GROUP_NONE = 0, + SWR_GROUP_12 = 12, + SWR_GROUP_13 = 13, + SWR_BROADCAST = 15, +}; + +/* + * struct swr_port_info - represent soundwire frame shape + * @dev_id: logical device number of the soundwire slave device + * @port_en: flag indicates whether the port is enabled + * @port_id: logical port number of the soundwire slave device + * @offset1: sample offset indicating the offset of the channel + * from the start of the frame + * @offset2: channel offset indicating offset between to channels + * @sinterval: sample interval indicates spacing from one sample + * event to the next + * @ch_en: channels in a port that need to be enabled + * @num_ch: number of channels enabled in a port + * @ch_rate: sampling rate of the channel with which data will be + * transferred + * + * Soundwire frame shape is created based on swr_port_info struct + * parameters. + */ +struct swr_port_info { + u8 dev_id; + u8 port_en; + u8 port_id; + u8 offset1; + u8 offset2; + u8 sinterval; + u8 ch_en; + u8 num_ch; + u32 ch_rate; +}; + +/* + * struct swr_params - represent transfer of data from soundwire slave + * to soundwire master + * @tid: transaction ID to track each transaction + * @dev_id: logical device number of the soundwire slave device + * @num_port: number of ports that needs to be configured + * @port_id: array of logical port numbers of the soundwire slave device + * @num_ch: array of number of channels enabled + * @ch_rate: array of sampling rate of different channels that need to + * be configured + * @ch_en: array of channels mask for all the ports + */ +struct swr_params { + u8 tid; + u8 dev_id; + u8 num_port; + u8 port_id[SWR_MAX_DEV_PORT_NUM]; + u8 num_ch[SWR_MAX_DEV_PORT_NUM]; + u32 ch_rate[SWR_MAX_DEV_PORT_NUM]; + u8 ch_en[SWR_MAX_DEV_PORT_NUM]; +}; + +/* + * struct swr_reg - struct to handle soundwire slave register read/writes + * @tid: transaction id for reg read/writes + * @dev_id: logical device number of the soundwire slave device + * @regaddr: 16 bit regaddr of soundwire slave + * @buf: value to be written/read to/from regaddr + * @len: length of the buffer buf + */ +struct swr_reg { + u8 tid; + u8 dev_id; + u32 regaddr; + u32 *buf; + u32 len; +}; + +/* + * struct swr_master - Interface to the soundwire master controller + * @dev: device interface to this driver + * @list: link with other soundwire master controllers + * @bus_num: board/SoC specific identifier for a soundwire master + * @mlock: mutex protecting master data structures + * @devices: list of devices on this master + * @port: logical port numbers of the soundwire master. This array + * can hold maximum master ports which is equal to number of slave + * devices multiplied by number of ports in each slave device + * @port_txn: table of port config transactions with transaction id + * @reg_txn: table of register transactions with transaction id + * @last_tid: size of table port_txn (can't grow beyond 256 since + * tid is 8 bits) + * @num_port: number of active ports on soundwire master + * @gr_sid: slave id used by the group for write operations + * @connect_port: callback for configuration of soundwire port(s) + * @disconnect_port: callback for disable of soundwire port(s) + * @read: callback for soundwire slave register read + * @write: callback for soundwire slave register write + * @get_logical_dev_num: callback to get soundwire slave logical + * device number + */ +struct swr_master { + struct device dev; + struct list_head list; + unsigned int bus_num; + struct mutex mlock; + struct list_head devices; + struct swr_port_info port[SWR_MAX_MSTR_PORT_NUM]; + struct swr_params **port_txn; + struct swr_reg **reg_txn; + u8 last_tid; + u8 num_port; + u8 num_dev; + u8 gr_sid; + int (*connect_port)(struct swr_master *mstr, struct swr_params *txn); + int (*disconnect_port)(struct swr_master *mstr, struct swr_params *txn); + int (*read)(struct swr_master *mstr, u8 dev_num, u16 reg_addr, + void *buf, u32 len); + int (*write)(struct swr_master *mstr, u8 dev_num, u16 reg_addr, + const void *buf); + int (*bulk_write)(struct swr_master *master, u8 dev_num, void *reg, + const void *buf, size_t len); + int (*get_logical_dev_num)(struct swr_master *mstr, u64 dev_id, + u8 *dev_num); + void (*slvdev_datapath_control)(struct swr_master *mstr, bool enable); + bool (*remove_from_group)(struct swr_master *mstr); +}; + +static inline struct swr_master *to_swr_master(struct device *dev) +{ + return dev ? container_of(dev, struct swr_master, dev) : NULL; +} + +/* + * struct swr_device - represent a soundwire slave device + * @name: indicates the name of the device, defined in devicetree + * binding under soundwire slave device node as a compatible field. + * @master: soundwire master managing the bus hosting this device + * @driver: Device's driver. Pointer to access routines + * @dev_list: list of devices on a controller + * @dev_num: logical device number of the soundwire slave device + * @dev: driver model representation of the device + * @addr: represents "ea-addr" which is unique-id of soundwire slave + * device + * @group_id: group id supported by the slave device + */ +struct swr_device { + char name[SOUNDWIRE_NAME_SIZE]; + struct swr_master *master; + struct swr_driver *driver; + struct list_head dev_list; + u8 dev_num; + struct device dev; + unsigned long addr; + u8 group_id; +}; + +static inline struct swr_device *to_swr_device(struct device *dev) +{ + return dev ? container_of(dev, struct swr_device, dev) : NULL; +} + +/* + * struct swr_driver - Manage soundwire slave device driver + * @probe: binds this driver to soundwire device + * @remove: unbinds this driver from soundwire device + * @shutdown: standard shutdown callback used during power down/halt + * @suspend: standard suspend callback used during system suspend + * @resume: standard resume callback used during system resume + * @driver: soundwire device drivers should initialize name and + * owner field of this structure + * @id_table: list of soundwire devices supported by this driver + */ +struct swr_driver { + int (*probe)(struct swr_device *swr); + int (*remove)(struct swr_device *swr); + void (*shutdown)(struct swr_device *swr); + int (*suspend)(struct swr_device *swr, pm_message_t pmesg); + int (*resume)(struct swr_device *swr); + int (*device_up)(struct swr_device *swr); + int (*device_down)(struct swr_device *swr); + int (*reset_device)(struct swr_device *swr); + struct device_driver driver; + const struct swr_device_id *id_table; +}; + +static inline struct swr_driver *to_swr_driver(struct device_driver *drv) +{ + return drv ? container_of(drv, struct swr_driver, driver) : NULL; +} + +/* + * struct swr_boardinfo - Declare board info for soundwire device bringup + * @name: name to initialize swr_device.name + * @bus_num: identifies which soundwire master parents the soundwire + * slave_device + * @addr: represents "ea-addr" of soundwire slave device + * @of_node: pointer to OpenFirmware device node + * @swr_slave: device to be registered with soundwire + */ +struct swr_boardinfo { + char name[SOUNDWIRE_NAME_SIZE]; + int bus_num; + u64 addr; + struct device_node *of_node; + struct swr_device *swr_slave; +}; + +static inline void *swr_get_ctrl_data(const struct swr_master *master) +{ + return master ? dev_get_drvdata(&master->dev) : NULL; +} + +static inline void swr_set_ctrl_data(struct swr_master *master, void *data) +{ + dev_set_drvdata(&master->dev, data); +} + +static inline void *swr_get_dev_data(const struct swr_device *dev) +{ + return dev ? dev_get_drvdata(&dev->dev) : NULL; +} + +static inline void swr_set_dev_data(struct swr_device *dev, void *data) +{ + dev_set_drvdata(&dev->dev, data); +} + +extern int swr_startup_devices(struct swr_device *swr_dev); + +extern struct swr_device *swr_new_device(struct swr_master *master, + struct swr_boardinfo const *info); + +extern int of_register_swr_devices(struct swr_master *master); + +extern void swr_port_response(struct swr_master *mstr, u8 tid); + +extern int swr_get_logical_dev_num(struct swr_device *dev, u64 dev_id, + u8 *dev_num); + +extern int swr_read(struct swr_device *dev, u8 dev_num, u16 reg_addr, + void *buf, u32 len); + +extern int swr_write(struct swr_device *dev, u8 dev_num, u16 reg_addr, + const void *buf); + +extern int swr_bulk_write(struct swr_device *dev, u8 dev_num, void *reg_addr, + const void *buf, size_t len); + +extern int swr_connect_port(struct swr_device *dev, u8 *port_id, u8 num_port, + u8 *ch_mask, u32 *ch_rate, u8 *num_ch); + +extern int swr_disconnect_port(struct swr_device *dev, + u8 *port_id, u8 num_port); + +extern int swr_set_device_group(struct swr_device *swr_dev, u8 id); + +extern int swr_driver_register(struct swr_driver *drv); + +extern void swr_driver_unregister(struct swr_driver *drv); + +extern int swr_add_device(struct swr_master *master, + struct swr_device *swrdev); +extern void swr_remove_device(struct swr_device *swr); + +extern void swr_master_add_boarddevices(struct swr_master *master); + +extern void swr_unregister_master(struct swr_master *master); + +extern int swr_register_master(struct swr_master *master); + +extern int swr_device_up(struct swr_device *swr_dev); + +extern int swr_device_down(struct swr_device *swr_dev); + +extern int swr_reset_device(struct swr_device *swr_dev); + +extern int swr_slvdev_datapath_control(struct swr_device *swr_dev, u8 dev_num, + bool enable); +extern int swr_remove_from_group(struct swr_device *dev, u8 dev_num); + +extern void swr_remove_device(struct swr_device *swr_dev); +#endif /* _LINUX_SOUNDWIRE_H */ diff --git a/include/linux/soundwire/swr-wcd.h b/include/linux/soundwire/swr-wcd.h new file mode 100644 index 000000000000..041b901fd954 --- /dev/null +++ b/include/linux/soundwire/swr-wcd.h @@ -0,0 +1,35 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _LINUX_SWR_WCD_H +#define _LINUX_SWR_WCD_H +#include +#include +#include +#include + +enum { + SWR_CH_MAP, + SWR_DEVICE_DOWN, + SWR_DEVICE_UP, + SWR_SUBSYS_RESTART, + SWR_SET_NUM_RX_CH, +}; + +struct swr_mstr_port { + int num_port; + u8 *port; +}; + +extern int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data); + +#endif /* _LINUX_SWR_WCD_H */ diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h new file mode 100644 index 000000000000..14f644579430 --- /dev/null +++ b/include/sound/apr_audio-v2.h @@ -0,0 +1,10683 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#ifndef _APR_AUDIO_V2_H_ +#define _APR_AUDIO_V2_H_ + +#include +#include + +/* size of header needed for passing data out of band */ +#define APR_CMD_OB_HDR_SZ 12 + +/* size of header needed for getting data */ +#define APR_CMD_GET_HDR_SZ 16 + +struct param_outband { + size_t size; + void *kvaddr; + phys_addr_t paddr; +}; + +#define ADSP_ADM_VERSION 0x00070000 + +#define ADM_CMD_SHARED_MEM_MAP_REGIONS 0x00010322 +#define ADM_CMDRSP_SHARED_MEM_MAP_REGIONS 0x00010323 +#define ADM_CMD_SHARED_MEM_UNMAP_REGIONS 0x00010324 + +#define ADM_CMD_MATRIX_MAP_ROUTINGS_V5 0x00010325 +#define ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5 0x0001033D +/* Enumeration for an audio Rx matrix ID.*/ +#define ADM_MATRIX_ID_AUDIO_RX 0 + +#define ADM_MATRIX_ID_AUDIO_TX 1 + +#define ADM_MATRIX_ID_COMPRESSED_AUDIO_RX 2 + +#define ADM_MATRIX_ID_COMPRESSED_AUDIO_TX 3 + +#define ADM_MATRIX_ID_LISTEN_TX 4 +/* Enumeration for an audio Tx matrix ID.*/ +#define ADM_MATRIX_ID_AUDIOX 1 + +#define ADM_MAX_COPPS 5 + +/* make sure this matches with msm_audio_calibration */ +#define SP_V2_NUM_MAX_SPKR 2 + +/* Session map node structure. + * Immediately following this structure are num_copps + * entries of COPP IDs. The COPP IDs are 16 bits, so + * there might be a padding 16-bit field if num_copps + * is odd. + */ +struct adm_session_map_node_v5 { + u16 session_id; + /* Handle of the ASM session to be routed. Supported values: 1 + * to 8. + */ + + + u16 num_copps; + /* Number of COPPs to which this session is to be routed. + * Supported values: 0 < num_copps <= ADM_MAX_COPPS. + */ +} __packed; + +/* Payload of the #ADM_CMD_MATRIX_MAP_ROUTINGS_V5 command. + * Immediately following this structure are num_sessions of the session map + * node payload (adm_session_map_node_v5). + */ + +struct adm_cmd_matrix_map_routings_v5 { + struct apr_hdr hdr; + + u32 matrix_id; + /* Specifies whether the matrix ID is Audio Rx (0) or Audio Tx + * (1). Use the ADM_MATRIX_ID_AUDIO_RX or ADM_MATRIX_ID_AUDIOX + * macros to set this field. + */ + u32 num_sessions; + /* Number of sessions being updated by this command (optional). */ +} __packed; + +/* This command allows a client to open a COPP/Voice Proc. TX module + * and sets up the device session: Matrix -> COPP -> AFE on the RX + * and AFE -> COPP -> Matrix on the TX. This enables PCM data to + * be transferred to/from the endpoint (AFEPortID). + * + * @return + * #ADM_CMDRSP_DEVICE_OPEN_V5 with the resulting status and COPP ID. + */ +#define ADM_CMD_DEVICE_OPEN_V5 0x00010326 + +/* This command allows a client to open a COPP/Voice Proc the + * way as ADM_CMD_DEVICE_OPEN_V5 but supports multiple endpoint2 + * channels. + * + * @return + * #ADM_CMDRSP_DEVICE_OPEN_V6 with the resulting status and + * COPP ID. + */ +#define ADM_CMD_DEVICE_OPEN_V6 0x00010356 + +/* Definition for a low latency stream session. */ +#define ADM_LOW_LATENCY_DEVICE_SESSION 0x2000 + +/* Definition for a ultra low latency stream session. */ +#define ADM_ULTRA_LOW_LATENCY_DEVICE_SESSION 0x4000 + +/* Definition for a ultra low latency with Post Processing stream session. */ +#define ADM_ULL_POST_PROCESSING_DEVICE_SESSION 0x8000 + +/* Definition for a legacy device session. */ +#define ADM_LEGACY_DEVICE_SESSION 0 + +/* Indicates that endpoint_id_2 is to be ignored.*/ +#define ADM_CMD_COPP_OPEN_END_POINT_ID_2_IGNORE 0xFFFF + +#define ADM_CMD_COPP_OPEN_MODE_OF_OPERATION_RX_PATH_COPP 1 + +#define ADM_CMD_COPP_OPEN_MODE_OF_OPERATIONX_PATH_LIVE_COPP 2 + +#define ADM_CMD_COPP_OPEN_MODE_OF_OPERATIONX_PATH_NON_LIVE_COPP 3 + +/* Indicates that an audio COPP is to send/receive a mono PCM + * stream to/from + * END_POINT_ID_1. + */ +#define ADM_CMD_COPP_OPEN_CHANNEL_CONFIG_MONO 1 + +/* Indicates that an audio COPP is to send/receive a + * stereo PCM stream to/from END_POINT_ID_1. + */ +#define ADM_CMD_COPP_OPEN_CHANNEL_CONFIG_STEREO 2 + +/* Sample rate is 8000 Hz.*/ +#define ADM_CMD_COPP_OPEN_SAMPLE_RATE_8K 8000 + +/* Sample rate is 16000 Hz.*/ +#define ADM_CMD_COPP_OPEN_SAMPLE_RATE_16K 16000 + +/* Sample rate is 48000 Hz.*/ +#define ADM_CMD_COPP_OPEN_SAMPLE_RATE_48K 48000 + +/* Definition for a COPP live input flag bitmask.*/ +#define ADM_BIT_MASK_COPP_LIVE_INPUT_FLAG (0x0001U) + +/* Definition for a COPP live shift value bitmask.*/ +#define ADM_SHIFT_COPP_LIVE_INPUT_FLAG 0 + +/* Definition for the COPP ID bitmask.*/ +#define ADM_BIT_MASK_COPP_ID (0x0000FFFFUL) + +/* Definition for the COPP ID shift value.*/ +#define ADM_SHIFT_COPP_ID 0 + +/* Definition for the service ID bitmask.*/ +#define ADM_BIT_MASK_SERVICE_ID (0x00FF0000UL) + +/* Definition for the service ID shift value.*/ +#define ADM_SHIFT_SERVICE_ID 16 + +/* Definition for the domain ID bitmask.*/ +#define ADM_BIT_MASK_DOMAIN_ID (0xFF000000UL) + +/* Definition for the domain ID shift value.*/ +#define ADM_SHIFT_DOMAIN_ID 24 + +/* ADM device open command payload of the + * #ADM_CMD_DEVICE_OPEN_V5 command. + */ +struct adm_cmd_device_open_v5 { + struct apr_hdr hdr; + u16 flags; +/* Reserved for future use. Clients must set this field + * to zero. + */ + + u16 mode_of_operation; +/* Specifies whether the COPP must be opened on the Tx or Rx + * path. Use the ADM_CMD_COPP_OPEN_MODE_OF_OPERATION_* macros for + * supported values and interpretation. + * Supported values: + * - 0x1 -- Rx path COPP + * - 0x2 -- Tx path live COPP + * - 0x3 -- Tx path nonlive COPP + * Live connections cause sample discarding in the Tx device + * matrix if the destination output ports do not pull them + * fast enough. Nonlive connections queue the samples + * indefinitely. + */ + + u16 endpoint_id_1; +/* Logical and physical endpoint ID of the audio path. + * If the ID is a voice processor Tx block, it receives near + * samples. Supported values: Any pseudoport, AFE Rx port, + * or AFE Tx port For a list of valid IDs, refer to + * @xhyperref{Q4,[Q4]}. + * Q4 = Hexagon Multimedia: AFE Interface Specification + */ + + u16 endpoint_id_2; +/* Logical and physical endpoint ID 2 for a voice processor + * Tx block. + * This is not applicable to audio COPP. + * Supported values: + * - AFE Rx port + * - 0xFFFF -- Endpoint 2 is unavailable and the voice + * processor Tx + * block ignores this endpoint + * When the voice processor Tx block is created on the audio + * record path, + * it can receive far-end samples from an AFE Rx port if the + * voice call + * is active. The ID of the AFE port is provided in this + * field. + * For a list of valid IDs, refer @xhyperref{Q4,[Q4]}. + */ + + u32 topology_id; +/* Audio COPP topology ID; 32-bit GUID. */ + + u16 dev_num_channel; +/* Number of channels the audio COPP sends to/receives from + * the endpoint. + * Supported values: 1 to 8. + * The value is ignored for the voice processor Tx block, + * where channel + * configuration is derived from the topology ID. + */ + + u16 bit_width; +/* Bit width (in bits) that the audio COPP sends to/receives + * from the + * endpoint. The value is ignored for the voice processing + * Tx block, + * where the PCM width is 16 bits. + */ + + u32 sample_rate; +/* Sampling rate at which the audio COPP/voice processor + * Tx block + * interfaces with the endpoint. + * Supported values for voice processor Tx: 8000, 16000, + * 48000 Hz + * Supported values for audio COPP: >0 and <=192 kHz + */ + + u8 dev_channel_mapping[8]; +/* Array of channel mapping of buffers that the audio COPP + * sends to the endpoint. Channel[i] mapping describes channel + * I inside the buffer, where 0 < i < dev_num_channel. + * This value is relevant only for an audio Rx COPP. + * For the voice processor block and Tx audio block, this field + * is set to zero and is ignored. + */ +} __packed; + +/* ADM device open command payload of the + * #ADM_CMD_DEVICE_OPEN_V6 command. + */ +struct adm_cmd_device_open_v6 { + struct apr_hdr hdr; + u16 flags; +/* Reserved for future use. Clients must set this field + * to zero. + */ + + u16 mode_of_operation; +/* Specifies whether the COPP must be opened on the Tx or Rx + * path. Use the ADM_CMD_COPP_OPEN_MODE_OF_OPERATION_* macros for + * supported values and interpretation. + * Supported values: + * - 0x1 -- Rx path COPP + * - 0x2 -- Tx path live COPP + * - 0x3 -- Tx path nonlive COPP + * Live connections cause sample discarding in the Tx device + * matrix if the destination output ports do not pull them + * fast enough. Nonlive connections queue the samples + * indefinitely. + */ + + u16 endpoint_id_1; +/* Logical and physical endpoint ID of the audio path. + * If the ID is a voice processor Tx block, it receives near + * samples. Supported values: Any pseudoport, AFE Rx port, + * or AFE Tx port For a list of valid IDs, refer to + * @xhyperref{Q4,[Q4]}. + * Q4 = Hexagon Multimedia: AFE Interface Specification + */ + + u16 endpoint_id_2; +/* Logical and physical endpoint ID 2 for a voice processor + * Tx block. + * This is not applicable to audio COPP. + * Supported values: + * - AFE Rx port + * - 0xFFFF -- Endpoint 2 is unavailable and the voice + * processor Tx + * block ignores this endpoint + * When the voice processor Tx block is created on the audio + * record path, + * it can receive far-end samples from an AFE Rx port if the + * voice call + * is active. The ID of the AFE port is provided in this + * field. + * For a list of valid IDs, refer @xhyperref{Q4,[Q4]}. + */ + + u32 topology_id; +/* Audio COPP topology ID; 32-bit GUID. */ + + u16 dev_num_channel; +/* Number of channels the audio COPP sends to/receives from + * the endpoint. + * Supported values: 1 to 8. + * The value is ignored for the voice processor Tx block, + * where channel + * configuration is derived from the topology ID. + */ + + u16 bit_width; +/* Bit width (in bits) that the audio COPP sends to/receives + * from the + * endpoint. The value is ignored for the voice processing + * Tx block, + * where the PCM width is 16 bits. + */ + + u32 sample_rate; +/* Sampling rate at which the audio COPP/voice processor + * Tx block + * interfaces with the endpoint. + * Supported values for voice processor Tx: 8000, 16000, + * 48000 Hz + * Supported values for audio COPP: >0 and <=192 kHz + */ + + u8 dev_channel_mapping[8]; +/* Array of channel mapping of buffers that the audio COPP + * sends to the endpoint. Channel[i] mapping describes channel + * I inside the buffer, where 0 < i < dev_num_channel. + * This value is relevant only for an audio Rx COPP. + * For the voice processor block and Tx audio block, this field + * is set to zero and is ignored. + */ + + u16 dev_num_channel_eid2; +/* Number of channels the voice processor block sends + * to/receives from the endpoint2. + * Supported values: 1 to 8. + * The value is ignored for audio COPP or if endpoint_id_2 is + * set to 0xFFFF. + */ + + u16 bit_width_eid2; +/* Bit width (in bits) that the voice processor sends + * to/receives from the endpoint2. + * Supported values: 16 and 24. + * The value is ignored for audio COPP or if endpoint_id_2 is + * set to 0xFFFF. + */ + + u32 sample_rate_eid2; +/* Sampling rate at which the voice processor Tx block + * interfaces with the endpoint2. + * Supported values for Tx voice processor: >0 and <=384 kHz + * The value is ignored for audio COPP or if endpoint_id_2 is + * set to 0xFFFF. + */ + + u8 dev_channel_mapping_eid2[8]; +/* Array of channel mapping of buffers that the voice processor + * sends to the endpoint. Channel[i] mapping describes channel + * I inside the buffer, where 0 < i < dev_num_channel. + * This value is relevant only for the Tx voice processor. + * The values are ignored for audio COPP or if endpoint_id_2 is + * set to 0xFFFF. + */ +} __packed; + +/* + * This command allows the client to close a COPP and disconnect + * the device session. + */ +#define ADM_CMD_DEVICE_CLOSE_V5 0x00010327 + +/* Sets one or more parameters to a COPP. */ +#define ADM_CMD_SET_PP_PARAMS_V5 0x00010328 + +/* Payload of the #ADM_CMD_SET_PP_PARAMS_V5 command. + * If the data_payload_addr_lsw and data_payload_addr_msw element + * are NULL, a series of adm_param_datastructures immediately + * follows, whose total size is data_payload_size bytes. + */ +struct adm_cmd_set_pp_params_v5 { + struct apr_hdr hdr; + u32 payload_addr_lsw; +/* LSW of parameter data payload address. */ + u32 payload_addr_msw; +/* MSW of parameter data payload address. */ + + u32 mem_map_handle; +/* Memory map handle returned by ADM_CMD_SHARED_MEM_MAP_REGIONS + * command + * + * If mem_map_handle is zero implies the message is in + * the payload + */ + + u32 payload_size; +/* Size in bytes of the variable payload accompanying this + * message or + * in shared memory. This is used for parsing the parameter + * payload. + */ +} __packed; + +/* Payload format for COPP parameter data. + * Immediately following this structure are param_size bytes + * of parameter + * data. + */ +struct adm_param_data_v5 { + u32 module_id; + /* Unique ID of the module. */ + u32 param_id; + /* Unique ID of the parameter. */ + u16 param_size; + /* Data size of the param_id/module_id combination. + * This value is a + * multiple of 4 bytes. + */ + u16 reserved; + /* Reserved for future enhancements. + * This field must be set to zero. + */ +} __packed; + +#define ASM_STREAM_CMD_REGISTER_PP_EVENTS 0x00013213 +#define ASM_STREAM_PP_EVENT 0x00013214 +#define ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE 0x13333 +#define ASM_IEC_61937_MEDIA_FMT_EVENT 0x13334 + +#define DSP_STREAM_CMD "ADSP Stream Cmd" +#define DSP_STREAM_CALLBACK "ADSP Stream Callback Event" +#define DSP_STREAM_CALLBACK_QUEUE_SIZE 1024 + +struct dsp_stream_callback_list { + struct list_head list; + struct msm_adsp_event_data event; +}; + +struct dsp_stream_callback_prtd { + uint16_t event_count; + struct list_head event_queue; + spinlock_t prtd_spin_lock; +}; + +/* set customized mixing on matrix mixer */ +#define ADM_CMD_SET_PSPD_MTMX_STRTR_PARAMS_V5 0x00010344 +struct adm_cmd_set_pspd_mtmx_strtr_params_v5 { + struct apr_hdr hdr; + /* LSW of parameter data payload address.*/ + u32 payload_addr_lsw; + /* MSW of parameter data payload address.*/ + u32 payload_addr_msw; + /* Memory map handle returned by ADM_CMD_SHARED_MEM_MAP_REGIONS */ + /* command. If mem_map_handle is zero implies the message is in */ + /* the payload */ + u32 mem_map_handle; + /* Size in bytes of the variable payload accompanying this */ + /* message or in shared memory. This is used for parsing the */ + /* parameter payload. */ + u32 payload_size; + u16 direction; + u16 sessionid; + u16 deviceid; + u16 reserved; +} __packed; + +/* Defined specifically for in-band use, includes params */ +struct adm_cmd_set_pp_params_inband_v5 { + struct apr_hdr hdr; + /* LSW of parameter data payload address.*/ + u32 payload_addr_lsw; + /* MSW of parameter data payload address.*/ + u32 payload_addr_msw; + /* Memory map handle returned by ADM_CMD_SHARED_MEM_MAP_REGIONS */ + /* command. If mem_map_handle is zero implies the message is in */ + /* the payload */ + u32 mem_map_handle; + /* Size in bytes of the variable payload accompanying this */ + /* message or in shared memory. This is used for parsing the */ + /* parameter payload. */ + u32 payload_size; + /* Parameters passed for in band payload */ + struct adm_param_data_v5 params; +} __packed; + +/* Returns the status and COPP ID to an #ADM_CMD_DEVICE_OPEN_V5 command. + */ +#define ADM_CMDRSP_DEVICE_OPEN_V5 0x00010329 + +/* Payload of the #ADM_CMDRSP_DEVICE_OPEN_V5 message, + * which returns the + * status and COPP ID to an #ADM_CMD_DEVICE_OPEN_V5 command. + */ +struct adm_cmd_rsp_device_open_v5 { + u32 status; + /* Status message (error code).*/ + + u16 copp_id; + /* COPP ID: Supported values: 0 <= copp_id < ADM_MAX_COPPS*/ + + u16 reserved; + /* Reserved. This field must be set to zero.*/ +} __packed; + +/* Returns the status and COPP ID to an #ADM_CMD_DEVICE_OPEN_V6 command. */ +#define ADM_CMDRSP_DEVICE_OPEN_V6 0x00010357 + +/* Payload of the #ADM_CMDRSP_DEVICE_OPEN_V6 message, + * which returns the + * status and COPP ID to an #ADM_CMD_DEVICE_OPEN_V6 command + * is the exact same as ADM_CMDRSP_DEVICE_OPEN_V5. + */ + +/* This command allows a query of one COPP parameter. */ +#define ADM_CMD_GET_PP_PARAMS_V5 0x0001032A + +/* Payload an #ADM_CMD_GET_PP_PARAMS_V5 command. */ +struct adm_cmd_get_pp_params_v5 { + struct apr_hdr hdr; + u32 data_payload_addr_lsw; + /* LSW of parameter data payload address.*/ + + u32 data_payload_addr_msw; + /* MSW of parameter data payload address.*/ + + /* If the mem_map_handle is non zero, + * on ACK, the ParamData payloads begin at + * the address specified (out-of-band). + */ + + u32 mem_map_handle; + /* Memory map handle returned + * by ADM_CMD_SHARED_MEM_MAP_REGIONS command. + * If the mem_map_handle is 0, it implies that + * the ACK's payload will contain the ParamData (in-band). + */ + + u32 module_id; + /* Unique ID of the module. */ + + u32 param_id; + /* Unique ID of the parameter. */ + + u16 param_max_size; + /* Maximum data size of the parameter + *ID/module ID combination. This + * field is a multiple of 4 bytes. + */ + u16 reserved; + /* Reserved for future enhancements. + * This field must be set to zero. + */ +} __packed; + +/* Returns parameter values + * in response to an #ADM_CMD_GET_PP_PARAMS_V5 command. + */ +#define ADM_CMDRSP_GET_PP_PARAMS_V5 0x0001032B + +/* Payload of the #ADM_CMDRSP_GET_PP_PARAMS_V5 message, + * which returns parameter values in response + * to an #ADM_CMD_GET_PP_PARAMS_V5 command. + * Immediately following this + * structure is the adm_param_data_v5 + * structure containing the pre/postprocessing + * parameter data. For an in-band + * scenario, the variable payload depends + * on the size of the parameter. + */ +struct adm_cmd_rsp_get_pp_params_v5 { + u32 status; + /* Status message (error code).*/ +} __packed; + +/* Structure for holding soft stepping volume parameters. */ + +/* + * Payload of the #ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS + * parameters used by the Volume Control module. + */ + +struct audproc_softvolume_params { + u32 period; + u32 step; + u32 rampingcurve; +} __packed; + +/* + * ID of the Media Format Converter (MFC) module. + * This module supports the following parameter IDs: + * #AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT + * #AUDPROC_CHMIXER_PARAM_ID_COEFF + */ +#define AUDPROC_MODULE_ID_MFC 0x00010912 + +/* ID of the Output Media Format parameters used by AUDPROC_MODULE_ID_MFC. + * + */ +#define AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT 0x00010913 + + +struct audproc_mfc_output_media_fmt { + struct adm_cmd_set_pp_params_v5 params; + struct adm_param_data_v5 data; + uint32_t sampling_rate; + uint16_t bits_per_sample; + uint16_t num_channels; + uint16_t channel_type[8]; +} __packed; + +struct audproc_volume_ctrl_master_gain { + struct adm_cmd_set_pp_params_v5 params; + struct adm_param_data_v5 data; + /* Linear gain in Q13 format. */ + uint16_t master_gain; + /* Clients must set this field to zero. */ + uint16_t reserved; +} __packed; + +struct audproc_soft_step_volume_params { + struct adm_cmd_set_pp_params_v5 params; + struct adm_param_data_v5 data; +/* + * Period in milliseconds. + * Supported values: 0 to 15000 + */ + uint32_t period; +/* + * Step in microseconds. + * Supported values: 0 to 15000000 + */ + uint32_t step; +/* + * Ramping curve type. + * Supported values: + * - #AUDPROC_PARAM_SVC_RAMPINGCURVE_LINEAR + * - #AUDPROC_PARAM_SVC_RAMPINGCURVE_EXP + * - #AUDPROC_PARAM_SVC_RAMPINGCURVE_LOG + */ + uint32_t ramping_curve; +} __packed; + +struct audproc_enable_param_t { + struct adm_cmd_set_pp_params_inband_v5 pp_params; + /* + * Specifies whether the Audio processing module is enabled. + * This parameter is generic/common parameter to configure or + * determine the state of any audio processing module. + + * @values 0 : Disable 1: Enable + */ + uint32_t enable; +}; + +/* + * Allows a client to control the gains on various session-to-COPP paths. + */ +#define ADM_CMD_MATRIX_RAMP_GAINS_V5 0x0001032C + +/* Indicates that the target gain in the + * current adm_session_copp_gain_v5 + * structure is to be applied to all + * the session-to-COPP paths that exist for + * the specified session. + */ +#define ADM_CMD_MATRIX_RAMP_GAINS_COPP_ID_ALL_CONNECTED_COPPS 0xFFFF + +/* Indicates that the target gain is + * to be immediately applied to the + * specified session-to-COPP path, + * without a ramping fashion. + */ +#define ADM_CMD_MATRIX_RAMP_GAINS_RAMP_DURATION_IMMEDIATE 0x0000 + +/* Enumeration for a linear ramping curve.*/ +#define ADM_CMD_MATRIX_RAMP_GAINS_RAMP_CURVE_LINEAR 0x0000 + +/* Payload of the #ADM_CMD_MATRIX_RAMP_GAINS_V5 command. + * Immediately following this structure are num_gains of the + * adm_session_copp_gain_v5structure. + */ +struct adm_cmd_matrix_ramp_gains_v5 { + u32 matrix_id; +/* Specifies whether the matrix ID is Audio Rx (0) or Audio Tx (1). + * Use the ADM_MATRIX_ID_AUDIO_RX or ADM_MATRIX_ID_AUDIOX + * macros to set this field. + */ + + u16 num_gains; + /* Number of gains being applied. */ + + u16 reserved_for_align; + /* Reserved. This field must be set to zero.*/ +} __packed; + +/* Session-to-COPP path gain structure, used by the + * #ADM_CMD_MATRIX_RAMP_GAINS_V5 command. + * This structure specifies the target + * gain (per channel) that must be applied + * to a particular session-to-COPP path in + * the audio matrix. The structure can + * also be used to apply the gain globally + * to all session-to-COPP paths that + * exist for the given session. + * The aDSP uses device channel mapping to + * determine which channel gains to + * use from this command. For example, + * if the device is configured as stereo, + * the aDSP uses only target_gain_ch_1 and + * target_gain_ch_2, and it ignores + * the others. + */ +struct adm_session_copp_gain_v5 { + u16 session_id; +/* Handle of the ASM session. + * Supported values: 1 to 8. + */ + + u16 copp_id; +/* Handle of the COPP. Gain will be applied on the Session ID + * COPP ID path. + */ + + u16 ramp_duration; +/* Duration (in milliseconds) of the ramp over + * which target gains are + * to be applied. Use + * #ADM_CMD_MATRIX_RAMP_GAINS_RAMP_DURATION_IMMEDIATE + * to indicate that gain must be applied immediately. + */ + + u16 step_duration; +/* Duration (in milliseconds) of each step in the ramp. + * This parameter is ignored if ramp_duration is equal to + * #ADM_CMD_MATRIX_RAMP_GAINS_RAMP_DURATION_IMMEDIATE. + * Supported value: 1 + */ + + u16 ramp_curve; +/* Type of ramping curve. + * Supported value: #ADM_CMD_MATRIX_RAMP_GAINS_RAMP_CURVE_LINEAR + */ + + u16 reserved_for_align; + /* Reserved. This field must be set to zero. */ + + u16 target_gain_ch_1; + /* Target linear gain for channel 1 in Q13 format; */ + + u16 target_gain_ch_2; + /* Target linear gain for channel 2 in Q13 format; */ + + u16 target_gain_ch_3; + /* Target linear gain for channel 3 in Q13 format; */ + + u16 target_gain_ch_4; + /* Target linear gain for channel 4 in Q13 format; */ + + u16 target_gain_ch_5; + /* Target linear gain for channel 5 in Q13 format; */ + + u16 target_gain_ch_6; + /* Target linear gain for channel 6 in Q13 format; */ + + u16 target_gain_ch_7; + /* Target linear gain for channel 7 in Q13 format; */ + + u16 target_gain_ch_8; + /* Target linear gain for channel 8 in Q13 format; */ +} __packed; + +/* Allows to set mute/unmute on various session-to-COPP paths. + * For every session-to-COPP path (stream-device interconnection), + * mute/unmute can be set individually on the output channels. + */ +#define ADM_CMD_MATRIX_MUTE_V5 0x0001032D + +/* Indicates that mute/unmute in the + * current adm_session_copp_mute_v5structure + * is to be applied to all the session-to-COPP + * paths that exist for the specified session. + */ +#define ADM_CMD_MATRIX_MUTE_COPP_ID_ALL_CONNECTED_COPPS 0xFFFF + +/* Payload of the #ADM_CMD_MATRIX_MUTE_V5 command*/ +struct adm_cmd_matrix_mute_v5 { + u32 matrix_id; +/* Specifies whether the matrix ID is Audio Rx (0) or Audio Tx (1). + * Use the ADM_MATRIX_ID_AUDIO_RX or ADM_MATRIX_ID_AUDIOX + * macros to set this field. + */ + + u16 session_id; +/* Handle of the ASM session. + * Supported values: 1 to 8. + */ + + u16 copp_id; +/* Handle of the COPP. + * Use ADM_CMD_MATRIX_MUTE_COPP_ID_ALL_CONNECTED_COPPS + * to indicate that mute/unmute must be applied to + * all the COPPs connected to session_id. + * Supported values: + * - 0xFFFF -- Apply mute/unmute to all connected COPPs + * - Other values -- Valid COPP ID + */ + + u8 mute_flag_ch_1; + /* Mute flag for channel 1 is set to unmute (0) or mute (1). */ + + u8 mute_flag_ch_2; + /* Mute flag for channel 2 is set to unmute (0) or mute (1). */ + + u8 mute_flag_ch_3; + /* Mute flag for channel 3 is set to unmute (0) or mute (1). */ + + u8 mute_flag_ch_4; + /* Mute flag for channel 4 is set to unmute (0) or mute (1). */ + + u8 mute_flag_ch_5; + /* Mute flag for channel 5 is set to unmute (0) or mute (1). */ + + u8 mute_flag_ch_6; + /* Mute flag for channel 6 is set to unmute (0) or mute (1). */ + + u8 mute_flag_ch_7; + /* Mute flag for channel 7 is set to unmute (0) or mute (1). */ + + u8 mute_flag_ch_8; + /* Mute flag for channel 8 is set to unmute (0) or mute (1). */ + + u16 ramp_duration; +/* Period (in milliseconds) over which the soft mute/unmute will be + * applied. + * Supported values: 0 (Default) to 0xFFFF + * The default of 0 means mute/unmute will be applied immediately. + */ + + u16 reserved_for_align; + /* Clients must set this field to zero.*/ +} __packed; + +#define ASM_PARAM_ID_AAC_STEREO_MIX_COEFF_SELECTION_FLAG_V2 (0x00010DD8) + +struct asm_aac_stereo_mix_coeff_selection_param_v2 { + struct apr_hdr hdr; + u32 param_id; + u32 param_size; + u32 aac_stereo_mix_coeff_flag; +} __packed; + +/* Allows a client to connect the desired stream to + * the desired AFE port through the stream router + * + * This command allows the client to connect specified session to + * specified AFE port. This is used for compressed streams only + * opened using the #ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED or + * #ASM_STREAM_CMD_OPEN_READ_COMPRESSED command. + * + * @prerequisites + * Session ID and AFE Port ID must be valid. + * #ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED or + * #ASM_STREAM_CMD_OPEN_READ_COMPRESSED + * must have been called on this session. + */ + +#define ADM_CMD_CONNECT_AFE_PORT_V5 0x0001032E +#define ADM_CMD_DISCONNECT_AFE_PORT_V5 0x0001032F +/* Enumeration for the Rx stream router ID.*/ +#define ADM_STRTR_ID_RX 0 +/* Enumeration for the Tx stream router ID.*/ +#define ADM_STRTR_IDX 1 + +/* Payload of the #ADM_CMD_CONNECT_AFE_PORT_V5 command.*/ +struct adm_cmd_connect_afe_port_v5 { + struct apr_hdr hdr; + u8 mode; +/* ID of the stream router (RX/TX). Use the + * ADM_STRTR_ID_RX or ADM_STRTR_IDX macros + * to set this field. + */ + + u8 session_id; + /* Session ID of the stream to connect */ + + u16 afe_port_id; + /* Port ID of the AFE port to connect to.*/ + u32 num_channels; +/* Number of device channels + * Supported values: 2(Audio Sample Packet), + * 8 (HBR Audio Stream Sample Packet) + */ + + u32 sampling_rate; +/* Device sampling rate + * Supported values: Any + */ +} __packed; + + +/* adsp_adm_api.h */ + + +/* Port ID. Update afe_get_port_index + * when a new port is added here. + */ +#define PRIMARY_I2S_RX 0 +#define PRIMARY_I2S_TX 1 +#define SECONDARY_I2S_RX 4 +#define SECONDARY_I2S_TX 5 +#define MI2S_RX 6 +#define MI2S_TX 7 +#define HDMI_RX 8 +#define RSVD_2 9 +#define RSVD_3 10 +#define DIGI_MIC_TX 11 +#define VOICE2_PLAYBACK_TX 0x8002 +#define VOICE_RECORD_RX 0x8003 +#define VOICE_RECORD_TX 0x8004 +#define VOICE_PLAYBACK_TX 0x8005 + +/* Slimbus Multi channel port id pool */ +#define SLIMBUS_0_RX 0x4000 +#define SLIMBUS_0_TX 0x4001 +#define SLIMBUS_1_RX 0x4002 +#define SLIMBUS_1_TX 0x4003 +#define SLIMBUS_2_RX 0x4004 +#define SLIMBUS_2_TX 0x4005 +#define SLIMBUS_3_RX 0x4006 +#define SLIMBUS_3_TX 0x4007 +#define SLIMBUS_4_RX 0x4008 +#define SLIMBUS_4_TX 0x4009 +#define SLIMBUS_5_RX 0x400a +#define SLIMBUS_5_TX 0x400b +#define SLIMBUS_6_RX 0x400c +#define SLIMBUS_6_TX 0x400d +#define SLIMBUS_7_RX 0x400e +#define SLIMBUS_7_TX 0x400f +#define SLIMBUS_8_RX 0x4010 +#define SLIMBUS_8_TX 0x4011 +#define SLIMBUS_PORT_LAST SLIMBUS_8_TX +#define INT_BT_SCO_RX 0x3000 +#define INT_BT_SCO_TX 0x3001 +#define INT_BT_A2DP_RX 0x3002 +#define INT_FM_RX 0x3004 +#define INT_FM_TX 0x3005 +#define RT_PROXY_PORT_001_RX 0x2000 +#define RT_PROXY_PORT_001_TX 0x2001 +#define DISPLAY_PORT_RX 0x6020 + +#define AFE_PORT_INVALID 0xFFFF +#define SLIMBUS_INVALID AFE_PORT_INVALID + +#define AFE_PORT_CMD_START 0x000100ca + +#define AFE_EVENT_RTPORT_START 0 +#define AFE_EVENT_RTPORT_STOP 1 +#define AFE_EVENT_RTPORT_LOW_WM 2 +#define AFE_EVENT_RTPORT_HI_WM 3 + +#define ADSP_AFE_VERSION 0x00200000 + +/* Size of the range of port IDs for the audio interface. */ +#define AFE_PORT_ID_AUDIO_IF_PORT_RANGE_SIZE 0xF + +/* Size of the range of port IDs for internal BT-FM ports. */ +#define AFE_PORT_ID_INTERNAL_BT_FM_RANGE_SIZE 0x6 + +/* Size of the range of port IDs for SLIMbus® + * multichannel + * ports. + */ +#define AFE_PORT_ID_SLIMBUS_RANGE_SIZE 0xA + +/* Size of the range of port IDs for real-time proxy ports. */ +#define AFE_PORT_ID_RT_PROXY_PORT_RANGE_SIZE 0x2 + +/* Size of the range of port IDs for pseudoports. */ +#define AFE_PORT_ID_PSEUDOPORT_RANGE_SIZE 0x5 + +/* Start of the range of port IDs for the audio interface. */ +#define AFE_PORT_ID_AUDIO_IF_PORT_RANGE_START 0x1000 + +/* End of the range of port IDs for the audio interface. */ +#define AFE_PORT_ID_AUDIO_IF_PORT_RANGE_END \ + (AFE_PORT_ID_AUDIO_IF_PORT_RANGE_START +\ + AFE_PORT_ID_AUDIO_IF_PORT_RANGE_SIZE - 1) + +/* Start of the range of port IDs for real-time proxy ports. */ +#define AFE_PORT_ID_RT_PROXY_PORT_RANGE_START 0x2000 + +/* End of the range of port IDs for real-time proxy ports. */ +#define AFE_PORT_ID_RT_PROXY_PORT_RANGE_END \ + (AFE_PORT_ID_RT_PROXY_PORT_RANGE_START +\ + AFE_PORT_ID_RT_PROXY_PORT_RANGE_SIZE-1) + +/* Start of the range of port IDs for internal BT-FM devices. */ +#define AFE_PORT_ID_INTERNAL_BT_FM_RANGE_START 0x3000 + +/* End of the range of port IDs for internal BT-FM devices. */ +#define AFE_PORT_ID_INTERNAL_BT_FM_RANGE_END \ + (AFE_PORT_ID_INTERNAL_BT_FM_RANGE_START +\ + AFE_PORT_ID_INTERNAL_BT_FM_RANGE_SIZE-1) + +/* Start of the range of port IDs for SLIMbus devices. */ +#define AFE_PORT_ID_SLIMBUS_RANGE_START 0x4000 + +/* End of the range of port IDs for SLIMbus devices. */ +#define AFE_PORT_ID_SLIMBUS_RANGE_END \ + (AFE_PORT_ID_SLIMBUS_RANGE_START +\ + AFE_PORT_ID_SLIMBUS_RANGE_SIZE-1) + +/* Start of the range of port IDs for pseudoports. */ +#define AFE_PORT_ID_PSEUDOPORT_RANGE_START 0x8001 + +/* End of the range of port IDs for pseudoports. */ +#define AFE_PORT_ID_PSEUDOPORT_RANGE_END \ + (AFE_PORT_ID_PSEUDOPORT_RANGE_START +\ + AFE_PORT_ID_PSEUDOPORT_RANGE_SIZE-1) + +/* Start of the range of port IDs for TDM devices. */ +#define AFE_PORT_ID_TDM_PORT_RANGE_START 0x9000 + +/* End of the range of port IDs for TDM devices. */ +#define AFE_PORT_ID_TDM_PORT_RANGE_END \ + (AFE_PORT_ID_TDM_PORT_RANGE_START+0x40-1) + +/* Size of the range of port IDs for TDM ports. */ +#define AFE_PORT_ID_TDM_PORT_RANGE_SIZE \ + (AFE_PORT_ID_TDM_PORT_RANGE_END - \ + AFE_PORT_ID_TDM_PORT_RANGE_START+1) + +#define AFE_PORT_ID_PRIMARY_MI2S_RX 0x1000 +#define AFE_PORT_ID_PRIMARY_MI2S_TX 0x1001 +#define AFE_PORT_ID_SECONDARY_MI2S_RX 0x1002 +#define AFE_PORT_ID_SECONDARY_MI2S_TX 0x1003 +#define AFE_PORT_ID_TERTIARY_MI2S_RX 0x1004 +#define AFE_PORT_ID_TERTIARY_MI2S_TX 0x1005 +#define AFE_PORT_ID_QUATERNARY_MI2S_RX 0x1006 +#define AFE_PORT_ID_QUATERNARY_MI2S_TX 0x1007 +#define AUDIO_PORT_ID_I2S_RX 0x1008 +#define AFE_PORT_ID_DIGITAL_MIC_TX 0x1009 +#define AFE_PORT_ID_PRIMARY_PCM_RX 0x100A +#define AFE_PORT_ID_PRIMARY_PCM_TX 0x100B +#define AFE_PORT_ID_SECONDARY_PCM_RX 0x100C +#define AFE_PORT_ID_SECONDARY_PCM_TX 0x100D +#define AFE_PORT_ID_MULTICHAN_HDMI_RX 0x100E +#define AFE_PORT_ID_SECONDARY_MI2S_RX_SD1 0x1010 +#define AFE_PORT_ID_TERTIARY_PCM_RX 0x1012 +#define AFE_PORT_ID_TERTIARY_PCM_TX 0x1013 +#define AFE_PORT_ID_QUATERNARY_PCM_RX 0x1014 +#define AFE_PORT_ID_QUATERNARY_PCM_TX 0x1015 +#define AFE_PORT_ID_QUINARY_MI2S_RX 0x1016 +#define AFE_PORT_ID_QUINARY_MI2S_TX 0x1017 +/* ID of the senary MI2S Rx port. */ +#define AFE_PORT_ID_SENARY_MI2S_RX 0x1018 +/* ID of the senary MI2S Tx port. */ +#define AFE_PORT_ID_SENARY_MI2S_TX 0x1019 +/* ID of the Internal 0 MI2S Rx port */ +#define AFE_PORT_ID_INT0_MI2S_RX 0x102E +/* ID of the Internal 0 MI2S Tx port */ +#define AFE_PORT_ID_INT0_MI2S_TX 0x102F +/* ID of the Internal 1 MI2S Rx port */ +#define AFE_PORT_ID_INT1_MI2S_RX 0x1030 +/* ID of the Internal 1 MI2S Tx port */ +#define AFE_PORT_ID_INT1_MI2S_TX 0x1031 +/* ID of the Internal 2 MI2S Rx port */ +#define AFE_PORT_ID_INT2_MI2S_RX 0x1032 +/* ID of the Internal 2 MI2S Tx port */ +#define AFE_PORT_ID_INT2_MI2S_TX 0x1033 +/* ID of the Internal 3 MI2S Rx port */ +#define AFE_PORT_ID_INT3_MI2S_RX 0x1034 +/* ID of the Internal 3 MI2S Tx port */ +#define AFE_PORT_ID_INT3_MI2S_TX 0x1035 +/* ID of the Internal 4 MI2S Rx port */ +#define AFE_PORT_ID_INT4_MI2S_RX 0x1036 +/* ID of the Internal 4 MI2S Tx port */ +#define AFE_PORT_ID_INT4_MI2S_TX 0x1037 +/* ID of the Internal 5 MI2S Rx port */ +#define AFE_PORT_ID_INT5_MI2S_RX 0x1038 +/* ID of the Internal 5 MI2S Tx port */ +#define AFE_PORT_ID_INT5_MI2S_TX 0x1039 +/* ID of the Internal 6 MI2S Rx port */ +#define AFE_PORT_ID_INT6_MI2S_RX 0x103A +/* ID of the Internal 6 MI2S Tx port */ +#define AFE_PORT_ID_INT6_MI2S_TX 0x103B +#define AFE_PORT_ID_SPDIF_RX 0x5000 +#define AFE_PORT_ID_RT_PROXY_PORT_001_RX 0x2000 +#define AFE_PORT_ID_RT_PROXY_PORT_001_TX 0x2001 +#define AFE_PORT_ID_INTERNAL_BT_SCO_RX 0x3000 +#define AFE_PORT_ID_INTERNAL_BT_SCO_TX 0x3001 +#define AFE_PORT_ID_INTERNAL_BT_A2DP_RX 0x3002 +#define AFE_PORT_ID_INTERNAL_FM_RX 0x3004 +#define AFE_PORT_ID_INTERNAL_FM_TX 0x3005 +/* SLIMbus Rx port on channel 0. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX 0x4000 +/* SLIMbus Tx port on channel 0. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX 0x4001 +/* SLIMbus Rx port on channel 1. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX 0x4002 +/* SLIMbus Tx port on channel 1. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX 0x4003 +/* SLIMbus Rx port on channel 2. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX 0x4004 +/* SLIMbus Tx port on channel 2. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX 0x4005 +/* SLIMbus Rx port on channel 3. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX 0x4006 +/* SLIMbus Tx port on channel 3. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX 0x4007 +/* SLIMbus Rx port on channel 4. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX 0x4008 +/* SLIMbus Tx port on channel 4. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX 0x4009 +/* SLIMbus Rx port on channel 5. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX 0x400a +/* SLIMbus Tx port on channel 5. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX 0x400b +/* SLIMbus Rx port on channel 6. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX 0x400c +/* SLIMbus Tx port on channel 6. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX 0x400d +/* SLIMbus Rx port on channel 7. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_7_RX 0x400e +/* SLIMbus Tx port on channel 7. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_7_TX 0x400f +/* SLIMbus Rx port on channel 8. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_8_RX 0x4010 +/* SLIMbus Tx port on channel 8. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_8_TX 0x4011 +/* AFE Rx port for audio over Display port */ +#define AFE_PORT_ID_HDMI_OVER_DP_RX 0x6020 +/*USB AFE port */ +#define AFE_PORT_ID_USB_RX 0x7000 +#define AFE_PORT_ID_USB_TX 0x7001 + +/* Generic pseudoport 1. */ +#define AFE_PORT_ID_PSEUDOPORT_01 0x8001 +/* Generic pseudoport 2. */ +#define AFE_PORT_ID_PSEUDOPORT_02 0x8002 + +/* @xreflabel{hdr:AfePortIdPrimaryAuxPcmTx} + * Primary Aux PCM Tx port ID. + */ +#define AFE_PORT_ID_PRIMARY_PCM_TX 0x100B +/* Pseudoport that corresponds to the voice Rx path. + * For recording, the voice Rx path samples are written to this + * port and consumed by the audio path. + */ + +#define AFE_PORT_ID_VOICE_RECORD_RX 0x8003 + +/* Pseudoport that corresponds to the voice Tx path. + * For recording, the voice Tx path samples are written to this + * port and consumed by the audio path. + */ + +#define AFE_PORT_ID_VOICE_RECORD_TX 0x8004 +/* Pseudoport that corresponds to in-call voice delivery samples. + * During in-call audio delivery, the audio path delivers samples + * to this port from where the voice path delivers them on the + * Rx path. + */ +#define AFE_PORT_ID_VOICE2_PLAYBACK_TX 0x8002 +#define AFE_PORT_ID_VOICE_PLAYBACK_TX 0x8005 + +#define AFE_PORT_ID_PRIMARY_TDM_RX \ + (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x00) +#define AFE_PORT_ID_PRIMARY_TDM_RX_1 \ + (AFE_PORT_ID_PRIMARY_TDM_RX + 0x02) +#define AFE_PORT_ID_PRIMARY_TDM_RX_2 \ + (AFE_PORT_ID_PRIMARY_TDM_RX + 0x04) +#define AFE_PORT_ID_PRIMARY_TDM_RX_3 \ + (AFE_PORT_ID_PRIMARY_TDM_RX + 0x06) +#define AFE_PORT_ID_PRIMARY_TDM_RX_4 \ + (AFE_PORT_ID_PRIMARY_TDM_RX + 0x08) +#define AFE_PORT_ID_PRIMARY_TDM_RX_5 \ + (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0A) +#define AFE_PORT_ID_PRIMARY_TDM_RX_6 \ + (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0C) +#define AFE_PORT_ID_PRIMARY_TDM_RX_7 \ + (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0E) + +#define AFE_PORT_ID_PRIMARY_TDM_TX \ + (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x01) +#define AFE_PORT_ID_PRIMARY_TDM_TX_1 \ + (AFE_PORT_ID_PRIMARY_TDM_TX + 0x02) +#define AFE_PORT_ID_PRIMARY_TDM_TX_2 \ + (AFE_PORT_ID_PRIMARY_TDM_TX + 0x04) +#define AFE_PORT_ID_PRIMARY_TDM_TX_3 \ + (AFE_PORT_ID_PRIMARY_TDM_TX + 0x06) +#define AFE_PORT_ID_PRIMARY_TDM_TX_4 \ + (AFE_PORT_ID_PRIMARY_TDM_TX + 0x08) +#define AFE_PORT_ID_PRIMARY_TDM_TX_5 \ + (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0A) +#define AFE_PORT_ID_PRIMARY_TDM_TX_6 \ + (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0C) +#define AFE_PORT_ID_PRIMARY_TDM_TX_7 \ + (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0E) + +#define AFE_PORT_ID_SECONDARY_TDM_RX \ + (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x10) +#define AFE_PORT_ID_SECONDARY_TDM_RX_1 \ + (AFE_PORT_ID_SECONDARY_TDM_RX + 0x02) +#define AFE_PORT_ID_SECONDARY_TDM_RX_2 \ + (AFE_PORT_ID_SECONDARY_TDM_RX + 0x04) +#define AFE_PORT_ID_SECONDARY_TDM_RX_3 \ + (AFE_PORT_ID_SECONDARY_TDM_RX + 0x06) +#define AFE_PORT_ID_SECONDARY_TDM_RX_4 \ + (AFE_PORT_ID_SECONDARY_TDM_RX + 0x08) +#define AFE_PORT_ID_SECONDARY_TDM_RX_5 \ + (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0A) +#define AFE_PORT_ID_SECONDARY_TDM_RX_6 \ + (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0C) +#define AFE_PORT_ID_SECONDARY_TDM_RX_7 \ + (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0E) + +#define AFE_PORT_ID_SECONDARY_TDM_TX \ + (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x11) +#define AFE_PORT_ID_SECONDARY_TDM_TX_1 \ + (AFE_PORT_ID_SECONDARY_TDM_TX + 0x02) +#define AFE_PORT_ID_SECONDARY_TDM_TX_2 \ + (AFE_PORT_ID_SECONDARY_TDM_TX + 0x04) +#define AFE_PORT_ID_SECONDARY_TDM_TX_3 \ + (AFE_PORT_ID_SECONDARY_TDM_TX + 0x06) +#define AFE_PORT_ID_SECONDARY_TDM_TX_4 \ + (AFE_PORT_ID_SECONDARY_TDM_TX + 0x08) +#define AFE_PORT_ID_SECONDARY_TDM_TX_5 \ + (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0A) +#define AFE_PORT_ID_SECONDARY_TDM_TX_6 \ + (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0C) +#define AFE_PORT_ID_SECONDARY_TDM_TX_7 \ + (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0E) + +#define AFE_PORT_ID_TERTIARY_TDM_RX \ + (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x20) +#define AFE_PORT_ID_TERTIARY_TDM_RX_1 \ + (AFE_PORT_ID_TERTIARY_TDM_RX + 0x02) +#define AFE_PORT_ID_TERTIARY_TDM_RX_2 \ + (AFE_PORT_ID_TERTIARY_TDM_RX + 0x04) +#define AFE_PORT_ID_TERTIARY_TDM_RX_3 \ + (AFE_PORT_ID_TERTIARY_TDM_RX + 0x06) +#define AFE_PORT_ID_TERTIARY_TDM_RX_4 \ + (AFE_PORT_ID_TERTIARY_TDM_RX + 0x08) +#define AFE_PORT_ID_TERTIARY_TDM_RX_5 \ + (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0A) +#define AFE_PORT_ID_TERTIARY_TDM_RX_6 \ + (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0C) +#define AFE_PORT_ID_TERTIARY_TDM_RX_7 \ + (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0E) + +#define AFE_PORT_ID_TERTIARY_TDM_TX \ + (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x21) +#define AFE_PORT_ID_TERTIARY_TDM_TX_1 \ + (AFE_PORT_ID_TERTIARY_TDM_TX + 0x02) +#define AFE_PORT_ID_TERTIARY_TDM_TX_2 \ + (AFE_PORT_ID_TERTIARY_TDM_TX + 0x04) +#define AFE_PORT_ID_TERTIARY_TDM_TX_3 \ + (AFE_PORT_ID_TERTIARY_TDM_TX + 0x06) +#define AFE_PORT_ID_TERTIARY_TDM_TX_4 \ + (AFE_PORT_ID_TERTIARY_TDM_TX + 0x08) +#define AFE_PORT_ID_TERTIARY_TDM_TX_5 \ + (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0A) +#define AFE_PORT_ID_TERTIARY_TDM_TX_6 \ + (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0C) +#define AFE_PORT_ID_TERTIARY_TDM_TX_7 \ + (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0E) + +#define AFE_PORT_ID_QUATERNARY_TDM_RX \ + (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x30) +#define AFE_PORT_ID_QUATERNARY_TDM_RX_1 \ + (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x02) +#define AFE_PORT_ID_QUATERNARY_TDM_RX_2 \ + (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x04) +#define AFE_PORT_ID_QUATERNARY_TDM_RX_3 \ + (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x06) +#define AFE_PORT_ID_QUATERNARY_TDM_RX_4 \ + (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x08) +#define AFE_PORT_ID_QUATERNARY_TDM_RX_5 \ + (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0A) +#define AFE_PORT_ID_QUATERNARY_TDM_RX_6 \ + (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0C) +#define AFE_PORT_ID_QUATERNARY_TDM_RX_7 \ + (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0E) + +#define AFE_PORT_ID_QUATERNARY_TDM_TX \ + (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x31) +#define AFE_PORT_ID_QUATERNARY_TDM_TX_1 \ + (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x02) +#define AFE_PORT_ID_QUATERNARY_TDM_TX_2 \ + (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x04) +#define AFE_PORT_ID_QUATERNARY_TDM_TX_3 \ + (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x06) +#define AFE_PORT_ID_QUATERNARY_TDM_TX_4 \ + (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x08) +#define AFE_PORT_ID_QUATERNARY_TDM_TX_5 \ + (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0A) +#define AFE_PORT_ID_QUATERNARY_TDM_TX_6 \ + (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0C) +#define AFE_PORT_ID_QUATERNARY_TDM_TX_7 \ + (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0E) + +#define AFE_PORT_ID_INVALID 0xFFFF + +#define AAC_ENC_MODE_AAC_LC 0x02 +#define AAC_ENC_MODE_AAC_P 0x05 +#define AAC_ENC_MODE_EAAC_P 0x1D + +#define AFE_PSEUDOPORT_CMD_START 0x000100cf +struct afe_pseudoport_start_command { + struct apr_hdr hdr; + u16 port_id; /* Pseudo Port 1 = 0x8000 */ + /* Pseudo Port 2 = 0x8001 */ + /* Pseudo Port 3 = 0x8002 */ + u16 timing; /* FTRT = 0 , AVTimer = 1, */ +} __packed; + +#define AFE_PSEUDOPORT_CMD_STOP 0x000100d0 +struct afe_pseudoport_stop_command { + struct apr_hdr hdr; + u16 port_id; /* Pseudo Port 1 = 0x8000 */ + /* Pseudo Port 2 = 0x8001 */ + /* Pseudo Port 3 = 0x8002 */ + u16 reserved; +} __packed; + + +#define AFE_MODULE_SIDETONE_IIR_FILTER 0x00010202 +#define AFE_PARAM_ID_ENABLE 0x00010203 + +/* Payload of the #AFE_PARAM_ID_ENABLE + * parameter, which enables or + * disables any module. + * The fixed size of this structure is four bytes. + */ + +struct afe_mod_enable_param { + u16 enable; + /* Enables (1) or disables (0) the module. */ + + u16 reserved; + /* This field must be set to zero. */ +} __packed; + +/* ID of the configuration parameter used by the + * #AFE_MODULE_SIDETONE_IIR_FILTER module. + */ +#define AFE_PARAM_ID_SIDETONE_IIR_FILTER_CONFIG 0x00010204 +#define MAX_SIDETONE_IIR_DATA_SIZE 224 +#define MAX_NO_IIR_FILTER_STAGE 10 + +struct afe_sidetone_iir_filter_config_params { + u16 num_biquad_stages; +/* Number of stages. + * Supported values: Minimum of 5 and maximum of 10 + */ + + u16 pregain; +/* Pregain for the compensating filter response. + * Supported values: Any number in Q13 format + */ + uint8_t iir_config[MAX_SIDETONE_IIR_DATA_SIZE]; +} __packed; + +#define AFE_MODULE_LOOPBACK 0x00010205 +#define AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH 0x00010206 + +/* Payload of the #AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH parameter, + * which gets/sets loopback gain of a port to an Rx port. + * The Tx port ID of the loopback is part of the set_param command. + */ + +/* Payload of the #AFE_PORT_CMD_SET_PARAM_V2 command's + * configuration/calibration settings for the AFE port. + */ +struct afe_port_cmd_set_param_v2 { + u16 port_id; +/* Port interface and direction (Rx or Tx) to start. */ + + u16 payload_size; +/* Actual size of the payload in bytes. + * This is used for parsing the parameter payload. + * Supported values: > 0 + */ + +u32 payload_address_lsw; +/* LSW of 64 bit Payload address. + * Address should be 32-byte, + * 4kbyte aligned and must be contiguous memory. + */ + +u32 payload_address_msw; +/* MSW of 64 bit Payload address. + * In case of 32-bit shared memory address, + * this field must be set to zero. + * In case of 36-bit shared memory address, + * bit-4 to bit-31 must be set to zero. + * Address should be 32-byte, 4kbyte aligned + * and must be contiguous memory. + */ + +u32 mem_map_handle; +/* Memory map handle returned by + * AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS commands. + * Supported Values: + * - NULL -- Message. The parameter data is in-band. + * - Non-NULL -- The parameter data is Out-band.Pointer to + * the physical address + * in shared memory of the payload data. + * An optional field is available if parameter + * data is in-band: + * afe_param_data_v2 param_data[...]. + * For detailed payload content, see the + * afe_port_param_data_v2 structure. + */ +} __packed; + +#define AFE_PORT_CMD_SET_PARAM_V2 0x000100EF + +struct afe_port_param_data_v2 { + u32 module_id; +/* ID of the module to be configured. + * Supported values: Valid module ID + */ + +u32 param_id; +/* ID of the parameter corresponding to the supported parameters + * for the module ID. + * Supported values: Valid parameter ID + */ + +u16 param_size; +/* Actual size of the data for the + * module_id/param_id pair. The size is a + * multiple of four bytes. + * Supported values: > 0 + */ + +u16 reserved; +/* This field must be set to zero. + */ +} __packed; + +struct afe_loopback_gain_per_path_param { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + u16 rx_port_id; +/* Rx port of the loopback. */ + +u16 gain; +/* Loopback gain per path of the port. + * Supported values: Any number in Q13 format + */ +} __packed; + +/* Parameter ID used to configure and enable/disable the + * loopback path. The difference with respect to the existing + * API, AFE_PORT_CMD_LOOPBACK, is that it allows Rx port to be + * configured as source port in loopback path. Port-id in + * AFE_PORT_CMD_SET_PARAM cmd is the source port which can be + * Tx or Rx port. In addition, we can configure the type of + * routing mode to handle different use cases. + */ +#define AFE_PARAM_ID_LOOPBACK_CONFIG 0x0001020B +#define AFE_API_VERSION_LOOPBACK_CONFIG 0x1 + +enum afe_loopback_routing_mode { + LB_MODE_DEFAULT = 1, + /* Regular loopback from source to destination port */ + LB_MODE_SIDETONE, + /* Sidetone feed from Tx source to Rx destination port */ + LB_MODE_EC_REF_VOICE_AUDIO, + /* Echo canceller reference, voice + audio + DTMF */ + LB_MODE_EC_REF_VOICE + /* Echo canceller reference, voice alone */ +} __packed; + +/* Payload of the #AFE_PARAM_ID_LOOPBACK_CONFIG , + * which enables/disables one AFE loopback. + */ +struct afe_loopback_cfg_v1 { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + u32 loopback_cfg_minor_version; +/* Minor version used for tracking the version of the RMC module + * configuration interface. + * Supported values: #AFE_API_VERSION_LOOPBACK_CONFIG + */ + u16 dst_port_id; + /* Destination Port Id. */ + u16 routing_mode; +/* Specifies data path type from src to dest port. + * Supported values: + * #LB_MODE_DEFAULT + * #LB_MODE_SIDETONE + * #LB_MODE_EC_REF_VOICE_AUDIO + * #LB_MODE_EC_REF_VOICE_A + * #LB_MODE_EC_REF_VOICE + */ + + u16 enable; +/* Specifies whether to enable (1) or + * disable (0) an AFE loopback. + */ + u16 reserved; +/* Reserved for 32-bit alignment. This field must be set to 0. + */ + +} __packed; + +struct afe_loopback_sidetone_gain { + u16 rx_port_id; + u16 gain; +} __packed; + +struct loopback_cfg_data { + u32 loopback_cfg_minor_version; +/* Minor version used for tracking the version of the RMC module + * configuration interface. + * Supported values: #AFE_API_VERSION_LOOPBACK_CONFIG + */ + u16 dst_port_id; + /* Destination Port Id. */ + u16 routing_mode; +/* Specifies data path type from src to dest port. + * Supported values: + * #LB_MODE_DEFAULT + * #LB_MODE_SIDETONE + * #LB_MODE_EC_REF_VOICE_AUDIO + * #LB_MODE_EC_REF_VOICE_A + * #LB_MODE_EC_REF_VOICE + */ + + u16 enable; +/* Specifies whether to enable (1) or + * disable (0) an AFE loopback. + */ + u16 reserved; +/* Reserved for 32-bit alignment. This field must be set to 0. + */ +} __packed; + +struct afe_st_loopback_cfg_v1 { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 gain_pdata; + struct afe_loopback_sidetone_gain gain_data; + struct afe_port_param_data_v2 cfg_pdata; + struct loopback_cfg_data cfg_data; +} __packed; + +struct afe_loopback_iir_cfg_v2 { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 st_iir_enable_pdata; + struct afe_mod_enable_param st_iir_mode_enable_data; + struct afe_port_param_data_v2 st_iir_filter_config_pdata; + struct afe_sidetone_iir_filter_config_params st_iir_filter_config_data; +} __packed; +#define AFE_MODULE_SPEAKER_PROTECTION 0x00010209 +#define AFE_PARAM_ID_SPKR_PROT_CONFIG 0x0001020a +#define AFE_API_VERSION_SPKR_PROT_CONFIG 0x1 +#define AFE_SPKR_PROT_EXCURSIONF_LEN 512 +struct afe_spkr_prot_cfg_param_v1 { + u32 spkr_prot_minor_version; +/* + * Minor version used for tracking the version of the + * speaker protection module configuration interface. + * Supported values: #AFE_API_VERSION_SPKR_PROT_CONFIG + */ + +int16_t win_size; +/* Analysis and synthesis window size (nWinSize). + * Supported values: 1024, 512, 256 samples + */ + +int16_t margin; +/* Allowable margin for excursion prediction, + * in L16Q15 format. This is a + * control parameter to allow + * for overestimation of peak excursion. + */ + +int16_t spkr_exc_limit; +/* Speaker excursion limit, in L16Q15 format.*/ + +int16_t spkr_resonance_freq; +/* Resonance frequency of the speaker; used + * to define a frequency range + * for signal modification. + * + * Supported values: 0 to 2000 Hz + */ + +int16_t limhresh; +/* Threshold of the hard limiter; used to + * prevent overshooting beyond a + * signal level that was set by the limiter + * prior to speaker protection. + * Supported values: 0 to 32767 + */ + +int16_t hpf_cut_off_freq; +/* High pass filter cutoff frequency. + * Supported values: 100, 200, 300 Hz + */ + +int16_t hpf_enable; +/* Specifies whether the high pass filter + * is enabled (0) or disabled (1). + */ + +int16_t reserved; +/* This field must be set to zero. */ + +int32_t amp_gain; +/* Amplifier gain in L32Q15 format. + * This is the RMS voltage at the + * loudspeaker when a 0dBFS tone + * is played in the digital domain. + */ + +int16_t excursionf[AFE_SPKR_PROT_EXCURSIONF_LEN]; +/* Array of the excursion transfer function. + * The peak excursion of the + * loudspeaker diaphragm is + * measured in millimeters for 1 Vrms Sine + * tone at all FFT bin frequencies. + * Supported values: Q15 format + */ +} __packed; + + +#define AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER 0x000100E0 + +/* Payload of the #AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER + * command, which registers a real-time port driver + * with the AFE service. + */ +struct afe_service_cmd_register_rt_port_driver { + struct apr_hdr hdr; + u16 port_id; +/* Port ID with which the real-time driver exchanges data + * (registers for events). + * Supported values: #AFE_PORT_ID_RT_PROXY_PORT_RANGE_START to + * #AFE_PORT_ID_RT_PROXY_PORT_RANGE_END + */ + + u16 reserved; + /* This field must be set to zero. */ +} __packed; + +#define AFE_SERVICE_CMD_UNREGISTER_RT_PORT_DRIVER 0x000100E1 + +/* Payload of the #AFE_SERVICE_CMD_UNREGISTER_RT_PORT_DRIVER + * command, which unregisters a real-time port driver from + * the AFE service. + */ +struct afe_service_cmd_unregister_rt_port_driver { + struct apr_hdr hdr; + u16 port_id; +/* Port ID from which the real-time + * driver unregisters for events. + * Supported values: #AFE_PORT_ID_RT_PROXY_PORT_RANGE_START to + * #AFE_PORT_ID_RT_PROXY_PORT_RANGE_END + */ + + u16 reserved; + /* This field must be set to zero. */ +} __packed; + +#define AFE_EVENT_RT_PROXY_PORT_STATUS 0x00010105 +#define AFE_EVENTYPE_RT_PROXY_PORT_START 0 +#define AFE_EVENTYPE_RT_PROXY_PORT_STOP 1 +#define AFE_EVENTYPE_RT_PROXY_PORT_LOW_WATER_MARK 2 +#define AFE_EVENTYPE_RT_PROXY_PORT_HIGH_WATER_MARK 3 +#define AFE_EVENTYPE_RT_PROXY_PORT_INVALID 0xFFFF + +/* Payload of the #AFE_EVENT_RT_PROXY_PORT_STATUS + * message, which sends an event from the AFE service + * to a registered client. + */ +struct afe_event_rt_proxy_port_status { + u16 port_id; +/* Port ID to which the event is sent. + * Supported values: #AFE_PORT_ID_RT_PROXY_PORT_RANGE_START to + * #AFE_PORT_ID_RT_PROXY_PORT_RANGE_END + */ + + u16 eventype; +/* Type of event. + * Supported values: + * - #AFE_EVENTYPE_RT_PROXY_PORT_START + * - #AFE_EVENTYPE_RT_PROXY_PORT_STOP + * - #AFE_EVENTYPE_RT_PROXY_PORT_LOW_WATER_MARK + * - #AFE_EVENTYPE_RT_PROXY_PORT_HIGH_WATER_MARK + */ +} __packed; + +#define AFE_PORT_DATA_CMD_RT_PROXY_PORT_WRITE_V2 0x000100ED + +struct afe_port_data_cmd_rt_proxy_port_write_v2 { + struct apr_hdr hdr; + u16 port_id; +/* Tx (mic) proxy port ID with which the real-time + * driver exchanges data. + * Supported values: #AFE_PORT_ID_RT_PROXY_PORT_RANGE_START to + * #AFE_PORT_ID_RT_PROXY_PORT_RANGE_END + */ + + u16 reserved; + /* This field must be set to zero. */ + + u32 buffer_address_lsw; +/* LSW Address of the buffer containing the + * data from the real-time source + * device on a client. + */ + + u32 buffer_address_msw; +/* MSW Address of the buffer containing the + * data from the real-time source + * device on a client. + */ + + u32 mem_map_handle; +/* A memory map handle encapsulating shared memory + * attributes is returned if + * AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS + * command is successful. + * Supported Values: + * - Any 32 bit value + */ + + u32 available_bytes; +/* Number of valid bytes available + * in the buffer (including all + * channels: number of bytes per + * channel = availableBytesumChannels). + * Supported values: > 0 + * + * This field must be equal to the frame + * size specified in the #AFE_PORT_AUDIO_IF_CONFIG + * command that was sent to configure this + * port. + */ +} __packed; + +#define AFE_PORT_DATA_CMD_RT_PROXY_PORT_READ_V2 0x000100EE + +/* Payload of the + * #AFE_PORT_DATA_CMD_RT_PROXY_PORT_READ_V2 command, which + * delivers an empty buffer to the AFE service. On + * acknowledgment, data is filled in the buffer. + */ +struct afe_port_data_cmd_rt_proxy_port_read_v2 { + struct apr_hdr hdr; + u16 port_id; +/* Rx proxy port ID with which the real-time + * driver exchanges data. + * Supported values: #AFE_PORT_ID_RT_PROXY_PORT_RANGE_START to + * #AFE_PORT_ID_RT_PROXY_PORT_RANGE_END + * (This must be an Rx (speaker) port.) + */ + + u16 reserved; + /* This field must be set to zero. */ + + u32 buffer_address_lsw; +/* LSW Address of the buffer containing the data sent from the AFE + * service to a real-time sink device on the client. + */ + + + u32 buffer_address_msw; +/* MSW Address of the buffer containing the data sent from the AFE + * service to a real-time sink device on the client. + */ + + u32 mem_map_handle; +/* A memory map handle encapsulating shared memory attributes is + * returned if AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS command is + * successful. + * Supported Values: + * - Any 32 bit value + */ + + u32 available_bytes; +/* Number of valid bytes available in the buffer (including all + * channels). + * Supported values: > 0 + * This field must be equal to the frame size specified in the + * #AFE_PORT_AUDIO_IF_CONFIG command that was sent to configure + * this port. + */ +} __packed; + +/* This module ID is related to device configuring like I2S,PCM, + * HDMI, SLIMBus etc. This module supports following parameter ids. + * - #AFE_PARAM_ID_I2S_CONFIG + * - #AFE_PARAM_ID_PCM_CONFIG + * - #AFE_PARAM_ID_DIGI_MIC_CONFIG + * - #AFE_PARAM_ID_HDMI_CONFIG + * - #AFE_PARAM_ID_INTERNAL_BT_FM_CONFIG + * - #AFE_PARAM_ID_SLIMBUS_CONFIG + * - #AFE_PARAM_ID_RT_PROXY_CONFIG + */ + +#define AFE_MODULE_AUDIO_DEV_INTERFACE 0x0001020C +#define AFE_PORT_SAMPLE_RATE_8K 8000 +#define AFE_PORT_SAMPLE_RATE_16K 16000 +#define AFE_PORT_SAMPLE_RATE_48K 48000 +#define AFE_PORT_SAMPLE_RATE_96K 96000 +#define AFE_PORT_SAMPLE_RATE_176P4K 176400 +#define AFE_PORT_SAMPLE_RATE_192K 192000 +#define AFE_PORT_SAMPLE_RATE_352P8K 352800 +#define AFE_LINEAR_PCM_DATA 0x0 +#define AFE_NON_LINEAR_DATA 0x1 +#define AFE_LINEAR_PCM_DATA_PACKED_60958 0x2 +#define AFE_NON_LINEAR_DATA_PACKED_60958 0x3 +#define AFE_GENERIC_COMPRESSED 0x8 + +/* This param id is used to configure I2S interface */ +#define AFE_PARAM_ID_I2S_CONFIG 0x0001020D +#define AFE_API_VERSION_I2S_CONFIG 0x1 +/* Enumeration for setting the I2S configuration + * channel_mode parameter to + * serial data wire number 1-3 (SD3). + */ +#define AFE_PORT_I2S_SD0 0x1 +#define AFE_PORT_I2S_SD1 0x2 +#define AFE_PORT_I2S_SD2 0x3 +#define AFE_PORT_I2S_SD3 0x4 +#define AFE_PORT_I2S_QUAD01 0x5 +#define AFE_PORT_I2S_QUAD23 0x6 +#define AFE_PORT_I2S_6CHS 0x7 +#define AFE_PORT_I2S_8CHS 0x8 +#define AFE_PORT_I2S_MONO 0x0 +#define AFE_PORT_I2S_STEREO 0x1 +#define AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL 0x0 +#define AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL 0x1 + +/* Payload of the #AFE_PARAM_ID_I2S_CONFIG + * command's (I2S configuration + * parameter). + */ +struct afe_param_id_i2s_cfg { + u32 i2s_cfg_minor_version; +/* Minor version used for tracking the version of the I2S + * configuration interface. + * Supported values: #AFE_API_VERSION_I2S_CONFIG + */ + + u16 bit_width; +/* Bit width of the sample. + * Supported values: 16, 24 + */ + + u16 channel_mode; +/* I2S lines and multichannel operation. + * Supported values: + * - #AFE_PORT_I2S_SD0 + * - #AFE_PORT_I2S_SD1 + * - #AFE_PORT_I2S_SD2 + * - #AFE_PORT_I2S_SD3 + * - #AFE_PORT_I2S_QUAD01 + * - #AFE_PORT_I2S_QUAD23 + * - #AFE_PORT_I2S_6CHS + * - #AFE_PORT_I2S_8CHS + */ + + u16 mono_stereo; +/* Specifies mono or stereo. This applies only when + * a single I2S line is used. + * Supported values: + * - #AFE_PORT_I2S_MONO + * - #AFE_PORT_I2S_STEREO + */ + + u16 ws_src; +/* Word select source: internal or external. + * Supported values: + * - #AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL + * - #AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL + */ + + u32 sample_rate; +/* Sampling rate of the port. + * Supported values: + * - #AFE_PORT_SAMPLE_RATE_8K + * - #AFE_PORT_SAMPLE_RATE_16K + * - #AFE_PORT_SAMPLE_RATE_48K + * - #AFE_PORT_SAMPLE_RATE_96K + * - #AFE_PORT_SAMPLE_RATE_192K + */ + + u16 data_format; +/* data format + * Supported values: + * - #LINEAR_PCM_DATA + * - #NON_LINEAR_DATA + * - #LINEAR_PCM_DATA_PACKED_IN_60958 + * - #NON_LINEAR_DATA_PACKED_IN_60958 + */ + u16 reserved; + /* This field must be set to zero. */ +} __packed; + +/* + * This param id is used to configure PCM interface + */ + +#define AFE_API_VERSION_SPDIF_CONFIG 0x1 +#define AFE_API_VERSION_SPDIF_CH_STATUS_CONFIG 0x1 +#define AFE_API_VERSION_SPDIF_CLK_CONFIG 0x1 +#define AFE_CH_STATUS_A 1 +#define AFE_CH_STATUS_B 2 + +#define AFE_PARAM_ID_SPDIF_CONFIG 0x00010244 +#define AFE_PARAM_ID_CH_STATUS_CONFIG 0x00010245 +#define AFE_PARAM_ID_SPDIF_CLK_CONFIG 0x00010246 + +#define AFE_PORT_CLK_ROOT_LPAPLL 0x3 +#define AFE_PORT_CLK_ROOT_LPAQ6PLL 0x4 + +struct afe_param_id_spdif_cfg { +/* Minor version used for tracking the version of the SPDIF + * configuration interface. + * Supported values: #AFE_API_VERSION_SPDIF_CONFIG + */ + u32 spdif_cfg_minor_version; + +/* Sampling rate of the port. + * Supported values: + * - #AFE_PORT_SAMPLE_RATE_22_05K + * - #AFE_PORT_SAMPLE_RATE_32K + * - #AFE_PORT_SAMPLE_RATE_44_1K + * - #AFE_PORT_SAMPLE_RATE_48K + * - #AFE_PORT_SAMPLE_RATE_96K + * - #AFE_PORT_SAMPLE_RATE_176_4K + * - #AFE_PORT_SAMPLE_RATE_192K + */ + u32 sample_rate; + +/* data format + * Supported values: + * - #AFE_LINEAR_PCM_DATA + * - #AFE_NON_LINEAR_DATA + */ + u16 data_format; +/* Number of channels supported by the port + * - PCM - 1, Compressed Case - 2 + */ + u16 num_channels; +/* Bit width of the sample. + * Supported values: 16, 24 + */ + u16 bit_width; +/* This field must be set to zero. */ + u16 reserved; +} __packed; + +struct afe_param_id_spdif_ch_status_cfg { + u32 ch_status_cfg_minor_version; +/* Minor version used for tracking the version of channel + * status configuration. Current supported version is 1 + */ + + u32 status_type; +/* Indicate if the channel status is for channel A or B + * Supported values: + * - #AFE_CH_STATUS_A + * - #AFE_CH_STATUS_B + */ + + u8 status_bits[24]; +/* Channel status - 192 bits for channel + * Byte ordering as defined by IEC60958-3 + */ + + u8 status_mask[24]; +/* Channel status with mask bits 1 will be applied. + * Byte ordering as defined by IEC60958-3 + */ +} __packed; + +struct afe_param_id_spdif_clk_cfg { + u32 clk_cfg_minor_version; +/* Minor version used for tracking the version of SPDIF + * interface clock configuration. Current supported version + * is 1 + */ + + u32 clk_value; +/* Specifies the clock frequency in Hz to set + * Supported values: + * 0 - Disable the clock + * 2 (byphase) * 32 (60958 subframe size) * sampling rate * 2 + * (channels A and B) + */ + + u32 clk_root; +/* Specifies SPDIF root clk source + * Supported Values: + * - #AFE_PORT_CLK_ROOT_LPAPLL + * - #AFE_PORT_CLK_ROOT_LPAQ6PLL + */ +} __packed; + +struct afe_spdif_clk_config_command { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + struct afe_param_id_spdif_clk_cfg clk_cfg; +} __packed; + +struct afe_spdif_chstatus_config_command { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + struct afe_param_id_spdif_ch_status_cfg ch_status; +} __packed; + +struct afe_spdif_port_config { + struct afe_param_id_spdif_cfg cfg; + struct afe_param_id_spdif_ch_status_cfg ch_status; +} __packed; + +#define AFE_PARAM_ID_PCM_CONFIG 0x0001020E +#define AFE_API_VERSION_PCM_CONFIG 0x1 +/* Enumeration for the auxiliary PCM synchronization signal + * provided by an external source. + */ + +#define AFE_PORT_PCM_SYNC_SRC_EXTERNAL 0x0 +/* Enumeration for the auxiliary PCM synchronization signal + * provided by an internal source. + */ +#define AFE_PORT_PCM_SYNC_SRC_INTERNAL 0x1 +/* Enumeration for the PCM configuration aux_mode parameter, + * which configures the auxiliary PCM interface to use + * short synchronization. + */ +#define AFE_PORT_PCM_AUX_MODE_PCM 0x0 +/* + * Enumeration for the PCM configuration aux_mode parameter, + * which configures the auxiliary PCM interface to use long + * synchronization. + */ +#define AFE_PORT_PCM_AUX_MODE_AUX 0x1 +/* + * Enumeration for setting the PCM configuration frame to 8. + */ +#define AFE_PORT_PCM_BITS_PER_FRAME_8 0x0 +/* + * Enumeration for setting the PCM configuration frame to 16. + */ +#define AFE_PORT_PCM_BITS_PER_FRAME_16 0x1 + +/* Enumeration for setting the PCM configuration frame to 32.*/ +#define AFE_PORT_PCM_BITS_PER_FRAME_32 0x2 + +/* Enumeration for setting the PCM configuration frame to 64.*/ +#define AFE_PORT_PCM_BITS_PER_FRAME_64 0x3 + +/* Enumeration for setting the PCM configuration frame to 128.*/ +#define AFE_PORT_PCM_BITS_PER_FRAME_128 0x4 + +/* Enumeration for setting the PCM configuration frame to 256.*/ +#define AFE_PORT_PCM_BITS_PER_FRAME_256 0x5 + +/* Enumeration for setting the PCM configuration + * quantype parameter to A-law with no padding. + */ +#define AFE_PORT_PCM_ALAW_NOPADDING 0x0 + +/* Enumeration for setting the PCM configuration quantype + * parameter to mu-law with no padding. + */ +#define AFE_PORT_PCM_MULAW_NOPADDING 0x1 +/* Enumeration for setting the PCM configuration quantype + * parameter to linear with no padding. + */ +#define AFE_PORT_PCM_LINEAR_NOPADDING 0x2 +/* Enumeration for setting the PCM configuration quantype + * parameter to A-law with padding. + */ +#define AFE_PORT_PCM_ALAW_PADDING 0x3 +/* Enumeration for setting the PCM configuration quantype + * parameter to mu-law with padding. + */ +#define AFE_PORT_PCM_MULAW_PADDING 0x4 +/* Enumeration for setting the PCM configuration quantype + * parameter to linear with padding. + */ +#define AFE_PORT_PCM_LINEAR_PADDING 0x5 +/* Enumeration for disabling the PCM configuration + * ctrl_data_out_enable parameter. + * The PCM block is the only master. + */ +#define AFE_PORT_PCM_CTRL_DATA_OE_DISABLE 0x0 +/* + * Enumeration for enabling the PCM configuration + * ctrl_data_out_enable parameter. The PCM block shares + * the signal with other masters. + */ +#define AFE_PORT_PCM_CTRL_DATA_OE_ENABLE 0x1 + +/* Payload of the #AFE_PARAM_ID_PCM_CONFIG command's + * (PCM configuration parameter). + */ + +struct afe_param_id_pcm_cfg { + u32 pcm_cfg_minor_version; +/* Minor version used for tracking the version of the AUX PCM + * configuration interface. + * Supported values: #AFE_API_VERSION_PCM_CONFIG + */ + + u16 aux_mode; +/* PCM synchronization setting. + * Supported values: + * - #AFE_PORT_PCM_AUX_MODE_PCM + * - #AFE_PORT_PCM_AUX_MODE_AUX + */ + + u16 sync_src; +/* Synchronization source. + * Supported values: + * - #AFE_PORT_PCM_SYNC_SRC_EXTERNAL + * - #AFE_PORT_PCM_SYNC_SRC_INTERNAL + */ + + u16 frame_setting; +/* Number of bits per frame. + * Supported values: + * - #AFE_PORT_PCM_BITS_PER_FRAME_8 + * - #AFE_PORT_PCM_BITS_PER_FRAME_16 + * - #AFE_PORT_PCM_BITS_PER_FRAME_32 + * - #AFE_PORT_PCM_BITS_PER_FRAME_64 + * - #AFE_PORT_PCM_BITS_PER_FRAME_128 + * - #AFE_PORT_PCM_BITS_PER_FRAME_256 + */ + + u16 quantype; +/* PCM quantization type. + * Supported values: + * - #AFE_PORT_PCM_ALAW_NOPADDING + * - #AFE_PORT_PCM_MULAW_NOPADDING + * - #AFE_PORT_PCM_LINEAR_NOPADDING + * - #AFE_PORT_PCM_ALAW_PADDING + * - #AFE_PORT_PCM_MULAW_PADDING + * - #AFE_PORT_PCM_LINEAR_PADDING + */ + + u16 ctrl_data_out_enable; +/* Specifies whether the PCM block shares the data-out + * signal to the drive with other masters. + * Supported values: + * - #AFE_PORT_PCM_CTRL_DATA_OE_DISABLE + * - #AFE_PORT_PCM_CTRL_DATA_OE_ENABLE + */ + u16 reserved; + /* This field must be set to zero. */ + + u32 sample_rate; +/* Sampling rate of the port. + * Supported values: + * - #AFE_PORT_SAMPLE_RATE_8K + * - #AFE_PORT_SAMPLE_RATE_16K + */ + + u16 bit_width; +/* Bit width of the sample. + * Supported values: 16 + */ + + u16 num_channels; +/* Number of channels. + * Supported values: 1 to 4 + */ + + u16 slot_number_mapping[4]; +/* Specifies the slot number for the each channel in + * multi channel scenario. + * Supported values: 1 to 32 + */ +} __packed; + +/* + * This param id is used to configure DIGI MIC interface + */ +#define AFE_PARAM_ID_DIGI_MIC_CONFIG 0x0001020F +/* This version information is used to handle the new + * additions to the config interface in future in backward + * compatible manner. + */ +#define AFE_API_VERSION_DIGI_MIC_CONFIG 0x1 + +/* Enumeration for setting the digital mic configuration + * channel_mode parameter to left 0. + */ + +#define AFE_PORT_DIGI_MIC_MODE_LEFT0 0x1 + +/*Enumeration for setting the digital mic configuration + * channel_mode parameter to right 0. + */ + + +#define AFE_PORT_DIGI_MIC_MODE_RIGHT0 0x2 + +/* Enumeration for setting the digital mic configuration + * channel_mode parameter to left 1. + */ + +#define AFE_PORT_DIGI_MIC_MODE_LEFT1 0x3 + +/* Enumeration for setting the digital mic configuration + * channel_mode parameter to right 1. + */ + +#define AFE_PORT_DIGI_MIC_MODE_RIGHT1 0x4 + +/* Enumeration for setting the digital mic configuration + * channel_mode parameter to stereo 0. + */ +#define AFE_PORT_DIGI_MIC_MODE_STEREO0 0x5 + +/* Enumeration for setting the digital mic configuration + * channel_mode parameter to stereo 1. + */ + + +#define AFE_PORT_DIGI_MIC_MODE_STEREO1 0x6 + +/* Enumeration for setting the digital mic configuration + * channel_mode parameter to quad. + */ + +#define AFE_PORT_DIGI_MIC_MODE_QUAD 0x7 + +/* Payload of the #AFE_PARAM_ID_DIGI_MIC_CONFIG command's + * (DIGI MIC configuration + * parameter). + */ +struct afe_param_id_digi_mic_cfg { + u32 digi_mic_cfg_minor_version; +/* Minor version used for tracking the version of the DIGI Mic + * configuration interface. + * Supported values: #AFE_API_VERSION_DIGI_MIC_CONFIG + */ + + u16 bit_width; +/* Bit width of the sample. + * Supported values: 16 + */ + + u16 channel_mode; +/* Digital mic and multichannel operation. + * Supported values: + * - #AFE_PORT_DIGI_MIC_MODE_LEFT0 + * - #AFE_PORT_DIGI_MIC_MODE_RIGHT0 + * - #AFE_PORT_DIGI_MIC_MODE_LEFT1 + * - #AFE_PORT_DIGI_MIC_MODE_RIGHT1 + * - #AFE_PORT_DIGI_MIC_MODE_STEREO0 + * - #AFE_PORT_DIGI_MIC_MODE_STEREO1 + * - #AFE_PORT_DIGI_MIC_MODE_QUAD + */ + + u32 sample_rate; +/* Sampling rate of the port. + * Supported values: + * - #AFE_PORT_SAMPLE_RATE_8K + * - #AFE_PORT_SAMPLE_RATE_16K + * - #AFE_PORT_SAMPLE_RATE_48K + */ +} __packed; + +/* This param id is used to configure HDMI interface */ +#define AFE_PARAM_ID_HDMI_CONFIG 0x00010210 + +/* This version information is used to handle the new + * additions to the config interface in future in backward + * compatible manner. + */ +#define AFE_API_VERSION_HDMI_CONFIG 0x1 + +/* Payload of the #AFE_PARAM_ID_HDMI_CONFIG command, + * which configures a multichannel HDMI audio interface. + */ +struct afe_param_id_hdmi_multi_chan_audio_cfg { + u32 hdmi_cfg_minor_version; +/* Minor version used for tracking the version of the HDMI + * configuration interface. + * Supported values: #AFE_API_VERSION_HDMI_CONFIG + */ + +u16 datatype; +/* data type + * Supported values: + * - #LINEAR_PCM_DATA + * - #NON_LINEAR_DATA + * - #LINEAR_PCM_DATA_PACKED_IN_60958 + * - #NON_LINEAR_DATA_PACKED_IN_60958 + */ + +u16 channel_allocation; +/* HDMI channel allocation information for programming an HDMI + * frame. The default is 0 (Stereo). + * + * This information is defined in the HDMI standard, CEA 861-D + * (refer to @xhyperref{S1,[S1]}). The number of channels is also + * inferred from this parameter. + */ + + +u32 sample_rate; +/* Sampling rate of the port. + * Supported values: + * - #AFE_PORT_SAMPLE_RATE_8K + * - #AFE_PORT_SAMPLE_RATE_16K + * - #AFE_PORT_SAMPLE_RATE_48K + * - #AFE_PORT_SAMPLE_RATE_96K + * - 22050, 44100, 176400 for compressed streams + */ + + u16 bit_width; +/* Bit width of the sample. + * Supported values: 16, 24 + */ + u16 reserved; + /* This field must be set to zero. */ +} __packed; + +/* This param id is used to configure BT or FM(RIVA) interface */ +#define AFE_PARAM_ID_INTERNAL_BT_FM_CONFIG 0x00010211 + +/* This version information is used to handle the new + * additions to the config interface in future in backward + * compatible manner. + */ +#define AFE_API_VERSION_INTERNAL_BT_FM_CONFIG 0x1 + +/* Payload of the #AFE_PARAM_ID_INTERNAL_BT_FM_CONFIG + * command's BT voice/BT audio/FM configuration parameter. + */ +struct afe_param_id_internal_bt_fm_cfg { + u32 bt_fm_cfg_minor_version; +/* Minor version used for tracking the version of the BT and FM + * configuration interface. + * Supported values: #AFE_API_VERSION_INTERNAL_BT_FM_CONFIG + */ + + u16 num_channels; +/* Number of channels. + * Supported values: 1 to 2 + */ + + u16 bit_width; +/* Bit width of the sample. + * Supported values: 16 + */ + + u32 sample_rate; +/* Sampling rate of the port. + * Supported values: + * - #AFE_PORT_SAMPLE_RATE_8K (only for BTSCO) + * - #AFE_PORT_SAMPLE_RATE_16K (only for BTSCO) + * - #AFE_PORT_SAMPLE_RATE_48K (FM and A2DP) + */ +} __packed; + +/* This param id is used to configure SLIMBUS interface using + * shared channel approach. + */ + + +#define AFE_PARAM_ID_SLIMBUS_CONFIG 0x00010212 + +/* This version information is used to handle the new + * additions to the config interface in future in backward + * compatible manner. + */ +#define AFE_API_VERSION_SLIMBUS_CONFIG 0x1 + +/* Enumeration for setting SLIMbus device ID 1. */ +#define AFE_SLIMBUS_DEVICE_1 0x0 + +/* Enumeration for setting SLIMbus device ID 2. */ +#define AFE_SLIMBUS_DEVICE_2 0x1 + +/* Enumeration for setting the SLIMbus data formats. */ +#define AFE_SB_DATA_FORMAT_NOT_INDICATED 0x0 + +/* Enumeration for setting the maximum number of streams per + * device. + */ + +#define AFE_PORT_MAX_AUDIO_CHAN_CNT 0x8 + +/* Payload of the #AFE_PORT_CMD_SLIMBUS_CONFIG command's SLIMbus + * port configuration parameter. + */ + +struct afe_param_id_slimbus_cfg { + u32 sb_cfg_minor_version; +/* Minor version used for tracking the version of the SLIMBUS + * configuration interface. + * Supported values: #AFE_API_VERSION_SLIMBUS_CONFIG + */ + + u16 slimbus_dev_id; +/* SLIMbus hardware device ID, which is required to handle + * multiple SLIMbus hardware blocks. + * Supported values: - #AFE_SLIMBUS_DEVICE_1 - #AFE_SLIMBUS_DEVICE_2 + */ + + + u16 bit_width; +/* Bit width of the sample. + * Supported values: 16, 24 + */ + + u16 data_format; +/* Data format supported by the SLIMbus hardware. The default is + * 0 (#AFE_SB_DATA_FORMAT_NOT_INDICATED), which indicates the + * hardware does not perform any format conversions before the data + * transfer. + */ + + + u16 num_channels; +/* Number of channels. + * Supported values: 1 to #AFE_PORT_MAX_AUDIO_CHAN_CNT + */ + + u8 shared_ch_mapping[AFE_PORT_MAX_AUDIO_CHAN_CNT]; +/* Mapping of shared channel IDs (128 to 255) to which the + * master port is to be connected. + * Shared_channel_mapping[i] represents the shared channel assigned + * for audio channel i in multichannel audio data. + */ + + u32 sample_rate; +/* Sampling rate of the port. + * Supported values: + * - #AFE_PORT_SAMPLE_RATE_8K + * - #AFE_PORT_SAMPLE_RATE_16K + * - #AFE_PORT_SAMPLE_RATE_48K + * - #AFE_PORT_SAMPLE_RATE_96K + * - #AFE_PORT_SAMPLE_RATE_192K + */ +} __packed; + + +/* ID of the parameter used by AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS to configure + * USB audio device parameter. It should be used with + * AFE_MODULE_AUDIO_DEV_INTERFACE + */ +#define AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS 0x000102A5 + + +/* ID of the parameter used to set the endianness value for the + * USB audio device. It should be used with + * AFE_MODULE_AUDIO_DEV_INTERFACE + */ +#define AFE_PARAM_ID_USB_AUDIO_DEV_LPCM_FMT 0x000102AA + +/* Minor version used for tracking USB audio configuration */ +#define AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG 0x1 + +/* Payload of the AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS parameter used by + * AFE_MODULE_AUDIO_DEV_INTERFACE. + */ +struct afe_param_id_usb_audio_dev_params { +/* Minor version used for tracking USB audio device parameter. + * Supported values: AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG + */ + u32 cfg_minor_version; +/* Token of actual end USB aduio device */ + u32 dev_token; +} __packed; + +struct afe_param_id_usb_audio_dev_lpcm_fmt { +/* Minor version used for tracking USB audio device parameter. + * Supported values: AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG + */ + u32 cfg_minor_version; +/* Endianness of actual end USB audio device */ + u32 endian; +} __packed; + +/* ID of the parameter used by AFE_PARAM_ID_USB_AUDIO_CONFIG to configure + * USB audio interface. It should be used with AFE_MODULE_AUDIO_DEV_INTERFACE + */ +#define AFE_PARAM_ID_USB_AUDIO_CONFIG 0x000102A4 + +/* Payload of the AFE_PARAM_ID_USB_AUDIO_CONFIG parameter used by + * AFE_MODULE_AUDIO_DEV_INTERFACE. + */ +struct afe_param_id_usb_audio_cfg { +/* Minor version used for tracking USB audio device configuration. + * Supported values: AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG + */ + u32 cfg_minor_version; +/* Sampling rate of the port. + * Supported values: + * - AFE_PORT_SAMPLE_RATE_8K + * - AFE_PORT_SAMPLE_RATE_11025 + * - AFE_PORT_SAMPLE_RATE_12K + * - AFE_PORT_SAMPLE_RATE_16K + * - AFE_PORT_SAMPLE_RATE_22050 + * - AFE_PORT_SAMPLE_RATE_24K + * - AFE_PORT_SAMPLE_RATE_32K + * - AFE_PORT_SAMPLE_RATE_44P1K + * - AFE_PORT_SAMPLE_RATE_48K + * - AFE_PORT_SAMPLE_RATE_96K + * - AFE_PORT_SAMPLE_RATE_192K + */ + u32 sample_rate; +/* Bit width of the sample. + * Supported values: 16, 24 + */ + u16 bit_width; +/* Number of channels. + * Supported values: 1 and 2 + */ + u16 num_channels; +/* Data format supported by the USB. The supported value is + * 0 (#AFE_USB_AUDIO_DATA_FORMAT_LINEAR_PCM). + */ + u16 data_format; +/* this field must be 0 */ + u16 reserved; +/* device token of actual end USB aduio device */ + u32 dev_token; +/* endianness of this interface */ + u32 endian; +} __packed; + +struct afe_usb_audio_dev_param_command { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + union { + struct afe_param_id_usb_audio_dev_params usb_dev; + struct afe_param_id_usb_audio_dev_lpcm_fmt lpcm_fmt; + }; +} __packed; + +/* This param id is used to configure Real Time Proxy interface. */ +#define AFE_PARAM_ID_RT_PROXY_CONFIG 0x00010213 + +/* This version information is used to handle the new + * additions to the config interface in future in backward + * compatible manner. + */ +#define AFE_API_VERSION_RT_PROXY_CONFIG 0x1 + +/* Payload of the #AFE_PARAM_ID_RT_PROXY_CONFIG + * command (real-time proxy port configuration parameter). + */ +struct afe_param_id_rt_proxy_port_cfg { + u32 rt_proxy_cfg_minor_version; +/* Minor version used for tracking the version of rt-proxy + * config interface. + */ + + u16 bit_width; +/* Bit width of the sample. + * Supported values: 16 + */ + + u16 interleaved; +/* Specifies whether the data exchanged between the AFE + * interface and real-time port is interleaved. + * Supported values: - 0 -- Non-interleaved (samples from each + * channel are contiguous in the buffer) - 1 -- Interleaved + * (corresponding samples from each input channel are interleaved + * within the buffer) + */ + + + u16 frame_size; +/* Size of the frames that are used for PCM exchanges with this + * port. + * Supported values: > 0, in bytes + * For example, 5 ms buffers of 16 bits and 16 kHz stereo samples + * is 5 ms * 16 samples/ms * 2 bytes/sample * 2 channels = 320 + * bytes. + */ + u16 jitter_allowance; +/* Configures the amount of jitter that the port will allow. + * Supported values: > 0 + * For example, if +/-10 ms of jitter is anticipated in the timing + * of sending frames to the port, and the configuration is 16 kHz + * mono with 16-bit samples, this field is 10 ms * 16 samples/ms * 2 + * bytes/sample = 320. + */ + + u16 low_water_mark; +/* Low watermark in bytes (including all channels). + * Supported values: + * - 0 -- Do not send any low watermark events + * - > 0 -- Low watermark for triggering an event + * If the number of bytes in an internal circular buffer is lower + * than this low_water_mark parameter, a LOW_WATER_MARK event is + * sent to applications (via the #AFE_EVENT_RT_PROXY_PORT_STATUS + * event). + * Use of watermark events is optional for debugging purposes. + */ + + u16 high_water_mark; +/* High watermark in bytes (including all channels). + * Supported values: + * - 0 -- Do not send any high watermark events + * - > 0 -- High watermark for triggering an event + * If the number of bytes in an internal circular buffer exceeds + * TOTAL_CIRC_BUF_SIZE minus high_water_mark, a high watermark event + * is sent to applications (via the #AFE_EVENT_RT_PROXY_PORT_STATUS + * event). + * The use of watermark events is optional and for debugging + * purposes. + */ + + + u32 sample_rate; +/* Sampling rate of the port. + * Supported values: + * - #AFE_PORT_SAMPLE_RATE_8K + * - #AFE_PORT_SAMPLE_RATE_16K + * - #AFE_PORT_SAMPLE_RATE_48K + */ + + u16 num_channels; +/* Number of channels. + * Supported values: 1 to #AFE_PORT_MAX_AUDIO_CHAN_CNT + */ + + u16 reserved; + /* For 32 bit alignment. */ +} __packed; + + +/* This param id is used to configure the Pseudoport interface */ + +#define AFE_PARAM_ID_PSEUDO_PORT_CONFIG 0x00010219 + +/* Version information used to handle future additions to the configuration + * interface (for backward compatibility). + */ +#define AFE_API_VERSION_PSEUDO_PORT_CONFIG 0x1 + +/* Enumeration for setting the timing_mode parameter to faster than real + * time. + */ +#define AFE_PSEUDOPORT_TIMING_MODE_FTRT 0x0 + +/* Enumeration for setting the timing_mode parameter to real time using + * timers. + */ +#define AFE_PSEUDOPORT_TIMING_MODE_TIMER 0x1 + +/* Payload of the AFE_PARAM_ID_PSEUDO_PORT_CONFIG parameter used by + * AFE_MODULE_AUDIO_DEV_INTERFACE. + */ +struct afe_param_id_pseudo_port_cfg { + u32 pseud_port_cfg_minor_version; + /* + * Minor version used for tracking the version of the pseudoport + * configuration interface. + */ + + u16 bit_width; + /* Bit width of the sample at values 16, 24 */ + + u16 num_channels; + /* Number of channels at values 1 to 8 */ + + u16 data_format; + /* Non-linear data format supported by the pseudoport (for future use). + * At values #AFE_LINEAR_PCM_DATA + */ + + u16 timing_mode; + /* Indicates whether the pseudoport synchronizes to the clock or + * operates faster than real time. + * at values + * - #AFE_PSEUDOPORT_TIMING_MODE_FTRT + * - #AFE_PSEUDOPORT_TIMING_MODE_TIMER @tablebulletend + */ + + u32 sample_rate; + /* Sample rate at which the pseudoport will run. + * at values + * - #AFE_PORT_SAMPLE_RATE_8K + * - #AFE_PORT_SAMPLE_RATE_32K + * - #AFE_PORT_SAMPLE_RATE_48K + * - #AFE_PORT_SAMPLE_RATE_96K + * - #AFE_PORT_SAMPLE_RATE_192K @tablebulletend + */ +} __packed; + +#define AFE_PARAM_ID_TDM_CONFIG 0x0001029D + +#define AFE_API_VERSION_TDM_CONFIG 1 + +#define AFE_PORT_TDM_SHORT_SYNC_BIT_MODE 0 +#define AFE_PORT_TDM_LONG_SYNC_MODE 1 +#define AFE_PORT_TDM_SHORT_SYNC_SLOT_MODE 2 + +#define AFE_PORT_TDM_SYNC_SRC_EXTERNAL 0 +#define AFE_PORT_TDM_SYNC_SRC_INTERNAL 1 + +#define AFE_PORT_TDM_CTRL_DATA_OE_DISABLE 0 +#define AFE_PORT_TDM_CTRL_DATA_OE_ENABLE 1 + +#define AFE_PORT_TDM_SYNC_NORMAL 0 +#define AFE_PORT_TDM_SYNC_INVERT 1 + +#define AFE_PORT_TDM_DATA_DELAY_0_BCLK_CYCLE 0 +#define AFE_PORT_TDM_DATA_DELAY_1_BCLK_CYCLE 1 +#define AFE_PORT_TDM_DATA_DELAY_2_BCLK_CYCLE 2 + +/* Payload of the AFE_PARAM_ID_TDM_CONFIG parameter used by + * AFE_MODULE_AUDIO_DEV_INTERFACE. + */ +struct afe_param_id_tdm_cfg { + u32 tdm_cfg_minor_version; + /* < Minor version used to track TDM configuration. + * @values #AFE_API_VERSION_TDM_CONFIG + */ + + u32 num_channels; + /* < Number of enabled slots for TDM frame. + * @values 1 to 8 + */ + + u32 sample_rate; + /* < Sampling rate of the port. + * @values + * - #AFE_PORT_SAMPLE_RATE_8K + * - #AFE_PORT_SAMPLE_RATE_16K + * - #AFE_PORT_SAMPLE_RATE_24K + * - #AFE_PORT_SAMPLE_RATE_32K + * - #AFE_PORT_SAMPLE_RATE_48K + * - #AFE_PORT_SAMPLE_RATE_176P4K + * - #AFE_PORT_SAMPLE_RATE_352P8K @tablebulletend + */ + + u32 bit_width; + /* < Bit width of the sample. + * @values 16, 24 + */ + + u16 data_format; + /* < Data format: linear ,compressed, generic compresssed + * @values + * - #AFE_LINEAR_PCM_DATA + * - #AFE_NON_LINEAR_DATA + * - #AFE_GENERIC_COMPRESSED + */ + + u16 sync_mode; + /* < TDM synchronization setting. + * @values (short, long, slot) sync mode + * - #AFE_PORT_TDM_SHORT_SYNC_BIT_MODE + * - #AFE_PORT_TDM_LONG_SYNC_MODE + * - #AFE_PORT_TDM_SHORT_SYNC_SLOT_MODE @tablebulletend + */ + + u16 sync_src; + /* < Synchronization source. + * @values + * - #AFE_PORT_TDM_SYNC_SRC_EXTERNAL + * - #AFE_PORT_TDM_SYNC_SRC_INTERNAL @tablebulletend + */ + + u16 nslots_per_frame; + /* < Number of slots per frame. Typical : 1, 2, 4, 8, 16, 32. + * @values 1 - 32 + */ + + u16 ctrl_data_out_enable; + /* < Specifies whether the TDM block shares the data-out signal to the + * drive with other masters. + * @values + * - #AFE_PORT_TDM_CTRL_DATA_OE_DISABLE + * - #AFE_PORT_TDM_CTRL_DATA_OE_ENABLE @tablebulletend + */ + + u16 ctrl_invert_sync_pulse; + /* < Specifies whether to invert the sync or not. + * @values + * - #AFE_PORT_TDM_SYNC_NORMAL + * - #AFE_PORT_TDM_SYNC_INVERT @tablebulletend + */ + + u16 ctrl_sync_data_delay; + /* < Specifies the number of bit clock to delay data with respect to + * sync edge. + * @values + * - #AFE_PORT_TDM_DATA_DELAY_0_BCLK_CYCLE + * - #AFE_PORT_TDM_DATA_DELAY_1_BCLK_CYCLE + * - #AFE_PORT_TDM_DATA_DELAY_2_BCLK_CYCLE @tablebulletend + */ + + u16 slot_width; + /* < Slot width of the slot in a TDM frame. (slot_width >= bit_width) + * have to be satisfied. + * @values 16, 24, 32 + */ + + u32 slot_mask; + /* < Position of active slots. When that bit is set, + * that paricular slot is active. + * Number of active slots can be inferred by number of + * bits set in the mask. Only 8 individual bits can be enabled. + * Bits 0..31 corresponding to slot 0..31 + * @values 1 to 2^32 - 1 + */ +} __packed; + +/* ID of Time Divsion Multiplexing (TDM) module, + * which is used for configuring the AFE TDM. + * + * This module supports following parameter IDs: + * - #AFE_PORT_TDM_SLOT_CONFIG + * + * To configure the TDM interface, the client must use the + * #AFE_PORT_CMD_SET_PARAM command, and fill the module ID with the + * respective parameter IDs as listed above. + */ + +#define AFE_MODULE_TDM 0x0001028A + +/* ID of the parameter used by #AFE_MODULE_TDM to configure + * the TDM slot mapping. #AFE_PORT_CMD_SET_PARAM can use this parameter ID. + */ +#define AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG 0x00010297 + +/* Version information used to handle future additions to slot mapping + * configuration (for backward compatibility). + */ +#define AFE_API_VERSION_SLOT_MAPPING_CONFIG 0x1 + +/* Data align type */ +#define AFE_SLOT_MAPPING_DATA_ALIGN_MSB 0 +#define AFE_SLOT_MAPPING_DATA_ALIGN_LSB 1 + +#define AFE_SLOT_MAPPING_OFFSET_INVALID 0xFFFF + +/* Payload of the AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG + * command's TDM configuration parameter. + */ +struct afe_param_id_slot_mapping_cfg { + u32 minor_version; + /* < Minor version used for tracking TDM slot configuration. + * @values #AFE_API_VERSION_TDM_SLOT_CONFIG + */ + + u16 num_channel; + /* < number of channel of the audio sample. + * @values 1, 2, 4, 6, 8 @tablebulletend + */ + + u16 bitwidth; + /* < Slot bit width for each channel + * @values 16, 24, 32 + */ + + u32 data_align_type; + /* < indicate how data packed from slot_offset for 32 slot bit width + * in case of sample bit width is 24. + * @values + * #AFE_SLOT_MAPPING_DATA_ALIGN_MSB + * #AFE_SLOT_MAPPING_DATA_ALIGN_LSB + */ + + u16 offset[AFE_PORT_MAX_AUDIO_CHAN_CNT]; + /* < Array of the slot mapping start offset in bytes for this frame. + * The bytes is counted from 0. The 0 is mapped to the 1st byte + * in or out of the digital serial data line this sub-frame belong to. + * slot_offset[] setting is per-channel based. + * The max num of channel supported is 8. + * The valid offset value must always be continuly placed in from + * index 0. + * Set offset as AFE_SLOT_MAPPING_OFFSET_INVALID for not used arrays. + * If "slot_bitwidth_per_channel" is 32 and "sample_bitwidth" is 24, + * "data_align_type" is used to indicate how 24 bit sample data in + * aligning with 32 bit slot width per-channel. + * @values, in byte + */ +} __packed; + +/* ID of the parameter used by #AFE_MODULE_TDM to configure + * the customer TDM header. #AFE_PORT_CMD_SET_PARAM can use this parameter ID. + */ +#define AFE_PARAM_ID_CUSTOM_TDM_HEADER_CONFIG 0x00010298 + +/* Version information used to handle future additions to custom TDM header + * configuration (for backward compatibility). + */ +#define AFE_API_VERSION_CUSTOM_TDM_HEADER_CONFIG 0x1 + +#define AFE_CUSTOM_TDM_HEADER_TYPE_INVALID 0x0 +#define AFE_CUSTOM_TDM_HEADER_TYPE_DEFAULT 0x1 +#define AFE_CUSTOM_TDM_HEADER_TYPE_ENTERTAINMENT_MOST 0x2 + +#define AFE_CUSTOM_TDM_HEADER_MAX_CNT 0x8 + +/* Payload of the AFE_PARAM_ID_CUSTOM_TDM_HEADER_CONFIG parameter ID */ +struct afe_param_id_custom_tdm_header_cfg { + u32 minor_version; + /* < Minor version used for tracking custom TDM header configuration. + * @values #AFE_API_VERSION_CUSTOM_TDM_HEADER_CONFIG + */ + + u16 start_offset; + /* < the slot mapping start offset in bytes from this sub-frame + * The bytes is counted from 0. The 0 is mapped to the 1st byte in or + * out of the digital serial data line this sub-frame belong to. + * @values, in byte, + * supported values are 0, 4, 8 + */ + + u16 header_width; + /* < the header width per-frame followed. + * 2 bytes for MOST/TDM case + * @values, in byte + * supported value is 2 + */ + + u16 header_type; + /* < Indicate what kind of custom TDM header it is. + * @values #AFE_CUSTOM_TDM_HEADER_TYPE_INVALID = 0 + * #AFE_CUSTOM_TDM_HEADER_TYPE_DEFAULT = 1 (for AAN channel per MOST) + * #AFE_CUSTOM_TDM_HEADER_TYPE_ENTERTAINMENT_MOST = 2 + * (for entertainment channel, which will overwrite + * AFE_API_VERSION_TDM_SAD_HEADER_TYPE_DEFAULT per MOST) + */ + + u16 num_frame_repeat; + /* < num of header followed. + * @values, supported value is 8 + */ + u16 header[AFE_CUSTOM_TDM_HEADER_MAX_CNT]; + /* < SAD header for MOST/TDM case is followed as payload as below. + * The size of followed SAD header in bytes is num_of_frame_repeat * + * header_width_per_frame, which is 2 * 8 = 16 bytes here. + * the supported payload format is in uint16_t as below + * uint16_t header0; SyncHi 0x3C Info[4] - CodecType -> 0x3C00 + * uint16_t header1; SyncLo 0xB2 Info[5] - SampleWidth -> 0xB218 + * uint16_t header2; DTCP Info Info[6] - unused -> 0x0 + * uint16_t header3; Extension Info[7] - ASAD-Value -> 0xC0 + * uint16_t header4; Reserved Info[0] - Num of bytes following -> 0x7 + * uint16_t header5; Reserved Info[1] - Media Type -> 0x0 + * uint16_t header6; Reserved Info[2] - Bitrate[kbps] - High Byte -> 0x0 + * uint16_t header7; Reserved Info[3] - Bitrate[kbps] - Low Byte -> 0x0 + */ +} __packed; + +struct afe_slot_mapping_config_command { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + struct afe_param_id_slot_mapping_cfg slot_mapping; +} __packed; + +struct afe_custom_tdm_header_config_command { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + struct afe_param_id_custom_tdm_header_cfg custom_tdm_header; +} __packed; + +struct afe_tdm_port_config { + struct afe_param_id_tdm_cfg tdm; + struct afe_param_id_slot_mapping_cfg slot_mapping; + struct afe_param_id_custom_tdm_header_cfg custom_tdm_header; +} __packed; + +#define AFE_PARAM_ID_DEVICE_HW_DELAY 0x00010243 +#define AFE_API_VERSION_DEVICE_HW_DELAY 0x1 + +struct afe_param_id_device_hw_delay_cfg { + uint32_t device_hw_delay_minor_version; + uint32_t delay_in_us; +} __packed; + +#define AFE_PARAM_ID_SET_TOPOLOGY 0x0001025A +#define AFE_API_VERSION_TOPOLOGY_V1 0x1 + +struct afe_param_id_set_topology_cfg { + /* + * Minor version used for tracking afe topology id configuration. + * @values #AFE_API_VERSION_TOPOLOGY_V1 + */ + u32 minor_version; + /* + * Id of the topology for the afe session. + * @values Any valid AFE topology ID + */ + u32 topology_id; +} __packed; + + +/* + * Generic encoder module ID. + * This module supports the following parameter IDs: + * #AVS_ENCODER_PARAM_ID_ENC_FMT_ID (cannot be set run time) + * #AVS_ENCODER_PARAM_ID_ENC_CFG_BLK (may be set run time) + * #AVS_ENCODER_PARAM_ID_ENC_BITRATE (may be set run time) + * #AVS_ENCODER_PARAM_ID_PACKETIZER_ID (cannot be set run time) + * Opcode - AVS_MODULE_ID_ENCODER + * AFE Command AFE_PORT_CMD_SET_PARAM_V2 supports this module ID. + */ +#define AFE_MODULE_ID_ENCODER 0x00013229 + +/* Macro for defining the packetizer ID: COP. */ +#define AFE_MODULE_ID_PACKETIZER_COP 0x0001322A + +/* + * Packetizer type parameter for the #AVS_MODULE_ID_ENCODER module. + * This parameter cannot be set runtime. + */ +#define AFE_ENCODER_PARAM_ID_PACKETIZER_ID 0x0001322E + +/* + * Encoder config block parameter for the #AVS_MODULE_ID_ENCODER module. + * This parameter may be set runtime. + */ +#define AFE_ENCODER_PARAM_ID_ENC_CFG_BLK 0x0001322C + +/* + * Encoder format ID parameter for the #AVS_MODULE_ID_ENCODER module. + * This parameter cannot be set runtime. + */ +#define AFE_ENCODER_PARAM_ID_ENC_FMT_ID 0x0001322B + +/* + * Data format to send compressed data + * is transmitted/received over Slimbus lines. + */ +#define AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED 0x3 + +/* + * ID for AFE port module. This will be used to define port properties. + * This module supports following parameter IDs: + * #AFE_PARAM_ID_PORT_MEDIA_TYPE + * To configure the port property, the client must use the + * #AFE_PORT_CMD_SET_PARAM_V2 command, + * and fill the module ID with the respective parameter IDs as listed above. + * @apr_hdr_fields + * Opcode -- AFE_MODULE_PORT + */ +#define AFE_MODULE_PORT 0x000102a6 + +/* + * ID of the parameter used by #AFE_MODULE_PORT to set the port media type. + * parameter ID is currently supported using#AFE_PORT_CMD_SET_PARAM_V2 command. + */ +#define AFE_PARAM_ID_PORT_MEDIA_TYPE 0x000102a7 + +/* + * Macros for defining the "data_format" field in the + * #AFE_PARAM_ID_PORT_MEDIA_TYPE + */ +#define AFE_PORT_DATA_FORMAT_PCM 0x0 +#define AFE_PORT_DATA_FORMAT_GENERIC_COMPRESSED 0x1 + +/* + * Macro for defining the "minor_version" field in the + * #AFE_PARAM_ID_PORT_MEDIA_TYPE + */ +#define AFE_API_VERSION_PORT_MEDIA_TYPE 0x1 + +#define ASM_MEDIA_FMT_NONE 0x0 + +/* + * Media format ID for SBC encode configuration. + * @par SBC encode configuration (asm_sbc_enc_cfg_t) + * @table{weak__asm__sbc__enc__cfg__t} + */ +#define ASM_MEDIA_FMT_SBC 0x00010BF2 + +/* SBC channel Mono mode.*/ +#define ASM_MEDIA_FMT_SBC_CHANNEL_MODE_MONO 1 + +/* SBC channel Stereo mode. */ +#define ASM_MEDIA_FMT_SBC_CHANNEL_MODE_STEREO 2 + +/* SBC channel Dual Mono mode. */ +#define ASM_MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO 8 + +/* SBC channel Joint Stereo mode. */ +#define ASM_MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO 9 + +/* SBC bit allocation method = loudness. */ +#define ASM_MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS 0 + +/* SBC bit allocation method = SNR. */ +#define ASM_MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR 1 + + +/* + * Payload of the SBC encoder configuration parameters in the + * #ASM_MEDIA_FMT_SBC media format. + */ +struct asm_sbc_enc_cfg_t { + /* + * Number of subbands. + * @values 4, 8 + */ + uint32_t num_subbands; + + /* + * Size of the encoded block in samples. + * @values 4, 8, 12, 16 + */ + uint32_t blk_len; + + /* + * Mode used to allocate bits between channels. + * @values + * 0 (Native mode) + * #ASM_MEDIA_FMT_SBC_CHANNEL_MODE_MONO + * #ASM_MEDIA_FMT_SBC_CHANNEL_MODE_STEREO + * #ASM_MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO + * #ASM_MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO + * Native mode indicates that encoding must be performed with the number + * of channels at the input. + * If postprocessing outputs one-channel data, Mono mode is used. If + * postprocessing outputs two-channel data, Stereo mode is used. + * The number of channels must not change during encoding. + */ + uint32_t channel_mode; + + /* + * Encoder bit allocation method. + * @values + * #ASM_MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS + * #ASM_MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR @tablebulletend + */ + uint32_t alloc_method; + + /* + * Number of encoded bits per second. + * @values + * Mono channel -- Maximum of 320 kbps + * Stereo channel -- Maximum of 512 kbps @tablebulletend + */ + uint32_t bit_rate; + + /* + * Number of samples per second. + * @values 0 (Native mode), 16000, 32000, 44100, 48000 Hz + * Native mode indicates that encoding must be performed with the + * sampling rate at the input. + * The sampling rate must not change during encoding. + */ + uint32_t sample_rate; +}; + +#define ASM_MEDIA_FMT_AAC_AOT_LC 2 +#define ASM_MEDIA_FMT_AAC_AOT_SBR 5 +#define ASM_MEDIA_FMT_AAC_AOT_PS 29 +#define ASM_MEDIA_FMT_AAC_FORMAT_FLAG_ADTS 0 +#define ASM_MEDIA_FMT_AAC_FORMAT_FLAG_RAW 3 + +struct asm_aac_enc_cfg_v2_t { + + /* Encoding rate in bits per second.*/ + uint32_t bit_rate; + + /* + * Encoding mode. + * Supported values: + * #ASM_MEDIA_FMT_AAC_AOT_LC + * #ASM_MEDIA_FMT_AAC_AOT_SBR + * #ASM_MEDIA_FMT_AAC_AOT_PS + */ + uint32_t enc_mode; + + /* + * AAC format flag. + * Supported values: + * #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_ADTS + * #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_RAW + */ + uint16_t aac_fmt_flag; + + /* + * Number of channels to encode. + * Supported values: + * 0 - Native mode + * 1 - Mono + * 2 - Stereo + * Other values are not supported. + * @note1hang The eAAC+ encoder mode supports only stereo. + * Native mode indicates that encoding must be performed with the + * number of channels at the input. + * The number of channels must not change during encoding. + */ + uint16_t channel_cfg; + + /* + * Number of samples per second. + * Supported values: - 0 -- Native mode - For other values, + * Native mode indicates that encoding must be performed with the + * sampling rate at the input. + * The sampling rate must not change during encoding. + */ + uint32_t sample_rate; +} __packed; + +/* FMT ID for apt-X Classic */ +#define ASM_MEDIA_FMT_APTX 0x000131ff + +/* FMT ID for apt-X HD */ +#define ASM_MEDIA_FMT_APTX_HD 0x00013200 + +#define PCM_CHANNEL_L 1 +#define PCM_CHANNEL_R 2 +#define PCM_CHANNEL_C 3 + +struct asm_custom_enc_cfg_aptx_t { + uint32_t sample_rate; + /* Mono or stereo */ + uint16_t num_channels; + uint16_t reserved; + /* num_ch == 1, then PCM_CHANNEL_C, + * num_ch == 2, then {PCM_CHANNEL_L, PCM_CHANNEL_R} + */ + uint8_t channel_mapping[8]; + uint32_t custom_size; +} __packed; + +struct afe_enc_fmt_id_param_t { + /* + * Supported values: + * #ASM_MEDIA_FMT_SBC + * #ASM_MEDIA_FMT_AAC_V2 + * Any OpenDSP supported values + */ + uint32_t fmt_id; +} __packed; + +struct afe_port_media_type_t { + /* + * Minor version + * @values #AFE_API_VERSION_PORT_MEDIA_TYPE. + */ + uint32_t minor_version; + + /* + * Sampling rate of the port. + * @values + * #AFE_PORT_SAMPLE_RATE_8K + * #AFE_PORT_SAMPLE_RATE_11_025K + * #AFE_PORT_SAMPLE_RATE_12K + * #AFE_PORT_SAMPLE_RATE_16K + * #AFE_PORT_SAMPLE_RATE_22_05K + * #AFE_PORT_SAMPLE_RATE_24K + * #AFE_PORT_SAMPLE_RATE_32K + * #AFE_PORT_SAMPLE_RATE_44_1K + * #AFE_PORT_SAMPLE_RATE_48K + * #AFE_PORT_SAMPLE_RATE_88_2K + * #AFE_PORT_SAMPLE_RATE_96K + * #AFE_PORT_SAMPLE_RATE_176_4K + * #AFE_PORT_SAMPLE_RATE_192K + * #AFE_PORT_SAMPLE_RATE_352_8K + * #AFE_PORT_SAMPLE_RATE_384K + */ + uint32_t sample_rate; + + /* + * Bit width of the sample. + * @values 16, 24 + */ + uint16_t bit_width; + + /* + * Number of channels. + * @values 1 to #AFE_PORT_MAX_AUDIO_CHAN_CNT + */ + uint16_t num_channels; + + /* + * Data format supported by this port. + * If the port media type and device media type are different, + * it signifies a encoding/decoding use case + * @values + * #AFE_PORT_DATA_FORMAT_PCM + * #AFE_PORT_DATA_FORMAT_GENERIC_COMPRESSED + */ + uint16_t data_format; + + /*This field must be set to zero.*/ + uint16_t reserved; +} __packed; + +union afe_enc_config_data { + struct asm_sbc_enc_cfg_t sbc_config; + struct asm_aac_enc_cfg_v2_t aac_config; + struct asm_custom_enc_cfg_aptx_t aptx_config; +}; + +struct afe_enc_config { + u32 format; + union afe_enc_config_data data; +}; + +struct afe_enc_cfg_blk_param_t { + uint32_t enc_cfg_blk_size; + /* + *Size of the encoder configuration block that follows this member + */ + union afe_enc_config_data enc_blk_config; +}; + +/* + * Payload of the AVS_ENCODER_PARAM_ID_PACKETIZER_ID parameter. + */ +struct avs_enc_packetizer_id_param_t { + /* + * Supported values: + * #AVS_MODULE_ID_PACKETIZER_COP + * Any OpenDSP supported values + */ + uint32_t enc_packetizer_id; +}; + +union afe_port_config { + struct afe_param_id_pcm_cfg pcm; + struct afe_param_id_i2s_cfg i2s; + struct afe_param_id_hdmi_multi_chan_audio_cfg hdmi_multi_ch; + struct afe_param_id_slimbus_cfg slim_sch; + struct afe_param_id_rt_proxy_port_cfg rtproxy; + struct afe_param_id_internal_bt_fm_cfg int_bt_fm; + struct afe_param_id_pseudo_port_cfg pseudo_port; + struct afe_param_id_device_hw_delay_cfg hw_delay; + struct afe_param_id_spdif_cfg spdif; + struct afe_param_id_set_topology_cfg topology; + struct afe_param_id_tdm_cfg tdm; + struct afe_param_id_usb_audio_cfg usb_audio; + struct afe_enc_fmt_id_param_t enc_fmt; + struct afe_port_media_type_t media_type; + struct afe_enc_cfg_blk_param_t enc_blk_param; + struct avs_enc_packetizer_id_param_t enc_pkt_id_param; +} __packed; + +struct afe_audioif_config_command_no_payload { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; +} __packed; + +struct afe_audioif_config_command { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + union afe_port_config port; +} __packed; + +#define AFE_PORT_CMD_DEVICE_START 0x000100E5 + +/* Payload of the #AFE_PORT_CMD_DEVICE_START.*/ +struct afe_port_cmd_device_start { + struct apr_hdr hdr; + u16 port_id; +/* Port interface and direction (Rx or Tx) to start. An even + * number represents the Rx direction, and an odd number represents + * the Tx direction. + */ + + + u16 reserved; +/* Reserved for 32-bit alignment. This field must be set to 0.*/ + +} __packed; + +#define AFE_PORT_CMD_DEVICE_STOP 0x000100E6 + +/* Payload of the #AFE_PORT_CMD_DEVICE_STOP. */ +struct afe_port_cmd_device_stop { + struct apr_hdr hdr; + u16 port_id; +/* Port interface and direction (Rx or Tx) to start. An even + * number represents the Rx direction, and an odd number represents + * the Tx direction. + */ + + u16 reserved; +/* Reserved for 32-bit alignment. This field must be set to 0.*/ +} __packed; + +#define AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS 0x000100EA + +/* Memory map regions command payload used by the + * #AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS . + * This structure allows clients to map multiple shared memory + * regions in a single command. Following this structure are + * num_regions of afe_service_shared_map_region_payload. + */ +struct afe_service_cmd_shared_mem_map_regions { + struct apr_hdr hdr; +u16 mem_pool_id; +/* Type of memory on which this memory region is mapped. + * Supported values: + * - #ADSP_MEMORY_MAP_EBI_POOL + * - #ADSP_MEMORY_MAP_SMI_POOL + * - #ADSP_MEMORY_MAP_SHMEM8_4K_POOL + * - Other values are reserved + * + * The memory pool ID implicitly defines the characteristics of the + * memory. Characteristics may include alignment type, permissions, + * etc. + * + * ADSP_MEMORY_MAP_EBI_POOL is External Buffer Interface type memory + * ADSP_MEMORY_MAP_SMI_POOL is Shared Memory Interface type memory + * ADSP_MEMORY_MAP_SHMEM8_4K_POOL is shared memory, byte + * addressable, and 4 KB aligned. + */ + + + u16 num_regions; +/* Number of regions to map. + * Supported values: + * - Any value greater than zero + */ + + u32 property_flag; +/* Configures one common property for all the regions in the + * payload. + * + * Supported values: - 0x00000000 to 0x00000001 + * + * b0 - bit 0 indicates physical or virtual mapping 0 Shared memory + * address provided in afe_service_shared_map_region_payloadis a + * physical address. The shared memory needs to be mapped( hardware + * TLB entry) and a software entry needs to be added for internal + * book keeping. + * + * 1 Shared memory address provided in + * afe_service_shared_map_region_payloadis a virtual address. The + * shared memory must not be mapped (since hardware TLB entry is + * already available) but a software entry needs to be added for + * internal book keeping. This can be useful if two services with in + * ADSP is communicating via APR. They can now directly communicate + * via the Virtual address instead of Physical address. The virtual + * regions must be contiguous. num_regions must be 1 in this case. + * + * b31-b1 - reserved bits. must be set to zero + */ + + +} __packed; +/* Map region payload used by the + * afe_service_shared_map_region_payloadstructure. + */ +struct afe_service_shared_map_region_payload { + u32 shm_addr_lsw; +/* least significant word of starting address in the memory + * region to map. It must be contiguous memory, and it must be 4 KB + * aligned. + * Supported values: - Any 32 bit value + */ + + + u32 shm_addr_msw; +/* most significant word of startng address in the memory region + * to map. For 32 bit shared memory address, this field must be set + * to zero. For 36 bit shared memory address, bit31 to bit 4 must be + * set to zero + * + * Supported values: - For 32 bit shared memory address, this field + * must be set to zero. - For 36 bit shared memory address, bit31 to + * bit 4 must be set to zero - For 64 bit shared memory address, any + * 32 bit value + */ + + + u32 mem_size_bytes; +/* Number of bytes in the region. The aDSP will always map the + * regions as virtual contiguous memory, but the memory size must be + * in multiples of 4 KB to avoid gaps in the virtually contiguous + * mapped memory. + * + * Supported values: - multiples of 4KB + */ + +} __packed; + +#define AFE_SERVICE_CMDRSP_SHARED_MEM_MAP_REGIONS 0x000100EB +struct afe_service_cmdrsp_shared_mem_map_regions { + u32 mem_map_handle; +/* A memory map handle encapsulating shared memory attributes is + * returned iff AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS command is + * successful. In the case of failure , a generic APR error response + * is returned to the client. + * + * Supported Values: - Any 32 bit value + */ + +} __packed; +#define AFE_SERVICE_CMD_SHARED_MEM_UNMAP_REGIONS 0x000100EC +/* Memory unmap regions command payload used by the + * #AFE_SERVICE_CMD_SHARED_MEM_UNMAP_REGIONS + * + * This structure allows clients to unmap multiple shared memory + * regions in a single command. + */ + + +struct afe_service_cmd_shared_mem_unmap_regions { + struct apr_hdr hdr; +u32 mem_map_handle; +/* memory map handle returned by + * AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS commands + * + * Supported Values: + * - Any 32 bit value + */ +} __packed; + +#define AFE_PORT_CMD_GET_PARAM_V2 0x000100F0 + +/* Payload of the #AFE_PORT_CMD_GET_PARAM_V2 command, + * which queries for one post/preprocessing parameter of a + * stream. + */ +struct afe_port_cmd_get_param_v2 { + u16 port_id; +/* Port interface and direction (Rx or Tx) to start. */ + + u16 payload_size; +/* Maximum data size of the parameter ID/module ID combination. + * This is a multiple of four bytes + * Supported values: > 0 + */ + + u32 payload_address_lsw; +/* LSW of 64 bit Payload address. Address should be 32-byte, + * 4kbyte aligned and must be contig memory. + */ + + + u32 payload_address_msw; +/* MSW of 64 bit Payload address. In case of 32-bit shared + * memory address, this field must be set to zero. In case of 36-bit + * shared memory address, bit-4 to bit-31 must be set to zero. + * Address should be 32-byte, 4kbyte aligned and must be contiguous + * memory. + */ + + u32 mem_map_handle; +/* Memory map handle returned by + * AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS commands. + * Supported Values: - NULL -- Message. The parameter data is + * in-band. - Non-NULL -- The parameter data is Out-band.Pointer to + * - the physical address in shared memory of the payload data. + * For detailed payload content, see the afe_port_param_data_v2 + * structure + */ + + + u32 module_id; +/* ID of the module to be queried. + * Supported values: Valid module ID + */ + + u32 param_id; +/* ID of the parameter to be queried. + * Supported values: Valid parameter ID + */ +} __packed; + +#define AFE_PORT_CMDRSP_GET_PARAM_V2 0x00010106 + +/* Payload of the #AFE_PORT_CMDRSP_GET_PARAM_V2 message, which + * responds to an #AFE_PORT_CMD_GET_PARAM_V2 command. + * + * Immediately following this structure is the parameters structure + * (afe_port_param_data) containing the response(acknowledgment) + * parameter payload. This payload is included for an in-band + * scenario. For an address/shared memory-based set parameter, this + * payload is not needed. + */ + + +struct afe_port_cmdrsp_get_param_v2 { + u32 status; +} __packed; + +#define AFE_PARAM_ID_LPASS_CORE_SHARED_CLOCK_CONFIG 0x0001028C +#define AFE_API_VERSION_LPASS_CORE_SHARED_CLK_CONFIG 0x1 + +/* Payload of the AFE_PARAM_ID_LPASS_CORE_SHARED_CLOCK_CONFIG parameter used by + * AFE_MODULE_AUDIO_DEV_INTERFACE. + */ +struct afe_param_id_lpass_core_shared_clk_cfg { + u32 lpass_core_shared_clk_cfg_minor_version; +/* + * Minor version used for lpass core shared clock configuration + * Supported value: AFE_API_VERSION_LPASS_CORE_SHARED_CLK_CONFIG + */ + u32 enable; +/* + * Specifies whether the lpass core shared clock is + * enabled (1) or disabled (0). + */ +} __packed; + +struct afe_lpass_core_shared_clk_config_command { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + struct afe_param_id_lpass_core_shared_clk_cfg clk_cfg; +} __packed; + +/* adsp_afe_service_commands.h */ + +#define ADSP_MEMORY_MAP_EBI_POOL 0 + +#define ADSP_MEMORY_MAP_SMI_POOL 1 +#define ADSP_MEMORY_MAP_IMEM_POOL 2 +#define ADSP_MEMORY_MAP_SHMEM8_4K_POOL 3 + +/* Definition of virtual memory flag */ +#define ADSP_MEMORY_MAP_VIRTUAL_MEMORY 1 + +/* Definition of physical memory flag */ +#define ADSP_MEMORY_MAP_PHYSICAL_MEMORY 0 + +#define NULL_POPP_TOPOLOGY 0x00010C68 +#define NULL_COPP_TOPOLOGY 0x00010312 +#define DEFAULT_COPP_TOPOLOGY 0x00010314 +#define DEFAULT_POPP_TOPOLOGY 0x00010BE4 +#define COMPRESSED_PASSTHROUGH_DEFAULT_TOPOLOGY 0x0001076B +#define COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY 0x00010774 +#define VPM_TX_SM_ECNS_COPP_TOPOLOGY 0x00010F71 +#define VPM_TX_DM_FLUENCE_COPP_TOPOLOGY 0x00010F72 +#define VPM_TX_QMIC_FLUENCE_COPP_TOPOLOGY 0x00010F75 +#define VPM_TX_DM_RFECNS_COPP_TOPOLOGY 0x00010F86 +#define ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX 0x10015002 +#define ADM_CMD_COPP_OPEN_TOPOLOGY_ID_AUDIOSPHERE 0x10028000 + +/* Memory map regions command payload used by the + * #ASM_CMD_SHARED_MEM_MAP_REGIONS ,#ADM_CMD_SHARED_MEM_MAP_REGIONS + * commands. + * + * This structure allows clients to map multiple shared memory + * regions in a single command. Following this structure are + * num_regions of avs_shared_map_region_payload. + */ + + +struct avs_cmd_shared_mem_map_regions { + struct apr_hdr hdr; + u16 mem_pool_id; +/* Type of memory on which this memory region is mapped. + * + * Supported values: - #ADSP_MEMORY_MAP_EBI_POOL - + * #ADSP_MEMORY_MAP_SMI_POOL - #ADSP_MEMORY_MAP_IMEM_POOL + * (unsupported) - #ADSP_MEMORY_MAP_SHMEM8_4K_POOL - Other values + * are reserved + * + * The memory ID implicitly defines the characteristics of the + * memory. Characteristics may include alignment type, permissions, + * etc. + * + * SHMEM8_4K is shared memory, byte addressable, and 4 KB aligned. + */ + + + u16 num_regions; + /* Number of regions to map.*/ + + u32 property_flag; +/* Configures one common property for all the regions in the + * payload. No two regions in the same memory map regions cmd can + * have differnt property. Supported values: - 0x00000000 to + * 0x00000001 + * + * b0 - bit 0 indicates physical or virtual mapping 0 shared memory + * address provided in avs_shared_map_regions_payload is physical + * address. The shared memory needs to be mapped( hardware TLB + * entry) + * + * and a software entry needs to be added for internal book keeping. + * + * 1 Shared memory address provided in MayPayload[usRegions] is + * virtual address. The shared memory must not be mapped (since + * hardware TLB entry is already available) but a software entry + * needs to be added for internal book keeping. This can be useful + * if two services with in ADSP is communicating via APR. They can + * now directly communicate via the Virtual address instead of + * Physical address. The virtual regions must be contiguous. + * + * b31-b1 - reserved bits. must be set to zero + */ + +} __packed; + +struct avs_shared_map_region_payload { + u32 shm_addr_lsw; +/* least significant word of shared memory address of the memory + * region to map. It must be contiguous memory, and it must be 4 KB + * aligned. + */ + + u32 shm_addr_msw; +/* most significant word of shared memory address of the memory + * region to map. For 32 bit shared memory address, this field must + * tbe set to zero. For 36 bit shared memory address, bit31 to bit 4 + * must be set to zero + */ + + u32 mem_size_bytes; +/* Number of bytes in the region. + * + * The aDSP will always map the regions as virtual contiguous + * memory, but the memory size must be in multiples of 4 KB to avoid + * gaps in the virtually contiguous mapped memory. + */ + +} __packed; + +struct avs_cmd_shared_mem_unmap_regions { + struct apr_hdr hdr; + u32 mem_map_handle; +/* memory map handle returned by ASM_CMD_SHARED_MEM_MAP_REGIONS + * , ADM_CMD_SHARED_MEM_MAP_REGIONS, commands + */ + +} __packed; + +/* Memory map command response payload used by the + * #ASM_CMDRSP_SHARED_MEM_MAP_REGIONS + * ,#ADM_CMDRSP_SHARED_MEM_MAP_REGIONS + */ + + +struct avs_cmdrsp_shared_mem_map_regions { + u32 mem_map_handle; +/* A memory map handle encapsulating shared memory attributes is + * returned + */ + +} __packed; + +/*adsp_audio_memmap_api.h*/ + +/* ASM related data structures */ +struct asm_wma_cfg { + u16 format_tag; + u16 ch_cfg; + u32 sample_rate; + u32 avg_bytes_per_sec; + u16 block_align; + u16 valid_bits_per_sample; + u32 ch_mask; + u16 encode_opt; + u16 adv_encode_opt; + u32 adv_encode_opt2; + u32 drc_peak_ref; + u32 drc_peak_target; + u32 drc_ave_ref; + u32 drc_ave_target; +} __packed; + +struct asm_wmapro_cfg { + u16 format_tag; + u16 ch_cfg; + u32 sample_rate; + u32 avg_bytes_per_sec; + u16 block_align; + u16 valid_bits_per_sample; + u32 ch_mask; + u16 encode_opt; + u16 adv_encode_opt; + u32 adv_encode_opt2; + u32 drc_peak_ref; + u32 drc_peak_target; + u32 drc_ave_ref; + u32 drc_ave_target; +} __packed; + +struct asm_aac_cfg { + u16 format; + u16 aot; + u16 ep_config; + u16 section_data_resilience; + u16 scalefactor_data_resilience; + u16 spectral_data_resilience; + u16 ch_cfg; + u16 reserved; + u32 sample_rate; +} __packed; + +struct asm_amrwbplus_cfg { + u32 size_bytes; + u32 version; + u32 num_channels; + u32 amr_band_mode; + u32 amr_dtx_mode; + u32 amr_frame_fmt; + u32 amr_lsf_idx; +} __packed; + +struct asm_flac_cfg { + u32 sample_rate; + u32 ext_sample_rate; + u32 min_frame_size; + u32 max_frame_size; + u16 stream_info_present; + u16 min_blk_size; + u16 max_blk_size; + u16 ch_cfg; + u16 sample_size; + u16 md5_sum; +}; + +struct asm_alac_cfg { + u32 frame_length; + u8 compatible_version; + u8 bit_depth; + u8 pb; + u8 mb; + u8 kb; + u8 num_channels; + u16 max_run; + u32 max_frame_bytes; + u32 avg_bit_rate; + u32 sample_rate; + u32 channel_layout_tag; +}; + +struct asm_g711_dec_cfg { + u32 sample_rate; +}; + +struct asm_vorbis_cfg { + u32 bit_stream_fmt; +}; + +struct asm_ape_cfg { + u16 compatible_version; + u16 compression_level; + u32 format_flags; + u32 blocks_per_frame; + u32 final_frame_blocks; + u32 total_frames; + u16 bits_per_sample; + u16 num_channels; + u32 sample_rate; + u32 seek_table_present; +}; + +struct asm_dsd_cfg { + u16 num_version; + u16 is_bitwise_big_endian; + u16 dsd_channel_block_size; + u16 num_channels; + u8 channel_mapping[8]; + u32 dsd_data_rate; +}; + +struct asm_softpause_params { + u32 enable; + u32 period; + u32 step; + u32 rampingcurve; +} __packed; + +struct asm_softvolume_params { + u32 period; + u32 step; + u32 rampingcurve; +} __packed; + +#define ASM_END_POINT_DEVICE_MATRIX 0 + +#define PCM_CHANNEL_NULL 0 + +/* Front left channel. */ +#define PCM_CHANNEL_FL 1 + +/* Front right channel. */ +#define PCM_CHANNEL_FR 2 + +/* Front center channel. */ +#define PCM_CHANNEL_FC 3 + +/* Left surround channel.*/ +#define PCM_CHANNEL_LS 4 + +/* Right surround channel.*/ +#define PCM_CHANNEL_RS 5 + +/* Low frequency effect channel. */ +#define PCM_CHANNEL_LFE 6 + +/* Center surround channel; Rear center channel. */ +#define PCM_CHANNEL_CS 7 + +/* Left back channel; Rear left channel. */ +#define PCM_CHANNEL_LB 8 + +/* Right back channel; Rear right channel. */ +#define PCM_CHANNEL_RB 9 + +/* Top surround channel. */ +#define PCM_CHANNELS 10 + +/* Center vertical height channel.*/ +#define PCM_CHANNEL_CVH 11 + +/* Mono surround channel.*/ +#define PCM_CHANNEL_MS 12 + +/* Front left of center. */ +#define PCM_CHANNEL_FLC 13 + +/* Front right of center. */ +#define PCM_CHANNEL_FRC 14 + +/* Rear left of center. */ +#define PCM_CHANNEL_RLC 15 + +/* Rear right of center. */ +#define PCM_CHANNEL_RRC 16 + +#define PCM_FORMAT_MAX_NUM_CHANNEL 8 + +#define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2 0x00010DA5 + +#define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3 0x00010DDC + +#define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V4 0x0001320C + +#define ASM_MEDIA_FMT_EVRCB_FS 0x00010BEF + +#define ASM_MEDIA_FMT_EVRCWB_FS 0x00010BF0 + +#define ASM_MEDIA_FMT_GENERIC_COMPRESSED 0x00013212 + +#define ASM_MAX_EQ_BANDS 12 + +#define ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2 0x00010D98 + +struct asm_data_cmd_media_fmt_update_v2 { +u32 fmt_blk_size; + /* Media format block size in bytes.*/ +} __packed; + +struct asm_generic_compressed_fmt_blk_t { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmt_blk; + + /* + * Channel mapping array of bitstream output. + * Channel[i] mapping describes channel i inside the buffer, where + * i < num_channels. All valid used channels must be + * present at the beginning of the array. + */ + uint8_t channel_mapping[8]; + + /* + * Number of channels of the incoming bitstream. + * Supported values: 1,2,3,4,5,6,7,8 + */ + uint16_t num_channels; + + /* + * Nominal bits per sample value of the incoming bitstream. + * Supported values: 16, 32 + */ + uint16_t bits_per_sample; + + /* + * Nominal sampling rate of the incoming bitstream. + * Supported values: 8000, 11025, 16000, 22050, 24000, 32000, + * 44100, 48000, 88200, 96000, 176400, 192000, + * 352800, 384000 + */ + uint32_t sampling_rate; + +} __packed; + + +/* Command to send sample rate & channels for IEC61937 (compressed) or IEC60958 + * (pcm) streams. Both audio standards use the same format and are used for + * HDMI or SPDIF. + */ +#define ASM_DATA_CMD_IEC_60958_MEDIA_FMT 0x0001321E + +struct asm_iec_compressed_fmt_blk_t { + struct apr_hdr hdr; + + /* + * Nominal sampling rate of the incoming bitstream. + * Supported values: 8000, 11025, 16000, 22050, 24000, 32000, + * 44100, 48000, 88200, 96000, 176400, 192000, + * 352800, 384000 + */ + uint32_t sampling_rate; + + /* + * Number of channels of the incoming bitstream. + * Supported values: 1,2,3,4,5,6,7,8 + */ + uint32_t num_channels; + +} __packed; + +struct asm_multi_channel_pcm_fmt_blk_v2 { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmt_blk; + + u16 num_channels; + /* Number of channels. Supported values: 1 to 8 */ + u16 bits_per_sample; +/* Number of bits per sample per channel. * Supported values: + * 16, 24 * When used for playback, the client must send 24-bit + * samples packed in 32-bit words. The 24-bit samples must be placed + * in the most significant 24 bits of the 32-bit word. When used for + * recording, the aDSP sends 24-bit samples packed in 32-bit words. + * The 24-bit samples are placed in the most significant 24 bits of + * the 32-bit word. + */ + + + u32 sample_rate; +/* Number of samples per second (in Hertz). + * Supported values: 2000 to 48000 + */ + + u16 is_signed; + /* Flag that indicates the samples are signed (1). */ + + u16 reserved; + /* reserved field for 32 bit alignment. must be set to zero. */ + + u8 channel_mapping[8]; +/* Channel array of size 8. + * Supported values: + * - #PCM_CHANNEL_L + * - #PCM_CHANNEL_R + * - #PCM_CHANNEL_C + * - #PCM_CHANNEL_LS + * - #PCM_CHANNEL_RS + * - #PCM_CHANNEL_LFE + * - #PCM_CHANNEL_CS + * - #PCM_CHANNEL_LB + * - #PCM_CHANNEL_RB + * - #PCM_CHANNELS + * - #PCM_CHANNEL_CVH + * - #PCM_CHANNEL_MS + * - #PCM_CHANNEL_FLC + * - #PCM_CHANNEL_FRC + * - #PCM_CHANNEL_RLC + * - #PCM_CHANNEL_RRC + * + * Channel[i] mapping describes channel I. Each element i of the + * array describes channel I inside the buffer where 0 @le I < + * num_channels. An unused channel is set to zero. + */ +} __packed; + +struct asm_multi_channel_pcm_fmt_blk_v3 { + uint16_t num_channels; +/* + * Number of channels + * Supported values: 1 to 8 + */ + + uint16_t bits_per_sample; +/* + * Number of bits per sample per channel + * Supported values: 16, 24 + */ + + uint32_t sample_rate; +/* + * Number of samples per second + * Supported values: 2000 to 48000, 96000,192000 Hz + */ + + uint16_t is_signed; +/* Flag that indicates that PCM samples are signed (1) */ + + uint16_t sample_word_size; +/* + * Size in bits of the word that holds a sample of a channel. + * Supported values: 12,24,32 + */ + + uint8_t channel_mapping[8]; +/* + * Each element, i, in the array describes channel i inside the buffer where + * 0 <= i < num_channels. Unused channels are set to 0. + */ +} __packed; + +struct asm_multi_channel_pcm_fmt_blk_v4 { + uint16_t num_channels; +/* + * Number of channels + * Supported values: 1 to 8 + */ + + uint16_t bits_per_sample; +/* + * Number of bits per sample per channel + * Supported values: 16, 24, 32 + */ + + uint32_t sample_rate; +/* + * Number of samples per second + * Supported values: 2000 to 48000, 96000,192000 Hz + */ + + uint16_t is_signed; +/* Flag that indicates that PCM samples are signed (1) */ + + uint16_t sample_word_size; +/* + * Size in bits of the word that holds a sample of a channel. + * Supported values: 12,24,32 + */ + + uint8_t channel_mapping[8]; +/* + * Each element, i, in the array describes channel i inside the buffer where + * 0 <= i < num_channels. Unused channels are set to 0. + */ + uint16_t endianness; +/* + * Flag to indicate the endianness of the pcm sample + * Supported values: 0 - Little endian (all other formats) + * 1 - Big endian (AIFF) + */ + uint16_t mode; +/* + * Mode to provide additional info about the pcm input data. + * Supported values: 0 - Default QFs (Q15 for 16b, Q23 for packed 24b, + * Q31 for unpacked 24b or 32b) + * 15 - for 16 bit + * 23 - for 24b packed or 8.24 format + * 31 - for 24b unpacked or 32bit + */ +} __packed; + +/* + * Payload of the multichannel PCM configuration parameters in + * the ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3 media format. + */ +struct asm_multi_channel_pcm_fmt_blk_param_v3 { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmt_blk; + struct asm_multi_channel_pcm_fmt_blk_v3 param; +} __packed; + +/* + * Payload of the multichannel PCM configuration parameters in + * the ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V4 media format. + */ +struct asm_multi_channel_pcm_fmt_blk_param_v4 { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmt_blk; + struct asm_multi_channel_pcm_fmt_blk_v4 param; +} __packed; + +struct asm_stream_cmd_set_encdec_param { + u32 param_id; + /* ID of the parameter. */ + + u32 param_size; +/* Data size of this parameter, in bytes. The size is a multiple + * of 4 bytes. + */ + +} __packed; + +struct asm_enc_cfg_blk_param_v2 { + u32 frames_per_buf; +/* Number of encoded frames to pack into each buffer. + * + * @note1hang This is only guidance information for the aDSP. The + * number of encoded frames put into each buffer (specified by the + * client) is less than or equal to this number. + */ + + u32 enc_cfg_blk_size; +/* Size in bytes of the encoder configuration block that follows + * this member. + */ + +} __packed; + +/* @brief Dolby Digital Plus end point configuration structure + */ +struct asm_dec_ddp_endp_param_v2 { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + int endp_param_value; +} __packed; + +/* + * Payload of the multichannel PCM encoder configuration parameters in + * the ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V4 media format. + */ + +struct asm_multi_channel_pcm_enc_cfg_v4 { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + struct asm_enc_cfg_blk_param_v2 encblk; + uint16_t num_channels; + /* + * Number of PCM channels. + * @values + * - 0 -- Native mode + * - 1 -- 8 channels + * Native mode indicates that encoding must be performed with the number + * of channels at the input. + */ + uint16_t bits_per_sample; + /* + * Number of bits per sample per channel. + * @values 16, 24 + */ + uint32_t sample_rate; + /* + * Number of samples per second. + * @values 0, 8000 to 48000 Hz + * A value of 0 indicates the native sampling rate. Encoding is + * performed at the input sampling rate. + */ + uint16_t is_signed; + /* + * Flag that indicates the PCM samples are signed (1). Currently, only + * signed PCM samples are supported. + */ + uint16_t sample_word_size; + /* + * The size in bits of the word that holds a sample of a channel. + * @values 16, 24, 32 + * 16-bit samples are always placed in 16-bit words: + * sample_word_size = 1. + * 24-bit samples can be placed in 32-bit words or in consecutive + * 24-bit words. + * - If sample_word_size = 32, 24-bit samples are placed in the + * most significant 24 bits of a 32-bit word. + * - If sample_word_size = 24, 24-bit samples are placed in + * 24-bit words. @tablebulletend + */ + uint8_t channel_mapping[8]; + /* + * Channel mapping array expected at the encoder output. + * Channel[i] mapping describes channel i inside the buffer, where + * 0 @le i < num_channels. All valid used channels must be present at + * the beginning of the array. + * If Native mode is set for the channels, this field is ignored. + * @values See Section @xref{dox:PcmChannelDefs} + */ + uint16_t endianness; + /* + * Flag to indicate the endianness of the pcm sample + * Supported values: 0 - Little endian (all other formats) + * 1 - Big endian (AIFF) + */ + uint16_t mode; + /* + * Mode to provide additional info about the pcm input data. + * Supported values: 0 - Default QFs (Q15 for 16b, Q23 for packed 24b, + * Q31 for unpacked 24b or 32b) + * 15 - for 16 bit + * 23 - for 24b packed or 8.24 format + * 31 - for 24b unpacked or 32bit + */ +} __packed; + +/* + * Payload of the multichannel PCM encoder configuration parameters in + * the ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3 media format. + */ + +struct asm_multi_channel_pcm_enc_cfg_v3 { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + struct asm_enc_cfg_blk_param_v2 encblk; + uint16_t num_channels; + /* + * Number of PCM channels. + * @values + * - 0 -- Native mode + * - 1 -- 8 channels + * Native mode indicates that encoding must be performed with the number + * of channels at the input. + */ + uint16_t bits_per_sample; + /* + * Number of bits per sample per channel. + * @values 16, 24 + */ + uint32_t sample_rate; + /* + * Number of samples per second. + * @values 0, 8000 to 48000 Hz + * A value of 0 indicates the native sampling rate. Encoding is + * performed at the input sampling rate. + */ + uint16_t is_signed; + /* + * Flag that indicates the PCM samples are signed (1). Currently, only + * signed PCM samples are supported. + */ + uint16_t sample_word_size; + /* + * The size in bits of the word that holds a sample of a channel. + * @values 16, 24, 32 + * 16-bit samples are always placed in 16-bit words: + * sample_word_size = 1. + * 24-bit samples can be placed in 32-bit words or in consecutive + * 24-bit words. + * - If sample_word_size = 32, 24-bit samples are placed in the + * most significant 24 bits of a 32-bit word. + * - If sample_word_size = 24, 24-bit samples are placed in + * 24-bit words. @tablebulletend + */ + uint8_t channel_mapping[8]; + /* + * Channel mapping array expected at the encoder output. + * Channel[i] mapping describes channel i inside the buffer, where + * 0 @le i < num_channels. All valid used channels must be present at + * the beginning of the array. + * If Native mode is set for the channels, this field is ignored. + * @values See Section @xref{dox:PcmChannelDefs} + */ +}; + +/* @brief Multichannel PCM encoder configuration structure used + * in the #ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2 command. + */ + +struct asm_multi_channel_pcm_enc_cfg_v2 { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + struct asm_enc_cfg_blk_param_v2 encblk; + uint16_t num_channels; +/*< Number of PCM channels. + * + * Supported values: - 0 -- Native mode - 1 -- 8 Native mode + * indicates that encoding must be performed with the number of + * channels at the input. + */ + + uint16_t bits_per_sample; +/*< Number of bits per sample per channel. + * Supported values: 16, 24 + */ + + uint32_t sample_rate; +/*< Number of samples per second (in Hertz). + * + * Supported values: 0, 8000 to 48000 A value of 0 indicates the + * native sampling rate. Encoding is performed at the input sampling + * rate. + */ + + uint16_t is_signed; +/*< Specifies whether the samples are signed (1). Currently, + * only signed samples are supported. + */ + + uint16_t reserved; +/*< reserved field for 32 bit alignment. must be set to zero.*/ + + + uint8_t channel_mapping[8]; +} __packed; + +#define ASM_MEDIA_FMT_MP3 0x00010BE9 +#define ASM_MEDIA_FMT_AAC_V2 0x00010DA6 + +/* @xreflabel + * {hdr:AsmMediaFmtDolbyAac} Media format ID for the + * Dolby AAC decoder. This format ID is be used if the client wants + * to use the Dolby AAC decoder to decode MPEG2 and MPEG4 AAC + * contents. + */ + +#define ASM_MEDIA_FMT_DOLBY_AAC 0x00010D86 + +/* Enumeration for the audio data transport stream AAC format. */ +#define ASM_MEDIA_FMT_AAC_FORMAT_FLAG_ADTS 0 + +/* Enumeration for low overhead audio stream AAC format. */ +#define ASM_MEDIA_FMT_AAC_FORMAT_FLAG_LOAS 1 + +/* Enumeration for the audio data interchange format + * AAC format. + */ +#define ASM_MEDIA_FMT_AAC_FORMAT_FLAG_ADIF 2 + +/* Enumeration for the raw AAC format. */ +#define ASM_MEDIA_FMT_AAC_FORMAT_FLAG_RAW 3 + +/* Enumeration for the AAC LATM format. */ +#define ASM_MEDIA_FMT_AAC_FORMAT_FLAG_LATM 4 + +#define ASM_MEDIA_FMT_AAC_AOT_LC 2 +#define ASM_MEDIA_FMT_AAC_AOT_SBR 5 +#define ASM_MEDIA_FMT_AAC_AOT_PS 29 +#define ASM_MEDIA_FMT_AAC_AOT_BSAC 22 + +struct asm_aac_fmt_blk_v2 { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmt_blk; + + u16 aac_fmt_flag; +/* Bitstream format option. + * Supported values: + * - #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_ADTS + * - #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_LOAS + * - #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_ADIF + * - #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_RAW + */ + + u16 audio_objype; +/* Audio Object Type (AOT) present in the AAC stream. + * Supported values: + * - #ASM_MEDIA_FMT_AAC_AOT_LC + * - #ASM_MEDIA_FMT_AAC_AOT_SBR + * - #ASM_MEDIA_FMT_AAC_AOT_BSAC + * - #ASM_MEDIA_FMT_AAC_AOT_PS + * - Otherwise -- Not supported + */ + + u16 channel_config; +/* Number of channels present in the AAC stream. + * Supported values: + * - 1 -- Mono + * - 2 -- Stereo + * - 6 -- 5.1 content + */ + + u16 total_size_of_PCE_bits; +/* greater or equal to zero. * -In case of RAW formats and + * channel config = 0 (PCE), client can send * the bit stream + * containing PCE immediately following this structure * (in-band). + * -This number does not include bits included for 32 bit alignment. + * -If zero, then the PCE info is assumed to be available in the + * audio -bit stream & not in-band. + */ + + u32 sample_rate; +/* Number of samples per second (in Hertz). + * + * Supported values: 8000, 11025, 12000, 16000, 22050, 24000, 32000, + * 44100, 48000 + * + * This field must be equal to the sample rate of the AAC-LC + * decoder's output. - For MP4 or 3GP containers, this is indicated + * by the samplingFrequencyIndex field in the AudioSpecificConfig + * element. - For ADTS format, this is indicated by the + * samplingFrequencyIndex in the ADTS fixed header. - For ADIF + * format, this is indicated by the samplingFrequencyIndex in the + * program_config_element present in the ADIF header. + */ + +} __packed; + +struct asm_aac_enc_cfg_v2 { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + struct asm_enc_cfg_blk_param_v2 encblk; + + u32 bit_rate; + /* Encoding rate in bits per second. */ + u32 enc_mode; +/* Encoding mode. + * Supported values: + * - #ASM_MEDIA_FMT_AAC_AOT_LC + * - #ASM_MEDIA_FMT_AAC_AOT_SBR + * - #ASM_MEDIA_FMT_AAC_AOT_PS + */ + u16 aac_fmt_flag; +/* AAC format flag. + * Supported values: + * - #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_ADTS + * - #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_RAW + */ + u16 channel_cfg; +/* Number of channels to encode. + * Supported values: + * - 0 -- Native mode + * - 1 -- Mono + * - 2 -- Stereo + * - Other values are not supported. + * @note1hang The eAAC+ encoder mode supports only stereo. + * Native mode indicates that encoding must be performed with the + * number of channels at the input. + * The number of channels must not change during encoding. + */ + + u32 sample_rate; +/* Number of samples per second. + * Supported values: - 0 -- Native mode - For other values, + * Native mode indicates that encoding must be performed with the + * sampling rate at the input. + * The sampling rate must not change during encoding. + */ + +} __packed; + +#define ASM_MEDIA_FMT_G711_ALAW_FS 0x00010BF7 +#define ASM_MEDIA_FMT_G711_MLAW_FS 0x00010C2E + +struct asm_g711_enc_cfg_v2 { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + struct asm_enc_cfg_blk_param_v2 encblk; + + u32 sample_rate; +/* + * Number of samples per second. + * Supported values: 8000, 16000 Hz + */ + +} __packed; + +struct asm_vorbis_fmt_blk_v2 { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmtblk; + u32 bit_stream_fmt; +/* Bit stream format. + * Supported values: + * - 0 -- Raw bitstream + * - 1 -- Transcoded bitstream + * + * Transcoded bitstream containing the size of the frame as the first + * word in each frame. + */ + +} __packed; + +struct asm_flac_fmt_blk_v2 { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmtblk; + + u16 is_stream_info_present; +/* Specifies whether stream information is present in the FLAC format + * block. + * + * Supported values: + * - 0 -- Stream information is not present in this message + * - 1 -- Stream information is present in this message + * + * When set to 1, the FLAC bitstream was successfully parsed by the + * client, and other fields in the FLAC format block can be read by the + * decoder to get metadata stream information. + */ + + u16 num_channels; +/* Number of channels for decoding. + * Supported values: 1 to 2 + */ + + u16 min_blk_size; +/* Minimum block size (in samples) used in the stream. It must be less + * than or equal to max_blk_size. + */ + + u16 max_blk_size; +/* Maximum block size (in samples) used in the stream. If the + * minimum block size equals the maximum block size, a fixed block + * size stream is implied. + */ + + u16 md5_sum[8]; +/* MD5 signature array of the unencoded audio data. This allows the + * decoder to determine if an error exists in the audio data, even when + * the error does not result in an invalid bitstream. + */ + + u32 sample_rate; +/* Number of samples per second. + * Supported values: 8000 to 48000 Hz + */ + + u32 min_frame_size; +/* Minimum frame size used in the stream. + * Supported values: + * - > 0 bytes + * - 0 -- The value is unknown + */ + + u32 max_frame_size; +/* Maximum frame size used in the stream. + * Supported values: + * -- > 0 bytes + * -- 0 . The value is unknown + */ + + u16 sample_size; +/* Bits per sample.Supported values: 8, 16 */ + + u16 reserved; +/* Clients must set this field to zero + */ + +} __packed; + +struct asm_alac_fmt_blk_v2 { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmtblk; + + u32 frame_length; + u8 compatible_version; + u8 bit_depth; + u8 pb; + u8 mb; + u8 kb; + u8 num_channels; + u16 max_run; + u32 max_frame_bytes; + u32 avg_bit_rate; + u32 sample_rate; + u32 channel_layout_tag; + +} __packed; + +struct asm_g711_dec_fmt_blk_v2 { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmtblk; + u32 sample_rate; +} __packed; + +struct asm_ape_fmt_blk_v2 { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmtblk; + + u16 compatible_version; + u16 compression_level; + u32 format_flags; + u32 blocks_per_frame; + u32 final_frame_blocks; + u32 total_frames; + u16 bits_per_sample; + u16 num_channels; + u32 sample_rate; + u32 seek_table_present; + +} __packed; + +struct asm_dsd_fmt_blk_v2 { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmtblk; + + u16 num_version; + u16 is_bitwise_big_endian; + u16 dsd_channel_block_size; + u16 num_channels; + u8 channel_mapping[8]; + u32 dsd_data_rate; + +} __packed; + +#define ASM_MEDIA_FMT_AMRNB_FS 0x00010BEB + +/* Enumeration for 4.75 kbps AMR-NB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRNB_FS_ENCODE_MODE_MR475 0 + +/* Enumeration for 5.15 kbps AMR-NB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRNB_FS_ENCODE_MODE_MR515 1 + +/* Enumeration for 5.90 kbps AMR-NB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRNB_FS_ENCODE_MODE_MMR59 2 + +/* Enumeration for 6.70 kbps AMR-NB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRNB_FS_ENCODE_MODE_MMR67 3 + +/* Enumeration for 7.40 kbps AMR-NB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRNB_FS_ENCODE_MODE_MMR74 4 + +/* Enumeration for 7.95 kbps AMR-NB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRNB_FS_ENCODE_MODE_MMR795 5 + +/* Enumeration for 10.20 kbps AMR-NB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRNB_FS_ENCODE_MODE_MMR102 6 + +/* Enumeration for 12.20 kbps AMR-NB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRNB_FS_ENCODE_MODE_MMR122 7 + +/* Enumeration for AMR-NB Discontinuous Transmission mode off. */ +#define ASM_MEDIA_FMT_AMRNB_FS_DTX_MODE_OFF 0 + +/* Enumeration for AMR-NB DTX mode VAD1. */ +#define ASM_MEDIA_FMT_AMRNB_FS_DTX_MODE_VAD1 1 + +/* Enumeration for AMR-NB DTX mode VAD2. */ +#define ASM_MEDIA_FMT_AMRNB_FS_DTX_MODE_VAD2 2 + +/* Enumeration for AMR-NB DTX mode auto. */ +#define ASM_MEDIA_FMT_AMRNB_FS_DTX_MODE_AUTO 3 + +struct asm_amrnb_enc_cfg { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + struct asm_enc_cfg_blk_param_v2 encblk; + + u16 enc_mode; +/* AMR-NB encoding rate. + * Supported values: + * Use the ASM_MEDIA_FMT_AMRNB_FS_ENCODE_MODE_* + * macros + */ + + u16 dtx_mode; +/* Specifies whether DTX mode is disabled or enabled. + * Supported values: + * - #ASM_MEDIA_FMT_AMRNB_FS_DTX_MODE_OFF + * - #ASM_MEDIA_FMT_AMRNB_FS_DTX_MODE_VAD1 + */ +} __packed; + +#define ASM_MEDIA_FMT_AMRWB_FS 0x00010BEC + +/* Enumeration for 6.6 kbps AMR-WB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRWB_FS_ENCODE_MODE_MR66 0 + +/* Enumeration for 8.85 kbps AMR-WB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRWB_FS_ENCODE_MODE_MR885 1 + +/* Enumeration for 12.65 kbps AMR-WB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRWB_FS_ENCODE_MODE_MR1265 2 + +/* Enumeration for 14.25 kbps AMR-WB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRWB_FS_ENCODE_MODE_MR1425 3 + +/* Enumeration for 15.85 kbps AMR-WB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRWB_FS_ENCODE_MODE_MR1585 4 + +/* Enumeration for 18.25 kbps AMR-WB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRWB_FS_ENCODE_MODE_MR1825 5 + +/* Enumeration for 19.85 kbps AMR-WB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRWB_FS_ENCODE_MODE_MR1985 6 + +/* Enumeration for 23.05 kbps AMR-WB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRWB_FS_ENCODE_MODE_MR2305 7 + +/* Enumeration for 23.85 kbps AMR-WB Encoding mode. */ +#define ASM_MEDIA_FMT_AMRWB_FS_ENCODE_MODE_MR2385 8 + +struct asm_amrwb_enc_cfg { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + struct asm_enc_cfg_blk_param_v2 encblk; + + u16 enc_mode; +/* AMR-WB encoding rate. + * Suupported values: + * Use the ASM_MEDIA_FMT_AMRWB_FS_ENCODE_MODE_* + * macros + */ + + u16 dtx_mode; +/* Specifies whether DTX mode is disabled or enabled. + * Supported values: + * - #ASM_MEDIA_FMT_AMRNB_FS_DTX_MODE_OFF + * - #ASM_MEDIA_FMT_AMRNB_FS_DTX_MODE_VAD1 + */ +} __packed; + +#define ASM_MEDIA_FMT_V13K_FS 0x00010BED + +/* Enumeration for 14.4 kbps V13K Encoding mode. */ +#define ASM_MEDIA_FMT_V13K_FS_ENCODE_MODE_MR1440 0 + +/* Enumeration for 12.2 kbps V13K Encoding mode. */ +#define ASM_MEDIA_FMT_V13K_FS_ENCODE_MODE_MR1220 1 + +/* Enumeration for 11.2 kbps V13K Encoding mode. */ +#define ASM_MEDIA_FMT_V13K_FS_ENCODE_MODE_MR1120 2 + +/* Enumeration for 9.0 kbps V13K Encoding mode. */ +#define ASM_MEDIA_FMT_V13K_FS_ENCODE_MODE_MR90 3 + +/* Enumeration for 7.2 kbps V13K eEncoding mode. */ +#define ASM_MEDIA_FMT_V13K_FS_ENCODE_MODE_MR720 4 + +/* Enumeration for 1/8 vocoder rate.*/ +#define ASM_MEDIA_FMT_VOC_ONE_EIGHTH_RATE 1 + +/* Enumeration for 1/4 vocoder rate. */ +#define ASM_MEDIA_FMT_VOC_ONE_FOURTH_RATE 2 + +/* Enumeration for 1/2 vocoder rate. */ +#define ASM_MEDIA_FMT_VOC_HALF_RATE 3 + +/* Enumeration for full vocoder rate. */ +#define ASM_MEDIA_FMT_VOC_FULL_RATE 4 + +struct asm_v13k_enc_cfg { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + struct asm_enc_cfg_blk_param_v2 encblk; + u16 max_rate; +/* Maximum allowed encoder frame rate. + * Supported values: + * - #ASM_MEDIA_FMT_VOC_ONE_EIGHTH_RATE + * - #ASM_MEDIA_FMT_VOC_ONE_FOURTH_RATE + * - #ASM_MEDIA_FMT_VOC_HALF_RATE + * - #ASM_MEDIA_FMT_VOC_FULL_RATE + */ + + u16 min_rate; +/* Minimum allowed encoder frame rate. + * Supported values: + * - #ASM_MEDIA_FMT_VOC_ONE_EIGHTH_RATE + * - #ASM_MEDIA_FMT_VOC_ONE_FOURTH_RATE + * - #ASM_MEDIA_FMT_VOC_HALF_RATE + * - #ASM_MEDIA_FMT_VOC_FULL_RATE + */ + + u16 reduced_rate_cmd; +/* Reduced rate command, used to change + * the average bitrate of the V13K + * vocoder. + * Supported values: + * - #ASM_MEDIA_FMT_V13K_FS_ENCODE_MODE_MR1440 (Default) + * - #ASM_MEDIA_FMT_V13K_FS_ENCODE_MODE_MR1220 + * - #ASM_MEDIA_FMT_V13K_FS_ENCODE_MODE_MR1120 + * - #ASM_MEDIA_FMT_V13K_FS_ENCODE_MODE_MR90 + * - #ASM_MEDIA_FMT_V13K_FS_ENCODE_MODE_MR720 + */ + + u16 rate_mod_cmd; +/* Rate modulation command. Default = 0. + *- If bit 0=1, rate control is enabled. + *- If bit 1=1, the maximum number of consecutive full rate + * frames is limited with numbers supplied in + * bits 2 to 10. + *- If bit 1=0, the minimum number of non-full rate frames + * in between two full rate frames is forced to + * the number supplied in bits 2 to 10. In both cases, if necessary, + * half rate is used to substitute full rate. - Bits 15 to 10 are + * reserved and must all be set to zero. + */ + +} __packed; + +#define ASM_MEDIA_FMT_EVRC_FS 0x00010BEE + +/* EVRC encoder configuration structure used in the + * #ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2 command. + */ +struct asm_evrc_enc_cfg { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + struct asm_enc_cfg_blk_param_v2 encblk; + u16 max_rate; +/* Maximum allowed encoder frame rate. + * Supported values: + * - #ASM_MEDIA_FMT_VOC_ONE_EIGHTH_RATE + * - #ASM_MEDIA_FMT_VOC_ONE_FOURTH_RATE + * - #ASM_MEDIA_FMT_VOC_HALF_RATE + * - #ASM_MEDIA_FMT_VOC_FULL_RATE + */ + + u16 min_rate; +/* Minimum allowed encoder frame rate. + * Supported values: + * - #ASM_MEDIA_FMT_VOC_ONE_EIGHTH_RATE + * - #ASM_MEDIA_FMT_VOC_ONE_FOURTH_RATE + * - #ASM_MEDIA_FMT_VOC_HALF_RATE + * - #ASM_MEDIA_FMT_VOC_FULL_RATE + */ + + u16 rate_mod_cmd; +/* Rate modulation command. Default: 0. + * - If bit 0=1, rate control is enabled. + * - If bit 1=1, the maximum number of consecutive full rate frames + * is limited with numbers supplied in bits 2 to 10. + * + * - If bit 1=0, the minimum number of non-full rate frames in + * between two full rate frames is forced to the number supplied in + * bits 2 to 10. In both cases, if necessary, half rate is used to + * substitute full rate. + * + * - Bits 15 to 10 are reserved and must all be set to zero. + */ + + u16 reserved; + /* Reserved. Clients must set this field to zero. */ +} __packed; + +#define ASM_MEDIA_FMT_WMA_V10PRO_V2 0x00010DA7 + +struct asm_wmaprov10_fmt_blk_v2 { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmtblk; + + u16 fmtag; +/* WMA format type. + * Supported values: + * - 0x162 -- WMA 9 Pro + * - 0x163 -- WMA 9 Pro Lossless + * - 0x166 -- WMA 10 Pro + * - 0x167 -- WMA 10 Pro Lossless + */ + + u16 num_channels; +/* Number of channels encoded in the input stream. + * Supported values: 1 to 8 + */ + + u32 sample_rate; +/* Number of samples per second (in Hertz). + * Supported values: 11025, 16000, 22050, 32000, 44100, 48000, + * 88200, 96000 + */ + + u32 avg_bytes_per_sec; +/* Bitrate expressed as the average bytes per second. + * Supported values: 2000 to 96000 + */ + + u16 blk_align; +/* Size of the bitstream packet size in bytes. WMA Pro files + * have a payload of one block per bitstream packet. + * Supported values: @le 13376 + */ + + u16 bits_per_sample; +/* Number of bits per sample in the encoded WMA stream. + * Supported values: 16, 24 + */ + + u32 channel_mask; +/* Bit-packed double word (32-bits) that indicates the + * recommended speaker positions for each source channel. + */ + + u16 enc_options; +/* Bit-packed word with values that indicate whether certain + * features of the bitstream are used. + * Supported values: - 0x0001 -- ENCOPT3_PURE_LOSSLESS - 0x0006 -- + * ENCOPT3_FRM_SIZE_MOD - 0x0038 -- ENCOPT3_SUBFRM_DIV - 0x0040 -- + * ENCOPT3_WRITE_FRAMESIZE_IN_HDR - 0x0080 -- + * ENCOPT3_GENERATE_DRC_PARAMS - 0x0100 -- ENCOPT3_RTMBITS + */ + + + u16 usAdvancedEncodeOpt; + /* Advanced encoding option. */ + + u32 advanced_enc_options2; + /* Advanced encoding option 2. */ + +} __packed; + +#define ASM_MEDIA_FMT_WMA_V9_V2 0x00010DA8 +struct asm_wmastdv9_fmt_blk_v2 { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmtblk; + u16 fmtag; +/* WMA format tag. + * Supported values: 0x161 (WMA 9 standard) + */ + + u16 num_channels; +/* Number of channels in the stream. + * Supported values: 1, 2 + */ + + u32 sample_rate; +/* Number of samples per second (in Hertz). + * Supported values: 48000 + */ + + u32 avg_bytes_per_sec; + /* Bitrate expressed as the average bytes per second. */ + + u16 blk_align; +/* Block align. All WMA files with a maximum packet size of + * 13376 are supported. + */ + + + u16 bits_per_sample; +/* Number of bits per sample in the output. + * Supported values: 16 + */ + + u32 channel_mask; +/* Channel mask. + * Supported values: + * - 3 -- Stereo (front left/front right) + * - 4 -- Mono (center) + */ + + u16 enc_options; + /* Options used during encoding. */ + + u16 reserved; + +} __packed; + +#define ASM_MEDIA_FMT_WMA_V8 0x00010D91 + +struct asm_wmastdv8_enc_cfg { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + struct asm_enc_cfg_blk_param_v2 encblk; + u32 bit_rate; + /* Encoding rate in bits per second. */ + + u32 sample_rate; +/* Number of samples per second. + * + * Supported values: + * - 0 -- Native mode + * - Other Supported values are 22050, 32000, 44100, and 48000. + * + * Native mode indicates that encoding must be performed with the + * sampling rate at the input. + * The sampling rate must not change during encoding. + */ + + u16 channel_cfg; +/* Number of channels to encode. + * Supported values: + * - 0 -- Native mode + * - 1 -- Mono + * - 2 -- Stereo + * - Other values are not supported. + * + * Native mode indicates that encoding must be performed with the + * number of channels at the input. + * The number of channels must not change during encoding. + */ + + u16 reserved; + /* Reserved. Clients must set this field to zero.*/ + } __packed; + +#define ASM_MEDIA_FMT_AMR_WB_PLUS_V2 0x00010DA9 + +struct asm_amrwbplus_fmt_blk_v2 { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmtblk; + u32 amr_frame_fmt; +/* AMR frame format. + * Supported values: + * - 6 -- Transport Interface Format (TIF) + * - Any other value -- File storage format (FSF) + * + * TIF stream contains 2-byte header for each frame within the + * superframe. FSF stream contains one 2-byte header per superframe. + */ + +} __packed; + +#define ASM_MEDIA_FMT_AC3 0x00010DEE +#define ASM_MEDIA_FMT_EAC3 0x00010DEF +#define ASM_MEDIA_FMT_DTS 0x00010D88 +#define ASM_MEDIA_FMT_MP2 0x00010DE9 +#define ASM_MEDIA_FMT_FLAC 0x00010C16 +#define ASM_MEDIA_FMT_ALAC 0x00012F31 +#define ASM_MEDIA_FMT_VORBIS 0x00010C15 +#define ASM_MEDIA_FMT_APE 0x00012F32 +#define ASM_MEDIA_FMT_DSD 0x00012F3E +#define ASM_MEDIA_FMT_TRUEHD 0x00013215 +/* 0x0 is used for fomat ID since ADSP dynamically determines the + * format encapsulated in the IEC61937 (compressed) or IEC60958 + * (pcm) packets. + */ +#define ASM_MEDIA_FMT_IEC 0x00000000 + +/* Media format ID for adaptive transform acoustic coding. This + * ID is used by the #ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED command + * only. + */ + +#define ASM_MEDIA_FMT_ATRAC 0x00010D89 + +/* Media format ID for metadata-enhanced audio transmission. + * This ID is used by the #ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED + * command only. + */ + +#define ASM_MEDIA_FMT_MAT 0x00010D8A + +/* adsp_media_fmt.h */ + +#define ASM_DATA_CMD_WRITE_V2 0x00010DAB + +struct asm_data_cmd_write_v2 { + struct apr_hdr hdr; + u32 buf_addr_lsw; +/* The 64 bit address msw-lsw should be a valid, mapped address. + * 64 bit address should be a multiple of 32 bytes + */ + + u32 buf_addr_msw; +/* The 64 bit address msw-lsw should be a valid, mapped address. + * 64 bit address should be a multiple of 32 bytes. + * -Address of the buffer containing the data to be decoded. + * The buffer should be aligned to a 32 byte boundary. + * -In the case of 32 bit Shared memory address, msw field must + * -be set to zero. + * -In the case of 36 bit shared memory address, bit 31 to bit 4 + * -of msw must be set to zero. + */ + u32 mem_map_handle; +/* memory map handle returned by DSP through + * ASM_CMD_SHARED_MEM_MAP_REGIONS command + */ + u32 buf_size; +/* Number of valid bytes available in the buffer for decoding. The + * first byte starts at buf_addr. + */ + + u32 seq_id; + /* Optional buffer sequence ID. */ + + u32 timestamp_lsw; +/* Lower 32 bits of the 64-bit session time in microseconds of the + * first buffer sample. + */ + + u32 timestamp_msw; +/* Upper 32 bits of the 64-bit session time in microseconds of the + * first buffer sample. + */ + + u32 flags; +/* Bitfield of flags. + * Supported values for bit 31: + * - 1 -- Valid timestamp. + * - 0 -- Invalid timestamp. + * - Use #ASM_BIT_MASKIMESTAMP_VALID_FLAG as the bitmask and + * #ASM_SHIFTIMESTAMP_VALID_FLAG as the shift value to set this bit. + * Supported values for bit 30: + * - 1 -- Last buffer. + * - 0 -- Not the last buffer. + * + * Supported values for bit 29: + * - 1 -- Continue the timestamp from the previous buffer. + * - 0 -- Timestamp of the current buffer is not related + * to the timestamp of the previous buffer. + * - Use #ASM_BIT_MASKS_CONTINUE_FLAG and #ASM_SHIFTS_CONTINUE_FLAG + * to set this bit. + * + * Supported values for bit 4: + * - 1 -- End of the frame. + * - 0 -- Not the end of frame, or this information is not known. + * - Use #ASM_BIT_MASK_EOF_FLAG as the bitmask and #ASM_SHIFT_EOF_FLAG + * as the shift value to set this bit. + * + * All other bits are reserved and must be set to 0. + * + * If bit 31=0 and bit 29=1: The timestamp of the first sample in + * this buffer continues from the timestamp of the last sample in + * the previous buffer. If there is no previous buffer (i.e., this + * is the first buffer sent after opening the stream or after a + * flush operation), or if the previous buffer does not have a valid + * timestamp, the samples in the current buffer also do not have a + * valid timestamp. They are played out as soon as possible. + * + * + * If bit 31=0 and bit 29=0: No timestamp is associated with the + * first sample in this buffer. The samples are played out as soon + * as possible. + * + * + * If bit 31=1 and bit 29 is ignored: The timestamp specified in + * this payload is honored. + * + * + * If bit 30=0: Not the last buffer in the stream. This is useful + * in removing trailing samples. + * + * + * For bit 4: The client can set this flag for every buffer sent in + * which the last byte is the end of a frame. If this flag is set, + * the buffer can contain data from multiple frames, but it should + * always end at a frame boundary. Restrictions allow the aDSP to + * detect an end of frame without requiring additional processing. + */ + +} __packed; + +#define ASM_DATA_CMD_READ_V2 0x00010DAC + +struct asm_data_cmd_read_v2 { + struct apr_hdr hdr; + u32 buf_addr_lsw; +/* the 64 bit address msw-lsw should be a valid mapped address + * and should be a multiple of 32 bytes + */ + + + u32 buf_addr_msw; +/* the 64 bit address msw-lsw should be a valid mapped address + * and should be a multiple of 32 bytes. + * - Address of the buffer where the DSP puts the encoded data, + * potentially, at an offset specified by the uOffset field in + * ASM_DATA_EVENT_READ_DONE structure. The buffer should be aligned + * to a 32 byte boundary. + * - In the case of 32 bit Shared memory address, msw field must + * - be set to zero. + * - In the case of 36 bit shared memory address, bit 31 to bit + * - 4 of msw must be set to zero. + */ + u32 mem_map_handle; +/* memory map handle returned by DSP through + * ASM_CMD_SHARED_MEM_MAP_REGIONS command. + */ + + u32 buf_size; +/* Number of bytes available for the aDSP to write. The aDSP + * starts writing from buf_addr. + */ + + u32 seq_id; + /* Optional buffer sequence ID. */ +} __packed; + +#define ASM_DATA_CMD_EOS 0x00010BDB +#define ASM_DATA_EVENT_RENDERED_EOS 0x00010C1C +#define ASM_DATA_EVENT_EOS 0x00010BDD + +#define ASM_DATA_EVENT_WRITE_DONE_V2 0x00010D99 +struct asm_data_event_write_done_v2 { + u32 buf_addr_lsw; + /* lsw of the 64 bit address */ + u32 buf_addr_msw; + /* msw of the 64 bit address. address given by the client in + * ASM_DATA_CMD_WRITE_V2 command. + */ + u32 mem_map_handle; + /* memory map handle in the ASM_DATA_CMD_WRITE_V2 */ + + u32 status; +/* Status message (error code) that indicates whether the + * referenced buffer has been successfully consumed. + * Supported values: Refer to @xhyperref{Q3,[Q3]} + */ +} __packed; + +#define ASM_DATA_EVENT_READ_DONE_V2 0x00010D9A + +/* Definition of the frame metadata flag bitmask.*/ +#define ASM_BIT_MASK_FRAME_METADATA_FLAG (0x40000000UL) + +/* Definition of the frame metadata flag shift value. */ +#define ASM_SHIFT_FRAME_METADATA_FLAG 30 + +struct asm_data_event_read_done_v2 { + u32 status; +/* Status message (error code). + * Supported values: Refer to @xhyperref{Q3,[Q3]} + */ + +u32 buf_addr_lsw; +/* 64 bit address msw-lsw is a valid, mapped address. 64 bit + * address is a multiple of 32 bytes. + */ + +u32 buf_addr_msw; +/* 64 bit address msw-lsw is a valid, mapped address. 64 bit + * address is a multiple of 32 bytes. + * + * -Same address provided by the client in ASM_DATA_CMD_READ_V2 + * -In the case of 32 bit Shared memory address, msw field is set to + * zero. + * -In the case of 36 bit shared memory address, bit 31 to bit 4 + * -of msw is set to zero. + */ + +u32 mem_map_handle; +/* memory map handle in the ASM_DATA_CMD_READ_V2 */ + +u32 enc_framesotal_size; +/* Total size of the encoded frames in bytes. + * Supported values: >0 + */ + +u32 offset; +/* Offset (from buf_addr) to the first byte of the first encoded + * frame. All encoded frames are consecutive, starting from this + * offset. + * Supported values: > 0 + */ + +u32 timestamp_lsw; +/* Lower 32 bits of the 64-bit session time in microseconds of + * the first sample in the buffer. If Bit 5 of mode_flags flag of + * ASM_STREAM_CMD_OPEN_READ_V2 is 1 then the 64 bit timestamp is + * absolute capture time otherwise it is relative session time. The + * absolute timestamp doesn't reset unless the system is reset. + */ + + +u32 timestamp_msw; +/* Upper 32 bits of the 64-bit session time in microseconds of + * the first sample in the buffer. + */ + + +u32 flags; +/* Bitfield of flags. Bit 30 indicates whether frame metadata is + * present. If frame metadata is present, num_frames consecutive + * instances of @xhyperref{hdr:FrameMetaData,Frame metadata} start + * at the buffer address. + * Supported values for bit 31: + * - 1 -- Timestamp is valid. + * - 0 -- Timestamp is invalid. + * - Use #ASM_BIT_MASKIMESTAMP_VALID_FLAG and + * #ASM_SHIFTIMESTAMP_VALID_FLAG to set this bit. + * + * Supported values for bit 30: + * - 1 -- Frame metadata is present. + * - 0 -- Frame metadata is absent. + * - Use #ASM_BIT_MASK_FRAME_METADATA_FLAG and + * #ASM_SHIFT_FRAME_METADATA_FLAG to set this bit. + * + * All other bits are reserved; the aDSP sets them to 0. + */ + +u32 num_frames; +/* Number of encoded frames in the buffer. */ + +u32 seq_id; +/* Optional buffer sequence ID. */ +} __packed; + +struct asm_data_read_buf_metadata_v2 { + u32 offset; +/* Offset from buf_addr in #ASM_DATA_EVENT_READ_DONE_PAYLOAD to + * the frame associated with this metadata. + * Supported values: > 0 + */ + +u32 frm_size; +/* Size of the encoded frame in bytes. + * Supported values: > 0 + */ + +u32 num_encoded_pcm_samples; +/* Number of encoded PCM samples (per channel) in the frame + * associated with this metadata. + * Supported values: > 0 + */ + +u32 timestamp_lsw; +/* Lower 32 bits of the 64-bit session time in microseconds of the + * first sample for this frame. + * If Bit 5 of mode_flags flag of ASM_STREAM_CMD_OPEN_READ_V2 is 1 + * then the 64 bit timestamp is absolute capture time otherwise it + * is relative session time. The absolute timestamp doesn't reset + * unless the system is reset. + */ + + +u32 timestamp_msw; +/* Lower 32 bits of the 64-bit session time in microseconds of the + * first sample for this frame. + */ + +u32 flags; +/* Frame flags. + * Supported values for bit 31: + * - 1 -- Time stamp is valid + * - 0 -- Time stamp is not valid + * - All other bits are reserved; the aDSP sets them to 0. + */ +} __packed; + +/* Notifies the client of a change in the data sampling rate or + * Channel mode. This event is raised by the decoder service. The + * event is enabled through the mode flags of + * #ASM_STREAM_CMD_OPEN_WRITE_V2 or + * #ASM_STREAM_CMD_OPEN_READWRITE_V2. - The decoder detects a change + * in the output sampling frequency or the number/positioning of + * output channels, or if it is the first frame decoded.The new + * sampling frequency or the new channel configuration is + * communicated back to the client asynchronously. + */ + +#define ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY 0x00010C65 + +/* Payload of the #ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY event. + * This event is raised when the following conditions are both true: + * - The event is enabled through the mode_flags of + * #ASM_STREAM_CMD_OPEN_WRITE_V2 or + * #ASM_STREAM_CMD_OPEN_READWRITE_V2. - The decoder detects a change + * in either the output sampling frequency or the number/positioning + * of output channels, or if it is the first frame decoded. + * This event is not raised (even if enabled) if the decoder is + * MIDI, because + */ + + +struct asm_data_event_sr_cm_change_notify { + u32 sample_rate; +/* New sampling rate (in Hertz) after detecting a change in the + * bitstream. + * Supported values: 2000 to 48000 + */ + + u16 num_channels; +/* New number of channels after detecting a change in the + * bitstream. + * Supported values: 1 to 8 + */ + + + u16 reserved; + /* Reserved for future use. This field must be set to 0.*/ + + u8 channel_mapping[8]; + +} __packed; + +/* Notifies the client of a data sampling rate or channel mode + * change. This event is raised by the encoder service. + * This event is raised when : + * - Native mode encoding was requested in the encoder + * configuration (i.e., the channel number was 0), the sample rate + * was 0, or both were 0. + * + * - The input data frame at the encoder is the first one, or the + * sampling rate/channel mode is different from the previous input + * data frame. + * + */ +#define ASM_DATA_EVENT_ENC_SR_CM_CHANGE_NOTIFY 0x00010BDE + +struct asm_data_event_enc_sr_cm_change_notify { + u32 sample_rate; +/* New sampling rate (in Hertz) after detecting a change in the + * input data. + * Supported values: 2000 to 48000 + */ + + + u16 num_channels; +/* New number of channels after detecting a change in the input + * data. Supported values: 1 to 8 + */ + + + u16 bits_per_sample; +/* New bits per sample after detecting a change in the input + * data. + * Supported values: 16, 24 + */ + + + u8 channel_mapping[8]; + +} __packed; +#define ASM_DATA_CMD_IEC_60958_FRAME_RATE 0x00010D87 + + +/* Payload of the #ASM_DATA_CMD_IEC_60958_FRAME_RATE command, + * which is used to indicate the IEC 60958 frame rate of a given + * packetized audio stream. + */ + +struct asm_data_cmd_iec_60958_frame_rate { + u32 frame_rate; +/* IEC 60958 frame rate of the incoming IEC 61937 packetized stream. + * Supported values: Any valid frame rate + */ +} __packed; + +/* adsp_asm_data_commands.h*/ +/* Definition of the stream ID bitmask.*/ +#define ASM_BIT_MASK_STREAM_ID (0x000000FFUL) + +/* Definition of the stream ID shift value.*/ +#define ASM_SHIFT_STREAM_ID 0 + +/* Definition of the session ID bitmask.*/ +#define ASM_BIT_MASK_SESSION_ID (0x0000FF00UL) + +/* Definition of the session ID shift value.*/ +#define ASM_SHIFT_SESSION_ID 8 + +/* Definition of the service ID bitmask.*/ +#define ASM_BIT_MASK_SERVICE_ID (0x00FF0000UL) + +/* Definition of the service ID shift value.*/ +#define ASM_SHIFT_SERVICE_ID 16 + +/* Definition of the domain ID bitmask.*/ +#define ASM_BIT_MASK_DOMAIN_ID (0xFF000000UL) + +/* Definition of the domain ID shift value.*/ +#define ASM_SHIFT_DOMAIN_ID 24 + +#define ASM_CMD_SHARED_MEM_MAP_REGIONS 0x00010D92 +#define ASM_CMDRSP_SHARED_MEM_MAP_REGIONS 0x00010D93 +#define ASM_CMD_SHARED_MEM_UNMAP_REGIONS 0x00010D94 + +/* adsp_asm_service_commands.h */ + +#define ASM_MAX_SESSION_ID (15) + +/* Maximum number of sessions.*/ +#define ASM_MAX_NUM_SESSIONS ASM_MAX_SESSION_ID + +/* Maximum number of streams per session.*/ +#define ASM_MAX_STREAMS_PER_SESSION (8) +#define ASM_SESSION_CMD_RUN_V2 0x00010DAA +#define ASM_SESSION_CMD_RUN_STARTIME_RUN_IMMEDIATE 0 +#define ASM_SESSION_CMD_RUN_STARTIME_RUN_AT_ABSOLUTEIME 1 +#define ASM_SESSION_CMD_RUN_STARTIME_RUN_AT_RELATIVEIME 2 +#define ASM_SESSION_CMD_RUN_STARTIME_RUN_WITH_DELAY 3 + +#define ASM_BIT_MASK_RUN_STARTIME (0x00000003UL) + +/* Bit shift value used to specify the start time for the + * ASM_SESSION_CMD_RUN_V2 command. + */ +#define ASM_SHIFT_RUN_STARTIME 0 +struct asm_session_cmd_run_v2 { + struct apr_hdr hdr; + u32 flags; +/* Specifies whether to run immediately or at a specific + * rendering time or with a specified delay. Run with delay is + * useful for delaying in case of ASM loopback opened through + * ASM_STREAM_CMD_OPEN_LOOPBACK_V2. Use #ASM_BIT_MASK_RUN_STARTIME + * and #ASM_SHIFT_RUN_STARTIME to set this 2-bit flag. + * + * + *Bits 0 and 1 can take one of four possible values: + * + *- #ASM_SESSION_CMD_RUN_STARTIME_RUN_IMMEDIATE + *- #ASM_SESSION_CMD_RUN_STARTIME_RUN_AT_ABSOLUTEIME + *- #ASM_SESSION_CMD_RUN_STARTIME_RUN_AT_RELATIVEIME + *- #ASM_SESSION_CMD_RUN_STARTIME_RUN_WITH_DELAY + * + *All other bits are reserved; clients must set them to zero. + */ + + u32 time_lsw; +/* Lower 32 bits of the time in microseconds used to align the + * session origin time. When bits 0-1 of flags is + * ASM_SESSION_CMD_RUN_START_RUN_WITH_DELAY, time lsw is the lsw of + * the delay in us. For ASM_SESSION_CMD_RUN_START_RUN_WITH_DELAY, + * maximum value of the 64 bit delay is 150 ms. + */ + + u32 time_msw; +/* Upper 32 bits of the time in microseconds used to align the + * session origin time. When bits 0-1 of flags is + * ASM_SESSION_CMD_RUN_START_RUN_WITH_DELAY, time msw is the msw of + * the delay in us. For ASM_SESSION_CMD_RUN_START_RUN_WITH_DELAY, + * maximum value of the 64 bit delay is 150 ms. + */ + +} __packed; + +#define ASM_SESSION_CMD_PAUSE 0x00010BD3 +#define ASM_SESSION_CMD_SUSPEND 0x00010DEC +#define ASM_SESSION_CMD_GET_SESSIONTIME_V3 0x00010D9D +#define ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS 0x00010BD5 + +struct asm_session_cmd_rgstr_rx_underflow { + struct apr_hdr hdr; + u16 enable_flag; +/* Specifies whether a client is to receive events when an Rx + * session underflows. + * Supported values: + * - 0 -- Do not send underflow events + * - 1 -- Send underflow events + */ + u16 reserved; + /* Reserved. This field must be set to zero.*/ +} __packed; + +#define ASM_SESSION_CMD_REGISTER_FORX_OVERFLOW_EVENTS 0x00010BD6 + +struct asm_session_cmd_regx_overflow { + struct apr_hdr hdr; + u16 enable_flag; +/* Specifies whether a client is to receive events when a Tx + * session overflows. + * Supported values: + * - 0 -- Do not send overflow events + * - 1 -- Send overflow events + */ + + u16 reserved; + /* Reserved. This field must be set to zero.*/ +} __packed; + +#define ASM_SESSION_EVENT_RX_UNDERFLOW 0x00010C17 +#define ASM_SESSION_EVENTX_OVERFLOW 0x00010C18 +#define ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3 0x00010D9E + +struct asm_session_cmdrsp_get_sessiontime_v3 { + u32 status; + /* Status message (error code). + * Supported values: Refer to @xhyperref{Q3,[Q3]} + */ + + u32 sessiontime_lsw; + /* Lower 32 bits of the current session time in microseconds.*/ + + u32 sessiontime_msw; + /* Upper 32 bits of the current session time in microseconds.*/ + + u32 absolutetime_lsw; +/* Lower 32 bits in micro seconds of the absolute time at which + * the * sample corresponding to the above session time gets + * rendered * to hardware. This absolute time may be slightly in the + * future or past. + */ + + + u32 absolutetime_msw; +/* Upper 32 bits in micro seconds of the absolute time at which + * the * sample corresponding to the above session time gets + * rendered to * hardware. This absolute time may be slightly in the + * future or past. + */ + +} __packed; + +#define ASM_SESSION_CMD_ADJUST_SESSION_CLOCK_V2 0x00010D9F + +struct asm_session_cmd_adjust_session_clock_v2 { + struct apr_hdr hdr; +u32 adjustime_lsw; +/* Lower 32 bits of the signed 64-bit quantity that specifies the + * adjustment time in microseconds to the session clock. + * + * Positive values indicate advancement of the session clock. + * Negative values indicate delay of the session clock. + */ + + + u32 adjustime_msw; +/* Upper 32 bits of the signed 64-bit quantity that specifies + * the adjustment time in microseconds to the session clock. + * Positive values indicate advancement of the session clock. + * Negative values indicate delay of the session clock. + */ + +} __packed; + +#define ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2 0x00010DA0 + +struct asm_session_cmdrsp_adjust_session_clock_v2 { + u32 status; +/* Status message (error code). + * Supported values: Refer to @xhyperref{Q3,[Q3]} + * An error means the session clock is not adjusted. In this case, + * the next two fields are irrelevant. + */ + + + u32 actual_adjustime_lsw; +/* Lower 32 bits of the signed 64-bit quantity that specifies + * the actual adjustment in microseconds performed by the aDSP. + * A positive value indicates advancement of the session clock. A + * negative value indicates delay of the session clock. + */ + + + u32 actual_adjustime_msw; +/* Upper 32 bits of the signed 64-bit quantity that specifies + * the actual adjustment in microseconds performed by the aDSP. + * A positive value indicates advancement of the session clock. A + * negative value indicates delay of the session clock. + */ + + + u32 cmd_latency_lsw; +/* Lower 32 bits of the unsigned 64-bit quantity that specifies + * the amount of time in microseconds taken to perform the session + * clock adjustment. + */ + + + u32 cmd_latency_msw; +/* Upper 32 bits of the unsigned 64-bit quantity that specifies + * the amount of time in microseconds taken to perform the session + * clock adjustment. + */ + +} __packed; + +#define ASM_SESSION_CMD_GET_PATH_DELAY_V2 0x00010DAF +#define ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2 0x00010DB0 + +struct asm_session_cmdrsp_get_path_delay_v2 { + u32 status; +/* Status message (error code). Whether this get delay operation + * is successful or not. Delay value is valid only if status is + * success. + * Supported values: Refer to @xhyperref{Q5,[Q5]} + */ + + u32 audio_delay_lsw; + /* Upper 32 bits of the aDSP delay in microseconds. */ + + u32 audio_delay_msw; + /* Lower 32 bits of the aDSP delay in microseconds. */ + +} __packed; + +/* adsp_asm_session_command.h*/ +#define ASM_STREAM_CMD_OPEN_WRITE_V3 0x00010DB3 + +#define ASM_LOW_LATENCY_STREAM_SESSION 0x10000000 + +#define ASM_ULTRA_LOW_LATENCY_STREAM_SESSION 0x20000000 + +#define ASM_ULL_POST_PROCESSING_STREAM_SESSION 0x40000000 + +#define ASM_LEGACY_STREAM_SESSION 0 + + +struct asm_stream_cmd_open_write_v3 { + struct apr_hdr hdr; + uint32_t mode_flags; +/* Mode flags that configure the stream to notify the client + * whenever it detects an SR/CM change at the input to its POPP. + * Supported values for bits 0 to 1: + * - Reserved; clients must set them to zero. + * Supported values for bit 2: + * - 0 -- SR/CM change notification event is disabled. + * - 1 -- SR/CM change notification event is enabled. + * - Use #ASM_BIT_MASK_SR_CM_CHANGE_NOTIFY_FLAG and + * #ASM_SHIFT_SR_CM_CHANGE_NOTIFY_FLAG to set or get this bit. + * + * Supported values for bit 31: + * - 0 -- Stream to be opened in on-Gapless mode. + * - 1 -- Stream to be opened in Gapless mode. In Gapless mode, + * successive streams must be opened with same session ID but + * different stream IDs. + * + * - Use #ASM_BIT_MASK_GAPLESS_MODE_FLAG and + * #ASM_SHIFT_GAPLESS_MODE_FLAG to set or get this bit. + * + * + * @note1hang MIDI and DTMF streams cannot be opened in Gapless mode. + */ + + uint16_t sink_endpointype; +/*< Sink point type. + * Supported values: + * - 0 -- Device matrix + * - Other values are reserved. + * + * The device matrix is the gateway to the hardware ports. + */ + + uint16_t bits_per_sample; +/*< Number of bits per sample processed by ASM modules. + * Supported values: 16 and 24 bits per sample + */ + + uint32_t postprocopo_id; +/*< Specifies the topology (order of processing) of + * postprocessing algorithms. None means no postprocessing. + * Supported values: + * - #ASM_STREAM_POSTPROCOPO_ID_DEFAULT + * - #ASM_STREAM_POSTPROCOPO_ID_MCH_PEAK_VOL + * - #ASM_STREAM_POSTPROCOPO_ID_NONE + * + * This field can also be enabled through SetParams flags. + */ + + uint32_t dec_fmt_id; +/*< Configuration ID of the decoder media format. + * + * Supported values: + * - #ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2 + * - #ASM_MEDIA_FMT_ADPCM + * - #ASM_MEDIA_FMT_MP3 + * - #ASM_MEDIA_FMT_AAC_V2 + * - #ASM_MEDIA_FMT_DOLBY_AAC + * - #ASM_MEDIA_FMT_AMRNB_FS + * - #ASM_MEDIA_FMT_AMRWB_FS + * - #ASM_MEDIA_FMT_AMR_WB_PLUS_V2 + * - #ASM_MEDIA_FMT_V13K_FS + * - #ASM_MEDIA_FMT_EVRC_FS + * - #ASM_MEDIA_FMT_EVRCB_FS + * - #ASM_MEDIA_FMT_EVRCWB_FS + * - #ASM_MEDIA_FMT_SBC + * - #ASM_MEDIA_FMT_WMA_V10PRO_V2 + * - #ASM_MEDIA_FMT_WMA_V9_V2 + * - #ASM_MEDIA_FMT_AC3 + * - #ASM_MEDIA_FMT_EAC3 + * - #ASM_MEDIA_FMT_G711_ALAW_FS + * - #ASM_MEDIA_FMT_G711_MLAW_FS + * - #ASM_MEDIA_FMT_G729A_FS + * - #ASM_MEDIA_FMT_FR_FS + * - #ASM_MEDIA_FMT_VORBIS + * - #ASM_MEDIA_FMT_FLAC + * - #ASM_MEDIA_FMT_ALAC + * - #ASM_MEDIA_FMT_APE + * - #ASM_MEDIA_FMT_EXAMPLE + */ +} __packed; + +#define ASM_STREAM_CMD_OPEN_PULL_MODE_WRITE 0x00010DD9 + +/* Bitmask for the stream_perf_mode subfield. */ +#define ASM_BIT_MASK_STREAM_PERF_FLAG_PULL_MODE_WRITE 0xE0000000UL + +/* Bitmask for the stream_perf_mode subfield. */ +#define ASM_SHIFT_STREAM_PERF_FLAG_PULL_MODE_WRITE 29 + +#define ASM_STREAM_CMD_OPEN_PUSH_MODE_READ 0x00010DDA + +#define ASM_BIT_MASK_STREAM_PERF_FLAG_PUSH_MODE_READ 0xE0000000UL + +#define ASM_SHIFT_STREAM_PERF_FLAG_PUSH_MODE_READ 29 + +#define ASM_DATA_EVENT_WATERMARK 0x00010DDB + +struct asm_shared_position_buffer { + volatile uint32_t frame_counter; +/* Counter used to handle interprocessor synchronization issues. + * When frame_counter is 0: read_index, wall_clock_us_lsw, and + * wall_clock_us_msw are invalid. + * Supported values: >= 0. + */ + + volatile uint32_t index; +/* Index in bytes from where the aDSP is reading/writing. + * Supported values: 0 to circular buffer size - 1 + */ + + volatile uint32_t wall_clock_us_lsw; +/* Lower 32 bits of the 64-bit wall clock time in microseconds when the + * read index was updated. + * Supported values: >= 0 + */ + + volatile uint32_t wall_clock_us_msw; +/* Upper 32 bits of the 64 bit wall clock time in microseconds when the + * read index was updated + * Supported values: >= 0 + */ +} __packed; + +struct asm_shared_watermark_level { + uint32_t watermark_level_bytes; +} __packed; + +struct asm_stream_cmd_open_shared_io { + struct apr_hdr hdr; + uint32_t mode_flags; + uint16_t endpoint_type; + uint16_t topo_bits_per_sample; + uint32_t topo_id; + uint32_t fmt_id; + uint32_t shared_pos_buf_phy_addr_lsw; + uint32_t shared_pos_buf_phy_addr_msw; + uint16_t shared_pos_buf_mem_pool_id; + uint16_t shared_pos_buf_num_regions; + uint32_t shared_pos_buf_property_flag; + uint32_t shared_circ_buf_start_phy_addr_lsw; + uint32_t shared_circ_buf_start_phy_addr_msw; + uint32_t shared_circ_buf_size; + uint16_t shared_circ_buf_mem_pool_id; + uint16_t shared_circ_buf_num_regions; + uint32_t shared_circ_buf_property_flag; + uint32_t num_watermark_levels; + struct asm_multi_channel_pcm_fmt_blk_v3 fmt; + struct avs_shared_map_region_payload map_region_pos_buf; + struct avs_shared_map_region_payload map_region_circ_buf; + struct asm_shared_watermark_level watermark[0]; +} __packed; + +#define ASM_STREAM_CMD_OPEN_READ_V3 0x00010DB4 + +/* Definition of the timestamp type flag bitmask */ +#define ASM_BIT_MASKIMESTAMPYPE_FLAG (0x00000020UL) + +/* Definition of the timestamp type flag shift value. */ +#define ASM_SHIFTIMESTAMPYPE_FLAG 5 + +/* Relative timestamp is identified by this value.*/ +#define ASM_RELATIVEIMESTAMP 0 + +/* Absolute timestamp is identified by this value.*/ +#define ASM_ABSOLUTEIMESTAMP 1 + +/* Bit value for Low Latency Tx stream subfield */ +#define ASM_LOW_LATENCY_TX_STREAM_SESSION 1 + +/* Bit shift for the stream_perf_mode subfield. */ +#define ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ 29 + +struct asm_stream_cmd_open_read_v3 { + struct apr_hdr hdr; + u32 mode_flags; +/* Mode flags that indicate whether meta information per encoded + * frame is to be provided. + * Supported values for bit 4: + * + * - 0 -- Return data buffer contains all encoded frames only; it + * does not contain frame metadata. + * + * - 1 -- Return data buffer contains an array of metadata and + * encoded frames. + * + * - Use #ASM_BIT_MASK_META_INFO_FLAG as the bitmask and + * #ASM_SHIFT_META_INFO_FLAG as the shift value for this bit. + * + * + * Supported values for bit 5: + * + * - ASM_RELATIVEIMESTAMP -- ASM_DATA_EVENT_READ_DONE_V2 will have + * - relative time-stamp. + * - ASM_ABSOLUTEIMESTAMP -- ASM_DATA_EVENT_READ_DONE_V2 will + * - have absolute time-stamp. + * + * - Use #ASM_BIT_MASKIMESTAMPYPE_FLAG as the bitmask and + * #ASM_SHIFTIMESTAMPYPE_FLAG as the shift value for this bit. + * + * All other bits are reserved; clients must set them to zero. + */ + + u32 src_endpointype; +/* Specifies the endpoint providing the input samples. + * Supported values: + * - 0 -- Device matrix + * - All other values are reserved; clients must set them to zero. + * Otherwise, an error is returned. + * The device matrix is the gateway from the tunneled Tx ports. + */ + + u32 preprocopo_id; +/* Specifies the topology (order of processing) of preprocessing + * algorithms. None means no preprocessing. + * Supported values: + * - #ASM_STREAM_PREPROCOPO_ID_DEFAULT + * - #ASM_STREAM_PREPROCOPO_ID_NONE + * + * This field can also be enabled through SetParams flags. + */ + + u32 enc_cfg_id; +/* Media configuration ID for encoded output. + * Supported values: + * - #ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2 + * - #ASM_MEDIA_FMT_AAC_V2 + * - #ASM_MEDIA_FMT_AMRNB_FS + * - #ASM_MEDIA_FMT_AMRWB_FS + * - #ASM_MEDIA_FMT_V13K_FS + * - #ASM_MEDIA_FMT_EVRC_FS + * - #ASM_MEDIA_FMT_EVRCB_FS + * - #ASM_MEDIA_FMT_EVRCWB_FS + * - #ASM_MEDIA_FMT_SBC + * - #ASM_MEDIA_FMT_G711_ALAW_FS + * - #ASM_MEDIA_FMT_G711_MLAW_FS + * - #ASM_MEDIA_FMT_G729A_FS + * - #ASM_MEDIA_FMT_EXAMPLE + * - #ASM_MEDIA_FMT_WMA_V8 + */ + + u16 bits_per_sample; +/* Number of bits per sample processed by ASM modules. + * Supported values: 16 and 24 bits per sample + */ + + u16 reserved; +/* Reserved for future use. This field must be set to zero.*/ +} __packed; + +#define ASM_POPP_OUTPUT_SR_NATIVE_RATE 0 + +/* Enumeration for the maximum sampling rate at the POPP output.*/ +#define ASM_POPP_OUTPUT_SR_MAX_RATE 48000 + +#define ASM_STREAM_CMD_OPEN_READWRITE_V2 0x00010D8D +#define ASM_STREAM_CMD_OPEN_READWRITE_V2 0x00010D8D + +struct asm_stream_cmd_open_readwrite_v2 { + struct apr_hdr hdr; + u32 mode_flags; +/* Mode flags. + * Supported values for bit 2: + * - 0 -- SR/CM change notification event is disabled. + * - 1 -- SR/CM change notification event is enabled. Use + * #ASM_BIT_MASK_SR_CM_CHANGE_NOTIFY_FLAG and + * #ASM_SHIFT_SR_CM_CHANGE_NOTIFY_FLAG to set or + * getting this flag. + * + * Supported values for bit 4: + * - 0 -- Return read data buffer contains all encoded frames only; it + * does not contain frame metadata. + * - 1 -- Return read data buffer contains an array of metadata and + * encoded frames. + * + * All other bits are reserved; clients must set them to zero. + */ + + u32 postprocopo_id; +/* Specifies the topology (order of processing) of postprocessing + * algorithms. None means no postprocessing. + * + * Supported values: + * - #ASM_STREAM_POSTPROCOPO_ID_DEFAULT + * - #ASM_STREAM_POSTPROCOPO_ID_MCH_PEAK_VOL + * - #ASM_STREAM_POSTPROCOPO_ID_NONE + */ + + u32 dec_fmt_id; +/* Specifies the media type of the input data. PCM indicates that + * no decoding must be performed, e.g., this is an NT encoder + * session. + * Supported values: + * - #ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2 + * - #ASM_MEDIA_FMT_ADPCM + * - #ASM_MEDIA_FMT_MP3 + * - #ASM_MEDIA_FMT_AAC_V2 + * - #ASM_MEDIA_FMT_DOLBY_AAC + * - #ASM_MEDIA_FMT_AMRNB_FS + * - #ASM_MEDIA_FMT_AMRWB_FS + * - #ASM_MEDIA_FMT_V13K_FS + * - #ASM_MEDIA_FMT_EVRC_FS + * - #ASM_MEDIA_FMT_EVRCB_FS + * - #ASM_MEDIA_FMT_EVRCWB_FS + * - #ASM_MEDIA_FMT_SBC + * - #ASM_MEDIA_FMT_WMA_V10PRO_V2 + * - #ASM_MEDIA_FMT_WMA_V9_V2 + * - #ASM_MEDIA_FMT_AMR_WB_PLUS_V2 + * - #ASM_MEDIA_FMT_AC3 + * - #ASM_MEDIA_FMT_G711_ALAW_FS + * - #ASM_MEDIA_FMT_G711_MLAW_FS + * - #ASM_MEDIA_FMT_G729A_FS + * - #ASM_MEDIA_FMT_EXAMPLE + */ + + u32 enc_cfg_id; +/* Specifies the media type for the output of the stream. PCM + * indicates that no encoding must be performed, e.g., this is an NT + * decoder session. + * Supported values: + * - #ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2 + * - #ASM_MEDIA_FMT_AAC_V2 + * - #ASM_MEDIA_FMT_AMRNB_FS + * - #ASM_MEDIA_FMT_AMRWB_FS + * - #ASM_MEDIA_FMT_V13K_FS + * - #ASM_MEDIA_FMT_EVRC_FS + * - #ASM_MEDIA_FMT_EVRCB_FS + * - #ASM_MEDIA_FMT_EVRCWB_FS + * - #ASM_MEDIA_FMT_SBC + * - #ASM_MEDIA_FMT_G711_ALAW_FS + * - #ASM_MEDIA_FMT_G711_MLAW_FS + * - #ASM_MEDIA_FMT_G729A_FS + * - #ASM_MEDIA_FMT_EXAMPLE + * - #ASM_MEDIA_FMT_WMA_V8 + */ + + u16 bits_per_sample; +/* Number of bits per sample processed by ASM modules. + * Supported values: 16 and 24 bits per sample + */ + + u16 reserved; +/* Reserved for future use. This field must be set to zero.*/ + +} __packed; + +#define ASM_STREAM_CMD_OPEN_LOOPBACK_V2 0x00010D8E +struct asm_stream_cmd_open_loopback_v2 { + struct apr_hdr hdr; + u32 mode_flags; +/* Mode flags. + * Bit 0-31: reserved; client should set these bits to 0 + */ + u16 src_endpointype; + /* Endpoint type. 0 = Tx Matrix */ + u16 sink_endpointype; + /* Endpoint type. 0 = Rx Matrix */ + u32 postprocopo_id; +/* Postprocessor topology ID. Specifies the topology of + * postprocessing algorithms. + */ + + u16 bits_per_sample; +/* The number of bits per sample processed by ASM modules + * Supported values: 16 and 24 bits per sample + */ + u16 reserved; +/* Reserved for future use. This field must be set to zero. */ +} __packed; + + +#define ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK 0x00010DBA + +/* Bitmask for the stream's Performance mode. */ +#define ASM_BIT_MASK_STREAM_PERF_MODE_FLAG_IN_OPEN_TRANSCODE_LOOPBACK \ + (0x70000000UL) + +/* Bit shift for the stream's Performance mode. */ +#define ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_TRANSCODE_LOOPBACK 28 + +/* Bitmask for the decoder converter enable flag. */ +#define ASM_BIT_MASK_DECODER_CONVERTER_FLAG (0x00000078UL) + +/* Shift value for the decoder converter enable flag. */ +#define ASM_SHIFT_DECODER_CONVERTER_FLAG 3 + +/* Converter mode is None (Default). */ +#define ASM_CONVERTER_MODE_NONE 0 + +/* Converter mode is DDP-to-DD. */ +#define ASM_DDP_DD_CONVERTER_MODE 1 + +/* Identifies a special converter mode where source and sink formats + * are the same but postprocessing must applied. Therefore, Decode + * @rarrow Re-encode is necessary. + */ +#define ASM_POST_PROCESS_CONVERTER_MODE 2 + + +struct asm_stream_cmd_open_transcode_loopback_t { + struct apr_hdr hdr; + u32 mode_flags; +/* Mode Flags specifies the performance mode in which this stream + * is to be opened. + * Supported values{for bits 30 to 28}(stream_perf_mode flag) + * + * #ASM_LEGACY_STREAM_SESSION -- This mode ensures backward + * compatibility to the original behavior + * of ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK + * + * #ASM_LOW_LATENCY_STREAM_SESSION -- Opens a loopback session by using + * shortened buffers in low latency POPP + * - Recommendation: Do not enable high latency algorithms. They might + * negate the benefits of opening a low latency stream, and they + * might also suffer quality degradation from unexpected jitter. + * - This Low Latency mode is supported only for PCM In and PCM Out + * loopbacks. An error is returned if Low Latency mode is opened for + * other transcode loopback modes. + * - To configure this subfield, use + * ASM_BIT_MASK_STREAM_PERF_MODE_FLAG_IN_OPEN_TRANSCODE_LOOPBACK and + * ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_TRANSCODE_LOOPBACK. + * + * Supported values{for bits 6 to 3} (decoder-converter compatibility) + * #ASM_CONVERTER_MODE_NONE (0x0) -- Default + * #ASM_DDP_DD_CONVERTER_MODE (0x1) + * #ASM_POST_PROCESS_CONVERTER_MODE (0x2) + * 0x3-0xF -- Reserved for future use + * - Use #ASM_BIT_MASK_DECODER_CONVERTER_FLAG and + * ASM_SHIFT_DECODER_CONVERTER_FLAG to set this bit + * All other bits are reserved; clients must set them to 0. + */ + + u32 src_format_id; +/* Specifies the media format of the input audio stream. + * + * Supported values + * - #ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2 + * - #ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3 + * - #ASM_MEDIA_FMT_DTS + * - #ASM_MEDIA_FMT_EAC3_DEC + * - #ASM_MEDIA_FMT_EAC3 + * - #ASM_MEDIA_FMT_AC3_DEC + * - #ASM_MEDIA_FMT_AC3 + */ + u32 sink_format_id; +/* Specifies the media format of the output stream. + * + * Supported values + * - #ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2 + * - #ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3 + * - #ASM_MEDIA_FMT_DTS (not supported in Low Latency mode) + * - #ASM_MEDIA_FMT_EAC3_DEC (not supported in Low Latency mode) + * - #ASM_MEDIA_FMT_EAC3 (not supported in Low Latency mode) + * - #ASM_MEDIA_FMT_AC3_DEC (not supported in Low Latency mode) + * - #ASM_MEDIA_FMT_AC3 (not supported in Low Latency mode) + */ + + u32 audproc_topo_id; +/* Postprocessing topology ID, which specifies the topology (order of + * processing) of postprocessing algorithms. + * + * Supported values + * - #ASM_STREAM_POSTPROC_TOPO_ID_DEFAULT + * - #ASM_STREAM_POSTPROC_TOPO_ID_PEAKMETER + * - #ASM_STREAM_POSTPROC_TOPO_ID_MCH_PEAK_VOL + * - #ASM_STREAM_POSTPROC_TOPO_ID_NONE + * Topologies can be added through #ASM_CMD_ADD_TOPOLOGIES. + * This field is ignored for the Converter mode, in which no + * postprocessing is performed. + */ + + u16 src_endpoint_type; +/* Specifies the source endpoint that provides the input samples. + * + * Supported values + * - 0 -- Tx device matrix or stream router (gateway to the hardware + * ports) + * - All other values are reserved + * Clients must set this field to 0. Otherwise, an error is returned. + */ + + u16 sink_endpoint_type; +/* Specifies the sink endpoint type. + * + * Supported values + * - 0 -- Rx device matrix or stream router (gateway to the hardware + * ports) + * - All other values are reserved + * Clients must set this field to 0. Otherwise, an error is returned. + */ + + u16 bits_per_sample; +/* Number of bits per sample processed by the ASM modules. + * Supported values 16, 24 + */ + + u16 reserved; +/* This field must be set to 0. + */ +} __packed; + + +#define ASM_STREAM_CMD_CLOSE 0x00010BCD +#define ASM_STREAM_CMD_FLUSH 0x00010BCE + + +#define ASM_STREAM_CMD_FLUSH_READBUFS 0x00010C09 +#define ASM_STREAM_CMD_SET_PP_PARAMS_V2 0x00010DA1 + +struct asm_stream_cmd_set_pp_params_v2 { + u32 data_payload_addr_lsw; +/* LSW of parameter data payload address. Supported values: any. */ + u32 data_payload_addr_msw; +/* MSW of Parameter data payload address. Supported values: any. + * - Must be set to zero for in-band data. + * - In the case of 32 bit Shared memory address, msw field must be + * - set to zero. + * - In the case of 36 bit shared memory address, bit 31 to bit 4 of + * msw + * + * - must be set to zero. + */ + u32 mem_map_handle; +/* Supported Values: Any. + * memory map handle returned by DSP through + * ASM_CMD_SHARED_MEM_MAP_REGIONS + * command. + * if mmhandle is NULL, the ParamData payloads are within the + * message payload (in-band). + * If mmhandle is non-NULL, the ParamData payloads begin at the + * address specified in the address msw and lsw (out-of-band). + */ + + u32 data_payload_size; +/* Size in bytes of the variable payload accompanying the + * message, or in shared memory. This field is used for parsing the + * parameter payload. + */ +} __packed; + + +struct asm_stream_param_data_v2 { + u32 module_id; + /* Unique module ID. */ + + u32 param_id; + /* Unique parameter ID. */ + + u16 param_size; +/* Data size of the param_id/module_id combination. This is + * a multiple of 4 bytes. + */ + + u16 reserved; +/* Reserved for future enhancements. This field must be set to + * zero. + */ + +} __packed; + +#define ASM_STREAM_CMD_GET_PP_PARAMS_V2 0x00010DA2 + +struct asm_stream_cmd_get_pp_params_v2 { + u32 data_payload_addr_lsw; + /* LSW of the parameter data payload address. */ + u32 data_payload_addr_msw; +/* MSW of the parameter data payload address. + * - Size of the shared memory, if specified, shall be large enough + * to contain the whole ParamData payload, including Module ID, + * Param ID, Param Size, and Param Values + * - Must be set to zero for in-band data + * - In the case of 32 bit Shared memory address, msw field must be + * set to zero. + * - In the case of 36 bit shared memory address, bit 31 to bit 4 of + * msw must be set to zero. + */ + + u32 mem_map_handle; +/* Supported Values: Any. + * memory map handle returned by DSP through ASM_CMD_SHARED_MEM_MAP_REGIONS + * command. + * if mmhandle is NULL, the ParamData payloads in the ACK are within the + * message payload (in-band). + * If mmhandle is non-NULL, the ParamData payloads in the ACK begin at the + * address specified in the address msw and lsw. + * (out-of-band). + */ + + u32 module_id; +/* Unique module ID. */ + + u32 param_id; +/* Unique parameter ID. */ + + u16 param_max_size; +/* Maximum data size of the module_id/param_id combination. This + * is a multiple of 4 bytes. + */ + + + u16 reserved; +/* Reserved for backward compatibility. Clients must set this + * field to zero. + */ +} __packed; + +#define ASM_STREAM_CMD_SET_ENCDEC_PARAM 0x00010C10 + +#define ASM_STREAM_CMD_SET_ENCDEC_PARAM_V2 0x00013218 + +struct asm_stream_cmd_set_encdec_param_v2 { + u16 service_id; + /* 0 - ASM_ENCODER_SVC; 1 - ASM_DECODER_SVC */ + + u16 reserved; + + u32 param_id; + /* ID of the parameter. */ + + u32 param_size; + /* + * Data size of this parameter, in bytes. The size is a multiple + * of 4 bytes. + */ +} __packed; + +#define ASM_STREAM_CMD_REGISTER_ENCDEC_EVENTS 0x00013219 + +#define ASM_STREAM_CMD_ENCDEC_EVENTS 0x0001321A + +#define AVS_PARAM_ID_RTIC_SHARED_MEMORY_ADDR 0x00013237 + +struct avs_rtic_shared_mem_addr { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param_v2 encdec; + u32 shm_buf_addr_lsw; + /* Lower 32 bit of the RTIC shared memory */ + + u32 shm_buf_addr_msw; + /* Upper 32 bit of the RTIC shared memory */ + + u32 buf_size; + /* Size of buffer */ + + u16 shm_buf_mem_pool_id; + /* ADSP_MEMORY_MAP_SHMEM8_4K_POOL */ + + u16 shm_buf_num_regions; + /* number of regions to map */ + + u32 shm_buf_flag; + /* buffer property flag */ + + struct avs_shared_map_region_payload map_region; + /* memory map region*/ +} __packed; + +#define AVS_PARAM_ID_RTIC_EVENT_ACK 0x00013238 + +struct avs_param_rtic_event_ack { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param_v2 encdec; +} __packed; + +#define ASM_PARAM_ID_ENCDEC_BITRATE 0x00010C13 + +struct asm_bitrate_param { + u32 bitrate; +/* Maximum supported bitrate. Only the AAC encoder is supported.*/ + +} __packed; + +#define ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2 0x00010DA3 +#define ASM_PARAM_ID_AAC_SBR_PS_FLAG 0x00010C63 + +/* Flag to turn off both SBR and PS processing, if they are + * present in the bitstream. + */ + +#define ASM_AAC_SBR_OFF_PS_OFF (2) + +/* Flag to turn on SBR but turn off PS processing,if they are + * present in the bitstream. + */ + +#define ASM_AAC_SBR_ON_PS_OFF (1) + +/* Flag to turn on both SBR and PS processing, if they are + * present in the bitstream (default behavior). + */ + + +#define ASM_AAC_SBR_ON_PS_ON (0) + +/* Structure for an AAC SBR PS processing flag. */ + +/* Payload of the #ASM_PARAM_ID_AAC_SBR_PS_FLAG parameter in the + * #ASM_STREAM_CMD_SET_ENCDEC_PARAM command. + */ +struct asm_aac_sbr_ps_flag_param { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + struct asm_enc_cfg_blk_param_v2 encblk; + + u32 sbr_ps_flag; +/* Control parameter to enable or disable SBR/PS processing in + * the AAC bitstream. Use the following macros to set this field: + * - #ASM_AAC_SBR_OFF_PS_OFF -- Turn off both SBR and PS + * processing, if they are present in the bitstream. + * - #ASM_AAC_SBR_ON_PS_OFF -- Turn on SBR processing, but not PS + * processing, if they are present in the bitstream. + * - #ASM_AAC_SBR_ON_PS_ON -- Turn on both SBR and PS processing, + * if they are present in the bitstream (default behavior). + * - All other values are invalid. + * Changes are applied to the next decoded frame. + */ +} __packed; + +#define ASM_PARAM_ID_AAC_DUAL_MONO_MAPPING 0x00010C64 + +/* First single channel element in a dual mono bitstream.*/ +#define ASM_AAC_DUAL_MONO_MAP_SCE_1 (1) + +/* Second single channel element in a dual mono bitstream.*/ +#define ASM_AAC_DUAL_MONO_MAP_SCE_2 (2) + +/* Structure for AAC decoder dual mono channel mapping. */ + + +struct asm_aac_dual_mono_mapping_param { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + u16 left_channel_sce; + u16 right_channel_sce; + +} __packed; + +#define ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 0x00010DA4 + +struct asm_stream_cmdrsp_get_pp_params_v2 { + u32 status; +} __packed; + +#define ASM_PARAM_ID_AC3_KARAOKE_MODE 0x00010D73 + +/* Enumeration for both vocals in a karaoke stream.*/ +#define AC3_KARAOKE_MODE_NO_VOCAL (0) + +/* Enumeration for only the left vocal in a karaoke stream.*/ +#define AC3_KARAOKE_MODE_LEFT_VOCAL (1) + +/* Enumeration for only the right vocal in a karaoke stream.*/ +#define AC3_KARAOKE_MODE_RIGHT_VOCAL (2) + +/* Enumeration for both vocal channels in a karaoke stream.*/ +#define AC3_KARAOKE_MODE_BOTH_VOCAL (3) +#define ASM_PARAM_ID_AC3_DRC_MODE 0x00010D74 +/* Enumeration for the Custom Analog mode.*/ +#define AC3_DRC_MODE_CUSTOM_ANALOG (0) + +/* Enumeration for the Custom Digital mode.*/ +#define AC3_DRC_MODE_CUSTOM_DIGITAL (1) +/* Enumeration for the Line Out mode (light compression).*/ +#define AC3_DRC_MODE_LINE_OUT (2) + +/* Enumeration for the RF remodulation mode (heavy compression).*/ +#define AC3_DRC_MODE_RF_REMOD (3) +#define ASM_PARAM_ID_AC3_DUAL_MONO_MODE 0x00010D75 + +/* Enumeration for playing dual mono in stereo mode.*/ +#define AC3_DUAL_MONO_MODE_STEREO (0) + +/* Enumeration for playing left mono.*/ +#define AC3_DUAL_MONO_MODE_LEFT_MONO (1) + +/* Enumeration for playing right mono.*/ +#define AC3_DUAL_MONO_MODE_RIGHT_MONO (2) + +/* Enumeration for mixing both dual mono channels and playing them.*/ +#define AC3_DUAL_MONO_MODE_MIXED_MONO (3) +#define ASM_PARAM_ID_AC3_STEREO_DOWNMIX_MODE 0x00010D76 + +/* Enumeration for using the Downmix mode indicated in the bitstream. */ + +#define AC3_STEREO_DOWNMIX_MODE_AUTO_DETECT (0) + +/* Enumeration for Surround Compatible mode (preserves the + * surround information). + */ + +#define AC3_STEREO_DOWNMIX_MODE_LT_RT (1) +/* Enumeration for Mono Compatible mode (if the output is to be + * further downmixed to mono). + */ + +#define AC3_STEREO_DOWNMIX_MODE_LO_RO (2) + +/* ID of the AC3 PCM scale factor parameter in the + * #ASM_STREAM_CMD_SET_ENCDEC_PARAM command. + */ +#define ASM_PARAM_ID_AC3_PCM_SCALEFACTOR 0x00010D78 + +/* ID of the AC3 DRC boost scale factor parameter in the + * #ASM_STREAM_CMD_SET_ENCDEC_PARAM command. + */ +#define ASM_PARAM_ID_AC3_DRC_BOOST_SCALEFACTOR 0x00010D79 + +/* ID of the AC3 DRC cut scale factor parameter in the + * #ASM_STREAM_CMD_SET_ENCDEC_PARAM command. + */ +#define ASM_PARAM_ID_AC3_DRC_CUT_SCALEFACTOR 0x00010D7A + +/* Structure for AC3 Generic Parameter. */ + +/* Payload of the AC3 parameters in the + * #ASM_STREAM_CMD_SET_ENCDEC_PARAM command. + */ +struct asm_ac3_generic_param { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + struct asm_enc_cfg_blk_param_v2 encblk; + u32 generic_parameter; +/* AC3 generic parameter. Select from one of the following + * possible values. + * + * For #ASM_PARAM_ID_AC3_KARAOKE_MODE, supported values are: + * - AC3_KARAOKE_MODE_NO_VOCAL + * - AC3_KARAOKE_MODE_LEFT_VOCAL + * - AC3_KARAOKE_MODE_RIGHT_VOCAL + * - AC3_KARAOKE_MODE_BOTH_VOCAL + * + * For #ASM_PARAM_ID_AC3_DRC_MODE, supported values are: + * - AC3_DRC_MODE_CUSTOM_ANALOG + * - AC3_DRC_MODE_CUSTOM_DIGITAL + * - AC3_DRC_MODE_LINE_OUT + * - AC3_DRC_MODE_RF_REMOD + * + * For #ASM_PARAM_ID_AC3_DUAL_MONO_MODE, supported values are: + * - AC3_DUAL_MONO_MODE_STEREO + * - AC3_DUAL_MONO_MODE_LEFT_MONO + * - AC3_DUAL_MONO_MODE_RIGHT_MONO + * - AC3_DUAL_MONO_MODE_MIXED_MONO + * + * For #ASM_PARAM_ID_AC3_STEREO_DOWNMIX_MODE, supported values are: + * - AC3_STEREO_DOWNMIX_MODE_AUTO_DETECT + * - AC3_STEREO_DOWNMIX_MODE_LT_RT + * - AC3_STEREO_DOWNMIX_MODE_LO_RO + * + * For #ASM_PARAM_ID_AC3_PCM_SCALEFACTOR, supported values are + * 0 to 1 in Q31 format. + * + * For #ASM_PARAM_ID_AC3_DRC_BOOST_SCALEFACTOR, supported values are + * 0 to 1 in Q31 format. + * + * For #ASM_PARAM_ID_AC3_DRC_CUT_SCALEFACTOR, supported values are + * 0 to 1 in Q31 format. + */ +} __packed; + +/* Enumeration for Raw mode (no downmixing), which specifies + * that all channels in the bitstream are to be played out as is + * without any downmixing. (Default) + */ + +#define WMAPRO_CHANNEL_MASK_RAW (-1) + +/* Enumeration for setting the channel mask to 0. The 7.1 mode + * (Home Theater) is assigned. + */ + + +#define WMAPRO_CHANNEL_MASK_ZERO 0x0000 + +/* Speaker layout mask for one channel (Home Theater, mono). + * - Speaker front center + */ +#define WMAPRO_CHANNEL_MASK_1_C 0x0004 + +/* Speaker layout mask for two channels (Home Theater, stereo). + * - Speaker front left + * - Speaker front right + */ +#define WMAPRO_CHANNEL_MASK_2_L_R 0x0003 + +/* Speaker layout mask for three channels (Home Theater). + * - Speaker front left + * - Speaker front right + * - Speaker front center + */ +#define WMAPRO_CHANNEL_MASK_3_L_C_R 0x0007 + +/* Speaker layout mask for two channels (stereo). + * - Speaker back left + * - Speaker back right + */ +#define WMAPRO_CHANNEL_MASK_2_Bl_Br 0x0030 + +/* Speaker layout mask for four channels. + * - Speaker front left + * - Speaker front right + * - Speaker back left + * - Speaker back right + */ +#define WMAPRO_CHANNEL_MASK_4_L_R_Bl_Br 0x0033 + +/* Speaker layout mask for four channels (Home Theater). + * - Speaker front left + * - Speaker front right + * - Speaker front center + * - Speaker back center + */ +#define WMAPRO_CHANNEL_MASK_4_L_R_C_Bc_HT 0x0107 +/* Speaker layout mask for five channels. + * - Speaker front left + * - Speaker front right + * - Speaker front center + * - Speaker back left + * - Speaker back right + */ +#define WMAPRO_CHANNEL_MASK_5_L_C_R_Bl_Br 0x0037 + +/* Speaker layout mask for five channels (5 mode, Home Theater). + * - Speaker front left + * - Speaker front right + * - Speaker front center + * - Speaker side left + * - Speaker side right + */ +#define WMAPRO_CHANNEL_MASK_5_L_C_R_Sl_Sr_HT 0x0607 +/* Speaker layout mask for six channels (5.1 mode). + * - Speaker front left + * - Speaker front right + * - Speaker front center + * - Speaker low frequency + * - Speaker back left + * - Speaker back right + */ +#define WMAPRO_CHANNEL_MASK_5DOT1_L_C_R_Bl_Br_SLF 0x003F +/* Speaker layout mask for six channels (5.1 mode, Home Theater). + * - Speaker front left + * - Speaker front right + * - Speaker front center + * - Speaker low frequency + * - Speaker side left + * - Speaker side right + */ +#define WMAPRO_CHANNEL_MASK_5DOT1_L_C_R_Sl_Sr_SLF_HT 0x060F +/* Speaker layout mask for six channels (5.1 mode, no LFE). + * - Speaker front left + * - Speaker front right + * - Speaker front center + * - Speaker back left + * - Speaker back right + * - Speaker back center + */ +#define WMAPRO_CHANNEL_MASK_5DOT1_L_C_R_Bl_Br_Bc 0x0137 +/* Speaker layout mask for six channels (5.1 mode, Home Theater, + * no LFE). + * - Speaker front left + * - Speaker front right + * - Speaker front center + * - Speaker back center + * - Speaker side left + * - Speaker side right + */ +#define WMAPRO_CHANNEL_MASK_5DOT1_L_C_R_Sl_Sr_Bc_HT 0x0707 + +/* Speaker layout mask for seven channels (6.1 mode). + * - Speaker front left + * - Speaker front right + * - Speaker front center + * - Speaker low frequency + * - Speaker back left + * - Speaker back right + * - Speaker back center + */ +#define WMAPRO_CHANNEL_MASK_6DOT1_L_C_R_Bl_Br_Bc_SLF 0x013F + +/* Speaker layout mask for seven channels (6.1 mode, Home + * Theater). + * - Speaker front left + * - Speaker front right + * - Speaker front center + * - Speaker low frequency + * - Speaker back center + * - Speaker side left + * - Speaker side right + */ +#define WMAPRO_CHANNEL_MASK_6DOT1_L_C_R_Sl_Sr_Bc_SLF_HT 0x070F + +/* Speaker layout mask for seven channels (6.1 mode, no LFE). + * - Speaker front left + * - Speaker front right + * - Speaker front center + * - Speaker back left + * - Speaker back right + * - Speaker front left of center + * - Speaker front right of center + */ +#define WMAPRO_CHANNEL_MASK_6DOT1_L_C_R_Bl_Br_SFLOC_SFROC 0x00F7 + +/* Speaker layout mask for seven channels (6.1 mode, Home + * Theater, no LFE). + * - Speaker front left + * - Speaker front right + * - Speaker front center + * - Speaker side left + * - Speaker side right + * - Speaker front left of center + * - Speaker front right of center + */ +#define WMAPRO_CHANNEL_MASK_6DOT1_L_C_R_Sl_Sr_SFLOC_SFROC_HT 0x0637 + +/* Speaker layout mask for eight channels (7.1 mode). + * - Speaker front left + * - Speaker front right + * - Speaker front center + * - Speaker back left + * - Speaker back right + * - Speaker low frequency + * - Speaker front left of center + * - Speaker front right of center + */ +#define WMAPRO_CHANNEL_MASK_7DOT1_L_C_R_Bl_Br_SLF_SFLOC_SFROC \ + 0x00FF + +/* Speaker layout mask for eight channels (7.1 mode, Home Theater). + * - Speaker front left + * - Speaker front right + * - Speaker front center + * - Speaker side left + * - Speaker side right + * - Speaker low frequency + * - Speaker front left of center + * - Speaker front right of center + * + */ +#define WMAPRO_CHANNEL_MASK_7DOT1_L_C_R_Sl_Sr_SLF_SFLOC_SFROC_HT \ + 0x063F + +#define ASM_PARAM_ID_DEC_OUTPUT_CHAN_MAP 0x00010D82 + +/* Maximum number of decoder output channels. */ +#define MAX_CHAN_MAP_CHANNELS 16 + +/* Structure for decoder output channel mapping. */ + +/* Payload of the #ASM_PARAM_ID_DEC_OUTPUT_CHAN_MAP parameter in the + * #ASM_STREAM_CMD_SET_ENCDEC_PARAM command. + */ +struct asm_dec_out_chan_map_param { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + u32 num_channels; +/* Number of decoder output channels. + * Supported values: 0 to #MAX_CHAN_MAP_CHANNELS + * + * A value of 0 indicates native channel mapping, which is valid + * only for NT mode. This means the output of the decoder is to be + * preserved as is. + */ + u8 channel_mapping[MAX_CHAN_MAP_CHANNELS]; +} __packed; + +#define ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED 0x00010D84 + +/* Bitmask for the IEC 61937 enable flag.*/ +#define ASM_BIT_MASK_IEC_61937_STREAM_FLAG (0x00000001UL) + +/* Shift value for the IEC 61937 enable flag.*/ +#define ASM_SHIFT_IEC_61937_STREAM_FLAG 0 + +/* Bitmask for the IEC 60958 enable flag.*/ +#define ASM_BIT_MASK_IEC_60958_STREAM_FLAG (0x00000002UL) + +/* Shift value for the IEC 60958 enable flag.*/ +#define ASM_SHIFT_IEC_60958_STREAM_FLAG 1 + +/* Payload format for open write compressed command */ + +/* Payload format for the #ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED + * command, which opens a stream for a given session ID and stream ID + * to be rendered in the compressed format. + */ + +struct asm_stream_cmd_open_write_compressed { + struct apr_hdr hdr; + u32 flags; +/* Mode flags that configure the stream for a specific format. + * Supported values: + * - Bit 0 -- IEC 61937 compatibility + * - 0 -- Stream is not in IEC 61937 format + * - 1 -- Stream is in IEC 61937 format + * - Bit 1 -- IEC 60958 compatibility + * - 0 -- Stream is not in IEC 60958 format + * - 1 -- Stream is in IEC 60958 format + * - Bits 2 to 31 -- 0 (Reserved) + * + * For the same stream, bit 0 cannot be set to 0 and bit 1 cannot + * be set to 1. A compressed stream connot have IEC 60958 + * packetization applied without IEC 61937 packetization. + * @note1hang Currently, IEC 60958 packetized input streams are not + * supported. + */ + + + u32 fmt_id; +/* Specifies the media type of the HDMI stream to be opened. + * Supported values: + * - #ASM_MEDIA_FMT_AC3 + * - #ASM_MEDIA_FMT_EAC3 + * - #ASM_MEDIA_FMT_DTS + * - #ASM_MEDIA_FMT_ATRAC + * - #ASM_MEDIA_FMT_MAT + * + * @note1hang This field must be set to a valid media type even if + * IEC 61937 packetization is not performed by the aDSP. + */ + +} __packed; + + +/* Indicates the number of samples per channel to be removed from the + * beginning of the stream. + */ +#define ASM_DATA_CMD_REMOVE_INITIAL_SILENCE 0x00010D67 + +/* Indicates the number of samples per channel to be removed from + * the end of the stream. + */ +#define ASM_DATA_CMD_REMOVE_TRAILING_SILENCE 0x00010D68 + +struct asm_data_cmd_remove_silence { + struct apr_hdr hdr; + u32 num_samples_to_remove; + /* < Number of samples per channel to be removed. + * @values 0 to (2@sscr{32}-1) + */ +} __packed; + +#define ASM_STREAM_CMD_OPEN_READ_COMPRESSED 0x00010D95 + +struct asm_stream_cmd_open_read_compressed { + struct apr_hdr hdr; + u32 mode_flags; +/* Mode flags that indicate whether meta information per encoded + * frame is to be provided. + * Supported values for bit 4: + * - 0 -- Return data buffer contains all encoded frames only; it does + * not contain frame metadata. + * - 1 -- Return data buffer contains an array of metadata and encoded + * frames. + * - Use #ASM_BIT_MASK_META_INFO_FLAG to set the bitmask and + * #ASM_SHIFT_META_INFO_FLAG to set the shift value for this bit. + * All other bits are reserved; clients must set them to zero. + */ + + u32 frames_per_buf; +/* Indicates the number of frames that need to be returned per + * read buffer + * Supported values: should be greater than 0 + */ + +} __packed; + +/* adsp_asm_stream_commands.h*/ + + +/* adsp_asm_api.h (no changes)*/ +#define ASM_STREAM_POSTPROCOPO_ID_DEFAULT \ + 0x00010BE4 +#define ASM_STREAM_POSTPROCOPO_ID_PEAKMETER \ + 0x00010D83 +#define ASM_STREAM_POSTPROCOPO_ID_NONE \ + 0x00010C68 +#define ASM_STREAM_POSTPROCOPO_ID_MCH_PEAK_VOL \ + 0x00010D8B +#define ASM_STREAM_PREPROCOPO_ID_DEFAULT \ + ASM_STREAM_POSTPROCOPO_ID_DEFAULT +#define ASM_STREAM_PREPROCOPO_ID_NONE \ + ASM_STREAM_POSTPROCOPO_ID_NONE +#define ADM_CMD_COPP_OPENOPOLOGY_ID_NONE_AUDIO_COPP \ + 0x00010312 +#define ADM_CMD_COPP_OPENOPOLOGY_ID_SPEAKER_MONO_AUDIO_COPP \ + 0x00010313 +#define ADM_CMD_COPP_OPENOPOLOGY_ID_SPEAKER_STEREO_AUDIO_COPP \ + 0x00010314 +#define ADM_CMD_COPP_OPENOPOLOGY_ID_SPEAKER_STEREO_IIR_AUDIO_COPP\ + 0x00010704 +#define ADM_CMD_COPP_OPENOPOLOGY_ID_SPEAKER_MONO_AUDIO_COPP_MBDRCV2\ + 0x0001070D +#define ADM_CMD_COPP_OPENOPOLOGY_ID_SPEAKER_STEREO_AUDIO_COPP_MBDRCV2\ + 0x0001070E +#define ADM_CMD_COPP_OPENOPOLOGY_ID_SPEAKER_STEREO_IIR_AUDIO_COPP_MBDRCV2\ + 0x0001070F +#define ADM_CMD_COPP_OPENOPOLOGY_ID_SPEAKER_STEREO_AUDIO_COPP_MBDRC_V3 \ + 0x11000000 +#define ADM_CMD_COPP_OPENOPOLOGY_ID_SPEAKER_MCH_PEAK_VOL \ + 0x0001031B +#define ADM_CMD_COPP_OPENOPOLOGY_ID_MIC_MONO_AUDIO_COPP 0x00010315 +#define ADM_CMD_COPP_OPENOPOLOGY_ID_MIC_STEREO_AUDIO_COPP 0x00010316 +#define AUDPROC_COPPOPOLOGY_ID_MCHAN_IIR_AUDIO 0x00010715 +#define ADM_CMD_COPP_OPENOPOLOGY_ID_DEFAULT_AUDIO_COPP 0x00010BE3 +#define ADM_CMD_COPP_OPENOPOLOGY_ID_PEAKMETER_AUDIO_COPP 0x00010317 +#define AUDPROC_MODULE_ID_AIG 0x00010716 +#define AUDPROC_PARAM_ID_AIG_ENABLE 0x00010717 +#define AUDPROC_PARAM_ID_AIG_CONFIG 0x00010718 + +struct Audio_AigParam { + uint16_t mode; +/*< Mode word for enabling AIG/SIG mode . + * Byte offset: 0 + */ + int16_t staticGainL16Q12; +/*< Static input gain when aigMode is set to 1. + * Byte offset: 2 + */ + int16_t initialGainDBL16Q7; +/*module id + * data variable payload containing the pre/postprocessing module id + * values. For an in-band scenario, the variable payload depends on the size + * of the parameter. + */ +struct adm_cmd_rsp_get_pp_topo_module_list_t { + /* Status message (error code). */ + uint32_t status; +} __packed; + +struct audproc_topology_module_id_info_t { + uint32_t num_modules; +} __packed; + +/* end_addtogroup audio_pp_module_ids */ + +/* @ingroup audio_pp_module_ids + * ID of the Volume Control module pre/postprocessing block. + * This module supports the following parameter IDs: + * - #ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN + * - #ASM_PARAM_ID_MULTICHANNEL_GAIN + * - #ASM_PARAM_ID_VOL_CTRL_MUTE_CONFIG + * - #ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS + * - #ASM_PARAM_ID_SOFT_PAUSE_PARAMETERS + * - #ASM_PARAM_ID_MULTICHANNEL_GAIN + * - #ASM_PARAM_ID_MULTICHANNEL_MUTE + */ +#define ASM_MODULE_ID_VOL_CTRL 0x00010BFE +#define ASM_MODULE_ID_VOL_CTRL2 0x00010910 +#define AUDPROC_MODULE_ID_VOL_CTRL ASM_MODULE_ID_VOL_CTRL + +/* @addtogroup audio_pp_param_ids */ +/* ID of the master gain parameter used by the #ASM_MODULE_ID_VOL_CTRL + * module. + * @messagepayload + * @structure{asm_volume_ctrl_master_gain} + * @tablespace + * @inputtable{Audio_Postproc_ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN.tex} + */ +#define ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN 0x00010BFF +#define AUDPROC_PARAM_ID_VOL_CTRL_MASTER_GAIN ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN + +/* ID of the left/right channel gain parameter used by the + * #ASM_MODULE_ID_VOL_CTRL module. + * @messagepayload + * @structure{asm_volume_ctrl_lr_chan_gain} + * @tablespace + * @inputtable{Audio_Postproc_ASM_PARAM_ID_MULTICHANNEL_GAIN.tex} + */ +#define ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN 0x00010C00 + +/* ID of the mute configuration parameter used by the + * #ASM_MODULE_ID_VOL_CTRL module. + * @messagepayload + * @structure{asm_volume_ctrl_mute_config} + * @tablespace + * @inputtable{Audio_Postproc_ASM_PARAM_ID_VOL_CTRL_MUTE_CONFIG.tex} + */ +#define ASM_PARAM_ID_VOL_CTRL_MUTE_CONFIG 0x00010C01 + +/* ID of the soft stepping volume parameters used by the + * #ASM_MODULE_ID_VOL_CTRL module. + * @messagepayload + * @structure{asm_soft_step_volume_params} + * @tablespace + * @inputtable{Audio_Postproc_ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMET + * ERS.tex} + */ +#define ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS 0x00010C29 +#define AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS\ + ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS + +/* ID of the soft pause parameters used by the #ASM_MODULE_ID_VOL_CTRL + * module. + */ +#define ASM_PARAM_ID_SOFT_PAUSE_PARAMETERS 0x00010D6A + +/* ID of the multiple-channel volume control parameters used by the + * #ASM_MODULE_ID_VOL_CTRL module. + */ +#define ASM_PARAM_ID_MULTICHANNEL_GAIN 0x00010713 + +/* ID of the multiple-channel mute configuration parameters used by the + * #ASM_MODULE_ID_VOL_CTRL module. + */ + +#define ASM_PARAM_ID_MULTICHANNEL_MUTE 0x00010714 + +/* Structure for the master gain parameter for a volume control + * module. + */ + + +/* @brief Payload of the #ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN + * parameter used by the Volume Control module. + */ + + + +struct asm_volume_ctrl_master_gain { + struct apr_hdr hdr; + struct asm_stream_cmd_set_pp_params_v2 param; + struct asm_stream_param_data_v2 data; + uint16_t master_gain; + /* Linear gain in Q13 format. */ + + uint16_t reserved; + /* Clients must set this field to zero. */ +} __packed; + + +struct asm_volume_ctrl_lr_chan_gain { + struct apr_hdr hdr; + struct asm_stream_cmd_set_pp_params_v2 param; + struct asm_stream_param_data_v2 data; + + uint16_t l_chan_gain; + /*< Linear gain in Q13 format for the left channel. */ + + uint16_t r_chan_gain; + /*< Linear gain in Q13 format for the right channel.*/ +} __packed; + + +/* Structure for the mute configuration parameter for a + * volume control module. + */ + + +/* @brief Payload of the #ASM_PARAM_ID_VOL_CTRL_MUTE_CONFIG + * parameter used by the Volume Control module. + */ + + +struct asm_volume_ctrl_mute_config { + struct apr_hdr hdr; + struct asm_stream_cmd_set_pp_params_v2 param; + struct asm_stream_param_data_v2 data; + uint32_t mute_flag; +/*< Specifies whether mute is disabled (0) or enabled (nonzero).*/ + +} __packed; + +/* + * Supported parameters for a soft stepping linear ramping curve. + */ +#define ASM_PARAM_SVC_RAMPINGCURVE_LINEAR 0 + +/* + * Exponential ramping curve. + */ +#define ASM_PARAM_SVC_RAMPINGCURVE_EXP 1 + +/* + * Logarithmic ramping curve. + */ +#define ASM_PARAM_SVC_RAMPINGCURVE_LOG 2 + +/* Structure for holding soft stepping volume parameters. */ + + +/* Payload of the #ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS + * parameters used by the Volume Control module. + */ +struct asm_soft_step_volume_params { + struct apr_hdr hdr; + struct asm_stream_cmd_set_pp_params_v2 param; + struct asm_stream_param_data_v2 data; + uint32_t period; +/*< Period in milliseconds. + * Supported values: 0 to 15000 + */ + + uint32_t step; +/*< Step in microseconds. + * Supported values: 0 to 15000000 + */ + + uint32_t ramping_curve; +/*< Ramping curve type. + * Supported values: + * - #ASM_PARAM_SVC_RAMPINGCURVE_LINEAR + * - #ASM_PARAM_SVC_RAMPINGCURVE_EXP + * - #ASM_PARAM_SVC_RAMPINGCURVE_LOG + */ +} __packed; + + +/* Structure for holding soft pause parameters. */ + + +/* Payload of the #ASM_PARAM_ID_SOFT_PAUSE_PARAMETERS + * parameters used by the Volume Control module. + */ + + +struct asm_soft_pause_params { + struct apr_hdr hdr; + struct asm_stream_cmd_set_pp_params_v2 param; + struct asm_stream_param_data_v2 data; + uint32_t enable_flag; +/*< Specifies whether soft pause is disabled (0) or enabled + * (nonzero). + */ + + + + uint32_t period; +/*< Period in milliseconds. + * Supported values: 0 to 15000 + */ + + uint32_t step; +/*< Step in microseconds. + * Supported values: 0 to 15000000 + */ + + uint32_t ramping_curve; +/*< Ramping curve. + * Supported values: + * - #ASM_PARAM_SVC_RAMPINGCURVE_LINEAR + * - #ASM_PARAM_SVC_RAMPINGCURVE_EXP + * - #ASM_PARAM_SVC_RAMPINGCURVE_LOG + */ +} __packed; + + +/* Maximum number of channels.*/ +#define VOLUME_CONTROL_MAX_CHANNELS 8 + +/* Structure for holding one channel type - gain pair. */ + + +/* Payload of the #ASM_PARAM_ID_MULTICHANNEL_GAIN channel + * type/gain pairs used by the Volume Control module. \n \n This + * structure immediately follows the + * asm_volume_ctrl_multichannel_gain structure. + */ + + +struct asm_volume_ctrl_channeltype_gain_pair { + uint8_t channeltype; + /* + * Channel type for which the gain setting is to be applied. + * Supported values: + * - #PCM_CHANNEL_L + * - #PCM_CHANNEL_R + * - #PCM_CHANNEL_C + * - #PCM_CHANNEL_LS + * - #PCM_CHANNEL_RS + * - #PCM_CHANNEL_LFE + * - #PCM_CHANNEL_CS + * - #PCM_CHANNEL_LB + * - #PCM_CHANNEL_RB + * - #PCM_CHANNELS + * - #PCM_CHANNEL_CVH + * - #PCM_CHANNEL_MS + * - #PCM_CHANNEL_FLC + * - #PCM_CHANNEL_FRC + * - #PCM_CHANNEL_RLC + * - #PCM_CHANNEL_RRC + */ + + uint8_t reserved1; + /* Clients must set this field to zero. */ + + uint8_t reserved2; + /* Clients must set this field to zero. */ + + uint8_t reserved3; + /* Clients must set this field to zero. */ + + uint32_t gain; + /* + * Gain value for this channel in Q28 format. + * Supported values: Any + */ +} __packed; + + +/* Structure for the multichannel gain command */ + + +/* Payload of the #ASM_PARAM_ID_MULTICHANNEL_GAIN + * parameters used by the Volume Control module. + */ + + +struct asm_volume_ctrl_multichannel_gain { + struct apr_hdr hdr; + struct asm_stream_cmd_set_pp_params_v2 param; + struct asm_stream_param_data_v2 data; + uint32_t num_channels; + /* + * Number of channels for which gain values are provided. Any + * channels present in the data for which gain is not provided are + * set to unity gain. + * Supported values: 1 to 8 + */ + + struct asm_volume_ctrl_channeltype_gain_pair + gain_data[VOLUME_CONTROL_MAX_CHANNELS]; + /* Array of channel type/gain pairs.*/ +} __packed; + + +/* Structure for holding one channel type - mute pair. */ + + +/* Payload of the #ASM_PARAM_ID_MULTICHANNEL_MUTE channel + * type/mute setting pairs used by the Volume Control module. \n \n + * This structure immediately follows the + * asm_volume_ctrl_multichannel_mute structure. + */ + + +struct asm_volume_ctrl_channelype_mute_pair { + struct apr_hdr hdr; + struct asm_stream_cmd_set_pp_params_v2 param; + struct asm_stream_param_data_v2 data; + uint8_t channelype; +/*< Channel type for which the mute setting is to be applied. + * Supported values: + * - #PCM_CHANNEL_L + * - #PCM_CHANNEL_R + * - #PCM_CHANNEL_C + * - #PCM_CHANNEL_LS + * - #PCM_CHANNEL_RS + * - #PCM_CHANNEL_LFE + * - #PCM_CHANNEL_CS + * - #PCM_CHANNEL_LB + * - #PCM_CHANNEL_RB + * - #PCM_CHANNELS + * - #PCM_CHANNEL_CVH + * - #PCM_CHANNEL_MS + * - #PCM_CHANNEL_FLC + * - #PCM_CHANNEL_FRC + * - #PCM_CHANNEL_RLC + * - #PCM_CHANNEL_RRC + */ + + uint8_t reserved1; + /*< Clients must set this field to zero. */ + + uint8_t reserved2; + /*< Clients must set this field to zero. */ + + uint8_t reserved3; + /*< Clients must set this field to zero. */ + + uint32_t mute; +/*< Mute setting for this channel. + * Supported values: + * - 0 = Unmute + * - Nonzero = Mute + */ +} __packed; + + +/* Structure for the multichannel mute command */ + + +/* @brief Payload of the #ASM_PARAM_ID_MULTICHANNEL_MUTE + * parameters used by the Volume Control module. + */ + + +struct asm_volume_ctrl_multichannel_mute { + struct apr_hdr hdr; + struct asm_stream_cmd_set_pp_params_v2 param; + struct asm_stream_param_data_v2 data; + uint32_t num_channels; +/*< Number of channels for which mute configuration is + * provided. Any channels present in the data for which mute + * configuration is not provided are set to unmute. + * Supported values: 1 to 8 + */ + +struct asm_volume_ctrl_channelype_mute_pair + mute_data[VOLUME_CONTROL_MAX_CHANNELS]; + /*< Array of channel type/mute setting pairs.*/ +} __packed; +/* end_addtogroup audio_pp_param_ids */ + +/* audio_pp_module_ids + * ID of the IIR Tuning Filter module. + * This module supports the following parameter IDs: + * - #ASM_PARAM_ID_IIRUNING_FILTER_ENABLE_CONFIG + * - #ASM_PARAM_ID_IIRUNING_FILTER_PRE_GAIN + * - #ASM_PARAM_ID_IIRUNING_FILTER_CONFIG_PARAMS + */ +#define ASM_MODULE_ID_IIRUNING_FILTER 0x00010C02 + +/* @addtogroup audio_pp_param_ids */ +/* ID of the IIR tuning filter enable parameter used by the + * #ASM_MODULE_ID_IIRUNING_FILTER module. + * @messagepayload + * @structure{asm_iiruning_filter_enable} + * @tablespace + * @inputtable{Audio_Postproc_ASM_PARAM_ID_IIRUNING_FILTER_ENABLE_CO + * NFIG.tex} + */ +#define ASM_PARAM_ID_IIRUNING_FILTER_ENABLE_CONFIG 0x00010C03 + +/* ID of the IIR tuning filter pregain parameter used by the + * #ASM_MODULE_ID_IIRUNING_FILTER module. + */ +#define ASM_PARAM_ID_IIRUNING_FILTER_PRE_GAIN 0x00010C04 + +/* ID of the IIR tuning filter configuration parameters used by the + * #ASM_MODULE_ID_IIRUNING_FILTER module. + */ +#define ASM_PARAM_ID_IIRUNING_FILTER_CONFIG_PARAMS 0x00010C05 + +/* Structure for an enable configuration parameter for an + * IIR tuning filter module. + */ + + +/* @brief Payload of the #ASM_PARAM_ID_IIRUNING_FILTER_ENABLE_CONFIG + * parameter used by the IIR Tuning Filter module. + */ +struct asm_iiruning_filter_enable { + uint32_t enable_flag; +/*< Specifies whether the IIR tuning filter is disabled (0) or + * enabled (1). + */ +} __packed; + +/* Structure for the pregain parameter for an IIR tuning filter module. */ + + +/* Payload of the #ASM_PARAM_ID_IIRUNING_FILTER_PRE_GAIN + * parameters used by the IIR Tuning Filter module. + */ +struct asm_iiruning_filter_pregain { + uint16_t pregain; + /*< Linear gain in Q13 format. */ + + uint16_t reserved; + /*< Clients must set this field to zero.*/ +} __packed; + +/* Structure for the configuration parameter for an IIR tuning filter + * module. + */ + + +/* @brief Payload of the #ASM_PARAM_ID_IIRUNING_FILTER_CONFIG_PARAMS + * parameters used by the IIR Tuning Filter module. \n + * \n + * This structure is followed by the IIR filter coefficients: \n + * - Sequence of int32_t FilterCoeffs \n + * Five coefficients for each band. Each coefficient is in int32_t format, in + * the order of b0, b1, b2, a1, a2. + * - Sequence of int16_t NumShiftFactor \n + * One int16_t per band. The numerator shift factor is related to the Q + * factor of the filter coefficients. + * - Sequence of uint16_t PanSetting \n + * One uint16_t per band, indicating if the filter is applied to left (0), + * right (1), or both (2) channels. + */ +struct asm_iir_filter_config_params { + uint16_t num_biquad_stages; +/*< Number of bands. + * Supported values: 0 to 20 + */ + + uint16_t reserved; + /*< Clients must set this field to zero.*/ +} __packed; + +/* audio_pp_module_ids + * ID of the Multiband Dynamic Range Control (MBDRC) module on the Tx/Rx + * paths. + * This module supports the following parameter IDs: + * - #ASM_PARAM_ID_MBDRC_ENABLE + * - #ASM_PARAM_ID_MBDRC_CONFIG_PARAMS + */ +#define ASM_MODULE_ID_MBDRC 0x00010C06 + +/* audio_pp_param_ids */ +/* ID of the MBDRC enable parameter used by the #ASM_MODULE_ID_MBDRC module. + * @messagepayload + * @structure{asm_mbdrc_enable} + * @tablespace + * @inputtable{Audio_Postproc_ASM_PARAM_ID_MBDRC_ENABLE.tex} + */ +#define ASM_PARAM_ID_MBDRC_ENABLE 0x00010C07 + +/* ID of the MBDRC configuration parameters used by the + * #ASM_MODULE_ID_MBDRC module. + * @messagepayload + * @structure{asm_mbdrc_config_params} + * @tablespace + * @inputtable{Audio_Postproc_ASM_PARAM_ID_MBDRC_CONFIG_PARAMS.tex} + * + * @parspace Sub-band DRC configuration parameters + * @structure{asm_subband_drc_config_params} + * @tablespace + * @inputtable{Audio_Postproc_ASM_PARAM_ID_MBDRC_CONFIG_PARAMS_subband_DRC.tex} + * + * @keep{6} + * To obtain legacy ADRC from MBDRC, use the calibration tool to: + * + * - Enable MBDRC (EnableFlag = TRUE) + * - Set number of bands to 1 (uiNumBands = 1) + * - Enable the first MBDRC band (DrcMode[0] = DRC_ENABLED = 1) + * - Clear the first band mute flag (MuteFlag[0] = 0) + * - Set the first band makeup gain to unity (compMakeUpGain[0] = 0x2000) + * - Use the legacy ADRC parameters to calibrate the rest of the MBDRC + * parameters. + */ +#define ASM_PARAM_ID_MBDRC_CONFIG_PARAMS 0x00010C08 + +/* end_addtogroup audio_pp_param_ids */ + +/* audio_pp_module_ids + * ID of the MMBDRC module version 2 pre/postprocessing block. + * This module differs from the original MBDRC (#ASM_MODULE_ID_MBDRC) in + * the length of the filters used in each sub-band. + * This module supports the following parameter ID: + * - #ASM_PARAM_ID_MBDRC_CONFIG_PARAMS_IMPROVED_FILTBANK_V2 + */ +#define ASM_MODULE_ID_MBDRCV2 0x0001070B + +/* @addtogroup audio_pp_param_ids */ +/* ID of the configuration parameters used by the + * #ASM_MODULE_ID_MBDRCV2 module for the improved filter structure + * of the MBDRC v2 pre/postprocessing block. + * The update to this configuration structure from the original + * MBDRC is the number of filter coefficients in the filter + * structure. The sequence for is as follows: + * - 1 band = 0 FIR coefficient + 1 mute flag + uint16_t padding + * - 2 bands = 141 FIR coefficients + 2 mute flags + uint16_t padding + * - 3 bands = 141+81 FIR coefficients + 3 mute flags + uint16_t padding + * - 4 bands = 141+81+61 FIR coefficients + 4 mute flags + uint16_t + * padding + * - 5 bands = 141+81+61+61 FIR coefficients + 5 mute flags + + * uint16_t padding + * This block uses the same parameter structure as + * #ASM_PARAM_ID_MBDRC_CONFIG_PARAMS. + */ +#define ASM_PARAM_ID_MBDRC_CONFIG_PARAMS_IMPROVED_FILTBANK_V2 \ + 0x0001070C + +#define ASM_MODULE_ID_MBDRCV3 0x0001090B +/* + * ID of the MMBDRC module version 3 pre/postprocessing block. + * This module differs from MBDRCv2 (#ASM_MODULE_ID_MBDRCV2) in + * that it supports both 16- and 24-bit data. + * This module supports the following parameter ID: + * - #ASM_PARAM_ID_MBDRC_ENABLE + * - #ASM_PARAM_ID_MBDRC_CONFIG_PARAMS + * - #ASM_PARAM_ID_MBDRC_CONFIG_PARAMS_V3 + * - #ASM_PARAM_ID_MBDRC_FILTER_XOVER_FREQS + */ + +/* Structure for the enable parameter for an MBDRC module. */ + + +/* Payload of the #ASM_PARAM_ID_MBDRC_ENABLE parameter used by the + * MBDRC module. + */ +struct asm_mbdrc_enable { + uint32_t enable_flag; +/*< Specifies whether MBDRC is disabled (0) or enabled (nonzero).*/ +} __packed; + +/* Structure for the configuration parameters for an MBDRC module. */ + + +/* Payload of the #ASM_PARAM_ID_MBDRC_CONFIG_PARAMS + * parameters used by the MBDRC module. \n \n Following this + * structure is the payload for sub-band DRC configuration + * parameters (asm_subband_drc_config_params). This sub-band + * structure must be repeated for each band. + */ + + +struct asm_mbdrc_config_params { + uint16_t num_bands; +/*< Number of bands. + * Supported values: 1 to 5 + */ + + int16_t limiterhreshold; +/*< Threshold in decibels for the limiter output. + * Supported values: -72 to 18 \n + * Recommended value: 3994 (-0.22 db in Q3.12 format) + */ + + int16_t limiter_makeup_gain; +/*< Makeup gain in decibels for the limiter output. + * Supported values: -42 to 42 \n + * Recommended value: 256 (0 dB in Q7.8 format) + */ + + int16_t limiter_gc; +/*< Limiter gain recovery coefficient. + * Supported values: 0.5 to 0.99 \n + * Recommended value: 32440 (0.99 in Q15 format) + */ + + int16_t limiter_delay; +/*< Limiter delay in samples. + * Supported values: 0 to 10 \n + * Recommended value: 262 (0.008 samples in Q15 format) + */ + + int16_t limiter_max_wait; +/*< Maximum limiter waiting time in samples. + * Supported values: 0 to 10 \n + * Recommended value: 262 (0.008 samples in Q15 format) + */ +} __packed; + +/* DRC configuration structure for each sub-band of an MBDRC module. */ + + +/* Payload of the #ASM_PARAM_ID_MBDRC_CONFIG_PARAMS DRC + * configuration parameters for each sub-band in the MBDRC module. + * After this DRC structure is configured for valid bands, the next + * MBDRC setparams expects the sequence of sub-band MBDRC filter + * coefficients (the length depends on the number of bands) plus the + * mute flag for that band plus uint16_t padding. + * + * @keep{10} + * The filter coefficient and mute flag are of type int16_t: + * - FIR coefficient = int16_t firFilter + * - Mute flag = int16_t fMuteFlag + * + * The sequence is as follows: + * - 1 band = 0 FIR coefficient + 1 mute flag + uint16_t padding + * - 2 bands = 97 FIR coefficients + 2 mute flags + uint16_t padding + * - 3 bands = 97+33 FIR coefficients + 3 mute flags + uint16_t padding + * - 4 bands = 97+33+33 FIR coefficients + 4 mute flags + uint16_t padding + * - 5 bands = 97+33+33+33 FIR coefficients + 5 mute flags + uint16_t padding + * + * For improved filterbank, the sequence is as follows: + * - 1 band = 0 FIR coefficient + 1 mute flag + uint16_t padding + * - 2 bands = 141 FIR coefficients + 2 mute flags + uint16_t padding + * - 3 bands = 141+81 FIR coefficients + 3 mute flags + uint16_t padding + * - 4 bands = 141+81+61 FIR coefficients + 4 mute flags + uint16_t padding + * - 5 bands = 141+81+61+61 FIR coefficients + 5 mute flags + uint16_t padding + */ +struct asm_subband_drc_config_params { + int16_t drc_stereo_linked_flag; +/*< Specifies whether all stereo channels have the same applied + * dynamics (1) or if they process their dynamics independently (0). + * Supported values: + * - 0 -- Not linked + * - 1 -- Linked + */ + + int16_t drc_mode; +/*< Specifies whether DRC mode is bypassed for sub-bands. + * Supported values: + * - 0 -- Disabled + * - 1 -- Enabled + */ + + int16_t drc_down_sample_level; +/*< DRC down sample level. + * Supported values: @ge 1 + */ + + int16_t drc_delay; +/*< DRC delay in samples. + * Supported values: 0 to 1200 + */ + + uint16_t drc_rmsime_avg_const; +/*< RMS signal energy time-averaging constant. + * Supported values: 0 to 2^16-1 + */ + + uint16_t drc_makeup_gain; +/*< DRC makeup gain in decibels. + * Supported values: 258 to 64917 + */ + /* Down expander settings */ + int16_t down_expdrhreshold; +/*< Down expander threshold. + * Supported Q7 format values: 1320 to up_cmpsrhreshold + */ + + int16_t down_expdr_slope; +/*< Down expander slope. + * Supported Q8 format values: -32768 to 0. + */ + + uint32_t down_expdr_attack; +/*< Down expander attack constant. + * Supported Q31 format values: 196844 to 2^31. + */ + + uint32_t down_expdr_release; +/*< Down expander release constant. + * Supported Q31 format values: 19685 to 2^31 + */ + + uint16_t down_expdr_hysteresis; +/*< Down expander hysteresis constant. + * Supported Q14 format values: 1 to 32690 + */ + + uint16_t reserved; + /*< Clients must set this field to zero. */ + + int32_t down_expdr_min_gain_db; +/*< Down expander minimum gain. + * Supported Q23 format values: -805306368 to 0. + */ + + /* Up compressor settings */ + + int16_t up_cmpsrhreshold; +/*< Up compressor threshold. + * Supported Q7 format values: down_expdrhreshold to + * down_cmpsrhreshold. + */ + + uint16_t up_cmpsr_slope; +/*< Up compressor slope. + * Supported Q16 format values: 0 to 64881. + */ + + uint32_t up_cmpsr_attack; +/*< Up compressor attack constant. + * Supported Q31 format values: 196844 to 2^31. + */ + + uint32_t up_cmpsr_release; +/*< Up compressor release constant. + * Supported Q31 format values: 19685 to 2^31. + */ + + uint16_t up_cmpsr_hysteresis; +/*< Up compressor hysteresis constant. + * Supported Q14 format values: 1 to 32690. + */ + + /* Down compressor settings */ + + int16_t down_cmpsrhreshold; +/*< Down compressor threshold. + * Supported Q7 format values: up_cmpsrhreshold to 11560. + */ + + uint16_t down_cmpsr_slope; +/*< Down compressor slope. + * Supported Q16 format values: 0 to 64881. + */ + + uint16_t reserved1; +/*< Clients must set this field to zero. */ + + uint32_t down_cmpsr_attack; +/*< Down compressor attack constant. + * Supported Q31 format values: 196844 to 2^31. + */ + + uint32_t down_cmpsr_release; +/*< Down compressor release constant. + * Supported Q31 format values: 19685 to 2^31. + */ + + uint16_t down_cmpsr_hysteresis; +/*< Down compressor hysteresis constant. + * Supported Q14 values: 1 to 32690. + */ + + uint16_t reserved2; +/*< Clients must set this field to zero.*/ +} __packed; + +#define ASM_MODULE_ID_EQUALIZER 0x00010C27 +#define ASM_PARAM_ID_EQUALIZER_PARAMETERS 0x00010C28 + +#define ASM_MAX_EQ_BANDS 12 + +struct asm_eq_per_band_params { + uint32_t band_idx; +/*< Band index. + * Supported values: 0 to 11 + */ + + uint32_t filterype; +/*< Type of filter. + * Supported values: + * - #ASM_PARAM_EQYPE_NONE + * - #ASM_PARAM_EQ_BASS_BOOST + * - #ASM_PARAM_EQ_BASS_CUT + * - #ASM_PARAM_EQREBLE_BOOST + * - #ASM_PARAM_EQREBLE_CUT + * - #ASM_PARAM_EQ_BAND_BOOST + * - #ASM_PARAM_EQ_BAND_CUT + */ + + uint32_t center_freq_hz; + /*< Filter band center frequency in Hertz. */ + + int32_t filter_gain; +/*< Filter band initial gain. + * Supported values: +12 to -12 dB in 1 dB increments + */ + + int32_t q_factor; +/*< Filter band quality factor expressed as a Q8 number, i.e., a + * fixed-point number with q factor of 8. For example, 3000/(2^8). + */ +} __packed; + +struct asm_eq_params { + struct apr_hdr hdr; + struct asm_stream_cmd_set_pp_params_v2 param; + struct asm_stream_param_data_v2 data; + uint32_t enable_flag; +/*< Specifies whether the equalizer module is disabled (0) or enabled + * (nonzero). + */ + + uint32_t num_bands; +/*< Number of bands. + * Supported values: 1 to 12 + */ + struct asm_eq_per_band_params eq_bands[ASM_MAX_EQ_BANDS]; + +} __packed; + +/* No equalizer effect.*/ +#define ASM_PARAM_EQYPE_NONE 0 + +/* Bass boost equalizer effect.*/ +#define ASM_PARAM_EQ_BASS_BOOST 1 + +/*Bass cut equalizer effect.*/ +#define ASM_PARAM_EQ_BASS_CUT 2 + +/* Treble boost equalizer effect */ +#define ASM_PARAM_EQREBLE_BOOST 3 + +/* Treble cut equalizer effect.*/ +#define ASM_PARAM_EQREBLE_CUT 4 + +/* Band boost equalizer effect.*/ +#define ASM_PARAM_EQ_BAND_BOOST 5 + +/* Band cut equalizer effect.*/ +#define ASM_PARAM_EQ_BAND_CUT 6 + +/* Get & set params */ +#define VSS_ICOMMON_CMD_SET_PARAM_V2 0x0001133D +#define VSS_ICOMMON_CMD_GET_PARAM_V2 0x0001133E +#define VSS_ICOMMON_RSP_GET_PARAM 0x00011008 + +/* ID of the Bass Boost module. + * This module supports the following parameter IDs: + * - #AUDPROC_PARAM_ID_BASS_BOOST_ENABLE + * - #AUDPROC_PARAM_ID_BASS_BOOST_MODE + * - #AUDPROC_PARAM_ID_BASS_BOOST_STRENGTH + */ +#define AUDPROC_MODULE_ID_BASS_BOOST 0x000108A1 +/* ID of the Bass Boost enable parameter used by + * AUDPROC_MODULE_ID_BASS_BOOST. + */ +#define AUDPROC_PARAM_ID_BASS_BOOST_ENABLE 0x000108A2 +/* ID of the Bass Boost mode parameter used by + * AUDPROC_MODULE_ID_BASS_BOOST. + */ +#define AUDPROC_PARAM_ID_BASS_BOOST_MODE 0x000108A3 +/* ID of the Bass Boost strength parameter used by + * AUDPROC_MODULE_ID_BASS_BOOST. + */ +#define AUDPROC_PARAM_ID_BASS_BOOST_STRENGTH 0x000108A4 + +/* ID of the PBE module. + * This module supports the following parameter IDs: + * - #AUDPROC_PARAM_ID_PBE_ENABLE + * - #AUDPROC_PARAM_ID_PBE_PARAM_CONFIG + */ +#define AUDPROC_MODULE_ID_PBE 0x00010C2A +/* ID of the Bass Boost enable parameter used by + * AUDPROC_MODULE_ID_BASS_BOOST. + */ +#define AUDPROC_PARAM_ID_PBE_ENABLE 0x00010C2B +/* ID of the Bass Boost mode parameter used by + * AUDPROC_MODULE_ID_BASS_BOOST. + */ +#define AUDPROC_PARAM_ID_PBE_PARAM_CONFIG 0x00010C49 + +/* ID of the Virtualizer module. This module supports the + * following parameter IDs: + * - #AUDPROC_PARAM_ID_VIRTUALIZER_ENABLE + * - #AUDPROC_PARAM_ID_VIRTUALIZER_STRENGTH + * - #AUDPROC_PARAM_ID_VIRTUALIZER_OUT_TYPE + * - #AUDPROC_PARAM_ID_VIRTUALIZER_GAIN_ADJUST + */ +#define AUDPROC_MODULE_ID_VIRTUALIZER 0x000108A5 +/* ID of the Virtualizer enable parameter used by + * AUDPROC_MODULE_ID_VIRTUALIZER. + */ +#define AUDPROC_PARAM_ID_VIRTUALIZER_ENABLE 0x000108A6 +/* ID of the Virtualizer strength parameter used by + * AUDPROC_MODULE_ID_VIRTUALIZER. + */ +#define AUDPROC_PARAM_ID_VIRTUALIZER_STRENGTH 0x000108A7 +/* ID of the Virtualizer out type parameter used by + * AUDPROC_MODULE_ID_VIRTUALIZER. + */ +#define AUDPROC_PARAM_ID_VIRTUALIZER_OUT_TYPE 0x000108A8 +/* ID of the Virtualizer out type parameter used by + * AUDPROC_MODULE_ID_VIRTUALIZER. + */ +#define AUDPROC_PARAM_ID_VIRTUALIZER_GAIN_ADJUST 0x000108A9 + +/* ID of the Reverb module. This module supports the following + * parameter IDs: + * - #AUDPROC_PARAM_ID_REVERB_ENABLE + * - #AUDPROC_PARAM_ID_REVERB_MODE + * - #AUDPROC_PARAM_ID_REVERB_PRESET + * - #AUDPROC_PARAM_ID_REVERB_WET_MIX + * - #AUDPROC_PARAM_ID_REVERB_GAIN_ADJUST + * - #AUDPROC_PARAM_ID_REVERB_ROOM_LEVEL + * - #AUDPROC_PARAM_ID_REVERB_ROOM_HF_LEVEL + * - #AUDPROC_PARAM_ID_REVERB_DECAY_TIME + * - #AUDPROC_PARAM_ID_REVERB_DECAY_HF_RATIO + * - #AUDPROC_PARAM_ID_REVERB_REFLECTIONS_LEVEL + * - #AUDPROC_PARAM_ID_REVERB_REFLECTIONS_DELAY + * - #AUDPROC_PARAM_ID_REVERB_LEVEL + * - #AUDPROC_PARAM_ID_REVERB_DELAY + * - #AUDPROC_PARAM_ID_REVERB_DIFFUSION + * - #AUDPROC_PARAM_ID_REVERB_DENSITY + */ +#define AUDPROC_MODULE_ID_REVERB 0x000108AA +/* ID of the Reverb enable parameter used by + * AUDPROC_MODULE_ID_REVERB. + */ +#define AUDPROC_PARAM_ID_REVERB_ENABLE 0x000108AB +/* ID of the Reverb mode parameter used by + * AUDPROC_MODULE_ID_REVERB. + */ +#define AUDPROC_PARAM_ID_REVERB_MODE 0x000108AC +/* ID of the Reverb preset parameter used by + * AUDPROC_MODULE_ID_REVERB. + */ +#define AUDPROC_PARAM_ID_REVERB_PRESET 0x000108AD +/* ID of the Reverb wet mix parameter used by + * AUDPROC_MODULE_ID_REVERB. + */ +#define AUDPROC_PARAM_ID_REVERB_WET_MIX 0x000108AE +/* ID of the Reverb gain adjust parameter used by + * AUDPROC_MODULE_ID_REVERB. + */ +#define AUDPROC_PARAM_ID_REVERB_GAIN_ADJUST 0x000108AF +/* ID of the Reverb room level parameter used by + * AUDPROC_MODULE_ID_REVERB. + */ +#define AUDPROC_PARAM_ID_REVERB_ROOM_LEVEL 0x000108B0 +/* ID of the Reverb room hf level parameter used by + * AUDPROC_MODULE_ID_REVERB. + */ +#define AUDPROC_PARAM_ID_REVERB_ROOM_HF_LEVEL 0x000108B1 +/* ID of the Reverb decay time parameter used by + * AUDPROC_MODULE_ID_REVERB. + */ +#define AUDPROC_PARAM_ID_REVERB_DECAY_TIME 0x000108B2 +/* ID of the Reverb decay hf ratio parameter used by + * AUDPROC_MODULE_ID_REVERB. + */ +#define AUDPROC_PARAM_ID_REVERB_DECAY_HF_RATIO 0x000108B3 +/* ID of the Reverb reflections level parameter used by + * AUDPROC_MODULE_ID_REVERB. + */ +#define AUDPROC_PARAM_ID_REVERB_REFLECTIONS_LEVEL 0x000108B4 +/* ID of the Reverb reflections delay parameter used by + * AUDPROC_MODULE_ID_REVERB. + */ +#define AUDPROC_PARAM_ID_REVERB_REFLECTIONS_DELAY 0x000108B5 +/* ID of the Reverb level parameter used by + * AUDPROC_MODULE_ID_REVERB. + */ +#define AUDPROC_PARAM_ID_REVERB_LEVEL 0x000108B6 +/* ID of the Reverb delay parameter used by + * AUDPROC_MODULE_ID_REVERB. + */ +#define AUDPROC_PARAM_ID_REVERB_DELAY 0x000108B7 +/* ID of the Reverb diffusion parameter used by + * AUDPROC_MODULE_ID_REVERB. + */ +#define AUDPROC_PARAM_ID_REVERB_DIFFUSION 0x000108B8 +/* ID of the Reverb density parameter used by + * AUDPROC_MODULE_ID_REVERB. + */ +#define AUDPROC_PARAM_ID_REVERB_DENSITY 0x000108B9 + +/* ID of the Popless Equalizer module. This module supports the + * following parameter IDs: + * - #AUDPROC_PARAM_ID_EQ_ENABLE + * - #AUDPROC_PARAM_ID_EQ_CONFIG + * - #AUDPROC_PARAM_ID_EQ_NUM_BANDS + * - #AUDPROC_PARAM_ID_EQ_BAND_LEVELS + * - #AUDPROC_PARAM_ID_EQ_BAND_LEVEL_RANGE + * - #AUDPROC_PARAM_ID_EQ_BAND_FREQS + * - #AUDPROC_PARAM_ID_EQ_SINGLE_BAND_FREQ_RANGE + * - #AUDPROC_PARAM_ID_EQ_SINGLE_BAND_FREQ + * - #AUDPROC_PARAM_ID_EQ_BAND_INDEX + * - #AUDPROC_PARAM_ID_EQ_PRESET_ID + * - #AUDPROC_PARAM_ID_EQ_NUM_PRESETS + * - #AUDPROC_PARAM_ID_EQ_GET_PRESET_NAME + */ +#define AUDPROC_MODULE_ID_POPLESS_EQUALIZER 0x000108BA +/* ID of the Popless Equalizer enable parameter used by + * AUDPROC_MODULE_ID_POPLESS_EQUALIZER. + */ +#define AUDPROC_PARAM_ID_EQ_ENABLE 0x000108BB +/* ID of the Popless Equalizer config parameter used by + * AUDPROC_MODULE_ID_POPLESS_EQUALIZER. + */ +#define AUDPROC_PARAM_ID_EQ_CONFIG 0x000108BC +/* ID of the Popless Equalizer number of bands parameter used + * by AUDPROC_MODULE_ID_POPLESS_EQUALIZER. This param ID is + * used for get param only. + */ +#define AUDPROC_PARAM_ID_EQ_NUM_BANDS 0x000108BD +/* ID of the Popless Equalizer band levels parameter used by + * AUDPROC_MODULE_ID_POPLESS_EQUALIZER. This param ID is + * used for get param only. + */ +#define AUDPROC_PARAM_ID_EQ_BAND_LEVELS 0x000108BE +/* ID of the Popless Equalizer band level range parameter used + * by AUDPROC_MODULE_ID_POPLESS_EQUALIZER. This param ID is + * used for get param only. + */ +#define AUDPROC_PARAM_ID_EQ_BAND_LEVEL_RANGE 0x000108BF +/* ID of the Popless Equalizer band frequencies parameter used + * by AUDPROC_MODULE_ID_POPLESS_EQUALIZER. This param ID is + * used for get param only. + */ +#define AUDPROC_PARAM_ID_EQ_BAND_FREQS 0x000108C0 +/* ID of the Popless Equalizer single band frequency range + * parameter used by AUDPROC_MODULE_ID_POPLESS_EQUALIZER. + * This param ID is used for get param only. + */ +#define AUDPROC_PARAM_ID_EQ_SINGLE_BAND_FREQ_RANGE 0x000108C1 +/* ID of the Popless Equalizer single band frequency parameter + * used by AUDPROC_MODULE_ID_POPLESS_EQUALIZER. This param ID + * is used for set param only. + */ +#define AUDPROC_PARAM_ID_EQ_SINGLE_BAND_FREQ 0x000108C2 +/* ID of the Popless Equalizer band index parameter used by + * AUDPROC_MODULE_ID_POPLESS_EQUALIZER. + */ +#define AUDPROC_PARAM_ID_EQ_BAND_INDEX 0x000108C3 +/* ID of the Popless Equalizer preset id parameter used by + * AUDPROC_MODULE_ID_POPLESS_EQUALIZER. This param ID is used + * for get param only. + */ +#define AUDPROC_PARAM_ID_EQ_PRESET_ID 0x000108C4 +/* ID of the Popless Equalizer number of presets parameter used + * by AUDPROC_MODULE_ID_POPLESS_EQUALIZER. This param ID is used + * for get param only. + */ +#define AUDPROC_PARAM_ID_EQ_NUM_PRESETS 0x000108C5 +/* ID of the Popless Equalizer preset name parameter used by + * AUDPROC_MODULE_ID_POPLESS_EQUALIZER. This param ID is used + * for get param only. + */ +#define AUDPROC_PARAM_ID_EQ_PRESET_NAME 0x000108C6 + +/* Set Q6 topologies */ +#define ASM_CMD_ADD_TOPOLOGIES 0x00010DBE +#define ADM_CMD_ADD_TOPOLOGIES 0x00010335 +#define AFE_CMD_ADD_TOPOLOGIES 0x000100f8 +/* structure used for both ioctls */ +struct cmd_set_topologies { + struct apr_hdr hdr; + u32 payload_addr_lsw; + /* LSW of parameter data payload address.*/ + u32 payload_addr_msw; + /* MSW of parameter data payload address.*/ + u32 mem_map_handle; + /* Memory map handle returned by mem map command */ + u32 payload_size; + /* Size in bytes of the variable payload in shared memory */ +} __packed; + +/* This module represents the Rx processing of Feedback speaker protection. + * It contains the excursion control, thermal protection, + * analog clip manager features in it. + * This module id will support following param ids. + * - AFE_PARAM_ID_FBSP_MODE_RX_CFG + */ + +#define AFE_MODULE_FB_SPKR_PROT_RX 0x0001021C +#define AFE_MODULE_FB_SPKR_PROT_V2_RX 0x0001025F + +#define AFE_PARAM_ID_FBSP_MODE_RX_CFG 0x0001021D +#define AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG 0x00010260 + +struct asm_fbsp_mode_rx_cfg { + uint32_t minor_version; + uint32_t mode; +} __packed; + +/* This module represents the VI processing of feedback speaker protection. + * It will receive Vsens and Isens from codec and generates necessary + * parameters needed by Rx processing. + * This module id will support following param ids. + * - AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG + * - AFE_PARAM_ID_CALIB_RES_CFG + * - AFE_PARAM_ID_FEEDBACK_PATH_CFG + */ + +#define AFE_MODULE_FB_SPKR_PROT_VI_PROC 0x00010226 +#define AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2 0x0001026A + +#define AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG 0x0001022A +#define AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2 0x0001026B + +struct asm_spkr_calib_vi_proc_cfg { + uint32_t minor_version; + uint32_t operation_mode; + uint32_t r0_t0_selection_flag[SP_V2_NUM_MAX_SPKR]; + int32_t r0_cali_q24[SP_V2_NUM_MAX_SPKR]; + int16_t t0_cali_q6[SP_V2_NUM_MAX_SPKR]; + uint32_t quick_calib_flag; +} __packed; + +#define AFE_PARAM_ID_CALIB_RES_CFG 0x0001022B +#define AFE_PARAM_ID_CALIB_RES_CFG_V2 0x0001026E + +struct asm_calib_res_cfg { + uint32_t minor_version; + int32_t r0_cali_q24[SP_V2_NUM_MAX_SPKR]; + uint32_t th_vi_ca_state; +} __packed; + +#define AFE_PARAM_ID_FEEDBACK_PATH_CFG 0x0001022C +#define AFE_MODULE_FEEDBACK 0x00010257 + +struct asm_feedback_path_cfg { + uint32_t minor_version; + int32_t dst_portid; + int32_t num_channels; + int32_t chan_info[4]; +} __packed; + +#define AFE_PARAM_ID_MODE_VI_PROC_CFG 0x00010227 + +struct asm_mode_vi_proc_cfg { + uint32_t minor_version; + uint32_t cal_mode; +} __packed; + +#define AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI 0x0001026A +#define AFE_PARAM_ID_SP_V2_TH_VI_MODE_CFG 0x0001026B +#define AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG 0x0001029F +#define AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS 0x000102A0 + +struct afe_sp_th_vi_mode_cfg { + uint32_t minor_version; + uint32_t operation_mode; + /* + * Operation mode of thermal VI module. + * 0 -- Normal Running mode + * 1 -- Calibration mode + * 2 -- FTM mode + */ + uint32_t r0t0_selection_flag[SP_V2_NUM_MAX_SPKR]; + /* + * Specifies which set of R0, T0 values the algorithm will use. + * This field is valid only in Normal mode (operation_mode = 0). + * 0 -- Use calibrated R0, T0 value + * 1 -- Use safe R0, T0 value + */ + int32_t r0_cali_q24[SP_V2_NUM_MAX_SPKR]; + /* + * Calibration point resistance per device. This field is valid + * only in Normal mode (operation_mode = 0). + * values 33554432 to 1073741824 Ohms (in Q24 format) + */ + int16_t t0_cali_q6[SP_V2_NUM_MAX_SPKR]; + /* + * Calibration point temperature per device. This field is valid + * in both Normal mode and Calibration mode. + * values -1920 to 5120 degrees C (in Q6 format) + */ + uint32_t quick_calib_flag; + /* + * Indicates whether calibration is to be done in quick mode or not. + * This field is valid only in Calibration mode (operation_mode = 1). + * 0 -- Disabled + * 1 -- Enabled + */ +} __packed; + +struct afe_sp_th_vi_ftm_cfg { + uint32_t minor_version; + uint32_t wait_time_ms[SP_V2_NUM_MAX_SPKR]; + /* + * Wait time to heat up speaker before collecting statistics + * for ftm mode in ms. + * values 0 to 4294967295 ms + */ + uint32_t ftm_time_ms[SP_V2_NUM_MAX_SPKR]; + /* + * duration for which FTM statistics are collected in ms. + * values 0 to 2000 ms + */ +} __packed; + +struct afe_sp_th_vi_ftm_params { + uint32_t minor_version; + int32_t dc_res_q24[SP_V2_NUM_MAX_SPKR]; + /* + * DC resistance value in q24 format + * values 0 to 2147483647 Ohms (in Q24 format) + */ + int32_t temp_q22[SP_V2_NUM_MAX_SPKR]; + /* + * temperature value in q22 format + * values -125829120 to 2147483647 degC (in Q22 format) + */ + uint32_t status[SP_V2_NUM_MAX_SPKR]; + /* + * FTM packet status + * 0 - Incorrect operation mode.This status is returned + * when GET_PARAM is called in non FTM Mode + * 1 - Inactive mode -- Port is not yet started. + * 2 - Wait state. wait_time_ms has not yet elapsed + * 3 - In progress state. ftm_time_ms has not yet elapsed. + * 4 - Success. + * 5 - Failed. + */ +} __packed; + +struct afe_sp_th_vi_get_param { + struct apr_hdr hdr; + struct afe_port_cmd_get_param_v2 get_param; + struct afe_port_param_data_v2 pdata; + struct afe_sp_th_vi_ftm_params param; +} __packed; + +struct afe_sp_th_vi_get_param_resp { + uint32_t status; + struct afe_port_param_data_v2 pdata; + struct afe_sp_th_vi_ftm_params param; +} __packed; + + +#define AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI 0x0001026F +#define AFE_PARAM_ID_SP_V2_EX_VI_MODE_CFG 0x000102A1 +#define AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG 0x000102A2 +#define AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS 0x000102A3 + +struct afe_sp_ex_vi_mode_cfg { + uint32_t minor_version; + uint32_t operation_mode; + /* + * Operation mode of Excursion VI module. + * 0 - Normal Running mode + * 2 - FTM mode + */ +} __packed; + +struct afe_sp_ex_vi_ftm_cfg { + uint32_t minor_version; + uint32_t wait_time_ms[SP_V2_NUM_MAX_SPKR]; + /* + * Wait time to heat up speaker before collecting statistics + * for ftm mode in ms. + * values 0 to 4294967295 ms + */ + uint32_t ftm_time_ms[SP_V2_NUM_MAX_SPKR]; + /* + * duration for which FTM statistics are collected in ms. + * values 0 to 2000 ms + */ +} __packed; + +struct afe_sp_ex_vi_ftm_params { + uint32_t minor_version; + int32_t freq_q20[SP_V2_NUM_MAX_SPKR]; + /* + * Resonance frequency in q20 format + * values 0 to 2147483647 Hz (in Q20 format) + */ + int32_t resis_q24[SP_V2_NUM_MAX_SPKR]; + /* + * Mechanical resistance in q24 format + * values 0 to 2147483647 Ohms (in Q24 format) + */ + int32_t qmct_q24[SP_V2_NUM_MAX_SPKR]; + /* + * Mechanical Qfactor in q24 format + * values 0 to 2147483647 (in Q24 format) + */ + uint32_t status[SP_V2_NUM_MAX_SPKR]; + /* + * FTM packet status + * 0 - Incorrect operation mode.This status is returned + * when GET_PARAM is called in non FTM Mode. + * 1 - Inactive mode -- Port is not yet started. + * 2 - Wait state. wait_time_ms has not yet elapsed + * 3 - In progress state. ftm_time_ms has not yet elapsed. + * 4 - Success. + * 5 - Failed. + */ +} __packed; + +struct afe_sp_ex_vi_get_param { + struct apr_hdr hdr; + struct afe_port_cmd_get_param_v2 get_param; + struct afe_port_param_data_v2 pdata; + struct afe_sp_ex_vi_ftm_params param; +} __packed; + +struct afe_sp_ex_vi_get_param_resp { + uint32_t status; + struct afe_port_param_data_v2 pdata; + struct afe_sp_ex_vi_ftm_params param; +} __packed; + +union afe_spkr_prot_config { + struct asm_fbsp_mode_rx_cfg mode_rx_cfg; + struct asm_spkr_calib_vi_proc_cfg vi_proc_cfg; + struct asm_feedback_path_cfg feedback_path_cfg; + struct asm_mode_vi_proc_cfg mode_vi_proc_cfg; + struct afe_sp_th_vi_mode_cfg th_vi_mode_cfg; + struct afe_sp_th_vi_ftm_cfg th_vi_ftm_cfg; + struct afe_sp_ex_vi_mode_cfg ex_vi_mode_cfg; + struct afe_sp_ex_vi_ftm_cfg ex_vi_ftm_cfg; +} __packed; + +struct afe_spkr_prot_config_command { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + union afe_spkr_prot_config prot_config; +} __packed; + +struct afe_spkr_prot_get_vi_calib { + struct apr_hdr hdr; + struct afe_port_cmd_get_param_v2 get_param; + struct afe_port_param_data_v2 pdata; + struct asm_calib_res_cfg res_cfg; +} __packed; + +struct afe_spkr_prot_calib_get_resp { + uint32_t status; + struct afe_port_param_data_v2 pdata; + struct asm_calib_res_cfg res_cfg; +} __packed; + + +/* SRS TRUMEDIA start */ +/* topology */ +#define SRS_TRUMEDIA_TOPOLOGY_ID 0x00010D90 +/* module */ +#define SRS_TRUMEDIA_MODULE_ID 0x10005010 +/* parameters */ +#define SRS_TRUMEDIA_PARAMS 0x10005011 +#define SRS_TRUMEDIA_PARAMS_WOWHD 0x10005012 +#define SRS_TRUMEDIA_PARAMS_CSHP 0x10005013 +#define SRS_TRUMEDIA_PARAMS_HPF 0x10005014 +#define SRS_TRUMEDIA_PARAMS_AEQ 0x10005015 +#define SRS_TRUMEDIA_PARAMS_HL 0x10005016 +#define SRS_TRUMEDIA_PARAMS_GEQ 0x10005017 + +#define SRS_ID_GLOBAL 0x00000001 +#define SRS_ID_WOWHD 0x00000002 +#define SRS_ID_CSHP 0x00000003 +#define SRS_ID_HPF 0x00000004 +#define SRS_ID_AEQ 0x00000005 +#define SRS_ID_HL 0x00000006 +#define SRS_ID_GEQ 0x00000007 + +#define SRS_CMD_UPLOAD 0x7FFF0000 +#define SRS_PARAM_OFFSET_MASK 0x3FFF0000 +#define SRS_PARAM_VALUE_MASK 0x0000FFFF + +struct srs_trumedia_params_GLOBAL { + uint8_t v1; + uint8_t v2; + uint8_t v3; + uint8_t v4; + uint8_t v5; + uint8_t v6; + uint8_t v7; + uint8_t v8; + uint16_t v9; +} __packed; + +struct srs_trumedia_params_WOWHD { + uint32_t v1; + uint16_t v2; + uint16_t v3; + uint16_t v4; + uint16_t v5; + uint16_t v6; + uint16_t v7; + uint16_t v8; + uint16_t v____A1; + uint32_t v9; + uint16_t v10; + uint16_t v11; + uint32_t v12[16]; + uint32_t v13[16]; + uint32_t v14[16]; + uint32_t v15[16]; + uint32_t v16; + uint16_t v17; + uint16_t v18; +} __packed; + +struct srs_trumedia_params_CSHP { + uint32_t v1; + uint16_t v2; + uint16_t v3; + uint16_t v4; + uint16_t v5; + uint16_t v6; + uint16_t v____A1; + uint32_t v7; + uint16_t v8; + uint16_t v9; + uint32_t v10[16]; +} __packed; + +struct srs_trumedia_params_HPF { + uint32_t v1; + uint32_t v2[26]; +} __packed; + +struct srs_trumedia_params_AEQ { + uint32_t v1; + uint16_t v2; + uint16_t v3; + uint16_t v4; + uint16_t v____A1; + uint32_t v5[74]; + uint32_t v6[74]; + uint16_t v7[2048]; +} __packed; + +struct srs_trumedia_params_HL { + uint16_t v1; + uint16_t v2; + uint16_t v3; + uint16_t v____A1; + int32_t v4; + uint32_t v5; + uint16_t v6; + uint16_t v____A2; + uint32_t v7; +} __packed; + +struct srs_trumedia_params_GEQ { + int16_t v1[10]; +} __packed; +struct srs_trumedia_params { + struct srs_trumedia_params_GLOBAL global; + struct srs_trumedia_params_WOWHD wowhd; + struct srs_trumedia_params_CSHP cshp; + struct srs_trumedia_params_HPF hpf; + struct srs_trumedia_params_AEQ aeq; + struct srs_trumedia_params_HL hl; + struct srs_trumedia_params_GEQ geq; +} __packed; +/* SRS TruMedia end */ + +#define AUDPROC_PARAM_ID_ENABLE 0x00010904 +#define ASM_STREAM_POSTPROC_TOPO_ID_SA_PLUS 0x1000FFFF +/* DTS Eagle */ +#define AUDPROC_MODULE_ID_DTS_HPX_PREMIX 0x0001077C +#define AUDPROC_MODULE_ID_DTS_HPX_POSTMIX 0x0001077B +#define ASM_STREAM_POSTPROC_TOPO_ID_DTS_HPX 0x00010DED +#define ASM_STREAM_POSTPROC_TOPO_ID_HPX_PLUS 0x10015000 +#define ASM_STREAM_POSTPROC_TOPO_ID_HPX_MASTER 0x10015001 +struct asm_dts_eagle_param { + struct apr_hdr hdr; + struct asm_stream_cmd_set_pp_params_v2 param; + struct asm_stream_param_data_v2 data; +} __packed; + +struct asm_dts_eagle_param_get { + struct apr_hdr hdr; + struct asm_stream_cmd_get_pp_params_v2 param; +} __packed; + +/* Opcode to set BT address and license for aptx decoder */ +#define APTX_DECODER_BT_ADDRESS 0x00013201 +#define APTX_CLASSIC_DEC_LICENSE_ID 0x00013202 + +struct aptx_dec_bt_addr_cfg { + uint32_t lap; + uint32_t uap; + uint32_t nap; +} __packed; + +struct aptx_dec_bt_dev_addr { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + struct aptx_dec_bt_addr_cfg bt_addr_cfg; +} __packed; + +struct asm_aptx_dec_fmt_blk_v2 { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmtblk; + u32 sample_rate; +/* Number of samples per second. + * Supported values: 44100 and 48000 Hz + */ +} __packed; + +/* LSM Specific */ +#define VW_FEAT_DIM (39) + +#define APRV2_IDS_SERVICE_ID_ADSP_LSM_V (0xD) +#define APRV2_IDS_DOMAIN_ID_ADSP_V (0x4) +#define APRV2_IDS_DOMAIN_ID_APPS_V (0x5) + +#define LSM_SESSION_CMD_SHARED_MEM_MAP_REGIONS (0x00012A7F) +#define LSM_SESSION_CMDRSP_SHARED_MEM_MAP_REGIONS (0x00012A80) +#define LSM_SESSION_CMD_SHARED_MEM_UNMAP_REGIONS (0x00012A81) +#define LSM_SESSION_CMD_OPEN_TX (0x00012A82) +#define LSM_SESSION_CMD_CLOSE_TX (0x00012A88) +#define LSM_SESSION_CMD_SET_PARAMS (0x00012A83) +#define LSM_SESSION_CMD_SET_PARAMS_V2 (0x00012A8F) +#define LSM_SESSION_CMD_REGISTER_SOUND_MODEL (0x00012A84) +#define LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL (0x00012A85) +#define LSM_SESSION_CMD_START (0x00012A86) +#define LSM_SESSION_CMD_STOP (0x00012A87) +#define LSM_SESSION_CMD_EOB (0x00012A89) +#define LSM_SESSION_CMD_READ (0x00012A8A) +#define LSM_SESSION_CMD_OPEN_TX_V2 (0x00012A8B) +#define LSM_CMD_ADD_TOPOLOGIES (0x00012A8C) + +#define LSM_SESSION_EVENT_DETECTION_STATUS (0x00012B00) +#define LSM_SESSION_EVENT_DETECTION_STATUS_V2 (0x00012B01) +#define LSM_DATA_EVENT_READ_DONE (0x00012B02) +#define LSM_DATA_EVENT_STATUS (0x00012B03) +#define LSM_SESSION_EVENT_DETECTION_STATUS_V3 (0x00012B04) + +#define LSM_MODULE_ID_VOICE_WAKEUP (0x00012C00) +#define LSM_PARAM_ID_ENDPOINT_DETECT_THRESHOLD (0x00012C01) +#define LSM_PARAM_ID_OPERATION_MODE (0x00012C02) +#define LSM_PARAM_ID_GAIN (0x00012C03) +#define LSM_PARAM_ID_CONNECT_TO_PORT (0x00012C04) +#define LSM_PARAM_ID_FEATURE_COMPENSATION_DATA (0x00012C07) +#define LSM_PARAM_ID_MIN_CONFIDENCE_LEVELS (0x00012C07) +#define LSM_MODULE_ID_LAB (0x00012C08) +#define LSM_PARAM_ID_LAB_ENABLE (0x00012C09) +#define LSM_PARAM_ID_LAB_CONFIG (0x00012C0A) +#define LSM_MODULE_ID_FRAMEWORK (0x00012C0E) +#define LSM_PARAM_ID_SWMAD_CFG (0x00012C18) +#define LSM_PARAM_ID_SWMAD_MODEL (0x00012C19) +#define LSM_PARAM_ID_SWMAD_ENABLE (0x00012C1A) +#define LSM_PARAM_ID_POLLING_ENABLE (0x00012C1B) +#define LSM_PARAM_ID_MEDIA_FMT (0x00012C1E) +#define LSM_PARAM_ID_FWK_MODE_CONFIG (0x00012C27) + +/* HW MAD specific */ +#define AFE_MODULE_HW_MAD (0x00010230) +#define AFE_PARAM_ID_HW_MAD_CFG (0x00010231) +#define AFE_PARAM_ID_HW_MAD_CTRL (0x00010232) +#define AFE_PARAM_ID_SLIMBUS_SLAVE_PORT_CFG (0x00010233) + +/* SW MAD specific */ +#define AFE_MODULE_SW_MAD (0x0001022D) +#define AFE_PARAM_ID_SW_MAD_CFG (0x0001022E) +#define AFE_PARAM_ID_SVM_MODEL (0x0001022F) + +/* Commands/Params to pass the codec/slimbus data to DSP */ +#define AFE_SVC_CMD_SET_PARAM (0x000100f3) +#define AFE_MODULE_CDC_DEV_CFG (0x00010234) +#define AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG (0x00010235) +#define AFE_PARAM_ID_CDC_REG_CFG (0x00010236) +#define AFE_PARAM_ID_CDC_REG_CFG_INIT (0x00010237) +#define AFE_PARAM_ID_CDC_REG_PAGE_CFG (0x00010296) + +#define AFE_MAX_CDC_REGISTERS_TO_CONFIG (20) + +/* AANC Port Config Specific */ +#define AFE_PARAM_ID_AANC_PORT_CONFIG (0x00010215) +#define AFE_API_VERSION_AANC_PORT_CONFIG (0x1) +#define AANC_TX_MIC_UNUSED (0) +#define AANC_TX_VOICE_MIC (1) +#define AANC_TX_ERROR_MIC (2) +#define AANC_TX_NOISE_MIC (3) +#define AFE_PORT_MAX_CHANNEL_CNT (8) +#define AFE_MODULE_AANC (0x00010214) +#define AFE_PARAM_ID_CDC_AANC_VERSION (0x0001023A) +#define AFE_API_VERSION_CDC_AANC_VERSION (0x1) +#define AANC_HW_BLOCK_VERSION_1 (1) +#define AANC_HW_BLOCK_VERSION_2 (2) + +/*Clip bank selection*/ +#define AFE_API_VERSION_CLIP_BANK_SEL_CFG 0x1 +#define AFE_CLIP_MAX_BANKS 4 +#define AFE_PARAM_ID_CLIP_BANK_SEL_CFG 0x00010242 + +struct afe_param_aanc_port_cfg { + /* Minor version used for tracking the version of the module's + * source port configuration. + */ + uint32_t aanc_port_cfg_minor_version; + + /* Sampling rate of the source Tx port. 8k - 192k*/ + uint32_t tx_port_sample_rate; + + /* Channel mapping for the Tx port signal carrying Noise (X), + * Error (E), and Voice (V) signals. + */ + uint8_t tx_port_channel_map[AFE_PORT_MAX_CHANNEL_CNT]; + + /* Number of channels on the source Tx port. */ + uint16_t tx_port_num_channels; + + /* Port ID of the Rx path reference signal. */ + uint16_t rx_path_ref_port_id; + + /* Sampling rate of the reference port. 8k - 192k*/ + uint32_t ref_port_sample_rate; +} __packed; + +struct afe_param_id_cdc_aanc_version { + /* Minor version used for tracking the version of the module's + * hw version + */ + uint32_t cdc_aanc_minor_version; + + /* HW version. */ + uint32_t aanc_hw_version; +} __packed; + +struct afe_param_id_clip_bank_sel { + /* Minor version used for tracking the version of the module's + * hw version + */ + uint32_t minor_version; + + /* Number of banks to be read */ + uint32_t num_banks; + + uint32_t bank_map[AFE_CLIP_MAX_BANKS]; +} __packed; + +/* ERROR CODES */ +/* Success. The operation completed with no errors. */ +#define ADSP_EOK 0x00000000 +/* General failure. */ +#define ADSP_EFAILED 0x00000001 +/* Bad operation parameter. */ +#define ADSP_EBADPARAM 0x00000002 +/* Unsupported routine or operation. */ +#define ADSP_EUNSUPPORTED 0x00000003 +/* Unsupported version. */ +#define ADSP_EVERSION 0x00000004 +/* Unexpected problem encountered. */ +#define ADSP_EUNEXPECTED 0x00000005 +/* Unhandled problem occurred. */ +#define ADSP_EPANIC 0x00000006 +/* Unable to allocate resource. */ +#define ADSP_ENORESOURCE 0x00000007 +/* Invalid handle. */ +#define ADSP_EHANDLE 0x00000008 +/* Operation is already processed. */ +#define ADSP_EALREADY 0x00000009 +/* Operation is not ready to be processed. */ +#define ADSP_ENOTREADY 0x0000000A +/* Operation is pending completion. */ +#define ADSP_EPENDING 0x0000000B +/* Operation could not be accepted or processed. */ +#define ADSP_EBUSY 0x0000000C +/* Operation aborted due to an error. */ +#define ADSP_EABORTED 0x0000000D +/* Operation preempted by a higher priority. */ +#define ADSP_EPREEMPTED 0x0000000E +/* Operation requests intervention to complete. */ +#define ADSP_ECONTINUE 0x0000000F +/* Operation requests immediate intervention to complete. */ +#define ADSP_EIMMEDIATE 0x00000010 +/* Operation is not implemented. */ +#define ADSP_ENOTIMPL 0x00000011 +/* Operation needs more data or resources. */ +#define ADSP_ENEEDMORE 0x00000012 +/* Operation does not have memory. */ +#define ADSP_ENOMEMORY 0x00000014 +/* Item does not exist. */ +#define ADSP_ENOTEXIST 0x00000015 +/* Max count for adsp error code sent to HLOS*/ +#define ADSP_ERR_MAX (ADSP_ENOTEXIST + 1) +/* Operation is finished. */ +#define ADSP_ETERMINATED 0x00011174 + +/*bharath, adsp_error_codes.h */ + +/* LPASS clock for I2S Interface */ + +/* Supported OSR clock values */ +#define Q6AFE_LPASS_OSR_CLK_12_P288_MHZ 0xBB8000 +#define Q6AFE_LPASS_OSR_CLK_11_P2896_MHZ 0xAC4400 +#define Q6AFE_LPASS_OSR_CLK_9_P600_MHZ 0x927C00 +#define Q6AFE_LPASS_OSR_CLK_8_P192_MHZ 0x7D0000 +#define Q6AFE_LPASS_OSR_CLK_6_P144_MHZ 0x5DC000 +#define Q6AFE_LPASS_OSR_CLK_4_P096_MHZ 0x3E8000 +#define Q6AFE_LPASS_OSR_CLK_3_P072_MHZ 0x2EE000 +#define Q6AFE_LPASS_OSR_CLK_2_P048_MHZ 0x1F4000 +#define Q6AFE_LPASS_OSR_CLK_1_P536_MHZ 0x177000 +#define Q6AFE_LPASS_OSR_CLK_1_P024_MHZ 0xFA000 +#define Q6AFE_LPASS_OSR_CLK_768_kHZ 0xBB800 +#define Q6AFE_LPASS_OSR_CLK_512_kHZ 0x7D000 +#define Q6AFE_LPASS_OSR_CLK_DISABLE 0x0 + +/* Supported Bit clock values */ +#define Q6AFE_LPASS_IBIT_CLK_12_P288_MHZ 0xBB8000 +#define Q6AFE_LPASS_IBIT_CLK_11_P2896_MHZ 0xAC4400 +#define Q6AFE_LPASS_IBIT_CLK_8_P192_MHZ 0x7D0000 +#define Q6AFE_LPASS_IBIT_CLK_6_P144_MHZ 0x5DC000 +#define Q6AFE_LPASS_IBIT_CLK_4_P096_MHZ 0x3E8000 +#define Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ 0x2EE000 +#define Q6AFE_LPASS_IBIT_CLK_2_P8224_MHZ 0x2b1100 +#define Q6AFE_LPASS_IBIT_CLK_2_P048_MHZ 0x1F4000 +#define Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ 0x177000 +#define Q6AFE_LPASS_IBIT_CLK_1_P4112_MHZ 0x158880 +#define Q6AFE_LPASS_IBIT_CLK_1_P024_MHZ 0xFA000 +#define Q6AFE_LPASS_IBIT_CLK_768_KHZ 0xBB800 +#define Q6AFE_LPASS_IBIT_CLK_512_KHZ 0x7D000 +#define Q6AFE_LPASS_IBIT_CLK_256_KHZ 0x3E800 +#define Q6AFE_LPASS_IBIT_CLK_DISABLE 0x0 + +/* Supported LPASS CLK sources */ +#define Q6AFE_LPASS_CLK_SRC_EXTERNAL 0 +#define Q6AFE_LPASS_CLK_SRC_INTERNAL 1 + +/* Supported LPASS CLK root*/ +#define Q6AFE_LPASS_CLK_ROOT_DEFAULT 0 + +enum afe_lpass_clk_mode { + Q6AFE_LPASS_MODE_BOTH_INVALID, + Q6AFE_LPASS_MODE_CLK1_VALID, + Q6AFE_LPASS_MODE_CLK2_VALID, + Q6AFE_LPASS_MODE_BOTH_VALID, +} __packed; + +/* Clock ID Enumeration Define. */ +/* Clock ID for Primary I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT 0x100 +/* Clock ID for Primary I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT 0x101 +/* Clock ID for Secondary I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT 0x102 +/* Clock ID for Secondary I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT 0x103 +/* Clock ID for Tertiary I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT 0x104 +/* Clock ID for Tertiary I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT 0x105 +/* Clock ID for Quartnery I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT 0x106 +/* Clock ID for Quartnery I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT 0x107 +/* Clock ID for Speaker I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_IBIT 0x108 +/* Clock ID for Speaker I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_EBIT 0x109 +/* Clock ID for Speaker I2S OSR */ +#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR 0x10A + +/* Clock ID for QUINARY I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT 0x10B +/* Clock ID for QUINARY I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT 0x10C +/* Clock ID for SENARY I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT 0x10D +/* Clock ID for SENARY I2S EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEN_MI2S_EBIT 0x10E +/* Clock ID for INT0 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT0_MI2S_IBIT 0x10F +/* Clock ID for INT1 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT1_MI2S_IBIT 0x110 +/* Clock ID for INT2 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT2_MI2S_IBIT 0x111 +/* Clock ID for INT3 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT3_MI2S_IBIT 0x112 +/* Clock ID for INT4 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT4_MI2S_IBIT 0x113 +/* Clock ID for INT5 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT5_MI2S_IBIT 0x114 +/* Clock ID for INT6 I2S IBIT */ +#define Q6AFE_LPASS_CLK_ID_INT6_MI2S_IBIT 0x115 + +/* Clock ID for Primary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT 0x200 +/* Clock ID for Primary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_PCM_EBIT 0x201 +/* Clock ID for Secondary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_PCM_IBIT 0x202 +/* Clock ID for Secondary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_PCM_EBIT 0x203 +/* Clock ID for Tertiary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT 0x204 +/* Clock ID for Tertiary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_PCM_EBIT 0x205 +/* Clock ID for Quartery PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT 0x206 +/* Clock ID for Quartery PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_PCM_EBIT 0x207 + +/** Clock ID for Primary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT 0x200 +/** Clock ID for Primary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_PRI_TDM_EBIT 0x201 +/** Clock ID for Secondary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT 0x202 +/** Clock ID for Secondary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEC_TDM_EBIT 0x203 +/** Clock ID for Tertiary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT 0x204 +/** Clock ID for Tertiary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_TER_TDM_EBIT 0x205 +/** Clock ID for Quartery TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT 0x206 +/** Clock ID for Quartery TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUAD_TDM_EBIT 0x207 + +/* Clock ID for MCLK1 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_1 0x300 +/* Clock ID for MCLK2 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_2 0x301 +/* Clock ID for MCLK3 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_3 0x302 +/* Clock ID for MCLK4 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_4 0x304 +/* Clock ID for Internal Digital Codec Core */ +#define Q6AFE_LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE 0x303 +/* Clock ID for INT MCLK0 */ +#define Q6AFE_LPASS_CLK_ID_INT_MCLK_0 0x305 +/* Clock ID for INT MCLK1 */ +#define Q6AFE_LPASS_CLK_ID_INT_MCLK_1 0x306 +/* + * Clock ID for soundwire NPL. + * This is the clock to be used to enable NPL clock for internal Soundwire. + */ +#define AFE_CLOCK_SET_CLOCK_ID_SWR_NPL_CLK 0x307 + +/* Clock ID for AHB HDMI input */ +#define Q6AFE_LPASS_CLK_ID_AHB_HDMI_INPUT 0x400 + +/* Clock ID for SPDIF core */ +#define Q6AFE_LPASS_CLK_ID_SPDIF_CORE 0x500 + + +/* Clock attribute for invalid use (reserved for internal usage) */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_INVALID 0x0 +/* Clock attribute for no couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO 0x1 +/* Clock attribute for dividend couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVIDEND 0x2 +/* Clock attribute for divisor couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR 0x3 +/* Clock attribute for invert and no couple case */ +#define Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO 0x4 +/* Clock set API version */ +#define Q6AFE_LPASS_CLK_CONFIG_API_VERSION 0x1 + +struct afe_clk_set { + /* + * Minor version used for tracking clock set. + * @values #AFE_API_VERSION_CLOCK_SET + */ + uint32_t clk_set_minor_version; + + /* + * Clock ID + * @values + * - 0x100 to 0x10A - MSM8996 + * - 0x200 to 0x207 - MSM8996 + * - 0x300 to 0x302 - MSM8996 @tablebulletend + */ + uint32_t clk_id; + + /* + * Clock frequency (in Hertz) to be set. + * @values + * - >= 0 for clock frequency to set @tablebulletend + */ + uint32_t clk_freq_in_hz; + + /* Use to specific divider for two clocks if needed. + * Set to Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO for no divider + * relation clocks + * @values + * - #Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO + * - #Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVIDEND + * - #Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR @tablebulletend + */ + uint16_t clk_attri; + + /* + * Specifies the root clock source. + * Currently, only Q6AFE_LPASS_CLK_ROOT_DEFAULT is valid + * @values + * - 0 @tablebulletend + */ + uint16_t clk_root; + + /* + * for enable and disable clock. + * "clk_freq_in_hz", "clk_attri", and "clk_root" + * are ignored in disable clock case. + * @values  + * - 0 -- Disabled + * - 1 -- Enabled @tablebulletend + */ + uint32_t enable; +}; + +struct afe_clk_cfg { +/* Minor version used for tracking the version of the I2S + * configuration interface. + * Supported values: #AFE_API_VERSION_I2S_CONFIG + */ + u32 i2s_cfg_minor_version; + +/* clk value 1 in MHz. */ + u32 clk_val1; + +/* clk value 2 in MHz. */ + u32 clk_val2; + +/* clk_src + * #Q6AFE_LPASS_CLK_SRC_EXTERNAL + * #Q6AFE_LPASS_CLK_SRC_INTERNAL + */ + + u16 clk_src; + +/* clk_root -0 for default */ + u16 clk_root; + +/* clk_set_mode + * #Q6AFE_LPASS_MODE_BOTH_INVALID + * #Q6AFE_LPASS_MODE_CLK1_VALID + * #Q6AFE_LPASS_MODE_CLK2_VALID + * #Q6AFE_LPASS_MODE_BOTH_VALID + */ + u16 clk_set_mode; + +/* This param id is used to configure I2S clk */ + u16 reserved; +} __packed; + +/* This param id is used to configure I2S clk */ +#define AFE_PARAM_ID_LPAIF_CLK_CONFIG 0x00010238 +#define AFE_MODULE_CLOCK_SET 0x0001028F +#define AFE_PARAM_ID_CLOCK_SET 0x00010290 + +struct afe_lpass_clk_config_command { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + struct afe_clk_cfg clk_cfg; +} __packed; + +enum afe_lpass_digital_clk_src { + Q6AFE_LPASS_DIGITAL_ROOT_INVALID, + Q6AFE_LPASS_DIGITAL_ROOT_PRI_MI2S_OSR, + Q6AFE_LPASS_DIGITAL_ROOT_SEC_MI2S_OSR, + Q6AFE_LPASS_DIGITAL_ROOT_TER_MI2S_OSR, + Q6AFE_LPASS_DIGITAL_ROOT_QUAD_MI2S_OSR, + Q6AFE_LPASS_DIGITAL_ROOT_CDC_ROOT_CLK, +} __packed; + +/* This param id is used to configure internal clk */ +#define AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG 0x00010239 + +struct afe_digital_clk_cfg { +/* Minor version used for tracking the version of the I2S + * configuration interface. + * Supported values: #AFE_API_VERSION_I2S_CONFIG + */ + u32 i2s_cfg_minor_version; + +/* clk value in MHz. */ + u32 clk_val; + +/* INVALID + * PRI_MI2S_OSR + * SEC_MI2S_OSR + * TER_MI2S_OSR + * QUAD_MI2S_OSR + * DIGT_CDC_ROOT + */ + u16 clk_root; + +/* This field must be set to zero. */ + u16 reserved; +} __packed; + + +struct afe_lpass_digital_clk_config_command { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + struct afe_digital_clk_cfg clk_cfg; +} __packed; + +/* + * Opcode for AFE to start DTMF. + */ +#define AFE_PORTS_CMD_DTMF_CTL 0x00010102 + +/** DTMF payload.*/ +struct afe_dtmf_generation_command { + struct apr_hdr hdr; + + /* + * Duration of the DTMF tone in ms. + * -1 -> continuous, + * 0 -> disable + */ + int64_t duration_in_ms; + + /* + * The DTMF high tone frequency. + */ + uint16_t high_freq; + + /* + * The DTMF low tone frequency. + */ + uint16_t low_freq; + + /* + * The DTMF volume setting + */ + uint16_t gain; + + /* + * The number of ports to enable/disable on. + */ + uint16_t num_ports; + + /* + * The Destination ports - array . + * For DTMF on multiple ports, portIds needs to + * be populated numPorts times. + */ + uint16_t port_ids; + + /* + * variable for 32 bit alignment of APR packet. + */ + uint16_t reserved; +} __packed; + +enum afe_config_type { + AFE_SLIMBUS_SLAVE_PORT_CONFIG, + AFE_SLIMBUS_SLAVE_CONFIG, + AFE_CDC_REGISTERS_CONFIG, + AFE_AANC_VERSION, + AFE_CDC_CLIP_REGISTERS_CONFIG, + AFE_CLIP_BANK_SEL, + AFE_CDC_REGISTER_PAGE_CONFIG, + AFE_MAX_CONFIG_TYPES, +}; + +struct afe_param_slimbus_slave_port_cfg { + uint32_t minor_version; + uint16_t slimbus_dev_id; + uint16_t slave_dev_pgd_la; + uint16_t slave_dev_intfdev_la; + uint16_t bit_width; + uint16_t data_format; + uint16_t num_channels; + uint16_t slave_port_mapping[AFE_PORT_MAX_AUDIO_CHAN_CNT]; +} __packed; + +struct afe_param_cdc_slimbus_slave_cfg { + uint32_t minor_version; + uint32_t device_enum_addr_lsw; + uint32_t device_enum_addr_msw; + uint16_t tx_slave_port_offset; + uint16_t rx_slave_port_offset; +} __packed; + +struct afe_param_cdc_reg_cfg { + uint32_t minor_version; + uint32_t reg_logical_addr; + uint32_t reg_field_type; + uint32_t reg_field_bit_mask; + uint16_t reg_bit_width; + uint16_t reg_offset_scale; +} __packed; + +#define AFE_API_VERSION_CDC_REG_PAGE_CFG 1 + +enum { + AFE_CDC_REG_PAGE_ASSIGN_PROC_ID_0 = 0, + AFE_CDC_REG_PAGE_ASSIGN_PROC_ID_1, + AFE_CDC_REG_PAGE_ASSIGN_PROC_ID_2, + AFE_CDC_REG_PAGE_ASSIGN_PROC_ID_3, +}; + +struct afe_param_cdc_reg_page_cfg { + uint32_t minor_version; + uint32_t enable; + uint32_t proc_id; +} __packed; + +struct afe_param_cdc_reg_cfg_data { + uint32_t num_registers; + struct afe_param_cdc_reg_cfg *reg_data; +} __packed; + +struct afe_svc_cmd_set_param { + uint32_t payload_size; + uint32_t payload_address_lsw; + uint32_t payload_address_msw; + uint32_t mem_map_handle; +} __packed; + +struct afe_svc_param_data { + uint32_t module_id; + uint32_t param_id; + uint16_t param_size; + uint16_t reserved; +} __packed; + +struct afe_param_hw_mad_ctrl { + uint32_t minor_version; + uint16_t mad_type; + uint16_t mad_enable; +} __packed; + +struct afe_cmd_hw_mad_ctrl { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + struct afe_param_hw_mad_ctrl payload; +} __packed; + +struct afe_cmd_hw_mad_slimbus_slave_port_cfg { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + struct afe_param_slimbus_slave_port_cfg sb_port_cfg; +} __packed; + +struct afe_cmd_sw_mad_enable { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; +} __packed; + +struct afe_param_cdc_reg_cfg_payload { + struct afe_svc_param_data common; + struct afe_param_cdc_reg_cfg reg_cfg; +} __packed; + +struct afe_lpass_clk_config_command_v2 { + struct apr_hdr hdr; + struct afe_svc_cmd_set_param param; + struct afe_svc_param_data pdata; + struct afe_clk_set clk_cfg; +} __packed; + +/* + * reg_data's size can be up to AFE_MAX_CDC_REGISTERS_TO_CONFIG + */ +struct afe_svc_cmd_cdc_reg_cfg { + struct apr_hdr hdr; + struct afe_svc_cmd_set_param param; + struct afe_param_cdc_reg_cfg_payload reg_data[0]; +} __packed; + +struct afe_svc_cmd_init_cdc_reg_cfg { + struct apr_hdr hdr; + struct afe_svc_cmd_set_param param; + struct afe_port_param_data_v2 init; +} __packed; + +struct afe_svc_cmd_sb_slave_cfg { + struct apr_hdr hdr; + struct afe_svc_cmd_set_param param; + struct afe_port_param_data_v2 pdata; + struct afe_param_cdc_slimbus_slave_cfg sb_slave_cfg; +} __packed; + +struct afe_svc_cmd_cdc_reg_page_cfg { + struct apr_hdr hdr; + struct afe_svc_cmd_set_param param; + struct afe_port_param_data_v2 pdata; + struct afe_param_cdc_reg_page_cfg cdc_reg_page_cfg; +} __packed; + +struct afe_svc_cmd_cdc_aanc_version { + struct apr_hdr hdr; + struct afe_svc_cmd_set_param param; + struct afe_port_param_data_v2 pdata; + struct afe_param_id_cdc_aanc_version version; +} __packed; + +struct afe_port_cmd_set_aanc_param { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + union { + struct afe_param_aanc_port_cfg aanc_port_cfg; + struct afe_mod_enable_param mod_enable; + } __packed data; +} __packed; + +struct afe_port_cmd_set_aanc_acdb_table { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; +} __packed; + +/* Dolby DAP topology */ +#define DOLBY_ADM_COPP_TOPOLOGY_ID 0x0001033B +#define DS2_ADM_COPP_TOPOLOGY_ID 0x1301033B + +/* RMS value from DSP */ +#define RMS_MODULEID_APPI_PASSTHRU 0x10009011 +#define RMS_PARAM_FIRST_SAMPLE 0x10009012 +#define RMS_PAYLOAD_LEN 4 + +/* Customized mixing in matix mixer */ +#define MTMX_MODULE_ID_DEFAULT_CHMIXER 0x00010341 +#define DEFAULT_CHMIXER_PARAM_ID_COEFF 0x00010342 +#define CUSTOM_STEREO_PAYLOAD_SIZE 9 +#define CUSTOM_STEREO_CMD_PARAM_SIZE 24 +#define CUSTOM_STEREO_NUM_OUT_CH 0x0002 +#define CUSTOM_STEREO_NUM_IN_CH 0x0002 +#define CUSTOM_STEREO_INDEX_PARAM 0x0002 +#define Q14_GAIN_ZERO_POINT_FIVE 0x2000 +#define Q14_GAIN_UNITY 0x4000 + +struct afe_svc_cmd_set_clip_bank_selection { + struct apr_hdr hdr; + struct afe_svc_cmd_set_param param; + struct afe_port_param_data_v2 pdata; + struct afe_param_id_clip_bank_sel bank_sel; +} __packed; + +/* Ultrasound supported formats */ +#define US_POINT_EPOS_FORMAT_V2 0x0001272D +#define US_RAW_FORMAT_V2 0x0001272C +#define US_PROX_FORMAT_V4 0x0001273B +#define US_RAW_SYNC_FORMAT 0x0001272F +#define US_GES_SYNC_FORMAT 0x00012730 + +#define AFE_MODULE_GROUP_DEVICE 0x00010254 +#define AFE_PARAM_ID_GROUP_DEVICE_CFG 0x00010255 +#define AFE_PARAM_ID_GROUP_DEVICE_ENABLE 0x00010256 +#define AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX 0x1102 + +/* Payload of the #AFE_PARAM_ID_GROUP_DEVICE_CFG + * parameter, which configures max of 8 AFE ports + * into a group. + * The fixed size of this structure is sixteen bytes. + */ +struct afe_group_device_group_cfg { + u32 minor_version; + u16 group_id; + u16 num_channels; + u16 port_id[8]; +} __packed; + +#define AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX \ + (AFE_PORT_ID_PRIMARY_TDM_RX + 0x100) +#define AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX \ + (AFE_PORT_ID_PRIMARY_TDM_TX + 0x100) +#define AFE_GROUP_DEVICE_ID_SECONDARY_TDM_RX \ + (AFE_PORT_ID_SECONDARY_TDM_RX + 0x100) +#define AFE_GROUP_DEVICE_ID_SECONDARY_TDM_TX \ + (AFE_PORT_ID_SECONDARY_TDM_TX + 0x100) +#define AFE_GROUP_DEVICE_ID_TERTIARY_TDM_RX \ + (AFE_PORT_ID_TERTIARY_TDM_RX + 0x100) +#define AFE_GROUP_DEVICE_ID_TERTIARY_TDM_TX \ + (AFE_PORT_ID_TERTIARY_TDM_TX + 0x100) +#define AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_RX \ + (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x100) +#define AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_TX \ + (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x100) + +/* ID of the parameter used by #AFE_MODULE_GROUP_DEVICE to configure the + * group device. #AFE_SVC_CMD_SET_PARAM can use this parameter ID. + * + * Requirements: + * - Configure the group before the member ports in the group are + * configured and started. + * - Enable the group only after it is configured. + * - Stop all member ports in the group before disabling the group. + */ +#define AFE_PARAM_ID_GROUP_DEVICE_TDM_CONFIG 0x0001029E + +/* Version information used to handle future additions to + * AFE_PARAM_ID_GROUP_DEVICE_TDM_CONFIG processing (for backward compatibility). + */ +#define AFE_API_VERSION_GROUP_DEVICE_TDM_CONFIG 0x1 + +/* Number of AFE ports in group device */ +#define AFE_GROUP_DEVICE_NUM_PORTS 8 + +/* Payload of the AFE_PARAM_ID_GROUP_DEVICE_TDM_CONFIG parameter ID + * used by AFE_MODULE_GROUP_DEVICE. + */ +struct afe_param_id_group_device_tdm_cfg { + u32 group_device_cfg_minor_version; + /* Minor version used to track group device configuration. + * @values #AFE_API_VERSION_GROUP_DEVICE_TDM_CONFIG + */ + + u16 group_id; + /* ID for the group device. + * @values + * - #AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX + * - #AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX + * - #AFE_GROUP_DEVICE_ID_SECONDARY_TDM_RX + * - #AFE_GROUP_DEVICE_ID_SECONDARY_TDM_TX + * - #AFE_GROUP_DEVICE_ID_TERTIARY_TDM_RX + * - #AFE_GROUP_DEVICE_ID_TERTIARY_TDM_TX + * - #AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_RX + * - #AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_TX + */ + + u16 reserved; + /* 0 */ + + u16 port_id[AFE_GROUP_DEVICE_NUM_PORTS]; + /* Array of member port IDs of this group. + * @values + * - #AFE_PORT_ID_PRIMARY_TDM_RX + * - #AFE_PORT_ID_PRIMARY_TDM_RX_1 + * - #AFE_PORT_ID_PRIMARY_TDM_RX_2 + * - #AFE_PORT_ID_PRIMARY_TDM_RX_3 + * - #AFE_PORT_ID_PRIMARY_TDM_RX_4 + * - #AFE_PORT_ID_PRIMARY_TDM_RX_5 + * - #AFE_PORT_ID_PRIMARY_TDM_RX_6 + * - #AFE_PORT_ID_PRIMARY_TDM_RX_7 + + * - #AFE_PORT_ID_PRIMARY_TDM_TX + * - #AFE_PORT_ID_PRIMARY_TDM_TX_1 + * - #AFE_PORT_ID_PRIMARY_TDM_TX_2 + * - #AFE_PORT_ID_PRIMARY_TDM_TX_3 + * - #AFE_PORT_ID_PRIMARY_TDM_TX_4 + * - #AFE_PORT_ID_PRIMARY_TDM_TX_5 + * - #AFE_PORT_ID_PRIMARY_TDM_TX_6 + * - #AFE_PORT_ID_PRIMARY_TDM_TX_7 + + * - #AFE_PORT_ID_SECONDARY_TDM_RX + * - #AFE_PORT_ID_SECONDARY_TDM_RX_1 + * - #AFE_PORT_ID_SECONDARY_TDM_RX_2 + * - #AFE_PORT_ID_SECONDARY_TDM_RX_3 + * - #AFE_PORT_ID_SECONDARY_TDM_RX_4 + * - #AFE_PORT_ID_SECONDARY_TDM_RX_5 + * - #AFE_PORT_ID_SECONDARY_TDM_RX_6 + * - #AFE_PORT_ID_SECONDARY_TDM_RX_7 + + * - #AFE_PORT_ID_SECONDARY_TDM_TX + * - #AFE_PORT_ID_SECONDARY_TDM_TX_1 + * - #AFE_PORT_ID_SECONDARY_TDM_TX_2 + * - #AFE_PORT_ID_SECONDARY_TDM_TX_3 + * - #AFE_PORT_ID_SECONDARY_TDM_TX_4 + * - #AFE_PORT_ID_SECONDARY_TDM_TX_5 + * - #AFE_PORT_ID_SECONDARY_TDM_TX_6 + * - #AFE_PORT_ID_SECONDARY_TDM_TX_7 + + * - #AFE_PORT_ID_TERTIARY_TDM_RX + * - #AFE_PORT_ID_TERTIARY_TDM_RX_1 + * - #AFE_PORT_ID_TERTIARY_TDM_RX_2 + * - #AFE_PORT_ID_TERTIARY_TDM_RX_3 + * - #AFE_PORT_ID_TERTIARY_TDM_RX_4 + * - #AFE_PORT_ID_TERTIARY_TDM_RX_5 + * - #AFE_PORT_ID_TERTIARY_TDM_RX_6 + * - #AFE_PORT_ID_TERTIARY_TDM_RX_7 + + * - #AFE_PORT_ID_TERTIARY_TDM_TX + * - #AFE_PORT_ID_TERTIARY_TDM_TX_1 + * - #AFE_PORT_ID_TERTIARY_TDM_TX_2 + * - #AFE_PORT_ID_TERTIARY_TDM_TX_3 + * - #AFE_PORT_ID_TERTIARY_TDM_TX_4 + * - #AFE_PORT_ID_TERTIARY_TDM_TX_5 + * - #AFE_PORT_ID_TERTIARY_TDM_TX_6 + * - #AFE_PORT_ID_TERTIARY_TDM_TX_7 + + * - #AFE_PORT_ID_QUATERNARY_TDM_RX + * - #AFE_PORT_ID_QUATERNARY_TDM_RX_1 + * - #AFE_PORT_ID_QUATERNARY_TDM_RX_2 + * - #AFE_PORT_ID_QUATERNARY_TDM_RX_3 + * - #AFE_PORT_ID_QUATERNARY_TDM_RX_4 + * - #AFE_PORT_ID_QUATERNARY_TDM_RX_5 + * - #AFE_PORT_ID_QUATERNARY_TDM_RX_6 + * - #AFE_PORT_ID_QUATERNARY_TDM_RX_7 + + * - #AFE_PORT_ID_QUATERNARY_TDM_TX + * - #AFE_PORT_ID_QUATERNARY_TDM_TX_1 + * - #AFE_PORT_ID_QUATERNARY_TDM_TX_2 + * - #AFE_PORT_ID_QUATERNARY_TDM_TX_3 + * - #AFE_PORT_ID_QUATERNARY_TDM_TX_4 + * - #AFE_PORT_ID_QUATERNARY_TDM_TX_5 + * - #AFE_PORT_ID_QUATERNARY_TDM_TX_6 + * - #AFE_PORT_ID_QUATERNARY_TDM_TX_7 + * @tablebulletend + */ + + u32 num_channels; + /* Number of enabled slots for TDM frame. + * @values 1 to 8 + */ + + u32 sample_rate; + /* Sampling rate of the port. + * @values + * - #AFE_PORT_SAMPLE_RATE_8K + * - #AFE_PORT_SAMPLE_RATE_16K + * - #AFE_PORT_SAMPLE_RATE_24K + * - #AFE_PORT_SAMPLE_RATE_32K + * - #AFE_PORT_SAMPLE_RATE_48K @tablebulletend + */ + + u32 bit_width; + /* Bit width of the sample. + * @values 16, 24, (32) + */ + + u16 nslots_per_frame; + /* Number of slots per frame. Typical : 1, 2, 4, 8, 16, 32. + * @values 1 - 32 + */ + + u16 slot_width; + /* Slot width of the slot in a TDM frame. (slot_width >= bit_width) + * have to be satisfied. + * @values 16, 24, 32 + */ + + u32 slot_mask; + /* Position of active slots. When that bit is set, that paricular + * slot is active. + * Number of active slots can be inferred by number of bits set in + * the mask. Only 8 individual bits can be enabled. + * Bits 0..31 corresponding to slot 0..31 + * @values 1 to 2^32 -1 + */ +} __packed; + +/* Payload of the #AFE_PARAM_ID_GROUP_DEVICE_ENABLE + * parameter, which enables or + * disables any module. + * The fixed size of this structure is four bytes. + */ + +struct afe_group_device_enable { + u16 group_id; + /* valid value is AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX */ + u16 enable; + /* Enables (1) or disables (0) the module. */ +} __packed; + +union afe_port_group_config { + struct afe_group_device_group_cfg group_cfg; + struct afe_group_device_enable group_enable; + struct afe_param_id_group_device_tdm_cfg tdm_cfg; +} __packed; + +struct afe_port_group_create { + struct apr_hdr hdr; + struct afe_svc_cmd_set_param param; + struct afe_port_param_data_v2 pdata; + union afe_port_group_config data; +} __packed; + +/* ID of the parameter used by #AFE_MODULE_AUDIO_DEV_INTERFACE to specify + * the timing statistics of the corresponding device interface. + * Client can periodically query for the device time statistics to help adjust + * the PLL based on the drift value. The get param command must be sent to + * AFE port ID corresponding to device interface + + * This parameter ID supports following get param commands: + * #AFE_PORT_CMD_GET_PARAM_V2 and + * #AFE_PORT_CMD_GET_PARAM_V3. + */ +#define AFE_PARAM_ID_DEV_TIMING_STATS 0x000102AD + +/* Version information used to handle future additions to AFE device + * interface timing statistics (for backward compatibility). + */ +#define AFE_API_VERSION_DEV_TIMING_STATS 0x1 + +/* Enumeration for specifying a sink(Rx) device */ +#define AFE_SINK_DEVICE 0x0 + +/* Enumeration for specifying a source(Tx) device */ +#define AFE_SOURCE_DEVICE 0x1 + +/* Enumeration for specifying the drift reference is of type AV Timer */ +#define AFE_REF_TIMER_TYPE_AVTIMER 0x0 + +/* Message payload structure for the + * AFE_PARAM_ID_DEV_TIMING_STATS parameter. + */ +struct afe_param_id_dev_timing_stats { + /* Minor version used to track the version of device interface timing + * statistics. Currently, the supported version is 1. + * @values #AFE_API_VERSION_DEV_TIMING_STATS + */ + u32 minor_version; + + /* Indicates the device interface direction as either + * source (Tx) or sink (Rx). + * @values + * #AFE_SINK_DEVICE + * #AFE_SOURCE_DEVICE + */ + u16 device_direction; + + /* Reference timer for drift accumulation and time stamp information. + * @values + * #AFE_REF_TIMER_TYPE_AVTIMER @tablebulletend + */ + u16 reference_timer; + + /* + * Flag to indicate if resync is required on the client side for + * drift correction. Flag is set to TRUE for the first get_param + * response after device interface starts. This flag value can be + * used by client to identify if device interface restart has + * happened and if any re-sync is required at their end for drift + * correction. + * @values + * 0: FALSE (Resync not required) + * 1: TRUE (Resync required) @tablebulletend + */ + u32 resync_flag; + + /* Accumulated drift value in microseconds. This value is updated + * every 100th ms. + * Positive drift value indicates AV timer is running faster than device + * Negative drift value indicates AV timer is running slower than device + * @values Any valid int32 number + */ + s32 acc_drift_value; + + /* Lower 32 bits of the 64-bit absolute timestamp of reference + * timer in microseconds. + + * This timestamp corresponds to the time when the drift values + * are accumlated for every 100th ms. + * @values Any valid uint32 number + */ + u32 ref_timer_abs_ts_lsw; + + /* Upper 32 bits of the 64-bit absolute timestamp of reference + * timer in microseconds. + * This timestamp corresponds to the time when the drift values + * are accumlated for every 100th ms. + * @values Any valid uint32 number + */ + u32 ref_timer_abs_ts_msw; +} __packed; + +struct afe_av_dev_drift_get_param { + struct apr_hdr hdr; + struct afe_port_cmd_get_param_v2 get_param; + struct afe_port_param_data_v2 pdata; + struct afe_param_id_dev_timing_stats timing_stats; +} __packed; + +struct afe_av_dev_drift_get_param_resp { + uint32_t status; + struct afe_port_param_data_v2 pdata; + struct afe_param_id_dev_timing_stats timing_stats; +} __packed; + +/* Command for Matrix or Stream Router */ +#define ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2 0x00010DCE +/* Module for AVSYNC */ +#define ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC 0x00010DC6 + +/* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC to specify the + * render window start value. This parameter is supported only for a Set + * command (not a Get command) in the Rx direction + * (#ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2). + * Render window start is a value (session time minus timestamp, or ST-TS) + * below which frames are held, and after which frames are immediately + * rendered. + */ +#define ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_START_V2 0x00010DD1 + +/* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC to specify the + * render window end value. This parameter is supported only for a Set + * command (not a Get command) in the Rx direction + * (#ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2). Render window end is a value + * (session time minus timestamp) above which frames are dropped, and below + * which frames are immediately rendered. + */ +#define ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_END_V2 0x00010DD2 + +/* Generic payload of the window parameters in the + * #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC module. + * This payload is supported only for a Set command + * (not a Get command) on the Rx path. + */ +struct asm_session_mtmx_strtr_param_window_v2_t { + u32 window_lsw; + /* Lower 32 bits of the render window start value. */ + + u32 window_msw; + /* Upper 32 bits of the render window start value. + * + * The 64-bit number formed by window_lsw and window_msw specifies a + * signed 64-bit window value in microseconds. The sign extension is + * necessary. This value is used by the following parameter IDs: + * #ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_START_V2 + * #ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_END_V2 + * #ASM_SESSION_MTMX_STRTR_PARAM_STAT_WINDOW_START_V2 + * #ASM_SESSION_MTMX_STRTR_PARAM_STAT_WINDOW_END_V2 + * The value depends on which parameter ID is used. + * The aDSP honors the windows at a granularity of 1 ms. + */ +}; + +struct asm_session_cmd_set_mtmx_strstr_params_v2 { + uint32_t data_payload_addr_lsw; + /* Lower 32 bits of the 64-bit data payload address. */ + + uint32_t data_payload_addr_msw; + /* Upper 32 bits of the 64-bit data payload address. + * If the address is not sent (NULL), the message is in the payload. + * If the address is sent (non-NULL), the parameter data payloads + * begin at the specified address. + */ + + uint32_t mem_map_handle; + /* Unique identifier for an address. This memory map handle is returned + * by the aDSP through the #ASM_CMD_SHARED_MEM_MAP_REGIONS command. + * values + * - NULL -- Parameter data payloads are within the message payload + * (in-band). + * - Non-NULL -- Parameter data payloads begin at the address specified + * in the data_payload_addr_lsw and data_payload_addr_msw fields + * (out-of-band). + */ + + uint32_t data_payload_size; + /* Actual size of the variable payload accompanying the message, or in + * shared memory. This field is used for parsing the parameter payload. + * values > 0 bytes + */ + + uint32_t direction; + /* Direction of the entity (matrix mixer or stream router) on which + * the parameter is to be set. + * values + * - 0 -- Rx (for Rx stream router or Rx matrix mixer) + * - 1 -- Tx (for Tx stream router or Tx matrix mixer) + */ +}; + +/* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC which allows the + * audio client choose the rendering decision that the audio DSP should use. + */ +#define ASM_SESSION_MTMX_STRTR_PARAM_RENDER_MODE_CMD 0x00012F0D + +/* Indicates that rendering decision will be based on default rate + * (session clock based rendering, device driven). + * 1. The default session clock based rendering is inherently driven + * by the timing of the device. + * 2. After the initial decision is made (first buffer after a run + * command), subsequent data rendering decisions are made with + * respect to the rate at which the device is rendering, thus deriving + * its timing from the device. + * 3. While this decision making is simple, it has some inherent limitations + * (mentioned in the next section). + * 4. If this API is not set, the session clock based rendering will be assumed + * and this will ensure that the DSP is backward compatible. + */ +#define ASM_SESSION_MTMX_STRTR_PARAM_RENDER_DEFAULT 0 + +/* Indicates that rendering decision will be based on local clock rate. + * 1. In the DSP loopback/client loopback use cases (frame based + * inputs), the incoming data into audio DSP is time-stamped at the + * local clock rate (STC). + * 2. This TS rate may match the incoming data rate or maybe different + * from the incoming data rate. + * 3. Regardless, the data will be time-stamped with local STC and + * therefore, the client is recommended to set this mode for these + * use cases. This method is inherently more robust to sequencing + * (AFE Start/Stop) and device switches, among other benefits. + * 4. This API will inform the DSP to compare every incoming buffer TS + * against local STC. + * 5. DSP will continue to honor render windows APIs, as before. + */ +#define ASM_SESSION_MTMX_STRTR_PARAM_RENDER_LOCAL_STC 1 + +/* Structure for rendering decision parameter */ +struct asm_session_mtmx_strtr_param_render_mode_t { + /* Specifies the type of rendering decision the audio DSP should use. + * + * @values + * - #ASM_SESSION_MTMX_STRTR_PARAM_RENDER_DEFAULT + * - #ASM_SESSION_MTMX_STRTR_PARAM_RENDER_LOCAL_STC + */ + u32 flags; +} __packed; + +/* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC which allows the + * audio client to specify the clock recovery mechanism that the audio DSP + * should use. + */ + +#define ASM_SESSION_MTMX_STRTR_PARAM_CLK_REC_CMD 0x00012F0E + +/* Indicates that default clock recovery will be used (no clock recovery). + * If the client wishes that no clock recovery be done, the client can + * choose this. This means that no attempt will made by the DSP to try and + * match the rates of the input and output audio. + */ +#define ASM_SESSION_MTMX_STRTR_PARAM_CLK_REC_NONE 0 + +/* Indicates that independent clock recovery needs to be used. + * 1. In the DSP loopback/client loopback use cases (frame based inputs), + * the client should choose the independent clock recovery option. + * 2. This basically de-couples the audio and video from knowing each others + * clock sources and lets the audio DSP independently rate match the input + * and output rates. + * 3. After drift detection, the drift correction is achieved by either pulling + * the PLLs (if applicable) or by stream to device rate matching + * (for PCM use cases) by comparing drift with respect to STC. + * 4. For passthrough use cases, since the PLL pulling is the only option, + * a best effort will be made. + * If PLL pulling is not possible / available, the rendering will be + * done without rate matching. + */ +#define ASM_SESSION_MTMX_STRTR_PARAM_CLK_REC_AUTO 1 + +/* Payload of the #ASM_SESSION_MTMX_STRTR_PARAM_CLK_REC parameter. + */ +struct asm_session_mtmx_strtr_param_clk_rec_t { + /* Specifies the type of clock recovery that the audio DSP should + * use for rate matching. + */ + + /* @values + * #ASM_SESSION_MTMX_STRTR_PARAM_CLK_REC_DEFAULT + * #ASM_SESSION_MTMX_STRTR_PARAM_CLK_REC_INDEPENDENT + */ + u32 flags; +} __packed; + + +/* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC to + * realize smoother adjustment of audio session clock for a specified session. + * The desired audio session clock adjustment(in micro seconds) is specified + * using the command #ASM_SESSION_CMD_ADJUST_SESSION_CLOCK_V2. + * Delaying/Advancing the session clock would be implemented by inserting + * interpolated/dropping audio samples in the playback path respectively. + * Also, this parameter has to be configured before the Audio Session is put + * to RUN state to avoid cold start latency/glitches in the playback. + */ + +#define ASM_SESSION_MTMX_PARAM_ADJUST_SESSION_TIME_CTL 0x00013217 + +struct asm_session_mtmx_param_adjust_session_time_ctl_t { + /* Specifies whether the module is enabled or not + * @values + * 0 -- disabled + * 1 -- enabled + */ + u32 enable; +}; + +union asm_session_mtmx_strtr_param_config { + struct asm_session_mtmx_strtr_param_window_v2_t window_param; + struct asm_session_mtmx_strtr_param_render_mode_t render_param; + struct asm_session_mtmx_strtr_param_clk_rec_t clk_rec_param; + struct asm_session_mtmx_param_adjust_session_time_ctl_t adj_time_param; +} __packed; + +struct asm_mtmx_strtr_params { + struct apr_hdr hdr; + struct asm_session_cmd_set_mtmx_strstr_params_v2 param; + struct asm_stream_param_data_v2 data; + union asm_session_mtmx_strtr_param_config config; +} __packed; + +#define ASM_SESSION_CMD_GET_MTMX_STRTR_PARAMS_V2 0x00010DCF +#define ASM_SESSION_CMDRSP_GET_MTMX_STRTR_PARAMS_V2 0x00010DD0 + +#define ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3 0x00012F0B +#define ASM_SESSION_MTMX_STRTR_PARAM_STIME_TSTMP_FLG_BMASK (0x80000000UL) + +struct asm_session_cmd_get_mtmx_strstr_params_v2 { + uint32_t data_payload_addr_lsw; + /* Lower 32 bits of the 64-bit data payload address. */ + + uint32_t data_payload_addr_msw; + /* + * Upper 32 bits of the 64-bit data payload address. + * If the address is not sent (NULL), the message is in the payload. + * If the address is sent (non-NULL), the parameter data payloads + * begin at the specified address. + */ + + uint32_t mem_map_handle; + /* + * Unique identifier for an address. This memory map handle is returned + * by the aDSP through the #ASM_CMD_SHARED_MEM_MAP_REGIONS command. + * values + * - NULL -- Parameter data payloads are within the message payload + * (in-band). + * - Non-NULL -- Parameter data payloads begin at the address specified + * in the data_payload_addr_lsw and data_payload_addr_msw fields + * (out-of-band). + */ + uint32_t direction; + /* + * Direction of the entity (matrix mixer or stream router) on which + * the parameter is to be set. + * values + * - 0 -- Rx (for Rx stream router or Rx matrix mixer) + * - 1 -- Tx (for Tx stream router or Tx matrix mixer) + */ + uint32_t module_id; + /* Unique module ID. */ + + uint32_t param_id; + /* Unique parameter ID. */ + + uint32_t param_max_size; +}; + +struct asm_session_mtmx_strtr_param_session_time_v3_t { + uint32_t session_time_lsw; + /* Lower 32 bits of the current session time in microseconds */ + + uint32_t session_time_msw; + /* + * Upper 32 bits of the current session time in microseconds. + * The 64-bit number formed by session_time_lsw and session_time_msw + * is treated as signed. + */ + + uint32_t absolute_time_lsw; + /* + * Lower 32 bits of the 64-bit absolute time in microseconds. + * This is the time when the sample corresponding to the + * session_time_lsw is rendered to the hardware. This absolute + * time can be slightly in the future or past. + */ + + uint32_t absolute_time_msw; + /* + * Upper 32 bits of the 64-bit absolute time in microseconds. + * This is the time when the sample corresponding to the + * session_time_msw is rendered to hardware. This absolute + * time can be slightly in the future or past. The 64-bit number + * formed by absolute_time_lsw and absolute_time_msw is treated as + * unsigned. + */ + + uint32_t time_stamp_lsw; + /* Lower 32 bits of the last processed timestamp in microseconds */ + + uint32_t time_stamp_msw; + /* + * Upper 32 bits of the last processed timestamp in microseconds. + * The 64-bit number formed by time_stamp_lsw and time_stamp_lsw + * is treated as unsigned. + */ + + uint32_t flags; + /* + * Keeps track of any additional flags needed. + * @values{for bit 31} + * - 0 -- Uninitialized/invalid + * - 1 -- Valid + * All other bits are reserved; clients must set them to zero. + */ +}; + +union asm_session_mtmx_strtr_data_type { + struct asm_session_mtmx_strtr_param_session_time_v3_t session_time; +}; + +struct asm_mtmx_strtr_get_params { + struct apr_hdr hdr; + struct asm_session_cmd_get_mtmx_strstr_params_v2 param_info; +} __packed; + +struct asm_mtmx_strtr_get_params_cmdrsp { + uint32_t err_code; + struct asm_stream_param_data_v2 param_info; + union asm_session_mtmx_strtr_data_type param_data; +} __packed; + +#define AUDPROC_MODULE_ID_RESAMPLER 0x00010719 + +enum { + LEGACY_PCM = 0, + COMPRESSED_PASSTHROUGH, + COMPRESSED_PASSTHROUGH_CONVERT, + COMPRESSED_PASSTHROUGH_DSD, + LISTEN, + COMPRESSED_PASSTHROUGH_GEN, + COMPRESSED_PASSTHROUGH_IEC61937 +}; + +#define AUDPROC_MODULE_ID_COMPRESSED_MUTE 0x00010770 +#define AUDPROC_PARAM_ID_COMPRESSED_MUTE 0x00010771 + +struct adm_set_compressed_device_mute { + struct adm_cmd_set_pp_params_v5 command; + struct adm_param_data_v5 params; + u32 mute_on; +} __packed; + +#define AUDPROC_MODULE_ID_COMPRESSED_LATENCY 0x0001076E +#define AUDPROC_PARAM_ID_COMPRESSED_LATENCY 0x0001076F + +struct adm_set_compressed_device_latency { + struct adm_cmd_set_pp_params_v5 command; + struct adm_param_data_v5 params; + u32 latency; +} __packed; + +#define VOICEPROC_MODULE_ID_GENERIC_TX 0x00010EF6 +#define VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS 0x00010E37 +#define VOICEPROC_PARAM_ID_FLUENCE_SOURCETRACKING 0x00010E38 +#define MAX_SECTORS 8 +#define MAX_NOISE_SOURCE_INDICATORS 3 +#define MAX_POLAR_ACTIVITY_INDICATORS 360 + +struct sound_focus_param { + uint16_t start_angle[MAX_SECTORS]; + uint8_t enable[MAX_SECTORS]; + uint16_t gain_step; +} __packed; + +struct source_tracking_param { + uint8_t vad[MAX_SECTORS]; + uint16_t doa_speech; + uint16_t doa_noise[MAX_NOISE_SOURCE_INDICATORS]; + uint8_t polar_activity[MAX_POLAR_ACTIVITY_INDICATORS]; +} __packed; + +struct adm_param_fluence_soundfocus_t { + uint16_t start_angles[MAX_SECTORS]; + uint8_t enables[MAX_SECTORS]; + uint16_t gain_step; + uint16_t reserved; +} __packed; + +struct adm_set_fluence_soundfocus_param { + struct adm_cmd_set_pp_params_v5 params; + struct adm_param_data_v5 data; + struct adm_param_fluence_soundfocus_t soundfocus_data; +} __packed; + +struct adm_param_fluence_sourcetracking_t { + uint8_t vad[MAX_SECTORS]; + uint16_t doa_speech; + uint16_t doa_noise[MAX_NOISE_SOURCE_INDICATORS]; + uint8_t polar_activity[MAX_POLAR_ACTIVITY_INDICATORS]; +} __packed; + +#define AUDPROC_MODULE_ID_AUDIOSPHERE 0x00010916 +#define AUDPROC_PARAM_ID_AUDIOSPHERE_ENABLE 0x00010917 +#define AUDPROC_PARAM_ID_AUDIOSPHERE_STRENGTH 0x00010918 +#define AUDPROC_PARAM_ID_AUDIOSPHERE_CONFIG_MODE 0x00010919 + +#define AUDPROC_PARAM_ID_AUDIOSPHERE_COEFFS_STEREO_INPUT 0x0001091A +#define AUDPROC_PARAM_ID_AUDIOSPHERE_COEFFS_MULTICHANNEL_INPUT 0x0001091B +#define AUDPROC_PARAM_ID_AUDIOSPHERE_DESIGN_STEREO_INPUT 0x0001091C +#define AUDPROC_PARAM_ID_AUDIOSPHERE_DESIGN_MULTICHANNEL_INPUT 0x0001091D + +#define AUDPROC_PARAM_ID_AUDIOSPHERE_OPERATING_INPUT_MEDIA_INFO 0x0001091E + +#define AUDPROC_MODULE_ID_VOICE_TX_SECNS 0x10027059 +#define AUDPROC_PARAM_IDX_SEC_PRIMARY_MIC_CH 0x10014444 + +struct admx_sec_primary_mic_ch { + uint16_t version; + uint16_t reserved; + uint16_t sec_primary_mic_ch; + uint16_t reserved1; +} __packed; + + +struct adm_set_sec_primary_ch_params { + struct adm_cmd_set_pp_params_v5 params; + struct adm_param_data_v5 data; + struct admx_sec_primary_mic_ch sec_primary_mic_ch_data; +} __packed; +#endif /*_APR_AUDIO_V2_H_ */ diff --git a/include/sound/apr_audio.h b/include/sound/apr_audio.h new file mode 100644 index 000000000000..eb35645c759f --- /dev/null +++ b/include/sound/apr_audio.h @@ -0,0 +1,1931 @@ +/* + * + * Copyright (c) 2010-2013, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _APR_AUDIO_H_ +#define _APR_AUDIO_H_ + +/* ASM opcodes without APR payloads*/ +#include + +/* + * Audio Front End (AFE) + */ + +/* Port ID. Update afe_get_port_index when a new port is added here. */ +#define PRIMARY_I2S_RX 0 /* index = 0 */ +#define PRIMARY_I2S_TX 1 /* index = 1 */ +#define PCM_RX 2 /* index = 2 */ +#define PCM_TX 3 /* index = 3 */ +#define SECONDARY_I2S_RX 4 /* index = 4 */ +#define SECONDARY_I2S_TX 5 /* index = 5 */ +#define MI2S_RX 6 /* index = 6 */ +#define MI2S_TX 7 /* index = 7 */ +#define HDMI_RX 8 /* index = 8 */ +#define RSVD_2 9 /* index = 9 */ +#define RSVD_3 10 /* index = 10 */ +#define DIGI_MIC_TX 11 /* index = 11 */ +#define VOICE_RECORD_RX 0x8003 /* index = 12 */ +#define VOICE_RECORD_TX 0x8004 /* index = 13 */ +#define VOICE_PLAYBACK_TX 0x8005 /* index = 14 */ + +/* Slimbus Multi channel port id pool */ +#define SLIMBUS_0_RX 0x4000 /* index = 15 */ +#define SLIMBUS_0_TX 0x4001 /* index = 16 */ +#define SLIMBUS_1_RX 0x4002 /* index = 17 */ +#define SLIMBUS_1_TX 0x4003 /* index = 18 */ +#define SLIMBUS_2_RX 0x4004 +#define SLIMBUS_2_TX 0x4005 +#define SLIMBUS_3_RX 0x4006 +#define SLIMBUS_3_TX 0x4007 +#define SLIMBUS_4_RX 0x4008 +#define SLIMBUS_4_TX 0x4009 /* index = 24 */ + +#define INT_BT_SCO_RX 0x3000 /* index = 25 */ +#define INT_BT_SCO_TX 0x3001 /* index = 26 */ +#define INT_BT_A2DP_RX 0x3002 /* index = 27 */ +#define INT_FM_RX 0x3004 /* index = 28 */ +#define INT_FM_TX 0x3005 /* index = 29 */ +#define RT_PROXY_PORT_001_RX 0x2000 /* index = 30 */ +#define RT_PROXY_PORT_001_TX 0x2001 /* index = 31 */ +#define SECONDARY_PCM_RX 12 /* index = 32 */ +#define SECONDARY_PCM_TX 13 /* index = 33 */ +#define PSEUDOPORT_01 0x8001 /* index =34 */ + +#define AFE_PORT_INVALID 0xFFFF +#define SLIMBUS_EXTPROC_RX AFE_PORT_INVALID + +#define AFE_PORT_CMD_START 0x000100ca + +#define AFE_EVENT_RTPORT_START 0 +#define AFE_EVENT_RTPORT_STOP 1 +#define AFE_EVENT_RTPORT_LOW_WM 2 +#define AFE_EVENT_RTPORT_HI_WM 3 + +struct afe_port_start_command { + struct apr_hdr hdr; + u16 port_id; + u16 gain; /* Q13 */ + u32 sample_rate; /* 8 , 16, 48khz */ +} __packed; + +#define AFE_PORT_CMD_STOP 0x000100cb +struct afe_port_stop_command { + struct apr_hdr hdr; + u16 port_id; + u16 reserved; +} __packed; + +#define AFE_PORT_CMD_APPLY_GAIN 0x000100cc +struct afe_port_gain_command { + struct apr_hdr hdr; + u16 port_id; + u16 gain;/* Q13 */ +} __packed; + +#define AFE_PORT_CMD_SIDETONE_CTL 0x000100cd +struct afe_port_sidetone_command { + struct apr_hdr hdr; + u16 rx_port_id; /* Primary i2s tx = 1 */ + /* PCM tx = 3 */ + /* Secondary i2s tx = 5 */ + /* Mi2s tx = 7 */ + /* Digital mic tx = 11 */ + u16 tx_port_id; /* Primary i2s rx = 0 */ + /* PCM rx = 2 */ + /* Secondary i2s rx = 4 */ + /* Mi2S rx = 6 */ + /* HDMI rx = 8 */ + u16 gain; /* Q13 */ + u16 enable; /* 1 = enable, 0 = disable */ +} __packed; + +#define AFE_PORT_CMD_LOOPBACK 0x000100ce +struct afe_loopback_command { + struct apr_hdr hdr; + u16 tx_port_id; /* Primary i2s rx = 0 */ + /* PCM rx = 2 */ + /* Secondary i2s rx = 4 */ + /* Mi2S rx = 6 */ + /* HDMI rx = 8 */ + u16 rx_port_id; /* Primary i2s tx = 1 */ + /* PCM tx = 3 */ + /* Secondary i2s tx = 5 */ + /* Mi2s tx = 7 */ + /* Digital mic tx = 11 */ + u16 mode; /* Default -1, DSP will conver + * the tx to rx format + */ + u16 enable; /* 1 = enable, 0 = disable */ +} __packed; + +#define AFE_PSEUDOPORT_CMD_START 0x000100cf +struct afe_pseudoport_start_command { + struct apr_hdr hdr; + u16 port_id; /* Pseudo Port 1 = 0x8000 */ + /* Pseudo Port 2 = 0x8001 */ + /* Pseudo Port 3 = 0x8002 */ + u16 timing; /* FTRT = 0 , AVTimer = 1, */ +} __packed; + +#define AFE_PSEUDOPORT_CMD_STOP 0x000100d0 +struct afe_pseudoport_stop_command { + struct apr_hdr hdr; + u16 port_id; /* Pseudo Port 1 = 0x8000 */ + /* Pseudo Port 2 = 0x8001 */ + /* Pseudo Port 3 = 0x8002 */ + u16 reserved; +} __packed; + +#define AFE_CMD_GET_ACTIVE_PORTS 0x000100d1 + + +#define AFE_CMD_GET_ACTIVE_HANDLES_FOR_PORT 0x000100d2 +struct afe_get_active_handles_command { + struct apr_hdr hdr; + u16 port_id; + u16 reserved; +} __packed; + +/* + * Opcode for AFE to start DTMF. + */ +#define AFE_PORTS_CMD_DTMF_CTL 0x00010102 + +/** DTMF payload.*/ +struct afe_dtmf_generation_command { + struct apr_hdr hdr; + + /* + * Duration of the DTMF tone in ms. + * -1 -> continuous, + * 0 -> disable + */ + int64_t duration_in_ms; + + /* + * The DTMF high tone frequency. + */ + uint16_t high_freq; + + /* + * The DTMF low tone frequency. + */ + uint16_t low_freq; + + /* + * The DTMF volume setting + */ + uint16_t gain; + + /* + * The number of ports to enable/disable on. + */ + uint16_t num_ports; + + /* + * The Destination ports - array . + * For DTMF on multiple ports, portIds needs to + * be populated numPorts times. + */ + uint16_t port_ids; + + /* + * variable for 32 bit alignment of APR packet. + */ + uint16_t reserved; +} __packed; + +#define AFE_PCM_CFG_MODE_PCM 0x0 +#define AFE_PCM_CFG_MODE_AUX 0x1 +#define AFE_PCM_CFG_SYNC_EXT 0x0 +#define AFE_PCM_CFG_SYNC_INT 0x1 +#define AFE_PCM_CFG_FRM_8BPF 0x0 +#define AFE_PCM_CFG_FRM_16BPF 0x1 +#define AFE_PCM_CFG_FRM_32BPF 0x2 +#define AFE_PCM_CFG_FRM_64BPF 0x3 +#define AFE_PCM_CFG_FRM_128BPF 0x4 +#define AFE_PCM_CFG_FRM_256BPF 0x5 +#define AFE_PCM_CFG_QUANT_ALAW_NOPAD 0x0 +#define AFE_PCM_CFG_QUANT_MULAW_NOPAD 0x1 +#define AFE_PCM_CFG_QUANT_LINEAR_NOPAD 0x2 +#define AFE_PCM_CFG_QUANT_ALAW_PAD 0x3 +#define AFE_PCM_CFG_QUANT_MULAW_PAD 0x4 +#define AFE_PCM_CFG_QUANT_LINEAR_PAD 0x5 +#define AFE_PCM_CFG_CDATAOE_MASTER 0x0 +#define AFE_PCM_CFG_CDATAOE_SHARE 0x1 + +struct afe_port_pcm_cfg { + u16 mode; /* PCM (short sync) = 0, AUXPCM (long sync) = 1 */ + u16 sync; /* external = 0 , internal = 1 */ + u16 frame; /* 8 bpf = 0 */ + /* 16 bpf = 1 */ + /* 32 bpf = 2 */ + /* 64 bpf = 3 */ + /* 128 bpf = 4 */ + /* 256 bpf = 5 */ + u16 quant; + u16 slot; /* Slot for PCM stream , 0 - 31 */ + u16 data; /* 0, PCM block is the only master */ + /* 1, PCM block is shares to driver data out signal */ + /* other master */ + u16 reserved; +} __packed; + +enum { + AFE_I2S_SD0 = 1, + AFE_I2S_SD1, + AFE_I2S_SD2, + AFE_I2S_SD3, + AFE_I2S_QUAD01, + AFE_I2S_QUAD23, + AFE_I2S_6CHS, + AFE_I2S_8CHS, +}; + +#define AFE_MI2S_MONO 0 +#define AFE_MI2S_STEREO 3 +#define AFE_MI2S_4CHANNELS 4 +#define AFE_MI2S_6CHANNELS 6 +#define AFE_MI2S_8CHANNELS 8 + +struct afe_port_mi2s_cfg { + u16 bitwidth; /* 16,24,32 */ + u16 line; /* Called ChannelMode in documentation */ + /* i2s_sd0 = 1 */ + /* i2s_sd1 = 2 */ + /* i2s_sd2 = 3 */ + /* i2s_sd3 = 4 */ + /* i2s_quad01 = 5 */ + /* i2s_quad23 = 6 */ + /* i2s_6chs = 7 */ + /* i2s_8chs = 8 */ + u16 channel; /* Called MonoStereo in documentation */ + /* i2s mono = 0 */ + /* i2s mono right = 1 */ + /* i2s mono left = 2 */ + /* i2s stereo = 3 */ + u16 ws; /* 0, word select signal from external source */ + /* 1, word select signal from internal source */ + u16 format; /* don't touch this field if it is not for */ + /* AFE_PORT_CMD_I2S_CONFIG opcode */ +} __packed; + +struct afe_port_hdmi_cfg { + u16 bitwidth; /* 16,24,32 */ + u16 channel_mode; /* HDMI Stereo = 0 */ + /* HDMI_3Point1 (4-ch) = 1 */ + /* HDMI_5Point1 (6-ch) = 2 */ + /* HDMI_6Point1 (8-ch) = 3 */ + u16 data_type; /* HDMI_Linear = 0 */ + /* HDMI_non_Linear = 1 */ +} __packed; + + +struct afe_port_hdmi_multi_ch_cfg { + u16 data_type; /* HDMI_Linear = 0 */ + /* HDMI_non_Linear = 1 */ + u16 channel_allocation; /* The default is 0 (Stereo) */ + u16 reserved; /* must be set to 0 */ +} __packed; + + +/* Slimbus Device Ids */ +#define AFE_SLIMBUS_DEVICE_1 0x0 +#define AFE_SLIMBUS_DEVICE_2 0x1 +#define AFE_PORT_MAX_AUDIO_CHAN_CNT 16 + +struct afe_port_slimbus_cfg { + u16 slimbus_dev_id; /* SLIMBUS Device id.*/ + + u16 slave_dev_pgd_la; /* Slave ported generic device + * logical address. + */ + u16 slave_dev_intfdev_la; /* Slave interface device logical + * address. + */ + u16 bit_width; /* bit width of the samples, 16, 24.*/ + + u16 data_format; /* data format.*/ + + u16 num_channels; /* Number of channels.*/ + + /* Slave port mapping for respective channels.*/ + u16 slave_port_mapping[AFE_PORT_MAX_AUDIO_CHAN_CNT]; + + u16 reserved; +} __packed; + +struct afe_port_slimbus_sch_cfg { + u16 slimbus_dev_id; /* SLIMBUS Device id.*/ + u16 bit_width; /* bit width of the samples, 16, 24.*/ + u16 data_format; /* data format.*/ + u16 num_channels; /* Number of channels.*/ + u16 reserved; + /* Slave channel mapping for respective channels.*/ + u8 slave_ch_mapping[8]; +} __packed; + +struct afe_port_rtproxy_cfg { + u16 bitwidth; /* 16,24,32 */ + u16 interleaved; /* interleaved = 1 */ + /* Noninterleaved = 0 */ + u16 frame_sz; /* 5ms buffers = 160bytes */ + u16 jitter; /* 10ms of jitter = 320 */ + u16 lw_mark; /* Low watermark in bytes for triggering event*/ + u16 hw_mark; /* High watermark bytes for triggering event*/ + u16 rsvd; + int num_ch; /* 1 to 8 */ +} __packed; + +struct afe_port_pseudo_cfg { + u16 bit_width; + u16 num_channels; + u16 data_format; + u16 timing_mode; + u16 reserved; +} __packed; + +#define AFE_PORT_AUDIO_IF_CONFIG 0x000100d3 +#define AFE_PORT_AUDIO_SLIM_SCH_CONFIG 0x000100e4 +#define AFE_PORT_MULTI_CHAN_HDMI_AUDIO_IF_CONFIG 0x000100D9 +#define AFE_PORT_CMD_I2S_CONFIG 0x000100E7 + +union afe_port_config { + struct afe_port_pcm_cfg pcm; + struct afe_port_mi2s_cfg mi2s; + struct afe_port_hdmi_cfg hdmi; + struct afe_port_hdmi_multi_ch_cfg hdmi_multi_ch; + struct afe_port_slimbus_cfg slimbus; + struct afe_port_slimbus_sch_cfg slim_sch; + struct afe_port_rtproxy_cfg rtproxy; + struct afe_port_pseudo_cfg pseudo; +} __packed; + +struct afe_audioif_config_command { + struct apr_hdr hdr; + u16 port_id; + union afe_port_config port; +} __packed; + +#define AFE_TEST_CODEC_LOOPBACK_CTL 0x000100d5 +struct afe_codec_loopback_command { + u16 port_inf; /* Primary i2s = 0 */ + /* PCM = 2 */ + /* Secondary i2s = 4 */ + /* Mi2s = 6 */ + u16 enable; /* 0, disable. 1, enable */ +} __packed; + + +#define AFE_PARAM_ID_SIDETONE_GAIN 0x00010300 +struct afe_param_sidetone_gain { + u16 gain; + u16 reserved; +} __packed; + +#define AFE_PARAM_ID_SAMPLING_RATE 0x00010301 +struct afe_param_sampling_rate { + u32 sampling_rate; +} __packed; + + +#define AFE_PARAM_ID_CHANNELS 0x00010302 +struct afe_param_channels { + u16 channels; + u16 reserved; +} __packed; + + +#define AFE_PARAM_ID_LOOPBACK_GAIN 0x00010303 +struct afe_param_loopback_gain { + u16 gain; + u16 reserved; +} __packed; + +/* Parameter ID used to configure and enable/disable the loopback path. The + * difference with respect to the existing API, AFE_PORT_CMD_LOOPBACK, is that + * it allows Rx port to be configured as source port in loopback path. Port-id + * in AFE_PORT_CMD_SET_PARAM cmd is the source port which can be Tx or Rx port. + * In addition, we can configure the type of routing mode to handle different + * use cases. + */ +enum { + /* Regular loopback from source to destination port */ + LB_MODE_DEFAULT = 1, + /* Sidetone feed from Tx source to Rx destination port */ + LB_MODE_SIDETONE, + /* Echo canceller reference, voice + audio + DTMF */ + LB_MODE_EC_REF_VOICE_AUDIO, + /* Echo canceller reference, voice alone */ + LB_MODE_EC_REF_VOICE +}; + +#define AFE_PARAM_ID_LOOPBACK_CONFIG 0x0001020B +#define AFE_API_VERSION_LOOPBACK_CONFIG 0x1 +struct afe_param_loopback_cfg { + /* Minor version used for tracking the version of the configuration + * interface. + */ + uint32_t loopback_cfg_minor_version; + + /* Destination Port Id. */ + uint16_t dst_port_id; + + /* Specifies data path type from src to dest port. Supported values: + * LB_MODE_DEFAULT + * LB_MODE_SIDETONE + * LB_MODE_EC_REF_VOICE_AUDIO + * LB_MODE_EC_REF_VOICE + */ + uint16_t routing_mode; + + /* Specifies whether to enable (1) or disable (0) an AFE loopback. */ + uint16_t enable; + + /* Reserved for 32-bit alignment. This field must be set to 0. */ + uint16_t reserved; +} __packed; + +#define AFE_MODULE_ID_PORT_INFO 0x00010200 +/* Module ID for the loopback-related parameters. */ +#define AFE_MODULE_LOOPBACK 0x00010205 +struct afe_param_payload_base { + u32 module_id; + u32 param_id; + u16 param_size; + u16 reserved; +} __packed; + +struct afe_param_payload { + struct afe_param_payload_base base; + union { + struct afe_param_sidetone_gain sidetone_gain; + struct afe_param_sampling_rate sampling_rate; + struct afe_param_channels channels; + struct afe_param_loopback_gain loopback_gain; + struct afe_param_loopback_cfg loopback_cfg; + } __packed param; +} __packed; + +#define AFE_PORT_CMD_SET_PARAM 0x000100dc + +struct afe_port_cmd_set_param { + struct apr_hdr hdr; + u16 port_id; + u16 payload_size; + u32 payload_address; + struct afe_param_payload payload; +} __packed; + +struct afe_port_cmd_set_param_no_payload { + struct apr_hdr hdr; + u16 port_id; + u16 payload_size; + u32 payload_address; +} __packed; + +#define AFE_EVENT_GET_ACTIVE_PORTS 0x00010100 +struct afe_get_active_ports_rsp { + u16 num_ports; + u16 port_id; +} __packed; + + +#define AFE_EVENT_GET_ACTIVE_HANDLES 0x00010102 +struct afe_get_active_handles_rsp { + u16 port_id; + u16 num_handles; + u16 mode; /* 0, voice rx */ + /* 1, voice tx */ + /* 2, audio rx */ + /* 3, audio tx */ + u16 handle; +} __packed; + +#define AFE_SERVICE_CMD_MEMORY_MAP 0x000100DE +struct afe_cmd_memory_map { + struct apr_hdr hdr; + u32 phy_addr; + u32 mem_sz; + u16 mem_id; + u16 rsvd; +} __packed; + +#define AFE_SERVICE_CMD_MEMORY_UNMAP 0x000100DF +struct afe_cmd_memory_unmap { + struct apr_hdr hdr; + u32 phy_addr; +} __packed; + +#define AFE_SERVICE_CMD_REG_RTPORT 0x000100E0 +struct afe_cmd_reg_rtport { + struct apr_hdr hdr; + u16 port_id; + u16 rsvd; +} __packed; + +#define AFE_SERVICE_CMD_UNREG_RTPORT 0x000100E1 +struct afe_cmd_unreg_rtport { + struct apr_hdr hdr; + u16 port_id; + u16 rsvd; +} __packed; + +#define AFE_SERVICE_CMD_RTPORT_WR 0x000100E2 +struct afe_cmd_rtport_wr { + struct apr_hdr hdr; + u16 port_id; + u16 rsvd; + u32 buf_addr; + u32 bytes_avail; +} __packed; + +#define AFE_SERVICE_CMD_RTPORT_RD 0x000100E3 +struct afe_cmd_rtport_rd { + struct apr_hdr hdr; + u16 port_id; + u16 rsvd; + u32 buf_addr; + u32 bytes_avail; +} __packed; + +#define AFE_EVENT_RT_PROXY_PORT_STATUS 0x00010105 + +#define ADM_MAX_COPPS 5 + +#define ADM_SERVICE_CMD_GET_COPP_HANDLES 0x00010300 +struct adm_get_copp_handles_command { + struct apr_hdr hdr; +} __packed; + +#define ADM_CMD_MATRIX_MAP_ROUTINGS 0x00010301 +struct adm_routings_session { + u16 id; + u16 num_copps; + u16 copp_id[ADM_MAX_COPPS+1]; /*Padding if numCopps is odd */ +} __packed; + +struct adm_routings_command { + struct apr_hdr hdr; + u32 path; /* 0 = Rx, 1 Tx */ + u32 num_sessions; + struct adm_routings_session session[8]; +} __packed; + + +#define ADM_CMD_MATRIX_RAMP_GAINS 0x00010302 +struct adm_ramp_gain { + struct apr_hdr hdr; + u16 session_id; + u16 copp_id; + u16 initial_gain; + u16 gain_increment; + u16 ramp_duration; + u16 reserved; +} __packed; + +struct adm_ramp_gains_command { + struct apr_hdr hdr; + u32 id; + u32 num_gains; + struct adm_ramp_gain gains[ADM_MAX_COPPS]; +} __packed; + + +#define ADM_CMD_COPP_OPEN 0x00010304 +struct adm_copp_open_command { + struct apr_hdr hdr; + u16 flags; + u16 mode; /* 1-RX, 2-Live TX, 3-Non Live TX */ + u16 endpoint_id1; + u16 endpoint_id2; + u32 topology_id; + u16 channel_config; + u16 reserved; + u32 rate; +} __packed; + +#define ADM_CMD_COPP_CLOSE 0x00010305 + +#define ADM_CMD_MULTI_CHANNEL_COPP_OPEN 0x00010310 +#define ADM_CMD_MULTI_CHANNEL_COPP_OPEN_V3 0x00010333 +struct adm_multi_ch_copp_open_command { + struct apr_hdr hdr; + u16 flags; + u16 mode; /* 1-RX, 2-Live TX, 3-Non Live TX */ + u16 endpoint_id1; + u16 endpoint_id2; + u32 topology_id; + u16 channel_config; + u16 reserved; + u32 rate; + u8 dev_channel_mapping[8]; +} __packed; + +struct adm_multi_channel_copp_open_v3 { + struct apr_hdr hdr; + u16 flags; + u16 mode; + u16 endpoint_id1; + u16 endpoint_id2; + u32 topology_id; + u16 channel_config; + u16 bit_width; + u32 rate; + u8 dev_channel_mapping[8]; +}; + +#define ADM_CMD_MEMORY_MAP 0x00010C30 +struct adm_cmd_memory_map { + struct apr_hdr hdr; + u32 buf_add; + u32 buf_size; + u16 mempool_id; + u16 reserved; +} __packed; + +#define ADM_CMD_MEMORY_UNMAP 0x00010C31 +struct adm_cmd_memory_unmap { + struct apr_hdr hdr; + u32 buf_add; +} __packed; + +#define ADM_CMD_MEMORY_MAP_REGIONS 0x00010C47 +struct adm_memory_map_regions { + u32 phys; + u32 buf_size; +} __packed; + +struct adm_cmd_memory_map_regions { + struct apr_hdr hdr; + u16 mempool_id; + u16 nregions; +} __packed; + +#define ADM_CMD_MEMORY_UNMAP_REGIONS 0x00010C48 +struct adm_memory_unmap_regions { + u32 phys; +} __packed; + +struct adm_cmd_memory_unmap_regions { + struct apr_hdr hdr; + u16 nregions; + u16 reserved; +} __packed; + +#define DEFAULT_COPP_TOPOLOGY 0x00010be3 +#define DEFAULT_POPP_TOPOLOGY 0x00010be4 +#define VPM_TX_SM_ECNS_COPP_TOPOLOGY 0x00010F71 +#define VPM_TX_DM_FLUENCE_COPP_TOPOLOGY 0x00010F72 +#define VPM_TX_QMIC_FLUENCE_COPP_TOPOLOGY 0x00010F75 + +#define LOWLATENCY_POPP_TOPOLOGY 0x00010C68 +#define LOWLATENCY_COPP_TOPOLOGY 0x00010312 +#define PCM_BITS_PER_SAMPLE 16 + +#define ASM_OPEN_WRITE_PERF_MODE_BIT (1<<28) +#define ASM_OPEN_READ_PERF_MODE_BIT (1<<29) +#define ADM_MULTI_CH_COPP_OPEN_PERF_MODE_BIT (1<<13) + + +#define ASM_MAX_EQ_BANDS 12 + +struct asm_eq_band { + u32 band_idx; /* The band index, 0 .. 11 */ + u32 filter_type; /* Filter band type */ + u32 center_freq_hz; /* Filter band center frequency */ + u32 filter_gain; /* Filter band initial gain (dB) */ + /* Range is +12 dB to -12 dB with 1dB increments. */ + u32 q_factor; +} __packed; + +struct asm_equalizer_params { + u32 enable; + u32 num_bands; + struct asm_eq_band eq_bands[ASM_MAX_EQ_BANDS]; +} __packed; + +struct asm_master_gain_params { + u16 master_gain; + u16 padding; +} __packed; + +struct asm_lrchannel_gain_params { + u16 left_gain; + u16 right_gain; +} __packed; + +struct asm_mute_params { + u32 muteflag; +} __packed; + +struct asm_softvolume_params { + u32 period; + u32 step; + u32 rampingcurve; +} __packed; + +struct asm_softpause_params { + u32 enable; + u32 period; + u32 step; + u32 rampingcurve; +} __packed; + +struct asm_pp_param_data_hdr { + u32 module_id; + u32 param_id; + u16 param_size; + u16 reserved; +} __packed; + +struct asm_pp_params_command { + struct apr_hdr hdr; + u32 *payload; + u32 payload_size; + struct asm_pp_param_data_hdr params; +} __packed; + +#define EQUALIZER_MODULE_ID 0x00010c27 +#define EQUALIZER_PARAM_ID 0x00010c28 + +#define VOLUME_CONTROL_MODULE_ID 0x00010bfe +#define MASTER_GAIN_PARAM_ID 0x00010bff +#define L_R_CHANNEL_GAIN_PARAM_ID 0x00010c00 +#define MUTE_CONFIG_PARAM_ID 0x00010c01 +#define SOFT_PAUSE_PARAM_ID 0x00010D6A +#define SOFT_VOLUME_PARAM_ID 0x00010C29 + +#define IIR_FILTER_ENABLE_PARAM_ID 0x00010c03 +#define IIR_FILTER_PREGAIN_PARAM_ID 0x00010c04 +#define IIR_FILTER_CONFIG_PARAM_ID 0x00010c05 + +#define MBADRC_MODULE_ID 0x00010c06 +#define MBADRC_ENABLE_PARAM_ID 0x00010c07 +#define MBADRC_CONFIG_PARAM_ID 0x00010c08 + + +#define ADM_CMD_SET_PARAMS 0x00010306 +#define ADM_CMD_GET_PARAMS 0x0001030B +#define ADM_CMDRSP_GET_PARAMS 0x0001030C +struct adm_set_params_command { + struct apr_hdr hdr; + u32 payload; + u32 payload_size; +} __packed; + + +#define ADM_CMD_TAP_COPP_PCM 0x00010307 +struct adm_tap_copp_pcm_command { + struct apr_hdr hdr; +} __packed; + + +/* QDSP6 to Client messages */ +#define ADM_SERVICE_CMDRSP_GET_COPP_HANDLES 0x00010308 +struct adm_get_copp_handles_respond { + struct apr_hdr hdr; + u32 handles; + u32 copp_id; +} __packed; + +#define ADM_CMDRSP_COPP_OPEN 0x0001030A +struct adm_copp_open_respond { + u32 status; + u16 copp_id; + u16 reserved; +} __packed; + +#define ADM_CMDRSP_MULTI_CHANNEL_COPP_OPEN 0x00010311 +#define ADM_CMDRSP_MULTI_CHANNEL_COPP_OPEN_V3 0x00010334 + + +#define ASM_STREAM_PRIORITY_NORMAL 0 +#define ASM_STREAM_PRIORITY_LOW 1 +#define ASM_STREAM_PRIORITY_HIGH 2 +#define ASM_STREAM_PRIORITY_RESERVED 3 + +#define ASM_END_POINT_DEVICE_MATRIX 0 +#define ASM_END_POINT_STREAM 1 + +#define AAC_ENC_MODE_AAC_LC 0x02 +#define AAC_ENC_MODE_AAC_P 0x05 +#define AAC_ENC_MODE_EAAC_P 0x1D + +#define ASM_STREAM_CMD_CLOSE 0x00010BCD +#define ASM_STREAM_CMD_FLUSH 0x00010BCE +#define ASM_STREAM_CMD_SET_PP_PARAMS 0x00010BCF +#define ASM_STREAM_CMD_GET_PP_PARAMS 0x00010BD0 +#define ASM_STREAM_CMDRSP_GET_PP_PARAMS 0x00010BD1 +#define ASM_SESSION_CMD_PAUSE 0x00010BD3 +#define ASM_SESSION_CMD_GET_SESSION_TIME 0x00010BD4 +#define ASM_DATA_CMD_EOS 0x00010BDB +#define ASM_DATA_EVENT_EOS 0x00010BDD + +#define ASM_SERVICE_CMD_GET_STREAM_HANDLES 0x00010C0B +#define ASM_STREAM_CMD_FLUSH_READBUFS 0x00010C09 + +#define ASM_SESSION_EVENT_RX_UNDERFLOW 0x00010C17 +#define ASM_SESSION_EVENT_TX_OVERFLOW 0x00010C18 +#define ASM_SERVICE_CMD_GET_WALLCLOCK_TIME 0x00010C19 +#define ASM_DATA_CMDRSP_EOS 0x00010C1C + +/* ASM Data structures */ + +/* common declarations */ +struct asm_pcm_cfg { + u16 ch_cfg; + u16 bits_per_sample; + u32 sample_rate; + u16 is_signed; + u16 interleaved; +}; + +#define PCM_CHANNEL_NULL 0 + +/* Front left channel. */ +#define PCM_CHANNEL_FL 1 + +/* Front right channel. */ +#define PCM_CHANNEL_FR 2 + +/* Front center channel. */ +#define PCM_CHANNEL_FC 3 + +/* Left surround channel.*/ +#define PCM_CHANNEL_LS 4 + +/* Right surround channel.*/ +#define PCM_CHANNEL_RS 5 + +/* Low frequency effect channel. */ +#define PCM_CHANNEL_LFE 6 + +/* Center surround channel; Rear center channel. */ +#define PCM_CHANNEL_CS 7 + +/* Left back channel; Rear left channel. */ +#define PCM_CHANNEL_LB 8 + +/* Right back channel; Rear right channel. */ +#define PCM_CHANNEL_RB 9 + +/* Top surround channel. */ +#define PCM_CHANNEL_TS 10 + +/* Center vertical height channel.*/ +#define PCM_CHANNEL_CVH 11 + +/* Mono surround channel.*/ +#define PCM_CHANNEL_MS 12 + +/* Front left of center. */ +#define PCM_CHANNEL_FLC 13 + +/* Front right of center. */ +#define PCM_CHANNEL_FRC 14 + +/* Rear left of center. */ +#define PCM_CHANNEL_RLC 15 + +/* Rear right of center. */ +#define PCM_CHANNEL_RRC 16 + +#define PCM_FORMAT_MAX_NUM_CHANNEL 8 + +/* Maximum number of channels supported + * in ASM_ENCDEC_DEC_CHAN_MAP command + */ +#define MAX_CHAN_MAP_CHANNELS 16 +/* + * Multiple-channel PCM decoder format block structure used in the + * #ASM_STREAM_CMD_OPEN_WRITE command. + * The data must be in little-endian format. + */ +struct asm_multi_channel_pcm_fmt_blk { + + u16 num_channels; /* + * Number of channels. + * Supported values:1 to 8 + */ + + u16 bits_per_sample; /* + * Number of bits per sample per channel. + * Supported values: 16, 24 When used for + * playback, the client must send 24-bit + * samples packed in 32-bit words. The + * 24-bit samples must be placed in the most + * significant 24 bits of the 32-bit word. When + * used for recording, the aDSP sends 24-bit + * samples packed in 32-bit words. The 24-bit + * samples are placed in the most significant + * 24 bits of the 32-bit word. + */ + + u32 sample_rate; /* + * Number of samples per second + * (in Hertz). Supported values: + * 2000 to 48000 + */ + + u16 is_signed; /* + * Flag that indicates the samples + * are signed (1). + */ + + u16 is_interleaved; /* + * Flag that indicates whether the channels are + * de-interleaved (0) or interleaved (1). + * Interleaved format means corresponding + * samples from the left and right channels are + * interleaved within the buffer. + * De-interleaved format means samples from + * each channel are contiguous in the buffer. + * The samples from one channel immediately + * follow those of the previous channel. + */ + + u8 channel_mapping[8]; /* + * Supported values: + * PCM_CHANNEL_NULL, PCM_CHANNEL_FL, + * PCM_CHANNEL_FR, PCM_CHANNEL_FC, + * PCM_CHANNEL_LS, PCM_CHANNEL_RS, + * PCM_CHANNEL_LFE, PCM_CHANNEL_CS, + * PCM_CHANNEL_LB, PCM_CHANNEL_RB, + * PCM_CHANNEL_TS, PCM_CHANNEL_CVH, + * PCM_CHANNEL_MS, PCM_CHANNEL_FLC, + * PCM_CHANNEL_FRC, PCM_CHANNEL_RLC, + * PCM_CHANNEL_RRC. + * Channel[i] mapping describes channel I. Each + * element i of the array describes channel I + * inside the buffer where I < num_channels. + * An unused channel is set to zero. + */ +}; +struct asm_dts_enc_cfg { + uint32_t sample_rate; + /* + * Samples at which input is to be encoded. + * Supported values: + * 44100 -- encode at 44.1 Khz + * 48000 -- encode at 48 Khz + */ + + uint32_t num_channels; + /* + * Number of channels for multi-channel encoding. + * Supported values: 1 to 6 + */ + + uint8_t channel_mapping[6]; + /* + * Channel array of size 16. Channel[i] mapping describes channel I. + * Each element i of the array describes channel I inside the buffer + * where num_channels. An unused channel is set to zero. Only first + * num_channels elements are valid + * + * Supported values: + * - # PCM_CHANNEL_L + * - # PCM_CHANNEL_R + * - # PCM_CHANNEL_C + * - # PCM_CHANNEL_LS + * - # PCM_CHANNEL_RS + * - # PCM_CHANNEL_LFE + */ + +}; +struct asm_adpcm_cfg { + u16 ch_cfg; + u16 bits_per_sample; + u32 sample_rate; + u32 block_size; +}; + +struct asm_yadpcm_cfg { + u16 ch_cfg; + u16 bits_per_sample; + u32 sample_rate; +}; + +struct asm_midi_cfg { + u32 nMode; +}; + +struct asm_wma_cfg { + u16 format_tag; + u16 ch_cfg; + u32 sample_rate; + u32 avg_bytes_per_sec; + u16 block_align; + u16 valid_bits_per_sample; + u32 ch_mask; + u16 encode_opt; + u16 adv_encode_opt; + u32 adv_encode_opt2; + u32 drc_peak_ref; + u32 drc_peak_target; + u32 drc_ave_ref; + u32 drc_ave_target; +}; + +struct asm_wmapro_cfg { + u16 format_tag; + u16 ch_cfg; + u32 sample_rate; + u32 avg_bytes_per_sec; + u16 block_align; + u16 valid_bits_per_sample; + u32 ch_mask; + u16 encode_opt; + u16 adv_encode_opt; + u32 adv_encode_opt2; + u32 drc_peak_ref; + u32 drc_peak_target; + u32 drc_ave_ref; + u32 drc_ave_target; +}; + +struct asm_aac_cfg { + u16 format; + u16 aot; + u16 ep_config; + u16 section_data_resilience; + u16 scalefactor_data_resilience; + u16 spectral_data_resilience; + u16 ch_cfg; + u16 reserved; + u32 sample_rate; +}; + +struct asm_amrwbplus_cfg { + u32 size_bytes; + u32 version; + u32 num_channels; + u32 amr_band_mode; + u32 amr_dtx_mode; + u32 amr_frame_fmt; + u32 amr_lsf_idx; +}; + +struct asm_flac_cfg { + u16 stream_info_present; + u16 min_blk_size; + u16 max_blk_size; + u16 ch_cfg; + u16 sample_size; + u16 sample_rate; + u16 md5_sum; + u32 ext_sample_rate; + u32 min_frame_size; + u32 max_frame_size; +}; + +struct asm_vorbis_cfg { + u32 ch_cfg; + u32 bit_rate; + u32 min_bit_rate; + u32 max_bit_rate; + u16 bit_depth_pcm_sample; + u16 bit_stream_format; +}; + +struct asm_aac_read_cfg { + u32 bitrate; + u32 enc_mode; + u16 format; + u16 ch_cfg; + u32 sample_rate; +}; + +struct asm_amrnb_read_cfg { + u16 mode; + u16 dtx_mode; +}; + +struct asm_amrwb_read_cfg { + u16 mode; + u16 dtx_mode; +}; + +struct asm_evrc_read_cfg { + u16 max_rate; + u16 min_rate; + u16 rate_modulation_cmd; + u16 reserved; +}; + +struct asm_qcelp13_read_cfg { + u16 max_rate; + u16 min_rate; + u16 reduced_rate_level; + u16 rate_modulation_cmd; +}; + +struct asm_sbc_read_cfg { + u32 subband; + u32 block_len; + u32 ch_mode; + u32 alloc_method; + u32 bit_rate; + u32 sample_rate; +}; + +struct asm_sbc_bitrate { + u32 bitrate; +}; + +struct asm_immed_decode { + u32 mode; +}; + +struct asm_sbr_ps { + u32 enable; +}; + +struct asm_dual_mono { + u16 sce_left; + u16 sce_right; +}; + +struct asm_dec_chan_map { + u32 num_channels; /* Number of decoder output + * channels. A value of 0 + * indicates native channel + * mapping, which is valid + * only for NT mode. This + * means the output of the + * decoder is to be preserved + * as is. + */ + + u8 channel_mapping[MAX_CHAN_MAP_CHANNELS];/* Channel array of size + * num_channels. It can grow + * till MAX_CHAN_MAP_CHANNELS. + * Channel[i] mapping + * describes channel I inside + * the decoder output buffer. + * Valid channel mapping + * values are to be present at + * the beginning of the array. + * All remaining elements of + * the array are to be filled + * with PCM_CHANNEL_NULL. + */ +}; + +struct asm_encode_cfg_blk { + u32 frames_per_buf; + u32 format_id; + u32 cfg_size; + union { + struct asm_pcm_cfg pcm; + struct asm_aac_read_cfg aac; + struct asm_amrnb_read_cfg amrnb; + struct asm_evrc_read_cfg evrc; + struct asm_qcelp13_read_cfg qcelp13; + struct asm_sbc_read_cfg sbc; + struct asm_amrwb_read_cfg amrwb; + struct asm_multi_channel_pcm_fmt_blk mpcm; + struct asm_dts_enc_cfg dts; + } __packed cfg; +}; + +struct asm_frame_meta_info { + u32 offset_to_frame; + u32 frame_size; + u32 encoded_pcm_samples; + u32 msw_ts; + u32 lsw_ts; + u32 nflags; +}; + +/* Stream level commands */ +#define ASM_STREAM_CMD_OPEN_READ 0x00010BCB +#define ASM_STREAM_CMD_OPEN_READ_V2_1 0x00010DB2 +struct asm_stream_cmd_open_read { + struct apr_hdr hdr; + u32 uMode; + u32 src_endpoint; + u32 pre_proc_top; + u32 format; +} __packed; + +struct asm_stream_cmd_open_read_v2_1 { + struct apr_hdr hdr; + u32 uMode; + u32 src_endpoint; + u32 pre_proc_top; + u32 format; + u16 bits_per_sample; + u16 reserved; +} __packed; + +/* Supported formats */ +#define LINEAR_PCM 0x00010BE5 +#define DTMF 0x00010BE6 +#define ADPCM 0x00010BE7 +#define YADPCM 0x00010BE8 +#define MP3 0x00010BE9 +#define MPEG4_AAC 0x00010BEA +#define AMRNB_FS 0x00010BEB +#define AMRWB_FS 0x00010BEC +#define V13K_FS 0x00010BED +#define EVRC_FS 0x00010BEE +#define EVRCB_FS 0x00010BEF +#define EVRCWB_FS 0x00010BF0 +#define MIDI 0x00010BF1 +#define SBC 0x00010BF2 +#define WMA_V10PRO 0x00010BF3 +#define WMA_V9 0x00010BF4 +#define AMR_WB_PLUS 0x00010BF5 +#define AC3_DECODER 0x00010BF6 +#define EAC3_DECODER 0x00010C3C +#define DTS 0x00010D88 +#define DTS_LBR 0x00010DBB +#define MP2 0x00010DBE +#define ATRAC 0x00010D89 +#define MAT 0x00010D8A +#define G711_ALAW_FS 0x00010BF7 +#define G711_MLAW_FS 0x00010BF8 +#define G711_PCM_FS 0x00010BF9 +#define MPEG4_MULTI_AAC 0x00010D86 +#define US_POINT_EPOS_FORMAT 0x00012310 +#define US_RAW_FORMAT 0x0001127C +#define US_PROX_FORMAT 0x0001272B +#define MULTI_CHANNEL_PCM 0x00010C66 + +#define ASM_ENCDEC_SBCRATE 0x00010C13 +#define ASM_ENCDEC_IMMDIATE_DECODE 0x00010C14 +#define ASM_ENCDEC_CFG_BLK 0x00010C2C + +#define ASM_ENCDEC_SBCRATE 0x00010C13 +#define ASM_ENCDEC_IMMDIATE_DECODE 0x00010C14 +#define ASM_ENCDEC_CFG_BLK 0x00010C2C + +#define ASM_STREAM_CMD_OPEN_READ_COMPRESSED 0x00010D95 +struct asm_stream_cmd_open_read_compressed { + struct apr_hdr hdr; + u32 uMode; + u32 frame_per_buf; +} __packed; + +#define ASM_STREAM_CMD_OPEN_WRITE 0x00010BCA +#define ASM_STREAM_CMD_OPEN_WRITE_V2_1 0x00010DB1 +struct asm_stream_cmd_open_write { + struct apr_hdr hdr; + u32 uMode; + u16 sink_endpoint; + u16 stream_handle; + u32 post_proc_top; + u32 format; +} __packed; + +#define IEC_61937_MASK 0x00000001 +#define IEC_60958_MASK 0x00000002 + +#define ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED 0x00010D84 +struct asm_stream_cmd_open_write_compressed { + struct apr_hdr hdr; + u32 flags; + u32 format; +} __packed; +#define ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK 0x00010DBA +struct asm_stream_cmd_open_transcode_loopback { + struct apr_hdr hdr; + uint32_t mode_flags; + /* + * All bits are reserved. Clients must set them to zero. + */ + + uint32_t src_format_id; + /* + * Specifies the media format of the input audio stream. + * + * Supported values: + * - #ASM_MEDIA_FMT_LINEAR_PCM + * - #ASM_MEDIA_FMT_MULTI_CHANNEL_PCM + */ + + uint32_t sink_format_id; + /* + * Specifies the media format of the output stream. + * + * Supported values: + * - #ASM_MEDIA_FMT_LINEAR_PCM + * - #ASM_MEDIA_FMT_MULTI_CHANNEL_PCM + * - #ASM_MEDIA_FMT_DTS + */ + + uint32_t audproc_topo_id; + /* + * Postprocessing topology ID, which specifies the topology (order of + * processing) of postprocessing algorithms. + * + * Supported values: + * - #ASM_STREAM_POSTPROC_TOPO_ID_DEFAULT + * - #ASM_STREAM_POSTPROC_TOPO_ID_PEAKMETER + * - #ASM_STREAM_POSTPROC_TOPO_ID_NONE + * - #ASM_STREAM_POSTPROC_TOPO_ID_MCH_PEAK_VOL + */ + + uint16_t src_endpoint_type; + /* + * Specifies the source endpoint that provides the input samples. + * + * Supported values: + * - 0 -- Tx device matrix or stream router + * (gateway to the hardware ports) + * - All other values are reserved + * + * Clients must set this field to zero. Otherwise, an error is returned. + */ + + uint16_t sink_endpoint_type; + /* + * Specifies the sink endpoint type. + * + * Supported values: + * - 0 -- Rx device matrix or stream router + * (gateway to the hardware ports) + * - All other values are reserved + * + * Clients must set this field to zero. Otherwise, an error is returned. + */ + + uint16_t bits_per_sample; + /* + * Number of bits per sample processed by the ASM modules. + * Supported values: 16, 24 + */ + + uint16_t reserved; + /* + * This field must be set to zero. + */ +} __packed; + +/* + * ID of the DTS mix LFE channel to front channels parameter in the + * #ASM_STREAM_CMD_SET_ENCDEC_PARAM command. + * asm_dts_generic_param_t + * ASM_PARAM_ID_DTS_MIX_LFE_TO_FRONT + */ +#define ASM_PARAM_ID_DTS_MIX_LFE_TO_FRONT 0x00010DB6 + +/* + * ID of the DTS DRC ratio parameter in the + * #ASM_STREAM_CMD_SET_ENCDEC_PARAM command. + * asm_dts_generic_param_t + * ASM_PARAM_ID_DTS_DRC_RATIO + */ +#define ASM_PARAM_ID_DTS_DRC_RATIO 0x00010DB7 + +/* + * ID of the DTS enable dialog normalization parameter in the + * #ASM_STREAM_CMD_SET_ENCDEC_PARAM command. + * + * asm_dts_generic_param_t + * ASM_PARAM_ID_DTS_ENABLE_DIALNORM + */ +#define ASM_PARAM_ID_DTS_ENABLE_DIALNORM 0x00010DB8 + +/* + * ID of the DTS enable parse REV2AUX parameter in the + * #ASM_STREAM_CMD_SET_ENCDEC_PARAM command. + * asm_dts_generic_param_t + * ASM_PARAM_ID_DTS_ENABLE_PARSE_REV2AUX + */ +#define ASM_PARAM_ID_DTS_ENABLE_PARSE_REV2AUX 0x00010DB9 + +struct asm_dts_generic_param { + int32_t generic_parameter; + /* + * #ASM_PARAM_ID_DTS_MIX_LFE_TO_FRONT: + * - if enabled, mixes LFE channel to front + * while downmixing (if necessary) + * - Supported values: 1-> enable, 0-> disable + * - Default: disabled + * + * #ASM_PARAM_ID_DTS_DRC_RATIO: + * - percentage of DRC ratio. + * - Supported values: 0-100 + * - Default: 0, DRC is disabled. + * + * #ASM_PARAM_ID_DTS_ENABLE_DIALNORM: + * - flag to enable dialog normalization post processing. + * - Supported values: 1-> enable, 0-> disable. + * - Default: enabled. + * + * #ASM_PARAM_ID_DTS_ENABLE_PARSE_REV2AUX: + * - flag to enable parsing of rev2aux chunk in the bitstream. + * This chunk contains broadcast metadata. + * - Supported values: 1-> enable, 0-> disable. + * - Default: disabled. + */ +}; + +struct asm_stream_cmd_dts_dec_param { + struct apr_hdr hdr; + u32 param_id; + u32 param_size; + struct asm_dts_generic_param generic_param; +} __packed; + + +#define ASM_STREAM_CMD_OPEN_READWRITE 0x00010BCC + +struct asm_stream_cmd_open_read_write { + struct apr_hdr hdr; + u32 uMode; + u32 post_proc_top; + u32 write_format; + u32 read_format; +} __packed; + +#define ASM_STREAM_CMD_OPEN_LOOPBACK 0x00010D6E +struct asm_stream_cmd_open_loopback { + struct apr_hdr hdr; + u32 mode_flags; +/* Mode flags. + * Bit 0-31: reserved; client should set these bits to 0 + */ + u16 src_endpointype; + /* Endpoint type. 0 = Tx Matrix */ + u16 sink_endpointype; + /* Endpoint type. 0 = Rx Matrix */ + u32 postprocopo_id; +/* Postprocessor topology ID. Specifies the topology of + * postprocessing algorithms. + */ +} __packed; + +#define ADM_CMD_CONNECT_AFE_PORT 0x00010320 +#define ADM_CMD_DISCONNECT_AFE_PORT 0x00010321 + +struct adm_cmd_connect_afe_port { + struct apr_hdr hdr; + u8 mode; /*mode represent the interface is for RX or TX*/ + u8 session_id; /*ASM session ID*/ + u16 afe_port_id; +} __packed; + +#define ADM_CMD_CONNECT_AFE_PORT_V2 0x00010332 + +struct adm_cmd_connect_afe_port_v2 { + struct apr_hdr hdr; + u8 mode; /*mode represent the interface is for RX or TX*/ + u8 session_id; /*ASM session ID*/ + u16 afe_port_id; + u32 num_channels; + u32 sampling_rate; +} __packed; + +#define ASM_STREAM_CMD_SET_ENCDEC_PARAM 0x00010C10 +#define ASM_STREAM_CMD_GET_ENCDEC_PARAM 0x00010C11 +#define ASM_ENCDEC_CFG_BLK_ID 0x00010C2C +#define ASM_ENABLE_SBR_PS 0x00010C63 +#define ASM_CONFIGURE_DUAL_MONO 0x00010C64 +struct asm_stream_cmd_encdec_cfg_blk { + struct apr_hdr hdr; + u32 param_id; + u32 param_size; + struct asm_encode_cfg_blk enc_blk; +} __packed; + +struct asm_stream_cmd_encdec_sbc_bitrate { + struct apr_hdr hdr; + u32 param_id; + struct asm_sbc_bitrate sbc_bitrate; +} __packed; + +struct asm_stream_cmd_encdec_immed_decode { + struct apr_hdr hdr; + u32 param_id; + u32 param_size; + struct asm_immed_decode dec; +} __packed; + +struct asm_stream_cmd_encdec_sbr { + struct apr_hdr hdr; + u32 param_id; + u32 param_size; + struct asm_sbr_ps sbr_ps; +} __packed; + +struct asm_stream_cmd_encdec_dualmono { + struct apr_hdr hdr; + u32 param_id; + u32 param_size; + struct asm_dual_mono channel_map; +} __packed; + +#define ASM_PARAM_ID_AAC_STEREO_MIX_COEFF_SELECTION_FLAG 0x00010DD8 + +/* Structure for AAC decoder stereo coefficient setting. */ + +struct asm_aac_stereo_mix_coeff_selection_param { + struct apr_hdr hdr; + u32 param_id; + u32 param_size; + u32 aac_stereo_mix_coeff_flag; +} __packed; + +#define ASM_ENCDEC_DEC_CHAN_MAP 0x00010D82 +struct asm_stream_cmd_encdec_channelmap { + struct apr_hdr hdr; + u32 param_id; + u32 param_size; + struct asm_dec_chan_map chan_map; +} __packed; + +#define ASM_STREAM_CMD_ADJUST_SAMPLES 0x00010C0A +struct asm_stream_cmd_adjust_samples { + struct apr_hdr hdr; + u16 nsamples; + u16 reserved; +} __packed; + +#define ASM_STREAM_CMD_TAP_POPP_PCM 0x00010BF9 +struct asm_stream_cmd_tap_popp_pcm { + struct apr_hdr hdr; + u16 enable; + u16 reserved; + u32 module_id; +} __packed; + +/* Session Level commands */ +#define ASM_SESSION_CMD_MEMORY_MAP 0x00010C32 +struct asm_stream_cmd_memory_map { + struct apr_hdr hdr; + u32 buf_add; + u32 buf_size; + u16 mempool_id; + u16 reserved; +} __packed; + +#define ASM_SESSION_CMD_MEMORY_UNMAP 0x00010C33 +struct asm_stream_cmd_memory_unmap { + struct apr_hdr hdr; + u32 buf_add; +} __packed; + +#define ASM_SESSION_CMD_MEMORY_MAP_REGIONS 0x00010C45 +struct asm_memory_map_regions { + u32 phys; + u32 buf_size; +} __packed; + +struct asm_stream_cmd_memory_map_regions { + struct apr_hdr hdr; + u16 mempool_id; + u16 nregions; +} __packed; + +#define ASM_SESSION_CMD_MEMORY_UNMAP_REGIONS 0x00010C46 +struct asm_memory_unmap_regions { + u32 phys; +} __packed; + +struct asm_stream_cmd_memory_unmap_regions { + struct apr_hdr hdr; + u16 nregions; + u16 reserved; +} __packed; + +#define ASM_SESSION_CMD_RUN 0x00010BD2 +struct asm_stream_cmd_run { + struct apr_hdr hdr; + u32 flags; + u32 msw_ts; + u32 lsw_ts; +} __packed; + +/* Session level events */ +#define ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS 0x00010BD5 +struct asm_stream_cmd_reg_rx_underflow_event { + struct apr_hdr hdr; + u16 enable; + u16 reserved; +} __packed; + +#define ASM_SESSION_CMD_REGISTER_FOR_TX_OVERFLOW_EVENTS 0x00010BD6 +struct asm_stream_cmd_reg_tx_overflow_event { + struct apr_hdr hdr; + u16 enable; + u16 reserved; +} __packed; + +/* Data Path commands */ +#define ASM_DATA_CMD_WRITE 0x00010BD9 +struct asm_stream_cmd_write { + struct apr_hdr hdr; + u32 buf_add; + u32 avail_bytes; + u32 uid; + u32 msw_ts; + u32 lsw_ts; + u32 uflags; +} __packed; + +#define ASM_DATA_CMD_READ 0x00010BDA +struct asm_stream_cmd_read { + struct apr_hdr hdr; + u32 buf_add; + u32 buf_size; + u32 uid; +} __packed; + +#define ASM_DATA_CMD_READ_COMPRESSED 0x00010DBF +struct asm_stream_cmd_read_compressed { + struct apr_hdr hdr; + u32 buf_add; + u32 buf_size; + u32 uid; +} __packed; + +#define ASM_DATA_CMD_MEDIA_FORMAT_UPDATE 0x00010BDC +#define ASM_DATA_EVENT_ENC_SR_CM_NOTIFY 0x00010BDE +struct asm_stream_media_format_update { + struct apr_hdr hdr; + u32 format; + u32 cfg_size; + union { + struct asm_pcm_cfg pcm_cfg; + struct asm_adpcm_cfg adpcm_cfg; + struct asm_yadpcm_cfg yadpcm_cfg; + struct asm_midi_cfg midi_cfg; + struct asm_wma_cfg wma_cfg; + struct asm_wmapro_cfg wmapro_cfg; + struct asm_aac_cfg aac_cfg; + struct asm_flac_cfg flac_cfg; + struct asm_vorbis_cfg vorbis_cfg; + struct asm_multi_channel_pcm_fmt_blk multi_ch_pcm_cfg; + struct asm_amrwbplus_cfg amrwbplus_cfg; + } __packed write_cfg; +} __packed; + + +/* Command Responses */ +#define ASM_STREAM_CMDRSP_GET_ENCDEC_PARAM 0x00010C12 +struct asm_stream_cmdrsp_get_readwrite_param { + struct apr_hdr hdr; + u32 status; + u32 param_id; + u16 param_size; + u16 padding; + union { + struct asm_sbc_bitrate sbc_bitrate; + struct asm_immed_decode aac_dec; + } __packed read_write_cfg; +} __packed; + + +#define ASM_SESSION_CMDRSP_GET_SESSION_TIME 0x00010BD8 +struct asm_stream_cmdrsp_get_session_time { + struct apr_hdr hdr; + u32 status; + u32 msw_ts; + u32 lsw_ts; +} __packed; + +#define ASM_DATA_EVENT_WRITE_DONE 0x00010BDF +struct asm_data_event_write_done { + u32 buf_add; + u32 status; +} __packed; + +#define ASM_DATA_EVENT_READ_DONE 0x00010BE0 +struct asm_data_event_read_done { + u32 status; + u32 buffer_add; + u32 enc_frame_size; + u32 offset; + u32 msw_ts; + u32 lsw_ts; + u32 flags; + u32 num_frames; + u32 id; +} __packed; + +#define ASM_DATA_EVENT_READ_COMPRESSED_DONE 0x00010DC0 +struct asm_data_event_read_compressed_done { + u32 status; + u32 buffer_add; + u32 enc_frame_size; + u32 offset; + u32 msw_ts; + u32 lsw_ts; + u32 flags; + u32 num_frames; + u32 id; +} __packed; + +#define ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY 0x00010C65 +struct asm_data_event_sr_cm_change_notify { + u32 sample_rate; + u16 no_of_channels; + u16 reserved; + u8 channel_map[8]; +} __packed; + +/* service level events */ + +#define ASM_SERVICE_CMDRSP_GET_STREAM_HANDLES 0x00010C1B +struct asm_svc_cmdrsp_get_strm_handles { + struct apr_hdr hdr; + u32 num_handles; + u32 stream_handles; +} __packed; + + +#define ASM_SERVICE_CMDRSP_GET_WALLCLOCK_TIME 0x00010C1A +struct asm_svc_cmdrsp_get_wallclock_time { + struct apr_hdr hdr; + u32 status; + u32 msw_ts; + u32 lsw_ts; +} __packed; + +/* Error code */ +#define ADSP_EOK 0x00000000 /* Success / completed / no errors. */ +#define ADSP_EFAILED 0x00000001 /* General failure. */ +#define ADSP_EBADPARAM 0x00000002 /* Bad operation parameter(s). */ +#define ADSP_EUNSUPPORTED 0x00000003 /* Unsupported routine/operation. */ +#define ADSP_EVERSION 0x00000004 /* Unsupported version. */ +#define ADSP_EUNEXPECTED 0x00000005 /* Unexpected problem encountered. */ +#define ADSP_EPANIC 0x00000006 /* Unhandled problem occurred. */ +#define ADSP_ENORESOURCE 0x00000007 /* Unable to allocate resource(s). */ +#define ADSP_EHANDLE 0x00000008 /* Invalid handle. */ +#define ADSP_EALREADY 0x00000009 /* Operation is already processed. */ +#define ADSP_ENOTREADY 0x0000000A /* Operation not ready to be processed*/ +#define ADSP_EPENDING 0x0000000B /* Operation is pending completion*/ +#define ADSP_EBUSY 0x0000000C /* Operation could not be accepted or + * processed. + */ +#define ADSP_EABORTED 0x0000000D /* Operation aborted due to an error. */ +#define ADSP_EPREEMPTED 0x0000000E /* Operation preempted by higher priority*/ +#define ADSP_ECONTINUE 0x0000000F /* Operation requests intervention + * to complete. + */ +#define ADSP_EIMMEDIATE 0x00000010 /* Operation requests immediate + * intervention to complete. + */ +#define ADSP_ENOTIMPL 0x00000011 /* Operation is not implemented. */ +#define ADSP_ENEEDMORE 0x00000012 /* Operation needs more data or resources*/ + +/* SRS TRUMEDIA GUIDS */ +#define SRS_TRUMEDIA_TOPOLOGY_ID 0x00010D90 +#define SRS_TRUMEDIA_MODULE_ID 0x10005010 +#define SRS_TRUMEDIA_PARAMS 0x10005011 +#define SRS_TRUMEDIA_PARAMS_WOWHD 0x10005012 +#define SRS_TRUMEDIA_PARAMS_CSHP 0x10005013 +#define SRS_TRUMEDIA_PARAMS_HPF 0x10005014 +#define SRS_TRUMEDIA_PARAMS_PEQ 0x10005015 +#define SRS_TRUMEDIA_PARAMS_HL 0x10005016 + +/* SRS STUDIO SOUND 3D GUIDS */ +#define SRS_SS3D_TOPOLOGY_ID 0x00010720 +#define SRS_SS3D_MODULE_ID 0x10005020 +#define SRS_SS3D_PARAMS 0x10005021 +#define SRS_SS3D_PARAMS_CTRL 0x10005022 +#define SRS_SS3D_PARAMS_FILTER 0x10005023 + +/* SRS ALSA CMD MASKS */ +#define SRS_CMD_UPLOAD 0x7FFF0000 +#define SRS_PARAM_INDEX_MASK 0x80000000 +#define SRS_PARAM_OFFSET_MASK 0x3FFF0000 +#define SRS_PARAM_VALUE_MASK 0x0000FFFF + +/* SRS TRUMEDIA start */ +#define SRS_ID_GLOBAL 0x00000001 +#define SRS_ID_WOWHD 0x00000002 +#define SRS_ID_CSHP 0x00000003 +#define SRS_ID_HPF 0x00000004 +#define SRS_ID_PEQ 0x00000005 +#define SRS_ID_HL 0x00000006 + +struct srs_trumedia_params_GLOBAL { + uint8_t v1; + uint8_t v2; + uint8_t v3; + uint8_t v4; + uint8_t v5; + uint8_t v6; + uint8_t v7; + uint8_t v8; +} __packed; + +struct srs_trumedia_params_WOWHD { + uint32_t v1; + uint16_t v2; + uint16_t v3; + uint16_t v4; + uint16_t v5; + uint16_t v6; + uint16_t v7; + uint16_t v8; + uint16_t v____A1; + uint32_t v9; + uint16_t v10; + uint16_t v11; + uint32_t v12[16]; +} __packed; + +struct srs_trumedia_params_CSHP { + uint32_t v1; + uint16_t v2; + uint16_t v3; + uint16_t v4; + uint16_t v5; + uint16_t v6; + uint16_t v____A1; + uint32_t v7; + uint16_t v8; + uint16_t v9; + uint32_t v10[16]; +} __packed; + +struct srs_trumedia_params_HPF { + uint32_t v1; + uint32_t v2[26]; +} __packed; + +struct srs_trumedia_params_PEQ { + uint32_t v1; + uint16_t v2; + uint16_t v3; + uint16_t v4; + uint16_t v____A1; + uint32_t v5[26]; + uint32_t v6[26]; +} __packed; + +struct srs_trumedia_params_HL { + uint16_t v1; + uint16_t v2; + uint16_t v3; + uint16_t v____A1; + int32_t v4; + uint32_t v5; + uint16_t v6; + uint16_t v____A2; + uint32_t v7; +} __packed; + +struct srs_trumedia_params { + struct srs_trumedia_params_GLOBAL global; + struct srs_trumedia_params_WOWHD wowhd; + struct srs_trumedia_params_CSHP cshp; + struct srs_trumedia_params_HPF hpf; + struct srs_trumedia_params_PEQ peq; + struct srs_trumedia_params_HL hl; +} __packed; + +int srs_trumedia_open(int port_id, int srs_tech_id, void *srs_params); +/* SRS TruMedia end */ + +/* SRS Studio Sound 3D start */ +#define SRS_ID_SS3D_GLOBAL 0x00000001 +#define SRS_ID_SS3D_CTRL 0x00000002 +#define SRS_ID_SS3D_FILTER 0x00000003 + +struct srs_SS3D_params_GLOBAL { + uint8_t v1; + uint8_t v2; + uint8_t v3; + uint8_t v4; + uint8_t v5; + uint8_t v6; + uint8_t v7; + uint8_t v8; +} __packed; + +struct srs_SS3D_ctrl_params { + uint8_t v[236]; +} __packed; + +struct srs_SS3D_filter_params { + uint8_t v[28 + 2752]; +} __packed; + +struct srs_SS3D_params { + struct srs_SS3D_params_GLOBAL global; + struct srs_SS3D_ctrl_params ss3d; + struct srs_SS3D_filter_params ss3d_f; +} __packed; + +int srs_ss3d_open(int port_id, int srs_tech_id, void *srs_params); +/* SRS Studio Sound 3D end */ +#endif /*_APR_AUDIO_H_*/ diff --git a/include/sound/audio_cal_utils.h b/include/sound/audio_cal_utils.h new file mode 100644 index 000000000000..b28b3bdf4e83 --- /dev/null +++ b/include/sound/audio_cal_utils.h @@ -0,0 +1,102 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _AUDIO_CAL_UTILS_H +#define _AUDIO_CAL_UTILS_H + +#include +#include +#include +#include "audio_calibration.h" + +struct cal_data { + size_t size; + void *kvaddr; + phys_addr_t paddr; +}; + +struct mem_map_data { + size_t map_size; + int32_t q6map_handle; + int32_t ion_map_handle; + struct ion_client *ion_client; + struct ion_handle *ion_handle; +}; + +struct cal_block_data { + size_t client_info_size; + void *client_info; + void *cal_info; + struct list_head list; + struct cal_data cal_data; + struct mem_map_data map_data; + int32_t buffer_number; +}; + +struct cal_util_callbacks { + int (*map_cal) + (int32_t cal_type, struct cal_block_data *cal_block); + int (*unmap_cal) + (int32_t cal_type, struct cal_block_data *cal_block); + bool (*match_block) + (struct cal_block_data *cal_block, void *user_data); +}; + +struct cal_type_info { + struct audio_cal_reg reg; + struct cal_util_callbacks cal_util_callbacks; +}; + +struct cal_type_data { + struct cal_type_info info; + struct mutex lock; + struct list_head cal_blocks; +}; + + +/* to register & degregister with cal util driver */ +int cal_utils_create_cal_types(int num_cal_types, + struct cal_type_data **cal_type, + struct cal_type_info *info); +void cal_utils_destroy_cal_types(int num_cal_types, + struct cal_type_data **cal_type); + +/* common functions for callbacks */ +int cal_utils_alloc_cal(size_t data_size, void *data, + struct cal_type_data *cal_type, + size_t client_info_size, void *client_info); +int cal_utils_dealloc_cal(size_t data_size, void *data, + struct cal_type_data *cal_type); +int cal_utils_set_cal(size_t data_size, void *data, + struct cal_type_data *cal_type, + size_t client_info_size, void *client_info); + +/* use for SSR */ +void cal_utils_clear_cal_block_q6maps(int num_cal_types, + struct cal_type_data **cal_type); + + +/* common matching functions used to add blocks */ +bool cal_utils_match_buf_num(struct cal_block_data *cal_block, + void *user_data); + +/* common matching functions to find cal blocks */ +struct cal_block_data *cal_utils_get_only_cal_block( + struct cal_type_data *cal_type); + +/* Size of calibration specific data */ +size_t get_cal_info_size(int32_t cal_type); +size_t get_user_cal_type_size(int32_t cal_type); + +/* Version of the cal type*/ +int32_t cal_utils_get_cal_type_version(void *cal_type_data); +#endif diff --git a/include/sound/audio_calibration.h b/include/sound/audio_calibration.h new file mode 100644 index 000000000000..5decff913493 --- /dev/null +++ b/include/sound/audio_calibration.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2014, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _AUDIO_CALIBRATION_H +#define _AUDIO_CALIBRATION_H + +#include + +/* Used by driver in buffer_number field to notify client + * To update all blocks, for example: freeing all memory + */ +#define ALL_CAL_BLOCKS -1 + + +struct audio_cal_callbacks { + int (*alloc)(int32_t cal_type, size_t data_size, void *data); + int (*dealloc)(int32_t cal_type, size_t data_size, void *data); + int (*pre_cal)(int32_t cal_type, size_t data_size, void *data); + int (*set_cal)(int32_t cal_type, size_t data_size, void *data); + int (*get_cal)(int32_t cal_type, size_t data_size, void *data); + int (*post_cal)(int32_t cal_type, size_t data_size, void *data); +}; + +struct audio_cal_reg { + int32_t cal_type; + struct audio_cal_callbacks callbacks; +}; + +int audio_cal_register(int num_cal_types, struct audio_cal_reg *reg_data); +int audio_cal_deregister(int num_cal_types, struct audio_cal_reg *reg_data); + +#endif diff --git a/include/sound/cpe_cmi.h b/include/sound/cpe_cmi.h new file mode 100644 index 000000000000..c145a8a64261 --- /dev/null +++ b/include/sound/cpe_cmi.h @@ -0,0 +1,492 @@ +/* + * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __CPE_CMI_H__ +#define __CPE_CMI_H__ + +#include + +#define CPE_AFE_PORT_1_TX 1 +#define CPE_AFE_PORT_3_TX 3 +#define CPE_AFE_PORT_ID_2_OUT 0x02 +#define CMI_INBAND_MESSAGE_SIZE 127 + +/* + * Multiple mad types can be supported at once. + * these values can be OR'ed to form the set of + * supported mad types + */ +#define MAD_TYPE_AUDIO (1 << 0) +#define MAD_TYPE_BEACON (1 << 1) +#define MAD_TYPE_ULTRASND (1 << 2) + +/* Core service command opcodes */ +#define CPE_CORE_SVC_CMD_SHARED_MEM_ALLOC (0x3001) +#define CPE_CORE_SVC_CMDRSP_SHARED_MEM_ALLOC (0x3002) +#define CPE_CORE_SVC_CMD_SHARED_MEM_DEALLOC (0x3003) +#define CPE_CORE_SVC_CMD_DRAM_ACCESS_REQ (0x3004) +#define CPE_CORE_SVC_EVENT_SYSTEM_BOOT (0x3005) +/* core service command opcodes for WCD9335 */ +#define CPE_CORE_SVC_CMD_CFG_CLK_PLAN (0x3006) +#define CPE_CORE_SVC_CMD_CLK_FREQ_REQUEST (0x3007) + +#define CPE_BOOT_SUCCESS 0x00 +#define CPE_BOOT_FAILED 0x01 + +#define CPE_CORE_VERSION_SYSTEM_BOOT_EVENT 0x01 + +/* LSM Service command opcodes */ +#define CPE_LSM_SESSION_CMD_OPEN_TX (0x2000) +#define CPE_LSM_SESSION_CMD_SET_PARAMS (0x2001) +#define CPE_LSM_SESSION_CMD_REGISTER_SOUND_MODEL (0x2002) +#define CPE_LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL (0x2003) +#define CPE_LSM_SESSION_CMD_START (0x2004) +#define CPE_LSM_SESSION_CMD_STOP (0x2005) +#define CPE_LSM_SESSION_EVENT_DETECTION_STATUS_V2 (0x2006) +#define CPE_LSM_SESSION_CMD_CLOSE_TX (0x2007) +#define CPE_LSM_SESSION_CMD_SHARED_MEM_ALLOC (0x2008) +#define CPE_LSM_SESSION_CMDRSP_SHARED_MEM_ALLOC (0x2009) +#define CPE_LSM_SESSION_CMD_SHARED_MEM_DEALLOC (0x200A) +#define CPE_LSM_SESSION_CMD_TX_BUFF_OUTPUT_CONFIG (0x200f) +#define CPE_LSM_SESSION_CMD_OPEN_TX_V2 (0x200D) +#define CPE_LSM_SESSION_CMD_SET_PARAMS_V2 (0x200E) + +/* LSM Service module and param IDs */ +#define CPE_LSM_MODULE_ID_VOICE_WAKEUP (0x00012C00) +#define CPE_LSM_MODULE_ID_VOICE_WAKEUP_V2 (0x00012C0D) +#define CPE_LSM_MODULE_FRAMEWORK (0x00012C0E) + +#define CPE_LSM_PARAM_ID_ENDPOINT_DETECT_THRESHOLD (0x00012C01) +#define CPE_LSM_PARAM_ID_OPERATION_MODE (0x00012C02) +#define CPE_LSM_PARAM_ID_GAIN (0x00012C03) +#define CPE_LSM_PARAM_ID_CONNECT_TO_PORT (0x00012C04) +#define CPE_LSM_PARAM_ID_MIN_CONFIDENCE_LEVELS (0x00012C07) + +/* LSM LAB command opcodes */ +#define CPE_LSM_SESSION_CMD_EOB 0x0000200B +#define CPE_LSM_MODULE_ID_LAB 0x00012C08 +/* used for enable/disable lab*/ +#define CPE_LSM_PARAM_ID_LAB_ENABLE 0x00012C09 +/* used for T in LAB config DSP internal buffer*/ +#define CPE_LSM_PARAM_ID_LAB_CONFIG 0x00012C0A +#define CPE_LSM_PARAM_ID_REGISTER_SOUND_MODEL (0x00012C14) +#define CPE_LSM_PARAM_ID_DEREGISTER_SOUND_MODEL (0x00012C15) +#define CPE_LSM_PARAM_ID_MEDIA_FMT (0x00012C1E) + +/* AFE Service command opcodes */ +#define CPE_AFE_PORT_CMD_START (0x1001) +#define CPE_AFE_PORT_CMD_STOP (0x1002) +#define CPE_AFE_PORT_CMD_SUSPEND (0x1003) +#define CPE_AFE_PORT_CMD_RESUME (0x1004) +#define CPE_AFE_PORT_CMD_SHARED_MEM_ALLOC (0x1005) +#define CPE_AFE_PORT_CMDRSP_SHARED_MEM_ALLOC (0x1006) +#define CPE_AFE_PORT_CMD_SHARED_MEM_DEALLOC (0x1007) +#define CPE_AFE_PORT_CMD_GENERIC_CONFIG (0x1008) +#define CPE_AFE_SVC_CMD_LAB_MODE (0x1009) + +/* AFE Service module and param IDs */ +#define CPE_AFE_CMD_SET_PARAM (0x1000) +#define CPE_AFE_MODULE_ID_SW_MAD (0x0001022D) +#define CPE_AFE_PARAM_ID_SW_MAD_CFG (0x0001022E) +#define CPE_AFE_PARAM_ID_SVM_MODEL (0x0001022F) + +#define CPE_AFE_MODULE_HW_MAD (0x00010230) +#define CPE_AFE_PARAM_ID_HW_MAD_CTL (0x00010232) +#define CPE_AFE_PARAM_ID_HW_MAD_CFG (0x00010231) + +#define CPE_AFE_MODULE_AUDIO_DEV_INTERFACE (0x0001020C) +#define CPE_AFE_PARAM_ID_GENERIC_PORT_CONFIG (0x00010253) + +#define CPE_CMI_BASIC_RSP_OPCODE (0x0001) +#define CPE_HDR_MAX_PLD_SIZE (0x7F) + +#define CMI_OBM_FLAG_IN_BAND 0 +#define CMI_OBM_FLAG_OUT_BAND 1 + +#define CMI_SHMEM_ALLOC_FAILED 0xff + +/* + * Future Service ID's can be added one line + * before the CMI_CPE_SERVICE_ID_MAX + */ +enum { + CMI_CPE_SERVICE_ID_MIN = 0, + CMI_CPE_CORE_SERVICE_ID, + CMI_CPE_AFE_SERVICE_ID, + CMI_CPE_LSM_SERVICE_ID, + CMI_CPE_SERVICE_ID_MAX, +}; + +#define CPE_LSM_SESSION_ID_MAX 2 + +#define IS_VALID_SESSION_ID(s_id) \ + (s_id <= CPE_LSM_SESSION_ID_MAX) + +#define IS_VALID_SERVICE_ID(s_id) \ + (s_id > CMI_CPE_SERVICE_ID_MIN && \ + s_id < CMI_CPE_SERVICE_ID_MAX) + +#define IS_VALID_PLD_SIZE(p_size) \ + (p_size <= CPE_HDR_MAX_PLD_SIZE) + +#define CMI_HDR_SET_OPCODE(hdr, cmd) (hdr->opcode = cmd) + + +#define CMI_HDR_SET(hdr_info, mask, shift, value) \ + (hdr_info = (((hdr_info) & ~(mask)) | \ + ((value << shift) & mask))) + +#define SVC_ID_SHIFT 4 +#define SVC_ID_MASK (0x07 << SVC_ID_SHIFT) + +#define SESSION_ID_SHIFT 0 +#define SESSION_ID_MASK (0x0F << SESSION_ID_SHIFT) + +#define PAYLD_SIZE_SHIFT 0 +#define PAYLD_SIZE_MASK (0x7F << PAYLD_SIZE_SHIFT) + +#define OBM_FLAG_SHIFT 7 +#define OBM_FLAG_MASK (1 << OBM_FLAG_SHIFT) + +#define VERSION_SHIFT 7 +#define VERSION_MASK (1 << VERSION_SHIFT) + +#define CMI_HDR_SET_SERVICE(hdr, s_id) \ + CMI_HDR_SET(hdr->hdr_info, SVC_ID_MASK,\ + SVC_ID_SHIFT, s_id) +#define CMI_HDR_GET_SERVICE(hdr) \ + ((hdr->hdr_info >> SVC_ID_SHIFT) & \ + (SVC_ID_MASK >> SVC_ID_SHIFT)) + + +#define CMI_HDR_SET_SESSION(hdr, s_id) \ + CMI_HDR_SET(hdr->hdr_info, SESSION_ID_MASK,\ + SESSION_ID_SHIFT, s_id) + +#define CMI_HDR_GET_SESSION_ID(hdr) \ + ((hdr->hdr_info >> SESSION_ID_SHIFT) & \ + (SESSION_ID_MASK >> SESSION_ID_SHIFT)) + +#define CMI_GET_HEADER(msg) ((struct cmi_hdr *)(msg)) +#define CMI_GET_PAYLOAD(msg) ((void *)(CMI_GET_HEADER(msg) + 1)) +#define CMI_GET_OPCODE(msg) (CMI_GET_HEADER(msg)->opcode) + +#define CMI_HDR_SET_VERSION(hdr, ver) \ + CMI_HDR_SET(hdr->hdr_info, VERSION_MASK, \ + VERSION_SHIFT, ver) + +#define CMI_HDR_SET_PAYLOAD_SIZE(hdr, p_size) \ + CMI_HDR_SET(hdr->pld_info, PAYLD_SIZE_MASK, \ + PAYLD_SIZE_SHIFT, p_size) + +#define CMI_HDR_GET_PAYLOAD_SIZE(hdr) \ + ((hdr->pld_info >> PAYLD_SIZE_SHIFT) & \ + (PAYLD_SIZE_MASK >> PAYLD_SIZE_SHIFT)) + +#define CMI_HDR_SET_OBM(hdr, obm_flag) \ + CMI_HDR_SET(hdr->pld_info, OBM_FLAG_MASK, \ + OBM_FLAG_SHIFT, obm_flag) + +#define CMI_HDR_GET_OBM_FLAG(hdr) \ + ((hdr->pld_info >> OBM_FLAG_SHIFT) & \ + (OBM_FLAG_MASK >> OBM_FLAG_SHIFT)) + +struct cmi_hdr { + /* + * bits 0:3 is session id + * bits 4:6 is service id + * bit 7 is the version flag + */ + u8 hdr_info; + + /* + * bits 0:6 is payload size in case of in-band message + * bits 0:6 is size (OBM message size) + * bit 7 is the OBM flag + */ + u8 pld_info; + + /* 16 bit command opcode */ + u16 opcode; +} __packed; + +union cpe_addr { + u64 msw_lsw; + void *kvaddr; +} __packed; + +struct cmi_obm { + u32 version; + u32 size; + union cpe_addr data_ptr; + u32 mem_handle; +} __packed; + +struct cmi_obm_msg { + struct cmi_hdr hdr; + struct cmi_obm pld; +} __packed; + +struct cmi_core_svc_event_system_boot { + u8 status; + u8 version; + u16 sfr_buff_size; + u32 sfr_buff_address; +} __packed; + +struct cmi_core_svc_cmd_shared_mem_alloc { + u32 size; +} __packed; + +struct cmi_core_svc_cmdrsp_shared_mem_alloc { + u32 addr; +} __packed; + +struct cmi_core_svc_cmd_clk_freq_request { + u32 clk_freq; +} __packed; + +struct cmi_msg_transport { + u32 size; + u32 addr; +} __packed; + +struct cmi_basic_rsp_result { + u8 status; +} __packed; + +struct cpe_lsm_cmd_open_tx { + struct cmi_hdr hdr; + u16 app_id; + u16 reserved; + u32 sampling_rate; +} __packed; + +struct cpe_lsm_cmd_open_tx_v2 { + struct cmi_hdr hdr; + u32 topology_id; +} __packed; + +struct cpe_cmd_shmem_alloc { + struct cmi_hdr hdr; + u32 size; +} __packed; + +struct cpe_cmdrsp_shmem_alloc { + struct cmi_hdr hdr; + u32 addr; +} __packed; + +struct cpe_cmd_shmem_dealloc { + struct cmi_hdr hdr; + u32 addr; +} __packed; + +struct cpe_lsm_event_detect_v2 { + struct cmi_hdr hdr; + u8 detection_status; + u8 size; + u8 payload[0]; +} __packed; + +struct cpe_lsm_psize_res { + u16 param_size; + u16 reserved; +} __packed; + +union cpe_lsm_param_size { + u32 param_size; + struct cpe_lsm_psize_res sr; +} __packed; + +struct cpe_param_data { + u32 module_id; + u32 param_id; + union cpe_lsm_param_size p_size; +} __packed; + +struct cpe_lsm_param_epd_thres { + struct cmi_hdr hdr; + struct cpe_param_data param; + u32 minor_version; + u32 epd_begin; + u32 epd_end; +} __packed; + +struct cpe_lsm_param_gain { + struct cmi_hdr hdr; + struct cpe_param_data param; + u32 minor_version; + u16 gain; + u16 reserved; +} __packed; + +struct cpe_afe_hw_mad_ctrl { + struct cpe_param_data param; + u32 minor_version; + u16 mad_type; + u16 mad_enable; +} __packed; + +struct cpe_afe_port_cfg { + struct cpe_param_data param; + u32 minor_version; + u16 bit_width; + u16 num_channels; + u32 sample_rate; +} __packed; + +struct cpe_afe_cmd_port_cfg { + struct cmi_hdr hdr; + u8 bit_width; + u8 num_channels; + u16 buffer_size; + u32 sample_rate; +} __packed; + +struct cpe_afe_params { + struct cmi_hdr hdr; + struct cpe_afe_hw_mad_ctrl hw_mad_ctrl; + struct cpe_afe_port_cfg port_cfg; +} __packed; + +struct cpe_afe_svc_cmd_mode { + struct cmi_hdr hdr; + u8 mode; +} __packed; + +struct cpe_lsm_param_opmode { + struct cmi_hdr hdr; + struct cpe_param_data param; + u32 minor_version; + u16 mode; + u16 reserved; +} __packed; + +struct cpe_lsm_param_connectport { + struct cmi_hdr hdr; + struct cpe_param_data param; + u32 minor_version; + u16 afe_port_id; + u16 reserved; +} __packed; + +/* + * This cannot be sent to CPE as is, + * need to append the conf_levels dynamically + */ +struct cpe_lsm_conf_level { + struct cmi_hdr hdr; + struct cpe_param_data param; + u8 num_active_models; +} __packed; + +struct cpe_lsm_output_format_cfg { + struct cmi_hdr hdr; + u8 format; + u8 packing; + u8 data_path_events; +} __packed; + +struct cpe_lsm_lab_enable { + struct cpe_param_data param; + u16 enable; + u16 reserved; +} __packed; + +struct cpe_lsm_control_lab { + struct cmi_hdr hdr; + struct cpe_lsm_lab_enable lab_enable; +} __packed; + +struct cpe_lsm_lab_config { + struct cpe_param_data param; + u32 minor_ver; + u32 latency; +} __packed; + +struct cpe_lsm_lab_latency_config { + struct cmi_hdr hdr; + struct cpe_lsm_lab_config latency_cfg; +} __packed; + +struct cpe_lsm_media_fmt_param { + struct cmi_hdr hdr; + struct cpe_param_data param; + u32 minor_version; + u32 sample_rate; + u16 num_channels; + u16 bit_width; +} __packed; + + +#define CPE_PARAM_LSM_LAB_LATENCY_SIZE (\ + sizeof(struct cpe_lsm_lab_latency_config) - \ + sizeof(struct cmi_hdr)) +#define PARAM_SIZE_LSM_LATENCY_SIZE (\ + sizeof(struct cpe_lsm_lab_config) - \ + sizeof(struct cpe_param_data)) +#define CPE_PARAM_SIZE_LSM_LAB_CONTROL (\ + sizeof(struct cpe_lsm_control_lab) - \ + sizeof(struct cmi_hdr)) +#define PARAM_SIZE_LSM_CONTROL_SIZE (sizeof(struct cpe_lsm_lab_enable) - \ + sizeof(struct cpe_param_data)) +#define PARAM_SIZE_AFE_HW_MAD_CTRL (sizeof(struct cpe_afe_hw_mad_ctrl) - \ + sizeof(struct cpe_param_data)) +#define PARAM_SIZE_AFE_PORT_CFG (sizeof(struct cpe_afe_port_cfg) - \ + sizeof(struct cpe_param_data)) +#define CPE_AFE_PARAM_PAYLOAD_SIZE (sizeof(struct cpe_afe_params) - \ + sizeof(struct cmi_hdr)) + +#define OPEN_CMD_PAYLOAD_SIZE (sizeof(struct cpe_lsm_cmd_open_tx) - \ + sizeof(struct cmi_hdr)) +#define OPEN_V2_CMD_PAYLOAD_SIZE (sizeof(struct cpe_lsm_cmd_open_tx_v2) - \ + sizeof(struct cmi_hdr)) +#define SHMEM_ALLOC_CMD_PLD_SIZE (sizeof(struct cpe_cmd_shmem_alloc) - \ + sizeof(struct cmi_hdr)) + +#define SHMEM_DEALLOC_CMD_PLD_SIZE (sizeof(struct cpe_cmd_shmem_dealloc) - \ + sizeof(struct cmi_hdr)) +#define OUT_FMT_CFG_CMD_PAYLOAD_SIZE ( \ + sizeof(struct cpe_lsm_output_format_cfg) - \ + sizeof(struct cmi_hdr)) + +#define CPE_AFE_CMD_PORT_CFG_PAYLOAD_SIZE \ + (sizeof(struct cpe_afe_cmd_port_cfg) - \ + sizeof(struct cmi_hdr)) + +#define CPE_AFE_CMD_MODE_PAYLOAD_SIZE \ + (sizeof(struct cpe_afe_svc_cmd_mode) - \ + sizeof(struct cmi_hdr)) +#define CPE_CMD_EPD_THRES_PLD_SIZE (sizeof(struct cpe_lsm_param_epd_thres) - \ + sizeof(struct cmi_hdr)) +#define CPE_EPD_THRES_PARAM_SIZE ((CPE_CMD_EPD_THRES_PLD_SIZE) - \ + sizeof(struct cpe_param_data)) +#define CPE_CMD_OPMODE_PLD_SIZE (sizeof(struct cpe_lsm_param_opmode) - \ + sizeof(struct cmi_hdr)) +#define CPE_OPMODE_PARAM_SIZE ((CPE_CMD_OPMODE_PLD_SIZE) -\ + sizeof(struct cpe_param_data)) +#define CPE_CMD_CONNECTPORT_PLD_SIZE \ + (sizeof(struct cpe_lsm_param_connectport) - \ + sizeof(struct cmi_hdr)) +#define CPE_CONNECTPORT_PARAM_SIZE ((CPE_CMD_CONNECTPORT_PLD_SIZE) - \ + sizeof(struct cpe_param_data)) +#define CPE_CMD_GAIN_PLD_SIZE (sizeof(struct cpe_lsm_param_gain) - \ + sizeof(struct cmi_hdr)) +#define CPE_GAIN_PARAM_SIZE ((CPE_CMD_GAIN_PLD_SIZE) - \ + sizeof(struct cpe_param_data)) +#define CPE_MEDIA_FMT_PLD_SIZE (sizeof(struct cpe_lsm_media_fmt_param) - \ + sizeof(struct cmi_hdr)) +#define CPE_MEDIA_FMT_PARAM_SIZE ((CPE_MEDIA_FMT_PLD_SIZE) - \ + sizeof(struct cpe_param_data)) +#endif /* __CPE_CMI_H__ */ diff --git a/include/sound/cpe_core.h b/include/sound/cpe_core.h new file mode 100644 index 000000000000..9f7c2f31ff0d --- /dev/null +++ b/include/sound/cpe_core.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __CPE_CORE_H__ +#define __CPE_CORE_H__ + +#include +#include +#include +#include + +enum { + CMD_INIT_STATE = 0, + CMD_SENT, + CMD_RESP_RCVD, +}; + +enum wcd_cpe_event { + WCD_CPE_PRE_ENABLE = 1, + WCD_CPE_POST_ENABLE, + WCD_CPE_PRE_DISABLE, + WCD_CPE_POST_DISABLE, +}; + +struct wcd_cpe_afe_port_cfg { + u8 port_id; + u16 bit_width; + u16 num_channels; + u32 sample_rate; +}; + +struct lsm_out_fmt_cfg { + u8 format; + u8 pack_mode; + u8 data_path_events; + u8 transfer_mode; +}; + +struct lsm_hw_params { + u32 sample_rate; + u16 num_chs; + u16 bit_width; +}; + +struct cpe_lsm_session { + /* sound model related */ + void *snd_model_data; + u8 *conf_levels; + void *cmi_reg_handle; + + /* Clients private data */ + void *priv_d; + + void (*event_cb)(void *priv_data, + u8 detect_status, + u8 size, u8 *payload); + + struct completion cmd_comp; + struct wcd_cpe_afe_port_cfg afe_port_cfg; + struct wcd_cpe_afe_port_cfg afe_out_port_cfg; + struct mutex lsm_lock; + + u32 snd_model_size; + u32 lsm_mem_handle; + u16 cmd_err_code; + u8 id; + u8 num_confidence_levels; + u16 afe_out_port_id; + struct task_struct *lsm_lab_thread; + bool started; + + u32 lab_enable; + struct lsm_out_fmt_cfg out_fmt_cfg; + + bool is_topology_used; +}; + +struct wcd_cpe_afe_ops { + int (*afe_set_params)(void *core_handle, + struct wcd_cpe_afe_port_cfg *cfg, + bool afe_mad_ctl); + + int (*afe_port_start)(void *core_handle, + struct wcd_cpe_afe_port_cfg *cfg); + + int (*afe_port_stop)(void *core_handle, + struct wcd_cpe_afe_port_cfg *cfg); + + int (*afe_port_suspend)(void *core_handle, + struct wcd_cpe_afe_port_cfg *cfg); + + int (*afe_port_resume)(void *core_handle, + struct wcd_cpe_afe_port_cfg *cfg); + + int (*afe_port_cmd_cfg)(void *core_handle, + struct wcd_cpe_afe_port_cfg *cfg); +}; + +struct wcd_cpe_lsm_ops { + + struct cpe_lsm_session *(*lsm_alloc_session) + (void *core_handle, void *lsm_priv_d, + void (*event_cb)(void *priv_data, + u8 detect_status, + u8 size, u8 *payload)); + + int (*lsm_dealloc_session) + (void *core_handle, struct cpe_lsm_session *); + + int (*lsm_open_tx)(void *core_handle, + struct cpe_lsm_session *, u16, u16); + + int (*lsm_close_tx)(void *core_handle, + struct cpe_lsm_session *); + + int (*lsm_shmem_alloc)(void *core_handle, + struct cpe_lsm_session *, u32 size); + + int (*lsm_shmem_dealloc)(void *core_handle, + struct cpe_lsm_session *); + + int (*lsm_register_snd_model)(void *core_handle, + struct cpe_lsm_session *, + enum lsm_detection_mode, bool); + + int (*lsm_deregister_snd_model)(void *core_handle, + struct cpe_lsm_session *); + + int (*lsm_get_afe_out_port_id)(void *core_handle, + struct cpe_lsm_session *session); + + int (*lsm_start)(void *core_handle, + struct cpe_lsm_session *); + + int (*lsm_stop)(void *core_handle, + struct cpe_lsm_session *); + + int (*lsm_lab_control)(void *core_handle, + struct cpe_lsm_session *session, + bool enable); + + int (*lab_ch_setup)(void *core_handle, + struct cpe_lsm_session *session, + enum wcd_cpe_event event); + + int (*lsm_set_data)(void *core_handle, + struct cpe_lsm_session *session, + enum lsm_detection_mode detect_mode, + bool detect_failure); + int (*lsm_set_fmt_cfg)(void *core_handle, + struct cpe_lsm_session *session); + int (*lsm_set_one_param)(void *core_handle, + struct cpe_lsm_session *session, + struct lsm_params_info *p_info, + void *data, uint32_t param_type); + void (*lsm_get_snd_model_offset) + (void *core_handle, struct cpe_lsm_session *, + size_t *offset); + int (*lsm_set_media_fmt_params)(void *core_handle, + struct cpe_lsm_session *session, + struct lsm_hw_params *param); + int (*lsm_set_port)(void *core_handle, + struct cpe_lsm_session *session, void *data); +}; + +int wcd_cpe_get_lsm_ops(struct wcd_cpe_lsm_ops *lsm_ops); +int wcd_cpe_get_afe_ops(struct wcd_cpe_afe_ops *afe_ops); +void *wcd_cpe_get_core_handle(struct snd_soc_codec *codec); +#endif diff --git a/include/sound/cpe_err.h b/include/sound/cpe_err.h new file mode 100644 index 000000000000..b70dc490fb1a --- /dev/null +++ b/include/sound/cpe_err.h @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2015, 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __CPE_ERR__ +#define __CPE_ERR__ + +#include + +/* ERROR CODES */ +/* Success. The operation completed with no errors. */ +#define CPE_EOK 0x00000000 +/* General failure. */ +#define CPE_EFAILED 0x00000001 +/* Bad operation parameter. */ +#define CPE_EBADPARAM 0x00000002 +/* Unsupported routine or operation. */ +#define CPE_EUNSUPPORTED 0x00000003 +/* Unsupported version. */ +#define CPE_EVERSION 0x00000004 +/* Unexpected problem encountered. */ +#define CPE_EUNEXPECTED 0x00000005 +/* Unhandled problem occurred. */ +#define CPE_EPANIC 0x00000006 +/* Unable to allocate resource. */ +#define CPE_ENORESOURCE 0x00000007 +/* Invalid handle. */ +#define CPE_EHANDLE 0x00000008 +/* Operation is already processed. */ +#define CPE_EALREADY 0x00000009 +/* Operation is not ready to be processed. */ +#define CPE_ENOTREADY 0x0000000A +/* Operation is pending completion. */ +#define CPE_EPENDING 0x0000000B +/* Operation could not be accepted or processed. */ +#define CPE_EBUSY 0x0000000C +/* Operation aborted due to an error. */ +#define CPE_EABORTED 0x0000000D +/* Operation preempted by a higher priority. */ +#define CPE_EPREEMPTED 0x0000000E +/* Operation requests intervention to complete. */ +#define CPE_ECONTINUE 0x0000000F +/* Operation requests immediate intervention to complete. */ +#define CPE_EIMMEDIATE 0x00000010 +/* Operation is not implemented. */ +#define CPE_ENOTIMPL 0x00000011 +/* Operation needs more data or resources. */ +#define CPE_ENEEDMORE 0x00000012 +/* Operation does not have memory. */ +#define CPE_ENOMEMORY 0x00000014 +/* Item does not exist. */ +#define CPE_ENOTEXIST 0x00000015 +/* Operation is finished. */ +#define CPE_ETERMINATED 0x00000016 +/* Max count for adsp error code sent to HLOS*/ +#define CPE_ERR_MAX (CPE_ETERMINATED + 1) + + +/* ERROR STRING */ +/* Success. The operation completed with no errors. */ +#define CPE_EOK_STR "CPE_EOK" +/* General failure. */ +#define CPE_EFAILED_STR "CPE_EFAILED" +/* Bad operation parameter. */ +#define CPE_EBADPARAM_STR "CPE_EBADPARAM" +/* Unsupported routine or operation. */ +#define CPE_EUNSUPPORTED_STR "CPE_EUNSUPPORTED" +/* Unsupported version. */ +#define CPE_EVERSION_STR "CPE_EVERSION" +/* Unexpected problem encountered. */ +#define CPE_EUNEXPECTED_STR "CPE_EUNEXPECTED" +/* Unhandled problem occurred. */ +#define CPE_EPANIC_STR "CPE_EPANIC" +/* Unable to allocate resource. */ +#define CPE_ENORESOURCE_STR "CPE_ENORESOURCE" +/* Invalid handle. */ +#define CPE_EHANDLE_STR "CPE_EHANDLE" +/* Operation is already processed. */ +#define CPE_EALREADY_STR "CPE_EALREADY" +/* Operation is not ready to be processed. */ +#define CPE_ENOTREADY_STR "CPE_ENOTREADY" +/* Operation is pending completion. */ +#define CPE_EPENDING_STR "CPE_EPENDING" +/* Operation could not be accepted or processed. */ +#define CPE_EBUSY_STR "CPE_EBUSY" +/* Operation aborted due to an error. */ +#define CPE_EABORTED_STR "CPE_EABORTED" +/* Operation preempted by a higher priority. */ +#define CPE_EPREEMPTED_STR "CPE_EPREEMPTED" +/* Operation requests intervention to complete. */ +#define CPE_ECONTINUE_STR "CPE_ECONTINUE" +/* Operation requests immediate intervention to complete. */ +#define CPE_EIMMEDIATE_STR "CPE_EIMMEDIATE" +/* Operation is not implemented. */ +#define CPE_ENOTIMPL_STR "CPE_ENOTIMPL" +/* Operation needs more data or resources. */ +#define CPE_ENEEDMORE_STR "CPE_ENEEDMORE" +/* Operation does not have memory. */ +#define CPE_ENOMEMORY_STR "CPE_ENOMEMORY" +/* Item does not exist. */ +#define CPE_ENOTEXIST_STR "CPE_ENOTEXIST" +/* Operation is finished. */ +#define CPE_ETERMINATED_STR "CPE_ETERMINATED" +/* Unexpected error code. */ +#define CPE_ERR_MAX_STR "CPE_ERR_MAX" + + +struct cpe_err_code { + int lnx_err_code; + char *cpe_err_str; +}; + + +static struct cpe_err_code cpe_err_code_info[CPE_ERR_MAX+1] = { + { 0, CPE_EOK_STR}, + { -ENOTRECOVERABLE, CPE_EFAILED_STR}, + { -EINVAL, CPE_EBADPARAM_STR}, + { -EOPNOTSUPP, CPE_EUNSUPPORTED_STR}, + { -ENOPROTOOPT, CPE_EVERSION_STR}, + { -ENOTRECOVERABLE, CPE_EUNEXPECTED_STR}, + { -ENOTRECOVERABLE, CPE_EPANIC_STR}, + { -ENOSPC, CPE_ENORESOURCE_STR}, + { -EBADR, CPE_EHANDLE_STR}, + { -EALREADY, CPE_EALREADY_STR}, + { -EPERM, CPE_ENOTREADY_STR}, + { -EINPROGRESS, CPE_EPENDING_STR}, + { -EBUSY, CPE_EBUSY_STR}, + { -ECANCELED, CPE_EABORTED_STR}, + { -EAGAIN, CPE_EPREEMPTED_STR}, + { -EAGAIN, CPE_ECONTINUE_STR}, + { -EAGAIN, CPE_EIMMEDIATE_STR}, + { -EAGAIN, CPE_ENOTIMPL_STR}, + { -ENODATA, CPE_ENEEDMORE_STR}, + { -EADV, CPE_ERR_MAX_STR}, + { -ENOMEM, CPE_ENOMEMORY_STR}, + { -ENODEV, CPE_ENOTEXIST_STR}, + { -EADV, CPE_ETERMINATED_STR}, + { -EADV, CPE_ERR_MAX_STR}, +}; + +static inline int cpe_err_get_lnx_err_code(u32 cpe_error) +{ + if (cpe_error > CPE_ERR_MAX) + return cpe_err_code_info[CPE_ERR_MAX].lnx_err_code; + else + return cpe_err_code_info[cpe_error].lnx_err_code; +} + +static inline char *cpe_err_get_err_str(u32 cpe_error) +{ + if (cpe_error > CPE_ERR_MAX) + return cpe_err_code_info[CPE_ERR_MAX].cpe_err_str; + else + return cpe_err_code_info[cpe_error].cpe_err_str; +} + +#endif diff --git a/include/sound/msm-audio-effects-q6-v2.h b/include/sound/msm-audio-effects-q6-v2.h new file mode 100644 index 000000000000..6bc2338bcf55 --- /dev/null +++ b/include/sound/msm-audio-effects-q6-v2.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _MSM_AUDIO_EFFECTS_H +#define _MSM_AUDIO_EFFECTS_H + +#include + +#define MAX_PP_PARAMS_SZ 128 + +bool msm_audio_effects_is_effmodule_supp_in_top(int effect_module, + int topology); + +int msm_audio_effects_enable_extn(struct audio_client *ac, + struct msm_nt_eff_all_config *effects, + bool flag); + +int msm_audio_effects_reverb_handler(struct audio_client *ac, + struct reverb_params *reverb, + long *values); + +int msm_audio_effects_bass_boost_handler(struct audio_client *ac, + struct bass_boost_params *bass_boost, + long *values); + +int msm_audio_effects_pbe_handler(struct audio_client *ac, + struct pbe_params *pbe, + long *values); + +int msm_audio_effects_virtualizer_handler(struct audio_client *ac, + struct virtualizer_params *virtualizer, + long *values); + +int msm_audio_effects_popless_eq_handler(struct audio_client *ac, + struct eq_params *eq, + long *values); + +int msm_audio_effects_volume_handler(struct audio_client *ac, + struct soft_volume_params *vol, + long *values); + +int msm_audio_effects_volume_handler_v2(struct audio_client *ac, + struct soft_volume_params *vol, + long *values, int instance); +#endif /*_MSM_AUDIO_EFFECTS_H*/ diff --git a/include/sound/msm-dai-q6-v2.h b/include/sound/msm-dai-q6-v2.h new file mode 100644 index 000000000000..b1d76bf73f51 --- /dev/null +++ b/include/sound/msm-dai-q6-v2.h @@ -0,0 +1,92 @@ +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MSM_DAI_Q6_PDATA_H__ + +#define __MSM_DAI_Q6_PDATA_H__ + +#define MSM_MI2S_SD0 (1 << 0) +#define MSM_MI2S_SD1 (1 << 1) +#define MSM_MI2S_SD2 (1 << 2) +#define MSM_MI2S_SD3 (1 << 3) +#define MSM_MI2S_CAP_RX 0 +#define MSM_MI2S_CAP_TX 1 + +#define MSM_PRIM_MI2S 0 +#define MSM_SEC_MI2S 1 +#define MSM_TERT_MI2S 2 +#define MSM_QUAT_MI2S 3 +#define MSM_SEC_MI2S_SD1 4 +#define MSM_QUIN_MI2S 5 +#define MSM_SENARY_MI2S 6 +#define MSM_INT0_MI2S 7 +#define MSM_INT1_MI2S 8 +#define MSM_INT2_MI2S 9 +#define MSM_INT3_MI2S 10 +#define MSM_INT4_MI2S 11 +#define MSM_INT5_MI2S 12 +#define MSM_INT6_MI2S 13 +#define MSM_MI2S_MIN MSM_PRIM_MI2S +#define MSM_MI2S_MAX MSM_INT6_MI2S + +struct msm_dai_auxpcm_config { + u16 mode; + u16 sync; + u16 frame; + u16 quant; + u16 num_slots; + u16 *slot_mapping; + u16 data; + u32 pcm_clk_rate; +}; + +struct msm_dai_auxpcm_pdata { + struct msm_dai_auxpcm_config mode_8k; + struct msm_dai_auxpcm_config mode_16k; +}; + +struct msm_mi2s_pdata { + u16 rx_sd_lines; + u16 tx_sd_lines; + u16 intf_id; +}; + +struct msm_i2s_data { + u32 capability; /* RX or TX */ + u16 sd_lines; +}; + +struct msm_dai_tdm_group_config { + u16 group_id; + u16 num_ports; + u16 *port_id; + u32 clk_rate; +}; + +struct msm_dai_tdm_config { + u16 sync_mode; + u16 sync_src; + u16 data_out; + u16 invert_sync; + u16 data_delay; + u32 data_align; + u16 header_start_offset; + u16 header_width; + u16 header_num_frame_repeat; +}; + +struct msm_dai_tdm_pdata { + struct msm_dai_tdm_group_config group_config; + struct msm_dai_tdm_config config; +}; + +#endif diff --git a/include/sound/msm-slim-dma.h b/include/sound/msm-slim-dma.h new file mode 100644 index 000000000000..daf394bffaff --- /dev/null +++ b/include/sound/msm-slim-dma.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _MSM_SLIMBUS_DMA_H +#define _MSM_SLIMBUS_DMA_H + +#include + +/* + * struct msm_slim_dma_data - DMA data for slimbus data transfer + * + * @sdev: Handle to the slim_device instance associated with the + * data transfer. + * @ph: Port handle for the slimbus ports. + * @dai_channel_ctl: callback function into the CPU dai driver + * to setup the data path. + * + * This structure is used to share the slimbus port handles and + * other data path setup related handles with other drivers. + */ +struct msm_slim_dma_data { + + /* Handle to slimbus device */ + struct slim_device *sdev; + + /* Port Handle */ + u32 ph; + + /* Callback for data channel control */ + int (*dai_channel_ctl)(struct msm_slim_dma_data *dma_data, + struct snd_soc_dai *dai, bool enable); +}; + +#endif diff --git a/include/sound/q6adm-v2.h b/include/sound/q6adm-v2.h new file mode 100644 index 000000000000..e689e9357012 --- /dev/null +++ b/include/sound/q6adm-v2.h @@ -0,0 +1,187 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __Q6_ADM_V2_H__ +#define __Q6_ADM_V2_H__ + + +#define ADM_PATH_PLAYBACK 0x1 +#define ADM_PATH_LIVE_REC 0x2 +#define ADM_PATH_NONLIVE_REC 0x3 +#define ADM_PATH_COMPRESSED_RX 0x5 +#define ADM_PATH_COMPRESSED_TX 0x6 +#include +#include +#include + +#define MAX_MODULES_IN_TOPO 16 +#define ADM_GET_TOPO_MODULE_LIST_LENGTH\ + ((MAX_MODULES_IN_TOPO + 1) * sizeof(uint32_t)) +#define AUD_PROC_BLOCK_SIZE 4096 +#define AUD_VOL_BLOCK_SIZE 4096 +#define AUDIO_RX_CALIBRATION_SIZE (AUD_PROC_BLOCK_SIZE + \ + AUD_VOL_BLOCK_SIZE) +enum { + ADM_CUSTOM_TOP_CAL = 0, + ADM_AUDPROC_CAL, + ADM_AUDVOL_CAL, + ADM_RTAC_INFO_CAL, + ADM_RTAC_APR_CAL, + ADM_SRS_TRUMEDIA, + ADM_RTAC_AUDVOL_CAL, + ADM_MAX_CAL_TYPES +}; + +enum { + ADM_MEM_MAP_INDEX_SOURCE_TRACKING = ADM_MAX_CAL_TYPES, + ADM_MEM_MAP_INDEX_MAX +}; + +enum { + ADM_CLIENT_ID_DEFAULT = 0, + ADM_CLIENT_ID_SOURCE_TRACKING, + ADM_CLIENT_ID_MAX, +}; + +#define MAX_COPPS_PER_PORT 0x8 +#define ADM_MAX_CHANNELS 8 + +/* multiple copp per stream. */ +struct route_payload { + unsigned int copp_idx[MAX_COPPS_PER_PORT]; + unsigned int port_id[MAX_COPPS_PER_PORT]; + int app_type[MAX_COPPS_PER_PORT]; + int acdb_dev_id[MAX_COPPS_PER_PORT]; + int sample_rate[MAX_COPPS_PER_PORT]; + unsigned short num_copps; + unsigned int session_id; +}; + +struct default_chmixer_param_id_coeff { + uint32_t index; + uint16_t num_output_channels; + uint16_t num_input_channels; +}; + +struct msm_pcm_channel_mixer { + int output_channel; + int input_channels[ADM_MAX_CHANNELS]; + bool enable; + int rule; + int channel_weight[ADM_MAX_CHANNELS][ADM_MAX_CHANNELS]; +}; + +int srs_trumedia_open(int port_id, int copp_idx, __s32 srs_tech_id, + void *srs_params); + +int adm_dts_eagle_set(int port_id, int copp_idx, int param_id, + void *data, uint32_t size); + +int adm_dts_eagle_get(int port_id, int copp_idx, int param_id, + void *data, uint32_t size); + +void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate); + +int adm_get_params(int port_id, int copp_idx, uint32_t module_id, + uint32_t param_id, uint32_t params_length, char *params); + +int adm_send_params_v5(int port_id, int copp_idx, char *params, + uint32_t params_length); + +int adm_dolby_dap_send_params(int port_id, int copp_idx, char *params, + uint32_t params_length); + +int adm_open(int port, int path, int rate, int mode, int topology, + int perf_mode, uint16_t bits_per_sample, + int app_type, int acdbdev_id); + +int adm_map_rtac_block(struct rtac_cal_block_data *cal_block); + +int adm_unmap_rtac_block(uint32_t *mem_map_handle); + +int adm_close(int port, int topology, int perf_mode); + +int adm_matrix_map(int path, struct route_payload payload_map, + int perf_mode, uint32_t passthr_mode); + +int adm_connect_afe_port(int mode, int session_id, int port_id); + +void adm_ec_ref_rx_id(int port_id); + +void adm_num_ec_ref_rx_chans(int num_chans); + +void adm_ec_ref_rx_bit_width(int bit_width); + +void adm_ec_ref_rx_sampling_rate(int sampling_rate); + +int adm_get_lowlatency_copp_id(int port_id); + +int adm_set_multi_ch_map(char *channel_map, int path); + +int adm_get_multi_ch_map(char *channel_map, int path); + +int adm_validate_and_get_port_index(int port_id); + +int adm_get_default_copp_idx(int port_id); + +int adm_get_topology_for_port_from_copp_id(int port_id, int copp_id); + +int adm_get_topology_for_port_copp_idx(int port_id, int copp_idx); + +int adm_get_indexes_from_copp_id(int copp_id, int *port_idx, int *copp_idx); + +int adm_set_stereo_to_custom_stereo(int port_id, int copp_idx, + unsigned int session_id, + char *params, uint32_t params_length); + +int adm_get_pp_topo_module_list(int port_id, int copp_idx, int32_t param_length, + char *params); + +int adm_set_volume(int port_id, int copp_idx, int volume); + +int adm_set_softvolume(int port_id, int copp_idx, + struct audproc_softvolume_params *softvol_param); + +int adm_set_mic_gain(int port_id, int copp_idx, int volume); + +int adm_send_set_multichannel_ec_primary_mic_ch(int port_id, int copp_idx, + int primary_mic_ch); + +int adm_param_enable(int port_id, int copp_idx, int module_id, int enable); + +int adm_send_calibration(int port_id, int copp_idx, int path, int perf_mode, + int cal_type, char *params, int size); + +int adm_set_wait_parameters(int port_id, int copp_idx); + +int adm_reset_wait_parameters(int port_id, int copp_idx); + +int adm_wait_timeout(int port_id, int copp_idx, int wait_time); + +int adm_store_cal_data(int port_id, int copp_idx, int path, int perf_mode, + int cal_type, char *params, int *size); + +int adm_send_compressed_device_mute(int port_id, int copp_idx, bool mute_on); + +int adm_send_compressed_device_latency(int port_id, int copp_idx, int latency); +int adm_set_sound_focus(int port_id, int copp_idx, + struct sound_focus_param soundFocusData); +int adm_get_sound_focus(int port_id, int copp_idx, + struct sound_focus_param *soundFocusData); +int adm_get_source_tracking(int port_id, int copp_idx, + struct source_tracking_param *sourceTrackingData); +int adm_swap_speaker_channels(int port_id, int copp_idx, int sample_rate, + bool spk_swap); +int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, + int session_type, + struct msm_pcm_channel_mixer *ch_mixer, + int channel_index); +#endif /* __Q6_ADM_V2_H__ */ diff --git a/include/sound/q6afe-v2.h b/include/sound/q6afe-v2.h new file mode 100644 index 000000000000..836117568d37 --- /dev/null +++ b/include/sound/q6afe-v2.h @@ -0,0 +1,371 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __Q6AFE_V2_H__ +#define __Q6AFE_V2_H__ +#include +#include + +#define IN 0x000 +#define OUT 0x001 +#define MSM_AFE_MONO 0 +#define MSM_AFE_CH_STEREO 1 +#define MSM_AFE_MONO_RIGHT 1 +#define MSM_AFE_MONO_LEFT 2 +#define MSM_AFE_STEREO 3 +#define MSM_AFE_4CHANNELS 4 +#define MSM_AFE_6CHANNELS 6 +#define MSM_AFE_8CHANNELS 8 + +#define MSM_AFE_I2S_FORMAT_LPCM 0 +#define MSM_AFE_I2S_FORMAT_COMPR 1 +#define MSM_AFE_I2S_FORMAT_IEC60958_LPCM 2 +#define MSM_AFE_I2S_FORMAT_IEC60958_COMPR 3 + +#define MSM_AFE_PORT_TYPE_RX 0 +#define MSM_AFE_PORT_TYPE_TX 1 + +#define RT_PROXY_DAI_001_RX 0xE0 +#define RT_PROXY_DAI_001_TX 0xF0 +#define RT_PROXY_DAI_002_RX 0xF1 +#define RT_PROXY_DAI_002_TX 0xE1 +#define VIRTUAL_ID_TO_PORTID(val) ((val & 0xF) | 0x2000) + +#define AFE_CLK_VERSION_V1 1 +#define AFE_CLK_VERSION_V2 2 + +typedef int (*routing_cb)(int port); + +enum { + /* IDX 0->4 */ + IDX_PRIMARY_I2S_RX, + IDX_PRIMARY_I2S_TX, + IDX_AFE_PORT_ID_PRIMARY_PCM_RX, + IDX_AFE_PORT_ID_PRIMARY_PCM_TX, + IDX_SECONDARY_I2S_RX, + /* IDX 5->9 */ + IDX_SECONDARY_I2S_TX, + IDX_MI2S_RX, + IDX_MI2S_TX, + IDX_HDMI_RX, + IDX_RSVD_2, + /* IDX 10->14 */ + IDX_RSVD_3, + IDX_DIGI_MIC_TX, + IDX_VOICE_RECORD_RX, + IDX_VOICE_RECORD_TX, + IDX_VOICE_PLAYBACK_TX, + /* IDX 15->19 */ + IDX_SLIMBUS_0_RX, + IDX_SLIMBUS_0_TX, + IDX_SLIMBUS_1_RX, + IDX_SLIMBUS_1_TX, + IDX_SLIMBUS_2_RX, + /* IDX 20->24 */ + IDX_SLIMBUS_2_TX, + IDX_SLIMBUS_3_RX, + IDX_SLIMBUS_3_TX, + IDX_SLIMBUS_4_RX, + IDX_SLIMBUS_4_TX, + /* IDX 25->29 */ + IDX_SLIMBUS_5_RX, + IDX_SLIMBUS_5_TX, + IDX_INT_BT_SCO_RX, + IDX_INT_BT_SCO_TX, + IDX_INT_BT_A2DP_RX, + /* IDX 30->34 */ + IDX_INT_FM_RX, + IDX_INT_FM_TX, + IDX_RT_PROXY_PORT_001_RX, + IDX_RT_PROXY_PORT_001_TX, + IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX, + /* IDX 35->39 */ + IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX, + IDX_AFE_PORT_ID_SECONDARY_MI2S_RX, + IDX_AFE_PORT_ID_SECONDARY_MI2S_TX, + IDX_AFE_PORT_ID_TERTIARY_MI2S_RX, + IDX_AFE_PORT_ID_TERTIARY_MI2S_TX, + /* IDX 40->44 */ + IDX_AFE_PORT_ID_PRIMARY_MI2S_RX, + IDX_AFE_PORT_ID_PRIMARY_MI2S_TX, + IDX_AFE_PORT_ID_SECONDARY_PCM_RX, + IDX_AFE_PORT_ID_SECONDARY_PCM_TX, + IDX_VOICE2_PLAYBACK_TX, + /* IDX 45->49 */ + IDX_SLIMBUS_6_RX, + IDX_SLIMBUS_6_TX, + IDX_SPDIF_RX, + IDX_GLOBAL_CFG, + IDX_AUDIO_PORT_ID_I2S_RX, + /* IDX 50->53 */ + IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_SD1, + IDX_AFE_PORT_ID_QUINARY_MI2S_RX, + IDX_AFE_PORT_ID_QUINARY_MI2S_TX, + IDX_AFE_PORT_ID_SENARY_MI2S_TX, + /* IDX 54->117 */ + IDX_AFE_PORT_ID_PRIMARY_TDM_RX_0, + IDX_AFE_PORT_ID_PRIMARY_TDM_TX_0, + IDX_AFE_PORT_ID_PRIMARY_TDM_RX_1, + IDX_AFE_PORT_ID_PRIMARY_TDM_TX_1, + IDX_AFE_PORT_ID_PRIMARY_TDM_RX_2, + IDX_AFE_PORT_ID_PRIMARY_TDM_TX_2, + IDX_AFE_PORT_ID_PRIMARY_TDM_RX_3, + IDX_AFE_PORT_ID_PRIMARY_TDM_TX_3, + IDX_AFE_PORT_ID_PRIMARY_TDM_RX_4, + IDX_AFE_PORT_ID_PRIMARY_TDM_TX_4, + IDX_AFE_PORT_ID_PRIMARY_TDM_RX_5, + IDX_AFE_PORT_ID_PRIMARY_TDM_TX_5, + IDX_AFE_PORT_ID_PRIMARY_TDM_RX_6, + IDX_AFE_PORT_ID_PRIMARY_TDM_TX_6, + IDX_AFE_PORT_ID_PRIMARY_TDM_RX_7, + IDX_AFE_PORT_ID_PRIMARY_TDM_TX_7, + IDX_AFE_PORT_ID_SECONDARY_TDM_RX_0, + IDX_AFE_PORT_ID_SECONDARY_TDM_TX_0, + IDX_AFE_PORT_ID_SECONDARY_TDM_RX_1, + IDX_AFE_PORT_ID_SECONDARY_TDM_TX_1, + IDX_AFE_PORT_ID_SECONDARY_TDM_RX_2, + IDX_AFE_PORT_ID_SECONDARY_TDM_TX_2, + IDX_AFE_PORT_ID_SECONDARY_TDM_RX_3, + IDX_AFE_PORT_ID_SECONDARY_TDM_TX_3, + IDX_AFE_PORT_ID_SECONDARY_TDM_RX_4, + IDX_AFE_PORT_ID_SECONDARY_TDM_TX_4, + IDX_AFE_PORT_ID_SECONDARY_TDM_RX_5, + IDX_AFE_PORT_ID_SECONDARY_TDM_TX_5, + IDX_AFE_PORT_ID_SECONDARY_TDM_RX_6, + IDX_AFE_PORT_ID_SECONDARY_TDM_TX_6, + IDX_AFE_PORT_ID_SECONDARY_TDM_RX_7, + IDX_AFE_PORT_ID_SECONDARY_TDM_TX_7, + IDX_AFE_PORT_ID_TERTIARY_TDM_RX_0, + IDX_AFE_PORT_ID_TERTIARY_TDM_TX_0, + IDX_AFE_PORT_ID_TERTIARY_TDM_RX_1, + IDX_AFE_PORT_ID_TERTIARY_TDM_TX_1, + IDX_AFE_PORT_ID_TERTIARY_TDM_RX_2, + IDX_AFE_PORT_ID_TERTIARY_TDM_TX_2, + IDX_AFE_PORT_ID_TERTIARY_TDM_RX_3, + IDX_AFE_PORT_ID_TERTIARY_TDM_TX_3, + IDX_AFE_PORT_ID_TERTIARY_TDM_RX_4, + IDX_AFE_PORT_ID_TERTIARY_TDM_TX_4, + IDX_AFE_PORT_ID_TERTIARY_TDM_RX_5, + IDX_AFE_PORT_ID_TERTIARY_TDM_TX_5, + IDX_AFE_PORT_ID_TERTIARY_TDM_RX_6, + IDX_AFE_PORT_ID_TERTIARY_TDM_TX_6, + IDX_AFE_PORT_ID_TERTIARY_TDM_RX_7, + IDX_AFE_PORT_ID_TERTIARY_TDM_TX_7, + IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_0, + IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_0, + IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_1, + IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_1, + IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_2, + IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_2, + IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_3, + IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_3, + IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_4, + IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_4, + IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_5, + IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_5, + IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_6, + IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_6, + IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_7, + IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_7, + /* IDX 118->121 */ + IDX_SLIMBUS_7_RX, + IDX_SLIMBUS_7_TX, + IDX_SLIMBUS_8_RX, + IDX_SLIMBUS_8_TX, + /* IDX 122-> 123 */ + IDX_AFE_PORT_ID_USB_RX, + IDX_AFE_PORT_ID_USB_TX, + /* IDX 124 */ + IDX_DISPLAY_PORT_RX, + /* IDX 125-> 128 */ + IDX_AFE_PORT_ID_TERTIARY_PCM_RX, + IDX_AFE_PORT_ID_TERTIARY_PCM_TX, + IDX_AFE_PORT_ID_QUATERNARY_PCM_RX, + IDX_AFE_PORT_ID_QUATERNARY_PCM_TX, + /* IDX 129-> 142 */ + IDX_AFE_PORT_ID_INT0_MI2S_RX, + IDX_AFE_PORT_ID_INT0_MI2S_TX, + IDX_AFE_PORT_ID_INT1_MI2S_RX, + IDX_AFE_PORT_ID_INT1_MI2S_TX, + IDX_AFE_PORT_ID_INT2_MI2S_RX, + IDX_AFE_PORT_ID_INT2_MI2S_TX, + IDX_AFE_PORT_ID_INT3_MI2S_RX, + IDX_AFE_PORT_ID_INT3_MI2S_TX, + IDX_AFE_PORT_ID_INT4_MI2S_RX, + IDX_AFE_PORT_ID_INT4_MI2S_TX, + IDX_AFE_PORT_ID_INT5_MI2S_RX, + IDX_AFE_PORT_ID_INT5_MI2S_TX, + IDX_AFE_PORT_ID_INT6_MI2S_RX, + IDX_AFE_PORT_ID_INT6_MI2S_TX, + AFE_MAX_PORTS +}; + +enum afe_mad_type { + MAD_HW_NONE = 0x00, + MAD_HW_AUDIO = 0x01, + MAD_HW_BEACON = 0x02, + MAD_HW_ULTRASOUND = 0x04, + MAD_SW_AUDIO = 0x05, +}; + +enum afe_cal_mode { + AFE_CAL_MODE_DEFAULT = 0x00, + AFE_CAL_MODE_NONE, +}; + +struct afe_audio_buffer { + dma_addr_t phys; + void *data; + uint32_t used; + uint32_t size;/* size of buffer */ + uint32_t actual_size; /* actual number of bytes read by DSP */ + struct ion_handle *handle; + struct ion_client *client; +}; + +struct afe_audio_port_data { + struct afe_audio_buffer *buf; + uint32_t max_buf_cnt; + uint32_t dsp_buf; + uint32_t cpu_buf; + struct list_head mem_map_handle; + uint32_t tmp_hdl; + /* read or write locks */ + struct mutex lock; + spinlock_t dsp_lock; +}; + +struct afe_audio_client { + atomic_t cmd_state; + /* Relative or absolute TS */ + uint32_t time_flag; + void *priv; + uint64_t time_stamp; + struct mutex cmd_lock; + /* idx:1 out port, 0: in port*/ + struct afe_audio_port_data port[2]; + wait_queue_head_t cmd_wait; + uint32_t mem_map_handle; +}; + +struct aanc_data { + bool aanc_active; + uint16_t aanc_rx_port; + uint16_t aanc_tx_port; + uint32_t aanc_rx_port_sample_rate; + uint32_t aanc_tx_port_sample_rate; +}; + +int afe_open(u16 port_id, union afe_port_config *afe_config, int rate); +int afe_close(int port_id); +int afe_loopback(u16 enable, u16 rx_port, u16 tx_port); +int afe_sidetone_enable(u16 tx_port_id, u16 rx_port_id, bool enable); +int afe_loopback_gain(u16 port_id, u16 volume); +int afe_validate_port(u16 port_id); +int afe_get_port_index(u16 port_id); +int afe_get_topology(int port_id); +int afe_start_pseudo_port(u16 port_id); +int afe_stop_pseudo_port(u16 port_id); +uint32_t afe_req_mmap_handle(struct afe_audio_client *ac); +int afe_memory_map(phys_addr_t dma_addr_p, u32 dma_buf_sz, + struct afe_audio_client *ac); +int afe_cmd_memory_map(phys_addr_t dma_addr_p, u32 dma_buf_sz); +int afe_cmd_memory_map_nowait(int port_id, phys_addr_t dma_addr_p, + u32 dma_buf_sz); +int afe_cmd_memory_unmap(u32 dma_addr_p); +int afe_cmd_memory_unmap_nowait(u32 dma_addr_p); +void afe_set_dtmf_gen_rx_portid(u16 rx_port_id, int set); +int afe_dtmf_generate_rx(int64_t duration_in_ms, + uint16_t high_freq, + uint16_t low_freq, uint16_t gain); +int afe_register_get_events(u16 port_id, + void (*cb)(uint32_t opcode, + uint32_t token, uint32_t *payload, void *priv), + void *private_data); +int afe_unregister_get_events(u16 port_id); +int afe_rt_proxy_port_write(phys_addr_t buf_addr_p, + u32 mem_map_handle, int bytes); +int afe_rt_proxy_port_read(phys_addr_t buf_addr_p, + u32 mem_map_handle, int bytes); +void afe_set_cal_mode(u16 port_id, enum afe_cal_mode afe_cal_mode); +int afe_port_start(u16 port_id, union afe_port_config *afe_config, + u32 rate); +int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, + u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, + struct afe_enc_config *enc_config); +int afe_spk_prot_feed_back_cfg(int src_port, int dst_port, + int l_ch, int r_ch, u32 enable); +int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib); +int afe_port_stop_nowait(int port_id); +int afe_apply_gain(u16 port_id, u16 gain); +int afe_q6_interface_prepare(void); +int afe_get_port_type(u16 port_id); +int q6afe_audio_client_buf_alloc_contiguous(unsigned int dir, + struct afe_audio_client *ac, + unsigned int bufsz, + unsigned int bufcnt); +struct afe_audio_client *q6afe_audio_client_alloc(void *priv); +int q6afe_audio_client_buf_free_contiguous(unsigned int dir, + struct afe_audio_client *ac); +void q6afe_audio_client_free(struct afe_audio_client *ac); +/* if port_id is virtual, convert to physical.. + * if port_id is already physical, return physical + */ +int afe_convert_virtual_to_portid(u16 port_id); + +int afe_pseudo_port_start_nowait(u16 port_id); +int afe_pseudo_port_stop_nowait(u16 port_id); +int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg); +int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg); +int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg); +int afe_set_digital_codec_core_clock(u16 port_id, + struct afe_digital_clk_cfg *cfg); +int afe_set_lpass_internal_digital_codec_clock(u16 port_id, + struct afe_digital_clk_cfg *cfg); +int afe_enable_lpass_core_shared_clock(u16 port_id, u32 enable); + +int q6afe_check_osr_clk_freq(u32 freq); + +int afe_send_spdif_clk_cfg(struct afe_param_id_spdif_clk_cfg *cfg, + u16 port_id); +int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg + *ch_status_cfg, u16 port_id); + +int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port, + u32 rate); + +int afe_turn_onoff_hw_mad(u16 mad_type, u16 mad_enable); +int afe_port_set_mad_type(u16 port_id, enum afe_mad_type mad_type); +enum afe_mad_type afe_port_get_mad_type(u16 port_id); +int afe_set_config(enum afe_config_type config_type, void *config_data, + int arg); +void afe_clear_config(enum afe_config_type config); +bool afe_has_config(enum afe_config_type config); + +void afe_set_aanc_info(struct aanc_data *aanc_info); +int afe_port_group_set_param(u16 group_id, + union afe_port_group_config *afe_group_config); +int afe_port_group_enable(u16 group_id, + union afe_port_group_config *afe_group_config, u16 enable); +int afe_unmap_rtac_block(uint32_t *mem_map_handle); +int afe_map_rtac_block(struct rtac_cal_block_data *cal_block); +int afe_send_slot_mapping_cfg( + struct afe_param_id_slot_mapping_cfg *slot_mapping_cfg, + u16 port_id); +int afe_send_custom_tdm_header_cfg( + struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header_cfg, + u16 port_id); +int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, + u32 rate, u16 num_groups); +void afe_set_routing_callback(routing_cb cb); +int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats, + u16 port); +#endif /* __Q6AFE_V2_H__ */ diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h new file mode 100644 index 000000000000..00b46a598280 --- /dev/null +++ b/include/sound/q6asm-v2.h @@ -0,0 +1,686 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __Q6_ASM_V2_H__ +#define __Q6_ASM_V2_H__ + +#include +#include +#include +#include +#include + +#define IN 0x000 +#define OUT 0x001 +#define CH_MODE_MONO 0x001 +#define CH_MODE_STEREO 0x002 + +#define FORMAT_LINEAR_PCM 0x0000 +#define FORMAT_DTMF 0x0001 +#define FORMAT_ADPCM 0x0002 +#define FORMAT_YADPCM 0x0003 +#define FORMAT_MP3 0x0004 +#define FORMAT_MPEG4_AAC 0x0005 +#define FORMAT_AMRNB 0x0006 +#define FORMAT_AMRWB 0x0007 +#define FORMAT_V13K 0x0008 +#define FORMAT_EVRC 0x0009 +#define FORMAT_EVRCB 0x000a +#define FORMAT_EVRCWB 0x000b +#define FORMAT_MIDI 0x000c +#define FORMAT_SBC 0x000d +#define FORMAT_WMA_V10PRO 0x000e +#define FORMAT_WMA_V9 0x000f +#define FORMAT_AMR_WB_PLUS 0x0010 +#define FORMAT_MPEG4_MULTI_AAC 0x0011 +#define FORMAT_MULTI_CHANNEL_LINEAR_PCM 0x0012 +#define FORMAT_AC3 0x0013 +#define FORMAT_EAC3 0x0014 +#define FORMAT_MP2 0x0015 +#define FORMAT_FLAC 0x0016 +#define FORMAT_ALAC 0x0017 +#define FORMAT_VORBIS 0x0018 +#define FORMAT_APE 0x0019 +#define FORMAT_G711_ALAW_FS 0x001a +#define FORMAT_G711_MLAW_FS 0x001b +#define FORMAT_DTS 0x001c +#define FORMAT_DSD 0x001d +#define FORMAT_APTX 0x001e +#define FORMAT_GEN_COMPR 0x001f +#define FORMAT_TRUEHD 0x0020 +#define FORMAT_IEC61937 0x0021 + +#define ENCDEC_SBCBITRATE 0x0001 +#define ENCDEC_IMMEDIATE_DECODE 0x0002 +#define ENCDEC_CFG_BLK 0x0003 + +#define CMD_PAUSE 0x0001 +#define CMD_FLUSH 0x0002 +#define CMD_EOS 0x0003 +#define CMD_CLOSE 0x0004 +#define CMD_OUT_FLUSH 0x0005 +#define CMD_SUSPEND 0x0006 + +/* bit 0:1 represents priority of stream */ +#define STREAM_PRIORITY_NORMAL 0x0000 +#define STREAM_PRIORITY_LOW 0x0001 +#define STREAM_PRIORITY_HIGH 0x0002 + +/* bit 4 represents META enable of encoded data buffer */ +#define BUFFER_META_ENABLE 0x0010 + +/* bit 5 represents timestamp */ +/* bit 5 - 0 -- ASM_DATA_EVENT_READ_DONE will have relative time-stamp*/ +/* bit 5 - 1 -- ASM_DATA_EVENT_READ_DONE will have absolute time-stamp*/ +#define ABSOLUTE_TIMESTAMP_ENABLE 0x0020 + +/* Enable Sample_Rate/Channel_Mode notification event from Decoder */ +#define SR_CM_NOTIFY_ENABLE 0x0004 + +#define TUN_WRITE_IO_MODE 0x0008 /* tunnel read write mode */ +#define TUN_READ_IO_MODE 0x0004 /* tunnel read write mode */ +#define SYNC_IO_MODE 0x0001 +#define ASYNC_IO_MODE 0x0002 +#define COMPRESSED_IO 0x0040 +#define COMPRESSED_STREAM_IO 0x0080 +#define NT_MODE 0x0400 + +#define NO_TIMESTAMP 0xFF00 +#define SET_TIMESTAMP 0x0000 + +#define SOFT_PAUSE_ENABLE 1 +#define SOFT_PAUSE_DISABLE 0 + +#define ASM_ACTIVE_STREAMS_ALLOWED 0x8 +/* Control session is used for mapping calibration memory */ +#define ASM_CONTROL_SESSION (ASM_ACTIVE_STREAMS_ALLOWED + 1) + +#define ASM_SHIFT_GAPLESS_MODE_FLAG 31 +#define ASM_SHIFT_LAST_BUFFER_FLAG 30 + +#define ASM_LITTLE_ENDIAN 0 +#define ASM_BIG_ENDIAN 1 + +/* PCM_MEDIA_FORMAT_Version */ +enum { + PCM_MEDIA_FORMAT_V2 = 0, + PCM_MEDIA_FORMAT_V3, + PCM_MEDIA_FORMAT_V4, +}; + +/* PCM format modes in DSP */ +enum { + DEFAULT_QF = 0, + Q15 = 15, + Q23 = 23, + Q31 = 31, +}; + +/* payload structure bytes */ +#define READDONE_IDX_STATUS 0 +#define READDONE_IDX_BUFADD_LSW 1 +#define READDONE_IDX_BUFADD_MSW 2 +#define READDONE_IDX_MEMMAP_HDL 3 +#define READDONE_IDX_SIZE 4 +#define READDONE_IDX_OFFSET 5 +#define READDONE_IDX_LSW_TS 6 +#define READDONE_IDX_MSW_TS 7 +#define READDONE_IDX_FLAGS 8 +#define READDONE_IDX_NUMFRAMES 9 +#define READDONE_IDX_SEQ_ID 10 + +#define SOFT_PAUSE_PERIOD 30 /* ramp up/down for 30ms */ +#define SOFT_PAUSE_STEP 0 /* Step value 0ms or 0us */ +enum { + SOFT_PAUSE_CURVE_LINEAR = 0, + SOFT_PAUSE_CURVE_EXP, + SOFT_PAUSE_CURVE_LOG, +}; + +#define SOFT_VOLUME_PERIOD 30 /* ramp up/down for 30ms */ +#define SOFT_VOLUME_STEP 0 /* Step value 0ms or 0us */ +enum { + SOFT_VOLUME_CURVE_LINEAR = 0, + SOFT_VOLUME_CURVE_EXP, + SOFT_VOLUME_CURVE_LOG, +}; + +#define SOFT_VOLUME_INSTANCE_1 1 +#define SOFT_VOLUME_INSTANCE_2 2 + +typedef void (*app_cb)(uint32_t opcode, uint32_t token, + uint32_t *payload, void *priv); + +struct audio_buffer { + dma_addr_t phys; + void *data; + uint32_t used; + uint32_t size;/* size of buffer */ + uint32_t actual_size; /* actual number of bytes read by DSP */ + struct ion_handle *handle; + struct ion_client *client; +}; + +struct audio_aio_write_param { + phys_addr_t paddr; + uint32_t len; + uint32_t uid; + uint32_t lsw_ts; + uint32_t msw_ts; + uint32_t flags; + uint32_t metadata_len; + uint32_t last_buffer; +}; + +struct audio_aio_read_param { + phys_addr_t paddr; + uint32_t len; + uint32_t uid; + uint32_t flags;/*meta data flags*/ +}; + +struct audio_port_data { + struct audio_buffer *buf; + uint32_t max_buf_cnt; + uint32_t dsp_buf; + uint32_t cpu_buf; + struct list_head mem_map_handle; + uint32_t tmp_hdl; + /* read or write locks */ + struct mutex lock; + spinlock_t dsp_lock; +}; + +struct shared_io_config { + uint32_t format; + uint16_t bits_per_sample; + uint32_t rate; + uint32_t channels; + uint16_t sample_word_size; + uint32_t bufsz; + uint32_t bufcnt; +}; + +struct audio_client { + int session; + app_cb cb; + atomic_t cmd_state; + atomic_t cmd_state_pp; + /* Relative or absolute TS */ + atomic_t time_flag; + atomic_t nowait_cmd_cnt; + atomic_t mem_state; + void *priv; + uint32_t io_mode; + uint64_t time_stamp; + struct apr_svc *apr; + struct apr_svc *mmap_apr; + struct apr_svc *apr2; + struct mutex cmd_lock; + /* idx:1 out port, 0: in port*/ + struct audio_port_data port[2]; + wait_queue_head_t cmd_wait; + wait_queue_head_t time_wait; + wait_queue_head_t mem_wait; + int perf_mode; + int stream_id; + struct device *dev; + int topology; + int app_type; + /* audio cache operations fptr*/ + int (*fptr_cache_ops)(struct audio_buffer *abuff, int cache_op); + atomic_t unmap_cb_success; + atomic_t reset; + /* holds latest DSP pipeline delay */ + uint32_t path_delay; + /* shared io */ + struct audio_buffer shared_pos_buf; + struct shared_io_config config; +}; + +void q6asm_audio_client_free(struct audio_client *ac); + +struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv); + +struct audio_client *q6asm_get_audio_client(int session_id); + +int q6asm_audio_client_buf_alloc(unsigned int dir/* 1:Out,0:In */, + struct audio_client *ac, + unsigned int bufsz, + uint32_t bufcnt); +int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir + /* 1:Out,0:In */, + struct audio_client *ac, + unsigned int bufsz, + unsigned int bufcnt); + +int q6asm_audio_client_buf_free_contiguous(unsigned int dir, + struct audio_client *ac); + +int q6asm_open_read(struct audio_client *ac, uint32_t format + /*, uint16_t bits_per_sample*/); + +int q6asm_open_read_v2(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample); + +int q6asm_open_read_v3(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample); + +int q6asm_open_read_v4(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample, bool ts_mode); + +int q6asm_open_write(struct audio_client *ac, uint32_t format + /*, uint16_t bits_per_sample*/); + +int q6asm_open_write_v2(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample); + +int q6asm_open_shared_io(struct audio_client *ac, + struct shared_io_config *c, int dir); + +int q6asm_open_write_v3(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample); + +int q6asm_open_write_v4(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample); + +int q6asm_stream_open_write_v2(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample, int32_t stream_id, + bool is_gapless_mode); + +int q6asm_stream_open_write_v3(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample, int32_t stream_id, + bool is_gapless_mode); + +int q6asm_stream_open_write_v4(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample, int32_t stream_id, + bool is_gapless_mode); + +int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format, + uint32_t passthrough_flag); + +int q6asm_open_read_write(struct audio_client *ac, + uint32_t rd_format, + uint32_t wr_format); + +int q6asm_open_read_write_v2(struct audio_client *ac, uint32_t rd_format, + uint32_t wr_format, bool is_meta_data_mode, + uint32_t bits_per_sample, bool overwrite_topology, + int topology); + +int q6asm_open_loopback_v2(struct audio_client *ac, + uint16_t bits_per_sample); + +int q6asm_open_transcode_loopback(struct audio_client *ac, + uint16_t bits_per_sample, uint32_t source_format, + uint32_t sink_format); + +int q6asm_write(struct audio_client *ac, uint32_t len, uint32_t msw_ts, + uint32_t lsw_ts, uint32_t flags); +int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts, + uint32_t lsw_ts, uint32_t flags); + +int q6asm_async_write(struct audio_client *ac, + struct audio_aio_write_param *param); + +int q6asm_async_read(struct audio_client *ac, + struct audio_aio_read_param *param); + +int q6asm_read(struct audio_client *ac); +int q6asm_read_v2(struct audio_client *ac, uint32_t len); +int q6asm_read_nolock(struct audio_client *ac); + +int q6asm_memory_map(struct audio_client *ac, phys_addr_t buf_add, + int dir, uint32_t bufsz, uint32_t bufcnt); + +int q6asm_memory_unmap(struct audio_client *ac, phys_addr_t buf_add, + int dir); + +struct audio_buffer *q6asm_shared_io_buf(struct audio_client *ac, int dir); + +int q6asm_shared_io_free(struct audio_client *ac, int dir); + +int q6asm_get_shared_pos(struct audio_client *ac, uint32_t *si, uint32_t *msw, + uint32_t *lsw); + +int q6asm_map_rtac_block(struct rtac_cal_block_data *cal_block); + +int q6asm_unmap_rtac_block(uint32_t *mem_map_handle); + +int q6asm_send_cal(struct audio_client *ac); + +int q6asm_run(struct audio_client *ac, uint32_t flags, + uint32_t msw_ts, uint32_t lsw_ts); + +int q6asm_run_nowait(struct audio_client *ac, uint32_t flags, + uint32_t msw_ts, uint32_t lsw_ts); + +int q6asm_stream_run_nowait(struct audio_client *ac, uint32_t flags, + uint32_t msw_ts, uint32_t lsw_ts, uint32_t stream_id); + +int q6asm_reg_tx_overflow(struct audio_client *ac, uint16_t enable); + +int q6asm_reg_rx_underflow(struct audio_client *ac, uint16_t enable); + +int q6asm_cmd(struct audio_client *ac, int cmd); + +int q6asm_stream_cmd(struct audio_client *ac, int cmd, uint32_t stream_id); + +int q6asm_cmd_nowait(struct audio_client *ac, int cmd); + +int q6asm_stream_cmd_nowait(struct audio_client *ac, int cmd, + uint32_t stream_id); + +void *q6asm_is_cpu_buf_avail(int dir, struct audio_client *ac, + uint32_t *size, uint32_t *idx); + +int q6asm_cpu_buf_release(int dir, struct audio_client *ac); + +void *q6asm_is_cpu_buf_avail_nolock(int dir, struct audio_client *ac, + uint32_t *size, uint32_t *idx); + +int q6asm_is_dsp_buf_avail(int dir, struct audio_client *ac); + +/* File format specific configurations to be added below */ + +int q6asm_enc_cfg_blk_aac(struct audio_client *ac, + uint32_t frames_per_buf, + uint32_t sample_rate, uint32_t channels, + uint32_t bit_rate, + uint32_t mode, uint32_t format); + +int q6asm_enc_cfg_blk_g711(struct audio_client *ac, + uint32_t frames_per_buf, + uint32_t sample_rate); + +int q6asm_enc_cfg_blk_pcm(struct audio_client *ac, + uint32_t rate, uint32_t channels); + +int q6asm_enc_cfg_blk_pcm_v2(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, + bool use_default_chmap, bool use_back_flavor, + u8 *channel_map); + +int q6asm_enc_cfg_blk_pcm_v3(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, bool use_default_chmap, + bool use_back_flavor, u8 *channel_map, + uint16_t sample_word_size); + +int q6asm_enc_cfg_blk_pcm_v4(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, bool use_default_chmap, + bool use_back_flavor, u8 *channel_map, + uint16_t sample_word_size, uint16_t endianness, + uint16_t mode); + +int q6asm_enc_cfg_blk_pcm_format_support(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample); + +int q6asm_enc_cfg_blk_pcm_format_support_v3(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, + uint16_t sample_word_size); + +int q6asm_enc_cfg_blk_pcm_format_support_v4(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode); + +int q6asm_set_encdec_chan_map(struct audio_client *ac, + uint32_t num_channels); + +int q6asm_enc_cfg_blk_pcm_native(struct audio_client *ac, + uint32_t rate, uint32_t channels); + +int q6asm_enable_sbrps(struct audio_client *ac, + uint32_t sbr_ps); + +int q6asm_cfg_dual_mono_aac(struct audio_client *ac, + uint16_t sce_left, uint16_t sce_right); + +int q6asm_cfg_aac_sel_mix_coef(struct audio_client *ac, uint32_t mix_coeff); + +int q6asm_enc_cfg_blk_qcelp(struct audio_client *ac, uint32_t frames_per_buf, + uint16_t min_rate, uint16_t max_rate, + uint16_t reduced_rate_level, uint16_t rate_modulation_cmd); + +int q6asm_enc_cfg_blk_evrc(struct audio_client *ac, uint32_t frames_per_buf, + uint16_t min_rate, uint16_t max_rate, + uint16_t rate_modulation_cmd); + +int q6asm_enc_cfg_blk_amrnb(struct audio_client *ac, uint32_t frames_per_buf, + uint16_t band_mode, uint16_t dtx_enable); + +int q6asm_enc_cfg_blk_amrwb(struct audio_client *ac, uint32_t frames_per_buf, + uint16_t band_mode, uint16_t dtx_enable); + +int q6asm_media_format_block_pcm(struct audio_client *ac, + uint32_t rate, uint32_t channels); + +int q6asm_media_format_block_pcm_format_support(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample); + +int q6asm_media_format_block_pcm_format_support_v2(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, int stream_id, + bool use_default_chmap, char *channel_map); + +int q6asm_media_format_block_pcm_format_support_v3(struct audio_client *ac, + uint32_t rate, + uint32_t channels, + uint16_t bits_per_sample, + int stream_id, + bool use_default_chmap, + char *channel_map, + uint16_t sample_word_size); + +int q6asm_media_format_block_pcm_format_support_v4(struct audio_client *ac, + uint32_t rate, + uint32_t channels, + uint16_t bits_per_sample, + int stream_id, + bool use_default_chmap, + char *channel_map, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode); + +int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac, + uint32_t rate, uint32_t channels, + bool use_default_chmap, char *channel_map); + +int q6asm_media_format_block_multi_ch_pcm_v2( + struct audio_client *ac, + uint32_t rate, uint32_t channels, + bool use_default_chmap, char *channel_map, + uint16_t bits_per_sample); +int q6asm_media_format_block_gen_compr( + struct audio_client *ac, + uint32_t rate, uint32_t channels, + bool use_default_chmap, char *channel_map, + uint16_t bits_per_sample); + +int q6asm_media_format_block_iec( + struct audio_client *ac, + uint32_t rate, uint32_t channels); + +int q6asm_media_format_block_multi_ch_pcm_v3(struct audio_client *ac, + uint32_t rate, uint32_t channels, + bool use_default_chmap, + char *channel_map, + uint16_t bits_per_sample, + uint16_t sample_word_size); + +int q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac, + uint32_t rate, uint32_t channels, + bool use_default_chmap, + char *channel_map, + uint16_t bits_per_sample, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode); + +int q6asm_media_format_block_aac(struct audio_client *ac, + struct asm_aac_cfg *cfg); + +int q6asm_stream_media_format_block_aac(struct audio_client *ac, + struct asm_aac_cfg *cfg, int stream_id); + +int q6asm_media_format_block_multi_aac(struct audio_client *ac, + struct asm_aac_cfg *cfg); + +int q6asm_media_format_block_wma(struct audio_client *ac, + void *cfg, int stream_id); + +int q6asm_media_format_block_wmapro(struct audio_client *ac, + void *cfg, int stream_id); + +int q6asm_media_format_block_amrwbplus(struct audio_client *ac, + struct asm_amrwbplus_cfg *cfg); + +int q6asm_stream_media_format_block_flac(struct audio_client *ac, + struct asm_flac_cfg *cfg, int stream_id); + +int q6asm_media_format_block_alac(struct audio_client *ac, + struct asm_alac_cfg *cfg, int stream_id); + +int q6asm_media_format_block_g711(struct audio_client *ac, + struct asm_g711_dec_cfg *cfg, int stream_id); + +int q6asm_stream_media_format_block_vorbis(struct audio_client *ac, + struct asm_vorbis_cfg *cfg, int stream_id); + +int q6asm_media_format_block_ape(struct audio_client *ac, + struct asm_ape_cfg *cfg, int stream_id); + +int q6asm_media_format_block_dsd(struct audio_client *ac, + struct asm_dsd_cfg *cfg, int stream_id); + +int q6asm_stream_media_format_block_aptx_dec(struct audio_client *ac, + uint32_t sr, int stream_id); + +int q6asm_ds1_set_endp_params(struct audio_client *ac, + int param_id, int param_value); + +/* Send stream based end params */ +int q6asm_ds1_set_stream_endp_params(struct audio_client *ac, int param_id, + int param_value, int stream_id); + +/* PP specific */ +int q6asm_equalizer(struct audio_client *ac, void *eq); + +/* Send Volume Command */ +int q6asm_set_volume(struct audio_client *ac, int volume); + +/* Send Volume Command */ +int q6asm_set_volume_v2(struct audio_client *ac, int volume, int instance); + +/* DTS Eagle Params */ +int q6asm_dts_eagle_set(struct audio_client *ac, int param_id, uint32_t size, + void *data, struct param_outband *po, int m_id); +int q6asm_dts_eagle_get(struct audio_client *ac, int param_id, uint32_t size, + void *data, struct param_outband *po, int m_id); + +/* Send aptx decoder BT address */ +int q6asm_set_aptx_dec_bt_addr(struct audio_client *ac, + struct aptx_dec_bt_addr_cfg *cfg); + +/* Set SoftPause Params */ +int q6asm_set_softpause(struct audio_client *ac, + struct asm_softpause_params *param); + +/* Set Softvolume Params */ +int q6asm_set_softvolume(struct audio_client *ac, + struct asm_softvolume_params *param); + +/* Set Softvolume Params */ +int q6asm_set_softvolume_v2(struct audio_client *ac, + struct asm_softvolume_params *param, int instance); + +/* Send left-right channel gain */ +int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain); + +/* Send multi channel gain */ +int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, + uint32_t *gains, uint8_t *ch_map, bool use_default); + +/* Enable Mute/unmute flag */ +int q6asm_set_mute(struct audio_client *ac, int muteflag); + +int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp); + +int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp); + +int q6asm_send_audio_effects_params(struct audio_client *ac, char *params, + uint32_t params_length); + +int q6asm_send_stream_cmd(struct audio_client *ac, + struct msm_adsp_event_data *data); + +int q6asm_send_ion_fd(struct audio_client *ac, int fd); + +int q6asm_send_rtic_event_ack(struct audio_client *ac, + void *param, uint32_t params_length); + +/* Client can set the IO mode to either AIO/SIO mode */ +int q6asm_set_io_mode(struct audio_client *ac, uint32_t mode); + +/* Get Service ID for APR communication */ +int q6asm_get_apr_service_id(int session_id); + +/* Common format block without any payload */ +int q6asm_media_format_block(struct audio_client *ac, uint32_t format); + +/* Send the meta data to remove initial and trailing silence */ +int q6asm_send_meta_data(struct audio_client *ac, uint32_t initial_samples, + uint32_t trailing_samples); + +/* Send the stream meta data to remove initial and trailing silence */ +int q6asm_stream_send_meta_data(struct audio_client *ac, uint32_t stream_id, + uint32_t initial_samples, uint32_t trailing_samples); + +int q6asm_get_asm_topology(int session_id); +int q6asm_get_asm_app_type(int session_id); + +int q6asm_send_mtmx_strtr_window(struct audio_client *ac, + struct asm_session_mtmx_strtr_param_window_v2_t *window_param, + uint32_t param_id); + +/* Configure DSP render mode */ +int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac, + uint32_t render_mode); + +/* Configure DSP clock recovery mode */ +int q6asm_send_mtmx_strtr_clk_rec_mode(struct audio_client *ac, + uint32_t clk_rec_mode); + +/* Enable adjust session clock in DSP */ +int q6asm_send_mtmx_strtr_enable_adjust_session_clock(struct audio_client *ac, + bool enable); + +/* Retrieve the current DSP path delay */ +int q6asm_get_path_delay(struct audio_client *ac); + +/* Helper functions to retrieve data from token */ +uint8_t q6asm_get_buf_index_from_token(uint32_t token); +uint8_t q6asm_get_stream_id_from_token(uint32_t token); + +/* Adjust session clock in DSP */ +int q6asm_adjust_session_clock(struct audio_client *ac, + uint32_t adjust_time_lsw, + uint32_t adjust_time_msw); +#endif /* __Q6_ASM_H__ */ diff --git a/include/sound/q6audio-v2.h b/include/sound/q6audio-v2.h new file mode 100644 index 000000000000..fd14f330d1d5 --- /dev/null +++ b/include/sound/q6audio-v2.h @@ -0,0 +1,36 @@ +/* Copyright (c) 2012-2013, 2015 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _Q6_AUDIO_H_ +#define _Q6_AUDIO_H_ + +#include + +enum { + LEGACY_PCM_MODE = 0, + LOW_LATENCY_PCM_MODE, + ULTRA_LOW_LATENCY_PCM_MODE, + ULL_POST_PROCESSING_PCM_MODE, +}; + + +int q6audio_get_port_index(u16 port_id); + +int q6audio_convert_virtual_to_portid(u16 port_id); + +int q6audio_validate_port(u16 port_id); + +int q6audio_is_digital_pcm_interface(u16 port_id); + +int q6audio_get_port_id(u16 port_id); + +#endif diff --git a/include/sound/q6core.h b/include/sound/q6core.h new file mode 100644 index 000000000000..0b8309a10a66 --- /dev/null +++ b/include/sound/q6core.h @@ -0,0 +1,159 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __Q6CORE_H__ +#define __Q6CORE_H__ +#include + + + +#define AVCS_CMD_ADSP_EVENT_GET_STATE 0x0001290C +#define AVCS_CMDRSP_ADSP_EVENT_GET_STATE 0x0001290D + +bool q6core_is_adsp_ready(void); + +#define ADSP_CMD_SET_DTS_EAGLE_DATA_ID 0x00012919 +#define DTS_EAGLE_LICENSE_ID 0x00028346 +struct adsp_dts_eagle { + struct apr_hdr hdr; + uint32_t id; + uint32_t overwrite; + uint32_t size; + char data[]; +}; +int core_dts_eagle_set(int size, char *data); +int core_dts_eagle_get(int id, int size, char *data); + +#define ADSP_CMD_SET_DOLBY_MANUFACTURER_ID 0x00012918 + +struct adsp_dolby_manufacturer_id { + struct apr_hdr hdr; + int manufacturer_id; +}; + +uint32_t core_set_dolby_manufacturer_id(int manufacturer_id); + +/* Dolby Surround1 Module License ID. This ID is used as an identifier + * for DS1 license via ADSP generic license mechanism. + * Please refer AVCS_CMD_SET_LICENSE for more details. + */ +#define DOLBY_DS1_LICENSE_ID 0x00000001 + +#define AVCS_CMD_SET_LICENSE 0x00012919 +struct avcs_cmd_set_license { + struct apr_hdr hdr; + uint32_t id; /**< A unique ID used to refer to this license */ + uint32_t overwrite; + /* 0 = do not overwrite an existing license with this id. + * 1 = overwrite an existing license with this id. + */ + uint32_t size; + /**< Size in bytes of the license data following this header. */ + /* uint8_t* data , data and padding follows this structure + * total packet size needs to be multiple of 4 Bytes + */ + +}; + +#define AVCS_CMD_GET_LICENSE_VALIDATION_RESULT 0x0001291A +struct avcs_cmd_get_license_validation_result { + struct apr_hdr hdr; + uint32_t id; /**< A unique ID used to refer to this license */ +}; + +#define AVCS_CMDRSP_GET_LICENSE_VALIDATION_RESULT 0x0001291B +struct avcs_cmdrsp_get_license_validation_result { + uint32_t result; + /* ADSP_EOK if the license validation result was successfully retrieved. + * ADSP_ENOTEXIST if there is no license with the given id. + * ADSP_ENOTIMPL if there is no validation function for a license + * with this id. + */ + uint32_t size; + /* Length in bytes of the result that follows this structure*/ +}; + +/* Set Q6 topologies */ +/* + * Registers custom topologies in the aDSP for + * use in audio, voice, AFE and LSM. + */ + + +#define AVCS_CMD_SHARED_MEM_MAP_REGIONS 0x00012924 +#define AVCS_CMDRSP_SHARED_MEM_MAP_REGIONS 0x00012925 +#define AVCS_CMD_SHARED_MEM_UNMAP_REGIONS 0x00012926 + + +#define AVCS_CMD_REGISTER_TOPOLOGIES 0x00012923 + +/* The payload for the AVCS_CMD_REGISTER_TOPOLOGIES command */ +struct avcs_cmd_register_topologies { + struct apr_hdr hdr; + uint32_t payload_addr_lsw; + /* Lower 32 bits of the topology buffer address. */ + + uint32_t payload_addr_msw; + /* Upper 32 bits of the topology buffer address. */ + + uint32_t mem_map_handle; + /* Unique identifier for an address. + * -This memory map handle is returned by the aDSP through the + * memory map command. + * -NULL mem_map_handle is interpreted as in-band parameter + * passing. + * -Client has the flexibility to choose in-band or out-of-band. + * -Out-of-band is recommended in this case. + */ + + uint32_t payload_size; + /* Size in bytes of the valid data in the topology buffer. */ +} __packed; + + +#define AVCS_CMD_DEREGISTER_TOPOLOGIES 0x0001292a + +/* The payload for the AVCS_CMD_DEREGISTER_TOPOLOGIES command */ +struct avcs_cmd_deregister_topologies { + struct apr_hdr hdr; + uint32_t payload_addr_lsw; + /* Lower 32 bits of the topology buffer address. */ + + uint32_t payload_addr_msw; + /* Upper 32 bits of the topology buffer address. */ + + uint32_t mem_map_handle; + /* Unique identifier for an address. + * -This memory map handle is returned by the aDSP through the + * memory map command. + * -NULL mem_map_handle is interpreted as in-band parameter + * passing. + * -Client has the flexibility to choose in-band or out-of-band. + * -Out-of-band is recommended in this case. + */ + + uint32_t payload_size; + /* Size in bytes of the valid data in the topology buffer. */ + + uint32_t mode; + /* 1: Deregister selected topologies + * 2: Deregister all topologies + */ +} __packed; + +#define AVCS_MODE_DEREGISTER_ALL_CUSTOM_TOPOLOGIES 2 + + +int32_t core_set_license(uint32_t key, uint32_t module_id); +int32_t core_get_license_status(uint32_t module_id); + +#endif /* __Q6CORE_H__ */ diff --git a/include/sound/q6lsm.h b/include/sound/q6lsm.h new file mode 100644 index 000000000000..26106a8db0ce --- /dev/null +++ b/include/sound/q6lsm.h @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __Q6LSM_H__ +#define __Q6LSM_H__ + +#include +#include +#include +#include +#include + +#define MAX_NUM_CONFIDENCE 20 + +#define ADM_LSM_PORT_ID 0xADCB + +#define LSM_MAX_NUM_CHANNELS 8 + +typedef void (*lsm_app_cb)(uint32_t opcode, uint32_t token, + uint32_t *payload, void *priv); + +struct lsm_sound_model { + dma_addr_t phys; + void *data; + size_t size; /* size of buffer */ + uint32_t actual_size; /* actual number of bytes read by DSP */ + struct ion_handle *handle; + struct ion_client *client; + uint32_t mem_map_handle; +}; + +struct snd_lsm_event_status_v2 { + uint16_t status; + uint16_t payload_size; + uint8_t confidence_value[0]; +}; + +struct lsm_lab_buffer { + dma_addr_t phys; + void *data; + size_t size; + struct ion_handle *handle; + struct ion_client *client; + uint32_t mem_map_handle; +}; + +struct lsm_hw_params { + u16 sample_rate; + u16 sample_size; + u32 buf_sz; + u32 period_count; + u16 num_chs; +}; + +struct lsm_client { + int session; + lsm_app_cb cb; + atomic_t cmd_state; + void *priv; + struct apr_svc *apr; + struct apr_svc *mmap_apr; + struct mutex cmd_lock; + struct lsm_sound_model sound_model; + wait_queue_head_t cmd_wait; + uint32_t cmd_err_code; + uint16_t mode; + uint16_t connect_to_port; + uint8_t num_confidence_levels; + uint8_t *confidence_levels; + bool opened; + bool started; + dma_addr_t lsm_cal_phy_addr; + uint32_t lsm_cal_size; + uint32_t app_id; + bool lab_enable; + bool lab_started; + struct lsm_lab_buffer *lab_buffer; + struct lsm_hw_params hw_params; + bool use_topology; + int session_state; + bool poll_enable; + int perf_mode; + uint32_t event_mode; +}; + +struct lsm_stream_cmd_open_tx { + struct apr_hdr hdr; + uint16_t app_id; + uint16_t reserved; + uint32_t sampling_rate; +} __packed; + +struct lsm_stream_cmd_open_tx_v2 { + struct apr_hdr hdr; + uint32_t topology_id; +} __packed; + +struct lsm_custom_topologies { + struct apr_hdr hdr; + uint32_t data_payload_addr_lsw; + uint32_t data_payload_addr_msw; + uint32_t mem_map_handle; + uint32_t buffer_size; +} __packed; + +struct lsm_param_size_reserved { + uint16_t param_size; + uint16_t reserved; +} __packed; + +union lsm_param_size { + uint32_t param_size; + struct lsm_param_size_reserved sr; +} __packed; + +struct lsm_param_payload_common { + uint32_t module_id; + uint32_t param_id; + union lsm_param_size p_size; +} __packed; + +struct lsm_param_op_mode { + struct lsm_param_payload_common common; + uint32_t minor_version; + uint16_t mode; + uint16_t reserved; +} __packed; + +struct lsm_param_connect_to_port { + struct lsm_param_payload_common common; + uint32_t minor_version; + /* AFE port id that receives voice wake up data */ + uint16_t port_id; + uint16_t reserved; +} __packed; + +struct lsm_param_poll_enable { + struct lsm_param_payload_common common; + uint32_t minor_version; + /* indicates to voice wakeup that HW MAD/SW polling is enabled or not */ + uint32_t polling_enable; +} __packed; + +struct lsm_param_fwk_mode_cfg { + struct lsm_param_payload_common common; + uint32_t minor_version; + uint32_t mode; +} __packed; + +struct lsm_param_media_fmt { + struct lsm_param_payload_common common; + uint32_t minor_version; + uint32_t sample_rate; + uint16_t num_channels; + uint16_t bit_width; + uint8_t channel_mapping[LSM_MAX_NUM_CHANNELS]; +} __packed; + +/* + * This param cannot be sent in this format. + * The actual number of confidence level values + * need to appended to this param payload. + */ +struct lsm_param_min_confidence_levels { + struct lsm_param_payload_common common; + uint8_t num_confidence_levels; +} __packed; + +struct lsm_set_params_hdr { + uint32_t data_payload_size; + uint32_t data_payload_addr_lsw; + uint32_t data_payload_addr_msw; + uint32_t mem_map_handle; +} __packed; + +struct lsm_cmd_set_params { + struct apr_hdr msg_hdr; + struct lsm_set_params_hdr param_hdr; +} __packed; + +struct lsm_cmd_set_params_conf { + struct apr_hdr msg_hdr; + struct lsm_set_params_hdr params_hdr; + struct lsm_param_min_confidence_levels conf_payload; +} __packed; + +struct lsm_cmd_set_params_opmode { + struct apr_hdr msg_hdr; + struct lsm_set_params_hdr params_hdr; + struct lsm_param_op_mode op_mode; +} __packed; + +struct lsm_cmd_set_connectport { + struct apr_hdr msg_hdr; + struct lsm_set_params_hdr params_hdr; + struct lsm_param_connect_to_port connect_to_port; +} __packed; + +struct lsm_cmd_poll_enable { + struct apr_hdr msg_hdr; + struct lsm_set_params_hdr params_hdr; + struct lsm_param_poll_enable poll_enable; +} __packed; + +struct lsm_param_epd_thres { + struct lsm_param_payload_common common; + uint32_t minor_version; + uint32_t epd_begin; + uint32_t epd_end; +} __packed; + +struct lsm_cmd_set_epd_threshold { + struct apr_hdr msg_hdr; + struct lsm_set_params_hdr param_hdr; + struct lsm_param_epd_thres epd_thres; +} __packed; + +struct lsm_param_gain { + struct lsm_param_payload_common common; + uint32_t minor_version; + uint16_t gain; + uint16_t reserved; +} __packed; + +struct lsm_cmd_set_gain { + struct apr_hdr msg_hdr; + struct lsm_set_params_hdr param_hdr; + struct lsm_param_gain lsm_gain; +} __packed; + +struct lsm_cmd_reg_snd_model { + struct apr_hdr hdr; + uint32_t model_size; + uint32_t model_addr_lsw; + uint32_t model_addr_msw; + uint32_t mem_map_handle; +} __packed; + +struct lsm_lab_enable { + struct lsm_param_payload_common common; + uint16_t enable; + uint16_t reserved; +} __packed; + +struct lsm_params_lab_enable { + struct apr_hdr msg_hdr; + struct lsm_set_params_hdr params_hdr; + struct lsm_lab_enable lab_enable; +} __packed; + +struct lsm_lab_config { + struct lsm_param_payload_common common; + uint32_t minor_version; + uint32_t wake_up_latency_ms; +} __packed; + + +struct lsm_params_lab_config { + struct apr_hdr msg_hdr; + struct lsm_set_params_hdr params_hdr; + struct lsm_lab_config lab_config; +} __packed; + +struct lsm_cmd_read { + struct apr_hdr hdr; + uint32_t buf_addr_lsw; + uint32_t buf_addr_msw; + uint32_t mem_map_handle; + uint32_t buf_size; +} __packed; + +struct lsm_cmd_read_done { + struct apr_hdr hdr; + uint32_t status; + uint32_t buf_addr_lsw; + uint32_t buf_addr_msw; + uint32_t mem_map_handle; + uint32_t total_size; + uint32_t offset; + uint32_t timestamp_lsw; + uint32_t timestamp_msw; + uint32_t flags; +} __packed; + +struct lsm_cmd_set_fwk_mode_cfg { + struct apr_hdr msg_hdr; + struct lsm_set_params_hdr params_hdr; + struct lsm_param_fwk_mode_cfg fwk_mode_cfg; +} __packed; + +struct lsm_cmd_set_media_fmt { + struct apr_hdr msg_hdr; + struct lsm_set_params_hdr params_hdr; + struct lsm_param_media_fmt media_fmt; +} __packed; + + +struct lsm_client *q6lsm_client_alloc(lsm_app_cb cb, void *priv); +void q6lsm_client_free(struct lsm_client *client); +int q6lsm_open(struct lsm_client *client, uint16_t app_id); +int q6lsm_start(struct lsm_client *client, bool wait); +int q6lsm_stop(struct lsm_client *client, bool wait); +int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len, + bool allocate_module_data); +int q6lsm_snd_model_buf_free(struct lsm_client *client); +int q6lsm_close(struct lsm_client *client); +int q6lsm_register_sound_model(struct lsm_client *client, + enum lsm_detection_mode mode, + bool detectfailure); +int q6lsm_set_data(struct lsm_client *client, + enum lsm_detection_mode mode, + bool detectfailure); +int q6lsm_deregister_sound_model(struct lsm_client *client); +void set_lsm_port(int lsm_port); +int get_lsm_port(void); +int q6lsm_lab_control(struct lsm_client *client, u32 enable); +int q6lsm_stop_lab(struct lsm_client *client); +int q6lsm_read(struct lsm_client *client, struct lsm_cmd_read *read); +int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc); +int q6lsm_set_one_param(struct lsm_client *client, + struct lsm_params_info *p_info, void *data, + uint32_t param_type); +void q6lsm_sm_set_param_data(struct lsm_client *client, + struct lsm_params_info *p_info, + size_t *offset); +int q6lsm_set_port_connected(struct lsm_client *client); +int q6lsm_set_fwk_mode_cfg(struct lsm_client *client, uint32_t event_mode); +int q6lsm_set_media_fmt_params(struct lsm_client *client); +#endif /* __Q6LSM_H__ */ diff --git a/include/uapi/Kbuild b/include/uapi/Kbuild new file mode 100644 index 000000000000..2eb179d4de95 --- /dev/null +++ b/include/uapi/Kbuild @@ -0,0 +1,6 @@ +# UAPI Header export list +# Top-level Makefile calls into asm-$(ARCH) +# List only non-arch directories below + +header-y += linux/ +header-y += sound/ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild new file mode 100644 index 000000000000..7647f052b7f4 --- /dev/null +++ b/include/uapi/linux/Kbuild @@ -0,0 +1,19 @@ +# UAPI Header export list +header-y += avtimer.h +header-y += msm_audio.h +header-y += msm_audio_aac.h +header-y += msm_audio_ac3.h +header-y += msm_audio_amrnb.h +header-y += msm_audio_amrwb.h +header-y += msm_audio_amrwbplus.h +header-y += msm_audio_calibration.h +header-y += msm_audio_mvs.h +header-y += msm_audio_qcp.h +header-y += msm_audio_sbc.h +header-y += msm_audio_voicememo.h +header-y += msm_audio_wma.h +header-y += msm_audio_wmapro.h +header-y += msm_audio_alac.h +header-y += msm_audio_ape.h +header-y += msm_audio_g711.h +header-y += msm_audio_g711_dec.h diff --git a/include/uapi/linux/avtimer.h b/include/uapi/linux/avtimer.h new file mode 100644 index 000000000000..96b5483fbf2e --- /dev/null +++ b/include/uapi/linux/avtimer.h @@ -0,0 +1,10 @@ +#ifndef _UAPI_AVTIMER_H +#define _UAPI_AVTIMER_H + +#include + +#define MAJOR_NUM 100 + +#define IOCTL_GET_AVTIMER_TICK _IOR(MAJOR_NUM, 0, uint64_t) + +#endif diff --git a/include/uapi/linux/msm_audio.h b/include/uapi/linux/msm_audio.h new file mode 100644 index 000000000000..3213d00842c0 --- /dev/null +++ b/include/uapi/linux/msm_audio.h @@ -0,0 +1,475 @@ +/* include/linux/msm_audio.h + * + * Copyright (C) 2008 Google, Inc. + * Copyright (c) 2012, 2014, 2017 The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _UAPI_LINUX_MSM_AUDIO_H +#define _UAPI_LINUX_MSM_AUDIO_H + +#include +#include + +/* PCM Audio */ + +#define AUDIO_IOCTL_MAGIC 'a' + +#define AUDIO_START _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned int) +#define AUDIO_STOP _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned int) +#define AUDIO_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned int) +#define AUDIO_GET_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 3, \ + struct msm_audio_config) +#define AUDIO_SET_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 4, \ + struct msm_audio_config) +#define AUDIO_GET_STATS _IOR(AUDIO_IOCTL_MAGIC, 5, \ + struct msm_audio_stats) +#define AUDIO_ENABLE_AUDPP _IOW(AUDIO_IOCTL_MAGIC, 6, unsigned int) +#define AUDIO_SET_ADRC _IOW(AUDIO_IOCTL_MAGIC, 7, unsigned int) +#define AUDIO_SET_EQ _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned int) +#define AUDIO_SET_RX_IIR _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned int) +#define AUDIO_SET_VOLUME _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned int) +#define AUDIO_PAUSE _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned int) +#define AUDIO_PLAY_DTMF _IOW(AUDIO_IOCTL_MAGIC, 12, unsigned int) +#define AUDIO_GET_EVENT _IOR(AUDIO_IOCTL_MAGIC, 13, \ + struct msm_audio_event) +#define AUDIO_ABORT_GET_EVENT _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned int) +#define AUDIO_REGISTER_PMEM _IOW(AUDIO_IOCTL_MAGIC, 15, unsigned int) +#define AUDIO_DEREGISTER_PMEM _IOW(AUDIO_IOCTL_MAGIC, 16, unsigned int) +#define AUDIO_ASYNC_WRITE _IOW(AUDIO_IOCTL_MAGIC, 17, \ + struct msm_audio_aio_buf) +#define AUDIO_ASYNC_READ _IOW(AUDIO_IOCTL_MAGIC, 18, \ + struct msm_audio_aio_buf) +#define AUDIO_SET_INCALL _IOW(AUDIO_IOCTL_MAGIC, 19, struct msm_voicerec_mode) +#define AUDIO_GET_NUM_SND_DEVICE _IOR(AUDIO_IOCTL_MAGIC, 20, unsigned int) +#define AUDIO_GET_SND_DEVICES _IOWR(AUDIO_IOCTL_MAGIC, 21, \ + struct msm_snd_device_list) +#define AUDIO_ENABLE_SND_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 22, unsigned int) +#define AUDIO_DISABLE_SND_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 23, unsigned int) +#define AUDIO_ROUTE_STREAM _IOW(AUDIO_IOCTL_MAGIC, 24, \ + struct msm_audio_route_config) +#define AUDIO_GET_PCM_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 30, unsigned int) +#define AUDIO_SET_PCM_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 31, unsigned int) +#define AUDIO_SWITCH_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 32, unsigned int) +#define AUDIO_SET_MUTE _IOW(AUDIO_IOCTL_MAGIC, 33, unsigned int) +#define AUDIO_UPDATE_ACDB _IOW(AUDIO_IOCTL_MAGIC, 34, unsigned int) +#define AUDIO_START_VOICE _IOW(AUDIO_IOCTL_MAGIC, 35, unsigned int) +#define AUDIO_STOP_VOICE _IOW(AUDIO_IOCTL_MAGIC, 36, unsigned int) +#define AUDIO_REINIT_ACDB _IOW(AUDIO_IOCTL_MAGIC, 39, unsigned int) +#define AUDIO_OUTPORT_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 40, unsigned short) +#define AUDIO_SET_ERR_THRESHOLD_VALUE _IOW(AUDIO_IOCTL_MAGIC, 41, \ + unsigned short) +#define AUDIO_GET_BITSTREAM_ERROR_INFO _IOR(AUDIO_IOCTL_MAGIC, 42, \ + struct msm_audio_bitstream_error_info) + +#define AUDIO_SET_SRS_TRUMEDIA_PARAM _IOW(AUDIO_IOCTL_MAGIC, 43, unsigned int) + +/* Qualcomm technologies inc extensions */ +#define AUDIO_SET_STREAM_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 80, \ + struct msm_audio_stream_config) +#define AUDIO_GET_STREAM_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 81, \ + struct msm_audio_stream_config) +#define AUDIO_GET_SESSION_ID _IOR(AUDIO_IOCTL_MAGIC, 82, unsigned short) +#define AUDIO_GET_STREAM_INFO _IOR(AUDIO_IOCTL_MAGIC, 83, \ + struct msm_audio_bitstream_info) +#define AUDIO_SET_PAN _IOW(AUDIO_IOCTL_MAGIC, 84, unsigned int) +#define AUDIO_SET_QCONCERT_PLUS _IOW(AUDIO_IOCTL_MAGIC, 85, unsigned int) +#define AUDIO_SET_MBADRC _IOW(AUDIO_IOCTL_MAGIC, 86, unsigned int) +#define AUDIO_SET_VOLUME_PATH _IOW(AUDIO_IOCTL_MAGIC, 87, \ + struct msm_vol_info) +#define AUDIO_SET_MAX_VOL_ALL _IOW(AUDIO_IOCTL_MAGIC, 88, unsigned int) +#define AUDIO_ENABLE_AUDPRE _IOW(AUDIO_IOCTL_MAGIC, 89, unsigned int) +#define AUDIO_SET_AGC _IOW(AUDIO_IOCTL_MAGIC, 90, unsigned int) +#define AUDIO_SET_NS _IOW(AUDIO_IOCTL_MAGIC, 91, unsigned int) +#define AUDIO_SET_TX_IIR _IOW(AUDIO_IOCTL_MAGIC, 92, unsigned int) +#define AUDIO_GET_BUF_CFG _IOW(AUDIO_IOCTL_MAGIC, 93, \ + struct msm_audio_buf_cfg) +#define AUDIO_SET_BUF_CFG _IOW(AUDIO_IOCTL_MAGIC, 94, \ + struct msm_audio_buf_cfg) +#define AUDIO_SET_ACDB_BLK _IOW(AUDIO_IOCTL_MAGIC, 95, \ + struct msm_acdb_cmd_device) +#define AUDIO_GET_ACDB_BLK _IOW(AUDIO_IOCTL_MAGIC, 96, \ + struct msm_acdb_cmd_device) + +#define AUDIO_REGISTER_ION _IOW(AUDIO_IOCTL_MAGIC, 97, \ + struct msm_audio_ion_info) +#define AUDIO_DEREGISTER_ION _IOW(AUDIO_IOCTL_MAGIC, 98, \ + struct msm_audio_ion_info) +#define AUDIO_SET_EFFECTS_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 99, \ + struct msm_hwacc_effects_config) +#define AUDIO_EFFECTS_SET_BUF_LEN _IOW(AUDIO_IOCTL_MAGIC, 100, \ + struct msm_hwacc_buf_cfg) +#define AUDIO_EFFECTS_GET_BUF_AVAIL _IOW(AUDIO_IOCTL_MAGIC, 101, \ + struct msm_hwacc_buf_avail) +#define AUDIO_EFFECTS_WRITE _IOW(AUDIO_IOCTL_MAGIC, 102, void *) +#define AUDIO_EFFECTS_READ _IOWR(AUDIO_IOCTL_MAGIC, 103, void *) +#define AUDIO_EFFECTS_SET_PP_PARAMS _IOW(AUDIO_IOCTL_MAGIC, 104, void *) + +#define AUDIO_PM_AWAKE _IOW(AUDIO_IOCTL_MAGIC, 105, unsigned int) +#define AUDIO_PM_RELAX _IOW(AUDIO_IOCTL_MAGIC, 106, unsigned int) + +#define AUDIO_MAX_COMMON_IOCTL_NUM 107 + + +#define HANDSET_MIC 0x01 +#define HANDSET_SPKR 0x02 +#define HEADSET_MIC 0x03 +#define HEADSET_SPKR_MONO 0x04 +#define HEADSET_SPKR_STEREO 0x05 +#define SPKR_PHONE_MIC 0x06 +#define SPKR_PHONE_MONO 0x07 +#define SPKR_PHONE_STEREO 0x08 +#define BT_SCO_MIC 0x09 +#define BT_SCO_SPKR 0x0A +#define BT_A2DP_SPKR 0x0B +#define TTY_HEADSET_MIC 0x0C +#define TTY_HEADSET_SPKR 0x0D + +/* Default devices are not supported in a */ +/* device switching context. Only supported */ +/* for stream devices. */ +/* DO NOT USE */ +#define DEFAULT_TX 0x0E +#define DEFAULT_RX 0x0F + +#define BT_A2DP_TX 0x10 + +#define HEADSET_MONO_PLUS_SPKR_MONO_RX 0x11 +#define HEADSET_MONO_PLUS_SPKR_STEREO_RX 0x12 +#define HEADSET_STEREO_PLUS_SPKR_MONO_RX 0x13 +#define HEADSET_STEREO_PLUS_SPKR_STEREO_RX 0x14 + +#define I2S_RX 0x20 +#define I2S_TX 0x21 + +#define ADRC_ENABLE 0x0001 +#define EQUALIZER_ENABLE 0x0002 +#define IIR_ENABLE 0x0004 +#define QCONCERT_PLUS_ENABLE 0x0008 +#define MBADRC_ENABLE 0x0010 +#define SRS_ENABLE 0x0020 +#define SRS_DISABLE 0x0040 + +#define AGC_ENABLE 0x0001 +#define NS_ENABLE 0x0002 +#define TX_IIR_ENABLE 0x0004 +#define FLUENCE_ENABLE 0x0008 + +#define VOC_REC_UPLINK 0x00 +#define VOC_REC_DOWNLINK 0x01 +#define VOC_REC_BOTH 0x02 + +struct msm_audio_config { + uint32_t buffer_size; + uint32_t buffer_count; + uint32_t channel_count; + uint32_t sample_rate; + uint32_t type; + uint32_t meta_field; + uint32_t bits; + uint32_t unused[3]; +}; + +struct msm_audio_stream_config { + uint32_t buffer_size; + uint32_t buffer_count; +}; + +struct msm_audio_buf_cfg { + uint32_t meta_info_enable; + uint32_t frames_per_buf; +}; + +struct msm_audio_stats { + uint32_t byte_count; + uint32_t sample_count; + uint32_t unused[2]; +}; + +struct msm_audio_ion_info { + int fd; + void *vaddr; +}; + +struct msm_audio_pmem_info { + int fd; + void *vaddr; +}; + +struct msm_audio_aio_buf { + void *buf_addr; + uint32_t buf_len; + uint32_t data_len; + void *private_data; + unsigned short mfield_sz; /*only useful for data has meta field */ +}; + +/* Audio routing */ + +#define SND_IOCTL_MAGIC 's' + +#define SND_MUTE_UNMUTED 0 +#define SND_MUTE_MUTED 1 + +struct msm_mute_info { + uint32_t mute; + uint32_t path; +}; + +struct msm_vol_info { + uint32_t vol; + uint32_t path; +}; + +struct msm_voicerec_mode { + uint32_t rec_mode; +}; + +struct msm_snd_device_config { + uint32_t device; + uint32_t ear_mute; + uint32_t mic_mute; +}; + +#define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *) + +enum cad_device_path_type { + CAD_DEVICE_PATH_RX, /*For Decoding session*/ + CAD_DEVICE_PATH_TX, /* For Encoding session*/ + CAD_DEVICE_PATH_RX_TX, /* For Voice call */ + CAD_DEVICE_PATH_LB, /* For loopback (FM Analog)*/ + CAD_DEVICE_PATH_MAX +}; + +struct cad_devices_type { + uint32_t rx_device; + uint32_t tx_device; + enum cad_device_path_type pathtype; +}; + +struct msm_cad_device_config { + struct cad_devices_type device; + uint32_t ear_mute; + uint32_t mic_mute; +}; + +#define CAD_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_cad_device_config *) + +#define SND_METHOD_VOICE 0 +#define SND_METHOD_MIDI 4 + +struct msm_snd_volume_config { + uint32_t device; + uint32_t method; + uint32_t volume; +}; + +#define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *) + +struct msm_cad_volume_config { + struct cad_devices_type device; + uint32_t method; + uint32_t volume; +}; + +#define CAD_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_cad_volume_config *) + +/* Returns the number of SND endpoints supported. */ + +#define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned int *) + +struct msm_snd_endpoint { + int id; /* input and output */ + char name[64]; /* output only */ +}; + +/* Takes an index between 0 and one less than the number returned by + * SND_GET_NUM_ENDPOINTS, and returns the SND index and name of a + * SND endpoint. On input, the .id field contains the number of the + * endpoint, and on exit it contains the SND index, while .name contains + * the description of the endpoint. + */ + +#define SND_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_snd_endpoint *) + + +#define SND_AVC_CTL _IOW(SND_IOCTL_MAGIC, 6, unsigned int *) +#define SND_AGC_CTL _IOW(SND_IOCTL_MAGIC, 7, unsigned int *) + +/*return the number of CAD endpoints supported. */ + +#define CAD_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned int *) + +struct msm_cad_endpoint { + int id; /* input and output */ + char name[64]; /* output only */ +}; + +/* Takes an index between 0 and one less than the number returned by + * SND_GET_NUM_ENDPOINTS, and returns the CAD index and name of a + * CAD endpoint. On input, the .id field contains the number of the + * endpoint, and on exit it contains the SND index, while .name contains + * the description of the endpoint. + */ + +#define CAD_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_cad_endpoint *) + +struct msm_audio_pcm_config { + uint32_t pcm_feedback; /* 0 - disable > 0 - enable */ + uint32_t buffer_count; /* Number of buffers to allocate */ + uint32_t buffer_size; /* Size of buffer for capturing of + * PCM samples + */ +}; + +#define AUDIO_EVENT_SUSPEND 0 +#define AUDIO_EVENT_RESUME 1 +#define AUDIO_EVENT_WRITE_DONE 2 +#define AUDIO_EVENT_READ_DONE 3 +#define AUDIO_EVENT_STREAM_INFO 4 +#define AUDIO_EVENT_BITSTREAM_ERROR_INFO 5 + +#define AUDIO_CODEC_TYPE_MP3 0 +#define AUDIO_CODEC_TYPE_AAC 1 + +struct msm_audio_bitstream_info { + uint32_t codec_type; + uint32_t chan_info; + uint32_t sample_rate; + uint32_t bit_stream_info; + uint32_t bit_rate; + uint32_t unused[3]; +}; + +struct msm_audio_bitstream_error_info { + uint32_t dec_id; + uint32_t err_msg_indicator; + uint32_t err_type; +}; + +union msm_audio_event_payload { + struct msm_audio_aio_buf aio_buf; + struct msm_audio_bitstream_info stream_info; + struct msm_audio_bitstream_error_info error_info; + int reserved; +}; + +struct msm_audio_event { + int event_type; + int timeout_ms; + union msm_audio_event_payload event_payload; +}; + +#define MSM_SNDDEV_CAP_RX 0x1 +#define MSM_SNDDEV_CAP_TX 0x2 +#define MSM_SNDDEV_CAP_VOICE 0x4 + +struct msm_snd_device_info { + uint32_t dev_id; + uint32_t dev_cap; /* bitmask describe capability of device */ + char dev_name[64]; +}; + +struct msm_snd_device_list { + uint32_t num_dev; /* Indicate number of device info to be retrieved */ + struct msm_snd_device_info *list; +}; + +struct msm_dtmf_config { + uint16_t path; + uint16_t dtmf_hi; + uint16_t dtmf_low; + uint16_t duration; + uint16_t tx_gain; + uint16_t rx_gain; + uint16_t mixing; +}; + +#define AUDIO_ROUTE_STREAM_VOICE_RX 0 +#define AUDIO_ROUTE_STREAM_VOICE_TX 1 +#define AUDIO_ROUTE_STREAM_PLAYBACK 2 +#define AUDIO_ROUTE_STREAM_REC 3 + +struct msm_audio_route_config { + uint32_t stream_type; + uint32_t stream_id; + uint32_t dev_id; +}; + +#define AUDIO_MAX_EQ_BANDS 12 + +struct msm_audio_eq_band { + uint16_t band_idx; /* The band index, 0 .. 11 */ + uint32_t filter_type; /* Filter band type */ + uint32_t center_freq_hz; /* Filter band center frequency */ + uint32_t filter_gain; /* Filter band initial gain (dB) */ + /* Range is +12 dB to -12 dB with 1dB increments. */ + uint32_t q_factor; +} __attribute__ ((packed)); + +struct msm_audio_eq_stream_config { + uint32_t enable; /* Number of consequtive bands specified */ + uint32_t num_bands; + struct msm_audio_eq_band eq_bands[AUDIO_MAX_EQ_BANDS]; +} __attribute__ ((packed)); + +struct msm_acdb_cmd_device { + uint32_t command_id; + uint32_t device_id; + uint32_t network_id; + uint32_t sample_rate_id; /* Actual sample rate value */ + uint32_t interface_id; /* See interface id's above */ + uint32_t algorithm_block_id; /* See enumerations above */ + uint32_t total_bytes; /* Length in bytes used by buffer */ + uint32_t *phys_buf; /* Physical Address of data */ +}; + +struct msm_hwacc_data_config { + __u32 buf_size; + __u32 num_buf; + __u32 num_channels; + __u8 channel_map[8]; + __u32 sample_rate; + __u32 bits_per_sample; +}; + +struct msm_hwacc_buf_cfg { + __u32 input_len; + __u32 output_len; +}; + +struct msm_hwacc_buf_avail { + __u32 input_num_avail; + __u32 output_num_avail; +}; + +struct msm_hwacc_effects_config { + struct msm_hwacc_data_config input; + struct msm_hwacc_data_config output; + struct msm_hwacc_buf_cfg buf_cfg; + __u32 meta_mode_enabled; + __u32 overwrite_topology; + __s32 topology; +}; + +#define ADSP_STREAM_PP_EVENT 0 +#define ADSP_STREAM_ENCDEC_EVENT 1 +#define ADSP_STREAM_IEC_61937_FMT_UPDATE_EVENT 2 +#define ADSP_STREAM_EVENT_MAX 3 + +struct msm_adsp_event_data { + __u32 event_type; + __u32 payload_len; + __u8 payload[0]; +}; + +#endif diff --git a/include/uapi/linux/msm_audio_aac.h b/include/uapi/linux/msm_audio_aac.h new file mode 100644 index 000000000000..7e1e1b72424a --- /dev/null +++ b/include/uapi/linux/msm_audio_aac.h @@ -0,0 +1,76 @@ +#ifndef _UAPI_MSM_AUDIO_AAC_H +#define _UAPI_MSM_AUDIO_AAC_H + +#include + +#define AUDIO_SET_AAC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_aac_config) +#define AUDIO_GET_AAC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_aac_config) + +#define AUDIO_SET_AAC_ENC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+3), struct msm_audio_aac_enc_config) + +#define AUDIO_GET_AAC_ENC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+4), struct msm_audio_aac_enc_config) + +#define AUDIO_SET_AAC_MIX_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+5), uint32_t) + +#define AUDIO_AAC_FORMAT_ADTS -1 +#define AUDIO_AAC_FORMAT_RAW 0x0000 +#define AUDIO_AAC_FORMAT_PSUEDO_RAW 0x0001 +#define AUDIO_AAC_FORMAT_LOAS 0x0002 +#define AUDIO_AAC_FORMAT_ADIF 0x0003 + +#define AUDIO_AAC_OBJECT_LC 0x0002 +#define AUDIO_AAC_OBJECT_LTP 0x0004 +#define AUDIO_AAC_OBJECT_ERLC 0x0011 +#define AUDIO_AAC_OBJECT_BSAC 0x0016 + +#define AUDIO_AAC_SEC_DATA_RES_ON 0x0001 +#define AUDIO_AAC_SEC_DATA_RES_OFF 0x0000 + +#define AUDIO_AAC_SCA_DATA_RES_ON 0x0001 +#define AUDIO_AAC_SCA_DATA_RES_OFF 0x0000 + +#define AUDIO_AAC_SPEC_DATA_RES_ON 0x0001 +#define AUDIO_AAC_SPEC_DATA_RES_OFF 0x0000 + +#define AUDIO_AAC_SBR_ON_FLAG_ON 0x0001 +#define AUDIO_AAC_SBR_ON_FLAG_OFF 0x0000 + +#define AUDIO_AAC_SBR_PS_ON_FLAG_ON 0x0001 +#define AUDIO_AAC_SBR_PS_ON_FLAG_OFF 0x0000 + +/* Primary channel on both left and right channels */ +#define AUDIO_AAC_DUAL_MONO_PL_PR 0 +/* Secondary channel on both left and right channels */ +#define AUDIO_AAC_DUAL_MONO_SL_SR 1 +/* Primary channel on right channel and 2nd on left channel */ +#define AUDIO_AAC_DUAL_MONO_SL_PR 2 +/* 2nd channel on right channel and primary on left channel */ +#define AUDIO_AAC_DUAL_MONO_PL_SR 3 + +struct msm_audio_aac_config { + signed short format; + unsigned short audio_object; + unsigned short ep_config; /* 0 ~ 3 useful only obj = ERLC */ + unsigned short aac_section_data_resilience_flag; + unsigned short aac_scalefactor_data_resilience_flag; + unsigned short aac_spectral_data_resilience_flag; + unsigned short sbr_on_flag; + unsigned short sbr_ps_on_flag; + unsigned short dual_mono_mode; + unsigned short channel_configuration; + unsigned short sample_rate; +}; + +struct msm_audio_aac_enc_config { + uint32_t channels; + uint32_t sample_rate; + uint32_t bit_rate; + uint32_t stream_format; +}; + +#endif /* _UAPI_MSM_AUDIO_AAC_H */ diff --git a/include/uapi/linux/msm_audio_ac3.h b/include/uapi/linux/msm_audio_ac3.h new file mode 100644 index 000000000000..1df6e6949ccf --- /dev/null +++ b/include/uapi/linux/msm_audio_ac3.h @@ -0,0 +1,41 @@ +#ifndef _UAPI_MSM_AUDIO_AC3_H +#define _UAPI_MSM_AUDIO_AC3_H + +#include + +#define AUDIO_SET_AC3_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+0), unsigned int) +#define AUDIO_GET_AC3_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+1), unsigned int) + +#define AUDAC3_DEF_WORDSIZE 0 +#define AUDAC3_DEF_USER_DOWNMIX_FLAG 0x0 +#define AUDAC3_DEF_USER_KARAOKE_FLAG 0x0 +#define AUDAC3_DEF_ERROR_CONCEALMENT 0 +#define AUDAC3_DEF_MAX_REPEAT_COUNT 0 + +struct msm_audio_ac3_config { + unsigned short numChans; + unsigned short wordSize; + unsigned short kCapableMode; + unsigned short compMode; + unsigned short outLfeOn; + unsigned short outputMode; + unsigned short stereoMode; + unsigned short dualMonoMode; + unsigned short fsCod; + unsigned short pcmScaleFac; + unsigned short dynRngScaleHi; + unsigned short dynRngScaleLow; + unsigned short user_downmix_flag; + unsigned short user_karaoke_flag; + unsigned short dm_address_high; + unsigned short dm_address_low; + unsigned short ko_address_high; + unsigned short ko_address_low; + unsigned short error_concealment; + unsigned short max_rep_count; + unsigned short channel_routing_mode[6]; +}; + +#endif /* _UAPI_MSM_AUDIO_AC3_H */ diff --git a/include/uapi/linux/msm_audio_alac.h b/include/uapi/linux/msm_audio_alac.h new file mode 100644 index 000000000000..5476e96d06fc --- /dev/null +++ b/include/uapi/linux/msm_audio_alac.h @@ -0,0 +1,24 @@ +#ifndef _UAPI_MSM_AUDIO_ALAC_H +#define _UAPI_MSM_AUDIO_ALAC_H + +#define AUDIO_GET_ALAC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_alac_config) +#define AUDIO_SET_ALAC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_alac_config) + +struct msm_audio_alac_config { + uint32_t frameLength; + uint8_t compatVersion; + uint8_t bitDepth; + uint8_t pb; /* currently unused */ + uint8_t mb; /* currently unused */ + uint8_t kb; /* currently unused */ + uint8_t channelCount; + uint16_t maxRun; /* currently unused */ + uint32_t maxSize; + uint32_t averageBitRate; + uint32_t sampleRate; + uint32_t channelLayout; +}; + +#endif /* _UAPI_MSM_AUDIO_ALAC_H */ diff --git a/include/uapi/linux/msm_audio_amrnb.h b/include/uapi/linux/msm_audio_amrnb.h new file mode 100644 index 000000000000..619f928f7175 --- /dev/null +++ b/include/uapi/linux/msm_audio_amrnb.h @@ -0,0 +1,34 @@ +#ifndef _UAPI_MSM_AUDIO_AMRNB_H +#define _UAPI_MSM_AUDIO_AMRNB_H + +#include + +#define AUDIO_GET_AMRNB_ENC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+0), unsigned int) +#define AUDIO_SET_AMRNB_ENC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+1), unsigned int) +#define AUDIO_GET_AMRNB_ENC_CONFIG_V2 _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+2), \ + struct msm_audio_amrnb_enc_config_v2) +#define AUDIO_SET_AMRNB_ENC_CONFIG_V2 _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+3), \ + struct msm_audio_amrnb_enc_config_v2) + +struct msm_audio_amrnb_enc_config { + unsigned short voicememoencweight1; + unsigned short voicememoencweight2; + unsigned short voicememoencweight3; + unsigned short voicememoencweight4; + unsigned short dtx_mode_enable; /* 0xFFFF - enable, 0- disable */ + unsigned short test_mode_enable; /* 0xFFFF - enable, 0- disable */ + unsigned short enc_mode; /* 0-MR475,1-MR515,2-MR59,3-MR67,4-MR74 + * 5-MR795, 6- MR102, 7- MR122(default) + */ +}; + +struct msm_audio_amrnb_enc_config_v2 { + uint32_t band_mode; + uint32_t dtx_enable; + uint32_t frame_format; +}; +#endif /* _UAPI_MSM_AUDIO_AMRNB_H */ diff --git a/include/uapi/linux/msm_audio_amrwb.h b/include/uapi/linux/msm_audio_amrwb.h new file mode 100644 index 000000000000..51240389988f --- /dev/null +++ b/include/uapi/linux/msm_audio_amrwb.h @@ -0,0 +1,18 @@ +#ifndef _UAPI_MSM_AUDIO_AMRWB_H +#define _UAPI_MSM_AUDIO_AMRWB_H + +#include + +#define AUDIO_GET_AMRWB_ENC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+0), \ + struct msm_audio_amrwb_enc_config) +#define AUDIO_SET_AMRWB_ENC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+1), \ + struct msm_audio_amrwb_enc_config) + +struct msm_audio_amrwb_enc_config { + uint32_t band_mode; + uint32_t dtx_enable; + uint32_t frame_format; +}; +#endif /* _UAPI_MSM_AUDIO_AMRWB_H */ diff --git a/include/uapi/linux/msm_audio_amrwbplus.h b/include/uapi/linux/msm_audio_amrwbplus.h new file mode 100644 index 000000000000..ba2d06e99aa1 --- /dev/null +++ b/include/uapi/linux/msm_audio_amrwbplus.h @@ -0,0 +1,18 @@ +#ifndef _UAPI_MSM_AUDIO_AMR_WB_PLUS_H +#define _UAPI_MSM_AUDIO_AMR_WB_PLUS_H + +#define AUDIO_GET_AMRWBPLUS_CONFIG_V2 _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+2), struct msm_audio_amrwbplus_config_v2) +#define AUDIO_SET_AMRWBPLUS_CONFIG_V2 _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+3), struct msm_audio_amrwbplus_config_v2) + +struct msm_audio_amrwbplus_config_v2 { + unsigned int size_bytes; + unsigned int version; + unsigned int num_channels; + unsigned int amr_band_mode; + unsigned int amr_dtx_mode; + unsigned int amr_frame_fmt; + unsigned int amr_lsf_idx; +}; +#endif /* _UAPI_MSM_AUDIO_AMR_WB_PLUS_H */ diff --git a/include/uapi/linux/msm_audio_ape.h b/include/uapi/linux/msm_audio_ape.h new file mode 100644 index 000000000000..587d3bc1832d --- /dev/null +++ b/include/uapi/linux/msm_audio_ape.h @@ -0,0 +1,26 @@ +/* The following structure has been taken + * from Monkey's Audio SDK with permission + */ + +#ifndef _UAPI_MSM_AUDIO_APE_H +#define _UAPI_MSM_AUDIO_APE_H + +#define AUDIO_GET_APE_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_ape_config) +#define AUDIO_SET_APE_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_ape_config) + +struct msm_audio_ape_config { + uint16_t compatibleVersion; + uint16_t compressionLevel; + uint32_t formatFlags; + uint32_t blocksPerFrame; + uint32_t finalFrameBlocks; + uint32_t totalFrames; + uint16_t bitsPerSample; + uint16_t numChannels; + uint32_t sampleRate; + uint32_t seekTablePresent; +}; + +#endif /* _UAPI_MSM_AUDIO_APE_H */ diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h new file mode 100644 index 000000000000..5a0b8603070d --- /dev/null +++ b/include/uapi/linux/msm_audio_calibration.h @@ -0,0 +1,719 @@ +#ifndef _UAPI_MSM_AUDIO_CALIBRATION_H +#define _UAPI_MSM_AUDIO_CALIBRATION_H + +#include +#include + +#define CAL_IOCTL_MAGIC 'a' + +#define AUDIO_ALLOCATE_CALIBRATION _IOWR(CAL_IOCTL_MAGIC, \ + 200, void *) +#define AUDIO_DEALLOCATE_CALIBRATION _IOWR(CAL_IOCTL_MAGIC, \ + 201, void *) +#define AUDIO_PREPARE_CALIBRATION _IOWR(CAL_IOCTL_MAGIC, \ + 202, void *) +#define AUDIO_SET_CALIBRATION _IOWR(CAL_IOCTL_MAGIC, \ + 203, void *) +#define AUDIO_GET_CALIBRATION _IOWR(CAL_IOCTL_MAGIC, \ + 204, void *) +#define AUDIO_POST_CALIBRATION _IOWR(CAL_IOCTL_MAGIC, \ + 205, void *) + +/* For Real-Time Audio Calibration */ +#define AUDIO_GET_RTAC_ADM_INFO _IOR(CAL_IOCTL_MAGIC, \ + 207, void *) +#define AUDIO_GET_RTAC_VOICE_INFO _IOR(CAL_IOCTL_MAGIC, \ + 208, void *) +#define AUDIO_GET_RTAC_ADM_CAL _IOWR(CAL_IOCTL_MAGIC, \ + 209, void *) +#define AUDIO_SET_RTAC_ADM_CAL _IOWR(CAL_IOCTL_MAGIC, \ + 210, void *) +#define AUDIO_GET_RTAC_ASM_CAL _IOWR(CAL_IOCTL_MAGIC, \ + 211, void *) +#define AUDIO_SET_RTAC_ASM_CAL _IOWR(CAL_IOCTL_MAGIC, \ + 212, void *) +#define AUDIO_GET_RTAC_CVS_CAL _IOWR(CAL_IOCTL_MAGIC, \ + 213, void *) +#define AUDIO_SET_RTAC_CVS_CAL _IOWR(CAL_IOCTL_MAGIC, \ + 214, void *) +#define AUDIO_GET_RTAC_CVP_CAL _IOWR(CAL_IOCTL_MAGIC, \ + 215, void *) +#define AUDIO_SET_RTAC_CVP_CAL _IOWR(CAL_IOCTL_MAGIC, \ + 216, void *) +#define AUDIO_GET_RTAC_AFE_CAL _IOWR(CAL_IOCTL_MAGIC, \ + 217, void *) +#define AUDIO_SET_RTAC_AFE_CAL _IOWR(CAL_IOCTL_MAGIC, \ + 218, void *) +enum { + CVP_VOC_RX_TOPOLOGY_CAL_TYPE = 0, + CVP_VOC_TX_TOPOLOGY_CAL_TYPE, + CVP_VOCPROC_STATIC_CAL_TYPE, + CVP_VOCPROC_DYNAMIC_CAL_TYPE, + CVS_VOCSTRM_STATIC_CAL_TYPE, + CVP_VOCDEV_CFG_CAL_TYPE, + CVP_VOCPROC_STATIC_COL_CAL_TYPE, + CVP_VOCPROC_DYNAMIC_COL_CAL_TYPE, + CVS_VOCSTRM_STATIC_COL_CAL_TYPE, + + ADM_TOPOLOGY_CAL_TYPE, + ADM_CUST_TOPOLOGY_CAL_TYPE, + ADM_AUDPROC_CAL_TYPE, + ADM_AUDVOL_CAL_TYPE, + + ASM_TOPOLOGY_CAL_TYPE, + ASM_CUST_TOPOLOGY_CAL_TYPE, + ASM_AUDSTRM_CAL_TYPE, + + AFE_COMMON_RX_CAL_TYPE, + AFE_COMMON_TX_CAL_TYPE, + AFE_ANC_CAL_TYPE, + AFE_AANC_CAL_TYPE, + AFE_FB_SPKR_PROT_CAL_TYPE, + AFE_HW_DELAY_CAL_TYPE, + AFE_SIDETONE_CAL_TYPE, + AFE_TOPOLOGY_CAL_TYPE, + AFE_CUST_TOPOLOGY_CAL_TYPE, + + LSM_CUST_TOPOLOGY_CAL_TYPE, + LSM_TOPOLOGY_CAL_TYPE, + LSM_CAL_TYPE, + + ADM_RTAC_INFO_CAL_TYPE, + VOICE_RTAC_INFO_CAL_TYPE, + ADM_RTAC_APR_CAL_TYPE, + ASM_RTAC_APR_CAL_TYPE, + VOICE_RTAC_APR_CAL_TYPE, + + MAD_CAL_TYPE, + ULP_AFE_CAL_TYPE, + ULP_LSM_CAL_TYPE, + + DTS_EAGLE_CAL_TYPE, + AUDIO_CORE_METAINFO_CAL_TYPE, + SRS_TRUMEDIA_CAL_TYPE, + + CORE_CUSTOM_TOPOLOGIES_CAL_TYPE, + ADM_RTAC_AUDVOL_CAL_TYPE, + + ULP_LSM_TOPOLOGY_ID_CAL_TYPE, + AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE, + AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE, + AFE_SIDETONE_IIR_CAL_TYPE, + MAX_CAL_TYPES, +}; + +#define AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE +#define AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE + +#define AFE_SIDETONE_IIR_CAL_TYPE AFE_SIDETONE_IIR_CAL_TYPE + +enum { + VERSION_0_0, +}; + +enum { + PER_VOCODER_CAL_BIT_MASK = 0x10000, +}; + +#define MAX_IOCTL_CMD_SIZE 512 + +/* common structures */ + +struct audio_cal_header { + int32_t data_size; + int32_t version; + int32_t cal_type; + int32_t cal_type_size; +}; + +struct audio_cal_type_header { + int32_t version; + int32_t buffer_number; +}; + +struct audio_cal_data { + /* Size of cal data at mem_handle allocation or at vaddr */ + int32_t cal_size; + /* If mem_handle if shared memory is used*/ + int32_t mem_handle; + /* size of virtual memory if shared memory not used */ +}; + + +/* AUDIO_ALLOCATE_CALIBRATION */ +struct audio_cal_type_alloc { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; +}; + +struct audio_cal_alloc { + struct audio_cal_header hdr; + struct audio_cal_type_alloc cal_type; +}; + + +/* AUDIO_DEALLOCATE_CALIBRATION */ +struct audio_cal_type_dealloc { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; +}; + +struct audio_cal_dealloc { + struct audio_cal_header hdr; + struct audio_cal_type_dealloc cal_type; +}; + + +/* AUDIO_PREPARE_CALIBRATION */ +struct audio_cal_type_prepare { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; +}; + +struct audio_cal_prepare { + struct audio_cal_header hdr; + struct audio_cal_type_prepare cal_type; +}; + + +/* AUDIO_POST_CALIBRATION */ +struct audio_cal_type_post { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; +}; + +struct audio_cal_post { + struct audio_cal_header hdr; + struct audio_cal_type_post cal_type; +}; + +/*AUDIO_CORE_META_INFO */ + +struct audio_cal_info_metainfo { + uint32_t nKey; +}; + +/* Cal info types */ +enum { + RX_DEVICE, + TX_DEVICE, + MAX_PATH_TYPE +}; + +struct audio_cal_info_adm_top { + int32_t topology; + int32_t acdb_id; + /* RX_DEVICE or TX_DEVICE */ + int32_t path; + int32_t app_type; + int32_t sample_rate; +}; + +struct audio_cal_info_audproc { + int32_t acdb_id; + /* RX_DEVICE or TX_DEVICE */ + int32_t path; + int32_t app_type; + int32_t sample_rate; +}; + +struct audio_cal_info_audvol { + int32_t acdb_id; + /* RX_DEVICE or TX_DEVICE */ + int32_t path; + int32_t app_type; + int32_t vol_index; +}; + +struct audio_cal_info_afe { + int32_t acdb_id; + /* RX_DEVICE or TX_DEVICE */ + int32_t path; + int32_t sample_rate; +}; + +struct audio_cal_info_afe_top { + int32_t topology; + int32_t acdb_id; + /* RX_DEVICE or TX_DEVICE */ + int32_t path; + int32_t sample_rate; +}; + +struct audio_cal_info_asm_top { + int32_t topology; + int32_t app_type; +}; + +struct audio_cal_info_audstrm { + int32_t app_type; +}; + +struct audio_cal_info_aanc { + int32_t acdb_id; +}; + +#define MAX_HW_DELAY_ENTRIES 25 + +struct audio_cal_hw_delay_entry { + uint32_t sample_rate; + uint32_t delay_usec; +}; + +struct audio_cal_hw_delay_data { + uint32_t num_entries; + struct audio_cal_hw_delay_entry entry[MAX_HW_DELAY_ENTRIES]; +}; + +struct audio_cal_info_hw_delay { + int32_t acdb_id; + /* RX_DEVICE or TX_DEVICE */ + int32_t path; + int32_t property_type; + struct audio_cal_hw_delay_data data; +}; + +enum msm_spkr_prot_states { + MSM_SPKR_PROT_CALIBRATED, + MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS, + MSM_SPKR_PROT_DISABLED, + MSM_SPKR_PROT_NOT_CALIBRATED, + MSM_SPKR_PROT_PRE_CALIBRATED, + MSM_SPKR_PROT_IN_FTM_MODE +}; +#define MSM_SPKR_PROT_IN_FTM_MODE MSM_SPKR_PROT_IN_FTM_MODE + +enum msm_spkr_count { + SP_V2_SPKR_1, + SP_V2_SPKR_2, + SP_V2_NUM_MAX_SPKRS +}; + +struct audio_cal_info_spk_prot_cfg { + int32_t r0[SP_V2_NUM_MAX_SPKRS]; + int32_t t0[SP_V2_NUM_MAX_SPKRS]; + uint32_t quick_calib_flag; + uint32_t mode; + /* + * 0 - Start spk prot + * 1 - Start calib + * 2 - Disable spk prot + */ +}; + +struct audio_cal_info_sp_th_vi_ftm_cfg { + uint32_t wait_time[SP_V2_NUM_MAX_SPKRS]; + uint32_t ftm_time[SP_V2_NUM_MAX_SPKRS]; + uint32_t mode; + /* + * 0 - normal running mode + * 1 - Calibration + * 2 - FTM mode + */ +}; + +struct audio_cal_info_sp_ex_vi_ftm_cfg { + uint32_t wait_time[SP_V2_NUM_MAX_SPKRS]; + uint32_t ftm_time[SP_V2_NUM_MAX_SPKRS]; + uint32_t mode; + /* + * 0 - normal running mode + * 2 - FTM mode + */ +}; + +struct audio_cal_info_sp_ex_vi_param { + int32_t freq_q20[SP_V2_NUM_MAX_SPKRS]; + int32_t resis_q24[SP_V2_NUM_MAX_SPKRS]; + int32_t qmct_q24[SP_V2_NUM_MAX_SPKRS]; + int32_t status[SP_V2_NUM_MAX_SPKRS]; +}; + +struct audio_cal_info_sp_th_vi_param { + int32_t r_dc_q24[SP_V2_NUM_MAX_SPKRS]; + int32_t temp_q22[SP_V2_NUM_MAX_SPKRS]; + int32_t status[SP_V2_NUM_MAX_SPKRS]; +}; + +struct audio_cal_info_msm_spk_prot_status { + int32_t r0[SP_V2_NUM_MAX_SPKRS]; + int32_t status; +}; + +struct audio_cal_info_sidetone { + uint16_t enable; + uint16_t gain; + int32_t tx_acdb_id; + int32_t rx_acdb_id; + int32_t mid; + int32_t pid; +}; + +#define MAX_SIDETONE_IIR_DATA_SIZE 224 +#define MAX_NO_IIR_FILTER_STAGE 10 + +struct audio_cal_info_sidetone_iir { + uint16_t iir_enable; + uint16_t num_biquad_stages; + uint16_t pregain; + int32_t tx_acdb_id; + int32_t rx_acdb_id; + int32_t mid; + int32_t pid; + uint8_t iir_config[MAX_SIDETONE_IIR_DATA_SIZE]; +}; +struct audio_cal_info_lsm_top { + int32_t topology; + int32_t acdb_id; + int32_t app_type; +}; + + +struct audio_cal_info_lsm { + int32_t acdb_id; + /* RX_DEVICE or TX_DEVICE */ + int32_t path; + int32_t app_type; +}; + +struct audio_cal_info_voc_top { + int32_t topology; + int32_t acdb_id; +}; + +struct audio_cal_info_vocproc { + int32_t tx_acdb_id; + int32_t rx_acdb_id; + int32_t tx_sample_rate; + int32_t rx_sample_rate; +}; + +enum { + DEFAULT_FEATURE_SET, + VOL_BOOST_FEATURE_SET, +}; + +struct audio_cal_info_vocvol { + int32_t tx_acdb_id; + int32_t rx_acdb_id; + /* DEFAULT_ or VOL_BOOST_FEATURE_SET */ + int32_t feature_set; +}; + +struct audio_cal_info_vocdev_cfg { + int32_t tx_acdb_id; + int32_t rx_acdb_id; +}; + +#define MAX_VOICE_COLUMNS 20 + +union audio_cal_col_na { + uint8_t val8; + uint16_t val16; + uint32_t val32; + uint64_t val64; +} __packed; + +struct audio_cal_col { + uint32_t id; + uint32_t type; + union audio_cal_col_na na_value; +} __packed; + +struct audio_cal_col_data { + uint32_t num_columns; + struct audio_cal_col column[MAX_VOICE_COLUMNS]; +} __packed; + +struct audio_cal_info_voc_col { + int32_t table_id; + int32_t tx_acdb_id; + int32_t rx_acdb_id; + struct audio_cal_col_data data; +}; + +/* AUDIO_SET_CALIBRATION & */ +struct audio_cal_type_basic { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; +}; + +struct audio_cal_basic { + struct audio_cal_header hdr; + struct audio_cal_type_basic cal_type; +}; + +struct audio_cal_type_adm_top { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_adm_top cal_info; +}; + +struct audio_cal_adm_top { + struct audio_cal_header hdr; + struct audio_cal_type_adm_top cal_type; +}; + +struct audio_cal_type_metainfo { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_metainfo cal_info; +}; + +struct audio_core_metainfo { + struct audio_cal_header hdr; + struct audio_cal_type_metainfo cal_type; +}; + +struct audio_cal_type_audproc { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_audproc cal_info; +}; + +struct audio_cal_audproc { + struct audio_cal_header hdr; + struct audio_cal_type_audproc cal_type; +}; + +struct audio_cal_type_audvol { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_audvol cal_info; +}; + +struct audio_cal_audvol { + struct audio_cal_header hdr; + struct audio_cal_type_audvol cal_type; +}; + +struct audio_cal_type_asm_top { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_asm_top cal_info; +}; + +struct audio_cal_asm_top { + struct audio_cal_header hdr; + struct audio_cal_type_asm_top cal_type; +}; + +struct audio_cal_type_audstrm { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_audstrm cal_info; +}; + +struct audio_cal_audstrm { + struct audio_cal_header hdr; + struct audio_cal_type_audstrm cal_type; +}; + +struct audio_cal_type_afe { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_afe cal_info; +}; + +struct audio_cal_afe { + struct audio_cal_header hdr; + struct audio_cal_type_afe cal_type; +}; + +struct audio_cal_type_afe_top { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_afe_top cal_info; +}; + +struct audio_cal_afe_top { + struct audio_cal_header hdr; + struct audio_cal_type_afe_top cal_type; +}; + +struct audio_cal_type_aanc { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_aanc cal_info; +}; + +struct audio_cal_aanc { + struct audio_cal_header hdr; + struct audio_cal_type_aanc cal_type; +}; + +struct audio_cal_type_fb_spk_prot_cfg { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_spk_prot_cfg cal_info; +}; + +struct audio_cal_fb_spk_prot_cfg { + struct audio_cal_header hdr; + struct audio_cal_type_fb_spk_prot_cfg cal_type; +}; + +struct audio_cal_type_sp_th_vi_ftm_cfg { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_sp_th_vi_ftm_cfg cal_info; +}; + +struct audio_cal_sp_th_vi_ftm_cfg { + struct audio_cal_header hdr; + struct audio_cal_type_sp_th_vi_ftm_cfg cal_type; +}; + +struct audio_cal_type_sp_ex_vi_ftm_cfg { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_sp_ex_vi_ftm_cfg cal_info; +}; + +struct audio_cal_sp_ex_vi_ftm_cfg { + struct audio_cal_header hdr; + struct audio_cal_type_sp_ex_vi_ftm_cfg cal_type; +}; +struct audio_cal_type_hw_delay { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_hw_delay cal_info; +}; + +struct audio_cal_hw_delay { + struct audio_cal_header hdr; + struct audio_cal_type_hw_delay cal_type; +}; + +struct audio_cal_type_sidetone { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_sidetone cal_info; +}; + +struct audio_cal_sidetone { + struct audio_cal_header hdr; + struct audio_cal_type_sidetone cal_type; +}; + +struct audio_cal_type_sidetone_iir { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_sidetone_iir cal_info; +}; + +struct audio_cal_sidetone_iir { + struct audio_cal_header hdr; + struct audio_cal_type_sidetone_iir cal_type; +}; + +struct audio_cal_type_lsm_top { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_lsm_top cal_info; +}; + +struct audio_cal_lsm_top { + struct audio_cal_header hdr; + struct audio_cal_type_lsm_top cal_type; +}; + +struct audio_cal_type_lsm { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_lsm cal_info; +}; + +struct audio_cal_lsm { + struct audio_cal_header hdr; + struct audio_cal_type_lsm cal_type; +}; + +struct audio_cal_type_voc_top { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_voc_top cal_info; +}; + +struct audio_cal_voc_top { + struct audio_cal_header hdr; + struct audio_cal_type_voc_top cal_type; +}; + +struct audio_cal_type_vocproc { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_vocproc cal_info; +}; + +struct audio_cal_vocproc { + struct audio_cal_header hdr; + struct audio_cal_type_vocproc cal_type; +}; + +struct audio_cal_type_vocvol { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_vocvol cal_info; +}; + +struct audio_cal_vocvol { + struct audio_cal_header hdr; + struct audio_cal_type_vocvol cal_type; +}; + +struct audio_cal_type_vocdev_cfg { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_vocdev_cfg cal_info; +}; + +struct audio_cal_vocdev_cfg { + struct audio_cal_header hdr; + struct audio_cal_type_vocdev_cfg cal_type; +}; + +struct audio_cal_type_voc_col { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_voc_col cal_info; +}; + +struct audio_cal_voc_col { + struct audio_cal_header hdr; + struct audio_cal_type_voc_col cal_type; +}; + +/* AUDIO_GET_CALIBRATION */ +struct audio_cal_type_fb_spk_prot_status { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_msm_spk_prot_status cal_info; +}; + +struct audio_cal_fb_spk_prot_status { + struct audio_cal_header hdr; + struct audio_cal_type_fb_spk_prot_status cal_type; +}; + +struct audio_cal_type_sp_th_vi_param { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_sp_th_vi_param cal_info; +}; + +struct audio_cal_sp_th_vi_param { + struct audio_cal_header hdr; + struct audio_cal_type_sp_th_vi_param cal_type; +}; +struct audio_cal_type_sp_ex_vi_param { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_sp_ex_vi_param cal_info; +}; + +struct audio_cal_sp_ex_vi_param { + struct audio_cal_header hdr; + struct audio_cal_type_sp_ex_vi_param cal_type; +}; +#endif /* _UAPI_MSM_AUDIO_CALIBRATION_H */ diff --git a/include/uapi/linux/msm_audio_g711.h b/include/uapi/linux/msm_audio_g711.h new file mode 100644 index 000000000000..48ebd6a1131e --- /dev/null +++ b/include/uapi/linux/msm_audio_g711.h @@ -0,0 +1,17 @@ +#ifndef _UAPI_MSM_AUDIO_G711_H +#define _UAPI_MSM_AUDIO_G711_H + +#include + +struct msm_audio_g711_enc_config { + uint32_t sample_rate; +}; + +#define AUDIO_SET_G711_ENC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_g711_enc_config) + +#define AUDIO_GET_G711_ENC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_g711_enc_config) + + +#endif /* _UAPI_MSM_AUDIO_G711_H */ diff --git a/include/uapi/linux/msm_audio_g711_dec.h b/include/uapi/linux/msm_audio_g711_dec.h new file mode 100644 index 000000000000..ff7e4ce39fd5 --- /dev/null +++ b/include/uapi/linux/msm_audio_g711_dec.h @@ -0,0 +1,16 @@ +#ifndef _UAPI_MSM_AUDIO_G711_H +#define _UAPI_MSM_AUDIO_G711_H + +#include + +struct msm_audio_g711_dec_config { + uint32_t sample_rate; +}; + +#define AUDIO_SET_G711_DEC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_g711_dec_config) + +#define AUDIO_GET_G711_DEC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_g711_dec_config) + +#endif /* _UAPI_MSM_AUDIO_G711_H */ diff --git a/include/uapi/linux/msm_audio_mvs.h b/include/uapi/linux/msm_audio_mvs.h new file mode 100644 index 000000000000..5b76bf99a701 --- /dev/null +++ b/include/uapi/linux/msm_audio_mvs.h @@ -0,0 +1,155 @@ +#ifndef _UAPI_MSM_AUDIO_MVS_H +#define _UAPI_MSM_AUDIO_MVS_H + +#include + +#define AUDIO_GET_MVS_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM + 0), unsigned int) +#define AUDIO_SET_MVS_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM + 1), unsigned int) + +/* MVS modes */ +#define MVS_MODE_IS733 0x1 /*QCELP 13K*/ +#define MVS_MODE_IS127 0x2 /*EVRC-8k*/ +#define MVS_MODE_4GV_NB 0x3 /*EVRC-B*/ +#define MVS_MODE_4GV_WB 0x4 /*EVRC-WB*/ +#define MVS_MODE_AMR 0x5 +#define MVS_MODE_EFR 0x6 +#define MVS_MODE_FR 0x7 +#define MVS_MODE_HR 0x8 +#define MVS_MODE_LINEAR_PCM 0x9 +#define MVS_MODE_G711 0xA +#define MVS_MODE_PCM 0xC +#define MVS_MODE_AMR_WB 0xD +#define MVS_MODE_G729A 0xE +#define MVS_MODE_G711A 0xF +#define MVS_MODE_G722 0x10 +#define MVS_MODE_PCM_WB 0x12 + +enum msm_audio_amr_mode { + MVS_AMR_MODE_0475, /* AMR 4.75 kbps */ + MVS_AMR_MODE_0515, /* AMR 5.15 kbps */ + MVS_AMR_MODE_0590, /* AMR 5.90 kbps */ + MVS_AMR_MODE_0670, /* AMR 6.70 kbps */ + MVS_AMR_MODE_0740, /* AMR 7.40 kbps */ + MVS_AMR_MODE_0795, /* AMR 7.95 kbps */ + MVS_AMR_MODE_1020, /* AMR 10.20 kbps */ + MVS_AMR_MODE_1220, /* AMR 12.20 kbps */ + MVS_AMR_MODE_0660, /* AMR-WB 6.60 kbps */ + MVS_AMR_MODE_0885, /* AMR-WB 8.85 kbps */ + MVS_AMR_MODE_1265, /* AMR-WB 12.65 kbps */ + MVS_AMR_MODE_1425, /* AMR-WB 14.25 kbps */ + MVS_AMR_MODE_1585, /* AMR-WB 15.85 kbps */ + MVS_AMR_MODE_1825, /* AMR-WB 18.25 kbps */ + MVS_AMR_MODE_1985, /* AMR-WB 19.85 kbps */ + MVS_AMR_MODE_2305, /* AMR-WB 23.05 kbps */ + MVS_AMR_MODE_2385, /* AMR-WB 23.85 kbps */ + MVS_AMR_MODE_UNDEF +}; + +/* The MVS VOC rate type is used to identify the rate of QCELP 13K(IS733), + * EVRC(IS127), 4GV, or 4GV-WB frame. + */ +enum msm_audio_voc_rate { + MVS_VOC_0_RATE, /* Blank frame */ + MVS_VOC_8_RATE, /* 1/8 rate */ + MVS_VOC_4_RATE, /* 1/4 rate */ + MVS_VOC_2_RATE, /* 1/2 rate */ + MVS_VOC_1_RATE, /* Full rate */ + MVS_VOC_ERASURE, /* erasure frame */ + MVS_VOC_RATE_MAX, + MVS_VOC_RATE_UNDEF = MVS_VOC_RATE_MAX +}; + +enum msm_audio_amr_frame_type { + MVS_AMR_SPEECH_GOOD, /* Good speech frame */ + MVS_AMR_SPEECH_DEGRADED, /* Speech degraded */ + MVS_AMR_ONSET, /* Onset */ + MVS_AMR_SPEECH_BAD, /* Corrupt speech frame (bad CRC) */ + MVS_AMR_SID_FIRST, /* First silence descriptor */ + MVS_AMR_SID_UPDATE, /* Comfort noise frame */ + MVS_AMR_SID_BAD, /* Corrupt SID frame (bad CRC) */ + MVS_AMR_NO_DATA, /* Nothing to transmit */ + MVS_AMR_SPEECH_LOST /* Downlink speech lost */ +}; + +enum msm_audio_g711a_mode { + MVS_G711A_MODE_MULAW, + MVS_G711A_MODE_ALAW +}; + +enum msm_audio_g711_mode { + MVS_G711_MODE_MULAW, + MVS_G711_MODE_ALAW +}; + +enum mvs_g722_mode_type { + MVS_G722_MODE_01, + MVS_G722_MODE_02, + MVS_G722_MODE_03, + MVS_G722_MODE_MAX, + MVS_G722_MODE_UNDEF +}; + +enum msm_audio_g711a_frame_type { + MVS_G711A_SPEECH_GOOD, + MVS_G711A_SID, + MVS_G711A_NO_DATA, + MVS_G711A_ERASURE +}; + +enum msm_audio_g729a_frame_type { + MVS_G729A_NO_DATA, + MVS_G729A_SPEECH_GOOD, + MVS_G729A_SID, + MVS_G729A_ERASURE +}; + +struct min_max_rate { + uint32_t min_rate; + uint32_t max_rate; +}; + +struct msm_audio_mvs_config { + uint32_t mvs_mode; + uint32_t rate_type; + struct min_max_rate min_max_rate; + uint32_t dtx_mode; +}; + +#define MVS_MAX_VOC_PKT_SIZE 640 + +struct gsm_header { + uint8_t bfi; + uint8_t sid; + uint8_t taf; + uint8_t ufi; +}; + +struct q6_msm_audio_mvs_frame { + union { + uint32_t frame_type; + uint32_t packet_rate; + struct gsm_header gsm_frame_type; + } header; + uint32_t len; + uint8_t voc_pkt[MVS_MAX_VOC_PKT_SIZE]; + +}; + +struct msm_audio_mvs_frame { + uint32_t frame_type; + uint32_t len; + uint8_t voc_pkt[MVS_MAX_VOC_PKT_SIZE]; + +}; + +#define Q5V2_MVS_MAX_VOC_PKT_SIZE 320 + +struct q5v2_msm_audio_mvs_frame { + uint32_t frame_type; + uint32_t len; + uint8_t voc_pkt[Q5V2_MVS_MAX_VOC_PKT_SIZE]; + +}; +#endif /* _UAPI_MSM_AUDIO_MVS_H */ diff --git a/include/uapi/linux/msm_audio_qcp.h b/include/uapi/linux/msm_audio_qcp.h new file mode 100644 index 000000000000..fdb234e91acf --- /dev/null +++ b/include/uapi/linux/msm_audio_qcp.h @@ -0,0 +1,37 @@ +#ifndef _UAPI_MSM_AUDIO_QCP_H +#define _UAPI_MSM_AUDIO_QCP_H + +#include + +#define AUDIO_SET_QCELP_ENC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + 0, struct msm_audio_qcelp_enc_config) + +#define AUDIO_GET_QCELP_ENC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + 1, struct msm_audio_qcelp_enc_config) + +#define AUDIO_SET_EVRC_ENC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + 2, struct msm_audio_evrc_enc_config) + +#define AUDIO_GET_EVRC_ENC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + 3, struct msm_audio_evrc_enc_config) + +#define CDMA_RATE_BLANK 0x00 +#define CDMA_RATE_EIGHTH 0x01 +#define CDMA_RATE_QUARTER 0x02 +#define CDMA_RATE_HALF 0x03 +#define CDMA_RATE_FULL 0x04 +#define CDMA_RATE_ERASURE 0x05 + +struct msm_audio_qcelp_enc_config { + uint32_t cdma_rate; + uint32_t min_bit_rate; + uint32_t max_bit_rate; +}; + +struct msm_audio_evrc_enc_config { + uint32_t cdma_rate; + uint32_t min_bit_rate; + uint32_t max_bit_rate; +}; + +#endif /* _UAPI_MSM_AUDIO_QCP_H */ diff --git a/include/uapi/linux/msm_audio_sbc.h b/include/uapi/linux/msm_audio_sbc.h new file mode 100644 index 000000000000..1c7c63da3da7 --- /dev/null +++ b/include/uapi/linux/msm_audio_sbc.h @@ -0,0 +1,36 @@ +#ifndef _UAPI_MSM_AUDIO_SBC_H +#define _UAPI_MSM_AUDIO_SBC_H + +#include + +#define AUDIO_SET_SBC_ENC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_sbc_enc_config) + +#define AUDIO_GET_SBC_ENC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_sbc_enc_config) + +#define AUDIO_SBC_BA_LOUDNESS 0x0 +#define AUDIO_SBC_BA_SNR 0x1 + +#define AUDIO_SBC_MODE_MONO 0x0 +#define AUDIO_SBC_MODE_DUAL 0x1 +#define AUDIO_SBC_MODE_STEREO 0x2 +#define AUDIO_SBC_MODE_JSTEREO 0x3 + +#define AUDIO_SBC_BANDS_8 0x1 + +#define AUDIO_SBC_BLOCKS_4 0x0 +#define AUDIO_SBC_BLOCKS_8 0x1 +#define AUDIO_SBC_BLOCKS_12 0x2 +#define AUDIO_SBC_BLOCKS_16 0x3 + +struct msm_audio_sbc_enc_config { + uint32_t channels; + uint32_t sample_rate; + uint32_t bit_allocation; + uint32_t number_of_subbands; + uint32_t number_of_blocks; + uint32_t bit_rate; + uint32_t mode; +}; +#endif /* _UAPI_MSM_AUDIO_SBC_H */ diff --git a/include/uapi/linux/msm_audio_voicememo.h b/include/uapi/linux/msm_audio_voicememo.h new file mode 100644 index 000000000000..a7a7a4df17d5 --- /dev/null +++ b/include/uapi/linux/msm_audio_voicememo.h @@ -0,0 +1,66 @@ +#ifndef _UAPI_MSM_AUDIO_VOICEMEMO_H +#define _UAPI_MSM_AUDIO_VOICEMEMO_H + +#include + +#define AUDIO_GET_VOICEMEMO_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+0), unsigned int) +#define AUDIO_SET_VOICEMEMO_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+1), unsigned int) + +/* rec_type */ +enum rpc_voc_rec_dir_type { + RPC_VOC_REC_NONE, + RPC_VOC_REC_FORWARD, + RPC_VOC_REC_REVERSE, + RPC_VOC_REC_BOTH, + RPC_VOC_MAX_REC_TYPE +}; + +/* capability */ +enum rpc_voc_capability_type { + RPC_VOC_CAP_IS733 = 4, + RPC_VOC_CAP_IS127 = 8, + RPC_VOC_CAP_AMR = 64, + RPC_VOC_CAP_32BIT_DUMMY = 2147483647 +}; + +/* Rate */ +enum rpc_voc_rate_type { + RPC_VOC_0_RATE = 0, + RPC_VOC_8_RATE, + RPC_VOC_4_RATE, + RPC_VOC_2_RATE, + RPC_VOC_1_RATE, + RPC_VOC_ERASURE, + RPC_VOC_ERR_RATE, + RPC_VOC_AMR_RATE_475 = 0, + RPC_VOC_AMR_RATE_515 = 1, + RPC_VOC_AMR_RATE_590 = 2, + RPC_VOC_AMR_RATE_670 = 3, + RPC_VOC_AMR_RATE_740 = 4, + RPC_VOC_AMR_RATE_795 = 5, + RPC_VOC_AMR_RATE_1020 = 6, + RPC_VOC_AMR_RATE_1220 = 7, +}; + +/* frame_format */ +enum rpc_voc_pb_len_rate_var_type { + RPC_VOC_PB_NATIVE_QCP = 3, + RPC_VOC_PB_AMR, + RPC_VOC_PB_EVB +}; + +struct msm_audio_voicememo_config { + uint32_t rec_type; + uint32_t rec_interval_ms; + uint32_t auto_stop_ms; + uint32_t capability; + uint32_t max_rate; + uint32_t min_rate; + uint32_t frame_format; + uint32_t dtx_enable; + uint32_t data_req_ms; +}; + +#endif /* _UAPI_MSM_AUDIO_VOICEMEMO_H */ diff --git a/include/uapi/linux/msm_audio_wma.h b/include/uapi/linux/msm_audio_wma.h new file mode 100644 index 000000000000..523fadef08d1 --- /dev/null +++ b/include/uapi/linux/msm_audio_wma.h @@ -0,0 +1,33 @@ +#ifndef _UAPI_MSM_AUDIO_WMA_H +#define _UAPI_MSM_AUDIO_WMA_H + +#define AUDIO_GET_WMA_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+0), unsigned int) +#define AUDIO_SET_WMA_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+1), unsigned int) + +#define AUDIO_GET_WMA_CONFIG_V2 _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+2), struct msm_audio_wma_config_v2) +#define AUDIO_SET_WMA_CONFIG_V2 _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+3), struct msm_audio_wma_config_v2) + +struct msm_audio_wma_config { + unsigned short armdatareqthr; + unsigned short channelsdecoded; + unsigned short wmabytespersec; + unsigned short wmasamplingfreq; + unsigned short wmaencoderopts; +}; + +struct msm_audio_wma_config_v2 { + unsigned short format_tag; + unsigned short numchannels; + uint32_t samplingrate; + uint32_t avgbytespersecond; + unsigned short block_align; + unsigned short validbitspersample; + uint32_t channelmask; + unsigned short encodeopt; +}; + +#endif /* _UAPI_MSM_AUDIO_WMA_H */ diff --git a/include/uapi/linux/msm_audio_wmapro.h b/include/uapi/linux/msm_audio_wmapro.h new file mode 100644 index 000000000000..64cbf9e079d6 --- /dev/null +++ b/include/uapi/linux/msm_audio_wmapro.h @@ -0,0 +1,22 @@ +#ifndef _UAPI_MSM_AUDIO_WMAPRO_H +#define _UAPI_MSM_AUDIO_WMAPRO_H + +#define AUDIO_GET_WMAPRO_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+0), struct msm_audio_wmapro_config) +#define AUDIO_SET_WMAPRO_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+1), struct msm_audio_wmapro_config) + +struct msm_audio_wmapro_config { + unsigned short armdatareqthr; + uint8_t validbitspersample; + uint8_t numchannels; + unsigned short formattag; + uint32_t samplingrate; + uint32_t avgbytespersecond; + unsigned short asfpacketlength; + uint32_t channelmask; + unsigned short encodeopt; + unsigned short advancedencodeopt; + uint32_t advancedencodeopt2; +}; +#endif /* _UAPI_MSM_AUDIO_WMAPRO_H */ diff --git a/include/uapi/sound/Kbuild b/include/uapi/sound/Kbuild new file mode 100644 index 000000000000..175fb6f63359 --- /dev/null +++ b/include/uapi/sound/Kbuild @@ -0,0 +1,8 @@ +# UAPI Header export list +header-y += lsm_params.h +header-y += audio_slimslave.h +header-y += audio_effects.h +header-y += devdep_params.h +header-y += msmcal-hwdep.h +header-y += wcd-dsp-glink.h +header-y += voice_params.h diff --git a/include/uapi/sound/audio_effects.h b/include/uapi/sound/audio_effects.h new file mode 100644 index 000000000000..7964c34f890d --- /dev/null +++ b/include/uapi/sound/audio_effects.h @@ -0,0 +1,361 @@ +#ifndef _AUDIO_EFFECTS_H +#define _AUDIO_EFFECTS_H + +/** AUDIO EFFECTS **/ + + +/* CONFIG GET/SET */ +#define CONFIG_CACHE 0 +#define CONFIG_SET 1 +#define CONFIG_GET 2 + +/* CONFIG HEADER */ +/* + * MODULE_ID, + * DEVICE, + * NUM_COMMANDS, + * COMMAND_ID_1, + * CONFIG_CACHE/SET/GET, + * OFFSET_1, + * LENGTH_1, + * VALUES_1, + * ..., + * ..., + * COMMAND_ID_2, + * CONFIG_CACHE/SET/GET, + * OFFSET_2, + * LENGTH_2, + * VALUES_2, + * ..., + * ..., + * COMMAND_ID_3, + * ... + */ + + +/* CONFIG PARAM IDs */ +#define VIRTUALIZER_MODULE 0x00001000 +#define VIRTUALIZER_ENABLE 0x00001001 +#define VIRTUALIZER_STRENGTH 0x00001002 +#define VIRTUALIZER_OUT_TYPE 0x00001003 +#define VIRTUALIZER_GAIN_ADJUST 0x00001004 +#define VIRTUALIZER_ENABLE_PARAM_LEN 1 +#define VIRTUALIZER_STRENGTH_PARAM_LEN 1 +#define VIRTUALIZER_OUT_TYPE_PARAM_LEN 1 +#define VIRTUALIZER_GAIN_ADJUST_PARAM_LEN 1 + +#define REVERB_MODULE 0x00002000 +#define REVERB_ENABLE 0x00002001 +#define REVERB_MODE 0x00002002 +#define REVERB_PRESET 0x00002003 +#define REVERB_WET_MIX 0x00002004 +#define REVERB_GAIN_ADJUST 0x00002005 +#define REVERB_ROOM_LEVEL 0x00002006 +#define REVERB_ROOM_HF_LEVEL 0x00002007 +#define REVERB_DECAY_TIME 0x00002008 +#define REVERB_DECAY_HF_RATIO 0x00002009 +#define REVERB_REFLECTIONS_LEVEL 0x0000200a +#define REVERB_REFLECTIONS_DELAY 0x0000200b +#define REVERB_LEVEL 0x0000200c +#define REVERB_DELAY 0x0000200d +#define REVERB_DIFFUSION 0x0000200e +#define REVERB_DENSITY 0x0000200f +#define REVERB_ENABLE_PARAM_LEN 1 +#define REVERB_MODE_PARAM_LEN 1 +#define REVERB_PRESET_PARAM_LEN 1 +#define REVERB_WET_MIX_PARAM_LEN 1 +#define REVERB_GAIN_ADJUST_PARAM_LEN 1 +#define REVERB_ROOM_LEVEL_PARAM_LEN 1 +#define REVERB_ROOM_HF_LEVEL_PARAM_LEN 1 +#define REVERB_DECAY_TIME_PARAM_LEN 1 +#define REVERB_DECAY_HF_RATIO_PARAM_LEN 1 +#define REVERB_REFLECTIONS_LEVEL_PARAM_LEN 1 +#define REVERB_REFLECTIONS_DELAY_PARAM_LEN 1 +#define REVERB_LEVEL_PARAM_LEN 1 +#define REVERB_DELAY_PARAM_LEN 1 +#define REVERB_DIFFUSION_PARAM_LEN 1 +#define REVERB_DENSITY_PARAM_LEN 1 + +#define BASS_BOOST_MODULE 0x00003000 +#define BASS_BOOST_ENABLE 0x00003001 +#define BASS_BOOST_MODE 0x00003002 +#define BASS_BOOST_STRENGTH 0x00003003 +#define BASS_BOOST_ENABLE_PARAM_LEN 1 +#define BASS_BOOST_MODE_PARAM_LEN 1 +#define BASS_BOOST_STRENGTH_PARAM_LEN 1 + +#define EQ_MODULE 0x00004000 +#define EQ_ENABLE 0x00004001 +#define EQ_CONFIG 0x00004002 +#define EQ_NUM_BANDS 0x00004003 +#define EQ_BAND_LEVELS 0x00004004 +#define EQ_BAND_LEVEL_RANGE 0x00004005 +#define EQ_BAND_FREQS 0x00004006 +#define EQ_SINGLE_BAND_FREQ_RANGE 0x00004007 +#define EQ_SINGLE_BAND_FREQ 0x00004008 +#define EQ_BAND_INDEX 0x00004009 +#define EQ_PRESET_ID 0x0000400a +#define EQ_NUM_PRESETS 0x0000400b +#define EQ_PRESET_NAME 0x0000400c +#define EQ_ENABLE_PARAM_LEN 1 +#define EQ_CONFIG_PARAM_LEN 3 +#define EQ_CONFIG_PER_BAND_PARAM_LEN 5 +#define EQ_NUM_BANDS_PARAM_LEN 1 +#define EQ_BAND_LEVELS_PARAM_LEN 13 +#define EQ_BAND_LEVEL_RANGE_PARAM_LEN 2 +#define EQ_BAND_FREQS_PARAM_LEN 13 +#define EQ_SINGLE_BAND_FREQ_RANGE_PARAM_LEN 2 +#define EQ_SINGLE_BAND_FREQ_PARAM_LEN 1 +#define EQ_BAND_INDEX_PARAM_LEN 1 +#define EQ_PRESET_ID_PARAM_LEN 1 +#define EQ_NUM_PRESETS_PARAM_LEN 1 +#define EQ_PRESET_NAME_PARAM_LEN 32 + +#define EQ_TYPE_NONE 0 +#define EQ_BASS_BOOST 1 +#define EQ_BASS_CUT 2 +#define EQ_TREBLE_BOOST 3 +#define EQ_TREBLE_CUT 4 +#define EQ_BAND_BOOST 5 +#define EQ_BAND_CUT 6 + +#define SOFT_VOLUME_MODULE 0x00006000 +#define SOFT_VOLUME_ENABLE 0x00006001 +#define SOFT_VOLUME_GAIN_2CH 0x00006002 +#define SOFT_VOLUME_GAIN_MASTER 0x00006003 +#define SOFT_VOLUME_ENABLE_PARAM_LEN 1 +#define SOFT_VOLUME_GAIN_2CH_PARAM_LEN 2 +#define SOFT_VOLUME_GAIN_MASTER_PARAM_LEN 1 + +#define SOFT_VOLUME2_MODULE 0x00007000 +#define SOFT_VOLUME2_ENABLE 0x00007001 +#define SOFT_VOLUME2_GAIN_2CH 0x00007002 +#define SOFT_VOLUME2_GAIN_MASTER 0x00007003 +#define SOFT_VOLUME2_ENABLE_PARAM_LEN SOFT_VOLUME_ENABLE_PARAM_LEN +#define SOFT_VOLUME2_GAIN_2CH_PARAM_LEN SOFT_VOLUME_GAIN_2CH_PARAM_LEN +#define SOFT_VOLUME2_GAIN_MASTER_PARAM_LEN \ + SOFT_VOLUME_GAIN_MASTER_PARAM_LEN + +#define PBE_CONF_MODULE_ID 0x00010C2A +#define PBE_CONF_PARAM_ID 0x00010C49 + +#define PBE_MODULE 0x00008000 +#define PBE_ENABLE 0x00008001 +#define PBE_CONFIG 0x00008002 +#define PBE_ENABLE_PARAM_LEN 1 +#define PBE_CONFIG_PARAM_LEN 28 + +#define COMMAND_PAYLOAD_LEN 3 +#define COMMAND_PAYLOAD_SZ (COMMAND_PAYLOAD_LEN * sizeof(uint32_t)) +#define MAX_INBAND_PARAM_SZ 4096 +#define Q27_UNITY (1 << 27) +#define Q8_UNITY (1 << 8) +#define CUSTOM_OPENSL_PRESET 18 + +#define VIRTUALIZER_ENABLE_PARAM_SZ \ + (VIRTUALIZER_ENABLE_PARAM_LEN*sizeof(uint32_t)) +#define VIRTUALIZER_STRENGTH_PARAM_SZ \ + (VIRTUALIZER_STRENGTH_PARAM_LEN*sizeof(uint32_t)) +#define VIRTUALIZER_OUT_TYPE_PARAM_SZ \ + (VIRTUALIZER_OUT_TYPE_PARAM_LEN*sizeof(uint32_t)) +#define VIRTUALIZER_GAIN_ADJUST_PARAM_SZ \ + (VIRTUALIZER_GAIN_ADJUST_PARAM_LEN*sizeof(uint32_t)) +struct virtualizer_params { + uint32_t device; + uint32_t enable_flag; + uint32_t strength; + uint32_t out_type; + int32_t gain_adjust; +}; + +#define NUM_OSL_REVERB_PRESETS_SUPPORTED 6 +#define REVERB_ENABLE_PARAM_SZ \ + (REVERB_ENABLE_PARAM_LEN*sizeof(uint32_t)) +#define REVERB_MODE_PARAM_SZ \ + (REVERB_MODE_PARAM_LEN*sizeof(uint32_t)) +#define REVERB_PRESET_PARAM_SZ \ + (REVERB_PRESET_PARAM_LEN*sizeof(uint32_t)) +#define REVERB_WET_MIX_PARAM_SZ \ + (REVERB_WET_MIX_PARAM_LEN*sizeof(uint32_t)) +#define REVERB_GAIN_ADJUST_PARAM_SZ \ + (REVERB_GAIN_ADJUST_PARAM_LEN*sizeof(uint32_t)) +#define REVERB_ROOM_LEVEL_PARAM_SZ \ + (REVERB_ROOM_LEVEL_PARAM_LEN*sizeof(uint32_t)) +#define REVERB_ROOM_HF_LEVEL_PARAM_SZ \ + (REVERB_ROOM_HF_LEVEL_PARAM_LEN*sizeof(uint32_t)) +#define REVERB_DECAY_TIME_PARAM_SZ \ + (REVERB_DECAY_TIME_PARAM_LEN*sizeof(uint32_t)) +#define REVERB_DECAY_HF_RATIO_PARAM_SZ \ + (REVERB_DECAY_HF_RATIO_PARAM_LEN*sizeof(uint32_t)) +#define REVERB_REFLECTIONS_LEVEL_PARAM_SZ \ + (REVERB_REFLECTIONS_LEVEL_PARAM_LEN*sizeof(uint32_t)) +#define REVERB_REFLECTIONS_DELAY_PARAM_SZ \ + (REVERB_REFLECTIONS_DELAY_PARAM_LEN*sizeof(uint32_t)) +#define REVERB_LEVEL_PARAM_SZ \ + (REVERB_LEVEL_PARAM_LEN*sizeof(uint32_t)) +#define REVERB_DELAY_PARAM_SZ \ + (REVERB_DELAY_PARAM_LEN*sizeof(uint32_t)) +#define REVERB_DIFFUSION_PARAM_SZ \ + (REVERB_DIFFUSION_PARAM_LEN*sizeof(uint32_t)) +#define REVERB_DENSITY_PARAM_SZ \ + (REVERB_DENSITY_PARAM_LEN*sizeof(uint32_t)) +struct reverb_params { + uint32_t device; + uint32_t enable_flag; + uint32_t mode; + uint32_t preset; + uint32_t wet_mix; + int32_t gain_adjust; + int32_t room_level; + int32_t room_hf_level; + uint32_t decay_time; + uint32_t decay_hf_ratio; + int32_t reflections_level; + uint32_t reflections_delay; + int32_t level; + uint32_t delay; + uint32_t diffusion; + uint32_t density; +}; + +#define BASS_BOOST_ENABLE_PARAM_SZ \ + (BASS_BOOST_ENABLE_PARAM_LEN*sizeof(uint32_t)) +#define BASS_BOOST_MODE_PARAM_SZ \ + (BASS_BOOST_MODE_PARAM_LEN*sizeof(uint32_t)) +#define BASS_BOOST_STRENGTH_PARAM_SZ \ + (BASS_BOOST_STRENGTH_PARAM_LEN*sizeof(uint32_t)) +struct bass_boost_params { + uint32_t device; + uint32_t enable_flag; + uint32_t mode; + uint32_t strength; +}; + + +#define MAX_EQ_BANDS 12 +#define MAX_OSL_EQ_BANDS 5 +#define EQ_ENABLE_PARAM_SZ \ + (EQ_ENABLE_PARAM_LEN*sizeof(uint32_t)) +#define EQ_CONFIG_PARAM_SZ \ + (EQ_CONFIG_PARAM_LEN*sizeof(uint32_t)) +#define EQ_CONFIG_PER_BAND_PARAM_SZ \ + (EQ_CONFIG_PER_BAND_PARAM_LEN*sizeof(uint32_t)) +#define EQ_CONFIG_PARAM_MAX_LEN (EQ_CONFIG_PARAM_LEN+\ + MAX_EQ_BANDS*EQ_CONFIG_PER_BAND_PARAM_LEN) +#define EQ_CONFIG_PARAM_MAX_SZ \ + (EQ_CONFIG_PARAM_MAX_LEN*sizeof(uint32_t)) +#define EQ_NUM_BANDS_PARAM_SZ \ + (EQ_NUM_BANDS_PARAM_LEN*sizeof(uint32_t)) +#define EQ_BAND_LEVELS_PARAM_SZ \ + (EQ_BAND_LEVELS_PARAM_LEN*sizeof(uint32_t)) +#define EQ_BAND_LEVEL_RANGE_PARAM_SZ \ + (EQ_BAND_LEVEL_RANGE_PARAM_LEN*sizeof(uint32_t)) +#define EQ_BAND_FREQS_PARAM_SZ \ + (EQ_BAND_FREQS_PARAM_LEN*sizeof(uint32_t)) +#define EQ_SINGLE_BAND_FREQ_RANGE_PARAM_SZ \ + (EQ_SINGLE_BAND_FREQ_RANGE_PARAM_LEN*sizeof(uint32_t)) +#define EQ_SINGLE_BAND_FREQ_PARAM_SZ \ + (EQ_SINGLE_BAND_FREQ_PARAM_LEN*sizeof(uint32_t)) +#define EQ_BAND_INDEX_PARAM_SZ \ + (EQ_BAND_INDEX_PARAM_LEN*sizeof(uint32_t)) +#define EQ_PRESET_ID_PARAM_SZ \ + (EQ_PRESET_ID_PARAM_LEN*sizeof(uint32_t)) +#define EQ_NUM_PRESETS_PARAM_SZ \ + (EQ_NUM_PRESETS_PARAM_LEN*sizeof(uint8_t)) +struct eq_config_t { + int32_t eq_pregain; + int32_t preset_id; + uint32_t num_bands; +}; +struct eq_per_band_config_t { + int32_t band_idx; + uint32_t filter_type; + uint32_t freq_millihertz; + int32_t gain_millibels; + uint32_t quality_factor; +}; +struct eq_per_band_freq_range_t { + uint32_t band_index; + uint32_t min_freq_millihertz; + uint32_t max_freq_millihertz; +}; + +struct eq_params { + uint32_t device; + uint32_t enable_flag; + struct eq_config_t config; + struct eq_per_band_config_t per_band_cfg[MAX_EQ_BANDS]; + struct eq_per_band_freq_range_t per_band_freq_range[MAX_EQ_BANDS]; + uint32_t band_index; + uint32_t freq_millihertz; +}; + +#define PBE_ENABLE_PARAM_SZ \ + (PBE_ENABLE_PARAM_LEN*sizeof(uint32_t)) +#define PBE_CONFIG_PARAM_SZ \ + (PBE_CONFIG_PARAM_LEN*sizeof(uint16_t)) +struct pbe_config_t { + int16_t real_bass_mix; + int16_t bass_color_control; + uint16_t main_chain_delay; + uint16_t xover_filter_order; + uint16_t bandpass_filter_order; + int16_t drc_delay; + uint16_t rms_tav; + int16_t exp_threshold; + uint16_t exp_slope; + int16_t comp_threshold; + uint16_t comp_slope; + uint16_t makeup_gain; + uint32_t comp_attack; + uint32_t comp_release; + uint32_t exp_attack; + uint32_t exp_release; + int16_t limiter_bass_threshold; + int16_t limiter_high_threshold; + int16_t limiter_bass_makeup_gain; + int16_t limiter_high_makeup_gain; + int16_t limiter_bass_gc; + int16_t limiter_high_gc; + int16_t limiter_delay; + uint16_t reserved; + /* place holder for filter coeffs to be followed */ + int32_t p1LowPassCoeffs[5*2]; + int32_t p1HighPassCoeffs[5*2]; + int32_t p1BandPassCoeffs[5*3]; + int32_t p1BassShelfCoeffs[5]; + int32_t p1TrebleShelfCoeffs[5]; +} __packed; + +struct pbe_params { + uint32_t device; + uint32_t enable_flag; + uint32_t cfg_len; + struct pbe_config_t config; +}; + +#define SOFT_VOLUME_ENABLE_PARAM_SZ \ + (SOFT_VOLUME_ENABLE_PARAM_LEN*sizeof(uint32_t)) +#define SOFT_VOLUME_GAIN_MASTER_PARAM_SZ \ + (SOFT_VOLUME_GAIN_MASTER_PARAM_LEN*sizeof(uint32_t)) +#define SOFT_VOLUME_GAIN_2CH_PARAM_SZ \ + (SOFT_VOLUME_GAIN_2CH_PARAM_LEN*sizeof(uint16_t)) +struct soft_volume_params { + uint32_t device; + uint32_t enable_flag; + uint32_t master_gain; + uint32_t left_gain; + uint32_t right_gain; +}; + +struct msm_nt_eff_all_config { + struct bass_boost_params bass_boost; + struct pbe_params pbe; + struct virtualizer_params virtualizer; + struct reverb_params reverb; + struct eq_params equalizer; + struct soft_volume_params saplus_vol; + struct soft_volume_params topo_switch_vol; +}; + +#endif /*_MSM_AUDIO_EFFECTS_H*/ diff --git a/include/uapi/sound/audio_slimslave.h b/include/uapi/sound/audio_slimslave.h new file mode 100644 index 000000000000..316a5573f5b4 --- /dev/null +++ b/include/uapi/sound/audio_slimslave.h @@ -0,0 +1,18 @@ +#ifndef __AUDIO_SLIMSLAVE_H__ +#define __AUDIO_SLIMSLAVE_H__ + +#include +#include + +#define AUDIO_SLIMSLAVE_IOCTL_NAME "audio_slimslave" +#define AUDIO_SLIMSLAVE_MAGIC 'S' + +#define AUDIO_SLIMSLAVE_IOCTL_UNVOTE _IO(AUDIO_SLIMSLAVE_MAGIC, 0x00) +#define AUDIO_SLIMSLAVE_IOCTL_VOTE _IO(AUDIO_SLIMSLAVE_MAGIC, 0x01) + +enum { + AUDIO_SLIMSLAVE_UNVOTE, + AUDIO_SLIMSLAVE_VOTE +}; + +#endif diff --git a/include/uapi/sound/devdep_params.h b/include/uapi/sound/devdep_params.h new file mode 100644 index 000000000000..6697eca288fe --- /dev/null +++ b/include/uapi/sound/devdep_params.h @@ -0,0 +1,56 @@ +#ifndef _DEV_DEP_H +#define _DEV_DEP_H + +struct dolby_param_data { + int32_t version; + int32_t device_id; + int32_t be_id; + int32_t param_id; + int32_t length; + int32_t __user *data; +}; + +struct dolby_param_license { + int32_t dmid; + int32_t license_key; +}; + +#define SNDRV_DEVDEP_DAP_IOCTL_SET_PARAM\ + _IOWR('U', 0x10, struct dolby_param_data) +#define SNDRV_DEVDEP_DAP_IOCTL_GET_PARAM\ + _IOR('U', 0x11, struct dolby_param_data) +#define SNDRV_DEVDEP_DAP_IOCTL_DAP_COMMAND\ + _IOWR('U', 0x13, struct dolby_param_data) +#define SNDRV_DEVDEP_DAP_IOCTL_DAP_LICENSE\ + _IOWR('U', 0x14, struct dolby_param_license) +#define SNDRV_DEVDEP_DAP_IOCTL_GET_VISUALIZER\ + _IOR('U', 0x15, struct dolby_param_data) + +#define DTS_EAGLE_MODULE 0x00005000 +#define DTS_EAGLE_MODULE_ENABLE 0x00005001 +#define EAGLE_DRIVER_ID 0xF2 +#define DTS_EAGLE_IOCTL_GET_CACHE_SIZE _IOR(EAGLE_DRIVER_ID, 0, int) +#define DTS_EAGLE_IOCTL_SET_CACHE_SIZE _IOW(EAGLE_DRIVER_ID, 1, int) +#define DTS_EAGLE_IOCTL_GET_PARAM _IOR(EAGLE_DRIVER_ID, 2, void*) +#define DTS_EAGLE_IOCTL_SET_PARAM _IOW(EAGLE_DRIVER_ID, 3, void*) +#define DTS_EAGLE_IOCTL_SET_CACHE_BLOCK _IOW(EAGLE_DRIVER_ID, 4, void*) +#define DTS_EAGLE_IOCTL_SET_ACTIVE_DEVICE _IOW(EAGLE_DRIVER_ID, 5, void*) +#define DTS_EAGLE_IOCTL_GET_LICENSE _IOR(EAGLE_DRIVER_ID, 6, void*) +#define DTS_EAGLE_IOCTL_SET_LICENSE _IOW(EAGLE_DRIVER_ID, 7, void*) +#define DTS_EAGLE_IOCTL_SEND_LICENSE _IOW(EAGLE_DRIVER_ID, 8, int) +#define DTS_EAGLE_IOCTL_SET_VOLUME_COMMANDS _IOW(EAGLE_DRIVER_ID, 9, void*) +#define DTS_EAGLE_FLAG_IOCTL_PRE (1<<30) +#define DTS_EAGLE_FLAG_IOCTL_JUSTSETCACHE (1<<31) +#define DTS_EAGLE_FLAG_IOCTL_GETFROMCORE DTS_EAGLE_FLAG_IOCTL_JUSTSETCACHE +#define DTS_EAGLE_FLAG_IOCTL_MASK (~(DTS_EAGLE_FLAG_IOCTL_PRE | \ + DTS_EAGLE_FLAG_IOCTL_JUSTSETCACHE)) +#define DTS_EAGLE_FLAG_ALSA_GET (1<<31) + +struct dts_eagle_param_desc { + uint32_t id; + uint32_t size; + int32_t offset; + uint32_t device; +} __packed; + +#endif diff --git a/include/uapi/sound/lsm_params.h b/include/uapi/sound/lsm_params.h new file mode 100644 index 000000000000..9ca5930475ba --- /dev/null +++ b/include/uapi/sound/lsm_params.h @@ -0,0 +1,200 @@ +#ifndef _UAPI_LSM_PARAMS_H__ +#define _UAPI_LSM_PARAMS_H__ + +#define LSM_POLLING_ENABLE_SUPPORT +#define LSM_EVENT_TIMESTAMP_MODE_SUPPORT + +#include +#include + +#define SNDRV_LSM_VERSION SNDRV_PROTOCOL_VERSION(0, 1, 0) + +#define LSM_OUT_FORMAT_PCM (0) +#define LSM_OUT_FORMAT_ADPCM (1 << 0) + +#define LSM_OUT_DATA_RAW (0) +#define LSM_OUT_DATA_PACKED (1) + +#define LSM_OUT_DATA_EVENTS_DISABLED (0) +#define LSM_OUT_DATA_EVENTS_ENABLED (1) + +#define LSM_OUT_TRANSFER_MODE_RT (0) +#define LSM_OUT_TRANSFER_MODE_FTRT (1) + +#define LSM_ENDPOINT_DETECT_THRESHOLD (0) +#define LSM_OPERATION_MODE (1) +#define LSM_GAIN (2) +#define LSM_MIN_CONFIDENCE_LEVELS (3) +#define LSM_REG_SND_MODEL (4) +#define LSM_DEREG_SND_MODEL (5) +#define LSM_CUSTOM_PARAMS (6) +#define LSM_POLLING_ENABLE (7) +#define LSM_PARAMS_MAX (LSM_POLLING_ENABLE + 1) + +#define LSM_EVENT_NON_TIME_STAMP_MODE (0) +#define LSM_EVENT_TIME_STAMP_MODE (1) + +enum lsm_app_id { + LSM_VOICE_WAKEUP_APP_ID = 1, + LSM_VOICE_WAKEUP_APP_ID_V2 = 2, +}; + +enum lsm_detection_mode { + LSM_MODE_KEYWORD_ONLY_DETECTION = 1, + LSM_MODE_USER_KEYWORD_DETECTION +}; + +enum lsm_vw_status { + LSM_VOICE_WAKEUP_STATUS_RUNNING = 1, + LSM_VOICE_WAKEUP_STATUS_DETECTED, + LSM_VOICE_WAKEUP_STATUS_END_SPEECH, + LSM_VOICE_WAKEUP_STATUS_REJECTED +}; + +/* + * Data for LSM_ENDPOINT_DETECT_THRESHOLD param_type + * @epd_begin: Begin threshold + * @epd_end: End threshold + */ +struct snd_lsm_ep_det_thres { + __u32 epd_begin; + __u32 epd_end; +}; + +/* + * Data for LSM_OPERATION_MODE param_type + * @mode: The detection mode to be used + * @detect_failure: Setting to enable failure detections. + */ +struct snd_lsm_detect_mode { + enum lsm_detection_mode mode; + bool detect_failure; +}; + +/* + * Data for LSM_GAIN param_type + * @gain: The gain to be applied on LSM + */ +struct snd_lsm_gain { + __u16 gain; +}; + +/* + * Data for LSM_POLLING_ENABLE param_type + * @poll_en: Polling enable or disable + */ +struct snd_lsm_poll_enable { + bool poll_en; +}; + + +struct snd_lsm_sound_model_v2 { + __u8 __user *data; + __u8 *confidence_level; + __u32 data_size; + enum lsm_detection_mode detection_mode; + __u8 num_confidence_levels; + bool detect_failure; +}; + +struct snd_lsm_session_data { + enum lsm_app_id app_id; +}; + +struct snd_lsm_event_status { + __u16 status; + __u16 payload_size; + __u8 payload[0]; +}; + +struct snd_lsm_event_status_v3 { + __u32 timestamp_lsw; + __u32 timestamp_msw; + __u16 status; + __u16 payload_size; + __u8 payload[0]; +}; + +struct snd_lsm_detection_params { + __u8 *conf_level; + enum lsm_detection_mode detect_mode; + __u8 num_confidence_levels; + bool detect_failure; + bool poll_enable; +}; + +/* + * Param info for each parameter type + * @module_id: Module to which parameter is to be set + * @param_id: Parameter that is to be set + * @param_size: size (in number of bytes) for the data + * in param_data. + * For confidence levels, this is num_conf_levels + * For REG_SND_MODEL, this is size of sound model + * For CUSTOM_PARAMS, this is size of the entire blob of data + * @param_data: Data for the parameter. + * For some param_types this is a structure defined, ex: LSM_GAIN + * For CONFIDENCE_LEVELS, this is array of confidence levels + * For REG_SND_MODEL, this is the sound model data + * For CUSTOM_PARAMS, this is the blob of custom data. + */ +struct lsm_params_info { + __u32 module_id; + __u32 param_id; + __u32 param_size; + __u8 __user *param_data; + uint32_t param_type; +}; + +/* + * Data passed to the SET_PARAM_V2 IOCTL + * @num_params: Number of params that are to be set + * should not be greater than LSM_PARAMS_MAX + * @params: Points to an array of lsm_params_info + * Each entry points to one parameter to set + * @data_size: size (in bytes) for params + * should be equal to + * num_params * sizeof(struct lsm_parms_info) + */ +struct snd_lsm_module_params { + __u8 __user *params; + __u32 num_params; + __u32 data_size; +}; + +/* + * Data passed to LSM_OUT_FORMAT_CFG IOCTL + * @format: The media format enum + * @packing: indicates the packing method used for data path + * @events: indicates whether data path events need to be enabled + * @transfer_mode: indicates whether FTRT mode or RT mode. + */ +struct snd_lsm_output_format_cfg { + __u8 format; + __u8 packing; + __u8 events; + __u8 mode; +}; + +#define SNDRV_LSM_DEREG_SND_MODEL _IOW('U', 0x01, int) +#define SNDRV_LSM_EVENT_STATUS _IOW('U', 0x02, struct snd_lsm_event_status) +#define SNDRV_LSM_ABORT_EVENT _IOW('U', 0x03, int) +#define SNDRV_LSM_START _IOW('U', 0x04, int) +#define SNDRV_LSM_STOP _IOW('U', 0x05, int) +#define SNDRV_LSM_SET_SESSION_DATA _IOW('U', 0x06, struct snd_lsm_session_data) +#define SNDRV_LSM_REG_SND_MODEL_V2 _IOW('U', 0x07,\ + struct snd_lsm_sound_model_v2) +#define SNDRV_LSM_LAB_CONTROL _IOW('U', 0x08, uint32_t) +#define SNDRV_LSM_STOP_LAB _IO('U', 0x09) +#define SNDRV_LSM_SET_PARAMS _IOW('U', 0x0A, \ + struct snd_lsm_detection_params) +#define SNDRV_LSM_SET_MODULE_PARAMS _IOW('U', 0x0B, \ + struct snd_lsm_module_params) +#define SNDRV_LSM_OUT_FORMAT_CFG _IOW('U', 0x0C, \ + struct snd_lsm_output_format_cfg) +#define SNDRV_LSM_SET_PORT _IO('U', 0x0D) +#define SNDRV_LSM_SET_FWK_MODE_CONFIG _IOW('U', 0x0E, uint32_t) +#define SNDRV_LSM_EVENT_STATUS_V3 _IOW('U', 0x0F, \ + struct snd_lsm_event_status_v3) + +#endif diff --git a/include/uapi/sound/msmcal-hwdep.h b/include/uapi/sound/msmcal-hwdep.h new file mode 100644 index 000000000000..49f15de682fc --- /dev/null +++ b/include/uapi/sound/msmcal-hwdep.h @@ -0,0 +1,23 @@ +#ifndef _CALIB_HWDEP_H +#define _CALIB_HWDEP_H + +#define WCD9XXX_CODEC_HWDEP_NODE 1000 +enum wcd_cal_type { + WCD9XXX_MIN_CAL, + WCD9XXX_ANC_CAL = WCD9XXX_MIN_CAL, + WCD9XXX_MAD_CAL, + WCD9XXX_MBHC_CAL, + WCD9XXX_VBAT_CAL, + WCD9XXX_MAX_CAL, +}; + +struct wcdcal_ioctl_buffer { + __u32 size; + __u8 __user *buffer; + enum wcd_cal_type cal_type; +}; + +#define SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE \ + _IOW('U', 0x1, struct wcdcal_ioctl_buffer) + +#endif /*_CALIB_HWDEP_H*/ diff --git a/include/uapi/sound/voice_params.h b/include/uapi/sound/voice_params.h new file mode 100644 index 000000000000..43e3b9d0aa49 --- /dev/null +++ b/include/uapi/sound/voice_params.h @@ -0,0 +1,14 @@ +#ifndef __VOICE_PARAMS_H__ +#define __VOICE_PARAMS_H__ + +#include +#include + +enum voice_lch_mode { + VOICE_LCH_START = 1, + VOICE_LCH_STOP +}; + +#define SNDRV_VOICE_IOCTL_LCH _IOW('U', 0x00, enum voice_lch_mode) + +#endif diff --git a/include/uapi/sound/wcd-dsp-glink.h b/include/uapi/sound/wcd-dsp-glink.h new file mode 100644 index 000000000000..39d128d370a0 --- /dev/null +++ b/include/uapi/sound/wcd-dsp-glink.h @@ -0,0 +1,60 @@ +#ifndef _WCD_DSP_GLINK_H +#define _WCD_DSP_GLINK_H + +#include + +#define WDSP_CH_NAME_MAX_LEN 50 + +enum { + WDSP_REG_PKT = 1, + WDSP_CMD_PKT, + WDSP_READY_PKT, +}; +#define WDSP_READY_PKT WDSP_READY_PKT + +/* + * struct wdsp_reg_pkt - Glink channel information structure format + * @no_of_channels: Number of glink channels to open + * @payload[0]: Dynamic array contains all the glink channels information + */ +struct wdsp_reg_pkt { + __u8 no_of_channels; + __u8 payload[0]; +}; + +/* + * struct wdsp_cmd_pkt - WDSP command packet format + * @ch_name: Name of the glink channel + * @payload_size: Size of the payload + * @payload[0]: Actual data payload + */ +struct wdsp_cmd_pkt { + char ch_name[WDSP_CH_NAME_MAX_LEN]; + __u32 payload_size; + __u8 payload[0]; +}; + +/* + * struct wdsp_write_pkt - Format that userspace send the data to driver. + * @pkt_type: Type of the packet(REG or CMD PKT) + * @payload[0]: Payload is either cmd or reg pkt structure based on pkt type + */ +struct wdsp_write_pkt { + __u8 pkt_type; + __u8 payload[0]; +}; + +/* + * struct wdsp_glink_ch_cfg - Defines the glink channel configuration. + * @ch_name: Name of the glink channel + * @latency_in_us: Latency specified in micro seconds for QOS + * @no_of_intents: Number of intents prequeued + * @intents_size[0]: Dynamic array to specify size of each intent + */ +struct wdsp_glink_ch_cfg { + char name[WDSP_CH_NAME_MAX_LEN]; + __u32 latency_in_us; + __u32 no_of_intents; + __u32 intents_size[0]; +}; +#endif /* _WCD_DSP_GLINK_H */ diff --git a/sound/Makefile b/sound/Makefile new file mode 100644 index 000000000000..71c713a41d38 --- /dev/null +++ b/sound/Makefile @@ -0,0 +1,4 @@ +# MSM Machine Support + +obj-$(CONFIG_SND_SOC) += soc/msm/ +obj-$(CONFIG_SND_SOC) += soc/codecs/ diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile new file mode 100644 index 000000000000..53256649cd4e --- /dev/null +++ b/sound/soc/codecs/Makefile @@ -0,0 +1,26 @@ +snd-soc-wcd934x-objs := wcd934x.o +snd-soc-wcd9xxx-v2-objs := wcd9xxx-common-v2.o wcd9xxx-resmgr-v2.o wcdcal-hwdep.o wcd9xxx-soc-init.o +snd-soc-wcd-cpe-objs := wcd_cpe_services.o wcd_cpe_core.o +snd-soc-wsa881x-objs := wsa881x.o wsa881x-tables.o wsa881x-regmap.o wsa881x-temp-sensor.o +snd-soc-wcd-mbhc-objs := wcd-mbhc-v2.o wcd-mbhc-adc.o +snd-soc-wcd-dsp-utils-objs := wcd-dsp-utils.o +snd-soc-wcd-dsp-mgr-objs := wcd-dsp-mgr.o +snd-soc-wcd-spi-objs := wcd-spi.o + +obj-$(CONFIG_SND_SOC_WCD934X) += wcd934x/ +ifeq ($(CONFIG_COMMON_CLK_MSM), y) + obj-$(CONFIG_AUDIO_EXT_CLK) += audio-ext-clk.o +endif +ifeq ($(CONFIG_COMMON_CLK_QCOM), y) + obj-$(CONFIG_AUDIO_EXT_CLK) += audio-ext-clk-up.o +endif + +obj-$(CONFIG_SND_SOC_WCD9XXX_V2) += snd-soc-wcd9xxx-v2.o +obj-$(CONFIG_SND_SOC_WCD_CPE) += snd-soc-wcd-cpe.o +obj-$(CONFIG_SND_SOC_WCD_MBHC) += snd-soc-wcd-mbhc.o +obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o +obj-$(CONFIG_SND_SOC_WCD_DSP_MGR) += snd-soc-wcd-dsp-mgr.o snd-soc-wcd-dsp-utils.o +obj-$(CONFIG_SND_SOC_WCD_SPI) += snd-soc-wcd-spi.o + +snd-soc-msm-stub-objs := msm_stub.o +obj-$(CONFIG_SND_SOC_MSM_STUB) += snd-soc-msm-stub.o diff --git a/sound/soc/codecs/audio-ext-clk-up.c b/sound/soc/codecs/audio-ext-clk-up.c new file mode 100644 index 000000000000..31c063d4b93e --- /dev/null +++ b/sound/soc/codecs/audio-ext-clk-up.c @@ -0,0 +1,626 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "../../../drivers/clk/qcom/common.h" +#include +#include +#include +#include +#include +#include "audio-ext-clk-up.h" + +enum audio_clk_mux { + AP_CLK2, + LPASS_MCLK, + LPASS_MCLK2, +}; + +struct pinctrl_info { + struct pinctrl *pinctrl; + struct pinctrl_state *sleep; + struct pinctrl_state *active; + char __iomem *base; +}; + +struct audio_ext_ap_clk { + bool enabled; + int gpio; + struct clk_fixed_factor fact; +}; + +struct audio_ext_pmi_clk { + int gpio; + struct clk_fixed_factor fact; +}; + +struct audio_ext_ap_clk2 { + bool enabled; + struct pinctrl_info pnctrl_info; + struct clk_fixed_factor fact; +}; + +struct audio_ext_lpass_mclk { + struct pinctrl_info pnctrl_info; + struct clk_fixed_factor fact; +}; + +static struct afe_clk_set clk2_config = { + Q6AFE_LPASS_CLK_CONFIG_API_VERSION, + Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR, + Q6AFE_LPASS_IBIT_CLK_11_P2896_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, +}; + +static struct afe_clk_set lpass_default = { + Q6AFE_LPASS_CLK_CONFIG_API_VERSION, + Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR, + Q6AFE_LPASS_IBIT_CLK_11_P2896_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, +}; + +static struct afe_clk_set lpass_mclk = { + Q6AFE_LPASS_CLK_CONFIG_API_VERSION, + Q6AFE_LPASS_CLK_ID_MCLK_1, + Q6AFE_LPASS_OSR_CLK_11_P2896_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, +}; + +static inline struct audio_ext_ap_clk *to_audio_ap_clk(struct clk_hw *hw) +{ + return container_of(hw, struct audio_ext_ap_clk, fact.hw); +} + +static int audio_ext_clk_prepare(struct clk_hw *hw) +{ + struct audio_ext_ap_clk *audio_clk = to_audio_ap_clk(hw); + + pr_debug("%s: gpio: %d\n", __func__, audio_clk->gpio); + if (gpio_is_valid(audio_clk->gpio)) + return gpio_direction_output(audio_clk->gpio, 1); + return 0; +} + +static void audio_ext_clk_unprepare(struct clk_hw *hw) +{ + struct audio_ext_ap_clk *audio_clk = to_audio_ap_clk(hw); + + pr_debug("%s: gpio: %d\n", __func__, audio_clk->gpio); + if (gpio_is_valid(audio_clk->gpio)) + gpio_direction_output(audio_clk->gpio, 0); +} + +static inline struct audio_ext_ap_clk2 *to_audio_ap_clk2(struct clk_hw *hw) +{ + return container_of(hw, struct audio_ext_ap_clk2, fact.hw); +} + +static int audio_ext_clk2_prepare(struct clk_hw *hw) +{ + struct audio_ext_ap_clk2 *audio_clk2 = to_audio_ap_clk2(hw); + struct pinctrl_info *pnctrl_info = &audio_clk2->pnctrl_info; + int ret; + + + if (!pnctrl_info->pinctrl || !pnctrl_info->active) + return 0; + + ret = pinctrl_select_state(pnctrl_info->pinctrl, + pnctrl_info->active); + if (ret) { + pr_err("%s: active state select failed with %d\n", + __func__, ret); + return -EIO; + } + + clk2_config.enable = 1; + ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk2_config); + if (ret < 0) { + pr_err("%s: failed to set clock, ret = %d\n", __func__, ret); + return -EINVAL; + } + + return 0; +} + +static void audio_ext_clk2_unprepare(struct clk_hw *hw) +{ + struct audio_ext_ap_clk2 *audio_clk2 = to_audio_ap_clk2(hw); + struct pinctrl_info *pnctrl_info = &audio_clk2->pnctrl_info; + int ret; + + if (!pnctrl_info->pinctrl || !pnctrl_info->sleep) + return; + + ret = pinctrl_select_state(pnctrl_info->pinctrl, + pnctrl_info->sleep); + if (ret) + pr_err("%s: sleep state select failed with %d\n", + __func__, ret); + + clk2_config.enable = 0; + ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk2_config); + if (ret < 0) + pr_err("%s: failed to reset clock, ret = %d\n", __func__, ret); +} + +static inline struct audio_ext_lpass_mclk *to_audio_lpass_mclk( + struct clk_hw *hw) +{ + return container_of(hw, struct audio_ext_lpass_mclk, fact.hw); +} + +static int audio_ext_lpass_mclk_prepare(struct clk_hw *hw) +{ + struct audio_ext_lpass_mclk *audio_lpass_mclk = to_audio_lpass_mclk(hw); + struct pinctrl_info *pnctrl_info = &audio_lpass_mclk->pnctrl_info; + int ret; + + lpass_mclk.enable = 1; + ret = afe_set_lpass_clock_v2(AFE_PORT_ID_PRIMARY_MI2S_RX, + &lpass_mclk); + if (ret < 0) { + pr_err("%s afe_set_digital_codec_core_clock failed\n", + __func__); + return ret; + } + + if (pnctrl_info->pinctrl) { + ret = pinctrl_select_state(pnctrl_info->pinctrl, + pnctrl_info->active); + if (ret) { + pr_err("%s: active state select failed with %d\n", + __func__, ret); + return -EIO; + } + } + + if (pnctrl_info->base) + iowrite32(1, pnctrl_info->base); + return 0; +} + +static void audio_ext_lpass_mclk_unprepare(struct clk_hw *hw) +{ + struct audio_ext_lpass_mclk *audio_lpass_mclk = to_audio_lpass_mclk(hw); + struct pinctrl_info *pnctrl_info = &audio_lpass_mclk->pnctrl_info; + int ret; + + if (pnctrl_info->pinctrl) { + ret = pinctrl_select_state(pnctrl_info->pinctrl, + pnctrl_info->sleep); + if (ret) { + pr_err("%s: active state select failed with %d\n", + __func__, ret); + return; + } + } + + lpass_mclk.enable = 0; + ret = afe_set_lpass_clock_v2(AFE_PORT_ID_PRIMARY_MI2S_RX, + &lpass_mclk); + if (ret < 0) + pr_err("%s: afe_set_digital_codec_core_clock failed, ret = %d\n", + __func__, ret); + if (pnctrl_info->base) + iowrite32(0, pnctrl_info->base); +} + +static int audio_ext_lpass_mclk2_prepare(struct clk_hw *hw) +{ + struct audio_ext_lpass_mclk *audio_lpass_mclk2 = + to_audio_lpass_mclk(hw); + struct pinctrl_info *pnctrl_info = &audio_lpass_mclk2->pnctrl_info; + int ret; + + if (pnctrl_info->pinctrl) { + ret = pinctrl_select_state(pnctrl_info->pinctrl, + pnctrl_info->active); + if (ret) { + pr_err("%s: active state select failed with %d\n", + __func__, ret); + return -EIO; + } + } + + lpass_default.enable = 1; + ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &lpass_default); + if (ret < 0) { + pr_err("%s: failed to set clock, ret = %d\n", __func__, ret); + return -EINVAL; + } + + return 0; +} + +static void audio_ext_lpass_mclk2_unprepare(struct clk_hw *hw) +{ + struct audio_ext_lpass_mclk *audio_lpass_mclk2 = + to_audio_lpass_mclk(hw); + struct pinctrl_info *pnctrl_info = &audio_lpass_mclk2->pnctrl_info; + int ret; + + if (pnctrl_info->pinctrl) { + ret = pinctrl_select_state(pnctrl_info->pinctrl, + pnctrl_info->sleep); + if (ret) + pr_err("%s: sleep state select failed with %d\n", + __func__, ret); + } + + lpass_default.enable = 0; + ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &lpass_default); + if (ret < 0) + pr_err("%s: failed to reset clock, ret = %d\n", __func__, ret); +} + +static const struct clk_ops audio_ext_ap_clk_ops = { + .prepare = audio_ext_clk_prepare, + .unprepare = audio_ext_clk_unprepare, +}; + +static const struct clk_ops audio_ext_ap_clk2_ops = { + .prepare = audio_ext_clk2_prepare, + .unprepare = audio_ext_clk2_unprepare, +}; + +static const struct clk_ops audio_ext_lpass_mclk_ops = { + .prepare = audio_ext_lpass_mclk_prepare, + .unprepare = audio_ext_lpass_mclk_unprepare, +}; + +static const struct clk_ops audio_ext_lpass_mclk2_ops = { + .prepare = audio_ext_lpass_mclk2_prepare, + .unprepare = audio_ext_lpass_mclk2_unprepare, +}; + +static struct audio_ext_pmi_clk audio_pmi_clk = { + .gpio = -EINVAL, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_ext_pmi_clk", + .parent_names = (const char *[]){ "div_clk1" }, + .num_parents = 1, + .ops = &clk_dummy_ops, + }, + }, +}; + +static struct audio_ext_pmi_clk audio_pmi_lnbb_clk = { + .gpio = -EINVAL, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_ext_pmi_lnbb_clk", + .parent_names = (const char *[]){ "ln_bb_clk2" }, + .num_parents = 1, + .ops = &clk_dummy_ops, + }, + }, +}; + +static struct audio_ext_ap_clk audio_ap_clk = { + .gpio = -EINVAL, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_ap_clk", + .ops = &audio_ext_ap_clk_ops, + }, + }, +}; + +static struct audio_ext_ap_clk2 audio_ap_clk2 = { + .enabled = false, + .pnctrl_info = {NULL}, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_ap_clk2", + .ops = &audio_ext_ap_clk2_ops, + }, + }, +}; + +static struct audio_ext_lpass_mclk audio_lpass_mclk = { + .pnctrl_info = {NULL}, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_lpass_mclk", + .ops = &audio_ext_lpass_mclk_ops, + }, + }, +}; + +static struct audio_ext_lpass_mclk audio_lpass_mclk2 = { + .pnctrl_info = {NULL}, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_lpass_mclk2", + .ops = &audio_ext_lpass_mclk2_ops, + }, + }, +}; + +static struct clk_hw *audio_msm_hws[] = { + &audio_pmi_clk.fact.hw, + &audio_ap_clk.fact.hw, + &audio_ap_clk2.fact.hw, + &audio_lpass_mclk.fact.hw, + &audio_lpass_mclk2.fact.hw, +}; + +static struct clk_hw *audio_msm_hws1[] = { + &audio_pmi_lnbb_clk.fact.hw, +}; + +static int audio_get_pinctrl(struct platform_device *pdev, + enum audio_clk_mux mux) +{ + struct device *dev = &pdev->dev; + struct pinctrl_info *pnctrl_info; + struct pinctrl *pinctrl; + int ret; + u32 reg; + + switch (mux) { + case AP_CLK2: + pnctrl_info = &audio_ap_clk2.pnctrl_info; + break; + case LPASS_MCLK: + pnctrl_info = &audio_lpass_mclk.pnctrl_info; + break; + case LPASS_MCLK2: + pnctrl_info = &audio_lpass_mclk2.pnctrl_info; + break; + default: + dev_err(dev, "%s Not a valid MUX ID: %d\n", + __func__, mux); + return -EINVAL; + } + + if (pnctrl_info->pinctrl) { + dev_dbg(dev, "%s: already requested before\n", + __func__); + return -EINVAL; + } + + pinctrl = devm_pinctrl_get(dev); + if (IS_ERR_OR_NULL(pinctrl)) { + dev_dbg(dev, "%s: Unable to get pinctrl handle\n", + __func__); + return -EINVAL; + } + pnctrl_info->pinctrl = pinctrl; + /* get all state handles from Device Tree */ + pnctrl_info->sleep = pinctrl_lookup_state(pinctrl, "sleep"); + if (IS_ERR(pnctrl_info->sleep)) { + dev_err(dev, "%s: could not get sleep pinstate\n", + __func__); + goto err; + } + pnctrl_info->active = pinctrl_lookup_state(pinctrl, "active"); + if (IS_ERR(pnctrl_info->active)) { + dev_err(dev, "%s: could not get active pinstate\n", + __func__); + goto err; + } + /* Reset the TLMM pins to a default state */ + ret = pinctrl_select_state(pnctrl_info->pinctrl, + pnctrl_info->sleep); + if (ret) { + dev_err(dev, "%s: Disable TLMM pins failed with %d\n", + __func__, ret); + goto err; + } + + ret = of_property_read_u32(dev->of_node, "qcom,mclk-clk-reg", ®); + if (ret < 0) { + dev_dbg(dev, "%s: miss mclk reg\n", __func__); + } else { + pnctrl_info->base = ioremap(reg, sizeof(u32)); + if (pnctrl_info->base == NULL) { + dev_err(dev, "%s ioremap failed\n", __func__); + goto err; + } + } + + return 0; + +err: + devm_pinctrl_put(pnctrl_info->pinctrl); + return -EINVAL; +} + +static int audio_ref_clk_probe(struct platform_device *pdev) +{ + int clk_gpio; + int ret; + u32 mclk_freq; + struct clk *audio_clk; + struct device *dev = &pdev->dev; + int i; + struct clk_onecell_data *clk_data; + + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,codec-mclk-clk-freq", + &mclk_freq); + if (!ret) { + lpass_mclk.clk_freq_in_hz = mclk_freq; + + ret = audio_get_pinctrl(pdev, LPASS_MCLK); + if (ret) + dev_err(&pdev->dev, "%s: Parsing pinctrl %s failed\n", + __func__, "LPASS_MCLK"); + ret = audio_get_pinctrl(pdev, LPASS_MCLK2); + if (ret) + dev_dbg(&pdev->dev, "%s: Parsing pinctrl %s failed\n", + __func__, "LPASS_MCLK2"); + } + + clk_gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,audio-ref-clk-gpio", 0); + if (clk_gpio > 0) { + ret = gpio_request(clk_gpio, "EXT_CLK"); + if (ret) { + dev_err(&pdev->dev, + "Request ext clk gpio failed %d, err:%d\n", + clk_gpio, ret); + goto err; + } + if (of_property_read_bool(pdev->dev.of_node, + "qcom,node_has_rpm_clock")) { + audio_pmi_clk.gpio = clk_gpio; + } else + audio_ap_clk.gpio = clk_gpio; + + } + + ret = audio_get_pinctrl(pdev, AP_CLK2); + if (ret) + dev_dbg(&pdev->dev, "%s: Parsing pinctrl failed\n", + __func__); + + clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL); + if (!clk_data) + goto err_gpio; + + + clk_gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,audio-ref-clk-gpio", 0); + if (clk_gpio > 0) { + clk_data->clk_num = ARRAY_SIZE(audio_msm_hws); + clk_data->clks = devm_kzalloc(&pdev->dev, + clk_data->clk_num * + sizeof(struct clk *), + GFP_KERNEL); + if (!clk_data->clks) + goto err_clk; + + for (i = 0; i < ARRAY_SIZE(audio_msm_hws); i++) { + audio_clk = devm_clk_register(dev, audio_msm_hws[i]); + if (IS_ERR(audio_clk)) { + dev_err(&pdev->dev, + "%s: ref clock: %d register failed\n", + __func__, i); + return PTR_ERR(audio_clk); + } + clk_data->clks[i] = audio_clk; + } + } else { + clk_data->clk_num = ARRAY_SIZE(audio_msm_hws1); + clk_data->clks = devm_kzalloc(&pdev->dev, + clk_data->clk_num * + sizeof(struct clk *), + GFP_KERNEL); + if (!clk_data->clks) + goto err_clk; + + for (i = 0; i < ARRAY_SIZE(audio_msm_hws1); i++) { + audio_clk = devm_clk_register(dev, audio_msm_hws1[i]); + if (IS_ERR(audio_clk)) { + dev_err(&pdev->dev, + "%s: ref clock: %d register failed\n", + __func__, i); + return PTR_ERR(audio_clk); + } + clk_data->clks[i] = audio_clk; + } + } + + ret = of_clk_add_provider(pdev->dev.of_node, + of_clk_src_onecell_get, clk_data); + if (ret) { + dev_err(&pdev->dev, "%s: audio ref clock register failed\n", + __func__); + goto err_gpio; + } + + return 0; + +err_clk: + if (clk_data) + devm_kfree(&pdev->dev, clk_data->clks); + devm_kfree(&pdev->dev, clk_data); +err_gpio: + gpio_free(clk_gpio); + +err: + return ret; +} + +static int audio_ref_clk_remove(struct platform_device *pdev) +{ + struct pinctrl_info *pnctrl_info = &audio_ap_clk2.pnctrl_info; + + if (audio_pmi_clk.gpio > 0) + gpio_free(audio_pmi_clk.gpio); + else if (audio_ap_clk.gpio > 0) + gpio_free(audio_ap_clk.gpio); + + if (pnctrl_info->pinctrl) { + devm_pinctrl_put(pnctrl_info->pinctrl); + pnctrl_info->pinctrl = NULL; + } + + return 0; +} + +static const struct of_device_id audio_ref_clk_match[] = { + {.compatible = "qcom,audio-ref-clk"}, + {} +}; +MODULE_DEVICE_TABLE(of, audio_ref_clk_match); + +static struct platform_driver audio_ref_clk_driver = { + .driver = { + .name = "audio-ref-clk", + .owner = THIS_MODULE, + .of_match_table = audio_ref_clk_match, + }, + .probe = audio_ref_clk_probe, + .remove = audio_ref_clk_remove, +}; + +int audio_ref_clk_platform_init(void) +{ + return platform_driver_register(&audio_ref_clk_driver); +} + +void audio_ref_clk_platform_exit(void) +{ + platform_driver_unregister(&audio_ref_clk_driver); +} + +MODULE_DESCRIPTION("Audio Ref Up Clock module platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/audio-ext-clk-up.h b/sound/soc/codecs/audio-ext-clk-up.h new file mode 100644 index 000000000000..8a0232e11d0f --- /dev/null +++ b/sound/soc/codecs/audio-ext-clk-up.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __AUDIO_EXT_CLK_UP_H_ +#define __AUDIO_EXT_CLK_UP_H_ + +int audio_ref_clk_platform_init(void); +void audio_ref_clk_platform_exit(void); + +#endif diff --git a/sound/soc/codecs/audio-ext-clk.c b/sound/soc/codecs/audio-ext-clk.c new file mode 100644 index 000000000000..72f16f5848dd --- /dev/null +++ b/sound/soc/codecs/audio-ext-clk.c @@ -0,0 +1,348 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "audio-ext-clk-up.h" + +struct pinctrl_info { + struct pinctrl *pinctrl; + struct pinctrl_state *sleep; + struct pinctrl_state *active; +}; + +struct audio_ext_ap_clk { + bool enabled; + int gpio; + struct clk c; +}; + +struct audio_ext_pmi_clk { + int gpio; + struct clk c; +}; + +struct audio_ext_ap_clk2 { + bool enabled; + struct pinctrl_info pnctrl_info; + struct clk c; +}; + +static struct afe_clk_set clk2_config = { + Q6AFE_LPASS_CLK_CONFIG_API_VERSION, + Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR, + Q6AFE_LPASS_IBIT_CLK_11_P2896_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, +}; + +static inline struct audio_ext_ap_clk *to_audio_ap_clk(struct clk *clk) +{ + return container_of(clk, struct audio_ext_ap_clk, c); +} + +static int audio_ext_clk_prepare(struct clk *clk) +{ + struct audio_ext_ap_clk *audio_clk = to_audio_ap_clk(clk); + + pr_debug("%s: gpio: %d\n", __func__, audio_clk->gpio); + if (gpio_is_valid(audio_clk->gpio)) + return gpio_direction_output(audio_clk->gpio, 1); + return 0; +} + +static void audio_ext_clk_unprepare(struct clk *clk) +{ + struct audio_ext_ap_clk *audio_clk = to_audio_ap_clk(clk); + + pr_debug("%s: gpio: %d\n", __func__, audio_clk->gpio); + if (gpio_is_valid(audio_clk->gpio)) + gpio_direction_output(audio_clk->gpio, 0); +} + +static inline struct audio_ext_ap_clk2 *to_audio_ap_clk2(struct clk *clk) +{ + return container_of(clk, struct audio_ext_ap_clk2, c); +} + +static int audio_ext_clk2_prepare(struct clk *clk) +{ + struct audio_ext_ap_clk2 *audio_clk2 = to_audio_ap_clk2(clk); + struct pinctrl_info *pnctrl_info = &audio_clk2->pnctrl_info; + int ret; + + + if (!pnctrl_info->pinctrl || !pnctrl_info->active) + return 0; + + ret = pinctrl_select_state(pnctrl_info->pinctrl, + pnctrl_info->active); + if (ret) { + pr_err("%s: active state select failed with %d\n", + __func__, ret); + return -EIO; + } + + clk2_config.enable = 1; + ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk2_config); + if (ret < 0) { + pr_err("%s: failed to set clock, ret = %d\n", __func__, ret); + return -EINVAL; + } + + return 0; +} + +static void audio_ext_clk2_unprepare(struct clk *clk) +{ + struct audio_ext_ap_clk2 *audio_clk2 = to_audio_ap_clk2(clk); + struct pinctrl_info *pnctrl_info = &audio_clk2->pnctrl_info; + int ret; + + if (!pnctrl_info->pinctrl || !pnctrl_info->sleep) + return; + + ret = pinctrl_select_state(pnctrl_info->pinctrl, + pnctrl_info->sleep); + if (ret) + pr_err("%s: sleep state select failed with %d\n", + __func__, ret); + + clk2_config.enable = 0; + ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk2_config); + if (ret < 0) + pr_err("%s: failed to reset clock, ret = %d\n", __func__, ret); +} + +static const struct clk_ops audio_ext_ap_clk_ops = { + .prepare = audio_ext_clk_prepare, + .unprepare = audio_ext_clk_unprepare, +}; + +static const struct clk_ops audio_ext_ap_clk2_ops = { + .prepare = audio_ext_clk2_prepare, + .unprepare = audio_ext_clk2_unprepare, +}; + +static struct audio_ext_pmi_clk audio_pmi_clk = { + .gpio = -EINVAL, + .c = { + .dbg_name = "audio_ext_pmi_clk", + .ops = &clk_ops_dummy, + CLK_INIT(audio_pmi_clk.c), + }, +}; + +static struct audio_ext_pmi_clk audio_pmi_lnbb_clk = { + .gpio = -EINVAL, + .c = { + .dbg_name = "audio_ext_pmi_lnbb_clk", + .ops = &clk_ops_dummy, + CLK_INIT(audio_pmi_lnbb_clk.c), + }, +}; + +static struct audio_ext_ap_clk audio_ap_clk = { + .gpio = -EINVAL, + .c = { + .dbg_name = "audio_ext_ap_clk", + .ops = &audio_ext_ap_clk_ops, + CLK_INIT(audio_ap_clk.c), + }, +}; + +static struct audio_ext_ap_clk2 audio_ap_clk2 = { + .c = { + .dbg_name = "audio_ext_ap_clk2", + .ops = &audio_ext_ap_clk2_ops, + CLK_INIT(audio_ap_clk2.c), + }, +}; + +static struct clk_lookup audio_ref_clock[] = { + CLK_LIST(audio_ap_clk), + CLK_LIST(audio_pmi_clk), + CLK_LIST(audio_pmi_lnbb_clk), + CLK_LIST(audio_ap_clk2), +}; + +static int audio_get_pinctrl(struct platform_device *pdev) +{ + struct pinctrl_info *pnctrl_info; + struct pinctrl *pinctrl; + int ret; + + pnctrl_info = &audio_ap_clk2.pnctrl_info; + + if (pnctrl_info->pinctrl) { + dev_dbg(&pdev->dev, "%s: already requested before\n", + __func__); + return -EINVAL; + } + + pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR_OR_NULL(pinctrl)) { + dev_dbg(&pdev->dev, "%s: Unable to get pinctrl handle\n", + __func__); + return -EINVAL; + } + pnctrl_info->pinctrl = pinctrl; + /* get all state handles from Device Tree */ + pnctrl_info->sleep = pinctrl_lookup_state(pinctrl, "sleep"); + if (IS_ERR(pnctrl_info->sleep)) { + dev_err(&pdev->dev, "%s: could not get sleep pinstate\n", + __func__); + goto err; + } + pnctrl_info->active = pinctrl_lookup_state(pinctrl, "active"); + if (IS_ERR(pnctrl_info->active)) { + dev_err(&pdev->dev, "%s: could not get active pinstate\n", + __func__); + goto err; + } + /* Reset the TLMM pins to a default state */ + ret = pinctrl_select_state(pnctrl_info->pinctrl, + pnctrl_info->sleep); + if (ret) { + dev_err(&pdev->dev, "%s: Disable TLMM pins failed with %d\n", + __func__, ret); + goto err; + } + return 0; + +err: + devm_pinctrl_put(pnctrl_info->pinctrl); + return -EINVAL; +} + +static int audio_ref_clk_probe(struct platform_device *pdev) +{ + int clk_gpio; + int ret; + struct clk *audio_clk; + + clk_gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,audio-ref-clk-gpio", 0); + if (clk_gpio > 0) { + ret = gpio_request(clk_gpio, "EXT_CLK"); + if (ret) { + dev_err(&pdev->dev, + "Request ext clk gpio failed %d, err:%d\n", + clk_gpio, ret); + goto err; + } + if (of_property_read_bool(pdev->dev.of_node, + "qcom,node_has_rpm_clock")) { + audio_clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(audio_clk)) { + dev_err(&pdev->dev, "Failed to get RPM div clk\n"); + ret = PTR_ERR(audio_clk); + goto err_gpio; + } + audio_pmi_clk.c.parent = audio_clk; + audio_pmi_clk.gpio = clk_gpio; + } else + audio_ap_clk.gpio = clk_gpio; + + } else { + if (of_property_read_bool(pdev->dev.of_node, + "qcom,node_has_rpm_clock")) { + audio_clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(audio_clk)) { + dev_err(&pdev->dev, "Failed to get lnbbclk2\n"); + ret = PTR_ERR(audio_clk); + goto err; + } + audio_pmi_lnbb_clk.c.parent = audio_clk; + audio_pmi_lnbb_clk.gpio = -EINVAL; + } + } + + ret = audio_get_pinctrl(pdev); + if (ret) + dev_dbg(&pdev->dev, "%s: Parsing pinctrl failed\n", + __func__); + + ret = of_msm_clock_register(pdev->dev.of_node, audio_ref_clock, + ARRAY_SIZE(audio_ref_clock)); + if (ret) { + dev_err(&pdev->dev, "%s: audio ref clock register failed\n", + __func__); + goto err_gpio; + } + + return 0; + +err_gpio: + gpio_free(clk_gpio); + +err: + return ret; +} + +static int audio_ref_clk_remove(struct platform_device *pdev) +{ + struct pinctrl_info *pnctrl_info = &audio_ap_clk2.pnctrl_info; + + if (audio_pmi_clk.gpio > 0) + gpio_free(audio_pmi_clk.gpio); + else if (audio_ap_clk.gpio > 0) + gpio_free(audio_ap_clk.gpio); + + if (pnctrl_info->pinctrl) { + devm_pinctrl_put(pnctrl_info->pinctrl); + pnctrl_info->pinctrl = NULL; + } + + return 0; +} + +static const struct of_device_id audio_ref_clk_match[] = { + {.compatible = "qcom,audio-ref-clk"}, + {} +}; +MODULE_DEVICE_TABLE(of, audio_ref_clk_match); + +static struct platform_driver audio_ref_clk_driver = { + .driver = { + .name = "audio-ref-clk", + .owner = THIS_MODULE, + .of_match_table = audio_ref_clk_match, + }, + .probe = audio_ref_clk_probe, + .remove = audio_ref_clk_remove, +}; + +int audio_ref_clk_platform_init(void) +{ + return platform_driver_register(&audio_ref_clk_driver); +} + +void audio_ref_clk_platform_exit(void) +{ + platform_driver_unregister(&audio_ref_clk_driver); +} + +MODULE_DESCRIPTION("Audio Ref Clock module platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/msm_stub.c b/sound/soc/codecs/msm_stub.c new file mode 100644 index 000000000000..68e55ae1da16 --- /dev/null +++ b/sound/soc/codecs/msm_stub.c @@ -0,0 +1,88 @@ +/* Copyright (c) 2011-2014, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include + +/* A dummy driver useful only to advertise hardware parameters */ +static struct snd_soc_dai_driver msm_stub_dais[] = { + { + .name = "msm-stub-rx", + .playback = { /* Support maximum range */ + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + }, + { + .name = "msm-stub-tx", + .capture = { /* Support maximum range */ + .stream_name = "Record", + .channels_min = 1, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + }, + }, +}; + +static struct snd_soc_codec_driver soc_msm_stub = {}; + +static int msm_stub_dev_probe(struct platform_device *pdev) +{ + dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev)); + + return snd_soc_register_codec(&pdev->dev, + &soc_msm_stub, msm_stub_dais, ARRAY_SIZE(msm_stub_dais)); +} + +static int msm_stub_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_codec(&pdev->dev); + return 0; +} +static const struct of_device_id msm_stub_codec_dt_match[] = { + { .compatible = "qcom,msm-stub-codec", }, + {} +}; + +static struct platform_driver msm_stub_driver = { + .driver = { + .name = "msm-stub-codec", + .owner = THIS_MODULE, + .of_match_table = msm_stub_codec_dt_match, + }, + .probe = msm_stub_dev_probe, + .remove = msm_stub_dev_remove, +}; + +static int __init msm_stub_init(void) +{ + return platform_driver_register(&msm_stub_driver); +} +module_init(msm_stub_init); + +static void __exit msm_stub_exit(void) +{ + platform_driver_unregister(&msm_stub_driver); +} +module_exit(msm_stub_exit); + +MODULE_DESCRIPTION("Generic MSM CODEC driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/sdm660_cdc/Kconfig b/sound/soc/codecs/sdm660_cdc/Kconfig new file mode 100644 index 000000000000..2f36c393a65b --- /dev/null +++ b/sound/soc/codecs/sdm660_cdc/Kconfig @@ -0,0 +1,5 @@ + +config SND_SOC_SDM660_CDC + tristate "MSM Internal PMIC based codec" + select SND_SOC_WCD_MBHC + select SND_SOC_WCD_MBHC_LEGACY diff --git a/sound/soc/codecs/sdm660_cdc/Makefile b/sound/soc/codecs/sdm660_cdc/Makefile new file mode 100644 index 000000000000..d846fae26054 --- /dev/null +++ b/sound/soc/codecs/sdm660_cdc/Makefile @@ -0,0 +1,2 @@ +snd-soc-sdm660-cdc-objs := msm-analog-cdc.o msm-digital-cdc.o sdm660-regmap.o +obj-$(CONFIG_SND_SOC_SDM660_CDC) += snd-soc-sdm660-cdc.o sdm660-cdc-irq.o diff --git a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c new file mode 100644 index 000000000000..a8fcd347b38b --- /dev/null +++ b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c @@ -0,0 +1,4683 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm-analog-cdc.h" +#include "sdm660-cdc-irq.h" +#include "sdm660-cdc-registers.h" +#include "msm-cdc-common.h" +#include "../../msm/sdm660-common.h" +#include "../wcd-mbhc-v2-api.h" + +#define DRV_NAME "pmic_analog_codec" +#define SDM660_CDC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_192000) +#define SDM660_CDC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE) +#define MSM_DIG_CDC_STRING_LEN 80 +#define MSM_ANLG_CDC_VERSION_ENTRY_SIZE 32 + +#define CODEC_DT_MAX_PROP_SIZE 40 +#define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64 +#define BUS_DOWN 1 + +/* + * 50 Milliseconds sufficient for DSP bring up in the lpass + * after Sub System Restart + */ +#define ADSP_STATE_READY_TIMEOUT_MS 50 + +#define EAR_PMD 0 +#define EAR_PMU 1 +#define SPK_PMD 2 +#define SPK_PMU 3 + +#define MICBIAS_DEFAULT_VAL 1800000 +#define MICBIAS_MIN_VAL 1600000 +#define MICBIAS_STEP_SIZE 50000 + +#define DEFAULT_BOOST_VOLTAGE 5000 +#define MIN_BOOST_VOLTAGE 4000 +#define MAX_BOOST_VOLTAGE 5550 +#define BOOST_VOLTAGE_STEP 50 + +#define SDM660_CDC_MBHC_BTN_COARSE_ADJ 100 /* in mV */ +#define SDM660_CDC_MBHC_BTN_FINE_ADJ 12 /* in mV */ + +#define VOLTAGE_CONVERTER(value, min_value, step_size)\ + ((value - min_value)/step_size) + +enum { + BOOST_SWITCH = 0, + BOOST_ALWAYS, + BYPASS_ALWAYS, + BOOST_ON_FOREVER, +}; + +static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); +static struct snd_soc_dai_driver msm_anlg_cdc_i2s_dai[]; +/* By default enable the internal speaker boost */ +static bool spkr_boost_en = true; + +static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = { + "cdc-vdd-mic-bias", +}; + +static struct wcd_mbhc_register + wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = { + WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_DET_EN", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MECH_DETECTION_TYPE", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_CLAMP_CTL", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x18, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_DETECTION_TYPE", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_CTRL", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PLUG_TYPE", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_PLUG_TYPE", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SW_HPH_LP_100K_TO_GND", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_SCHMT_ISRC", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x06, 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_EN", + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_INSREM_DBNC", + MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, 0xF0, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_DBNC", + MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, 0x0C, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_VREF", + MSM89XX_PMIC_ANALOG_MBHC_BTN3_CTL, 0x03, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT", + MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x01, + 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT", + MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x02, + 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT", + MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x08, + 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_SCHMT_RESULT", + MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x04, + 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_OCP_FSM_EN", + MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_RESULT", + MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT, 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_ISRC_CTL", + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT", + MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0xFF, + 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL", + MSM89XX_PMIC_ANALOG_MICB_2_EN, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME", + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME, 0xFC, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN", + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PA_EN", + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_PA_EN", + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, 0x30, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE", + MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, + 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL", + MSM89XX_PMIC_ANALOG_MICB_2_EN, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN", 0, 0, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_STATUS", 0, 0, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL", 0, 0, 0, 0), +}; + +/* Multiply gain_adj and offset by 1000 and 100 to avoid float arithmetic */ +static const struct wcd_imped_i_ref imped_i_ref[] = { + {I_h4_UA, 8, 800, 9000, 10000}, + {I_pt5_UA, 10, 100, 990, 4600}, + {I_14_UA, 17, 14, 1050, 700}, + {I_l4_UA, 10, 4, 1165, 110}, + {I_1_UA, 0, 1, 1200, 65}, +}; + +static const struct wcd_mbhc_intr intr_ids = { + .mbhc_sw_intr = MSM89XX_IRQ_MBHC_HS_DET, + .mbhc_btn_press_intr = MSM89XX_IRQ_MBHC_PRESS, + .mbhc_btn_release_intr = MSM89XX_IRQ_MBHC_RELEASE, + .mbhc_hs_ins_intr = MSM89XX_IRQ_MBHC_INSREM_DET1, + .mbhc_hs_rem_intr = MSM89XX_IRQ_MBHC_INSREM_DET, + .hph_left_ocp = MSM89XX_IRQ_HPHL_OCP, + .hph_right_ocp = MSM89XX_IRQ_HPHR_OCP, +}; + +static int msm_anlg_cdc_dt_parse_vreg_info(struct device *dev, + struct sdm660_cdc_regulator *vreg, + const char *vreg_name, + bool ondemand); +static struct sdm660_cdc_pdata *msm_anlg_cdc_populate_dt_pdata( + struct device *dev); +static int msm_anlg_cdc_enable_ext_mb_source(struct wcd_mbhc *wcd_mbhc, + bool turn_on); +static void msm_anlg_cdc_trim_btn_reg(struct snd_soc_codec *codec); +static void msm_anlg_cdc_set_micb_v(struct snd_soc_codec *codec); +static void msm_anlg_cdc_set_boost_v(struct snd_soc_codec *codec); +static void msm_anlg_cdc_set_auto_zeroing(struct snd_soc_codec *codec, + bool enable); +static void msm_anlg_cdc_configure_cap(struct snd_soc_codec *codec, + bool micbias1, bool micbias2); +static bool msm_anlg_cdc_use_mb(struct snd_soc_codec *codec); + +static int get_codec_version(struct sdm660_cdc_priv *sdm660_cdc) +{ + if (sdm660_cdc->codec_version == DRAX_CDC) + return DRAX_CDC; + else if (sdm660_cdc->codec_version == DIANGU) + return DIANGU; + else if (sdm660_cdc->codec_version == CAJON_2_0) + return CAJON_2_0; + else if (sdm660_cdc->codec_version == CAJON) + return CAJON; + else if (sdm660_cdc->codec_version == CONGA) + return CONGA; + else if (sdm660_cdc->pmic_rev == TOMBAK_2_0) + return TOMBAK_2_0; + else if (sdm660_cdc->pmic_rev == TOMBAK_1_0) + return TOMBAK_1_0; + + pr_err("%s: unsupported codec version\n", __func__); + return UNSUPPORTED; +} + +static void wcd_mbhc_meas_imped(struct snd_soc_codec *codec, + s16 *impedance_l, s16 *impedance_r) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + if ((sdm660_cdc->imped_det_pin == WCD_MBHC_DET_BOTH) || + (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHL)) { + /* Enable ZDET_L_MEAS_EN */ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x08, 0x08); + /* Wait for 2ms for measurement to complete */ + usleep_range(2000, 2100); + /* Read Left impedance value from Result1 */ + *impedance_l = snd_soc_read(codec, + MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT); + /* Enable ZDET_R_MEAS_EN */ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x08, 0x00); + } + if ((sdm660_cdc->imped_det_pin == WCD_MBHC_DET_BOTH) || + (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHR)) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x04, 0x04); + /* Wait for 2ms for measurement to complete */ + usleep_range(2000, 2100); + /* Read Right impedance value from Result1 */ + *impedance_r = snd_soc_read(codec, + MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x04, 0x00); + } +} + +static void msm_anlg_cdc_set_ref_current(struct snd_soc_codec *codec, + enum wcd_curr_ref curr_ref) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: curr_ref: %d\n", __func__, curr_ref); + + if (get_codec_version(sdm660_cdc) < CAJON) + dev_dbg(codec->dev, "%s: Setting ref current not required\n", + __func__); + + sdm660_cdc->imped_i_ref = imped_i_ref[curr_ref]; + + switch (curr_ref) { + case I_h4_UA: + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MICB_2_EN, + 0x07, 0x01); + break; + case I_pt5_UA: + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MICB_2_EN, + 0x07, 0x04); + break; + case I_14_UA: + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MICB_2_EN, + 0x07, 0x03); + break; + case I_l4_UA: + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MICB_2_EN, + 0x07, 0x01); + break; + case I_1_UA: + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MICB_2_EN, + 0x07, 0x00); + break; + default: + pr_debug("%s: No ref current set\n", __func__); + break; + } +} + +static bool msm_anlg_cdc_adj_ref_current(struct snd_soc_codec *codec, + s16 *impedance_l, s16 *impedance_r) +{ + int i = 2; + s16 compare_imp = 0; + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHR) + compare_imp = *impedance_r; + else + compare_imp = *impedance_l; + + if (get_codec_version(sdm660_cdc) < CAJON) { + dev_dbg(codec->dev, + "%s: Reference current adjustment not required\n", + __func__); + return false; + } + + while (compare_imp < imped_i_ref[i].min_val) { + msm_anlg_cdc_set_ref_current(codec, imped_i_ref[++i].curr_ref); + wcd_mbhc_meas_imped(codec, impedance_l, impedance_r); + compare_imp = (sdm660_cdc->imped_det_pin == + WCD_MBHC_DET_HPHR) ? *impedance_r : *impedance_l; + if (i >= I_1_UA) + break; + } + return true; +} + +void msm_anlg_cdc_spk_ext_pa_cb( + int (*codec_spk_ext_pa)(struct snd_soc_codec *codec, + int enable), struct snd_soc_codec *codec) +{ + struct sdm660_cdc_priv *sdm660_cdc; + + if (!codec) { + pr_err("%s: NULL codec pointer!\n", __func__); + return; + } + + sdm660_cdc = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: Enter\n", __func__); + sdm660_cdc->codec_spk_ext_pa_cb = codec_spk_ext_pa; +} + +static void msm_anlg_cdc_compute_impedance(struct snd_soc_codec *codec, s16 l, + s16 r, uint32_t *zl, uint32_t *zr, + bool high) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + uint32_t rl = 0, rr = 0; + struct wcd_imped_i_ref R = sdm660_cdc->imped_i_ref; + int codec_ver = get_codec_version(sdm660_cdc); + + switch (codec_ver) { + case TOMBAK_1_0: + case TOMBAK_2_0: + case CONGA: + if (high) { + dev_dbg(codec->dev, + "%s: This plug has high range impedance\n", + __func__); + rl = (uint32_t)(((100 * (l * 400 - 200))/96) - 230); + rr = (uint32_t)(((100 * (r * 400 - 200))/96) - 230); + } else { + dev_dbg(codec->dev, + "%s: This plug has low range impedance\n", + __func__); + rl = (uint32_t)(((1000 * (l * 2 - 1))/1165) - (13/10)); + rr = (uint32_t)(((1000 * (r * 2 - 1))/1165) - (13/10)); + } + break; + case CAJON: + case CAJON_2_0: + case DIANGU: + case DRAX_CDC: + if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHL) { + rr = (uint32_t)(((DEFAULT_MULTIPLIER * (10 * r - 5)) - + (DEFAULT_OFFSET * DEFAULT_GAIN))/DEFAULT_GAIN); + rl = (uint32_t)(((10000 * (R.multiplier * (10 * l - 5))) + - R.offset * R.gain_adj)/(R.gain_adj * 100)); + } else if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHR) { + rr = (uint32_t)(((10000 * (R.multiplier * (10 * r - 5))) + - R.offset * R.gain_adj)/(R.gain_adj * 100)); + rl = (uint32_t)(((DEFAULT_MULTIPLIER * (10 * l - 5))- + (DEFAULT_OFFSET * DEFAULT_GAIN))/DEFAULT_GAIN); + } else if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_NONE) { + rr = (uint32_t)(((DEFAULT_MULTIPLIER * (10 * r - 5)) - + (DEFAULT_OFFSET * DEFAULT_GAIN))/DEFAULT_GAIN); + rl = (uint32_t)(((DEFAULT_MULTIPLIER * (10 * l - 5))- + (DEFAULT_OFFSET * DEFAULT_GAIN))/DEFAULT_GAIN); + } else { + rr = (uint32_t)(((10000 * (R.multiplier * (10 * r - 5))) + - R.offset * R.gain_adj)/(R.gain_adj * 100)); + rl = (uint32_t)(((10000 * (R.multiplier * (10 * l - 5))) + - R.offset * R.gain_adj)/(R.gain_adj * 100)); + } + break; + default: + dev_dbg(codec->dev, "%s: No codec mentioned\n", __func__); + break; + } + *zl = rl; + *zr = rr; +} + +static struct firmware_cal *msm_anlg_cdc_get_hwdep_fw_cal( + struct wcd_mbhc *wcd_mbhc, + enum wcd_cal_type type) +{ + struct sdm660_cdc_priv *sdm660_cdc; + struct firmware_cal *hwdep_cal; + struct snd_soc_codec *codec = wcd_mbhc->codec; + + if (!codec) { + pr_err("%s: NULL codec pointer\n", __func__); + return NULL; + } + sdm660_cdc = snd_soc_codec_get_drvdata(codec); + hwdep_cal = wcdcal_get_fw_cal(sdm660_cdc->fw_data, type); + if (!hwdep_cal) { + dev_err(codec->dev, "%s: cal not sent by %d\n", + __func__, type); + return NULL; + } + return hwdep_cal; +} + +static void wcd9xxx_spmi_irq_control(struct snd_soc_codec *codec, + int irq, bool enable) +{ + if (enable) + wcd9xxx_spmi_enable_irq(irq); + else + wcd9xxx_spmi_disable_irq(irq); +} + +static void msm_anlg_cdc_mbhc_clk_setup(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x08, 0x08); + else + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x08, 0x00); +} + +static int msm_anlg_cdc_mbhc_map_btn_code_to_num(struct snd_soc_codec *codec) +{ + int btn_code; + int btn; + + btn_code = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT); + + switch (btn_code) { + case 0: + btn = 0; + break; + case 1: + btn = 1; + break; + case 3: + btn = 2; + break; + case 7: + btn = 3; + break; + case 15: + btn = 4; + break; + default: + btn = -EINVAL; + break; + }; + + return btn; +} + +static bool msm_anlg_cdc_spmi_lock_sleep(struct wcd_mbhc *mbhc, bool lock) +{ + if (lock) + return wcd9xxx_spmi_lock_sleep(); + wcd9xxx_spmi_unlock_sleep(); + return 0; +} + +static bool msm_anlg_cdc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) +{ + if (micb_num == MIC_BIAS_1) + return (snd_soc_read(mbhc->codec, + MSM89XX_PMIC_ANALOG_MICB_1_EN) & + 0x80); + if (micb_num == MIC_BIAS_2) + return (snd_soc_read(mbhc->codec, + MSM89XX_PMIC_ANALOG_MICB_2_EN) & + 0x80); + return false; +} + +static void msm_anlg_cdc_enable_master_bias(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, + 0x30, 0x30); + else + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, + 0x30, 0x00); +} + +static void msm_anlg_cdc_mbhc_common_micb_ctrl(struct snd_soc_codec *codec, + int event, bool enable) +{ + u16 reg; + u8 mask; + u8 val; + + switch (event) { + case MBHC_COMMON_MICB_PRECHARGE: + reg = MSM89XX_PMIC_ANALOG_MICB_1_CTL; + mask = 0x60; + val = (enable ? 0x60 : 0x00); + break; + case MBHC_COMMON_MICB_SET_VAL: + reg = MSM89XX_PMIC_ANALOG_MICB_1_VAL; + mask = 0xFF; + val = (enable ? 0xC0 : 0x00); + break; + case MBHC_COMMON_MICB_TAIL_CURR: + reg = MSM89XX_PMIC_ANALOG_MICB_1_EN; + mask = 0x04; + val = (enable ? 0x04 : 0x00); + break; + default: + dev_err(codec->dev, + "%s: Invalid event received\n", __func__); + return; + }; + snd_soc_update_bits(codec, reg, mask, val); +} + +static void msm_anlg_cdc_mbhc_internal_micbias_ctrl(struct snd_soc_codec *codec, + int micbias_num, + bool enable) +{ + if (micbias_num == 1) { + if (enable) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS, + 0x10, 0x10); + else + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS, + 0x10, 0x00); + } +} + +static bool msm_anlg_cdc_mbhc_hph_pa_on_status(struct snd_soc_codec *codec) +{ + return (snd_soc_read(codec, MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN) & + 0x30) ? true : false; +} + +static void msm_anlg_cdc_mbhc_program_btn_thr(struct snd_soc_codec *codec, + s16 *btn_low, s16 *btn_high, + int num_btn, bool is_micbias) +{ + int i; + u32 course, fine, reg_val; + u16 reg_addr = MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL; + s16 *btn_voltage; + + btn_voltage = ((is_micbias) ? btn_high : btn_low); + + for (i = 0; i < num_btn; i++) { + course = (btn_voltage[i] / SDM660_CDC_MBHC_BTN_COARSE_ADJ); + fine = ((btn_voltage[i] % SDM660_CDC_MBHC_BTN_COARSE_ADJ) / + SDM660_CDC_MBHC_BTN_FINE_ADJ); + + reg_val = (course << 5) | (fine << 2); + snd_soc_update_bits(codec, reg_addr, 0xFC, reg_val); + dev_dbg(codec->dev, + "%s: course: %d fine: %d reg_addr: %x reg_val: %x\n", + __func__, course, fine, reg_addr, reg_val); + reg_addr++; + } +} + +static void msm_anlg_cdc_mbhc_calc_impedance(struct wcd_mbhc *mbhc, + uint32_t *zl, uint32_t *zr) +{ + struct snd_soc_codec *codec = mbhc->codec; + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + s16 impedance_l, impedance_r; + s16 impedance_l_fixed; + s16 reg0, reg1, reg2, reg3, reg4; + bool high = false; + bool min_range_used = false; + + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + reg0 = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER); + reg1 = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL); + reg2 = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2); + reg3 = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MICB_2_EN); + reg4 = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL); + + sdm660_cdc->imped_det_pin = WCD_MBHC_DET_BOTH; + mbhc->hph_type = WCD_MBHC_HPH_NONE; + + /* disable FSM and micbias and enable pullup*/ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x80, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MICB_2_EN, + 0xA5, 0x25); + /* + * Enable legacy electrical detection current sources + * and disable fast ramp and enable manual switching + * of extra capacitance + */ + dev_dbg(codec->dev, "%s: Setup for impedance det\n", __func__); + + msm_anlg_cdc_set_ref_current(codec, I_h4_UA); + + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, + 0x06, 0x02); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, + 0x02, 0x02); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL, + 0x02, 0x00); + + dev_dbg(codec->dev, "%s: Start performing impedance detection\n", + __func__); + + wcd_mbhc_meas_imped(codec, &impedance_l, &impedance_r); + + if (impedance_l > 2 || impedance_r > 2) { + high = true; + if (!mbhc->mbhc_cfg->mono_stero_detection) { + /* Set ZDET_CHG to 0 to discharge ramp */ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x02, 0x00); + /* wait 40ms for the discharge ramp to complete */ + usleep_range(40000, 40100); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, + 0x03, 0x00); + sdm660_cdc->imped_det_pin = (impedance_l > 2 && + impedance_r > 2) ? + WCD_MBHC_DET_NONE : + ((impedance_l > 2) ? + WCD_MBHC_DET_HPHR : + WCD_MBHC_DET_HPHL); + if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_NONE) + goto exit; + } else { + if (get_codec_version(sdm660_cdc) >= CAJON) { + if (impedance_l == 63 && impedance_r == 63) { + dev_dbg(codec->dev, + "%s: HPHL and HPHR are floating\n", + __func__); + sdm660_cdc->imped_det_pin = + WCD_MBHC_DET_NONE; + mbhc->hph_type = WCD_MBHC_HPH_NONE; + } else if (impedance_l == 63 + && impedance_r < 63) { + dev_dbg(codec->dev, + "%s: Mono HS with HPHL floating\n", + __func__); + sdm660_cdc->imped_det_pin = + WCD_MBHC_DET_HPHR; + mbhc->hph_type = WCD_MBHC_HPH_MONO; + } else if (impedance_r == 63 && + impedance_l < 63) { + dev_dbg(codec->dev, + "%s: Mono HS with HPHR floating\n", + __func__); + sdm660_cdc->imped_det_pin = + WCD_MBHC_DET_HPHL; + mbhc->hph_type = WCD_MBHC_HPH_MONO; + } else if (impedance_l > 3 && impedance_r > 3 && + (impedance_l == impedance_r)) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, + 0x06, 0x06); + wcd_mbhc_meas_imped(codec, &impedance_l, + &impedance_r); + if (impedance_r == impedance_l) + dev_dbg(codec->dev, + "%s: Mono Headset\n", + __func__); + sdm660_cdc->imped_det_pin = + WCD_MBHC_DET_NONE; + mbhc->hph_type = + WCD_MBHC_HPH_MONO; + } else { + dev_dbg(codec->dev, + "%s: STEREO headset is found\n", + __func__); + sdm660_cdc->imped_det_pin = + WCD_MBHC_DET_BOTH; + mbhc->hph_type = WCD_MBHC_HPH_STEREO; + } + } + } + } + + msm_anlg_cdc_set_ref_current(codec, I_pt5_UA); + msm_anlg_cdc_set_ref_current(codec, I_14_UA); + + /* Enable RAMP_L , RAMP_R & ZDET_CHG*/ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, + 0x03, 0x03); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x02, 0x02); + /* wait for 50msec for the HW to apply ramp on HPHL and HPHR */ + usleep_range(50000, 50100); + /* Enable ZDET_DISCHG_CAP_CTL to add extra capacitance */ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x01, 0x01); + /* wait for 5msec for the voltage to get stable */ + usleep_range(5000, 5100); + + wcd_mbhc_meas_imped(codec, &impedance_l, &impedance_r); + + min_range_used = msm_anlg_cdc_adj_ref_current(codec, + &impedance_l, &impedance_r); + if (!mbhc->mbhc_cfg->mono_stero_detection) { + /* Set ZDET_CHG to 0 to discharge ramp */ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x02, 0x00); + /* wait for 40msec for the capacitor to discharge */ + usleep_range(40000, 40100); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, + 0x03, 0x00); + goto exit; + } + + /* we are setting ref current to the minimun range or the measured + * value larger than the minimum value, so min_range_used is true. + * If the headset is mono headset with either HPHL or HPHR floating + * then we have already done the mono stereo detection and do not + * need to continue further. + */ + + if (!min_range_used || + sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHL || + sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHR) + goto exit; + + + /* Disable Set ZDET_CONN_RAMP_L and enable ZDET_CONN_FIXED_L */ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, + 0x02, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL, + 0x02, 0x02); + /* Set ZDET_CHG to 0 */ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x02, 0x00); + /* wait for 40msec for the capacitor to discharge */ + usleep_range(40000, 40100); + + /* Set ZDET_CONN_RAMP_R to 0 */ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, + 0x01, 0x00); + /* Enable ZDET_L_MEAS_EN */ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x08, 0x08); + /* wait for 2msec for the HW to compute left inpedance value */ + usleep_range(2000, 2100); + /* Read Left impedance value from Result1 */ + impedance_l_fixed = snd_soc_read(codec, + MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT); + /* Disable ZDET_L_MEAS_EN */ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x08, 0x00); + /* + * Assume impedance_l is L1, impedance_l_fixed is L2. + * If the following condition is met, we can take this + * headset as mono one with impedance of L2. + * Otherwise, take it as stereo with impedance of L1. + * Condition: + * abs[(L2-0.5L1)/(L2+0.5L1)] < abs [(L2-L1)/(L2+L1)] + */ + if ((abs(impedance_l_fixed - impedance_l/2) * + (impedance_l_fixed + impedance_l)) >= + (abs(impedance_l_fixed - impedance_l) * + (impedance_l_fixed + impedance_l/2))) { + dev_dbg(codec->dev, + "%s: STEREO plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_STEREO; + } else { + dev_dbg(codec->dev, + "%s: MONO plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_MONO; + impedance_l = impedance_l_fixed; + } + /* Enable ZDET_CHG */ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x02, 0x02); + /* wait for 10msec for the capacitor to charge */ + usleep_range(10000, 10100); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, + 0x02, 0x02); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL, + 0x02, 0x00); + /* Set ZDET_CHG to 0 to discharge HPHL */ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x02, 0x00); + /* wait for 40msec for the capacitor to discharge */ + usleep_range(40000, 40100); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, + 0x02, 0x00); + +exit: + snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, reg4); + snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MICB_2_EN, reg3); + snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL, reg1); + snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, reg0); + snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, reg2); + msm_anlg_cdc_compute_impedance(codec, impedance_l, impedance_r, + zl, zr, high); + + dev_dbg(codec->dev, "%s: RL %d ohm, RR %d ohm\n", __func__, *zl, *zr); + dev_dbg(codec->dev, "%s: Impedance detection completed\n", __func__); +} + +static int msm_anlg_cdc_dig_register_notifier(void *handle, + struct notifier_block *nblock, + bool enable) +{ + struct sdm660_cdc_priv *handle_cdc = handle; + + if (enable) + return blocking_notifier_chain_register(&handle_cdc->notifier, + nblock); + + return blocking_notifier_chain_unregister(&handle_cdc->notifier, + nblock); +} + +static int msm_anlg_cdc_mbhc_register_notifier(struct wcd_mbhc *wcd_mbhc, + struct notifier_block *nblock, + bool enable) +{ + struct snd_soc_codec *codec = wcd_mbhc->codec; + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + if (enable) + return blocking_notifier_chain_register( + &sdm660_cdc->notifier_mbhc, + nblock); + + return blocking_notifier_chain_unregister(&sdm660_cdc->notifier_mbhc, + nblock); +} + +static int msm_anlg_cdc_request_irq(struct snd_soc_codec *codec, + int irq, irq_handler_t handler, + const char *name, void *data) +{ + return wcd9xxx_spmi_request_irq(irq, handler, name, data); +} + +static int msm_anlg_cdc_free_irq(struct snd_soc_codec *codec, + int irq, void *data) +{ + return wcd9xxx_spmi_free_irq(irq, data); +} + +static const struct wcd_mbhc_cb mbhc_cb = { + .enable_mb_source = msm_anlg_cdc_enable_ext_mb_source, + .trim_btn_reg = msm_anlg_cdc_trim_btn_reg, + .compute_impedance = msm_anlg_cdc_mbhc_calc_impedance, + .set_micbias_value = msm_anlg_cdc_set_micb_v, + .set_auto_zeroing = msm_anlg_cdc_set_auto_zeroing, + .get_hwdep_fw_cal = msm_anlg_cdc_get_hwdep_fw_cal, + .set_cap_mode = msm_anlg_cdc_configure_cap, + .register_notifier = msm_anlg_cdc_mbhc_register_notifier, + .request_irq = msm_anlg_cdc_request_irq, + .irq_control = wcd9xxx_spmi_irq_control, + .free_irq = msm_anlg_cdc_free_irq, + .clk_setup = msm_anlg_cdc_mbhc_clk_setup, + .map_btn_code_to_num = msm_anlg_cdc_mbhc_map_btn_code_to_num, + .lock_sleep = msm_anlg_cdc_spmi_lock_sleep, + .micbias_enable_status = msm_anlg_cdc_micb_en_status, + .mbhc_bias = msm_anlg_cdc_enable_master_bias, + .mbhc_common_micb_ctrl = msm_anlg_cdc_mbhc_common_micb_ctrl, + .micb_internal = msm_anlg_cdc_mbhc_internal_micbias_ctrl, + .hph_pa_on_status = msm_anlg_cdc_mbhc_hph_pa_on_status, + .set_btn_thr = msm_anlg_cdc_mbhc_program_btn_thr, + .extn_use_mb = msm_anlg_cdc_use_mb, +}; + +static const uint32_t wcd_imped_val[] = {4, 8, 12, 13, 16, + 20, 24, 28, 32, + 36, 40, 44, 48}; + +static void msm_anlg_cdc_dig_notifier_call(struct snd_soc_codec *codec, + const enum dig_cdc_notify_event event) +{ + struct sdm660_cdc_priv *sdm660_cdc = snd_soc_codec_get_drvdata(codec); + + pr_debug("%s: notifier call event %d\n", __func__, event); + blocking_notifier_call_chain(&sdm660_cdc->notifier, + event, NULL); +} + +static void msm_anlg_cdc_notifier_call(struct snd_soc_codec *codec, + const enum wcd_notify_event event) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: notifier call event %d\n", __func__, event); + blocking_notifier_call_chain(&sdm660_cdc->notifier_mbhc, event, + &sdm660_cdc->mbhc); +} + +static void msm_anlg_cdc_boost_on(struct snd_soc_codec *codec) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x0F, 0x0F); + snd_soc_write(codec, MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0xA5); + snd_soc_write(codec, MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x0F); + snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, 0x30); + if (get_codec_version(sdm660_cdc) < CAJON_2_0) + snd_soc_write(codec, MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x82); + else + snd_soc_write(codec, MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0xA2); + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, + 0x69, 0x69); + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, + 0x01, 0x01); + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO, + 0x88, 0x88); + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, + 0x03, 0x03); + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, + 0xE1, 0xE1); + if (get_codec_version(sdm660_cdc) < CAJON_2_0) { + snd_soc_update_bits(codec, MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x20, 0x20); + /* Wait for 1ms after clock ctl enable */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, + 0xDF, 0xDF); + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + } else { + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, + 0x40, 0x00); + snd_soc_update_bits(codec, MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x20, 0x20); + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, + 0x80, 0x80); + /* Wait for 500us after BOOST_EN to happen */ + usleep_range(500, 510); + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, + 0x40, 0x40); + /* Wait for 500us after BOOST pulse_skip */ + usleep_range(500, 510); + } +} + +static void msm_anlg_cdc_boost_off(struct snd_soc_codec *codec) +{ + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, + 0xDF, 0x5F); + snd_soc_update_bits(codec, MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x20, 0x00); +} + +static void msm_anlg_cdc_bypass_on(struct snd_soc_codec *codec) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + if (get_codec_version(sdm660_cdc) < CAJON_2_0) { + snd_soc_write(codec, + MSM89XX_PMIC_ANALOG_SEC_ACCESS, + 0xA5); + snd_soc_write(codec, + MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, + 0x07); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x02, 0x02); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x01, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x40, 0x40); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x80, 0x80); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, + 0xDF, 0xDF); + } else { + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x20, 0x20); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x20, 0x20); + } +} + +static void msm_anlg_cdc_bypass_off(struct snd_soc_codec *codec) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + if (get_codec_version(sdm660_cdc) < CAJON_2_0) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, + 0x80, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x80, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x02, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x40, 0x00); + } else { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x20, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x20, 0x00); + } +} + +static void msm_anlg_cdc_boost_mode_sequence(struct snd_soc_codec *codec, + int flag) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + if (flag == EAR_PMU) { + switch (sdm660_cdc->boost_option) { + case BOOST_SWITCH: + if (sdm660_cdc->ear_pa_boost_set) { + msm_anlg_cdc_boost_off(codec); + msm_anlg_cdc_bypass_on(codec); + } + break; + case BOOST_ALWAYS: + msm_anlg_cdc_boost_on(codec); + break; + case BYPASS_ALWAYS: + msm_anlg_cdc_bypass_on(codec); + break; + case BOOST_ON_FOREVER: + msm_anlg_cdc_boost_on(codec); + break; + default: + dev_err(codec->dev, + "%s: invalid boost option: %d\n", __func__, + sdm660_cdc->boost_option); + break; + } + } else if (flag == EAR_PMD) { + switch (sdm660_cdc->boost_option) { + case BOOST_SWITCH: + if (sdm660_cdc->ear_pa_boost_set) + msm_anlg_cdc_bypass_off(codec); + break; + case BOOST_ALWAYS: + msm_anlg_cdc_boost_off(codec); + /* 80ms for EAR boost to settle down */ + msleep(80); + break; + case BYPASS_ALWAYS: + /* nothing to do as bypass on always */ + break; + case BOOST_ON_FOREVER: + /* nothing to do as boost on forever */ + break; + default: + dev_err(codec->dev, + "%s: invalid boost option: %d\n", __func__, + sdm660_cdc->boost_option); + break; + } + } else if (flag == SPK_PMU) { + switch (sdm660_cdc->boost_option) { + case BOOST_SWITCH: + if (sdm660_cdc->spk_boost_set) { + msm_anlg_cdc_bypass_off(codec); + msm_anlg_cdc_boost_on(codec); + } + break; + case BOOST_ALWAYS: + msm_anlg_cdc_boost_on(codec); + break; + case BYPASS_ALWAYS: + msm_anlg_cdc_bypass_on(codec); + break; + case BOOST_ON_FOREVER: + msm_anlg_cdc_boost_on(codec); + break; + default: + dev_err(codec->dev, + "%s: invalid boost option: %d\n", __func__, + sdm660_cdc->boost_option); + break; + } + } else if (flag == SPK_PMD) { + switch (sdm660_cdc->boost_option) { + case BOOST_SWITCH: + if (sdm660_cdc->spk_boost_set) { + msm_anlg_cdc_boost_off(codec); + /* + * Add 40 ms sleep for the spk + * boost to settle down + */ + msleep(40); + } + break; + case BOOST_ALWAYS: + msm_anlg_cdc_boost_off(codec); + /* + * Add 40 ms sleep for the spk + * boost to settle down + */ + msleep(40); + break; + case BYPASS_ALWAYS: + /* nothing to do as bypass on always */ + break; + case BOOST_ON_FOREVER: + /* nothing to do as boost on forever */ + break; + default: + dev_err(codec->dev, + "%s: invalid boost option: %d\n", __func__, + sdm660_cdc->boost_option); + break; + } + } +} + +static int msm_anlg_cdc_dt_parse_vreg_info(struct device *dev, + struct sdm660_cdc_regulator *vreg, const char *vreg_name, + bool ondemand) +{ + int len, ret = 0; + const __be32 *prop; + char prop_name[CODEC_DT_MAX_PROP_SIZE]; + struct device_node *regnode = NULL; + u32 prop_val; + + snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "%s-supply", + vreg_name); + regnode = of_parse_phandle(dev->of_node, prop_name, 0); + + if (!regnode) { + dev_err(dev, "Looking up %s property in node %s failed\n", + prop_name, dev->of_node->full_name); + return -ENODEV; + } + + dev_dbg(dev, "Looking up %s property in node %s\n", + prop_name, dev->of_node->full_name); + + vreg->name = vreg_name; + vreg->ondemand = ondemand; + + snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, + "qcom,%s-voltage", vreg_name); + prop = of_get_property(dev->of_node, prop_name, &len); + + if (!prop || (len != (2 * sizeof(__be32)))) { + dev_err(dev, "%s %s property\n", + prop ? "invalid format" : "no", prop_name); + return -EINVAL; + } + vreg->min_uv = be32_to_cpup(&prop[0]); + vreg->max_uv = be32_to_cpup(&prop[1]); + + snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, + "qcom,%s-current", vreg_name); + + ret = of_property_read_u32(dev->of_node, prop_name, &prop_val); + if (ret) { + dev_err(dev, "Looking up %s property in node %s failed", + prop_name, dev->of_node->full_name); + return -EFAULT; + } + vreg->optimum_ua = prop_val; + + dev_dbg(dev, "%s: vol=[%d %d]uV, curr=[%d]uA, ond %d\n\n", vreg->name, + vreg->min_uv, vreg->max_uv, vreg->optimum_ua, vreg->ondemand); + return 0; +} + +static void msm_anlg_cdc_dt_parse_boost_info(struct snd_soc_codec *codec) +{ + struct sdm660_cdc_priv *sdm660_cdc_priv = + snd_soc_codec_get_drvdata(codec); + const char *prop_name = "qcom,cdc-boost-voltage"; + int boost_voltage, ret; + + ret = of_property_read_u32(codec->dev->of_node, prop_name, + &boost_voltage); + if (ret) { + dev_dbg(codec->dev, "Looking up %s property in node %s failed\n", + prop_name, codec->dev->of_node->full_name); + boost_voltage = DEFAULT_BOOST_VOLTAGE; + } + if (boost_voltage < MIN_BOOST_VOLTAGE || + boost_voltage > MAX_BOOST_VOLTAGE) { + dev_err(codec->dev, + "Incorrect boost voltage. Reverting to default\n"); + boost_voltage = DEFAULT_BOOST_VOLTAGE; + } + + sdm660_cdc_priv->boost_voltage = + VOLTAGE_CONVERTER(boost_voltage, MIN_BOOST_VOLTAGE, + BOOST_VOLTAGE_STEP); + dev_dbg(codec->dev, "Boost voltage value is: %d\n", + boost_voltage); +} + +static void msm_anlg_cdc_dt_parse_micbias_info(struct device *dev, + struct wcd_micbias_setting *micbias) +{ + const char *prop_name = "qcom,cdc-micbias-cfilt-mv"; + int ret; + + ret = of_property_read_u32(dev->of_node, prop_name, + &micbias->cfilt1_mv); + if (ret) { + dev_dbg(dev, "Looking up %s property in node %s failed", + prop_name, dev->of_node->full_name); + micbias->cfilt1_mv = MICBIAS_DEFAULT_VAL; + } +} + +static struct sdm660_cdc_pdata *msm_anlg_cdc_populate_dt_pdata( + struct device *dev) +{ + struct sdm660_cdc_pdata *pdata; + int ret, static_cnt, ond_cnt, idx, i; + const char *name = NULL; + const char *static_prop_name = "qcom,cdc-static-supplies"; + const char *ond_prop_name = "qcom,cdc-on-demand-supplies"; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return NULL; + + static_cnt = of_property_count_strings(dev->of_node, static_prop_name); + if (static_cnt < 0) { + dev_err(dev, "%s: Failed to get static supplies %d\n", __func__, + static_cnt); + ret = -EINVAL; + goto err; + } + + /* On-demand supply list is an optional property */ + ond_cnt = of_property_count_strings(dev->of_node, ond_prop_name); + if (ond_cnt < 0) + ond_cnt = 0; + + WARN_ON(static_cnt <= 0 || ond_cnt < 0); + if ((static_cnt + ond_cnt) > ARRAY_SIZE(pdata->regulator)) { + dev_err(dev, "%s: Num of supplies %u > max supported %zd\n", + __func__, (static_cnt + ond_cnt), + ARRAY_SIZE(pdata->regulator)); + ret = -EINVAL; + goto err; + } + + for (idx = 0; idx < static_cnt; idx++) { + ret = of_property_read_string_index(dev->of_node, + static_prop_name, idx, + &name); + if (ret) { + dev_err(dev, "%s: of read string %s idx %d error %d\n", + __func__, static_prop_name, idx, ret); + goto err; + } + + dev_dbg(dev, "%s: Found static cdc supply %s\n", __func__, + name); + ret = msm_anlg_cdc_dt_parse_vreg_info(dev, + &pdata->regulator[idx], + name, false); + if (ret) { + dev_err(dev, "%s:err parsing vreg for %s idx %d\n", + __func__, name, idx); + goto err; + } + } + + for (i = 0; i < ond_cnt; i++, idx++) { + ret = of_property_read_string_index(dev->of_node, ond_prop_name, + i, &name); + if (ret) { + dev_err(dev, "%s: err parsing on_demand for %s idx %d\n", + __func__, ond_prop_name, i); + goto err; + } + + dev_dbg(dev, "%s: Found on-demand cdc supply %s\n", __func__, + name); + ret = msm_anlg_cdc_dt_parse_vreg_info(dev, + &pdata->regulator[idx], + name, true); + if (ret) { + dev_err(dev, "%s: err parsing vreg on_demand for %s idx %d\n", + __func__, name, idx); + goto err; + } + } + msm_anlg_cdc_dt_parse_micbias_info(dev, &pdata->micbias); + + return pdata; +err: + devm_kfree(dev, pdata); + dev_err(dev, "%s: Failed to populate DT data ret = %d\n", + __func__, ret); + return NULL; +} + +static int msm_anlg_cdc_codec_enable_on_demand_supply( + struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + int ret = 0; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + struct on_demand_supply *supply; + + if (w->shift >= ON_DEMAND_SUPPLIES_MAX) { + dev_err(codec->dev, "%s: error index > MAX Demand supplies", + __func__); + ret = -EINVAL; + goto out; + } + dev_dbg(codec->dev, "%s: supply: %s event: %d ref: %d\n", + __func__, on_demand_supply_name[w->shift], event, + atomic_read(&sdm660_cdc->on_demand_list[w->shift].ref)); + + supply = &sdm660_cdc->on_demand_list[w->shift]; + WARN_ONCE(!supply->supply, "%s isn't defined\n", + on_demand_supply_name[w->shift]); + if (!supply->supply) { + dev_err(codec->dev, "%s: err supply not present ond for %d", + __func__, w->shift); + goto out; + } + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (atomic_inc_return(&supply->ref) == 1) { + ret = regulator_set_voltage(supply->supply, + supply->min_uv, + supply->max_uv); + if (ret) { + dev_err(codec->dev, + "Setting regulator voltage(en) for micbias with err = %d\n", + ret); + goto out; + } + ret = regulator_set_load(supply->supply, + supply->optimum_ua); + if (ret < 0) { + dev_err(codec->dev, + "Setting regulator optimum mode(en) failed for micbias with err = %d\n", + ret); + goto out; + } + ret = regulator_enable(supply->supply); + } + if (ret) + dev_err(codec->dev, "%s: Failed to enable %s\n", + __func__, + on_demand_supply_name[w->shift]); + break; + case SND_SOC_DAPM_POST_PMD: + if (atomic_read(&supply->ref) == 0) { + dev_dbg(codec->dev, "%s: %s supply has been disabled.\n", + __func__, on_demand_supply_name[w->shift]); + goto out; + } + if (atomic_dec_return(&supply->ref) == 0) { + ret = regulator_disable(supply->supply); + if (ret) + dev_err(codec->dev, "%s: Failed to disable %s\n", + __func__, + on_demand_supply_name[w->shift]); + ret = regulator_set_voltage(supply->supply, + 0, + supply->max_uv); + if (ret) { + dev_err(codec->dev, + "Setting regulator voltage(dis) failed for micbias with err = %d\n", + ret); + goto out; + } + ret = regulator_set_load(supply->supply, 0); + if (ret < 0) + dev_err(codec->dev, + "Setting regulator optimum mode(dis) failed for micbias with err = %d\n", + ret); + } + break; + default: + break; + } +out: + return ret; +} + +static int msm_anlg_cdc_codec_enable_clock_block(struct snd_soc_codec *codec, + int enable) +{ + struct msm_asoc_mach_data *pdata = NULL; + + pdata = snd_soc_card_get_drvdata(codec->component.card); + if (enable) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, 0x30, 0x30); + msm_anlg_cdc_dig_notifier_call(codec, DIG_CDC_EVENT_CLK_ON); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80, 0x80); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL, 0x0C, 0x0C); + } else { + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL, 0x0C, 0x00); + } + return 0; +} + +static int msm_anlg_cdc_codec_enable_charge_pump(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: event = %d\n", __func__, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + msm_anlg_cdc_codec_enable_clock_block(codec, 1); + if (!(strcmp(w->name, "EAR CP"))) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x80); + msm_anlg_cdc_boost_mode_sequence(codec, EAR_PMU); + } else if (get_codec_version(sdm660_cdc) >= DIANGU) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x80); + } else { + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0xC0, 0xC0); + } + break; + case SND_SOC_DAPM_POST_PMU: + /* Wait for 1ms post powerup of chargepump */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + break; + case SND_SOC_DAPM_POST_PMD: + /* Wait for 1ms post powerdown of chargepump */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + if (!(strcmp(w->name, "EAR CP"))) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x00); + if (sdm660_cdc->boost_option != BOOST_ALWAYS) { + dev_dbg(codec->dev, + "%s: boost_option:%d, tear down ear\n", + __func__, sdm660_cdc->boost_option); + msm_anlg_cdc_boost_mode_sequence(codec, + EAR_PMD); + } + /* + * Reset pa select bit from ear to hph after ear pa + * is disabled and HPH DAC disable to reduce ear + * turn off pop and avoid HPH pop in concurrency + */ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x80, 0x00); + } else { + if (get_codec_version(sdm660_cdc) < DIANGU) + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x40, 0x00); + if (sdm660_cdc->rx_bias_count == 0) + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x00); + dev_dbg(codec->dev, "%s: rx_bias_count = %d\n", + __func__, sdm660_cdc->rx_bias_count); + } + break; + } + return 0; +} + +static int msm_anlg_cdc_ear_pa_boost_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = + (sdm660_cdc->ear_pa_boost_set ? 1 : 0); + dev_dbg(codec->dev, "%s: sdm660_cdc->ear_pa_boost_set = %d\n", + __func__, sdm660_cdc->ear_pa_boost_set); + return 0; +} + +static int msm_anlg_cdc_ear_pa_boost_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + sdm660_cdc->ear_pa_boost_set = + (ucontrol->value.integer.value[0] ? true : false); + return 0; +} + +static int msm_anlg_cdc_loopback_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct msm_asoc_mach_data *pdata = NULL; + + pdata = snd_soc_card_get_drvdata(codec->component.card); + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return pdata->lb_mode; +} + +static int msm_anlg_cdc_loopback_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct msm_asoc_mach_data *pdata = NULL; + + pdata = snd_soc_card_get_drvdata(codec->component.card); + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + switch (ucontrol->value.integer.value[0]) { + case 0: + pdata->lb_mode = false; + break; + case 1: + pdata->lb_mode = true; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int msm_anlg_cdc_pa_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 ear_pa_gain; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + if (get_codec_version(sdm660_cdc) >= DIANGU) { + ear_pa_gain = snd_soc_read(codec, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC); + ear_pa_gain = (ear_pa_gain >> 1) & 0x3; + + if (ear_pa_gain == 0x00) { + ucontrol->value.integer.value[0] = 3; + } else if (ear_pa_gain == 0x01) { + ucontrol->value.integer.value[1] = 2; + } else if (ear_pa_gain == 0x02) { + ucontrol->value.integer.value[2] = 1; + } else if (ear_pa_gain == 0x03) { + ucontrol->value.integer.value[3] = 0; + } else { + dev_err(codec->dev, + "%s: ERROR: Unsupported Ear Gain = 0x%x\n", + __func__, ear_pa_gain); + return -EINVAL; + } + } else { + ear_pa_gain = snd_soc_read(codec, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL); + ear_pa_gain = (ear_pa_gain >> 5) & 0x1; + if (ear_pa_gain == 0x00) { + ucontrol->value.integer.value[0] = 0; + } else if (ear_pa_gain == 0x01) { + ucontrol->value.integer.value[0] = 3; + } else { + dev_err(codec->dev, + "%s: ERROR: Unsupported Ear Gain = 0x%x\n", + __func__, ear_pa_gain); + return -EINVAL; + } + } + ucontrol->value.integer.value[0] = ear_pa_gain; + dev_dbg(codec->dev, "%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain); + return 0; +} + +static int msm_anlg_cdc_pa_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 ear_pa_gain; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + if (get_codec_version(sdm660_cdc) >= DIANGU) { + switch (ucontrol->value.integer.value[0]) { + case 0: + ear_pa_gain = 0x06; + break; + case 1: + ear_pa_gain = 0x04; + break; + case 2: + ear_pa_gain = 0x02; + break; + case 3: + ear_pa_gain = 0x00; + break; + default: + return -EINVAL; + } + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, + 0x06, ear_pa_gain); + } else { + switch (ucontrol->value.integer.value[0]) { + case 0: + ear_pa_gain = 0x00; + break; + case 3: + ear_pa_gain = 0x20; + break; + case 1: + case 2: + default: + return -EINVAL; + } + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x20, ear_pa_gain); + } + return 0; +} + +static int msm_anlg_cdc_hph_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + if (sdm660_cdc->hph_mode == NORMAL_MODE) { + ucontrol->value.integer.value[0] = 0; + } else if (sdm660_cdc->hph_mode == HD2_MODE) { + ucontrol->value.integer.value[0] = 1; + } else { + dev_err(codec->dev, "%s: ERROR: Default HPH Mode= %d\n", + __func__, sdm660_cdc->hph_mode); + } + + dev_dbg(codec->dev, "%s: sdm660_cdc->hph_mode = %d\n", __func__, + sdm660_cdc->hph_mode); + return 0; +} + +static int msm_anlg_cdc_hph_mode_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + switch (ucontrol->value.integer.value[0]) { + case 0: + sdm660_cdc->hph_mode = NORMAL_MODE; + break; + case 1: + if (get_codec_version(sdm660_cdc) >= DIANGU) + sdm660_cdc->hph_mode = HD2_MODE; + break; + default: + sdm660_cdc->hph_mode = NORMAL_MODE; + break; + } + dev_dbg(codec->dev, "%s: sdm660_cdc->hph_mode_set = %d\n", + __func__, sdm660_cdc->hph_mode); + return 0; +} + +static int msm_anlg_cdc_boost_option_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + if (sdm660_cdc->boost_option == BOOST_SWITCH) { + ucontrol->value.integer.value[0] = 0; + } else if (sdm660_cdc->boost_option == BOOST_ALWAYS) { + ucontrol->value.integer.value[0] = 1; + } else if (sdm660_cdc->boost_option == BYPASS_ALWAYS) { + ucontrol->value.integer.value[0] = 2; + } else if (sdm660_cdc->boost_option == BOOST_ON_FOREVER) { + ucontrol->value.integer.value[0] = 3; + } else { + dev_err(codec->dev, "%s: ERROR: Unsupported Boost option= %d\n", + __func__, sdm660_cdc->boost_option); + return -EINVAL; + } + + dev_dbg(codec->dev, "%s: sdm660_cdc->boost_option = %d\n", __func__, + sdm660_cdc->boost_option); + return 0; +} + +static int msm_anlg_cdc_boost_option_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + switch (ucontrol->value.integer.value[0]) { + case 0: + sdm660_cdc->boost_option = BOOST_SWITCH; + break; + case 1: + sdm660_cdc->boost_option = BOOST_ALWAYS; + break; + case 2: + sdm660_cdc->boost_option = BYPASS_ALWAYS; + msm_anlg_cdc_bypass_on(codec); + break; + case 3: + sdm660_cdc->boost_option = BOOST_ON_FOREVER; + msm_anlg_cdc_boost_on(codec); + break; + default: + pr_err("%s: invalid boost option: %d\n", __func__, + sdm660_cdc->boost_option); + return -EINVAL; + } + dev_dbg(codec->dev, "%s: sdm660_cdc->boost_option_set = %d\n", + __func__, sdm660_cdc->boost_option); + return 0; +} + +static int msm_anlg_cdc_spk_boost_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + if (sdm660_cdc->spk_boost_set == false) { + ucontrol->value.integer.value[0] = 0; + } else if (sdm660_cdc->spk_boost_set == true) { + ucontrol->value.integer.value[0] = 1; + } else { + dev_err(codec->dev, "%s: ERROR: Unsupported Speaker Boost = %d\n", + __func__, sdm660_cdc->spk_boost_set); + return -EINVAL; + } + + dev_dbg(codec->dev, "%s: sdm660_cdc->spk_boost_set = %d\n", __func__, + sdm660_cdc->spk_boost_set); + return 0; +} + +static int msm_anlg_cdc_spk_boost_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + switch (ucontrol->value.integer.value[0]) { + case 0: + sdm660_cdc->spk_boost_set = false; + break; + case 1: + sdm660_cdc->spk_boost_set = true; + break; + default: + return -EINVAL; + } + dev_dbg(codec->dev, "%s: sdm660_cdc->spk_boost_set = %d\n", + __func__, sdm660_cdc->spk_boost_set); + return 0; +} + +static int msm_anlg_cdc_ext_spk_boost_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + if (sdm660_cdc->ext_spk_boost_set == false) + ucontrol->value.integer.value[0] = 0; + else + ucontrol->value.integer.value[0] = 1; + + dev_dbg(codec->dev, "%s: sdm660_cdc->ext_spk_boost_set = %d\n", + __func__, sdm660_cdc->ext_spk_boost_set); + return 0; +} + +static int msm_anlg_cdc_ext_spk_boost_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + switch (ucontrol->value.integer.value[0]) { + case 0: + sdm660_cdc->ext_spk_boost_set = false; + break; + case 1: + sdm660_cdc->ext_spk_boost_set = true; + break; + default: + return -EINVAL; + } + dev_dbg(codec->dev, "%s: sdm660_cdc->spk_boost_set = %d\n", + __func__, sdm660_cdc->spk_boost_set); + return 0; +} + + +static const char * const msm_anlg_cdc_loopback_mode_ctrl_text[] = { + "DISABLE", "ENABLE"}; +static const struct soc_enum msm_anlg_cdc_loopback_mode_ctl_enum[] = { + SOC_ENUM_SINGLE_EXT(2, msm_anlg_cdc_loopback_mode_ctrl_text), +}; + +static const char * const msm_anlg_cdc_ear_pa_boost_ctrl_text[] = { + "DISABLE", "ENABLE"}; +static const struct soc_enum msm_anlg_cdc_ear_pa_boost_ctl_enum[] = { + SOC_ENUM_SINGLE_EXT(2, msm_anlg_cdc_ear_pa_boost_ctrl_text), +}; + +static const char * const msm_anlg_cdc_ear_pa_gain_text[] = { + "POS_1P5_DB", "POS_3_DB", "POS_4P5_DB", "POS_6_DB"}; +static const struct soc_enum msm_anlg_cdc_ear_pa_gain_enum[] = { + SOC_ENUM_SINGLE_EXT(4, msm_anlg_cdc_ear_pa_gain_text), +}; + +static const char * const msm_anlg_cdc_boost_option_ctrl_text[] = { + "BOOST_SWITCH", "BOOST_ALWAYS", "BYPASS_ALWAYS", + "BOOST_ON_FOREVER"}; +static const struct soc_enum msm_anlg_cdc_boost_option_ctl_enum[] = { + SOC_ENUM_SINGLE_EXT(4, msm_anlg_cdc_boost_option_ctrl_text), +}; +static const char * const msm_anlg_cdc_spk_boost_ctrl_text[] = { + "DISABLE", "ENABLE"}; +static const struct soc_enum msm_anlg_cdc_spk_boost_ctl_enum[] = { + SOC_ENUM_SINGLE_EXT(2, msm_anlg_cdc_spk_boost_ctrl_text), +}; + +static const char * const msm_anlg_cdc_ext_spk_boost_ctrl_text[] = { + "DISABLE", "ENABLE"}; +static const struct soc_enum msm_anlg_cdc_ext_spk_boost_ctl_enum[] = { + SOC_ENUM_SINGLE_EXT(2, msm_anlg_cdc_ext_spk_boost_ctrl_text), +}; + +static const char * const msm_anlg_cdc_hph_mode_ctrl_text[] = { + "NORMAL", "HD2"}; +static const struct soc_enum msm_anlg_cdc_hph_mode_ctl_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(msm_anlg_cdc_hph_mode_ctrl_text), + msm_anlg_cdc_hph_mode_ctrl_text), +}; + +/*cut of frequency for high pass filter*/ +static const char * const cf_text[] = { + "MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz" +}; + + +static const struct snd_kcontrol_new msm_anlg_cdc_snd_controls[] = { + + SOC_ENUM_EXT("RX HPH Mode", msm_anlg_cdc_hph_mode_ctl_enum[0], + msm_anlg_cdc_hph_mode_get, msm_anlg_cdc_hph_mode_set), + + SOC_ENUM_EXT("Boost Option", msm_anlg_cdc_boost_option_ctl_enum[0], + msm_anlg_cdc_boost_option_get, msm_anlg_cdc_boost_option_set), + + SOC_ENUM_EXT("EAR PA Boost", msm_anlg_cdc_ear_pa_boost_ctl_enum[0], + msm_anlg_cdc_ear_pa_boost_get, msm_anlg_cdc_ear_pa_boost_set), + + SOC_ENUM_EXT("EAR PA Gain", msm_anlg_cdc_ear_pa_gain_enum[0], + msm_anlg_cdc_pa_gain_get, msm_anlg_cdc_pa_gain_put), + + SOC_ENUM_EXT("Speaker Boost", msm_anlg_cdc_spk_boost_ctl_enum[0], + msm_anlg_cdc_spk_boost_get, msm_anlg_cdc_spk_boost_set), + + SOC_ENUM_EXT("Ext Spk Boost", msm_anlg_cdc_ext_spk_boost_ctl_enum[0], + msm_anlg_cdc_ext_spk_boost_get, msm_anlg_cdc_ext_spk_boost_set), + + SOC_ENUM_EXT("LOOPBACK Mode", msm_anlg_cdc_loopback_mode_ctl_enum[0], + msm_anlg_cdc_loopback_mode_get, msm_anlg_cdc_loopback_mode_put), + SOC_SINGLE_TLV("ADC1 Volume", MSM89XX_PMIC_ANALOG_TX_1_EN, 3, + 8, 0, analog_gain), + SOC_SINGLE_TLV("ADC2 Volume", MSM89XX_PMIC_ANALOG_TX_2_EN, 3, + 8, 0, analog_gain), + SOC_SINGLE_TLV("ADC3 Volume", MSM89XX_PMIC_ANALOG_TX_3_EN, 3, + 8, 0, analog_gain), + + +}; + +static int tombak_hph_impedance_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret; + uint32_t zl, zr; + bool hphr; + struct soc_multi_mixer_control *mc; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct sdm660_cdc_priv *priv = snd_soc_codec_get_drvdata(codec); + + mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); + + hphr = mc->shift; + ret = wcd_mbhc_get_impedance(&priv->mbhc, &zl, &zr); + if (ret) + dev_dbg(codec->dev, "%s: Failed to get mbhc imped", __func__); + dev_dbg(codec->dev, "%s: zl %u, zr %u\n", __func__, zl, zr); + ucontrol->value.integer.value[0] = hphr ? zr : zl; + + return 0; +} + +static const struct snd_kcontrol_new impedance_detect_controls[] = { + SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0, + tombak_hph_impedance_get, NULL), + SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0, + tombak_hph_impedance_get, NULL), +}; + +static int tombak_get_hph_type(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct sdm660_cdc_priv *priv = snd_soc_codec_get_drvdata(codec); + struct wcd_mbhc *mbhc; + + if (!priv) { + dev_err(codec->dev, + "%s: sdm660_cdc-wcd private data is NULL\n", + __func__); + return -EINVAL; + } + + mbhc = &priv->mbhc; + if (!mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized\n", __func__); + return -EINVAL; + } + + ucontrol->value.integer.value[0] = (u32) mbhc->hph_type; + dev_dbg(codec->dev, "%s: hph_type = %u\n", __func__, mbhc->hph_type); + + return 0; +} + +static const struct snd_kcontrol_new hph_type_detect_controls[] = { + SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0, + tombak_get_hph_type, NULL), +}; + +static const char * const rdac2_mux_text[] = { + "ZERO", "RX2", "RX1" +}; + +static const struct soc_enum rdac2_mux_enum = + SOC_ENUM_SINGLE(MSM89XX_PMIC_DIGITAL_CDC_CONN_HPHR_DAC_CTL, + 0, 3, rdac2_mux_text); + +static const char * const adc2_mux_text[] = { + "ZERO", "INP2", "INP3" +}; + +static const char * const ext_spk_text[] = { + "Off", "On" +}; + +static const char * const wsa_spk_text[] = { + "ZERO", "WSA" +}; + +static const struct soc_enum adc2_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, + ARRAY_SIZE(adc2_mux_text), adc2_mux_text); + +static const struct soc_enum ext_spk_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, + ARRAY_SIZE(ext_spk_text), ext_spk_text); + +static const struct soc_enum wsa_spk_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, + ARRAY_SIZE(wsa_spk_text), wsa_spk_text); + + + +static const struct snd_kcontrol_new ext_spk_mux = + SOC_DAPM_ENUM("Ext Spk Switch Mux", ext_spk_enum); + + + +static const struct snd_kcontrol_new tx_adc2_mux = + SOC_DAPM_ENUM("ADC2 MUX Mux", adc2_enum); + + +static const struct snd_kcontrol_new rdac2_mux = + SOC_DAPM_ENUM("RDAC2 MUX Mux", rdac2_mux_enum); + +static const char * const ear_text[] = { + "ZERO", "Switch", +}; + +static const struct soc_enum ear_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(ear_text), ear_text); + +static const struct snd_kcontrol_new ear_pa_mux[] = { + SOC_DAPM_ENUM("EAR_S", ear_enum) +}; + +static const struct snd_kcontrol_new wsa_spk_mux[] = { + SOC_DAPM_ENUM("WSA Spk Switch", wsa_spk_enum) +}; + + + +static const char * const hph_text[] = { + "ZERO", "Switch", +}; + +static const struct soc_enum hph_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hph_text), hph_text); + +static const struct snd_kcontrol_new hphl_mux[] = { + SOC_DAPM_ENUM("HPHL", hph_enum) +}; + +static const struct snd_kcontrol_new hphr_mux[] = { + SOC_DAPM_ENUM("HPHR", hph_enum) +}; + +static const struct snd_kcontrol_new spkr_mux[] = { + SOC_DAPM_ENUM("SPK", hph_enum) +}; + +static const char * const lo_text[] = { + "ZERO", "Switch", +}; + +static const struct soc_enum lo_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hph_text), hph_text); + +static const struct snd_kcontrol_new lo_mux[] = { + SOC_DAPM_ENUM("LINE_OUT", lo_enum) +}; + +static void msm_anlg_cdc_codec_enable_adc_block(struct snd_soc_codec *codec, + int enable) +{ + struct sdm660_cdc_priv *wcd8x16 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s %d\n", __func__, enable); + + if (enable) { + wcd8x16->adc_count++; + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, + 0x20, 0x20); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x10, 0x10); + } else { + wcd8x16->adc_count--; + if (!wcd8x16->adc_count) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x10, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, + 0x20, 0x0); + } + } +} + +static int msm_anlg_cdc_codec_enable_adc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 adc_reg; + u8 init_bit_shift; + + dev_dbg(codec->dev, "%s %d\n", __func__, event); + + adc_reg = MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_2; + + if (w->reg == MSM89XX_PMIC_ANALOG_TX_1_EN) + init_bit_shift = 5; + else if ((w->reg == MSM89XX_PMIC_ANALOG_TX_2_EN) || + (w->reg == MSM89XX_PMIC_ANALOG_TX_3_EN)) + init_bit_shift = 4; + else { + dev_err(codec->dev, "%s: Error, invalid adc register\n", + __func__); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + msm_anlg_cdc_codec_enable_adc_block(codec, 1); + if (w->reg == MSM89XX_PMIC_ANALOG_TX_2_EN) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MICB_1_CTL, 0x02, 0x02); + /* + * Add delay of 10 ms to give sufficient time for the voltage + * to shoot up and settle so that the txfe init does not + * happen when the input voltage is changing too much. + */ + usleep_range(10000, 10010); + snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, + 1 << init_bit_shift); + if (w->reg == MSM89XX_PMIC_ANALOG_TX_1_EN) + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL, + 0x03, 0x00); + else if ((w->reg == MSM89XX_PMIC_ANALOG_TX_2_EN) || + (w->reg == MSM89XX_PMIC_ANALOG_TX_3_EN)) + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL, + 0x03, 0x00); + /* Wait for 1ms to allow txfe settling time */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + break; + case SND_SOC_DAPM_POST_PMU: + /* + * Add delay of 12 ms before deasserting the init + * to reduce the tx pop + */ + usleep_range(12000, 12010); + snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, 0x00); + /* Wait for 1ms to allow txfe settling time post powerup */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + break; + case SND_SOC_DAPM_POST_PMD: + msm_anlg_cdc_codec_enable_adc_block(codec, 0); + if (w->reg == MSM89XX_PMIC_ANALOG_TX_2_EN) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MICB_1_CTL, 0x02, 0x00); + if (w->reg == MSM89XX_PMIC_ANALOG_TX_1_EN) + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL, + 0x03, 0x02); + else if ((w->reg == MSM89XX_PMIC_ANALOG_TX_2_EN) || + (w->reg == MSM89XX_PMIC_ANALOG_TX_3_EN)) + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL, + 0x03, 0x02); + + break; + } + return 0; +} + +static int msm_anlg_cdc_codec_enable_spk_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0x01, 0x01); + switch (sdm660_cdc->boost_option) { + case BOOST_SWITCH: + if (!sdm660_cdc->spk_boost_set) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, + 0x10, 0x10); + break; + case BOOST_ALWAYS: + case BOOST_ON_FOREVER: + break; + case BYPASS_ALWAYS: + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, + 0x10, 0x10); + break; + default: + dev_err(codec->dev, + "%s: invalid boost option: %d\n", __func__, + sdm660_cdc->boost_option); + break; + } + /* Wait for 1ms after SPK_DAC CTL setting */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0xE0, 0xE0); + if (get_codec_version(sdm660_cdc) != TOMBAK_1_0) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x01, 0x01); + break; + case SND_SOC_DAPM_POST_PMU: + /* Wait for 1ms after SPK_VBAT_LDO Enable */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + switch (sdm660_cdc->boost_option) { + case BOOST_SWITCH: + if (sdm660_cdc->spk_boost_set) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, + 0xEF, 0xEF); + else + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, + 0x10, 0x00); + break; + case BOOST_ALWAYS: + case BOOST_ON_FOREVER: + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, + 0xEF, 0xEF); + break; + case BYPASS_ALWAYS: + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x10, 0x00); + break; + default: + dev_err(codec->dev, + "%s: invalid boost option: %d\n", __func__, + sdm660_cdc->boost_option); + break; + } + msm_anlg_cdc_dig_notifier_call(codec, + DIG_CDC_EVENT_RX3_MUTE_OFF); + snd_soc_update_bits(codec, w->reg, 0x80, 0x80); + break; + case SND_SOC_DAPM_PRE_PMD: + msm_anlg_cdc_dig_notifier_call(codec, + DIG_CDC_EVENT_RX3_MUTE_ON); + /* + * Add 1 ms sleep for the mute to take effect + */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x10, 0x10); + if (get_codec_version(sdm660_cdc) < CAJON_2_0) + msm_anlg_cdc_boost_mode_sequence(codec, SPK_PMD); + snd_soc_update_bits(codec, w->reg, 0x80, 0x00); + switch (sdm660_cdc->boost_option) { + case BOOST_SWITCH: + if (sdm660_cdc->spk_boost_set) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, + 0xEF, 0x69); + break; + case BOOST_ALWAYS: + case BOOST_ON_FOREVER: + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, + 0xEF, 0x69); + break; + case BYPASS_ALWAYS: + break; + default: + dev_err(codec->dev, + "%s: invalid boost option: %d\n", __func__, + sdm660_cdc->boost_option); + break; + } + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0xE0, 0x00); + /* Wait for 1ms to allow setting time for spkr path disable */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0x01, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x10, 0x00); + if (get_codec_version(sdm660_cdc) != TOMBAK_1_0) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x01, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00); + if (get_codec_version(sdm660_cdc) >= CAJON_2_0) + msm_anlg_cdc_boost_mode_sequence(codec, SPK_PMD); + break; + } + return 0; +} + +static int msm_anlg_cdc_codec_enable_dig_clk(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + struct msm_asoc_mach_data *pdata = NULL; + + pdata = snd_soc_card_get_drvdata(codec->component.card); + + dev_dbg(codec->dev, "%s event %d w->name %s\n", __func__, + event, w->name); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + msm_anlg_cdc_codec_enable_clock_block(codec, 1); + snd_soc_update_bits(codec, w->reg, 0x80, 0x80); + msm_anlg_cdc_boost_mode_sequence(codec, SPK_PMU); + break; + case SND_SOC_DAPM_POST_PMD: + if (sdm660_cdc->rx_bias_count == 0) + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x00); + } + return 0; +} + + + +static bool msm_anlg_cdc_use_mb(struct snd_soc_codec *codec) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + if (get_codec_version(sdm660_cdc) < CAJON) + return true; + else + return false; +} + +static void msm_anlg_cdc_set_auto_zeroing(struct snd_soc_codec *codec, + bool enable) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + if (get_codec_version(sdm660_cdc) < CONGA) { + if (enable) + /* + * Set autozeroing for special headset detection and + * buttons to work. + */ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MICB_2_EN, + 0x18, 0x10); + else + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MICB_2_EN, + 0x18, 0x00); + + } else { + dev_dbg(codec->dev, + "%s: Auto Zeroing is not required from CONGA\n", + __func__); + } +} + +static void msm_anlg_cdc_trim_btn_reg(struct snd_soc_codec *codec) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + if (get_codec_version(sdm660_cdc) == TOMBAK_1_0) { + pr_debug("%s: This device needs to be trimmed\n", __func__); + /* + * Calculate the trim value for each device used + * till is comes in production by hardware team + */ + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SEC_ACCESS, + 0xA5, 0xA5); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_TRIM_CTRL2, + 0xFF, 0x30); + } else { + dev_dbg(codec->dev, "%s: This device is trimmed at ATE\n", + __func__); + } +} + +static int msm_anlg_cdc_enable_ext_mb_source(struct wcd_mbhc *wcd_mbhc, + bool turn_on) +{ + int ret = 0; + static int count; + struct snd_soc_codec *codec = wcd_mbhc->codec; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + + dev_dbg(codec->dev, "%s turn_on: %d count: %d\n", __func__, turn_on, + count); + if (turn_on) { + if (!count) { + ret = snd_soc_dapm_force_enable_pin(dapm, + "MICBIAS_REGULATOR"); + snd_soc_dapm_sync(dapm); + } + count++; + } else { + if (count > 0) + count--; + if (!count) { + ret = snd_soc_dapm_disable_pin(dapm, + "MICBIAS_REGULATOR"); + snd_soc_dapm_sync(dapm); + } + } + + if (ret) + dev_err(codec->dev, "%s: Failed to %s external micbias source\n", + __func__, turn_on ? "enable" : "disabled"); + else + dev_dbg(codec->dev, "%s: %s external micbias source\n", + __func__, turn_on ? "Enabled" : "Disabled"); + + return ret; +} + +static int msm_anlg_cdc_codec_enable_micbias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + u16 micb_int_reg; + char *internal1_text = "Internal1"; + char *internal2_text = "Internal2"; + char *internal3_text = "Internal3"; + char *external2_text = "External2"; + char *external_text = "External"; + bool micbias2; + + dev_dbg(codec->dev, "%s %d\n", __func__, event); + switch (w->reg) { + case MSM89XX_PMIC_ANALOG_MICB_1_EN: + case MSM89XX_PMIC_ANALOG_MICB_2_EN: + micb_int_reg = MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS; + break; + default: + dev_err(codec->dev, + "%s: Error, invalid micbias register 0x%x\n", + __func__, w->reg); + return -EINVAL; + } + + micbias2 = (snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MICB_2_EN) & 0x80); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (strnstr(w->name, internal1_text, strlen(w->name))) { + if (get_codec_version(sdm660_cdc) >= CAJON) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2, + 0x02, 0x02); + snd_soc_update_bits(codec, micb_int_reg, 0x80, 0x80); + } else if (strnstr(w->name, internal2_text, strlen(w->name))) { + snd_soc_update_bits(codec, micb_int_reg, 0x10, 0x10); + snd_soc_update_bits(codec, w->reg, 0x60, 0x00); + } else if (strnstr(w->name, internal3_text, strlen(w->name))) { + snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x2); + /* + * update MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2 + * for external bias only, not for external2. + */ + } else if (!strnstr(w->name, external2_text, strlen(w->name)) && + strnstr(w->name, external_text, + strlen(w->name))) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2, + 0x02, 0x02); + } + if (!strnstr(w->name, external_text, strlen(w->name))) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MICB_1_EN, 0x05, 0x04); + if (w->reg == MSM89XX_PMIC_ANALOG_MICB_1_EN) + msm_anlg_cdc_configure_cap(codec, true, micbias2); + + break; + case SND_SOC_DAPM_POST_PMU: + if (get_codec_version(sdm660_cdc) <= TOMBAK_2_0) + /* + * Wait for 20ms post micbias enable + * for version < tombak 2.0. + */ + usleep_range(20000, 20100); + if (strnstr(w->name, internal1_text, strlen(w->name))) { + snd_soc_update_bits(codec, micb_int_reg, 0x40, 0x40); + } else if (strnstr(w->name, internal2_text, strlen(w->name))) { + snd_soc_update_bits(codec, micb_int_reg, 0x08, 0x08); + msm_anlg_cdc_notifier_call(codec, + WCD_EVENT_POST_MICBIAS_2_ON); + } else if (strnstr(w->name, internal3_text, 30)) { + snd_soc_update_bits(codec, micb_int_reg, 0x01, 0x01); + } else if (strnstr(w->name, external2_text, strlen(w->name))) { + msm_anlg_cdc_notifier_call(codec, + WCD_EVENT_POST_MICBIAS_2_ON); + } + break; + case SND_SOC_DAPM_POST_PMD: + if (strnstr(w->name, internal1_text, strlen(w->name))) { + snd_soc_update_bits(codec, micb_int_reg, 0xC0, 0x40); + } else if (strnstr(w->name, internal2_text, strlen(w->name))) { + msm_anlg_cdc_notifier_call(codec, + WCD_EVENT_POST_MICBIAS_2_OFF); + } else if (strnstr(w->name, internal3_text, 30)) { + snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x0); + } else if (strnstr(w->name, external2_text, strlen(w->name))) { + /* + * send micbias turn off event to mbhc driver and then + * break, as no need to set MICB_1_EN register. + */ + msm_anlg_cdc_notifier_call(codec, + WCD_EVENT_POST_MICBIAS_2_OFF); + break; + } + if (w->reg == MSM89XX_PMIC_ANALOG_MICB_1_EN) + msm_anlg_cdc_configure_cap(codec, false, micbias2); + break; + } + return 0; +} + +static void update_clkdiv(void *handle, int val) +{ + struct sdm660_cdc_priv *handle_cdc = handle; + struct snd_soc_codec *codec = handle_cdc->codec; + + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_TX_1_2_TXFE_CLKDIV, + 0xFF, val); +} + +static int get_cdc_version(void *handle) +{ + struct sdm660_cdc_priv *sdm660_cdc = handle; + + return get_codec_version(sdm660_cdc); +} + +static int sdm660_wcd_codec_enable_vdd_spkr(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + int ret = 0; + + if (!sdm660_cdc->ext_spk_boost_set) { + dev_dbg(codec->dev, "%s: ext_boost not supported/disabled\n", + __func__); + return 0; + } + dev_dbg(codec->dev, "%s: %s %d\n", __func__, w->name, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (sdm660_cdc->spkdrv_reg) { + ret = regulator_enable(sdm660_cdc->spkdrv_reg); + if (ret) + dev_err(codec->dev, + "%s Failed to enable spkdrv reg %s\n", + __func__, MSM89XX_VDD_SPKDRV_NAME); + } + break; + case SND_SOC_DAPM_POST_PMD: + if (sdm660_cdc->spkdrv_reg) { + ret = regulator_disable(sdm660_cdc->spkdrv_reg); + if (ret) + dev_err(codec->dev, + "%s: Failed to disable spkdrv_reg %s\n", + __func__, MSM89XX_VDD_SPKDRV_NAME); + } + break; + } + return 0; +} + + +/* The register address is the same as other codec so it can use resmgr */ +static int msm_anlg_cdc_codec_enable_rx_bias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + sdm660_cdc->rx_bias_count++; + if (sdm660_cdc->rx_bias_count == 1) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, + 0x80, 0x80); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, + 0x01, 0x01); + } + break; + case SND_SOC_DAPM_POST_PMD: + sdm660_cdc->rx_bias_count--; + if (sdm660_cdc->rx_bias_count == 0) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, + 0x01, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, + 0x80, 0x00); + } + break; + } + dev_dbg(codec->dev, "%s rx_bias_count = %d\n", + __func__, sdm660_cdc->rx_bias_count); + return 0; +} + +static uint32_t wcd_get_impedance_value(uint32_t imped) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(wcd_imped_val) - 1; i++) { + if (imped >= wcd_imped_val[i] && + imped < wcd_imped_val[i + 1]) + break; + } + + pr_debug("%s: selected impedance value = %d\n", + __func__, wcd_imped_val[i]); + return wcd_imped_val[i]; +} + +static void wcd_imped_config(struct snd_soc_codec *codec, + uint32_t imped, bool set_gain) +{ + uint32_t value; + int codec_version; + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + value = wcd_get_impedance_value(imped); + + if (value < wcd_imped_val[0]) { + dev_dbg(codec->dev, + "%s, detected impedance is less than 4 Ohm\n", + __func__); + return; + } + + codec_version = get_codec_version(sdm660_cdc); + + if (set_gain) { + switch (codec_version) { + case TOMBAK_1_0: + case TOMBAK_2_0: + case CONGA: + /* + * For 32Ohm load and higher loads, Set 0x19E + * bit 5 to 1 (POS_0_DB_DI). For loads lower + * than 32Ohm (such as 16Ohm load), Set 0x19E + * bit 5 to 0 (POS_M4P5_DB_DI) + */ + if (value >= 32) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x20, 0x20); + else + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x20, 0x00); + break; + case CAJON: + case CAJON_2_0: + case DIANGU: + case DRAX_CDC: + if (value >= 13) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x20, 0x20); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_NCP_VCTRL, + 0x07, 0x07); + } else { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x20, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_NCP_VCTRL, + 0x07, 0x04); + } + break; + } + } else { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x20, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_NCP_VCTRL, + 0x07, 0x04); + } + + dev_dbg(codec->dev, "%s: Exit\n", __func__); +} + +static int msm_anlg_cdc_hphl_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + uint32_t impedl, impedr; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + int ret; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + ret = wcd_mbhc_get_impedance(&sdm660_cdc->mbhc, + &impedl, &impedr); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (get_codec_version(sdm660_cdc) > CAJON) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, + 0x08, 0x08); + if (get_codec_version(sdm660_cdc) == CAJON || + get_codec_version(sdm660_cdc) == CAJON_2_0) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, + 0x80, 0x80); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, + 0x80, 0x80); + } + if (get_codec_version(sdm660_cdc) > CAJON) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, + 0x08, 0x00); + if (sdm660_cdc->hph_mode == HD2_MODE) + msm_anlg_cdc_dig_notifier_call(codec, + DIG_CDC_EVENT_PRE_RX1_INT_ON); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x02, 0x02); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x01); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x02); + if (!ret) + wcd_imped_config(codec, impedl, true); + else + dev_dbg(codec->dev, "Failed to get mbhc impedance %d\n", + ret); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x02, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + wcd_imped_config(codec, impedl, false); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x00); + if (sdm660_cdc->hph_mode == HD2_MODE) + msm_anlg_cdc_dig_notifier_call(codec, + DIG_CDC_EVENT_POST_RX1_INT_OFF); + break; + } + return 0; +} + +static int msm_anlg_cdc_lo_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x20, 0x20); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x80, 0x80); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x08, 0x08); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x40, 0x40); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x80, 0x80); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x08, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x40, 0x40); + break; + case SND_SOC_DAPM_POST_PMD: + /* Wait for 20ms before powerdown of lineout_dac */ + usleep_range(20000, 20100); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x80, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x40, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x08, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x80, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x40, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x20, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00); + break; + } + return 0; +} + +static int msm_anlg_cdc_hphr_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (sdm660_cdc->hph_mode == HD2_MODE) + msm_anlg_cdc_dig_notifier_call(codec, + DIG_CDC_EVENT_PRE_RX2_INT_ON); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x02, 0x02); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x02, 0x02); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x01, 0x01); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x02, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x01, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x02, 0x00); + if (sdm660_cdc->hph_mode == HD2_MODE) + msm_anlg_cdc_dig_notifier_call(codec, + DIG_CDC_EVENT_POST_RX2_INT_OFF); + break; + } + return 0; +} + +static int msm_anlg_cdc_hph_pa_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: %s event = %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (w->shift == 5) + msm_anlg_cdc_notifier_call(codec, + WCD_EVENT_PRE_HPHL_PA_ON); + else if (w->shift == 4) + msm_anlg_cdc_notifier_call(codec, + WCD_EVENT_PRE_HPHR_PA_ON); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0x20, 0x20); + break; + + case SND_SOC_DAPM_POST_PMU: + /* Wait for 7ms to allow setting time for HPH_PA Enable */ + usleep_range(7000, 7100); + if (w->shift == 5) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x04, 0x04); + msm_anlg_cdc_dig_notifier_call(codec, + DIG_CDC_EVENT_RX1_MUTE_OFF); + } else if (w->shift == 4) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x04, 0x04); + msm_anlg_cdc_dig_notifier_call(codec, + DIG_CDC_EVENT_RX2_MUTE_OFF); + } + break; + + case SND_SOC_DAPM_PRE_PMD: + if (w->shift == 5) { + msm_anlg_cdc_dig_notifier_call(codec, + DIG_CDC_EVENT_RX1_MUTE_ON); + /* Wait for 20ms after HPHL RX digital mute */ + msleep(20); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x04, 0x00); + msm_anlg_cdc_notifier_call(codec, + WCD_EVENT_PRE_HPHL_PA_OFF); + } else if (w->shift == 4) { + msm_anlg_cdc_dig_notifier_call(codec, + DIG_CDC_EVENT_RX2_MUTE_ON); + /* Wait for 20ms after HPHR RX digital mute */ + msleep(20); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x04, 0x00); + msm_anlg_cdc_notifier_call(codec, + WCD_EVENT_PRE_HPHR_PA_OFF); + } + if (get_codec_version(sdm660_cdc) >= CAJON) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_CNP, + 0xF0, 0x30); + } + break; + case SND_SOC_DAPM_POST_PMD: + if (w->shift == 5) { + clear_bit(WCD_MBHC_HPHL_PA_OFF_ACK, + &sdm660_cdc->mbhc.hph_pa_dac_state); + msm_anlg_cdc_notifier_call(codec, + WCD_EVENT_POST_HPHL_PA_OFF); + } else if (w->shift == 4) { + clear_bit(WCD_MBHC_HPHR_PA_OFF_ACK, + &sdm660_cdc->mbhc.hph_pa_dac_state); + msm_anlg_cdc_notifier_call(codec, + WCD_EVENT_POST_HPHR_PA_OFF); + } + /* Wait for 15ms after HPH RX teardown */ + usleep_range(15000, 15100); + break; + } + return 0; +} + +static const struct snd_soc_dapm_route audio_map[] = { + /* RDAC Connections */ + {"HPHR DAC", NULL, "RDAC2 MUX"}, + {"RDAC2 MUX", "RX1", "PDM_IN_RX1"}, + {"RDAC2 MUX", "RX2", "PDM_IN_RX2"}, + + /* WSA */ + {"WSA_SPK OUT", NULL, "WSA Spk Switch"}, + {"WSA Spk Switch", "WSA", "EAR PA"}, + + /* Earpiece (RX MIX1) */ + {"EAR", NULL, "EAR_S"}, + {"EAR_S", "Switch", "EAR PA"}, + {"EAR PA", NULL, "RX_BIAS"}, + {"EAR PA", NULL, "HPHL DAC"}, + {"EAR PA", NULL, "HPHR DAC"}, + {"EAR PA", NULL, "EAR CP"}, + + /* Headset (RX MIX1 and RX MIX2) */ + {"HEADPHONE", NULL, "HPHL PA"}, + {"HEADPHONE", NULL, "HPHR PA"}, + + {"Ext Spk", NULL, "Ext Spk Switch"}, + {"Ext Spk Switch", "On", "HPHL PA"}, + {"Ext Spk Switch", "On", "HPHR PA"}, + + {"HPHL PA", NULL, "HPHL"}, + {"HPHR PA", NULL, "HPHR"}, + {"HPHL", "Switch", "HPHL DAC"}, + {"HPHR", "Switch", "HPHR DAC"}, + {"HPHL PA", NULL, "CP"}, + {"HPHL PA", NULL, "RX_BIAS"}, + {"HPHR PA", NULL, "CP"}, + {"HPHR PA", NULL, "RX_BIAS"}, + {"HPHL DAC", NULL, "PDM_IN_RX1"}, + + {"SPK_OUT", NULL, "SPK PA"}, + {"SPK PA", NULL, "SPK_RX_BIAS"}, + {"SPK PA", NULL, "SPK"}, + {"SPK", "Switch", "SPK DAC"}, + {"SPK DAC", NULL, "PDM_IN_RX3"}, + {"SPK DAC", NULL, "VDD_SPKDRV"}, + + /* lineout */ + {"LINEOUT", NULL, "LINEOUT PA"}, + {"LINEOUT PA", NULL, "SPK_RX_BIAS"}, + {"LINEOUT PA", NULL, "LINE_OUT"}, + {"LINE_OUT", "Switch", "LINEOUT DAC"}, + {"LINEOUT DAC", NULL, "PDM_IN_RX3"}, + + /* lineout to WSA */ + {"WSA_SPK OUT", NULL, "LINEOUT PA"}, + + {"PDM_IN_RX1", NULL, "RX1 CLK"}, + {"PDM_IN_RX2", NULL, "RX2 CLK"}, + {"PDM_IN_RX3", NULL, "RX3 CLK"}, + + {"ADC1_OUT", NULL, "ADC1"}, + {"ADC2_OUT", NULL, "ADC2"}, + {"ADC3_OUT", NULL, "ADC3"}, + + /* ADC Connections */ + {"ADC2", NULL, "ADC2 MUX"}, + {"ADC3", NULL, "ADC2 MUX"}, + {"ADC2 MUX", "INP2", "ADC2_INP2"}, + {"ADC2 MUX", "INP3", "ADC2_INP3"}, + + {"ADC1", NULL, "AMIC1"}, + {"ADC2_INP2", NULL, "AMIC2"}, + {"ADC2_INP3", NULL, "AMIC3"}, + + {"MIC BIAS Internal1", NULL, "INT_LDO_H"}, + {"MIC BIAS Internal2", NULL, "INT_LDO_H"}, + {"MIC BIAS External", NULL, "INT_LDO_H"}, + {"MIC BIAS External2", NULL, "INT_LDO_H"}, + {"MIC BIAS Internal1", NULL, "MICBIAS_REGULATOR"}, + {"MIC BIAS Internal2", NULL, "MICBIAS_REGULATOR"}, + {"MIC BIAS External", NULL, "MICBIAS_REGULATOR"}, + {"MIC BIAS External2", NULL, "MICBIAS_REGULATOR"}, +}; + +static int msm_anlg_cdc_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(dai->codec); + + dev_dbg(dai->codec->dev, "%s(): substream = %s stream = %d\n", + __func__, + substream->name, substream->stream); + /* + * If status_mask is BUS_DOWN it means SSR is not complete. + * So return error. + */ + if (test_bit(BUS_DOWN, &sdm660_cdc->status_mask)) { + dev_err(dai->codec->dev, "Error, Device is not up post SSR\n"); + return -EINVAL; + } + return 0; +} + +static void msm_anlg_cdc_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + dev_dbg(dai->codec->dev, + "%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); +} + +int msm_anlg_cdc_mclk_enable(struct snd_soc_codec *codec, + int mclk_enable, bool dapm) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: mclk_enable = %u, dapm = %d\n", + __func__, mclk_enable, dapm); + if (mclk_enable) { + sdm660_cdc->int_mclk0_enabled = true; + msm_anlg_cdc_codec_enable_clock_block(codec, 1); + } else { + if (!sdm660_cdc->int_mclk0_enabled) { + dev_err(codec->dev, "Error, MCLK already diabled\n"); + return -EINVAL; + } + sdm660_cdc->int_mclk0_enabled = false; + msm_anlg_cdc_codec_enable_clock_block(codec, 0); + } + return 0; +} + +static int msm_anlg_cdc_set_dai_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + dev_dbg(dai->codec->dev, "%s\n", __func__); + return 0; +} + +static int msm_anlg_cdc_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + dev_dbg(dai->codec->dev, "%s\n", __func__); + return 0; +} + +static int msm_anlg_cdc_set_channel_map(struct snd_soc_dai *dai, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot) + +{ + dev_dbg(dai->codec->dev, "%s\n", __func__); + return 0; +} + +static int msm_anlg_cdc_get_channel_map(struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot) + +{ + dev_dbg(dai->codec->dev, "%s\n", __func__); + return 0; +} + +static struct snd_soc_dai_ops msm_anlg_cdc_dai_ops = { + .startup = msm_anlg_cdc_startup, + .shutdown = msm_anlg_cdc_shutdown, + .set_sysclk = msm_anlg_cdc_set_dai_sysclk, + .set_fmt = msm_anlg_cdc_set_dai_fmt, + .set_channel_map = msm_anlg_cdc_set_channel_map, + .get_channel_map = msm_anlg_cdc_get_channel_map, +}; + +static struct snd_soc_dai_driver msm_anlg_cdc_i2s_dai[] = { + { + .name = "msm_anlg_cdc_i2s_rx1", + .id = AIF1_PB, + .playback = { + .stream_name = "PDM Playback", + .rates = SDM660_CDC_RATES, + .formats = SDM660_CDC_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 3, + }, + .ops = &msm_anlg_cdc_dai_ops, + }, + { + .name = "msm_anlg_cdc_i2s_tx1", + .id = AIF1_CAP, + .capture = { + .stream_name = "PDM Capture", + .rates = SDM660_CDC_RATES, + .formats = SDM660_CDC_FORMATS, + .rate_max = 48000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 4, + }, + .ops = &msm_anlg_cdc_dai_ops, + }, + { + .name = "msm_anlg_cdc_i2s_tx2", + .id = AIF3_SVA, + .capture = { + .stream_name = "RecordSVA", + .rates = SDM660_CDC_RATES, + .formats = SDM660_CDC_FORMATS, + .rate_max = 48000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &msm_anlg_cdc_dai_ops, + }, + { + .name = "msm_anlg_vifeedback", + .id = AIF2_VIFEED, + .capture = { + .stream_name = "VIfeed", + .rates = SDM660_CDC_RATES, + .formats = SDM660_CDC_FORMATS, + .rate_max = 48000, + .rate_min = 48000, + .channels_min = 2, + .channels_max = 2, + }, + .ops = &msm_anlg_cdc_dai_ops, + }, +}; + + +static int msm_anlg_cdc_codec_enable_lo_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s: %d %s\n", __func__, event, w->name); + switch (event) { + case SND_SOC_DAPM_POST_PMU: + msm_anlg_cdc_dig_notifier_call(codec, + DIG_CDC_EVENT_RX3_MUTE_OFF); + break; + case SND_SOC_DAPM_POST_PMD: + msm_anlg_cdc_dig_notifier_call(codec, + DIG_CDC_EVENT_RX3_MUTE_ON); + break; + } + + return 0; +} + +static int msm_anlg_cdc_codec_enable_spk_ext_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: %s event = %d\n", __func__, w->name, event); + switch (event) { + case SND_SOC_DAPM_POST_PMU: + dev_dbg(codec->dev, + "%s: enable external speaker PA\n", __func__); + if (sdm660_cdc->codec_spk_ext_pa_cb) + sdm660_cdc->codec_spk_ext_pa_cb(codec, 1); + break; + case SND_SOC_DAPM_PRE_PMD: + dev_dbg(codec->dev, + "%s: enable external speaker PA\n", __func__); + if (sdm660_cdc->codec_spk_ext_pa_cb) + sdm660_cdc->codec_spk_ext_pa_cb(codec, 0); + break; + } + return 0; +} + +static int msm_anlg_cdc_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + dev_dbg(codec->dev, + "%s: Sleeping 20ms after select EAR PA\n", + __func__); + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x80, 0x80); + if (get_codec_version(sdm660_cdc) < CONGA) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME, 0xFF, 0x2A); + if (get_codec_version(sdm660_cdc) >= DIANGU) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, 0x08, 0x00); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x04, 0x04); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x04, 0x04); + } + break; + case SND_SOC_DAPM_POST_PMU: + dev_dbg(codec->dev, + "%s: Sleeping 20ms after enabling EAR PA\n", + __func__); + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x40, 0x40); + /* Wait for 7ms after EAR PA enable */ + usleep_range(7000, 7100); + msm_anlg_cdc_dig_notifier_call(codec, + DIG_CDC_EVENT_RX1_MUTE_OFF); + break; + case SND_SOC_DAPM_PRE_PMD: + msm_anlg_cdc_dig_notifier_call(codec, + DIG_CDC_EVENT_RX1_MUTE_ON); + /* Wait for 20ms for RX digital mute to take effect */ + msleep(20); + if (sdm660_cdc->boost_option == BOOST_ALWAYS) { + dev_dbg(codec->dev, + "%s: boost_option:%d, tear down ear\n", + __func__, sdm660_cdc->boost_option); + msm_anlg_cdc_boost_mode_sequence(codec, EAR_PMD); + } + if (get_codec_version(sdm660_cdc) >= DIANGU) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x04, 0x0); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x04, 0x0); + } + break; + case SND_SOC_DAPM_POST_PMD: + dev_dbg(codec->dev, + "%s: Sleeping 7ms after disabling EAR PA\n", + __func__); + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x40, 0x00); + /* Wait for 7ms after EAR PA teardown */ + usleep_range(7000, 7100); + if (get_codec_version(sdm660_cdc) < CONGA) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME, 0xFF, 0x16); + if (get_codec_version(sdm660_cdc) >= DIANGU) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, 0x08, 0x08); + break; + } + return 0; +} + +static const struct snd_soc_dapm_widget msm_anlg_cdc_dapm_widgets[] = { + SND_SOC_DAPM_PGA_E("EAR PA", SND_SOC_NOPM, + 0, 0, NULL, 0, msm_anlg_cdc_codec_enable_ear_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("HPHL PA", MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, + 5, 0, NULL, 0, + msm_anlg_cdc_hph_pa_event, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("HPHR PA", MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, + 4, 0, NULL, 0, + msm_anlg_cdc_hph_pa_event, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("SPK PA", SND_SOC_NOPM, + 0, 0, NULL, 0, msm_anlg_cdc_codec_enable_spk_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("LINEOUT PA", MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, + 5, 0, NULL, 0, msm_anlg_cdc_codec_enable_lo_pa, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("EAR_S", SND_SOC_NOPM, 0, 0, ear_pa_mux), + SND_SOC_DAPM_MUX("SPK", SND_SOC_NOPM, 0, 0, spkr_mux), + SND_SOC_DAPM_MUX("HPHL", SND_SOC_NOPM, 0, 0, hphl_mux), + SND_SOC_DAPM_MUX("HPHR", SND_SOC_NOPM, 0, 0, hphr_mux), + SND_SOC_DAPM_MUX("RDAC2 MUX", SND_SOC_NOPM, 0, 0, &rdac2_mux), + SND_SOC_DAPM_MUX("WSA Spk Switch", SND_SOC_NOPM, 0, 0, wsa_spk_mux), + SND_SOC_DAPM_MUX("Ext Spk Switch", SND_SOC_NOPM, 0, 0, &ext_spk_mux), + SND_SOC_DAPM_MUX("LINE_OUT", SND_SOC_NOPM, 0, 0, lo_mux), + SND_SOC_DAPM_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, &tx_adc2_mux), + + SND_SOC_DAPM_MIXER_E("HPHL DAC", + MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 3, 0, NULL, + 0, msm_anlg_cdc_hphl_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("HPHR DAC", + MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 3, 0, NULL, + 0, msm_anlg_cdc_hphr_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("ADC2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("ADC3", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_DAC("SPK DAC", NULL, MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, + 7, 0), + SND_SOC_DAPM_DAC_E("LINEOUT DAC", NULL, + SND_SOC_NOPM, 0, 0, msm_anlg_cdc_lo_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SPK("Ext Spk", msm_anlg_cdc_codec_enable_spk_ext_pa), + + SND_SOC_DAPM_SUPPLY("RX1 CLK", MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("RX2 CLK", MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 1, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("RX3 CLK", MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 2, 0, msm_anlg_cdc_codec_enable_dig_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("CP", MSM89XX_PMIC_ANALOG_NCP_EN, 0, 0, + msm_anlg_cdc_codec_enable_charge_pump, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("EAR CP", MSM89XX_PMIC_ANALOG_NCP_EN, 4, 0, + msm_anlg_cdc_codec_enable_charge_pump, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("RX_BIAS", 1, SND_SOC_NOPM, + 0, 0, msm_anlg_cdc_codec_enable_rx_bias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("SPK_RX_BIAS", 1, SND_SOC_NOPM, 0, 0, + msm_anlg_cdc_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("VDD_SPKDRV", SND_SOC_NOPM, 0, 0, + sdm660_wcd_codec_enable_vdd_spkr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("INT_LDO_H", SND_SOC_NOPM, 1, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("MICBIAS_REGULATOR", SND_SOC_NOPM, + ON_DEMAND_MICBIAS, 0, + msm_anlg_cdc_codec_enable_on_demand_supply, + SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MICBIAS_E("MIC BIAS Internal1", + MSM89XX_PMIC_ANALOG_MICB_1_EN, 7, 0, + msm_anlg_cdc_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS Internal2", + MSM89XX_PMIC_ANALOG_MICB_2_EN, 7, 0, + msm_anlg_cdc_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS Internal3", + MSM89XX_PMIC_ANALOG_MICB_1_EN, 7, 0, + msm_anlg_cdc_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("ADC1", NULL, MSM89XX_PMIC_ANALOG_TX_1_EN, 7, 0, + msm_anlg_cdc_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("ADC2_INP2", + NULL, MSM89XX_PMIC_ANALOG_TX_2_EN, 7, 0, + msm_anlg_cdc_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("ADC2_INP3", + NULL, MSM89XX_PMIC_ANALOG_TX_3_EN, 7, 0, + msm_anlg_cdc_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MICBIAS_E("MIC BIAS External", + MSM89XX_PMIC_ANALOG_MICB_1_EN, 7, 0, + msm_anlg_cdc_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS External2", + MSM89XX_PMIC_ANALOG_MICB_2_EN, 7, 0, + msm_anlg_cdc_codec_enable_micbias, SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_INPUT("AMIC1"), + SND_SOC_DAPM_INPUT("AMIC2"), + SND_SOC_DAPM_INPUT("AMIC3"), + SND_SOC_DAPM_AIF_IN("PDM_IN_RX1", "PDM Playback", + 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("PDM_IN_RX2", "PDM Playback", + 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("PDM_IN_RX3", "PDM Playback", + 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_OUTPUT("EAR"), + SND_SOC_DAPM_OUTPUT("WSA_SPK OUT"), + SND_SOC_DAPM_OUTPUT("HEADPHONE"), + SND_SOC_DAPM_OUTPUT("SPK_OUT"), + SND_SOC_DAPM_OUTPUT("LINEOUT"), + SND_SOC_DAPM_AIF_OUT("ADC1_OUT", "PDM Capture", + 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("ADC2_OUT", "PDM Capture", + 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("ADC3_OUT", "PDM Capture", + 0, SND_SOC_NOPM, 0, 0), +}; + +static const struct sdm660_cdc_reg_mask_val msm_anlg_cdc_reg_defaults[] = { + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x03), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x82), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1), +}; + +static const struct sdm660_cdc_reg_mask_val + msm_anlg_cdc_reg_defaults_2_0[] = { + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0xA5), + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x0F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x4F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0x28), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x69), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x01), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, 0x5F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO, 0x88), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0xA5), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x0F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x82), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x03), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1), + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80), +}; + +static const struct sdm660_cdc_reg_mask_val conga_wcd_reg_defaults[] = { + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0xA5), + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x0F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0xA5), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x0F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x4C), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0x28), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x69), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x01), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_PERPH_SUBTYPE, 0x0A), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x03), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1), + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80), +}; + +static const struct sdm660_cdc_reg_mask_val cajon_wcd_reg_defaults[] = { + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0xA5), + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x0F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0xA5), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x0F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x4C), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x82), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0xA8), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_VCTRL, 0xA4), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET, 0x41), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x69), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x01), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x03), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA, 0xFA), + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80), +}; + +static const struct sdm660_cdc_reg_mask_val cajon2p0_wcd_reg_defaults[] = { + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0xA5), + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x0F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0xA5), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x0F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x4C), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0xA2), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0xA8), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_VCTRL, 0xA4), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET, 0x41), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x69), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x01), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x03), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_RX_EAR_STATUS, 0x10), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_BYPASS_MODE, 0x18), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA, 0xFA), + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80), +}; + +static void msm_anlg_cdc_update_reg_defaults(struct snd_soc_codec *codec) +{ + u32 i, version; + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_codec_get_drvdata(codec); + + version = get_codec_version(sdm660_cdc); + if (version == TOMBAK_1_0) { + for (i = 0; i < ARRAY_SIZE(msm_anlg_cdc_reg_defaults); i++) + snd_soc_write(codec, msm_anlg_cdc_reg_defaults[i].reg, + msm_anlg_cdc_reg_defaults[i].val); + } else if (version == TOMBAK_2_0) { + for (i = 0; i < ARRAY_SIZE(msm_anlg_cdc_reg_defaults_2_0); i++) + snd_soc_write(codec, + msm_anlg_cdc_reg_defaults_2_0[i].reg, + msm_anlg_cdc_reg_defaults_2_0[i].val); + } else if (version == CONGA) { + for (i = 0; i < ARRAY_SIZE(conga_wcd_reg_defaults); i++) + snd_soc_write(codec, + conga_wcd_reg_defaults[i].reg, + conga_wcd_reg_defaults[i].val); + } else if (version == CAJON) { + for (i = 0; i < ARRAY_SIZE(cajon_wcd_reg_defaults); i++) + snd_soc_write(codec, + cajon_wcd_reg_defaults[i].reg, + cajon_wcd_reg_defaults[i].val); + } else if (version == CAJON_2_0 || version == DIANGU + || version == DRAX_CDC) { + for (i = 0; i < ARRAY_SIZE(cajon2p0_wcd_reg_defaults); i++) + snd_soc_write(codec, + cajon2p0_wcd_reg_defaults[i].reg, + cajon2p0_wcd_reg_defaults[i].val); + } +} + +static const struct sdm660_cdc_reg_mask_val + msm_anlg_cdc_codec_reg_init_val[] = { + + /* Initialize current threshold to 350MA + * number of wait and run cycles to 4096 + */ + {MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL, 0xFF, 0x12}, + {MSM89XX_PMIC_ANALOG_RX_COM_OCP_COUNT, 0xFF, 0xFF}, +}; + +static void msm_anlg_cdc_codec_init_cache(struct snd_soc_codec *codec) +{ + u32 i; + + regcache_cache_only(codec->component.regmap, true); + /* update cache with POR values */ + for (i = 0; i < ARRAY_SIZE(msm89xx_pmic_cdc_defaults); i++) + snd_soc_write(codec, msm89xx_pmic_cdc_defaults[i].reg, + msm89xx_pmic_cdc_defaults[i].def); + regcache_cache_only(codec->component.regmap, false); +} + +static void msm_anlg_cdc_codec_init_reg(struct snd_soc_codec *codec) +{ + u32 i; + + for (i = 0; i < ARRAY_SIZE(msm_anlg_cdc_codec_reg_init_val); i++) + snd_soc_update_bits(codec, + msm_anlg_cdc_codec_reg_init_val[i].reg, + msm_anlg_cdc_codec_reg_init_val[i].mask, + msm_anlg_cdc_codec_reg_init_val[i].val); +} + +static int msm_anlg_cdc_bringup(struct snd_soc_codec *codec) +{ + snd_soc_write(codec, + MSM89XX_PMIC_DIGITAL_SEC_ACCESS, + 0xA5); + snd_soc_write(codec, MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4, 0x01); + snd_soc_write(codec, + MSM89XX_PMIC_ANALOG_SEC_ACCESS, + 0xA5); + snd_soc_write(codec, MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4, 0x01); + snd_soc_write(codec, + MSM89XX_PMIC_DIGITAL_SEC_ACCESS, + 0xA5); + snd_soc_write(codec, MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4, 0x00); + snd_soc_write(codec, + MSM89XX_PMIC_ANALOG_SEC_ACCESS, + 0xA5); + snd_soc_write(codec, MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4, 0x00); + + return 0; +} + +static struct regulator *msm_anlg_cdc_find_regulator( + const struct sdm660_cdc_priv *sdm660_cdc, + const char *name) +{ + int i; + + for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { + if (sdm660_cdc->supplies[i].supply && + !strcmp(sdm660_cdc->supplies[i].supply, name)) + return sdm660_cdc->supplies[i].consumer; + } + + dev_err(sdm660_cdc->dev, "Error: regulator not found:%s\n" + , name); + return NULL; +} + +static void msm_anlg_cdc_update_micbias_regulator( + const struct sdm660_cdc_priv *sdm660_cdc, + const char *name, + struct on_demand_supply *micbias_supply) +{ + int i; + struct sdm660_cdc_pdata *pdata = sdm660_cdc->dev->platform_data; + + for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { + if (sdm660_cdc->supplies[i].supply && + !strcmp(sdm660_cdc->supplies[i].supply, name)) { + micbias_supply->supply = + sdm660_cdc->supplies[i].consumer; + micbias_supply->min_uv = pdata->regulator[i].min_uv; + micbias_supply->max_uv = pdata->regulator[i].max_uv; + micbias_supply->optimum_ua = + pdata->regulator[i].optimum_ua; + return; + } + } + + dev_err(sdm660_cdc->dev, "Error: regulator not found:%s\n", name); +} + +static int msm_anlg_cdc_device_down(struct snd_soc_codec *codec) +{ + struct msm_asoc_mach_data *pdata = NULL; + struct sdm660_cdc_priv *sdm660_cdc_priv = + snd_soc_codec_get_drvdata(codec); + unsigned int tx_1_en; + unsigned int tx_2_en; + + pdata = snd_soc_card_get_drvdata(codec->component.card); + dev_dbg(codec->dev, "%s: device down!\n", __func__); + + tx_1_en = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_TX_1_EN); + tx_2_en = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_TX_2_EN); + tx_1_en = tx_1_en & 0x7f; + tx_2_en = tx_2_en & 0x7f; + snd_soc_write(codec, + MSM89XX_PMIC_ANALOG_TX_1_EN, tx_1_en); + snd_soc_write(codec, + MSM89XX_PMIC_ANALOG_TX_2_EN, tx_2_en); + if (sdm660_cdc_priv->boost_option == BOOST_ON_FOREVER) { + if ((snd_soc_read(codec, MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL) + & 0x80) == 0) { + msm_anlg_cdc_dig_notifier_call(codec, + DIG_CDC_EVENT_CLK_ON); + snd_soc_write(codec, + MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, 0x30); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80, 0x80); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL, + 0x0C, 0x0C); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x84, 0x84); + snd_soc_update_bits(codec, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, + 0x10, 0x10); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, + 0x1F, 0x1F); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, + 0x90, 0x90); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0xFF, 0xFF); + /* Wait for 20us for boost settings to take effect */ + usleep_range(20, 21); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, + 0xFF, 0xFF); + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, + 0xE9, 0xE9); + } + } + msm_anlg_cdc_boost_off(codec); + sdm660_cdc_priv->hph_mode = NORMAL_MODE; + + /* 40ms to allow boost to discharge */ + msleep(40); + /* Disable PA to avoid pop during codec bring up */ + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, + 0x30, 0x00); + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, + 0x80, 0x00); + snd_soc_write(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x20); + snd_soc_write(codec, + MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x20); + snd_soc_write(codec, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x12); + snd_soc_write(codec, + MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x93); + + msm_anlg_cdc_dig_notifier_call(codec, DIG_CDC_EVENT_SSR_DOWN); + atomic_set(&pdata->int_mclk0_enabled, false); + set_bit(BUS_DOWN, &sdm660_cdc_priv->status_mask); + snd_soc_card_change_online_state(codec->component.card, 0); + + return 0; +} + +static int msm_anlg_cdc_device_up(struct snd_soc_codec *codec) +{ + struct sdm660_cdc_priv *sdm660_cdc_priv = + snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: device up!\n", __func__); + + msm_anlg_cdc_dig_notifier_call(codec, DIG_CDC_EVENT_SSR_UP); + clear_bit(BUS_DOWN, &sdm660_cdc_priv->status_mask); + snd_soc_card_change_online_state(codec->component.card, 1); + /* delay is required to make sure sound card state updated */ + usleep_range(5000, 5100); + + snd_soc_write(codec, MSM89XX_PMIC_DIGITAL_INT_EN_SET, + MSM89XX_PMIC_DIGITAL_INT_EN_SET__POR); + snd_soc_write(codec, MSM89XX_PMIC_DIGITAL_INT_EN_CLR, + MSM89XX_PMIC_DIGITAL_INT_EN_CLR__POR); + + msm_anlg_cdc_set_boost_v(codec); + msm_anlg_cdc_set_micb_v(codec); + if (sdm660_cdc_priv->boost_option == BOOST_ON_FOREVER) + msm_anlg_cdc_boost_on(codec); + else if (sdm660_cdc_priv->boost_option == BYPASS_ALWAYS) + msm_anlg_cdc_bypass_on(codec); + + return 0; +} + +static int sdm660_cdc_notifier_service_cb(struct notifier_block *nb, + unsigned long opcode, void *ptr) +{ + struct snd_soc_codec *codec; + struct sdm660_cdc_priv *sdm660_cdc_priv = + container_of(nb, struct sdm660_cdc_priv, + audio_ssr_nb); + bool adsp_ready = false; + bool timedout; + unsigned long timeout; + static bool initial_boot = true; + + codec = sdm660_cdc_priv->codec; + dev_dbg(codec->dev, "%s: Service opcode 0x%lx\n", __func__, opcode); + + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + if (initial_boot) { + initial_boot = false; + break; + } + dev_dbg(codec->dev, + "ADSP is about to power down. teardown/reset codec\n"); + msm_anlg_cdc_device_down(codec); + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (initial_boot) + initial_boot = false; + dev_dbg(codec->dev, + "ADSP is about to power up. bring up codec\n"); + + if (!q6core_is_adsp_ready()) { + dev_dbg(codec->dev, + "ADSP isn't ready\n"); + timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + while (!(timedout = time_after(jiffies, timeout))) { + if (!q6core_is_adsp_ready()) { + dev_dbg(codec->dev, + "ADSP isn't ready\n"); + } else { + dev_dbg(codec->dev, + "ADSP is ready\n"); + adsp_ready = true; + goto powerup; + } + } + } else { + adsp_ready = true; + dev_dbg(codec->dev, "%s: DSP is ready\n", __func__); + } +powerup: + if (adsp_ready) + msm_anlg_cdc_device_up(codec); + break; + default: + break; + } + return NOTIFY_OK; +} + +int msm_anlg_cdc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg) +{ + struct sdm660_cdc_priv *sdm660_cdc_priv = + snd_soc_codec_get_drvdata(codec); + + return wcd_mbhc_start(&sdm660_cdc_priv->mbhc, mbhc_cfg); +} +EXPORT_SYMBOL(msm_anlg_cdc_hs_detect); + +void msm_anlg_cdc_hs_detect_exit(struct snd_soc_codec *codec) +{ + struct sdm660_cdc_priv *sdm660_cdc_priv = + snd_soc_codec_get_drvdata(codec); + + wcd_mbhc_stop(&sdm660_cdc_priv->mbhc); +} +EXPORT_SYMBOL(msm_anlg_cdc_hs_detect_exit); + +void msm_anlg_cdc_update_int_spk_boost(bool enable) +{ + pr_debug("%s: enable = %d\n", __func__, enable); + spkr_boost_en = enable; +} +EXPORT_SYMBOL(msm_anlg_cdc_update_int_spk_boost); + +static void msm_anlg_cdc_set_micb_v(struct snd_soc_codec *codec) +{ + + struct sdm660_cdc_priv *sdm660_cdc = snd_soc_codec_get_drvdata(codec); + struct sdm660_cdc_pdata *pdata = sdm660_cdc->dev->platform_data; + u8 reg_val; + + reg_val = VOLTAGE_CONVERTER(pdata->micbias.cfilt1_mv, MICBIAS_MIN_VAL, + MICBIAS_STEP_SIZE); + dev_dbg(codec->dev, "cfilt1_mv %d reg_val %x\n", + (u32)pdata->micbias.cfilt1_mv, reg_val); + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_MICB_1_VAL, + 0xF8, (reg_val << 3)); +} + +static void msm_anlg_cdc_set_boost_v(struct snd_soc_codec *codec) +{ + struct sdm660_cdc_priv *sdm660_cdc_priv = + snd_soc_codec_get_drvdata(codec); + + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_OUTPUT_VOLTAGE, + 0x1F, sdm660_cdc_priv->boost_voltage); +} + +static void msm_anlg_cdc_configure_cap(struct snd_soc_codec *codec, + bool micbias1, bool micbias2) +{ + + struct msm_asoc_mach_data *pdata = NULL; + + pdata = snd_soc_card_get_drvdata(codec->component.card); + + pr_debug("\n %s: micbias1 %x micbias2 = %d\n", __func__, micbias1, + micbias2); + if (micbias1 && micbias2) { + if ((pdata->micbias1_cap_mode + == MICBIAS_EXT_BYP_CAP) || + (pdata->micbias2_cap_mode + == MICBIAS_EXT_BYP_CAP)) + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MICB_1_EN, + 0x40, (MICBIAS_EXT_BYP_CAP << 6)); + else + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_MICB_1_EN, + 0x40, (MICBIAS_NO_EXT_BYP_CAP << 6)); + } else if (micbias2) { + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_MICB_1_EN, + 0x40, (pdata->micbias2_cap_mode << 6)); + } else if (micbias1) { + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_MICB_1_EN, + 0x40, (pdata->micbias1_cap_mode << 6)); + } else { + snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_MICB_1_EN, + 0x40, 0x00); + } +} + +static ssize_t msm_anlg_codec_version_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, size_t count, + loff_t pos) +{ + struct sdm660_cdc_priv *sdm660_cdc_priv; + char buffer[MSM_ANLG_CDC_VERSION_ENTRY_SIZE]; + int len = 0; + + sdm660_cdc_priv = (struct sdm660_cdc_priv *) entry->private_data; + if (!sdm660_cdc_priv) { + pr_err("%s: sdm660_cdc_priv is null\n", __func__); + return -EINVAL; + } + + switch (get_codec_version(sdm660_cdc_priv)) { + case DRAX_CDC: + len = snprintf(buffer, sizeof(buffer), "DRAX-CDC_1_0\n"); + break; + default: + len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + } + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops msm_anlg_codec_info_ops = { + .read = msm_anlg_codec_version_read, +}; + +/* + * msm_anlg_codec_info_create_codec_entry - creates pmic_analog module + * @codec_root: The parent directory + * @codec: Codec instance + * + * Creates pmic_analog module and version entry under the given + * parent directory. + * + * Return: 0 on success or negative error code on failure. + */ +int msm_anlg_codec_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + struct snd_info_entry *version_entry; + struct sdm660_cdc_priv *sdm660_cdc_priv; + struct snd_soc_card *card; + int ret; + + if (!codec_root || !codec) + return -EINVAL; + + sdm660_cdc_priv = snd_soc_codec_get_drvdata(codec); + card = codec->component.card; + sdm660_cdc_priv->entry = snd_register_module_info(codec_root->module, + "spmi0-03", + codec_root); + if (!sdm660_cdc_priv->entry) { + dev_dbg(codec->dev, "%s: failed to create pmic_analog entry\n", + __func__); + return -ENOMEM; + } + + version_entry = snd_info_create_card_entry(card->snd_card, + "version", + sdm660_cdc_priv->entry); + if (!version_entry) { + dev_dbg(codec->dev, "%s: failed to create pmic_analog version entry\n", + __func__); + return -ENOMEM; + } + + version_entry->private_data = sdm660_cdc_priv; + version_entry->size = MSM_ANLG_CDC_VERSION_ENTRY_SIZE; + version_entry->content = SNDRV_INFO_CONTENT_DATA; + version_entry->c.ops = &msm_anlg_codec_info_ops; + + if (snd_info_register(version_entry) < 0) { + snd_info_free_entry(version_entry); + return -ENOMEM; + } + sdm660_cdc_priv->version_entry = version_entry; + + sdm660_cdc_priv->audio_ssr_nb.notifier_call = + sdm660_cdc_notifier_service_cb; + ret = audio_notifier_register("pmic_analog_cdc", + AUDIO_NOTIFIER_ADSP_DOMAIN, + &sdm660_cdc_priv->audio_ssr_nb); + if (ret < 0) { + pr_err("%s: Audio notifier register failed ret = %d\n", + __func__, ret); + return ret; + } + return 0; +} +EXPORT_SYMBOL(msm_anlg_codec_info_create_codec_entry); + +static int msm_anlg_cdc_soc_probe(struct snd_soc_codec *codec) +{ + struct sdm660_cdc_priv *sdm660_cdc; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + int ret; + + sdm660_cdc = dev_get_drvdata(codec->dev); + sdm660_cdc->codec = codec; + + /* codec resmgr module init */ + sdm660_cdc->spkdrv_reg = + msm_anlg_cdc_find_regulator(sdm660_cdc, + MSM89XX_VDD_SPKDRV_NAME); + sdm660_cdc->pmic_rev = + snd_soc_read(codec, + MSM89XX_PMIC_DIGITAL_REVISION1); + sdm660_cdc->codec_version = + snd_soc_read(codec, + MSM89XX_PMIC_DIGITAL_PERPH_SUBTYPE); + sdm660_cdc->analog_major_rev = + snd_soc_read(codec, + MSM89XX_PMIC_ANALOG_REVISION4); + + if (sdm660_cdc->codec_version == CONGA) { + dev_dbg(codec->dev, "%s :Conga REV: %d\n", __func__, + sdm660_cdc->codec_version); + sdm660_cdc->ext_spk_boost_set = true; + } else { + dev_dbg(codec->dev, "%s :PMIC REV: %d\n", __func__, + sdm660_cdc->pmic_rev); + if (sdm660_cdc->pmic_rev == TOMBAK_1_0 && + sdm660_cdc->codec_version == CAJON_2_0) { + if (sdm660_cdc->analog_major_rev == 0x02) { + sdm660_cdc->codec_version = DRAX_CDC; + dev_dbg(codec->dev, + "%s : Drax codec detected\n", __func__); + } else { + sdm660_cdc->codec_version = DIANGU; + dev_dbg(codec->dev, "%s : Diangu detected\n", + __func__); + } + } else if (sdm660_cdc->pmic_rev == TOMBAK_1_0 && + (snd_soc_read(codec, MSM89XX_PMIC_ANALOG_NCP_FBCTRL) + & 0x80)) { + sdm660_cdc->codec_version = CAJON; + dev_dbg(codec->dev, "%s : Cajon detected\n", __func__); + } else if (sdm660_cdc->pmic_rev == TOMBAK_2_0 && + (snd_soc_read(codec, MSM89XX_PMIC_ANALOG_NCP_FBCTRL) + & 0x80)) { + sdm660_cdc->codec_version = CAJON_2_0; + dev_dbg(codec->dev, "%s : Cajon 2.0 detected\n", + __func__); + } + } + /* + * set to default boost option BOOST_SWITCH, user mixer path can change + * it to BOOST_ALWAYS or BOOST_BYPASS based on solution chosen. + */ + sdm660_cdc->boost_option = BOOST_SWITCH; + sdm660_cdc->hph_mode = NORMAL_MODE; + + msm_anlg_cdc_dt_parse_boost_info(codec); + msm_anlg_cdc_set_boost_v(codec); + + snd_soc_add_codec_controls(codec, impedance_detect_controls, + ARRAY_SIZE(impedance_detect_controls)); + snd_soc_add_codec_controls(codec, hph_type_detect_controls, + ARRAY_SIZE(hph_type_detect_controls)); + + msm_anlg_cdc_bringup(codec); + msm_anlg_cdc_codec_init_cache(codec); + msm_anlg_cdc_codec_init_reg(codec); + msm_anlg_cdc_update_reg_defaults(codec); + + wcd9xxx_spmi_set_codec(codec); + + msm_anlg_cdc_update_micbias_regulator( + sdm660_cdc, + on_demand_supply_name[ON_DEMAND_MICBIAS], + &sdm660_cdc->on_demand_list[ON_DEMAND_MICBIAS]); + atomic_set(&sdm660_cdc->on_demand_list[ON_DEMAND_MICBIAS].ref, + 0); + + sdm660_cdc->fw_data = devm_kzalloc(codec->dev, + sizeof(*(sdm660_cdc->fw_data)), + GFP_KERNEL); + if (!sdm660_cdc->fw_data) + return -ENOMEM; + + set_bit(WCD9XXX_MBHC_CAL, sdm660_cdc->fw_data->cal_bit); + ret = wcd_cal_create_hwdep(sdm660_cdc->fw_data, + WCD9XXX_CODEC_HWDEP_NODE, codec); + if (ret < 0) { + dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret); + return ret; + } + + wcd_mbhc_init(&sdm660_cdc->mbhc, codec, &mbhc_cb, &intr_ids, + wcd_mbhc_registers, true); + + sdm660_cdc->int_mclk0_enabled = false; + /*Update speaker boost configuration*/ + sdm660_cdc->spk_boost_set = spkr_boost_en; + pr_debug("%s: speaker boost configured = %d\n", + __func__, sdm660_cdc->spk_boost_set); + + /* Set initial MICBIAS voltage level */ + msm_anlg_cdc_set_micb_v(codec); + + /* Set initial cap mode */ + msm_anlg_cdc_configure_cap(codec, false, false); + + snd_soc_dapm_ignore_suspend(dapm, "PDM Playback"); + snd_soc_dapm_ignore_suspend(dapm, "PDM Capture"); + + snd_soc_dapm_sync(dapm); + + return 0; +} + +static int msm_anlg_cdc_soc_remove(struct snd_soc_codec *codec) +{ + struct sdm660_cdc_priv *sdm660_cdc_priv = + dev_get_drvdata(codec->dev); + + sdm660_cdc_priv->spkdrv_reg = NULL; + sdm660_cdc_priv->on_demand_list[ON_DEMAND_MICBIAS].supply = NULL; + atomic_set(&sdm660_cdc_priv->on_demand_list[ON_DEMAND_MICBIAS].ref, + 0); + wcd_mbhc_deinit(&sdm660_cdc_priv->mbhc); + + return 0; +} + +static int msm_anlg_cdc_enable_static_supplies_to_optimum( + struct sdm660_cdc_priv *sdm660_cdc, + struct sdm660_cdc_pdata *pdata) +{ + int i; + int ret = 0; + + for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { + if (pdata->regulator[i].ondemand) + continue; + if (regulator_count_voltages( + sdm660_cdc->supplies[i].consumer) <= 0) + continue; + + ret = regulator_set_voltage( + sdm660_cdc->supplies[i].consumer, + pdata->regulator[i].min_uv, + pdata->regulator[i].max_uv); + if (ret) { + dev_err(sdm660_cdc->dev, + "Setting volt failed for regulator %s err %d\n", + sdm660_cdc->supplies[i].supply, ret); + } + + ret = regulator_set_load(sdm660_cdc->supplies[i].consumer, + pdata->regulator[i].optimum_ua); + dev_dbg(sdm660_cdc->dev, "Regulator %s set optimum mode\n", + sdm660_cdc->supplies[i].supply); + } + + return ret; +} + +static int msm_anlg_cdc_disable_static_supplies_to_optimum( + struct sdm660_cdc_priv *sdm660_cdc, + struct sdm660_cdc_pdata *pdata) +{ + int i; + int ret = 0; + + for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { + if (pdata->regulator[i].ondemand) + continue; + if (regulator_count_voltages( + sdm660_cdc->supplies[i].consumer) <= 0) + continue; + regulator_set_voltage(sdm660_cdc->supplies[i].consumer, 0, + pdata->regulator[i].max_uv); + regulator_set_load(sdm660_cdc->supplies[i].consumer, 0); + dev_dbg(sdm660_cdc->dev, "Regulator %s set optimum mode\n", + sdm660_cdc->supplies[i].supply); + } + + return ret; +} + +static int msm_anlg_cdc_suspend(struct snd_soc_codec *codec) +{ + struct sdm660_cdc_priv *sdm660_cdc = snd_soc_codec_get_drvdata(codec); + struct sdm660_cdc_pdata *sdm660_cdc_pdata = + sdm660_cdc->dev->platform_data; + + msm_anlg_cdc_disable_static_supplies_to_optimum(sdm660_cdc, + sdm660_cdc_pdata); + return 0; +} + +static int msm_anlg_cdc_resume(struct snd_soc_codec *codec) +{ + struct msm_asoc_mach_data *pdata = NULL; + struct sdm660_cdc_priv *sdm660_cdc = snd_soc_codec_get_drvdata(codec); + struct sdm660_cdc_pdata *sdm660_cdc_pdata = + sdm660_cdc->dev->platform_data; + + pdata = snd_soc_card_get_drvdata(codec->component.card); + msm_anlg_cdc_enable_static_supplies_to_optimum(sdm660_cdc, + sdm660_cdc_pdata); + return 0; +} + +static struct regmap *msm_anlg_get_regmap(struct device *dev) +{ + return dev_get_regmap(dev->parent, NULL); +} + +static struct snd_soc_codec_driver soc_codec_dev_sdm660_cdc = { + .probe = msm_anlg_cdc_soc_probe, + .remove = msm_anlg_cdc_soc_remove, + .suspend = msm_anlg_cdc_suspend, + .resume = msm_anlg_cdc_resume, + .reg_word_size = 1, + .controls = msm_anlg_cdc_snd_controls, + .num_controls = ARRAY_SIZE(msm_anlg_cdc_snd_controls), + .dapm_widgets = msm_anlg_cdc_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(msm_anlg_cdc_dapm_widgets), + .dapm_routes = audio_map, + .num_dapm_routes = ARRAY_SIZE(audio_map), + .get_regmap = msm_anlg_get_regmap, +}; + +static int msm_anlg_cdc_init_supplies(struct sdm660_cdc_priv *sdm660_cdc, + struct sdm660_cdc_pdata *pdata) +{ + int ret; + int i; + + sdm660_cdc->supplies = devm_kzalloc(sdm660_cdc->dev, + sizeof(struct regulator_bulk_data) * + ARRAY_SIZE(pdata->regulator), + GFP_KERNEL); + if (!sdm660_cdc->supplies) { + ret = -ENOMEM; + goto err; + } + + sdm660_cdc->num_of_supplies = 0; + if (ARRAY_SIZE(pdata->regulator) > MAX_REGULATOR) { + dev_err(sdm660_cdc->dev, "%s: Array Size out of bound\n", + __func__); + ret = -EINVAL; + goto err; + } + + for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) { + if (pdata->regulator[i].name) { + sdm660_cdc->supplies[i].supply = + pdata->regulator[i].name; + sdm660_cdc->num_of_supplies++; + } + } + + ret = devm_regulator_bulk_get(sdm660_cdc->dev, + sdm660_cdc->num_of_supplies, + sdm660_cdc->supplies); + if (ret != 0) { + dev_err(sdm660_cdc->dev, + "Failed to get supplies: err = %d\n", + ret); + goto err_supplies; + } + + for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { + if (regulator_count_voltages( + sdm660_cdc->supplies[i].consumer) <= 0) + continue; + if (pdata->regulator[i].ondemand) { + ret = regulator_set_voltage( + sdm660_cdc->supplies[i].consumer, + 0, pdata->regulator[i].max_uv); + if (ret) { + dev_err(sdm660_cdc->dev, + "Setting regulator voltage failed for regulator %s err = %d\n", + sdm660_cdc->supplies[i].supply, ret); + goto err_supplies; + } + ret = regulator_set_load( + sdm660_cdc->supplies[i].consumer, 0); + if (ret < 0) { + dev_err(sdm660_cdc->dev, + "Setting regulator optimum mode failed for regulator %s err = %d\n", + sdm660_cdc->supplies[i].supply, ret); + goto err_supplies; + } else { + ret = 0; + continue; + } + } + ret = regulator_set_voltage(sdm660_cdc->supplies[i].consumer, + pdata->regulator[i].min_uv, + pdata->regulator[i].max_uv); + if (ret) { + dev_err(sdm660_cdc->dev, + "Setting regulator voltage failed for regulator %s err = %d\n", + sdm660_cdc->supplies[i].supply, ret); + goto err_supplies; + } + ret = regulator_set_load(sdm660_cdc->supplies[i].consumer, + pdata->regulator[i].optimum_ua); + if (ret < 0) { + dev_err(sdm660_cdc->dev, + "Setting regulator optimum mode failed for regulator %s err = %d\n", + sdm660_cdc->supplies[i].supply, ret); + goto err_supplies; + } else { + ret = 0; + } + } + + return ret; + +err_supplies: + kfree(sdm660_cdc->supplies); +err: + return ret; +} + +static int msm_anlg_cdc_enable_static_supplies( + struct sdm660_cdc_priv *sdm660_cdc, + struct sdm660_cdc_pdata *pdata) +{ + int i; + int ret = 0; + + for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { + if (pdata->regulator[i].ondemand) + continue; + ret = regulator_enable(sdm660_cdc->supplies[i].consumer); + if (ret) { + dev_err(sdm660_cdc->dev, "Failed to enable %s\n", + sdm660_cdc->supplies[i].supply); + break; + } + dev_dbg(sdm660_cdc->dev, "Enabled regulator %s\n", + sdm660_cdc->supplies[i].supply); + } + + while (ret && --i) + if (!pdata->regulator[i].ondemand) + regulator_disable(sdm660_cdc->supplies[i].consumer); + return ret; +} + +static void msm_anlg_cdc_disable_supplies(struct sdm660_cdc_priv *sdm660_cdc, + struct sdm660_cdc_pdata *pdata) +{ + int i; + + regulator_bulk_disable(sdm660_cdc->num_of_supplies, + sdm660_cdc->supplies); + for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { + if (regulator_count_voltages( + sdm660_cdc->supplies[i].consumer) <= 0) + continue; + regulator_set_voltage(sdm660_cdc->supplies[i].consumer, 0, + pdata->regulator[i].max_uv); + regulator_set_load(sdm660_cdc->supplies[i].consumer, 0); + } + regulator_bulk_free(sdm660_cdc->num_of_supplies, + sdm660_cdc->supplies); + kfree(sdm660_cdc->supplies); +} + +static const struct of_device_id sdm660_codec_of_match[] = { + { .compatible = "qcom,pmic-analog-codec", }, + {}, +}; + +static void msm_anlg_add_child_devices(struct work_struct *work) +{ + struct sdm660_cdc_priv *pdata; + struct platform_device *pdev; + struct device_node *node; + struct msm_dig_ctrl_data *dig_ctrl_data = NULL, *temp; + int ret, ctrl_num = 0; + struct msm_dig_ctrl_platform_data *platdata; + char plat_dev_name[MSM_DIG_CDC_STRING_LEN]; + + pdata = container_of(work, struct sdm660_cdc_priv, + msm_anlg_add_child_devices_work); + if (!pdata) { + pr_err("%s: Memory for pdata does not exist\n", + __func__); + return; + } + if (!pdata->dev->of_node) { + dev_err(pdata->dev, + "%s: DT node for pdata does not exist\n", __func__); + return; + } + + platdata = &pdata->dig_plat_data; + + for_each_child_of_node(pdata->dev->of_node, node) { + if (!strcmp(node->name, "msm-dig-codec")) + strlcpy(plat_dev_name, "msm_digital_codec", + (MSM_DIG_CDC_STRING_LEN - 1)); + else + continue; + + pdev = platform_device_alloc(plat_dev_name, -1); + if (!pdev) { + dev_err(pdata->dev, "%s: pdev memory alloc failed\n", + __func__); + ret = -ENOMEM; + goto err; + } + pdev->dev.parent = pdata->dev; + pdev->dev.of_node = node; + + if (!strcmp(node->name, "msm-dig-codec")) { + ret = platform_device_add_data(pdev, platdata, + sizeof(*platdata)); + if (ret) { + dev_err(&pdev->dev, + "%s: cannot add plat data ctrl:%d\n", + __func__, ctrl_num); + goto fail_pdev_add; + } + } + + ret = platform_device_add(pdev); + if (ret) { + dev_err(&pdev->dev, + "%s: Cannot add platform device\n", + __func__); + goto fail_pdev_add; + } + + if (!strcmp(node->name, "msm-dig-codec")) { + temp = krealloc(dig_ctrl_data, + (ctrl_num + 1) * sizeof( + struct msm_dig_ctrl_data), + GFP_KERNEL); + if (!temp) { + dev_err(&pdev->dev, "out of memory\n"); + ret = -ENOMEM; + goto err; + } + dig_ctrl_data = temp; + dig_ctrl_data[ctrl_num].dig_pdev = pdev; + ctrl_num++; + dev_dbg(&pdev->dev, + "%s: Added digital codec device(s)\n", + __func__); + pdata->dig_ctrl_data = dig_ctrl_data; + } + } + + return; +fail_pdev_add: + platform_device_put(pdev); +err: + return; +} + +static int msm_anlg_cdc_probe(struct platform_device *pdev) +{ + int ret = 0; + struct sdm660_cdc_priv *sdm660_cdc = NULL; + struct sdm660_cdc_pdata *pdata; + int adsp_state; + + adsp_state = apr_get_subsys_state(); + if (adsp_state != APR_SUBSYS_LOADED) { + dev_err(&pdev->dev, "Adsp is not loaded yet %d\n", + adsp_state); + return -EPROBE_DEFER; + } + device_init_wakeup(&pdev->dev, true); + + if (pdev->dev.of_node) { + dev_dbg(&pdev->dev, "%s:Platform data from device tree\n", + __func__); + pdata = msm_anlg_cdc_populate_dt_pdata(&pdev->dev); + pdev->dev.platform_data = pdata; + } else { + dev_dbg(&pdev->dev, "%s:Platform data from board file\n", + __func__); + pdata = pdev->dev.platform_data; + } + if (pdata == NULL) { + dev_err(&pdev->dev, "%s:Platform data failed to populate\n", + __func__); + goto rtn; + } + sdm660_cdc = devm_kzalloc(&pdev->dev, sizeof(struct sdm660_cdc_priv), + GFP_KERNEL); + if (sdm660_cdc == NULL) { + ret = -ENOMEM; + goto rtn; + } + + sdm660_cdc->dev = &pdev->dev; + ret = msm_anlg_cdc_init_supplies(sdm660_cdc, pdata); + if (ret) { + dev_err(&pdev->dev, "%s: Fail to enable Codec supplies\n", + __func__); + goto rtn; + } + ret = msm_anlg_cdc_enable_static_supplies(sdm660_cdc, pdata); + if (ret) { + dev_err(&pdev->dev, + "%s: Fail to enable Codec pre-reset supplies\n", + __func__); + goto rtn; + } + /* Allow supplies to be ready */ + usleep_range(5, 6); + + wcd9xxx_spmi_set_dev(pdev, 0); + wcd9xxx_spmi_set_dev(pdev, 1); + if (wcd9xxx_spmi_irq_init()) { + dev_err(&pdev->dev, + "%s: irq initialization failed\n", __func__); + } else { + dev_dbg(&pdev->dev, + "%s: irq initialization passed\n", __func__); + } + dev_set_drvdata(&pdev->dev, sdm660_cdc); + + ret = snd_soc_register_codec(&pdev->dev, + &soc_codec_dev_sdm660_cdc, + msm_anlg_cdc_i2s_dai, + ARRAY_SIZE(msm_anlg_cdc_i2s_dai)); + if (ret) { + dev_err(&pdev->dev, + "%s:snd_soc_register_codec failed with error %d\n", + __func__, ret); + goto err_supplies; + } + BLOCKING_INIT_NOTIFIER_HEAD(&sdm660_cdc->notifier); + BLOCKING_INIT_NOTIFIER_HEAD(&sdm660_cdc->notifier_mbhc); + + sdm660_cdc->dig_plat_data.handle = (void *) sdm660_cdc; + sdm660_cdc->dig_plat_data.update_clkdiv = update_clkdiv; + sdm660_cdc->dig_plat_data.get_cdc_version = get_cdc_version; + sdm660_cdc->dig_plat_data.register_notifier = + msm_anlg_cdc_dig_register_notifier; + INIT_WORK(&sdm660_cdc->msm_anlg_add_child_devices_work, + msm_anlg_add_child_devices); + schedule_work(&sdm660_cdc->msm_anlg_add_child_devices_work); + + return ret; +err_supplies: + msm_anlg_cdc_disable_supplies(sdm660_cdc, pdata); +rtn: + return ret; +} + +static int msm_anlg_cdc_remove(struct platform_device *pdev) +{ + struct sdm660_cdc_priv *sdm660_cdc = dev_get_drvdata(&pdev->dev); + struct sdm660_cdc_pdata *pdata = sdm660_cdc->dev->platform_data; + + snd_soc_unregister_codec(&pdev->dev); + msm_anlg_cdc_disable_supplies(sdm660_cdc, pdata); + return 0; +} + +static struct platform_driver msm_anlg_codec_driver = { + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + .of_match_table = of_match_ptr(sdm660_codec_of_match) + }, + .probe = msm_anlg_cdc_probe, + .remove = msm_anlg_cdc_remove, +}; +module_platform_driver(msm_anlg_codec_driver); + +MODULE_DESCRIPTION("MSM Audio Analog codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.h b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.h new file mode 100644 index 000000000000..9563565f36d2 --- /dev/null +++ b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.h @@ -0,0 +1,240 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef MSM_ANALOG_CDC_H +#define MSM_ANALOG_CDC_H + +#include +#include +#include +#include "../wcd-mbhc-v2.h" +#include "../wcdcal-hwdep.h" +#include "sdm660-cdc-registers.h" + +#define MICBIAS_EXT_BYP_CAP 0x00 +#define MICBIAS_NO_EXT_BYP_CAP 0x01 + +#define MSM89XX_NUM_IRQ_REGS 2 +#define MAX_REGULATOR 7 +#define MSM89XX_REG_VAL(reg, val) {reg, 0, val} + +#define MSM89XX_VDD_SPKDRV_NAME "cdc-vdd-spkdrv" + +#define DEFAULT_MULTIPLIER 800 +#define DEFAULT_GAIN 9 +#define DEFAULT_OFFSET 100 + +extern const u8 msm89xx_pmic_cdc_reg_readable[MSM89XX_PMIC_CDC_CACHE_SIZE]; +extern const u8 msm89xx_cdc_core_reg_readable[MSM89XX_CDC_CORE_CACHE_SIZE]; +extern struct regmap_config msm89xx_cdc_core_regmap_config; +extern struct regmap_config msm89xx_pmic_cdc_regmap_config; + +enum wcd_curr_ref { + I_h4_UA = 0, + I_pt5_UA, + I_14_UA, + I_l4_UA, + I_1_UA, +}; + +enum wcd_mbhc_imp_det_pin { + WCD_MBHC_DET_NONE = 0, + WCD_MBHC_DET_HPHL, + WCD_MBHC_DET_HPHR, + WCD_MBHC_DET_BOTH, +}; + + +/* Each micbias can be assigned to one of three cfilters + * Vbatt_min >= .15V + ldoh_v + * ldoh_v >= .15v + cfiltx_mv + * If ldoh_v = 1.95 160 mv < cfiltx_mv < 1800 mv + * If ldoh_v = 2.35 200 mv < cfiltx_mv < 2200 mv + * If ldoh_v = 2.75 240 mv < cfiltx_mv < 2600 mv + * If ldoh_v = 2.85 250 mv < cfiltx_mv < 2700 mv + */ + +struct wcd_micbias_setting { + u8 ldoh_v; + u32 cfilt1_mv; /* in mv */ + u32 cfilt2_mv; /* in mv */ + u32 cfilt3_mv; /* in mv */ + /* Different WCD9xxx series codecs may not + * have 4 mic biases. If a codec has fewer + * mic biases, some of these properties will + * not be used. + */ + u8 bias1_cfilt_sel; + u8 bias2_cfilt_sel; + u8 bias3_cfilt_sel; + u8 bias4_cfilt_sel; + u8 bias1_cap_mode; + u8 bias2_cap_mode; + u8 bias3_cap_mode; + u8 bias4_cap_mode; + bool bias2_is_headset_only; +}; + +enum sdm660_cdc_pid_current { + MSM89XX_PID_MIC_2P5_UA, + MSM89XX_PID_MIC_5_UA, + MSM89XX_PID_MIC_10_UA, + MSM89XX_PID_MIC_20_UA, +}; + +struct sdm660_cdc_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + +enum { + /* INTR_REG 0 - Digital Periph */ + MSM89XX_IRQ_SPKR_CNP = 0, + MSM89XX_IRQ_SPKR_CLIP, + MSM89XX_IRQ_SPKR_OCP, + MSM89XX_IRQ_MBHC_INSREM_DET1, + MSM89XX_IRQ_MBHC_RELEASE, + MSM89XX_IRQ_MBHC_PRESS, + MSM89XX_IRQ_MBHC_INSREM_DET, + MSM89XX_IRQ_MBHC_HS_DET, + /* INTR_REG 1 - Analog Periph */ + MSM89XX_IRQ_EAR_OCP, + MSM89XX_IRQ_HPHR_OCP, + MSM89XX_IRQ_HPHL_OCP, + MSM89XX_IRQ_EAR_CNP, + MSM89XX_IRQ_HPHR_CNP, + MSM89XX_IRQ_HPHL_CNP, + MSM89XX_NUM_IRQS, +}; + +enum { + ON_DEMAND_MICBIAS = 0, + ON_DEMAND_SPKDRV, + ON_DEMAND_SUPPLIES_MAX, +}; + +/* + * The delay list is per codec HW specification. + * Please add delay in the list in the future instead + * of magic number + */ +enum { + CODEC_DELAY_1_MS = 1000, + CODEC_DELAY_1_1_MS = 1100, +}; + +struct sdm660_cdc_regulator { + const char *name; + int min_uv; + int max_uv; + int optimum_ua; + bool ondemand; + struct regulator *regulator; +}; + +struct on_demand_supply { + struct regulator *supply; + atomic_t ref; + int min_uv; + int max_uv; + int optimum_ua; +}; + +struct wcd_imped_i_ref { + enum wcd_curr_ref curr_ref; + int min_val; + int multiplier; + int gain_adj; + int offset; +}; + +enum sdm660_cdc_micbias_num { + MSM89XX_MICBIAS1 = 0, +}; + +/* Hold instance to digital codec platform device */ +struct msm_dig_ctrl_data { + struct platform_device *dig_pdev; +}; + +struct msm_dig_ctrl_platform_data { + void *handle; + void (*update_clkdiv)(void *handle, int val); + int (*get_cdc_version)(void *handle); + int (*register_notifier)(void *handle, + struct notifier_block *nblock, + bool enable); +}; + +struct sdm660_cdc_priv { + struct device *dev; + u32 num_of_supplies; + struct regulator_bulk_data *supplies; + struct snd_soc_codec *codec; + struct work_struct msm_anlg_add_child_devices_work; + struct msm_dig_ctrl_platform_data dig_plat_data; + /* digital codec data structure */ + struct msm_dig_ctrl_data *dig_ctrl_data; + struct blocking_notifier_head notifier; + u16 pmic_rev; + u16 codec_version; + u16 analog_major_rev; + u32 boost_voltage; + u32 adc_count; + u32 rx_bias_count; + bool int_mclk0_enabled; + u16 boost_option; + /* mode to select hd2 */ + u32 hph_mode; + /* compander used for each rx chain */ + bool spk_boost_set; + bool ear_pa_boost_set; + bool ext_spk_boost_set; + struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX]; + struct regulator *spkdrv_reg; + struct blocking_notifier_head notifier_mbhc; + /* mbhc module */ + struct wcd_mbhc mbhc; + /* cal info for codec */ + struct fw_info *fw_data; + struct notifier_block audio_ssr_nb; + int (*codec_spk_ext_pa_cb)(struct snd_soc_codec *codec, int enable); + unsigned long status_mask; + struct wcd_imped_i_ref imped_i_ref; + enum wcd_mbhc_imp_det_pin imped_det_pin; + /* Entry for version info */ + struct snd_info_entry *entry; + struct snd_info_entry *version_entry; +}; + +struct sdm660_cdc_pdata { + struct wcd_micbias_setting micbias; + struct sdm660_cdc_regulator regulator[MAX_REGULATOR]; +}; + + +extern int msm_anlg_cdc_mclk_enable(struct snd_soc_codec *codec, + int mclk_enable, bool dapm); + +extern int msm_anlg_cdc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg); + +extern void msm_anlg_cdc_hs_detect_exit(struct snd_soc_codec *codec); + +extern void sdm660_cdc_update_int_spk_boost(bool enable); + +extern void msm_anlg_cdc_spk_ext_pa_cb( + int (*codec_spk_ext_pa)(struct snd_soc_codec *codec, + int enable), struct snd_soc_codec *codec); +int msm_anlg_codec_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_codec *codec); +#endif diff --git a/sound/soc/codecs/sdm660_cdc/msm-cdc-common.h b/sound/soc/codecs/sdm660_cdc/msm-cdc-common.h new file mode 100644 index 000000000000..1a490a492b45 --- /dev/null +++ b/sound/soc/codecs/sdm660_cdc/msm-cdc-common.h @@ -0,0 +1,67 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "sdm660-cdc-registers.h" + +extern struct reg_default + msm89xx_cdc_core_defaults[MSM89XX_CDC_CORE_CACHE_SIZE]; +extern struct reg_default + msm89xx_pmic_cdc_defaults[MSM89XX_PMIC_CDC_CACHE_SIZE]; + +bool msm89xx_cdc_core_readable_reg(struct device *dev, unsigned int reg); +bool msm89xx_cdc_core_writeable_reg(struct device *dev, unsigned int reg); +bool msm89xx_cdc_core_volatile_reg(struct device *dev, unsigned int reg); + +enum { + AIF1_PB = 0, + AIF1_CAP, + AIF2_VIFEED, + AIF3_SVA, + NUM_CODEC_DAIS, +}; + +enum codec_versions { + TOMBAK_1_0, + TOMBAK_2_0, + CONGA, + CAJON, + CAJON_2_0, + DIANGU, + DRAX_CDC, + UNSUPPORTED, +}; + +/* Support different hph modes */ +enum { + NORMAL_MODE = 0, + HD2_MODE, +}; + +enum dig_cdc_notify_event { + DIG_CDC_EVENT_INVALID, + DIG_CDC_EVENT_CLK_ON, + DIG_CDC_EVENT_CLK_OFF, + DIG_CDC_EVENT_RX1_MUTE_ON, + DIG_CDC_EVENT_RX1_MUTE_OFF, + DIG_CDC_EVENT_RX2_MUTE_ON, + DIG_CDC_EVENT_RX2_MUTE_OFF, + DIG_CDC_EVENT_RX3_MUTE_ON, + DIG_CDC_EVENT_RX3_MUTE_OFF, + DIG_CDC_EVENT_PRE_RX1_INT_ON, + DIG_CDC_EVENT_PRE_RX2_INT_ON, + DIG_CDC_EVENT_POST_RX1_INT_OFF, + DIG_CDC_EVENT_POST_RX2_INT_OFF, + DIG_CDC_EVENT_SSR_DOWN, + DIG_CDC_EVENT_SSR_UP, + DIG_CDC_EVENT_LAST, +}; diff --git a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c new file mode 100644 index 000000000000..3f9c0b4a5b83 --- /dev/null +++ b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -0,0 +1,2189 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sdm660-cdc-registers.h" +#include "msm-digital-cdc.h" +#include "msm-cdc-common.h" +#include "../../msm/sdm660-common.h" +#include "../../../../drivers/base/regmap/internal.h" + +#define DRV_NAME "msm_digital_codec" +#define MCLK_RATE_9P6MHZ 9600000 +#define MCLK_RATE_12P288MHZ 12288000 +#define TX_MUX_CTL_CUT_OFF_FREQ_MASK 0x30 +#define CF_MIN_3DB_4HZ 0x0 +#define CF_MIN_3DB_75HZ 0x1 +#define CF_MIN_3DB_150HZ 0x2 + +#define MSM_DIG_CDC_VERSION_ENTRY_SIZE 32 + +static unsigned long rx_digital_gain_reg[] = { + MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL, + MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL, + MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL, +}; + +static unsigned long tx_digital_gain_reg[] = { + MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN, + MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN, + MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN, + MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN, + MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN, +}; + +static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); + +struct snd_soc_codec *registered_digcodec; +struct hpf_work tx_hpf_work[NUM_DECIMATORS]; + +/* Codec supports 2 IIR filters */ +enum { + IIR1 = 0, + IIR2, + IIR_MAX, +}; + +static int msm_digcdc_clock_control(bool flag) +{ + int ret = -EINVAL; + struct msm_asoc_mach_data *pdata = NULL; + struct msm_dig_priv *msm_dig_cdc = + snd_soc_codec_get_drvdata(registered_digcodec); + + pdata = snd_soc_card_get_drvdata(registered_digcodec->component.card); + + if (flag) { + mutex_lock(&pdata->cdc_int_mclk0_mutex); + if (atomic_read(&pdata->int_mclk0_enabled) == false) { + pdata->digital_cdc_core_clk.enable = 1; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + if (ret < 0) { + pr_err("%s:failed to enable the MCLK\n", + __func__); + /* + * Avoid access to lpass register + * as clock enable failed during SSR. + */ + if (ret == -ENODEV) + msm_dig_cdc->regmap->cache_only = true; + return ret; + } + pr_debug("enabled digital codec core clk\n"); + atomic_set(&pdata->int_mclk0_enabled, true); + schedule_delayed_work(&pdata->disable_int_mclk0_work, + 50); + } + } else { + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + dev_dbg(registered_digcodec->dev, + "disable MCLK, workq to disable set already\n"); + } + return 0; +} + +static void enable_digital_callback(void *flag) +{ + msm_digcdc_clock_control(true); +} + +static void disable_digital_callback(void *flag) +{ + msm_digcdc_clock_control(false); + pr_debug("disable mclk happens in workq\n"); +} + +static int msm_dig_cdc_put_dec_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *w = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int dec_mux, decimator; + char *dec_name = NULL; + char *widget_name = NULL; + char *temp; + u16 tx_mux_ctl_reg; + u8 adc_dmic_sel = 0x0; + int ret = 0; + char *dec_num; + + if (ucontrol->value.enumerated.item[0] > e->items) { + dev_err(codec->dev, "%s: Invalid enum value: %d\n", + __func__, ucontrol->value.enumerated.item[0]); + return -EINVAL; + } + dec_mux = ucontrol->value.enumerated.item[0]; + + widget_name = kstrndup(w->name, 15, GFP_KERNEL); + if (!widget_name) { + dev_err(codec->dev, "%s: failed to copy string\n", + __func__); + return -ENOMEM; + } + temp = widget_name; + + dec_name = strsep(&widget_name, " "); + widget_name = temp; + if (!dec_name) { + dev_err(codec->dev, "%s: Invalid decimator = %s\n", + __func__, w->name); + ret = -EINVAL; + goto out; + } + + dec_num = strpbrk(dec_name, "12345"); + if (dec_num == NULL) { + dev_err(codec->dev, "%s: Invalid DEC selected\n", __func__); + ret = -EINVAL; + goto out; + } + + ret = kstrtouint(dec_num, 10, &decimator); + if (ret < 0) { + dev_err(codec->dev, "%s: Invalid decimator = %s\n", + __func__, dec_name); + ret = -EINVAL; + goto out; + } + + dev_dbg(w->dapm->dev, "%s(): widget = %s decimator = %u dec_mux = %u\n" + , __func__, w->name, decimator, dec_mux); + + switch (decimator) { + case 1: + case 2: + case 3: + case 4: + case 5: + if ((dec_mux == 4) || (dec_mux == 5) || + (dec_mux == 6) || (dec_mux == 7)) + adc_dmic_sel = 0x1; + else + adc_dmic_sel = 0x0; + break; + default: + dev_err(codec->dev, "%s: Invalid Decimator = %u\n", + __func__, decimator); + ret = -EINVAL; + goto out; + } + + tx_mux_ctl_reg = + MSM89XX_CDC_CORE_TX1_MUX_CTL + 32 * (decimator - 1); + + snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x1, adc_dmic_sel); + + ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol); + +out: + kfree(widget_name); + return ret; +} + + +static int msm_dig_cdc_codec_config_compander(struct snd_soc_codec *codec, + int interp_n, int event) +{ + struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: event %d shift %d, enabled %d\n", + __func__, event, interp_n, + dig_cdc->comp_enabled[interp_n]); + + /* compander is not enabled */ + if (!dig_cdc->comp_enabled[interp_n]) + return 0; + + switch (dig_cdc->comp_enabled[interp_n]) { + case COMPANDER_1: + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Compander Clock */ + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B2_CTL, 0x0F, 0x09); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x01, 0x01); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B1_CTL, + 1 << interp_n, 1 << interp_n); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x01); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xF0, 0x50); + /* add sleep for compander to settle */ + usleep_range(1000, 1100); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x28); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xF0, 0xB0); + + /* Enable Compander GPIO */ + if (dig_cdc->codec_hph_comp_gpio) + dig_cdc->codec_hph_comp_gpio(1, codec); + } else if (SND_SOC_DAPM_EVENT_OFF(event)) { + /* Disable Compander GPIO */ + if (dig_cdc->codec_hph_comp_gpio) + dig_cdc->codec_hph_comp_gpio(0, codec); + + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B2_CTL, 0x0F, 0x05); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B1_CTL, + 1 << interp_n, 0); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x01, 0x00); + } + break; + default: + dev_dbg(codec->dev, "%s: Invalid compander %d\n", __func__, + dig_cdc->comp_enabled[interp_n]); + break; + }; + + return 0; +} + +/** + * msm_dig_cdc_hph_comp_cb - registers callback to codec by machine driver. + * + * @codec_hph_comp_gpio: function pointer to set comp gpio at machine driver + * @codec: codec pointer + * + */ +void msm_dig_cdc_hph_comp_cb( + int (*codec_hph_comp_gpio)(bool enable, struct snd_soc_codec *codec), + struct snd_soc_codec *codec) +{ + struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec); + + pr_debug("%s: Enter\n", __func__); + dig_cdc->codec_hph_comp_gpio = codec_hph_comp_gpio; +} +EXPORT_SYMBOL(msm_dig_cdc_hph_comp_cb); + +static int msm_dig_cdc_codec_enable_interpolator(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct msm_dig_priv *msm_dig_cdc = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + + if (w->shift >= MSM89XX_RX_MAX || w->shift < 0) { + dev_err(codec->dev, "%s: wrong RX index: %d\n", + __func__, w->shift); + return -EINVAL; + } + switch (event) { + case SND_SOC_DAPM_POST_PMU: + msm_dig_cdc_codec_config_compander(codec, w->shift, event); + /* apply the digital gain after the interpolator is enabled*/ + if ((w->shift) < ARRAY_SIZE(rx_digital_gain_reg)) + snd_soc_write(codec, + rx_digital_gain_reg[w->shift], + snd_soc_read(codec, + rx_digital_gain_reg[w->shift]) + ); + break; + case SND_SOC_DAPM_POST_PMD: + msm_dig_cdc_codec_config_compander(codec, w->shift, event); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_CLK_RX_RESET_CTL, + 1 << w->shift, 1 << w->shift); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_CLK_RX_RESET_CTL, + 1 << w->shift, 0x0); + /* + * disable the mute enabled during the PMD of this device + */ + if ((w->shift == 0) && + (msm_dig_cdc->mute_mask & HPHL_PA_DISABLE)) { + pr_debug("disabling HPHL mute\n"); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX1_B6_CTL, 0x01, 0x00); + msm_dig_cdc->mute_mask &= ~(HPHL_PA_DISABLE); + } else if ((w->shift == 1) && + (msm_dig_cdc->mute_mask & HPHR_PA_DISABLE)) { + pr_debug("disabling HPHR mute\n"); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX2_B6_CTL, 0x01, 0x00); + msm_dig_cdc->mute_mask &= ~(HPHR_PA_DISABLE); + } else if ((w->shift == 2) && + (msm_dig_cdc->mute_mask & SPKR_PA_DISABLE)) { + pr_debug("disabling SPKR mute\n"); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX3_B6_CTL, 0x01, 0x00); + msm_dig_cdc->mute_mask &= ~(SPKR_PA_DISABLE); + } + } + return 0; +} + +static int msm_dig_cdc_get_iir_enable_audio_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + ucontrol->value.integer.value[0] = + (snd_soc_read(codec, + (MSM89XX_CDC_CORE_IIR1_CTL + 64 * iir_idx)) & + (1 << band_idx)) != 0; + + dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, + iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_dig_cdc_put_iir_enable_audio_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int value = ucontrol->value.integer.value[0]; + + /* Mask first 5 bits, 6-8 are reserved */ + snd_soc_update_bits(codec, + (MSM89XX_CDC_CORE_IIR1_CTL + 64 * iir_idx), + (1 << band_idx), (value << band_idx)); + + dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, + iir_idx, band_idx, + ((snd_soc_read(codec, + (MSM89XX_CDC_CORE_IIR1_CTL + 64 * iir_idx)) & + (1 << band_idx)) != 0)); + + return 0; +} + +static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec, + int iir_idx, int band_idx, + int coeff_idx) +{ + uint32_t value = 0; + + /* Address does not automatically update if reading */ + snd_soc_write(codec, + (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t)) & 0x7F); + + value |= snd_soc_read(codec, + (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx)); + + snd_soc_write(codec, + (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 1) & 0x7F); + + value |= (snd_soc_read(codec, + (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 8); + + snd_soc_write(codec, + (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 2) & 0x7F); + + value |= (snd_soc_read(codec, + (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 16); + + snd_soc_write(codec, + (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 3) & 0x7F); + + /* Mask bits top 2 bits since they are reserved */ + value |= ((snd_soc_read(codec, (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + + 64 * iir_idx)) & 0x3f) << 24); + + return value; + +} + +static void set_iir_band_coeff(struct snd_soc_codec *codec, + int iir_idx, int band_idx, + uint32_t value) +{ + snd_soc_write(codec, + (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx), + (value & 0xFF)); + + snd_soc_write(codec, + (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx), + (value >> 8) & 0xFF); + + snd_soc_write(codec, + (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx), + (value >> 16) & 0xFF); + + /* Mask top 2 bits, 7-8 are reserved */ + snd_soc_write(codec, + (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx), + (value >> 24) & 0x3F); + +} + +static int msm_dig_cdc_get_iir_band_audio_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + ucontrol->value.integer.value[0] = + get_iir_band_coeff(codec, iir_idx, band_idx, 0); + ucontrol->value.integer.value[1] = + get_iir_band_coeff(codec, iir_idx, band_idx, 1); + ucontrol->value.integer.value[2] = + get_iir_band_coeff(codec, iir_idx, band_idx, 2); + ucontrol->value.integer.value[3] = + get_iir_band_coeff(codec, iir_idx, band_idx, 3); + ucontrol->value.integer.value[4] = + get_iir_band_coeff(codec, iir_idx, band_idx, 4); + + dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n" + "%s: IIR #%d band #%d b1 = 0x%x\n" + "%s: IIR #%d band #%d b2 = 0x%x\n" + "%s: IIR #%d band #%d a1 = 0x%x\n" + "%s: IIR #%d band #%d a2 = 0x%x\n", + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[0], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[1], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[2], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[3], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[4]); + return 0; +} + +static int msm_dig_cdc_put_iir_band_audio_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + /* Mask top bit it is reserved */ + /* Updates addr automatically for each B2 write */ + snd_soc_write(codec, + (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx), + (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); + + + set_iir_band_coeff(codec, iir_idx, band_idx, + ucontrol->value.integer.value[0]); + set_iir_band_coeff(codec, iir_idx, band_idx, + ucontrol->value.integer.value[1]); + set_iir_band_coeff(codec, iir_idx, band_idx, + ucontrol->value.integer.value[2]); + set_iir_band_coeff(codec, iir_idx, band_idx, + ucontrol->value.integer.value[3]); + set_iir_band_coeff(codec, iir_idx, band_idx, + ucontrol->value.integer.value[4]); + + dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n" + "%s: IIR #%d band #%d b1 = 0x%x\n" + "%s: IIR #%d band #%d b2 = 0x%x\n" + "%s: IIR #%d band #%d a1 = 0x%x\n" + "%s: IIR #%d band #%d a2 = 0x%x\n", + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 0), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 1), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 2), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 3), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 4)); + return 0; +} + +static void tx_hpf_corner_freq_callback(struct work_struct *work) +{ + struct delayed_work *hpf_delayed_work; + struct hpf_work *hpf_work; + struct snd_soc_codec *codec; + struct msm_dig_priv *msm_dig_cdc; + u16 tx_mux_ctl_reg; + u8 hpf_cut_of_freq; + + hpf_delayed_work = to_delayed_work(work); + hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); + codec = hpf_work->dig_cdc->codec; + msm_dig_cdc = hpf_work->dig_cdc; + hpf_cut_of_freq = hpf_work->tx_hpf_cut_of_freq; + + tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX1_MUX_CTL + + (hpf_work->decimator - 1) * 32; + + dev_dbg(codec->dev, "%s(): decimator %u hpf_cut_of_freq 0x%x\n", + __func__, hpf_work->decimator, (unsigned int)hpf_cut_of_freq); + msm_dig_cdc->update_clkdiv(msm_dig_cdc->handle, 0x51); + + snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, hpf_cut_of_freq << 4); +} + +static int msm_dig_cdc_codec_set_iir_gain(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int value = 0, reg; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (w->shift == 0) + reg = MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL; + else if (w->shift == 1) + reg = MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL; + else + goto ret; + value = snd_soc_read(codec, reg); + snd_soc_write(codec, reg, value); + break; + default: + pr_err("%s: event = %d not expected\n", __func__, event); + } +ret: + return 0; +} + +static int msm_dig_cdc_compander_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec); + int comp_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int rx_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + dev_dbg(codec->dev, "%s: msm_dig_cdc->comp[%d]_enabled[%d] = %d\n", + __func__, comp_idx, rx_idx, + dig_cdc->comp_enabled[rx_idx]); + + ucontrol->value.integer.value[0] = dig_cdc->comp_enabled[rx_idx]; + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_dig_cdc_compander_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec); + int comp_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int rx_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int value = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + if (dig_cdc->version >= DIANGU) { + if (!value) + dig_cdc->comp_enabled[rx_idx] = 0; + else + dig_cdc->comp_enabled[rx_idx] = comp_idx; + } + + dev_dbg(codec->dev, "%s: msm_dig_cdc->comp[%d]_enabled[%d] = %d\n", + __func__, comp_idx, rx_idx, + dig_cdc->comp_enabled[rx_idx]); + + return 0; +} + +static const struct snd_kcontrol_new compander_kcontrols[] = { + SOC_SINGLE_EXT("COMP0 RX1", COMPANDER_1, MSM89XX_RX1, 1, 0, + msm_dig_cdc_compander_get, msm_dig_cdc_compander_set), + + SOC_SINGLE_EXT("COMP0 RX2", COMPANDER_1, MSM89XX_RX2, 1, 0, + msm_dig_cdc_compander_get, msm_dig_cdc_compander_set), + +}; + +static int msm_dig_cdc_set_interpolator_rate(struct snd_soc_dai *dai, + u8 rx_fs_rate_reg_val, + u32 sample_rate) +{ + snd_soc_update_bits(dai->codec, + MSM89XX_CDC_CORE_RX1_B5_CTL, 0xF0, rx_fs_rate_reg_val); + snd_soc_update_bits(dai->codec, + MSM89XX_CDC_CORE_RX2_B5_CTL, 0xF0, rx_fs_rate_reg_val); + return 0; +} + +static int msm_dig_cdc_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + u8 tx_fs_rate, rx_fs_rate, rx_clk_fs_rate; + int ret; + + dev_dbg(dai->codec->dev, + "%s: dai_name = %s DAI-ID %x rate %d num_ch %d format %d\n", + __func__, dai->name, dai->id, params_rate(params), + params_channels(params), params_format(params)); + + switch (params_rate(params)) { + case 8000: + tx_fs_rate = 0x00; + rx_fs_rate = 0x00; + rx_clk_fs_rate = 0x00; + break; + case 16000: + tx_fs_rate = 0x20; + rx_fs_rate = 0x20; + rx_clk_fs_rate = 0x01; + break; + case 32000: + tx_fs_rate = 0x40; + rx_fs_rate = 0x40; + rx_clk_fs_rate = 0x02; + break; + case 44100: + case 48000: + tx_fs_rate = 0x60; + rx_fs_rate = 0x60; + rx_clk_fs_rate = 0x03; + break; + case 96000: + tx_fs_rate = 0x80; + rx_fs_rate = 0x80; + rx_clk_fs_rate = 0x04; + break; + case 192000: + tx_fs_rate = 0xA0; + rx_fs_rate = 0xA0; + rx_clk_fs_rate = 0x05; + break; + default: + dev_err(dai->codec->dev, + "%s: Invalid sampling rate %d\n", __func__, + params_rate(params)); + return -EINVAL; + } + + snd_soc_update_bits(dai->codec, + MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x0F, rx_clk_fs_rate); + + switch (substream->stream) { + case SNDRV_PCM_STREAM_CAPTURE: + break; + case SNDRV_PCM_STREAM_PLAYBACK: + ret = msm_dig_cdc_set_interpolator_rate(dai, rx_fs_rate, + params_rate(params)); + if (ret < 0) { + dev_err(dai->codec->dev, + "%s: set decimator rate failed %d\n", __func__, + ret); + return ret; + } + break; + default: + dev_err(dai->codec->dev, + "%s: Invalid stream type %d\n", __func__, + substream->stream); + return -EINVAL; + } + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + snd_soc_update_bits(dai->codec, + MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x20, 0x20); + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + snd_soc_update_bits(dai->codec, + MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x20, 0x00); + break; + default: + dev_err(dai->codec->dev, "%s: wrong format selected\n", + __func__); + return -EINVAL; + } + return 0; +} + +static int msm_dig_cdc_codec_enable_dmic(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec); + u8 dmic_clk_en; + u16 dmic_clk_reg; + s32 *dmic_clk_cnt; + unsigned int dmic; + int ret; + char *dmic_num = strpbrk(w->name, "1234"); + + if (dmic_num == NULL) { + dev_err(codec->dev, "%s: Invalid DMIC\n", __func__); + return -EINVAL; + } + + ret = kstrtouint(dmic_num, 10, &dmic); + if (ret < 0) { + dev_err(codec->dev, + "%s: Invalid DMIC line on the codec\n", __func__); + return -EINVAL; + } + + switch (dmic) { + case 1: + case 2: + dmic_clk_en = 0x01; + dmic_clk_cnt = &(dig_cdc->dmic_1_2_clk_cnt); + dmic_clk_reg = MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL; + dev_dbg(codec->dev, + "%s() event %d DMIC%d dmic_1_2_clk_cnt %d\n", + __func__, event, dmic, *dmic_clk_cnt); + break; + case 3: + case 4: + dmic_clk_en = 0x01; + dmic_clk_cnt = &(dig_cdc->dmic_3_4_clk_cnt); + dmic_clk_reg = MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL; + dev_dbg(codec->dev, + "%s() event %d DMIC%d dmic_3_4_clk_cnt %d\n", + __func__, event, dmic, *dmic_clk_cnt); + break; + default: + dev_err(codec->dev, "%s: Invalid DMIC Selection\n", __func__); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + (*dmic_clk_cnt)++; + if (*dmic_clk_cnt == 1) { + snd_soc_update_bits(codec, dmic_clk_reg, + 0x0E, 0x04); + snd_soc_update_bits(codec, dmic_clk_reg, + dmic_clk_en, dmic_clk_en); + } + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_TX1_DMIC_CTL + (dmic - 1) * 0x20, + 0x07, 0x02); + break; + case SND_SOC_DAPM_POST_PMD: + (*dmic_clk_cnt)--; + if (*dmic_clk_cnt == 0) + snd_soc_update_bits(codec, dmic_clk_reg, + dmic_clk_en, 0); + break; + } + return 0; +} + +static int msm_dig_cdc_codec_enable_dec(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct msm_asoc_mach_data *pdata = NULL; + unsigned int decimator; + struct msm_dig_priv *msm_dig_cdc = snd_soc_codec_get_drvdata(codec); + char *dec_name = NULL; + char *widget_name = NULL; + char *temp; + int ret = 0, i; + u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg; + u8 dec_hpf_cut_of_freq; + int offset; + char *dec_num; + + pdata = snd_soc_card_get_drvdata(codec->component.card); + dev_dbg(codec->dev, "%s %d\n", __func__, event); + + widget_name = kstrndup(w->name, 15, GFP_KERNEL); + if (!widget_name) + return -ENOMEM; + temp = widget_name; + + dec_name = strsep(&widget_name, " "); + widget_name = temp; + if (!dec_name) { + dev_err(codec->dev, + "%s: Invalid decimator = %s\n", __func__, w->name); + ret = -EINVAL; + goto out; + } + + dec_num = strpbrk(dec_name, "12345"); + if (dec_num == NULL) { + dev_err(codec->dev, "%s: Invalid Decimator\n", __func__); + ret = -EINVAL; + goto out; + } + + ret = kstrtouint(dec_num, 10, &decimator); + if (ret < 0) { + dev_err(codec->dev, + "%s: Invalid decimator = %s\n", __func__, dec_name); + ret = -EINVAL; + goto out; + } + + dev_dbg(codec->dev, + "%s(): widget = %s dec_name = %s decimator = %u\n", __func__, + w->name, dec_name, decimator); + + if (w->reg == MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL) { + dec_reset_reg = MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL; + offset = 0; + } else { + dev_err(codec->dev, "%s: Error, incorrect dec\n", __func__); + ret = -EINVAL; + goto out; + } + + tx_vol_ctl_reg = MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG + + 32 * (decimator - 1); + tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX1_MUX_CTL + + 32 * (decimator - 1); + if (decimator == 5) { + tx_vol_ctl_reg = MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG; + tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX5_MUX_CTL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Enableable TX digital mute */ + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01); + for (i = 0; i < NUM_DECIMATORS; i++) { + if (decimator == i + 1) + msm_dig_cdc->dec_active[i] = true; + } + + dec_hpf_cut_of_freq = snd_soc_read(codec, tx_mux_ctl_reg); + + dec_hpf_cut_of_freq = (dec_hpf_cut_of_freq & 0x30) >> 4; + + tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq = + dec_hpf_cut_of_freq; + + if (dec_hpf_cut_of_freq != CF_MIN_3DB_150HZ) { + + /* set cut of freq to CF_MIN_3DB_150HZ (0x1); */ + snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, + CF_MIN_3DB_150HZ << 4); + } + msm_dig_cdc->update_clkdiv(msm_dig_cdc->handle, 0x42); + break; + case SND_SOC_DAPM_POST_PMU: + /* enable HPF */ + snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x00); + + if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq != + CF_MIN_3DB_150HZ) { + + schedule_delayed_work(&tx_hpf_work[decimator - 1].dwork, + msecs_to_jiffies(300)); + } + /* apply the digital gain after the decimator is enabled*/ + if ((w->shift) < ARRAY_SIZE(tx_digital_gain_reg)) + snd_soc_write(codec, + tx_digital_gain_reg[w->shift + offset], + snd_soc_read(codec, + tx_digital_gain_reg[w->shift + offset]) + ); + if (pdata->lb_mode) { + pr_debug("%s: loopback mode unmute the DEC\n", + __func__); + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00); + } + snd_soc_update_bits(codec, tx_vol_ctl_reg, + 0x01, 0x00); + + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01); + msleep(20); + snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08); + cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, + 1 << w->shift); + snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, 0x0); + snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08); + snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, + (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq) << 4); + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00); + for (i = 0; i < NUM_DECIMATORS; i++) { + if (decimator == i + 1) + msm_dig_cdc->dec_active[i] = false; + } + break; + } +out: + kfree(widget_name); + return ret; +} + +static int msm_dig_cdc_event_notify(struct notifier_block *block, + unsigned long val, + void *data) +{ + enum dig_cdc_notify_event event = (enum dig_cdc_notify_event)val; + struct snd_soc_codec *codec = registered_digcodec; + struct msm_dig_priv *msm_dig_cdc = snd_soc_codec_get_drvdata(codec); + struct msm_asoc_mach_data *pdata = NULL; + int ret = -EINVAL; + + pdata = snd_soc_card_get_drvdata(codec->component.card); + + switch (event) { + case DIG_CDC_EVENT_CLK_ON: + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_CLK_PDM_CTL, 0x03, 0x03); + if (pdata->mclk_freq == MCLK_RATE_12P288MHZ || + pdata->native_clk_set) + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_TOP_CTL, 0x01, 0x00); + else if (pdata->mclk_freq == MCLK_RATE_9P6MHZ) + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_TOP_CTL, 0x01, 0x01); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_CLK_MCLK_CTL, 0x01, 0x01); + break; + case DIG_CDC_EVENT_CLK_OFF: + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_CLK_PDM_CTL, 0x03, 0x00); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_CLK_MCLK_CTL, 0x01, 0x00); + break; + case DIG_CDC_EVENT_RX1_MUTE_ON: + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX1_B6_CTL, 0x01, 0x01); + msm_dig_cdc->mute_mask |= HPHL_PA_DISABLE; + break; + case DIG_CDC_EVENT_RX1_MUTE_OFF: + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX1_B6_CTL, 0x01, 0x00); + msm_dig_cdc->mute_mask &= (~HPHL_PA_DISABLE); + break; + case DIG_CDC_EVENT_RX2_MUTE_ON: + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX2_B6_CTL, 0x01, 0x01); + msm_dig_cdc->mute_mask |= HPHR_PA_DISABLE; + break; + case DIG_CDC_EVENT_RX2_MUTE_OFF: + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX2_B6_CTL, 0x01, 0x00); + msm_dig_cdc->mute_mask &= (~HPHR_PA_DISABLE); + break; + case DIG_CDC_EVENT_RX3_MUTE_ON: + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX3_B6_CTL, 0x01, 0x01); + msm_dig_cdc->mute_mask |= SPKR_PA_DISABLE; + break; + case DIG_CDC_EVENT_RX3_MUTE_OFF: + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX3_B6_CTL, 0x01, 0x00); + msm_dig_cdc->mute_mask &= (~SPKR_PA_DISABLE); + break; + case DIG_CDC_EVENT_PRE_RX1_INT_ON: + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX1_B3_CTL, 0x3C, 0x28); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX1_B4_CTL, 0x18, 0x10); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX1_B3_CTL, 0x80, 0x80); + break; + case DIG_CDC_EVENT_PRE_RX2_INT_ON: + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX2_B3_CTL, 0x3C, 0x28); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX2_B4_CTL, 0x18, 0x10); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX2_B3_CTL, 0x80, 0x80); + break; + case DIG_CDC_EVENT_POST_RX1_INT_OFF: + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX1_B3_CTL, 0x3C, 0x00); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX1_B4_CTL, 0x18, 0xFF); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX1_B3_CTL, 0x80, 0x00); + break; + case DIG_CDC_EVENT_POST_RX2_INT_OFF: + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX2_B3_CTL, 0x3C, 0x00); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX2_B4_CTL, 0x18, 0xFF); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_RX2_B3_CTL, 0x80, 0x00); + break; + case DIG_CDC_EVENT_SSR_DOWN: + regcache_cache_only(msm_dig_cdc->regmap, true); + break; + case DIG_CDC_EVENT_SSR_UP: + regcache_cache_only(msm_dig_cdc->regmap, false); + regcache_mark_dirty(msm_dig_cdc->regmap); + + mutex_lock(&pdata->cdc_int_mclk0_mutex); + pdata->digital_cdc_core_clk.enable = 1; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + if (ret < 0) { + pr_err("%s:failed to enable the MCLK\n", + __func__); + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + break; + } + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + + regcache_sync(msm_dig_cdc->regmap); + + mutex_lock(&pdata->cdc_int_mclk0_mutex); + pdata->digital_cdc_core_clk.enable = 0; + afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + break; + case DIG_CDC_EVENT_INVALID: + default: + break; + } + return 0; +} + +static ssize_t msm_dig_codec_version_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, size_t count, + loff_t pos) +{ + struct msm_dig_priv *msm_dig; + char buffer[MSM_DIG_CDC_VERSION_ENTRY_SIZE]; + int len = 0; + + msm_dig = (struct msm_dig_priv *) entry->private_data; + if (!msm_dig) { + pr_err("%s: msm_dig priv is null\n", __func__); + return -EINVAL; + } + + switch (msm_dig->version) { + case DRAX_CDC: + len = snprintf(buffer, sizeof(buffer), "SDM660-CDC_1_0\n"); + break; + default: + len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + } + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops msm_dig_codec_info_ops = { + .read = msm_dig_codec_version_read, +}; + +/* + * msm_dig_codec_info_create_codec_entry - creates msm_dig module + * @codec_root: The parent directory + * @codec: Codec instance + * + * Creates msm_dig module and version entry under the given + * parent directory. + * + * Return: 0 on success or negative error code on failure. + */ +int msm_dig_codec_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + struct snd_info_entry *version_entry; + struct msm_dig_priv *msm_dig; + struct snd_soc_card *card; + + if (!codec_root || !codec) + return -EINVAL; + + msm_dig = snd_soc_codec_get_drvdata(codec); + card = codec->component.card; + msm_dig->entry = snd_register_module_info(codec_root->module, + "msm_digital_codec", + codec_root); + if (!msm_dig->entry) { + dev_dbg(codec->dev, "%s: failed to create msm_digital entry\n", + __func__); + return -ENOMEM; + } + + version_entry = snd_info_create_card_entry(card->snd_card, + "version", + msm_dig->entry); + if (!version_entry) { + dev_dbg(codec->dev, "%s: failed to create msm_digital version entry\n", + __func__); + return -ENOMEM; + } + + version_entry->private_data = msm_dig; + version_entry->size = MSM_DIG_CDC_VERSION_ENTRY_SIZE; + version_entry->content = SNDRV_INFO_CONTENT_DATA; + version_entry->c.ops = &msm_dig_codec_info_ops; + + if (snd_info_register(version_entry) < 0) { + snd_info_free_entry(version_entry); + return -ENOMEM; + } + msm_dig->version_entry = version_entry; + if (msm_dig->get_cdc_version) + msm_dig->version = msm_dig->get_cdc_version(msm_dig->handle); + else + msm_dig->version = DRAX_CDC; + + return 0; +} +EXPORT_SYMBOL(msm_dig_codec_info_create_codec_entry); + +static int msm_dig_cdc_soc_probe(struct snd_soc_codec *codec) +{ + struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev); + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + int i, ret; + + msm_dig_cdc->codec = codec; + + snd_soc_add_codec_controls(codec, compander_kcontrols, + ARRAY_SIZE(compander_kcontrols)); + + for (i = 0; i < NUM_DECIMATORS; i++) { + tx_hpf_work[i].dig_cdc = msm_dig_cdc; + tx_hpf_work[i].decimator = i + 1; + INIT_DELAYED_WORK(&tx_hpf_work[i].dwork, + tx_hpf_corner_freq_callback); + } + + for (i = 0; i < MSM89XX_RX_MAX; i++) + msm_dig_cdc->comp_enabled[i] = COMPANDER_NONE; + + /* Register event notifier */ + msm_dig_cdc->nblock.notifier_call = msm_dig_cdc_event_notify; + if (msm_dig_cdc->register_notifier) { + ret = msm_dig_cdc->register_notifier(msm_dig_cdc->handle, + &msm_dig_cdc->nblock, + true); + if (ret) { + pr_err("%s: Failed to register notifier %d\n", + __func__, ret); + return ret; + } + } + registered_digcodec = codec; + + snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AIF1 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "ADC1_IN"); + snd_soc_dapm_ignore_suspend(dapm, "ADC2_IN"); + snd_soc_dapm_ignore_suspend(dapm, "ADC3_IN"); + snd_soc_dapm_ignore_suspend(dapm, "PDM_OUT_RX1"); + snd_soc_dapm_ignore_suspend(dapm, "PDM_OUT_RX2"); + snd_soc_dapm_ignore_suspend(dapm, "PDM_OUT_RX3"); + + snd_soc_dapm_sync(dapm); + + return 0; +} + +static int msm_dig_cdc_soc_remove(struct snd_soc_codec *codec) +{ + struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev); + + if (msm_dig_cdc->register_notifier) + msm_dig_cdc->register_notifier(msm_dig_cdc->handle, + &msm_dig_cdc->nblock, + false); + iounmap(msm_dig_cdc->dig_base); + return 0; +} + +static const struct snd_soc_dapm_route audio_dig_map[] = { + {"RX_I2S_CLK", NULL, "CDC_CONN"}, + {"I2S RX1", NULL, "RX_I2S_CLK"}, + {"I2S RX2", NULL, "RX_I2S_CLK"}, + {"I2S RX3", NULL, "RX_I2S_CLK"}, + + {"I2S TX1", NULL, "TX_I2S_CLK"}, + {"I2S TX2", NULL, "TX_I2S_CLK"}, + {"I2S TX3", NULL, "TX_I2S_CLK"}, + {"I2S TX4", NULL, "TX_I2S_CLK"}, + {"I2S TX5", NULL, "TX_I2S_CLK"}, + {"I2S TX6", NULL, "TX_I2S_CLK"}, + + {"I2S TX1", NULL, "DEC1 MUX"}, + {"I2S TX2", NULL, "DEC2 MUX"}, + {"I2S TX3", NULL, "I2S TX2 INP1"}, + {"I2S TX4", NULL, "I2S TX2 INP2"}, + {"I2S TX5", NULL, "DEC3 MUX"}, + {"I2S TX6", NULL, "I2S TX3 INP2"}, + + {"I2S TX2 INP1", "RX_MIX1", "RX1 MIX2"}, + {"I2S TX2 INP1", "DEC3", "DEC3 MUX"}, + {"I2S TX2 INP2", "RX_MIX2", "RX2 MIX2"}, + {"I2S TX2 INP2", "RX_MIX3", "RX3 MIX1"}, + {"I2S TX2 INP2", "DEC4", "DEC4 MUX"}, + {"I2S TX3 INP2", "DEC4", "DEC4 MUX"}, + {"I2S TX3 INP2", "DEC5", "DEC5 MUX"}, + + {"PDM_OUT_RX1", NULL, "RX1 CHAIN"}, + {"PDM_OUT_RX2", NULL, "RX2 CHAIN"}, + {"PDM_OUT_RX3", NULL, "RX3 CHAIN"}, + + {"RX1 CHAIN", NULL, "RX1 MIX2"}, + {"RX2 CHAIN", NULL, "RX2 MIX2"}, + {"RX3 CHAIN", NULL, "RX3 MIX1"}, + + {"RX1 MIX1", NULL, "RX1 MIX1 INP1"}, + {"RX1 MIX1", NULL, "RX1 MIX1 INP2"}, + {"RX1 MIX1", NULL, "RX1 MIX1 INP3"}, + {"RX2 MIX1", NULL, "RX2 MIX1 INP1"}, + {"RX2 MIX1", NULL, "RX2 MIX1 INP2"}, + {"RX3 MIX1", NULL, "RX3 MIX1 INP1"}, + {"RX3 MIX1", NULL, "RX3 MIX1 INP2"}, + {"RX1 MIX2", NULL, "RX1 MIX1"}, + {"RX1 MIX2", NULL, "RX1 MIX2 INP1"}, + {"RX2 MIX2", NULL, "RX2 MIX1"}, + {"RX2 MIX2", NULL, "RX2 MIX2 INP1"}, + + {"RX1 MIX1 INP1", "RX1", "I2S RX1"}, + {"RX1 MIX1 INP1", "RX2", "I2S RX2"}, + {"RX1 MIX1 INP1", "RX3", "I2S RX3"}, + {"RX1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX1 MIX1 INP1", "IIR2", "IIR2"}, + {"RX1 MIX1 INP2", "RX1", "I2S RX1"}, + {"RX1 MIX1 INP2", "RX2", "I2S RX2"}, + {"RX1 MIX1 INP2", "RX3", "I2S RX3"}, + {"RX1 MIX1 INP2", "IIR1", "IIR1"}, + {"RX1 MIX1 INP2", "IIR2", "IIR2"}, + {"RX1 MIX1 INP3", "RX1", "I2S RX1"}, + {"RX1 MIX1 INP3", "RX2", "I2S RX2"}, + {"RX1 MIX1 INP3", "RX3", "I2S RX3"}, + + {"RX2 MIX1 INP1", "RX1", "I2S RX1"}, + {"RX2 MIX1 INP1", "RX2", "I2S RX2"}, + {"RX2 MIX1 INP1", "RX3", "I2S RX3"}, + {"RX2 MIX1 INP1", "IIR1", "IIR1"}, + {"RX2 MIX1 INP1", "IIR2", "IIR2"}, + {"RX2 MIX1 INP2", "RX1", "I2S RX1"}, + {"RX2 MIX1 INP2", "RX2", "I2S RX2"}, + {"RX2 MIX1 INP2", "RX3", "I2S RX3"}, + {"RX2 MIX1 INP2", "IIR1", "IIR1"}, + {"RX2 MIX1 INP2", "IIR2", "IIR2"}, + + {"RX3 MIX1 INP1", "RX1", "I2S RX1"}, + {"RX3 MIX1 INP1", "RX2", "I2S RX2"}, + {"RX3 MIX1 INP1", "RX3", "I2S RX3"}, + {"RX3 MIX1 INP1", "IIR1", "IIR1"}, + {"RX3 MIX1 INP1", "IIR2", "IIR2"}, + {"RX3 MIX1 INP2", "RX1", "I2S RX1"}, + {"RX3 MIX1 INP2", "RX2", "I2S RX2"}, + {"RX3 MIX1 INP2", "RX3", "I2S RX3"}, + {"RX3 MIX1 INP2", "IIR1", "IIR1"}, + {"RX3 MIX1 INP2", "IIR2", "IIR2"}, + + {"RX1 MIX2 INP1", "IIR1", "IIR1"}, + {"RX2 MIX2 INP1", "IIR1", "IIR1"}, + {"RX1 MIX2 INP1", "IIR2", "IIR2"}, + {"RX2 MIX2 INP1", "IIR2", "IIR2"}, + + /* Decimator Inputs */ + {"DEC1 MUX", "DMIC1", "DMIC1"}, + {"DEC1 MUX", "DMIC2", "DMIC2"}, + {"DEC1 MUX", "DMIC3", "DMIC3"}, + {"DEC1 MUX", "DMIC4", "DMIC4"}, + {"DEC1 MUX", "ADC1", "ADC1_IN"}, + {"DEC1 MUX", "ADC2", "ADC2_IN"}, + {"DEC1 MUX", "ADC3", "ADC3_IN"}, + {"DEC1 MUX", NULL, "CDC_CONN"}, + + {"DEC2 MUX", "DMIC1", "DMIC1"}, + {"DEC2 MUX", "DMIC2", "DMIC2"}, + {"DEC2 MUX", "DMIC3", "DMIC3"}, + {"DEC2 MUX", "DMIC4", "DMIC4"}, + {"DEC2 MUX", "ADC1", "ADC1_IN"}, + {"DEC2 MUX", "ADC2", "ADC2_IN"}, + {"DEC2 MUX", "ADC3", "ADC3_IN"}, + {"DEC2 MUX", NULL, "CDC_CONN"}, + + {"DEC3 MUX", "DMIC1", "DMIC1"}, + {"DEC3 MUX", "DMIC2", "DMIC2"}, + {"DEC3 MUX", "DMIC3", "DMIC3"}, + {"DEC3 MUX", "DMIC4", "DMIC4"}, + {"DEC3 MUX", "ADC1", "ADC1_IN"}, + {"DEC3 MUX", "ADC2", "ADC2_IN"}, + {"DEC3 MUX", "ADC3", "ADC3_IN"}, + {"DEC3 MUX", NULL, "CDC_CONN"}, + + {"DEC4 MUX", "DMIC1", "DMIC1"}, + {"DEC4 MUX", "DMIC2", "DMIC2"}, + {"DEC4 MUX", "DMIC3", "DMIC3"}, + {"DEC4 MUX", "DMIC4", "DMIC4"}, + {"DEC4 MUX", "ADC1", "ADC1_IN"}, + {"DEC4 MUX", "ADC2", "ADC2_IN"}, + {"DEC4 MUX", "ADC3", "ADC3_IN"}, + {"DEC4 MUX", NULL, "CDC_CONN"}, + + {"DEC5 MUX", "DMIC1", "DMIC1"}, + {"DEC5 MUX", "DMIC2", "DMIC2"}, + {"DEC5 MUX", "DMIC3", "DMIC3"}, + {"DEC5 MUX", "DMIC4", "DMIC4"}, + {"DEC5 MUX", "ADC1", "ADC1_IN"}, + {"DEC5 MUX", "ADC2", "ADC2_IN"}, + {"DEC5 MUX", "ADC3", "ADC3_IN"}, + {"DEC5 MUX", NULL, "CDC_CONN"}, + + {"IIR1", NULL, "IIR1 INP1 MUX"}, + {"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"}, + {"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"}, + {"IIR1 INP1 MUX", "DEC3", "DEC3 MUX"}, + {"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"}, + {"IIR2", NULL, "IIR2 INP1 MUX"}, + {"IIR2 INP1 MUX", "DEC1", "DEC1 MUX"}, + {"IIR2 INP1 MUX", "DEC2", "DEC2 MUX"}, + {"IIR1 INP1 MUX", "DEC3", "DEC3 MUX"}, + {"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"}, +}; + + +static const char * const i2s_tx2_inp1_text[] = { + "ZERO", "RX_MIX1", "DEC3" +}; + +static const char * const i2s_tx2_inp2_text[] = { + "ZERO", "RX_MIX2", "RX_MIX3", "DEC4" +}; + +static const char * const i2s_tx3_inp2_text[] = { + "DEC4", "DEC5" +}; + +static const char * const rx_mix1_text[] = { + "ZERO", "IIR1", "IIR2", "RX1", "RX2", "RX3" +}; + +static const char * const rx_mix2_text[] = { + "ZERO", "IIR1", "IIR2" +}; + +static const char * const dec_mux_text[] = { + "ZERO", "ADC1", "ADC2", "ADC3", "DMIC1", "DMIC2", "DMIC3", "DMIC4" +}; + +static const char * const iir_inp1_text[] = { + "ZERO", "DEC1", "DEC2", "RX1", "RX2", "RX3", "DEC3", "DEC4" +}; + +/* I2S TX MUXes */ +static const struct soc_enum i2s_tx2_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL, + 2, 3, i2s_tx2_inp1_text); + +static const struct soc_enum i2s_tx2_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL, + 0, 4, i2s_tx2_inp2_text); + +static const struct soc_enum i2s_tx3_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL, + 4, 2, i2s_tx3_inp2_text); + +/* RX1 MIX1 */ +static const struct soc_enum rx_mix1_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B1_CTL, + 0, 6, rx_mix1_text); + +static const struct soc_enum rx_mix1_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B1_CTL, + 3, 6, rx_mix1_text); + +static const struct soc_enum rx_mix1_inp3_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B2_CTL, + 0, 6, rx_mix1_text); + +/* RX1 MIX2 */ +static const struct soc_enum rx_mix2_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B3_CTL, + 0, 3, rx_mix2_text); + +/* RX2 MIX1 */ +static const struct soc_enum rx2_mix1_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX2_B1_CTL, + 0, 6, rx_mix1_text); + +static const struct soc_enum rx2_mix1_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX2_B1_CTL, + 3, 6, rx_mix1_text); + +static const struct soc_enum rx2_mix1_inp3_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX2_B1_CTL, + 0, 6, rx_mix1_text); + +/* RX2 MIX2 */ +static const struct soc_enum rx2_mix2_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX2_B3_CTL, + 0, 3, rx_mix2_text); + +/* RX3 MIX1 */ +static const struct soc_enum rx3_mix1_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX3_B1_CTL, + 0, 6, rx_mix1_text); + +static const struct soc_enum rx3_mix1_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX3_B1_CTL, + 3, 6, rx_mix1_text); + +static const struct soc_enum rx3_mix1_inp3_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX3_B1_CTL, + 0, 6, rx_mix1_text); + +/* DEC */ +static const struct soc_enum dec1_mux_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B1_CTL, + 0, 8, dec_mux_text); + +static const struct soc_enum dec2_mux_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B1_CTL, + 3, 8, dec_mux_text); + +static const struct soc_enum dec3_mux_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B2_CTL, + 0, 8, dec_mux_text); + +static const struct soc_enum dec4_mux_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B2_CTL, + 3, 8, dec_mux_text); + +static const struct soc_enum decsva_mux_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B3_CTL, + 0, 8, dec_mux_text); + +static const struct soc_enum iir1_inp1_mux_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL, + 0, 8, iir_inp1_text); + +static const struct soc_enum iir2_inp1_mux_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL, + 0, 8, iir_inp1_text); + +/*cut of frequency for high pass filter*/ +static const char * const cf_text[] = { + "MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz" +}; + +static const struct soc_enum cf_rxmix1_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_RX1_B4_CTL, 0, 3, cf_text); + +static const struct soc_enum cf_rxmix2_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_RX2_B4_CTL, 0, 3, cf_text); + +static const struct soc_enum cf_rxmix3_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_RX3_B4_CTL, 0, 3, cf_text); + +static const struct snd_kcontrol_new rx3_mix1_inp1_mux = + SOC_DAPM_ENUM("RX3 MIX1 INP1 Mux", rx3_mix1_inp1_chain_enum); + +#define MSM89XX_DEC_ENUM(xname, xenum) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_soc_info_enum_double, \ + .get = snd_soc_dapm_get_enum_double, \ + .put = msm_dig_cdc_put_dec_enum, \ + .private_value = (unsigned long)&xenum } + +static const struct snd_kcontrol_new dec1_mux = + MSM89XX_DEC_ENUM("DEC1 MUX Mux", dec1_mux_enum); + +static const struct snd_kcontrol_new dec2_mux = + MSM89XX_DEC_ENUM("DEC2 MUX Mux", dec2_mux_enum); + +static const struct snd_kcontrol_new dec3_mux = + MSM89XX_DEC_ENUM("DEC3 MUX Mux", dec3_mux_enum); + +static const struct snd_kcontrol_new dec4_mux = + MSM89XX_DEC_ENUM("DEC4 MUX Mux", dec4_mux_enum); + +static const struct snd_kcontrol_new decsva_mux = + MSM89XX_DEC_ENUM("DEC5 MUX Mux", decsva_mux_enum); + +static const struct snd_kcontrol_new i2s_tx2_inp1_mux = + SOC_DAPM_ENUM("I2S TX2 INP1 Mux", i2s_tx2_inp1_chain_enum); + +static const struct snd_kcontrol_new i2s_tx2_inp2_mux = + SOC_DAPM_ENUM("I2S TX2 INP2 Mux", i2s_tx2_inp2_chain_enum); + +static const struct snd_kcontrol_new i2s_tx3_inp2_mux = + SOC_DAPM_ENUM("I2S TX3 INP2 Mux", i2s_tx3_inp2_chain_enum); + +static const struct snd_kcontrol_new iir1_inp1_mux = + SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum); + +static const struct snd_kcontrol_new iir2_inp1_mux = + SOC_DAPM_ENUM("IIR2 INP1 Mux", iir2_inp1_mux_enum); + +static const struct snd_kcontrol_new rx_mix1_inp1_mux = + SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum); + +static const struct snd_kcontrol_new rx_mix1_inp2_mux = + SOC_DAPM_ENUM("RX1 MIX1 INP2 Mux", rx_mix1_inp2_chain_enum); + +static const struct snd_kcontrol_new rx_mix1_inp3_mux = + SOC_DAPM_ENUM("RX1 MIX1 INP3 Mux", rx_mix1_inp3_chain_enum); + +static const struct snd_kcontrol_new rx2_mix1_inp1_mux = + SOC_DAPM_ENUM("RX2 MIX1 INP1 Mux", rx2_mix1_inp1_chain_enum); + +static const struct snd_kcontrol_new rx2_mix1_inp2_mux = + SOC_DAPM_ENUM("RX2 MIX1 INP2 Mux", rx2_mix1_inp2_chain_enum); + +static const struct snd_kcontrol_new rx2_mix1_inp3_mux = + SOC_DAPM_ENUM("RX2 MIX1 INP3 Mux", rx2_mix1_inp3_chain_enum); + +static const struct snd_kcontrol_new rx3_mix1_inp2_mux = + SOC_DAPM_ENUM("RX3 MIX1 INP2 Mux", rx3_mix1_inp2_chain_enum); + +static const struct snd_kcontrol_new rx3_mix1_inp3_mux = + SOC_DAPM_ENUM("RX3 MIX1 INP3 Mux", rx3_mix1_inp3_chain_enum); + +static const struct snd_kcontrol_new rx1_mix2_inp1_mux = + SOC_DAPM_ENUM("RX1 MIX2 INP1 Mux", rx_mix2_inp1_chain_enum); + +static const struct snd_kcontrol_new rx2_mix2_inp1_mux = + SOC_DAPM_ENUM("RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum); + +static const struct snd_soc_dapm_widget msm_dig_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN("I2S RX1", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("I2S RX2", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("I2S RX3", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_OUT("I2S TX1", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("I2S TX2", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("I2S TX3", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("I2S TX4", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("I2S TX5", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("I2S TX6", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_MIXER_E("RX1 MIX2", MSM89XX_CDC_CORE_CLK_RX_B1_CTL, + MSM89XX_RX1, 0, NULL, 0, + msm_dig_cdc_codec_enable_interpolator, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX2 MIX2", MSM89XX_CDC_CORE_CLK_RX_B1_CTL, + MSM89XX_RX2, 0, NULL, 0, + msm_dig_cdc_codec_enable_interpolator, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX3 MIX1", MSM89XX_CDC_CORE_CLK_RX_B1_CTL, + MSM89XX_RX3, 0, NULL, 0, + msm_dig_cdc_codec_enable_interpolator, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MIXER("RX1 CHAIN", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX2 CHAIN", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX3 CHAIN", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx_mix1_inp1_mux), + SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx_mix1_inp2_mux), + SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0, + &rx_mix1_inp3_mux), + + SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx2_mix1_inp1_mux), + SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx2_mix1_inp2_mux), + SND_SOC_DAPM_MUX("RX2 MIX1 INP3", SND_SOC_NOPM, 0, 0, + &rx2_mix1_inp3_mux), + + SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx3_mix1_inp1_mux), + SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx3_mix1_inp2_mux), + SND_SOC_DAPM_MUX("RX3 MIX1 INP3", SND_SOC_NOPM, 0, 0, + &rx3_mix1_inp3_mux), + + SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0, + &rx1_mix2_inp1_mux), + SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0, + &rx2_mix2_inp1_mux), + + SND_SOC_DAPM_SUPPLY_S("CDC_CONN", -2, MSM89XX_CDC_CORE_CLK_OTHR_CTL, + 2, 0, NULL, 0), + + SND_SOC_DAPM_MUX_E("DEC1 MUX", + MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 0, 0, + &dec1_mux, msm_dig_cdc_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("DEC2 MUX", + MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 1, 0, + &dec2_mux, msm_dig_cdc_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("DEC3 MUX", + MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 2, 0, + &dec3_mux, msm_dig_cdc_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("DEC4 MUX", + MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 3, 0, + &dec4_mux, msm_dig_cdc_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("DEC5 MUX", + MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 4, 0, + &decsva_mux, msm_dig_cdc_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + /* Sidetone */ + SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux), + SND_SOC_DAPM_PGA_E("IIR1", MSM89XX_CDC_CORE_CLK_SD_CTL, 0, 0, NULL, 0, + msm_dig_cdc_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_MUX("IIR2 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir2_inp1_mux), + SND_SOC_DAPM_PGA_E("IIR2", MSM89XX_CDC_CORE_CLK_SD_CTL, 1, 0, NULL, 0, + msm_dig_cdc_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", + MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 4, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("TX_I2S_CLK", + MSM89XX_CDC_CORE_CLK_TX_I2S_CTL, 4, 0, NULL, 0), + + + SND_SOC_DAPM_MUX("I2S TX2 INP1", SND_SOC_NOPM, 0, 0, + &i2s_tx2_inp1_mux), + SND_SOC_DAPM_MUX("I2S TX2 INP2", SND_SOC_NOPM, 0, 0, + &i2s_tx2_inp2_mux), + SND_SOC_DAPM_MUX("I2S TX3 INP2", SND_SOC_NOPM, 0, 0, + &i2s_tx3_inp2_mux), + + /* Digital Mic Inputs */ + SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0, + msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0, + msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0, + msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0, + msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_INPUT("ADC1_IN"), + SND_SOC_DAPM_INPUT("ADC2_IN"), + SND_SOC_DAPM_INPUT("ADC3_IN"), + SND_SOC_DAPM_OUTPUT("PDM_OUT_RX1"), + SND_SOC_DAPM_OUTPUT("PDM_OUT_RX2"), + SND_SOC_DAPM_OUTPUT("PDM_OUT_RX3"), +}; + +static const struct soc_enum cf_dec1_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX1_MUX_CTL, 4, 3, cf_text); + +static const struct soc_enum cf_dec2_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX2_MUX_CTL, 4, 3, cf_text); + +static const struct soc_enum cf_dec3_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX3_MUX_CTL, 4, 3, cf_text); + +static const struct soc_enum cf_dec4_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX4_MUX_CTL, 4, 3, cf_text); + +static const struct soc_enum cf_decsva_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX5_MUX_CTL, 4, 3, cf_text); + +static const struct snd_kcontrol_new msm_dig_snd_controls[] = { + SOC_SINGLE_SX_TLV("DEC1 Volume", + MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC2 Volume", + MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC3 Volume", + MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC4 Volume", + MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC5 Volume", + MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN, + 0, -84, 40, digital_gain), + + SOC_SINGLE_SX_TLV("IIR1 INP1 Volume", + MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP2 Volume", + MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP3 Volume", + MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP4 Volume", + MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("IIR2 INP1 Volume", + MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL, + 0, -84, 40, digital_gain), + + SOC_SINGLE_SX_TLV("RX1 Digital Volume", + MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX2 Digital Volume", + MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX3 Digital Volume", + MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL, + 0, -84, 40, digital_gain), + + SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + + SOC_SINGLE_EXT("IIR2 Enable Band1", IIR2, BAND1, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR2 Enable Band2", IIR2, BAND2, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR2 Enable Band3", IIR2, BAND3, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR2 Enable Band4", IIR2, BAND4, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR2 Enable Band5", IIR2, BAND5, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + + SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + + SOC_SINGLE_MULTI_EXT("IIR2 Band1", IIR2, BAND1, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR2 Band2", IIR2, BAND2, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR2 Band3", IIR2, BAND3, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR2 Band4", IIR2, BAND4, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + + SOC_SINGLE("RX1 HPF Switch", + MSM89XX_CDC_CORE_RX1_B5_CTL, 2, 1, 0), + SOC_SINGLE("RX2 HPF Switch", + MSM89XX_CDC_CORE_RX2_B5_CTL, 2, 1, 0), + SOC_SINGLE("RX3 HPF Switch", + MSM89XX_CDC_CORE_RX3_B5_CTL, 2, 1, 0), + + SOC_ENUM("RX1 HPF cut off", cf_rxmix1_enum), + SOC_ENUM("RX2 HPF cut off", cf_rxmix2_enum), + SOC_ENUM("RX3 HPF cut off", cf_rxmix3_enum), + + SOC_ENUM("TX1 HPF cut off", cf_dec1_enum), + SOC_ENUM("TX2 HPF cut off", cf_dec2_enum), + SOC_ENUM("TX3 HPF cut off", cf_dec3_enum), + SOC_ENUM("TX4 HPF cut off", cf_dec4_enum), + SOC_ENUM("TX5 HPF cut off", cf_decsva_enum), + SOC_SINGLE("TX1 HPF Switch", + MSM89XX_CDC_CORE_TX1_MUX_CTL, 3, 1, 0), + SOC_SINGLE("TX2 HPF Switch", + MSM89XX_CDC_CORE_TX2_MUX_CTL, 3, 1, 0), + SOC_SINGLE("TX3 HPF Switch", + MSM89XX_CDC_CORE_TX3_MUX_CTL, 3, 1, 0), + SOC_SINGLE("TX4 HPF Switch", + MSM89XX_CDC_CORE_TX4_MUX_CTL, 3, 1, 0), + SOC_SINGLE("TX5 HPF Switch", + MSM89XX_CDC_CORE_TX5_MUX_CTL, 3, 1, 0), +}; + +static int msm_dig_cdc_digital_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec = NULL; + u16 tx_vol_ctl_reg = 0; + u8 decimator = 0, i; + struct msm_dig_priv *dig_cdc; + + pr_debug("%s: Digital Mute val = %d\n", __func__, mute); + + if (!dai || !dai->codec) { + pr_err("%s: Invalid params\n", __func__); + return -EINVAL; + } + codec = dai->codec; + dig_cdc = snd_soc_codec_get_drvdata(codec); + + if (dai->id == AIF1_PB) { + dev_dbg(codec->dev, "%s: Not capture use case skip\n", + __func__); + return 0; + } + + mute = (mute) ? 1 : 0; + if (!mute) { + /* + * 15 ms is an emperical value for the mute time + * that was arrived by checking the pop level + * to be inaudible + */ + usleep_range(15000, 15010); + } + + if (dai->id == AIF3_SVA) { + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG, 0x01, mute); + goto ret; + } + for (i = 0; i < (NUM_DECIMATORS - 1); i++) { + if (dig_cdc->dec_active[i]) + decimator = i + 1; + if (decimator && decimator < NUM_DECIMATORS) { + /* mute/unmute decimators corresponding to Tx DAI's */ + tx_vol_ctl_reg = + MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG + + 32 * (decimator - 1); + snd_soc_update_bits(codec, tx_vol_ctl_reg, + 0x01, mute); + } + decimator = 0; + } +ret: + return 0; +} + +static struct snd_soc_dai_ops msm_dig_dai_ops = { + .hw_params = msm_dig_cdc_hw_params, + .digital_mute = msm_dig_cdc_digital_mute, +}; + + +static struct snd_soc_dai_driver msm_codec_dais[] = { + { + .name = "msm_dig_cdc_dai_rx1", + .id = AIF1_PB, + .playback = { /* Support maximum range */ + .stream_name = "AIF1 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .rate_max = 192000, + .rate_min = 8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + }, + .ops = &msm_dig_dai_ops, + }, + { + .name = "msm_dig_cdc_dai_tx1", + .id = AIF1_CAP, + .capture = { /* Support maximum range */ + .stream_name = "AIF1 Capture", + .channels_min = 1, + .channels_max = 4, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = &msm_dig_dai_ops, + }, + { + .name = "msm_dig_cdc_dai_tx2", + .id = AIF3_SVA, + .capture = { /* Support maximum range */ + .stream_name = "AIF2 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = &msm_dig_dai_ops, + }, + { + .name = "msm_dig_cdc_dai_vifeed", + .id = AIF2_VIFEED, + .capture = { /* Support maximum range */ + .stream_name = "AIF2 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = &msm_dig_dai_ops, + }, +}; + +static struct regmap *msm_digital_get_regmap(struct device *dev) +{ + struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(dev); + + return msm_dig_cdc->regmap; +} + +static int msm_dig_cdc_suspend(struct snd_soc_codec *codec) +{ + struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev); + + msm_dig_cdc->dapm_bias_off = 1; + return 0; +} + +static int msm_dig_cdc_resume(struct snd_soc_codec *codec) +{ + struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev); + + msm_dig_cdc->dapm_bias_off = 0; + return 0; +} + +static struct snd_soc_codec_driver soc_msm_dig_codec = { + .probe = msm_dig_cdc_soc_probe, + .remove = msm_dig_cdc_soc_remove, + .suspend = msm_dig_cdc_suspend, + .resume = msm_dig_cdc_resume, + .controls = msm_dig_snd_controls, + .num_controls = ARRAY_SIZE(msm_dig_snd_controls), + .dapm_widgets = msm_dig_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(msm_dig_dapm_widgets), + .dapm_routes = audio_dig_map, + .num_dapm_routes = ARRAY_SIZE(audio_dig_map), + .get_regmap = msm_digital_get_regmap, +}; + +const struct regmap_config msm_digital_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 8, + .lock = enable_digital_callback, + .unlock = disable_digital_callback, + .cache_type = REGCACHE_FLAT, + .reg_defaults = msm89xx_cdc_core_defaults, + .num_reg_defaults = MSM89XX_CDC_CORE_MAX_REGISTER, + .writeable_reg = msm89xx_cdc_core_writeable_reg, + .readable_reg = msm89xx_cdc_core_readable_reg, + .volatile_reg = msm89xx_cdc_core_volatile_reg, + .reg_format_endian = REGMAP_ENDIAN_NATIVE, + .val_format_endian = REGMAP_ENDIAN_NATIVE, + .max_register = MSM89XX_CDC_CORE_MAX_REGISTER, +}; + +static int msm_dig_cdc_probe(struct platform_device *pdev) +{ + int ret; + u32 dig_cdc_addr; + struct msm_dig_priv *msm_dig_cdc; + struct dig_ctrl_platform_data *pdata; + + msm_dig_cdc = devm_kzalloc(&pdev->dev, sizeof(struct msm_dig_priv), + GFP_KERNEL); + if (!msm_dig_cdc) + return -ENOMEM; + pdata = dev_get_platdata(&pdev->dev); + if (!pdata) { + dev_err(&pdev->dev, "%s: pdata from parent is NULL\n", + __func__); + ret = -EINVAL; + goto rtn; + } + + ret = of_property_read_u32(pdev->dev.of_node, "reg", + &dig_cdc_addr); + if (ret) { + dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "reg"); + return ret; + } + + msm_dig_cdc->dig_base = ioremap(dig_cdc_addr, + MSM89XX_CDC_CORE_MAX_REGISTER); + if (msm_dig_cdc->dig_base == NULL) { + dev_err(&pdev->dev, "%s ioremap failed\n", __func__); + return -ENOMEM; + } + msm_dig_cdc->regmap = + devm_regmap_init_mmio_clk(&pdev->dev, NULL, + msm_dig_cdc->dig_base, &msm_digital_regmap_config); + + msm_dig_cdc->update_clkdiv = pdata->update_clkdiv; + msm_dig_cdc->get_cdc_version = pdata->get_cdc_version; + msm_dig_cdc->handle = pdata->handle; + msm_dig_cdc->register_notifier = pdata->register_notifier; + + dev_set_drvdata(&pdev->dev, msm_dig_cdc); + snd_soc_register_codec(&pdev->dev, &soc_msm_dig_codec, + msm_codec_dais, ARRAY_SIZE(msm_codec_dais)); + dev_dbg(&pdev->dev, "%s: registered DIG CODEC 0x%x\n", + __func__, dig_cdc_addr); +rtn: + return ret; +} + +static int msm_dig_cdc_remove(struct platform_device *pdev) +{ + snd_soc_unregister_codec(&pdev->dev); + return 0; +} + +#ifdef CONFIG_PM +static int msm_dig_suspend(struct device *dev) +{ + struct msm_asoc_mach_data *pdata; + struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(dev); + + if (!registered_digcodec || !msm_dig_cdc) { + pr_debug("%s:digcodec not initialized, return\n", __func__); + return 0; + } + pdata = snd_soc_card_get_drvdata(registered_digcodec->component.card); + if (!pdata) { + pr_debug("%s:card not initialized, return\n", __func__); + return 0; + } + if (msm_dig_cdc->dapm_bias_off) { + pr_debug("%s: mclk cnt = %d, mclk_enabled = %d\n", + __func__, atomic_read(&pdata->int_mclk0_rsc_ref), + atomic_read(&pdata->int_mclk0_enabled)); + + if (atomic_read(&pdata->int_mclk0_enabled) == true) { + cancel_delayed_work_sync( + &pdata->disable_int_mclk0_work); + mutex_lock(&pdata->cdc_int_mclk0_mutex); + pdata->digital_cdc_core_clk.enable = 0; + afe_set_lpass_clock_v2(AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + atomic_set(&pdata->int_mclk0_enabled, false); + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + } + } + + return 0; +} + +static int msm_dig_resume(struct device *dev) +{ + return 0; +} + +static const struct dev_pm_ops msm_dig_pm_ops = { + .suspend_late = msm_dig_suspend, + .resume_early = msm_dig_resume, +}; +#endif + +static const struct of_device_id msm_dig_cdc_of_match[] = { + {.compatible = "qcom,msm-digital-codec"}, + {}, +}; + +static struct platform_driver msm_digcodec_driver = { + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + .of_match_table = msm_dig_cdc_of_match, +#ifdef CONFIG_PM + .pm = &msm_dig_pm_ops, +#endif + }, + .probe = msm_dig_cdc_probe, + .remove = msm_dig_cdc_remove, +}; +module_platform_driver(msm_digcodec_driver); + +MODULE_DESCRIPTION("MSM Audio Digital codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.h b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.h new file mode 100644 index 000000000000..f0e7a9cf9228 --- /dev/null +++ b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.h @@ -0,0 +1,91 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef MSM_DIGITAL_CDC_H +#define MSM_DIGITAL_CDC_H + +#define HPHL_PA_DISABLE (0x01 << 1) +#define HPHR_PA_DISABLE (0x01 << 2) +#define SPKR_PA_DISABLE (0x01 << 3) + +#define NUM_DECIMATORS 5 +/* Codec supports 1 compander */ +enum { + COMPANDER_NONE = 0, + COMPANDER_1, /* HPHL/R */ + COMPANDER_MAX, +}; + +/* Number of output I2S port */ +enum { + MSM89XX_RX1 = 0, + MSM89XX_RX2, + MSM89XX_RX3, + MSM89XX_RX_MAX, +}; + +struct msm_dig_priv { + struct snd_soc_codec *codec; + u32 comp_enabled[MSM89XX_RX_MAX]; + int (*codec_hph_comp_gpio)(bool enable, struct snd_soc_codec *codec); + s32 dmic_1_2_clk_cnt; + s32 dmic_3_4_clk_cnt; + bool dec_active[NUM_DECIMATORS]; + int version; + /* Entry for version info */ + struct snd_info_entry *entry; + struct snd_info_entry *version_entry; + char __iomem *dig_base; + struct regmap *regmap; + struct notifier_block nblock; + u32 mute_mask; + int dapm_bias_off; + void *handle; + void (*update_clkdiv)(void *handle, int val); + int (*get_cdc_version)(void *handle); + int (*register_notifier)(void *handle, + struct notifier_block *nblock, + bool enable); +}; + +struct dig_ctrl_platform_data { + void *handle; + void (*update_clkdiv)(void *handle, int val); + int (*get_cdc_version)(void *handle); + int (*register_notifier)(void *handle, + struct notifier_block *nblock, + bool enable); +}; + +struct hpf_work { + struct msm_dig_priv *dig_cdc; + u32 decimator; + u8 tx_hpf_cut_of_freq; + struct delayed_work dwork; +}; + +/* Codec supports 5 bands */ +enum { + BAND1 = 0, + BAND2, + BAND3, + BAND4, + BAND5, + BAND_MAX, +}; + +extern void msm_dig_cdc_hph_comp_cb( + int (*codec_hph_comp_gpio)( + bool enable, struct snd_soc_codec *codec), + struct snd_soc_codec *codec); +int msm_dig_codec_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_codec *codec); +#endif diff --git a/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.c b/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.c new file mode 100644 index 000000000000..ee4ec34fa2d7 --- /dev/null +++ b/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.c @@ -0,0 +1,413 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm-analog-cdc.h" +#include "sdm660-cdc-irq.h" +#include "sdm660-cdc-registers.h" + +#define MAX_NUM_IRQS 14 +#define NUM_IRQ_REGS 2 +#define WCD9XXX_SYSTEM_RESUME_TIMEOUT_MS 700 + +#define BYTE_BIT_MASK(nr) (1UL << ((nr) % BITS_PER_BYTE)) +#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE) + +static irqreturn_t wcd9xxx_spmi_irq_handler(int linux_irq, void *data); + +char *irq_names[MAX_NUM_IRQS] = { + "spk_cnp_int", + "spk_clip_int", + "spk_ocp_int", + "ins_rem_det1", + "but_rel_det", + "but_press_det", + "ins_rem_det", + "mbhc_int", + "ear_ocp_int", + "hphr_ocp_int", + "hphl_ocp_det", + "ear_cnp_int", + "hphr_cnp_int", + "hphl_cnp_int" +}; + +int order[MAX_NUM_IRQS] = { + MSM89XX_IRQ_SPKR_CNP, + MSM89XX_IRQ_SPKR_CLIP, + MSM89XX_IRQ_SPKR_OCP, + MSM89XX_IRQ_MBHC_INSREM_DET1, + MSM89XX_IRQ_MBHC_RELEASE, + MSM89XX_IRQ_MBHC_PRESS, + MSM89XX_IRQ_MBHC_INSREM_DET, + MSM89XX_IRQ_MBHC_HS_DET, + MSM89XX_IRQ_EAR_OCP, + MSM89XX_IRQ_HPHR_OCP, + MSM89XX_IRQ_HPHL_OCP, + MSM89XX_IRQ_EAR_CNP, + MSM89XX_IRQ_HPHR_CNP, + MSM89XX_IRQ_HPHL_CNP, +}; + +enum wcd9xxx_spmi_pm_state { + WCD9XXX_PM_SLEEPABLE, + WCD9XXX_PM_AWAKE, + WCD9XXX_PM_ASLEEP, +}; + +struct wcd9xxx_spmi_map { + uint8_t handled[NUM_IRQ_REGS]; + uint8_t mask[NUM_IRQ_REGS]; + int linuxirq[MAX_NUM_IRQS]; + irq_handler_t handler[MAX_NUM_IRQS]; + struct platform_device *spmi[NUM_IRQ_REGS]; + struct snd_soc_codec *codec; + + enum wcd9xxx_spmi_pm_state pm_state; + struct mutex pm_lock; + /* pm_wq notifies change of pm_state */ + wait_queue_head_t pm_wq; + struct pm_qos_request pm_qos_req; + int wlock_holders; +}; + +struct wcd9xxx_spmi_map map; + +void wcd9xxx_spmi_enable_irq(int irq) +{ + pr_debug("%s: irqno =%d\n", __func__, irq); + + if (!(map.mask[BIT_BYTE(irq)] & (BYTE_BIT_MASK(irq)))) + return; + + map.mask[BIT_BYTE(irq)] &= + ~(BYTE_BIT_MASK(irq)); + + enable_irq(map.linuxirq[irq]); +} + +void wcd9xxx_spmi_disable_irq(int irq) +{ + pr_debug("%s: irqno =%d\n", __func__, irq); + + if (map.mask[BIT_BYTE(irq)] & (BYTE_BIT_MASK(irq))) + return; + + map.mask[BIT_BYTE(irq)] |= + (BYTE_BIT_MASK(irq)); + + disable_irq_nosync(map.linuxirq[irq]); +} + +int wcd9xxx_spmi_request_irq(int irq, irq_handler_t handler, + const char *name, void *priv) +{ + int rc; + unsigned long irq_flags; + + map.linuxirq[irq] = + platform_get_irq_byname(map.spmi[BIT_BYTE(irq)], + irq_names[irq]); + + if (strcmp(name, "mbhc sw intr")) + irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_ONESHOT; + else + irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_ONESHOT | IRQF_NO_SUSPEND; + pr_debug("%s: name:%s irq_flags = %lx\n", __func__, name, irq_flags); + + rc = devm_request_threaded_irq(&map.spmi[BIT_BYTE(irq)]->dev, + map.linuxirq[irq], NULL, + wcd9xxx_spmi_irq_handler, + irq_flags, + name, priv); + if (rc < 0) { + dev_err(&map.spmi[BIT_BYTE(irq)]->dev, + "Can't request %d IRQ\n", irq); + return rc; + } + + dev_dbg(&map.spmi[BIT_BYTE(irq)]->dev, + "irq %d linuxIRQ: %d\n", irq, map.linuxirq[irq]); + map.mask[BIT_BYTE(irq)] &= ~BYTE_BIT_MASK(irq); + map.handler[irq] = handler; + enable_irq_wake(map.linuxirq[irq]); + return 0; +} + +int wcd9xxx_spmi_free_irq(int irq, void *priv) +{ + devm_free_irq(&map.spmi[BIT_BYTE(irq)]->dev, map.linuxirq[irq], + priv); + map.mask[BIT_BYTE(irq)] |= BYTE_BIT_MASK(irq); + return 0; +} + +static int get_irq_bit(int linux_irq) +{ + int i = 0; + + for (; i < MAX_NUM_IRQS; i++) + if (map.linuxirq[i] == linux_irq) + return i; + + return i; +} + +static int get_order_irq(int i) +{ + return order[i]; +} + +static irqreturn_t wcd9xxx_spmi_irq_handler(int linux_irq, void *data) +{ + int irq, i, j; + unsigned long status[NUM_IRQ_REGS] = {0}; + + if (unlikely(wcd9xxx_spmi_lock_sleep() == false)) { + pr_err("Failed to hold suspend\n"); + return IRQ_NONE; + } + + irq = get_irq_bit(linux_irq); + if (irq == MAX_NUM_IRQS) + return IRQ_HANDLED; + + status[BIT_BYTE(irq)] |= BYTE_BIT_MASK(irq); + for (i = 0; i < NUM_IRQ_REGS; i++) { + status[i] |= snd_soc_read(map.codec, + BIT_BYTE(irq) * 0x100 + + MSM89XX_PMIC_DIGITAL_INT_LATCHED_STS); + status[i] &= ~map.mask[i]; + } + for (i = 0; i < MAX_NUM_IRQS; i++) { + j = get_order_irq(i); + if ((status[BIT_BYTE(j)] & BYTE_BIT_MASK(j)) && + ((map.handled[BIT_BYTE(j)] & + BYTE_BIT_MASK(j)) == 0)) { + map.handler[j](irq, data); + map.handled[BIT_BYTE(j)] |= + BYTE_BIT_MASK(j); + } + } + map.handled[BIT_BYTE(irq)] &= ~BYTE_BIT_MASK(irq); + wcd9xxx_spmi_unlock_sleep(); + + return IRQ_HANDLED; +} + +enum wcd9xxx_spmi_pm_state wcd9xxx_spmi_pm_cmpxchg( + enum wcd9xxx_spmi_pm_state o, + enum wcd9xxx_spmi_pm_state n) +{ + enum wcd9xxx_spmi_pm_state old; + + mutex_lock(&map.pm_lock); + old = map.pm_state; + if (old == o) + map.pm_state = n; + pr_debug("%s: map.pm_state = %d\n", __func__, map.pm_state); + mutex_unlock(&map.pm_lock); + return old; +} +EXPORT_SYMBOL(wcd9xxx_spmi_pm_cmpxchg); + +int wcd9xxx_spmi_suspend(pm_message_t pmesg) +{ + int ret = 0; + + pr_debug("%s: enter\n", __func__); + /* + * pm_qos_update_request() can be called after this suspend chain call + * started. thus suspend can be called while lock is being held + */ + mutex_lock(&map.pm_lock); + if (map.pm_state == WCD9XXX_PM_SLEEPABLE) { + pr_debug("%s: suspending system, state %d, wlock %d\n", + __func__, map.pm_state, + map.wlock_holders); + map.pm_state = WCD9XXX_PM_ASLEEP; + } else if (map.pm_state == WCD9XXX_PM_AWAKE) { + /* + * unlock to wait for pm_state == WCD9XXX_PM_SLEEPABLE + * then set to WCD9XXX_PM_ASLEEP + */ + pr_debug("%s: waiting to suspend system, state %d, wlock %d\n", + __func__, map.pm_state, + map.wlock_holders); + mutex_unlock(&map.pm_lock); + if (!(wait_event_timeout(map.pm_wq, + wcd9xxx_spmi_pm_cmpxchg( + WCD9XXX_PM_SLEEPABLE, + WCD9XXX_PM_ASLEEP) == + WCD9XXX_PM_SLEEPABLE, + HZ))) { + pr_debug("%s: suspend failed state %d, wlock %d\n", + __func__, map.pm_state, + map.wlock_holders); + ret = -EBUSY; + } else { + pr_debug("%s: done, state %d, wlock %d\n", __func__, + map.pm_state, + map.wlock_holders); + } + mutex_lock(&map.pm_lock); + } else if (map.pm_state == WCD9XXX_PM_ASLEEP) { + pr_warn("%s: system is already suspended, state %d, wlock %dn", + __func__, map.pm_state, + map.wlock_holders); + } + mutex_unlock(&map.pm_lock); + + return ret; +} +EXPORT_SYMBOL(wcd9xxx_spmi_suspend); + +int wcd9xxx_spmi_resume(void) +{ + int ret = 0; + + pr_debug("%s: enter\n", __func__); + mutex_lock(&map.pm_lock); + if (map.pm_state == WCD9XXX_PM_ASLEEP) { + pr_debug("%s: resuming system, state %d, wlock %d\n", __func__, + map.pm_state, + map.wlock_holders); + map.pm_state = WCD9XXX_PM_SLEEPABLE; + } else { + pr_warn("%s: system is already awake, state %d wlock %d\n", + __func__, map.pm_state, + map.wlock_holders); + } + mutex_unlock(&map.pm_lock); + wake_up_all(&map.pm_wq); + + return ret; +} +EXPORT_SYMBOL(wcd9xxx_spmi_resume); + +bool wcd9xxx_spmi_lock_sleep(void) +{ + /* + * wcd9xxx_spmi_{lock/unlock}_sleep will be called by + * wcd9xxx_spmi_irq_thread + * and its subroutines only motly. + * but btn0_lpress_fn is not wcd9xxx_spmi_irq_thread's subroutine and + * It can race with wcd9xxx_spmi_irq_thread. + * So need to embrace wlock_holders with mutex. + */ + mutex_lock(&map.pm_lock); + if (map.wlock_holders++ == 0) { + pr_debug("%s: holding wake lock\n", __func__); + pm_qos_update_request(&map.pm_qos_req, + msm_cpuidle_get_deep_idle_latency()); + pm_stay_awake(&map.spmi[0]->dev); + } + mutex_unlock(&map.pm_lock); + pr_debug("%s: wake lock counter %d\n", __func__, + map.wlock_holders); + pr_debug("%s: map.pm_state = %d\n", __func__, map.pm_state); + + if (!wait_event_timeout(map.pm_wq, + ((wcd9xxx_spmi_pm_cmpxchg( + WCD9XXX_PM_SLEEPABLE, + WCD9XXX_PM_AWAKE)) == + WCD9XXX_PM_SLEEPABLE || + (wcd9xxx_spmi_pm_cmpxchg( + WCD9XXX_PM_SLEEPABLE, + WCD9XXX_PM_AWAKE) == + WCD9XXX_PM_AWAKE)), + msecs_to_jiffies( + WCD9XXX_SYSTEM_RESUME_TIMEOUT_MS))) { + pr_warn("%s: system didn't resume within %dms, s %d, w %d\n", + __func__, + WCD9XXX_SYSTEM_RESUME_TIMEOUT_MS, map.pm_state, + map.wlock_holders); + wcd9xxx_spmi_unlock_sleep(); + return false; + } + wake_up_all(&map.pm_wq); + pr_debug("%s: leaving pm_state = %d\n", __func__, map.pm_state); + return true; +} +EXPORT_SYMBOL(wcd9xxx_spmi_lock_sleep); + +void wcd9xxx_spmi_unlock_sleep(void) +{ + mutex_lock(&map.pm_lock); + if (--map.wlock_holders == 0) { + pr_debug("%s: releasing wake lock pm_state %d -> %d\n", + __func__, map.pm_state, WCD9XXX_PM_SLEEPABLE); + /* + * if wcd9xxx_spmi_lock_sleep failed, pm_state would be still + * WCD9XXX_PM_ASLEEP, don't overwrite + */ + if (likely(map.pm_state == WCD9XXX_PM_AWAKE)) + map.pm_state = WCD9XXX_PM_SLEEPABLE; + pm_qos_update_request(&map.pm_qos_req, + PM_QOS_DEFAULT_VALUE); + pm_relax(&map.spmi[0]->dev); + } + mutex_unlock(&map.pm_lock); + pr_debug("%s: wake lock counter %d\n", __func__, + map.wlock_holders); + pr_debug("%s: map.pm_state = %d\n", __func__, map.pm_state); + wake_up_all(&map.pm_wq); +} +EXPORT_SYMBOL(wcd9xxx_spmi_unlock_sleep); + +void wcd9xxx_spmi_set_codec(struct snd_soc_codec *codec) +{ + map.codec = codec; +} + +void wcd9xxx_spmi_set_dev(struct platform_device *spmi, int i) +{ + if (i < NUM_IRQ_REGS) + map.spmi[i] = spmi; +} + +int wcd9xxx_spmi_irq_init(void) +{ + int i = 0; + + for (; i < MAX_NUM_IRQS; i++) + map.mask[BIT_BYTE(i)] |= BYTE_BIT_MASK(i); + mutex_init(&map.pm_lock); + map.wlock_holders = 0; + map.pm_state = WCD9XXX_PM_SLEEPABLE; + init_waitqueue_head(&map.pm_wq); + pm_qos_add_request(&map.pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + PM_QOS_DEFAULT_VALUE); + + return 0; +} + +MODULE_DESCRIPTION("MSM8x16 SPMI IRQ driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.h b/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.h new file mode 100644 index 000000000000..d0f48d0c2af2 --- /dev/null +++ b/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __WCD9XXX_SPMI_IRQ_H__ +#define __WCD9XXX_SPMI_IRQ_H__ + +#include +#include +#include +#include +#include + +extern void wcd9xxx_spmi_enable_irq(int irq); +extern void wcd9xxx_spmi_disable_irq(int irq); +extern int wcd9xxx_spmi_request_irq(int irq, irq_handler_t handler, + const char *name, void *priv); +extern int wcd9xxx_spmi_free_irq(int irq, void *priv); +extern void wcd9xxx_spmi_set_codec(struct snd_soc_codec *codec); +extern void wcd9xxx_spmi_set_dev(struct platform_device *spmi, int i); +extern int wcd9xxx_spmi_irq_init(void); +extern int wcd9xxx_spmi_suspend(pm_message_t pmesg); +extern int wcd9xxx_spmi_resume(void); +bool wcd9xxx_spmi_lock_sleep(void); +void wcd9xxx_spmi_unlock_sleep(void); + +#endif diff --git a/sound/soc/codecs/sdm660_cdc/sdm660-cdc-registers.h b/sound/soc/codecs/sdm660_cdc/sdm660-cdc-registers.h new file mode 100644 index 000000000000..1317ce169755 --- /dev/null +++ b/sound/soc/codecs/sdm660_cdc/sdm660-cdc-registers.h @@ -0,0 +1,603 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef SDM660_WCD_REGISTERS_H +#define SDM660_WCD_REGISTERS_H + +#define CDC_DIG_BASE 0xF000 +#define CDC_ANA_BASE 0xF100 + +#define MSM89XX_PMIC_DIGITAL_REVISION1 (CDC_DIG_BASE+0x000) +#define MSM89XX_PMIC_DIGITAL_REVISION1__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_REVISION2 (CDC_DIG_BASE+0x001) +#define MSM89XX_PMIC_DIGITAL_REVISION2__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_PERPH_TYPE (CDC_DIG_BASE+0x004) +#define MSM89XX_PMIC_DIGITAL_PERPH_TYPE__POR (0x23) +#define MSM89XX_PMIC_DIGITAL_PERPH_SUBTYPE (CDC_DIG_BASE+0x005) +#define MSM89XX_PMIC_DIGITAL_PERPH_SUBTYPE__POR (0x01) +#define MSM89XX_PMIC_DIGITAL_INT_RT_STS (CDC_DIG_BASE+0x010) +#define MSM89XX_PMIC_DIGITAL_INT_RT_STS__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_SET_TYPE (CDC_DIG_BASE+0x011) +#define MSM89XX_PMIC_DIGITAL_INT_SET_TYPE__POR (0xFF) +#define MSM89XX_PMIC_DIGITAL_INT_POLARITY_HIGH (CDC_DIG_BASE+0x012) +#define MSM89XX_PMIC_DIGITAL_INT_POLARITY_HIGH__POR (0xFF) +#define MSM89XX_PMIC_DIGITAL_INT_POLARITY_LOW (CDC_DIG_BASE+0x013) +#define MSM89XX_PMIC_DIGITAL_INT_POLARITY_LOW__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_LATCHED_CLR (CDC_DIG_BASE+0x014) +#define MSM89XX_PMIC_DIGITAL_INT_LATCHED_CLR__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_EN_SET (CDC_DIG_BASE+0x015) +#define MSM89XX_PMIC_DIGITAL_INT_EN_SET__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_EN_CLR (CDC_DIG_BASE+0x016) +#define MSM89XX_PMIC_DIGITAL_INT_EN_CLR__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_LATCHED_STS (CDC_DIG_BASE+0x018) +#define MSM89XX_PMIC_DIGITAL_INT_LATCHED_STS__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_PENDING_STS (CDC_DIG_BASE+0x019) +#define MSM89XX_PMIC_DIGITAL_INT_PENDING_STS__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_MID_SEL (CDC_DIG_BASE+0x01A) +#define MSM89XX_PMIC_DIGITAL_INT_MID_SEL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_PRIORITY (CDC_DIG_BASE+0x01B) +#define MSM89XX_PMIC_DIGITAL_INT_PRIORITY__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_GPIO_MODE (CDC_DIG_BASE+0x040) +#define MSM89XX_PMIC_DIGITAL_GPIO_MODE__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_PIN_CTL_OE (CDC_DIG_BASE+0x041) +#define MSM89XX_PMIC_DIGITAL_PIN_CTL_OE__POR (0x01) +#define MSM89XX_PMIC_DIGITAL_PIN_CTL_DATA (CDC_DIG_BASE+0x042) +#define MSM89XX_PMIC_DIGITAL_PIN_CTL_DATA__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_PIN_STATUS (CDC_DIG_BASE+0x043) +#define MSM89XX_PMIC_DIGITAL_PIN_STATUS__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_HDRIVE_CTL (CDC_DIG_BASE+0x044) +#define MSM89XX_PMIC_DIGITAL_HDRIVE_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_RST_CTL (CDC_DIG_BASE+0x046) +#define MSM89XX_PMIC_DIGITAL_CDC_RST_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL (CDC_DIG_BASE+0x048) +#define MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL (CDC_DIG_BASE+0x049) +#define MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL (CDC_DIG_BASE+0x04A) +#define MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL (CDC_DIG_BASE+0x050) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL__POR (0x02) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL (CDC_DIG_BASE+0x051) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL__POR (0x02) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_HPHR_DAC_CTL (CDC_DIG_BASE+0x052) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_HPHR_DAC_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX1_CTL (CDC_DIG_BASE+0x053) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX1_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX2_CTL (CDC_DIG_BASE+0x054) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX2_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX3_CTL (CDC_DIG_BASE+0x055) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX3_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX_LB_CTL (CDC_DIG_BASE+0x056) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX_LB_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL1 (CDC_DIG_BASE+0x058) +#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL1__POR (0x7C) +#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL2 (CDC_DIG_BASE+0x059) +#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL2__POR (0x7C) +#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL3 (CDC_DIG_BASE+0x05A) +#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL3__POR (0x7C) +#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA0 (CDC_DIG_BASE+0x05B) +#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA0__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA1 (CDC_DIG_BASE+0x05C) +#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA1__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA2 (CDC_DIG_BASE+0x05D) +#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA2__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA3 (CDC_DIG_BASE+0x05E) +#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA3__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_DIG_DEBUG_CTL (CDC_DIG_BASE+0x068) +#define MSM89XX_PMIC_DIGITAL_DIG_DEBUG_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_DIG_DEBUG_EN (CDC_DIG_BASE+0x069) +#define MSM89XX_PMIC_DIGITAL_DIG_DEBUG_EN__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_SPARE_0 (CDC_DIG_BASE+0x070) +#define MSM89XX_PMIC_DIGITAL_SPARE_0__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_SPARE_1 (CDC_DIG_BASE+0x071) +#define MSM89XX_PMIC_DIGITAL_SPARE_1__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_SPARE_2 (CDC_DIG_BASE+0x072) +#define MSM89XX_PMIC_DIGITAL_SPARE_2__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_SEC_ACCESS (CDC_DIG_BASE+0x0D0) +#define MSM89XX_PMIC_DIGITAL_SEC_ACCESS__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL1 (CDC_DIG_BASE+0x0D8) +#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL1__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL2 (CDC_DIG_BASE+0x0D9) +#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL2__POR (0x01) +#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3 (CDC_DIG_BASE+0x0DA) +#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3__POR (0x05) +#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4 (CDC_DIG_BASE+0x0DB) +#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_TEST1 (CDC_DIG_BASE+0x0E0) +#define MSM89XX_PMIC_DIGITAL_INT_TEST1__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_TEST_VAL (CDC_DIG_BASE+0x0E1) +#define MSM89XX_PMIC_DIGITAL_INT_TEST_VAL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_TRIM_NUM (CDC_DIG_BASE+0x0F0) +#define MSM89XX_PMIC_DIGITAL_TRIM_NUM__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_TRIM_CTRL (CDC_DIG_BASE+0x0F1) +#define MSM89XX_PMIC_DIGITAL_TRIM_CTRL__POR (0x00) + +#define MSM89XX_PMIC_ANALOG_REVISION1 (CDC_ANA_BASE+0x00) +#define MSM89XX_PMIC_ANALOG_REVISION1__POR (0x00) +#define MSM89XX_PMIC_ANALOG_REVISION2 (CDC_ANA_BASE+0x01) +#define MSM89XX_PMIC_ANALOG_REVISION2__POR (0x00) +#define MSM89XX_PMIC_ANALOG_REVISION3 (CDC_ANA_BASE+0x02) +#define MSM89XX_PMIC_ANALOG_REVISION3__POR (0x00) +#define MSM89XX_PMIC_ANALOG_REVISION4 (CDC_ANA_BASE+0x03) +#define MSM89XX_PMIC_ANALOG_REVISION4__POR (0x00) +#define MSM89XX_PMIC_ANALOG_PERPH_TYPE (CDC_ANA_BASE+0x04) +#define MSM89XX_PMIC_ANALOG_PERPH_TYPE__POR (0x23) +#define MSM89XX_PMIC_ANALOG_PERPH_SUBTYPE (CDC_ANA_BASE+0x05) +#define MSM89XX_PMIC_ANALOG_PERPH_SUBTYPE__POR (0x09) +#define MSM89XX_PMIC_ANALOG_INT_RT_STS (CDC_ANA_BASE+0x10) +#define MSM89XX_PMIC_ANALOG_INT_RT_STS__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_SET_TYPE (CDC_ANA_BASE+0x11) +#define MSM89XX_PMIC_ANALOG_INT_SET_TYPE__POR (0x3F) +#define MSM89XX_PMIC_ANALOG_INT_POLARITY_HIGH (CDC_ANA_BASE+0x12) +#define MSM89XX_PMIC_ANALOG_INT_POLARITY_HIGH__POR (0x3F) +#define MSM89XX_PMIC_ANALOG_INT_POLARITY_LOW (CDC_ANA_BASE+0x13) +#define MSM89XX_PMIC_ANALOG_INT_POLARITY_LOW__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_LATCHED_CLR (CDC_ANA_BASE+0x14) +#define MSM89XX_PMIC_ANALOG_INT_LATCHED_CLR__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_EN_SET (CDC_ANA_BASE+0x15) +#define MSM89XX_PMIC_ANALOG_INT_EN_SET__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_EN_CLR (CDC_ANA_BASE+0x16) +#define MSM89XX_PMIC_ANALOG_INT_EN_CLR__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_LATCHED_STS (CDC_ANA_BASE+0x18) +#define MSM89XX_PMIC_ANALOG_INT_LATCHED_STS__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_PENDING_STS (CDC_ANA_BASE+0x19) +#define MSM89XX_PMIC_ANALOG_INT_PENDING_STS__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_MID_SEL (CDC_ANA_BASE+0x1A) +#define MSM89XX_PMIC_ANALOG_INT_MID_SEL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_PRIORITY (CDC_ANA_BASE+0x1B) +#define MSM89XX_PMIC_ANALOG_INT_PRIORITY__POR (0x00) +#define MSM89XX_PMIC_ANALOG_MICB_1_EN (CDC_ANA_BASE+0x40) +#define MSM89XX_PMIC_ANALOG_MICB_1_EN__POR (0x00) +#define MSM89XX_PMIC_ANALOG_MICB_1_VAL (CDC_ANA_BASE+0x41) +#define MSM89XX_PMIC_ANALOG_MICB_1_VAL__POR (0x20) +#define MSM89XX_PMIC_ANALOG_MICB_1_CTL (CDC_ANA_BASE+0x42) +#define MSM89XX_PMIC_ANALOG_MICB_1_CTL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS (CDC_ANA_BASE+0x43) +#define MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS__POR (0x49) +#define MSM89XX_PMIC_ANALOG_MICB_2_EN (CDC_ANA_BASE+0x44) +#define MSM89XX_PMIC_ANALOG_MICB_2_EN__POR (0x20) +#define MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2 (CDC_ANA_BASE+0x45) +#define MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2__POR (0x00) +#define MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL (CDC_ANA_BASE+0x46) +#define MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1 (CDC_ANA_BASE+0x47) +#define MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1__POR (0x35) +#define MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2 (CDC_ANA_BASE+0x50) +#define MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2__POR (0x08) +#define MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL (CDC_ANA_BASE+0x51) +#define MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER (CDC_ANA_BASE+0x52) +#define MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER__POR (0x98) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL (CDC_ANA_BASE+0x53) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL (CDC_ANA_BASE+0x54) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL__POR (0x20) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL (CDC_ANA_BASE+0x55) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL__POR (0x40) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN3_CTL (CDC_ANA_BASE+0x56) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN3_CTL__POR (0x61) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN4_CTL (CDC_ANA_BASE+0x57) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN4_CTL__POR (0x80) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT (CDC_ANA_BASE+0x58) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT__POR (0x00) +#define MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT (CDC_ANA_BASE+0x59) +#define MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT__POR (0x00) +#define MSM89XX_PMIC_ANALOG_TX_1_EN (CDC_ANA_BASE+0x60) +#define MSM89XX_PMIC_ANALOG_TX_1_EN__POR (0x03) +#define MSM89XX_PMIC_ANALOG_TX_2_EN (CDC_ANA_BASE+0x61) +#define MSM89XX_PMIC_ANALOG_TX_2_EN__POR (0x03) +#define MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_1 (CDC_ANA_BASE+0x62) +#define MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_1__POR (0xBF) +#define MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_2 (CDC_ANA_BASE+0x63) +#define MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_2__POR (0x8C) +#define MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL (CDC_ANA_BASE+0x64) +#define MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS (CDC_ANA_BASE+0x65) +#define MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS__POR (0x6B) +#define MSM89XX_PMIC_ANALOG_TX_1_2_TXFE_CLKDIV (CDC_ANA_BASE+0x66) +#define MSM89XX_PMIC_ANALOG_TX_1_2_TXFE_CLKDIV__POR (0x51) +#define MSM89XX_PMIC_ANALOG_TX_3_EN (CDC_ANA_BASE+0x67) +#define MSM89XX_PMIC_ANALOG_TX_3_EN__POR (0x02) +#define MSM89XX_PMIC_ANALOG_NCP_EN (CDC_ANA_BASE+0x80) +#define MSM89XX_PMIC_ANALOG_NCP_EN__POR (0x26) +#define MSM89XX_PMIC_ANALOG_NCP_CLK (CDC_ANA_BASE+0x81) +#define MSM89XX_PMIC_ANALOG_NCP_CLK__POR (0x23) +#define MSM89XX_PMIC_ANALOG_NCP_DEGLITCH (CDC_ANA_BASE+0x82) +#define MSM89XX_PMIC_ANALOG_NCP_DEGLITCH__POR (0x5B) +#define MSM89XX_PMIC_ANALOG_NCP_FBCTRL (CDC_ANA_BASE+0x83) +#define MSM89XX_PMIC_ANALOG_NCP_FBCTRL__POR (0x08) +#define MSM89XX_PMIC_ANALOG_NCP_BIAS (CDC_ANA_BASE+0x84) +#define MSM89XX_PMIC_ANALOG_NCP_BIAS__POR (0x29) +#define MSM89XX_PMIC_ANALOG_NCP_VCTRL (CDC_ANA_BASE+0x85) +#define MSM89XX_PMIC_ANALOG_NCP_VCTRL__POR (0x24) +#define MSM89XX_PMIC_ANALOG_NCP_TEST (CDC_ANA_BASE+0x86) +#define MSM89XX_PMIC_ANALOG_NCP_TEST__POR (0x00) +#define MSM89XX_PMIC_ANALOG_NCP_CLIM_ADDR (CDC_ANA_BASE+0x87) +#define MSM89XX_PMIC_ANALOG_NCP_CLIM_ADDR__POR (0xD5) +#define MSM89XX_PMIC_ANALOG_RX_CLOCK_DIVIDER (CDC_ANA_BASE+0x90) +#define MSM89XX_PMIC_ANALOG_RX_CLOCK_DIVIDER__POR (0xE8) +#define MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL (CDC_ANA_BASE+0x91) +#define MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL__POR (0xCF) +#define MSM89XX_PMIC_ANALOG_RX_COM_OCP_COUNT (CDC_ANA_BASE+0x92) +#define MSM89XX_PMIC_ANALOG_RX_COM_OCP_COUNT__POR (0x6E) +#define MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC (CDC_ANA_BASE+0x93) +#define MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC__POR (0x18) +#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA (CDC_ANA_BASE+0x94) +#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA__POR (0x5A) +#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_LDO_OCP (CDC_ANA_BASE+0x95) +#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_LDO_OCP__POR (0x69) +#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_CNP (CDC_ANA_BASE+0x96) +#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_CNP__POR (0x29) +#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN (CDC_ANA_BASE+0x97) +#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN__POR (0x80) +#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_CTL (CDC_ANA_BASE+0x98) +#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_CTL__POR (0xDA) +#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME (CDC_ANA_BASE+0x99) +#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME__POR (0x16) +#define MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST (CDC_ANA_BASE+0x9A) +#define MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST__POR (0x00) +#define MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL (CDC_ANA_BASE+0x9B) +#define MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL__POR (0x20) +#define MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST (CDC_ANA_BASE+0x9C) +#define MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST__POR (0x00) +#define MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL (CDC_ANA_BASE+0x9D) +#define MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL__POR (0x20) +#define MSM89XX_PMIC_ANALOG_RX_EAR_CTL (CDC_ANA_BASE+0x9E) +#define MSM89XX_PMIC_ANALOG_RX_EAR_CTL___POR (0x12) +#define MSM89XX_PMIC_ANALOG_RX_ATEST (CDC_ANA_BASE+0x9F) +#define MSM89XX_PMIC_ANALOG_RX_ATEST__POR (0x00) +#define MSM89XX_PMIC_ANALOG_RX_HPH_STATUS (CDC_ANA_BASE+0xA0) +#define MSM89XX_PMIC_ANALOG_RX_HPH_STATUS__POR (0x0C) +#define MSM89XX_PMIC_ANALOG_RX_EAR_STATUS (CDC_ANA_BASE+0xA1) +#define MSM89XX_PMIC_ANALOG_RX_EAR_STATUS__POR (0x00) +#define MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL (CDC_ANA_BASE+0xAC) +#define MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL (CDC_ANA_BASE+0xAD) +#define MSM89XX_PMIC_ANALOG_RX_RX_LO_EN_CTL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL (CDC_ANA_BASE+0xB0) +#define MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL__POR (0x83) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_CLIP_DET (CDC_ANA_BASE+0xB1) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_CLIP_DET__POR (0x91) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL (CDC_ANA_BASE+0xB2) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL__POR (0x29) +#define MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET (CDC_ANA_BASE+0xB3) +#define MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET__POR (0x4D) +#define MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL (CDC_ANA_BASE+0xB4) +#define MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL__POR (0xE1) +#define MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL (CDC_ANA_BASE+0xB5) +#define MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL__POR (0x1E) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_MISC (CDC_ANA_BASE+0xB6) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_MISC__POR (0xCB) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG (CDC_ANA_BASE+0xB7) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG__POR (0x00) +#define MSM89XX_PMIC_ANALOG_CURRENT_LIMIT (CDC_ANA_BASE+0xC0) +#define MSM89XX_PMIC_ANALOG_CURRENT_LIMIT__POR (0x02) +#define MSM89XX_PMIC_ANALOG_OUTPUT_VOLTAGE (CDC_ANA_BASE+0xC1) +#define MSM89XX_PMIC_ANALOG_OUTPUT_VOLTAGE__POR (0x14) +#define MSM89XX_PMIC_ANALOG_BYPASS_MODE (CDC_ANA_BASE+0xC2) +#define MSM89XX_PMIC_ANALOG_BYPASS_MODE__POR (0x00) +#define MSM89XX_PMIC_ANALOG_BOOST_EN_CTL (CDC_ANA_BASE+0xC3) +#define MSM89XX_PMIC_ANALOG_BOOST_EN_CTL__POR (0x1F) +#define MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO (CDC_ANA_BASE+0xC4) +#define MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO__POR (0x8C) +#define MSM89XX_PMIC_ANALOG_RDSON_MAX_DUTY_CYCLE (CDC_ANA_BASE+0xC5) +#define MSM89XX_PMIC_ANALOG_RDSON_MAX_DUTY_CYCLE__POR (0xC0) +#define MSM89XX_PMIC_ANALOG_BOOST_TEST1_1 (CDC_ANA_BASE+0xC6) +#define MSM89XX_PMIC_ANALOG_BOOST_TEST1_1__POR (0x00) +#define MSM89XX_PMIC_ANALOG_BOOST_TEST_2 (CDC_ANA_BASE+0xC7) +#define MSM89XX_PMIC_ANALOG_BOOST_TEST_2__POR (0x00) +#define MSM89XX_PMIC_ANALOG_SPKR_SAR_STATUS (CDC_ANA_BASE+0xC8) +#define MSM89XX_PMIC_ANALOG_SPKR_SAR_STATUS__POR (0x00) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_STATUS (CDC_ANA_BASE+0xC9) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_STATUS__POR (0x00) +#define MSM89XX_PMIC_ANALOG_PBUS_ADD_CSR (CDC_ANA_BASE+0xCE) +#define MSM89XX_PMIC_ANALOG_PBUS_ADD_CSR__POR (0x00) +#define MSM89XX_PMIC_ANALOG_PBUS_ADD_SEL (CDC_ANA_BASE+0xCF) +#define MSM89XX_PMIC_ANALOG_PBUS_ADD_SEL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_SEC_ACCESS (CDC_ANA_BASE+0xD0) +#define MSM89XX_PMIC_ANALOG_SEC_ACCESS__POR (0x00) +#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL1 (CDC_ANA_BASE+0xD8) +#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL1__POR (0x00) +#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL2 (CDC_ANA_BASE+0xD9) +#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL2__POR (0x01) +#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3 (CDC_ANA_BASE+0xDA) +#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3__POR (0x05) +#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4 (CDC_ANA_BASE+0xDB) +#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_TEST1 (CDC_ANA_BASE+0xE0) +#define MSM89XX_PMIC_ANALOG_INT_TEST1__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_TEST_VAL (CDC_ANA_BASE+0xE1) +#define MSM89XX_PMIC_ANALOG_INT_TEST_VAL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_TRIM_NUM (CDC_ANA_BASE+0xF0) +#define MSM89XX_PMIC_ANALOG_TRIM_NUM__POR (0x04) +#define MSM89XX_PMIC_ANALOG_TRIM_CTRL1 (CDC_ANA_BASE+0xF1) +#define MSM89XX_PMIC_ANALOG_TRIM_CTRL1__POR (0x00) +#define MSM89XX_PMIC_ANALOG_TRIM_CTRL2 (CDC_ANA_BASE+0xF2) +#define MSM89XX_PMIC_ANALOG_TRIM_CTRL2__POR (0x00) +#define MSM89XX_PMIC_ANALOG_TRIM_CTRL3 (CDC_ANA_BASE+0xF3) +#define MSM89XX_PMIC_ANALOG_TRIM_CTRL3__POR (0x00) +#define MSM89XX_PMIC_ANALOG_TRIM_CTRL4 (CDC_ANA_BASE+0xF4) +#define MSM89XX_PMIC_ANALOG_TRIM_CTRL4__POR (0x00) + +#define MSM89XX_PMIC_CDC_NUM_REGISTERS \ + (MSM89XX_PMIC_ANALOG_TRIM_CTRL4+1) +#define MSM89XX_PMIC_CDC_MAX_REGISTER \ + (MSM89XX_PMIC_CDC_NUM_REGISTERS-1) +#define MSM89XX_PMIC_CDC_CACHE_SIZE \ + MSM89XX_PMIC_CDC_NUM_REGISTERS + + +#define MSM89XX_CDC_CORE_CLK_RX_RESET_CTL (0x00) +#define MSM89XX_CDC_CORE_CLK_RX_RESET_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL (0x04) +#define MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL (0x08) +#define MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_RX_I2S_CTL (0x0C) +#define MSM89XX_CDC_CORE_CLK_RX_I2S_CTL__POR (0x13) +#define MSM89XX_CDC_CORE_CLK_TX_I2S_CTL (0x10) +#define MSM89XX_CDC_CORE_CLK_TX_I2S_CTL__POR (0x13) +#define MSM89XX_CDC_CORE_CLK_OTHR_RESET_B1_CTL (0x14) +#define MSM89XX_CDC_CORE_CLK_OTHR_RESET_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL (0x18) +#define MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_OTHR_CTL (0x1C) +#define MSM89XX_CDC_CORE_CLK_OTHR_CTL__POR (0x04) +#define MSM89XX_CDC_CORE_CLK_RX_B1_CTL (0x20) +#define MSM89XX_CDC_CORE_CLK_RX_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_MCLK_CTL (0x24) +#define MSM89XX_CDC_CORE_CLK_MCLK_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_PDM_CTL (0x28) +#define MSM89XX_CDC_CORE_CLK_PDM_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_SD_CTL (0x2C) +#define MSM89XX_CDC_CORE_CLK_SD_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL (0x30) +#define MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_RX_B2_CTL (0x34) +#define MSM89XX_CDC_CORE_CLK_RX_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_TX2_I2S_CTL (0x38) +#define MSM89XX_CDC_CORE_CLK_TX2_I2S_CTL__POR (0x13) +#define MSM89XX_CDC_CORE_RX1_B1_CTL (0x40) +#define MSM89XX_CDC_CORE_RX1_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX2_B1_CTL (0x60) +#define MSM89XX_CDC_CORE_RX2_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX3_B1_CTL (0x80) +#define MSM89XX_CDC_CORE_RX3_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX1_B2_CTL (0x44) +#define MSM89XX_CDC_CORE_RX1_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX2_B2_CTL (0x64) +#define MSM89XX_CDC_CORE_RX2_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX3_B2_CTL (0x84) +#define MSM89XX_CDC_CORE_RX3_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX1_B3_CTL (0x48) +#define MSM89XX_CDC_CORE_RX1_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX2_B3_CTL (0x68) +#define MSM89XX_CDC_CORE_RX2_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX3_B3_CTL (0x88) +#define MSM89XX_CDC_CORE_RX3_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX1_B4_CTL (0x4C) +#define MSM89XX_CDC_CORE_RX1_B4_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX2_B4_CTL (0x6C) +#define MSM89XX_CDC_CORE_RX2_B4_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX3_B4_CTL (0x8C) +#define MSM89XX_CDC_CORE_RX3_B4_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX1_B5_CTL (0x50) +#define MSM89XX_CDC_CORE_RX1_B5_CTL__POR (0x68) +#define MSM89XX_CDC_CORE_RX2_B5_CTL (0x70) +#define MSM89XX_CDC_CORE_RX2_B5_CTL__POR (0x68) +#define MSM89XX_CDC_CORE_RX3_B5_CTL (0x90) +#define MSM89XX_CDC_CORE_RX3_B5_CTL__POR (0x68) +#define MSM89XX_CDC_CORE_RX1_B6_CTL (0x54) +#define MSM89XX_CDC_CORE_RX1_B6_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX2_B6_CTL (0x74) +#define MSM89XX_CDC_CORE_RX2_B6_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX3_B6_CTL (0x94) +#define MSM89XX_CDC_CORE_RX3_B6_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX1_VOL_CTL_B1_CTL (0x58) +#define MSM89XX_CDC_CORE_RX1_VOL_CTL_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX2_VOL_CTL_B1_CTL (0x78) +#define MSM89XX_CDC_CORE_RX2_VOL_CTL_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX3_VOL_CTL_B1_CTL (0x98) +#define MSM89XX_CDC_CORE_RX3_VOL_CTL_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL (0x5C) +#define MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL (0x7C) +#define MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL (0x9C) +#define MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TOP_GAIN_UPDATE (0xA0) +#define MSM89XX_CDC_CORE_TOP_GAIN_UPDATE__POR (0x00) +#define MSM89XX_CDC_CORE_TOP_CTL (0xA4) +#define MSM89XX_CDC_CORE_TOP_CTL__POR (0x01) +#define MSM89XX_CDC_CORE_COMP0_B1_CTL (0xB0) +#define MSM89XX_CDC_CORE_COMP0_B1_CTL__POR (0x30) +#define MSM89XX_CDC_CORE_COMP0_B2_CTL (0xB4) +#define MSM89XX_CDC_CORE_COMP0_B2_CTL__POR (0xB5) +#define MSM89XX_CDC_CORE_COMP0_B3_CTL (0xB8) +#define MSM89XX_CDC_CORE_COMP0_B3_CTL__POR (0x28) +#define MSM89XX_CDC_CORE_COMP0_B4_CTL (0xBC) +#define MSM89XX_CDC_CORE_COMP0_B4_CTL__POR (0x37) +#define MSM89XX_CDC_CORE_COMP0_B5_CTL (0xC0) +#define MSM89XX_CDC_CORE_COMP0_B5_CTL__POR (0x7F) +#define MSM89XX_CDC_CORE_COMP0_B6_CTL (0xC4) +#define MSM89XX_CDC_CORE_COMP0_B6_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_COMP0_SHUT_DOWN_STATUS (0xC8) +#define MSM89XX_CDC_CORE_COMP0_SHUT_DOWN_STATUS__POR (0x03) +#define MSM89XX_CDC_CORE_COMP0_FS_CFG (0xCC) +#define MSM89XX_CDC_CORE_COMP0_FS_CFG__POR (0x03) +#define MSM89XX_CDC_CORE_COMP0_DELAY_BUF_CTL (0xD0) +#define MSM89XX_CDC_CORE_COMP0_DELAY_BUF_CTL__POR (0x02) +#define MSM89XX_CDC_CORE_DEBUG_DESER1_CTL (0xE0) +#define MSM89XX_CDC_CORE_DEBUG_DESER1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_DEBUG_DESER2_CTL (0xE4) +#define MSM89XX_CDC_CORE_DEBUG_DESER2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_DEBUG_B1_CTL_CFG (0xE8) +#define MSM89XX_CDC_CORE_DEBUG_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_DEBUG_B2_CTL_CFG (0xEC) +#define MSM89XX_CDC_CORE_DEBUG_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_DEBUG_B3_CTL_CFG (0xF0) +#define MSM89XX_CDC_CORE_DEBUG_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL (0x100) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL (0x140) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL (0x104) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B2_CTL (0x144) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL (0x108) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B3_CTL (0x148) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL (0x10C) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B4_CTL (0x14C) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B4_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B5_CTL (0x110) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B5_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B5_CTL (0x150) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B5_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B6_CTL (0x114) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B6_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B6_CTL (0x154) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B6_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B7_CTL (0x118) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B7_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B7_CTL (0x158) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B7_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B8_CTL (0x11C) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B8_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B8_CTL (0x15C) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B8_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_CTL (0x120) +#define MSM89XX_CDC_CORE_IIR1_CTL__POR (0x40) +#define MSM89XX_CDC_CORE_IIR2_CTL (0x160) +#define MSM89XX_CDC_CORE_IIR2_CTL__POR (0x40) +#define MSM89XX_CDC_CORE_IIR1_GAIN_TIMER_CTL (0x124) +#define MSM89XX_CDC_CORE_IIR1_GAIN_TIMER_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_TIMER_CTL (0x164) +#define MSM89XX_CDC_CORE_IIR2_GAIN_TIMER_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL (0x128) +#define MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL (0x168) +#define MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL (0x12C) +#define MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_COEF_B2_CTL (0x16C) +#define MSM89XX_CDC_CORE_IIR2_COEF_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_RX1_B1_CTL (0x180) +#define MSM89XX_CDC_CORE_CONN_RX1_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_RX1_B2_CTL (0x184) +#define MSM89XX_CDC_CORE_CONN_RX1_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_RX1_B3_CTL (0x188) +#define MSM89XX_CDC_CORE_CONN_RX1_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_RX2_B1_CTL (0x18C) +#define MSM89XX_CDC_CORE_CONN_RX2_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_RX2_B2_CTL (0x190) +#define MSM89XX_CDC_CORE_CONN_RX2_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_RX2_B3_CTL (0x194) +#define MSM89XX_CDC_CORE_CONN_RX2_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_RX3_B1_CTL (0x198) +#define MSM89XX_CDC_CORE_CONN_RX3_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_RX3_B2_CTL (0x19C) +#define MSM89XX_CDC_CORE_CONN_RX3_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_TX_B1_CTL (0x1A0) +#define MSM89XX_CDC_CORE_CONN_TX_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_TX_B2_CTL (0x1A4) +#define MSM89XX_CDC_CORE_CONN_TX_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL (0x1A8) +#define MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_EQ1_B2_CTL (0x1AC) +#define MSM89XX_CDC_CORE_CONN_EQ1_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_EQ1_B3_CTL (0x1B0) +#define MSM89XX_CDC_CORE_CONN_EQ1_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_EQ1_B4_CTL (0x1B4) +#define MSM89XX_CDC_CORE_CONN_EQ1_B4_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL (0x1B8) +#define MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_EQ2_B2_CTL (0x1BC) +#define MSM89XX_CDC_CORE_CONN_EQ2_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_EQ2_B3_CTL (0x1C0) +#define MSM89XX_CDC_CORE_CONN_EQ2_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_EQ2_B4_CTL (0x1C4) +#define MSM89XX_CDC_CORE_CONN_EQ2_B4_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL (0x1C8) +#define MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_TX_B3_CTL (0x1CC) +#define MSM89XX_CDC_CORE_CONN_TX_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX5_VOL_CTL_TIMER (0x1E0) +#define MSM89XX_CDC_CORE_TX5_VOL_CTL_TIMER__POR (0x00) +#define MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN (0x1E4) +#define MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN__POR (0x00) +#define MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG (0x1E8) +#define MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG__POR (0x00) +#define MSM89XX_CDC_CORE_TX5_MUX_CTL (0x1EC) +#define MSM89XX_CDC_CORE_TX5_MUX_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX5_CLK_FS_CTL (0x1F0) +#define MSM89XX_CDC_CORE_TX5_CLK_FS_CTL__POR (0x03) +#define MSM89XX_CDC_CORE_TX5_DMIC_CTL (0x1F4) +#define MSM89XX_CDC_CORE_TX5_DMIC_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX1_VOL_CTL_TIMER (0x280) +#define MSM89XX_CDC_CORE_TX1_VOL_CTL_TIMER__POR (0x00) +#define MSM89XX_CDC_CORE_TX2_VOL_CTL_TIMER (0x2A0) +#define MSM89XX_CDC_CORE_TX2_VOL_CTL_TIMER__POR (0x00) +#define MSM89XX_CDC_CORE_TX3_VOL_CTL_TIMER (0x2C0) +#define MSM89XX_CDC_CORE_TX3_VOL_CTL_TIMER__POR (0x00) +#define MSM89XX_CDC_CORE_TX4_VOL_CTL_TIMER (0x2E0) +#define MSM89XX_CDC_CORE_TX4_VOL_CTL_TIMER__POR (0x00) +#define MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN (0x284) +#define MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN__POR (0x00) +#define MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN (0x2A4) +#define MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN__POR (0x00) +#define MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN (0x2C4) +#define MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN__POR (0x00) +#define MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN (0x2E4) +#define MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN__POR (0x00) +#define MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG (0x288) +#define MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG__POR (0x00) +#define MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG (0x2A8) +#define MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG__POR (0x00) +#define MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG (0x2C8) +#define MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG__POR (0x00) +#define MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG (0x2E8) +#define MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG__POR (0x00) +#define MSM89XX_CDC_CORE_TX1_MUX_CTL (0x28C) +#define MSM89XX_CDC_CORE_TX1_MUX_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX2_MUX_CTL (0x2AC) +#define MSM89XX_CDC_CORE_TX2_MUX_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX3_MUX_CTL (0x2CC) +#define MSM89XX_CDC_CORE_TX3_MUX_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX4_MUX_CTL (0x2EC) +#define MSM89XX_CDC_CORE_TX4_MUX_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX1_CLK_FS_CTL (0x290) +#define MSM89XX_CDC_CORE_TX1_CLK_FS_CTL__POR (0x03) +#define MSM89XX_CDC_CORE_TX2_CLK_FS_CTL (0x2B0) +#define MSM89XX_CDC_CORE_TX2_CLK_FS_CTL__POR (0x03) +#define MSM89XX_CDC_CORE_TX3_CLK_FS_CTL (0x2D0) +#define MSM89XX_CDC_CORE_TX3_CLK_FS_CTL__POR (0x03) +#define MSM89XX_CDC_CORE_TX4_CLK_FS_CTL (0x2F0) +#define MSM89XX_CDC_CORE_TX4_CLK_FS_CTL__POR (0x03) +#define MSM89XX_CDC_CORE_TX1_DMIC_CTL (0x294) +#define MSM89XX_CDC_CORE_TX1_DMIC_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX2_DMIC_CTL (0x2B4) +#define MSM89XX_CDC_CORE_TX2_DMIC_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX3_DMIC_CTL (0x2D4) +#define MSM89XX_CDC_CORE_TX3_DMIC_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX4_DMIC_CTL (0x2F4) +#define MSM89XX_CDC_CORE_TX4_DMIC_CTL__POR (0x00) + +#define MSM89XX_CDC_CORE_NUM_REGISTERS \ + (MSM89XX_CDC_CORE_TX4_DMIC_CTL+1) +#define MSM89XX_CDC_CORE_MAX_REGISTER \ + (MSM89XX_CDC_CORE_NUM_REGISTERS-1) +#define MSM89XX_CDC_CORE_CACHE_SIZE \ + MSM89XX_CDC_CORE_NUM_REGISTERS +#endif diff --git a/sound/soc/codecs/sdm660_cdc/sdm660-regmap.c b/sound/soc/codecs/sdm660_cdc/sdm660-regmap.c new file mode 100644 index 000000000000..7d8ac6df14bb --- /dev/null +++ b/sound/soc/codecs/sdm660_cdc/sdm660-regmap.c @@ -0,0 +1,611 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "msm-cdc-common.h" +#include "sdm660-cdc-registers.h" + +/* + * Default register reset values that are common across different versions + * are defined here. If a register reset value is changed based on version + * then remove it from this structure and add it in version specific + * structures. + */ +struct reg_default + msm89xx_cdc_core_defaults[MSM89XX_CDC_CORE_CACHE_SIZE] = { + {MSM89XX_CDC_CORE_CLK_RX_RESET_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x13}, + {MSM89XX_CDC_CORE_CLK_TX_I2S_CTL, 0x13}, + {MSM89XX_CDC_CORE_CLK_OTHR_RESET_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_OTHR_CTL, 0x04}, + {MSM89XX_CDC_CORE_CLK_RX_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_MCLK_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_PDM_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_SD_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_TX2_I2S_CTL, 0x13}, + {MSM89XX_CDC_CORE_RX1_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX2_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX3_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX1_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX2_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX3_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX1_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX2_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX3_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX1_B4_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX2_B4_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX3_B4_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX1_B5_CTL, 0x68}, + {MSM89XX_CDC_CORE_RX2_B5_CTL, 0x68}, + {MSM89XX_CDC_CORE_RX3_B5_CTL, 0x68}, + {MSM89XX_CDC_CORE_RX1_B6_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX2_B6_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX3_B6_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX1_VOL_CTL_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX2_VOL_CTL_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX3_VOL_CTL_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_TOP_GAIN_UPDATE, 0x00}, + {MSM89XX_CDC_CORE_TOP_CTL, 0x01}, + {MSM89XX_CDC_CORE_COMP0_B1_CTL, 0x30}, + {MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xB5}, + {MSM89XX_CDC_CORE_COMP0_B3_CTL, 0x28}, + {MSM89XX_CDC_CORE_COMP0_B4_CTL, 0x37}, + {MSM89XX_CDC_CORE_COMP0_B5_CTL, 0x7F}, + {MSM89XX_CDC_CORE_COMP0_B6_CTL, 0x00}, + {MSM89XX_CDC_CORE_COMP0_SHUT_DOWN_STATUS, 0x03}, + {MSM89XX_CDC_CORE_COMP0_FS_CFG, 0x03}, + {MSM89XX_CDC_CORE_COMP0_DELAY_BUF_CTL, 0x02}, + {MSM89XX_CDC_CORE_DEBUG_DESER1_CTL, 0x00}, + {MSM89XX_CDC_CORE_DEBUG_DESER2_CTL, 0x00}, + {MSM89XX_CDC_CORE_DEBUG_B1_CTL_CFG, 0x00}, + {MSM89XX_CDC_CORE_DEBUG_B2_CTL_CFG, 0x00}, + {MSM89XX_CDC_CORE_DEBUG_B3_CTL_CFG, 0x00}, + {MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_B4_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_GAIN_B5_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_B5_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_GAIN_B6_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_B6_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_GAIN_B7_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_B7_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_GAIN_B8_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_B8_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_CTL, 0x40}, + {MSM89XX_CDC_CORE_IIR2_CTL, 0x40}, + {MSM89XX_CDC_CORE_IIR1_GAIN_TIMER_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_TIMER_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_COEF_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_RX1_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_RX1_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_RX1_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_RX2_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_RX2_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_RX2_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_RX3_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_RX3_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_TX_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_TX_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_EQ1_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_EQ1_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_EQ1_B4_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_EQ2_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_EQ2_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_EQ2_B4_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_TX_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX5_VOL_CTL_TIMER, 0x00}, + {MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN, 0x00}, + {MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG, 0x00}, + {MSM89XX_CDC_CORE_TX5_MUX_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX5_CLK_FS_CTL, 0x03}, + {MSM89XX_CDC_CORE_TX5_DMIC_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX1_VOL_CTL_TIMER, 0x00}, + {MSM89XX_CDC_CORE_TX2_VOL_CTL_TIMER, 0x00}, + {MSM89XX_CDC_CORE_TX3_VOL_CTL_TIMER, 0x00}, + {MSM89XX_CDC_CORE_TX4_VOL_CTL_TIMER, 0x00}, + {MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN, 0x00}, + {MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN, 0x00}, + {MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN, 0x00}, + {MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN, 0x00}, + {MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG, 0x00}, + {MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG, 0x00}, + {MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG, 0x00}, + {MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG, 0x00}, + {MSM89XX_CDC_CORE_TX1_MUX_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX2_MUX_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX3_MUX_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX4_MUX_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX1_CLK_FS_CTL, 0x03}, + {MSM89XX_CDC_CORE_TX2_CLK_FS_CTL, 0x03}, + {MSM89XX_CDC_CORE_TX3_CLK_FS_CTL, 0x03}, + {MSM89XX_CDC_CORE_TX4_CLK_FS_CTL, 0x03}, + {MSM89XX_CDC_CORE_TX1_DMIC_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX2_DMIC_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX3_DMIC_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX4_DMIC_CTL, 0x00}, +}; + +struct reg_default + msm89xx_pmic_cdc_defaults[MSM89XX_PMIC_CDC_CACHE_SIZE] = { + {MSM89XX_PMIC_DIGITAL_REVISION1, 0x00}, + {MSM89XX_PMIC_DIGITAL_REVISION2, 0x00}, + {MSM89XX_PMIC_DIGITAL_PERPH_TYPE, 0x23}, + {MSM89XX_PMIC_DIGITAL_PERPH_SUBTYPE, 0x01}, + {MSM89XX_PMIC_DIGITAL_INT_RT_STS, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_SET_TYPE, 0xFF}, + {MSM89XX_PMIC_DIGITAL_INT_POLARITY_HIGH, 0xFF}, + {MSM89XX_PMIC_DIGITAL_INT_POLARITY_LOW, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_LATCHED_CLR, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_EN_SET, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_EN_CLR, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_LATCHED_STS, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_PENDING_STS, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_MID_SEL, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_PRIORITY, 0x00}, + {MSM89XX_PMIC_DIGITAL_GPIO_MODE, 0x00}, + {MSM89XX_PMIC_DIGITAL_PIN_CTL_OE, 0x01}, + {MSM89XX_PMIC_DIGITAL_PIN_CTL_DATA, 0x00}, + {MSM89XX_PMIC_DIGITAL_PIN_STATUS, 0x00}, + {MSM89XX_PMIC_DIGITAL_HDRIVE_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL, 0x02}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL, 0x02}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_HPHR_DAC_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX1_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX2_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX3_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX_LB_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_RX_CTL1, 0x7C}, + {MSM89XX_PMIC_DIGITAL_CDC_RX_CTL2, 0x7C}, + {MSM89XX_PMIC_DIGITAL_CDC_RX_CTL3, 0x7C}, + {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA0, 0x00}, + {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA1, 0x00}, + {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA2, 0x00}, + {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA3, 0x00}, + {MSM89XX_PMIC_DIGITAL_DIG_DEBUG_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_DIG_DEBUG_EN, 0x00}, + {MSM89XX_PMIC_DIGITAL_SPARE_0, 0x00}, + {MSM89XX_PMIC_DIGITAL_SPARE_1, 0x00}, + {MSM89XX_PMIC_DIGITAL_SPARE_2, 0x00}, + {MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0x00}, + {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL1, 0x00}, + {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL2, 0x02}, + {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x05}, + {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_TEST1, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_TEST_VAL, 0x00}, + {MSM89XX_PMIC_DIGITAL_TRIM_NUM, 0x00}, + {MSM89XX_PMIC_DIGITAL_TRIM_CTRL, 0x00}, + {MSM89XX_PMIC_ANALOG_REVISION1, 0x00}, + {MSM89XX_PMIC_ANALOG_REVISION2, 0x00}, + {MSM89XX_PMIC_ANALOG_REVISION3, 0x00}, + {MSM89XX_PMIC_ANALOG_REVISION4, 0x00}, + {MSM89XX_PMIC_ANALOG_PERPH_TYPE, 0x23}, + {MSM89XX_PMIC_ANALOG_PERPH_SUBTYPE, 0x09}, + {MSM89XX_PMIC_ANALOG_INT_RT_STS, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_SET_TYPE, 0x3F}, + {MSM89XX_PMIC_ANALOG_INT_POLARITY_HIGH, 0x3F}, + {MSM89XX_PMIC_ANALOG_INT_POLARITY_LOW, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_LATCHED_CLR, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_EN_SET, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_EN_CLR, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_LATCHED_STS, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_PENDING_STS, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_MID_SEL, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_PRIORITY, 0x00}, + {MSM89XX_PMIC_ANALOG_MICB_1_EN, 0x00}, + {MSM89XX_PMIC_ANALOG_MICB_1_VAL, 0x20}, + {MSM89XX_PMIC_ANALOG_MICB_1_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS, 0x49}, + {MSM89XX_PMIC_ANALOG_MICB_2_EN, 0x20}, + {MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2, 0x00}, + {MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x35}, + {MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x08}, + {MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, 0x98}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL, 0x20}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL, 0x40}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN3_CTL, 0x61}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN4_CTL, 0x80}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT, 0x00}, + {MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x00}, + {MSM89XX_PMIC_ANALOG_TX_1_EN, 0x03}, + {MSM89XX_PMIC_ANALOG_TX_2_EN, 0x03}, + {MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_1, 0xBF}, + {MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_2, 0x8C}, + {MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x6B}, + {MSM89XX_PMIC_ANALOG_TX_1_2_TXFE_CLKDIV, 0x51}, + {MSM89XX_PMIC_ANALOG_TX_3_EN, 0x02}, + {MSM89XX_PMIC_ANALOG_NCP_EN, 0x26}, + {MSM89XX_PMIC_ANALOG_NCP_CLK, 0x23}, + {MSM89XX_PMIC_ANALOG_NCP_DEGLITCH, 0x5B}, + {MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0x08}, + {MSM89XX_PMIC_ANALOG_NCP_BIAS, 0x29}, + {MSM89XX_PMIC_ANALOG_NCP_VCTRL, 0x24}, + {MSM89XX_PMIC_ANALOG_NCP_TEST, 0x00}, + {MSM89XX_PMIC_ANALOG_NCP_CLIM_ADDR, 0xD5}, + {MSM89XX_PMIC_ANALOG_RX_CLOCK_DIVIDER, 0xE8}, + {MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL, 0xCF}, + {MSM89XX_PMIC_ANALOG_RX_COM_OCP_COUNT, 0x6E}, + {MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, 0x18}, + {MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA, 0x5A}, + {MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_LDO_OCP, 0x69}, + {MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_CNP, 0x29}, + {MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, 0x80}, + {MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_CTL, 0xDA}, + {MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME, 0x16}, + {MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x00}, + {MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x20}, + {MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x00}, + {MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x20}, + {MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x12}, + {MSM89XX_PMIC_ANALOG_RX_ATEST, 0x00}, + {MSM89XX_PMIC_ANALOG_RX_HPH_STATUS, 0x0C}, + {MSM89XX_PMIC_ANALOG_RX_EAR_STATUS, 0x00}, + {MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x83}, + {MSM89XX_PMIC_ANALOG_SPKR_DRV_CLIP_DET, 0x91}, + {MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x29}, + {MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET, 0x4D}, + {MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1}, + {MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0x1E}, + {MSM89XX_PMIC_ANALOG_SPKR_DRV_MISC, 0xCB}, + {MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x00}, + {MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x02}, + {MSM89XX_PMIC_ANALOG_OUTPUT_VOLTAGE, 0x14}, + {MSM89XX_PMIC_ANALOG_BYPASS_MODE, 0x00}, + {MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, 0x1F}, + {MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO, 0x8C}, + {MSM89XX_PMIC_ANALOG_RDSON_MAX_DUTY_CYCLE, 0xC0}, + {MSM89XX_PMIC_ANALOG_BOOST_TEST1_1, 0x00}, + {MSM89XX_PMIC_ANALOG_BOOST_TEST_2, 0x00}, + {MSM89XX_PMIC_ANALOG_SPKR_SAR_STATUS, 0x00}, + {MSM89XX_PMIC_ANALOG_SPKR_DRV_STATUS, 0x00}, + {MSM89XX_PMIC_ANALOG_PBUS_ADD_CSR, 0x00}, + {MSM89XX_PMIC_ANALOG_PBUS_ADD_SEL, 0x00}, + {MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0x00}, + {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL1, 0x00}, + {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL2, 0x01}, + {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x05}, + {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_TEST1, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_TEST_VAL, 0x00}, + {MSM89XX_PMIC_ANALOG_TRIM_NUM, 0x04}, + {MSM89XX_PMIC_ANALOG_TRIM_CTRL1, 0x00}, + {MSM89XX_PMIC_ANALOG_TRIM_CTRL2, 0x00}, + {MSM89XX_PMIC_ANALOG_TRIM_CTRL3, 0x00}, + {MSM89XX_PMIC_ANALOG_TRIM_CTRL4, 0x00}, +}; + +static const u8 msm89xx_cdc_core_reg_readable[MSM89XX_CDC_CORE_CACHE_SIZE] = { + [MSM89XX_CDC_CORE_CLK_RX_RESET_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_RX_I2S_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_TX_I2S_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_OTHR_RESET_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_OTHR_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_RX_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_MCLK_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_PDM_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_SD_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_RX_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_TX2_I2S_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B3_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B3_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B3_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B4_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B4_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B4_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B5_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B5_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B5_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B6_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B6_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B6_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_VOL_CTL_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_VOL_CTL_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_VOL_CTL_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL] = 1, + [MSM89XX_CDC_CORE_TOP_GAIN_UPDATE] = 1, + [MSM89XX_CDC_CORE_TOP_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B1_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B2_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B3_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B4_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B5_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B6_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_SHUT_DOWN_STATUS] = 1, + [MSM89XX_CDC_CORE_COMP0_FS_CFG] = 1, + [MSM89XX_CDC_CORE_COMP0_DELAY_BUF_CTL] = 1, + [MSM89XX_CDC_CORE_DEBUG_DESER1_CTL] = 1, + [MSM89XX_CDC_CORE_DEBUG_DESER2_CTL] = 1, + [MSM89XX_CDC_CORE_DEBUG_B1_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_DEBUG_B2_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_DEBUG_B3_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B2_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B3_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B4_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B5_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B5_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B6_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B6_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B7_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B7_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B8_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B8_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_TIMER_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_TIMER_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_COEF_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX1_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX1_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX1_B3_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX2_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX2_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX2_B3_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX3_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX3_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_TX_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_TX_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ1_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ1_B3_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ1_B4_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ2_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ2_B3_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ2_B4_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_TX_B3_CTL] = 1, + [MSM89XX_CDC_CORE_TX1_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX2_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX3_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX4_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX1_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX2_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX3_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX4_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX1_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX2_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX3_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX4_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX5_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX5_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX5_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX5_DMIC_CTL] = 1, + [MSM89XX_CDC_CORE_TX1_DMIC_CTL] = 1, + [MSM89XX_CDC_CORE_TX2_DMIC_CTL] = 1, + [MSM89XX_CDC_CORE_TX3_DMIC_CTL] = 1, + [MSM89XX_CDC_CORE_TX4_DMIC_CTL] = 1, +}; + +static const u8 msm89xx_cdc_core_reg_writeable[MSM89XX_CDC_CORE_CACHE_SIZE] = { + [MSM89XX_CDC_CORE_CLK_RX_RESET_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_RX_I2S_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_TX_I2S_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_OTHR_RESET_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_OTHR_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_RX_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_MCLK_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_PDM_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_SD_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_RX_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_TX2_I2S_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B3_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B3_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B3_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B4_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B4_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B4_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B5_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B5_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B5_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B6_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B6_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B6_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_VOL_CTL_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_VOL_CTL_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_VOL_CTL_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL] = 1, + [MSM89XX_CDC_CORE_TOP_GAIN_UPDATE] = 1, + [MSM89XX_CDC_CORE_TOP_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B1_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B2_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B3_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B4_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B5_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B6_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_FS_CFG] = 1, + [MSM89XX_CDC_CORE_COMP0_DELAY_BUF_CTL] = 1, + [MSM89XX_CDC_CORE_DEBUG_DESER1_CTL] = 1, + [MSM89XX_CDC_CORE_DEBUG_DESER2_CTL] = 1, + [MSM89XX_CDC_CORE_DEBUG_B1_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_DEBUG_B2_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_DEBUG_B3_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B2_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B3_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B4_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B5_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B5_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B6_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B6_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B7_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B7_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B8_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B8_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_TIMER_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_TIMER_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_COEF_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX1_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX1_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX1_B3_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX2_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX2_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX2_B3_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX3_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX3_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_TX_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_TX_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ1_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ1_B3_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ1_B4_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ2_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ2_B3_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ2_B4_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_TX_B3_CTL] = 1, + [MSM89XX_CDC_CORE_TX1_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX2_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX3_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX4_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX1_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX2_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX3_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX4_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX1_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX2_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX3_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX4_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX5_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX5_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX5_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX5_DMIC_CTL] = 1, + [MSM89XX_CDC_CORE_TX1_DMIC_CTL] = 1, + [MSM89XX_CDC_CORE_TX2_DMIC_CTL] = 1, + [MSM89XX_CDC_CORE_TX3_DMIC_CTL] = 1, + [MSM89XX_CDC_CORE_TX4_DMIC_CTL] = 1, +}; + +bool msm89xx_cdc_core_readable_reg(struct device *dev, unsigned int reg) +{ + return msm89xx_cdc_core_reg_readable[reg]; +} + +bool msm89xx_cdc_core_writeable_reg(struct device *dev, unsigned int reg) +{ + return msm89xx_cdc_core_reg_writeable[reg]; +} + +bool msm89xx_cdc_core_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MSM89XX_CDC_CORE_RX1_B1_CTL: + case MSM89XX_CDC_CORE_RX2_B1_CTL: + case MSM89XX_CDC_CORE_RX3_B1_CTL: + case MSM89XX_CDC_CORE_RX1_B6_CTL: + case MSM89XX_CDC_CORE_RX2_B6_CTL: + case MSM89XX_CDC_CORE_RX3_B6_CTL: + case MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG: + case MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG: + case MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG: + case MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG: + case MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG: + case MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL: + case MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL: + case MSM89XX_CDC_CORE_CLK_MCLK_CTL: + case MSM89XX_CDC_CORE_CLK_PDM_CTL: + return true; + default: + return false; + } +} diff --git a/sound/soc/codecs/wcd-dsp-mgr.c b/sound/soc/codecs/wcd-dsp-mgr.c new file mode 100644 index 000000000000..661db2b66324 --- /dev/null +++ b/sound/soc/codecs/wcd-dsp-mgr.c @@ -0,0 +1,1253 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcd-dsp-utils.h" + +/* Forward declarations */ +static char *wdsp_get_cmpnt_type_string(enum wdsp_cmpnt_type); + +/* Component related macros */ +#define WDSP_GET_COMPONENT(wdsp, x) (&(wdsp->cmpnts[x])) +#define WDSP_GET_CMPNT_TYPE_STR(x) wdsp_get_cmpnt_type_string(x) + +/* + * These #defines indicate the bit number in status field + * for each of the status. If bit is set, it indicates + * the status as done, else if bit is not set, it indicates + * the status is either failed or not done. + */ +#define WDSP_STATUS_INITIALIZED BIT(0) +#define WDSP_STATUS_CODE_DLOADED BIT(1) +#define WDSP_STATUS_DATA_DLOADED BIT(2) +#define WDSP_STATUS_BOOTED BIT(3) + +/* Helper macros for printing wdsp messages */ +#define WDSP_ERR(wdsp, fmt, ...) \ + dev_err(wdsp->mdev, "%s: " fmt "\n", __func__, ##__VA_ARGS__) +#define WDSP_DBG(wdsp, fmt, ...) \ + dev_dbg(wdsp->mdev, "%s: " fmt "\n", __func__, ##__VA_ARGS__) + +/* Helper macros for locking */ +#define WDSP_MGR_MUTEX_LOCK(wdsp, lock) \ +{ \ + WDSP_DBG(wdsp, "mutex_lock(%s)", \ + __stringify_1(lock)); \ + mutex_lock(&lock); \ +} + +#define WDSP_MGR_MUTEX_UNLOCK(wdsp, lock) \ +{ \ + WDSP_DBG(wdsp, "mutex_unlock(%s)", \ + __stringify_1(lock)); \ + mutex_unlock(&lock); \ +} + +/* Helper macros for using status mask */ +#define WDSP_SET_STATUS(wdsp, state) \ +{ \ + wdsp->status |= state; \ + WDSP_DBG(wdsp, "set 0x%lx, new_state = 0x%x", \ + state, wdsp->status); \ +} + +#define WDSP_CLEAR_STATUS(wdsp, state) \ +{ \ + wdsp->status &= (~state); \ + WDSP_DBG(wdsp, "clear 0x%lx, new_state = 0x%x", \ + state, wdsp->status); \ +} + +#define WDSP_STATUS_IS_SET(wdsp, state) (wdsp->status & state) + +/* SSR relate status macros */ +#define WDSP_SSR_STATUS_WDSP_READY BIT(0) +#define WDSP_SSR_STATUS_CDC_READY BIT(1) +#define WDSP_SSR_STATUS_READY \ + (WDSP_SSR_STATUS_WDSP_READY | WDSP_SSR_STATUS_CDC_READY) +#define WDSP_SSR_READY_WAIT_TIMEOUT (10 * HZ) + +enum wdsp_ssr_type { + + /* Init value, indicates there is no SSR in progress */ + WDSP_SSR_TYPE_NO_SSR = 0, + + /* + * Indicates WDSP crashed. The manager driver internally + * decides when to perform WDSP restart based on the + * users of wdsp. Hence there is no explicit WDSP_UP. + */ + WDSP_SSR_TYPE_WDSP_DOWN, + + /* Indicates codec hardware is down */ + WDSP_SSR_TYPE_CDC_DOWN, + + /* Indicates codec hardware is up, trigger to restart WDSP */ + WDSP_SSR_TYPE_CDC_UP, +}; + +struct wdsp_cmpnt { + + /* OF node of the phandle */ + struct device_node *np; + + /* + * Child component's dev_name, should be set in DT for the child's + * phandle if child's dev->of_node does not match the phandle->of_node + */ + const char *cdev_name; + + /* Child component's device node */ + struct device *cdev; + + /* Private data that component may want back on callbacks */ + void *priv_data; + + /* Child ops */ + struct wdsp_cmpnt_ops *ops; +}; + +struct wdsp_ramdump_data { + + /* Ramdump device */ + void *rd_dev; + + /* DMA address of the dump */ + dma_addr_t rd_addr; + + /* Virtual address of the dump */ + void *rd_v_addr; + + /* Data provided through error interrupt */ + struct wdsp_err_signal_arg err_data; +}; + +struct wdsp_mgr_priv { + + /* Manager driver's struct device pointer */ + struct device *mdev; + + /* Match struct for component framework */ + struct component_match *match; + + /* Manager's ops/function callbacks */ + struct wdsp_mgr_ops *ops; + + /* Array to store information for all expected components */ + struct wdsp_cmpnt cmpnts[WDSP_CMPNT_TYPE_MAX]; + + /* The filename of image to be downloaded */ + const char *img_fname; + + /* Keeps track of current state of manager driver */ + u32 status; + + /* Work to load the firmware image after component binding */ + struct work_struct load_fw_work; + + /* List of segments in image to be downloaded */ + struct list_head *seg_list; + + /* Base address of the image in memory */ + u32 base_addr; + + /* Instances using dsp */ + int dsp_users; + + /* Lock for serializing ops called by components */ + struct mutex api_mutex; + + struct wdsp_ramdump_data dump_data; + + /* SSR related */ + enum wdsp_ssr_type ssr_type; + struct mutex ssr_mutex; + struct work_struct ssr_work; + u16 ready_status; + struct completion ready_compl; + + /* Debugfs related */ + struct dentry *entry; + bool panic_on_error; +}; + +static char *wdsp_get_ssr_type_string(enum wdsp_ssr_type type) +{ + switch (type) { + case WDSP_SSR_TYPE_NO_SSR: + return "NO_SSR"; + case WDSP_SSR_TYPE_WDSP_DOWN: + return "WDSP_DOWN"; + case WDSP_SSR_TYPE_CDC_DOWN: + return "CDC_DOWN"; + case WDSP_SSR_TYPE_CDC_UP: + return "CDC_UP"; + default: + pr_err("%s: Invalid ssr_type %d\n", + __func__, type); + return "Invalid"; + } +} + +static char *wdsp_get_cmpnt_type_string(enum wdsp_cmpnt_type type) +{ + switch (type) { + case WDSP_CMPNT_CONTROL: + return "control"; + case WDSP_CMPNT_IPC: + return "ipc"; + case WDSP_CMPNT_TRANSPORT: + return "transport"; + default: + pr_err("%s: Invalid component type %d\n", + __func__, type); + return "Invalid"; + } +} + +static void __wdsp_clr_ready_locked(struct wdsp_mgr_priv *wdsp, + u16 value) +{ + wdsp->ready_status &= ~(value); + WDSP_DBG(wdsp, "ready_status = 0x%x", wdsp->ready_status); +} + +static void __wdsp_set_ready_locked(struct wdsp_mgr_priv *wdsp, + u16 value, bool mark_complete) +{ + wdsp->ready_status |= value; + WDSP_DBG(wdsp, "ready_status = 0x%x", wdsp->ready_status); + + if (mark_complete && + wdsp->ready_status == WDSP_SSR_STATUS_READY) { + WDSP_DBG(wdsp, "marking ready completion"); + complete(&wdsp->ready_compl); + } +} + +static void wdsp_broadcast_event_upseq(struct wdsp_mgr_priv *wdsp, + enum wdsp_event_type event, + void *data) +{ + struct wdsp_cmpnt *cmpnt; + int i; + + for (i = 0; i < WDSP_CMPNT_TYPE_MAX; i++) { + cmpnt = WDSP_GET_COMPONENT(wdsp, i); + if (cmpnt && cmpnt->ops && cmpnt->ops->event_handler) + cmpnt->ops->event_handler(cmpnt->cdev, cmpnt->priv_data, + event, data); + } +} + +static void wdsp_broadcast_event_downseq(struct wdsp_mgr_priv *wdsp, + enum wdsp_event_type event, + void *data) +{ + struct wdsp_cmpnt *cmpnt; + int i; + + for (i = WDSP_CMPNT_TYPE_MAX - 1; i >= 0; i--) { + cmpnt = WDSP_GET_COMPONENT(wdsp, i); + if (cmpnt && cmpnt->ops && cmpnt->ops->event_handler) + cmpnt->ops->event_handler(cmpnt->cdev, cmpnt->priv_data, + event, data); + } +} + +static int wdsp_unicast_event(struct wdsp_mgr_priv *wdsp, + enum wdsp_cmpnt_type type, + enum wdsp_event_type event, + void *data) +{ + struct wdsp_cmpnt *cmpnt; + int ret; + + cmpnt = WDSP_GET_COMPONENT(wdsp, type); + if (cmpnt && cmpnt->ops && cmpnt->ops->event_handler) { + ret = cmpnt->ops->event_handler(cmpnt->cdev, cmpnt->priv_data, + event, data); + } else { + WDSP_ERR(wdsp, "not valid event_handler for %s", + WDSP_GET_CMPNT_TYPE_STR(type)); + ret = -EINVAL; + } + + return ret; +} + +static void wdsp_deinit_components(struct wdsp_mgr_priv *wdsp) +{ + struct wdsp_cmpnt *cmpnt; + int i; + + for (i = WDSP_CMPNT_TYPE_MAX - 1; i >= 0; i--) { + cmpnt = WDSP_GET_COMPONENT(wdsp, i); + if (cmpnt && cmpnt->ops && cmpnt->ops->deinit) + cmpnt->ops->deinit(cmpnt->cdev, cmpnt->priv_data); + } +} + +static int wdsp_init_components(struct wdsp_mgr_priv *wdsp) +{ + struct wdsp_cmpnt *cmpnt; + int fail_idx = WDSP_CMPNT_TYPE_MAX; + int i, ret = 0; + + for (i = 0; i < WDSP_CMPNT_TYPE_MAX; i++) { + + cmpnt = WDSP_GET_COMPONENT(wdsp, i); + + /* Init is allowed to be NULL */ + if (!cmpnt->ops || !cmpnt->ops->init) + continue; + ret = cmpnt->ops->init(cmpnt->cdev, cmpnt->priv_data); + if (ret) { + WDSP_ERR(wdsp, "Init failed (%d) for component %s", + ret, WDSP_GET_CMPNT_TYPE_STR(i)); + fail_idx = i; + break; + } + } + + if (fail_idx < WDSP_CMPNT_TYPE_MAX) { + /* Undo init for already initialized components */ + for (i = fail_idx - 1; i >= 0; i--) { + struct wdsp_cmpnt *cmpnt = WDSP_GET_COMPONENT(wdsp, i); + + if (cmpnt->ops && cmpnt->ops->deinit) + cmpnt->ops->deinit(cmpnt->cdev, + cmpnt->priv_data); + } + } else { + wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_POST_INIT, NULL); + } + + return ret; +} + +static int wdsp_load_each_segment(struct wdsp_mgr_priv *wdsp, + struct wdsp_img_segment *seg) +{ + struct wdsp_img_section img_section; + int ret; + + WDSP_DBG(wdsp, + "base_addr 0x%x, split_fname %s, load_addr 0x%x, size 0x%zx", + wdsp->base_addr, seg->split_fname, seg->load_addr, seg->size); + + if (seg->load_addr < wdsp->base_addr) { + WDSP_ERR(wdsp, "Invalid addr 0x%x, base_addr = 0x%x", + seg->load_addr, wdsp->base_addr); + return -EINVAL; + } + + img_section.addr = seg->load_addr - wdsp->base_addr; + img_section.size = seg->size; + img_section.data = seg->data; + + ret = wdsp_unicast_event(wdsp, WDSP_CMPNT_TRANSPORT, + WDSP_EVENT_DLOAD_SECTION, + &img_section); + if (ret < 0) + WDSP_ERR(wdsp, + "Failed, err = %d for base_addr = 0x%x split_fname = %s, load_addr = 0x%x, size = 0x%zx", + ret, wdsp->base_addr, seg->split_fname, + seg->load_addr, seg->size); + return ret; +} + +static int wdsp_download_segments(struct wdsp_mgr_priv *wdsp, + unsigned int type) +{ + struct wdsp_cmpnt *ctl; + struct wdsp_img_segment *seg = NULL; + enum wdsp_event_type pre, post; + long status; + int ret; + + ctl = WDSP_GET_COMPONENT(wdsp, WDSP_CMPNT_CONTROL); + + if (type == WDSP_ELF_FLAG_RE) { + pre = WDSP_EVENT_PRE_DLOAD_CODE; + post = WDSP_EVENT_POST_DLOAD_CODE; + status = WDSP_STATUS_CODE_DLOADED; + } else if (type == WDSP_ELF_FLAG_WRITE) { + pre = WDSP_EVENT_PRE_DLOAD_DATA; + post = WDSP_EVENT_POST_DLOAD_DATA; + status = WDSP_STATUS_DATA_DLOADED; + } else { + WDSP_ERR(wdsp, "Invalid type %u", type); + return -EINVAL; + } + + ret = wdsp_get_segment_list(ctl->cdev, wdsp->img_fname, + type, wdsp->seg_list, &wdsp->base_addr); + if (ret < 0 || + list_empty(wdsp->seg_list)) { + WDSP_ERR(wdsp, "Error %d to get image segments for type %d", + ret, type); + wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_DLOAD_FAILED, + NULL); + goto done; + } + + /* Notify all components that image is about to be downloaded */ + wdsp_broadcast_event_upseq(wdsp, pre, NULL); + + /* Go through the list of segments and download one by one */ + list_for_each_entry(seg, wdsp->seg_list, list) { + ret = wdsp_load_each_segment(wdsp, seg); + if (ret < 0) { + wdsp_broadcast_event_downseq(wdsp, + WDSP_EVENT_DLOAD_FAILED, + NULL); + goto dload_error; + } + } + + WDSP_SET_STATUS(wdsp, status); + + /* Notify all components that image is downloaded */ + wdsp_broadcast_event_downseq(wdsp, post, NULL); + +dload_error: + wdsp_flush_segment_list(wdsp->seg_list); +done: + return ret; +} + +static int wdsp_init_and_dload_code_sections(struct wdsp_mgr_priv *wdsp) +{ + int ret; + bool is_initialized; + + is_initialized = WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_INITIALIZED); + + if (!is_initialized) { + /* Components are not initialized yet, initialize them */ + ret = wdsp_init_components(wdsp); + if (ret < 0) { + WDSP_ERR(wdsp, "INIT failed, err = %d", ret); + goto done; + } + WDSP_SET_STATUS(wdsp, WDSP_STATUS_INITIALIZED); + } + + /* Download the read-execute sections of image */ + ret = wdsp_download_segments(wdsp, WDSP_ELF_FLAG_RE); + if (ret < 0) { + WDSP_ERR(wdsp, "Error %d to download code sections", ret); + goto done; + } +done: + return ret; +} + +static void wdsp_load_fw_image(struct work_struct *work) +{ + struct wdsp_mgr_priv *wdsp; + int ret; + + wdsp = container_of(work, struct wdsp_mgr_priv, load_fw_work); + if (!wdsp) { + pr_err("%s: Invalid private_data\n", __func__); + return; + } + + ret = wdsp_init_and_dload_code_sections(wdsp); + if (ret < 0) + WDSP_ERR(wdsp, "dload code sections failed, err = %d", ret); +} + +static int wdsp_enable_dsp(struct wdsp_mgr_priv *wdsp) +{ + int ret; + + /* Make sure wdsp is in good state */ + if (!WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_CODE_DLOADED)) { + WDSP_ERR(wdsp, "WDSP in invalid state 0x%x", wdsp->status); + ret = -EINVAL; + goto done; + } + + /* Download the read-write sections of image */ + ret = wdsp_download_segments(wdsp, WDSP_ELF_FLAG_WRITE); + if (ret < 0) { + WDSP_ERR(wdsp, "Data section download failed, err = %d", ret); + goto done; + } + + wdsp_broadcast_event_upseq(wdsp, WDSP_EVENT_PRE_BOOTUP, NULL); + + ret = wdsp_unicast_event(wdsp, WDSP_CMPNT_CONTROL, + WDSP_EVENT_DO_BOOT, NULL); + if (ret < 0) { + WDSP_ERR(wdsp, "Failed to boot dsp, err = %d", ret); + WDSP_CLEAR_STATUS(wdsp, WDSP_STATUS_DATA_DLOADED); + goto done; + } + + wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_POST_BOOTUP, NULL); + WDSP_SET_STATUS(wdsp, WDSP_STATUS_BOOTED); +done: + return ret; +} + +static int wdsp_disable_dsp(struct wdsp_mgr_priv *wdsp) +{ + int ret; + + WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex); + + /* + * If Disable happened while SSR is in progress, then set the SSR + * ready status indicating WDSP is now ready. Ignore the disable + * event here and let the SSR handler go through shutdown. + */ + if (wdsp->ssr_type != WDSP_SSR_TYPE_NO_SSR) { + __wdsp_set_ready_locked(wdsp, WDSP_SSR_STATUS_WDSP_READY, true); + WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex); + return 0; + } + + WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex); + + /* Make sure wdsp is in good state */ + if (!WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_BOOTED)) { + WDSP_ERR(wdsp, "wdsp in invalid state 0x%x", wdsp->status); + ret = -EINVAL; + goto done; + } + + wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_PRE_SHUTDOWN, NULL); + ret = wdsp_unicast_event(wdsp, WDSP_CMPNT_CONTROL, + WDSP_EVENT_DO_SHUTDOWN, NULL); + if (ret < 0) { + WDSP_ERR(wdsp, "Failed to shutdown dsp, err = %d", ret); + goto done; + } + + wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_POST_SHUTDOWN, NULL); + WDSP_CLEAR_STATUS(wdsp, WDSP_STATUS_BOOTED); + + /* Data sections are to be downloaded per boot */ + WDSP_CLEAR_STATUS(wdsp, WDSP_STATUS_DATA_DLOADED); +done: + return ret; +} + +static int wdsp_register_cmpnt_ops(struct device *wdsp_dev, + struct device *cdev, + void *priv_data, + struct wdsp_cmpnt_ops *ops) +{ + struct wdsp_mgr_priv *wdsp; + struct wdsp_cmpnt *cmpnt; + int i, ret; + + if (!wdsp_dev || !cdev || !ops) + return -EINVAL; + + wdsp = dev_get_drvdata(wdsp_dev); + + WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->api_mutex); + + for (i = 0; i < WDSP_CMPNT_TYPE_MAX; i++) { + cmpnt = WDSP_GET_COMPONENT(wdsp, i); + if ((cdev->of_node && cdev->of_node == cmpnt->np) || + (cmpnt->cdev_name && + !strcmp(dev_name(cdev), cmpnt->cdev_name))) { + break; + } + } + + if (i == WDSP_CMPNT_TYPE_MAX) { + WDSP_ERR(wdsp, "Failed to register component dev %s", + dev_name(cdev)); + ret = -EINVAL; + goto done; + } + + cmpnt->cdev = cdev; + cmpnt->ops = ops; + cmpnt->priv_data = priv_data; +done: + WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->api_mutex); + return 0; +} + +static struct device *wdsp_get_dev_for_cmpnt(struct device *wdsp_dev, + enum wdsp_cmpnt_type type) +{ + struct wdsp_mgr_priv *wdsp; + struct wdsp_cmpnt *cmpnt; + + if (!wdsp_dev || type >= WDSP_CMPNT_TYPE_MAX) + return NULL; + + wdsp = dev_get_drvdata(wdsp_dev); + cmpnt = WDSP_GET_COMPONENT(wdsp, type); + + return cmpnt->cdev; +} + +static int wdsp_get_devops_for_cmpnt(struct device *wdsp_dev, + enum wdsp_cmpnt_type type, + void *data) +{ + struct wdsp_mgr_priv *wdsp; + int ret = 0; + + if (!wdsp_dev || type >= WDSP_CMPNT_TYPE_MAX) + return -EINVAL; + + wdsp = dev_get_drvdata(wdsp_dev); + ret = wdsp_unicast_event(wdsp, type, + WDSP_EVENT_GET_DEVOPS, data); + if (ret) + WDSP_ERR(wdsp, "get_dev_ops failed for cmpnt type %d", + type); + return ret; +} + +static void wdsp_collect_ramdumps(struct wdsp_mgr_priv *wdsp) +{ + struct wdsp_img_section img_section; + struct wdsp_err_signal_arg *data = &wdsp->dump_data.err_data; + struct ramdump_segment rd_seg; + int ret = 0; + + if (wdsp->ssr_type != WDSP_SSR_TYPE_WDSP_DOWN || + !data->mem_dumps_enabled) { + WDSP_DBG(wdsp, "cannot dump memory, ssr_type %s, dumps %s", + wdsp_get_ssr_type_string(wdsp->ssr_type), + !(data->mem_dumps_enabled) ? "disabled" : "enabled"); + goto done; + } + + if (data->dump_size == 0 || + data->remote_start_addr < wdsp->base_addr) { + WDSP_ERR(wdsp, "Invalid start addr 0x%x or dump_size 0x%zx", + data->remote_start_addr, data->dump_size); + goto done; + } + + if (!wdsp->dump_data.rd_dev) { + WDSP_ERR(wdsp, "Ramdump device is not setup"); + goto done; + } + + WDSP_DBG(wdsp, "base_addr 0x%x, dump_start_addr 0x%x, dump_size 0x%zx", + wdsp->base_addr, data->remote_start_addr, data->dump_size); + + /* Allocate memory for dumps */ + wdsp->dump_data.rd_v_addr = dma_alloc_coherent(wdsp->mdev, + data->dump_size, + &wdsp->dump_data.rd_addr, + GFP_KERNEL); + if (!wdsp->dump_data.rd_v_addr) + goto done; + + img_section.addr = data->remote_start_addr - wdsp->base_addr; + img_section.size = data->dump_size; + img_section.data = wdsp->dump_data.rd_v_addr; + + ret = wdsp_unicast_event(wdsp, WDSP_CMPNT_TRANSPORT, + WDSP_EVENT_READ_SECTION, + &img_section); + if (ret < 0) { + WDSP_ERR(wdsp, "Failed to read dumps, size 0x%zx at addr 0x%x", + img_section.size, img_section.addr); + goto err_read_dumps; + } + + /* + * If panic_on_error flag is explicitly set through the debugfs, + * then cause a BUG here to aid debugging. + */ + BUG_ON(wdsp->panic_on_error); + + rd_seg.address = (unsigned long) wdsp->dump_data.rd_v_addr; + rd_seg.size = img_section.size; + rd_seg.v_address = wdsp->dump_data.rd_v_addr; + + ret = do_ramdump(wdsp->dump_data.rd_dev, &rd_seg, 1); + if (ret < 0) + WDSP_ERR(wdsp, "do_ramdump failed with error %d", ret); + +err_read_dumps: + dma_free_coherent(wdsp->mdev, data->dump_size, + wdsp->dump_data.rd_v_addr, wdsp->dump_data.rd_addr); +done: + return; +} + +static void wdsp_ssr_work_fn(struct work_struct *work) +{ + struct wdsp_mgr_priv *wdsp; + int ret; + + wdsp = container_of(work, struct wdsp_mgr_priv, ssr_work); + if (!wdsp) { + pr_err("%s: Invalid private_data\n", __func__); + return; + } + + WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex); + + /* Issue ramdumps and shutdown only if DSP is currently booted */ + if (WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_BOOTED)) { + wdsp_collect_ramdumps(wdsp); + ret = wdsp_unicast_event(wdsp, WDSP_CMPNT_CONTROL, + WDSP_EVENT_DO_SHUTDOWN, NULL); + if (ret < 0) + WDSP_ERR(wdsp, "Failed WDSP shutdown, err = %d", ret); + + wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_POST_SHUTDOWN, + NULL); + WDSP_CLEAR_STATUS(wdsp, WDSP_STATUS_BOOTED); + } + + WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex); + ret = wait_for_completion_timeout(&wdsp->ready_compl, + WDSP_SSR_READY_WAIT_TIMEOUT); + WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex); + if (ret == 0) { + WDSP_ERR(wdsp, "wait_for_ready timed out, status = 0x%x", + wdsp->ready_status); + goto done; + } + + /* Data sections are to downloaded per WDSP boot */ + WDSP_CLEAR_STATUS(wdsp, WDSP_STATUS_DATA_DLOADED); + + /* + * Even though code section could possible be retained on DSP + * crash, go ahead and still re-download just to avoid any + * memory corruption from previous crash. + */ + WDSP_CLEAR_STATUS(wdsp, WDSP_STATUS_CODE_DLOADED); + + /* If codec restarted, then all components must be re-initialized */ + if (wdsp->ssr_type == WDSP_SSR_TYPE_CDC_UP) { + wdsp_deinit_components(wdsp); + WDSP_CLEAR_STATUS(wdsp, WDSP_STATUS_INITIALIZED); + } + + ret = wdsp_init_and_dload_code_sections(wdsp); + if (ret < 0) { + WDSP_ERR(wdsp, "Failed to dload code sections err = %d", + ret); + goto done; + } + + /* SSR handling is finished, mark SSR type as NO_SSR */ + wdsp->ssr_type = WDSP_SSR_TYPE_NO_SSR; +done: + WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex); +} + +static int wdsp_ssr_handler(struct wdsp_mgr_priv *wdsp, void *arg, + enum wdsp_ssr_type ssr_type) +{ + enum wdsp_ssr_type current_ssr_type; + struct wdsp_err_signal_arg *err_data; + + WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex); + + current_ssr_type = wdsp->ssr_type; + WDSP_DBG(wdsp, "Current ssr_type %s, handling ssr_type %s", + wdsp_get_ssr_type_string(current_ssr_type), + wdsp_get_ssr_type_string(ssr_type)); + wdsp->ssr_type = ssr_type; + + if (arg) { + err_data = (struct wdsp_err_signal_arg *) arg; + memcpy(&wdsp->dump_data.err_data, err_data, + sizeof(*err_data)); + } else { + memset(&wdsp->dump_data.err_data, 0, + sizeof(wdsp->dump_data.err_data)); + } + + switch (ssr_type) { + + case WDSP_SSR_TYPE_WDSP_DOWN: + __wdsp_clr_ready_locked(wdsp, WDSP_SSR_STATUS_WDSP_READY); + wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_PRE_SHUTDOWN, + NULL); + schedule_work(&wdsp->ssr_work); + break; + + case WDSP_SSR_TYPE_CDC_DOWN: + __wdsp_clr_ready_locked(wdsp, WDSP_SSR_STATUS_CDC_READY); + /* + * If DSP is booted when CDC_DOWN is received, it needs + * to be shutdown. + */ + if (WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_BOOTED)) { + __wdsp_clr_ready_locked(wdsp, + WDSP_SSR_STATUS_WDSP_READY); + wdsp_broadcast_event_downseq(wdsp, + WDSP_EVENT_PRE_SHUTDOWN, + NULL); + } + + schedule_work(&wdsp->ssr_work); + break; + + case WDSP_SSR_TYPE_CDC_UP: + __wdsp_set_ready_locked(wdsp, WDSP_SSR_STATUS_CDC_READY, true); + break; + + default: + WDSP_ERR(wdsp, "undefined ssr_type %d\n", ssr_type); + /* Revert back the ssr_type for undefined events */ + wdsp->ssr_type = current_ssr_type; + break; + } + + WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex); + + return 0; +} + +static int wdsp_signal_handler(struct device *wdsp_dev, + enum wdsp_signal signal, void *arg) +{ + struct wdsp_mgr_priv *wdsp; + int ret; + + if (!wdsp_dev) + return -EINVAL; + + wdsp = dev_get_drvdata(wdsp_dev); + WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->api_mutex); + + WDSP_DBG(wdsp, "Raised signal %d", signal); + + switch (signal) { + case WDSP_IPC1_INTR: + ret = wdsp_unicast_event(wdsp, WDSP_CMPNT_IPC, + WDSP_EVENT_IPC1_INTR, NULL); + break; + case WDSP_ERR_INTR: + ret = wdsp_ssr_handler(wdsp, arg, WDSP_SSR_TYPE_WDSP_DOWN); + break; + case WDSP_CDC_DOWN_SIGNAL: + ret = wdsp_ssr_handler(wdsp, arg, WDSP_SSR_TYPE_CDC_DOWN); + break; + case WDSP_CDC_UP_SIGNAL: + ret = wdsp_ssr_handler(wdsp, arg, WDSP_SSR_TYPE_CDC_UP); + break; + default: + ret = -EINVAL; + break; + } + + if (ret < 0) + WDSP_ERR(wdsp, "handling signal %d failed with error %d", + signal, ret); + WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->api_mutex); + + return ret; +} + +static int wdsp_vote_for_dsp(struct device *wdsp_dev, + bool vote) +{ + struct wdsp_mgr_priv *wdsp; + int ret = 0; + + if (!wdsp_dev) + return -EINVAL; + + wdsp = dev_get_drvdata(wdsp_dev); + + WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->api_mutex); + WDSP_DBG(wdsp, "request %s, current users = %d", + vote ? "enable" : "disable", wdsp->dsp_users); + + if (vote) { + wdsp->dsp_users++; + if (wdsp->dsp_users == 1) + ret = wdsp_enable_dsp(wdsp); + } else { + if (wdsp->dsp_users == 0) + goto done; + + wdsp->dsp_users--; + if (wdsp->dsp_users == 0) + ret = wdsp_disable_dsp(wdsp); + } + + if (ret < 0) + WDSP_DBG(wdsp, "wdsp %s failed, err = %d", + vote ? "enable" : "disable", ret); + +done: + WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->api_mutex); + return ret; +} + +static int wdsp_suspend(struct device *wdsp_dev) +{ + struct wdsp_mgr_priv *wdsp; + int rc = 0, i; + + if (!wdsp_dev) { + pr_err("%s: Invalid handle to device\n", __func__); + return -EINVAL; + } + + wdsp = dev_get_drvdata(wdsp_dev); + + for (i = WDSP_CMPNT_TYPE_MAX - 1; i >= 0; i--) { + rc = wdsp_unicast_event(wdsp, i, WDSP_EVENT_SUSPEND, NULL); + if (rc < 0) { + WDSP_ERR(wdsp, "component %s failed to suspend\n", + WDSP_GET_CMPNT_TYPE_STR(i)); + break; + } + } + + return rc; +} + +static int wdsp_resume(struct device *wdsp_dev) +{ + struct wdsp_mgr_priv *wdsp; + int rc = 0, i; + + if (!wdsp_dev) { + pr_err("%s: Invalid handle to device\n", __func__); + return -EINVAL; + } + + wdsp = dev_get_drvdata(wdsp_dev); + + for (i = 0; i < WDSP_CMPNT_TYPE_MAX; i++) { + rc = wdsp_unicast_event(wdsp, i, WDSP_EVENT_RESUME, NULL); + if (rc < 0) { + WDSP_ERR(wdsp, "component %s failed to resume\n", + WDSP_GET_CMPNT_TYPE_STR(i)); + break; + } + } + + return rc; +} + +static struct wdsp_mgr_ops wdsp_ops = { + .register_cmpnt_ops = wdsp_register_cmpnt_ops, + .get_dev_for_cmpnt = wdsp_get_dev_for_cmpnt, + .get_devops_for_cmpnt = wdsp_get_devops_for_cmpnt, + .signal_handler = wdsp_signal_handler, + .vote_for_dsp = wdsp_vote_for_dsp, + .suspend = wdsp_suspend, + .resume = wdsp_resume, +}; + +static int wdsp_mgr_compare_of(struct device *dev, void *data) +{ + struct wdsp_cmpnt *cmpnt = data; + + /* + * First try to match based on of_node, if of_node is not + * present, try to match on the dev_name + */ + return ((dev->of_node && dev->of_node == cmpnt->np) || + (cmpnt->cdev_name && + !strcmp(dev_name(dev), cmpnt->cdev_name))); +} + +static void wdsp_mgr_debugfs_init(struct wdsp_mgr_priv *wdsp) +{ + wdsp->entry = debugfs_create_dir("wdsp_mgr", NULL); + if (IS_ERR_OR_NULL(wdsp->entry)) + return; + + debugfs_create_bool("panic_on_error", 0644, + wdsp->entry, &wdsp->panic_on_error); +} + +static void wdsp_mgr_debugfs_remove(struct wdsp_mgr_priv *wdsp) +{ + debugfs_remove_recursive(wdsp->entry); + wdsp->entry = NULL; +} + +static int wdsp_mgr_bind(struct device *dev) +{ + struct wdsp_mgr_priv *wdsp = dev_get_drvdata(dev); + struct wdsp_cmpnt *cmpnt; + int ret, idx; + + wdsp->ops = &wdsp_ops; + + /* Setup ramdump device */ + wdsp->dump_data.rd_dev = create_ramdump_device("wdsp", dev); + if (!wdsp->dump_data.rd_dev) + dev_info(dev, "%s: create_ramdump_device failed\n", __func__); + + ret = component_bind_all(dev, wdsp->ops); + if (ret < 0) + WDSP_ERR(wdsp, "component_bind_all failed %d\n", ret); + + /* Make sure all components registered ops */ + for (idx = 0; idx < WDSP_CMPNT_TYPE_MAX; idx++) { + cmpnt = WDSP_GET_COMPONENT(wdsp, idx); + if (!cmpnt->cdev || !cmpnt->ops) { + WDSP_ERR(wdsp, "%s did not register ops\n", + WDSP_GET_CMPNT_TYPE_STR(idx)); + ret = -EINVAL; + component_unbind_all(dev, wdsp->ops); + break; + } + } + + wdsp_mgr_debugfs_init(wdsp); + + /* Schedule the work to download image if binding was successful. */ + if (!ret) + schedule_work(&wdsp->load_fw_work); + + return ret; +} + +static void wdsp_mgr_unbind(struct device *dev) +{ + struct wdsp_mgr_priv *wdsp = dev_get_drvdata(dev); + struct wdsp_cmpnt *cmpnt; + int idx; + + component_unbind_all(dev, wdsp->ops); + + wdsp_mgr_debugfs_remove(wdsp); + + if (wdsp->dump_data.rd_dev) { + destroy_ramdump_device(wdsp->dump_data.rd_dev); + wdsp->dump_data.rd_dev = NULL; + } + + /* Clear all status bits */ + wdsp->status = 0x00; + + /* clean up the components */ + for (idx = 0; idx < WDSP_CMPNT_TYPE_MAX; idx++) { + cmpnt = WDSP_GET_COMPONENT(wdsp, idx); + cmpnt->cdev = NULL; + cmpnt->ops = NULL; + cmpnt->priv_data = NULL; + } +} + +static const struct component_master_ops wdsp_master_ops = { + .bind = wdsp_mgr_bind, + .unbind = wdsp_mgr_unbind, +}; + +static void *wdsp_mgr_parse_phandle(struct wdsp_mgr_priv *wdsp, + int index) +{ + struct device *mdev = wdsp->mdev; + struct device_node *np; + struct wdsp_cmpnt *cmpnt = NULL; + struct of_phandle_args pargs; + u32 value; + int ret; + + ret = of_parse_phandle_with_fixed_args(mdev->of_node, + "qcom,wdsp-components", 1, + index, &pargs); + if (ret) { + WDSP_ERR(wdsp, "parse_phandle at index %d failed %d", + index, ret); + return NULL; + } + + np = pargs.np; + value = pargs.args[0]; + + if (value >= WDSP_CMPNT_TYPE_MAX) { + WDSP_ERR(wdsp, "invalid phandle_arg to of_node %s", np->name); + goto done; + } + + cmpnt = WDSP_GET_COMPONENT(wdsp, value); + if (cmpnt->np || cmpnt->cdev_name) { + WDSP_ERR(wdsp, "cmpnt %d already added", value); + cmpnt = NULL; + goto done; + } + + cmpnt->np = np; + of_property_read_string(np, "qcom,wdsp-cmpnt-dev-name", + &cmpnt->cdev_name); +done: + of_node_put(np); + return cmpnt; +} + +static int wdsp_mgr_parse_dt_entries(struct wdsp_mgr_priv *wdsp) +{ + struct device *dev = wdsp->mdev; + void *match_data; + int ph_idx, ret; + + ret = of_property_read_string(dev->of_node, "qcom,img-filename", + &wdsp->img_fname); + if (ret < 0) { + WDSP_ERR(wdsp, "Reading property %s failed, error = %d", + "qcom,img-filename", ret); + return ret; + } + + ret = of_count_phandle_with_args(dev->of_node, + "qcom,wdsp-components", + NULL); + if (ret == -ENOENT) { + WDSP_ERR(wdsp, "Property %s not defined in DT", + "qcom,wdsp-components"); + goto done; + } else if (ret != WDSP_CMPNT_TYPE_MAX * 2) { + WDSP_ERR(wdsp, "Invalid phandle + arg count %d, expected %d", + ret, WDSP_CMPNT_TYPE_MAX * 2); + ret = -EINVAL; + goto done; + } + + ret = 0; + + for (ph_idx = 0; ph_idx < WDSP_CMPNT_TYPE_MAX; ph_idx++) { + + match_data = wdsp_mgr_parse_phandle(wdsp, ph_idx); + if (!match_data) { + WDSP_ERR(wdsp, "component not found at idx %d", ph_idx); + ret = -EINVAL; + goto done; + } + + component_match_add(dev, &wdsp->match, + wdsp_mgr_compare_of, match_data); + } + +done: + return ret; +} + +static int wdsp_mgr_probe(struct platform_device *pdev) +{ + struct wdsp_mgr_priv *wdsp; + struct device *mdev = &pdev->dev; + int ret; + + wdsp = devm_kzalloc(mdev, sizeof(*wdsp), GFP_KERNEL); + if (!wdsp) + return -ENOMEM; + wdsp->mdev = mdev; + wdsp->seg_list = devm_kzalloc(mdev, sizeof(struct list_head), + GFP_KERNEL); + if (!wdsp->seg_list) { + devm_kfree(mdev, wdsp); + return -ENOMEM; + } + + ret = wdsp_mgr_parse_dt_entries(wdsp); + if (ret) + goto err_dt_parse; + + INIT_WORK(&wdsp->load_fw_work, wdsp_load_fw_image); + INIT_LIST_HEAD(wdsp->seg_list); + mutex_init(&wdsp->api_mutex); + mutex_init(&wdsp->ssr_mutex); + wdsp->ssr_type = WDSP_SSR_TYPE_NO_SSR; + wdsp->ready_status = WDSP_SSR_STATUS_READY; + INIT_WORK(&wdsp->ssr_work, wdsp_ssr_work_fn); + init_completion(&wdsp->ready_compl); + arch_setup_dma_ops(wdsp->mdev, 0, 0, NULL, 0); + dev_set_drvdata(mdev, wdsp); + + ret = component_master_add_with_match(mdev, &wdsp_master_ops, + wdsp->match); + if (ret < 0) { + WDSP_ERR(wdsp, "Failed to add master, err = %d", ret); + goto err_master_add; + } + + return 0; + +err_master_add: + mutex_destroy(&wdsp->api_mutex); + mutex_destroy(&wdsp->ssr_mutex); +err_dt_parse: + devm_kfree(mdev, wdsp->seg_list); + devm_kfree(mdev, wdsp); + dev_set_drvdata(mdev, NULL); + + return ret; +} + +static int wdsp_mgr_remove(struct platform_device *pdev) +{ + struct device *mdev = &pdev->dev; + struct wdsp_mgr_priv *wdsp = dev_get_drvdata(mdev); + + component_master_del(mdev, &wdsp_master_ops); + + mutex_destroy(&wdsp->api_mutex); + mutex_destroy(&wdsp->ssr_mutex); + devm_kfree(mdev, wdsp->seg_list); + devm_kfree(mdev, wdsp); + dev_set_drvdata(mdev, NULL); + + return 0; +}; + +static const struct of_device_id wdsp_mgr_dt_match[] = { + {.compatible = "qcom,wcd-dsp-mgr" }, + { } +}; + +static struct platform_driver wdsp_mgr_driver = { + .driver = { + .name = "wcd-dsp-mgr", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(wdsp_mgr_dt_match), + }, + .probe = wdsp_mgr_probe, + .remove = wdsp_mgr_remove, +}; + +int wcd_dsp_mgr_init(void) +{ + return platform_driver_register(&wdsp_mgr_driver); +} + +void wcd_dsp_mgr_exit(void) +{ + platform_driver_unregister(&wdsp_mgr_driver); +} + +MODULE_DESCRIPTION("WCD DSP manager driver"); +MODULE_DEVICE_TABLE(of, wdsp_mgr_dt_match); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/wcd-dsp-utils.c b/sound/soc/codecs/wcd-dsp-utils.c new file mode 100644 index 000000000000..4eafd55894c5 --- /dev/null +++ b/sound/soc/codecs/wcd-dsp-utils.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include "wcd-dsp-utils.h" + +static bool wdsp_is_valid_elf_hdr(const struct elf32_hdr *ehdr, + size_t fw_size) +{ + if (fw_size < sizeof(*ehdr)) { + pr_err("%s: Firmware too small\n", __func__); + goto elf_check_fail; + } + + if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) { + pr_err("%s: Not an ELF file\n", __func__); + goto elf_check_fail; + } + + if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) { + pr_err("%s: Not an executable image\n", __func__); + goto elf_check_fail; + } + + if (ehdr->e_phnum == 0) { + pr_err("%s: no segments to load\n", __func__); + goto elf_check_fail; + } + + if (sizeof(struct elf32_phdr) * ehdr->e_phnum + + sizeof(struct elf32_hdr) > fw_size) { + pr_err("%s: Too small MDT file\n", __func__); + goto elf_check_fail; + } + + return true; + +elf_check_fail: + return false; +} + +static int wdsp_add_segment_to_list(struct device *dev, + const char *img_fname, + const struct elf32_phdr *phdr, + int phdr_idx, + struct list_head *seg_list) +{ + struct wdsp_img_segment *seg; + int ret = 0; + + /* Do not load segments with zero size */ + if (phdr->p_filesz == 0 || phdr->p_memsz == 0) + goto done; + + seg = kzalloc(sizeof(*seg), GFP_KERNEL); + if (!seg) { + ret = -ENOMEM; + goto done; + } + + snprintf(seg->split_fname, sizeof(seg->split_fname), + "%s.b%02d", img_fname, phdr_idx); + ret = request_firmware(&seg->split_fw, seg->split_fname, dev); + if (ret < 0) { + dev_err(dev, "%s: firmware %s not found\n", + __func__, seg->split_fname); + goto bad_seg; + } + + seg->load_addr = phdr->p_paddr; + seg->size = phdr->p_filesz; + seg->data = (u8 *) seg->split_fw->data; + + list_add_tail(&seg->list, seg_list); +done: + return ret; +bad_seg: + kfree(seg); + return ret; +} + +/* + * wdsp_flush_segment_list: Flush the list of segments + * @seg_list: List of segments to be flushed + * This API will traverse through the list of segments provided in + * seg_list, release the firmware for each segment and delete the + * segment from the list. + */ +void wdsp_flush_segment_list(struct list_head *seg_list) +{ + struct wdsp_img_segment *seg, *next; + + list_for_each_entry_safe(seg, next, seg_list, list) { + release_firmware(seg->split_fw); + list_del(&seg->list); + kfree(seg); + } +} +EXPORT_SYMBOL(wdsp_flush_segment_list); + +/* + * wdsp_get_segment_list: Get the list of requested segments + * @dev: struct device pointer of caller + * @img_fname: Image name for the mdt and split firmware files + * @segment_type: Requested segment type, should be either + * WDSP_ELF_FLAG_RE or WDSP_ELF_FLAG_WRITE + * @seg_list: An initialized head for list of segmented to be returned + * @entry_point: Pointer to return the entry point of the image + * This API will parse the mdt file for img_fname and create + * an struct wdsp_img_segment for each segment that matches segment_type + * and add this structure to list pointed by seg_list + */ +int wdsp_get_segment_list(struct device *dev, + const char *img_fname, + unsigned int segment_type, + struct list_head *seg_list, + u32 *entry_point) +{ + const struct firmware *fw; + const struct elf32_hdr *ehdr; + const struct elf32_phdr *phdr; + const u8 *elf_ptr; + char mdt_name[WDSP_IMG_NAME_LEN_MAX]; + int ret, phdr_idx; + bool segment_match; + + if (!dev) { + ret = -EINVAL; + pr_err("%s: Invalid device handle\n", __func__); + goto done; + } + + if (!img_fname || !seg_list || !entry_point) { + ret = -EINVAL; + dev_err(dev, "%s: Invalid input params\n", + __func__); + goto done; + } + + if (segment_type != WDSP_ELF_FLAG_RE && + segment_type != WDSP_ELF_FLAG_WRITE) { + dev_err(dev, "%s: Invalid request for segment_type %d\n", + __func__, segment_type); + ret = -EINVAL; + goto done; + } + + snprintf(mdt_name, sizeof(mdt_name), "%s.mdt", img_fname); + ret = request_firmware(&fw, mdt_name, dev); + if (ret < 0) { + dev_err(dev, "%s: firmware %s not found\n", + __func__, mdt_name); + goto done; + } + + ehdr = (struct elf32_hdr *) fw->data; + *entry_point = ehdr->e_entry; + if (!wdsp_is_valid_elf_hdr(ehdr, fw->size)) { + dev_err(dev, "%s: fw mdt %s is invalid\n", + __func__, mdt_name); + ret = -EINVAL; + goto bad_elf; + } + + elf_ptr = fw->data + sizeof(*ehdr); + for (phdr_idx = 0; phdr_idx < ehdr->e_phnum; phdr_idx++) { + phdr = (struct elf32_phdr *) elf_ptr; + segment_match = false; + + switch (segment_type) { + case WDSP_ELF_FLAG_RE: + /* + * Flag can be READ or EXECUTE or both but + * WRITE flag should not be set. + */ + if ((phdr->p_flags & segment_type) && + !(phdr->p_flags & WDSP_ELF_FLAG_WRITE)) + segment_match = true; + break; + case WDSP_ELF_FLAG_WRITE: + /* + * If WRITE flag is set, other flags do not + * matter. + */ + if (phdr->p_flags & segment_type) + segment_match = true; + break; + } + + if (segment_match) { + ret = wdsp_add_segment_to_list(dev, img_fname, phdr, + phdr_idx, seg_list); + if (ret < 0) { + wdsp_flush_segment_list(seg_list); + goto bad_elf; + } + } + elf_ptr = elf_ptr + sizeof(*phdr); + } + +bad_elf: + release_firmware(fw); +done: + return ret; +} +EXPORT_SYMBOL(wdsp_get_segment_list); diff --git a/sound/soc/codecs/wcd-dsp-utils.h b/sound/soc/codecs/wcd-dsp-utils.h new file mode 100644 index 000000000000..a530a1c3b67d --- /dev/null +++ b/sound/soc/codecs/wcd-dsp-utils.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __WCD_DSP_UTILS_H__ +#define __WCD_DSP_UTILS_H__ + +#define WDSP_IMG_NAME_LEN_MAX 64 + +#define WDSP_ELF_FLAG_EXECUTE (1 << 0) +#define WDSP_ELF_FLAG_WRITE (1 << 1) +#define WDSP_ELF_FLAG_READ (1 << 2) + +#define WDSP_ELF_FLAG_RE (WDSP_ELF_FLAG_READ | WDSP_ELF_FLAG_EXECUTE) + +struct wdsp_img_segment { + + /* Firmware for the slit image */ + const struct firmware *split_fw; + + /* Name of the split firmware file */ + char split_fname[WDSP_IMG_NAME_LEN_MAX]; + + /* Address where the segment is to be loaded */ + u32 load_addr; + + /* Buffer to hold the data to be loaded */ + u8 *data; + + /* Size of the data to be loaded */ + size_t size; + + /* List node pointing to next segment */ + struct list_head list; +}; + +int wdsp_get_segment_list(struct device *dev, const char *img_fname, + unsigned int segment_type, struct list_head *seg_list, + u32 *entry_point); +void wdsp_flush_segment_list(struct list_head *seg_list); + +#endif /* __WCD_DSP_UTILS_H__ */ diff --git a/sound/soc/codecs/wcd-mbhc-adc.c b/sound/soc/codecs/wcd-mbhc-adc.c new file mode 100644 index 000000000000..e44eec9fa5c7 --- /dev/null +++ b/sound/soc/codecs/wcd-mbhc-adc.c @@ -0,0 +1,1020 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcd-mbhc-adc.h" +#include "wcd-mbhc-v2.h" + +#define WCD_MBHC_ADC_HS_THRESHOLD_MV 1700 +#define WCD_MBHC_ADC_HPH_THRESHOLD_MV 75 +#define WCD_MBHC_ADC_MICBIAS_MV 1800 + +static int wcd_mbhc_get_micbias(struct wcd_mbhc *mbhc) +{ + int micbias = 0; + u8 vout_ctl = 0; + + /* Read MBHC Micbias (Mic Bias2) voltage */ + WCD_MBHC_REG_READ(WCD_MBHC_MICB2_VOUT, vout_ctl); + + /* Formula for getting micbias from vout + * micbias = 1.0V + VOUT_CTL * 50mV + */ + micbias = 1000 + (vout_ctl * 50); + pr_debug("%s: vout_ctl: %d, micbias: %d\n", + __func__, vout_ctl, micbias); + + return micbias; +} + +static int wcd_get_voltage_from_adc(u8 val, int micbias) +{ + /* Formula for calculating voltage from ADC + * Voltage = ADC_RESULT*12.5mV*V_MICBIAS/1.8 + */ + return ((val * 125 * micbias)/(WCD_MBHC_ADC_MICBIAS_MV * 10)); +} + +static int wcd_measure_adc_continuous(struct wcd_mbhc *mbhc) +{ + u8 adc_result = 0; + int output_mv = 0; + int retry = 3; + u8 adc_en = 0; + + pr_debug("%s: enter\n", __func__); + + /* Pre-requisites for ADC continuous measurement */ + /* Read legacy electircal detection and disable */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0x00); + /* Set ADC to continuous measurement */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, 1); + /* Read ADC Enable bit to restore after adc measurement */ + WCD_MBHC_REG_READ(WCD_MBHC_ADC_EN, adc_en); + /* Disable ADC_ENABLE bit */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 0); + /* Disable MBHC FSM */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); + /* Set the MUX selection to IN2P */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MUX_CTL, MUX_CTL_IN2P); + /* Enable MBHC FSM */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); + /* Enable ADC_ENABLE bit */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 1); + + while (retry--) { + /* wait for 3 msec before reading ADC result */ + usleep_range(3000, 3100); + + /* Read ADC result */ + WCD_MBHC_REG_READ(WCD_MBHC_ADC_RESULT, adc_result); + } + + /* Restore ADC Enable */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, adc_en); + /* Get voltage from ADC result */ + output_mv = wcd_get_voltage_from_adc(adc_result, + wcd_mbhc_get_micbias(mbhc)); + pr_debug("%s: adc_result: 0x%x, output_mv: %d\n", + __func__, adc_result, output_mv); + + return output_mv; +} + +static int wcd_measure_adc_once(struct wcd_mbhc *mbhc, int mux_ctl) +{ + u8 adc_timeout = 0; + u8 adc_complete = 0; + u8 adc_result = 0; + int retry = 6; + int ret = 0; + int output_mv = 0; + u8 adc_en = 0; + + pr_debug("%s: enter\n", __func__); + + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, 0); + /* Read ADC Enable bit to restore after adc measurement */ + WCD_MBHC_REG_READ(WCD_MBHC_ADC_EN, adc_en); + /* Trigger ADC one time measurement */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); + /* Set the appropriate MUX selection */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MUX_CTL, mux_ctl); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 1); + + while (retry--) { + /* wait for 600usec to get adc results */ + usleep_range(600, 610); + + /* check for ADC Timeout */ + WCD_MBHC_REG_READ(WCD_MBHC_ADC_TIMEOUT, adc_timeout); + if (adc_timeout) + continue; + + /* Read ADC complete bit */ + WCD_MBHC_REG_READ(WCD_MBHC_ADC_COMPLETE, adc_complete); + if (!adc_complete) + continue; + + /* Read ADC result */ + WCD_MBHC_REG_READ(WCD_MBHC_ADC_RESULT, adc_result); + + pr_debug("%s: ADC result: 0x%x\n", __func__, adc_result); + /* Get voltage from ADC result */ + output_mv = wcd_get_voltage_from_adc(adc_result, + wcd_mbhc_get_micbias(mbhc)); + break; + } + + /* Restore ADC Enable */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, adc_en); + + if (retry <= 0) { + pr_err("%s: adc complete: %d, adc timeout: %d\n", + __func__, adc_complete, adc_timeout); + ret = -EINVAL; + } else { + pr_debug("%s: adc complete: %d, adc timeout: %d output_mV: %d\n", + __func__, adc_complete, adc_timeout, output_mv); + ret = output_mv; + } + + pr_debug("%s: leave\n", __func__); + + return ret; +} + +static bool wcd_mbhc_adc_detect_anc_plug_type(struct wcd_mbhc *mbhc) +{ + bool anc_mic_found = false; + u16 fsm_en = 0; + u8 det = 0; + unsigned long retry = 0; + int valid_plug_cnt = 0, invalid_plug_cnt = 0; + int ret = 0; + u8 elect_ctl = 0; + u8 adc_mode = 0; + u8 vref = 0; + int vref_mv[] = {1650, 1500, 1600, 1700}; + + if (mbhc->mbhc_cfg->anc_micbias < MIC_BIAS_1 || + mbhc->mbhc_cfg->anc_micbias > MIC_BIAS_4) + return false; + + if (!mbhc->mbhc_cb->mbhc_micbias_control) + return false; + + /* Disable Detection done for ADC operation */ + WCD_MBHC_REG_READ(WCD_MBHC_DETECTION_DONE, det); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_DETECTION_DONE, 0); + + /* Mask ADC COMPLETE interrupt */ + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, false); + + WCD_MBHC_REG_READ(WCD_MBHC_FSM_EN, fsm_en); + mbhc->mbhc_cb->mbhc_micbias_control(mbhc->codec, + mbhc->mbhc_cfg->anc_micbias, + MICB_ENABLE); + + /* Read legacy electircal detection and disable */ + WCD_MBHC_REG_READ(WCD_MBHC_ELECT_SCHMT_ISRC, elect_ctl); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0x00); + + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ANC_DET_EN, 1); + WCD_MBHC_REG_READ(WCD_MBHC_ADC_MODE, adc_mode); + + /* + * wait for button debounce time 20ms. If 4-pole plug is inserted + * into 5-pole jack, then there will be a button press interrupt + * during anc plug detection. In that case though Hs_comp_res is 0, + * it should not be declared as ANC plug type + */ + usleep_range(20000, 20100); + + /* + * After enabling FSM, to handle slow insertion scenarios, + * check IN3 voltage is below the Vref + */ + WCD_MBHC_REG_READ(WCD_MBHC_HS_VREF, vref); + + do { + if (wcd_swch_level_remove(mbhc)) { + pr_debug("%s: Switch level is low\n", __func__); + goto done; + } + pr_debug("%s: Retry attempt %lu\n", __func__, retry + 1); + ret = wcd_measure_adc_once(mbhc, MUX_CTL_IN3P); + /* TODO - check the logic */ + if (ret && (ret < vref_mv[vref])) + valid_plug_cnt++; + else + invalid_plug_cnt++; + retry++; + } while (retry < ANC_DETECT_RETRY_CNT); + + pr_debug("%s: valid: %d, invalid: %d\n", __func__, valid_plug_cnt, + invalid_plug_cnt); + + /* decision logic */ + if (valid_plug_cnt > invalid_plug_cnt) + anc_mic_found = true; +done: + /* Restore ADC mode */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, adc_mode); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ANC_DET_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); + /* Set the MUX selection to AUTO */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MUX_CTL, MUX_CTL_AUTO); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, fsm_en); + /* Restore detection done */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_DETECTION_DONE, det); + + /* Restore electrical detection */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, elect_ctl); + + mbhc->mbhc_cb->mbhc_micbias_control(mbhc->codec, + mbhc->mbhc_cfg->anc_micbias, + MICB_DISABLE); + pr_debug("%s: anc mic %sfound\n", __func__, + anc_mic_found ? "" : "not "); + + return anc_mic_found; +} + +/* To determine if cross connection occurred */ +static int wcd_check_cross_conn(struct wcd_mbhc *mbhc) +{ + enum wcd_mbhc_plug_type plug_type = MBHC_PLUG_TYPE_NONE; + int hphl_adc_res = 0, hphr_adc_res = 0; + u8 fsm_en = 0; + int ret = 0; + u8 adc_mode = 0; + u8 elect_ctl = 0; + u8 adc_en = 0; + + pr_debug("%s: enter\n", __func__); + /* Check for button press and plug detection */ + if (wcd_swch_level_remove(mbhc)) { + pr_debug("%s: Switch level is low\n", __func__); + return -EINVAL; + } + + /* If PA is enabled, dont check for cross-connection */ + if (mbhc->mbhc_cb->hph_pa_on_status) + if (mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec)) + return -EINVAL; + + /* Read legacy electircal detection and disable */ + WCD_MBHC_REG_READ(WCD_MBHC_ELECT_SCHMT_ISRC, elect_ctl); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0x00); + + /* Read and set ADC to single measurement */ + WCD_MBHC_REG_READ(WCD_MBHC_ADC_MODE, adc_mode); + /* Read ADC Enable bit to restore after adc measurement */ + WCD_MBHC_REG_READ(WCD_MBHC_ADC_EN, adc_en); + /* Read FSM status */ + WCD_MBHC_REG_READ(WCD_MBHC_FSM_EN, fsm_en); + + /* Get adc result for HPH L */ + hphl_adc_res = wcd_measure_adc_once(mbhc, MUX_CTL_HPH_L); + if (hphl_adc_res < 0) { + pr_err("%s: hphl_adc_res adc measurement failed\n", __func__); + ret = hphl_adc_res; + goto done; + } + + /* Get adc result for HPH R in mV */ + hphr_adc_res = wcd_measure_adc_once(mbhc, MUX_CTL_HPH_R); + if (hphr_adc_res < 0) { + pr_err("%s: hphr_adc_res adc measurement failed\n", __func__); + ret = hphr_adc_res; + goto done; + } + + if (hphl_adc_res > 100 && hphr_adc_res > 100) { + plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; + pr_debug("%s: Cross connection identified\n", __func__); + } else { + pr_debug("%s: No Cross connection found\n", __func__); + } + +done: + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); + /* Set the MUX selection to Auto */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MUX_CTL, MUX_CTL_AUTO); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); + + /* Restore ADC Enable */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, adc_en); + + /* Restore ADC mode */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, adc_mode); + + /* Restore FSM state */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, fsm_en); + + /* Restore electrical detection */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, elect_ctl); + + pr_debug("%s: leave, plug type: %d\n", __func__, plug_type); + + return (plug_type == MBHC_PLUG_TYPE_GND_MIC_SWAP) ? true : false; +} + +static bool wcd_mbhc_adc_check_for_spl_headset(struct wcd_mbhc *mbhc, + int *spl_hs_cnt) +{ + bool spl_hs = false; + int output_mv = 0; + int adc_threshold = 0, adc_hph_threshold = 0; + + pr_debug("%s: enter\n", __func__); + if (!mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) + goto exit; + + /* Bump up MB2 to 2.7V */ + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->codec, + mbhc->mbhc_cfg->mbhc_micbias, true); + usleep_range(10000, 10100); + + /* + * Use ADC single mode to minimize the chance of missing out + * btn press/relesae for HEADSET type during correct work. + */ + output_mv = wcd_measure_adc_once(mbhc, MUX_CTL_IN2P); + adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV * + wcd_mbhc_get_micbias(mbhc))/WCD_MBHC_ADC_MICBIAS_MV); + adc_hph_threshold = ((WCD_MBHC_ADC_HPH_THRESHOLD_MV * + wcd_mbhc_get_micbias(mbhc))/ + WCD_MBHC_ADC_MICBIAS_MV); + + if (output_mv > adc_threshold || output_mv < adc_hph_threshold) { + spl_hs = false; + } else { + spl_hs = true; + if (spl_hs_cnt) + *spl_hs_cnt += 1; + } + + /* MB2 back to 1.8v if the type is not special headset */ + if (spl_hs_cnt && (*spl_hs_cnt != WCD_MBHC_SPL_HS_CNT)) { + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->codec, + mbhc->mbhc_cfg->mbhc_micbias, false); + /* Add 10ms delay for micbias to settle */ + usleep_range(10000, 10100); + } + + if (spl_hs) + pr_debug("%s: Detected special HS (%d)\n", __func__, spl_hs); + +exit: + pr_debug("%s: leave\n", __func__); + return spl_hs; +} + +static bool wcd_is_special_headset(struct wcd_mbhc *mbhc) +{ + int delay = 0; + bool ret = false; + bool is_spl_hs = false; + int output_mv = 0; + int adc_threshold = 0; + + /* + * Increase micbias to 2.7V to detect headsets with + * threshold on microphone + */ + if (mbhc->mbhc_cb->mbhc_micbias_control && + !mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) { + pr_debug("%s: callback fn micb_ctrl_thr_mic not defined\n", + __func__); + return false; + } else if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) { + ret = mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->codec, + MIC_BIAS_2, true); + if (ret) { + pr_err("%s: mbhc_micb_ctrl_thr_mic failed, ret: %d\n", + __func__, ret); + return false; + } + } + + adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV * + wcd_mbhc_get_micbias(mbhc)) / + WCD_MBHC_ADC_MICBIAS_MV); + + while (!is_spl_hs) { + if (mbhc->hs_detect_work_stop) { + pr_debug("%s: stop requested: %d\n", __func__, + mbhc->hs_detect_work_stop); + break; + } + delay += 50; + /* Wait for 50ms for FSM to update result */ + msleep(50); + output_mv = wcd_measure_adc_once(mbhc, MUX_CTL_IN2P); + if (output_mv <= adc_threshold) { + pr_debug("%s: Special headset detected in %d msecs\n", + __func__, delay); + is_spl_hs = true; + } + + if (delay == SPECIAL_HS_DETECT_TIME_MS) { + pr_debug("%s: Spl headset not found in 2 sec\n", + __func__); + break; + } + } + if (is_spl_hs) { + pr_debug("%s: Headset with threshold found\n", __func__); + mbhc->micbias_enable = true; + ret = true; + } + if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic && + !mbhc->micbias_enable) + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->codec, MIC_BIAS_2, + false); + pr_debug("%s: leave, micb_enable: %d\n", __func__, + mbhc->micbias_enable); + + return ret; +} + +static void wcd_mbhc_adc_update_fsm_source(struct wcd_mbhc *mbhc, + enum wcd_mbhc_plug_type plug_type) +{ + bool micbias2; + + micbias2 = mbhc->mbhc_cb->micbias_enable_status(mbhc, + MIC_BIAS_2); + switch (plug_type) { + case MBHC_PLUG_TYPE_HEADPHONE: + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 3); + break; + case MBHC_PLUG_TYPE_HEADSET: + case MBHC_PLUG_TYPE_ANC_HEADPHONE: + if (!mbhc->is_hs_recording && !micbias2) + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 3); + break; + default: + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0); + break; + + }; +} + +/* should be called under interrupt context that hold suspend */ +static void wcd_schedule_hs_detect_plug(struct wcd_mbhc *mbhc, + struct work_struct *work) +{ + pr_debug("%s: scheduling correct_swch_plug\n", __func__); + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + mbhc->hs_detect_work_stop = false; + mbhc->mbhc_cb->lock_sleep(mbhc, true); + schedule_work(work); +} + +/* called under codec_resource_lock acquisition */ +static void wcd_cancel_hs_detect_plug(struct wcd_mbhc *mbhc, + struct work_struct *work) +{ + pr_debug("%s: Canceling correct_plug_swch\n", __func__); + mbhc->hs_detect_work_stop = true; + WCD_MBHC_RSC_UNLOCK(mbhc); + if (cancel_work_sync(work)) { + pr_debug("%s: correct_plug_swch is canceled\n", + __func__); + mbhc->mbhc_cb->lock_sleep(mbhc, false); + } + WCD_MBHC_RSC_LOCK(mbhc); +} + +/* called under codec_resource_lock acquisition */ +static void wcd_mbhc_adc_detect_plug_type(struct wcd_mbhc *mbhc) +{ + struct snd_soc_codec *codec = mbhc->codec; + + pr_debug("%s: enter\n", __func__); + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + + if (mbhc->mbhc_cb->hph_pull_down_ctrl) + mbhc->mbhc_cb->hph_pull_down_ctrl(codec, false); + + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_DETECTION_DONE, 0); + + if (mbhc->mbhc_cb->mbhc_micbias_control) { + mbhc->mbhc_cb->mbhc_micbias_control(codec, MIC_BIAS_2, + MICB_ENABLE); + } else { + pr_err("%s: Mic Bias is not enabled\n", __func__); + return; + } + + /* Re-initialize button press completion object */ + reinit_completion(&mbhc->btn_press_compl); + wcd_schedule_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); + pr_debug("%s: leave\n", __func__); +} + +static void wcd_micbias_disable(struct wcd_mbhc *mbhc) +{ + if (mbhc->micbias_enable) { + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( + mbhc->codec, MIC_BIAS_2, false); + if (mbhc->mbhc_cb->set_micbias_value) + mbhc->mbhc_cb->set_micbias_value( + mbhc->codec); + mbhc->micbias_enable = false; + } +} + +static int wcd_mbhc_get_plug_from_adc(int adc_result) + +{ + enum wcd_mbhc_plug_type plug_type = MBHC_PLUG_TYPE_INVALID; + + if (adc_result < WCD_MBHC_ADC_HPH_THRESHOLD_MV) + plug_type = MBHC_PLUG_TYPE_HEADPHONE; + else if (adc_result > WCD_MBHC_ADC_HS_THRESHOLD_MV) + plug_type = MBHC_PLUG_TYPE_HIGH_HPH; + else + plug_type = MBHC_PLUG_TYPE_HEADSET; + pr_debug("%s: plug type is %d found\n", __func__, plug_type); + + return plug_type; +} + +static void wcd_correct_swch_plug(struct work_struct *work) +{ + struct wcd_mbhc *mbhc; + struct snd_soc_codec *codec; + enum wcd_mbhc_plug_type plug_type = MBHC_PLUG_TYPE_INVALID; + unsigned long timeout; + bool wrk_complete = false; + int pt_gnd_mic_swap_cnt = 0; + int no_gnd_mic_swap_cnt = 0; + bool is_pa_on = false, spl_hs = false, spl_hs_reported = false; + int ret = 0; + int spl_hs_count = 0; + int output_mv = 0; + int cross_conn; + int try = 0; + + pr_debug("%s: enter\n", __func__); + + mbhc = container_of(work, struct wcd_mbhc, correct_plug_swch); + codec = mbhc->codec; + + WCD_MBHC_RSC_LOCK(mbhc); + /* Mask ADC COMPLETE interrupt */ + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, false); + WCD_MBHC_RSC_UNLOCK(mbhc); + + /* Check for cross connection */ + do { + cross_conn = wcd_check_cross_conn(mbhc); + try++; + } while (try < GND_MIC_SWAP_THRESHOLD); + + if (cross_conn > 0) { + plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; + pr_debug("%s: cross connection found, Plug type %d\n", + __func__, plug_type); + goto correct_plug_type; + } + /* Find plug type */ + output_mv = wcd_measure_adc_continuous(mbhc); + plug_type = wcd_mbhc_get_plug_from_adc(output_mv); + + /* + * Report plug type if it is either headset or headphone + * else start the 3 sec loop + */ + if ((plug_type == MBHC_PLUG_TYPE_HEADSET || + plug_type == MBHC_PLUG_TYPE_HEADPHONE) && + (!wcd_swch_level_remove(mbhc))) { + WCD_MBHC_RSC_LOCK(mbhc); + wcd_mbhc_find_plug_and_report(mbhc, plug_type); + WCD_MBHC_RSC_UNLOCK(mbhc); + } + + /* + * Set DETECTION_DONE bit for HEADSET and ANC_HEADPHONE, + * so that btn press/release interrupt can be generated. + */ + if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET || + mbhc->current_plug == MBHC_PLUG_TYPE_ANC_HEADPHONE) { + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_DETECTION_DONE, 1); + } + +correct_plug_type: + timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS); + while (!time_after(jiffies, timeout)) { + if (mbhc->hs_detect_work_stop) { + pr_debug("%s: stop requested: %d\n", __func__, + mbhc->hs_detect_work_stop); + wcd_micbias_disable(mbhc); + goto exit; + } + + /* allow sometime and re-check stop requested again */ + msleep(20); + if (mbhc->hs_detect_work_stop) { + pr_debug("%s: stop requested: %d\n", __func__, + mbhc->hs_detect_work_stop); + wcd_micbias_disable(mbhc); + goto exit; + } + + msleep(180); + /* + * Use ADC single mode to minimize the chance of missing out + * btn press/release for HEADSET type during correct work. + */ + output_mv = wcd_measure_adc_once(mbhc, MUX_CTL_IN2P); + + /* + * instead of hogging system by contineous polling, wait for + * sometime and re-check stop request again. + */ + plug_type = wcd_mbhc_get_plug_from_adc(output_mv); + + if ((output_mv > WCD_MBHC_ADC_HS_THRESHOLD_MV) && + (spl_hs_count < WCD_MBHC_SPL_HS_CNT)) { + spl_hs = wcd_mbhc_adc_check_for_spl_headset(mbhc, + &spl_hs_count); + + if (spl_hs_count == WCD_MBHC_SPL_HS_CNT) { + output_mv = WCD_MBHC_ADC_HS_THRESHOLD_MV; + spl_hs = true; + mbhc->micbias_enable = true; + } + } + + if (mbhc->mbhc_cb->hph_pa_on_status) + is_pa_on = mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec); + + if ((output_mv <= WCD_MBHC_ADC_HS_THRESHOLD_MV) && + (!is_pa_on)) { + /* Check for cross connection*/ + ret = wcd_check_cross_conn(mbhc); + if (ret < 0) + continue; + else if (ret > 0) { + pt_gnd_mic_swap_cnt++; + no_gnd_mic_swap_cnt = 0; + if (pt_gnd_mic_swap_cnt < + GND_MIC_SWAP_THRESHOLD) { + continue; + } else if (pt_gnd_mic_swap_cnt > + GND_MIC_SWAP_THRESHOLD) { + /* + * This is due to GND/MIC switch didn't + * work, Report unsupported plug. + */ + pr_debug("%s: switch did not work\n", + __func__); + plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; + goto report; + } else { + plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; + } + } else { + no_gnd_mic_swap_cnt++; + pt_gnd_mic_swap_cnt = 0; + plug_type = wcd_mbhc_get_plug_from_adc( + output_mv); + if ((no_gnd_mic_swap_cnt < + GND_MIC_SWAP_THRESHOLD) && + (spl_hs_count != WCD_MBHC_SPL_HS_CNT)) { + continue; + } else { + no_gnd_mic_swap_cnt = 0; + } + } + if ((pt_gnd_mic_swap_cnt == GND_MIC_SWAP_THRESHOLD) && + (plug_type == MBHC_PLUG_TYPE_GND_MIC_SWAP)) { + /* + * if switch is toggled, check again, + * otherwise report unsupported plug + */ + if (mbhc->mbhc_cfg->swap_gnd_mic && + mbhc->mbhc_cfg->swap_gnd_mic(codec, + true)) { + pr_debug("%s: US_EU gpio present,flip switch\n" + , __func__); + continue; + } + } + } + + if (output_mv > WCD_MBHC_ADC_HS_THRESHOLD_MV) { + pr_debug("%s: cable is extension cable\n", __func__); + plug_type = MBHC_PLUG_TYPE_HIGH_HPH; + wrk_complete = true; + } else { + pr_debug("%s: cable might be headset: %d\n", __func__, + plug_type); + if (plug_type != MBHC_PLUG_TYPE_GND_MIC_SWAP) { + plug_type = wcd_mbhc_get_plug_from_adc( + output_mv); + if (!spl_hs_reported && + spl_hs_count == WCD_MBHC_SPL_HS_CNT) { + spl_hs_reported = true; + WCD_MBHC_RSC_LOCK(mbhc); + wcd_mbhc_find_plug_and_report(mbhc, + plug_type); + WCD_MBHC_RSC_UNLOCK(mbhc); + continue; + } else if (spl_hs_reported) + continue; + /* + * Report headset only if not already reported + * and if there is not button press without + * release + */ + if ((mbhc->current_plug != + MBHC_PLUG_TYPE_HEADSET) && + (mbhc->current_plug != + MBHC_PLUG_TYPE_ANC_HEADPHONE) && + !wcd_swch_level_remove(mbhc)) { + pr_debug("%s: cable is %s headset\n", + __func__, + ((spl_hs_count == + WCD_MBHC_SPL_HS_CNT) ? + "special ":"")); + goto report; + } + } + wrk_complete = false; + } + } + if (!wrk_complete) { + /* + * If plug_tye is headset, we might have already reported either + * in detect_plug-type or in above while loop, no need to report + * again + */ + if ((plug_type == MBHC_PLUG_TYPE_HEADSET) || + (plug_type == MBHC_PLUG_TYPE_ANC_HEADPHONE)) { + pr_debug("%s: plug_type:0x%x already reported\n", + __func__, mbhc->current_plug); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 0); + goto enable_supply; + } + } + if (plug_type == MBHC_PLUG_TYPE_HIGH_HPH) { + if (wcd_is_special_headset(mbhc)) { + pr_debug("%s: Special headset found %d\n", + __func__, plug_type); + plug_type = MBHC_PLUG_TYPE_HEADSET; + } else { + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_ISRC_EN, 1); + } + } + +report: + if (wcd_swch_level_remove(mbhc)) { + pr_debug("%s: Switch level is low\n", __func__); + goto exit; + } + + pr_debug("%s: Valid plug found, plug type %d wrk_cmpt %d btn_intr %d\n", + __func__, plug_type, wrk_complete, + mbhc->btn_press_intr); + + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 0); + + WCD_MBHC_RSC_LOCK(mbhc); + wcd_mbhc_find_plug_and_report(mbhc, plug_type); + WCD_MBHC_RSC_UNLOCK(mbhc); +enable_supply: + /* + * Set DETECTION_DONE bit for HEADSET and ANC_HEADPHONE, + * so that btn press/release interrupt can be generated. + * For other plug type, clear the bit. + */ + if (plug_type == MBHC_PLUG_TYPE_HEADSET || + plug_type == MBHC_PLUG_TYPE_ANC_HEADPHONE) + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_DETECTION_DONE, 1); + else + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_DETECTION_DONE, 0); + + if (mbhc->mbhc_cb->mbhc_micbias_control) + wcd_mbhc_adc_update_fsm_source(mbhc, plug_type); +exit: + if (mbhc->mbhc_cb->mbhc_micbias_control && + !mbhc->micbias_enable) + mbhc->mbhc_cb->mbhc_micbias_control(codec, MIC_BIAS_2, + MICB_DISABLE); + + /* + * If plug type is corrected from special headset to headphone, + * clear the micbias enable flag, set micbias back to 1.8V and + * disable micbias. + */ + if (plug_type == MBHC_PLUG_TYPE_HEADPHONE && + mbhc->micbias_enable) { + if (mbhc->mbhc_cb->mbhc_micbias_control) + mbhc->mbhc_cb->mbhc_micbias_control( + codec, MIC_BIAS_2, + MICB_DISABLE); + if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( + codec, + MIC_BIAS_2, false); + if (mbhc->mbhc_cb->set_micbias_value) { + mbhc->mbhc_cb->set_micbias_value(codec); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MICB_CTRL, 0); + } + mbhc->micbias_enable = false; + } + + if (mbhc->mbhc_cfg->detect_extn_cable && + ((plug_type == MBHC_PLUG_TYPE_HEADPHONE) || + (plug_type == MBHC_PLUG_TYPE_HEADSET)) && + !mbhc->hs_detect_work_stop) { + WCD_MBHC_RSC_LOCK(mbhc); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_REM, true); + WCD_MBHC_RSC_UNLOCK(mbhc); + } + + /* + * Enable ADC COMPLETE interrupt for HEADPHONE. + * Btn release may happen after the correct work, ADC COMPLETE + * interrupt needs to be captured to correct plug type. + */ + if (plug_type == MBHC_PLUG_TYPE_HEADPHONE) { + WCD_MBHC_RSC_LOCK(mbhc); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, + true); + WCD_MBHC_RSC_UNLOCK(mbhc); + } + + if (mbhc->mbhc_cb->hph_pull_down_ctrl) + mbhc->mbhc_cb->hph_pull_down_ctrl(codec, true); + + mbhc->mbhc_cb->lock_sleep(mbhc, false); + pr_debug("%s: leave\n", __func__); +} + +static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) +{ + struct wcd_mbhc *mbhc = data; + unsigned long timeout; + int adc_threshold, output_mv, retry = 0; + + pr_debug("%s: enter\n", __func__); + WCD_MBHC_RSC_LOCK(mbhc); + + timeout = jiffies + + msecs_to_jiffies(WCD_FAKE_REMOVAL_MIN_PERIOD_MS); + adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV * + wcd_mbhc_get_micbias(mbhc)) / + WCD_MBHC_ADC_MICBIAS_MV); + do { + retry++; + /* + * read output_mv every 10ms to look for + * any change in IN2_P + */ + usleep_range(10000, 10100); + output_mv = wcd_measure_adc_once(mbhc, MUX_CTL_IN2P); + + pr_debug("%s: Check for fake removal: output_mv %d\n", + __func__, output_mv); + if ((output_mv <= adc_threshold) && + retry > FAKE_REM_RETRY_ATTEMPTS) { + pr_debug("%s: headset is NOT actually removed\n", + __func__); + goto exit; + } + } while (!time_after(jiffies, timeout)); + + if (wcd_swch_level_remove(mbhc)) { + pr_debug("%s: Switch level is low ", __func__); + goto exit; + } + + /* + * ADC COMPLETE and ELEC_REM interrupts are both enabled for HEADPHONE, + * need to reject the ADC COMPLETE interrupt which follows ELEC_REM one + * when HEADPHONE is removed. + */ + if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) + mbhc->extn_cable_hph_rem = true; + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_DETECTION_DONE, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 0); + wcd_mbhc_elec_hs_report_unplug(mbhc); +exit: + WCD_MBHC_RSC_UNLOCK(mbhc); + pr_debug("%s: leave\n", __func__); + return IRQ_HANDLED; +} + +static irqreturn_t wcd_mbhc_adc_hs_ins_irq(int irq, void *data) +{ + struct wcd_mbhc *mbhc = data; + + pr_debug("%s: enter\n", __func__); + + /* + * ADC COMPLETE and ELEC_REM interrupts are both enabled for HEADPHONE, + * need to reject the ADC COMPLETE interrupt which follows ELEC_REM one + * when HEADPHONE is removed. + */ + if (mbhc->extn_cable_hph_rem == true) { + mbhc->extn_cable_hph_rem = false; + pr_debug("%s: leave\n", __func__); + return IRQ_HANDLED; + } + + WCD_MBHC_RSC_LOCK(mbhc); + /* + * If current plug is headphone then there is no chance to + * get ADC complete interrupt, so connected cable should be + * headset not headphone. + */ + if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) { + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, false); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_DETECTION_DONE, 1); + wcd_mbhc_find_plug_and_report(mbhc, MBHC_PLUG_TYPE_HEADSET); + WCD_MBHC_RSC_UNLOCK(mbhc); + return IRQ_HANDLED; + } + + if (!mbhc->mbhc_cfg->detect_extn_cable) { + pr_debug("%s: Returning as Extension cable feature not enabled\n", + __func__); + WCD_MBHC_RSC_UNLOCK(mbhc); + return IRQ_HANDLED; + } + + pr_debug("%s: Disable electrical headset insertion interrupt\n", + __func__); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, false); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_ISRC_EN, 0); + mbhc->is_extn_cable = true; + mbhc->btn_press_intr = false; + wcd_mbhc_adc_detect_plug_type(mbhc); + WCD_MBHC_RSC_UNLOCK(mbhc); + pr_debug("%s: leave\n", __func__); + return IRQ_HANDLED; +} + +static struct wcd_mbhc_fn mbhc_fn = { + .wcd_mbhc_hs_ins_irq = wcd_mbhc_adc_hs_ins_irq, + .wcd_mbhc_hs_rem_irq = wcd_mbhc_adc_hs_rem_irq, + .wcd_mbhc_detect_plug_type = wcd_mbhc_adc_detect_plug_type, + .wcd_mbhc_detect_anc_plug_type = wcd_mbhc_adc_detect_anc_plug_type, + .wcd_cancel_hs_detect_plug = wcd_cancel_hs_detect_plug, +}; + +/* Function: wcd_mbhc_adc_init + * @mbhc: MBHC function pointer + * Description: Initialize MBHC ADC related function pointers to MBHC structure + */ +void wcd_mbhc_adc_init(struct wcd_mbhc *mbhc) +{ + if (!mbhc) { + pr_err("%s: mbhc is NULL\n", __func__); + return; + } + mbhc->mbhc_fn = &mbhc_fn; + INIT_WORK(&mbhc->correct_plug_swch, wcd_correct_swch_plug); +} +EXPORT_SYMBOL(wcd_mbhc_adc_init); diff --git a/sound/soc/codecs/wcd-mbhc-adc.h b/sound/soc/codecs/wcd-mbhc-adc.h new file mode 100644 index 000000000000..31161089e793 --- /dev/null +++ b/sound/soc/codecs/wcd-mbhc-adc.h @@ -0,0 +1,35 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __WCD_MBHC_ADC_H__ +#define __WCD_MBHC_ADC_H__ + +#include "wcd-mbhc-v2.h" + +enum wcd_mbhc_adc_mux_ctl { + MUX_CTL_AUTO = 0, + MUX_CTL_IN2P, + MUX_CTL_IN3P, + MUX_CTL_IN4P, + MUX_CTL_HPH_L, + MUX_CTL_HPH_R, + MUX_CTL_NONE, +}; + +#if IS_ENABLED(CONFIG_SND_SOC_WCD_MBHC_ADC) +void wcd_mbhc_adc_init(struct wcd_mbhc *mbhc); +#else +static inline void wcd_mbhc_adc_init(struct wcd_mbhc *mbhc) +{ + +} +#endif +#endif /* __WCD_MBHC_ADC_H__ */ diff --git a/sound/soc/codecs/wcd-mbhc-legacy.c b/sound/soc/codecs/wcd-mbhc-legacy.c new file mode 100644 index 000000000000..745e2e81a556 --- /dev/null +++ b/sound/soc/codecs/wcd-mbhc-legacy.c @@ -0,0 +1,975 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcd-mbhc-legacy.h" +#include "wcd-mbhc-v2.h" + +static int det_extn_cable_en; +module_param(det_extn_cable_en, int, 0664); +MODULE_PARM_DESC(det_extn_cable_en, "enable/disable extn cable detect"); + +static bool wcd_mbhc_detect_anc_plug_type(struct wcd_mbhc *mbhc) +{ + bool anc_mic_found = false; + u16 val, hs_comp_res, btn_status = 0; + unsigned long retry = 0; + int valid_plug_cnt = 0, invalid_plug_cnt = 0; + int btn_status_cnt = 0; + bool is_check_btn_press = false; + + + if (mbhc->mbhc_cfg->anc_micbias < MIC_BIAS_1 || + mbhc->mbhc_cfg->anc_micbias > MIC_BIAS_4) + return false; + + if (!mbhc->mbhc_cb->mbhc_micbias_control) + return false; + + WCD_MBHC_REG_READ(WCD_MBHC_FSM_EN, val); + + if (val) + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); + + mbhc->mbhc_cb->mbhc_micbias_control(mbhc->codec, + mbhc->mbhc_cfg->anc_micbias, + MICB_ENABLE); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MUX_CTL, 0x2); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ANC_DET_EN, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); + /* + * wait for button debounce time 20ms. If 4-pole plug is inserted + * into 5-pole jack, then there will be a button press interrupt + * during anc plug detection. In that case though Hs_comp_res is 0, + * it should not be declared as ANC plug type + */ + usleep_range(20000, 20100); + + /* + * After enabling FSM, to handle slow insertion scenarios, + * check hs_comp_result for few times to see if the IN3 voltage + * is below the Vref + */ + do { + if (wcd_swch_level_remove(mbhc)) { + pr_debug("%s: Switch level is low\n", __func__); + goto exit; + } + pr_debug("%s: Retry attempt %lu\n", __func__, retry + 1); + WCD_MBHC_REG_READ(WCD_MBHC_HS_COMP_RESULT, hs_comp_res); + + if (!hs_comp_res) { + valid_plug_cnt++; + is_check_btn_press = true; + } else + invalid_plug_cnt++; + /* Wait 1ms before taking another reading */ + usleep_range(1000, 1100); + + WCD_MBHC_REG_READ(WCD_MBHC_FSM_STATUS, btn_status); + if (btn_status) + btn_status_cnt++; + + retry++; + } while (retry < ANC_DETECT_RETRY_CNT); + + pr_debug("%s: valid: %d, invalid: %d, btn_status_cnt: %d\n", + __func__, valid_plug_cnt, invalid_plug_cnt, btn_status_cnt); + + /* decision logic */ + if ((valid_plug_cnt > invalid_plug_cnt) && is_check_btn_press && + (btn_status_cnt == 0)) + anc_mic_found = true; +exit: + if (!val) + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); + + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ANC_DET_EN, 0); + + mbhc->mbhc_cb->mbhc_micbias_control(mbhc->codec, + mbhc->mbhc_cfg->anc_micbias, + MICB_DISABLE); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MUX_CTL, 0x0); + pr_debug("%s: anc mic %sfound\n", __func__, + anc_mic_found ? "" : "not "); + return anc_mic_found; +} + +/* To determine if cross connection occurred */ +static int wcd_check_cross_conn(struct wcd_mbhc *mbhc) +{ + u16 swap_res = 0; + enum wcd_mbhc_plug_type plug_type = MBHC_PLUG_TYPE_NONE; + s16 reg1 = 0; + bool hphl_sch_res = 0, hphr_sch_res = 0; + + if (wcd_swch_level_remove(mbhc)) { + pr_debug("%s: Switch level is low\n", __func__); + return -EINVAL; + } + + /* If PA is enabled, dont check for cross-connection */ + if (mbhc->mbhc_cb->hph_pa_on_status) + if (mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec)) + return false; + + WCD_MBHC_REG_READ(WCD_MBHC_ELECT_SCHMT_ISRC, reg1); + /* + * Check if there is any cross connection, + * Micbias and schmitt trigger (HPHL-HPHR) + * needs to be enabled. For some codecs like wcd9335, + * pull-up will already be enabled when this function + * is called for cross-connection identification. No + * need to enable micbias in that case. + */ + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 2); + + WCD_MBHC_REG_READ(WCD_MBHC_ELECT_RESULT, swap_res); + pr_debug("%s: swap_res%x\n", __func__, swap_res); + + /* + * Read reg hphl and hphr schmitt result with cross connection + * bit. These bits will both be "0" in case of cross connection + * otherwise, they stay at 1 + */ + WCD_MBHC_REG_READ(WCD_MBHC_HPHL_SCHMT_RESULT, hphl_sch_res); + WCD_MBHC_REG_READ(WCD_MBHC_HPHR_SCHMT_RESULT, hphr_sch_res); + if (!(hphl_sch_res || hphr_sch_res)) { + plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; + pr_debug("%s: Cross connection identified\n", __func__); + } else { + pr_debug("%s: No Cross connection found\n", __func__); + } + + /* Disable schmitt trigger and restore micbias */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, reg1); + pr_debug("%s: leave, plug type: %d\n", __func__, plug_type); + + return (plug_type == MBHC_PLUG_TYPE_GND_MIC_SWAP) ? true : false; +} + +static bool wcd_is_special_headset(struct wcd_mbhc *mbhc) +{ + struct snd_soc_codec *codec = mbhc->codec; + int delay = 0, rc; + bool ret = false; + u16 hs_comp_res; + bool is_spl_hs = false; + + /* + * Increase micbias to 2.7V to detect headsets with + * threshold on microphone + */ + if (mbhc->mbhc_cb->mbhc_micbias_control && + !mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) { + pr_debug("%s: callback fn micb_ctrl_thr_mic not defined\n", + __func__); + return false; + } else if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) { + rc = mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(codec, + MIC_BIAS_2, true); + if (rc) { + pr_err("%s: Micbias control for thr mic failed, rc: %d\n", + __func__, rc); + return false; + } + } + + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); + + pr_debug("%s: special headset, start register writes\n", __func__); + + WCD_MBHC_REG_READ(WCD_MBHC_HS_COMP_RESULT, hs_comp_res); + while (!is_spl_hs) { + if (mbhc->hs_detect_work_stop) { + pr_debug("%s: stop requested: %d\n", __func__, + mbhc->hs_detect_work_stop); + break; + } + delay = delay + 50; + if (mbhc->mbhc_cb->mbhc_common_micb_ctrl) { + mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, + MBHC_COMMON_MICB_PRECHARGE, + true); + mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, + MBHC_COMMON_MICB_SET_VAL, + true); + } + /* Wait for 50msec for MICBIAS to settle down */ + msleep(50); + if (mbhc->mbhc_cb->set_auto_zeroing) + mbhc->mbhc_cb->set_auto_zeroing(codec, true); + /* Wait for 50msec for FSM to update result values */ + msleep(50); + WCD_MBHC_REG_READ(WCD_MBHC_HS_COMP_RESULT, hs_comp_res); + if (!(hs_comp_res)) { + pr_debug("%s: Special headset detected in %d msecs\n", + __func__, (delay * 2)); + is_spl_hs = true; + } + if (delay == SPECIAL_HS_DETECT_TIME_MS) { + pr_debug("%s: Spl headset didn't get detect in 4 sec\n", + __func__); + break; + } + } + if (is_spl_hs) { + pr_debug("%s: Headset with threshold found\n", __func__); + mbhc->micbias_enable = true; + ret = true; + } + if (mbhc->mbhc_cb->mbhc_common_micb_ctrl) + mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, + MBHC_COMMON_MICB_PRECHARGE, + false); + if (mbhc->mbhc_cb->set_micbias_value && !mbhc->micbias_enable) + mbhc->mbhc_cb->set_micbias_value(codec); + if (mbhc->mbhc_cb->set_auto_zeroing) + mbhc->mbhc_cb->set_auto_zeroing(codec, false); + + if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic && + !mbhc->micbias_enable) + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(codec, MIC_BIAS_2, + false); + + pr_debug("%s: leave, micb_enable: %d\n", __func__, + mbhc->micbias_enable); + return ret; +} + +static void wcd_mbhc_update_fsm_source(struct wcd_mbhc *mbhc, + enum wcd_mbhc_plug_type plug_type) +{ + bool micbias2; + + micbias2 = mbhc->mbhc_cb->micbias_enable_status(mbhc, + MIC_BIAS_2); + switch (plug_type) { + case MBHC_PLUG_TYPE_HEADPHONE: + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 3); + break; + case MBHC_PLUG_TYPE_HEADSET: + case MBHC_PLUG_TYPE_ANC_HEADPHONE: + if (!mbhc->is_hs_recording && !micbias2) + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 3); + break; + default: + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0); + break; + + }; +} + +static void wcd_enable_mbhc_supply(struct wcd_mbhc *mbhc, + enum wcd_mbhc_plug_type plug_type) +{ + + struct snd_soc_codec *codec = mbhc->codec; + + /* + * Do not disable micbias if recording is going on or + * headset is inserted on the other side of the extn + * cable. If headset has been detected current source + * needs to be kept enabled for button detection to work. + * If the accessory type is invalid or unsupported, we + * dont need to enable either of them. + */ + if (det_extn_cable_en && mbhc->is_extn_cable && + mbhc->mbhc_cb && mbhc->mbhc_cb->extn_use_mb && + mbhc->mbhc_cb->extn_use_mb(codec)) { + if (plug_type == MBHC_PLUG_TYPE_HEADPHONE || + plug_type == MBHC_PLUG_TYPE_HEADSET) + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); + } else { + if (plug_type == MBHC_PLUG_TYPE_HEADSET) { + if (mbhc->is_hs_recording || mbhc->micbias_enable) { + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); + } else if ((test_bit(WCD_MBHC_EVENT_PA_HPHL, + &mbhc->event_state)) || + (test_bit(WCD_MBHC_EVENT_PA_HPHR, + &mbhc->event_state))) { + wcd_enable_curr_micbias(mbhc, + WCD_MBHC_EN_PULLUP); + } else { + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_CS); + } + } else if (plug_type == MBHC_PLUG_TYPE_HEADPHONE) { + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_CS); + } else { + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_NONE); + } + } +} + +static bool wcd_mbhc_check_for_spl_headset(struct wcd_mbhc *mbhc, + int *spl_hs_cnt) +{ + u16 hs_comp_res_1_8v = 0, hs_comp_res_2_7v = 0; + bool spl_hs = false; + + if (!mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) + goto done; + + if (!spl_hs_cnt) { + pr_err("%s: spl_hs_cnt is NULL\n", __func__); + goto done; + } + /* Read back hs_comp_res @ 1.8v Micbias */ + WCD_MBHC_REG_READ(WCD_MBHC_HS_COMP_RESULT, hs_comp_res_1_8v); + if (!hs_comp_res_1_8v) { + spl_hs = false; + goto done; + } + + /* Bump up MB2 to 2.7v */ + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->codec, + mbhc->mbhc_cfg->mbhc_micbias, true); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); + usleep_range(10000, 10100); + + /* Read back HS_COMP_RESULT */ + WCD_MBHC_REG_READ(WCD_MBHC_HS_COMP_RESULT, hs_comp_res_2_7v); + if (!hs_comp_res_2_7v && hs_comp_res_1_8v) + spl_hs = true; + + if (spl_hs) + *spl_hs_cnt += 1; + + /* MB2 back to 1.8v */ + if (*spl_hs_cnt != WCD_MBHC_SPL_HS_CNT) { + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->codec, + mbhc->mbhc_cfg->mbhc_micbias, false); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); + usleep_range(10000, 10100); + } + + if (spl_hs) + pr_debug("%s: Detected special HS (%d)\n", __func__, spl_hs); + +done: + return spl_hs; +} + +/* should be called under interrupt context that hold suspend */ +static void wcd_schedule_hs_detect_plug(struct wcd_mbhc *mbhc, + struct work_struct *work) +{ + pr_debug("%s: scheduling correct_swch_plug\n", __func__); + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + mbhc->hs_detect_work_stop = false; + mbhc->mbhc_cb->lock_sleep(mbhc, true); + schedule_work(work); +} + +/* called under codec_resource_lock acquisition */ +static void wcd_cancel_hs_detect_plug(struct wcd_mbhc *mbhc, + struct work_struct *work) +{ + pr_debug("%s: Canceling correct_plug_swch\n", __func__); + mbhc->hs_detect_work_stop = true; + WCD_MBHC_RSC_UNLOCK(mbhc); + if (cancel_work_sync(work)) { + pr_debug("%s: correct_plug_swch is canceled\n", + __func__); + mbhc->mbhc_cb->lock_sleep(mbhc, false); + } + WCD_MBHC_RSC_LOCK(mbhc); +} + +/* called under codec_resource_lock acquisition */ +static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc) +{ + struct snd_soc_codec *codec = mbhc->codec; + bool micbias1 = false; + + pr_debug("%s: enter\n", __func__); + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + + if (mbhc->mbhc_cb->hph_pull_down_ctrl) + mbhc->mbhc_cb->hph_pull_down_ctrl(codec, false); + + if (mbhc->mbhc_cb->micbias_enable_status) + micbias1 = mbhc->mbhc_cb->micbias_enable_status(mbhc, + MIC_BIAS_1); + + if (mbhc->mbhc_cb->set_cap_mode) + mbhc->mbhc_cb->set_cap_mode(codec, micbias1, true); + + if (mbhc->mbhc_cb->mbhc_micbias_control) + mbhc->mbhc_cb->mbhc_micbias_control(codec, MIC_BIAS_2, + MICB_ENABLE); + else + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); + + /* Re-initialize button press completion object */ + reinit_completion(&mbhc->btn_press_compl); + wcd_schedule_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); + pr_debug("%s: leave\n", __func__); +} + +static void wcd_correct_swch_plug(struct work_struct *work) +{ + struct wcd_mbhc *mbhc; + struct snd_soc_codec *codec; + enum wcd_mbhc_plug_type plug_type = MBHC_PLUG_TYPE_INVALID; + unsigned long timeout; + u16 hs_comp_res = 0, hphl_sch = 0, mic_sch = 0, btn_result = 0; + bool wrk_complete = false; + int pt_gnd_mic_swap_cnt = 0; + int no_gnd_mic_swap_cnt = 0; + bool is_pa_on = false, spl_hs = false, spl_hs_reported = false; + bool micbias2 = false; + bool micbias1 = false; + int ret = 0; + int rc, spl_hs_count = 0; + int cross_conn; + int try = 0; + + pr_debug("%s: enter\n", __func__); + + mbhc = container_of(work, struct wcd_mbhc, correct_plug_swch); + codec = mbhc->codec; + + /* + * Enable micbias/pullup for detection in correct work. + * This work will get scheduled from detect_plug_type which + * will already request for pullup/micbias. If the pullup/micbias + * is handled with ref-counts by individual codec drivers, there is + * no need to enabale micbias/pullup here + */ + + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); + + /* Enable HW FSM */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); + /* + * Check for any button press interrupts before starting 3-sec + * loop. + */ + rc = wait_for_completion_timeout(&mbhc->btn_press_compl, + msecs_to_jiffies(WCD_MBHC_BTN_PRESS_COMPL_TIMEOUT_MS)); + + WCD_MBHC_REG_READ(WCD_MBHC_BTN_RESULT, btn_result); + WCD_MBHC_REG_READ(WCD_MBHC_HS_COMP_RESULT, hs_comp_res); + + if (!rc) { + pr_debug("%s No btn press interrupt\n", __func__); + if (!btn_result && !hs_comp_res) + plug_type = MBHC_PLUG_TYPE_HEADSET; + else if (!btn_result && hs_comp_res) + plug_type = MBHC_PLUG_TYPE_HIGH_HPH; + else + plug_type = MBHC_PLUG_TYPE_INVALID; + } else { + if (!btn_result && !hs_comp_res) + plug_type = MBHC_PLUG_TYPE_HEADPHONE; + else + plug_type = MBHC_PLUG_TYPE_INVALID; + } + + do { + cross_conn = wcd_check_cross_conn(mbhc); + try++; + } while (try < GND_MIC_SWAP_THRESHOLD); + + /* + * Check for cross connection 4 times. + * Consider the result of the fourth iteration. + */ + if (cross_conn > 0) { + pr_debug("%s: cross con found, start polling\n", + __func__); + plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; + pr_debug("%s: Plug found, plug type is %d\n", + __func__, plug_type); + goto correct_plug_type; + } + + if ((plug_type == MBHC_PLUG_TYPE_HEADSET || + plug_type == MBHC_PLUG_TYPE_HEADPHONE) && + (!wcd_swch_level_remove(mbhc))) { + WCD_MBHC_RSC_LOCK(mbhc); + if (mbhc->current_plug == MBHC_PLUG_TYPE_HIGH_HPH) + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_DETECTION_TYPE, + 0); + wcd_mbhc_find_plug_and_report(mbhc, plug_type); + WCD_MBHC_RSC_UNLOCK(mbhc); + } + +correct_plug_type: + + timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS); + while (!time_after(jiffies, timeout)) { + if (mbhc->hs_detect_work_stop) { + pr_debug("%s: stop requested: %d\n", __func__, + mbhc->hs_detect_work_stop); + wcd_enable_curr_micbias(mbhc, + WCD_MBHC_EN_NONE); + if (mbhc->micbias_enable) { + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( + mbhc->codec, MIC_BIAS_2, false); + if (mbhc->mbhc_cb->set_micbias_value) + mbhc->mbhc_cb->set_micbias_value( + mbhc->codec); + mbhc->micbias_enable = false; + } + goto exit; + } + if (mbhc->btn_press_intr) { + wcd_cancel_btn_work(mbhc); + mbhc->btn_press_intr = false; + } + /* Toggle FSM */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); + + /* allow sometime and re-check stop requested again */ + msleep(20); + if (mbhc->hs_detect_work_stop) { + pr_debug("%s: stop requested: %d\n", __func__, + mbhc->hs_detect_work_stop); + wcd_enable_curr_micbias(mbhc, + WCD_MBHC_EN_NONE); + if (mbhc->micbias_enable) { + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( + mbhc->codec, MIC_BIAS_2, false); + if (mbhc->mbhc_cb->set_micbias_value) + mbhc->mbhc_cb->set_micbias_value( + mbhc->codec); + mbhc->micbias_enable = false; + } + goto exit; + } + WCD_MBHC_REG_READ(WCD_MBHC_HS_COMP_RESULT, hs_comp_res); + + pr_debug("%s: hs_comp_res: %x\n", __func__, hs_comp_res); + if (mbhc->mbhc_cb->hph_pa_on_status) + is_pa_on = mbhc->mbhc_cb->hph_pa_on_status(codec); + + /* + * instead of hogging system by contineous polling, wait for + * sometime and re-check stop request again. + */ + msleep(180); + if (hs_comp_res && (spl_hs_count < WCD_MBHC_SPL_HS_CNT)) { + spl_hs = wcd_mbhc_check_for_spl_headset(mbhc, + &spl_hs_count); + + if (spl_hs_count == WCD_MBHC_SPL_HS_CNT) { + hs_comp_res = 0; + spl_hs = true; + mbhc->micbias_enable = true; + } + } + + if ((!hs_comp_res) && (!is_pa_on)) { + /* Check for cross connection*/ + ret = wcd_check_cross_conn(mbhc); + if (ret < 0) { + continue; + } else if (ret > 0) { + pt_gnd_mic_swap_cnt++; + no_gnd_mic_swap_cnt = 0; + if (pt_gnd_mic_swap_cnt < + GND_MIC_SWAP_THRESHOLD) { + continue; + } else if (pt_gnd_mic_swap_cnt > + GND_MIC_SWAP_THRESHOLD) { + /* + * This is due to GND/MIC switch didn't + * work, Report unsupported plug. + */ + pr_debug("%s: switch didn't work\n", + __func__); + plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; + goto report; + } else { + plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; + } + } else { + no_gnd_mic_swap_cnt++; + pt_gnd_mic_swap_cnt = 0; + plug_type = MBHC_PLUG_TYPE_HEADSET; + if ((no_gnd_mic_swap_cnt < + GND_MIC_SWAP_THRESHOLD) && + (spl_hs_count != WCD_MBHC_SPL_HS_CNT)) { + continue; + } else { + no_gnd_mic_swap_cnt = 0; + } + } + if ((pt_gnd_mic_swap_cnt == GND_MIC_SWAP_THRESHOLD) && + (plug_type == MBHC_PLUG_TYPE_GND_MIC_SWAP)) { + /* + * if switch is toggled, check again, + * otherwise report unsupported plug + */ + if (mbhc->mbhc_cfg->swap_gnd_mic && + mbhc->mbhc_cfg->swap_gnd_mic(codec, + true)) { + pr_debug("%s: US_EU gpio present,flip switch\n" + , __func__); + continue; + } + } + } + + WCD_MBHC_REG_READ(WCD_MBHC_HPHL_SCHMT_RESULT, hphl_sch); + WCD_MBHC_REG_READ(WCD_MBHC_MIC_SCHMT_RESULT, mic_sch); + if (hs_comp_res && !(hphl_sch || mic_sch)) { + pr_debug("%s: cable is extension cable\n", __func__); + plug_type = MBHC_PLUG_TYPE_HIGH_HPH; + wrk_complete = true; + } else { + pr_debug("%s: cable might be headset: %d\n", __func__, + plug_type); + if (!(plug_type == MBHC_PLUG_TYPE_GND_MIC_SWAP)) { + plug_type = MBHC_PLUG_TYPE_HEADSET; + if (!spl_hs_reported && + spl_hs_count == WCD_MBHC_SPL_HS_CNT) { + spl_hs_reported = true; + WCD_MBHC_RSC_LOCK(mbhc); + wcd_mbhc_find_plug_and_report(mbhc, + plug_type); + WCD_MBHC_RSC_UNLOCK(mbhc); + continue; + } else if (spl_hs_reported) + continue; + /* + * Report headset only if not already reported + * and if there is not button press without + * release + */ + if (((mbhc->current_plug != + MBHC_PLUG_TYPE_HEADSET) && + (mbhc->current_plug != + MBHC_PLUG_TYPE_ANC_HEADPHONE)) && + !wcd_swch_level_remove(mbhc) && + !mbhc->btn_press_intr) { + pr_debug("%s: cable is %sheadset\n", + __func__, + ((spl_hs_count == + WCD_MBHC_SPL_HS_CNT) ? + "special ":"")); + goto report; + } + } + wrk_complete = false; + } + } + if (!wrk_complete && mbhc->btn_press_intr) { + pr_debug("%s: Can be slow insertion of headphone\n", __func__); + wcd_cancel_btn_work(mbhc); + plug_type = MBHC_PLUG_TYPE_HEADPHONE; + } + /* + * If plug_tye is headset, we might have already reported either in + * detect_plug-type or in above while loop, no need to report again + */ + if (!wrk_complete && ((plug_type == MBHC_PLUG_TYPE_HEADSET) || + (plug_type == MBHC_PLUG_TYPE_ANC_HEADPHONE))) { + pr_debug("%s: plug_type:0x%x already reported\n", + __func__, mbhc->current_plug); + goto enable_supply; + } + + if (plug_type == MBHC_PLUG_TYPE_HIGH_HPH && + (!det_extn_cable_en)) { + if (wcd_is_special_headset(mbhc)) { + pr_debug("%s: Special headset found %d\n", + __func__, plug_type); + plug_type = MBHC_PLUG_TYPE_HEADSET; + goto report; + } + } + +report: + if (wcd_swch_level_remove(mbhc)) { + pr_debug("%s: Switch level is low\n", __func__); + goto exit; + } + if (plug_type == MBHC_PLUG_TYPE_GND_MIC_SWAP && mbhc->btn_press_intr) { + pr_debug("%s: insertion of headphone with swap\n", __func__); + wcd_cancel_btn_work(mbhc); + plug_type = MBHC_PLUG_TYPE_HEADPHONE; + } + pr_debug("%s: Valid plug found, plug type %d wrk_cmpt %d btn_intr %d\n", + __func__, plug_type, wrk_complete, + mbhc->btn_press_intr); + WCD_MBHC_RSC_LOCK(mbhc); + wcd_mbhc_find_plug_and_report(mbhc, plug_type); + WCD_MBHC_RSC_UNLOCK(mbhc); +enable_supply: + if (mbhc->mbhc_cb->mbhc_micbias_control) + wcd_mbhc_update_fsm_source(mbhc, plug_type); + else + wcd_enable_mbhc_supply(mbhc, plug_type); +exit: + if (mbhc->mbhc_cb->mbhc_micbias_control && + !mbhc->micbias_enable) + mbhc->mbhc_cb->mbhc_micbias_control(codec, MIC_BIAS_2, + MICB_DISABLE); + + /* + * If plug type is corrected from special headset to headphone, + * clear the micbias enable flag, set micbias back to 1.8V and + * disable micbias. + */ + if (plug_type == MBHC_PLUG_TYPE_HEADPHONE && + mbhc->micbias_enable) { + if (mbhc->mbhc_cb->mbhc_micbias_control) + mbhc->mbhc_cb->mbhc_micbias_control( + codec, MIC_BIAS_2, + MICB_DISABLE); + if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( + codec, + MIC_BIAS_2, false); + if (mbhc->mbhc_cb->set_micbias_value) { + mbhc->mbhc_cb->set_micbias_value(codec); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MICB_CTRL, 0); + } + mbhc->micbias_enable = false; + } + + if (mbhc->mbhc_cb->micbias_enable_status) { + micbias1 = mbhc->mbhc_cb->micbias_enable_status(mbhc, + MIC_BIAS_1); + micbias2 = mbhc->mbhc_cb->micbias_enable_status(mbhc, + MIC_BIAS_2); + } + + if (mbhc->mbhc_cfg->detect_extn_cable && + ((plug_type == MBHC_PLUG_TYPE_HEADPHONE) || + (plug_type == MBHC_PLUG_TYPE_HEADSET)) && + !mbhc->hs_detect_work_stop) { + WCD_MBHC_RSC_LOCK(mbhc); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_REM, true); + WCD_MBHC_RSC_UNLOCK(mbhc); + } + if (mbhc->mbhc_cb->set_cap_mode) + mbhc->mbhc_cb->set_cap_mode(codec, micbias1, micbias2); + + if (mbhc->mbhc_cb->hph_pull_down_ctrl) + mbhc->mbhc_cb->hph_pull_down_ctrl(codec, true); + + mbhc->mbhc_cb->lock_sleep(mbhc, false); + pr_debug("%s: leave\n", __func__); +} + +static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) +{ + struct wcd_mbhc *mbhc = data; + u8 hs_comp_result = 0, hphl_sch = 0, mic_sch = 0; + static u16 hphl_trigerred; + static u16 mic_trigerred; + unsigned long timeout; + bool removed = true; + int retry = 0; + + pr_debug("%s: enter\n", __func__); + + WCD_MBHC_RSC_LOCK(mbhc); + + timeout = jiffies + + msecs_to_jiffies(WCD_FAKE_REMOVAL_MIN_PERIOD_MS); + do { + retry++; + /* + * read the result register every 10ms to look for + * any change in HS_COMP_RESULT bit + */ + usleep_range(10000, 10100); + WCD_MBHC_REG_READ(WCD_MBHC_HS_COMP_RESULT, hs_comp_result); + pr_debug("%s: Check result reg for fake removal: hs_comp_res %x\n", + __func__, hs_comp_result); + if ((!hs_comp_result) && + retry > FAKE_REM_RETRY_ATTEMPTS) { + removed = false; + break; + } + } while (!time_after(jiffies, timeout)); + + if (wcd_swch_level_remove(mbhc)) { + pr_debug("%s: Switch level is low ", __func__); + goto exit; + } + pr_debug("%s: headset %s actually removed\n", __func__, + removed ? "" : "not "); + + WCD_MBHC_REG_READ(WCD_MBHC_HPHL_SCHMT_RESULT, hphl_sch); + WCD_MBHC_REG_READ(WCD_MBHC_MIC_SCHMT_RESULT, mic_sch); + WCD_MBHC_REG_READ(WCD_MBHC_HS_COMP_RESULT, hs_comp_result); + + if (removed) { + if (!(hphl_sch && mic_sch && hs_comp_result)) { + /* + * extension cable is still plugged in + * report it as LINEOUT device + */ + goto report_unplug; + } else { + if (!mic_sch) { + mic_trigerred++; + pr_debug("%s: Removal MIC trigerred %d\n", + __func__, mic_trigerred); + } + if (!hphl_sch) { + hphl_trigerred++; + pr_debug("%s: Removal HPHL trigerred %d\n", + __func__, hphl_trigerred); + } + if (mic_trigerred && hphl_trigerred) { + /* + * extension cable is still plugged in + * report it as LINEOUT device + */ + goto report_unplug; + } + } + } +exit: + WCD_MBHC_RSC_UNLOCK(mbhc); + pr_debug("%s: leave\n", __func__); + return IRQ_HANDLED; + +report_unplug: + wcd_mbhc_elec_hs_report_unplug(mbhc); + hphl_trigerred = 0; + mic_trigerred = 0; + WCD_MBHC_RSC_UNLOCK(mbhc); + pr_debug("%s: leave\n", __func__); + return IRQ_HANDLED; +} + +static irqreturn_t wcd_mbhc_hs_ins_irq(int irq, void *data) +{ + struct wcd_mbhc *mbhc = data; + bool detection_type = 0, hphl_sch = 0, mic_sch = 0; + u16 elect_result = 0; + static u16 hphl_trigerred; + static u16 mic_trigerred; + + pr_debug("%s: enter\n", __func__); + if (!mbhc->mbhc_cfg->detect_extn_cable) { + pr_debug("%s: Returning as Extension cable feature not enabled\n", + __func__); + return IRQ_HANDLED; + } + WCD_MBHC_RSC_LOCK(mbhc); + + WCD_MBHC_REG_READ(WCD_MBHC_ELECT_DETECTION_TYPE, detection_type); + WCD_MBHC_REG_READ(WCD_MBHC_ELECT_RESULT, elect_result); + + pr_debug("%s: detection_type %d, elect_result %x\n", __func__, + detection_type, elect_result); + if (detection_type) { + /* check if both Left and MIC Schmitt triggers are triggered */ + WCD_MBHC_REG_READ(WCD_MBHC_HPHL_SCHMT_RESULT, hphl_sch); + WCD_MBHC_REG_READ(WCD_MBHC_MIC_SCHMT_RESULT, mic_sch); + if (hphl_sch && mic_sch) { + /* Go for plug type determination */ + pr_debug("%s: Go for plug type determination\n", + __func__); + goto determine_plug; + + } else { + if (mic_sch) { + mic_trigerred++; + pr_debug("%s: Insertion MIC trigerred %d\n", + __func__, mic_trigerred); + WCD_MBHC_REG_UPDATE_BITS( + WCD_MBHC_ELECT_SCHMT_ISRC, + 0); + msleep(20); + WCD_MBHC_REG_UPDATE_BITS( + WCD_MBHC_ELECT_SCHMT_ISRC, + 1); + } + if (hphl_sch) { + hphl_trigerred++; + pr_debug("%s: Insertion HPHL trigerred %d\n", + __func__, hphl_trigerred); + } + if (mic_trigerred && hphl_trigerred) { + /* Go for plug type determination */ + pr_debug("%s: Go for plug type determination\n", + __func__); + goto determine_plug; + } + } + } + WCD_MBHC_RSC_UNLOCK(mbhc); + pr_debug("%s: leave\n", __func__); + return IRQ_HANDLED; + +determine_plug: + /* + * Disable HPHL trigger and MIC Schmitt triggers. + * Setup for insertion detection. + */ + pr_debug("%s: Disable insertion interrupt\n", __func__); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, + false); + + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0); + hphl_trigerred = 0; + mic_trigerred = 0; + mbhc->is_extn_cable = true; + mbhc->btn_press_intr = false; + wcd_mbhc_detect_plug_type(mbhc); + WCD_MBHC_RSC_UNLOCK(mbhc); + pr_debug("%s: leave\n", __func__); + return IRQ_HANDLED; +} + +static struct wcd_mbhc_fn mbhc_fn = { + .wcd_mbhc_hs_ins_irq = wcd_mbhc_hs_ins_irq, + .wcd_mbhc_hs_rem_irq = wcd_mbhc_hs_rem_irq, + .wcd_mbhc_detect_plug_type = wcd_mbhc_detect_plug_type, + .wcd_mbhc_detect_anc_plug_type = wcd_mbhc_detect_anc_plug_type, + .wcd_cancel_hs_detect_plug = wcd_cancel_hs_detect_plug, +}; + +/* Function: wcd_mbhc_legacy_init + * @mbhc: MBHC function pointer + * Description: Initialize MBHC legacy based function pointers to MBHC structure + */ +void wcd_mbhc_legacy_init(struct wcd_mbhc *mbhc) +{ + if (!mbhc) { + pr_err("%s: mbhc is NULL\n", __func__); + return; + } + mbhc->mbhc_fn = &mbhc_fn; + INIT_WORK(&mbhc->correct_plug_swch, wcd_correct_swch_plug); +} +EXPORT_SYMBOL(wcd_mbhc_legacy_init); diff --git a/sound/soc/codecs/wcd-mbhc-legacy.h b/sound/soc/codecs/wcd-mbhc-legacy.h new file mode 100644 index 000000000000..594393d47896 --- /dev/null +++ b/sound/soc/codecs/wcd-mbhc-legacy.h @@ -0,0 +1,26 @@ +/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __WCD_MBHC_LEGACY_H__ +#define __WCD_MBHC_LEGACY_H__ + +#include "wcdcal-hwdep.h" +#include "wcd-mbhc-v2.h" + +#ifdef CONFIG_SND_SOC_WCD_MBHC_LEGACY +void wcd_mbhc_legacy_init(struct wcd_mbhc *mbhc); +#else +static inline void wcd_mbhc_legacy_init(struct wcd_mbhc *mbhc) +{ +} +#endif + +#endif /* __WCD_MBHC_LEGACY_H__ */ diff --git a/sound/soc/codecs/wcd-mbhc-v2-api.h b/sound/soc/codecs/wcd-mbhc-v2-api.h new file mode 100644 index 000000000000..7b6e94507ad0 --- /dev/null +++ b/sound/soc/codecs/wcd-mbhc-v2-api.h @@ -0,0 +1,60 @@ +/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __WCD_MBHC_V2_API_H__ +#define __WCD_MBHC_V2_API_H__ + +#include "wcd-mbhc-v2.h" + +#if IS_ENABLED(CONFIG_SND_SOC_WCD_MBHC) +int wcd_mbhc_start(struct wcd_mbhc *mbhc, + struct wcd_mbhc_config *mbhc_cfg); +void wcd_mbhc_stop(struct wcd_mbhc *mbhc); +int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, + const struct wcd_mbhc_cb *mbhc_cb, + const struct wcd_mbhc_intr *mbhc_cdc_intr_ids, + struct wcd_mbhc_register *wcd_mbhc_regs, + bool impedance_det_en); +int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, + uint32_t *zr); +void wcd_mbhc_deinit(struct wcd_mbhc *mbhc); + +#else +static inline void wcd_mbhc_stop(struct wcd_mbhc *mbhc) +{ +} +int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, + const struct wcd_mbhc_cb *mbhc_cb, + const struct wcd_mbhc_intr *mbhc_cdc_intr_ids, + struct wcd_mbhc_register *wcd_mbhc_regs, + bool impedance_det_en) +{ + return 0; +} +static inline int wcd_mbhc_start(struct wcd_mbhc *mbhc, + struct wcd_mbhc_config *mbhc_cfg) +{ + return 0; +} +static inline int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, + uint32_t *zl, + uint32_t *zr) +{ + *zl = 0; + *zr = 0; + return -EINVAL; +} +static inline void wcd_mbhc_deinit(struct wcd_mbhc *mbhc) +{ +} +#endif + +#endif /* __WCD_MBHC_V2_API_H__ */ diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c new file mode 100644 index 000000000000..3b2426dc7234 --- /dev/null +++ b/sound/soc/codecs/wcd-mbhc-v2.c @@ -0,0 +1,2074 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcdcal-hwdep.h" +#include "wcd-mbhc-legacy.h" +#include "wcd-mbhc-adc.h" +#include "wcd-mbhc-v2-api.h" + +void wcd_mbhc_jack_report(struct wcd_mbhc *mbhc, + struct snd_soc_jack *jack, int status, int mask) +{ + snd_soc_jack_report(jack, status, mask); +} +EXPORT_SYMBOL(wcd_mbhc_jack_report); + +static void __hphocp_off_report(struct wcd_mbhc *mbhc, u32 jack_status, + int irq) +{ + struct snd_soc_codec *codec = mbhc->codec; + + dev_dbg(codec->dev, "%s: clear ocp status %x\n", + __func__, jack_status); + + if (mbhc->hph_status & jack_status) { + mbhc->hph_status &= ~jack_status; + wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack, + mbhc->hph_status, WCD_MBHC_JACK_MASK); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_OCP_FSM_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_OCP_FSM_EN, 1); + /* + * reset retry counter as PA is turned off signifying + * start of new OCP detection session + */ + if (mbhc->intr_ids->hph_left_ocp) + mbhc->hphlocp_cnt = 0; + else + mbhc->hphrocp_cnt = 0; + mbhc->mbhc_cb->irq_control(codec, irq, true); + } +} + +static void hphrocp_off_report(struct wcd_mbhc *mbhc, u32 jack_status) +{ + __hphocp_off_report(mbhc, SND_JACK_OC_HPHR, + mbhc->intr_ids->hph_right_ocp); +} + +static void hphlocp_off_report(struct wcd_mbhc *mbhc, u32 jack_status) +{ + __hphocp_off_report(mbhc, SND_JACK_OC_HPHL, + mbhc->intr_ids->hph_left_ocp); +} + +static void wcd_program_hs_vref(struct wcd_mbhc *mbhc) +{ + struct wcd_mbhc_plug_type_cfg *plug_type_cfg; + struct snd_soc_codec *codec = mbhc->codec; + u32 reg_val; + + plug_type_cfg = WCD_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration); + reg_val = ((plug_type_cfg->v_hs_max - HS_VREF_MIN_VAL) / 100); + + dev_dbg(codec->dev, "%s: reg_val = %x\n", __func__, reg_val); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_VREF, reg_val); +} + +static void wcd_program_btn_threshold(const struct wcd_mbhc *mbhc, bool micbias) +{ + struct wcd_mbhc_btn_detect_cfg *btn_det; + struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_card *card = codec->component.card; + s16 *btn_low, *btn_high; + + if (mbhc->mbhc_cfg->calibration == NULL) { + dev_err(card->dev, "%s: calibration data is NULL\n", __func__); + return; + } + + btn_det = WCD_MBHC_CAL_BTN_DET_PTR(mbhc->mbhc_cfg->calibration); + btn_low = btn_det->_v_btn_low; + btn_high = ((void *)&btn_det->_v_btn_low) + + (sizeof(btn_det->_v_btn_low[0]) * btn_det->num_btn); + + mbhc->mbhc_cb->set_btn_thr(codec, btn_low, btn_high, btn_det->num_btn, + micbias); +} + +void wcd_enable_curr_micbias(const struct wcd_mbhc *mbhc, + const enum wcd_mbhc_cs_mb_en_flag cs_mb_en) +{ + + /* + * Some codecs handle micbias/pullup enablement in codec + * drivers itself and micbias is not needed for regular + * plug type detection. So if micbias_control callback function + * is defined, just return. + */ + if (mbhc->mbhc_cb->mbhc_micbias_control) + return; + + pr_debug("%s: enter, cs_mb_en: %d\n", __func__, cs_mb_en); + + switch (cs_mb_en) { + case WCD_MBHC_EN_CS: + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MICB_CTRL, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 3); + /* Program Button threshold registers as per CS */ + wcd_program_btn_threshold(mbhc, false); + break; + case WCD_MBHC_EN_MB: + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); + + /* Disable PULL_UP_EN & enable MICBIAS */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MICB_CTRL, 2); + /* Program Button threshold registers as per MICBIAS */ + wcd_program_btn_threshold(mbhc, true); + break; + case WCD_MBHC_EN_PULLUP: + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 3); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MICB_CTRL, 1); + /* Program Button threshold registers as per MICBIAS */ + wcd_program_btn_threshold(mbhc, true); + break; + case WCD_MBHC_EN_NONE: + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MICB_CTRL, 0); + break; + default: + pr_debug("%s: Invalid parameter", __func__); + break; + } + + pr_debug("%s: exit\n", __func__); +} +EXPORT_SYMBOL(wcd_enable_curr_micbias); + +static const char *wcd_mbhc_get_event_string(int event) +{ + switch (event) { + case WCD_EVENT_PRE_MICBIAS_2_OFF: + return WCD_MBHC_STRINGIFY(WCD_EVENT_PRE_MICBIAS_2_OFF); + case WCD_EVENT_POST_MICBIAS_2_OFF: + return WCD_MBHC_STRINGIFY(WCD_EVENT_POST_MICBIAS_2_OFF); + case WCD_EVENT_PRE_MICBIAS_2_ON: + return WCD_MBHC_STRINGIFY(WCD_EVENT_PRE_MICBIAS_2_ON); + case WCD_EVENT_POST_MICBIAS_2_ON: + return WCD_MBHC_STRINGIFY(WCD_EVENT_POST_MICBIAS_2_ON); + case WCD_EVENT_PRE_HPHL_PA_ON: + return WCD_MBHC_STRINGIFY(WCD_EVENT_PRE_HPHL_PA_ON); + case WCD_EVENT_POST_HPHL_PA_OFF: + return WCD_MBHC_STRINGIFY(WCD_EVENT_POST_HPHL_PA_OFF); + case WCD_EVENT_PRE_HPHR_PA_ON: + return WCD_MBHC_STRINGIFY(WCD_EVENT_PRE_HPHR_PA_ON); + case WCD_EVENT_POST_HPHR_PA_OFF: + return WCD_MBHC_STRINGIFY(WCD_EVENT_POST_HPHR_PA_OFF); + case WCD_EVENT_PRE_HPHR_PA_OFF: + return WCD_MBHC_STRINGIFY(WCD_EVENT_PRE_HPHR_PA_OFF); + case WCD_EVENT_PRE_HPHL_PA_OFF: + return WCD_MBHC_STRINGIFY(WCD_EVENT_PRE_HPHL_PA_OFF); + case WCD_EVENT_POST_DAPM_MICBIAS_2_ON: + return WCD_MBHC_STRINGIFY(WCD_EVENT_POST_DAPM_MICBIAS_2_ON); + case WCD_EVENT_PRE_DAPM_MICBIAS_2_ON: + return WCD_MBHC_STRINGIFY(WCD_EVENT_PRE_DAPM_MICBIAS_2_ON); + case WCD_EVENT_POST_DAPM_MICBIAS_2_OFF: + return WCD_MBHC_STRINGIFY(WCD_EVENT_POST_DAPM_MICBIAS_2_OFF); + case WCD_EVENT_PRE_DAPM_MICBIAS_2_OFF: + return WCD_MBHC_STRINGIFY(WCD_EVENT_PRE_DAPM_MICBIAS_2_OFF); + case WCD_EVENT_OCP_OFF: + return WCD_MBHC_STRINGIFY(WCD_EVENT_OCP_OFF); + case WCD_EVENT_OCP_ON: + return WCD_MBHC_STRINGIFY(WCD_EVENT_OCP_ON); + case WCD_EVENT_INVALID: + default: + return WCD_MBHC_STRINGIFY(WCD_EVENT_INVALID); + } +} + +static int wcd_event_notify(struct notifier_block *self, unsigned long val, + void *data) +{ + struct wcd_mbhc *mbhc = (struct wcd_mbhc *)data; + enum wcd_notify_event event = (enum wcd_notify_event)val; + struct snd_soc_codec *codec = mbhc->codec; + bool micbias2 = false; + bool micbias1 = false; + u8 fsm_en = 0; + + pr_debug("%s: event %s (%d)\n", __func__, + wcd_mbhc_get_event_string(event), event); + if (mbhc->mbhc_cb->micbias_enable_status) { + micbias2 = mbhc->mbhc_cb->micbias_enable_status(mbhc, + MIC_BIAS_2); + micbias1 = mbhc->mbhc_cb->micbias_enable_status(mbhc, + MIC_BIAS_1); + } + switch (event) { + /* MICBIAS usage change */ + case WCD_EVENT_POST_DAPM_MICBIAS_2_ON: + mbhc->is_hs_recording = true; + pr_debug("%s: is_capture: %d\n", __func__, + mbhc->is_hs_recording); + break; + case WCD_EVENT_POST_MICBIAS_2_ON: + if (!mbhc->micbias_enable) + goto out_micb_en; + if (mbhc->mbhc_cb->mbhc_common_micb_ctrl) { + mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, + MBHC_COMMON_MICB_PRECHARGE, + true); + mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, + MBHC_COMMON_MICB_SET_VAL, + true); + /* + * Special headset needs MICBIAS as 2.7V so wait for + * 50 msec for the MICBIAS to reach 2.7 volts. + */ + msleep(50); + } + if (mbhc->mbhc_cb->set_auto_zeroing) + mbhc->mbhc_cb->set_auto_zeroing(codec, true); + if (mbhc->mbhc_cb->mbhc_common_micb_ctrl) + mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, + MBHC_COMMON_MICB_PRECHARGE, + false); +out_micb_en: + /* Disable current source if micbias enabled */ + if (mbhc->mbhc_cb->mbhc_micbias_control) { + WCD_MBHC_REG_READ(WCD_MBHC_FSM_EN, fsm_en); + if (fsm_en) + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, + 0); + } else { + mbhc->is_hs_recording = true; + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); + } + /* configure cap settings properly when micbias is enabled */ + if (mbhc->mbhc_cb->set_cap_mode) + mbhc->mbhc_cb->set_cap_mode(codec, micbias1, true); + break; + case WCD_EVENT_PRE_MICBIAS_2_OFF: + /* + * Before MICBIAS_2 is turned off, if FSM is enabled, + * make sure current source is enabled so as to detect + * button press/release events + */ + if (mbhc->mbhc_cb->mbhc_micbias_control && + !mbhc->micbias_enable) { + WCD_MBHC_REG_READ(WCD_MBHC_FSM_EN, fsm_en); + if (fsm_en) + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, + 3); + } + break; + /* MICBIAS usage change */ + case WCD_EVENT_POST_DAPM_MICBIAS_2_OFF: + mbhc->is_hs_recording = false; + pr_debug("%s: is_capture: %d\n", __func__, + mbhc->is_hs_recording); + break; + case WCD_EVENT_POST_MICBIAS_2_OFF: + if (!mbhc->mbhc_cb->mbhc_micbias_control) + mbhc->is_hs_recording = false; + if (mbhc->micbias_enable) { + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); + break; + } + + if (mbhc->mbhc_cb->set_auto_zeroing) + mbhc->mbhc_cb->set_auto_zeroing(codec, false); + if (mbhc->mbhc_cb->set_micbias_value && !mbhc->micbias_enable) + mbhc->mbhc_cb->set_micbias_value(codec); + /* Enable PULL UP if PA's are enabled */ + if ((test_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state)) || + (test_bit(WCD_MBHC_EVENT_PA_HPHR, + &mbhc->event_state))) + /* enable pullup and cs, disable mb */ + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_PULLUP); + else + /* enable current source and disable mb, pullup*/ + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_CS); + + /* configure cap settings properly when micbias is disabled */ + if (mbhc->mbhc_cb->set_cap_mode) + mbhc->mbhc_cb->set_cap_mode(codec, micbias1, false); + break; + case WCD_EVENT_PRE_HPHL_PA_OFF: + mutex_lock(&mbhc->hphl_pa_lock); + break; + case WCD_EVENT_POST_HPHL_PA_OFF: + clear_bit(WCD_MBHC_HPHL_PA_OFF_ACK, &mbhc->hph_pa_dac_state); + if (mbhc->hph_status & SND_JACK_OC_HPHL) + hphlocp_off_report(mbhc, SND_JACK_OC_HPHL); + clear_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state); + /* check if micbias is enabled */ + if (micbias2) + /* Disable cs, pullup & enable micbias */ + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); + else + /* Disable micbias, pullup & enable cs */ + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_CS); + mutex_unlock(&mbhc->hphl_pa_lock); + break; + case WCD_EVENT_PRE_HPHR_PA_OFF: + mutex_lock(&mbhc->hphr_pa_lock); + break; + case WCD_EVENT_POST_HPHR_PA_OFF: + clear_bit(WCD_MBHC_HPHR_PA_OFF_ACK, &mbhc->hph_pa_dac_state); + if (mbhc->hph_status & SND_JACK_OC_HPHR) + hphrocp_off_report(mbhc, SND_JACK_OC_HPHR); + clear_bit(WCD_MBHC_EVENT_PA_HPHR, &mbhc->event_state); + /* check if micbias is enabled */ + if (micbias2) + /* Disable cs, pullup & enable micbias */ + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); + else + /* Disable micbias, pullup & enable cs */ + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_CS); + mutex_unlock(&mbhc->hphr_pa_lock); + break; + case WCD_EVENT_PRE_HPHL_PA_ON: + set_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state); + /* check if micbias is enabled */ + if (micbias2) + /* Disable cs, pullup & enable micbias */ + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); + else + /* Disable micbias, enable pullup & cs */ + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_PULLUP); + break; + case WCD_EVENT_PRE_HPHR_PA_ON: + set_bit(WCD_MBHC_EVENT_PA_HPHR, &mbhc->event_state); + /* check if micbias is enabled */ + if (micbias2) + /* Disable cs, pullup & enable micbias */ + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); + else + /* Disable micbias, enable pullup & cs */ + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_PULLUP); + break; + case WCD_EVENT_OCP_OFF: + mbhc->mbhc_cb->irq_control(mbhc->codec, + mbhc->intr_ids->hph_left_ocp, + false); + break; + case WCD_EVENT_OCP_ON: + mbhc->mbhc_cb->irq_control(mbhc->codec, + mbhc->intr_ids->hph_left_ocp, + true); + break; + default: + break; + } + return 0; +} + +int wcd_cancel_btn_work(struct wcd_mbhc *mbhc) +{ + int r; + + r = cancel_delayed_work_sync(&mbhc->mbhc_btn_dwork); + /* + * if scheduled mbhc.mbhc_btn_dwork is canceled from here, + * we have to unlock from here instead btn_work + */ + if (r) + mbhc->mbhc_cb->lock_sleep(mbhc, false); + return r; +} +EXPORT_SYMBOL(wcd_cancel_btn_work); + +bool wcd_swch_level_remove(struct wcd_mbhc *mbhc) +{ + u16 result2 = 0; + + WCD_MBHC_REG_READ(WCD_MBHC_SWCH_LEVEL_REMOVE, result2); + return (result2) ? true : false; +} +EXPORT_SYMBOL(wcd_swch_level_remove); + +static void wcd_mbhc_clr_and_turnon_hph_padac(struct wcd_mbhc *mbhc) +{ + bool pa_turned_on = false; + u8 wg_time = 0; + + WCD_MBHC_REG_READ(WCD_MBHC_HPH_CNP_WG_TIME, wg_time); + wg_time += 1; + + mutex_lock(&mbhc->hphr_pa_lock); + if (test_and_clear_bit(WCD_MBHC_HPHR_PA_OFF_ACK, + &mbhc->hph_pa_dac_state)) { + pr_debug("%s: HPHR clear flag and enable PA\n", __func__); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHR_PA_EN, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHR_OCP_DET_EN, 1); + pa_turned_on = true; + } + mutex_unlock(&mbhc->hphr_pa_lock); + mutex_lock(&mbhc->hphl_pa_lock); + if (test_and_clear_bit(WCD_MBHC_HPHL_PA_OFF_ACK, + &mbhc->hph_pa_dac_state)) { + pr_debug("%s: HPHL clear flag and enable PA\n", __func__); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_PA_EN, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_OCP_DET_EN, 1); + pa_turned_on = true; + } + mutex_unlock(&mbhc->hphl_pa_lock); + + if (pa_turned_on) { + pr_debug("%s: PA was turned on by MBHC and not by DAPM\n", + __func__); + usleep_range(wg_time * 1000, wg_time * 1000 + 50); + } +} + +static bool wcd_mbhc_is_hph_pa_on(struct wcd_mbhc *mbhc) +{ + bool hph_pa_on = false; + + WCD_MBHC_REG_READ(WCD_MBHC_HPH_PA_EN, hph_pa_on); + + return (hph_pa_on) ? true : false; +} + +static void wcd_mbhc_set_and_turnoff_hph_padac(struct wcd_mbhc *mbhc) +{ + u8 wg_time = 0; + + WCD_MBHC_REG_READ(WCD_MBHC_HPH_CNP_WG_TIME, wg_time); + wg_time += 1; + + /* If headphone PA is on, check if userspace receives + * removal event to sync-up PA's state + */ + if (wcd_mbhc_is_hph_pa_on(mbhc)) { + pr_debug("%s PA is on, setting PA_OFF_ACK\n", __func__); + set_bit(WCD_MBHC_HPHL_PA_OFF_ACK, &mbhc->hph_pa_dac_state); + set_bit(WCD_MBHC_HPHR_PA_OFF_ACK, &mbhc->hph_pa_dac_state); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_OCP_DET_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHR_OCP_DET_EN, 0); + } else { + pr_debug("%s PA is off\n", __func__); + } + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPH_PA_EN, 0); + usleep_range(wg_time * 1000, wg_time * 1000 + 50); +} + +int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, + uint32_t *zr) +{ + *zl = mbhc->zl; + *zr = mbhc->zr; + + if (*zl && *zr) + return 0; + else + return -EINVAL; +} +EXPORT_SYMBOL(wcd_mbhc_get_impedance); + +void wcd_mbhc_hs_elec_irq(struct wcd_mbhc *mbhc, int irq_type, + bool enable) +{ + int irq; + + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + + if (irq_type == WCD_MBHC_ELEC_HS_INS) + irq = mbhc->intr_ids->mbhc_hs_ins_intr; + else if (irq_type == WCD_MBHC_ELEC_HS_REM) + irq = mbhc->intr_ids->mbhc_hs_rem_intr; + else { + pr_debug("%s: irq_type: %d, enable: %d\n", + __func__, irq_type, enable); + return; + } + + pr_debug("%s: irq: %d, enable: %d, intr_status:%lu\n", + __func__, irq, enable, mbhc->intr_status); + if ((test_bit(irq_type, &mbhc->intr_status)) != enable) { + mbhc->mbhc_cb->irq_control(mbhc->codec, irq, enable); + if (enable) + set_bit(irq_type, &mbhc->intr_status); + else + clear_bit(irq_type, &mbhc->intr_status); + } +} +EXPORT_SYMBOL(wcd_mbhc_hs_elec_irq); + +static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, + enum snd_jack_types jack_type) +{ + struct snd_soc_codec *codec = mbhc->codec; + bool is_pa_on = false; + u8 fsm_en = 0; + + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + + pr_debug("%s: enter insertion %d hph_status %x\n", + __func__, insertion, mbhc->hph_status); + if (!insertion) { + /* Report removal */ + mbhc->hph_status &= ~jack_type; + /* + * cancel possibly scheduled btn work and + * report release if we reported button press + */ + if (wcd_cancel_btn_work(mbhc)) { + pr_debug("%s: button press is canceled\n", __func__); + } else if (mbhc->buttons_pressed) { + pr_debug("%s: release of button press%d\n", + __func__, jack_type); + wcd_mbhc_jack_report(mbhc, &mbhc->button_jack, 0, + mbhc->buttons_pressed); + mbhc->buttons_pressed &= + ~WCD_MBHC_JACK_BUTTON_MASK; + } + + if (mbhc->micbias_enable) { + if (mbhc->mbhc_cb->mbhc_micbias_control) + mbhc->mbhc_cb->mbhc_micbias_control( + codec, MIC_BIAS_2, + MICB_DISABLE); + if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( + codec, + MIC_BIAS_2, false); + if (mbhc->mbhc_cb->set_micbias_value) { + mbhc->mbhc_cb->set_micbias_value(codec); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MICB_CTRL, 0); + } + mbhc->micbias_enable = false; + } + + mbhc->hph_type = WCD_MBHC_HPH_NONE; + mbhc->zl = mbhc->zr = 0; + pr_debug("%s: Reporting removal %d(%x)\n", __func__, + jack_type, mbhc->hph_status); + wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack, + mbhc->hph_status, WCD_MBHC_JACK_MASK); + wcd_mbhc_set_and_turnoff_hph_padac(mbhc); + hphrocp_off_report(mbhc, SND_JACK_OC_HPHR); + hphlocp_off_report(mbhc, SND_JACK_OC_HPHL); + mbhc->current_plug = MBHC_PLUG_TYPE_NONE; + } else { + /* + * Report removal of current jack type. + * Headphone to headset shouldn't report headphone + * removal. + */ + if (mbhc->mbhc_cfg->detect_extn_cable && + (mbhc->current_plug == MBHC_PLUG_TYPE_HIGH_HPH || + jack_type == SND_JACK_LINEOUT) && + (mbhc->hph_status && mbhc->hph_status != jack_type)) { + + if (mbhc->micbias_enable) { + if (mbhc->mbhc_cb->mbhc_micbias_control) + mbhc->mbhc_cb->mbhc_micbias_control( + codec, MIC_BIAS_2, + MICB_DISABLE); + if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( + codec, + MIC_BIAS_2, false); + if (mbhc->mbhc_cb->set_micbias_value) { + mbhc->mbhc_cb->set_micbias_value( + codec); + WCD_MBHC_REG_UPDATE_BITS( + WCD_MBHC_MICB_CTRL, 0); + } + mbhc->micbias_enable = false; + } + mbhc->hph_type = WCD_MBHC_HPH_NONE; + mbhc->zl = mbhc->zr = 0; + pr_debug("%s: Reporting removal (%x)\n", + __func__, mbhc->hph_status); + wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack, + 0, WCD_MBHC_JACK_MASK); + + if (mbhc->hph_status == SND_JACK_LINEOUT) { + + pr_debug("%s: Enable micbias\n", __func__); + /* Disable current source and enable micbias */ + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); + pr_debug("%s: set up elec removal detection\n", + __func__); + usleep_range(200, 210); + wcd_mbhc_hs_elec_irq(mbhc, + WCD_MBHC_ELEC_HS_REM, + true); + } + mbhc->hph_status &= ~(SND_JACK_HEADSET | + SND_JACK_LINEOUT | + SND_JACK_ANC_HEADPHONE | + SND_JACK_UNSUPPORTED); + } + + if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET && + jack_type == SND_JACK_HEADPHONE) + mbhc->hph_status &= ~SND_JACK_HEADSET; + + /* Report insertion */ + if (jack_type == SND_JACK_HEADPHONE) + mbhc->current_plug = MBHC_PLUG_TYPE_HEADPHONE; + else if (jack_type == SND_JACK_UNSUPPORTED) + mbhc->current_plug = MBHC_PLUG_TYPE_GND_MIC_SWAP; + else if (jack_type == SND_JACK_HEADSET) { + mbhc->current_plug = MBHC_PLUG_TYPE_HEADSET; + mbhc->jiffies_atreport = jiffies; + } else if (jack_type == SND_JACK_LINEOUT) { + mbhc->current_plug = MBHC_PLUG_TYPE_HIGH_HPH; + } else if (jack_type == SND_JACK_ANC_HEADPHONE) + mbhc->current_plug = MBHC_PLUG_TYPE_ANC_HEADPHONE; + + if (mbhc->mbhc_cb->hph_pa_on_status) + is_pa_on = mbhc->mbhc_cb->hph_pa_on_status(codec); + + if (mbhc->impedance_detect && + mbhc->mbhc_cb->compute_impedance && + (mbhc->mbhc_cfg->linein_th != 0) && + (!is_pa_on)) { + /* Set MUX_CTL to AUTO for Z-det */ + WCD_MBHC_REG_READ(WCD_MBHC_FSM_EN, fsm_en); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MUX_CTL, + MUX_CTL_AUTO); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); + mbhc->mbhc_cb->compute_impedance(mbhc, + &mbhc->zl, &mbhc->zr); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, + fsm_en); + if ((mbhc->zl > mbhc->mbhc_cfg->linein_th && + mbhc->zl < MAX_IMPED) && + (mbhc->zr > mbhc->mbhc_cfg->linein_th && + mbhc->zr < MAX_IMPED) && + (jack_type == SND_JACK_HEADPHONE)) { + jack_type = SND_JACK_LINEOUT; + mbhc->current_plug = MBHC_PLUG_TYPE_HIGH_HPH; + if (mbhc->hph_status) { + mbhc->hph_status &= ~(SND_JACK_HEADSET | + SND_JACK_LINEOUT | + SND_JACK_UNSUPPORTED); + wcd_mbhc_jack_report(mbhc, + &mbhc->headset_jack, + mbhc->hph_status, + WCD_MBHC_JACK_MASK); + } + pr_debug("%s: Marking jack type as SND_JACK_LINEOUT\n", + __func__); + } + } + + mbhc->hph_status |= jack_type; + + pr_debug("%s: Reporting insertion %d(%x)\n", __func__, + jack_type, mbhc->hph_status); + wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack, + (mbhc->hph_status | SND_JACK_MECHANICAL), + WCD_MBHC_JACK_MASK); + wcd_mbhc_clr_and_turnon_hph_padac(mbhc); + } + pr_debug("%s: leave hph_status %x\n", __func__, mbhc->hph_status); +} + +void wcd_mbhc_elec_hs_report_unplug(struct wcd_mbhc *mbhc) +{ + /* cancel pending button press */ + if (wcd_cancel_btn_work(mbhc)) + pr_debug("%s: button press is canceled\n", __func__); + /* cancel correct work function */ + if (mbhc->mbhc_fn->wcd_cancel_hs_detect_plug) + mbhc->mbhc_fn->wcd_cancel_hs_detect_plug(mbhc, + &mbhc->correct_plug_swch); + else + pr_info("%s: hs_detect_plug work not cancelled\n", __func__); + + pr_debug("%s: Report extension cable\n", __func__); + wcd_mbhc_report_plug(mbhc, 1, SND_JACK_LINEOUT); + /* + * If PA is enabled HPHL schmitt trigger can + * be unreliable, make sure to disable it + */ + if (test_bit(WCD_MBHC_EVENT_PA_HPHL, + &mbhc->event_state)) + wcd_mbhc_set_and_turnoff_hph_padac(mbhc); + /* + * Disable HPHL trigger and MIC Schmitt triggers. + * Setup for insertion detection. + */ + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_REM, + false); + wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_NONE); + /* Disable HW FSM */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 3); + + /* Set the detection type appropriately */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_DETECTION_TYPE, 1); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, + true); +} +EXPORT_SYMBOL(wcd_mbhc_elec_hs_report_unplug); + +void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc, + enum wcd_mbhc_plug_type plug_type) +{ + bool anc_mic_found = false; + enum snd_jack_types jack_type; + + pr_debug("%s: enter current_plug(%d) new_plug(%d)\n", + __func__, mbhc->current_plug, plug_type); + + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + + if (mbhc->current_plug == plug_type) { + pr_debug("%s: cable already reported, exit\n", __func__); + goto exit; + } + + if (plug_type == MBHC_PLUG_TYPE_HEADPHONE) { + /* + * Nothing was reported previously + * report a headphone or unsupported + */ + wcd_mbhc_report_plug(mbhc, 1, SND_JACK_HEADPHONE); + } else if (plug_type == MBHC_PLUG_TYPE_GND_MIC_SWAP) { + if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) + wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADPHONE); + if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET) + wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADSET); + wcd_mbhc_report_plug(mbhc, 1, SND_JACK_UNSUPPORTED); + } else if (plug_type == MBHC_PLUG_TYPE_HEADSET) { + if (mbhc->mbhc_cfg->enable_anc_mic_detect && + mbhc->mbhc_fn->wcd_mbhc_detect_anc_plug_type) + anc_mic_found = + mbhc->mbhc_fn->wcd_mbhc_detect_anc_plug_type(mbhc); + jack_type = SND_JACK_HEADSET; + if (anc_mic_found) + jack_type = SND_JACK_ANC_HEADPHONE; + + /* + * If Headphone was reported previously, this will + * only report the mic line + */ + wcd_mbhc_report_plug(mbhc, 1, jack_type); + } else if (plug_type == MBHC_PLUG_TYPE_HIGH_HPH) { + if (mbhc->mbhc_cfg->detect_extn_cable) { + /* High impedance device found. Report as LINEOUT */ + wcd_mbhc_report_plug(mbhc, 1, SND_JACK_LINEOUT); + pr_debug("%s: setup mic trigger for further detection\n", + __func__); + + /* Disable HW FSM and current source */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0); + /* Setup for insertion detection */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_DETECTION_TYPE, + 1); + /* + * Enable HPHL trigger and MIC Schmitt triggers + * and request for elec insertion interrupts + */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, + 3); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, + true); + } else { + wcd_mbhc_report_plug(mbhc, 1, SND_JACK_LINEOUT); + } + } else { + WARN(1, "Unexpected current plug_type %d, plug_type %d\n", + mbhc->current_plug, plug_type); + } +exit: + pr_debug("%s: leave\n", __func__); +} +EXPORT_SYMBOL(wcd_mbhc_find_plug_and_report); + +static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) +{ + bool detection_type = 0; + bool micbias1 = false; + struct snd_soc_codec *codec = mbhc->codec; + enum snd_jack_types jack_type; + + dev_dbg(codec->dev, "%s: enter\n", __func__); + WCD_MBHC_RSC_LOCK(mbhc); + mbhc->in_swch_irq_handler = true; + + /* cancel pending button press */ + if (wcd_cancel_btn_work(mbhc)) + pr_debug("%s: button press is canceled\n", __func__); + + WCD_MBHC_REG_READ(WCD_MBHC_MECH_DETECTION_TYPE, detection_type); + + /* Set the detection type appropriately */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MECH_DETECTION_TYPE, + !detection_type); + + pr_debug("%s: mbhc->current_plug: %d detection_type: %d\n", __func__, + mbhc->current_plug, detection_type); + if (mbhc->mbhc_fn->wcd_cancel_hs_detect_plug) + mbhc->mbhc_fn->wcd_cancel_hs_detect_plug(mbhc, + &mbhc->correct_plug_swch); + else + pr_info("%s: hs_detect_plug work not cancelled\n", __func__); + + if (mbhc->mbhc_cb->micbias_enable_status) + micbias1 = mbhc->mbhc_cb->micbias_enable_status(mbhc, + MIC_BIAS_1); + + if ((mbhc->current_plug == MBHC_PLUG_TYPE_NONE) && + detection_type) { + /* Make sure MASTER_BIAS_CTL is enabled */ + mbhc->mbhc_cb->mbhc_bias(codec, true); + + if (mbhc->mbhc_cb->mbhc_common_micb_ctrl) + mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, + MBHC_COMMON_MICB_TAIL_CURR, true); + + if (!mbhc->mbhc_cfg->hs_ext_micbias && + mbhc->mbhc_cb->micb_internal) + /* + * Enable Tx2 RBias if the headset + * is using internal micbias + */ + mbhc->mbhc_cb->micb_internal(codec, 1, true); + + /* Remove micbias pulldown */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_PULLDOWN_CTRL, 0); + /* Apply trim if needed on the device */ + if (mbhc->mbhc_cb->trim_btn_reg) + mbhc->mbhc_cb->trim_btn_reg(codec); + /* Enable external voltage source to micbias if present */ + if (mbhc->mbhc_cb->enable_mb_source) + mbhc->mbhc_cb->enable_mb_source(mbhc, true); + mbhc->btn_press_intr = false; + mbhc->is_btn_press = false; + if (mbhc->mbhc_fn) + mbhc->mbhc_fn->wcd_mbhc_detect_plug_type(mbhc); + } else if ((mbhc->current_plug != MBHC_PLUG_TYPE_NONE) + && !detection_type) { + /* Disable external voltage source to micbias if present */ + if (mbhc->mbhc_cb->enable_mb_source) + mbhc->mbhc_cb->enable_mb_source(mbhc, false); + /* Disable HW FSM */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0); + if (mbhc->mbhc_cb->mbhc_common_micb_ctrl) + mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, + MBHC_COMMON_MICB_TAIL_CURR, false); + + if (mbhc->mbhc_cb->set_cap_mode) + mbhc->mbhc_cb->set_cap_mode(codec, micbias1, false); + + mbhc->btn_press_intr = false; + mbhc->is_btn_press = false; + switch (mbhc->current_plug) { + case MBHC_PLUG_TYPE_HEADPHONE: + jack_type = SND_JACK_HEADPHONE; + break; + case MBHC_PLUG_TYPE_GND_MIC_SWAP: + jack_type = SND_JACK_UNSUPPORTED; + break; + case MBHC_PLUG_TYPE_HEADSET: + /* make sure to turn off Rbias */ + if (mbhc->mbhc_cb->micb_internal) + mbhc->mbhc_cb->micb_internal(codec, 1, false); + /* Pulldown micbias */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_PULLDOWN_CTRL, 1); + jack_type = SND_JACK_HEADSET; + break; + case MBHC_PLUG_TYPE_HIGH_HPH: + mbhc->is_extn_cable = false; + jack_type = SND_JACK_LINEOUT; + break; + case MBHC_PLUG_TYPE_ANC_HEADPHONE: + jack_type = SND_JACK_ANC_HEADPHONE; + break; + default: + pr_info("%s: Invalid current plug: %d\n", + __func__, mbhc->current_plug); + jack_type = SND_JACK_UNSUPPORTED; + break; + } + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_REM, false); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, false); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_DETECTION_TYPE, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0); + mbhc->extn_cable_hph_rem = false; + wcd_mbhc_report_plug(mbhc, 0, jack_type); + + } else if (!detection_type) { + /* Disable external voltage source to micbias if present */ + if (mbhc->mbhc_cb->enable_mb_source) + mbhc->mbhc_cb->enable_mb_source(mbhc, false); + /* Disable HW FSM */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0); + mbhc->extn_cable_hph_rem = false; + } + + mbhc->in_swch_irq_handler = false; + WCD_MBHC_RSC_UNLOCK(mbhc); + pr_debug("%s: leave\n", __func__); +} + +static irqreturn_t wcd_mbhc_mech_plug_detect_irq(int irq, void *data) +{ + int r = IRQ_HANDLED; + struct wcd_mbhc *mbhc = data; + + pr_debug("%s: enter\n", __func__); + if (unlikely((mbhc->mbhc_cb->lock_sleep(mbhc, true)) == false)) { + pr_warn("%s: failed to hold suspend\n", __func__); + r = IRQ_NONE; + } else { + /* Call handler */ + wcd_mbhc_swch_irq_handler(mbhc); + mbhc->mbhc_cb->lock_sleep(mbhc, false); + } + pr_debug("%s: leave %d\n", __func__, r); + return r; +} + +int wcd_mbhc_get_button_mask(struct wcd_mbhc *mbhc) +{ + int mask = 0; + int btn; + + btn = mbhc->mbhc_cb->map_btn_code_to_num(mbhc->codec); + + switch (btn) { + case 0: + mask = SND_JACK_BTN_0; + break; + case 1: + mask = SND_JACK_BTN_1; + break; + case 2: + mask = SND_JACK_BTN_2; + break; + case 3: + mask = SND_JACK_BTN_3; + break; + case 4: + mask = SND_JACK_BTN_4; + break; + case 5: + mask = SND_JACK_BTN_5; + break; + default: + break; + } + + return mask; +} +EXPORT_SYMBOL(wcd_mbhc_get_button_mask); + +static void wcd_btn_lpress_fn(struct work_struct *work) +{ + struct delayed_work *dwork; + struct wcd_mbhc *mbhc; + s16 btn_result = 0; + + pr_debug("%s: Enter\n", __func__); + + dwork = to_delayed_work(work); + mbhc = container_of(dwork, struct wcd_mbhc, mbhc_btn_dwork); + + WCD_MBHC_REG_READ(WCD_MBHC_BTN_RESULT, btn_result); + if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET) { + pr_debug("%s: Reporting long button press event, btn_result: %d\n", + __func__, btn_result); + wcd_mbhc_jack_report(mbhc, &mbhc->button_jack, + mbhc->buttons_pressed, mbhc->buttons_pressed); + } + pr_debug("%s: leave\n", __func__); + mbhc->mbhc_cb->lock_sleep(mbhc, false); +} + +static bool wcd_mbhc_fw_validate(const void *data, size_t size) +{ + u32 cfg_offset; + struct wcd_mbhc_btn_detect_cfg *btn_cfg; + struct firmware_cal fw; + + fw.data = (void *)data; + fw.size = size; + + if (fw.size < WCD_MBHC_CAL_MIN_SIZE) + return false; + + /* + * Previous check guarantees that there is enough fw data up + * to num_btn + */ + btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(fw.data); + cfg_offset = (u32) ((void *) btn_cfg - (void *) fw.data); + if (fw.size < (cfg_offset + WCD_MBHC_CAL_BTN_SZ(btn_cfg))) + return false; + + return true; +} + +static irqreturn_t wcd_mbhc_btn_press_handler(int irq, void *data) +{ + struct wcd_mbhc *mbhc = data; + int mask; + unsigned long msec_val; + + pr_debug("%s: enter\n", __func__); + complete(&mbhc->btn_press_compl); + WCD_MBHC_RSC_LOCK(mbhc); + wcd_cancel_btn_work(mbhc); + if (wcd_swch_level_remove(mbhc)) { + pr_debug("%s: Switch level is low ", __func__); + goto done; + } + + mbhc->is_btn_press = true; + msec_val = jiffies_to_msecs(jiffies - mbhc->jiffies_atreport); + pr_debug("%s: msec_val = %ld\n", __func__, msec_val); + if (msec_val < MBHC_BUTTON_PRESS_THRESHOLD_MIN) { + pr_debug("%s: Too short, ignore button press\n", __func__); + goto done; + } + + /* If switch interrupt already kicked in, ignore button press */ + if (mbhc->in_swch_irq_handler) { + pr_debug("%s: Swtich level changed, ignore button press\n", + __func__); + goto done; + } + mask = wcd_mbhc_get_button_mask(mbhc); + if (mask == SND_JACK_BTN_0) + mbhc->btn_press_intr = true; + + if (mbhc->current_plug != MBHC_PLUG_TYPE_HEADSET) { + pr_debug("%s: Plug isn't headset, ignore button press\n", + __func__); + goto done; + } + mbhc->buttons_pressed |= mask; + mbhc->mbhc_cb->lock_sleep(mbhc, true); + if (schedule_delayed_work(&mbhc->mbhc_btn_dwork, + msecs_to_jiffies(400)) == 0) { + WARN(1, "Button pressed twice without release event\n"); + mbhc->mbhc_cb->lock_sleep(mbhc, false); + } +done: + pr_debug("%s: leave\n", __func__); + WCD_MBHC_RSC_UNLOCK(mbhc); + return IRQ_HANDLED; +} + +static irqreturn_t wcd_mbhc_release_handler(int irq, void *data) +{ + struct wcd_mbhc *mbhc = data; + int ret; + + pr_debug("%s: enter\n", __func__); + WCD_MBHC_RSC_LOCK(mbhc); + if (wcd_swch_level_remove(mbhc)) { + pr_debug("%s: Switch level is low ", __func__); + goto exit; + } + + if (mbhc->is_btn_press) { + mbhc->is_btn_press = false; + } else { + pr_debug("%s: This release is for fake btn press\n", __func__); + goto exit; + } + + /* + * If current plug is headphone then there is no chance to + * get btn release interrupt, so connected cable should be + * headset not headphone. + * For ADC MBHC, ADC_COMPLETE interrupt will be generated + * in this case. So skip the check here. + */ + if (!WCD_MBHC_DETECTION && + mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) { + wcd_mbhc_find_plug_and_report(mbhc, MBHC_PLUG_TYPE_HEADSET); + goto exit; + + } + if (mbhc->buttons_pressed & WCD_MBHC_JACK_BUTTON_MASK) { + ret = wcd_cancel_btn_work(mbhc); + if (ret == 0) { + pr_debug("%s: Reporting long button release event\n", + __func__); + wcd_mbhc_jack_report(mbhc, &mbhc->button_jack, + 0, mbhc->buttons_pressed); + } else { + if (mbhc->in_swch_irq_handler) { + pr_debug("%s: Switch irq kicked in, ignore\n", + __func__); + } else { + pr_debug("%s: Reporting btn press\n", + __func__); + wcd_mbhc_jack_report(mbhc, + &mbhc->button_jack, + mbhc->buttons_pressed, + mbhc->buttons_pressed); + pr_debug("%s: Reporting btn release\n", + __func__); + wcd_mbhc_jack_report(mbhc, + &mbhc->button_jack, + 0, mbhc->buttons_pressed); + } + } + mbhc->buttons_pressed &= ~WCD_MBHC_JACK_BUTTON_MASK; + } +exit: + pr_debug("%s: leave\n", __func__); + WCD_MBHC_RSC_UNLOCK(mbhc); + return IRQ_HANDLED; +} + +static irqreturn_t wcd_mbhc_hphl_ocp_irq(int irq, void *data) +{ + struct wcd_mbhc *mbhc = data; + int val; + + pr_debug("%s: received HPHL OCP irq\n", __func__); + if (mbhc) { + if (mbhc->mbhc_cb->hph_register_recovery) { + if (mbhc->mbhc_cb->hph_register_recovery(mbhc)) { + WCD_MBHC_REG_READ(WCD_MBHC_HPHR_OCP_STATUS, + val); + if ((val != -EINVAL) && val) + mbhc->is_hph_ocp_pending = true; + goto done; + } + } + + if (mbhc->hphlocp_cnt < OCP_ATTEMPT) { + mbhc->hphlocp_cnt++; + pr_debug("%s: retry, hphlocp_cnt: %d\n", __func__, + mbhc->hphlocp_cnt); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_OCP_FSM_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_OCP_FSM_EN, 1); + } else { + mbhc->mbhc_cb->irq_control(mbhc->codec, + mbhc->intr_ids->hph_left_ocp, + false); + mbhc->hph_status |= SND_JACK_OC_HPHL; + wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack, + mbhc->hph_status, + WCD_MBHC_JACK_MASK); + } + } else { + pr_err("%s: Bad wcd9xxx_spmi private data\n", __func__); + } +done: + return IRQ_HANDLED; +} + +static irqreturn_t wcd_mbhc_hphr_ocp_irq(int irq, void *data) +{ + struct wcd_mbhc *mbhc = data; + + pr_debug("%s: received HPHR OCP irq\n", __func__); + + if (!mbhc) { + pr_err("%s: Bad mbhc private data\n", __func__); + goto done; + } + + if (mbhc->is_hph_ocp_pending) { + mbhc->is_hph_ocp_pending = false; + goto done; + } + + if (mbhc->mbhc_cb->hph_register_recovery) { + if (mbhc->mbhc_cb->hph_register_recovery(mbhc)) + /* register corruption, hence reset registers */ + goto done; + } + if (mbhc->hphrocp_cnt < OCP_ATTEMPT) { + mbhc->hphrocp_cnt++; + pr_debug("%s: retry, hphrocp_cnt: %d\n", __func__, + mbhc->hphrocp_cnt); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_OCP_FSM_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_OCP_FSM_EN, 1); + } else { + mbhc->mbhc_cb->irq_control(mbhc->codec, + mbhc->intr_ids->hph_right_ocp, + false); + mbhc->hph_status |= SND_JACK_OC_HPHR; + wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack, + mbhc->hph_status, WCD_MBHC_JACK_MASK); + } +done: + return IRQ_HANDLED; +} + +static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) +{ + int ret = 0; + struct snd_soc_codec *codec = mbhc->codec; + + pr_debug("%s: enter\n", __func__); + WCD_MBHC_RSC_LOCK(mbhc); + + /* enable HS detection */ + if (mbhc->mbhc_cb->hph_pull_up_control) + mbhc->mbhc_cb->hph_pull_up_control(codec, I_DEFAULT); + else + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, 3); + + if (mbhc->mbhc_cfg->moisture_en && mbhc->mbhc_cb->mbhc_moisture_config) + mbhc->mbhc_cb->mbhc_moisture_config(mbhc); + + /* + * For USB analog we need to override the switch configuration. + * Also, disable hph_l pull-up current source as HS_DET_L is driven + * by an external source + */ + if (mbhc->mbhc_cfg->enable_usbc_analog) { + mbhc->hphl_swh = 1; + mbhc->gnd_swh = 1; + + if (mbhc->mbhc_cb->hph_pull_up_control) + mbhc->mbhc_cb->hph_pull_up_control(codec, I_OFF); + else + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, + 0); + } + + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_PLUG_TYPE, mbhc->hphl_swh); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_GND_PLUG_TYPE, mbhc->gnd_swh); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_SW_HPH_LP_100K_TO_GND, 1); + if (mbhc->mbhc_cfg->gnd_det_en && mbhc->mbhc_cb->mbhc_gnd_det_ctrl) + mbhc->mbhc_cb->mbhc_gnd_det_ctrl(codec, true); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1); + + if (mbhc->mbhc_cfg->enable_usbc_analog) { + /* Insertion debounce set to 48ms */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_INSREM_DBNC, 4); + } else { + /* Insertion debounce set to 96ms */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_INSREM_DBNC, 6); + } + + /* Button Debounce set to 16ms */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_DBNC, 2); + + /* Enable micbias ramp */ + if (mbhc->mbhc_cb->mbhc_micb_ramp_control) + mbhc->mbhc_cb->mbhc_micb_ramp_control(codec, true); + /* enable bias */ + mbhc->mbhc_cb->mbhc_bias(codec, true); + /* enable MBHC clock */ + if (mbhc->mbhc_cb->clk_setup) + mbhc->mbhc_cb->clk_setup(codec, true); + + /* program HS_VREF value */ + wcd_program_hs_vref(mbhc); + + wcd_program_btn_threshold(mbhc, false); + + + reinit_completion(&mbhc->btn_press_compl); + + WCD_MBHC_RSC_UNLOCK(mbhc); + pr_debug("%s: leave\n", __func__); + return ret; +} + +static void wcd_mbhc_fw_read(struct work_struct *work) +{ + struct delayed_work *dwork; + struct wcd_mbhc *mbhc; + struct snd_soc_codec *codec; + const struct firmware *fw; + struct firmware_cal *fw_data = NULL; + int ret = -1, retry = 0; + bool use_default_cal = false; + + dwork = to_delayed_work(work); + mbhc = container_of(dwork, struct wcd_mbhc, mbhc_firmware_dwork); + codec = mbhc->codec; + + while (retry < FW_READ_ATTEMPTS) { + retry++; + pr_debug("%s:Attempt %d to request MBHC firmware\n", + __func__, retry); + if (mbhc->mbhc_cb->get_hwdep_fw_cal) + fw_data = mbhc->mbhc_cb->get_hwdep_fw_cal(mbhc, + WCD9XXX_MBHC_CAL); + if (!fw_data) + ret = request_firmware(&fw, "wcd9320/wcd9320_mbhc.bin", + codec->dev); + /* + * if request_firmware and hwdep cal both fail then + * sleep for 4sec for the userspace to send data to kernel + * retry for few times before bailing out + */ + if ((ret != 0) && !fw_data) { + usleep_range(FW_READ_TIMEOUT, FW_READ_TIMEOUT + + WCD_MBHC_USLEEP_RANGE_MARGIN_US); + } else { + pr_debug("%s: MBHC Firmware read successful\n", + __func__); + break; + } + } + if (!fw_data) + pr_debug("%s: using request_firmware\n", __func__); + else + pr_debug("%s: using hwdep cal\n", __func__); + + if (ret != 0 && !fw_data) { + pr_err("%s: Cannot load MBHC firmware use default cal\n", + __func__); + use_default_cal = true; + } + if (!use_default_cal) { + const void *data; + size_t size; + + if (fw_data) { + data = fw_data->data; + size = fw_data->size; + } else { + data = fw->data; + size = fw->size; + } + if (wcd_mbhc_fw_validate(data, size) == false) { + pr_err("%s: Invalid MBHC cal data size use default cal\n", + __func__); + if (!fw_data) + release_firmware(fw); + } else { + if (fw_data) { + mbhc->mbhc_cfg->calibration = + (void *)fw_data->data; + mbhc->mbhc_cal = fw_data; + } else { + mbhc->mbhc_cfg->calibration = + (void *)fw->data; + mbhc->mbhc_fw = fw; + } + } + + } + + (void) wcd_mbhc_initialise(mbhc); +} + +static int wcd_mbhc_set_keycode(struct wcd_mbhc *mbhc) +{ + enum snd_jack_types type; + int i, ret, result = 0; + int *btn_key_code; + + btn_key_code = mbhc->mbhc_cfg->key_code; + + for (i = 0 ; i < WCD_MBHC_KEYCODE_NUM ; i++) { + if (btn_key_code[i] != 0) { + switch (i) { + case 0: + type = SND_JACK_BTN_0; + break; + case 1: + type = SND_JACK_BTN_1; + break; + case 2: + type = SND_JACK_BTN_2; + break; + case 3: + type = SND_JACK_BTN_3; + break; + case 4: + type = SND_JACK_BTN_4; + break; + case 5: + type = SND_JACK_BTN_5; + break; + default: + WARN_ONCE(1, "Wrong button number:%d\n", i); + result = -1; + return result; + } + ret = snd_jack_set_key(mbhc->button_jack.jack, + type, + btn_key_code[i]); + if (ret) { + pr_err("%s: Failed to set code for %d\n", + __func__, btn_key_code[i]); + result = -1; + return result; + } + input_set_capability( + mbhc->button_jack.jack->input_dev, + EV_KEY, btn_key_code[i]); + pr_debug("%s: set btn%d key code:%d\n", __func__, + i, btn_key_code[i]); + } + } + if (btn_key_code[0]) + mbhc->is_btn_already_regd = true; + return result; +} + +static int wcd_mbhc_usb_c_analog_setup_gpios(struct wcd_mbhc *mbhc, + bool active) +{ + int rc = 0; + struct usbc_ana_audio_config *config = + &mbhc->mbhc_cfg->usbc_analog_cfg; + union power_supply_propval pval; + + dev_dbg(mbhc->codec->dev, "%s: setting GPIOs active = %d\n", + __func__, active); + + memset(&pval, 0, sizeof(pval)); + + if (active) { + pval.intval = POWER_SUPPLY_TYPEC_PR_SOURCE; + if (power_supply_set_property(mbhc->usb_psy, + POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &pval)) + dev_info(mbhc->codec->dev, "%s: force PR_SOURCE mode unsuccessful\n", + __func__); + else + mbhc->usbc_force_pr_mode = true; + + if (config->usbc_en1_gpio_p) + rc = msm_cdc_pinctrl_select_active_state( + config->usbc_en1_gpio_p); + if (rc == 0 && config->usbc_force_gpio_p) + rc = msm_cdc_pinctrl_select_active_state( + config->usbc_force_gpio_p); + mbhc->usbc_mode = POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER; + } else { + /* no delay is required when disabling GPIOs */ + if (config->usbc_en1_gpio_p) + msm_cdc_pinctrl_select_sleep_state( + config->usbc_en1_gpio_p); + if (config->usbc_force_gpio_p) + msm_cdc_pinctrl_select_sleep_state( + config->usbc_force_gpio_p); + + if (mbhc->usbc_force_pr_mode) { + pval.intval = POWER_SUPPLY_TYPEC_PR_DUAL; + if (power_supply_set_property(mbhc->usb_psy, + POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &pval)) + dev_info(mbhc->codec->dev, "%s: force PR_DUAL mode unsuccessful\n", + __func__); + + mbhc->usbc_force_pr_mode = false; + } + + mbhc->usbc_mode = POWER_SUPPLY_TYPEC_NONE; + if (mbhc->mbhc_cfg->swap_gnd_mic) + mbhc->mbhc_cfg->swap_gnd_mic(mbhc->codec, false); + } + + return rc; +} + +/* workqueue */ +static void wcd_mbhc_usbc_analog_work_fn(struct work_struct *work) +{ + struct wcd_mbhc *mbhc = + container_of(work, struct wcd_mbhc, usbc_analog_work); + + wcd_mbhc_usb_c_analog_setup_gpios(mbhc, + mbhc->usbc_mode != POWER_SUPPLY_TYPEC_NONE); +} + +/* this callback function is used to process PMI notification */ +static int wcd_mbhc_usb_c_event_changed(struct notifier_block *nb, + unsigned long evt, void *ptr) +{ + int ret; + union power_supply_propval mode; + struct wcd_mbhc *mbhc = container_of(nb, struct wcd_mbhc, psy_nb); + struct snd_soc_codec *codec = mbhc->codec; + + if (ptr != mbhc->usb_psy || evt != PSY_EVENT_PROP_CHANGED) + return 0; + + ret = power_supply_get_property(mbhc->usb_psy, + POWER_SUPPLY_PROP_TYPEC_MODE, &mode); + if (ret) { + dev_err(codec->dev, "%s: Unable to read USB TYPEC_MODE: %d\n", + __func__, ret); + return ret; + } + + dev_dbg(codec->dev, "%s: USB change event received\n", + __func__); + dev_dbg(codec->dev, "%s: supply mode %d, expected %d\n", __func__, + mode.intval, POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER); + + switch (mode.intval) { + case POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER: + case POWER_SUPPLY_TYPEC_NONE: + dev_dbg(codec->dev, "%s: usbc_mode: %d; mode.intval: %d\n", + __func__, mbhc->usbc_mode, mode.intval); + + if (mbhc->usbc_mode == mode.intval) + break; /* filter notifications received before */ + mbhc->usbc_mode = mode.intval; + + dev_dbg(codec->dev, "%s: queueing usbc_analog_work\n", + __func__); + schedule_work(&mbhc->usbc_analog_work); + break; + default: + break; + } + return ret; +} + +/* PMI registration code */ +static int wcd_mbhc_usb_c_analog_init(struct wcd_mbhc *mbhc) +{ + int ret = 0; + struct snd_soc_codec *codec = mbhc->codec; + + dev_dbg(mbhc->codec->dev, "%s: usb-c analog setup start\n", __func__); + INIT_WORK(&mbhc->usbc_analog_work, wcd_mbhc_usbc_analog_work_fn); + + mbhc->usb_psy = power_supply_get_by_name("usb"); + if (IS_ERR_OR_NULL(mbhc->usb_psy)) { + dev_err(codec->dev, "%s: could not get USB psy info\n", + __func__); + ret = -EPROBE_DEFER; + if (IS_ERR(mbhc->usb_psy)) + ret = PTR_ERR(mbhc->usb_psy); + mbhc->usb_psy = NULL; + goto err; + } + + ret = wcd_mbhc_usb_c_analog_setup_gpios(mbhc, false); + if (ret) { + dev_err(codec->dev, "%s: error while setting USBC ana gpios\n", + __func__); + goto err; + } + + mbhc->psy_nb.notifier_call = wcd_mbhc_usb_c_event_changed; + mbhc->psy_nb.priority = 0; + ret = power_supply_reg_notifier(&mbhc->psy_nb); + if (ret) { + dev_err(codec->dev, "%s: power supply registration failed\n", + __func__); + goto err; + } + + /* + * as part of the init sequence check if there is a connected + * USB C analog adapter + */ + dev_dbg(mbhc->codec->dev, "%s: verify if USB adapter is already inserted\n", + __func__); + ret = wcd_mbhc_usb_c_event_changed(&mbhc->psy_nb, + PSY_EVENT_PROP_CHANGED, + mbhc->usb_psy); + +err: + return ret; +} + +static int wcd_mbhc_usb_c_analog_deinit(struct wcd_mbhc *mbhc) +{ + wcd_mbhc_usb_c_analog_setup_gpios(mbhc, false); + + /* deregister from PMI */ + power_supply_unreg_notifier(&mbhc->psy_nb); + + return 0; +} + +static int wcd_mbhc_init_gpio(struct wcd_mbhc *mbhc, + struct wcd_mbhc_config *mbhc_cfg, + const char *gpio_dt_str, + int *gpio, struct device_node **gpio_dn) +{ + int rc = 0; + struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_card *card = codec->component.card; + + dev_dbg(mbhc->codec->dev, "%s: gpio %s\n", __func__, gpio_dt_str); + + *gpio_dn = of_parse_phandle(card->dev->of_node, gpio_dt_str, 0); + + if (!(*gpio_dn)) { + *gpio = of_get_named_gpio(card->dev->of_node, gpio_dt_str, 0); + if (!gpio_is_valid(*gpio)) { + dev_err(card->dev, "%s, property %s not in node %s", + __func__, gpio_dt_str, + card->dev->of_node->full_name); + rc = -EINVAL; + } + } + + return rc; +} + +int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) +{ + int rc = 0; + struct usbc_ana_audio_config *config; + struct snd_soc_codec *codec; + struct snd_soc_card *card; + const char *usb_c_dt = "qcom,msm-mbhc-usbc-audio-supported"; + + if (!mbhc || !mbhc_cfg) + return -EINVAL; + + config = &mbhc_cfg->usbc_analog_cfg; + codec = mbhc->codec; + card = codec->component.card; + + /* update the mbhc config */ + mbhc->mbhc_cfg = mbhc_cfg; + + dev_dbg(mbhc->codec->dev, "%s: enter\n", __func__); + + /* check if USB C analog is defined on device tree */ + mbhc_cfg->enable_usbc_analog = 0; + if (of_find_property(card->dev->of_node, usb_c_dt, NULL)) { + rc = of_property_read_u32(card->dev->of_node, usb_c_dt, + &mbhc_cfg->enable_usbc_analog); + } + if (mbhc_cfg->enable_usbc_analog == 0 || rc != 0) { + dev_info(card->dev, + "%s: %s in dt node is missing or false\n", + __func__, usb_c_dt); + dev_info(card->dev, + "%s: skipping USB c analog configuration\n", __func__); + } + + /* initialize GPIOs */ + if (mbhc_cfg->enable_usbc_analog) { + dev_dbg(mbhc->codec->dev, "%s: usbc analog enabled\n", + __func__); + rc = wcd_mbhc_init_gpio(mbhc, mbhc_cfg, + "qcom,usbc-analog-en1-gpio", + &config->usbc_en1_gpio, + &config->usbc_en1_gpio_p); + if (rc) + goto err; + + if (of_find_property(card->dev->of_node, + "qcom,usbc-analog-force_detect_gpio", + NULL)) { + rc = wcd_mbhc_init_gpio(mbhc, mbhc_cfg, + "qcom,usbc-analog-force_detect_gpio", + &config->usbc_force_gpio, + &config->usbc_force_gpio_p); + if (rc) + goto err; + } + + dev_dbg(mbhc->codec->dev, "%s: calling usb_c_analog_init\n", + __func__); + /* init PMI notifier */ + rc = wcd_mbhc_usb_c_analog_init(mbhc); + if (rc) { + rc = EPROBE_DEFER; + goto err; + } + } + + /* Set btn key code */ + if ((!mbhc->is_btn_already_regd) && wcd_mbhc_set_keycode(mbhc)) + pr_err("Set btn key code error!!!\n"); + + if (!mbhc->mbhc_cfg->read_fw_bin || + (mbhc->mbhc_cfg->read_fw_bin && mbhc->mbhc_fw) || + (mbhc->mbhc_cfg->read_fw_bin && mbhc->mbhc_cal)) { + rc = wcd_mbhc_initialise(mbhc); + } else { + if (!mbhc->mbhc_fw || !mbhc->mbhc_cal) + schedule_delayed_work(&mbhc->mbhc_firmware_dwork, + usecs_to_jiffies(FW_READ_TIMEOUT)); + else + pr_err("%s: Skipping to read mbhc fw, 0x%pK %pK\n", + __func__, mbhc->mbhc_fw, mbhc->mbhc_cal); + } + + return rc; +err: + if (config->usbc_en1_gpio > 0) { + dev_dbg(card->dev, "%s free usb en1 gpio %d\n", + __func__, config->usbc_en1_gpio); + gpio_free(config->usbc_en1_gpio); + config->usbc_en1_gpio = 0; + } + if (config->usbc_force_gpio > 0) { + dev_dbg(card->dev, "%s free usb_force gpio %d\n", + __func__, config->usbc_force_gpio); + gpio_free(config->usbc_force_gpio); + config->usbc_force_gpio = 0; + } + if (config->usbc_en1_gpio_p) + of_node_put(config->usbc_en1_gpio_p); + if (config->usbc_force_gpio_p) + of_node_put(config->usbc_force_gpio_p); + dev_dbg(mbhc->codec->dev, "%s: leave %d\n", __func__, rc); + return rc; +} +EXPORT_SYMBOL(wcd_mbhc_start); + +void wcd_mbhc_stop(struct wcd_mbhc *mbhc) +{ + struct usbc_ana_audio_config *config = &mbhc->mbhc_cfg->usbc_analog_cfg; + + pr_debug("%s: enter\n", __func__); + + if (mbhc->current_plug != MBHC_PLUG_TYPE_NONE) { + if (mbhc->mbhc_cb && mbhc->mbhc_cb->skip_imped_detect) + mbhc->mbhc_cb->skip_imped_detect(mbhc->codec); + } + mbhc->current_plug = MBHC_PLUG_TYPE_NONE; + mbhc->hph_status = 0; + if (mbhc->mbhc_cb && mbhc->mbhc_cb->irq_control) { + mbhc->mbhc_cb->irq_control(mbhc->codec, + mbhc->intr_ids->hph_left_ocp, + false); + mbhc->mbhc_cb->irq_control(mbhc->codec, + mbhc->intr_ids->hph_right_ocp, + false); + } + if (mbhc->mbhc_fw || mbhc->mbhc_cal) { + cancel_delayed_work_sync(&mbhc->mbhc_firmware_dwork); + if (!mbhc->mbhc_cal) + release_firmware(mbhc->mbhc_fw); + mbhc->mbhc_fw = NULL; + mbhc->mbhc_cal = NULL; + } + + if (mbhc->mbhc_cfg->enable_usbc_analog) { + wcd_mbhc_usb_c_analog_deinit(mbhc); + /* free GPIOs */ + if (config->usbc_en1_gpio > 0) + gpio_free(config->usbc_en1_gpio); + if (config->usbc_force_gpio) + gpio_free(config->usbc_force_gpio); + + if (config->usbc_en1_gpio_p) + of_node_put(config->usbc_en1_gpio_p); + if (config->usbc_force_gpio_p) + of_node_put(config->usbc_force_gpio_p); + } + + pr_debug("%s: leave\n", __func__); +} +EXPORT_SYMBOL(wcd_mbhc_stop); + +/* + * wcd_mbhc_init : initialize MBHC internal structures. + * + * NOTE: mbhc->mbhc_cfg is not YET configure so shouldn't be used + */ +int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, + const struct wcd_mbhc_cb *mbhc_cb, + const struct wcd_mbhc_intr *mbhc_cdc_intr_ids, + struct wcd_mbhc_register *wcd_mbhc_regs, + bool impedance_det_en) +{ + int ret = 0; + int hph_swh = 0; + int gnd_swh = 0; + u32 hph_moist_config[3]; + struct snd_soc_card *card = codec->component.card; + const char *hph_switch = "qcom,msm-mbhc-hphl-swh"; + const char *gnd_switch = "qcom,msm-mbhc-gnd-swh"; + + pr_debug("%s: enter\n", __func__); + + ret = of_property_read_u32(card->dev->of_node, hph_switch, &hph_swh); + if (ret) { + dev_err(card->dev, + "%s: missing %s in dt node\n", __func__, hph_switch); + goto err; + } + + ret = of_property_read_u32(card->dev->of_node, gnd_switch, &gnd_swh); + if (ret) { + dev_err(card->dev, + "%s: missing %s in dt node\n", __func__, gnd_switch); + goto err; + } + + ret = of_property_read_u32_array(card->dev->of_node, + "qcom,msm-mbhc-moist-cfg", + hph_moist_config, 3); + if (ret) { + dev_dbg(card->dev, "%s: no qcom,msm-mbhc-moist-cfg in DT\n", + __func__); + mbhc->moist_vref = V_45_MV; + mbhc->moist_iref = I_3P0_UA; + mbhc->moist_rref = R_24_KOHM; + } else { + mbhc->moist_vref = hph_moist_config[0]; + mbhc->moist_iref = hph_moist_config[1]; + mbhc->moist_rref = hph_moist_config[2]; + } + + mbhc->in_swch_irq_handler = false; + mbhc->current_plug = MBHC_PLUG_TYPE_NONE; + mbhc->is_btn_press = false; + mbhc->codec = codec; + mbhc->intr_ids = mbhc_cdc_intr_ids; + mbhc->impedance_detect = impedance_det_en; + mbhc->hphl_swh = hph_swh; + mbhc->gnd_swh = gnd_swh; + mbhc->micbias_enable = false; + mbhc->mbhc_cb = mbhc_cb; + mbhc->btn_press_intr = false; + mbhc->is_hs_recording = false; + mbhc->is_extn_cable = false; + mbhc->extn_cable_hph_rem = false; + mbhc->hph_type = WCD_MBHC_HPH_NONE; + mbhc->wcd_mbhc_regs = wcd_mbhc_regs; + + if (mbhc->intr_ids == NULL) { + pr_err("%s: Interrupt mapping not provided\n", __func__); + return -EINVAL; + } + if (!mbhc->wcd_mbhc_regs) { + dev_err(codec->dev, "%s: mbhc registers are not defined\n", + __func__); + return -EINVAL; + } + + /* Check if IRQ and other required callbacks are defined or not */ + if (!mbhc_cb || !mbhc_cb->request_irq || !mbhc_cb->irq_control || + !mbhc_cb->free_irq || !mbhc_cb->map_btn_code_to_num || + !mbhc_cb->lock_sleep || !mbhc_cb->mbhc_bias || + !mbhc_cb->set_btn_thr) { + dev_err(codec->dev, "%s: required mbhc callbacks are not defined\n", + __func__); + return -EINVAL; + } + + /* No need to create new sound card jacks if is is already created */ + if (mbhc->headset_jack.jack == NULL) { + ret = snd_soc_card_jack_new(codec->component.card, + "Headset Jack", WCD_MBHC_JACK_MASK, + &mbhc->headset_jack, NULL, 0); + if (ret) { + pr_err("%s: Failed to create new jack\n", __func__); + return ret; + } + + ret = snd_soc_card_jack_new(codec->component.card, + "Button Jack", + WCD_MBHC_JACK_BUTTON_MASK, + &mbhc->button_jack, NULL, 0); + if (ret) { + pr_err("Failed to create new jack\n"); + return ret; + } + + ret = snd_jack_set_key(mbhc->button_jack.jack, + SND_JACK_BTN_0, + KEY_MEDIA); + if (ret) { + pr_err("%s: Failed to set code for btn-0\n", + __func__); + return ret; + } + + INIT_DELAYED_WORK(&mbhc->mbhc_firmware_dwork, + wcd_mbhc_fw_read); + INIT_DELAYED_WORK(&mbhc->mbhc_btn_dwork, wcd_btn_lpress_fn); + } + mutex_init(&mbhc->hphl_pa_lock); + mutex_init(&mbhc->hphr_pa_lock); + init_completion(&mbhc->btn_press_compl); + + /* Register event notifier */ + mbhc->nblock.notifier_call = wcd_event_notify; + if (mbhc->mbhc_cb->register_notifier) { + ret = mbhc->mbhc_cb->register_notifier(mbhc, &mbhc->nblock, + true); + if (ret) { + pr_err("%s: Failed to register notifier %d\n", + __func__, ret); + return ret; + } + } + + init_waitqueue_head(&mbhc->wait_btn_press); + mutex_init(&mbhc->codec_resource_lock); + + switch (WCD_MBHC_DETECTION) { + case WCD_DETECTION_LEGACY: + wcd_mbhc_legacy_init(mbhc); + break; + case WCD_DETECTION_ADC: + wcd_mbhc_adc_init(mbhc); + break; + default: + pr_err("%s: Unknown detection logic type %d\n", + __func__, WCD_MBHC_DETECTION); + break; + } + + if (!mbhc->mbhc_fn || + !mbhc->mbhc_fn->wcd_mbhc_hs_ins_irq || + !mbhc->mbhc_fn->wcd_mbhc_hs_rem_irq || + !mbhc->mbhc_fn->wcd_mbhc_detect_plug_type || + !mbhc->mbhc_fn->wcd_cancel_hs_detect_plug) { + pr_err("%s: mbhc function pointer is NULL\n", __func__); + goto err_mbhc_sw_irq; + } + ret = mbhc->mbhc_cb->request_irq(codec, mbhc->intr_ids->mbhc_sw_intr, + wcd_mbhc_mech_plug_detect_irq, + "mbhc sw intr", mbhc); + if (ret) { + pr_err("%s: Failed to request irq %d, ret = %d\n", __func__, + mbhc->intr_ids->mbhc_sw_intr, ret); + goto err_mbhc_sw_irq; + } + + ret = mbhc->mbhc_cb->request_irq(codec, + mbhc->intr_ids->mbhc_btn_press_intr, + wcd_mbhc_btn_press_handler, + "Button Press detect", mbhc); + if (ret) { + pr_err("%s: Failed to request irq %d\n", __func__, + mbhc->intr_ids->mbhc_btn_press_intr); + goto err_btn_press_irq; + } + + ret = mbhc->mbhc_cb->request_irq(codec, + mbhc->intr_ids->mbhc_btn_release_intr, + wcd_mbhc_release_handler, + "Button Release detect", mbhc); + if (ret) { + pr_err("%s: Failed to request irq %d\n", __func__, + mbhc->intr_ids->mbhc_btn_release_intr); + goto err_btn_release_irq; + } + + ret = mbhc->mbhc_cb->request_irq(codec, + mbhc->intr_ids->mbhc_hs_ins_intr, + mbhc->mbhc_fn->wcd_mbhc_hs_ins_irq, + "Elect Insert", mbhc); + if (ret) { + pr_err("%s: Failed to request irq %d\n", __func__, + mbhc->intr_ids->mbhc_hs_ins_intr); + goto err_mbhc_hs_ins_irq; + } + mbhc->mbhc_cb->irq_control(codec, mbhc->intr_ids->mbhc_hs_ins_intr, + false); + clear_bit(WCD_MBHC_ELEC_HS_INS, &mbhc->intr_status); + + ret = mbhc->mbhc_cb->request_irq(codec, + mbhc->intr_ids->mbhc_hs_rem_intr, + mbhc->mbhc_fn->wcd_mbhc_hs_rem_irq, + "Elect Remove", mbhc); + if (ret) { + pr_err("%s: Failed to request irq %d\n", __func__, + mbhc->intr_ids->mbhc_hs_rem_intr); + goto err_mbhc_hs_rem_irq; + } + mbhc->mbhc_cb->irq_control(codec, mbhc->intr_ids->mbhc_hs_rem_intr, + false); + clear_bit(WCD_MBHC_ELEC_HS_REM, &mbhc->intr_status); + + ret = mbhc->mbhc_cb->request_irq(codec, mbhc->intr_ids->hph_left_ocp, + wcd_mbhc_hphl_ocp_irq, "HPH_L OCP detect", + mbhc); + if (ret) { + pr_err("%s: Failed to request irq %d\n", __func__, + mbhc->intr_ids->hph_left_ocp); + goto err_hphl_ocp_irq; + } + + ret = mbhc->mbhc_cb->request_irq(codec, mbhc->intr_ids->hph_right_ocp, + wcd_mbhc_hphr_ocp_irq, "HPH_R OCP detect", + mbhc); + if (ret) { + pr_err("%s: Failed to request irq %d\n", __func__, + mbhc->intr_ids->hph_right_ocp); + goto err_hphr_ocp_irq; + } + + pr_debug("%s: leave ret %d\n", __func__, ret); + return ret; + +err_hphr_ocp_irq: + mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->hph_left_ocp, mbhc); +err_hphl_ocp_irq: + mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_hs_rem_intr, mbhc); +err_mbhc_hs_rem_irq: + mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_hs_ins_intr, mbhc); +err_mbhc_hs_ins_irq: + mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_btn_release_intr, + mbhc); +err_btn_release_irq: + mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_btn_press_intr, + mbhc); +err_btn_press_irq: + mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_sw_intr, mbhc); +err_mbhc_sw_irq: + if (mbhc->mbhc_cb->register_notifier) + mbhc->mbhc_cb->register_notifier(mbhc, &mbhc->nblock, false); + mutex_destroy(&mbhc->codec_resource_lock); +err: + pr_debug("%s: leave ret %d\n", __func__, ret); + return ret; +} +EXPORT_SYMBOL(wcd_mbhc_init); + +void wcd_mbhc_deinit(struct wcd_mbhc *mbhc) +{ + struct snd_soc_codec *codec = mbhc->codec; + + mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_sw_intr, mbhc); + mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_btn_press_intr, + mbhc); + mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_btn_release_intr, + mbhc); + mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_hs_ins_intr, mbhc); + mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_hs_rem_intr, mbhc); + mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->hph_left_ocp, mbhc); + mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->hph_right_ocp, mbhc); + if (mbhc->mbhc_cb && mbhc->mbhc_cb->register_notifier) + mbhc->mbhc_cb->register_notifier(mbhc, &mbhc->nblock, false); + if (mbhc->mbhc_fn->wcd_cancel_hs_detect_plug) { + WCD_MBHC_RSC_LOCK(mbhc); + mbhc->mbhc_fn->wcd_cancel_hs_detect_plug(mbhc, + &mbhc->correct_plug_swch); + WCD_MBHC_RSC_UNLOCK(mbhc); + } + mutex_destroy(&mbhc->codec_resource_lock); + mutex_destroy(&mbhc->hphl_pa_lock); + mutex_destroy(&mbhc->hphr_pa_lock); +} +EXPORT_SYMBOL(wcd_mbhc_deinit); + +MODULE_DESCRIPTION("wcd MBHC v2 module"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/wcd-mbhc-v2.h b/sound/soc/codecs/wcd-mbhc-v2.h new file mode 100644 index 000000000000..7ed06c355990 --- /dev/null +++ b/sound/soc/codecs/wcd-mbhc-v2.h @@ -0,0 +1,592 @@ +/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __WCD_MBHC_V2_H__ +#define __WCD_MBHC_V2_H__ + +#include +#include +#include +#include "wcdcal-hwdep.h" + +#define TOMBAK_MBHC_NC 0 +#define TOMBAK_MBHC_NO 1 +#define WCD_MBHC_DEF_BUTTONS 8 +#define WCD_MBHC_KEYCODE_NUM 8 +#define WCD_MBHC_USLEEP_RANGE_MARGIN_US 100 +#define WCD_MBHC_THR_HS_MICB_MV 2700 +/* z value defined in Ohms */ +#define WCD_MONO_HS_MIN_THR 2 +#define WCD_MBHC_STRINGIFY(s) __stringify(s) + +#define WCD_MBHC_REGISTER(rid, rreg, rmask, rshift, rinvert) \ +{ .id = rid, .reg = rreg, .mask = rmask, .offset = rshift, .invert = rinvert } + +#define WCD_MBHC_RSC_LOCK(mbhc) \ +{ \ + pr_debug("%s: Acquiring BCL\n", __func__); \ + mutex_lock(&mbhc->codec_resource_lock); \ + pr_debug("%s: Acquiring BCL done\n", __func__); \ +} + +#define WCD_MBHC_RSC_UNLOCK(mbhc) \ +{ \ + pr_debug("%s: Release BCL\n", __func__); \ + mutex_unlock(&mbhc->codec_resource_lock); \ +} + +#define WCD_MBHC_RSC_ASSERT_LOCKED(mbhc) \ +{ \ + WARN_ONCE(!mutex_is_locked(&mbhc->codec_resource_lock), \ + "%s: BCL should have acquired\n", __func__); \ +} + +/* + * Macros to update and read mbhc register bits. Check for + * "0" before updating or reading the register, because it + * is possible that one codec wants to write to that bit and + * other codec does not. + */ +#define WCD_MBHC_REG_UPDATE_BITS(function, val) \ +do { \ + if (mbhc->wcd_mbhc_regs[function].reg) { \ + snd_soc_update_bits(mbhc->codec, \ + mbhc->wcd_mbhc_regs[function].reg, \ + mbhc->wcd_mbhc_regs[function].mask, \ + val << (mbhc->wcd_mbhc_regs[function].offset)); \ + } \ +} while (0) + +#define WCD_MBHC_REG_READ(function, val) \ +do { \ + if (mbhc->wcd_mbhc_regs[function].reg) { \ + val = (((snd_soc_read(mbhc->codec, \ + mbhc->wcd_mbhc_regs[function].reg)) & \ + (mbhc->wcd_mbhc_regs[function].mask)) >> \ + (mbhc->wcd_mbhc_regs[function].offset)); \ + } else { \ + val = -EINVAL; \ + } \ +} while (0) + +#define WCD_MBHC_CAL_SIZE(buttons, rload) ( \ + sizeof(struct wcd_mbhc_general_cfg) + \ + sizeof(struct wcd_mbhc_plug_detect_cfg) + \ + ((sizeof(s16) + sizeof(s16)) * buttons) + \ + sizeof(struct wcd_mbhc_plug_type_cfg) + \ + sizeof(struct wcd_mbhc_btn_detect_cfg) + \ + sizeof(struct wcd_mbhc_imped_detect_cfg) + \ + ((sizeof(u16) + sizeof(u16)) * rload) \ + ) + +#define WCD_MBHC_CAL_GENERAL_PTR(cali) ( \ + (struct wcd_mbhc_general_cfg *) cali) +#define WCD_MBHC_CAL_PLUG_DET_PTR(cali) ( \ + (struct wcd_mbhc_plug_detect_cfg *) \ + &(WCD_MBHC_CAL_GENERAL_PTR(cali)[1])) +#define WCD_MBHC_CAL_PLUG_TYPE_PTR(cali) ( \ + (struct wcd_mbhc_plug_type_cfg *) \ + &(WCD_MBHC_CAL_PLUG_DET_PTR(cali)[1])) +#define WCD_MBHC_CAL_BTN_DET_PTR(cali) ( \ + (struct wcd_mbhc_btn_detect_cfg *) \ + &(WCD_MBHC_CAL_PLUG_TYPE_PTR(cali)[1])) +#define WCD_MBHC_CAL_IMPED_DET_PTR(cali) ( \ + (struct wcd_mbhc_imped_detect_cfg *) \ + (((void *)&WCD_MBHC_CAL_BTN_DET_PTR(cali)[1]) + \ + (WCD_MBHC_CAL_BTN_DET_PTR(cali)->num_btn * \ + (sizeof(WCD_MBHC_CAL_BTN_DET_PTR(cali)->_v_btn_low[0]) + \ + sizeof(WCD_MBHC_CAL_BTN_DET_PTR(cali)->_v_btn_high[0])))) \ + ) + +#define WCD_MBHC_CAL_MIN_SIZE ( \ + sizeof(struct wcd_mbhc_general_cfg) + \ + sizeof(struct wcd_mbhc_plug_detect_cfg) + \ + sizeof(struct wcd_mbhc_plug_type_cfg) + \ + sizeof(struct wcd_mbhc_btn_detect_cfg) + \ + sizeof(struct wcd_mbhc_imped_detect_cfg) + \ + (sizeof(u16)*2) \ + ) + +#define WCD_MBHC_CAL_BTN_SZ(cfg_ptr) ( \ + sizeof(struct wcd_mbhc_btn_detect_cfg) + \ + (cfg_ptr->num_btn * (sizeof(cfg_ptr->_v_btn_low[0]) + \ + sizeof(cfg_ptr->_v_btn_high[0])))) + +#define WCD_MBHC_CAL_IMPED_MIN_SZ ( \ + sizeof(struct wcd_mbhc_imped_detect_cfg) + sizeof(u16) * 2) + +#define WCD_MBHC_CAL_IMPED_SZ(cfg_ptr) ( \ + sizeof(struct wcd_mbhc_imped_detect_cfg) + \ + (cfg_ptr->_n_rload * \ + (sizeof(cfg_ptr->_rload[0]) + sizeof(cfg_ptr->_alpha[0])))) + +#define WCD_MBHC_JACK_MASK (SND_JACK_HEADSET | SND_JACK_OC_HPHL | \ + SND_JACK_OC_HPHR | SND_JACK_LINEOUT | \ + SND_JACK_MECHANICAL | SND_JACK_MICROPHONE2 | \ + SND_JACK_UNSUPPORTED) + +#define WCD_MBHC_JACK_BUTTON_MASK (SND_JACK_BTN_0 | SND_JACK_BTN_1 | \ + SND_JACK_BTN_2 | SND_JACK_BTN_3 | \ + SND_JACK_BTN_4 | SND_JACK_BTN_5) +#define OCP_ATTEMPT 20 +#define HS_DETECT_PLUG_TIME_MS (3 * 1000) +#define SPECIAL_HS_DETECT_TIME_MS (2 * 1000) +#define MBHC_BUTTON_PRESS_THRESHOLD_MIN 250 +#define GND_MIC_SWAP_THRESHOLD 4 +#define WCD_FAKE_REMOVAL_MIN_PERIOD_MS 100 +#define HS_VREF_MIN_VAL 1400 +#define FW_READ_ATTEMPTS 15 +#define FW_READ_TIMEOUT 4000000 +#define FAKE_REM_RETRY_ATTEMPTS 3 +#define MAX_IMPED 60000 + +#define WCD_MBHC_BTN_PRESS_COMPL_TIMEOUT_MS 50 +#define ANC_DETECT_RETRY_CNT 7 +#define WCD_MBHC_SPL_HS_CNT 1 + +enum wcd_mbhc_detect_logic { + WCD_DETECTION_LEGACY, + WCD_DETECTION_ADC, +}; + +#ifdef CONFIG_SND_SOC_WCD_MBHC_ADC +#define WCD_MBHC_DETECTION WCD_DETECTION_ADC +#else +#define WCD_MBHC_DETECTION WCD_DETECTION_LEGACY +#endif + +enum wcd_mbhc_cs_mb_en_flag { + WCD_MBHC_EN_CS = 0, + WCD_MBHC_EN_MB, + WCD_MBHC_EN_PULLUP, + WCD_MBHC_EN_NONE, +}; + +enum { + WCD_MBHC_ELEC_HS_INS, + WCD_MBHC_ELEC_HS_REM, +}; + +struct wcd_mbhc; +enum wcd_mbhc_register_function { + WCD_MBHC_L_DET_EN, + WCD_MBHC_GND_DET_EN, + WCD_MBHC_MECH_DETECTION_TYPE, + WCD_MBHC_MIC_CLAMP_CTL, + WCD_MBHC_ELECT_DETECTION_TYPE, + WCD_MBHC_HS_L_DET_PULL_UP_CTRL, + WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL, + WCD_MBHC_HPHL_PLUG_TYPE, + WCD_MBHC_GND_PLUG_TYPE, + WCD_MBHC_SW_HPH_LP_100K_TO_GND, + WCD_MBHC_ELECT_SCHMT_ISRC, + WCD_MBHC_FSM_EN, + WCD_MBHC_INSREM_DBNC, + WCD_MBHC_BTN_DBNC, + WCD_MBHC_HS_VREF, + WCD_MBHC_HS_COMP_RESULT, + WCD_MBHC_MIC_SCHMT_RESULT, + WCD_MBHC_HPHL_SCHMT_RESULT, + WCD_MBHC_HPHR_SCHMT_RESULT, + WCD_MBHC_OCP_FSM_EN, + WCD_MBHC_BTN_RESULT, + WCD_MBHC_BTN_ISRC_CTL, + WCD_MBHC_ELECT_RESULT, + WCD_MBHC_MICB_CTRL, /* Pull-up and micb control */ + WCD_MBHC_HPH_CNP_WG_TIME, + WCD_MBHC_HPHR_PA_EN, + WCD_MBHC_HPHL_PA_EN, + WCD_MBHC_HPH_PA_EN, + WCD_MBHC_SWCH_LEVEL_REMOVE, + WCD_MBHC_PULLDOWN_CTRL, + WCD_MBHC_ANC_DET_EN, + WCD_MBHC_FSM_STATUS, + WCD_MBHC_MUX_CTL, + WCD_MBHC_HPHL_OCP_DET_EN, + WCD_MBHC_HPHR_OCP_DET_EN, + WCD_MBHC_HPHL_OCP_STATUS, + WCD_MBHC_HPHR_OCP_STATUS, + WCD_MBHC_ADC_EN, + WCD_MBHC_ADC_COMPLETE, + WCD_MBHC_ADC_TIMEOUT, + WCD_MBHC_ADC_RESULT, + WCD_MBHC_MICB2_VOUT, + WCD_MBHC_ADC_MODE, + WCD_MBHC_DETECTION_DONE, + WCD_MBHC_ELECT_ISRC_EN, + WCD_MBHC_REG_FUNC_MAX, +}; + +enum wcd_mbhc_plug_type { + MBHC_PLUG_TYPE_INVALID = -1, + MBHC_PLUG_TYPE_NONE, + MBHC_PLUG_TYPE_HEADSET, + MBHC_PLUG_TYPE_HEADPHONE, + MBHC_PLUG_TYPE_HIGH_HPH, + MBHC_PLUG_TYPE_GND_MIC_SWAP, + MBHC_PLUG_TYPE_ANC_HEADPHONE, +}; + +enum pa_dac_ack_flags { + WCD_MBHC_HPHL_PA_OFF_ACK = 0, + WCD_MBHC_HPHR_PA_OFF_ACK, +}; + +enum wcd_mbhc_btn_det_mem { + WCD_MBHC_BTN_DET_V_BTN_LOW, + WCD_MBHC_BTN_DET_V_BTN_HIGH +}; + +enum { + MIC_BIAS_1 = 1, + MIC_BIAS_2, + MIC_BIAS_3, + MIC_BIAS_4 +}; + +enum { + MICB_PULLUP_ENABLE, + MICB_PULLUP_DISABLE, + MICB_ENABLE, + MICB_DISABLE, +}; + +enum { + MBHC_COMMON_MICB_PRECHARGE, + MBHC_COMMON_MICB_SET_VAL, + MBHC_COMMON_MICB_TAIL_CURR, +}; + +enum wcd_notify_event { + WCD_EVENT_INVALID, + /* events for micbias ON and OFF */ + WCD_EVENT_PRE_MICBIAS_2_OFF, + WCD_EVENT_POST_MICBIAS_2_OFF, + WCD_EVENT_PRE_MICBIAS_2_ON, + WCD_EVENT_POST_MICBIAS_2_ON, + WCD_EVENT_PRE_DAPM_MICBIAS_2_OFF, + WCD_EVENT_POST_DAPM_MICBIAS_2_OFF, + WCD_EVENT_PRE_DAPM_MICBIAS_2_ON, + WCD_EVENT_POST_DAPM_MICBIAS_2_ON, + /* events for PA ON and OFF */ + WCD_EVENT_PRE_HPHL_PA_ON, + WCD_EVENT_POST_HPHL_PA_OFF, + WCD_EVENT_PRE_HPHR_PA_ON, + WCD_EVENT_POST_HPHR_PA_OFF, + WCD_EVENT_PRE_HPHL_PA_OFF, + WCD_EVENT_PRE_HPHR_PA_OFF, + WCD_EVENT_OCP_OFF, + WCD_EVENT_OCP_ON, + WCD_EVENT_LAST, +}; + +enum wcd_mbhc_event_state { + WCD_MBHC_EVENT_PA_HPHL, + WCD_MBHC_EVENT_PA_HPHR, +}; + +struct wcd_mbhc_general_cfg { + u8 t_ldoh; + u8 t_bg_fast_settle; + u8 t_shutdown_plug_rem; + u8 mbhc_nsa; + u8 mbhc_navg; + u8 v_micbias_l; + u8 v_micbias; + u8 mbhc_reserved; + u16 settle_wait; + u16 t_micbias_rampup; + u16 t_micbias_rampdown; + u16 t_supply_bringup; +} __packed; + +struct wcd_mbhc_plug_detect_cfg { + u32 mic_current; + u32 hph_current; + u16 t_mic_pid; + u16 t_ins_complete; + u16 t_ins_retry; + u16 v_removal_delta; + u8 micbias_slow_ramp; + u8 reserved0; + u8 reserved1; + u8 reserved2; +} __packed; + +struct wcd_mbhc_plug_type_cfg { + u8 av_detect; + u8 mono_detect; + u8 num_ins_tries; + u8 reserved0; + s16 v_no_mic; + s16 v_av_min; + s16 v_av_max; + s16 v_hs_min; + s16 v_hs_max; + u16 reserved1; +} __packed; + +struct wcd_mbhc_btn_detect_cfg { + s8 c[8]; + u8 nc; + u8 n_meas; + u8 mbhc_nsc; + u8 n_btn_meas; + u8 n_btn_con; + u8 num_btn; + u8 reserved0; + u8 reserved1; + u16 t_poll; + u16 t_bounce_wait; + u16 t_rel_timeout; + s16 v_btn_press_delta_sta; + s16 v_btn_press_delta_cic; + u16 t_btn0_timeout; + s16 _v_btn_low[0]; /* v_btn_low[num_btn] */ + s16 _v_btn_high[0]; /* v_btn_high[num_btn] */ + u8 _n_ready[2]; + u8 _n_cic[2]; + u8 _gain[2]; +} __packed; + +struct wcd_mbhc_imped_detect_cfg { + u8 _hs_imped_detect; + u8 _n_rload; + u8 _hph_keep_on; + u8 _repeat_rload_calc; + u16 _t_dac_ramp_time; + u16 _rhph_high; + u16 _rhph_low; + u16 _rload[0]; /* rload[n_rload] */ + u16 _alpha[0]; /* alpha[n_rload] */ + u16 _beta[3]; +} __packed; + +enum wcd_mbhc_hph_type { + WCD_MBHC_HPH_NONE = 0, + WCD_MBHC_HPH_MONO, + WCD_MBHC_HPH_STEREO, +}; + +/* + * These enum definitions are directly mapped to the register + * definitions + */ +enum mbhc_moisture_vref { + V_OFF, + V_45_MV, + V_100_MV, + V_225_MV, +}; + +enum mbhc_hs_pullup_iref { + I_DEFAULT = -1, + I_OFF = 0, + I_1P0_UA, + I_2P0_UA, + I_3P0_UA, +}; + +enum mbhc_moisture_rref { + R_OFF, + R_24_KOHM, + R_84_KOHM, + R_184_KOHM, +}; + +struct usbc_ana_audio_config { + int usbc_en1_gpio; + int usbc_en2_gpio; + int usbc_force_gpio; + struct device_node *usbc_en1_gpio_p; /* used by pinctrl API */ + struct device_node *usbc_en2_gpio_p; /* used by pinctrl API */ + struct device_node *usbc_force_gpio_p; /* used by pinctrl API */ +}; + +struct wcd_mbhc_config { + bool read_fw_bin; + void *calibration; + bool detect_extn_cable; + bool mono_stero_detection; + bool (*swap_gnd_mic)(struct snd_soc_codec *codec, bool active); + bool hs_ext_micbias; + bool gnd_det_en; + int key_code[WCD_MBHC_KEYCODE_NUM]; + uint32_t linein_th; + bool moisture_en; + int mbhc_micbias; + int anc_micbias; + bool enable_anc_mic_detect; + u32 enable_usbc_analog; + struct usbc_ana_audio_config usbc_analog_cfg; +}; + +struct wcd_mbhc_intr { + int mbhc_sw_intr; + int mbhc_btn_press_intr; + int mbhc_btn_release_intr; + int mbhc_hs_ins_intr; + int mbhc_hs_rem_intr; + int hph_left_ocp; + int hph_right_ocp; +}; + +struct wcd_mbhc_register { + const char *id; + u16 reg; + u8 mask; + u8 offset; + u8 invert; +}; + +struct wcd_mbhc_cb { + int (*enable_mb_source)(struct wcd_mbhc *, bool); + void (*trim_btn_reg)(struct snd_soc_codec *); + void (*compute_impedance)(struct wcd_mbhc *, uint32_t *, uint32_t *); + void (*set_micbias_value)(struct snd_soc_codec *); + void (*set_auto_zeroing)(struct snd_soc_codec *, bool); + struct firmware_cal * (*get_hwdep_fw_cal)(struct wcd_mbhc *, + enum wcd_cal_type); + void (*set_cap_mode)(struct snd_soc_codec *, bool, bool); + int (*register_notifier)(struct wcd_mbhc *, + struct notifier_block *nblock, + bool enable); + int (*request_irq)(struct snd_soc_codec *, + int, irq_handler_t, const char *, void *); + void (*irq_control)(struct snd_soc_codec *, + int irq, bool enable); + int (*free_irq)(struct snd_soc_codec *, + int irq, void *); + void (*clk_setup)(struct snd_soc_codec *, bool); + int (*map_btn_code_to_num)(struct snd_soc_codec *); + bool (*lock_sleep)(struct wcd_mbhc *, bool); + bool (*micbias_enable_status)(struct wcd_mbhc *, int); + void (*mbhc_bias)(struct snd_soc_codec *, bool); + void (*mbhc_common_micb_ctrl)(struct snd_soc_codec *, + int event, bool); + void (*micb_internal)(struct snd_soc_codec *, + int micb_num, bool); + bool (*hph_pa_on_status)(struct snd_soc_codec *); + void (*set_btn_thr)(struct snd_soc_codec *, s16 *, s16 *, + int num_btn, bool); + void (*hph_pull_up_control)(struct snd_soc_codec *, + enum mbhc_hs_pullup_iref); + int (*mbhc_micbias_control)(struct snd_soc_codec *, int, int req); + void (*mbhc_micb_ramp_control)(struct snd_soc_codec *, bool); + void (*skip_imped_detect)(struct snd_soc_codec *); + bool (*extn_use_mb)(struct snd_soc_codec *); + int (*mbhc_micb_ctrl_thr_mic)(struct snd_soc_codec *, int, bool); + void (*mbhc_gnd_det_ctrl)(struct snd_soc_codec *, bool); + void (*hph_pull_down_ctrl)(struct snd_soc_codec *, bool); + void (*mbhc_moisture_config)(struct wcd_mbhc *); + bool (*hph_register_recovery)(struct wcd_mbhc *); +}; + +struct wcd_mbhc_fn { + irqreturn_t (*wcd_mbhc_hs_ins_irq)(int irq, void *data); + irqreturn_t (*wcd_mbhc_hs_rem_irq)(int irq, void *data); + void (*wcd_mbhc_detect_plug_type)(struct wcd_mbhc *mbhc); + bool (*wcd_mbhc_detect_anc_plug_type)(struct wcd_mbhc *mbhc); + void (*wcd_cancel_hs_detect_plug)(struct wcd_mbhc *mbhc, + struct work_struct *work); +}; + +struct wcd_mbhc { + /* Delayed work to report long button press */ + struct delayed_work mbhc_btn_dwork; + int buttons_pressed; + struct wcd_mbhc_config *mbhc_cfg; + const struct wcd_mbhc_cb *mbhc_cb; + + u32 hph_status; /* track headhpone status */ + u8 hphlocp_cnt; /* headphone left ocp retry */ + u8 hphrocp_cnt; /* headphone right ocp retry */ + + wait_queue_head_t wait_btn_press; + bool is_btn_press; + u8 current_plug; + bool in_swch_irq_handler; + bool hphl_swh; /*track HPHL switch NC / NO */ + bool gnd_swh; /*track GND switch NC / NO */ + u32 moist_vref; + u32 moist_iref; + u32 moist_rref; + u8 micbias1_cap_mode; /* track ext cap setting */ + u8 micbias2_cap_mode; /* track ext cap setting */ + bool hs_detect_work_stop; + bool micbias_enable; + bool btn_press_intr; + bool is_hs_recording; + bool is_extn_cable; + bool skip_imped_detection; + bool is_btn_already_regd; + bool extn_cable_hph_rem; + + struct snd_soc_codec *codec; + /* Work to perform MBHC Firmware Read */ + struct delayed_work mbhc_firmware_dwork; + const struct firmware *mbhc_fw; + struct firmware_cal *mbhc_cal; + + /* track PA/DAC state to sync with userspace */ + unsigned long hph_pa_dac_state; + unsigned long event_state; + unsigned long jiffies_atreport; + + /* impedance of hphl and hphr */ + uint32_t zl, zr; + bool impedance_detect; + + /* Holds type of Headset - Mono/Stereo */ + enum wcd_mbhc_hph_type hph_type; + + struct snd_soc_jack headset_jack; + struct snd_soc_jack button_jack; + struct mutex codec_resource_lock; + + /* Holds codec specific interrupt mapping */ + const struct wcd_mbhc_intr *intr_ids; + + /* Work to correct accessory type */ + struct work_struct correct_plug_swch; + struct notifier_block nblock; + + struct wcd_mbhc_register *wcd_mbhc_regs; + + struct completion btn_press_compl; + struct mutex hphl_pa_lock; + struct mutex hphr_pa_lock; + + unsigned long intr_status; + bool is_hph_ocp_pending; + + bool usbc_force_pr_mode; + int usbc_mode; + struct notifier_block psy_nb; + struct power_supply *usb_psy; + struct work_struct usbc_analog_work; + + struct wcd_mbhc_fn *mbhc_fn; +}; + +void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc, + enum wcd_mbhc_plug_type plug_type); +void wcd_mbhc_hs_elec_irq(struct wcd_mbhc *mbhc, int irq_type, bool enable); +void wcd_mbhc_elec_hs_report_unplug(struct wcd_mbhc *mbhc); +bool wcd_swch_level_remove(struct wcd_mbhc *mbhc); +void wcd_enable_curr_micbias(const struct wcd_mbhc *mbhc, + const enum wcd_mbhc_cs_mb_en_flag cs_mb_en); +void wcd_mbhc_jack_report(struct wcd_mbhc *mbhc, + struct snd_soc_jack *jack, int status, int mask); +int wcd_cancel_btn_work(struct wcd_mbhc *mbhc); +int wcd_mbhc_get_button_mask(struct wcd_mbhc *mbhc); + +#endif /* __WCD_MBHC_V2_H__ */ diff --git a/sound/soc/codecs/wcd-spi-registers.h b/sound/soc/codecs/wcd-spi-registers.h new file mode 100644 index 000000000000..4e579696cc49 --- /dev/null +++ b/sound/soc/codecs/wcd-spi-registers.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __WCD_SPI_REGISTERS_H__ +#define __WCD_SPI_REGISTERS_H__ + +#include + +#define WCD_SPI_SLAVE_SANITY (0x00) +#define WCD_SPI_SLAVE_DEVICE_ID (0x04) +#define WCD_SPI_SLAVE_STATUS (0x08) +#define WCD_SPI_SLAVE_CONFIG (0x0c) +#define WCD_SPI_SLAVE_SW_RESET (0x10) +#define WCD_SPI_SLAVE_IRQ_STATUS (0x14) +#define WCD_SPI_SLAVE_IRQ_EN (0x18) +#define WCD_SPI_SLAVE_IRQ_CLR (0x1c) +#define WCD_SPI_SLAVE_IRQ_FORCE (0x20) +#define WCD_SPI_SLAVE_TX (0x24) +#define WCD_SPI_SLAVE_TEST_BUS_DATA (0x2c) +#define WCD_SPI_SLAVE_TEST_BUS_CTRL (0x30) +#define WCD_SPI_SLAVE_SW_RST_IRQ (0x34) +#define WCD_SPI_SLAVE_CHAR_CFG (0x38) +#define WCD_SPI_SLAVE_CHAR_DATA_MOSI (0x3c) +#define WCD_SPI_SLAVE_CHAR_DATA_CS_N (0x40) +#define WCD_SPI_SLAVE_CHAR_DATA_MISO (0x44) +#define WCD_SPI_SLAVE_TRNS_BYTE_CNT (0x4c) +#define WCD_SPI_SLAVE_TRNS_LEN (0x50) +#define WCD_SPI_SLAVE_FIFO_LEVEL (0x54) +#define WCD_SPI_SLAVE_GENERICS (0x58) +#define WCD_SPI_SLAVE_EXT_BASE_ADDR (0x5c) +#define WCD_SPI_MAX_REGISTER (0x5F) + +#endif /* End __WCD_SPI_REGISTERS_H__ */ diff --git a/sound/soc/codecs/wcd-spi.c b/sound/soc/codecs/wcd-spi.c new file mode 100644 index 000000000000..957d6428427c --- /dev/null +++ b/sound/soc/codecs/wcd-spi.c @@ -0,0 +1,1535 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcd-spi-registers.h" + +/* Byte manipulations */ +#define SHIFT_1_BYTES (8) +#define SHIFT_2_BYTES (16) +#define SHIFT_3_BYTES (24) + +/* Command opcodes */ +#define WCD_SPI_CMD_NOP (0x00) +#define WCD_SPI_CMD_WREN (0x06) +#define WCD_SPI_CMD_CLKREQ (0xDA) +#define WCD_SPI_CMD_RDSR (0x05) +#define WCD_SPI_CMD_IRR (0x81) +#define WCD_SPI_CMD_IRW (0x82) +#define WCD_SPI_CMD_MIOR (0x83) +#define WCD_SPI_CMD_FREAD (0x0B) +#define WCD_SPI_CMD_MIOW (0x02) +#define WCD_SPI_WRITE_FRAME_OPCODE \ + (WCD_SPI_CMD_MIOW << SHIFT_3_BYTES) +#define WCD_SPI_READ_FRAME_OPCODE \ + (WCD_SPI_CMD_MIOR << SHIFT_3_BYTES) +#define WCD_SPI_FREAD_FRAME_OPCODE \ + (WCD_SPI_CMD_FREAD << SHIFT_3_BYTES) + +/* Command lengths */ +#define WCD_SPI_OPCODE_LEN (0x01) +#define WCD_SPI_CMD_NOP_LEN (0x01) +#define WCD_SPI_CMD_WREN_LEN (0x01) +#define WCD_SPI_CMD_CLKREQ_LEN (0x04) +#define WCD_SPI_CMD_IRR_LEN (0x04) +#define WCD_SPI_CMD_IRW_LEN (0x06) +#define WCD_SPI_WRITE_SINGLE_LEN (0x08) +#define WCD_SPI_READ_SINGLE_LEN (0x13) +#define WCD_SPI_CMD_FREAD_LEN (0x13) + +/* Command delays */ +#define WCD_SPI_CLKREQ_DELAY_USECS (500) +#define WCD_SPI_CLK_OFF_TIMER_MS (500) +#define WCD_SPI_RESUME_TIMEOUT_MS 100 + +/* Command masks */ +#define WCD_CMD_ADDR_MASK \ + (0xFF | \ + (0xFF << SHIFT_1_BYTES) | \ + (0xFF << SHIFT_2_BYTES)) + +/* Clock ctrl request related */ +#define WCD_SPI_CLK_ENABLE true +#define WCD_SPI_CLK_DISABLE false +#define WCD_SPI_CLK_FLAG_DELAYED (1 << 0) +#define WCD_SPI_CLK_FLAG_IMMEDIATE (1 << 1) + +/* Internal addresses */ +#define WCD_SPI_ADDR_IPC_CTL_HOST (0x012014) + +/* Word sizes and min/max lengths */ +#define WCD_SPI_WORD_BYTE_CNT (4) +#define WCD_SPI_RW_MULTI_MIN_LEN (16) + +/* Max size is 32 bytes less than 64Kbytes */ +#define WCD_SPI_RW_MULTI_MAX_LEN ((64 * 1024) - 32) + +/* + * Max size for the pre-allocated buffers is the max + * possible read/write length + 32 bytes for the SPI + * read/write command header itself. + */ +#define WCD_SPI_RW_MAX_BUF_SIZE (WCD_SPI_RW_MULTI_MAX_LEN + 32) + +/* Alignment requirements */ +#define WCD_SPI_RW_MIN_ALIGN WCD_SPI_WORD_BYTE_CNT +#define WCD_SPI_RW_MULTI_ALIGN (16) + +/* Status mask bits */ +#define WCD_SPI_CLK_STATE_ENABLED BIT(0) +#define WCD_SPI_IS_SUSPENDED BIT(1) + +/* Locking related */ +#define WCD_SPI_MUTEX_LOCK(spi, lock) \ +{ \ + dev_vdbg(&spi->dev, "%s: mutex_lock(%s)\n", \ + __func__, __stringify_1(lock)); \ + mutex_lock(&lock); \ +} + +#define WCD_SPI_MUTEX_UNLOCK(spi, lock) \ +{ \ + dev_vdbg(&spi->dev, "%s: mutex_unlock(%s)\n", \ + __func__, __stringify_1(lock)); \ + mutex_unlock(&lock); \ +} + +struct wcd_spi_debug_data { + struct dentry *dir; + u32 addr; + u32 size; +}; + +struct wcd_spi_priv { + struct spi_device *spi; + u32 mem_base_addr; + + struct regmap *regmap; + + /* Message for single transfer */ + struct spi_message msg1; + struct spi_transfer xfer1; + + /* Message for two transfers */ + struct spi_message msg2; + struct spi_transfer xfer2[2]; + + /* Register access related */ + u32 reg_bytes; + u32 val_bytes; + + /* Clock requests related */ + struct mutex clk_mutex; + int clk_users; + unsigned long status_mask; + struct delayed_work clk_dwork; + + /* Transaction related */ + struct mutex xfer_mutex; + + struct device *m_dev; + struct wdsp_mgr_ops *m_ops; + + /* Debugfs related information */ + struct wcd_spi_debug_data debug_data; + + /* Completion object to indicate system resume completion */ + struct completion resume_comp; + + /* Buffers to hold memory used for transfers */ + void *tx_buf; + void *rx_buf; +}; + +enum xfer_request { + WCD_SPI_XFER_WRITE, + WCD_SPI_XFER_READ, +}; + + +static char *wcd_spi_xfer_req_str(enum xfer_request req) +{ + if (req == WCD_SPI_XFER_WRITE) + return "xfer_write"; + else if (req == WCD_SPI_XFER_READ) + return "xfer_read"; + else + return "xfer_invalid"; +} + +static void wcd_spi_reinit_xfer(struct spi_transfer *xfer) +{ + xfer->tx_buf = NULL; + xfer->rx_buf = NULL; + xfer->delay_usecs = 0; + xfer->len = 0; +} + +static bool wcd_spi_is_suspended(struct wcd_spi_priv *wcd_spi) +{ + return test_bit(WCD_SPI_IS_SUSPENDED, &wcd_spi->status_mask); +} + +static bool wcd_spi_can_suspend(struct wcd_spi_priv *wcd_spi) +{ + struct spi_device *spi = wcd_spi->spi; + + if (wcd_spi->clk_users > 0 || + test_bit(WCD_SPI_CLK_STATE_ENABLED, &wcd_spi->status_mask)) { + dev_err(&spi->dev, "%s: cannot suspend, clk_users = %d\n", + __func__, wcd_spi->clk_users); + return false; + } + + return true; +} + +static int wcd_spi_wait_for_resume(struct wcd_spi_priv *wcd_spi) +{ + struct spi_device *spi = wcd_spi->spi; + int rc = 0; + + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + /* If the system is already in resumed state, return right away */ + if (!wcd_spi_is_suspended(wcd_spi)) + goto done; + + /* If suspended then wait for resume to happen */ + reinit_completion(&wcd_spi->resume_comp); + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); + rc = wait_for_completion_timeout(&wcd_spi->resume_comp, + msecs_to_jiffies(WCD_SPI_RESUME_TIMEOUT_MS)); + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + if (rc == 0) { + dev_err(&spi->dev, "%s: failed to resume in %u msec\n", + __func__, WCD_SPI_RESUME_TIMEOUT_MS); + rc = -EIO; + goto done; + } + + dev_dbg(&spi->dev, "%s: resume successful\n", __func__); + rc = 0; +done: + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); + return rc; +} + +static int wcd_spi_read_single(struct spi_device *spi, + u32 remote_addr, u32 *val) +{ + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + struct spi_transfer *tx_xfer = &wcd_spi->xfer2[0]; + struct spi_transfer *rx_xfer = &wcd_spi->xfer2[1]; + u8 *tx_buf = wcd_spi->tx_buf; + u32 frame = 0; + int ret; + + dev_dbg(&spi->dev, "%s: remote_addr = 0x%x\n", + __func__, remote_addr); + + if (!tx_buf) { + dev_err(&spi->dev, "%s: tx_buf not allocated\n", + __func__); + return -ENOMEM; + } + + frame |= WCD_SPI_READ_FRAME_OPCODE; + frame |= remote_addr & WCD_CMD_ADDR_MASK; + + wcd_spi_reinit_xfer(tx_xfer); + frame = cpu_to_be32(frame); + memcpy(tx_buf, &frame, sizeof(frame)); + tx_xfer->tx_buf = tx_buf; + tx_xfer->len = WCD_SPI_READ_SINGLE_LEN; + + wcd_spi_reinit_xfer(rx_xfer); + rx_xfer->rx_buf = val; + rx_xfer->len = sizeof(*val); + + ret = spi_sync(spi, &wcd_spi->msg2); + + return ret; +} + +static int wcd_spi_read_multi(struct spi_device *spi, + u32 remote_addr, u8 *data, + size_t len) +{ + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + struct spi_transfer *xfer = &wcd_spi->xfer1; + u8 *tx_buf = wcd_spi->tx_buf; + u8 *rx_buf = wcd_spi->rx_buf; + u32 frame = 0; + int ret; + + dev_dbg(&spi->dev, "%s: addr 0x%x, len = %zd\n", + __func__, remote_addr, len); + + frame |= WCD_SPI_FREAD_FRAME_OPCODE; + frame |= remote_addr & WCD_CMD_ADDR_MASK; + + if (!tx_buf || !rx_buf) { + dev_err(&spi->dev, "%s: %s not allocated\n", __func__, + (!tx_buf) ? "tx_buf" : "rx_buf"); + return -ENOMEM; + } + + wcd_spi_reinit_xfer(xfer); + frame = cpu_to_be32(frame); + memcpy(tx_buf, &frame, sizeof(frame)); + xfer->tx_buf = tx_buf; + xfer->rx_buf = rx_buf; + xfer->len = WCD_SPI_CMD_FREAD_LEN + len; + + ret = spi_sync(spi, &wcd_spi->msg1); + if (ret) { + dev_err(&spi->dev, "%s: failed, err = %d\n", + __func__, ret); + goto done; + } + + memcpy(data, rx_buf + WCD_SPI_CMD_FREAD_LEN, len); +done: + return ret; +} + +static int wcd_spi_write_single(struct spi_device *spi, + u32 remote_addr, u32 val) +{ + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + struct spi_transfer *xfer = &wcd_spi->xfer1; + u8 buf[WCD_SPI_WRITE_SINGLE_LEN]; + u32 frame = 0; + + dev_dbg(&spi->dev, "%s: remote_addr = 0x%x, val = 0x%x\n", + __func__, remote_addr, val); + + memset(buf, 0, WCD_SPI_WRITE_SINGLE_LEN); + frame |= WCD_SPI_WRITE_FRAME_OPCODE; + frame |= (remote_addr & WCD_CMD_ADDR_MASK); + + frame = cpu_to_be32(frame); + memcpy(buf, &frame, sizeof(frame)); + memcpy(buf + sizeof(frame), &val, sizeof(val)); + + wcd_spi_reinit_xfer(xfer); + xfer->tx_buf = buf; + xfer->len = WCD_SPI_WRITE_SINGLE_LEN; + + return spi_sync(spi, &wcd_spi->msg1); +} + +static int wcd_spi_write_multi(struct spi_device *spi, + u32 remote_addr, u8 *data, + size_t len) +{ + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + struct spi_transfer *xfer = &wcd_spi->xfer1; + u32 frame = 0; + u8 *tx_buf = wcd_spi->tx_buf; + int xfer_len, ret; + + dev_dbg(&spi->dev, "%s: addr = 0x%x len = %zd\n", + __func__, remote_addr, len); + + frame |= WCD_SPI_WRITE_FRAME_OPCODE; + frame |= (remote_addr & WCD_CMD_ADDR_MASK); + + frame = cpu_to_be32(frame); + xfer_len = len + sizeof(frame); + + if (!tx_buf) { + dev_err(&spi->dev, "%s: tx_buf not allocated\n", + __func__); + return -ENOMEM; + } + + memcpy(tx_buf, &frame, sizeof(frame)); + memcpy(tx_buf + sizeof(frame), data, len); + + wcd_spi_reinit_xfer(xfer); + xfer->tx_buf = tx_buf; + xfer->len = xfer_len; + + ret = spi_sync(spi, &wcd_spi->msg1); + if (ret < 0) + dev_err(&spi->dev, + "%s: Failed, addr = 0x%x, len = %zd\n", + __func__, remote_addr, len); + return ret; +} + +static int wcd_spi_transfer_split(struct spi_device *spi, + struct wcd_spi_msg *data_msg, + enum xfer_request xfer_req) +{ + u32 addr = data_msg->remote_addr; + u8 *data = data_msg->data; + int remain_size = data_msg->len; + int to_xfer, loop_cnt, ret = 0; + + /* Perform single writes until multi word alignment is met */ + loop_cnt = 1; + while (remain_size && + !IS_ALIGNED(addr, WCD_SPI_RW_MULTI_ALIGN)) { + if (xfer_req == WCD_SPI_XFER_WRITE) + ret = wcd_spi_write_single(spi, addr, + (*(u32 *)data)); + else + ret = wcd_spi_read_single(spi, addr, + (u32 *)data); + if (ret < 0) { + dev_err(&spi->dev, + "%s: %s fail iter(%d) start-word addr (0x%x)\n", + __func__, wcd_spi_xfer_req_str(xfer_req), + loop_cnt, addr); + goto done; + } + + addr += WCD_SPI_WORD_BYTE_CNT; + data += WCD_SPI_WORD_BYTE_CNT; + remain_size -= WCD_SPI_WORD_BYTE_CNT; + loop_cnt++; + } + + /* Perform multi writes for max allowed multi writes */ + loop_cnt = 1; + while (remain_size >= WCD_SPI_RW_MULTI_MAX_LEN) { + if (xfer_req == WCD_SPI_XFER_WRITE) + ret = wcd_spi_write_multi(spi, addr, data, + WCD_SPI_RW_MULTI_MAX_LEN); + else + ret = wcd_spi_read_multi(spi, addr, data, + WCD_SPI_RW_MULTI_MAX_LEN); + if (ret < 0) { + dev_err(&spi->dev, + "%s: %s fail iter(%d) max-write addr (0x%x)\n", + __func__, wcd_spi_xfer_req_str(xfer_req), + loop_cnt, addr); + goto done; + } + + addr += WCD_SPI_RW_MULTI_MAX_LEN; + data += WCD_SPI_RW_MULTI_MAX_LEN; + remain_size -= WCD_SPI_RW_MULTI_MAX_LEN; + loop_cnt++; + } + + /* + * Perform write for max possible data that is multiple + * of the minimum size for multi-write commands. + */ + to_xfer = remain_size - (remain_size % WCD_SPI_RW_MULTI_MIN_LEN); + if (remain_size >= WCD_SPI_RW_MULTI_MIN_LEN && + to_xfer > 0) { + if (xfer_req == WCD_SPI_XFER_WRITE) + ret = wcd_spi_write_multi(spi, addr, data, to_xfer); + else + ret = wcd_spi_read_multi(spi, addr, data, to_xfer); + if (ret < 0) { + dev_err(&spi->dev, + "%s: %s fail write addr (0x%x), size (0x%x)\n", + __func__, wcd_spi_xfer_req_str(xfer_req), + addr, to_xfer); + goto done; + } + + addr += to_xfer; + data += to_xfer; + remain_size -= to_xfer; + } + + /* Perform single writes for the last remaining data */ + loop_cnt = 1; + while (remain_size > 0) { + if (xfer_req == WCD_SPI_XFER_WRITE) + ret = wcd_spi_write_single(spi, addr, (*((u32 *)data))); + else + ret = wcd_spi_read_single(spi, addr, (u32 *) data); + if (ret < 0) { + dev_err(&spi->dev, + "%s: %s fail iter(%d) end-write addr (0x%x)\n", + __func__, wcd_spi_xfer_req_str(xfer_req), + loop_cnt, addr); + goto done; + } + + addr += WCD_SPI_WORD_BYTE_CNT; + data += WCD_SPI_WORD_BYTE_CNT; + remain_size -= WCD_SPI_WORD_BYTE_CNT; + loop_cnt++; + } + +done: + return ret; +} + +static int wcd_spi_cmd_nop(struct spi_device *spi) +{ + u8 nop = WCD_SPI_CMD_NOP; + + return spi_write(spi, &nop, WCD_SPI_CMD_NOP_LEN); +} + +static int wcd_spi_cmd_clkreq(struct spi_device *spi) +{ + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + struct spi_transfer *xfer = &wcd_spi->xfer1; + u8 cmd[WCD_SPI_CMD_CLKREQ_LEN] = { + WCD_SPI_CMD_CLKREQ, + 0xBA, 0x80, 0x00}; + + wcd_spi_reinit_xfer(xfer); + xfer->tx_buf = cmd; + xfer->len = WCD_SPI_CMD_CLKREQ_LEN; + xfer->delay_usecs = WCD_SPI_CLKREQ_DELAY_USECS; + + return spi_sync(spi, &wcd_spi->msg1); +} + +static int wcd_spi_cmd_wr_en(struct spi_device *spi) +{ + u8 wr_en = WCD_SPI_CMD_WREN; + + return spi_write(spi, &wr_en, WCD_SPI_CMD_WREN_LEN); +} + +static int wcd_spi_cmd_rdsr(struct spi_device *spi, + u32 *rdsr_status) +{ + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + struct spi_transfer *tx_xfer = &wcd_spi->xfer2[0]; + struct spi_transfer *rx_xfer = &wcd_spi->xfer2[1]; + u8 rdsr_cmd; + u32 status; + int ret; + + rdsr_cmd = WCD_SPI_CMD_RDSR; + wcd_spi_reinit_xfer(tx_xfer); + tx_xfer->tx_buf = &rdsr_cmd; + tx_xfer->len = sizeof(rdsr_cmd); + + + wcd_spi_reinit_xfer(rx_xfer); + rx_xfer->rx_buf = &status; + rx_xfer->len = sizeof(status); + + ret = spi_sync(spi, &wcd_spi->msg2); + if (ret < 0) { + dev_err(&spi->dev, "%s: RDSR failed, err = %d\n", + __func__, ret); + goto done; + } + + *rdsr_status = be32_to_cpu(status); + + dev_dbg(&spi->dev, "%s: RDSR success, value = 0x%x\n", + __func__, *rdsr_status); +done: + return ret; +} + +static int wcd_spi_clk_enable(struct spi_device *spi) +{ + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + int ret; + u32 rd_status = 0; + + ret = wcd_spi_cmd_nop(spi); + if (ret < 0) { + dev_err(&spi->dev, "%s: NOP1 failed, err = %d\n", + __func__, ret); + goto done; + } + + ret = wcd_spi_cmd_clkreq(spi); + if (ret < 0) { + dev_err(&spi->dev, "%s: CLK_REQ failed, err = %d\n", + __func__, ret); + goto done; + } + + ret = wcd_spi_cmd_nop(spi); + if (ret < 0) { + dev_err(&spi->dev, "%s: NOP2 failed, err = %d\n", + __func__, ret); + goto done; + } + wcd_spi_cmd_rdsr(spi, &rd_status); + /* + * Read status zero means reads are not + * happenning on the bus, possibly because + * clock request failed. + */ + if (rd_status) { + set_bit(WCD_SPI_CLK_STATE_ENABLED, + &wcd_spi->status_mask); + } else { + dev_err(&spi->dev, "%s: RDSR status is zero\n", + __func__); + ret = -EIO; + } +done: + return ret; +} + +static int wcd_spi_clk_disable(struct spi_device *spi) +{ + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + int ret; + + ret = wcd_spi_write_single(spi, WCD_SPI_ADDR_IPC_CTL_HOST, 0x01); + if (ret < 0) + dev_err(&spi->dev, "%s: Failed, err = %d\n", + __func__, ret); + else + clear_bit(WCD_SPI_CLK_STATE_ENABLED, &wcd_spi->status_mask); + + return ret; +} + +static int wcd_spi_clk_ctrl(struct spi_device *spi, + bool request, u32 flags) +{ + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + int ret = 0; + const char *delay_str; + + delay_str = (flags == WCD_SPI_CLK_FLAG_DELAYED) ? + "delayed" : "immediate"; + + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + + /* Reject any unbalanced disable request */ + if (wcd_spi->clk_users < 0 || + (!request && wcd_spi->clk_users == 0)) { + dev_err(&spi->dev, "%s: Unbalanced clk_users %d for %s\n", + __func__, wcd_spi->clk_users, + request ? "enable" : "disable"); + ret = -EINVAL; + + /* Reset the clk_users to 0 */ + wcd_spi->clk_users = 0; + + goto done; + } + + if (request == WCD_SPI_CLK_ENABLE) { + /* + * If the SPI bus is suspended, then return error + * as the transaction cannot be completed. + */ + if (wcd_spi_is_suspended(wcd_spi)) { + dev_err(&spi->dev, + "%s: SPI suspended, cannot enable clk\n", + __func__); + ret = -EIO; + goto done; + } + + /* Cancel the disable clk work */ + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); + cancel_delayed_work_sync(&wcd_spi->clk_dwork); + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + + wcd_spi->clk_users++; + + /* + * If clk state is already set, + * then clk wasnt really disabled + */ + if (test_bit(WCD_SPI_CLK_STATE_ENABLED, &wcd_spi->status_mask)) + goto done; + else if (wcd_spi->clk_users == 1) + ret = wcd_spi_clk_enable(spi); + + } else { + wcd_spi->clk_users--; + + /* Clock is still voted for */ + if (wcd_spi->clk_users > 0) + goto done; + + /* + * If we are here, clk_users must be 0 and needs + * to be disabled. Call the disable based on the + * flags. + */ + if (flags == WCD_SPI_CLK_FLAG_DELAYED) { + schedule_delayed_work(&wcd_spi->clk_dwork, + msecs_to_jiffies(WCD_SPI_CLK_OFF_TIMER_MS)); + } else { + ret = wcd_spi_clk_disable(spi); + if (ret < 0) + dev_err(&spi->dev, + "%s: Failed to disable clk err = %d\n", + __func__, ret); + } + } + +done: + dev_dbg(&spi->dev, "%s: updated clk_users = %d, request_%s %s\n", + __func__, wcd_spi->clk_users, request ? "enable" : "disable", + request ? "" : delay_str); + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); + + return ret; +} + +static int wcd_spi_init(struct spi_device *spi) +{ + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + int ret; + + ret = wcd_spi_clk_ctrl(spi, WCD_SPI_CLK_ENABLE, + WCD_SPI_CLK_FLAG_IMMEDIATE); + if (ret < 0) + goto done; + + ret = wcd_spi_cmd_wr_en(spi); + if (ret < 0) + goto err_wr_en; + + /* + * In case spi_init is called after component deinit, + * it is possible hardware register state is also reset. + * Sync the regcache here so hardware state is updated + * to reflect the cache. + */ + regcache_sync(wcd_spi->regmap); + + regmap_write(wcd_spi->regmap, WCD_SPI_SLAVE_CONFIG, + 0x0F3D0800); + + /* Write the MTU to max allowed size */ + regmap_update_bits(wcd_spi->regmap, + WCD_SPI_SLAVE_TRNS_LEN, + 0xFFFF0000, 0xFFFF0000); +err_wr_en: + wcd_spi_clk_ctrl(spi, WCD_SPI_CLK_DISABLE, + WCD_SPI_CLK_FLAG_IMMEDIATE); +done: + return ret; +} + +static void wcd_spi_clk_work(struct work_struct *work) +{ + struct delayed_work *dwork; + struct wcd_spi_priv *wcd_spi; + struct spi_device *spi; + int ret; + + dwork = to_delayed_work(work); + wcd_spi = container_of(dwork, struct wcd_spi_priv, clk_dwork); + spi = wcd_spi->spi; + + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + ret = wcd_spi_clk_disable(spi); + if (ret < 0) + dev_err(&spi->dev, + "%s: Failed to disable clk, err = %d\n", + __func__, ret); + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); +} + +static int __wcd_spi_data_xfer(struct spi_device *spi, + struct wcd_spi_msg *msg, + enum xfer_request xfer_req) +{ + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + int ret; + + /* Check for minimum alignment requirements */ + if (!IS_ALIGNED(msg->remote_addr, WCD_SPI_RW_MIN_ALIGN)) { + dev_err(&spi->dev, + "%s addr 0x%x is not aligned to 0x%x\n", + __func__, msg->remote_addr, WCD_SPI_RW_MIN_ALIGN); + return -EINVAL; + } else if (msg->len % WCD_SPI_WORD_BYTE_CNT) { + dev_err(&spi->dev, + "%s len 0x%zx is not multiple of %d\n", + __func__, msg->len, WCD_SPI_WORD_BYTE_CNT); + return -EINVAL; + } + + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->xfer_mutex); + if (msg->len == WCD_SPI_WORD_BYTE_CNT) { + if (xfer_req == WCD_SPI_XFER_WRITE) + ret = wcd_spi_write_single(spi, msg->remote_addr, + (*((u32 *)msg->data))); + else + ret = wcd_spi_read_single(spi, msg->remote_addr, + (u32 *) msg->data); + } else { + ret = wcd_spi_transfer_split(spi, msg, xfer_req); + } + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->xfer_mutex); + + return ret; +} + +static int wcd_spi_data_xfer(struct spi_device *spi, + struct wcd_spi_msg *msg, + enum xfer_request req) +{ + int ret, ret1; + + if (msg->len <= 0) { + dev_err(&spi->dev, "%s: Invalid size %zd\n", + __func__, msg->len); + return -EINVAL; + } + + /* Request for clock */ + ret = wcd_spi_clk_ctrl(spi, WCD_SPI_CLK_ENABLE, + WCD_SPI_CLK_FLAG_IMMEDIATE); + if (ret < 0) { + dev_err(&spi->dev, "%s: clk enable failed %d\n", + __func__, ret); + goto done; + } + + /* Perform the transaction */ + ret = __wcd_spi_data_xfer(spi, msg, req); + if (ret < 0) + dev_err(&spi->dev, + "%s: Failed %s, addr = 0x%x, size = 0x%zx, err = %d\n", + __func__, wcd_spi_xfer_req_str(req), + msg->remote_addr, msg->len, ret); + + /* Release the clock even if xfer failed */ + ret1 = wcd_spi_clk_ctrl(spi, WCD_SPI_CLK_DISABLE, + WCD_SPI_CLK_FLAG_DELAYED); + if (ret1 < 0) + dev_err(&spi->dev, "%s: clk disable failed %d\n", + __func__, ret1); +done: + return ret; +} + +/* + * wcd_spi_data_write: Write data to WCD SPI + * @spi: spi_device struct + * @msg: msg that needs to be written to WCD + * + * This API writes length of data to address specified. These details + * about the write are encapsulated in @msg. Write size should be multiple + * of 4 bytes and write address should be 4-byte aligned. + */ +static int wcd_spi_data_write(struct spi_device *spi, + struct wcd_spi_msg *msg) +{ + if (!spi || !msg) { + pr_err("%s: Invalid %s\n", __func__, + (!spi) ? "spi device" : "msg"); + return -EINVAL; + } + + dev_dbg_ratelimited(&spi->dev, "%s: addr = 0x%x, len = %zu\n", + __func__, msg->remote_addr, msg->len); + return wcd_spi_data_xfer(spi, msg, WCD_SPI_XFER_WRITE); +} + +/* + * wcd_spi_data_read: Read data from WCD SPI + * @spi: spi_device struct + * @msg: msg that needs to be read from WCD + * + * This API reads length of data from address specified. These details + * about the read are encapsulated in @msg. Read size should be multiple + * of 4 bytes and read address should be 4-byte aligned. + */ +static int wcd_spi_data_read(struct spi_device *spi, + struct wcd_spi_msg *msg) +{ + if (!spi || !msg) { + pr_err("%s: Invalid %s\n", __func__, + (!spi) ? "spi device" : "msg"); + return -EINVAL; + } + + dev_dbg_ratelimited(&spi->dev, "%s: addr = 0x%x,len = %zu\n", + __func__, msg->remote_addr, msg->len); + return wcd_spi_data_xfer(spi, msg, WCD_SPI_XFER_READ); +} + +static int wdsp_spi_dload_section(struct spi_device *spi, + void *data) +{ + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + struct wdsp_img_section *sec = data; + struct wcd_spi_msg msg; + int ret; + + dev_dbg(&spi->dev, "%s: addr = 0x%x, size = 0x%zx\n", + __func__, sec->addr, sec->size); + + msg.remote_addr = sec->addr + wcd_spi->mem_base_addr; + msg.data = sec->data; + msg.len = sec->size; + + ret = __wcd_spi_data_xfer(spi, &msg, WCD_SPI_XFER_WRITE); + if (ret < 0) + dev_err(&spi->dev, "%s: fail addr (0x%x) size (0x%zx)\n", + __func__, msg.remote_addr, msg.len); + return ret; +} + +static int wdsp_spi_read_section(struct spi_device *spi, void *data) +{ + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + struct wdsp_img_section *sec = data; + struct wcd_spi_msg msg; + int ret; + + msg.remote_addr = sec->addr + wcd_spi->mem_base_addr; + msg.data = sec->data; + msg.len = sec->size; + + dev_dbg(&spi->dev, "%s: addr = 0x%x, size = 0x%zx\n", + __func__, msg.remote_addr, msg.len); + + ret = wcd_spi_data_xfer(spi, &msg, WCD_SPI_XFER_READ); + if (ret < 0) + dev_err(&spi->dev, "%s: fail addr (0x%x) size (0x%zx)\n", + __func__, msg.remote_addr, msg.len); + return ret; +} + +static int wdsp_spi_event_handler(struct device *dev, void *priv_data, + enum wdsp_event_type event, + void *data) +{ + struct spi_device *spi = to_spi_device(dev); + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + struct wcd_spi_ops *spi_ops; + int ret = 0; + + dev_dbg(&spi->dev, "%s: event type %d\n", + __func__, event); + + switch (event) { + case WDSP_EVENT_POST_SHUTDOWN: + cancel_delayed_work_sync(&wcd_spi->clk_dwork); + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + if (test_bit(WCD_SPI_CLK_STATE_ENABLED, &wcd_spi->status_mask)) + wcd_spi_clk_disable(spi); + wcd_spi->clk_users = 0; + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); + break; + + case WDSP_EVENT_PRE_DLOAD_CODE: + case WDSP_EVENT_PRE_DLOAD_DATA: + ret = wcd_spi_clk_ctrl(spi, WCD_SPI_CLK_ENABLE, + WCD_SPI_CLK_FLAG_IMMEDIATE); + if (ret < 0) + dev_err(&spi->dev, "%s: clk_req failed %d\n", + __func__, ret); + break; + + case WDSP_EVENT_POST_DLOAD_CODE: + case WDSP_EVENT_POST_DLOAD_DATA: + case WDSP_EVENT_DLOAD_FAILED: + + ret = wcd_spi_clk_ctrl(spi, WCD_SPI_CLK_DISABLE, + WCD_SPI_CLK_FLAG_IMMEDIATE); + if (ret < 0) + dev_err(&spi->dev, "%s: clk unvote failed %d\n", + __func__, ret); + break; + + case WDSP_EVENT_DLOAD_SECTION: + ret = wdsp_spi_dload_section(spi, data); + break; + + case WDSP_EVENT_READ_SECTION: + ret = wdsp_spi_read_section(spi, data); + break; + + case WDSP_EVENT_SUSPEND: + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + if (!wcd_spi_can_suspend(wcd_spi)) + ret = -EBUSY; + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); + break; + + case WDSP_EVENT_RESUME: + ret = wcd_spi_wait_for_resume(wcd_spi); + break; + + case WDSP_EVENT_GET_DEVOPS: + if (!data) { + dev_err(&spi->dev, "%s: invalid data\n", + __func__); + ret = -EINVAL; + break; + } + + spi_ops = (struct wcd_spi_ops *) data; + spi_ops->spi_dev = spi; + spi_ops->read_dev = wcd_spi_data_read; + spi_ops->write_dev = wcd_spi_data_write; + break; + + default: + dev_dbg(&spi->dev, "%s: Unhandled event %d\n", + __func__, event); + break; + } + + return ret; +} + +static int wcd_spi_bus_gwrite(void *context, const void *reg, + size_t reg_len, const void *val, + size_t val_len) +{ + struct device *dev = context; + struct spi_device *spi = to_spi_device(dev); + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + u8 tx_buf[WCD_SPI_CMD_IRW_LEN]; + + if (!reg || !val || reg_len != wcd_spi->reg_bytes || + val_len != wcd_spi->val_bytes) { + dev_err(&spi->dev, + "%s: Invalid input, reg_len = %zd, val_len = %zd", + __func__, reg_len, val_len); + return -EINVAL; + } + + tx_buf[0] = WCD_SPI_CMD_IRW; + tx_buf[1] = *((u8 *)reg); + memcpy(&tx_buf[WCD_SPI_OPCODE_LEN + reg_len], + val, val_len); + + return spi_write(spi, tx_buf, WCD_SPI_CMD_IRW_LEN); +} + +static int wcd_spi_bus_write(void *context, const void *data, + size_t count) +{ + struct device *dev = context; + struct spi_device *spi = to_spi_device(dev); + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + + if (count < (wcd_spi->reg_bytes + wcd_spi->val_bytes)) { + dev_err(&spi->dev, "%s: Invalid size %zd\n", + __func__, count); + WARN_ON(1); + return -EINVAL; + } + + return wcd_spi_bus_gwrite(context, data, wcd_spi->reg_bytes, + data + wcd_spi->reg_bytes, + count - wcd_spi->reg_bytes); +} + +static int wcd_spi_bus_read(void *context, const void *reg, + size_t reg_len, void *val, + size_t val_len) +{ + struct device *dev = context; + struct spi_device *spi = to_spi_device(dev); + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + struct spi_transfer *tx_xfer = &wcd_spi->xfer2[0]; + struct spi_transfer *rx_xfer = &wcd_spi->xfer2[1]; + u8 tx_buf[WCD_SPI_CMD_IRR_LEN]; + + if (!reg || !val || reg_len != wcd_spi->reg_bytes || + val_len != wcd_spi->val_bytes) { + dev_err(&spi->dev, + "%s: Invalid input, reg_len = %zd, val_len = %zd", + __func__, reg_len, val_len); + return -EINVAL; + } + + memset(tx_buf, 0, WCD_SPI_OPCODE_LEN); + tx_buf[0] = WCD_SPI_CMD_IRR; + tx_buf[1] = *((u8 *)reg); + + wcd_spi_reinit_xfer(tx_xfer); + tx_xfer->tx_buf = tx_buf; + tx_xfer->rx_buf = NULL; + tx_xfer->len = WCD_SPI_CMD_IRR_LEN; + + wcd_spi_reinit_xfer(rx_xfer); + rx_xfer->tx_buf = NULL; + rx_xfer->rx_buf = val; + rx_xfer->len = val_len; + + return spi_sync(spi, &wcd_spi->msg2); +} + +static struct regmap_bus wcd_spi_regmap_bus = { + .write = wcd_spi_bus_write, + .gather_write = wcd_spi_bus_gwrite, + .read = wcd_spi_bus_read, + .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, + .val_format_endian_default = REGMAP_ENDIAN_BIG, +}; + +static int wcd_spi_state_show(struct seq_file *f, void *ptr) +{ + struct spi_device *spi = f->private; + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + const char *clk_state, *clk_mutex, *xfer_mutex; + + if (test_bit(WCD_SPI_CLK_STATE_ENABLED, &wcd_spi->status_mask)) + clk_state = "enabled"; + else + clk_state = "disabled"; + + clk_mutex = mutex_is_locked(&wcd_spi->clk_mutex) ? + "locked" : "unlocked"; + + xfer_mutex = mutex_is_locked(&wcd_spi->xfer_mutex) ? + "locked" : "unlocked"; + + seq_printf(f, "clk_state = %s\nclk_users = %d\n" + "clk_mutex = %s\nxfer_mutex = %s\n", + clk_state, wcd_spi->clk_users, clk_mutex, + xfer_mutex); + return 0; +} + +static int wcd_spi_state_open(struct inode *inode, struct file *file) +{ + return single_open(file, wcd_spi_state_show, inode->i_private); +} + +static const struct file_operations state_fops = { + .open = wcd_spi_state_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static ssize_t wcd_spi_debugfs_mem_read(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct spi_device *spi = file->private_data; + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + struct wcd_spi_debug_data *dbg_data = &wcd_spi->debug_data; + struct wcd_spi_msg msg; + ssize_t buf_size, read_count = 0; + char *buf; + int ret; + + if (*ppos < 0 || !count) + return -EINVAL; + + if (dbg_data->size == 0 || dbg_data->addr == 0) { + dev_err(&spi->dev, + "%s: Invalid request, size = %u, addr = 0x%x\n", + __func__, dbg_data->size, dbg_data->addr); + return 0; + } + + buf_size = count < dbg_data->size ? count : dbg_data->size; + buf = kzalloc(buf_size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + msg.data = buf; + msg.remote_addr = dbg_data->addr; + msg.len = buf_size; + msg.flags = 0; + + ret = wcd_spi_data_read(spi, &msg); + if (ret < 0) { + dev_err(&spi->dev, + "%s: Failed to read %zu bytes from addr 0x%x\n", + __func__, buf_size, msg.remote_addr); + goto done; + } + + read_count = simple_read_from_buffer(ubuf, count, ppos, buf, buf_size); + +done: + kfree(buf); + if (ret < 0) + return ret; + else + return read_count; +} + +static const struct file_operations mem_read_fops = { + .open = simple_open, + .read = wcd_spi_debugfs_mem_read, +}; + +static int wcd_spi_debugfs_init(struct spi_device *spi) +{ + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + struct wcd_spi_debug_data *dbg_data = &wcd_spi->debug_data; + int rc = 0; + + dbg_data->dir = debugfs_create_dir("wcd_spi", NULL); + if (IS_ERR_OR_NULL(dbg_data->dir)) { + dbg_data->dir = NULL; + rc = -ENODEV; + goto done; + } + + debugfs_create_file("state", 0444, dbg_data->dir, spi, &state_fops); + debugfs_create_u32("addr", 0644, dbg_data->dir, + &dbg_data->addr); + debugfs_create_u32("size", 0644, dbg_data->dir, + &dbg_data->size); + + debugfs_create_file("mem_read", 0444, dbg_data->dir, + spi, &mem_read_fops); +done: + return rc; +} + + +static const struct reg_default wcd_spi_defaults[] = { + {WCD_SPI_SLAVE_SANITY, 0xDEADBEEF}, + {WCD_SPI_SLAVE_DEVICE_ID, 0x00500000}, + {WCD_SPI_SLAVE_STATUS, 0x80100000}, + {WCD_SPI_SLAVE_CONFIG, 0x0F200808}, + {WCD_SPI_SLAVE_SW_RESET, 0x00000000}, + {WCD_SPI_SLAVE_IRQ_STATUS, 0x00000000}, + {WCD_SPI_SLAVE_IRQ_EN, 0x00000000}, + {WCD_SPI_SLAVE_IRQ_CLR, 0x00000000}, + {WCD_SPI_SLAVE_IRQ_FORCE, 0x00000000}, + {WCD_SPI_SLAVE_TX, 0x00000000}, + {WCD_SPI_SLAVE_TEST_BUS_DATA, 0x00000000}, + {WCD_SPI_SLAVE_TEST_BUS_CTRL, 0x00000000}, + {WCD_SPI_SLAVE_SW_RST_IRQ, 0x00000000}, + {WCD_SPI_SLAVE_CHAR_CFG, 0x00000000}, + {WCD_SPI_SLAVE_CHAR_DATA_MOSI, 0x00000000}, + {WCD_SPI_SLAVE_CHAR_DATA_CS_N, 0x00000000}, + {WCD_SPI_SLAVE_CHAR_DATA_MISO, 0x00000000}, + {WCD_SPI_SLAVE_TRNS_BYTE_CNT, 0x00000000}, + {WCD_SPI_SLAVE_TRNS_LEN, 0x00000000}, + {WCD_SPI_SLAVE_FIFO_LEVEL, 0x00000000}, + {WCD_SPI_SLAVE_GENERICS, 0x80000000}, + {WCD_SPI_SLAVE_EXT_BASE_ADDR, 0x00000000}, +}; + +static bool wcd_spi_is_volatile_reg(struct device *dev, + unsigned int reg) +{ + switch (reg) { + case WCD_SPI_SLAVE_SANITY: + case WCD_SPI_SLAVE_STATUS: + case WCD_SPI_SLAVE_IRQ_STATUS: + case WCD_SPI_SLAVE_TX: + case WCD_SPI_SLAVE_SW_RST_IRQ: + case WCD_SPI_SLAVE_TRNS_BYTE_CNT: + case WCD_SPI_SLAVE_FIFO_LEVEL: + case WCD_SPI_SLAVE_GENERICS: + return true; + } + + return false; +} + +static bool wcd_spi_is_readable_reg(struct device *dev, + unsigned int reg) +{ + switch (reg) { + case WCD_SPI_SLAVE_SW_RESET: + case WCD_SPI_SLAVE_IRQ_CLR: + case WCD_SPI_SLAVE_IRQ_FORCE: + return false; + } + + return true; +} + +static struct regmap_config wcd_spi_regmap_cfg = { + .reg_bits = 8, + .val_bits = 32, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wcd_spi_defaults, + .num_reg_defaults = ARRAY_SIZE(wcd_spi_defaults), + .max_register = WCD_SPI_MAX_REGISTER, + .volatile_reg = wcd_spi_is_volatile_reg, + .readable_reg = wcd_spi_is_readable_reg, +}; + +static int wdsp_spi_init(struct device *dev, void *priv_data) +{ + struct spi_device *spi = to_spi_device(dev); + int ret; + + ret = wcd_spi_init(spi); + if (ret < 0) + dev_err(&spi->dev, "%s: Init failed, err = %d\n", + __func__, ret); + return ret; +} + +static int wdsp_spi_deinit(struct device *dev, void *priv_data) +{ + struct spi_device *spi = to_spi_device(dev); + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + + /* + * Deinit means the hardware is reset. Mark the cache + * as dirty here, so init will sync the cache + */ + regcache_mark_dirty(wcd_spi->regmap); + + return 0; +} + +static struct wdsp_cmpnt_ops wdsp_spi_ops = { + .init = wdsp_spi_init, + .deinit = wdsp_spi_deinit, + .event_handler = wdsp_spi_event_handler, +}; + +static int wcd_spi_component_bind(struct device *dev, + struct device *master, + void *data) +{ + struct spi_device *spi = to_spi_device(dev); + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + int ret = 0; + + wcd_spi->m_dev = master; + wcd_spi->m_ops = data; + + if (wcd_spi->m_ops && + wcd_spi->m_ops->register_cmpnt_ops) + ret = wcd_spi->m_ops->register_cmpnt_ops(master, dev, + wcd_spi, + &wdsp_spi_ops); + if (ret) { + dev_err(dev, "%s: register_cmpnt_ops failed, err = %d\n", + __func__, ret); + goto done; + } + + wcd_spi->reg_bytes = DIV_ROUND_UP(wcd_spi_regmap_cfg.reg_bits, 8); + wcd_spi->val_bytes = DIV_ROUND_UP(wcd_spi_regmap_cfg.val_bits, 8); + + wcd_spi->regmap = devm_regmap_init(&spi->dev, &wcd_spi_regmap_bus, + &spi->dev, &wcd_spi_regmap_cfg); + if (IS_ERR(wcd_spi->regmap)) { + ret = PTR_ERR(wcd_spi->regmap); + dev_err(&spi->dev, "%s: Failed to allocate regmap, err = %d\n", + __func__, ret); + goto done; + } + + if (wcd_spi_debugfs_init(spi)) + dev_err(&spi->dev, "%s: Failed debugfs init\n", __func__); + + spi_message_init(&wcd_spi->msg1); + spi_message_add_tail(&wcd_spi->xfer1, &wcd_spi->msg1); + + spi_message_init(&wcd_spi->msg2); + spi_message_add_tail(&wcd_spi->xfer2[0], &wcd_spi->msg2); + spi_message_add_tail(&wcd_spi->xfer2[1], &wcd_spi->msg2); + + /* Pre-allocate the buffers */ + wcd_spi->tx_buf = kzalloc(WCD_SPI_RW_MAX_BUF_SIZE, + GFP_KERNEL | GFP_DMA); + if (!wcd_spi->tx_buf) { + ret = -ENOMEM; + goto done; + } + + wcd_spi->rx_buf = kzalloc(WCD_SPI_RW_MAX_BUF_SIZE, + GFP_KERNEL | GFP_DMA); + if (!wcd_spi->rx_buf) { + kfree(wcd_spi->tx_buf); + wcd_spi->tx_buf = NULL; + ret = -ENOMEM; + goto done; + } +done: + return ret; +} + +static void wcd_spi_component_unbind(struct device *dev, + struct device *master, + void *data) +{ + struct spi_device *spi = to_spi_device(dev); + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + + wcd_spi->m_dev = NULL; + wcd_spi->m_ops = NULL; + + spi_transfer_del(&wcd_spi->xfer1); + spi_transfer_del(&wcd_spi->xfer2[0]); + spi_transfer_del(&wcd_spi->xfer2[1]); + + kfree(wcd_spi->tx_buf); + kfree(wcd_spi->rx_buf); + wcd_spi->tx_buf = NULL; + wcd_spi->rx_buf = NULL; +} + +static const struct component_ops wcd_spi_component_ops = { + .bind = wcd_spi_component_bind, + .unbind = wcd_spi_component_unbind, +}; + +static int wcd_spi_probe(struct spi_device *spi) +{ + struct wcd_spi_priv *wcd_spi; + int ret = 0; + + wcd_spi = devm_kzalloc(&spi->dev, sizeof(*wcd_spi), + GFP_KERNEL); + if (!wcd_spi) + return -ENOMEM; + + ret = of_property_read_u32(spi->dev.of_node, + "qcom,mem-base-addr", + &wcd_spi->mem_base_addr); + if (ret < 0) { + dev_err(&spi->dev, "%s: Missing %s DT entry", + __func__, "qcom,mem-base-addr"); + goto err_ret; + } + + dev_dbg(&spi->dev, + "%s: mem_base_addr 0x%x\n", __func__, wcd_spi->mem_base_addr); + + mutex_init(&wcd_spi->clk_mutex); + mutex_init(&wcd_spi->xfer_mutex); + INIT_DELAYED_WORK(&wcd_spi->clk_dwork, wcd_spi_clk_work); + init_completion(&wcd_spi->resume_comp); + + wcd_spi->spi = spi; + spi_set_drvdata(spi, wcd_spi); + + ret = component_add(&spi->dev, &wcd_spi_component_ops); + if (ret) { + dev_err(&spi->dev, "%s: component_add failed err = %d\n", + __func__, ret); + goto err_component_add; + } + + return ret; + +err_component_add: + mutex_destroy(&wcd_spi->clk_mutex); + mutex_destroy(&wcd_spi->xfer_mutex); +err_ret: + devm_kfree(&spi->dev, wcd_spi); + spi_set_drvdata(spi, NULL); + return ret; +} + +static int wcd_spi_remove(struct spi_device *spi) +{ + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + + component_del(&spi->dev, &wcd_spi_component_ops); + + mutex_destroy(&wcd_spi->clk_mutex); + mutex_destroy(&wcd_spi->xfer_mutex); + + devm_kfree(&spi->dev, wcd_spi); + spi_set_drvdata(spi, NULL); + + return 0; +} + +#ifdef CONFIG_PM +static int wcd_spi_suspend(struct device *dev) +{ + struct spi_device *spi = to_spi_device(dev); + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + int rc = 0; + + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + if (!wcd_spi_can_suspend(wcd_spi)) { + rc = -EBUSY; + goto done; + } + + /* + * If we are here, it is okay to let the suspend go + * through for this driver. But, still need to notify + * the master to make sure all other components can suspend + * as well. + */ + if (wcd_spi->m_dev && wcd_spi->m_ops && + wcd_spi->m_ops->suspend) { + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); + rc = wcd_spi->m_ops->suspend(wcd_spi->m_dev); + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + } + + if (rc == 0) + set_bit(WCD_SPI_IS_SUSPENDED, &wcd_spi->status_mask); + else + dev_dbg(&spi->dev, "%s: cannot suspend, err = %d\n", + __func__, rc); +done: + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); + return rc; +} + +static int wcd_spi_resume(struct device *dev) +{ + struct spi_device *spi = to_spi_device(dev); + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + clear_bit(WCD_SPI_IS_SUSPENDED, &wcd_spi->status_mask); + complete(&wcd_spi->resume_comp); + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); + + return 0; +} + +static const struct dev_pm_ops wcd_spi_pm_ops = { + .suspend = wcd_spi_suspend, + .resume = wcd_spi_resume, +}; +#endif + +static const struct of_device_id wcd_spi_of_match[] = { + { .compatible = "qcom,wcd-spi-v2", }, + { } +}; +MODULE_DEVICE_TABLE(of, wcd_spi_of_match); + +static struct spi_driver wcd_spi_driver = { + .driver = { + .name = "wcd-spi-v2", + .of_match_table = wcd_spi_of_match, +#ifdef CONFIG_PM + .pm = &wcd_spi_pm_ops, +#endif + }, + .probe = wcd_spi_probe, + .remove = wcd_spi_remove, +}; + +module_spi_driver(wcd_spi_driver); + +MODULE_DESCRIPTION("WCD SPI driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c new file mode 100644 index 000000000000..329aa7a4c466 --- /dev/null +++ b/sound/soc/codecs/wcd9335.c @@ -0,0 +1,14178 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcd9335.h" +#include "wcd-mbhc-v2.h" +#include "wcd9xxx-common-v2.h" +#include "wcd9xxx-resmgr-v2.h" +#include "wcd_cpe_core.h" +#include "wcdcal-hwdep.h" +#include "wcd-mbhc-v2-api.h" + +#define TASHA_RX_PORT_START_NUMBER 16 + +#define WCD9335_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) +/* Fractional Rates */ +#define WCD9335_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100) + +#define WCD9335_MIX_RATES_MASK (SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) + +#define TASHA_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S24_3LE) + +#define TASHA_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S24_3LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +#define TASHA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) + +/* + * Timeout in milli seconds and it is the wait time for + * slim channel removal interrupt to receive. + */ +#define TASHA_SLIM_CLOSE_TIMEOUT 1000 +#define TASHA_SLIM_IRQ_OVERFLOW (1 << 0) +#define TASHA_SLIM_IRQ_UNDERFLOW (1 << 1) +#define TASHA_SLIM_IRQ_PORT_CLOSED (1 << 2) +#define TASHA_MCLK_CLK_12P288MHZ 12288000 +#define TASHA_MCLK_CLK_9P6MHZ 9600000 + +#define TASHA_SLIM_PGD_PORT_INT_TX_EN0 (TASHA_SLIM_PGD_PORT_INT_EN0 + 2) + +#define TASHA_NUM_INTERPOLATORS 9 +#define TASHA_NUM_DECIMATORS 9 + +#define BYTE_BIT_MASK(nr) (1 << ((nr) % BITS_PER_BYTE)) +#define TASHA_MAD_AUDIO_FIRMWARE_PATH "wcd9335/wcd9335_mad_audio.bin" +#define TASHA_CPE_SS_ERR_STATUS_MEM_ACCESS (1 << 0) +#define TASHA_CPE_SS_ERR_STATUS_WDOG_BITE (1 << 1) + +#define TASHA_CPE_FATAL_IRQS \ + (TASHA_CPE_SS_ERR_STATUS_WDOG_BITE | \ + TASHA_CPE_SS_ERR_STATUS_MEM_ACCESS) + +#define SLIM_BW_CLK_GEAR_9 6200000 +#define SLIM_BW_UNVOTE 0 + +#define CPE_FLL_CLK_75MHZ 75000000 +#define CPE_FLL_CLK_150MHZ 150000000 +#define WCD9335_REG_BITS 8 + +#define WCD9335_MAX_VALID_ADC_MUX 13 +#define WCD9335_INVALID_ADC_MUX 9 + +#define TASHA_DIG_CORE_REG_MIN WCD9335_CDC_ANC0_CLK_RESET_CTL +#define TASHA_DIG_CORE_REG_MAX 0xDFF + +/* Convert from vout ctl to micbias voltage in mV */ +#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50) + +#define TASHA_ZDET_NUM_MEASUREMENTS 150 +#define TASHA_MBHC_GET_C1(c) ((c & 0xC000) >> 14) +#define TASHA_MBHC_GET_X1(x) (x & 0x3FFF) +/* z value compared in milliOhm */ +#define TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000)) +#define TASHA_MBHC_ZDET_CONST (86 * 16384) +#define TASHA_MBHC_MOISTURE_VREF V_45_MV +#define TASHA_MBHC_MOISTURE_IREF I_3P0_UA + +#define TASHA_VERSION_ENTRY_SIZE 17 + +#define WCD9335_AMIC_PWR_LEVEL_LP 0 +#define WCD9335_AMIC_PWR_LEVEL_DEFAULT 1 +#define WCD9335_AMIC_PWR_LEVEL_HP 2 +#define WCD9335_AMIC_PWR_LVL_MASK 0x60 +#define WCD9335_AMIC_PWR_LVL_SHIFT 0x5 + +#define WCD9335_DEC_PWR_LVL_MASK 0x06 +#define WCD9335_DEC_PWR_LVL_LP 0x02 +#define WCD9335_DEC_PWR_LVL_HP 0x04 +#define WCD9335_DEC_PWR_LVL_DF 0x00 +#define WCD9335_STRING_LEN 100 + +#define CALCULATE_VOUT_D(req_mv) (((req_mv - 650) * 10) / 25) + +static int cpe_debug_mode; + +#define TASHA_MAX_MICBIAS 4 +#define DAPM_MICBIAS1_STANDALONE "MIC BIAS1 Standalone" +#define DAPM_MICBIAS2_STANDALONE "MIC BIAS2 Standalone" +#define DAPM_MICBIAS3_STANDALONE "MIC BIAS3 Standalone" +#define DAPM_MICBIAS4_STANDALONE "MIC BIAS4 Standalone" + +#define DAPM_LDO_H_STANDALONE "LDO_H" +module_param(cpe_debug_mode, int, 0664); +MODULE_PARM_DESC(cpe_debug_mode, "boot cpe in debug mode"); + +#define TASHA_DIG_CORE_COLLAPSE_TIMER_MS (5 * 1000) + +#define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64 + +static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = { + "cdc-vdd-mic-bias", +}; + +enum { + POWER_COLLAPSE, + POWER_RESUME, +}; + +enum tasha_sido_voltage { + SIDO_VOLTAGE_SVS_MV = 950, + SIDO_VOLTAGE_NOMINAL_MV = 1100, +}; + +static enum codec_variant codec_ver; + +static int dig_core_collapse_enable = 1; +module_param(dig_core_collapse_enable, int, 0664); +MODULE_PARM_DESC(dig_core_collapse_enable, "enable/disable power gating"); + +/* dig_core_collapse timer in seconds */ +static int dig_core_collapse_timer = (TASHA_DIG_CORE_COLLAPSE_TIMER_MS/1000); +module_param(dig_core_collapse_timer, int, 0664); +MODULE_PARM_DESC(dig_core_collapse_timer, "timer for power gating"); + +/* SVS Scaling enable/disable */ +static int svs_scaling_enabled = 1; +module_param(svs_scaling_enabled, int, 0664); +MODULE_PARM_DESC(svs_scaling_enabled, "enable/disable svs scaling"); + +/* SVS buck setting */ +static int sido_buck_svs_voltage = SIDO_VOLTAGE_SVS_MV; +module_param(sido_buck_svs_voltage, int, 0664); +MODULE_PARM_DESC(sido_buck_svs_voltage, + "setting for SVS voltage for SIDO BUCK"); + +#define TASHA_TX_UNMUTE_DELAY_MS 40 + +static int tx_unmute_delay = TASHA_TX_UNMUTE_DELAY_MS; +module_param(tx_unmute_delay, int, 0664); +MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path"); + +static struct afe_param_slimbus_slave_port_cfg tasha_slimbus_slave_port_cfg = { + .minor_version = 1, + .slimbus_dev_id = AFE_SLIMBUS_DEVICE_1, + .slave_dev_pgd_la = 0, + .slave_dev_intfdev_la = 0, + .bit_width = 16, + .data_format = 0, + .num_channels = 1 +}; + +struct tasha_mbhc_zdet_param { + u16 ldo_ctl; + u16 noff; + u16 nshift; + u16 btn5; + u16 btn6; + u16 btn7; +}; + +static struct afe_param_cdc_reg_page_cfg tasha_cdc_reg_page_cfg = { + .minor_version = AFE_API_VERSION_CDC_REG_PAGE_CFG, + .enable = 1, + .proc_id = AFE_CDC_REG_PAGE_ASSIGN_PROC_ID_1, +}; + +static struct afe_param_cdc_reg_cfg audio_reg_cfg[] = { + { + 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_SOC_MAD_MAIN_CTL_1), + HW_MAD_AUDIO_ENABLE, 0x1, WCD9335_REG_BITS, 0 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_SOC_MAD_AUDIO_CTL_3), + HW_MAD_AUDIO_SLEEP_TIME, 0xF, WCD9335_REG_BITS, 0 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_SOC_MAD_AUDIO_CTL_4), + HW_MAD_TX_AUDIO_SWITCH_OFF, 0x1, WCD9335_REG_BITS, 0 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_CFG), + MAD_AUDIO_INT_DEST_SELECT_REG, 0x2, WCD9335_REG_BITS, 0 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_MASK3), + MAD_AUDIO_INT_MASK_REG, 0x1, WCD9335_REG_BITS, 0 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_STATUS3), + MAD_AUDIO_INT_STATUS_REG, 0x1, WCD9335_REG_BITS, 0 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_CLEAR3), + MAD_AUDIO_INT_CLEAR_REG, 0x1, WCD9335_REG_BITS, 0 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_CFG), + VBAT_INT_DEST_SELECT_REG, 0x2, WCD9335_REG_BITS, 0 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_MASK3), + VBAT_INT_MASK_REG, 0x08, WCD9335_REG_BITS, 0 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_STATUS3), + VBAT_INT_STATUS_REG, 0x08, WCD9335_REG_BITS, 0 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_CLEAR3), + VBAT_INT_CLEAR_REG, 0x08, WCD9335_REG_BITS, 0 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_CFG), + VBAT_RELEASE_INT_DEST_SELECT_REG, 0x2, WCD9335_REG_BITS, 0 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_MASK3), + VBAT_RELEASE_INT_MASK_REG, 0x10, WCD9335_REG_BITS, 0 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_STATUS3), + VBAT_RELEASE_INT_STATUS_REG, 0x10, WCD9335_REG_BITS, 0 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_INTR_PIN2_CLEAR3), + VBAT_RELEASE_INT_CLEAR_REG, 0x10, WCD9335_REG_BITS, 0 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_TX_BASE), + SB_PGD_PORT_TX_WATERMARK_N, 0x1E, WCD9335_REG_BITS, 0x1 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_TX_BASE), + SB_PGD_PORT_TX_ENABLE_N, 0x1, WCD9335_REG_BITS, 0x1 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_RX_BASE), + SB_PGD_PORT_RX_WATERMARK_N, 0x1E, WCD9335_REG_BITS, 0x1 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + TASHA_SB_PGD_PORT_RX_BASE), + SB_PGD_PORT_RX_ENABLE_N, 0x1, WCD9335_REG_BITS, 0x1 + }, + { 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_CDC_ANC0_IIR_ADAPT_CTL), + AANC_FF_GAIN_ADAPTIVE, 0x4, WCD9335_REG_BITS, 0 + }, + { 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_CDC_ANC0_IIR_ADAPT_CTL), + AANC_FFGAIN_ADAPTIVE_EN, 0x8, WCD9335_REG_BITS, 0 + }, + { + 1, + (TASHA_REGISTER_START_OFFSET + WCD9335_CDC_ANC0_FF_A_GAIN_CTL), + AANC_GAIN_CONTROL, 0xFF, WCD9335_REG_BITS, 0 + }, +}; + +static struct afe_param_cdc_reg_cfg_data tasha_audio_reg_cfg = { + .num_registers = ARRAY_SIZE(audio_reg_cfg), + .reg_data = audio_reg_cfg, +}; + +static struct afe_param_id_cdc_aanc_version tasha_cdc_aanc_version = { + .cdc_aanc_minor_version = AFE_API_VERSION_CDC_AANC_VERSION, + .aanc_hw_version = AANC_HW_BLOCK_VERSION_2, +}; + +enum { + VI_SENSE_1, + VI_SENSE_2, + AIF4_SWITCH_VALUE, + AUDIO_NOMINAL, + CPE_NOMINAL, + HPH_PA_DELAY, + SB_CLK_GEAR, + ANC_MIC_AMIC1, + ANC_MIC_AMIC2, + ANC_MIC_AMIC3, + ANC_MIC_AMIC4, + ANC_MIC_AMIC5, + ANC_MIC_AMIC6, + CLASSH_CONFIG, +}; + +enum { + AIF1_PB = 0, + AIF1_CAP, + AIF2_PB, + AIF2_CAP, + AIF3_PB, + AIF3_CAP, + AIF4_PB, + AIF_MIX1_PB, + AIF4_MAD_TX, + AIF4_VIFEED, + AIF5_CPE_TX, + NUM_CODEC_DAIS, +}; + +enum { + INTn_1_MIX_INP_SEL_ZERO = 0, + INTn_1_MIX_INP_SEL_DEC0, + INTn_1_MIX_INP_SEL_DEC1, + INTn_1_MIX_INP_SEL_IIR0, + INTn_1_MIX_INP_SEL_IIR1, + INTn_1_MIX_INP_SEL_RX0, + INTn_1_MIX_INP_SEL_RX1, + INTn_1_MIX_INP_SEL_RX2, + INTn_1_MIX_INP_SEL_RX3, + INTn_1_MIX_INP_SEL_RX4, + INTn_1_MIX_INP_SEL_RX5, + INTn_1_MIX_INP_SEL_RX6, + INTn_1_MIX_INP_SEL_RX7, + +}; + +#define IS_VALID_NATIVE_FIFO_PORT(inp) \ + ((inp >= INTn_1_MIX_INP_SEL_RX0) && \ + (inp <= INTn_1_MIX_INP_SEL_RX3)) + +enum { + INTn_2_INP_SEL_ZERO = 0, + INTn_2_INP_SEL_RX0, + INTn_2_INP_SEL_RX1, + INTn_2_INP_SEL_RX2, + INTn_2_INP_SEL_RX3, + INTn_2_INP_SEL_RX4, + INTn_2_INP_SEL_RX5, + INTn_2_INP_SEL_RX6, + INTn_2_INP_SEL_RX7, + INTn_2_INP_SEL_PROXIMITY, +}; + +enum { + INTERP_EAR = 0, + INTERP_HPHL, + INTERP_HPHR, + INTERP_LO1, + INTERP_LO2, + INTERP_LO3, + INTERP_LO4, + INTERP_SPKR1, + INTERP_SPKR2, +}; + +struct interp_sample_rate { + int sample_rate; + int rate_val; +}; + +static struct interp_sample_rate int_prim_sample_rate_val[] = { + {8000, 0x0}, /* 8K */ + {16000, 0x1}, /* 16K */ + {24000, -EINVAL},/* 24K */ + {32000, 0x3}, /* 32K */ + {48000, 0x4}, /* 48K */ + {96000, 0x5}, /* 96K */ + {192000, 0x6}, /* 192K */ + {384000, 0x7}, /* 384K */ + {44100, 0x8}, /* 44.1K */ +}; + +static struct interp_sample_rate int_mix_sample_rate_val[] = { + {48000, 0x4}, /* 48K */ + {96000, 0x5}, /* 96K */ + {192000, 0x6}, /* 192K */ +}; + +static const struct wcd9xxx_ch tasha_rx_chs[TASHA_RX_MAX] = { + WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER, 0), + WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 1, 1), + WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 2, 2), + WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 3, 3), + WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 4, 4), + WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 5, 5), + WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 6, 6), + WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 7, 7), + WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 8, 8), + WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 9, 9), + WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 10, 10), + WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 11, 11), + WCD9XXX_CH(TASHA_RX_PORT_START_NUMBER + 12, 12), +}; + +static const struct wcd9xxx_ch tasha_tx_chs[TASHA_TX_MAX] = { + WCD9XXX_CH(0, 0), + WCD9XXX_CH(1, 1), + WCD9XXX_CH(2, 2), + WCD9XXX_CH(3, 3), + WCD9XXX_CH(4, 4), + WCD9XXX_CH(5, 5), + WCD9XXX_CH(6, 6), + WCD9XXX_CH(7, 7), + WCD9XXX_CH(8, 8), + WCD9XXX_CH(9, 9), + WCD9XXX_CH(10, 10), + WCD9XXX_CH(11, 11), + WCD9XXX_CH(12, 12), + WCD9XXX_CH(13, 13), + WCD9XXX_CH(14, 14), + WCD9XXX_CH(15, 15), +}; + +static const u32 vport_slim_check_table[NUM_CODEC_DAIS] = { + /* Needs to define in the same order of DAI enum definitions */ + 0, + BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX), + 0, + BIT(AIF1_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX), + 0, + BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX), + 0, + 0, + BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF5_CPE_TX), + 0, + BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX), +}; + +static const u32 vport_i2s_check_table[NUM_CODEC_DAIS] = { + 0, /* AIF1_PB */ + BIT(AIF2_CAP), /* AIF1_CAP */ + 0, /* AIF2_PB */ + BIT(AIF1_CAP), /* AIF2_CAP */ +}; + +/* Codec supports 2 IIR filters */ +enum { + IIR0 = 0, + IIR1, + IIR_MAX, +}; + +/* Each IIR has 5 Filter Stages */ +enum { + BAND1 = 0, + BAND2, + BAND3, + BAND4, + BAND5, + BAND_MAX, +}; + +enum { + COMPANDER_1, /* HPH_L */ + COMPANDER_2, /* HPH_R */ + COMPANDER_3, /* LO1_DIFF */ + COMPANDER_4, /* LO2_DIFF */ + COMPANDER_5, /* LO3_SE */ + COMPANDER_6, /* LO4_SE */ + COMPANDER_7, /* SWR SPK CH1 */ + COMPANDER_8, /* SWR SPK CH2 */ + COMPANDER_MAX, +}; + +enum { + SRC_IN_HPHL, + SRC_IN_LO1, + SRC_IN_HPHR, + SRC_IN_LO2, + SRC_IN_SPKRL, + SRC_IN_LO3, + SRC_IN_SPKRR, + SRC_IN_LO4, +}; + +enum { + SPLINE_SRC0, + SPLINE_SRC1, + SPLINE_SRC2, + SPLINE_SRC3, + SPLINE_SRC_MAX, +}; + +static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); +static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); +static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); + +static struct snd_soc_dai_driver tasha_dai[]; +static int wcd9335_get_micb_vout_ctl_val(u32 micb_mv); + +static int tasha_config_compander(struct snd_soc_codec *, int, int); +static void tasha_codec_set_tx_hold(struct snd_soc_codec *, u16, bool); +static int tasha_codec_internal_rco_ctrl(struct snd_soc_codec *codec, + bool enable); + +/* Hold instance to soundwire platform device */ +struct tasha_swr_ctrl_data { + struct platform_device *swr_pdev; + struct ida swr_ida; +}; + +struct wcd_swr_ctrl_platform_data { + void *handle; /* holds codec private data */ + int (*read)(void *handle, int reg); + int (*write)(void *handle, int reg, int val); + int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); + int (*clk)(void *handle, bool enable); + int (*handle_irq)(void *handle, + irqreturn_t (*swrm_irq_handler)(int irq, + void *data), + void *swrm_handle, + int action); +}; + +static struct wcd_mbhc_register + wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = { + WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN", + WCD9335_ANA_MBHC_MECH, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_DET_EN", + WCD9335_ANA_MBHC_MECH, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MECH_DETECTION_TYPE", + WCD9335_ANA_MBHC_MECH, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_CLAMP_CTL", + WCD9335_MBHC_PLUG_DETECT_CTL, 0x30, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_DETECTION_TYPE", + WCD9335_ANA_MBHC_ELECT, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_CTRL", + WCD9335_MBHC_PLUG_DETECT_CTL, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL", + WCD9335_ANA_MBHC_MECH, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PLUG_TYPE", + WCD9335_ANA_MBHC_MECH, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_PLUG_TYPE", + WCD9335_ANA_MBHC_MECH, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SW_HPH_LP_100K_TO_GND", + WCD9335_ANA_MBHC_MECH, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_SCHMT_ISRC", + WCD9335_ANA_MBHC_ELECT, 0x06, 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_EN", + WCD9335_ANA_MBHC_ELECT, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_INSREM_DBNC", + WCD9335_MBHC_PLUG_DETECT_CTL, 0x0F, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_DBNC", + WCD9335_MBHC_CTL_1, 0x03, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_VREF", + WCD9335_MBHC_CTL_2, 0x03, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT", + WCD9335_ANA_MBHC_RESULT_3, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT", + WCD9335_ANA_MBHC_RESULT_3, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT", + WCD9335_ANA_MBHC_RESULT_3, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_SCHMT_RESULT", + WCD9335_ANA_MBHC_RESULT_3, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_OCP_FSM_EN", + WCD9335_HPH_OCP_CTL, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_RESULT", + WCD9335_ANA_MBHC_RESULT_3, 0x07, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_ISRC_CTL", + WCD9335_ANA_MBHC_ELECT, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT", + WCD9335_ANA_MBHC_RESULT_3, 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL", + WCD9335_ANA_MICB2, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME", + WCD9335_HPH_CNP_WG_TIME, 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN", + WCD9335_ANA_HPH, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PA_EN", + WCD9335_ANA_HPH, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_PA_EN", + WCD9335_ANA_HPH, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE", + WCD9335_ANA_MBHC_RESULT_3, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL", + 0, 0, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN", + WCD9335_ANA_MBHC_ZDET, 0x01, 0, 0), + /* + * MBHC FSM status register is only available in Tasha 2.0. + * So, init with 0 later once the version is known, then values + * will be updated. + */ + WCD_MBHC_REGISTER("WCD_MBHC_FSM_STATUS", + 0, 0, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL", + WCD9335_MBHC_CTL_2, 0x70, 4, 0), +}; + +static const struct wcd_mbhc_intr intr_ids = { + .mbhc_sw_intr = WCD9335_IRQ_MBHC_SW_DET, + .mbhc_btn_press_intr = WCD9335_IRQ_MBHC_BUTTON_PRESS_DET, + .mbhc_btn_release_intr = WCD9335_IRQ_MBHC_BUTTON_RELEASE_DET, + .mbhc_hs_ins_intr = WCD9335_IRQ_MBHC_ELECT_INS_REM_LEG_DET, + .mbhc_hs_rem_intr = WCD9335_IRQ_MBHC_ELECT_INS_REM_DET, + .hph_left_ocp = WCD9335_IRQ_HPH_PA_OCPL_FAULT, + .hph_right_ocp = WCD9335_IRQ_HPH_PA_OCPR_FAULT, +}; + +struct wcd_vbat { + bool is_enabled; + bool adc_config; + /* Variables to cache Vbat ADC output values */ + u16 dcp1; + u16 dcp2; +}; + +struct hpf_work { + struct tasha_priv *tasha; + u8 decimator; + u8 hpf_cut_off_freq; + struct delayed_work dwork; +}; + +#define WCD9335_SPK_ANC_EN_DELAY_MS 350 +static int spk_anc_en_delay = WCD9335_SPK_ANC_EN_DELAY_MS; +module_param(spk_anc_en_delay, int, 0664); +MODULE_PARM_DESC(spk_anc_en_delay, "delay to enable anc in speaker path"); + +struct spk_anc_work { + struct tasha_priv *tasha; + struct delayed_work dwork; +}; + +struct tx_mute_work { + struct tasha_priv *tasha; + u8 decimator; + struct delayed_work dwork; +}; + +struct tasha_priv { + struct device *dev; + struct wcd9xxx *wcd9xxx; + + struct snd_soc_codec *codec; + u32 adc_count; + u32 rx_bias_count; + s32 dmic_0_1_clk_cnt; + s32 dmic_2_3_clk_cnt; + s32 dmic_4_5_clk_cnt; + s32 ldo_h_users; + s32 micb_ref[TASHA_MAX_MICBIAS]; + s32 pullup_ref[TASHA_MAX_MICBIAS]; + + u32 anc_slot; + bool anc_func; + + /* Vbat module */ + struct wcd_vbat vbat; + + /* cal info for codec */ + struct fw_info *fw_data; + + /*track tasha interface type*/ + u8 intf_type; + + /* num of slim ports required */ + struct wcd9xxx_codec_dai_data dai[NUM_CODEC_DAIS]; + + /* SoundWire data structure */ + struct tasha_swr_ctrl_data *swr_ctrl_data; + int nr; + + /*compander*/ + int comp_enabled[COMPANDER_MAX]; + + /* Maintain the status of AUX PGA */ + int aux_pga_cnt; + u8 aux_l_gain; + u8 aux_r_gain; + + bool spkr_pa_widget_on; + struct regulator *spkdrv_reg; + struct regulator *spkdrv2_reg; + + bool mbhc_started; + /* class h specific data */ + struct wcd_clsh_cdc_data clsh_d; + + struct afe_param_cdc_slimbus_slave_cfg slimbus_slave_cfg; + + /* + * list used to save/restore registers at start and + * end of impedance measurement + */ + struct list_head reg_save_restore; + + /* handle to cpe core */ + struct wcd_cpe_core *cpe_core; + u32 current_cpe_clk_freq; + enum tasha_sido_voltage sido_voltage; + int sido_ccl_cnt; + + u32 ana_rx_supplies; + /* Multiplication factor used for impedance detection */ + int zdet_gain_mul_fact; + + /* to track the status */ + unsigned long status_mask; + + struct work_struct tasha_add_child_devices_work; + struct wcd_swr_ctrl_platform_data swr_plat_data; + + /* Port values for Rx and Tx codec_dai */ + unsigned int rx_port_value[TASHA_RX_MAX]; + unsigned int tx_port_value; + + unsigned int vi_feed_value; + /* Tasha Interpolator Mode Select for EAR, HPH_L and HPH_R */ + u32 hph_mode; + + u16 prim_int_users[TASHA_NUM_INTERPOLATORS]; + int spl_src_users[SPLINE_SRC_MAX]; + + struct wcd9xxx_resmgr_v2 *resmgr; + struct delayed_work power_gate_work; + struct mutex power_lock; + struct mutex sido_lock; + + /* mbhc module */ + struct wcd_mbhc mbhc; + struct blocking_notifier_head notifier; + struct mutex micb_lock; + + struct clk *wcd_ext_clk; + struct clk *wcd_native_clk; + struct mutex swr_read_lock; + struct mutex swr_write_lock; + struct mutex swr_clk_lock; + int swr_clk_users; + int native_clk_users; + int (*zdet_gpio_cb)(struct snd_soc_codec *codec, bool high); + + struct snd_info_entry *entry; + struct snd_info_entry *version_entry; + int power_active_ref; + + struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX]; + + int (*machine_codec_event_cb)(struct snd_soc_codec *codec, + enum wcd9335_codec_event); + int spkr_gain_offset; + int spkr_mode; + int ear_spkr_gain; + struct hpf_work tx_hpf_work[TASHA_NUM_DECIMATORS]; + struct tx_mute_work tx_mute_dwork[TASHA_NUM_DECIMATORS]; + struct spk_anc_work spk_anc_dwork; + struct mutex codec_mutex; + int hph_l_gain; + int hph_r_gain; + int rx_7_count; + int rx_8_count; + bool clk_mode; + bool clk_internal; + + /* Lock to protect mclk enablement */ + struct mutex mclk_lock; +}; + +static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec, + bool vote); + +static const struct tasha_reg_mask_val tasha_spkr_default[] = { + {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x80}, + {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80}, + {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01}, + {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01}, + {WCD9335_CDC_BOOST0_BOOST_CTL, 0x7C, 0x50}, + {WCD9335_CDC_BOOST1_BOOST_CTL, 0x7C, 0x50}, +}; + +static const struct tasha_reg_mask_val tasha_spkr_mode1[] = { + {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x00}, + {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x00}, + {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x00}, + {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x00}, + {WCD9335_CDC_BOOST0_BOOST_CTL, 0x7C, 0x44}, + {WCD9335_CDC_BOOST1_BOOST_CTL, 0x7C, 0x44}, +}; + +/** + * tasha_set_spkr_gain_offset - offset the speaker path + * gain with the given offset value. + * + * @codec: codec instance + * @offset: Indicates speaker path gain offset value. + * + * Returns 0 on success or -EINVAL on error. + */ +int tasha_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset) +{ + struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + + if (!priv) + return -EINVAL; + + priv->spkr_gain_offset = offset; + return 0; +} +EXPORT_SYMBOL(tasha_set_spkr_gain_offset); + +/** + * tasha_set_spkr_mode - Configures speaker compander and smartboost + * settings based on speaker mode. + * + * @codec: codec instance + * @mode: Indicates speaker configuration mode. + * + * Returns 0 on success or -EINVAL on error. + */ +int tasha_set_spkr_mode(struct snd_soc_codec *codec, int mode) +{ + struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + int i; + const struct tasha_reg_mask_val *regs; + int size; + + if (!priv) + return -EINVAL; + + switch (mode) { + case SPKR_MODE_1: + regs = tasha_spkr_mode1; + size = ARRAY_SIZE(tasha_spkr_mode1); + break; + default: + regs = tasha_spkr_default; + size = ARRAY_SIZE(tasha_spkr_default); + break; + } + + priv->spkr_mode = mode; + for (i = 0; i < size; i++) + snd_soc_update_bits(codec, regs[i].reg, + regs[i].mask, regs[i].val); + return 0; +} +EXPORT_SYMBOL(tasha_set_spkr_mode); + +static void tasha_enable_sido_buck(struct snd_soc_codec *codec) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + snd_soc_update_bits(codec, WCD9335_ANA_RCO, 0x80, 0x80); + snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, 0x02, 0x02); + /* 100us sleep needed after IREF settings */ + usleep_range(100, 110); + snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, 0x04, 0x04); + /* 100us sleep needed after VREF settings */ + usleep_range(100, 110); + tasha->resmgr->sido_input_src = SIDO_SOURCE_RCO_BG; +} + +static void tasha_cdc_sido_ccl_enable(struct tasha_priv *tasha, bool ccl_flag) +{ + struct snd_soc_codec *codec = tasha->codec; + + if (!codec) + return; + + if (!TASHA_IS_2_0(tasha->wcd9xxx)) { + dev_dbg(codec->dev, "%s: tasha version < 2p0, return\n", + __func__); + return; + } + dev_dbg(codec->dev, "%s: sido_ccl_cnt=%d, ccl_flag:%d\n", + __func__, tasha->sido_ccl_cnt, ccl_flag); + if (ccl_flag) { + if (++tasha->sido_ccl_cnt == 1) + snd_soc_update_bits(codec, + WCD9335_SIDO_SIDO_CCL_10, 0xFF, 0x6E); + } else { + if (tasha->sido_ccl_cnt == 0) { + dev_dbg(codec->dev, "%s: sido_ccl already disabled\n", + __func__); + return; + } + if (--tasha->sido_ccl_cnt == 0) + snd_soc_update_bits(codec, + WCD9335_SIDO_SIDO_CCL_10, 0xFF, 0x02); + } +} + +static bool tasha_cdc_is_svs_enabled(struct tasha_priv *tasha) +{ + if (TASHA_IS_2_0(tasha->wcd9xxx) && + svs_scaling_enabled) + return true; + + return false; +} + +static int tasha_cdc_req_mclk_enable(struct tasha_priv *tasha, + bool enable) +{ + int ret = 0; + + mutex_lock(&tasha->mclk_lock); + if (enable) { + tasha_cdc_sido_ccl_enable(tasha, true); + ret = clk_prepare_enable(tasha->wcd_ext_clk); + if (ret) { + dev_err(tasha->dev, "%s: ext clk enable failed\n", + __func__); + goto unlock_mutex; + } + /* get BG */ + wcd_resmgr_enable_master_bias(tasha->resmgr); + /* get MCLK */ + wcd_resmgr_enable_clk_block(tasha->resmgr, WCD_CLK_MCLK); + } else { + /* put MCLK */ + wcd_resmgr_disable_clk_block(tasha->resmgr, WCD_CLK_MCLK); + /* put BG */ + wcd_resmgr_disable_master_bias(tasha->resmgr); + clk_disable_unprepare(tasha->wcd_ext_clk); + tasha_cdc_sido_ccl_enable(tasha, false); + } +unlock_mutex: + mutex_unlock(&tasha->mclk_lock); + return ret; +} + +static int tasha_cdc_check_sido_value(enum tasha_sido_voltage req_mv) +{ + if ((req_mv != SIDO_VOLTAGE_SVS_MV) && + (req_mv != SIDO_VOLTAGE_NOMINAL_MV)) + return -EINVAL; + + return 0; +} + +static void tasha_codec_apply_sido_voltage( + struct tasha_priv *tasha, + enum tasha_sido_voltage req_mv) +{ + u32 vout_d_val; + struct snd_soc_codec *codec = tasha->codec; + int ret; + + if (!codec) + return; + + if (!tasha_cdc_is_svs_enabled(tasha)) + return; + + if ((sido_buck_svs_voltage != SIDO_VOLTAGE_SVS_MV) && + (sido_buck_svs_voltage != SIDO_VOLTAGE_NOMINAL_MV)) + sido_buck_svs_voltage = SIDO_VOLTAGE_SVS_MV; + + ret = tasha_cdc_check_sido_value(req_mv); + if (ret < 0) { + dev_dbg(codec->dev, "%s: requested mv=%d not in range\n", + __func__, req_mv); + return; + } + if (req_mv == tasha->sido_voltage) { + dev_dbg(codec->dev, "%s: Already at requested mv=%d\n", + __func__, req_mv); + return; + } + if (req_mv == sido_buck_svs_voltage) { + if (test_bit(AUDIO_NOMINAL, &tasha->status_mask) || + test_bit(CPE_NOMINAL, &tasha->status_mask)) { + dev_dbg(codec->dev, + "%s: nominal client running, status_mask=%lu\n", + __func__, tasha->status_mask); + return; + } + } + /* compute the vout_d step value */ + vout_d_val = CALCULATE_VOUT_D(req_mv); + snd_soc_write(codec, WCD9335_ANA_BUCK_VOUT_D, vout_d_val & 0xFF); + snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, 0x80, 0x80); + + /* 1 msec sleep required after SIDO Vout_D voltage change */ + usleep_range(1000, 1100); + tasha->sido_voltage = req_mv; + dev_dbg(codec->dev, + "%s: updated SIDO buck Vout_D to %d, vout_d step = %u\n", + __func__, tasha->sido_voltage, vout_d_val); + + snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, + 0x80, 0x00); +} + +static int tasha_codec_update_sido_voltage( + struct tasha_priv *tasha, + enum tasha_sido_voltage req_mv) +{ + int ret = 0; + + if (!tasha_cdc_is_svs_enabled(tasha)) + return ret; + + mutex_lock(&tasha->sido_lock); + /* enable mclk before setting SIDO voltage */ + ret = tasha_cdc_req_mclk_enable(tasha, true); + if (ret) { + dev_err(tasha->dev, "%s: ext clk enable failed\n", + __func__); + goto err; + } + tasha_codec_apply_sido_voltage(tasha, req_mv); + tasha_cdc_req_mclk_enable(tasha, false); + +err: + mutex_unlock(&tasha->sido_lock); + return ret; +} + +int tasha_enable_efuse_sensing(struct snd_soc_codec *codec) +{ + struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + + tasha_cdc_mclk_enable(codec, true, false); + + if (!TASHA_IS_2_0(priv->wcd9xxx)) + snd_soc_update_bits(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, + 0x1E, 0x02); + snd_soc_update_bits(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, + 0x01, 0x01); + /* + * 5ms sleep required after enabling efuse control + * before checking the status. + */ + usleep_range(5000, 5500); + if (!(snd_soc_read(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS) & 0x01)) + WARN(1, "%s: Efuse sense is not complete\n", __func__); + + if (TASHA_IS_2_0(priv->wcd9xxx)) { + if (!(snd_soc_read(codec, + WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0) & 0x40)) + snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST, + 0x04, 0x00); + tasha_enable_sido_buck(codec); + } + + tasha_cdc_mclk_enable(codec, false, false); + + return 0; +} +EXPORT_SYMBOL(tasha_enable_efuse_sensing); + +void *tasha_get_afe_config(struct snd_soc_codec *codec, + enum afe_config_type config_type) +{ + struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + + switch (config_type) { + case AFE_SLIMBUS_SLAVE_CONFIG: + return &priv->slimbus_slave_cfg; + case AFE_CDC_REGISTERS_CONFIG: + return &tasha_audio_reg_cfg; + case AFE_SLIMBUS_SLAVE_PORT_CONFIG: + return &tasha_slimbus_slave_port_cfg; + case AFE_AANC_VERSION: + return &tasha_cdc_aanc_version; + case AFE_CLIP_BANK_SEL: + return NULL; + case AFE_CDC_CLIP_REGISTERS_CONFIG: + return NULL; + case AFE_CDC_REGISTER_PAGE_CONFIG: + return &tasha_cdc_reg_page_cfg; + default: + dev_err(codec->dev, "%s: Unknown config_type 0x%x\n", + __func__, config_type); + return NULL; + } +} +EXPORT_SYMBOL(tasha_get_afe_config); + +/* + * tasha_event_register: Registers a machine driver callback + * function with codec private data for post ADSP sub-system + * restart (SSR). This callback function will be called from + * codec driver once codec comes out of reset after ADSP SSR. + * + * @machine_event_cb: callback function from machine driver + * @codec: Codec instance + * + * Return: none + */ +void tasha_event_register( + int (*machine_event_cb)(struct snd_soc_codec *codec, + enum wcd9335_codec_event), + struct snd_soc_codec *codec) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + if (tasha) + tasha->machine_codec_event_cb = machine_event_cb; + else + dev_dbg(codec->dev, "%s: Invalid tasha_priv data\n", __func__); +} +EXPORT_SYMBOL(tasha_event_register); + +static int tasha_mbhc_request_irq(struct snd_soc_codec *codec, + int irq, irq_handler_t handler, + const char *name, void *data) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + + return wcd9xxx_request_irq(core_res, irq, handler, name, data); +} + +static void tasha_mbhc_irq_control(struct snd_soc_codec *codec, + int irq, bool enable) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + if (enable) + wcd9xxx_enable_irq(core_res, irq); + else + wcd9xxx_disable_irq(core_res, irq); +} + +static int tasha_mbhc_free_irq(struct snd_soc_codec *codec, + int irq, void *data) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + + wcd9xxx_free_irq(core_res, irq, data); + return 0; +} + +static void tasha_mbhc_clk_setup(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) + snd_soc_update_bits(codec, WCD9335_MBHC_CTL_1, + 0x80, 0x80); + else + snd_soc_update_bits(codec, WCD9335_MBHC_CTL_1, + 0x80, 0x00); +} + +static int tasha_mbhc_btn_to_num(struct snd_soc_codec *codec) +{ + return snd_soc_read(codec, WCD9335_ANA_MBHC_RESULT_3) & 0x7; +} + +static void tasha_mbhc_mbhc_bias_control(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) + snd_soc_update_bits(codec, WCD9335_ANA_MBHC_ELECT, + 0x01, 0x01); + else + snd_soc_update_bits(codec, WCD9335_ANA_MBHC_ELECT, + 0x01, 0x00); +} + +static void tasha_mbhc_program_btn_thr(struct snd_soc_codec *codec, + s16 *btn_low, s16 *btn_high, + int num_btn, bool is_micbias) +{ + int i; + int vth; + + if (num_btn > WCD_MBHC_DEF_BUTTONS) { + dev_err(codec->dev, "%s: invalid number of buttons: %d\n", + __func__, num_btn); + return; + } + /* + * Tasha just needs one set of thresholds for button detection + * due to micbias voltage ramp to pullup upon button press. So + * btn_low and is_micbias are ignored and always program button + * thresholds using btn_high. + */ + for (i = 0; i < num_btn; i++) { + vth = ((btn_high[i] * 2) / 25) & 0x3F; + snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN0 + i, + 0xFC, vth << 2); + dev_dbg(codec->dev, "%s: btn_high[%d]: %d, vth: %d\n", + __func__, i, btn_high[i], vth); + } +} + +static bool tasha_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock) +{ + struct snd_soc_codec *codec = mbhc->codec; + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + if (lock) + return wcd9xxx_lock_sleep(core_res); + else { + wcd9xxx_unlock_sleep(core_res); + return 0; + } +} + +static int tasha_mbhc_register_notifier(struct wcd_mbhc *mbhc, + struct notifier_block *nblock, + bool enable) +{ + struct snd_soc_codec *codec = mbhc->codec; + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + if (enable) + return blocking_notifier_chain_register(&tasha->notifier, + nblock); + else + return blocking_notifier_chain_unregister(&tasha->notifier, + nblock); +} + +static bool tasha_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) +{ + u8 val; + + if (micb_num == MIC_BIAS_2) { + val = (snd_soc_read(mbhc->codec, WCD9335_ANA_MICB2) >> 6); + if (val == 0x01) + return true; + } + return false; +} + +static bool tasha_mbhc_hph_pa_on_status(struct snd_soc_codec *codec) +{ + return (snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0) ? true : false; +} + +static void tasha_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec, + enum mbhc_hs_pullup_iref pull_up_cur) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + if (!tasha) + return; + + /* Default pull up current to 2uA */ + if (pull_up_cur < I_OFF || pull_up_cur > I_3P0_UA || + pull_up_cur == I_DEFAULT) + pull_up_cur = I_2P0_UA; + + dev_dbg(codec->dev, "%s: HS pull up current:%d\n", + __func__, pull_up_cur); + + if (TASHA_IS_2_0(tasha->wcd9xxx)) + snd_soc_update_bits(codec, WCD9335_MBHC_PLUG_DETECT_CTL, + 0xC0, pull_up_cur << 6); + else + snd_soc_update_bits(codec, WCD9335_MBHC_PLUG_DETECT_CTL, + 0xC0, 0x40); +} + +static int tasha_enable_ext_mb_source(struct wcd_mbhc *mbhc, + bool turn_on) +{ + struct snd_soc_codec *codec = mbhc->codec; + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + int ret = 0; + struct on_demand_supply *supply; + + if (!tasha) + return -EINVAL; + + supply = &tasha->on_demand_list[ON_DEMAND_MICBIAS]; + if (!supply->supply) { + dev_dbg(codec->dev, "%s: warning supply not present ond for %s\n", + __func__, "onDemand Micbias"); + return ret; + } + + dev_dbg(codec->dev, "%s turn_on: %d count: %d\n", __func__, turn_on, + supply->ondemand_supply_count); + + if (turn_on) { + if (!(supply->ondemand_supply_count)) { + ret = snd_soc_dapm_force_enable_pin( + snd_soc_codec_get_dapm(codec), + "MICBIAS_REGULATOR"); + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + } + supply->ondemand_supply_count++; + } else { + if (supply->ondemand_supply_count > 0) + supply->ondemand_supply_count--; + if (!(supply->ondemand_supply_count)) { + ret = snd_soc_dapm_disable_pin( + snd_soc_codec_get_dapm(codec), + "MICBIAS_REGULATOR"); + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + } + } + + if (ret) + dev_err(codec->dev, "%s: Failed to %s external micbias source\n", + __func__, turn_on ? "enable" : "disabled"); + else + dev_dbg(codec->dev, "%s: %s external micbias source\n", + __func__, turn_on ? "Enabled" : "Disabled"); + + return ret; +} + +static int tasha_micbias_control(struct snd_soc_codec *codec, + int micb_num, + int req, bool is_dapm) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + int micb_index = micb_num - 1; + u16 micb_reg; + int pre_off_event = 0, post_off_event = 0; + int post_on_event = 0, post_dapm_off = 0; + int post_dapm_on = 0; + + if ((micb_index < 0) || (micb_index > TASHA_MAX_MICBIAS - 1)) { + dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n", + __func__, micb_index); + return -EINVAL; + } + switch (micb_num) { + case MIC_BIAS_1: + micb_reg = WCD9335_ANA_MICB1; + break; + case MIC_BIAS_2: + micb_reg = WCD9335_ANA_MICB2; + pre_off_event = WCD_EVENT_PRE_MICBIAS_2_OFF; + post_off_event = WCD_EVENT_POST_MICBIAS_2_OFF; + post_on_event = WCD_EVENT_POST_MICBIAS_2_ON; + post_dapm_on = WCD_EVENT_POST_DAPM_MICBIAS_2_ON; + post_dapm_off = WCD_EVENT_POST_DAPM_MICBIAS_2_OFF; + break; + case MIC_BIAS_3: + micb_reg = WCD9335_ANA_MICB3; + break; + case MIC_BIAS_4: + micb_reg = WCD9335_ANA_MICB4; + break; + default: + dev_err(codec->dev, "%s: Invalid micbias number: %d\n", + __func__, micb_num); + return -EINVAL; + } + mutex_lock(&tasha->micb_lock); + + switch (req) { + case MICB_PULLUP_ENABLE: + tasha->pullup_ref[micb_index]++; + if ((tasha->pullup_ref[micb_index] == 1) && + (tasha->micb_ref[micb_index] == 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + break; + case MICB_PULLUP_DISABLE: + if (tasha->pullup_ref[micb_index] > 0) + tasha->pullup_ref[micb_index]--; + if ((tasha->pullup_ref[micb_index] == 0) && + (tasha->micb_ref[micb_index] == 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + break; + case MICB_ENABLE: + tasha->micb_ref[micb_index]++; + if (tasha->micb_ref[micb_index] == 1) { + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + if (post_on_event) + blocking_notifier_call_chain(&tasha->notifier, + post_on_event, &tasha->mbhc); + } + if (is_dapm && post_dapm_on) + blocking_notifier_call_chain(&tasha->notifier, + post_dapm_on, &tasha->mbhc); + break; + case MICB_DISABLE: + if (tasha->micb_ref[micb_index] > 0) + tasha->micb_ref[micb_index]--; + if ((tasha->micb_ref[micb_index] == 0) && + (tasha->pullup_ref[micb_index] > 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + else if ((tasha->micb_ref[micb_index] == 0) && + (tasha->pullup_ref[micb_index] == 0)) { + if (pre_off_event) + blocking_notifier_call_chain(&tasha->notifier, + pre_off_event, &tasha->mbhc); + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + if (post_off_event) + blocking_notifier_call_chain(&tasha->notifier, + post_off_event, &tasha->mbhc); + } + if (is_dapm && post_dapm_off) + blocking_notifier_call_chain(&tasha->notifier, + post_dapm_off, &tasha->mbhc); + break; + }; + + dev_dbg(codec->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", + __func__, micb_num, tasha->micb_ref[micb_index], + tasha->pullup_ref[micb_index]); + + mutex_unlock(&tasha->micb_lock); + + return 0; +} + +static int tasha_mbhc_request_micbias(struct snd_soc_codec *codec, + int micb_num, int req) +{ + int ret; + + /* + * If micbias is requested, make sure that there + * is vote to enable mclk + */ + if (req == MICB_ENABLE) + tasha_cdc_mclk_enable(codec, true, false); + + ret = tasha_micbias_control(codec, micb_num, req, false); + + /* + * Release vote for mclk while requesting for + * micbias disable + */ + if (req == MICB_DISABLE) + tasha_cdc_mclk_enable(codec, false, false); + + return ret; +} + +static void tasha_mbhc_micb_ramp_control(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP, + 0x1C, 0x0C); + snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP, + 0x80, 0x80); + } else { + snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP, + 0x80, 0x00); + snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP, + 0x1C, 0x00); + } +} + +static struct firmware_cal *tasha_get_hwdep_fw_cal(struct wcd_mbhc *mbhc, + enum wcd_cal_type type) +{ + struct tasha_priv *tasha; + struct firmware_cal *hwdep_cal; + struct snd_soc_codec *codec = mbhc->codec; + + if (!codec) { + pr_err("%s: NULL codec pointer\n", __func__); + return NULL; + } + tasha = snd_soc_codec_get_drvdata(codec); + hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, type); + if (!hwdep_cal) + dev_err(codec->dev, "%s: cal not sent by %d\n", + __func__, type); + + return hwdep_cal; +} + +static int tasha_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, + int req_volt, + int micb_num) +{ + int cur_vout_ctl, req_vout_ctl; + int micb_reg, micb_val, micb_en; + + switch (micb_num) { + case MIC_BIAS_1: + micb_reg = WCD9335_ANA_MICB1; + break; + case MIC_BIAS_2: + micb_reg = WCD9335_ANA_MICB2; + break; + case MIC_BIAS_3: + micb_reg = WCD9335_ANA_MICB3; + break; + case MIC_BIAS_4: + micb_reg = WCD9335_ANA_MICB4; + break; + default: + return -EINVAL; + } + + /* + * If requested micbias voltage is same as current micbias + * voltage, then just return. Otherwise, adjust voltage as + * per requested value. If micbias is already enabled, then + * to avoid slow micbias ramp-up or down enable pull-up + * momentarily, change the micbias value and then re-enable + * micbias. + */ + micb_val = snd_soc_read(codec, micb_reg); + micb_en = (micb_val & 0xC0) >> 6; + cur_vout_ctl = micb_val & 0x3F; + + req_vout_ctl = wcd9335_get_micb_vout_ctl_val(req_volt); + if (req_vout_ctl < 0) + return -EINVAL; + if (cur_vout_ctl == req_vout_ctl) + return 0; + + dev_dbg(codec->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n", + __func__, micb_num, WCD_VOUT_CTL_TO_MICB(cur_vout_ctl), + req_volt, micb_en); + + if (micb_en == 0x1) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + + snd_soc_update_bits(codec, micb_reg, 0x3F, req_vout_ctl); + + if (micb_en == 0x1) { + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + /* + * Add 2ms delay as per HW requirement after enabling + * micbias + */ + usleep_range(2000, 2100); + } + + return 0; +} + +static int tasha_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec, + int micb_num, bool req_en) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + int rc, micb_mv; + + if (micb_num != MIC_BIAS_2) + return -EINVAL; + + /* + * If device tree micbias level is already above the minimum + * voltage needed to detect threshold microphone, then do + * not change the micbias, just return. + */ + if (pdata->micbias.micb2_mv >= WCD_MBHC_THR_HS_MICB_MV) + return 0; + + micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb2_mv; + + mutex_lock(&tasha->micb_lock); + rc = tasha_mbhc_micb_adjust_voltage(codec, micb_mv, MIC_BIAS_2); + mutex_unlock(&tasha->micb_lock); + + return rc; +} + +static inline void tasha_mbhc_get_result_params(struct wcd9xxx *wcd9xxx, + s16 *d1_a, u16 noff, + int32_t *zdet) +{ + int i; + int val, val1; + s16 c1; + s32 x1, d1; + int32_t denom; + int minCode_param[] = { + 3277, 1639, 820, 410, 205, 103, 52, 26 + }; + + regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_ZDET, 0x20, 0x20); + for (i = 0; i < TASHA_ZDET_NUM_MEASUREMENTS; i++) { + regmap_read(wcd9xxx->regmap, WCD9335_ANA_MBHC_RESULT_2, &val); + if (val & 0x80) + break; + } + val = val << 0x8; + regmap_read(wcd9xxx->regmap, WCD9335_ANA_MBHC_RESULT_1, &val1); + val |= val1; + regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_ZDET, 0x20, 0x00); + x1 = TASHA_MBHC_GET_X1(val); + c1 = TASHA_MBHC_GET_C1(val); + /* If ramp is not complete, give additional 5ms */ + if ((c1 < 2) && x1) + usleep_range(5000, 5050); + + if (!c1 || !x1) { + dev_dbg(wcd9xxx->dev, + "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n", + __func__, c1, x1); + goto ramp_down; + } + d1 = d1_a[c1]; + denom = (x1 * d1) - (1 << (14 - noff)); + if (denom > 0) + *zdet = (TASHA_MBHC_ZDET_CONST * 1000) / denom; + else if (x1 < minCode_param[noff]) + *zdet = TASHA_ZDET_FLOATING_IMPEDANCE; + + dev_dbg(wcd9xxx->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n", + __func__, d1, c1, x1, *zdet); +ramp_down: + i = 0; + while (x1) { + regmap_bulk_read(wcd9xxx->regmap, + WCD9335_ANA_MBHC_RESULT_1, (u8 *)&val, 2); + x1 = TASHA_MBHC_GET_X1(val); + i++; + if (i == TASHA_ZDET_NUM_MEASUREMENTS) + break; + } +} + +/* + * tasha_mbhc_zdet_gpio_ctrl: Register callback function for + * controlling the switch on hifi amps. Default switch state + * will put a 51ohm load in parallel to the hph load. So, + * impedance detection function will pull the gpio high + * to make the switch open. + * + * @zdet_gpio_cb: callback function from machine driver + * @codec: Codec instance + * + * Return: none + */ +void tasha_mbhc_zdet_gpio_ctrl( + int (*zdet_gpio_cb)(struct snd_soc_codec *codec, bool high), + struct snd_soc_codec *codec) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + tasha->zdet_gpio_cb = zdet_gpio_cb; +} +EXPORT_SYMBOL(tasha_mbhc_zdet_gpio_ctrl); + +static void tasha_mbhc_zdet_ramp(struct snd_soc_codec *codec, + struct tasha_mbhc_zdet_param *zdet_param, + int32_t *zl, int32_t *zr, s16 *d1_a) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + int32_t zdet = 0; + + snd_soc_update_bits(codec, WCD9335_MBHC_ZDET_ANA_CTL, 0x70, + zdet_param->ldo_ctl << 4); + snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN5, 0xFC, + zdet_param->btn5); + snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN6, 0xFC, + zdet_param->btn6); + snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN7, 0xFC, + zdet_param->btn7); + snd_soc_update_bits(codec, WCD9335_MBHC_ZDET_ANA_CTL, 0x0F, + zdet_param->noff); + snd_soc_update_bits(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x0F, + zdet_param->nshift); + + if (!zl) + goto z_right; + /* Start impedance measurement for HPH_L */ + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_ZDET, 0x80, 0x80); + dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_L, noff = %d\n", + __func__, zdet_param->noff); + tasha_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet); + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_ZDET, 0x80, 0x00); + + *zl = zdet; + +z_right: + if (!zr) + return; + /* Start impedance measurement for HPH_R */ + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_ZDET, 0x40, 0x40); + dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_R, noff = %d\n", + __func__, zdet_param->noff); + tasha_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet); + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_ZDET, 0x40, 0x00); + + *zr = zdet; +} + +static inline void tasha_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec, + int32_t *z_val, int flag_l_r) +{ + s16 q1; + int q1_cal; + + if (*z_val < (TASHA_ZDET_VAL_400/1000)) + q1 = snd_soc_read(codec, + WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT1 + (2 * flag_l_r)); + else + q1 = snd_soc_read(codec, + WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT2 + (2 * flag_l_r)); + if (q1 & 0x80) + q1_cal = (10000 - ((q1 & 0x7F) * 25)); + else + q1_cal = (10000 + (q1 * 25)); + if (q1_cal > 0) + *z_val = ((*z_val) * 10000) / q1_cal; +} + +static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, + uint32_t *zr) +{ + struct snd_soc_codec *codec = mbhc->codec; + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; + s16 reg0, reg1, reg2, reg3, reg4; + int32_t z1L, z1R, z1Ls; + int zMono, z_diff1, z_diff2; + bool is_fsm_disable = false; + bool is_change = false; + struct tasha_mbhc_zdet_param zdet_param[] = { + {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */ + {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */ + {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */ + {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */ + }; + struct tasha_mbhc_zdet_param *zdet_param_ptr = NULL; + s16 d1_a[][4] = { + {0, 30, 90, 30}, + {0, 30, 30, 5}, + {0, 30, 30, 5}, + {0, 30, 30, 5}, + }; + s16 *d1 = NULL; + + if (!TASHA_IS_2_0(wcd9xxx)) { + dev_dbg(codec->dev, "%s: Z-det is not supported for this codec version\n", + __func__); + *zl = 0; + *zr = 0; + return; + } + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + + if (tasha->zdet_gpio_cb) + is_change = tasha->zdet_gpio_cb(codec, true); + + reg0 = snd_soc_read(codec, WCD9335_ANA_MBHC_BTN5); + reg1 = snd_soc_read(codec, WCD9335_ANA_MBHC_BTN6); + reg2 = snd_soc_read(codec, WCD9335_ANA_MBHC_BTN7); + reg3 = snd_soc_read(codec, WCD9335_MBHC_CTL_1); + reg4 = snd_soc_read(codec, WCD9335_MBHC_ZDET_ANA_CTL); + + if (snd_soc_read(codec, WCD9335_ANA_MBHC_ELECT) & 0x80) { + is_fsm_disable = true; + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_ELECT, 0x80, 0x00); + } + + /* For NO-jack, disable L_DET_EN before Z-det measurements */ + if (mbhc->hphl_swh) + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_MECH, 0x80, 0x00); + + /* Enable AZ */ + snd_soc_update_bits(codec, WCD9335_MBHC_CTL_1, 0x0C, 0x04); + /* Turn off 100k pull down on HPHL */ + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_MECH, 0x01, 0x00); + + /* First get impedance on Left */ + d1 = d1_a[1]; + zdet_param_ptr = &zdet_param[1]; + tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + + if (!TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z1L)) + goto left_ch_impedance; + + /* second ramp for left ch */ + if (z1L < TASHA_ZDET_VAL_32) { + zdet_param_ptr = &zdet_param[0]; + d1 = d1_a[0]; + } else if ((z1L > TASHA_ZDET_VAL_400) && (z1L <= TASHA_ZDET_VAL_1200)) { + zdet_param_ptr = &zdet_param[2]; + d1 = d1_a[2]; + } else if (z1L > TASHA_ZDET_VAL_1200) { + zdet_param_ptr = &zdet_param[3]; + d1 = d1_a[3]; + } + tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + +left_ch_impedance: + if ((z1L == TASHA_ZDET_FLOATING_IMPEDANCE) || + (z1L > TASHA_ZDET_VAL_100K)) { + *zl = TASHA_ZDET_FLOATING_IMPEDANCE; + zdet_param_ptr = &zdet_param[1]; + d1 = d1_a[1]; + } else { + *zl = z1L/1000; + tasha_wcd_mbhc_qfuse_cal(codec, zl, 0); + } + dev_dbg(codec->dev, "%s: impedance on HPH_L = %d(ohms)\n", + __func__, *zl); + + /* start of right impedance ramp and calculation */ + tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + if (TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) { + if (((z1R > TASHA_ZDET_VAL_1200) && + (zdet_param_ptr->noff == 0x6)) || + ((*zl) != TASHA_ZDET_FLOATING_IMPEDANCE)) + goto right_ch_impedance; + /* second ramp for right ch */ + if (z1R < TASHA_ZDET_VAL_32) { + zdet_param_ptr = &zdet_param[0]; + d1 = d1_a[0]; + } else if ((z1R > TASHA_ZDET_VAL_400) && + (z1R <= TASHA_ZDET_VAL_1200)) { + zdet_param_ptr = &zdet_param[2]; + d1 = d1_a[2]; + } else if (z1R > TASHA_ZDET_VAL_1200) { + zdet_param_ptr = &zdet_param[3]; + d1 = d1_a[3]; + } + tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + } +right_ch_impedance: + if ((z1R == TASHA_ZDET_FLOATING_IMPEDANCE) || + (z1R > TASHA_ZDET_VAL_100K)) { + *zr = TASHA_ZDET_FLOATING_IMPEDANCE; + } else { + *zr = z1R/1000; + tasha_wcd_mbhc_qfuse_cal(codec, zr, 1); + } + dev_dbg(codec->dev, "%s: impedance on HPH_R = %d(ohms)\n", + __func__, *zr); + + /* mono/stereo detection */ + if ((*zl == TASHA_ZDET_FLOATING_IMPEDANCE) && + (*zr == TASHA_ZDET_FLOATING_IMPEDANCE)) { + dev_dbg(codec->dev, + "%s: plug type is invalid or extension cable\n", + __func__); + goto zdet_complete; + } + if ((*zl == TASHA_ZDET_FLOATING_IMPEDANCE) || + (*zr == TASHA_ZDET_FLOATING_IMPEDANCE) || + ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) || + ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) { + dev_dbg(codec->dev, + "%s: Mono plug type with one ch floating or shorted to GND\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_MONO; + goto zdet_complete; + } + snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST, 0x02, 0x02); + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x40, 0x01); + if (*zl < (TASHA_ZDET_VAL_32/1000)) + tasha_mbhc_zdet_ramp(codec, &zdet_param[0], &z1Ls, NULL, d1); + else + tasha_mbhc_zdet_ramp(codec, &zdet_param[1], &z1Ls, NULL, d1); + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x40, 0x00); + snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST, 0x02, 0x00); + z1Ls /= 1000; + tasha_wcd_mbhc_qfuse_cal(codec, &z1Ls, 0); + /* parallel of left Z and 9 ohm pull down resistor */ + zMono = ((*zl) * 9) / ((*zl) + 9); + z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls); + z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl)); + if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) { + dev_dbg(codec->dev, "%s: stereo plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_STEREO; + } else { + dev_dbg(codec->dev, "%s: MONO plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_MONO; + } + +zdet_complete: + snd_soc_write(codec, WCD9335_ANA_MBHC_BTN5, reg0); + snd_soc_write(codec, WCD9335_ANA_MBHC_BTN6, reg1); + snd_soc_write(codec, WCD9335_ANA_MBHC_BTN7, reg2); + /* Turn on 100k pull down on HPHL */ + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_MECH, 0x01, 0x01); + + /* For NO-jack, re-enable L_DET_EN after Z-det measurements */ + if (mbhc->hphl_swh) + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_MECH, 0x80, 0x80); + + snd_soc_write(codec, WCD9335_MBHC_ZDET_ANA_CTL, reg4); + snd_soc_write(codec, WCD9335_MBHC_CTL_1, reg3); + if (is_fsm_disable) + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_ELECT, 0x80, 0x80); + if (tasha->zdet_gpio_cb && is_change) + tasha->zdet_gpio_cb(codec, false); +} + +static void tasha_mbhc_gnd_det_ctrl(struct snd_soc_codec *codec, bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH, + 0x02, 0x02); + snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH, + 0x40, 0x40); + } else { + snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH, + 0x40, 0x00); + snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH, + 0x02, 0x00); + } +} + +static void tasha_mbhc_hph_pull_down_ctrl(struct snd_soc_codec *codec, + bool enable) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + if (enable) { + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, + 0x40, 0x40); + if (TASHA_IS_2_0(tasha->wcd9xxx)) + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, + 0x10, 0x10); + } else { + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, + 0x40, 0x00); + if (TASHA_IS_2_0(tasha->wcd9xxx)) + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, + 0x10, 0x00); + } +} + +static void tasha_mbhc_moisture_config(struct wcd_mbhc *mbhc) +{ + struct snd_soc_codec *codec = mbhc->codec; + + if (mbhc->moist_vref == V_OFF) + return; + + /* Donot enable moisture detection if jack type is NC */ + if (!mbhc->hphl_swh) { + dev_dbg(codec->dev, "%s: disable moisture detection for NC\n", + __func__); + return; + } + + snd_soc_update_bits(codec, WCD9335_MBHC_CTL_2, + 0x0C, mbhc->moist_vref << 2); + tasha_mbhc_hph_l_pull_up_control(codec, mbhc->moist_iref); +} + +static const struct wcd_mbhc_cb mbhc_cb = { + .request_irq = tasha_mbhc_request_irq, + .irq_control = tasha_mbhc_irq_control, + .free_irq = tasha_mbhc_free_irq, + .clk_setup = tasha_mbhc_clk_setup, + .map_btn_code_to_num = tasha_mbhc_btn_to_num, + .enable_mb_source = tasha_enable_ext_mb_source, + .mbhc_bias = tasha_mbhc_mbhc_bias_control, + .set_btn_thr = tasha_mbhc_program_btn_thr, + .lock_sleep = tasha_mbhc_lock_sleep, + .register_notifier = tasha_mbhc_register_notifier, + .micbias_enable_status = tasha_mbhc_micb_en_status, + .hph_pa_on_status = tasha_mbhc_hph_pa_on_status, + .hph_pull_up_control = tasha_mbhc_hph_l_pull_up_control, + .mbhc_micbias_control = tasha_mbhc_request_micbias, + .mbhc_micb_ramp_control = tasha_mbhc_micb_ramp_control, + .get_hwdep_fw_cal = tasha_get_hwdep_fw_cal, + .mbhc_micb_ctrl_thr_mic = tasha_mbhc_micb_ctrl_threshold_mic, + .compute_impedance = tasha_wcd_mbhc_calc_impedance, + .mbhc_gnd_det_ctrl = tasha_mbhc_gnd_det_ctrl, + .hph_pull_down_ctrl = tasha_mbhc_hph_pull_down_ctrl, + .mbhc_moisture_config = tasha_mbhc_moisture_config, +}; + +static int tasha_get_anc_slot(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = tasha->anc_slot; + return 0; +} + +static int tasha_put_anc_slot(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + tasha->anc_slot = ucontrol->value.integer.value[0]; + return 0; +} + +static int tasha_get_anc_func(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = (tasha->anc_func == true ? 1 : 0); + return 0; +} + +static int tasha_put_anc_func(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + + mutex_lock(&tasha->codec_mutex); + tasha->anc_func = (!ucontrol->value.integer.value[0] ? false : true); + + dev_dbg(codec->dev, "%s: anc_func %x", __func__, tasha->anc_func); + + if (tasha->anc_func == true) { + snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT2 PA"); + snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT2"); + snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT1 PA"); + snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT1"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHR PA"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHR"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHL PA"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHL"); + snd_soc_dapm_enable_pin(dapm, "ANC EAR PA"); + snd_soc_dapm_enable_pin(dapm, "ANC EAR"); + snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA"); + snd_soc_dapm_disable_pin(dapm, "LINEOUT2"); + snd_soc_dapm_disable_pin(dapm, "LINEOUT2 PA"); + snd_soc_dapm_disable_pin(dapm, "LINEOUT1"); + snd_soc_dapm_disable_pin(dapm, "LINEOUT1 PA"); + snd_soc_dapm_disable_pin(dapm, "HPHR"); + snd_soc_dapm_disable_pin(dapm, "HPHL"); + snd_soc_dapm_disable_pin(dapm, "HPHR PA"); + snd_soc_dapm_disable_pin(dapm, "HPHL PA"); + snd_soc_dapm_disable_pin(dapm, "EAR PA"); + snd_soc_dapm_disable_pin(dapm, "EAR"); + } else { + snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2 PA"); + snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2"); + snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1 PA"); + snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHR"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHL"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA"); + snd_soc_dapm_disable_pin(dapm, "ANC EAR PA"); + snd_soc_dapm_disable_pin(dapm, "ANC EAR"); + snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA"); + snd_soc_dapm_enable_pin(dapm, "LINEOUT2"); + snd_soc_dapm_enable_pin(dapm, "LINEOUT2 PA"); + snd_soc_dapm_enable_pin(dapm, "LINEOUT1"); + snd_soc_dapm_enable_pin(dapm, "LINEOUT1 PA"); + snd_soc_dapm_enable_pin(dapm, "HPHR"); + snd_soc_dapm_enable_pin(dapm, "HPHL"); + snd_soc_dapm_enable_pin(dapm, "HPHR PA"); + snd_soc_dapm_enable_pin(dapm, "HPHL PA"); + snd_soc_dapm_enable_pin(dapm, "EAR PA"); + snd_soc_dapm_enable_pin(dapm, "EAR"); + } + mutex_unlock(&tasha->codec_mutex); + snd_soc_dapm_sync(dapm); + return 0; +} + +static int tasha_get_clkmode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = tasha->clk_mode; + dev_dbg(codec->dev, "%s: clk_mode: %d\n", __func__, tasha->clk_mode); + + return 0; +} + +static int tasha_put_clkmode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + tasha->clk_mode = ucontrol->value.enumerated.item[0]; + dev_dbg(codec->dev, "%s: clk_mode: %d\n", __func__, tasha->clk_mode); + + return 0; +} + +static int tasha_get_iir_enable_audio_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + /* IIR filter band registers are at integer multiples of 16 */ + u16 iir_reg = WCD9335_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx; + + ucontrol->value.integer.value[0] = (snd_soc_read(codec, iir_reg) & + (1 << band_idx)) != 0; + + dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, + iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[0]); + return 0; +} + +static int tasha_hph_impedance_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + uint32_t zl, zr; + bool hphr; + struct soc_multi_mixer_control *mc; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + + mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); + hphr = mc->shift; + wcd_mbhc_get_impedance(&priv->mbhc, &zl, &zr); + dev_dbg(codec->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr); + ucontrol->value.integer.value[0] = hphr ? zr : zl; + + return 0; +} + +static const struct snd_kcontrol_new impedance_detect_controls[] = { + SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0, + tasha_hph_impedance_get, NULL), + SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0, + tasha_hph_impedance_get, NULL), +}; + +static int tasha_get_hph_type(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + struct wcd_mbhc *mbhc; + + if (!priv) { + dev_dbg(codec->dev, "%s: wcd9335 private data is NULL\n", + __func__); + return 0; + } + + mbhc = &priv->mbhc; + if (!mbhc) { + dev_dbg(codec->dev, "%s: mbhc not initialized\n", __func__); + return 0; + } + + ucontrol->value.integer.value[0] = (u32) mbhc->hph_type; + dev_dbg(codec->dev, "%s: hph_type = %u\n", __func__, mbhc->hph_type); + + return 0; +} + +static const struct snd_kcontrol_new hph_type_detect_controls[] = { + SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0, + tasha_get_hph_type, NULL), +}; + +static int tasha_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = tasha_p->vi_feed_value; + + return 0; +} + +static int tasha_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *core = tasha_p->wcd9xxx; + struct soc_multi_mixer_control *mixer = + ((struct soc_multi_mixer_control *)kcontrol->private_value); + u32 dai_id = widget->shift; + u32 port_id = mixer->shift; + u32 enable = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: enable: %d, port_id:%d, dai_id: %d\n", + __func__, enable, port_id, dai_id); + + tasha_p->vi_feed_value = ucontrol->value.integer.value[0]; + + mutex_lock(&tasha_p->codec_mutex); + if (enable) { + if (port_id == TASHA_TX14 && !test_bit(VI_SENSE_1, + &tasha_p->status_mask)) { + list_add_tail(&core->tx_chs[TASHA_TX14].list, + &tasha_p->dai[dai_id].wcd9xxx_ch_list); + set_bit(VI_SENSE_1, &tasha_p->status_mask); + } + if (port_id == TASHA_TX15 && !test_bit(VI_SENSE_2, + &tasha_p->status_mask)) { + list_add_tail(&core->tx_chs[TASHA_TX15].list, + &tasha_p->dai[dai_id].wcd9xxx_ch_list); + set_bit(VI_SENSE_2, &tasha_p->status_mask); + } + } else { + if (port_id == TASHA_TX14 && test_bit(VI_SENSE_1, + &tasha_p->status_mask)) { + list_del_init(&core->tx_chs[TASHA_TX14].list); + clear_bit(VI_SENSE_1, &tasha_p->status_mask); + } + if (port_id == TASHA_TX15 && test_bit(VI_SENSE_2, + &tasha_p->status_mask)) { + list_del_init(&core->tx_chs[TASHA_TX15].list); + clear_bit(VI_SENSE_2, &tasha_p->status_mask); + } + } + mutex_unlock(&tasha_p->codec_mutex); + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL); + + return 0; +} + +/* virtual port entries */ +static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = tasha_p->tx_port_value; + return 0; +} + +static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); + struct snd_soc_dapm_update *update = NULL; + struct soc_multi_mixer_control *mixer = + ((struct soc_multi_mixer_control *)kcontrol->private_value); + u32 dai_id = widget->shift; + u32 port_id = mixer->shift; + u32 enable = ucontrol->value.integer.value[0]; + u32 vtable; + + + dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", + __func__, + widget->name, ucontrol->id.name, tasha_p->tx_port_value, + widget->shift, ucontrol->value.integer.value[0]); + + mutex_lock(&tasha_p->codec_mutex); + + if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) { + if (dai_id != AIF1_CAP) { + dev_err(codec->dev, "%s: invalid AIF for I2C mode\n", + __func__); + mutex_unlock(&tasha_p->codec_mutex); + return -EINVAL; + } + vtable = vport_slim_check_table[dai_id]; + } else { + if (dai_id >= ARRAY_SIZE(vport_i2s_check_table)) { + dev_err(codec->dev, "%s: dai_id: %d, out of bounds\n", + __func__, dai_id); + return -EINVAL; + } + vtable = vport_i2s_check_table[dai_id]; + } + switch (dai_id) { + case AIF1_CAP: + case AIF2_CAP: + case AIF3_CAP: + /* only add to the list if value not set */ + if (enable && !(tasha_p->tx_port_value & 1 << port_id)) { + + if (wcd9xxx_tx_vport_validation(vtable, port_id, + tasha_p->dai, NUM_CODEC_DAIS)) { + dev_dbg(codec->dev, "%s: TX%u is used by other virtual port\n", + __func__, port_id); + mutex_unlock(&tasha_p->codec_mutex); + return 0; + } + tasha_p->tx_port_value |= 1 << port_id; + list_add_tail(&core->tx_chs[port_id].list, + &tasha_p->dai[dai_id].wcd9xxx_ch_list + ); + } else if (!enable && (tasha_p->tx_port_value & + 1 << port_id)) { + tasha_p->tx_port_value &= ~(1 << port_id); + list_del_init(&core->tx_chs[port_id].list); + } else { + if (enable) + dev_dbg(codec->dev, "%s: TX%u port is used by\n" + "this virtual port\n", + __func__, port_id); + else + dev_dbg(codec->dev, "%s: TX%u port is not used by\n" + "this virtual port\n", + __func__, port_id); + /* avoid update power function */ + mutex_unlock(&tasha_p->codec_mutex); + return 0; + } + break; + case AIF4_MAD_TX: + case AIF5_CPE_TX: + break; + default: + pr_err("Unknown AIF %d\n", dai_id); + mutex_unlock(&tasha_p->codec_mutex); + return -EINVAL; + } + pr_debug("%s: name %s sname %s updated value %u shift %d\n", __func__, + widget->name, widget->sname, tasha_p->tx_port_value, + widget->shift); + + mutex_unlock(&tasha_p->codec_mutex); + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update); + + return 0; +} + +static int slim_rx_mux_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = + tasha_p->rx_port_value[widget->shift]; + return 0; +} + +static const char *const slim_rx_mux_text[] = { + "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB", "AIF_MIX1_PB" +}; + +static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + unsigned int rx_port_value; + u32 port_id = widget->shift; + + tasha_p->rx_port_value[port_id] = ucontrol->value.enumerated.item[0]; + rx_port_value = tasha_p->rx_port_value[port_id]; + + pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__, + widget->name, ucontrol->id.name, rx_port_value, + widget->shift, ucontrol->value.integer.value[0]); + + mutex_lock(&tasha_p->codec_mutex); + + if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) { + if (rx_port_value > 2) { + dev_err(codec->dev, "%s: invalid AIF for I2C mode\n", + __func__); + goto err; + } + } + /* value need to match the Virtual port and AIF number */ + switch (rx_port_value) { + case 0: + list_del_init(&core->rx_chs[port_id].list); + break; + case 1: + if (wcd9xxx_rx_vport_validation(port_id + + TASHA_RX_PORT_START_NUMBER, + &tasha_p->dai[AIF1_PB].wcd9xxx_ch_list)) { + dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + __func__, port_id); + goto rtn; + } + list_add_tail(&core->rx_chs[port_id].list, + &tasha_p->dai[AIF1_PB].wcd9xxx_ch_list); + break; + case 2: + if (wcd9xxx_rx_vport_validation(port_id + + TASHA_RX_PORT_START_NUMBER, + &tasha_p->dai[AIF2_PB].wcd9xxx_ch_list)) { + dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + __func__, port_id); + goto rtn; + } + list_add_tail(&core->rx_chs[port_id].list, + &tasha_p->dai[AIF2_PB].wcd9xxx_ch_list); + break; + case 3: + if (wcd9xxx_rx_vport_validation(port_id + + TASHA_RX_PORT_START_NUMBER, + &tasha_p->dai[AIF3_PB].wcd9xxx_ch_list)) { + dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + __func__, port_id); + goto rtn; + } + list_add_tail(&core->rx_chs[port_id].list, + &tasha_p->dai[AIF3_PB].wcd9xxx_ch_list); + break; + case 4: + if (wcd9xxx_rx_vport_validation(port_id + + TASHA_RX_PORT_START_NUMBER, + &tasha_p->dai[AIF4_PB].wcd9xxx_ch_list)) { + dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + __func__, port_id); + goto rtn; + } + list_add_tail(&core->rx_chs[port_id].list, + &tasha_p->dai[AIF4_PB].wcd9xxx_ch_list); + break; + case 5: + if (wcd9xxx_rx_vport_validation(port_id + + TASHA_RX_PORT_START_NUMBER, + &tasha_p->dai[AIF_MIX1_PB].wcd9xxx_ch_list)) { + dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + __func__, port_id); + goto rtn; + } + list_add_tail(&core->rx_chs[port_id].list, + &tasha_p->dai[AIF_MIX1_PB].wcd9xxx_ch_list); + break; + default: + pr_err("Unknown AIF %d\n", rx_port_value); + goto err; + } +rtn: + mutex_unlock(&tasha_p->codec_mutex); + snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, + rx_port_value, e, update); + + return 0; +err: + mutex_unlock(&tasha_p->codec_mutex); + return -EINVAL; +} + +static const struct soc_enum slim_rx_mux_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text); + +static const struct snd_kcontrol_new slim_rx_mux[TASHA_RX_MAX] = { + SOC_DAPM_ENUM_EXT("SLIM RX0 Mux", slim_rx_mux_enum, + slim_rx_mux_get, slim_rx_mux_put), + SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum, + slim_rx_mux_get, slim_rx_mux_put), + SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum, + slim_rx_mux_get, slim_rx_mux_put), + SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum, + slim_rx_mux_get, slim_rx_mux_put), + SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum, + slim_rx_mux_get, slim_rx_mux_put), + SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum, + slim_rx_mux_get, slim_rx_mux_put), + SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum, + slim_rx_mux_get, slim_rx_mux_put), + SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum, + slim_rx_mux_get, slim_rx_mux_put), +}; + +static const struct snd_kcontrol_new aif4_vi_mixer[] = { + SOC_SINGLE_EXT("SPKR_VI_1", SND_SOC_NOPM, TASHA_TX14, 1, 0, + tasha_vi_feed_mixer_get, tasha_vi_feed_mixer_put), + SOC_SINGLE_EXT("SPKR_VI_2", SND_SOC_NOPM, TASHA_TX15, 1, 0, + tasha_vi_feed_mixer_get, tasha_vi_feed_mixer_put), +}; + +static const struct snd_kcontrol_new aif1_cap_mixer[] = { + SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, TASHA_TX0, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TASHA_TX1, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TASHA_TX2, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TASHA_TX3, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TASHA_TX4, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TASHA_TX5, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TASHA_TX6, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TASHA_TX7, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TASHA_TX8, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TASHA_TX9, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TASHA_TX10, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, TASHA_TX11, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), +}; + +static const struct snd_kcontrol_new aif2_cap_mixer[] = { + SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, TASHA_TX0, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TASHA_TX1, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TASHA_TX2, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TASHA_TX3, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TASHA_TX4, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TASHA_TX5, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TASHA_TX6, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TASHA_TX7, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TASHA_TX8, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TASHA_TX9, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TASHA_TX10, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, TASHA_TX11, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), +}; + +static const struct snd_kcontrol_new aif3_cap_mixer[] = { + SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, TASHA_TX0, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, TASHA_TX1, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, TASHA_TX2, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, TASHA_TX3, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, TASHA_TX4, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, TASHA_TX5, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, TASHA_TX6, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, TASHA_TX7, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, TASHA_TX8, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, TASHA_TX9, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, TASHA_TX10, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, TASHA_TX11, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), +}; + +static const struct snd_kcontrol_new aif4_mad_mixer[] = { + SOC_SINGLE_EXT("SLIM TX12", SND_SOC_NOPM, TASHA_TX12, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, TASHA_TX13, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, 0, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + +}; + +static const struct snd_kcontrol_new rx_int1_spline_mix_switch[] = { + SOC_DAPM_SINGLE("HPHL Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new rx_int2_spline_mix_switch[] = { + SOC_DAPM_SINGLE("HPHR Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new rx_int3_spline_mix_switch[] = { + SOC_DAPM_SINGLE("LO1 Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new rx_int4_spline_mix_switch[] = { + SOC_DAPM_SINGLE("LO2 Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new rx_int5_spline_mix_switch[] = { + SOC_DAPM_SINGLE("LO3 Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new rx_int6_spline_mix_switch[] = { + SOC_DAPM_SINGLE("LO4 Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new rx_int7_spline_mix_switch[] = { + SOC_DAPM_SINGLE("SPKRL Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new rx_int8_spline_mix_switch[] = { + SOC_DAPM_SINGLE("SPKRR Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new rx_int5_vbat_mix_switch[] = { + SOC_DAPM_SINGLE("LO3 VBAT Enable", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new rx_int6_vbat_mix_switch[] = { + SOC_DAPM_SINGLE("LO4 VBAT Enable", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new rx_int7_vbat_mix_switch[] = { + SOC_DAPM_SINGLE("SPKRL VBAT Enable", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new rx_int8_vbat_mix_switch[] = { + SOC_DAPM_SINGLE("SPKRR VBAT Enable", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new cpe_in_mix_switch[] = { + SOC_DAPM_SINGLE("MAD_BYPASS", SND_SOC_NOPM, 0, 1, 0) +}; + + + +static int tasha_put_iir_enable_audio_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + bool iir_band_en_status; + int value = ucontrol->value.integer.value[0]; + u16 iir_reg = WCD9335_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx; + + /* Mask first 5 bits, 6-8 are reserved */ + snd_soc_update_bits(codec, iir_reg, (1 << band_idx), + (value << band_idx)); + + iir_band_en_status = ((snd_soc_read(codec, iir_reg) & + (1 << band_idx)) != 0); + pr_debug("%s: IIR #%d band #%d enable %d\n", __func__, + iir_idx, band_idx, iir_band_en_status); + return 0; +} + +static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec, + int iir_idx, int band_idx, + int coeff_idx) +{ + uint32_t value = 0; + + /* Address does not automatically update if reading */ + snd_soc_write(codec, + (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t)) & 0x7F); + + value |= snd_soc_read(codec, + (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx)); + + snd_soc_write(codec, + (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 1) & 0x7F); + + value |= (snd_soc_read(codec, + (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + + 16 * iir_idx)) << 8); + + snd_soc_write(codec, + (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 2) & 0x7F); + + value |= (snd_soc_read(codec, + (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + + 16 * iir_idx)) << 16); + + snd_soc_write(codec, + (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 3) & 0x7F); + + /* Mask bits top 2 bits since they are reserved */ + value |= ((snd_soc_read(codec, + (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + + 16 * iir_idx)) & 0x3F) << 24); + + return value; +} + +static int tasha_get_iir_band_audio_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + ucontrol->value.integer.value[0] = + get_iir_band_coeff(codec, iir_idx, band_idx, 0); + ucontrol->value.integer.value[1] = + get_iir_band_coeff(codec, iir_idx, band_idx, 1); + ucontrol->value.integer.value[2] = + get_iir_band_coeff(codec, iir_idx, band_idx, 2); + ucontrol->value.integer.value[3] = + get_iir_band_coeff(codec, iir_idx, band_idx, 3); + ucontrol->value.integer.value[4] = + get_iir_band_coeff(codec, iir_idx, band_idx, 4); + + pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n" + "%s: IIR #%d band #%d b1 = 0x%x\n" + "%s: IIR #%d band #%d b2 = 0x%x\n" + "%s: IIR #%d band #%d a1 = 0x%x\n" + "%s: IIR #%d band #%d a2 = 0x%x\n", + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[0], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[1], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[2], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[3], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[4]); + return 0; +} + +static void set_iir_band_coeff(struct snd_soc_codec *codec, + int iir_idx, int band_idx, + uint32_t value) +{ + snd_soc_write(codec, + (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), + (value & 0xFF)); + + snd_soc_write(codec, + (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), + (value >> 8) & 0xFF); + + snd_soc_write(codec, + (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), + (value >> 16) & 0xFF); + + /* Mask top 2 bits, 7-8 are reserved */ + snd_soc_write(codec, + (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), + (value >> 24) & 0x3F); +} + +static void tasha_codec_enable_int_port(struct wcd9xxx_codec_dai_data *dai, + struct snd_soc_codec *codec) +{ + struct wcd9xxx_ch *ch; + int port_num = 0; + unsigned short reg = 0; + u8 val = 0; + struct tasha_priv *tasha_p; + + if (!dai || !codec) { + pr_err("%s: Invalid params\n", __func__); + return; + } + + tasha_p = snd_soc_codec_get_drvdata(codec); + list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) { + if (ch->port >= TASHA_RX_PORT_START_NUMBER) { + port_num = ch->port - TASHA_RX_PORT_START_NUMBER; + reg = TASHA_SLIM_PGD_PORT_INT_EN0 + (port_num / 8); + val = wcd9xxx_interface_reg_read(tasha_p->wcd9xxx, + reg); + if (!(val & BYTE_BIT_MASK(port_num))) { + val |= BYTE_BIT_MASK(port_num); + wcd9xxx_interface_reg_write( + tasha_p->wcd9xxx, reg, val); + val = wcd9xxx_interface_reg_read( + tasha_p->wcd9xxx, reg); + } + } else { + port_num = ch->port; + reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8); + val = wcd9xxx_interface_reg_read(tasha_p->wcd9xxx, + reg); + if (!(val & BYTE_BIT_MASK(port_num))) { + val |= BYTE_BIT_MASK(port_num); + wcd9xxx_interface_reg_write(tasha_p->wcd9xxx, + reg, val); + val = wcd9xxx_interface_reg_read( + tasha_p->wcd9xxx, reg); + } + } + } +} + +static int tasha_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai, + bool up) +{ + int ret = 0; + struct wcd9xxx_ch *ch; + + if (up) { + list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) { + ret = wcd9xxx_get_slave_port(ch->ch_num); + if (ret < 0) { + pr_err("%s: Invalid slave port ID: %d\n", + __func__, ret); + ret = -EINVAL; + } else { + set_bit(ret, &dai->ch_mask); + } + } + } else { + ret = wait_event_timeout(dai->dai_wait, (dai->ch_mask == 0), + msecs_to_jiffies( + TASHA_SLIM_CLOSE_TIMEOUT)); + if (!ret) { + pr_err("%s: Slim close tx/rx wait timeout, ch_mask:0x%lx\n", + __func__, dai->ch_mask); + ret = -ETIMEDOUT; + } else { + ret = 0; + } + } + return ret; +} + +static int tasha_codec_enable_slimrx(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct wcd9xxx *core; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + int ret = 0; + struct wcd9xxx_codec_dai_data *dai; + + core = dev_get_drvdata(codec->dev->parent); + + dev_dbg(codec->dev, "%s: event called! codec name %s num_dai %d\n" + "stream name %s event %d\n", + __func__, codec->component.name, + codec->component.num_dai, w->sname, event); + + /* Execute the callback only if interface type is slimbus */ + if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) + return 0; + + dai = &tasha_p->dai[w->shift]; + dev_dbg(codec->dev, "%s: w->name %s w->shift %d event %d\n", + __func__, w->name, w->shift, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + dai->bus_down_in_recovery = false; + tasha_codec_enable_int_port(dai, codec); + (void) tasha_codec_enable_slim_chmask(dai, true); + ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list, + dai->rate, dai->bit_width, + &dai->grph); + break; + case SND_SOC_DAPM_PRE_PMD: + if (!test_bit(SB_CLK_GEAR, &tasha_p->status_mask)) { + tasha_codec_vote_max_bw(codec, true); + set_bit(SB_CLK_GEAR, &tasha_p->status_mask); + } + break; + case SND_SOC_DAPM_POST_PMD: + ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list, + dai->grph); + dev_dbg(codec->dev, "%s: Disconnect RX port, ret = %d\n", + __func__, ret); + + if (!dai->bus_down_in_recovery) + ret = tasha_codec_enable_slim_chmask(dai, false); + else + dev_dbg(codec->dev, + "%s: bus in recovery skip enable slim_chmask", + __func__); + ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list, + dai->grph); + break; + } + return ret; +} + +static int tasha_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct wcd9xxx *core = NULL; + struct snd_soc_codec *codec = NULL; + struct tasha_priv *tasha_p = NULL; + int ret = 0; + struct wcd9xxx_codec_dai_data *dai = NULL; + + if (!w) { + pr_err("%s invalid params\n", __func__); + return -EINVAL; + } + codec = snd_soc_dapm_to_codec(w->dapm); + tasha_p = snd_soc_codec_get_drvdata(codec); + core = tasha_p->wcd9xxx; + + dev_dbg(codec->dev, "%s: num_dai %d stream name %s\n", + __func__, codec->component.num_dai, w->sname); + + /* Execute the callback only if interface type is slimbus */ + if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) { + dev_err(codec->dev, "%s Interface is not correct", __func__); + return 0; + } + + dev_dbg(codec->dev, "%s(): w->name %s event %d w->shift %d\n", + __func__, w->name, event, w->shift); + if (w->shift != AIF4_VIFEED) { + pr_err("%s Error in enabling the tx path\n", __func__); + ret = -EINVAL; + goto out_vi; + } + dai = &tasha_p->dai[w->shift]; + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (test_bit(VI_SENSE_1, &tasha_p->status_mask)) { + dev_dbg(codec->dev, "%s: spkr1 enabled\n", __func__); + /* Enable V&I sensing */ + snd_soc_update_bits(codec, + WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); + snd_soc_update_bits(codec, + WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x0F, 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x0F, + 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x10); + snd_soc_update_bits(codec, + WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10, + 0x10); + snd_soc_update_bits(codec, + WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, + 0x00); + } + if (test_bit(VI_SENSE_2, &tasha_p->status_mask)) { + pr_debug("%s: spkr2 enabled\n", __func__); + /* Enable V&I sensing */ + snd_soc_update_bits(codec, + WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x0F, + 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x0F, + 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10, + 0x10); + snd_soc_update_bits(codec, + WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10, + 0x10); + snd_soc_update_bits(codec, + WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, + 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, + 0x00); + } + dai->bus_down_in_recovery = false; + tasha_codec_enable_int_port(dai, codec); + (void) tasha_codec_enable_slim_chmask(dai, true); + ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list, + dai->rate, dai->bit_width, + &dai->grph); + break; + case SND_SOC_DAPM_POST_PMD: + ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list, + dai->grph); + if (ret) + dev_err(codec->dev, "%s error in close_slim_sch_tx %d\n", + __func__, ret); + if (!dai->bus_down_in_recovery) + ret = tasha_codec_enable_slim_chmask(dai, false); + if (ret < 0) { + ret = wcd9xxx_disconnect_port(core, + &dai->wcd9xxx_ch_list, + dai->grph); + dev_dbg(codec->dev, "%s: Disconnect TX port, ret = %d\n", + __func__, ret); + } + if (test_bit(VI_SENSE_1, &tasha_p->status_mask)) { + /* Disable V&I sensing */ + dev_dbg(codec->dev, "%s: spkr1 disabled\n", __func__); + snd_soc_update_bits(codec, + WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); + snd_soc_update_bits(codec, + WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10, + 0x00); + } + if (test_bit(VI_SENSE_2, &tasha_p->status_mask)) { + /* Disable V&I sensing */ + dev_dbg(codec->dev, "%s: spkr2 disabled\n", __func__); + snd_soc_update_bits(codec, + WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10, + 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10, + 0x00); + } + break; + } +out_vi: + return ret; +} + +/* + * __tasha_codec_enable_slimtx: Enable the slimbus slave port + * for TX path + * @codec: Handle to the codec for which the slave port is to be + * enabled. + * @dai_data: The dai specific data for dai which is enabled. + */ +static int __tasha_codec_enable_slimtx(struct snd_soc_codec *codec, + int event, struct wcd9xxx_codec_dai_data *dai) +{ + struct wcd9xxx *core; + struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + /* Execute the callback only if interface type is slimbus */ + if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) + return 0; + + dev_dbg(codec->dev, + "%s: event = %d\n", __func__, event); + core = dev_get_drvdata(codec->dev->parent); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + dai->bus_down_in_recovery = false; + tasha_codec_enable_int_port(dai, codec); + (void) tasha_codec_enable_slim_chmask(dai, true); + ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list, + dai->rate, dai->bit_width, + &dai->grph); + break; + case SND_SOC_DAPM_POST_PMD: + ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list, + dai->grph); + if (!dai->bus_down_in_recovery) + ret = tasha_codec_enable_slim_chmask(dai, false); + if (ret < 0) { + ret = wcd9xxx_disconnect_port(core, + &dai->wcd9xxx_ch_list, + dai->grph); + pr_debug("%s: Disconnect TX port, ret = %d\n", + __func__, ret); + } + + break; + } + + return ret; +} + +static int tasha_codec_enable_slimtx(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx_codec_dai_data *dai; + + dev_dbg(codec->dev, + "%s: w->name %s, w->shift = %d, num_dai %d stream name %s\n", + __func__, w->name, w->shift, + codec->component.num_dai, w->sname); + + dai = &tasha_p->dai[w->shift]; + return __tasha_codec_enable_slimtx(codec, event, dai); +} + +static void tasha_codec_cpe_pp_set_cfg(struct snd_soc_codec *codec, int event) +{ + struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx_codec_dai_data *dai; + u8 bit_width, rate, buf_period; + + dai = &tasha_p->dai[AIF4_MAD_TX]; + switch (event) { + case SND_SOC_DAPM_POST_PMU: + switch (dai->bit_width) { + case 32: + bit_width = 0xF; + break; + case 24: + bit_width = 0xE; + break; + case 20: + bit_width = 0xD; + break; + case 16: + default: + bit_width = 0x0; + break; + } + snd_soc_update_bits(codec, WCD9335_CPE_SS_TX_PP_CFG, 0x0F, + bit_width); + + switch (dai->rate) { + case 384000: + rate = 0x30; + break; + case 192000: + rate = 0x20; + break; + case 48000: + rate = 0x10; + break; + case 16000: + default: + rate = 0x00; + break; + } + snd_soc_update_bits(codec, WCD9335_CPE_SS_TX_PP_CFG, 0x70, + rate); + + buf_period = (dai->rate * (dai->bit_width/8)) / (16*1000); + snd_soc_update_bits(codec, WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD, + 0xFF, buf_period); + dev_dbg(codec->dev, "%s: PP buffer period= 0x%x\n", + __func__, buf_period); + break; + + case SND_SOC_DAPM_POST_PMD: + snd_soc_write(codec, WCD9335_CPE_SS_TX_PP_CFG, 0x3C); + snd_soc_write(codec, WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD, 0x60); + break; + + default: + break; + } +} + +/* + * tasha_codec_get_mad_port_id: Callback function that will be invoked + * to get the port ID for MAD. + * @codec: Handle to the codec + * @port_id: cpe port_id needs to enable + */ +static int tasha_codec_get_mad_port_id(struct snd_soc_codec *codec, + u16 *port_id) +{ + struct tasha_priv *tasha_p; + struct wcd9xxx_codec_dai_data *dai; + struct wcd9xxx_ch *ch; + + if (!port_id || !codec) + return -EINVAL; + + tasha_p = snd_soc_codec_get_drvdata(codec); + if (!tasha_p) + return -EINVAL; + + dai = &tasha_p->dai[AIF4_MAD_TX]; + list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) { + if (ch->port == TASHA_TX12) + *port_id = WCD_CPE_AFE_OUT_PORT_2; + else if (ch->port == TASHA_TX13) + *port_id = WCD_CPE_AFE_OUT_PORT_4; + else { + dev_err(codec->dev, "%s: invalid mad_port = %d\n", + __func__, ch->port); + return -EINVAL; + } + } + dev_dbg(codec->dev, "%s: port_id = %d\n", __func__, *port_id); + + return 0; +} + +/* + * tasha_codec_enable_slimtx_mad: Callback function that will be invoked + * to setup the slave port for MAD. + * @codec: Handle to the codec + * @event: Indicates whether to enable or disable the slave port + */ +static int tasha_codec_enable_slimtx_mad(struct snd_soc_codec *codec, + u8 event) +{ + struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx_codec_dai_data *dai; + struct wcd9xxx_ch *ch; + int dapm_event = SND_SOC_DAPM_POST_PMU; + u16 port = 0; + int ret = 0; + + dai = &tasha_p->dai[AIF4_MAD_TX]; + + if (event == 0) + dapm_event = SND_SOC_DAPM_POST_PMD; + + dev_dbg(codec->dev, + "%s: mad_channel, event = 0x%x\n", + __func__, event); + + list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) { + dev_dbg(codec->dev, "%s: mad_port = %d, event = 0x%x\n", + __func__, ch->port, event); + if (ch->port == TASHA_TX13) { + tasha_codec_cpe_pp_set_cfg(codec, dapm_event); + port = TASHA_TX13; + break; + } + } + + ret = __tasha_codec_enable_slimtx(codec, dapm_event, dai); + + if (port == TASHA_TX13) { + switch (dapm_event) { + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, + WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN, + 0x20, 0x00); + snd_soc_update_bits(codec, + WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG, + 0x03, 0x02); + snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, + 0x80, 0x80); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, + WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN, + 0x20, 0x20); + snd_soc_update_bits(codec, + WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG, + 0x03, 0x00); + snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, + 0x80, 0x00); + break; + } + } + + return ret; +} + +static int tasha_put_iir_band_audio_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + /* + * Mask top bit it is reserved + * Updates addr automatically for each B2 write + */ + snd_soc_write(codec, + (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); + + set_iir_band_coeff(codec, iir_idx, band_idx, + ucontrol->value.integer.value[0]); + set_iir_band_coeff(codec, iir_idx, band_idx, + ucontrol->value.integer.value[1]); + set_iir_band_coeff(codec, iir_idx, band_idx, + ucontrol->value.integer.value[2]); + set_iir_band_coeff(codec, iir_idx, band_idx, + ucontrol->value.integer.value[3]); + set_iir_band_coeff(codec, iir_idx, band_idx, + ucontrol->value.integer.value[4]); + + pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n" + "%s: IIR #%d band #%d b1 = 0x%x\n" + "%s: IIR #%d band #%d b2 = 0x%x\n" + "%s: IIR #%d band #%d a1 = 0x%x\n" + "%s: IIR #%d band #%d a2 = 0x%x\n", + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 0), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 1), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 2), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 3), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 4)); + return 0; +} + +static int tasha_get_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = tasha->comp_enabled[comp]; + return 0; +} + +static int tasha_set_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int value = ucontrol->value.integer.value[0]; + + pr_debug("%s: Compander %d enable current %d, new %d\n", + __func__, comp + 1, tasha->comp_enabled[comp], value); + tasha->comp_enabled[comp] = value; + + /* Any specific register configuration for compander */ + switch (comp) { + case COMPANDER_1: + /* Set Gain Source Select based on compander enable/disable */ + snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0x20, + (value ? 0x00:0x20)); + break; + case COMPANDER_2: + snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0x20, + (value ? 0x00:0x20)); + break; + case COMPANDER_3: + break; + case COMPANDER_4: + break; + case COMPANDER_5: + snd_soc_update_bits(codec, WCD9335_SE_LO_LO3_GAIN, 0x20, + (value ? 0x00:0x20)); + break; + case COMPANDER_6: + snd_soc_update_bits(codec, WCD9335_SE_LO_LO4_GAIN, 0x20, + (value ? 0x00:0x20)); + break; + case COMPANDER_7: + break; + case COMPANDER_8: + break; + default: + /* + * if compander is not enabled for any interpolator, + * it does not cause any audio failure, so do not + * return error in this case, but just print a log + */ + dev_warn(codec->dev, "%s: unknown compander: %d\n", + __func__, comp); + }; + return 0; +} + +static void tasha_codec_init_flyback(struct snd_soc_codec *codec) +{ + snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0xC0, 0x00); + snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0xC0, 0x00); + snd_soc_update_bits(codec, WCD9335_RX_BIAS_FLYB_BUFF, 0x0F, 0x00); + snd_soc_update_bits(codec, WCD9335_RX_BIAS_FLYB_BUFF, 0xF0, 0x00); +} + +static int tasha_codec_enable_rx_bias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + tasha->rx_bias_count++; + if (tasha->rx_bias_count == 1) { + if (TASHA_IS_2_0(tasha->wcd9xxx)) + tasha_codec_init_flyback(codec); + snd_soc_update_bits(codec, WCD9335_ANA_RX_SUPPLIES, + 0x01, 0x01); + } + break; + case SND_SOC_DAPM_POST_PMD: + tasha->rx_bias_count--; + if (!tasha->rx_bias_count) + snd_soc_update_bits(codec, WCD9335_ANA_RX_SUPPLIES, + 0x01, 0x00); + break; + }; + dev_dbg(codec->dev, "%s: Current RX BIAS user count: %d\n", __func__, + tasha->rx_bias_count); + + return 0; +} + +static void tasha_realign_anc_coeff(struct snd_soc_codec *codec, + u16 reg1, u16 reg2) +{ + u8 val1, val2, tmpval1, tmpval2; + + snd_soc_write(codec, reg1, 0x00); + tmpval1 = snd_soc_read(codec, reg2); + tmpval2 = snd_soc_read(codec, reg2); + snd_soc_write(codec, reg1, 0x00); + snd_soc_write(codec, reg2, 0xFF); + snd_soc_write(codec, reg1, 0x01); + snd_soc_write(codec, reg2, 0xFF); + + snd_soc_write(codec, reg1, 0x00); + val1 = snd_soc_read(codec, reg2); + val2 = snd_soc_read(codec, reg2); + + if (val1 == 0x0F && val2 == 0xFF) { + dev_dbg(codec->dev, "%s: ANC0 co-eff index re-aligned\n", + __func__); + snd_soc_read(codec, reg2); + snd_soc_write(codec, reg1, 0x00); + snd_soc_write(codec, reg2, tmpval2); + snd_soc_write(codec, reg1, 0x01); + snd_soc_write(codec, reg2, tmpval1); + } else if (val1 == 0xFF && val2 == 0x0F) { + dev_dbg(codec->dev, "%s: ANC1 co-eff index already aligned\n", + __func__); + snd_soc_write(codec, reg1, 0x00); + snd_soc_write(codec, reg2, tmpval1); + snd_soc_write(codec, reg1, 0x01); + snd_soc_write(codec, reg2, tmpval2); + } else { + dev_err(codec->dev, "%s: ANC0 co-eff index not aligned\n", + __func__); + } +} + +static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + const char *filename; + const struct firmware *fw; + int i; + int ret = 0; + int num_anc_slots; + struct wcd9xxx_anc_header *anc_head; + struct firmware_cal *hwdep_cal = NULL; + u32 anc_writes_size = 0; + u32 anc_cal_size = 0; + int anc_size_remaining; + u32 *anc_ptr; + u16 reg; + u8 mask, val; + size_t cal_size; + const void *data; + + if (!tasha->anc_func) + return 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_ANC_CAL); + if (hwdep_cal) { + data = hwdep_cal->data; + cal_size = hwdep_cal->size; + dev_dbg(codec->dev, "%s: using hwdep calibration\n", + __func__); + } else { + filename = "wcd9335/wcd9335_anc.bin"; + ret = request_firmware(&fw, filename, codec->dev); + if (ret != 0) { + dev_err(codec->dev, + "Failed to acquire ANC data: %d\n", ret); + return -ENODEV; + } + if (!fw) { + dev_err(codec->dev, "failed to get anc fw"); + return -ENODEV; + } + data = fw->data; + cal_size = fw->size; + dev_dbg(codec->dev, + "%s: using request_firmware calibration\n", __func__); + } + if (cal_size < sizeof(struct wcd9xxx_anc_header)) { + dev_err(codec->dev, "Not enough data\n"); + ret = -ENOMEM; + goto err; + } + /* First number is the number of register writes */ + anc_head = (struct wcd9xxx_anc_header *)(data); + anc_ptr = (u32 *)(data + + sizeof(struct wcd9xxx_anc_header)); + anc_size_remaining = cal_size - + sizeof(struct wcd9xxx_anc_header); + num_anc_slots = anc_head->num_anc_slots; + + if (tasha->anc_slot >= num_anc_slots) { + dev_err(codec->dev, "Invalid ANC slot selected\n"); + ret = -EINVAL; + goto err; + } + for (i = 0; i < num_anc_slots; i++) { + if (anc_size_remaining < TASHA_PACKED_REG_SIZE) { + dev_err(codec->dev, + "Invalid register format\n"); + ret = -EINVAL; + goto err; + } + anc_writes_size = (u32)(*anc_ptr); + anc_size_remaining -= sizeof(u32); + anc_ptr += 1; + + if (anc_writes_size * TASHA_PACKED_REG_SIZE + > anc_size_remaining) { + dev_err(codec->dev, + "Invalid register format\n"); + ret = -EINVAL; + goto err; + } + + if (tasha->anc_slot == i) + break; + + anc_size_remaining -= (anc_writes_size * + TASHA_PACKED_REG_SIZE); + anc_ptr += anc_writes_size; + } + if (i == num_anc_slots) { + dev_err(codec->dev, "Selected ANC slot not present\n"); + ret = -EINVAL; + goto err; + } + + i = 0; + anc_cal_size = anc_writes_size; + + if (!strcmp(w->name, "RX INT0 DAC") || + !strcmp(w->name, "ANC SPK1 PA")) + tasha_realign_anc_coeff(codec, + WCD9335_CDC_ANC0_IIR_COEFF_1_CTL, + WCD9335_CDC_ANC0_IIR_COEFF_2_CTL); + + if (!strcmp(w->name, "RX INT1 DAC") || + !strcmp(w->name, "RX INT3 DAC")) { + tasha_realign_anc_coeff(codec, + WCD9335_CDC_ANC0_IIR_COEFF_1_CTL, + WCD9335_CDC_ANC0_IIR_COEFF_2_CTL); + anc_writes_size = anc_cal_size / 2; + snd_soc_update_bits(codec, + WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x39, 0x39); + } else if (!strcmp(w->name, "RX INT2 DAC") || + !strcmp(w->name, "RX INT4 DAC")) { + tasha_realign_anc_coeff(codec, + WCD9335_CDC_ANC1_IIR_COEFF_1_CTL, + WCD9335_CDC_ANC1_IIR_COEFF_2_CTL); + i = anc_cal_size / 2; + snd_soc_update_bits(codec, + WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x39, 0x39); + } + + for (; i < anc_writes_size; i++) { + TASHA_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val); + snd_soc_write(codec, reg, (val & mask)); + } + if (!strcmp(w->name, "RX INT1 DAC") || + !strcmp(w->name, "RX INT3 DAC")) { + snd_soc_update_bits(codec, + WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x08); + } else if (!strcmp(w->name, "RX INT2 DAC") || + !strcmp(w->name, "RX INT4 DAC")) { + snd_soc_update_bits(codec, + WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x08); + } + + if (!hwdep_cal) + release_firmware(fw); + break; + case SND_SOC_DAPM_POST_PMU: + /* Remove ANC Rx from reset */ + snd_soc_update_bits(codec, WCD9335_CDC_ANC0_CLK_RESET_CTL, + 0x08, 0x00); + snd_soc_update_bits(codec, WCD9335_CDC_ANC1_CLK_RESET_CTL, + 0x08, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + if (!strcmp(w->name, "ANC HPHL PA") || + !strcmp(w->name, "ANC EAR PA") || + !strcmp(w->name, "ANC SPK1 PA") || + !strcmp(w->name, "ANC LINEOUT1 PA")) { + snd_soc_update_bits(codec, + WCD9335_CDC_ANC0_MODE_1_CTL, 0x30, 0x00); + msleep(50); + snd_soc_update_bits(codec, + WCD9335_CDC_ANC0_MODE_1_CTL, 0x01, 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x38); + snd_soc_update_bits(codec, + WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x07, 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x00); + } else if (!strcmp(w->name, "ANC HPHR PA") || + !strcmp(w->name, "ANC LINEOUT2 PA")) { + snd_soc_update_bits(codec, + WCD9335_CDC_ANC1_MODE_1_CTL, 0x30, 0x00); + msleep(50); + snd_soc_update_bits(codec, + WCD9335_CDC_ANC1_MODE_1_CTL, 0x01, 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x38, 0x38); + snd_soc_update_bits(codec, + WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x07, 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x38, 0x00); + } + break; + } + + return 0; +err: + if (!hwdep_cal) + release_firmware(fw); + return ret; +} + +static void tasha_codec_clear_anc_tx_hold(struct tasha_priv *tasha) +{ + if (test_and_clear_bit(ANC_MIC_AMIC1, &tasha->status_mask)) + tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC1, false); + if (test_and_clear_bit(ANC_MIC_AMIC2, &tasha->status_mask)) + tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC2, false); + if (test_and_clear_bit(ANC_MIC_AMIC3, &tasha->status_mask)) + tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC3, false); + if (test_and_clear_bit(ANC_MIC_AMIC4, &tasha->status_mask)) + tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC4, false); + if (test_and_clear_bit(ANC_MIC_AMIC5, &tasha->status_mask)) + tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC5, false); + if (test_and_clear_bit(ANC_MIC_AMIC6, &tasha->status_mask)) + tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC6, false); +} + +static void tasha_codec_hph_post_pa_config(struct tasha_priv *tasha, + int mode, int event) +{ + u8 scale_val = 0; + + if (!TASHA_IS_2_0(tasha->wcd9xxx)) + return; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + switch (mode) { + case CLS_H_HIFI: + scale_val = 0x3; + break; + case CLS_H_LOHIFI: + scale_val = 0x1; + break; + } + if (tasha->anc_func) { + /* Clear Tx FE HOLD if both PAs are enabled */ + if ((snd_soc_read(tasha->codec, WCD9335_ANA_HPH) & + 0xC0) == 0xC0) { + tasha_codec_clear_anc_tx_hold(tasha); + } + } + break; + case SND_SOC_DAPM_PRE_PMD: + scale_val = 0x6; + break; + } + + if (scale_val) + snd_soc_update_bits(tasha->codec, WCD9335_HPH_PA_CTL1, 0x0E, + scale_val << 1); + if (SND_SOC_DAPM_EVENT_ON(event)) { + if (tasha->comp_enabled[COMPANDER_1] || + tasha->comp_enabled[COMPANDER_2]) { + snd_soc_update_bits(tasha->codec, WCD9335_HPH_L_EN, + 0x20, 0x00); + snd_soc_update_bits(tasha->codec, WCD9335_HPH_R_EN, + 0x20, 0x00); + snd_soc_update_bits(tasha->codec, WCD9335_HPH_AUTO_CHOP, + 0x20, 0x20); + } + snd_soc_update_bits(tasha->codec, WCD9335_HPH_L_EN, 0x1F, + tasha->hph_l_gain); + snd_soc_update_bits(tasha->codec, WCD9335_HPH_R_EN, 0x1F, + tasha->hph_r_gain); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(tasha->codec, WCD9335_HPH_AUTO_CHOP, 0x20, + 0x00); + } +} + +static void tasha_codec_override(struct snd_soc_codec *codec, + int mode, + int event) +{ + if (mode == CLS_AB) { + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (!(snd_soc_read(codec, + WCD9335_CDC_RX2_RX_PATH_CTL) & 0x10) && + (!(snd_soc_read(codec, + WCD9335_CDC_RX1_RX_PATH_CTL) & 0x10))) + snd_soc_update_bits(codec, + WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x02); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, + WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x00); + break; + } + } +} + +static int tasha_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + int hph_mode = tasha->hph_mode; + int ret = 0; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if ((!(strcmp(w->name, "ANC HPHR PA"))) && + (test_bit(HPH_PA_DELAY, &tasha->status_mask))) { + snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0xC0, 0xC0); + } + set_bit(HPH_PA_DELAY, &tasha->status_mask); + break; + case SND_SOC_DAPM_POST_PMU: + if (!(strcmp(w->name, "ANC HPHR PA"))) { + if ((snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0) + != 0xC0) + /* + * If PA_EN is not set (potentially in ANC case) + * then do nothing for POST_PMU and let left + * channel handle everything. + */ + break; + } + /* + * 7ms sleep is required after PA is enabled as per + * HW requirement + */ + if (test_bit(HPH_PA_DELAY, &tasha->status_mask)) { + usleep_range(7000, 7100); + clear_bit(HPH_PA_DELAY, &tasha->status_mask); + } + tasha_codec_hph_post_pa_config(tasha, hph_mode, event); + snd_soc_update_bits(codec, WCD9335_CDC_RX2_RX_PATH_CTL, + 0x10, 0x00); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + WCD9335_CDC_RX2_RX_PATH_MIX_CTL, + 0x10, 0x00); + + if (!(strcmp(w->name, "ANC HPHR PA"))) { + /* Do everything needed for left channel */ + snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CTL, + 0x10, 0x00); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, + WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + WCD9335_CDC_RX1_RX_PATH_MIX_CTL, + 0x10, 0x00); + /* Remove ANC Rx from reset */ + ret = tasha_codec_enable_anc(w, kcontrol, event); + } + tasha_codec_override(codec, hph_mode, event); + break; + + case SND_SOC_DAPM_PRE_PMD: + blocking_notifier_call_chain(&tasha->notifier, + WCD_EVENT_PRE_HPHR_PA_OFF, + &tasha->mbhc); + tasha_codec_hph_post_pa_config(tasha, hph_mode, event); + if (!(strcmp(w->name, "ANC HPHR PA"))) + snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x40, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + /* 5ms sleep is required after PA is disabled as per + * HW requirement + */ + usleep_range(5000, 5500); + tasha_codec_override(codec, hph_mode, event); + blocking_notifier_call_chain(&tasha->notifier, + WCD_EVENT_POST_HPHR_PA_OFF, + &tasha->mbhc); + + if (!(strcmp(w->name, "ANC HPHR PA"))) { + ret = tasha_codec_enable_anc(w, kcontrol, event); + snd_soc_update_bits(codec, + WCD9335_CDC_RX2_RX_PATH_CFG0, 0x10, 0x00); + } + break; + }; + + return ret; +} + +static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + int hph_mode = tasha->hph_mode; + int ret = 0; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if ((!(strcmp(w->name, "ANC HPHL PA"))) && + (test_bit(HPH_PA_DELAY, &tasha->status_mask))) { + snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0xC0, 0xC0); + } + set_bit(HPH_PA_DELAY, &tasha->status_mask); + break; + case SND_SOC_DAPM_POST_PMU: + if (!(strcmp(w->name, "ANC HPHL PA"))) { + if ((snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0) + != 0xC0) + /* + * If PA_EN is not set (potentially in ANC case) + * then do nothing for POST_PMU and let right + * channel handle everything. + */ + break; + } + /* + * 7ms sleep is required after PA is enabled as per + * HW requirement + */ + if (test_bit(HPH_PA_DELAY, &tasha->status_mask)) { + usleep_range(7000, 7100); + clear_bit(HPH_PA_DELAY, &tasha->status_mask); + } + + tasha_codec_hph_post_pa_config(tasha, hph_mode, event); + snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CTL, + 0x10, 0x00); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + WCD9335_CDC_RX1_RX_PATH_MIX_CTL, + 0x10, 0x00); + + if (!(strcmp(w->name, "ANC HPHL PA"))) { + /* Do everything needed for right channel */ + snd_soc_update_bits(codec, WCD9335_CDC_RX2_RX_PATH_CTL, + 0x10, 0x00); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, + WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + WCD9335_CDC_RX2_RX_PATH_MIX_CTL, + 0x10, 0x00); + + /* Remove ANC Rx from reset */ + ret = tasha_codec_enable_anc(w, kcontrol, event); + } + tasha_codec_override(codec, hph_mode, event); + break; + case SND_SOC_DAPM_PRE_PMD: + blocking_notifier_call_chain(&tasha->notifier, + WCD_EVENT_PRE_HPHL_PA_OFF, + &tasha->mbhc); + tasha_codec_hph_post_pa_config(tasha, hph_mode, event); + if (!(strcmp(w->name, "ANC HPHL PA"))) + snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x80, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + /* 5ms sleep is required after PA is disabled as per + * HW requirement + */ + usleep_range(5000, 5500); + tasha_codec_override(codec, hph_mode, event); + blocking_notifier_call_chain(&tasha->notifier, + WCD_EVENT_POST_HPHL_PA_OFF, + &tasha->mbhc); + + if (!(strcmp(w->name, "ANC HPHL PA"))) { + ret = tasha_codec_enable_anc(w, kcontrol, event); + snd_soc_update_bits(codec, + WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x00); + } + break; + }; + + return ret; +} + +static int tasha_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 lineout_vol_reg = 0, lineout_mix_vol_reg = 0; + int ret = 0; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + if (w->reg == WCD9335_ANA_LO_1_2) { + if (w->shift == 7) { + lineout_vol_reg = WCD9335_CDC_RX3_RX_PATH_CTL; + lineout_mix_vol_reg = WCD9335_CDC_RX3_RX_PATH_MIX_CTL; + } else if (w->shift == 6) { + lineout_vol_reg = WCD9335_CDC_RX4_RX_PATH_CTL; + lineout_mix_vol_reg = WCD9335_CDC_RX4_RX_PATH_MIX_CTL; + } + } else if (w->reg == WCD9335_ANA_LO_3_4) { + if (w->shift == 7) { + lineout_vol_reg = WCD9335_CDC_RX5_RX_PATH_CTL; + lineout_mix_vol_reg = WCD9335_CDC_RX5_RX_PATH_MIX_CTL; + } else if (w->shift == 6) { + lineout_vol_reg = WCD9335_CDC_RX6_RX_PATH_CTL; + lineout_mix_vol_reg = WCD9335_CDC_RX6_RX_PATH_MIX_CTL; + } + } else { + dev_err(codec->dev, "%s: Error enabling lineout PA\n", + __func__); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* 5ms sleep is required after PA is enabled as per + * HW requirement + */ + usleep_range(5000, 5500); + snd_soc_update_bits(codec, lineout_vol_reg, + 0x10, 0x00); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, lineout_mix_vol_reg)) & 0x10) + snd_soc_update_bits(codec, + lineout_mix_vol_reg, + 0x10, 0x00); + if (!(strcmp(w->name, "ANC LINEOUT1 PA")) || + !(strcmp(w->name, "ANC LINEOUT2 PA"))) + ret = tasha_codec_enable_anc(w, kcontrol, event); + tasha_codec_override(codec, CLS_AB, event); + break; + case SND_SOC_DAPM_POST_PMD: + /* 5ms sleep is required after PA is disabled as per + * HW requirement + */ + usleep_range(5000, 5500); + tasha_codec_override(codec, CLS_AB, event); + if (!(strcmp(w->name, "ANC LINEOUT1 PA")) || + !(strcmp(w->name, "ANC LINEOUT2 PA"))) { + ret = tasha_codec_enable_anc(w, kcontrol, event); + if (!(strcmp(w->name, "ANC LINEOUT1 PA"))) + snd_soc_update_bits(codec, + WCD9335_CDC_RX3_RX_PATH_CFG0, 0x10, 0x10); + else + snd_soc_update_bits(codec, + WCD9335_CDC_RX4_RX_PATH_CFG0, 0x10, 0x10); + } + break; + }; + + return ret; +} + +static void tasha_spk_anc_update_callback(struct work_struct *work) +{ + struct spk_anc_work *spk_anc_dwork; + struct tasha_priv *tasha; + struct delayed_work *delayed_work; + struct snd_soc_codec *codec; + + delayed_work = to_delayed_work(work); + spk_anc_dwork = container_of(delayed_work, struct spk_anc_work, dwork); + tasha = spk_anc_dwork->tasha; + codec = tasha->codec; + + snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_CFG0, 0x10, 0x10); +} + +static int tasha_codec_enable_spk_anc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + int ret = 0; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s %s %d %d\n", __func__, w->name, event, + tasha->anc_func); + + if (!tasha->anc_func) + return 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = tasha_codec_enable_anc(w, kcontrol, event); + schedule_delayed_work(&tasha->spk_anc_dwork.dwork, + msecs_to_jiffies(spk_anc_en_delay)); + break; + case SND_SOC_DAPM_POST_PMD: + cancel_delayed_work_sync(&tasha->spk_anc_dwork.dwork); + snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_CFG0, + 0x10, 0x00); + ret = tasha_codec_enable_anc(w, kcontrol, event); + break; + } + return ret; +} + +static int tasha_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int ret = 0; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* 5ms sleep is required after PA is enabled as per + * HW requirement + */ + usleep_range(5000, 5500); + snd_soc_update_bits(codec, WCD9335_CDC_RX0_RX_PATH_CTL, + 0x10, 0x00); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, WCD9335_CDC_RX0_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + WCD9335_CDC_RX0_RX_PATH_MIX_CTL, + 0x10, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + /* 5ms sleep is required after PA is disabled as per + * HW requirement + */ + usleep_range(5000, 5500); + + if (!(strcmp(w->name, "ANC EAR PA"))) { + ret = tasha_codec_enable_anc(w, kcontrol, event); + snd_soc_update_bits(codec, + WCD9335_CDC_RX0_RX_PATH_CFG0, 0x10, 0x00); + } + break; + }; + + return ret; +} + +static void tasha_codec_hph_mode_gain_opt(struct snd_soc_codec *codec, + u8 gain) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + u8 hph_l_en, hph_r_en; + u8 l_val, r_val; + u8 hph_pa_status; + bool is_hphl_pa, is_hphr_pa; + + hph_pa_status = snd_soc_read(codec, WCD9335_ANA_HPH); + is_hphl_pa = hph_pa_status >> 7; + is_hphr_pa = (hph_pa_status & 0x40) >> 6; + + hph_l_en = snd_soc_read(codec, WCD9335_HPH_L_EN); + hph_r_en = snd_soc_read(codec, WCD9335_HPH_R_EN); + + l_val = (hph_l_en & 0xC0) | 0x20 | gain; + r_val = (hph_r_en & 0xC0) | 0x20 | gain; + + /* + * Set HPH_L & HPH_R gain source selection to REGISTER + * for better click and pop only if corresponding PAs are + * not enabled. Also cache the values of the HPHL/R + * PA gains to be applied after PAs are enabled + */ + if ((l_val != hph_l_en) && !is_hphl_pa) { + snd_soc_write(codec, WCD9335_HPH_L_EN, l_val); + tasha->hph_l_gain = hph_l_en & 0x1F; + } + + if ((r_val != hph_r_en) && !is_hphr_pa) { + snd_soc_write(codec, WCD9335_HPH_R_EN, r_val); + tasha->hph_r_gain = hph_r_en & 0x1F; + } +} + +static void tasha_codec_hph_lohifi_config(struct snd_soc_codec *codec, + int event) +{ + if (SND_SOC_DAPM_EVENT_ON(event)) { + snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_PA, 0x0F, 0x06); + snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2, + 0xF0, 0x40); + snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03); + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08); + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C); + tasha_codec_hph_mode_gain_opt(codec, 0x11); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00); + snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02); + snd_soc_write(codec, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8A); + snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_PA, 0x0F, 0x0A); + } +} + +static void tasha_codec_hph_lp_config(struct snd_soc_codec *codec, + int event) +{ + if (SND_SOC_DAPM_EVENT_ON(event)) { + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C); + tasha_codec_hph_mode_gain_opt(codec, 0x10); + snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03); + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08); + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x04, 0x04); + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x20, 0x20); + snd_soc_update_bits(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x07, + 0x01); + snd_soc_update_bits(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x70, + 0x10); + snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO, + 0x0F, 0x01); + snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO, + 0xF0, 0x10); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_write(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO, 0x88); + snd_soc_write(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x33); + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x20, 0x00); + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x04, 0x00); + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00); + snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02); + snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0xC0, 0x80); + snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0xC0, 0x80); + } +} + +static void tasha_codec_hph_hifi_config(struct snd_soc_codec *codec, + int event) +{ + if (SND_SOC_DAPM_EVENT_ON(event)) { + snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03); + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08); + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C); + tasha_codec_hph_mode_gain_opt(codec, 0x11); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00); + snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02); + } +} + +static void tasha_codec_hph_mode_config(struct snd_soc_codec *codec, + int event, int mode) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + if (!TASHA_IS_2_0(tasha->wcd9xxx)) + return; + + switch (mode) { + case CLS_H_LP: + tasha_codec_hph_lp_config(codec, event); + break; + case CLS_H_LOHIFI: + tasha_codec_hph_lohifi_config(codec, event); + break; + case CLS_H_HIFI: + tasha_codec_hph_hifi_config(codec, event); + break; + } +} + +static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + int hph_mode = tasha->hph_mode; + u8 dem_inp; + int ret = 0; + + dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, + w->name, event, hph_mode); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (tasha->anc_func) { + ret = tasha_codec_enable_anc(w, kcontrol, event); + /* 40 msec delay is needed to avoid click and pop */ + msleep(40); + } + + /* Read DEM INP Select */ + dem_inp = snd_soc_read(codec, WCD9335_CDC_RX2_RX_PATH_SEC0) & + 0x03; + if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || + (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { + dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", + __func__, hph_mode); + return -EINVAL; + } + wcd_clsh_fsm(codec, &tasha->clsh_d, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_HPHR, + ((hph_mode == CLS_H_LOHIFI) ? + CLS_H_HIFI : hph_mode)); + + tasha_codec_hph_mode_config(codec, event, hph_mode); + + if (tasha->anc_func) + snd_soc_update_bits(codec, + WCD9335_CDC_RX2_RX_PATH_CFG0, 0x10, 0x10); + + break; + case SND_SOC_DAPM_POST_PMU: + /* 1000us required as per HW requirement */ + usleep_range(1000, 1100); + if ((hph_mode == CLS_H_LP) && + (TASHA_IS_1_1(wcd9xxx))) { + snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL, + 0x03, 0x03); + } + break; + case SND_SOC_DAPM_PRE_PMD: + if ((hph_mode == CLS_H_LP) && + (TASHA_IS_1_1(wcd9xxx))) { + snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL, + 0x03, 0x00); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* 1000us required as per HW requirement */ + usleep_range(1000, 1100); + + if (!(wcd_clsh_get_clsh_state(&tasha->clsh_d) & + WCD_CLSH_STATE_HPHL)) + tasha_codec_hph_mode_config(codec, event, hph_mode); + + wcd_clsh_fsm(codec, &tasha->clsh_d, + WCD_CLSH_EVENT_POST_PA, + WCD_CLSH_STATE_HPHR, + ((hph_mode == CLS_H_LOHIFI) ? + CLS_H_HIFI : hph_mode)); + break; + }; + + return ret; +} + +static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + int hph_mode = tasha->hph_mode; + u8 dem_inp; + int ret = 0; + uint32_t impedl = 0, impedr = 0; + + dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, + w->name, event, hph_mode); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (tasha->anc_func) { + ret = tasha_codec_enable_anc(w, kcontrol, event); + /* 40 msec delay is needed to avoid click and pop */ + msleep(40); + } + + /* Read DEM INP Select */ + dem_inp = snd_soc_read(codec, WCD9335_CDC_RX1_RX_PATH_SEC0) & + 0x03; + if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || + (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { + dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", + __func__, hph_mode); + return -EINVAL; + } + wcd_clsh_fsm(codec, &tasha->clsh_d, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_HPHL, + ((hph_mode == CLS_H_LOHIFI) ? + CLS_H_HIFI : hph_mode)); + + tasha_codec_hph_mode_config(codec, event, hph_mode); + + if (tasha->anc_func) + snd_soc_update_bits(codec, + WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x10); + + ret = wcd_mbhc_get_impedance(&tasha->mbhc, + &impedl, &impedr); + if (!ret) { + wcd_clsh_imped_config(codec, impedl, false); + set_bit(CLASSH_CONFIG, &tasha->status_mask); + } else { + dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n", + __func__, ret); + ret = 0; + } + + + break; + case SND_SOC_DAPM_POST_PMU: + /* 1000us required as per HW requirement */ + usleep_range(1000, 1100); + if ((hph_mode == CLS_H_LP) && + (TASHA_IS_1_1(wcd9xxx))) { + snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL, + 0x03, 0x03); + } + break; + case SND_SOC_DAPM_PRE_PMD: + if ((hph_mode == CLS_H_LP) && + (TASHA_IS_1_1(wcd9xxx))) { + snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL, + 0x03, 0x00); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* 1000us required as per HW requirement */ + usleep_range(1000, 1100); + + if (!(wcd_clsh_get_clsh_state(&tasha->clsh_d) & + WCD_CLSH_STATE_HPHR)) + tasha_codec_hph_mode_config(codec, event, hph_mode); + wcd_clsh_fsm(codec, &tasha->clsh_d, + WCD_CLSH_EVENT_POST_PA, + WCD_CLSH_STATE_HPHL, + ((hph_mode == CLS_H_LOHIFI) ? + CLS_H_HIFI : hph_mode)); + + if (test_bit(CLASSH_CONFIG, &tasha->status_mask)) { + wcd_clsh_imped_config(codec, impedl, true); + clear_bit(CLASSH_CONFIG, &tasha->status_mask); + } else + dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n", + __func__, ret); + + + break; + }; + + return ret; +} + +static int tasha_codec_lineout_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (tasha->anc_func && + (!strcmp(w->name, "RX INT3 DAC") || + !strcmp(w->name, "RX INT4 DAC"))) + ret = tasha_codec_enable_anc(w, kcontrol, event); + + wcd_clsh_fsm(codec, &tasha->clsh_d, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_LO, + CLS_AB); + + if (tasha->anc_func) { + if (!strcmp(w->name, "RX INT3 DAC")) + snd_soc_update_bits(codec, + WCD9335_CDC_RX3_RX_PATH_CFG0, 0x10, 0x10); + else if (!strcmp(w->name, "RX INT4 DAC")) + snd_soc_update_bits(codec, + WCD9335_CDC_RX4_RX_PATH_CFG0, 0x10, 0x10); + } + break; + case SND_SOC_DAPM_POST_PMD: + wcd_clsh_fsm(codec, &tasha->clsh_d, + WCD_CLSH_EVENT_POST_PA, + WCD_CLSH_STATE_LO, + CLS_AB); + break; + } + + return 0; +} + +static const struct snd_soc_dapm_widget tasha_dapm_i2s_widgets[] = { + SND_SOC_DAPM_SUPPLY("RX_I2S_CTL", WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL, + 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("TX_I2S_CTL", WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL, + 0, 0, NULL, 0), +}; + +static int tasha_codec_ear_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (tasha->anc_func) + ret = tasha_codec_enable_anc(w, kcontrol, event); + + wcd_clsh_fsm(codec, &tasha->clsh_d, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_EAR, + CLS_H_NORMAL); + if (tasha->anc_func) + snd_soc_update_bits(codec, + WCD9335_CDC_RX0_RX_PATH_CFG0, 0x10, 0x10); + + break; + case SND_SOC_DAPM_POST_PMU: + break; + case SND_SOC_DAPM_PRE_PMD: + break; + case SND_SOC_DAPM_POST_PMD: + wcd_clsh_fsm(codec, &tasha->clsh_d, + WCD_CLSH_EVENT_POST_PA, + WCD_CLSH_STATE_EAR, + CLS_H_NORMAL); + break; + }; + + return ret; +} + +static int tasha_codec_spk_boost_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 boost_path_ctl, boost_path_cfg1; + u16 reg, reg_mix; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + if (!strcmp(w->name, "RX INT7 CHAIN")) { + boost_path_ctl = WCD9335_CDC_BOOST0_BOOST_PATH_CTL; + boost_path_cfg1 = WCD9335_CDC_RX7_RX_PATH_CFG1; + reg = WCD9335_CDC_RX7_RX_PATH_CTL; + reg_mix = WCD9335_CDC_RX7_RX_PATH_MIX_CTL; + } else if (!strcmp(w->name, "RX INT8 CHAIN")) { + boost_path_ctl = WCD9335_CDC_BOOST1_BOOST_PATH_CTL; + boost_path_cfg1 = WCD9335_CDC_RX8_RX_PATH_CFG1; + reg = WCD9335_CDC_RX8_RX_PATH_CTL; + reg_mix = WCD9335_CDC_RX8_RX_PATH_MIX_CTL; + } else { + dev_err(codec->dev, "%s: unknown widget: %s\n", + __func__, w->name); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x10); + snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x01); + snd_soc_update_bits(codec, reg, 0x10, 0x00); + if ((snd_soc_read(codec, reg_mix)) & 0x10) + snd_soc_update_bits(codec, reg_mix, 0x10, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x00); + snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x00); + break; + }; + + return 0; +} + +static u16 tasha_interp_get_primary_reg(u16 reg, u16 *ind) +{ + u16 prim_int_reg = 0; + + switch (reg) { + case WCD9335_CDC_RX0_RX_PATH_CTL: + case WCD9335_CDC_RX0_RX_PATH_MIX_CTL: + prim_int_reg = WCD9335_CDC_RX0_RX_PATH_CTL; + *ind = 0; + break; + case WCD9335_CDC_RX1_RX_PATH_CTL: + case WCD9335_CDC_RX1_RX_PATH_MIX_CTL: + prim_int_reg = WCD9335_CDC_RX1_RX_PATH_CTL; + *ind = 1; + break; + case WCD9335_CDC_RX2_RX_PATH_CTL: + case WCD9335_CDC_RX2_RX_PATH_MIX_CTL: + prim_int_reg = WCD9335_CDC_RX2_RX_PATH_CTL; + *ind = 2; + break; + case WCD9335_CDC_RX3_RX_PATH_CTL: + case WCD9335_CDC_RX3_RX_PATH_MIX_CTL: + prim_int_reg = WCD9335_CDC_RX3_RX_PATH_CTL; + *ind = 3; + break; + case WCD9335_CDC_RX4_RX_PATH_CTL: + case WCD9335_CDC_RX4_RX_PATH_MIX_CTL: + prim_int_reg = WCD9335_CDC_RX4_RX_PATH_CTL; + *ind = 4; + break; + case WCD9335_CDC_RX5_RX_PATH_CTL: + case WCD9335_CDC_RX5_RX_PATH_MIX_CTL: + prim_int_reg = WCD9335_CDC_RX5_RX_PATH_CTL; + *ind = 5; + break; + case WCD9335_CDC_RX6_RX_PATH_CTL: + case WCD9335_CDC_RX6_RX_PATH_MIX_CTL: + prim_int_reg = WCD9335_CDC_RX6_RX_PATH_CTL; + *ind = 6; + break; + case WCD9335_CDC_RX7_RX_PATH_CTL: + case WCD9335_CDC_RX7_RX_PATH_MIX_CTL: + prim_int_reg = WCD9335_CDC_RX7_RX_PATH_CTL; + *ind = 7; + break; + case WCD9335_CDC_RX8_RX_PATH_CTL: + case WCD9335_CDC_RX8_RX_PATH_MIX_CTL: + prim_int_reg = WCD9335_CDC_RX8_RX_PATH_CTL; + *ind = 8; + break; + }; + + return prim_int_reg; +} + +static void tasha_codec_hd2_control(struct snd_soc_codec *codec, + u16 prim_int_reg, int event) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + u16 hd2_scale_reg; + u16 hd2_enable_reg = 0; + + if (!TASHA_IS_2_0(tasha->wcd9xxx)) + return; + + if (prim_int_reg == WCD9335_CDC_RX1_RX_PATH_CTL) { + hd2_scale_reg = WCD9335_CDC_RX1_RX_PATH_SEC3; + hd2_enable_reg = WCD9335_CDC_RX1_RX_PATH_CFG0; + } + if (prim_int_reg == WCD9335_CDC_RX2_RX_PATH_CTL) { + hd2_scale_reg = WCD9335_CDC_RX2_RX_PATH_SEC3; + hd2_enable_reg = WCD9335_CDC_RX2_RX_PATH_CFG0; + } + + if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { + snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x10); + snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x01); + snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x04); + } + + if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x00); + snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x00); + snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x00); + } +} + +static int tasha_codec_enable_prim_interpolator( + struct snd_soc_codec *codec, + u16 reg, int event) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + u16 prim_int_reg; + u16 ind = 0; + + prim_int_reg = tasha_interp_get_primary_reg(reg, &ind); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + tasha->prim_int_users[ind]++; + if (tasha->prim_int_users[ind] == 1) { + snd_soc_update_bits(codec, prim_int_reg, + 0x10, 0x10); + tasha_codec_hd2_control(codec, prim_int_reg, event); + snd_soc_update_bits(codec, prim_int_reg, + 1 << 0x5, 1 << 0x5); + } + if ((reg != prim_int_reg) && + ((snd_soc_read(codec, prim_int_reg)) & 0x10)) + snd_soc_update_bits(codec, reg, 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMD: + tasha->prim_int_users[ind]--; + if (tasha->prim_int_users[ind] == 0) { + snd_soc_update_bits(codec, prim_int_reg, + 1 << 0x5, 0 << 0x5); + snd_soc_update_bits(codec, prim_int_reg, + 0x40, 0x40); + snd_soc_update_bits(codec, prim_int_reg, + 0x40, 0x00); + tasha_codec_hd2_control(codec, prim_int_reg, event); + } + break; + }; + + dev_dbg(codec->dev, "%s: primary interpolator: INT%d, users: %d\n", + __func__, ind, tasha->prim_int_users[ind]); + return 0; +} + +static int tasha_codec_enable_spline_src(struct snd_soc_codec *codec, + int src_num, + int event) +{ + u16 src_paired_reg = 0; + struct tasha_priv *tasha; + u16 rx_path_cfg_reg = WCD9335_CDC_RX1_RX_PATH_CFG0; + u16 rx_path_ctl_reg = WCD9335_CDC_RX1_RX_PATH_CTL; + int *src_users, count, spl_src = SPLINE_SRC0; + u16 src_clk_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0; + + tasha = snd_soc_codec_get_drvdata(codec); + + switch (src_num) { + case SRC_IN_HPHL: + rx_path_cfg_reg = WCD9335_CDC_RX1_RX_PATH_CFG0; + src_clk_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0; + src_paired_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0; + rx_path_ctl_reg = WCD9335_CDC_RX1_RX_PATH_CTL; + spl_src = SPLINE_SRC0; + break; + case SRC_IN_LO1: + rx_path_cfg_reg = WCD9335_CDC_RX3_RX_PATH_CFG0; + src_clk_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0; + src_paired_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0; + rx_path_ctl_reg = WCD9335_CDC_RX3_RX_PATH_CTL; + spl_src = SPLINE_SRC0; + break; + case SRC_IN_HPHR: + rx_path_cfg_reg = WCD9335_CDC_RX2_RX_PATH_CFG0; + src_clk_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0; + src_paired_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0; + rx_path_ctl_reg = WCD9335_CDC_RX2_RX_PATH_CTL; + spl_src = SPLINE_SRC1; + break; + case SRC_IN_LO2: + rx_path_cfg_reg = WCD9335_CDC_RX4_RX_PATH_CFG0; + src_clk_reg = WCD9335_SPLINE_SRC1_CLK_RST_CTL_0; + src_paired_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0; + rx_path_ctl_reg = WCD9335_CDC_RX4_RX_PATH_CTL; + spl_src = SPLINE_SRC1; + break; + case SRC_IN_SPKRL: + rx_path_cfg_reg = WCD9335_CDC_RX7_RX_PATH_CFG0; + src_clk_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0; + src_paired_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0; + rx_path_ctl_reg = WCD9335_CDC_RX7_RX_PATH_CTL; + spl_src = SPLINE_SRC2; + break; + case SRC_IN_LO3: + rx_path_cfg_reg = WCD9335_CDC_RX5_RX_PATH_CFG0; + src_clk_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0; + src_paired_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0; + rx_path_ctl_reg = WCD9335_CDC_RX5_RX_PATH_CTL; + spl_src = SPLINE_SRC2; + break; + case SRC_IN_SPKRR: + rx_path_cfg_reg = WCD9335_CDC_RX8_RX_PATH_CFG0; + src_clk_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0; + src_paired_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0; + rx_path_ctl_reg = WCD9335_CDC_RX8_RX_PATH_CTL; + spl_src = SPLINE_SRC3; + break; + case SRC_IN_LO4: + rx_path_cfg_reg = WCD9335_CDC_RX6_RX_PATH_CFG0; + src_clk_reg = WCD9335_SPLINE_SRC3_CLK_RST_CTL_0; + src_paired_reg = WCD9335_SPLINE_SRC2_CLK_RST_CTL_0; + rx_path_ctl_reg = WCD9335_CDC_RX6_RX_PATH_CTL; + spl_src = SPLINE_SRC3; + break; + }; + + src_users = &tasha->spl_src_users[spl_src]; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + count = *src_users; + count++; + if (count == 1) { + if ((snd_soc_read(codec, src_clk_reg) & 0x02) || + (snd_soc_read(codec, src_paired_reg) & 0x02)) { + snd_soc_update_bits(codec, src_clk_reg, 0x02, + 0x00); + snd_soc_update_bits(codec, src_paired_reg, + 0x02, 0x00); + } + snd_soc_update_bits(codec, src_clk_reg, 0x01, 0x01); + snd_soc_update_bits(codec, rx_path_cfg_reg, 0x80, + 0x80); + } + *src_users = count; + break; + case SND_SOC_DAPM_POST_PMD: + count = *src_users; + count--; + if (count == 0) { + snd_soc_update_bits(codec, rx_path_cfg_reg, 0x80, + 0x00); + snd_soc_update_bits(codec, src_clk_reg, 0x03, 0x02); + /* default sample rate */ + snd_soc_update_bits(codec, rx_path_ctl_reg, 0x0f, + 0x04); + } + *src_users = count; + break; + }; + + dev_dbg(codec->dev, "%s: Spline SRC%d, users: %d\n", + __func__, spl_src, *src_users); + return 0; +} + +static int tasha_codec_enable_spline_resampler(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int ret = 0; + u8 src_in; + + src_in = snd_soc_read(codec, WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0); + if (!(src_in & 0xFF)) { + dev_err(codec->dev, "%s: Spline SRC%u input not selected\n", + __func__, w->shift); + return -EINVAL; + } + + switch (w->shift) { + case SPLINE_SRC0: + ret = tasha_codec_enable_spline_src(codec, + ((src_in & 0x03) == 1) ? SRC_IN_HPHL : SRC_IN_LO1, + event); + break; + case SPLINE_SRC1: + ret = tasha_codec_enable_spline_src(codec, + ((src_in & 0x0C) == 4) ? SRC_IN_HPHR : SRC_IN_LO2, + event); + break; + case SPLINE_SRC2: + ret = tasha_codec_enable_spline_src(codec, + ((src_in & 0x30) == 0x10) ? SRC_IN_LO3 : SRC_IN_SPKRL, + event); + break; + case SPLINE_SRC3: + ret = tasha_codec_enable_spline_src(codec, + ((src_in & 0xC0) == 0x40) ? SRC_IN_LO4 : SRC_IN_SPKRR, + event); + break; + default: + dev_err(codec->dev, "%s: Invalid spline src:%u\n", __func__, + w->shift); + ret = -EINVAL; + }; + + return ret; +} + +static int tasha_codec_enable_swr(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha; + int i, ch_cnt; + + tasha = snd_soc_codec_get_drvdata(codec); + + if (!tasha->nr) + return 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) && + !tasha->rx_7_count) + tasha->rx_7_count++; + if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) && + !tasha->rx_8_count) + tasha->rx_8_count++; + ch_cnt = tasha->rx_7_count + tasha->rx_8_count; + + for (i = 0; i < tasha->nr; i++) { + swrm_wcd_notify(tasha->swr_ctrl_data[i].swr_pdev, + SWR_DEVICE_UP, NULL); + swrm_wcd_notify(tasha->swr_ctrl_data[i].swr_pdev, + SWR_SET_NUM_RX_CH, &ch_cnt); + } + break; + case SND_SOC_DAPM_POST_PMD: + if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) && + tasha->rx_7_count) + tasha->rx_7_count--; + if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) && + tasha->rx_8_count) + tasha->rx_8_count--; + ch_cnt = tasha->rx_7_count + tasha->rx_8_count; + + for (i = 0; i < tasha->nr; i++) + swrm_wcd_notify(tasha->swr_ctrl_data[i].swr_pdev, + SWR_SET_NUM_RX_CH, &ch_cnt); + + break; + } + dev_dbg(tasha->dev, "%s: current swr ch cnt: %d\n", + __func__, tasha->rx_7_count + tasha->rx_8_count); + + return 0; +} + +static int tasha_codec_config_ear_spkr_gain(struct snd_soc_codec *codec, + int event, int gain_reg) +{ + int comp_gain_offset, val; + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + switch (tasha->spkr_mode) { + /* Compander gain in SPKR_MODE1 case is 12 dB */ + case SPKR_MODE_1: + comp_gain_offset = -12; + break; + /* Default case compander gain is 15 dB */ + default: + comp_gain_offset = -15; + break; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* Apply ear spkr gain only if compander is enabled */ + if (tasha->comp_enabled[COMPANDER_7] && + (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL || + gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL) && + (tasha->ear_spkr_gain != 0)) { + /* For example, val is -8(-12+5-1) for 4dB of gain */ + val = comp_gain_offset + tasha->ear_spkr_gain - 1; + snd_soc_write(codec, gain_reg, val); + + dev_dbg(codec->dev, "%s: RX7 Volume %d dB\n", + __func__, val); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* + * Reset RX7 volume to 0 dB if compander is enabled and + * ear_spkr_gain is non-zero. + */ + if (tasha->comp_enabled[COMPANDER_7] && + (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL || + gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL) && + (tasha->ear_spkr_gain != 0)) { + snd_soc_write(codec, gain_reg, 0x0); + + dev_dbg(codec->dev, "%s: Reset RX7 Volume to 0 dB\n", + __func__); + } + break; + } + + return 0; +} + +static int tasha_codec_enable_mix_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + u16 gain_reg; + int offset_val = 0; + int val = 0; + + dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + + switch (w->reg) { + case WCD9335_CDC_RX0_RX_PATH_MIX_CTL: + gain_reg = WCD9335_CDC_RX0_RX_VOL_MIX_CTL; + break; + case WCD9335_CDC_RX1_RX_PATH_MIX_CTL: + gain_reg = WCD9335_CDC_RX1_RX_VOL_MIX_CTL; + break; + case WCD9335_CDC_RX2_RX_PATH_MIX_CTL: + gain_reg = WCD9335_CDC_RX2_RX_VOL_MIX_CTL; + break; + case WCD9335_CDC_RX3_RX_PATH_MIX_CTL: + gain_reg = WCD9335_CDC_RX3_RX_VOL_MIX_CTL; + break; + case WCD9335_CDC_RX4_RX_PATH_MIX_CTL: + gain_reg = WCD9335_CDC_RX4_RX_VOL_MIX_CTL; + break; + case WCD9335_CDC_RX5_RX_PATH_MIX_CTL: + gain_reg = WCD9335_CDC_RX5_RX_VOL_MIX_CTL; + break; + case WCD9335_CDC_RX6_RX_PATH_MIX_CTL: + gain_reg = WCD9335_CDC_RX6_RX_VOL_MIX_CTL; + break; + case WCD9335_CDC_RX7_RX_PATH_MIX_CTL: + gain_reg = WCD9335_CDC_RX7_RX_VOL_MIX_CTL; + break; + case WCD9335_CDC_RX8_RX_PATH_MIX_CTL: + gain_reg = WCD9335_CDC_RX8_RX_VOL_MIX_CTL; + break; + default: + dev_err(codec->dev, "%s: No gain register avail for %s\n", + __func__, w->name); + return 0; + }; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && + (tasha->comp_enabled[COMPANDER_7] || + tasha->comp_enabled[COMPANDER_8]) && + (gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL || + gain_reg == WCD9335_CDC_RX8_RX_VOL_MIX_CTL)) { + snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_update_bits(codec, + WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x01); + snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_update_bits(codec, + WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x01); + offset_val = -2; + } + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + tasha_codec_config_ear_spkr_gain(codec, event, gain_reg); + break; + case SND_SOC_DAPM_POST_PMD: + if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && + (tasha->comp_enabled[COMPANDER_7] || + tasha->comp_enabled[COMPANDER_8]) && + (gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL || + gain_reg == WCD9335_CDC_RX8_RX_VOL_MIX_CTL)) { + snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x00); + snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x00); + offset_val = 2; + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + } + tasha_codec_config_ear_spkr_gain(codec, event, gain_reg); + break; + }; + + return 0; +} + +static int __tasha_cdc_native_clk_enable(struct tasha_priv *tasha, + bool enable) +{ + int ret = 0; + struct snd_soc_codec *codec = tasha->codec; + + if (!tasha->wcd_native_clk) { + dev_err(tasha->dev, "%s: wcd native clock is NULL\n", __func__); + return -EINVAL; + } + + dev_dbg(tasha->dev, "%s: native_clk_enable = %u\n", __func__, enable); + + if (enable) { + ret = clk_prepare_enable(tasha->wcd_native_clk); + if (ret) { + dev_err(tasha->dev, "%s: native clk enable failed\n", + __func__); + goto err; + } + if (++tasha->native_clk_users == 1) { + snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL, + 0x10, 0x10); + snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL, + 0x80, 0x80); + snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_GATE, + 0x04, 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x02, 0x02); + } + } else { + if (tasha->native_clk_users && + (--tasha->native_clk_users == 0)) { + snd_soc_update_bits(codec, + WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x02, 0x00); + snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_GATE, + 0x04, 0x04); + snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL, + 0x80, 0x00); + snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL, + 0x10, 0x00); + } + clk_disable_unprepare(tasha->wcd_native_clk); + } + + dev_dbg(codec->dev, "%s: native_clk_users: %d\n", __func__, + tasha->native_clk_users); +err: + return ret; +} + +static int tasha_codec_get_native_fifo_sync_mask(struct snd_soc_codec *codec, + int interp_n) +{ + int mask = 0; + u16 reg; + u8 val1, val2, inp0 = 0; + u8 inp1 = 0, inp2 = 0; + + reg = WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0 + (2 * interp_n) - 2; + + val1 = snd_soc_read(codec, reg); + val2 = snd_soc_read(codec, reg + 1); + + inp0 = val1 & 0x0F; + inp1 = (val1 >> 4) & 0x0F; + inp2 = (val2 >> 4) & 0x0F; + + if (IS_VALID_NATIVE_FIFO_PORT(inp0)) + mask |= (1 << (inp0 - 5)); + if (IS_VALID_NATIVE_FIFO_PORT(inp1)) + mask |= (1 << (inp1 - 5)); + if (IS_VALID_NATIVE_FIFO_PORT(inp2)) + mask |= (1 << (inp2 - 5)); + + dev_dbg(codec->dev, "%s: native fifo mask: 0x%x\n", __func__, mask); + if (!mask) + dev_err(codec->dev, "native fifo err,int:%d,inp0:%d,inp1:%d,inp2:%d\n", + interp_n, inp0, inp1, inp2); + return mask; +} + +static int tasha_enable_native_supply(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + int mask; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + u16 interp_reg; + + dev_dbg(codec->dev, "%s: event: %d, shift:%d\n", __func__, event, + w->shift); + + if (w->shift < INTERP_HPHL || w->shift > INTERP_LO2) + return -EINVAL; + + interp_reg = WCD9335_CDC_RX1_RX_PATH_CTL + 20 * (w->shift - 1); + + mask = tasha_codec_get_native_fifo_sync_mask(codec, w->shift); + if (!mask) + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Adjust interpolator rate to 44P1_NATIVE */ + snd_soc_update_bits(codec, interp_reg, 0x0F, 0x09); + __tasha_cdc_native_clk_enable(tasha, true); + snd_soc_update_bits(codec, WCD9335_DATA_HUB_NATIVE_FIFO_SYNC, + mask, mask); + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_update_bits(codec, WCD9335_DATA_HUB_NATIVE_FIFO_SYNC, + mask, 0x0); + __tasha_cdc_native_clk_enable(tasha, false); + /* Adjust interpolator rate to default */ + snd_soc_update_bits(codec, interp_reg, 0x0F, 0x04); + break; + } + + return 0; +} + +static int tasha_codec_enable_interpolator(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + u16 gain_reg; + u16 reg; + int val; + int offset_val = 0; + + dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + + if (!(strcmp(w->name, "RX INT0 INTERP"))) { + reg = WCD9335_CDC_RX0_RX_PATH_CTL; + gain_reg = WCD9335_CDC_RX0_RX_VOL_CTL; + } else if (!(strcmp(w->name, "RX INT1 INTERP"))) { + reg = WCD9335_CDC_RX1_RX_PATH_CTL; + gain_reg = WCD9335_CDC_RX1_RX_VOL_CTL; + } else if (!(strcmp(w->name, "RX INT2 INTERP"))) { + reg = WCD9335_CDC_RX2_RX_PATH_CTL; + gain_reg = WCD9335_CDC_RX2_RX_VOL_CTL; + } else if (!(strcmp(w->name, "RX INT3 INTERP"))) { + reg = WCD9335_CDC_RX3_RX_PATH_CTL; + gain_reg = WCD9335_CDC_RX3_RX_VOL_CTL; + } else if (!(strcmp(w->name, "RX INT4 INTERP"))) { + reg = WCD9335_CDC_RX4_RX_PATH_CTL; + gain_reg = WCD9335_CDC_RX4_RX_VOL_CTL; + } else if (!(strcmp(w->name, "RX INT5 INTERP"))) { + reg = WCD9335_CDC_RX5_RX_PATH_CTL; + gain_reg = WCD9335_CDC_RX5_RX_VOL_CTL; + } else if (!(strcmp(w->name, "RX INT6 INTERP"))) { + reg = WCD9335_CDC_RX6_RX_PATH_CTL; + gain_reg = WCD9335_CDC_RX6_RX_VOL_CTL; + } else if (!(strcmp(w->name, "RX INT7 INTERP"))) { + reg = WCD9335_CDC_RX7_RX_PATH_CTL; + gain_reg = WCD9335_CDC_RX7_RX_VOL_CTL; + } else if (!(strcmp(w->name, "RX INT8 INTERP"))) { + reg = WCD9335_CDC_RX8_RX_PATH_CTL; + gain_reg = WCD9335_CDC_RX8_RX_VOL_CTL; + } else { + dev_err(codec->dev, "%s: Interpolator reg not found\n", + __func__); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (!test_bit(SB_CLK_GEAR, &tasha->status_mask)) { + tasha_codec_vote_max_bw(codec, true); + set_bit(SB_CLK_GEAR, &tasha->status_mask); + } + /* Reset if needed */ + tasha_codec_enable_prim_interpolator(codec, reg, event); + break; + case SND_SOC_DAPM_POST_PMU: + tasha_config_compander(codec, w->shift, event); + /* apply gain after int clk is enabled */ + if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && + (tasha->comp_enabled[COMPANDER_7] || + tasha->comp_enabled[COMPANDER_8]) && + (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL || + gain_reg == WCD9335_CDC_RX8_RX_VOL_CTL)) { + snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_update_bits(codec, + WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x01); + snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_update_bits(codec, + WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x01); + offset_val = -2; + } + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + tasha_codec_config_ear_spkr_gain(codec, event, gain_reg); + break; + case SND_SOC_DAPM_POST_PMD: + tasha_config_compander(codec, w->shift, event); + tasha_codec_enable_prim_interpolator(codec, reg, event); + if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && + (tasha->comp_enabled[COMPANDER_7] || + tasha->comp_enabled[COMPANDER_8]) && + (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL || + gain_reg == WCD9335_CDC_RX8_RX_VOL_CTL)) { + snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x00); + snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x00); + offset_val = 2; + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + } + tasha_codec_config_ear_spkr_gain(codec, event, gain_reg); + break; + }; + + return 0; +} + +static int tasha_codec_set_iir_gain(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: /* fall through */ + case SND_SOC_DAPM_PRE_PMD: + if (strnstr(w->name, "IIR0", sizeof("IIR0"))) { + snd_soc_write(codec, + WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, + snd_soc_read(codec, + WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)); + snd_soc_write(codec, + WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, + snd_soc_read(codec, + WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)); + snd_soc_write(codec, + WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, + snd_soc_read(codec, + WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)); + snd_soc_write(codec, + WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, + snd_soc_read(codec, + WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)); + } else { + snd_soc_write(codec, + WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, + snd_soc_read(codec, + WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL)); + snd_soc_write(codec, + WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, + snd_soc_read(codec, + WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL)); + snd_soc_write(codec, + WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, + snd_soc_read(codec, + WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL)); + } + break; + } + return 0; +} + +static int tasha_codec_enable_on_demand_supply( + struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + int ret = 0; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct on_demand_supply *supply; + + if (w->shift >= ON_DEMAND_SUPPLIES_MAX) { + dev_err(codec->dev, "%s: error index > MAX Demand supplies", + __func__); + ret = -EINVAL; + goto out; + } + + dev_dbg(codec->dev, "%s: supply: %s event: %d\n", + __func__, on_demand_supply_name[w->shift], event); + + supply = &tasha->on_demand_list[w->shift]; + WARN_ONCE(!supply->supply, "%s isn't defined\n", + on_demand_supply_name[w->shift]); + if (!supply->supply) { + dev_err(codec->dev, "%s: err supply not present ond for %d", + __func__, w->shift); + goto out; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = regulator_enable(supply->supply); + if (ret) + dev_err(codec->dev, "%s: Failed to enable %s\n", + __func__, + on_demand_supply_name[w->shift]); + break; + case SND_SOC_DAPM_POST_PMD: + ret = regulator_disable(supply->supply); + if (ret) + dev_err(codec->dev, "%s: Failed to disable %s\n", + __func__, + on_demand_supply_name[w->shift]); + break; + default: + break; + }; + +out: + return ret; +} + +static int tasha_codec_find_amic_input(struct snd_soc_codec *codec, + int adc_mux_n) +{ + u16 mask, shift, adc_mux_in_reg; + u16 amic_mux_sel_reg; + bool is_amic; + + if (adc_mux_n < 0 || adc_mux_n > WCD9335_MAX_VALID_ADC_MUX || + adc_mux_n == WCD9335_INVALID_ADC_MUX) + return 0; + + /* Check whether adc mux input is AMIC or DMIC */ + if (adc_mux_n < 4) { + adc_mux_in_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + + 2 * adc_mux_n; + amic_mux_sel_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + + 2 * adc_mux_n; + mask = 0x03; + shift = 0; + } else { + adc_mux_in_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + + adc_mux_n - 4; + amic_mux_sel_reg = adc_mux_in_reg; + mask = 0xC0; + shift = 6; + } + is_amic = (((snd_soc_read(codec, adc_mux_in_reg) & mask) >> shift) + == 1); + if (!is_amic) + return 0; + + return snd_soc_read(codec, amic_mux_sel_reg) & 0x07; +} + +static void tasha_codec_set_tx_hold(struct snd_soc_codec *codec, + u16 amic_reg, bool set) +{ + u8 mask = 0x20; + u8 val; + + if (amic_reg == WCD9335_ANA_AMIC1 || + amic_reg == WCD9335_ANA_AMIC3 || + amic_reg == WCD9335_ANA_AMIC5) + mask = 0x40; + + val = set ? mask : 0x00; + + switch (amic_reg) { + case WCD9335_ANA_AMIC1: + case WCD9335_ANA_AMIC2: + snd_soc_update_bits(codec, WCD9335_ANA_AMIC2, mask, val); + break; + case WCD9335_ANA_AMIC3: + case WCD9335_ANA_AMIC4: + snd_soc_update_bits(codec, WCD9335_ANA_AMIC4, mask, val); + break; + case WCD9335_ANA_AMIC5: + case WCD9335_ANA_AMIC6: + snd_soc_update_bits(codec, WCD9335_ANA_AMIC6, mask, val); + break; + default: + dev_dbg(codec->dev, "%s: invalid amic: %d\n", + __func__, amic_reg); + break; + } +} + +static int tasha_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + int adc_mux_n = w->shift; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + int amic_n; + + dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + amic_n = tasha_codec_find_amic_input(codec, adc_mux_n); + if (amic_n) { + /* + * Prevent ANC Rx pop by leaving Tx FE in HOLD + * state until PA is up. Track AMIC being used + * so we can release the HOLD later. + */ + set_bit(ANC_MIC_AMIC1 + amic_n - 1, + &tasha->status_mask); + } + break; + default: + break; + } + + return 0; +} + +static u16 tasha_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic) +{ + u16 pwr_level_reg = 0; + + switch (amic) { + case 1: + case 2: + pwr_level_reg = WCD9335_ANA_AMIC1; + break; + + case 3: + case 4: + pwr_level_reg = WCD9335_ANA_AMIC3; + break; + + case 5: + case 6: + pwr_level_reg = WCD9335_ANA_AMIC5; + break; + default: + dev_dbg(codec->dev, "%s: invalid amic: %d\n", + __func__, amic); + break; + } + + return pwr_level_reg; +} + +#define TX_HPF_CUT_OFF_FREQ_MASK 0x60 +#define CF_MIN_3DB_4HZ 0x0 +#define CF_MIN_3DB_75HZ 0x1 +#define CF_MIN_3DB_150HZ 0x2 + +static void tasha_tx_hpf_corner_freq_callback(struct work_struct *work) +{ + struct delayed_work *hpf_delayed_work; + struct hpf_work *hpf_work; + struct tasha_priv *tasha; + struct snd_soc_codec *codec; + u16 dec_cfg_reg, amic_reg; + u8 hpf_cut_off_freq; + int amic_n; + + hpf_delayed_work = to_delayed_work(work); + hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); + tasha = hpf_work->tasha; + codec = tasha->codec; + hpf_cut_off_freq = hpf_work->hpf_cut_off_freq; + + dec_cfg_reg = WCD9335_CDC_TX0_TX_PATH_CFG0 + 16 * hpf_work->decimator; + + dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", + __func__, hpf_work->decimator, hpf_cut_off_freq); + + amic_n = tasha_codec_find_amic_input(codec, hpf_work->decimator); + if (amic_n) { + amic_reg = WCD9335_ANA_AMIC1 + amic_n - 1; + tasha_codec_set_tx_hold(codec, amic_reg, false); + } + tasha_codec_vote_max_bw(codec, true); + snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + tasha_codec_vote_max_bw(codec, false); +} + +static void tasha_tx_mute_update_callback(struct work_struct *work) +{ + struct tx_mute_work *tx_mute_dwork; + struct tasha_priv *tasha; + struct delayed_work *delayed_work; + struct snd_soc_codec *codec; + u16 tx_vol_ctl_reg, hpf_gate_reg; + + delayed_work = to_delayed_work(work); + tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); + tasha = tx_mute_dwork->tasha; + codec = tasha->codec; + + tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL + + 16 * tx_mute_dwork->decimator; + hpf_gate_reg = WCD9335_CDC_TX0_TX_PATH_SEC2 + + 16 * tx_mute_dwork->decimator; + snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x01); + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); +} + +static int tasha_codec_enable_dec(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + unsigned int decimator; + char *dec_adc_mux_name = NULL; + char *widget_name = NULL; + char *wname; + int ret = 0, amic_n; + u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg; + u16 tx_gain_ctl_reg; + char *dec; + u8 hpf_cut_off_freq; + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s %d\n", __func__, event); + + widget_name = kstrndup(w->name, 15, GFP_KERNEL); + if (!widget_name) + return -ENOMEM; + + wname = widget_name; + dec_adc_mux_name = strsep(&widget_name, " "); + if (!dec_adc_mux_name) { + dev_err(codec->dev, "%s: Invalid decimator = %s\n", + __func__, w->name); + ret = -EINVAL; + goto out; + } + dec_adc_mux_name = widget_name; + + dec = strpbrk(dec_adc_mux_name, "012345678"); + if (!dec) { + dev_err(codec->dev, "%s: decimator index not found\n", + __func__); + ret = -EINVAL; + goto out; + } + + ret = kstrtouint(dec, 10, &decimator); + if (ret < 0) { + dev_err(codec->dev, "%s: Invalid decimator = %s\n", + __func__, wname); + ret = -EINVAL; + goto out; + } + + dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__, + w->name, decimator); + + tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL + 16 * decimator; + hpf_gate_reg = WCD9335_CDC_TX0_TX_PATH_SEC2 + 16 * decimator; + dec_cfg_reg = WCD9335_CDC_TX0_TX_PATH_CFG0 + 16 * decimator; + tx_gain_ctl_reg = WCD9335_CDC_TX0_TX_VOL_CTL + 16 * decimator; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + amic_n = tasha_codec_find_amic_input(codec, decimator); + if (amic_n) + pwr_level_reg = tasha_codec_get_amic_pwlvl_reg(codec, + amic_n); + + if (pwr_level_reg) { + switch ((snd_soc_read(codec, pwr_level_reg) & + WCD9335_AMIC_PWR_LVL_MASK) >> + WCD9335_AMIC_PWR_LVL_SHIFT) { + case WCD9335_AMIC_PWR_LEVEL_LP: + snd_soc_update_bits(codec, dec_cfg_reg, + WCD9335_DEC_PWR_LVL_MASK, + WCD9335_DEC_PWR_LVL_LP); + break; + + case WCD9335_AMIC_PWR_LEVEL_HP: + snd_soc_update_bits(codec, dec_cfg_reg, + WCD9335_DEC_PWR_LVL_MASK, + WCD9335_DEC_PWR_LVL_HP); + break; + case WCD9335_AMIC_PWR_LEVEL_DEFAULT: + default: + snd_soc_update_bits(codec, dec_cfg_reg, + WCD9335_DEC_PWR_LVL_MASK, + WCD9335_DEC_PWR_LVL_DF); + break; + } + } + hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) & + TX_HPF_CUT_OFF_FREQ_MASK) >> 5; + tasha->tx_hpf_work[decimator].hpf_cut_off_freq = + hpf_cut_off_freq; + + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) + snd_soc_update_bits(codec, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + CF_MIN_3DB_150HZ << 5); + /* Enable TX PGA Mute */ + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00); + + if (decimator == 0) { + snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x83); + snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0xA3); + snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x83); + snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x03); + } + /* schedule work queue to Remove Mute */ + schedule_delayed_work(&tasha->tx_mute_dwork[decimator].dwork, + msecs_to_jiffies(tx_unmute_delay)); + if (tasha->tx_hpf_work[decimator].hpf_cut_off_freq != + CF_MIN_3DB_150HZ) + schedule_delayed_work( + &tasha->tx_hpf_work[decimator].dwork, + msecs_to_jiffies(300)); + /* apply gain after decimator is enabled */ + snd_soc_write(codec, tx_gain_ctl_reg, + snd_soc_read(codec, tx_gain_ctl_reg)); + break; + case SND_SOC_DAPM_PRE_PMD: + hpf_cut_off_freq = + tasha->tx_hpf_work[decimator].hpf_cut_off_freq; + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + if (cancel_delayed_work_sync( + &tasha->tx_hpf_work[decimator].dwork)) { + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { + tasha_codec_vote_max_bw(codec, true); + snd_soc_update_bits(codec, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + tasha_codec_vote_max_bw(codec, false); + } + } + cancel_delayed_work_sync( + &tasha->tx_mute_dwork[decimator].dwork); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); + break; + }; +out: + kfree(wname); + return ret; +} + +static u32 tasha_get_dmic_sample_rate(struct snd_soc_codec *codec, + unsigned int dmic, struct wcd9xxx_pdata *pdata) +{ + u8 tx_stream_fs; + u8 adc_mux_index = 0, adc_mux_sel = 0; + bool dec_found = false; + u16 adc_mux_ctl_reg, tx_fs_reg; + u32 dmic_fs; + + while (dec_found == 0 && adc_mux_index < WCD9335_MAX_VALID_ADC_MUX) { + if (adc_mux_index < 4) { + adc_mux_ctl_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + + (adc_mux_index * 2); + adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) & + 0x78) >> 3) - 1; + } else if (adc_mux_index < 9) { + adc_mux_ctl_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + + ((adc_mux_index - 4) * 1); + adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) & + 0x38) >> 3) - 1; + } else if (adc_mux_index == 9) { + ++adc_mux_index; + continue; + } + if (adc_mux_sel == dmic) + dec_found = true; + else + ++adc_mux_index; + } + + if (dec_found == true && adc_mux_index <= 8) { + tx_fs_reg = WCD9335_CDC_TX0_TX_PATH_CTL + (16 * adc_mux_index); + tx_stream_fs = snd_soc_read(codec, tx_fs_reg) & 0x0F; + dmic_fs = tx_stream_fs <= 4 ? WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ : + WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ; + + /* + * Check for ECPP path selection and DEC1 not connected to + * any other audio path to apply ECPP DMIC sample rate + */ + if ((adc_mux_index == 1) && + ((snd_soc_read(codec, WCD9335_CPE_SS_US_EC_MUX_CFG) + & 0x0F) == 0x0A) && + ((snd_soc_read(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0) + & 0x0C) == 0x00)) { + dmic_fs = pdata->ecpp_dmic_sample_rate; + } + } else { + dmic_fs = pdata->dmic_sample_rate; + } + + return dmic_fs; +} + +static u8 tasha_get_dmic_clk_val(struct snd_soc_codec *codec, + u32 mclk_rate, u32 dmic_clk_rate) +{ + u32 div_factor; + u8 dmic_ctl_val; + + dev_dbg(codec->dev, + "%s: mclk_rate = %d, dmic_sample_rate = %d\n", + __func__, mclk_rate, dmic_clk_rate); + + /* Default value to return in case of error */ + if (mclk_rate == TASHA_MCLK_CLK_9P6MHZ) + dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2; + else + dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3; + + if (dmic_clk_rate == 0) { + dev_err(codec->dev, + "%s: dmic_sample_rate cannot be 0\n", + __func__); + goto done; + } + + div_factor = mclk_rate / dmic_clk_rate; + switch (div_factor) { + case 2: + dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2; + break; + case 3: + dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3; + break; + case 4: + dmic_ctl_val = WCD9335_DMIC_CLK_DIV_4; + break; + case 6: + dmic_ctl_val = WCD9335_DMIC_CLK_DIV_6; + break; + case 8: + dmic_ctl_val = WCD9335_DMIC_CLK_DIV_8; + break; + case 16: + dmic_ctl_val = WCD9335_DMIC_CLK_DIV_16; + break; + default: + dev_err(codec->dev, + "%s: Invalid div_factor %u, clk_rate(%u), dmic_rate(%u)\n", + __func__, div_factor, mclk_rate, dmic_clk_rate); + break; + } + +done: + return dmic_ctl_val; +} + +static int tasha_codec_enable_adc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s: event:%d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + tasha_codec_set_tx_hold(codec, w->reg, true); + break; + default: + break; + } + + return 0; +} + +static int tasha_codec_enable_dmic(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + u8 dmic_clk_en = 0x01; + u16 dmic_clk_reg; + s32 *dmic_clk_cnt; + u8 dmic_rate_val, dmic_rate_shift = 1; + unsigned int dmic; + u32 dmic_sample_rate; + int ret; + char *wname; + + wname = strpbrk(w->name, "012345"); + if (!wname) { + dev_err(codec->dev, "%s: widget not found\n", __func__); + return -EINVAL; + } + + ret = kstrtouint(wname, 10, &dmic); + if (ret < 0) { + dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n", + __func__); + return -EINVAL; + } + + switch (dmic) { + case 0: + case 1: + dmic_clk_cnt = &(tasha->dmic_0_1_clk_cnt); + dmic_clk_reg = WCD9335_CPE_SS_DMIC0_CTL; + break; + case 2: + case 3: + dmic_clk_cnt = &(tasha->dmic_2_3_clk_cnt); + dmic_clk_reg = WCD9335_CPE_SS_DMIC1_CTL; + break; + case 4: + case 5: + dmic_clk_cnt = &(tasha->dmic_4_5_clk_cnt); + dmic_clk_reg = WCD9335_CPE_SS_DMIC2_CTL; + break; + default: + dev_err(codec->dev, "%s: Invalid DMIC Selection\n", + __func__); + return -EINVAL; + }; + dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", + __func__, event, dmic, *dmic_clk_cnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + dmic_sample_rate = tasha_get_dmic_sample_rate(codec, dmic, + pdata); + dmic_rate_val = + tasha_get_dmic_clk_val(codec, + pdata->mclk_rate, + dmic_sample_rate); + + (*dmic_clk_cnt)++; + if (*dmic_clk_cnt == 1) { + snd_soc_update_bits(codec, dmic_clk_reg, + 0x07 << dmic_rate_shift, + dmic_rate_val << dmic_rate_shift); + snd_soc_update_bits(codec, dmic_clk_reg, + dmic_clk_en, dmic_clk_en); + } + + break; + case SND_SOC_DAPM_POST_PMD: + dmic_rate_val = + tasha_get_dmic_clk_val(codec, + pdata->mclk_rate, + pdata->mad_dmic_sample_rate); + (*dmic_clk_cnt)--; + if (*dmic_clk_cnt == 0) { + snd_soc_update_bits(codec, dmic_clk_reg, + dmic_clk_en, 0); + snd_soc_update_bits(codec, dmic_clk_reg, + 0x07 << dmic_rate_shift, + dmic_rate_val << dmic_rate_shift); + } + break; + }; + + return 0; +} + +static int __tasha_codec_enable_micbias(struct snd_soc_dapm_widget *w, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int micb_num; + + dev_dbg(codec->dev, "%s: wname: %s, event: %d\n", + __func__, w->name, event); + + if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) + micb_num = MIC_BIAS_1; + else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2"))) + micb_num = MIC_BIAS_2; + else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3"))) + micb_num = MIC_BIAS_3; + else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4"))) + micb_num = MIC_BIAS_4; + else + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* + * MIC BIAS can also be requested by MBHC, + * so use ref count to handle micbias pullup + * and enable requests + */ + tasha_micbias_control(codec, micb_num, MICB_ENABLE, true); + break; + case SND_SOC_DAPM_POST_PMU: + /* wait for cnp time */ + usleep_range(1000, 1100); + break; + case SND_SOC_DAPM_POST_PMD: + tasha_micbias_control(codec, micb_num, MICB_DISABLE, true); + break; + }; + + return 0; +} + +static int tasha_codec_ldo_h_control(struct snd_soc_dapm_widget *w, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + tasha->ldo_h_users++; + + if (tasha->ldo_h_users == 1) + snd_soc_update_bits(codec, WCD9335_LDOH_MODE, + 0x80, 0x80); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + tasha->ldo_h_users--; + + if (tasha->ldo_h_users < 0) + tasha->ldo_h_users = 0; + + if (tasha->ldo_h_users == 0) + snd_soc_update_bits(codec, WCD9335_LDOH_MODE, + 0x80, 0x00); + } + + return 0; +} + +static int tasha_codec_force_enable_ldo_h(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd_resmgr_enable_master_bias(tasha->resmgr); + tasha_codec_ldo_h_control(w, event); + break; + case SND_SOC_DAPM_POST_PMD: + tasha_codec_ldo_h_control(w, event); + wcd_resmgr_disable_master_bias(tasha->resmgr); + break; + } + + return 0; +} + +static int tasha_codec_force_enable_micbias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + int ret = 0; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd_resmgr_enable_master_bias(tasha->resmgr); + tasha_cdc_mclk_enable(codec, true, true); + ret = __tasha_codec_enable_micbias(w, SND_SOC_DAPM_PRE_PMU); + /* Wait for 1ms for better cnp */ + usleep_range(1000, 1100); + tasha_cdc_mclk_enable(codec, false, true); + break; + case SND_SOC_DAPM_POST_PMD: + ret = __tasha_codec_enable_micbias(w, SND_SOC_DAPM_POST_PMD); + wcd_resmgr_disable_master_bias(tasha->resmgr); + break; + } + + return ret; +} + +static int tasha_codec_enable_micbias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + return __tasha_codec_enable_micbias(w, event); +} + +static int tasha_codec_enable_standalone_ldo_h(struct snd_soc_codec *codec, + bool enable) +{ + int rc; + + if (enable) + rc = snd_soc_dapm_force_enable_pin( + snd_soc_codec_get_dapm(codec), + DAPM_LDO_H_STANDALONE); + else + rc = snd_soc_dapm_disable_pin( + snd_soc_codec_get_dapm(codec), + DAPM_LDO_H_STANDALONE); + + if (!rc) + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + else + dev_err(codec->dev, "%s: ldo_h force %s pin failed\n", + __func__, (enable ? "enable" : "disable")); + + return rc; +} + +/* + * tasha_codec_enable_standalone_micbias - enable micbias standalone + * @codec: pointer to codec instance + * @micb_num: number of micbias to be enabled + * @enable: true to enable micbias or false to disable + * + * This function is used to enable micbias (1, 2, 3 or 4) during + * standalone independent of whether TX use-case is running or not + * + * Return: error code in case of failure or 0 for success + */ +int tasha_codec_enable_standalone_micbias(struct snd_soc_codec *codec, + int micb_num, + bool enable) +{ + const char * const micb_names[] = { + DAPM_MICBIAS1_STANDALONE, DAPM_MICBIAS2_STANDALONE, + DAPM_MICBIAS3_STANDALONE, DAPM_MICBIAS4_STANDALONE + }; + int micb_index = micb_num - 1; + int rc; + + if (!codec) { + pr_err("%s: Codec memory is NULL\n", __func__); + return -EINVAL; + } + + if ((micb_index < 0) || (micb_index > TASHA_MAX_MICBIAS - 1)) { + dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n", + __func__, micb_index); + return -EINVAL; + } + + if (enable) + rc = snd_soc_dapm_force_enable_pin( + snd_soc_codec_get_dapm(codec), + micb_names[micb_index]); + else + rc = snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(codec), + micb_names[micb_index]); + + if (!rc) + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + else + dev_err(codec->dev, "%s: micbias%d force %s pin failed\n", + __func__, micb_num, (enable ? "enable" : "disable")); + + return rc; +} +EXPORT_SYMBOL(tasha_codec_enable_standalone_micbias); + +static const char *const tasha_anc_func_text[] = {"OFF", "ON"}; +static const struct soc_enum tasha_anc_func_enum = + SOC_ENUM_SINGLE_EXT(2, tasha_anc_func_text); + +static const char *const tasha_clkmode_text[] = {"EXTERNAL", "INTERNAL"}; +static SOC_ENUM_SINGLE_EXT_DECL(tasha_clkmode_enum, tasha_clkmode_text); + +/* Cutoff frequency for high pass filter */ +static const char * const cf_text[] = { + "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ" +}; + +static const char * const rx_cf_text[] = { + "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ", + "CF_NEG_3DB_0P48HZ" +}; + +static const struct soc_enum cf_dec0_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX0_TX_PATH_CFG0, 5, 3, cf_text); + +static const struct soc_enum cf_dec1_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX1_TX_PATH_CFG0, 5, 3, cf_text); + +static const struct soc_enum cf_dec2_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX2_TX_PATH_CFG0, 5, 3, cf_text); + +static const struct soc_enum cf_dec3_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX3_TX_PATH_CFG0, 5, 3, cf_text); + +static const struct soc_enum cf_dec4_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX4_TX_PATH_CFG0, 5, 3, cf_text); + +static const struct soc_enum cf_dec5_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX5_TX_PATH_CFG0, 5, 3, cf_text); + +static const struct soc_enum cf_dec6_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX6_TX_PATH_CFG0, 5, 3, cf_text); + +static const struct soc_enum cf_dec7_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX7_TX_PATH_CFG0, 5, 3, cf_text); + +static const struct soc_enum cf_dec8_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX8_TX_PATH_CFG0, 5, 3, cf_text); + +static const struct soc_enum cf_int0_1_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CFG2, 0, 4, rx_cf_text); + +static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 2, + rx_cf_text); + +static const struct soc_enum cf_int1_1_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CFG2, 0, 4, rx_cf_text); + +static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 2, + rx_cf_text); + +static const struct soc_enum cf_int2_1_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CFG2, 0, 4, rx_cf_text); + +static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 2, + rx_cf_text); + +static const struct soc_enum cf_int3_1_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CFG2, 0, 4, rx_cf_text); + +static SOC_ENUM_SINGLE_DECL(cf_int3_2_enum, WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 2, + rx_cf_text); + +static const struct soc_enum cf_int4_1_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CFG2, 0, 4, rx_cf_text); + +static SOC_ENUM_SINGLE_DECL(cf_int4_2_enum, WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 2, + rx_cf_text); + +static const struct soc_enum cf_int5_1_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CFG2, 0, 4, rx_cf_text); + +static SOC_ENUM_SINGLE_DECL(cf_int5_2_enum, WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 2, + rx_cf_text); + +static const struct soc_enum cf_int6_1_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CFG2, 0, 4, rx_cf_text); + +static SOC_ENUM_SINGLE_DECL(cf_int6_2_enum, WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 2, + rx_cf_text); + +static const struct soc_enum cf_int7_1_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CFG2, 0, 4, rx_cf_text); + +static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 2, + rx_cf_text); + +static const struct soc_enum cf_int8_1_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CFG2, 0, 4, rx_cf_text); + +static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 2, + rx_cf_text); + +static const struct snd_soc_dapm_route audio_i2s_map[] = { + {"SLIM RX0 MUX", NULL, "RX_I2S_CTL"}, + {"SLIM RX1 MUX", NULL, "RX_I2S_CTL"}, + {"SLIM RX2 MUX", NULL, "RX_I2S_CTL"}, + {"SLIM RX3 MUX", NULL, "RX_I2S_CTL"}, + + {"SLIM TX6 MUX", NULL, "TX_I2S_CTL"}, + {"SLIM TX7 MUX", NULL, "TX_I2S_CTL"}, + {"SLIM TX8 MUX", NULL, "TX_I2S_CTL"}, + {"SLIM TX11 MUX", NULL, "TX_I2S_CTL"}, +}; + +static const struct snd_soc_dapm_route audio_map[] = { + + /* MAD */ + {"MAD_SEL MUX", "SPE", "MAD_CPE_INPUT"}, + {"MAD_SEL MUX", "MSM", "MADINPUT"}, + {"MADONOFF", "Switch", "MAD_SEL MUX"}, + {"MAD_BROADCAST", "Switch", "MAD_SEL MUX"}, + {"TX13 INP MUX", "CPE_TX_PP", "MADONOFF"}, + + /* CPE HW MAD bypass */ + {"CPE IN Mixer", "MAD_BYPASS", "SLIM TX1 MUX"}, + + {"AIF4_MAD Mixer", "SLIM TX1", "CPE IN Mixer"}, + {"AIF4_MAD Mixer", "SLIM TX12", "MADONOFF"}, + {"AIF4_MAD Mixer", "SLIM TX13", "TX13 INP MUX"}, + {"AIF4 MAD", NULL, "AIF4_MAD Mixer"}, + {"AIF4 MAD", NULL, "AIF4"}, + + {"EC BUF MUX INP", "DEC1", "ADC MUX1"}, + {"AIF5 CPE", NULL, "EC BUF MUX INP"}, + + /* SLIMBUS Connections */ + {"AIF1 CAP", NULL, "AIF1_CAP Mixer"}, + {"AIF2 CAP", NULL, "AIF2_CAP Mixer"}, + {"AIF3 CAP", NULL, "AIF3_CAP Mixer"}, + + /* VI Feedback */ + {"AIF4_VI Mixer", "SPKR_VI_1", "VIINPUT"}, + {"AIF4_VI Mixer", "SPKR_VI_2", "VIINPUT"}, + {"AIF4 VI", NULL, "AIF4_VI Mixer"}, + + /* SLIM_MIXER("AIF1_CAP Mixer"),*/ + {"AIF1_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"}, + {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"}, + {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"}, + {"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"}, + {"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"}, + {"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"}, + {"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"}, + {"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"}, + {"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"}, + {"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"}, + {"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"}, + {"AIF1_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"}, + {"AIF1_CAP Mixer", "SLIM TX13", "TX13 INP MUX"}, + /* SLIM_MIXER("AIF2_CAP Mixer"),*/ + {"AIF2_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"}, + {"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"}, + {"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"}, + {"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"}, + {"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"}, + {"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"}, + {"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"}, + {"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"}, + {"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"}, + {"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"}, + {"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"}, + {"AIF2_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"}, + {"AIF2_CAP Mixer", "SLIM TX13", "TX13 INP MUX"}, + /* SLIM_MIXER("AIF3_CAP Mixer"),*/ + {"AIF3_CAP Mixer", "SLIM TX0", "SLIM TX0 MUX"}, + {"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1 MUX"}, + {"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2 MUX"}, + {"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3 MUX"}, + {"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4 MUX"}, + {"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5 MUX"}, + {"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6 MUX"}, + {"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7 MUX"}, + {"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8 MUX"}, + {"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9 MUX"}, + {"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10 MUX"}, + {"AIF3_CAP Mixer", "SLIM TX11", "SLIM TX11 MUX"}, + {"AIF3_CAP Mixer", "SLIM TX13", "TX13 INP MUX"}, + + {"SLIM TX0 MUX", "DEC0", "ADC MUX0"}, + {"SLIM TX0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"}, + {"SLIM TX0 MUX", "DEC0_192", "ADC US MUX0"}, + + {"SLIM TX1 MUX", "DEC1", "ADC MUX1"}, + {"SLIM TX1 MUX", "RX_MIX_TX1", "RX MIX TX1 MUX"}, + {"SLIM TX1 MUX", "DEC1_192", "ADC US MUX1"}, + + {"SLIM TX2 MUX", "DEC2", "ADC MUX2"}, + {"SLIM TX2 MUX", "RX_MIX_TX2", "RX MIX TX2 MUX"}, + {"SLIM TX2 MUX", "DEC2_192", "ADC US MUX2"}, + + {"SLIM TX3 MUX", "DEC3", "ADC MUX3"}, + {"SLIM TX3 MUX", "RX_MIX_TX3", "RX MIX TX3 MUX"}, + {"SLIM TX3 MUX", "DEC3_192", "ADC US MUX3"}, + + {"SLIM TX4 MUX", "DEC4", "ADC MUX4"}, + {"SLIM TX4 MUX", "RX_MIX_TX4", "RX MIX TX4 MUX"}, + {"SLIM TX4 MUX", "DEC4_192", "ADC US MUX4"}, + + {"SLIM TX5 MUX", "DEC5", "ADC MUX5"}, + {"SLIM TX5 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"}, + {"SLIM TX5 MUX", "DEC5_192", "ADC US MUX5"}, + + {"SLIM TX6 MUX", "DEC6", "ADC MUX6"}, + {"SLIM TX6 MUX", "RX_MIX_TX6", "RX MIX TX6 MUX"}, + {"SLIM TX6 MUX", "DEC6_192", "ADC US MUX6"}, + + {"SLIM TX7 MUX", "DEC7", "ADC MUX7"}, + {"SLIM TX7 MUX", "RX_MIX_TX7", "RX MIX TX7 MUX"}, + {"SLIM TX7 MUX", "DEC7_192", "ADC US MUX7"}, + + {"SLIM TX8 MUX", "DEC8", "ADC MUX8"}, + {"SLIM TX8 MUX", "RX_MIX_TX8", "RX MIX TX8 MUX"}, + {"SLIM TX8 MUX", "DEC8_192", "ADC US MUX8"}, + + {"SLIM TX9 MUX", "DEC7", "ADC MUX7"}, + {"SLIM TX9 MUX", "DEC7_192", "ADC US MUX7"}, + {"SLIM TX10 MUX", "DEC6", "ADC MUX6"}, + {"SLIM TX10 MUX", "DEC6_192", "ADC US MUX6"}, + + {"SLIM TX11 MUX", "DEC_0_5", "SLIM TX11 INP1 MUX"}, + {"SLIM TX11 MUX", "DEC_9_12", "SLIM TX11 INP1 MUX"}, + {"SLIM TX11 INP1 MUX", "DEC0", "ADC MUX0"}, + {"SLIM TX11 INP1 MUX", "DEC1", "ADC MUX1"}, + {"SLIM TX11 INP1 MUX", "DEC2", "ADC MUX2"}, + {"SLIM TX11 INP1 MUX", "DEC3", "ADC MUX3"}, + {"SLIM TX11 INP1 MUX", "DEC4", "ADC MUX4"}, + {"SLIM TX11 INP1 MUX", "DEC5", "ADC MUX5"}, + {"SLIM TX11 INP1 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"}, + + {"TX13 INP MUX", "MAD_BRDCST", "MAD_BROADCAST"}, + {"TX13 INP MUX", "CDC_DEC_5", "SLIM TX13 MUX"}, + {"SLIM TX13 MUX", "DEC5", "ADC MUX5"}, + + {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX5", "RX INT5 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX6", "RX INT6 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"}, + {"RX MIX TX0 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"}, + {"RX MIX TX0 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"}, + {"RX MIX TX0 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"}, + + {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX5", "RX INT5 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX6", "RX INT6 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"}, + {"RX MIX TX1 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"}, + {"RX MIX TX1 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"}, + {"RX MIX TX1 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"}, + + {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX5", "RX INT5 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX6", "RX INT6 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"}, + {"RX MIX TX2 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"}, + {"RX MIX TX2 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"}, + {"RX MIX TX2 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"}, + + {"RX MIX TX3 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX5", "RX INT5 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX6", "RX INT6 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"}, + {"RX MIX TX3 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"}, + {"RX MIX TX3 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"}, + {"RX MIX TX3 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"}, + + {"RX MIX TX4 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX5", "RX INT5 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX6", "RX INT6 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"}, + {"RX MIX TX4 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"}, + {"RX MIX TX4 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"}, + {"RX MIX TX4 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"}, + + {"RX MIX TX5 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX5", "RX INT5 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX6", "RX INT6 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"}, + {"RX MIX TX5 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"}, + {"RX MIX TX5 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"}, + {"RX MIX TX5 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"}, + + {"RX MIX TX6 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX5", "RX INT5 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX6", "RX INT6 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"}, + {"RX MIX TX6 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"}, + {"RX MIX TX6 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"}, + {"RX MIX TX6 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"}, + + {"RX MIX TX7 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX5", "RX INT5 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX6", "RX INT6 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"}, + {"RX MIX TX7 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"}, + {"RX MIX TX7 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"}, + {"RX MIX TX7 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"}, + + {"RX MIX TX8 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX5", "RX INT5 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX6", "RX INT6 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX_VBAT5", "RX INT5 VBAT"}, + {"RX MIX TX8 MUX", "RX_MIX_VBAT6", "RX INT6 VBAT"}, + {"RX MIX TX8 MUX", "RX_MIX_VBAT7", "RX INT7 VBAT"}, + {"RX MIX TX8 MUX", "RX_MIX_VBAT8", "RX INT8 VBAT"}, + + {"ADC US MUX0", "US_Switch", "ADC MUX0"}, + {"ADC US MUX1", "US_Switch", "ADC MUX1"}, + {"ADC US MUX2", "US_Switch", "ADC MUX2"}, + {"ADC US MUX3", "US_Switch", "ADC MUX3"}, + {"ADC US MUX4", "US_Switch", "ADC MUX4"}, + {"ADC US MUX5", "US_Switch", "ADC MUX5"}, + {"ADC US MUX6", "US_Switch", "ADC MUX6"}, + {"ADC US MUX7", "US_Switch", "ADC MUX7"}, + {"ADC US MUX8", "US_Switch", "ADC MUX8"}, + {"ADC MUX0", "DMIC", "DMIC MUX0"}, + {"ADC MUX0", "AMIC", "AMIC MUX0"}, + {"ADC MUX1", "DMIC", "DMIC MUX1"}, + {"ADC MUX1", "AMIC", "AMIC MUX1"}, + {"ADC MUX2", "DMIC", "DMIC MUX2"}, + {"ADC MUX2", "AMIC", "AMIC MUX2"}, + {"ADC MUX3", "DMIC", "DMIC MUX3"}, + {"ADC MUX3", "AMIC", "AMIC MUX3"}, + {"ADC MUX4", "DMIC", "DMIC MUX4"}, + {"ADC MUX4", "AMIC", "AMIC MUX4"}, + {"ADC MUX5", "DMIC", "DMIC MUX5"}, + {"ADC MUX5", "AMIC", "AMIC MUX5"}, + {"ADC MUX6", "DMIC", "DMIC MUX6"}, + {"ADC MUX6", "AMIC", "AMIC MUX6"}, + {"ADC MUX7", "DMIC", "DMIC MUX7"}, + {"ADC MUX7", "AMIC", "AMIC MUX7"}, + {"ADC MUX8", "DMIC", "DMIC MUX8"}, + {"ADC MUX8", "AMIC", "AMIC MUX8"}, + {"ADC MUX10", "DMIC", "DMIC MUX10"}, + {"ADC MUX10", "AMIC", "AMIC MUX10"}, + {"ADC MUX11", "DMIC", "DMIC MUX11"}, + {"ADC MUX11", "AMIC", "AMIC MUX11"}, + {"ADC MUX12", "DMIC", "DMIC MUX12"}, + {"ADC MUX12", "AMIC", "AMIC MUX12"}, + {"ADC MUX13", "DMIC", "DMIC MUX13"}, + {"ADC MUX13", "AMIC", "AMIC MUX13"}, + + {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX0", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX0", "ANC_FB_TUNE2", "ADC MUX13"}, + {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX1", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX1", "ANC_FB_TUNE2", "ADC MUX13"}, + {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX2", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX2", "ANC_FB_TUNE2", "ADC MUX13"}, + {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX3", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX3", "ANC_FB_TUNE2", "ADC MUX13"}, + {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX4", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX4", "ANC_FB_TUNE2", "ADC MUX13"}, + {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX5", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX5", "ANC_FB_TUNE2", "ADC MUX13"}, + {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX6", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX6", "ANC_FB_TUNE2", "ADC MUX13"}, + {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX7", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX7", "ANC_FB_TUNE2", "ADC MUX13"}, + {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX8", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX8", "ANC_FB_TUNE2", "ADC MUX13"}, + + {"DMIC MUX0", "DMIC0", "DMIC0"}, + {"DMIC MUX0", "DMIC1", "DMIC1"}, + {"DMIC MUX0", "DMIC2", "DMIC2"}, + {"DMIC MUX0", "DMIC3", "DMIC3"}, + {"DMIC MUX0", "DMIC4", "DMIC4"}, + {"DMIC MUX0", "DMIC5", "DMIC5"}, + {"AMIC MUX0", "ADC1", "ADC1"}, + {"AMIC MUX0", "ADC2", "ADC2"}, + {"AMIC MUX0", "ADC3", "ADC3"}, + {"AMIC MUX0", "ADC4", "ADC4"}, + {"AMIC MUX0", "ADC5", "ADC5"}, + {"AMIC MUX0", "ADC6", "ADC6"}, + + {"DMIC MUX1", "DMIC0", "DMIC0"}, + {"DMIC MUX1", "DMIC1", "DMIC1"}, + {"DMIC MUX1", "DMIC2", "DMIC2"}, + {"DMIC MUX1", "DMIC3", "DMIC3"}, + {"DMIC MUX1", "DMIC4", "DMIC4"}, + {"DMIC MUX1", "DMIC5", "DMIC5"}, + {"AMIC MUX1", "ADC1", "ADC1"}, + {"AMIC MUX1", "ADC2", "ADC2"}, + {"AMIC MUX1", "ADC3", "ADC3"}, + {"AMIC MUX1", "ADC4", "ADC4"}, + {"AMIC MUX1", "ADC5", "ADC5"}, + {"AMIC MUX1", "ADC6", "ADC6"}, + + {"DMIC MUX2", "DMIC0", "DMIC0"}, + {"DMIC MUX2", "DMIC1", "DMIC1"}, + {"DMIC MUX2", "DMIC2", "DMIC2"}, + {"DMIC MUX2", "DMIC3", "DMIC3"}, + {"DMIC MUX2", "DMIC4", "DMIC4"}, + {"DMIC MUX2", "DMIC5", "DMIC5"}, + {"AMIC MUX2", "ADC1", "ADC1"}, + {"AMIC MUX2", "ADC2", "ADC2"}, + {"AMIC MUX2", "ADC3", "ADC3"}, + {"AMIC MUX2", "ADC4", "ADC4"}, + {"AMIC MUX2", "ADC5", "ADC5"}, + {"AMIC MUX2", "ADC6", "ADC6"}, + + {"DMIC MUX3", "DMIC0", "DMIC0"}, + {"DMIC MUX3", "DMIC1", "DMIC1"}, + {"DMIC MUX3", "DMIC2", "DMIC2"}, + {"DMIC MUX3", "DMIC3", "DMIC3"}, + {"DMIC MUX3", "DMIC4", "DMIC4"}, + {"DMIC MUX3", "DMIC5", "DMIC5"}, + {"AMIC MUX3", "ADC1", "ADC1"}, + {"AMIC MUX3", "ADC2", "ADC2"}, + {"AMIC MUX3", "ADC3", "ADC3"}, + {"AMIC MUX3", "ADC4", "ADC4"}, + {"AMIC MUX3", "ADC5", "ADC5"}, + {"AMIC MUX3", "ADC6", "ADC6"}, + + {"DMIC MUX4", "DMIC0", "DMIC0"}, + {"DMIC MUX4", "DMIC1", "DMIC1"}, + {"DMIC MUX4", "DMIC2", "DMIC2"}, + {"DMIC MUX4", "DMIC3", "DMIC3"}, + {"DMIC MUX4", "DMIC4", "DMIC4"}, + {"DMIC MUX4", "DMIC5", "DMIC5"}, + {"AMIC MUX4", "ADC1", "ADC1"}, + {"AMIC MUX4", "ADC2", "ADC2"}, + {"AMIC MUX4", "ADC3", "ADC3"}, + {"AMIC MUX4", "ADC4", "ADC4"}, + {"AMIC MUX4", "ADC5", "ADC5"}, + {"AMIC MUX4", "ADC6", "ADC6"}, + + {"DMIC MUX5", "DMIC0", "DMIC0"}, + {"DMIC MUX5", "DMIC1", "DMIC1"}, + {"DMIC MUX5", "DMIC2", "DMIC2"}, + {"DMIC MUX5", "DMIC3", "DMIC3"}, + {"DMIC MUX5", "DMIC4", "DMIC4"}, + {"DMIC MUX5", "DMIC5", "DMIC5"}, + {"AMIC MUX5", "ADC1", "ADC1"}, + {"AMIC MUX5", "ADC2", "ADC2"}, + {"AMIC MUX5", "ADC3", "ADC3"}, + {"AMIC MUX5", "ADC4", "ADC4"}, + {"AMIC MUX5", "ADC5", "ADC5"}, + {"AMIC MUX5", "ADC6", "ADC6"}, + + {"DMIC MUX6", "DMIC0", "DMIC0"}, + {"DMIC MUX6", "DMIC1", "DMIC1"}, + {"DMIC MUX6", "DMIC2", "DMIC2"}, + {"DMIC MUX6", "DMIC3", "DMIC3"}, + {"DMIC MUX6", "DMIC4", "DMIC4"}, + {"DMIC MUX6", "DMIC5", "DMIC5"}, + {"AMIC MUX6", "ADC1", "ADC1"}, + {"AMIC MUX6", "ADC2", "ADC2"}, + {"AMIC MUX6", "ADC3", "ADC3"}, + {"AMIC MUX6", "ADC4", "ADC4"}, + {"AMIC MUX6", "ADC5", "ADC5"}, + {"AMIC MUX6", "ADC6", "ADC6"}, + + {"DMIC MUX7", "DMIC0", "DMIC0"}, + {"DMIC MUX7", "DMIC1", "DMIC1"}, + {"DMIC MUX7", "DMIC2", "DMIC2"}, + {"DMIC MUX7", "DMIC3", "DMIC3"}, + {"DMIC MUX7", "DMIC4", "DMIC4"}, + {"DMIC MUX7", "DMIC5", "DMIC5"}, + {"AMIC MUX7", "ADC1", "ADC1"}, + {"AMIC MUX7", "ADC2", "ADC2"}, + {"AMIC MUX7", "ADC3", "ADC3"}, + {"AMIC MUX7", "ADC4", "ADC4"}, + {"AMIC MUX7", "ADC5", "ADC5"}, + {"AMIC MUX7", "ADC6", "ADC6"}, + + {"DMIC MUX8", "DMIC0", "DMIC0"}, + {"DMIC MUX8", "DMIC1", "DMIC1"}, + {"DMIC MUX8", "DMIC2", "DMIC2"}, + {"DMIC MUX8", "DMIC3", "DMIC3"}, + {"DMIC MUX8", "DMIC4", "DMIC4"}, + {"DMIC MUX8", "DMIC5", "DMIC5"}, + {"AMIC MUX8", "ADC1", "ADC1"}, + {"AMIC MUX8", "ADC2", "ADC2"}, + {"AMIC MUX8", "ADC3", "ADC3"}, + {"AMIC MUX8", "ADC4", "ADC4"}, + {"AMIC MUX8", "ADC5", "ADC5"}, + {"AMIC MUX8", "ADC6", "ADC6"}, + + {"DMIC MUX10", "DMIC0", "DMIC0"}, + {"DMIC MUX10", "DMIC1", "DMIC1"}, + {"DMIC MUX10", "DMIC2", "DMIC2"}, + {"DMIC MUX10", "DMIC3", "DMIC3"}, + {"DMIC MUX10", "DMIC4", "DMIC4"}, + {"DMIC MUX10", "DMIC5", "DMIC5"}, + {"AMIC MUX10", "ADC1", "ADC1"}, + {"AMIC MUX10", "ADC2", "ADC2"}, + {"AMIC MUX10", "ADC3", "ADC3"}, + {"AMIC MUX10", "ADC4", "ADC4"}, + {"AMIC MUX10", "ADC5", "ADC5"}, + {"AMIC MUX10", "ADC6", "ADC6"}, + + {"DMIC MUX11", "DMIC0", "DMIC0"}, + {"DMIC MUX11", "DMIC1", "DMIC1"}, + {"DMIC MUX11", "DMIC2", "DMIC2"}, + {"DMIC MUX11", "DMIC3", "DMIC3"}, + {"DMIC MUX11", "DMIC4", "DMIC4"}, + {"DMIC MUX11", "DMIC5", "DMIC5"}, + {"AMIC MUX11", "ADC1", "ADC1"}, + {"AMIC MUX11", "ADC2", "ADC2"}, + {"AMIC MUX11", "ADC3", "ADC3"}, + {"AMIC MUX11", "ADC4", "ADC4"}, + {"AMIC MUX11", "ADC5", "ADC5"}, + {"AMIC MUX11", "ADC6", "ADC6"}, + + {"DMIC MUX12", "DMIC0", "DMIC0"}, + {"DMIC MUX12", "DMIC1", "DMIC1"}, + {"DMIC MUX12", "DMIC2", "DMIC2"}, + {"DMIC MUX12", "DMIC3", "DMIC3"}, + {"DMIC MUX12", "DMIC4", "DMIC4"}, + {"DMIC MUX12", "DMIC5", "DMIC5"}, + {"AMIC MUX12", "ADC1", "ADC1"}, + {"AMIC MUX12", "ADC2", "ADC2"}, + {"AMIC MUX12", "ADC3", "ADC3"}, + {"AMIC MUX12", "ADC4", "ADC4"}, + {"AMIC MUX12", "ADC5", "ADC5"}, + {"AMIC MUX12", "ADC6", "ADC6"}, + + {"DMIC MUX13", "DMIC0", "DMIC0"}, + {"DMIC MUX13", "DMIC1", "DMIC1"}, + {"DMIC MUX13", "DMIC2", "DMIC2"}, + {"DMIC MUX13", "DMIC3", "DMIC3"}, + {"DMIC MUX13", "DMIC4", "DMIC4"}, + {"DMIC MUX13", "DMIC5", "DMIC5"}, + {"AMIC MUX13", "ADC1", "ADC1"}, + {"AMIC MUX13", "ADC2", "ADC2"}, + {"AMIC MUX13", "ADC3", "ADC3"}, + {"AMIC MUX13", "ADC4", "ADC4"}, + {"AMIC MUX13", "ADC5", "ADC5"}, + {"AMIC MUX13", "ADC6", "ADC6"}, + /* ADC Connections */ + {"ADC1", NULL, "AMIC1"}, + {"ADC2", NULL, "AMIC2"}, + {"ADC3", NULL, "AMIC3"}, + {"ADC4", NULL, "AMIC4"}, + {"ADC5", NULL, "AMIC5"}, + {"ADC6", NULL, "AMIC6"}, + + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"}, + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"}, + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"}, + {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP0"}, + {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP1"}, + {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP2"}, + {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP0"}, + {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP1"}, + {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP2"}, + {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP0"}, + {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP1"}, + {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP2"}, + {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP0"}, + {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP1"}, + {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP2"}, + {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP0"}, + {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP1"}, + {"RX INT5_1 MIX1", NULL, "RX INT5_1 MIX1 INP2"}, + {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP0"}, + {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP1"}, + {"RX INT6_1 MIX1", NULL, "RX INT6_1 MIX1 INP2"}, + {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP0"}, + {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP1"}, + {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP2"}, + {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP0"}, + {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP1"}, + {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP2"}, + + {"RX INT0 SEC MIX", NULL, "RX INT0_1 MIX1"}, + {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"}, + {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"}, + {"RX INT0 INTERP", NULL, "RX INT0 MIX2"}, + {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 INTERP"}, + {"RX INT0 DAC", NULL, "RX INT0 DEM MUX"}, + {"RX INT0 DAC", NULL, "RX_BIAS"}, + {"EAR PA", NULL, "RX INT0 DAC"}, + {"EAR", NULL, "EAR PA"}, + + {"SPL SRC0 MUX", "SRC_IN_HPHL", "RX INT1_1 MIX1"}, + {"RX INT1 SPLINE MIX", NULL, "RX INT1_1 MIX1"}, + {"RX INT1 SPLINE MIX", "HPHL Switch", "SPL SRC0 MUX"}, + {"RX INT1_1 NATIVE MUX", "ON", "RX INT1_1 MIX1"}, + {"RX INT1 SPLINE MIX", NULL, "RX INT1_1 NATIVE MUX"}, + {"RX INT1_1 NATIVE MUX", NULL, "RX INT1 NATIVE SUPPLY"}, + {"RX INT1 SEC MIX", NULL, "RX INT1 SPLINE MIX"}, + {"RX INT1 MIX2", NULL, "RX INT1 SEC MIX"}, + {"RX INT1 MIX2", NULL, "RX INT1 MIX2 INP"}, + {"RX INT1 INTERP", NULL, "RX INT1 MIX2"}, + {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 INTERP"}, + {"RX INT1 DAC", NULL, "RX INT1 DEM MUX"}, + {"RX INT1 DAC", NULL, "RX_BIAS"}, + {"HPHL PA", NULL, "RX INT1 DAC"}, + {"HPHL", NULL, "HPHL PA"}, + + {"SPL SRC1 MUX", "SRC_IN_HPHR", "RX INT2_1 MIX1"}, + {"RX INT2 SPLINE MIX", NULL, "RX INT2_1 MIX1"}, + {"RX INT2 SPLINE MIX", "HPHR Switch", "SPL SRC1 MUX"}, + {"RX INT2_1 NATIVE MUX", "ON", "RX INT2_1 MIX1"}, + {"RX INT2 SPLINE MIX", NULL, "RX INT2_1 NATIVE MUX"}, + {"RX INT2_1 NATIVE MUX", NULL, "RX INT2 NATIVE SUPPLY"}, + {"RX INT2 SEC MIX", NULL, "RX INT2 SPLINE MIX"}, + {"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"}, + {"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"}, + {"RX INT2 INTERP", NULL, "RX INT2 MIX2"}, + {"RX INT2 DEM MUX", "CLSH_DSM_OUT", "RX INT2 INTERP"}, + {"RX INT2 DAC", NULL, "RX INT2 DEM MUX"}, + {"RX INT2 DAC", NULL, "RX_BIAS"}, + {"HPHR PA", NULL, "RX INT2 DAC"}, + {"HPHR", NULL, "HPHR PA"}, + + {"SPL SRC0 MUX", "SRC_IN_LO1", "RX INT3_1 MIX1"}, + {"RX INT3 SPLINE MIX", NULL, "RX INT3_1 MIX1"}, + {"RX INT3 SPLINE MIX", "LO1 Switch", "SPL SRC0 MUX"}, + {"RX INT3_1 NATIVE MUX", "ON", "RX INT3_1 MIX1"}, + {"RX INT3 SPLINE MIX", NULL, "RX INT3_1 NATIVE MUX"}, + {"RX INT3_1 NATIVE MUX", NULL, "RX INT3 NATIVE SUPPLY"}, + {"RX INT3 SEC MIX", NULL, "RX INT3 SPLINE MIX"}, + {"RX INT3 MIX2", NULL, "RX INT3 SEC MIX"}, + {"RX INT3 MIX2", NULL, "RX INT3 MIX2 INP"}, + {"RX INT3 INTERP", NULL, "RX INT3 MIX2"}, + {"RX INT3 DAC", NULL, "RX INT3 INTERP"}, + {"RX INT3 DAC", NULL, "RX_BIAS"}, + {"LINEOUT1 PA", NULL, "RX INT3 DAC"}, + {"LINEOUT1", NULL, "LINEOUT1 PA"}, + + {"SPL SRC1 MUX", "SRC_IN_LO2", "RX INT4_1 MIX1"}, + {"RX INT4 SPLINE MIX", NULL, "RX INT4_1 MIX1"}, + {"RX INT4 SPLINE MIX", "LO2 Switch", "SPL SRC1 MUX"}, + {"RX INT4_1 NATIVE MUX", "ON", "RX INT4_1 MIX1"}, + {"RX INT4 SPLINE MIX", NULL, "RX INT4_1 NATIVE MUX"}, + {"RX INT4_1 NATIVE MUX", NULL, "RX INT4 NATIVE SUPPLY"}, + {"RX INT4 SEC MIX", NULL, "RX INT4 SPLINE MIX"}, + {"RX INT4 MIX2", NULL, "RX INT4 SEC MIX"}, + {"RX INT4 MIX2", NULL, "RX INT4 MIX2 INP"}, + {"RX INT4 INTERP", NULL, "RX INT4 MIX2"}, + {"RX INT4 DAC", NULL, "RX INT4 INTERP"}, + {"RX INT4 DAC", NULL, "RX_BIAS"}, + {"LINEOUT2 PA", NULL, "RX INT4 DAC"}, + {"LINEOUT2", NULL, "LINEOUT2 PA"}, + + {"SPL SRC2 MUX", "SRC_IN_LO3", "RX INT5_1 MIX1"}, + {"RX INT5 SPLINE MIX", NULL, "RX INT5_1 MIX1"}, + {"RX INT5 SPLINE MIX", "LO3 Switch", "SPL SRC2 MUX"}, + {"RX INT5 SEC MIX", NULL, "RX INT5 SPLINE MIX"}, + {"RX INT5 MIX2", NULL, "RX INT5 SEC MIX"}, + {"RX INT5 INTERP", NULL, "RX INT5 MIX2"}, + + {"RX INT5 VBAT", "LO3 VBAT Enable", "RX INT5 INTERP"}, + {"RX INT5 DAC", NULL, "RX INT5 VBAT"}, + + {"RX INT5 DAC", NULL, "RX INT5 INTERP"}, + {"RX INT5 DAC", NULL, "RX_BIAS"}, + {"LINEOUT3 PA", NULL, "RX INT5 DAC"}, + {"LINEOUT3", NULL, "LINEOUT3 PA"}, + + {"SPL SRC3 MUX", "SRC_IN_LO4", "RX INT6_1 MIX1"}, + {"RX INT6 SPLINE MIX", NULL, "RX INT6_1 MIX1"}, + {"RX INT6 SPLINE MIX", "LO4 Switch", "SPL SRC3 MUX"}, + {"RX INT6 SEC MIX", NULL, "RX INT6 SPLINE MIX"}, + {"RX INT6 MIX2", NULL, "RX INT6 SEC MIX"}, + {"RX INT6 INTERP", NULL, "RX INT6 MIX2"}, + + {"RX INT6 VBAT", "LO4 VBAT Enable", "RX INT6 INTERP"}, + {"RX INT6 DAC", NULL, "RX INT6 VBAT"}, + + {"RX INT6 DAC", NULL, "RX INT6 INTERP"}, + {"RX INT6 DAC", NULL, "RX_BIAS"}, + {"LINEOUT4 PA", NULL, "RX INT6 DAC"}, + {"LINEOUT4", NULL, "LINEOUT4 PA"}, + + {"SPL SRC2 MUX", "SRC_IN_SPKRL", "RX INT7_1 MIX1"}, + {"RX INT7 SPLINE MIX", NULL, "RX INT7_1 MIX1"}, + {"RX INT7 SPLINE MIX", "SPKRL Switch", "SPL SRC2 MUX"}, + {"RX INT7 SEC MIX", NULL, "RX INT7 SPLINE MIX"}, + {"RX INT7 MIX2", NULL, "RX INT7 SEC MIX"}, + {"RX INT7 MIX2", NULL, "RX INT7 MIX2 INP"}, + + {"RX INT7 INTERP", NULL, "RX INT7 MIX2"}, + + {"RX INT7 VBAT", "SPKRL VBAT Enable", "RX INT7 INTERP"}, + {"RX INT7 CHAIN", NULL, "RX INT7 VBAT"}, + + {"RX INT7 CHAIN", NULL, "RX INT7 INTERP"}, + {"RX INT7 CHAIN", NULL, "RX_BIAS"}, + {"SPK1 OUT", NULL, "RX INT7 CHAIN"}, + + {"ANC SPKR PA Enable", "Switch", "RX INT7 CHAIN"}, + {"ANC SPK1 PA", NULL, "ANC SPKR PA Enable"}, + {"SPK1 OUT", NULL, "ANC SPK1 PA"}, + + {"SPL SRC3 MUX", "SRC_IN_SPKRR", "RX INT8_1 MIX1"}, + {"RX INT8 SPLINE MIX", NULL, "RX INT8_1 MIX1"}, + {"RX INT8 SPLINE MIX", "SPKRR Switch", "SPL SRC3 MUX"}, + {"RX INT8 SEC MIX", NULL, "RX INT8 SPLINE MIX"}, + {"RX INT8 INTERP", NULL, "RX INT8 SEC MIX"}, + + {"RX INT8 VBAT", "SPKRR VBAT Enable", "RX INT8 INTERP"}, + {"RX INT8 CHAIN", NULL, "RX INT8 VBAT"}, + + {"RX INT8 CHAIN", NULL, "RX INT8 INTERP"}, + {"RX INT8 CHAIN", NULL, "RX_BIAS"}, + {"SPK2 OUT", NULL, "RX INT8 CHAIN"}, + + {"ANC0 FB MUX", "ANC_IN_EAR", "RX INT0 MIX2"}, + {"ANC0 FB MUX", "ANC_IN_HPHL", "RX INT1 MIX2"}, + {"ANC0 FB MUX", "ANC_IN_LO1", "RX INT3 MIX2"}, + {"ANC0 FB MUX", "ANC_IN_EAR_SPKR", "RX INT7 MIX2"}, + {"ANC1 FB MUX", "ANC_IN_HPHR", "RX INT2 MIX2"}, + {"ANC1 FB MUX", "ANC_IN_LO2", "RX INT4 MIX2"}, + + {"ANC HPHL Enable", "Switch", "ADC MUX10"}, + {"ANC HPHL Enable", "Switch", "ADC MUX11"}, + {"RX INT1 MIX2", NULL, "ANC HPHL Enable"}, + + {"ANC HPHR Enable", "Switch", "ADC MUX12"}, + {"ANC HPHR Enable", "Switch", "ADC MUX13"}, + {"RX INT2 MIX2", NULL, "ANC HPHR Enable"}, + + {"ANC EAR Enable", "Switch", "ADC MUX10"}, + {"ANC EAR Enable", "Switch", "ADC MUX11"}, + {"RX INT0 MIX2", NULL, "ANC EAR Enable"}, + + {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX10"}, + {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX11"}, + {"RX INT7 MIX2", NULL, "ANC OUT EAR SPKR Enable"}, + + {"ANC LINEOUT1 Enable", "Switch", "ADC MUX10"}, + {"ANC LINEOUT1 Enable", "Switch", "ADC MUX11"}, + {"RX INT3 MIX2", NULL, "ANC LINEOUT1 Enable"}, + + {"ANC LINEOUT2 Enable", "Switch", "ADC MUX12"}, + {"ANC LINEOUT2 Enable", "Switch", "ADC MUX13"}, + {"RX INT4 MIX2", NULL, "ANC LINEOUT2 Enable"}, + + {"ANC EAR PA", NULL, "RX INT0 DAC"}, + {"ANC EAR", NULL, "ANC EAR PA"}, + {"ANC HPHL PA", NULL, "RX INT1 DAC"}, + {"ANC HPHL", NULL, "ANC HPHL PA"}, + {"ANC HPHR PA", NULL, "RX INT2 DAC"}, + {"ANC HPHR", NULL, "ANC HPHR PA"}, + {"ANC LINEOUT1 PA", NULL, "RX INT3 DAC"}, + {"ANC LINEOUT1", NULL, "ANC LINEOUT1 PA"}, + {"ANC LINEOUT2 PA", NULL, "RX INT4 DAC"}, + {"ANC LINEOUT2", NULL, "ANC LINEOUT2 PA"}, + + /* SLIM_MUX("AIF1_PB", "AIF1 PB"),*/ + {"SLIM RX0 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"}, + /* SLIM_MUX("AIF2_PB", "AIF2 PB"),*/ + {"SLIM RX0 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"}, + /* SLIM_MUX("AIF3_PB", "AIF3 PB"),*/ + {"SLIM RX0 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"}, + /* SLIM_MUX("AIF4_PB", "AIF4 PB"),*/ + {"SLIM RX0 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX1 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX2 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX3 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX4 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX5 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX6 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX7 MUX", "AIF4_PB", "AIF4 PB"}, + + /* SLIM_MUX("AIF_MIX1_PB", "AIF MIX1 PB"),*/ + {"SLIM RX0 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"}, + {"SLIM RX1 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"}, + {"SLIM RX2 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"}, + {"SLIM RX3 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"}, + {"SLIM RX4 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"}, + {"SLIM RX5 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"}, + {"SLIM RX6 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"}, + {"SLIM RX7 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"}, + + {"SLIM RX0", NULL, "SLIM RX0 MUX"}, + {"SLIM RX1", NULL, "SLIM RX1 MUX"}, + {"SLIM RX2", NULL, "SLIM RX2 MUX"}, + {"SLIM RX3", NULL, "SLIM RX3 MUX"}, + {"SLIM RX4", NULL, "SLIM RX4 MUX"}, + {"SLIM RX5", NULL, "SLIM RX5 MUX"}, + {"SLIM RX6", NULL, "SLIM RX6 MUX"}, + {"SLIM RX7", NULL, "SLIM RX7 MUX"}, + + {"RX INT0_1 MIX1 INP0", "RX0", "SLIM RX0"}, + {"RX INT0_1 MIX1 INP0", "RX1", "SLIM RX1"}, + {"RX INT0_1 MIX1 INP0", "RX2", "SLIM RX2"}, + {"RX INT0_1 MIX1 INP0", "RX3", "SLIM RX3"}, + {"RX INT0_1 MIX1 INP0", "RX4", "SLIM RX4"}, + {"RX INT0_1 MIX1 INP0", "RX5", "SLIM RX5"}, + {"RX INT0_1 MIX1 INP0", "RX6", "SLIM RX6"}, + {"RX INT0_1 MIX1 INP0", "RX7", "SLIM RX7"}, + {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT0_1 MIX1 INP1", "RX0", "SLIM RX0"}, + {"RX INT0_1 MIX1 INP1", "RX1", "SLIM RX1"}, + {"RX INT0_1 MIX1 INP1", "RX2", "SLIM RX2"}, + {"RX INT0_1 MIX1 INP1", "RX3", "SLIM RX3"}, + {"RX INT0_1 MIX1 INP1", "RX4", "SLIM RX4"}, + {"RX INT0_1 MIX1 INP1", "RX5", "SLIM RX5"}, + {"RX INT0_1 MIX1 INP1", "RX6", "SLIM RX6"}, + {"RX INT0_1 MIX1 INP1", "RX7", "SLIM RX7"}, + {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT0_1 MIX1 INP2", "RX0", "SLIM RX0"}, + {"RX INT0_1 MIX1 INP2", "RX1", "SLIM RX1"}, + {"RX INT0_1 MIX1 INP2", "RX2", "SLIM RX2"}, + {"RX INT0_1 MIX1 INP2", "RX3", "SLIM RX3"}, + {"RX INT0_1 MIX1 INP2", "RX4", "SLIM RX4"}, + {"RX INT0_1 MIX1 INP2", "RX5", "SLIM RX5"}, + {"RX INT0_1 MIX1 INP2", "RX6", "SLIM RX6"}, + {"RX INT0_1 MIX1 INP2", "RX7", "SLIM RX7"}, + {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP2", "IIR1", "IIR1"}, + + /* MIXing path INT0 */ + {"RX INT0_2 MUX", "RX0", "SLIM RX0"}, + {"RX INT0_2 MUX", "RX1", "SLIM RX1"}, + {"RX INT0_2 MUX", "RX2", "SLIM RX2"}, + {"RX INT0_2 MUX", "RX3", "SLIM RX3"}, + {"RX INT0_2 MUX", "RX4", "SLIM RX4"}, + {"RX INT0_2 MUX", "RX5", "SLIM RX5"}, + {"RX INT0_2 MUX", "RX6", "SLIM RX6"}, + {"RX INT0_2 MUX", "RX7", "SLIM RX7"}, + {"RX INT0 SEC MIX", NULL, "RX INT0_2 MUX"}, + + /* MIXing path INT1 */ + {"RX INT1_2 MUX", "RX0", "SLIM RX0"}, + {"RX INT1_2 MUX", "RX1", "SLIM RX1"}, + {"RX INT1_2 MUX", "RX2", "SLIM RX2"}, + {"RX INT1_2 MUX", "RX3", "SLIM RX3"}, + {"RX INT1_2 MUX", "RX4", "SLIM RX4"}, + {"RX INT1_2 MUX", "RX5", "SLIM RX5"}, + {"RX INT1_2 MUX", "RX6", "SLIM RX6"}, + {"RX INT1_2 MUX", "RX7", "SLIM RX7"}, + {"RX INT1 SEC MIX", NULL, "RX INT1_2 MUX"}, + + /* MIXing path INT2 */ + {"RX INT2_2 MUX", "RX0", "SLIM RX0"}, + {"RX INT2_2 MUX", "RX1", "SLIM RX1"}, + {"RX INT2_2 MUX", "RX2", "SLIM RX2"}, + {"RX INT2_2 MUX", "RX3", "SLIM RX3"}, + {"RX INT2_2 MUX", "RX4", "SLIM RX4"}, + {"RX INT2_2 MUX", "RX5", "SLIM RX5"}, + {"RX INT2_2 MUX", "RX6", "SLIM RX6"}, + {"RX INT2_2 MUX", "RX7", "SLIM RX7"}, + {"RX INT2 SEC MIX", NULL, "RX INT2_2 MUX"}, + + /* MIXing path INT3 */ + {"RX INT3_2 MUX", "RX0", "SLIM RX0"}, + {"RX INT3_2 MUX", "RX1", "SLIM RX1"}, + {"RX INT3_2 MUX", "RX2", "SLIM RX2"}, + {"RX INT3_2 MUX", "RX3", "SLIM RX3"}, + {"RX INT3_2 MUX", "RX4", "SLIM RX4"}, + {"RX INT3_2 MUX", "RX5", "SLIM RX5"}, + {"RX INT3_2 MUX", "RX6", "SLIM RX6"}, + {"RX INT3_2 MUX", "RX7", "SLIM RX7"}, + {"RX INT3 SEC MIX", NULL, "RX INT3_2 MUX"}, + + /* MIXing path INT4 */ + {"RX INT4_2 MUX", "RX0", "SLIM RX0"}, + {"RX INT4_2 MUX", "RX1", "SLIM RX1"}, + {"RX INT4_2 MUX", "RX2", "SLIM RX2"}, + {"RX INT4_2 MUX", "RX3", "SLIM RX3"}, + {"RX INT4_2 MUX", "RX4", "SLIM RX4"}, + {"RX INT4_2 MUX", "RX5", "SLIM RX5"}, + {"RX INT4_2 MUX", "RX6", "SLIM RX6"}, + {"RX INT4_2 MUX", "RX7", "SLIM RX7"}, + {"RX INT4 SEC MIX", NULL, "RX INT4_2 MUX"}, + + /* MIXing path INT5 */ + {"RX INT5_2 MUX", "RX0", "SLIM RX0"}, + {"RX INT5_2 MUX", "RX1", "SLIM RX1"}, + {"RX INT5_2 MUX", "RX2", "SLIM RX2"}, + {"RX INT5_2 MUX", "RX3", "SLIM RX3"}, + {"RX INT5_2 MUX", "RX4", "SLIM RX4"}, + {"RX INT5_2 MUX", "RX5", "SLIM RX5"}, + {"RX INT5_2 MUX", "RX6", "SLIM RX6"}, + {"RX INT5_2 MUX", "RX7", "SLIM RX7"}, + {"RX INT5 SEC MIX", NULL, "RX INT5_2 MUX"}, + + /* MIXing path INT6 */ + {"RX INT6_2 MUX", "RX0", "SLIM RX0"}, + {"RX INT6_2 MUX", "RX1", "SLIM RX1"}, + {"RX INT6_2 MUX", "RX2", "SLIM RX2"}, + {"RX INT6_2 MUX", "RX3", "SLIM RX3"}, + {"RX INT6_2 MUX", "RX4", "SLIM RX4"}, + {"RX INT6_2 MUX", "RX5", "SLIM RX5"}, + {"RX INT6_2 MUX", "RX6", "SLIM RX6"}, + {"RX INT6_2 MUX", "RX7", "SLIM RX7"}, + {"RX INT6 SEC MIX", NULL, "RX INT6_2 MUX"}, + + /* MIXing path INT7 */ + {"RX INT7_2 MUX", "RX0", "SLIM RX0"}, + {"RX INT7_2 MUX", "RX1", "SLIM RX1"}, + {"RX INT7_2 MUX", "RX2", "SLIM RX2"}, + {"RX INT7_2 MUX", "RX3", "SLIM RX3"}, + {"RX INT7_2 MUX", "RX4", "SLIM RX4"}, + {"RX INT7_2 MUX", "RX5", "SLIM RX5"}, + {"RX INT7_2 MUX", "RX6", "SLIM RX6"}, + {"RX INT7_2 MUX", "RX7", "SLIM RX7"}, + {"RX INT7 SEC MIX", NULL, "RX INT7_2 MUX"}, + + /* MIXing path INT8 */ + {"RX INT8_2 MUX", "RX0", "SLIM RX0"}, + {"RX INT8_2 MUX", "RX1", "SLIM RX1"}, + {"RX INT8_2 MUX", "RX2", "SLIM RX2"}, + {"RX INT8_2 MUX", "RX3", "SLIM RX3"}, + {"RX INT8_2 MUX", "RX4", "SLIM RX4"}, + {"RX INT8_2 MUX", "RX5", "SLIM RX5"}, + {"RX INT8_2 MUX", "RX6", "SLIM RX6"}, + {"RX INT8_2 MUX", "RX7", "SLIM RX7"}, + {"RX INT8 SEC MIX", NULL, "RX INT8_2 MUX"}, + + {"RX INT1_1 MIX1 INP0", "RX0", "SLIM RX0"}, + {"RX INT1_1 MIX1 INP0", "RX1", "SLIM RX1"}, + {"RX INT1_1 MIX1 INP0", "RX2", "SLIM RX2"}, + {"RX INT1_1 MIX1 INP0", "RX3", "SLIM RX3"}, + {"RX INT1_1 MIX1 INP0", "RX4", "SLIM RX4"}, + {"RX INT1_1 MIX1 INP0", "RX5", "SLIM RX5"}, + {"RX INT1_1 MIX1 INP0", "RX6", "SLIM RX6"}, + {"RX INT1_1 MIX1 INP0", "RX7", "SLIM RX7"}, + {"RX INT1_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT1_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT1_1 MIX1 INP1", "RX0", "SLIM RX0"}, + {"RX INT1_1 MIX1 INP1", "RX1", "SLIM RX1"}, + {"RX INT1_1 MIX1 INP1", "RX2", "SLIM RX2"}, + {"RX INT1_1 MIX1 INP1", "RX3", "SLIM RX3"}, + {"RX INT1_1 MIX1 INP1", "RX4", "SLIM RX4"}, + {"RX INT1_1 MIX1 INP1", "RX5", "SLIM RX5"}, + {"RX INT1_1 MIX1 INP1", "RX6", "SLIM RX6"}, + {"RX INT1_1 MIX1 INP1", "RX7", "SLIM RX7"}, + {"RX INT1_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT1_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT1_1 MIX1 INP2", "RX0", "SLIM RX0"}, + {"RX INT1_1 MIX1 INP2", "RX1", "SLIM RX1"}, + {"RX INT1_1 MIX1 INP2", "RX2", "SLIM RX2"}, + {"RX INT1_1 MIX1 INP2", "RX3", "SLIM RX3"}, + {"RX INT1_1 MIX1 INP2", "RX4", "SLIM RX4"}, + {"RX INT1_1 MIX1 INP2", "RX5", "SLIM RX5"}, + {"RX INT1_1 MIX1 INP2", "RX6", "SLIM RX6"}, + {"RX INT1_1 MIX1 INP2", "RX7", "SLIM RX7"}, + {"RX INT1_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT1_1 MIX1 INP2", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP0", "RX0", "SLIM RX0"}, + {"RX INT2_1 MIX1 INP0", "RX1", "SLIM RX1"}, + {"RX INT2_1 MIX1 INP0", "RX2", "SLIM RX2"}, + {"RX INT2_1 MIX1 INP0", "RX3", "SLIM RX3"}, + {"RX INT2_1 MIX1 INP0", "RX4", "SLIM RX4"}, + {"RX INT2_1 MIX1 INP0", "RX5", "SLIM RX5"}, + {"RX INT2_1 MIX1 INP0", "RX6", "SLIM RX6"}, + {"RX INT2_1 MIX1 INP0", "RX7", "SLIM RX7"}, + {"RX INT2_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT2_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP1", "RX0", "SLIM RX0"}, + {"RX INT2_1 MIX1 INP1", "RX1", "SLIM RX1"}, + {"RX INT2_1 MIX1 INP1", "RX2", "SLIM RX2"}, + {"RX INT2_1 MIX1 INP1", "RX3", "SLIM RX3"}, + {"RX INT2_1 MIX1 INP1", "RX4", "SLIM RX4"}, + {"RX INT2_1 MIX1 INP1", "RX5", "SLIM RX5"}, + {"RX INT2_1 MIX1 INP1", "RX6", "SLIM RX6"}, + {"RX INT2_1 MIX1 INP1", "RX7", "SLIM RX7"}, + {"RX INT2_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT2_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP2", "RX0", "SLIM RX0"}, + {"RX INT2_1 MIX1 INP2", "RX1", "SLIM RX1"}, + {"RX INT2_1 MIX1 INP2", "RX2", "SLIM RX2"}, + {"RX INT2_1 MIX1 INP2", "RX3", "SLIM RX3"}, + {"RX INT2_1 MIX1 INP2", "RX4", "SLIM RX4"}, + {"RX INT2_1 MIX1 INP2", "RX5", "SLIM RX5"}, + {"RX INT2_1 MIX1 INP2", "RX6", "SLIM RX6"}, + {"RX INT2_1 MIX1 INP2", "RX7", "SLIM RX7"}, + {"RX INT2_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT2_1 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX INT3_1 MIX1 INP0", "RX0", "SLIM RX0"}, + {"RX INT3_1 MIX1 INP0", "RX1", "SLIM RX1"}, + {"RX INT3_1 MIX1 INP0", "RX2", "SLIM RX2"}, + {"RX INT3_1 MIX1 INP0", "RX3", "SLIM RX3"}, + {"RX INT3_1 MIX1 INP0", "RX4", "SLIM RX4"}, + {"RX INT3_1 MIX1 INP0", "RX5", "SLIM RX5"}, + {"RX INT3_1 MIX1 INP0", "RX6", "SLIM RX6"}, + {"RX INT3_1 MIX1 INP0", "RX7", "SLIM RX7"}, + {"RX INT3_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT3_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT3_1 MIX1 INP1", "RX0", "SLIM RX0"}, + {"RX INT3_1 MIX1 INP1", "RX1", "SLIM RX1"}, + {"RX INT3_1 MIX1 INP1", "RX2", "SLIM RX2"}, + {"RX INT3_1 MIX1 INP1", "RX3", "SLIM RX3"}, + {"RX INT3_1 MIX1 INP1", "RX4", "SLIM RX4"}, + {"RX INT3_1 MIX1 INP1", "RX5", "SLIM RX5"}, + {"RX INT3_1 MIX1 INP1", "RX6", "SLIM RX6"}, + {"RX INT3_1 MIX1 INP1", "RX7", "SLIM RX7"}, + {"RX INT3_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT3_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT3_1 MIX1 INP2", "RX0", "SLIM RX0"}, + {"RX INT3_1 MIX1 INP2", "RX1", "SLIM RX1"}, + {"RX INT3_1 MIX1 INP2", "RX2", "SLIM RX2"}, + {"RX INT3_1 MIX1 INP2", "RX3", "SLIM RX3"}, + {"RX INT3_1 MIX1 INP2", "RX4", "SLIM RX4"}, + {"RX INT3_1 MIX1 INP2", "RX5", "SLIM RX5"}, + {"RX INT3_1 MIX1 INP2", "RX6", "SLIM RX6"}, + {"RX INT3_1 MIX1 INP2", "RX7", "SLIM RX7"}, + {"RX INT3_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT3_1 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX INT4_1 MIX1 INP0", "RX0", "SLIM RX0"}, + {"RX INT4_1 MIX1 INP0", "RX1", "SLIM RX1"}, + {"RX INT4_1 MIX1 INP0", "RX2", "SLIM RX2"}, + {"RX INT4_1 MIX1 INP0", "RX3", "SLIM RX3"}, + {"RX INT4_1 MIX1 INP0", "RX4", "SLIM RX4"}, + {"RX INT4_1 MIX1 INP0", "RX5", "SLIM RX5"}, + {"RX INT4_1 MIX1 INP0", "RX6", "SLIM RX6"}, + {"RX INT4_1 MIX1 INP0", "RX7", "SLIM RX7"}, + {"RX INT4_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT4_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT4_1 MIX1 INP1", "RX0", "SLIM RX0"}, + {"RX INT4_1 MIX1 INP1", "RX1", "SLIM RX1"}, + {"RX INT4_1 MIX1 INP1", "RX2", "SLIM RX2"}, + {"RX INT4_1 MIX1 INP1", "RX3", "SLIM RX3"}, + {"RX INT4_1 MIX1 INP1", "RX4", "SLIM RX4"}, + {"RX INT4_1 MIX1 INP1", "RX5", "SLIM RX5"}, + {"RX INT4_1 MIX1 INP1", "RX6", "SLIM RX6"}, + {"RX INT4_1 MIX1 INP1", "RX7", "SLIM RX7"}, + {"RX INT4_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT4_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT4_1 MIX1 INP2", "RX0", "SLIM RX0"}, + {"RX INT4_1 MIX1 INP2", "RX1", "SLIM RX1"}, + {"RX INT4_1 MIX1 INP2", "RX2", "SLIM RX2"}, + {"RX INT4_1 MIX1 INP2", "RX3", "SLIM RX3"}, + {"RX INT4_1 MIX1 INP2", "RX4", "SLIM RX4"}, + {"RX INT4_1 MIX1 INP2", "RX5", "SLIM RX5"}, + {"RX INT4_1 MIX1 INP2", "RX6", "SLIM RX6"}, + {"RX INT4_1 MIX1 INP2", "RX7", "SLIM RX7"}, + {"RX INT4_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT4_1 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX INT5_1 MIX1 INP0", "RX0", "SLIM RX0"}, + {"RX INT5_1 MIX1 INP0", "RX1", "SLIM RX1"}, + {"RX INT5_1 MIX1 INP0", "RX2", "SLIM RX2"}, + {"RX INT5_1 MIX1 INP0", "RX3", "SLIM RX3"}, + {"RX INT5_1 MIX1 INP0", "RX4", "SLIM RX4"}, + {"RX INT5_1 MIX1 INP0", "RX5", "SLIM RX5"}, + {"RX INT5_1 MIX1 INP0", "RX6", "SLIM RX6"}, + {"RX INT5_1 MIX1 INP0", "RX7", "SLIM RX7"}, + {"RX INT5_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT5_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT5_1 MIX1 INP1", "RX0", "SLIM RX0"}, + {"RX INT5_1 MIX1 INP1", "RX1", "SLIM RX1"}, + {"RX INT5_1 MIX1 INP1", "RX2", "SLIM RX2"}, + {"RX INT5_1 MIX1 INP1", "RX3", "SLIM RX3"}, + {"RX INT5_1 MIX1 INP1", "RX4", "SLIM RX4"}, + {"RX INT5_1 MIX1 INP1", "RX5", "SLIM RX5"}, + {"RX INT5_1 MIX1 INP1", "RX6", "SLIM RX6"}, + {"RX INT5_1 MIX1 INP1", "RX7", "SLIM RX7"}, + {"RX INT5_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT5_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT5_1 MIX1 INP2", "RX0", "SLIM RX0"}, + {"RX INT5_1 MIX1 INP2", "RX1", "SLIM RX1"}, + {"RX INT5_1 MIX1 INP2", "RX2", "SLIM RX2"}, + {"RX INT5_1 MIX1 INP2", "RX3", "SLIM RX3"}, + {"RX INT5_1 MIX1 INP2", "RX4", "SLIM RX4"}, + {"RX INT5_1 MIX1 INP2", "RX5", "SLIM RX5"}, + {"RX INT5_1 MIX1 INP2", "RX6", "SLIM RX6"}, + {"RX INT5_1 MIX1 INP2", "RX7", "SLIM RX7"}, + {"RX INT5_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT5_1 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX INT6_1 MIX1 INP0", "RX0", "SLIM RX0"}, + {"RX INT6_1 MIX1 INP0", "RX1", "SLIM RX1"}, + {"RX INT6_1 MIX1 INP0", "RX2", "SLIM RX2"}, + {"RX INT6_1 MIX1 INP0", "RX3", "SLIM RX3"}, + {"RX INT6_1 MIX1 INP0", "RX4", "SLIM RX4"}, + {"RX INT6_1 MIX1 INP0", "RX5", "SLIM RX5"}, + {"RX INT6_1 MIX1 INP0", "RX6", "SLIM RX6"}, + {"RX INT6_1 MIX1 INP0", "RX7", "SLIM RX7"}, + {"RX INT6_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT6_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT6_1 MIX1 INP1", "RX0", "SLIM RX0"}, + {"RX INT6_1 MIX1 INP1", "RX1", "SLIM RX1"}, + {"RX INT6_1 MIX1 INP1", "RX2", "SLIM RX2"}, + {"RX INT6_1 MIX1 INP1", "RX3", "SLIM RX3"}, + {"RX INT6_1 MIX1 INP1", "RX4", "SLIM RX4"}, + {"RX INT6_1 MIX1 INP1", "RX5", "SLIM RX5"}, + {"RX INT6_1 MIX1 INP1", "RX6", "SLIM RX6"}, + {"RX INT6_1 MIX1 INP1", "RX7", "SLIM RX7"}, + {"RX INT6_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT6_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT6_1 MIX1 INP2", "RX0", "SLIM RX0"}, + {"RX INT6_1 MIX1 INP2", "RX1", "SLIM RX1"}, + {"RX INT6_1 MIX1 INP2", "RX2", "SLIM RX2"}, + {"RX INT6_1 MIX1 INP2", "RX3", "SLIM RX3"}, + {"RX INT6_1 MIX1 INP2", "RX4", "SLIM RX4"}, + {"RX INT6_1 MIX1 INP2", "RX5", "SLIM RX5"}, + {"RX INT6_1 MIX1 INP2", "RX6", "SLIM RX6"}, + {"RX INT6_1 MIX1 INP2", "RX7", "SLIM RX7"}, + {"RX INT6_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT6_1 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX INT7_1 MIX1 INP0", "RX0", "SLIM RX0"}, + {"RX INT7_1 MIX1 INP0", "RX1", "SLIM RX1"}, + {"RX INT7_1 MIX1 INP0", "RX2", "SLIM RX2"}, + {"RX INT7_1 MIX1 INP0", "RX3", "SLIM RX3"}, + {"RX INT7_1 MIX1 INP0", "RX4", "SLIM RX4"}, + {"RX INT7_1 MIX1 INP0", "RX5", "SLIM RX5"}, + {"RX INT7_1 MIX1 INP0", "RX6", "SLIM RX6"}, + {"RX INT7_1 MIX1 INP0", "RX7", "SLIM RX7"}, + {"RX INT7_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT7_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT7_1 MIX1 INP1", "RX0", "SLIM RX0"}, + {"RX INT7_1 MIX1 INP1", "RX1", "SLIM RX1"}, + {"RX INT7_1 MIX1 INP1", "RX2", "SLIM RX2"}, + {"RX INT7_1 MIX1 INP1", "RX3", "SLIM RX3"}, + {"RX INT7_1 MIX1 INP1", "RX4", "SLIM RX4"}, + {"RX INT7_1 MIX1 INP1", "RX5", "SLIM RX5"}, + {"RX INT7_1 MIX1 INP1", "RX6", "SLIM RX6"}, + {"RX INT7_1 MIX1 INP1", "RX7", "SLIM RX7"}, + {"RX INT7_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT7_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT7_1 MIX1 INP2", "RX0", "SLIM RX0"}, + {"RX INT7_1 MIX1 INP2", "RX1", "SLIM RX1"}, + {"RX INT7_1 MIX1 INP2", "RX2", "SLIM RX2"}, + {"RX INT7_1 MIX1 INP2", "RX3", "SLIM RX3"}, + {"RX INT7_1 MIX1 INP2", "RX4", "SLIM RX4"}, + {"RX INT7_1 MIX1 INP2", "RX5", "SLIM RX5"}, + {"RX INT7_1 MIX1 INP2", "RX6", "SLIM RX6"}, + {"RX INT7_1 MIX1 INP2", "RX7", "SLIM RX7"}, + {"RX INT7_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT7_1 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX INT8_1 MIX1 INP0", "RX0", "SLIM RX0"}, + {"RX INT8_1 MIX1 INP0", "RX1", "SLIM RX1"}, + {"RX INT8_1 MIX1 INP0", "RX2", "SLIM RX2"}, + {"RX INT8_1 MIX1 INP0", "RX3", "SLIM RX3"}, + {"RX INT8_1 MIX1 INP0", "RX4", "SLIM RX4"}, + {"RX INT8_1 MIX1 INP0", "RX5", "SLIM RX5"}, + {"RX INT8_1 MIX1 INP0", "RX6", "SLIM RX6"}, + {"RX INT8_1 MIX1 INP0", "RX7", "SLIM RX7"}, + {"RX INT8_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT8_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT8_1 MIX1 INP1", "RX0", "SLIM RX0"}, + {"RX INT8_1 MIX1 INP1", "RX1", "SLIM RX1"}, + {"RX INT8_1 MIX1 INP1", "RX2", "SLIM RX2"}, + {"RX INT8_1 MIX1 INP1", "RX3", "SLIM RX3"}, + {"RX INT8_1 MIX1 INP1", "RX4", "SLIM RX4"}, + {"RX INT8_1 MIX1 INP1", "RX5", "SLIM RX5"}, + {"RX INT8_1 MIX1 INP1", "RX6", "SLIM RX6"}, + {"RX INT8_1 MIX1 INP1", "RX7", "SLIM RX7"}, + {"RX INT8_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT8_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT8_1 MIX1 INP2", "RX0", "SLIM RX0"}, + {"RX INT8_1 MIX1 INP2", "RX1", "SLIM RX1"}, + {"RX INT8_1 MIX1 INP2", "RX2", "SLIM RX2"}, + {"RX INT8_1 MIX1 INP2", "RX3", "SLIM RX3"}, + {"RX INT8_1 MIX1 INP2", "RX4", "SLIM RX4"}, + {"RX INT8_1 MIX1 INP2", "RX5", "SLIM RX5"}, + {"RX INT8_1 MIX1 INP2", "RX6", "SLIM RX6"}, + {"RX INT8_1 MIX1 INP2", "RX7", "SLIM RX7"}, + {"RX INT8_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT8_1 MIX1 INP2", "IIR1", "IIR1"}, + + /* SRC0, SRC1 inputs to Sidetone RX Mixer + * on RX0, RX1, RX2, RX3, RX4 and RX7 chains + */ + {"IIR0", NULL, "IIR0 INP0 MUX"}, + {"IIR0 INP0 MUX", "DEC0", "ADC MUX0"}, + {"IIR0 INP0 MUX", "DEC1", "ADC MUX1"}, + {"IIR0 INP0 MUX", "DEC2", "ADC MUX2"}, + {"IIR0 INP0 MUX", "DEC3", "ADC MUX3"}, + {"IIR0 INP0 MUX", "DEC4", "ADC MUX4"}, + {"IIR0 INP0 MUX", "DEC5", "ADC MUX5"}, + {"IIR0 INP0 MUX", "DEC6", "ADC MUX6"}, + {"IIR0 INP0 MUX", "DEC7", "ADC MUX7"}, + {"IIR0 INP0 MUX", "DEC8", "ADC MUX8"}, + {"IIR0 INP0 MUX", "RX0", "SLIM RX0"}, + {"IIR0 INP0 MUX", "RX1", "SLIM RX1"}, + {"IIR0 INP0 MUX", "RX2", "SLIM RX2"}, + {"IIR0 INP0 MUX", "RX3", "SLIM RX3"}, + {"IIR0 INP0 MUX", "RX4", "SLIM RX4"}, + {"IIR0 INP0 MUX", "RX5", "SLIM RX5"}, + {"IIR0 INP0 MUX", "RX6", "SLIM RX6"}, + {"IIR0 INP0 MUX", "RX7", "SLIM RX7"}, + {"IIR0", NULL, "IIR0 INP1 MUX"}, + {"IIR0 INP1 MUX", "DEC0", "ADC MUX0"}, + {"IIR0 INP1 MUX", "DEC1", "ADC MUX1"}, + {"IIR0 INP1 MUX", "DEC2", "ADC MUX2"}, + {"IIR0 INP1 MUX", "DEC3", "ADC MUX3"}, + {"IIR0 INP1 MUX", "DEC4", "ADC MUX4"}, + {"IIR0 INP1 MUX", "DEC5", "ADC MUX5"}, + {"IIR0 INP1 MUX", "DEC6", "ADC MUX6"}, + {"IIR0 INP1 MUX", "DEC7", "ADC MUX7"}, + {"IIR0 INP1 MUX", "DEC8", "ADC MUX8"}, + {"IIR0 INP1 MUX", "RX0", "SLIM RX0"}, + {"IIR0 INP1 MUX", "RX1", "SLIM RX1"}, + {"IIR0 INP1 MUX", "RX2", "SLIM RX2"}, + {"IIR0 INP1 MUX", "RX3", "SLIM RX3"}, + {"IIR0 INP1 MUX", "RX4", "SLIM RX4"}, + {"IIR0 INP1 MUX", "RX5", "SLIM RX5"}, + {"IIR0 INP1 MUX", "RX6", "SLIM RX6"}, + {"IIR0 INP1 MUX", "RX7", "SLIM RX7"}, + {"IIR0", NULL, "IIR0 INP2 MUX"}, + {"IIR0 INP2 MUX", "DEC0", "ADC MUX0"}, + {"IIR0 INP2 MUX", "DEC1", "ADC MUX1"}, + {"IIR0 INP2 MUX", "DEC2", "ADC MUX2"}, + {"IIR0 INP2 MUX", "DEC3", "ADC MUX3"}, + {"IIR0 INP2 MUX", "DEC4", "ADC MUX4"}, + {"IIR0 INP2 MUX", "DEC5", "ADC MUX5"}, + {"IIR0 INP2 MUX", "DEC6", "ADC MUX6"}, + {"IIR0 INP2 MUX", "DEC7", "ADC MUX7"}, + {"IIR0 INP2 MUX", "DEC8", "ADC MUX8"}, + {"IIR0 INP2 MUX", "RX0", "SLIM RX0"}, + {"IIR0 INP2 MUX", "RX1", "SLIM RX1"}, + {"IIR0 INP2 MUX", "RX2", "SLIM RX2"}, + {"IIR0 INP2 MUX", "RX3", "SLIM RX3"}, + {"IIR0 INP2 MUX", "RX4", "SLIM RX4"}, + {"IIR0 INP2 MUX", "RX5", "SLIM RX5"}, + {"IIR0 INP2 MUX", "RX6", "SLIM RX6"}, + {"IIR0 INP2 MUX", "RX7", "SLIM RX7"}, + {"IIR0", NULL, "IIR0 INP3 MUX"}, + {"IIR0 INP3 MUX", "DEC0", "ADC MUX0"}, + {"IIR0 INP3 MUX", "DEC1", "ADC MUX1"}, + {"IIR0 INP3 MUX", "DEC2", "ADC MUX2"}, + {"IIR0 INP3 MUX", "DEC3", "ADC MUX3"}, + {"IIR0 INP3 MUX", "DEC4", "ADC MUX4"}, + {"IIR0 INP3 MUX", "DEC5", "ADC MUX5"}, + {"IIR0 INP3 MUX", "DEC6", "ADC MUX6"}, + {"IIR0 INP3 MUX", "DEC7", "ADC MUX7"}, + {"IIR0 INP3 MUX", "DEC8", "ADC MUX8"}, + {"IIR0 INP3 MUX", "RX0", "SLIM RX0"}, + {"IIR0 INP3 MUX", "RX1", "SLIM RX1"}, + {"IIR0 INP3 MUX", "RX2", "SLIM RX2"}, + {"IIR0 INP3 MUX", "RX3", "SLIM RX3"}, + {"IIR0 INP3 MUX", "RX4", "SLIM RX4"}, + {"IIR0 INP3 MUX", "RX5", "SLIM RX5"}, + {"IIR0 INP3 MUX", "RX6", "SLIM RX6"}, + {"IIR0 INP3 MUX", "RX7", "SLIM RX7"}, + + {"IIR1", NULL, "IIR1 INP0 MUX"}, + {"IIR1 INP0 MUX", "DEC0", "ADC MUX0"}, + {"IIR1 INP0 MUX", "DEC1", "ADC MUX1"}, + {"IIR1 INP0 MUX", "DEC2", "ADC MUX2"}, + {"IIR1 INP0 MUX", "DEC3", "ADC MUX3"}, + {"IIR1 INP0 MUX", "DEC4", "ADC MUX4"}, + {"IIR1 INP0 MUX", "DEC5", "ADC MUX5"}, + {"IIR1 INP0 MUX", "DEC6", "ADC MUX6"}, + {"IIR1 INP0 MUX", "DEC7", "ADC MUX7"}, + {"IIR1 INP0 MUX", "DEC8", "ADC MUX8"}, + {"IIR1 INP0 MUX", "RX0", "SLIM RX0"}, + {"IIR1 INP0 MUX", "RX1", "SLIM RX1"}, + {"IIR1 INP0 MUX", "RX2", "SLIM RX2"}, + {"IIR1 INP0 MUX", "RX3", "SLIM RX3"}, + {"IIR1 INP0 MUX", "RX4", "SLIM RX4"}, + {"IIR1 INP0 MUX", "RX5", "SLIM RX5"}, + {"IIR1 INP0 MUX", "RX6", "SLIM RX6"}, + {"IIR1 INP0 MUX", "RX7", "SLIM RX7"}, + {"IIR1", NULL, "IIR1 INP1 MUX"}, + {"IIR1 INP1 MUX", "DEC0", "ADC MUX0"}, + {"IIR1 INP1 MUX", "DEC1", "ADC MUX1"}, + {"IIR1 INP1 MUX", "DEC2", "ADC MUX2"}, + {"IIR1 INP1 MUX", "DEC3", "ADC MUX3"}, + {"IIR1 INP1 MUX", "DEC4", "ADC MUX4"}, + {"IIR1 INP1 MUX", "DEC5", "ADC MUX5"}, + {"IIR1 INP1 MUX", "DEC6", "ADC MUX6"}, + {"IIR1 INP1 MUX", "DEC7", "ADC MUX7"}, + {"IIR1 INP1 MUX", "DEC8", "ADC MUX8"}, + {"IIR1 INP1 MUX", "RX0", "SLIM RX0"}, + {"IIR1 INP1 MUX", "RX1", "SLIM RX1"}, + {"IIR1 INP1 MUX", "RX2", "SLIM RX2"}, + {"IIR1 INP1 MUX", "RX3", "SLIM RX3"}, + {"IIR1 INP1 MUX", "RX4", "SLIM RX4"}, + {"IIR1 INP1 MUX", "RX5", "SLIM RX5"}, + {"IIR1 INP1 MUX", "RX6", "SLIM RX6"}, + {"IIR1 INP1 MUX", "RX7", "SLIM RX7"}, + {"IIR1", NULL, "IIR1 INP2 MUX"}, + {"IIR1 INP2 MUX", "DEC0", "ADC MUX0"}, + {"IIR1 INP2 MUX", "DEC1", "ADC MUX1"}, + {"IIR1 INP2 MUX", "DEC2", "ADC MUX2"}, + {"IIR1 INP2 MUX", "DEC3", "ADC MUX3"}, + {"IIR1 INP2 MUX", "DEC4", "ADC MUX4"}, + {"IIR1 INP2 MUX", "DEC5", "ADC MUX5"}, + {"IIR1 INP2 MUX", "DEC6", "ADC MUX6"}, + {"IIR1 INP2 MUX", "DEC7", "ADC MUX7"}, + {"IIR1 INP2 MUX", "DEC8", "ADC MUX8"}, + {"IIR1 INP2 MUX", "RX0", "SLIM RX0"}, + {"IIR1 INP2 MUX", "RX1", "SLIM RX1"}, + {"IIR1 INP2 MUX", "RX2", "SLIM RX2"}, + {"IIR1 INP2 MUX", "RX3", "SLIM RX3"}, + {"IIR1 INP2 MUX", "RX4", "SLIM RX4"}, + {"IIR1 INP2 MUX", "RX5", "SLIM RX5"}, + {"IIR1 INP2 MUX", "RX6", "SLIM RX6"}, + {"IIR1 INP2 MUX", "RX7", "SLIM RX7"}, + {"IIR1", NULL, "IIR1 INP3 MUX"}, + {"IIR1 INP3 MUX", "DEC0", "ADC MUX0"}, + {"IIR1 INP3 MUX", "DEC1", "ADC MUX1"}, + {"IIR1 INP3 MUX", "DEC2", "ADC MUX2"}, + {"IIR1 INP3 MUX", "DEC3", "ADC MUX3"}, + {"IIR1 INP3 MUX", "DEC4", "ADC MUX4"}, + {"IIR1 INP3 MUX", "DEC5", "ADC MUX5"}, + {"IIR1 INP3 MUX", "DEC6", "ADC MUX6"}, + {"IIR1 INP3 MUX", "DEC7", "ADC MUX7"}, + {"IIR1 INP3 MUX", "DEC8", "ADC MUX8"}, + {"IIR1 INP3 MUX", "RX0", "SLIM RX0"}, + {"IIR1 INP3 MUX", "RX1", "SLIM RX1"}, + {"IIR1 INP3 MUX", "RX2", "SLIM RX2"}, + {"IIR1 INP3 MUX", "RX3", "SLIM RX3"}, + {"IIR1 INP3 MUX", "RX4", "SLIM RX4"}, + {"IIR1 INP3 MUX", "RX5", "SLIM RX5"}, + {"IIR1 INP3 MUX", "RX6", "SLIM RX6"}, + {"IIR1 INP3 MUX", "RX7", "SLIM RX7"}, + + {"SRC0", NULL, "IIR0"}, + {"SRC1", NULL, "IIR1"}, + {"RX INT0 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT0 MIX2 INP", "SRC1", "SRC1"}, + {"RX INT1 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT1 MIX2 INP", "SRC1", "SRC1"}, + {"RX INT2 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT2 MIX2 INP", "SRC1", "SRC1"}, + {"RX INT3 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT3 MIX2 INP", "SRC1", "SRC1"}, + {"RX INT4 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT4 MIX2 INP", "SRC1", "SRC1"}, + {"RX INT7 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT7 MIX2 INP", "SRC1", "SRC1"}, +}; + +static int tasha_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u16 amic_reg; + + if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE")) + amic_reg = WCD9335_ANA_AMIC1; + if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE")) + amic_reg = WCD9335_ANA_AMIC3; + if (!strcmp(kcontrol->id.name, "AMIC_5_6 PWR MODE")) + amic_reg = WCD9335_ANA_AMIC5; + + ucontrol->value.integer.value[0] = + (snd_soc_read(codec, amic_reg) & WCD9335_AMIC_PWR_LVL_MASK) >> + WCD9335_AMIC_PWR_LVL_SHIFT; + + return 0; +} + +static int tasha_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u32 mode_val; + u16 amic_reg; + + mode_val = ucontrol->value.enumerated.item[0]; + + dev_dbg(codec->dev, "%s: mode: %d\n", + __func__, mode_val); + + if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE")) + amic_reg = WCD9335_ANA_AMIC1; + if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE")) + amic_reg = WCD9335_ANA_AMIC3; + if (!strcmp(kcontrol->id.name, "AMIC_5_6 PWR MODE")) + amic_reg = WCD9335_ANA_AMIC5; + + snd_soc_update_bits(codec, amic_reg, WCD9335_AMIC_PWR_LVL_MASK, + mode_val << WCD9335_AMIC_PWR_LVL_SHIFT); + + return 0; +} + +static int tasha_rx_hph_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = tasha->hph_mode; + return 0; +} + +static int tasha_rx_hph_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + u32 mode_val; + + mode_val = ucontrol->value.enumerated.item[0]; + + dev_dbg(codec->dev, "%s: mode: %d\n", + __func__, mode_val); + + if (mode_val == 0) { + dev_warn(codec->dev, "%s:Invalid HPH Mode, default to Cls-H HiFi\n", + __func__); + mode_val = CLS_H_HIFI; + } + tasha->hph_mode = mode_val; + return 0; +} + +static const char *const tasha_conn_mad_text[] = { + "NOTUSED1", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6", + "NOTUSED2", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", + "DMIC5", "NOTUSED3", "NOTUSED4" +}; + +static const struct soc_enum tasha_conn_mad_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_conn_mad_text), + tasha_conn_mad_text); + +static int tasha_enable_ldo_h_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u8 val = 0; + + if (codec) + val = snd_soc_read(codec, WCD9335_LDOH_MODE) & 0x80; + + ucontrol->value.integer.value[0] = !!val; + + return 0; +} + +static int tasha_enable_ldo_h_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int value = ucontrol->value.integer.value[0]; + bool enable; + + enable = !!value; + if (codec) + tasha_codec_enable_standalone_ldo_h(codec, enable); + + return 0; +} + +static int tasha_mad_input_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 tasha_mad_input; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + tasha_mad_input = snd_soc_read(codec, + WCD9335_SOC_MAD_INP_SEL) & 0x0F; + ucontrol->value.integer.value[0] = tasha_mad_input; + + dev_dbg(codec->dev, + "%s: tasha_mad_input = %s\n", __func__, + tasha_conn_mad_text[tasha_mad_input]); + return 0; +} + +static int tasha_mad_input_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 tasha_mad_input; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_card *card = codec->component.card; + char mad_amic_input_widget[6]; + const char *mad_input_widget; + const char *source_widget = NULL; + u32 adc, i, mic_bias_found = 0; + int ret = 0; + char *mad_input; + + tasha_mad_input = ucontrol->value.integer.value[0]; + + if (tasha_mad_input >= ARRAY_SIZE(tasha_conn_mad_text)) { + dev_err(codec->dev, + "%s: tasha_mad_input = %d out of bounds\n", + __func__, tasha_mad_input); + return -EINVAL; + } + + if (!strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED1") || + !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED2") || + !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED3") || + !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED4")) { + dev_err(codec->dev, + "%s: Unsupported tasha_mad_input = %s\n", + __func__, tasha_conn_mad_text[tasha_mad_input]); + return -EINVAL; + } + + if (strnstr(tasha_conn_mad_text[tasha_mad_input], + "ADC", sizeof("ADC"))) { + mad_input = strpbrk(tasha_conn_mad_text[tasha_mad_input], + "123456"); + if (!mad_input) { + dev_err(codec->dev, "%s: Invalid MAD input %s\n", + __func__, + tasha_conn_mad_text[tasha_mad_input]); + return -EINVAL; + } + ret = kstrtouint(mad_input, 10, &adc); + if ((ret < 0) || (adc > 6)) { + dev_err(codec->dev, + "%s: Invalid ADC = %s\n", __func__, + tasha_conn_mad_text[tasha_mad_input]); + ret = -EINVAL; + } + + snprintf(mad_amic_input_widget, 6, "%s%u", "AMIC", adc); + + mad_input_widget = mad_amic_input_widget; + } else { + /* DMIC type input widget*/ + mad_input_widget = tasha_conn_mad_text[tasha_mad_input]; + } + + dev_dbg(codec->dev, + "%s: tasha input widget = %s\n", __func__, + mad_input_widget); + + for (i = 0; i < card->num_of_dapm_routes; i++) { + if (!strcmp(card->of_dapm_routes[i].sink, mad_input_widget)) { + source_widget = card->of_dapm_routes[i].source; + if (!source_widget) { + dev_err(codec->dev, + "%s: invalid source widget\n", + __func__); + return -EINVAL; + } + + if (strnstr(source_widget, + "MIC BIAS1", sizeof("MIC BIAS1"))) { + mic_bias_found = 1; + break; + } else if (strnstr(source_widget, + "MIC BIAS2", sizeof("MIC BIAS2"))) { + mic_bias_found = 2; + break; + } else if (strnstr(source_widget, + "MIC BIAS3", sizeof("MIC BIAS3"))) { + mic_bias_found = 3; + break; + } else if (strnstr(source_widget, + "MIC BIAS4", sizeof("MIC BIAS4"))) { + mic_bias_found = 4; + break; + } + } + } + + if (!mic_bias_found) { + dev_err(codec->dev, + "%s: mic bias source not found for input = %s\n", + __func__, mad_input_widget); + return -EINVAL; + } + + dev_dbg(codec->dev, + "%s: mic_bias found = %d\n", __func__, + mic_bias_found); + + snd_soc_update_bits(codec, WCD9335_SOC_MAD_INP_SEL, + 0x0F, tasha_mad_input); + snd_soc_update_bits(codec, WCD9335_ANA_MAD_SETUP, + 0x07, mic_bias_found); + + return 0; +} + +static int tasha_pinctl_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u16 ctl_reg; + u8 reg_val, pinctl_position; + + pinctl_position = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + switch (pinctl_position >> 3) { + case 0: + ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_0; + break; + case 1: + ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_1; + break; + case 2: + ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_2; + break; + case 3: + ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_3; + break; + default: + dev_err(codec->dev, "%s: Invalid pinctl position = %d\n", + __func__, pinctl_position); + return -EINVAL; + } + + reg_val = snd_soc_read(codec, ctl_reg); + reg_val = (reg_val >> (pinctl_position & 0x07)) & 0x1; + ucontrol->value.integer.value[0] = reg_val; + + return 0; +} + +static int tasha_pinctl_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + u16 ctl_reg, cfg_reg; + u8 ctl_val, cfg_val, pinctl_position, pinctl_mode, mask; + + /* 1- high or low; 0- high Z */ + pinctl_mode = ucontrol->value.integer.value[0]; + pinctl_position = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + switch (pinctl_position >> 3) { + case 0: + ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_0; + break; + case 1: + ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_1; + break; + case 2: + ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_2; + break; + case 3: + ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_3; + break; + default: + dev_err(codec->dev, "%s: Invalid pinctl position = %d\n", + __func__, pinctl_position); + return -EINVAL; + } + + ctl_val = pinctl_mode << (pinctl_position & 0x07); + mask = 1 << (pinctl_position & 0x07); + snd_soc_update_bits(codec, ctl_reg, mask, ctl_val); + + cfg_reg = WCD9335_TLMM_BIST_MODE_PINCFG + pinctl_position; + if (!pinctl_mode) { + if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) + cfg_val = 0x4; + else + cfg_val = 0xC; + } else { + cfg_val = 0; + } + snd_soc_update_bits(codec, cfg_reg, 0x07, cfg_val); + + dev_dbg(codec->dev, "%s: reg=0x%x mask=0x%x val=%d reg=0x%x val=%d\n", + __func__, ctl_reg, mask, ctl_val, cfg_reg, cfg_val); + + return 0; +} + +static void wcd_vbat_adc_out_config_2_0(struct wcd_vbat *vbat, + struct snd_soc_codec *codec) +{ + u8 val1, val2; + + /* + * Measure dcp1 by using "ALT" branch of band gap + * voltage(Vbg) and use it in FAST mode + */ + snd_soc_update_bits(codec, WCD9335_BIAS_CTL, 0x82, 0x82); + snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x10); + snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01, 0x01); + snd_soc_update_bits(codec, WCD9335_ANA_VBADC, 0x80, 0x80); + snd_soc_update_bits(codec, WCD9335_VBADC_SUBBLOCK_EN, 0x20, 0x00); + + snd_soc_update_bits(codec, WCD9335_VBADC_FE_CTRL, 0x20, 0x20); + /* Wait 100 usec after calibration select as Vbg */ + usleep_range(100, 110); + + snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x40); + val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB); + val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB); + snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x00); + + vbat->dcp1 = (((val1 & 0xFF) << 3) | (val2 & 0x07)); + + snd_soc_update_bits(codec, WCD9335_BIAS_CTL, 0x40, 0x40); + /* Wait 100 usec after selecting Vbg as 1.05V */ + usleep_range(100, 110); + + snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x40); + val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB); + val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB); + snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x00); + + vbat->dcp2 = (((val1 & 0xFF) << 3) | (val2 & 0x07)); + + dev_dbg(codec->dev, "%s: dcp1:0x%x, dcp2:0x%x\n", + __func__, vbat->dcp1, vbat->dcp2); + + snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28); + /* Wait 100 usec after selecting Vbg as 0.85V */ + usleep_range(100, 110); + + snd_soc_update_bits(codec, WCD9335_VBADC_FE_CTRL, 0x20, 0x00); + snd_soc_update_bits(codec, WCD9335_VBADC_SUBBLOCK_EN, 0x20, 0x20); + snd_soc_update_bits(codec, WCD9335_ANA_VBADC, 0x80, 0x00); + + snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x00); + snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01, 0x00); +} + +static void wcd_vbat_adc_out_config_1_x(struct wcd_vbat *vbat, + struct snd_soc_codec *codec) +{ + u8 val1, val2; + + /* + * Measure dcp1 by applying band gap voltage(Vbg) + * of 0.85V + */ + snd_soc_write(codec, WCD9335_ANA_BIAS, 0x20); + snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28); + snd_soc_write(codec, WCD9335_BIAS_VBG_FINE_ADJ, 0x05); + snd_soc_write(codec, WCD9335_ANA_BIAS, 0xA0); + /* Wait 2 sec after enabling band gap bias */ + usleep_range(2000000, 2000100); + + snd_soc_write(codec, WCD9335_ANA_CLK_TOP, 0x82); + snd_soc_write(codec, WCD9335_ANA_CLK_TOP, 0x87); + snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x10); + snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_CFG, 0x0D); + snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01); + + snd_soc_write(codec, WCD9335_ANA_VBADC, 0x80); + snd_soc_write(codec, WCD9335_VBADC_SUBBLOCK_EN, 0xDE); + snd_soc_write(codec, WCD9335_VBADC_FE_CTRL, 0x3C); + /* Wait 1 msec after calibration select as Vbg */ + usleep_range(1000, 1100); + + snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0xC0); + val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB); + val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB); + snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80); + + vbat->dcp1 = (((val1 & 0xFF) << 3) | (val2 & 0x07)); + + /* + * Measure dcp2 by applying band gap voltage(Vbg) + * of 1.05V + */ + snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80); + snd_soc_write(codec, WCD9335_ANA_BIAS, 0xC0); + snd_soc_write(codec, WCD9335_BIAS_CTL, 0x68); + /* Wait 2 msec after selecting Vbg as 1.05V */ + usleep_range(2000, 2100); + + snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80); + /* Wait 1 sec after enabling band gap bias */ + usleep_range(1000000, 1000100); + + snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0xC0); + val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB); + val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB); + snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80); + + vbat->dcp2 = (((val1 & 0xFF) << 3) | (val2 & 0x07)); + + dev_dbg(codec->dev, "%s: dcp1:0x%x, dcp2:0x%x\n", + __func__, vbat->dcp1, vbat->dcp2); + + /* Reset the Vbat ADC configuration */ + snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80); + snd_soc_write(codec, WCD9335_ANA_BIAS, 0xC0); + + snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28); + /* Wait 2 msec after selecting Vbg as 0.85V */ + usleep_range(2000, 2100); + + snd_soc_write(codec, WCD9335_ANA_BIAS, 0xA0); + /* Wait 1 sec after enabling band gap bias */ + usleep_range(1000000, 1000100); + + snd_soc_write(codec, WCD9335_VBADC_FE_CTRL, 0x1C); + snd_soc_write(codec, WCD9335_VBADC_SUBBLOCK_EN, 0xFE); + snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80); + snd_soc_write(codec, WCD9335_ANA_VBADC, 0x00); + + snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x00); + snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x00); + snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_CFG, 0x0A); +} + +static void wcd_vbat_adc_out_config(struct wcd_vbat *vbat, + struct snd_soc_codec *codec) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + + if (!vbat->adc_config) { + tasha_cdc_mclk_enable(codec, true, false); + + if (TASHA_IS_2_0(wcd9xxx)) + wcd_vbat_adc_out_config_2_0(vbat, codec); + else + wcd_vbat_adc_out_config_1_x(vbat, codec); + + tasha_cdc_mclk_enable(codec, false, false); + vbat->adc_config = true; + } +} + +static int tasha_update_vbat_reg_config(struct snd_soc_codec *codec) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct firmware_cal *hwdep_cal = NULL; + struct vbat_monitor_reg *vbat_reg_ptr = NULL; + const void *data; + size_t cal_size, vbat_size_remaining; + int ret = 0, i; + u32 vbat_writes_size = 0; + u16 reg; + u8 mask, val, old_val; + + hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_VBAT_CAL); + if (hwdep_cal) { + data = hwdep_cal->data; + cal_size = hwdep_cal->size; + dev_dbg(codec->dev, "%s: using hwdep calibration\n", + __func__); + } else { + dev_err(codec->dev, "%s: Vbat cal not received\n", + __func__); + ret = -EINVAL; + goto done; + } + + if (cal_size < sizeof(*vbat_reg_ptr)) { + dev_err(codec->dev, + "%s: Incorrect size %zd for Vbat Cal, expected %zd\n", + __func__, cal_size, sizeof(*vbat_reg_ptr)); + ret = -EINVAL; + goto done; + } + + vbat_reg_ptr = (struct vbat_monitor_reg *) (data); + + if (!vbat_reg_ptr) { + dev_err(codec->dev, + "%s: Invalid calibration data for Vbat\n", + __func__); + ret = -EINVAL; + goto done; + } + + vbat_writes_size = vbat_reg_ptr->size; + vbat_size_remaining = cal_size - sizeof(u32); + dev_dbg(codec->dev, "%s: vbat_writes_sz: %d, vbat_sz_remaining: %zd\n", + __func__, vbat_writes_size, vbat_size_remaining); + + if ((vbat_writes_size * TASHA_PACKED_REG_SIZE) + > vbat_size_remaining) { + pr_err("%s: Incorrect Vbat calibration data\n", __func__); + ret = -EINVAL; + goto done; + } + + for (i = 0 ; i < vbat_writes_size; i++) { + TASHA_CODEC_UNPACK_ENTRY(vbat_reg_ptr->writes[i], + reg, mask, val); + old_val = snd_soc_read(codec, reg); + snd_soc_write(codec, reg, (old_val & ~mask) | (val & mask)); + } + +done: + return ret; +} + +static int tasha_vbat_adc_data_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + wcd_vbat_adc_out_config(&tasha->vbat, codec); + + ucontrol->value.integer.value[0] = tasha->vbat.dcp1; + ucontrol->value.integer.value[1] = tasha->vbat.dcp2; + + dev_dbg(codec->dev, + "%s: Vbat ADC output values, Dcp1 : %lu, Dcp2: %lu\n", + __func__, ucontrol->value.integer.value[0], + ucontrol->value.integer.value[1]); + + return 0; +} + +static const char * const tasha_vbat_gsm_mode_text[] = { + "OFF", "ON"}; + +static const struct soc_enum tasha_vbat_gsm_mode_enum = + SOC_ENUM_SINGLE_EXT(2, tasha_vbat_gsm_mode_text); + +static int tasha_vbat_gsm_mode_func_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + ucontrol->value.integer.value[0] = + ((snd_soc_read(codec, WCD9335_CDC_VBAT_VBAT_CFG) & 0x04) ? + 1 : 0); + + dev_dbg(codec->dev, "%s: value: %lu\n", __func__, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int tasha_vbat_gsm_mode_func_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: value: %lu\n", __func__, + ucontrol->value.integer.value[0]); + + /* Set Vbat register configuration for GSM mode bit based on value */ + if (ucontrol->value.integer.value[0]) + snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_CFG, + 0x04, 0x04); + else + snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_CFG, + 0x04, 0x00); + + return 0; +} + +static int tasha_codec_vbat_enable_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + int ret = 0; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + u16 vbat_path_ctl, vbat_cfg, vbat_path_cfg; + + vbat_path_ctl = WCD9335_CDC_VBAT_VBAT_PATH_CTL; + vbat_cfg = WCD9335_CDC_VBAT_VBAT_CFG; + vbat_path_cfg = WCD9335_CDC_RX8_RX_PATH_CFG1; + + if (!strcmp(w->name, "RX INT8 VBAT")) + vbat_path_cfg = WCD9335_CDC_RX8_RX_PATH_CFG1; + else if (!strcmp(w->name, "RX INT7 VBAT")) + vbat_path_cfg = WCD9335_CDC_RX7_RX_PATH_CFG1; + else if (!strcmp(w->name, "RX INT6 VBAT")) + vbat_path_cfg = WCD9335_CDC_RX6_RX_PATH_CFG1; + else if (!strcmp(w->name, "RX INT5 VBAT")) + vbat_path_cfg = WCD9335_CDC_RX5_RX_PATH_CFG1; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = tasha_update_vbat_reg_config(codec); + if (ret) { + dev_dbg(codec->dev, + "%s : VBAT isn't calibrated, So not enabling it\n", + __func__); + return 0; + } + snd_soc_write(codec, WCD9335_ANA_VBADC, 0x80); + snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x02); + snd_soc_update_bits(codec, vbat_path_ctl, 0x10, 0x10); + snd_soc_update_bits(codec, vbat_cfg, 0x01, 0x01); + tasha->vbat.is_enabled = true; + break; + case SND_SOC_DAPM_POST_PMD: + if (tasha->vbat.is_enabled) { + snd_soc_update_bits(codec, vbat_cfg, 0x01, 0x00); + snd_soc_update_bits(codec, vbat_path_ctl, 0x10, 0x00); + snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x00); + snd_soc_write(codec, WCD9335_ANA_VBADC, 0x00); + tasha->vbat.is_enabled = false; + } + break; + }; + + return ret; +} + +static const char * const rx_hph_mode_mux_text[] = { + "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI" +}; + +static const struct soc_enum rx_hph_mode_mux_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text), + rx_hph_mode_mux_text); + +static const char * const amic_pwr_lvl_text[] = { + "LOW_PWR", "DEFAULT", "HIGH_PERF" +}; + +static const struct soc_enum amic_pwr_lvl_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(amic_pwr_lvl_text), + amic_pwr_lvl_text); + +static const struct snd_kcontrol_new tasha_snd_controls[] = { + SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL, + 0, -84, 40, digital_gain), /* -84dB min - 40dB max */ + SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL, + 0, -84, 40, digital_gain), + + SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume", + WCD9335_CDC_RX0_RX_VOL_MIX_CTL, + 0, -84, 40, digital_gain), /* -84dB min - 40dB max */ + SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume", + WCD9335_CDC_RX1_RX_VOL_MIX_CTL, + 0, -84, 40, digital_gain), /* -84dB min - 40dB max */ + SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume", + WCD9335_CDC_RX2_RX_VOL_MIX_CTL, + 0, -84, 40, digital_gain), /* -84dB min - 40dB max */ + SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume", + WCD9335_CDC_RX3_RX_VOL_MIX_CTL, + 0, -84, 40, digital_gain), /* -84dB min - 40dB max */ + SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume", + WCD9335_CDC_RX4_RX_VOL_MIX_CTL, + 0, -84, 40, digital_gain), /* -84dB min - 40dB max */ + SOC_SINGLE_SX_TLV("RX5 Mix Digital Volume", + WCD9335_CDC_RX5_RX_VOL_MIX_CTL, + 0, -84, 40, digital_gain), /* -84dB min - 40dB max */ + SOC_SINGLE_SX_TLV("RX6 Mix Digital Volume", + WCD9335_CDC_RX6_RX_VOL_MIX_CTL, + 0, -84, 40, digital_gain), /* -84dB min - 40dB max */ + SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume", + WCD9335_CDC_RX7_RX_VOL_MIX_CTL, + 0, -84, 40, digital_gain), /* -84dB min - 40dB max */ + SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume", + WCD9335_CDC_RX8_RX_VOL_MIX_CTL, + 0, -84, 40, digital_gain), /* -84dB min - 40dB max */ + + SOC_SINGLE_SX_TLV("DEC0 Volume", WCD9335_CDC_TX0_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC1 Volume", WCD9335_CDC_TX1_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC2 Volume", WCD9335_CDC_TX2_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC3 Volume", WCD9335_CDC_TX3_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC4 Volume", WCD9335_CDC_TX4_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC5 Volume", WCD9335_CDC_TX5_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC6 Volume", WCD9335_CDC_TX6_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC7 Volume", WCD9335_CDC_TX7_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC8 Volume", WCD9335_CDC_TX8_TX_VOL_CTL, 0, + -84, 40, digital_gain), + + SOC_SINGLE_SX_TLV("IIR0 INP0 Volume", + WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, + 40, digital_gain), + SOC_SINGLE_SX_TLV("IIR0 INP1 Volume", + WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84, + 40, digital_gain), + SOC_SINGLE_SX_TLV("IIR0 INP2 Volume", + WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84, + 40, digital_gain), + SOC_SINGLE_SX_TLV("IIR0 INP3 Volume", + WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84, + 40, digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP0 Volume", + WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0, -84, + 40, digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP1 Volume", + WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0, -84, + 40, digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP2 Volume", + WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0, -84, + 40, digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP3 Volume", + WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0, -84, + 40, digital_gain), + + SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, tasha_get_anc_slot, + tasha_put_anc_slot), + SOC_ENUM_EXT("ANC Function", tasha_anc_func_enum, tasha_get_anc_func, + tasha_put_anc_func), + + SOC_ENUM_EXT("CLK MODE", tasha_clkmode_enum, tasha_get_clkmode, + tasha_put_clkmode), + + SOC_ENUM("TX0 HPF cut off", cf_dec0_enum), + SOC_ENUM("TX1 HPF cut off", cf_dec1_enum), + SOC_ENUM("TX2 HPF cut off", cf_dec2_enum), + SOC_ENUM("TX3 HPF cut off", cf_dec3_enum), + SOC_ENUM("TX4 HPF cut off", cf_dec4_enum), + SOC_ENUM("TX5 HPF cut off", cf_dec5_enum), + SOC_ENUM("TX6 HPF cut off", cf_dec6_enum), + SOC_ENUM("TX7 HPF cut off", cf_dec7_enum), + SOC_ENUM("TX8 HPF cut off", cf_dec8_enum), + + SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum), + SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum), + SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum), + SOC_ENUM("RX INT1_2 HPF cut off", cf_int1_2_enum), + SOC_ENUM("RX INT2_1 HPF cut off", cf_int2_1_enum), + SOC_ENUM("RX INT2_2 HPF cut off", cf_int2_2_enum), + SOC_ENUM("RX INT3_1 HPF cut off", cf_int3_1_enum), + SOC_ENUM("RX INT3_2 HPF cut off", cf_int3_2_enum), + SOC_ENUM("RX INT4_1 HPF cut off", cf_int4_1_enum), + SOC_ENUM("RX INT4_2 HPF cut off", cf_int4_2_enum), + SOC_ENUM("RX INT5_1 HPF cut off", cf_int5_1_enum), + SOC_ENUM("RX INT5_2 HPF cut off", cf_int5_2_enum), + SOC_ENUM("RX INT6_1 HPF cut off", cf_int6_1_enum), + SOC_ENUM("RX INT6_2 HPF cut off", cf_int6_2_enum), + SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum), + SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum), + SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum), + SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum), + + SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0, + tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR0 Enable Band2", IIR0, BAND2, 1, 0, + tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR0 Enable Band3", IIR0, BAND3, 1, 0, + tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR0 Enable Band4", IIR0, BAND4, 1, 0, + tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR0 Enable Band5", IIR0, BAND5, 1, 0, + tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0, + tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0, + tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0, + tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0, + tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0, + tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer), + + SOC_SINGLE_MULTI_EXT("IIR0 Band1", IIR0, BAND1, 255, 0, 5, + tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR0 Band2", IIR0, BAND2, 255, 0, 5, + tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR0 Band3", IIR0, BAND3, 255, 0, 5, + tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR0 Band4", IIR0, BAND4, 255, 0, 5, + tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR0 Band5", IIR0, BAND5, 255, 0, 5, + tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5, + tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5, + tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5, + tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5, + tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5, + tasha_get_iir_band_audio_mixer, tasha_put_iir_band_audio_mixer), + + SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0, + tasha_get_compander, tasha_set_compander), + SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0, + tasha_get_compander, tasha_set_compander), + SOC_SINGLE_EXT("COMP3 Switch", SND_SOC_NOPM, COMPANDER_3, 1, 0, + tasha_get_compander, tasha_set_compander), + SOC_SINGLE_EXT("COMP4 Switch", SND_SOC_NOPM, COMPANDER_4, 1, 0, + tasha_get_compander, tasha_set_compander), + SOC_SINGLE_EXT("COMP5 Switch", SND_SOC_NOPM, COMPANDER_5, 1, 0, + tasha_get_compander, tasha_set_compander), + SOC_SINGLE_EXT("COMP6 Switch", SND_SOC_NOPM, COMPANDER_6, 1, 0, + tasha_get_compander, tasha_set_compander), + SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0, + tasha_get_compander, tasha_set_compander), + SOC_SINGLE_EXT("COMP8 Switch", SND_SOC_NOPM, COMPANDER_8, 1, 0, + tasha_get_compander, tasha_set_compander), + + SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum, + tasha_rx_hph_mode_get, tasha_rx_hph_mode_put), + + SOC_ENUM_EXT("MAD Input", tasha_conn_mad_enum, + tasha_mad_input_get, tasha_mad_input_put), + SOC_SINGLE_EXT("LDO_H Enable", SND_SOC_NOPM, 0, 1, 0, + tasha_enable_ldo_h_get, tasha_enable_ldo_h_put), + + SOC_SINGLE_EXT("DMIC1_CLK_PIN_MODE", SND_SOC_NOPM, 17, 1, 0, + tasha_pinctl_mode_get, tasha_pinctl_mode_put), + + SOC_SINGLE_EXT("DMIC1_DATA_PIN_MODE", SND_SOC_NOPM, 18, 1, 0, + tasha_pinctl_mode_get, tasha_pinctl_mode_put), + + SOC_SINGLE_EXT("DMIC2_CLK_PIN_MODE", SND_SOC_NOPM, 19, 1, 0, + tasha_pinctl_mode_get, tasha_pinctl_mode_put), + + SOC_SINGLE_EXT("DMIC2_DATA_PIN_MODE", SND_SOC_NOPM, 20, 1, 0, + tasha_pinctl_mode_get, tasha_pinctl_mode_put), + + SOC_SINGLE_EXT("DMIC3_CLK_PIN_MODE", SND_SOC_NOPM, 21, 1, 0, + tasha_pinctl_mode_get, tasha_pinctl_mode_put), + + SOC_SINGLE_EXT("DMIC3_DATA_PIN_MODE", SND_SOC_NOPM, 22, 1, 0, + tasha_pinctl_mode_get, tasha_pinctl_mode_put), + SOC_ENUM_EXT("AMIC_1_2 PWR MODE", amic_pwr_lvl_enum, + tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put), + SOC_ENUM_EXT("AMIC_3_4 PWR MODE", amic_pwr_lvl_enum, + tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put), + SOC_ENUM_EXT("AMIC_5_6 PWR MODE", amic_pwr_lvl_enum, + tasha_amic_pwr_lvl_get, tasha_amic_pwr_lvl_put), + + SOC_SINGLE_MULTI_EXT("Vbat ADC data", SND_SOC_NOPM, 0, 0xFFFF, 0, 2, + tasha_vbat_adc_data_get, NULL), + + SOC_ENUM_EXT("GSM mode Enable", tasha_vbat_gsm_mode_enum, + tasha_vbat_gsm_mode_func_get, + tasha_vbat_gsm_mode_func_put), +}; + +static int tasha_put_dec_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val; + u16 mic_sel_reg; + u8 mic_sel; + + val = ucontrol->value.enumerated.item[0]; + if (val > e->items - 1) + return -EINVAL; + + dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + widget->name, val); + + switch (e->reg) { + case WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1: + mic_sel_reg = WCD9335_CDC_TX0_TX_PATH_CFG0; + break; + case WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1: + mic_sel_reg = WCD9335_CDC_TX1_TX_PATH_CFG0; + break; + case WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1: + mic_sel_reg = WCD9335_CDC_TX2_TX_PATH_CFG0; + break; + case WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1: + mic_sel_reg = WCD9335_CDC_TX3_TX_PATH_CFG0; + break; + case WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0: + mic_sel_reg = WCD9335_CDC_TX4_TX_PATH_CFG0; + break; + case WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0: + mic_sel_reg = WCD9335_CDC_TX5_TX_PATH_CFG0; + break; + case WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0: + mic_sel_reg = WCD9335_CDC_TX6_TX_PATH_CFG0; + break; + case WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0: + mic_sel_reg = WCD9335_CDC_TX7_TX_PATH_CFG0; + break; + case WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0: + mic_sel_reg = WCD9335_CDC_TX8_TX_PATH_CFG0; + break; + default: + dev_err(codec->dev, "%s: e->reg: 0x%x not expected\n", + __func__, e->reg); + return -EINVAL; + } + + /* ADC: 0, DMIC: 1 */ + mic_sel = val ? 0x0 : 0x1; + snd_soc_update_bits(codec, mic_sel_reg, 1 << 7, mic_sel << 7); + + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +static int tasha_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val; + unsigned short look_ahead_dly_reg = WCD9335_CDC_RX0_RX_PATH_CFG0; + + val = ucontrol->value.enumerated.item[0]; + if (val >= e->items) + return -EINVAL; + + dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + widget->name, val); + + if (e->reg == WCD9335_CDC_RX0_RX_PATH_SEC0) + look_ahead_dly_reg = WCD9335_CDC_RX0_RX_PATH_CFG0; + else if (e->reg == WCD9335_CDC_RX1_RX_PATH_SEC0) + look_ahead_dly_reg = WCD9335_CDC_RX1_RX_PATH_CFG0; + else if (e->reg == WCD9335_CDC_RX2_RX_PATH_SEC0) + look_ahead_dly_reg = WCD9335_CDC_RX2_RX_PATH_CFG0; + + /* Set Look Ahead Delay */ + snd_soc_update_bits(codec, look_ahead_dly_reg, + 0x08, (val ? 0x08 : 0x00)); + /* Set DEM INP Select */ + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +static int tasha_ear_pa_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 ear_pa_gain; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + ear_pa_gain = snd_soc_read(codec, WCD9335_ANA_EAR); + + ear_pa_gain = (ear_pa_gain & 0x70) >> 4; + + ucontrol->value.integer.value[0] = ear_pa_gain; + + dev_dbg(codec->dev, "%s: ear_pa_gain = 0x%x\n", __func__, + ear_pa_gain); + + return 0; +} + +static int tasha_ear_pa_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 ear_pa_gain; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + ear_pa_gain = ucontrol->value.integer.value[0] << 4; + + snd_soc_update_bits(codec, WCD9335_ANA_EAR, 0x70, ear_pa_gain); + return 0; +} + +static int tasha_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = tasha->ear_spkr_gain; + + dev_dbg(codec->dev, "%s: ear_spkr_gain = %ld\n", __func__, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int tasha_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + tasha->ear_spkr_gain = ucontrol->value.integer.value[0]; + + return 0; +} + +static int tasha_config_compander(struct snd_soc_codec *codec, int interp_n, + int event) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + int comp; + u16 comp_ctl0_reg, rx_path_cfg0_reg; + + /* EAR does not have compander */ + if (!interp_n) + return 0; + + comp = interp_n - 1; + dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n", + __func__, event, comp + 1, tasha->comp_enabled[comp]); + + if (!tasha->comp_enabled[comp]) + return 0; + + comp_ctl0_reg = WCD9335_CDC_COMPANDER1_CTL0 + (comp * 8); + rx_path_cfg0_reg = WCD9335_CDC_RX1_RX_PATH_CFG0 + (comp * 20); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Compander Clock */ + snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); + snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); + } + + return 0; +} + +static int tasha_codec_config_mad(struct snd_soc_codec *codec) +{ + int ret = 0; + int idx; + const struct firmware *fw; + struct firmware_cal *hwdep_cal = NULL; + struct wcd_mad_audio_cal *mad_cal = NULL; + const void *data; + const char *filename = TASHA_MAD_AUDIO_FIRMWARE_PATH; + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + size_t cal_size; + + hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_MAD_CAL); + if (hwdep_cal) { + data = hwdep_cal->data; + cal_size = hwdep_cal->size; + dev_dbg(codec->dev, "%s: using hwdep calibration\n", + __func__); + } else { + ret = request_firmware(&fw, filename, codec->dev); + if (ret || !fw) { + dev_err(codec->dev, + "%s: MAD firmware acquire failed, err = %d\n", + __func__, ret); + return -ENODEV; + } + data = fw->data; + cal_size = fw->size; + dev_dbg(codec->dev, "%s: using request_firmware calibration\n", + __func__); + } + + if (cal_size < sizeof(*mad_cal)) { + dev_err(codec->dev, + "%s: Incorrect size %zd for MAD Cal, expected %zd\n", + __func__, cal_size, sizeof(*mad_cal)); + ret = -ENOMEM; + goto done; + } + + mad_cal = (struct wcd_mad_audio_cal *) (data); + if (!mad_cal) { + dev_err(codec->dev, + "%s: Invalid calibration data\n", + __func__); + ret = -EINVAL; + goto done; + } + + snd_soc_write(codec, WCD9335_SOC_MAD_MAIN_CTL_2, + mad_cal->microphone_info.cycle_time); + snd_soc_update_bits(codec, WCD9335_SOC_MAD_MAIN_CTL_1, 0xFF << 3, + ((uint16_t)mad_cal->microphone_info.settle_time) + << 3); + + /* Audio */ + snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_8, + mad_cal->audio_info.rms_omit_samples); + snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_CTL_1, + 0x07 << 4, mad_cal->audio_info.rms_comp_time << 4); + snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03 << 2, + mad_cal->audio_info.detection_mechanism << 2); + snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_7, + mad_cal->audio_info.rms_diff_threshold & 0x3F); + snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_5, + mad_cal->audio_info.rms_threshold_lsb); + snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_6, + mad_cal->audio_info.rms_threshold_msb); + + for (idx = 0; idx < ARRAY_SIZE(mad_cal->audio_info.iir_coefficients); + idx++) { + snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_IIR_CTL_PTR, + 0x3F, idx); + snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_IIR_CTL_VAL, + mad_cal->audio_info.iir_coefficients[idx]); + dev_dbg(codec->dev, "%s:MAD Audio IIR Coef[%d] = 0X%x", + __func__, idx, + mad_cal->audio_info.iir_coefficients[idx]); + } + + /* Beacon */ + snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_8, + mad_cal->beacon_info.rms_omit_samples); + snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_CTL_1, + 0x07 << 4, mad_cal->beacon_info.rms_comp_time << 4); + snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_CTL_2, 0x03 << 2, + mad_cal->beacon_info.detection_mechanism << 2); + snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_7, + mad_cal->beacon_info.rms_diff_threshold & 0x1F); + snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_5, + mad_cal->beacon_info.rms_threshold_lsb); + snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_6, + mad_cal->beacon_info.rms_threshold_msb); + + for (idx = 0; idx < ARRAY_SIZE(mad_cal->beacon_info.iir_coefficients); + idx++) { + snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_IIR_CTL_PTR, + 0x3F, idx); + snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_IIR_CTL_VAL, + mad_cal->beacon_info.iir_coefficients[idx]); + dev_dbg(codec->dev, "%s:MAD Beacon IIR Coef[%d] = 0X%x", + __func__, idx, + mad_cal->beacon_info.iir_coefficients[idx]); + } + + /* Ultrasound */ + snd_soc_update_bits(codec, WCD9335_SOC_MAD_ULTR_CTL_1, + 0x07 << 4, + mad_cal->ultrasound_info.rms_comp_time << 4); + snd_soc_update_bits(codec, WCD9335_SOC_MAD_ULTR_CTL_2, 0x03 << 2, + mad_cal->ultrasound_info.detection_mechanism << 2); + snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_7, + mad_cal->ultrasound_info.rms_diff_threshold & 0x1F); + snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_5, + mad_cal->ultrasound_info.rms_threshold_lsb); + snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_6, + mad_cal->ultrasound_info.rms_threshold_msb); + +done: + if (!hwdep_cal) + release_firmware(fw); + + return ret; +} + +static int tasha_codec_enable_mad(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int ret = 0; + + dev_dbg(codec->dev, + "%s: event = %d\n", __func__, event); + + /* Return if CPE INPUT is DEC1 */ + if (snd_soc_read(codec, WCD9335_CPE_SS_SVA_CFG) & 0x01) + return ret; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + + /* Turn on MAD clk */ + snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL, + 0x01, 0x01); + + /* Undo reset for MAD */ + snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL, + 0x02, 0x00); + ret = tasha_codec_config_mad(codec); + if (ret) + dev_err(codec->dev, + "%s: Failed to config MAD, err = %d\n", + __func__, ret); + break; + case SND_SOC_DAPM_POST_PMD: + /* Reset the MAD block */ + snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL, + 0x02, 0x02); + /* Turn off MAD clk */ + snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL, + 0x01, 0x00); + break; + } + + return ret; +} + +static int tasha_codec_configure_cpe_input(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, + "%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Configure CPE input as DEC1 */ + snd_soc_update_bits(codec, WCD9335_CPE_SS_SVA_CFG, + 0x01, 0x01); + + /* Configure DEC1 Tx out with sample rate as 16K */ + snd_soc_update_bits(codec, WCD9335_CDC_TX1_TX_PATH_CTL, + 0x0F, 0x01); + + break; + case SND_SOC_DAPM_POST_PMD: + /* Reset DEC1 Tx out sample rate */ + snd_soc_update_bits(codec, WCD9335_CDC_TX1_TX_PATH_CTL, + 0x0F, 0x04); + snd_soc_update_bits(codec, WCD9335_CPE_SS_SVA_CFG, + 0x01, 0x00); + + break; + } + + return 0; +} + + +static int tasha_codec_aif4_mixer_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + + if (test_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask)) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; + + dev_dbg(codec->dev, "%s: AIF4 switch value = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int tasha_codec_aif4_mixer_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_update *update = NULL; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: AIF4 switch value = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + if (ucontrol->value.integer.value[0]) { + snd_soc_dapm_mixer_update_power(widget->dapm, + kcontrol, 1, update); + set_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask); + } else { + snd_soc_dapm_mixer_update_power(widget->dapm, + kcontrol, 0, update); + clear_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask); + } + + return 1; +} + +static const char * const tasha_ear_pa_gain_text[] = { + "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB", + "G_0_DB", "G_M2P5_DB", "UNDEFINED", "G_M12_DB" +}; + +static const char * const tasha_ear_spkr_pa_gain_text[] = { + "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB", "G_4_DB", + "G_5_DB", "G_6_DB" +}; + +static const struct soc_enum tasha_ear_pa_gain_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_ear_pa_gain_text), + tasha_ear_pa_gain_text); + +static const struct soc_enum tasha_ear_spkr_pa_gain_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_ear_spkr_pa_gain_text), + tasha_ear_spkr_pa_gain_text); + +static const struct snd_kcontrol_new tasha_analog_gain_controls[] = { + SOC_ENUM_EXT("EAR PA Gain", tasha_ear_pa_gain_enum, + tasha_ear_pa_gain_get, tasha_ear_pa_gain_put), + + SOC_ENUM_EXT("EAR SPKR PA Gain", tasha_ear_spkr_pa_gain_enum, + tasha_ear_spkr_pa_gain_get, tasha_ear_spkr_pa_gain_put), + + SOC_SINGLE_TLV("HPHL Volume", WCD9335_HPH_L_EN, 0, 20, 1, + line_gain), + SOC_SINGLE_TLV("HPHR Volume", WCD9335_HPH_R_EN, 0, 20, 1, + line_gain), + SOC_SINGLE_TLV("LINEOUT1 Volume", WCD9335_DIFF_LO_LO1_COMPANDER, + 3, 16, 1, line_gain), + SOC_SINGLE_TLV("LINEOUT2 Volume", WCD9335_DIFF_LO_LO2_COMPANDER, + 3, 16, 1, line_gain), + SOC_SINGLE_TLV("LINEOUT3 Volume", WCD9335_SE_LO_LO3_GAIN, 0, 20, 1, + line_gain), + SOC_SINGLE_TLV("LINEOUT4 Volume", WCD9335_SE_LO_LO4_GAIN, 0, 20, 1, + line_gain), + + SOC_SINGLE_TLV("ADC1 Volume", WCD9335_ANA_AMIC1, 0, 20, 0, + analog_gain), + SOC_SINGLE_TLV("ADC2 Volume", WCD9335_ANA_AMIC2, 0, 20, 0, + analog_gain), + SOC_SINGLE_TLV("ADC3 Volume", WCD9335_ANA_AMIC3, 0, 20, 0, + analog_gain), + SOC_SINGLE_TLV("ADC4 Volume", WCD9335_ANA_AMIC4, 0, 20, 0, + analog_gain), + SOC_SINGLE_TLV("ADC5 Volume", WCD9335_ANA_AMIC5, 0, 20, 0, + analog_gain), + SOC_SINGLE_TLV("ADC6 Volume", WCD9335_ANA_AMIC6, 0, 20, 0, + analog_gain), +}; + +static const char * const spl_src0_mux_text[] = { + "ZERO", "SRC_IN_HPHL", "SRC_IN_LO1", +}; + +static const char * const spl_src1_mux_text[] = { + "ZERO", "SRC_IN_HPHR", "SRC_IN_LO2", +}; + +static const char * const spl_src2_mux_text[] = { + "ZERO", "SRC_IN_LO3", "SRC_IN_SPKRL", +}; + +static const char * const spl_src3_mux_text[] = { + "ZERO", "SRC_IN_LO4", "SRC_IN_SPKRR", +}; + +static const char * const rx_int0_7_mix_mux_text[] = { + "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", + "RX6", "RX7", "PROXIMITY" +}; + +static const char * const rx_int_mix_mux_text[] = { + "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", + "RX6", "RX7" +}; + +static const char * const rx_prim_mix_text[] = { + "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2", + "RX3", "RX4", "RX5", "RX6", "RX7" +}; + +static const char * const rx_sidetone_mix_text[] = { + "ZERO", "SRC0", "SRC1", "SRC_SUM" +}; + +static const char * const sb_tx0_mux_text[] = { + "ZERO", "RX_MIX_TX0", "DEC0", "DEC0_192" +}; + +static const char * const sb_tx1_mux_text[] = { + "ZERO", "RX_MIX_TX1", "DEC1", "DEC1_192" +}; + +static const char * const sb_tx2_mux_text[] = { + "ZERO", "RX_MIX_TX2", "DEC2", "DEC2_192" +}; + +static const char * const sb_tx3_mux_text[] = { + "ZERO", "RX_MIX_TX3", "DEC3", "DEC3_192" +}; + +static const char * const sb_tx4_mux_text[] = { + "ZERO", "RX_MIX_TX4", "DEC4", "DEC4_192" +}; + +static const char * const sb_tx5_mux_text[] = { + "ZERO", "RX_MIX_TX5", "DEC5", "DEC5_192" +}; + +static const char * const sb_tx6_mux_text[] = { + "ZERO", "RX_MIX_TX6", "DEC6", "DEC6_192" +}; + +static const char * const sb_tx7_mux_text[] = { + "ZERO", "RX_MIX_TX7", "DEC7", "DEC7_192" +}; + +static const char * const sb_tx8_mux_text[] = { + "ZERO", "RX_MIX_TX8", "DEC8", "DEC8_192" +}; + +static const char * const sb_tx9_mux_text[] = { + "ZERO", "DEC7", "DEC7_192" +}; + +static const char * const sb_tx10_mux_text[] = { + "ZERO", "DEC6", "DEC6_192" +}; + +static const char * const sb_tx11_mux_text[] = { + "DEC_0_5", "DEC_9_12", "MAD_AUDIO", "MAD_BRDCST" +}; + +static const char * const sb_tx11_inp1_mux_text[] = { + "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", + "DEC5", "RX_MIX_TX5", "DEC9_10", "DEC11_12" +}; + +static const char * const sb_tx13_mux_text[] = { + "ZERO", "DEC5", "DEC5_192" +}; + +static const char * const tx13_inp_mux_text[] = { + "CDC_DEC_5", "MAD_BRDCST", "CPE_TX_PP" +}; + +static const char * const iir_inp_mux_text[] = { + "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", + "DEC7", "DEC8", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7" +}; + +static const char * const rx_int_dem_inp_mux_text[] = { + "NORMAL_DSM_OUT", "CLSH_DSM_OUT", +}; + +static const char * const rx_int0_interp_mux_text[] = { + "ZERO", "RX INT0 MIX2", +}; + +static const char * const rx_int1_interp_mux_text[] = { + "ZERO", "RX INT1 MIX2", +}; + +static const char * const rx_int2_interp_mux_text[] = { + "ZERO", "RX INT2 MIX2", +}; + +static const char * const rx_int3_interp_mux_text[] = { + "ZERO", "RX INT3 MIX2", +}; + +static const char * const rx_int4_interp_mux_text[] = { + "ZERO", "RX INT4 MIX2", +}; + +static const char * const rx_int5_interp_mux_text[] = { + "ZERO", "RX INT5 MIX2", +}; + +static const char * const rx_int6_interp_mux_text[] = { + "ZERO", "RX INT6 MIX2", +}; + +static const char * const rx_int7_interp_mux_text[] = { + "ZERO", "RX INT7 MIX2", +}; + +static const char * const rx_int8_interp_mux_text[] = { + "ZERO", "RX INT8 SEC MIX" +}; + +static const char * const mad_sel_text[] = { + "SPE", "MSM" +}; + +static const char * const adc_mux_text[] = { + "DMIC", "AMIC", "ANC_FB_TUNE1", "ANC_FB_TUNE2" +}; + +static const char * const dmic_mux_text[] = { + "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", + "SMIC0", "SMIC1", "SMIC2", "SMIC3" +}; + +static const char * const dmic_mux_alt_text[] = { + "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", +}; + +static const char * const amic_mux_text[] = { + "ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6" +}; + +static const char * const rx_echo_mux_text[] = { + "ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2", "RX_MIX3", "RX_MIX4", + "RX_MIX5", "RX_MIX6", "RX_MIX7", "RX_MIX8", "RX_MIX_VBAT5", + "RX_MIX_VBAT6", "RX_MIX_VBAT7", "RX_MIX_VBAT8" +}; + +static const char * const anc0_fb_mux_text[] = { + "ZERO", "ANC_IN_HPHL", "ANC_IN_EAR", "ANC_IN_EAR_SPKR", + "ANC_IN_LO1" +}; + +static const char * const anc1_fb_mux_text[] = { + "ZERO", "ANC_IN_HPHR", "ANC_IN_LO2" +}; + +static const char * const native_mux_text[] = { + "OFF", "ON", +}; + +static const struct soc_enum spl_src0_mux_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 0, 3, + spl_src0_mux_text); + +static const struct soc_enum spl_src1_mux_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 2, 3, + spl_src1_mux_text); + +static const struct soc_enum spl_src2_mux_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 4, 3, + spl_src2_mux_text); + +static const struct soc_enum spl_src3_mux_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0, 6, 3, + spl_src3_mux_text); + +static const struct soc_enum rx_int0_2_mux_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, 10, + rx_int0_7_mix_mux_text); + +static const struct soc_enum rx_int1_2_mux_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, 9, + rx_int_mix_mux_text); + +static const struct soc_enum rx_int2_2_mux_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, 9, + rx_int_mix_mux_text); + +static const struct soc_enum rx_int3_2_mux_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 0, 9, + rx_int_mix_mux_text); + +static const struct soc_enum rx_int4_2_mux_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 0, 9, + rx_int_mix_mux_text); + +static const struct soc_enum rx_int5_2_mux_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 0, 9, + rx_int_mix_mux_text); + +static const struct soc_enum rx_int6_2_mux_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 0, 9, + rx_int_mix_mux_text); + +static const struct soc_enum rx_int7_2_mux_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 0, 10, + rx_int0_7_mix_mux_text); + +static const struct soc_enum rx_int8_2_mux_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 0, 9, + rx_int_mix_mux_text); + +static const struct soc_enum int1_1_native_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text), + native_mux_text); + +static const struct soc_enum int2_1_native_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text), + native_mux_text); + +static const struct soc_enum int3_1_native_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text), + native_mux_text); + +static const struct soc_enum int4_1_native_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(native_mux_text), + native_mux_text); + +static const struct soc_enum rx_int0_1_mix_inp0_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 0, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int0_1_mix_inp1_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int0_1_mix_inp2_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int1_1_mix_inp0_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 0, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int1_1_mix_inp1_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int1_1_mix_inp2_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int2_1_mix_inp0_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int2_1_mix_inp1_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int2_1_mix_inp2_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int3_1_mix_inp0_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 0, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int3_1_mix_inp1_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int3_1_mix_inp2_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int4_1_mix_inp0_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 0, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int4_1_mix_inp1_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int4_1_mix_inp2_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int5_1_mix_inp0_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 0, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int5_1_mix_inp1_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int5_1_mix_inp2_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int6_1_mix_inp0_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 0, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int6_1_mix_inp1_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int6_1_mix_inp2_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int7_1_mix_inp0_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 0, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int7_1_mix_inp1_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int7_1_mix_inp2_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int8_1_mix_inp0_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 0, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int8_1_mix_inp1_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int8_1_mix_inp2_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 4, 13, + rx_prim_mix_text); + +static const struct soc_enum rx_int0_sidetone_mix_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0, 4, + rx_sidetone_mix_text); + +static const struct soc_enum rx_int1_sidetone_mix_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2, 4, + rx_sidetone_mix_text); + +static const struct soc_enum rx_int2_sidetone_mix_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4, 4, + rx_sidetone_mix_text); + +static const struct soc_enum rx_int3_sidetone_mix_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6, 4, + rx_sidetone_mix_text); + +static const struct soc_enum rx_int4_sidetone_mix_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 0, 4, + rx_sidetone_mix_text); + +static const struct soc_enum rx_int7_sidetone_mix_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 2, 4, + rx_sidetone_mix_text); + +static const struct soc_enum tx_adc_mux0_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0, 4, + adc_mux_text); + +static const struct soc_enum tx_adc_mux1_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0, 4, + adc_mux_text); + +static const struct soc_enum tx_adc_mux2_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0, 4, + adc_mux_text); + +static const struct soc_enum tx_adc_mux3_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0, 4, + adc_mux_text); + +static const struct soc_enum tx_adc_mux4_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 6, 4, + adc_mux_text); + +static const struct soc_enum tx_adc_mux5_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 6, 4, + adc_mux_text); + +static const struct soc_enum tx_adc_mux6_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 6, 4, + adc_mux_text); + +static const struct soc_enum tx_adc_mux7_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 6, 4, + adc_mux_text); + +static const struct soc_enum tx_adc_mux8_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 6, 4, + adc_mux_text); + +static const struct soc_enum tx_adc_mux10_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 6, 4, + adc_mux_text); + +static const struct soc_enum tx_adc_mux11_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 6, 4, + adc_mux_text); + +static const struct soc_enum tx_adc_mux12_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 6, 4, + adc_mux_text); + +static const struct soc_enum tx_adc_mux13_chain_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 6, 4, + adc_mux_text); + +static const struct soc_enum tx_dmic_mux0_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 3, 11, + dmic_mux_text); + +static const struct soc_enum tx_dmic_mux1_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 3, 11, + dmic_mux_text); + +static const struct soc_enum tx_dmic_mux2_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 3, 11, + dmic_mux_text); + +static const struct soc_enum tx_dmic_mux3_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 3, 11, + dmic_mux_text); + +static const struct soc_enum tx_dmic_mux4_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 3, 7, + dmic_mux_alt_text); + +static const struct soc_enum tx_dmic_mux5_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 3, 7, + dmic_mux_alt_text); + +static const struct soc_enum tx_dmic_mux6_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 3, 7, + dmic_mux_alt_text); + +static const struct soc_enum tx_dmic_mux7_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 3, 7, + dmic_mux_alt_text); + +static const struct soc_enum tx_dmic_mux8_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 3, 7, + dmic_mux_alt_text); + +static const struct soc_enum tx_dmic_mux10_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 3, 7, + dmic_mux_alt_text); + +static const struct soc_enum tx_dmic_mux11_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 3, 7, + dmic_mux_alt_text); + +static const struct soc_enum tx_dmic_mux12_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 3, 7, + dmic_mux_alt_text); + +static const struct soc_enum tx_dmic_mux13_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 3, 7, + dmic_mux_alt_text); + +static const struct soc_enum tx_amic_mux0_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0, 7, + amic_mux_text); + +static const struct soc_enum tx_amic_mux1_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0, 7, + amic_mux_text); + +static const struct soc_enum tx_amic_mux2_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0, 7, + amic_mux_text); + +static const struct soc_enum tx_amic_mux3_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0, 7, + amic_mux_text); + +static const struct soc_enum tx_amic_mux4_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0, 7, + amic_mux_text); + +static const struct soc_enum tx_amic_mux5_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0, 7, + amic_mux_text); + +static const struct soc_enum tx_amic_mux6_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0, 7, + amic_mux_text); + +static const struct soc_enum tx_amic_mux7_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0, 7, + amic_mux_text); + +static const struct soc_enum tx_amic_mux8_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0, 7, + amic_mux_text); + +static const struct soc_enum tx_amic_mux10_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0, 7, + amic_mux_text); + +static const struct soc_enum tx_amic_mux11_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0, 7, + amic_mux_text); + +static const struct soc_enum tx_amic_mux12_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 0, 7, + amic_mux_text); + +static const struct soc_enum tx_amic_mux13_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 0, 7, + amic_mux_text); + +static const struct soc_enum sb_tx0_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 0, 4, + sb_tx0_mux_text); + +static const struct soc_enum sb_tx1_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 2, 4, + sb_tx1_mux_text); + +static const struct soc_enum sb_tx2_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 4, 4, + sb_tx2_mux_text); + +static const struct soc_enum sb_tx3_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 6, 4, + sb_tx3_mux_text); + +static const struct soc_enum sb_tx4_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 0, 4, + sb_tx4_mux_text); + +static const struct soc_enum sb_tx5_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 2, 4, + sb_tx5_mux_text); + +static const struct soc_enum sb_tx6_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 4, 4, + sb_tx6_mux_text); + +static const struct soc_enum sb_tx7_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 6, 4, + sb_tx7_mux_text); + +static const struct soc_enum sb_tx8_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 0, 4, + sb_tx8_mux_text); + +static const struct soc_enum sb_tx9_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 2, 3, + sb_tx9_mux_text); + +static const struct soc_enum sb_tx10_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 4, 3, + sb_tx10_mux_text); + +static const struct soc_enum sb_tx11_mux_enum = + SOC_ENUM_SINGLE(WCD9335_DATA_HUB_DATA_HUB_SB_TX11_INP_CFG, 0, 4, + sb_tx11_mux_text); + +static const struct soc_enum sb_tx11_inp1_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3, 0, 10, + sb_tx11_inp1_mux_text); + +static const struct soc_enum sb_tx13_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3, 4, 3, + sb_tx13_mux_text); + +static const struct soc_enum tx13_inp_mux_enum = + SOC_ENUM_SINGLE(WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG, 0, 3, + tx13_inp_mux_text); + +static const struct soc_enum rx_mix_tx0_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG0, 0, 14, + rx_echo_mux_text); + +static const struct soc_enum rx_mix_tx1_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG0, 4, 14, + rx_echo_mux_text); + +static const struct soc_enum rx_mix_tx2_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG1, 0, 14, + rx_echo_mux_text); + +static const struct soc_enum rx_mix_tx3_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG1, 4, 14, + rx_echo_mux_text); + +static const struct soc_enum rx_mix_tx4_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG2, 0, 14, + rx_echo_mux_text); + +static const struct soc_enum rx_mix_tx5_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG2, 4, 14, + rx_echo_mux_text); + +static const struct soc_enum rx_mix_tx6_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG3, 0, 14, + rx_echo_mux_text); + +static const struct soc_enum rx_mix_tx7_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG3, 4, 14, + rx_echo_mux_text); + +static const struct soc_enum rx_mix_tx8_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, 14, + rx_echo_mux_text); + +static const struct soc_enum iir0_inp0_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0, 18, + iir_inp_mux_text); + +static const struct soc_enum iir0_inp1_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1, 0, 18, + iir_inp_mux_text); + +static const struct soc_enum iir0_inp2_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2, 0, 18, + iir_inp_mux_text); + +static const struct soc_enum iir0_inp3_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3, 0, 18, + iir_inp_mux_text); + +static const struct soc_enum iir1_inp0_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0, 0, 18, + iir_inp_mux_text); + +static const struct soc_enum iir1_inp1_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1, 0, 18, + iir_inp_mux_text); + +static const struct soc_enum iir1_inp2_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2, 0, 18, + iir_inp_mux_text); + +static const struct soc_enum iir1_inp3_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3, 0, 18, + iir_inp_mux_text); + +static const struct soc_enum rx_int0_dem_inp_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_SEC0, 0, + ARRAY_SIZE(rx_int_dem_inp_mux_text), + rx_int_dem_inp_mux_text); + +static const struct soc_enum rx_int1_dem_inp_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_SEC0, 0, + ARRAY_SIZE(rx_int_dem_inp_mux_text), + rx_int_dem_inp_mux_text); + +static const struct soc_enum rx_int2_dem_inp_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_SEC0, 0, + ARRAY_SIZE(rx_int_dem_inp_mux_text), + rx_int_dem_inp_mux_text); + +static const struct soc_enum rx_int0_interp_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CTL, 5, 2, + rx_int0_interp_mux_text); + +static const struct soc_enum rx_int1_interp_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CTL, 5, 2, + rx_int1_interp_mux_text); + +static const struct soc_enum rx_int2_interp_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CTL, 5, 2, + rx_int2_interp_mux_text); + +static const struct soc_enum rx_int3_interp_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CTL, 5, 2, + rx_int3_interp_mux_text); + +static const struct soc_enum rx_int4_interp_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CTL, 5, 2, + rx_int4_interp_mux_text); + +static const struct soc_enum rx_int5_interp_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CTL, 5, 2, + rx_int5_interp_mux_text); + +static const struct soc_enum rx_int6_interp_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CTL, 5, 2, + rx_int6_interp_mux_text); + +static const struct soc_enum rx_int7_interp_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CTL, 5, 2, + rx_int7_interp_mux_text); + +static const struct soc_enum rx_int8_interp_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CTL, 5, 2, + rx_int8_interp_mux_text); + +static const struct soc_enum mad_sel_enum = + SOC_ENUM_SINGLE(WCD9335_CPE_SS_CFG, 0, 2, mad_sel_text); + +static const struct soc_enum anc0_fb_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_ANC_CFG0, 0, 5, + anc0_fb_mux_text); + +static const struct soc_enum anc1_fb_mux_enum = + SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_ANC_CFG0, 3, 3, + anc1_fb_mux_text); + +static const struct snd_kcontrol_new rx_int0_dem_inp_mux = + SOC_DAPM_ENUM_EXT("RX INT0 DEM MUX Mux", rx_int0_dem_inp_mux_enum, + snd_soc_dapm_get_enum_double, + tasha_int_dem_inp_mux_put); + +static const struct snd_kcontrol_new rx_int1_dem_inp_mux = + SOC_DAPM_ENUM_EXT("RX INT1 DEM MUX Mux", rx_int1_dem_inp_mux_enum, + snd_soc_dapm_get_enum_double, + tasha_int_dem_inp_mux_put); + +static const struct snd_kcontrol_new rx_int2_dem_inp_mux = + SOC_DAPM_ENUM_EXT("RX INT2 DEM MUX Mux", rx_int2_dem_inp_mux_enum, + snd_soc_dapm_get_enum_double, + tasha_int_dem_inp_mux_put); + +static const struct snd_kcontrol_new spl_src0_mux = + SOC_DAPM_ENUM("SPL SRC0 MUX Mux", spl_src0_mux_chain_enum); + +static const struct snd_kcontrol_new spl_src1_mux = + SOC_DAPM_ENUM("SPL SRC1 MUX Mux", spl_src1_mux_chain_enum); + +static const struct snd_kcontrol_new spl_src2_mux = + SOC_DAPM_ENUM("SPL SRC2 MUX Mux", spl_src2_mux_chain_enum); + +static const struct snd_kcontrol_new spl_src3_mux = + SOC_DAPM_ENUM("SPL SRC3 MUX Mux", spl_src3_mux_chain_enum); + +static const struct snd_kcontrol_new rx_int0_2_mux = + SOC_DAPM_ENUM("RX INT0_2 MUX Mux", rx_int0_2_mux_chain_enum); + +static const struct snd_kcontrol_new rx_int1_2_mux = + SOC_DAPM_ENUM("RX INT1_2 MUX Mux", rx_int1_2_mux_chain_enum); + +static const struct snd_kcontrol_new rx_int2_2_mux = + SOC_DAPM_ENUM("RX INT2_2 MUX Mux", rx_int2_2_mux_chain_enum); + +static const struct snd_kcontrol_new rx_int3_2_mux = + SOC_DAPM_ENUM("RX INT3_2 MUX Mux", rx_int3_2_mux_chain_enum); + +static const struct snd_kcontrol_new rx_int4_2_mux = + SOC_DAPM_ENUM("RX INT4_2 MUX Mux", rx_int4_2_mux_chain_enum); + +static const struct snd_kcontrol_new rx_int5_2_mux = + SOC_DAPM_ENUM("RX INT5_2 MUX Mux", rx_int5_2_mux_chain_enum); + +static const struct snd_kcontrol_new rx_int6_2_mux = + SOC_DAPM_ENUM("RX INT6_2 MUX Mux", rx_int6_2_mux_chain_enum); + +static const struct snd_kcontrol_new rx_int7_2_mux = + SOC_DAPM_ENUM("RX INT7_2 MUX Mux", rx_int7_2_mux_chain_enum); + +static const struct snd_kcontrol_new rx_int8_2_mux = + SOC_DAPM_ENUM("RX INT8_2 MUX Mux", rx_int8_2_mux_chain_enum); + +static const struct snd_kcontrol_new int1_1_native_mux = + SOC_DAPM_ENUM("RX INT1_1 NATIVE MUX Mux", int1_1_native_enum); + +static const struct snd_kcontrol_new int2_1_native_mux = + SOC_DAPM_ENUM("RX INT2_1 NATIVE MUX Mux", int2_1_native_enum); + +static const struct snd_kcontrol_new int3_1_native_mux = + SOC_DAPM_ENUM("RX INT3_1 NATIVE MUX Mux", int3_1_native_enum); + +static const struct snd_kcontrol_new int4_1_native_mux = + SOC_DAPM_ENUM("RX INT4_1 NATIVE MUX Mux", int4_1_native_enum); + +static const struct snd_kcontrol_new rx_int0_1_mix_inp0_mux = + SOC_DAPM_ENUM("RX INT0_1 MIX1 INP0 Mux", rx_int0_1_mix_inp0_chain_enum); + +static const struct snd_kcontrol_new rx_int0_1_mix_inp1_mux = + SOC_DAPM_ENUM("RX INT0_1 MIX1 INP1 Mux", rx_int0_1_mix_inp1_chain_enum); + +static const struct snd_kcontrol_new rx_int0_1_mix_inp2_mux = + SOC_DAPM_ENUM("RX INT0_1 MIX1 INP2 Mux", rx_int0_1_mix_inp2_chain_enum); + +static const struct snd_kcontrol_new rx_int1_1_mix_inp0_mux = + SOC_DAPM_ENUM("RX INT1_1 MIX1 INP0 Mux", rx_int1_1_mix_inp0_chain_enum); + +static const struct snd_kcontrol_new rx_int1_1_mix_inp1_mux = + SOC_DAPM_ENUM("RX INT1_1 MIX1 INP1 Mux", rx_int1_1_mix_inp1_chain_enum); + +static const struct snd_kcontrol_new rx_int1_1_mix_inp2_mux = + SOC_DAPM_ENUM("RX INT1_1 MIX1 INP2 Mux", rx_int1_1_mix_inp2_chain_enum); + +static const struct snd_kcontrol_new rx_int2_1_mix_inp0_mux = + SOC_DAPM_ENUM("RX INT2_1 MIX1 INP0 Mux", rx_int2_1_mix_inp0_chain_enum); + +static const struct snd_kcontrol_new rx_int2_1_mix_inp1_mux = + SOC_DAPM_ENUM("RX INT2_1 MIX1 INP1 Mux", rx_int2_1_mix_inp1_chain_enum); + +static const struct snd_kcontrol_new rx_int2_1_mix_inp2_mux = + SOC_DAPM_ENUM("RX INT2_1 MIX1 INP2 Mux", rx_int2_1_mix_inp2_chain_enum); + +static const struct snd_kcontrol_new rx_int3_1_mix_inp0_mux = + SOC_DAPM_ENUM("RX INT3_1 MIX1 INP0 Mux", rx_int3_1_mix_inp0_chain_enum); + +static const struct snd_kcontrol_new rx_int3_1_mix_inp1_mux = + SOC_DAPM_ENUM("RX INT3_1 MIX1 INP1 Mux", rx_int3_1_mix_inp1_chain_enum); + +static const struct snd_kcontrol_new rx_int3_1_mix_inp2_mux = + SOC_DAPM_ENUM("RX INT3_1 MIX1 INP2 Mux", rx_int3_1_mix_inp2_chain_enum); + +static const struct snd_kcontrol_new rx_int4_1_mix_inp0_mux = + SOC_DAPM_ENUM("RX INT4_1 MIX1 INP0 Mux", rx_int4_1_mix_inp0_chain_enum); + +static const struct snd_kcontrol_new rx_int4_1_mix_inp1_mux = + SOC_DAPM_ENUM("RX INT4_1 MIX1 INP1 Mux", rx_int4_1_mix_inp1_chain_enum); + +static const struct snd_kcontrol_new rx_int4_1_mix_inp2_mux = + SOC_DAPM_ENUM("RX INT4_1 MIX1 INP2 Mux", rx_int4_1_mix_inp2_chain_enum); + +static const struct snd_kcontrol_new rx_int5_1_mix_inp0_mux = + SOC_DAPM_ENUM("RX INT5_1 MIX1 INP0 Mux", rx_int5_1_mix_inp0_chain_enum); + +static const struct snd_kcontrol_new rx_int5_1_mix_inp1_mux = + SOC_DAPM_ENUM("RX INT5_1 MIX1 INP1 Mux", rx_int5_1_mix_inp1_chain_enum); + +static const struct snd_kcontrol_new rx_int5_1_mix_inp2_mux = + SOC_DAPM_ENUM("RX INT5_1 MIX1 INP2 Mux", rx_int5_1_mix_inp2_chain_enum); + +static const struct snd_kcontrol_new rx_int6_1_mix_inp0_mux = + SOC_DAPM_ENUM("RX INT6_1 MIX1 INP0 Mux", rx_int6_1_mix_inp0_chain_enum); + +static const struct snd_kcontrol_new rx_int6_1_mix_inp1_mux = + SOC_DAPM_ENUM("RX INT6_1 MIX1 INP1 Mux", rx_int6_1_mix_inp1_chain_enum); + +static const struct snd_kcontrol_new rx_int6_1_mix_inp2_mux = + SOC_DAPM_ENUM("RX INT6_1 MIX1 INP2 Mux", rx_int6_1_mix_inp2_chain_enum); + +static const struct snd_kcontrol_new rx_int7_1_mix_inp0_mux = + SOC_DAPM_ENUM("RX INT7_1 MIX1 INP0 Mux", rx_int7_1_mix_inp0_chain_enum); + +static const struct snd_kcontrol_new rx_int7_1_mix_inp1_mux = + SOC_DAPM_ENUM("RX INT7_1 MIX1 INP1 Mux", rx_int7_1_mix_inp1_chain_enum); + +static const struct snd_kcontrol_new rx_int7_1_mix_inp2_mux = + SOC_DAPM_ENUM("RX INT7_1 MIX1 INP2 Mux", rx_int7_1_mix_inp2_chain_enum); + +static const struct snd_kcontrol_new rx_int8_1_mix_inp0_mux = + SOC_DAPM_ENUM("RX INT8_1 MIX1 INP0 Mux", rx_int8_1_mix_inp0_chain_enum); + +static const struct snd_kcontrol_new rx_int8_1_mix_inp1_mux = + SOC_DAPM_ENUM("RX INT8_1 MIX1 INP1 Mux", rx_int8_1_mix_inp1_chain_enum); + +static const struct snd_kcontrol_new rx_int8_1_mix_inp2_mux = + SOC_DAPM_ENUM("RX INT8_1 MIX1 INP2 Mux", rx_int8_1_mix_inp2_chain_enum); + +static const struct snd_kcontrol_new rx_int0_mix2_inp_mux = + SOC_DAPM_ENUM("RX INT0 MIX2 INP Mux", rx_int0_sidetone_mix_chain_enum); + +static const struct snd_kcontrol_new rx_int1_mix2_inp_mux = + SOC_DAPM_ENUM("RX INT1 MIX2 INP Mux", rx_int1_sidetone_mix_chain_enum); + +static const struct snd_kcontrol_new rx_int2_mix2_inp_mux = + SOC_DAPM_ENUM("RX INT2 MIX2 INP Mux", rx_int2_sidetone_mix_chain_enum); + +static const struct snd_kcontrol_new rx_int3_mix2_inp_mux = + SOC_DAPM_ENUM("RX INT3 MIX2 INP Mux", rx_int3_sidetone_mix_chain_enum); + +static const struct snd_kcontrol_new rx_int4_mix2_inp_mux = + SOC_DAPM_ENUM("RX INT4 MIX2 INP Mux", rx_int4_sidetone_mix_chain_enum); + +static const struct snd_kcontrol_new rx_int7_mix2_inp_mux = + SOC_DAPM_ENUM("RX INT7 MIX2 INP Mux", rx_int7_sidetone_mix_chain_enum); + +static const struct snd_kcontrol_new tx_adc_mux0 = + SOC_DAPM_ENUM_EXT("ADC MUX0 Mux", tx_adc_mux0_chain_enum, + snd_soc_dapm_get_enum_double, + tasha_put_dec_enum); + +static const struct snd_kcontrol_new tx_adc_mux1 = + SOC_DAPM_ENUM_EXT("ADC MUX1 Mux", tx_adc_mux1_chain_enum, + snd_soc_dapm_get_enum_double, + tasha_put_dec_enum); + +static const struct snd_kcontrol_new tx_adc_mux2 = + SOC_DAPM_ENUM_EXT("ADC MUX2 Mux", tx_adc_mux2_chain_enum, + snd_soc_dapm_get_enum_double, + tasha_put_dec_enum); + +static const struct snd_kcontrol_new tx_adc_mux3 = + SOC_DAPM_ENUM_EXT("ADC MUX3 Mux", tx_adc_mux3_chain_enum, + snd_soc_dapm_get_enum_double, + tasha_put_dec_enum); + +static const struct snd_kcontrol_new tx_adc_mux4 = + SOC_DAPM_ENUM_EXT("ADC MUX4 Mux", tx_adc_mux4_chain_enum, + snd_soc_dapm_get_enum_double, + tasha_put_dec_enum); + +static const struct snd_kcontrol_new tx_adc_mux5 = + SOC_DAPM_ENUM_EXT("ADC MUX5 Mux", tx_adc_mux5_chain_enum, + snd_soc_dapm_get_enum_double, + tasha_put_dec_enum); + +static const struct snd_kcontrol_new tx_adc_mux6 = + SOC_DAPM_ENUM_EXT("ADC MUX6 Mux", tx_adc_mux6_chain_enum, + snd_soc_dapm_get_enum_double, + tasha_put_dec_enum); + +static const struct snd_kcontrol_new tx_adc_mux7 = + SOC_DAPM_ENUM_EXT("ADC MUX7 Mux", tx_adc_mux7_chain_enum, + snd_soc_dapm_get_enum_double, + tasha_put_dec_enum); + +static const struct snd_kcontrol_new tx_adc_mux8 = + SOC_DAPM_ENUM_EXT("ADC MUX8 Mux", tx_adc_mux8_chain_enum, + snd_soc_dapm_get_enum_double, + tasha_put_dec_enum); + +static const struct snd_kcontrol_new tx_adc_mux10 = + SOC_DAPM_ENUM("ADC MUX10 Mux", tx_adc_mux10_chain_enum); + +static const struct snd_kcontrol_new tx_adc_mux11 = + SOC_DAPM_ENUM("ADC MUX11 Mux", tx_adc_mux11_chain_enum); + +static const struct snd_kcontrol_new tx_adc_mux12 = + SOC_DAPM_ENUM("ADC MUX12 Mux", tx_adc_mux12_chain_enum); + +static const struct snd_kcontrol_new tx_adc_mux13 = + SOC_DAPM_ENUM("ADC MUX13 Mux", tx_adc_mux13_chain_enum); + +static const struct snd_kcontrol_new tx_dmic_mux0 = + SOC_DAPM_ENUM("DMIC MUX0 Mux", tx_dmic_mux0_enum); + +static const struct snd_kcontrol_new tx_dmic_mux1 = + SOC_DAPM_ENUM("DMIC MUX1 Mux", tx_dmic_mux1_enum); + +static const struct snd_kcontrol_new tx_dmic_mux2 = + SOC_DAPM_ENUM("DMIC MUX2 Mux", tx_dmic_mux2_enum); + +static const struct snd_kcontrol_new tx_dmic_mux3 = + SOC_DAPM_ENUM("DMIC MUX3 Mux", tx_dmic_mux3_enum); + +static const struct snd_kcontrol_new tx_dmic_mux4 = + SOC_DAPM_ENUM("DMIC MUX4 Mux", tx_dmic_mux4_enum); + +static const struct snd_kcontrol_new tx_dmic_mux5 = + SOC_DAPM_ENUM("DMIC MUX5 Mux", tx_dmic_mux5_enum); + +static const struct snd_kcontrol_new tx_dmic_mux6 = + SOC_DAPM_ENUM("DMIC MUX6 Mux", tx_dmic_mux6_enum); + +static const struct snd_kcontrol_new tx_dmic_mux7 = + SOC_DAPM_ENUM("DMIC MUX7 Mux", tx_dmic_mux7_enum); + +static const struct snd_kcontrol_new tx_dmic_mux8 = + SOC_DAPM_ENUM("DMIC MUX8 Mux", tx_dmic_mux8_enum); + +static const struct snd_kcontrol_new tx_dmic_mux10 = + SOC_DAPM_ENUM("DMIC MUX10 Mux", tx_dmic_mux10_enum); + +static const struct snd_kcontrol_new tx_dmic_mux11 = + SOC_DAPM_ENUM("DMIC MUX11 Mux", tx_dmic_mux11_enum); + +static const struct snd_kcontrol_new tx_dmic_mux12 = + SOC_DAPM_ENUM("DMIC MUX12 Mux", tx_dmic_mux12_enum); + +static const struct snd_kcontrol_new tx_dmic_mux13 = + SOC_DAPM_ENUM("DMIC MUX13 Mux", tx_dmic_mux13_enum); + +static const struct snd_kcontrol_new tx_amic_mux0 = + SOC_DAPM_ENUM("AMIC MUX0 Mux", tx_amic_mux0_enum); + +static const struct snd_kcontrol_new tx_amic_mux1 = + SOC_DAPM_ENUM("AMIC MUX1 Mux", tx_amic_mux1_enum); + +static const struct snd_kcontrol_new tx_amic_mux2 = + SOC_DAPM_ENUM("AMIC MUX2 Mux", tx_amic_mux2_enum); + +static const struct snd_kcontrol_new tx_amic_mux3 = + SOC_DAPM_ENUM("AMIC MUX3 Mux", tx_amic_mux3_enum); + +static const struct snd_kcontrol_new tx_amic_mux4 = + SOC_DAPM_ENUM("AMIC MUX4 Mux", tx_amic_mux4_enum); + +static const struct snd_kcontrol_new tx_amic_mux5 = + SOC_DAPM_ENUM("AMIC MUX5 Mux", tx_amic_mux5_enum); + +static const struct snd_kcontrol_new tx_amic_mux6 = + SOC_DAPM_ENUM("AMIC MUX6 Mux", tx_amic_mux6_enum); + +static const struct snd_kcontrol_new tx_amic_mux7 = + SOC_DAPM_ENUM("AMIC MUX7 Mux", tx_amic_mux7_enum); + +static const struct snd_kcontrol_new tx_amic_mux8 = + SOC_DAPM_ENUM("AMIC MUX8 Mux", tx_amic_mux8_enum); + +static const struct snd_kcontrol_new tx_amic_mux10 = + SOC_DAPM_ENUM("AMIC MUX10 Mux", tx_amic_mux10_enum); + +static const struct snd_kcontrol_new tx_amic_mux11 = + SOC_DAPM_ENUM("AMIC MUX11 Mux", tx_amic_mux11_enum); + +static const struct snd_kcontrol_new tx_amic_mux12 = + SOC_DAPM_ENUM("AMIC MUX12 Mux", tx_amic_mux12_enum); + +static const struct snd_kcontrol_new tx_amic_mux13 = + SOC_DAPM_ENUM("AMIC MUX13 Mux", tx_amic_mux13_enum); + +static const struct snd_kcontrol_new sb_tx0_mux = + SOC_DAPM_ENUM("SLIM TX0 MUX Mux", sb_tx0_mux_enum); + +static const struct snd_kcontrol_new sb_tx1_mux = + SOC_DAPM_ENUM("SLIM TX1 MUX Mux", sb_tx1_mux_enum); + +static const struct snd_kcontrol_new sb_tx2_mux = + SOC_DAPM_ENUM("SLIM TX2 MUX Mux", sb_tx2_mux_enum); + +static const struct snd_kcontrol_new sb_tx3_mux = + SOC_DAPM_ENUM("SLIM TX3 MUX Mux", sb_tx3_mux_enum); + +static const struct snd_kcontrol_new sb_tx4_mux = + SOC_DAPM_ENUM("SLIM TX4 MUX Mux", sb_tx4_mux_enum); + +static const struct snd_kcontrol_new sb_tx5_mux = + SOC_DAPM_ENUM("SLIM TX5 MUX Mux", sb_tx5_mux_enum); + +static const struct snd_kcontrol_new sb_tx6_mux = + SOC_DAPM_ENUM("SLIM TX6 MUX Mux", sb_tx6_mux_enum); + +static const struct snd_kcontrol_new sb_tx7_mux = + SOC_DAPM_ENUM("SLIM TX7 MUX Mux", sb_tx7_mux_enum); + +static const struct snd_kcontrol_new sb_tx8_mux = + SOC_DAPM_ENUM("SLIM TX8 MUX Mux", sb_tx8_mux_enum); + +static const struct snd_kcontrol_new sb_tx9_mux = + SOC_DAPM_ENUM("SLIM TX9 MUX Mux", sb_tx9_mux_enum); + +static const struct snd_kcontrol_new sb_tx10_mux = + SOC_DAPM_ENUM("SLIM TX10 MUX Mux", sb_tx10_mux_enum); + +static const struct snd_kcontrol_new sb_tx11_mux = + SOC_DAPM_ENUM("SLIM TX11 MUX Mux", sb_tx11_mux_enum); + +static const struct snd_kcontrol_new sb_tx11_inp1_mux = + SOC_DAPM_ENUM("SLIM TX11 INP1 MUX Mux", sb_tx11_inp1_mux_enum); + +static const struct snd_kcontrol_new sb_tx13_mux = + SOC_DAPM_ENUM("SLIM TX13 MUX Mux", sb_tx13_mux_enum); + +static const struct snd_kcontrol_new tx13_inp_mux = + SOC_DAPM_ENUM("TX13 INP MUX Mux", tx13_inp_mux_enum); + +static const struct snd_kcontrol_new rx_mix_tx0_mux = + SOC_DAPM_ENUM("RX MIX TX0 MUX Mux", rx_mix_tx0_mux_enum); + +static const struct snd_kcontrol_new rx_mix_tx1_mux = + SOC_DAPM_ENUM("RX MIX TX1 MUX Mux", rx_mix_tx1_mux_enum); + +static const struct snd_kcontrol_new rx_mix_tx2_mux = + SOC_DAPM_ENUM("RX MIX TX2 MUX Mux", rx_mix_tx2_mux_enum); + +static const struct snd_kcontrol_new rx_mix_tx3_mux = + SOC_DAPM_ENUM("RX MIX TX3 MUX Mux", rx_mix_tx3_mux_enum); + +static const struct snd_kcontrol_new rx_mix_tx4_mux = + SOC_DAPM_ENUM("RX MIX TX4 MUX Mux", rx_mix_tx4_mux_enum); + +static const struct snd_kcontrol_new rx_mix_tx5_mux = + SOC_DAPM_ENUM("RX MIX TX5 MUX Mux", rx_mix_tx5_mux_enum); + +static const struct snd_kcontrol_new rx_mix_tx6_mux = + SOC_DAPM_ENUM("RX MIX TX6 MUX Mux", rx_mix_tx6_mux_enum); + +static const struct snd_kcontrol_new rx_mix_tx7_mux = + SOC_DAPM_ENUM("RX MIX TX7 MUX Mux", rx_mix_tx7_mux_enum); + +static const struct snd_kcontrol_new rx_mix_tx8_mux = + SOC_DAPM_ENUM("RX MIX TX8 MUX Mux", rx_mix_tx8_mux_enum); + +static const struct snd_kcontrol_new iir0_inp0_mux = + SOC_DAPM_ENUM("IIR0 INP0 Mux", iir0_inp0_mux_enum); + +static const struct snd_kcontrol_new iir0_inp1_mux = + SOC_DAPM_ENUM("IIR0 INP1 Mux", iir0_inp1_mux_enum); + +static const struct snd_kcontrol_new iir0_inp2_mux = + SOC_DAPM_ENUM("IIR0 INP2 Mux", iir0_inp2_mux_enum); + +static const struct snd_kcontrol_new iir0_inp3_mux = + SOC_DAPM_ENUM("IIR0 INP3 Mux", iir0_inp3_mux_enum); + +static const struct snd_kcontrol_new iir1_inp0_mux = + SOC_DAPM_ENUM("IIR1 INP0 Mux", iir1_inp0_mux_enum); + +static const struct snd_kcontrol_new iir1_inp1_mux = + SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum); + +static const struct snd_kcontrol_new iir1_inp2_mux = + SOC_DAPM_ENUM("IIR1 INP2 Mux", iir1_inp2_mux_enum); + +static const struct snd_kcontrol_new iir1_inp3_mux = + SOC_DAPM_ENUM("IIR1 INP3 Mux", iir1_inp3_mux_enum); + +static const struct snd_kcontrol_new rx_int0_interp_mux = + SOC_DAPM_ENUM("RX INT0 INTERP Mux", rx_int0_interp_mux_enum); + +static const struct snd_kcontrol_new rx_int1_interp_mux = + SOC_DAPM_ENUM("RX INT1 INTERP Mux", rx_int1_interp_mux_enum); + +static const struct snd_kcontrol_new rx_int2_interp_mux = + SOC_DAPM_ENUM("RX INT2 INTERP Mux", rx_int2_interp_mux_enum); + +static const struct snd_kcontrol_new rx_int3_interp_mux = + SOC_DAPM_ENUM("RX INT3 INTERP Mux", rx_int3_interp_mux_enum); + +static const struct snd_kcontrol_new rx_int4_interp_mux = + SOC_DAPM_ENUM("RX INT4 INTERP Mux", rx_int4_interp_mux_enum); + +static const struct snd_kcontrol_new rx_int5_interp_mux = + SOC_DAPM_ENUM("RX INT5 INTERP Mux", rx_int5_interp_mux_enum); + +static const struct snd_kcontrol_new rx_int6_interp_mux = + SOC_DAPM_ENUM("RX INT6 INTERP Mux", rx_int6_interp_mux_enum); + +static const struct snd_kcontrol_new rx_int7_interp_mux = + SOC_DAPM_ENUM("RX INT7 INTERP Mux", rx_int7_interp_mux_enum); + +static const struct snd_kcontrol_new rx_int8_interp_mux = + SOC_DAPM_ENUM("RX INT8 INTERP Mux", rx_int8_interp_mux_enum); + +static const struct snd_kcontrol_new mad_sel_mux = + SOC_DAPM_ENUM("MAD_SEL MUX Mux", mad_sel_enum); + +static const struct snd_kcontrol_new aif4_mad_switch = + SOC_DAPM_SINGLE("Switch", WCD9335_CPE_SS_CFG, 5, 1, 0); + +static const struct snd_kcontrol_new mad_brdcst_switch = + SOC_DAPM_SINGLE("Switch", WCD9335_CPE_SS_CFG, 6, 1, 0); + +static const struct snd_kcontrol_new aif4_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, tasha_codec_aif4_mixer_switch_get, + tasha_codec_aif4_mixer_switch_put); + +static const struct snd_kcontrol_new anc_hphl_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new anc_hphr_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new anc_ear_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new anc_ear_spkr_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new anc_lineout1_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new anc_lineout2_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new anc_spkr_pa_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux0_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux1_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux2_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux3_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux4_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux5_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux6_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux7_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux8_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new anc0_fb_mux = + SOC_DAPM_ENUM("ANC0 FB MUX Mux", anc0_fb_mux_enum); + +static const struct snd_kcontrol_new anc1_fb_mux = + SOC_DAPM_ENUM("ANC1 FB MUX Mux", anc1_fb_mux_enum); + +static int tasha_codec_ec_buf_mux_enable(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s: event = %d name = %s\n", + __func__, event, w->name); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + snd_soc_write(codec, WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x3B); + snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, 0x08, 0x08); + snd_soc_update_bits(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, + 0x08, 0x08); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, + 0x08, 0x00); + snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, 0x08, 0x00); + snd_soc_write(codec, WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x00); + break; + } + + return 0; +}; + +static const char * const ec_buf_mux_text[] = { + "ZERO", "RXMIXEC", "SB_RX0", "SB_RX1", "SB_RX2", "SB_RX3", + "I2S_RX_SD0_L", "I2S_RX_SD0_R", "I2S_RX_SD1_L", "I2S_RX_SD1_R", + "DEC1" +}; + +static SOC_ENUM_SINGLE_DECL(ec_buf_mux_enum, WCD9335_CPE_SS_US_EC_MUX_CFG, + 0, ec_buf_mux_text); + +static const struct snd_kcontrol_new ec_buf_mux = + SOC_DAPM_ENUM("EC BUF Mux", ec_buf_mux_enum); + +static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = { + SND_SOC_DAPM_OUTPUT("EAR"), + SND_SOC_DAPM_OUTPUT("ANC EAR"), + SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM, + AIF1_PB, 0, tasha_codec_enable_slimrx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM, + AIF2_PB, 0, tasha_codec_enable_slimrx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM, + AIF3_PB, 0, tasha_codec_enable_slimrx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM, + AIF4_PB, 0, tasha_codec_enable_slimrx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_IN_E("AIF MIX1 PB", "AIF Mix Playback", 0, + SND_SOC_NOPM, AIF_MIX1_PB, 0, + tasha_codec_enable_slimrx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("SLIM RX0 MUX", SND_SOC_NOPM, TASHA_RX0, 0, + &slim_rx_mux[TASHA_RX0]), + SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, TASHA_RX1, 0, + &slim_rx_mux[TASHA_RX1]), + SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, TASHA_RX2, 0, + &slim_rx_mux[TASHA_RX2]), + SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, TASHA_RX3, 0, + &slim_rx_mux[TASHA_RX3]), + SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, TASHA_RX4, 0, + &slim_rx_mux[TASHA_RX4]), + SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, TASHA_RX5, 0, + &slim_rx_mux[TASHA_RX5]), + SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, TASHA_RX6, 0, + &slim_rx_mux[TASHA_RX6]), + SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, TASHA_RX7, 0, + &slim_rx_mux[TASHA_RX7]), + + SND_SOC_DAPM_MIXER("SLIM RX0", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MUX_E("SPL SRC0 MUX", SND_SOC_NOPM, SPLINE_SRC0, 0, + &spl_src0_mux, tasha_codec_enable_spline_resampler, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("SPL SRC1 MUX", SND_SOC_NOPM, SPLINE_SRC1, 0, + &spl_src1_mux, tasha_codec_enable_spline_resampler, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("SPL SRC2 MUX", SND_SOC_NOPM, SPLINE_SRC2, 0, + &spl_src2_mux, tasha_codec_enable_spline_resampler, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("SPL SRC3 MUX", SND_SOC_NOPM, SPLINE_SRC3, 0, + &spl_src3_mux, tasha_codec_enable_spline_resampler, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", WCD9335_CDC_RX0_RX_PATH_MIX_CTL, + 5, 0, &rx_int0_2_mux, tasha_codec_enable_mix_path, + SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", WCD9335_CDC_RX1_RX_PATH_MIX_CTL, + 5, 0, &rx_int1_2_mux, tasha_codec_enable_mix_path, + SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", WCD9335_CDC_RX2_RX_PATH_MIX_CTL, + 5, 0, &rx_int2_2_mux, tasha_codec_enable_mix_path, + SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_MUX_E("RX INT3_2 MUX", WCD9335_CDC_RX3_RX_PATH_MIX_CTL, + 5, 0, &rx_int3_2_mux, tasha_codec_enable_mix_path, + SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_MUX_E("RX INT4_2 MUX", WCD9335_CDC_RX4_RX_PATH_MIX_CTL, + 5, 0, &rx_int4_2_mux, tasha_codec_enable_mix_path, + SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_MUX_E("RX INT5_2 MUX", WCD9335_CDC_RX5_RX_PATH_MIX_CTL, + 5, 0, &rx_int5_2_mux, tasha_codec_enable_mix_path, + SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_MUX_E("RX INT6_2 MUX", WCD9335_CDC_RX6_RX_PATH_MIX_CTL, + 5, 0, &rx_int6_2_mux, tasha_codec_enable_mix_path, + SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_MUX_E("RX INT7_2 MUX", WCD9335_CDC_RX7_RX_PATH_MIX_CTL, + 5, 0, &rx_int7_2_mux, tasha_codec_enable_mix_path, + SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_MUX_E("RX INT8_2 MUX", WCD9335_CDC_RX8_RX_PATH_MIX_CTL, + 5, 0, &rx_int8_2_mux, tasha_codec_enable_mix_path, + SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, + &rx_int0_1_mix_inp0_mux), + SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx_int0_1_mix_inp1_mux), + SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx_int0_1_mix_inp2_mux), + SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, + &rx_int1_1_mix_inp0_mux), + SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx_int1_1_mix_inp1_mux), + SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx_int1_1_mix_inp2_mux), + SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, + &rx_int2_1_mix_inp0_mux), + SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx_int2_1_mix_inp1_mux), + SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx_int2_1_mix_inp2_mux), + SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, + &rx_int3_1_mix_inp0_mux), + SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx_int3_1_mix_inp1_mux), + SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx_int3_1_mix_inp2_mux), + SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, + &rx_int4_1_mix_inp0_mux), + SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx_int4_1_mix_inp1_mux), + SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx_int4_1_mix_inp2_mux), + SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, + &rx_int5_1_mix_inp0_mux), + SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx_int5_1_mix_inp1_mux), + SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx_int5_1_mix_inp2_mux), + SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, + &rx_int6_1_mix_inp0_mux), + SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx_int6_1_mix_inp1_mux), + SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx_int6_1_mix_inp2_mux), + SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, + &rx_int7_1_mix_inp0_mux, tasha_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx_int7_1_mix_inp1_mux, tasha_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx_int7_1_mix_inp2_mux, tasha_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, + &rx_int8_1_mix_inp0_mux, tasha_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx_int8_1_mix_inp1_mux, tasha_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx_int8_1_mix_inp2_mux, tasha_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT1 SPLINE MIX", SND_SOC_NOPM, 0, 0, + rx_int1_spline_mix_switch, + ARRAY_SIZE(rx_int1_spline_mix_switch)), + SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT2 SPLINE MIX", SND_SOC_NOPM, 0, 0, + rx_int2_spline_mix_switch, + ARRAY_SIZE(rx_int2_spline_mix_switch)), + SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT3_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT3 SPLINE MIX", SND_SOC_NOPM, 0, 0, + rx_int3_spline_mix_switch, + ARRAY_SIZE(rx_int3_spline_mix_switch)), + SND_SOC_DAPM_MIXER("RX INT3 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT4_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT4 SPLINE MIX", SND_SOC_NOPM, 0, 0, + rx_int4_spline_mix_switch, + ARRAY_SIZE(rx_int4_spline_mix_switch)), + SND_SOC_DAPM_MIXER("RX INT4 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT5_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT5 SPLINE MIX", SND_SOC_NOPM, 0, 0, + rx_int5_spline_mix_switch, + ARRAY_SIZE(rx_int5_spline_mix_switch)), + SND_SOC_DAPM_MIXER("RX INT5 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MIXER("RX INT6_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT6 SPLINE MIX", SND_SOC_NOPM, 0, 0, + rx_int6_spline_mix_switch, + ARRAY_SIZE(rx_int6_spline_mix_switch)), + SND_SOC_DAPM_MIXER("RX INT6 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MIXER("RX INT7_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT7 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT7 SPLINE MIX", SND_SOC_NOPM, 0, 0, + rx_int7_spline_mix_switch, + ARRAY_SIZE(rx_int7_spline_mix_switch)), + + SND_SOC_DAPM_MIXER("RX INT8_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT8 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT8 SPLINE MIX", SND_SOC_NOPM, 0, 0, + rx_int8_spline_mix_switch, + ARRAY_SIZE(rx_int8_spline_mix_switch)), + + SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT3 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT4 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT5 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT6 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT7 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER_E("RX INT7 CHAIN", SND_SOC_NOPM, 0, 0, + NULL, 0, tasha_codec_spk_boost_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX INT8 CHAIN", SND_SOC_NOPM, 0, 0, + NULL, 0, tasha_codec_spk_boost_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER_E("RX INT5 VBAT", SND_SOC_NOPM, 0, 0, + rx_int5_vbat_mix_switch, + ARRAY_SIZE(rx_int5_vbat_mix_switch), + tasha_codec_vbat_enable_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX INT6 VBAT", SND_SOC_NOPM, 0, 0, + rx_int6_vbat_mix_switch, + ARRAY_SIZE(rx_int6_vbat_mix_switch), + tasha_codec_vbat_enable_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX INT7 VBAT", SND_SOC_NOPM, 0, 0, + rx_int7_vbat_mix_switch, + ARRAY_SIZE(rx_int7_vbat_mix_switch), + tasha_codec_vbat_enable_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX INT8 VBAT", SND_SOC_NOPM, 0, 0, + rx_int8_vbat_mix_switch, + ARRAY_SIZE(rx_int8_vbat_mix_switch), + tasha_codec_vbat_enable_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("RX INT0 MIX2 INP", WCD9335_CDC_RX0_RX_PATH_CFG1, 4, + 0, &rx_int0_mix2_inp_mux), + SND_SOC_DAPM_MUX("RX INT1 MIX2 INP", WCD9335_CDC_RX1_RX_PATH_CFG1, 4, + 0, &rx_int1_mix2_inp_mux), + SND_SOC_DAPM_MUX("RX INT2 MIX2 INP", WCD9335_CDC_RX2_RX_PATH_CFG1, 4, + 0, &rx_int2_mix2_inp_mux), + SND_SOC_DAPM_MUX("RX INT3 MIX2 INP", WCD9335_CDC_RX3_RX_PATH_CFG1, 4, + 0, &rx_int3_mix2_inp_mux), + SND_SOC_DAPM_MUX("RX INT4 MIX2 INP", WCD9335_CDC_RX4_RX_PATH_CFG1, 4, + 0, &rx_int4_mix2_inp_mux), + SND_SOC_DAPM_MUX("RX INT7 MIX2 INP", WCD9335_CDC_RX7_RX_PATH_CFG1, 4, + 0, &rx_int7_mix2_inp_mux), + + SND_SOC_DAPM_MUX("SLIM TX0 MUX", SND_SOC_NOPM, TASHA_TX0, 0, + &sb_tx0_mux), + SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, TASHA_TX1, 0, + &sb_tx1_mux), + SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, TASHA_TX2, 0, + &sb_tx2_mux), + SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, TASHA_TX3, 0, + &sb_tx3_mux), + SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, TASHA_TX4, 0, + &sb_tx4_mux), + SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, TASHA_TX5, 0, + &sb_tx5_mux), + SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, TASHA_TX6, 0, + &sb_tx6_mux), + SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, TASHA_TX7, 0, + &sb_tx7_mux), + SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, TASHA_TX8, 0, + &sb_tx8_mux), + SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, TASHA_TX9, 0, + &sb_tx9_mux), + SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, TASHA_TX10, 0, + &sb_tx10_mux), + SND_SOC_DAPM_MUX("SLIM TX11 MUX", SND_SOC_NOPM, TASHA_TX11, 0, + &sb_tx11_mux), + SND_SOC_DAPM_MUX("SLIM TX11 INP1 MUX", SND_SOC_NOPM, TASHA_TX11, 0, + &sb_tx11_inp1_mux), + SND_SOC_DAPM_MUX("SLIM TX13 MUX", SND_SOC_NOPM, TASHA_TX13, 0, + &sb_tx13_mux), + SND_SOC_DAPM_MUX("TX13 INP MUX", SND_SOC_NOPM, 0, 0, + &tx13_inp_mux), + + SND_SOC_DAPM_MUX_E("ADC MUX0", WCD9335_CDC_TX0_TX_PATH_CTL, 5, 0, + &tx_adc_mux0, tasha_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX1", WCD9335_CDC_TX1_TX_PATH_CTL, 5, 0, + &tx_adc_mux1, tasha_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX2", WCD9335_CDC_TX2_TX_PATH_CTL, 5, 0, + &tx_adc_mux2, tasha_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX3", WCD9335_CDC_TX3_TX_PATH_CTL, 5, 0, + &tx_adc_mux3, tasha_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX4", WCD9335_CDC_TX4_TX_PATH_CTL, 5, 0, + &tx_adc_mux4, tasha_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX5", WCD9335_CDC_TX5_TX_PATH_CTL, 5, 0, + &tx_adc_mux5, tasha_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX6", WCD9335_CDC_TX6_TX_PATH_CTL, 5, 0, + &tx_adc_mux6, tasha_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX7", WCD9335_CDC_TX7_TX_PATH_CTL, 5, 0, + &tx_adc_mux7, tasha_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX8", WCD9335_CDC_TX8_TX_PATH_CTL, 5, 0, + &tx_adc_mux8, tasha_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX10", SND_SOC_NOPM, 10, 0, + &tx_adc_mux10, tasha_codec_tx_adc_cfg, + SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_MUX_E("ADC MUX11", SND_SOC_NOPM, 11, 0, + &tx_adc_mux11, tasha_codec_tx_adc_cfg, + SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_MUX_E("ADC MUX12", SND_SOC_NOPM, 12, 0, + &tx_adc_mux12, tasha_codec_tx_adc_cfg, + SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_MUX_E("ADC MUX13", SND_SOC_NOPM, 13, 0, + &tx_adc_mux13, tasha_codec_tx_adc_cfg, + SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_MUX("DMIC MUX0", SND_SOC_NOPM, 0, 0, + &tx_dmic_mux0), + SND_SOC_DAPM_MUX("DMIC MUX1", SND_SOC_NOPM, 0, 0, + &tx_dmic_mux1), + SND_SOC_DAPM_MUX("DMIC MUX2", SND_SOC_NOPM, 0, 0, + &tx_dmic_mux2), + SND_SOC_DAPM_MUX("DMIC MUX3", SND_SOC_NOPM, 0, 0, + &tx_dmic_mux3), + SND_SOC_DAPM_MUX("DMIC MUX4", SND_SOC_NOPM, 0, 0, + &tx_dmic_mux4), + SND_SOC_DAPM_MUX("DMIC MUX5", SND_SOC_NOPM, 0, 0, + &tx_dmic_mux5), + SND_SOC_DAPM_MUX("DMIC MUX6", SND_SOC_NOPM, 0, 0, + &tx_dmic_mux6), + SND_SOC_DAPM_MUX("DMIC MUX7", SND_SOC_NOPM, 0, 0, + &tx_dmic_mux7), + SND_SOC_DAPM_MUX("DMIC MUX8", SND_SOC_NOPM, 0, 0, + &tx_dmic_mux8), + SND_SOC_DAPM_MUX("DMIC MUX10", SND_SOC_NOPM, 0, 0, + &tx_dmic_mux10), + SND_SOC_DAPM_MUX("DMIC MUX11", SND_SOC_NOPM, 0, 0, + &tx_dmic_mux11), + SND_SOC_DAPM_MUX("DMIC MUX12", SND_SOC_NOPM, 0, 0, + &tx_dmic_mux12), + SND_SOC_DAPM_MUX("DMIC MUX13", SND_SOC_NOPM, 0, 0, + &tx_dmic_mux13), + + SND_SOC_DAPM_MUX("AMIC MUX0", SND_SOC_NOPM, 0, 0, + &tx_amic_mux0), + SND_SOC_DAPM_MUX("AMIC MUX1", SND_SOC_NOPM, 0, 0, + &tx_amic_mux1), + SND_SOC_DAPM_MUX("AMIC MUX2", SND_SOC_NOPM, 0, 0, + &tx_amic_mux2), + SND_SOC_DAPM_MUX("AMIC MUX3", SND_SOC_NOPM, 0, 0, + &tx_amic_mux3), + SND_SOC_DAPM_MUX("AMIC MUX4", SND_SOC_NOPM, 0, 0, + &tx_amic_mux4), + SND_SOC_DAPM_MUX("AMIC MUX5", SND_SOC_NOPM, 0, 0, + &tx_amic_mux5), + SND_SOC_DAPM_MUX("AMIC MUX6", SND_SOC_NOPM, 0, 0, + &tx_amic_mux6), + SND_SOC_DAPM_MUX("AMIC MUX7", SND_SOC_NOPM, 0, 0, + &tx_amic_mux7), + SND_SOC_DAPM_MUX("AMIC MUX8", SND_SOC_NOPM, 0, 0, + &tx_amic_mux8), + SND_SOC_DAPM_MUX("AMIC MUX10", SND_SOC_NOPM, 0, 0, + &tx_amic_mux10), + SND_SOC_DAPM_MUX("AMIC MUX11", SND_SOC_NOPM, 0, 0, + &tx_amic_mux11), + SND_SOC_DAPM_MUX("AMIC MUX12", SND_SOC_NOPM, 0, 0, + &tx_amic_mux12), + SND_SOC_DAPM_MUX("AMIC MUX13", SND_SOC_NOPM, 0, 0, + &tx_amic_mux13), + + SND_SOC_DAPM_ADC_E("ADC1", NULL, WCD9335_ANA_AMIC1, 7, 0, + tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_ADC_E("ADC2", NULL, WCD9335_ANA_AMIC2, 7, 0, + tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_ADC_E("ADC3", NULL, WCD9335_ANA_AMIC3, 7, 0, + tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_ADC_E("ADC4", NULL, WCD9335_ANA_AMIC4, 7, 0, + tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_ADC_E("ADC5", NULL, WCD9335_ANA_AMIC5, 7, 0, + tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_ADC_E("ADC6", NULL, WCD9335_ANA_AMIC6, 7, 0, + tasha_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + + SND_SOC_DAPM_SUPPLY("RX INT1 NATIVE SUPPLY", SND_SOC_NOPM, + INTERP_HPHL, 0, tasha_enable_native_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_SUPPLY("RX INT2 NATIVE SUPPLY", SND_SOC_NOPM, + INTERP_HPHR, 0, tasha_enable_native_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_SUPPLY("RX INT3 NATIVE SUPPLY", SND_SOC_NOPM, + INTERP_LO1, 0, tasha_enable_native_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_SUPPLY("RX INT4 NATIVE SUPPLY", SND_SOC_NOPM, + INTERP_LO2, 0, tasha_enable_native_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_INPUT("AMIC1"), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS1", SND_SOC_NOPM, 0, 0, + tasha_codec_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS2", SND_SOC_NOPM, 0, 0, + tasha_codec_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS3", SND_SOC_NOPM, 0, 0, + tasha_codec_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS4", SND_SOC_NOPM, 0, 0, + tasha_codec_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS1_STANDALONE, SND_SOC_NOPM, 0, 0, + tasha_codec_force_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS2_STANDALONE, SND_SOC_NOPM, 0, 0, + tasha_codec_force_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS3_STANDALONE, SND_SOC_NOPM, 0, 0, + tasha_codec_force_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS4_STANDALONE, SND_SOC_NOPM, 0, 0, + tasha_codec_force_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY(DAPM_LDO_H_STANDALONE, SND_SOC_NOPM, 0, 0, + tasha_codec_force_enable_ldo_h, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("ANC0 FB MUX", SND_SOC_NOPM, 0, 0, &anc0_fb_mux), + SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux), + + SND_SOC_DAPM_INPUT("AMIC2"), + SND_SOC_DAPM_INPUT("AMIC3"), + SND_SOC_DAPM_INPUT("AMIC4"), + SND_SOC_DAPM_INPUT("AMIC5"), + SND_SOC_DAPM_INPUT("AMIC6"), + + SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM, + AIF1_CAP, 0, tasha_codec_enable_slimtx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM, + AIF2_CAP, 0, tasha_codec_enable_slimtx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM, + AIF3_CAP, 0, tasha_codec_enable_slimtx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM, + AIF4_VIFEED, 0, tasha_codec_enable_slimvi_feedback, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("AIF4_VI Mixer", SND_SOC_NOPM, AIF4_VIFEED, 0, + aif4_vi_mixer, ARRAY_SIZE(aif4_vi_mixer)), + + SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0, + aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)), + + SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0, + aif2_cap_mixer, ARRAY_SIZE(aif2_cap_mixer)), + + SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0, + aif3_cap_mixer, ARRAY_SIZE(aif3_cap_mixer)), + + SND_SOC_DAPM_MIXER("AIF4_MAD Mixer", SND_SOC_NOPM, AIF4_MAD_TX, 0, + aif4_mad_mixer, ARRAY_SIZE(aif4_mad_mixer)), + + SND_SOC_DAPM_INPUT("VIINPUT"), + + SND_SOC_DAPM_AIF_OUT("AIF5 CPE", "AIF5 CPE TX", 0, SND_SOC_NOPM, + AIF5_CPE_TX, 0), + + SND_SOC_DAPM_MUX_E("EC BUF MUX INP", SND_SOC_NOPM, 0, 0, &ec_buf_mux, + tasha_codec_ec_buf_mux_enable, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + /* Digital Mic Inputs */ + SND_SOC_DAPM_ADC_E("DMIC0", NULL, SND_SOC_NOPM, 0, 0, + tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0, + tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0, + tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0, + tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0, + tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0, + tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("IIR0 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp0_mux), + SND_SOC_DAPM_MUX("IIR0 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp1_mux), + SND_SOC_DAPM_MUX("IIR0 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp2_mux), + SND_SOC_DAPM_MUX("IIR0 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp3_mux), + SND_SOC_DAPM_MUX("IIR1 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp0_mux), + SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux), + SND_SOC_DAPM_MUX("IIR1 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp2_mux), + SND_SOC_DAPM_MUX("IIR1 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp3_mux), + + SND_SOC_DAPM_MIXER_E("IIR0", WCD9335_CDC_SIDETONE_IIR0_IIR_PATH_CTL, + 4, 0, NULL, 0, tasha_codec_set_iir_gain, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_MIXER_E("IIR1", WCD9335_CDC_SIDETONE_IIR1_IIR_PATH_CTL, + 4, 0, NULL, 0, tasha_codec_set_iir_gain, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_MIXER("SRC0", WCD9335_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL, + 4, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SRC1", WCD9335_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL, + 4, 0, NULL, 0), + SND_SOC_DAPM_MIXER_E("CPE IN Mixer", SND_SOC_NOPM, 0, 0, + cpe_in_mix_switch, + ARRAY_SIZE(cpe_in_mix_switch), + tasha_codec_configure_cpe_input, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("RX INT1_1 NATIVE MUX", SND_SOC_NOPM, 0, 0, + &int1_1_native_mux), + SND_SOC_DAPM_MUX("RX INT2_1 NATIVE MUX", SND_SOC_NOPM, 0, 0, + &int2_1_native_mux), + SND_SOC_DAPM_MUX("RX INT3_1 NATIVE MUX", SND_SOC_NOPM, 0, 0, + &int3_1_native_mux), + SND_SOC_DAPM_MUX("RX INT4_1 NATIVE MUX", SND_SOC_NOPM, 0, 0, + &int4_1_native_mux), + SND_SOC_DAPM_MUX("RX MIX TX0 MUX", SND_SOC_NOPM, 0, 0, + &rx_mix_tx0_mux), + SND_SOC_DAPM_MUX("RX MIX TX1 MUX", SND_SOC_NOPM, 0, 0, + &rx_mix_tx1_mux), + SND_SOC_DAPM_MUX("RX MIX TX2 MUX", SND_SOC_NOPM, 0, 0, + &rx_mix_tx2_mux), + SND_SOC_DAPM_MUX("RX MIX TX3 MUX", SND_SOC_NOPM, 0, 0, + &rx_mix_tx3_mux), + SND_SOC_DAPM_MUX("RX MIX TX4 MUX", SND_SOC_NOPM, 0, 0, + &rx_mix_tx4_mux), + SND_SOC_DAPM_MUX("RX MIX TX5 MUX", SND_SOC_NOPM, 0, 0, + &rx_mix_tx5_mux), + SND_SOC_DAPM_MUX("RX MIX TX6 MUX", SND_SOC_NOPM, 0, 0, + &rx_mix_tx6_mux), + SND_SOC_DAPM_MUX("RX MIX TX7 MUX", SND_SOC_NOPM, 0, 0, + &rx_mix_tx7_mux), + SND_SOC_DAPM_MUX("RX MIX TX8 MUX", SND_SOC_NOPM, 0, 0, + &rx_mix_tx8_mux), + + SND_SOC_DAPM_MUX("RX INT0 DEM MUX", SND_SOC_NOPM, 0, 0, + &rx_int0_dem_inp_mux), + SND_SOC_DAPM_MUX("RX INT1 DEM MUX", SND_SOC_NOPM, 0, 0, + &rx_int1_dem_inp_mux), + SND_SOC_DAPM_MUX("RX INT2 DEM MUX", SND_SOC_NOPM, 0, 0, + &rx_int2_dem_inp_mux), + + SND_SOC_DAPM_MUX_E("RX INT0 INTERP", SND_SOC_NOPM, + INTERP_EAR, 0, &rx_int0_interp_mux, + tasha_codec_enable_interpolator, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT1 INTERP", SND_SOC_NOPM, + INTERP_HPHL, 0, &rx_int1_interp_mux, + tasha_codec_enable_interpolator, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT2 INTERP", SND_SOC_NOPM, + INTERP_HPHR, 0, &rx_int2_interp_mux, + tasha_codec_enable_interpolator, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT3 INTERP", SND_SOC_NOPM, + INTERP_LO1, 0, &rx_int3_interp_mux, + tasha_codec_enable_interpolator, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT4 INTERP", SND_SOC_NOPM, + INTERP_LO2, 0, &rx_int4_interp_mux, + tasha_codec_enable_interpolator, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT5 INTERP", SND_SOC_NOPM, + INTERP_LO3, 0, &rx_int5_interp_mux, + tasha_codec_enable_interpolator, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT6 INTERP", SND_SOC_NOPM, + INTERP_LO4, 0, &rx_int6_interp_mux, + tasha_codec_enable_interpolator, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT7 INTERP", SND_SOC_NOPM, + INTERP_SPKR1, 0, &rx_int7_interp_mux, + tasha_codec_enable_interpolator, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT8 INTERP", SND_SOC_NOPM, + INTERP_SPKR2, 0, &rx_int8_interp_mux, + tasha_codec_enable_interpolator, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_DAC_E("RX INT0 DAC", NULL, SND_SOC_NOPM, + 0, 0, tasha_codec_ear_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RX INT1 DAC", NULL, WCD9335_ANA_HPH, + 5, 0, tasha_codec_hphl_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RX INT2 DAC", NULL, WCD9335_ANA_HPH, + 4, 0, tasha_codec_hphr_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RX INT3 DAC", NULL, SND_SOC_NOPM, + 0, 0, tasha_codec_lineout_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RX INT4 DAC", NULL, SND_SOC_NOPM, + 0, 0, tasha_codec_lineout_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RX INT5 DAC", NULL, SND_SOC_NOPM, + 0, 0, tasha_codec_lineout_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RX INT6 DAC", NULL, SND_SOC_NOPM, + 0, 0, tasha_codec_lineout_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("HPHL PA", WCD9335_ANA_HPH, 7, 0, NULL, 0, + tasha_codec_enable_hphl_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("HPHR PA", WCD9335_ANA_HPH, 6, 0, NULL, 0, + tasha_codec_enable_hphr_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0, + tasha_codec_enable_ear_pa, + SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("LINEOUT1 PA", WCD9335_ANA_LO_1_2, 7, 0, NULL, 0, + tasha_codec_enable_lineout_pa, + SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("LINEOUT2 PA", WCD9335_ANA_LO_1_2, 6, 0, NULL, 0, + tasha_codec_enable_lineout_pa, + SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("LINEOUT3 PA", WCD9335_ANA_LO_3_4, 7, 0, NULL, 0, + tasha_codec_enable_lineout_pa, + SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("LINEOUT4 PA", WCD9335_ANA_LO_3_4, 6, 0, NULL, 0, + tasha_codec_enable_lineout_pa, + SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("ANC EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0, + tasha_codec_enable_ear_pa, + SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("ANC HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0, + tasha_codec_enable_hphl_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("ANC HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0, + tasha_codec_enable_hphr_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("ANC LINEOUT1 PA", WCD9335_ANA_LO_1_2, + 7, 0, NULL, 0, + tasha_codec_enable_lineout_pa, + SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("ANC LINEOUT2 PA", WCD9335_ANA_LO_1_2, + 6, 0, NULL, 0, + tasha_codec_enable_lineout_pa, + SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("ANC SPK1 PA", SND_SOC_NOPM, 0, 0, NULL, 0, + tasha_codec_enable_spk_anc, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_OUTPUT("HPHL"), + SND_SOC_DAPM_OUTPUT("HPHR"), + SND_SOC_DAPM_OUTPUT("ANC HPHL"), + SND_SOC_DAPM_OUTPUT("ANC HPHR"), + SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0, + tasha_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_OUTPUT("SPK1 OUT"), + SND_SOC_DAPM_OUTPUT("SPK2 OUT"), + SND_SOC_DAPM_OUTPUT("LINEOUT1"), + SND_SOC_DAPM_OUTPUT("LINEOUT2"), + SND_SOC_DAPM_OUTPUT("LINEOUT3"), + SND_SOC_DAPM_OUTPUT("LINEOUT4"), + SND_SOC_DAPM_OUTPUT("ANC LINEOUT1"), + SND_SOC_DAPM_OUTPUT("ANC LINEOUT2"), + SND_SOC_DAPM_SUPPLY("MICBIAS_REGULATOR", SND_SOC_NOPM, + ON_DEMAND_MICBIAS, 0, + tasha_codec_enable_on_demand_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SWITCH("ADC US MUX0", WCD9335_CDC_TX0_TX_PATH_192_CTL, 0, + 0, &adc_us_mux0_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX1", WCD9335_CDC_TX1_TX_PATH_192_CTL, 0, + 0, &adc_us_mux1_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX2", WCD9335_CDC_TX2_TX_PATH_192_CTL, 0, + 0, &adc_us_mux2_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX3", WCD9335_CDC_TX3_TX_PATH_192_CTL, 0, + 0, &adc_us_mux3_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX4", WCD9335_CDC_TX4_TX_PATH_192_CTL, 0, + 0, &adc_us_mux4_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX5", WCD9335_CDC_TX5_TX_PATH_192_CTL, 0, + 0, &adc_us_mux5_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX6", WCD9335_CDC_TX6_TX_PATH_192_CTL, 0, + 0, &adc_us_mux6_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX7", WCD9335_CDC_TX7_TX_PATH_192_CTL, 0, + 0, &adc_us_mux7_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX8", WCD9335_CDC_TX8_TX_PATH_192_CTL, 0, + 0, &adc_us_mux8_switch), + /* MAD related widgets */ + SND_SOC_DAPM_AIF_OUT_E("AIF4 MAD", "AIF4 MAD TX", 0, + SND_SOC_NOPM, 0, 0, + tasha_codec_enable_mad, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("MAD_SEL MUX", SND_SOC_NOPM, 0, 0, + &mad_sel_mux), + SND_SOC_DAPM_INPUT("MAD_CPE_INPUT"), + SND_SOC_DAPM_INPUT("MADINPUT"), + SND_SOC_DAPM_SWITCH("MADONOFF", SND_SOC_NOPM, 0, 0, + &aif4_mad_switch), + SND_SOC_DAPM_SWITCH("MAD_BROADCAST", SND_SOC_NOPM, 0, 0, + &mad_brdcst_switch), + SND_SOC_DAPM_SWITCH("AIF4", SND_SOC_NOPM, 0, 0, + &aif4_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("ANC HPHL Enable", SND_SOC_NOPM, 0, 0, + &anc_hphl_switch), + SND_SOC_DAPM_SWITCH("ANC HPHR Enable", SND_SOC_NOPM, 0, 0, + &anc_hphr_switch), + SND_SOC_DAPM_SWITCH("ANC EAR Enable", SND_SOC_NOPM, 0, 0, + &anc_ear_switch), + SND_SOC_DAPM_SWITCH("ANC OUT EAR SPKR Enable", SND_SOC_NOPM, 0, 0, + &anc_ear_spkr_switch), + SND_SOC_DAPM_SWITCH("ANC LINEOUT1 Enable", SND_SOC_NOPM, 0, 0, + &anc_lineout1_switch), + SND_SOC_DAPM_SWITCH("ANC LINEOUT2 Enable", SND_SOC_NOPM, 0, 0, + &anc_lineout2_switch), + SND_SOC_DAPM_SWITCH("ANC SPKR PA Enable", SND_SOC_NOPM, 0, 0, + &anc_spkr_pa_switch), +}; + +static int tasha_get_channel_map(struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot) +{ + struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(dai->codec); + u32 i = 0; + struct wcd9xxx_ch *ch; + + switch (dai->id) { + case AIF1_PB: + case AIF2_PB: + case AIF3_PB: + case AIF4_PB: + case AIF_MIX1_PB: + if (!rx_slot || !rx_num) { + pr_err("%s: Invalid rx_slot %pK or rx_num %pK\n", + __func__, rx_slot, rx_num); + return -EINVAL; + } + list_for_each_entry(ch, &tasha_p->dai[dai->id].wcd9xxx_ch_list, + list) { + pr_debug("%s: slot_num %u ch->ch_num %d\n", + __func__, i, ch->ch_num); + rx_slot[i++] = ch->ch_num; + } + pr_debug("%s: rx_num %d\n", __func__, i); + *rx_num = i; + break; + case AIF1_CAP: + case AIF2_CAP: + case AIF3_CAP: + case AIF4_MAD_TX: + case AIF4_VIFEED: + if (!tx_slot || !tx_num) { + pr_err("%s: Invalid tx_slot %pK or tx_num %pK\n", + __func__, tx_slot, tx_num); + return -EINVAL; + } + list_for_each_entry(ch, &tasha_p->dai[dai->id].wcd9xxx_ch_list, + list) { + pr_debug("%s: slot_num %u ch->ch_num %d\n", + __func__, i, ch->ch_num); + tx_slot[i++] = ch->ch_num; + } + pr_debug("%s: tx_num %d\n", __func__, i); + *tx_num = i; + break; + + default: + pr_err("%s: Invalid DAI ID %x\n", __func__, dai->id); + break; + } + + return 0; +} + +static int tasha_set_channel_map(struct snd_soc_dai *dai, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot) +{ + struct tasha_priv *tasha; + struct wcd9xxx *core; + struct wcd9xxx_codec_dai_data *dai_data = NULL; + + if (!dai) { + pr_err("%s: dai is empty\n", __func__); + return -EINVAL; + } + tasha = snd_soc_codec_get_drvdata(dai->codec); + core = dev_get_drvdata(dai->codec->dev->parent); + + if (!tx_slot || !rx_slot) { + pr_err("%s: Invalid tx_slot=%pK, rx_slot=%pK\n", + __func__, tx_slot, rx_slot); + return -EINVAL; + } + pr_debug("%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n" + "tasha->intf_type %d\n", + __func__, dai->name, dai->id, tx_num, rx_num, + tasha->intf_type); + + if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) { + wcd9xxx_init_slimslave(core, core->slim->laddr, + tx_num, tx_slot, rx_num, rx_slot); + /* Reserve TX12/TX13 for MAD data channel */ + dai_data = &tasha->dai[AIF4_MAD_TX]; + if (dai_data) { + if (TASHA_IS_2_0(tasha->wcd9xxx)) + list_add_tail(&core->tx_chs[TASHA_TX13].list, + &dai_data->wcd9xxx_ch_list); + else + list_add_tail(&core->tx_chs[TASHA_TX12].list, + &dai_data->wcd9xxx_ch_list); + } + } + return 0; +} + +static int tasha_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + return 0; +} + +static void tasha_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec); + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) + return; + + if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) && + test_bit(SB_CLK_GEAR, &tasha->status_mask)) { + tasha_codec_vote_max_bw(dai->codec, false); + clear_bit(SB_CLK_GEAR, &tasha->status_mask); + } +} + +static int tasha_set_decimator_rate(struct snd_soc_dai *dai, + u8 tx_fs_rate_reg_val, u32 sample_rate) +{ + struct snd_soc_codec *codec = dai->codec; + struct wcd9xxx_ch *ch; + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + u32 tx_port = 0; + u8 shift = 0, shift_val = 0, tx_mux_sel = 0; + int decimator = -1; + u16 tx_port_reg = 0, tx_fs_reg = 0; + + list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) { + tx_port = ch->port; + dev_dbg(codec->dev, "%s: dai->id = %d, tx_port = %d", + __func__, dai->id, tx_port); + + if ((tx_port < 0) || (tx_port == 12) || (tx_port >= 14)) { + dev_err(codec->dev, "%s: Invalid SLIM TX%u port. DAI ID: %d\n", + __func__, tx_port, dai->id); + return -EINVAL; + } + /* Find the SB TX MUX input - which decimator is connected */ + if (tx_port < 4) { + tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0; + shift = (tx_port << 1); + shift_val = 0x03; + } else if ((tx_port >= 4) && (tx_port < 8)) { + tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1; + shift = ((tx_port - 4) << 1); + shift_val = 0x03; + } else if ((tx_port >= 8) && (tx_port < 11)) { + tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2; + shift = ((tx_port - 8) << 1); + shift_val = 0x03; + } else if (tx_port == 11) { + tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3; + shift = 0; + shift_val = 0x0F; + } else if (tx_port == 13) { + tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3; + shift = 4; + shift_val = 0x03; + } + tx_mux_sel = snd_soc_read(codec, tx_port_reg) & + (shift_val << shift); + tx_mux_sel = tx_mux_sel >> shift; + + if (tx_port <= 8) { + if ((tx_mux_sel == 0x2) || (tx_mux_sel == 0x3)) + decimator = tx_port; + } else if (tx_port <= 10) { + if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2)) + decimator = ((tx_port == 9) ? 7 : 6); + } else if (tx_port == 11) { + if ((tx_mux_sel >= 1) && (tx_mux_sel < 7)) + decimator = tx_mux_sel - 1; + } else if (tx_port == 13) { + if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2)) + decimator = 5; + } + + if (decimator >= 0) { + tx_fs_reg = WCD9335_CDC_TX0_TX_PATH_CTL + + 16 * decimator; + dev_dbg(codec->dev, "%s: set DEC%u (-> SLIM_TX%u) rate to %u\n", + __func__, decimator, tx_port, sample_rate); + snd_soc_update_bits(codec, tx_fs_reg, 0x0F, + tx_fs_rate_reg_val); + } else if ((tx_port <= 8) && (tx_mux_sel == 0x01)) { + /* Check if the TX Mux input is RX MIX TXn */ + dev_dbg(codec->dev, "%s: RX_MIX_TX%u going to SLIM TX%u\n", + __func__, tx_port, tx_port); + } else { + dev_err(codec->dev, "%s: ERROR: Invalid decimator: %d\n", + __func__, decimator); + return -EINVAL; + } + } + return 0; +} + +static int tasha_set_mix_interpolator_rate(struct snd_soc_dai *dai, + u8 int_mix_fs_rate_reg_val, + u32 sample_rate) +{ + u8 int_2_inp; + u32 j; + u16 int_mux_cfg1, int_fs_reg; + u8 int_mux_cfg1_val; + struct snd_soc_codec *codec = dai->codec; + struct wcd9xxx_ch *ch; + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) { + int_2_inp = ch->port + INTn_2_INP_SEL_RX0 - + TASHA_RX_PORT_START_NUMBER; + if ((int_2_inp < INTn_2_INP_SEL_RX0) || + (int_2_inp > INTn_2_INP_SEL_RX7)) { + pr_err("%s: Invalid RX%u port, Dai ID is %d\n", + __func__, + (ch->port - TASHA_RX_PORT_START_NUMBER), + dai->id); + return -EINVAL; + } + + int_mux_cfg1 = WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1; + for (j = 0; j < TASHA_NUM_INTERPOLATORS; j++) { + int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1) & + 0x0F; + if (int_mux_cfg1_val == int_2_inp) { + int_fs_reg = WCD9335_CDC_RX0_RX_PATH_MIX_CTL + + 20 * j; + pr_debug("%s: AIF_MIX_PB DAI(%d) connected to INT%u_2\n", + __func__, dai->id, j); + pr_debug("%s: set INT%u_2 sample rate to %u\n", + __func__, j, sample_rate); + snd_soc_update_bits(codec, int_fs_reg, + 0x0F, int_mix_fs_rate_reg_val); + } + int_mux_cfg1 += 2; + } + } + return 0; +} + +static int tasha_set_prim_interpolator_rate(struct snd_soc_dai *dai, + u8 int_prim_fs_rate_reg_val, + u32 sample_rate) +{ + u8 int_1_mix1_inp; + u32 j; + u16 int_mux_cfg0, int_mux_cfg1; + u16 int_fs_reg; + u8 int_mux_cfg0_val, int_mux_cfg1_val; + u8 inp0_sel, inp1_sel, inp2_sel; + struct snd_soc_codec *codec = dai->codec; + struct wcd9xxx_ch *ch; + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) { + int_1_mix1_inp = ch->port + INTn_1_MIX_INP_SEL_RX0 - + TASHA_RX_PORT_START_NUMBER; + if ((int_1_mix1_inp < INTn_1_MIX_INP_SEL_RX0) || + (int_1_mix1_inp > INTn_1_MIX_INP_SEL_RX7)) { + pr_err("%s: Invalid RX%u port, Dai ID is %d\n", + __func__, + (ch->port - TASHA_RX_PORT_START_NUMBER), + dai->id); + return -EINVAL; + } + + int_mux_cfg0 = WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0; + + /* + * Loop through all interpolator MUX inputs and find out + * to which interpolator input, the slim rx port + * is connected + */ + for (j = 0; j < TASHA_NUM_INTERPOLATORS; j++) { + int_mux_cfg1 = int_mux_cfg0 + 1; + + int_mux_cfg0_val = snd_soc_read(codec, int_mux_cfg0); + int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1); + inp0_sel = int_mux_cfg0_val & 0x0F; + inp1_sel = (int_mux_cfg0_val >> 4) & 0x0F; + inp2_sel = (int_mux_cfg1_val >> 4) & 0x0F; + if ((inp0_sel == int_1_mix1_inp) || + (inp1_sel == int_1_mix1_inp) || + (inp2_sel == int_1_mix1_inp)) { + int_fs_reg = WCD9335_CDC_RX0_RX_PATH_CTL + + 20 * j; + pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_1\n", + __func__, dai->id, j); + pr_debug("%s: set INT%u_1 sample rate to %u\n", + __func__, j, sample_rate); + /* sample_rate is in Hz */ + if ((j == 0) && (sample_rate == 44100)) { + pr_info("%s: Cannot set 44.1KHz on INT0\n", + __func__); + } else + snd_soc_update_bits(codec, int_fs_reg, + 0x0F, int_prim_fs_rate_reg_val); + } + int_mux_cfg0 += 2; + } + } + + return 0; +} + + +static int tasha_set_interpolator_rate(struct snd_soc_dai *dai, + u32 sample_rate) +{ + int rate_val = 0; + int i, ret; + + /* set mixing path rate */ + for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) { + if (sample_rate == + int_mix_sample_rate_val[i].sample_rate) { + rate_val = + int_mix_sample_rate_val[i].rate_val; + break; + } + } + if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) || + (rate_val < 0)) + goto prim_rate; + ret = tasha_set_mix_interpolator_rate(dai, + (u8) rate_val, sample_rate); +prim_rate: + /* set primary path sample rate */ + for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) { + if (sample_rate == + int_prim_sample_rate_val[i].sample_rate) { + rate_val = + int_prim_sample_rate_val[i].rate_val; + break; + } + } + if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) || + (rate_val < 0)) + return -EINVAL; + ret = tasha_set_prim_interpolator_rate(dai, + (u8) rate_val, sample_rate); + return ret; +} + +static int tasha_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec); + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) && + test_bit(SB_CLK_GEAR, &tasha->status_mask)) { + tasha_codec_vote_max_bw(dai->codec, false); + clear_bit(SB_CLK_GEAR, &tasha->status_mask); + } + return 0; +} + +static int tasha_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec); + int ret; + int tx_fs_rate = -EINVAL; + int rx_fs_rate = -EINVAL; + int i2s_bit_mode; + struct snd_soc_codec *codec = dai->codec; + + pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__, + dai->name, dai->id, params_rate(params), + params_channels(params)); + + switch (substream->stream) { + case SNDRV_PCM_STREAM_PLAYBACK: + ret = tasha_set_interpolator_rate(dai, params_rate(params)); + if (ret) { + pr_err("%s: cannot set sample rate: %u\n", + __func__, params_rate(params)); + return ret; + } + switch (params_width(params)) { + case 16: + tasha->dai[dai->id].bit_width = 16; + i2s_bit_mode = 0x01; + break; + case 24: + tasha->dai[dai->id].bit_width = 24; + i2s_bit_mode = 0x00; + break; + default: + return -EINVAL; + } + tasha->dai[dai->id].rate = params_rate(params); + if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { + switch (params_rate(params)) { + case 8000: + rx_fs_rate = 0; + break; + case 16000: + rx_fs_rate = 1; + break; + case 32000: + rx_fs_rate = 2; + break; + case 48000: + rx_fs_rate = 3; + break; + case 96000: + rx_fs_rate = 4; + break; + case 192000: + rx_fs_rate = 5; + break; + default: + dev_err(tasha->dev, + "%s: Invalid RX sample rate: %d\n", + __func__, params_rate(params)); + return -EINVAL; + }; + snd_soc_update_bits(codec, + WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL, + 0x20, i2s_bit_mode << 5); + snd_soc_update_bits(codec, + WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL, + 0x1c, (rx_fs_rate << 2)); + } + break; + case SNDRV_PCM_STREAM_CAPTURE: + switch (params_rate(params)) { + case 8000: + tx_fs_rate = 0; + break; + case 16000: + tx_fs_rate = 1; + break; + case 32000: + tx_fs_rate = 3; + break; + case 48000: + tx_fs_rate = 4; + break; + case 96000: + tx_fs_rate = 5; + break; + case 192000: + tx_fs_rate = 6; + break; + case 384000: + tx_fs_rate = 7; + break; + default: + dev_err(tasha->dev, "%s: Invalid TX sample rate: %d\n", + __func__, params_rate(params)); + return -EINVAL; + + }; + if (dai->id != AIF4_VIFEED && + dai->id != AIF4_MAD_TX) { + ret = tasha_set_decimator_rate(dai, tx_fs_rate, + params_rate(params)); + if (ret < 0) { + dev_err(tasha->dev, "%s: cannot set TX Decimator rate: %d\n", + __func__, tx_fs_rate); + return ret; + } + } + tasha->dai[dai->id].rate = params_rate(params); + switch (params_width(params)) { + case 16: + tasha->dai[dai->id].bit_width = 16; + i2s_bit_mode = 0x01; + break; + case 24: + tasha->dai[dai->id].bit_width = 24; + i2s_bit_mode = 0x00; + break; + case 32: + tasha->dai[dai->id].bit_width = 32; + i2s_bit_mode = 0x00; + break; + default: + dev_err(tasha->dev, "%s: Invalid format 0x%x\n", + __func__, params_width(params)); + return -EINVAL; + }; + if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { + snd_soc_update_bits(codec, + WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL, + 0x20, i2s_bit_mode << 5); + if (tx_fs_rate > 1) + tx_fs_rate--; + snd_soc_update_bits(codec, + WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL, + 0x1c, tx_fs_rate << 2); + snd_soc_update_bits(codec, + WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG, + 0x05, 0x05); + + snd_soc_update_bits(codec, + WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG, + 0x05, 0x05); + + snd_soc_update_bits(codec, + WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG, + 0x05, 0x05); + + snd_soc_update_bits(codec, + WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG, + 0x05, 0x05); + } + break; + default: + pr_err("%s: Invalid stream type %d\n", __func__, + substream->stream); + return -EINVAL; + }; + if (dai->id == AIF4_VIFEED) + tasha->dai[dai->id].bit_width = 32; + + return 0; +} + +static int tasha_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + /* CPU is master */ + if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { + if (dai->id == AIF1_CAP) + snd_soc_update_bits(dai->codec, + WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL, + 0x2, 0); + else if (dai->id == AIF1_PB) + snd_soc_update_bits(dai->codec, + WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL, + 0x2, 0); + } + break; + case SND_SOC_DAIFMT_CBM_CFM: + /* CPU is slave */ + if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { + if (dai->id == AIF1_CAP) + snd_soc_update_bits(dai->codec, + WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL, + 0x2, 0x2); + else if (dai->id == AIF1_PB) + snd_soc_update_bits(dai->codec, + WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL, + 0x2, 0x2); + } + break; + default: + return -EINVAL; + } + return 0; +} + +static int tasha_set_dai_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + pr_debug("%s\n", __func__); + return 0; +} + +static struct snd_soc_dai_ops tasha_dai_ops = { + .startup = tasha_startup, + .shutdown = tasha_shutdown, + .hw_params = tasha_hw_params, + .prepare = tasha_prepare, + .set_sysclk = tasha_set_dai_sysclk, + .set_fmt = tasha_set_dai_fmt, + .set_channel_map = tasha_set_channel_map, + .get_channel_map = tasha_get_channel_map, +}; + +static struct snd_soc_dai_driver tasha_dai[] = { + { + .name = "tasha_rx1", + .id = AIF1_PB, + .playback = { + .stream_name = "AIF1 Playback", + .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, + .formats = TASHA_FORMATS_S16_S24_LE, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tasha_dai_ops, + }, + { + .name = "tasha_tx1", + .id = AIF1_CAP, + .capture = { + .stream_name = "AIF1 Capture", + .rates = WCD9335_RATES_MASK, + .formats = TASHA_FORMATS_S16_S24_LE, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 4, + }, + .ops = &tasha_dai_ops, + }, + { + .name = "tasha_rx2", + .id = AIF2_PB, + .playback = { + .stream_name = "AIF2 Playback", + .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, + .formats = TASHA_FORMATS_S16_S24_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tasha_dai_ops, + }, + { + .name = "tasha_tx2", + .id = AIF2_CAP, + .capture = { + .stream_name = "AIF2 Capture", + .rates = WCD9335_RATES_MASK, + .formats = TASHA_FORMATS_S16_S24_LE, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &tasha_dai_ops, + }, + { + .name = "tasha_rx3", + .id = AIF3_PB, + .playback = { + .stream_name = "AIF3 Playback", + .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, + .formats = TASHA_FORMATS_S16_S24_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tasha_dai_ops, + }, + { + .name = "tasha_tx3", + .id = AIF3_CAP, + .capture = { + .stream_name = "AIF3 Capture", + .rates = WCD9335_RATES_MASK, + .formats = TASHA_FORMATS_S16_S24_LE, + .rate_max = 48000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tasha_dai_ops, + }, + { + .name = "tasha_rx4", + .id = AIF4_PB, + .playback = { + .stream_name = "AIF4 Playback", + .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, + .formats = TASHA_FORMATS_S16_S24_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tasha_dai_ops, + }, + { + .name = "tasha_mix_rx1", + .id = AIF_MIX1_PB, + .playback = { + .stream_name = "AIF Mix Playback", + .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, + .formats = TASHA_FORMATS_S16_S24_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &tasha_dai_ops, + }, + { + .name = "tasha_mad1", + .id = AIF4_MAD_TX, + .capture = { + .stream_name = "AIF4 MAD TX", + .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_384000, + .formats = TASHA_FORMATS_S16_S24_S32_LE, + .rate_min = 16000, + .rate_max = 384000, + .channels_min = 1, + .channels_max = 1, + }, + .ops = &tasha_dai_ops, + }, + { + .name = "tasha_vifeedback", + .id = AIF4_VIFEED, + .capture = { + .stream_name = "VIfeed", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, + .formats = TASHA_FORMATS_S16_S24_S32_LE, + .rate_max = 48000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 4, + }, + .ops = &tasha_dai_ops, + }, + { + .name = "tasha_cpe", + .id = AIF5_CPE_TX, + .capture = { + .stream_name = "AIF5 CPE TX", + .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000, + .formats = TASHA_FORMATS_S16_S24_S32_LE, + .rate_min = 16000, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 1, + }, + }, +}; + +static struct snd_soc_dai_driver tasha_i2s_dai[] = { + { + .name = "tasha_i2s_rx1", + .id = AIF1_PB, + .playback = { + .stream_name = "AIF1 Playback", + .rates = WCD9335_RATES_MASK, + .formats = TASHA_FORMATS_S16_S24_LE, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tasha_dai_ops, + }, + { + .name = "tasha_i2s_tx1", + .id = AIF1_CAP, + .capture = { + .stream_name = "AIF1 Capture", + .rates = WCD9335_RATES_MASK, + .formats = TASHA_FORMATS_S16_S24_LE, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 4, + }, + .ops = &tasha_dai_ops, + }, + { + .name = "tasha_i2s_rx2", + .id = AIF2_PB, + .playback = { + .stream_name = "AIF2 Playback", + .rates = WCD9335_RATES_MASK, + .formats = TASHA_FORMATS_S16_S24_LE, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tasha_dai_ops, + }, + { + .name = "tasha_i2s_tx2", + .id = AIF2_CAP, + .capture = { + .stream_name = "AIF2 Capture", + .rates = WCD9335_RATES_MASK, + .formats = TASHA_FORMATS_S16_S24_LE, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 4, + }, + .ops = &tasha_dai_ops, + }, +}; + +static void tasha_codec_power_gate_digital_core(struct tasha_priv *tasha) +{ + struct snd_soc_codec *codec = tasha->codec; + + if (!codec) + return; + + mutex_lock(&tasha->power_lock); + dev_dbg(codec->dev, "%s: Entering power gating function, %d\n", + __func__, tasha->power_active_ref); + + if (tasha->power_active_ref > 0) + goto exit; + + wcd9xxx_set_power_state(tasha->wcd9xxx, + WCD_REGION_POWER_COLLAPSE_BEGIN, + WCD9XXX_DIG_CORE_REGION_1); + snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x04, 0x04); + snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x01, 0x00); + snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x02, 0x00); + clear_bit(AUDIO_NOMINAL, &tasha->status_mask); + tasha_codec_update_sido_voltage(tasha, sido_buck_svs_voltage); + wcd9xxx_set_power_state(tasha->wcd9xxx, WCD_REGION_POWER_DOWN, + WCD9XXX_DIG_CORE_REGION_1); +exit: + dev_dbg(codec->dev, "%s: Exiting power gating function, %d\n", + __func__, tasha->power_active_ref); + mutex_unlock(&tasha->power_lock); +} + +static void tasha_codec_power_gate_work(struct work_struct *work) +{ + struct tasha_priv *tasha; + struct delayed_work *dwork; + struct snd_soc_codec *codec; + + dwork = to_delayed_work(work); + tasha = container_of(dwork, struct tasha_priv, power_gate_work); + codec = tasha->codec; + + if (!codec) + return; + + tasha_codec_power_gate_digital_core(tasha); +} + +/* called under power_lock acquisition */ +static int tasha_dig_core_remove_power_collapse(struct snd_soc_codec *codec) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + tasha_codec_vote_max_bw(codec, true); + snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5); + snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7); + snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3); + snd_soc_update_bits(codec, WCD9335_CODEC_RPM_RST_CTL, 0x02, 0x00); + snd_soc_update_bits(codec, WCD9335_CODEC_RPM_RST_CTL, 0x02, 0x02); + + wcd9xxx_set_power_state(tasha->wcd9xxx, + WCD_REGION_POWER_COLLAPSE_REMOVE, + WCD9XXX_DIG_CORE_REGION_1); + regcache_mark_dirty(codec->component.regmap); + regcache_sync_region(codec->component.regmap, + TASHA_DIG_CORE_REG_MIN, TASHA_DIG_CORE_REG_MAX); + tasha_codec_vote_max_bw(codec, false); + + return 0; +} + +static int tasha_dig_core_power_collapse(struct tasha_priv *tasha, + int req_state) +{ + struct snd_soc_codec *codec; + int cur_state; + + /* Exit if feature is disabled */ + if (!dig_core_collapse_enable) + return 0; + + mutex_lock(&tasha->power_lock); + if (req_state == POWER_COLLAPSE) + tasha->power_active_ref--; + else if (req_state == POWER_RESUME) + tasha->power_active_ref++; + else + goto unlock_mutex; + + if (tasha->power_active_ref < 0) { + dev_dbg(tasha->dev, "%s: power_active_ref is negative\n", + __func__); + goto unlock_mutex; + } + + codec = tasha->codec; + if (!codec) + goto unlock_mutex; + + if (req_state == POWER_COLLAPSE) { + if (tasha->power_active_ref == 0) { + schedule_delayed_work(&tasha->power_gate_work, + msecs_to_jiffies(dig_core_collapse_timer * 1000)); + } + } else if (req_state == POWER_RESUME) { + if (tasha->power_active_ref == 1) { + /* + * At this point, there can be two cases: + * 1. Core already in power collapse state + * 2. Timer kicked in and still did not expire or + * waiting for the power_lock + */ + cur_state = wcd9xxx_get_current_power_state( + tasha->wcd9xxx, + WCD9XXX_DIG_CORE_REGION_1); + if (cur_state == WCD_REGION_POWER_DOWN) + tasha_dig_core_remove_power_collapse(codec); + else { + mutex_unlock(&tasha->power_lock); + cancel_delayed_work_sync( + &tasha->power_gate_work); + mutex_lock(&tasha->power_lock); + } + } + } + +unlock_mutex: + mutex_unlock(&tasha->power_lock); + + return 0; +} + +static int __tasha_cdc_mclk_enable_locked(struct tasha_priv *tasha, + bool enable) +{ + int ret = 0; + + if (!tasha->wcd_ext_clk) { + dev_err(tasha->dev, "%s: wcd ext clock is NULL\n", __func__); + return -EINVAL; + } + + dev_dbg(tasha->dev, "%s: mclk_enable = %u\n", __func__, enable); + + if (enable) { + tasha_dig_core_power_collapse(tasha, POWER_RESUME); + ret = tasha_cdc_req_mclk_enable(tasha, true); + if (ret) + goto err; + + set_bit(AUDIO_NOMINAL, &tasha->status_mask); + tasha_codec_apply_sido_voltage(tasha, + SIDO_VOLTAGE_NOMINAL_MV); + } else { + if (!dig_core_collapse_enable) { + clear_bit(AUDIO_NOMINAL, &tasha->status_mask); + tasha_codec_update_sido_voltage(tasha, + sido_buck_svs_voltage); + } + tasha_cdc_req_mclk_enable(tasha, false); + tasha_dig_core_power_collapse(tasha, POWER_COLLAPSE); + } + +err: + return ret; +} + +static int __tasha_cdc_mclk_enable(struct tasha_priv *tasha, + bool enable) +{ + int ret; + + WCD9XXX_V2_BG_CLK_LOCK(tasha->resmgr); + ret = __tasha_cdc_mclk_enable_locked(tasha, enable); + WCD9XXX_V2_BG_CLK_UNLOCK(tasha->resmgr); + + return ret; +} + +int tasha_cdc_mclk_enable(struct snd_soc_codec *codec, int enable, bool dapm) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + return __tasha_cdc_mclk_enable(tasha, enable); +} +EXPORT_SYMBOL(tasha_cdc_mclk_enable); + +int tasha_cdc_mclk_tx_enable(struct snd_soc_codec *codec, int enable, bool dapm) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + dev_dbg(tasha->dev, "%s: clk_mode: %d, enable: %d, clk_internal: %d\n", + __func__, tasha->clk_mode, enable, tasha->clk_internal); + if (tasha->clk_mode || tasha->clk_internal) { + if (enable) { + tasha_cdc_sido_ccl_enable(tasha, true); + wcd_resmgr_enable_master_bias(tasha->resmgr); + tasha_dig_core_power_collapse(tasha, POWER_RESUME); + snd_soc_update_bits(codec, + WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); + snd_soc_update_bits(codec, + WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + set_bit(CPE_NOMINAL, &tasha->status_mask); + tasha_codec_update_sido_voltage(tasha, + SIDO_VOLTAGE_NOMINAL_MV); + tasha->clk_internal = true; + } else { + tasha->clk_internal = false; + clear_bit(CPE_NOMINAL, &tasha->status_mask); + tasha_codec_update_sido_voltage(tasha, + sido_buck_svs_voltage); + tasha_dig_core_power_collapse(tasha, POWER_COLLAPSE); + wcd_resmgr_disable_master_bias(tasha->resmgr); + tasha_cdc_sido_ccl_enable(tasha, false); + } + } else { + ret = __tasha_cdc_mclk_enable(tasha, enable); + } + return ret; +} +EXPORT_SYMBOL(tasha_cdc_mclk_tx_enable); + +static ssize_t tasha_codec_version_read(struct snd_info_entry *entry, + void *file_private_data, struct file *file, + char __user *buf, size_t count, loff_t pos) +{ + struct tasha_priv *tasha; + struct wcd9xxx *wcd9xxx; + char buffer[TASHA_VERSION_ENTRY_SIZE]; + int len = 0; + + tasha = (struct tasha_priv *) entry->private_data; + if (!tasha) { + pr_err("%s: tasha priv is null\n", __func__); + return -EINVAL; + } + + wcd9xxx = tasha->wcd9xxx; + + if (wcd9xxx->codec_type->id_major == TASHA_MAJOR) { + if (TASHA_IS_1_0(wcd9xxx)) + len = snprintf(buffer, sizeof(buffer), "WCD9335_1_0\n"); + else if (TASHA_IS_1_1(wcd9xxx)) + len = snprintf(buffer, sizeof(buffer), "WCD9335_1_1\n"); + else + snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + } else if (wcd9xxx->codec_type->id_major == TASHA2P0_MAJOR) { + len = snprintf(buffer, sizeof(buffer), "WCD9335_2_0\n"); + } else + len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops tasha_codec_info_ops = { + .read = tasha_codec_version_read, +}; + +/* + * tasha_codec_info_create_codec_entry - creates wcd9335 module + * @codec_root: The parent directory + * @codec: Codec instance + * + * Creates wcd9335 module and version entry under the given + * parent directory. + * + * Return: 0 on success or negative error code on failure. + */ +int tasha_codec_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + struct snd_info_entry *version_entry; + struct tasha_priv *tasha; + struct snd_soc_card *card; + + if (!codec_root || !codec) + return -EINVAL; + + tasha = snd_soc_codec_get_drvdata(codec); + card = codec->component.card; + tasha->entry = snd_info_create_subdir(codec_root->module, + "tasha", codec_root); + if (!tasha->entry) { + dev_dbg(codec->dev, "%s: failed to create wcd9335 entry\n", + __func__); + return -ENOMEM; + } + + version_entry = snd_info_create_card_entry(card->snd_card, + "version", + tasha->entry); + if (!version_entry) { + dev_dbg(codec->dev, "%s: failed to create wcd9335 version entry\n", + __func__); + return -ENOMEM; + } + + version_entry->private_data = tasha; + version_entry->size = TASHA_VERSION_ENTRY_SIZE; + version_entry->content = SNDRV_INFO_CONTENT_DATA; + version_entry->c.ops = &tasha_codec_info_ops; + + if (snd_info_register(version_entry) < 0) { + snd_info_free_entry(version_entry); + return -ENOMEM; + } + tasha->version_entry = version_entry; + + return 0; +} +EXPORT_SYMBOL(tasha_codec_info_create_codec_entry); + +static int __tasha_codec_internal_rco_ctrl( + struct snd_soc_codec *codec, bool enable) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + if (enable) { + tasha_cdc_sido_ccl_enable(tasha, true); + if (wcd_resmgr_get_clk_type(tasha->resmgr) == + WCD_CLK_RCO) { + ret = wcd_resmgr_enable_clk_block(tasha->resmgr, + WCD_CLK_RCO); + } else { + ret = tasha_cdc_req_mclk_enable(tasha, true); + ret |= wcd_resmgr_enable_clk_block(tasha->resmgr, + WCD_CLK_RCO); + ret |= tasha_cdc_req_mclk_enable(tasha, false); + } + + } else { + ret = wcd_resmgr_disable_clk_block(tasha->resmgr, + WCD_CLK_RCO); + tasha_cdc_sido_ccl_enable(tasha, false); + } + + if (ret) { + dev_err(codec->dev, "%s: Error in %s RCO\n", + __func__, (enable ? "enabling" : "disabling")); + ret = -EINVAL; + } + + return ret; +} + +/* + * tasha_codec_internal_rco_ctrl() + * Make sure that the caller does not acquire + * BG_CLK_LOCK. + */ +static int tasha_codec_internal_rco_ctrl(struct snd_soc_codec *codec, + bool enable) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + WCD9XXX_V2_BG_CLK_LOCK(tasha->resmgr); + ret = __tasha_codec_internal_rco_ctrl(codec, enable); + WCD9XXX_V2_BG_CLK_UNLOCK(tasha->resmgr); + return ret; +} + +/* + * tasha_mbhc_hs_detect: starts mbhc insertion/removal functionality + * @codec: handle to snd_soc_codec * + * @mbhc_cfg: handle to mbhc configuration structure + * return 0 if mbhc_start is success or error code in case of failure + */ +int tasha_mbhc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + return wcd_mbhc_start(&tasha->mbhc, mbhc_cfg); +} +EXPORT_SYMBOL(tasha_mbhc_hs_detect); + +/* + * tasha_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality + * @codec: handle to snd_soc_codec * + */ +void tasha_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + wcd_mbhc_stop(&tasha->mbhc); +} +EXPORT_SYMBOL(tasha_mbhc_hs_detect_exit); + +static int wcd9335_get_micb_vout_ctl_val(u32 micb_mv) +{ + /* min micbias voltage is 1V and maximum is 2.85V */ + if (micb_mv < 1000 || micb_mv > 2850) { + pr_err("%s: unsupported micbias voltage\n", __func__); + return -EINVAL; + } + + return (micb_mv - 1000) / 50; +} + +static const struct tasha_reg_mask_val tasha_reg_update_reset_val_1_1[] = { + {WCD9335_RCO_CTRL_2, 0xFF, 0x47}, + {WCD9335_FLYBACK_VNEG_DAC_CTRL_4, 0xFF, 0x60}, +}; + +static const struct tasha_reg_mask_val tasha_codec_reg_init_val_1_1[] = { + {WCD9335_FLYBACK_VNEG_DAC_CTRL_1, 0xFF, 0x65}, + {WCD9335_FLYBACK_VNEG_DAC_CTRL_2, 0xFF, 0x52}, + {WCD9335_FLYBACK_VNEG_DAC_CTRL_3, 0xFF, 0xAF}, + {WCD9335_FLYBACK_VNEG_DAC_CTRL_4, 0xFF, 0x60}, + {WCD9335_FLYBACK_VNEG_CTRL_3, 0xFF, 0xF4}, + {WCD9335_FLYBACK_VNEG_CTRL_9, 0xFF, 0x40}, + {WCD9335_FLYBACK_VNEG_CTRL_2, 0xFF, 0x4F}, + {WCD9335_FLYBACK_EN, 0xFF, 0x6E}, + {WCD9335_CDC_RX2_RX_PATH_SEC0, 0xF8, 0xF8}, + {WCD9335_CDC_RX1_RX_PATH_SEC0, 0xF8, 0xF8}, +}; + +static const struct tasha_reg_mask_val tasha_codec_reg_init_val_1_0[] = { + {WCD9335_FLYBACK_VNEG_CTRL_3, 0xFF, 0x54}, + {WCD9335_CDC_RX2_RX_PATH_SEC0, 0xFC, 0xFC}, + {WCD9335_CDC_RX1_RX_PATH_SEC0, 0xFC, 0xFC}, +}; + +static const struct tasha_reg_mask_val tasha_codec_reg_init_val_2_0[] = { + {WCD9335_RCO_CTRL_2, 0x0F, 0x08}, + {WCD9335_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10}, + {WCD9335_FLYBACK_CTRL_1, 0x20, 0x20}, + {WCD9335_HPH_OCP_CTL, 0xFF, 0x7A}, + {WCD9335_HPH_L_TEST, 0x01, 0x01}, + {WCD9335_HPH_R_TEST, 0x01, 0x01}, + {WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12}, + {WCD9335_CDC_BOOST0_BOOST_CFG2, 0x1C, 0x08}, + {WCD9335_CDC_COMPANDER7_CTL7, 0x1E, 0x18}, + {WCD9335_CDC_BOOST1_BOOST_CFG1, 0x3F, 0x12}, + {WCD9335_CDC_BOOST1_BOOST_CFG2, 0x1C, 0x08}, + {WCD9335_CDC_COMPANDER8_CTL7, 0x1E, 0x18}, + {WCD9335_CDC_TX0_TX_PATH_SEC7, 0xFF, 0x45}, + {WCD9335_CDC_RX0_RX_PATH_SEC0, 0xFC, 0xF4}, + {WCD9335_HPH_REFBUFF_LP_CTL, 0x08, 0x08}, + {WCD9335_HPH_REFBUFF_LP_CTL, 0x06, 0x02}, + {WCD9335_DIFF_LO_CORE_OUT_PROG, 0xFC, 0xA0}, + {WCD9335_SE_LO_COM1, 0xFF, 0xC0}, + {WCD9335_CDC_RX3_RX_PATH_SEC0, 0xFC, 0xF4}, + {WCD9335_CDC_RX4_RX_PATH_SEC0, 0xFC, 0xF4}, + {WCD9335_CDC_RX5_RX_PATH_SEC0, 0xFC, 0xF8}, + {WCD9335_CDC_RX6_RX_PATH_SEC0, 0xFC, 0xF8}, +}; + +static const struct tasha_reg_mask_val tasha_codec_reg_defaults[] = { + {WCD9335_CODEC_RPM_CLK_GATE, 0x03, 0x00}, + {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x01}, + {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x04, 0x04}, +}; + +static const struct tasha_reg_mask_val tasha_codec_reg_i2c_defaults[] = { + {WCD9335_ANA_CLK_TOP, 0x20, 0x20}, + {WCD9335_CODEC_RPM_CLK_GATE, 0x03, 0x01}, + {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x00}, + {WCD9335_CODEC_RPM_CLK_MCLK_CFG, 0x05, 0x05}, + {WCD9335_DATA_HUB_DATA_HUB_RX0_INP_CFG, 0x01, 0x01}, + {WCD9335_DATA_HUB_DATA_HUB_RX1_INP_CFG, 0x01, 0x01}, + {WCD9335_DATA_HUB_DATA_HUB_RX2_INP_CFG, 0x01, 0x01}, + {WCD9335_DATA_HUB_DATA_HUB_RX3_INP_CFG, 0x01, 0x01}, + {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG, 0x05, 0x05}, + {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG, 0x05, 0x05}, + {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG, 0x05, 0x05}, + {WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG, 0x05, 0x05}, +}; + +static const struct tasha_reg_mask_val tasha_codec_reg_init_common_val[] = { + /* Rbuckfly/R_EAR(32) */ + {WCD9335_CDC_CLSH_K2_MSB, 0x0F, 0x00}, + {WCD9335_CDC_CLSH_K2_LSB, 0xFF, 0x60}, + {WCD9335_CPE_SS_DMIC_CFG, 0x80, 0x00}, + {WCD9335_CDC_BOOST0_BOOST_CTL, 0x70, 0x50}, + {WCD9335_CDC_BOOST1_BOOST_CTL, 0x70, 0x50}, + {WCD9335_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08}, + {WCD9335_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08}, + {WCD9335_ANA_LO_1_2, 0x3C, 0X3C}, + {WCD9335_DIFF_LO_COM_SWCAP_REFBUF_FREQ, 0x70, 0x00}, + {WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03, 0x03}, + {WCD9335_CDC_TOP_TOP_CFG1, 0x02, 0x02}, + {WCD9335_CDC_TOP_TOP_CFG1, 0x01, 0x01}, + {WCD9335_EAR_CMBUFF, 0x08, 0x00}, + {WCD9335_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {WCD9335_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {WCD9335_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {WCD9335_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x80}, + {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80}, + {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01}, + {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01}, + {WCD9335_CDC_RX0_RX_PATH_CFG0, 0x01, 0x01}, + {WCD9335_CDC_RX1_RX_PATH_CFG0, 0x01, 0x01}, + {WCD9335_CDC_RX2_RX_PATH_CFG0, 0x01, 0x01}, + {WCD9335_CDC_RX3_RX_PATH_CFG0, 0x01, 0x01}, + {WCD9335_CDC_RX4_RX_PATH_CFG0, 0x01, 0x01}, + {WCD9335_CDC_RX5_RX_PATH_CFG0, 0x01, 0x01}, + {WCD9335_CDC_RX6_RX_PATH_CFG0, 0x01, 0x01}, + {WCD9335_CDC_RX7_RX_PATH_CFG0, 0x01, 0x01}, + {WCD9335_CDC_RX8_RX_PATH_CFG0, 0x01, 0x01}, + {WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 0x01, 0x01}, + {WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 0x01, 0x01}, + {WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 0x01, 0x01}, + {WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 0x01, 0x01}, + {WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 0x01, 0x01}, + {WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 0x01, 0x01}, + {WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 0x01, 0x01}, + {WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 0x01, 0x01}, + {WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 0x01, 0x01}, + {WCD9335_VBADC_IBIAS_FE, 0x0C, 0x08}, +}; + +static const struct tasha_reg_mask_val tasha_codec_reg_init_1_x_val[] = { + /* Enable TX HPF Filter & Linear Phase */ + {WCD9335_CDC_TX0_TX_PATH_CFG0, 0x11, 0x11}, + {WCD9335_CDC_TX1_TX_PATH_CFG0, 0x11, 0x11}, + {WCD9335_CDC_TX2_TX_PATH_CFG0, 0x11, 0x11}, + {WCD9335_CDC_TX3_TX_PATH_CFG0, 0x11, 0x11}, + {WCD9335_CDC_TX4_TX_PATH_CFG0, 0x11, 0x11}, + {WCD9335_CDC_TX5_TX_PATH_CFG0, 0x11, 0x11}, + {WCD9335_CDC_TX6_TX_PATH_CFG0, 0x11, 0x11}, + {WCD9335_CDC_TX7_TX_PATH_CFG0, 0x11, 0x11}, + {WCD9335_CDC_TX8_TX_PATH_CFG0, 0x11, 0x11}, + {WCD9335_CDC_RX0_RX_PATH_SEC0, 0xF8, 0xF8}, + {WCD9335_CDC_RX0_RX_PATH_SEC1, 0x08, 0x08}, + {WCD9335_CDC_RX1_RX_PATH_SEC1, 0x08, 0x08}, + {WCD9335_CDC_RX2_RX_PATH_SEC1, 0x08, 0x08}, + {WCD9335_CDC_RX3_RX_PATH_SEC1, 0x08, 0x08}, + {WCD9335_CDC_RX4_RX_PATH_SEC1, 0x08, 0x08}, + {WCD9335_CDC_RX5_RX_PATH_SEC1, 0x08, 0x08}, + {WCD9335_CDC_RX6_RX_PATH_SEC1, 0x08, 0x08}, + {WCD9335_CDC_RX7_RX_PATH_SEC1, 0x08, 0x08}, + {WCD9335_CDC_RX8_RX_PATH_SEC1, 0x08, 0x08}, + {WCD9335_CDC_RX0_RX_PATH_MIX_SEC0, 0x08, 0x08}, + {WCD9335_CDC_RX1_RX_PATH_MIX_SEC0, 0x08, 0x08}, + {WCD9335_CDC_RX2_RX_PATH_MIX_SEC0, 0x08, 0x08}, + {WCD9335_CDC_RX3_RX_PATH_MIX_SEC0, 0x08, 0x08}, + {WCD9335_CDC_RX4_RX_PATH_MIX_SEC0, 0x08, 0x08}, + {WCD9335_CDC_RX5_RX_PATH_MIX_SEC0, 0x08, 0x08}, + {WCD9335_CDC_RX6_RX_PATH_MIX_SEC0, 0x08, 0x08}, + {WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, 0x08, 0x08}, + {WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, 0x08, 0x08}, + {WCD9335_CDC_TX0_TX_PATH_SEC2, 0x01, 0x01}, + {WCD9335_CDC_TX1_TX_PATH_SEC2, 0x01, 0x01}, + {WCD9335_CDC_TX2_TX_PATH_SEC2, 0x01, 0x01}, + {WCD9335_CDC_TX3_TX_PATH_SEC2, 0x01, 0x01}, + {WCD9335_CDC_TX4_TX_PATH_SEC2, 0x01, 0x01}, + {WCD9335_CDC_TX5_TX_PATH_SEC2, 0x01, 0x01}, + {WCD9335_CDC_TX6_TX_PATH_SEC2, 0x01, 0x01}, + {WCD9335_CDC_TX7_TX_PATH_SEC2, 0x01, 0x01}, + {WCD9335_CDC_TX8_TX_PATH_SEC2, 0x01, 0x01}, + {WCD9335_CDC_RX3_RX_PATH_SEC0, 0xF8, 0xF0}, + {WCD9335_CDC_RX4_RX_PATH_SEC0, 0xF8, 0xF0}, + {WCD9335_CDC_RX5_RX_PATH_SEC0, 0xF8, 0xF8}, + {WCD9335_CDC_RX6_RX_PATH_SEC0, 0xF8, 0xF8}, + {WCD9335_RX_OCP_COUNT, 0xFF, 0xFF}, + {WCD9335_HPH_OCP_CTL, 0xF0, 0x70}, + {WCD9335_CPE_SS_CPAR_CFG, 0xFF, 0x00}, + {WCD9335_FLYBACK_VNEG_CTRL_1, 0xFF, 0x63}, + {WCD9335_FLYBACK_VNEG_CTRL_4, 0xFF, 0x7F}, + {WCD9335_CLASSH_CTRL_VCL_1, 0xFF, 0x60}, + {WCD9335_CLASSH_CTRL_CCL_5, 0xFF, 0x40}, + {WCD9335_RX_TIMER_DIV, 0xFF, 0x32}, + {WCD9335_SE_LO_COM2, 0xFF, 0x01}, + {WCD9335_MBHC_ZDET_ANA_CTL, 0x0F, 0x07}, + {WCD9335_RX_BIAS_HPH_PA, 0xF0, 0x60}, + {WCD9335_HPH_RDAC_LDO_CTL, 0x88, 0x88}, + {WCD9335_HPH_L_EN, 0x20, 0x20}, + {WCD9335_HPH_R_EN, 0x20, 0x20}, + {WCD9335_DIFF_LO_CORE_OUT_PROG, 0xFC, 0xD8}, + {WCD9335_CDC_RX5_RX_PATH_SEC3, 0xBD, 0xBD}, + {WCD9335_CDC_RX6_RX_PATH_SEC3, 0xBD, 0xBD}, + {WCD9335_DIFF_LO_COM_PA_FREQ, 0x70, 0x40}, +}; + +static void tasha_update_reg_reset_values(struct snd_soc_codec *codec) +{ + u32 i; + struct wcd9xxx *tasha_core = dev_get_drvdata(codec->dev->parent); + + if (TASHA_IS_1_1(tasha_core)) { + for (i = 0; i < ARRAY_SIZE(tasha_reg_update_reset_val_1_1); + i++) + snd_soc_write(codec, + tasha_reg_update_reset_val_1_1[i].reg, + tasha_reg_update_reset_val_1_1[i].val); + } +} + +static void tasha_codec_init_reg(struct snd_soc_codec *codec) +{ + u32 i; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + + for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_common_val); i++) + snd_soc_update_bits(codec, + tasha_codec_reg_init_common_val[i].reg, + tasha_codec_reg_init_common_val[i].mask, + tasha_codec_reg_init_common_val[i].val); + + if (TASHA_IS_1_1(wcd9xxx) || + TASHA_IS_1_0(wcd9xxx)) + for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_1_x_val); i++) + snd_soc_update_bits(codec, + tasha_codec_reg_init_1_x_val[i].reg, + tasha_codec_reg_init_1_x_val[i].mask, + tasha_codec_reg_init_1_x_val[i].val); + + if (TASHA_IS_1_1(wcd9xxx)) { + for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_1_1); i++) + snd_soc_update_bits(codec, + tasha_codec_reg_init_val_1_1[i].reg, + tasha_codec_reg_init_val_1_1[i].mask, + tasha_codec_reg_init_val_1_1[i].val); + } else if (TASHA_IS_1_0(wcd9xxx)) { + for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_1_0); i++) + snd_soc_update_bits(codec, + tasha_codec_reg_init_val_1_0[i].reg, + tasha_codec_reg_init_val_1_0[i].mask, + tasha_codec_reg_init_val_1_0[i].val); + } else if (TASHA_IS_2_0(wcd9xxx)) { + for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_2_0); i++) + snd_soc_update_bits(codec, + tasha_codec_reg_init_val_2_0[i].reg, + tasha_codec_reg_init_val_2_0[i].mask, + tasha_codec_reg_init_val_2_0[i].val); + } +} + +static void tasha_update_reg_defaults(struct tasha_priv *tasha) +{ + u32 i; + struct wcd9xxx *wcd9xxx; + + wcd9xxx = tasha->wcd9xxx; + for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_defaults); i++) + regmap_update_bits(wcd9xxx->regmap, + tasha_codec_reg_defaults[i].reg, + tasha_codec_reg_defaults[i].mask, + tasha_codec_reg_defaults[i].val); + + tasha->intf_type = wcd9xxx_get_intf_type(); + if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) + for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_i2c_defaults); i++) + regmap_update_bits(wcd9xxx->regmap, + tasha_codec_reg_i2c_defaults[i].reg, + tasha_codec_reg_i2c_defaults[i].mask, + tasha_codec_reg_i2c_defaults[i].val); + +} + +static void tasha_slim_interface_init_reg(struct snd_soc_codec *codec) +{ + int i; + struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + + for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++) + wcd9xxx_interface_reg_write(priv->wcd9xxx, + TASHA_SLIM_PGD_PORT_INT_EN0 + i, + 0xFF); +} + +static irqreturn_t tasha_slimbus_irq(int irq, void *data) +{ + struct tasha_priv *priv = data; + unsigned long status = 0; + int i, j, port_id, k; + u32 bit; + u8 val, int_val = 0; + bool tx, cleared; + unsigned short reg = 0; + + for (i = TASHA_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0; + i <= TASHA_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) { + val = wcd9xxx_interface_reg_read(priv->wcd9xxx, i); + status |= ((u32)val << (8 * j)); + } + + for_each_set_bit(j, &status, 32) { + tx = (j >= 16 ? true : false); + port_id = (tx ? j - 16 : j); + val = wcd9xxx_interface_reg_read(priv->wcd9xxx, + TASHA_SLIM_PGD_PORT_INT_RX_SOURCE0 + j); + if (val) { + if (!tx) + reg = TASHA_SLIM_PGD_PORT_INT_EN0 + + (port_id / 8); + else + reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 + + (port_id / 8); + int_val = wcd9xxx_interface_reg_read( + priv->wcd9xxx, reg); + /* + * Ignore interrupts for ports for which the + * interrupts are not specifically enabled. + */ + if (!(int_val & (1 << (port_id % 8)))) + continue; + } + if (val & TASHA_SLIM_IRQ_OVERFLOW) + pr_err_ratelimited( + "%s: overflow error on %s port %d, value %x\n", + __func__, (tx ? "TX" : "RX"), port_id, val); + if (val & TASHA_SLIM_IRQ_UNDERFLOW) + pr_err_ratelimited( + "%s: underflow error on %s port %d, value %x\n", + __func__, (tx ? "TX" : "RX"), port_id, val); + if ((val & TASHA_SLIM_IRQ_OVERFLOW) || + (val & TASHA_SLIM_IRQ_UNDERFLOW)) { + if (!tx) + reg = TASHA_SLIM_PGD_PORT_INT_EN0 + + (port_id / 8); + else + reg = TASHA_SLIM_PGD_PORT_INT_TX_EN0 + + (port_id / 8); + int_val = wcd9xxx_interface_reg_read( + priv->wcd9xxx, reg); + if (int_val & (1 << (port_id % 8))) { + int_val = int_val ^ (1 << (port_id % 8)); + wcd9xxx_interface_reg_write(priv->wcd9xxx, + reg, int_val); + } + } + if (val & TASHA_SLIM_IRQ_PORT_CLOSED) { + /* + * INT SOURCE register starts from RX to TX + * but port number in the ch_mask is in opposite way + */ + bit = (tx ? j - 16 : j + 16); + pr_debug("%s: %s port %d closed value %x, bit %u\n", + __func__, (tx ? "TX" : "RX"), port_id, val, + bit); + for (k = 0, cleared = false; k < NUM_CODEC_DAIS; k++) { + pr_debug("%s: priv->dai[%d].ch_mask = 0x%lx\n", + __func__, k, priv->dai[k].ch_mask); + if (test_and_clear_bit(bit, + &priv->dai[k].ch_mask)) { + cleared = true; + if (!priv->dai[k].ch_mask) + wake_up(&priv->dai[k].dai_wait); + /* + * There are cases when multiple DAIs + * might be using the same slimbus + * channel. Hence don't break here. + */ + } + } + WARN(!cleared, + "Couldn't find slimbus %s port %d for closing\n", + (tx ? "TX" : "RX"), port_id); + } + wcd9xxx_interface_reg_write(priv->wcd9xxx, + TASHA_SLIM_PGD_PORT_INT_CLR_RX_0 + + (j / 8), + 1 << (j % 8)); + } + + return IRQ_HANDLED; +} + +static int tasha_setup_irqs(struct tasha_priv *tasha) +{ + int ret = 0; + struct snd_soc_codec *codec = tasha->codec; + struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + + ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_SLIMBUS, + tasha_slimbus_irq, "SLIMBUS Slave", tasha); + if (ret) + pr_err("%s: Failed to request irq %d\n", __func__, + WCD9XXX_IRQ_SLIMBUS); + else + tasha_slim_interface_init_reg(codec); + + return ret; +} + +static void tasha_init_slim_slave_cfg(struct snd_soc_codec *codec) +{ + struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + struct afe_param_cdc_slimbus_slave_cfg *cfg; + struct wcd9xxx *wcd9xxx = priv->wcd9xxx; + uint64_t eaddr = 0; + + cfg = &priv->slimbus_slave_cfg; + cfg->minor_version = 1; + cfg->tx_slave_port_offset = 0; + cfg->rx_slave_port_offset = 16; + + memcpy(&eaddr, &wcd9xxx->slim->e_addr, sizeof(wcd9xxx->slim->e_addr)); + WARN_ON(sizeof(wcd9xxx->slim->e_addr) != 6); + cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF; + cfg->device_enum_addr_msw = eaddr >> 32; + + dev_dbg(codec->dev, "%s: slimbus logical address 0x%llx\n", + __func__, eaddr); +} + +static void tasha_cleanup_irqs(struct tasha_priv *tasha) +{ + struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + + wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_SLIMBUS, tasha); +} + +static int tasha_handle_pdata(struct tasha_priv *tasha, + struct wcd9xxx_pdata *pdata) +{ + struct snd_soc_codec *codec = tasha->codec; + u8 dmic_ctl_val, mad_dmic_ctl_val; + u8 anc_ctl_value; + u32 def_dmic_rate, dmic_clk_drv; + int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4; + int rc = 0; + + if (!pdata) { + dev_err(codec->dev, "%s: NULL pdata\n", __func__); + return -ENODEV; + } + + /* set micbias voltage */ + vout_ctl_1 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb1_mv); + vout_ctl_2 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb2_mv); + vout_ctl_3 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb3_mv); + vout_ctl_4 = wcd9335_get_micb_vout_ctl_val(pdata->micbias.micb4_mv); + if (vout_ctl_1 < 0 || vout_ctl_2 < 0 || + vout_ctl_3 < 0 || vout_ctl_4 < 0) { + rc = -EINVAL; + goto done; + } + snd_soc_update_bits(codec, WCD9335_ANA_MICB1, 0x3F, vout_ctl_1); + snd_soc_update_bits(codec, WCD9335_ANA_MICB2, 0x3F, vout_ctl_2); + snd_soc_update_bits(codec, WCD9335_ANA_MICB3, 0x3F, vout_ctl_3); + snd_soc_update_bits(codec, WCD9335_ANA_MICB4, 0x3F, vout_ctl_4); + + /* Set the DMIC sample rate */ + switch (pdata->mclk_rate) { + case TASHA_MCLK_CLK_9P6MHZ: + def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ; + break; + case TASHA_MCLK_CLK_12P288MHZ: + def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ; + break; + default: + /* should never happen */ + dev_err(codec->dev, "%s: Invalid mclk_rate %d\n", + __func__, pdata->mclk_rate); + rc = -EINVAL; + goto done; + }; + + if (pdata->dmic_sample_rate == + WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) { + dev_info(codec->dev, "%s: dmic_rate invalid default = %d\n", + __func__, def_dmic_rate); + pdata->dmic_sample_rate = def_dmic_rate; + } + if (pdata->mad_dmic_sample_rate == + WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) { + dev_info(codec->dev, "%s: mad_dmic_rate invalid default = %d\n", + __func__, def_dmic_rate); + /* + * use dmic_sample_rate as the default for MAD + * if mad dmic sample rate is undefined + */ + pdata->mad_dmic_sample_rate = pdata->dmic_sample_rate; + } + if (pdata->ecpp_dmic_sample_rate == + WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) { + dev_info(codec->dev, + "%s: ecpp_dmic_rate invalid default = %d\n", + __func__, def_dmic_rate); + /* + * use dmic_sample_rate as the default for ECPP DMIC + * if ecpp dmic sample rate is undefined + */ + pdata->ecpp_dmic_sample_rate = pdata->dmic_sample_rate; + } + + if (pdata->dmic_clk_drv == + WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED) { + pdata->dmic_clk_drv = WCD9335_DMIC_CLK_DRIVE_DEFAULT; + dev_info(codec->dev, + "%s: dmic_clk_strength invalid, default = %d\n", + __func__, pdata->dmic_clk_drv); + } + + switch (pdata->dmic_clk_drv) { + case 2: + dmic_clk_drv = 0; + break; + case 4: + dmic_clk_drv = 1; + break; + case 8: + dmic_clk_drv = 2; + break; + case 16: + dmic_clk_drv = 3; + break; + default: + dev_err(codec->dev, + "%s: invalid dmic_clk_drv %d, using default\n", + __func__, pdata->dmic_clk_drv); + dmic_clk_drv = 0; + break; + } + + snd_soc_update_bits(codec, WCD9335_TEST_DEBUG_PAD_DRVCTL, + 0x0C, dmic_clk_drv << 2); + + /* + * Default the DMIC clk rates to mad_dmic_sample_rate, + * whereas, the anc/txfe dmic rates to dmic_sample_rate + * since the anc/txfe are independent of mad block. + */ + mad_dmic_ctl_val = tasha_get_dmic_clk_val(tasha->codec, + pdata->mclk_rate, + pdata->mad_dmic_sample_rate); + snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC0_CTL, + 0x0E, mad_dmic_ctl_val << 1); + snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC1_CTL, + 0x0E, mad_dmic_ctl_val << 1); + snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC2_CTL, + 0x0E, mad_dmic_ctl_val << 1); + + dmic_ctl_val = tasha_get_dmic_clk_val(tasha->codec, + pdata->mclk_rate, + pdata->dmic_sample_rate); + + if (dmic_ctl_val == WCD9335_DMIC_CLK_DIV_2) + anc_ctl_value = WCD9335_ANC_DMIC_X2_FULL_RATE; + else + anc_ctl_value = WCD9335_ANC_DMIC_X2_HALF_RATE; + + snd_soc_update_bits(codec, WCD9335_CDC_ANC0_MODE_2_CTL, + 0x40, anc_ctl_value << 6); + snd_soc_update_bits(codec, WCD9335_CDC_ANC0_MODE_2_CTL, + 0x20, anc_ctl_value << 5); + snd_soc_update_bits(codec, WCD9335_CDC_ANC1_MODE_2_CTL, + 0x40, anc_ctl_value << 6); + snd_soc_update_bits(codec, WCD9335_CDC_ANC1_MODE_2_CTL, + 0x20, anc_ctl_value << 5); +done: + return rc; +} + +static struct wcd_cpe_core *tasha_codec_get_cpe_core( + struct snd_soc_codec *codec) +{ + struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + + return priv->cpe_core; +} + +static int tasha_codec_cpe_fll_update_divider( + struct snd_soc_codec *codec, u32 cpe_fll_rate) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + u32 div_val = 0, l_val = 0; + u32 computed_cpe_fll; + + if (cpe_fll_rate != CPE_FLL_CLK_75MHZ && + cpe_fll_rate != CPE_FLL_CLK_150MHZ) { + dev_err(codec->dev, + "%s: Invalid CPE fll rate request %u\n", + __func__, cpe_fll_rate); + return -EINVAL; + } + + if (wcd9xxx->mclk_rate == TASHA_MCLK_CLK_12P288MHZ) { + /* update divider to 10 and enable 5x divider */ + snd_soc_write(codec, WCD9335_CPE_FLL_USER_CTL_1, + 0x55); + div_val = 10; + } else if (wcd9xxx->mclk_rate == TASHA_MCLK_CLK_9P6MHZ) { + /* update divider to 8 and enable 2x divider */ + snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0, + 0x7C, 0x70); + snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_1, + 0xE0, 0x20); + div_val = 8; + } else { + dev_err(codec->dev, + "%s: Invalid MCLK rate %u\n", + __func__, wcd9xxx->mclk_rate); + return -EINVAL; + } + + l_val = ((cpe_fll_rate / 1000) * div_val) / + (wcd9xxx->mclk_rate / 1000); + + /* If l_val was integer truncated, increment l_val once */ + computed_cpe_fll = (wcd9xxx->mclk_rate / div_val) * l_val; + if (computed_cpe_fll < cpe_fll_rate) + l_val++; + + + /* update L value LSB and MSB */ + snd_soc_write(codec, WCD9335_CPE_FLL_L_VAL_CTL_0, + (l_val & 0xFF)); + snd_soc_write(codec, WCD9335_CPE_FLL_L_VAL_CTL_1, + ((l_val >> 8) & 0xFF)); + + tasha->current_cpe_clk_freq = cpe_fll_rate; + dev_dbg(codec->dev, + "%s: updated l_val to %u for cpe_clk %u and mclk %u\n", + __func__, l_val, cpe_fll_rate, wcd9xxx->mclk_rate); + + return 0; +} + +static int __tasha_cdc_change_cpe_clk(struct snd_soc_codec *codec, + u32 clk_freq) +{ + int ret = 0; + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + if (!tasha_cdc_is_svs_enabled(tasha)) { + dev_dbg(codec->dev, + "%s: SVS not enabled or tasha is not 2p0, return\n", + __func__); + return 0; + } + dev_dbg(codec->dev, "%s: clk_freq = %u\n", __func__, clk_freq); + + if (clk_freq == CPE_FLL_CLK_75MHZ) { + /* Change to SVS */ + snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE, + 0x08, 0x08); + if (tasha_codec_cpe_fll_update_divider(codec, clk_freq)) { + ret = -EINVAL; + goto done; + } + + snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE, + 0x10, 0x10); + + clear_bit(CPE_NOMINAL, &tasha->status_mask); + tasha_codec_update_sido_voltage(tasha, sido_buck_svs_voltage); + + } else if (clk_freq == CPE_FLL_CLK_150MHZ) { + /* change to nominal */ + snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE, + 0x08, 0x08); + + set_bit(CPE_NOMINAL, &tasha->status_mask); + tasha_codec_update_sido_voltage(tasha, SIDO_VOLTAGE_NOMINAL_MV); + + if (tasha_codec_cpe_fll_update_divider(codec, clk_freq)) { + ret = -EINVAL; + goto done; + } + snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE, + 0x10, 0x10); + } else { + dev_err(codec->dev, + "%s: Invalid clk_freq request %d for CPE FLL\n", + __func__, clk_freq); + ret = -EINVAL; + } + +done: + snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE, + 0x10, 0x00); + snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE, + 0x08, 0x00); + return ret; +} + + +static int tasha_codec_cpe_fll_enable(struct snd_soc_codec *codec, + bool enable) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + u8 clk_sel_reg_val = 0x00; + + dev_dbg(codec->dev, "%s: enable = %s\n", + __func__, enable ? "true" : "false"); + + if (enable) { + if (tasha_cdc_is_svs_enabled(tasha)) { + /* FLL enable is always at SVS */ + if (__tasha_cdc_change_cpe_clk(codec, + CPE_FLL_CLK_75MHZ)) { + dev_err(codec->dev, + "%s: clk change to %d failed\n", + __func__, CPE_FLL_CLK_75MHZ); + return -EINVAL; + } + } else { + if (tasha_codec_cpe_fll_update_divider(codec, + CPE_FLL_CLK_75MHZ)) { + dev_err(codec->dev, + "%s: clk change to %d failed\n", + __func__, CPE_FLL_CLK_75MHZ); + return -EINVAL; + } + } + + if (TASHA_IS_1_0(wcd9xxx)) { + tasha_cdc_mclk_enable(codec, true, false); + clk_sel_reg_val = 0x02; + } + + /* Setup CPE reference clk */ + snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP, + 0x02, clk_sel_reg_val); + + /* enable CPE FLL reference clk */ + snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP, + 0x01, 0x01); + + /* program the PLL */ + snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0, + 0x01, 0x01); + + /* TEST clk setting */ + snd_soc_update_bits(codec, WCD9335_CPE_FLL_TEST_CTL_0, + 0x80, 0x80); + /* set FLL mode to HW controlled */ + snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE, + 0x60, 0x00); + snd_soc_write(codec, WCD9335_CPE_FLL_FLL_MODE, 0x80); + } else { + /* disable CPE FLL reference clk */ + snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP, + 0x01, 0x00); + /* undo TEST clk setting */ + snd_soc_update_bits(codec, WCD9335_CPE_FLL_TEST_CTL_0, + 0x80, 0x00); + /* undo FLL mode to HW control */ + snd_soc_write(codec, WCD9335_CPE_FLL_FLL_MODE, 0x00); + snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE, + 0x60, 0x20); + /* undo the PLL */ + snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0, + 0x01, 0x00); + + if (TASHA_IS_1_0(wcd9xxx)) + tasha_cdc_mclk_enable(codec, false, false); + + /* + * FLL could get disabled while at nominal, + * scale it back to SVS + */ + if (tasha_cdc_is_svs_enabled(tasha)) + __tasha_cdc_change_cpe_clk(codec, + CPE_FLL_CLK_75MHZ); + } + + return 0; + +} + +static void tasha_cdc_query_cpe_clk_plan(void *data, + struct cpe_svc_cfg_clk_plan *clk_freq) +{ + struct snd_soc_codec *codec = data; + struct tasha_priv *tasha; + u32 cpe_clk_khz; + + if (!codec) { + pr_err("%s: Invalid codec handle\n", + __func__); + return; + } + + tasha = snd_soc_codec_get_drvdata(codec); + cpe_clk_khz = tasha->current_cpe_clk_freq / 1000; + + dev_dbg(codec->dev, + "%s: current_clk_freq = %u\n", + __func__, tasha->current_cpe_clk_freq); + + clk_freq->current_clk_feq = cpe_clk_khz; + clk_freq->num_clk_freqs = 2; + + if (tasha_cdc_is_svs_enabled(tasha)) { + clk_freq->clk_freqs[0] = CPE_FLL_CLK_75MHZ / 1000; + clk_freq->clk_freqs[1] = CPE_FLL_CLK_150MHZ / 1000; + } else { + clk_freq->clk_freqs[0] = CPE_FLL_CLK_75MHZ; + clk_freq->clk_freqs[1] = CPE_FLL_CLK_150MHZ; + } +} + +static void tasha_cdc_change_cpe_clk(void *data, + u32 clk_freq) +{ + struct snd_soc_codec *codec = data; + struct tasha_priv *tasha; + u32 cpe_clk_khz, req_freq = 0; + + if (!codec) { + pr_err("%s: Invalid codec handle\n", + __func__); + return; + } + + tasha = snd_soc_codec_get_drvdata(codec); + cpe_clk_khz = tasha->current_cpe_clk_freq / 1000; + + if (tasha_cdc_is_svs_enabled(tasha)) { + if ((clk_freq * 1000) <= CPE_FLL_CLK_75MHZ) + req_freq = CPE_FLL_CLK_75MHZ; + else + req_freq = CPE_FLL_CLK_150MHZ; + } + + dev_dbg(codec->dev, + "%s: requested clk_freq = %u, current clk_freq = %u\n", + __func__, clk_freq * 1000, + tasha->current_cpe_clk_freq); + + if (tasha_cdc_is_svs_enabled(tasha)) { + if (__tasha_cdc_change_cpe_clk(codec, req_freq)) + dev_err(codec->dev, + "%s: clock/voltage scaling failed\n", + __func__); + } +} + +static int tasha_codec_slim_reserve_bw(struct snd_soc_codec *codec, + u32 bw_ops, bool commit) +{ + struct wcd9xxx *wcd9xxx; + + if (!codec) { + pr_err("%s: Invalid handle to codec\n", + __func__); + return -EINVAL; + } + + wcd9xxx = dev_get_drvdata(codec->dev->parent); + + if (!wcd9xxx) { + dev_err(codec->dev, "%s: Invalid parent drv_data\n", + __func__); + return -EINVAL; + } + + return wcd9xxx_slim_reserve_bw(wcd9xxx, bw_ops, commit); +} + +static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec, + bool vote) +{ + u32 bw_ops; + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + + if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) + return 0; + + if (vote) + bw_ops = SLIM_BW_CLK_GEAR_9; + else + bw_ops = SLIM_BW_UNVOTE; + + return tasha_codec_slim_reserve_bw(codec, + bw_ops, true); +} + +static int tasha_cpe_err_irq_control(struct snd_soc_codec *codec, + enum cpe_err_irq_cntl_type cntl_type, u8 *status) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + u8 irq_bits; + + if (TASHA_IS_2_0(tasha->wcd9xxx)) + irq_bits = 0xFF; + else + irq_bits = 0x3F; + + if (status) + irq_bits = (*status) & irq_bits; + + switch (cntl_type) { + case CPE_ERR_IRQ_MASK: + snd_soc_update_bits(codec, + WCD9335_CPE_SS_SS_ERROR_INT_MASK, + irq_bits, irq_bits); + break; + case CPE_ERR_IRQ_UNMASK: + snd_soc_update_bits(codec, + WCD9335_CPE_SS_SS_ERROR_INT_MASK, + irq_bits, 0x00); + break; + case CPE_ERR_IRQ_CLEAR: + snd_soc_write(codec, WCD9335_CPE_SS_SS_ERROR_INT_CLEAR, + irq_bits); + break; + case CPE_ERR_IRQ_STATUS: + if (!status) + return -EINVAL; + *status = snd_soc_read(codec, + WCD9335_CPE_SS_SS_ERROR_INT_STATUS); + break; + } + + return 0; +} + +static const struct wcd_cpe_cdc_cb cpe_cb = { + .cdc_clk_en = tasha_codec_internal_rco_ctrl, + .cpe_clk_en = tasha_codec_cpe_fll_enable, + .get_afe_out_port_id = tasha_codec_get_mad_port_id, + .lab_cdc_ch_ctl = tasha_codec_enable_slimtx_mad, + .cdc_ext_clk = tasha_cdc_mclk_enable, + .bus_vote_bw = tasha_codec_vote_max_bw, + .cpe_err_irq_control = tasha_cpe_err_irq_control, +}; + +static struct cpe_svc_init_param cpe_svc_params = { + .version = CPE_SVC_INIT_PARAM_V1, + .query_freq_plans_cb = tasha_cdc_query_cpe_clk_plan, + .change_freq_plan_cb = tasha_cdc_change_cpe_clk, +}; + +static int tasha_cpe_initialize(struct snd_soc_codec *codec) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct wcd_cpe_params cpe_params; + + memset(&cpe_params, 0, + sizeof(struct wcd_cpe_params)); + cpe_params.codec = codec; + cpe_params.get_cpe_core = tasha_codec_get_cpe_core; + cpe_params.cdc_cb = &cpe_cb; + cpe_params.dbg_mode = cpe_debug_mode; + cpe_params.cdc_major_ver = CPE_SVC_CODEC_WCD9335; + cpe_params.cdc_minor_ver = CPE_SVC_CODEC_V1P0; + cpe_params.cdc_id = CPE_SVC_CODEC_WCD9335; + + cpe_params.cdc_irq_info.cpe_engine_irq = + WCD9335_IRQ_SVA_OUTBOX1; + cpe_params.cdc_irq_info.cpe_err_irq = + WCD9335_IRQ_SVA_ERROR; + cpe_params.cdc_irq_info.cpe_fatal_irqs = + TASHA_CPE_FATAL_IRQS; + + cpe_svc_params.context = codec; + cpe_params.cpe_svc_params = &cpe_svc_params; + + tasha->cpe_core = wcd_cpe_init("cpe_9335", codec, + &cpe_params); + if (IS_ERR_OR_NULL(tasha->cpe_core)) { + dev_err(codec->dev, + "%s: Failed to enable CPE\n", + __func__); + return -EINVAL; + } + + return 0; +} + +static const struct wcd_resmgr_cb tasha_resmgr_cb = { + .cdc_rco_ctrl = __tasha_codec_internal_rco_ctrl, +}; + +static int tasha_device_down(struct wcd9xxx *wcd9xxx) +{ + struct snd_soc_codec *codec; + struct tasha_priv *priv; + int count; + int i = 0; + + codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); + priv = snd_soc_codec_get_drvdata(codec); + wcd_cpe_ssr_event(priv->cpe_core, WCD_CPE_BUS_DOWN_EVENT); + for (i = 0; i < priv->nr; i++) + swrm_wcd_notify(priv->swr_ctrl_data[i].swr_pdev, + SWR_DEVICE_DOWN, NULL); + snd_soc_card_change_online_state(codec->component.card, 0); + for (count = 0; count < NUM_CODEC_DAIS; count++) + priv->dai[count].bus_down_in_recovery = true; + + priv->resmgr->sido_input_src = SIDO_SOURCE_INTERNAL; + + return 0; +} + +static int tasha_post_reset_cb(struct wcd9xxx *wcd9xxx) +{ + int i, ret = 0; + struct wcd9xxx *control; + struct snd_soc_codec *codec; + struct tasha_priv *tasha; + struct wcd9xxx_pdata *pdata; + + codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); + tasha = snd_soc_codec_get_drvdata(codec); + control = dev_get_drvdata(codec->dev->parent); + + wcd9xxx_set_power_state(tasha->wcd9xxx, + WCD_REGION_POWER_COLLAPSE_REMOVE, + WCD9XXX_DIG_CORE_REGION_1); + + mutex_lock(&tasha->codec_mutex); + + tasha_slimbus_slave_port_cfg.slave_dev_intfdev_la = + control->slim_slave->laddr; + tasha_slimbus_slave_port_cfg.slave_dev_pgd_la = + control->slim->laddr; + tasha_init_slim_slave_cfg(codec); + if (tasha->machine_codec_event_cb) + tasha->machine_codec_event_cb(codec, + WCD9335_CODEC_EVENT_CODEC_UP); + snd_soc_card_change_online_state(codec->component.card, 1); + + /* Class-H Init*/ + wcd_clsh_init(&tasha->clsh_d); + + for (i = 0; i < TASHA_MAX_MICBIAS; i++) + tasha->micb_ref[i] = 0; + + tasha_update_reg_defaults(tasha); + + tasha->codec = codec; + + dev_dbg(codec->dev, "%s: MCLK Rate = %x\n", + __func__, control->mclk_rate); + + if (control->mclk_rate == TASHA_MCLK_CLK_12P288MHZ) + snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG, + 0x03, 0x00); + else if (control->mclk_rate == TASHA_MCLK_CLK_9P6MHZ) + snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG, + 0x03, 0x01); + tasha_codec_init_reg(codec); + + wcd_resmgr_post_ssr_v2(tasha->resmgr); + + tasha_enable_efuse_sensing(codec); + + regcache_mark_dirty(codec->component.regmap); + regcache_sync(codec->component.regmap); + + pdata = dev_get_platdata(codec->dev->parent); + ret = tasha_handle_pdata(tasha, pdata); + if (ret < 0) + dev_err(codec->dev, "%s: invalid pdata\n", __func__); + + /* MBHC Init */ + wcd_mbhc_deinit(&tasha->mbhc); + tasha->mbhc_started = false; + + /* Initialize MBHC module */ + ret = wcd_mbhc_init(&tasha->mbhc, codec, &mbhc_cb, &intr_ids, + wcd_mbhc_registers, TASHA_ZDET_SUPPORTED); + if (ret) + dev_err(codec->dev, "%s: mbhc initialization failed\n", + __func__); + else + tasha_mbhc_hs_detect(codec, tasha->mbhc.mbhc_cfg); + + tasha_cleanup_irqs(tasha); + ret = tasha_setup_irqs(tasha); + if (ret) { + dev_err(codec->dev, "%s: tasha irq setup failed %d\n", + __func__, ret); + goto err; + } + + tasha_set_spkr_mode(codec, tasha->spkr_mode); + wcd_cpe_ssr_event(tasha->cpe_core, WCD_CPE_BUS_UP_EVENT); + +err: + mutex_unlock(&tasha->codec_mutex); + return ret; +} + +static struct regulator *tasha_codec_find_ondemand_regulator( + struct snd_soc_codec *codec, const char *name) +{ + int i; + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; + struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + + for (i = 0; i < wcd9xxx->num_of_supplies; ++i) { + if (pdata->regulator[i].ondemand && + wcd9xxx->supplies[i].supply && + !strcmp(wcd9xxx->supplies[i].supply, name)) + return wcd9xxx->supplies[i].consumer; + } + + dev_dbg(tasha->dev, "Warning: regulator not found:%s\n", + name); + return NULL; +} + +static int tasha_codec_probe(struct snd_soc_codec *codec) +{ + struct wcd9xxx *control; + struct tasha_priv *tasha; + struct wcd9xxx_pdata *pdata; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + int i, ret; + void *ptr = NULL; + struct regulator *supply; + + control = dev_get_drvdata(codec->dev->parent); + + dev_info(codec->dev, "%s()\n", __func__); + tasha = snd_soc_codec_get_drvdata(codec); + tasha->intf_type = wcd9xxx_get_intf_type(); + + if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) { + control->dev_down = tasha_device_down; + control->post_reset = tasha_post_reset_cb; + control->ssr_priv = (void *)codec; + } + + /* Resource Manager post Init */ + ret = wcd_resmgr_post_init(tasha->resmgr, &tasha_resmgr_cb, codec); + if (ret) { + dev_err(codec->dev, "%s: wcd resmgr post init failed\n", + __func__); + goto err; + } + /* Class-H Init*/ + wcd_clsh_init(&tasha->clsh_d); + /* Default HPH Mode to Class-H HiFi */ + tasha->hph_mode = CLS_H_HIFI; + + tasha->codec = codec; + for (i = 0; i < COMPANDER_MAX; i++) + tasha->comp_enabled[i] = 0; + + tasha->spkr_gain_offset = RX_GAIN_OFFSET_0_DB; + tasha->intf_type = wcd9xxx_get_intf_type(); + tasha_update_reg_reset_values(codec); + pr_debug("%s: MCLK Rate = %x\n", __func__, control->mclk_rate); + if (control->mclk_rate == TASHA_MCLK_CLK_12P288MHZ) + snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG, + 0x03, 0x00); + else if (control->mclk_rate == TASHA_MCLK_CLK_9P6MHZ) + snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG, + 0x03, 0x01); + tasha_codec_init_reg(codec); + + tasha_enable_efuse_sensing(codec); + + pdata = dev_get_platdata(codec->dev->parent); + ret = tasha_handle_pdata(tasha, pdata); + if (ret < 0) { + pr_err("%s: bad pdata\n", __func__); + goto err; + } + + supply = tasha_codec_find_ondemand_regulator(codec, + on_demand_supply_name[ON_DEMAND_MICBIAS]); + if (supply) { + tasha->on_demand_list[ON_DEMAND_MICBIAS].supply = supply; + tasha->on_demand_list[ON_DEMAND_MICBIAS].ondemand_supply_count = + 0; + } + + tasha->fw_data = devm_kzalloc(codec->dev, + sizeof(*(tasha->fw_data)), GFP_KERNEL); + if (!tasha->fw_data) + goto err; + set_bit(WCD9XXX_ANC_CAL, tasha->fw_data->cal_bit); + set_bit(WCD9XXX_MBHC_CAL, tasha->fw_data->cal_bit); + set_bit(WCD9XXX_MAD_CAL, tasha->fw_data->cal_bit); + set_bit(WCD9XXX_VBAT_CAL, tasha->fw_data->cal_bit); + + ret = wcd_cal_create_hwdep(tasha->fw_data, + WCD9XXX_CODEC_HWDEP_NODE, codec); + if (ret < 0) { + dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret); + goto err_hwdep; + } + + /* Initialize MBHC module */ + if (TASHA_IS_2_0(tasha->wcd9xxx)) { + wcd_mbhc_registers[WCD_MBHC_FSM_STATUS].reg = + WCD9335_MBHC_FSM_STATUS; + wcd_mbhc_registers[WCD_MBHC_FSM_STATUS].mask = 0x01; + } + ret = wcd_mbhc_init(&tasha->mbhc, codec, &mbhc_cb, &intr_ids, + wcd_mbhc_registers, TASHA_ZDET_SUPPORTED); + if (ret) { + pr_err("%s: mbhc initialization failed\n", __func__); + goto err_hwdep; + } + + ptr = devm_kzalloc(codec->dev, (sizeof(tasha_rx_chs) + + sizeof(tasha_tx_chs)), GFP_KERNEL); + if (!ptr) { + ret = -ENOMEM; + goto err_hwdep; + } + + if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { + snd_soc_dapm_new_controls(dapm, tasha_dapm_i2s_widgets, + ARRAY_SIZE(tasha_dapm_i2s_widgets)); + snd_soc_dapm_add_routes(dapm, audio_i2s_map, + ARRAY_SIZE(audio_i2s_map)); + for (i = 0; i < ARRAY_SIZE(tasha_i2s_dai); i++) { + INIT_LIST_HEAD(&tasha->dai[i].wcd9xxx_ch_list); + init_waitqueue_head(&tasha->dai[i].dai_wait); + } + } else if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) { + for (i = 0; i < NUM_CODEC_DAIS; i++) { + INIT_LIST_HEAD(&tasha->dai[i].wcd9xxx_ch_list); + init_waitqueue_head(&tasha->dai[i].dai_wait); + } + tasha_slimbus_slave_port_cfg.slave_dev_intfdev_la = + control->slim_slave->laddr; + tasha_slimbus_slave_port_cfg.slave_dev_pgd_la = + control->slim->laddr; + tasha_slimbus_slave_port_cfg.slave_port_mapping[0] = + TASHA_TX13; + tasha_init_slim_slave_cfg(codec); + } + + snd_soc_add_codec_controls(codec, impedance_detect_controls, + ARRAY_SIZE(impedance_detect_controls)); + snd_soc_add_codec_controls(codec, hph_type_detect_controls, + ARRAY_SIZE(hph_type_detect_controls)); + + snd_soc_add_codec_controls(codec, + tasha_analog_gain_controls, + ARRAY_SIZE(tasha_analog_gain_controls)); + control->num_rx_port = TASHA_RX_MAX; + control->rx_chs = ptr; + memcpy(control->rx_chs, tasha_rx_chs, sizeof(tasha_rx_chs)); + control->num_tx_port = TASHA_TX_MAX; + control->tx_chs = ptr + sizeof(tasha_rx_chs); + memcpy(control->tx_chs, tasha_tx_chs, sizeof(tasha_tx_chs)); + + snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AIF1 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "AIF2 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AIF2 Capture"); + + if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) { + snd_soc_dapm_ignore_suspend(dapm, "AIF3 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AIF3 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "AIF4 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AIF Mix Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX"); + snd_soc_dapm_ignore_suspend(dapm, "VIfeed"); + snd_soc_dapm_ignore_suspend(dapm, "AIF5 CPE TX"); + } + + snd_soc_dapm_sync(dapm); + + ret = tasha_setup_irqs(tasha); + if (ret) { + pr_err("%s: tasha irq setup failed %d\n", __func__, ret); + goto err_pdata; + } + + ret = tasha_cpe_initialize(codec); + if (ret) { + dev_err(codec->dev, + "%s: cpe initialization failed, err = %d\n", + __func__, ret); + /* Do not fail probe if CPE failed */ + ret = 0; + } + + for (i = 0; i < TASHA_NUM_DECIMATORS; i++) { + tasha->tx_hpf_work[i].tasha = tasha; + tasha->tx_hpf_work[i].decimator = i; + INIT_DELAYED_WORK(&tasha->tx_hpf_work[i].dwork, + tasha_tx_hpf_corner_freq_callback); + } + + for (i = 0; i < TASHA_NUM_DECIMATORS; i++) { + tasha->tx_mute_dwork[i].tasha = tasha; + tasha->tx_mute_dwork[i].decimator = i; + INIT_DELAYED_WORK(&tasha->tx_mute_dwork[i].dwork, + tasha_tx_mute_update_callback); + } + + tasha->spk_anc_dwork.tasha = tasha; + INIT_DELAYED_WORK(&tasha->spk_anc_dwork.dwork, + tasha_spk_anc_update_callback); + + mutex_lock(&tasha->codec_mutex); + snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1"); + snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2"); + snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT1 PA"); + snd_soc_dapm_disable_pin(dapm, "ANC LINEOUT2 PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHL"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHR"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA"); + snd_soc_dapm_disable_pin(dapm, "ANC EAR PA"); + snd_soc_dapm_disable_pin(dapm, "ANC EAR"); + snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA"); + mutex_unlock(&tasha->codec_mutex); + snd_soc_dapm_sync(dapm); + + return ret; + +err_pdata: + devm_kfree(codec->dev, ptr); + control->rx_chs = NULL; + control->tx_chs = NULL; +err_hwdep: + devm_kfree(codec->dev, tasha->fw_data); + tasha->fw_data = NULL; +err: + return ret; +} + +static int tasha_codec_remove(struct snd_soc_codec *codec) +{ + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *control; + + control = dev_get_drvdata(codec->dev->parent); + control->rx_chs = NULL; + control->tx_chs = NULL; + + tasha_cleanup_irqs(tasha); + /* Cleanup MBHC */ + /* Cleanup resmgr */ + + return 0; +} + +static struct regmap *tasha_get_regmap(struct device *dev) +{ + struct wcd9xxx *control = dev_get_drvdata(dev->parent); + + return control->regmap; +} + +static struct snd_soc_codec_driver soc_codec_dev_tasha = { + .probe = tasha_codec_probe, + .remove = tasha_codec_remove, + .get_regmap = tasha_get_regmap, + .component_driver = { + .controls = tasha_snd_controls, + .num_controls = ARRAY_SIZE(tasha_snd_controls), + .dapm_widgets = tasha_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tasha_dapm_widgets), + .dapm_routes = audio_map, + .num_dapm_routes = ARRAY_SIZE(audio_map), + }, +}; + +#ifdef CONFIG_PM +static int tasha_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct tasha_priv *tasha = platform_get_drvdata(pdev); + + dev_dbg(dev, "%s: system suspend\n", __func__); + if (cancel_delayed_work_sync(&tasha->power_gate_work)) + tasha_codec_power_gate_digital_core(tasha); + + return 0; +} + +static int tasha_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct tasha_priv *tasha = platform_get_drvdata(pdev); + + if (!tasha) { + dev_err(dev, "%s: tasha private data is NULL\n", __func__); + return -EINVAL; + } + dev_dbg(dev, "%s: system resume\n", __func__); + return 0; +} + +static const struct dev_pm_ops tasha_pm_ops = { + .suspend = tasha_suspend, + .resume = tasha_resume, +}; +#endif + +static int tasha_swrm_read(void *handle, int reg) +{ + struct tasha_priv *tasha; + struct wcd9xxx *wcd9xxx; + unsigned short swr_rd_addr_base; + unsigned short swr_rd_data_base; + int val, ret; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + tasha = (struct tasha_priv *)handle; + wcd9xxx = tasha->wcd9xxx; + + dev_dbg(tasha->dev, "%s: Reading soundwire register, 0x%x\n", + __func__, reg); + swr_rd_addr_base = WCD9335_SWR_AHB_BRIDGE_RD_ADDR_0; + swr_rd_data_base = WCD9335_SWR_AHB_BRIDGE_RD_DATA_0; + /* read_lock */ + mutex_lock(&tasha->swr_read_lock); + ret = regmap_bulk_write(wcd9xxx->regmap, swr_rd_addr_base, + (u8 *)®, 4); + if (ret < 0) { + pr_err("%s: RD Addr Failure\n", __func__); + goto err; + } + /* Check for RD status */ + ret = regmap_bulk_read(wcd9xxx->regmap, swr_rd_data_base, + (u8 *)&val, 4); + if (ret < 0) { + pr_err("%s: RD Data Failure\n", __func__); + goto err; + } + ret = val; +err: + /* read_unlock */ + mutex_unlock(&tasha->swr_read_lock); + return ret; +} + +static int tasha_swrm_i2s_bulk_write(struct wcd9xxx *wcd9xxx, + struct wcd9xxx_reg_val *bulk_reg, + size_t len) +{ + int i, ret = 0; + unsigned short swr_wr_addr_base; + unsigned short swr_wr_data_base; + + swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0; + swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0; + + for (i = 0; i < (len * 2); i += 2) { + /* First Write the Data to register */ + ret = regmap_bulk_write(wcd9xxx->regmap, + swr_wr_data_base, bulk_reg[i].buf, 4); + if (ret < 0) { + dev_err(wcd9xxx->dev, "%s: WR Data Failure\n", + __func__); + break; + } + /* Next Write Address */ + ret = regmap_bulk_write(wcd9xxx->regmap, + swr_wr_addr_base, bulk_reg[i+1].buf, 4); + if (ret < 0) { + dev_err(wcd9xxx->dev, "%s: WR Addr Failure\n", + __func__); + break; + } + } + return ret; +} + +static int tasha_swrm_bulk_write(void *handle, u32 *reg, u32 *val, size_t len) +{ + struct tasha_priv *tasha; + struct wcd9xxx *wcd9xxx; + struct wcd9xxx_reg_val *bulk_reg; + unsigned short swr_wr_addr_base; + unsigned short swr_wr_data_base; + int i, j, ret; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + if (len <= 0) { + pr_err("%s: Invalid size: %zu\n", __func__, len); + return -EINVAL; + } + tasha = (struct tasha_priv *)handle; + wcd9xxx = tasha->wcd9xxx; + + swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0; + swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0; + + bulk_reg = kzalloc((2 * len * sizeof(struct wcd9xxx_reg_val)), + GFP_KERNEL); + if (!bulk_reg) + return -ENOMEM; + + for (i = 0, j = 0; i < (len * 2); i += 2, j++) { + bulk_reg[i].reg = swr_wr_data_base; + bulk_reg[i].buf = (u8 *)(&val[j]); + bulk_reg[i].bytes = 4; + bulk_reg[i+1].reg = swr_wr_addr_base; + bulk_reg[i+1].buf = (u8 *)(®[j]); + bulk_reg[i+1].bytes = 4; + } + mutex_lock(&tasha->swr_write_lock); + + if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) { + ret = tasha_swrm_i2s_bulk_write(wcd9xxx, bulk_reg, len); + if (ret) { + dev_err(tasha->dev, "%s: i2s bulk write failed, ret: %d\n", + __func__, ret); + } + } else { + ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, + (len * 2), false); + if (ret) { + dev_err(tasha->dev, "%s: swrm bulk write failed, ret: %d\n", + __func__, ret); + } + } + + mutex_unlock(&tasha->swr_write_lock); + kfree(bulk_reg); + + return ret; +} + +static int tasha_swrm_write(void *handle, int reg, int val) +{ + struct tasha_priv *tasha; + struct wcd9xxx *wcd9xxx; + unsigned short swr_wr_addr_base; + unsigned short swr_wr_data_base; + struct wcd9xxx_reg_val bulk_reg[2]; + int ret; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + tasha = (struct tasha_priv *)handle; + wcd9xxx = tasha->wcd9xxx; + + swr_wr_addr_base = WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0; + swr_wr_data_base = WCD9335_SWR_AHB_BRIDGE_WR_DATA_0; + + /* First Write the Data to register */ + bulk_reg[0].reg = swr_wr_data_base; + bulk_reg[0].buf = (u8 *)(&val); + bulk_reg[0].bytes = 4; + bulk_reg[1].reg = swr_wr_addr_base; + bulk_reg[1].buf = (u8 *)(®); + bulk_reg[1].bytes = 4; + + mutex_lock(&tasha->swr_write_lock); + + if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) { + ret = tasha_swrm_i2s_bulk_write(wcd9xxx, bulk_reg, 1); + if (ret) { + dev_err(tasha->dev, "%s: i2s swrm write failed, ret: %d\n", + __func__, ret); + } + } else { + ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, 2, false); + if (ret < 0) + pr_err("%s: WR Data Failure\n", __func__); + } + + mutex_unlock(&tasha->swr_write_lock); + return ret; +} + +static int tasha_swrm_clock(void *handle, bool enable) +{ + struct tasha_priv *tasha = (struct tasha_priv *) handle; + + mutex_lock(&tasha->swr_clk_lock); + + dev_dbg(tasha->dev, "%s: swrm clock %s\n", + __func__, (enable?"enable" : "disable")); + if (enable) { + tasha->swr_clk_users++; + if (tasha->swr_clk_users == 1) { + if (TASHA_IS_2_0(tasha->wcd9xxx)) + regmap_update_bits( + tasha->wcd9xxx->regmap, + WCD9335_TEST_DEBUG_NPL_DLY_TEST_1, + 0x10, 0x00); + __tasha_cdc_mclk_enable(tasha, true); + regmap_update_bits(tasha->wcd9xxx->regmap, + WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x01); + } + } else { + tasha->swr_clk_users--; + if (tasha->swr_clk_users == 0) { + regmap_update_bits(tasha->wcd9xxx->regmap, + WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x00); + __tasha_cdc_mclk_enable(tasha, false); + if (TASHA_IS_2_0(tasha->wcd9xxx)) + regmap_update_bits( + tasha->wcd9xxx->regmap, + WCD9335_TEST_DEBUG_NPL_DLY_TEST_1, + 0x10, 0x10); + } + } + dev_dbg(tasha->dev, "%s: swrm clock users %d\n", + __func__, tasha->swr_clk_users); + mutex_unlock(&tasha->swr_clk_lock); + return 0; +} + +static int tasha_swrm_handle_irq(void *handle, + irqreturn_t (*swrm_irq_handler)(int irq, + void *data), + void *swrm_handle, + int action) +{ + struct tasha_priv *tasha; + int ret = 0; + struct wcd9xxx *wcd9xxx; + + if (!handle) { + pr_err("%s: null handle received\n", __func__); + return -EINVAL; + } + tasha = (struct tasha_priv *) handle; + wcd9xxx = tasha->wcd9xxx; + + if (action) { + ret = wcd9xxx_request_irq(&wcd9xxx->core_res, + WCD9335_IRQ_SOUNDWIRE, + swrm_irq_handler, + "Tasha SWR Master", swrm_handle); + if (ret) + dev_err(tasha->dev, "%s: Failed to request irq %d\n", + __func__, WCD9335_IRQ_SOUNDWIRE); + } else + wcd9xxx_free_irq(&wcd9xxx->core_res, WCD9335_IRQ_SOUNDWIRE, + swrm_handle); + + return ret; +} + +static void tasha_add_child_devices(struct work_struct *work) +{ + struct tasha_priv *tasha; + struct platform_device *pdev; + struct device_node *node; + struct wcd9xxx *wcd9xxx; + struct tasha_swr_ctrl_data *swr_ctrl_data = NULL, *temp; + int ret, ctrl_num = 0; + struct wcd_swr_ctrl_platform_data *platdata; + char plat_dev_name[WCD9335_STRING_LEN]; + + tasha = container_of(work, struct tasha_priv, + tasha_add_child_devices_work); + if (!tasha) { + pr_err("%s: Memory for WCD9335 does not exist\n", + __func__); + return; + } + wcd9xxx = tasha->wcd9xxx; + if (!wcd9xxx) { + pr_err("%s: Memory for WCD9XXX does not exist\n", + __func__); + return; + } + if (!wcd9xxx->dev->of_node) { + pr_err("%s: DT node for wcd9xxx does not exist\n", + __func__); + return; + } + + platdata = &tasha->swr_plat_data; + + for_each_child_of_node(wcd9xxx->dev->of_node, node) { + if (!strcmp(node->name, "swr_master")) + strlcpy(plat_dev_name, "tasha_swr_ctrl", + (WCD9335_STRING_LEN - 1)); + else if (strnstr(node->name, "msm_cdc_pinctrl", + strlen("msm_cdc_pinctrl")) != NULL) + strlcpy(plat_dev_name, node->name, + (WCD9335_STRING_LEN - 1)); + else + continue; + + pdev = platform_device_alloc(plat_dev_name, -1); + if (!pdev) { + dev_err(wcd9xxx->dev, "%s: pdev memory alloc failed\n", + __func__); + ret = -ENOMEM; + goto err; + } + pdev->dev.parent = tasha->dev; + pdev->dev.of_node = node; + + if (!strcmp(node->name, "swr_master")) { + ret = platform_device_add_data(pdev, platdata, + sizeof(*platdata)); + if (ret) { + dev_err(&pdev->dev, + "%s: cannot add plat data ctrl:%d\n", + __func__, ctrl_num); + goto fail_pdev_add; + } + } + + ret = platform_device_add(pdev); + if (ret) { + dev_err(&pdev->dev, + "%s: Cannot add platform device\n", + __func__); + goto fail_pdev_add; + } + + if (!strcmp(node->name, "swr_master")) { + temp = krealloc(swr_ctrl_data, + (ctrl_num + 1) * sizeof( + struct tasha_swr_ctrl_data), + GFP_KERNEL); + if (!temp) { + dev_err(wcd9xxx->dev, "out of memory\n"); + ret = -ENOMEM; + goto err; + } + swr_ctrl_data = temp; + swr_ctrl_data[ctrl_num].swr_pdev = pdev; + ctrl_num++; + dev_dbg(&pdev->dev, + "%s: Added soundwire ctrl device(s)\n", + __func__); + tasha->nr = ctrl_num; + tasha->swr_ctrl_data = swr_ctrl_data; + } + } + + return; +fail_pdev_add: + platform_device_put(pdev); +err: + return; +} + +/* + * tasha_codec_ver: to get tasha codec version + * @codec: handle to snd_soc_codec * + * return enum codec_variant - version + */ +enum codec_variant tasha_codec_ver(void) +{ + return codec_ver; +} +EXPORT_SYMBOL(tasha_codec_ver); + +static int __tasha_enable_efuse_sensing(struct tasha_priv *tasha) +{ + int val, rc; + + __tasha_cdc_mclk_enable(tasha, true); + + regmap_update_bits(tasha->wcd9xxx->regmap, + WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x1E, 0x20); + regmap_update_bits(tasha->wcd9xxx->regmap, + WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x01, 0x01); + + /* + * 5ms sleep required after enabling efuse control + * before checking the status. + */ + usleep_range(5000, 5500); + rc = regmap_read(tasha->wcd9xxx->regmap, + WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS, &val); + + if (rc || (!(val & 0x01))) + WARN(1, "%s: Efuse sense is not complete\n", __func__); + + __tasha_cdc_mclk_enable(tasha, false); + + return rc; +} + +void tasha_get_codec_ver(struct tasha_priv *tasha) +{ + int i; + int val; + struct tasha_reg_mask_val codec_reg[] = { + {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT10, 0xFF, 0xFF}, + {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT11, 0xFF, 0x83}, + {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT12, 0xFF, 0x0A}, + }; + + __tasha_enable_efuse_sensing(tasha); + for (i = 0; i < ARRAY_SIZE(codec_reg); i++) { + regmap_read(tasha->wcd9xxx->regmap, codec_reg[i].reg, &val); + if (!(val && codec_reg[i].val)) { + codec_ver = WCD9335; + goto ret; + } + } + codec_ver = WCD9326; +ret: + pr_debug("%s: codec is %d\n", __func__, codec_ver); +} +EXPORT_SYMBOL(tasha_get_codec_ver); + +static int tasha_probe(struct platform_device *pdev) +{ + int ret = 0; + struct tasha_priv *tasha; + struct clk *wcd_ext_clk, *wcd_native_clk; + struct wcd9xxx_resmgr_v2 *resmgr; + struct wcd9xxx_power_region *cdc_pwr; + + if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) { + if (apr_get_subsys_state() == APR_SUBSYS_DOWN) { + dev_err(&pdev->dev, "%s: dsp down\n", __func__); + return -EPROBE_DEFER; + } + } + + tasha = devm_kzalloc(&pdev->dev, sizeof(struct tasha_priv), + GFP_KERNEL); + if (!tasha) + return -ENOMEM; + platform_set_drvdata(pdev, tasha); + + tasha->wcd9xxx = dev_get_drvdata(pdev->dev.parent); + tasha->dev = &pdev->dev; + INIT_DELAYED_WORK(&tasha->power_gate_work, tasha_codec_power_gate_work); + mutex_init(&tasha->power_lock); + mutex_init(&tasha->sido_lock); + INIT_WORK(&tasha->tasha_add_child_devices_work, + tasha_add_child_devices); + BLOCKING_INIT_NOTIFIER_HEAD(&tasha->notifier); + mutex_init(&tasha->micb_lock); + mutex_init(&tasha->swr_read_lock); + mutex_init(&tasha->swr_write_lock); + mutex_init(&tasha->swr_clk_lock); + mutex_init(&tasha->mclk_lock); + + cdc_pwr = devm_kzalloc(&pdev->dev, sizeof(struct wcd9xxx_power_region), + GFP_KERNEL); + if (!cdc_pwr) { + ret = -ENOMEM; + goto err_cdc_pwr; + } + tasha->wcd9xxx->wcd9xxx_pwr[WCD9XXX_DIG_CORE_REGION_1] = cdc_pwr; + cdc_pwr->pwr_collapse_reg_min = TASHA_DIG_CORE_REG_MIN; + cdc_pwr->pwr_collapse_reg_max = TASHA_DIG_CORE_REG_MAX; + wcd9xxx_set_power_state(tasha->wcd9xxx, + WCD_REGION_POWER_COLLAPSE_REMOVE, + WCD9XXX_DIG_CORE_REGION_1); + + mutex_init(&tasha->codec_mutex); + /* + * Init resource manager so that if child nodes such as SoundWire + * requests for clock, resource manager can honor the request + */ + resmgr = wcd_resmgr_init(&tasha->wcd9xxx->core_res, NULL); + if (IS_ERR(resmgr)) { + ret = PTR_ERR(resmgr); + dev_err(&pdev->dev, "%s: Failed to initialize wcd resmgr\n", + __func__); + goto err_resmgr; + } + tasha->resmgr = resmgr; + tasha->swr_plat_data.handle = (void *) tasha; + tasha->swr_plat_data.read = tasha_swrm_read; + tasha->swr_plat_data.write = tasha_swrm_write; + tasha->swr_plat_data.bulk_write = tasha_swrm_bulk_write; + tasha->swr_plat_data.clk = tasha_swrm_clock; + tasha->swr_plat_data.handle_irq = tasha_swrm_handle_irq; + + /* Register for Clock */ + wcd_ext_clk = clk_get(tasha->wcd9xxx->dev, "wcd_clk"); + if (IS_ERR(wcd_ext_clk)) { + dev_err(tasha->wcd9xxx->dev, "%s: clk get %s failed\n", + __func__, "wcd_ext_clk"); + goto err_clk; + } + tasha->wcd_ext_clk = wcd_ext_clk; + tasha->sido_voltage = SIDO_VOLTAGE_NOMINAL_MV; + set_bit(AUDIO_NOMINAL, &tasha->status_mask); + tasha->sido_ccl_cnt = 0; + + /* Register native clk for 44.1 playback */ + wcd_native_clk = clk_get(tasha->wcd9xxx->dev, "wcd_native_clk"); + if (IS_ERR(wcd_native_clk)) + dev_dbg(tasha->wcd9xxx->dev, "%s: clk get %s failed\n", + __func__, "wcd_native_clk"); + else + tasha->wcd_native_clk = wcd_native_clk; + + if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS) + ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tasha, + tasha_dai, ARRAY_SIZE(tasha_dai)); + else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) + ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tasha, + tasha_i2s_dai, + ARRAY_SIZE(tasha_i2s_dai)); + else + ret = -EINVAL; + if (ret) { + dev_err(&pdev->dev, "%s: Codec registration failed, ret = %d\n", + __func__, ret); + goto err_cdc_reg; + } + /* Update codec register default values */ + tasha_update_reg_defaults(tasha); + schedule_work(&tasha->tasha_add_child_devices_work); + tasha_get_codec_ver(tasha); + + dev_info(&pdev->dev, "%s: Tasha driver probe done\n", __func__); + return ret; + +err_cdc_reg: + clk_put(tasha->wcd_ext_clk); + if (tasha->wcd_native_clk) + clk_put(tasha->wcd_native_clk); +err_clk: + wcd_resmgr_remove(tasha->resmgr); +err_resmgr: + devm_kfree(&pdev->dev, cdc_pwr); +err_cdc_pwr: + mutex_destroy(&tasha->mclk_lock); + devm_kfree(&pdev->dev, tasha); + return ret; +} + +static int tasha_remove(struct platform_device *pdev) +{ + struct tasha_priv *tasha; + + tasha = platform_get_drvdata(pdev); + + mutex_destroy(&tasha->codec_mutex); + clk_put(tasha->wcd_ext_clk); + if (tasha->wcd_native_clk) + clk_put(tasha->wcd_native_clk); + mutex_destroy(&tasha->mclk_lock); + devm_kfree(&pdev->dev, tasha); + snd_soc_unregister_codec(&pdev->dev); + return 0; +} + +static struct platform_driver tasha_codec_driver = { + .probe = tasha_probe, + .remove = tasha_remove, + .driver = { + .name = "tasha_codec", + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &tasha_pm_ops, +#endif + }, +}; + +module_platform_driver(tasha_codec_driver); + +MODULE_DESCRIPTION("Tasha Codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/wcd9335.h b/sound/soc/codecs/wcd9335.h new file mode 100644 index 000000000000..c76461edecf1 --- /dev/null +++ b/sound/soc/codecs/wcd9335.h @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef WCD9335_H +#define WCD9335_H + +#include +#include +#include +#include +#include "wcd-mbhc-v2.h" + +#define TASHA_REG_VAL(reg, val) {reg, 0, val} + +#define TASHA_REGISTER_START_OFFSET 0x800 +#define TASHA_SB_PGD_PORT_RX_BASE 0x40 +#define TASHA_SB_PGD_PORT_TX_BASE 0x50 + +#define TASHA_ZDET_SUPPORTED true +/* z value defined in milliohm */ +#define TASHA_ZDET_VAL_32 32000 +#define TASHA_ZDET_VAL_400 400000 +#define TASHA_ZDET_VAL_1200 1200000 +#define TASHA_ZDET_VAL_100K 100000000 +/* z floating defined in ohms */ +#define TASHA_ZDET_FLOATING_IMPEDANCE 0x0FFFFFFE + +#define WCD9335_DMIC_CLK_DIV_2 0x0 +#define WCD9335_DMIC_CLK_DIV_3 0x1 +#define WCD9335_DMIC_CLK_DIV_4 0x2 +#define WCD9335_DMIC_CLK_DIV_6 0x3 +#define WCD9335_DMIC_CLK_DIV_8 0x4 +#define WCD9335_DMIC_CLK_DIV_16 0x5 +#define WCD9335_DMIC_CLK_DRIVE_DEFAULT 0x02 + +#define WCD9335_ANC_DMIC_X2_FULL_RATE 1 +#define WCD9335_ANC_DMIC_X2_HALF_RATE 0 + +/* Number of input and output Slimbus port */ +enum { + TASHA_RX0 = 0, + TASHA_RX1, + TASHA_RX2, + TASHA_RX3, + TASHA_RX4, + TASHA_RX5, + TASHA_RX6, + TASHA_RX7, + TASHA_RX8, + TASHA_RX9, + TASHA_RX10, + TASHA_RX11, + TASHA_RX12, + TASHA_RX_MAX, +}; + +enum { + TASHA_TX0 = 0, + TASHA_TX1, + TASHA_TX2, + TASHA_TX3, + TASHA_TX4, + TASHA_TX5, + TASHA_TX6, + TASHA_TX7, + TASHA_TX8, + TASHA_TX9, + TASHA_TX10, + TASHA_TX11, + TASHA_TX12, + TASHA_TX13, + TASHA_TX14, + TASHA_TX15, + TASHA_TX_MAX, +}; + +enum wcd9335_codec_event { + WCD9335_CODEC_EVENT_CODEC_UP = 0, +}; + +enum tasha_on_demand_supply { + ON_DEMAND_MICBIAS = 0, + ON_DEMAND_SUPPLIES_MAX, +}; + +/* structure used to put the defined + * ondemand supply for codec + * and count being used. + */ +struct on_demand_supply { + struct regulator *supply; + int ondemand_supply_count; +}; + +/* Dai data structure holds the + * dai specific info like rate, + * channel number etc. + */ +struct tasha_codec_dai_data { + u32 rate; + u32 *ch_num; + u32 ch_act; + u32 ch_tot; +}; + +/* Structure used to update codec + * register defaults after reset + */ +struct tasha_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + +/* Selects compander and smart boost settings + * for a given speaker mode + */ +enum { + SPKR_MODE_DEFAULT, + SPKR_MODE_1, /* COMP Gain = 12dB, Smartboost Max = 5.5V */ +}; + +/* + * Rx path gain offsets + */ +enum { + RX_GAIN_OFFSET_M1P5_DB, + RX_GAIN_OFFSET_0_DB, +}; + +extern void *tasha_get_afe_config(struct snd_soc_codec *codec, + enum afe_config_type config_type); +extern int tasha_cdc_mclk_enable(struct snd_soc_codec *codec, int enable, + bool dapm); +extern int tasha_cdc_mclk_tx_enable(struct snd_soc_codec *codec, int enable, + bool dapm); +extern int tasha_enable_efuse_sensing(struct snd_soc_codec *codec); +extern int tasha_mbhc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg); +extern void tasha_mbhc_hs_detect_exit(struct snd_soc_codec *codec); +extern void tasha_mbhc_zdet_gpio_ctrl( + int (*zdet_gpio_cb)(struct snd_soc_codec *codec, bool high), + struct snd_soc_codec *codec); +extern int tasha_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_codec *codec); +extern void tasha_event_register( + int (*machine_event_cb)(struct snd_soc_codec *codec, + enum wcd9335_codec_event), + struct snd_soc_codec *codec); +extern int tasha_codec_enable_standalone_micbias(struct snd_soc_codec *codec, + int micb_num, + bool enable); +extern int tasha_set_spkr_mode(struct snd_soc_codec *codec, int mode); +extern int tasha_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset); +extern enum codec_variant tasha_codec_ver(void); +#endif diff --git a/sound/soc/codecs/wcd934x/Makefile b/sound/soc/codecs/wcd934x/Makefile new file mode 100644 index 000000000000..12781f6d4556 --- /dev/null +++ b/sound/soc/codecs/wcd934x/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for wcd934x codec driver. +# +snd-soc-wcd934x-objs := wcd934x.o wcd934x-dsp-cntl.o \ + wcd934x-mbhc.o wcd934x-dsd.o +obj-$(CONFIG_SND_SOC_WCD934X) += snd-soc-wcd934x.o diff --git a/sound/soc/codecs/wcd934x/wcd934x-dsd.c b/sound/soc/codecs/wcd934x/wcd934x-dsd.c new file mode 100644 index 000000000000..3e23e3749bda --- /dev/null +++ b/sound/soc/codecs/wcd934x/wcd934x-dsd.c @@ -0,0 +1,772 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include "wcd934x-dsd.h" + +#define DSD_VOLUME_MAX_0dB 0 +#define DSD_VOLUME_MIN_M110dB -110 + +#define DSD_VOLUME_RANGE_CHECK(x) ((x >= DSD_VOLUME_MIN_M110dB) &&\ + (x <= DSD_VOLUME_MAX_0dB)) +#define DSD_VOLUME_STEPS 3 +#define DSD_VOLUME_UPDATE_DELAY_MS 30 +#define DSD_VOLUME_USLEEP_MARGIN_US 100 +#define DSD_VOLUME_STEP_DELAY_US ((1000 * DSD_VOLUME_UPDATE_DELAY_MS) / \ + (2 * DSD_VOLUME_STEPS)) + +#define TAVIL_VERSION_1_0 0 +#define TAVIL_VERSION_1_1 1 + +static const DECLARE_TLV_DB_MINMAX(tavil_dsd_db_scale, DSD_VOLUME_MIN_M110dB, + DSD_VOLUME_MAX_0dB); + +static const char *const dsd_if_text[] = { + "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7", + "DSD_DATA_PAD" +}; + +static const char * const dsd_filt0_mux_text[] = { + "ZERO", "DSD_L IF MUX", +}; + +static const char * const dsd_filt1_mux_text[] = { + "ZERO", "DSD_R IF MUX", +}; + +static const struct soc_enum dsd_filt0_mux_enum = + SOC_ENUM_SINGLE(WCD934X_CDC_DSD0_PATH_CTL, 0, + ARRAY_SIZE(dsd_filt0_mux_text), dsd_filt0_mux_text); + +static const struct soc_enum dsd_filt1_mux_enum = + SOC_ENUM_SINGLE(WCD934X_CDC_DSD1_PATH_CTL, 0, + ARRAY_SIZE(dsd_filt1_mux_text), dsd_filt1_mux_text); + +static SOC_ENUM_SINGLE_DECL(dsd_l_if_enum, WCD934X_CDC_DSD0_CFG0, + 2, dsd_if_text); +static SOC_ENUM_SINGLE_DECL(dsd_r_if_enum, WCD934X_CDC_DSD1_CFG0, + 2, dsd_if_text); + +static const struct snd_kcontrol_new dsd_filt0_mux = + SOC_DAPM_ENUM("DSD Filt0 Mux", dsd_filt0_mux_enum); + +static const struct snd_kcontrol_new dsd_filt1_mux = + SOC_DAPM_ENUM("DSD Filt1 Mux", dsd_filt1_mux_enum); + +static const struct snd_kcontrol_new dsd_l_if_mux = + SOC_DAPM_ENUM("DSD Left If Mux", dsd_l_if_enum); +static const struct snd_kcontrol_new dsd_r_if_mux = + SOC_DAPM_ENUM("DSD Right If Mux", dsd_r_if_enum); + +static const struct snd_soc_dapm_route tavil_dsd_audio_map[] = { + {"DSD_L IF MUX", "RX0", "CDC_IF RX0 MUX"}, + {"DSD_L IF MUX", "RX1", "CDC_IF RX1 MUX"}, + {"DSD_L IF MUX", "RX2", "CDC_IF RX2 MUX"}, + {"DSD_L IF MUX", "RX3", "CDC_IF RX3 MUX"}, + {"DSD_L IF MUX", "RX4", "CDC_IF RX4 MUX"}, + {"DSD_L IF MUX", "RX5", "CDC_IF RX5 MUX"}, + {"DSD_L IF MUX", "RX6", "CDC_IF RX6 MUX"}, + {"DSD_L IF MUX", "RX7", "CDC_IF RX7 MUX"}, + + {"DSD_FILTER_0", NULL, "DSD_L IF MUX"}, + {"DSD_FILTER_0", NULL, "RX INT1 NATIVE SUPPLY"}, + {"RX INT1 MIX3", "DSD HPHL Switch", "DSD_FILTER_0"}, + + {"DSD_R IF MUX", "RX0", "CDC_IF RX0 MUX"}, + {"DSD_R IF MUX", "RX1", "CDC_IF RX1 MUX"}, + {"DSD_R IF MUX", "RX2", "CDC_IF RX2 MUX"}, + {"DSD_R IF MUX", "RX3", "CDC_IF RX3 MUX"}, + {"DSD_R IF MUX", "RX4", "CDC_IF RX4 MUX"}, + {"DSD_R IF MUX", "RX5", "CDC_IF RX5 MUX"}, + {"DSD_R IF MUX", "RX6", "CDC_IF RX6 MUX"}, + {"DSD_R IF MUX", "RX7", "CDC_IF RX7 MUX"}, + + {"DSD_FILTER_1", NULL, "DSD_R IF MUX"}, + {"DSD_FILTER_1", NULL, "RX INT2 NATIVE SUPPLY"}, + {"RX INT2 MIX3", "DSD HPHR Switch", "DSD_FILTER_1"}, + + {"DSD_FILTER_0", NULL, "RX INT3 NATIVE SUPPLY"}, + {"RX INT3 MIX3", "DSD LO1 Switch", "DSD_FILTER_0"}, + {"DSD_FILTER_1", NULL, "RX INT4 NATIVE SUPPLY"}, + {"RX INT4 MIX3", "DSD LO2 Switch", "DSD_FILTER_1"}, +}; + +static bool is_valid_dsd_interpolator(int interp_num) +{ + if ((interp_num == INTERP_HPHL) || (interp_num == INTERP_HPHR) || + (interp_num == INTERP_LO1) || (interp_num == INTERP_LO2)) + return true; + + return false; +} + +/** + * tavil_dsd_set_mixer_value - Set DSD HPH/LO mixer value + * + * @dsd_conf: pointer to dsd config + * @interp_num: Interpolator number (HPHL/R, LO1/2) + * @sw_value: Mixer switch value + * + * Returns 0 on success or -EINVAL on failure + */ +int tavil_dsd_set_mixer_value(struct tavil_dsd_config *dsd_conf, + int interp_num, int sw_value) +{ + if (!dsd_conf) + return -EINVAL; + + if (!is_valid_dsd_interpolator(interp_num)) + return -EINVAL; + + dsd_conf->dsd_interp_mixer[interp_num] = !!sw_value; + + return 0; +} +EXPORT_SYMBOL(tavil_dsd_set_mixer_value); + +/** + * tavil_dsd_get_current_mixer_value - Get DSD HPH/LO mixer value + * + * @dsd_conf: pointer to dsd config + * @interp_num: Interpolator number (HPHL/R, LO1/2) + * + * Returns current mixer val for success or -EINVAL for failure + */ +int tavil_dsd_get_current_mixer_value(struct tavil_dsd_config *dsd_conf, + int interp_num) +{ + if (!dsd_conf) + return -EINVAL; + + if (!is_valid_dsd_interpolator(interp_num)) + return -EINVAL; + + return dsd_conf->dsd_interp_mixer[interp_num]; +} +EXPORT_SYMBOL(tavil_dsd_get_current_mixer_value); + +/** + * tavil_dsd_set_out_select - DSD0/1 out select to HPH or LO + * + * @dsd_conf: pointer to dsd config + * @interp_num: Interpolator number (HPHL/R, LO1/2) + * + * Returns 0 for success or -EINVAL for failure + */ +int tavil_dsd_set_out_select(struct tavil_dsd_config *dsd_conf, + int interp_num) +{ + unsigned int reg, val; + struct snd_soc_codec *codec; + + if (!dsd_conf || !dsd_conf->codec) + return -EINVAL; + + codec = dsd_conf->codec; + + if (!is_valid_dsd_interpolator(interp_num)) { + dev_err(codec->dev, "%s: Invalid Interpolator: %d for DSD\n", + __func__, interp_num); + return -EINVAL; + } + + switch (interp_num) { + case INTERP_HPHL: + reg = WCD934X_CDC_DSD0_CFG0; + val = 0x00; + break; + case INTERP_HPHR: + reg = WCD934X_CDC_DSD1_CFG0; + val = 0x00; + break; + case INTERP_LO1: + reg = WCD934X_CDC_DSD0_CFG0; + val = 0x02; + break; + case INTERP_LO2: + reg = WCD934X_CDC_DSD1_CFG0; + val = 0x02; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, reg, 0x02, val); + + return 0; +} +EXPORT_SYMBOL(tavil_dsd_set_out_select); + +/** + * tavil_dsd_reset - Reset DSD block + * + * @dsd_conf: pointer to dsd config + * + */ +void tavil_dsd_reset(struct tavil_dsd_config *dsd_conf) +{ + if (!dsd_conf || !dsd_conf->codec) + return; + + snd_soc_update_bits(dsd_conf->codec, WCD934X_CDC_DSD0_PATH_CTL, + 0x02, 0x02); + snd_soc_update_bits(dsd_conf->codec, WCD934X_CDC_DSD0_PATH_CTL, + 0x01, 0x00); + snd_soc_update_bits(dsd_conf->codec, WCD934X_CDC_DSD1_PATH_CTL, + 0x02, 0x02); + snd_soc_update_bits(dsd_conf->codec, WCD934X_CDC_DSD1_PATH_CTL, + 0x01, 0x00); +} +EXPORT_SYMBOL(tavil_dsd_reset); + +/** + * tavil_dsd_set_interp_rate - Set interpolator rate for DSD + * + * @dsd_conf: pointer to dsd config + * @rx_port: RX port number + * @sample_rate: Sample rate of the RX interpolator + * @sample_rate_val: Interpolator rate value + */ +void tavil_dsd_set_interp_rate(struct tavil_dsd_config *dsd_conf, u16 rx_port, + u32 sample_rate, u8 sample_rate_val) +{ + u8 dsd_inp_sel; + u8 dsd0_inp, dsd1_inp; + u8 val0, val1; + u8 dsd0_out_sel, dsd1_out_sel; + u16 int_fs_reg, interp_num = 0; + struct snd_soc_codec *codec; + + if (!dsd_conf || !dsd_conf->codec) + return; + + codec = dsd_conf->codec; + + dsd_inp_sel = DSD_INP_SEL_RX0 + rx_port - WCD934X_RX_PORT_START_NUMBER; + + val0 = snd_soc_read(codec, WCD934X_CDC_DSD0_CFG0); + val1 = snd_soc_read(codec, WCD934X_CDC_DSD1_CFG0); + dsd0_inp = (val0 & 0x3C) >> 2; + dsd1_inp = (val1 & 0x3C) >> 2; + dsd0_out_sel = (val0 & 0x02) >> 1; + dsd1_out_sel = (val1 & 0x02) >> 1; + + /* Set HPHL or LO1 interp rate based on out select */ + if (dsd_inp_sel == dsd0_inp) { + interp_num = dsd0_out_sel ? INTERP_LO1 : INTERP_HPHL; + dsd_conf->base_sample_rate[DSD0] = sample_rate; + } + + /* Set HPHR or LO2 interp rate based on out select */ + if (dsd_inp_sel == dsd1_inp) { + interp_num = dsd1_out_sel ? INTERP_LO2 : INTERP_HPHR; + dsd_conf->base_sample_rate[DSD1] = sample_rate; + } + + if (interp_num) { + int_fs_reg = WCD934X_CDC_RX0_RX_PATH_CTL + 20 * interp_num; + if ((snd_soc_read(codec, int_fs_reg) & 0x0f) < 0x09) { + dev_dbg(codec->dev, "%s: Set Interp %d to sample_rate val 0x%x\n", + __func__, interp_num, sample_rate_val); + snd_soc_update_bits(codec, int_fs_reg, 0x0F, + sample_rate_val); + } + } +} +EXPORT_SYMBOL(tavil_dsd_set_interp_rate); + +static int tavil_set_dsd_mode(struct snd_soc_codec *codec, int dsd_num, + u8 *pcm_rate_val) +{ + unsigned int dsd_out_sel_reg; + u8 dsd_mode; + u32 sample_rate; + struct tavil_dsd_config *dsd_conf = tavil_get_dsd_config(codec); + + if (!dsd_conf) + return -EINVAL; + + if ((dsd_num < 0) || (dsd_num > 1)) + return -EINVAL; + + sample_rate = dsd_conf->base_sample_rate[dsd_num]; + dsd_out_sel_reg = WCD934X_CDC_DSD0_CFG0 + dsd_num * 16; + + switch (sample_rate) { + case 176400: + dsd_mode = 0; /* DSD_64 */ + *pcm_rate_val = 0xb; + break; + case 352800: + dsd_mode = 1; /* DSD_128 */ + *pcm_rate_val = 0xc; + break; + default: + dev_err(codec->dev, "%s: Invalid DSD rate: %d\n", + __func__, sample_rate); + return -EINVAL; + } + + snd_soc_update_bits(codec, dsd_out_sel_reg, 0x01, dsd_mode); + + return 0; +} + +static void tavil_dsd_data_pull(struct snd_soc_codec *codec, int dsd_num, + u8 pcm_rate_val, bool enable) +{ + u8 clk_en, mute_en; + u8 dsd_inp_sel; + + if (enable) { + clk_en = 0x20; + mute_en = 0x10; + } else { + clk_en = 0x00; + mute_en = 0x00; + } + + if (dsd_num & 0x01) { + snd_soc_update_bits(codec, WCD934X_CDC_RX7_RX_PATH_MIX_CTL, + 0x20, clk_en); + dsd_inp_sel = (snd_soc_read(codec, WCD934X_CDC_DSD0_CFG0) & + 0x3C) >> 2; + dsd_inp_sel = (enable) ? dsd_inp_sel : 0; + if (dsd_inp_sel < 9) { + snd_soc_update_bits(codec, + WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG1, + 0x0F, dsd_inp_sel); + snd_soc_update_bits(codec, + WCD934X_CDC_RX7_RX_PATH_MIX_CTL, + 0x0F, pcm_rate_val); + snd_soc_update_bits(codec, + WCD934X_CDC_RX7_RX_PATH_MIX_CTL, + 0x10, mute_en); + } + } + if (dsd_num & 0x02) { + snd_soc_update_bits(codec, WCD934X_CDC_RX8_RX_PATH_MIX_CTL, + 0x20, clk_en); + dsd_inp_sel = (snd_soc_read(codec, WCD934X_CDC_DSD1_CFG0) & + 0x3C) >> 2; + dsd_inp_sel = (enable) ? dsd_inp_sel : 0; + if (dsd_inp_sel < 9) { + snd_soc_update_bits(codec, + WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG1, + 0x0F, dsd_inp_sel); + snd_soc_update_bits(codec, + WCD934X_CDC_RX8_RX_PATH_MIX_CTL, + 0x0F, pcm_rate_val); + snd_soc_update_bits(codec, + WCD934X_CDC_RX8_RX_PATH_MIX_CTL, + 0x10, mute_en); + } + } +} + +static void tavil_dsd_update_volume(struct tavil_dsd_config *dsd_conf) +{ + snd_soc_update_bits(dsd_conf->codec, WCD934X_CDC_TOP_TOP_CFG0, + 0x01, 0x01); + snd_soc_update_bits(dsd_conf->codec, WCD934X_CDC_TOP_TOP_CFG0, + 0x01, 0x00); +} + +static int tavil_enable_dsd(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_dsd_config *dsd_conf = tavil_get_dsd_config(codec); + int rc, clk_users; + int interp_idx; + u8 pcm_rate_val; + + if (!dsd_conf) { + dev_err(codec->dev, "%s: null dsd_config pointer\n", __func__); + return -EINVAL; + } + + dev_dbg(codec->dev, "%s: DSD%d, event: %d\n", __func__, + w->shift, event); + + if (w->shift == DSD0) { + /* Read out select */ + if (snd_soc_read(codec, WCD934X_CDC_DSD0_CFG0) & 0x02) + interp_idx = INTERP_LO1; + else + interp_idx = INTERP_HPHL; + } else if (w->shift == DSD1) { + /* Read out select */ + if (snd_soc_read(codec, WCD934X_CDC_DSD1_CFG0) & 0x02) + interp_idx = INTERP_LO2; + else + interp_idx = INTERP_HPHR; + } else { + dev_err(codec->dev, "%s: Unsupported DSD:%d\n", + __func__, w->shift); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + clk_users = tavil_codec_enable_interp_clk(codec, event, + interp_idx); + + rc = tavil_set_dsd_mode(codec, w->shift, &pcm_rate_val); + if (rc) + return rc; + + tavil_dsd_data_pull(codec, (1 << w->shift), pcm_rate_val, + true); + + snd_soc_update_bits(codec, + WCD934X_CDC_CLK_RST_CTRL_DSD_CONTROL, 0x01, + 0x01); + if (w->shift == DSD0) { + snd_soc_update_bits(codec, WCD934X_CDC_DSD0_PATH_CTL, + 0x02, 0x02); + snd_soc_update_bits(codec, WCD934X_CDC_DSD0_PATH_CTL, + 0x02, 0x00); + snd_soc_update_bits(codec, WCD934X_CDC_DSD0_PATH_CTL, + 0x01, 0x01); + /* Apply Gain */ + snd_soc_write(codec, WCD934X_CDC_DSD0_CFG1, + dsd_conf->volume[DSD0]); + if (dsd_conf->version == TAVIL_VERSION_1_1) + tavil_dsd_update_volume(dsd_conf); + + } else if (w->shift == DSD1) { + snd_soc_update_bits(codec, WCD934X_CDC_DSD1_PATH_CTL, + 0x02, 0x02); + snd_soc_update_bits(codec, WCD934X_CDC_DSD1_PATH_CTL, + 0x02, 0x00); + snd_soc_update_bits(codec, WCD934X_CDC_DSD1_PATH_CTL, + 0x01, 0x01); + /* Apply Gain */ + snd_soc_write(codec, WCD934X_CDC_DSD1_CFG1, + dsd_conf->volume[DSD1]); + if (dsd_conf->version == TAVIL_VERSION_1_1) + tavil_dsd_update_volume(dsd_conf); + } + /* 10msec sleep required after DSD clock is set */ + usleep_range(10000, 10100); + + if (clk_users > 1) { + snd_soc_update_bits(codec, WCD934X_ANA_RX_SUPPLIES, + 0x02, 0x02); + if (w->shift == DSD0) + snd_soc_update_bits(codec, + WCD934X_CDC_DSD0_CFG2, + 0x04, 0x00); + if (w->shift == DSD1) + snd_soc_update_bits(codec, + WCD934X_CDC_DSD1_CFG2, + 0x04, 0x00); + + } + break; + case SND_SOC_DAPM_POST_PMD: + if (w->shift == DSD0) { + snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, + 0x04, 0x04); + snd_soc_update_bits(codec, WCD934X_CDC_DSD0_PATH_CTL, + 0x01, 0x00); + } else if (w->shift == DSD1) { + snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, + 0x04, 0x04); + snd_soc_update_bits(codec, WCD934X_CDC_DSD1_PATH_CTL, + 0x01, 0x00); + } + + tavil_codec_enable_interp_clk(codec, event, interp_idx); + + if (!(snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01) && + !(snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) { + snd_soc_update_bits(codec, + WCD934X_CDC_CLK_RST_CTRL_DSD_CONTROL, + 0x01, 0x00); + tavil_dsd_data_pull(codec, 0x03, 0x04, false); + tavil_dsd_reset(dsd_conf); + } + break; + } + + return 0; +} + +static int tavil_dsd_vol_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 2; + uinfo->value.integer.min = DSD_VOLUME_MIN_M110dB; + uinfo->value.integer.max = DSD_VOLUME_MAX_0dB; + + return 0; +} + +static int tavil_dsd_vol_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_dsd_config *dsd_conf = tavil_get_dsd_config(codec); + int nv[DSD_MAX], cv[DSD_MAX]; + int step_size, nv1; + int i, dsd_idx; + + if (!dsd_conf) + return 0; + + mutex_lock(&dsd_conf->vol_mutex); + + for (dsd_idx = DSD0; dsd_idx < DSD_MAX; dsd_idx++) { + cv[dsd_idx] = dsd_conf->volume[dsd_idx]; + nv[dsd_idx] = ucontrol->value.integer.value[dsd_idx]; + } + + if ((!DSD_VOLUME_RANGE_CHECK(nv[DSD0])) || + (!DSD_VOLUME_RANGE_CHECK(nv[DSD1]))) + goto done; + + for (dsd_idx = DSD0; dsd_idx < DSD_MAX; dsd_idx++) { + if (cv[dsd_idx] == nv[dsd_idx]) + continue; + + dev_dbg(codec->dev, "%s: DSD%d cur.vol: %d, new vol: %d\n", + __func__, dsd_idx, cv[dsd_idx], nv[dsd_idx]); + + step_size = (nv[dsd_idx] - cv[dsd_idx]) / + DSD_VOLUME_STEPS; + + nv1 = cv[dsd_idx]; + + for (i = 0; i < DSD_VOLUME_STEPS; i++) { + nv1 += step_size; + snd_soc_write(codec, + WCD934X_CDC_DSD0_CFG1 + 16 * dsd_idx, + nv1); + if (dsd_conf->version == TAVIL_VERSION_1_1) + tavil_dsd_update_volume(dsd_conf); + + /* sleep required after each volume step */ + usleep_range(DSD_VOLUME_STEP_DELAY_US, + (DSD_VOLUME_STEP_DELAY_US + + DSD_VOLUME_USLEEP_MARGIN_US)); + } + if (nv1 != nv[dsd_idx]) { + snd_soc_write(codec, + WCD934X_CDC_DSD0_CFG1 + 16 * dsd_idx, + nv[dsd_idx]); + + if (dsd_conf->version == TAVIL_VERSION_1_1) + tavil_dsd_update_volume(dsd_conf); + } + + dsd_conf->volume[dsd_idx] = nv[dsd_idx]; + } + +done: + mutex_unlock(&dsd_conf->vol_mutex); + + return 0; +} + +static int tavil_dsd_vol_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_dsd_config *dsd_conf = tavil_get_dsd_config(codec); + + if (dsd_conf) { + ucontrol->value.integer.value[0] = dsd_conf->volume[DSD0]; + ucontrol->value.integer.value[1] = dsd_conf->volume[DSD1]; + } + + return 0; +} + +static const struct snd_kcontrol_new tavil_dsd_vol_controls[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .name = "DSD Volume", + .info = tavil_dsd_vol_info, + .get = tavil_dsd_vol_get, + .put = tavil_dsd_vol_put, + .tlv = { .p = tavil_dsd_db_scale }, + }, +}; + +static const struct snd_soc_dapm_widget tavil_dsd_widgets[] = { + SND_SOC_DAPM_MUX("DSD_L IF MUX", SND_SOC_NOPM, 0, 0, &dsd_l_if_mux), + SND_SOC_DAPM_MUX_E("DSD_FILTER_0", SND_SOC_NOPM, 0, 0, &dsd_filt0_mux, + tavil_enable_dsd, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("DSD_R IF MUX", SND_SOC_NOPM, 0, 0, &dsd_r_if_mux), + SND_SOC_DAPM_MUX_E("DSD_FILTER_1", SND_SOC_NOPM, 1, 0, &dsd_filt1_mux, + tavil_enable_dsd, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +/** + * tavil_dsd_post_ssr_init - DSD intialization after subsystem restart + * + * @codec: pointer to snd_soc_codec + * + * Returns 0 on success or error on failure + */ +int tavil_dsd_post_ssr_init(struct tavil_dsd_config *dsd_conf) +{ + struct snd_soc_codec *codec; + + if (!dsd_conf || !dsd_conf->codec) + return -EINVAL; + + codec = dsd_conf->codec; + /* Disable DSD Interrupts */ + snd_soc_update_bits(codec, WCD934X_INTR_CODEC_MISC_MASK, 0x08, 0x08); + + /* DSD registers init */ + if (dsd_conf->version == TAVIL_VERSION_1_0) { + snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, 0x02, 0x00); + snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, 0x02, 0x00); + } + /* DSD0: Mute EN */ + snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, 0x04, 0x04); + /* DSD1: Mute EN */ + snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, 0x04, 0x04); + snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG3, 0x10, + 0x10); + snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG3, 0x10, + 0x10); + snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG0, 0x0E, + 0x0A); + snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG0, 0x0E, + 0x0A); + snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG1, 0x07, + 0x04); + snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG1, 0x07, + 0x04); + + /* Enable DSD Interrupts */ + snd_soc_update_bits(codec, WCD934X_INTR_CODEC_MISC_MASK, 0x08, 0x00); + + return 0; +} +EXPORT_SYMBOL(tavil_dsd_post_ssr_init); + +/** + * tavil_dsd_init - DSD intialization + * + * @codec: pointer to snd_soc_codec + * + * Returns pointer to tavil_dsd_config for success or NULL for failure + */ +struct tavil_dsd_config *tavil_dsd_init(struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm; + struct tavil_dsd_config *dsd_conf; + u8 val; + + if (!codec) + return NULL; + + dapm = snd_soc_codec_get_dapm(codec); + + /* Read efuse register to check if DSD is supported */ + val = snd_soc_read(codec, WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT14); + if (val & 0x80) { + dev_info(codec->dev, "%s: DSD unsupported for this codec version\n", + __func__); + return NULL; + } + + dsd_conf = devm_kzalloc(codec->dev, sizeof(struct tavil_dsd_config), + GFP_KERNEL); + if (!dsd_conf) + return NULL; + + dsd_conf->codec = codec; + + /* Read version */ + dsd_conf->version = snd_soc_read(codec, + WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE0); + /* DSD registers init */ + if (dsd_conf->version == TAVIL_VERSION_1_0) { + snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, 0x02, 0x00); + snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, 0x02, 0x00); + } + /* DSD0: Mute EN */ + snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, 0x04, 0x04); + /* DSD1: Mute EN */ + snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, 0x04, 0x04); + snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG3, 0x10, + 0x10); + snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG3, 0x10, + 0x10); + snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG0, 0x0E, + 0x0A); + snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG0, 0x0E, + 0x0A); + snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG1, 0x07, + 0x04); + snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG1, 0x07, + 0x04); + + snd_soc_dapm_new_controls(dapm, tavil_dsd_widgets, + ARRAY_SIZE(tavil_dsd_widgets)); + + snd_soc_dapm_add_routes(dapm, tavil_dsd_audio_map, + ARRAY_SIZE(tavil_dsd_audio_map)); + + mutex_init(&dsd_conf->vol_mutex); + dsd_conf->volume[DSD0] = DSD_VOLUME_MAX_0dB; + dsd_conf->volume[DSD1] = DSD_VOLUME_MAX_0dB; + + snd_soc_add_codec_controls(codec, tavil_dsd_vol_controls, + ARRAY_SIZE(tavil_dsd_vol_controls)); + + /* Enable DSD Interrupts */ + snd_soc_update_bits(codec, WCD934X_INTR_CODEC_MISC_MASK, 0x08, 0x00); + + return dsd_conf; +} +EXPORT_SYMBOL(tavil_dsd_init); + +/** + * tavil_dsd_deinit - DSD de-intialization + * + * @dsd_conf: pointer to tavil_dsd_config + */ +void tavil_dsd_deinit(struct tavil_dsd_config *dsd_conf) +{ + struct snd_soc_codec *codec; + + if (!dsd_conf) + return; + + codec = dsd_conf->codec; + + mutex_destroy(&dsd_conf->vol_mutex); + + /* Disable DSD Interrupts */ + snd_soc_update_bits(codec, WCD934X_INTR_CODEC_MISC_MASK, 0x08, 0x08); + + devm_kfree(codec->dev, dsd_conf); +} +EXPORT_SYMBOL(tavil_dsd_deinit); diff --git a/sound/soc/codecs/wcd934x/wcd934x-dsd.h b/sound/soc/codecs/wcd934x/wcd934x-dsd.h new file mode 100644 index 000000000000..834b96cd1805 --- /dev/null +++ b/sound/soc/codecs/wcd934x/wcd934x-dsd.h @@ -0,0 +1,97 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __WCD934X_DSD_H__ +#define __WCD934X_DSD_H__ + +#include +#include "wcd934x.h" + +enum { + DSD0, + DSD1, + DSD_MAX, +}; + +enum { + DSD_INP_SEL_ZERO = 0, + DSD_INP_SEL_RX0, + DSD_INP_SEL_RX1, + DSD_INP_SEL_RX2, + DSD_INP_SEL_RX3, + DSD_INP_SEL_RX4, + DSD_INP_SEL_RX5, + DSD_INP_SEL_RX6, + DSD_INP_SEL_RX7, +}; + +struct tavil_dsd_config { + struct snd_soc_codec *codec; + unsigned int dsd_interp_mixer[INTERP_MAX]; + u32 base_sample_rate[DSD_MAX]; + int volume[DSD_MAX]; + struct mutex vol_mutex; + int version; +}; + +#if IS_ENABLED(CONFIG_SND_SOC_WCD934X_DSD) +int tavil_dsd_set_mixer_value(struct tavil_dsd_config *dsd_conf, + int interp_num, int sw_value); +int tavil_dsd_get_current_mixer_value(struct tavil_dsd_config *dsd_conf, + int interp_num); +int tavil_dsd_set_out_select(struct tavil_dsd_config *dsd_conf, + int interp_num); +void tavil_dsd_reset(struct tavil_dsd_config *dsd_conf); +void tavil_dsd_set_interp_rate(struct tavil_dsd_config *dsd_conf, u16 rx_port, + u32 sample_rate, u8 sample_rate_val); +struct tavil_dsd_config *tavil_dsd_init(struct snd_soc_codec *codec); +void tavil_dsd_deinit(struct tavil_dsd_config *dsd_config); +int tavil_dsd_post_ssr_init(struct tavil_dsd_config *dsd_config); +#else +int tavil_dsd_set_mixer_value(struct tavil_dsd_config *dsd_conf, + int interp_num, int sw_value) +{ + return 0; +} + +int tavil_dsd_get_current_mixer_value(struct tavil_dsd_config *dsd_conf, + int interp_num) +{ + return 0; +} + +int tavil_dsd_set_out_select(struct tavil_dsd_config *dsd_conf, + int interp_num) +{ + return 0; +} + +void tavil_dsd_reset(struct tavil_dsd_config *dsd_conf) +{ } + +void tavil_dsd_set_interp_rate(struct tavil_dsd_config *dsd_conf, u16 rx_port, + u32 sample_rate, u8 sample_rate_val) +{ } + +struct tavil_dsd_config *tavil_dsd_init(struct snd_soc_codec *codec) +{ + return NULL; +} + +void tavil_dsd_deinit(struct tavil_dsd_config *dsd_config) +{ } +int tavil_dsd_post_ssr_init(struct tavil_dsd_config *dsd_config) +{ + return 0; +} +#endif +#endif diff --git a/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c b/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c new file mode 100644 index 000000000000..8da042531fd8 --- /dev/null +++ b/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c @@ -0,0 +1,1369 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcd934x.h" +#include "wcd934x-dsp-cntl.h" + +#define WCD_CNTL_DIR_NAME_LEN_MAX 32 +#define WCD_CPE_FLL_MAX_RETRIES 5 +#define WCD_MEM_ENABLE_MAX_RETRIES 20 +#define WCD_DSP_BOOT_TIMEOUT_MS 3000 +#define WCD_SYSFS_ENTRY_MAX_LEN 8 +#define WCD_PROCFS_ENTRY_MAX_LEN 16 +#define WCD_934X_RAMDUMP_START_ADDR 0x20100000 +#define WCD_934X_RAMDUMP_SIZE ((1024 * 1024) - 128) + +#define WCD_CNTL_MUTEX_LOCK(codec, lock) \ +{ \ + dev_dbg(codec->dev, "%s: mutex_lock(%s)\n", \ + __func__, __stringify_1(lock)); \ + mutex_lock(&lock); \ +} + +#define WCD_CNTL_MUTEX_UNLOCK(codec, lock) \ +{ \ + dev_dbg(codec->dev, "%s: mutex_unlock(%s)\n", \ + __func__, __stringify_1(lock)); \ + mutex_unlock(&lock); \ +} + +enum wcd_mem_type { + WCD_MEM_TYPE_ALWAYS_ON, + WCD_MEM_TYPE_SWITCHABLE, +}; + +struct wcd_cntl_attribute { + struct attribute attr; + ssize_t (*show)(struct wcd_dsp_cntl *cntl, char *buf); + ssize_t (*store)(struct wcd_dsp_cntl *cntl, const char *buf, + ssize_t count); +}; + +#define WCD_CNTL_ATTR(_name, _mode, _show, _store) \ +static struct wcd_cntl_attribute cntl_attr_##_name = { \ + .attr = {.name = __stringify(_name), .mode = _mode}, \ + .show = _show, \ + .store = _store, \ +} + +#define to_wcd_cntl_attr(a) \ + container_of((a), struct wcd_cntl_attribute, attr) + +#define to_wcd_cntl(kobj) \ + container_of((kobj), struct wcd_dsp_cntl, wcd_kobj) + +static u8 mem_enable_values[] = { + 0xFE, 0xFC, 0xF8, 0xF0, + 0xE0, 0xC0, 0x80, 0x00, +}; + +static ssize_t wdsp_boot_show(struct wcd_dsp_cntl *cntl, char *buf) +{ + return snprintf(buf, WCD_SYSFS_ENTRY_MAX_LEN, + "%u", cntl->boot_reqs); +} + +static ssize_t wdsp_boot_store(struct wcd_dsp_cntl *cntl, + const char *buf, ssize_t count) +{ + u32 val; + bool vote; + int ret; + + ret = kstrtou32(buf, 10, &val); + if (ret) { + dev_err(cntl->codec->dev, + "%s: Invalid entry, ret = %d\n", __func__, ret); + return -EINVAL; + } + + if (val > 0) { + cntl->boot_reqs++; + vote = true; + } else { + cntl->boot_reqs--; + vote = false; + } + + if (cntl->m_dev && cntl->m_ops && + cntl->m_ops->vote_for_dsp) + ret = cntl->m_ops->vote_for_dsp(cntl->m_dev, vote); + else + ret = -EINVAL; + + if (ret < 0) + dev_err(cntl->codec->dev, + "%s: failed to %s dsp\n", __func__, + vote ? "enable" : "disable"); + return count; +} + +WCD_CNTL_ATTR(boot, 0660, wdsp_boot_show, wdsp_boot_store); + +static ssize_t wcd_cntl_sysfs_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct wcd_cntl_attribute *wcd_attr = to_wcd_cntl_attr(attr); + struct wcd_dsp_cntl *cntl = to_wcd_cntl(kobj); + ssize_t ret = -EINVAL; + + if (cntl && wcd_attr->show) + ret = wcd_attr->show(cntl, buf); + + return ret; +} + +static ssize_t wcd_cntl_sysfs_store(struct kobject *kobj, + struct attribute *attr, const char *buf, + size_t count) +{ + struct wcd_cntl_attribute *wcd_attr = to_wcd_cntl_attr(attr); + struct wcd_dsp_cntl *cntl = to_wcd_cntl(kobj); + ssize_t ret = -EINVAL; + + if (cntl && wcd_attr->store) + ret = wcd_attr->store(cntl, buf, count); + + return ret; +} + +static const struct sysfs_ops wcd_cntl_sysfs_ops = { + .show = wcd_cntl_sysfs_show, + .store = wcd_cntl_sysfs_store, +}; + +static struct kobj_type wcd_cntl_ktype = { + .sysfs_ops = &wcd_cntl_sysfs_ops, +}; + +static void wcd_cntl_change_online_state(struct wcd_dsp_cntl *cntl, + u8 online) +{ + struct wdsp_ssr_entry *ssr_entry = &cntl->ssr_entry; + unsigned long ret; + + WCD_CNTL_MUTEX_LOCK(cntl->codec, cntl->ssr_mutex); + ssr_entry->offline = !online; + /* Make sure the write is complete */ + wmb(); + ret = xchg(&ssr_entry->offline_change, 1); + wake_up_interruptible(&ssr_entry->offline_poll_wait); + dev_dbg(cntl->codec->dev, + "%s: requested %u, offline %u offline_change %u, ret = %ldn", + __func__, online, ssr_entry->offline, + ssr_entry->offline_change, ret); + WCD_CNTL_MUTEX_UNLOCK(cntl->codec, cntl->ssr_mutex); +} + +static ssize_t wdsp_ssr_entry_read(struct snd_info_entry *entry, + void *file_priv_data, struct file *file, + char __user *buf, size_t count, loff_t pos) +{ + int len = 0; + char buffer[WCD_PROCFS_ENTRY_MAX_LEN]; + struct wcd_dsp_cntl *cntl; + struct wdsp_ssr_entry *ssr_entry; + ssize_t ret; + u8 offline; + + cntl = (struct wcd_dsp_cntl *) entry->private_data; + if (!cntl) { + pr_err("%s: Invalid private data for SSR procfs entry\n", + __func__); + return -EINVAL; + } + + ssr_entry = &cntl->ssr_entry; + + WCD_CNTL_MUTEX_LOCK(cntl->codec, cntl->ssr_mutex); + offline = ssr_entry->offline; + /* Make sure the read is complete */ + rmb(); + dev_dbg(cntl->codec->dev, "%s: offline = %s\n", __func__, + offline ? "true" : "false"); + len = snprintf(buffer, sizeof(buffer), "%s\n", + offline ? "OFFLINE" : "ONLINE"); + ret = simple_read_from_buffer(buf, count, &pos, buffer, len); + WCD_CNTL_MUTEX_UNLOCK(cntl->codec, cntl->ssr_mutex); + + return ret; +} + +static unsigned int wdsp_ssr_entry_poll(struct snd_info_entry *entry, + void *private_data, struct file *file, + poll_table *wait) +{ + struct wcd_dsp_cntl *cntl; + struct wdsp_ssr_entry *ssr_entry; + unsigned int ret = 0; + + if (!entry || !entry->private_data) { + pr_err("%s: %s is NULL\n", __func__, + (!entry) ? "entry" : "private_data"); + return -EINVAL; + } + + cntl = (struct wcd_dsp_cntl *) entry->private_data; + ssr_entry = &cntl->ssr_entry; + + dev_dbg(cntl->codec->dev, "%s: Poll wait, offline = %u\n", + __func__, ssr_entry->offline); + poll_wait(file, &ssr_entry->offline_poll_wait, wait); + dev_dbg(cntl->codec->dev, "%s: Woken up Poll wait, offline = %u\n", + __func__, ssr_entry->offline); + + WCD_CNTL_MUTEX_LOCK(cntl->codec, cntl->ssr_mutex); + if (xchg(&ssr_entry->offline_change, 0)) + ret = POLLIN | POLLPRI | POLLRDNORM; + dev_dbg(cntl->codec->dev, "%s: ret (%d) from poll_wait\n", + __func__, ret); + WCD_CNTL_MUTEX_UNLOCK(cntl->codec, cntl->ssr_mutex); + + return ret; +} + +static struct snd_info_entry_ops wdsp_ssr_entry_ops = { + .read = wdsp_ssr_entry_read, + .poll = wdsp_ssr_entry_poll, +}; + +static int wcd_cntl_cpe_fll_calibrate(struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + int ret = 0, retry = 0; + u8 cal_lsb, cal_msb; + u8 lock_det; + + /* Make sure clocks are gated */ + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPE_CTL, + 0x05, 0x00); + + /* Enable CPE FLL reference clock */ + snd_soc_update_bits(codec, WCD934X_CLK_SYS_MCLK2_PRG1, + 0x80, 0x80); + + snd_soc_update_bits(codec, WCD934X_CPE_FLL_USER_CTL_5, + 0xF3, 0x13); + snd_soc_write(codec, WCD934X_CPE_FLL_L_VAL_CTL_0, 0x50); + + /* Disable CPAR reset and Enable CPAR clk */ + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, + 0x02, 0x02); + + /* Write calibration l-value based on cdc clk rate */ + if (cntl->clk_rate == 9600000) { + cal_lsb = 0x6d; + cal_msb = 0x00; + } else { + cal_lsb = 0x56; + cal_msb = 0x00; + } + snd_soc_write(codec, WCD934X_CPE_FLL_USER_CTL_6, cal_lsb); + snd_soc_write(codec, WCD934X_CPE_FLL_USER_CTL_7, cal_msb); + + /* FLL mode to follow power up sequence */ + snd_soc_update_bits(codec, WCD934X_CPE_FLL_FLL_MODE, + 0x60, 0x00); + + /* HW controlled CPE FLL */ + snd_soc_update_bits(codec, WCD934X_CPE_FLL_FLL_MODE, + 0x80, 0x80); + + /* Force on CPE FLL */ + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CFG, + 0x04, 0x04); + + do { + /* Time for FLL calibration to complete */ + usleep_range(1000, 1100); + lock_det = snd_soc_read(codec, WCD934X_CPE_FLL_STATUS_3); + retry++; + } while (!(lock_det & 0x01) && + retry <= WCD_CPE_FLL_MAX_RETRIES); + + if (!(lock_det & 0x01)) { + dev_err(codec->dev, "%s: lock detect not set, 0x%02x\n", + __func__, lock_det); + ret = -EIO; + goto err_lock_det; + } + + snd_soc_update_bits(codec, WCD934X_CPE_FLL_FLL_MODE, + 0x60, 0x20); + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CFG, + 0x04, 0x00); + return ret; + +err_lock_det: + /* Undo the register settings */ + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CFG, + 0x04, 0x00); + snd_soc_update_bits(codec, WCD934X_CPE_FLL_FLL_MODE, + 0x80, 0x00); + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, + 0x02, 0x00); + return ret; +} + +static void wcd_cntl_config_cpar(struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + u8 nom_lo, nom_hi, svs2_lo, svs2_hi; + + /* Configure CPAR */ + nom_hi = svs2_hi = 0; + if (cntl->clk_rate == 9600000) { + nom_lo = 0x90; + svs2_lo = 0x50; + } else { + nom_lo = 0x70; + svs2_lo = 0x3e; + } + + snd_soc_write(codec, WCD934X_TEST_DEBUG_LVAL_NOM_LOW, nom_lo); + snd_soc_write(codec, WCD934X_TEST_DEBUG_LVAL_NOM_HIGH, nom_hi); + snd_soc_write(codec, WCD934X_TEST_DEBUG_LVAL_SVS_SVS2_LOW, svs2_lo); + snd_soc_write(codec, WCD934X_TEST_DEBUG_LVAL_SVS_SVS2_HIGH, svs2_hi); + + snd_soc_update_bits(codec, WCD934X_CPE_SS_PWR_CPEFLL_CTL, + 0x03, 0x03); +} + +static int wcd_cntl_cpe_fll_ctrl(struct wcd_dsp_cntl *cntl, + bool enable) +{ + struct snd_soc_codec *codec = cntl->codec; + int ret = 0; + + if (enable) { + ret = wcd_cntl_cpe_fll_calibrate(cntl); + if (ret < 0) { + dev_err(codec->dev, + "%s: cpe_fll_cal failed, err = %d\n", + __func__, ret); + goto done; + } + + wcd_cntl_config_cpar(cntl); + + /* Enable AHB CLK and CPE CLK*/ + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPE_CTL, + 0x05, 0x05); + } else { + /* Disable AHB CLK and CPE CLK */ + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPE_CTL, + 0x05, 0x00); + /* Reset the CPAR mode for CPE FLL */ + snd_soc_write(codec, WCD934X_CPE_FLL_FLL_MODE, 0x20); + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CFG, + 0x04, 0x00); + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, + 0x02, 0x00); + } +done: + return ret; +} + +static int wcd_cntl_clocks_enable(struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + int ret; + + WCD_CNTL_MUTEX_LOCK(codec, cntl->clk_mutex); + /* Enable codec clock */ + if (cntl->cdc_cb && cntl->cdc_cb->cdc_clk_en) + ret = cntl->cdc_cb->cdc_clk_en(codec, true); + else + ret = -EINVAL; + + if (ret < 0) { + dev_err(codec->dev, + "%s: Failed to enable cdc clk, err = %d\n", + __func__, ret); + goto done; + } + /* Pull CPAR out of reset */ + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, 0x04, 0x00); + + /* Configure and Enable CPE FLL clock */ + ret = wcd_cntl_cpe_fll_ctrl(cntl, true); + if (ret < 0) { + dev_err(codec->dev, + "%s: Failed to enable cpe clk, err = %d\n", + __func__, ret); + goto err_cpe_clk; + } + cntl->is_clk_enabled = true; + + /* Ungate the CPR clock */ + snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_GATE, 0x10, 0x00); +done: + WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex); + return ret; + +err_cpe_clk: + if (cntl->cdc_cb && cntl->cdc_cb->cdc_clk_en) + cntl->cdc_cb->cdc_clk_en(codec, false); + + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, 0x04, 0x04); + WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex); + return ret; +} + +static int wcd_cntl_clocks_disable(struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + int ret = 0; + + WCD_CNTL_MUTEX_LOCK(codec, cntl->clk_mutex); + if (!cntl->is_clk_enabled) { + dev_info(codec->dev, "%s: clocks already disabled\n", + __func__); + goto done; + } + + /* Gate the CPR clock */ + snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_GATE, 0x10, 0x10); + + /* Disable CPE FLL clock */ + ret = wcd_cntl_cpe_fll_ctrl(cntl, false); + if (ret < 0) + dev_err(codec->dev, + "%s: Failed to disable cpe clk, err = %d\n", + __func__, ret); + + /* + * Even if CPE FLL disable failed, go ahead and disable + * the codec clock + */ + if (cntl->cdc_cb && cntl->cdc_cb->cdc_clk_en) + ret = cntl->cdc_cb->cdc_clk_en(codec, false); + else + ret = -EINVAL; + + cntl->is_clk_enabled = false; + + /* Put CPAR in reset */ + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, 0x04, 0x04); +done: + WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex); + return ret; +} + +static void wcd_cntl_cpar_ctrl(struct wcd_dsp_cntl *cntl, + bool enable) +{ + struct snd_soc_codec *codec = cntl->codec; + + if (enable) + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, 0x03, 0x03); + else + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, 0x03, 0x00); +} + +static int wcd_cntl_enable_memory(struct wcd_dsp_cntl *cntl, + enum wcd_mem_type mem_type) +{ + struct snd_soc_codec *codec = cntl->codec; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + int loop_cnt = 0; + u8 status; + int ret = 0; + + + switch (mem_type) { + + case WCD_MEM_TYPE_ALWAYS_ON: + + /* 512KB of always on region */ + wcd9xxx_slim_write_repeat(wcd9xxx, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0, + ARRAY_SIZE(mem_enable_values), + mem_enable_values); + wcd9xxx_slim_write_repeat(wcd9xxx, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1, + ARRAY_SIZE(mem_enable_values), + mem_enable_values); + break; + + case WCD_MEM_TYPE_SWITCHABLE: + + snd_soc_update_bits(codec, WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL, + 0x04, 0x00); + snd_soc_update_bits(codec, WCD934X_TEST_DEBUG_MEM_CTRL, + 0x80, 0x80); + snd_soc_update_bits(codec, WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL, + 0x01, 0x01); + do { + loop_cnt++; + /* Time to enable the power domain for memory */ + usleep_range(100, 150); + status = snd_soc_read(codec, + WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL); + } while ((status & 0x02) != 0x02 && + loop_cnt != WCD_MEM_ENABLE_MAX_RETRIES); + + if ((status & 0x02) != 0x02) { + dev_err(cntl->codec->dev, + "%s: power domain not enabled, status = 0x%02x\n", + __func__, status); + ret = -EIO; + goto done; + } + + /* Rest of the memory */ + wcd9xxx_slim_write_repeat(wcd9xxx, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2, + ARRAY_SIZE(mem_enable_values), + mem_enable_values); + wcd9xxx_slim_write_repeat(wcd9xxx, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3, + ARRAY_SIZE(mem_enable_values), + mem_enable_values); + + snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN, + 0x05); + break; + + default: + dev_err(cntl->codec->dev, "%s: Invalid mem_type %d\n", + __func__, mem_type); + ret = -EINVAL; + break; + } +done: + /* Make sure Deep sleep of memories is enabled for all banks */ + snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, 0xFF); + snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, 0x0F); + + return ret; +} + +static void wcd_cntl_disable_memory(struct wcd_dsp_cntl *cntl, + enum wcd_mem_type mem_type) +{ + struct snd_soc_codec *codec = cntl->codec; + u8 val; + + switch (mem_type) { + case WCD_MEM_TYPE_ALWAYS_ON: + snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1, + 0xFF); + snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0, + 0xFF); + break; + case WCD_MEM_TYPE_SWITCHABLE: + snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3, + 0xFF); + snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2, + 0xFF); + snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN, + 0x07); + + snd_soc_update_bits(codec, WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL, + 0x01, 0x00); + val = snd_soc_read(codec, WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL); + if (val & 0x02) + dev_err(codec->dev, + "%s: Disable switchable failed, val = 0x%02x", + __func__, val); + + snd_soc_update_bits(codec, WCD934X_TEST_DEBUG_MEM_CTRL, + 0x80, 0x00); + break; + default: + dev_err(cntl->codec->dev, "%s: Invalid mem_type %d\n", + __func__, mem_type); + break; + } + + snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, 0xFF); + snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, 0x0F); +} + +static void wcd_cntl_do_shutdown(struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + + /* Disable WDOG */ + snd_soc_update_bits(codec, WCD934X_CPE_SS_WDOG_CFG, + 0x3F, 0x01); + + /* Put WDSP in reset state */ + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPE_CTL, + 0x02, 0x00); + + /* If DSP transitions from boot to shutdown, then vote for SVS */ + if (cntl->is_wdsp_booted) + cntl->cdc_cb->cdc_vote_svs(codec, true); + cntl->is_wdsp_booted = false; +} + +static int wcd_cntl_do_boot(struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + int ret = 0; + + /* + * Debug mode is set from debugfs file node. If debug_mode + * is set, then do not configure the watchdog timer. This + * will be required for debugging the DSP firmware. + */ + if (cntl->debug_mode) { + snd_soc_update_bits(codec, WCD934X_CPE_SS_WDOG_CFG, + 0x3F, 0x01); + } else { + snd_soc_update_bits(codec, WCD934X_CPE_SS_WDOG_CFG, + 0x3F, 0x21); + } + + /* Make sure all the error interrupts are cleared */ + snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_0A, 0xFF); + snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_0B, 0xFF); + + reinit_completion(&cntl->boot_complete); + + /* Remove WDSP out of reset */ + snd_soc_update_bits(codec, WCD934X_CPE_SS_CPE_CTL, + 0x02, 0x02); + + /* + * In debug mode, DSP may not boot up normally, + * wait indefinitely for DSP to boot. + */ + if (cntl->debug_mode) { + wait_for_completion(&cntl->boot_complete); + dev_dbg(codec->dev, "%s: WDSP booted in dbg mode\n", __func__); + cntl->is_wdsp_booted = true; + goto done; + } + + /* Boot in normal mode */ + ret = wait_for_completion_timeout(&cntl->boot_complete, + msecs_to_jiffies(WCD_DSP_BOOT_TIMEOUT_MS)); + if (!ret) { + dev_err(codec->dev, "%s: WDSP boot timed out\n", + __func__); + ret = -ETIMEDOUT; + goto err_boot; + } else { + /* + * Re-initialize the return code to 0, as in success case, + * it will hold the remaining time for completion timeout + */ + ret = 0; + } + + dev_dbg(codec->dev, "%s: WDSP booted in normal mode\n", __func__); + cntl->is_wdsp_booted = true; + + /* Enable WDOG */ + snd_soc_update_bits(codec, WCD934X_CPE_SS_WDOG_CFG, + 0x10, 0x10); +done: + /* If dsp booted up, then remove vote on SVS */ + if (cntl->is_wdsp_booted) + cntl->cdc_cb->cdc_vote_svs(codec, false); + + return ret; +err_boot: + /* call shutdown to perform cleanup */ + wcd_cntl_do_shutdown(cntl); + return ret; +} + +static irqreturn_t wcd_cntl_ipc_irq(int irq, void *data) +{ + struct wcd_dsp_cntl *cntl = data; + int ret; + + complete(&cntl->boot_complete); + + if (cntl->m_dev && cntl->m_ops && + cntl->m_ops->signal_handler) + ret = cntl->m_ops->signal_handler(cntl->m_dev, WDSP_IPC1_INTR, + NULL); + else + ret = -EINVAL; + + if (ret < 0) + dev_err(cntl->codec->dev, + "%s: Failed to handle irq %d\n", __func__, irq); + + return IRQ_HANDLED; +} + +static irqreturn_t wcd_cntl_err_irq(int irq, void *data) +{ + struct wcd_dsp_cntl *cntl = data; + struct snd_soc_codec *codec = cntl->codec; + struct wdsp_err_signal_arg arg; + u16 status = 0; + u8 reg_val; + int ret = 0; + + reg_val = snd_soc_read(codec, WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0A); + status = status | reg_val; + + reg_val = snd_soc_read(codec, WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0B); + status = status | (reg_val << 8); + + dev_info(codec->dev, "%s: error interrupt status = 0x%x\n", + __func__, status); + + if ((status & cntl->irqs.fatal_irqs) && + (cntl->m_dev && cntl->m_ops && cntl->m_ops->signal_handler)) { + arg.mem_dumps_enabled = cntl->ramdump_enable; + arg.remote_start_addr = WCD_934X_RAMDUMP_START_ADDR; + arg.dump_size = WCD_934X_RAMDUMP_SIZE; + ret = cntl->m_ops->signal_handler(cntl->m_dev, WDSP_ERR_INTR, + &arg); + if (ret < 0) + dev_err(cntl->codec->dev, + "%s: Failed to handle fatal irq 0x%x\n", + __func__, status & cntl->irqs.fatal_irqs); + wcd_cntl_change_online_state(cntl, 0); + } else { + dev_err(cntl->codec->dev, "%s: Invalid signal_handler\n", + __func__); + } + + return IRQ_HANDLED; +} + +static int wcd_control_handler(struct device *dev, void *priv_data, + enum wdsp_event_type event, void *data) +{ + struct wcd_dsp_cntl *cntl = priv_data; + struct snd_soc_codec *codec = cntl->codec; + int ret = 0; + + switch (event) { + case WDSP_EVENT_POST_INIT: + case WDSP_EVENT_POST_DLOAD_CODE: + case WDSP_EVENT_DLOAD_FAILED: + case WDSP_EVENT_POST_SHUTDOWN: + + if (event == WDSP_EVENT_POST_DLOAD_CODE) + /* Mark DSP online since code download is complete */ + wcd_cntl_change_online_state(cntl, 1); + + /* Disable CPAR */ + wcd_cntl_cpar_ctrl(cntl, false); + /* Disable all the clocks */ + ret = wcd_cntl_clocks_disable(cntl); + if (ret < 0) + dev_err(codec->dev, + "%s: Failed to disable clocks, err = %d\n", + __func__, ret); + break; + + case WDSP_EVENT_PRE_DLOAD_DATA: + case WDSP_EVENT_PRE_DLOAD_CODE: + + /* Enable all the clocks */ + ret = wcd_cntl_clocks_enable(cntl); + if (ret < 0) { + dev_err(codec->dev, + "%s: Failed to enable clocks, err = %d\n", + __func__, ret); + goto done; + } + + /* Enable CPAR */ + wcd_cntl_cpar_ctrl(cntl, true); + + if (event == WDSP_EVENT_PRE_DLOAD_CODE) + wcd_cntl_enable_memory(cntl, WCD_MEM_TYPE_ALWAYS_ON); + else if (event == WDSP_EVENT_PRE_DLOAD_DATA) + wcd_cntl_enable_memory(cntl, WCD_MEM_TYPE_SWITCHABLE); + break; + + case WDSP_EVENT_DO_BOOT: + + ret = wcd_cntl_do_boot(cntl); + if (ret < 0) + dev_err(codec->dev, + "%s: WDSP boot failed, err = %d\n", + __func__, ret); + break; + + case WDSP_EVENT_DO_SHUTDOWN: + + wcd_cntl_do_shutdown(cntl); + wcd_cntl_disable_memory(cntl, WCD_MEM_TYPE_SWITCHABLE); + break; + + default: + dev_dbg(codec->dev, "%s: unhandled event %d\n", + __func__, event); + } + +done: + return ret; +} + +static int wcd_cntl_sysfs_init(char *dir, struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + int ret = 0; + + ret = kobject_init_and_add(&cntl->wcd_kobj, &wcd_cntl_ktype, + kernel_kobj, dir); + if (ret < 0) { + dev_err(codec->dev, + "%s: Failed to add kobject %s, err = %d\n", + __func__, dir, ret); + goto done; + } + + ret = sysfs_create_file(&cntl->wcd_kobj, &cntl_attr_boot.attr); + if (ret < 0) { + dev_err(codec->dev, + "%s: Failed to add wdsp_boot sysfs entry to %s\n", + __func__, dir); + goto fail_create_file; + } + + return ret; + +fail_create_file: + kobject_put(&cntl->wcd_kobj); +done: + return ret; +} + +static void wcd_cntl_sysfs_remove(struct wcd_dsp_cntl *cntl) +{ + sysfs_remove_file(&cntl->wcd_kobj, &cntl_attr_boot.attr); + kobject_put(&cntl->wcd_kobj); +} + +static void wcd_cntl_debugfs_init(char *dir, struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + + cntl->entry = debugfs_create_dir(dir, NULL); + if (IS_ERR_OR_NULL(dir)) { + dev_err(codec->dev, "%s debugfs_create_dir failed for %s\n", + __func__, dir); + goto done; + } + + debugfs_create_u32("debug_mode", 0644, + cntl->entry, &cntl->debug_mode); + debugfs_create_bool("ramdump_enable", 0644, + cntl->entry, &cntl->ramdump_enable); +done: + return; +} + +static void wcd_cntl_debugfs_remove(struct wcd_dsp_cntl *cntl) +{ + if (cntl) + debugfs_remove(cntl->entry); +} + +static int wcd_miscdev_release(struct inode *inode, struct file *filep) +{ + struct wcd_dsp_cntl *cntl = container_of(filep->private_data, + struct wcd_dsp_cntl, miscdev); + if (!cntl->m_dev || !cntl->m_ops || + !cntl->m_ops->vote_for_dsp) { + dev_err(cntl->codec->dev, + "%s: DSP not ready to boot\n", __func__); + return -EINVAL; + } + + /* Make sure the DSP users goes to zero upon closing dev node */ + while (cntl->boot_reqs > 0) { + cntl->m_ops->vote_for_dsp(cntl->m_dev, false); + cntl->boot_reqs--; + } + + return 0; +} + +static ssize_t wcd_miscdev_write(struct file *filep, const char __user *ubuf, + size_t count, loff_t *pos) +{ + struct wcd_dsp_cntl *cntl = container_of(filep->private_data, + struct wcd_dsp_cntl, miscdev); + char val[count]; + bool vote; + int ret = 0; + + if (count == 0 || count > 2) { + pr_err("%s: Invalid count = %zd\n", __func__, count); + ret = -EINVAL; + goto done; + } + + ret = copy_from_user(val, ubuf, count); + if (ret < 0) { + dev_err(cntl->codec->dev, + "%s: copy_from_user failed, err = %d\n", + __func__, ret); + ret = -EFAULT; + goto done; + } + + if (val[0] == '1') { + cntl->boot_reqs++; + vote = true; + } else if (val[0] == '0') { + if (cntl->boot_reqs == 0) { + dev_err(cntl->codec->dev, + "%s: WDSP already disabled\n", __func__); + ret = -EINVAL; + goto done; + } + cntl->boot_reqs--; + vote = false; + } else { + dev_err(cntl->codec->dev, "%s: Invalid value %s\n", + __func__, val); + ret = -EINVAL; + goto done; + } + + dev_dbg(cntl->codec->dev, + "%s: booted = %s, ref_cnt = %d, vote = %s\n", + __func__, cntl->is_wdsp_booted ? "true" : "false", + cntl->boot_reqs, vote ? "true" : "false"); + + if (cntl->m_dev && cntl->m_ops && + cntl->m_ops->vote_for_dsp) + ret = cntl->m_ops->vote_for_dsp(cntl->m_dev, vote); + else + ret = -EINVAL; +done: + if (ret) + return ret; + else + return count; +} + +static const struct file_operations wcd_miscdev_fops = { + .write = wcd_miscdev_write, + .release = wcd_miscdev_release, +}; + +static int wcd_cntl_miscdev_create(struct wcd_dsp_cntl *cntl) +{ + snprintf(cntl->miscdev_name, ARRAY_SIZE(cntl->miscdev_name), + "wcd_dsp%u_control", cntl->dsp_instance); + cntl->miscdev.minor = MISC_DYNAMIC_MINOR; + cntl->miscdev.name = cntl->miscdev_name; + cntl->miscdev.fops = &wcd_miscdev_fops; + cntl->miscdev.parent = cntl->codec->dev; + + return misc_register(&cntl->miscdev); +} + +static void wcd_cntl_miscdev_destroy(struct wcd_dsp_cntl *cntl) +{ + misc_deregister(&cntl->miscdev); +} + +static int wcd_control_init(struct device *dev, void *priv_data) +{ + struct wcd_dsp_cntl *cntl = priv_data; + struct snd_soc_codec *codec = cntl->codec; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; + int ret; + bool err_irq_requested = false; + + ret = wcd9xxx_request_irq(core_res, + cntl->irqs.cpe_ipc1_irq, + wcd_cntl_ipc_irq, "CPE IPC1", + cntl); + if (ret < 0) { + dev_err(codec->dev, + "%s: Failed to request cpe ipc irq, err = %d\n", + __func__, ret); + goto done; + } + + /* Unmask the fatal irqs */ + snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, + ~(cntl->irqs.fatal_irqs & 0xFF)); + snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, + ~((cntl->irqs.fatal_irqs >> 8) & 0xFF)); + + /* + * CPE ERR irq is used only for error reporting from WCD DSP, + * even if this request fails, DSP can be function normally. + * Continuing with init even if the CPE ERR irq request fails. + */ + if (wcd9xxx_request_irq(core_res, cntl->irqs.cpe_err_irq, + wcd_cntl_err_irq, "CPE ERR", cntl)) + dev_info(codec->dev, "%s: Failed request_irq(cpe_err_irq)", + __func__); + else + err_irq_requested = true; + + + /* Enable all the clocks */ + ret = wcd_cntl_clocks_enable(cntl); + if (ret < 0) { + dev_err(codec->dev, "%s: Failed to enable clocks, err = %d\n", + __func__, ret); + goto err_clk_enable; + } + wcd_cntl_cpar_ctrl(cntl, true); + + return 0; + +err_clk_enable: + /* Mask all error interrupts */ + snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, 0xFF); + snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, 0xFF); + + /* Free the irq's requested */ + wcd9xxx_free_irq(core_res, cntl->irqs.cpe_ipc1_irq, cntl); + + if (err_irq_requested) + wcd9xxx_free_irq(core_res, cntl->irqs.cpe_err_irq, cntl); +done: + return ret; +} + +static int wcd_control_deinit(struct device *dev, void *priv_data) +{ + struct wcd_dsp_cntl *cntl = priv_data; + struct snd_soc_codec *codec = cntl->codec; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; + + wcd_cntl_clocks_disable(cntl); + wcd_cntl_cpar_ctrl(cntl, false); + + /* Mask all error interrupts */ + snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, 0xFF); + snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, 0xFF); + + /* Free the irq's requested */ + wcd9xxx_free_irq(core_res, cntl->irqs.cpe_err_irq, cntl); + wcd9xxx_free_irq(core_res, cntl->irqs.cpe_ipc1_irq, cntl); + + return 0; +} + +static struct wdsp_cmpnt_ops control_ops = { + .init = wcd_control_init, + .deinit = wcd_control_deinit, + .event_handler = wcd_control_handler, +}; + +static int wcd_ctrl_component_bind(struct device *dev, + struct device *master, + void *data) +{ + struct wcd_dsp_cntl *cntl; + struct snd_soc_codec *codec; + struct snd_card *card; + struct snd_info_entry *entry; + char proc_name[WCD_PROCFS_ENTRY_MAX_LEN]; + char wcd_cntl_dir_name[WCD_CNTL_DIR_NAME_LEN_MAX]; + int ret = 0; + + if (!dev || !master || !data) { + pr_err("%s: Invalid parameters\n", __func__); + return -EINVAL; + } + + cntl = tavil_get_wcd_dsp_cntl(dev); + if (!cntl) { + dev_err(dev, "%s: Failed to get cntl reference\n", + __func__); + return -EINVAL; + } + + cntl->m_dev = master; + cntl->m_ops = data; + + if (!cntl->m_ops->register_cmpnt_ops) { + dev_err(dev, "%s: invalid master callback register_cmpnt_ops\n", + __func__); + ret = -EINVAL; + goto done; + } + + ret = cntl->m_ops->register_cmpnt_ops(master, dev, cntl, &control_ops); + if (ret) { + dev_err(dev, "%s: register_cmpnt_ops failed, err = %d\n", + __func__, ret); + goto done; + } + + ret = wcd_cntl_miscdev_create(cntl); + if (ret < 0) { + dev_err(dev, "%s: misc dev register failed, err = %d\n", + __func__, ret); + goto done; + } + + snprintf(wcd_cntl_dir_name, WCD_CNTL_DIR_NAME_LEN_MAX, + "%s%d", "wdsp", cntl->dsp_instance); + ret = wcd_cntl_sysfs_init(wcd_cntl_dir_name, cntl); + if (ret < 0) { + dev_err(dev, "%s: sysfs_init failed, err = %d\n", + __func__, ret); + goto err_sysfs_init; + } + + wcd_cntl_debugfs_init(wcd_cntl_dir_name, cntl); + + codec = cntl->codec; + card = codec->component.card->snd_card; + snprintf(proc_name, WCD_PROCFS_ENTRY_MAX_LEN, "%s%d%s", "cpe", + cntl->dsp_instance, "_state"); + entry = snd_info_create_card_entry(card, proc_name, card->proc_root); + if (!entry) { + /* Do not treat this as Fatal error */ + dev_err(dev, "%s: Failed to create procfs entry %s\n", + __func__, proc_name); + goto err_sysfs_init; + } + + cntl->ssr_entry.entry = entry; + cntl->ssr_entry.offline = 1; + entry->size = WCD_PROCFS_ENTRY_MAX_LEN; + entry->content = SNDRV_INFO_CONTENT_DATA; + entry->c.ops = &wdsp_ssr_entry_ops; + entry->private_data = cntl; + ret = snd_info_register(entry); + if (ret < 0) { + dev_err(dev, "%s: Failed to register entry %s, err = %d\n", + __func__, proc_name, ret); + snd_info_free_entry(entry); + /* Let bind still happen even if creating the entry failed */ + ret = 0; + } +done: + return ret; + +err_sysfs_init: + wcd_cntl_miscdev_destroy(cntl); + return ret; +} + +static void wcd_ctrl_component_unbind(struct device *dev, + struct device *master, + void *data) +{ + struct wcd_dsp_cntl *cntl; + + if (!dev) { + pr_err("%s: Invalid device\n", __func__); + return; + } + + cntl = tavil_get_wcd_dsp_cntl(dev); + if (!cntl) { + dev_err(dev, "%s: Failed to get cntl reference\n", + __func__); + return; + } + + cntl->m_dev = NULL; + cntl->m_ops = NULL; + + /* Remove the sysfs entries */ + wcd_cntl_sysfs_remove(cntl); + + /* Remove the debugfs entries */ + wcd_cntl_debugfs_remove(cntl); + + /* Remove the misc device */ + wcd_cntl_miscdev_destroy(cntl); +} + +static const struct component_ops wcd_ctrl_component_ops = { + .bind = wcd_ctrl_component_bind, + .unbind = wcd_ctrl_component_unbind, +}; + +/* + * wcd_dsp_ssr_event: handle the SSR event raised by caller. + * @cntl: Handle to the wcd_dsp_cntl structure + * @event: The SSR event to be handled + * + * Notifies the manager driver about the SSR event. + * Returns 0 on success and negative error code on error. + */ +int wcd_dsp_ssr_event(struct wcd_dsp_cntl *cntl, enum cdc_ssr_event event) +{ + int ret = 0; + + if (!cntl) { + pr_err("%s: Invalid handle to control\n", __func__); + return -EINVAL; + } + + if (!cntl->m_dev || !cntl->m_ops || !cntl->m_ops->signal_handler) { + dev_err(cntl->codec->dev, + "%s: Invalid signal_handler callback\n", __func__); + return -EINVAL; + } + + switch (event) { + case WCD_CDC_DOWN_EVENT: + ret = cntl->m_ops->signal_handler(cntl->m_dev, + WDSP_CDC_DOWN_SIGNAL, + NULL); + if (ret < 0) + dev_err(cntl->codec->dev, + "%s: WDSP_CDC_DOWN_SIGNAL failed, err = %d\n", + __func__, ret); + wcd_cntl_change_online_state(cntl, 0); + break; + case WCD_CDC_UP_EVENT: + ret = cntl->m_ops->signal_handler(cntl->m_dev, + WDSP_CDC_UP_SIGNAL, + NULL); + if (ret < 0) + dev_err(cntl->codec->dev, + "%s: WDSP_CDC_UP_SIGNAL failed, err = %d\n", + __func__, ret); + break; + default: + dev_err(cntl->codec->dev, "%s: Invalid event %d\n", + __func__, event); + ret = -EINVAL; + break; + } + + return ret; +} +EXPORT_SYMBOL(wcd_dsp_ssr_event); + +/* + * wcd_dsp_cntl_init: Initialize the wcd-dsp control + * @codec: pointer to the codec handle + * @params: Parameters required to initialize wcd-dsp control + * + * This API is expected to be invoked by the codec driver and + * provide information essential for the wcd dsp control to + * configure and initialize the dsp + */ +void wcd_dsp_cntl_init(struct snd_soc_codec *codec, + struct wcd_dsp_params *params, + struct wcd_dsp_cntl **cntl) +{ + struct wcd_dsp_cntl *control; + int ret; + + if (!codec || !params) { + pr_err("%s: Invalid handle to %s\n", __func__, + (!codec) ? "codec" : "params"); + *cntl = NULL; + return; + } + + if (*cntl) { + pr_err("%s: cntl is non NULL, maybe already initialized ?\n", + __func__); + return; + } + + if (!params->cb || !params->cb->cdc_clk_en || + !params->cb->cdc_vote_svs) { + dev_err(codec->dev, + "%s: clk_en and vote_svs callbacks must be provided\n", + __func__); + return; + } + + control = kzalloc(sizeof(*control), GFP_KERNEL); + if (!(control)) + return; + + control->codec = codec; + control->clk_rate = params->clk_rate; + control->cdc_cb = params->cb; + control->dsp_instance = params->dsp_instance; + memcpy(&control->irqs, ¶ms->irqs, sizeof(control->irqs)); + init_completion(&control->boot_complete); + mutex_init(&control->clk_mutex); + mutex_init(&control->ssr_mutex); + init_waitqueue_head(&control->ssr_entry.offline_poll_wait); + + /* + * The default state of WDSP is in SVS mode. + * Vote for SVS now, the vote will be removed only + * after DSP is booted up. + */ + control->cdc_cb->cdc_vote_svs(codec, true); + + /* + * If this is the last component needed by master to be ready, + * then component_bind will be called within the component_add. + * Hence, the data pointer should be assigned before component_add, + * so that we can access it during this component's bind call. + */ + *cntl = control; + ret = component_add(codec->dev, &wcd_ctrl_component_ops); + if (ret) { + dev_err(codec->dev, "%s: component_add failed, err = %d\n", + __func__, ret); + kfree(*cntl); + *cntl = NULL; + } +} +EXPORT_SYMBOL(wcd_dsp_cntl_init); + +/* + * wcd_dsp_cntl_deinit: De-initialize the wcd-dsp control + * @cntl: The struct wcd_dsp_cntl to de-initialize + * + * This API is intended to be invoked by the codec driver + * to de-initialize the wcd dsp control + */ +void wcd_dsp_cntl_deinit(struct wcd_dsp_cntl **cntl) +{ + struct wcd_dsp_cntl *control = *cntl; + struct snd_soc_codec *codec; + + /* If control is NULL, there is nothing to de-initialize */ + if (!control) + return; + codec = control->codec; + + /* + * Calling shutdown will cleanup all register states, + * irrespective of DSP was booted up or not. + */ + wcd_cntl_do_shutdown(control); + wcd_cntl_disable_memory(control, WCD_MEM_TYPE_SWITCHABLE); + wcd_cntl_disable_memory(control, WCD_MEM_TYPE_ALWAYS_ON); + + component_del(codec->dev, &wcd_ctrl_component_ops); + + mutex_destroy(&control->clk_mutex); + mutex_destroy(&control->ssr_mutex); + kfree(*cntl); + *cntl = NULL; +} +EXPORT_SYMBOL(wcd_dsp_cntl_deinit); diff --git a/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.h b/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.h new file mode 100644 index 000000000000..e934638cc487 --- /dev/null +++ b/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __WCD934X_DSP_CNTL_H__ +#define __WCD934X_DSP_CNTL_H__ + +#include +#include + +enum cdc_ssr_event { + WCD_CDC_DOWN_EVENT, + WCD_CDC_UP_EVENT, +}; + +struct wcd_dsp_cdc_cb { + /* Callback to enable codec clock */ + int (*cdc_clk_en)(struct snd_soc_codec *, bool); + /* Callback to vote and unvote for SVS2 mode */ + void (*cdc_vote_svs)(struct snd_soc_codec *, bool); +}; + +struct wcd_dsp_irq_info { + /* IPC interrupt */ + int cpe_ipc1_irq; + + /* CPE error summary interrupt */ + int cpe_err_irq; + + /* + * Bit mask to indicate which of the + * error interrupts are to be considered + * as fatal. + */ + u16 fatal_irqs; +}; + +struct wcd_dsp_params { + struct wcd_dsp_cdc_cb *cb; + struct wcd_dsp_irq_info irqs; + + /* Rate at which the codec clock operates */ + u32 clk_rate; + + /* + * Represents the dsp instance, will be used + * to create sysfs and debugfs entries with + * directory wdsp + */ + u32 dsp_instance; +}; + +struct wdsp_ssr_entry { + u8 offline; + u8 offline_change; + wait_queue_head_t offline_poll_wait; + struct snd_info_entry *entry; +}; + +struct wcd_dsp_cntl { + /* Handle to codec */ + struct snd_soc_codec *codec; + + /* Clk rate of the codec clock */ + u32 clk_rate; + + /* Callbacks to codec driver */ + const struct wcd_dsp_cdc_cb *cdc_cb; + + /* Completion to indicate WDSP boot done */ + struct completion boot_complete; + + struct wcd_dsp_irq_info irqs; + u32 dsp_instance; + + /* Sysfs entries related */ + int boot_reqs; + struct kobject wcd_kobj; + + /* Debugfs related */ + struct dentry *entry; + u32 debug_mode; + bool ramdump_enable; + + /* WDSP manager drivers data */ + struct device *m_dev; + struct wdsp_mgr_ops *m_ops; + + /* clk related */ + struct mutex clk_mutex; + bool is_clk_enabled; + + /* Keep track of WDSP boot status */ + bool is_wdsp_booted; + + /* SSR related */ + struct wdsp_ssr_entry ssr_entry; + struct mutex ssr_mutex; + + /* Misc device related */ + char miscdev_name[256]; + struct miscdevice miscdev; +}; + +void wcd_dsp_cntl_init(struct snd_soc_codec *codec, + struct wcd_dsp_params *params, + struct wcd_dsp_cntl **cntl); +void wcd_dsp_cntl_deinit(struct wcd_dsp_cntl **cntl); +int wcd_dsp_ssr_event(struct wcd_dsp_cntl *cntl, enum cdc_ssr_event event); +#endif /* end __WCD_DSP_CONTROL_H__ */ diff --git a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c b/sound/soc/codecs/wcd934x/wcd934x-mbhc.c new file mode 100644 index 000000000000..a1a5e2d65062 --- /dev/null +++ b/sound/soc/codecs/wcd934x/wcd934x-mbhc.c @@ -0,0 +1,1098 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcd934x.h" +#include "wcd934x-mbhc.h" +#include "../wcdcal-hwdep.h" +#include "../wcd-mbhc-v2-api.h" + +#define TAVIL_ZDET_SUPPORTED true +/* Z value defined in milliohm */ +#define TAVIL_ZDET_VAL_32 32000 +#define TAVIL_ZDET_VAL_400 400000 +#define TAVIL_ZDET_VAL_1200 1200000 +#define TAVIL_ZDET_VAL_100K 100000000 +/* Z floating defined in ohms */ +#define TAVIL_ZDET_FLOATING_IMPEDANCE 0x0FFFFFFE + +#define TAVIL_ZDET_NUM_MEASUREMENTS 150 +#define TAVIL_MBHC_GET_C1(c) ((c & 0xC000) >> 14) +#define TAVIL_MBHC_GET_X1(x) (x & 0x3FFF) +/* Z value compared in milliOhm */ +#define TAVIL_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000)) +#define TAVIL_MBHC_ZDET_CONST (86 * 16384) +#define TAVIL_MBHC_MOISTURE_RREF R_24_KOHM + +static struct wcd_mbhc_register + wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = { + WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN", + WCD934X_ANA_MBHC_MECH, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_DET_EN", + WCD934X_ANA_MBHC_MECH, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MECH_DETECTION_TYPE", + WCD934X_ANA_MBHC_MECH, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_CLAMP_CTL", + WCD934X_MBHC_NEW_PLUG_DETECT_CTL, 0x30, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_DETECTION_TYPE", + WCD934X_ANA_MBHC_ELECT, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_CTRL", + WCD934X_MBHC_NEW_PLUG_DETECT_CTL, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL", + WCD934X_ANA_MBHC_MECH, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PLUG_TYPE", + WCD934X_ANA_MBHC_MECH, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_PLUG_TYPE", + WCD934X_ANA_MBHC_MECH, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SW_HPH_LP_100K_TO_GND", + WCD934X_ANA_MBHC_MECH, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_SCHMT_ISRC", + WCD934X_ANA_MBHC_ELECT, 0x06, 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_EN", + WCD934X_ANA_MBHC_ELECT, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_INSREM_DBNC", + WCD934X_MBHC_NEW_PLUG_DETECT_CTL, 0x0F, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_DBNC", + WCD934X_MBHC_NEW_CTL_1, 0x03, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_VREF", + WCD934X_MBHC_NEW_CTL_2, 0x03, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT", + WCD934X_ANA_MBHC_RESULT_3, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT", + WCD934X_ANA_MBHC_RESULT_3, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT", + WCD934X_ANA_MBHC_RESULT_3, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_SCHMT_RESULT", + WCD934X_ANA_MBHC_RESULT_3, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_OCP_FSM_EN", + WCD934X_HPH_OCP_CTL, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_RESULT", + WCD934X_ANA_MBHC_RESULT_3, 0x07, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_ISRC_CTL", + WCD934X_ANA_MBHC_ELECT, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT", + WCD934X_ANA_MBHC_RESULT_3, 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL", + WCD934X_ANA_MICB2, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME", + WCD934X_HPH_CNP_WG_TIME, 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN", + WCD934X_ANA_HPH, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PA_EN", + WCD934X_ANA_HPH, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_PA_EN", + WCD934X_ANA_HPH, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE", + WCD934X_ANA_MBHC_RESULT_3, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL", + 0, 0, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN", + WCD934X_MBHC_CTL_BCS, 0x02, 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_STATUS", + WCD934X_MBHC_STATUS_SPARE_1, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL", + WCD934X_MBHC_NEW_CTL_2, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_DET_EN", + WCD934X_HPH_L_TEST, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_DET_EN", + WCD934X_HPH_R_TEST, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_STATUS", + WCD934X_INTR_PIN1_STATUS0, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_STATUS", + WCD934X_INTR_PIN1_STATUS0, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_EN", + WCD934X_MBHC_NEW_CTL_1, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_COMPLETE", WCD934X_MBHC_NEW_FSM_STATUS, + 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_TIMEOUT", WCD934X_MBHC_NEW_FSM_STATUS, + 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_RESULT", WCD934X_MBHC_NEW_ADC_RESULT, + 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB2_VOUT", WCD934X_ANA_MICB2, 0x3F, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_MODE", + WCD934X_MBHC_NEW_CTL_1, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_DETECTION_DONE", + WCD934X_MBHC_NEW_CTL_1, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_ISRC_EN", + WCD934X_ANA_MBHC_ZDET, 0x02, 1, 0), +}; + +static const struct wcd_mbhc_intr intr_ids = { + .mbhc_sw_intr = WCD934X_IRQ_MBHC_SW_DET, + .mbhc_btn_press_intr = WCD934X_IRQ_MBHC_BUTTON_PRESS_DET, + .mbhc_btn_release_intr = WCD934X_IRQ_MBHC_BUTTON_RELEASE_DET, + .mbhc_hs_ins_intr = WCD934X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, + .mbhc_hs_rem_intr = WCD934X_IRQ_MBHC_ELECT_INS_REM_DET, + .hph_left_ocp = WCD934X_IRQ_HPH_PA_OCPL_FAULT, + .hph_right_ocp = WCD934X_IRQ_HPH_PA_OCPR_FAULT, +}; + + +static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = { + "cdc-vdd-mic-bias", +}; + +struct tavil_mbhc_zdet_param { + u16 ldo_ctl; + u16 noff; + u16 nshift; + u16 btn5; + u16 btn6; + u16 btn7; +}; + +static int tavil_mbhc_request_irq(struct snd_soc_codec *codec, + int irq, irq_handler_t handler, + const char *name, void *data) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + + return wcd9xxx_request_irq(core_res, irq, handler, name, data); +} + +static void tavil_mbhc_irq_control(struct snd_soc_codec *codec, + int irq, bool enable) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + if (enable) + wcd9xxx_enable_irq(core_res, irq); + else + wcd9xxx_disable_irq(core_res, irq); +} + +static int tavil_mbhc_free_irq(struct snd_soc_codec *codec, + int irq, void *data) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + + wcd9xxx_free_irq(core_res, irq, data); + return 0; +} + +static void tavil_mbhc_clk_setup(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) + snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_1, + 0x80, 0x80); + else + snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_1, + 0x80, 0x00); +} + +static int tavil_mbhc_btn_to_num(struct snd_soc_codec *codec) +{ + return snd_soc_read(codec, WCD934X_ANA_MBHC_RESULT_3) & 0x7; +} + +static int tavil_enable_ext_mb_source(struct wcd_mbhc *mbhc, + bool turn_on) +{ + struct wcd934x_mbhc *wcd934x_mbhc; + struct snd_soc_codec *codec = mbhc->codec; + struct wcd934x_on_demand_supply *supply; + int ret = 0; + + wcd934x_mbhc = container_of(mbhc, struct wcd934x_mbhc, wcd_mbhc); + + supply = &wcd934x_mbhc->on_demand_list[WCD934X_ON_DEMAND_MICBIAS]; + if (!supply->supply) { + dev_dbg(codec->dev, "%s: warning supply not present ond for %s\n", + __func__, "onDemand Micbias"); + return ret; + } + + dev_dbg(codec->dev, "%s turn_on: %d count: %d\n", __func__, turn_on, + supply->ondemand_supply_count); + + if (turn_on) { + if (!(supply->ondemand_supply_count)) { + ret = snd_soc_dapm_force_enable_pin( + snd_soc_codec_get_dapm(codec), + "MICBIAS_REGULATOR"); + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + } + supply->ondemand_supply_count++; + } else { + if (supply->ondemand_supply_count > 0) + supply->ondemand_supply_count--; + if (!(supply->ondemand_supply_count)) { + ret = snd_soc_dapm_disable_pin( + snd_soc_codec_get_dapm(codec), + "MICBIAS_REGULATOR"); + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + } + } + + if (ret) + dev_err(codec->dev, "%s: Failed to %s external micbias source\n", + __func__, turn_on ? "enable" : "disabled"); + else + dev_dbg(codec->dev, "%s: %s external micbias source\n", + __func__, turn_on ? "Enabled" : "Disabled"); + + return ret; +} + +static void tavil_mbhc_mbhc_bias_control(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) + snd_soc_update_bits(codec, WCD934X_ANA_MBHC_ELECT, + 0x01, 0x01); + else + snd_soc_update_bits(codec, WCD934X_ANA_MBHC_ELECT, + 0x01, 0x00); +} + +static void tavil_mbhc_program_btn_thr(struct snd_soc_codec *codec, + s16 *btn_low, s16 *btn_high, + int num_btn, bool is_micbias) +{ + int i; + int vth; + + if (num_btn > WCD_MBHC_DEF_BUTTONS) { + dev_err(codec->dev, "%s: invalid number of buttons: %d\n", + __func__, num_btn); + return; + } + /* + * Tavil just needs one set of thresholds for button detection + * due to micbias voltage ramp to pullup upon button press. So + * btn_low and is_micbias are ignored and always program button + * thresholds using btn_high. + */ + for (i = 0; i < num_btn; i++) { + vth = ((btn_high[i] * 2) / 25) & 0x3F; + snd_soc_update_bits(codec, WCD934X_ANA_MBHC_BTN0 + i, + 0xFC, vth << 2); + dev_dbg(codec->dev, "%s: btn_high[%d]: %d, vth: %d\n", + __func__, i, btn_high[i], vth); + } +} + +static bool tavil_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock) +{ + struct snd_soc_codec *codec = mbhc->codec; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + bool ret = 0; + + if (lock) + ret = wcd9xxx_lock_sleep(core_res); + else + wcd9xxx_unlock_sleep(core_res); + + return ret; +} + +static int tavil_mbhc_register_notifier(struct wcd_mbhc *mbhc, + struct notifier_block *nblock, + bool enable) +{ + struct wcd934x_mbhc *wcd934x_mbhc; + + wcd934x_mbhc = container_of(mbhc, struct wcd934x_mbhc, wcd_mbhc); + + if (enable) + return blocking_notifier_chain_register(&wcd934x_mbhc->notifier, + nblock); + else + return blocking_notifier_chain_unregister( + &wcd934x_mbhc->notifier, nblock); +} + +static bool tavil_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) +{ + u8 val; + + if (micb_num == MIC_BIAS_2) { + val = (snd_soc_read(mbhc->codec, WCD934X_ANA_MICB2) >> 6); + if (val == 0x01) + return true; + } + return false; +} + +static bool tavil_mbhc_hph_pa_on_status(struct snd_soc_codec *codec) +{ + return (snd_soc_read(codec, WCD934X_ANA_HPH) & 0xC0) ? true : false; +} + +static void tavil_mbhc_hph_l_pull_up_control( + struct snd_soc_codec *codec, + enum mbhc_hs_pullup_iref pull_up_cur) +{ + /* Default pull up current to 2uA */ + if (pull_up_cur < I_OFF || pull_up_cur > I_3P0_UA || + pull_up_cur == I_DEFAULT) + pull_up_cur = I_2P0_UA; + + dev_dbg(codec->dev, "%s: HS pull up current:%d\n", + __func__, pull_up_cur); + + snd_soc_update_bits(codec, WCD934X_MBHC_NEW_PLUG_DETECT_CTL, + 0xC0, pull_up_cur << 6); +} + +static int tavil_mbhc_request_micbias(struct snd_soc_codec *codec, + int micb_num, int req) +{ + int ret; + + /* + * If micbias is requested, make sure that there + * is vote to enable mclk + */ + if (req == MICB_ENABLE) + tavil_cdc_mclk_enable(codec, true); + + ret = tavil_micbias_control(codec, micb_num, req, false); + + /* + * Release vote for mclk while requesting for + * micbias disable + */ + if (req == MICB_DISABLE) + tavil_cdc_mclk_enable(codec, false); + + return ret; +} + +static void tavil_mbhc_micb_ramp_control(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, WCD934X_ANA_MICB2_RAMP, + 0x1C, 0x0C); + snd_soc_update_bits(codec, WCD934X_ANA_MICB2_RAMP, + 0x80, 0x80); + } else { + snd_soc_update_bits(codec, WCD934X_ANA_MICB2_RAMP, + 0x80, 0x00); + snd_soc_update_bits(codec, WCD934X_ANA_MICB2_RAMP, + 0x1C, 0x00); + } +} + +static struct firmware_cal *tavil_get_hwdep_fw_cal(struct wcd_mbhc *mbhc, + enum wcd_cal_type type) +{ + struct wcd934x_mbhc *wcd934x_mbhc; + struct firmware_cal *hwdep_cal; + struct snd_soc_codec *codec = mbhc->codec; + + wcd934x_mbhc = container_of(mbhc, struct wcd934x_mbhc, wcd_mbhc); + + if (!codec) { + pr_err("%s: NULL codec pointer\n", __func__); + return NULL; + } + hwdep_cal = wcdcal_get_fw_cal(wcd934x_mbhc->fw_data, type); + if (!hwdep_cal) + dev_err(codec->dev, "%s: cal not sent by %d\n", + __func__, type); + + return hwdep_cal; +} + +static int tavil_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec, + int micb_num, bool req_en) +{ + struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + int rc, micb_mv; + + if (micb_num != MIC_BIAS_2) + return -EINVAL; + + /* + * If device tree micbias level is already above the minimum + * voltage needed to detect threshold microphone, then do + * not change the micbias, just return. + */ + if (pdata->micbias.micb2_mv >= WCD_MBHC_THR_HS_MICB_MV) + return 0; + + micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb2_mv; + + rc = tavil_mbhc_micb_adjust_voltage(codec, micb_mv, MIC_BIAS_2); + + return rc; +} + +static inline void tavil_mbhc_get_result_params(struct wcd9xxx *wcd9xxx, + s16 *d1_a, u16 noff, + int32_t *zdet) +{ + int i; + int val, val1; + s16 c1; + s32 x1, d1; + int32_t denom; + int minCode_param[] = { + 3277, 1639, 820, 410, 205, 103, 52, 26 + }; + + regmap_update_bits(wcd9xxx->regmap, WCD934X_ANA_MBHC_ZDET, 0x20, 0x20); + for (i = 0; i < TAVIL_ZDET_NUM_MEASUREMENTS; i++) { + regmap_read(wcd9xxx->regmap, WCD934X_ANA_MBHC_RESULT_2, &val); + if (val & 0x80) + break; + } + val = val << 0x8; + regmap_read(wcd9xxx->regmap, WCD934X_ANA_MBHC_RESULT_1, &val1); + val |= val1; + regmap_update_bits(wcd9xxx->regmap, WCD934X_ANA_MBHC_ZDET, 0x20, 0x00); + x1 = TAVIL_MBHC_GET_X1(val); + c1 = TAVIL_MBHC_GET_C1(val); + /* If ramp is not complete, give additional 5ms */ + if ((c1 < 2) && x1) + usleep_range(5000, 5050); + + if (!c1 || !x1) { + dev_dbg(wcd9xxx->dev, + "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n", + __func__, c1, x1); + goto ramp_down; + } + d1 = d1_a[c1]; + denom = (x1 * d1) - (1 << (14 - noff)); + if (denom > 0) + *zdet = (TAVIL_MBHC_ZDET_CONST * 1000) / denom; + else if (x1 < minCode_param[noff]) + *zdet = TAVIL_ZDET_FLOATING_IMPEDANCE; + + dev_dbg(wcd9xxx->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n", + __func__, d1, c1, x1, *zdet); +ramp_down: + i = 0; + while (x1) { + regmap_bulk_read(wcd9xxx->regmap, + WCD934X_ANA_MBHC_RESULT_1, (u8 *)&val, 2); + x1 = TAVIL_MBHC_GET_X1(val); + i++; + if (i == TAVIL_ZDET_NUM_MEASUREMENTS) + break; + } +} + +static void tavil_mbhc_zdet_ramp(struct snd_soc_codec *codec, + struct tavil_mbhc_zdet_param *zdet_param, + int32_t *zl, int32_t *zr, s16 *d1_a) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + int32_t zdet = 0; + + snd_soc_update_bits(codec, WCD934X_MBHC_NEW_ZDET_ANA_CTL, 0x70, + zdet_param->ldo_ctl << 4); + snd_soc_update_bits(codec, WCD934X_ANA_MBHC_BTN5, 0xFC, + zdet_param->btn5); + snd_soc_update_bits(codec, WCD934X_ANA_MBHC_BTN6, 0xFC, + zdet_param->btn6); + snd_soc_update_bits(codec, WCD934X_ANA_MBHC_BTN7, 0xFC, + zdet_param->btn7); + snd_soc_update_bits(codec, WCD934X_MBHC_NEW_ZDET_ANA_CTL, 0x0F, + zdet_param->noff); + snd_soc_update_bits(codec, WCD934X_MBHC_NEW_ZDET_RAMP_CTL, 0x0F, + zdet_param->nshift); + + if (!zl) + goto z_right; + /* Start impedance measurement for HPH_L */ + regmap_update_bits(wcd9xxx->regmap, + WCD934X_ANA_MBHC_ZDET, 0x80, 0x80); + dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_L, noff = %d\n", + __func__, zdet_param->noff); + tavil_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet); + regmap_update_bits(wcd9xxx->regmap, + WCD934X_ANA_MBHC_ZDET, 0x80, 0x00); + + *zl = zdet; + +z_right: + if (!zr) + return; + /* Start impedance measurement for HPH_R */ + regmap_update_bits(wcd9xxx->regmap, + WCD934X_ANA_MBHC_ZDET, 0x40, 0x40); + dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_R, noff = %d\n", + __func__, zdet_param->noff); + tavil_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet); + regmap_update_bits(wcd9xxx->regmap, + WCD934X_ANA_MBHC_ZDET, 0x40, 0x00); + + *zr = zdet; +} + +static inline void tavil_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec, + int32_t *z_val, int flag_l_r) +{ + s16 q1; + int q1_cal; + + if (*z_val < (TAVIL_ZDET_VAL_400/1000)) + q1 = snd_soc_read(codec, + WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT1 + (2 * flag_l_r)); + else + q1 = snd_soc_read(codec, + WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT2 + (2 * flag_l_r)); + if (q1 & 0x80) + q1_cal = (10000 - ((q1 & 0x7F) * 25)); + else + q1_cal = (10000 + (q1 * 25)); + if (q1_cal > 0) + *z_val = ((*z_val) * 10000) / q1_cal; +} + +static void tavil_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, + uint32_t *zr) +{ + struct snd_soc_codec *codec = mbhc->codec; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + s16 reg0, reg1, reg2, reg3, reg4; + int32_t z1L, z1R, z1Ls; + int zMono, z_diff1, z_diff2; + bool is_fsm_disable = false; + struct tavil_mbhc_zdet_param zdet_param[] = { + {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */ + {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */ + {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */ + {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */ + }; + struct tavil_mbhc_zdet_param *zdet_param_ptr = NULL; + s16 d1_a[][4] = { + {0, 30, 90, 30}, + {0, 30, 30, 5}, + {0, 30, 30, 5}, + {0, 30, 30, 5}, + }; + s16 *d1 = NULL; + + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + + reg0 = snd_soc_read(codec, WCD934X_ANA_MBHC_BTN5); + reg1 = snd_soc_read(codec, WCD934X_ANA_MBHC_BTN6); + reg2 = snd_soc_read(codec, WCD934X_ANA_MBHC_BTN7); + reg3 = snd_soc_read(codec, WCD934X_MBHC_CTL_CLK); + reg4 = snd_soc_read(codec, WCD934X_MBHC_NEW_ZDET_ANA_CTL); + + if (snd_soc_read(codec, WCD934X_ANA_MBHC_ELECT) & 0x80) { + is_fsm_disable = true; + regmap_update_bits(wcd9xxx->regmap, + WCD934X_ANA_MBHC_ELECT, 0x80, 0x00); + } + + /* For NO-jack, disable L_DET_EN before Z-det measurements */ + if (mbhc->hphl_swh) + regmap_update_bits(wcd9xxx->regmap, + WCD934X_ANA_MBHC_MECH, 0x80, 0x00); + + /* Turn off 100k pull down on HPHL */ + regmap_update_bits(wcd9xxx->regmap, + WCD934X_ANA_MBHC_MECH, 0x01, 0x00); + + /* First get impedance on Left */ + d1 = d1_a[1]; + zdet_param_ptr = &zdet_param[1]; + tavil_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + + if (!TAVIL_MBHC_IS_SECOND_RAMP_REQUIRED(z1L)) + goto left_ch_impedance; + + /* Second ramp for left ch */ + if (z1L < TAVIL_ZDET_VAL_32) { + zdet_param_ptr = &zdet_param[0]; + d1 = d1_a[0]; + } else if ((z1L > TAVIL_ZDET_VAL_400) && (z1L <= TAVIL_ZDET_VAL_1200)) { + zdet_param_ptr = &zdet_param[2]; + d1 = d1_a[2]; + } else if (z1L > TAVIL_ZDET_VAL_1200) { + zdet_param_ptr = &zdet_param[3]; + d1 = d1_a[3]; + } + tavil_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + +left_ch_impedance: + if ((z1L == TAVIL_ZDET_FLOATING_IMPEDANCE) || + (z1L > TAVIL_ZDET_VAL_100K)) { + *zl = TAVIL_ZDET_FLOATING_IMPEDANCE; + zdet_param_ptr = &zdet_param[1]; + d1 = d1_a[1]; + } else { + *zl = z1L/1000; + tavil_wcd_mbhc_qfuse_cal(codec, zl, 0); + } + dev_dbg(codec->dev, "%s: impedance on HPH_L = %d(ohms)\n", + __func__, *zl); + + /* Start of right impedance ramp and calculation */ + tavil_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + if (TAVIL_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) { + if (((z1R > TAVIL_ZDET_VAL_1200) && + (zdet_param_ptr->noff == 0x6)) || + ((*zl) != TAVIL_ZDET_FLOATING_IMPEDANCE)) + goto right_ch_impedance; + /* Second ramp for right ch */ + if (z1R < TAVIL_ZDET_VAL_32) { + zdet_param_ptr = &zdet_param[0]; + d1 = d1_a[0]; + } else if ((z1R > TAVIL_ZDET_VAL_400) && + (z1R <= TAVIL_ZDET_VAL_1200)) { + zdet_param_ptr = &zdet_param[2]; + d1 = d1_a[2]; + } else if (z1R > TAVIL_ZDET_VAL_1200) { + zdet_param_ptr = &zdet_param[3]; + d1 = d1_a[3]; + } + tavil_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + } +right_ch_impedance: + if ((z1R == TAVIL_ZDET_FLOATING_IMPEDANCE) || + (z1R > TAVIL_ZDET_VAL_100K)) { + *zr = TAVIL_ZDET_FLOATING_IMPEDANCE; + } else { + *zr = z1R/1000; + tavil_wcd_mbhc_qfuse_cal(codec, zr, 1); + } + dev_dbg(codec->dev, "%s: impedance on HPH_R = %d(ohms)\n", + __func__, *zr); + + /* Mono/stereo detection */ + if ((*zl == TAVIL_ZDET_FLOATING_IMPEDANCE) && + (*zr == TAVIL_ZDET_FLOATING_IMPEDANCE)) { + dev_dbg(codec->dev, + "%s: plug type is invalid or extension cable\n", + __func__); + goto zdet_complete; + } + if ((*zl == TAVIL_ZDET_FLOATING_IMPEDANCE) || + (*zr == TAVIL_ZDET_FLOATING_IMPEDANCE) || + ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) || + ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) { + dev_dbg(codec->dev, + "%s: Mono plug type with one ch floating or shorted to GND\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_MONO; + goto zdet_complete; + } + snd_soc_update_bits(codec, WCD934X_HPH_R_ATEST, 0x02, 0x02); + snd_soc_update_bits(codec, WCD934X_HPH_PA_CTL2, 0x40, 0x01); + if (*zl < (TAVIL_ZDET_VAL_32/1000)) + tavil_mbhc_zdet_ramp(codec, &zdet_param[0], &z1Ls, NULL, d1); + else + tavil_mbhc_zdet_ramp(codec, &zdet_param[1], &z1Ls, NULL, d1); + snd_soc_update_bits(codec, WCD934X_HPH_PA_CTL2, 0x40, 0x00); + snd_soc_update_bits(codec, WCD934X_HPH_R_ATEST, 0x02, 0x00); + z1Ls /= 1000; + tavil_wcd_mbhc_qfuse_cal(codec, &z1Ls, 0); + /* Parallel of left Z and 9 ohm pull down resistor */ + zMono = ((*zl) * 9) / ((*zl) + 9); + z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls); + z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl)); + if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) { + dev_dbg(codec->dev, "%s: stereo plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_STEREO; + } else { + dev_dbg(codec->dev, "%s: MONO plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_MONO; + } + +zdet_complete: + snd_soc_write(codec, WCD934X_ANA_MBHC_BTN5, reg0); + snd_soc_write(codec, WCD934X_ANA_MBHC_BTN6, reg1); + snd_soc_write(codec, WCD934X_ANA_MBHC_BTN7, reg2); + /* Turn on 100k pull down on HPHL */ + regmap_update_bits(wcd9xxx->regmap, + WCD934X_ANA_MBHC_MECH, 0x01, 0x01); + + /* For NO-jack, re-enable L_DET_EN after Z-det measurements */ + if (mbhc->hphl_swh) + regmap_update_bits(wcd9xxx->regmap, + WCD934X_ANA_MBHC_MECH, 0x80, 0x80); + + snd_soc_write(codec, WCD934X_MBHC_NEW_ZDET_ANA_CTL, reg4); + snd_soc_write(codec, WCD934X_MBHC_CTL_CLK, reg3); + if (is_fsm_disable) + regmap_update_bits(wcd9xxx->regmap, + WCD934X_ANA_MBHC_ELECT, 0x80, 0x80); +} + +static void tavil_mbhc_gnd_det_ctrl(struct snd_soc_codec *codec, bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, WCD934X_ANA_MBHC_MECH, + 0x02, 0x02); + snd_soc_update_bits(codec, WCD934X_ANA_MBHC_MECH, + 0x40, 0x40); + } else { + snd_soc_update_bits(codec, WCD934X_ANA_MBHC_MECH, + 0x40, 0x00); + snd_soc_update_bits(codec, WCD934X_ANA_MBHC_MECH, + 0x02, 0x00); + } +} + +static void tavil_mbhc_hph_pull_down_ctrl(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, WCD934X_HPH_PA_CTL2, + 0x40, 0x40); + snd_soc_update_bits(codec, WCD934X_HPH_PA_CTL2, + 0x10, 0x10); + } else { + snd_soc_update_bits(codec, WCD934X_HPH_PA_CTL2, + 0x40, 0x00); + snd_soc_update_bits(codec, WCD934X_HPH_PA_CTL2, + 0x10, 0x00); + } +} +static void tavil_mbhc_moisture_config(struct wcd_mbhc *mbhc) +{ + struct snd_soc_codec *codec = mbhc->codec; + + if ((mbhc->moist_rref == R_OFF) || + (mbhc->mbhc_cfg->enable_usbc_analog)) { + snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); + return; + } + + /* Donot enable moisture detection if jack type is NC */ + if (!mbhc->hphl_swh) { + dev_dbg(codec->dev, "%s: disable moisture detection for NC\n", + __func__); + snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); + return; + } + + snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_2, + 0x0C, mbhc->moist_rref << 2); +} + +static bool tavil_hph_register_recovery(struct wcd_mbhc *mbhc) +{ + struct snd_soc_codec *codec = mbhc->codec; + struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(codec); + + if (!wcd934x_mbhc) + return false; + + wcd934x_mbhc->is_hph_recover = false; + snd_soc_dapm_force_enable_pin(snd_soc_codec_get_dapm(codec), + "RESET_HPH_REGISTERS"); + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + + snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(codec), + "RESET_HPH_REGISTERS"); + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + + return wcd934x_mbhc->is_hph_recover; +} + +static const struct wcd_mbhc_cb mbhc_cb = { + .request_irq = tavil_mbhc_request_irq, + .irq_control = tavil_mbhc_irq_control, + .free_irq = tavil_mbhc_free_irq, + .clk_setup = tavil_mbhc_clk_setup, + .map_btn_code_to_num = tavil_mbhc_btn_to_num, + .enable_mb_source = tavil_enable_ext_mb_source, + .mbhc_bias = tavil_mbhc_mbhc_bias_control, + .set_btn_thr = tavil_mbhc_program_btn_thr, + .lock_sleep = tavil_mbhc_lock_sleep, + .register_notifier = tavil_mbhc_register_notifier, + .micbias_enable_status = tavil_mbhc_micb_en_status, + .hph_pa_on_status = tavil_mbhc_hph_pa_on_status, + .hph_pull_up_control = tavil_mbhc_hph_l_pull_up_control, + .mbhc_micbias_control = tavil_mbhc_request_micbias, + .mbhc_micb_ramp_control = tavil_mbhc_micb_ramp_control, + .get_hwdep_fw_cal = tavil_get_hwdep_fw_cal, + .mbhc_micb_ctrl_thr_mic = tavil_mbhc_micb_ctrl_threshold_mic, + .compute_impedance = tavil_wcd_mbhc_calc_impedance, + .mbhc_gnd_det_ctrl = tavil_mbhc_gnd_det_ctrl, + .hph_pull_down_ctrl = tavil_mbhc_hph_pull_down_ctrl, + .mbhc_moisture_config = tavil_mbhc_moisture_config, + .hph_register_recovery = tavil_hph_register_recovery, +}; + +static struct regulator *tavil_codec_find_ondemand_regulator( + struct snd_soc_codec *codec, const char *name) +{ + int i; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + + for (i = 0; i < wcd9xxx->num_of_supplies; ++i) { + if (pdata->regulator[i].ondemand && + wcd9xxx->supplies[i].supply && + !strcmp(wcd9xxx->supplies[i].supply, name)) + return wcd9xxx->supplies[i].consumer; + } + + dev_dbg(codec->dev, "Warning: regulator not found:%s\n", + name); + return NULL; +} + +static int tavil_get_hph_type(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(codec); + struct wcd_mbhc *mbhc; + + if (!wcd934x_mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + + mbhc = &wcd934x_mbhc->wcd_mbhc; + + ucontrol->value.integer.value[0] = (u32) mbhc->hph_type; + dev_dbg(codec->dev, "%s: hph_type = %u\n", __func__, mbhc->hph_type); + + return 0; +} + +static int tavil_hph_impedance_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + uint32_t zl, zr; + bool hphr; + struct soc_multi_mixer_control *mc; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(codec); + + if (!wcd934x_mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + + mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); + hphr = mc->shift; + wcd_mbhc_get_impedance(&wcd934x_mbhc->wcd_mbhc, &zl, &zr); + dev_dbg(codec->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr); + ucontrol->value.integer.value[0] = hphr ? zr : zl; + + return 0; +} + +static const struct snd_kcontrol_new hph_type_detect_controls[] = { + SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0, + tavil_get_hph_type, NULL), +}; + +static const struct snd_kcontrol_new impedance_detect_controls[] = { + SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0, + tavil_hph_impedance_get, NULL), + SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0, + tavil_hph_impedance_get, NULL), +}; + +/* + * tavil_mbhc_get_impedance: get impedance of headphone left and right channels + * @wcd934x_mbhc: handle to struct wcd934x_mbhc * + * @zl: handle to left-ch impedance + * @zr: handle to right-ch impedance + * return 0 for success or error code in case of failure + */ +int tavil_mbhc_get_impedance(struct wcd934x_mbhc *wcd934x_mbhc, + uint32_t *zl, uint32_t *zr) +{ + if (!wcd934x_mbhc) { + pr_err("%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + if (!zl || !zr) { + pr_err("%s: zl or zr null!\n", __func__); + return -EINVAL; + } + + return wcd_mbhc_get_impedance(&wcd934x_mbhc->wcd_mbhc, zl, zr); +} +EXPORT_SYMBOL(tavil_mbhc_get_impedance); + +/* + * tavil_mbhc_hs_detect: starts mbhc insertion/removal functionality + * @codec: handle to snd_soc_codec * + * @mbhc_cfg: handle to mbhc configuration structure + * return 0 if mbhc_start is success or error code in case of failure + */ +int tavil_mbhc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg) +{ + struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(codec); + + if (!wcd934x_mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + + return wcd_mbhc_start(&wcd934x_mbhc->wcd_mbhc, mbhc_cfg); +} +EXPORT_SYMBOL(tavil_mbhc_hs_detect); + +/* + * tavil_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality + * @codec: handle to snd_soc_codec * + */ +void tavil_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +{ + struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(codec); + + if (!wcd934x_mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + return; + } + wcd_mbhc_stop(&wcd934x_mbhc->wcd_mbhc); +} +EXPORT_SYMBOL(tavil_mbhc_hs_detect_exit); + +/* + * tavil_mbhc_post_ssr_init: initialize mbhc for tavil post subsystem restart + * @mbhc: poniter to wcd934x_mbhc structure + * @codec: handle to snd_soc_codec * + * + * return 0 if mbhc_init is success or error code in case of failure + */ +int tavil_mbhc_post_ssr_init(struct wcd934x_mbhc *mbhc, + struct snd_soc_codec *codec) +{ + int ret; + + if (!mbhc || !codec) + return -EINVAL; + + wcd_mbhc_deinit(&mbhc->wcd_mbhc); + ret = wcd_mbhc_init(&mbhc->wcd_mbhc, codec, &mbhc_cb, &intr_ids, + wcd_mbhc_registers, TAVIL_ZDET_SUPPORTED); + if (ret) { + dev_err(codec->dev, "%s: mbhc initialization failed\n", + __func__); + goto done; + } + if (!WCD_MBHC_DETECTION) { + snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_1, 0x04, 0x04); + snd_soc_update_bits(codec, WCD934X_MBHC_CTL_BCS, 0x01, 0x01); + } + +done: + return ret; +} +EXPORT_SYMBOL(tavil_mbhc_post_ssr_init); + +/* + * tavil_mbhc_init: initialize mbhc for tavil + * @mbhc: poniter to wcd934x_mbhc struct pointer to store the configs + * @codec: handle to snd_soc_codec * + * @fw_data: handle to firmware data + * + * return 0 if mbhc_init is success or error code in case of failure + */ +int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, struct snd_soc_codec *codec, + struct fw_info *fw_data) +{ + struct regulator *supply; + struct wcd934x_mbhc *wcd934x_mbhc; + int ret; + + wcd934x_mbhc = devm_kzalloc(codec->dev, sizeof(struct wcd934x_mbhc), + GFP_KERNEL); + if (!wcd934x_mbhc) + return -ENOMEM; + + wcd934x_mbhc->wcd9xxx = dev_get_drvdata(codec->dev->parent); + wcd934x_mbhc->fw_data = fw_data; + BLOCKING_INIT_NOTIFIER_HEAD(&wcd934x_mbhc->notifier); + + ret = wcd_mbhc_init(&wcd934x_mbhc->wcd_mbhc, codec, &mbhc_cb, + &intr_ids, wcd_mbhc_registers, + TAVIL_ZDET_SUPPORTED); + if (ret) { + dev_err(codec->dev, "%s: mbhc initialization failed\n", + __func__); + goto err; + } + + supply = tavil_codec_find_ondemand_regulator(codec, + on_demand_supply_name[WCD934X_ON_DEMAND_MICBIAS]); + if (supply) { + wcd934x_mbhc->on_demand_list[ + WCD934X_ON_DEMAND_MICBIAS].supply = + supply; + wcd934x_mbhc->on_demand_list[ + WCD934X_ON_DEMAND_MICBIAS].ondemand_supply_count = + 0; + } + + (*mbhc) = wcd934x_mbhc; + snd_soc_add_codec_controls(codec, impedance_detect_controls, + ARRAY_SIZE(impedance_detect_controls)); + snd_soc_add_codec_controls(codec, hph_type_detect_controls, + ARRAY_SIZE(hph_type_detect_controls)); + + if (!WCD_MBHC_DETECTION) { + snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_1, 0x04, 0x04); + snd_soc_update_bits(codec, WCD934X_MBHC_CTL_BCS, 0x01, 0x01); + } + + return 0; +err: + devm_kfree(codec->dev, wcd934x_mbhc); + return ret; +} +EXPORT_SYMBOL(tavil_mbhc_init); + +/* + * tavil_mbhc_deinit: deinitialize mbhc for tavil + * @codec: handle to snd_soc_codec * + */ +void tavil_mbhc_deinit(struct snd_soc_codec *codec) +{ + struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(codec); + + if (wcd934x_mbhc) { + wcd_mbhc_deinit(&wcd934x_mbhc->wcd_mbhc); + devm_kfree(codec->dev, wcd934x_mbhc); + } +} +EXPORT_SYMBOL(tavil_mbhc_deinit); diff --git a/sound/soc/codecs/wcd934x/wcd934x-mbhc.h b/sound/soc/codecs/wcd934x/wcd934x-mbhc.h new file mode 100644 index 000000000000..53c886da0f6b --- /dev/null +++ b/sound/soc/codecs/wcd934x/wcd934x-mbhc.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __WCD934X_MBHC_H__ +#define __WCD934X_MBHC_H__ +#include "../wcd-mbhc-v2.h" + +enum wcd934x_on_demand_supply_name { + WCD934X_ON_DEMAND_MICBIAS = 0, + WCD934X_ON_DEMAND_SUPPLIES_MAX, +}; + +struct wcd934x_on_demand_supply { + struct regulator *supply; + int ondemand_supply_count; +}; + +struct wcd934x_mbhc { + struct wcd_mbhc wcd_mbhc; + struct blocking_notifier_head notifier; + struct wcd934x_on_demand_supply on_demand_list[ + WCD934X_ON_DEMAND_SUPPLIES_MAX]; + struct wcd9xxx *wcd9xxx; + struct fw_info *fw_data; + bool mbhc_started; + bool is_hph_recover; +}; + +#if IS_ENABLED(CONFIG_SND_SOC_WCD934X_MBHC) +extern int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, + struct snd_soc_codec *codec, + struct fw_info *fw_data); +extern void tavil_mbhc_hs_detect_exit(struct snd_soc_codec *codec); +extern int tavil_mbhc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg); +extern void tavil_mbhc_deinit(struct snd_soc_codec *codec); +extern int tavil_mbhc_post_ssr_init(struct wcd934x_mbhc *mbhc, + struct snd_soc_codec *codec); +extern int tavil_mbhc_get_impedance(struct wcd934x_mbhc *wcd934x_mbhc, + uint32_t *zl, uint32_t *zr); +#else +static inline int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, + struct snd_soc_codec *codec, + struct fw_info *fw_data) +{ + return 0; +} +static inline void tavil_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +{ +} +static inline int tavil_mbhc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg) +{ + return 0; +} +static inline void tavil_mbhc_deinit(struct snd_soc_codec *codec) +{ +} +static inline int tavil_mbhc_post_ssr_init(struct wcd934x_mbhc *mbhc, + struct snd_soc_codec *codec) +{ + return 0; +} +static inline int tavil_mbhc_get_impedance(struct wcd934x_mbhc *wcd934x_mbhc, + uint32_t *zl, uint32_t *zr) +{ + if (zl) + *zl = 0; + if (zr) + *zr = 0; + return -EINVAL; +} +#endif + +#endif /* __WCD934X_MBHC_H__ */ diff --git a/sound/soc/codecs/wcd934x/wcd934x-routing.h b/sound/soc/codecs/wcd934x/wcd934x-routing.h new file mode 100644 index 000000000000..afd93b2cf56d --- /dev/null +++ b/sound/soc/codecs/wcd934x/wcd934x-routing.h @@ -0,0 +1,1171 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef WCD934X_ROUTING_H +#define WCD934X_ROUTING_H + +#include + +const struct snd_soc_dapm_route tavil_slim_audio_map[] = { + + /* Virtual input widgets */ + {"AIF1 CAP", NULL, "AIF1_CAP Mixer"}, + {"AIF2 CAP", NULL, "AIF2_CAP Mixer"}, + {"AIF3 CAP", NULL, "AIF3_CAP Mixer"}, + {"AIF4 MAD", NULL, "AIF4_MAD Mixer"}, + + /* Virtual input widget Mixer */ + {"AIF1_CAP Mixer", "SLIM TX0", "SLIM TX0"}, + {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1"}, + {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2"}, + {"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3"}, + {"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4"}, + {"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5"}, + {"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6"}, + {"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7"}, + {"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8"}, + {"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9"}, + {"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10"}, + {"AIF1_CAP Mixer", "SLIM TX11", "SLIM TX11"}, + {"AIF1_CAP Mixer", "SLIM TX13", "SLIM TX13"}, + + {"AIF2_CAP Mixer", "SLIM TX0", "SLIM TX0"}, + {"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1"}, + {"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2"}, + {"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3"}, + {"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4"}, + {"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5"}, + {"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6"}, + {"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7"}, + {"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8"}, + {"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9"}, + {"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10"}, + {"AIF2_CAP Mixer", "SLIM TX11", "SLIM TX11"}, + {"AIF2_CAP Mixer", "SLIM TX13", "SLIM TX13"}, + + {"AIF3_CAP Mixer", "SLIM TX0", "SLIM TX0"}, + {"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1"}, + {"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2"}, + {"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3"}, + {"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4"}, + {"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5"}, + {"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6"}, + {"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7"}, + {"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8"}, + {"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9"}, + {"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10"}, + {"AIF3_CAP Mixer", "SLIM TX11", "SLIM TX11"}, + {"AIF3_CAP Mixer", "SLIM TX13", "SLIM TX13"}, + + {"AIF4_MAD Mixer", "SLIM TX13", "SLIM TX13"}, + + {"SLIM RX0 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"}, + + {"SLIM RX0 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"}, + + {"SLIM RX0 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"}, + + {"SLIM RX0 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX1 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX2 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX3 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX4 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX5 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX6 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX7 MUX", "AIF4_PB", "AIF4 PB"}, + + {"SLIM RX0", NULL, "SLIM RX0 MUX"}, + {"SLIM RX1", NULL, "SLIM RX1 MUX"}, + {"SLIM RX2", NULL, "SLIM RX2 MUX"}, + {"SLIM RX3", NULL, "SLIM RX3 MUX"}, + {"SLIM RX4", NULL, "SLIM RX4 MUX"}, + {"SLIM RX5", NULL, "SLIM RX5 MUX"}, + {"SLIM RX6", NULL, "SLIM RX6 MUX"}, + {"SLIM RX7", NULL, "SLIM RX7 MUX"}, + +}; + +const struct snd_soc_dapm_route tavil_audio_map[] = { + + /* MAD */ + {"MAD_SEL MUX", "SPE", "MAD_CPE_INPUT"}, + {"MAD_SEL MUX", "MSM", "MADINPUT"}, + + {"MAD_INP MUX", "MAD", "MAD_SEL MUX"}, + {"MAD_INP MUX", "DEC1", "ADC MUX1"}, + + {"MAD_BROADCAST", "Switch", "MAD_INP MUX"}, + {"MAD_CPE1", "Switch", "MAD_INP MUX"}, + {"MAD_CPE2", "Switch", "MAD_INP MUX"}, + + {"MAD_CPE_OUT1", NULL, "MAD_CPE1"}, + {"MAD_CPE_OUT2", NULL, "MAD_CPE2"}, + + /* VI Feedback */ + {"AIF4_VI Mixer", "SPKR_VI_1", "VIINPUT"}, + {"AIF4_VI Mixer", "SPKR_VI_2", "VIINPUT"}, + {"AIF4 VI", NULL, "AIF4_VI Mixer"}, + + /* CDC Tx interface with SLIMBUS */ + {"SLIM TX0", NULL, "CDC_IF TX0 MUX"}, + {"SLIM TX1", NULL, "CDC_IF TX1 MUX"}, + {"SLIM TX2", NULL, "CDC_IF TX2 MUX"}, + {"SLIM TX3", NULL, "CDC_IF TX3 MUX"}, + {"SLIM TX4", NULL, "CDC_IF TX4 MUX"}, + {"SLIM TX5", NULL, "CDC_IF TX5 MUX"}, + {"SLIM TX6", NULL, "CDC_IF TX6 MUX"}, + {"SLIM TX7", NULL, "CDC_IF TX7 MUX"}, + {"SLIM TX8", NULL, "CDC_IF TX8 MUX"}, + {"SLIM TX9", NULL, "CDC_IF TX9 MUX"}, + {"SLIM TX10", NULL, "CDC_IF TX10 MUX"}, + {"SLIM TX11", NULL, "CDC_IF TX11 MUX"}, + {"SLIM TX13", NULL, "CDC_IF TX13 MUX"}, + + {"CDC_IF TX0 MUX", "DEC0", "ADC MUX0"}, + {"CDC_IF TX0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"}, + {"CDC_IF TX0 MUX", "DEC0_192", "ADC US MUX0"}, + + {"CDC_IF TX1 MUX", "DEC1", "ADC MUX1"}, + {"CDC_IF TX1 MUX", "RX_MIX_TX1", "RX MIX TX1 MUX"}, + {"CDC_IF TX1 MUX", "DEC1_192", "ADC US MUX1"}, + + {"CDC_IF TX2 MUX", "DEC2", "ADC MUX2"}, + {"CDC_IF TX2 MUX", "RX_MIX_TX2", "RX MIX TX2 MUX"}, + {"CDC_IF TX2 MUX", "DEC2_192", "ADC US MUX2"}, + + {"CDC_IF TX3 MUX", "DEC3", "ADC MUX3"}, + {"CDC_IF TX3 MUX", "RX_MIX_TX3", "RX MIX TX3 MUX"}, + {"CDC_IF TX3 MUX", "DEC3_192", "ADC US MUX3"}, + + {"CDC_IF TX4 MUX", "DEC4", "ADC MUX4"}, + {"CDC_IF TX4 MUX", "RX_MIX_TX4", "RX MIX TX4 MUX"}, + {"CDC_IF TX4 MUX", "DEC4_192", "ADC US MUX4"}, + + {"CDC_IF TX5 MUX", "DEC5", "ADC MUX5"}, + {"CDC_IF TX5 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"}, + {"CDC_IF TX5 MUX", "DEC5_192", "ADC US MUX5"}, + + {"CDC_IF TX6 MUX", "DEC6", "ADC MUX6"}, + {"CDC_IF TX6 MUX", "RX_MIX_TX6", "RX MIX TX6 MUX"}, + {"CDC_IF TX6 MUX", "DEC6_192", "ADC US MUX6"}, + + {"CDC_IF TX7 MUX", "DEC7", "ADC MUX7"}, + {"CDC_IF TX7 MUX", "RX_MIX_TX7", "RX MIX TX7 MUX"}, + {"CDC_IF TX7 MUX", "DEC7_192", "ADC US MUX7"}, + + {"CDC_IF TX8 MUX", "DEC8", "ADC MUX8"}, + {"CDC_IF TX8 MUX", "RX_MIX_TX8", "RX MIX TX8 MUX"}, + {"CDC_IF TX8 MUX", "DEC8_192", "ADC US MUX8"}, + + {"CDC_IF TX9 MUX", "DEC7", "ADC MUX7"}, + {"CDC_IF TX9 MUX", "DEC7_192", "ADC US MUX7"}, + {"CDC_IF TX10 MUX", "DEC6", "ADC MUX6"}, + {"CDC_IF TX10 MUX", "DEC6_192", "ADC US MUX6"}, + + {"CDC_IF TX11 MUX", "DEC_0_5", "CDC_IF TX11 INP1 MUX"}, + {"CDC_IF TX11 MUX", "DEC_9_12", "CDC_IF TX11 INP1 MUX"}, + {"CDC_IF TX11 INP1 MUX", "DEC0", "ADC MUX0"}, + {"CDC_IF TX11 INP1 MUX", "DEC1", "ADC MUX1"}, + {"CDC_IF TX11 INP1 MUX", "DEC2", "ADC MUX2"}, + {"CDC_IF TX11 INP1 MUX", "DEC3", "ADC MUX3"}, + {"CDC_IF TX11 INP1 MUX", "DEC4", "ADC MUX4"}, + {"CDC_IF TX11 INP1 MUX", "DEC5", "ADC MUX5"}, + {"CDC_IF TX11 INP1 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"}, + + {"CDC_IF TX13 MUX", "MAD_BRDCST", "MAD_BROADCAST"}, + {"CDC_IF TX13 MUX", "CDC_DEC_5", "CDC_IF TX13 INP1 MUX"}, + {"CDC_IF TX13 INP1 MUX", "DEC5", "ADC MUX5"}, + {"CDC_IF TX13 INP1 MUX", "DEC5_192", "ADC US MUX5"}, + + {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + + {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + + {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + + {"RX MIX TX3 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + + {"RX MIX TX4 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + + {"RX MIX TX5 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + + {"RX MIX TX6 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + + {"RX MIX TX7 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + + {"RX MIX TX8 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX3", "RX INT3 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX4", "RX INT4 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + + {"ADC US MUX0", "US_Switch", "ADC MUX0"}, + {"ADC US MUX1", "US_Switch", "ADC MUX1"}, + {"ADC US MUX2", "US_Switch", "ADC MUX2"}, + {"ADC US MUX3", "US_Switch", "ADC MUX3"}, + {"ADC US MUX4", "US_Switch", "ADC MUX4"}, + {"ADC US MUX5", "US_Switch", "ADC MUX5"}, + {"ADC US MUX6", "US_Switch", "ADC MUX6"}, + {"ADC US MUX7", "US_Switch", "ADC MUX7"}, + {"ADC US MUX8", "US_Switch", "ADC MUX8"}, + + {"ADC MUX0", "DMIC", "DMIC MUX0"}, + {"ADC MUX0", "AMIC", "AMIC MUX0"}, + {"ADC MUX1", "DMIC", "DMIC MUX1"}, + {"ADC MUX1", "AMIC", "AMIC MUX1"}, + {"ADC MUX2", "DMIC", "DMIC MUX2"}, + {"ADC MUX2", "AMIC", "AMIC MUX2"}, + {"ADC MUX3", "DMIC", "DMIC MUX3"}, + {"ADC MUX3", "AMIC", "AMIC MUX3"}, + {"ADC MUX4", "DMIC", "DMIC MUX4"}, + {"ADC MUX4", "AMIC", "AMIC MUX4"}, + {"ADC MUX5", "DMIC", "DMIC MUX5"}, + {"ADC MUX5", "AMIC", "AMIC MUX5"}, + {"ADC MUX6", "DMIC", "DMIC MUX6"}, + {"ADC MUX6", "AMIC", "AMIC MUX6"}, + {"ADC MUX7", "DMIC", "DMIC MUX7"}, + {"ADC MUX7", "AMIC", "AMIC MUX7"}, + {"ADC MUX8", "DMIC", "DMIC MUX8"}, + {"ADC MUX8", "AMIC", "AMIC MUX8"}, + {"ADC MUX10", "DMIC", "DMIC MUX10"}, + {"ADC MUX10", "AMIC", "AMIC MUX10"}, + {"ADC MUX11", "DMIC", "DMIC MUX11"}, + {"ADC MUX11", "AMIC", "AMIC MUX11"}, + {"ADC MUX12", "DMIC", "DMIC MUX12"}, + {"ADC MUX12", "AMIC", "AMIC MUX12"}, + {"ADC MUX13", "DMIC", "DMIC MUX13"}, + {"ADC MUX13", "AMIC", "AMIC MUX13"}, + + {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX0", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX0", "ANC_FB_TUNE2", "ADC MUX13"}, + {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX1", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX1", "ANC_FB_TUNE2", "ADC MUX13"}, + {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX2", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX2", "ANC_FB_TUNE2", "ADC MUX13"}, + {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX3", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX3", "ANC_FB_TUNE2", "ADC MUX13"}, + {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX4", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX4", "ANC_FB_TUNE2", "ADC MUX13"}, + {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX5", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX5", "ANC_FB_TUNE2", "ADC MUX13"}, + {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX6", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX6", "ANC_FB_TUNE2", "ADC MUX13"}, + {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX7", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX7", "ANC_FB_TUNE2", "ADC MUX13"}, + {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX8", "ANC_FB_TUNE2", "ADC MUX12"}, + {"ADC MUX8", "ANC_FB_TUNE2", "ADC MUX13"}, + + {"DMIC MUX0", "DMIC0", "DMIC0"}, + {"DMIC MUX0", "DMIC1", "DMIC1"}, + {"DMIC MUX0", "DMIC2", "DMIC2"}, + {"DMIC MUX0", "DMIC3", "DMIC3"}, + {"DMIC MUX0", "DMIC4", "DMIC4"}, + {"DMIC MUX0", "DMIC5", "DMIC5"}, + {"AMIC MUX0", "ADC1", "ADC1"}, + {"AMIC MUX0", "ADC2", "ADC2"}, + {"AMIC MUX0", "ADC3", "ADC3"}, + {"AMIC MUX0", "ADC4", "ADC4"}, + + {"DMIC MUX1", "DMIC0", "DMIC0"}, + {"DMIC MUX1", "DMIC1", "DMIC1"}, + {"DMIC MUX1", "DMIC2", "DMIC2"}, + {"DMIC MUX1", "DMIC3", "DMIC3"}, + {"DMIC MUX1", "DMIC4", "DMIC4"}, + {"DMIC MUX1", "DMIC5", "DMIC5"}, + {"AMIC MUX1", "ADC1", "ADC1"}, + {"AMIC MUX1", "ADC2", "ADC2"}, + {"AMIC MUX1", "ADC3", "ADC3"}, + {"AMIC MUX1", "ADC4", "ADC4"}, + + {"DMIC MUX2", "DMIC0", "DMIC0"}, + {"DMIC MUX2", "DMIC1", "DMIC1"}, + {"DMIC MUX2", "DMIC2", "DMIC2"}, + {"DMIC MUX2", "DMIC3", "DMIC3"}, + {"DMIC MUX2", "DMIC4", "DMIC4"}, + {"DMIC MUX2", "DMIC5", "DMIC5"}, + {"AMIC MUX2", "ADC1", "ADC1"}, + {"AMIC MUX2", "ADC2", "ADC2"}, + {"AMIC MUX2", "ADC3", "ADC3"}, + {"AMIC MUX2", "ADC4", "ADC4"}, + + {"DMIC MUX3", "DMIC0", "DMIC0"}, + {"DMIC MUX3", "DMIC1", "DMIC1"}, + {"DMIC MUX3", "DMIC2", "DMIC2"}, + {"DMIC MUX3", "DMIC3", "DMIC3"}, + {"DMIC MUX3", "DMIC4", "DMIC4"}, + {"DMIC MUX3", "DMIC5", "DMIC5"}, + {"AMIC MUX3", "ADC1", "ADC1"}, + {"AMIC MUX3", "ADC2", "ADC2"}, + {"AMIC MUX3", "ADC3", "ADC3"}, + {"AMIC MUX3", "ADC4", "ADC4"}, + + {"DMIC MUX4", "DMIC0", "DMIC0"}, + {"DMIC MUX4", "DMIC1", "DMIC1"}, + {"DMIC MUX4", "DMIC2", "DMIC2"}, + {"DMIC MUX4", "DMIC3", "DMIC3"}, + {"DMIC MUX4", "DMIC4", "DMIC4"}, + {"DMIC MUX4", "DMIC5", "DMIC5"}, + {"AMIC MUX4", "ADC1", "ADC1"}, + {"AMIC MUX4", "ADC2", "ADC2"}, + {"AMIC MUX4", "ADC3", "ADC3"}, + {"AMIC MUX4", "ADC4", "ADC4"}, + + {"DMIC MUX5", "DMIC0", "DMIC0"}, + {"DMIC MUX5", "DMIC1", "DMIC1"}, + {"DMIC MUX5", "DMIC2", "DMIC2"}, + {"DMIC MUX5", "DMIC3", "DMIC3"}, + {"DMIC MUX5", "DMIC4", "DMIC4"}, + {"DMIC MUX5", "DMIC5", "DMIC5"}, + {"AMIC MUX5", "ADC1", "ADC1"}, + {"AMIC MUX5", "ADC2", "ADC2"}, + {"AMIC MUX5", "ADC3", "ADC3"}, + {"AMIC MUX5", "ADC4", "ADC4"}, + + {"DMIC MUX6", "DMIC0", "DMIC0"}, + {"DMIC MUX6", "DMIC1", "DMIC1"}, + {"DMIC MUX6", "DMIC2", "DMIC2"}, + {"DMIC MUX6", "DMIC3", "DMIC3"}, + {"DMIC MUX6", "DMIC4", "DMIC4"}, + {"DMIC MUX6", "DMIC5", "DMIC5"}, + {"AMIC MUX6", "ADC1", "ADC1"}, + {"AMIC MUX6", "ADC2", "ADC2"}, + {"AMIC MUX6", "ADC3", "ADC3"}, + {"AMIC MUX6", "ADC4", "ADC4"}, + + {"DMIC MUX7", "DMIC0", "DMIC0"}, + {"DMIC MUX7", "DMIC1", "DMIC1"}, + {"DMIC MUX7", "DMIC2", "DMIC2"}, + {"DMIC MUX7", "DMIC3", "DMIC3"}, + {"DMIC MUX7", "DMIC4", "DMIC4"}, + {"DMIC MUX7", "DMIC5", "DMIC5"}, + {"AMIC MUX7", "ADC1", "ADC1"}, + {"AMIC MUX7", "ADC2", "ADC2"}, + {"AMIC MUX7", "ADC3", "ADC3"}, + {"AMIC MUX7", "ADC4", "ADC4"}, + + {"DMIC MUX8", "DMIC0", "DMIC0"}, + {"DMIC MUX8", "DMIC1", "DMIC1"}, + {"DMIC MUX8", "DMIC2", "DMIC2"}, + {"DMIC MUX8", "DMIC3", "DMIC3"}, + {"DMIC MUX8", "DMIC4", "DMIC4"}, + {"DMIC MUX8", "DMIC5", "DMIC5"}, + {"AMIC MUX8", "ADC1", "ADC1"}, + {"AMIC MUX8", "ADC2", "ADC2"}, + {"AMIC MUX8", "ADC3", "ADC3"}, + {"AMIC MUX8", "ADC4", "ADC4"}, + + {"DMIC MUX10", "DMIC0", "DMIC0"}, + {"DMIC MUX10", "DMIC1", "DMIC1"}, + {"DMIC MUX10", "DMIC2", "DMIC2"}, + {"DMIC MUX10", "DMIC3", "DMIC3"}, + {"DMIC MUX10", "DMIC4", "DMIC4"}, + {"DMIC MUX10", "DMIC5", "DMIC5"}, + {"AMIC MUX10", "ADC1", "ADC1"}, + {"AMIC MUX10", "ADC2", "ADC2"}, + {"AMIC MUX10", "ADC3", "ADC3"}, + {"AMIC MUX10", "ADC4", "ADC4"}, + + {"DMIC MUX11", "DMIC0", "DMIC0"}, + {"DMIC MUX11", "DMIC1", "DMIC1"}, + {"DMIC MUX11", "DMIC2", "DMIC2"}, + {"DMIC MUX11", "DMIC3", "DMIC3"}, + {"DMIC MUX11", "DMIC4", "DMIC4"}, + {"DMIC MUX11", "DMIC5", "DMIC5"}, + {"AMIC MUX11", "ADC1", "ADC1"}, + {"AMIC MUX11", "ADC2", "ADC2"}, + {"AMIC MUX11", "ADC3", "ADC3"}, + {"AMIC MUX11", "ADC4", "ADC4"}, + + {"DMIC MUX12", "DMIC0", "DMIC0"}, + {"DMIC MUX12", "DMIC1", "DMIC1"}, + {"DMIC MUX12", "DMIC2", "DMIC2"}, + {"DMIC MUX12", "DMIC3", "DMIC3"}, + {"DMIC MUX12", "DMIC4", "DMIC4"}, + {"DMIC MUX12", "DMIC5", "DMIC5"}, + {"AMIC MUX12", "ADC1", "ADC1"}, + {"AMIC MUX12", "ADC2", "ADC2"}, + {"AMIC MUX12", "ADC3", "ADC3"}, + {"AMIC MUX12", "ADC4", "ADC4"}, + + {"DMIC MUX13", "DMIC0", "DMIC0"}, + {"DMIC MUX13", "DMIC1", "DMIC1"}, + {"DMIC MUX13", "DMIC2", "DMIC2"}, + {"DMIC MUX13", "DMIC3", "DMIC3"}, + {"DMIC MUX13", "DMIC4", "DMIC4"}, + {"DMIC MUX13", "DMIC5", "DMIC5"}, + {"AMIC MUX13", "ADC1", "ADC1"}, + {"AMIC MUX13", "ADC2", "ADC2"}, + {"AMIC MUX13", "ADC3", "ADC3"}, + {"AMIC MUX13", "ADC4", "ADC4"}, + + {"AMIC4_5 SEL", "AMIC4", "AMIC4"}, + {"AMIC4_5 SEL", "AMIC5", "AMIC5"}, + + {"ADC1", NULL, "AMIC1"}, + {"ADC2", NULL, "AMIC2"}, + {"ADC3", NULL, "AMIC3"}, + {"ADC4", NULL, "AMIC4_5 SEL"}, + + /* CDC Rx interface with SLIMBUS */ + {"CDC_IF RX0 MUX", "SLIM RX0", "SLIM RX0"}, + {"CDC_IF RX1 MUX", "SLIM RX1", "SLIM RX1"}, + {"CDC_IF RX2 MUX", "SLIM RX2", "SLIM RX2"}, + {"CDC_IF RX3 MUX", "SLIM RX3", "SLIM RX3"}, + {"CDC_IF RX4 MUX", "SLIM RX4", "SLIM RX4"}, + {"CDC_IF RX5 MUX", "SLIM RX5", "SLIM RX5"}, + {"CDC_IF RX6 MUX", "SLIM RX6", "SLIM RX6"}, + {"CDC_IF RX7 MUX", "SLIM RX7", "SLIM RX7"}, + + {"RX INT0_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT0_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT0_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT0_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT0_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT0_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT0_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT0_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT0_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT0_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT0_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT0_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT0_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT0_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT0_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT0_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT0_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT0_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT0_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT0_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT0_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT0_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT0_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT0_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX INT1_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT1_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT1_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT1_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT1_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT1_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT1_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT1_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT1_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT1_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT1_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT1_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT1_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT1_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT1_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT1_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT1_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT1_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT1_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT1_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT1_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT1_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT1_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT1_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT1_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT1_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT1_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT1_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT1_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT1_1 MIX1 INP2", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT2_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT2_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT2_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT2_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT2_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT2_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT2_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT2_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT2_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT2_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT2_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT2_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT2_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT2_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT2_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT2_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT2_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT2_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT2_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT2_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT2_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT2_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT2_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT2_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT2_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT2_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT2_1 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX INT3_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT3_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT3_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT3_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT3_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT3_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT3_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT3_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT3_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT3_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT3_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT3_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT3_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT3_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT3_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT3_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT3_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT3_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT3_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT3_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT3_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT3_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT3_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT3_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT3_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT3_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT3_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT3_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT3_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT3_1 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX INT4_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT4_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT4_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT4_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT4_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT4_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT4_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT4_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT4_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT4_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT4_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT4_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT4_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT4_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT4_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT4_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT4_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT4_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT4_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT4_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT4_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT4_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT4_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT4_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT4_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT4_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT4_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT4_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT4_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT4_1 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX INT7_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT7_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT7_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT7_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT7_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT7_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT7_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT7_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT7_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT7_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT7_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT7_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT7_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT7_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT7_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT7_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT7_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT7_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT7_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT7_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT7_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT7_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT7_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT7_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT7_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT7_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT7_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT7_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT7_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT7_1 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX INT8_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT8_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT8_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT8_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT8_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT8_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT8_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT8_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT8_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT8_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT8_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT8_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT8_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT8_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT8_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT8_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT8_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT8_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT8_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT8_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT8_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT8_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT8_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT8_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT8_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT8_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT8_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT8_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT8_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT8_1 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"}, + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"}, + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"}, + {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP0"}, + {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP1"}, + {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP2"}, + {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP0"}, + {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP1"}, + {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP2"}, + {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP0"}, + {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP1"}, + {"RX INT3_1 MIX1", NULL, "RX INT3_1 MIX1 INP2"}, + {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP0"}, + {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP1"}, + {"RX INT4_1 MIX1", NULL, "RX INT4_1 MIX1 INP2"}, + {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP0"}, + {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP1"}, + {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP2"}, + {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP0"}, + {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP1"}, + {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP2"}, + + /* Mixing path INT0 */ + {"RX INT0_2 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT0_2 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT0_2 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT0_2 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT0_2 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT0_2 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT0_2 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT0_2 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT0_2 INTERP", NULL, "RX INT0_2 MUX"}, + {"RX INT0 SEC MIX", NULL, "RX INT0_2 INTERP"}, + + /* Mixing path INT1 */ + {"RX INT1_2 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT1_2 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT1_2 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT1_2 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT1_2 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT1_2 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT1_2 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT1_2 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT1_2 INTERP", NULL, "RX INT1_2 MUX"}, + {"RX INT1 SEC MIX", NULL, "RX INT1_2 INTERP"}, + + /* Mixing path INT2 */ + {"RX INT2_2 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT2_2 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT2_2 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT2_2 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT2_2 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT2_2 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT2_2 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT2_2 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT2_2 INTERP", NULL, "RX INT2_2 MUX"}, + {"RX INT2 SEC MIX", NULL, "RX INT2_2 INTERP"}, + + /* Mixing path INT3 */ + {"RX INT3_2 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT3_2 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT3_2 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT3_2 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT3_2 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT3_2 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT3_2 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT3_2 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT3_2 INTERP", NULL, "RX INT3_2 MUX"}, + {"RX INT3 SEC MIX", NULL, "RX INT3_2 INTERP"}, + + /* Mixing path INT4 */ + {"RX INT4_2 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT4_2 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT4_2 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT4_2 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT4_2 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT4_2 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT4_2 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT4_2 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT4_2 INTERP", NULL, "RX INT4_2 MUX"}, + {"RX INT4 SEC MIX", NULL, "RX INT4_2 INTERP"}, + + /* Mixing path INT7 */ + {"RX INT7_2 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT7_2 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT7_2 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT7_2 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT7_2 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT7_2 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT7_2 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT7_2 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT7_2 INTERP", NULL, "RX INT7_2 MUX"}, + {"RX INT7 SEC MIX", NULL, "RX INT7_2 INTERP"}, + + /* Mixing path INT8 */ + {"RX INT8_2 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT8_2 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT8_2 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT8_2 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT8_2 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT8_2 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT8_2 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT8_2 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT8_2 INTERP", NULL, "RX INT8_2 MUX"}, + {"RX INT8 SEC MIX", NULL, "RX INT8_2 INTERP"}, + + {"RX INT0_1 INTERP", NULL, "RX INT0_1 MIX1"}, + {"RX INT0 SEC MIX", NULL, "RX INT0_1 INTERP"}, + {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"}, + {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"}, + {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 MIX2"}, + {"RX INT0 DAC", NULL, "RX INT0 DEM MUX"}, + {"RX INT0 DAC", NULL, "RX_BIAS"}, + {"EAR PA", NULL, "RX INT0 DAC"}, + {"EAR", NULL, "EAR PA"}, + + {"RX INT1_1 INTERP", NULL, "RX INT1_1 MIX1"}, + {"RX INT1 SEC MIX", NULL, "RX INT1_1 INTERP"}, + {"RX INT1 MIX2", NULL, "RX INT1 SEC MIX"}, + {"RX INT1 MIX2", NULL, "RX INT1 MIX2 INP"}, + {"RX INT1 MIX3", NULL, "RX INT1 MIX2"}, + {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 MIX3"}, + {"RX INT1 DAC", NULL, "RX INT1 DEM MUX"}, + {"RX INT1 DAC", NULL, "RX_BIAS"}, + {"HPHL PA", NULL, "RX INT1 DAC"}, + {"HPHL", NULL, "HPHL PA"}, + + {"RX INT2_1 INTERP", NULL, "RX INT2_1 MIX1"}, + {"RX INT2 SEC MIX", NULL, "RX INT2_1 INTERP"}, + {"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"}, + {"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"}, + {"RX INT2 MIX3", NULL, "RX INT2 MIX2"}, + {"RX INT2 DEM MUX", "CLSH_DSM_OUT", "RX INT2 MIX3"}, + {"RX INT2 DAC", NULL, "RX INT2 DEM MUX"}, + {"RX INT2 DAC", NULL, "RX_BIAS"}, + {"HPHR PA", NULL, "RX INT2 DAC"}, + {"HPHR", NULL, "HPHR PA"}, + + {"RX INT3_1 INTERP", NULL, "RX INT3_1 MIX1"}, + {"RX INT3 SEC MIX", NULL, "RX INT3_1 INTERP"}, + {"RX INT3 MIX2", NULL, "RX INT3 SEC MIX"}, + {"RX INT3 MIX2", NULL, "RX INT3 MIX2 INP"}, + {"RX INT3 MIX3", NULL, "RX INT3 MIX2"}, + {"RX INT3 DAC", NULL, "RX INT3 MIX3"}, + {"RX INT3 DAC", NULL, "RX_BIAS"}, + {"LINEOUT1 PA", NULL, "RX INT3 DAC"}, + {"LINEOUT1", NULL, "LINEOUT1 PA"}, + + {"RX INT4_1 INTERP", NULL, "RX INT4_1 MIX1"}, + {"RX INT4 SEC MIX", NULL, "RX INT4_1 INTERP"}, + {"RX INT4 SEC MIX", NULL, "RX INT4_1 MIX1"}, + {"RX INT4 MIX2", NULL, "RX INT4 SEC MIX"}, + {"RX INT4 MIX2", NULL, "RX INT4 MIX2 INP"}, + {"RX INT4 MIX3", NULL, "RX INT4 MIX2"}, + {"RX INT4 DAC", NULL, "RX INT4 MIX3"}, + {"RX INT4 DAC", NULL, "RX_BIAS"}, + {"LINEOUT2 PA", NULL, "RX INT4 DAC"}, + {"LINEOUT2", NULL, "LINEOUT2 PA"}, + + {"RX INT7_1 INTERP", NULL, "RX INT7_1 MIX1"}, + {"RX INT7 SEC MIX", NULL, "RX INT7_1 INTERP"}, + {"RX INT7 MIX2", NULL, "RX INT7 SEC MIX"}, + {"RX INT7 MIX2", NULL, "RX INT7 MIX2 INP"}, + {"RX INT7 CHAIN", NULL, "RX INT7 MIX2"}, + {"RX INT7 CHAIN", NULL, "RX_BIAS"}, + {"SPK1 OUT", NULL, "RX INT7 CHAIN"}, + + {"RX INT8_1 INTERP", NULL, "RX INT8_1 MIX1"}, + {"RX INT8 SEC MIX", NULL, "RX INT8_1 INTERP"}, + {"RX INT8 SEC MIX", NULL, "RX INT8_1 MIX1"}, + {"RX INT8 CHAIN", NULL, "RX INT8 SEC MIX"}, + {"RX INT8 CHAIN", NULL, "RX_BIAS"}, + {"SPK2 OUT", NULL, "RX INT8 CHAIN"}, + + /* ANC Routing */ + {"ANC0 FB MUX", "ANC_IN_EAR", "RX INT0 MIX2"}, + {"ANC0 FB MUX", "ANC_IN_HPHL", "RX INT1 MIX2"}, + {"ANC0 FB MUX", "ANC_IN_LO1", "RX INT3 MIX2"}, + {"ANC0 FB MUX", "ANC_IN_EAR_SPKR", "RX INT7 MIX2"}, + {"ANC1 FB MUX", "ANC_IN_HPHR", "RX INT2 MIX2"}, + {"ANC1 FB MUX", "ANC_IN_LO2", "RX INT4 MIX2"}, + + {"ANC OUT EAR Enable", "Switch", "ADC MUX10"}, + {"ANC OUT EAR Enable", "Switch", "ADC MUX11"}, + {"RX INT0 MIX2", NULL, "ANC OUT EAR Enable"}, + + {"ANC OUT HPHL Enable", "Switch", "ADC MUX10"}, + {"ANC OUT HPHL Enable", "Switch", "ADC MUX11"}, + {"RX INT1 MIX2", NULL, "ANC OUT HPHL Enable"}, + + {"ANC OUT HPHR Enable", "Switch", "ADC MUX12"}, + {"ANC OUT HPHR Enable", "Switch", "ADC MUX13"}, + {"RX INT2 MIX2", NULL, "ANC OUT HPHR Enable"}, + + {"ANC EAR PA", NULL, "RX INT0 DAC"}, + {"ANC EAR", NULL, "ANC EAR PA"}, + + {"ANC HPHL PA", NULL, "RX INT1 DAC"}, + {"ANC HPHL", NULL, "ANC HPHL PA"}, + + {"ANC HPHR PA", NULL, "RX INT2 DAC"}, + {"ANC HPHR", NULL, "ANC HPHR PA"}, + + {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX10"}, + {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX11"}, + {"RX INT7 MIX2", NULL, "ANC OUT EAR SPKR Enable"}, + + {"ANC SPKR PA Enable", "Switch", "RX INT7 CHAIN"}, + {"ANC SPK1 PA", NULL, "ANC SPKR PA Enable"}, + {"SPK1 OUT", NULL, "ANC SPK1 PA"}, + + /* + * SRC0, SRC1 inputs to Sidetone RX Mixer + * on RX0, RX1, RX2, RX3, RX4 and RX7 chains + */ + {"IIR0", NULL, "IIR0 INP0 MUX"}, + {"IIR0 INP0 MUX", "DEC0", "ADC MUX0"}, + {"IIR0 INP0 MUX", "DEC1", "ADC MUX1"}, + {"IIR0 INP0 MUX", "DEC2", "ADC MUX2"}, + {"IIR0 INP0 MUX", "DEC3", "ADC MUX3"}, + {"IIR0 INP0 MUX", "DEC4", "ADC MUX4"}, + {"IIR0 INP0 MUX", "DEC5", "ADC MUX5"}, + {"IIR0 INP0 MUX", "DEC6", "ADC MUX6"}, + {"IIR0 INP0 MUX", "DEC7", "ADC MUX7"}, + {"IIR0 INP0 MUX", "DEC8", "ADC MUX8"}, + {"IIR0 INP0 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"IIR0 INP0 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"IIR0 INP0 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"IIR0 INP0 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"IIR0 INP0 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"IIR0 INP0 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"IIR0 INP0 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"IIR0 INP0 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"IIR0", NULL, "IIR0 INP1 MUX"}, + {"IIR0 INP1 MUX", "DEC0", "ADC MUX0"}, + {"IIR0 INP1 MUX", "DEC1", "ADC MUX1"}, + {"IIR0 INP1 MUX", "DEC2", "ADC MUX2"}, + {"IIR0 INP1 MUX", "DEC3", "ADC MUX3"}, + {"IIR0 INP1 MUX", "DEC4", "ADC MUX4"}, + {"IIR0 INP1 MUX", "DEC5", "ADC MUX5"}, + {"IIR0 INP1 MUX", "DEC6", "ADC MUX6"}, + {"IIR0 INP1 MUX", "DEC7", "ADC MUX7"}, + {"IIR0 INP1 MUX", "DEC8", "ADC MUX8"}, + {"IIR0 INP1 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"IIR0 INP1 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"IIR0 INP1 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"IIR0 INP1 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"IIR0 INP1 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"IIR0 INP1 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"IIR0 INP1 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"IIR0 INP1 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"IIR0", NULL, "IIR0 INP2 MUX"}, + {"IIR0 INP2 MUX", "DEC0", "ADC MUX0"}, + {"IIR0 INP2 MUX", "DEC1", "ADC MUX1"}, + {"IIR0 INP2 MUX", "DEC2", "ADC MUX2"}, + {"IIR0 INP2 MUX", "DEC3", "ADC MUX3"}, + {"IIR0 INP2 MUX", "DEC4", "ADC MUX4"}, + {"IIR0 INP2 MUX", "DEC5", "ADC MUX5"}, + {"IIR0 INP2 MUX", "DEC6", "ADC MUX6"}, + {"IIR0 INP2 MUX", "DEC7", "ADC MUX7"}, + {"IIR0 INP2 MUX", "DEC8", "ADC MUX8"}, + {"IIR0 INP2 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"IIR0 INP2 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"IIR0 INP2 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"IIR0 INP2 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"IIR0 INP2 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"IIR0 INP2 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"IIR0 INP2 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"IIR0 INP2 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"IIR0", NULL, "IIR0 INP3 MUX"}, + {"IIR0 INP3 MUX", "DEC0", "ADC MUX0"}, + {"IIR0 INP3 MUX", "DEC1", "ADC MUX1"}, + {"IIR0 INP3 MUX", "DEC2", "ADC MUX2"}, + {"IIR0 INP3 MUX", "DEC3", "ADC MUX3"}, + {"IIR0 INP3 MUX", "DEC4", "ADC MUX4"}, + {"IIR0 INP3 MUX", "DEC5", "ADC MUX5"}, + {"IIR0 INP3 MUX", "DEC6", "ADC MUX6"}, + {"IIR0 INP3 MUX", "DEC7", "ADC MUX7"}, + {"IIR0 INP3 MUX", "DEC8", "ADC MUX8"}, + {"IIR0 INP3 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"IIR0 INP3 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"IIR0 INP3 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"IIR0 INP3 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"IIR0 INP3 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"IIR0 INP3 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"IIR0 INP3 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"IIR0 INP3 MUX", "RX7", "CDC_IF RX7 MUX"}, + + {"IIR1", NULL, "IIR1 INP0 MUX"}, + {"IIR1 INP0 MUX", "DEC0", "ADC MUX0"}, + {"IIR1 INP0 MUX", "DEC1", "ADC MUX1"}, + {"IIR1 INP0 MUX", "DEC2", "ADC MUX2"}, + {"IIR1 INP0 MUX", "DEC3", "ADC MUX3"}, + {"IIR1 INP0 MUX", "DEC4", "ADC MUX4"}, + {"IIR1 INP0 MUX", "DEC5", "ADC MUX5"}, + {"IIR1 INP0 MUX", "DEC6", "ADC MUX6"}, + {"IIR1 INP0 MUX", "DEC7", "ADC MUX7"}, + {"IIR1 INP0 MUX", "DEC8", "ADC MUX8"}, + {"IIR1 INP0 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"IIR1 INP0 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"IIR1 INP0 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"IIR1 INP0 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"IIR1 INP0 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"IIR1 INP0 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"IIR1 INP0 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"IIR1 INP0 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"IIR1", NULL, "IIR1 INP1 MUX"}, + {"IIR1 INP1 MUX", "DEC0", "ADC MUX0"}, + {"IIR1 INP1 MUX", "DEC1", "ADC MUX1"}, + {"IIR1 INP1 MUX", "DEC2", "ADC MUX2"}, + {"IIR1 INP1 MUX", "DEC3", "ADC MUX3"}, + {"IIR1 INP1 MUX", "DEC4", "ADC MUX4"}, + {"IIR1 INP1 MUX", "DEC5", "ADC MUX5"}, + {"IIR1 INP1 MUX", "DEC6", "ADC MUX6"}, + {"IIR1 INP1 MUX", "DEC7", "ADC MUX7"}, + {"IIR1 INP1 MUX", "DEC8", "ADC MUX8"}, + {"IIR1 INP1 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"IIR1 INP1 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"IIR1 INP1 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"IIR1 INP1 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"IIR1 INP1 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"IIR1 INP1 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"IIR1 INP1 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"IIR1 INP1 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"IIR1", NULL, "IIR1 INP2 MUX"}, + {"IIR1 INP2 MUX", "DEC0", "ADC MUX0"}, + {"IIR1 INP2 MUX", "DEC1", "ADC MUX1"}, + {"IIR1 INP2 MUX", "DEC2", "ADC MUX2"}, + {"IIR1 INP2 MUX", "DEC3", "ADC MUX3"}, + {"IIR1 INP2 MUX", "DEC4", "ADC MUX4"}, + {"IIR1 INP2 MUX", "DEC5", "ADC MUX5"}, + {"IIR1 INP2 MUX", "DEC6", "ADC MUX6"}, + {"IIR1 INP2 MUX", "DEC7", "ADC MUX7"}, + {"IIR1 INP2 MUX", "DEC8", "ADC MUX8"}, + {"IIR1 INP2 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"IIR1 INP2 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"IIR1 INP2 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"IIR1 INP2 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"IIR1 INP2 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"IIR1 INP2 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"IIR1 INP2 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"IIR1 INP2 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"IIR1", NULL, "IIR1 INP3 MUX"}, + {"IIR1 INP3 MUX", "DEC0", "ADC MUX0"}, + {"IIR1 INP3 MUX", "DEC1", "ADC MUX1"}, + {"IIR1 INP3 MUX", "DEC2", "ADC MUX2"}, + {"IIR1 INP3 MUX", "DEC3", "ADC MUX3"}, + {"IIR1 INP3 MUX", "DEC4", "ADC MUX4"}, + {"IIR1 INP3 MUX", "DEC5", "ADC MUX5"}, + {"IIR1 INP3 MUX", "DEC6", "ADC MUX6"}, + {"IIR1 INP3 MUX", "DEC7", "ADC MUX7"}, + {"IIR1 INP3 MUX", "DEC8", "ADC MUX8"}, + {"IIR1 INP3 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"IIR1 INP3 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"IIR1 INP3 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"IIR1 INP3 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"IIR1 INP3 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"IIR1 INP3 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"IIR1 INP3 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"IIR1 INP3 MUX", "RX7", "CDC_IF RX7 MUX"}, + + {"SRC0", NULL, "IIR0"}, + {"SRC1", NULL, "IIR1"}, + {"RX INT0 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT0 MIX2 INP", "SRC1", "SRC1"}, + {"RX INT1 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT1 MIX2 INP", "SRC1", "SRC1"}, + {"RX INT2 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT2 MIX2 INP", "SRC1", "SRC1"}, + {"RX INT3 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT3 MIX2 INP", "SRC1", "SRC1"}, + {"RX INT4 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT4 MIX2 INP", "SRC1", "SRC1"}, + {"RX INT7 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT7 MIX2 INP", "SRC1", "SRC1"}, + + /* Native clk main path routing */ + {"RX INT1_1 NATIVE MUX", "ON", "RX INT1_1 MIX1"}, + {"RX INT1_1 INTERP", NULL, "RX INT1_1 NATIVE MUX"}, + {"RX INT1_1 NATIVE MUX", NULL, "RX INT1 NATIVE SUPPLY"}, + + {"RX INT2_1 NATIVE MUX", "ON", "RX INT2_1 MIX1"}, + {"RX INT2_1 INTERP", NULL, "RX INT2_1 NATIVE MUX"}, + {"RX INT2_1 NATIVE MUX", NULL, "RX INT2 NATIVE SUPPLY"}, + + {"RX INT3_1 NATIVE MUX", "ON", "RX INT3_1 MIX1"}, + {"RX INT3_1 INTERP", NULL, "RX INT3_1 NATIVE MUX"}, + {"RX INT3_1 NATIVE MUX", NULL, "RX INT3 NATIVE SUPPLY"}, + + {"RX INT4_1 NATIVE MUX", "ON", "RX INT4_1 MIX1"}, + {"RX INT4_1 INTERP", NULL, "RX INT4_1 NATIVE MUX"}, + {"RX INT4_1 NATIVE MUX", NULL, "RX INT4 NATIVE SUPPLY"}, + + /* Native clk mix path routing */ + {"RX INT1_2 NATIVE MUX", "ON", "RX INT1_2 MUX"}, + {"RX INT1_2 INTERP", NULL, "RX INT1_2 NATIVE MUX"}, + {"RX INT1_2 NATIVE MUX", NULL, "RX INT1 NATIVE SUPPLY"}, + + {"RX INT2_2 NATIVE MUX", "ON", "RX INT2_2 MUX"}, + {"RX INT2_2 INTERP", NULL, "RX INT2_2 NATIVE MUX"}, + {"RX INT2_2 NATIVE MUX", NULL, "RX INT2 NATIVE SUPPLY"}, + + {"RX INT3_2 NATIVE MUX", "ON", "RX INT3_2 MUX"}, + {"RX INT3_2 INTERP", NULL, "RX INT3_2 NATIVE MUX"}, + {"RX INT3_2 NATIVE MUX", NULL, "RX INT3 NATIVE SUPPLY"}, + + {"RX INT4_2 NATIVE MUX", "ON", "RX INT4_2 MUX"}, + {"RX INT4_2 INTERP", NULL, "RX INT4_2 NATIVE MUX"}, + {"RX INT4_2 NATIVE MUX", NULL, "RX INT4 NATIVE SUPPLY"}, + + {"RX INT7_2 NATIVE MUX", "ON", "RX INT7_2 MUX"}, + {"RX INT7_2 INTERP", NULL, "RX INT7_2 NATIVE MUX"}, + {"RX INT7_2 NATIVE MUX", NULL, "RX INT7 NATIVE SUPPLY"}, + + {"RX INT8_2 NATIVE MUX", "ON", "RX INT8_2 MUX"}, + {"RX INT8_2 INTERP", NULL, "RX INT8_2 NATIVE MUX"}, + {"RX INT8_2 NATIVE MUX", NULL, "RX INT8 NATIVE SUPPLY"}, + + /* ASRC Routing */ + {"ASRC0 MUX", "ASRC_IN_HPHL", "RX INT1_2 INTERP"}, + {"RX INT1 SEC MIX", "HPHL Switch", "ASRC0 MUX"}, + + {"ASRC1 MUX", "ASRC_IN_HPHR", "RX INT2_2 INTERP"}, + {"RX INT2 SEC MIX", "HPHR Switch", "ASRC1 MUX"}, + + {"ASRC0 MUX", "ASRC_IN_LO1", "RX INT3_2 INTERP"}, + {"RX INT3 SEC MIX", "LO1 Switch", "ASRC0 MUX"}, + + {"ASRC1 MUX", "ASRC_IN_LO2", "RX INT4_2 INTERP"}, + {"RX INT4 SEC MIX", "LO2 Switch", "ASRC1 MUX"}, + + {"ASRC2 MUX", "ASRC_IN_SPKR1", "RX INT7_2 INTERP"}, + {"RX INT7 SEC MIX", NULL, "ASRC2 MUX"}, + + {"ASRC3 MUX", "ASRC_IN_SPKR2", "RX INT8_2 INTERP"}, + {"RX INT8 SEC MIX", NULL, "ASRC3 MUX"}, +}; + +#endif diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c new file mode 100644 index 000000000000..ca16ed8c8ae3 --- /dev/null +++ b/sound/soc/codecs/wcd934x/wcd934x.c @@ -0,0 +1,9938 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcd934x.h" +#include "wcd934x-mbhc.h" +#include "wcd934x-routing.h" +#include "wcd934x-dsp-cntl.h" +#include "../wcd9xxx-common-v2.h" +#include "../wcd9xxx-resmgr-v2.h" +#include "../wcdcal-hwdep.h" +#include "wcd934x-dsd.h" + +#define WCD934X_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\ + SNDRV_PCM_RATE_384000) +/* Fractional Rates */ +#define WCD934X_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_176400) + +#define WCD934X_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE) + +#define WCD934X_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +#define WCD934X_FORMATS_S16_LE (SNDRV_PCM_FMTBIT_S16_LE) + +/* Macros for packing register writes into a U32 */ +#define WCD934X_PACKED_REG_SIZE sizeof(u32) +#define WCD934X_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \ + do { \ + ((reg) = ((packed >> 16) & (0xffff))); \ + ((mask) = ((packed >> 8) & (0xff))); \ + ((val) = ((packed) & (0xff))); \ + } while (0) + +#define STRING(name) #name +#define WCD_DAPM_ENUM(name, reg, offset, text) \ +static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ +static const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_ENUM(STRING(name), name##_enum) + +#define WCD_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \ +static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ +static const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname) + +#define WCD_DAPM_MUX(name, shift, kctl) \ + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux) + +/* + * Timeout in milli seconds and it is the wait time for + * slim channel removal interrupt to receive. + */ +#define WCD934X_SLIM_CLOSE_TIMEOUT 1000 +#define WCD934X_SLIM_IRQ_OVERFLOW (1 << 0) +#define WCD934X_SLIM_IRQ_UNDERFLOW (1 << 1) +#define WCD934X_SLIM_IRQ_PORT_CLOSED (1 << 2) +#define WCD934X_MCLK_CLK_12P288MHZ 12288000 +#define WCD934X_MCLK_CLK_9P6MHZ 9600000 + +#define WCD934X_INTERP_MUX_NUM_INPUTS 3 +#define WCD934X_NUM_INTERPOLATORS 9 +#define WCD934X_NUM_DECIMATORS 9 +#define WCD934X_RX_PATH_CTL_OFFSET 20 + +#define BYTE_BIT_MASK(nr) (1 << ((nr) % BITS_PER_BYTE)) + +#define WCD934X_REG_BITS 8 +#define WCD934X_MAX_VALID_ADC_MUX 13 +#define WCD934X_INVALID_ADC_MUX 9 + +#define WCD934X_AMIC_PWR_LEVEL_LP 0 +#define WCD934X_AMIC_PWR_LEVEL_DEFAULT 1 +#define WCD934X_AMIC_PWR_LEVEL_HP 2 +#define WCD934X_AMIC_PWR_LVL_MASK 0x60 +#define WCD934X_AMIC_PWR_LVL_SHIFT 0x5 + +#define WCD934X_DEC_PWR_LVL_MASK 0x06 +#define WCD934X_DEC_PWR_LVL_LP 0x02 +#define WCD934X_DEC_PWR_LVL_HP 0x04 +#define WCD934X_DEC_PWR_LVL_DF 0x00 +#define WCD934X_STRING_LEN 100 + +#define WCD934X_CDC_SIDETONE_IIR_COEFF_MAX 5 +#define WCD934X_DIG_CORE_REG_MIN WCD934X_CDC_ANC0_CLK_RESET_CTL +#define WCD934X_DIG_CORE_REG_MAX 0xFFF + +#define WCD934X_MAX_MICBIAS 4 +#define DAPM_MICBIAS1_STANDALONE "MIC BIAS1 Standalone" +#define DAPM_MICBIAS2_STANDALONE "MIC BIAS2 Standalone" +#define DAPM_MICBIAS3_STANDALONE "MIC BIAS3 Standalone" +#define DAPM_MICBIAS4_STANDALONE "MIC BIAS4 Standalone" + +#define TX_HPF_CUT_OFF_FREQ_MASK 0x60 +#define CF_MIN_3DB_4HZ 0x0 +#define CF_MIN_3DB_75HZ 0x1 +#define CF_MIN_3DB_150HZ 0x2 + +#define CPE_ERR_WDOG_BITE BIT(0) +#define CPE_FATAL_IRQS CPE_ERR_WDOG_BITE + +#define WCD934X_MAD_AUDIO_FIRMWARE_PATH "wcd934x/wcd934x_mad_audio.bin" + +#define TAVIL_VERSION_ENTRY_SIZE 17 + +#define WCD934X_DIG_CORE_COLLAPSE_TIMER_MS (5 * 1000) + +enum { + POWER_COLLAPSE, + POWER_RESUME, +}; + +static int dig_core_collapse_enable = 1; +module_param(dig_core_collapse_enable, int, 0664); +MODULE_PARM_DESC(dig_core_collapse_enable, "enable/disable power gating"); + +/* dig_core_collapse timer in seconds */ +static int dig_core_collapse_timer = (WCD934X_DIG_CORE_COLLAPSE_TIMER_MS/1000); +module_param(dig_core_collapse_timer, int, 0664); +MODULE_PARM_DESC(dig_core_collapse_timer, "timer for power gating"); + +#define TAVIL_HPH_REG_RANGE_1 (WCD934X_HPH_R_DAC_CTL - WCD934X_HPH_CNP_EN + 1) +#define TAVIL_HPH_REG_RANGE_2 (WCD934X_HPH_NEW_ANA_HPH3 -\ + WCD934X_HPH_NEW_ANA_HPH2 + 1) +#define TAVIL_HPH_REG_RANGE_3 (WCD934X_HPH_NEW_INT_PA_RDAC_MISC3 -\ + WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL + 1) +#define TAVIL_HPH_TOTAL_REG (TAVIL_HPH_REG_RANGE_1 + TAVIL_HPH_REG_RANGE_2 +\ + TAVIL_HPH_REG_RANGE_3) + +enum { + VI_SENSE_1, + VI_SENSE_2, + AUDIO_NOMINAL, + HPH_PA_DELAY, + CLSH_Z_CONFIG, + ANC_MIC_AMIC1, + ANC_MIC_AMIC2, + ANC_MIC_AMIC3, + ANC_MIC_AMIC4, +}; + +enum { + AIF1_PB = 0, + AIF1_CAP, + AIF2_PB, + AIF2_CAP, + AIF3_PB, + AIF3_CAP, + AIF4_PB, + AIF4_VIFEED, + AIF4_MAD_TX, + NUM_CODEC_DAIS, +}; + +enum { + INTn_1_INP_SEL_ZERO = 0, + INTn_1_INP_SEL_DEC0, + INTn_1_INP_SEL_DEC1, + INTn_1_INP_SEL_IIR0, + INTn_1_INP_SEL_IIR1, + INTn_1_INP_SEL_RX0, + INTn_1_INP_SEL_RX1, + INTn_1_INP_SEL_RX2, + INTn_1_INP_SEL_RX3, + INTn_1_INP_SEL_RX4, + INTn_1_INP_SEL_RX5, + INTn_1_INP_SEL_RX6, + INTn_1_INP_SEL_RX7, +}; + +enum { + INTn_2_INP_SEL_ZERO = 0, + INTn_2_INP_SEL_RX0, + INTn_2_INP_SEL_RX1, + INTn_2_INP_SEL_RX2, + INTn_2_INP_SEL_RX3, + INTn_2_INP_SEL_RX4, + INTn_2_INP_SEL_RX5, + INTn_2_INP_SEL_RX6, + INTn_2_INP_SEL_RX7, + INTn_2_INP_SEL_PROXIMITY, +}; + +enum { + INTERP_MAIN_PATH, + INTERP_MIX_PATH, +}; + +struct tavil_idle_detect_config { + u8 hph_idle_thr; + u8 hph_idle_detect_en; +}; + +struct tavil_cpr_reg_defaults { + int wr_data; + int wr_addr; +}; + +struct interp_sample_rate { + int sample_rate; + int rate_val; +}; + +static struct interp_sample_rate sr_val_tbl[] = { + {8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5}, + {192000, 0x6}, {384000, 0x7}, {44100, 0x9}, {88200, 0xA}, + {176400, 0xB}, {352800, 0xC}, +}; + +static const struct wcd9xxx_ch tavil_rx_chs[WCD934X_RX_MAX] = { + WCD9XXX_CH(WCD934X_RX_PORT_START_NUMBER, 0), + WCD9XXX_CH(WCD934X_RX_PORT_START_NUMBER + 1, 1), + WCD9XXX_CH(WCD934X_RX_PORT_START_NUMBER + 2, 2), + WCD9XXX_CH(WCD934X_RX_PORT_START_NUMBER + 3, 3), + WCD9XXX_CH(WCD934X_RX_PORT_START_NUMBER + 4, 4), + WCD9XXX_CH(WCD934X_RX_PORT_START_NUMBER + 5, 5), + WCD9XXX_CH(WCD934X_RX_PORT_START_NUMBER + 6, 6), + WCD9XXX_CH(WCD934X_RX_PORT_START_NUMBER + 7, 7), +}; + +static const struct wcd9xxx_ch tavil_tx_chs[WCD934X_TX_MAX] = { + WCD9XXX_CH(0, 0), + WCD9XXX_CH(1, 1), + WCD9XXX_CH(2, 2), + WCD9XXX_CH(3, 3), + WCD9XXX_CH(4, 4), + WCD9XXX_CH(5, 5), + WCD9XXX_CH(6, 6), + WCD9XXX_CH(7, 7), + WCD9XXX_CH(8, 8), + WCD9XXX_CH(9, 9), + WCD9XXX_CH(10, 10), + WCD9XXX_CH(11, 11), + WCD9XXX_CH(12, 12), + WCD9XXX_CH(13, 13), + WCD9XXX_CH(14, 14), + WCD9XXX_CH(15, 15), +}; + +static const u32 vport_slim_check_table[NUM_CODEC_DAIS] = { + 0, /* AIF1_PB */ + BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX), /* AIF1_CAP */ + 0, /* AIF2_PB */ + BIT(AIF1_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX), /* AIF2_CAP */ + 0, /* AIF3_PB */ + BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF4_MAD_TX), /* AIF3_CAP */ + 0, /* AIF4_PB */ +}; + +/* Codec supports 2 IIR filters */ +enum { + IIR0 = 0, + IIR1, + IIR_MAX, +}; + +/* Each IIR has 5 Filter Stages */ +enum { + BAND1 = 0, + BAND2, + BAND3, + BAND4, + BAND5, + BAND_MAX, +}; + +enum { + COMPANDER_1, /* HPH_L */ + COMPANDER_2, /* HPH_R */ + COMPANDER_3, /* LO1_DIFF */ + COMPANDER_4, /* LO2_DIFF */ + COMPANDER_5, /* LO3_SE - not used in Tavil */ + COMPANDER_6, /* LO4_SE - not used in Tavil */ + COMPANDER_7, /* SWR SPK CH1 */ + COMPANDER_8, /* SWR SPK CH2 */ + COMPANDER_MAX, +}; + +enum { + ASRC_IN_HPHL, + ASRC_IN_LO1, + ASRC_IN_HPHR, + ASRC_IN_LO2, + ASRC_IN_SPKR1, + ASRC_IN_SPKR2, + ASRC_INVALID, +}; + +enum { + ASRC0, + ASRC1, + ASRC2, + ASRC3, + ASRC_MAX, +}; + +enum { + CONV_88P2K_TO_384K, + CONV_96K_TO_352P8K, + CONV_352P8K_TO_384K, + CONV_384K_TO_352P8K, + CONV_384K_TO_384K, + CONV_96K_TO_384K, +}; + +static struct afe_param_slimbus_slave_port_cfg tavil_slimbus_slave_port_cfg = { + .minor_version = 1, + .slimbus_dev_id = AFE_SLIMBUS_DEVICE_1, + .slave_dev_pgd_la = 0, + .slave_dev_intfdev_la = 0, + .bit_width = 16, + .data_format = 0, + .num_channels = 1 +}; + +static struct afe_param_cdc_reg_page_cfg tavil_cdc_reg_page_cfg = { + .minor_version = AFE_API_VERSION_CDC_REG_PAGE_CFG, + .enable = 1, + .proc_id = AFE_CDC_REG_PAGE_ASSIGN_PROC_ID_1, +}; + +static struct afe_param_cdc_reg_cfg audio_reg_cfg[] = { + { + 1, + (WCD934X_REGISTER_START_OFFSET + WCD934X_SOC_MAD_MAIN_CTL_1), + HW_MAD_AUDIO_ENABLE, 0x1, WCD934X_REG_BITS, 0 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + WCD934X_SOC_MAD_AUDIO_CTL_3), + HW_MAD_AUDIO_SLEEP_TIME, 0xF, WCD934X_REG_BITS, 0 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + WCD934X_SOC_MAD_AUDIO_CTL_4), + HW_MAD_TX_AUDIO_SWITCH_OFF, 0x1, WCD934X_REG_BITS, 0 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + WCD934X_INTR_CFG), + MAD_AUDIO_INT_DEST_SELECT_REG, 0x2, WCD934X_REG_BITS, 0 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + WCD934X_INTR_PIN2_MASK3), + MAD_AUDIO_INT_MASK_REG, 0x1, WCD934X_REG_BITS, 0 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + WCD934X_INTR_PIN2_STATUS3), + MAD_AUDIO_INT_STATUS_REG, 0x1, WCD934X_REG_BITS, 0 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + WCD934X_INTR_PIN2_CLEAR3), + MAD_AUDIO_INT_CLEAR_REG, 0x1, WCD934X_REG_BITS, 0 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + WCD934X_SB_PGD_PORT_TX_BASE), + SB_PGD_PORT_TX_WATERMARK_N, 0x1E, WCD934X_REG_BITS, 0x1 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + WCD934X_SB_PGD_PORT_TX_BASE), + SB_PGD_PORT_TX_ENABLE_N, 0x1, WCD934X_REG_BITS, 0x1 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + WCD934X_SB_PGD_PORT_RX_BASE), + SB_PGD_PORT_RX_WATERMARK_N, 0x1E, WCD934X_REG_BITS, 0x1 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + WCD934X_SB_PGD_PORT_RX_BASE), + SB_PGD_PORT_RX_ENABLE_N, 0x1, WCD934X_REG_BITS, 0x1 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + + WCD934X_CDC_ANC0_IIR_ADAPT_CTL), + AANC_FF_GAIN_ADAPTIVE, 0x4, WCD934X_REG_BITS, 0 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + + WCD934X_CDC_ANC0_IIR_ADAPT_CTL), + AANC_FFGAIN_ADAPTIVE_EN, 0x8, WCD934X_REG_BITS, 0 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + + WCD934X_CDC_ANC0_FF_A_GAIN_CTL), + AANC_GAIN_CONTROL, 0xFF, WCD934X_REG_BITS, 0 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + + SB_PGD_TX_PORT_MULTI_CHANNEL_0(0)), + SB_PGD_TX_PORTn_MULTI_CHNL_0, 0xFF, WCD934X_REG_BITS, 0x4 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + + SB_PGD_TX_PORT_MULTI_CHANNEL_1(0)), + SB_PGD_TX_PORTn_MULTI_CHNL_1, 0xFF, WCD934X_REG_BITS, 0x4 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + + SB_PGD_RX_PORT_MULTI_CHANNEL_0(0x180, 0)), + SB_PGD_RX_PORTn_MULTI_CHNL_0, 0xFF, WCD934X_REG_BITS, 0x4 + }, + { + 1, + (WCD934X_REGISTER_START_OFFSET + + SB_PGD_RX_PORT_MULTI_CHANNEL_0(0x181, 0)), + SB_PGD_RX_PORTn_MULTI_CHNL_1, 0xFF, WCD934X_REG_BITS, 0x4 + }, +}; + +static struct afe_param_cdc_reg_cfg_data tavil_audio_reg_cfg = { + .num_registers = ARRAY_SIZE(audio_reg_cfg), + .reg_data = audio_reg_cfg, +}; + +static struct afe_param_id_cdc_aanc_version tavil_cdc_aanc_version = { + .cdc_aanc_minor_version = AFE_API_VERSION_CDC_AANC_VERSION, + .aanc_hw_version = AANC_HW_BLOCK_VERSION_2, +}; + +static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); +static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); +static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); + +#define WCD934X_TX_UNMUTE_DELAY_MS 40 + +static int tx_unmute_delay = WCD934X_TX_UNMUTE_DELAY_MS; +module_param(tx_unmute_delay, int, 0664); +MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path"); + +static void tavil_codec_set_tx_hold(struct snd_soc_codec *, u16, bool); + +/* Hold instance to soundwire platform device */ +struct tavil_swr_ctrl_data { + struct platform_device *swr_pdev; +}; + +struct wcd_swr_ctrl_platform_data { + void *handle; /* holds codec private data */ + int (*read)(void *handle, int reg); + int (*write)(void *handle, int reg, int val); + int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); + int (*clk)(void *handle, bool enable); + int (*handle_irq)(void *handle, + irqreturn_t (*swrm_irq_handler)(int irq, void *data), + void *swrm_handle, int action); +}; + +/* Holds all Soundwire and speaker related information */ +struct wcd934x_swr { + struct tavil_swr_ctrl_data *ctrl_data; + struct wcd_swr_ctrl_platform_data plat_data; + struct mutex read_mutex; + struct mutex write_mutex; + struct mutex clk_mutex; + int spkr_gain_offset; + int spkr_mode; + int clk_users; + int rx_7_count; + int rx_8_count; +}; + +struct tx_mute_work { + struct tavil_priv *tavil; + u8 decimator; + struct delayed_work dwork; +}; + +#define WCD934X_SPK_ANC_EN_DELAY_MS 350 +static int spk_anc_en_delay = WCD934X_SPK_ANC_EN_DELAY_MS; +module_param(spk_anc_en_delay, int, 0664); +MODULE_PARM_DESC(spk_anc_en_delay, "delay to enable anc in speaker path"); + +struct spk_anc_work { + struct tavil_priv *tavil; + struct delayed_work dwork; +}; + +struct hpf_work { + struct tavil_priv *tavil; + u8 decimator; + u8 hpf_cut_off_freq; + struct delayed_work dwork; +}; + +struct tavil_priv { + struct device *dev; + struct wcd9xxx *wcd9xxx; + struct snd_soc_codec *codec; + u32 rx_bias_count; + s32 dmic_0_1_clk_cnt; + s32 dmic_2_3_clk_cnt; + s32 dmic_4_5_clk_cnt; + s32 micb_ref[TAVIL_MAX_MICBIAS]; + s32 pullup_ref[TAVIL_MAX_MICBIAS]; + + /* ANC related */ + u32 anc_slot; + bool anc_func; + + /* compander */ + int comp_enabled[COMPANDER_MAX]; + int ear_spkr_gain; + + /* class h specific data */ + struct wcd_clsh_cdc_data clsh_d; + /* Tavil Interpolator Mode Select for EAR, HPH_L and HPH_R */ + u32 hph_mode; + + /* Mad switch reference count */ + int mad_switch_cnt; + + /* track tavil interface type */ + u8 intf_type; + + /* to track the status */ + unsigned long status_mask; + + struct afe_param_cdc_slimbus_slave_cfg slimbus_slave_cfg; + + /* num of slim ports required */ + struct wcd9xxx_codec_dai_data dai[NUM_CODEC_DAIS]; + /* Port values for Rx and Tx codec_dai */ + unsigned int rx_port_value[WCD934X_RX_MAX]; + unsigned int tx_port_value; + + struct wcd9xxx_resmgr_v2 *resmgr; + struct wcd934x_swr swr; + struct mutex micb_lock; + + struct delayed_work power_gate_work; + struct mutex power_lock; + + struct clk *wcd_ext_clk; + + /* mbhc module */ + struct wcd934x_mbhc *mbhc; + + struct mutex codec_mutex; + struct work_struct tavil_add_child_devices_work; + struct hpf_work tx_hpf_work[WCD934X_NUM_DECIMATORS]; + struct tx_mute_work tx_mute_dwork[WCD934X_NUM_DECIMATORS]; + struct spk_anc_work spk_anc_dwork; + + unsigned int vi_feed_value; + + /* DSP control */ + struct wcd_dsp_cntl *wdsp_cntl; + + /* cal info for codec */ + struct fw_info *fw_data; + + /* Entry for version info */ + struct snd_info_entry *entry; + struct snd_info_entry *version_entry; + + /* SVS voting related */ + struct mutex svs_mutex; + int svs_ref_cnt; + + int native_clk_users; + /* ASRC users count */ + int asrc_users[ASRC_MAX]; + int asrc_output_mode[ASRC_MAX]; + /* Main path clock users count */ + int main_clk_users[WCD934X_NUM_INTERPOLATORS]; + struct tavil_dsd_config *dsd_config; + struct tavil_idle_detect_config idle_det_cfg; + + int power_active_ref; + int sidetone_coeff_array[IIR_MAX][BAND_MAX] + [WCD934X_CDC_SIDETONE_IIR_COEFF_MAX]; +}; + +static const struct tavil_reg_mask_val tavil_spkr_default[] = { + {WCD934X_CDC_COMPANDER7_CTL3, 0x80, 0x80}, + {WCD934X_CDC_COMPANDER8_CTL3, 0x80, 0x80}, + {WCD934X_CDC_COMPANDER7_CTL7, 0x01, 0x01}, + {WCD934X_CDC_COMPANDER8_CTL7, 0x01, 0x01}, + {WCD934X_CDC_BOOST0_BOOST_CTL, 0x7C, 0x50}, + {WCD934X_CDC_BOOST1_BOOST_CTL, 0x7C, 0x50}, +}; + +static const struct tavil_reg_mask_val tavil_spkr_mode1[] = { + {WCD934X_CDC_COMPANDER7_CTL3, 0x80, 0x00}, + {WCD934X_CDC_COMPANDER8_CTL3, 0x80, 0x00}, + {WCD934X_CDC_COMPANDER7_CTL7, 0x01, 0x00}, + {WCD934X_CDC_COMPANDER8_CTL7, 0x01, 0x00}, + {WCD934X_CDC_BOOST0_BOOST_CTL, 0x7C, 0x44}, + {WCD934X_CDC_BOOST1_BOOST_CTL, 0x7C, 0x44}, +}; + +static int __tavil_enable_efuse_sensing(struct tavil_priv *tavil); + +/** + * tavil_set_spkr_gain_offset - offset the speaker path + * gain with the given offset value. + * + * @codec: codec instance + * @offset: Indicates speaker path gain offset value. + * + * Returns 0 on success or -EINVAL on error. + */ +int tavil_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset) +{ + struct tavil_priv *priv = snd_soc_codec_get_drvdata(codec); + + if (!priv) + return -EINVAL; + + priv->swr.spkr_gain_offset = offset; + return 0; +} +EXPORT_SYMBOL(tavil_set_spkr_gain_offset); + +/** + * tavil_set_spkr_mode - Configures speaker compander and smartboost + * settings based on speaker mode. + * + * @codec: codec instance + * @mode: Indicates speaker configuration mode. + * + * Returns 0 on success or -EINVAL on error. + */ +int tavil_set_spkr_mode(struct snd_soc_codec *codec, int mode) +{ + struct tavil_priv *priv = snd_soc_codec_get_drvdata(codec); + int i; + const struct tavil_reg_mask_val *regs; + int size; + + if (!priv) + return -EINVAL; + + switch (mode) { + case WCD934X_SPKR_MODE_1: + regs = tavil_spkr_mode1; + size = ARRAY_SIZE(tavil_spkr_mode1); + break; + default: + regs = tavil_spkr_default; + size = ARRAY_SIZE(tavil_spkr_default); + break; + } + + priv->swr.spkr_mode = mode; + for (i = 0; i < size; i++) + snd_soc_update_bits(codec, regs[i].reg, + regs[i].mask, regs[i].val); + return 0; +} +EXPORT_SYMBOL(tavil_set_spkr_mode); + +/** + * tavil_get_afe_config - returns specific codec configuration to afe to write + * + * @codec: codec instance + * @config_type: Indicates type of configuration to write. + */ +void *tavil_get_afe_config(struct snd_soc_codec *codec, + enum afe_config_type config_type) +{ + struct tavil_priv *priv = snd_soc_codec_get_drvdata(codec); + + switch (config_type) { + case AFE_SLIMBUS_SLAVE_CONFIG: + return &priv->slimbus_slave_cfg; + case AFE_CDC_REGISTERS_CONFIG: + return &tavil_audio_reg_cfg; + case AFE_SLIMBUS_SLAVE_PORT_CONFIG: + return &tavil_slimbus_slave_port_cfg; + case AFE_AANC_VERSION: + return &tavil_cdc_aanc_version; + case AFE_CDC_REGISTER_PAGE_CONFIG: + return &tavil_cdc_reg_page_cfg; + default: + dev_info(codec->dev, "%s: Unknown config_type 0x%x\n", + __func__, config_type); + return NULL; + } +} +EXPORT_SYMBOL(tavil_get_afe_config); + +static bool is_tavil_playback_dai(int dai_id) +{ + if ((dai_id == AIF1_PB) || (dai_id == AIF2_PB) || + (dai_id == AIF3_PB) || (dai_id == AIF4_PB)) + return true; + + return false; +} + +static int tavil_find_playback_dai_id_for_port(int port_id, + struct tavil_priv *tavil) +{ + struct wcd9xxx_codec_dai_data *dai; + struct wcd9xxx_ch *ch; + int i, slv_port_id; + + for (i = AIF1_PB; i < NUM_CODEC_DAIS; i++) { + if (!is_tavil_playback_dai(i)) + continue; + + dai = &tavil->dai[i]; + list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) { + slv_port_id = wcd9xxx_get_slave_port(ch->ch_num); + if ((slv_port_id > 0) && (slv_port_id == port_id)) + return i; + } + } + + return -EINVAL; +} + +static void tavil_vote_svs(struct tavil_priv *tavil, bool vote) +{ + struct wcd9xxx *wcd9xxx; + + wcd9xxx = tavil->wcd9xxx; + + mutex_lock(&tavil->svs_mutex); + if (vote) { + tavil->svs_ref_cnt++; + if (tavil->svs_ref_cnt == 1) + regmap_update_bits(wcd9xxx->regmap, + WCD934X_CPE_SS_PWR_SYS_PSTATE_CTL_0, + 0x01, 0x01); + } else { + /* Do not decrement ref count if it is already 0 */ + if (tavil->svs_ref_cnt == 0) + goto done; + + tavil->svs_ref_cnt--; + if (tavil->svs_ref_cnt == 0) + regmap_update_bits(wcd9xxx->regmap, + WCD934X_CPE_SS_PWR_SYS_PSTATE_CTL_0, + 0x01, 0x00); + } +done: + dev_dbg(tavil->dev, "%s: vote = %s, updated ref cnt = %u\n", __func__, + vote ? "vote" : "Unvote", tavil->svs_ref_cnt); + mutex_unlock(&tavil->svs_mutex); +} + +static int tavil_get_anc_slot(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = tavil->anc_slot; + return 0; +} + +static int tavil_put_anc_slot(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + tavil->anc_slot = ucontrol->value.integer.value[0]; + return 0; +} + +static int tavil_get_anc_func(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = (tavil->anc_func == true ? 1 : 0); + return 0; +} + +static int tavil_put_anc_func(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + + mutex_lock(&tavil->codec_mutex); + tavil->anc_func = (!ucontrol->value.integer.value[0] ? false : true); + dev_dbg(codec->dev, "%s: anc_func %x", __func__, tavil->anc_func); + + if (tavil->anc_func == true) { + snd_soc_dapm_enable_pin(dapm, "ANC EAR PA"); + snd_soc_dapm_enable_pin(dapm, "ANC EAR"); + snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHL PA"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHR PA"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHL"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHR"); + snd_soc_dapm_disable_pin(dapm, "EAR PA"); + snd_soc_dapm_disable_pin(dapm, "EAR"); + snd_soc_dapm_disable_pin(dapm, "HPHL PA"); + snd_soc_dapm_disable_pin(dapm, "HPHR PA"); + snd_soc_dapm_disable_pin(dapm, "HPHL"); + snd_soc_dapm_disable_pin(dapm, "HPHR"); + } else { + snd_soc_dapm_disable_pin(dapm, "ANC EAR PA"); + snd_soc_dapm_disable_pin(dapm, "ANC EAR"); + snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHL"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHR"); + snd_soc_dapm_enable_pin(dapm, "EAR PA"); + snd_soc_dapm_enable_pin(dapm, "EAR"); + snd_soc_dapm_enable_pin(dapm, "HPHL"); + snd_soc_dapm_enable_pin(dapm, "HPHR"); + snd_soc_dapm_enable_pin(dapm, "HPHL PA"); + snd_soc_dapm_enable_pin(dapm, "HPHR PA"); + } + mutex_unlock(&tavil->codec_mutex); + + snd_soc_dapm_sync(dapm); + return 0; +} + +static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + const char *filename; + const struct firmware *fw; + int i; + int ret = 0; + int num_anc_slots; + struct wcd9xxx_anc_header *anc_head; + struct firmware_cal *hwdep_cal = NULL; + u32 anc_writes_size = 0; + u32 anc_cal_size = 0; + int anc_size_remaining; + u32 *anc_ptr; + u16 reg; + u8 mask, val; + size_t cal_size; + const void *data; + + if (!tavil->anc_func) + return 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + hwdep_cal = wcdcal_get_fw_cal(tavil->fw_data, WCD9XXX_ANC_CAL); + if (hwdep_cal) { + data = hwdep_cal->data; + cal_size = hwdep_cal->size; + dev_dbg(codec->dev, "%s: using hwdep calibration, cal_size %zd", + __func__, cal_size); + } else { + filename = "WCD934X/WCD934X_anc.bin"; + ret = request_firmware(&fw, filename, codec->dev); + if (ret < 0) { + dev_err(codec->dev, "%s: Failed to acquire ANC data: %d\n", + __func__, ret); + return ret; + } + if (!fw) { + dev_err(codec->dev, "%s: Failed to get anc fw\n", + __func__); + return -ENODEV; + } + data = fw->data; + cal_size = fw->size; + dev_dbg(codec->dev, "%s: using request_firmware calibration\n", + __func__); + } + if (cal_size < sizeof(struct wcd9xxx_anc_header)) { + dev_err(codec->dev, "%s: Invalid cal_size %zd\n", + __func__, cal_size); + ret = -EINVAL; + goto err; + } + /* First number is the number of register writes */ + anc_head = (struct wcd9xxx_anc_header *)(data); + anc_ptr = (u32 *)(data + sizeof(struct wcd9xxx_anc_header)); + anc_size_remaining = cal_size - + sizeof(struct wcd9xxx_anc_header); + num_anc_slots = anc_head->num_anc_slots; + + if (tavil->anc_slot >= num_anc_slots) { + dev_err(codec->dev, "%s: Invalid ANC slot selected\n", + __func__); + ret = -EINVAL; + goto err; + } + for (i = 0; i < num_anc_slots; i++) { + if (anc_size_remaining < WCD934X_PACKED_REG_SIZE) { + dev_err(codec->dev, "%s: Invalid register format\n", + __func__); + ret = -EINVAL; + goto err; + } + anc_writes_size = (u32)(*anc_ptr); + anc_size_remaining -= sizeof(u32); + anc_ptr += 1; + + if ((anc_writes_size * WCD934X_PACKED_REG_SIZE) > + anc_size_remaining) { + dev_err(codec->dev, "%s: Invalid register format\n", + __func__); + ret = -EINVAL; + goto err; + } + + if (tavil->anc_slot == i) + break; + + anc_size_remaining -= (anc_writes_size * + WCD934X_PACKED_REG_SIZE); + anc_ptr += anc_writes_size; + } + if (i == num_anc_slots) { + dev_err(codec->dev, "%s: Selected ANC slot not present\n", + __func__); + ret = -EINVAL; + goto err; + } + + anc_cal_size = anc_writes_size; + for (i = 0; i < anc_writes_size; i++) { + WCD934X_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val); + snd_soc_write(codec, reg, (val & mask)); + } + + /* Rate converter clk enable and set bypass mode */ + if (!strcmp(w->name, "RX INT0 DAC") || + !strcmp(w->name, "RX INT1 DAC") || + !strcmp(w->name, "ANC SPK1 PA")) { + snd_soc_update_bits(codec, + WCD934X_CDC_ANC0_RC_COMMON_CTL, + 0x05, 0x05); + if (!strcmp(w->name, "RX INT1 DAC")) { + snd_soc_update_bits(codec, + WCD934X_CDC_ANC0_FIFO_COMMON_CTL, + 0x66, 0x66); + } + } else if (!strcmp(w->name, "RX INT2 DAC")) { + snd_soc_update_bits(codec, + WCD934X_CDC_ANC1_RC_COMMON_CTL, + 0x05, 0x05); + snd_soc_update_bits(codec, + WCD934X_CDC_ANC1_FIFO_COMMON_CTL, + 0x66, 0x66); + } + if (!strcmp(w->name, "RX INT1 DAC")) + snd_soc_update_bits(codec, + WCD934X_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x08); + else if (!strcmp(w->name, "RX INT2 DAC")) + snd_soc_update_bits(codec, + WCD934X_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x08); + + if (!hwdep_cal) + release_firmware(fw); + break; + + case SND_SOC_DAPM_POST_PMU: + if (!strcmp(w->name, "ANC HPHL PA") || + !strcmp(w->name, "ANC HPHR PA")) { + /* Remove ANC Rx from reset */ + snd_soc_update_bits(codec, + WCD934X_CDC_ANC0_CLK_RESET_CTL, + 0x08, 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_ANC1_CLK_RESET_CTL, + 0x08, 0x00); + } + + break; + + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, WCD934X_CDC_ANC0_RC_COMMON_CTL, + 0x05, 0x00); + if (!strcmp(w->name, "ANC EAR PA") || + !strcmp(w->name, "ANC SPK1 PA") || + !strcmp(w->name, "ANC HPHL PA")) { + snd_soc_update_bits(codec, WCD934X_CDC_ANC0_MODE_1_CTL, + 0x30, 0x00); + msleep(50); + snd_soc_update_bits(codec, WCD934X_CDC_ANC0_MODE_1_CTL, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_ANC0_CLK_RESET_CTL, + 0x38, 0x38); + snd_soc_update_bits(codec, + WCD934X_CDC_ANC0_CLK_RESET_CTL, + 0x07, 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_ANC0_CLK_RESET_CTL, + 0x38, 0x00); + } else if (!strcmp(w->name, "ANC HPHR PA")) { + snd_soc_update_bits(codec, WCD934X_CDC_ANC1_MODE_1_CTL, + 0x30, 0x00); + msleep(50); + snd_soc_update_bits(codec, WCD934X_CDC_ANC1_MODE_1_CTL, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_ANC1_CLK_RESET_CTL, + 0x38, 0x38); + snd_soc_update_bits(codec, + WCD934X_CDC_ANC1_CLK_RESET_CTL, + 0x07, 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_ANC1_CLK_RESET_CTL, + 0x38, 0x00); + } + break; + } + + return 0; +err: + if (!hwdep_cal) + release_firmware(fw); + return ret; +} + +static int tavil_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = tavil_p->vi_feed_value; + + return 0; +} + +static int tavil_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); + struct soc_multi_mixer_control *mixer = + ((struct soc_multi_mixer_control *)kcontrol->private_value); + u32 dai_id = widget->shift; + u32 port_id = mixer->shift; + u32 enable = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: enable: %d, port_id:%d, dai_id: %d\n", + __func__, enable, port_id, dai_id); + + tavil_p->vi_feed_value = ucontrol->value.integer.value[0]; + + mutex_lock(&tavil_p->codec_mutex); + if (enable) { + if (port_id == WCD934X_TX14 && !test_bit(VI_SENSE_1, + &tavil_p->status_mask)) { + list_add_tail(&core->tx_chs[WCD934X_TX14].list, + &tavil_p->dai[dai_id].wcd9xxx_ch_list); + set_bit(VI_SENSE_1, &tavil_p->status_mask); + } + if (port_id == WCD934X_TX15 && !test_bit(VI_SENSE_2, + &tavil_p->status_mask)) { + list_add_tail(&core->tx_chs[WCD934X_TX15].list, + &tavil_p->dai[dai_id].wcd9xxx_ch_list); + set_bit(VI_SENSE_2, &tavil_p->status_mask); + } + } else { + if (port_id == WCD934X_TX14 && test_bit(VI_SENSE_1, + &tavil_p->status_mask)) { + list_del_init(&core->tx_chs[WCD934X_TX14].list); + clear_bit(VI_SENSE_1, &tavil_p->status_mask); + } + if (port_id == WCD934X_TX15 && test_bit(VI_SENSE_2, + &tavil_p->status_mask)) { + list_del_init(&core->tx_chs[WCD934X_TX15].list); + clear_bit(VI_SENSE_2, &tavil_p->status_mask); + } + } + mutex_unlock(&tavil_p->codec_mutex); + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL); + + return 0; +} + +static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = tavil_p->tx_port_value; + return 0; +} + +static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); + struct snd_soc_dapm_update *update = NULL; + struct soc_multi_mixer_control *mixer = + ((struct soc_multi_mixer_control *)kcontrol->private_value); + u32 dai_id = widget->shift; + u32 port_id = mixer->shift; + u32 enable = ucontrol->value.integer.value[0]; + u32 vtable; + + dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", + __func__, + widget->name, ucontrol->id.name, tavil_p->tx_port_value, + widget->shift, ucontrol->value.integer.value[0]); + + mutex_lock(&tavil_p->codec_mutex); + if (dai_id >= ARRAY_SIZE(vport_slim_check_table)) { + dev_err(codec->dev, "%s: dai_id: %d, out of bounds\n", + __func__, dai_id); + mutex_unlock(&tavil_p->codec_mutex); + return -EINVAL; + } + vtable = vport_slim_check_table[dai_id]; + + switch (dai_id) { + case AIF1_CAP: + case AIF2_CAP: + case AIF3_CAP: + /* only add to the list if value not set */ + if (enable && !(tavil_p->tx_port_value & 1 << port_id)) { + if (wcd9xxx_tx_vport_validation(vtable, port_id, + tavil_p->dai, NUM_CODEC_DAIS)) { + dev_dbg(codec->dev, "%s: TX%u is used by other virtual port\n", + __func__, port_id); + mutex_unlock(&tavil_p->codec_mutex); + return 0; + } + tavil_p->tx_port_value |= 1 << port_id; + list_add_tail(&core->tx_chs[port_id].list, + &tavil_p->dai[dai_id].wcd9xxx_ch_list); + } else if (!enable && (tavil_p->tx_port_value & + 1 << port_id)) { + tavil_p->tx_port_value &= ~(1 << port_id); + list_del_init(&core->tx_chs[port_id].list); + } else { + if (enable) + dev_dbg(codec->dev, "%s: TX%u port is used by\n" + "this virtual port\n", + __func__, port_id); + else + dev_dbg(codec->dev, "%s: TX%u port is not used by\n" + "this virtual port\n", + __func__, port_id); + /* avoid update power function */ + mutex_unlock(&tavil_p->codec_mutex); + return 0; + } + break; + case AIF4_MAD_TX: + break; + default: + dev_err(codec->dev, "Unknown AIF %d\n", dai_id); + mutex_unlock(&tavil_p->codec_mutex); + return -EINVAL; + } + dev_dbg(codec->dev, "%s: name %s sname %s updated value %u shift %d\n", + __func__, widget->name, widget->sname, tavil_p->tx_port_value, + widget->shift); + + mutex_unlock(&tavil_p->codec_mutex); + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update); + + return 0; +} + +static int slim_rx_mux_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = + tavil_p->rx_port_value[widget->shift]; + return 0; +} + +static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + unsigned int rx_port_value; + u32 port_id = widget->shift; + + tavil_p->rx_port_value[port_id] = ucontrol->value.enumerated.item[0]; + rx_port_value = tavil_p->rx_port_value[port_id]; + + mutex_lock(&tavil_p->codec_mutex); + dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", + __func__, widget->name, ucontrol->id.name, + rx_port_value, widget->shift, + ucontrol->value.integer.value[0]); + + /* value need to match the Virtual port and AIF number */ + switch (rx_port_value) { + case 0: + list_del_init(&core->rx_chs[port_id].list); + break; + case 1: + if (wcd9xxx_rx_vport_validation(port_id + + WCD934X_RX_PORT_START_NUMBER, + &tavil_p->dai[AIF1_PB].wcd9xxx_ch_list)) { + dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + __func__, port_id); + goto rtn; + } + list_add_tail(&core->rx_chs[port_id].list, + &tavil_p->dai[AIF1_PB].wcd9xxx_ch_list); + break; + case 2: + if (wcd9xxx_rx_vport_validation(port_id + + WCD934X_RX_PORT_START_NUMBER, + &tavil_p->dai[AIF2_PB].wcd9xxx_ch_list)) { + dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + __func__, port_id); + goto rtn; + } + list_add_tail(&core->rx_chs[port_id].list, + &tavil_p->dai[AIF2_PB].wcd9xxx_ch_list); + break; + case 3: + if (wcd9xxx_rx_vport_validation(port_id + + WCD934X_RX_PORT_START_NUMBER, + &tavil_p->dai[AIF3_PB].wcd9xxx_ch_list)) { + dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + __func__, port_id); + goto rtn; + } + list_add_tail(&core->rx_chs[port_id].list, + &tavil_p->dai[AIF3_PB].wcd9xxx_ch_list); + break; + case 4: + if (wcd9xxx_rx_vport_validation(port_id + + WCD934X_RX_PORT_START_NUMBER, + &tavil_p->dai[AIF4_PB].wcd9xxx_ch_list)) { + dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + __func__, port_id); + goto rtn; + } + list_add_tail(&core->rx_chs[port_id].list, + &tavil_p->dai[AIF4_PB].wcd9xxx_ch_list); + break; + default: + dev_err(codec->dev, "Unknown AIF %d\n", rx_port_value); + goto err; + } +rtn: + mutex_unlock(&tavil_p->codec_mutex); + snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, + rx_port_value, e, update); + + return 0; +err: + mutex_unlock(&tavil_p->codec_mutex); + return -EINVAL; +} + +static void tavil_codec_enable_slim_port_intr( + struct wcd9xxx_codec_dai_data *dai, + struct snd_soc_codec *codec) +{ + struct wcd9xxx_ch *ch; + int port_num = 0; + unsigned short reg = 0; + u8 val = 0; + struct tavil_priv *tavil_p; + + if (!dai || !codec) { + pr_err("%s: Invalid params\n", __func__); + return; + } + + tavil_p = snd_soc_codec_get_drvdata(codec); + list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) { + if (ch->port >= WCD934X_RX_PORT_START_NUMBER) { + port_num = ch->port - WCD934X_RX_PORT_START_NUMBER; + reg = WCD934X_SLIM_PGD_PORT_INT_RX_EN0 + (port_num / 8); + val = wcd9xxx_interface_reg_read(tavil_p->wcd9xxx, + reg); + if (!(val & BYTE_BIT_MASK(port_num))) { + val |= BYTE_BIT_MASK(port_num); + wcd9xxx_interface_reg_write( + tavil_p->wcd9xxx, reg, val); + val = wcd9xxx_interface_reg_read( + tavil_p->wcd9xxx, reg); + } + } else { + port_num = ch->port; + reg = WCD934X_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8); + val = wcd9xxx_interface_reg_read(tavil_p->wcd9xxx, + reg); + if (!(val & BYTE_BIT_MASK(port_num))) { + val |= BYTE_BIT_MASK(port_num); + wcd9xxx_interface_reg_write(tavil_p->wcd9xxx, + reg, val); + val = wcd9xxx_interface_reg_read( + tavil_p->wcd9xxx, reg); + } + } + } +} + +static int tavil_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai, + bool up) +{ + int ret = 0; + struct wcd9xxx_ch *ch; + + if (up) { + list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) { + ret = wcd9xxx_get_slave_port(ch->ch_num); + if (ret < 0) { + pr_err("%s: Invalid slave port ID: %d\n", + __func__, ret); + ret = -EINVAL; + } else { + set_bit(ret, &dai->ch_mask); + } + } + } else { + ret = wait_event_timeout(dai->dai_wait, (dai->ch_mask == 0), + msecs_to_jiffies( + WCD934X_SLIM_CLOSE_TIMEOUT)); + if (!ret) { + pr_err("%s: Slim close tx/rx wait timeout, ch_mask:0x%lx\n", + __func__, dai->ch_mask); + ret = -ETIMEDOUT; + } else { + ret = 0; + } + } + return ret; +} + +static void tavil_codec_mute_dsd(struct snd_soc_codec *codec, + struct list_head *ch_list) +{ + u8 dsd0_in; + u8 dsd1_in; + struct wcd9xxx_ch *ch; + + /* Read DSD Input Ports */ + dsd0_in = (snd_soc_read(codec, WCD934X_CDC_DSD0_CFG0) & 0x3C) >> 2; + dsd1_in = (snd_soc_read(codec, WCD934X_CDC_DSD1_CFG0) & 0x3C) >> 2; + + if ((dsd0_in == 0) && (dsd1_in == 0)) + return; + + /* + * Check if the ports getting disabled are connected to DSD inputs. + * If connected, enable DSD mute to avoid DC entering into DSD Filter + */ + list_for_each_entry(ch, ch_list, list) { + if (ch->port == (dsd0_in + WCD934X_RX_PORT_START_NUMBER - 1)) + snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, + 0x04, 0x04); + if (ch->port == (dsd1_in + WCD934X_RX_PORT_START_NUMBER - 1)) + snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, + 0x04, 0x04); + } +} + +static int tavil_codec_enable_slimrx(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct wcd9xxx *core; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + int ret = 0; + struct wcd9xxx_codec_dai_data *dai; + struct tavil_dsd_config *dsd_conf = tavil_p->dsd_config; + + core = dev_get_drvdata(codec->dev->parent); + + dev_dbg(codec->dev, "%s: event called! codec name %s num_dai %d\n" + "stream name %s event %d\n", + __func__, codec->component.name, + codec->component.num_dai, w->sname, event); + + dai = &tavil_p->dai[w->shift]; + dev_dbg(codec->dev, "%s: w->name %s w->shift %d event %d\n", + __func__, w->name, w->shift, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + dai->bus_down_in_recovery = false; + tavil_codec_enable_slim_port_intr(dai, codec); + (void) tavil_codec_enable_slim_chmask(dai, true); + ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list, + dai->rate, dai->bit_width, + &dai->grph); + break; + case SND_SOC_DAPM_POST_PMD: + if (dsd_conf) + tavil_codec_mute_dsd(codec, &dai->wcd9xxx_ch_list); + + ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list, + dai->grph); + dev_dbg(codec->dev, "%s: Disconnect RX port, ret = %d\n", + __func__, ret); + + if (!dai->bus_down_in_recovery) + ret = tavil_codec_enable_slim_chmask(dai, false); + else + dev_dbg(codec->dev, + "%s: bus in recovery skip enable slim_chmask", + __func__); + ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list, + dai->grph); + break; + } + return ret; +} + +static int tavil_codec_enable_slimtx(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx_codec_dai_data *dai; + struct wcd9xxx *core; + int ret = 0; + + dev_dbg(codec->dev, + "%s: w->name %s, w->shift = %d, num_dai %d stream name %s\n", + __func__, w->name, w->shift, + codec->component.num_dai, w->sname); + + dai = &tavil_p->dai[w->shift]; + core = dev_get_drvdata(codec->dev->parent); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + dai->bus_down_in_recovery = false; + tavil_codec_enable_slim_port_intr(dai, codec); + (void) tavil_codec_enable_slim_chmask(dai, true); + ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list, + dai->rate, dai->bit_width, + &dai->grph); + break; + case SND_SOC_DAPM_POST_PMD: + ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list, + dai->grph); + if (!dai->bus_down_in_recovery) + ret = tavil_codec_enable_slim_chmask(dai, false); + if (ret < 0) { + ret = wcd9xxx_disconnect_port(core, + &dai->wcd9xxx_ch_list, + dai->grph); + dev_dbg(codec->dev, "%s: Disconnect RX port, ret = %d\n", + __func__, ret); + } + break; + } + return ret; +} + +static int tavil_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct wcd9xxx *core = NULL; + struct snd_soc_codec *codec = NULL; + struct tavil_priv *tavil_p = NULL; + int ret = 0; + struct wcd9xxx_codec_dai_data *dai = NULL; + + codec = snd_soc_dapm_to_codec(w->dapm); + tavil_p = snd_soc_codec_get_drvdata(codec); + core = dev_get_drvdata(codec->dev->parent); + + dev_dbg(codec->dev, + "%s: num_dai %d stream name %s w->name %s event %d shift %d\n", + __func__, codec->component.num_dai, w->sname, + w->name, event, w->shift); + + if (w->shift != AIF4_VIFEED) { + pr_err("%s Error in enabling the tx path\n", __func__); + ret = -EINVAL; + goto done; + } + dai = &tavil_p->dai[w->shift]; + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (test_bit(VI_SENSE_1, &tavil_p->status_mask)) { + dev_dbg(codec->dev, "%s: spkr1 enabled\n", __func__); + /* Enable V&I sensing */ + snd_soc_update_bits(codec, + WCD934X_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); + snd_soc_update_bits(codec, + WCD934X_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD934X_CDC_TX9_SPKR_PROT_PATH_CTL, 0x0F, 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_TX10_SPKR_PROT_PATH_CTL, 0x0F, + 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x10); + snd_soc_update_bits(codec, + WCD934X_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10, + 0x10); + snd_soc_update_bits(codec, + WCD934X_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, + 0x00); + } + if (test_bit(VI_SENSE_2, &tavil_p->status_mask)) { + pr_debug("%s: spkr2 enabled\n", __func__); + /* Enable V&I sensing */ + snd_soc_update_bits(codec, + WCD934X_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD934X_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD934X_CDC_TX11_SPKR_PROT_PATH_CTL, 0x0F, + 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_TX12_SPKR_PROT_PATH_CTL, 0x0F, + 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10, + 0x10); + snd_soc_update_bits(codec, + WCD934X_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10, + 0x10); + snd_soc_update_bits(codec, + WCD934X_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, + 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, + 0x00); + } + dai->bus_down_in_recovery = false; + tavil_codec_enable_slim_port_intr(dai, codec); + (void) tavil_codec_enable_slim_chmask(dai, true); + ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list, + dai->rate, dai->bit_width, + &dai->grph); + break; + case SND_SOC_DAPM_POST_PMD: + ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list, + dai->grph); + if (ret) + dev_err(codec->dev, "%s error in close_slim_sch_tx %d\n", + __func__, ret); + if (!dai->bus_down_in_recovery) + ret = tavil_codec_enable_slim_chmask(dai, false); + if (ret < 0) { + ret = wcd9xxx_disconnect_port(core, + &dai->wcd9xxx_ch_list, + dai->grph); + dev_dbg(codec->dev, "%s: Disconnect TX port, ret = %d\n", + __func__, ret); + } + if (test_bit(VI_SENSE_1, &tavil_p->status_mask)) { + /* Disable V&I sensing */ + dev_dbg(codec->dev, "%s: spkr1 disabled\n", __func__); + snd_soc_update_bits(codec, + WCD934X_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); + snd_soc_update_bits(codec, + WCD934X_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD934X_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10, + 0x00); + } + if (test_bit(VI_SENSE_2, &tavil_p->status_mask)) { + /* Disable V&I sensing */ + dev_dbg(codec->dev, "%s: spkr2 disabled\n", __func__); + snd_soc_update_bits(codec, + WCD934X_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD934X_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD934X_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10, + 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10, + 0x00); + } + break; + } +done: + return ret; +} + +static int tavil_codec_enable_rx_bias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + tavil->rx_bias_count++; + if (tavil->rx_bias_count == 1) { + snd_soc_update_bits(codec, WCD934X_ANA_RX_SUPPLIES, + 0x01, 0x01); + } + break; + case SND_SOC_DAPM_POST_PMD: + tavil->rx_bias_count--; + if (!tavil->rx_bias_count) + snd_soc_update_bits(codec, WCD934X_ANA_RX_SUPPLIES, + 0x01, 0x00); + break; + }; + dev_dbg(codec->dev, "%s: Current RX BIAS user count: %d\n", __func__, + tavil->rx_bias_count); + + return 0; +} + +static void tavil_spk_anc_update_callback(struct work_struct *work) +{ + struct spk_anc_work *spk_anc_dwork; + struct tavil_priv *tavil; + struct delayed_work *delayed_work; + struct snd_soc_codec *codec; + + delayed_work = to_delayed_work(work); + spk_anc_dwork = container_of(delayed_work, struct spk_anc_work, dwork); + tavil = spk_anc_dwork->tavil; + codec = tavil->codec; + + snd_soc_update_bits(codec, WCD934X_CDC_RX7_RX_PATH_CFG0, 0x10, 0x10); +} + +static int tavil_codec_enable_spkr_anc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + int ret = 0; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + if (!tavil->anc_func) + return 0; + + dev_dbg(codec->dev, "%s: w: %s event: %d anc: %d\n", __func__, + w->name, event, tavil->anc_func); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = tavil_codec_enable_anc(w, kcontrol, event); + schedule_delayed_work(&tavil->spk_anc_dwork.dwork, + msecs_to_jiffies(spk_anc_en_delay)); + break; + case SND_SOC_DAPM_POST_PMD: + cancel_delayed_work_sync(&tavil->spk_anc_dwork.dwork); + snd_soc_update_bits(codec, WCD934X_CDC_RX7_RX_PATH_CFG0, + 0x10, 0x00); + ret = tavil_codec_enable_anc(w, kcontrol, event); + break; + } + return ret; +} + +static int tavil_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + int ret = 0; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* + * 5ms sleep is required after PA is enabled as per + * HW requirement + */ + usleep_range(5000, 5500); + snd_soc_update_bits(codec, WCD934X_CDC_RX0_RX_PATH_CTL, + 0x10, 0x00); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, WCD934X_CDC_RX0_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + WCD934X_CDC_RX0_RX_PATH_MIX_CTL, + 0x10, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + /* + * 5ms sleep is required after PA is disabled as per + * HW requirement + */ + usleep_range(5000, 5500); + + if (!(strcmp(w->name, "ANC EAR PA"))) { + ret = tavil_codec_enable_anc(w, kcontrol, event); + snd_soc_update_bits(codec, WCD934X_CDC_RX0_RX_PATH_CFG0, + 0x10, 0x00); + } + break; + }; + + return ret; +} + +static void tavil_codec_override(struct snd_soc_codec *codec, int mode, + int event) +{ + if (mode == CLS_AB || mode == CLS_AB_HIFI) { + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, + WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x02); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, + WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x00); + break; + } + } +} + +static void tavil_codec_clear_anc_tx_hold(struct tavil_priv *tavil) +{ + if (test_and_clear_bit(ANC_MIC_AMIC1, &tavil->status_mask)) + tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC1, false); + if (test_and_clear_bit(ANC_MIC_AMIC2, &tavil->status_mask)) + tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC2, false); + if (test_and_clear_bit(ANC_MIC_AMIC3, &tavil->status_mask)) + tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC3, false); + if (test_and_clear_bit(ANC_MIC_AMIC4, &tavil->status_mask)) + tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC4, false); +} + +static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_dsd_config *dsd_conf = tavil->dsd_config; + int ret = 0; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (TAVIL_IS_1_0(tavil->wcd9xxx)) + snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL, + 0x06, (0x03 << 1)); + + if ((!(strcmp(w->name, "ANC HPHR PA"))) && + (test_bit(HPH_PA_DELAY, &tavil->status_mask))) + snd_soc_update_bits(codec, WCD934X_ANA_HPH, 0xC0, 0xC0); + + set_bit(HPH_PA_DELAY, &tavil->status_mask); + if (dsd_conf && + (snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) { + /* Set regulator mode to AB if DSD is enabled */ + snd_soc_update_bits(codec, WCD934X_ANA_RX_SUPPLIES, + 0x02, 0x02); + } + break; + case SND_SOC_DAPM_POST_PMU: + if ((!(strcmp(w->name, "ANC HPHR PA")))) { + if ((snd_soc_read(codec, WCD934X_ANA_HPH) & 0xC0) + != 0xC0) + /* + * If PA_EN is not set (potentially in ANC case) + * then do nothing for POST_PMU and let left + * channel handle everything. + */ + break; + } + /* + * 7ms sleep is required after PA is enabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is needed. + */ + if (test_bit(HPH_PA_DELAY, &tavil->status_mask)) { + if (!tavil->comp_enabled[COMPANDER_2]) + usleep_range(20000, 20100); + else + usleep_range(7000, 7100); + clear_bit(HPH_PA_DELAY, &tavil->status_mask); + } + if (tavil->anc_func) { + /* Clear Tx FE HOLD if both PAs are enabled */ + if ((snd_soc_read(tavil->codec, WCD934X_ANA_HPH) & + 0xC0) == 0xC0) + tavil_codec_clear_anc_tx_hold(tavil); + } + + snd_soc_update_bits(codec, WCD934X_HPH_R_TEST, 0x01, 0x01); + + /* Remove mute */ + snd_soc_update_bits(codec, WCD934X_CDC_RX2_RX_PATH_CTL, + 0x10, 0x00); + /* Enable GM3 boost */ + snd_soc_update_bits(codec, WCD934X_HPH_CNP_WG_CTL, + 0x80, 0x80); + /* Enable AutoChop timer at the end of power up */ + snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x02); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, WCD934X_CDC_RX2_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + WCD934X_CDC_RX2_RX_PATH_MIX_CTL, + 0x10, 0x00); + if (dsd_conf && + (snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) + snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, + 0x04, 0x00); + if (!(strcmp(w->name, "ANC HPHR PA"))) { + pr_debug("%s:Do everything needed for left channel\n", + __func__); + /* Do everything needed for left channel */ + snd_soc_update_bits(codec, WCD934X_HPH_L_TEST, + 0x01, 0x01); + + /* Remove mute */ + snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CTL, + 0x10, 0x00); + + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, + WCD934X_CDC_RX1_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + WCD934X_CDC_RX1_RX_PATH_MIX_CTL, + 0x10, 0x00); + + if (dsd_conf && (snd_soc_read(codec, + WCD934X_CDC_DSD0_PATH_CTL) & + 0x01)) + snd_soc_update_bits(codec, + WCD934X_CDC_DSD0_CFG2, + 0x04, 0x00); + /* Remove ANC Rx from reset */ + ret = tavil_codec_enable_anc(w, kcontrol, event); + } + tavil_codec_override(codec, tavil->hph_mode, event); + break; + case SND_SOC_DAPM_PRE_PMD: + blocking_notifier_call_chain(&tavil->mbhc->notifier, + WCD_EVENT_PRE_HPHR_PA_OFF, + &tavil->mbhc->wcd_mbhc); + /* Enable DSD Mute before PA disable */ + if (dsd_conf && + (snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) + snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, + 0x04, 0x04); + snd_soc_update_bits(codec, WCD934X_HPH_R_TEST, 0x01, 0x00); + snd_soc_update_bits(codec, WCD934X_CDC_RX2_RX_PATH_CTL, + 0x10, 0x10); + snd_soc_update_bits(codec, WCD934X_CDC_RX2_RX_PATH_MIX_CTL, + 0x10, 0x10); + if (!(strcmp(w->name, "ANC HPHR PA"))) + snd_soc_update_bits(codec, WCD934X_ANA_HPH, 0x40, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + /* + * 5ms sleep is required after PA disable. If compander is + * disabled, then 20ms delay is needed after PA disable. + */ + if (!tavil->comp_enabled[COMPANDER_2]) + usleep_range(20000, 20100); + else + usleep_range(5000, 5100); + tavil_codec_override(codec, tavil->hph_mode, event); + blocking_notifier_call_chain(&tavil->mbhc->notifier, + WCD_EVENT_POST_HPHR_PA_OFF, + &tavil->mbhc->wcd_mbhc); + if (TAVIL_IS_1_0(tavil->wcd9xxx)) + snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL, + 0x06, 0x0); + if (!(strcmp(w->name, "ANC HPHR PA"))) { + ret = tavil_codec_enable_anc(w, kcontrol, event); + snd_soc_update_bits(codec, + WCD934X_CDC_RX2_RX_PATH_CFG0, + 0x10, 0x00); + } + break; + }; + + return ret; +} + +static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_dsd_config *dsd_conf = tavil->dsd_config; + int ret = 0; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (TAVIL_IS_1_0(tavil->wcd9xxx)) + snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL, + 0x06, (0x03 << 1)); + if ((!(strcmp(w->name, "ANC HPHL PA"))) && + (test_bit(HPH_PA_DELAY, &tavil->status_mask))) + snd_soc_update_bits(codec, WCD934X_ANA_HPH, + 0xC0, 0xC0); + set_bit(HPH_PA_DELAY, &tavil->status_mask); + if (dsd_conf && + (snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) { + /* Set regulator mode to AB if DSD is enabled */ + snd_soc_update_bits(codec, WCD934X_ANA_RX_SUPPLIES, + 0x02, 0x02); + } + break; + case SND_SOC_DAPM_POST_PMU: + if (!(strcmp(w->name, "ANC HPHL PA"))) { + if ((snd_soc_read(codec, WCD934X_ANA_HPH) & 0xC0) + != 0xC0) + /* + * If PA_EN is not set (potentially in ANC + * case) then do nothing for POST_PMU and + * let right channel handle everything. + */ + break; + } + /* + * 7ms sleep is required after PA is enabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is needed. + */ + if (test_bit(HPH_PA_DELAY, &tavil->status_mask)) { + if (!tavil->comp_enabled[COMPANDER_1]) + usleep_range(20000, 20100); + else + usleep_range(7000, 7100); + clear_bit(HPH_PA_DELAY, &tavil->status_mask); + } + if (tavil->anc_func) { + /* Clear Tx FE HOLD if both PAs are enabled */ + if ((snd_soc_read(tavil->codec, WCD934X_ANA_HPH) & + 0xC0) == 0xC0) + tavil_codec_clear_anc_tx_hold(tavil); + } + + snd_soc_update_bits(codec, WCD934X_HPH_L_TEST, 0x01, 0x01); + /* Remove Mute on primary path */ + snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CTL, + 0x10, 0x00); + /* Enable GM3 boost */ + snd_soc_update_bits(codec, WCD934X_HPH_CNP_WG_CTL, + 0x80, 0x80); + /* Enable AutoChop timer at the end of power up */ + snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x02); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, WCD934X_CDC_RX1_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + WCD934X_CDC_RX1_RX_PATH_MIX_CTL, + 0x10, 0x00); + if (dsd_conf && + (snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) + snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, + 0x04, 0x00); + if (!(strcmp(w->name, "ANC HPHL PA"))) { + pr_debug("%s:Do everything needed for right channel\n", + __func__); + + /* Do everything needed for right channel */ + snd_soc_update_bits(codec, WCD934X_HPH_R_TEST, + 0x01, 0x01); + + /* Remove mute */ + snd_soc_update_bits(codec, WCD934X_CDC_RX2_RX_PATH_CTL, + 0x10, 0x00); + + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, + WCD934X_CDC_RX2_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + WCD934X_CDC_RX2_RX_PATH_MIX_CTL, + 0x10, 0x00); + if (dsd_conf && (snd_soc_read(codec, + WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) + snd_soc_update_bits(codec, + WCD934X_CDC_DSD1_CFG2, + 0x04, 0x00); + /* Remove ANC Rx from reset */ + ret = tavil_codec_enable_anc(w, kcontrol, event); + } + tavil_codec_override(codec, tavil->hph_mode, event); + break; + case SND_SOC_DAPM_PRE_PMD: + blocking_notifier_call_chain(&tavil->mbhc->notifier, + WCD_EVENT_PRE_HPHL_PA_OFF, + &tavil->mbhc->wcd_mbhc); + /* Enable DSD Mute before PA disable */ + if (dsd_conf && + (snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) + snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, + 0x04, 0x04); + + snd_soc_update_bits(codec, WCD934X_HPH_L_TEST, 0x01, 0x00); + snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CTL, + 0x10, 0x10); + snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_MIX_CTL, + 0x10, 0x10); + if (!(strcmp(w->name, "ANC HPHL PA"))) + snd_soc_update_bits(codec, WCD934X_ANA_HPH, + 0x80, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + /* + * 5ms sleep is required after PA disable. If compander is + * disabled, then 20ms delay is needed after PA disable. + */ + if (!tavil->comp_enabled[COMPANDER_1]) + usleep_range(20000, 20100); + else + usleep_range(5000, 5100); + tavil_codec_override(codec, tavil->hph_mode, event); + blocking_notifier_call_chain(&tavil->mbhc->notifier, + WCD_EVENT_POST_HPHL_PA_OFF, + &tavil->mbhc->wcd_mbhc); + if (TAVIL_IS_1_0(tavil->wcd9xxx)) + snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL, + 0x06, 0x0); + if (!(strcmp(w->name, "ANC HPHL PA"))) { + ret = tavil_codec_enable_anc(w, kcontrol, event); + snd_soc_update_bits(codec, + WCD934X_CDC_RX1_RX_PATH_CFG0, 0x10, 0x00); + } + break; + }; + + return ret; +} + +static int tavil_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 lineout_vol_reg = 0, lineout_mix_vol_reg = 0; + u16 dsd_mute_reg = 0, dsd_clk_reg = 0; + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_dsd_config *dsd_conf = tavil->dsd_config; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + if (w->reg == WCD934X_ANA_LO_1_2) { + if (w->shift == 7) { + lineout_vol_reg = WCD934X_CDC_RX3_RX_PATH_CTL; + lineout_mix_vol_reg = WCD934X_CDC_RX3_RX_PATH_MIX_CTL; + dsd_mute_reg = WCD934X_CDC_DSD0_CFG2; + dsd_clk_reg = WCD934X_CDC_DSD0_PATH_CTL; + } else if (w->shift == 6) { + lineout_vol_reg = WCD934X_CDC_RX4_RX_PATH_CTL; + lineout_mix_vol_reg = WCD934X_CDC_RX4_RX_PATH_MIX_CTL; + dsd_mute_reg = WCD934X_CDC_DSD1_CFG2; + dsd_clk_reg = WCD934X_CDC_DSD1_PATH_CTL; + } + } else { + dev_err(codec->dev, "%s: Error enabling lineout PA\n", + __func__); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + tavil_codec_override(codec, CLS_AB, event); + break; + case SND_SOC_DAPM_POST_PMU: + /* + * 5ms sleep is required after PA is enabled as per + * HW requirement + */ + usleep_range(5000, 5500); + snd_soc_update_bits(codec, lineout_vol_reg, + 0x10, 0x00); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, lineout_mix_vol_reg)) & 0x10) + snd_soc_update_bits(codec, + lineout_mix_vol_reg, + 0x10, 0x00); + if (dsd_conf && (snd_soc_read(codec, dsd_clk_reg) & 0x01)) + snd_soc_update_bits(codec, dsd_mute_reg, 0x04, 0x00); + break; + case SND_SOC_DAPM_PRE_PMD: + if (dsd_conf && (snd_soc_read(codec, dsd_clk_reg) & 0x01)) + snd_soc_update_bits(codec, dsd_mute_reg, 0x04, 0x04); + break; + case SND_SOC_DAPM_POST_PMD: + /* + * 5ms sleep is required after PA is disabled as per + * HW requirement + */ + usleep_range(5000, 5500); + tavil_codec_override(codec, CLS_AB, event); + default: + break; + }; + + return 0; +} + +static int tavil_codec_ear_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + int ret = 0; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Disable AutoChop timer during power up */ + snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x00); + + if (tavil->anc_func) + ret = tavil_codec_enable_anc(w, kcontrol, event); + + wcd_clsh_fsm(codec, &tavil->clsh_d, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_EAR, + CLS_H_NORMAL); + if (tavil->anc_func) + snd_soc_update_bits(codec, WCD934X_CDC_RX0_RX_PATH_CFG0, + 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMD: + wcd_clsh_fsm(codec, &tavil->clsh_d, + WCD_CLSH_EVENT_POST_PA, + WCD_CLSH_STATE_EAR, + CLS_H_NORMAL); + break; + default: + break; + }; + + return ret; +} + +static int tavil_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + int hph_mode = tavil->hph_mode; + u8 dem_inp; + struct tavil_dsd_config *dsd_conf = tavil->dsd_config; + int ret = 0; + + dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, + w->name, event, hph_mode); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (tavil->anc_func) { + ret = tavil_codec_enable_anc(w, kcontrol, event); + /* 40 msec delay is needed to avoid click and pop */ + msleep(40); + } + /* Read DEM INP Select */ + dem_inp = snd_soc_read(codec, WCD934X_CDC_RX2_RX_PATH_SEC0) & + 0x03; + if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || + (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { + dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", + __func__, hph_mode); + return -EINVAL; + } + if ((hph_mode != CLS_H_LP) && (hph_mode != CLS_H_ULP)) + /* Ripple freq control enable */ + snd_soc_update_bits(codec, + WCD934X_SIDO_NEW_VOUT_D_FREQ2, + 0x01, 0x01); + /* Disable AutoChop timer during power up */ + snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x00); + /* Set RDAC gain */ + if (TAVIL_IS_1_0(tavil->wcd9xxx)) + snd_soc_update_bits(codec, + WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, + 0xF0, 0x40); + if (dsd_conf && + (snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) + hph_mode = CLS_H_HIFI; + + wcd_clsh_fsm(codec, &tavil->clsh_d, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_HPHR, + hph_mode); + if (tavil->anc_func) + snd_soc_update_bits(codec, + WCD934X_CDC_RX2_RX_PATH_CFG0, + 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMD: + /* 1000us required as per HW requirement */ + usleep_range(1000, 1100); + wcd_clsh_fsm(codec, &tavil->clsh_d, + WCD_CLSH_EVENT_POST_PA, + WCD_CLSH_STATE_HPHR, + hph_mode); + if ((hph_mode != CLS_H_LP) && (hph_mode != CLS_H_ULP)) + /* Ripple freq control disable */ + snd_soc_update_bits(codec, + WCD934X_SIDO_NEW_VOUT_D_FREQ2, + 0x01, 0x0); + /* Re-set RDAC gain */ + if (TAVIL_IS_1_0(tavil->wcd9xxx)) + snd_soc_update_bits(codec, + WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, + 0xF0, 0x0); + break; + default: + break; + }; + + return 0; +} + +static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + int hph_mode = tavil->hph_mode; + u8 dem_inp; + int ret = 0; + struct tavil_dsd_config *dsd_conf = tavil->dsd_config; + uint32_t impedl = 0, impedr = 0; + + dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, + w->name, event, hph_mode); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (tavil->anc_func) { + ret = tavil_codec_enable_anc(w, kcontrol, event); + /* 40 msec delay is needed to avoid click and pop */ + msleep(40); + } + /* Read DEM INP Select */ + dem_inp = snd_soc_read(codec, WCD934X_CDC_RX1_RX_PATH_SEC0) & + 0x03; + if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || + (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { + dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", + __func__, hph_mode); + return -EINVAL; + } + if ((hph_mode != CLS_H_LP) && (hph_mode != CLS_H_ULP)) + /* Ripple freq control enable */ + snd_soc_update_bits(codec, + WCD934X_SIDO_NEW_VOUT_D_FREQ2, + 0x01, 0x01); + /* Disable AutoChop timer during power up */ + snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x00); + /* Set RDAC gain */ + if (TAVIL_IS_1_0(tavil->wcd9xxx)) + snd_soc_update_bits(codec, + WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, + 0xF0, 0x40); + if (dsd_conf && + (snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) + hph_mode = CLS_H_HIFI; + + wcd_clsh_fsm(codec, &tavil->clsh_d, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_HPHL, + hph_mode); + + if (tavil->anc_func) + snd_soc_update_bits(codec, + WCD934X_CDC_RX1_RX_PATH_CFG0, + 0x10, 0x10); + + ret = tavil_mbhc_get_impedance(tavil->mbhc, + &impedl, &impedr); + if (!ret) { + wcd_clsh_imped_config(codec, impedl, false); + set_bit(CLSH_Z_CONFIG, &tavil->status_mask); + } else { + dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n", + __func__, ret); + ret = 0; + } + + break; + case SND_SOC_DAPM_POST_PMD: + /* 1000us required as per HW requirement */ + usleep_range(1000, 1100); + wcd_clsh_fsm(codec, &tavil->clsh_d, + WCD_CLSH_EVENT_POST_PA, + WCD_CLSH_STATE_HPHL, + hph_mode); + if ((hph_mode != CLS_H_LP) && (hph_mode != CLS_H_ULP)) + /* Ripple freq control disable */ + snd_soc_update_bits(codec, + WCD934X_SIDO_NEW_VOUT_D_FREQ2, + 0x01, 0x0); + /* Re-set RDAC gain */ + if (TAVIL_IS_1_0(tavil->wcd9xxx)) + snd_soc_update_bits(codec, + WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, + 0xF0, 0x0); + + if (test_bit(CLSH_Z_CONFIG, &tavil->status_mask)) { + wcd_clsh_imped_config(codec, impedl, true); + clear_bit(CLSH_Z_CONFIG, &tavil->status_mask); + } + break; + default: + break; + }; + + return ret; +} + +static int tavil_codec_lineout_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd_clsh_fsm(codec, &tavil->clsh_d, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_LO, + CLS_AB); + break; + case SND_SOC_DAPM_POST_PMD: + wcd_clsh_fsm(codec, &tavil->clsh_d, + WCD_CLSH_EVENT_POST_PA, + WCD_CLSH_STATE_LO, + CLS_AB); + break; + } + + return 0; +} + +static int tavil_codec_spk_boost_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 boost_path_ctl, boost_path_cfg1; + u16 reg, reg_mix; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + if (!strcmp(w->name, "RX INT7 CHAIN")) { + boost_path_ctl = WCD934X_CDC_BOOST0_BOOST_PATH_CTL; + boost_path_cfg1 = WCD934X_CDC_RX7_RX_PATH_CFG1; + reg = WCD934X_CDC_RX7_RX_PATH_CTL; + reg_mix = WCD934X_CDC_RX7_RX_PATH_MIX_CTL; + } else if (!strcmp(w->name, "RX INT8 CHAIN")) { + boost_path_ctl = WCD934X_CDC_BOOST1_BOOST_PATH_CTL; + boost_path_cfg1 = WCD934X_CDC_RX8_RX_PATH_CFG1; + reg = WCD934X_CDC_RX8_RX_PATH_CTL; + reg_mix = WCD934X_CDC_RX8_RX_PATH_MIX_CTL; + } else { + dev_err(codec->dev, "%s: unknown widget: %s\n", + __func__, w->name); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x01); + snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x10); + snd_soc_update_bits(codec, reg, 0x10, 0x00); + if ((snd_soc_read(codec, reg_mix)) & 0x10) + snd_soc_update_bits(codec, reg_mix, 0x10, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x00); + snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x00); + break; + }; + + return 0; +} + +static int __tavil_codec_enable_swr(struct snd_soc_dapm_widget *w, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil; + int ch_cnt = 0; + + tavil = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) || + (strnstr(w->name, "INT7 MIX2", + sizeof("RX INT7 MIX2"))))) + tavil->swr.rx_7_count++; + if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) && + !tavil->swr.rx_8_count) + tavil->swr.rx_8_count++; + ch_cnt = !!(tavil->swr.rx_7_count) + tavil->swr.rx_8_count; + + swrm_wcd_notify(tavil->swr.ctrl_data[0].swr_pdev, + SWR_DEVICE_UP, NULL); + swrm_wcd_notify(tavil->swr.ctrl_data[0].swr_pdev, + SWR_SET_NUM_RX_CH, &ch_cnt); + break; + case SND_SOC_DAPM_POST_PMD: + if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) || + (strnstr(w->name, "INT7 MIX2", + sizeof("RX INT7 MIX2")))) + tavil->swr.rx_7_count--; + if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) && + tavil->swr.rx_8_count) + tavil->swr.rx_8_count--; + ch_cnt = !!(tavil->swr.rx_7_count) + tavil->swr.rx_8_count; + + swrm_wcd_notify(tavil->swr.ctrl_data[0].swr_pdev, + SWR_SET_NUM_RX_CH, &ch_cnt); + + break; + } + dev_dbg(tavil->dev, "%s: %s: current swr ch cnt: %d\n", + __func__, w->name, ch_cnt); + + return 0; +} + +static int tavil_codec_enable_swr(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + return __tavil_codec_enable_swr(w, event); +} + +static int tavil_codec_config_mad(struct snd_soc_codec *codec) +{ + int ret = 0; + int idx; + const struct firmware *fw; + struct firmware_cal *hwdep_cal = NULL; + struct wcd_mad_audio_cal *mad_cal = NULL; + const void *data; + const char *filename = WCD934X_MAD_AUDIO_FIRMWARE_PATH; + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + size_t cal_size; + + hwdep_cal = wcdcal_get_fw_cal(tavil->fw_data, WCD9XXX_MAD_CAL); + if (hwdep_cal) { + data = hwdep_cal->data; + cal_size = hwdep_cal->size; + dev_dbg(codec->dev, "%s: using hwdep calibration\n", + __func__); + } else { + ret = request_firmware(&fw, filename, codec->dev); + if (ret || !fw) { + dev_err(codec->dev, + "%s: MAD firmware acquire failed, err = %d\n", + __func__, ret); + return -ENODEV; + } + data = fw->data; + cal_size = fw->size; + dev_dbg(codec->dev, "%s: using request_firmware calibration\n", + __func__); + } + + if (cal_size < sizeof(*mad_cal)) { + dev_err(codec->dev, + "%s: Incorrect size %zd for MAD Cal, expected %zd\n", + __func__, cal_size, sizeof(*mad_cal)); + ret = -ENOMEM; + goto done; + } + + mad_cal = (struct wcd_mad_audio_cal *) (data); + if (!mad_cal) { + dev_err(codec->dev, + "%s: Invalid calibration data\n", + __func__); + ret = -EINVAL; + goto done; + } + + snd_soc_write(codec, WCD934X_SOC_MAD_MAIN_CTL_2, + mad_cal->microphone_info.cycle_time); + snd_soc_update_bits(codec, WCD934X_SOC_MAD_MAIN_CTL_1, 0xFF << 3, + ((uint16_t)mad_cal->microphone_info.settle_time) + << 3); + + /* Audio */ + snd_soc_write(codec, WCD934X_SOC_MAD_AUDIO_CTL_8, + mad_cal->audio_info.rms_omit_samples); + snd_soc_update_bits(codec, WCD934X_SOC_MAD_AUDIO_CTL_1, + 0x07 << 4, mad_cal->audio_info.rms_comp_time << 4); + snd_soc_update_bits(codec, WCD934X_SOC_MAD_AUDIO_CTL_2, 0x03 << 2, + mad_cal->audio_info.detection_mechanism << 2); + snd_soc_write(codec, WCD934X_SOC_MAD_AUDIO_CTL_7, + mad_cal->audio_info.rms_diff_threshold & 0x3F); + snd_soc_write(codec, WCD934X_SOC_MAD_AUDIO_CTL_5, + mad_cal->audio_info.rms_threshold_lsb); + snd_soc_write(codec, WCD934X_SOC_MAD_AUDIO_CTL_6, + mad_cal->audio_info.rms_threshold_msb); + + for (idx = 0; idx < ARRAY_SIZE(mad_cal->audio_info.iir_coefficients); + idx++) { + snd_soc_update_bits(codec, WCD934X_SOC_MAD_AUDIO_IIR_CTL_PTR, + 0x3F, idx); + snd_soc_write(codec, WCD934X_SOC_MAD_AUDIO_IIR_CTL_VAL, + mad_cal->audio_info.iir_coefficients[idx]); + dev_dbg(codec->dev, "%s:MAD Audio IIR Coef[%d] = 0X%x", + __func__, idx, + mad_cal->audio_info.iir_coefficients[idx]); + } + + /* Beacon */ + snd_soc_write(codec, WCD934X_SOC_MAD_BEACON_CTL_8, + mad_cal->beacon_info.rms_omit_samples); + snd_soc_update_bits(codec, WCD934X_SOC_MAD_BEACON_CTL_1, + 0x07 << 4, mad_cal->beacon_info.rms_comp_time << 4); + snd_soc_update_bits(codec, WCD934X_SOC_MAD_BEACON_CTL_2, 0x03 << 2, + mad_cal->beacon_info.detection_mechanism << 2); + snd_soc_write(codec, WCD934X_SOC_MAD_BEACON_CTL_7, + mad_cal->beacon_info.rms_diff_threshold & 0x1F); + snd_soc_write(codec, WCD934X_SOC_MAD_BEACON_CTL_5, + mad_cal->beacon_info.rms_threshold_lsb); + snd_soc_write(codec, WCD934X_SOC_MAD_BEACON_CTL_6, + mad_cal->beacon_info.rms_threshold_msb); + + for (idx = 0; idx < ARRAY_SIZE(mad_cal->beacon_info.iir_coefficients); + idx++) { + snd_soc_update_bits(codec, WCD934X_SOC_MAD_BEACON_IIR_CTL_PTR, + 0x3F, idx); + snd_soc_write(codec, WCD934X_SOC_MAD_BEACON_IIR_CTL_VAL, + mad_cal->beacon_info.iir_coefficients[idx]); + dev_dbg(codec->dev, "%s:MAD Beacon IIR Coef[%d] = 0X%x", + __func__, idx, + mad_cal->beacon_info.iir_coefficients[idx]); + } + + /* Ultrasound */ + snd_soc_update_bits(codec, WCD934X_SOC_MAD_ULTR_CTL_1, + 0x07 << 4, + mad_cal->ultrasound_info.rms_comp_time << 4); + snd_soc_update_bits(codec, WCD934X_SOC_MAD_ULTR_CTL_2, 0x03 << 2, + mad_cal->ultrasound_info.detection_mechanism << 2); + snd_soc_write(codec, WCD934X_SOC_MAD_ULTR_CTL_7, + mad_cal->ultrasound_info.rms_diff_threshold & 0x1F); + snd_soc_write(codec, WCD934X_SOC_MAD_ULTR_CTL_5, + mad_cal->ultrasound_info.rms_threshold_lsb); + snd_soc_write(codec, WCD934X_SOC_MAD_ULTR_CTL_6, + mad_cal->ultrasound_info.rms_threshold_msb); + +done: + if (!hwdep_cal) + release_firmware(fw); + + return ret; +} + +static int __tavil_codec_enable_mad(struct snd_soc_codec *codec, bool enable) +{ + int rc = 0; + + /* Return if CPE INPUT is DEC1 */ + if (snd_soc_read(codec, WCD934X_CPE_SS_SVA_CFG) & 0x04) { + dev_dbg(codec->dev, "%s: MAD is bypassed, skip mad %s\n", + __func__, enable ? "enable" : "disable"); + return rc; + } + + dev_dbg(codec->dev, "%s: enable = %s\n", __func__, + enable ? "enable" : "disable"); + + if (enable) { + snd_soc_update_bits(codec, WCD934X_SOC_MAD_AUDIO_CTL_2, + 0x03, 0x03); + rc = tavil_codec_config_mad(codec); + if (rc < 0) { + snd_soc_update_bits(codec, WCD934X_SOC_MAD_AUDIO_CTL_2, + 0x03, 0x00); + goto done; + } + + /* Turn on MAD clk */ + snd_soc_update_bits(codec, WCD934X_CPE_SS_MAD_CTL, + 0x01, 0x01); + + /* Undo reset for MAD */ + snd_soc_update_bits(codec, WCD934X_CPE_SS_MAD_CTL, + 0x02, 0x00); + snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_MCLK_CFG, + 0x04, 0x04); + } else { + snd_soc_update_bits(codec, WCD934X_SOC_MAD_AUDIO_CTL_2, + 0x03, 0x00); + /* Reset the MAD block */ + snd_soc_update_bits(codec, WCD934X_CPE_SS_MAD_CTL, + 0x02, 0x02); + /* Turn off MAD clk */ + snd_soc_update_bits(codec, WCD934X_CPE_SS_MAD_CTL, + 0x01, 0x00); + snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_MCLK_CFG, + 0x04, 0x00); + } +done: + return rc; +} + +static int tavil_codec_ape_enable_mad(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + int rc = 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WCD934X_CPE_SS_SVA_CFG, 0x40, 0x40); + rc = __tavil_codec_enable_mad(codec, true); + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_update_bits(codec, WCD934X_CPE_SS_SVA_CFG, 0x40, 0x00); + __tavil_codec_enable_mad(codec, false); + break; + } + + dev_dbg(tavil->dev, "%s: event = %d\n", __func__, event); + return rc; +} + +static int tavil_codec_cpe_mad_ctl(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + int rc = 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + tavil->mad_switch_cnt++; + if (tavil->mad_switch_cnt != 1) + goto done; + + snd_soc_update_bits(codec, WCD934X_CPE_SS_SVA_CFG, 0x20, 0x20); + rc = __tavil_codec_enable_mad(codec, true); + if (rc < 0) { + tavil->mad_switch_cnt--; + goto done; + } + + break; + case SND_SOC_DAPM_PRE_PMD: + tavil->mad_switch_cnt--; + if (tavil->mad_switch_cnt != 0) + goto done; + + snd_soc_update_bits(codec, WCD934X_CPE_SS_SVA_CFG, 0x20, 0x00); + __tavil_codec_enable_mad(codec, false); + break; + } +done: + dev_dbg(tavil->dev, "%s: event = %d, mad_switch_cnt = %d\n", + __func__, event, tavil->mad_switch_cnt); + return rc; +} + +static int tavil_get_asrc_mode(struct tavil_priv *tavil, int asrc, + u8 main_sr, u8 mix_sr) +{ + u8 asrc_output_mode; + int asrc_mode = CONV_88P2K_TO_384K; + + if ((asrc < 0) || (asrc >= ASRC_MAX)) + return 0; + + asrc_output_mode = tavil->asrc_output_mode[asrc]; + + if (asrc_output_mode) { + /* + * If Mix sample rate is < 96KHz, use 96K to 352.8K + * conversion, or else use 384K to 352.8K conversion + */ + if (mix_sr < 5) + asrc_mode = CONV_96K_TO_352P8K; + else + asrc_mode = CONV_384K_TO_352P8K; + } else { + /* Integer main and Fractional mix path */ + if (main_sr < 8 && mix_sr > 9) { + asrc_mode = CONV_352P8K_TO_384K; + } else if (main_sr > 8 && mix_sr < 8) { + /* Fractional main and Integer mix path */ + if (mix_sr < 5) + asrc_mode = CONV_96K_TO_352P8K; + else + asrc_mode = CONV_384K_TO_352P8K; + } else if (main_sr < 8 && mix_sr < 8) { + /* Integer main and Integer mix path */ + asrc_mode = CONV_96K_TO_384K; + } + } + + return asrc_mode; +} + +static int tavil_codec_enable_asrc(struct snd_soc_codec *codec, + int asrc_in, int event) +{ + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + u16 cfg_reg, ctl_reg, clk_reg, asrc_ctl, mix_ctl_reg; + int asrc, ret = 0; + u8 main_sr, mix_sr, asrc_mode = 0; + + switch (asrc_in) { + case ASRC_IN_HPHL: + cfg_reg = WCD934X_CDC_RX1_RX_PATH_CFG0; + ctl_reg = WCD934X_CDC_RX1_RX_PATH_CTL; + clk_reg = WCD934X_MIXING_ASRC0_CLK_RST_CTL; + asrc_ctl = WCD934X_MIXING_ASRC0_CTL1; + asrc = ASRC0; + break; + case ASRC_IN_LO1: + cfg_reg = WCD934X_CDC_RX3_RX_PATH_CFG0; + ctl_reg = WCD934X_CDC_RX3_RX_PATH_CTL; + clk_reg = WCD934X_MIXING_ASRC0_CLK_RST_CTL; + asrc_ctl = WCD934X_MIXING_ASRC0_CTL1; + asrc = ASRC0; + break; + case ASRC_IN_HPHR: + cfg_reg = WCD934X_CDC_RX2_RX_PATH_CFG0; + ctl_reg = WCD934X_CDC_RX2_RX_PATH_CTL; + clk_reg = WCD934X_MIXING_ASRC1_CLK_RST_CTL; + asrc_ctl = WCD934X_MIXING_ASRC1_CTL1; + asrc = ASRC1; + break; + case ASRC_IN_LO2: + cfg_reg = WCD934X_CDC_RX4_RX_PATH_CFG0; + ctl_reg = WCD934X_CDC_RX4_RX_PATH_CTL; + clk_reg = WCD934X_MIXING_ASRC1_CLK_RST_CTL; + asrc_ctl = WCD934X_MIXING_ASRC1_CTL1; + asrc = ASRC1; + break; + case ASRC_IN_SPKR1: + cfg_reg = WCD934X_CDC_RX7_RX_PATH_CFG0; + ctl_reg = WCD934X_CDC_RX7_RX_PATH_CTL; + clk_reg = WCD934X_MIXING_ASRC2_CLK_RST_CTL; + asrc_ctl = WCD934X_MIXING_ASRC2_CTL1; + asrc = ASRC2; + break; + case ASRC_IN_SPKR2: + cfg_reg = WCD934X_CDC_RX8_RX_PATH_CFG0; + ctl_reg = WCD934X_CDC_RX8_RX_PATH_CTL; + clk_reg = WCD934X_MIXING_ASRC3_CLK_RST_CTL; + asrc_ctl = WCD934X_MIXING_ASRC3_CTL1; + asrc = ASRC3; + break; + default: + dev_err(codec->dev, "%s: Invalid asrc input :%d\n", __func__, + asrc_in); + ret = -EINVAL; + goto done; + }; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (tavil->asrc_users[asrc] == 0) { + snd_soc_update_bits(codec, cfg_reg, 0x80, 0x80); + snd_soc_update_bits(codec, clk_reg, 0x01, 0x01); + main_sr = snd_soc_read(codec, ctl_reg) & 0x0F; + mix_ctl_reg = ctl_reg + 5; + mix_sr = snd_soc_read(codec, mix_ctl_reg) & 0x0F; + asrc_mode = tavil_get_asrc_mode(tavil, asrc, + main_sr, mix_sr); + dev_dbg(codec->dev, "%s: main_sr:%d mix_sr:%d asrc_mode %d\n", + __func__, main_sr, mix_sr, asrc_mode); + snd_soc_update_bits(codec, asrc_ctl, 0x07, asrc_mode); + } + tavil->asrc_users[asrc]++; + break; + case SND_SOC_DAPM_POST_PMD: + tavil->asrc_users[asrc]--; + if (tavil->asrc_users[asrc] <= 0) { + tavil->asrc_users[asrc] = 0; + snd_soc_update_bits(codec, asrc_ctl, 0x07, 0x00); + snd_soc_update_bits(codec, cfg_reg, 0x80, 0x00); + snd_soc_update_bits(codec, clk_reg, 0x01, 0x00); + } + break; + }; + + dev_dbg(codec->dev, "%s: ASRC%d, users: %d\n", + __func__, asrc, tavil->asrc_users[asrc]); + +done: + return ret; +} + +static int tavil_codec_enable_asrc_resampler(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int ret = 0; + u8 cfg, asrc_in; + + cfg = snd_soc_read(codec, WCD934X_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0); + if (!(cfg & 0xFF)) { + dev_err(codec->dev, "%s: ASRC%u input not selected\n", + __func__, w->shift); + return -EINVAL; + } + + switch (w->shift) { + case ASRC0: + asrc_in = ((cfg & 0x03) == 1) ? ASRC_IN_HPHL : ASRC_IN_LO1; + ret = tavil_codec_enable_asrc(codec, asrc_in, event); + break; + case ASRC1: + asrc_in = ((cfg & 0x0C) == 4) ? ASRC_IN_HPHR : ASRC_IN_LO2; + ret = tavil_codec_enable_asrc(codec, asrc_in, event); + break; + case ASRC2: + asrc_in = ((cfg & 0x30) == 0x20) ? ASRC_IN_SPKR1 : ASRC_INVALID; + ret = tavil_codec_enable_asrc(codec, asrc_in, event); + break; + case ASRC3: + asrc_in = ((cfg & 0xC0) == 0x80) ? ASRC_IN_SPKR2 : ASRC_INVALID; + ret = tavil_codec_enable_asrc(codec, asrc_in, event); + break; + default: + dev_err(codec->dev, "%s: Invalid asrc:%u\n", __func__, + w->shift); + ret = -EINVAL; + break; + }; + + return ret; +} + +static int tavil_enable_native_supply(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (++tavil->native_clk_users == 1) { + snd_soc_update_bits(codec, WCD934X_CLK_SYS_PLL_ENABLES, + 0x01, 0x01); + usleep_range(100, 120); + snd_soc_update_bits(codec, WCD934X_CLK_SYS_MCLK2_PRG1, + 0x06, 0x02); + snd_soc_update_bits(codec, WCD934X_CLK_SYS_MCLK2_PRG1, + 0x01, 0x01); + snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_GATE, + 0x04, 0x00); + usleep_range(30, 50); + snd_soc_update_bits(codec, + WCD934X_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x02, 0x02); + snd_soc_update_bits(codec, + WCD934X_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x10, 0x10); + } + break; + case SND_SOC_DAPM_PRE_PMD: + if (tavil->native_clk_users && + (--tavil->native_clk_users == 0)) { + snd_soc_update_bits(codec, + WCD934X_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x10, 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x02, 0x00); + snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_GATE, + 0x04, 0x04); + snd_soc_update_bits(codec, WCD934X_CLK_SYS_MCLK2_PRG1, + 0x01, 0x00); + snd_soc_update_bits(codec, WCD934X_CLK_SYS_MCLK2_PRG1, + 0x06, 0x00); + snd_soc_update_bits(codec, WCD934X_CLK_SYS_PLL_ENABLES, + 0x01, 0x00); + } + break; + } + + dev_dbg(codec->dev, "%s: native_clk_users: %d, event: %d\n", + __func__, tavil->native_clk_users, event); + + return 0; +} + +static void tavil_codec_hphdelay_lutbypass(struct snd_soc_codec *codec, + u16 interp_idx, int event) +{ + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + u8 hph_dly_mask; + u16 hph_lut_bypass_reg = 0; + u16 hph_comp_ctrl7 = 0; + + + switch (interp_idx) { + case INTERP_HPHL: + hph_dly_mask = 1; + hph_lut_bypass_reg = WCD934X_CDC_TOP_HPHL_COMP_LUT; + hph_comp_ctrl7 = WCD934X_CDC_COMPANDER1_CTL7; + break; + case INTERP_HPHR: + hph_dly_mask = 2; + hph_lut_bypass_reg = WCD934X_CDC_TOP_HPHR_COMP_LUT; + hph_comp_ctrl7 = WCD934X_CDC_COMPANDER2_CTL7; + break; + default: + break; + } + + if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) { + snd_soc_update_bits(codec, WCD934X_CDC_CLSH_TEST0, + hph_dly_mask, 0x0); + snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x80); + if (tavil->hph_mode == CLS_H_ULP) + snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x20); + } + + if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, WCD934X_CDC_CLSH_TEST0, + hph_dly_mask, hph_dly_mask); + snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x00); + snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x0); + } +} + +static void tavil_codec_hd2_control(struct tavil_priv *priv, + u16 interp_idx, int event) +{ + u16 hd2_scale_reg; + u16 hd2_enable_reg = 0; + struct snd_soc_codec *codec = priv->codec; + + if (TAVIL_IS_1_1(priv->wcd9xxx)) + return; + + switch (interp_idx) { + case INTERP_HPHL: + hd2_scale_reg = WCD934X_CDC_RX1_RX_PATH_SEC3; + hd2_enable_reg = WCD934X_CDC_RX1_RX_PATH_CFG0; + break; + case INTERP_HPHR: + hd2_scale_reg = WCD934X_CDC_RX2_RX_PATH_SEC3; + hd2_enable_reg = WCD934X_CDC_RX2_RX_PATH_CFG0; + break; + } + + if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { + snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x14); + snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x04); + } + + if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x00); + snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x00); + } +} + +static int tavil_codec_config_ear_spkr_gain(struct snd_soc_codec *codec, + int event, int gain_reg) +{ + int comp_gain_offset, val; + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + switch (tavil->swr.spkr_mode) { + /* Compander gain in SPKR_MODE1 case is 12 dB */ + case WCD934X_SPKR_MODE_1: + comp_gain_offset = -12; + break; + /* Default case compander gain is 15 dB */ + default: + comp_gain_offset = -15; + break; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* Apply ear spkr gain only if compander is enabled */ + if (tavil->comp_enabled[COMPANDER_7] && + (gain_reg == WCD934X_CDC_RX7_RX_VOL_CTL || + gain_reg == WCD934X_CDC_RX7_RX_VOL_MIX_CTL) && + (tavil->ear_spkr_gain != 0)) { + /* For example, val is -8(-12+5-1) for 4dB of gain */ + val = comp_gain_offset + tavil->ear_spkr_gain - 1; + snd_soc_write(codec, gain_reg, val); + + dev_dbg(codec->dev, "%s: RX7 Volume %d dB\n", + __func__, val); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* + * Reset RX7 volume to 0 dB if compander is enabled and + * ear_spkr_gain is non-zero. + */ + if (tavil->comp_enabled[COMPANDER_7] && + (gain_reg == WCD934X_CDC_RX7_RX_VOL_CTL || + gain_reg == WCD934X_CDC_RX7_RX_VOL_MIX_CTL) && + (tavil->ear_spkr_gain != 0)) { + snd_soc_write(codec, gain_reg, 0x0); + + dev_dbg(codec->dev, "%s: Reset RX7 Volume to 0 dB\n", + __func__); + } + break; + } + + return 0; +} + +static int tavil_config_compander(struct snd_soc_codec *codec, int interp_n, + int event) +{ + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + int comp; + u16 comp_ctl0_reg, rx_path_cfg0_reg; + + /* EAR does not have compander */ + if (!interp_n) + return 0; + + comp = interp_n - 1; + dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n", + __func__, event, comp + 1, tavil->comp_enabled[comp]); + + if (!tavil->comp_enabled[comp]) + return 0; + + comp_ctl0_reg = WCD934X_CDC_COMPANDER1_CTL0 + (comp * 8); + rx_path_cfg0_reg = WCD934X_CDC_RX1_RX_PATH_CFG0 + (comp * 20); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Compander Clock */ + snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); + } + + return 0; +} + +static void tavil_codec_idle_detect_control(struct snd_soc_codec *codec, + int interp, int event) +{ + int reg = 0, mask, val; + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + if (!tavil->idle_det_cfg.hph_idle_detect_en) + return; + + if (interp == INTERP_HPHL) { + reg = WCD934X_CDC_RX_IDLE_DET_PATH_CTL; + mask = 0x01; + val = 0x01; + } + if (interp == INTERP_HPHR) { + reg = WCD934X_CDC_RX_IDLE_DET_PATH_CTL; + mask = 0x02; + val = 0x02; + } + + if (reg && SND_SOC_DAPM_EVENT_ON(event)) + snd_soc_update_bits(codec, reg, mask, val); + + if (reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, reg, mask, 0x00); + tavil->idle_det_cfg.hph_idle_thr = 0; + snd_soc_write(codec, WCD934X_CDC_RX_IDLE_DET_CFG3, 0x0); + } +} + +/** + * tavil_codec_enable_interp_clk - Enable main path Interpolator + * clock. + * + * @codec: Codec instance + * @event: Indicates speaker path gain offset value + * @intp_idx: Interpolator index + * Returns number of main clock users + */ +int tavil_codec_enable_interp_clk(struct snd_soc_codec *codec, + int event, int interp_idx) +{ + struct tavil_priv *tavil; + u16 main_reg; + + if (!codec) { + pr_err("%s: codec is NULL\n", __func__); + return -EINVAL; + } + + tavil = snd_soc_codec_get_drvdata(codec); + main_reg = WCD934X_CDC_RX0_RX_PATH_CTL + (interp_idx * 20); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + if (tavil->main_clk_users[interp_idx] == 0) { + /* Main path PGA mute enable */ + snd_soc_update_bits(codec, main_reg, 0x10, 0x10); + /* Clk enable */ + snd_soc_update_bits(codec, main_reg, 0x20, 0x20); + tavil_codec_idle_detect_control(codec, interp_idx, + event); + tavil_codec_hd2_control(tavil, interp_idx, event); + tavil_codec_hphdelay_lutbypass(codec, interp_idx, + event); + tavil_config_compander(codec, interp_idx, event); + } + tavil->main_clk_users[interp_idx]++; + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + tavil->main_clk_users[interp_idx]--; + if (tavil->main_clk_users[interp_idx] <= 0) { + tavil->main_clk_users[interp_idx] = 0; + tavil_config_compander(codec, interp_idx, event); + tavil_codec_hphdelay_lutbypass(codec, interp_idx, + event); + tavil_codec_hd2_control(tavil, interp_idx, event); + tavil_codec_idle_detect_control(codec, interp_idx, + event); + /* Clk Disable */ + snd_soc_update_bits(codec, main_reg, 0x20, 0x00); + /* Reset enable and disable */ + snd_soc_update_bits(codec, main_reg, 0x40, 0x40); + snd_soc_update_bits(codec, main_reg, 0x40, 0x00); + /* Reset rate to 48K*/ + snd_soc_update_bits(codec, main_reg, 0x0F, 0x04); + } + } + + dev_dbg(codec->dev, "%s event %d main_clk_users %d\n", + __func__, event, tavil->main_clk_users[interp_idx]); + + return tavil->main_clk_users[interp_idx]; +} +EXPORT_SYMBOL(tavil_codec_enable_interp_clk); + +static int tavil_anc_out_switch_cb(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + tavil_codec_enable_interp_clk(codec, event, w->shift); + + return 0; +} +static int tavil_codec_set_idle_detect_thr(struct snd_soc_codec *codec, + int interp, int path_type) +{ + int port_id[4] = { 0, 0, 0, 0 }; + int *port_ptr, num_ports; + int bit_width = 0, i; + int mux_reg, mux_reg_val; + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + int dai_id, idle_thr; + + if ((interp != INTERP_HPHL) && (interp != INTERP_HPHR)) + return 0; + + if (!tavil->idle_det_cfg.hph_idle_detect_en) + return 0; + + port_ptr = &port_id[0]; + num_ports = 0; + + /* + * Read interpolator MUX input registers and find + * which slimbus port is connected and store the port + * numbers in port_id array. + */ + if (path_type == INTERP_MIX_PATH) { + mux_reg = WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG1 + + 2 * (interp - 1); + mux_reg_val = snd_soc_read(codec, mux_reg) & 0x0f; + + if ((mux_reg_val >= INTn_2_INP_SEL_RX0) && + (mux_reg_val < INTn_2_INP_SEL_PROXIMITY)) { + *port_ptr++ = mux_reg_val + + WCD934X_RX_PORT_START_NUMBER - 1; + num_ports++; + } + } + + if (path_type == INTERP_MAIN_PATH) { + mux_reg = WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG0 + + 2 * (interp - 1); + mux_reg_val = snd_soc_read(codec, mux_reg) & 0x0f; + i = WCD934X_INTERP_MUX_NUM_INPUTS; + + while (i) { + if ((mux_reg_val >= INTn_1_INP_SEL_RX0) && + (mux_reg_val <= INTn_1_INP_SEL_RX7)) { + *port_ptr++ = mux_reg_val + + WCD934X_RX_PORT_START_NUMBER - + INTn_1_INP_SEL_RX0; + num_ports++; + } + mux_reg_val = (snd_soc_read(codec, mux_reg) & + 0xf0) >> 4; + mux_reg += 1; + i--; + } + } + + dev_dbg(codec->dev, "%s: num_ports: %d, ports[%d %d %d %d]\n", + __func__, num_ports, port_id[0], port_id[1], + port_id[2], port_id[3]); + + i = 0; + while (num_ports) { + dai_id = tavil_find_playback_dai_id_for_port(port_id[i++], + tavil); + + if ((dai_id >= 0) && (dai_id < NUM_CODEC_DAIS)) { + dev_dbg(codec->dev, "%s: dai_id: %d bit_width: %d\n", + __func__, dai_id, + tavil->dai[dai_id].bit_width); + + if (tavil->dai[dai_id].bit_width > bit_width) + bit_width = tavil->dai[dai_id].bit_width; + } + + num_ports--; + } + + switch (bit_width) { + case 16: + idle_thr = 0xff; /* F16 */ + break; + case 24: + case 32: + idle_thr = 0x03; /* F22 */ + break; + default: + idle_thr = 0x00; + break; + } + + dev_dbg(codec->dev, "%s: (new) idle_thr: %d, (cur) idle_thr: %d\n", + __func__, idle_thr, tavil->idle_det_cfg.hph_idle_thr); + + if ((tavil->idle_det_cfg.hph_idle_thr == 0) || + (idle_thr < tavil->idle_det_cfg.hph_idle_thr)) { + snd_soc_write(codec, WCD934X_CDC_RX_IDLE_DET_CFG3, idle_thr); + tavil->idle_det_cfg.hph_idle_thr = idle_thr; + } + + return 0; +} + +static int tavil_codec_enable_mix_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + u16 gain_reg, mix_reg; + int offset_val = 0; + int val = 0; + + if (w->shift >= WCD934X_NUM_INTERPOLATORS || + w->shift == INTERP_LO3_NA || w->shift == INTERP_LO4_NA) { + dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", + __func__, w->shift, w->name); + return -EINVAL; + }; + + gain_reg = WCD934X_CDC_RX0_RX_VOL_MIX_CTL + + (w->shift * WCD934X_RX_PATH_CTL_OFFSET); + mix_reg = WCD934X_CDC_RX0_RX_PATH_MIX_CTL + + (w->shift * WCD934X_RX_PATH_CTL_OFFSET); + + if (w->shift == INTERP_SPKR1 || w->shift == INTERP_SPKR2) + __tavil_codec_enable_swr(w, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + tavil_codec_set_idle_detect_thr(codec, w->shift, + INTERP_MIX_PATH); + tavil_codec_enable_interp_clk(codec, event, w->shift); + /* Clk enable */ + snd_soc_update_bits(codec, mix_reg, 0x20, 0x20); + break; + case SND_SOC_DAPM_POST_PMU: + if ((tavil->swr.spkr_gain_offset == + WCD934X_RX_GAIN_OFFSET_M1P5_DB) && + (tavil->comp_enabled[COMPANDER_7] || + tavil->comp_enabled[COMPANDER_8]) && + (gain_reg == WCD934X_CDC_RX7_RX_VOL_MIX_CTL || + gain_reg == WCD934X_CDC_RX8_RX_VOL_MIX_CTL)) { + snd_soc_update_bits(codec, WCD934X_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_update_bits(codec, + WCD934X_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x01); + snd_soc_update_bits(codec, WCD934X_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_update_bits(codec, + WCD934X_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x01); + offset_val = -2; + } + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + tavil_codec_config_ear_spkr_gain(codec, event, gain_reg); + break; + case SND_SOC_DAPM_POST_PMD: + /* Clk Disable */ + snd_soc_update_bits(codec, mix_reg, 0x20, 0x00); + tavil_codec_enable_interp_clk(codec, event, w->shift); + /* Reset enable and disable */ + snd_soc_update_bits(codec, mix_reg, 0x40, 0x40); + snd_soc_update_bits(codec, mix_reg, 0x40, 0x00); + + if ((tavil->swr.spkr_gain_offset == + WCD934X_RX_GAIN_OFFSET_M1P5_DB) && + (tavil->comp_enabled[COMPANDER_7] || + tavil->comp_enabled[COMPANDER_8]) && + (gain_reg == WCD934X_CDC_RX7_RX_VOL_MIX_CTL || + gain_reg == WCD934X_CDC_RX8_RX_VOL_MIX_CTL)) { + snd_soc_update_bits(codec, WCD934X_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x00); + snd_soc_update_bits(codec, WCD934X_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x00); + offset_val = 2; + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + } + tavil_codec_config_ear_spkr_gain(codec, event, gain_reg); + break; + }; + dev_dbg(codec->dev, "%s event %d name %s\n", __func__, event, w->name); + + return 0; +} + +/** + * tavil_get_dsd_config - Get pointer to dsd config structure + * + * @codec: pointer to snd_soc_codec structure + * + * Returns pointer to tavil_dsd_config structure + */ +struct tavil_dsd_config *tavil_get_dsd_config(struct snd_soc_codec *codec) +{ + struct tavil_priv *tavil; + + if (!codec) + return NULL; + + tavil = snd_soc_codec_get_drvdata(codec); + + if (!tavil) + return NULL; + + return tavil->dsd_config; +} +EXPORT_SYMBOL(tavil_get_dsd_config); + +static int tavil_codec_enable_main_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + u16 gain_reg; + u16 reg; + int val; + int offset_val = 0; + + dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + + if (w->shift >= WCD934X_NUM_INTERPOLATORS || + w->shift == INTERP_LO3_NA || w->shift == INTERP_LO4_NA) { + dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", + __func__, w->shift, w->name); + return -EINVAL; + }; + + reg = WCD934X_CDC_RX0_RX_PATH_CTL + (w->shift * + WCD934X_RX_PATH_CTL_OFFSET); + gain_reg = WCD934X_CDC_RX0_RX_VOL_CTL + (w->shift * + WCD934X_RX_PATH_CTL_OFFSET); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + tavil_codec_set_idle_detect_thr(codec, w->shift, + INTERP_MAIN_PATH); + tavil_codec_enable_interp_clk(codec, event, w->shift); + break; + case SND_SOC_DAPM_POST_PMU: + /* apply gain after int clk is enabled */ + if ((tavil->swr.spkr_gain_offset == + WCD934X_RX_GAIN_OFFSET_M1P5_DB) && + (tavil->comp_enabled[COMPANDER_7] || + tavil->comp_enabled[COMPANDER_8]) && + (gain_reg == WCD934X_CDC_RX7_RX_VOL_CTL || + gain_reg == WCD934X_CDC_RX8_RX_VOL_CTL)) { + snd_soc_update_bits(codec, WCD934X_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_update_bits(codec, + WCD934X_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x01); + snd_soc_update_bits(codec, WCD934X_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_update_bits(codec, + WCD934X_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x01); + offset_val = -2; + } + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + tavil_codec_config_ear_spkr_gain(codec, event, gain_reg); + break; + case SND_SOC_DAPM_POST_PMD: + tavil_codec_enable_interp_clk(codec, event, w->shift); + + if ((tavil->swr.spkr_gain_offset == + WCD934X_RX_GAIN_OFFSET_M1P5_DB) && + (tavil->comp_enabled[COMPANDER_7] || + tavil->comp_enabled[COMPANDER_8]) && + (gain_reg == WCD934X_CDC_RX7_RX_VOL_CTL || + gain_reg == WCD934X_CDC_RX8_RX_VOL_CTL)) { + snd_soc_update_bits(codec, WCD934X_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x00); + snd_soc_update_bits(codec, WCD934X_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD934X_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x00); + offset_val = 2; + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + } + tavil_codec_config_ear_spkr_gain(codec, event, gain_reg); + break; + }; + + return 0; +} + +static int tavil_codec_set_iir_gain(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: /* fall through */ + case SND_SOC_DAPM_PRE_PMD: + if (strnstr(w->name, "IIR0", sizeof("IIR0"))) { + snd_soc_write(codec, + WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, + snd_soc_read(codec, + WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)); + snd_soc_write(codec, + WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, + snd_soc_read(codec, + WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)); + snd_soc_write(codec, + WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, + snd_soc_read(codec, + WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)); + snd_soc_write(codec, + WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, + snd_soc_read(codec, + WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)); + } else { + snd_soc_write(codec, + WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, + snd_soc_read(codec, + WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL)); + snd_soc_write(codec, + WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, + snd_soc_read(codec, + WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL)); + snd_soc_write(codec, + WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, + snd_soc_read(codec, + WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL)); + } + break; + } + return 0; +} + +static int tavil_codec_find_amic_input(struct snd_soc_codec *codec, + int adc_mux_n) +{ + u16 mask, shift, adc_mux_in_reg; + u16 amic_mux_sel_reg; + bool is_amic; + + if (adc_mux_n < 0 || adc_mux_n > WCD934X_MAX_VALID_ADC_MUX || + adc_mux_n == WCD934X_INVALID_ADC_MUX) + return 0; + + if (adc_mux_n < 3) { + adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + + adc_mux_n; + mask = 0x03; + shift = 0; + amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + + 2 * adc_mux_n; + } else if (adc_mux_n < 4) { + adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1; + mask = 0x03; + shift = 0; + amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + + 2 * adc_mux_n; + } else if (adc_mux_n < 7) { + adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + + (adc_mux_n - 4); + mask = 0x0C; + shift = 2; + amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + + adc_mux_n - 4; + } else if (adc_mux_n < 8) { + adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1; + mask = 0x0C; + shift = 2; + amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + + adc_mux_n - 4; + } else if (adc_mux_n < 12) { + adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + + ((adc_mux_n == 8) ? (adc_mux_n - 8) : + (adc_mux_n - 9)); + mask = 0x30; + shift = 4; + amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + + adc_mux_n - 4; + } else if (adc_mux_n < 13) { + adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1; + mask = 0x30; + shift = 4; + amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + + adc_mux_n - 4; + } else { + adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1; + mask = 0xC0; + shift = 6; + amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + + adc_mux_n - 4; + } + + is_amic = (((snd_soc_read(codec, adc_mux_in_reg) & mask) >> shift) + == 1); + if (!is_amic) + return 0; + + return snd_soc_read(codec, amic_mux_sel_reg) & 0x07; +} + +static void tavil_codec_set_tx_hold(struct snd_soc_codec *codec, + u16 amic_reg, bool set) +{ + u8 mask = 0x20; + u8 val; + + if (amic_reg == WCD934X_ANA_AMIC1 || + amic_reg == WCD934X_ANA_AMIC3) + mask = 0x40; + + val = set ? mask : 0x00; + + switch (amic_reg) { + case WCD934X_ANA_AMIC1: + case WCD934X_ANA_AMIC2: + snd_soc_update_bits(codec, WCD934X_ANA_AMIC2, mask, val); + break; + case WCD934X_ANA_AMIC3: + case WCD934X_ANA_AMIC4: + snd_soc_update_bits(codec, WCD934X_ANA_AMIC4, mask, val); + break; + default: + dev_dbg(codec->dev, "%s: invalid amic: %d\n", + __func__, amic_reg); + break; + } +} + +static int tavil_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + int adc_mux_n = w->shift; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + int amic_n; + + dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + amic_n = tavil_codec_find_amic_input(codec, adc_mux_n); + if (amic_n) { + /* + * Prevent ANC Rx pop by leaving Tx FE in HOLD + * state until PA is up. Track AMIC being used + * so we can release the HOLD later. + */ + set_bit(ANC_MIC_AMIC1 + amic_n - 1, + &tavil->status_mask); + } + break; + default: + break; + } + + return 0; +} + +static u16 tavil_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic) +{ + u16 pwr_level_reg = 0; + + switch (amic) { + case 1: + case 2: + pwr_level_reg = WCD934X_ANA_AMIC1; + break; + + case 3: + case 4: + pwr_level_reg = WCD934X_ANA_AMIC3; + break; + default: + dev_dbg(codec->dev, "%s: invalid amic: %d\n", + __func__, amic); + break; + } + + return pwr_level_reg; +} + +#define TX_HPF_CUT_OFF_FREQ_MASK 0x60 +#define CF_MIN_3DB_4HZ 0x0 +#define CF_MIN_3DB_75HZ 0x1 +#define CF_MIN_3DB_150HZ 0x2 + +static void tavil_tx_hpf_corner_freq_callback(struct work_struct *work) +{ + struct delayed_work *hpf_delayed_work; + struct hpf_work *hpf_work; + struct tavil_priv *tavil; + struct snd_soc_codec *codec; + u16 dec_cfg_reg, amic_reg, go_bit_reg; + u8 hpf_cut_off_freq; + int amic_n; + + hpf_delayed_work = to_delayed_work(work); + hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); + tavil = hpf_work->tavil; + codec = tavil->codec; + hpf_cut_off_freq = hpf_work->hpf_cut_off_freq; + + dec_cfg_reg = WCD934X_CDC_TX0_TX_PATH_CFG0 + 16 * hpf_work->decimator; + go_bit_reg = dec_cfg_reg + 7; + + dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", + __func__, hpf_work->decimator, hpf_cut_off_freq); + + amic_n = tavil_codec_find_amic_input(codec, hpf_work->decimator); + if (amic_n) { + amic_reg = WCD934X_ANA_AMIC1 + amic_n - 1; + tavil_codec_set_tx_hold(codec, amic_reg, false); + } + snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x02); + /* Minimum 1 clk cycle delay is required as per HW spec */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x00); +} + +static void tavil_tx_mute_update_callback(struct work_struct *work) +{ + struct tx_mute_work *tx_mute_dwork; + struct tavil_priv *tavil; + struct delayed_work *delayed_work; + struct snd_soc_codec *codec; + u16 tx_vol_ctl_reg, hpf_gate_reg; + + delayed_work = to_delayed_work(work); + tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); + tavil = tx_mute_dwork->tavil; + codec = tavil->codec; + + tx_vol_ctl_reg = WCD934X_CDC_TX0_TX_PATH_CTL + + 16 * tx_mute_dwork->decimator; + hpf_gate_reg = WCD934X_CDC_TX0_TX_PATH_SEC2 + + 16 * tx_mute_dwork->decimator; + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); +} + +static int tavil_codec_enable_rx_path_clk(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 sidetone_reg; + + dev_dbg(codec->dev, "%s %d %d\n", __func__, event, w->shift); + sidetone_reg = WCD934X_CDC_RX0_RX_PATH_CFG1 + 0x14*(w->shift); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (!strcmp(w->name, "RX INT7 MIX2 INP")) + __tavil_codec_enable_swr(w, event); + tavil_codec_enable_interp_clk(codec, event, w->shift); + snd_soc_update_bits(codec, sidetone_reg, 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, sidetone_reg, 0x10, 0x00); + tavil_codec_enable_interp_clk(codec, event, w->shift); + if (!strcmp(w->name, "RX INT7 MIX2 INP")) + __tavil_codec_enable_swr(w, event); + break; + default: + break; + }; + return 0; +} + +static int tavil_codec_enable_dec(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + unsigned int decimator; + char *dec_adc_mux_name = NULL; + char *widget_name = NULL; + char *wname; + int ret = 0, amic_n; + u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg; + u16 tx_gain_ctl_reg; + char *dec; + u8 hpf_cut_off_freq; + + dev_dbg(codec->dev, "%s %d\n", __func__, event); + + widget_name = kstrndup(w->name, 15, GFP_KERNEL); + if (!widget_name) + return -ENOMEM; + + wname = widget_name; + dec_adc_mux_name = strsep(&widget_name, " "); + if (!dec_adc_mux_name) { + dev_err(codec->dev, "%s: Invalid decimator = %s\n", + __func__, w->name); + ret = -EINVAL; + goto out; + } + dec_adc_mux_name = widget_name; + + dec = strpbrk(dec_adc_mux_name, "012345678"); + if (!dec) { + dev_err(codec->dev, "%s: decimator index not found\n", + __func__); + ret = -EINVAL; + goto out; + } + + ret = kstrtouint(dec, 10, &decimator); + if (ret < 0) { + dev_err(codec->dev, "%s: Invalid decimator = %s\n", + __func__, wname); + ret = -EINVAL; + goto out; + } + + dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__, + w->name, decimator); + + tx_vol_ctl_reg = WCD934X_CDC_TX0_TX_PATH_CTL + 16 * decimator; + hpf_gate_reg = WCD934X_CDC_TX0_TX_PATH_SEC2 + 16 * decimator; + dec_cfg_reg = WCD934X_CDC_TX0_TX_PATH_CFG0 + 16 * decimator; + tx_gain_ctl_reg = WCD934X_CDC_TX0_TX_VOL_CTL + 16 * decimator; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + amic_n = tavil_codec_find_amic_input(codec, decimator); + if (amic_n) + pwr_level_reg = tavil_codec_get_amic_pwlvl_reg(codec, + amic_n); + + if (pwr_level_reg) { + switch ((snd_soc_read(codec, pwr_level_reg) & + WCD934X_AMIC_PWR_LVL_MASK) >> + WCD934X_AMIC_PWR_LVL_SHIFT) { + case WCD934X_AMIC_PWR_LEVEL_LP: + snd_soc_update_bits(codec, dec_cfg_reg, + WCD934X_DEC_PWR_LVL_MASK, + WCD934X_DEC_PWR_LVL_LP); + break; + + case WCD934X_AMIC_PWR_LEVEL_HP: + snd_soc_update_bits(codec, dec_cfg_reg, + WCD934X_DEC_PWR_LVL_MASK, + WCD934X_DEC_PWR_LVL_HP); + break; + case WCD934X_AMIC_PWR_LEVEL_DEFAULT: + default: + snd_soc_update_bits(codec, dec_cfg_reg, + WCD934X_DEC_PWR_LVL_MASK, + WCD934X_DEC_PWR_LVL_DF); + break; + } + } + /* Enable TX PGA Mute */ + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMU: + hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) & + TX_HPF_CUT_OFF_FREQ_MASK) >> 5; + + tavil->tx_hpf_work[decimator].hpf_cut_off_freq = + hpf_cut_off_freq; + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { + snd_soc_update_bits(codec, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + CF_MIN_3DB_150HZ << 5); + snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); + /* + * Minimum 1 clk cycle delay is required as per + * HW spec. + */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00); + } + /* schedule work queue to Remove Mute */ + schedule_delayed_work(&tavil->tx_mute_dwork[decimator].dwork, + msecs_to_jiffies(tx_unmute_delay)); + if (tavil->tx_hpf_work[decimator].hpf_cut_off_freq != + CF_MIN_3DB_150HZ) + schedule_delayed_work( + &tavil->tx_hpf_work[decimator].dwork, + msecs_to_jiffies(300)); + /* apply gain after decimator is enabled */ + snd_soc_write(codec, tx_gain_ctl_reg, + snd_soc_read(codec, tx_gain_ctl_reg)); + break; + case SND_SOC_DAPM_PRE_PMD: + hpf_cut_off_freq = + tavil->tx_hpf_work[decimator].hpf_cut_off_freq; + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + if (cancel_delayed_work_sync( + &tavil->tx_hpf_work[decimator].dwork)) { + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { + snd_soc_update_bits(codec, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_update_bits(codec, hpf_gate_reg, + 0x02, 0x02); + /* + * Minimum 1 clk cycle delay is required as per + * HW spec. + */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, hpf_gate_reg, + 0x02, 0x00); + } + } + cancel_delayed_work_sync( + &tavil->tx_mute_dwork[decimator].dwork); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); + snd_soc_update_bits(codec, dec_cfg_reg, + WCD934X_DEC_PWR_LVL_MASK, + WCD934X_DEC_PWR_LVL_DF); + break; + }; +out: + kfree(wname); + return ret; +} + +static u32 tavil_get_dmic_sample_rate(struct snd_soc_codec *codec, + unsigned int dmic, + struct wcd9xxx_pdata *pdata) +{ + u8 tx_stream_fs; + u8 adc_mux_index = 0, adc_mux_sel = 0; + bool dec_found = false; + u16 adc_mux_ctl_reg, tx_fs_reg; + u32 dmic_fs; + + while (dec_found == 0 && adc_mux_index < WCD934X_MAX_VALID_ADC_MUX) { + if (adc_mux_index < 4) { + adc_mux_ctl_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + + (adc_mux_index * 2); + } else if (adc_mux_index < WCD934X_INVALID_ADC_MUX) { + adc_mux_ctl_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + + adc_mux_index - 4; + } else if (adc_mux_index == WCD934X_INVALID_ADC_MUX) { + ++adc_mux_index; + continue; + } + adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) & + 0xF8) >> 3) - 1; + + if (adc_mux_sel == dmic) { + dec_found = true; + break; + } + + ++adc_mux_index; + } + + if (dec_found && adc_mux_index <= 8) { + tx_fs_reg = WCD934X_CDC_TX0_TX_PATH_CTL + (16 * adc_mux_index); + tx_stream_fs = snd_soc_read(codec, tx_fs_reg) & 0x0F; + if (tx_stream_fs <= 4) { + if (pdata->dmic_sample_rate <= + WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ) + dmic_fs = pdata->dmic_sample_rate; + else + dmic_fs = WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ; + } else + dmic_fs = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ; + } else { + dmic_fs = pdata->dmic_sample_rate; + } + + return dmic_fs; +} + +static u8 tavil_get_dmic_clk_val(struct snd_soc_codec *codec, + u32 mclk_rate, u32 dmic_clk_rate) +{ + u32 div_factor; + u8 dmic_ctl_val; + + dev_dbg(codec->dev, + "%s: mclk_rate = %d, dmic_sample_rate = %d\n", + __func__, mclk_rate, dmic_clk_rate); + + /* Default value to return in case of error */ + if (mclk_rate == WCD934X_MCLK_CLK_9P6MHZ) + dmic_ctl_val = WCD934X_DMIC_CLK_DIV_2; + else + dmic_ctl_val = WCD934X_DMIC_CLK_DIV_3; + + if (dmic_clk_rate == 0) { + dev_err(codec->dev, + "%s: dmic_sample_rate cannot be 0\n", + __func__); + goto done; + } + + div_factor = mclk_rate / dmic_clk_rate; + switch (div_factor) { + case 2: + dmic_ctl_val = WCD934X_DMIC_CLK_DIV_2; + break; + case 3: + dmic_ctl_val = WCD934X_DMIC_CLK_DIV_3; + break; + case 4: + dmic_ctl_val = WCD934X_DMIC_CLK_DIV_4; + break; + case 6: + dmic_ctl_val = WCD934X_DMIC_CLK_DIV_6; + break; + case 8: + dmic_ctl_val = WCD934X_DMIC_CLK_DIV_8; + break; + case 16: + dmic_ctl_val = WCD934X_DMIC_CLK_DIV_16; + break; + default: + dev_err(codec->dev, + "%s: Invalid div_factor %u, clk_rate(%u), dmic_rate(%u)\n", + __func__, div_factor, mclk_rate, dmic_clk_rate); + break; + } + +done: + return dmic_ctl_val; +} + +static int tavil_codec_enable_adc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s: event:%d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + tavil_codec_set_tx_hold(codec, w->reg, true); + break; + default: + break; + } + + return 0; +} + +static int tavil_codec_enable_dmic(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + u8 dmic_clk_en = 0x01; + u16 dmic_clk_reg; + s32 *dmic_clk_cnt; + u8 dmic_rate_val, dmic_rate_shift = 1; + unsigned int dmic; + u32 dmic_sample_rate; + int ret; + char *wname; + + wname = strpbrk(w->name, "012345"); + if (!wname) { + dev_err(codec->dev, "%s: widget not found\n", __func__); + return -EINVAL; + } + + ret = kstrtouint(wname, 10, &dmic); + if (ret < 0) { + dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n", + __func__); + return -EINVAL; + } + + switch (dmic) { + case 0: + case 1: + dmic_clk_cnt = &(tavil->dmic_0_1_clk_cnt); + dmic_clk_reg = WCD934X_CPE_SS_DMIC0_CTL; + break; + case 2: + case 3: + dmic_clk_cnt = &(tavil->dmic_2_3_clk_cnt); + dmic_clk_reg = WCD934X_CPE_SS_DMIC1_CTL; + break; + case 4: + case 5: + dmic_clk_cnt = &(tavil->dmic_4_5_clk_cnt); + dmic_clk_reg = WCD934X_CPE_SS_DMIC2_CTL; + break; + default: + dev_err(codec->dev, "%s: Invalid DMIC Selection\n", + __func__); + return -EINVAL; + }; + dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", + __func__, event, dmic, *dmic_clk_cnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + dmic_sample_rate = tavil_get_dmic_sample_rate(codec, dmic, + pdata); + dmic_rate_val = + tavil_get_dmic_clk_val(codec, + pdata->mclk_rate, + dmic_sample_rate); + + (*dmic_clk_cnt)++; + if (*dmic_clk_cnt == 1) { + snd_soc_update_bits(codec, dmic_clk_reg, + 0x07 << dmic_rate_shift, + dmic_rate_val << dmic_rate_shift); + snd_soc_update_bits(codec, dmic_clk_reg, + dmic_clk_en, dmic_clk_en); + } + + break; + case SND_SOC_DAPM_POST_PMD: + dmic_rate_val = + tavil_get_dmic_clk_val(codec, + pdata->mclk_rate, + pdata->mad_dmic_sample_rate); + (*dmic_clk_cnt)--; + if (*dmic_clk_cnt == 0) { + snd_soc_update_bits(codec, dmic_clk_reg, + dmic_clk_en, 0); + snd_soc_update_bits(codec, dmic_clk_reg, + 0x07 << dmic_rate_shift, + dmic_rate_val << dmic_rate_shift); + } + break; + }; + + return 0; +} + +/* + * tavil_mbhc_micb_adjust_voltage: adjust specific micbias voltage + * @codec: handle to snd_soc_codec * + * @req_volt: micbias voltage to be set + * @micb_num: micbias to be set, e.g. micbias1 or micbias2 + * + * return 0 if adjustment is success or error code in case of failure + */ +int tavil_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, + int req_volt, int micb_num) +{ + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + int cur_vout_ctl, req_vout_ctl; + int micb_reg, micb_val, micb_en; + int ret = 0; + + switch (micb_num) { + case MIC_BIAS_1: + micb_reg = WCD934X_ANA_MICB1; + break; + case MIC_BIAS_2: + micb_reg = WCD934X_ANA_MICB2; + break; + case MIC_BIAS_3: + micb_reg = WCD934X_ANA_MICB3; + break; + case MIC_BIAS_4: + micb_reg = WCD934X_ANA_MICB4; + break; + default: + return -EINVAL; + } + mutex_lock(&tavil->micb_lock); + + /* + * If requested micbias voltage is same as current micbias + * voltage, then just return. Otherwise, adjust voltage as + * per requested value. If micbias is already enabled, then + * to avoid slow micbias ramp-up or down enable pull-up + * momentarily, change the micbias value and then re-enable + * micbias. + */ + micb_val = snd_soc_read(codec, micb_reg); + micb_en = (micb_val & 0xC0) >> 6; + cur_vout_ctl = micb_val & 0x3F; + + req_vout_ctl = wcd934x_get_micb_vout_ctl_val(req_volt); + if (req_vout_ctl < 0) { + ret = -EINVAL; + goto exit; + } + if (cur_vout_ctl == req_vout_ctl) { + ret = 0; + goto exit; + } + + dev_dbg(codec->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n", + __func__, micb_num, WCD_VOUT_CTL_TO_MICB(cur_vout_ctl), + req_volt, micb_en); + + if (micb_en == 0x1) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + + snd_soc_update_bits(codec, micb_reg, 0x3F, req_vout_ctl); + + if (micb_en == 0x1) { + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + /* + * Add 2ms delay as per HW requirement after enabling + * micbias + */ + usleep_range(2000, 2100); + } +exit: + mutex_unlock(&tavil->micb_lock); + return ret; +} +EXPORT_SYMBOL(tavil_mbhc_micb_adjust_voltage); + +/* + * tavil_micbias_control: enable/disable micbias + * @codec: handle to snd_soc_codec * + * @micb_num: micbias to be enabled/disabled, e.g. micbias1 or micbias2 + * @req: control requested, enable/disable or pullup enable/disable + * @is_dapm: triggered by dapm or not + * + * return 0 if control is success or error code in case of failure + */ +int tavil_micbias_control(struct snd_soc_codec *codec, + int micb_num, int req, bool is_dapm) +{ + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + int micb_index = micb_num - 1; + u16 micb_reg; + int pre_off_event = 0, post_off_event = 0; + int post_on_event = 0, post_dapm_off = 0; + int post_dapm_on = 0; + + if ((micb_index < 0) || (micb_index > TAVIL_MAX_MICBIAS - 1)) { + dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n", + __func__, micb_index); + return -EINVAL; + } + + switch (micb_num) { + case MIC_BIAS_1: + micb_reg = WCD934X_ANA_MICB1; + break; + case MIC_BIAS_2: + micb_reg = WCD934X_ANA_MICB2; + pre_off_event = WCD_EVENT_PRE_MICBIAS_2_OFF; + post_off_event = WCD_EVENT_POST_MICBIAS_2_OFF; + post_on_event = WCD_EVENT_POST_MICBIAS_2_ON; + post_dapm_on = WCD_EVENT_POST_DAPM_MICBIAS_2_ON; + post_dapm_off = WCD_EVENT_POST_DAPM_MICBIAS_2_OFF; + break; + case MIC_BIAS_3: + micb_reg = WCD934X_ANA_MICB3; + break; + case MIC_BIAS_4: + micb_reg = WCD934X_ANA_MICB4; + break; + default: + dev_err(codec->dev, "%s: Invalid micbias number: %d\n", + __func__, micb_num); + return -EINVAL; + } + mutex_lock(&tavil->micb_lock); + + switch (req) { + case MICB_PULLUP_ENABLE: + tavil->pullup_ref[micb_index]++; + if ((tavil->pullup_ref[micb_index] == 1) && + (tavil->micb_ref[micb_index] == 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + break; + case MICB_PULLUP_DISABLE: + if (tavil->pullup_ref[micb_index] > 0) + tavil->pullup_ref[micb_index]--; + if ((tavil->pullup_ref[micb_index] == 0) && + (tavil->micb_ref[micb_index] == 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + break; + case MICB_ENABLE: + tavil->micb_ref[micb_index]++; + if (tavil->micb_ref[micb_index] == 1) { + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + if (post_on_event && tavil->mbhc) + blocking_notifier_call_chain( + &tavil->mbhc->notifier, + post_on_event, + &tavil->mbhc->wcd_mbhc); + } + if (is_dapm && post_dapm_on && tavil->mbhc) + blocking_notifier_call_chain(&tavil->mbhc->notifier, + post_dapm_on, &tavil->mbhc->wcd_mbhc); + break; + case MICB_DISABLE: + if (tavil->micb_ref[micb_index] > 0) + tavil->micb_ref[micb_index]--; + if ((tavil->micb_ref[micb_index] == 0) && + (tavil->pullup_ref[micb_index] > 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + else if ((tavil->micb_ref[micb_index] == 0) && + (tavil->pullup_ref[micb_index] == 0)) { + if (pre_off_event && tavil->mbhc) + blocking_notifier_call_chain( + &tavil->mbhc->notifier, + pre_off_event, + &tavil->mbhc->wcd_mbhc); + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + if (post_off_event && tavil->mbhc) + blocking_notifier_call_chain( + &tavil->mbhc->notifier, + post_off_event, + &tavil->mbhc->wcd_mbhc); + } + if (is_dapm && post_dapm_off && tavil->mbhc) + blocking_notifier_call_chain(&tavil->mbhc->notifier, + post_dapm_off, &tavil->mbhc->wcd_mbhc); + break; + }; + + dev_dbg(codec->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", + __func__, micb_num, tavil->micb_ref[micb_index], + tavil->pullup_ref[micb_index]); + + mutex_unlock(&tavil->micb_lock); + + return 0; +} +EXPORT_SYMBOL(tavil_micbias_control); + +static int __tavil_codec_enable_micbias(struct snd_soc_dapm_widget *w, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int micb_num; + + dev_dbg(codec->dev, "%s: wname: %s, event: %d\n", + __func__, w->name, event); + + if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) + micb_num = MIC_BIAS_1; + else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2"))) + micb_num = MIC_BIAS_2; + else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3"))) + micb_num = MIC_BIAS_3; + else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4"))) + micb_num = MIC_BIAS_4; + else + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* + * MIC BIAS can also be requested by MBHC, + * so use ref count to handle micbias pullup + * and enable requests + */ + tavil_micbias_control(codec, micb_num, MICB_ENABLE, true); + break; + case SND_SOC_DAPM_POST_PMU: + /* wait for cnp time */ + usleep_range(1000, 1100); + break; + case SND_SOC_DAPM_POST_PMD: + tavil_micbias_control(codec, micb_num, MICB_DISABLE, true); + break; + }; + + return 0; +} + +/* + * tavil_codec_enable_standalone_micbias - enable micbias standalone + * @codec: pointer to codec instance + * @micb_num: number of micbias to be enabled + * @enable: true to enable micbias or false to disable + * + * This function is used to enable micbias (1, 2, 3 or 4) during + * standalone independent of whether TX use-case is running or not + * + * Return: error code in case of failure or 0 for success + */ +int tavil_codec_enable_standalone_micbias(struct snd_soc_codec *codec, + int micb_num, + bool enable) +{ + const char * const micb_names[] = { + DAPM_MICBIAS1_STANDALONE, DAPM_MICBIAS2_STANDALONE, + DAPM_MICBIAS3_STANDALONE, DAPM_MICBIAS4_STANDALONE + }; + int micb_index = micb_num - 1; + int rc; + + if (!codec) { + pr_err("%s: Codec memory is NULL\n", __func__); + return -EINVAL; + } + + if ((micb_index < 0) || (micb_index > TAVIL_MAX_MICBIAS - 1)) { + dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n", + __func__, micb_index); + return -EINVAL; + } + + if (enable) + rc = snd_soc_dapm_force_enable_pin( + snd_soc_codec_get_dapm(codec), + micb_names[micb_index]); + else + rc = snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(codec), + micb_names[micb_index]); + + if (!rc) + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + else + dev_err(codec->dev, "%s: micbias%d force %s pin failed\n", + __func__, micb_num, (enable ? "enable" : "disable")); + + return rc; +} +EXPORT_SYMBOL(tavil_codec_enable_standalone_micbias); + +static int tavil_codec_force_enable_micbias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + int ret = 0; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd_resmgr_enable_master_bias(tavil->resmgr); + tavil_cdc_mclk_enable(codec, true); + ret = __tavil_codec_enable_micbias(w, SND_SOC_DAPM_PRE_PMU); + /* Wait for 1ms for better cnp */ + usleep_range(1000, 1100); + tavil_cdc_mclk_enable(codec, false); + break; + case SND_SOC_DAPM_POST_PMD: + ret = __tavil_codec_enable_micbias(w, SND_SOC_DAPM_POST_PMD); + wcd_resmgr_disable_master_bias(tavil->resmgr); + break; + } + + return ret; +} + +static int tavil_codec_enable_micbias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + return __tavil_codec_enable_micbias(w, event); +} + + +static const struct reg_sequence tavil_hph_reset_tbl[] = { + { WCD934X_HPH_CNP_EN, 0x80 }, + { WCD934X_HPH_CNP_WG_CTL, 0x9A }, + { WCD934X_HPH_CNP_WG_TIME, 0x14 }, + { WCD934X_HPH_OCP_CTL, 0x28 }, + { WCD934X_HPH_AUTO_CHOP, 0x16 }, + { WCD934X_HPH_CHOP_CTL, 0x83 }, + { WCD934X_HPH_PA_CTL1, 0x46 }, + { WCD934X_HPH_PA_CTL2, 0x50 }, + { WCD934X_HPH_L_EN, 0x80 }, + { WCD934X_HPH_L_TEST, 0xE0 }, + { WCD934X_HPH_L_ATEST, 0x50 }, + { WCD934X_HPH_R_EN, 0x80 }, + { WCD934X_HPH_R_TEST, 0xE0 }, + { WCD934X_HPH_R_ATEST, 0x54 }, + { WCD934X_HPH_RDAC_CLK_CTL1, 0x99 }, + { WCD934X_HPH_RDAC_CLK_CTL2, 0x9B }, + { WCD934X_HPH_RDAC_LDO_CTL, 0x33 }, + { WCD934X_HPH_RDAC_CHOP_CLK_LP_CTL, 0x00 }, + { WCD934X_HPH_REFBUFF_UHQA_CTL, 0xA8 }, +}; + +static const struct reg_sequence tavil_hph_reset_tbl_1_0[] = { + { WCD934X_HPH_REFBUFF_LP_CTL, 0x0A }, + { WCD934X_HPH_L_DAC_CTL, 0x00 }, + { WCD934X_HPH_R_DAC_CTL, 0x00 }, + { WCD934X_HPH_NEW_ANA_HPH2, 0x00 }, + { WCD934X_HPH_NEW_ANA_HPH3, 0x00 }, + { WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, 0x00 }, + { WCD934X_HPH_NEW_INT_RDAC_HD2_CTL, 0xA0 }, + { WCD934X_HPH_NEW_INT_RDAC_VREF_CTL, 0x10 }, + { WCD934X_HPH_NEW_INT_RDAC_OVERRIDE_CTL, 0x00 }, + { WCD934X_HPH_NEW_INT_RDAC_MISC1, 0x00 }, + { WCD934X_HPH_NEW_INT_PA_MISC1, 0x22 }, + { WCD934X_HPH_NEW_INT_PA_MISC2, 0x00 }, + { WCD934X_HPH_NEW_INT_PA_RDAC_MISC, 0x00 }, + { WCD934X_HPH_NEW_INT_HPH_TIMER1, 0xFE }, + { WCD934X_HPH_NEW_INT_HPH_TIMER2, 0x2 }, + { WCD934X_HPH_NEW_INT_HPH_TIMER3, 0x4e}, + { WCD934X_HPH_NEW_INT_HPH_TIMER4, 0x54 }, + { WCD934X_HPH_NEW_INT_PA_RDAC_MISC2, 0x00 }, + { WCD934X_HPH_NEW_INT_PA_RDAC_MISC3, 0x00 }, +}; + +static const struct reg_sequence tavil_hph_reset_tbl_1_1[] = { + { WCD934X_HPH_REFBUFF_LP_CTL, 0x0E }, + { WCD934X_HPH_L_DAC_CTL, 0x00 }, + { WCD934X_HPH_R_DAC_CTL, 0x00 }, + { WCD934X_HPH_NEW_ANA_HPH2, 0x00 }, + { WCD934X_HPH_NEW_ANA_HPH3, 0x00 }, + { WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, 0x40 }, + { WCD934X_HPH_NEW_INT_RDAC_HD2_CTL, 0x81 }, + { WCD934X_HPH_NEW_INT_RDAC_VREF_CTL, 0x10 }, + { WCD934X_HPH_NEW_INT_RDAC_OVERRIDE_CTL, 0x00 }, + { WCD934X_HPH_NEW_INT_RDAC_MISC1, 0x81 }, + { WCD934X_HPH_NEW_INT_PA_MISC1, 0x22 }, + { WCD934X_HPH_NEW_INT_PA_MISC2, 0x00 }, + { WCD934X_HPH_NEW_INT_PA_RDAC_MISC, 0x00 }, + { WCD934X_HPH_NEW_INT_HPH_TIMER1, 0xFE }, + { WCD934X_HPH_NEW_INT_HPH_TIMER2, 0x2 }, + { WCD934X_HPH_NEW_INT_HPH_TIMER3, 0x4e}, + { WCD934X_HPH_NEW_INT_HPH_TIMER4, 0x54 }, + { WCD934X_HPH_NEW_INT_PA_RDAC_MISC2, 0x00 }, + { WCD934X_HPH_NEW_INT_PA_RDAC_MISC3, 0x00 }, +}; + +static const struct tavil_reg_mask_val tavil_pa_disable[] = { + { WCD934X_CDC_RX1_RX_PATH_CTL, 0x30, 0x10 }, /* RX1 mute enable */ + { WCD934X_CDC_RX2_RX_PATH_CTL, 0x30, 0x10 }, /* RX2 mute enable */ + { WCD934X_HPH_CNP_WG_CTL, 0x80, 0x00 }, /* GM3 boost disable */ + { WCD934X_ANA_HPH, 0x80, 0x00 }, /* HPHL PA disable */ + { WCD934X_ANA_HPH, 0x40, 0x00 }, /* HPHR PA disable */ + { WCD934X_ANA_HPH, 0x20, 0x00 }, /* HPHL REF dsable */ + { WCD934X_ANA_HPH, 0x10, 0x00 }, /* HPHR REF disable */ +}; + +static const struct tavil_reg_mask_val tavil_ocp_en_seq[] = { + { WCD934X_RX_OCP_CTL, 0x0F, 0x02 }, /* OCP number of attempts is 2 */ + { WCD934X_HPH_OCP_CTL, 0xFA, 0x3A }, /* OCP current limit */ + { WCD934X_HPH_L_TEST, 0x01, 0x01 }, /* Enable HPHL OCP */ + { WCD934X_HPH_R_TEST, 0x01, 0x01 }, /* Enable HPHR OCP */ +}; + +static const struct tavil_reg_mask_val tavil_ocp_en_seq_1[] = { + { WCD934X_RX_OCP_CTL, 0x0F, 0x02 }, /* OCP number of attempts is 2 */ + { WCD934X_HPH_OCP_CTL, 0xFA, 0x3A }, /* OCP current limit */ +}; + +/* LO-HIFI */ +static const struct tavil_reg_mask_val tavil_pre_pa_en_lohifi[] = { + { WCD934X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00 }, + { WCD934X_FLYBACK_VNEG_CTRL_4, 0xf0, 0x80 }, + { WCD934X_HPH_NEW_INT_PA_MISC2, 0x20, 0x20 }, + { WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, 0xf0, 0x40 }, + { WCD934X_HPH_CNP_WG_CTL, 0x80, 0x00 }, + { WCD934X_RX_BIAS_HPH_LOWPOWER, 0xf0, 0xc0 }, + { WCD934X_HPH_PA_CTL1, 0x0e, 0x02 }, + { WCD934X_HPH_REFBUFF_LP_CTL, 0x06, 0x06 }, +}; + +static const struct tavil_reg_mask_val tavil_pre_pa_en[] = { + { WCD934X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00 }, + { WCD934X_HPH_NEW_INT_PA_MISC2, 0x20, 0x0 }, + { WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, 0xf0, 0x40 }, + { WCD934X_HPH_CNP_WG_CTL, 0x80, 0x00 }, + { WCD934X_RX_BIAS_HPH_LOWPOWER, 0xf0, 0x80 }, + { WCD934X_HPH_PA_CTL1, 0x0e, 0x06 }, + { WCD934X_HPH_REFBUFF_LP_CTL, 0x06, 0x06 }, +}; + +static const struct tavil_reg_mask_val tavil_post_pa_en[] = { + { WCD934X_HPH_L_TEST, 0x01, 0x01 }, /* Enable HPHL OCP */ + { WCD934X_HPH_R_TEST, 0x01, 0x01 }, /* Enable HPHR OCP */ + { WCD934X_CDC_RX1_RX_PATH_CTL, 0x30, 0x20 }, /* RX1 mute disable */ + { WCD934X_CDC_RX2_RX_PATH_CTL, 0x30, 0x20 }, /* RX2 mute disable */ + { WCD934X_HPH_CNP_WG_CTL, 0x80, 0x80 }, /* GM3 boost enable */ + { WCD934X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02 }, +}; + +static void tavil_codec_hph_reg_range_read(struct regmap *map, u8 *buf) +{ + regmap_bulk_read(map, WCD934X_HPH_CNP_EN, buf, TAVIL_HPH_REG_RANGE_1); + regmap_bulk_read(map, WCD934X_HPH_NEW_ANA_HPH2, + buf + TAVIL_HPH_REG_RANGE_1, TAVIL_HPH_REG_RANGE_2); + regmap_bulk_read(map, WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, + buf + TAVIL_HPH_REG_RANGE_1 + TAVIL_HPH_REG_RANGE_2, + TAVIL_HPH_REG_RANGE_3); +} + +static void tavil_codec_hph_reg_recover(struct tavil_priv *tavil, + struct regmap *map, int pa_status) +{ + int i; + unsigned int reg; + + blocking_notifier_call_chain(&tavil->mbhc->notifier, + WCD_EVENT_OCP_OFF, + &tavil->mbhc->wcd_mbhc); + + if (pa_status & 0xC0) + goto pa_en_restore; + + dev_dbg(tavil->dev, "%s: HPH PA in disable state (0x%x)\n", + __func__, pa_status); + + regmap_write_bits(map, WCD934X_CDC_RX1_RX_PATH_CTL, 0x10, 0x10); + regmap_write_bits(map, WCD934X_CDC_RX2_RX_PATH_CTL, 0x10, 0x10); + regmap_write_bits(map, WCD934X_ANA_HPH, 0xC0, 0x00); + regmap_write_bits(map, WCD934X_ANA_HPH, 0x30, 0x00); + regmap_write_bits(map, WCD934X_CDC_RX1_RX_PATH_CTL, 0x10, 0x00); + regmap_write_bits(map, WCD934X_CDC_RX2_RX_PATH_CTL, 0x10, 0x00); + + /* Restore to HW defaults */ + regmap_multi_reg_write(map, tavil_hph_reset_tbl, + ARRAY_SIZE(tavil_hph_reset_tbl)); + if (TAVIL_IS_1_1(tavil->wcd9xxx)) + regmap_multi_reg_write(map, tavil_hph_reset_tbl_1_1, + ARRAY_SIZE(tavil_hph_reset_tbl_1_1)); + if (TAVIL_IS_1_0(tavil->wcd9xxx)) + regmap_multi_reg_write(map, tavil_hph_reset_tbl_1_0, + ARRAY_SIZE(tavil_hph_reset_tbl_1_0)); + + for (i = 0; i < ARRAY_SIZE(tavil_ocp_en_seq); i++) + regmap_write_bits(map, tavil_ocp_en_seq[i].reg, + tavil_ocp_en_seq[i].mask, + tavil_ocp_en_seq[i].val); + goto end; + + +pa_en_restore: + dev_dbg(tavil->dev, "%s: HPH PA in enable state (0x%x)\n", + __func__, pa_status); + + /* Disable PA and other registers before restoring */ + for (i = 0; i < ARRAY_SIZE(tavil_pa_disable); i++) { + if (TAVIL_IS_1_1(tavil->wcd9xxx) && + (tavil_pa_disable[i].reg == WCD934X_HPH_CNP_WG_CTL)) + continue; + regmap_write_bits(map, tavil_pa_disable[i].reg, + tavil_pa_disable[i].mask, + tavil_pa_disable[i].val); + } + + regmap_multi_reg_write(map, tavil_hph_reset_tbl, + ARRAY_SIZE(tavil_hph_reset_tbl)); + if (TAVIL_IS_1_1(tavil->wcd9xxx)) + regmap_multi_reg_write(map, tavil_hph_reset_tbl_1_1, + ARRAY_SIZE(tavil_hph_reset_tbl_1_1)); + if (TAVIL_IS_1_0(tavil->wcd9xxx)) + regmap_multi_reg_write(map, tavil_hph_reset_tbl_1_0, + ARRAY_SIZE(tavil_hph_reset_tbl_1_0)); + + for (i = 0; i < ARRAY_SIZE(tavil_ocp_en_seq_1); i++) + regmap_write_bits(map, tavil_ocp_en_seq_1[i].reg, + tavil_ocp_en_seq_1[i].mask, + tavil_ocp_en_seq_1[i].val); + + if (tavil->hph_mode == CLS_H_LOHIFI) { + for (i = 0; i < ARRAY_SIZE(tavil_pre_pa_en_lohifi); i++) { + reg = tavil_pre_pa_en_lohifi[i].reg; + if ((TAVIL_IS_1_1(tavil->wcd9xxx)) && + ((reg == WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL) || + (reg == WCD934X_HPH_CNP_WG_CTL) || + (reg == WCD934X_HPH_REFBUFF_LP_CTL))) + continue; + regmap_write_bits(map, + tavil_pre_pa_en_lohifi[i].reg, + tavil_pre_pa_en_lohifi[i].mask, + tavil_pre_pa_en_lohifi[i].val); + } + } else { + for (i = 0; i < ARRAY_SIZE(tavil_pre_pa_en); i++) { + reg = tavil_pre_pa_en[i].reg; + if ((TAVIL_IS_1_1(tavil->wcd9xxx)) && + ((reg == WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL) || + (reg == WCD934X_HPH_CNP_WG_CTL) || + (reg == WCD934X_HPH_REFBUFF_LP_CTL))) + continue; + regmap_write_bits(map, tavil_pre_pa_en[i].reg, + tavil_pre_pa_en[i].mask, + tavil_pre_pa_en[i].val); + } + } + + if (TAVIL_IS_1_1(tavil->wcd9xxx)) { + regmap_write(map, WCD934X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x84); + regmap_write(map, WCD934X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x84); + } + + regmap_write_bits(map, WCD934X_ANA_HPH, 0x0C, pa_status & 0x0C); + regmap_write_bits(map, WCD934X_ANA_HPH, 0x30, 0x30); + /* wait for 100usec after HPH DAC is enabled */ + usleep_range(100, 110); + regmap_write(map, WCD934X_ANA_HPH, pa_status); + /* Sleep for 7msec after PA is enabled */ + usleep_range(7000, 7100); + + for (i = 0; i < ARRAY_SIZE(tavil_post_pa_en); i++) { + if ((TAVIL_IS_1_1(tavil->wcd9xxx)) && + (tavil_post_pa_en[i].reg == WCD934X_HPH_CNP_WG_CTL)) + continue; + regmap_write_bits(map, tavil_post_pa_en[i].reg, + tavil_post_pa_en[i].mask, + tavil_post_pa_en[i].val); + } + +end: + tavil->mbhc->is_hph_recover = true; + blocking_notifier_call_chain( + &tavil->mbhc->notifier, + WCD_EVENT_OCP_ON, + &tavil->mbhc->wcd_mbhc); +} + +static int tavil_codec_reset_hph_registers(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + u8 cache_val[TAVIL_HPH_TOTAL_REG]; + u8 hw_val[TAVIL_HPH_TOTAL_REG]; + int pa_status; + int ret; + + dev_dbg(wcd9xxx->dev, "%s: event: %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + memset(cache_val, 0, TAVIL_HPH_TOTAL_REG); + memset(hw_val, 0, TAVIL_HPH_TOTAL_REG); + + regmap_read(wcd9xxx->regmap, WCD934X_ANA_HPH, &pa_status); + + tavil_codec_hph_reg_range_read(wcd9xxx->regmap, cache_val); + + /* Read register values from HW directly */ + regcache_cache_bypass(wcd9xxx->regmap, true); + tavil_codec_hph_reg_range_read(wcd9xxx->regmap, hw_val); + regcache_cache_bypass(wcd9xxx->regmap, false); + + /* compare both the registers to know if there is corruption */ + ret = memcmp(cache_val, hw_val, TAVIL_HPH_TOTAL_REG); + + /* If both the values are same, it means no corruption */ + if (ret) { + dev_dbg(codec->dev, "%s: cache and hw reg are not same\n", + __func__); + tavil_codec_hph_reg_recover(tavil, wcd9xxx->regmap, + pa_status); + } else { + dev_dbg(codec->dev, "%s: cache and hw reg are same\n", + __func__); + tavil->mbhc->is_hph_recover = false; + } + break; + default: + break; + }; + + return 0; +} + +static int tavil_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + /* IIR filter band registers are at integer multiples of 16 */ + u16 iir_reg = WCD934X_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx; + + ucontrol->value.integer.value[0] = (snd_soc_read(codec, iir_reg) & + (1 << band_idx)) != 0; + + dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, + iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[0]); + return 0; +} + +static int tavil_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + bool iir_band_en_status; + int value = ucontrol->value.integer.value[0]; + u16 iir_reg = WCD934X_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx; + + /* Mask first 5 bits, 6-8 are reserved */ + snd_soc_update_bits(codec, iir_reg, (1 << band_idx), + (value << band_idx)); + + iir_band_en_status = ((snd_soc_read(codec, iir_reg) & + (1 << band_idx)) != 0); + dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, + iir_idx, band_idx, iir_band_en_status); + return 0; +} + +static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec, + int iir_idx, int band_idx, + int coeff_idx) +{ + uint32_t value = 0; + + /* Address does not automatically update if reading */ + snd_soc_write(codec, + (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t)) & 0x7F); + + value |= snd_soc_read(codec, + (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx)); + + snd_soc_write(codec, + (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 1) & 0x7F); + + value |= (snd_soc_read(codec, + (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + + 16 * iir_idx)) << 8); + + snd_soc_write(codec, + (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 2) & 0x7F); + + value |= (snd_soc_read(codec, + (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + + 16 * iir_idx)) << 16); + + snd_soc_write(codec, + (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 3) & 0x7F); + + /* Mask bits top 2 bits since they are reserved */ + value |= ((snd_soc_read(codec, + (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + + 16 * iir_idx)) & 0x3F) << 24); + + return value; +} + +static int tavil_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + ucontrol->value.integer.value[0] = + get_iir_band_coeff(codec, iir_idx, band_idx, 0); + ucontrol->value.integer.value[1] = + get_iir_band_coeff(codec, iir_idx, band_idx, 1); + ucontrol->value.integer.value[2] = + get_iir_band_coeff(codec, iir_idx, band_idx, 2); + ucontrol->value.integer.value[3] = + get_iir_band_coeff(codec, iir_idx, band_idx, 3); + ucontrol->value.integer.value[4] = + get_iir_band_coeff(codec, iir_idx, band_idx, 4); + + dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n" + "%s: IIR #%d band #%d b1 = 0x%x\n" + "%s: IIR #%d band #%d b2 = 0x%x\n" + "%s: IIR #%d band #%d a1 = 0x%x\n" + "%s: IIR #%d band #%d a2 = 0x%x\n", + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[0], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[1], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[2], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[3], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[4]); + return 0; +} + +static void set_iir_band_coeff(struct snd_soc_codec *codec, + int iir_idx, int band_idx, + uint32_t value) +{ + snd_soc_write(codec, + (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), + (value & 0xFF)); + + snd_soc_write(codec, + (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), + (value >> 8) & 0xFF); + + snd_soc_write(codec, + (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), + (value >> 16) & 0xFF); + + /* Mask top 2 bits, 7-8 are reserved */ + snd_soc_write(codec, + (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), + (value >> 24) & 0x3F); +} + +static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int coeff_idx; + + /* + * Mask top bit it is reserved + * Updates addr automatically for each B2 write + */ + snd_soc_write(codec, + (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); + + /* Store the coefficients in sidetone coeff array */ + for (coeff_idx = 0; coeff_idx < WCD934X_CDC_SIDETONE_IIR_COEFF_MAX; + coeff_idx++) { + tavil->sidetone_coeff_array[iir_idx][band_idx][coeff_idx] = + ucontrol->value.integer.value[coeff_idx]; + set_iir_band_coeff(codec, iir_idx, band_idx, + tavil->sidetone_coeff_array[iir_idx][band_idx] + [coeff_idx]); + } + + pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n" + "%s: IIR #%d band #%d b1 = 0x%x\n" + "%s: IIR #%d band #%d b2 = 0x%x\n" + "%s: IIR #%d band #%d a1 = 0x%x\n" + "%s: IIR #%d band #%d a2 = 0x%x\n", + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 0), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 1), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 2), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 3), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 4)); + return 0; +} + +static void tavil_restore_iir_coeff(struct tavil_priv *tavil, int iir_idx) +{ + int band_idx = 0, coeff_idx = 0; + struct snd_soc_codec *codec = tavil->codec; + + for (band_idx = 0; band_idx < BAND_MAX; band_idx++) { + snd_soc_write(codec, + (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); + + for (coeff_idx = 0; + coeff_idx < WCD934X_CDC_SIDETONE_IIR_COEFF_MAX; + coeff_idx++) { + set_iir_band_coeff(codec, iir_idx, band_idx, + tavil->sidetone_coeff_array[iir_idx][band_idx] + [coeff_idx]); + } + } +} + +static int tavil_compander_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = tavil->comp_enabled[comp]; + return 0; +} + +static int tavil_compander_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int value = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n", + __func__, comp + 1, tavil->comp_enabled[comp], value); + tavil->comp_enabled[comp] = value; + + /* Any specific register configuration for compander */ + switch (comp) { + case COMPANDER_1: + /* Set Gain Source Select based on compander enable/disable */ + snd_soc_update_bits(codec, WCD934X_HPH_L_EN, 0x20, + (value ? 0x00:0x20)); + break; + case COMPANDER_2: + snd_soc_update_bits(codec, WCD934X_HPH_R_EN, 0x20, + (value ? 0x00:0x20)); + break; + case COMPANDER_3: + case COMPANDER_4: + case COMPANDER_7: + case COMPANDER_8: + break; + default: + /* + * if compander is not enabled for any interpolator, + * it does not cause any audio failure, so do not + * return error in this case, but just print a log + */ + dev_warn(codec->dev, "%s: unknown compander: %d\n", + __func__, comp); + }; + return 0; +} + +static int tavil_hph_asrc_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + int index = -EINVAL; + + if (!strcmp(kcontrol->id.name, "ASRC0 Output Mode")) + index = ASRC0; + if (!strcmp(kcontrol->id.name, "ASRC1 Output Mode")) + index = ASRC1; + + if (tavil && (index >= 0) && (index < ASRC_MAX)) + tavil->asrc_output_mode[index] = + ucontrol->value.integer.value[0]; + + return 0; +} + +static int tavil_hph_asrc_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + int val = 0; + int index = -EINVAL; + + if (!strcmp(kcontrol->id.name, "ASRC0 Output Mode")) + index = ASRC0; + if (!strcmp(kcontrol->id.name, "ASRC1 Output Mode")) + index = ASRC1; + + if (tavil && (index >= 0) && (index < ASRC_MAX)) + val = tavil->asrc_output_mode[index]; + + ucontrol->value.integer.value[0] = val; + + return 0; +} + +static int tavil_hph_idle_detect_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + int val = 0; + + if (tavil) + val = tavil->idle_det_cfg.hph_idle_detect_en; + + ucontrol->value.integer.value[0] = val; + + return 0; +} + +static int tavil_hph_idle_detect_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + if (tavil) + tavil->idle_det_cfg.hph_idle_detect_en = + ucontrol->value.integer.value[0]; + + return 0; +} + +static int tavil_dmic_pin_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u16 dmic_pin; + u8 reg_val, pinctl_position; + + pinctl_position = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + dmic_pin = pinctl_position & 0x07; + reg_val = snd_soc_read(codec, + WCD934X_TLMM_DMIC1_CLK_PINCFG + dmic_pin - 1); + + ucontrol->value.integer.value[0] = !!reg_val; + + return 0; +} + +static int tavil_dmic_pin_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + u16 ctl_reg, cfg_reg, dmic_pin; + u8 ctl_val, cfg_val, pinctl_position, pinctl_mode, mask; + + /* 0- high or low; 1- high Z */ + pinctl_mode = ucontrol->value.integer.value[0]; + pinctl_position = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + switch (pinctl_position >> 3) { + case 0: + ctl_reg = WCD934X_TEST_DEBUG_PIN_CTL_OE_0; + break; + case 1: + ctl_reg = WCD934X_TEST_DEBUG_PIN_CTL_OE_1; + break; + case 2: + ctl_reg = WCD934X_TEST_DEBUG_PIN_CTL_OE_2; + break; + case 3: + ctl_reg = WCD934X_TEST_DEBUG_PIN_CTL_OE_3; + break; + default: + dev_err(codec->dev, "%s: Invalid pinctl position = %d\n", + __func__, pinctl_position); + return -EINVAL; + } + + ctl_val = ~(pinctl_mode << (pinctl_position & 0x07)); + mask = 1 << (pinctl_position & 0x07); + snd_soc_update_bits(codec, ctl_reg, mask, ctl_val); + + dmic_pin = pinctl_position & 0x07; + cfg_reg = WCD934X_TLMM_DMIC1_CLK_PINCFG + dmic_pin - 1; + if (pinctl_mode) { + if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) + cfg_val = 0x6; + else + cfg_val = 0xD; + } else + cfg_val = 0; + snd_soc_update_bits(codec, cfg_reg, 0x1F, cfg_val); + + dev_dbg(codec->dev, "%s: reg=0x%x mask=0x%x val=%d reg=0x%x val=%d\n", + __func__, ctl_reg, mask, ctl_val, cfg_reg, cfg_val); + + return 0; +} + +static int tavil_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u16 amic_reg = 0; + + if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE")) + amic_reg = WCD934X_ANA_AMIC1; + if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE")) + amic_reg = WCD934X_ANA_AMIC3; + + if (amic_reg) + ucontrol->value.integer.value[0] = + (snd_soc_read(codec, amic_reg) & + WCD934X_AMIC_PWR_LVL_MASK) >> + WCD934X_AMIC_PWR_LVL_SHIFT; + return 0; +} + +static int tavil_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u32 mode_val; + u16 amic_reg = 0; + + mode_val = ucontrol->value.enumerated.item[0]; + + dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val); + + if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE")) + amic_reg = WCD934X_ANA_AMIC1; + if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE")) + amic_reg = WCD934X_ANA_AMIC3; + + if (amic_reg) + snd_soc_update_bits(codec, amic_reg, WCD934X_AMIC_PWR_LVL_MASK, + mode_val << WCD934X_AMIC_PWR_LVL_SHIFT); + return 0; +} + +static const char *const tavil_conn_mad_text[] = { + "NOTUSED1", "ADC1", "ADC2", "ADC3", "ADC4", "NOTUSED5", + "NOTUSED6", "NOTUSED2", "DMIC0", "DMIC1", "DMIC2", "DMIC3", + "DMIC4", "DMIC5", "NOTUSED3", "NOTUSED4" +}; + +static const struct soc_enum tavil_conn_mad_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tavil_conn_mad_text), + tavil_conn_mad_text); + +static int tavil_mad_input_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u8 tavil_mad_input; + + tavil_mad_input = snd_soc_read(codec, WCD934X_SOC_MAD_INP_SEL) & 0x0F; + ucontrol->value.integer.value[0] = tavil_mad_input; + + dev_dbg(codec->dev, "%s: tavil_mad_input = %s\n", __func__, + tavil_conn_mad_text[tavil_mad_input]); + + return 0; +} + +static int tavil_mad_input_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_card *card = codec->component.card; + u8 tavil_mad_input; + char mad_amic_input_widget[6]; + const char *mad_input_widget; + const char *source_widget = NULL; + u32 adc, i, mic_bias_found = 0; + int ret = 0; + char *mad_input; + bool is_adc_input = false; + + tavil_mad_input = ucontrol->value.integer.value[0]; + + if (tavil_mad_input >= sizeof(tavil_conn_mad_text)/ + sizeof(tavil_conn_mad_text[0])) { + dev_err(codec->dev, + "%s: tavil_mad_input = %d out of bounds\n", + __func__, tavil_mad_input); + return -EINVAL; + } + + if (strnstr(tavil_conn_mad_text[tavil_mad_input], "NOTUSED", + sizeof("NOTUSED"))) { + dev_dbg(codec->dev, + "%s: Unsupported tavil_mad_input = %s\n", + __func__, tavil_conn_mad_text[tavil_mad_input]); + /* Make sure the MAD register is updated */ + snd_soc_update_bits(codec, WCD934X_ANA_MAD_SETUP, + 0x88, 0x00); + return -EINVAL; + } + + if (strnstr(tavil_conn_mad_text[tavil_mad_input], + "ADC", sizeof("ADC"))) { + mad_input = strpbrk(tavil_conn_mad_text[tavil_mad_input], + "1234"); + if (!mad_input) { + dev_err(codec->dev, "%s: Invalid MAD input %s\n", + __func__, tavil_conn_mad_text[tavil_mad_input]); + return -EINVAL; + } + + ret = kstrtouint(mad_input, 10, &adc); + if ((ret < 0) || (adc > 4)) { + dev_err(codec->dev, "%s: Invalid ADC = %s\n", __func__, + tavil_conn_mad_text[tavil_mad_input]); + return -EINVAL; + } + + /*AMIC4 and AMIC5 share ADC4*/ + if ((adc == 4) && + (snd_soc_read(codec, WCD934X_TX_NEW_AMIC_4_5_SEL) & 0x10)) + adc = 5; + + snprintf(mad_amic_input_widget, 6, "%s%u", "AMIC", adc); + + mad_input_widget = mad_amic_input_widget; + is_adc_input = true; + } else { + /* DMIC type input widget*/ + mad_input_widget = tavil_conn_mad_text[tavil_mad_input]; + } + + dev_dbg(codec->dev, + "%s: tavil input widget = %s, adc_input = %s\n", __func__, + mad_input_widget, is_adc_input ? "true" : "false"); + + for (i = 0; i < card->num_of_dapm_routes; i++) { + if (!strcmp(card->of_dapm_routes[i].sink, mad_input_widget)) { + source_widget = card->of_dapm_routes[i].source; + if (!source_widget) { + dev_err(codec->dev, + "%s: invalid source widget\n", + __func__); + return -EINVAL; + } + + if (strnstr(source_widget, + "MIC BIAS1", sizeof("MIC BIAS1"))) { + mic_bias_found = 1; + break; + } else if (strnstr(source_widget, + "MIC BIAS2", sizeof("MIC BIAS2"))) { + mic_bias_found = 2; + break; + } else if (strnstr(source_widget, + "MIC BIAS3", sizeof("MIC BIAS3"))) { + mic_bias_found = 3; + break; + } else if (strnstr(source_widget, + "MIC BIAS4", sizeof("MIC BIAS4"))) { + mic_bias_found = 4; + break; + } + } + } + + if (!mic_bias_found) { + dev_err(codec->dev, "%s: mic bias not found for input %s\n", + __func__, mad_input_widget); + return -EINVAL; + } + + dev_dbg(codec->dev, "%s: mic_bias found = %d\n", __func__, + mic_bias_found); + + snd_soc_update_bits(codec, WCD934X_SOC_MAD_INP_SEL, + 0x0F, tavil_mad_input); + snd_soc_update_bits(codec, WCD934X_ANA_MAD_SETUP, + 0x07, mic_bias_found); + /* for all adc inputs, mad should be in micbias mode with BG enabled */ + if (is_adc_input) + snd_soc_update_bits(codec, WCD934X_ANA_MAD_SETUP, + 0x88, 0x88); + else + snd_soc_update_bits(codec, WCD934X_ANA_MAD_SETUP, + 0x88, 0x00); + return 0; +} + +static int tavil_ear_pa_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 ear_pa_gain; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + ear_pa_gain = snd_soc_read(codec, WCD934X_ANA_EAR); + + ear_pa_gain = (ear_pa_gain & 0x70) >> 4; + + ucontrol->value.integer.value[0] = ear_pa_gain; + + dev_dbg(codec->dev, "%s: ear_pa_gain = 0x%x\n", __func__, + ear_pa_gain); + + return 0; +} + +static int tavil_ear_pa_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 ear_pa_gain; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + ear_pa_gain = ucontrol->value.integer.value[0] << 4; + + snd_soc_update_bits(codec, WCD934X_ANA_EAR, 0x70, ear_pa_gain); + return 0; +} + +static int tavil_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = tavil->ear_spkr_gain; + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int tavil_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + tavil->ear_spkr_gain = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: gain = %d\n", __func__, tavil->ear_spkr_gain); + + return 0; +} + +static int tavil_rx_hph_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = tavil->hph_mode; + return 0; +} + +static int tavil_rx_hph_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + u32 mode_val; + + mode_val = ucontrol->value.enumerated.item[0]; + + dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val); + + if (mode_val == 0) { + dev_warn(codec->dev, "%s:Invalid HPH Mode, default to Cls-H LOHiFi\n", + __func__); + mode_val = CLS_H_LOHIFI; + } + tavil->hph_mode = mode_val; + return 0; +} + +static const char * const rx_hph_mode_mux_text[] = { + "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI", + "CLS_H_ULP", "CLS_AB_HIFI", +}; + +static const struct soc_enum rx_hph_mode_mux_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text), + rx_hph_mode_mux_text); + +static const char *const tavil_anc_func_text[] = {"OFF", "ON"}; +static const struct soc_enum tavil_anc_func_enum = + SOC_ENUM_SINGLE_EXT(2, tavil_anc_func_text); + +/* Cutoff frequency for high pass filter */ +static const char * const cf_text[] = { + "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ" +}; + +static const char * const rx_cf_text[] = { + "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ", + "CF_NEG_3DB_0P48HZ" +}; + +static const char * const amic_pwr_lvl_text[] = { + "LOW_PWR", "DEFAULT", "HIGH_PERF" +}; + +static const char * const hph_idle_detect_text[] = { + "OFF", "ON" +}; + +static const char * const asrc_mode_text[] = { + "INT", "FRAC" +}; + +static const char * const tavil_ear_pa_gain_text[] = { + "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB", + "G_0_DB", "G_M2P5_DB", "UNDEFINED", "G_M12_DB" +}; + +static const char * const tavil_ear_spkr_pa_gain_text[] = { + "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB", + "G_4_DB", "G_5_DB", "G_6_DB" +}; + +static SOC_ENUM_SINGLE_EXT_DECL(tavil_ear_pa_gain_enum, tavil_ear_pa_gain_text); +static SOC_ENUM_SINGLE_EXT_DECL(tavil_ear_spkr_pa_gain_enum, + tavil_ear_spkr_pa_gain_text); +static SOC_ENUM_SINGLE_EXT_DECL(amic_pwr_lvl_enum, amic_pwr_lvl_text); +static SOC_ENUM_SINGLE_EXT_DECL(hph_idle_detect_enum, hph_idle_detect_text); +static SOC_ENUM_SINGLE_EXT_DECL(asrc_mode_enum, asrc_mode_text); +static SOC_ENUM_SINGLE_DECL(cf_dec0_enum, WCD934X_CDC_TX0_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec1_enum, WCD934X_CDC_TX1_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec2_enum, WCD934X_CDC_TX2_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec3_enum, WCD934X_CDC_TX3_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec4_enum, WCD934X_CDC_TX4_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec5_enum, WCD934X_CDC_TX5_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec6_enum, WCD934X_CDC_TX6_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec7_enum, WCD934X_CDC_TX7_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec8_enum, WCD934X_CDC_TX8_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int0_1_enum, WCD934X_CDC_RX0_RX_PATH_CFG2, 0, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD934X_CDC_RX0_RX_PATH_MIX_CFG, 2, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int1_1_enum, WCD934X_CDC_RX1_RX_PATH_CFG2, 0, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, WCD934X_CDC_RX1_RX_PATH_MIX_CFG, 2, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int2_1_enum, WCD934X_CDC_RX2_RX_PATH_CFG2, 0, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, WCD934X_CDC_RX2_RX_PATH_MIX_CFG, 2, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int3_1_enum, WCD934X_CDC_RX3_RX_PATH_CFG2, 0, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int3_2_enum, WCD934X_CDC_RX3_RX_PATH_MIX_CFG, 2, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int4_1_enum, WCD934X_CDC_RX4_RX_PATH_CFG2, 0, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int4_2_enum, WCD934X_CDC_RX4_RX_PATH_MIX_CFG, 2, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int7_1_enum, WCD934X_CDC_RX7_RX_PATH_CFG2, 0, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD934X_CDC_RX7_RX_PATH_MIX_CFG, 2, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int8_1_enum, WCD934X_CDC_RX8_RX_PATH_CFG2, 0, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD934X_CDC_RX8_RX_PATH_MIX_CFG, 2, + rx_cf_text); + +static const struct snd_kcontrol_new tavil_snd_controls[] = { + SOC_ENUM_EXT("EAR PA Gain", tavil_ear_pa_gain_enum, + tavil_ear_pa_gain_get, tavil_ear_pa_gain_put), + SOC_ENUM_EXT("EAR SPKR PA Gain", tavil_ear_spkr_pa_gain_enum, + tavil_ear_spkr_pa_gain_get, tavil_ear_spkr_pa_gain_put), + SOC_SINGLE_TLV("HPHL Volume", WCD934X_HPH_L_EN, 0, 20, 1, line_gain), + SOC_SINGLE_TLV("HPHR Volume", WCD934X_HPH_R_EN, 0, 20, 1, line_gain), + SOC_SINGLE_TLV("LINEOUT1 Volume", WCD934X_DIFF_LO_LO1_COMPANDER, + 3, 16, 1, line_gain), + SOC_SINGLE_TLV("LINEOUT2 Volume", WCD934X_DIFF_LO_LO2_COMPANDER, + 3, 16, 1, line_gain), + SOC_SINGLE_TLV("ADC1 Volume", WCD934X_ANA_AMIC1, 0, 20, 0, analog_gain), + SOC_SINGLE_TLV("ADC2 Volume", WCD934X_ANA_AMIC2, 0, 20, 0, analog_gain), + SOC_SINGLE_TLV("ADC3 Volume", WCD934X_ANA_AMIC3, 0, 20, 0, analog_gain), + SOC_SINGLE_TLV("ADC4 Volume", WCD934X_ANA_AMIC4, 0, 20, 0, analog_gain), + + SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD934X_CDC_RX0_RX_VOL_CTL, + 0, -84, 40, digital_gain), /* -84dB min - 40dB max */ + SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD934X_CDC_RX1_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD934X_CDC_RX2_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD934X_CDC_RX3_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD934X_CDC_RX4_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD934X_CDC_RX7_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD934X_CDC_RX8_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume", + WCD934X_CDC_RX0_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume", + WCD934X_CDC_RX1_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume", + WCD934X_CDC_RX2_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume", + WCD934X_CDC_RX3_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume", + WCD934X_CDC_RX4_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume", + WCD934X_CDC_RX7_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume", + WCD934X_CDC_RX8_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), + + SOC_SINGLE_SX_TLV("DEC0 Volume", WCD934X_CDC_TX0_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC1 Volume", WCD934X_CDC_TX1_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC2 Volume", WCD934X_CDC_TX2_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC3 Volume", WCD934X_CDC_TX3_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC4 Volume", WCD934X_CDC_TX4_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC5 Volume", WCD934X_CDC_TX5_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC6 Volume", WCD934X_CDC_TX6_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC7 Volume", WCD934X_CDC_TX7_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC8 Volume", WCD934X_CDC_TX8_TX_VOL_CTL, 0, + -84, 40, digital_gain), + + SOC_SINGLE_SX_TLV("IIR0 INP0 Volume", + WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR0 INP1 Volume", + WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR0 INP2 Volume", + WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR0 INP3 Volume", + WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP0 Volume", + WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP1 Volume", + WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP2 Volume", + WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP3 Volume", + WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0, -84, 40, + digital_gain), + + SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, tavil_get_anc_slot, + tavil_put_anc_slot), + SOC_ENUM_EXT("ANC Function", tavil_anc_func_enum, tavil_get_anc_func, + tavil_put_anc_func), + + SOC_ENUM("TX0 HPF cut off", cf_dec0_enum), + SOC_ENUM("TX1 HPF cut off", cf_dec1_enum), + SOC_ENUM("TX2 HPF cut off", cf_dec2_enum), + SOC_ENUM("TX3 HPF cut off", cf_dec3_enum), + SOC_ENUM("TX4 HPF cut off", cf_dec4_enum), + SOC_ENUM("TX5 HPF cut off", cf_dec5_enum), + SOC_ENUM("TX6 HPF cut off", cf_dec6_enum), + SOC_ENUM("TX7 HPF cut off", cf_dec7_enum), + SOC_ENUM("TX8 HPF cut off", cf_dec8_enum), + + SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum), + SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum), + SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum), + SOC_ENUM("RX INT1_2 HPF cut off", cf_int1_2_enum), + SOC_ENUM("RX INT2_1 HPF cut off", cf_int2_1_enum), + SOC_ENUM("RX INT2_2 HPF cut off", cf_int2_2_enum), + SOC_ENUM("RX INT3_1 HPF cut off", cf_int3_1_enum), + SOC_ENUM("RX INT3_2 HPF cut off", cf_int3_2_enum), + SOC_ENUM("RX INT4_1 HPF cut off", cf_int4_1_enum), + SOC_ENUM("RX INT4_2 HPF cut off", cf_int4_2_enum), + SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum), + SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum), + SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum), + SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum), + + SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum, + tavil_rx_hph_mode_get, tavil_rx_hph_mode_put), + + SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0, + tavil_iir_enable_audio_mixer_get, + tavil_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR0 Enable Band2", IIR0, BAND2, 1, 0, + tavil_iir_enable_audio_mixer_get, + tavil_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR0 Enable Band3", IIR0, BAND3, 1, 0, + tavil_iir_enable_audio_mixer_get, + tavil_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR0 Enable Band4", IIR0, BAND4, 1, 0, + tavil_iir_enable_audio_mixer_get, + tavil_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR0 Enable Band5", IIR0, BAND5, 1, 0, + tavil_iir_enable_audio_mixer_get, + tavil_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0, + tavil_iir_enable_audio_mixer_get, + tavil_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0, + tavil_iir_enable_audio_mixer_get, + tavil_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0, + tavil_iir_enable_audio_mixer_get, + tavil_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0, + tavil_iir_enable_audio_mixer_get, + tavil_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0, + tavil_iir_enable_audio_mixer_get, + tavil_iir_enable_audio_mixer_put), + + SOC_SINGLE_MULTI_EXT("IIR0 Band1", IIR0, BAND1, 255, 0, 5, + tavil_iir_band_audio_mixer_get, tavil_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR0 Band2", IIR0, BAND2, 255, 0, 5, + tavil_iir_band_audio_mixer_get, tavil_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR0 Band3", IIR0, BAND3, 255, 0, 5, + tavil_iir_band_audio_mixer_get, tavil_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR0 Band4", IIR0, BAND4, 255, 0, 5, + tavil_iir_band_audio_mixer_get, tavil_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR0 Band5", IIR0, BAND5, 255, 0, 5, + tavil_iir_band_audio_mixer_get, tavil_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5, + tavil_iir_band_audio_mixer_get, tavil_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5, + tavil_iir_band_audio_mixer_get, tavil_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5, + tavil_iir_band_audio_mixer_get, tavil_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5, + tavil_iir_band_audio_mixer_get, tavil_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5, + tavil_iir_band_audio_mixer_get, tavil_iir_band_audio_mixer_put), + + SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0, + tavil_compander_get, tavil_compander_put), + SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0, + tavil_compander_get, tavil_compander_put), + SOC_SINGLE_EXT("COMP3 Switch", SND_SOC_NOPM, COMPANDER_3, 1, 0, + tavil_compander_get, tavil_compander_put), + SOC_SINGLE_EXT("COMP4 Switch", SND_SOC_NOPM, COMPANDER_4, 1, 0, + tavil_compander_get, tavil_compander_put), + SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0, + tavil_compander_get, tavil_compander_put), + SOC_SINGLE_EXT("COMP8 Switch", SND_SOC_NOPM, COMPANDER_8, 1, 0, + tavil_compander_get, tavil_compander_put), + + SOC_ENUM_EXT("ASRC0 Output Mode", asrc_mode_enum, + tavil_hph_asrc_mode_get, tavil_hph_asrc_mode_put), + SOC_ENUM_EXT("ASRC1 Output Mode", asrc_mode_enum, + tavil_hph_asrc_mode_get, tavil_hph_asrc_mode_put), + + SOC_ENUM_EXT("HPH Idle Detect", hph_idle_detect_enum, + tavil_hph_idle_detect_get, tavil_hph_idle_detect_put), + + SOC_ENUM_EXT("MAD Input", tavil_conn_mad_enum, + tavil_mad_input_get, tavil_mad_input_put), + + SOC_SINGLE_EXT("DMIC1_CLK_PIN_MODE", SND_SOC_NOPM, 17, 1, 0, + tavil_dmic_pin_mode_get, tavil_dmic_pin_mode_put), + + SOC_SINGLE_EXT("DMIC1_DATA_PIN_MODE", SND_SOC_NOPM, 18, 1, 0, + tavil_dmic_pin_mode_get, tavil_dmic_pin_mode_put), + + SOC_SINGLE_EXT("DMIC2_CLK_PIN_MODE", SND_SOC_NOPM, 19, 1, 0, + tavil_dmic_pin_mode_get, tavil_dmic_pin_mode_put), + + SOC_SINGLE_EXT("DMIC2_DATA_PIN_MODE", SND_SOC_NOPM, 20, 1, 0, + tavil_dmic_pin_mode_get, tavil_dmic_pin_mode_put), + + SOC_SINGLE_EXT("DMIC3_CLK_PIN_MODE", SND_SOC_NOPM, 21, 1, 0, + tavil_dmic_pin_mode_get, tavil_dmic_pin_mode_put), + + SOC_SINGLE_EXT("DMIC3_DATA_PIN_MODE", SND_SOC_NOPM, 22, 1, 0, + tavil_dmic_pin_mode_get, tavil_dmic_pin_mode_put), + SOC_ENUM_EXT("AMIC_1_2 PWR MODE", amic_pwr_lvl_enum, + tavil_amic_pwr_lvl_get, tavil_amic_pwr_lvl_put), + SOC_ENUM_EXT("AMIC_3_4 PWR MODE", amic_pwr_lvl_enum, + tavil_amic_pwr_lvl_get, tavil_amic_pwr_lvl_put), + SOC_ENUM_EXT("AMIC_5_6 PWR MODE", amic_pwr_lvl_enum, + tavil_amic_pwr_lvl_get, tavil_amic_pwr_lvl_put), +}; + +static int tavil_dec_enum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val; + u16 mic_sel_reg = 0; + u8 mic_sel; + + val = ucontrol->value.enumerated.item[0]; + if (val > e->items - 1) + return -EINVAL; + + dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + widget->name, val); + + switch (e->reg) { + case WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1: + if (e->shift_l == 0) + mic_sel_reg = WCD934X_CDC_TX0_TX_PATH_CFG0; + else if (e->shift_l == 2) + mic_sel_reg = WCD934X_CDC_TX4_TX_PATH_CFG0; + else if (e->shift_l == 4) + mic_sel_reg = WCD934X_CDC_TX8_TX_PATH_CFG0; + break; + case WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG1: + if (e->shift_l == 0) + mic_sel_reg = WCD934X_CDC_TX1_TX_PATH_CFG0; + else if (e->shift_l == 2) + mic_sel_reg = WCD934X_CDC_TX5_TX_PATH_CFG0; + break; + case WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG1: + if (e->shift_l == 0) + mic_sel_reg = WCD934X_CDC_TX2_TX_PATH_CFG0; + else if (e->shift_l == 2) + mic_sel_reg = WCD934X_CDC_TX6_TX_PATH_CFG0; + break; + case WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1: + if (e->shift_l == 0) + mic_sel_reg = WCD934X_CDC_TX3_TX_PATH_CFG0; + else if (e->shift_l == 2) + mic_sel_reg = WCD934X_CDC_TX7_TX_PATH_CFG0; + break; + default: + dev_err(codec->dev, "%s: e->reg: 0x%x not expected\n", + __func__, e->reg); + return -EINVAL; + } + + /* ADC: 0, DMIC: 1 */ + mic_sel = val ? 0x0 : 0x1; + if (mic_sel_reg) + snd_soc_update_bits(codec, mic_sel_reg, 1 << 7, mic_sel << 7); + + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +static int tavil_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val; + unsigned short look_ahead_dly_reg = WCD934X_CDC_RX0_RX_PATH_CFG0; + + val = ucontrol->value.enumerated.item[0]; + if (val >= e->items) + return -EINVAL; + + dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + widget->name, val); + + if (e->reg == WCD934X_CDC_RX0_RX_PATH_SEC0) + look_ahead_dly_reg = WCD934X_CDC_RX0_RX_PATH_CFG0; + else if (e->reg == WCD934X_CDC_RX1_RX_PATH_SEC0) + look_ahead_dly_reg = WCD934X_CDC_RX1_RX_PATH_CFG0; + else if (e->reg == WCD934X_CDC_RX2_RX_PATH_SEC0) + look_ahead_dly_reg = WCD934X_CDC_RX2_RX_PATH_CFG0; + + /* Set Look Ahead Delay */ + snd_soc_update_bits(codec, look_ahead_dly_reg, + 0x08, (val ? 0x08 : 0x00)); + /* Set DEM INP Select */ + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +static const char * const rx_int0_7_mix_mux_text[] = { + "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", + "RX6", "RX7", "PROXIMITY" +}; + +static const char * const rx_int_mix_mux_text[] = { + "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", + "RX6", "RX7" +}; + +static const char * const rx_prim_mix_text[] = { + "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2", + "RX3", "RX4", "RX5", "RX6", "RX7" +}; + +static const char * const rx_sidetone_mix_text[] = { + "ZERO", "SRC0", "SRC1", "SRC_SUM" +}; + +static const char * const cdc_if_tx0_mux_text[] = { + "ZERO", "RX_MIX_TX0", "DEC0", "DEC0_192" +}; +static const char * const cdc_if_tx1_mux_text[] = { + "ZERO", "RX_MIX_TX1", "DEC1", "DEC1_192" +}; +static const char * const cdc_if_tx2_mux_text[] = { + "ZERO", "RX_MIX_TX2", "DEC2", "DEC2_192" +}; +static const char * const cdc_if_tx3_mux_text[] = { + "ZERO", "RX_MIX_TX3", "DEC3", "DEC3_192" +}; +static const char * const cdc_if_tx4_mux_text[] = { + "ZERO", "RX_MIX_TX4", "DEC4", "DEC4_192" +}; +static const char * const cdc_if_tx5_mux_text[] = { + "ZERO", "RX_MIX_TX5", "DEC5", "DEC5_192" +}; +static const char * const cdc_if_tx6_mux_text[] = { + "ZERO", "RX_MIX_TX6", "DEC6", "DEC6_192" +}; +static const char * const cdc_if_tx7_mux_text[] = { + "ZERO", "RX_MIX_TX7", "DEC7", "DEC7_192" +}; +static const char * const cdc_if_tx8_mux_text[] = { + "ZERO", "RX_MIX_TX8", "DEC8", "DEC8_192" +}; +static const char * const cdc_if_tx9_mux_text[] = { + "ZERO", "DEC7", "DEC7_192" +}; +static const char * const cdc_if_tx10_mux_text[] = { + "ZERO", "DEC6", "DEC6_192" +}; +static const char * const cdc_if_tx11_mux_text[] = { + "DEC_0_5", "DEC_9_12", "MAD_AUDIO", "MAD_BRDCST" +}; +static const char * const cdc_if_tx11_inp1_mux_text[] = { + "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", + "DEC5", "RX_MIX_TX5", "DEC9_10", "DEC11_12" +}; +static const char * const cdc_if_tx13_mux_text[] = { + "CDC_DEC_5", "MAD_BRDCST" +}; +static const char * const cdc_if_tx13_inp1_mux_text[] = { + "ZERO", "DEC5", "DEC5_192" +}; + +static const char * const iir_inp_mux_text[] = { + "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", + "DEC7", "DEC8", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7" +}; + +static const char * const rx_int_dem_inp_mux_text[] = { + "NORMAL_DSM_OUT", "CLSH_DSM_OUT", +}; + +static const char * const rx_int0_1_interp_mux_text[] = { + "ZERO", "RX INT0_1 MIX1", +}; + +static const char * const rx_int1_1_interp_mux_text[] = { + "ZERO", "RX INT1_1 MIX1", +}; + +static const char * const rx_int2_1_interp_mux_text[] = { + "ZERO", "RX INT2_1 MIX1", +}; + +static const char * const rx_int3_1_interp_mux_text[] = { + "ZERO", "RX INT3_1 MIX1", +}; + +static const char * const rx_int4_1_interp_mux_text[] = { + "ZERO", "RX INT4_1 MIX1", +}; + +static const char * const rx_int7_1_interp_mux_text[] = { + "ZERO", "RX INT7_1 MIX1", +}; + +static const char * const rx_int8_1_interp_mux_text[] = { + "ZERO", "RX INT8_1 MIX1", +}; + +static const char * const rx_int0_2_interp_mux_text[] = { + "ZERO", "RX INT0_2 MUX", +}; + +static const char * const rx_int1_2_interp_mux_text[] = { + "ZERO", "RX INT1_2 MUX", +}; + +static const char * const rx_int2_2_interp_mux_text[] = { + "ZERO", "RX INT2_2 MUX", +}; + +static const char * const rx_int3_2_interp_mux_text[] = { + "ZERO", "RX INT3_2 MUX", +}; + +static const char * const rx_int4_2_interp_mux_text[] = { + "ZERO", "RX INT4_2 MUX", +}; + +static const char * const rx_int7_2_interp_mux_text[] = { + "ZERO", "RX INT7_2 MUX", +}; + +static const char * const rx_int8_2_interp_mux_text[] = { + "ZERO", "RX INT8_2 MUX", +}; + +static const char * const mad_sel_txt[] = { + "SPE", "MSM" +}; + +static const char * const mad_inp_mux_txt[] = { + "MAD", "DEC1" +}; + +static const char * const adc_mux_text[] = { + "DMIC", "AMIC", "ANC_FB_TUNE1", "ANC_FB_TUNE2" +}; + +static const char * const dmic_mux_text[] = { + "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5" +}; + +static const char * const amic_mux_text[] = { + "ZERO", "ADC1", "ADC2", "ADC3", "ADC4" +}; + +static const char * const amic4_5_sel_text[] = { + "AMIC4", "AMIC5" +}; + +static const char * const anc0_fb_mux_text[] = { + "ZERO", "ANC_IN_HPHL", "ANC_IN_EAR", "ANC_IN_EAR_SPKR", + "ANC_IN_LO1" +}; + +static const char * const anc1_fb_mux_text[] = { + "ZERO", "ANC_IN_HPHR", "ANC_IN_LO2" +}; + +static const char * const rx_echo_mux_text[] = { + "ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2", "RX_MIX3", "RX_MIX4", + "RX_MIX5", "RX_MIX6", "RX_MIX7", "RX_MIX8" +}; + +static const char *const slim_rx_mux_text[] = { + "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB" +}; + +static const char *const cdc_if_rx0_mux_text[] = { + "SLIM RX0", "I2S_0 RX0" +}; +static const char *const cdc_if_rx1_mux_text[] = { + "SLIM RX1", "I2S_0 RX1" +}; +static const char *const cdc_if_rx2_mux_text[] = { + "SLIM RX2", "I2S_0 RX2" +}; +static const char *const cdc_if_rx3_mux_text[] = { + "SLIM RX3", "I2S_0 RX3" +}; +static const char *const cdc_if_rx4_mux_text[] = { + "SLIM RX4", "I2S_0 RX4" +}; +static const char *const cdc_if_rx5_mux_text[] = { + "SLIM RX5", "I2S_0 RX5" +}; +static const char *const cdc_if_rx6_mux_text[] = { + "SLIM RX6", "I2S_0 RX6" +}; +static const char *const cdc_if_rx7_mux_text[] = { + "SLIM RX7", "I2S_0 RX7" +}; + +static const char * const asrc0_mux_text[] = { + "ZERO", "ASRC_IN_HPHL", "ASRC_IN_LO1", +}; + +static const char * const asrc1_mux_text[] = { + "ZERO", "ASRC_IN_HPHR", "ASRC_IN_LO2", +}; + +static const char * const asrc2_mux_text[] = { + "ZERO", "ASRC_IN_SPKR1", +}; + +static const char * const asrc3_mux_text[] = { + "ZERO", "ASRC_IN_SPKR2", +}; + +static const char * const native_mux_text[] = { + "OFF", "ON", +}; + +static const struct snd_kcontrol_new aif4_vi_mixer[] = { + SOC_SINGLE_EXT("SPKR_VI_1", SND_SOC_NOPM, WCD934X_TX14, 1, 0, + tavil_vi_feed_mixer_get, tavil_vi_feed_mixer_put), + SOC_SINGLE_EXT("SPKR_VI_2", SND_SOC_NOPM, WCD934X_TX15, 1, 0, + tavil_vi_feed_mixer_get, tavil_vi_feed_mixer_put), +}; + +static const struct snd_kcontrol_new aif1_cap_mixer[] = { + SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD934X_TX0, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD934X_TX1, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD934X_TX2, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD934X_TX3, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD934X_TX4, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD934X_TX5, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD934X_TX6, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD934X_TX7, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD934X_TX8, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD934X_TX9, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD934X_TX10, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD934X_TX11, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD934X_TX13, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), +}; + +static const struct snd_kcontrol_new aif2_cap_mixer[] = { + SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD934X_TX0, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD934X_TX1, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD934X_TX2, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD934X_TX3, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD934X_TX4, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD934X_TX5, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD934X_TX6, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD934X_TX7, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD934X_TX8, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD934X_TX9, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD934X_TX10, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD934X_TX11, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD934X_TX13, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), +}; + +static const struct snd_kcontrol_new aif3_cap_mixer[] = { + SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD934X_TX0, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD934X_TX1, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD934X_TX2, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD934X_TX3, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD934X_TX4, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD934X_TX5, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD934X_TX6, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD934X_TX7, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD934X_TX8, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD934X_TX9, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD934X_TX10, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD934X_TX11, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD934X_TX13, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), +}; + +static const struct snd_kcontrol_new aif4_mad_mixer[] = { + SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD934X_TX13, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), +}; + +WCD_DAPM_ENUM_EXT(slim_rx0, SND_SOC_NOPM, 0, slim_rx_mux_text, + slim_rx_mux_get, slim_rx_mux_put); +WCD_DAPM_ENUM_EXT(slim_rx1, SND_SOC_NOPM, 0, slim_rx_mux_text, + slim_rx_mux_get, slim_rx_mux_put); +WCD_DAPM_ENUM_EXT(slim_rx2, SND_SOC_NOPM, 0, slim_rx_mux_text, + slim_rx_mux_get, slim_rx_mux_put); +WCD_DAPM_ENUM_EXT(slim_rx3, SND_SOC_NOPM, 0, slim_rx_mux_text, + slim_rx_mux_get, slim_rx_mux_put); +WCD_DAPM_ENUM_EXT(slim_rx4, SND_SOC_NOPM, 0, slim_rx_mux_text, + slim_rx_mux_get, slim_rx_mux_put); +WCD_DAPM_ENUM_EXT(slim_rx5, SND_SOC_NOPM, 0, slim_rx_mux_text, + slim_rx_mux_get, slim_rx_mux_put); +WCD_DAPM_ENUM_EXT(slim_rx6, SND_SOC_NOPM, 0, slim_rx_mux_text, + slim_rx_mux_get, slim_rx_mux_put); +WCD_DAPM_ENUM_EXT(slim_rx7, SND_SOC_NOPM, 0, slim_rx_mux_text, + slim_rx_mux_get, slim_rx_mux_put); + +WCD_DAPM_ENUM(cdc_if_rx0, SND_SOC_NOPM, 0, cdc_if_rx0_mux_text); +WCD_DAPM_ENUM(cdc_if_rx1, SND_SOC_NOPM, 0, cdc_if_rx1_mux_text); +WCD_DAPM_ENUM(cdc_if_rx2, SND_SOC_NOPM, 0, cdc_if_rx2_mux_text); +WCD_DAPM_ENUM(cdc_if_rx3, SND_SOC_NOPM, 0, cdc_if_rx3_mux_text); +WCD_DAPM_ENUM(cdc_if_rx4, SND_SOC_NOPM, 0, cdc_if_rx4_mux_text); +WCD_DAPM_ENUM(cdc_if_rx5, SND_SOC_NOPM, 0, cdc_if_rx5_mux_text); +WCD_DAPM_ENUM(cdc_if_rx6, SND_SOC_NOPM, 0, cdc_if_rx6_mux_text); +WCD_DAPM_ENUM(cdc_if_rx7, SND_SOC_NOPM, 0, cdc_if_rx7_mux_text); + +WCD_DAPM_ENUM(rx_int0_2, WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, + rx_int0_7_mix_mux_text); +WCD_DAPM_ENUM(rx_int1_2, WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, + rx_int_mix_mux_text); +WCD_DAPM_ENUM(rx_int2_2, WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, + rx_int_mix_mux_text); +WCD_DAPM_ENUM(rx_int3_2, WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG1, 0, + rx_int_mix_mux_text); +WCD_DAPM_ENUM(rx_int4_2, WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG1, 0, + rx_int_mix_mux_text); +WCD_DAPM_ENUM(rx_int7_2, WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG1, 0, + rx_int0_7_mix_mux_text); +WCD_DAPM_ENUM(rx_int8_2, WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG1, 0, + rx_int_mix_mux_text); + +WCD_DAPM_ENUM(rx_int0_1_mix_inp0, WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG0, 0, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int0_1_mix_inp1, WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG0, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int0_1_mix_inp2, WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG1, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int1_1_mix_inp0, WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG0, 0, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int1_1_mix_inp1, WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG0, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int1_1_mix_inp2, WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG1, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int2_1_mix_inp0, WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int2_1_mix_inp1, WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG0, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int2_1_mix_inp2, WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG1, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int3_1_mix_inp0, WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG0, 0, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int3_1_mix_inp1, WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG0, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int3_1_mix_inp2, WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG1, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int4_1_mix_inp0, WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG0, 0, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int4_1_mix_inp1, WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG0, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int4_1_mix_inp2, WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG1, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int7_1_mix_inp0, WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG0, 0, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int7_1_mix_inp1, WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG0, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int7_1_mix_inp2, WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG1, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int8_1_mix_inp0, WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG0, 0, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int8_1_mix_inp1, WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG0, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int8_1_mix_inp2, WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG1, 4, + rx_prim_mix_text); + +WCD_DAPM_ENUM(rx_int0_mix2_inp, WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0, + rx_sidetone_mix_text); +WCD_DAPM_ENUM(rx_int1_mix2_inp, WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2, + rx_sidetone_mix_text); +WCD_DAPM_ENUM(rx_int2_mix2_inp, WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4, + rx_sidetone_mix_text); +WCD_DAPM_ENUM(rx_int3_mix2_inp, WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6, + rx_sidetone_mix_text); +WCD_DAPM_ENUM(rx_int4_mix2_inp, WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 0, + rx_sidetone_mix_text); +WCD_DAPM_ENUM(rx_int7_mix2_inp, WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 2, + rx_sidetone_mix_text); + +WCD_DAPM_ENUM(tx_adc_mux10, WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 4, + adc_mux_text); +WCD_DAPM_ENUM(tx_adc_mux11, WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 4, + adc_mux_text); +WCD_DAPM_ENUM(tx_adc_mux12, WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 4, + adc_mux_text); +WCD_DAPM_ENUM(tx_adc_mux13, WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 6, + adc_mux_text); + + +WCD_DAPM_ENUM(tx_dmic_mux0, WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux1, WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux2, WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux3, WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux4, WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux5, WCD934X_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux6, WCD934X_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux7, WCD934X_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux8, WCD934X_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux10, WCD934X_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux11, WCD934X_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux12, WCD934X_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux13, WCD934X_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 3, + dmic_mux_text); + + +WCD_DAPM_ENUM(tx_amic_mux0, WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux1, WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux2, WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux3, WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux4, WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux5, WCD934X_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux6, WCD934X_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux7, WCD934X_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux8, WCD934X_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux10, WCD934X_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux11, WCD934X_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux12, WCD934X_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux13, WCD934X_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 0, + amic_mux_text); + +WCD_DAPM_ENUM(tx_amic4_5, WCD934X_TX_NEW_AMIC_4_5_SEL, 7, amic4_5_sel_text); + +WCD_DAPM_ENUM(cdc_if_tx0, WCD934X_CDC_IF_ROUTER_TX_MUX_CFG0, 0, + cdc_if_tx0_mux_text); +WCD_DAPM_ENUM(cdc_if_tx1, WCD934X_CDC_IF_ROUTER_TX_MUX_CFG0, 2, + cdc_if_tx1_mux_text); +WCD_DAPM_ENUM(cdc_if_tx2, WCD934X_CDC_IF_ROUTER_TX_MUX_CFG0, 4, + cdc_if_tx2_mux_text); +WCD_DAPM_ENUM(cdc_if_tx3, WCD934X_CDC_IF_ROUTER_TX_MUX_CFG0, 6, + cdc_if_tx3_mux_text); +WCD_DAPM_ENUM(cdc_if_tx4, WCD934X_CDC_IF_ROUTER_TX_MUX_CFG1, 0, + cdc_if_tx4_mux_text); +WCD_DAPM_ENUM(cdc_if_tx5, WCD934X_CDC_IF_ROUTER_TX_MUX_CFG1, 2, + cdc_if_tx5_mux_text); +WCD_DAPM_ENUM(cdc_if_tx6, WCD934X_CDC_IF_ROUTER_TX_MUX_CFG1, 4, + cdc_if_tx6_mux_text); +WCD_DAPM_ENUM(cdc_if_tx7, WCD934X_CDC_IF_ROUTER_TX_MUX_CFG1, 6, + cdc_if_tx7_mux_text); +WCD_DAPM_ENUM(cdc_if_tx8, WCD934X_CDC_IF_ROUTER_TX_MUX_CFG2, 0, + cdc_if_tx8_mux_text); +WCD_DAPM_ENUM(cdc_if_tx9, WCD934X_CDC_IF_ROUTER_TX_MUX_CFG2, 2, + cdc_if_tx9_mux_text); +WCD_DAPM_ENUM(cdc_if_tx10, WCD934X_CDC_IF_ROUTER_TX_MUX_CFG2, 4, + cdc_if_tx10_mux_text); +WCD_DAPM_ENUM(cdc_if_tx11_inp1, WCD934X_CDC_IF_ROUTER_TX_MUX_CFG3, 0, + cdc_if_tx11_inp1_mux_text); +WCD_DAPM_ENUM(cdc_if_tx11, WCD934X_DATA_HUB_SB_TX11_INP_CFG, 0, + cdc_if_tx11_mux_text); +WCD_DAPM_ENUM(cdc_if_tx13_inp1, WCD934X_CDC_IF_ROUTER_TX_MUX_CFG3, 4, + cdc_if_tx13_inp1_mux_text); +WCD_DAPM_ENUM(cdc_if_tx13, WCD934X_DATA_HUB_SB_TX13_INP_CFG, 0, + cdc_if_tx13_mux_text); + +WCD_DAPM_ENUM(rx_mix_tx0, WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG0, 0, + rx_echo_mux_text); +WCD_DAPM_ENUM(rx_mix_tx1, WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG0, 4, + rx_echo_mux_text); +WCD_DAPM_ENUM(rx_mix_tx2, WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG1, 0, + rx_echo_mux_text); +WCD_DAPM_ENUM(rx_mix_tx3, WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG1, 4, + rx_echo_mux_text); +WCD_DAPM_ENUM(rx_mix_tx4, WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG2, 0, + rx_echo_mux_text); +WCD_DAPM_ENUM(rx_mix_tx5, WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG2, 4, + rx_echo_mux_text); +WCD_DAPM_ENUM(rx_mix_tx6, WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG3, 0, + rx_echo_mux_text); +WCD_DAPM_ENUM(rx_mix_tx7, WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG3, 4, + rx_echo_mux_text); +WCD_DAPM_ENUM(rx_mix_tx8, WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, + rx_echo_mux_text); + +WCD_DAPM_ENUM(iir0_inp0, WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0, + iir_inp_mux_text); +WCD_DAPM_ENUM(iir0_inp1, WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1, 0, + iir_inp_mux_text); +WCD_DAPM_ENUM(iir0_inp2, WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2, 0, + iir_inp_mux_text); +WCD_DAPM_ENUM(iir0_inp3, WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3, 0, + iir_inp_mux_text); +WCD_DAPM_ENUM(iir1_inp0, WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0, 0, + iir_inp_mux_text); +WCD_DAPM_ENUM(iir1_inp1, WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1, 0, + iir_inp_mux_text); +WCD_DAPM_ENUM(iir1_inp2, WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2, 0, + iir_inp_mux_text); +WCD_DAPM_ENUM(iir1_inp3, WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3, 0, + iir_inp_mux_text); + +WCD_DAPM_ENUM(rx_int0_1_interp, SND_SOC_NOPM, 0, rx_int0_1_interp_mux_text); +WCD_DAPM_ENUM(rx_int1_1_interp, SND_SOC_NOPM, 0, rx_int1_1_interp_mux_text); +WCD_DAPM_ENUM(rx_int2_1_interp, SND_SOC_NOPM, 0, rx_int2_1_interp_mux_text); +WCD_DAPM_ENUM(rx_int3_1_interp, SND_SOC_NOPM, 0, rx_int3_1_interp_mux_text); +WCD_DAPM_ENUM(rx_int4_1_interp, SND_SOC_NOPM, 0, rx_int4_1_interp_mux_text); +WCD_DAPM_ENUM(rx_int7_1_interp, SND_SOC_NOPM, 0, rx_int7_1_interp_mux_text); +WCD_DAPM_ENUM(rx_int8_1_interp, SND_SOC_NOPM, 0, rx_int8_1_interp_mux_text); + +WCD_DAPM_ENUM(rx_int0_2_interp, SND_SOC_NOPM, 0, rx_int0_2_interp_mux_text); +WCD_DAPM_ENUM(rx_int1_2_interp, SND_SOC_NOPM, 0, rx_int1_2_interp_mux_text); +WCD_DAPM_ENUM(rx_int2_2_interp, SND_SOC_NOPM, 0, rx_int2_2_interp_mux_text); +WCD_DAPM_ENUM(rx_int3_2_interp, SND_SOC_NOPM, 0, rx_int3_2_interp_mux_text); +WCD_DAPM_ENUM(rx_int4_2_interp, SND_SOC_NOPM, 0, rx_int4_2_interp_mux_text); +WCD_DAPM_ENUM(rx_int7_2_interp, SND_SOC_NOPM, 0, rx_int7_2_interp_mux_text); +WCD_DAPM_ENUM(rx_int8_2_interp, SND_SOC_NOPM, 0, rx_int8_2_interp_mux_text); + +WCD_DAPM_ENUM(mad_sel, WCD934X_CPE_SS_SVA_CFG, 0, + mad_sel_txt); + +WCD_DAPM_ENUM(mad_inp_mux, WCD934X_CPE_SS_SVA_CFG, 2, + mad_inp_mux_txt); + +WCD_DAPM_ENUM_EXT(rx_int0_dem_inp, WCD934X_CDC_RX0_RX_PATH_SEC0, 0, + rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double, + tavil_int_dem_inp_mux_put); +WCD_DAPM_ENUM_EXT(rx_int1_dem_inp, WCD934X_CDC_RX1_RX_PATH_SEC0, 0, + rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double, + tavil_int_dem_inp_mux_put); +WCD_DAPM_ENUM_EXT(rx_int2_dem_inp, WCD934X_CDC_RX2_RX_PATH_SEC0, 0, + rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double, + tavil_int_dem_inp_mux_put); + +WCD_DAPM_ENUM_EXT(tx_adc_mux0, WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0, + adc_mux_text, snd_soc_dapm_get_enum_double, tavil_dec_enum_put); +WCD_DAPM_ENUM_EXT(tx_adc_mux1, WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0, + adc_mux_text, snd_soc_dapm_get_enum_double, tavil_dec_enum_put); +WCD_DAPM_ENUM_EXT(tx_adc_mux2, WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0, + adc_mux_text, snd_soc_dapm_get_enum_double, tavil_dec_enum_put); +WCD_DAPM_ENUM_EXT(tx_adc_mux3, WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0, + adc_mux_text, snd_soc_dapm_get_enum_double, tavil_dec_enum_put); +WCD_DAPM_ENUM_EXT(tx_adc_mux4, WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 2, + adc_mux_text, snd_soc_dapm_get_enum_double, tavil_dec_enum_put); +WCD_DAPM_ENUM_EXT(tx_adc_mux5, WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 2, + adc_mux_text, snd_soc_dapm_get_enum_double, tavil_dec_enum_put); +WCD_DAPM_ENUM_EXT(tx_adc_mux6, WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 2, + adc_mux_text, snd_soc_dapm_get_enum_double, tavil_dec_enum_put); +WCD_DAPM_ENUM_EXT(tx_adc_mux7, WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 2, + adc_mux_text, snd_soc_dapm_get_enum_double, tavil_dec_enum_put); +WCD_DAPM_ENUM_EXT(tx_adc_mux8, WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 4, + adc_mux_text, snd_soc_dapm_get_enum_double, tavil_dec_enum_put); + +WCD_DAPM_ENUM(asrc0, WCD934X_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 0, + asrc0_mux_text); +WCD_DAPM_ENUM(asrc1, WCD934X_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 2, + asrc1_mux_text); +WCD_DAPM_ENUM(asrc2, WCD934X_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 4, + asrc2_mux_text); +WCD_DAPM_ENUM(asrc3, WCD934X_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 6, + asrc3_mux_text); + +WCD_DAPM_ENUM(int1_1_native, SND_SOC_NOPM, 0, native_mux_text); +WCD_DAPM_ENUM(int2_1_native, SND_SOC_NOPM, 0, native_mux_text); +WCD_DAPM_ENUM(int3_1_native, SND_SOC_NOPM, 0, native_mux_text); +WCD_DAPM_ENUM(int4_1_native, SND_SOC_NOPM, 0, native_mux_text); + +WCD_DAPM_ENUM(int1_2_native, SND_SOC_NOPM, 0, native_mux_text); +WCD_DAPM_ENUM(int2_2_native, SND_SOC_NOPM, 0, native_mux_text); +WCD_DAPM_ENUM(int3_2_native, SND_SOC_NOPM, 0, native_mux_text); +WCD_DAPM_ENUM(int4_2_native, SND_SOC_NOPM, 0, native_mux_text); +WCD_DAPM_ENUM(int7_2_native, SND_SOC_NOPM, 0, native_mux_text); +WCD_DAPM_ENUM(int8_2_native, SND_SOC_NOPM, 0, native_mux_text); + +WCD_DAPM_ENUM(anc0_fb, WCD934X_CDC_RX_INP_MUX_ANC_CFG0, 0, anc0_fb_mux_text); +WCD_DAPM_ENUM(anc1_fb, WCD934X_CDC_RX_INP_MUX_ANC_CFG0, 3, anc1_fb_mux_text); + +static const struct snd_kcontrol_new anc_ear_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new anc_ear_spkr_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new anc_spkr_pa_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new anc_hphl_pa_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new anc_hphr_pa_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new mad_cpe1_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new mad_cpe2_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new mad_brdcst_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux0_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux1_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux2_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux3_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux4_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux5_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux6_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux7_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux8_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new rx_int1_asrc_switch[] = { + SOC_DAPM_SINGLE("HPHL Switch", SND_SOC_NOPM, 0, 1, 0), +}; + +static const struct snd_kcontrol_new rx_int2_asrc_switch[] = { + SOC_DAPM_SINGLE("HPHR Switch", SND_SOC_NOPM, 0, 1, 0), +}; + +static const struct snd_kcontrol_new rx_int3_asrc_switch[] = { + SOC_DAPM_SINGLE("LO1 Switch", SND_SOC_NOPM, 0, 1, 0), +}; + +static const struct snd_kcontrol_new rx_int4_asrc_switch[] = { + SOC_DAPM_SINGLE("LO2 Switch", SND_SOC_NOPM, 0, 1, 0), +}; + +static int tavil_dsd_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_context *dapm = + snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct tavil_dsd_config *dsd_conf = tavil_p->dsd_config; + int val; + + val = tavil_dsd_get_current_mixer_value(dsd_conf, mc->shift); + + ucontrol->value.integer.value[0] = ((val < 0) ? 0 : val); + + return 0; +} + +static int tavil_dsd_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_dapm_context *dapm = + snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + unsigned int wval = ucontrol->value.integer.value[0]; + struct tavil_dsd_config *dsd_conf = tavil_p->dsd_config; + + if (!dsd_conf) + return 0; + + mutex_lock(&tavil_p->codec_mutex); + + tavil_dsd_set_out_select(dsd_conf, mc->shift); + tavil_dsd_set_mixer_value(dsd_conf, mc->shift, wval); + + mutex_unlock(&tavil_p->codec_mutex); + snd_soc_dapm_mixer_update_power(dapm, kcontrol, wval, NULL); + + return 0; +} + +static const struct snd_kcontrol_new hphl_mixer[] = { + SOC_SINGLE_EXT("DSD HPHL Switch", SND_SOC_NOPM, INTERP_HPHL, 1, 0, + tavil_dsd_mixer_get, tavil_dsd_mixer_put), +}; + +static const struct snd_kcontrol_new hphr_mixer[] = { + SOC_SINGLE_EXT("DSD HPHR Switch", SND_SOC_NOPM, INTERP_HPHR, 1, 0, + tavil_dsd_mixer_get, tavil_dsd_mixer_put), +}; + +static const struct snd_kcontrol_new lo1_mixer[] = { + SOC_SINGLE_EXT("DSD LO1 Switch", SND_SOC_NOPM, INTERP_LO1, 1, 0, + tavil_dsd_mixer_get, tavil_dsd_mixer_put), +}; + +static const struct snd_kcontrol_new lo2_mixer[] = { + SOC_SINGLE_EXT("DSD LO2 Switch", SND_SOC_NOPM, INTERP_LO2, 1, 0, + tavil_dsd_mixer_get, tavil_dsd_mixer_put), +}; + +static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM, + AIF1_PB, 0, tavil_codec_enable_slimrx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM, + AIF2_PB, 0, tavil_codec_enable_slimrx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM, + AIF3_PB, 0, tavil_codec_enable_slimrx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM, + AIF4_PB, 0, tavil_codec_enable_slimrx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + WCD_DAPM_MUX("SLIM RX0 MUX", WCD934X_RX0, slim_rx0), + WCD_DAPM_MUX("SLIM RX1 MUX", WCD934X_RX1, slim_rx1), + WCD_DAPM_MUX("SLIM RX2 MUX", WCD934X_RX2, slim_rx2), + WCD_DAPM_MUX("SLIM RX3 MUX", WCD934X_RX3, slim_rx3), + WCD_DAPM_MUX("SLIM RX4 MUX", WCD934X_RX4, slim_rx4), + WCD_DAPM_MUX("SLIM RX5 MUX", WCD934X_RX5, slim_rx5), + WCD_DAPM_MUX("SLIM RX6 MUX", WCD934X_RX6, slim_rx6), + WCD_DAPM_MUX("SLIM RX7 MUX", WCD934X_RX7, slim_rx7), + + SND_SOC_DAPM_MIXER("SLIM RX0", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0), + + WCD_DAPM_MUX("CDC_IF RX0 MUX", WCD934X_RX0, cdc_if_rx0), + WCD_DAPM_MUX("CDC_IF RX1 MUX", WCD934X_RX1, cdc_if_rx1), + WCD_DAPM_MUX("CDC_IF RX2 MUX", WCD934X_RX2, cdc_if_rx2), + WCD_DAPM_MUX("CDC_IF RX3 MUX", WCD934X_RX3, cdc_if_rx3), + WCD_DAPM_MUX("CDC_IF RX4 MUX", WCD934X_RX4, cdc_if_rx4), + WCD_DAPM_MUX("CDC_IF RX5 MUX", WCD934X_RX5, cdc_if_rx5), + WCD_DAPM_MUX("CDC_IF RX6 MUX", WCD934X_RX6, cdc_if_rx6), + WCD_DAPM_MUX("CDC_IF RX7 MUX", WCD934X_RX7, cdc_if_rx7), + + SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", SND_SOC_NOPM, INTERP_EAR, 0, + &rx_int0_2_mux, tavil_codec_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", SND_SOC_NOPM, INTERP_HPHL, 0, + &rx_int1_2_mux, tavil_codec_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", SND_SOC_NOPM, INTERP_HPHR, 0, + &rx_int2_2_mux, tavil_codec_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT3_2 MUX", SND_SOC_NOPM, INTERP_LO1, 0, + &rx_int3_2_mux, tavil_codec_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT4_2 MUX", SND_SOC_NOPM, INTERP_LO2, 0, + &rx_int4_2_mux, tavil_codec_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT7_2 MUX", SND_SOC_NOPM, INTERP_SPKR1, 0, + &rx_int7_2_mux, tavil_codec_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT8_2 MUX", SND_SOC_NOPM, INTERP_SPKR2, 0, + &rx_int8_2_mux, tavil_codec_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + WCD_DAPM_MUX("RX INT0_1 MIX1 INP0", 0, rx_int0_1_mix_inp0), + WCD_DAPM_MUX("RX INT0_1 MIX1 INP1", 0, rx_int0_1_mix_inp1), + WCD_DAPM_MUX("RX INT0_1 MIX1 INP2", 0, rx_int0_1_mix_inp2), + WCD_DAPM_MUX("RX INT1_1 MIX1 INP0", 0, rx_int1_1_mix_inp0), + WCD_DAPM_MUX("RX INT1_1 MIX1 INP1", 0, rx_int1_1_mix_inp1), + WCD_DAPM_MUX("RX INT1_1 MIX1 INP2", 0, rx_int1_1_mix_inp2), + WCD_DAPM_MUX("RX INT2_1 MIX1 INP0", 0, rx_int2_1_mix_inp0), + WCD_DAPM_MUX("RX INT2_1 MIX1 INP1", 0, rx_int2_1_mix_inp1), + WCD_DAPM_MUX("RX INT2_1 MIX1 INP2", 0, rx_int2_1_mix_inp2), + WCD_DAPM_MUX("RX INT3_1 MIX1 INP0", 0, rx_int3_1_mix_inp0), + WCD_DAPM_MUX("RX INT3_1 MIX1 INP1", 0, rx_int3_1_mix_inp1), + WCD_DAPM_MUX("RX INT3_1 MIX1 INP2", 0, rx_int3_1_mix_inp2), + WCD_DAPM_MUX("RX INT4_1 MIX1 INP0", 0, rx_int4_1_mix_inp0), + WCD_DAPM_MUX("RX INT4_1 MIX1 INP1", 0, rx_int4_1_mix_inp1), + WCD_DAPM_MUX("RX INT4_1 MIX1 INP2", 0, rx_int4_1_mix_inp2), + + SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, + &rx_int7_1_mix_inp0_mux, tavil_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx_int7_1_mix_inp1_mux, tavil_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx_int7_1_mix_inp2_mux, tavil_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, + &rx_int8_1_mix_inp0_mux, tavil_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx_int8_1_mix_inp1_mux, tavil_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx_int8_1_mix_inp2_mux, tavil_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, + rx_int1_asrc_switch, ARRAY_SIZE(rx_int1_asrc_switch)), + SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, + rx_int2_asrc_switch, ARRAY_SIZE(rx_int2_asrc_switch)), + SND_SOC_DAPM_MIXER("RX INT3_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT3 SEC MIX", SND_SOC_NOPM, 0, 0, + rx_int3_asrc_switch, ARRAY_SIZE(rx_int3_asrc_switch)), + SND_SOC_DAPM_MIXER("RX INT4_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT4 SEC MIX", SND_SOC_NOPM, 0, 0, + rx_int4_asrc_switch, ARRAY_SIZE(rx_int4_asrc_switch)), + SND_SOC_DAPM_MIXER("RX INT7_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT7 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT8_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT8 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT1 MIX3", SND_SOC_NOPM, 0, 0, hphl_mixer, + ARRAY_SIZE(hphl_mixer)), + SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT2 MIX3", SND_SOC_NOPM, 0, 0, hphr_mixer, + ARRAY_SIZE(hphr_mixer)), + SND_SOC_DAPM_MIXER("RX INT3 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT3 MIX3", SND_SOC_NOPM, 0, 0, lo1_mixer, + ARRAY_SIZE(lo1_mixer)), + SND_SOC_DAPM_MIXER("RX INT4 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT4 MIX3", SND_SOC_NOPM, 0, 0, lo2_mixer, + ARRAY_SIZE(lo2_mixer)), + SND_SOC_DAPM_MIXER("RX INT7 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER_E("RX INT7 CHAIN", SND_SOC_NOPM, 0, 0, + NULL, 0, tavil_codec_spk_boost_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX INT8 CHAIN", SND_SOC_NOPM, 0, 0, + NULL, 0, tavil_codec_spk_boost_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("RX INT0 MIX2 INP", SND_SOC_NOPM, INTERP_EAR, + 0, &rx_int0_mix2_inp_mux, tavil_codec_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT1 MIX2 INP", SND_SOC_NOPM, INTERP_HPHL, + 0, &rx_int1_mix2_inp_mux, tavil_codec_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT2 MIX2 INP", SND_SOC_NOPM, INTERP_HPHR, + 0, &rx_int2_mix2_inp_mux, tavil_codec_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT3 MIX2 INP", SND_SOC_NOPM, INTERP_LO1, + 0, &rx_int3_mix2_inp_mux, tavil_codec_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT4 MIX2 INP", SND_SOC_NOPM, INTERP_LO2, + 0, &rx_int4_mix2_inp_mux, tavil_codec_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT7 MIX2 INP", SND_SOC_NOPM, INTERP_SPKR1, + 0, &rx_int7_mix2_inp_mux, tavil_codec_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + WCD_DAPM_MUX("CDC_IF TX0 MUX", WCD934X_TX0, cdc_if_tx0), + WCD_DAPM_MUX("CDC_IF TX1 MUX", WCD934X_TX1, cdc_if_tx1), + WCD_DAPM_MUX("CDC_IF TX2 MUX", WCD934X_TX2, cdc_if_tx2), + WCD_DAPM_MUX("CDC_IF TX3 MUX", WCD934X_TX3, cdc_if_tx3), + WCD_DAPM_MUX("CDC_IF TX4 MUX", WCD934X_TX4, cdc_if_tx4), + WCD_DAPM_MUX("CDC_IF TX5 MUX", WCD934X_TX5, cdc_if_tx5), + WCD_DAPM_MUX("CDC_IF TX6 MUX", WCD934X_TX6, cdc_if_tx6), + WCD_DAPM_MUX("CDC_IF TX7 MUX", WCD934X_TX7, cdc_if_tx7), + WCD_DAPM_MUX("CDC_IF TX8 MUX", WCD934X_TX8, cdc_if_tx8), + WCD_DAPM_MUX("CDC_IF TX9 MUX", WCD934X_TX9, cdc_if_tx9), + WCD_DAPM_MUX("CDC_IF TX10 MUX", WCD934X_TX10, cdc_if_tx10), + WCD_DAPM_MUX("CDC_IF TX11 MUX", WCD934X_TX11, cdc_if_tx11), + WCD_DAPM_MUX("CDC_IF TX11 INP1 MUX", WCD934X_TX11, cdc_if_tx11_inp1), + WCD_DAPM_MUX("CDC_IF TX13 MUX", WCD934X_TX13, cdc_if_tx13), + WCD_DAPM_MUX("CDC_IF TX13 INP1 MUX", WCD934X_TX13, cdc_if_tx13_inp1), + + SND_SOC_DAPM_MUX_E("ADC MUX0", WCD934X_CDC_TX0_TX_PATH_CTL, 5, 0, + &tx_adc_mux0_mux, tavil_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX1", WCD934X_CDC_TX1_TX_PATH_CTL, 5, 0, + &tx_adc_mux1_mux, tavil_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX2", WCD934X_CDC_TX2_TX_PATH_CTL, 5, 0, + &tx_adc_mux2_mux, tavil_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX3", WCD934X_CDC_TX3_TX_PATH_CTL, 5, 0, + &tx_adc_mux3_mux, tavil_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX4", WCD934X_CDC_TX4_TX_PATH_CTL, 5, 0, + &tx_adc_mux4_mux, tavil_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX5", WCD934X_CDC_TX5_TX_PATH_CTL, 5, 0, + &tx_adc_mux5_mux, tavil_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX6", WCD934X_CDC_TX6_TX_PATH_CTL, 5, 0, + &tx_adc_mux6_mux, tavil_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX7", WCD934X_CDC_TX7_TX_PATH_CTL, 5, 0, + &tx_adc_mux7_mux, tavil_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX8", WCD934X_CDC_TX8_TX_PATH_CTL, 5, 0, + &tx_adc_mux8_mux, tavil_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX10", SND_SOC_NOPM, 10, 0, &tx_adc_mux10_mux, + tavil_codec_tx_adc_cfg, SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_MUX_E("ADC MUX11", SND_SOC_NOPM, 11, 0, &tx_adc_mux11_mux, + tavil_codec_tx_adc_cfg, SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_MUX_E("ADC MUX12", SND_SOC_NOPM, 12, 0, &tx_adc_mux12_mux, + tavil_codec_tx_adc_cfg, SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_MUX_E("ADC MUX13", SND_SOC_NOPM, 13, 0, &tx_adc_mux13_mux, + tavil_codec_tx_adc_cfg, SND_SOC_DAPM_POST_PMU), + + WCD_DAPM_MUX("DMIC MUX0", 0, tx_dmic_mux0), + WCD_DAPM_MUX("DMIC MUX1", 0, tx_dmic_mux1), + WCD_DAPM_MUX("DMIC MUX2", 0, tx_dmic_mux2), + WCD_DAPM_MUX("DMIC MUX3", 0, tx_dmic_mux3), + WCD_DAPM_MUX("DMIC MUX4", 0, tx_dmic_mux4), + WCD_DAPM_MUX("DMIC MUX5", 0, tx_dmic_mux5), + WCD_DAPM_MUX("DMIC MUX6", 0, tx_dmic_mux6), + WCD_DAPM_MUX("DMIC MUX7", 0, tx_dmic_mux7), + WCD_DAPM_MUX("DMIC MUX8", 0, tx_dmic_mux8), + WCD_DAPM_MUX("DMIC MUX10", 0, tx_dmic_mux10), + WCD_DAPM_MUX("DMIC MUX11", 0, tx_dmic_mux11), + WCD_DAPM_MUX("DMIC MUX12", 0, tx_dmic_mux12), + WCD_DAPM_MUX("DMIC MUX13", 0, tx_dmic_mux13), + + WCD_DAPM_MUX("AMIC MUX0", 0, tx_amic_mux0), + WCD_DAPM_MUX("AMIC MUX1", 0, tx_amic_mux1), + WCD_DAPM_MUX("AMIC MUX2", 0, tx_amic_mux2), + WCD_DAPM_MUX("AMIC MUX3", 0, tx_amic_mux3), + WCD_DAPM_MUX("AMIC MUX4", 0, tx_amic_mux4), + WCD_DAPM_MUX("AMIC MUX5", 0, tx_amic_mux5), + WCD_DAPM_MUX("AMIC MUX6", 0, tx_amic_mux6), + WCD_DAPM_MUX("AMIC MUX7", 0, tx_amic_mux7), + WCD_DAPM_MUX("AMIC MUX8", 0, tx_amic_mux8), + WCD_DAPM_MUX("AMIC MUX10", 0, tx_amic_mux10), + WCD_DAPM_MUX("AMIC MUX11", 0, tx_amic_mux11), + WCD_DAPM_MUX("AMIC MUX12", 0, tx_amic_mux12), + WCD_DAPM_MUX("AMIC MUX13", 0, tx_amic_mux13), + + SND_SOC_DAPM_ADC_E("ADC1", NULL, WCD934X_ANA_AMIC1, 7, 0, + tavil_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_ADC_E("ADC2", NULL, WCD934X_ANA_AMIC2, 7, 0, + tavil_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_ADC_E("ADC3", NULL, WCD934X_ANA_AMIC3, 7, 0, + tavil_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_ADC_E("ADC4", NULL, WCD934X_ANA_AMIC4, 7, 0, + tavil_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + + WCD_DAPM_MUX("AMIC4_5 SEL", 0, tx_amic4_5), + + WCD_DAPM_MUX("ANC0 FB MUX", 0, anc0_fb), + WCD_DAPM_MUX("ANC1 FB MUX", 0, anc1_fb), + + SND_SOC_DAPM_INPUT("AMIC1"), + SND_SOC_DAPM_INPUT("AMIC2"), + SND_SOC_DAPM_INPUT("AMIC3"), + SND_SOC_DAPM_INPUT("AMIC4"), + SND_SOC_DAPM_INPUT("AMIC5"), + + SND_SOC_DAPM_MICBIAS_E("MIC BIAS1", SND_SOC_NOPM, 0, 0, + tavil_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS2", SND_SOC_NOPM, 0, 0, + tavil_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS3", SND_SOC_NOPM, 0, 0, + tavil_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS4", SND_SOC_NOPM, 0, 0, + tavil_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + /* + * Not supply widget, this is used to recover HPH registers. + * It is not connected to any other widgets + */ + SND_SOC_DAPM_SUPPLY("RESET_HPH_REGISTERS", SND_SOC_NOPM, + 0, 0, tavil_codec_reset_hph_registers, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS1_STANDALONE, SND_SOC_NOPM, 0, 0, + tavil_codec_force_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS2_STANDALONE, SND_SOC_NOPM, 0, 0, + tavil_codec_force_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS3_STANDALONE, SND_SOC_NOPM, 0, 0, + tavil_codec_force_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS4_STANDALONE, SND_SOC_NOPM, 0, 0, + tavil_codec_force_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM, + AIF1_CAP, 0, tavil_codec_enable_slimtx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM, + AIF2_CAP, 0, tavil_codec_enable_slimtx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM, + AIF3_CAP, 0, tavil_codec_enable_slimtx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0, + aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)), + SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0, + aif2_cap_mixer, ARRAY_SIZE(aif2_cap_mixer)), + SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0, + aif3_cap_mixer, ARRAY_SIZE(aif3_cap_mixer)), + SND_SOC_DAPM_MIXER("AIF4_MAD Mixer", SND_SOC_NOPM, AIF4_MAD_TX, 0, + aif4_mad_mixer, ARRAY_SIZE(aif4_mad_mixer)), + + SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM, + AIF4_VIFEED, 0, tavil_codec_enable_slimvi_feedback, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_AIF_OUT("AIF4 MAD", "AIF4 MAD TX", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_MIXER("AIF4_VI Mixer", SND_SOC_NOPM, AIF4_VIFEED, 0, + aif4_vi_mixer, ARRAY_SIZE(aif4_vi_mixer)), + SND_SOC_DAPM_INPUT("VIINPUT"), + + SND_SOC_DAPM_MIXER("SLIM TX0", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX3", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX4", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX5", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX6", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX7", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX8", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX9", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX10", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX11", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX13", SND_SOC_NOPM, 0, 0, NULL, 0), + + /* Digital Mic Inputs */ + SND_SOC_DAPM_ADC_E("DMIC0", NULL, SND_SOC_NOPM, 0, 0, + tavil_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0, + tavil_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0, + tavil_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0, + tavil_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0, + tavil_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0, + tavil_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + WCD_DAPM_MUX("IIR0 INP0 MUX", 0, iir0_inp0), + WCD_DAPM_MUX("IIR0 INP1 MUX", 0, iir0_inp1), + WCD_DAPM_MUX("IIR0 INP2 MUX", 0, iir0_inp2), + WCD_DAPM_MUX("IIR0 INP3 MUX", 0, iir0_inp3), + WCD_DAPM_MUX("IIR1 INP0 MUX", 0, iir1_inp0), + WCD_DAPM_MUX("IIR1 INP1 MUX", 0, iir1_inp1), + WCD_DAPM_MUX("IIR1 INP2 MUX", 0, iir1_inp2), + WCD_DAPM_MUX("IIR1 INP3 MUX", 0, iir1_inp3), + + SND_SOC_DAPM_MIXER_E("IIR0", WCD934X_CDC_SIDETONE_IIR0_IIR_PATH_CTL, + 4, 0, NULL, 0, tavil_codec_set_iir_gain, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_MIXER_E("IIR1", WCD934X_CDC_SIDETONE_IIR1_IIR_PATH_CTL, + 4, 0, NULL, 0, tavil_codec_set_iir_gain, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_MIXER("SRC0", WCD934X_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL, + 4, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SRC1", WCD934X_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL, + 4, 0, NULL, 0), + + WCD_DAPM_MUX("RX MIX TX0 MUX", 0, rx_mix_tx0), + WCD_DAPM_MUX("RX MIX TX1 MUX", 0, rx_mix_tx1), + WCD_DAPM_MUX("RX MIX TX2 MUX", 0, rx_mix_tx2), + WCD_DAPM_MUX("RX MIX TX3 MUX", 0, rx_mix_tx3), + WCD_DAPM_MUX("RX MIX TX4 MUX", 0, rx_mix_tx4), + WCD_DAPM_MUX("RX MIX TX5 MUX", 0, rx_mix_tx5), + WCD_DAPM_MUX("RX MIX TX6 MUX", 0, rx_mix_tx6), + WCD_DAPM_MUX("RX MIX TX7 MUX", 0, rx_mix_tx7), + WCD_DAPM_MUX("RX MIX TX8 MUX", 0, rx_mix_tx8), + WCD_DAPM_MUX("RX INT0 DEM MUX", 0, rx_int0_dem_inp), + WCD_DAPM_MUX("RX INT1 DEM MUX", 0, rx_int1_dem_inp), + WCD_DAPM_MUX("RX INT2 DEM MUX", 0, rx_int2_dem_inp), + + SND_SOC_DAPM_MUX_E("RX INT0_1 INTERP", SND_SOC_NOPM, INTERP_EAR, 0, + &rx_int0_1_interp_mux, tavil_codec_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT1_1 INTERP", SND_SOC_NOPM, INTERP_HPHL, 0, + &rx_int1_1_interp_mux, tavil_codec_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT2_1 INTERP", SND_SOC_NOPM, INTERP_HPHR, 0, + &rx_int2_1_interp_mux, tavil_codec_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT3_1 INTERP", SND_SOC_NOPM, INTERP_LO1, 0, + &rx_int3_1_interp_mux, tavil_codec_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT4_1 INTERP", SND_SOC_NOPM, INTERP_LO2, 0, + &rx_int4_1_interp_mux, tavil_codec_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT7_1 INTERP", SND_SOC_NOPM, INTERP_SPKR1, 0, + &rx_int7_1_interp_mux, tavil_codec_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT8_1 INTERP", SND_SOC_NOPM, INTERP_SPKR2, 0, + &rx_int8_1_interp_mux, tavil_codec_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + WCD_DAPM_MUX("RX INT0_2 INTERP", 0, rx_int0_2_interp), + WCD_DAPM_MUX("RX INT1_2 INTERP", 0, rx_int1_2_interp), + WCD_DAPM_MUX("RX INT2_2 INTERP", 0, rx_int2_2_interp), + WCD_DAPM_MUX("RX INT3_2 INTERP", 0, rx_int3_2_interp), + WCD_DAPM_MUX("RX INT4_2 INTERP", 0, rx_int4_2_interp), + WCD_DAPM_MUX("RX INT7_2 INTERP", 0, rx_int7_2_interp), + WCD_DAPM_MUX("RX INT8_2 INTERP", 0, rx_int8_2_interp), + + SND_SOC_DAPM_SWITCH("ADC US MUX0", WCD934X_CDC_TX0_TX_PATH_192_CTL, 0, + 0, &adc_us_mux0_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX1", WCD934X_CDC_TX1_TX_PATH_192_CTL, 0, + 0, &adc_us_mux1_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX2", WCD934X_CDC_TX2_TX_PATH_192_CTL, 0, + 0, &adc_us_mux2_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX3", WCD934X_CDC_TX3_TX_PATH_192_CTL, 0, + 0, &adc_us_mux3_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX4", WCD934X_CDC_TX4_TX_PATH_192_CTL, 0, + 0, &adc_us_mux4_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX5", WCD934X_CDC_TX5_TX_PATH_192_CTL, 0, + 0, &adc_us_mux5_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX6", WCD934X_CDC_TX6_TX_PATH_192_CTL, 0, + 0, &adc_us_mux6_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX7", WCD934X_CDC_TX7_TX_PATH_192_CTL, 0, + 0, &adc_us_mux7_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX8", WCD934X_CDC_TX8_TX_PATH_192_CTL, 0, + 0, &adc_us_mux8_switch), + + /* MAD related widgets */ + SND_SOC_DAPM_INPUT("MAD_CPE_INPUT"), + SND_SOC_DAPM_INPUT("MADINPUT"), + + WCD_DAPM_MUX("MAD_SEL MUX", 0, mad_sel), + WCD_DAPM_MUX("MAD_INP MUX", 0, mad_inp_mux), + + SND_SOC_DAPM_SWITCH_E("MAD_BROADCAST", SND_SOC_NOPM, 0, 0, + &mad_brdcst_switch, tavil_codec_ape_enable_mad, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_SWITCH_E("MAD_CPE1", SND_SOC_NOPM, 0, 0, + &mad_cpe1_switch, tavil_codec_cpe_mad_ctl, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SWITCH_E("MAD_CPE2", SND_SOC_NOPM, 0, 0, + &mad_cpe2_switch, tavil_codec_cpe_mad_ctl, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_OUTPUT("MAD_CPE_OUT1"), + SND_SOC_DAPM_OUTPUT("MAD_CPE_OUT2"), + + SND_SOC_DAPM_DAC_E("RX INT0 DAC", NULL, SND_SOC_NOPM, + 0, 0, tavil_codec_ear_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RX INT1 DAC", NULL, WCD934X_ANA_HPH, + 5, 0, tavil_codec_hphl_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RX INT2 DAC", NULL, WCD934X_ANA_HPH, + 4, 0, tavil_codec_hphr_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RX INT3 DAC", NULL, SND_SOC_NOPM, + 0, 0, tavil_codec_lineout_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RX INT4 DAC", NULL, SND_SOC_NOPM, + 0, 0, tavil_codec_lineout_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_PGA_E("EAR PA", WCD934X_ANA_EAR, 7, 0, NULL, 0, + tavil_codec_enable_ear_pa, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("HPHL PA", WCD934X_ANA_HPH, 7, 0, NULL, 0, + tavil_codec_enable_hphl_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("HPHR PA", WCD934X_ANA_HPH, 6, 0, NULL, 0, + tavil_codec_enable_hphr_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("LINEOUT1 PA", WCD934X_ANA_LO_1_2, 7, 0, NULL, 0, + tavil_codec_enable_lineout_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("LINEOUT2 PA", WCD934X_ANA_LO_1_2, 6, 0, NULL, 0, + tavil_codec_enable_lineout_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("ANC EAR PA", WCD934X_ANA_EAR, 7, 0, NULL, 0, + tavil_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("ANC SPK1 PA", SND_SOC_NOPM, 0, 0, NULL, 0, + tavil_codec_enable_spkr_anc, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("ANC HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0, + tavil_codec_enable_hphl_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("ANC HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0, + tavil_codec_enable_hphr_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_OUTPUT("EAR"), + SND_SOC_DAPM_OUTPUT("HPHL"), + SND_SOC_DAPM_OUTPUT("HPHR"), + SND_SOC_DAPM_OUTPUT("LINEOUT1"), + SND_SOC_DAPM_OUTPUT("LINEOUT2"), + SND_SOC_DAPM_OUTPUT("SPK1 OUT"), + SND_SOC_DAPM_OUTPUT("SPK2 OUT"), + SND_SOC_DAPM_OUTPUT("ANC EAR"), + SND_SOC_DAPM_OUTPUT("ANC HPHL"), + SND_SOC_DAPM_OUTPUT("ANC HPHR"), + + SND_SOC_DAPM_SWITCH("ANC OUT EAR Enable", SND_SOC_NOPM, 0, 0, + &anc_ear_switch), + SND_SOC_DAPM_SWITCH("ANC OUT EAR SPKR Enable", SND_SOC_NOPM, 0, 0, + &anc_ear_spkr_switch), + SND_SOC_DAPM_SWITCH("ANC SPKR PA Enable", SND_SOC_NOPM, 0, 0, + &anc_spkr_pa_switch), + + SND_SOC_DAPM_SWITCH_E("ANC OUT HPHL Enable", SND_SOC_NOPM, INTERP_HPHL, + 0, &anc_hphl_pa_switch, tavil_anc_out_switch_cb, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SWITCH_E("ANC OUT HPHR Enable", SND_SOC_NOPM, INTERP_HPHR, + 0, &anc_hphr_pa_switch, tavil_anc_out_switch_cb, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0, + tavil_codec_enable_rx_bias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("RX INT1 NATIVE SUPPLY", SND_SOC_NOPM, + INTERP_HPHL, 0, tavil_enable_native_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SUPPLY("RX INT2 NATIVE SUPPLY", SND_SOC_NOPM, + INTERP_HPHR, 0, tavil_enable_native_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SUPPLY("RX INT3 NATIVE SUPPLY", SND_SOC_NOPM, + INTERP_LO1, 0, tavil_enable_native_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SUPPLY("RX INT4 NATIVE SUPPLY", SND_SOC_NOPM, + INTERP_LO2, 0, tavil_enable_native_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SUPPLY("RX INT7 NATIVE SUPPLY", SND_SOC_NOPM, + INTERP_SPKR1, 0, tavil_enable_native_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SUPPLY("RX INT8 NATIVE SUPPLY", SND_SOC_NOPM, + INTERP_SPKR2, 0, tavil_enable_native_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + WCD_DAPM_MUX("RX INT1_1 NATIVE MUX", 0, int1_1_native), + WCD_DAPM_MUX("RX INT2_1 NATIVE MUX", 0, int2_1_native), + WCD_DAPM_MUX("RX INT3_1 NATIVE MUX", 0, int3_1_native), + WCD_DAPM_MUX("RX INT4_1 NATIVE MUX", 0, int4_1_native), + + WCD_DAPM_MUX("RX INT1_2 NATIVE MUX", 0, int1_2_native), + WCD_DAPM_MUX("RX INT2_2 NATIVE MUX", 0, int2_2_native), + WCD_DAPM_MUX("RX INT3_2 NATIVE MUX", 0, int3_2_native), + WCD_DAPM_MUX("RX INT4_2 NATIVE MUX", 0, int4_2_native), + WCD_DAPM_MUX("RX INT7_2 NATIVE MUX", 0, int7_2_native), + WCD_DAPM_MUX("RX INT8_2 NATIVE MUX", 0, int8_2_native), + + SND_SOC_DAPM_MUX_E("ASRC0 MUX", SND_SOC_NOPM, ASRC0, 0, + &asrc0_mux, tavil_codec_enable_asrc_resampler, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("ASRC1 MUX", SND_SOC_NOPM, ASRC1, 0, + &asrc1_mux, tavil_codec_enable_asrc_resampler, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("ASRC2 MUX", SND_SOC_NOPM, ASRC2, 0, + &asrc2_mux, tavil_codec_enable_asrc_resampler, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("ASRC3 MUX", SND_SOC_NOPM, ASRC3, 0, + &asrc3_mux, tavil_codec_enable_asrc_resampler, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static int tavil_get_channel_map(struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot) +{ + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(dai->codec); + u32 i = 0; + struct wcd9xxx_ch *ch; + int ret = 0; + + switch (dai->id) { + case AIF1_PB: + case AIF2_PB: + case AIF3_PB: + case AIF4_PB: + if (!rx_slot || !rx_num) { + dev_err(tavil->dev, "%s: Invalid rx_slot 0x%pK or rx_num 0x%pK\n", + __func__, rx_slot, rx_num); + ret = -EINVAL; + break; + } + list_for_each_entry(ch, &tavil->dai[dai->id].wcd9xxx_ch_list, + list) { + dev_dbg(tavil->dev, "%s: slot_num %u ch->ch_num %d\n", + __func__, i, ch->ch_num); + rx_slot[i++] = ch->ch_num; + } + *rx_num = i; + dev_dbg(tavil->dev, "%s: dai_name = %s dai_id = %x rx_num = %d\n", + __func__, dai->name, dai->id, i); + if (*rx_num == 0) { + dev_err(tavil->dev, "%s: Channel list empty for dai_name = %s dai_id = %x\n", + __func__, dai->name, dai->id); + ret = -EINVAL; + } + break; + case AIF1_CAP: + case AIF2_CAP: + case AIF3_CAP: + case AIF4_MAD_TX: + case AIF4_VIFEED: + if (!tx_slot || !tx_num) { + dev_err(tavil->dev, "%s: Invalid tx_slot 0x%pK or tx_num 0x%pK\n", + __func__, tx_slot, tx_num); + ret = -EINVAL; + break; + } + list_for_each_entry(ch, &tavil->dai[dai->id].wcd9xxx_ch_list, + list) { + dev_dbg(tavil->dev, "%s: slot_num %u ch->ch_num %d\n", + __func__, i, ch->ch_num); + tx_slot[i++] = ch->ch_num; + } + *tx_num = i; + dev_dbg(tavil->dev, "%s: dai_name = %s dai_id = %x tx_num = %d\n", + __func__, dai->name, dai->id, i); + if (*tx_num == 0) { + dev_err(tavil->dev, "%s: Channel list empty for dai_name = %s dai_id = %x\n", + __func__, dai->name, dai->id); + ret = -EINVAL; + } + break; + default: + dev_err(tavil->dev, "%s: Invalid DAI ID %x\n", + __func__, dai->id); + ret = -EINVAL; + break; + } + + return ret; +} + +static int tavil_set_channel_map(struct snd_soc_dai *dai, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot) +{ + struct tavil_priv *tavil; + struct wcd9xxx *core; + struct wcd9xxx_codec_dai_data *dai_data = NULL; + + tavil = snd_soc_codec_get_drvdata(dai->codec); + core = dev_get_drvdata(dai->codec->dev->parent); + + if (!tx_slot || !rx_slot) { + dev_err(tavil->dev, "%s: Invalid tx_slot 0x%pK, rx_slot 0x%pK\n", + __func__, tx_slot, rx_slot); + return -EINVAL; + } + dev_dbg(tavil->dev, "%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n", + __func__, dai->name, dai->id, tx_num, rx_num); + + wcd9xxx_init_slimslave(core, core->slim->laddr, + tx_num, tx_slot, rx_num, rx_slot); + /* Reserve TX13 for MAD data channel */ + dai_data = &tavil->dai[AIF4_MAD_TX]; + if (dai_data) + list_add_tail(&core->tx_chs[WCD934X_TX13].list, + &dai_data->wcd9xxx_ch_list); + + return 0; +} + +static int tavil_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + return 0; +} + +static void tavil_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); +} + +static int tavil_set_decimator_rate(struct snd_soc_dai *dai, + u32 sample_rate) +{ + struct snd_soc_codec *codec = dai->codec; + struct wcd9xxx_ch *ch; + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + u32 tx_port = 0, tx_fs_rate = 0; + u8 shift = 0, shift_val = 0, tx_mux_sel = 0; + int decimator = -1; + u16 tx_port_reg = 0, tx_fs_reg = 0; + + switch (sample_rate) { + case 8000: + tx_fs_rate = 0; + break; + case 16000: + tx_fs_rate = 1; + break; + case 32000: + tx_fs_rate = 3; + break; + case 48000: + tx_fs_rate = 4; + break; + case 96000: + tx_fs_rate = 5; + break; + case 192000: + tx_fs_rate = 6; + break; + default: + dev_err(tavil->dev, "%s: Invalid TX sample rate: %d\n", + __func__, sample_rate); + return -EINVAL; + + }; + + list_for_each_entry(ch, &tavil->dai[dai->id].wcd9xxx_ch_list, list) { + tx_port = ch->port; + dev_dbg(codec->dev, "%s: dai->id = %d, tx_port = %d", + __func__, dai->id, tx_port); + + if ((tx_port < 0) || (tx_port == 12) || (tx_port >= 14)) { + dev_err(codec->dev, "%s: Invalid SLIM TX%u port. DAI ID: %d\n", + __func__, tx_port, dai->id); + return -EINVAL; + } + /* Find the SB TX MUX input - which decimator is connected */ + if (tx_port < 4) { + tx_port_reg = WCD934X_CDC_IF_ROUTER_TX_MUX_CFG0; + shift = (tx_port << 1); + shift_val = 0x03; + } else if ((tx_port >= 4) && (tx_port < 8)) { + tx_port_reg = WCD934X_CDC_IF_ROUTER_TX_MUX_CFG1; + shift = ((tx_port - 4) << 1); + shift_val = 0x03; + } else if ((tx_port >= 8) && (tx_port < 11)) { + tx_port_reg = WCD934X_CDC_IF_ROUTER_TX_MUX_CFG2; + shift = ((tx_port - 8) << 1); + shift_val = 0x03; + } else if (tx_port == 11) { + tx_port_reg = WCD934X_CDC_IF_ROUTER_TX_MUX_CFG3; + shift = 0; + shift_val = 0x0F; + } else if (tx_port == 13) { + tx_port_reg = WCD934X_CDC_IF_ROUTER_TX_MUX_CFG3; + shift = 4; + shift_val = 0x03; + } + tx_mux_sel = snd_soc_read(codec, tx_port_reg) & + (shift_val << shift); + tx_mux_sel = tx_mux_sel >> shift; + + if (tx_port <= 8) { + if ((tx_mux_sel == 0x2) || (tx_mux_sel == 0x3)) + decimator = tx_port; + } else if (tx_port <= 10) { + if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2)) + decimator = ((tx_port == 9) ? 7 : 6); + } else if (tx_port == 11) { + if ((tx_mux_sel >= 1) && (tx_mux_sel < 7)) + decimator = tx_mux_sel - 1; + } else if (tx_port == 13) { + if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2)) + decimator = 5; + } + + if (decimator >= 0) { + tx_fs_reg = WCD934X_CDC_TX0_TX_PATH_CTL + + 16 * decimator; + dev_dbg(codec->dev, "%s: set DEC%u (-> SLIM_TX%u) rate to %u\n", + __func__, decimator, tx_port, sample_rate); + snd_soc_update_bits(codec, tx_fs_reg, 0x0F, tx_fs_rate); + } else if ((tx_port <= 8) && (tx_mux_sel == 0x01)) { + /* Check if the TX Mux input is RX MIX TXn */ + dev_dbg(codec->dev, "%s: RX_MIX_TX%u going to CDC_IF TX%u\n", + __func__, tx_port, tx_port); + } else { + dev_err(codec->dev, "%s: ERROR: Invalid decimator: %d\n", + __func__, decimator); + return -EINVAL; + } + } + return 0; +} + +static int tavil_set_mix_interpolator_rate(struct snd_soc_dai *dai, + u8 rate_reg_val, + u32 sample_rate) +{ + u8 int_2_inp; + u32 j; + u16 int_mux_cfg1, int_fs_reg; + u8 int_mux_cfg1_val; + struct snd_soc_codec *codec = dai->codec; + struct wcd9xxx_ch *ch; + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + list_for_each_entry(ch, &tavil->dai[dai->id].wcd9xxx_ch_list, list) { + int_2_inp = INTn_2_INP_SEL_RX0 + ch->port - + WCD934X_RX_PORT_START_NUMBER; + if ((int_2_inp < INTn_2_INP_SEL_RX0) || + (int_2_inp > INTn_2_INP_SEL_RX7)) { + dev_err(codec->dev, "%s: Invalid RX%u port, Dai ID is %d\n", + __func__, + (ch->port - WCD934X_RX_PORT_START_NUMBER), + dai->id); + return -EINVAL; + } + + int_mux_cfg1 = WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG1; + for (j = 0; j < WCD934X_NUM_INTERPOLATORS; j++) { + /* Interpolators 5 and 6 are not aviliable in Tavil */ + if (j == INTERP_LO3_NA || j == INTERP_LO4_NA) { + int_mux_cfg1 += 2; + continue; + } + int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1) & + 0x0F; + if (int_mux_cfg1_val == int_2_inp) { + /* + * Ear mix path supports only 48, 96, 192, + * 384KHz only + */ + if ((j == INTERP_EAR) && + (rate_reg_val < 0x4 || + rate_reg_val > 0x7)) { + dev_err_ratelimited(codec->dev, + "%s: Invalid rate for AIF_PB DAI(%d)\n", + __func__, dai->id); + return -EINVAL; + } + + int_fs_reg = WCD934X_CDC_RX0_RX_PATH_MIX_CTL + + 20 * j; + dev_dbg(codec->dev, "%s: AIF_PB DAI(%d) connected to INT%u_2\n", + __func__, dai->id, j); + dev_dbg(codec->dev, "%s: set INT%u_2 sample rate to %u\n", + __func__, j, sample_rate); + snd_soc_update_bits(codec, int_fs_reg, 0x0F, + rate_reg_val); + } + int_mux_cfg1 += 2; + } + } + return 0; +} + +static int tavil_set_prim_interpolator_rate(struct snd_soc_dai *dai, + u8 rate_reg_val, + u32 sample_rate) +{ + u8 int_1_mix1_inp; + u32 j; + u16 int_mux_cfg0, int_mux_cfg1; + u16 int_fs_reg; + u8 int_mux_cfg0_val, int_mux_cfg1_val; + u8 inp0_sel, inp1_sel, inp2_sel; + struct snd_soc_codec *codec = dai->codec; + struct wcd9xxx_ch *ch; + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_dsd_config *dsd_conf = tavil->dsd_config; + + list_for_each_entry(ch, &tavil->dai[dai->id].wcd9xxx_ch_list, list) { + int_1_mix1_inp = INTn_1_INP_SEL_RX0 + ch->port - + WCD934X_RX_PORT_START_NUMBER; + if ((int_1_mix1_inp < INTn_1_INP_SEL_RX0) || + (int_1_mix1_inp > INTn_1_INP_SEL_RX7)) { + dev_err(codec->dev, "%s: Invalid RX%u port, Dai ID is %d\n", + __func__, + (ch->port - WCD934X_RX_PORT_START_NUMBER), + dai->id); + return -EINVAL; + } + + int_mux_cfg0 = WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG0; + + /* + * Loop through all interpolator MUX inputs and find out + * to which interpolator input, the slim rx port + * is connected + */ + for (j = 0; j < WCD934X_NUM_INTERPOLATORS; j++) { + /* Interpolators 5 and 6 are not aviliable in Tavil */ + if (j == INTERP_LO3_NA || j == INTERP_LO4_NA) { + int_mux_cfg0 += 2; + continue; + } + int_mux_cfg1 = int_mux_cfg0 + 1; + + int_mux_cfg0_val = snd_soc_read(codec, int_mux_cfg0); + int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1); + inp0_sel = int_mux_cfg0_val & 0x0F; + inp1_sel = (int_mux_cfg0_val >> 4) & 0x0F; + inp2_sel = (int_mux_cfg1_val >> 4) & 0x0F; + if ((inp0_sel == int_1_mix1_inp) || + (inp1_sel == int_1_mix1_inp) || + (inp2_sel == int_1_mix1_inp)) { + /* + * Ear and speaker primary path does not support + * native sample rates + */ + if ((j == INTERP_EAR || j == INTERP_SPKR1 || + j == INTERP_SPKR2) && + (rate_reg_val > 0x7)) { + dev_err_ratelimited(codec->dev, + "%s: Invalid rate for AIF_PB DAI(%d)\n", + __func__, dai->id); + return -EINVAL; + } + + int_fs_reg = WCD934X_CDC_RX0_RX_PATH_CTL + + 20 * j; + dev_dbg(codec->dev, + "%s: AIF_PB DAI(%d) connected to INT%u_1\n", + __func__, dai->id, j); + dev_dbg(codec->dev, + "%s: set INT%u_1 sample rate to %u\n", + __func__, j, sample_rate); + snd_soc_update_bits(codec, int_fs_reg, 0x0F, + rate_reg_val); + } + int_mux_cfg0 += 2; + } + if (dsd_conf) + tavil_dsd_set_interp_rate(dsd_conf, ch->port, + sample_rate, rate_reg_val); + } + + return 0; +} + + +static int tavil_set_interpolator_rate(struct snd_soc_dai *dai, + u32 sample_rate) +{ + struct snd_soc_codec *codec = dai->codec; + int rate_val = 0; + int i, ret; + + for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) { + if (sample_rate == sr_val_tbl[i].sample_rate) { + rate_val = sr_val_tbl[i].rate_val; + break; + } + } + if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) { + dev_err(codec->dev, "%s: Unsupported sample rate: %d\n", + __func__, sample_rate); + return -EINVAL; + } + + ret = tavil_set_prim_interpolator_rate(dai, (u8)rate_val, sample_rate); + if (ret) + return ret; + ret = tavil_set_mix_interpolator_rate(dai, (u8)rate_val, sample_rate); + if (ret) + return ret; + + return ret; +} + +static int tavil_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + return 0; +} + +static int tavil_vi_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(dai->codec); + + dev_dbg(tavil->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", + __func__, dai->name, dai->id, params_rate(params), + params_channels(params)); + + tavil->dai[dai->id].rate = params_rate(params); + tavil->dai[dai->id].bit_width = 32; + + return 0; +} + +static int tavil_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(dai->codec); + int ret = 0; + + dev_dbg(tavil->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", + __func__, dai->name, dai->id, params_rate(params), + params_channels(params)); + + switch (substream->stream) { + case SNDRV_PCM_STREAM_PLAYBACK: + ret = tavil_set_interpolator_rate(dai, params_rate(params)); + if (ret) { + dev_err(tavil->dev, "%s: cannot set sample rate: %u\n", + __func__, params_rate(params)); + return ret; + } + switch (params_width(params)) { + case 16: + tavil->dai[dai->id].bit_width = 16; + break; + case 24: + tavil->dai[dai->id].bit_width = 24; + break; + case 32: + tavil->dai[dai->id].bit_width = 32; + break; + default: + return -EINVAL; + } + tavil->dai[dai->id].rate = params_rate(params); + break; + case SNDRV_PCM_STREAM_CAPTURE: + if (dai->id != AIF4_MAD_TX) + ret = tavil_set_decimator_rate(dai, + params_rate(params)); + if (ret) { + dev_err(tavil->dev, "%s: cannot set TX Decimator rate: %d\n", + __func__, ret); + return ret; + } + switch (params_width(params)) { + case 16: + tavil->dai[dai->id].bit_width = 16; + break; + case 24: + tavil->dai[dai->id].bit_width = 24; + break; + default: + dev_err(tavil->dev, "%s: Invalid format 0x%x\n", + __func__, params_width(params)); + return -EINVAL; + }; + tavil->dai[dai->id].rate = params_rate(params); + break; + default: + dev_err(tavil->dev, "%s: Invalid stream type %d\n", __func__, + substream->stream); + return -EINVAL; + }; + + return 0; +} + +static struct snd_soc_dai_ops tavil_dai_ops = { + .startup = tavil_startup, + .shutdown = tavil_shutdown, + .hw_params = tavil_hw_params, + .prepare = tavil_prepare, + .set_channel_map = tavil_set_channel_map, + .get_channel_map = tavil_get_channel_map, +}; + +static struct snd_soc_dai_ops tavil_vi_dai_ops = { + .hw_params = tavil_vi_hw_params, + .set_channel_map = tavil_set_channel_map, + .get_channel_map = tavil_get_channel_map, +}; + +static struct snd_soc_dai_driver tavil_dai[] = { + { + .name = "tavil_rx1", + .id = AIF1_PB, + .playback = { + .stream_name = "AIF1 Playback", + .rates = WCD934X_RATES_MASK | WCD934X_FRAC_RATES_MASK, + .formats = WCD934X_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 384000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tavil_dai_ops, + }, + { + .name = "tavil_tx1", + .id = AIF1_CAP, + .capture = { + .stream_name = "AIF1 Capture", + .rates = WCD934X_RATES_MASK, + .formats = WCD934X_FORMATS_S16_S24_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 4, + }, + .ops = &tavil_dai_ops, + }, + { + .name = "tavil_rx2", + .id = AIF2_PB, + .playback = { + .stream_name = "AIF2 Playback", + .rates = WCD934X_RATES_MASK | WCD934X_FRAC_RATES_MASK, + .formats = WCD934X_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 384000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tavil_dai_ops, + }, + { + .name = "tavil_tx2", + .id = AIF2_CAP, + .capture = { + .stream_name = "AIF2 Capture", + .rates = WCD934X_RATES_MASK, + .formats = WCD934X_FORMATS_S16_S24_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 4, + }, + .ops = &tavil_dai_ops, + }, + { + .name = "tavil_rx3", + .id = AIF3_PB, + .playback = { + .stream_name = "AIF3 Playback", + .rates = WCD934X_RATES_MASK | WCD934X_FRAC_RATES_MASK, + .formats = WCD934X_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 384000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tavil_dai_ops, + }, + { + .name = "tavil_tx3", + .id = AIF3_CAP, + .capture = { + .stream_name = "AIF3 Capture", + .rates = WCD934X_RATES_MASK, + .formats = WCD934X_FORMATS_S16_S24_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 4, + }, + .ops = &tavil_dai_ops, + }, + { + .name = "tavil_rx4", + .id = AIF4_PB, + .playback = { + .stream_name = "AIF4 Playback", + .rates = WCD934X_RATES_MASK | WCD934X_FRAC_RATES_MASK, + .formats = WCD934X_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 384000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tavil_dai_ops, + }, + { + .name = "tavil_vifeedback", + .id = AIF4_VIFEED, + .capture = { + .stream_name = "VIfeed", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, + .formats = WCD934X_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 4, + }, + .ops = &tavil_vi_dai_ops, + }, + { + .name = "tavil_mad1", + .id = AIF4_MAD_TX, + .capture = { + .stream_name = "AIF4 MAD TX", + .rates = SNDRV_PCM_RATE_16000, + .formats = WCD934X_FORMATS_S16_LE, + .rate_min = 16000, + .rate_max = 16000, + .channels_min = 1, + .channels_max = 1, + }, + .ops = &tavil_dai_ops, + }, +}; + +static void tavil_codec_power_gate_digital_core(struct tavil_priv *tavil) +{ + mutex_lock(&tavil->power_lock); + dev_dbg(tavil->dev, "%s: Entering power gating function, %d\n", + __func__, tavil->power_active_ref); + + if (tavil->power_active_ref > 0) + goto exit; + + wcd9xxx_set_power_state(tavil->wcd9xxx, + WCD_REGION_POWER_COLLAPSE_BEGIN, + WCD9XXX_DIG_CORE_REGION_1); + regmap_update_bits(tavil->wcd9xxx->regmap, + WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x04, 0x04); + regmap_update_bits(tavil->wcd9xxx->regmap, + WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x01, 0x00); + regmap_update_bits(tavil->wcd9xxx->regmap, + WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x02, 0x00); + wcd9xxx_set_power_state(tavil->wcd9xxx, WCD_REGION_POWER_DOWN, + WCD9XXX_DIG_CORE_REGION_1); +exit: + dev_dbg(tavil->dev, "%s: Exiting power gating function, %d\n", + __func__, tavil->power_active_ref); + mutex_unlock(&tavil->power_lock); +} + +static void tavil_codec_power_gate_work(struct work_struct *work) +{ + struct tavil_priv *tavil; + struct delayed_work *dwork; + + dwork = to_delayed_work(work); + tavil = container_of(dwork, struct tavil_priv, power_gate_work); + + tavil_codec_power_gate_digital_core(tavil); +} + +/* called under power_lock acquisition */ +static int tavil_dig_core_remove_power_collapse(struct tavil_priv *tavil) +{ + regmap_write(tavil->wcd9xxx->regmap, + WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x05); + regmap_write(tavil->wcd9xxx->regmap, + WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x07); + regmap_update_bits(tavil->wcd9xxx->regmap, + WCD934X_CODEC_RPM_RST_CTL, 0x02, 0x00); + regmap_update_bits(tavil->wcd9xxx->regmap, + WCD934X_CODEC_RPM_RST_CTL, 0x02, 0x02); + regmap_write(tavil->wcd9xxx->regmap, + WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x03); + + wcd9xxx_set_power_state(tavil->wcd9xxx, + WCD_REGION_POWER_COLLAPSE_REMOVE, + WCD9XXX_DIG_CORE_REGION_1); + regcache_mark_dirty(tavil->wcd9xxx->regmap); + regcache_sync_region(tavil->wcd9xxx->regmap, + WCD934X_DIG_CORE_REG_MIN, + WCD934X_DIG_CORE_REG_MAX); + + tavil_restore_iir_coeff(tavil, IIR0); + tavil_restore_iir_coeff(tavil, IIR1); + return 0; +} + +static int tavil_dig_core_power_collapse(struct tavil_priv *tavil, + int req_state) +{ + int cur_state; + + /* Exit if feature is disabled */ + if (!dig_core_collapse_enable) + return 0; + + mutex_lock(&tavil->power_lock); + if (req_state == POWER_COLLAPSE) + tavil->power_active_ref--; + else if (req_state == POWER_RESUME) + tavil->power_active_ref++; + else + goto unlock_mutex; + + if (tavil->power_active_ref < 0) { + dev_dbg(tavil->dev, "%s: power_active_ref is negative\n", + __func__); + goto unlock_mutex; + } + + if (req_state == POWER_COLLAPSE) { + if (tavil->power_active_ref == 0) { + schedule_delayed_work(&tavil->power_gate_work, + msecs_to_jiffies(dig_core_collapse_timer * 1000)); + } + } else if (req_state == POWER_RESUME) { + if (tavil->power_active_ref == 1) { + /* + * At this point, there can be two cases: + * 1. Core already in power collapse state + * 2. Timer kicked in and still did not expire or + * waiting for the power_lock + */ + cur_state = wcd9xxx_get_current_power_state( + tavil->wcd9xxx, + WCD9XXX_DIG_CORE_REGION_1); + if (cur_state == WCD_REGION_POWER_DOWN) { + tavil_dig_core_remove_power_collapse(tavil); + } else { + mutex_unlock(&tavil->power_lock); + cancel_delayed_work_sync( + &tavil->power_gate_work); + mutex_lock(&tavil->power_lock); + } + } + } + +unlock_mutex: + mutex_unlock(&tavil->power_lock); + + return 0; +} + +static int tavil_cdc_req_mclk_enable(struct tavil_priv *tavil, + bool enable) +{ + int ret = 0; + + if (enable) { + ret = clk_prepare_enable(tavil->wcd_ext_clk); + if (ret) { + dev_err(tavil->dev, "%s: ext clk enable failed\n", + __func__); + goto done; + } + /* get BG */ + wcd_resmgr_enable_master_bias(tavil->resmgr); + /* get MCLK */ + wcd_resmgr_enable_clk_block(tavil->resmgr, WCD_CLK_MCLK); + } else { + /* put MCLK */ + wcd_resmgr_disable_clk_block(tavil->resmgr, WCD_CLK_MCLK); + /* put BG */ + wcd_resmgr_disable_master_bias(tavil->resmgr); + clk_disable_unprepare(tavil->wcd_ext_clk); + } + +done: + return ret; +} + +static int __tavil_cdc_mclk_enable_locked(struct tavil_priv *tavil, + bool enable) +{ + int ret = 0; + + if (!tavil->wcd_ext_clk) { + dev_err(tavil->dev, "%s: wcd ext clock is NULL\n", __func__); + return -EINVAL; + } + + dev_dbg(tavil->dev, "%s: mclk_enable = %u\n", __func__, enable); + + if (enable) { + tavil_dig_core_power_collapse(tavil, POWER_RESUME); + tavil_vote_svs(tavil, true); + ret = tavil_cdc_req_mclk_enable(tavil, true); + if (ret) + goto done; + } else { + tavil_cdc_req_mclk_enable(tavil, false); + tavil_vote_svs(tavil, false); + tavil_dig_core_power_collapse(tavil, POWER_COLLAPSE); + } + +done: + return ret; +} + +static int __tavil_cdc_mclk_enable(struct tavil_priv *tavil, + bool enable) +{ + int ret; + + WCD9XXX_V2_BG_CLK_LOCK(tavil->resmgr); + ret = __tavil_cdc_mclk_enable_locked(tavil, enable); + if (enable) + wcd_resmgr_set_sido_input_src(tavil->resmgr, + SIDO_SOURCE_RCO_BG); + WCD9XXX_V2_BG_CLK_UNLOCK(tavil->resmgr); + + return ret; +} + +static ssize_t tavil_codec_version_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, size_t count, + loff_t pos) +{ + struct tavil_priv *tavil; + struct wcd9xxx *wcd9xxx; + char buffer[TAVIL_VERSION_ENTRY_SIZE]; + int len = 0; + + tavil = (struct tavil_priv *) entry->private_data; + if (!tavil) { + pr_err("%s: tavil priv is null\n", __func__); + return -EINVAL; + } + + wcd9xxx = tavil->wcd9xxx; + + switch (wcd9xxx->version) { + case TAVIL_VERSION_WCD9340_1_0: + len = snprintf(buffer, sizeof(buffer), "WCD9340_1_0\n"); + break; + case TAVIL_VERSION_WCD9341_1_0: + len = snprintf(buffer, sizeof(buffer), "WCD9341_1_0\n"); + break; + case TAVIL_VERSION_WCD9340_1_1: + len = snprintf(buffer, sizeof(buffer), "WCD9340_1_1\n"); + break; + case TAVIL_VERSION_WCD9341_1_1: + len = snprintf(buffer, sizeof(buffer), "WCD9341_1_1\n"); + break; + default: + len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + } + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops tavil_codec_info_ops = { + .read = tavil_codec_version_read, +}; + +/* + * tavil_codec_info_create_codec_entry - creates wcd934x module + * @codec_root: The parent directory + * @codec: Codec instance + * + * Creates wcd934x module and version entry under the given + * parent directory. + * + * Return: 0 on success or negative error code on failure. + */ +int tavil_codec_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + struct snd_info_entry *version_entry; + struct tavil_priv *tavil; + struct snd_soc_card *card; + + if (!codec_root || !codec) + return -EINVAL; + + tavil = snd_soc_codec_get_drvdata(codec); + card = codec->component.card; + tavil->entry = snd_info_create_subdir(codec_root->module, + "tavil", codec_root); + if (!tavil->entry) { + dev_dbg(codec->dev, "%s: failed to create wcd934x entry\n", + __func__); + return -ENOMEM; + } + + version_entry = snd_info_create_card_entry(card->snd_card, + "version", + tavil->entry); + if (!version_entry) { + dev_dbg(codec->dev, "%s: failed to create wcd934x version entry\n", + __func__); + return -ENOMEM; + } + + version_entry->private_data = tavil; + version_entry->size = TAVIL_VERSION_ENTRY_SIZE; + version_entry->content = SNDRV_INFO_CONTENT_DATA; + version_entry->c.ops = &tavil_codec_info_ops; + + if (snd_info_register(version_entry) < 0) { + snd_info_free_entry(version_entry); + return -ENOMEM; + } + tavil->version_entry = version_entry; + + return 0; +} +EXPORT_SYMBOL(tavil_codec_info_create_codec_entry); + +/** + * tavil_cdc_mclk_enable - Enable/disable codec mclk + * + * @codec: codec instance + * @enable: Indicates clk enable or disable + * + * Returns 0 on Success and error on failure + */ +int tavil_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable) +{ + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + return __tavil_cdc_mclk_enable(tavil, enable); +} +EXPORT_SYMBOL(tavil_cdc_mclk_enable); + +static int __tavil_codec_internal_rco_ctrl(struct snd_soc_codec *codec, + bool enable) +{ + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + if (enable) { + if (wcd_resmgr_get_clk_type(tavil->resmgr) == + WCD_CLK_RCO) { + ret = wcd_resmgr_enable_clk_block(tavil->resmgr, + WCD_CLK_RCO); + } else { + ret = tavil_cdc_req_mclk_enable(tavil, true); + if (ret) { + dev_err(codec->dev, + "%s: mclk_enable failed, err = %d\n", + __func__, ret); + goto done; + } + wcd_resmgr_set_sido_input_src(tavil->resmgr, + SIDO_SOURCE_RCO_BG); + ret = wcd_resmgr_enable_clk_block(tavil->resmgr, + WCD_CLK_RCO); + ret |= tavil_cdc_req_mclk_enable(tavil, false); + } + + } else { + ret = wcd_resmgr_disable_clk_block(tavil->resmgr, + WCD_CLK_RCO); + } + + if (ret) { + dev_err(codec->dev, "%s: Error in %s RCO\n", + __func__, (enable ? "enabling" : "disabling")); + ret = -EINVAL; + } + +done: + return ret; +} + +/* + * tavil_codec_internal_rco_ctrl: Enable/Disable codec's RCO clock + * @codec: Handle to the codec + * @enable: Indicates whether clock should be enabled or disabled + */ +static int tavil_codec_internal_rco_ctrl(struct snd_soc_codec *codec, + bool enable) +{ + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + WCD9XXX_V2_BG_CLK_LOCK(tavil->resmgr); + ret = __tavil_codec_internal_rco_ctrl(codec, enable); + WCD9XXX_V2_BG_CLK_UNLOCK(tavil->resmgr); + return ret; +} + +static const struct wcd_resmgr_cb tavil_resmgr_cb = { + .cdc_rco_ctrl = __tavil_codec_internal_rco_ctrl, +}; + +static const struct tavil_reg_mask_val tavil_codec_mclk2_1_1_defaults[] = { + {WCD934X_CLK_SYS_MCLK2_PRG1, 0x60, 0x20}, +}; + +static const struct tavil_reg_mask_val tavil_codec_mclk2_1_0_defaults[] = { + /* + * PLL Settings: + * Clock Root: MCLK2, + * Clock Source: EXT_CLK, + * Clock Destination: MCLK2 + * Clock Freq In: 19.2MHz, + * Clock Freq Out: 11.2896MHz + */ + {WCD934X_CLK_SYS_MCLK2_PRG1, 0x60, 0x20}, + {WCD934X_CLK_SYS_INT_POST_DIV_REG0, 0xFF, 0x5E}, + {WCD934X_CLK_SYS_INT_POST_DIV_REG1, 0x1F, 0x1F}, + {WCD934X_CLK_SYS_INT_REF_DIV_REG0, 0xFF, 0x54}, + {WCD934X_CLK_SYS_INT_REF_DIV_REG1, 0xFF, 0x01}, + {WCD934X_CLK_SYS_INT_FILTER_REG1, 0x07, 0x04}, + {WCD934X_CLK_SYS_INT_PLL_L_VAL, 0xFF, 0x93}, + {WCD934X_CLK_SYS_INT_PLL_N_VAL, 0xFF, 0xFA}, + {WCD934X_CLK_SYS_INT_TEST_REG0, 0xFF, 0x90}, + {WCD934X_CLK_SYS_INT_PFD_CP_DSM_PROG, 0xFF, 0x7E}, + {WCD934X_CLK_SYS_INT_VCO_PROG, 0xFF, 0xF8}, + {WCD934X_CLK_SYS_INT_TEST_REG1, 0xFF, 0x68}, + {WCD934X_CLK_SYS_INT_LDO_LOCK_CFG, 0xFF, 0x40}, + {WCD934X_CLK_SYS_INT_DIG_LOCK_DET_CFG, 0xFF, 0x32}, +}; + +static const struct tavil_reg_mask_val tavil_codec_reg_defaults[] = { + {WCD934X_BIAS_VBG_FINE_ADJ, 0xFF, 0x75}, + {WCD934X_CODEC_CPR_SVS_CX_VDD, 0xFF, 0x7C}, /* value in svs mode */ + {WCD934X_CODEC_CPR_SVS2_CX_VDD, 0xFF, 0x58}, /* value in svs2 mode */ + {WCD934X_CDC_RX0_RX_PATH_DSMDEM_CTL, 0x01, 0x01}, + {WCD934X_CDC_RX1_RX_PATH_DSMDEM_CTL, 0x01, 0x01}, + {WCD934X_CDC_RX2_RX_PATH_DSMDEM_CTL, 0x01, 0x01}, + {WCD934X_CDC_RX3_RX_PATH_DSMDEM_CTL, 0x01, 0x01}, + {WCD934X_CDC_RX4_RX_PATH_DSMDEM_CTL, 0x01, 0x01}, + {WCD934X_CDC_RX7_RX_PATH_DSMDEM_CTL, 0x01, 0x01}, + {WCD934X_CDC_RX8_RX_PATH_DSMDEM_CTL, 0x01, 0x01}, + {WCD934X_CDC_COMPANDER8_CTL7, 0x1E, 0x18}, + {WCD934X_CDC_COMPANDER7_CTL7, 0x1E, 0x18}, + {WCD934X_CDC_RX0_RX_PATH_SEC0, 0x08, 0x0}, + {WCD934X_CDC_CLSH_DECAY_CTRL, 0x03, 0x0}, + {WCD934X_MICB1_TEST_CTL_2, 0x07, 0x01}, + {WCD934X_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12}, + {WCD934X_CDC_BOOST0_BOOST_CFG2, 0x1C, 0x08}, + {WCD934X_CDC_BOOST1_BOOST_CFG1, 0x3F, 0x12}, + {WCD934X_CDC_BOOST1_BOOST_CFG2, 0x1C, 0x08}, + {WCD934X_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD, 0x1F, 0x09}, + {WCD934X_CDC_TX0_TX_PATH_CFG1, 0x01, 0x00}, + {WCD934X_CDC_TX1_TX_PATH_CFG1, 0x01, 0x00}, + {WCD934X_CDC_TX2_TX_PATH_CFG1, 0x01, 0x00}, + {WCD934X_CDC_TX3_TX_PATH_CFG1, 0x01, 0x00}, + {WCD934X_CDC_TX4_TX_PATH_CFG1, 0x01, 0x00}, + {WCD934X_CDC_TX5_TX_PATH_CFG1, 0x01, 0x00}, + {WCD934X_CDC_TX6_TX_PATH_CFG1, 0x01, 0x00}, + {WCD934X_CDC_TX7_TX_PATH_CFG1, 0x01, 0x00}, + {WCD934X_CDC_TX8_TX_PATH_CFG1, 0x01, 0x00}, + {WCD934X_RX_OCP_CTL, 0x0F, 0x02}, /* OCP number of attempts is 2 */ + {WCD934X_HPH_OCP_CTL, 0xFF, 0x3A}, /* OCP current limit */ + {WCD934X_HPH_L_TEST, 0x01, 0x01}, + {WCD934X_HPH_R_TEST, 0x01, 0x01}, + {WCD934X_CPE_FLL_CONFIG_CTL_2, 0xFF, 0x20}, + {WCD934X_MBHC_NEW_CTL_2, 0x0C, 0x00}, +}; + +static const struct tavil_reg_mask_val tavil_codec_reg_init_1_1_val[] = { + {WCD934X_CDC_COMPANDER1_CTL7, 0x1E, 0x06}, + {WCD934X_CDC_COMPANDER2_CTL7, 0x1E, 0x06}, + {WCD934X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0xFF, 0x84}, + {WCD934X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0xFF, 0x84}, + {WCD934X_CDC_RX3_RX_PATH_SEC0, 0xFC, 0xF4}, + {WCD934X_CDC_RX4_RX_PATH_SEC0, 0xFC, 0xF4}, +}; + +static const struct tavil_cpr_reg_defaults cpr_defaults[] = { + { 0x00000820, 0x00000094 }, + { 0x00000fC0, 0x00000048 }, + { 0x0000f000, 0x00000044 }, + { 0x0000bb80, 0xC0000178 }, + { 0x00000000, 0x00000160 }, + { 0x10854522, 0x00000060 }, + { 0x10854509, 0x00000064 }, + { 0x108544dd, 0x00000068 }, + { 0x108544ad, 0x0000006C }, + { 0x0000077E, 0x00000070 }, + { 0x000007da, 0x00000074 }, + { 0x00000000, 0x00000078 }, + { 0x00000000, 0x0000007C }, + { 0x00042029, 0x00000080 }, + { 0x4002002A, 0x00000090 }, + { 0x4002002B, 0x00000090 }, +}; + +static const struct tavil_reg_mask_val tavil_codec_reg_init_common_val[] = { + {WCD934X_CDC_CLSH_K2_MSB, 0x0F, 0x00}, + {WCD934X_CDC_CLSH_K2_LSB, 0xFF, 0x60}, + {WCD934X_CPE_SS_DMIC_CFG, 0x80, 0x00}, + {WCD934X_CDC_BOOST0_BOOST_CTL, 0x70, 0x50}, + {WCD934X_CDC_BOOST1_BOOST_CTL, 0x70, 0x50}, + {WCD934X_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08}, + {WCD934X_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08}, + {WCD934X_CDC_TOP_TOP_CFG1, 0x02, 0x02}, + {WCD934X_CDC_TOP_TOP_CFG1, 0x01, 0x01}, + {WCD934X_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {WCD934X_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {WCD934X_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {WCD934X_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {WCD934X_DATA_HUB_SB_TX11_INP_CFG, 0x01, 0x01}, + {WCD934X_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x01}, + {WCD934X_CDC_COMPANDER7_CTL3, 0x80, 0x80}, + {WCD934X_CDC_COMPANDER8_CTL3, 0x80, 0x80}, + {WCD934X_CDC_COMPANDER7_CTL7, 0x01, 0x01}, + {WCD934X_CDC_COMPANDER8_CTL7, 0x01, 0x01}, + {WCD934X_CODEC_RPM_CLK_GATE, 0x08, 0x00}, + {WCD934X_TLMM_DMIC3_CLK_PINCFG, 0xFF, 0x0a}, + {WCD934X_TLMM_DMIC3_DATA_PINCFG, 0xFF, 0x0a}, + {WCD934X_CPE_SS_SVA_CFG, 0x60, 0x00}, + {WCD934X_CPE_SS_CPAR_CFG, 0x10, 0x10}, +}; + +static void tavil_codec_init_reg(struct tavil_priv *priv) +{ + struct snd_soc_codec *codec = priv->codec; + u32 i; + + for (i = 0; i < ARRAY_SIZE(tavil_codec_reg_init_common_val); i++) + snd_soc_update_bits(codec, + tavil_codec_reg_init_common_val[i].reg, + tavil_codec_reg_init_common_val[i].mask, + tavil_codec_reg_init_common_val[i].val); + + if (TAVIL_IS_1_1(priv->wcd9xxx)) { + for (i = 0; i < ARRAY_SIZE(tavil_codec_reg_init_1_1_val); i++) + snd_soc_update_bits(codec, + tavil_codec_reg_init_1_1_val[i].reg, + tavil_codec_reg_init_1_1_val[i].mask, + tavil_codec_reg_init_1_1_val[i].val); + } +} + +static void tavil_update_reg_defaults(struct tavil_priv *tavil) +{ + u32 i; + struct wcd9xxx *wcd9xxx; + + wcd9xxx = tavil->wcd9xxx; + for (i = 0; i < ARRAY_SIZE(tavil_codec_reg_defaults); i++) + regmap_update_bits(wcd9xxx->regmap, + tavil_codec_reg_defaults[i].reg, + tavil_codec_reg_defaults[i].mask, + tavil_codec_reg_defaults[i].val); +} + +static void tavil_update_cpr_defaults(struct tavil_priv *tavil) +{ + int i; + struct wcd9xxx *wcd9xxx; + + wcd9xxx = tavil->wcd9xxx; + if (!TAVIL_IS_1_1(wcd9xxx)) + return; + + __tavil_cdc_mclk_enable(tavil, true); + + regmap_write(wcd9xxx->regmap, WCD934X_CODEC_CPR_SVS2_MIN_CX_VDD, 0x2C); + regmap_update_bits(wcd9xxx->regmap, WCD934X_CODEC_RPM_CLK_GATE, + 0x10, 0x00); + + for (i = 0; i < ARRAY_SIZE(cpr_defaults); i++) { + regmap_bulk_write(wcd9xxx->regmap, + WCD934X_CODEC_CPR_WR_DATA_0, + (u8 *)&cpr_defaults[i].wr_data, 4); + regmap_bulk_write(wcd9xxx->regmap, + WCD934X_CODEC_CPR_WR_ADDR_0, + (u8 *)&cpr_defaults[i].wr_addr, 4); + } + + __tavil_cdc_mclk_enable(tavil, false); +} + +static void tavil_slim_interface_init_reg(struct snd_soc_codec *codec) +{ + int i; + struct tavil_priv *priv = snd_soc_codec_get_drvdata(codec); + + for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++) + wcd9xxx_interface_reg_write(priv->wcd9xxx, + WCD934X_SLIM_PGD_PORT_INT_RX_EN0 + i, + 0xFF); +} + +static irqreturn_t tavil_misc_irq(int irq, void *data) +{ + struct tavil_priv *tavil = data; + int misc_val; + + /* Find source of interrupt */ + regmap_read(tavil->wcd9xxx->regmap, WCD934X_INTR_CODEC_MISC_STATUS, + &misc_val); + + if (misc_val & 0x08) { + dev_info(tavil->dev, "%s: irq: %d, DSD DC detected!\n", + __func__, irq); + /* DSD DC interrupt, reset DSD path */ + tavil_dsd_reset(tavil->dsd_config); + } else { + dev_err(tavil->dev, "%s: Codec misc irq: %d, val: 0x%x\n", + __func__, irq, misc_val); + } + + /* Clear interrupt status */ + regmap_update_bits(tavil->wcd9xxx->regmap, + WCD934X_INTR_CODEC_MISC_CLEAR, misc_val, 0x00); + + return IRQ_HANDLED; +} + +static irqreturn_t tavil_slimbus_irq(int irq, void *data) +{ + struct tavil_priv *tavil = data; + unsigned long status = 0; + int i, j, port_id, k; + u32 bit; + u8 val, int_val = 0; + bool tx, cleared; + unsigned short reg = 0; + + for (i = WCD934X_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0; + i <= WCD934X_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) { + val = wcd9xxx_interface_reg_read(tavil->wcd9xxx, i); + status |= ((u32)val << (8 * j)); + } + + for_each_set_bit(j, &status, 32) { + tx = (j >= 16 ? true : false); + port_id = (tx ? j - 16 : j); + val = wcd9xxx_interface_reg_read(tavil->wcd9xxx, + WCD934X_SLIM_PGD_PORT_INT_RX_SOURCE0 + j); + if (val) { + if (!tx) + reg = WCD934X_SLIM_PGD_PORT_INT_RX_EN0 + + (port_id / 8); + else + reg = WCD934X_SLIM_PGD_PORT_INT_TX_EN0 + + (port_id / 8); + int_val = wcd9xxx_interface_reg_read( + tavil->wcd9xxx, reg); + /* + * Ignore interrupts for ports for which the + * interrupts are not specifically enabled. + */ + if (!(int_val & (1 << (port_id % 8)))) + continue; + } + if (val & WCD934X_SLIM_IRQ_OVERFLOW) + dev_err_ratelimited(tavil->dev, "%s: overflow error on %s port %d, value %x\n", + __func__, (tx ? "TX" : "RX"), port_id, val); + if (val & WCD934X_SLIM_IRQ_UNDERFLOW) + dev_err_ratelimited(tavil->dev, "%s: underflow error on %s port %d, value %x\n", + __func__, (tx ? "TX" : "RX"), port_id, val); + if ((val & WCD934X_SLIM_IRQ_OVERFLOW) || + (val & WCD934X_SLIM_IRQ_UNDERFLOW)) { + if (!tx) + reg = WCD934X_SLIM_PGD_PORT_INT_RX_EN0 + + (port_id / 8); + else + reg = WCD934X_SLIM_PGD_PORT_INT_TX_EN0 + + (port_id / 8); + int_val = wcd9xxx_interface_reg_read( + tavil->wcd9xxx, reg); + if (int_val & (1 << (port_id % 8))) { + int_val = int_val ^ (1 << (port_id % 8)); + wcd9xxx_interface_reg_write(tavil->wcd9xxx, + reg, int_val); + } + } + if (val & WCD934X_SLIM_IRQ_PORT_CLOSED) { + /* + * INT SOURCE register starts from RX to TX + * but port number in the ch_mask is in opposite way + */ + bit = (tx ? j - 16 : j + 16); + dev_dbg(tavil->dev, "%s: %s port %d closed value %x, bit %u\n", + __func__, (tx ? "TX" : "RX"), port_id, val, + bit); + for (k = 0, cleared = false; k < NUM_CODEC_DAIS; k++) { + dev_dbg(tavil->dev, "%s: tavil->dai[%d].ch_mask = 0x%lx\n", + __func__, k, tavil->dai[k].ch_mask); + if (test_and_clear_bit(bit, + &tavil->dai[k].ch_mask)) { + cleared = true; + if (!tavil->dai[k].ch_mask) + wake_up( + &tavil->dai[k].dai_wait); + /* + * There are cases when multiple DAIs + * might be using the same slimbus + * channel. Hence don't break here. + */ + } + } + WARN(!cleared, + "Couldn't find slimbus %s port %d for closing\n", + (tx ? "TX" : "RX"), port_id); + } + wcd9xxx_interface_reg_write(tavil->wcd9xxx, + WCD934X_SLIM_PGD_PORT_INT_CLR_RX_0 + + (j / 8), + 1 << (j % 8)); + } + + return IRQ_HANDLED; +} + +static int tavil_setup_irqs(struct tavil_priv *tavil) +{ + int ret = 0; + struct snd_soc_codec *codec = tavil->codec; + struct wcd9xxx *wcd9xxx = tavil->wcd9xxx; + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + + ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_SLIMBUS, + tavil_slimbus_irq, "SLIMBUS Slave", tavil); + if (ret) + dev_err(codec->dev, "%s: Failed to request irq %d\n", __func__, + WCD9XXX_IRQ_SLIMBUS); + else + tavil_slim_interface_init_reg(codec); + + /* Register for misc interrupts as well */ + ret = wcd9xxx_request_irq(core_res, WCD934X_IRQ_MISC, + tavil_misc_irq, "CDC MISC Irq", tavil); + if (ret) + dev_err(codec->dev, "%s: Failed to request cdc misc irq\n", + __func__); + + return ret; +} + +static void tavil_init_slim_slave_cfg(struct snd_soc_codec *codec) +{ + struct tavil_priv *priv = snd_soc_codec_get_drvdata(codec); + struct afe_param_cdc_slimbus_slave_cfg *cfg; + struct wcd9xxx *wcd9xxx = priv->wcd9xxx; + uint64_t eaddr = 0; + + cfg = &priv->slimbus_slave_cfg; + cfg->minor_version = 1; + cfg->tx_slave_port_offset = 0; + cfg->rx_slave_port_offset = 16; + + memcpy(&eaddr, &wcd9xxx->slim->e_addr, sizeof(wcd9xxx->slim->e_addr)); + WARN_ON(sizeof(wcd9xxx->slim->e_addr) != 6); + cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF; + cfg->device_enum_addr_msw = eaddr >> 32; + + dev_dbg(codec->dev, "%s: slimbus logical address 0x%llx\n", + __func__, eaddr); +} + +static void tavil_cleanup_irqs(struct tavil_priv *tavil) +{ + struct wcd9xxx *wcd9xxx = tavil->wcd9xxx; + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + + wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_SLIMBUS, tavil); + wcd9xxx_free_irq(core_res, WCD934X_IRQ_MISC, tavil); +} + +/* + * wcd934x_get_micb_vout_ctl_val: converts micbias from volts to register value + * @micb_mv: micbias in mv + * + * return register value converted + */ +int wcd934x_get_micb_vout_ctl_val(u32 micb_mv) +{ + /* min micbias voltage is 1V and maximum is 2.85V */ + if (micb_mv < 1000 || micb_mv > 2850) { + pr_err("%s: unsupported micbias voltage\n", __func__); + return -EINVAL; + } + + return (micb_mv - 1000) / 50; +} +EXPORT_SYMBOL(wcd934x_get_micb_vout_ctl_val); + +static int tavil_handle_pdata(struct tavil_priv *tavil, + struct wcd9xxx_pdata *pdata) +{ + struct snd_soc_codec *codec = tavil->codec; + u8 mad_dmic_ctl_val; + u8 anc_ctl_value; + u32 def_dmic_rate, dmic_clk_drv; + int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4; + int rc = 0; + + if (!pdata) { + dev_err(codec->dev, "%s: NULL pdata\n", __func__); + return -ENODEV; + } + + /* set micbias voltage */ + vout_ctl_1 = wcd934x_get_micb_vout_ctl_val(pdata->micbias.micb1_mv); + vout_ctl_2 = wcd934x_get_micb_vout_ctl_val(pdata->micbias.micb2_mv); + vout_ctl_3 = wcd934x_get_micb_vout_ctl_val(pdata->micbias.micb3_mv); + vout_ctl_4 = wcd934x_get_micb_vout_ctl_val(pdata->micbias.micb4_mv); + if (vout_ctl_1 < 0 || vout_ctl_2 < 0 || + vout_ctl_3 < 0 || vout_ctl_4 < 0) { + rc = -EINVAL; + goto done; + } + snd_soc_update_bits(codec, WCD934X_ANA_MICB1, 0x3F, vout_ctl_1); + snd_soc_update_bits(codec, WCD934X_ANA_MICB2, 0x3F, vout_ctl_2); + snd_soc_update_bits(codec, WCD934X_ANA_MICB3, 0x3F, vout_ctl_3); + snd_soc_update_bits(codec, WCD934X_ANA_MICB4, 0x3F, vout_ctl_4); + + /* Set the DMIC sample rate */ + switch (pdata->mclk_rate) { + case WCD934X_MCLK_CLK_9P6MHZ: + def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ; + break; + case WCD934X_MCLK_CLK_12P288MHZ: + def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ; + break; + default: + /* should never happen */ + dev_err(codec->dev, "%s: Invalid mclk_rate %d\n", + __func__, pdata->mclk_rate); + rc = -EINVAL; + goto done; + }; + + if (pdata->dmic_sample_rate == + WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) { + dev_info(codec->dev, "%s: dmic_rate invalid default = %d\n", + __func__, def_dmic_rate); + pdata->dmic_sample_rate = def_dmic_rate; + } + if (pdata->mad_dmic_sample_rate == + WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) { + dev_info(codec->dev, "%s: mad_dmic_rate invalid default = %d\n", + __func__, def_dmic_rate); + /* + * use dmic_sample_rate as the default for MAD + * if mad dmic sample rate is undefined + */ + pdata->mad_dmic_sample_rate = pdata->dmic_sample_rate; + } + + if (pdata->dmic_clk_drv == + WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED) { + pdata->dmic_clk_drv = WCD934X_DMIC_CLK_DRIVE_DEFAULT; + dev_dbg(codec->dev, + "%s: dmic_clk_strength invalid, default = %d\n", + __func__, pdata->dmic_clk_drv); + } + + switch (pdata->dmic_clk_drv) { + case 2: + dmic_clk_drv = 0; + break; + case 4: + dmic_clk_drv = 1; + break; + case 8: + dmic_clk_drv = 2; + break; + case 16: + dmic_clk_drv = 3; + break; + default: + dev_err(codec->dev, + "%s: invalid dmic_clk_drv %d, using default\n", + __func__, pdata->dmic_clk_drv); + dmic_clk_drv = 0; + break; + } + + snd_soc_update_bits(codec, WCD934X_TEST_DEBUG_PAD_DRVCTL_0, + 0x0C, dmic_clk_drv << 2); + + /* + * Default the DMIC clk rates to mad_dmic_sample_rate, + * whereas, the anc/txfe dmic rates to dmic_sample_rate + * since the anc/txfe are independent of mad block. + */ + mad_dmic_ctl_val = tavil_get_dmic_clk_val(tavil->codec, + pdata->mclk_rate, + pdata->mad_dmic_sample_rate); + snd_soc_update_bits(codec, WCD934X_CPE_SS_DMIC0_CTL, + 0x0E, mad_dmic_ctl_val << 1); + snd_soc_update_bits(codec, WCD934X_CPE_SS_DMIC1_CTL, + 0x0E, mad_dmic_ctl_val << 1); + snd_soc_update_bits(codec, WCD934X_CPE_SS_DMIC2_CTL, + 0x0E, mad_dmic_ctl_val << 1); + + if (dmic_clk_drv == WCD934X_DMIC_CLK_DIV_2) + anc_ctl_value = WCD934X_ANC_DMIC_X2_FULL_RATE; + else + anc_ctl_value = WCD934X_ANC_DMIC_X2_HALF_RATE; + + snd_soc_update_bits(codec, WCD934X_CDC_ANC0_MODE_2_CTL, + 0x40, anc_ctl_value << 6); + snd_soc_update_bits(codec, WCD934X_CDC_ANC0_MODE_2_CTL, + 0x20, anc_ctl_value << 5); + snd_soc_update_bits(codec, WCD934X_CDC_ANC1_MODE_2_CTL, + 0x40, anc_ctl_value << 6); + snd_soc_update_bits(codec, WCD934X_CDC_ANC1_MODE_2_CTL, + 0x20, anc_ctl_value << 5); + +done: + return rc; +} + +static void tavil_cdc_vote_svs(struct snd_soc_codec *codec, bool vote) +{ + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + return tavil_vote_svs(tavil, vote); +} + +struct wcd_dsp_cdc_cb cdc_cb = { + .cdc_clk_en = tavil_codec_internal_rco_ctrl, + .cdc_vote_svs = tavil_cdc_vote_svs, +}; + +static int tavil_wdsp_initialize(struct snd_soc_codec *codec) +{ + struct wcd9xxx *control; + struct tavil_priv *tavil; + struct wcd_dsp_params params; + int ret = 0; + + control = dev_get_drvdata(codec->dev->parent); + tavil = snd_soc_codec_get_drvdata(codec); + + params.cb = &cdc_cb; + params.irqs.cpe_ipc1_irq = WCD934X_IRQ_CPE1_INTR; + params.irqs.cpe_err_irq = WCD934X_IRQ_CPE_ERROR; + params.irqs.fatal_irqs = CPE_FATAL_IRQS; + params.clk_rate = control->mclk_rate; + params.dsp_instance = 0; + + wcd_dsp_cntl_init(codec, ¶ms, &tavil->wdsp_cntl); + if (!tavil->wdsp_cntl) { + dev_err(tavil->dev, "%s: wcd-dsp-control init failed\n", + __func__); + ret = -EINVAL; + } + + return ret; +} + +/* + * tavil_soc_get_mbhc: get wcd934x_mbhc handle of corresponding codec + * @codec: handle to snd_soc_codec * + * + * return wcd934x_mbhc handle or error code in case of failure + */ +struct wcd934x_mbhc *tavil_soc_get_mbhc(struct snd_soc_codec *codec) +{ + struct tavil_priv *tavil; + + if (!codec) { + pr_err("%s: Invalid params, NULL codec\n", __func__); + return NULL; + } + tavil = snd_soc_codec_get_drvdata(codec); + + if (!tavil) { + pr_err("%s: Invalid params, NULL tavil\n", __func__); + return NULL; + } + + return tavil->mbhc; +} +EXPORT_SYMBOL(tavil_soc_get_mbhc); + +static void tavil_mclk2_reg_defaults(struct tavil_priv *tavil) +{ + int i; + struct snd_soc_codec *codec = tavil->codec; + + if (TAVIL_IS_1_0(tavil->wcd9xxx)) { + /* MCLK2 configuration */ + for (i = 0; i < ARRAY_SIZE(tavil_codec_mclk2_1_0_defaults); i++) + snd_soc_update_bits(codec, + tavil_codec_mclk2_1_0_defaults[i].reg, + tavil_codec_mclk2_1_0_defaults[i].mask, + tavil_codec_mclk2_1_0_defaults[i].val); + } + if (TAVIL_IS_1_1(tavil->wcd9xxx)) { + /* MCLK2 configuration */ + for (i = 0; i < ARRAY_SIZE(tavil_codec_mclk2_1_1_defaults); i++) + snd_soc_update_bits(codec, + tavil_codec_mclk2_1_1_defaults[i].reg, + tavil_codec_mclk2_1_1_defaults[i].mask, + tavil_codec_mclk2_1_1_defaults[i].val); + } +} + +static int tavil_device_down(struct wcd9xxx *wcd9xxx) +{ + struct snd_soc_codec *codec; + struct tavil_priv *priv; + int count; + + codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); + priv = snd_soc_codec_get_drvdata(codec); + if (priv->swr.ctrl_data) + swrm_wcd_notify(priv->swr.ctrl_data[0].swr_pdev, + SWR_DEVICE_DOWN, NULL); + tavil_dsd_reset(priv->dsd_config); + snd_soc_card_change_online_state(codec->component.card, 0); + for (count = 0; count < NUM_CODEC_DAIS; count++) + priv->dai[count].bus_down_in_recovery = true; + wcd_dsp_ssr_event(priv->wdsp_cntl, WCD_CDC_DOWN_EVENT); + wcd_resmgr_set_sido_input_src_locked(priv->resmgr, + SIDO_SOURCE_INTERNAL); + + return 0; +} + +static int tavil_post_reset_cb(struct wcd9xxx *wcd9xxx) +{ + int i, ret = 0; + struct wcd9xxx *control; + struct snd_soc_codec *codec; + struct tavil_priv *tavil; + struct wcd9xxx_pdata *pdata; + struct wcd_mbhc *mbhc; + + codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); + tavil = snd_soc_codec_get_drvdata(codec); + control = dev_get_drvdata(codec->dev->parent); + + wcd9xxx_set_power_state(tavil->wcd9xxx, + WCD_REGION_POWER_COLLAPSE_REMOVE, + WCD9XXX_DIG_CORE_REGION_1); + + mutex_lock(&tavil->codec_mutex); + + tavil_vote_svs(tavil, true); + tavil_slimbus_slave_port_cfg.slave_dev_intfdev_la = + control->slim_slave->laddr; + tavil_slimbus_slave_port_cfg.slave_dev_pgd_la = + control->slim->laddr; + tavil_init_slim_slave_cfg(codec); + snd_soc_card_change_online_state(codec->component.card, 1); + + for (i = 0; i < TAVIL_MAX_MICBIAS; i++) + tavil->micb_ref[i] = 0; + + dev_dbg(codec->dev, "%s: MCLK Rate = %x\n", + __func__, control->mclk_rate); + + if (control->mclk_rate == WCD934X_MCLK_CLK_12P288MHZ) + snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_MCLK_CFG, + 0x03, 0x00); + else if (control->mclk_rate == WCD934X_MCLK_CLK_9P6MHZ) + snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_MCLK_CFG, + 0x03, 0x01); + wcd_resmgr_post_ssr_v2(tavil->resmgr); + tavil_update_reg_defaults(tavil); + tavil_codec_init_reg(tavil); + __tavil_enable_efuse_sensing(tavil); + tavil_mclk2_reg_defaults(tavil); + + __tavil_cdc_mclk_enable(tavil, true); + regcache_mark_dirty(codec->component.regmap); + regcache_sync(codec->component.regmap); + __tavil_cdc_mclk_enable(tavil, false); + + tavil_update_cpr_defaults(tavil); + + pdata = dev_get_platdata(codec->dev->parent); + ret = tavil_handle_pdata(tavil, pdata); + if (ret < 0) + dev_err(codec->dev, "%s: invalid pdata\n", __func__); + + /* Initialize MBHC module */ + mbhc = &tavil->mbhc->wcd_mbhc; + ret = tavil_mbhc_post_ssr_init(tavil->mbhc, codec); + if (ret) { + dev_err(codec->dev, "%s: mbhc initialization failed\n", + __func__); + goto done; + } else { + tavil_mbhc_hs_detect(codec, mbhc->mbhc_cfg); + } + + /* DSD initialization */ + ret = tavil_dsd_post_ssr_init(tavil->dsd_config); + if (ret) + dev_dbg(tavil->dev, "%s: DSD init failed\n", __func__); + + tavil_cleanup_irqs(tavil); + ret = tavil_setup_irqs(tavil); + if (ret) { + dev_err(codec->dev, "%s: tavil irq setup failed %d\n", + __func__, ret); + goto done; + } + + tavil_set_spkr_mode(codec, tavil->swr.spkr_mode); + /* + * Once the codec initialization is completed, the svs vote + * can be released allowing the codec to go to SVS2. + */ + tavil_vote_svs(tavil, false); + wcd_dsp_ssr_event(tavil->wdsp_cntl, WCD_CDC_UP_EVENT); + +done: + mutex_unlock(&tavil->codec_mutex); + return ret; +} + +static int tavil_soc_codec_probe(struct snd_soc_codec *codec) +{ + struct wcd9xxx *control; + struct tavil_priv *tavil; + struct wcd9xxx_pdata *pdata; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + int i, ret; + void *ptr = NULL; + + control = dev_get_drvdata(codec->dev->parent); + + dev_info(codec->dev, "%s()\n", __func__); + tavil = snd_soc_codec_get_drvdata(codec); + tavil->intf_type = wcd9xxx_get_intf_type(); + + control->dev_down = tavil_device_down; + control->post_reset = tavil_post_reset_cb; + control->ssr_priv = (void *)codec; + + /* Resource Manager post Init */ + ret = wcd_resmgr_post_init(tavil->resmgr, &tavil_resmgr_cb, codec); + if (ret) { + dev_err(codec->dev, "%s: wcd resmgr post init failed\n", + __func__); + goto err; + } + /* Class-H Init */ + wcd_clsh_init(&tavil->clsh_d); + /* Default HPH Mode to Class-H Low HiFi */ + tavil->hph_mode = CLS_H_LOHIFI; + + tavil->fw_data = devm_kzalloc(codec->dev, sizeof(*(tavil->fw_data)), + GFP_KERNEL); + if (!tavil->fw_data) + goto err; + + set_bit(WCD9XXX_ANC_CAL, tavil->fw_data->cal_bit); + set_bit(WCD9XXX_MBHC_CAL, tavil->fw_data->cal_bit); + set_bit(WCD9XXX_MAD_CAL, tavil->fw_data->cal_bit); + set_bit(WCD9XXX_VBAT_CAL, tavil->fw_data->cal_bit); + + ret = wcd_cal_create_hwdep(tavil->fw_data, + WCD9XXX_CODEC_HWDEP_NODE, codec); + if (ret < 0) { + dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret); + goto err_hwdep; + } + + /* Initialize MBHC module */ + ret = tavil_mbhc_init(&tavil->mbhc, codec, tavil->fw_data); + if (ret) { + pr_err("%s: mbhc initialization failed\n", __func__); + goto err_hwdep; + } + + tavil->codec = codec; + for (i = 0; i < COMPANDER_MAX; i++) + tavil->comp_enabled[i] = 0; + + tavil_codec_init_reg(tavil); + + pdata = dev_get_platdata(codec->dev->parent); + ret = tavil_handle_pdata(tavil, pdata); + if (ret < 0) { + dev_err(codec->dev, "%s: bad pdata\n", __func__); + goto err_hwdep; + } + + ptr = devm_kzalloc(codec->dev, (sizeof(tavil_rx_chs) + + sizeof(tavil_tx_chs)), GFP_KERNEL); + if (!ptr) { + ret = -ENOMEM; + goto err_hwdep; + } + + snd_soc_dapm_add_routes(dapm, tavil_slim_audio_map, + ARRAY_SIZE(tavil_slim_audio_map)); + for (i = 0; i < NUM_CODEC_DAIS; i++) { + INIT_LIST_HEAD(&tavil->dai[i].wcd9xxx_ch_list); + init_waitqueue_head(&tavil->dai[i].dai_wait); + } + tavil_slimbus_slave_port_cfg.slave_dev_intfdev_la = + control->slim_slave->laddr; + tavil_slimbus_slave_port_cfg.slave_dev_pgd_la = + control->slim->laddr; + tavil_slimbus_slave_port_cfg.slave_port_mapping[0] = + WCD934X_TX13; + tavil_init_slim_slave_cfg(codec); + + control->num_rx_port = WCD934X_RX_MAX; + control->rx_chs = ptr; + memcpy(control->rx_chs, tavil_rx_chs, sizeof(tavil_rx_chs)); + control->num_tx_port = WCD934X_TX_MAX; + control->tx_chs = ptr + sizeof(tavil_rx_chs); + memcpy(control->tx_chs, tavil_tx_chs, sizeof(tavil_tx_chs)); + + ret = tavil_setup_irqs(tavil); + if (ret) { + dev_err(tavil->dev, "%s: tavil irq setup failed %d\n", + __func__, ret); + goto err_pdata; + } + + for (i = 0; i < WCD934X_NUM_DECIMATORS; i++) { + tavil->tx_hpf_work[i].tavil = tavil; + tavil->tx_hpf_work[i].decimator = i; + INIT_DELAYED_WORK(&tavil->tx_hpf_work[i].dwork, + tavil_tx_hpf_corner_freq_callback); + + tavil->tx_mute_dwork[i].tavil = tavil; + tavil->tx_mute_dwork[i].decimator = i; + INIT_DELAYED_WORK(&tavil->tx_mute_dwork[i].dwork, + tavil_tx_mute_update_callback); + } + + tavil->spk_anc_dwork.tavil = tavil; + INIT_DELAYED_WORK(&tavil->spk_anc_dwork.dwork, + tavil_spk_anc_update_callback); + + tavil_mclk2_reg_defaults(tavil); + + /* DSD initialization */ + tavil->dsd_config = tavil_dsd_init(codec); + if (IS_ERR_OR_NULL(tavil->dsd_config)) + dev_dbg(tavil->dev, "%s: DSD init failed\n", __func__); + + mutex_lock(&tavil->codec_mutex); + snd_soc_dapm_disable_pin(dapm, "ANC EAR PA"); + snd_soc_dapm_disable_pin(dapm, "ANC EAR"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHL"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHR"); + snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA"); + mutex_unlock(&tavil->codec_mutex); + + snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AIF1 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "AIF2 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AIF2 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "AIF3 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AIF3 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "AIF4 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX"); + snd_soc_dapm_ignore_suspend(dapm, "VIfeed"); + + snd_soc_dapm_sync(dapm); + + tavil_wdsp_initialize(codec); + + /* + * Once the codec initialization is completed, the svs vote + * can be released allowing the codec to go to SVS2. + */ + tavil_vote_svs(tavil, false); + + return ret; + +err_pdata: + devm_kfree(codec->dev, ptr); + control->rx_chs = NULL; + control->tx_chs = NULL; +err_hwdep: + devm_kfree(codec->dev, tavil->fw_data); + tavil->fw_data = NULL; +err: + return ret; +} + +static int tavil_soc_codec_remove(struct snd_soc_codec *codec) +{ + struct wcd9xxx *control; + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + + control = dev_get_drvdata(codec->dev->parent); + devm_kfree(codec->dev, control->rx_chs); + control->rx_chs = NULL; + control->tx_chs = NULL; + tavil_cleanup_irqs(tavil); + + if (tavil->wdsp_cntl) + wcd_dsp_cntl_deinit(&tavil->wdsp_cntl); + + /* Deinitialize MBHC module */ + tavil_mbhc_deinit(codec); + tavil->mbhc = NULL; + + return 0; +} + +static struct regmap *tavil_get_regmap(struct device *dev) +{ + struct wcd9xxx *control = dev_get_drvdata(dev->parent); + + return control->regmap; +} + +static struct snd_soc_codec_driver soc_codec_dev_tavil = { + .probe = tavil_soc_codec_probe, + .remove = tavil_soc_codec_remove, + .get_regmap = tavil_get_regmap, + .component_driver = { + .controls = tavil_snd_controls, + .num_controls = ARRAY_SIZE(tavil_snd_controls), + .dapm_widgets = tavil_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tavil_dapm_widgets), + .dapm_routes = tavil_audio_map, + .num_dapm_routes = ARRAY_SIZE(tavil_audio_map), + }, +}; + +#ifdef CONFIG_PM +static int tavil_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct tavil_priv *tavil = platform_get_drvdata(pdev); + + if (!tavil) { + dev_err(dev, "%s: tavil private data is NULL\n", __func__); + return -EINVAL; + } + dev_dbg(dev, "%s: system suspend\n", __func__); + if (delayed_work_pending(&tavil->power_gate_work) && + cancel_delayed_work_sync(&tavil->power_gate_work)) + tavil_codec_power_gate_digital_core(tavil); + return 0; +} + +static int tavil_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct tavil_priv *tavil = platform_get_drvdata(pdev); + + if (!tavil) { + dev_err(dev, "%s: tavil private data is NULL\n", __func__); + return -EINVAL; + } + dev_dbg(dev, "%s: system resume\n", __func__); + return 0; +} + +static const struct dev_pm_ops tavil_pm_ops = { + .suspend = tavil_suspend, + .resume = tavil_resume, +}; +#endif + +static int tavil_swrm_read(void *handle, int reg) +{ + struct tavil_priv *tavil; + struct wcd9xxx *wcd9xxx; + unsigned short swr_rd_addr_base; + unsigned short swr_rd_data_base; + int val, ret; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + tavil = (struct tavil_priv *)handle; + wcd9xxx = tavil->wcd9xxx; + + dev_dbg(tavil->dev, "%s: Reading soundwire register, 0x%x\n", + __func__, reg); + swr_rd_addr_base = WCD934X_SWR_AHB_BRIDGE_RD_ADDR_0; + swr_rd_data_base = WCD934X_SWR_AHB_BRIDGE_RD_DATA_0; + + mutex_lock(&tavil->swr.read_mutex); + ret = regmap_bulk_write(wcd9xxx->regmap, swr_rd_addr_base, + (u8 *)®, 4); + if (ret < 0) { + dev_err(tavil->dev, "%s: RD Addr Failure\n", __func__); + goto done; + } + ret = regmap_bulk_read(wcd9xxx->regmap, swr_rd_data_base, + (u8 *)&val, 4); + if (ret < 0) { + dev_err(tavil->dev, "%s: RD Data Failure\n", __func__); + goto done; + } + ret = val; +done: + mutex_unlock(&tavil->swr.read_mutex); + + return ret; +} + +static int tavil_swrm_bulk_write(void *handle, u32 *reg, u32 *val, size_t len) +{ + struct tavil_priv *tavil; + struct wcd9xxx *wcd9xxx; + struct wcd9xxx_reg_val *bulk_reg; + unsigned short swr_wr_addr_base; + unsigned short swr_wr_data_base; + int i, j, ret; + + if (!handle || !reg || !val) { + pr_err("%s: NULL parameter\n", __func__); + return -EINVAL; + } + if (len <= 0) { + pr_err("%s: Invalid size: %zu\n", __func__, len); + return -EINVAL; + } + tavil = (struct tavil_priv *)handle; + wcd9xxx = tavil->wcd9xxx; + + swr_wr_addr_base = WCD934X_SWR_AHB_BRIDGE_WR_ADDR_0; + swr_wr_data_base = WCD934X_SWR_AHB_BRIDGE_WR_DATA_0; + + bulk_reg = kzalloc((2 * len * sizeof(struct wcd9xxx_reg_val)), + GFP_KERNEL); + if (!bulk_reg) + return -ENOMEM; + + for (i = 0, j = 0; i < (len * 2); i += 2, j++) { + bulk_reg[i].reg = swr_wr_data_base; + bulk_reg[i].buf = (u8 *)(&val[j]); + bulk_reg[i].bytes = 4; + bulk_reg[i+1].reg = swr_wr_addr_base; + bulk_reg[i+1].buf = (u8 *)(®[j]); + bulk_reg[i+1].bytes = 4; + } + + mutex_lock(&tavil->swr.write_mutex); + ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, + (len * 2), false); + if (ret) { + dev_err(tavil->dev, "%s: swrm bulk write failed, ret: %d\n", + __func__, ret); + } + mutex_unlock(&tavil->swr.write_mutex); + + kfree(bulk_reg); + return ret; +} + +static int tavil_swrm_write(void *handle, int reg, int val) +{ + struct tavil_priv *tavil; + struct wcd9xxx *wcd9xxx; + unsigned short swr_wr_addr_base; + unsigned short swr_wr_data_base; + struct wcd9xxx_reg_val bulk_reg[2]; + int ret; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + tavil = (struct tavil_priv *)handle; + wcd9xxx = tavil->wcd9xxx; + + swr_wr_addr_base = WCD934X_SWR_AHB_BRIDGE_WR_ADDR_0; + swr_wr_data_base = WCD934X_SWR_AHB_BRIDGE_WR_DATA_0; + + /* First Write the Data to register */ + bulk_reg[0].reg = swr_wr_data_base; + bulk_reg[0].buf = (u8 *)(&val); + bulk_reg[0].bytes = 4; + bulk_reg[1].reg = swr_wr_addr_base; + bulk_reg[1].buf = (u8 *)(®); + bulk_reg[1].bytes = 4; + + mutex_lock(&tavil->swr.write_mutex); + ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, 2, false); + if (ret < 0) + dev_err(tavil->dev, "%s: WR Data Failure\n", __func__); + mutex_unlock(&tavil->swr.write_mutex); + + return ret; +} + +static int tavil_swrm_clock(void *handle, bool enable) +{ + struct tavil_priv *tavil; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + tavil = (struct tavil_priv *)handle; + + mutex_lock(&tavil->swr.clk_mutex); + dev_dbg(tavil->dev, "%s: swrm clock %s\n", + __func__, (enable?"enable" : "disable")); + if (enable) { + tavil->swr.clk_users++; + if (tavil->swr.clk_users == 1) { + regmap_update_bits(tavil->wcd9xxx->regmap, + WCD934X_TEST_DEBUG_NPL_DLY_TEST_1, + 0x10, 0x00); + __tavil_cdc_mclk_enable(tavil, true); + regmap_update_bits(tavil->wcd9xxx->regmap, + WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x01); + } + } else { + tavil->swr.clk_users--; + if (tavil->swr.clk_users == 0) { + regmap_update_bits(tavil->wcd9xxx->regmap, + WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x00); + __tavil_cdc_mclk_enable(tavil, false); + regmap_update_bits(tavil->wcd9xxx->regmap, + WCD934X_TEST_DEBUG_NPL_DLY_TEST_1, + 0x10, 0x10); + } + } + dev_dbg(tavil->dev, "%s: swrm clock users %d\n", + __func__, tavil->swr.clk_users); + mutex_unlock(&tavil->swr.clk_mutex); + + return 0; +} + +static int tavil_swrm_handle_irq(void *handle, + irqreturn_t (*swrm_irq_handler)(int irq, + void *data), + void *swrm_handle, + int action) +{ + struct tavil_priv *tavil; + int ret = 0; + struct wcd9xxx *wcd9xxx; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + tavil = (struct tavil_priv *) handle; + wcd9xxx = tavil->wcd9xxx; + + if (action) { + ret = wcd9xxx_request_irq(&wcd9xxx->core_res, + WCD934X_IRQ_SOUNDWIRE, + swrm_irq_handler, + "Tavil SWR Master", swrm_handle); + if (ret) + dev_err(tavil->dev, "%s: Failed to request irq %d\n", + __func__, WCD934X_IRQ_SOUNDWIRE); + } else + wcd9xxx_free_irq(&wcd9xxx->core_res, WCD934X_IRQ_SOUNDWIRE, + swrm_handle); + + return ret; +} + +static void tavil_codec_add_spi_device(struct tavil_priv *tavil, + struct device_node *node) +{ + struct spi_master *master; + struct spi_device *spi; + u32 prop_value; + int rc; + + /* Read the master bus num from DT node */ + rc = of_property_read_u32(node, "qcom,master-bus-num", + &prop_value); + if (rc < 0) { + dev_err(tavil->dev, "%s: prop %s not found in node %s", + __func__, "qcom,master-bus-num", node->full_name); + goto done; + } + + /* Get the reference to SPI master */ + master = spi_busnum_to_master(prop_value); + if (!master) { + dev_err(tavil->dev, "%s: Invalid spi_master for bus_num %u\n", + __func__, prop_value); + goto done; + } + + /* Allocate the spi device */ + spi = spi_alloc_device(master); + if (!spi) { + dev_err(tavil->dev, "%s: spi_alloc_device failed\n", + __func__); + goto err_spi_alloc_dev; + } + + /* Initialize device properties */ + if (of_modalias_node(node, spi->modalias, + sizeof(spi->modalias)) < 0) { + dev_err(tavil->dev, "%s: cannot find modalias for %s\n", + __func__, node->full_name); + goto err_dt_parse; + } + + rc = of_property_read_u32(node, "qcom,chip-select", + &prop_value); + if (rc < 0) { + dev_err(tavil->dev, "%s: prop %s not found in node %s", + __func__, "qcom,chip-select", node->full_name); + goto err_dt_parse; + } + spi->chip_select = prop_value; + + rc = of_property_read_u32(node, "qcom,max-frequency", + &prop_value); + if (rc < 0) { + dev_err(tavil->dev, "%s: prop %s not found in node %s", + __func__, "qcom,max-frequency", node->full_name); + goto err_dt_parse; + } + spi->max_speed_hz = prop_value; + + spi->dev.of_node = node; + + rc = spi_add_device(spi); + if (rc < 0) { + dev_err(tavil->dev, "%s: spi_add_device failed\n", __func__); + goto err_dt_parse; + } + + /* Put the reference to SPI master */ + put_device(&master->dev); + + return; + +err_dt_parse: + spi_dev_put(spi); + +err_spi_alloc_dev: + /* Put the reference to SPI master */ + put_device(&master->dev); +done: + return; +} + +static void tavil_add_child_devices(struct work_struct *work) +{ + struct tavil_priv *tavil; + struct platform_device *pdev; + struct device_node *node; + struct wcd9xxx *wcd9xxx; + struct tavil_swr_ctrl_data *swr_ctrl_data = NULL, *temp; + int ret, ctrl_num = 0; + struct wcd_swr_ctrl_platform_data *platdata; + char plat_dev_name[WCD934X_STRING_LEN]; + + tavil = container_of(work, struct tavil_priv, + tavil_add_child_devices_work); + if (!tavil) { + pr_err("%s: Memory for WCD934X does not exist\n", + __func__); + return; + } + wcd9xxx = tavil->wcd9xxx; + if (!wcd9xxx) { + pr_err("%s: Memory for WCD9XXX does not exist\n", + __func__); + return; + } + if (!wcd9xxx->dev->of_node) { + dev_err(wcd9xxx->dev, "%s: DT node for wcd9xxx does not exist\n", + __func__); + return; + } + + platdata = &tavil->swr.plat_data; + + for_each_child_of_node(wcd9xxx->dev->of_node, node) { + + /* Parse and add the SPI device node */ + if (!strcmp(node->name, "wcd_spi")) { + tavil_codec_add_spi_device(tavil, node); + continue; + } + + /* Parse other child device nodes and add platform device */ + if (!strcmp(node->name, "swr_master")) + strlcpy(plat_dev_name, "tavil_swr_ctrl", + (WCD934X_STRING_LEN - 1)); + else if (strnstr(node->name, "msm_cdc_pinctrl", + strlen("msm_cdc_pinctrl")) != NULL) + strlcpy(plat_dev_name, node->name, + (WCD934X_STRING_LEN - 1)); + else + continue; + + pdev = platform_device_alloc(plat_dev_name, -1); + if (!pdev) { + dev_err(wcd9xxx->dev, "%s: pdev memory alloc failed\n", + __func__); + ret = -ENOMEM; + goto err_mem; + } + pdev->dev.parent = tavil->dev; + pdev->dev.of_node = node; + + if (strcmp(node->name, "swr_master") == 0) { + ret = platform_device_add_data(pdev, platdata, + sizeof(*platdata)); + if (ret) { + dev_err(&pdev->dev, + "%s: cannot add plat data ctrl:%d\n", + __func__, ctrl_num); + goto err_pdev_add; + } + } + + ret = platform_device_add(pdev); + if (ret) { + dev_err(&pdev->dev, + "%s: Cannot add platform device\n", + __func__); + goto err_pdev_add; + } + + if (strcmp(node->name, "swr_master") == 0) { + temp = krealloc(swr_ctrl_data, + (ctrl_num + 1) * sizeof( + struct tavil_swr_ctrl_data), + GFP_KERNEL); + if (!temp) { + dev_err(wcd9xxx->dev, "out of memory\n"); + ret = -ENOMEM; + goto err_pdev_add; + } + swr_ctrl_data = temp; + swr_ctrl_data[ctrl_num].swr_pdev = pdev; + ctrl_num++; + dev_dbg(&pdev->dev, + "%s: Added soundwire ctrl device(s)\n", + __func__); + tavil->swr.ctrl_data = swr_ctrl_data; + } + } + + return; + +err_pdev_add: + platform_device_put(pdev); +err_mem: + return; +} + +static int __tavil_enable_efuse_sensing(struct tavil_priv *tavil) +{ + int val, rc; + + WCD9XXX_V2_BG_CLK_LOCK(tavil->resmgr); + __tavil_cdc_mclk_enable_locked(tavil, true); + + regmap_update_bits(tavil->wcd9xxx->regmap, + WCD934X_CHIP_TIER_CTRL_EFUSE_CTL, 0x1E, 0x10); + regmap_update_bits(tavil->wcd9xxx->regmap, + WCD934X_CHIP_TIER_CTRL_EFUSE_CTL, 0x01, 0x01); + /* + * 5ms sleep required after enabling efuse control + * before checking the status. + */ + usleep_range(5000, 5500); + wcd_resmgr_set_sido_input_src(tavil->resmgr, + SIDO_SOURCE_RCO_BG); + + WCD9XXX_V2_BG_CLK_UNLOCK(tavil->resmgr); + + rc = regmap_read(tavil->wcd9xxx->regmap, + WCD934X_CHIP_TIER_CTRL_EFUSE_STATUS, &val); + if (rc || (!(val & 0x01))) + WARN(1, "%s: Efuse sense is not complete val=%x, ret=%d\n", + __func__, val, rc); + + __tavil_cdc_mclk_enable(tavil, false); + + return rc; +} + +static void ___tavil_get_codec_fine_version(struct tavil_priv *tavil) +{ + int val1, val2, version; + struct regmap *regmap; + u16 id_minor; + u32 version_mask = 0; + + regmap = tavil->wcd9xxx->regmap; + version = tavil->wcd9xxx->version; + id_minor = tavil->wcd9xxx->codec_type->id_minor; + + regmap_read(regmap, WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT14, &val1); + regmap_read(regmap, WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT15, &val2); + + dev_dbg(tavil->dev, "%s: chip version :0x%x 0x:%x\n", + __func__, val1, val2); + + version_mask |= (!!((u8)val1 & 0x80)) << DSD_DISABLED_MASK; + version_mask |= (!!((u8)val2 & 0x01)) << SLNQ_DISABLED_MASK; + + switch (version_mask) { + case DSD_DISABLED | SLNQ_DISABLED: + if (id_minor == cpu_to_le16(0)) + version = TAVIL_VERSION_WCD9340_1_0; + else if (id_minor == cpu_to_le16(0x01)) + version = TAVIL_VERSION_WCD9340_1_1; + break; + case SLNQ_DISABLED: + if (id_minor == cpu_to_le16(0)) + version = TAVIL_VERSION_WCD9341_1_0; + else if (id_minor == cpu_to_le16(0x01)) + version = TAVIL_VERSION_WCD9341_1_1; + break; + } + + tavil->wcd9xxx->version = version; + tavil->wcd9xxx->codec_type->version = version; +} + +/* + * tavil_get_wcd_dsp_cntl: Get the reference to wcd_dsp_cntl + * @dev: Device pointer for codec device + * + * This API gets the reference to codec's struct wcd_dsp_cntl + */ +struct wcd_dsp_cntl *tavil_get_wcd_dsp_cntl(struct device *dev) +{ + struct platform_device *pdev; + struct tavil_priv *tavil; + + if (!dev) { + pr_err("%s: Invalid device\n", __func__); + return NULL; + } + + pdev = to_platform_device(dev); + tavil = platform_get_drvdata(pdev); + + return tavil->wdsp_cntl; +} +EXPORT_SYMBOL(tavil_get_wcd_dsp_cntl); + +static int tavil_probe(struct platform_device *pdev) +{ + int ret = 0; + struct tavil_priv *tavil; + struct clk *wcd_ext_clk; + struct wcd9xxx_resmgr_v2 *resmgr; + struct wcd9xxx_power_region *cdc_pwr; + + tavil = devm_kzalloc(&pdev->dev, sizeof(struct tavil_priv), + GFP_KERNEL); + if (!tavil) + return -ENOMEM; + + platform_set_drvdata(pdev, tavil); + + tavil->wcd9xxx = dev_get_drvdata(pdev->dev.parent); + tavil->dev = &pdev->dev; + INIT_DELAYED_WORK(&tavil->power_gate_work, tavil_codec_power_gate_work); + mutex_init(&tavil->power_lock); + INIT_WORK(&tavil->tavil_add_child_devices_work, + tavil_add_child_devices); + mutex_init(&tavil->micb_lock); + mutex_init(&tavil->swr.read_mutex); + mutex_init(&tavil->swr.write_mutex); + mutex_init(&tavil->swr.clk_mutex); + mutex_init(&tavil->codec_mutex); + mutex_init(&tavil->svs_mutex); + + /* + * Codec hardware by default comes up in SVS mode. + * Initialize the svs_ref_cnt to 1 to reflect the hardware + * state in the driver. + */ + tavil->svs_ref_cnt = 1; + + cdc_pwr = devm_kzalloc(&pdev->dev, sizeof(struct wcd9xxx_power_region), + GFP_KERNEL); + if (!cdc_pwr) { + ret = -ENOMEM; + goto err_resmgr; + } + tavil->wcd9xxx->wcd9xxx_pwr[WCD9XXX_DIG_CORE_REGION_1] = cdc_pwr; + cdc_pwr->pwr_collapse_reg_min = WCD934X_DIG_CORE_REG_MIN; + cdc_pwr->pwr_collapse_reg_max = WCD934X_DIG_CORE_REG_MAX; + wcd9xxx_set_power_state(tavil->wcd9xxx, + WCD_REGION_POWER_COLLAPSE_REMOVE, + WCD9XXX_DIG_CORE_REGION_1); + /* + * Init resource manager so that if child nodes such as SoundWire + * requests for clock, resource manager can honor the request + */ + resmgr = wcd_resmgr_init(&tavil->wcd9xxx->core_res, NULL); + if (IS_ERR(resmgr)) { + ret = PTR_ERR(resmgr); + dev_err(&pdev->dev, "%s: Failed to initialize wcd resmgr\n", + __func__); + goto err_resmgr; + } + tavil->resmgr = resmgr; + tavil->swr.plat_data.handle = (void *) tavil; + tavil->swr.plat_data.read = tavil_swrm_read; + tavil->swr.plat_data.write = tavil_swrm_write; + tavil->swr.plat_data.bulk_write = tavil_swrm_bulk_write; + tavil->swr.plat_data.clk = tavil_swrm_clock; + tavil->swr.plat_data.handle_irq = tavil_swrm_handle_irq; + tavil->swr.spkr_gain_offset = WCD934X_RX_GAIN_OFFSET_0_DB; + + /* Register for Clock */ + wcd_ext_clk = clk_get(tavil->wcd9xxx->dev, "wcd_clk"); + if (IS_ERR(wcd_ext_clk)) { + dev_err(tavil->wcd9xxx->dev, "%s: clk get %s failed\n", + __func__, "wcd_ext_clk"); + goto err_clk; + } + tavil->wcd_ext_clk = wcd_ext_clk; + set_bit(AUDIO_NOMINAL, &tavil->status_mask); + /* Update codec register default values */ + dev_dbg(&pdev->dev, "%s: MCLK Rate = %x\n", __func__, + tavil->wcd9xxx->mclk_rate); + if (tavil->wcd9xxx->mclk_rate == WCD934X_MCLK_CLK_12P288MHZ) + regmap_update_bits(tavil->wcd9xxx->regmap, + WCD934X_CODEC_RPM_CLK_MCLK_CFG, + 0x03, 0x00); + else if (tavil->wcd9xxx->mclk_rate == WCD934X_MCLK_CLK_9P6MHZ) + regmap_update_bits(tavil->wcd9xxx->regmap, + WCD934X_CODEC_RPM_CLK_MCLK_CFG, + 0x03, 0x01); + tavil_update_reg_defaults(tavil); + __tavil_enable_efuse_sensing(tavil); + ___tavil_get_codec_fine_version(tavil); + tavil_update_cpr_defaults(tavil); + + /* Register with soc framework */ + ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tavil, + tavil_dai, ARRAY_SIZE(tavil_dai)); + if (ret) { + dev_err(&pdev->dev, "%s: Codec registration failed\n", + __func__); + goto err_cdc_reg; + } + schedule_work(&tavil->tavil_add_child_devices_work); + + return ret; + +err_cdc_reg: + clk_put(tavil->wcd_ext_clk); +err_clk: + wcd_resmgr_remove(tavil->resmgr); +err_resmgr: + mutex_destroy(&tavil->micb_lock); + mutex_destroy(&tavil->svs_mutex); + mutex_destroy(&tavil->codec_mutex); + mutex_destroy(&tavil->swr.read_mutex); + mutex_destroy(&tavil->swr.write_mutex); + mutex_destroy(&tavil->swr.clk_mutex); + devm_kfree(&pdev->dev, tavil); + + return ret; +} + +static int tavil_remove(struct platform_device *pdev) +{ + struct tavil_priv *tavil; + + tavil = platform_get_drvdata(pdev); + if (!tavil) + return -EINVAL; + + mutex_destroy(&tavil->micb_lock); + mutex_destroy(&tavil->svs_mutex); + mutex_destroy(&tavil->codec_mutex); + mutex_destroy(&tavil->swr.read_mutex); + mutex_destroy(&tavil->swr.write_mutex); + mutex_destroy(&tavil->swr.clk_mutex); + + snd_soc_unregister_codec(&pdev->dev); + clk_put(tavil->wcd_ext_clk); + wcd_resmgr_remove(tavil->resmgr); + if (tavil->dsd_config) { + tavil_dsd_deinit(tavil->dsd_config); + tavil->dsd_config = NULL; + } + devm_kfree(&pdev->dev, tavil); + return 0; +} + +static struct platform_driver tavil_codec_driver = { + .probe = tavil_probe, + .remove = tavil_remove, + .driver = { + .name = "tavil_codec", + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &tavil_pm_ops, +#endif + }, +}; + +module_platform_driver(tavil_codec_driver); + +MODULE_DESCRIPTION("Tavil Codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/wcd934x/wcd934x.h b/sound/soc/codecs/wcd934x/wcd934x.h new file mode 100644 index 000000000000..c3bf50a4ffdb --- /dev/null +++ b/sound/soc/codecs/wcd934x/wcd934x.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef WCD934X_H +#define WCD934X_H + +#include +#include +#include "wcd934x-dsp-cntl.h" +#include "../wcd9xxx-common-v2.h" +#include "../wcd-mbhc-v2.h" + +#define WCD934X_REGISTER_START_OFFSET 0x800 +#define WCD934X_SB_PGD_PORT_RX_BASE 0x40 +#define WCD934X_SB_PGD_PORT_TX_BASE 0x50 +#define WCD934X_RX_PORT_START_NUMBER 16 + +#define WCD934X_DMIC_CLK_DIV_2 0x0 +#define WCD934X_DMIC_CLK_DIV_3 0x1 +#define WCD934X_DMIC_CLK_DIV_4 0x2 +#define WCD934X_DMIC_CLK_DIV_6 0x3 +#define WCD934X_DMIC_CLK_DIV_8 0x4 +#define WCD934X_DMIC_CLK_DIV_16 0x5 +#define WCD934X_DMIC_CLK_DRIVE_DEFAULT 0x02 + +#define WCD934X_ANC_DMIC_X2_FULL_RATE 1 +#define WCD934X_ANC_DMIC_X2_HALF_RATE 0 + +#define TAVIL_MAX_MICBIAS 4 +#define TAVIL_NUM_INTERPOLATORS 9 +#define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64 + +/* Convert from vout ctl to micbias voltage in mV */ +#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50) + +/* Feature masks to distinguish codec version */ +#define DSD_DISABLED_MASK 0 +#define SLNQ_DISABLED_MASK 1 + +#define DSD_DISABLED (1 << DSD_DISABLED_MASK) +#define SLNQ_DISABLED (1 << SLNQ_DISABLED_MASK) + +/* Number of input and output Slimbus port */ +enum { + WCD934X_RX0 = 0, + WCD934X_RX1, + WCD934X_RX2, + WCD934X_RX3, + WCD934X_RX4, + WCD934X_RX5, + WCD934X_RX6, + WCD934X_RX7, + WCD934X_RX_MAX, +}; + +enum { + WCD934X_TX0 = 0, + WCD934X_TX1, + WCD934X_TX2, + WCD934X_TX3, + WCD934X_TX4, + WCD934X_TX5, + WCD934X_TX6, + WCD934X_TX7, + WCD934X_TX8, + WCD934X_TX9, + WCD934X_TX10, + WCD934X_TX11, + WCD934X_TX12, + WCD934X_TX13, + WCD934X_TX14, + WCD934X_TX15, + WCD934X_TX_MAX, +}; + +enum { + INTERP_EAR = 0, + INTERP_HPHL, + INTERP_HPHR, + INTERP_LO1, + INTERP_LO2, + INTERP_LO3_NA, /* LO3 not avalible in Tavil*/ + INTERP_LO4_NA, + INTERP_SPKR1, + INTERP_SPKR2, + INTERP_MAX, +}; + +/* + * Selects compander and smart boost settings + * for a given speaker mode + */ +enum { + WCD934X_SPKR_MODE_DEFAULT, + WCD934X_SPKR_MODE_1, /* COMP Gain = 12dB, Smartboost Max = 5.5V */ +}; + +/* + * Rx path gain offsets + */ +enum { + WCD934X_RX_GAIN_OFFSET_M1P5_DB, + WCD934X_RX_GAIN_OFFSET_0_DB, +}; + +/* + * Dai data structure holds the + * dai specific info like rate, + * channel number etc. + */ +struct tavil_codec_dai_data { + u32 rate; + u32 *ch_num; + u32 ch_act; + u32 ch_tot; +}; + +/* + * Structure used to update codec + * register defaults after reset + */ +struct tavil_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + +extern void *tavil_get_afe_config(struct snd_soc_codec *codec, + enum afe_config_type config_type); +extern int tavil_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable); +extern int tavil_set_spkr_mode(struct snd_soc_codec *codec, int mode); +extern int tavil_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset); +extern struct wcd_dsp_cntl *tavil_get_wcd_dsp_cntl(struct device *dev); +extern int wcd934x_get_micb_vout_ctl_val(u32 micb_mv); +extern int tavil_micbias_control(struct snd_soc_codec *codec, + int micb_num, + int req, bool is_dapm); +extern int tavil_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, + int req_volt, + int micb_num); +extern struct wcd934x_mbhc *tavil_soc_get_mbhc(struct snd_soc_codec *codec); +extern int tavil_codec_enable_interp_clk(struct snd_soc_codec *codec, + int event, int intp_idx); +extern struct tavil_dsd_config *tavil_get_dsd_config( + struct snd_soc_codec *codec); +extern int tavil_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_codec *codec); +#endif diff --git a/sound/soc/codecs/wcd9xxx-common-v2.c b/sound/soc/codecs/wcd9xxx-common-v2.c new file mode 100644 index 000000000000..62166579342a --- /dev/null +++ b/sound/soc/codecs/wcd9xxx-common-v2.c @@ -0,0 +1,1367 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "wcd9xxx-common-v2.h" + +#define WCD_USLEEP_RANGE 50 +#define MAX_IMPED_PARAMS 6 + +enum { + DAC_GAIN_0DB = 0, + DAC_GAIN_0P2DB, + DAC_GAIN_0P4DB, + DAC_GAIN_0P6DB, + DAC_GAIN_0P8DB, + DAC_GAIN_M0P2DB, + DAC_GAIN_M0P4DB, + DAC_GAIN_M0P6DB, +}; + +enum { + VREF_FILT_R_0OHM = 0, + VREF_FILT_R_25KOHM, + VREF_FILT_R_50KOHM, + VREF_FILT_R_100KOHM, +}; + +enum { + DELTA_I_0MA, + DELTA_I_10MA, + DELTA_I_20MA, + DELTA_I_30MA, + DELTA_I_40MA, + DELTA_I_50MA, +}; + +struct wcd_imped_val { + u32 imped_val; + u8 index; +}; + +static const struct wcd_reg_mask_val imped_table[][MAX_IMPED_PARAMS] = { + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xf5}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf5}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xf5}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf5}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01}, + }, + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xf7}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf7}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xf7}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf7}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01}, + }, + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xf9}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf9}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x0}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xf9}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf9}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x0}, + }, + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfa}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfa}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xfa}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfa}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01}, + }, + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfb}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfb}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xfb}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfb}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01}, + }, + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfc}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfc}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xfc}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfc}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01}, + }, + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfd}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xfd}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01}, + }, + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfe}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfe}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xfe}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfe}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01}, + }, + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xff}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xff}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xff}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xff}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, +}; + +static const struct wcd_reg_mask_val imped_table_tavil[][MAX_IMPED_PARAMS] = { + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xf2}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf2}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xf2}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf2}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xf4}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf4}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xf4}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf4}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xf7}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf7}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xf7}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf7}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01}, + }, + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xf9}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf9}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xf9}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf9}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfa}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfa}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xfa}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfa}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfb}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfb}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xfb}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfb}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfc}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfc}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xfc}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfc}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfd}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xfd}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfd}, + {WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01}, + {WCD9XXX_CDC_RX2_RX_VOL_CTL, 0xff, 0xfd}, + {WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01}, + }, +}; + +static const struct wcd_imped_val imped_index[] = { + {4, 0}, + {5, 1}, + {6, 2}, + {7, 3}, + {8, 4}, + {9, 5}, + {10, 6}, + {11, 7}, + {12, 8}, + {13, 9}, +}; + +static void (*clsh_state_fp[NUM_CLSH_STATES_V2])(struct snd_soc_codec *, + struct wcd_clsh_cdc_data *, + u8 req_state, bool en, int mode); + +static int get_impedance_index(int imped) +{ + int i = 0; + + if (imped < imped_index[i].imped_val) { + pr_debug("%s, detected impedance is less than 4 Ohm\n", + __func__); + i = 0; + goto ret; + } + if (imped >= imped_index[ARRAY_SIZE(imped_index) - 1].imped_val) { + pr_debug("%s, detected impedance is greater than 12 Ohm\n", + __func__); + i = ARRAY_SIZE(imped_index) - 1; + goto ret; + } + for (i = 0; i < ARRAY_SIZE(imped_index) - 1; i++) { + if (imped >= imped_index[i].imped_val && + imped < imped_index[i + 1].imped_val) + break; + } +ret: + pr_debug("%s: selected impedance index = %d\n", + __func__, imped_index[i].index); + return imped_index[i].index; +} + +/* + * Function: wcd_clsh_imped_config + * Params: codec, imped, reset + * Description: + * This function updates HPHL and HPHR gain settings + * according to the impedance value. + */ +void wcd_clsh_imped_config(struct snd_soc_codec *codec, int imped, bool reset) +{ + int i; + int index = 0; + int table_size; + + static const struct wcd_reg_mask_val + (*imped_table_ptr)[MAX_IMPED_PARAMS]; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + + if (IS_CODEC_TYPE(wcd9xxx, WCD934X)) { + table_size = ARRAY_SIZE(imped_table_tavil); + imped_table_ptr = imped_table_tavil; + } else { + table_size = ARRAY_SIZE(imped_table); + imped_table_ptr = imped_table; + } + + /* reset = 1, which means request is to reset the register values */ + if (reset) { + for (i = 0; i < MAX_IMPED_PARAMS; i++) + snd_soc_update_bits(codec, + imped_table_ptr[index][i].reg, + imped_table_ptr[index][i].mask, 0); + return; + } + index = get_impedance_index(imped); + if (index >= (ARRAY_SIZE(imped_index) - 1)) { + pr_debug("%s, impedance not in range = %d\n", __func__, imped); + return; + } + if (index >= table_size) { + pr_debug("%s, impedance index not in range = %d\n", __func__, + index); + return; + } + for (i = 0; i < MAX_IMPED_PARAMS; i++) + snd_soc_update_bits(codec, + imped_table_ptr[index][i].reg, + imped_table_ptr[index][i].mask, + imped_table_ptr[index][i].val); +} +EXPORT_SYMBOL(wcd_clsh_imped_config); + +static bool is_native_44_1_active(struct snd_soc_codec *codec) +{ + bool native_active = false; + u8 native_clk, rx1_rate, rx2_rate; + + native_clk = snd_soc_read(codec, + WCD9XXX_CDC_CLK_RST_CTRL_MCLK_CONTROL); + rx1_rate = snd_soc_read(codec, WCD9XXX_CDC_RX1_RX_PATH_CTL); + rx2_rate = snd_soc_read(codec, WCD9XXX_CDC_RX2_RX_PATH_CTL); + + dev_dbg(codec->dev, "%s: native_clk %x rx1_rate= %x rx2_rate= %x", + __func__, native_clk, rx1_rate, rx2_rate); + + if ((native_clk & 0x2) && + ((rx1_rate & 0x0F) == 0x9 || (rx2_rate & 0x0F) == 0x9)) + native_active = true; + + return native_active; +} + +static const char *mode_to_str(int mode) +{ + switch (mode) { + case CLS_H_NORMAL: + return "CLS_H_NORMAL"; + case CLS_H_HIFI: + return "CLS_H_HIFI"; + case CLS_H_LOHIFI: + return "CLS_H_LOHIFI"; + case CLS_H_LP: + return "CLS_H_LP"; + case CLS_H_ULP: + return "CLS_H_ULP"; + case CLS_AB: + return "CLS_AB"; + case CLS_AB_HIFI: + return "CLS_AB_HIFI"; + default: + return "CLS_H_INVALID"; + }; +} + +static const char *state_to_str(u8 state, char *buf, size_t buflen) +{ + int i; + int cnt = 0; + /* + * This array of strings should match with enum wcd_clsh_state_bit. + */ + static const char *const states[] = { + "STATE_EAR", + "STATE_HPH_L", + "STATE_HPH_R", + "STATE_LO", + }; + + if (state == WCD_CLSH_STATE_IDLE) { + snprintf(buf, buflen, "[STATE_IDLE]"); + goto done; + } + + buf[0] = '\0'; + for (i = 0; i < ARRAY_SIZE(states); i++) { + if (!(state & (1 << i))) + continue; + cnt = snprintf(buf, buflen - cnt - 1, "%s%s%s", buf, + buf[0] == '\0' ? "[" : "|", + states[i]); + } + if (cnt > 0) + strlcat(buf + cnt, "]", buflen); + +done: + if (buf[0] == '\0') + snprintf(buf, buflen, "[STATE_UNKNOWN]"); + return buf; +} + +static inline void +wcd_enable_clsh_block(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_data *clsh_d, bool enable) +{ + if ((enable && ++clsh_d->clsh_users == 1) || + (!enable && --clsh_d->clsh_users == 0)) + snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLSH_CRC, 0x01, + (u8) enable); + if (clsh_d->clsh_users < 0) + clsh_d->clsh_users = 0; + dev_dbg(codec->dev, "%s: clsh_users %d, enable %d", __func__, + clsh_d->clsh_users, enable); +} + +static inline bool wcd_clsh_enable_status(struct snd_soc_codec *codec) +{ + return snd_soc_read(codec, WCD9XXX_A_CDC_CLSH_CRC) & 0x01; +} + +static inline int wcd_clsh_get_int_mode(struct wcd_clsh_cdc_data *clsh_d, + int clsh_state) +{ + int mode; + + if ((clsh_state != WCD_CLSH_STATE_EAR) && + (clsh_state != WCD_CLSH_STATE_HPHL) && + (clsh_state != WCD_CLSH_STATE_HPHR) && + (clsh_state != WCD_CLSH_STATE_LO)) + mode = CLS_NONE; + else + mode = clsh_d->interpolator_modes[ffs(clsh_state)]; + + return mode; +} + +static inline void wcd_clsh_set_int_mode(struct wcd_clsh_cdc_data *clsh_d, + int clsh_state, int mode) +{ + if ((clsh_state != WCD_CLSH_STATE_EAR) && + (clsh_state != WCD_CLSH_STATE_HPHL) && + (clsh_state != WCD_CLSH_STATE_HPHR) && + (clsh_state != WCD_CLSH_STATE_LO)) + return; + + clsh_d->interpolator_modes[ffs(clsh_state)] = mode; +} + +static inline void wcd_clsh_set_buck_mode(struct snd_soc_codec *codec, + int mode) +{ + if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || + mode == CLS_AB_HIFI || mode == CLS_AB) + snd_soc_update_bits(codec, WCD9XXX_A_ANA_RX_SUPPLIES, + 0x08, 0x08); /* set to HIFI */ + else + snd_soc_update_bits(codec, WCD9XXX_A_ANA_RX_SUPPLIES, + 0x08, 0x00); /* set to default */ +} + +static inline void wcd_clsh_set_flyback_mode(struct snd_soc_codec *codec, + int mode) +{ + if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || + mode == CLS_AB_HIFI || mode == CLS_AB) + snd_soc_update_bits(codec, WCD9XXX_A_ANA_RX_SUPPLIES, + 0x04, 0x04); /* set to HIFI */ + else + snd_soc_update_bits(codec, WCD9XXX_A_ANA_RX_SUPPLIES, + 0x04, 0x00); /* set to Default */ +} + +static inline void wcd_clsh_gm3_boost_disable(struct snd_soc_codec *codec, + int mode) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + + if (!IS_CODEC_TYPE(wcd9xxx, WCD934X)) + return; + + if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || + mode == CLS_AB_HIFI || mode == CLS_AB) { + if (TAVIL_IS_1_0(wcd9xxx)) + snd_soc_update_bits(codec, WCD9XXX_HPH_CNP_WG_CTL, + 0x80, 0x0); /* disable GM3 Boost */ + snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEG_CTRL_4, + 0xF0, 0x80); + } else { + snd_soc_update_bits(codec, WCD9XXX_HPH_CNP_WG_CTL, + 0x80, 0x80); /* set to Default */ + snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEG_CTRL_4, + 0xF0, 0x70); + } +} + + +static inline void wcd_clsh_force_iq_ctl(struct snd_soc_codec *codec, + int mode) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + + if (!IS_CODEC_TYPE(wcd9xxx, WCD934X)) + return; + + if (mode == CLS_H_LOHIFI || mode == CLS_AB) { + snd_soc_update_bits(codec, WCD9XXX_HPH_NEW_INT_PA_MISC2, + 0x20, 0x20); + snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_HPH_LOWPOWER, + 0xF0, 0xC0); + snd_soc_update_bits(codec, WCD9XXX_HPH_PA_CTL1, + 0x0E, 0x02); + } else { + + snd_soc_update_bits(codec, WCD9XXX_HPH_NEW_INT_PA_MISC2, + 0x20, 0x0); + snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_HPH_LOWPOWER, + 0xF0, 0x80); + snd_soc_update_bits(codec, WCD9XXX_HPH_PA_CTL1, + 0x0E, 0x06); + } +} + +static void wcd_clsh_buck_ctrl(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_data *clsh_d, + int mode, + bool enable) +{ + /* enable/disable buck */ + if ((enable && (++clsh_d->buck_users == 1)) || + (!enable && (--clsh_d->buck_users == 0))) + snd_soc_update_bits(codec, WCD9XXX_A_ANA_RX_SUPPLIES, + (1 << 7), (enable << 7)); + dev_dbg(codec->dev, "%s: buck_users %d, enable %d, mode: %s", + __func__, clsh_d->buck_users, enable, mode_to_str(mode)); + /* + * 500us sleep is required after buck enable/disable + * as per HW requirement + */ + usleep_range(500, 500 + WCD_USLEEP_RANGE); +} + +static void wcd_clsh_flyback_ctrl(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_data *clsh_d, + int mode, + bool enable) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_reg_val bulk_reg[2]; + u8 vneg[] = {0x00, 0x40}; + + /* enable/disable flyback */ + if ((enable && (++clsh_d->flyback_users == 1)) || + (!enable && (--clsh_d->flyback_users == 0))) { + snd_soc_update_bits(codec, WCD9XXX_A_ANA_RX_SUPPLIES, + (1 << 6), (enable << 6)); + /* 100usec delay is needed as per HW requirement */ + usleep_range(100, 110); + if (enable && (TASHA_IS_1_1(wcd9xxx))) { + wcd_clsh_set_flyback_mode(codec, CLS_H_HIFI); + snd_soc_update_bits(codec, WCD9XXX_FLYBACK_EN, + 0x60, 0x40); + snd_soc_update_bits(codec, WCD9XXX_FLYBACK_EN, + 0x10, 0x10); + vneg[0] = snd_soc_read(codec, + WCD9XXX_A_ANA_RX_SUPPLIES); + vneg[0] &= ~(0x40); + vneg[1] = vneg[0] | 0x40; + bulk_reg[0].reg = WCD9XXX_A_ANA_RX_SUPPLIES; + bulk_reg[0].buf = &vneg[0]; + bulk_reg[0].bytes = 1; + bulk_reg[1].reg = WCD9XXX_A_ANA_RX_SUPPLIES; + bulk_reg[1].buf = &vneg[1]; + bulk_reg[1].bytes = 1; + /* 500usec delay is needed as per HW requirement */ + usleep_range(500, 510); + wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, 2, + false); + snd_soc_update_bits(codec, WCD9XXX_FLYBACK_EN, + 0x10, 0x00); + wcd_clsh_set_flyback_mode(codec, mode); + } + + } + dev_dbg(codec->dev, "%s: flyback_users %d, enable %d, mode: %s", + __func__, clsh_d->flyback_users, enable, mode_to_str(mode)); + /* + * 500us sleep is required after flyback enable/disable + * as per HW requirement + */ + usleep_range(500, 500 + WCD_USLEEP_RANGE); +} + +static void wcd_clsh_set_gain_path(struct snd_soc_codec *codec, + int mode) +{ + u8 val = 0; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + + if (!TASHA_IS_2_0(wcd9xxx)) + return; + + switch (mode) { + case CLS_H_NORMAL: + case CLS_AB: + val = 0x00; + break; + case CLS_H_HIFI: + val = 0x02; + break; + case CLS_H_LP: + val = 0x01; + break; + default: + return; + }; + snd_soc_update_bits(codec, WCD9XXX_HPH_L_EN, 0xC0, (val << 6)); + snd_soc_update_bits(codec, WCD9XXX_HPH_R_EN, 0xC0, (val << 6)); +} + +static void wcd_clsh_set_hph_mode(struct snd_soc_codec *codec, + int mode) +{ + u8 val = 0; + u8 gain = 0; + u8 res_val = VREF_FILT_R_0OHM; + u8 ipeak = DELTA_I_50MA; + + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + + switch (mode) { + case CLS_H_NORMAL: + res_val = VREF_FILT_R_50KOHM; + val = 0x00; + gain = DAC_GAIN_0DB; + ipeak = DELTA_I_50MA; + break; + case CLS_AB: + val = 0x00; + gain = DAC_GAIN_0DB; + ipeak = DELTA_I_50MA; + break; + case CLS_AB_HIFI: + val = 0x08; + break; + case CLS_H_HIFI: + val = 0x08; + gain = DAC_GAIN_M0P2DB; + ipeak = DELTA_I_50MA; + break; + case CLS_H_LOHIFI: + val = 0x00; + if ((IS_CODEC_TYPE(wcd9xxx, WCD9335)) || + (IS_CODEC_TYPE(wcd9xxx, WCD9326))) { + val = 0x08; + gain = DAC_GAIN_M0P2DB; + ipeak = DELTA_I_50MA; + } + break; + case CLS_H_ULP: + val = 0x0C; + break; + case CLS_H_LP: + val = 0x04; + ipeak = DELTA_I_30MA; + break; + default: + return; + }; + + /* + * For tavil set mode to Lower_power for + * CLS_H_LOHIFI and CLS_AB + */ + if ((IS_CODEC_TYPE(wcd9xxx, WCD934X)) && + (mode == CLS_H_LOHIFI || mode == CLS_AB)) + val = 0x04; + + snd_soc_update_bits(codec, WCD9XXX_A_ANA_HPH, 0x0C, val); + if (TASHA_IS_2_0(wcd9xxx)) { + snd_soc_update_bits(codec, WCD9XXX_CLASSH_CTRL_VCL_2, + 0x30, (res_val << 4)); + if (mode != CLS_H_LP) + snd_soc_update_bits(codec, WCD9XXX_HPH_REFBUFF_UHQA_CTL, + 0x07, gain); + snd_soc_update_bits(codec, WCD9XXX_CLASSH_CTRL_CCL_1, + 0xF0, (ipeak << 4)); + } +} + +static void wcd_clsh_set_flyback_vneg_ctl(struct snd_soc_codec *codec, + bool enable) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + + if (!TASHA_IS_2_0(wcd9xxx)) + return; + + if (enable) { + snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEG_CTRL_1, 0xE0, + 0x00); + snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEGDAC_CTRL_2, + 0xE0, (0x07 << 5)); + } else { + snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEG_CTRL_1, 0xE0, + (0x07 << 5)); + snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEGDAC_CTRL_2, + 0xE0, (0x02 << 5)); + } +} + +static void wcd_clsh_set_flyback_current(struct snd_soc_codec *codec, int mode) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + + if (!TASHA_IS_2_0(wcd9xxx)) + return; + + snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_FLYB_BUFF, 0x0F, 0x0A); + snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_FLYB_BUFF, 0xF0, 0xA0); + /* Sleep needed to avoid click and pop as per HW requirement */ + usleep_range(100, 110); +} + +static void wcd_clsh_set_buck_regulator_mode(struct snd_soc_codec *codec, + int mode) +{ + snd_soc_update_bits(codec, WCD9XXX_A_ANA_RX_SUPPLIES, + 0x02, 0x00); +} + +static void wcd_clsh_state_lo(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (mode != CLS_AB && mode != CLS_AB_HIFI) { + dev_err(codec->dev, "%s: LO cannot be in this mode: %d\n", + __func__, mode); + return; + } + + if (is_enable) { + wcd_clsh_set_buck_regulator_mode(codec, mode); + wcd_clsh_set_flyback_vneg_ctl(codec, true); + wcd_clsh_set_buck_mode(codec, mode); + wcd_clsh_set_flyback_mode(codec, mode); + wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true); + wcd_clsh_set_flyback_current(codec, mode); + wcd_clsh_buck_ctrl(codec, clsh_d, mode, true); + } else { + wcd_clsh_buck_ctrl(codec, clsh_d, mode, false); + wcd_clsh_flyback_ctrl(codec, clsh_d, mode, false); + wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_flyback_vneg_ctl(codec, false); + wcd_clsh_set_buck_regulator_mode(codec, CLS_H_NORMAL); + } +} + +static void wcd_clsh_state_hph_ear(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + int hph_mode = 0; + + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (is_enable) { + if (req_state == WCD_CLSH_STATE_EAR) { + /* If HPH is running in CLS-AB when + * EAR comes, let it continue to run + * in Class-AB, no need to enable Class-H + * for EAR. + */ + if (clsh_d->state & WCD_CLSH_STATE_HPHL) + hph_mode = wcd_clsh_get_int_mode(clsh_d, + WCD_CLSH_STATE_HPHL); + else if (clsh_d->state & WCD_CLSH_STATE_HPHR) + hph_mode = wcd_clsh_get_int_mode(clsh_d, + WCD_CLSH_STATE_HPHR); + else + return; + if (hph_mode != CLS_AB && hph_mode != CLS_AB_HIFI + && !is_native_44_1_active(codec)) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, + 0x40, 0x40); + } + + if (is_native_44_1_active(codec)) { + snd_soc_write(codec, WCD9XXX_CDC_CLSH_HPH_V_PA, 0x39); + snd_soc_update_bits(codec, + WCD9XXX_CDC_RX0_RX_PATH_SEC0, + 0x03, 0x00); + if ((req_state == WCD_CLSH_STATE_HPHL) || + (req_state == WCD_CLSH_STATE_HPHR)) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, + 0x40, 0x00); + } + + if (req_state == WCD_CLSH_STATE_HPHL) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x40); + if (req_state == WCD_CLSH_STATE_HPHR) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x40); + if ((req_state == WCD_CLSH_STATE_HPHL) || + (req_state == WCD_CLSH_STATE_HPHR)) { + wcd_clsh_set_gain_path(codec, mode); + wcd_clsh_set_flyback_mode(codec, mode); + wcd_clsh_set_buck_mode(codec, mode); + } + } else { + if (req_state == WCD_CLSH_STATE_EAR) { + /* + * If EAR goes away, disable EAR Channel Enable + * if HPH running in Class-H otherwise + * and if HPH requested mode is CLS_AB then + * no need to disable EAR channel enable bit. + */ + if (wcd_clsh_enable_status(codec)) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, + 0x40, 0x00); + } + + if (is_native_44_1_active(codec)) { + snd_soc_write(codec, WCD9XXX_CDC_CLSH_HPH_V_PA, 0x1C); + snd_soc_update_bits(codec, + WCD9XXX_CDC_RX0_RX_PATH_SEC0, + 0x03, 0x01); + if (((clsh_d->state & WCD_CLSH_STATE_HPH_ST) + != WCD_CLSH_STATE_HPH_ST) && + ((req_state == WCD_CLSH_STATE_HPHL) || + (req_state == WCD_CLSH_STATE_HPHR))) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, + 0x40, 0x40); + } + + if (req_state == WCD_CLSH_STATE_HPHL) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x00); + if (req_state == WCD_CLSH_STATE_HPHR) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x00); + if ((req_state & WCD_CLSH_STATE_HPH_ST) && + !wcd_clsh_enable_status(codec)) { + /* If Class-H is not enabled when HPH is turned + * off, enable it as EAR is in progress + */ + wcd_enable_clsh_block(codec, clsh_d, true); + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, + 0x40, 0x40); + wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + } + } +} + +static void wcd_clsh_state_ear_lo(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (is_enable) { + /* LO powerup is taken care in PA sequence. + * No need to change to class AB here. + */ + if (req_state == WCD_CLSH_STATE_EAR) { + /* EAR powerup.*/ + if (!wcd_clsh_enable_status(codec)) { + wcd_enable_clsh_block(codec, clsh_d, true); + wcd_clsh_set_buck_mode(codec, mode); + wcd_clsh_set_flyback_mode(codec, mode); + } + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, + 0x40, 0x40); + } + } else { + if (req_state == WCD_CLSH_STATE_EAR) { + /* EAR powerdown.*/ + wcd_enable_clsh_block(codec, clsh_d, false); + wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, + 0x40, 0x00); + } + /* LO powerdown is taken care in PA sequence. + * No need to change to class H here. + */ + } +} + +static void wcd_clsh_state_hph_lo(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + int hph_mode = 0; + + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (is_enable) { + /* + * If requested state is LO, put regulator + * in class-AB or if requested state is HPH, + * which means LO is already enabled, keep + * the regulator config the same at class-AB + * and just set the power modes for flyback + * and buck. + */ + if (req_state == WCD_CLSH_STATE_LO) + wcd_clsh_set_buck_regulator_mode(codec, CLS_AB); + else { + if (!wcd_clsh_enable_status(codec)) { + wcd_enable_clsh_block(codec, clsh_d, true); + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_CLSH_K1_MSB, + 0x0F, 0x00); + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_CLSH_K1_LSB, + 0xFF, 0xC0); + wcd_clsh_set_flyback_mode(codec, mode); + wcd_clsh_set_flyback_vneg_ctl(codec, false); + wcd_clsh_set_buck_mode(codec, mode); + wcd_clsh_set_hph_mode(codec, mode); + wcd_clsh_set_gain_path(codec, mode); + } else { + dev_dbg(codec->dev, "%s:clsh is already enabled\n", + __func__); + } + if (req_state == WCD_CLSH_STATE_HPHL) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x40); + if (req_state == WCD_CLSH_STATE_HPHR) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x40); + } + } else { + if ((req_state == WCD_CLSH_STATE_HPHL) || + (req_state == WCD_CLSH_STATE_HPHR)) { + if (req_state == WCD_CLSH_STATE_HPHL) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x00); + if (req_state == WCD_CLSH_STATE_HPHR) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x00); + /* + * If HPH is powering down first, then disable clsh, + * set the buck/flyback mode to default and keep the + * regulator at Class-AB + */ + if ((clsh_d->state & WCD_CLSH_STATE_HPH_ST) + != WCD_CLSH_STATE_HPH_ST) { + wcd_enable_clsh_block(codec, clsh_d, false); + wcd_clsh_set_flyback_vneg_ctl(codec, true); + wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + } + } else { + /* LO powerdown. + * If HPH mode also is CLS-AB, no need + * to turn-on class-H, otherwise enable + * Class-H configuration. + */ + if (clsh_d->state & WCD_CLSH_STATE_HPHL) + hph_mode = wcd_clsh_get_int_mode(clsh_d, + WCD_CLSH_STATE_HPHL); + else if (clsh_d->state & WCD_CLSH_STATE_HPHR) + hph_mode = wcd_clsh_get_int_mode(clsh_d, + WCD_CLSH_STATE_HPHR); + else + return; + dev_dbg(codec->dev, "%s: hph_mode = %d\n", __func__, + hph_mode); + + if ((hph_mode == CLS_AB) || + (hph_mode == CLS_AB_HIFI) || + (hph_mode == CLS_NONE)) + goto end; + + /* + * If Class-H is already enabled (HPH ON and then + * LO ON), no need to turn on again, just set the + * regulator mode. + */ + if (wcd_clsh_enable_status(codec)) { + wcd_clsh_set_buck_regulator_mode(codec, + hph_mode); + goto end; + } else { + dev_dbg(codec->dev, "%s: clsh is not enabled\n", + __func__); + } + + wcd_enable_clsh_block(codec, clsh_d, true); + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_CLSH_K1_MSB, + 0x0F, 0x00); + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_CLSH_K1_LSB, + 0xFF, 0xC0); + wcd_clsh_set_buck_regulator_mode(codec, + hph_mode); + if (clsh_d->state & WCD_CLSH_STATE_HPHL) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x40); + if (clsh_d->state & WCD_CLSH_STATE_HPHR) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x40); + wcd_clsh_set_hph_mode(codec, hph_mode); + } + } +end: + return; +} + +static void wcd_clsh_state_hph_st(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (mode == CLS_AB || mode == CLS_AB_HIFI) + return; + + if (is_enable) { + if (req_state == WCD_CLSH_STATE_HPHL) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x40); + if (req_state == WCD_CLSH_STATE_HPHR) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x40); + } else { + if (req_state == WCD_CLSH_STATE_HPHL) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x00); + if (req_state == WCD_CLSH_STATE_HPHR) + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x00); + } +} + +static void wcd_clsh_state_hph_r(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (mode == CLS_H_NORMAL) { + dev_err(codec->dev, "%s: Normal mode not applicable for hph_r\n", + __func__); + return; + } + + if (is_enable) { + if (mode != CLS_AB && mode != CLS_AB_HIFI) { + wcd_enable_clsh_block(codec, clsh_d, true); + /* + * These K1 values depend on the Headphone Impedance + * For now it is assumed to be 16 ohm + */ + snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLSH_K1_MSB, + 0x0F, 0x00); + snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLSH_K1_LSB, + 0xFF, 0xC0); + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x40); + } + wcd_clsh_set_buck_regulator_mode(codec, mode); + wcd_clsh_set_flyback_mode(codec, mode); + wcd_clsh_gm3_boost_disable(codec, mode); + wcd_clsh_force_iq_ctl(codec, mode); + wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true); + wcd_clsh_set_flyback_current(codec, mode); + wcd_clsh_set_buck_mode(codec, mode); + wcd_clsh_buck_ctrl(codec, clsh_d, mode, true); + wcd_clsh_set_hph_mode(codec, mode); + wcd_clsh_set_gain_path(codec, mode); + } else { + wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL); + + if (mode != CLS_AB && mode != CLS_AB_HIFI) { + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x00); + wcd_enable_clsh_block(codec, clsh_d, false); + } + /* buck and flyback set to default mode and disable */ + wcd_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_force_iq_ctl(codec, CLS_H_NORMAL); + wcd_clsh_gm3_boost_disable(codec, CLS_H_NORMAL); + wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_buck_regulator_mode(codec, CLS_H_NORMAL); + } +} + +static void wcd_clsh_state_hph_l(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (mode == CLS_H_NORMAL) { + dev_err(codec->dev, "%s: Normal mode not applicable for hph_l\n", + __func__); + return; + } + + if (is_enable) { + if (mode != CLS_AB && mode != CLS_AB_HIFI) { + wcd_enable_clsh_block(codec, clsh_d, true); + /* + * These K1 values depend on the Headphone Impedance + * For now it is assumed to be 16 ohm + */ + snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLSH_K1_MSB, + 0x0F, 0x00); + snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLSH_K1_LSB, + 0xFF, 0xC0); + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x40); + } + wcd_clsh_set_buck_regulator_mode(codec, mode); + wcd_clsh_set_flyback_mode(codec, mode); + wcd_clsh_gm3_boost_disable(codec, mode); + wcd_clsh_force_iq_ctl(codec, mode); + wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true); + wcd_clsh_set_flyback_current(codec, mode); + wcd_clsh_set_buck_mode(codec, mode); + wcd_clsh_buck_ctrl(codec, clsh_d, mode, true); + wcd_clsh_set_hph_mode(codec, mode); + wcd_clsh_set_gain_path(codec, mode); + } else { + wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL); + + if (mode != CLS_AB && mode != CLS_AB_HIFI) { + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x00); + wcd_enable_clsh_block(codec, clsh_d, false); + } + /* set buck and flyback to Default Mode */ + wcd_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_force_iq_ctl(codec, CLS_H_NORMAL); + wcd_clsh_gm3_boost_disable(codec, CLS_H_NORMAL); + wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_buck_regulator_mode(codec, CLS_H_NORMAL); + } +} + +static void wcd_clsh_state_ear(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (mode != CLS_H_NORMAL) { + dev_err(codec->dev, "%s: mode: %s cannot be used for EAR\n", + __func__, mode_to_str(mode)); + return; + } + + if (is_enable) { + wcd_enable_clsh_block(codec, clsh_d, true); + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, + 0x40, 0x40); + wcd_clsh_set_buck_mode(codec, mode); + wcd_clsh_set_flyback_mode(codec, mode); + wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true); + wcd_clsh_set_flyback_current(codec, mode); + wcd_clsh_buck_ctrl(codec, clsh_d, mode, true); + } else { + snd_soc_update_bits(codec, + WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, + 0x40, 0x00); + wcd_enable_clsh_block(codec, clsh_d, false); + wcd_clsh_buck_ctrl(codec, clsh_d, mode, false); + wcd_clsh_flyback_ctrl(codec, clsh_d, mode, false); + wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + } +} + +static void wcd_clsh_state_err(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + char msg[128]; + + dev_err(codec->dev, + "%s Wrong request for class H state machine requested to %s %s", + __func__, is_enable ? "enable" : "disable", + state_to_str(req_state, msg, sizeof(msg))); + WARN_ON(1); +} + +/* + * Function: wcd_clsh_is_state_valid + * Params: state + * Description: + * Provides information on valid states of Class H configuration + */ +static bool wcd_clsh_is_state_valid(u8 state) +{ + switch (state) { + case WCD_CLSH_STATE_IDLE: + case WCD_CLSH_STATE_EAR: + case WCD_CLSH_STATE_HPHL: + case WCD_CLSH_STATE_HPHR: + case WCD_CLSH_STATE_HPH_ST: + case WCD_CLSH_STATE_LO: + case WCD_CLSH_STATE_HPHL_EAR: + case WCD_CLSH_STATE_HPHR_EAR: + case WCD_CLSH_STATE_HPH_ST_EAR: + case WCD_CLSH_STATE_HPHL_LO: + case WCD_CLSH_STATE_HPHR_LO: + case WCD_CLSH_STATE_HPH_ST_LO: + case WCD_CLSH_STATE_EAR_LO: + return true; + default: + return false; + }; +} + +/* + * Function: wcd_clsh_fsm + * Params: codec, cdc_clsh_d, req_state, req_type, clsh_event + * Description: + * This function handles PRE DAC and POST DAC conditions of different devices + * and updates class H configuration of different combination of devices + * based on validity of their states. cdc_clsh_d will contain current + * class h state information + */ +void wcd_clsh_fsm(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_data *cdc_clsh_d, + u8 clsh_event, u8 req_state, + int int_mode) +{ + u8 old_state, new_state; + char msg0[128], msg1[128]; + + switch (clsh_event) { + case WCD_CLSH_EVENT_PRE_DAC: + old_state = cdc_clsh_d->state; + new_state = old_state | req_state; + + if (!wcd_clsh_is_state_valid(new_state)) { + dev_err(codec->dev, + "%s: Class-H not a valid new state: %s\n", + __func__, + state_to_str(new_state, msg0, sizeof(msg0))); + return; + } + if (new_state == old_state) { + dev_err(codec->dev, + "%s: Class-H already in requested state: %s\n", + __func__, + state_to_str(new_state, msg0, sizeof(msg0))); + return; + } + cdc_clsh_d->state = new_state; + wcd_clsh_set_int_mode(cdc_clsh_d, req_state, int_mode); + (*clsh_state_fp[new_state]) (codec, cdc_clsh_d, req_state, + CLSH_REQ_ENABLE, int_mode); + dev_dbg(codec->dev, + "%s: ClassH state transition from %s to %s\n", + __func__, state_to_str(old_state, msg0, sizeof(msg0)), + state_to_str(cdc_clsh_d->state, msg1, sizeof(msg1))); + break; + case WCD_CLSH_EVENT_POST_PA: + old_state = cdc_clsh_d->state; + new_state = old_state & (~req_state); + if (new_state < NUM_CLSH_STATES_V2) { + if (!wcd_clsh_is_state_valid(old_state)) { + dev_err(codec->dev, + "%s:Invalid old state:%s\n", + __func__, + state_to_str(old_state, msg0, + sizeof(msg0))); + return; + } + if (new_state == old_state) { + dev_err(codec->dev, + "%s: Class-H already in requested state: %s\n", + __func__, + state_to_str(new_state, msg0, + sizeof(msg0))); + return; + } + (*clsh_state_fp[old_state]) (codec, cdc_clsh_d, + req_state, CLSH_REQ_DISABLE, + int_mode); + cdc_clsh_d->state = new_state; + wcd_clsh_set_int_mode(cdc_clsh_d, req_state, CLS_NONE); + dev_dbg(codec->dev, "%s: ClassH state transition from %s to %s\n", + __func__, state_to_str(old_state, msg0, + sizeof(msg0)), + state_to_str(cdc_clsh_d->state, msg1, + sizeof(msg1))); + } + break; + }; +} +EXPORT_SYMBOL(wcd_clsh_fsm); + +int wcd_clsh_get_clsh_state(struct wcd_clsh_cdc_data *clsh) +{ + return clsh->state; +} +EXPORT_SYMBOL(wcd_clsh_get_clsh_state); + +void wcd_clsh_init(struct wcd_clsh_cdc_data *clsh) +{ + int i; + + clsh->state = WCD_CLSH_STATE_IDLE; + + for (i = 0; i < NUM_CLSH_STATES_V2; i++) + clsh_state_fp[i] = wcd_clsh_state_err; + + clsh_state_fp[WCD_CLSH_STATE_EAR] = wcd_clsh_state_ear; + clsh_state_fp[WCD_CLSH_STATE_HPHL] = + wcd_clsh_state_hph_l; + clsh_state_fp[WCD_CLSH_STATE_HPHR] = + wcd_clsh_state_hph_r; + clsh_state_fp[WCD_CLSH_STATE_HPH_ST] = + wcd_clsh_state_hph_st; + clsh_state_fp[WCD_CLSH_STATE_LO] = wcd_clsh_state_lo; + clsh_state_fp[WCD_CLSH_STATE_HPHL_EAR] = + wcd_clsh_state_hph_ear; + clsh_state_fp[WCD_CLSH_STATE_HPHR_EAR] = + wcd_clsh_state_hph_ear; + clsh_state_fp[WCD_CLSH_STATE_HPH_ST_EAR] = + wcd_clsh_state_hph_ear; + clsh_state_fp[WCD_CLSH_STATE_HPHL_LO] = wcd_clsh_state_hph_lo; + clsh_state_fp[WCD_CLSH_STATE_HPHR_LO] = wcd_clsh_state_hph_lo; + clsh_state_fp[WCD_CLSH_STATE_HPH_ST_LO] = + wcd_clsh_state_hph_lo; + clsh_state_fp[WCD_CLSH_STATE_EAR_LO] = wcd_clsh_state_ear_lo; + /* Set interpolaotr modes to NONE */ + wcd_clsh_set_int_mode(clsh, WCD_CLSH_STATE_EAR, CLS_NONE); + wcd_clsh_set_int_mode(clsh, WCD_CLSH_STATE_HPHL, CLS_NONE); + wcd_clsh_set_int_mode(clsh, WCD_CLSH_STATE_HPHR, CLS_NONE); + wcd_clsh_set_int_mode(clsh, WCD_CLSH_STATE_LO, CLS_NONE); + clsh->flyback_users = 0; + clsh->buck_users = 0; + clsh->clsh_users = 0; +} +EXPORT_SYMBOL(wcd_clsh_init); + +MODULE_DESCRIPTION("WCD9XXX Common Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/wcd9xxx-common-v2.h b/sound/soc/codecs/wcd9xxx-common-v2.h new file mode 100644 index 000000000000..53c9a84b51ad --- /dev/null +++ b/sound/soc/codecs/wcd9xxx-common-v2.h @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _WCD9XXX_COMMON_V2 + +#define _WCD9XXX_COMMON_V2 + +#define CLSH_REQ_ENABLE true +#define CLSH_REQ_DISABLE false + +#define WCD_CLSH_EVENT_PRE_DAC 0x01 +#define WCD_CLSH_EVENT_POST_PA 0x02 +#define MAX_VBAT_MONITOR_WRITES 17 +/* + * Basic states for Class H state machine. + * represented as a bit mask within a u8 data type + * bit 0: EAR mode + * bit 1: HPH Left mode + * bit 2: HPH Right mode + * bit 3: Lineout mode + */ +#define WCD_CLSH_STATE_IDLE 0x00 +#define WCD_CLSH_STATE_EAR (0x01 << 0) +#define WCD_CLSH_STATE_HPHL (0x01 << 1) +#define WCD_CLSH_STATE_HPHR (0x01 << 2) +#define WCD_CLSH_STATE_LO (0x01 << 3) + +/* + * Though number of CLSH states are 4, max state shoulbe be 5 + * because state array index starts from 1. + */ +#define WCD_CLSH_STATE_MAX 5 +#define NUM_CLSH_STATES_V2 (0x01 << WCD_CLSH_STATE_MAX) + + +/* Derived State: Bits 1 and 2 should be set for Headphone stereo */ +#define WCD_CLSH_STATE_HPH_ST (WCD_CLSH_STATE_HPHL | \ + WCD_CLSH_STATE_HPHR) + +#define WCD_CLSH_STATE_HPHL_LO (WCD_CLSH_STATE_HPHL | \ + WCD_CLSH_STATE_LO) +#define WCD_CLSH_STATE_HPHR_LO (WCD_CLSH_STATE_HPHR | \ + WCD_CLSH_STATE_LO) +#define WCD_CLSH_STATE_HPH_ST_LO (WCD_CLSH_STATE_HPH_ST | \ + WCD_CLSH_STATE_LO) +#define WCD_CLSH_STATE_EAR_LO (WCD_CLSH_STATE_EAR | \ + WCD_CLSH_STATE_LO) +#define WCD_CLSH_STATE_HPHL_EAR (WCD_CLSH_STATE_HPHL | \ + WCD_CLSH_STATE_EAR) +#define WCD_CLSH_STATE_HPHR_EAR (WCD_CLSH_STATE_HPHR | \ + WCD_CLSH_STATE_EAR) +#define WCD_CLSH_STATE_HPH_ST_EAR (WCD_CLSH_STATE_HPH_ST | \ + WCD_CLSH_STATE_EAR) + +enum { + CLS_H_NORMAL = 0, /* Class-H Default */ + CLS_H_HIFI, /* Class-H HiFi */ + CLS_H_LP, /* Class-H Low Power */ + CLS_AB, /* Class-AB Low HIFI*/ + CLS_H_LOHIFI, /* LoHIFI */ + CLS_H_ULP, /* Ultra Low power */ + CLS_AB_HIFI, /* Class-AB */ + CLS_NONE, /* None of the above modes */ +}; + +/* Class H data that the codec driver will maintain */ +struct wcd_clsh_cdc_data { + u8 state; + int flyback_users; + int buck_users; + int clsh_users; + int interpolator_modes[WCD_CLSH_STATE_MAX]; +}; + +struct wcd_mad_audio_header { + u32 reserved[3]; + u32 num_reg_cfg; +}; + +struct wcd_mad_microphone_info { + uint8_t input_microphone; + uint8_t cycle_time; + uint8_t settle_time; + uint8_t padding; +} __packed; + +struct wcd_mad_micbias_info { + uint8_t micbias; + uint8_t k_factor; + uint8_t external_bypass_capacitor; + uint8_t internal_biasing; + uint8_t cfilter; + uint8_t padding[3]; +} __packed; + +struct wcd_mad_rms_audio_beacon_info { + uint8_t rms_omit_samples; + uint8_t rms_comp_time; + uint8_t detection_mechanism; + uint8_t rms_diff_threshold; + uint8_t rms_threshold_lsb; + uint8_t rms_threshold_msb; + uint8_t padding[2]; + uint8_t iir_coefficients[36]; +} __packed; + +struct wcd_mad_rms_ultrasound_info { + uint8_t rms_comp_time; + uint8_t detection_mechanism; + uint8_t rms_diff_threshold; + uint8_t rms_threshold_lsb; + uint8_t rms_threshold_msb; + uint8_t padding[3]; + uint8_t iir_coefficients[36]; +} __packed; + +struct wcd_mad_audio_cal { + uint32_t version; + struct wcd_mad_microphone_info microphone_info; + struct wcd_mad_micbias_info micbias_info; + struct wcd_mad_rms_audio_beacon_info audio_info; + struct wcd_mad_rms_audio_beacon_info beacon_info; + struct wcd_mad_rms_ultrasound_info ultrasound_info; +} __packed; + +struct wcd9xxx_anc_header { + u32 reserved[3]; + u32 num_anc_slots; +}; + +struct vbat_monitor_reg { + u32 size; + u32 writes[MAX_VBAT_MONITOR_WRITES]; +} __packed; + +struct wcd_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + +extern void wcd_clsh_fsm(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_data *cdc_clsh_d, + u8 clsh_event, u8 req_state, + int int_mode); + +extern void wcd_clsh_init(struct wcd_clsh_cdc_data *clsh); +extern int wcd_clsh_get_clsh_state(struct wcd_clsh_cdc_data *clsh); +extern void wcd_clsh_imped_config(struct snd_soc_codec *codec, int imped, + bool reset); + +enum { + RESERVED = 0, + AANC_LPF_FF_FB = 1, + AANC_LPF_COEFF_MSB, + AANC_LPF_COEFF_LSB, + HW_MAD_AUDIO_ENABLE, + HW_MAD_ULTR_ENABLE, + HW_MAD_BEACON_ENABLE, + HW_MAD_AUDIO_SLEEP_TIME, + HW_MAD_ULTR_SLEEP_TIME, + HW_MAD_BEACON_SLEEP_TIME, + HW_MAD_TX_AUDIO_SWITCH_OFF, + HW_MAD_TX_ULTR_SWITCH_OFF, + HW_MAD_TX_BEACON_SWITCH_OFF, + MAD_AUDIO_INT_DEST_SELECT_REG, + MAD_ULT_INT_DEST_SELECT_REG, + MAD_BEACON_INT_DEST_SELECT_REG, + MAD_CLIP_INT_DEST_SELECT_REG, + VBAT_INT_DEST_SELECT_REG, + MAD_AUDIO_INT_MASK_REG, + MAD_ULT_INT_MASK_REG, + MAD_BEACON_INT_MASK_REG, + MAD_CLIP_INT_MASK_REG, + VBAT_INT_MASK_REG, + MAD_AUDIO_INT_STATUS_REG, + MAD_ULT_INT_STATUS_REG, + MAD_BEACON_INT_STATUS_REG, + MAD_CLIP_INT_STATUS_REG, + VBAT_INT_STATUS_REG, + MAD_AUDIO_INT_CLEAR_REG, + MAD_ULT_INT_CLEAR_REG, + MAD_BEACON_INT_CLEAR_REG, + MAD_CLIP_INT_CLEAR_REG, + VBAT_INT_CLEAR_REG, + SB_PGD_PORT_TX_WATERMARK_N, + SB_PGD_PORT_TX_ENABLE_N, + SB_PGD_PORT_RX_WATERMARK_N, + SB_PGD_PORT_RX_ENABLE_N, + SB_PGD_TX_PORTn_MULTI_CHNL_0, + SB_PGD_TX_PORTn_MULTI_CHNL_1, + SB_PGD_RX_PORTn_MULTI_CHNL_0, + SB_PGD_RX_PORTn_MULTI_CHNL_1, + AANC_FF_GAIN_ADAPTIVE, + AANC_FFGAIN_ADAPTIVE_EN, + AANC_GAIN_CONTROL, + SPKR_CLIP_PIPE_BANK_SEL, + SPKR_CLIPDET_VAL0, + SPKR_CLIPDET_VAL1, + SPKR_CLIPDET_VAL2, + SPKR_CLIPDET_VAL3, + SPKR_CLIPDET_VAL4, + SPKR_CLIPDET_VAL5, + SPKR_CLIPDET_VAL6, + SPKR_CLIPDET_VAL7, + VBAT_RELEASE_INT_DEST_SELECT_REG, + VBAT_RELEASE_INT_MASK_REG, + VBAT_RELEASE_INT_STATUS_REG, + VBAT_RELEASE_INT_CLEAR_REG, + MAD2_CLIP_INT_DEST_SELECT_REG, + MAD2_CLIP_INT_MASK_REG, + MAD2_CLIP_INT_STATUS_REG, + MAD2_CLIP_INT_CLEAR_REG, + SPKR2_CLIP_PIPE_BANK_SEL, + SPKR2_CLIPDET_VAL0, + SPKR2_CLIPDET_VAL1, + SPKR2_CLIPDET_VAL2, + SPKR2_CLIPDET_VAL3, + SPKR2_CLIPDET_VAL4, + SPKR2_CLIPDET_VAL5, + SPKR2_CLIPDET_VAL6, + SPKR2_CLIPDET_VAL7, + MAX_CFG_REGISTERS, +}; + +#endif diff --git a/sound/soc/codecs/wcd9xxx-resmgr-v2.c b/sound/soc/codecs/wcd9xxx-resmgr-v2.c new file mode 100644 index 000000000000..feef0a48af79 --- /dev/null +++ b/sound/soc/codecs/wcd9xxx-resmgr-v2.c @@ -0,0 +1,693 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcd9xxx-resmgr-v2.h" + +#define WCD9XXX_RCO_CALIBRATION_DELAY_INC_US 5000 +#define WCD93XX_ANA_BIAS 0x0601 +#define WCD93XX_CDC_CLK_RST_CTRL_MCLK_CONTROL 0x0d41 +#define WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL 0x0d42 + + +static const char *wcd_resmgr_clk_type_to_str(enum wcd_clock_type clk_type) +{ + if (clk_type == WCD_CLK_OFF) + return "WCD_CLK_OFF"; + else if (clk_type == WCD_CLK_RCO) + return "WCD_CLK_RCO"; + else if (clk_type == WCD_CLK_MCLK) + return "WCD_CLK_MCLK"; + else + return "WCD_CLK_UNDEFINED"; +} + +static int wcd_resmgr_codec_reg_update_bits(struct wcd9xxx_resmgr_v2 *resmgr, + u16 reg, u8 mask, u8 val) +{ + bool change; + int ret; + + if (resmgr->codec_type == WCD934X) { + /* Tavil does not support ANA_CLK_TOP register */ + if (reg == WCD9335_ANA_CLK_TOP) + return 0; + } else { + /* Tasha does not support CLK_SYS_MCLK_PRG register */ + if (reg == WCD934X_CLK_SYS_MCLK_PRG) + return 0; + } + if (resmgr->codec) { + ret = snd_soc_update_bits(resmgr->codec, reg, mask, val); + } else if (resmgr->core_res->wcd_core_regmap) { + ret = regmap_update_bits_check( + resmgr->core_res->wcd_core_regmap, + reg, mask, val, &change); + if (!ret) + ret = change; + } else { + pr_err("%s: codec/regmap not defined\n", __func__); + ret = -EINVAL; + } + + return ret; +} + +static int wcd_resmgr_codec_reg_read(struct wcd9xxx_resmgr_v2 *resmgr, + unsigned int reg) +{ + int val, ret; + + if (resmgr->codec_type == WCD934X) { + if (reg == WCD9335_ANA_CLK_TOP) + return 0; + } else { + if (reg == WCD934X_CLK_SYS_MCLK_PRG) + return 0; + } + if (resmgr->codec) { + val = snd_soc_read(resmgr->codec, reg); + } else if (resmgr->core_res->wcd_core_regmap) { + ret = regmap_read(resmgr->core_res->wcd_core_regmap, + reg, &val); + if (ret) + val = ret; + } else { + pr_err("%s: wcd regmap is null\n", __func__); + return -EINVAL; + } + + return val; +} + +/* + * wcd_resmgr_get_clk_type() + * Returns clk type that is currently enabled + */ +int wcd_resmgr_get_clk_type(struct wcd9xxx_resmgr_v2 *resmgr) +{ + if (!resmgr) { + pr_err("%s: resmgr not initialized\n", __func__); + return -EINVAL; + } + return resmgr->clk_type; +} +EXPORT_SYMBOL(wcd_resmgr_get_clk_type); + +static void wcd_resmgr_cdc_specific_get_clk(struct wcd9xxx_resmgr_v2 *resmgr, + int clk_users) +{ + /* Caller of this function should have acquired BG_CLK lock */ + if (clk_users) { + if (resmgr->resmgr_cb && + resmgr->resmgr_cb->cdc_rco_ctrl) { + while (clk_users--) + resmgr->resmgr_cb->cdc_rco_ctrl(resmgr->codec, + true); + } + } +} + +/* + * wcd_resmgr_post_ssr_v2 + * @resmgr: handle to struct wcd9xxx_resmgr_v2 + */ +void wcd_resmgr_post_ssr_v2(struct wcd9xxx_resmgr_v2 *resmgr) +{ + int old_bg_audio_users; + int old_clk_rco_users, old_clk_mclk_users; + + WCD9XXX_V2_BG_CLK_LOCK(resmgr); + + old_bg_audio_users = resmgr->master_bias_users; + old_clk_mclk_users = resmgr->clk_mclk_users; + old_clk_rco_users = resmgr->clk_rco_users; + resmgr->master_bias_users = 0; + resmgr->clk_mclk_users = 0; + resmgr->clk_rco_users = 0; + resmgr->clk_type = WCD_CLK_OFF; + + pr_debug("%s: old_bg_audio_users=%d old_clk_mclk_users=%d old_clk_rco_users=%d\n", + __func__, old_bg_audio_users, + old_clk_mclk_users, old_clk_rco_users); + + if (old_bg_audio_users) { + while (old_bg_audio_users--) + wcd_resmgr_enable_master_bias(resmgr); + } + + if (old_clk_mclk_users) { + while (old_clk_mclk_users--) + wcd_resmgr_enable_clk_block(resmgr, WCD_CLK_MCLK); + } + + if (old_clk_rco_users) + wcd_resmgr_cdc_specific_get_clk(resmgr, old_clk_rco_users); + + WCD9XXX_V2_BG_CLK_UNLOCK(resmgr); +} +EXPORT_SYMBOL(wcd_resmgr_post_ssr_v2); + +/* + * wcd_resmgr_enable_master_bias: enable codec master bias + * @resmgr: handle to struct wcd9xxx_resmgr_v2 + */ +int wcd_resmgr_enable_master_bias(struct wcd9xxx_resmgr_v2 *resmgr) +{ + mutex_lock(&resmgr->master_bias_lock); + + resmgr->master_bias_users++; + if (resmgr->master_bias_users == 1) { + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BIAS, + 0x80, 0x80); + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BIAS, + 0x40, 0x40); + /* + * 1ms delay is required after pre-charge is enabled + * as per HW requirement + */ + usleep_range(1000, 1100); + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BIAS, + 0x40, 0x00); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD93XX_ANA_BIAS, 0x20, 0x00); + } + + pr_debug("%s: current master bias users: %d\n", __func__, + resmgr->master_bias_users); + + mutex_unlock(&resmgr->master_bias_lock); + return 0; +} +EXPORT_SYMBOL(wcd_resmgr_enable_master_bias); + +/* + * wcd_resmgr_disable_master_bias: disable codec master bias + * @resmgr: handle to struct wcd9xxx_resmgr_v2 + */ +int wcd_resmgr_disable_master_bias(struct wcd9xxx_resmgr_v2 *resmgr) +{ + mutex_lock(&resmgr->master_bias_lock); + if (resmgr->master_bias_users <= 0) { + mutex_unlock(&resmgr->master_bias_lock); + return -EINVAL; + } + + resmgr->master_bias_users--; + if (resmgr->master_bias_users == 0) { + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BIAS, + 0x80, 0x00); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD93XX_ANA_BIAS, 0x20, 0x00); + } + mutex_unlock(&resmgr->master_bias_lock); + return 0; +} +EXPORT_SYMBOL(wcd_resmgr_disable_master_bias); + +static int wcd_resmgr_enable_clk_mclk(struct wcd9xxx_resmgr_v2 *resmgr) +{ + /* Enable mclk requires master bias to be enabled first */ + if (resmgr->master_bias_users <= 0) { + pr_err("%s: Cannot turn on MCLK, BG is not enabled\n", + __func__); + return -EINVAL; + } + + if (((resmgr->clk_mclk_users == 0) && + (resmgr->clk_type == WCD_CLK_MCLK)) || + ((resmgr->clk_mclk_users > 0) && + (resmgr->clk_type != WCD_CLK_MCLK))) { + pr_err("%s: Error enabling MCLK, clk_type: %s\n", + __func__, + wcd_resmgr_clk_type_to_str(resmgr->clk_type)); + return -EINVAL; + } + + if (++resmgr->clk_mclk_users == 1) { + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD9335_ANA_CLK_TOP, 0x80, 0x80); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD9335_ANA_CLK_TOP, 0x08, 0x00); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD9335_ANA_CLK_TOP, 0x04, 0x04); + if (resmgr->codec_type == WCD934X) { + /* + * In tavil clock contrl register is changed + * to CLK_SYS_MCLK_PRG + */ + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD934X_CLK_SYS_MCLK_PRG, 0x80, 0x80); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD934X_CLK_SYS_MCLK_PRG, 0x30, 0x10); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD934X_CLK_SYS_MCLK_PRG, 0x02, 0x00); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD934X_CLK_SYS_MCLK_PRG, 0x01, 0x01); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD934X_CLK_SYS_MCLK_PRG, 0x02, 0x00); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD93XX_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD93XX_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD934X_CODEC_RPM_CLK_GATE, 0x03, 0x00); + } else { + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD93XX_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + } + /* + * 10us sleep is required after clock is enabled + * as per HW requirement + */ + usleep_range(10, 15); + } + + resmgr->clk_type = WCD_CLK_MCLK; + + pr_debug("%s: mclk_users: %d, clk_type: %s\n", __func__, + resmgr->clk_mclk_users, + wcd_resmgr_clk_type_to_str(resmgr->clk_type)); + + return 0; +} + +static int wcd_resmgr_disable_clk_mclk(struct wcd9xxx_resmgr_v2 *resmgr) +{ + if (resmgr->clk_mclk_users <= 0) { + pr_err("%s: No mclk users, cannot disable mclk\n", __func__); + return -EINVAL; + } + + if (--resmgr->clk_mclk_users == 0) { + if (resmgr->clk_rco_users > 0) { + /* MCLK to RCO switch */ + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD9335_ANA_CLK_TOP, + 0x08, 0x08); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD934X_CLK_SYS_MCLK_PRG, 0x02, 0x02); + /* Disable clock buffer */ + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD934X_CLK_SYS_MCLK_PRG, 0x80, 0x00); + resmgr->clk_type = WCD_CLK_RCO; + } else { + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD9335_ANA_CLK_TOP, + 0x04, 0x00); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD934X_CLK_SYS_MCLK_PRG, 0x81, 0x00); + resmgr->clk_type = WCD_CLK_OFF; + } + + wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_CLK_TOP, + 0x80, 0x00); + } + + if ((resmgr->codec_type == WCD934X) && + (resmgr->clk_type == WCD_CLK_OFF)) + wcd_resmgr_set_sido_input_src(resmgr, SIDO_SOURCE_INTERNAL); + + pr_debug("%s: mclk_users: %d, clk_type: %s\n", __func__, + resmgr->clk_mclk_users, + wcd_resmgr_clk_type_to_str(resmgr->clk_type)); + + return 0; +} + +static void wcd_resmgr_set_buck_accuracy(struct wcd9xxx_resmgr_v2 *resmgr) +{ + wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL, + 0x02, 0x02); + /* 100us sleep needed after HIGH_ACCURACY_PRE_EN1 */ + usleep_range(100, 110); + wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL, + 0x01, 0x01); + /* 100us sleep needed after HIGH_ACCURACY_PRE_EN2 */ + usleep_range(100, 110); + wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL, + 0x04, 0x04); + /* 100us sleep needed after HIGH_ACCURACY_EN */ + usleep_range(100, 110); +} + +static int wcd_resmgr_enable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr) +{ + bool rco_cal_done = true; + + resmgr->clk_rco_users++; + if ((resmgr->clk_rco_users == 1) && + ((resmgr->clk_type == WCD_CLK_OFF) || + (resmgr->clk_mclk_users == 0))) { + pr_warn("%s: RCO enable requires MCLK to be ON first\n", + __func__); + resmgr->clk_rco_users--; + return -EINVAL; + } else if ((resmgr->clk_rco_users == 1) && + (resmgr->clk_mclk_users)) { + /* RCO Enable */ + if (resmgr->sido_input_src == SIDO_SOURCE_INTERNAL) { + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD9335_ANA_RCO, + 0x80, 0x80); + if (resmgr->codec_type == WCD934X) + wcd_resmgr_set_buck_accuracy(resmgr); + } + + /* + * 20us required after RCO BG is enabled as per HW + * requirements + */ + usleep_range(20, 25); + wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO, + 0x40, 0x40); + /* + * 20us required after RCO is enabled as per HW + * requirements + */ + usleep_range(20, 25); + /* RCO Calibration */ + wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO, + 0x04, 0x04); + if (resmgr->codec_type == WCD934X) + /* + * For wcd934x codec, 20us sleep is needed + * after enabling RCO calibration + */ + usleep_range(20, 25); + + wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO, + 0x04, 0x00); + if (resmgr->codec_type == WCD934X) + /* + * For wcd934x codec, 20us sleep is needed + * after disabling RCO calibration + */ + usleep_range(20, 25); + + /* RCO calibration takes app. 5ms to complete */ + usleep_range(WCD9XXX_RCO_CALIBRATION_DELAY_INC_US, + WCD9XXX_RCO_CALIBRATION_DELAY_INC_US + 100); + if (wcd_resmgr_codec_reg_read(resmgr, WCD9335_ANA_RCO) & 0x02) + rco_cal_done = false; + + WARN((!rco_cal_done), "RCO Calibration failed\n"); + + /* Switch MUX to RCO */ + if (resmgr->clk_mclk_users == 1) { + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD9335_ANA_CLK_TOP, + 0x08, 0x08); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD934X_CLK_SYS_MCLK_PRG, + 0x02, 0x02); + resmgr->clk_type = WCD_CLK_RCO; + } + } + pr_debug("%s: rco clk users: %d, clk_type: %s\n", __func__, + resmgr->clk_rco_users, + wcd_resmgr_clk_type_to_str(resmgr->clk_type)); + + return 0; +} + +static int wcd_resmgr_disable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr) +{ + if ((resmgr->clk_rco_users <= 0) || + (resmgr->clk_type == WCD_CLK_OFF)) { + pr_err("%s: rco_clk_users = %d, clk_type = %d, cannot disable\n", + __func__, resmgr->clk_rco_users, resmgr->clk_type); + return -EINVAL; + } + + resmgr->clk_rco_users--; + + if ((resmgr->clk_rco_users == 0) && + (resmgr->clk_type == WCD_CLK_RCO)) { + wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_CLK_TOP, + 0x08, 0x00); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD934X_CLK_SYS_MCLK_PRG, + 0x02, 0x00); + wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_CLK_TOP, + 0x04, 0x00); + wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO, + 0x40, 0x00); + if (resmgr->sido_input_src == SIDO_SOURCE_INTERNAL) + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD9335_ANA_RCO, + 0x80, 0x00); + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD934X_CLK_SYS_MCLK_PRG, + 0x01, 0x00); + resmgr->clk_type = WCD_CLK_OFF; + } else if ((resmgr->clk_rco_users == 0) && + (resmgr->clk_mclk_users)) { + /* Disable RCO while MCLK is ON */ + wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO, + 0x40, 0x00); + if (resmgr->sido_input_src == SIDO_SOURCE_INTERNAL) + wcd_resmgr_codec_reg_update_bits(resmgr, + WCD9335_ANA_RCO, + 0x80, 0x00); + } + + if ((resmgr->codec_type == WCD934X) && + (resmgr->clk_type == WCD_CLK_OFF)) + wcd_resmgr_set_sido_input_src(resmgr, SIDO_SOURCE_INTERNAL); + + pr_debug("%s: rco clk users: %d, clk_type: %s\n", __func__, + resmgr->clk_rco_users, + wcd_resmgr_clk_type_to_str(resmgr->clk_type)); + + return 0; +} + +/* + * wcd_resmgr_enable_clk_block: enable MCLK or RCO + * @resmgr: handle to struct wcd9xxx_resmgr_v2 + * @type: Clock type to enable + */ +int wcd_resmgr_enable_clk_block(struct wcd9xxx_resmgr_v2 *resmgr, + enum wcd_clock_type type) +{ + int ret; + + switch (type) { + case WCD_CLK_MCLK: + ret = wcd_resmgr_enable_clk_mclk(resmgr); + break; + case WCD_CLK_RCO: + ret = wcd_resmgr_enable_clk_rco(resmgr); + break; + default: + pr_err("%s: Unknown Clock type: %s\n", __func__, + wcd_resmgr_clk_type_to_str(type)); + ret = -EINVAL; + break; + }; + + if (ret) + pr_err("%s: Enable clock %s failed\n", __func__, + wcd_resmgr_clk_type_to_str(type)); + + return ret; +} +EXPORT_SYMBOL(wcd_resmgr_enable_clk_block); + +void wcd_resmgr_set_sido_input_src(struct wcd9xxx_resmgr_v2 *resmgr, + int sido_src) +{ + if (!resmgr) + return; + + if (sido_src == resmgr->sido_input_src) + return; + + if (sido_src == SIDO_SOURCE_INTERNAL) { + wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL, + 0x04, 0x00); + usleep_range(100, 110); + wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL, + 0x03, 0x00); + usleep_range(100, 110); + wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_RCO, + 0x80, 0x00); + usleep_range(100, 110); + resmgr->sido_input_src = SIDO_SOURCE_INTERNAL; + pr_debug("%s: sido input src to internal\n", __func__); + } else if (sido_src == SIDO_SOURCE_RCO_BG) { + wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_RCO, + 0x80, 0x80); + usleep_range(100, 110); + wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL, + 0x02, 0x02); + usleep_range(100, 110); + wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL, + 0x01, 0x01); + usleep_range(100, 110); + wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL, + 0x04, 0x04); + usleep_range(100, 110); + resmgr->sido_input_src = SIDO_SOURCE_RCO_BG; + pr_debug("%s: sido input src to external\n", __func__); + } +} +EXPORT_SYMBOL(wcd_resmgr_set_sido_input_src); + +/* + * wcd_resmgr_set_sido_input_src_locked: + * Set SIDO input in BG_CLK locked context + * + * @resmgr: handle to struct wcd9xxx_resmgr_v2 + * @sido_src: Select the SIDO input source + */ +void wcd_resmgr_set_sido_input_src_locked(struct wcd9xxx_resmgr_v2 *resmgr, + int sido_src) +{ + if (!resmgr) + return; + + WCD9XXX_V2_BG_CLK_LOCK(resmgr); + wcd_resmgr_set_sido_input_src(resmgr, sido_src); + WCD9XXX_V2_BG_CLK_UNLOCK(resmgr); +} +EXPORT_SYMBOL(wcd_resmgr_set_sido_input_src_locked); + +/* + * wcd_resmgr_disable_clk_block: disable MCLK or RCO + * @resmgr: handle to struct wcd9xxx_resmgr_v2 + * @type: Clock type to disable + */ +int wcd_resmgr_disable_clk_block(struct wcd9xxx_resmgr_v2 *resmgr, + enum wcd_clock_type type) +{ + int ret; + + switch (type) { + case WCD_CLK_MCLK: + ret = wcd_resmgr_disable_clk_mclk(resmgr); + break; + case WCD_CLK_RCO: + ret = wcd_resmgr_disable_clk_rco(resmgr); + break; + default: + pr_err("%s: Unknown Clock type: %s\n", __func__, + wcd_resmgr_clk_type_to_str(type)); + ret = -EINVAL; + break; + }; + + if (ret) + pr_err("%s: Disable clock %s failed\n", __func__, + wcd_resmgr_clk_type_to_str(type)); + + return ret; +} +EXPORT_SYMBOL(wcd_resmgr_disable_clk_block); + +/* + * wcd_resmgr_init: initialize wcd resource manager + * @core_res: handle to struct wcd9xxx_core_resource + * + * Early init call without a handle to snd_soc_codec * + */ +struct wcd9xxx_resmgr_v2 *wcd_resmgr_init( + struct wcd9xxx_core_resource *core_res, + struct snd_soc_codec *codec) +{ + struct wcd9xxx_resmgr_v2 *resmgr; + struct wcd9xxx *wcd9xxx; + + resmgr = kzalloc(sizeof(struct wcd9xxx_resmgr_v2), GFP_KERNEL); + if (!resmgr) + return ERR_PTR(-ENOMEM); + + wcd9xxx = container_of(core_res, struct wcd9xxx, core_res); + if (!wcd9xxx) { + kfree(resmgr); + pr_err("%s: Cannot get wcd9xx pointer\n", __func__); + return ERR_PTR(-EINVAL); + } + + mutex_init(&resmgr->codec_bg_clk_lock); + mutex_init(&resmgr->master_bias_lock); + resmgr->master_bias_users = 0; + resmgr->clk_mclk_users = 0; + resmgr->clk_rco_users = 0; + resmgr->master_bias_users = 0; + resmgr->codec = codec; + resmgr->core_res = core_res; + resmgr->sido_input_src = SIDO_SOURCE_INTERNAL; + resmgr->codec_type = wcd9xxx->type; + + return resmgr; +} +EXPORT_SYMBOL(wcd_resmgr_init); + +/* + * wcd_resmgr_remove: Clean-up wcd resource manager + * @resmgr: handle to struct wcd9xxx_resmgr_v2 + */ +void wcd_resmgr_remove(struct wcd9xxx_resmgr_v2 *resmgr) +{ + mutex_destroy(&resmgr->master_bias_lock); + kfree(resmgr); +} +EXPORT_SYMBOL(wcd_resmgr_remove); + +/* + * wcd_resmgr_post_init: post init call to assign codec handle + * @resmgr: handle to struct wcd9xxx_resmgr_v2 created during early init + * @resmgr_cb: codec callback function for resmgr + * @codec: handle to struct snd_soc_codec + */ +int wcd_resmgr_post_init(struct wcd9xxx_resmgr_v2 *resmgr, + const struct wcd_resmgr_cb *resmgr_cb, + struct snd_soc_codec *codec) +{ + if (!resmgr) { + pr_err("%s: resmgr not allocated\n", __func__); + return -EINVAL; + } + + if (!codec) { + pr_err("%s: Codec memory is NULL, nothing to post init\n", + __func__); + return -EINVAL; + } + + resmgr->codec = codec; + resmgr->resmgr_cb = resmgr_cb; + + return 0; +} +EXPORT_SYMBOL(wcd_resmgr_post_init); + +MODULE_DESCRIPTION("wcd9xxx resmgr v2 module"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/wcd9xxx-resmgr-v2.h b/sound/soc/codecs/wcd9xxx-resmgr-v2.h new file mode 100644 index 000000000000..e831ba61e9c2 --- /dev/null +++ b/sound/soc/codecs/wcd9xxx-resmgr-v2.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __WCD9XXX_COMMON_V2_H__ +#define __WCD9XXX_COMMON_V2_H__ + +#include +#include + +enum wcd_clock_type { + WCD_CLK_OFF, + WCD_CLK_RCO, + WCD_CLK_MCLK, +}; + +enum { + SIDO_SOURCE_INTERNAL, + SIDO_SOURCE_RCO_BG, +}; + +struct wcd_resmgr_cb { + int (*cdc_rco_ctrl)(struct snd_soc_codec *, bool); +}; + +struct wcd9xxx_resmgr_v2 { + struct snd_soc_codec *codec; + struct wcd9xxx_core_resource *core_res; + + int master_bias_users; + int clk_mclk_users; + int clk_rco_users; + + struct mutex codec_bg_clk_lock; + struct mutex master_bias_lock; + + enum codec_variant codec_type; + enum wcd_clock_type clk_type; + + const struct wcd_resmgr_cb *resmgr_cb; + int sido_input_src; +}; + +#define WCD9XXX_V2_BG_CLK_LOCK(resmgr) \ +{ \ + struct wcd9xxx_resmgr_v2 *__resmgr = resmgr; \ + pr_debug("%s: Acquiring BG_CLK\n", __func__); \ + mutex_lock(&__resmgr->codec_bg_clk_lock); \ + pr_debug("%s: Acquiring BG_CLK done\n", __func__); \ +} + +#define WCD9XXX_V2_BG_CLK_UNLOCK(resmgr) \ +{ \ + struct wcd9xxx_resmgr_v2 *__resmgr = resmgr; \ + pr_debug("%s: Releasing BG_CLK\n", __func__); \ + mutex_unlock(&__resmgr->codec_bg_clk_lock); \ +} + +#define WCD9XXX_V2_BG_CLK_ASSERT_LOCKED(resmgr) \ +{ \ + WARN_ONCE(!mutex_is_locked(&resmgr->codec_bg_clk_lock), \ + "%s: BG_CLK lock should have acquired\n", __func__); \ +} + +int wcd_resmgr_enable_master_bias(struct wcd9xxx_resmgr_v2 *resmgr); +int wcd_resmgr_disable_master_bias(struct wcd9xxx_resmgr_v2 *resmgr); +struct wcd9xxx_resmgr_v2 *wcd_resmgr_init( + struct wcd9xxx_core_resource *core_res, + struct snd_soc_codec *codec); +void wcd_resmgr_remove(struct wcd9xxx_resmgr_v2 *resmgr); +int wcd_resmgr_post_init(struct wcd9xxx_resmgr_v2 *resmgr, + const struct wcd_resmgr_cb *resmgr_cb, + struct snd_soc_codec *codec); +int wcd_resmgr_enable_clk_block(struct wcd9xxx_resmgr_v2 *resmgr, + enum wcd_clock_type type); +int wcd_resmgr_disable_clk_block(struct wcd9xxx_resmgr_v2 *resmgr, + enum wcd_clock_type type); +int wcd_resmgr_get_clk_type(struct wcd9xxx_resmgr_v2 *resmgr); +void wcd_resmgr_post_ssr_v2(struct wcd9xxx_resmgr_v2 *resmgr); +void wcd_resmgr_set_sido_input_src_locked(struct wcd9xxx_resmgr_v2 *resmgr, + int sido_src); +void wcd_resmgr_set_sido_input_src(struct wcd9xxx_resmgr_v2 *resmgr, + int sido_src); + +#endif diff --git a/sound/soc/codecs/wcd9xxx-soc-init.c b/sound/soc/codecs/wcd9xxx-soc-init.c new file mode 100644 index 000000000000..fa8abb7de5e4 --- /dev/null +++ b/sound/soc/codecs/wcd9xxx-soc-init.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "audio-ext-clk-up.h" + +static int __init wcd9xxx_soc_init(void) +{ + int ret = 0; + + ret = wcd_dsp_mgr_init(); + if (!ret) { + ret = audio_ref_clk_platform_init(); + if (ret) { + pr_err("%s: init extclk fail: %d\n", __func__, ret); + wcd_dsp_mgr_exit(); + } + } else { + pr_err("%s: init dsp mgr fail: %d\n", __func__, ret); + } + + return ret; +} +module_init(wcd9xxx_soc_init); + +static void __exit wcd9xxx_soc_exit(void) +{ + audio_ref_clk_platform_exit(); + wcd_dsp_mgr_exit(); +} +module_exit(wcd9xxx_soc_exit); + +MODULE_DESCRIPTION("WCD9XXX CODEC soc init driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/wcd_cmi_api.h b/sound/soc/codecs/wcd_cmi_api.h new file mode 100644 index 000000000000..39be6417e327 --- /dev/null +++ b/sound/soc/codecs/wcd_cmi_api.h @@ -0,0 +1,43 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __CMI_API__ +#define __CMI_API__ + +enum cmi_api_result { + CMI_API_FAILED = 1, + CMI_API_BUSY, + CMI_API_NO_MEMORY, + CMI_API_NOT_READY, +}; + +enum cmi_api_event { + CMI_API_MSG = 1, + CMI_API_OFFLINE, + CMI_API_ONLINE, + CMI_API_DEINITIALIZED, +}; + +struct cmi_api_notification { + enum cmi_api_event event; + enum cmi_api_result result; + void *message; +}; + +void *cmi_register( + void notification_callback + (const struct cmi_api_notification *parameter), + u32 service); +enum cmi_api_result cmi_deregister(void *reg_handle); +enum cmi_api_result cmi_send_msg(void *message); + +#endif /*__CMI_API__*/ diff --git a/sound/soc/codecs/wcd_cpe_core.c b/sound/soc/codecs/wcd_cpe_core.c new file mode 100644 index 000000000000..f2a20d51d0e2 --- /dev/null +++ b/sound/soc/codecs/wcd_cpe_core.c @@ -0,0 +1,4579 @@ +/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcd_cpe_core.h" +#include "wcd_cpe_services.h" +#include "wcd_cmi_api.h" + +#define CMI_CMD_TIMEOUT (10 * HZ) +#define WCD_CPE_LSM_MAX_SESSIONS 2 +#define WCD_CPE_AFE_MAX_PORTS 4 +#define AFE_SVC_EXPLICIT_PORT_START 1 +#define WCD_CPE_EC_PP_BUF_SIZE 480 /* 5 msec buffer */ + +#define ELF_FLAG_EXECUTE (1 << 0) +#define ELF_FLAG_WRITE (1 << 1) +#define ELF_FLAG_READ (1 << 2) + +#define ELF_FLAG_RW (ELF_FLAG_READ | ELF_FLAG_WRITE) + +#define WCD_CPE_GRAB_LOCK(lock, name) \ +{ \ + pr_debug("%s: %s lock acquire\n", \ + __func__, name); \ + mutex_lock(lock); \ +} + +#define WCD_CPE_REL_LOCK(lock, name) \ +{ \ + pr_debug("%s: %s lock release\n", \ + __func__, name); \ + mutex_unlock(lock); \ +} + +#define WCD_CPE_STATE_MAX_LEN 11 +#define CPE_OFFLINE_WAIT_TIMEOUT (2 * HZ) +#define CPE_READY_WAIT_TIMEOUT (3 * HZ) +#define WCD_CPE_SYSFS_DIR_MAX_LENGTH 32 + +#define CPE_ERR_IRQ_CB(core) \ + (core->cpe_cdc_cb->cpe_err_irq_control) + +/* + * AFE output buffer size is always + * (sample_rate * number of bytes per sample/2*1000) + */ +#define AFE_OUT_BUF_SIZE(bit_width, sample_rate) \ + (((sample_rate) * (bit_width / BITS_PER_BYTE))/(2*1000)) + +enum afe_port_state { + AFE_PORT_STATE_DEINIT = 0, + AFE_PORT_STATE_INIT, + AFE_PORT_STATE_CONFIG, + AFE_PORT_STATE_STARTED, + AFE_PORT_STATE_SUSPENDED, +}; + +struct wcd_cmi_afe_port_data { + u8 port_id; + struct mutex afe_lock; + struct completion afe_cmd_complete; + enum afe_port_state port_state; + u8 cmd_result; + u32 mem_handle; +}; + +struct cpe_lsm_ids { + u32 module_id; + u32 param_id; +}; + +static struct wcd_cpe_core *core_d; +static struct cpe_lsm_session + *lsm_sessions[WCD_CPE_LSM_MAX_SESSIONS + 1]; +struct wcd_cpe_core * (*wcd_get_cpe_core)(struct snd_soc_codec *); +static struct wcd_cmi_afe_port_data afe_ports[WCD_CPE_AFE_MAX_PORTS + 1]; +static void wcd_cpe_svc_event_cb(const struct cpe_svc_notification *param); +static int wcd_cpe_setup_irqs(struct wcd_cpe_core *core); +static void wcd_cpe_cleanup_irqs(struct wcd_cpe_core *core); +static ssize_t cpe_ftm_test_trigger(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos); +static u32 ramdump_enable; +static u32 cpe_ftm_test_status; +static const struct file_operations cpe_ftm_test_trigger_fops = { + .open = simple_open, + .write = cpe_ftm_test_trigger, +}; + +static int wcd_cpe_afe_svc_cmd_mode(void *core_handle, + u8 mode); +struct wcd_cpe_attribute { + struct attribute attr; + ssize_t (*show)(struct wcd_cpe_core *core, char *buf); + ssize_t (*store)(struct wcd_cpe_core *core, const char *buf, + ssize_t count); +}; + +#define WCD_CPE_ATTR(_name, _mode, _show, _store) \ +static struct wcd_cpe_attribute cpe_attr_##_name = { \ + .attr = {.name = __stringify(_name), .mode = _mode}, \ + .show = _show, \ + .store = _store, \ +} + +#define to_wcd_cpe_attr(a) \ + container_of((a), struct wcd_cpe_attribute, attr) + +#define kobj_to_cpe_core(kobj) \ + container_of((kobj), struct wcd_cpe_core, cpe_kobj) + +/* wcd_cpe_lsm_session_active: check if any session is active + * return true if any session is active. + */ +static bool wcd_cpe_lsm_session_active(void) +{ + int index = 1; + bool lsm_active = false; + + /* session starts from index 1 */ + for (; index <= WCD_CPE_LSM_MAX_SESSIONS; index++) { + if (lsm_sessions[index] != NULL) { + lsm_active = true; + break; + } else { + lsm_active = false; + } + } + return lsm_active; +} + +static int wcd_cpe_get_sfr_dump(struct wcd_cpe_core *core) +{ + struct cpe_svc_mem_segment dump_seg; + int rc; + u8 *sfr_dump; + + sfr_dump = kzalloc(core->sfr_buf_size, GFP_KERNEL); + if (!sfr_dump) + goto done; + + dump_seg.type = CPE_SVC_DATA_MEM; + dump_seg.cpe_addr = core->sfr_buf_addr; + dump_seg.size = core->sfr_buf_size; + dump_seg.data = sfr_dump; + dev_dbg(core->dev, + "%s: reading SFR from CPE, size = %zu\n", + __func__, core->sfr_buf_size); + + rc = cpe_svc_ramdump(core->cpe_handle, &dump_seg); + if (rc < 0) { + dev_err(core->dev, + "%s: Failed to read cpe sfr_dump, err = %d\n", + __func__, rc); + goto free_sfr_dump; + } + + dev_info(core->dev, + "%s: cpe_sfr = %s\n", __func__, sfr_dump); + +free_sfr_dump: + kfree(sfr_dump); +done: + /* Even if SFR dump failed, do not return error */ + return 0; +} + +static int wcd_cpe_collect_ramdump(struct wcd_cpe_core *core) +{ + struct cpe_svc_mem_segment dump_seg; + int rc; + + if (!core->cpe_ramdump_dev || !core->cpe_dump_v_addr || + core->hw_info.dram_size == 0) { + dev_err(core->dev, + "%s: Ramdump devices not set up, size = %zu\n", + __func__, core->hw_info.dram_size); + return -EINVAL; + } + + dump_seg.type = CPE_SVC_DATA_MEM; + dump_seg.cpe_addr = core->hw_info.dram_offset; + dump_seg.size = core->hw_info.dram_size; + dump_seg.data = core->cpe_dump_v_addr; + + dev_dbg(core->dev, + "%s: Reading ramdump from CPE\n", + __func__); + + rc = cpe_svc_ramdump(core->cpe_handle, &dump_seg); + if (rc < 0) { + dev_err(core->dev, + "%s: Failed to read CPE ramdump, err = %d\n", + __func__, rc); + return rc; + } + + dev_dbg(core->dev, + "%s: completed reading ramdump from CPE\n", + __func__); + + core->cpe_ramdump_seg.address = (unsigned long) core->cpe_dump_addr; + core->cpe_ramdump_seg.size = core->hw_info.dram_size; + core->cpe_ramdump_seg.v_address = core->cpe_dump_v_addr; + + rc = do_ramdump(core->cpe_ramdump_dev, + &core->cpe_ramdump_seg, 1); + if (rc) + dev_err(core->dev, + "%s: fail to dump cpe ram to device, err = %d\n", + __func__, rc); + return rc; +} + +/* wcd_cpe_is_valid_elf_hdr: check if the ELF header is valid + * @core: handle to wcd_cpe_core + * @fw_size: size of firmware from request_firmware + * @ehdr: the elf header to be checked for + * return true if all checks pass, true if any elf check fails + */ +static bool wcd_cpe_is_valid_elf_hdr(struct wcd_cpe_core *core, size_t fw_size, + const struct elf32_hdr *ehdr) +{ + if (fw_size < sizeof(*ehdr)) { + dev_err(core->dev, "%s:Firmware too small\n", __func__); + goto elf_check_fail; + } + + if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) { + dev_err(core->dev, "%s: Not an ELF file\n", __func__); + goto elf_check_fail; + } + + if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) { + dev_err(core->dev, "%s: Not a executable image\n", __func__); + goto elf_check_fail; + } + + if (ehdr->e_phnum == 0) { + dev_err(core->dev, "%s: no segments to load\n", __func__); + goto elf_check_fail; + } + + if (sizeof(struct elf32_phdr) * ehdr->e_phnum + + sizeof(struct elf32_hdr) > fw_size) { + dev_err(core->dev, "%s: Too small MDT file\n", __func__); + goto elf_check_fail; + } + + return true; + +elf_check_fail: + return false; +} + +/* + * wcd_cpe_load_each_segment: download segment to CPE + * @core: handle to struct wcd_cpe_core + * @file_idx: index of split firmware image file name + * @phdr: program header from metadata + */ +static int wcd_cpe_load_each_segment(struct wcd_cpe_core *core, + int file_idx, const struct elf32_phdr *phdr) +{ + const struct firmware *split_fw; + char split_fname[32]; + int ret = 0; + struct cpe_svc_mem_segment *segment; + + if (!core || !phdr) { + pr_err("%s: Invalid params\n", __func__); + return -EINVAL; + } + + /* file size can be 0 for bss segments */ + if (phdr->p_filesz == 0 || phdr->p_memsz == 0) + return 0; + + segment = kzalloc(sizeof(struct cpe_svc_mem_segment), GFP_KERNEL); + if (!segment) + return -ENOMEM; + + snprintf(split_fname, sizeof(split_fname), "%s.b%02d", + core->fname, file_idx); + + ret = request_firmware(&split_fw, split_fname, core->dev); + if (ret) { + dev_err(core->dev, "firmware %s not found\n", + split_fname); + ret = -EIO; + goto fw_req_fail; + } + + if (phdr->p_flags & ELF_FLAG_EXECUTE) + segment->type = CPE_SVC_INSTRUCTION_MEM; + else if (phdr->p_flags & ELF_FLAG_RW) + segment->type = CPE_SVC_DATA_MEM; + else { + dev_err(core->dev, "%s invalid flags 0x%x\n", + __func__, phdr->p_flags); + goto done; + } + + segment->cpe_addr = phdr->p_paddr; + segment->size = phdr->p_filesz; + segment->data = (u8 *) split_fw->data; + + dev_dbg(core->dev, + "%s: cpe segment type %s read from firmware\n", __func__, + (segment->type == CPE_SVC_INSTRUCTION_MEM) ? + "INSTRUCTION" : "DATA"); + + ret = cpe_svc_download_segment(core->cpe_handle, segment); + if (ret) { + dev_err(core->dev, + "%s: Failed to download %s, error = %d\n", + __func__, split_fname, ret); + goto done; + } + +done: + release_firmware(split_fw); + +fw_req_fail: + kfree(segment); + return ret; +} + +/* + * wcd_cpe_enable_cpe_clks: enable the clocks for CPE + * @core: handle to wcd_cpe_core + * @enable: flag indicating whether to enable/disable cpe clocks + */ +static int wcd_cpe_enable_cpe_clks(struct wcd_cpe_core *core, bool enable) +{ + int ret, ret1; + + if (!core || !core->cpe_cdc_cb || + !core->cpe_cdc_cb->cpe_clk_en) { + pr_err("%s: invalid handle\n", + __func__); + return -EINVAL; + } + + ret = core->cpe_cdc_cb->cdc_clk_en(core->codec, enable); + if (ret) { + dev_err(core->dev, "%s: Failed to enable RCO\n", + __func__); + return ret; + } + + if (!enable && core->cpe_clk_ref > 0) + core->cpe_clk_ref--; + + /* + * CPE clk will be enabled at the first time + * and be disabled at the last time. + */ + if (core->cpe_clk_ref == 0) { + ret = core->cpe_cdc_cb->cpe_clk_en(core->codec, enable); + if (ret) { + dev_err(core->dev, + "%s: cpe_clk_en() failed, err = %d\n", + __func__, ret); + goto cpe_clk_fail; + } + } + + if (enable) + core->cpe_clk_ref++; + + return 0; + +cpe_clk_fail: + /* Release the codec clk if CPE clk enable failed */ + if (enable) { + ret1 = core->cpe_cdc_cb->cdc_clk_en(core->codec, !enable); + if (ret1) + dev_err(core->dev, + "%s: Fail to release codec clk, err = %d\n", + __func__, ret1); + } + + return ret; +} + +/* + * wcd_cpe_bus_vote_max_bw: Function to vote for max bandwidth on codec bus + * @core: handle to core for cpe + * @vote: flag to indicate enable/disable of vote + * + * This function will try to use the codec provided callback to + * vote/unvote for the max bandwidth of the bus that is used by + * the codec for register reads/writes. + */ +static int wcd_cpe_bus_vote_max_bw(struct wcd_cpe_core *core, + bool vote) +{ + if (!core || !core->cpe_cdc_cb) { + pr_err("%s: Invalid handle to %s\n", + __func__, + (!core) ? "core" : "codec callbacks"); + return -EINVAL; + } + + if (core->cpe_cdc_cb->bus_vote_bw) { + dev_dbg(core->dev, "%s: %s cdc bus max bandwidth\n", + __func__, vote ? "Vote" : "Unvote"); + core->cpe_cdc_cb->bus_vote_bw(core->codec, vote); + } + + return 0; +} + +/* + * wcd_cpe_load_fw: Function to load the fw image + * @core: cpe core pointer + * @load_type: indicates whether to load to data section + * or the instruction section + * + * Parse the mdt file to look for program headers, load each + * split file corresponding to the program headers. + */ +static int wcd_cpe_load_fw(struct wcd_cpe_core *core, + unsigned int load_type) +{ + + int ret, phdr_idx; + struct snd_soc_codec *codec = NULL; + struct wcd9xxx *wcd9xxx = NULL; + const struct elf32_hdr *ehdr; + const struct elf32_phdr *phdr; + const struct firmware *fw; + const u8 *elf_ptr; + char mdt_name[64]; + bool img_dload_fail = false; + bool load_segment; + + if (!core || !core->cpe_handle) { + pr_err("%s: Error CPE core %pK\n", __func__, + core); + return -EINVAL; + } + codec = core->codec; + wcd9xxx = dev_get_drvdata(codec->dev->parent); + snprintf(mdt_name, sizeof(mdt_name), "%s.mdt", core->fname); + ret = request_firmware(&fw, mdt_name, core->dev); + if (ret < 0) { + dev_err(core->dev, "firmware %s not found\n", mdt_name); + return ret; + } + + ehdr = (struct elf32_hdr *) fw->data; + if (!wcd_cpe_is_valid_elf_hdr(core, fw->size, ehdr)) { + dev_err(core->dev, "%s: fw mdt %s is invalid\n", + __func__, mdt_name); + ret = -EINVAL; + goto done; + } + + elf_ptr = fw->data + sizeof(*ehdr); + + if (load_type == ELF_FLAG_EXECUTE) { + /* Reset CPE first */ + ret = cpe_svc_reset(core->cpe_handle); + if (ret < 0) { + dev_err(core->dev, + "%s: Failed to reset CPE with error %d\n", + __func__, ret); + goto done; + } + } + + dev_dbg(core->dev, "%s: start image dload, name = %s, load_type = 0x%x\n", + __func__, core->fname, load_type); + + wcd_cpe_bus_vote_max_bw(core, true); + + /* parse every program header and request corresponding firmware */ + for (phdr_idx = 0; phdr_idx < ehdr->e_phnum; phdr_idx++) { + phdr = (struct elf32_phdr *)elf_ptr; + load_segment = false; + + dev_dbg(core->dev, + "index = %d, vaddr = 0x%x, paddr = 0x%x, filesz = 0x%x, memsz = 0x%x, flags = 0x%x\n" + , phdr_idx, phdr->p_vaddr, phdr->p_paddr, + phdr->p_filesz, phdr->p_memsz, phdr->p_flags); + + switch (load_type) { + case ELF_FLAG_EXECUTE: + if (phdr->p_flags & load_type) + load_segment = true; + break; + case ELF_FLAG_RW: + if (!(phdr->p_flags & ELF_FLAG_EXECUTE) && + (phdr->p_flags & load_type)) + load_segment = true; + break; + default: + pr_err("%s: Invalid load_type 0x%x\n", + __func__, load_type); + ret = -EINVAL; + goto rel_bus_vote; + } + + if (load_segment) { + ret = wcd_cpe_load_each_segment(core, + phdr_idx, phdr); + if (ret < 0) { + dev_err(core->dev, + "Failed to load segment %d, aborting img dload\n", + phdr_idx); + img_dload_fail = true; + goto rel_bus_vote; + } + } else { + dev_dbg(core->dev, + "%s: skipped segment with index %d\n", + __func__, phdr_idx); + } + + elf_ptr = elf_ptr + sizeof(*phdr); + } + if (load_type == ELF_FLAG_EXECUTE) + core->ssr_type = WCD_CPE_IMEM_DOWNLOADED; + +rel_bus_vote: + wcd_cpe_bus_vote_max_bw(core, false); + +done: + release_firmware(fw); + return ret; +} + +/* + * wcd_cpe_change_online_state - mark cpe online/offline state + * @core: core session to mark + * @online: whether online of offline + * + */ +static void wcd_cpe_change_online_state(struct wcd_cpe_core *core, + int online) +{ + struct wcd_cpe_ssr_entry *ssr_entry = NULL; + unsigned long ret; + + if (!core) { + pr_err("%s: Invalid core handle\n", + __func__); + return; + } + + ssr_entry = &core->ssr_entry; + WCD_CPE_GRAB_LOCK(&core->ssr_lock, "SSR"); + ssr_entry->offline = !online; + + /* Make sure write to offline state is completed. */ + wmb(); + ret = xchg(&ssr_entry->offline_change, 1); + wake_up_interruptible(&ssr_entry->offline_poll_wait); + WCD_CPE_REL_LOCK(&core->ssr_lock, "SSR"); + pr_debug("%s: change state 0x%x offline_change 0x%x\n" + " core->offline 0x%x, ret = %ld\n", + __func__, online, + ssr_entry->offline_change, + core->ssr_entry.offline, ret); +} + +/* + * wcd_cpe_load_fw_image: work function to load the fw image + * @work: work that is scheduled to perform the image loading + * + * Parse the mdt file to look for program headers, load each + * split file corresponding to the program headers. + */ +static void wcd_cpe_load_fw_image(struct work_struct *work) +{ + struct wcd_cpe_core *core; + int ret = 0; + + core = container_of(work, struct wcd_cpe_core, load_fw_work); + ret = wcd_cpe_load_fw(core, ELF_FLAG_EXECUTE); + if (!ret) + wcd_cpe_change_online_state(core, 1); + else + pr_err("%s: failed to load instruction section, err = %d\n", + __func__, ret); +} + +/* + * wcd_cpe_get_core_handle: get the handle to wcd_cpe_core + * @codec: codec from which this handle is to be obtained + * Codec driver should provide a callback function to obtain + * handle to wcd_cpe_core during initialization of wcd_cpe_core + */ +void *wcd_cpe_get_core_handle( + struct snd_soc_codec *codec) +{ + struct wcd_cpe_core *core = NULL; + + if (!codec) { + pr_err("%s: Invalid codec handle\n", + __func__); + goto done; + } + + if (!wcd_get_cpe_core) { + dev_err(codec->dev, + "%s: codec callback not available\n", + __func__); + goto done; + } + + core = wcd_get_cpe_core(codec); + + if (!core) + dev_err(codec->dev, + "%s: handle to core not available\n", + __func__); +done: + return core; +} +EXPORT_SYMBOL(wcd_cpe_get_core_handle); + +/* + * svass_engine_irq: threaded interrupt handler for svass engine irq + * @irq: interrupt number + * @data: data pointer passed during irq registration + */ +static irqreturn_t svass_engine_irq(int irq, void *data) +{ + struct wcd_cpe_core *core = data; + int ret = 0; + + if (!core) { + pr_err("%s: Invalid data for interrupt handler\n", + __func__); + goto done; + } + + ret = cpe_svc_process_irq(core->cpe_handle, CPE_IRQ_OUTBOX_IRQ); + if (ret < 0) + dev_err(core->dev, + "%s: Error processing irq from cpe_Services\n", + __func__); +done: + return IRQ_HANDLED; +} + +/* + * wcd_cpe_state_read - update read status in procfs + * @entry: snd_info_entry + * @buf: buffer where the read status is updated. + * + */ +static ssize_t wcd_cpe_state_read(struct snd_info_entry *entry, + void *file_private_data, struct file *file, + char __user *buf, size_t count, loff_t pos) +{ + int len = 0; + char buffer[WCD_CPE_STATE_MAX_LEN]; + struct wcd_cpe_core *core = NULL; + struct wcd_cpe_ssr_entry *ssr_entry = NULL; + + core = (struct wcd_cpe_core *) entry->private_data; + if (!core) { + pr_err("%s: CPE core NULL\n", __func__); + return -EINVAL; + } + ssr_entry = &core->ssr_entry; + + /* Make sure read from ssr_entry is completed. */ + rmb(); + dev_dbg(core->dev, + "%s: Offline 0x%x\n", __func__, + ssr_entry->offline); + + WCD_CPE_GRAB_LOCK(&core->ssr_lock, "SSR"); + len = snprintf(buffer, sizeof(buffer), "%s\n", + ssr_entry->offline ? "OFFLINE" : "ONLINE"); + WCD_CPE_REL_LOCK(&core->ssr_lock, "SSR"); + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +/* + * wcd_cpe_state_poll - polls for change state + * @entry: snd_info_entry + * @wait: wait for duration for poll wait + * + */ +static unsigned int wcd_cpe_state_poll(struct snd_info_entry *entry, + void *private_data, struct file *file, + poll_table *wait) +{ + struct wcd_cpe_core *core = NULL; + struct wcd_cpe_ssr_entry *ssr_entry = NULL; + int ret = 0; + + core = (struct wcd_cpe_core *) entry->private_data; + if (!core) { + pr_err("%s: CPE core NULL\n", __func__); + return -EINVAL; + } + + ssr_entry = &core->ssr_entry; + + dev_dbg(core->dev, "%s: CPE Poll wait\n", + __func__); + poll_wait(file, &ssr_entry->offline_poll_wait, wait); + dev_dbg(core->dev, "%s: Wake-up Poll wait\n", + __func__); + WCD_CPE_GRAB_LOCK(&core->ssr_lock, "SSR"); + + if (xchg(&ssr_entry->offline_change, 0)) + ret = POLLIN | POLLPRI | POLLRDNORM; + + WCD_CPE_REL_LOCK(&core->ssr_lock, "SSR"); + + dev_dbg(core->dev, "%s: ret (%d) from poll_wait\n", + __func__, ret); + return ret; +} + +/* + * wcd_cpe_is_online_state - return true if card is online state + * @core: core offline to query + */ +static bool wcd_cpe_is_online_state(void *core_handle) +{ + struct wcd_cpe_core *core = core_handle; + + if (core_handle) { + return !core->ssr_entry.offline; + } else { + pr_err("%s: Core handle NULL\n", __func__); + /* still return 1- offline if core ptr null */ + return false; + } +} + +static struct snd_info_entry_ops wcd_cpe_state_proc_ops = { + .read = wcd_cpe_state_read, + .poll = wcd_cpe_state_poll, +}; + +static int wcd_cpe_check_new_image(struct wcd_cpe_core *core) +{ + int rc = 0; + char temp_img_name[WCD_CPE_IMAGE_FNAME_MAX]; + + if (!strcmp(core->fname, core->dyn_fname) && + core->ssr_type != WCD_CPE_INITIALIZED) { + dev_dbg(core->dev, + "%s: Firmware unchanged, fname = %s, ssr_type 0x%x\n", + __func__, core->fname, core->ssr_type); + goto done; + } + + /* + * Different firmware name requested, + * Re-load the instruction section + */ + strlcpy(temp_img_name, core->fname, + WCD_CPE_IMAGE_FNAME_MAX); + strlcpy(core->fname, core->dyn_fname, + WCD_CPE_IMAGE_FNAME_MAX); + + rc = wcd_cpe_load_fw(core, ELF_FLAG_EXECUTE); + if (rc) { + dev_err(core->dev, + "%s: Failed to dload new image %s, err = %d\n", + __func__, core->fname, rc); + /* If new image download failed, revert back to old image */ + strlcpy(core->fname, temp_img_name, + WCD_CPE_IMAGE_FNAME_MAX); + rc = wcd_cpe_load_fw(core, ELF_FLAG_EXECUTE); + if (rc) + dev_err(core->dev, + "%s: Failed to re-dload image %s, err = %d\n", + __func__, core->fname, rc); + } else { + dev_info(core->dev, "%s: fw changed to %s\n", + __func__, core->fname); + } +done: + return rc; +} + +static int wcd_cpe_enable(struct wcd_cpe_core *core, + bool enable) +{ + int ret = 0; + + if (enable) { + /* Reset CPE first */ + ret = cpe_svc_reset(core->cpe_handle); + if (ret < 0) { + dev_err(core->dev, + "%s: CPE Reset failed, error = %d\n", + __func__, ret); + goto done; + } + + ret = wcd_cpe_setup_irqs(core); + if (ret) { + dev_err(core->dev, + "%s: CPE IRQs setup failed, error = %d\n", + __func__, ret); + goto done; + } + ret = wcd_cpe_check_new_image(core); + if (ret) + goto fail_boot; + + /* Dload data section */ + ret = wcd_cpe_load_fw(core, ELF_FLAG_RW); + if (ret) { + dev_err(core->dev, + "%s: Failed to dload data section, err = %d\n", + __func__, ret); + goto fail_boot; + } + + ret = wcd_cpe_enable_cpe_clks(core, true); + if (ret < 0) { + dev_err(core->dev, + "%s: CPE clk enable failed, err = %d\n", + __func__, ret); + goto fail_boot; + } + + ret = cpe_svc_boot(core->cpe_handle, + core->cpe_debug_mode); + if (ret < 0) { + dev_err(core->dev, + "%s: Failed to boot CPE\n", + __func__); + goto fail_boot; + } + + /* wait for CPE to be online */ + dev_dbg(core->dev, + "%s: waiting for CPE bootup\n", + __func__); + + wait_for_completion(&core->online_compl); + + dev_dbg(core->dev, + "%s: CPE bootup done\n", + __func__); + + core->ssr_type = WCD_CPE_ENABLED; + } else { + if (core->ssr_type == WCD_CPE_BUS_DOWN_EVENT || + core->ssr_type == WCD_CPE_SSR_EVENT) { + /* + * If this disable vote is when + * SSR is in progress, do not disable CPE here, + * instead SSR handler will control CPE. + */ + wcd_cpe_enable_cpe_clks(core, false); + wcd_cpe_cleanup_irqs(core); + goto done; + } + + ret = cpe_svc_shutdown(core->cpe_handle); + if (ret < 0) { + dev_err(core->dev, + "%s: CPE shutdown failed, error %d\n", + __func__, ret); + goto done; + } + + wcd_cpe_enable_cpe_clks(core, false); + wcd_cpe_cleanup_irqs(core); + core->ssr_type = WCD_CPE_IMEM_DOWNLOADED; + } + + return ret; + +fail_boot: + wcd_cpe_cleanup_irqs(core); + +done: + return ret; +} + +/* + * wcd_cpe_boot_ssr: Load the images to CPE after ssr and bootup cpe + * @core: handle to the core + */ +static int wcd_cpe_boot_ssr(struct wcd_cpe_core *core) +{ + int rc = 0; + + if (!core || !core->cpe_handle) { + pr_err("%s: Invalid handle\n", __func__); + rc = -EINVAL; + goto fail; + } + /* Load the instruction section and mark CPE as online */ + rc = wcd_cpe_load_fw(core, ELF_FLAG_EXECUTE); + if (rc) { + dev_err(core->dev, + "%s: Failed to load instruction, err = %d\n", + __func__, rc); + goto fail; + } else { + wcd_cpe_change_online_state(core, 1); + } + +fail: + return rc; +} + +/* + * wcd_cpe_clr_ready_status: + * Clear the value from the ready status for CPE + * @core: handle to the core + * @value: flag/bitmask that is to be cleared + * + * This function should not be invoked with ssr_lock acquired + */ +static void wcd_cpe_clr_ready_status(struct wcd_cpe_core *core, + u8 value) +{ + WCD_CPE_GRAB_LOCK(&core->ssr_lock, "SSR"); + core->ready_status &= ~(value); + dev_dbg(core->dev, + "%s: ready_status = 0x%x\n", + __func__, core->ready_status); + WCD_CPE_REL_LOCK(&core->ssr_lock, "SSR"); +} + +/* + * wcd_cpe_set_and_complete: + * Set the ready status with the provided value and + * flag the completion object if ready status moves + * to ready to download + * @core: handle to the core + * @value: flag/bitmask that is to be set + */ +static void wcd_cpe_set_and_complete(struct wcd_cpe_core *core, + u8 value) +{ + WCD_CPE_GRAB_LOCK(&core->ssr_lock, "SSR"); + core->ready_status |= value; + if ((core->ready_status & WCD_CPE_READY_TO_DLOAD) == + WCD_CPE_READY_TO_DLOAD) { + dev_dbg(core->dev, + "%s: marking ready, status = 0x%x\n", + __func__, core->ready_status); + complete(&core->ready_compl); + } + WCD_CPE_REL_LOCK(&core->ssr_lock, "SSR"); +} + + +/* + * wcd_cpe_ssr_work: work function to handle CPE SSR + * @work: work that is scheduled to perform CPE shutdown + * and restart + */ +static void wcd_cpe_ssr_work(struct work_struct *work) +{ + + int rc = 0; + u32 irq = 0; + struct wcd_cpe_core *core = NULL; + u8 status = 0; + + core = container_of(work, struct wcd_cpe_core, ssr_work); + if (!core) { + pr_err("%s: Core handle NULL\n", __func__); + return; + } + + /* Obtain pm request up in case of suspend mode */ + pm_qos_add_request(&core->pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + PM_QOS_DEFAULT_VALUE); + pm_qos_update_request(&core->pm_qos_req, + msm_cpuidle_get_deep_idle_latency()); + + dev_dbg(core->dev, + "%s: CPE SSR with event %d\n", + __func__, core->ssr_type); + + if (core->ssr_type == WCD_CPE_SSR_EVENT) { + if (CPE_ERR_IRQ_CB(core)) + core->cpe_cdc_cb->cpe_err_irq_control( + core->codec, + CPE_ERR_IRQ_STATUS, + &status); + if (status & core->irq_info.cpe_fatal_irqs) + irq = CPE_IRQ_WDOG_BITE; + } else { + /* If bus is down, cdc reg cannot be read */ + irq = CPE_IRQ_WDOG_BITE; + } + + if (core->cpe_users > 0) { + rc = cpe_svc_process_irq(core->cpe_handle, irq); + if (rc < 0) + /* + * Even if process_irq fails, + * wait for cpe to move to offline state + */ + dev_err(core->dev, + "%s: irq processing failed, error = %d\n", + __func__, rc); + + rc = wait_for_completion_timeout(&core->offline_compl, + CPE_OFFLINE_WAIT_TIMEOUT); + if (!rc) { + dev_err(core->dev, + "%s: wait for cpe offline timed out\n", + __func__); + goto err_ret; + } + if (core->ssr_type != WCD_CPE_BUS_DOWN_EVENT) { + wcd_cpe_get_sfr_dump(core); + + /* + * Ramdump has to be explicitly enabled + * through debugfs and cannot be collected + * when bus is down. + */ + if (ramdump_enable) + wcd_cpe_collect_ramdump(core); + } + } else { + pr_err("%s: no cpe users, mark as offline\n", __func__); + wcd_cpe_change_online_state(core, 0); + wcd_cpe_set_and_complete(core, + WCD_CPE_BLK_READY); + } + + rc = wait_for_completion_timeout(&core->ready_compl, + CPE_READY_WAIT_TIMEOUT); + if (!rc) { + dev_err(core->dev, + "%s: ready to online timed out, status = %u\n", + __func__, core->ready_status); + goto err_ret; + } + + rc = wcd_cpe_boot_ssr(core); + + /* Once image are downloaded make sure all + * error interrupts are cleared + */ + if (CPE_ERR_IRQ_CB(core)) + core->cpe_cdc_cb->cpe_err_irq_control(core->codec, + CPE_ERR_IRQ_CLEAR, NULL); + +err_ret: + /* remove after default pm qos */ + pm_qos_update_request(&core->pm_qos_req, + PM_QOS_DEFAULT_VALUE); + pm_qos_remove_request(&core->pm_qos_req); +} + +/* + * wcd_cpe_ssr_handle: handle SSR events here. + * @core_handle: handle to the cpe core + * @event: indicates ADSP or CDSP SSR. + */ +int wcd_cpe_ssr_event(void *core_handle, + enum wcd_cpe_ssr_state_event event) +{ + struct wcd_cpe_core *core = core_handle; + + if (!core) { + pr_err("%s: Invalid handle to core\n", + __func__); + return -EINVAL; + } + + /* + * If CPE is not even enabled, the SSR event for + * CPE needs to be ignored + */ + if (core->ssr_type == WCD_CPE_INITIALIZED) { + dev_info(core->dev, + "%s: CPE initialized but not enabled, skip CPE ssr\n", + __func__); + return 0; + } + + dev_dbg(core->dev, + "%s: Schedule ssr work, event = %d\n", + __func__, core->ssr_type); + + switch (event) { + case WCD_CPE_BUS_DOWN_EVENT: + /* + * If bus down, then CPE block is also + * treated to be down + */ + wcd_cpe_clr_ready_status(core, WCD_CPE_READY_TO_DLOAD); + core->ssr_type = event; + schedule_work(&core->ssr_work); + break; + + case WCD_CPE_SSR_EVENT: + wcd_cpe_clr_ready_status(core, WCD_CPE_BLK_READY); + core->ssr_type = event; + schedule_work(&core->ssr_work); + break; + + case WCD_CPE_BUS_UP_EVENT: + wcd_cpe_set_and_complete(core, WCD_CPE_BUS_READY); + /* + * In case of bus up event ssr_type will be changed + * to WCD_CPE_ACTIVE once CPE is online + */ + break; + + default: + dev_err(core->dev, + "%s: unhandled SSR event %d\n", + __func__, event); + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL(wcd_cpe_ssr_event); + +/* + * svass_exception_irq: threaded irq handler for sva error interrupts + * @irq: interrupt number + * @data: data pointer passed during irq registration + * + * Once a error interrupt is received, it is not cleared, since + * clearing this interrupt will raise spurious interrupts unless + * CPE is reset. + */ +static irqreturn_t svass_exception_irq(int irq, void *data) +{ + struct wcd_cpe_core *core = data; + u8 status = 0; + + if (!core || !CPE_ERR_IRQ_CB(core)) { + pr_err("%s: Invalid %s\n", + __func__, + (!core) ? "core" : "cdc control"); + return IRQ_HANDLED; + } + + core->cpe_cdc_cb->cpe_err_irq_control(core->codec, + CPE_ERR_IRQ_STATUS, &status); + + while (status != 0) { + if (status & core->irq_info.cpe_fatal_irqs) { + dev_err(core->dev, + "%s: CPE SSR event,err_status = 0x%02x\n", + __func__, status); + wcd_cpe_ssr_event(core, WCD_CPE_SSR_EVENT); + /* + * If fatal interrupt is received, + * trigger SSR and stop processing + * further interrupts + */ + break; + } + /* + * Mask the interrupt that was raised to + * avoid spurious interrupts + */ + core->cpe_cdc_cb->cpe_err_irq_control(core->codec, + CPE_ERR_IRQ_MASK, &status); + + /* Clear only the interrupt that was raised */ + core->cpe_cdc_cb->cpe_err_irq_control(core->codec, + CPE_ERR_IRQ_CLEAR, &status); + dev_err(core->dev, + "%s: err_interrupt status = 0x%x\n", + __func__, status); + + /* Read status for pending interrupts */ + core->cpe_cdc_cb->cpe_err_irq_control(core->codec, + CPE_ERR_IRQ_STATUS, &status); + } + + return IRQ_HANDLED; +} + +/* + * wcd_cpe_cmi_afe_cb: callback called on response to afe commands + * @param: parameter containing the response code, etc + * + * Process the request to the command sent to CPE and wakeup the + * command send wait. + */ +static void wcd_cpe_cmi_afe_cb(const struct cmi_api_notification *param) +{ + struct cmi_hdr *hdr; + struct wcd_cmi_afe_port_data *afe_port_d; + u8 port_id; + + if (!param) { + pr_err("%s: param is null\n", __func__); + return; + } + + if (param->event != CMI_API_MSG) { + pr_err("%s: unhandled event 0x%x\n", + __func__, param->event); + return; + } + + pr_debug("%s: param->result = %d\n", + __func__, param->result); + + hdr = (struct cmi_hdr *) param->message; + + /* + * for AFE cmd response, port id is + * stored at session id field of header + */ + port_id = CMI_HDR_GET_SESSION_ID(hdr); + if (port_id > WCD_CPE_AFE_MAX_PORTS) { + pr_err("%s: invalid port_id %d\n", + __func__, port_id); + return; + } + + afe_port_d = &(afe_ports[port_id]); + + if (hdr->opcode == CPE_CMI_BASIC_RSP_OPCODE) { + + u8 *payload = ((u8 *)param->message) + (sizeof(struct cmi_hdr)); + u8 result = payload[0]; + + afe_port_d->cmd_result = result; + complete(&afe_port_d->afe_cmd_complete); + + } else if (hdr->opcode == CPE_AFE_PORT_CMDRSP_SHARED_MEM_ALLOC) { + + struct cpe_cmdrsp_shmem_alloc *cmdrsp_shmem_alloc = + (struct cpe_cmdrsp_shmem_alloc *) param->message; + + if (cmdrsp_shmem_alloc->addr == 0) { + pr_err("%s: Failed AFE shared mem alloc\n", __func__); + afe_port_d->cmd_result = CMI_SHMEM_ALLOC_FAILED; + } else { + pr_debug("%s AFE shared mem addr = 0x%x\n", + __func__, cmdrsp_shmem_alloc->addr); + afe_port_d->mem_handle = cmdrsp_shmem_alloc->addr; + afe_port_d->cmd_result = 0; + } + complete(&afe_port_d->afe_cmd_complete); + } +} + +/* + * wcd_cpe_initialize_afe_port_data: Initialize all AFE ports + * + * Initialize the data for all the afe ports. Assign the + * afe port state to INIT state. + */ +static void wcd_cpe_initialize_afe_port_data(void) +{ + struct wcd_cmi_afe_port_data *afe_port_d; + int i; + + for (i = 0; i <= WCD_CPE_AFE_MAX_PORTS; i++) { + afe_port_d = &afe_ports[i]; + afe_port_d->port_id = i; + init_completion(&afe_port_d->afe_cmd_complete); + afe_port_d->port_state = AFE_PORT_STATE_INIT; + mutex_init(&afe_port_d->afe_lock); + } +} + +/* + * wcd_cpe_deinitialize_afe_port_data: De-initialize all AFE ports + * + * De-Initialize the data for all the afe ports. Assign the + * afe port state to DEINIT state. + */ +static void wcd_cpe_deinitialize_afe_port_data(void) +{ + struct wcd_cmi_afe_port_data *afe_port_d; + int i; + + for (i = 0; i <= WCD_CPE_AFE_MAX_PORTS; i++) { + afe_port_d = &afe_ports[i]; + afe_port_d->port_state = AFE_PORT_STATE_DEINIT; + mutex_destroy(&afe_port_d->afe_lock); + } +} + +/* + * wcd_cpe_svc_event_cb: callback from cpe services, indicating + * CPE is online or offline. + * @param: parameter / payload for event to be notified + */ +static void wcd_cpe_svc_event_cb(const struct cpe_svc_notification *param) +{ + struct snd_soc_codec *codec; + struct wcd_cpe_core *core; + struct cpe_svc_boot_event *boot_data; + bool active_sessions; + + if (!param) { + pr_err("%s: Invalid event\n", __func__); + return; + } + + codec = param->private_data; + if (!codec) { + pr_err("%s: Invalid handle to codec\n", + __func__); + return; + } + + core = wcd_cpe_get_core_handle(codec); + if (!core) { + pr_err("%s: Invalid handle to core\n", + __func__); + return; + } + + dev_dbg(core->dev, + "%s: event = 0x%x, ssr_type = 0x%x\n", + __func__, param->event, core->ssr_type); + + switch (param->event) { + case CPE_SVC_BOOT: + boot_data = (struct cpe_svc_boot_event *) + param->payload; + core->sfr_buf_addr = boot_data->debug_address; + core->sfr_buf_size = boot_data->debug_buffer_size; + dev_dbg(core->dev, + "%s: CPE booted, sfr_addr = %d, sfr_size = %zu\n", + __func__, core->sfr_buf_addr, + core->sfr_buf_size); + break; + case CPE_SVC_ONLINE: + core->ssr_type = WCD_CPE_ACTIVE; + dev_dbg(core->dev, "%s CPE is now online\n", + __func__); + complete(&core->online_compl); + break; + case CPE_SVC_OFFLINE: + /* + * offline can happen during normal shutdown, + * but we are interested in offline only during + * SSR. + */ + if (core->ssr_type != WCD_CPE_SSR_EVENT && + core->ssr_type != WCD_CPE_BUS_DOWN_EVENT) + break; + + active_sessions = wcd_cpe_lsm_session_active(); + wcd_cpe_change_online_state(core, 0); + complete(&core->offline_compl); + dev_err(core->dev, "%s: CPE is now offline\n", + __func__); + break; + case CPE_SVC_CMI_CLIENTS_DEREG: + + /* + * Only when either CPE SSR is in progress, + * or the bus is down, we need to mark the CPE + * as ready. In all other cases, this event is + * ignored + */ + if (core->ssr_type == WCD_CPE_SSR_EVENT || + core->ssr_type == WCD_CPE_BUS_DOWN_EVENT) + wcd_cpe_set_and_complete(core, + WCD_CPE_BLK_READY); + break; + default: + dev_err(core->dev, + "%s: unhandled notification\n", + __func__); + break; + } +} + +/* + * wcd_cpe_cleanup_irqs: free the irq resources required by cpe + * @core: handle the cpe core + * + * This API will free the IRQs for CPE but does not mask the + * CPE interrupts. If masking is needed, it has to be done + * explicity by caller. + */ +static void wcd_cpe_cleanup_irqs(struct wcd_cpe_core *core) +{ + + struct snd_soc_codec *codec = core->codec; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; + + wcd9xxx_free_irq(core_res, + core->irq_info.cpe_engine_irq, + core); + wcd9xxx_free_irq(core_res, + core->irq_info.cpe_err_irq, + core); + +} + +/* + * wcd_cpe_setup_sva_err_intr: setup the irqs for CPE + * @core: handle to wcd_cpe_core + * All interrupts needed for CPE are acquired. If any + * request_irq fails, then all irqs are free'd + */ +static int wcd_cpe_setup_irqs(struct wcd_cpe_core *core) +{ + int ret; + struct snd_soc_codec *codec = core->codec; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; + + ret = wcd9xxx_request_irq(core_res, + core->irq_info.cpe_engine_irq, + svass_engine_irq, "SVASS_Engine", core); + if (ret) { + dev_err(core->dev, + "%s: Failed to request svass engine irq\n", + __func__); + goto fail_engine_irq; + } + + /* Make sure all error interrupts are cleared */ + if (CPE_ERR_IRQ_CB(core)) + core->cpe_cdc_cb->cpe_err_irq_control( + core->codec, + CPE_ERR_IRQ_CLEAR, + NULL); + + /* Enable required error interrupts */ + if (CPE_ERR_IRQ_CB(core)) + core->cpe_cdc_cb->cpe_err_irq_control( + core->codec, + CPE_ERR_IRQ_UNMASK, + NULL); + + ret = wcd9xxx_request_irq(core_res, + core->irq_info.cpe_err_irq, + svass_exception_irq, "SVASS_Exception", core); + if (ret) { + dev_err(core->dev, + "%s: Failed to request svass err irq\n", + __func__); + goto fail_exception_irq; + } + + return 0; + +fail_exception_irq: + wcd9xxx_free_irq(core_res, + core->irq_info.cpe_engine_irq, core); + +fail_engine_irq: + return ret; +} + +static int wcd_cpe_get_cal_index(int32_t cal_type) +{ + int cal_index = -EINVAL; + + if (cal_type == ULP_AFE_CAL_TYPE) + cal_index = WCD_CPE_LSM_CAL_AFE; + else if (cal_type == ULP_LSM_CAL_TYPE) + cal_index = WCD_CPE_LSM_CAL_LSM; + else if (cal_type == ULP_LSM_TOPOLOGY_ID_CAL_TYPE) + cal_index = WCD_CPE_LSM_CAL_TOPOLOGY_ID; + else + pr_err("%s: invalid cal_type %d\n", + __func__, cal_type); + + return cal_index; +} + +static int wcd_cpe_alloc_cal(int32_t cal_type, size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + + cal_index = wcd_cpe_get_cal_index(cal_type); + if (cal_index < 0) { + pr_err("%s: invalid caltype %d\n", + __func__, cal_type); + return -EINVAL; + } + + ret = cal_utils_alloc_cal(data_size, data, + core_d->cal_data[cal_index], + 0, NULL); + if (ret < 0) + pr_err("%s: cal_utils_alloc_block failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + return ret; +} + +static int wcd_cpe_dealloc_cal(int32_t cal_type, size_t data_size, + void *data) +{ + int ret = 0; + int cal_index; + + cal_index = wcd_cpe_get_cal_index(cal_type); + if (cal_index < 0) { + pr_err("%s: invalid caltype %d\n", + __func__, cal_type); + return -EINVAL; + } + + ret = cal_utils_dealloc_cal(data_size, data, + core_d->cal_data[cal_index]); + if (ret < 0) + pr_err("%s: cal_utils_dealloc_block failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + return ret; +} + +static int wcd_cpe_set_cal(int32_t cal_type, size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + + cal_index = wcd_cpe_get_cal_index(cal_type); + if (cal_index < 0) { + pr_err("%s: invalid caltype %d\n", + __func__, cal_type); + return -EINVAL; + } + + ret = cal_utils_set_cal(data_size, data, + core_d->cal_data[cal_index], + 0, NULL); + if (ret < 0) + pr_err("%s: cal_utils_set_cal failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + return ret; +} + +static int wcd_cpe_cal_init(struct wcd_cpe_core *core) +{ + int ret = 0; + + struct cal_type_info cal_type_info[] = { + {{ULP_AFE_CAL_TYPE, + {wcd_cpe_alloc_cal, wcd_cpe_dealloc_cal, NULL, + wcd_cpe_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{ULP_LSM_CAL_TYPE, + {wcd_cpe_alloc_cal, wcd_cpe_dealloc_cal, NULL, + wcd_cpe_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{ULP_LSM_TOPOLOGY_ID_CAL_TYPE, + {wcd_cpe_alloc_cal, wcd_cpe_dealloc_cal, NULL, + wcd_cpe_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + }; + + ret = cal_utils_create_cal_types(WCD_CPE_LSM_CAL_MAX, + core->cal_data, + cal_type_info); + if (ret < 0) + pr_err("%s: could not create cal type!\n", + __func__); + return ret; +} + +/* + * wcd_cpe_enable: setup the cpe interrupts and schedule + * the work to download image and bootup the CPE. + * core: handle to cpe core structure + */ +static int wcd_cpe_vote(struct wcd_cpe_core *core, + bool enable) +{ + int ret = 0; + + if (!core) { + pr_err("%s: Invalid handle to core\n", + __func__); + ret = -EINVAL; + goto done; + } + + dev_dbg(core->dev, + "%s: enter, enable = %s, cpe_users = %u\n", + __func__, (enable ? "true" : "false"), + core->cpe_users); + + if (enable) { + core->cpe_users++; + if (core->cpe_users == 1) { + ret = wcd_cpe_enable(core, enable); + if (ret) { + dev_err(core->dev, + "%s: CPE enable failed, err = %d\n", + __func__, ret); + goto done; + } + } else { + dev_dbg(core->dev, + "%s: cpe already enabled, users = %u\n", + __func__, core->cpe_users); + goto done; + } + } else { + core->cpe_users--; + if (core->cpe_users == 0) { + ret = wcd_cpe_enable(core, enable); + if (ret) { + dev_err(core->dev, + "%s: CPE disable failed, err = %d\n", + __func__, ret); + goto done; + } + } else { + dev_dbg(core->dev, + "%s: %u valid users on cpe\n", + __func__, core->cpe_users); + goto done; + } + } + + dev_dbg(core->dev, + "%s: leave, enable = %s, cpe_users = %u\n", + __func__, (enable ? "true" : "false"), + core->cpe_users); + +done: + return ret; +} + +static int wcd_cpe_debugfs_init(struct wcd_cpe_core *core) +{ + int rc = 0; + + struct dentry *dir = debugfs_create_dir("wcd_cpe", NULL); + + if (IS_ERR_OR_NULL(dir)) { + dir = NULL; + rc = -ENODEV; + goto err_create_dir; + } + + if (!debugfs_create_u32("ramdump_enable", 0644, + dir, &ramdump_enable)) { + dev_err(core->dev, "%s: Failed to create debugfs node %s\n", + __func__, "ramdump_enable"); + rc = -ENODEV; + goto err_create_entry; + } + + if (!debugfs_create_file("cpe_ftm_test_trigger", 0200, + dir, core, &cpe_ftm_test_trigger_fops)) { + dev_err(core->dev, "%s: Failed to create debugfs node %s\n", + __func__, "cpe_ftm_test_trigger"); + rc = -ENODEV; + goto err_create_entry; + } + + if (!debugfs_create_u32("cpe_ftm_test_status", 0444, + dir, &cpe_ftm_test_status)) { + dev_err(core->dev, "%s: Failed to create debugfs node %s\n", + __func__, "cpe_ftm_test_status"); + rc = -ENODEV; + goto err_create_entry; + } + +err_create_entry: + debugfs_remove(dir); + +err_create_dir: + return rc; +} + +static ssize_t fw_name_show(struct wcd_cpe_core *core, char *buf) +{ + return snprintf(buf, WCD_CPE_IMAGE_FNAME_MAX, "%s", + core->dyn_fname); +} + +static ssize_t fw_name_store(struct wcd_cpe_core *core, + const char *buf, ssize_t count) +{ + int copy_count = count; + const char *pos; + + pos = memchr(buf, '\n', count); + if (pos) + copy_count = pos - buf; + + if (copy_count > (WCD_CPE_IMAGE_FNAME_MAX - 1)) { + dev_err(core->dev, + "%s: Invalid length %d, max allowed %d\n", + __func__, copy_count, WCD_CPE_IMAGE_FNAME_MAX - 1); + return -EINVAL; + } + + strlcpy(core->dyn_fname, buf, copy_count + 1); + + return count; +} + +WCD_CPE_ATTR(fw_name, 0660, fw_name_show, fw_name_store); + +static ssize_t wcd_cpe_sysfs_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct wcd_cpe_attribute *cpe_attr = to_wcd_cpe_attr(attr); + struct wcd_cpe_core *core = kobj_to_cpe_core(kobj); + ssize_t ret = -EINVAL; + + if (core && cpe_attr->show) + ret = cpe_attr->show(core, buf); + + return ret; +} + +static ssize_t wcd_cpe_sysfs_store(struct kobject *kobj, + struct attribute *attr, const char *buf, + size_t count) +{ + struct wcd_cpe_attribute *cpe_attr = to_wcd_cpe_attr(attr); + struct wcd_cpe_core *core = kobj_to_cpe_core(kobj); + ssize_t ret = -EINVAL; + + if (core && cpe_attr->store) + ret = cpe_attr->store(core, buf, count); + + return ret; +} + +static const struct sysfs_ops wcd_cpe_sysfs_ops = { + .show = wcd_cpe_sysfs_show, + .store = wcd_cpe_sysfs_store, +}; + +static struct kobj_type wcd_cpe_ktype = { + .sysfs_ops = &wcd_cpe_sysfs_ops, +}; + +static int wcd_cpe_sysfs_init(struct wcd_cpe_core *core, int id) +{ + char sysfs_dir_name[WCD_CPE_SYSFS_DIR_MAX_LENGTH]; + int rc = 0; + + snprintf(sysfs_dir_name, WCD_CPE_SYSFS_DIR_MAX_LENGTH, + "%s%d", "wcd_cpe", id); + + rc = kobject_init_and_add(&core->cpe_kobj, &wcd_cpe_ktype, + kernel_kobj, + sysfs_dir_name); + if (unlikely(rc)) { + dev_err(core->dev, + "%s: Failed to add kobject %s, err = %d\n", + __func__, sysfs_dir_name, rc); + goto done; + } + + rc = sysfs_create_file(&core->cpe_kobj, &cpe_attr_fw_name.attr); + if (rc) { + dev_err(core->dev, + "%s: Failed to fw_name sysfs entry to %s\n", + __func__, sysfs_dir_name); + goto fail_create_file; + } + + return 0; + +fail_create_file: + kobject_put(&core->cpe_kobj); +done: + return rc; +} + +static ssize_t cpe_ftm_test_trigger(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wcd_cpe_core *core = file->private_data; + int ret = 0; + + /* Enable the clks for cpe */ + ret = wcd_cpe_enable_cpe_clks(core, true); + if (ret < 0) { + dev_err(core->dev, + "%s: CPE clk enable failed, err = %d\n", + __func__, ret); + goto done; + } + + /* Get the CPE_STATUS */ + ret = cpe_svc_ftm_test(core->cpe_handle, &cpe_ftm_test_status); + if (ret < 0) { + dev_err(core->dev, + "%s: CPE FTM test failed, err = %d\n", + __func__, ret); + if (ret == CPE_SVC_BUSY) { + cpe_ftm_test_status = 1; + ret = 0; + } + } + + /* Disable the clks for cpe */ + ret = wcd_cpe_enable_cpe_clks(core, false); + if (ret < 0) { + dev_err(core->dev, + "%s: CPE clk disable failed, err = %d\n", + __func__, ret); + } + +done: + if (ret < 0) + return ret; + else + return count; +} + +static int wcd_cpe_validate_params( + struct snd_soc_codec *codec, + struct wcd_cpe_params *params) +{ + + if (!codec) { + pr_err("%s: Invalid codec\n", __func__); + return -EINVAL; + } + + if (!params) { + dev_err(codec->dev, + "%s: No params supplied for codec %s\n", + __func__, codec->component.name); + return -EINVAL; + } + + if (!params->codec || !params->get_cpe_core || + !params->cdc_cb) { + dev_err(codec->dev, + "%s: Invalid params for codec %s\n", + __func__, codec->component.name); + return -EINVAL; + } + + return 0; +} + +/* + * wcd_cpe_init: Initialize CPE related structures + * @img_fname: filename for firmware image + * @codec: handle to codec requesting for image download + * @params: parameter structure passed from caller + * + * This API will initialize the cpe core but will not + * download the image or boot the cpe core. + */ +struct wcd_cpe_core *wcd_cpe_init(const char *img_fname, + struct snd_soc_codec *codec, + struct wcd_cpe_params *params) +{ + struct wcd_cpe_core *core; + int ret = 0; + struct snd_card *card = NULL; + struct snd_info_entry *entry = NULL; + char proc_name[WCD_CPE_STATE_MAX_LEN]; + const char *cpe_name = "cpe"; + const char *state_name = "_state"; + const struct cpe_svc_hw_cfg *hw_info; + int id = 0; + + if (wcd_cpe_validate_params(codec, params)) + return NULL; + + core = kzalloc(sizeof(struct wcd_cpe_core), GFP_KERNEL); + if (!core) + return NULL; + + snprintf(core->fname, sizeof(core->fname), "%s", img_fname); + strlcpy(core->dyn_fname, core->fname, WCD_CPE_IMAGE_FNAME_MAX); + + wcd_get_cpe_core = params->get_cpe_core; + + core->codec = params->codec; + core->dev = params->codec->dev; + core->cpe_debug_mode = params->dbg_mode; + + core->cdc_info.major_version = params->cdc_major_ver; + core->cdc_info.minor_version = params->cdc_minor_ver; + core->cdc_info.id = params->cdc_id; + + core->cpe_cdc_cb = params->cdc_cb; + + memcpy(&core->irq_info, ¶ms->cdc_irq_info, + sizeof(core->irq_info)); + + INIT_WORK(&core->load_fw_work, wcd_cpe_load_fw_image); + INIT_WORK(&core->ssr_work, wcd_cpe_ssr_work); + init_completion(&core->offline_compl); + init_completion(&core->ready_compl); + init_completion(&core->online_compl); + init_waitqueue_head(&core->ssr_entry.offline_poll_wait); + mutex_init(&core->ssr_lock); + core->cpe_users = 0; + core->cpe_clk_ref = 0; + + /* + * By default, during probe, it is assumed that + * both CPE hardware block and underlying bus to codec + * are ready + */ + core->ready_status = WCD_CPE_READY_TO_DLOAD; + + core->cpe_handle = cpe_svc_initialize(NULL, &core->cdc_info, + params->cpe_svc_params); + if (!core->cpe_handle) { + dev_err(core->dev, + "%s: failed to initialize cpe services\n", + __func__); + goto fail_cpe_initialize; + } + + core->cpe_reg_handle = cpe_svc_register(core->cpe_handle, + wcd_cpe_svc_event_cb, + CPE_SVC_ONLINE | CPE_SVC_OFFLINE | + CPE_SVC_BOOT | + CPE_SVC_CMI_CLIENTS_DEREG, + "codec cpe handler"); + if (!core->cpe_reg_handle) { + dev_err(core->dev, + "%s: failed to register cpe service\n", + __func__); + goto fail_cpe_register; + } + + card = codec->component.card->snd_card; + snprintf(proc_name, (sizeof("cpe") + sizeof("_state") + + sizeof(id) - 2), "%s%d%s", cpe_name, id, state_name); + entry = snd_info_create_card_entry(card, proc_name, + card->proc_root); + if (entry) { + core->ssr_entry.entry = entry; + core->ssr_entry.offline = 1; + entry->size = WCD_CPE_STATE_MAX_LEN; + entry->content = SNDRV_INFO_CONTENT_DATA; + entry->c.ops = &wcd_cpe_state_proc_ops; + entry->private_data = core; + ret = snd_info_register(entry); + if (ret < 0) { + dev_err(core->dev, + "%s: snd_info_register failed (%d)\n", + __func__, ret); + snd_info_free_entry(entry); + entry = NULL; + } + } else { + dev_err(core->dev, + "%s: Failed to create CPE SSR status entry\n", + __func__); + /* + * Even if SSR entry creation fails, continue + * with image download + */ + } + + core_d = core; + ret = wcd_cpe_cal_init(core); + if (ret < 0) { + dev_err(core->dev, + "%s: CPE calibration init failed, err = %d\n", + __func__, ret); + goto fail_cpe_reset; + } + + wcd_cpe_debugfs_init(core); + + wcd_cpe_sysfs_init(core, id); + + hw_info = cpe_svc_get_hw_cfg(core->cpe_handle); + if (!hw_info) { + dev_err(core->dev, + "%s: hw info not available\n", + __func__); + goto schedule_dload_work; + } else { + core->hw_info.dram_offset = hw_info->DRAM_offset; + core->hw_info.dram_size = hw_info->DRAM_size; + core->hw_info.iram_offset = hw_info->IRAM_offset; + core->hw_info.iram_size = hw_info->IRAM_size; + } + + /* Setup the ramdump device and buffer */ + core->cpe_ramdump_dev = create_ramdump_device("cpe", + core->dev); + if (!core->cpe_ramdump_dev) { + dev_err(core->dev, + "%s: Failed to create ramdump device\n", + __func__); + goto schedule_dload_work; + } + + arch_setup_dma_ops(core->dev, 0, 0, NULL, 0); + core->cpe_dump_v_addr = dma_alloc_coherent(core->dev, + core->hw_info.dram_size, + &core->cpe_dump_addr, + GFP_KERNEL); + if (!core->cpe_dump_v_addr) { + dev_err(core->dev, + "%s: Failed to alloc memory for cpe dump, size = %zd\n", + __func__, core->hw_info.dram_size); + goto schedule_dload_work; + } else { + memset(core->cpe_dump_v_addr, 0, core->hw_info.dram_size); + } + +schedule_dload_work: + core->ssr_type = WCD_CPE_INITIALIZED; + schedule_work(&core->load_fw_work); + return core; + +fail_cpe_reset: + cpe_svc_deregister(core->cpe_handle, core->cpe_reg_handle); + +fail_cpe_register: + cpe_svc_deinitialize(core->cpe_handle); + +fail_cpe_initialize: + kfree(core); + return NULL; +} +EXPORT_SYMBOL(wcd_cpe_init); + +/* + * wcd_cpe_cmi_lsm_callback: callback called from cpe services + * to notify command response for lsm + * service + * @param: param containing the response code and status + * + * This callback is registered with cpe services while registering + * the LSM service + */ +static void wcd_cpe_cmi_lsm_callback(const struct cmi_api_notification *param) +{ + struct cmi_hdr *hdr; + struct cpe_lsm_session *lsm_session; + u8 session_id; + + if (!param) { + pr_err("%s: param is null\n", __func__); + return; + } + + if (param->event != CMI_API_MSG) { + pr_err("%s: unhandled event 0x%x\n", __func__, param->event); + return; + } + + hdr = (struct cmi_hdr *) param->message; + session_id = CMI_HDR_GET_SESSION_ID(hdr); + + if (session_id > WCD_CPE_LSM_MAX_SESSIONS) { + pr_err("%s: invalid lsm session id = %d\n", + __func__, session_id); + return; + } + + lsm_session = lsm_sessions[session_id]; + + if (hdr->opcode == CPE_CMI_BASIC_RSP_OPCODE) { + + u8 *payload = ((u8 *)param->message) + (sizeof(struct cmi_hdr)); + u8 result = payload[0]; + + lsm_session->cmd_err_code = result; + complete(&lsm_session->cmd_comp); + + } else if (hdr->opcode == CPE_LSM_SESSION_CMDRSP_SHARED_MEM_ALLOC) { + + struct cpe_cmdrsp_shmem_alloc *cmdrsp_shmem_alloc = + (struct cpe_cmdrsp_shmem_alloc *) param->message; + + if (cmdrsp_shmem_alloc->addr == 0) { + pr_err("%s: Failed LSM shared mem alloc\n", __func__); + lsm_session->cmd_err_code = CMI_SHMEM_ALLOC_FAILED; + + } else { + + pr_debug("%s LSM shared mem addr = 0x%x\n", + __func__, cmdrsp_shmem_alloc->addr); + lsm_session->lsm_mem_handle = cmdrsp_shmem_alloc->addr; + lsm_session->cmd_err_code = 0; + } + + complete(&lsm_session->cmd_comp); + + } else if (hdr->opcode == CPE_LSM_SESSION_EVENT_DETECTION_STATUS_V2) { + + struct cpe_lsm_event_detect_v2 *event_detect_v2 = + (struct cpe_lsm_event_detect_v2 *) param->message; + + if (!lsm_session->priv_d) { + pr_err("%s: private data is not present\n", + __func__); + return; + } + + pr_debug("%s: event payload, status = %u, size = %u\n", + __func__, event_detect_v2->detection_status, + event_detect_v2->size); + + if (lsm_session->event_cb) + lsm_session->event_cb( + lsm_session->priv_d, + event_detect_v2->detection_status, + event_detect_v2->size, + event_detect_v2->payload); + } +} + +/* + * wcd_cpe_cmi_send_lsm_msg: send a message to lsm service + * @core: handle to cpe core + * @session: session on which to send the message + * @message: actual message containing header and payload + * + * Sends message to lsm service for specified session and wait + * for response back on the message. + * should be called after acquiring session specific mutex + */ +static int wcd_cpe_cmi_send_lsm_msg( + struct wcd_cpe_core *core, + struct cpe_lsm_session *session, + void *message) +{ + int ret = 0; + struct cmi_hdr *hdr = message; + + pr_debug("%s: sending message with opcode 0x%x\n", + __func__, hdr->opcode); + + if (unlikely(!wcd_cpe_is_online_state(core))) { + dev_err(core->dev, + "%s: MSG not sent, CPE offline\n", + __func__); + goto done; + } + + if (CMI_HDR_GET_OBM_FLAG(hdr)) + wcd_cpe_bus_vote_max_bw(core, true); + + reinit_completion(&session->cmd_comp); + ret = cmi_send_msg(message); + if (ret) { + pr_err("%s: msg opcode (0x%x) send failed (%d)\n", + __func__, hdr->opcode, ret); + goto rel_bus_vote; + } + + ret = wait_for_completion_timeout(&session->cmd_comp, + CMI_CMD_TIMEOUT); + if (ret > 0) { + pr_debug("%s: command 0x%x, received response 0x%x\n", + __func__, hdr->opcode, session->cmd_err_code); + if (session->cmd_err_code == CMI_SHMEM_ALLOC_FAILED) + session->cmd_err_code = CPE_ENOMEMORY; + if (session->cmd_err_code > 0) + pr_err("%s: CPE returned error[%s]\n", + __func__, cpe_err_get_err_str( + session->cmd_err_code)); + ret = cpe_err_get_lnx_err_code(session->cmd_err_code); + goto rel_bus_vote; + } else { + pr_err("%s: command (0x%x) send timed out\n", + __func__, hdr->opcode); + ret = -ETIMEDOUT; + goto rel_bus_vote; + } + + +rel_bus_vote: + + if (CMI_HDR_GET_OBM_FLAG(hdr)) + wcd_cpe_bus_vote_max_bw(core, false); + +done: + return ret; +} + + +/* + * fill_cmi_header: fill the cmi header with specified values + * + * @hdr: header to be updated with values + * @session_id: session id of the header, + * in case of AFE service it is port_id + * @service_id: afe/lsm, etc + * @version: update the version field in header + * @payload_size: size of the payload following after header + * @opcode: opcode of the message + * @obm_flag: indicates if this header is for obm message + * + */ +static int fill_cmi_header(struct cmi_hdr *hdr, + u8 session_id, u8 service_id, + bool version, u8 payload_size, + u16 opcode, bool obm_flag) +{ + /* sanitize the data */ + if (!IS_VALID_SESSION_ID(session_id) || + !IS_VALID_SERVICE_ID(service_id) || + !IS_VALID_PLD_SIZE(payload_size)) { + pr_err("Invalid header creation request\n"); + return -EINVAL; + } + + CMI_HDR_SET_SESSION(hdr, session_id); + CMI_HDR_SET_SERVICE(hdr, service_id); + if (version) + CMI_HDR_SET_VERSION(hdr, 1); + else + CMI_HDR_SET_VERSION(hdr, 0); + + CMI_HDR_SET_PAYLOAD_SIZE(hdr, payload_size); + + hdr->opcode = opcode; + + if (obm_flag) + CMI_HDR_SET_OBM(hdr, CMI_OBM_FLAG_OUT_BAND); + else + CMI_HDR_SET_OBM(hdr, CMI_OBM_FLAG_IN_BAND); + + return 0; +} + +/* + * fill_lsm_cmd_header_v0_inband: + * Given the header, fill the header with information + * for lsm service, version 0 and inband message + * @hdr: the cmi header to be filled. + * @session_id: ID for the lsm session + * @payload_size: size for cmi message payload + * @opcode: opcode for cmi message + */ +static int fill_lsm_cmd_header_v0_inband(struct cmi_hdr *hdr, + u8 session_id, u8 payload_size, u16 opcode) +{ + return fill_cmi_header(hdr, session_id, + CMI_CPE_LSM_SERVICE_ID, false, + payload_size, opcode, false); +} + +/* + * wcd_cpe_is_valid_lsm_session: + * Check session parameters to identify validity for the sesion + * @core: handle to cpe core + * @session: handle to the lsm session + * @func: invoking function to be printed in error logs + */ +static int wcd_cpe_is_valid_lsm_session(struct wcd_cpe_core *core, + struct cpe_lsm_session *session, + const char *func) +{ + if (unlikely(IS_ERR_OR_NULL(core))) { + pr_err("%s: invalid handle to core\n", + func); + return -EINVAL; + } + + if (unlikely(IS_ERR_OR_NULL(session))) { + dev_err(core->dev, "%s: invalid session\n", + func); + return -EINVAL; + } + + if (session->id > WCD_CPE_LSM_MAX_SESSIONS) { + dev_err(core->dev, "%s: invalid session id (%u)\n", + func, session->id); + return -EINVAL; + } + + dev_dbg(core->dev, "%s: session_id = %u\n", + func, session->id); + return 0; +} + +static int wcd_cpe_cmd_lsm_open_tx_v2( + struct wcd_cpe_core *core, + struct cpe_lsm_session *session) +{ + struct cpe_lsm_cmd_open_tx_v2 cmd_open_tx_v2; + struct cal_block_data *top_cal = NULL; + struct audio_cal_info_lsm_top *lsm_top; + int ret = 0; + + ret = wcd_cpe_is_valid_lsm_session(core, session, + __func__); + if (ret) + return ret; + + if (core->cal_data[WCD_CPE_LSM_CAL_TOPOLOGY_ID] == NULL) { + dev_err(core->dev, + "%s: LSM_TOPOLOGY cal not allocated!\n", + __func__); + return -EINVAL; + } + + mutex_lock(&core->cal_data[WCD_CPE_LSM_CAL_TOPOLOGY_ID]->lock); + top_cal = cal_utils_get_only_cal_block( + core->cal_data[WCD_CPE_LSM_CAL_TOPOLOGY_ID]); + if (!top_cal) { + dev_err(core->dev, + "%s: Failed to get LSM TOPOLOGY cal block\n", + __func__); + ret = -EINVAL; + goto unlock_cal_mutex; + } + + lsm_top = (struct audio_cal_info_lsm_top *) + top_cal->cal_info; + + if (!lsm_top) { + dev_err(core->dev, + "%s: cal_info for LSM_TOPOLOGY not found\n", + __func__); + ret = -EINVAL; + goto unlock_cal_mutex; + } + + dev_dbg(core->dev, + "%s: topology_id = 0x%x, acdb_id = 0x%x, app_type = 0x%x\n", + __func__, lsm_top->topology, lsm_top->acdb_id, + lsm_top->app_type); + + if (lsm_top->topology == 0) { + dev_err(core->dev, + "%s: topology id not sent for app_type 0x%x\n", + __func__, lsm_top->app_type); + ret = -EINVAL; + goto unlock_cal_mutex; + } + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + + memset(&cmd_open_tx_v2, 0, sizeof(struct cpe_lsm_cmd_open_tx_v2)); + if (fill_lsm_cmd_header_v0_inband(&cmd_open_tx_v2.hdr, + session->id, OPEN_V2_CMD_PAYLOAD_SIZE, + CPE_LSM_SESSION_CMD_OPEN_TX_V2)) { + ret = -EINVAL; + goto end_ret; + } + + cmd_open_tx_v2.topology_id = lsm_top->topology; + ret = wcd_cpe_cmi_send_lsm_msg(core, session, &cmd_open_tx_v2); + if (ret) + dev_err(core->dev, + "%s: failed to send open_tx_v2 cmd, err = %d\n", + __func__, ret); + else + session->is_topology_used = true; +end_ret: + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); + +unlock_cal_mutex: + mutex_unlock(&core->cal_data[WCD_CPE_LSM_CAL_TOPOLOGY_ID]->lock); + return ret; +} + +/* + * wcd_cpe_cmd_lsm_open_tx: compose and send lsm open command + * @core_handle: handle to cpe core + * @session: session for which the command needs to be sent + * @app_id: application id part of the command + * @sample_rate: sample rate for this session + */ +static int wcd_cpe_cmd_lsm_open_tx(void *core_handle, + struct cpe_lsm_session *session, + u16 app_id, u16 sample_rate) +{ + struct cpe_lsm_cmd_open_tx cmd_open_tx; + struct wcd_cpe_core *core = core_handle; + int ret = 0; + + ret = wcd_cpe_is_valid_lsm_session(core, session, + __func__); + if (ret) + return ret; + + /* Try to open with topology first */ + ret = wcd_cpe_cmd_lsm_open_tx_v2(core, session); + if (!ret) + goto done; + + dev_dbg(core->dev, "%s: Try open_tx without topology\n", + __func__); + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + + memset(&cmd_open_tx, 0, sizeof(struct cpe_lsm_cmd_open_tx)); + if (fill_lsm_cmd_header_v0_inband(&cmd_open_tx.hdr, + session->id, OPEN_CMD_PAYLOAD_SIZE, + CPE_LSM_SESSION_CMD_OPEN_TX)) { + ret = -EINVAL; + goto end_ret; + } + + cmd_open_tx.app_id = app_id; + cmd_open_tx.sampling_rate = sample_rate; + + ret = wcd_cpe_cmi_send_lsm_msg(core, session, &cmd_open_tx); + if (ret) + dev_err(core->dev, + "%s: failed to send open_tx cmd, err = %d\n", + __func__, ret); +end_ret: + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); +done: + return ret; +} + +/* + * wcd_cpe_cmd_close_tx: compose and send lsm close command + * @core_handle: handle to cpe core + * @session: session for which the command needs to be sent + */ +static int wcd_cpe_cmd_lsm_close_tx(void *core_handle, + struct cpe_lsm_session *session) +{ + struct cmi_hdr cmd_close_tx; + struct wcd_cpe_core *core = core_handle; + int ret = 0; + + ret = wcd_cpe_is_valid_lsm_session(core, session, + __func__); + if (ret) + return ret; + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + + memset(&cmd_close_tx, 0, sizeof(cmd_close_tx)); + if (fill_lsm_cmd_header_v0_inband(&cmd_close_tx, session->id, + 0, CPE_LSM_SESSION_CMD_CLOSE_TX)) { + ret = -EINVAL; + goto end_ret; + } + + ret = wcd_cpe_cmi_send_lsm_msg(core, session, &cmd_close_tx); + if (ret) + dev_err(core->dev, + "%s: lsm close_tx cmd failed, err = %d\n", + __func__, ret); + else + session->is_topology_used = false; +end_ret: + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); + return ret; +} + +/* + * wcd_cpe_cmd_shmem_alloc: compose and send lsm shared + * memory allocation command + * @core_handle: handle to cpe core + * @session: session for which the command needs to be sent + * @size: size of memory to be allocated + */ +static int wcd_cpe_cmd_lsm_shmem_alloc(void *core_handle, + struct cpe_lsm_session *session, + u32 size) +{ + struct cpe_cmd_shmem_alloc cmd_shmem_alloc; + struct wcd_cpe_core *core = core_handle; + int ret = 0; + + ret = wcd_cpe_is_valid_lsm_session(core, session, + __func__); + if (ret) + return ret; + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + + memset(&cmd_shmem_alloc, 0, sizeof(cmd_shmem_alloc)); + if (fill_lsm_cmd_header_v0_inband(&cmd_shmem_alloc.hdr, session->id, + SHMEM_ALLOC_CMD_PLD_SIZE, + CPE_LSM_SESSION_CMD_SHARED_MEM_ALLOC)) { + ret = -EINVAL; + goto end_ret; + } + + cmd_shmem_alloc.size = size; + ret = wcd_cpe_cmi_send_lsm_msg(core, session, &cmd_shmem_alloc); + if (ret) + dev_err(core->dev, + "%s: lsm_shmem_alloc cmd send fail, %d\n", + __func__, ret); +end_ret: + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); + return ret; +} + +/* + * wcd_cpe_cmd_lsm_shmem_dealloc: deallocate the shared memory + * for the specified session + * @core_handle: handle to cpe core + * @session: session for which memory needs to be deallocated. + */ +static int wcd_cpe_cmd_lsm_shmem_dealloc(void *core_handle, + struct cpe_lsm_session *session) +{ + struct cpe_cmd_shmem_dealloc cmd_dealloc; + struct wcd_cpe_core *core = core_handle; + int ret = 0; + + ret = wcd_cpe_is_valid_lsm_session(core, session, + __func__); + if (ret) + return ret; + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + + memset(&cmd_dealloc, 0, sizeof(cmd_dealloc)); + if (fill_lsm_cmd_header_v0_inband(&cmd_dealloc.hdr, session->id, + SHMEM_DEALLOC_CMD_PLD_SIZE, + CPE_LSM_SESSION_CMD_SHARED_MEM_DEALLOC)) { + ret = -EINVAL; + goto end_ret; + } + + cmd_dealloc.addr = session->lsm_mem_handle; + ret = wcd_cpe_cmi_send_lsm_msg(core, session, &cmd_dealloc); + if (ret) { + dev_err(core->dev, + "%s: lsm_shmem_dealloc cmd failed, rc %d\n", + __func__, ret); + goto end_ret; + } + + memset(&session->lsm_mem_handle, 0, + sizeof(session->lsm_mem_handle)); + +end_ret: + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); + return ret; +} + +/* + * wcd_cpe_send_lsm_cal: send the calibration for lsm service + * from acdb to the cpe + * @core: handle to cpe core + * @session: session for which the calibration needs to be set. + */ +static int wcd_cpe_send_lsm_cal( + struct wcd_cpe_core *core, + struct cpe_lsm_session *session) +{ + + u8 *msg_pld; + struct cmi_hdr *hdr; + struct cal_block_data *lsm_cal = NULL; + void *inb_msg; + int rc = 0; + + if (core->cal_data[WCD_CPE_LSM_CAL_LSM] == NULL) { + pr_err("%s: LSM cal not allocated!\n", __func__); + return -EINVAL; + } + + mutex_lock(&core->cal_data[WCD_CPE_LSM_CAL_LSM]->lock); + lsm_cal = cal_utils_get_only_cal_block( + core->cal_data[WCD_CPE_LSM_CAL_LSM]); + if (!lsm_cal) { + pr_err("%s: failed to get lsm cal block\n", __func__); + rc = -EINVAL; + goto unlock_cal_mutex; + } + + if (lsm_cal->cal_data.size == 0) { + dev_dbg(core->dev, "%s: No LSM cal to send\n", + __func__); + rc = 0; + goto unlock_cal_mutex; + } + + inb_msg = kzalloc(sizeof(struct cmi_hdr) + lsm_cal->cal_data.size, + GFP_KERNEL); + if (!inb_msg) { + rc = -ENOMEM; + goto unlock_cal_mutex; + } + + hdr = (struct cmi_hdr *) inb_msg; + + rc = fill_lsm_cmd_header_v0_inband(hdr, session->id, + lsm_cal->cal_data.size, + CPE_LSM_SESSION_CMD_SET_PARAMS); + if (rc) { + pr_err("%s: invalid params for header, err = %d\n", + __func__, rc); + goto free_msg; + } + + msg_pld = ((u8 *) inb_msg) + sizeof(struct cmi_hdr); + memcpy(msg_pld, lsm_cal->cal_data.kvaddr, + lsm_cal->cal_data.size); + + rc = wcd_cpe_cmi_send_lsm_msg(core, session, inb_msg); + if (rc) + pr_err("%s: acdb lsm_params send failed, err = %d\n", + __func__, rc); + +free_msg: + kfree(inb_msg); + +unlock_cal_mutex: + mutex_unlock(&core->cal_data[WCD_CPE_LSM_CAL_LSM]->lock); + return rc; + +} + +static void wcd_cpe_set_param_data(struct cpe_param_data *param_d, + struct cpe_lsm_ids *ids, u32 p_size, + u32 set_param_cmd) +{ + param_d->module_id = ids->module_id; + param_d->param_id = ids->param_id; + + switch (set_param_cmd) { + case CPE_LSM_SESSION_CMD_SET_PARAMS_V2: + param_d->p_size.param_size = p_size; + break; + case CPE_LSM_SESSION_CMD_SET_PARAMS: + default: + param_d->p_size.sr.param_size = + (u16) p_size; + param_d->p_size.sr.reserved = 0; + break; + } +} + +static int wcd_cpe_send_param_epd_thres(struct wcd_cpe_core *core, + struct cpe_lsm_session *session, + void *data, struct cpe_lsm_ids *ids) +{ + struct snd_lsm_ep_det_thres *ep_det_data; + struct cpe_lsm_param_epd_thres epd_cmd; + struct cmi_hdr *msg_hdr = &epd_cmd.hdr; + struct cpe_param_data *param_d = + &epd_cmd.param; + int rc; + + memset(&epd_cmd, 0, sizeof(epd_cmd)); + ep_det_data = (struct snd_lsm_ep_det_thres *) data; + if (fill_lsm_cmd_header_v0_inband(msg_hdr, + session->id, + CPE_CMD_EPD_THRES_PLD_SIZE, + CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) { + rc = -EINVAL; + goto err_ret; + } + + wcd_cpe_set_param_data(param_d, ids, + CPE_EPD_THRES_PARAM_SIZE, + CPE_LSM_SESSION_CMD_SET_PARAMS_V2); + + epd_cmd.minor_version = 1; + epd_cmd.epd_begin = ep_det_data->epd_begin; + epd_cmd.epd_end = ep_det_data->epd_end; + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + rc = wcd_cpe_cmi_send_lsm_msg(core, session, &epd_cmd); + if (unlikely(rc)) + dev_err(core->dev, + "%s: set_param(EPD Threshold) failed, rc %dn", + __func__, rc); + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); +err_ret: + return rc; +} + +static int wcd_cpe_send_param_opmode(struct wcd_cpe_core *core, + struct cpe_lsm_session *session, + void *data, struct cpe_lsm_ids *ids) +{ + struct snd_lsm_detect_mode *opmode_d; + struct cpe_lsm_param_opmode opmode_cmd; + struct cmi_hdr *msg_hdr = &opmode_cmd.hdr; + struct cpe_param_data *param_d = + &opmode_cmd.param; + int rc; + + memset(&opmode_cmd, 0, sizeof(opmode_cmd)); + opmode_d = (struct snd_lsm_detect_mode *) data; + if (fill_lsm_cmd_header_v0_inband(msg_hdr, + session->id, + CPE_CMD_OPMODE_PLD_SIZE, + CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) { + rc = -EINVAL; + goto err_ret; + } + + wcd_cpe_set_param_data(param_d, ids, + CPE_OPMODE_PARAM_SIZE, + CPE_LSM_SESSION_CMD_SET_PARAMS_V2); + + opmode_cmd.minor_version = 1; + if (opmode_d->mode == LSM_MODE_KEYWORD_ONLY_DETECTION) + opmode_cmd.mode = 1; + else + opmode_cmd.mode = 3; + + if (opmode_d->detect_failure) + opmode_cmd.mode |= 0x04; + + opmode_cmd.reserved = 0; + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + rc = wcd_cpe_cmi_send_lsm_msg(core, session, &opmode_cmd); + if (unlikely(rc)) + dev_err(core->dev, + "%s: set_param(operation_mode) failed, rc %dn", + __func__, rc); + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); +err_ret: + return rc; +} + +static int wcd_cpe_send_param_gain(struct wcd_cpe_core *core, + struct cpe_lsm_session *session, + void *data, struct cpe_lsm_ids *ids) +{ + struct snd_lsm_gain *gain_d; + struct cpe_lsm_param_gain gain_cmd; + struct cmi_hdr *msg_hdr = &gain_cmd.hdr; + struct cpe_param_data *param_d = + &gain_cmd.param; + int rc; + + memset(&gain_cmd, 0, sizeof(gain_cmd)); + gain_d = (struct snd_lsm_gain *) data; + if (fill_lsm_cmd_header_v0_inband(msg_hdr, + session->id, + CPE_CMD_GAIN_PLD_SIZE, + CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) { + rc = -EINVAL; + goto err_ret; + } + + wcd_cpe_set_param_data(param_d, ids, + CPE_GAIN_PARAM_SIZE, + CPE_LSM_SESSION_CMD_SET_PARAMS_V2); + + gain_cmd.minor_version = 1; + gain_cmd.gain = gain_d->gain; + gain_cmd.reserved = 0; + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + rc = wcd_cpe_cmi_send_lsm_msg(core, session, &gain_cmd); + if (unlikely(rc)) + dev_err(core->dev, + "%s: set_param(lsm_gain) failed, rc %dn", + __func__, rc); + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); +err_ret: + return rc; +} + +static int wcd_cpe_send_param_connectport(struct wcd_cpe_core *core, + struct cpe_lsm_session *session, + void *data, struct cpe_lsm_ids *ids, u16 port_id) +{ + struct cpe_lsm_param_connectport con_port_cmd; + struct cmi_hdr *msg_hdr = &con_port_cmd.hdr; + struct cpe_param_data *param_d = + &con_port_cmd.param; + int rc; + + memset(&con_port_cmd, 0, sizeof(con_port_cmd)); + if (fill_lsm_cmd_header_v0_inband(msg_hdr, + session->id, + CPE_CMD_CONNECTPORT_PLD_SIZE, + CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) { + rc = -EINVAL; + goto err_ret; + } + + wcd_cpe_set_param_data(param_d, ids, + CPE_CONNECTPORT_PARAM_SIZE, + CPE_LSM_SESSION_CMD_SET_PARAMS_V2); + + con_port_cmd.minor_version = 1; + con_port_cmd.afe_port_id = port_id; + con_port_cmd.reserved = 0; + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + rc = wcd_cpe_cmi_send_lsm_msg(core, session, &con_port_cmd); + if (unlikely(rc)) + dev_err(core->dev, + "%s: set_param(connect_port) failed, rc %dn", + __func__, rc); + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); +err_ret: + return rc; +} + +static int wcd_cpe_send_param_conf_levels( + struct wcd_cpe_core *core, + struct cpe_lsm_session *session, + struct cpe_lsm_ids *ids) +{ + struct cpe_lsm_conf_level conf_level_data; + struct cmi_hdr *hdr = &(conf_level_data.hdr); + struct cpe_param_data *param_d = &(conf_level_data.param); + u8 pld_size = 0; + u8 pad_bytes = 0; + void *message; + int ret = 0; + + memset(&conf_level_data, 0, sizeof(conf_level_data)); + + pld_size = (sizeof(struct cpe_lsm_conf_level) - sizeof(struct cmi_hdr)); + pld_size += session->num_confidence_levels; + pad_bytes = ((4 - (pld_size % 4)) % 4); + pld_size += pad_bytes; + + fill_cmi_header(hdr, session->id, CMI_CPE_LSM_SERVICE_ID, + false, pld_size, + CPE_LSM_SESSION_CMD_SET_PARAMS_V2, false); + + wcd_cpe_set_param_data(param_d, ids, + pld_size - sizeof(struct cpe_param_data), + CPE_LSM_SESSION_CMD_SET_PARAMS_V2); + + conf_level_data.num_active_models = session->num_confidence_levels; + + message = kzalloc(sizeof(struct cpe_lsm_conf_level) + + conf_level_data.num_active_models + pad_bytes, + GFP_KERNEL); + if (!message) { + pr_err("%s: no memory for conf_level\n", __func__); + return -ENOMEM; + } + + memcpy(message, &conf_level_data, + sizeof(struct cpe_lsm_conf_level)); + memcpy(((u8 *) message) + sizeof(struct cpe_lsm_conf_level), + session->conf_levels, conf_level_data.num_active_models); + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + ret = wcd_cpe_cmi_send_lsm_msg(core, session, message); + if (ret) + pr_err("%s: lsm_set_conf_levels failed, err = %d\n", + __func__, ret); + kfree(message); + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); + return ret; +} + +static int wcd_cpe_send_param_snd_model(struct wcd_cpe_core *core, + struct cpe_lsm_session *session, struct cpe_lsm_ids *ids) +{ + int ret = 0; + struct cmi_obm_msg obm_msg; + struct cpe_param_data *param_d; + + + ret = fill_cmi_header(&obm_msg.hdr, session->id, + CMI_CPE_LSM_SERVICE_ID, 0, 20, + CPE_LSM_SESSION_CMD_SET_PARAMS_V2, true); + if (ret) { + dev_err(core->dev, + "%s: Invalid parameters, rc = %d\n", + __func__, ret); + goto err_ret; + } + + obm_msg.pld.version = 0; + obm_msg.pld.size = session->snd_model_size; + obm_msg.pld.data_ptr.kvaddr = session->snd_model_data; + obm_msg.pld.mem_handle = session->lsm_mem_handle; + + param_d = (struct cpe_param_data *) session->snd_model_data; + wcd_cpe_set_param_data(param_d, ids, + (session->snd_model_size - sizeof(*param_d)), + CPE_LSM_SESSION_CMD_SET_PARAMS_V2); + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + ret = wcd_cpe_cmi_send_lsm_msg(core, session, &obm_msg); + if (ret) + dev_err(core->dev, + "%s: snd_model_register failed, %d\n", + __func__, ret); + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); + +err_ret: + return ret; +} + +static int wcd_cpe_send_param_dereg_model( + struct wcd_cpe_core *core, + struct cpe_lsm_session *session, + struct cpe_lsm_ids *ids) +{ + struct cmi_hdr *hdr; + struct cpe_param_data *param_d; + u8 *message; + u32 pld_size; + int rc = 0; + + pld_size = sizeof(*hdr) + sizeof(*param_d); + + message = kzalloc(pld_size, GFP_KERNEL); + if (!message) + return -ENOMEM; + + hdr = (struct cmi_hdr *) message; + param_d = (struct cpe_param_data *) + (((u8 *) message) + sizeof(*hdr)); + + if (fill_lsm_cmd_header_v0_inband(hdr, + session->id, + sizeof(*param_d), + CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) { + rc = -EINVAL; + goto err_ret; + } + wcd_cpe_set_param_data(param_d, ids, 0, + CPE_LSM_SESSION_CMD_SET_PARAMS_V2); + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + rc = wcd_cpe_cmi_send_lsm_msg(core, session, message); + if (rc) + dev_err(core->dev, + "%s: snd_model_deregister failed, %d\n", + __func__, rc); + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); +err_ret: + kfree(message); + return rc; +} + +static int wcd_cpe_send_custom_param( + struct wcd_cpe_core *core, + struct cpe_lsm_session *session, + void *data, u32 msg_size) +{ + u8 *msg; + struct cmi_hdr *hdr; + u8 *msg_pld; + int rc; + + if (msg_size > CMI_INBAND_MESSAGE_SIZE) { + dev_err(core->dev, + "%s: out of band custom params not supported\n", + __func__); + return -EINVAL; + } + + msg = kzalloc(sizeof(*hdr) + msg_size, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + hdr = (struct cmi_hdr *) msg; + msg_pld = msg + sizeof(struct cmi_hdr); + + if (fill_lsm_cmd_header_v0_inband(hdr, + session->id, + msg_size, + CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) { + rc = -EINVAL; + goto err_ret; + } + + memcpy(msg_pld, data, msg_size); + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + rc = wcd_cpe_cmi_send_lsm_msg(core, session, msg); + if (rc) + dev_err(core->dev, + "%s: custom params send failed, err = %d\n", + __func__, rc); + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); +err_ret: + kfree(msg); + return rc; +} + +static int wcd_cpe_set_one_param(void *core_handle, + struct cpe_lsm_session *session, struct lsm_params_info *p_info, + void *data, uint32_t param_type) +{ + struct wcd_cpe_core *core = core_handle; + int rc = 0; + struct cpe_lsm_ids ids; + + memset(&ids, 0, sizeof(ids)); + ids.module_id = p_info->module_id; + ids.param_id = p_info->param_id; + + switch (param_type) { + case LSM_ENDPOINT_DETECT_THRESHOLD: + rc = wcd_cpe_send_param_epd_thres(core, session, + data, &ids); + break; + case LSM_OPERATION_MODE: + rc = wcd_cpe_send_param_opmode(core, session, data, &ids); + break; + case LSM_GAIN: + rc = wcd_cpe_send_param_gain(core, session, data, &ids); + break; + case LSM_MIN_CONFIDENCE_LEVELS: + rc = wcd_cpe_send_param_conf_levels(core, session, &ids); + break; + case LSM_REG_SND_MODEL: + rc = wcd_cpe_send_param_snd_model(core, session, &ids); + break; + case LSM_DEREG_SND_MODEL: + rc = wcd_cpe_send_param_dereg_model(core, session, &ids); + break; + case LSM_CUSTOM_PARAMS: + rc = wcd_cpe_send_custom_param(core, session, + data, p_info->param_size); + break; + default: + pr_err("%s: wrong param_type 0x%x\n", + __func__, param_type); + } + + if (rc) + dev_err(core->dev, + "%s: send_param(%d) failed, err %d\n", + __func__, param_type, rc); + return rc; +} + +/* + * wcd_cpe_lsm_set_params: set the parameters for lsm service + * @core: handle to cpe core + * @session: session for which the parameters are to be set + * @detect_mode: mode for detection + * @detect_failure: flag indicating failure detection enabled/disabled + * + */ +static int wcd_cpe_lsm_set_params(struct wcd_cpe_core *core, + struct cpe_lsm_session *session, + enum lsm_detection_mode detect_mode, bool detect_failure) +{ + struct cpe_lsm_ids ids; + struct snd_lsm_detect_mode det_mode; + + int ret = 0; + + /* Send lsm calibration */ + ret = wcd_cpe_send_lsm_cal(core, session); + if (ret) { + pr_err("%s: fail to sent acdb cal, err = %d", + __func__, ret); + goto err_ret; + } + + /* Send operation mode */ + ids.module_id = CPE_LSM_MODULE_ID_VOICE_WAKEUP; + ids.param_id = CPE_LSM_PARAM_ID_OPERATION_MODE; + det_mode.mode = detect_mode; + det_mode.detect_failure = detect_failure; + ret = wcd_cpe_send_param_opmode(core, session, + &det_mode, &ids); + if (ret) + dev_err(core->dev, + "%s: Failed to set opmode, err=%d\n", + __func__, ret); + +err_ret: + return ret; +} + +static int wcd_cpe_lsm_set_data(void *core_handle, + struct cpe_lsm_session *session, + enum lsm_detection_mode detect_mode, + bool detect_failure) +{ + struct wcd_cpe_core *core = core_handle; + struct cpe_lsm_ids ids; + int ret = 0; + + if (session->num_confidence_levels > 0) { + ret = wcd_cpe_lsm_set_params(core, session, detect_mode, + detect_failure); + if (ret) { + dev_err(core->dev, + "%s: lsm set params failed, rc = %d\n", + __func__, ret); + goto err_ret; + } + + ids.module_id = CPE_LSM_MODULE_ID_VOICE_WAKEUP; + ids.param_id = CPE_LSM_PARAM_ID_MIN_CONFIDENCE_LEVELS; + ret = wcd_cpe_send_param_conf_levels(core, session, &ids); + if (ret) { + dev_err(core->dev, + "%s: lsm confidence levels failed, rc = %d\n", + __func__, ret); + goto err_ret; + } + } else { + dev_dbg(core->dev, + "%s: no conf levels to set\n", + __func__); + } + +err_ret: + return ret; +} + +/* + * wcd_cpe_lsm_reg_snd_model: register the sound model for listen + * @session: session for which to register the sound model + * @detect_mode: detection mode, user dependent/independent + * @detect_failure: flag to indicate if failure detection is enabled + * + * The memory required for sound model should be pre-allocated on CPE + * before this function is invoked. + */ +static int wcd_cpe_lsm_reg_snd_model(void *core_handle, + struct cpe_lsm_session *session, + enum lsm_detection_mode detect_mode, + bool detect_failure) +{ + int ret = 0; + struct cmi_obm_msg obm_msg; + struct wcd_cpe_core *core = core_handle; + + ret = wcd_cpe_is_valid_lsm_session(core, session, + __func__); + if (ret) + return ret; + + ret = wcd_cpe_lsm_set_data(core_handle, session, + detect_mode, detect_failure); + if (ret) { + dev_err(core->dev, + "%s: fail to set lsm data, err = %d\n", + __func__, ret); + return ret; + } + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + + ret = fill_cmi_header(&obm_msg.hdr, session->id, + CMI_CPE_LSM_SERVICE_ID, 0, 20, + CPE_LSM_SESSION_CMD_REGISTER_SOUND_MODEL, true); + if (ret) { + dev_err(core->dev, + "%s: Invalid parameters, rc = %d\n", + __func__, ret); + goto err_ret; + } + + obm_msg.pld.version = 0; + obm_msg.pld.size = session->snd_model_size; + obm_msg.pld.data_ptr.kvaddr = session->snd_model_data; + obm_msg.pld.mem_handle = session->lsm_mem_handle; + + ret = wcd_cpe_cmi_send_lsm_msg(core, session, &obm_msg); + if (ret) + dev_err(core->dev, + "%s: snd_model_register failed, %d\n", + __func__, ret); +err_ret: + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); + return ret; +} + +/* + * wcd_cpe_lsm_dereg_snd_model: deregister the sound model for listen + * @core_handle: handle to cpe core + * @session: session for which to deregister the sound model + * + */ +static int wcd_cpe_lsm_dereg_snd_model(void *core_handle, + struct cpe_lsm_session *session) +{ + struct cmi_hdr cmd_dereg_snd_model; + struct wcd_cpe_core *core = core_handle; + int ret = 0; + + ret = wcd_cpe_is_valid_lsm_session(core, session, + __func__); + if (ret) + return ret; + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + + memset(&cmd_dereg_snd_model, 0, sizeof(cmd_dereg_snd_model)); + if (fill_lsm_cmd_header_v0_inband(&cmd_dereg_snd_model, session->id, + 0, CPE_LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL)) { + ret = -EINVAL; + goto end_ret; + } + + ret = wcd_cpe_cmi_send_lsm_msg(core, session, &cmd_dereg_snd_model); + if (ret) + dev_err(core->dev, + "%s: failed to send dereg_snd_model cmd\n", + __func__); +end_ret: + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); + return ret; +} + +/* + * wcd_cpe_lsm_get_afe_out_port_id: get afe output port id + * @core_handle: handle to the CPE core + * @session: session for which port id needs to get + */ +static int wcd_cpe_lsm_get_afe_out_port_id(void *core_handle, + struct cpe_lsm_session *session) +{ + struct wcd_cpe_core *core = core_handle; + struct snd_soc_codec *codec; + int rc = 0; + + if (!core || !core->codec) { + pr_err("%s: Invalid handle to %s\n", + __func__, + (!core) ? "core" : "codec"); + rc = -EINVAL; + goto done; + } + + if (!session) { + dev_err(core->dev, "%s: Invalid session\n", + __func__); + rc = -EINVAL; + goto done; + } + + if (!core->cpe_cdc_cb || + !core->cpe_cdc_cb->get_afe_out_port_id) { + session->afe_out_port_id = WCD_CPE_AFE_OUT_PORT_2; + dev_dbg(core->dev, + "%s: callback not defined, default port_id = %d\n", + __func__, session->afe_out_port_id); + goto done; + } + + codec = core->codec; + rc = core->cpe_cdc_cb->get_afe_out_port_id(codec, + &session->afe_out_port_id); + if (rc) { + dev_err(core->dev, + "%s: failed to get port id, err = %d\n", + __func__, rc); + goto done; + } + dev_dbg(core->dev, "%s: port_id: %d\n", __func__, + session->afe_out_port_id); + +done: + return rc; +} + +/* + * wcd_cpe_cmd_lsm_start: send the start command to lsm + * @core_handle: handle to the CPE core + * @session: session for which start command to be sent + * + */ +static int wcd_cpe_cmd_lsm_start(void *core_handle, + struct cpe_lsm_session *session) +{ + struct cmi_hdr cmd_lsm_start; + struct wcd_cpe_core *core = core_handle; + int ret = 0; + + ret = wcd_cpe_is_valid_lsm_session(core, session, + __func__); + if (ret) + return ret; + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + + memset(&cmd_lsm_start, 0, sizeof(struct cmi_hdr)); + if (fill_lsm_cmd_header_v0_inband(&cmd_lsm_start, session->id, 0, + CPE_LSM_SESSION_CMD_START)) { + ret = -EINVAL; + goto end_ret; + } + + ret = wcd_cpe_cmi_send_lsm_msg(core, session, &cmd_lsm_start); + if (ret) + dev_err(core->dev, "failed to send lsm_start cmd\n"); +end_ret: + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); + return ret; +} + +/* + * wcd_cpe_cmd_lsm_stop: send the stop command for LSM service + * @core_handle: handle to the cpe core + * @session: session for which stop command to be sent + * + */ +static int wcd_cpe_cmd_lsm_stop(void *core_handle, + struct cpe_lsm_session *session) +{ + struct cmi_hdr cmd_lsm_stop; + struct wcd_cpe_core *core = core_handle; + int ret = 0; + + ret = wcd_cpe_is_valid_lsm_session(core, session, + __func__); + if (ret) + return ret; + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + + memset(&cmd_lsm_stop, 0, sizeof(struct cmi_hdr)); + if (fill_lsm_cmd_header_v0_inband(&cmd_lsm_stop, session->id, 0, + CPE_LSM_SESSION_CMD_STOP)) { + ret = -EINVAL; + goto end_ret; + } + + ret = wcd_cpe_cmi_send_lsm_msg(core, session, &cmd_lsm_stop); + if (ret) + dev_err(core->dev, + "%s: failed to send lsm_stop cmd\n", + __func__); +end_ret: + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); + return ret; + +} + +/* + * wcd_cpe_alloc_lsm_session: allocate a lsm session + * @core: handle to wcd_cpe_core + * @lsm_priv_d: lsm private data + */ +static struct cpe_lsm_session *wcd_cpe_alloc_lsm_session( + void *core_handle, void *client_data, + void (*event_cb)(void *, u8, u8, u8 *)) +{ + struct cpe_lsm_session *session; + int i, session_id = -1; + struct wcd_cpe_core *core = core_handle; + bool afe_register_service = false; + int ret = 0; + + /* + * Even if multiple listen sessions can be + * allocated, the AFE service registration + * should be done only once as CPE can only + * have one instance of AFE service. + * + * If this is the first session to be allocated, + * only then register the afe service. + */ + if (!wcd_cpe_lsm_session_active()) + afe_register_service = true; + + for (i = 1; i <= WCD_CPE_LSM_MAX_SESSIONS; i++) { + if (!lsm_sessions[i]) { + session_id = i; + break; + } + } + + if (session_id < 0) { + dev_err(core->dev, + "%s: max allowed sessions already allocated\n", + __func__); + return NULL; + } + + ret = wcd_cpe_vote(core, true); + if (ret) { + dev_err(core->dev, + "%s: Failed to enable cpe, err = %d\n", + __func__, ret); + return NULL; + } + + session = kzalloc(sizeof(struct cpe_lsm_session), GFP_KERNEL); + if (!session) + goto err_session_alloc; + + session->id = session_id; + session->event_cb = event_cb; + session->cmi_reg_handle = cmi_register(wcd_cpe_cmi_lsm_callback, + CMI_CPE_LSM_SERVICE_ID); + if (!session->cmi_reg_handle) { + dev_err(core->dev, + "%s: Failed to register LSM service with CMI\n", + __func__); + goto err_ret; + } + session->priv_d = client_data; + mutex_init(&session->lsm_lock); + if (afe_register_service) { + /* Register for AFE Service */ + core->cmi_afe_handle = cmi_register(wcd_cpe_cmi_afe_cb, + CMI_CPE_AFE_SERVICE_ID); + wcd_cpe_initialize_afe_port_data(); + if (!core->cmi_afe_handle) { + dev_err(core->dev, + "%s: Failed to register AFE service with CMI\n", + __func__); + goto err_afe_svc_reg; + } + + /* Once AFE service is registered, send the mode command */ + ret = wcd_cpe_afe_svc_cmd_mode(core, + AFE_SVC_EXPLICIT_PORT_START); + if (ret) + goto err_afe_mode_cmd; + } + + session->lsm_mem_handle = 0; + init_completion(&session->cmd_comp); + + lsm_sessions[session_id] = session; + return session; + +err_afe_mode_cmd: + cmi_deregister(core->cmi_afe_handle); + +err_afe_svc_reg: + cmi_deregister(session->cmi_reg_handle); + mutex_destroy(&session->lsm_lock); + +err_ret: + kfree(session); + +err_session_alloc: + wcd_cpe_vote(core, false); + return NULL; +} + +/* + * wcd_cpe_lsm_config_lab_latency: send lab latency value + * @core: handle to wcd_cpe_core + * @session: lsm session + * @latency: the value of latency for lab setup in msec + */ +static int wcd_cpe_lsm_config_lab_latency( + struct wcd_cpe_core *core, + struct cpe_lsm_session *session, + u32 latency) +{ + int ret = 0, pld_size = CPE_PARAM_LSM_LAB_LATENCY_SIZE; + struct cpe_lsm_lab_latency_config cpe_lab_latency; + struct cpe_lsm_lab_config *lab_lat = &cpe_lab_latency.latency_cfg; + struct cpe_param_data *param_d = &lab_lat->param; + struct cpe_lsm_ids ids; + + if (fill_lsm_cmd_header_v0_inband(&cpe_lab_latency.hdr, session->id, + (u8) pld_size, CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) { + pr_err("%s: Failed to create header\n", __func__); + return -EINVAL; + } + if (latency == 0x00 || latency > WCD_CPE_LAB_MAX_LATENCY) { + pr_err("%s: Invalid latency %u\n", + __func__, latency); + return -EINVAL; + } + + lab_lat->latency = latency; + lab_lat->minor_ver = 1; + ids.module_id = CPE_LSM_MODULE_ID_LAB; + ids.param_id = CPE_LSM_PARAM_ID_LAB_CONFIG; + wcd_cpe_set_param_data(param_d, &ids, + PARAM_SIZE_LSM_LATENCY_SIZE, + CPE_LSM_SESSION_CMD_SET_PARAMS_V2); + + pr_debug("%s: Module 0x%x Param 0x%x size %zu pld_size 0x%x\n", + __func__, lab_lat->param.module_id, + lab_lat->param.param_id, PARAM_SIZE_LSM_LATENCY_SIZE, + pld_size); + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + ret = wcd_cpe_cmi_send_lsm_msg(core, session, &cpe_lab_latency); + if (ret != 0) + pr_err("%s: lsm_set_params failed, error = %d\n", + __func__, ret); + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); + return ret; +} + +/* + * wcd_cpe_lsm_lab_control: enable/disable lab + * @core: handle to wcd_cpe_core + * @session: lsm session + * @enable: Indicates whether to enable / disable lab + */ +static int wcd_cpe_lsm_lab_control( + void *core_handle, + struct cpe_lsm_session *session, + bool enable) +{ + struct wcd_cpe_core *core = core_handle; + int ret = 0, pld_size = CPE_PARAM_SIZE_LSM_LAB_CONTROL; + struct cpe_lsm_control_lab cpe_lab_enable; + struct cpe_lsm_lab_enable *lab_enable = &cpe_lab_enable.lab_enable; + struct cpe_param_data *param_d = &lab_enable->param; + struct cpe_lsm_ids ids; + + pr_debug("%s: enter payload_size = %d Enable %d\n", + __func__, pld_size, enable); + + memset(&cpe_lab_enable, 0, sizeof(cpe_lab_enable)); + + if (fill_lsm_cmd_header_v0_inband(&cpe_lab_enable.hdr, session->id, + (u8) pld_size, CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) { + return -EINVAL; + } + if (enable == true) + lab_enable->enable = 1; + else + lab_enable->enable = 0; + + ids.module_id = CPE_LSM_MODULE_ID_LAB; + ids.param_id = CPE_LSM_PARAM_ID_LAB_ENABLE; + wcd_cpe_set_param_data(param_d, &ids, + PARAM_SIZE_LSM_CONTROL_SIZE, + CPE_LSM_SESSION_CMD_SET_PARAMS_V2); + + pr_debug("%s: Module 0x%x, Param 0x%x size %zu pld_size 0x%x\n", + __func__, lab_enable->param.module_id, + lab_enable->param.param_id, PARAM_SIZE_LSM_CONTROL_SIZE, + pld_size); + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + ret = wcd_cpe_cmi_send_lsm_msg(core, session, &cpe_lab_enable); + if (ret != 0) { + pr_err("%s: lsm_set_params failed, error = %d\n", + __func__, ret); + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); + goto done; + } + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); + + if (lab_enable->enable) + ret = wcd_cpe_lsm_config_lab_latency(core, session, + WCD_CPE_LAB_MAX_LATENCY); +done: + return ret; +} + +/* + * wcd_cpe_lsm_eob: stop lab + * @core: handle to wcd_cpe_core + * @session: lsm session to be deallocated + */ +static int wcd_cpe_lsm_eob( + struct wcd_cpe_core *core, + struct cpe_lsm_session *session) +{ + int ret = 0; + struct cmi_hdr lab_eob; + + if (fill_lsm_cmd_header_v0_inband(&lab_eob, session->id, + 0, CPE_LSM_SESSION_CMD_EOB)) { + return -EINVAL; + } + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + ret = wcd_cpe_cmi_send_lsm_msg(core, session, &lab_eob); + if (ret != 0) + pr_err("%s: lsm_set_params failed\n", __func__); + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); + + return ret; +} + +/* + * wcd_cpe_dealloc_lsm_session: deallocate lsm session + * @core: handle to wcd_cpe_core + * @session: lsm session to be deallocated + */ +static int wcd_cpe_dealloc_lsm_session(void *core_handle, + struct cpe_lsm_session *session) +{ + struct wcd_cpe_core *core = core_handle; + int ret = 0; + + if (!session) { + dev_err(core->dev, + "%s: Invalid lsm session\n", __func__); + return -EINVAL; + } + + dev_dbg(core->dev, "%s: session %d being deallocated\n", + __func__, session->id); + if (session->id > WCD_CPE_LSM_MAX_SESSIONS) { + dev_err(core->dev, + "%s: Wrong session id %d max allowed = %d\n", + __func__, session->id, + WCD_CPE_LSM_MAX_SESSIONS); + return -EINVAL; + } + + cmi_deregister(session->cmi_reg_handle); + mutex_destroy(&session->lsm_lock); + lsm_sessions[session->id] = NULL; + kfree(session); + + if (!wcd_cpe_lsm_session_active()) { + cmi_deregister(core->cmi_afe_handle); + core->cmi_afe_handle = NULL; + wcd_cpe_deinitialize_afe_port_data(); + } + + ret = wcd_cpe_vote(core, false); + if (ret) + dev_dbg(core->dev, + "%s: Failed to un-vote cpe, err = %d\n", + __func__, ret); + + return ret; +} + +static int wcd_cpe_lab_ch_setup(void *core_handle, + struct cpe_lsm_session *session, + enum wcd_cpe_event event) +{ + struct wcd_cpe_core *core = core_handle; + struct snd_soc_codec *codec; + int rc = 0; + u8 cpe_intr_bits; + + if (!core || !core->codec) { + pr_err("%s: Invalid handle to %s\n", + __func__, + (!core) ? "core" : "codec"); + rc = EINVAL; + goto done; + } + + if (!core->cpe_cdc_cb || + !core->cpe_cdc_cb->cdc_ext_clk || + !core->cpe_cdc_cb->lab_cdc_ch_ctl) { + dev_err(core->dev, + "%s: Invalid codec callbacks\n", + __func__); + rc = -EINVAL; + goto done; + } + + codec = core->codec; + dev_dbg(core->dev, + "%s: event = 0x%x\n", + __func__, event); + + switch (event) { + case WCD_CPE_PRE_ENABLE: + rc = core->cpe_cdc_cb->cdc_ext_clk(codec, true, false); + if (rc) { + dev_err(core->dev, + "%s: failed to enable cdc clk, err = %d\n", + __func__, rc); + goto done; + } + + rc = core->cpe_cdc_cb->lab_cdc_ch_ctl(codec, + true); + if (rc) { + dev_err(core->dev, + "%s: failed to enable cdc port, err = %d\n", + __func__, rc); + rc = core->cpe_cdc_cb->cdc_ext_clk(codec, false, false); + goto done; + } + + break; + + case WCD_CPE_POST_ENABLE: + rc = cpe_svc_toggle_lab(core->cpe_handle, true); + if (rc) + dev_err(core->dev, + "%s: Failed to enable lab\n", __func__); + break; + + case WCD_CPE_PRE_DISABLE: + /* + * Mask the non-fatal interrupts in CPE as they will + * be generated during lab teardown and may flood. + */ + cpe_intr_bits = ~(core->irq_info.cpe_fatal_irqs & 0xFF); + if (CPE_ERR_IRQ_CB(core)) + core->cpe_cdc_cb->cpe_err_irq_control( + core->codec, + CPE_ERR_IRQ_MASK, + &cpe_intr_bits); + + rc = core->cpe_cdc_cb->lab_cdc_ch_ctl(codec, + false); + if (rc) + dev_err(core->dev, + "%s: failed to disable cdc port, err = %d\n", + __func__, rc); + break; + + case WCD_CPE_POST_DISABLE: + rc = wcd_cpe_lsm_eob(core, session); + if (rc) + dev_err(core->dev, + "%s: eob send failed, err = %d\n", + __func__, rc); + + /* Continue teardown even if eob failed */ + rc = cpe_svc_toggle_lab(core->cpe_handle, false); + if (rc) + dev_err(core->dev, + "%s: Failed to disable lab\n", __func__); + + /* Continue with disabling even if toggle lab fails */ + rc = core->cpe_cdc_cb->cdc_ext_clk(codec, false, false); + if (rc) + dev_err(core->dev, + "%s: failed to disable cdc clk, err = %d\n", + __func__, rc); + + /* Unmask non-fatal CPE interrupts */ + cpe_intr_bits = ~(core->irq_info.cpe_fatal_irqs & 0xFF); + if (CPE_ERR_IRQ_CB(core)) + core->cpe_cdc_cb->cpe_err_irq_control( + core->codec, + CPE_ERR_IRQ_UNMASK, + &cpe_intr_bits); + break; + + default: + dev_err(core->dev, + "%s: Invalid event 0x%x\n", + __func__, event); + rc = -EINVAL; + break; + } + +done: + return rc; +} + +static int wcd_cpe_lsm_set_fmt_cfg(void *core_handle, + struct cpe_lsm_session *session) +{ + int ret; + struct cpe_lsm_output_format_cfg out_fmt_cfg; + struct wcd_cpe_core *core = core_handle; + + ret = wcd_cpe_is_valid_lsm_session(core, session, __func__); + if (ret) + goto done; + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + + memset(&out_fmt_cfg, 0, sizeof(out_fmt_cfg)); + if (fill_lsm_cmd_header_v0_inband(&out_fmt_cfg.hdr, + session->id, OUT_FMT_CFG_CMD_PAYLOAD_SIZE, + CPE_LSM_SESSION_CMD_TX_BUFF_OUTPUT_CONFIG)) { + ret = -EINVAL; + goto err_ret; + } + + out_fmt_cfg.format = session->out_fmt_cfg.format; + out_fmt_cfg.packing = session->out_fmt_cfg.pack_mode; + out_fmt_cfg.data_path_events = session->out_fmt_cfg.data_path_events; + + ret = wcd_cpe_cmi_send_lsm_msg(core, session, &out_fmt_cfg); + if (ret) + dev_err(core->dev, + "%s: lsm_set_output_format_cfg failed, err = %d\n", + __func__, ret); + +err_ret: + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); +done: + return ret; +} + +static void wcd_cpe_snd_model_offset(void *core_handle, + struct cpe_lsm_session *session, size_t *offset) +{ + *offset = sizeof(struct cpe_param_data); +} + +static int wcd_cpe_lsm_set_media_fmt_params(void *core_handle, + struct cpe_lsm_session *session, + struct lsm_hw_params *param) +{ + struct cpe_lsm_media_fmt_param media_fmt; + struct cmi_hdr *msg_hdr = &media_fmt.hdr; + struct wcd_cpe_core *core = core_handle; + struct cpe_param_data *param_d = &media_fmt.param; + struct cpe_lsm_ids ids; + int ret; + + memset(&media_fmt, 0, sizeof(media_fmt)); + if (fill_lsm_cmd_header_v0_inband(msg_hdr, + session->id, + CPE_MEDIA_FMT_PLD_SIZE, + CPE_LSM_SESSION_CMD_SET_PARAMS_V2)) { + ret = -EINVAL; + goto done; + } + + memset(&ids, 0, sizeof(ids)); + ids.module_id = CPE_LSM_MODULE_FRAMEWORK; + ids.param_id = CPE_LSM_PARAM_ID_MEDIA_FMT; + + wcd_cpe_set_param_data(param_d, &ids, CPE_MEDIA_FMT_PARAM_SIZE, + CPE_LSM_SESSION_CMD_SET_PARAMS_V2); + + media_fmt.minor_version = 1; + media_fmt.sample_rate = param->sample_rate; + media_fmt.num_channels = param->num_chs; + media_fmt.bit_width = param->bit_width; + + WCD_CPE_GRAB_LOCK(&session->lsm_lock, "lsm"); + ret = wcd_cpe_cmi_send_lsm_msg(core, session, &media_fmt); + if (ret) + dev_err(core->dev, + "%s: Set_param(media_format) failed, err=%d\n", + __func__, ret); + WCD_CPE_REL_LOCK(&session->lsm_lock, "lsm"); +done: + return ret; +} + +static int wcd_cpe_lsm_set_port(void *core_handle, + struct cpe_lsm_session *session, void *data) +{ + u32 port_id; + int ret; + struct cpe_lsm_ids ids; + struct wcd_cpe_core *core = core_handle; + + ret = wcd_cpe_is_valid_lsm_session(core, session, __func__); + if (ret) + goto done; + + if (!data) { + dev_err(core->dev, "%s: data is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + port_id = *(u32 *)data; + dev_dbg(core->dev, "%s: port_id: %d\n", __func__, port_id); + + memset(&ids, 0, sizeof(ids)); + ids.module_id = LSM_MODULE_ID_FRAMEWORK; + ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; + + ret = wcd_cpe_send_param_connectport(core, session, NULL, + &ids, port_id); + if (ret) + dev_err(core->dev, + "%s: send_param_connectport failed, err %d\n", + __func__, ret); +done: + return ret; +} + +/* + * wcd_cpe_get_lsm_ops: register lsm driver to codec + * @lsm_ops: structure with lsm callbacks + * @codec: codec to which this lsm driver is registered to + */ +int wcd_cpe_get_lsm_ops(struct wcd_cpe_lsm_ops *lsm_ops) +{ + lsm_ops->lsm_alloc_session = wcd_cpe_alloc_lsm_session; + lsm_ops->lsm_dealloc_session = wcd_cpe_dealloc_lsm_session; + lsm_ops->lsm_open_tx = wcd_cpe_cmd_lsm_open_tx; + lsm_ops->lsm_close_tx = wcd_cpe_cmd_lsm_close_tx; + lsm_ops->lsm_shmem_alloc = wcd_cpe_cmd_lsm_shmem_alloc; + lsm_ops->lsm_shmem_dealloc = wcd_cpe_cmd_lsm_shmem_dealloc; + lsm_ops->lsm_register_snd_model = wcd_cpe_lsm_reg_snd_model; + lsm_ops->lsm_deregister_snd_model = wcd_cpe_lsm_dereg_snd_model; + lsm_ops->lsm_get_afe_out_port_id = wcd_cpe_lsm_get_afe_out_port_id; + lsm_ops->lsm_start = wcd_cpe_cmd_lsm_start; + lsm_ops->lsm_stop = wcd_cpe_cmd_lsm_stop; + lsm_ops->lsm_lab_control = wcd_cpe_lsm_lab_control; + lsm_ops->lab_ch_setup = wcd_cpe_lab_ch_setup; + lsm_ops->lsm_set_data = wcd_cpe_lsm_set_data; + lsm_ops->lsm_set_fmt_cfg = wcd_cpe_lsm_set_fmt_cfg; + lsm_ops->lsm_set_one_param = wcd_cpe_set_one_param; + lsm_ops->lsm_get_snd_model_offset = wcd_cpe_snd_model_offset; + lsm_ops->lsm_set_media_fmt_params = wcd_cpe_lsm_set_media_fmt_params; + lsm_ops->lsm_set_port = wcd_cpe_lsm_set_port; + + return 0; +} +EXPORT_SYMBOL(wcd_cpe_get_lsm_ops); + +static int fill_afe_cmd_header(struct cmi_hdr *hdr, u8 port_id, + u16 opcode, u8 pld_size, + bool obm_flag) +{ + CMI_HDR_SET_SESSION(hdr, port_id); + CMI_HDR_SET_SERVICE(hdr, CMI_CPE_AFE_SERVICE_ID); + + CMI_HDR_SET_PAYLOAD_SIZE(hdr, pld_size); + + hdr->opcode = opcode; + + if (obm_flag) + CMI_HDR_SET_OBM(hdr, CMI_OBM_FLAG_OUT_BAND); + else + CMI_HDR_SET_OBM(hdr, CMI_OBM_FLAG_IN_BAND); + + return 0; +} + +/* + * wcd_cpe_cmi_send_afe_msg: send message to AFE service + * @core: wcd cpe core handle + * @port_cfg: configuration data for the afe port + * for which this message is to be sent + * @message: actual message with header and payload + * + * Port specific lock needs to be acquired before this + * function can be invoked + */ +static int wcd_cpe_cmi_send_afe_msg( + struct wcd_cpe_core *core, + struct wcd_cmi_afe_port_data *port_d, + void *message) +{ + int ret = 0; + struct cmi_hdr *hdr = message; + + pr_debug("%s: sending message with opcode 0x%x\n", + __func__, hdr->opcode); + + if (unlikely(!wcd_cpe_is_online_state(core))) { + dev_err(core->dev, "%s: CPE offline\n", __func__); + return 0; + } + + if (CMI_HDR_GET_OBM_FLAG(hdr)) + wcd_cpe_bus_vote_max_bw(core, true); + + ret = cmi_send_msg(message); + if (ret) { + pr_err("%s: cmd 0x%x send failed, err = %d\n", + __func__, hdr->opcode, ret); + goto rel_bus_vote; + } + + ret = wait_for_completion_timeout(&port_d->afe_cmd_complete, + CMI_CMD_TIMEOUT); + if (ret > 0) { + pr_debug("%s: command 0x%x, received response 0x%x\n", + __func__, hdr->opcode, port_d->cmd_result); + if (port_d->cmd_result == CMI_SHMEM_ALLOC_FAILED) + port_d->cmd_result = CPE_ENOMEMORY; + if (port_d->cmd_result > 0) + pr_err("%s: CPE returned error[%s]\n", + __func__, cpe_err_get_err_str( + port_d->cmd_result)); + ret = cpe_err_get_lnx_err_code(port_d->cmd_result); + goto rel_bus_vote; + } else { + pr_err("%s: command 0x%x send timed out\n", + __func__, hdr->opcode); + ret = -ETIMEDOUT; + goto rel_bus_vote; + } + +rel_bus_vote: + reinit_completion(&port_d->afe_cmd_complete); + + if (CMI_HDR_GET_OBM_FLAG(hdr)) + wcd_cpe_bus_vote_max_bw(core, false); + + return ret; +} + + + +/* + * wcd_cpe_afe_shmem_alloc: allocate the cpe memory for afe service + * @core: handle to cpe core + * @port_cfg: configuration data for the port which needs + * memory to be allocated on CPE + * @size: size of the memory to be allocated + */ +static int wcd_cpe_afe_shmem_alloc( + struct wcd_cpe_core *core, + struct wcd_cmi_afe_port_data *port_d, + u32 size) +{ + struct cpe_cmd_shmem_alloc cmd_shmem_alloc; + int ret = 0; + + pr_debug("%s: enter: size = %d\n", __func__, size); + + memset(&cmd_shmem_alloc, 0, sizeof(cmd_shmem_alloc)); + if (fill_afe_cmd_header(&cmd_shmem_alloc.hdr, port_d->port_id, + CPE_AFE_PORT_CMD_SHARED_MEM_ALLOC, + SHMEM_ALLOC_CMD_PLD_SIZE, false)) { + ret = -EINVAL; + goto end_ret; + } + + cmd_shmem_alloc.size = size; + + ret = wcd_cpe_cmi_send_afe_msg(core, port_d, &cmd_shmem_alloc); + if (ret) { + pr_err("%s: afe_shmem_alloc fail,ret = %d\n", + __func__, ret); + goto end_ret; + } + + pr_debug("%s: completed %s, mem_handle = 0x%x\n", + __func__, "CPE_AFE_CMD_SHARED_MEM_ALLOC", + port_d->mem_handle); + +end_ret: + return ret; +} + +/* + * wcd_cpe_afe_shmem_dealloc: deallocate the cpe memory for + * afe service + * @core: handle to cpe core + * @port_d: configuration data for the port which needs + * memory to be deallocated on CPE + * The memory handle to be de-allocated is saved in the + * port configuration data + */ +static int wcd_cpe_afe_shmem_dealloc( + struct wcd_cpe_core *core, + struct wcd_cmi_afe_port_data *port_d) +{ + struct cpe_cmd_shmem_dealloc cmd_dealloc; + int ret = 0; + + pr_debug("%s: enter, port_id = %d\n", + __func__, port_d->port_id); + + memset(&cmd_dealloc, 0, sizeof(cmd_dealloc)); + if (fill_afe_cmd_header(&cmd_dealloc.hdr, port_d->port_id, + CPE_AFE_PORT_CMD_SHARED_MEM_DEALLOC, + SHMEM_DEALLOC_CMD_PLD_SIZE, false)) { + ret = -EINVAL; + goto end_ret; + } + + cmd_dealloc.addr = port_d->mem_handle; + ret = wcd_cpe_cmi_send_afe_msg(core, port_d, &cmd_dealloc); + if (ret) { + pr_err("failed to send shmem_dealloc cmd\n"); + goto end_ret; + } + memset(&port_d->mem_handle, 0, + sizeof(port_d->mem_handle)); + +end_ret: + return ret; +} + +/* + * wcd_cpe_send_afe_cal: send the acdb calibration to AFE port + * @core: handle to cpe core + * @port_d: configuration data for the port for which the + * calibration needs to be appplied + */ +static int wcd_cpe_send_afe_cal(void *core_handle, + struct wcd_cmi_afe_port_data *port_d) +{ + + struct cal_block_data *afe_cal = NULL; + struct wcd_cpe_core *core = core_handle; + struct cmi_obm_msg obm_msg; + void *inb_msg = NULL; + void *msg; + int rc = 0; + bool is_obm_msg; + + if (core->cal_data[WCD_CPE_LSM_CAL_AFE] == NULL) { + pr_err("%s: LSM cal not allocated!\n", + __func__); + rc = -EINVAL; + goto rel_cal_mutex; + } + + mutex_lock(&core->cal_data[WCD_CPE_LSM_CAL_AFE]->lock); + afe_cal = cal_utils_get_only_cal_block( + core->cal_data[WCD_CPE_LSM_CAL_AFE]); + if (!afe_cal) { + pr_err("%s: failed to get afe cal block\n", + __func__); + rc = -EINVAL; + goto rel_cal_mutex; + } + + if (afe_cal->cal_data.size == 0) { + dev_dbg(core->dev, "%s: No AFE cal to send\n", + __func__); + rc = 0; + goto rel_cal_mutex; + } + + is_obm_msg = (afe_cal->cal_data.size > + CMI_INBAND_MESSAGE_SIZE) ? true : false; + + if (is_obm_msg) { + struct cmi_hdr *hdr = &(obm_msg.hdr); + struct cmi_obm *pld = &(obm_msg.pld); + + rc = wcd_cpe_afe_shmem_alloc(core, port_d, + afe_cal->cal_data.size); + if (rc) { + dev_err(core->dev, + "%s: AFE shmem alloc fail %d\n", + __func__, rc); + goto rel_cal_mutex; + } + + rc = fill_afe_cmd_header(hdr, port_d->port_id, + CPE_AFE_CMD_SET_PARAM, + CPE_AFE_PARAM_PAYLOAD_SIZE, + true); + if (rc) { + dev_err(core->dev, + "%s: invalid params for header, err = %d\n", + __func__, rc); + wcd_cpe_afe_shmem_dealloc(core, port_d); + goto rel_cal_mutex; + } + + pld->version = 0; + pld->size = afe_cal->cal_data.size; + pld->data_ptr.kvaddr = afe_cal->cal_data.kvaddr; + pld->mem_handle = port_d->mem_handle; + msg = &obm_msg; + + } else { + u8 *msg_pld; + struct cmi_hdr *hdr; + + inb_msg = kzalloc(sizeof(struct cmi_hdr) + + afe_cal->cal_data.size, + GFP_KERNEL); + if (!inb_msg) { + dev_err(core->dev, + "%s: no memory for afe cal inband\n", + __func__); + rc = -ENOMEM; + goto rel_cal_mutex; + } + + hdr = (struct cmi_hdr *) inb_msg; + + rc = fill_afe_cmd_header(hdr, port_d->port_id, + CPE_AFE_CMD_SET_PARAM, + CPE_AFE_PARAM_PAYLOAD_SIZE, + false); + if (rc) { + dev_err(core->dev, + "%s: invalid params for header, err = %d\n", + __func__, rc); + kfree(inb_msg); + inb_msg = NULL; + goto rel_cal_mutex; + } + + msg_pld = ((u8 *) inb_msg) + sizeof(struct cmi_hdr); + memcpy(msg_pld, afe_cal->cal_data.kvaddr, + afe_cal->cal_data.size); + + msg = inb_msg; + } + + rc = wcd_cpe_cmi_send_afe_msg(core, port_d, msg); + if (rc) + pr_err("%s: afe cal for listen failed, rc = %d\n", + __func__, rc); + + if (is_obm_msg) { + wcd_cpe_afe_shmem_dealloc(core, port_d); + port_d->mem_handle = 0; + } else { + kfree(inb_msg); + inb_msg = NULL; + } + +rel_cal_mutex: + mutex_unlock(&core->cal_data[WCD_CPE_LSM_CAL_AFE]->lock); + return rc; +} + +/* + * wcd_cpe_is_valid_port: check validity of afe port id + * @core: handle to core to check for validity + * @afe_cfg: client provided afe configuration + * @func: function name invoking this validity check, + * used for logging purpose only. + */ +static int wcd_cpe_is_valid_port(struct wcd_cpe_core *core, + struct wcd_cpe_afe_port_cfg *afe_cfg, + const char *func) +{ + if (unlikely(IS_ERR_OR_NULL(core))) { + pr_err("%s: Invalid core handle\n", func); + return -EINVAL; + } + + if (afe_cfg->port_id > WCD_CPE_AFE_MAX_PORTS) { + dev_err(core->dev, + "%s: invalid afe port (%u)\n", + func, afe_cfg->port_id); + return -EINVAL; + } + + dev_dbg(core->dev, + "%s: port_id = %u\n", + func, afe_cfg->port_id); + + return 0; +} + +static int wcd_cpe_afe_svc_cmd_mode(void *core_handle, + u8 mode) +{ + struct cpe_afe_svc_cmd_mode afe_mode; + struct wcd_cpe_core *core = core_handle; + struct wcd_cmi_afe_port_data *afe_port_d; + int ret; + + afe_port_d = &afe_ports[0]; + /* + * AFE SVC mode command is for the service and not port + * specific, hence use AFE port as 0 so the command will + * be applied to all AFE ports on CPE. + */ + afe_port_d->port_id = 0; + + WCD_CPE_GRAB_LOCK(&afe_port_d->afe_lock, "afe"); + memset(&afe_mode, 0, sizeof(afe_mode)); + if (fill_afe_cmd_header(&afe_mode.hdr, afe_port_d->port_id, + CPE_AFE_SVC_CMD_LAB_MODE, + CPE_AFE_CMD_MODE_PAYLOAD_SIZE, + false)) { + ret = -EINVAL; + goto err_ret; + } + + afe_mode.mode = mode; + + ret = wcd_cpe_cmi_send_afe_msg(core, afe_port_d, &afe_mode); + if (ret) + dev_err(core->dev, + "%s: afe_svc_mode cmd failed, err = %d\n", + __func__, ret); + +err_ret: + WCD_CPE_REL_LOCK(&afe_port_d->afe_lock, "afe"); + return ret; +} + +static int wcd_cpe_afe_cmd_port_cfg(void *core_handle, + struct wcd_cpe_afe_port_cfg *afe_cfg) +{ + struct cpe_afe_cmd_port_cfg port_cfg_cmd; + struct wcd_cpe_core *core = core_handle; + struct wcd_cmi_afe_port_data *afe_port_d; + int ret; + + ret = wcd_cpe_is_valid_port(core, afe_cfg, __func__); + if (ret) + goto done; + + afe_port_d = &afe_ports[afe_cfg->port_id]; + afe_port_d->port_id = afe_cfg->port_id; + + WCD_CPE_GRAB_LOCK(&afe_port_d->afe_lock, "afe"); + memset(&port_cfg_cmd, 0, sizeof(port_cfg_cmd)); + if (fill_afe_cmd_header(&port_cfg_cmd.hdr, + afe_cfg->port_id, + CPE_AFE_PORT_CMD_GENERIC_CONFIG, + CPE_AFE_CMD_PORT_CFG_PAYLOAD_SIZE, + false)) { + ret = -EINVAL; + goto err_ret; + } + + port_cfg_cmd.bit_width = afe_cfg->bit_width; + port_cfg_cmd.num_channels = afe_cfg->num_channels; + port_cfg_cmd.sample_rate = afe_cfg->sample_rate; + + if (afe_port_d->port_id == CPE_AFE_PORT_3_TX) + port_cfg_cmd.buffer_size = WCD_CPE_EC_PP_BUF_SIZE; + else + port_cfg_cmd.buffer_size = AFE_OUT_BUF_SIZE(afe_cfg->bit_width, + afe_cfg->sample_rate); + + ret = wcd_cpe_cmi_send_afe_msg(core, afe_port_d, &port_cfg_cmd); + if (ret) + dev_err(core->dev, + "%s: afe_port_config failed, err = %d\n", + __func__, ret); + +err_ret: + WCD_CPE_REL_LOCK(&afe_port_d->afe_lock, "afe"); +done: + return ret; +} + +/* + * wcd_cpe_afe_set_params: set the parameters for afe port + * @afe_cfg: configuration data for the port for which the + * parameters are to be set + */ +static int wcd_cpe_afe_set_params(void *core_handle, + struct wcd_cpe_afe_port_cfg *afe_cfg, bool afe_mad_ctl) +{ + struct cpe_afe_params afe_params; + struct cpe_afe_hw_mad_ctrl *hw_mad_ctrl = &afe_params.hw_mad_ctrl; + struct cpe_afe_port_cfg *port_cfg = &afe_params.port_cfg; + struct wcd_cpe_core *core = core_handle; + struct wcd_cmi_afe_port_data *afe_port_d; + int ret = 0, pld_size = 0; + + ret = wcd_cpe_is_valid_port(core, afe_cfg, __func__); + if (ret) + return ret; + + afe_port_d = &afe_ports[afe_cfg->port_id]; + afe_port_d->port_id = afe_cfg->port_id; + + WCD_CPE_GRAB_LOCK(&afe_port_d->afe_lock, "afe"); + + ret = wcd_cpe_send_afe_cal(core, afe_port_d); + if (ret) { + dev_err(core->dev, + "%s: afe acdb cal send failed, err = %d\n", + __func__, ret); + goto err_ret; + } + + pld_size = CPE_AFE_PARAM_PAYLOAD_SIZE; + memset(&afe_params, 0, sizeof(afe_params)); + + if (fill_afe_cmd_header(&afe_params.hdr, + afe_cfg->port_id, + CPE_AFE_CMD_SET_PARAM, + (u8) pld_size, false)) { + ret = -EINVAL; + goto err_ret; + } + + hw_mad_ctrl->param.module_id = CPE_AFE_MODULE_HW_MAD; + hw_mad_ctrl->param.param_id = CPE_AFE_PARAM_ID_HW_MAD_CTL; + hw_mad_ctrl->param.p_size.sr.param_size = PARAM_SIZE_AFE_HW_MAD_CTRL; + hw_mad_ctrl->param.p_size.sr.reserved = 0; + hw_mad_ctrl->minor_version = 1; + hw_mad_ctrl->mad_type = MAD_TYPE_AUDIO; + hw_mad_ctrl->mad_enable = afe_mad_ctl; + + port_cfg->param.module_id = CPE_AFE_MODULE_AUDIO_DEV_INTERFACE; + port_cfg->param.param_id = CPE_AFE_PARAM_ID_GENERIC_PORT_CONFIG; + port_cfg->param.p_size.sr.param_size = PARAM_SIZE_AFE_PORT_CFG; + port_cfg->param.p_size.sr.reserved = 0; + port_cfg->minor_version = 1; + port_cfg->bit_width = afe_cfg->bit_width; + port_cfg->num_channels = afe_cfg->num_channels; + port_cfg->sample_rate = afe_cfg->sample_rate; + + ret = wcd_cpe_cmi_send_afe_msg(core, afe_port_d, &afe_params); + if (ret) + dev_err(core->dev, + "%s: afe_port_config failed, err = %d\n", + __func__, ret); +err_ret: + WCD_CPE_REL_LOCK(&afe_port_d->afe_lock, "afe"); + return ret; +} + +/* + * wcd_cpe_afe_port_start: send the start command to afe service + * @core_handle: handle to the cpe core + * @port_cfg: configuration data for the afe port which needs + * to be started. + */ +static int wcd_cpe_afe_port_start(void *core_handle, + struct wcd_cpe_afe_port_cfg *port_cfg) +{ + + struct cmi_hdr hdr; + struct wcd_cpe_core *core = core_handle; + struct wcd_cmi_afe_port_data *afe_port_d; + int ret = 0; + + ret = wcd_cpe_is_valid_port(core, port_cfg, __func__); + if (ret) + return ret; + + afe_port_d = &afe_ports[port_cfg->port_id]; + afe_port_d->port_id = port_cfg->port_id; + + WCD_CPE_GRAB_LOCK(&afe_port_d->afe_lock, "afe"); + + memset(&hdr, 0, sizeof(struct cmi_hdr)); + fill_afe_cmd_header(&hdr, port_cfg->port_id, + CPE_AFE_PORT_CMD_START, + 0, false); + ret = wcd_cpe_cmi_send_afe_msg(core, afe_port_d, &hdr); + if (ret) + dev_err(core->dev, + "%s: afe_port_start cmd failed, err = %d\n", + __func__, ret); + WCD_CPE_REL_LOCK(&afe_port_d->afe_lock, "afe"); + return ret; +} + +/* + * wcd_cpe_afe_port_stop: send stop command to afe service + * @core_handle: handle to the cpe core + * @port_cfg: configuration data for the afe port which needs + * to be stopped. + */ +static int wcd_cpe_afe_port_stop(void *core_handle, + struct wcd_cpe_afe_port_cfg *port_cfg) +{ + struct cmi_hdr hdr; + struct wcd_cpe_core *core = core_handle; + struct wcd_cmi_afe_port_data *afe_port_d; + int ret = 0; + + ret = wcd_cpe_is_valid_port(core, port_cfg, __func__); + if (ret) + return ret; + + afe_port_d = &afe_ports[port_cfg->port_id]; + afe_port_d->port_id = port_cfg->port_id; + + WCD_CPE_GRAB_LOCK(&afe_port_d->afe_lock, "afe"); + + memset(&hdr, 0, sizeof(hdr)); + fill_afe_cmd_header(&hdr, port_cfg->port_id, + CPE_AFE_PORT_CMD_STOP, + 0, false); + ret = wcd_cpe_cmi_send_afe_msg(core, afe_port_d, &hdr); + if (ret) + dev_err(core->dev, + "%s: afe_stop cmd failed, err = %d\n", + __func__, ret); + + WCD_CPE_REL_LOCK(&afe_port_d->afe_lock, "afe"); + return ret; +} + +/* + * wcd_cpe_afe_port_suspend: send suspend command to afe service + * @core_handle: handle to the cpe core + * @port_cfg: configuration data for the afe port which needs + * to be suspended. + */ +static int wcd_cpe_afe_port_suspend(void *core_handle, + struct wcd_cpe_afe_port_cfg *port_cfg) +{ + struct cmi_hdr hdr; + struct wcd_cpe_core *core = core_handle; + struct wcd_cmi_afe_port_data *afe_port_d; + int ret = 0; + + ret = wcd_cpe_is_valid_port(core, port_cfg, __func__); + if (ret) + return ret; + + afe_port_d = &afe_ports[port_cfg->port_id]; + afe_port_d->port_id = port_cfg->port_id; + + WCD_CPE_GRAB_LOCK(&afe_port_d->afe_lock, "afe"); + + memset(&hdr, 0, sizeof(struct cmi_hdr)); + fill_afe_cmd_header(&hdr, port_cfg->port_id, + CPE_AFE_PORT_CMD_SUSPEND, + 0, false); + ret = wcd_cpe_cmi_send_afe_msg(core, afe_port_d, &hdr); + if (ret) + dev_err(core->dev, + "%s: afe_suspend cmd failed, err = %d\n", + __func__, ret); + WCD_CPE_REL_LOCK(&afe_port_d->afe_lock, "afe"); + return ret; +} + +/* + * wcd_cpe_afe_port_resume: send the resume command to afe service + * @core_handle: handle to the cpe core + * @port_cfg: configuration data for the afe port which needs + * to be resumed. + */ +static int wcd_cpe_afe_port_resume(void *core_handle, + struct wcd_cpe_afe_port_cfg *port_cfg) +{ + struct cmi_hdr hdr; + struct wcd_cpe_core *core = core_handle; + struct wcd_cmi_afe_port_data *afe_port_d; + int ret = 0; + + ret = wcd_cpe_is_valid_port(core, port_cfg, __func__); + if (ret) + return ret; + + afe_port_d = &afe_ports[port_cfg->port_id]; + afe_port_d->port_id = port_cfg->port_id; + + WCD_CPE_GRAB_LOCK(&afe_port_d->afe_lock, "afe"); + + memset(&hdr, 0, sizeof(hdr)); + fill_afe_cmd_header(&hdr, port_cfg->port_id, + CPE_AFE_PORT_CMD_RESUME, + 0, false); + ret = wcd_cpe_cmi_send_afe_msg(core, afe_port_d, &hdr); + if (ret) + dev_err(core->dev, + "%s: afe_resume cmd failed, err = %d\n", + __func__, ret); + WCD_CPE_REL_LOCK(&afe_port_d->afe_lock, "afe"); + return ret; + +} + +/* + * wcd_cpe_register_afe_driver: register lsm driver to codec + * @cpe_ops: structure with lsm callbacks + * @codec: codec to which this lsm driver is registered to + */ +int wcd_cpe_get_afe_ops(struct wcd_cpe_afe_ops *afe_ops) +{ + afe_ops->afe_set_params = wcd_cpe_afe_set_params; + afe_ops->afe_port_start = wcd_cpe_afe_port_start; + afe_ops->afe_port_stop = wcd_cpe_afe_port_stop; + afe_ops->afe_port_suspend = wcd_cpe_afe_port_suspend; + afe_ops->afe_port_resume = wcd_cpe_afe_port_resume; + afe_ops->afe_port_cmd_cfg = wcd_cpe_afe_cmd_port_cfg; + + return 0; +} +EXPORT_SYMBOL(wcd_cpe_get_afe_ops); + +MODULE_DESCRIPTION("WCD CPE Core"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/wcd_cpe_core.h b/sound/soc/codecs/wcd_cpe_core.h new file mode 100644 index 000000000000..3d672b860ff4 --- /dev/null +++ b/sound/soc/codecs/wcd_cpe_core.h @@ -0,0 +1,226 @@ +/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef WCD_CPE_CORE_H +#define WCD_CPE_CORE_H + +#include +#include +#include "wcd_cpe_services.h" + +#define WCD_CPE_LAB_MAX_LATENCY 250 +#define WCD_CPE_MAD_SLIM_CHANNEL 140 + +/* Indicates CPE block is ready for image re-download */ +#define WCD_CPE_BLK_READY (1 << 0) +/* Indicates the underlying bus is ready */ +#define WCD_CPE_BUS_READY (1 << 1) + +/* + * only when the underlying bus and CPE block both are ready, + * the state will be ready to download + */ +#define WCD_CPE_READY_TO_DLOAD \ + (WCD_CPE_BLK_READY | WCD_CPE_BUS_READY) + +#define WCD_CPE_LOAD_IMEM (1 << 0) +#define WCD_CPE_LOAD_DATA (1 << 1) +#define WCD_CPE_LOAD_ALL \ + (WCD_CPE_LOAD_IMEM | WCD_CPE_LOAD_DATA) + +#define WCD_CPE_IMAGE_FNAME_MAX 64 + +#define WCD_CPE_AFE_OUT_PORT_2 2 +#define WCD_CPE_AFE_OUT_PORT_4 4 + +enum { + WCD_CPE_LSM_CAL_AFE = 0, + WCD_CPE_LSM_CAL_LSM, + WCD_CPE_LSM_CAL_TOPOLOGY_ID, + WCD_CPE_LSM_CAL_MAX, +}; + +enum cpe_err_irq_cntl_type { + CPE_ERR_IRQ_MASK = 0, + CPE_ERR_IRQ_UNMASK, + CPE_ERR_IRQ_CLEAR, + CPE_ERR_IRQ_STATUS, +}; + +struct wcd_cpe_cdc_cb { + /* codec provided callback to enable RCO */ + int (*cdc_clk_en)(struct snd_soc_codec *, bool); + + /* callback for FLL setup for codec */ + int (*cpe_clk_en)(struct snd_soc_codec *, bool); + int (*cdc_ext_clk)(struct snd_soc_codec *codec, int enable, bool dapm); + int (*lab_cdc_ch_ctl)(struct snd_soc_codec *codec, u8 event); + int (*get_afe_out_port_id)(struct snd_soc_codec *codec, u16 *port_id); + int (*bus_vote_bw)(struct snd_soc_codec *codec, + bool vote); + + /* Callback to control the cpe error interrupt mask/status/clear */ + int (*cpe_err_irq_control)(struct snd_soc_codec *codec, + enum cpe_err_irq_cntl_type cntl_type, + u8 *status); +}; + +enum wcd_cpe_ssr_state_event { + /* Indicates CPE is initialized */ + WCD_CPE_INITIALIZED = 0, + /* Indicates that IMEM is downloaded to CPE */ + WCD_CPE_IMEM_DOWNLOADED, + /* Indicates CPE is enabled */ + WCD_CPE_ENABLED, + /* Indicates that CPE is currently active */ + WCD_CPE_ACTIVE, + /* Event from underlying bus notifying bus is down */ + WCD_CPE_BUS_DOWN_EVENT, + /* Event from CPE block, notifying CPE is down */ + WCD_CPE_SSR_EVENT, + /* Event from underlying bus notifying bus is up */ + WCD_CPE_BUS_UP_EVENT, +}; + +struct wcd_cpe_ssr_entry { + int offline; + u32 offline_change; + wait_queue_head_t offline_poll_wait; + struct snd_info_entry *entry; +}; + +struct wcd_cpe_irq_info { + int cpe_engine_irq; + int cpe_err_irq; + u8 cpe_fatal_irqs; +}; + +struct wcd_cpe_hw_info { + u32 dram_offset; + size_t dram_size; + u32 iram_offset; + size_t iram_size; +}; + +struct wcd_cpe_core { + /* handle to cpe services */ + void *cpe_handle; + + /* registration handle to cpe services */ + void *cpe_reg_handle; + + /* cmi registration handle for afe service */ + void *cmi_afe_handle; + + /* handle to codec */ + struct snd_soc_codec *codec; + + /* codec device */ + struct device *dev; + + /* firmware image file name */ + char fname[WCD_CPE_IMAGE_FNAME_MAX]; + + /* firmware image file name from sysfs */ + char dyn_fname[WCD_CPE_IMAGE_FNAME_MAX]; + + /* codec information needed by cpe services */ + struct cpe_svc_codec_info_v1 cdc_info; + + /* work to perform image download */ + struct work_struct load_fw_work; + + /* flag to indicate mode in which cpe needs to be booted */ + int cpe_debug_mode; + + /* callbacks for codec specific implementation */ + const struct wcd_cpe_cdc_cb *cpe_cdc_cb; + + /* work to handle CPE SSR*/ + struct work_struct ssr_work; + + /* PM handle for suspend mode during SSR */ + struct pm_qos_request pm_qos_req; + + /* completion event indicating CPE OFFLINE */ + struct completion offline_compl; + + /* entry into snd card procfs indicating cpe status */ + struct wcd_cpe_ssr_entry ssr_entry; + + /* + * completion event to signal CPE is + * ready for image re-download + */ + struct completion ready_compl; + + /* maintains the status for cpe ssr */ + u8 ready_status; + + /* Indicate SSR type */ + enum wcd_cpe_ssr_state_event ssr_type; + + /* mutex to protect cpe ssr status variables */ + struct mutex ssr_lock; + + /* Store the calibration data needed for cpe */ + struct cal_type_data *cal_data[WCD_CPE_LSM_CAL_MAX]; + + /* completion event to signal CPE is online */ + struct completion online_compl; + + /* reference counter for cpe usage */ + u8 cpe_users; + + /* Ramdump support */ + void *cpe_ramdump_dev; + struct ramdump_segment cpe_ramdump_seg; + dma_addr_t cpe_dump_addr; + void *cpe_dump_v_addr; + + /* SFR support */ + u32 sfr_buf_addr; + size_t sfr_buf_size; + + /* IRQ information for CPE interrupts */ + struct wcd_cpe_irq_info irq_info; + + /* Kobject for sysfs entry */ + struct kobject cpe_kobj; + + /* Reference count for cpe clk*/ + int cpe_clk_ref; + + /* codec based hardware info */ + struct wcd_cpe_hw_info hw_info; +}; + +struct wcd_cpe_params { + struct snd_soc_codec *codec; + struct wcd_cpe_core * (*get_cpe_core)( + struct snd_soc_codec *); + const struct wcd_cpe_cdc_cb *cdc_cb; + int dbg_mode; + u16 cdc_major_ver; + u16 cdc_minor_ver; + u32 cdc_id; + + struct wcd_cpe_irq_info cdc_irq_info; + + struct cpe_svc_init_param *cpe_svc_params; +}; + +int wcd_cpe_ssr_event(void *core_handle, + enum wcd_cpe_ssr_state_event event); +struct wcd_cpe_core *wcd_cpe_init(const char *img_fname, +struct snd_soc_codec *codec, struct wcd_cpe_params *params); +#endif diff --git a/sound/soc/codecs/wcd_cpe_services.c b/sound/soc/codecs/wcd_cpe_services.c new file mode 100644 index 000000000000..0028ebc08d5f --- /dev/null +++ b/sound/soc/codecs/wcd_cpe_services.c @@ -0,0 +1,2990 @@ +/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcd_cpe_services.h" +#include "wcd_cmi_api.h" + +#define CPE_MSG_BUFFER_SIZE 132 +#define CPE_NO_SERVICE 0 + +#define CMI_DRIVER_SUPPORTED_VERSION 0 +#define CMI_API_SUCCESS 0 +#define CMI_MSG_TRANSPORT (0x0002) +#define CPE_SVC_INACTIVE_STATE_RETRIES_MAX 10 + +#define TOMTOM_A_SVASS_SPE_DRAM_OFFSET 0x50000 +#define TOMTOM_A_SVASS_SPE_DRAM_SIZE 0x30000 +#define TOMTOM_A_SVASS_SPE_IRAM_OFFSET 0x80000 +#define TOMTOM_A_SVASS_SPE_IRAM_SIZE 0xC000 +#define TOMTOM_A_SVASS_SPE_INBOX_SIZE 12 +#define TOMTOM_A_SVASS_SPE_OUTBOX_SIZE 12 + +#define MEM_ACCESS_NONE_VAL 0x0 +#define MEM_ACCESS_IRAM_VAL 0x1 +#define MEM_ACCESS_DRAM_VAL 0x2 +#define LISTEN_CTL_SPE_VAL 0x0 +#define LISTEN_CTL_MSM_VAL 0x1 + +#define TOMTOM_A_SVASS_SPE_INBOX(N) (TOMTOM_A_SVASS_SPE_INBOX_0 + (N)) +#define TOMTOM_A_SVASS_SPE_OUTBOX(N) (TOMTOM_A_SVASS_SPE_OUTBOX_0 + (N)) + +#define WCD9335_CPE_SS_SPE_DRAM_OFFSET 0x48000 +#define WCD9335_CPE_SS_SPE_DRAM_SIZE 0x34000 +#define WCD9335_CPE_SS_SPE_IRAM_OFFSET 0x80000 +#define WCD9335_CPE_SS_SPE_IRAM_SIZE 0x20000 + +#define WCD9335_CPE_SS_SPE_INBOX_SIZE 16 +#define WCD9335_CPE_SS_SPE_OUTBOX_SIZE 16 +#define WCD9335_CPE_SS_SPE_MEM_BANK_SIZ 16 + +#define WCD9335_CPE_SS_SPE_INBOX1(N) (WCD9335_CPE_SS_INBOX1_0 + (N)) +#define WCD9335_CPE_SS_SPE_OUTBOX1(N) (WCD9335_CPE_SS_OUTBOX1_0 + (N)) +#define WCD9335_CPE_SS_MEM_BANK(N) (WCD9335_CPE_SS_MEM_BANK_0 + (N)) + +#define CHUNK_SIZE 16 + +#define CPE_SVC_GRAB_LOCK(lock, name) \ +{ \ + pr_debug("%s: %s lock acquire\n", \ + __func__, name); \ + mutex_lock(lock); \ +} + +#define CPE_SVC_REL_LOCK(lock, name) \ +{ \ + pr_debug("%s: %s lock release\n", \ + __func__, name); \ + mutex_unlock(lock); \ +} + +static const struct cpe_svc_hw_cfg cpe_svc_tomtom_info = { + TOMTOM_A_SVASS_SPE_DRAM_SIZE, + TOMTOM_A_SVASS_SPE_DRAM_OFFSET, + TOMTOM_A_SVASS_SPE_IRAM_SIZE, + TOMTOM_A_SVASS_SPE_IRAM_OFFSET, + TOMTOM_A_SVASS_SPE_INBOX_SIZE, + TOMTOM_A_SVASS_SPE_OUTBOX_SIZE +}; + +static const struct cpe_svc_hw_cfg cpe_svc_wcd9335_info = { + WCD9335_CPE_SS_SPE_DRAM_SIZE, + WCD9335_CPE_SS_SPE_DRAM_OFFSET, + WCD9335_CPE_SS_SPE_IRAM_SIZE, + WCD9335_CPE_SS_SPE_IRAM_OFFSET, + WCD9335_CPE_SS_SPE_INBOX_SIZE, + WCD9335_CPE_SS_SPE_OUTBOX_SIZE +}; + +enum cpe_state { + CPE_STATE_UNINITIALIZED = 0, + CPE_STATE_INITIALIZED, + CPE_STATE_IDLE, + CPE_STATE_DOWNLOADING, + CPE_STATE_BOOTING, + CPE_STATE_SENDING_MSG, + CPE_STATE_OFFLINE, + CPE_STATE_BUFFERING, + CPE_STATE_BUFFERING_CANCELLED +}; + +enum cpe_substate { + CPE_SS_IDLE = 0, + CPE_SS_MSG_REQUEST_ACCESS, + CPE_SS_MSG_SEND_INBOX, + CPE_SS_MSG_SENT, + CPE_SS_DL_DOWNLOADING, + CPE_SS_DL_COMPLETED, + CPE_SS_BOOT, + CPE_SS_BOOT_INIT, + CPE_SS_ONLINE +}; + +enum cpe_command { + CPE_CMD_KILL_THREAD = 0, + CPE_CMD_BOOT, + CPE_CMD_BOOT_INITIALIZE, + CPE_CMD_BOOT_COMPLETE, + CPE_CMD_SEND_MSG, + CPE_CMD_SEND_TRANS_MSG, + CPE_CMD_SEND_MSG_COMPLETE, + CPE_CMD_PROCESS_IRQ, + CPE_CMD_RAMDUMP, + CPE_CMD_DL_SEGMENT, + CPE_CMD_SHUTDOWN, + CPE_CMD_RESET, + CPE_CMD_DEINITIALIZE, + CPE_CMD_READ, + CPE_CMD_ENABLE_LAB, + CPE_CMD_DISABLE_LAB, + CPE_CMD_SWAP_BUFFER, + CPE_LAB_CFG_SB, + CPE_CMD_CANCEL_MEMACCESS, + CPE_CMD_PROC_INCOMING_MSG, + CPE_CMD_FTM_TEST, +}; + +enum cpe_process_result { + CPE_PROC_SUCCESS = 0, + CPE_PROC_FAILED, + CPE_PROC_KILLED, + CPE_PROC_QUEUED, +}; + +struct cpe_command_node { + enum cpe_command command; + enum cpe_svc_result result; + void *data; + struct list_head list; +}; + +struct cpe_info { + struct list_head main_queue; + struct completion cmd_complete; + struct completion thread_comp; + void *thread_handler; + bool stop_thread; + struct mutex msg_lock; + enum cpe_state state; + enum cpe_substate substate; + struct list_head client_list; + enum cpe_process_result (*cpe_process_command) + (struct cpe_command_node *command_node); + enum cpe_svc_result (*cpe_cmd_validate) + (const struct cpe_info *i, + enum cpe_command command); + enum cpe_svc_result (*cpe_start_notification) + (struct cpe_info *i); + u32 initialized; + struct cpe_svc_tgt_abstraction *tgt; + void *pending; + void *data; + void *client_context; + u32 codec_id; + struct work_struct clk_plan_work; + struct completion core_svc_cmd_compl; +}; + +struct cpe_tgt_waiti_info { + u8 tgt_waiti_size; + u8 *tgt_waiti_data; +}; + +struct cpe_svc_tgt_abstraction { + enum cpe_svc_result (*tgt_boot)(int debug_mode); + + u32 (*tgt_cpar_init_done)(void); + + u32 (*tgt_is_active)(void); + + enum cpe_svc_result (*tgt_reset)(void); + + enum cpe_svc_result (*tgt_stop)(void); + + enum cpe_svc_result (*tgt_read_mailbox) + (u8 *buffer, size_t size); + + enum cpe_svc_result (*tgt_write_mailbox) + (u8 *buffer, size_t size); + + enum cpe_svc_result (*tgt_read_ram) + (struct cpe_info *c, + struct cpe_svc_mem_segment *data); + + enum cpe_svc_result (*tgt_write_ram) + (struct cpe_info *c, + const struct cpe_svc_mem_segment *data); + + enum cpe_svc_result (*tgt_route_notification) + (enum cpe_svc_module module, + enum cpe_svc_route_dest dest); + + enum cpe_svc_result (*tgt_set_debug_mode)(u32 enable); + const struct cpe_svc_hw_cfg *(*tgt_get_cpe_info)(void); + enum cpe_svc_result (*tgt_deinit) + (struct cpe_svc_tgt_abstraction *param); + enum cpe_svc_result (*tgt_voice_tx_lab) + (bool); + u8 *inbox; + u8 *outbox; + struct cpe_tgt_waiti_info *tgt_waiti_info; +}; + +static enum cpe_svc_result cpe_tgt_tomtom_init( + struct cpe_svc_codec_info_v1 *codec_info, + struct cpe_svc_tgt_abstraction *param); + +static enum cpe_svc_result cpe_tgt_wcd9335_init( + struct cpe_svc_codec_info_v1 *codec_info, + struct cpe_svc_tgt_abstraction *param); + +struct cpe_send_msg { + u8 *payload; + u32 isobm; + u32 address; + size_t size; +}; + +struct cpe_read_handle { + void *registration; + struct cpe_info t_info; + struct list_head buffers; + void *config; +}; + +struct generic_notification { + void (*notification) + (const struct cpe_svc_notification *parameter); + void (*cmi_notification) + (const struct cmi_api_notification *parameter); +}; + +struct cpe_notif_node { + struct generic_notification notif; + u32 mask; + u32 service; + const struct cpe_info *context; + const char *name; + u32 disabled; + struct list_head list; +}; + +struct cpe_priv { + struct cpe_info *cpe_default_handle; + void (*cpe_irq_control_callback)(u32 enable); + void (*cpe_query_freq_plans_cb) + (void *cdc_priv, + struct cpe_svc_cfg_clk_plan *clk_freq); + void (*cpe_change_freq_plan_cb)(void *cdc_priv, + u32 clk_freq); + u32 cpe_msg_buffer; + void *cpe_cmi_handle; + struct mutex cpe_api_mutex; + struct mutex cpe_svc_lock; + struct cpe_svc_boot_event cpe_debug_vector; + void *cdc_priv; +}; + +static struct cpe_priv cpe_d; + +static enum cpe_svc_result __cpe_svc_shutdown(void *cpe_handle); + +static enum cpe_svc_result cpe_is_command_valid( + const struct cpe_info *t_info, + enum cpe_command command); + +static int cpe_register_read(u32 reg, u8 *val) +{ + *(val) = snd_soc_read(cpe_d.cdc_priv, reg); + return 0; +} + +static enum cpe_svc_result cpe_update_bits(u32 reg, + u32 mask, u32 value) +{ + int ret = 0; + + ret = snd_soc_update_bits(cpe_d.cdc_priv, reg, + mask, value); + if (ret < 0) + return CPE_SVC_FAILED; + + return CPE_SVC_SUCCESS; +} + +static int cpe_register_write(u32 reg, u32 val) +{ + int ret = 0; + + if (reg != TOMTOM_A_SVASS_MEM_BANK && + reg != WCD9335_CPE_SS_MEM_BANK_0) + pr_debug("%s: reg = 0x%x, value = 0x%x\n", + __func__, reg, val); + + ret = snd_soc_write(cpe_d.cdc_priv, reg, val); + if (ret < 0) + return CPE_SVC_FAILED; + + return CPE_SVC_SUCCESS; +} + +static int cpe_register_write_repeat(u32 reg, u8 *ptr, u32 to_write) +{ + struct snd_soc_codec *codec = cpe_d.cdc_priv; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + int ret = 0; + + ret = wcd9xxx_slim_write_repeat(wcd9xxx, reg, to_write, ptr); + if (ret != 0) + pr_err("%s: slim_write_repeat failed\n", __func__); + + if (ret < 0) + return CPE_SVC_FAILED; + + return CPE_SVC_SUCCESS; +} + +static bool cpe_register_read_autoinc_supported(void) +{ + return true; +} + + +/* Called under msgq locked context */ +static void cpe_cmd_received(struct cpe_info *t_info) +{ + struct cpe_command_node *node = NULL; + enum cpe_process_result proc_rc = CPE_PROC_SUCCESS; + + if (!t_info) { + pr_err("%s: Invalid thread info\n", + __func__); + return; + } + + while (!list_empty(&t_info->main_queue)) { + if (proc_rc != CPE_PROC_SUCCESS) + break; + node = list_first_entry(&t_info->main_queue, + struct cpe_command_node, list); + if (!node) + break; + list_del(&node->list); + proc_rc = t_info->cpe_process_command(node); + pr_debug("%s: process command return %d\n", + __func__, proc_rc); + + switch (proc_rc) { + case CPE_PROC_SUCCESS: + kfree(node); + break; + case CPE_PROC_FAILED: + kfree(node); + pr_err("%s: cmd failed\n", __func__); + break; + case CPE_PROC_KILLED: + break; + default: + list_add(&node->list, &(t_info->main_queue)); + + } + } +} + +static int cpe_worker_thread(void *context) +{ + struct cpe_info *t_info = (struct cpe_info *)context; + + /* + * Thread will run until requested to stop explicitly + * by setting the t_info->stop_thread flag + */ + while (1) { + /* Wait for command to be processed */ + wait_for_completion(&t_info->cmd_complete); + + CPE_SVC_GRAB_LOCK(&t_info->msg_lock, "msg_lock"); + cpe_cmd_received(t_info); + reinit_completion(&t_info->cmd_complete); + /* Check if thread needs to be stopped */ + if (t_info->stop_thread) + goto unlock_and_exit; + CPE_SVC_REL_LOCK(&t_info->msg_lock, "msg_lock"); + }; + +unlock_and_exit: + pr_debug("%s: thread stopped\n", __func__); + CPE_SVC_REL_LOCK(&t_info->msg_lock, "msg_lock"); + complete_and_exit(&t_info->thread_comp, 0); +} + +static void cpe_create_worker_thread(struct cpe_info *t_info) +{ + INIT_LIST_HEAD(&t_info->main_queue); + init_completion(&t_info->cmd_complete); + init_completion(&t_info->thread_comp); + t_info->stop_thread = false; + t_info->thread_handler = kthread_run(cpe_worker_thread, + (void *)t_info, "cpe-worker-thread"); + pr_debug("%s: Created new worker thread\n", + __func__); +} + +static void cpe_cleanup_worker_thread(struct cpe_info *t_info) +{ + if (!t_info->thread_handler) { + pr_err("%s: thread not created\n", __func__); + return; + } + + /* + * Wake up the command handler in case + * it is waiting for an command to be processed. + */ + CPE_SVC_GRAB_LOCK(&t_info->msg_lock, "msg_lock"); + t_info->stop_thread = true; + complete(&t_info->cmd_complete); + CPE_SVC_REL_LOCK(&t_info->msg_lock, "msg_lock"); + + /* Wait for the thread to exit */ + wait_for_completion(&t_info->thread_comp); + t_info->thread_handler = NULL; + + pr_debug("%s: Thread cleaned up successfully\n", + __func__); +} + +static enum cpe_svc_result +cpe_send_cmd_to_thread(struct cpe_info *t_info, + enum cpe_command command, void *data, + bool high_prio) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + struct cpe_command_node *cmd = NULL; + + rc = cpe_is_command_valid(t_info, command); + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: Invalid command %d\n", + __func__, command); + return rc; + } + + cmd = kzalloc(sizeof(struct cpe_command_node), + GFP_ATOMIC); + if (!cmd) + return CPE_SVC_NO_MEMORY; + + cmd->command = command; + cmd->data = data; + + CPE_SVC_GRAB_LOCK(&t_info->msg_lock, "msg_lock"); + if (high_prio) + list_add(&(cmd->list), + &(t_info->main_queue)); + else + list_add_tail(&(cmd->list), + &(t_info->main_queue)); + complete(&t_info->cmd_complete); + CPE_SVC_REL_LOCK(&t_info->msg_lock, "msg_lock"); + + return rc; +} + +static enum cpe_svc_result cpe_change_state( + struct cpe_info *t_info, + enum cpe_state state, enum cpe_substate ss) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + + if (!t_info) + t_info = cpe_d.cpe_default_handle; + + t_info->state = state; + t_info->substate = ss; + + pr_debug("%s: current state: %d,%d, new_state: %d,%d\n", + __func__, t_info->state, t_info->substate, + state, ss); + + return rc; +} + +static enum cpe_svc_result +cpe_is_command_valid(const struct cpe_info *t_info, + enum cpe_command command) +{ + enum cpe_svc_result rc = CPE_SVC_INVALID_HANDLE; + + if (t_info && t_info->cpe_cmd_validate) + rc = t_info->cpe_cmd_validate(t_info, command); + else + pr_err("%s: invalid handle or callback\n", + __func__); + return rc; +} + +static void cpe_notify_client(struct cpe_notif_node *client, + struct cpe_svc_notification *payload) +{ + if (!client || !payload) { + pr_err("%s: invalid client or payload\n", + __func__); + return; + } + + if (!(client->mask & payload->event)) { + pr_debug("%s: client mask 0x%x not registered for event 0x%x\n", + __func__, client->mask, payload->event); + return; + } + + if (client->notif.notification && !client->disabled) + client->notif.notification(payload); + + if ((client->mask & CPE_SVC_CMI_MSG) && + client->notif.cmi_notification) + client->notif.cmi_notification( + (const struct cmi_api_notification *)payload); +} + +static void cpe_broadcast_notification(const struct cpe_info *t_info, + struct cpe_svc_notification *payload) +{ + struct cpe_notif_node *n = NULL; + + if (!t_info || !payload) { + pr_err("%s: invalid handle\n", __func__); + return; + } + + pr_debug("%s: notify clients, event = %d\n", + __func__, payload->event); + payload->private_data = cpe_d.cdc_priv; + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_svc_lock, "cpe_svc"); + list_for_each_entry(n, &t_info->client_list, list) { + if (!(n->mask & CPE_SVC_CMI_MSG)) + cpe_notify_client(n, payload); + } + CPE_SVC_REL_LOCK(&cpe_d.cpe_svc_lock, "cpe_svc"); +} + +static void *cpe_register_generic(struct cpe_info *t_info, + void notification_callback( + const struct cpe_svc_notification *parameter), + void cmi_callback( + const struct cmi_api_notification *parameter), + u32 mask, u32 service, const char *name) +{ + struct cpe_notif_node *n = NULL; + + n = kzalloc(sizeof(struct cpe_notif_node), + GFP_KERNEL); + if (!n) + return NULL; + n->mask = mask; + n->service = service; + n->notif.notification = notification_callback; + n->notif.cmi_notification = cmi_callback; + n->context = t_info; + n->disabled = false; + n->name = name; + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_svc_lock, "cpe_svc"); + /* Make sure CPE core service is first */ + if (service == CMI_CPE_CORE_SERVICE_ID) + list_add(&n->list, &t_info->client_list); + else + list_add_tail(&n->list, &t_info->client_list); + CPE_SVC_REL_LOCK(&cpe_d.cpe_svc_lock, "cpe_svc"); + + return n; +} + +static enum cpe_svc_result cpe_deregister_generic(struct cpe_info *t_info, + void *reg_handle) +{ + struct cpe_notif_node *n = (struct cpe_notif_node *)reg_handle; + + if (!t_info || !reg_handle) { + pr_err("%s: invalid handle\n", __func__); + return CPE_SVC_INVALID_HANDLE; + } + + list_del(&(n->list)); + kfree(reg_handle); + + return CPE_SVC_SUCCESS; +} + +static enum cpe_svc_result cpe_svc_tgt_init(struct cpe_svc_codec_info_v1 *i, + struct cpe_svc_tgt_abstraction *abs) +{ + if (!i || !abs) { + pr_err("%s: Incorrect information provided\n", + __func__); + return CPE_SVC_FAILED; + } + + switch (i->id) { + case CPE_SVC_CODEC_TOMTOM: + return cpe_tgt_tomtom_init(i, abs); + case CPE_SVC_CODEC_WCD9335: + return cpe_tgt_wcd9335_init(i, abs); + default: + pr_err("%s: Codec type %d not supported\n", + __func__, i->id); + return CPE_SVC_FAILED; + } + + return CPE_SVC_SUCCESS; +} + +static void cpe_notify_cmi_client(struct cpe_info *t_info, u8 *payload, + enum cpe_svc_result result) +{ + struct cpe_notif_node *n = NULL; + struct cmi_api_notification notif; + struct cmi_hdr *hdr; + u8 service = 0; + + if (!t_info || !payload) { + pr_err("%s: invalid payload/handle\n", + __func__); + return; + } + + hdr = CMI_GET_HEADER(payload); + service = CMI_HDR_GET_SERVICE(hdr); + + notif.event = CPE_SVC_CMI_MSG; + notif.result = result; + notif.message = payload; + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_svc_lock, "cpe_svc"); + list_for_each_entry(n, &t_info->client_list, list) { + + if ((n->mask & CPE_SVC_CMI_MSG) && + n->service == service && + n->notif.cmi_notification) { + n->notif.cmi_notification(¬if); + break; + } + } + CPE_SVC_REL_LOCK(&cpe_d.cpe_svc_lock, "cpe_svc"); +} + +static void cpe_toggle_irq_notification(struct cpe_info *t_info, u32 value) +{ + if (cpe_d.cpe_irq_control_callback) + cpe_d.cpe_irq_control_callback(value); +} + +static void cpe_command_cleanup(struct cpe_command_node *command_node) +{ + switch (command_node->command) { + case CPE_CMD_SEND_MSG: + case CPE_CMD_SEND_TRANS_MSG: + case CPE_CMD_SEND_MSG_COMPLETE: + case CPE_CMD_SHUTDOWN: + case CPE_CMD_READ: + kfree(command_node->data); + command_node->data = NULL; + break; + default: + pr_err("%s: unhandled command\n", + __func__); + break; + } +} + +static enum cpe_svc_result cpe_send_msg_to_inbox( + struct cpe_info *t_info, u32 opcode, + struct cpe_send_msg *msg) +{ + size_t bytes = 0; + size_t inbox_size = + t_info->tgt->tgt_get_cpe_info()->inbox_size; + struct cmi_hdr *hdr; + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + + memset(t_info->tgt->inbox, 0, inbox_size); + hdr = CMI_GET_HEADER(t_info->tgt->inbox); + CMI_HDR_SET_SESSION(hdr, 1); + CMI_HDR_SET_SERVICE(hdr, CMI_CPE_CORE_SERVICE_ID); + CMI_HDR_SET_VERSION(hdr, CMI_DRIVER_SUPPORTED_VERSION); + CMI_HDR_SET_OBM(hdr, CMI_OBM_FLAG_IN_BAND); + + switch (opcode) { + case CPE_CORE_SVC_CMD_SHARED_MEM_ALLOC: { + struct cmi_core_svc_cmd_shared_mem_alloc *m; + + CMI_HDR_SET_OPCODE(hdr, + CPE_CORE_SVC_CMD_SHARED_MEM_ALLOC); + CMI_HDR_SET_PAYLOAD_SIZE(hdr, + sizeof(struct cmi_core_svc_cmd_shared_mem_alloc)); + m = (struct cmi_core_svc_cmd_shared_mem_alloc *) + CMI_GET_PAYLOAD(t_info->tgt->inbox); + m->size = CPE_MSG_BUFFER_SIZE; + pr_debug("send shared mem alloc msg to cpe inbox\n"); + } + break; + case CPE_CORE_SVC_CMD_DRAM_ACCESS_REQ: + CMI_HDR_SET_OPCODE(hdr, + CPE_CORE_SVC_CMD_DRAM_ACCESS_REQ); + CMI_HDR_SET_PAYLOAD_SIZE(hdr, 0); + pr_debug("%s: Creating DRAM acces request msg\n", + __func__); + break; + + case CPE_CMI_BASIC_RSP_OPCODE: { + struct cmi_basic_rsp_result *rsp; + + CMI_HDR_SET_OPCODE(hdr, + CPE_CMI_BASIC_RSP_OPCODE); + CMI_HDR_SET_PAYLOAD_SIZE(hdr, + sizeof(struct cmi_basic_rsp_result)); + rsp = (struct cmi_basic_rsp_result *) + CMI_GET_PAYLOAD(t_info->tgt->inbox); + rsp->status = 0; + pr_debug("%s: send basic response\n", __func__); + } + break; + + default: + if (msg->address != 0) { + struct cmi_msg_transport *m = NULL; + struct cpe_svc_mem_segment mem_seg; + + mem_seg.type = CPE_SVC_DATA_MEM; + if (msg->isobm) { + struct cmi_obm *obm = (struct cmi_obm *) + + CMI_GET_PAYLOAD(msg->payload); + mem_seg.cpe_addr = obm->mem_handle; + mem_seg.data = (u8 *)obm->data_ptr.kvaddr; + mem_seg.size = obm->size; + t_info->tgt->tgt_write_ram(t_info, &mem_seg); + } + + mem_seg.cpe_addr = msg->address; + mem_seg.data = msg->payload; + mem_seg.size = msg->size; + t_info->tgt->tgt_write_ram(t_info, &mem_seg); + + hdr = CMI_GET_HEADER(t_info->tgt->inbox); + CMI_HDR_SET_OPCODE(hdr, CMI_MSG_TRANSPORT); + m = (struct cmi_msg_transport *) + CMI_GET_PAYLOAD(t_info->tgt->inbox); + m->addr = msg->address; + m->size = msg->size; + CMI_HDR_SET_PAYLOAD_SIZE(hdr, + sizeof(struct cmi_msg_transport)); + } else { + memcpy(t_info->tgt->inbox, msg->payload, + msg->size); + } + + break; + } + + pr_debug("%s: sending message to cpe inbox\n", + __func__); + bytes = sizeof(struct cmi_hdr); + hdr = CMI_GET_HEADER(t_info->tgt->inbox); + bytes += CMI_HDR_GET_PAYLOAD_SIZE(hdr); + rc = t_info->tgt->tgt_write_mailbox(t_info->tgt->inbox, bytes); + + return rc; +} + +static bool cpe_is_cmd_clk_req(void *cmd) +{ + struct cmi_hdr *hdr; + + hdr = CMI_GET_HEADER(cmd); + + if ((CMI_HDR_GET_SERVICE(hdr) == + CMI_CPE_CORE_SERVICE_ID)) { + if (CMI_GET_OPCODE(cmd) == + CPE_CORE_SVC_CMD_CLK_FREQ_REQUEST) + return true; + } + + return false; +} + +static enum cpe_svc_result cpe_process_clk_change_req( + struct cpe_info *t_info) +{ + struct cmi_core_svc_cmd_clk_freq_request *req; + + req = (struct cmi_core_svc_cmd_clk_freq_request *) + CMI_GET_PAYLOAD(t_info->tgt->outbox); + + if (!cpe_d.cpe_change_freq_plan_cb) { + pr_err("%s: No support for clk freq change\n", + __func__); + return CPE_SVC_FAILED; + } + + cpe_d.cpe_change_freq_plan_cb(cpe_d.cdc_priv, + req->clk_freq); + + /*send a basic response*/ + cpe_send_msg_to_inbox(t_info, + CPE_CMI_BASIC_RSP_OPCODE, NULL); + + return CPE_SVC_SUCCESS; +} + +static void cpe_process_irq_int(u32 irq, + struct cpe_info *t_info) +{ + struct cpe_command_node temp_node; + struct cpe_send_msg *m; + u8 size = 0; + bool err_irq = false; + struct cmi_hdr *hdr; + + pr_debug("%s: irq = %u\n", __func__, irq); + + if (!t_info) { + pr_err("%s: Invalid handle\n", + __func__); + return; + } + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + switch (irq) { + case CPE_IRQ_OUTBOX_IRQ: + size = t_info->tgt->tgt_get_cpe_info()->outbox_size; + t_info->tgt->tgt_read_mailbox(t_info->tgt->outbox, size); + break; + + case CPE_IRQ_MEM_ACCESS_ERROR: + err_irq = true; + cpe_change_state(t_info, CPE_STATE_OFFLINE, CPE_SS_IDLE); + break; + + case CPE_IRQ_WDOG_BITE: + case CPE_IRQ_RCO_WDOG_INT: + err_irq = true; + __cpe_svc_shutdown(t_info); + break; + + case CPE_IRQ_FLL_LOCK_LOST: + default: + err_irq = true; + break; + } + + if (err_irq) { + pr_err("%s: CPE error IRQ %u occurred\n", + __func__, irq); + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + return; + } + + switch (t_info->state) { + case CPE_STATE_BOOTING: + + switch (t_info->substate) { + case CPE_SS_BOOT: + temp_node.command = CPE_CMD_BOOT_INITIALIZE; + temp_node.result = CPE_SVC_SUCCESS; + t_info->substate = CPE_SS_BOOT_INIT; + t_info->cpe_process_command(&temp_node); + break; + + case CPE_SS_BOOT_INIT: + temp_node.command = CPE_CMD_BOOT_COMPLETE; + temp_node.result = CPE_SVC_SUCCESS; + t_info->substate = CPE_SS_ONLINE; + t_info->cpe_process_command(&temp_node); + break; + + default: + pr_debug("%s: unhandled substate %d for state %d\n", + __func__, t_info->state, t_info->substate); + break; + } + break; + + case CPE_STATE_SENDING_MSG: + hdr = CMI_GET_HEADER(t_info->tgt->outbox); + if (CMI_GET_OPCODE(t_info->tgt->outbox) == + CPE_LSM_SESSION_EVENT_DETECTION_STATUS_V2) { + pr_debug("%s: session_id: %u, state: %d,%d, event received\n", + __func__, CMI_HDR_GET_SESSION_ID(hdr), + t_info->state, t_info->substate); + temp_node.command = CPE_CMD_PROC_INCOMING_MSG; + temp_node.data = NULL; + t_info->cpe_process_command(&temp_node); + break; + } + + m = (struct cpe_send_msg *)t_info->pending; + + switch (t_info->substate) { + case CPE_SS_MSG_REQUEST_ACCESS: + cpe_send_cmd_to_thread(t_info, + CPE_CMD_SEND_TRANS_MSG, m, true); + break; + + case CPE_SS_MSG_SEND_INBOX: + if (cpe_is_cmd_clk_req(t_info->tgt->outbox)) + cpe_process_clk_change_req(t_info); + else + cpe_send_cmd_to_thread(t_info, + CPE_CMD_SEND_MSG_COMPLETE, m, true); + break; + + default: + pr_debug("%s: unhandled substate %d for state %d\n", + __func__, t_info->state, t_info->substate); + break; + } + break; + + case CPE_STATE_IDLE: + pr_debug("%s: Message received, notifying client\n", + __func__); + temp_node.command = CPE_CMD_PROC_INCOMING_MSG; + temp_node.data = NULL; + t_info->cpe_process_command(&temp_node); + break; + + default: + pr_debug("%s: unhandled state %d\n", + __func__, t_info->state); + break; + } + + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); +} + + +static void broacast_boot_failed(void) +{ + struct cpe_info *t_info = cpe_d.cpe_default_handle; + struct cpe_svc_notification payload; + + payload.event = CPE_SVC_BOOT_FAILED; + payload.result = CPE_SVC_FAILED; + payload.payload = NULL; + if (t_info) + payload.private_data = + t_info->client_context; + cpe_broadcast_notification(t_info, &payload); +} + +static enum cpe_svc_result broadcast_boot_event( + struct cpe_info *t_info) +{ + struct cpe_svc_notification payload; + + payload.event = CPE_SVC_ONLINE; + payload.result = CPE_SVC_SUCCESS; + payload.payload = NULL; + if (t_info) + payload.private_data = + t_info->client_context; + cpe_broadcast_notification(t_info, &payload); + + return CPE_SVC_SUCCESS; +} + +static enum cpe_process_result cpe_boot_initialize(struct cpe_info *t_info, + enum cpe_svc_result *cpe_rc) +{ + enum cpe_process_result rc = CPE_SVC_FAILED; + struct cpe_svc_notification payload; + struct cmi_core_svc_event_system_boot *p = NULL; + + if (CMI_GET_OPCODE(t_info->tgt->outbox) != + CPE_CORE_SVC_EVENT_SYSTEM_BOOT) { + broacast_boot_failed(); + return rc; + } + + p = (struct cmi_core_svc_event_system_boot *) + CMI_GET_PAYLOAD(t_info->tgt->outbox); + if (p->status != CPE_BOOT_SUCCESS) { + pr_err("%s: cpe boot failed, status = %d\n", + __func__, p->status); + broacast_boot_failed(); + return rc; + } + + /* boot was successful */ + if (p->version == + CPE_CORE_VERSION_SYSTEM_BOOT_EVENT) { + cpe_d.cpe_debug_vector.debug_address = + p->sfr_buff_address; + cpe_d.cpe_debug_vector.debug_buffer_size = + p->sfr_buff_size; + cpe_d.cpe_debug_vector.status = p->status; + payload.event = CPE_SVC_BOOT; + payload.result = CPE_SVC_SUCCESS; + payload.payload = (void *)&cpe_d.cpe_debug_vector; + payload.private_data = t_info->client_context; + cpe_broadcast_notification(t_info, &payload); + } + cpe_change_state(t_info, CPE_STATE_BOOTING, + CPE_SS_BOOT_INIT); + (*cpe_rc) = cpe_send_msg_to_inbox(t_info, + CPE_CORE_SVC_CMD_SHARED_MEM_ALLOC, NULL); + rc = CPE_PROC_SUCCESS; + return rc; +} + +static void cpe_svc_core_cmi_handler( + const struct cmi_api_notification *parameter) +{ + struct cmi_hdr *hdr; + + if (!parameter) + return; + + pr_debug("%s: event = %d\n", + __func__, parameter->event); + + if (parameter->event != CMI_API_MSG) + return; + + hdr = (struct cmi_hdr *) parameter->message; + + if (hdr->opcode == CPE_CMI_BASIC_RSP_OPCODE) { + struct cmi_basic_rsp_result *result; + + result = (struct cmi_basic_rsp_result *) + ((u8 *)parameter->message) + (sizeof(*hdr)); + if (result->status) + pr_err("%s: error response, error code = %u\n", + __func__, result->status); + complete(&cpe_d.cpe_default_handle->core_svc_cmd_compl); + } +} + +static void cpe_clk_plan_work(struct work_struct *work) +{ + struct cpe_info *t_info = NULL; + size_t size = 0; + struct cpe_svc_cfg_clk_plan plan; + u8 *cmi_msg; + struct cmi_hdr *hdr; + int rc; + + t_info = container_of(work, struct cpe_info, clk_plan_work); + if (!t_info) { + pr_err("%s: Invalid handle for cpe_info\n", + __func__); + return; + } + + /* Register the core service */ + cpe_d.cpe_cmi_handle = cmi_register( + cpe_svc_core_cmi_handler, + CMI_CPE_CORE_SERVICE_ID); + + /* send the clk plan command */ + if (!cpe_d.cpe_query_freq_plans_cb) { + pr_err("%s: No support for querying clk plans\n", + __func__); + return; + } + + cpe_d.cpe_query_freq_plans_cb(cpe_d.cdc_priv, &plan); + size = sizeof(plan.current_clk_feq) + + sizeof(plan.num_clk_freqs); + size += plan.num_clk_freqs * + sizeof(plan.clk_freqs[0]); + cmi_msg = kzalloc(size + sizeof(struct cmi_hdr), + GFP_KERNEL); + if (!cmi_msg) + return; + + hdr = (struct cmi_hdr *) cmi_msg; + CMI_HDR_SET_OPCODE(hdr, + CPE_CORE_SVC_CMD_CFG_CLK_PLAN); + CMI_HDR_SET_SERVICE(hdr, CMI_CPE_CORE_SERVICE_ID); + CMI_HDR_SET_SESSION(hdr, 1); + CMI_HDR_SET_VERSION(hdr, CMI_DRIVER_SUPPORTED_VERSION); + CMI_HDR_SET_PAYLOAD_SIZE(hdr, size); + memcpy(CMI_GET_PAYLOAD(cmi_msg), &plan, + size); + cmi_send_msg(cmi_msg); + + /* Wait for clk plan command to complete */ + rc = wait_for_completion_timeout(&t_info->core_svc_cmd_compl, + (10 * HZ)); + if (!rc) { + pr_err("%s: clk plan cmd timed out\n", + __func__); + goto cmd_fail; + } + + /* clk plan cmd is successful, send start notification */ + if (t_info->cpe_start_notification) + t_info->cpe_start_notification(t_info); + else + pr_err("%s: no start notification\n", + __func__); + +cmd_fail: + kfree(cmi_msg); + cmi_deregister(cpe_d.cpe_cmi_handle); +} + +static enum cpe_process_result cpe_boot_complete( + struct cpe_info *t_info) +{ + struct cmi_core_svc_cmdrsp_shared_mem_alloc *p = NULL; + + if (CMI_GET_OPCODE(t_info->tgt->outbox) != + CPE_CORE_SVC_CMDRSP_SHARED_MEM_ALLOC) { + broacast_boot_failed(); + return CPE_PROC_FAILED; + } + + p = (struct cmi_core_svc_cmdrsp_shared_mem_alloc *) + CMI_GET_PAYLOAD(t_info->tgt->outbox); + cpe_d.cpe_msg_buffer = p->addr; + + if (cpe_d.cpe_msg_buffer == 0) { + pr_err("%s: Invalid cpe buffer for message\n", + __func__); + broacast_boot_failed(); + return CPE_PROC_FAILED; + } + + cpe_change_state(t_info, CPE_STATE_IDLE, CPE_SS_IDLE); + cpe_create_worker_thread(t_info); + + if (t_info->codec_id != CPE_SVC_CODEC_TOMTOM) { + schedule_work(&t_info->clk_plan_work); + } else { + if (t_info->cpe_start_notification) + t_info->cpe_start_notification(t_info); + else + pr_err("%s: no start notification\n", + __func__); + } + + pr_debug("%s: boot complete\n", __func__); + return CPE_SVC_SUCCESS; +} + +static enum cpe_process_result cpe_process_send_msg( + struct cpe_info *t_info, + enum cpe_svc_result *cpe_rc, + struct cpe_command_node *command_node) +{ + enum cpe_process_result rc = CPE_PROC_SUCCESS; + struct cpe_send_msg *m = + (struct cpe_send_msg *)command_node->data; + u32 size = m->size; + + if (t_info->pending) { + pr_debug("%s: message queued\n", __func__); + *cpe_rc = CPE_SVC_SUCCESS; + return CPE_PROC_QUEUED; + } + + pr_debug("%s: Send CMI message, size = %u\n", + __func__, size); + + if (size <= t_info->tgt->tgt_get_cpe_info()->inbox_size) { + pr_debug("%s: Msg fits mailbox, size %u\n", + __func__, size); + cpe_change_state(t_info, CPE_STATE_SENDING_MSG, + CPE_SS_MSG_SEND_INBOX); + t_info->pending = m; + *cpe_rc = cpe_send_msg_to_inbox(t_info, 0, m); + } else if (size < CPE_MSG_BUFFER_SIZE) { + m->address = cpe_d.cpe_msg_buffer; + pr_debug("%s: Message req CMI mem access\n", + __func__); + t_info->pending = m; + cpe_change_state(t_info, CPE_STATE_SENDING_MSG, + CPE_SS_MSG_REQUEST_ACCESS); + *cpe_rc = cpe_send_msg_to_inbox(t_info, + CPE_CORE_SVC_CMD_DRAM_ACCESS_REQ, m); + } else { + pr_debug("%s: Invalid msg size %u\n", + __func__, size); + cpe_command_cleanup(command_node); + rc = CPE_PROC_FAILED; + cpe_change_state(t_info, CPE_STATE_IDLE, + CPE_SS_IDLE); + } + + return rc; +} + +static enum cpe_process_result cpe_process_incoming( + struct cpe_info *t_info) +{ + enum cpe_process_result rc = CPE_PROC_FAILED; + struct cmi_hdr *hdr; + + hdr = CMI_GET_HEADER(t_info->tgt->outbox); + + if (CMI_HDR_GET_SERVICE(hdr) == + CMI_CPE_CORE_SERVICE_ID) { + pr_debug("%s: core service message received\n", + __func__); + + switch (CMI_GET_OPCODE(t_info->tgt->outbox)) { + case CPE_CORE_SVC_CMD_CLK_FREQ_REQUEST: + cpe_process_clk_change_req(t_info); + rc = CPE_PROC_SUCCESS; + break; + case CMI_MSG_TRANSPORT: + pr_debug("%s: transport msg received\n", + __func__); + rc = CPE_PROC_SUCCESS; + break; + case CPE_CMI_BASIC_RSP_OPCODE: + pr_debug("%s: received basic rsp\n", + __func__); + rc = CPE_PROC_SUCCESS; + break; + default: + pr_debug("%s: unknown message received\n", + __func__); + break; + } + } else { + /* if service id if for a CMI client, notify client */ + pr_debug("%s: Message received, notifying client\n", + __func__); + cpe_notify_cmi_client(t_info, + t_info->tgt->outbox, CPE_SVC_SUCCESS); + rc = CPE_PROC_SUCCESS; + } + + return rc; +} + +static enum cpe_process_result cpe_process_kill_thread( + struct cpe_info *t_info, + struct cpe_command_node *command_node) +{ + struct cpe_svc_notification payload; + + cpe_d.cpe_msg_buffer = 0; + payload.result = CPE_SVC_SHUTTING_DOWN; + payload.event = CPE_SVC_OFFLINE; + payload.payload = NULL; + payload.private_data = t_info->client_context; + /* + * Make state as offline before broadcasting + * the message to clients. + */ + cpe_change_state(t_info, CPE_STATE_OFFLINE, + CPE_SS_IDLE); + cpe_broadcast_notification(t_info, &payload); + + return CPE_PROC_KILLED; +} + +static enum cpe_process_result cpe_mt_process_cmd( + struct cpe_command_node *command_node) +{ + struct cpe_info *t_info = cpe_d.cpe_default_handle; + enum cpe_svc_result cpe_rc = CPE_SVC_SUCCESS; + enum cpe_process_result rc = CPE_PROC_SUCCESS; + struct cpe_send_msg *m; + struct cmi_hdr *hdr; + u8 service = 0; + u8 retries = 0; + + if (!t_info || !command_node) { + pr_err("%s: Invalid handle/command node\n", + __func__); + return CPE_PROC_FAILED; + } + + pr_debug("%s: cmd = %u\n", __func__, command_node->command); + + cpe_rc = cpe_is_command_valid(t_info, command_node->command); + + if (cpe_rc != CPE_SVC_SUCCESS) { + pr_err("%s: Invalid command %d, err = %d\n", + __func__, command_node->command, cpe_rc); + return CPE_PROC_FAILED; + } + + switch (command_node->command) { + + case CPE_CMD_BOOT_INITIALIZE: + rc = cpe_boot_initialize(t_info, &cpe_rc); + break; + + case CPE_CMD_BOOT_COMPLETE: + rc = cpe_boot_complete(t_info); + break; + + case CPE_CMD_SEND_MSG: + rc = cpe_process_send_msg(t_info, &cpe_rc, + command_node); + break; + + case CPE_CMD_SEND_TRANS_MSG: + m = (struct cpe_send_msg *)command_node->data; + + while (retries < CPE_SVC_INACTIVE_STATE_RETRIES_MAX) { + if (t_info->tgt->tgt_is_active()) { + ++retries; + /* Wait for CPE to be inactive */ + usleep_range(5000, 5100); + } else { + break; + } + } + + pr_debug("%s: cpe inactive after %d attempts\n", + __func__, retries); + + cpe_change_state(t_info, CPE_STATE_SENDING_MSG, + CPE_SS_MSG_SEND_INBOX); + rc = cpe_send_msg_to_inbox(t_info, 0, m); + break; + + case CPE_CMD_SEND_MSG_COMPLETE: + hdr = CMI_GET_HEADER(t_info->tgt->outbox); + service = CMI_HDR_GET_SERVICE(hdr); + pr_debug("%s: msg send success, notifying clients\n", + __func__); + cpe_command_cleanup(command_node); + t_info->pending = NULL; + cpe_change_state(t_info, + CPE_STATE_IDLE, CPE_SS_IDLE); + cpe_notify_cmi_client(t_info, + t_info->tgt->outbox, CPE_SVC_SUCCESS); + break; + + case CPE_CMD_PROC_INCOMING_MSG: + rc = cpe_process_incoming(t_info); + break; + + case CPE_CMD_KILL_THREAD: + rc = cpe_process_kill_thread(t_info, command_node); + break; + + default: + pr_err("%s: unhandled cpe cmd = %d\n", + __func__, command_node->command); + break; + } + + if (cpe_rc != CPE_SVC_SUCCESS) { + pr_err("%s: failed to execute command\n", __func__); + if (t_info->pending) { + m = (struct cpe_send_msg *)t_info->pending; + cpe_notify_cmi_client(t_info, m->payload, + CPE_SVC_FAILED); + t_info->pending = NULL; + } + + cpe_command_cleanup(command_node); + rc = CPE_PROC_FAILED; + cpe_change_state(t_info, CPE_STATE_IDLE, + CPE_SS_IDLE); + } + + return rc; +} + +static enum cpe_svc_result cpe_mt_validate_cmd( + const struct cpe_info *t_info, + enum cpe_command command) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + + if ((t_info == NULL) || t_info->initialized == false) { + pr_err("%s: cpe service is not ready\n", + __func__); + return CPE_SVC_NOT_READY; + } + + switch (t_info->state) { + case CPE_STATE_UNINITIALIZED: + case CPE_STATE_INITIALIZED: + switch (command) { + case CPE_CMD_RESET: + case CPE_CMD_DL_SEGMENT: + case CPE_CMD_RAMDUMP: + case CPE_CMD_PROCESS_IRQ: + case CPE_CMD_KILL_THREAD: + case CPE_CMD_DEINITIALIZE: + case CPE_CMD_FTM_TEST: + rc = CPE_SVC_SUCCESS; + break; + default: + rc = CPE_SVC_NOT_READY; + break; + } + break; + + case CPE_STATE_DOWNLOADING: + switch (command) { + case CPE_CMD_RESET: + case CPE_CMD_DL_SEGMENT: + case CPE_CMD_BOOT: + case CPE_CMD_FTM_TEST: + rc = CPE_SVC_SUCCESS; + break; + default: + rc = CPE_SVC_NOT_READY; + break; + } + break; + + case CPE_STATE_BOOTING: + switch (command) { + case CPE_CMD_PROCESS_IRQ: + case CPE_CMD_BOOT_INITIALIZE: + case CPE_CMD_BOOT_COMPLETE: + case CPE_CMD_SHUTDOWN: + rc = CPE_SVC_SUCCESS; + break; + case CPE_CMD_FTM_TEST: + rc = CPE_SVC_BUSY; + break; + default: + rc = CPE_SVC_NOT_READY; + break; + } + break; + + case CPE_STATE_IDLE: + switch (command) { + case CPE_CMD_SEND_MSG: + case CPE_CMD_SEND_TRANS_MSG: + case CPE_CMD_SEND_MSG_COMPLETE: + case CPE_CMD_PROCESS_IRQ: + case CPE_CMD_RESET: + case CPE_CMD_SHUTDOWN: + case CPE_CMD_KILL_THREAD: + case CPE_CMD_PROC_INCOMING_MSG: + rc = CPE_SVC_SUCCESS; + break; + case CPE_CMD_FTM_TEST: + rc = CPE_SVC_BUSY; + break; + default: + rc = CPE_SVC_FAILED; + break; + } + break; + + case CPE_STATE_SENDING_MSG: + switch (command) { + case CPE_CMD_SEND_MSG: + case CPE_CMD_SEND_TRANS_MSG: + case CPE_CMD_SEND_MSG_COMPLETE: + case CPE_CMD_PROCESS_IRQ: + case CPE_CMD_SHUTDOWN: + case CPE_CMD_KILL_THREAD: + case CPE_CMD_PROC_INCOMING_MSG: + rc = CPE_SVC_SUCCESS; + break; + case CPE_CMD_FTM_TEST: + rc = CPE_SVC_BUSY; + break; + default: + rc = CPE_SVC_FAILED; + break; + } + break; + + case CPE_STATE_OFFLINE: + switch (command) { + case CPE_CMD_RESET: + case CPE_CMD_RAMDUMP: + case CPE_CMD_KILL_THREAD: + rc = CPE_SVC_SUCCESS; + break; + default: + rc = CPE_SVC_NOT_READY; + break; + } + break; + + default: + pr_debug("%s: unhandled state %d\n", + __func__, t_info->state); + break; + } + + if (rc != CPE_SVC_SUCCESS) + pr_err("%s: invalid command %d, state = %d\n", + __func__, command, t_info->state); + return rc; +} + +void *cpe_svc_initialize( + void irq_control_callback(u32 enable), + const void *codec_info, void *context) +{ + struct cpe_info *t_info = NULL; + const struct cpe_svc_hw_cfg *cap = NULL; + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + struct cpe_svc_init_param *init_context = + (struct cpe_svc_init_param *) context; + void *client_context = NULL; + + if (cpe_d.cpe_default_handle && + cpe_d.cpe_default_handle->initialized == true) + return (void *)cpe_d.cpe_default_handle; + cpe_d.cpe_query_freq_plans_cb = NULL; + cpe_d.cpe_change_freq_plan_cb = NULL; + + if (context) { + client_context = init_context->context; + switch (init_context->version) { + case CPE_SVC_INIT_PARAM_V1: + cpe_d.cpe_query_freq_plans_cb = + init_context->query_freq_plans_cb; + cpe_d.cpe_change_freq_plan_cb = + init_context->change_freq_plan_cb; + break; + default: + break; + } + } + + if (!cpe_d.cpe_default_handle) { + cpe_d.cpe_default_handle = kzalloc(sizeof(struct cpe_info), + GFP_KERNEL); + if (!cpe_d.cpe_default_handle) + goto err_register; + + memset(cpe_d.cpe_default_handle, 0, + sizeof(struct cpe_info)); + } + + t_info = cpe_d.cpe_default_handle; + t_info->client_context = client_context; + + INIT_LIST_HEAD(&t_info->client_list); + cpe_d.cdc_priv = client_context; + INIT_WORK(&t_info->clk_plan_work, cpe_clk_plan_work); + init_completion(&t_info->core_svc_cmd_compl); + + t_info->tgt = kzalloc(sizeof(struct cpe_svc_tgt_abstraction), + GFP_KERNEL); + if (!t_info->tgt) + goto err_tgt_alloc; + t_info->codec_id = + ((struct cpe_svc_codec_info_v1 *) codec_info)->id; + + rc = cpe_svc_tgt_init((struct cpe_svc_codec_info_v1 *)codec_info, + t_info->tgt); + + if (rc != CPE_SVC_SUCCESS) + goto err_tgt_init; + + cap = t_info->tgt->tgt_get_cpe_info(); + + memset(t_info->tgt->outbox, 0, cap->outbox_size); + memset(t_info->tgt->inbox, 0, cap->inbox_size); + mutex_init(&t_info->msg_lock); + cpe_d.cpe_irq_control_callback = irq_control_callback; + t_info->cpe_process_command = cpe_mt_process_cmd; + t_info->cpe_cmd_validate = cpe_mt_validate_cmd; + t_info->cpe_start_notification = broadcast_boot_event; + mutex_init(&cpe_d.cpe_api_mutex); + mutex_init(&cpe_d.cpe_svc_lock); + pr_debug("%s: cpe services initialized\n", __func__); + t_info->state = CPE_STATE_INITIALIZED; + t_info->initialized = true; + + return t_info; + +err_tgt_init: + kfree(t_info->tgt); + +err_tgt_alloc: + kfree(cpe_d.cpe_default_handle); + cpe_d.cpe_default_handle = NULL; + +err_register: + return NULL; +} + +enum cpe_svc_result cpe_svc_deinitialize(void *cpe_handle) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + struct cpe_info *t_info = (struct cpe_info *)cpe_handle; + + if (!t_info) + t_info = cpe_d.cpe_default_handle; + + rc = cpe_is_command_valid(t_info, CPE_CMD_DEINITIALIZE); + + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: Invalid command %d\n", + __func__, CPE_CMD_DEINITIALIZE); + return rc; + } + + if (cpe_d.cpe_default_handle == t_info) + cpe_d.cpe_default_handle = NULL; + + t_info->tgt->tgt_deinit(t_info->tgt); + cpe_change_state(t_info, CPE_STATE_UNINITIALIZED, + CPE_SS_IDLE); + mutex_destroy(&t_info->msg_lock); + kfree(t_info->tgt); + kfree(t_info); + mutex_destroy(&cpe_d.cpe_api_mutex); + mutex_destroy(&cpe_d.cpe_svc_lock); + + return rc; +} + +void *cpe_svc_register(void *cpe_handle, + void (*notification_callback) + (const struct cpe_svc_notification *parameter), + u32 mask, const char *name) +{ + void *reg_handle; + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + if (!cpe_d.cpe_default_handle) { + cpe_d.cpe_default_handle = kzalloc(sizeof(struct cpe_info), + GFP_KERNEL); + if (!cpe_d.cpe_default_handle) { + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + return NULL; + } + + memset(cpe_d.cpe_default_handle, 0, + sizeof(struct cpe_info)); + } + + if (!cpe_handle) + cpe_handle = cpe_d.cpe_default_handle; + + reg_handle = cpe_register_generic((struct cpe_info *)cpe_handle, + notification_callback, + NULL, + mask, CPE_NO_SERVICE, name); + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + + return reg_handle; +} + +enum cpe_svc_result cpe_svc_deregister(void *cpe_handle, void *reg_handle) +{ + enum cpe_svc_result rc; + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + if (!cpe_handle) + cpe_handle = cpe_d.cpe_default_handle; + + rc = cpe_deregister_generic((struct cpe_info *)cpe_handle, + reg_handle); + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + + return rc; +} + +enum cpe_svc_result cpe_svc_download_segment(void *cpe_handle, + const struct cpe_svc_mem_segment *segment) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + struct cpe_info *t_info = (struct cpe_info *)cpe_handle; + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + if (!t_info) + t_info = cpe_d.cpe_default_handle; + + rc = cpe_is_command_valid(t_info, CPE_CMD_DL_SEGMENT); + + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: cmd validation fail, cmd = %d\n", + __func__, CPE_CMD_DL_SEGMENT); + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + return rc; + } + + cpe_toggle_irq_notification(t_info, false); + t_info->state = CPE_STATE_DOWNLOADING; + t_info->substate = CPE_SS_DL_DOWNLOADING; + rc = t_info->tgt->tgt_write_ram(t_info, segment); + cpe_toggle_irq_notification(t_info, true); + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + + return rc; +} + +enum cpe_svc_result cpe_svc_boot(void *cpe_handle, int debug_mode) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + struct cpe_info *t_info = (struct cpe_info *)cpe_handle; + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + if (!t_info) + t_info = cpe_d.cpe_default_handle; + + rc = cpe_is_command_valid(t_info, CPE_CMD_BOOT); + + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: cmd validation fail, cmd = %d\n", + __func__, CPE_CMD_BOOT); + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + return rc; + } + + if (rc == CPE_SVC_SUCCESS) { + t_info->tgt->tgt_boot(debug_mode); + t_info->state = CPE_STATE_BOOTING; + t_info->substate = CPE_SS_BOOT; + pr_debug("%s: cpe service booting\n", + __func__); + } + + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + return rc; +} + +enum cpe_svc_result cpe_svc_process_irq(void *cpe_handle, u32 cpe_irq) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + struct cpe_info *t_info = (struct cpe_info *)cpe_handle; + + if (!t_info) + t_info = cpe_d.cpe_default_handle; + + cpe_toggle_irq_notification(t_info, false); + cpe_process_irq_int(cpe_irq, t_info); + cpe_toggle_irq_notification(t_info, true); + + return rc; +} + +enum cpe_svc_result cpe_svc_route_notification(void *cpe_handle, + enum cpe_svc_module module, enum cpe_svc_route_dest dest) +{ + struct cpe_info *t_info = (struct cpe_info *)cpe_handle; + enum cpe_svc_result rc = CPE_SVC_NOT_READY; + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + if (!t_info) + t_info = cpe_d.cpe_default_handle; + + if (t_info->tgt) + rc = t_info->tgt->tgt_route_notification(module, dest); + + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + return rc; +} + +static enum cpe_svc_result __cpe_svc_shutdown(void *cpe_handle) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + struct cpe_info *t_info = (struct cpe_info *)cpe_handle; + struct cpe_command_node *n = NULL; + struct cpe_command_node kill_cmd; + + if (!t_info) + t_info = cpe_d.cpe_default_handle; + + rc = cpe_is_command_valid(t_info, CPE_CMD_SHUTDOWN); + + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: cmd validation fail, cmd = %d\n", + __func__, CPE_CMD_SHUTDOWN); + return rc; + } + + while (!list_empty(&t_info->main_queue)) { + n = list_first_entry(&t_info->main_queue, + struct cpe_command_node, list); + + if (n->command == CPE_CMD_SEND_MSG) { + cpe_notify_cmi_client(t_info, (u8 *)n->data, + CPE_SVC_SHUTTING_DOWN); + } + /* + * Since command cannot be processed, + * delete it from the list and perform cleanup + */ + list_del(&n->list); + cpe_command_cleanup(n); + kfree(n); + } + + pr_debug("%s: cpe service OFFLINE state\n", __func__); + + t_info->state = CPE_STATE_OFFLINE; + t_info->substate = CPE_SS_IDLE; + + memset(&kill_cmd, 0, sizeof(kill_cmd)); + kill_cmd.command = CPE_CMD_KILL_THREAD; + + if (t_info->pending) { + struct cpe_send_msg *m = + (struct cpe_send_msg *)t_info->pending; + cpe_notify_cmi_client(t_info, m->payload, + CPE_SVC_SHUTTING_DOWN); + kfree(t_info->pending); + t_info->pending = NULL; + } + + cpe_cleanup_worker_thread(t_info); + t_info->cpe_process_command(&kill_cmd); + + return rc; +} + +enum cpe_svc_result cpe_svc_shutdown(void *cpe_handle) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + rc = __cpe_svc_shutdown(cpe_handle); + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + return rc; +} + +enum cpe_svc_result cpe_svc_reset(void *cpe_handle) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + struct cpe_info *t_info = (struct cpe_info *)cpe_handle; + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + if (!t_info) + t_info = cpe_d.cpe_default_handle; + + rc = cpe_is_command_valid(t_info, CPE_CMD_RESET); + + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: cmd validation fail, cmd = %d\n", + __func__, CPE_CMD_RESET); + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + return rc; + } + + if (t_info && t_info->tgt) { + rc = t_info->tgt->tgt_reset(); + pr_debug("%s: cpe services in INITIALIZED state\n", + __func__); + t_info->state = CPE_STATE_INITIALIZED; + t_info->substate = CPE_SS_IDLE; + } + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + + return rc; +} + +enum cpe_svc_result cpe_svc_ramdump(void *cpe_handle, + struct cpe_svc_mem_segment *buffer) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + struct cpe_info *t_info = (struct cpe_info *)cpe_handle; + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + if (!t_info) + t_info = cpe_d.cpe_default_handle; + + rc = cpe_is_command_valid(t_info, CPE_CMD_RAMDUMP); + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: cmd validation fail, cmd = %d\n", + __func__, CPE_CMD_RAMDUMP); + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + return rc; + } + + if (t_info->tgt) { + rc = t_info->tgt->tgt_read_ram(t_info, buffer); + } else { + pr_err("%s: cpe service not ready\n", __func__); + rc = CPE_SVC_NOT_READY; + } + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + + return rc; +} + +enum cpe_svc_result cpe_svc_set_debug_mode(void *cpe_handle, u32 mode) +{ + struct cpe_info *t_info = (struct cpe_info *)cpe_handle; + enum cpe_svc_result rc = CPE_SVC_INVALID_HANDLE; + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + if (!t_info) + t_info = cpe_d.cpe_default_handle; + + if (t_info->tgt) + rc = t_info->tgt->tgt_set_debug_mode(mode); + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + + return rc; +} + +const struct cpe_svc_hw_cfg *cpe_svc_get_hw_cfg(void *cpe_handle) +{ + struct cpe_info *t_info = (struct cpe_info *)cpe_handle; + + if (!t_info) + t_info = cpe_d.cpe_default_handle; + + if (t_info->tgt) + return t_info->tgt->tgt_get_cpe_info(); + + return NULL; +} + +void *cmi_register( + void notification_callback( + const struct cmi_api_notification *parameter), + u32 service) +{ + void *reg_handle = NULL; + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + reg_handle = cpe_register_generic(cpe_d.cpe_default_handle, + NULL, + notification_callback, + (CPE_SVC_CMI_MSG | CPE_SVC_OFFLINE | + CPE_SVC_ONLINE), + service, + "CMI_CLIENT"); + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + + return reg_handle; +} + +enum cmi_api_result cmi_deregister(void *reg_handle) +{ + u32 clients = 0; + struct cpe_notif_node *n = NULL; + enum cmi_api_result rc = CMI_API_SUCCESS; + struct cpe_svc_notification payload; + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + rc = (enum cmi_api_result) cpe_deregister_generic( + cpe_d.cpe_default_handle, reg_handle); + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_svc_lock, "cpe_svc"); + list_for_each_entry(n, &cpe_d.cpe_default_handle->client_list, list) { + if (n->mask & CPE_SVC_CMI_MSG) + clients++; + } + CPE_SVC_REL_LOCK(&cpe_d.cpe_svc_lock, "cpe_svc"); + + if (clients == 0) { + payload.event = CPE_SVC_CMI_CLIENTS_DEREG; + payload.payload = NULL; + payload.result = CPE_SVC_SUCCESS; + cpe_broadcast_notification(cpe_d.cpe_default_handle, &payload); + } + + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + return rc; +} + +enum cmi_api_result cmi_send_msg(void *message) +{ + enum cmi_api_result rc = CMI_API_SUCCESS; + struct cpe_send_msg *msg = NULL; + struct cmi_hdr *hdr; + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + hdr = CMI_GET_HEADER(message); + msg = kzalloc(sizeof(struct cpe_send_msg), + GFP_ATOMIC); + if (!msg) { + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + return CPE_SVC_NO_MEMORY; + } + + if (CMI_HDR_GET_OBM_FLAG(hdr) == CMI_OBM_FLAG_OUT_BAND) + msg->isobm = 1; + else + msg->isobm = 0; + + msg->size = sizeof(struct cmi_hdr) + + CMI_HDR_GET_PAYLOAD_SIZE(hdr); + + msg->payload = kzalloc(msg->size, GFP_ATOMIC); + if (!msg->payload) { + kfree(msg); + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + return CPE_SVC_NO_MEMORY; + } + + msg->address = 0; + memcpy((void *)msg->payload, message, msg->size); + + rc = (enum cmi_api_result) cpe_send_cmd_to_thread( + cpe_d.cpe_default_handle, + CPE_CMD_SEND_MSG, + (void *)msg, false); + + if (rc != 0) { + pr_err("%s: Failed to queue message\n", __func__); + kfree(msg->payload); + kfree(msg); + } + + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + return rc; +} + +enum cpe_svc_result cpe_svc_ftm_test(void *cpe_handle, u32 *status) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + struct cpe_info *t_info = (struct cpe_info *)cpe_handle; + struct cpe_svc_mem_segment backup_seg; + struct cpe_svc_mem_segment waiti_seg; + u8 *backup_data = NULL; + + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + if (!t_info) + t_info = cpe_d.cpe_default_handle; + + rc = cpe_is_command_valid(t_info, CPE_CMD_FTM_TEST); + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: cmd validation fail, cmd = %d\n", + __func__, CPE_CMD_FTM_TEST); + goto fail_cmd; + } + + if (t_info && t_info->tgt) { + backup_data = kzalloc( + t_info->tgt->tgt_waiti_info->tgt_waiti_size, + GFP_KERNEL); + + /* CPE reset */ + rc = t_info->tgt->tgt_reset(); + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: CPE reset fail! err = %d\n", + __func__, rc); + goto err_return; + } + + /* Back up the 4 byte IRAM data first */ + backup_seg.type = CPE_SVC_INSTRUCTION_MEM; + backup_seg.cpe_addr = + t_info->tgt->tgt_get_cpe_info()->IRAM_offset; + backup_seg.size = t_info->tgt->tgt_waiti_info->tgt_waiti_size; + backup_seg.data = backup_data; + + pr_debug("%s: Backing up IRAM data from CPE\n", + __func__); + + rc = t_info->tgt->tgt_read_ram(t_info, &backup_seg); + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: Fail to backup CPE IRAM data, err = %d\n", + __func__, rc); + goto err_return; + } + + pr_debug("%s: Complete backing up IRAM data from CPE\n", + __func__); + + /* Write the WAITI instruction data */ + waiti_seg.type = CPE_SVC_INSTRUCTION_MEM; + waiti_seg.cpe_addr = + t_info->tgt->tgt_get_cpe_info()->IRAM_offset; + waiti_seg.size = t_info->tgt->tgt_waiti_info->tgt_waiti_size; + waiti_seg.data = t_info->tgt->tgt_waiti_info->tgt_waiti_data; + + rc = t_info->tgt->tgt_write_ram(t_info, &waiti_seg); + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: Fail to write the WAITI data, err = %d\n", + __func__, rc); + goto restore_iram; + } + + /* Boot up cpe to execute the WAITI instructions */ + rc = t_info->tgt->tgt_boot(1); + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: Fail to boot CPE, err = %d\n", + __func__, rc); + goto reset; + } + + /* + * 1ms delay is suggested by the hw team to + * wait for cpe to boot up. + */ + usleep_range(1000, 1100); + + /* Check if the cpe init is done after executing the WAITI */ + *status = t_info->tgt->tgt_cpar_init_done(); + +reset: + /* Set the cpe back to reset state */ + rc = t_info->tgt->tgt_reset(); + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: CPE reset fail! err = %d\n", + __func__, rc); + goto restore_iram; + } + +restore_iram: + /* Restore the IRAM 4 bytes data */ + rc = t_info->tgt->tgt_write_ram(t_info, &backup_seg); + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: Fail to restore the IRAM data, err = %d\n", + __func__, rc); + goto err_return; + } + } + +err_return: + kfree(backup_data); +fail_cmd: + CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api"); + return rc; +} + +static enum cpe_svc_result cpe_tgt_tomtom_boot(int debug_mode) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + + if (!debug_mode) + rc = cpe_update_bits(TOMTOM_A_SVASS_CPAR_WDOG_CFG, + 0x3F, 0x31); + else + pr_info("%s: CPE in debug mode, WDOG disabled\n", + __func__); + + rc = cpe_update_bits(TOMTOM_A_SVASS_CLKRST_CTL, + 0x02, 0x00); + rc = cpe_update_bits(TOMTOM_A_SVASS_CLKRST_CTL, + 0x0C, 0x04); + rc = cpe_update_bits(TOMTOM_A_SVASS_CPAR_CFG, + 0x01, 0x01); + + return rc; +} + +static u32 cpe_tgt_tomtom_is_cpar_init_done(void) +{ + u8 status = 0; + + cpe_register_read(TOMTOM_A_SVASS_STATUS, &status); + return status & 0x01; +} + +static u32 cpe_tgt_tomtom_is_active(void) +{ + u8 status = 0; + + cpe_register_read(TOMTOM_A_SVASS_STATUS, &status); + return status & 0x04; +} + +static enum cpe_svc_result cpe_tgt_tomtom_reset(void) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + + rc = cpe_update_bits(TOMTOM_A_SVASS_CPAR_WDOG_CFG, + 0x30, 0x00); + + rc = cpe_update_bits(TOMTOM_A_SVASS_CPAR_CFG, + 0x01, 0x00); + rc = cpe_update_bits(TOMTOM_A_MEM_LEAKAGE_CTL, + 0x07, 0x03); + rc = cpe_update_bits(TOMTOM_A_SVASS_CLKRST_CTL, + 0x08, 0x08); + rc = cpe_update_bits(TOMTOM_A_SVASS_CLKRST_CTL, + 0x02, 0x02); + return rc; +} + +enum cpe_svc_result cpe_tgt_tomtom_voicetx(bool enable) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + u8 val = 0; + + if (enable) + val = 0x02; + else + val = 0x00; + rc = cpe_update_bits(TOMTOM_A_SVASS_CFG, + 0x02, val); + val = 0; + cpe_register_read(TOMTOM_A_SVASS_CFG, &val); + return rc; +} + +enum cpe_svc_result cpe_svc_toggle_lab(void *cpe_handle, bool enable) +{ + + struct cpe_info *t_info = (struct cpe_info *)cpe_handle; + + if (!t_info) + t_info = cpe_d.cpe_default_handle; + + if (t_info->tgt) + return t_info->tgt->tgt_voice_tx_lab(enable); + else + return CPE_SVC_INVALID_HANDLE; +} + +static enum cpe_svc_result cpe_tgt_tomtom_read_mailbox(u8 *buffer, + size_t size) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + u32 cnt = 0; + + if (size >= TOMTOM_A_SVASS_SPE_OUTBOX_SIZE) + size = TOMTOM_A_SVASS_SPE_OUTBOX_SIZE - 1; + for (cnt = 0; (cnt < size) && (rc == CPE_SVC_SUCCESS); cnt++) { + rc = cpe_register_read(TOMTOM_A_SVASS_SPE_OUTBOX(cnt), + &(buffer[cnt])); + } + return rc; +} + +static enum cpe_svc_result cpe_tgt_tomtom_write_mailbox(u8 *buffer, + size_t size) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + u32 cnt = 0; + + if (size >= TOMTOM_A_SVASS_SPE_INBOX_SIZE) + size = TOMTOM_A_SVASS_SPE_INBOX_SIZE - 1; + for (cnt = 0; (cnt < size) && (rc == CPE_SVC_SUCCESS); cnt++) { + rc = cpe_register_write(TOMTOM_A_SVASS_SPE_INBOX(cnt), + buffer[cnt]); + } + + if (rc == CPE_SVC_SUCCESS) + rc = cpe_register_write(TOMTOM_A_SVASS_SPE_INBOX_TRG, 1); + + return rc; +} + +static enum cpe_svc_result cpe_get_mem_addr(struct cpe_info *t_info, + const struct cpe_svc_mem_segment *mem_seg, + u32 *addr, u8 *mem) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + u32 offset, mem_sz, address; + u8 mem_type; + + switch (mem_seg->type) { + + case CPE_SVC_DATA_MEM: + mem_type = MEM_ACCESS_DRAM_VAL; + offset = TOMTOM_A_SVASS_SPE_DRAM_OFFSET; + mem_sz = TOMTOM_A_SVASS_SPE_DRAM_SIZE; + break; + + case CPE_SVC_INSTRUCTION_MEM: + mem_type = MEM_ACCESS_IRAM_VAL; + offset = TOMTOM_A_SVASS_SPE_IRAM_OFFSET; + mem_sz = TOMTOM_A_SVASS_SPE_IRAM_SIZE; + break; + + default: + pr_err("%s: Invalid mem type = %u\n", + __func__, mem_seg->type); + return CPE_SVC_INVALID_HANDLE; + } + + if (mem_seg->cpe_addr < offset) { + pr_err("%s: Invalid addr %x for mem type %u\n", + __func__, mem_seg->cpe_addr, mem_type); + return CPE_SVC_INVALID_HANDLE; + } + + address = mem_seg->cpe_addr - offset; + if (address + mem_seg->size > mem_sz) { + pr_err("%s: wrong size %zu, start address %x, mem_type %u\n", + __func__, mem_seg->size, address, mem_type); + return CPE_SVC_INVALID_HANDLE; + } + + (*addr) = address; + (*mem) = mem_type; + + return rc; +} + +static enum cpe_svc_result cpe_tgt_tomtom_read_RAM(struct cpe_info *t_info, + struct cpe_svc_mem_segment *mem_seg) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + u8 mem_reg_val = 0; + u32 cnt = 0; + bool autoinc; + u8 mem = MEM_ACCESS_NONE_VAL; + u32 addr = 0; + u32 ptr_update = true; + + if (!mem_seg) { + pr_err("%s: Invalid mem segment\n", + __func__); + return CPE_SVC_INVALID_HANDLE; + } + + rc = cpe_get_mem_addr(t_info, mem_seg, &addr, &mem); + + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: Cannot obtain address, mem_type %u\n", + __func__, mem_seg->type); + return rc; + } + + rc = cpe_register_write(TOMTOM_A_SVASS_MEM_CTL, 0); + autoinc = cpe_register_read_autoinc_supported(); + if (autoinc) + mem_reg_val |= 0x04; + + mem_reg_val |= 0x08; + mem_reg_val |= mem; + + do { + if (!autoinc || ptr_update) { + rc = cpe_register_write(TOMTOM_A_SVASS_MEM_PTR0, + (addr & 0xFF)); + rc = cpe_register_write(TOMTOM_A_SVASS_MEM_PTR1, + ((addr >> 8) & 0xFF)); + rc = cpe_register_write(TOMTOM_A_SVASS_MEM_PTR2, + ((addr >> 16) & 0xFF)); + + rc = cpe_register_write(TOMTOM_A_SVASS_MEM_CTL, + mem_reg_val); + + ptr_update = false; + } + rc = cpe_register_read(TOMTOM_A_SVASS_MEM_BANK, + &mem_seg->data[cnt]); + + if (!autoinc) + rc = cpe_register_write(TOMTOM_A_SVASS_MEM_CTL, 0); + } while (++cnt < mem_seg->size); + + rc = cpe_register_write(TOMTOM_A_SVASS_MEM_CTL, 0); + + return rc; +} + +static enum cpe_svc_result cpe_tgt_tomtom_write_RAM(struct cpe_info *t_info, + const struct cpe_svc_mem_segment *mem_seg) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + u8 mem_reg_val = 0; + u8 mem = MEM_ACCESS_NONE_VAL; + u32 addr = 0; + u8 *temp_ptr = NULL; + u32 temp_size = 0; + bool autoinc; + + if (!mem_seg) { + pr_err("%s: Invalid mem segment\n", + __func__); + return CPE_SVC_INVALID_HANDLE; + } + + rc = cpe_get_mem_addr(t_info, mem_seg, &addr, &mem); + + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: Cannot obtain address, mem_type %u\n", + __func__, mem_seg->type); + return rc; + } + + autoinc = cpe_register_read_autoinc_supported(); + if (autoinc) + mem_reg_val |= 0x04; + mem_reg_val |= mem; + + rc = cpe_update_bits(TOMTOM_A_SVASS_MEM_CTL, + 0x0F, mem_reg_val); + + rc = cpe_register_write(TOMTOM_A_SVASS_MEM_PTR0, + (addr & 0xFF)); + rc = cpe_register_write(TOMTOM_A_SVASS_MEM_PTR1, + ((addr >> 8) & 0xFF)); + + rc = cpe_register_write(TOMTOM_A_SVASS_MEM_PTR2, + ((addr >> 16) & 0xFF)); + + temp_size = 0; + temp_ptr = mem_seg->data; + + while (temp_size <= mem_seg->size) { + u32 to_write = (mem_seg->size >= temp_size+CHUNK_SIZE) + ? CHUNK_SIZE : (mem_seg->size-temp_size); + + if (t_info->state == CPE_STATE_OFFLINE) { + pr_err("%s: CPE is offline\n", __func__); + return CPE_SVC_FAILED; + } + + cpe_register_write_repeat(TOMTOM_A_SVASS_MEM_BANK, + temp_ptr, to_write); + temp_size += CHUNK_SIZE; + temp_ptr += CHUNK_SIZE; + } + + rc = cpe_register_write(TOMTOM_A_SVASS_MEM_CTL, 0); + return rc; +} + +static enum cpe_svc_result cpe_tgt_tomtom_route_notification( + enum cpe_svc_module module, + enum cpe_svc_route_dest dest) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + u8 ctl_reg_val = 0; + + switch (module) { + case CPE_SVC_LISTEN_PROC: + switch (dest) { + case CPE_SVC_EXTERNAL: + ctl_reg_val = LISTEN_CTL_MSM_VAL; + break; + case CPE_SVC_INTERNAL: + ctl_reg_val = LISTEN_CTL_SPE_VAL; + break; + default: + pr_err("%s: Invalid dest %d\n", + __func__, dest); + return CPE_SVC_FAILED; + } + + rc = cpe_update_bits(TOMTOM_A_SVASS_CFG, + 0x01, ctl_reg_val); + break; + default: + pr_err("%s: Invalid module %d\n", + __func__, module); + rc = CPE_SVC_FAILED; + break; + } + + return rc; +} + +static enum cpe_svc_result cpe_tgt_tomtom_set_debug_mode(u32 enable) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + u8 dbg_reg_val = 0x00; + + if (enable) + dbg_reg_val = 0x08; + rc = cpe_update_bits(TOMTOM_A_SVASS_DEBUG, + 0x08, dbg_reg_val); + return rc; +} + +static const struct cpe_svc_hw_cfg *cpe_tgt_tomtom_get_cpe_info(void) +{ + return &cpe_svc_tomtom_info; +} + +static enum cpe_svc_result cpe_tgt_tomtom_deinit( + struct cpe_svc_tgt_abstraction *param) +{ + kfree(param->inbox); + param->inbox = NULL; + kfree(param->outbox); + param->outbox = NULL; + memset(param, 0, sizeof(struct cpe_svc_tgt_abstraction)); + return CPE_SVC_SUCCESS; +} + +static u8 cpe_tgt_tomtom_waiti_data[] = {0x00, 0x70, 0x00, 0x00}; + +static struct cpe_tgt_waiti_info cpe_tgt_tomtom_waiti_info = { + .tgt_waiti_size = ARRAY_SIZE(cpe_tgt_tomtom_waiti_data), + .tgt_waiti_data = cpe_tgt_tomtom_waiti_data, +}; + +static enum cpe_svc_result cpe_tgt_tomtom_init( + struct cpe_svc_codec_info_v1 *codec_info, + struct cpe_svc_tgt_abstraction *param) +{ + if (!codec_info) + return CPE_SVC_INVALID_HANDLE; + if (!param) + return CPE_SVC_INVALID_HANDLE; + + if (codec_info->id == CPE_SVC_CODEC_TOMTOM) { + param->tgt_boot = cpe_tgt_tomtom_boot; + param->tgt_cpar_init_done = cpe_tgt_tomtom_is_cpar_init_done; + param->tgt_is_active = cpe_tgt_tomtom_is_active; + param->tgt_reset = cpe_tgt_tomtom_reset; + param->tgt_read_mailbox = cpe_tgt_tomtom_read_mailbox; + param->tgt_write_mailbox = cpe_tgt_tomtom_write_mailbox; + param->tgt_read_ram = cpe_tgt_tomtom_read_RAM; + param->tgt_write_ram = cpe_tgt_tomtom_write_RAM; + param->tgt_route_notification = + cpe_tgt_tomtom_route_notification; + param->tgt_set_debug_mode = cpe_tgt_tomtom_set_debug_mode; + param->tgt_get_cpe_info = cpe_tgt_tomtom_get_cpe_info; + param->tgt_deinit = cpe_tgt_tomtom_deinit; + param->tgt_voice_tx_lab = cpe_tgt_tomtom_voicetx; + param->tgt_waiti_info = &cpe_tgt_tomtom_waiti_info; + + param->inbox = kzalloc(TOMTOM_A_SVASS_SPE_INBOX_SIZE, + GFP_KERNEL); + if (!param->inbox) + return CPE_SVC_NO_MEMORY; + + param->outbox = kzalloc(TOMTOM_A_SVASS_SPE_OUTBOX_SIZE, + GFP_KERNEL); + if (!param->outbox) { + kfree(param->inbox); + return CPE_SVC_NO_MEMORY; + } + } + + return CPE_SVC_SUCCESS; +} + +static enum cpe_svc_result cpe_tgt_wcd9335_boot(int debug_mode) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + + if (!debug_mode) + rc |= cpe_update_bits( + WCD9335_CPE_SS_WDOG_CFG, + 0x3f, 0x31); + else + pr_info("%s: CPE in debug mode, WDOG disabled\n", + __func__); + + rc |= cpe_register_write(WCD9335_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD, 19); + rc |= cpe_update_bits(WCD9335_CPE_SS_CPAR_CTL, 0x04, 0x00); + rc |= cpe_update_bits(WCD9335_CPE_SS_CPAR_CTL, 0x02, 0x02); + rc |= cpe_update_bits(WCD9335_CPE_SS_CPAR_CTL, 0x01, 0x01); + + if (unlikely(rc)) { + pr_err("%s: Failed to boot, err = %d\n", + __func__, rc); + rc = CPE_SVC_FAILED; + } + + return rc; +} + +static u32 cpe_tgt_wcd9335_is_cpar_init_done(void) +{ + u8 temp = 0; + + cpe_register_read(WCD9335_CPE_SS_STATUS, &temp); + return temp & 0x1; +} + +static u32 cpe_tgt_wcd9335_is_active(void) +{ + u8 temp = 0; + + cpe_register_read(WCD9335_CPE_SS_STATUS, &temp); + return temp & 0x4; +} + +static enum cpe_svc_result cpe_tgt_wcd9335_reset(void) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + + rc |= cpe_update_bits(WCD9335_CPE_SS_CPAR_CFG, 0x01, 0x00); + + rc |= cpe_register_write( + WCD9335_CODEC_RPM_PWR_CPE_IRAM_SHUTDOWN, 0x00); + rc |= cpe_register_write( + WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN, 0x00); + rc |= cpe_register_write( + WCD9335_CODEC_RPM_PWR_CPE_DRAM0_SHUTDOWN_1, 0x00); + rc |= cpe_register_write( + WCD9335_CODEC_RPM_PWR_CPE_DRAM0_SHUTDOWN_2, 0x00); + + rc |= cpe_update_bits(WCD9335_CPE_SS_CPAR_CTL, 0x04, 0x04); + + if (unlikely(rc)) { + pr_err("%s: failed to reset cpe, err = %d\n", + __func__, rc); + rc = CPE_SVC_FAILED; + } + + return rc; +} + +static enum cpe_svc_result cpe_tgt_wcd9335_read_mailbox(u8 *buffer, + size_t size) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + u32 cnt = 0; + + pr_debug("%s: size=%zd\n", __func__, size); + + if (size > WCD9335_CPE_SS_SPE_OUTBOX_SIZE) + size = WCD9335_CPE_SS_SPE_OUTBOX_SIZE; + + for (cnt = 0; (cnt < size) && (rc == CPE_SVC_SUCCESS); cnt++) + rc = cpe_register_read(WCD9335_CPE_SS_SPE_OUTBOX1(cnt), + &buffer[cnt]); + + rc = cpe_register_write(WCD9335_CPE_SS_OUTBOX1_ACK, 0x01); + + if (unlikely(rc)) { + pr_err("%s: failed to ACK outbox, err = %d\n", + __func__, rc); + rc = CPE_SVC_FAILED; + } + + return rc; +} + +static enum cpe_svc_result cpe_tgt_wcd9335_write_mailbox(u8 *buffer, + size_t size) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + u32 cnt = 0; + + pr_debug("%s: size = %zd\n", __func__, size); + if (size > WCD9335_CPE_SS_SPE_INBOX_SIZE) + size = WCD9335_CPE_SS_SPE_INBOX_SIZE; + for (cnt = 0; (cnt < size) && (rc == CPE_SVC_SUCCESS); cnt++) { + rc |= cpe_register_write(WCD9335_CPE_SS_SPE_INBOX1(cnt), + buffer[cnt]); + } + + if (unlikely(rc)) { + pr_err("%s: Error %d writing mailbox registers\n", + __func__, rc); + return rc; + } + + rc = cpe_register_write(WCD9335_CPE_SS_INBOX1_TRG, 1); + return rc; +} + +static enum cpe_svc_result cpe_wcd9335_get_mem_addr(struct cpe_info *t_info, + const struct cpe_svc_mem_segment *mem_seg, + u32 *addr, u8 *mem) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + u32 offset, mem_sz, address; + u8 mem_type; + + switch (mem_seg->type) { + case CPE_SVC_DATA_MEM: + mem_type = MEM_ACCESS_DRAM_VAL; + offset = WCD9335_CPE_SS_SPE_DRAM_OFFSET; + mem_sz = WCD9335_CPE_SS_SPE_DRAM_SIZE; + break; + + case CPE_SVC_INSTRUCTION_MEM: + mem_type = MEM_ACCESS_IRAM_VAL; + offset = WCD9335_CPE_SS_SPE_IRAM_OFFSET; + mem_sz = WCD9335_CPE_SS_SPE_IRAM_SIZE; + break; + + default: + pr_err("%s: Invalid mem type = %u\n", + __func__, mem_seg->type); + return CPE_SVC_INVALID_HANDLE; + } + + if (mem_seg->cpe_addr < offset) { + pr_err("%s: Invalid addr %x for mem type %u\n", + __func__, mem_seg->cpe_addr, mem_type); + return CPE_SVC_INVALID_HANDLE; + } + + address = mem_seg->cpe_addr - offset; + if (address + mem_seg->size > mem_sz) { + pr_err("%s: wrong size %zu, start address %x, mem_type %u\n", + __func__, mem_seg->size, address, mem_type); + return CPE_SVC_INVALID_HANDLE; + } + + (*addr) = address; + (*mem) = mem_type; + + return rc; +} + +static enum cpe_svc_result cpe_tgt_wcd9335_read_RAM(struct cpe_info *t_info, + struct cpe_svc_mem_segment *mem_seg) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + u8 temp = 0; + u32 cnt = 0; + u8 mem = 0x0; + u32 addr = 0; + u32 lastaddr = 0; + u32 ptr_update = true; + bool autoinc; + + if (!mem_seg) { + pr_err("%s: Invalid buffer\n", __func__); + return CPE_SVC_INVALID_HANDLE; + } + + rc = cpe_wcd9335_get_mem_addr(t_info, mem_seg, &addr, &mem); + + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: Cannot obtain address, mem_type %u\n", + __func__, mem_seg->type); + return rc; + } + + rc |= cpe_register_write(WCD9335_CPE_SS_MEM_CTRL, 0); + autoinc = cpe_register_read_autoinc_supported(); + + if (autoinc) + temp = 0x18; + else + temp = 0x10; + + temp |= mem; + + lastaddr = ~addr; + do { + if (!autoinc || (ptr_update)) { + /* write LSB only if modified */ + if ((lastaddr & 0xFF) != (addr & 0xFF)) + rc |= cpe_register_write( + WCD9335_CPE_SS_MEM_PTR_0, + (addr & 0xFF)); + /* write middle byte only if modified */ + if (((lastaddr >> 8) & 0xFF) != ((addr >> 8) & 0xFF)) + rc |= cpe_register_write( + WCD9335_CPE_SS_MEM_PTR_1, + ((addr>>8) & 0xFF)); + /* write MSB only if modified */ + if (((lastaddr >> 16) & 0xFF) != ((addr >> 16) & 0xFF)) + rc |= cpe_register_write( + WCD9335_CPE_SS_MEM_PTR_2, + ((addr>>16) & 0xFF)); + + rc |= cpe_register_write(WCD9335_CPE_SS_MEM_CTRL, temp); + lastaddr = addr; + addr++; + ptr_update = false; + } + + rc |= cpe_register_read(WCD9335_CPE_SS_MEM_BANK_0, + &mem_seg->data[cnt]); + + if (!autoinc) + rc |= cpe_register_write(WCD9335_CPE_SS_MEM_CTRL, 0); + } while ((++cnt < mem_seg->size) || + (rc != CPE_SVC_SUCCESS)); + + rc |= cpe_register_write(WCD9335_CPE_SS_MEM_CTRL, 0); + + if (rc) + pr_err("%s: Failed to read registers, err = %d\n", + __func__, rc); + + return rc; +} + +static enum cpe_svc_result cpe_tgt_wcd9335_write_RAM(struct cpe_info *t_info, + const struct cpe_svc_mem_segment *mem_seg) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + u8 mem_reg_val = 0; + u8 mem = MEM_ACCESS_NONE_VAL; + u32 addr = 0; + u8 *temp_ptr = NULL; + u32 temp_size = 0; + bool autoinc; + + if (!mem_seg) { + pr_err("%s: Invalid mem segment\n", + __func__); + return CPE_SVC_INVALID_HANDLE; + } + + rc = cpe_wcd9335_get_mem_addr(t_info, mem_seg, &addr, &mem); + + if (rc != CPE_SVC_SUCCESS) { + pr_err("%s: Cannot obtain address, mem_type %u\n", + __func__, mem_seg->type); + return rc; + } + + autoinc = cpe_register_read_autoinc_supported(); + if (autoinc) + mem_reg_val = 0x18; + else + mem_reg_val = 0x10; + + mem_reg_val |= mem; + + rc = cpe_update_bits(WCD9335_CPE_SS_MEM_CTRL, + 0x0F, mem_reg_val); + + rc = cpe_register_write(WCD9335_CPE_SS_MEM_PTR_0, + (addr & 0xFF)); + rc = cpe_register_write(WCD9335_CPE_SS_MEM_PTR_1, + ((addr >> 8) & 0xFF)); + + rc = cpe_register_write(WCD9335_CPE_SS_MEM_PTR_2, + ((addr >> 16) & 0xFF)); + + temp_size = 0; + temp_ptr = mem_seg->data; + + while (temp_size <= mem_seg->size) { + u32 to_write = (mem_seg->size >= temp_size+CHUNK_SIZE) + ? CHUNK_SIZE : (mem_seg->size - temp_size); + + if (t_info->state == CPE_STATE_OFFLINE) { + pr_err("%s: CPE is offline\n", __func__); + return CPE_SVC_FAILED; + } + + cpe_register_write_repeat(WCD9335_CPE_SS_MEM_BANK_0, + temp_ptr, to_write); + temp_size += CHUNK_SIZE; + temp_ptr += CHUNK_SIZE; + } + + rc = cpe_register_write(WCD9335_CPE_SS_MEM_CTRL, 0); + + if (rc) + pr_err("%s: Failed to write registers, err = %d\n", + __func__, rc); + return rc; +} + +static enum cpe_svc_result cpe_tgt_wcd9335_route_notification( + enum cpe_svc_module module, + enum cpe_svc_route_dest dest) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + + pr_debug("%s: Module = %d, Destination = %d\n", + __func__, module, dest); + + switch (module) { + case CPE_SVC_LISTEN_PROC: + switch (dest) { + case CPE_SVC_EXTERNAL: + rc = cpe_update_bits(WCD9335_CPE_SS_CFG, 0x01, 0x01); + break; + case CPE_SVC_INTERNAL: + rc = cpe_update_bits(WCD9335_CPE_SS_CFG, 0x01, 0x00); + break; + default: + pr_err("%s: Invalid destination %d\n", + __func__, dest); + return CPE_SVC_FAILED; + } + break; + default: + pr_err("%s: Invalid module %d\n", + __func__, module); + rc = CPE_SVC_FAILED; + break; + } + return rc; +} + +static enum cpe_svc_result cpe_tgt_wcd9335_set_debug_mode(u32 enable) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + + pr_debug("%s: enable = %s\n", __func__, + (enable) ? "true" : "false"); + + return rc; +} + +static const struct cpe_svc_hw_cfg *cpe_tgt_wcd9335_get_cpe_info(void) +{ + return &cpe_svc_wcd9335_info; +} + +static enum cpe_svc_result +cpe_tgt_wcd9335_deinit(struct cpe_svc_tgt_abstraction *param) +{ + kfree(param->inbox); + param->inbox = NULL; + kfree(param->outbox); + param->outbox = NULL; + memset(param, 0, sizeof(struct cpe_svc_tgt_abstraction)); + + return CPE_SVC_SUCCESS; +} + +static enum cpe_svc_result + cpe_tgt_wcd9335_voicetx(bool enable) +{ + enum cpe_svc_result rc = CPE_SVC_SUCCESS; + u8 val = 0; + + pr_debug("%s: enable = %u\n", __func__, enable); + if (enable) + val = 0x02; + else + val = 0x00; + + rc = cpe_update_bits(WCD9335_CPE_SS_CFG, 0x02, val); + val = 0; + cpe_register_read(WCD9335_CPE_SS_CFG, &val); + + return rc; +} + +static u8 cpe_tgt_wcd9335_waiti_data[] = {0x00, 0x70, 0x00, 0x00}; + +static struct cpe_tgt_waiti_info cpe_tgt_wcd9335_waiti_info = { + .tgt_waiti_size = ARRAY_SIZE(cpe_tgt_wcd9335_waiti_data), + .tgt_waiti_data = cpe_tgt_wcd9335_waiti_data, +}; + +static enum cpe_svc_result cpe_tgt_wcd9335_init( + struct cpe_svc_codec_info_v1 *codec_info, + struct cpe_svc_tgt_abstraction *param) +{ + if (!codec_info) + return CPE_SVC_INVALID_HANDLE; + if (!param) + return CPE_SVC_INVALID_HANDLE; + + if (codec_info->id == CPE_SVC_CODEC_WCD9335) { + param->tgt_boot = cpe_tgt_wcd9335_boot; + param->tgt_cpar_init_done = cpe_tgt_wcd9335_is_cpar_init_done; + param->tgt_is_active = cpe_tgt_wcd9335_is_active; + param->tgt_reset = cpe_tgt_wcd9335_reset; + param->tgt_read_mailbox = cpe_tgt_wcd9335_read_mailbox; + param->tgt_write_mailbox = cpe_tgt_wcd9335_write_mailbox; + param->tgt_read_ram = cpe_tgt_wcd9335_read_RAM; + param->tgt_write_ram = cpe_tgt_wcd9335_write_RAM; + param->tgt_route_notification = + cpe_tgt_wcd9335_route_notification; + param->tgt_set_debug_mode = cpe_tgt_wcd9335_set_debug_mode; + param->tgt_get_cpe_info = cpe_tgt_wcd9335_get_cpe_info; + param->tgt_deinit = cpe_tgt_wcd9335_deinit; + param->tgt_voice_tx_lab = cpe_tgt_wcd9335_voicetx; + param->tgt_waiti_info = &cpe_tgt_wcd9335_waiti_info; + + param->inbox = kzalloc(WCD9335_CPE_SS_SPE_INBOX_SIZE, + GFP_KERNEL); + if (!param->inbox) + return CPE_SVC_NO_MEMORY; + + param->outbox = kzalloc(WCD9335_CPE_SS_SPE_OUTBOX_SIZE, + GFP_KERNEL); + if (!param->outbox) { + kfree(param->inbox); + return CPE_SVC_NO_MEMORY; + } + } + + return CPE_SVC_SUCCESS; +} + +MODULE_DESCRIPTION("WCD CPE Services"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/wcd_cpe_services.h b/sound/soc/codecs/wcd_cpe_services.h new file mode 100644 index 000000000000..68eb61996a69 --- /dev/null +++ b/sound/soc/codecs/wcd_cpe_services.h @@ -0,0 +1,179 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __CPE_SERVICES__ +#define __CPE_SERVICES__ + +#define CPE_IRQ_OUTBOX_IRQ 0x01 +#define CPE_IRQ_MEM_ACCESS_ERROR 0x02 +#define CPE_IRQ_WDOG_BITE 0x04 +#define CPE_IRQ_BUFFER_OVERFLOW 0x08 +#define CPE_IRQ_LAB_OVFUNF 0x10 +#define CPE_IRQ_FLL_LOCK_LOST 0x20 +#define CPE_IRQ_RCO_WDOG_INT 0x40 + +#define EFAILED (MAX_ERRNO - 1) +#define ENOTREADY (MAX_ERRNO - 2) + +#define MAX_SUPPORTED_CLKFREQ 8 +#define CPE_SVC_INIT_PARAM_V1 1 + +enum cpe_svc_result { + CPE_SVC_SUCCESS = 0, + CPE_SVC_FAILED = -EFAILED, + CPE_SVC_NO_MEMORY = -ENOMEM, + CPE_SVC_INVALID_HANDLE = -EINVAL, + CPE_SVC_NOT_READY = -ENOTREADY, + CPE_SVC_SHUTTING_DOWN = -ESHUTDOWN, + CPE_SVC_BUSY = -EBUSY, +}; + +enum cpe_svc_event { + CPE_SVC_CMI_MSG = 0x01, + CPE_SVC_OFFLINE = 0x02, + CPE_SVC_ONLINE = 0x04, + CPE_SVC_BOOT_FAILED = 0x08, + CPE_SVC_READ_COMPLETE = 0x10, + CPE_SVC_READ_ERROR = 0x20, + CPE_SVC_BOOT = 0x40, + CPE_SVC_CMI_CLIENTS_DEREG = 0x100, + CPE_SVC_EVENT_ANCHOR = 0x7FFF +}; + +enum cpe_svc_module { + CPE_SVC_LISTEN_PROC = 1, + CPE_SVC_MODULE_ANCHOR = 0x7F +}; + +enum cpe_svc_route_dest { + CPE_SVC_EXTERNAL = 1, + CPE_SVC_INTERNAL = 2, + CPE_SVC_ROUTE_ANCHOR = 0x7F +}; + +enum cpe_svc_mem_type { + CPE_SVC_DATA_MEM = 1, + CPE_SVC_INSTRUCTION_MEM = 2, + CPE_SVC_IPC_MEM = 3, + CPE_SVC_MEM_TYPE_ANCHOR = 0x7F +}; + +enum cpe_svc_codec_id { + CPE_SVC_CODEC_TOMTOM = 5, + CPE_SVC_CODEC_WCD9335 = 7, + CPE_SVC_CODEC_WCD9326 = 8, + CPE_SVC_CODEC_ID_ANCHOR = 0x7ffffff +}; + +enum cpe_svc_codec_version { + CPE_SVC_CODEC_V1P0 = 1, + CPE_SVC_CODEC_VERSION_ANCHOR = 0x7fffffff +}; + +struct cpe_svc_codec_info_v1 { + u16 major_version;/*must be 1*/ + u16 minor_version;/*must be 0*/ + u32 id; + u32 version; + /*Add 1.1 version fields after this line*/ +}; + +struct cpe_svc_notification { + enum cpe_svc_event event; + enum cpe_svc_result result; + void *payload; + void *private_data; +}; + +struct cpe_svc_msg_payload { + u8 *cmi_msg; +}; + +struct cpe_svc_read_complete { + u8 *buffer; + size_t size; +}; + +struct cpe_svc_boot_event { + u32 debug_address; + size_t debug_buffer_size; + u32 status; +}; + +struct cpe_svc_mem_segment { + enum cpe_svc_mem_type type; + u32 cpe_addr; + size_t size; + u8 *data; +}; + +struct cpe_svc_hw_cfg { + size_t DRAM_size; + u32 DRAM_offset; + size_t IRAM_size; + u32 IRAM_offset; + u8 inbox_size; + u8 outbox_size; +}; + +struct cpe_svc_cfg_clk_plan { + u32 current_clk_feq; + u32 num_clk_freqs; + u32 clk_freqs[MAX_SUPPORTED_CLKFREQ]; +}; + +struct cpe_svc_init_param { + void *context; + u32 version; + void (*query_freq_plans_cb)(void *cdc_priv, + struct cpe_svc_cfg_clk_plan *clk_freq); + void (*change_freq_plan_cb)(void *cdc_priv, + u32 clk_freq); +}; + + +void *cpe_svc_initialize( + void irq_control_callback(u32 enable), + const void *codec_info, void *context); +enum cpe_svc_result cpe_svc_deinitialize(void *cpe_handle); + +void *cpe_svc_register(void *cpe_handle, + void (*notification_callback)( + const struct cpe_svc_notification *parameter), + u32 mask, const char *name); + +enum cpe_svc_result cpe_svc_deregister(void *cpe_handle, void *reg_handle); + +enum cpe_svc_result cpe_svc_download_segment(void *cpe_handle, + const struct cpe_svc_mem_segment *segment); + +enum cpe_svc_result cpe_svc_boot(void *cpe_handle, int debug_mode); + +enum cpe_svc_result cpe_svc_shutdown(void *cpe_handle); + +enum cpe_svc_result cpe_svc_reset(void *cpe_handle); + +enum cpe_svc_result cpe_svc_process_irq(void *cpe_handle, u32 cpe_irq); + +enum cpe_svc_result +cpe_svc_route_notification(void *cpe_handle, enum cpe_svc_module module, + enum cpe_svc_route_dest dest); + +enum cpe_svc_result cpe_svc_ramdump(void *cpe_handle, + struct cpe_svc_mem_segment *buffer); + +enum cpe_svc_result cpe_svc_set_debug_mode(void *cpe_handle, u32 mode); + +const struct cpe_svc_hw_cfg *cpe_svc_get_hw_cfg(void *cpe_handle); +enum cpe_svc_result cpe_svc_toggle_lab(void *cpe_handle, bool enable); +enum cpe_svc_result cpe_svc_ftm_test(void *cpe_handle, u32 *status); +#endif /*__CPE_SERVICES__*/ diff --git a/sound/soc/codecs/wcdcal-hwdep.c b/sound/soc/codecs/wcdcal-hwdep.c new file mode 100644 index 000000000000..31eae69b1f4b --- /dev/null +++ b/sound/soc/codecs/wcdcal-hwdep.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcdcal-hwdep.h" + +const int cal_size_info[WCD9XXX_MAX_CAL] = { + [WCD9XXX_ANC_CAL] = 16384, + [WCD9XXX_MBHC_CAL] = 4096, + [WCD9XXX_MAD_CAL] = 4096, + [WCD9XXX_VBAT_CAL] = 72, +}; + +const char *cal_name_info[WCD9XXX_MAX_CAL] = { + [WCD9XXX_ANC_CAL] = "anc", + [WCD9XXX_MBHC_CAL] = "mbhc", + [WCD9XXX_MAD_CAL] = "mad", + [WCD9XXX_VBAT_CAL] = "vbat", +}; + +struct firmware_cal *wcdcal_get_fw_cal(struct fw_info *fw_data, + enum wcd_cal_type type) +{ + if (!fw_data) { + pr_err("%s: fw_data is NULL\n", __func__); + return NULL; + } + if (type >= WCD9XXX_MAX_CAL || + type < WCD9XXX_MIN_CAL) { + pr_err("%s: wrong cal type sent %d\n", __func__, type); + return NULL; + } + mutex_lock(&fw_data->lock); + if (!test_bit(WCDCAL_RECIEVED, + &fw_data->wcdcal_state[type])) { + pr_err("%s: cal not sent by userspace %d\n", + __func__, type); + mutex_unlock(&fw_data->lock); + return NULL; + } + mutex_unlock(&fw_data->lock); + return fw_data->fw[type]; +} +EXPORT_SYMBOL(wcdcal_get_fw_cal); + +static int wcdcal_hwdep_ioctl_shared(struct snd_hwdep *hw, + struct wcdcal_ioctl_buffer fw_user) +{ + struct fw_info *fw_data = hw->private_data; + struct firmware_cal **fw = fw_data->fw; + void *data; + + if (!test_bit(fw_user.cal_type, fw_data->cal_bit)) { + pr_err("%s: codec didn't set this %d!!\n", + __func__, fw_user.cal_type); + return -EFAULT; + } + if (fw_user.cal_type >= WCD9XXX_MAX_CAL || + fw_user.cal_type < WCD9XXX_MIN_CAL) { + pr_err("%s: wrong cal type sent %d\n", + __func__, fw_user.cal_type); + return -EFAULT; + } + if (fw_user.size > cal_size_info[fw_user.cal_type] || + fw_user.size <= 0) { + pr_err("%s: incorrect firmware size %d for %s\n", + __func__, fw_user.size, + cal_name_info[fw_user.cal_type]); + return -EFAULT; + } + data = fw[fw_user.cal_type]->data; + if (copy_from_user(data, fw_user.buffer, fw_user.size)) + return -EFAULT; + fw[fw_user.cal_type]->size = fw_user.size; + mutex_lock(&fw_data->lock); + set_bit(WCDCAL_RECIEVED, &fw_data->wcdcal_state[fw_user.cal_type]); + mutex_unlock(&fw_data->lock); + return 0; +} + +#ifdef CONFIG_COMPAT +struct wcdcal_ioctl_buffer32 { + u32 size; + compat_uptr_t buffer; + enum wcd_cal_type cal_type; +}; + +enum { + SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE32 = + _IOW('U', 0x1, struct wcdcal_ioctl_buffer32), +}; + +static int wcdcal_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct wcdcal_ioctl_buffer __user *argp = (void __user *)arg; + struct wcdcal_ioctl_buffer32 fw_user32; + struct wcdcal_ioctl_buffer fw_user_compat; + + if (cmd != SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE32) { + pr_err("%s: wrong ioctl command sent %u!\n", __func__, cmd); + return -ENOIOCTLCMD; + } + if (copy_from_user(&fw_user32, argp, sizeof(fw_user32))) { + pr_err("%s: failed to copy\n", __func__); + return -EFAULT; + } + fw_user_compat.size = fw_user32.size; + fw_user_compat.buffer = compat_ptr(fw_user32.buffer); + fw_user_compat.cal_type = fw_user32.cal_type; + return wcdcal_hwdep_ioctl_shared(hw, fw_user_compat); +} +#else +#define wcdcal_hwdep_ioctl_compat NULL +#endif + +static int wcdcal_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct wcdcal_ioctl_buffer __user *argp = (void __user *)arg; + struct wcdcal_ioctl_buffer fw_user; + + if (cmd != SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE) { + pr_err("%s: wrong ioctl command sent %d!\n", __func__, cmd); + return -ENOIOCTLCMD; + } + if (copy_from_user(&fw_user, argp, sizeof(fw_user))) { + pr_err("%s: failed to copy\n", __func__); + return -EFAULT; + } + return wcdcal_hwdep_ioctl_shared(hw, fw_user); +} + +static int wcdcal_hwdep_release(struct snd_hwdep *hw, struct file *file) +{ + struct fw_info *fw_data = hw->private_data; + + mutex_lock(&fw_data->lock); + /* clear all the calibrations */ + memset(fw_data->wcdcal_state, 0, + sizeof(fw_data->wcdcal_state)); + mutex_unlock(&fw_data->lock); + return 0; +} + +int wcd_cal_create_hwdep(void *data, int node, struct snd_soc_codec *codec) +{ + char hwname[40]; + struct snd_hwdep *hwdep; + struct firmware_cal **fw; + struct fw_info *fw_data = data; + int err, cal_bit; + + if (!fw_data || !codec) { + pr_err("%s: wrong arguments passed\n", __func__); + return -EINVAL; + } + + fw = fw_data->fw; + snprintf(hwname, strlen("Codec %s"), "Codec %s", + codec->component.name); + err = snd_hwdep_new(codec->component.card->snd_card, + hwname, node, &hwdep); + if (err < 0) { + dev_err(codec->dev, "%s: new hwdep failed %d\n", + __func__, err); + return err; + } + snprintf(hwdep->name, strlen("Codec %s"), "Codec %s", + codec->component.name); + hwdep->iface = SNDRV_HWDEP_IFACE_AUDIO_CODEC; + hwdep->private_data = fw_data; + hwdep->ops.ioctl_compat = wcdcal_hwdep_ioctl_compat; + hwdep->ops.ioctl = wcdcal_hwdep_ioctl; + hwdep->ops.release = wcdcal_hwdep_release; + mutex_init(&fw_data->lock); + + for_each_set_bit(cal_bit, fw_data->cal_bit, WCD9XXX_MAX_CAL) { + set_bit(WCDCAL_UNINITIALISED, + &fw_data->wcdcal_state[cal_bit]); + fw[cal_bit] = kzalloc(sizeof *(fw[cal_bit]), GFP_KERNEL); + if (!fw[cal_bit]) { + dev_err(codec->dev, "%s: no memory for %s cal\n", + __func__, cal_name_info[cal_bit]); + goto end; + } + } + for_each_set_bit(cal_bit, fw_data->cal_bit, WCD9XXX_MAX_CAL) { + fw[cal_bit]->data = kzalloc(cal_size_info[cal_bit], + GFP_KERNEL); + if (!fw[cal_bit]->data) + goto exit; + set_bit(WCDCAL_INITIALISED, + &fw_data->wcdcal_state[cal_bit]); + } + return 0; +exit: + for_each_set_bit(cal_bit, fw_data->cal_bit, WCD9XXX_MAX_CAL) { + kfree(fw[cal_bit]->data); + fw[cal_bit]->data = NULL; + } +end: + for_each_set_bit(cal_bit, fw_data->cal_bit, WCD9XXX_MAX_CAL) { + kfree(fw[cal_bit]); + fw[cal_bit] = NULL; + } + return -ENOMEM; +} +EXPORT_SYMBOL(wcd_cal_create_hwdep); diff --git a/sound/soc/codecs/wcdcal-hwdep.h b/sound/soc/codecs/wcdcal-hwdep.h new file mode 100644 index 000000000000..632e2f11f323 --- /dev/null +++ b/sound/soc/codecs/wcdcal-hwdep.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __WCD9XXX_HWDEP_H__ +#define __WCD9XXX_HWDEP_H__ +#include + +enum wcd_cal_states { + WCDCAL_UNINITIALISED, + WCDCAL_INITIALISED, + WCDCAL_RECIEVED +}; + +struct fw_info { + struct firmware_cal *fw[WCD9XXX_MAX_CAL]; + DECLARE_BITMAP(cal_bit, WCD9XXX_MAX_CAL); + /* for calibration tracking */ + unsigned long wcdcal_state[WCD9XXX_MAX_CAL]; + struct mutex lock; +}; + +struct firmware_cal { + u8 *data; + size_t size; +}; + +struct snd_soc_codec; +int wcd_cal_create_hwdep(void *fw, int node, struct snd_soc_codec *codec); +struct firmware_cal *wcdcal_get_fw_cal(struct fw_info *fw_data, + enum wcd_cal_type type); +#endif /* __WCD9XXX_HWDEP_H__ */ diff --git a/sound/soc/codecs/wsa881x-analog.c b/sound/soc/codecs/wsa881x-analog.c new file mode 100644 index 000000000000..4de962497765 --- /dev/null +++ b/sound/soc/codecs/wsa881x-analog.c @@ -0,0 +1,1446 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wsa881x-analog.h" +#include "wsa881x-temp-sensor.h" +#include "../msm/msm-audio-pinctrl.h" + +#define SPK_GAIN_12DB 4 +#define WIDGET_NAME_MAX_SIZE 80 + +/* + * Private data Structure for wsa881x. All parameters related to + * WSA881X codec needs to be defined here. + */ +struct wsa881x_pdata { + struct regmap *regmap[2]; + struct i2c_client *client[2]; + struct snd_soc_codec *codec; + + /* track wsa881x status during probe */ + int status; + bool boost_enable; + bool visense_enable; + int spk_pa_gain; + struct i2c_msg xfer_msg[2]; + struct mutex xfer_lock; + bool regmap_flag; + bool wsa_active; + int index; + int (*enable_mclk)(struct snd_soc_card *, bool); + struct wsa881x_tz_priv tz_pdata; + int bg_cnt; + int clk_cnt; + int enable_cnt; + int version; + struct mutex bg_lock; + struct mutex res_lock; + struct delayed_work ocp_ctl_work; +}; + +enum { + WSA881X_STATUS_PROBING, + WSA881X_STATUS_I2C, +}; + +#define WSA881X_OCP_CTL_TIMER_SEC 2 +#define WSA881X_OCP_CTL_TEMP_CELSIUS 25 +#define WSA881X_OCP_CTL_POLL_TIMER_SEC 60 + +static int wsa881x_ocp_poll_timer_sec = WSA881X_OCP_CTL_POLL_TIMER_SEC; +module_param(wsa881x_ocp_poll_timer_sec, int, 0664); +MODULE_PARM_DESC(wsa881x_ocp_poll_timer_sec, "timer for ocp ctl polling"); + +static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec, + bool enable); + +const char *wsa_tz_names[] = {"wsa881x.0e", "wsa881x.0f"}; + +struct wsa881x_pdata wsa_pdata[MAX_WSA881X_DEVICE]; + +static bool pinctrl_init; + +static int wsa881x_populate_dt_pdata(struct device *dev); +static int wsa881x_reset(struct wsa881x_pdata *pdata, bool enable); +static int wsa881x_startup(struct wsa881x_pdata *pdata); +static int wsa881x_shutdown(struct wsa881x_pdata *pdata); + +static int delay_array_msec[] = {10, 20, 30, 40, 50}; + +static int wsa881x_i2c_addr = -1; +static int wsa881x_probing_count; +static int wsa881x_presence_count; + +static const char * const wsa881x_spk_pa_gain_text[] = { +"POS_13P5_DB", "POS_12_DB", "POS_10P5_DB", "POS_9_DB", "POS_7P5_DB", +"POS_6_DB", "POS_4P5_DB", "POS_3_DB", "POS_1P5_DB", "POS_0_DB"}; + +static const struct soc_enum wsa881x_spk_pa_gain_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa881x_spk_pa_gain_text), + wsa881x_spk_pa_gain_text), +}; + +static int wsa881x_spk_pa_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = wsa881x->spk_pa_gain; + + dev_dbg(codec->dev, "%s: spk_pa_gain = %ld\n", __func__, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int wsa881x_spk_pa_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + + if (ucontrol->value.integer.value[0] < 0 || + ucontrol->value.integer.value[0] > 0xC) { + dev_err(codec->dev, "%s: Unsupported gain val %ld\n", + __func__, ucontrol->value.integer.value[0]); + return -EINVAL; + } + wsa881x->spk_pa_gain = ucontrol->value.integer.value[0]; + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int get_i2c_wsa881x_device_index(u16 reg) +{ + u16 mask = 0x0f00; + int value = 0; + + value = ((reg & mask) >> 8) & 0x000f; + + switch (value) { + case 0: + return 0; + case 1: + return 1; + default: + break; + } + return -EINVAL; +} + +static int wsa881x_i2c_write_device(struct wsa881x_pdata *wsa881x, + unsigned int reg, unsigned int val) +{ + int i = 0, rc = 0; + int wsa881x_index; + struct i2c_msg *msg; + int ret = 0; + int bytes = 1; + u8 reg_addr = 0; + u8 data[bytes + 1]; + + wsa881x_index = get_i2c_wsa881x_device_index(reg); + if (wsa881x_index < 0) { + pr_err("%s:invalid register to write\n", __func__); + return -EINVAL; + } + if (wsa881x->regmap_flag) { + rc = regmap_write(wsa881x->regmap[wsa881x_index], reg, val); + for (i = 0; rc && i < ARRAY_SIZE(delay_array_msec); i++) { + pr_err("Failed writing reg=%u - retry(%d)\n", reg, i); + /* retry after delay of increasing order */ + msleep(delay_array_msec[i]); + rc = regmap_write(wsa881x->regmap[wsa881x_index], + reg, val); + } + if (rc) + pr_err("Failed writing reg=%u rc=%d\n", reg, rc); + else + pr_err("write success register = %x val = %x\n", + reg, val); + } else { + reg_addr = (u8)reg; + msg = &wsa881x->xfer_msg[0]; + msg->addr = wsa881x->client[wsa881x_index]->addr; + msg->len = bytes + 1; + msg->flags = 0; + data[0] = reg; + data[1] = (u8)val; + msg->buf = data; + ret = i2c_transfer(wsa881x->client[wsa881x_index]->adapter, + wsa881x->xfer_msg, 1); + /* Try again if the write fails */ + if (ret != 1) { + ret = i2c_transfer( + wsa881x->client[wsa881x_index]->adapter, + wsa881x->xfer_msg, 1); + if (ret != 1) { + pr_err("failed to write the device\n"); + return ret; + } + } + pr_debug("write success reg = %x val = %x\n", reg, data[1]); + } + return rc; +} + +static int wsa881x_i2c_read_device(struct wsa881x_pdata *wsa881x, + unsigned int reg) +{ + int wsa881x_index; + int i = 0, rc = 0; + unsigned int val; + struct i2c_msg *msg; + int ret = 0; + u8 reg_addr = 0; + u8 dest[5]; + + wsa881x_index = get_i2c_wsa881x_device_index(reg); + if (wsa881x_index < 0) { + pr_err("%s:invalid register to read\n", __func__); + return -EINVAL; + } + if (wsa881x->regmap_flag) { + rc = regmap_read(wsa881x->regmap[wsa881x_index], reg, &val); + for (i = 0; rc && i < ARRAY_SIZE(delay_array_msec); i++) { + pr_err("Failed reading reg=%u - retry(%d)\n", reg, i); + /* retry after delay of increasing order */ + msleep(delay_array_msec[i]); + rc = regmap_read(wsa881x->regmap[wsa881x_index], + reg, &val); + } + if (rc) { + pr_err("Failed reading reg=%u rc=%d\n", reg, rc); + return rc; + } + pr_debug("read success reg = %x val = %x\n", + reg, val); + } else { + reg_addr = (u8)reg; + msg = &wsa881x->xfer_msg[0]; + msg->addr = wsa881x->client[wsa881x_index]->addr; + msg->len = 1; + msg->flags = 0; + msg->buf = ®_addr; + + msg = &wsa881x->xfer_msg[1]; + msg->addr = wsa881x->client[wsa881x_index]->addr; + msg->len = 1; + msg->flags = I2C_M_RD; + msg->buf = dest; + ret = i2c_transfer(wsa881x->client[wsa881x_index]->adapter, + wsa881x->xfer_msg, 2); + + /* Try again if read fails first time */ + if (ret != 2) { + ret = i2c_transfer( + wsa881x->client[wsa881x_index]->adapter, + wsa881x->xfer_msg, 2); + if (ret != 2) { + pr_err("failed to read wsa register:%d\n", + reg); + return ret; + } + } + val = dest[0]; + } + return val; +} + +static unsigned int wsa881x_i2c_read(struct snd_soc_codec *codec, + unsigned int reg) +{ + struct wsa881x_pdata *wsa881x; + unsigned int val; + int ret; + + if (codec == NULL) { + pr_err("%s: invalid codec\n", __func__); + return -EINVAL; + } + wsa881x = snd_soc_codec_get_drvdata(codec); + if (!wsa881x->wsa_active) { + ret = snd_soc_cache_read(codec, reg, &val); + if (ret >= 0) + return val; + dev_err(codec->dev, + "cache read failed for reg: 0x%x ret: %d\n", + reg, ret); + return ret; + } + return wsa881x_i2c_read_device(wsa881x, reg); +} + +static int wsa881x_i2c_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val) +{ + struct wsa881x_pdata *wsa881x; + int ret = 0; + + if (codec == NULL) { + pr_err("%s: invalid codec\n", __func__); + return -EINVAL; + } + wsa881x = snd_soc_codec_get_drvdata(codec); + if (!wsa881x->wsa_active) { + ret = snd_soc_cache_write(codec, reg, val); + if (ret != 0) + dev_err(codec->dev, "cache write to %x failed: %d\n", + reg, ret); + return ret; + } + return wsa881x_i2c_write_device(wsa881x, reg, val); +} + +static int wsa881x_i2c_get_client_index(struct i2c_client *client, + int *wsa881x_index) +{ + int ret = 0; + + switch (client->addr) { + case WSA881X_I2C_SPK0_SLAVE0_ADDR: + case WSA881X_I2C_SPK0_SLAVE1_ADDR: + *wsa881x_index = WSA881X_I2C_SPK0_SLAVE0; + break; + case WSA881X_I2C_SPK1_SLAVE0_ADDR: + case WSA881X_I2C_SPK1_SLAVE1_ADDR: + *wsa881x_index = WSA881X_I2C_SPK1_SLAVE0; + break; + default: + ret = -EINVAL; + break; + } + return ret; +} + +static int wsa881x_boost_ctrl(struct snd_soc_codec *codec, bool enable) +{ + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + + pr_debug("%s: enable:%d\n", __func__, enable); + if (enable) { + if (!WSA881X_IS_2_0(wsa881x->version)) { + snd_soc_update_bits(codec, WSA881X_ANA_CTL, + 0x01, 0x01); + snd_soc_update_bits(codec, WSA881X_ANA_CTL, + 0x04, 0x04); + snd_soc_update_bits(codec, WSA881X_BOOST_PS_CTL, + 0x40, 0x00); + snd_soc_update_bits(codec, WSA881X_BOOST_PRESET_OUT1, + 0xF0, 0xB0); + snd_soc_update_bits(codec, WSA881X_BOOST_ZX_CTL, + 0x20, 0x00); + snd_soc_update_bits(codec, WSA881X_BOOST_EN_CTL, + 0x80, 0x80); + } else { + snd_soc_update_bits(codec, WSA881X_BOOST_LOOP_STABILITY, + 0x03, 0x03); + snd_soc_update_bits(codec, WSA881X_BOOST_MISC2_CTL, + 0xFF, 0x14); + snd_soc_update_bits(codec, WSA881X_BOOST_START_CTL, + 0x80, 0x80); + snd_soc_update_bits(codec, WSA881X_BOOST_START_CTL, + 0x03, 0x00); + snd_soc_update_bits(codec, + WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, + 0x0C, 0x04); + snd_soc_update_bits(codec, + WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, + 0x03, 0x00); + snd_soc_update_bits(codec, WSA881X_BOOST_PRESET_OUT1, + 0xF0, 0x70); + snd_soc_update_bits(codec, WSA881X_ANA_CTL, 0x03, 0x01); + snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, + 0x08, 0x08); + snd_soc_update_bits(codec, WSA881X_ANA_CTL, 0x04, 0x04); + snd_soc_update_bits(codec, WSA881X_BOOST_CURRENT_LIMIT, + 0x0F, 0x08); + snd_soc_update_bits(codec, WSA881X_BOOST_EN_CTL, + 0x80, 0x80); + } + /* For WSA8810, start-up time is 1500us as per qcrg sequence */ + usleep_range(1500, 1510); + } else { + /* ENSURE: Class-D amp is shutdown. CLK is still on */ + snd_soc_update_bits(codec, WSA881X_BOOST_EN_CTL, 0x80, 0x00); + /* boost settle time is 1500us as per qcrg sequence */ + usleep_range(1500, 1510); + } + return 0; +} + +static int wsa881x_visense_txfe_ctrl(struct snd_soc_codec *codec, bool enable, + u8 isense1_gain, u8 isense2_gain, + u8 vsense_gain) +{ + u8 value = 0; + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + + pr_debug("%s: enable:%d\n", __func__, enable); + + if (enable) { + if (WSA881X_IS_2_0(wsa881x->version)) { + snd_soc_update_bits(codec, WSA881X_OTP_REG_28, + 0x3F, 0x3A); + snd_soc_update_bits(codec, WSA881X_BONGO_RESRV_REG1, + 0xFF, 0xB2); + snd_soc_update_bits(codec, WSA881X_BONGO_RESRV_REG2, + 0xFF, 0x05); + } + snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_VSENSE_VCM, + 0x08, 0x00); + if (WSA881X_IS_2_0(wsa881x->version)) { + snd_soc_update_bits(codec, WSA881X_SPKR_PROT_ATEST2, + 0x1C, 0x04); + } else { + snd_soc_update_bits(codec, WSA881X_SPKR_PROT_ATEST2, + 0x08, 0x08); + snd_soc_update_bits(codec, WSA881X_SPKR_PROT_ATEST2, + 0x02, 0x02); + } + value = ((isense2_gain << 6) | (isense1_gain << 4) | + (vsense_gain << 3)); + snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_GAIN, + 0xF8, value); + snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_GAIN, + 0x01, 0x01); + } else { + if (WSA881X_IS_2_0(wsa881x->version)) + snd_soc_update_bits(codec, + WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x10, 0x10); + else + snd_soc_update_bits(codec, + WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x08, 0x08); + /* + * 200us sleep is needed after visense txfe disable as per + * HW requirement. + */ + usleep_range(200, 210); + + snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_GAIN, + 0x01, 0x00); + } + return 0; +} + +static int wsa881x_visense_adc_ctrl(struct snd_soc_codec *codec, bool enable) +{ + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + + pr_debug("%s: enable:%d\n", __func__, enable); + if (enable) { + if (!WSA881X_IS_2_0(wsa881x->version)) + snd_soc_update_bits(codec, WSA881X_ADC_SEL_IBIAS, + 0x70, 0x40); + snd_soc_update_bits(codec, WSA881X_ADC_EN_SEL_IBIAS, + 0x07, 0x04); + snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_V, 0x80, 0x80); + snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_I, 0x80, 0x80); + } else { + /* Ensure: Speaker Protection has been stopped */ + snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_V, 0x80, 0x00); + snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_I, 0x80, 0x00); + } + + return 0; +} + +static void wsa881x_bandgap_ctrl(struct snd_soc_codec *codec, bool enable) +{ + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: enable:%d, bg_count:%d\n", __func__, + enable, wsa881x->bg_cnt); + mutex_lock(&wsa881x->bg_lock); + if (enable) { + ++wsa881x->bg_cnt; + if (wsa881x->bg_cnt == 1) { + snd_soc_update_bits(codec, WSA881X_TEMP_OP, + 0x08, 0x08); + /* 400usec sleep is needed as per HW requirement */ + usleep_range(400, 410); + snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x04); + } + } else { + --wsa881x->bg_cnt; + if (wsa881x->bg_cnt <= 0) { + WARN_ON(wsa881x->bg_cnt < 0); + wsa881x->bg_cnt = 0; + snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x00); + snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x08, 0x00); + } + } + mutex_unlock(&wsa881x->bg_lock); +} + +static void wsa881x_clk_ctrl(struct snd_soc_codec *codec, bool enable) +{ + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s:ss enable:%d, clk_count:%d\n", __func__, + enable, wsa881x->clk_cnt); + mutex_lock(&wsa881x->res_lock); + if (enable) { + ++wsa881x->clk_cnt; + if (wsa881x->clk_cnt == 1) { + snd_soc_write(codec, WSA881X_CDC_RST_CTL, 0x02); + snd_soc_write(codec, WSA881X_CDC_RST_CTL, 0x03); + snd_soc_write(codec, WSA881X_CLOCK_CONFIG, 0x01); + snd_soc_write(codec, WSA881X_CDC_DIG_CLK_CTL, 0x01); + snd_soc_write(codec, WSA881X_CDC_ANA_CLK_CTL, 0x01); + } + } else { + --wsa881x->clk_cnt; + if (wsa881x->clk_cnt <= 0) { + WARN_ON(wsa881x->clk_cnt < 0); + wsa881x->clk_cnt = 0; + snd_soc_write(codec, WSA881X_CDC_ANA_CLK_CTL, 0x00); + snd_soc_write(codec, WSA881X_CDC_DIG_CLK_CTL, 0x00); + if (WSA881X_IS_2_0(wsa881x->version)) + snd_soc_update_bits(codec, + WSA881X_CDC_TOP_CLK_CTL, 0x01, 0x00); + } + } + mutex_unlock(&wsa881x->res_lock); +} + +static int wsa881x_rdac_ctrl(struct snd_soc_codec *codec, bool enable) +{ + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + + pr_debug("%s: enable:%d\n", __func__, enable); + if (enable) { + snd_soc_update_bits(codec, WSA881X_ANA_CTL, 0x08, 0x00); + snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, 0x08, 0x08); + snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x20, 0x20); + snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x20, 0x00); + snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x40, 0x40); + snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x80, 0x80); + if (WSA881X_IS_2_0(wsa881x->version)) { + snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_CAL, + 0x01, 0x01); + snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, + 0x30, 0x30); + snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, + 0x0C, 0x00); + } + snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, 0xF0, 0x40); + snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL1, 0x01, 0x01); + } else { + /* Ensure class-D amp is off */ + snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x80, 0x00); + } + return 0; +} + +static int wsa881x_spkr_pa_ctrl(struct snd_soc_codec *codec, bool enable) +{ + int ret = 0; + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + + pr_debug("%s: enable:%d\n", __func__, enable); + if (enable) { + /* + * Ensure: Boost is enabled and stable, Analog input is up + * and outputting silence + */ + if (!WSA881X_IS_2_0(wsa881x->version)) { + snd_soc_update_bits(codec, WSA881X_ADC_EN_DET_TEST_I, + 0xFF, 0x01); + snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_V, + 0x02, 0x02); + snd_soc_update_bits(codec, WSA881X_ADC_EN_DET_TEST_V, + 0xFF, 0x10); + snd_soc_update_bits(codec, WSA881X_SPKR_PWRSTG_DBG, + 0xA0, 0xA0); + snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, + 0x80, 0x80); + usleep_range(700, 710); + snd_soc_update_bits(codec, WSA881X_SPKR_PWRSTG_DBG, + 0x00, 0x00); + snd_soc_update_bits(codec, WSA881X_ADC_EN_DET_TEST_V, + 0xFF, 0x00); + snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_V, + 0x02, 0x00); + snd_soc_update_bits(codec, WSA881X_ADC_EN_DET_TEST_I, + 0xFF, 0x00); + } else + snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, + 0x80, 0x80); + /* add 1000us delay as per qcrg */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, 0x01, 0x01); + if (WSA881X_IS_2_0(wsa881x->version)) + snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_CAL, + 0x01, 0x00); + usleep_range(1000, 1010); + snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, 0xF0, + (wsa881x->spk_pa_gain << 4)); + if (wsa881x->visense_enable) { + ret = msm_gpioset_activate(CLIENT_WSA_BONGO_1, + "wsa_vi"); + if (ret) { + pr_err("%s: gpio set cannot be activated %s\n", + __func__, "wsa_vi"); + return ret; + } + wsa881x_visense_txfe_ctrl(codec, true, + 0x00, 0x01, 0x00); + wsa881x_visense_adc_ctrl(codec, true); + } + } else { + /* + * Ensure: Boost is still on, Stream from Analog input and + * Speaker Protection has been stopped and input is at 0V + */ + if (WSA881X_IS_2_0(wsa881x->version)) { + snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_CAL, + 0x01, 0x01); + usleep_range(1000, 1010); + snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_CAL, + 0x01, 0x00); + msleep(20); + snd_soc_update_bits(codec, WSA881X_ANA_CTL, + 0x03, 0x00); + usleep_range(200, 210); + } + snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, 0x80, 0x00); + } + return 0; +} + +static int wsa881x_get_boost(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = wsa881x->boost_enable; + return 0; +} + +static int wsa881x_set_boost(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + int value = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: Boost enable current %d, new %d\n", + __func__, wsa881x->boost_enable, value); + wsa881x->boost_enable = value; + return 0; +} + +static int wsa881x_get_visense(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = wsa881x->visense_enable; + return 0; +} + +static int wsa881x_set_visense(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + int value = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: VIsense enable current %d, new %d\n", + __func__, wsa881x->visense_enable, value); + wsa881x->visense_enable = value; + return 0; +} + +static const struct snd_kcontrol_new wsa881x_snd_controls[] = { + SOC_SINGLE_EXT("BOOST Switch", SND_SOC_NOPM, 0, 1, 0, + wsa881x_get_boost, wsa881x_set_boost), + + SOC_SINGLE_EXT("VISENSE Switch", SND_SOC_NOPM, 0, 1, 0, + wsa881x_get_visense, wsa881x_set_visense), + + SOC_ENUM_EXT("WSA_SPK PA Gain", wsa881x_spk_pa_gain_enum[0], + wsa881x_spk_pa_gain_get, wsa881x_spk_pa_gain_put), +}; + +static const char * const rdac_text[] = { + "ZERO", "Switch", +}; + +static const struct soc_enum rdac_enum = + SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(rdac_text), rdac_text); + +static const struct snd_kcontrol_new rdac_mux[] = { + SOC_DAPM_ENUM("RDAC", rdac_enum) +}; + +static int wsa881x_rdac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + dev_dbg(codec->dev, "%s: %s %d boost %d visense %d\n", + __func__, w->name, event, + wsa881x->boost_enable, wsa881x->visense_enable); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = wsa881x_startup(wsa881x); + if (ret) { + pr_err("%s: wsa startup failed ret: %d", __func__, ret); + return ret; + } + wsa881x_clk_ctrl(codec, true); + snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x02, 0x02); + if (!WSA881X_IS_2_0(wsa881x->version)) + snd_soc_update_bits(codec, WSA881X_BIAS_REF_CTRL, + 0x0F, 0x08); + wsa881x_bandgap_ctrl(codec, true); + if (!WSA881X_IS_2_0(wsa881x->version)) + snd_soc_update_bits(codec, WSA881X_SPKR_BBM_CTL, + 0x02, 0x02); + snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL1, 0xC0, 0x80); + snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL1, 0x06, 0x06); + if (!WSA881X_IS_2_0(wsa881x->version)) { + snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL2, + 0x04, 0x04); + snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_INT, + 0x09, 0x09); + } + snd_soc_update_bits(codec, WSA881X_SPKR_PA_INT, 0xF0, 0x20); + if (WSA881X_IS_2_0(wsa881x->version)) + snd_soc_update_bits(codec, WSA881X_SPKR_PA_INT, + 0x0E, 0x0E); + if (wsa881x->boost_enable) + wsa881x_boost_ctrl(codec, true); + break; + case SND_SOC_DAPM_POST_PMU: + wsa881x_rdac_ctrl(codec, true); + break; + case SND_SOC_DAPM_PRE_PMD: + wsa881x_rdac_ctrl(codec, false); + if (wsa881x->visense_enable) { + wsa881x_visense_adc_ctrl(codec, false); + wsa881x_visense_txfe_ctrl(codec, false, + 0x00, 0x01, 0x00); + ret = msm_gpioset_suspend(CLIENT_WSA_BONGO_1, + "wsa_vi"); + if (ret) { + pr_err("%s: gpio set cannot be suspended %s\n", + __func__, "wsa_vi"); + return ret; + } + } + break; + case SND_SOC_DAPM_POST_PMD: + if (wsa881x->boost_enable) + wsa881x_boost_ctrl(codec, false); + wsa881x_clk_ctrl(codec, false); + wsa881x_bandgap_ctrl(codec, false); + ret = wsa881x_shutdown(wsa881x); + if (ret < 0) { + pr_err("%s: wsa shutdown failed ret: %d", + __func__, ret); + return ret; + } + break; + default: + pr_err("%s: invalid event:%d\n", __func__, event); + return -EINVAL; + } + return 0; +} + +static void wsa881x_ocp_ctl_work(struct work_struct *work) +{ + struct wsa881x_pdata *wsa881x; + struct delayed_work *dwork; + struct snd_soc_codec *codec; + unsigned long temp_val; + + dwork = to_delayed_work(work); + wsa881x = container_of(dwork, struct wsa881x_pdata, ocp_ctl_work); + + if (!wsa881x) + return; + + codec = wsa881x->codec; + wsa881x_get_temp(wsa881x->tz_pdata.tz_dev, &temp_val); + dev_dbg(codec->dev, " temp = %ld\n", temp_val); + + if (temp_val <= WSA881X_OCP_CTL_TEMP_CELSIUS) + snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0x00); + else + snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0); + + schedule_delayed_work(&wsa881x->ocp_ctl_work, + msecs_to_jiffies(wsa881x_ocp_poll_timer_sec * 1000)); +} + +static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + + pr_debug("%s: %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0x80); + break; + case SND_SOC_DAPM_POST_PMU: + wsa881x_spkr_pa_ctrl(codec, true); + schedule_delayed_work(&wsa881x->ocp_ctl_work, + msecs_to_jiffies(WSA881X_OCP_CTL_TIMER_SEC * 1000)); + break; + case SND_SOC_DAPM_PRE_PMD: + wsa881x_spkr_pa_ctrl(codec, false); + break; + case SND_SOC_DAPM_POST_PMD: + cancel_delayed_work_sync(&wsa881x->ocp_ctl_work); + snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0); + break; + default: + pr_err("%s: invalid event:%d\n", __func__, event); + return -EINVAL; + } + return 0; +} + + +static const struct snd_soc_dapm_widget wsa881x_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("WSA_IN"), + + SND_SOC_DAPM_DAC_E("RDAC Analog", NULL, SND_SOC_NOPM, 0, 0, + wsa881x_rdac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("WSA_RDAC", SND_SOC_NOPM, 0, 0, + rdac_mux), + + SND_SOC_DAPM_PGA_S("WSA_SPKR PGA", 1, SND_SOC_NOPM, 0, 0, + wsa881x_spkr_pa_event, + SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_OUTPUT("WSA_SPKR"), +}; + +static const struct snd_soc_dapm_route wsa881x_audio_map[] = { + {"WSA_RDAC", "Switch", "WSA_IN"}, + {"RDAC Analog", NULL, "WSA_RDAC"}, + {"WSA_SPKR PGA", NULL, "RDAC Analog"}, + {"WSA_SPKR", NULL, "WSA_SPKR PGA"}, +}; + + +static int wsa881x_startup(struct wsa881x_pdata *pdata) +{ + int ret = 0; + struct snd_soc_codec *codec = pdata->codec; + struct snd_soc_card *card = codec->component.card; + + pr_debug("%s(): wsa startup, enable_cnt:%d\n", __func__, + pdata->enable_cnt); + + if (pdata->enable_cnt++ > 0) + return 0; + ret = msm_gpioset_activate(CLIENT_WSA_BONGO_1, "wsa_clk"); + if (ret) { + pr_err("%s: gpio set cannot be activated %s\n", + __func__, "wsa_clk"); + return ret; + } + if (pdata->enable_mclk) { + ret = pdata->enable_mclk(card, true); + if (ret < 0) { + dev_err_ratelimited(codec->dev, + "%s: mclk enable failed %d\n", + __func__, ret); + return ret; + } + } + ret = wsa881x_reset(pdata, true); + return ret; +} + +static int wsa881x_shutdown(struct wsa881x_pdata *pdata) +{ + int ret = 0, reg; + struct snd_soc_codec *codec = pdata->codec; + struct snd_soc_card *card = codec->component.card; + + pr_debug("%s(): wsa shutdown, enable_cnt:%d\n", __func__, + pdata->enable_cnt); + if (--pdata->enable_cnt > 0) + return 0; + ret = wsa881x_reset(pdata, false); + if (ret) { + pr_err("%s: wsa reset failed suspend %d\n", + __func__, ret); + return ret; + } + + if (pdata->enable_mclk) { + ret = pdata->enable_mclk(card, false); + if (ret < 0) { + pr_err("%s: mclk disable failed %d\n", + __func__, ret); + return ret; + } + } + + ret = msm_gpioset_suspend(CLIENT_WSA_BONGO_1, "wsa_clk"); + if (ret) { + pr_err("%s: gpio set cannot be suspended %s\n", + __func__, "wsa_clk"); + return ret; + } + if (pdata->codec) { + /* restore defaults to cache */ + for (reg = 0; reg < ARRAY_SIZE(wsa881x_ana_reg_defaults); + reg++) { + if (wsa881x_ana_reg_readable[reg]) + snd_soc_cache_write(pdata->codec, + wsa881x_ana_reg_defaults[reg].reg, + wsa881x_ana_reg_defaults[reg].def); + } + } + return 0; +} + +static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec, + bool enable) +{ + int ret = 0; + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + + if (enable) { + ret = wsa881x_startup(wsa881x); + if (ret < 0) { + dev_err_ratelimited(codec->dev, + "%s: failed to startup\n", __func__); + return ret; + } + } + wsa881x_clk_ctrl(codec, enable); + wsa881x_bandgap_ctrl(codec, enable); + if (!enable) { + ret = wsa881x_shutdown(wsa881x); + if (ret < 0) + dev_err_ratelimited(codec->dev, + "%s: failed to shutdown\n", __func__); + } + return ret; +} + +static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec, + struct wsa_temp_register *wsa_temp_reg) +{ + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + if (!wsa881x) { + dev_err(codec->dev, "%s: wsa881x is NULL\n", __func__); + return -EINVAL; + } + ret = wsa881x_resource_acquire(codec, true); + if (ret) { + dev_err_ratelimited(codec->dev, + "%s: resource acquire fail\n", __func__); + return ret; + } + + if (WSA881X_IS_2_0(wsa881x->version)) { + snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x00); + wsa_temp_reg->dmeas_msb = snd_soc_read(codec, WSA881X_TEMP_MSB); + wsa_temp_reg->dmeas_lsb = snd_soc_read(codec, WSA881X_TEMP_LSB); + snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x01); + } else { + wsa_temp_reg->dmeas_msb = snd_soc_read(codec, + WSA881X_TEMP_DOUT_MSB); + wsa_temp_reg->dmeas_lsb = snd_soc_read(codec, + WSA881X_TEMP_DOUT_LSB); + } + wsa_temp_reg->d1_msb = snd_soc_read(codec, WSA881X_OTP_REG_1); + wsa_temp_reg->d1_lsb = snd_soc_read(codec, WSA881X_OTP_REG_2); + wsa_temp_reg->d2_msb = snd_soc_read(codec, WSA881X_OTP_REG_3); + wsa_temp_reg->d2_lsb = snd_soc_read(codec, WSA881X_OTP_REG_4); + + ret = wsa881x_resource_acquire(codec, false); + if (ret) + dev_err_ratelimited(codec->dev, + "%s: resource release fail\n", __func__); + + return ret; +} + +static int wsa881x_probe(struct snd_soc_codec *codec) +{ + struct i2c_client *client; + int ret = 0; + int wsa881x_index = 0; + struct snd_soc_dapm_context *dapm = &codec->dapm; + char *widget_name = NULL; + struct snd_soc_card *card = codec->component.card; + struct snd_soc_codec_conf *codec_conf = card->codec_conf; + + client = dev_get_drvdata(codec->dev); + ret = wsa881x_i2c_get_client_index(client, &wsa881x_index); + if (ret != 0) { + dev_err(&client->dev, "%s: I2C get codec I2C\n" + "client failed\n", __func__); + return ret; + } + mutex_init(&wsa_pdata[wsa881x_index].bg_lock); + mutex_init(&wsa_pdata[wsa881x_index].res_lock); + snprintf(wsa_pdata[wsa881x_index].tz_pdata.name, 100, "%s", + wsa_tz_names[wsa881x_index]); + wsa_pdata[wsa881x_index].codec = codec; + wsa_pdata[wsa881x_index].spk_pa_gain = SPK_GAIN_12DB; + wsa_pdata[wsa881x_index].codec = codec; + wsa_pdata[wsa881x_index].tz_pdata.codec = codec; + wsa_pdata[wsa881x_index].tz_pdata.wsa_temp_reg_read = + wsa881x_temp_reg_read; + snd_soc_codec_set_drvdata(codec, &wsa_pdata[wsa881x_index]); + wsa881x_init_thermal(&wsa_pdata[wsa881x_index].tz_pdata); + INIT_DELAYED_WORK(&wsa_pdata[wsa881x_index].ocp_ctl_work, + wsa881x_ocp_ctl_work); + + if (codec_conf->name_prefix) { + widget_name = kcalloc(WIDGET_NAME_MAX_SIZE, sizeof(char), + GFP_KERNEL); + if (!widget_name) + return -ENOMEM; + + snprintf(widget_name, WIDGET_NAME_MAX_SIZE, + "%s WSA_SPKR", codec_conf->name_prefix); + snd_soc_dapm_ignore_suspend(dapm, widget_name); + snprintf(widget_name, WIDGET_NAME_MAX_SIZE, + "%s WSA_IN", codec_conf->name_prefix); + snd_soc_dapm_ignore_suspend(dapm, widget_name); + kfree(widget_name); + } else { + snd_soc_dapm_ignore_suspend(dapm, "WSA_SPKR"); + snd_soc_dapm_ignore_suspend(dapm, "WSA_IN"); + } + + snd_soc_dapm_sync(dapm); + return 0; +} + +static int wsa881x_remove(struct snd_soc_codec *codec) +{ + struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + + if (wsa881x->tz_pdata.tz_dev) + wsa881x_deinit_thermal(wsa881x->tz_pdata.tz_dev); + + mutex_destroy(&wsa881x->bg_lock); + mutex_destroy(&wsa881x->res_lock); + return 0; +} + +static struct snd_soc_codec_driver soc_codec_dev_wsa881x = { + .probe = wsa881x_probe, + .remove = wsa881x_remove, + + .read = wsa881x_i2c_read, + .write = wsa881x_i2c_write, + + .reg_cache_size = WSA881X_CACHE_SIZE, + .reg_cache_default = wsa881x_ana_reg_defaults, + .reg_word_size = 1, + + .component_driver = { + .controls = wsa881x_snd_controls, + .num_controls = ARRAY_SIZE(wsa881x_snd_controls), + .dapm_widgets = wsa881x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wsa881x_dapm_widgets), + .dapm_routes = wsa881x_audio_map, + .num_dapm_routes = ARRAY_SIZE(wsa881x_audio_map), + }, +}; + +static int wsa881x_reset(struct wsa881x_pdata *pdata, bool enable) +{ + int ret = 0; + + /* + * shutdown the GPIOs WSA_EN, WSA_MCLK, regulators + * and restore defaults in soc cache when shutdown. + * Enable regulators, GPIOs WSA_MCLK, WSA_EN when powerup. + */ + if (enable) { + if (pdata->wsa_active) + return 0; + ret = msm_gpioset_activate(CLIENT_WSA_BONGO_1, "wsa_reset"); + if (ret) { + pr_err("%s: gpio set cannot be activated %s\n", + __func__, "wsa_reset"); + return ret; + } + ret = msm_gpioset_suspend(CLIENT_WSA_BONGO_1, "wsa_reset"); + if (ret) { + pr_err("%s: gpio set cannot be suspended(powerup) %s\n", + __func__, "wsa_reset"); + return ret; + } + ret = msm_gpioset_activate(CLIENT_WSA_BONGO_1, "wsa_reset"); + if (ret) { + pr_err("%s: gpio set cannot be activated %s\n", + __func__, "wsa_reset"); + return ret; + } + pdata->wsa_active = true; + } else { + if (!pdata->wsa_active) + return 0; + ret = msm_gpioset_suspend(CLIENT_WSA_BONGO_1, "wsa_reset"); + if (ret) { + pr_err("%s: gpio set cannot be suspended %s\n", + __func__, "wsa_reset"); + return ret; + } + pdata->wsa_active = false; + } + return ret; +} + +int wsa881x_get_client_index(void) +{ + return wsa881x_i2c_addr; +} +EXPORT_SYMBOL(wsa881x_get_client_index); + +int wsa881x_get_probing_count(void) +{ + return wsa881x_probing_count; +} +EXPORT_SYMBOL(wsa881x_get_probing_count); + +int wsa881x_get_presence_count(void) +{ + return wsa881x_presence_count; +} +EXPORT_SYMBOL(wsa881x_get_presence_count); + +int wsa881x_set_mclk_callback( + int (*enable_mclk_callback)(struct snd_soc_card *, bool)) +{ + int i; + + for (i = 0; i < MAX_WSA881X_DEVICE; i++) { + if (wsa_pdata[i].status == WSA881X_STATUS_I2C) + wsa_pdata[i].enable_mclk = enable_mclk_callback; + } + return 0; +} +EXPORT_SYMBOL(wsa881x_set_mclk_callback); + +static int check_wsa881x_presence(struct i2c_client *client) +{ + int ret = 0; + int wsa881x_index = 0; + + ret = wsa881x_i2c_get_client_index(client, &wsa881x_index); + if (ret != 0) { + dev_err(&client->dev, "%s: I2C get codec I2C\n" + "client failed\n", __func__); + return ret; + } + ret = wsa881x_i2c_read_device(&wsa_pdata[wsa881x_index], + WSA881X_CDC_RST_CTL); + if (ret < 0) { + dev_err(&client->dev, "failed to read wsa881x with addr %x\n", + client->addr); + return ret; + } + ret = wsa881x_i2c_write_device(&wsa_pdata[wsa881x_index], + WSA881X_CDC_RST_CTL, 0x01); + if (ret < 0) { + dev_err(&client->dev, "failed write addr %x reg:0x5 val:0x1\n", + client->addr); + return ret; + } + /* allow 20ms before trigger next write to verify WSA881x presence */ + msleep(20); + ret = wsa881x_i2c_write_device(&wsa_pdata[wsa881x_index], + WSA881X_CDC_RST_CTL, 0x00); + if (ret < 0) { + dev_err(&client->dev, "failed write addr %x reg:0x5 val:0x0\n", + client->addr); + return ret; + } + return ret; +} + +static int wsa881x_populate_dt_pdata(struct device *dev) +{ + int ret = 0; + + /* reading the gpio configurations from dtsi file */ + if (!pinctrl_init) { + ret = msm_gpioset_initialize(CLIENT_WSA_BONGO_1, dev); + if (ret < 0) { + dev_err(dev, + "%s: error reading dtsi files%d\n", __func__, ret); + goto err; + } + pinctrl_init = true; + } +err: + return ret; +} + +static int wsa881x_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret = 0; + int wsa881x_index = 0; + struct wsa881x_pdata *pdata = NULL; + + ret = wsa881x_i2c_get_client_index(client, &wsa881x_index); + if (ret != 0) { + dev_err(&client->dev, "%s: I2C get codec I2C\n" + "client failed\n", __func__); + return ret; + } + + pdata = &wsa_pdata[wsa881x_index]; + + if ((client->addr == WSA881X_I2C_SPK0_SLAVE1_ADDR || + client->addr == WSA881X_I2C_SPK1_SLAVE1_ADDR) && + (pdata->status == WSA881X_STATUS_PROBING)) + return ret; + + if (pdata->status == WSA881X_STATUS_I2C) { + dev_dbg(&client->dev, "%s:probe for other slaves\n" + "devices of codec I2C slave Addr = %x\n", + __func__, client->addr); + + dev_dbg(&client->dev, "%s:wsa_idx = %d SLAVE = %d\n", + __func__, wsa881x_index, WSA881X_ANALOG_SLAVE); + pdata->regmap[WSA881X_ANALOG_SLAVE] = + devm_regmap_init_i2c( + client, + &wsa881x_ana_regmap_config[WSA881X_ANALOG_SLAVE]); + regcache_cache_bypass(pdata->regmap[WSA881X_ANALOG_SLAVE], + true); + if (IS_ERR(pdata->regmap[WSA881X_ANALOG_SLAVE])) { + ret = PTR_ERR(pdata->regmap[WSA881X_ANALOG_SLAVE]); + dev_err(&client->dev, + "%s: regmap_init failed %d\n", + __func__, ret); + } + client->dev.platform_data = pdata; + i2c_set_clientdata(client, pdata); + pdata->client[WSA881X_ANALOG_SLAVE] = client; + if (pdata->version == WSA881X_2_0) + wsa881x_update_regmap_2_0( + pdata->regmap[WSA881X_ANALOG_SLAVE], + WSA881X_ANALOG_SLAVE); + + return ret; + } else if (pdata->status == WSA881X_STATUS_PROBING) { + pdata->index = wsa881x_index; + if (client->dev.of_node) { + dev_dbg(&client->dev, "%s:Platform data\n" + "from device tree\n", __func__); + ret = wsa881x_populate_dt_pdata(&client->dev); + if (ret < 0) { + dev_err(&client->dev, + "%s: Fail to obtain pdata from device tree\n", + __func__); + ret = -EINVAL; + goto err; + } + client->dev.platform_data = pdata; + } else { + dev_dbg(&client->dev, "%s:Platform data from\n" + "board file\n", __func__); + pdata = client->dev.platform_data; + } + if (!pdata) { + dev_dbg(&client->dev, "no platform data?\n"); + ret = -EINVAL; + goto err; + } + i2c_set_clientdata(client, pdata); + dev_set_drvdata(&client->dev, client); + + pdata->regmap[WSA881X_DIGITAL_SLAVE] = + devm_regmap_init_i2c( + client, + &wsa881x_ana_regmap_config[WSA881X_DIGITAL_SLAVE]); + regcache_cache_bypass(pdata->regmap[WSA881X_DIGITAL_SLAVE], + true); + if (IS_ERR(pdata->regmap[WSA881X_DIGITAL_SLAVE])) { + ret = PTR_ERR(pdata->regmap[WSA881X_DIGITAL_SLAVE]); + dev_err(&client->dev, "%s: regmap_init failed %d\n", + __func__, ret); + goto err; + } + /* bus reset sequence */ + ret = wsa881x_reset(pdata, true); + if (ret < 0) { + dev_err(&client->dev, "%s: WSA enable Failed %d\n", + __func__, ret); + goto err; + } + pdata->client[WSA881X_DIGITAL_SLAVE] = client; + pdata->regmap_flag = true; + ret = check_wsa881x_presence(client); + if (ret < 0) { + dev_err(&client->dev, + "failed to ping wsa with addr:%x, ret = %d\n", + client->addr, ret); + wsa881x_probing_count++; + goto err1; + } + pdata->version = wsa881x_i2c_read_device(pdata, + WSA881X_CHIP_ID1); + pr_debug("%s: wsa881x version: %d\n", __func__, pdata->version); + if (pdata->version == WSA881X_2_0) { + wsa881x_update_reg_defaults_2_0(); + wsa881x_update_regmap_2_0( + pdata->regmap[WSA881X_DIGITAL_SLAVE], + WSA881X_DIGITAL_SLAVE); + } + wsa881x_presence_count++; + wsa881x_probing_count++; + ret = snd_soc_register_codec(&client->dev, + &soc_codec_dev_wsa881x, + NULL, 0); + if (ret < 0) + goto err1; + pdata->status = WSA881X_STATUS_I2C; + } +err1: + wsa881x_reset(pdata, false); +err: + return 0; +} + +static int wsa881x_i2c_remove(struct i2c_client *client) +{ + struct wsa881x_pdata *wsa881x = i2c_get_clientdata(client); + + snd_soc_unregister_codec(&client->dev); + i2c_set_clientdata(client, NULL); + kfree(wsa881x); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int wsa881x_i2c_suspend(struct device *dev) +{ + pr_debug("%s: system suspend\n", __func__); + return 0; +} + +static int wsa881x_i2c_resume(struct device *dev) +{ + pr_debug("%s: system resume\n", __func__); + return 0; +} + +static const struct dev_pm_ops wsa881x_i2c_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(wsa881x_i2c_suspend, wsa881x_i2c_resume) +}; +#endif /* CONFIG_PM_SLEEP */ + +static const struct i2c_device_id wsa881x_i2c_id[] = { + {"wsa881x-i2c-dev", WSA881X_I2C_SPK0_SLAVE0_ADDR}, + {"wsa881x-i2c-dev", WSA881X_I2C_SPK0_SLAVE1_ADDR}, + {"wsa881x-i2c-dev", WSA881X_I2C_SPK1_SLAVE0_ADDR}, + {"wsa881x-i2c-dev", WSA881X_I2C_SPK1_SLAVE1_ADDR}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, wsa881x_i2c_id); + + +static const struct of_device_id msm_match_table[] = { + {.compatible = "qcom,wsa881x-i2c-codec"}, + {} +}; +MODULE_DEVICE_TABLE(of, msm_match_table); + +static struct i2c_driver wsa881x_codec_driver = { + .driver = { + .name = "wsa881x-i2c-codec", + .owner = THIS_MODULE, +#ifdef CONFIG_PM_SLEEP + .pm = &wsa881x_i2c_pm_ops, +#endif + .of_match_table = msm_match_table, + }, + .id_table = wsa881x_i2c_id, + .probe = wsa881x_i2c_probe, + .remove = wsa881x_i2c_remove, +}; + +static int __init wsa881x_codec_init(void) +{ + int i = 0; + + for (i = 0; i < MAX_WSA881X_DEVICE; i++) + wsa_pdata[i].status = WSA881X_STATUS_PROBING; + return i2c_add_driver(&wsa881x_codec_driver); +} +module_init(wsa881x_codec_init); + +static void __exit wsa881x_codec_exit(void) +{ + i2c_del_driver(&wsa881x_codec_driver); +} + +module_exit(wsa881x_codec_exit); + +MODULE_DESCRIPTION("WSA881x Codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/wsa881x-analog.h b/sound/soc/codecs/wsa881x-analog.h new file mode 100644 index 000000000000..a2ef2a284c23 --- /dev/null +++ b/sound/soc/codecs/wsa881x-analog.h @@ -0,0 +1,50 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _WSA881X_H +#define _WSA881X_H + +#include +#include "wsa881x-registers-analog.h" +#include + +#define WSA881X_I2C_SPK0_SLAVE0_ADDR 0x0E +#define WSA881X_I2C_SPK0_SLAVE1_ADDR 0x44 +#define WSA881X_I2C_SPK1_SLAVE0_ADDR 0x0F +#define WSA881X_I2C_SPK1_SLAVE1_ADDR 0x45 + +#define WSA881X_I2C_SPK0_SLAVE0 0 +#define WSA881X_I2C_SPK1_SLAVE0 1 +#define MAX_WSA881X_DEVICE 2 +#define WSA881X_DIGITAL_SLAVE 0 +#define WSA881X_ANALOG_SLAVE 1 + +enum { + WSA881X_1_X = 0, + WSA881X_2_0, +}; + +#define WSA881X_IS_2_0(ver) \ + ((ver == WSA881X_2_0) ? 1 : 0) + +extern const u8 wsa881x_ana_reg_readable[WSA881X_CACHE_SIZE]; +extern struct reg_default wsa881x_ana_reg_defaults[WSA881X_CACHE_SIZE]; +extern struct regmap_config wsa881x_ana_regmap_config[2]; +int wsa881x_get_client_index(void); +int wsa881x_get_probing_count(void); +int wsa881x_get_presence_count(void); +int wsa881x_set_mclk_callback( + int (*enable_mclk_callback)(struct snd_soc_card *, bool)); +void wsa881x_update_reg_defaults_2_0(void); +void wsa881x_update_regmap_2_0(struct regmap *regmap, int flag); + +#endif /* _WSA881X_H */ diff --git a/sound/soc/codecs/wsa881x-irq.c b/sound/soc/codecs/wsa881x-irq.c new file mode 100644 index 000000000000..9afbd92b8f72 --- /dev/null +++ b/sound/soc/codecs/wsa881x-irq.c @@ -0,0 +1,610 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wsa881x-irq.h" +#include "wsa881x-registers-analog.h" + +#define BYTE_BIT_MASK(nr) (1UL << ((nr) % BITS_PER_BYTE)) +#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE) + + +#define WSA_MAX_NUM_IRQS 8 + +#ifndef NO_IRQ +#define NO_IRQ (-1) +#endif + +static int virq_to_phyirq( + struct wsa_resource *wsa_res, int virq); +static int phyirq_to_virq( + struct wsa_resource *wsa_res, int irq); +static unsigned int wsa_irq_get_upstream_irq( + struct wsa_resource *wsa_res); +static void wsa_irq_put_upstream_irq( + struct wsa_resource *wsa_res); +static int wsa_map_irq( + struct wsa_resource *wsa_res, int irq); + +static struct snd_soc_codec *ptr_codec; + +/** + * wsa_set_codec() - to update codec pointer + * @codec: codec pointer. + * + * To update the codec pointer, which is used to read/write + * wsa register. + * + * Return: void. + */ +void wsa_set_codec(struct snd_soc_codec *codec) +{ + if (codec == NULL) { + pr_err("%s: codec pointer is NULL\n", __func__); + ptr_codec = NULL; + return; + } + ptr_codec = codec; + /* Initialize interrupt mask and level registers */ + snd_soc_write(codec, WSA881X_INTR_LEVEL, 0x8F); + snd_soc_write(codec, WSA881X_INTR_MASK, 0x8F); +} + +static void wsa_irq_lock(struct irq_data *data) +{ + struct wsa_resource *wsa_res = + irq_data_get_irq_chip_data(data); + + if (wsa_res == NULL) { + pr_err("%s: wsa_res pointer is NULL\n", __func__); + return; + } + mutex_lock(&wsa_res->irq_lock); +} + +static void wsa_irq_sync_unlock(struct irq_data *data) +{ + struct wsa_resource *wsa_res = + irq_data_get_irq_chip_data(data); + + if (wsa_res == NULL) { + pr_err("%s: wsa_res pointer is NULL\n", __func__); + return; + } + if (wsa_res->codec == NULL) { + pr_err("%s: codec pointer not registered\n", __func__); + if (ptr_codec == NULL) { + pr_err("%s: did not receive valid codec pointer\n", + __func__); + goto unlock; + } else { + wsa_res->codec = ptr_codec; + } + } + + /* + * If there's been a change in the mask write it back + * to the hardware. + */ + if (wsa_res->irq_masks_cur != + wsa_res->irq_masks_cache) { + + wsa_res->irq_masks_cache = + wsa_res->irq_masks_cur; + snd_soc_write(wsa_res->codec, + WSA881X_INTR_MASK, + wsa_res->irq_masks_cur); + } +unlock: + mutex_unlock(&wsa_res->irq_lock); +} + +static void wsa_irq_enable(struct irq_data *data) +{ + struct wsa_resource *wsa_res = + irq_data_get_irq_chip_data(data); + int wsa_irq; + + if (wsa_res == NULL) { + pr_err("%s: wsa_res pointer is NULL\n", __func__); + return; + } + wsa_irq = virq_to_phyirq(wsa_res, data->irq); + pr_debug("%s: wsa_irq = %d\n", __func__, wsa_irq); + wsa_res->irq_masks_cur &= + ~(BYTE_BIT_MASK(wsa_irq)); +} + +static void wsa_irq_disable(struct irq_data *data) +{ + struct wsa_resource *wsa_res = + irq_data_get_irq_chip_data(data); + int wsa_irq; + + if (wsa_res == NULL) { + pr_err("%s: wsa_res pointer is NULL\n", __func__); + return; + } + wsa_irq = virq_to_phyirq(wsa_res, data->irq); + pr_debug("%s: wsa_irq = %d\n", __func__, wsa_irq); + wsa_res->irq_masks_cur + |= BYTE_BIT_MASK(wsa_irq); +} + +static void wsa_irq_ack(struct irq_data *data) +{ + int wsa_irq = 0; + struct wsa_resource *wsa_res = + irq_data_get_irq_chip_data(data); + + if (wsa_res == NULL) { + pr_err("%s: wsa_res is NULL\n", __func__); + return; + } + wsa_irq = virq_to_phyirq(wsa_res, data->irq); + pr_debug("%s: IRQ_ACK called for WCD9XXX IRQ: %d\n", + __func__, wsa_irq); +} + +static void wsa_irq_mask(struct irq_data *d) +{ + /* do nothing but required as linux calls irq_mask without NULL check */ +} + +static struct irq_chip wsa_irq_chip = { + .name = "wsa", + .irq_bus_lock = wsa_irq_lock, + .irq_bus_sync_unlock = wsa_irq_sync_unlock, + .irq_disable = wsa_irq_disable, + .irq_enable = wsa_irq_enable, + .irq_mask = wsa_irq_mask, + .irq_ack = wsa_irq_ack, +}; + +static irqreturn_t wsa_irq_thread(int irq, void *data) +{ + struct wsa_resource *wsa_res = data; + int i; + u8 status; + + if (wsa_res == NULL) { + pr_err("%s: wsa_res is NULL\n", __func__); + return IRQ_HANDLED; + } + if (wsa_res->codec == NULL) { + pr_err("%s: codec pointer not registered\n", __func__); + if (ptr_codec == NULL) { + pr_err("%s: did not receive valid codec pointer\n", + __func__); + return IRQ_HANDLED; + } + wsa_res->codec = ptr_codec; + } + status = snd_soc_read(wsa_res->codec, WSA881X_INTR_STATUS); + /* Apply masking */ + status &= ~wsa_res->irq_masks_cur; + + for (i = 0; i < wsa_res->num_irqs; i++) { + if (status & BYTE_BIT_MASK(i)) { + mutex_lock(&wsa_res->nested_irq_lock); + handle_nested_irq(phyirq_to_virq(wsa_res, i)); + mutex_unlock(&wsa_res->nested_irq_lock); + } + } + + return IRQ_HANDLED; +} + +/** + * wsa_free_irq() - to free an interrupt + * @irq: interrupt number. + * @data: pointer to wsa resource. + * + * To free already requested interrupt. + * + * Return: void. + */ +void wsa_free_irq(int irq, void *data) +{ + struct wsa_resource *wsa_res = data; + + if (wsa_res == NULL) { + pr_err("%s: wsa_res is NULL\n", __func__); + return; + } + free_irq(phyirq_to_virq(wsa_res, irq), data); +} + +/** + * wsa_enable_irq() - to enable an interrupt + * @wsa_res: pointer to wsa resource. + * @irq: interrupt number. + * + * This function is to enable an interrupt. + * + * Return: void. + */ +void wsa_enable_irq(struct wsa_resource *wsa_res, int irq) +{ + if (wsa_res == NULL) { + pr_err("%s: wsa_res is NULL\n", __func__); + return; + } + enable_irq(phyirq_to_virq(wsa_res, irq)); +} + +/** + * wsa_disable_irq() - to disable an interrupt + * @wsa_res: pointer to wsa resource. + * @irq: interrupt number. + * + * To disable an interrupt without waiting for executing + * handler to complete. + * + * Return: void. + */ +void wsa_disable_irq(struct wsa_resource *wsa_res, int irq) +{ + if (wsa_res == NULL) { + pr_err("%s: wsa_res is NULL\n", __func__); + return; + } + disable_irq_nosync(phyirq_to_virq(wsa_res, irq)); +} + +/** + * wsa_disable_irq_sync() - to disable an interrupt + * @wsa_res: pointer to wsa resource. + * @irq: interrupt number. + * + * To disable an interrupt, wait for executing IRQ + * handler to complete. + * + * Return: void. + */ +void wsa_disable_irq_sync( + struct wsa_resource *wsa_res, int irq) +{ + if (wsa_res == NULL) { + pr_err("%s: wsa_res is NULL\n", __func__); + return; + } + disable_irq(phyirq_to_virq(wsa_res, irq)); +} + +static int wsa_irq_setup_downstream_irq(struct wsa_resource *wsa_res) +{ + int irq, virq, ret; + + if (wsa_res == NULL) { + pr_err("%s: wsa_res is NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: enter\n", __func__); + + for (irq = 0; irq < wsa_res->num_irqs; irq++) { + /* Map OF irq */ + virq = wsa_map_irq(wsa_res, irq); + pr_debug("%s: irq %d -> %d\n", __func__, irq, virq); + if (virq == NO_IRQ) { + pr_err("%s, No interrupt specifier for irq %d\n", + __func__, irq); + return NO_IRQ; + } + + ret = irq_set_chip_data(virq, wsa_res); + if (ret) { + pr_err("%s: Failed to configure irq %d (%d)\n", + __func__, irq, ret); + return ret; + } + + if (wsa_res->irq_level_high[irq]) + irq_set_chip_and_handler(virq, &wsa_irq_chip, + handle_level_irq); + else + irq_set_chip_and_handler(virq, &wsa_irq_chip, + handle_edge_irq); + + irq_set_nested_thread(virq, 1); + } + + pr_debug("%s: leave\n", __func__); + + return 0; +} + +static int wsa_irq_init(struct wsa_resource *wsa_res) +{ + int i, ret; + + if (wsa_res == NULL) { + pr_err("%s: wsa_res is NULL\n", __func__); + return -EINVAL; + } + mutex_init(&wsa_res->irq_lock); + mutex_init(&wsa_res->nested_irq_lock); + + wsa_res->irq = wsa_irq_get_upstream_irq(wsa_res); + if (!wsa_res->irq) { + pr_warn("%s: irq driver is not yet initialized\n", __func__); + mutex_destroy(&wsa_res->irq_lock); + mutex_destroy(&wsa_res->nested_irq_lock); + return -EPROBE_DEFER; + } + pr_debug("%s: probed irq %d\n", __func__, wsa_res->irq); + + /* Setup downstream IRQs */ + ret = wsa_irq_setup_downstream_irq(wsa_res); + if (ret) { + pr_err("%s: Failed to setup downstream IRQ\n", __func__); + goto fail_irq_init; + } + + /* mask all the interrupts */ + for (i = 0; i < wsa_res->num_irqs; i++) { + wsa_res->irq_masks_cur |= BYTE_BIT_MASK(i); + wsa_res->irq_masks_cache |= BYTE_BIT_MASK(i); + } + + ret = request_threaded_irq(wsa_res->irq, NULL, wsa_irq_thread, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "wsa", wsa_res); + if (ret != 0) { + dev_err(wsa_res->dev, "Failed to request IRQ %d: %d\n", + wsa_res->irq, ret); + } else { + ret = enable_irq_wake(wsa_res->irq); + if (ret) { + dev_err(wsa_res->dev, + "Failed to set wake interrupt on IRQ %d: %d\n", + wsa_res->irq, ret); + free_irq(wsa_res->irq, wsa_res); + } + } + + if (ret) + goto fail_irq_init; + + return ret; + +fail_irq_init: + dev_err(wsa_res->dev, + "%s: Failed to init wsa irq\n", __func__); + wsa_irq_put_upstream_irq(wsa_res); + mutex_destroy(&wsa_res->irq_lock); + mutex_destroy(&wsa_res->nested_irq_lock); + return ret; +} + +/** + * wsa_request_irq() - to request/register an interrupt + * @wsa_res: pointer to wsa_resource. + * @irq: interrupt number. + * @handler: interrupt handler function pointer. + * @name: interrupt name. + * @data: device info. + * + * Convert physical irq to virtual irq and then + * reguest for threaded handler. + * + * Return: Retuns success/failure. + */ +int wsa_request_irq(struct wsa_resource *wsa_res, + int irq, irq_handler_t handler, + const char *name, void *data) +{ + int virq; + + if (wsa_res == NULL) { + pr_err("%s: wsa_res is NULL\n", __func__); + return -EINVAL; + } + virq = phyirq_to_virq(wsa_res, irq); + + /* + * ARM needs us to explicitly flag the IRQ as valid + * and will set them noprobe when we do so. + */ +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) + set_irq_flags(virq, IRQF_VALID); +#else + set_irq_noprobe(virq); +#endif + + return request_threaded_irq(virq, NULL, handler, IRQF_TRIGGER_RISING, + name, data); +} + +/** + * wsa_irq_exit() - to disable/clear interrupt/resources + * @wsa_res: pointer to wsa_resource + * + * Disable and free the interrupts and then release resources. + * + * Return: void. + */ +void wsa_irq_exit(struct wsa_resource *wsa_res) +{ + if (wsa_res == NULL) { + pr_err("%s: wsa_res is NULL\n", __func__); + return; + } + dev_dbg(wsa_res->dev, "%s: Cleaning up irq %d\n", __func__, + wsa_res->irq); + + if (wsa_res->irq) { + disable_irq_wake(wsa_res->irq); + free_irq(wsa_res->irq, wsa_res); + /* Release parent's of node */ + wsa_irq_put_upstream_irq(wsa_res); + } + mutex_destroy(&wsa_res->irq_lock); + mutex_destroy(&wsa_res->nested_irq_lock); +} + +static int phyirq_to_virq(struct wsa_resource *wsa_res, int offset) +{ + if (wsa_res == NULL) { + pr_err("%s: wsa_res is NULL\n", __func__); + return -EINVAL; + } + return irq_linear_revmap(wsa_res->domain, offset); +} + +static int virq_to_phyirq(struct wsa_resource *wsa_res, int virq) +{ + struct irq_data *irq_data = irq_get_irq_data(virq); + + if (unlikely(!irq_data)) { + pr_err("%s: irq_data is NULL\n", __func__); + return -EINVAL; + } + return irq_data->hwirq; +} + +static unsigned int wsa_irq_get_upstream_irq(struct wsa_resource *wsa_res) +{ + if (wsa_res == NULL) { + pr_err("%s: wsa_res is NULL\n", __func__); + return -EINVAL; + } + return wsa_res->irq; +} + +static void wsa_irq_put_upstream_irq(struct wsa_resource *wsa_res) +{ + if (wsa_res == NULL) { + pr_err("%s: wsa_res is NULL\n", __func__); + return; + } + /* Hold parent's of node */ + of_node_put(wsa_res->dev->of_node); +} + +static int wsa_map_irq(struct wsa_resource *wsa_res, int irq) +{ + if (wsa_res == NULL) { + pr_err("%s: wsa_res is NULL\n", __func__); + return -EINVAL; + } + return of_irq_to_resource(wsa_res->dev->of_node, irq, NULL); +} + +static int wsa_irq_probe(struct platform_device *pdev) +{ + int irq; + struct wsa_resource *wsa_res = NULL; + int ret = -EINVAL; + + irq = platform_get_irq_byname(pdev, "wsa-int"); + if (irq < 0) { + dev_err(&pdev->dev, "%s: Couldn't find wsa-int node(%d)\n", + __func__, irq); + return -EINVAL; + } + pr_debug("%s: node %s\n", __func__, pdev->name); + wsa_res = kzalloc(sizeof(*wsa_res), GFP_KERNEL); + if (!wsa_res) { + pr_err("%s: could not allocate memory\n", __func__); + return -ENOMEM; + } + /* + * wsa interrupt controller supports N to N irq mapping with + * single cell binding with irq numbers(offsets) only. + * Use irq_domain_simple_ops that has irq_domain_simple_map and + * irq_domain_xlate_onetwocell. + */ + wsa_res->dev = &pdev->dev; + wsa_res->domain = irq_domain_add_linear(wsa_res->dev->of_node, + WSA_MAX_NUM_IRQS, &irq_domain_simple_ops, + wsa_res); + if (!wsa_res->domain) { + dev_err(&pdev->dev, "%s: domain is NULL\n", __func__); + ret = -ENOMEM; + goto err; + } + wsa_res->dev = &pdev->dev; + + dev_dbg(&pdev->dev, "%s: virq = %d\n", __func__, irq); + wsa_res->irq = irq; + wsa_res->num_irq_regs = 1; + wsa_res->num_irqs = WSA_NUM_IRQS; + ret = wsa_irq_init(wsa_res); + if (ret < 0) { + dev_err(&pdev->dev, "%s: failed to do irq init %d\n", + __func__, ret); + goto err; + } + + return ret; +err: + kfree(wsa_res); + return ret; +} + +static int wsa_irq_remove(struct platform_device *pdev) +{ + struct irq_domain *domain; + struct wsa_resource *data; + + domain = irq_find_host(pdev->dev.of_node); + if (unlikely(!domain)) { + pr_err("%s: domain is NULL\n", __func__); + return -EINVAL; + } + data = (struct wsa_resource *)domain->host_data; + data->irq = 0; + + return 0; +} + +static const struct of_device_id of_match[] = { + { .compatible = "qcom,wsa-irq" }, + { } +}; + +static struct platform_driver wsa_irq_driver = { + .probe = wsa_irq_probe, + .remove = wsa_irq_remove, + .driver = { + .name = "wsa_intc", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(of_match), + }, +}; + +static int wsa_irq_drv_init(void) +{ + return platform_driver_register(&wsa_irq_driver); +} +subsys_initcall(wsa_irq_drv_init); + +static void wsa_irq_drv_exit(void) +{ + platform_driver_unregister(&wsa_irq_driver); +} +module_exit(wsa_irq_drv_exit); + +MODULE_DESCRIPTION("WSA881x IRQ driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/wsa881x-irq.h b/sound/soc/codecs/wsa881x-irq.h new file mode 100644 index 000000000000..270eb917a666 --- /dev/null +++ b/sound/soc/codecs/wsa881x-irq.h @@ -0,0 +1,82 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __WSA881X_IRQ_H__ +#define __WSA881X_IRQ_H__ + +#include +#include +#include + +/** + * enum wsa_interrupts - wsa interrupt number + * @WSA_INT_SAF2WAR: Temp irq interrupt, from safe state to warning state. + * @WSA_INT_WAR2SAF: Temp irq interrupt, from warning state to safe state. + * @WSA_INT_DISABLE: Disable Temp sensor interrupts. + * @WSA_INT_OCP: OCP interrupt. + * @WSA_INT_CLIP: CLIP detect interrupt. + * @WSA_NUM_IRQS: MAX Interrupt number. + * + * WSA IRQ Interrupt numbers. + */ +enum wsa_interrupts { + WSA_INT_SAF2WAR = 0, + WSA_INT_WAR2SAF, + WSA_INT_DISABLE, + WSA_INT_OCP, + WSA_INT_CLIP, + WSA_NUM_IRQS, +}; + +/** + * struct wsa_resource - the basic wsa_resource structure + * @irq_lock: lock used by irq_chip functions. + * @nested_irq_lock: lock used while handling nested interrupts. + * @irq: interrupt number. + * @irq_masks_cur: current mask value to be written to mask registers. + * @irq_masks_cache: cached mask value. + * @num_irqs: number of supported interrupts. + * @num_irq_regs: number of irq registers. + * @parent: parent pointer. + * @dev: device pointer. + * @domain: irq domain pointer. + * codec: codec pointer. + * + * Contains required members used in wsa irq driver. + */ + +struct wsa_resource { + struct mutex irq_lock; + struct mutex nested_irq_lock; + unsigned int irq; + u8 irq_masks_cur; + u8 irq_masks_cache; + bool irq_level_high[8]; + int num_irqs; + int num_irq_regs; + void *parent; + struct device *dev; + struct irq_domain *domain; + struct snd_soc_codec *codec; +}; + +void wsa_set_codec(struct snd_soc_codec *codec); +void wsa_free_irq(int irq, void *data); +void wsa_enable_irq(struct wsa_resource *wsa_res, int irq); +void wsa_disable_irq(struct wsa_resource *wsa_res, int irq); +void wsa_disable_irq_sync(struct wsa_resource *wsa_res, int irq); +int wsa_request_irq(struct wsa_resource *wsa_res, + int irq, irq_handler_t handler, + const char *name, void *data); + +void wsa_irq_exit(struct wsa_resource *wsa_res); + +#endif /* __WSA881X_IRQ_H__ */ diff --git a/sound/soc/codecs/wsa881x-registers-analog.h b/sound/soc/codecs/wsa881x-registers-analog.h new file mode 100644 index 000000000000..a5ebf8e1aab4 --- /dev/null +++ b/sound/soc/codecs/wsa881x-registers-analog.h @@ -0,0 +1,206 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef WSA881X_REGISTERS_H +#define WSA881X_REGISTERS_H + +#define WSA881X_DIGITAL_BASE 0x0000 +#define WSA881X_ANALOG_BASE 0x0100 + +#define WSA881X_CHIP_ID0 (WSA881X_DIGITAL_BASE+0x0000) +#define WSA881X_CHIP_ID1 (WSA881X_DIGITAL_BASE+0x0001) +#define WSA881X_CHIP_ID2 (WSA881X_DIGITAL_BASE+0x0002) +#define WSA881X_CHIP_ID3 (WSA881X_DIGITAL_BASE+0x0003) +#define WSA881X_BUS_ID (WSA881X_DIGITAL_BASE+0x0004) +#define WSA881X_CDC_RST_CTL (WSA881X_DIGITAL_BASE+0x0005) +#define WSA881X_CDC_TOP_CLK_CTL (WSA881X_DIGITAL_BASE+0x0006) +#define WSA881X_CDC_ANA_CLK_CTL (WSA881X_DIGITAL_BASE+0x0007) +#define WSA881X_CDC_DIG_CLK_CTL (WSA881X_DIGITAL_BASE+0x0008) +#define WSA881X_CLOCK_CONFIG (WSA881X_DIGITAL_BASE+0x0009) +#define WSA881X_ANA_CTL (WSA881X_DIGITAL_BASE+0x000A) +#define WSA881X_SWR_RESET_EN (WSA881X_DIGITAL_BASE+0x000B) +#define WSA881X_RESET_CTL (WSA881X_DIGITAL_BASE+0x000C) +#define WSA881X_TADC_VALUE_CTL (WSA881X_DIGITAL_BASE+0x000F) +#define WSA881X_TEMP_DETECT_CTL (WSA881X_DIGITAL_BASE+0x0010) +#define WSA881X_TEMP_MSB (WSA881X_DIGITAL_BASE+0x0011) +#define WSA881X_TEMP_LSB (WSA881X_DIGITAL_BASE+0x0012) +#define WSA881X_TEMP_CONFIG0 (WSA881X_DIGITAL_BASE+0x0013) +#define WSA881X_TEMP_CONFIG1 (WSA881X_DIGITAL_BASE+0x0014) +#define WSA881X_CDC_CLIP_CTL (WSA881X_DIGITAL_BASE+0x0015) +#define WSA881X_SDM_PDM9_LSB (WSA881X_DIGITAL_BASE+0x0016) +#define WSA881X_SDM_PDM9_MSB (WSA881X_DIGITAL_BASE+0x0017) +#define WSA881X_CDC_RX_CTL (WSA881X_DIGITAL_BASE+0x0018) +#define WSA881X_DEM_BYPASS_DATA0 (WSA881X_DIGITAL_BASE+0x0019) +#define WSA881X_DEM_BYPASS_DATA1 (WSA881X_DIGITAL_BASE+0x001A) +#define WSA881X_DEM_BYPASS_DATA2 (WSA881X_DIGITAL_BASE+0x001B) +#define WSA881X_DEM_BYPASS_DATA3 (WSA881X_DIGITAL_BASE+0x001C) +#define WSA881X_OTP_CTRL0 (WSA881X_DIGITAL_BASE+0x001D) +#define WSA881X_OTP_CTRL1 (WSA881X_DIGITAL_BASE+0x001E) +#define WSA881X_HDRIVE_CTL_GROUP1 (WSA881X_DIGITAL_BASE+0x001F) +#define WSA881X_INTR_MODE (WSA881X_DIGITAL_BASE+0x0020) +#define WSA881X_INTR_MASK (WSA881X_DIGITAL_BASE+0x0021) +#define WSA881X_INTR_STATUS (WSA881X_DIGITAL_BASE+0x0022) +#define WSA881X_INTR_CLEAR (WSA881X_DIGITAL_BASE+0x0023) +#define WSA881X_INTR_LEVEL (WSA881X_DIGITAL_BASE+0x0024) +#define WSA881X_INTR_SET (WSA881X_DIGITAL_BASE+0x0025) +#define WSA881X_INTR_TEST (WSA881X_DIGITAL_BASE+0x0026) +#define WSA881X_PDM_TEST_MODE (WSA881X_DIGITAL_BASE+0x0030) +#define WSA881X_ATE_TEST_MODE (WSA881X_DIGITAL_BASE+0x0031) +#define WSA881X_PIN_CTL_MODE (WSA881X_DIGITAL_BASE+0x0032) +#define WSA881X_PIN_CTL_OE (WSA881X_DIGITAL_BASE+0x0033) +#define WSA881X_PIN_WDATA_IOPAD (WSA881X_DIGITAL_BASE+0x0034) +#define WSA881X_PIN_STATUS (WSA881X_DIGITAL_BASE+0x0035) +#define WSA881X_DIG_DEBUG_MODE (WSA881X_DIGITAL_BASE+0x0037) +#define WSA881X_DIG_DEBUG_SEL (WSA881X_DIGITAL_BASE+0x0038) +#define WSA881X_DIG_DEBUG_EN (WSA881X_DIGITAL_BASE+0x0039) +#define WSA881X_SWR_HM_TEST1 (WSA881X_DIGITAL_BASE+0x003B) +#define WSA881X_SWR_HM_TEST2 (WSA881X_DIGITAL_BASE+0x003C) +#define WSA881X_TEMP_DETECT_DBG_CTL (WSA881X_DIGITAL_BASE+0x003D) +#define WSA881X_TEMP_DEBUG_MSB (WSA881X_DIGITAL_BASE+0x003E) +#define WSA881X_TEMP_DEBUG_LSB (WSA881X_DIGITAL_BASE+0x003F) +#define WSA881X_SAMPLE_EDGE_SEL (WSA881X_DIGITAL_BASE+0x0044) +#define WSA881X_IOPAD_CTL (WSA881X_DIGITAL_BASE+0x0045) +#define WSA881X_SPARE_0 (WSA881X_DIGITAL_BASE+0x0050) +#define WSA881X_SPARE_1 (WSA881X_DIGITAL_BASE+0x0051) +#define WSA881X_SPARE_2 (WSA881X_DIGITAL_BASE+0x0052) +#define WSA881X_OTP_REG_0 (WSA881X_DIGITAL_BASE+0x0080) +#define WSA881X_OTP_REG_1 (WSA881X_DIGITAL_BASE+0x0081) +#define WSA881X_OTP_REG_2 (WSA881X_DIGITAL_BASE+0x0082) +#define WSA881X_OTP_REG_3 (WSA881X_DIGITAL_BASE+0x0083) +#define WSA881X_OTP_REG_4 (WSA881X_DIGITAL_BASE+0x0084) +#define WSA881X_OTP_REG_5 (WSA881X_DIGITAL_BASE+0x0085) +#define WSA881X_OTP_REG_6 (WSA881X_DIGITAL_BASE+0x0086) +#define WSA881X_OTP_REG_7 (WSA881X_DIGITAL_BASE+0x0087) +#define WSA881X_OTP_REG_8 (WSA881X_DIGITAL_BASE+0x0088) +#define WSA881X_OTP_REG_9 (WSA881X_DIGITAL_BASE+0x0089) +#define WSA881X_OTP_REG_10 (WSA881X_DIGITAL_BASE+0x008A) +#define WSA881X_OTP_REG_11 (WSA881X_DIGITAL_BASE+0x008B) +#define WSA881X_OTP_REG_12 (WSA881X_DIGITAL_BASE+0x008C) +#define WSA881X_OTP_REG_13 (WSA881X_DIGITAL_BASE+0x008D) +#define WSA881X_OTP_REG_14 (WSA881X_DIGITAL_BASE+0x008E) +#define WSA881X_OTP_REG_15 (WSA881X_DIGITAL_BASE+0x008F) +#define WSA881X_OTP_REG_16 (WSA881X_DIGITAL_BASE+0x0090) +#define WSA881X_OTP_REG_17 (WSA881X_DIGITAL_BASE+0x0091) +#define WSA881X_OTP_REG_18 (WSA881X_DIGITAL_BASE+0x0092) +#define WSA881X_OTP_REG_19 (WSA881X_DIGITAL_BASE+0x0093) +#define WSA881X_OTP_REG_20 (WSA881X_DIGITAL_BASE+0x0094) +#define WSA881X_OTP_REG_21 (WSA881X_DIGITAL_BASE+0x0095) +#define WSA881X_OTP_REG_22 (WSA881X_DIGITAL_BASE+0x0096) +#define WSA881X_OTP_REG_23 (WSA881X_DIGITAL_BASE+0x0097) +#define WSA881X_OTP_REG_24 (WSA881X_DIGITAL_BASE+0x0098) +#define WSA881X_OTP_REG_25 (WSA881X_DIGITAL_BASE+0x0099) +#define WSA881X_OTP_REG_26 (WSA881X_DIGITAL_BASE+0x009A) +#define WSA881X_OTP_REG_27 (WSA881X_DIGITAL_BASE+0x009B) +#define WSA881X_OTP_REG_28 (WSA881X_DIGITAL_BASE+0x009C) +#define WSA881X_OTP_REG_29 (WSA881X_DIGITAL_BASE+0x009D) +#define WSA881X_OTP_REG_30 (WSA881X_DIGITAL_BASE+0x009E) +#define WSA881X_OTP_REG_31 (WSA881X_DIGITAL_BASE+0x009F) +#define WSA881X_OTP_REG_32 (WSA881X_DIGITAL_BASE+0x00A0) +#define WSA881X_OTP_REG_33 (WSA881X_DIGITAL_BASE+0x00A1) +#define WSA881X_OTP_REG_34 (WSA881X_DIGITAL_BASE+0x00A2) +#define WSA881X_OTP_REG_35 (WSA881X_DIGITAL_BASE+0x00A3) +#define WSA881X_OTP_REG_36 (WSA881X_DIGITAL_BASE+0x00A4) +#define WSA881X_OTP_REG_37 (WSA881X_DIGITAL_BASE+0x00A5) +#define WSA881X_OTP_REG_38 (WSA881X_DIGITAL_BASE+0x00A6) +#define WSA881X_OTP_REG_39 (WSA881X_DIGITAL_BASE+0x00A7) +#define WSA881X_OTP_REG_40 (WSA881X_DIGITAL_BASE+0x00A8) +#define WSA881X_OTP_REG_41 (WSA881X_DIGITAL_BASE+0x00A9) +#define WSA881X_OTP_REG_42 (WSA881X_DIGITAL_BASE+0x00AA) +#define WSA881X_OTP_REG_43 (WSA881X_DIGITAL_BASE+0x00AB) +#define WSA881X_OTP_REG_44 (WSA881X_DIGITAL_BASE+0x00AC) +#define WSA881X_OTP_REG_45 (WSA881X_DIGITAL_BASE+0x00AD) +#define WSA881X_OTP_REG_46 (WSA881X_DIGITAL_BASE+0x00AE) +#define WSA881X_OTP_REG_47 (WSA881X_DIGITAL_BASE+0x00AF) +#define WSA881X_OTP_REG_48 (WSA881X_DIGITAL_BASE+0x00B0) +#define WSA881X_OTP_REG_49 (WSA881X_DIGITAL_BASE+0x00B1) +#define WSA881X_OTP_REG_50 (WSA881X_DIGITAL_BASE+0x00B2) +#define WSA881X_OTP_REG_51 (WSA881X_DIGITAL_BASE+0x00B3) +#define WSA881X_OTP_REG_52 (WSA881X_DIGITAL_BASE+0x00B4) +#define WSA881X_OTP_REG_53 (WSA881X_DIGITAL_BASE+0x00B5) +#define WSA881X_OTP_REG_54 (WSA881X_DIGITAL_BASE+0x00B6) +#define WSA881X_OTP_REG_55 (WSA881X_DIGITAL_BASE+0x00B7) +#define WSA881X_OTP_REG_56 (WSA881X_DIGITAL_BASE+0x00B8) +#define WSA881X_OTP_REG_57 (WSA881X_DIGITAL_BASE+0x00B9) +#define WSA881X_OTP_REG_58 (WSA881X_DIGITAL_BASE+0x00BA) +#define WSA881X_OTP_REG_59 (WSA881X_DIGITAL_BASE+0x00BB) +#define WSA881X_OTP_REG_60 (WSA881X_DIGITAL_BASE+0x00BC) +#define WSA881X_OTP_REG_61 (WSA881X_DIGITAL_BASE+0x00BD) +#define WSA881X_OTP_REG_62 (WSA881X_DIGITAL_BASE+0x00BE) +#define WSA881X_OTP_REG_63 (WSA881X_DIGITAL_BASE+0x00BF) +/* Analog Register address space */ +#define WSA881X_BIAS_REF_CTRL (WSA881X_ANALOG_BASE+0x0000) +#define WSA881X_BIAS_TEST (WSA881X_ANALOG_BASE+0x0001) +#define WSA881X_BIAS_BIAS (WSA881X_ANALOG_BASE+0x0002) +#define WSA881X_TEMP_OP (WSA881X_ANALOG_BASE+0x0003) +#define WSA881X_TEMP_IREF_CTRL (WSA881X_ANALOG_BASE+0x0004) +#define WSA881X_TEMP_ISENS_CTRL (WSA881X_ANALOG_BASE+0x0005) +#define WSA881X_TEMP_CLK_CTRL (WSA881X_ANALOG_BASE+0x0006) +#define WSA881X_TEMP_TEST (WSA881X_ANALOG_BASE+0x0007) +#define WSA881X_TEMP_BIAS (WSA881X_ANALOG_BASE+0x0008) +#define WSA881X_TEMP_ADC_CTRL (WSA881X_ANALOG_BASE+0x0009) +#define WSA881X_TEMP_DOUT_MSB (WSA881X_ANALOG_BASE+0x000A) +#define WSA881X_TEMP_DOUT_LSB (WSA881X_ANALOG_BASE+0x000B) +#define WSA881X_ADC_EN_MODU_V (WSA881X_ANALOG_BASE+0x0010) +#define WSA881X_ADC_EN_MODU_I (WSA881X_ANALOG_BASE+0x0011) +#define WSA881X_ADC_EN_DET_TEST_V (WSA881X_ANALOG_BASE+0x0012) +#define WSA881X_ADC_EN_DET_TEST_I (WSA881X_ANALOG_BASE+0x0013) +#define WSA881X_ADC_SEL_IBIAS (WSA881X_ANALOG_BASE+0x0014) +#define WSA881X_ADC_EN_SEL_IBIAS (WSA881X_ANALOG_BASE+0x0015) +#define WSA881X_SPKR_DRV_EN (WSA881X_ANALOG_BASE+0x001A) +#define WSA881X_SPKR_DRV_GAIN (WSA881X_ANALOG_BASE+0x001B) +#define WSA881X_SPKR_DAC_CTL (WSA881X_ANALOG_BASE+0x001C) +#define WSA881X_SPKR_DRV_DBG (WSA881X_ANALOG_BASE+0x001D) +#define WSA881X_SPKR_PWRSTG_DBG (WSA881X_ANALOG_BASE+0x001E) +#define WSA881X_SPKR_OCP_CTL (WSA881X_ANALOG_BASE+0x001F) +#define WSA881X_SPKR_CLIP_CTL (WSA881X_ANALOG_BASE+0x0020) +#define WSA881X_SPKR_BBM_CTL (WSA881X_ANALOG_BASE+0x0021) +#define WSA881X_SPKR_MISC_CTL1 (WSA881X_ANALOG_BASE+0x0022) +#define WSA881X_SPKR_MISC_CTL2 (WSA881X_ANALOG_BASE+0x0023) +#define WSA881X_SPKR_BIAS_INT (WSA881X_ANALOG_BASE+0x0024) +#define WSA881X_SPKR_PA_INT (WSA881X_ANALOG_BASE+0x0025) +#define WSA881X_SPKR_BIAS_CAL (WSA881X_ANALOG_BASE+0x0026) +#define WSA881X_SPKR_BIAS_PSRR (WSA881X_ANALOG_BASE+0x0027) +#define WSA881X_SPKR_STATUS1 (WSA881X_ANALOG_BASE+0x0028) +#define WSA881X_SPKR_STATUS2 (WSA881X_ANALOG_BASE+0x0029) +#define WSA881X_BOOST_EN_CTL (WSA881X_ANALOG_BASE+0x002A) +#define WSA881X_BOOST_CURRENT_LIMIT (WSA881X_ANALOG_BASE+0x002B) +#define WSA881X_BOOST_PS_CTL (WSA881X_ANALOG_BASE+0x002C) +#define WSA881X_BOOST_PRESET_OUT1 (WSA881X_ANALOG_BASE+0x002D) +#define WSA881X_BOOST_PRESET_OUT2 (WSA881X_ANALOG_BASE+0x002E) +#define WSA881X_BOOST_FORCE_OUT (WSA881X_ANALOG_BASE+0x002F) +#define WSA881X_BOOST_LDO_PROG (WSA881X_ANALOG_BASE+0x0030) +#define WSA881X_BOOST_SLOPE_COMP_ISENSE_FB (WSA881X_ANALOG_BASE+0x0031) +#define WSA881X_BOOST_RON_CTL (WSA881X_ANALOG_BASE+0x0032) +#define WSA881X_BOOST_LOOP_STABILITY (WSA881X_ANALOG_BASE+0x0033) +#define WSA881X_BOOST_ZX_CTL (WSA881X_ANALOG_BASE+0x0034) +#define WSA881X_BOOST_START_CTL (WSA881X_ANALOG_BASE+0x0035) +#define WSA881X_BOOST_MISC1_CTL (WSA881X_ANALOG_BASE+0x0036) +#define WSA881X_BOOST_MISC2_CTL (WSA881X_ANALOG_BASE+0x0037) +#define WSA881X_BOOST_MISC3_CTL (WSA881X_ANALOG_BASE+0x0038) +#define WSA881X_BOOST_ATEST_CTL (WSA881X_ANALOG_BASE+0x0039) +#define WSA881X_SPKR_PROT_FE_GAIN (WSA881X_ANALOG_BASE+0x003A) +#define WSA881X_SPKR_PROT_FE_CM_LDO_SET (WSA881X_ANALOG_BASE+0x003B) +#define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1 (WSA881X_ANALOG_BASE+0x003C) +#define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2 (WSA881X_ANALOG_BASE+0x003D) +#define WSA881X_SPKR_PROT_ATEST1 (WSA881X_ANALOG_BASE+0x003E) +#define WSA881X_SPKR_PROT_ATEST2 (WSA881X_ANALOG_BASE+0x003F) +#define WSA881X_SPKR_PROT_FE_VSENSE_VCM (WSA881X_ANALOG_BASE+0x0040) +#define WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1 (WSA881X_ANALOG_BASE+0x0041) +#define WSA881X_BONGO_RESRV_REG1 (WSA881X_ANALOG_BASE+0x0042) +#define WSA881X_BONGO_RESRV_REG2 (WSA881X_ANALOG_BASE+0x0043) +#define WSA881X_SPKR_PROT_SAR (WSA881X_ANALOG_BASE+0x0044) +#define WSA881X_SPKR_STATUS3 (WSA881X_ANALOG_BASE+0x0045) + +#define WSA881X_NUM_REGISTERS (WSA881X_SPKR_STATUS3+1) +#define WSA881X_MAX_REGISTER (WSA881X_NUM_REGISTERS-1) +#define WSA881X_CACHE_SIZE WSA881X_NUM_REGISTERS +#endif /* WSA881X_REGISTERS_H */ diff --git a/sound/soc/codecs/wsa881x-registers.h b/sound/soc/codecs/wsa881x-registers.h new file mode 100644 index 000000000000..825a5f034da8 --- /dev/null +++ b/sound/soc/codecs/wsa881x-registers.h @@ -0,0 +1,178 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef WSA881X_REGISTERS_H +#define WSA881X_REGISTERS_H + +#define WSA881X_DIGITAL_BASE 0x3000 +#define WSA881X_ANALOG_BASE 0x3100 + +/* Digital register address space */ +#define WSA881X_CHIP_ID0 (WSA881X_DIGITAL_BASE+0x0000) +#define WSA881X_CHIP_ID1 (WSA881X_DIGITAL_BASE+0x0001) +#define WSA881X_CHIP_ID2 (WSA881X_DIGITAL_BASE+0x0002) +#define WSA881X_CHIP_ID3 (WSA881X_DIGITAL_BASE+0x0003) +#define WSA881X_BUS_ID (WSA881X_DIGITAL_BASE+0x0004) +#define WSA881X_CDC_RST_CTL (WSA881X_DIGITAL_BASE+0x0005) +#define WSA881X_CDC_TOP_CLK_CTL (WSA881X_DIGITAL_BASE+0x0006) +#define WSA881X_CDC_ANA_CLK_CTL (WSA881X_DIGITAL_BASE+0x0007) +#define WSA881X_CDC_DIG_CLK_CTL (WSA881X_DIGITAL_BASE+0x0008) +#define WSA881X_CLOCK_CONFIG (WSA881X_DIGITAL_BASE+0x0009) +#define WSA881X_ANA_CTL (WSA881X_DIGITAL_BASE+0x000A) +#define WSA881X_SWR_RESET_EN (WSA881X_DIGITAL_BASE+0x000B) +#define WSA881X_RESET_CTL (WSA881X_DIGITAL_BASE+0x000C) +#define WSA881X_TADC_VALUE_CTL (WSA881X_DIGITAL_BASE+0x000F) +#define WSA881X_TEMP_DETECT_CTL (WSA881X_DIGITAL_BASE+0x0010) +#define WSA881X_TEMP_MSB (WSA881X_DIGITAL_BASE+0x0011) +#define WSA881X_TEMP_LSB (WSA881X_DIGITAL_BASE+0x0012) +#define WSA881X_TEMP_CONFIG0 (WSA881X_DIGITAL_BASE+0x0013) +#define WSA881X_TEMP_CONFIG1 (WSA881X_DIGITAL_BASE+0x0014) +#define WSA881X_CDC_CLIP_CTL (WSA881X_DIGITAL_BASE+0x0015) +#define WSA881X_SDM_PDM9_LSB (WSA881X_DIGITAL_BASE+0x0016) +#define WSA881X_SDM_PDM9_MSB (WSA881X_DIGITAL_BASE+0x0017) +#define WSA881X_CDC_RX_CTL (WSA881X_DIGITAL_BASE+0x0018) +#define WSA881X_DEM_BYPASS_DATA0 (WSA881X_DIGITAL_BASE+0x0019) +#define WSA881X_DEM_BYPASS_DATA1 (WSA881X_DIGITAL_BASE+0x001A) +#define WSA881X_DEM_BYPASS_DATA2 (WSA881X_DIGITAL_BASE+0x001B) +#define WSA881X_DEM_BYPASS_DATA3 (WSA881X_DIGITAL_BASE+0x001C) +#define WSA881X_OTP_CTRL0 (WSA881X_DIGITAL_BASE+0x001D) +#define WSA881X_OTP_CTRL1 (WSA881X_DIGITAL_BASE+0x001E) +#define WSA881X_HDRIVE_CTL_GROUP1 (WSA881X_DIGITAL_BASE+0x001F) +#define WSA881X_INTR_MODE (WSA881X_DIGITAL_BASE+0x0020) +#define WSA881X_INTR_MASK (WSA881X_DIGITAL_BASE+0x0021) +#define WSA881X_INTR_STATUS (WSA881X_DIGITAL_BASE+0x0022) +#define WSA881X_INTR_CLEAR (WSA881X_DIGITAL_BASE+0x0023) +#define WSA881X_INTR_LEVEL (WSA881X_DIGITAL_BASE+0x0024) +#define WSA881X_INTR_SET (WSA881X_DIGITAL_BASE+0x0025) +#define WSA881X_INTR_TEST (WSA881X_DIGITAL_BASE+0x0026) +#define WSA881X_PDM_TEST_MODE (WSA881X_DIGITAL_BASE+0x0030) +#define WSA881X_ATE_TEST_MODE (WSA881X_DIGITAL_BASE+0x0031) +#define WSA881X_PIN_CTL_MODE (WSA881X_DIGITAL_BASE+0x0032) +#define WSA881X_PIN_CTL_OE (WSA881X_DIGITAL_BASE+0x0033) +#define WSA881X_PIN_WDATA_IOPAD (WSA881X_DIGITAL_BASE+0x0034) +#define WSA881X_PIN_STATUS (WSA881X_DIGITAL_BASE+0x0035) +#define WSA881X_DIG_DEBUG_MODE (WSA881X_DIGITAL_BASE+0x0037) +#define WSA881X_DIG_DEBUG_SEL (WSA881X_DIGITAL_BASE+0x0038) +#define WSA881X_DIG_DEBUG_EN (WSA881X_DIGITAL_BASE+0x0039) +#define WSA881X_SWR_HM_TEST1 (WSA881X_DIGITAL_BASE+0x003B) +#define WSA881X_SWR_HM_TEST2 (WSA881X_DIGITAL_BASE+0x003C) +#define WSA881X_TEMP_DETECT_DBG_CTL (WSA881X_DIGITAL_BASE+0x003D) +#define WSA881X_TEMP_DEBUG_MSB (WSA881X_DIGITAL_BASE+0x003E) +#define WSA881X_TEMP_DEBUG_LSB (WSA881X_DIGITAL_BASE+0x003F) +#define WSA881X_SAMPLE_EDGE_SEL (WSA881X_DIGITAL_BASE+0x0044) +#define WSA881X_IOPAD_CTL (WSA881X_DIGITAL_BASE+0x0045) +#define WSA881X_SPARE_0 (WSA881X_DIGITAL_BASE+0x0050) +#define WSA881X_SPARE_1 (WSA881X_DIGITAL_BASE+0x0051) +#define WSA881X_SPARE_2 (WSA881X_DIGITAL_BASE+0x0052) +#define WSA881X_OTP_REG_0 (WSA881X_DIGITAL_BASE+0x0080) +#define WSA881X_OTP_REG_1 (WSA881X_DIGITAL_BASE+0x0081) +#define WSA881X_OTP_REG_2 (WSA881X_DIGITAL_BASE+0x0082) +#define WSA881X_OTP_REG_3 (WSA881X_DIGITAL_BASE+0x0083) +#define WSA881X_OTP_REG_4 (WSA881X_DIGITAL_BASE+0x0084) +#define WSA881X_OTP_REG_5 (WSA881X_DIGITAL_BASE+0x0085) +#define WSA881X_OTP_REG_6 (WSA881X_DIGITAL_BASE+0x0086) +#define WSA881X_OTP_REG_7 (WSA881X_DIGITAL_BASE+0x0087) +#define WSA881X_OTP_REG_8 (WSA881X_DIGITAL_BASE+0x0088) +#define WSA881X_OTP_REG_9 (WSA881X_DIGITAL_BASE+0x0089) +#define WSA881X_OTP_REG_10 (WSA881X_DIGITAL_BASE+0x008A) +#define WSA881X_OTP_REG_11 (WSA881X_DIGITAL_BASE+0x008B) +#define WSA881X_OTP_REG_12 (WSA881X_DIGITAL_BASE+0x008C) +#define WSA881X_OTP_REG_13 (WSA881X_DIGITAL_BASE+0x008D) +#define WSA881X_OTP_REG_14 (WSA881X_DIGITAL_BASE+0x008E) +#define WSA881X_OTP_REG_15 (WSA881X_DIGITAL_BASE+0x008F) +#define WSA881X_OTP_REG_16 (WSA881X_DIGITAL_BASE+0x0090) +#define WSA881X_OTP_REG_17 (WSA881X_DIGITAL_BASE+0x0091) +#define WSA881X_OTP_REG_18 (WSA881X_DIGITAL_BASE+0x0092) +#define WSA881X_OTP_REG_19 (WSA881X_DIGITAL_BASE+0x0093) +#define WSA881X_OTP_REG_20 (WSA881X_DIGITAL_BASE+0x0094) +#define WSA881X_OTP_REG_21 (WSA881X_DIGITAL_BASE+0x0095) +#define WSA881X_OTP_REG_22 (WSA881X_DIGITAL_BASE+0x0096) +#define WSA881X_OTP_REG_23 (WSA881X_DIGITAL_BASE+0x0097) +#define WSA881X_OTP_REG_24 (WSA881X_DIGITAL_BASE+0x0098) +#define WSA881X_OTP_REG_25 (WSA881X_DIGITAL_BASE+0x0099) +#define WSA881X_OTP_REG_26 (WSA881X_DIGITAL_BASE+0x009A) +#define WSA881X_OTP_REG_27 (WSA881X_DIGITAL_BASE+0x009B) +#define WSA881X_OTP_REG_28 (WSA881X_DIGITAL_BASE+0x009C) +#define WSA881X_OTP_REG_29 (WSA881X_DIGITAL_BASE+0x009D) +#define WSA881X_OTP_REG_30 (WSA881X_DIGITAL_BASE+0x009E) +#define WSA881X_OTP_REG_31 (WSA881X_DIGITAL_BASE+0x009F) +#define WSA881X_OTP_REG_63 (WSA881X_DIGITAL_BASE+0x00BF) + +/* Analog Register address space */ +#define WSA881X_BIAS_REF_CTRL (WSA881X_ANALOG_BASE+0x0000) +#define WSA881X_BIAS_TEST (WSA881X_ANALOG_BASE+0x0001) +#define WSA881X_BIAS_BIAS (WSA881X_ANALOG_BASE+0x0002) +#define WSA881X_TEMP_OP (WSA881X_ANALOG_BASE+0x0003) +#define WSA881X_TEMP_IREF_CTRL (WSA881X_ANALOG_BASE+0x0004) +#define WSA881X_TEMP_ISENS_CTRL (WSA881X_ANALOG_BASE+0x0005) +#define WSA881X_TEMP_CLK_CTRL (WSA881X_ANALOG_BASE+0x0006) +#define WSA881X_TEMP_TEST (WSA881X_ANALOG_BASE+0x0007) +#define WSA881X_TEMP_BIAS (WSA881X_ANALOG_BASE+0x0008) +#define WSA881X_TEMP_ADC_CTRL (WSA881X_ANALOG_BASE+0x0009) +#define WSA881X_TEMP_DOUT_MSB (WSA881X_ANALOG_BASE+0x000A) +#define WSA881X_TEMP_DOUT_LSB (WSA881X_ANALOG_BASE+0x000B) +#define WSA881X_ADC_EN_MODU_V (WSA881X_ANALOG_BASE+0x0010) +#define WSA881X_ADC_EN_MODU_I (WSA881X_ANALOG_BASE+0x0011) +#define WSA881X_ADC_EN_DET_TEST_V (WSA881X_ANALOG_BASE+0x0012) +#define WSA881X_ADC_EN_DET_TEST_I (WSA881X_ANALOG_BASE+0x0013) +#define WSA881X_ADC_SEL_IBIAS (WSA881X_ANALOG_BASE+0x0014) +#define WSA881X_ADC_EN_SEL_IBAIS (WSA881X_ANALOG_BASE+0x0015) +#define WSA881X_SPKR_DRV_EN (WSA881X_ANALOG_BASE+0x001A) +#define WSA881X_SPKR_DRV_GAIN (WSA881X_ANALOG_BASE+0x001B) +#define WSA881X_SPKR_DAC_CTL (WSA881X_ANALOG_BASE+0x001C) +#define WSA881X_SPKR_DRV_DBG (WSA881X_ANALOG_BASE+0x001D) +#define WSA881X_SPKR_PWRSTG_DBG (WSA881X_ANALOG_BASE+0x001E) +#define WSA881X_SPKR_OCP_CTL (WSA881X_ANALOG_BASE+0x001F) +#define WSA881X_SPKR_CLIP_CTL (WSA881X_ANALOG_BASE+0x0020) +#define WSA881X_SPKR_BBM_CTL (WSA881X_ANALOG_BASE+0x0021) +#define WSA881X_SPKR_MISC_CTL1 (WSA881X_ANALOG_BASE+0x0022) +#define WSA881X_SPKR_MISC_CTL2 (WSA881X_ANALOG_BASE+0x0023) +#define WSA881X_SPKR_BIAS_INT (WSA881X_ANALOG_BASE+0x0024) +#define WSA881X_SPKR_PA_INT (WSA881X_ANALOG_BASE+0x0025) +#define WSA881X_SPKR_BIAS_CAL (WSA881X_ANALOG_BASE+0x0026) +#define WSA881X_SPKR_BIAS_PSRR (WSA881X_ANALOG_BASE+0x0027) +#define WSA881X_SPKR_STATUS1 (WSA881X_ANALOG_BASE+0x0028) +#define WSA881X_SPKR_STATUS2 (WSA881X_ANALOG_BASE+0x0029) +#define WSA881X_BOOST_EN_CTL (WSA881X_ANALOG_BASE+0x002A) +#define WSA881X_BOOST_CURRENT_LIMIT (WSA881X_ANALOG_BASE+0x002B) +#define WSA881X_BOOST_PS_CTL (WSA881X_ANALOG_BASE+0x002C) +#define WSA881X_BOOST_PRESET_OUT1 (WSA881X_ANALOG_BASE+0x002D) +#define WSA881X_BOOST_PRESET_OUT2 (WSA881X_ANALOG_BASE+0x002E) +#define WSA881X_BOOST_FORCE_OUT (WSA881X_ANALOG_BASE+0x002F) +#define WSA881X_BOOST_LDO_PROG (WSA881X_ANALOG_BASE+0x0030) +#define WSA881X_BOOST_SLOPE_COMP_ISENSE_FB (WSA881X_ANALOG_BASE+0x0031) +#define WSA881X_BOOST_RON_CTL (WSA881X_ANALOG_BASE+0x0032) +#define WSA881X_BOOST_LOOP_STABILITY (WSA881X_ANALOG_BASE+0x0033) +#define WSA881X_BOOST_ZX_CTL (WSA881X_ANALOG_BASE+0x0034) +#define WSA881X_BOOST_START_CTL (WSA881X_ANALOG_BASE+0x0035) +#define WSA881X_BOOST_MISC1_CTL (WSA881X_ANALOG_BASE+0x0036) +#define WSA881X_BOOST_MISC2_CTL (WSA881X_ANALOG_BASE+0x0037) +#define WSA881X_BOOST_MISC3_CTL (WSA881X_ANALOG_BASE+0x0038) +#define WSA881X_BOOST_ATEST_CTL (WSA881X_ANALOG_BASE+0x0039) +#define WSA881X_SPKR_PROT_FE_GAIN (WSA881X_ANALOG_BASE+0x003A) +#define WSA881X_SPKR_PROT_FE_CM_LDO_SET (WSA881X_ANALOG_BASE+0x003B) +#define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1 (WSA881X_ANALOG_BASE+0x003C) +#define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2 (WSA881X_ANALOG_BASE+0x003D) +#define WSA881X_SPKR_PROT_ATEST1 (WSA881X_ANALOG_BASE+0x003E) +#define WSA881X_SPKR_PROT_ATEST2 (WSA881X_ANALOG_BASE+0x003F) +#define WSA881X_SPKR_PROT_FE_VSENSE_VCM (WSA881X_ANALOG_BASE+0x0040) +#define WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1 (WSA881X_ANALOG_BASE+0x0041) +#define WSA881X_BONGO_RESRV_REG1 (WSA881X_ANALOG_BASE+0x0042) +#define WSA881X_BONGO_RESRV_REG2 (WSA881X_ANALOG_BASE+0x0043) +#define WSA881X_SPKR_PROT_SAR (WSA881X_ANALOG_BASE+0x0044) +#define WSA881X_SPKR_STATUS3 (WSA881X_ANALOG_BASE+0x0045) + +#define WSA881X_NUM_REGISTERS (WSA881X_SPKR_STATUS3+1) +#define WSA881X_MAX_REGISTER (WSA881X_NUM_REGISTERS-1) +#define WSA881X_CACHE_SIZE WSA881X_NUM_REGISTERS + +#endif /* WSA881X_REGISTERS_H */ diff --git a/sound/soc/codecs/wsa881x-regmap-analog.c b/sound/soc/codecs/wsa881x-regmap-analog.c new file mode 100644 index 000000000000..2bc3c9eb7061 --- /dev/null +++ b/sound/soc/codecs/wsa881x-regmap-analog.c @@ -0,0 +1,499 @@ +/* + * Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "wsa881x-registers-analog.h" +#include "wsa881x-analog.h" + +struct reg_default wsa881x_ana_reg_defaults[] = { + {WSA881X_CHIP_ID0, 0x00}, + {WSA881X_CHIP_ID1, 0x00}, + {WSA881X_CHIP_ID2, 0x00}, + {WSA881X_CHIP_ID3, 0x02}, + {WSA881X_BUS_ID, 0x00}, + {WSA881X_CDC_RST_CTL, 0x00}, + {WSA881X_CDC_TOP_CLK_CTL, 0x03}, + {WSA881X_CDC_ANA_CLK_CTL, 0x00}, + {WSA881X_CDC_DIG_CLK_CTL, 0x00}, + {WSA881X_CLOCK_CONFIG, 0x00}, + {WSA881X_ANA_CTL, 0x08}, + {WSA881X_SWR_RESET_EN, 0x00}, + {WSA881X_TEMP_DETECT_CTL, 0x01}, + {WSA881X_TEMP_MSB, 0x00}, + {WSA881X_TEMP_LSB, 0x00}, + {WSA881X_TEMP_CONFIG0, 0x00}, + {WSA881X_TEMP_CONFIG1, 0x00}, + {WSA881X_CDC_CLIP_CTL, 0x03}, + {WSA881X_SDM_PDM9_LSB, 0x00}, + {WSA881X_SDM_PDM9_MSB, 0x00}, + {WSA881X_CDC_RX_CTL, 0x7E}, + {WSA881X_DEM_BYPASS_DATA0, 0x00}, + {WSA881X_DEM_BYPASS_DATA1, 0x00}, + {WSA881X_DEM_BYPASS_DATA2, 0x00}, + {WSA881X_DEM_BYPASS_DATA3, 0x00}, + {WSA881X_OTP_CTRL0, 0x00}, + {WSA881X_OTP_CTRL1, 0x00}, + {WSA881X_HDRIVE_CTL_GROUP1, 0x00}, + {WSA881X_INTR_MODE, 0x00}, + {WSA881X_INTR_MASK, 0x1F}, + {WSA881X_INTR_STATUS, 0x00}, + {WSA881X_INTR_CLEAR, 0x00}, + {WSA881X_INTR_LEVEL, 0x00}, + {WSA881X_INTR_SET, 0x00}, + {WSA881X_INTR_TEST, 0x00}, + {WSA881X_PDM_TEST_MODE, 0x00}, + {WSA881X_ATE_TEST_MODE, 0x00}, + {WSA881X_PIN_CTL_MODE, 0x00}, + {WSA881X_PIN_CTL_OE, 0x00}, + {WSA881X_PIN_WDATA_IOPAD, 0x00}, + {WSA881X_PIN_STATUS, 0x00}, + {WSA881X_DIG_DEBUG_MODE, 0x00}, + {WSA881X_DIG_DEBUG_SEL, 0x00}, + {WSA881X_DIG_DEBUG_EN, 0x00}, + {WSA881X_SWR_HM_TEST1, 0x08}, + {WSA881X_SWR_HM_TEST2, 0x00}, + {WSA881X_TEMP_DETECT_DBG_CTL, 0x00}, + {WSA881X_TEMP_DEBUG_MSB, 0x00}, + {WSA881X_TEMP_DEBUG_LSB, 0x00}, + {WSA881X_SAMPLE_EDGE_SEL, 0x0C}, + {WSA881X_SPARE_0, 0x00}, + {WSA881X_SPARE_1, 0x00}, + {WSA881X_SPARE_2, 0x00}, + {WSA881X_OTP_REG_0, 0x01}, + {WSA881X_OTP_REG_1, 0xFF}, + {WSA881X_OTP_REG_2, 0xC0}, + {WSA881X_OTP_REG_3, 0xFF}, + {WSA881X_OTP_REG_4, 0xC0}, + {WSA881X_OTP_REG_5, 0xFF}, + {WSA881X_OTP_REG_6, 0xFF}, + {WSA881X_OTP_REG_7, 0xFF}, + {WSA881X_OTP_REG_8, 0xFF}, + {WSA881X_OTP_REG_9, 0xFF}, + {WSA881X_OTP_REG_10, 0xFF}, + {WSA881X_OTP_REG_11, 0xFF}, + {WSA881X_OTP_REG_12, 0xFF}, + {WSA881X_OTP_REG_13, 0xFF}, + {WSA881X_OTP_REG_14, 0xFF}, + {WSA881X_OTP_REG_15, 0xFF}, + {WSA881X_OTP_REG_16, 0xFF}, + {WSA881X_OTP_REG_17, 0xFF}, + {WSA881X_OTP_REG_18, 0xFF}, + {WSA881X_OTP_REG_19, 0xFF}, + {WSA881X_OTP_REG_20, 0xFF}, + {WSA881X_OTP_REG_21, 0xFF}, + {WSA881X_OTP_REG_22, 0xFF}, + {WSA881X_OTP_REG_23, 0xFF}, + {WSA881X_OTP_REG_24, 0x03}, + {WSA881X_OTP_REG_25, 0x01}, + {WSA881X_OTP_REG_26, 0x03}, + {WSA881X_OTP_REG_27, 0x11}, + {WSA881X_OTP_REG_28, 0xFF}, + {WSA881X_OTP_REG_29, 0xFF}, + {WSA881X_OTP_REG_30, 0xFF}, + {WSA881X_OTP_REG_31, 0xFF}, + {WSA881X_OTP_REG_63, 0x40}, + /* WSA881x Analog registers */ + {WSA881X_BIAS_REF_CTRL, 0x6C}, + {WSA881X_BIAS_TEST, 0x16}, + {WSA881X_BIAS_BIAS, 0xF0}, + {WSA881X_TEMP_OP, 0x00}, + {WSA881X_TEMP_IREF_CTRL, 0x56}, + {WSA881X_TEMP_ISENS_CTRL, 0x47}, + {WSA881X_TEMP_CLK_CTRL, 0x87}, + {WSA881X_TEMP_TEST, 0x00}, + {WSA881X_TEMP_BIAS, 0x51}, + {WSA881X_TEMP_ADC_CTRL, 0x00}, + {WSA881X_TEMP_DOUT_MSB, 0x00}, + {WSA881X_TEMP_DOUT_LSB, 0x00}, + {WSA881X_ADC_EN_MODU_V, 0x00}, + {WSA881X_ADC_EN_MODU_I, 0x00}, + {WSA881X_ADC_EN_DET_TEST_V, 0x00}, + {WSA881X_ADC_EN_DET_TEST_I, 0x00}, + {WSA881X_ADC_SEL_IBIAS, 0x25}, + {WSA881X_ADC_EN_SEL_IBIAS, 0x10}, + {WSA881X_SPKR_DRV_EN, 0x74}, + {WSA881X_SPKR_DRV_GAIN, 0x01}, + {WSA881X_SPKR_DAC_CTL, 0x40}, + {WSA881X_SPKR_DRV_DBG, 0x15}, + {WSA881X_SPKR_PWRSTG_DBG, 0x00}, + {WSA881X_SPKR_OCP_CTL, 0xD4}, + {WSA881X_SPKR_CLIP_CTL, 0x90}, + {WSA881X_SPKR_BBM_CTL, 0x00}, + {WSA881X_SPKR_MISC_CTL1, 0x80}, + {WSA881X_SPKR_MISC_CTL2, 0x00}, + {WSA881X_SPKR_BIAS_INT, 0x56}, + {WSA881X_SPKR_PA_INT, 0x54}, + {WSA881X_SPKR_BIAS_CAL, 0xAC}, + {WSA881X_SPKR_BIAS_PSRR, 0x54}, + {WSA881X_SPKR_STATUS1, 0x00}, + {WSA881X_SPKR_STATUS2, 0x00}, + {WSA881X_BOOST_EN_CTL, 0x18}, + {WSA881X_BOOST_CURRENT_LIMIT, 0x7A}, + {WSA881X_BOOST_PS_CTL, 0xC0}, + {WSA881X_BOOST_PRESET_OUT1, 0x77}, + {WSA881X_BOOST_PRESET_OUT2, 0x70}, + {WSA881X_BOOST_FORCE_OUT, 0x0E}, + {WSA881X_BOOST_LDO_PROG, 0x16}, + {WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, 0x71}, + {WSA881X_BOOST_RON_CTL, 0x0F}, + {WSA881X_BOOST_LOOP_STABILITY, 0xAD}, + {WSA881X_BOOST_ZX_CTL, 0x34}, + {WSA881X_BOOST_START_CTL, 0x23}, + {WSA881X_BOOST_MISC1_CTL, 0x80}, + {WSA881X_BOOST_MISC2_CTL, 0x00}, + {WSA881X_BOOST_MISC3_CTL, 0x00}, + {WSA881X_BOOST_ATEST_CTL, 0x00}, + {WSA881X_SPKR_PROT_FE_GAIN, 0x46}, + {WSA881X_SPKR_PROT_FE_CM_LDO_SET, 0x3B}, + {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1, 0x8D}, + {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2, 0x8D}, + {WSA881X_SPKR_PROT_ATEST1, 0x01}, + {WSA881X_SPKR_PROT_ATEST2, 0x00}, + {WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x8D}, + {WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1, 0x4D}, + {WSA881X_BONGO_RESRV_REG1, 0x00}, + {WSA881X_BONGO_RESRV_REG2, 0x00}, + {WSA881X_SPKR_PROT_SAR, 0x00}, + {WSA881X_SPKR_STATUS3, 0x00}, +}; + +struct reg_default wsa881x_ana_reg_defaults_0[] = { + {WSA881X_CHIP_ID0, 0x00}, + {WSA881X_CHIP_ID1, 0x00}, + {WSA881X_CHIP_ID2, 0x00}, + {WSA881X_CHIP_ID3, 0x02}, + {WSA881X_BUS_ID, 0x00}, + {WSA881X_CDC_RST_CTL, 0x00}, + {WSA881X_CDC_TOP_CLK_CTL, 0x03}, + {WSA881X_CDC_ANA_CLK_CTL, 0x00}, + {WSA881X_CDC_DIG_CLK_CTL, 0x00}, + {WSA881X_CLOCK_CONFIG, 0x00}, + {WSA881X_ANA_CTL, 0x08}, + {WSA881X_SWR_RESET_EN, 0x00}, + {WSA881X_TEMP_DETECT_CTL, 0x01}, + {WSA881X_TEMP_MSB, 0x00}, + {WSA881X_TEMP_LSB, 0x00}, + {WSA881X_TEMP_CONFIG0, 0x00}, + {WSA881X_TEMP_CONFIG1, 0x00}, + {WSA881X_CDC_CLIP_CTL, 0x03}, + {WSA881X_SDM_PDM9_LSB, 0x00}, + {WSA881X_SDM_PDM9_MSB, 0x00}, + {WSA881X_CDC_RX_CTL, 0x7E}, + {WSA881X_DEM_BYPASS_DATA0, 0x00}, + {WSA881X_DEM_BYPASS_DATA1, 0x00}, + {WSA881X_DEM_BYPASS_DATA2, 0x00}, + {WSA881X_DEM_BYPASS_DATA3, 0x00}, + {WSA881X_OTP_CTRL0, 0x00}, + {WSA881X_OTP_CTRL1, 0x00}, + {WSA881X_HDRIVE_CTL_GROUP1, 0x00}, + {WSA881X_INTR_MODE, 0x00}, + {WSA881X_INTR_MASK, 0x1F}, + {WSA881X_INTR_STATUS, 0x00}, + {WSA881X_INTR_CLEAR, 0x00}, + {WSA881X_INTR_LEVEL, 0x00}, + {WSA881X_INTR_SET, 0x00}, + {WSA881X_INTR_TEST, 0x00}, + {WSA881X_PDM_TEST_MODE, 0x00}, + {WSA881X_ATE_TEST_MODE, 0x00}, + {WSA881X_PIN_CTL_MODE, 0x00}, + {WSA881X_PIN_CTL_OE, 0x00}, + {WSA881X_PIN_WDATA_IOPAD, 0x00}, + {WSA881X_PIN_STATUS, 0x00}, + {WSA881X_DIG_DEBUG_MODE, 0x00}, + {WSA881X_DIG_DEBUG_SEL, 0x00}, + {WSA881X_DIG_DEBUG_EN, 0x00}, + {WSA881X_SWR_HM_TEST1, 0x08}, + {WSA881X_SWR_HM_TEST2, 0x00}, + {WSA881X_TEMP_DETECT_DBG_CTL, 0x00}, + {WSA881X_TEMP_DEBUG_MSB, 0x00}, + {WSA881X_TEMP_DEBUG_LSB, 0x00}, + {WSA881X_SAMPLE_EDGE_SEL, 0x0C}, + {WSA881X_SPARE_0, 0x00}, + {WSA881X_SPARE_1, 0x00}, + {WSA881X_SPARE_2, 0x00}, + {WSA881X_OTP_REG_0, 0x01}, + {WSA881X_OTP_REG_1, 0xFF}, + {WSA881X_OTP_REG_2, 0xC0}, + {WSA881X_OTP_REG_3, 0xFF}, + {WSA881X_OTP_REG_4, 0xC0}, + {WSA881X_OTP_REG_5, 0xFF}, + {WSA881X_OTP_REG_6, 0xFF}, + {WSA881X_OTP_REG_7, 0xFF}, + {WSA881X_OTP_REG_8, 0xFF}, + {WSA881X_OTP_REG_9, 0xFF}, + {WSA881X_OTP_REG_10, 0xFF}, + {WSA881X_OTP_REG_11, 0xFF}, + {WSA881X_OTP_REG_12, 0xFF}, + {WSA881X_OTP_REG_13, 0xFF}, + {WSA881X_OTP_REG_14, 0xFF}, + {WSA881X_OTP_REG_15, 0xFF}, + {WSA881X_OTP_REG_16, 0xFF}, + {WSA881X_OTP_REG_17, 0xFF}, + {WSA881X_OTP_REG_18, 0xFF}, + {WSA881X_OTP_REG_19, 0xFF}, + {WSA881X_OTP_REG_20, 0xFF}, + {WSA881X_OTP_REG_21, 0xFF}, + {WSA881X_OTP_REG_22, 0xFF}, + {WSA881X_OTP_REG_23, 0xFF}, + {WSA881X_OTP_REG_24, 0x03}, + {WSA881X_OTP_REG_25, 0x01}, + {WSA881X_OTP_REG_26, 0x03}, + {WSA881X_OTP_REG_27, 0x11}, + {WSA881X_OTP_REG_28, 0xFF}, + {WSA881X_OTP_REG_29, 0xFF}, + {WSA881X_OTP_REG_30, 0xFF}, + {WSA881X_OTP_REG_31, 0xFF}, + {WSA881X_OTP_REG_63, 0x40}, +}; + +struct reg_default wsa881x_ana_reg_defaults_1[] = { + {WSA881X_BIAS_REF_CTRL - WSA881X_ANALOG_BASE, 0x6C}, + {WSA881X_BIAS_TEST - WSA881X_ANALOG_BASE, 0x16}, + {WSA881X_BIAS_BIAS - WSA881X_ANALOG_BASE, 0xF0}, + {WSA881X_TEMP_OP - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_TEMP_IREF_CTRL - WSA881X_ANALOG_BASE, 0x56}, + {WSA881X_TEMP_ISENS_CTRL - WSA881X_ANALOG_BASE, 0x47}, + {WSA881X_TEMP_CLK_CTRL - WSA881X_ANALOG_BASE, 0x87}, + {WSA881X_TEMP_TEST - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_TEMP_BIAS - WSA881X_ANALOG_BASE, 0x51}, + {WSA881X_TEMP_ADC_CTRL - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_TEMP_DOUT_MSB - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_TEMP_DOUT_LSB - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_ADC_EN_MODU_V - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_ADC_EN_MODU_I - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_ADC_EN_DET_TEST_V - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_ADC_EN_DET_TEST_I - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_ADC_SEL_IBIAS - WSA881X_ANALOG_BASE, 0x25}, + {WSA881X_ADC_EN_SEL_IBIAS - WSA881X_ANALOG_BASE, 0x10}, + {WSA881X_SPKR_DRV_EN - WSA881X_ANALOG_BASE, 0x74}, + {WSA881X_SPKR_DRV_GAIN - WSA881X_ANALOG_BASE, 0x01}, + {WSA881X_SPKR_DAC_CTL - WSA881X_ANALOG_BASE, 0x40}, + {WSA881X_SPKR_DRV_DBG - WSA881X_ANALOG_BASE, 0x15}, + {WSA881X_SPKR_PWRSTG_DBG - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_SPKR_OCP_CTL - WSA881X_ANALOG_BASE, 0xD4}, + {WSA881X_SPKR_CLIP_CTL - WSA881X_ANALOG_BASE, 0x90}, + {WSA881X_SPKR_BBM_CTL - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_SPKR_MISC_CTL1 - WSA881X_ANALOG_BASE, 0x80}, + {WSA881X_SPKR_MISC_CTL2 - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_SPKR_BIAS_INT - WSA881X_ANALOG_BASE, 0x56}, + {WSA881X_SPKR_PA_INT - WSA881X_ANALOG_BASE, 0x54}, + {WSA881X_SPKR_BIAS_CAL - WSA881X_ANALOG_BASE, 0xAC}, + {WSA881X_SPKR_BIAS_PSRR - WSA881X_ANALOG_BASE, 0x54}, + {WSA881X_SPKR_STATUS1 - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_SPKR_STATUS2 - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_BOOST_EN_CTL - WSA881X_ANALOG_BASE, 0x18}, + {WSA881X_BOOST_CURRENT_LIMIT - WSA881X_ANALOG_BASE, 0x7A}, + {WSA881X_BOOST_PS_CTL - WSA881X_ANALOG_BASE, 0xC0}, + {WSA881X_BOOST_PRESET_OUT1 - WSA881X_ANALOG_BASE, 0x77}, + {WSA881X_BOOST_PRESET_OUT2 - WSA881X_ANALOG_BASE, 0x70}, + {WSA881X_BOOST_FORCE_OUT - WSA881X_ANALOG_BASE, 0x0E}, + {WSA881X_BOOST_LDO_PROG - WSA881X_ANALOG_BASE, 0x16}, + {WSA881X_BOOST_SLOPE_COMP_ISENSE_FB - WSA881X_ANALOG_BASE, 0x71}, + {WSA881X_BOOST_RON_CTL - WSA881X_ANALOG_BASE, 0x0F}, + {WSA881X_BOOST_LOOP_STABILITY - WSA881X_ANALOG_BASE, 0xAD}, + {WSA881X_BOOST_ZX_CTL - WSA881X_ANALOG_BASE, 0x34}, + {WSA881X_BOOST_START_CTL - WSA881X_ANALOG_BASE, 0x23}, + {WSA881X_BOOST_MISC1_CTL - WSA881X_ANALOG_BASE, 0x80}, + {WSA881X_BOOST_MISC2_CTL - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_BOOST_MISC3_CTL - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_BOOST_ATEST_CTL - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_SPKR_PROT_FE_GAIN - WSA881X_ANALOG_BASE, 0x46}, + {WSA881X_SPKR_PROT_FE_CM_LDO_SET - WSA881X_ANALOG_BASE, 0x3B}, + {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1 - WSA881X_ANALOG_BASE, 0x8D}, + {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2 - WSA881X_ANALOG_BASE, 0x8D}, + {WSA881X_SPKR_PROT_ATEST1 - WSA881X_ANALOG_BASE, 0x01}, + {WSA881X_SPKR_PROT_ATEST2 - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_SPKR_PROT_FE_VSENSE_VCM - WSA881X_ANALOG_BASE, 0x8D}, + {WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1 - WSA881X_ANALOG_BASE, 0x4D}, + {WSA881X_BONGO_RESRV_REG1 - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_BONGO_RESRV_REG2 - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_SPKR_PROT_SAR - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_SPKR_STATUS3 - WSA881X_ANALOG_BASE, 0x00}, +}; + +struct reg_default wsa881x_rev_2_0_dig[] = { + {WSA881X_RESET_CTL, 0x00}, + {WSA881X_TADC_VALUE_CTL, 0x01}, + {WSA881X_INTR_MASK, 0x1B}, + {WSA881X_IOPAD_CTL, 0x00}, + {WSA881X_OTP_REG_28, 0x3F}, + {WSA881X_OTP_REG_29, 0x3F}, + {WSA881X_OTP_REG_30, 0x01}, + {WSA881X_OTP_REG_31, 0x01}, +}; + +struct reg_default wsa881x_rev_2_0_ana[] = { + {WSA881X_TEMP_ADC_CTRL, 0x03}, + {WSA881X_ADC_SEL_IBIAS, 0x45}, + {WSA881X_SPKR_DRV_GAIN, 0xC1}, + {WSA881X_SPKR_DAC_CTL, 0x42}, + {WSA881X_SPKR_BBM_CTL, 0x02}, + {WSA881X_SPKR_MISC_CTL1, 0x40}, + {WSA881X_SPKR_MISC_CTL2, 0x07}, + {WSA881X_SPKR_BIAS_INT, 0x5F}, + {WSA881X_SPKR_BIAS_PSRR, 0x44}, + {WSA881X_BOOST_PS_CTL, 0xA0}, + {WSA881X_BOOST_PRESET_OUT1, 0xB7}, + {WSA881X_BOOST_LOOP_STABILITY, 0x8D}, + {WSA881X_SPKR_PROT_ATEST2, 0x02}, + {WSA881X_BONGO_RESRV_REG1, 0x5E}, + {WSA881X_BONGO_RESRV_REG2, 0x07}, +}; + +struct reg_default wsa881x_rev_2_0_regmap_ana[] = { + {WSA881X_TEMP_ADC_CTRL - WSA881X_ANALOG_BASE, 0x03}, + {WSA881X_ADC_SEL_IBIAS - WSA881X_ANALOG_BASE, 0x45}, + {WSA881X_SPKR_DRV_GAIN - WSA881X_ANALOG_BASE, 0xC1}, + {WSA881X_SPKR_DAC_CTL - WSA881X_ANALOG_BASE, 0x42}, + {WSA881X_SPKR_BBM_CTL - WSA881X_ANALOG_BASE, 0x02}, + {WSA881X_SPKR_MISC_CTL1 - WSA881X_ANALOG_BASE, 0x40}, + {WSA881X_SPKR_MISC_CTL2 - WSA881X_ANALOG_BASE, 0x07}, + {WSA881X_SPKR_BIAS_INT - WSA881X_ANALOG_BASE, 0x5F}, + {WSA881X_SPKR_BIAS_PSRR - WSA881X_ANALOG_BASE, 0x44}, + {WSA881X_BOOST_PS_CTL - WSA881X_ANALOG_BASE, 0xA0}, + {WSA881X_BOOST_PRESET_OUT1 - WSA881X_ANALOG_BASE, 0xB7}, + {WSA881X_BOOST_LOOP_STABILITY - WSA881X_ANALOG_BASE, 0x8D}, + {WSA881X_SPKR_PROT_ATEST2 - WSA881X_ANALOG_BASE, 0x02}, + {WSA881X_BONGO_RESRV_REG1 - WSA881X_ANALOG_BASE, 0x5E}, + {WSA881X_BONGO_RESRV_REG2 - WSA881X_ANALOG_BASE, 0x07}, +}; + +/** + * wsa881x_update_reg_defaults_2_0 - update default values of regs for v2.0 + * + * WSA881x v2.0 has different default values for certain analog and digital + * registers compared to v1.x. Therefore, update the values of these registers + * with the values from tables defined above for v2.0. + */ +void wsa881x_update_reg_defaults_2_0(void) +{ + int i, j; + + for (i = 0; i < ARRAY_SIZE(wsa881x_rev_2_0_dig); i++) { + for (j = 0; j < ARRAY_SIZE(wsa881x_ana_reg_defaults); j++) + if (wsa881x_ana_reg_defaults[j].reg == + wsa881x_rev_2_0_dig[i].reg) + wsa881x_ana_reg_defaults[j].def = + wsa881x_rev_2_0_dig[i].def; + } + for (i = 0; i < ARRAY_SIZE(wsa881x_rev_2_0_ana); i++) { + for (j = 0; j < ARRAY_SIZE(wsa881x_ana_reg_defaults); j++) + if (wsa881x_ana_reg_defaults[j].reg == + wsa881x_rev_2_0_ana[i].reg) + wsa881x_ana_reg_defaults[j].def = + wsa881x_rev_2_0_ana[i].def; + } +} +EXPORT_SYMBOL(wsa881x_update_reg_defaults_2_0); + +/** + * wsa881x_update_regmap_2_0 - update regmap framework with new tables + * @regmap: pointer to WSA881x regmap structure + * @flag: indicates digital or analog WSA881x slave + * + * WSA881x v2.0 has some new registers for both analog and digital slaves. + * Update the regmap framework with all the new registers. + */ +void wsa881x_update_regmap_2_0(struct regmap *regmap, int flag) +{ + u16 ret = 0; + + switch (flag) { + case WSA881X_DIGITAL_SLAVE: + ret = regmap_register_patch(regmap, wsa881x_rev_2_0_dig, + ARRAY_SIZE(wsa881x_rev_2_0_dig)); + break; + case WSA881X_ANALOG_SLAVE: + ret = regmap_register_patch(regmap, wsa881x_rev_2_0_ana, + ARRAY_SIZE(wsa881x_rev_2_0_ana)); + break; + default: + pr_debug("%s: unknown version", __func__); + ret = -EINVAL; + break; + } + if (ret) + pr_err("%s: Failed to update regmap defaults ret= %d\n", + __func__, ret); +} +EXPORT_SYMBOL(wsa881x_update_regmap_2_0); + +static bool wsa881x_readable_register(struct device *dev, unsigned int reg) +{ + return wsa881x_ana_reg_readable[reg]; +} + +static bool wsa881x_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WSA881X_CHIP_ID0: + case WSA881X_CHIP_ID1: + case WSA881X_CHIP_ID2: + case WSA881X_CHIP_ID3: + case WSA881X_BUS_ID: + case WSA881X_TEMP_MSB: + case WSA881X_TEMP_LSB: + case WSA881X_SDM_PDM9_LSB: + case WSA881X_SDM_PDM9_MSB: + case WSA881X_OTP_REG_0: + case WSA881X_OTP_REG_1: + case WSA881X_OTP_REG_2: + case WSA881X_OTP_REG_3: + case WSA881X_OTP_REG_4: + case WSA881X_OTP_REG_5: + case WSA881X_OTP_REG_31: + case WSA881X_TEMP_DOUT_MSB: + case WSA881X_TEMP_DOUT_LSB: + case WSA881X_TEMP_OP: + case WSA881X_OTP_CTRL1: + case WSA881X_INTR_STATUS: + case WSA881X_ATE_TEST_MODE: + case WSA881X_PIN_STATUS: + case WSA881X_SWR_HM_TEST2: + case WSA881X_SPKR_STATUS1: + case WSA881X_SPKR_STATUS2: + case WSA881X_SPKR_STATUS3: + case WSA881X_SPKR_PROT_SAR: + return true; + default: + return false; + } +} + +struct regmap_config wsa881x_ana_regmap_config[] = { +{ + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_NONE, + .reg_defaults = wsa881x_ana_reg_defaults_0, + .num_reg_defaults = ARRAY_SIZE(wsa881x_ana_reg_defaults_0), + .max_register = WSA881X_MAX_REGISTER, + .volatile_reg = wsa881x_volatile_register, + .readable_reg = wsa881x_readable_register, + .reg_format_endian = REGMAP_ENDIAN_NATIVE, + .val_format_endian = REGMAP_ENDIAN_NATIVE, +}, +{ + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_NONE, + .reg_defaults = wsa881x_ana_reg_defaults_1, + .num_reg_defaults = ARRAY_SIZE(wsa881x_ana_reg_defaults_1), + .max_register = WSA881X_MAX_REGISTER, + .volatile_reg = wsa881x_volatile_register, + .readable_reg = wsa881x_readable_register, + .reg_format_endian = REGMAP_ENDIAN_NATIVE, + .val_format_endian = REGMAP_ENDIAN_NATIVE, +} +}; diff --git a/sound/soc/codecs/wsa881x-regmap.c b/sound/soc/codecs/wsa881x-regmap.c new file mode 100644 index 000000000000..63bbbfa6beab --- /dev/null +++ b/sound/soc/codecs/wsa881x-regmap.c @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "wsa881x-registers.h" +#include "wsa881x.h" + +/* + * Default register reset values that are common across different versions + * are defined here. If a register reset value is changed based on version + * then remove it from this structure and add it in version specific + * structures. + */ +static struct reg_default wsa881x_defaults[] = { + {WSA881X_CHIP_ID0, 0x00}, + {WSA881X_CHIP_ID1, 0x00}, + {WSA881X_CHIP_ID2, 0x00}, + {WSA881X_CHIP_ID3, 0x02}, + {WSA881X_BUS_ID, 0x00}, + {WSA881X_CDC_RST_CTL, 0x00}, + {WSA881X_CDC_TOP_CLK_CTL, 0x03}, + {WSA881X_CDC_ANA_CLK_CTL, 0x00}, + {WSA881X_CDC_DIG_CLK_CTL, 0x00}, + {WSA881X_CLOCK_CONFIG, 0x00}, + {WSA881X_ANA_CTL, 0x08}, + {WSA881X_SWR_RESET_EN, 0x00}, + {WSA881X_TEMP_DETECT_CTL, 0x01}, + {WSA881X_TEMP_MSB, 0x00}, + {WSA881X_TEMP_LSB, 0x00}, + {WSA881X_TEMP_CONFIG0, 0x00}, + {WSA881X_TEMP_CONFIG1, 0x00}, + {WSA881X_CDC_CLIP_CTL, 0x03}, + {WSA881X_SDM_PDM9_LSB, 0x00}, + {WSA881X_SDM_PDM9_MSB, 0x00}, + {WSA881X_CDC_RX_CTL, 0x7E}, + {WSA881X_DEM_BYPASS_DATA0, 0x00}, + {WSA881X_DEM_BYPASS_DATA1, 0x00}, + {WSA881X_DEM_BYPASS_DATA2, 0x00}, + {WSA881X_DEM_BYPASS_DATA3, 0x00}, + {WSA881X_OTP_CTRL0, 0x00}, + {WSA881X_OTP_CTRL1, 0x00}, + {WSA881X_HDRIVE_CTL_GROUP1, 0x00}, + {WSA881X_INTR_MODE, 0x00}, + {WSA881X_INTR_STATUS, 0x00}, + {WSA881X_INTR_CLEAR, 0x00}, + {WSA881X_INTR_LEVEL, 0x00}, + {WSA881X_INTR_SET, 0x00}, + {WSA881X_INTR_TEST, 0x00}, + {WSA881X_PDM_TEST_MODE, 0x00}, + {WSA881X_ATE_TEST_MODE, 0x00}, + {WSA881X_PIN_CTL_MODE, 0x00}, + {WSA881X_PIN_CTL_OE, 0x00}, + {WSA881X_PIN_WDATA_IOPAD, 0x00}, + {WSA881X_PIN_STATUS, 0x00}, + {WSA881X_DIG_DEBUG_MODE, 0x00}, + {WSA881X_DIG_DEBUG_SEL, 0x00}, + {WSA881X_DIG_DEBUG_EN, 0x00}, + {WSA881X_SWR_HM_TEST1, 0x08}, + {WSA881X_SWR_HM_TEST2, 0x00}, + {WSA881X_TEMP_DETECT_DBG_CTL, 0x00}, + {WSA881X_TEMP_DEBUG_MSB, 0x00}, + {WSA881X_TEMP_DEBUG_LSB, 0x00}, + {WSA881X_SAMPLE_EDGE_SEL, 0x0C}, + {WSA881X_SPARE_0, 0x00}, + {WSA881X_SPARE_1, 0x00}, + {WSA881X_SPARE_2, 0x00}, + {WSA881X_OTP_REG_0, 0x01}, + {WSA881X_OTP_REG_1, 0xFF}, + {WSA881X_OTP_REG_2, 0xC0}, + {WSA881X_OTP_REG_3, 0xFF}, + {WSA881X_OTP_REG_4, 0xC0}, + {WSA881X_OTP_REG_5, 0xFF}, + {WSA881X_OTP_REG_6, 0xFF}, + {WSA881X_OTP_REG_7, 0xFF}, + {WSA881X_OTP_REG_8, 0xFF}, + {WSA881X_OTP_REG_9, 0xFF}, + {WSA881X_OTP_REG_10, 0xFF}, + {WSA881X_OTP_REG_11, 0xFF}, + {WSA881X_OTP_REG_12, 0xFF}, + {WSA881X_OTP_REG_13, 0xFF}, + {WSA881X_OTP_REG_14, 0xFF}, + {WSA881X_OTP_REG_15, 0xFF}, + {WSA881X_OTP_REG_16, 0xFF}, + {WSA881X_OTP_REG_17, 0xFF}, + {WSA881X_OTP_REG_18, 0xFF}, + {WSA881X_OTP_REG_19, 0xFF}, + {WSA881X_OTP_REG_20, 0xFF}, + {WSA881X_OTP_REG_21, 0xFF}, + {WSA881X_OTP_REG_22, 0xFF}, + {WSA881X_OTP_REG_23, 0xFF}, + {WSA881X_OTP_REG_24, 0x03}, + {WSA881X_OTP_REG_25, 0x01}, + {WSA881X_OTP_REG_26, 0x03}, + {WSA881X_OTP_REG_27, 0x11}, + {WSA881X_OTP_REG_63, 0x40}, + /* WSA881x Analog registers */ + {WSA881X_BIAS_REF_CTRL, 0x6C}, + {WSA881X_BIAS_TEST, 0x16}, + {WSA881X_BIAS_BIAS, 0xF0}, + {WSA881X_TEMP_OP, 0x00}, + {WSA881X_TEMP_IREF_CTRL, 0x56}, + {WSA881X_TEMP_ISENS_CTRL, 0x47}, + {WSA881X_TEMP_CLK_CTRL, 0x87}, + {WSA881X_TEMP_TEST, 0x00}, + {WSA881X_TEMP_BIAS, 0x51}, + {WSA881X_TEMP_DOUT_MSB, 0x00}, + {WSA881X_TEMP_DOUT_LSB, 0x00}, + {WSA881X_ADC_EN_MODU_V, 0x00}, + {WSA881X_ADC_EN_MODU_I, 0x00}, + {WSA881X_ADC_EN_DET_TEST_V, 0x00}, + {WSA881X_ADC_EN_DET_TEST_I, 0x00}, + {WSA881X_ADC_EN_SEL_IBAIS, 0x10}, + {WSA881X_SPKR_DRV_EN, 0x74}, + {WSA881X_SPKR_DRV_DBG, 0x15}, + {WSA881X_SPKR_PWRSTG_DBG, 0x00}, + {WSA881X_SPKR_OCP_CTL, 0xD4}, + {WSA881X_SPKR_CLIP_CTL, 0x90}, + {WSA881X_SPKR_PA_INT, 0x54}, + {WSA881X_SPKR_BIAS_CAL, 0xAC}, + {WSA881X_SPKR_STATUS1, 0x00}, + {WSA881X_SPKR_STATUS2, 0x00}, + {WSA881X_BOOST_EN_CTL, 0x18}, + {WSA881X_BOOST_CURRENT_LIMIT, 0x7A}, + {WSA881X_BOOST_PRESET_OUT2, 0x70}, + {WSA881X_BOOST_FORCE_OUT, 0x0E}, + {WSA881X_BOOST_LDO_PROG, 0x16}, + {WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, 0x71}, + {WSA881X_BOOST_RON_CTL, 0x0F}, + {WSA881X_BOOST_ZX_CTL, 0x34}, + {WSA881X_BOOST_START_CTL, 0x23}, + {WSA881X_BOOST_MISC1_CTL, 0x80}, + {WSA881X_BOOST_MISC2_CTL, 0x00}, + {WSA881X_BOOST_MISC3_CTL, 0x00}, + {WSA881X_BOOST_ATEST_CTL, 0x00}, + {WSA881X_SPKR_PROT_FE_GAIN, 0x46}, + {WSA881X_SPKR_PROT_FE_CM_LDO_SET, 0x3B}, + {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1, 0x8D}, + {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2, 0x8D}, + {WSA881X_SPKR_PROT_ATEST1, 0x01}, + {WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x8D}, + {WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1, 0x4D}, + {WSA881X_SPKR_PROT_SAR, 0x00}, + {WSA881X_SPKR_STATUS3, 0x00}, +}; + +/* Default register reset values for WSA881x rev 2.0 */ +static struct reg_sequence wsa881x_rev_2_0[] = { + {WSA881X_RESET_CTL, 0x00, 0x00}, + {WSA881X_TADC_VALUE_CTL, 0x01, 0x00}, + {WSA881X_INTR_MASK, 0x1B, 0x00}, + {WSA881X_IOPAD_CTL, 0x00, 0x00}, + {WSA881X_OTP_REG_28, 0x3F, 0x00}, + {WSA881X_OTP_REG_29, 0x3F, 0x00}, + {WSA881X_OTP_REG_30, 0x01, 0x00}, + {WSA881X_OTP_REG_31, 0x01, 0x00}, + {WSA881X_TEMP_ADC_CTRL, 0x03, 0x00}, + {WSA881X_ADC_SEL_IBIAS, 0x45, 0x00}, + {WSA881X_SPKR_DRV_GAIN, 0xC1, 0x00}, + {WSA881X_SPKR_DAC_CTL, 0x42, 0x00}, + {WSA881X_SPKR_BBM_CTL, 0x02, 0x00}, + {WSA881X_SPKR_MISC_CTL1, 0x40, 0x00}, + {WSA881X_SPKR_MISC_CTL2, 0x07, 0x00}, + {WSA881X_SPKR_BIAS_INT, 0x5F, 0x00}, + {WSA881X_SPKR_BIAS_PSRR, 0x44, 0x00}, + {WSA881X_BOOST_PS_CTL, 0xA0, 0x00}, + {WSA881X_BOOST_PRESET_OUT1, 0xB7, 0x00}, + {WSA881X_BOOST_LOOP_STABILITY, 0x8D, 0x00}, + {WSA881X_SPKR_PROT_ATEST2, 0x02, 0x00}, + {WSA881X_BONGO_RESRV_REG1, 0x5E, 0x00}, + {WSA881X_BONGO_RESRV_REG2, 0x07, 0x00}, +}; + +/* + * wsa881x_regmap_defaults - update regmap default register values + * @regmap: pointer to regmap structure + * @version: wsa881x version id + * + * Update regmap default register values based on version id + * + */ +void wsa881x_regmap_defaults(struct regmap *regmap, u8 version) +{ + u16 ret = 0; + + if (!regmap) { + pr_debug("%s: regmap structure is NULL\n", __func__); + return; + } + + regcache_cache_only(regmap, true); + ret = regmap_multi_reg_write(regmap, wsa881x_rev_2_0, + ARRAY_SIZE(wsa881x_rev_2_0)); + regcache_cache_only(regmap, false); + + if (ret) + pr_debug("%s: Failed to update regmap defaults ret= %d\n", + __func__, ret); +} +EXPORT_SYMBOL(wsa881x_regmap_defaults); + +static bool wsa881x_readable_register(struct device *dev, unsigned int reg) +{ + return wsa881x_reg_readable[reg]; +} + +static bool wsa881x_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WSA881X_CHIP_ID0: + case WSA881X_CHIP_ID1: + case WSA881X_CHIP_ID2: + case WSA881X_CHIP_ID3: + case WSA881X_BUS_ID: + case WSA881X_TEMP_MSB: + case WSA881X_TEMP_LSB: + case WSA881X_SDM_PDM9_LSB: + case WSA881X_SDM_PDM9_MSB: + case WSA881X_OTP_CTRL1: + case WSA881X_INTR_STATUS: + case WSA881X_ATE_TEST_MODE: + case WSA881X_PIN_STATUS: + case WSA881X_SWR_HM_TEST2: + case WSA881X_SPKR_STATUS1: + case WSA881X_SPKR_STATUS2: + case WSA881X_SPKR_STATUS3: + case WSA881X_OTP_REG_0: + case WSA881X_OTP_REG_1: + case WSA881X_OTP_REG_2: + case WSA881X_OTP_REG_3: + case WSA881X_OTP_REG_4: + case WSA881X_OTP_REG_5: + case WSA881X_OTP_REG_31: + case WSA881X_TEMP_DOUT_MSB: + case WSA881X_TEMP_DOUT_LSB: + case WSA881X_TEMP_OP: + case WSA881X_SPKR_PROT_SAR: + return true; + default: + return false; + } +} + +struct regmap_config wsa881x_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wsa881x_defaults, + .num_reg_defaults = ARRAY_SIZE(wsa881x_defaults), + .max_register = WSA881X_MAX_REGISTER, + .volatile_reg = wsa881x_volatile_register, + .readable_reg = wsa881x_readable_register, + .reg_format_endian = REGMAP_ENDIAN_NATIVE, + .val_format_endian = REGMAP_ENDIAN_NATIVE, + .can_multi_write = true, +}; diff --git a/sound/soc/codecs/wsa881x-tables-analog.c b/sound/soc/codecs/wsa881x-tables-analog.c new file mode 100644 index 000000000000..061ed6fff798 --- /dev/null +++ b/sound/soc/codecs/wsa881x-tables-analog.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "wsa881x-registers-analog.h" + +const u8 wsa881x_ana_reg_readable[WSA881X_CACHE_SIZE] = { + [WSA881X_CHIP_ID0] = 1, + [WSA881X_CHIP_ID1] = 1, + [WSA881X_CHIP_ID2] = 1, + [WSA881X_CHIP_ID3] = 1, + [WSA881X_BUS_ID] = 1, + [WSA881X_CDC_RST_CTL] = 1, + [WSA881X_CDC_TOP_CLK_CTL] = 1, + [WSA881X_CDC_ANA_CLK_CTL] = 1, + [WSA881X_CDC_DIG_CLK_CTL] = 1, + [WSA881X_CLOCK_CONFIG] = 1, + [WSA881X_ANA_CTL] = 1, + [WSA881X_SWR_RESET_EN] = 1, + [WSA881X_RESET_CTL] = 1, + [WSA881X_TADC_VALUE_CTL] = 1, + [WSA881X_TEMP_DETECT_CTL] = 1, + [WSA881X_TEMP_MSB] = 1, + [WSA881X_TEMP_LSB] = 1, + [WSA881X_TEMP_CONFIG0] = 1, + [WSA881X_TEMP_CONFIG1] = 1, + [WSA881X_CDC_CLIP_CTL] = 1, + [WSA881X_SDM_PDM9_LSB] = 1, + [WSA881X_SDM_PDM9_MSB] = 1, + [WSA881X_CDC_RX_CTL] = 1, + [WSA881X_DEM_BYPASS_DATA0] = 1, + [WSA881X_DEM_BYPASS_DATA1] = 1, + [WSA881X_DEM_BYPASS_DATA2] = 1, + [WSA881X_DEM_BYPASS_DATA3] = 1, + [WSA881X_OTP_CTRL0] = 1, + [WSA881X_OTP_CTRL1] = 1, + [WSA881X_HDRIVE_CTL_GROUP1] = 1, + [WSA881X_INTR_MODE] = 1, + [WSA881X_INTR_MASK] = 1, + [WSA881X_INTR_STATUS] = 1, + [WSA881X_INTR_CLEAR] = 1, + [WSA881X_INTR_LEVEL] = 1, + [WSA881X_INTR_SET] = 1, + [WSA881X_INTR_TEST] = 1, + [WSA881X_PDM_TEST_MODE] = 1, + [WSA881X_ATE_TEST_MODE] = 1, + [WSA881X_PIN_CTL_MODE] = 1, + [WSA881X_PIN_CTL_OE] = 1, + [WSA881X_PIN_WDATA_IOPAD] = 1, + [WSA881X_PIN_STATUS] = 1, + [WSA881X_DIG_DEBUG_MODE] = 1, + [WSA881X_DIG_DEBUG_SEL] = 1, + [WSA881X_DIG_DEBUG_EN] = 1, + [WSA881X_SWR_HM_TEST1] = 1, + [WSA881X_SWR_HM_TEST2] = 1, + [WSA881X_TEMP_DETECT_DBG_CTL] = 1, + [WSA881X_TEMP_DEBUG_MSB] = 1, + [WSA881X_TEMP_DEBUG_LSB] = 1, + [WSA881X_SAMPLE_EDGE_SEL] = 1, + [WSA881X_IOPAD_CTL] = 1, + [WSA881X_SPARE_0] = 1, + [WSA881X_SPARE_1] = 1, + [WSA881X_SPARE_2] = 1, + [WSA881X_OTP_REG_0] = 1, + [WSA881X_OTP_REG_1] = 1, + [WSA881X_OTP_REG_2] = 1, + [WSA881X_OTP_REG_3] = 1, + [WSA881X_OTP_REG_4] = 1, + [WSA881X_OTP_REG_5] = 1, + [WSA881X_OTP_REG_6] = 1, + [WSA881X_OTP_REG_7] = 1, + [WSA881X_OTP_REG_8] = 1, + [WSA881X_OTP_REG_9] = 1, + [WSA881X_OTP_REG_10] = 1, + [WSA881X_OTP_REG_11] = 1, + [WSA881X_OTP_REG_12] = 1, + [WSA881X_OTP_REG_13] = 1, + [WSA881X_OTP_REG_14] = 1, + [WSA881X_OTP_REG_15] = 1, + [WSA881X_OTP_REG_16] = 1, + [WSA881X_OTP_REG_17] = 1, + [WSA881X_OTP_REG_18] = 1, + [WSA881X_OTP_REG_19] = 1, + [WSA881X_OTP_REG_20] = 1, + [WSA881X_OTP_REG_21] = 1, + [WSA881X_OTP_REG_22] = 1, + [WSA881X_OTP_REG_23] = 1, + [WSA881X_OTP_REG_24] = 1, + [WSA881X_OTP_REG_25] = 1, + [WSA881X_OTP_REG_26] = 1, + [WSA881X_OTP_REG_27] = 1, + [WSA881X_OTP_REG_28] = 1, + [WSA881X_OTP_REG_29] = 1, + [WSA881X_OTP_REG_30] = 1, + [WSA881X_OTP_REG_31] = 1, + [WSA881X_OTP_REG_63] = 1, + /* Analog Registers */ + [WSA881X_BIAS_REF_CTRL] = 1, + [WSA881X_BIAS_TEST] = 1, + [WSA881X_BIAS_BIAS] = 1, + [WSA881X_TEMP_OP] = 1, + [WSA881X_TEMP_IREF_CTRL] = 1, + [WSA881X_TEMP_ISENS_CTRL] = 1, + [WSA881X_TEMP_CLK_CTRL] = 1, + [WSA881X_TEMP_TEST] = 1, + [WSA881X_TEMP_BIAS] = 1, + [WSA881X_TEMP_ADC_CTRL] = 1, + [WSA881X_TEMP_DOUT_MSB] = 1, + [WSA881X_TEMP_DOUT_LSB] = 1, + [WSA881X_ADC_EN_MODU_V] = 1, + [WSA881X_ADC_EN_MODU_I] = 1, + [WSA881X_ADC_EN_DET_TEST_V] = 1, + [WSA881X_ADC_EN_DET_TEST_I] = 1, + [WSA881X_ADC_SEL_IBIAS] = 1, + [WSA881X_ADC_EN_SEL_IBIAS] = 1, + [WSA881X_SPKR_DRV_EN] = 1, + [WSA881X_SPKR_DRV_GAIN] = 1, + [WSA881X_SPKR_DAC_CTL] = 1, + [WSA881X_SPKR_DRV_DBG] = 1, + [WSA881X_SPKR_PWRSTG_DBG] = 1, + [WSA881X_SPKR_OCP_CTL] = 1, + [WSA881X_SPKR_CLIP_CTL] = 1, + [WSA881X_SPKR_BBM_CTL] = 1, + [WSA881X_SPKR_MISC_CTL1] = 1, + [WSA881X_SPKR_MISC_CTL2] = 1, + [WSA881X_SPKR_BIAS_INT] = 1, + [WSA881X_SPKR_PA_INT] = 1, + [WSA881X_SPKR_BIAS_CAL] = 1, + [WSA881X_SPKR_BIAS_PSRR] = 1, + [WSA881X_SPKR_STATUS1] = 1, + [WSA881X_SPKR_STATUS2] = 1, + [WSA881X_BOOST_EN_CTL] = 1, + [WSA881X_BOOST_CURRENT_LIMIT] = 1, + [WSA881X_BOOST_PS_CTL] = 1, + [WSA881X_BOOST_PRESET_OUT1] = 1, + [WSA881X_BOOST_PRESET_OUT2] = 1, + [WSA881X_BOOST_FORCE_OUT] = 1, + [WSA881X_BOOST_LDO_PROG] = 1, + [WSA881X_BOOST_SLOPE_COMP_ISENSE_FB] = 1, + [WSA881X_BOOST_RON_CTL] = 1, + [WSA881X_BOOST_LOOP_STABILITY] = 1, + [WSA881X_BOOST_ZX_CTL] = 1, + [WSA881X_BOOST_START_CTL] = 1, + [WSA881X_BOOST_MISC1_CTL] = 1, + [WSA881X_BOOST_MISC2_CTL] = 1, + [WSA881X_BOOST_MISC3_CTL] = 1, + [WSA881X_BOOST_ATEST_CTL] = 1, + [WSA881X_SPKR_PROT_FE_GAIN] = 1, + [WSA881X_SPKR_PROT_FE_CM_LDO_SET] = 1, + [WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1] = 1, + [WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2] = 1, + [WSA881X_SPKR_PROT_ATEST1] = 1, + [WSA881X_SPKR_PROT_ATEST2] = 1, + [WSA881X_SPKR_PROT_FE_VSENSE_VCM] = 1, + [WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1] = 1, + [WSA881X_BONGO_RESRV_REG1] = 1, + [WSA881X_BONGO_RESRV_REG2] = 1, + [WSA881X_SPKR_PROT_SAR] = 1, + [WSA881X_SPKR_STATUS3] = 1, +}; diff --git a/sound/soc/codecs/wsa881x-tables.c b/sound/soc/codecs/wsa881x-tables.c new file mode 100644 index 000000000000..4f1212be9c5b --- /dev/null +++ b/sound/soc/codecs/wsa881x-tables.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "wsa881x-registers.h" + +const u8 wsa881x_reg_readable[WSA881X_CACHE_SIZE] = { + [WSA881X_CHIP_ID0] = 1, + [WSA881X_CHIP_ID1] = 1, + [WSA881X_CHIP_ID2] = 1, + [WSA881X_CHIP_ID3] = 1, + [WSA881X_BUS_ID] = 1, + [WSA881X_CDC_RST_CTL] = 1, + [WSA881X_CDC_TOP_CLK_CTL] = 1, + [WSA881X_CDC_ANA_CLK_CTL] = 1, + [WSA881X_CDC_DIG_CLK_CTL] = 1, + [WSA881X_CLOCK_CONFIG] = 1, + [WSA881X_ANA_CTL] = 1, + [WSA881X_SWR_RESET_EN] = 1, + [WSA881X_RESET_CTL] = 1, + [WSA881X_TADC_VALUE_CTL] = 1, + [WSA881X_TEMP_DETECT_CTL] = 1, + [WSA881X_TEMP_MSB] = 1, + [WSA881X_TEMP_LSB] = 1, + [WSA881X_TEMP_CONFIG0] = 1, + [WSA881X_TEMP_CONFIG1] = 1, + [WSA881X_CDC_CLIP_CTL] = 1, + [WSA881X_SDM_PDM9_LSB] = 1, + [WSA881X_SDM_PDM9_MSB] = 1, + [WSA881X_CDC_RX_CTL] = 1, + [WSA881X_DEM_BYPASS_DATA0] = 1, + [WSA881X_DEM_BYPASS_DATA1] = 1, + [WSA881X_DEM_BYPASS_DATA2] = 1, + [WSA881X_DEM_BYPASS_DATA3] = 1, + [WSA881X_OTP_CTRL0] = 1, + [WSA881X_OTP_CTRL1] = 1, + [WSA881X_HDRIVE_CTL_GROUP1] = 1, + [WSA881X_INTR_MODE] = 1, + [WSA881X_INTR_MASK] = 1, + [WSA881X_INTR_STATUS] = 1, + [WSA881X_INTR_CLEAR] = 1, + [WSA881X_INTR_LEVEL] = 1, + [WSA881X_INTR_SET] = 1, + [WSA881X_INTR_TEST] = 1, + [WSA881X_PDM_TEST_MODE] = 1, + [WSA881X_ATE_TEST_MODE] = 1, + [WSA881X_PIN_CTL_MODE] = 1, + [WSA881X_PIN_CTL_OE] = 1, + [WSA881X_PIN_WDATA_IOPAD] = 1, + [WSA881X_PIN_STATUS] = 1, + [WSA881X_DIG_DEBUG_MODE] = 1, + [WSA881X_DIG_DEBUG_SEL] = 1, + [WSA881X_DIG_DEBUG_EN] = 1, + [WSA881X_SWR_HM_TEST1] = 1, + [WSA881X_SWR_HM_TEST2] = 1, + [WSA881X_TEMP_DETECT_DBG_CTL] = 1, + [WSA881X_TEMP_DEBUG_MSB] = 1, + [WSA881X_TEMP_DEBUG_LSB] = 1, + [WSA881X_SAMPLE_EDGE_SEL] = 1, + [WSA881X_IOPAD_CTL] = 1, + [WSA881X_SPARE_0] = 1, + [WSA881X_SPARE_1] = 1, + [WSA881X_SPARE_2] = 1, + [WSA881X_OTP_REG_0] = 1, + [WSA881X_OTP_REG_1] = 1, + [WSA881X_OTP_REG_2] = 1, + [WSA881X_OTP_REG_3] = 1, + [WSA881X_OTP_REG_4] = 1, + [WSA881X_OTP_REG_5] = 1, + [WSA881X_OTP_REG_6] = 1, + [WSA881X_OTP_REG_7] = 1, + [WSA881X_OTP_REG_8] = 1, + [WSA881X_OTP_REG_9] = 1, + [WSA881X_OTP_REG_10] = 1, + [WSA881X_OTP_REG_11] = 1, + [WSA881X_OTP_REG_12] = 1, + [WSA881X_OTP_REG_13] = 1, + [WSA881X_OTP_REG_14] = 1, + [WSA881X_OTP_REG_15] = 1, + [WSA881X_OTP_REG_16] = 1, + [WSA881X_OTP_REG_17] = 1, + [WSA881X_OTP_REG_18] = 1, + [WSA881X_OTP_REG_19] = 1, + [WSA881X_OTP_REG_20] = 1, + [WSA881X_OTP_REG_21] = 1, + [WSA881X_OTP_REG_22] = 1, + [WSA881X_OTP_REG_23] = 1, + [WSA881X_OTP_REG_24] = 1, + [WSA881X_OTP_REG_25] = 1, + [WSA881X_OTP_REG_26] = 1, + [WSA881X_OTP_REG_27] = 1, + [WSA881X_OTP_REG_28] = 1, + [WSA881X_OTP_REG_29] = 1, + [WSA881X_OTP_REG_30] = 1, + [WSA881X_OTP_REG_31] = 1, + [WSA881X_OTP_REG_63] = 1, + /* Analog Registers */ + [WSA881X_BIAS_REF_CTRL] = 1, + [WSA881X_BIAS_TEST] = 1, + [WSA881X_BIAS_BIAS] = 1, + [WSA881X_TEMP_OP] = 1, + [WSA881X_TEMP_IREF_CTRL] = 1, + [WSA881X_TEMP_ISENS_CTRL] = 1, + [WSA881X_TEMP_CLK_CTRL] = 1, + [WSA881X_TEMP_TEST] = 1, + [WSA881X_TEMP_BIAS] = 1, + [WSA881X_TEMP_ADC_CTRL] = 1, + [WSA881X_TEMP_DOUT_MSB] = 1, + [WSA881X_TEMP_DOUT_LSB] = 1, + [WSA881X_ADC_EN_MODU_V] = 1, + [WSA881X_ADC_EN_MODU_I] = 1, + [WSA881X_ADC_EN_DET_TEST_V] = 1, + [WSA881X_ADC_EN_DET_TEST_I] = 1, + [WSA881X_ADC_SEL_IBIAS] = 1, + [WSA881X_ADC_EN_SEL_IBAIS] = 1, + [WSA881X_SPKR_DRV_EN] = 1, + [WSA881X_SPKR_DRV_GAIN] = 1, + [WSA881X_SPKR_DAC_CTL] = 1, + [WSA881X_SPKR_DRV_DBG] = 1, + [WSA881X_SPKR_PWRSTG_DBG] = 1, + [WSA881X_SPKR_OCP_CTL] = 1, + [WSA881X_SPKR_CLIP_CTL] = 1, + [WSA881X_SPKR_BBM_CTL] = 1, + [WSA881X_SPKR_MISC_CTL1] = 1, + [WSA881X_SPKR_MISC_CTL2] = 1, + [WSA881X_SPKR_BIAS_INT] = 1, + [WSA881X_SPKR_PA_INT] = 1, + [WSA881X_SPKR_BIAS_CAL] = 1, + [WSA881X_SPKR_BIAS_PSRR] = 1, + [WSA881X_SPKR_STATUS1] = 1, + [WSA881X_SPKR_STATUS2] = 1, + [WSA881X_BOOST_EN_CTL] = 1, + [WSA881X_BOOST_CURRENT_LIMIT] = 1, + [WSA881X_BOOST_PS_CTL] = 1, + [WSA881X_BOOST_PRESET_OUT1] = 1, + [WSA881X_BOOST_PRESET_OUT2] = 1, + [WSA881X_BOOST_FORCE_OUT] = 1, + [WSA881X_BOOST_LDO_PROG] = 1, + [WSA881X_BOOST_SLOPE_COMP_ISENSE_FB] = 1, + [WSA881X_BOOST_RON_CTL] = 1, + [WSA881X_BOOST_LOOP_STABILITY] = 1, + [WSA881X_BOOST_ZX_CTL] = 1, + [WSA881X_BOOST_START_CTL] = 1, + [WSA881X_BOOST_MISC1_CTL] = 1, + [WSA881X_BOOST_MISC2_CTL] = 1, + [WSA881X_BOOST_MISC3_CTL] = 1, + [WSA881X_BOOST_ATEST_CTL] = 1, + [WSA881X_SPKR_PROT_FE_GAIN] = 1, + [WSA881X_SPKR_PROT_FE_CM_LDO_SET] = 1, + [WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1] = 1, + [WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2] = 1, + [WSA881X_SPKR_PROT_ATEST1] = 1, + [WSA881X_SPKR_PROT_ATEST2] = 1, + [WSA881X_SPKR_PROT_FE_VSENSE_VCM] = 1, + [WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1] = 1, + [WSA881X_BONGO_RESRV_REG1] = 1, + [WSA881X_BONGO_RESRV_REG2] = 1, + [WSA881X_SPKR_PROT_SAR] = 1, + [WSA881X_SPKR_STATUS3] = 1, +}; diff --git a/sound/soc/codecs/wsa881x-temp-sensor.c b/sound/soc/codecs/wsa881x-temp-sensor.c new file mode 100644 index 000000000000..5ab0ecfdc022 --- /dev/null +++ b/sound/soc/codecs/wsa881x-temp-sensor.c @@ -0,0 +1,149 @@ +/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include "wsa881x-temp-sensor.h" + +#define T1_TEMP -10 +#define T2_TEMP 150 +#define LOW_TEMP_THRESHOLD 5 +#define HIGH_TEMP_THRESHOLD 45 +#define TEMP_INVALID 0xFFFF +#define WSA881X_TEMP_RETRY 3 +/* + * wsa881x_get_temp - get wsa temperature + * @thermal: thermal zone device + * @temp: temperature value + * + * Get the temperature of wsa881x. + * + * Return: 0 on success or negative error code on failure. + */ +int wsa881x_get_temp(struct thermal_zone_device *thermal, + int *temp) +{ + struct wsa881x_tz_priv *pdata; + struct snd_soc_codec *codec; + struct wsa_temp_register reg; + int dmeas, d1, d2; + int ret = 0; + int temp_val; + int t1 = T1_TEMP; + int t2 = T2_TEMP; + u8 retry = WSA881X_TEMP_RETRY; + + if (!thermal) + return -EINVAL; + + if (thermal->devdata) { + pdata = thermal->devdata; + if (pdata->codec) { + codec = pdata->codec; + } else { + pr_err("%s: codec is NULL\n", __func__); + return -EINVAL; + } + } else { + pr_err("%s: pdata is NULL\n", __func__); + return -EINVAL; + } +temp_retry: + if (pdata->wsa_temp_reg_read) { + ret = pdata->wsa_temp_reg_read(codec, ®); + if (ret) { + pr_err("%s: temperature register read failed: %d\n", + __func__, ret); + return ret; + } + } else { + pr_err("%s: wsa_temp_reg_read is NULL\n", __func__); + return -EINVAL; + } + /* + * Temperature register values are expected to be in the + * following range. + * d1_msb = 68 - 92 and d1_lsb = 0, 64, 128, 192 + * d2_msb = 185 -218 and d2_lsb = 0, 64, 128, 192 + */ + if ((reg.d1_msb < 68 || reg.d1_msb > 92) || + (!(reg.d1_lsb == 0 || reg.d1_lsb == 64 || reg.d1_lsb == 128 || + reg.d1_lsb == 192)) || + (reg.d2_msb < 185 || reg.d2_msb > 218) || + (!(reg.d2_lsb == 0 || reg.d2_lsb == 64 || reg.d2_lsb == 128 || + reg.d2_lsb == 192))) { + printk_ratelimited("%s: Temperature registers[%d %d %d %d] are out of range\n", + __func__, reg.d1_msb, reg.d1_lsb, reg.d2_msb, + reg.d2_lsb); + } + dmeas = ((reg.dmeas_msb << 0x8) | reg.dmeas_lsb) >> 0x6; + d1 = ((reg.d1_msb << 0x8) | reg.d1_lsb) >> 0x6; + d2 = ((reg.d2_msb << 0x8) | reg.d2_lsb) >> 0x6; + + if (d1 == d2) + temp_val = TEMP_INVALID; + else + temp_val = t1 + (((dmeas - d1) * (t2 - t1))/(d2 - d1)); + + if (temp_val <= LOW_TEMP_THRESHOLD || + temp_val >= HIGH_TEMP_THRESHOLD) { + printk_ratelimited("%s: T0: %d is out of range[%d, %d]\n", + __func__, temp_val, LOW_TEMP_THRESHOLD, + HIGH_TEMP_THRESHOLD); + if (retry--) { + msleep(20); + goto temp_retry; + } + } + if (temp) + *temp = temp_val; + pr_debug("%s: t0 measured: %d dmeas = %d, d1 = %d, d2 = %d\n", + __func__, temp_val, dmeas, d1, d2); + return ret; +} +EXPORT_SYMBOL(wsa881x_get_temp); + +static struct thermal_zone_device_ops wsa881x_thermal_ops = { + .get_temp = wsa881x_get_temp, +}; + +int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata) +{ + struct thermal_zone_device *tz_dev; + + if (tz_pdata == NULL) { + pr_err("%s: thermal pdata is NULL\n", __func__); + return -EINVAL; + } + /* Register with the thermal zone */ + tz_dev = thermal_zone_device_register(tz_pdata->name, + 0, 0, tz_pdata, + &wsa881x_thermal_ops, NULL, 0, 0); + if (IS_ERR(tz_dev)) { + pr_err("%s: thermal device register failed.\n", __func__); + return -EINVAL; + } + tz_pdata->tz_dev = tz_dev; + return 0; +} +EXPORT_SYMBOL(wsa881x_init_thermal); + +void wsa881x_deinit_thermal(struct thermal_zone_device *tz_dev) +{ + if (tz_dev) + thermal_zone_device_unregister(tz_dev); +} +EXPORT_SYMBOL(wsa881x_deinit_thermal); diff --git a/sound/soc/codecs/wsa881x-temp-sensor.h b/sound/soc/codecs/wsa881x-temp-sensor.h new file mode 100644 index 000000000000..d6c1eb75e940 --- /dev/null +++ b/sound/soc/codecs/wsa881x-temp-sensor.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef WSA881X_TEMP_SENSOR_H +#define WSA881X_TEMP_SENSOR_H + +#include +#include + +struct wsa_temp_register { + u8 d1_msb; + u8 d1_lsb; + u8 d2_msb; + u8 d2_lsb; + u8 dmeas_msb; + u8 dmeas_lsb; +}; +typedef int32_t (*wsa_temp_register_read)(struct snd_soc_codec *codec, + struct wsa_temp_register *wsa_temp_reg); +struct wsa881x_tz_priv { + struct thermal_zone_device *tz_dev; + struct snd_soc_codec *codec; + struct wsa_temp_register *wsa_temp_reg; + char name[80]; + wsa_temp_register_read wsa_temp_reg_read; +}; + +int wsa881x_get_temp(struct thermal_zone_device *tz_dev, int *temp); +int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata); +void wsa881x_deinit_thermal(struct thermal_zone_device *tz_dev); +#endif diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c new file mode 100644 index 000000000000..77aea1049ca5 --- /dev/null +++ b/sound/soc/codecs/wsa881x.c @@ -0,0 +1,1439 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wsa881x.h" +#include "wsa881x-temp-sensor.h" + +#define WSA881X_NUM_RETRY 5 + +enum { + G_18DB = 0, + G_16P5DB, + G_15DB, + G_13P5DB, + G_12DB, + G_10P5DB, + G_9DB, + G_7P5DB, + G_6DB, + G_4P5DB, + G_3DB, + G_1P5DB, + G_0DB, +}; + +enum { + DISABLE = 0, + ENABLE, +}; + +enum { + SWR_DAC_PORT, + SWR_COMP_PORT, + SWR_BOOST_PORT, + SWR_VISENSE_PORT, +}; + +struct swr_port { + u8 port_id; + u8 ch_mask; + u32 ch_rate; + u8 num_ch; +}; + +enum { + WSA881X_DEV_DOWN, + WSA881X_DEV_UP, +}; + +/* + * Private data Structure for wsa881x. All parameters related to + * WSA881X codec needs to be defined here. + */ +struct wsa881x_priv { + struct regmap *regmap; + struct device *dev; + struct swr_device *swr_slave; + struct snd_soc_codec *codec; + bool comp_enable; + bool boost_enable; + bool visense_enable; + u8 pa_gain; + struct swr_port port[WSA881X_MAX_SWR_PORTS]; + int pd_gpio; + struct wsa881x_tz_priv tz_pdata; + int bg_cnt; + int clk_cnt; + int version; + struct mutex bg_lock; + struct mutex res_lock; + struct snd_info_entry *entry; + struct snd_info_entry *version_entry; + int state; + struct delayed_work ocp_ctl_work; + struct device_node *wsa_rst_np; + int pa_mute; +}; + +#define SWR_SLV_MAX_REG_ADDR 0x390 +#define SWR_SLV_START_REG_ADDR 0x40 +#define SWR_SLV_MAX_BUF_LEN 20 +#define BYTES_PER_LINE 12 +#define SWR_SLV_RD_BUF_LEN 8 +#define SWR_SLV_WR_BUF_LEN 32 +#define SWR_SLV_MAX_DEVICES 2 + +#define WSA881X_VERSION_ENTRY_SIZE 27 +#define WSA881X_OCP_CTL_TIMER_SEC 2 +#define WSA881X_OCP_CTL_TEMP_CELSIUS 25 +#define WSA881X_OCP_CTL_POLL_TIMER_SEC 60 + +static int wsa881x_ocp_poll_timer_sec = WSA881X_OCP_CTL_POLL_TIMER_SEC; +module_param(wsa881x_ocp_poll_timer_sec, int, 0664); +MODULE_PARM_DESC(wsa881x_ocp_poll_timer_sec, "timer for ocp ctl polling"); + +static struct wsa881x_priv *dbgwsa881x; +static struct dentry *debugfs_wsa881x_dent; +static struct dentry *debugfs_peek; +static struct dentry *debugfs_poke; +static struct dentry *debugfs_reg_dump; +static unsigned int read_data; +static unsigned int devnum; + +static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec, + bool enable); + +static const char * const wsa_pa_gain_text[] = { + "G_18_DB", "G_16P5_DB", "G_15_DB", "G_13P5_DB", "G_12_DB", "G_10P5_DB", + "G_9_DB", "G_7P5_DB", "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB", + "G_0_DB" +}; + +static const struct soc_enum wsa_pa_gain_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa_pa_gain_text), wsa_pa_gain_text); + +static int wsa_pa_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = wsa881x->pa_gain; + + dev_dbg(codec->dev, "%s: PA gain = 0x%x\n", __func__, wsa881x->pa_gain); + + return 0; +} + +static int wsa_pa_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + wsa881x->pa_gain = ucontrol->value.integer.value[0]; + + return 0; +} + +static int wsa881x_get_mute(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = wsa881x->pa_mute; + + return 0; +} + +static int wsa881x_set_mute(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + int value = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: mute current %d, new %d\n", + __func__, wsa881x->pa_mute, value); + + if (value) + snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, 0x80, 0x00); + wsa881x->pa_mute = value; + + return 0; +} + + +static const struct snd_kcontrol_new wsa_snd_controls[] = { + SOC_ENUM_EXT("WSA PA Gain", wsa_pa_gain_enum, + wsa_pa_gain_get, wsa_pa_gain_put), + SOC_SINGLE_EXT("WSA PA Mute", SND_SOC_NOPM, 0, 1, 0, + wsa881x_get_mute, wsa881x_set_mute), +}; + +static int codec_debug_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static int get_parameters(char *buf, u32 *param1, int num_of_par) +{ + char *token; + int base, cnt; + + token = strsep(&buf, " "); + for (cnt = 0; cnt < num_of_par; cnt++) { + if (token) { + if ((token[1] == 'x') || (token[1] == 'X')) + base = 16; + else + base = 10; + + if (kstrtou32(token, base, ¶m1[cnt]) != 0) + return -EINVAL; + + token = strsep(&buf, " "); + } else + return -EINVAL; + } + return 0; +} + +static ssize_t wsa881x_codec_version_read(struct snd_info_entry *entry, + void *file_private_data, struct file *file, + char __user *buf, size_t count, loff_t pos) +{ + struct wsa881x_priv *wsa881x; + char buffer[WSA881X_VERSION_ENTRY_SIZE]; + int len; + + wsa881x = (struct wsa881x_priv *) entry->private_data; + if (!wsa881x) { + pr_err("%s: wsa881x priv is null\n", __func__); + return -EINVAL; + } + + len = snprintf(buffer, sizeof(buffer), "WSA881X-SOUNDWIRE_2_0\n"); + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops wsa881x_codec_info_ops = { + .read = wsa881x_codec_version_read, +}; + +/* + * wsa881x_codec_info_create_codec_entry - creates wsa881x module + * @codec_root: The parent directory + * @codec: Codec instance + * + * Creates wsa881x module and version entry under the given + * parent directory. + * + * Return: 0 on success or negative error code on failure. + */ +int wsa881x_codec_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + struct snd_info_entry *version_entry; + struct wsa881x_priv *wsa881x; + struct snd_soc_card *card; + char name[80]; + + if (!codec_root || !codec) + return -EINVAL; + + wsa881x = snd_soc_codec_get_drvdata(codec); + card = codec->component.card; + snprintf(name, sizeof(name), "%s.%x", "wsa881x", + (u32)wsa881x->swr_slave->addr); + + wsa881x->entry = snd_info_create_subdir(codec_root->module, + (const char *)name, + codec_root); + if (!wsa881x->entry) { + dev_dbg(codec->dev, "%s: failed to create wsa881x entry\n", + __func__); + return -ENOMEM; + } + + version_entry = snd_info_create_card_entry(card->snd_card, + "version", + wsa881x->entry); + if (!version_entry) { + dev_dbg(codec->dev, "%s: failed to create wsa881x version entry\n", + __func__); + return -ENOMEM; + } + + version_entry->private_data = wsa881x; + version_entry->size = WSA881X_VERSION_ENTRY_SIZE; + version_entry->content = SNDRV_INFO_CONTENT_DATA; + version_entry->c.ops = &wsa881x_codec_info_ops; + + if (snd_info_register(version_entry) < 0) { + snd_info_free_entry(version_entry); + return -ENOMEM; + } + wsa881x->version_entry = version_entry; + + return 0; +} +EXPORT_SYMBOL(wsa881x_codec_info_create_codec_entry); + +static bool is_swr_slv_reg_readable(int reg) +{ + bool ret = true; + + if (((reg > 0x46) && (reg < 0x4A)) || + ((reg > 0x4A) && (reg < 0x50)) || + ((reg > 0x55) && (reg < 0xE0)) || + ((reg > 0xE0) && (reg < 0xF0)) || + ((reg > 0xF0) && (reg < 0x100)) || + ((reg > 0x105) && (reg < 0x120)) || + ((reg > 0x128) && (reg < 0x130)) || + ((reg > 0x138) && (reg < 0x200)) || + ((reg > 0x205) && (reg < 0x220)) || + ((reg > 0x228) && (reg < 0x230)) || + ((reg > 0x238) && (reg < 0x300)) || + ((reg > 0x305) && (reg < 0x320)) || + ((reg > 0x328) && (reg < 0x330)) || + ((reg > 0x338) && (reg < 0x400)) || + ((reg > 0x405) && (reg < 0x420))) + ret = false; + + return ret; +} + +static ssize_t wsa881x_swrslave_reg_show(char __user *ubuf, size_t count, + loff_t *ppos) +{ + int i, reg_val, len; + ssize_t total = 0; + char tmp_buf[SWR_SLV_MAX_BUF_LEN]; + + if (!ubuf || !ppos || (devnum == 0)) + return 0; + + for (i = (((int) *ppos / BYTES_PER_LINE) + SWR_SLV_START_REG_ADDR); + i <= SWR_SLV_MAX_REG_ADDR; i++) { + if (!is_swr_slv_reg_readable(i)) + continue; + swr_read(dbgwsa881x->swr_slave, devnum, + i, ®_val, 1); + len = snprintf(tmp_buf, 25, "0x%.3x: 0x%.2x\n", i, + (reg_val & 0xFF)); + if ((total + len) >= count - 1) + break; + if (copy_to_user((ubuf + total), tmp_buf, len)) { + pr_err("%s: fail to copy reg dump\n", __func__); + total = -EFAULT; + goto copy_err; + } + *ppos += len; + total += len; + } + +copy_err: + return total; +} + +static ssize_t codec_debug_read(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + char lbuf[SWR_SLV_RD_BUF_LEN]; + char *access_str; + ssize_t ret_cnt; + + if (!count || !file || !ppos || !ubuf) + return -EINVAL; + + access_str = file->private_data; + if (*ppos < 0) + return -EINVAL; + + if (!strcmp(access_str, "swrslave_peek")) { + snprintf(lbuf, sizeof(lbuf), "0x%x\n", (read_data & 0xFF)); + ret_cnt = simple_read_from_buffer(ubuf, count, ppos, lbuf, + strnlen(lbuf, 7)); + } else if (!strcmp(access_str, "swrslave_reg_dump")) { + ret_cnt = wsa881x_swrslave_reg_show(ubuf, count, ppos); + } else { + pr_err("%s: %s not permitted to read\n", __func__, access_str); + ret_cnt = -EPERM; + } + return ret_cnt; +} + +static ssize_t codec_debug_write(struct file *filp, + const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char lbuf[SWR_SLV_WR_BUF_LEN]; + int rc; + u32 param[5]; + char *access_str; + + if (!filp || !ppos || !ubuf) + return -EINVAL; + + access_str = filp->private_data; + if (cnt > sizeof(lbuf) - 1) + return -EINVAL; + + rc = copy_from_user(lbuf, ubuf, cnt); + if (rc) + return -EFAULT; + + lbuf[cnt] = '\0'; + if (!strcmp(access_str, "swrslave_poke")) { + /* write */ + rc = get_parameters(lbuf, param, 3); + if ((param[0] <= SWR_SLV_MAX_REG_ADDR) && (param[1] <= 0xFF) && + (rc == 0)) + swr_write(dbgwsa881x->swr_slave, param[2], + param[0], ¶m[1]); + else + rc = -EINVAL; + } else if (!strcmp(access_str, "swrslave_peek")) { + /* read */ + rc = get_parameters(lbuf, param, 2); + if ((param[0] <= SWR_SLV_MAX_REG_ADDR) && (rc == 0)) + swr_read(dbgwsa881x->swr_slave, param[1], + param[0], &read_data, 1); + else + rc = -EINVAL; + } else if (!strcmp(access_str, "swrslave_reg_dump")) { + /* reg dump */ + rc = get_parameters(lbuf, param, 1); + if ((rc == 0) && (param[0] > 0) && + (param[0] <= SWR_SLV_MAX_DEVICES)) + devnum = param[0]; + else + rc = -EINVAL; + } + if (rc == 0) + rc = cnt; + else + pr_err("%s: rc = %d\n", __func__, rc); + + return rc; +} + +static const struct file_operations codec_debug_ops = { + .open = codec_debug_open, + .write = codec_debug_write, + .read = codec_debug_read, +}; + +static const struct reg_sequence wsa881x_pre_pmu_pa[] = { + {WSA881X_SPKR_DRV_GAIN, 0x41, 0}, + {WSA881X_SPKR_MISC_CTL1, 0x01, 0}, + {WSA881X_ADC_EN_DET_TEST_I, 0x01, 0}, + {WSA881X_ADC_EN_MODU_V, 0x02, 0}, + {WSA881X_ADC_EN_DET_TEST_V, 0x10, 0}, + {WSA881X_SPKR_PWRSTG_DBG, 0xA0, 0}, +}; + +static const struct reg_sequence wsa881x_pre_pmu_pa_2_0[] = { + {WSA881X_SPKR_DRV_GAIN, 0x41, 0}, + {WSA881X_SPKR_MISC_CTL1, 0x87, 0}, +}; + +static const struct reg_sequence wsa881x_post_pmu_pa[] = { + {WSA881X_SPKR_PWRSTG_DBG, 0x00, 0}, + {WSA881X_ADC_EN_DET_TEST_V, 0x00, 0}, + {WSA881X_ADC_EN_MODU_V, 0x00, 0}, + {WSA881X_ADC_EN_DET_TEST_I, 0x00, 0}, +}; + +static const struct reg_sequence wsa881x_vi_txfe_en[] = { + {WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x85, 0}, + {WSA881X_SPKR_PROT_ATEST2, 0x0A, 0}, + {WSA881X_SPKR_PROT_FE_GAIN, 0xCF, 0}, +}; + +static const struct reg_sequence wsa881x_vi_txfe_en_2_0[] = { + {WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x85, 0}, + {WSA881X_SPKR_PROT_ATEST2, 0x0A, 0}, + {WSA881X_SPKR_PROT_FE_GAIN, 0x47, 0}, +}; + +static int wsa881x_boost_ctrl(struct snd_soc_codec *codec, bool enable) +{ + dev_dbg(codec->dev, "%s: enable:%d\n", __func__, enable); + if (enable) + snd_soc_update_bits(codec, WSA881X_BOOST_EN_CTL, 0x80, 0x80); + else + snd_soc_update_bits(codec, WSA881X_BOOST_EN_CTL, 0x80, 0x00); + /* + * 1.5ms sleep is needed after boost enable/disable as per + * HW requirement + */ + usleep_range(1500, 1510); + return 0; +} + +static int wsa881x_visense_txfe_ctrl(struct snd_soc_codec *codec, bool enable, + u8 isense1_gain, u8 isense2_gain, + u8 vsense_gain) +{ + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, + "%s: enable:%d, isense1 gain: %d, isense2 gain: %d, vsense_gain %d\n", + __func__, enable, isense1_gain, isense2_gain, vsense_gain); + + if (enable) { + regmap_multi_reg_write(wsa881x->regmap, + wsa881x_vi_txfe_en_2_0, + ARRAY_SIZE(wsa881x_vi_txfe_en_2_0)); + } else { + snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_VSENSE_VCM, + 0x08, 0x08); + /* + * 200us sleep is needed after visense txfe disable as per + * HW requirement. + */ + usleep_range(200, 210); + snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_GAIN, + 0x01, 0x00); + } + return 0; +} + +static int wsa881x_visense_adc_ctrl(struct snd_soc_codec *codec, bool enable) +{ + + dev_dbg(codec->dev, "%s: enable:%d\n", __func__, enable); + snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_V, (0x01 << 7), + (enable << 7)); + snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_I, (0x01 << 7), + (enable << 7)); + return 0; +} + +static void wsa881x_bandgap_ctrl(struct snd_soc_codec *codec, bool enable) +{ + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: enable:%d, bg_count:%d\n", __func__, + enable, wsa881x->bg_cnt); + mutex_lock(&wsa881x->bg_lock); + if (enable) { + ++wsa881x->bg_cnt; + if (wsa881x->bg_cnt == 1) { + snd_soc_update_bits(codec, WSA881X_TEMP_OP, + 0x08, 0x08); + /* 400usec sleep is needed as per HW requirement */ + usleep_range(400, 410); + snd_soc_update_bits(codec, WSA881X_TEMP_OP, + 0x04, 0x04); + } + } else { + --wsa881x->bg_cnt; + if (wsa881x->bg_cnt <= 0) { + WARN_ON(wsa881x->bg_cnt < 0); + wsa881x->bg_cnt = 0; + snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x00); + snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x08, 0x00); + } + } + mutex_unlock(&wsa881x->bg_lock); +} + +static void wsa881x_clk_ctrl(struct snd_soc_codec *codec, bool enable) +{ + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: enable:%d, clk_count:%d\n", __func__, + enable, wsa881x->clk_cnt); + mutex_lock(&wsa881x->res_lock); + if (enable) { + ++wsa881x->clk_cnt; + if (wsa881x->clk_cnt == 1) { + snd_soc_write(codec, WSA881X_CDC_DIG_CLK_CTL, 0x01); + snd_soc_write(codec, WSA881X_CDC_ANA_CLK_CTL, 0x01); + } + } else { + --wsa881x->clk_cnt; + if (wsa881x->clk_cnt <= 0) { + WARN_ON(wsa881x->clk_cnt < 0); + wsa881x->clk_cnt = 0; + snd_soc_write(codec, WSA881X_CDC_DIG_CLK_CTL, 0x00); + snd_soc_write(codec, WSA881X_CDC_ANA_CLK_CTL, 0x00); + } + } + mutex_unlock(&wsa881x->res_lock); +} + +static int wsa881x_get_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = wsa881x->comp_enable; + return 0; +} + +static int wsa881x_set_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + int value = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: Compander enable current %d, new %d\n", + __func__, wsa881x->comp_enable, value); + wsa881x->comp_enable = value; + return 0; +} + +static int wsa881x_get_boost(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = wsa881x->boost_enable; + return 0; +} + +static int wsa881x_set_boost(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + int value = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: Boost enable current %d, new %d\n", + __func__, wsa881x->boost_enable, value); + wsa881x->boost_enable = value; + return 0; +} + +static int wsa881x_get_visense(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = wsa881x->visense_enable; + return 0; +} + +static int wsa881x_set_visense(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + int value = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: VIsense enable current %d, new %d\n", + __func__, wsa881x->visense_enable, value); + wsa881x->visense_enable = value; + return 0; +} + +static const struct snd_kcontrol_new wsa881x_snd_controls[] = { + SOC_SINGLE_EXT("COMP Switch", SND_SOC_NOPM, 0, 1, 0, + wsa881x_get_compander, wsa881x_set_compander), + + SOC_SINGLE_EXT("BOOST Switch", SND_SOC_NOPM, 0, 1, 0, + wsa881x_get_boost, wsa881x_set_boost), + + SOC_SINGLE_EXT("VISENSE Switch", SND_SOC_NOPM, 0, 1, 0, + wsa881x_get_visense, wsa881x_set_visense), +}; + +static const struct snd_kcontrol_new swr_dac_port[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static int wsa881x_set_port(struct snd_soc_codec *codec, int port_idx, + u8 *port_id, u8 *num_ch, u8 *ch_mask, u32 *ch_rate) +{ + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + + *port_id = wsa881x->port[port_idx].port_id; + *num_ch = wsa881x->port[port_idx].num_ch; + *ch_mask = wsa881x->port[port_idx].ch_mask; + *ch_rate = wsa881x->port[port_idx].ch_rate; + return 0; +} + +static int wsa881x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + u8 port_id[WSA881X_MAX_SWR_PORTS]; + u8 num_ch[WSA881X_MAX_SWR_PORTS]; + u8 ch_mask[WSA881X_MAX_SWR_PORTS]; + u32 ch_rate[WSA881X_MAX_SWR_PORTS]; + u8 num_port = 0; + + dev_dbg(codec->dev, "%s: event %d name %s\n", __func__, + event, w->name); + if (wsa881x == NULL) + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wsa881x_set_port(codec, SWR_DAC_PORT, + &port_id[num_port], &num_ch[num_port], + &ch_mask[num_port], &ch_rate[num_port]); + ++num_port; + + if (wsa881x->comp_enable) { + wsa881x_set_port(codec, SWR_COMP_PORT, + &port_id[num_port], &num_ch[num_port], + &ch_mask[num_port], &ch_rate[num_port]); + ++num_port; + } + if (wsa881x->boost_enable) { + wsa881x_set_port(codec, SWR_BOOST_PORT, + &port_id[num_port], &num_ch[num_port], + &ch_mask[num_port], &ch_rate[num_port]); + ++num_port; + } + if (wsa881x->visense_enable) { + wsa881x_set_port(codec, SWR_VISENSE_PORT, + &port_id[num_port], &num_ch[num_port], + &ch_mask[num_port], &ch_rate[num_port]); + ++num_port; + } + swr_connect_port(wsa881x->swr_slave, &port_id[0], num_port, + &ch_mask[0], &ch_rate[0], &num_ch[0]); + break; + case SND_SOC_DAPM_POST_PMU: + break; + case SND_SOC_DAPM_PRE_PMD: + break; + case SND_SOC_DAPM_POST_PMD: + port_id[num_port] = wsa881x->port[SWR_DAC_PORT].port_id; + ++num_port; + if (wsa881x->comp_enable) { + port_id[num_port] = + wsa881x->port[SWR_COMP_PORT].port_id; + ++num_port; + } + if (wsa881x->boost_enable) { + port_id[num_port] = + wsa881x->port[SWR_BOOST_PORT].port_id; + ++num_port; + } + if (wsa881x->visense_enable) { + port_id[num_port] = + wsa881x->port[SWR_VISENSE_PORT].port_id; + ++num_port; + } + swr_disconnect_port(wsa881x->swr_slave, &port_id[0], num_port); + break; + default: + break; + } + return 0; +} + +static int wsa881x_rdac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: %s %d boost %d visense %d\n", __func__, + w->name, event, wsa881x->boost_enable, + wsa881x->visense_enable); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wsa881x_resource_acquire(codec, ENABLE); + wsa881x_boost_ctrl(codec, ENABLE); + break; + case SND_SOC_DAPM_POST_PMD: + swr_slvdev_datapath_control(wsa881x->swr_slave, + wsa881x->swr_slave->dev_num, + false); + wsa881x_boost_ctrl(codec, DISABLE); + wsa881x_resource_acquire(codec, DISABLE); + break; + } + return 0; +} + +static int wsa881x_ramp_pa_gain(struct snd_soc_codec *codec, + int min_gain, int max_gain, int udelay) +{ + int val; + + for (val = min_gain; max_gain <= val; val--) { + snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, + 0xF0, val << 4); + /* + * 1ms delay is needed for every step change in gain as per + * HW requirement. + */ + usleep_range(udelay, udelay+10); + } + return 0; +} + +static void wsa881x_ocp_ctl_work(struct work_struct *work) +{ + struct wsa881x_priv *wsa881x; + struct delayed_work *dwork; + struct snd_soc_codec *codec; + int temp_val; + + dwork = to_delayed_work(work); + wsa881x = container_of(dwork, struct wsa881x_priv, ocp_ctl_work); + + codec = wsa881x->codec; + wsa881x_get_temp(wsa881x->tz_pdata.tz_dev, &temp_val); + dev_dbg(codec->dev, " temp = %d\n", temp_val); + + if (temp_val <= WSA881X_OCP_CTL_TEMP_CELSIUS) + snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0x00); + else + snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0); + + schedule_delayed_work(&wsa881x->ocp_ctl_work, + msecs_to_jiffies(wsa881x_ocp_poll_timer_sec * 1000)); +} + +static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + int min_gain, max_gain; + + dev_dbg(codec->dev, "%s: %s %d\n", __func__, w->name, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0x80); + regmap_multi_reg_write(wsa881x->regmap, + wsa881x_pre_pmu_pa_2_0, + ARRAY_SIZE(wsa881x_pre_pmu_pa_2_0)); + swr_slvdev_datapath_control(wsa881x->swr_slave, + wsa881x->swr_slave->dev_num, + true); + /* Set register mode if compander is not enabled */ + if (!wsa881x->comp_enable) + snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, + 0x08, 0x08); + else + snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, + 0x08, 0x00); + + break; + case SND_SOC_DAPM_POST_PMU: + if (!wsa881x->comp_enable) { + max_gain = wsa881x->pa_gain; + /* + * Gain has to set incrementally in 4 steps + * as per HW sequence + */ + if (max_gain > G_4P5DB) + min_gain = G_0DB; + else + min_gain = max_gain + 3; + /* + * 1ms delay is needed before change in gain + * as per HW requirement. + */ + usleep_range(1000, 1010); + wsa881x_ramp_pa_gain(codec, min_gain, max_gain, 1000); + } + if (wsa881x->visense_enable) { + wsa881x_visense_txfe_ctrl(codec, ENABLE, + 0x00, 0x03, 0x01); + snd_soc_update_bits(codec, WSA881X_ADC_EN_SEL_IBAIS, + 0x07, 0x01); + wsa881x_visense_adc_ctrl(codec, ENABLE); + } + schedule_delayed_work(&wsa881x->ocp_ctl_work, + msecs_to_jiffies(WSA881X_OCP_CTL_TIMER_SEC * 1000)); + /* Force remove group */ + swr_remove_from_group(wsa881x->swr_slave, + wsa881x->swr_slave->dev_num); + break; + case SND_SOC_DAPM_POST_PMD: + if (wsa881x->visense_enable) { + wsa881x_visense_adc_ctrl(codec, DISABLE); + wsa881x_visense_txfe_ctrl(codec, DISABLE, + 0x00, 0x01, 0x01); + } + cancel_delayed_work_sync(&wsa881x->ocp_ctl_work); + snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0); + break; + } + return 0; +} + +static const struct snd_soc_dapm_widget wsa881x_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("IN"), + + SND_SOC_DAPM_MIXER_E("SWR DAC_Port", SND_SOC_NOPM, 0, 0, swr_dac_port, + ARRAY_SIZE(swr_dac_port), wsa881x_enable_swr_dac_port, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_DAC_E("RDAC", NULL, WSA881X_SPKR_DAC_CTL, 7, 0, + wsa881x_rdac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_PGA_E("SPKR PGA", WSA881X_SPKR_DRV_EN, 7, 0, NULL, 0, + wsa881x_spkr_pa_event, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_OUTPUT("SPKR"), +}; + +static const struct snd_soc_dapm_route wsa881x_audio_map[] = { + {"SWR DAC_Port", "Switch", "IN"}, + {"RDAC", NULL, "SWR DAC_Port"}, + {"SPKR PGA", NULL, "RDAC"}, + {"SPKR", NULL, "SPKR PGA"}, +}; + +int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, u8 num_port, + unsigned int *ch_mask, unsigned int *ch_rate) +{ + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + int i; + + if (!port || !ch_mask || !ch_rate || + (num_port > WSA881X_MAX_SWR_PORTS)) { + dev_err(codec->dev, + "%s: Invalid port=%pK, ch_mask=%pK, ch_rate=%pK\n", + __func__, port, ch_mask, ch_rate); + return -EINVAL; + } + for (i = 0; i < num_port; i++) { + wsa881x->port[i].port_id = port[i]; + wsa881x->port[i].ch_mask = ch_mask[i]; + wsa881x->port[i].ch_rate = ch_rate[i]; + wsa881x->port[i].num_ch = __sw_hweight8(ch_mask[i]); + } + return 0; +} +EXPORT_SYMBOL(wsa881x_set_channel_map); + +static void wsa881x_init(struct snd_soc_codec *codec) +{ + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + + wsa881x->version = snd_soc_read(codec, WSA881X_CHIP_ID1); + wsa881x_regmap_defaults(wsa881x->regmap, wsa881x->version); + /* Bring out of analog reset */ + snd_soc_update_bits(codec, WSA881X_CDC_RST_CTL, 0x02, 0x02); + /* Bring out of digital reset */ + snd_soc_update_bits(codec, WSA881X_CDC_RST_CTL, 0x01, 0x01); + + snd_soc_update_bits(codec, WSA881X_CLOCK_CONFIG, 0x10, 0x10); + snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0x02, 0x02); + snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL1, 0xC0, 0x80); + snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL1, 0x06, 0x06); + snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_INT, 0xFF, 0x00); + snd_soc_update_bits(codec, WSA881X_SPKR_PA_INT, 0xF0, 0x40); + snd_soc_update_bits(codec, WSA881X_SPKR_PA_INT, 0x0E, 0x0E); + snd_soc_update_bits(codec, WSA881X_BOOST_LOOP_STABILITY, + 0x03, 0x03); + snd_soc_update_bits(codec, WSA881X_BOOST_MISC2_CTL, 0xFF, 0x14); + snd_soc_update_bits(codec, WSA881X_BOOST_START_CTL, 0x80, 0x80); + snd_soc_update_bits(codec, WSA881X_BOOST_START_CTL, 0x03, 0x00); + snd_soc_update_bits(codec, WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, + 0x0C, 0x04); + snd_soc_update_bits(codec, WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, + 0x03, 0x00); + if (snd_soc_read(codec, WSA881X_OTP_REG_0)) + snd_soc_update_bits(codec, WSA881X_BOOST_PRESET_OUT1, + 0xF0, 0x70); + snd_soc_update_bits(codec, WSA881X_BOOST_PRESET_OUT2, + 0xF0, 0x30); + snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, 0x08, 0x08); + snd_soc_update_bits(codec, WSA881X_BOOST_CURRENT_LIMIT, + 0x0F, 0x08); + snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0x30, 0x30); + snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0x0C, 0x00); + snd_soc_update_bits(codec, WSA881X_OTP_REG_28, 0x3F, 0x3A); + snd_soc_update_bits(codec, WSA881X_BONGO_RESRV_REG1, + 0xFF, 0xB2); + snd_soc_update_bits(codec, WSA881X_BONGO_RESRV_REG2, + 0xFF, 0x05); +} + +static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec, + bool enable) +{ + wsa881x_clk_ctrl(codec, enable); + wsa881x_bandgap_ctrl(codec, enable); + return 0; +} + +static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec, + struct wsa_temp_register *wsa_temp_reg) +{ + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct swr_device *dev; + u8 retry = WSA881X_NUM_RETRY; + u8 devnum = 0; + + if (!wsa881x) { + dev_err(codec->dev, "%s: wsa881x is NULL\n", __func__); + return -EINVAL; + } + dev = wsa881x->swr_slave; + if (dev && (wsa881x->state == WSA881X_DEV_DOWN)) { + while (swr_get_logical_dev_num(dev, dev->addr, &devnum) && + retry--) { + /* Retry after 1 msec delay */ + usleep_range(1000, 1100); + } + if (retry == 0) { + dev_err(codec->dev, + "%s get devnum %d for dev addr %lx failed\n", + __func__, devnum, dev->addr); + return -EINVAL; + } + } + mutex_lock(&wsa881x->res_lock); + if (!wsa881x->clk_cnt) { + regcache_mark_dirty(wsa881x->regmap); + regcache_sync(wsa881x->regmap); + } + mutex_unlock(&wsa881x->res_lock); + + wsa881x_resource_acquire(codec, ENABLE); + + snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x00); + wsa_temp_reg->dmeas_msb = snd_soc_read(codec, WSA881X_TEMP_MSB); + wsa_temp_reg->dmeas_lsb = snd_soc_read(codec, WSA881X_TEMP_LSB); + snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x01); + wsa_temp_reg->d1_msb = snd_soc_read(codec, WSA881X_OTP_REG_1); + wsa_temp_reg->d1_lsb = snd_soc_read(codec, WSA881X_OTP_REG_2); + wsa_temp_reg->d2_msb = snd_soc_read(codec, WSA881X_OTP_REG_3); + wsa_temp_reg->d2_lsb = snd_soc_read(codec, WSA881X_OTP_REG_4); + + wsa881x_resource_acquire(codec, DISABLE); + + return 0; +} + +static int wsa881x_probe(struct snd_soc_codec *codec) +{ + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct swr_device *dev; + + if (!wsa881x) + return -EINVAL; + + dev = wsa881x->swr_slave; + wsa881x->codec = codec; + mutex_init(&wsa881x->bg_lock); + mutex_init(&wsa881x->res_lock); + wsa881x_init(codec); + snprintf(wsa881x->tz_pdata.name, sizeof(wsa881x->tz_pdata.name), + "%s.%x", "wsatz", (u8)dev->addr); + wsa881x->bg_cnt = 0; + wsa881x->clk_cnt = 0; + wsa881x->tz_pdata.codec = codec; + wsa881x->tz_pdata.wsa_temp_reg_read = wsa881x_temp_reg_read; + wsa881x_init_thermal(&wsa881x->tz_pdata); + snd_soc_add_codec_controls(codec, wsa_snd_controls, + ARRAY_SIZE(wsa_snd_controls)); + INIT_DELAYED_WORK(&wsa881x->ocp_ctl_work, wsa881x_ocp_ctl_work); + return 0; +} + +static int wsa881x_remove(struct snd_soc_codec *codec) +{ + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + + if (wsa881x->tz_pdata.tz_dev) + wsa881x_deinit_thermal(wsa881x->tz_pdata.tz_dev); + mutex_destroy(&wsa881x->bg_lock); + mutex_destroy(&wsa881x->res_lock); + + return 0; +} + +static struct regmap *wsa881x_get_regmap(struct device *dev) +{ + struct wsa881x_priv *control = swr_get_dev_data(to_swr_device(dev)); + + if (!control) + return NULL; + + return control->regmap; +} + +static struct snd_soc_codec_driver soc_codec_dev_wsa881x = { + .probe = wsa881x_probe, + .remove = wsa881x_remove, + .get_regmap = wsa881x_get_regmap, + .component_driver = { + .controls = wsa881x_snd_controls, + .num_controls = ARRAY_SIZE(wsa881x_snd_controls), + .dapm_widgets = wsa881x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wsa881x_dapm_widgets), + .dapm_routes = wsa881x_audio_map, + .num_dapm_routes = ARRAY_SIZE(wsa881x_audio_map), + }, +}; + +static int wsa881x_gpio_ctrl(struct wsa881x_priv *wsa881x, bool enable) +{ + int ret = 0; + + if (wsa881x->pd_gpio < 0) { + dev_err(wsa881x->dev, "%s: gpio is not valid %d\n", + __func__, wsa881x->pd_gpio); + return -EINVAL; + } + + if (wsa881x->wsa_rst_np) { + if (enable) + ret = msm_cdc_pinctrl_select_active_state( + wsa881x->wsa_rst_np); + else + ret = msm_cdc_pinctrl_select_sleep_state( + wsa881x->wsa_rst_np); + if (ret != 0) + dev_err(wsa881x->dev, + "%s: Failed to turn state %d; ret=%d\n", + __func__, enable, ret); + } else { + if (gpio_is_valid(wsa881x->pd_gpio)) + gpio_direction_output(wsa881x->pd_gpio, enable); + } + + return ret; +} + +static int wsa881x_gpio_init(struct swr_device *pdev) +{ + int ret = 0; + struct wsa881x_priv *wsa881x; + + wsa881x = swr_get_dev_data(pdev); + if (!wsa881x) { + dev_err(&pdev->dev, "%s: wsa881x is NULL\n", __func__); + return -EINVAL; + } + dev_dbg(&pdev->dev, "%s: gpio %d request with name %s\n", + __func__, wsa881x->pd_gpio, dev_name(&pdev->dev)); + ret = gpio_request(wsa881x->pd_gpio, dev_name(&pdev->dev)); + if (ret) { + if (ret == -EBUSY) { + /* GPIO was already requested */ + dev_dbg(&pdev->dev, + "%s: gpio %d is already set to high\n", + __func__, wsa881x->pd_gpio); + ret = 0; + } else { + dev_err(&pdev->dev, "%s: Failed to request gpio %d, err: %d\n", + __func__, wsa881x->pd_gpio, ret); + } + } + return ret; +} + +static int wsa881x_swr_probe(struct swr_device *pdev) +{ + int ret = 0; + struct wsa881x_priv *wsa881x; + u8 devnum = 0; + bool pin_state_current = false; + + wsa881x = devm_kzalloc(&pdev->dev, sizeof(struct wsa881x_priv), + GFP_KERNEL); + if (!wsa881x) + return -ENOMEM; + wsa881x->wsa_rst_np = of_parse_phandle(pdev->dev.of_node, + "qcom,spkr-sd-n-node", 0); + if (!wsa881x->wsa_rst_np) { + dev_dbg(&pdev->dev, "%s: Not using pinctrl, fallback to gpio\n", + __func__); + wsa881x->pd_gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,spkr-sd-n-gpio", 0); + if (wsa881x->pd_gpio < 0) { + dev_err(&pdev->dev, "%s: %s property is not found %d\n", + __func__, "qcom,spkr-sd-n-gpio", + wsa881x->pd_gpio); + goto err; + } + dev_dbg(&pdev->dev, "%s: reset gpio %d\n", __func__, + wsa881x->pd_gpio); + } + swr_set_dev_data(pdev, wsa881x); + + wsa881x->swr_slave = pdev; + + if (!wsa881x->wsa_rst_np) { + ret = wsa881x_gpio_init(pdev); + if (ret) + goto err; + } + if (wsa881x->wsa_rst_np) + pin_state_current = msm_cdc_pinctrl_get_state( + wsa881x->wsa_rst_np); + wsa881x_gpio_ctrl(wsa881x, true); + wsa881x->state = WSA881X_DEV_UP; + + if (!debugfs_wsa881x_dent) { + dbgwsa881x = wsa881x; + debugfs_wsa881x_dent = debugfs_create_dir( + "wsa881x_swr_slave", 0); + if (!IS_ERR(debugfs_wsa881x_dent)) { + debugfs_peek = debugfs_create_file("swrslave_peek", + S_IFREG | 0444, debugfs_wsa881x_dent, + (void *) "swrslave_peek", + &codec_debug_ops); + + debugfs_poke = debugfs_create_file("swrslave_poke", + S_IFREG | 0444, debugfs_wsa881x_dent, + (void *) "swrslave_poke", + &codec_debug_ops); + + debugfs_reg_dump = debugfs_create_file( + "swrslave_reg_dump", + S_IFREG | 0444, + debugfs_wsa881x_dent, + (void *) "swrslave_reg_dump", + &codec_debug_ops); + } + } + + /* + * Add 5msec delay to provide sufficient time for + * soundwire auto enumeration of slave devices as + * as per HW requirement. + */ + usleep_range(5000, 5010); + ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum); + if (ret) { + dev_dbg(&pdev->dev, + "%s get devnum %d for dev addr %lx failed\n", + __func__, devnum, pdev->addr); + goto dev_err; + } + pdev->dev_num = devnum; + + wsa881x->regmap = devm_regmap_init_swr(pdev, + &wsa881x_regmap_config); + if (IS_ERR(wsa881x->regmap)) { + ret = PTR_ERR(wsa881x->regmap); + dev_err(&pdev->dev, "%s: regmap_init failed %d\n", + __func__, ret); + goto dev_err; + } + + ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wsa881x, + NULL, 0); + if (ret) { + dev_err(&pdev->dev, "%s: Codec registration failed\n", + __func__); + goto dev_err; + } + + return 0; + +dev_err: + if (pin_state_current == false) + wsa881x_gpio_ctrl(wsa881x, false); + swr_remove_device(pdev); +err: + return ret; +} + +static int wsa881x_swr_remove(struct swr_device *pdev) +{ + struct wsa881x_priv *wsa881x; + + wsa881x = swr_get_dev_data(pdev); + if (!wsa881x) { + dev_err(&pdev->dev, "%s: wsa881x is NULL\n", __func__); + return -EINVAL; + } + debugfs_remove_recursive(debugfs_wsa881x_dent); + debugfs_wsa881x_dent = NULL; + snd_soc_unregister_codec(&pdev->dev); + if (wsa881x->pd_gpio) + gpio_free(wsa881x->pd_gpio); + swr_set_dev_data(pdev, NULL); + return 0; +} + +static int wsa881x_swr_up(struct swr_device *pdev) +{ + int ret; + struct wsa881x_priv *wsa881x; + + wsa881x = swr_get_dev_data(pdev); + if (!wsa881x) { + dev_err(&pdev->dev, "%s: wsa881x is NULL\n", __func__); + return -EINVAL; + } + ret = wsa881x_gpio_ctrl(wsa881x, true); + if (ret) + dev_err(&pdev->dev, "%s: Failed to enable gpio\n", __func__); + else + wsa881x->state = WSA881X_DEV_UP; + + return ret; +} + +static int wsa881x_swr_down(struct swr_device *pdev) +{ + struct wsa881x_priv *wsa881x; + int ret; + + wsa881x = swr_get_dev_data(pdev); + if (!wsa881x) { + dev_err(&pdev->dev, "%s: wsa881x is NULL\n", __func__); + return -EINVAL; + } + if (delayed_work_pending(&wsa881x->ocp_ctl_work)) + cancel_delayed_work_sync(&wsa881x->ocp_ctl_work); + ret = wsa881x_gpio_ctrl(wsa881x, false); + if (ret) + dev_err(&pdev->dev, "%s: Failed to disable gpio\n", __func__); + else + wsa881x->state = WSA881X_DEV_DOWN; + + return ret; +} + +static int wsa881x_swr_reset(struct swr_device *pdev) +{ + struct wsa881x_priv *wsa881x; + u8 retry = WSA881X_NUM_RETRY; + u8 devnum = 0; + + wsa881x = swr_get_dev_data(pdev); + if (!wsa881x) { + dev_err(&pdev->dev, "%s: wsa881x is NULL\n", __func__); + return -EINVAL; + } + wsa881x->bg_cnt = 0; + wsa881x->clk_cnt = 0; + while (swr_get_logical_dev_num(pdev, pdev->addr, &devnum) && retry--) { + /* Retry after 1 msec delay */ + usleep_range(1000, 1100); + } + pdev->dev_num = devnum; + regcache_mark_dirty(wsa881x->regmap); + regcache_sync(wsa881x->regmap); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int wsa881x_swr_suspend(struct device *dev) +{ + dev_dbg(dev, "%s: system suspend\n", __func__); + return 0; +} + +static int wsa881x_swr_resume(struct device *dev) +{ + struct wsa881x_priv *wsa881x = swr_get_dev_data(to_swr_device(dev)); + + if (!wsa881x) { + dev_err(dev, "%s: wsa881x private data is NULL\n", __func__); + return -EINVAL; + } + dev_dbg(dev, "%s: system resume\n", __func__); + return 0; +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops wsa881x_swr_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(wsa881x_swr_suspend, wsa881x_swr_resume) +}; + +static const struct swr_device_id wsa881x_swr_id[] = { + {"wsa881x", 0}, + {} +}; + +static const struct of_device_id wsa881x_swr_dt_match[] = { + { + .compatible = "qcom,wsa881x", + }, + {} +}; + +static struct swr_driver wsa881x_codec_driver = { + .driver = { + .name = "wsa881x", + .owner = THIS_MODULE, + .pm = &wsa881x_swr_pm_ops, + .of_match_table = wsa881x_swr_dt_match, + }, + .probe = wsa881x_swr_probe, + .remove = wsa881x_swr_remove, + .id_table = wsa881x_swr_id, + .device_up = wsa881x_swr_up, + .device_down = wsa881x_swr_down, + .reset_device = wsa881x_swr_reset, +}; + +static int __init wsa881x_codec_init(void) +{ + return swr_driver_register(&wsa881x_codec_driver); +} + +static void __exit wsa881x_codec_exit(void) +{ + swr_driver_unregister(&wsa881x_codec_driver); +} + +module_init(wsa881x_codec_init); +module_exit(wsa881x_codec_exit); + +MODULE_DESCRIPTION("WSA881x Codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/wsa881x.h b/sound/soc/codecs/wsa881x.h new file mode 100644 index 000000000000..be234ac0cd07 --- /dev/null +++ b/sound/soc/codecs/wsa881x.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _WSA881X_H +#define _WSA881X_H + +#include +#include +#include +#include "wsa881x-registers.h" + +#define WSA881X_MAX_SWR_PORTS 4 + +extern int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, + u8 num_port, unsigned int *ch_mask, + unsigned int *ch_rate); + +extern const u8 wsa881x_reg_readable[WSA881X_CACHE_SIZE]; +extern struct regmap_config wsa881x_regmap_config; +extern int wsa881x_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_codec *codec); +void wsa881x_regmap_defaults(struct regmap *regmap, u8 version); + +#endif /* _WSA881X_H */ diff --git a/sound/soc/msm/Kconfig b/sound/soc/msm/Kconfig new file mode 100644 index 000000000000..c557ae06e95f --- /dev/null +++ b/sound/soc/msm/Kconfig @@ -0,0 +1,283 @@ +menu "MSM SoC Audio support" + +config SND_SOC_MSM_HOSTLESS_PCM + tristate + +config SND_SOC_MSM_QDSP6V2_INTF + bool "SoC Q6 audio driver for MSM/APQ" + depends on MSM_QDSP6_APRV2_GLINK + help + To add support for SoC audio on MSM/APQ. + This will enable all the platform specific + interactions towards DSP. It includes asm, + adm and afe interfaces on the DSP. + +config SND_SOC_QDSP6V2 + tristate "SoC ALSA audio driver for QDSP6V2" + select SND_SOC_MSM_QDSP6V2_INTF + select SND_SOC_COMPRESS + help + To add support for MSM QDSP6V2 Soc Audio. + This will enable sound soc platform specific + audio drivers. This includes q6asm, q6adm, + q6afe interfaces to DSP using apr. + +config SND_SOC_QDSP_DEBUG + bool "QDSP Audio Driver Debug Feature" + help + Configuration to enable debugging utilities for + QDSP6 based audio drivers. One debugging utility + is inducing kernel panic upon encountering critical + errors from DSP audio modules + +config DOLBY_DS2 + bool "Enable Dolby DS2" + depends on SND_SOC_MSM_QDSP6V2_INTF + help + To add support for dolby DAP post processing. + This support is to configure the post processing parameters + to DSP. The configuration includes sending the end point + device, end point dependent post processing parameters and + the various posrt processing parameters + +config DOLBY_LICENSE + bool "Enable Dolby LICENSE" + depends on SND_SOC_MSM_QDSP6V2_INTF + help + To add support for dolby DAP post processing, + and retain DAP set license functionality only. + This is required by Dolby GEF implementation which needs + nothing but dolby license validation functionality in driver. + +config DTS_EAGLE + bool "Enable DTS Eagle Support" + depends on SND_SOC_MSM_QDSP6V2_INTF + select SND_HWDEP + help + To add DTS Eagle support on QDSP6 targets. + Eagle is a DTS pre/post processing + package that includes HeadphoneX. The configuration + includes sending tuning parameters of various modules. + +config DTS_SRS_TM + bool "Enable DTS SRS" + depends on SND_SOC_MSM_QDSP6V2_INTF + help + To add support for DTS SRS post processing. + This support is to configure the post processing + parameters to DSP. The configuration includes sending + tuning parameters of various modules. + +config QTI_PP + bool "Enable QTI PP" + depends on SND_SOC_MSM_QDSP6V2_INTF + help + To add support for default QTI post processing. + This support is to configure the post processing + parameters to DSP. The configuration includes sending + tuning parameters of various modules such as equalizer, + customized mixing. + +config QTI_PP_AUDIOSPHERE + bool "Enable QTI AUDIOSPHERE PP" + depends on SND_SOC_MSM_QDSP6V2_INTF + help + To add support for QTI audio sphere post processing. + This support is to configure the post processing + parameters to DSP. The configuration includes sending + tuning parameters of audio sphere module. + +config SND_SOC_CPE + tristate "CPE drivers" + depends on SND_SOC_WCD_CPE + help + To add support for Codec Processing Engine. This support + is to enable CPE block on the codec and this config needs + to be added to codecs that contain the CPE hardware block. + The configuration includes the cpe lsm driver to enable + listen on codec. + +config SND_SOC_INT_CODEC + tristate "SoC Machine driver for SDM660_INT" + depends on ARCH_QCOM + select SND_SOC_QDSP6V2 + select SND_SOC_MSM_STUB + select SND_SOC_MSM_HOSTLESS_PCM + select SND_DYNAMIC_MINORS + select MSM_QDSP6_APRV2_GLINK + select MSM_QDSP6_SSR + select MSM_QDSP6_PDR + select MSM_QDSP6_NOTIFIER + select MSM_QDSP6V2_CODECS + select MSM_CDC_PINCTRL + select SND_SOC_MSM_SDW + select SND_SOC_SDM660_CDC + select SND_SOC_MSM_HDMI_CODEC_RX + select QTI_PP + select DTS_SRS_TM + select DOLBY_LICENSE + select SND_HWDEP + select MSM_ULTRASOUND + select DTS_EAGLE + select SND_SOC_SDM660_COMMON + select SND_SOC_COMPRESS + select PINCTRL_LPI + help + To add support for SoC audio on MSM_INT. + This will enable sound soc drivers which + interfaces with DSP, also it will enable + the machine driver and the corresponding + DAI-links + +config SND_SOC_EXT_CODEC + tristate "SoC Machine driver for SDM660_EXT" + depends on ARCH_QCOM + select SND_SOC_QDSP6V2 + select SND_SOC_MSM_STUB + select SND_SOC_MSM_HOSTLESS_PCM + select SND_DYNAMIC_MINORS + select MSM_QDSP6_APRV2_GLINK + select MSM_QDSP6_SSR + select MSM_QDSP6_PDR + select MSM_QDSP6_NOTIFIER + select MSM_QDSP6V2_CODECS + select SND_SOC_WCD9335 + select SND_SOC_WCD934X + select SND_SOC_WSA881X + select SND_SOC_MSM_HDMI_CODEC_RX + select MFD_CORE + select QTI_PP + select DTS_SRS_TM + select DOLBY_LICENSE + select SND_SOC_CPE + select SND_SOC_WCD_CPE + select SND_HWDEP + select MSM_ULTRASOUND + select DTS_EAGLE + select SND_SOC_SDM660_COMMON + select SND_SOC_COMPRESS + select PINCTRL_LPI + help + To add support for SoC audio on MSM_EXT. + This will enable sound soc drivers which + interfaces with DSP, also it will enable + the machine driver and the corresponding + DAI-links + +config SND_SOC_MSM8996 + tristate "SoC Machine driver for MSM8996 boards" + depends on ARCH_MSM8996 + select SND_SOC_COMPRESS + select SND_SOC_QDSP6V2 + select SND_SOC_MSM_STUB + select SND_SOC_MSM_HOSTLESS_PCM + select SND_DYNAMIC_MINORS + select MSM_QDSP6_APRV2 + select MSM_QDSP6V2_CODECS + select SND_SOC_WCD9335 + select SND_SOC_WSA881X + select SND_SOC_MSM_HDMI_CODEC_RX + select DTS_SRS_TM + select QTI_PP + select QTI_PP_AUDIOSPHERE + select SND_SOC_CPE + select MSM_ULTRASOUND + select DOLBY_DS2 + select SND_HWDEP + select DTS_EAGLE + help + To add support for SoC audio on MSM8996. + This will enable sound soc drivers which + interfaces with DSP, also it will enable + the machine driver and the corresponding + DAI-links + +config SND_SOC_MACHINE_MSM8998 + tristate "SoC Machine driver for MSM8998 boards" + select SND_SOC_WSA881X + select SND_SOC_WCD9335 + select SND_SOC_WCD934X + select SND_SOC_CPE + + help + To enable the machine driver and the + corresponding DAI-links on MSM8998. + All platform specific audio modules are + enabled here. + +config SND_SOC_MSM8998 + tristate "Sound SoC drivers to interface with DSP" + depends on ARCH_QCOM + select SND_SOC_COMPRESS + select SND_SOC_QDSP6V2 + select SND_SOC_MSM_STUB + select SND_SOC_MSM_HOSTLESS_PCM + select SND_DYNAMIC_MINORS + select MSM_QDSP6_APRV2_GLINK + select MSM_QDSP6_SSR + select MSM_QDSP6_PDR + select MSM_QDSP6_NOTIFIER + select MSM_QDSP6V2_CODECS + select SND_SOC_MSM_HDMI_CODEC_RX + select DTS_SRS_TM + select QTI_PP + select MSM_ULTRASOUND + select DOLBY_LICENSE + select SND_HWDEP + select DTS_EAGLE + help + To add support for SoC audio on MSM8998. + This will enable sound soc drivers which + interfaces with DSP, also it will enable + the machine driver and the corresponding + DAI-links + +config SND_SOC_660 + tristate "SoC Machine driver for SDM660 boards" + depends on ARCH_SDM660 + select SND_SOC_INT_CODEC + select SND_SOC_EXT_CODEC + help + To add support for SoC audio on SDM660. + This will enable sound soc drivers which + interfaces with DSP, also it will enable + the machine driver and the corresponding + DAI-links + +config SND_SOC_MACHINE_SDM845 + tristate "SoC Machine driver for SDM845 boards" + select SND_SOC_WSA881X + select SND_SOC_WCD934X + + help + To enable the machine driver and the + corresponding DAI-links on SDM845. + All platform specific audio modules are + enabled here. + +config SND_SOC_SDM845 + tristate "SoC Machine driver for SDM845 boards" + depends on ARCH_QCOM + select SND_SOC_COMPRESS + select SND_SOC_QDSP6V2 + select SND_SOC_MSM_STUB + select SND_SOC_MSM_HOSTLESS_PCM + select SND_DYNAMIC_MINORS + select MSM_QDSP6_APRV2_GLINK + select MSM_QDSP6_SSR + select MSM_QDSP6_PDR + select MSM_QDSP6_NOTIFIER + select MSM_QDSP6V2_CODECS + select DTS_SRS_TM + select QTI_PP + select MSM_ULTRASOUND + select DOLBY_DS2 + select SND_HWDEP + select DTS_EAGLE + help + To add support for SoC audio on SDM845. + This enables sound soc drivers that interfaces + with DSP. This also enables the machine driver + and the corresponding DAI-links. + +endmenu diff --git a/sound/soc/msm/Makefile b/sound/soc/msm/Makefile new file mode 100644 index 000000000000..caf884322d9e --- /dev/null +++ b/sound/soc/msm/Makefile @@ -0,0 +1,39 @@ +# MSM Machine Support + +snd-soc-hostless-pcm-objs := msm-pcm-hostless.o +obj-$(CONFIG_SND_SOC_MSM_HOSTLESS_PCM) += snd-soc-hostless-pcm.o + +obj-$(CONFIG_SND_SOC_MSM_QDSP6V2_INTF) += qdsp6v2/ + +snd-soc-qdsp6v2-objs := msm-dai-fe.o +obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o + +#for CPE drivers +snd-soc-cpe-objs := msm-cpe-lsm.o +obj-$(CONFIG_SND_SOC_CPE) += snd-soc-cpe.o + +# for MSM8996 sound card driver +snd-soc-msm8996-objs := msm8996.o +obj-$(CONFIG_SND_SOC_MSM8996) += snd-soc-msm8996.o + +# for MSM8998 sound card driver +snd-soc-msm8998-objs := msm8998.o +obj-$(CONFIG_SND_SOC_MACHINE_MSM8998) += snd-soc-msm8998.o + +# for SDM660 sound card driver +snd-soc-sdm660-common-objs := sdm660-common.o +obj-$(CONFIG_SND_SOC_SDM660_COMMON) += snd-soc-sdm660-common.o + +# for SDM660 sound card driver +snd-soc-int-codec-objs := sdm660-internal.o +obj-$(CONFIG_SND_SOC_INT_CODEC) += snd-soc-sdm660-common.o +obj-$(CONFIG_SND_SOC_INT_CODEC) += snd-soc-int-codec.o + +# for SDM660 sound card driver +snd-soc-ext-codec-objs := sdm660-external.o sdm660-ext-dai-links.o +obj-$(CONFIG_SND_SOC_EXT_CODEC) += snd-soc-sdm660-common.o +obj-$(CONFIG_SND_SOC_EXT_CODEC) += snd-soc-ext-codec.o + +# for SDM845 sound card driver +snd-soc-sdm845-objs := sdm845.o +obj-$(CONFIG_SND_SOC_MACHINE_SDM845) += snd-soc-sdm845.o diff --git a/sound/soc/msm/device_event.h b/sound/soc/msm/device_event.h new file mode 100644 index 000000000000..408d114e3c84 --- /dev/null +++ b/sound/soc/msm/device_event.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __DEVICE_EVENT_H +#define __DEVICE_EVENT_H + +#define QC_AUDIO_EXTERNAL_SPK_1_EVENT "qc_ext_spk_1" +#define QC_AUDIO_EXTERNAL_SPK_2_EVENT "qc_ext_spk_2" +#define QC_AUDIO_EXTERNAL_MIC_EVENT "qc_ext_mic" + +#endif /* __DEVICE_EVENT_H */ diff --git a/sound/soc/msm/msm-audio-pinctrl.c b/sound/soc/msm/msm-audio-pinctrl.c new file mode 100644 index 000000000000..f0fba840eb2d --- /dev/null +++ b/sound/soc/msm/msm-audio-pinctrl.c @@ -0,0 +1,316 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include "msm-audio-pinctrl.h" + +/* + * pinctrl -- handle to query pinctrl apis + * cdc lines -- stores pinctrl handles for pinctrl states + * active_set -- maintain the overall pinctrl state + */ +struct cdc_pinctrl_info { + struct pinctrl *pinctrl; + struct pinctrl_state **cdc_lines; + int active_set; +}; + +/* + * gpiosets -- stores all gpiosets mentioned in dtsi file + * gpiosets_comb_names -- stores all possible gpioset combinations + * gpioset_state -- maintains counter for each gpioset + * gpiosets_max -- maintain the total supported gpiosets + * gpiosets_comb_max -- maintain the total gpiosets combinations + */ +struct cdc_gpioset_info { + char **gpiosets; + char **gpiosets_comb_names; + uint8_t *gpioset_state; + int gpiosets_max; + int gpiosets_comb_max; +}; + +static struct cdc_pinctrl_info pinctrl_info[MAX_PINCTRL_CLIENT]; +static struct cdc_gpioset_info gpioset_info[MAX_PINCTRL_CLIENT]; + +/* Finds the index for the gpio set in the dtsi file */ +int msm_get_gpioset_index(enum pinctrl_client client, char *keyword) +{ + int i; + + for (i = 0; i < gpioset_info[client].gpiosets_max; i++) { + if (!(strcmp(gpioset_info[client].gpiosets[i], keyword))) + break; + } + /* Checking if the keyword is present in dtsi or not */ + if (i != gpioset_info[client].gpiosets_max) + return i; + else + return -EINVAL; +} + +/* + * This function reads the following from dtsi file + * 1. All gpio sets + * 2. All combinations of gpio sets + * 3. Pinctrl handles to gpio sets + * + * Returns error if there is + * 1. Problem reading from dtsi file + * 2. Memory allocation failure + */ +int msm_gpioset_initialize(enum pinctrl_client client, + struct device *dev) +{ + struct pinctrl *pinctrl; + const char *gpioset_names = "qcom,msm-gpios"; + const char *gpioset_combinations = "qcom,pinctrl-names"; + const char *gpioset_names_str = NULL; + const char *gpioset_comb_str = NULL; + int num_strings = 0; + int ret = 0; + int i = 0; + + pr_debug("%s\n", __func__); + pinctrl = devm_pinctrl_get(dev); + if (IS_ERR(pinctrl)) { + pr_err("%s: Unable to get pinctrl handle\n", + __func__); + return -EINVAL; + } + pinctrl_info[client].pinctrl = pinctrl; + + /* Reading of gpio sets */ + num_strings = of_property_count_strings(dev->of_node, + gpioset_names); + if (num_strings < 0) { + dev_err(dev, + "%s: missing %s in dt node or length is incorrect\n", + __func__, gpioset_names); + goto err; + } + gpioset_info[client].gpiosets_max = num_strings; + gpioset_info[client].gpiosets = devm_kzalloc(dev, + gpioset_info[client].gpiosets_max * + sizeof(char *), GFP_KERNEL); + if (!gpioset_info[client].gpiosets) { + dev_err(dev, "Can't allocate memory for gpio set names\n"); + ret = -ENOMEM; + goto err; + } + + for (i = 0; i < num_strings; i++) { + ret = of_property_read_string_index(dev->of_node, + gpioset_names, i, &gpioset_names_str); + + gpioset_info[client].gpiosets[i] = devm_kzalloc(dev, + (strlen(gpioset_names_str) + 1), GFP_KERNEL); + + if (!gpioset_info[client].gpiosets[i]) { + dev_err(dev, "%s: Can't allocate gpiosets[%d] data\n", + __func__, i); + ret = -ENOMEM; + goto err; + } + strlcpy(gpioset_info[client].gpiosets[i], + gpioset_names_str, strlen(gpioset_names_str)+1); + gpioset_names_str = NULL; + } + num_strings = 0; + + /* Allocating memory for gpio set counter */ + gpioset_info[client].gpioset_state = devm_kzalloc(dev, + gpioset_info[client].gpiosets_max * + sizeof(uint8_t), GFP_KERNEL); + if (!gpioset_info[client].gpioset_state) { + dev_err(dev, "Can't allocate memory for gpio set counter\n"); + ret = -ENOMEM; + goto err; + } + + /* Reading of all combinations of gpio sets */ + num_strings = of_property_count_strings(dev->of_node, + gpioset_combinations); + if (num_strings < 0) { + dev_err(dev, + "%s: missing %s in dt node or length is incorrect\n", + __func__, gpioset_combinations); + goto err; + } + gpioset_info[client].gpiosets_comb_max = num_strings; + gpioset_info[client].gpiosets_comb_names = devm_kzalloc(dev, + num_strings * sizeof(char *), GFP_KERNEL); + if (!gpioset_info[client].gpiosets_comb_names) { + ret = -ENOMEM; + goto err; + } + + for (i = 0; i < gpioset_info[client].gpiosets_comb_max; i++) { + ret = of_property_read_string_index(dev->of_node, + gpioset_combinations, i, &gpioset_comb_str); + + gpioset_info[client].gpiosets_comb_names[i] = devm_kzalloc(dev, + (strlen(gpioset_comb_str) + 1), GFP_KERNEL); + if (!gpioset_info[client].gpiosets_comb_names[i]) { + ret = -ENOMEM; + goto err; + } + + strlcpy(gpioset_info[client].gpiosets_comb_names[i], + gpioset_comb_str, + strlen(gpioset_comb_str)+1); + pr_debug("%s: GPIO configuration %s\n", + __func__, + gpioset_info[client].gpiosets_comb_names[i]); + gpioset_comb_str = NULL; + } + + /* Allocating memory for handles to pinctrl states */ + pinctrl_info[client].cdc_lines = devm_kzalloc(dev, + num_strings * sizeof(char *), GFP_KERNEL); + if (!pinctrl_info[client].cdc_lines) { + ret = -ENOMEM; + goto err; + } + + /* Get pinctrl handles for gpio sets in dtsi file */ + for (i = 0; i < num_strings; i++) { + pinctrl_info[client].cdc_lines[i] = pinctrl_lookup_state( + pinctrl, + (const char *)gpioset_info[client]. + gpiosets_comb_names[i]); + if (IS_ERR(pinctrl_info[client].cdc_lines[i])) + pr_err("%s: Unable to get pinctrl handle for %s\n", + __func__, gpioset_info[client]. + gpiosets_comb_names[i]); + } + goto success; + +err: + /* Free up memory allocated for gpio set combinations */ + for (i = 0; i < gpioset_info[client].gpiosets_max; i++) { + if (gpioset_info[client].gpiosets[i] != NULL) { + devm_kfree(dev, gpioset_info[client].gpiosets[i]); + gpioset_info[client].gpiosets[i] = NULL; + } + } + if (gpioset_info[client].gpiosets != NULL) { + devm_kfree(dev, gpioset_info[client].gpiosets); + gpioset_info[client].gpiosets = NULL; + } + + /* Free up memory allocated for gpio set combinations */ + for (i = 0; i < gpioset_info[client].gpiosets_comb_max; i++) { + if (gpioset_info[client].gpiosets_comb_names[i] != NULL) { + devm_kfree(dev, + gpioset_info[client].gpiosets_comb_names[i]); + gpioset_info[client].gpiosets_comb_names[i] = NULL; + } + } + if (gpioset_info[client].gpiosets_comb_names != NULL) { + devm_kfree(dev, gpioset_info[client].gpiosets_comb_names); + gpioset_info[client].gpiosets_comb_names = NULL; + } + + /* Free up memory allocated for handles to pinctrl states */ + if (pinctrl_info[client].cdc_lines != NULL) { + devm_kfree(dev, pinctrl_info[client].cdc_lines); + pinctrl_info[client].cdc_lines = NULL; + } + + /* Free up memory allocated for counter of gpio sets */ + if (gpioset_info[client].gpioset_state != NULL) { + devm_kfree(dev, gpioset_info[client].gpioset_state); + gpioset_info[client].gpioset_state = NULL; + } + +success: + return ret; +} + +int msm_gpioset_activate(enum pinctrl_client client, char *keyword) +{ + int ret = 0; + int gp_set = 0; + int active_set = 0; + + gp_set = msm_get_gpioset_index(client, keyword); + if (gp_set < 0) { + pr_err("%s: gpio set name does not exist\n", + __func__); + return gp_set; + } + + if (!gpioset_info[client].gpioset_state[gp_set]) { + /* + * If pinctrl pointer is not valid, + * no need to proceed further + */ + active_set = pinctrl_info[client].active_set; + if (IS_ERR(pinctrl_info[client].cdc_lines[active_set])) + return 0; + + pinctrl_info[client].active_set |= (1 << gp_set); + active_set = pinctrl_info[client].active_set; + pr_debug("%s: pinctrl.active_set: %d\n", __func__, active_set); + + /* Select the appropriate pinctrl state */ + ret = pinctrl_select_state(pinctrl_info[client].pinctrl, + pinctrl_info[client].cdc_lines[active_set]); + } + gpioset_info[client].gpioset_state[gp_set]++; + + return ret; +} + +int msm_gpioset_suspend(enum pinctrl_client client, char *keyword) +{ + int ret = 0; + int gp_set = 0; + int active_set = 0; + + gp_set = msm_get_gpioset_index(client, keyword); + if (gp_set < 0) { + pr_err("%s: gpio set name does not exist\n", + __func__); + return gp_set; + } + + if (gpioset_info[client].gpioset_state[gp_set] == 1) { + pinctrl_info[client].active_set &= ~(1 << gp_set); + /* + * If pinctrl pointer is not valid, + * no need to proceed further + */ + active_set = pinctrl_info[client].active_set; + if (IS_ERR(pinctrl_info[client].cdc_lines[active_set])) + return -EINVAL; + + pr_debug("%s: pinctrl.active_set: %d\n", __func__, + pinctrl_info[client].active_set); + /* Select the appropriate pinctrl state */ + ret = pinctrl_select_state(pinctrl_info[client].pinctrl, + pinctrl_info[client].cdc_lines[pinctrl_info[client]. + active_set]); + } + if (!(gpioset_info[client].gpioset_state[gp_set])) { + pr_err("%s: Invalid call to de activate gpios: %d\n", __func__, + gpioset_info[client].gpioset_state[gp_set]); + return -EINVAL; + } + + gpioset_info[client].gpioset_state[gp_set]--; + + return ret; +} diff --git a/sound/soc/msm/msm-audio-pinctrl.h b/sound/soc/msm/msm-audio-pinctrl.h new file mode 100644 index 000000000000..ec7c6aafdaea --- /dev/null +++ b/sound/soc/msm/msm-audio-pinctrl.h @@ -0,0 +1,43 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MSM_AUDIO_PINCTRL_H +#define __MSM_AUDIO_PINCTRL_H + +enum pinctrl_client { + CLIENT_WCD, + CLIENT_WSA_BONGO_1, + CLIENT_WSA_BONGO_2, + MAX_PINCTRL_CLIENT, +}; + + +/* finds the index for the gpio set in the dtsi file */ +int msm_get_gpioset_index(enum pinctrl_client client, char *keyword); + +/* + * this function reads the following from dtsi file + * 1. all gpio sets + * 2. all combinations of gpio sets + * 3. pinctrl handles to gpio sets + * + * returns error if there is + * 1. problem reading from dtsi file + * 2. memory allocation failure + */ +int msm_gpioset_initialize(enum pinctrl_client client, struct device *dev); + +int msm_gpioset_activate(enum pinctrl_client client, char *keyword); + +int msm_gpioset_suspend(enum pinctrl_client client, char *keyword); + +#endif /* __MSM_AUDIO_PINCTRL_H */ diff --git a/sound/soc/msm/msm-cpe-lsm.c b/sound/soc/msm/msm-cpe-lsm.c new file mode 100644 index 000000000000..7b65dda227b9 --- /dev/null +++ b/sound/soc/msm/msm-cpe-lsm.c @@ -0,0 +1,3342 @@ +/* + * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SAMPLE_RATE_48KHZ 48000 +#define SAMPLE_RATE_16KHZ 16000 +#define LSM_VOICE_WAKEUP_APP_V2 2 +#define AFE_PORT_ID_1 1 +#define AFE_PORT_ID_3 3 +#define AFE_OUT_PORT_2 2 +#define LISTEN_MIN_NUM_PERIODS 2 +#define LISTEN_MAX_NUM_PERIODS 12 +#define LISTEN_MAX_PERIOD_SIZE 61440 +#define LISTEN_MIN_PERIOD_SIZE 320 +#define LISTEN_MAX_STATUS_PAYLOAD_SIZE 256 +#define MSM_CPE_MAX_CUSTOM_PARAM_SIZE 2048 + +#define MSM_CPE_LAB_THREAD_TIMEOUT (3 * (HZ/10)) + +#define MSM_CPE_LSM_GRAB_LOCK(lock, name) \ +{ \ + pr_debug("%s: %s lock acquire\n", \ + __func__, name); \ + mutex_lock(lock); \ +} + +#define MSM_CPE_LSM_REL_LOCK(lock, name) \ +{ \ + pr_debug("%s: %s lock release\n", \ + __func__, name); \ + mutex_unlock(lock); \ +} + +/* Conventional and unconventional sample rate supported */ +static unsigned int supported_sample_rates[] = { + 8000, 16000, 48000, 192000, 384000 +}; + +static struct snd_pcm_hw_constraint_list constraints_sample_rates = { + .count = ARRAY_SIZE(supported_sample_rates), + .list = supported_sample_rates, + .mask = 0, +}; + + +static struct snd_pcm_hardware msm_pcm_hardware_listen = { + .info = (SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE), + .rates = (SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_384000), + .rate_min = 16000, + .rate_max = 384000, + .channels_min = 1, + .channels_max = 1, + .buffer_bytes_max = LISTEN_MAX_NUM_PERIODS * + LISTEN_MAX_PERIOD_SIZE, + .period_bytes_min = LISTEN_MIN_PERIOD_SIZE, + .period_bytes_max = LISTEN_MAX_PERIOD_SIZE, + .periods_min = LISTEN_MIN_NUM_PERIODS, + .periods_max = LISTEN_MAX_NUM_PERIODS, + .fifo_size = 0, +}; + +enum { + AFE_CMD_INVALID = 0, + AFE_CMD_PORT_START, + AFE_CMD_PORT_SUSPEND, + AFE_CMD_PORT_RESUME, + AFE_CMD_PORT_STOP, +}; + +enum cpe_lab_thread_status { + MSM_LSM_LAB_THREAD_STOP, + MSM_LSM_LAB_THREAD_RUNNING, + MSM_LSM_LAB_THREAD_ERROR, +}; + +struct cpe_hw_params { + u32 sample_rate; + u16 sample_size; + u32 buf_sz; + u32 period_count; + u16 channels; +}; + +struct cpe_data_pcm_buf { + u8 *mem; + phys_addr_t phys; +}; + +struct cpe_lsm_lab { + atomic_t in_count; + atomic_t abort_read; + u32 dma_write; + u32 buf_idx; + u32 pcm_size; + enum cpe_lab_thread_status thread_status; + struct cpe_data_pcm_buf *pcm_buf; + wait_queue_head_t period_wait; + struct completion comp; + struct completion thread_complete; +}; + +struct cpe_priv { + void *core_handle; + struct snd_soc_codec *codec; + struct wcd_cpe_lsm_ops lsm_ops; + struct wcd_cpe_afe_ops afe_ops; + bool afe_mad_ctl; + u32 input_port_id; +}; + +struct cpe_lsm_data { + struct device *dev; + struct cpe_lsm_session *lsm_session; + struct mutex lsm_api_lock; + struct cpe_lsm_lab lab; + struct cpe_hw_params hw_params; + struct snd_pcm_substream *substream; + + wait_queue_head_t event_wait; + atomic_t event_avail; + atomic_t event_stop; + + u8 ev_det_status; + u8 ev_det_pld_size; + u8 *ev_det_payload; + + bool cpe_prepared; +}; + +static int msm_cpe_afe_mad_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct cpe_priv *cpe = kcontrol->private_data; + + ucontrol->value.integer.value[0] = cpe->afe_mad_ctl; + return 0; +} + +static int msm_cpe_afe_mad_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct cpe_priv *cpe = kcontrol->private_data; + + cpe->afe_mad_ctl = ucontrol->value.integer.value[0]; + return 0; +} + +static struct snd_kcontrol_new msm_cpe_kcontrols[] = { + SOC_SINGLE_EXT("CPE AFE MAD Enable", SND_SOC_NOPM, 0, 1, 0, + msm_cpe_afe_mad_ctl_get, msm_cpe_afe_mad_ctl_put), +}; + +/* + * cpe_get_private_data: obtain ASoC platform driver private data + * @substream: ASoC substream for which private data to be obtained + */ +static struct cpe_priv *cpe_get_private_data( + struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd; + + if (!substream || !substream->private_data) { + pr_err("%s: %s is invalid\n", + __func__, + (!substream) ? "substream" : "private_data"); + goto err_ret; + } + + rtd = substream->private_data; + + if (!rtd || !rtd->platform) { + pr_err("%s: %s is invalid\n", + __func__, + (!rtd) ? "runtime" : "platform"); + goto err_ret; + } + + return snd_soc_platform_get_drvdata(rtd->platform); + +err_ret: + return NULL; +} + +/* + * cpe_get_lsm_data: obtain the lsm session data given the substream + * @substream: ASoC substream for which lsm session data to be obtained + */ +static struct cpe_lsm_data *cpe_get_lsm_data( + struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + return runtime->private_data; +} + +static void msm_cpe_process_event_status(void *data, + u8 detect_status, u8 size, u8 *payload) +{ + struct cpe_lsm_data *lsm_d = data; + + lsm_d->ev_det_status = detect_status; + lsm_d->ev_det_pld_size = size; + + lsm_d->ev_det_payload = kzalloc(size, GFP_KERNEL); + if (!lsm_d->ev_det_payload) + return; + + memcpy(lsm_d->ev_det_payload, payload, size); + + atomic_set(&lsm_d->event_avail, 1); + wake_up(&lsm_d->event_wait); +} + +static void msm_cpe_process_event_status_done(struct cpe_lsm_data *lsm_data) +{ + kfree(lsm_data->ev_det_payload); + lsm_data->ev_det_payload = NULL; + + lsm_data->ev_det_status = 0; + lsm_data->ev_det_pld_size = 0; +} + +/* + * msm_cpe_afe_port_cntl: Perform the afe port control + * @substream: substream for which afe port command to be performed + * @core_handle: handle to core + * @afe_ops: handle to the afe operations + * @afe_cfg: afe port configuration data + * @cmd: command to be sent to AFE + * + */ +static int msm_cpe_afe_port_cntl( + struct snd_pcm_substream *substream, + void *core_handle, + struct wcd_cpe_afe_ops *afe_ops, + struct wcd_cpe_afe_port_cfg *afe_cfg, + int cmd) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int rc = 0; + + if (!afe_cfg->port_id) { + /* + * It is possible driver can get closed without prepare, + * in which case afe ports will not be initialized. + */ + dev_dbg(rtd->dev, + "%s: Invalid afe port id\n", + __func__); + return 0; + } + + switch (cmd) { + case AFE_CMD_PORT_START: + rc = afe_ops->afe_port_start(core_handle, afe_cfg); + if (rc != 0) + dev_err(rtd->dev, + "%s: AFE port start failed\n", + __func__); + break; + case AFE_CMD_PORT_SUSPEND: + rc = afe_ops->afe_port_suspend(core_handle, afe_cfg); + if (rc != 0) + dev_err(rtd->dev, + "%s: afe_suspend failed, err = %d\n", + __func__, rc); + break; + case AFE_CMD_PORT_RESUME: + rc = afe_ops->afe_port_resume(core_handle, afe_cfg); + if (rc != 0) + dev_err(rtd->dev, + "%s: afe_resume failed, err = %d\n", + __func__, rc); + break; + case AFE_CMD_PORT_STOP: + rc = afe_ops->afe_port_stop(core_handle, afe_cfg); + if (rc != 0) + dev_err(rtd->dev, + "%s: afe_stopfailed, err = %d\n", + __func__, rc); + break; + } + + return rc; +} + +static int msm_cpe_lsm_lab_stop(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct cpe_lsm_data *lsm_d = cpe_get_lsm_data(substream); + struct cpe_priv *cpe = cpe_get_private_data(substream); + struct wcd_cpe_lsm_ops *lsm_ops; + struct wcd_cpe_afe_ops *afe_ops; + struct cpe_lsm_session *session; + struct cpe_lsm_lab *lab_d = &lsm_d->lab; + struct msm_slim_dma_data *dma_data = NULL; + int rc; + + /* + * the caller is not aware of LAB status and will + * try to stop lab even if it is already stopped. + * return success right away is LAB is already stopped + */ + if (lab_d->thread_status == MSM_LSM_LAB_THREAD_STOP) { + dev_dbg(rtd->dev, + "%s: lab already stopped\n", + __func__); + return 0; + } + + if (!cpe || !cpe->core_handle) { + dev_err(rtd->dev, + "%s: Invalid private data\n", + __func__); + return -EINVAL; + } + + if (!lsm_d->lsm_session) { + dev_err(rtd->dev, + "%s: Invalid session data\n", + __func__); + return -EINVAL; + } + + lsm_ops = &cpe->lsm_ops; + afe_ops = &cpe->afe_ops; + session = lsm_d->lsm_session; + if (rtd->cpu_dai) + dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, + substream); + if (!dma_data || !dma_data->dai_channel_ctl) { + dev_err(rtd->dev, + "%s: dma_data is not set\n", + __func__); + return -EINVAL; + } + + if (lab_d->thread_status == MSM_LSM_LAB_THREAD_RUNNING) { + dev_dbg(rtd->dev, "%s: stopping lab thread\n", + __func__); + rc = kthread_stop(session->lsm_lab_thread); + + /* + * kthread_stop returns EINTR if the thread_fn + * was not scheduled before calling kthread_stop. + * In this case, we dont need to wait for lab + * thread to complete as lab thread will not be + * scheduled at all. + */ + if (rc == -EINTR) + goto done; + + /* Wait for the lab thread to exit */ + rc = wait_for_completion_timeout( + &lab_d->thread_complete, + MSM_CPE_LAB_THREAD_TIMEOUT); + if (!rc) { + dev_err(rtd->dev, + "%s: Wait for lab thread timedout\n", + __func__); + return -ETIMEDOUT; + } + } + + rc = lsm_ops->lab_ch_setup(cpe->core_handle, + session, + WCD_CPE_PRE_DISABLE); + if (rc) + dev_err(rtd->dev, + "%s: PRE ch teardown failed, err = %d\n", + __func__, rc); + /* continue with teardown even if any intermediate step fails */ + rc = dma_data->dai_channel_ctl(dma_data, rtd->cpu_dai, false); + if (rc) + dev_err(rtd->dev, + "%s: open data failed %d\n", __func__, rc); + dma_data->ph = 0; + + /* + * Even though LAB stop failed, + * output AFE port needs to be stopped + */ + rc = afe_ops->afe_port_stop(cpe->core_handle, + &session->afe_out_port_cfg); + if (rc) + dev_err(rtd->dev, + "%s: AFE out port stop failed, err = %d\n", + __func__, rc); + + rc = lsm_ops->lab_ch_setup(cpe->core_handle, + session, + WCD_CPE_POST_DISABLE); + if (rc) + dev_err(rtd->dev, + "%s: POST ch teardown failed, err = %d\n", + __func__, rc); + +done: + lab_d->thread_status = MSM_LSM_LAB_THREAD_STOP; + lab_d->buf_idx = 0; + atomic_set(&lab_d->in_count, 0); + lab_d->dma_write = 0; + + return 0; +} + +static int msm_cpe_lab_buf_alloc(struct snd_pcm_substream *substream, + struct cpe_lsm_session *session, + struct msm_slim_dma_data *dma_data) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct cpe_lsm_data *lsm_d = cpe_get_lsm_data(substream); + struct cpe_lsm_lab *lab_d = &lsm_d->lab; + struct cpe_hw_params *hw_params = &lsm_d->hw_params; + struct cpe_data_pcm_buf *pcm_buf = NULL; + int rc = 0; + int dma_alloc = 0; + u32 count = 0; + u32 bufsz, bufcnt; + + if (lab_d->pcm_buf && + lab_d->pcm_buf->mem) { + dev_dbg(rtd->dev, + "%s: LAB buf already allocated\n", + __func__); + goto exit; + } + + bufsz = hw_params->buf_sz; + bufcnt = hw_params->period_count; + + dev_dbg(rtd->dev, + "%s:Buf Size %d Buf count %d\n", + __func__, + bufsz, bufcnt); + + pcm_buf = kzalloc(((sizeof(struct cpe_data_pcm_buf)) * bufcnt), + GFP_KERNEL); + if (!pcm_buf) { + rc = -ENOMEM; + goto exit; + } + + lab_d->pcm_buf = pcm_buf; + dma_alloc = bufsz * bufcnt; + pcm_buf->mem = NULL; + pcm_buf->mem = dma_alloc_coherent(dma_data->sdev->dev.parent, + dma_alloc, + &(pcm_buf->phys), + GFP_KERNEL); + if (!pcm_buf->mem) { + dev_err(rtd->dev, + "%s:DMA alloc failed size = %x\n", + __func__, dma_alloc); + rc = -ENOMEM; + goto fail; + } + + count = 0; + while (count < bufcnt) { + pcm_buf[count].mem = pcm_buf[0].mem + (count * bufsz); + pcm_buf[count].phys = pcm_buf[0].phys + (count * bufsz); + dev_dbg(rtd->dev, + "%s: pcm_buf[%d].mem %pK pcm_buf[%d].phys %pK\n", + __func__, count, + (void *)pcm_buf[count].mem, + count, &(pcm_buf[count].phys)); + count++; + } + + return 0; +fail: + if (pcm_buf) { + if (pcm_buf->mem) + dma_free_coherent(dma_data->sdev->dev.parent, dma_alloc, + pcm_buf->mem, pcm_buf->phys); + kfree(pcm_buf); + lab_d->pcm_buf = NULL; + } +exit: + return rc; +} + +static int msm_cpe_lab_buf_dealloc(struct snd_pcm_substream *substream, + struct cpe_lsm_session *session, struct msm_slim_dma_data *dma_data) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct cpe_lsm_data *lsm_d = cpe_get_lsm_data(substream); + struct cpe_lsm_lab *lab_d = &lsm_d->lab; + struct cpe_hw_params *hw_params = &lsm_d->hw_params; + int rc = 0; + int dma_alloc = 0; + struct cpe_data_pcm_buf *pcm_buf = NULL; + int bufsz, bufcnt; + + bufsz = hw_params->buf_sz; + bufcnt = hw_params->period_count; + + dev_dbg(rtd->dev, + "%s:Buf Size %d Buf count %d\n", __func__, + bufsz, bufcnt); + + if (bufcnt <= 0 || bufsz <= 0) { + dev_err(rtd->dev, + "%s: Invalid params, bufsz = %u, bufcnt = %u\n", + __func__, bufsz, bufcnt); + return -EINVAL; + } + + pcm_buf = lab_d->pcm_buf; + dma_alloc = bufsz * bufcnt; + if (dma_data && pcm_buf) + dma_free_coherent(dma_data->sdev->dev.parent, dma_alloc, + pcm_buf->mem, pcm_buf->phys); + kfree(pcm_buf); + lab_d->pcm_buf = NULL; + return rc; +} + +/* + * msm_cpe_lab_thread: Initiated on KW detection + * @data: lab data + * + * Start lab thread and call CPE core API for SLIM + * read operations. + */ +static int msm_cpe_lab_thread(void *data) +{ + struct cpe_lsm_data *lsm_d = data; + struct cpe_lsm_session *session = lsm_d->lsm_session; + struct snd_pcm_substream *substream = lsm_d->substream; + struct cpe_lsm_lab *lab_d = &lsm_d->lab; + struct cpe_hw_params *hw_params = &lsm_d->hw_params; + struct cpe_priv *cpe = cpe_get_private_data(substream); + struct wcd_cpe_lsm_ops *lsm_ops; + struct wcd_cpe_afe_ops *afe_ops; + struct cpe_data_pcm_buf *cur_buf, *next_buf; + struct msm_slim_dma_data *dma_data = NULL; + struct snd_soc_pcm_runtime *rtd = NULL; + bool wait_timedout = false; + int rc = 0; + u32 done_len = 0; + u32 buf_count = 0; + u32 prd_cnt; + + allow_signal(SIGKILL); + set_current_state(TASK_INTERRUPTIBLE); + + pr_debug("%s: Lab thread start\n", __func__); + init_completion(&lab_d->comp); + + if (PCM_RUNTIME_CHECK(substream)) { + rc = -EINVAL; + goto done; + } + + if (!cpe || !cpe->core_handle) { + pr_err("%s: Handle to %s is invalid\n", + __func__, + (!cpe) ? "cpe" : "core"); + rc = -EINVAL; + goto done; + } + + rtd = substream->private_data; + if (rtd->cpu_dai) + dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, + substream); + if (!dma_data || !dma_data->dai_channel_ctl) { + pr_err("%s: dma_data is not set\n", __func__); + rc = -EINVAL; + goto done; + } + + lsm_ops = &cpe->lsm_ops; + afe_ops = &cpe->afe_ops; + + rc = lsm_ops->lab_ch_setup(cpe->core_handle, + session, + WCD_CPE_PRE_ENABLE); + if (rc) { + dev_err(rtd->dev, + "%s: PRE ch setup failed, err = %d\n", + __func__, rc); + goto done; + } + + rc = dma_data->dai_channel_ctl(dma_data, rtd->cpu_dai, true); + if (rc) { + dev_err(rtd->dev, + "%s: open data failed %d\n", __func__, rc); + goto done; + } + + dev_dbg(rtd->dev, "%s: Established data channel\n", + __func__); + + init_waitqueue_head(&lab_d->period_wait); + memset(lab_d->pcm_buf[0].mem, 0, lab_d->pcm_size); + + rc = slim_port_xfer(dma_data->sdev, dma_data->ph, + lab_d->pcm_buf[0].phys, + hw_params->buf_sz, &lab_d->comp); + if (rc) { + dev_err(rtd->dev, + "%s: buf[0] slim_port_xfer failed, err = %d\n", + __func__, rc); + goto done; + } + + rc = slim_port_xfer(dma_data->sdev, dma_data->ph, + lab_d->pcm_buf[1].phys, + hw_params->buf_sz, &lab_d->comp); + if (rc) { + dev_err(rtd->dev, + "%s: buf[0] slim_port_xfer failed, err = %d\n", + __func__, rc); + goto done; + } + + cur_buf = &lab_d->pcm_buf[0]; + next_buf = &lab_d->pcm_buf[2]; + prd_cnt = hw_params->period_count; + rc = lsm_ops->lab_ch_setup(cpe->core_handle, + session, + WCD_CPE_POST_ENABLE); + if (rc) { + dev_err(rtd->dev, + "%s: POST ch setup failed, err = %d\n", + __func__, rc); + goto done; + } + + rc = afe_ops->afe_port_start(cpe->core_handle, + &session->afe_out_port_cfg); + if (rc) { + dev_err(rtd->dev, + "%s: AFE out port start failed, err = %d\n", + __func__, rc); + goto done; + } + + while (!kthread_should_stop() && + lab_d->thread_status != MSM_LSM_LAB_THREAD_ERROR) { + + rc = slim_port_xfer(dma_data->sdev, dma_data->ph, + next_buf->phys, + hw_params->buf_sz, &lab_d->comp); + if (rc) { + dev_err(rtd->dev, + "%s: slim_port_xfer failed, err = %d\n", + __func__, rc); + lab_d->thread_status = MSM_LSM_LAB_THREAD_ERROR; + } + + rc = wait_for_completion_timeout(&lab_d->comp, (2 * HZ/10)); + if (!rc) { + dev_err(rtd->dev, + "%s: wait timedout for slim buffer\n", + __func__); + wait_timedout = true; + } else { + wait_timedout = false; + } + + rc = slim_port_get_xfer_status(dma_data->sdev, + dma_data->ph, + &cur_buf->phys, &done_len); + if (rc || + (!rc && wait_timedout)) { + dev_err(rtd->dev, + "%s: xfer_status failure, rc = %d, wait_timedout = %s\n", + __func__, rc, + (wait_timedout ? "true" : "false")); + lab_d->thread_status = MSM_LSM_LAB_THREAD_ERROR; + } + + if (done_len || + ((!done_len) && + lab_d->thread_status == MSM_LSM_LAB_THREAD_ERROR)) { + atomic_inc(&lab_d->in_count); + lab_d->dma_write += snd_pcm_lib_period_bytes(substream); + snd_pcm_period_elapsed(substream); + wake_up(&lab_d->period_wait); + buf_count++; + + cur_buf = &lab_d->pcm_buf[buf_count % prd_cnt]; + next_buf = &lab_d->pcm_buf[(buf_count + 2) % prd_cnt]; + dev_dbg(rtd->dev, + "%s: Cur buf.mem = %pK Next Buf.mem = %pK\n" + " buf count = 0x%x\n", __func__, + cur_buf->mem, next_buf->mem, buf_count); + } else { + dev_err(rtd->dev, + "%s: SB get status, invalid len = 0x%x\n", + __func__, done_len); + } + done_len = 0; + } + +done: + if (rc) + lab_d->thread_status = MSM_LSM_LAB_THREAD_ERROR; + pr_debug("%s: Exit lab_thread, exit_status=%d, thread_status=%d\n", + __func__, rc, lab_d->thread_status); + complete(&lab_d->thread_complete); + + return 0; +} + +/* + * msm_cpe_lsm_open: ASoC call to open the stream + * @substream: substream that is to be opened + * + * Create session data for lsm session and open the lsm session + * on CPE. + */ +static int msm_cpe_lsm_open(struct snd_pcm_substream *substream) +{ + struct cpe_lsm_data *lsm_d; + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct cpe_priv *cpe = cpe_get_private_data(substream); + struct wcd_cpe_lsm_ops *lsm_ops; + int rc = 0; + + if (!cpe || !cpe->codec) { + dev_err(rtd->dev, + "%s: Invalid private data\n", + __func__); + return -EINVAL; + } + + runtime->hw = msm_pcm_hardware_listen; + + rc = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_sample_rates); + if (rc < 0) { + pr_err("snd_pcm_hw_constraint_list failed rc %d\n", rc); + return -EINVAL; + } + + /* Ensure that buffer size is a multiple of period size */ + rc = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (rc < 0) { + pr_err("%s: Unable to set pcm_param_periods, rc %d\n", + __func__, rc); + return -EINVAL; + } + + rc = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, + LISTEN_MIN_NUM_PERIODS * LISTEN_MIN_PERIOD_SIZE, + LISTEN_MAX_NUM_PERIODS * LISTEN_MAX_PERIOD_SIZE); + if (rc < 0) { + pr_err("%s: Unable to set pcm constraints, rc %d\n", + __func__, rc); + return -EINVAL; + } + + cpe->core_handle = wcd_cpe_get_core_handle(cpe->codec); + + if (!cpe->core_handle) { + dev_err(rtd->dev, + "%s: Invalid handle to codec core\n", + __func__); + return -EINVAL; + } + + lsm_ops = &cpe->lsm_ops; + lsm_d = kzalloc(sizeof(struct cpe_lsm_data), GFP_KERNEL); + if (!lsm_d) { + dev_err(rtd->dev, + "%s: ENOMEM for lsm session, size = %zd\n", + __func__, sizeof(struct cpe_lsm_data)); + rc = -ENOMEM; + goto fail_return; + } + mutex_init(&lsm_d->lsm_api_lock); + + lsm_d->lsm_session = lsm_ops->lsm_alloc_session(cpe->core_handle, + lsm_d, msm_cpe_process_event_status); + if (!lsm_d->lsm_session) { + dev_err(rtd->dev, + "%s: session allocation failed", + __func__); + rc = -EINVAL; + goto fail_session_alloc; + } + /* Explicitly Assign the LAB thread to STOP state */ + lsm_d->lab.thread_status = MSM_LSM_LAB_THREAD_STOP; + lsm_d->lsm_session->started = false; + lsm_d->substream = substream; + init_waitqueue_head(&lsm_d->lab.period_wait); + lsm_d->cpe_prepared = false; + + dev_dbg(rtd->dev, "%s: allocated session with id = %d\n", + __func__, lsm_d->lsm_session->id); + + + rc = lsm_ops->lsm_open_tx(cpe->core_handle, lsm_d->lsm_session, + LSM_VOICE_WAKEUP_APP_V2, 16000); + if (rc < 0) { + dev_err(rtd->dev, + "%s: OPEN_TX cmd failed, err = %d\n", + __func__, rc); + goto fail_open_tx; + } + + init_waitqueue_head(&lsm_d->event_wait); + atomic_set(&lsm_d->event_avail, 0); + atomic_set(&lsm_d->event_stop, 0); + runtime->private_data = lsm_d; + + return 0; + +fail_open_tx: + lsm_ops->lsm_dealloc_session(cpe->core_handle, lsm_d->lsm_session); + +fail_session_alloc: + mutex_destroy(&lsm_d->lsm_api_lock); + kfree(lsm_d); +fail_return: + return rc; +} + +/* + * msm_cpe_lsm_close: ASoC call to close/cleanup the stream + * @substream: substream that is to be closed + * + * Deallocate the session and release the AFE port. It is not + * required to deregister the sound model as long as we close + * the lsm session on CPE. + */ +static int msm_cpe_lsm_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct cpe_lsm_data *lsm_d = cpe_get_lsm_data(substream); + struct cpe_priv *cpe = cpe_get_private_data(substream); + struct wcd_cpe_lsm_ops *lsm_ops; + struct cpe_lsm_session *session; + struct wcd_cpe_afe_ops *afe_ops; + struct wcd_cpe_afe_port_cfg *afe_cfg; + int rc = 0; + + if (!cpe || !cpe->core_handle) { + dev_err(rtd->dev, + "%s: Invalid private data\n", + __func__); + return -EINVAL; + } + + if (!lsm_d || !lsm_d->lsm_session) { + dev_err(rtd->dev, + "%s: Invalid session data\n", + __func__); + return -EINVAL; + } + + lsm_ops = &cpe->lsm_ops; + session = lsm_d->lsm_session; + afe_ops = &cpe->afe_ops; + afe_cfg = &(lsm_d->lsm_session->afe_port_cfg); + + /* + * If driver is closed without stopping LAB, + * explicitly stop LAB before cleaning up the + * driver resources. + */ + rc = msm_cpe_lsm_lab_stop(substream); + if (rc) { + dev_err(rtd->dev, + "%s: Failed to stop lab, error = %d\n", + __func__, rc); + return rc; + } + + rc = msm_cpe_afe_port_cntl(substream, + cpe->core_handle, + afe_ops, afe_cfg, + AFE_CMD_PORT_STOP); + + lsm_d->cpe_prepared = false; + + rc = lsm_ops->lsm_close_tx(cpe->core_handle, session); + if (rc != 0) { + dev_err(rtd->dev, + "%s: lsm_close fail, err = %d\n", + __func__, rc); + return rc; + } + + lsm_ops->lsm_dealloc_session(cpe->core_handle, session); + runtime->private_data = NULL; + mutex_destroy(&lsm_d->lsm_api_lock); + kfree(lsm_d); + + return rc; +} + +static int msm_cpe_lsm_get_conf_levels( + struct cpe_lsm_session *session, + u8 *conf_levels_ptr) +{ + int rc = 0; + + if (session->num_confidence_levels <= 0) { + pr_debug("%s: conf_levels (%u), skip set params\n", + __func__, + session->num_confidence_levels); + goto done; + } + + session->conf_levels = kzalloc(session->num_confidence_levels, + GFP_KERNEL); + if (!session->conf_levels) { + rc = -ENOMEM; + goto done; + } + + if (copy_from_user(session->conf_levels, + conf_levels_ptr, + session->num_confidence_levels)) { + pr_err("%s: copy_from_user failed for confidence levels %u\n", + __func__, session->num_confidence_levels); + kfree(session->conf_levels); + session->conf_levels = NULL; + rc = -EFAULT; + goto done; + } + +done: + return rc; +} + +static int msm_cpe_lsm_validate_out_format( + struct snd_pcm_substream *substream, + struct snd_lsm_output_format_cfg *cfg) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int rc = 0; + + if (!cfg) { + dev_err(rtd->dev, + "%s: Invalid lsm out cfg\n", __func__); + rc = -EINVAL; + goto done; + } + + if (cfg->format != LSM_OUT_FORMAT_PCM && + cfg->format != LSM_OUT_FORMAT_ADPCM) { + dev_err(rtd->dev, + "%s: Invalid format %u\n", + __func__, cfg->format); + rc = -EINVAL; + goto done; + } + + if (cfg->packing != LSM_OUT_DATA_RAW && + cfg->packing != LSM_OUT_DATA_PACKED) { + dev_err(rtd->dev, + "%s: Invalid packing method %u\n", + __func__, cfg->packing); + rc = -EINVAL; + goto done; + } + + if (cfg->events != LSM_OUT_DATA_EVENTS_DISABLED && + cfg->events != LSM_OUT_DATA_EVENTS_ENABLED) { + dev_err(rtd->dev, + "%s: Invalid events provided %u\n", + __func__, cfg->events); + rc = -EINVAL; + goto done; + } + + if (cfg->mode != LSM_OUT_TRANSFER_MODE_RT && + cfg->mode != LSM_OUT_TRANSFER_MODE_FTRT) { + dev_err(rtd->dev, + "%s: Invalid transfer mode %u\n", + __func__, cfg->mode); + rc = -EINVAL; + goto done; + } + +done: + return rc; +} + +/* + * msm_cpe_lsm_ioctl_shared: Shared IOCTL for this platform driver + * @substream: ASoC substream for which the operation is invoked + * @cmd: command for the ioctl + * @arg: argument for the ioctl + * + * Perform dedicated listen functions like register sound model, + * deregister sound model, etc + * Called with lsm_api_lock acquired. + */ +static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream, + unsigned int cmd, void *arg) +{ + struct snd_lsm_sound_model_v2 snd_model; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct cpe_lsm_data *lsm_d = cpe_get_lsm_data(substream); + struct cpe_priv *cpe = cpe_get_private_data(substream); + struct cpe_lsm_session *session; + struct wcd_cpe_lsm_ops *lsm_ops; + struct cpe_lsm_lab *lab_d = &lsm_d->lab; + struct snd_dma_buffer *dma_buf = &substream->dma_buffer; + struct msm_slim_dma_data *dma_data = NULL; + struct snd_lsm_detection_params det_params; + int rc = 0; + + if (!cpe || !cpe->core_handle) { + dev_err(rtd->dev, + "%s: Invalid private data\n", + __func__); + return -EINVAL; + } + + if (!lsm_d || !lsm_d->lsm_session) { + dev_err(rtd->dev, + "%s: Invalid session data\n", + __func__); + return -EINVAL; + } + + session = lsm_d->lsm_session; + lsm_ops = &cpe->lsm_ops; + + switch (cmd) { + case SNDRV_LSM_STOP_LAB: + dev_dbg(rtd->dev, + "%s: %s, lab_enable = %d, lab_thread_ststus = %d\n", + __func__, "SNDRV_LSM_STOP_LAB", + session->lab_enable, + lab_d->thread_status); + + if (session->lab_enable && + lab_d->thread_status != MSM_LSM_LAB_THREAD_STOP) { + atomic_inc(&lab_d->abort_read); + wake_up(&lab_d->period_wait); + rc = msm_cpe_lsm_lab_stop(substream); + if (rc) { + dev_err(rtd->dev, + "%s: stop LAB failed, error = %d\n", + __func__, rc); + return rc; + } + } else if (!session->lab_enable) { + dev_dbg(rtd->dev, + "%s: LAB already stopped\n", + __func__); + } + + break; + + case SNDRV_LSM_LAB_CONTROL: + if (copy_from_user(&session->lab_enable, (void *)arg, + sizeof(u32))) { + dev_err(rtd->dev, + "%s: copy_from_user failed, size %zd\n", + __func__, sizeof(u32)); + return -EFAULT; + } + + dev_dbg(rtd->dev, + "%s: %s, lab_enable = %d\n", + __func__, "SNDRV_LSM_LAB_CONTROL", + session->lab_enable); + if (rtd->cpu_dai) + dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, + substream); + if (!dma_data || !dma_data->dai_channel_ctl) { + dev_err(rtd->dev, + "%s: dma_data is not set\n", __func__); + return -EINVAL; + } + + if (session->lab_enable) { + rc = msm_cpe_lab_buf_alloc(substream, + session, dma_data); + if (rc < 0) { + dev_err(rtd->dev, + "%s: lab buffer alloc failed, err = %d\n", + __func__, rc); + return rc; + } + + dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; + dma_buf->dev.dev = substream->pcm->card->dev; + dma_buf->private_data = NULL; + dma_buf->area = lab_d->pcm_buf[0].mem; + dma_buf->addr = lab_d->pcm_buf[0].phys; + dma_buf->bytes = (lsm_d->hw_params.buf_sz * + lsm_d->hw_params.period_count); + init_completion(&lab_d->thread_complete); + snd_pcm_set_runtime_buffer(substream, + &substream->dma_buffer); + rc = lsm_ops->lsm_lab_control(cpe->core_handle, + session, true); + if (rc < 0) { + dev_err(rtd->dev, + "%s: Lab Enable Failed rc %d\n", + __func__, rc); + return rc; + } + } else { + /* + * It is possible that lab is still enabled + * when trying to de-allocate the lab buffer. + * Make sure to disable lab before de-allocating + * the lab buffer. + */ + rc = msm_cpe_lsm_lab_stop(substream); + if (rc < 0) { + dev_err(rtd->dev, + "%s: LAB stop failed, error = %d\n", + __func__, rc); + return rc; + } + /* + * Buffer has to be de-allocated even if + * lab_control failed. + */ + rc = msm_cpe_lab_buf_dealloc(substream, + session, dma_data); + if (rc < 0) { + dev_err(rtd->dev, + "%s: lab buffer free failed, err = %d\n", + __func__, rc); + return rc; + } + } + break; + case SNDRV_LSM_REG_SND_MODEL_V2: + dev_dbg(rtd->dev, + "%s: %s\n", + __func__, "SNDRV_LSM_REG_SND_MODEL_V2"); + + memcpy(&snd_model, arg, + sizeof(struct snd_lsm_sound_model_v2)); + + session->num_confidence_levels = + snd_model.num_confidence_levels; + rc = msm_cpe_lsm_get_conf_levels(session, + snd_model.confidence_level); + if (rc) { + dev_err(rtd->dev, + "%s: %s get_conf_levels fail, err = %d\n", + __func__, "SNDRV_LSM_REG_SND_MODEL_V2", + rc); + break; + } + + session->snd_model_data = kzalloc(snd_model.data_size, + GFP_KERNEL); + if (!session->snd_model_data) { + kfree(session->conf_levels); + session->conf_levels = NULL; + return -ENOMEM; + } + session->snd_model_size = snd_model.data_size; + + if (copy_from_user(session->snd_model_data, + snd_model.data, snd_model.data_size)) { + dev_err(rtd->dev, + "%s: copy_from_user failed for snd_model\n", + __func__); + kfree(session->conf_levels); + kfree(session->snd_model_data); + session->conf_levels = NULL; + session->snd_model_data = NULL; + return -EFAULT; + } + + rc = lsm_ops->lsm_shmem_alloc(cpe->core_handle, session, + session->snd_model_size); + if (rc != 0) { + dev_err(rtd->dev, + "%s: shared memory allocation failed, err = %d\n", + __func__, rc); + kfree(session->snd_model_data); + kfree(session->conf_levels); + session->snd_model_data = NULL; + session->conf_levels = NULL; + return rc; + } + + rc = lsm_ops->lsm_register_snd_model(cpe->core_handle, session, + snd_model.detection_mode, + snd_model.detect_failure); + if (rc != 0) { + dev_err(rtd->dev, + "%s: snd_model_reg failed, err = %d\n", + __func__, rc); + lsm_ops->lsm_shmem_dealloc(cpe->core_handle, session); + kfree(session->snd_model_data); + kfree(session->conf_levels); + session->snd_model_data = NULL; + session->conf_levels = NULL; + return rc; + } + + break; + + case SNDRV_LSM_DEREG_SND_MODEL: + dev_dbg(rtd->dev, + "%s: %s\n", + __func__, "SNDRV_LSM_DEREG_SND_MODEL"); + + if (session->lab_enable) { + /* + * It is possible that lab is still enabled + * when trying to deregister sound model. + * Make sure to disable lab before de-allocating + * the lab buffer. + */ + rc = msm_cpe_lsm_lab_stop(substream); + if (rc) { + dev_err(rtd->dev, + "%s: LAB stop failed, error = %d\n", + __func__, rc); + return rc; + } + + rc = lsm_ops->lsm_lab_control(cpe->core_handle, + session, false); + if (rc) + dev_err(rtd->dev, + "%s: Lab Disable Failed rc %d\n", + __func__, rc); + + dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, + substream); + if (!dma_data || !dma_data->dai_channel_ctl) + dev_err(rtd->dev, + "%s: dma_data is not set\n", __func__); + + /* + * Buffer has to be de-allocated even if + * lab_control failed and/or dma data is invalid. + */ + rc = msm_cpe_lab_buf_dealloc(substream, + session, dma_data); + if (rc < 0) + dev_err(rtd->dev, + "%s: lab buffer free failed, err = %d\n", + __func__, rc); + } + + rc = lsm_ops->lsm_deregister_snd_model( + cpe->core_handle, session); + if (rc != 0) { + dev_err(rtd->dev, + "%s: snd_model de-reg failed, err = %d\n", + __func__, rc); + return rc; + } + + kfree(session->snd_model_data); + kfree(session->conf_levels); + session->snd_model_data = NULL; + session->conf_levels = NULL; + + rc = lsm_ops->lsm_shmem_dealloc(cpe->core_handle, session); + if (rc != 0) { + dev_err(rtd->dev, + "%s: LSM shared memory dealloc failed, err = %d\n", + __func__, rc); + return rc; + } + + break; + + case SNDRV_LSM_EVENT_STATUS: + case SNDRV_LSM_EVENT_STATUS_V3: { + struct snd_lsm_event_status *user; + struct snd_lsm_event_status_v3 *user_v3; + + dev_dbg(rtd->dev, + "%s: %s\n", + __func__, "SNDRV_LSM_EVENT_STATUS(_V3)"); + if (!arg) { + dev_err(rtd->dev, + "%s: Invalid argument to ioctl %s\n", + __func__, + "SNDRV_LSM_EVENT_STATUS(_V3)"); + return -EINVAL; + } + + /* + * Release the api lock before wait to allow + * other IOCTLs to be invoked while waiting + * for event + */ + MSM_CPE_LSM_REL_LOCK(&lsm_d->lsm_api_lock, + "lsm_api_lock"); + + rc = wait_event_freezable(lsm_d->event_wait, + (atomic_read(&lsm_d->event_avail) == 1) || + (atomic_read(&lsm_d->event_stop) == 1)); + + MSM_CPE_LSM_GRAB_LOCK(&lsm_d->lsm_api_lock, + "lsm_api_lock"); + + if (!rc) { + if (atomic_read(&lsm_d->event_avail) == 1) { + rc = 0; + atomic_set(&lsm_d->event_avail, 0); + + if (cmd == SNDRV_LSM_EVENT_STATUS) { + user = arg; + if (lsm_d->ev_det_pld_size > + user->payload_size) { + dev_err(rtd->dev, + "%s: avail pld_bytes = %u, needed = %u\n", + __func__, + user->payload_size, + lsm_d->ev_det_pld_size); + return -EINVAL; + } + + user->status = lsm_d->ev_det_status; + user->payload_size = + lsm_d->ev_det_pld_size; + memcpy(user->payload, + lsm_d->ev_det_payload, + lsm_d->ev_det_pld_size); + } else { + user_v3 = arg; + if (lsm_d->ev_det_pld_size > + user_v3->payload_size) { + dev_err(rtd->dev, + "%s: avail pld_bytes = %u, needed = %u\n", + __func__, + user_v3->payload_size, + lsm_d->ev_det_pld_size); + return -EINVAL; + } + /* event status timestamp not supported + * on CPE mode. Set msw and lsw to 0. + */ + user_v3->timestamp_lsw = 0; + user_v3->timestamp_msw = 0; + user_v3->status = lsm_d->ev_det_status; + user_v3->payload_size = + lsm_d->ev_det_pld_size; + memcpy(user_v3->payload, + lsm_d->ev_det_payload, + lsm_d->ev_det_pld_size); + } + } else if (atomic_read(&lsm_d->event_stop) == 1) { + dev_dbg(rtd->dev, + "%s: wait_aborted\n", __func__); + if (cmd == SNDRV_LSM_EVENT_STATUS) { + user = arg; + user->payload_size = 0; + } else { + user_v3 = arg; + user_v3->payload_size = 0; + } + rc = 0; + } + } + } + break; + + case SNDRV_LSM_ABORT_EVENT: + dev_dbg(rtd->dev, + "%s: %s\n", + __func__, "SNDRV_LSM_ABORT_EVENT"); + atomic_set(&lsm_d->event_stop, 1); + wake_up(&lsm_d->event_wait); + break; + + case SNDRV_LSM_START: + dev_dbg(rtd->dev, + "%s: %s\n", + __func__, "SNDRV_LSM_START"); + rc = lsm_ops->lsm_start(cpe->core_handle, session); + if (rc != 0) { + dev_err(rtd->dev, + "%s: lsm_start fail, err = %d\n", + __func__, rc); + return rc; + } + session->started = true; + break; + + case SNDRV_LSM_STOP: + dev_dbg(rtd->dev, + "%s: %s, lab_enable = %d, lab_thread_status = %d\n", + __func__, "SNDRV_LSM_STOP", + session->lab_enable, + lab_d->thread_status); + if ((session->lab_enable && + lab_d->thread_status == + MSM_LSM_LAB_THREAD_RUNNING)) { + /* Explicitly stop LAB */ + rc = msm_cpe_lsm_lab_stop(substream); + if (rc) { + dev_err(rtd->dev, + "%s: lab_stop failed, err = %d\n", + __func__, rc); + return rc; + } + } + + rc = lsm_ops->lsm_stop(cpe->core_handle, session); + if (rc != 0) { + dev_err(rtd->dev, + "%s: lsm_stop fail err = %d\n", + __func__, rc); + + return rc; + } + session->started = false; + break; + + case SNDRV_LSM_SET_PARAMS: + memcpy(&det_params, arg, + sizeof(det_params)); + if (det_params.num_confidence_levels <= 0) { + dev_err(rtd->dev, + "%s: %s: Invalid confidence levels %u\n", + __func__, "SNDRV_LSM_SET_PARAMS", + det_params.num_confidence_levels); + return -EINVAL; + } + + session->num_confidence_levels = + det_params.num_confidence_levels; + rc = msm_cpe_lsm_get_conf_levels(session, + det_params.conf_level); + if (rc) { + dev_err(rtd->dev, + "%s: %s get_conf_levels fail, err = %d\n", + __func__, "SNDRV_LSM_SET_PARAMS", + rc); + break; + } + + rc = lsm_ops->lsm_set_data(cpe->core_handle, session, + det_params.detect_mode, + det_params.detect_failure); + if (rc) { + dev_err(rtd->dev, + "%s: lsm_set_data failed, err = %d\n", + __func__, rc); + return rc; + } + + kfree(session->conf_levels); + session->conf_levels = NULL; + + break; + + case SNDRV_LSM_OUT_FORMAT_CFG: { + struct snd_lsm_output_format_cfg u_fmt_cfg; + + if (!arg) { + dev_err(rtd->dev, + "%s: Invalid argument to ioctl %s\n", + __func__, "SNDRV_LSM_OUT_FORMAT_CFG"); + return -EINVAL; + } + + if (copy_from_user(&u_fmt_cfg, arg, + sizeof(u_fmt_cfg))) { + dev_err(rtd->dev, + "%s: copy_from_user failed for out_fmt_cfg\n", + __func__); + return -EFAULT; + } + + if (msm_cpe_lsm_validate_out_format(substream, + &u_fmt_cfg)) + return -EINVAL; + + session->out_fmt_cfg.format = u_fmt_cfg.format; + session->out_fmt_cfg.pack_mode = u_fmt_cfg.packing; + session->out_fmt_cfg.data_path_events = + u_fmt_cfg.events; + session->out_fmt_cfg.transfer_mode = u_fmt_cfg.mode; + + rc = lsm_ops->lsm_set_fmt_cfg(cpe->core_handle, + session); + if (rc) { + dev_err(rtd->dev, + "%s: lsm_set_fmt_cfg failed, err = %d\n", + __func__, rc); + return rc; + } + } + break; + + case SNDRV_LSM_SET_PORT: { + u32 port_id = cpe->input_port_id; + + dev_dbg(rtd->dev, "%s: %s\n", __func__, "SNDRV_LSM_SET_PORT"); + rc = lsm_ops->lsm_set_port(cpe->core_handle, session, &port_id); + if (rc) { + dev_err(rtd->dev, + "%s: lsm_set_port failed, err = %d\n", + __func__, rc); + return rc; + } + } + break; + + default: + dev_dbg(rtd->dev, + "%s: Default snd_lib_ioctl cmd 0x%x\n", + __func__, cmd); + rc = snd_pcm_lib_ioctl(substream, cmd, arg); + } + + return rc; +} + +static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream, + u16 event_det_status) +{ + struct snd_soc_pcm_runtime *rtd; + struct cpe_lsm_data *lsm_d = NULL; + struct cpe_priv *cpe = NULL; + struct cpe_lsm_session *session = NULL; + struct cpe_lsm_lab *lab_d = NULL; + struct cpe_hw_params *hw_params; + struct wcd_cpe_lsm_ops *lsm_ops; + struct wcd_cpe_afe_ops *afe_ops; + struct wcd_cpe_afe_port_cfg *out_port; + int rc; + + if (!substream || !substream->private_data) { + pr_err("%s: invalid substream (%pK)\n", + __func__, substream); + return -EINVAL; + } + + rtd = substream->private_data; + lsm_d = cpe_get_lsm_data(substream); + cpe = cpe_get_private_data(substream); + + if (!cpe || !cpe->core_handle) { + dev_err(rtd->dev, + "%s: Invalid private data\n", + __func__); + return -EINVAL; + } + + if (!lsm_d || !lsm_d->lsm_session) { + dev_err(rtd->dev, + "%s: Invalid session data\n", + __func__); + return -EINVAL; + } + + session = lsm_d->lsm_session; + lsm_ops = &cpe->lsm_ops; + lab_d = &lsm_d->lab; + afe_ops = &cpe->afe_ops; + hw_params = &lsm_d->hw_params; + + if (!session->started) { + dev_dbg(rtd->dev, + "%s: Session is stopped, cannot start LAB\n", + __func__); + return 0; + } + + reinit_completion(&lab_d->thread_complete); + + if (session->lab_enable && + event_det_status == + LSM_VOICE_WAKEUP_STATUS_DETECTED) { + out_port = &session->afe_out_port_cfg; + out_port->port_id = session->afe_out_port_id; + out_port->bit_width = hw_params->sample_size; + out_port->num_channels = hw_params->channels; + out_port->sample_rate = hw_params->sample_rate; + dev_dbg(rtd->dev, "%s: port_id= %u, bit_width= %u, rate= %u\n", + __func__, out_port->port_id, out_port->bit_width, + out_port->sample_rate); + + rc = afe_ops->afe_port_cmd_cfg(cpe->core_handle, + out_port); + if (rc) { + dev_err(rtd->dev, + "%s: Failed afe generic config v2, err = %d\n", + __func__, rc); + return rc; + } + + atomic_set(&lab_d->abort_read, 0); + dev_dbg(rtd->dev, + "%s: KW detected, scheduling LAB thread\n", + __func__); + + /* + * Even though thread might be only scheduled and + * not currently running, mark the internal driver + * status to running so driver can cancel this thread + * if it needs to before the thread gets chance to run. + */ + lab_d->thread_status = MSM_LSM_LAB_THREAD_RUNNING; + session->lsm_lab_thread = kthread_run( + msm_cpe_lab_thread, + lsm_d, + "lab_thread"); + } + + return 0; +} + +static bool msm_cpe_lsm_is_valid_stream(struct snd_pcm_substream *substream, + const char *func) +{ + struct snd_soc_pcm_runtime *rtd; + struct cpe_lsm_data *lsm_d = NULL; + struct cpe_priv *cpe = NULL; + struct cpe_lsm_session *session = NULL; + struct wcd_cpe_lsm_ops *lsm_ops; + + if (!substream || !substream->private_data) { + pr_err("%s: invalid substream (%pK)\n", + func, substream); + return false; + } + + rtd = substream->private_data; + lsm_d = cpe_get_lsm_data(substream); + cpe = cpe_get_private_data(substream); + + if (!cpe || !cpe->core_handle) { + dev_err(rtd->dev, + "%s: Invalid private data\n", + func); + return false; + } + + if (!lsm_d || !lsm_d->lsm_session) { + dev_err(rtd->dev, + "%s: Invalid session data\n", + func); + return false; + } + + session = lsm_d->lsm_session; + lsm_ops = &cpe->lsm_ops; + + if (!lsm_ops) { + dev_err(rtd->dev, + "%s: Invalid lsm_ops\n", func); + return false; + } + + return true; +} + +static int msm_cpe_lsm_set_epd(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_soc_pcm_runtime *rtd; + struct cpe_lsm_data *lsm_d = NULL; + struct cpe_priv *cpe = NULL; + struct cpe_lsm_session *session = NULL; + struct wcd_cpe_lsm_ops *lsm_ops; + struct snd_lsm_ep_det_thres epd_thres; + int rc; + + if (!msm_cpe_lsm_is_valid_stream(substream, __func__)) + return -EINVAL; + + rtd = substream->private_data; + lsm_d = cpe_get_lsm_data(substream); + cpe = cpe_get_private_data(substream); + session = lsm_d->lsm_session; + lsm_ops = &cpe->lsm_ops; + + if (p_info->param_size != sizeof(epd_thres)) { + dev_err(rtd->dev, + "%s: Invalid param_size %d\n", + __func__, p_info->param_size); + rc = -EINVAL; + goto done; + } + + if (copy_from_user(&epd_thres, p_info->param_data, + p_info->param_size)) { + dev_err(rtd->dev, + "%s: copy_from_user failed, size = %d\n", + __func__, p_info->param_size); + rc = -EFAULT; + goto done; + } + + rc = lsm_ops->lsm_set_one_param(cpe->core_handle, + session, p_info, &epd_thres, + LSM_ENDPOINT_DETECT_THRESHOLD); + if (unlikely(rc)) + dev_err(rtd->dev, + "%s: set_one_param(epd_threshold) failed, rc %d\n", + __func__, rc); +done: + return rc; +} + +static int msm_cpe_lsm_set_mode(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_soc_pcm_runtime *rtd; + struct cpe_lsm_data *lsm_d = NULL; + struct cpe_priv *cpe = NULL; + struct cpe_lsm_session *session = NULL; + struct wcd_cpe_lsm_ops *lsm_ops; + struct snd_lsm_detect_mode det_mode; + int rc; + + if (!msm_cpe_lsm_is_valid_stream(substream, __func__)) + return -EINVAL; + + rtd = substream->private_data; + lsm_d = cpe_get_lsm_data(substream); + cpe = cpe_get_private_data(substream); + session = lsm_d->lsm_session; + lsm_ops = &cpe->lsm_ops; + + if (p_info->param_size != sizeof(det_mode)) { + dev_err(rtd->dev, + "%s: Invalid param_size %d\n", + __func__, p_info->param_size); + rc = -EINVAL; + goto done; + } + + if (copy_from_user(&det_mode, p_info->param_data, + p_info->param_size)) { + dev_err(rtd->dev, + "%s: copy_from_user failed, size = %d\n", + __func__, p_info->param_size); + rc = -EFAULT; + goto done; + } + + rc = lsm_ops->lsm_set_one_param(cpe->core_handle, + session, p_info, &det_mode, + LSM_OPERATION_MODE); + if (unlikely(rc)) + dev_err(rtd->dev, + "%s: set_one_param(epd_threshold) failed, rc %d\n", + __func__, rc); +done: + return rc; +} + +static int msm_cpe_lsm_set_gain(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_soc_pcm_runtime *rtd; + struct cpe_lsm_data *lsm_d = NULL; + struct cpe_priv *cpe = NULL; + struct cpe_lsm_session *session = NULL; + struct wcd_cpe_lsm_ops *lsm_ops; + struct snd_lsm_gain gain; + int rc; + + if (!msm_cpe_lsm_is_valid_stream(substream, __func__)) + return -EINVAL; + + rtd = substream->private_data; + lsm_d = cpe_get_lsm_data(substream); + cpe = cpe_get_private_data(substream); + session = lsm_d->lsm_session; + lsm_ops = &cpe->lsm_ops; + + if (p_info->param_size != sizeof(gain)) { + dev_err(rtd->dev, + "%s: Invalid param_size %d\n", + __func__, p_info->param_size); + rc = -EINVAL; + goto done; + } + + if (copy_from_user(&gain, p_info->param_data, + p_info->param_size)) { + dev_err(rtd->dev, + "%s: copy_from_user failed, size = %d\n", + __func__, p_info->param_size); + rc = -EFAULT; + goto done; + } + + rc = lsm_ops->lsm_set_one_param(cpe->core_handle, + session, p_info, &gain, + LSM_GAIN); + if (unlikely(rc)) + dev_err(rtd->dev, + "%s: set_one_param(epd_threshold) failed, rc %d\n", + __func__, rc); +done: + return rc; + +} + +static int msm_cpe_lsm_set_conf(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_soc_pcm_runtime *rtd; + struct cpe_lsm_data *lsm_d = NULL; + struct cpe_priv *cpe = NULL; + struct cpe_lsm_session *session = NULL; + struct wcd_cpe_lsm_ops *lsm_ops; + int rc; + + if (!msm_cpe_lsm_is_valid_stream(substream, __func__)) + return -EINVAL; + + rtd = substream->private_data; + lsm_d = cpe_get_lsm_data(substream); + cpe = cpe_get_private_data(substream); + session = lsm_d->lsm_session; + lsm_ops = &cpe->lsm_ops; + + session->num_confidence_levels = + p_info->param_size; + rc = msm_cpe_lsm_get_conf_levels(session, + p_info->param_data); + if (rc) { + dev_err(rtd->dev, + "%s: get_conf_levels failed, err = %d\n", + __func__, rc); + goto done; + } + + rc = lsm_ops->lsm_set_one_param(cpe->core_handle, + session, p_info, NULL, + LSM_MIN_CONFIDENCE_LEVELS); + if (unlikely(rc)) + dev_err(rtd->dev, + "%s: set_one_param(conf_levels) failed, rc %d\n", + __func__, rc); +done: + return rc; +} + +static int msm_cpe_lsm_reg_model(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_soc_pcm_runtime *rtd; + struct cpe_lsm_data *lsm_d = NULL; + struct cpe_priv *cpe = NULL; + struct cpe_lsm_session *session = NULL; + struct wcd_cpe_lsm_ops *lsm_ops; + int rc; + size_t offset; + u8 *snd_model_ptr; + + if (!msm_cpe_lsm_is_valid_stream(substream, __func__)) + return -EINVAL; + + rtd = substream->private_data; + lsm_d = cpe_get_lsm_data(substream); + cpe = cpe_get_private_data(substream); + session = lsm_d->lsm_session; + lsm_ops = &cpe->lsm_ops; + + lsm_ops->lsm_get_snd_model_offset(cpe->core_handle, + session, &offset); + /* Check if 'p_info->param_size + offset' crosses U32_MAX. */ + if (p_info->param_size > U32_MAX - offset) { + dev_err(rtd->dev, + "%s: Invalid param_size %d\n", + __func__, p_info->param_size); + return -EINVAL; + } + session->snd_model_size = p_info->param_size + offset; + + session->snd_model_data = vzalloc(session->snd_model_size); + if (!session->snd_model_data) + return -ENOMEM; + + snd_model_ptr = ((u8 *) session->snd_model_data) + offset; + + if (copy_from_user(snd_model_ptr, + p_info->param_data, p_info->param_size)) { + dev_err(rtd->dev, + "%s: copy_from_user for snd_model failed\n", + __func__); + rc = -EFAULT; + goto free_snd_model_data; + } + + rc = lsm_ops->lsm_shmem_alloc(cpe->core_handle, session, + session->snd_model_size); + if (rc != 0) { + dev_err(rtd->dev, + "%s: shared memory allocation failed, err = %d\n", + __func__, rc); + rc = -EINVAL; + goto free_snd_model_data; + } + + rc = lsm_ops->lsm_set_one_param(cpe->core_handle, + session, p_info, NULL, + LSM_REG_SND_MODEL); + if (unlikely(rc)) { + dev_err(rtd->dev, + "%s: set_one_param(snd_model) failed, rc %d\n", + __func__, rc); + goto dealloc_shmem; + } + return 0; + +dealloc_shmem: + lsm_ops->lsm_shmem_dealloc(cpe->core_handle, session); + +free_snd_model_data: + vfree(session->snd_model_data); + return rc; +} + +static int msm_cpe_lsm_dereg_model(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_soc_pcm_runtime *rtd; + struct cpe_lsm_data *lsm_d = NULL; + struct cpe_priv *cpe = NULL; + struct cpe_lsm_session *session = NULL; + struct wcd_cpe_lsm_ops *lsm_ops; + int rc; + + if (!msm_cpe_lsm_is_valid_stream(substream, __func__)) + return -EINVAL; + + rtd = substream->private_data; + lsm_d = cpe_get_lsm_data(substream); + cpe = cpe_get_private_data(substream); + session = lsm_d->lsm_session; + lsm_ops = &cpe->lsm_ops; + + rc = lsm_ops->lsm_set_one_param(cpe->core_handle, + session, p_info, NULL, + LSM_DEREG_SND_MODEL); + if (rc) + dev_err(rtd->dev, + "%s: dereg_snd_model failed\n", + __func__); + return lsm_ops->lsm_shmem_dealloc(cpe->core_handle, session); +} + +static int msm_cpe_lsm_set_custom(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_soc_pcm_runtime *rtd; + struct cpe_lsm_data *lsm_d = NULL; + struct cpe_priv *cpe = NULL; + struct cpe_lsm_session *session = NULL; + struct wcd_cpe_lsm_ops *lsm_ops; + u8 *data; + int rc; + + if (!msm_cpe_lsm_is_valid_stream(substream, __func__)) + return -EINVAL; + + rtd = substream->private_data; + lsm_d = cpe_get_lsm_data(substream); + cpe = cpe_get_private_data(substream); + session = lsm_d->lsm_session; + lsm_ops = &cpe->lsm_ops; + + if (p_info->param_size > MSM_CPE_MAX_CUSTOM_PARAM_SIZE) { + dev_err(rtd->dev, + "%s: invalid size %d, max allowed %d\n", + __func__, p_info->param_size, + MSM_CPE_MAX_CUSTOM_PARAM_SIZE); + return -EINVAL; + } + + data = kzalloc(p_info->param_size, GFP_KERNEL); + if (!data) + return -ENOMEM; + + if (copy_from_user(data, p_info->param_data, + p_info->param_size)) { + dev_err(rtd->dev, + "%s: copy_from_user failed for custom params, size = %d\n", + __func__, p_info->param_size); + rc = -EFAULT; + goto err_ret; + } + + rc = lsm_ops->lsm_set_one_param(cpe->core_handle, + session, p_info, data, + LSM_CUSTOM_PARAMS); + if (rc) + dev_err(rtd->dev, + "%s: custom_params failed, err = %d\n", + __func__, rc); +err_ret: + kfree(data); + return rc; +} + +static int msm_cpe_lsm_process_params(struct snd_pcm_substream *substream, + struct snd_lsm_module_params *p_data, + void *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct lsm_params_info *p_info; + int i; + int rc = 0; + + p_info = (struct lsm_params_info *) params; + + for (i = 0; i < p_data->num_params; i++) { + dev_dbg(rtd->dev, + "%s: param (%d), module_id = 0x%x, param_id = 0x%x, param_size = 0x%x, param_type = 0x%x\n", + __func__, i, p_info->module_id, + p_info->param_id, p_info->param_size, + p_info->param_type); + + switch (p_info->param_type) { + case LSM_ENDPOINT_DETECT_THRESHOLD: + rc = msm_cpe_lsm_set_epd(substream, p_info); + break; + case LSM_OPERATION_MODE: + rc = msm_cpe_lsm_set_mode(substream, p_info); + break; + case LSM_GAIN: + rc = msm_cpe_lsm_set_gain(substream, p_info); + break; + case LSM_MIN_CONFIDENCE_LEVELS: + rc = msm_cpe_lsm_set_conf(substream, p_info); + break; + case LSM_REG_SND_MODEL: + rc = msm_cpe_lsm_reg_model(substream, p_info); + break; + case LSM_DEREG_SND_MODEL: + rc = msm_cpe_lsm_dereg_model(substream, p_info); + break; + case LSM_CUSTOM_PARAMS: + rc = msm_cpe_lsm_set_custom(substream, p_info); + break; + default: + dev_err(rtd->dev, + "%s: Invalid param_type %d\n", + __func__, p_info->param_type); + rc = -EINVAL; + break; + } + if (rc) { + pr_err("%s: set_param fail for param_type %d\n", + __func__, p_info->param_type); + return rc; + } + + p_info++; + } + + return rc; +} + +static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream, + unsigned int cmd, void *arg) +{ + int err = 0; + struct snd_soc_pcm_runtime *rtd; + struct cpe_priv *cpe = NULL; + struct cpe_lsm_data *lsm_d = NULL; + struct cpe_lsm_session *session = NULL; + struct wcd_cpe_lsm_ops *lsm_ops; + + if (!substream || !substream->private_data) { + pr_err("%s: invalid substream (%pK)\n", + __func__, substream); + return -EINVAL; + } + + rtd = substream->private_data; + lsm_d = cpe_get_lsm_data(substream); + cpe = cpe_get_private_data(substream); + + if (!cpe || !cpe->core_handle) { + dev_err(rtd->dev, + "%s: Invalid private data\n", + __func__); + return -EINVAL; + } + + if (!lsm_d || !lsm_d->lsm_session) { + dev_err(rtd->dev, + "%s: Invalid session data\n", + __func__); + return -EINVAL; + } + + MSM_CPE_LSM_GRAB_LOCK(&lsm_d->lsm_api_lock, + "lsm_api_lock"); + + session = lsm_d->lsm_session; + lsm_ops = &cpe->lsm_ops; + + switch (cmd) { + case SNDRV_LSM_REG_SND_MODEL_V2: { + struct snd_lsm_sound_model_v2 snd_model; + + if (session->is_topology_used) { + dev_err(rtd->dev, + "%s: %s: not supported if using topology\n", + __func__, "LSM_REG_SND_MODEL_V2"); + err = -EINVAL; + goto done; + } + + if (copy_from_user(&snd_model, (void *)arg, + sizeof(struct snd_lsm_sound_model_v2))) { + dev_err(rtd->dev, + "%s: copy from user failed, size %zd\n", + __func__, + sizeof(struct snd_lsm_sound_model_v2)); + err = -EFAULT; + goto done; + } + + err = msm_cpe_lsm_ioctl_shared(substream, cmd, + &snd_model); + } + break; + case SNDRV_LSM_EVENT_STATUS: { + struct snd_lsm_event_status u_event_status; + struct snd_lsm_event_status *event_status = NULL; + int u_pld_size = 0; + + if (copy_from_user(&u_event_status, (void *)arg, + sizeof(struct snd_lsm_event_status))) { + dev_err(rtd->dev, + "%s: event status copy from user failed, size %zd\n", + __func__, + sizeof(struct snd_lsm_event_status)); + err = -EFAULT; + goto done; + } + + if (u_event_status.payload_size > + LISTEN_MAX_STATUS_PAYLOAD_SIZE) { + dev_err(rtd->dev, + "%s: payload_size %d is invalid, max allowed = %d\n", + __func__, u_event_status.payload_size, + LISTEN_MAX_STATUS_PAYLOAD_SIZE); + err = -EINVAL; + goto done; + } + + u_pld_size = sizeof(struct snd_lsm_event_status) + + u_event_status.payload_size; + + event_status = kzalloc(u_pld_size, GFP_KERNEL); + if (!event_status) { + err = -ENOMEM; + goto done; + } else { + event_status->payload_size = + u_event_status.payload_size; + err = msm_cpe_lsm_ioctl_shared(substream, + cmd, event_status); + } + + if (!err && copy_to_user(arg, event_status, u_pld_size)) { + dev_err(rtd->dev, + "%s: copy to user failed\n", + __func__); + kfree(event_status); + err = -EFAULT; + goto done; + } + + msm_cpe_lsm_lab_start(substream, event_status->status); + msm_cpe_process_event_status_done(lsm_d); + kfree(event_status); + } + break; + case SNDRV_LSM_EVENT_STATUS_V3: { + struct snd_lsm_event_status_v3 u_event_status; + struct snd_lsm_event_status_v3 *event_status = NULL; + int u_pld_size = 0; + + if (copy_from_user(&u_event_status, (void *)arg, + sizeof(struct snd_lsm_event_status_v3))) { + dev_err(rtd->dev, + "%s: event status copy from user failed, size %zd\n", + __func__, + sizeof(struct snd_lsm_event_status_v3)); + err = -EFAULT; + goto done; + } + + if (u_event_status.payload_size > + LISTEN_MAX_STATUS_PAYLOAD_SIZE) { + dev_err(rtd->dev, + "%s: payload_size %d is invalid, max allowed = %d\n", + __func__, u_event_status.payload_size, + LISTEN_MAX_STATUS_PAYLOAD_SIZE); + err = -EINVAL; + goto done; + } + + u_pld_size = sizeof(struct snd_lsm_event_status_v3) + + u_event_status.payload_size; + + event_status = kzalloc(u_pld_size, GFP_KERNEL); + if (!event_status) { + err = -ENOMEM; + goto done; + } else { + event_status->payload_size = + u_event_status.payload_size; + err = msm_cpe_lsm_ioctl_shared(substream, + cmd, event_status); + } + + if (!err && copy_to_user(arg, event_status, u_pld_size)) { + dev_err(rtd->dev, + "%s: copy to user failed\n", + __func__); + kfree(event_status); + err = -EFAULT; + goto done; + } + + msm_cpe_lsm_lab_start(substream, event_status->status); + msm_cpe_process_event_status_done(lsm_d); + kfree(event_status); + } + break; + case SNDRV_LSM_SET_PARAMS: { + struct snd_lsm_detection_params det_params; + + if (session->is_topology_used) { + dev_err(rtd->dev, + "%s: %s: not supported if using topology\n", + __func__, "SNDRV_LSM_SET_PARAMS"); + err = -EINVAL; + goto done; + } + + if (copy_from_user(&det_params, (void *) arg, + sizeof(det_params))) { + dev_err(rtd->dev, + "%s: %s: copy_from_user failed, size = %zd\n", + __func__, "SNDRV_LSM_SET_PARAMS", + sizeof(det_params)); + err = -EFAULT; + goto done; + } + + err = msm_cpe_lsm_ioctl_shared(substream, cmd, + &det_params); + } + break; + + case SNDRV_LSM_SET_MODULE_PARAMS: { + struct snd_lsm_module_params p_data; + size_t p_size; + u8 *params; + + if (!session->is_topology_used) { + dev_err(rtd->dev, + "%s: %s: not supported if not using topology\n", + __func__, "SET_MODULE_PARAMS"); + err = -EINVAL; + goto done; + } + + if (!arg) { + dev_err(rtd->dev, + "%s: %s: No Param data to set\n", + __func__, "SET_MODULE_PARAMS"); + err = -EINVAL; + goto done; + } + + if (copy_from_user(&p_data, arg, + sizeof(p_data))) { + dev_err(rtd->dev, + "%s: %s: copy_from_user failed, size = %zd\n", + __func__, "p_data", sizeof(p_data)); + err = -EFAULT; + goto done; + } + + if (p_data.num_params > LSM_PARAMS_MAX) { + dev_err(rtd->dev, + "%s: %s: Invalid num_params %d\n", + __func__, "SET_MODULE_PARAMS", + p_data.num_params); + err = -EINVAL; + goto done; + } + + p_size = p_data.num_params * + sizeof(struct lsm_params_info); + + if (p_data.data_size != p_size) { + dev_err(rtd->dev, + "%s: %s: Invalid size %zd\n", + __func__, "SET_MODULE_PARAMS", p_size); + + err = -EFAULT; + goto done; + } + + params = kzalloc(p_size, GFP_KERNEL); + if (!params) { + err = -ENOMEM; + goto done; + } + + if (copy_from_user(params, p_data.params, + p_data.data_size)) { + dev_err(rtd->dev, + "%s: %s: copy_from_user failed, size = %d\n", + __func__, "params", p_data.data_size); + kfree(params); + err = -EFAULT; + goto done; + } + + err = msm_cpe_lsm_process_params(substream, &p_data, params); + if (err) + dev_err(rtd->dev, + "%s: %s: Failed to set params, err = %d\n", + __func__, "SET_MODULE_PARAMS", err); + kfree(params); + break; + } + default: + err = msm_cpe_lsm_ioctl_shared(substream, cmd, arg); + break; + } + +done: + MSM_CPE_LSM_REL_LOCK(&lsm_d->lsm_api_lock, + "lsm_api_lock"); + return err; +} + +#ifdef CONFIG_COMPAT +struct snd_lsm_sound_model_v2_32 { + compat_uptr_t data; + compat_uptr_t confidence_level; + u32 data_size; + enum lsm_detection_mode detection_mode; + u8 num_confidence_levels; + bool detect_failure; +}; + +struct snd_lsm_detection_params_32 { + compat_uptr_t conf_level; + enum lsm_detection_mode detect_mode; + u8 num_confidence_levels; + bool detect_failure; +}; + +struct lsm_params_info_32 { + u32 module_id; + u32 param_id; + u32 param_size; + compat_uptr_t param_data; + uint32_t param_type; +}; + +struct snd_lsm_module_params_32 { + compat_uptr_t params; + u32 num_params; + u32 data_size; +}; + +enum { + SNDRV_LSM_REG_SND_MODEL_V2_32 = + _IOW('U', 0x07, struct snd_lsm_sound_model_v2_32), + SNDRV_LSM_SET_PARAMS32 = + _IOW('U', 0x0A, struct snd_lsm_detection_params_32), + SNDRV_LSM_SET_MODULE_PARAMS_32 = + _IOW('U', 0x0B, struct snd_lsm_module_params_32), +}; + +static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream, + unsigned int cmd, void *arg) +{ + int err = 0; + struct snd_soc_pcm_runtime *rtd; + struct cpe_priv *cpe = NULL; + struct cpe_lsm_data *lsm_d = NULL; + struct cpe_lsm_session *session = NULL; + struct wcd_cpe_lsm_ops *lsm_ops; + + if (!substream || !substream->private_data) { + pr_err("%s: invalid substream (%pK)\n", + __func__, substream); + return -EINVAL; + } + + rtd = substream->private_data; + lsm_d = cpe_get_lsm_data(substream); + cpe = cpe_get_private_data(substream); + + if (!cpe || !cpe->core_handle) { + dev_err(rtd->dev, + "%s: Invalid private data\n", + __func__); + return -EINVAL; + } + + if (!lsm_d || !lsm_d->lsm_session) { + dev_err(rtd->dev, + "%s: Invalid session data\n", + __func__); + return -EINVAL; + } + + MSM_CPE_LSM_GRAB_LOCK(&lsm_d->lsm_api_lock, + "lsm_api_lock"); + + session = lsm_d->lsm_session; + lsm_ops = &cpe->lsm_ops; + + switch (cmd) { + case SNDRV_LSM_REG_SND_MODEL_V2_32: { + struct snd_lsm_sound_model_v2 snd_model; + struct snd_lsm_sound_model_v2_32 snd_model32; + + if (session->is_topology_used) { + dev_err(rtd->dev, + "%s: %s: not supported if using topology\n", + __func__, "LSM_REG_SND_MODEL_V2_32"); + err = -EINVAL; + goto done; + } + + dev_dbg(rtd->dev, + "%s: ioctl %s\n", __func__, + "SNDRV_LSM_REG_SND_MODEL_V2_32"); + + if (copy_from_user(&snd_model32, (void *)arg, + sizeof(snd_model32))) { + dev_err(rtd->dev, + "%s: copy from user failed, size %zd\n", + __func__, + sizeof(snd_model32)); + err = -EFAULT; + goto done; + } + + snd_model.data = compat_ptr(snd_model32.data); + snd_model.confidence_level = + compat_ptr(snd_model32.confidence_level); + snd_model.data_size = snd_model32.data_size; + snd_model.detect_failure = snd_model32.detect_failure; + snd_model.num_confidence_levels = + snd_model32.num_confidence_levels; + snd_model.detection_mode = snd_model32.detection_mode; + + cmd = SNDRV_LSM_REG_SND_MODEL_V2; + err = msm_cpe_lsm_ioctl_shared(substream, cmd, &snd_model); + if (err) + dev_err(rtd->dev, + "%s: %s failed, error = %d\n", + __func__, + "SNDRV_LSM_REG_SND_MODEL_V2_32", + err); + } + break; + case SNDRV_LSM_EVENT_STATUS: { + struct snd_lsm_event_status *event_status = NULL; + struct snd_lsm_event_status u_event_status32; + struct snd_lsm_event_status *udata_32 = NULL; + int u_pld_size = 0; + + dev_dbg(rtd->dev, + "%s: ioctl %s\n", __func__, + "SNDRV_LSM_EVENT_STATUS32"); + + if (copy_from_user(&u_event_status32, (void *)arg, + sizeof(struct snd_lsm_event_status))) { + dev_err(rtd->dev, + "%s: event status copy from user failed, size %zd\n", + __func__, + sizeof(struct snd_lsm_event_status)); + err = -EFAULT; + goto done; + } + + if (u_event_status32.payload_size > + LISTEN_MAX_STATUS_PAYLOAD_SIZE) { + dev_err(rtd->dev, + "%s: payload_size %d is invalid, max allowed = %d\n", + __func__, u_event_status32.payload_size, + LISTEN_MAX_STATUS_PAYLOAD_SIZE); + err = -EINVAL; + goto done; + } + + u_pld_size = sizeof(struct snd_lsm_event_status) + + u_event_status32.payload_size; + event_status = kzalloc(u_pld_size, GFP_KERNEL); + if (!event_status) { + dev_err(rtd->dev, + "%s: No memory for event status\n", + __func__); + err = -ENOMEM; + goto done; + } else { + event_status->payload_size = + u_event_status32.payload_size; + err = msm_cpe_lsm_ioctl_shared(substream, + cmd, event_status); + if (err) + dev_err(rtd->dev, + "%s: %s failed, error = %d\n", + __func__, + "SNDRV_LSM_EVENT_STATUS32", + err); + } + + if (!err) { + udata_32 = kzalloc(u_pld_size, GFP_KERNEL); + if (!udata_32) { + dev_err(rtd->dev, + "%s: nomem for udata\n", + __func__); + err = -EFAULT; + } else { + udata_32->status = event_status->status; + udata_32->payload_size = + event_status->payload_size; + memcpy(udata_32->payload, + event_status->payload, + u_pld_size); + } + } + + if (!err && copy_to_user(arg, udata_32, + u_pld_size)) { + dev_err(rtd->dev, + "%s: copy to user failed\n", + __func__); + kfree(event_status); + kfree(udata_32); + err = -EFAULT; + goto done; + } + + msm_cpe_lsm_lab_start(substream, event_status->status); + msm_cpe_process_event_status_done(lsm_d); + kfree(event_status); + kfree(udata_32); + } + break; + case SNDRV_LSM_EVENT_STATUS_V3: { + struct snd_lsm_event_status_v3 *event_status = NULL; + struct snd_lsm_event_status_v3 u_event_status32; + struct snd_lsm_event_status_v3 *udata_32 = NULL; + int u_pld_size = 0; + + dev_dbg(rtd->dev, + "%s: ioctl %s\n", __func__, + "SNDRV_LSM_EVENT_STATUS_V3_32"); + + if (copy_from_user(&u_event_status32, (void *)arg, + sizeof(struct snd_lsm_event_status_v3))) { + dev_err(rtd->dev, + "%s: event status copy from user failed, size %zd\n", + __func__, + sizeof(struct snd_lsm_event_status_v3)); + err = -EFAULT; + goto done; + } + + if (u_event_status32.payload_size > + LISTEN_MAX_STATUS_PAYLOAD_SIZE) { + dev_err(rtd->dev, + "%s: payload_size %d is invalid, max allowed = %d\n", + __func__, u_event_status32.payload_size, + LISTEN_MAX_STATUS_PAYLOAD_SIZE); + err = -EINVAL; + goto done; + } + + u_pld_size = sizeof(struct snd_lsm_event_status_v3) + + u_event_status32.payload_size; + event_status = kzalloc(u_pld_size, GFP_KERNEL); + if (!event_status) { + dev_err(rtd->dev, + "%s: No memory for event status\n", + __func__); + err = -ENOMEM; + goto done; + } else { + event_status->payload_size = + u_event_status32.payload_size; + err = msm_cpe_lsm_ioctl_shared(substream, + cmd, event_status); + if (err) + dev_err(rtd->dev, + "%s: %s failed, error = %d\n", + __func__, + "SNDRV_LSM_EVENT_STATUS_V3_32", + err); + } + + if (!err) { + udata_32 = kzalloc(u_pld_size, GFP_KERNEL); + if (!udata_32) { + dev_err(rtd->dev, + "%s: nomem for udata\n", + __func__); + err = -EFAULT; + } else { + udata_32->timestamp_lsw = + event_status->timestamp_lsw; + udata_32->timestamp_msw = + event_status->timestamp_msw; + udata_32->status = event_status->status; + udata_32->payload_size = + event_status->payload_size; + memcpy(udata_32->payload, + event_status->payload, + u_pld_size); + } + } + + if (!err && copy_to_user(arg, udata_32, + u_pld_size)) { + dev_err(rtd->dev, + "%s: copy to user failed\n", + __func__); + kfree(event_status); + kfree(udata_32); + err = -EFAULT; + goto done; + } + + msm_cpe_lsm_lab_start(substream, event_status->status); + msm_cpe_process_event_status_done(lsm_d); + kfree(event_status); + kfree(udata_32); + } + break; + case SNDRV_LSM_SET_PARAMS32: { + struct snd_lsm_detection_params_32 det_params32; + struct snd_lsm_detection_params det_params; + + if (session->is_topology_used) { + dev_err(rtd->dev, + "%s: %s: not supported if using topology\n", + __func__, "SNDRV_LSM_SET_PARAMS32"); + + err = -EINVAL; + goto done; + } + + if (copy_from_user(&det_params32, arg, + sizeof(det_params32))) { + err = -EFAULT; + dev_err(rtd->dev, + "%s: %s: copy_from_user failed, size = %zd\n", + __func__, "SNDRV_LSM_SET_PARAMS_32", + sizeof(det_params32)); + } else { + det_params.conf_level = + compat_ptr(det_params32.conf_level); + det_params.detect_mode = + det_params32.detect_mode; + det_params.num_confidence_levels = + det_params32.num_confidence_levels; + det_params.detect_failure = + det_params32.detect_failure; + cmd = SNDRV_LSM_SET_PARAMS; + err = msm_cpe_lsm_ioctl_shared(substream, cmd, + &det_params); + if (err) + dev_err(rtd->dev, + "%s: ioctl %s failed\n", __func__, + "SNDRV_LSM_SET_PARAMS"); + } + + break; + } + + case SNDRV_LSM_SET_MODULE_PARAMS_32: { + struct snd_lsm_module_params_32 p_data_32; + struct snd_lsm_module_params p_data; + u8 *params, *params32; + size_t p_size; + struct lsm_params_info_32 *p_info_32; + struct lsm_params_info *p_info; + int i; + + if (!session->is_topology_used) { + dev_err(rtd->dev, + "%s: %s: not supported if not using topology\n", + __func__, "SET_MODULE_PARAMS_32"); + err = -EINVAL; + goto done; + } + + if (copy_from_user(&p_data_32, arg, + sizeof(p_data_32))) { + dev_err(rtd->dev, + "%s: %s: copy_from_user failed, size = %zd\n", + __func__, "SET_MODULE_PARAMS_32", + sizeof(p_data_32)); + err = -EFAULT; + goto done; + } + + p_data.params = compat_ptr(p_data_32.params); + p_data.num_params = p_data_32.num_params; + p_data.data_size = p_data_32.data_size; + + if (p_data.num_params > LSM_PARAMS_MAX) { + dev_err(rtd->dev, + "%s: %s: Invalid num_params %d\n", + __func__, "SET_MODULE_PARAMS_32", + p_data.num_params); + err = -EINVAL; + goto done; + } + + if (p_data.data_size != + (p_data.num_params * sizeof(struct lsm_params_info_32))) { + dev_err(rtd->dev, + "%s: %s: Invalid size %d\n", + __func__, "SET_MODULE_PARAMS_32", + p_data.data_size); + err = -EINVAL; + goto done; + } + + p_size = sizeof(struct lsm_params_info_32) * + p_data.num_params; + + params32 = kzalloc(p_size, GFP_KERNEL); + if (!params32) { + err = -ENOMEM; + goto done; + } + + p_size = sizeof(struct lsm_params_info) * p_data.num_params; + params = kzalloc(p_size, GFP_KERNEL); + if (!params) { + kfree(params32); + err = -ENOMEM; + goto done; + } + + if (copy_from_user(params32, p_data.params, + p_data.data_size)) { + dev_err(rtd->dev, + "%s: %s: copy_from_user failed, size = %d\n", + __func__, "params32", p_data.data_size); + kfree(params32); + kfree(params); + err = -EFAULT; + goto done; + } + + p_info_32 = (struct lsm_params_info_32 *) params32; + p_info = (struct lsm_params_info *) params; + for (i = 0; i < p_data.num_params; i++) { + p_info->module_id = p_info_32->module_id; + p_info->param_id = p_info_32->param_id; + p_info->param_size = p_info_32->param_size; + p_info->param_data = compat_ptr(p_info_32->param_data); + p_info->param_type = p_info_32->param_type; + + p_info_32++; + p_info++; + } + + err = msm_cpe_lsm_process_params(substream, + &p_data, params); + if (err) + dev_err(rtd->dev, + "%s: Failed to process params, err = %d\n", + __func__, err); + kfree(params); + kfree(params32); + break; + } + case SNDRV_LSM_REG_SND_MODEL_V2: + case SNDRV_LSM_SET_PARAMS: + case SNDRV_LSM_SET_MODULE_PARAMS: + /* + * In ideal cases, the compat_ioctl should never be called + * with the above unlocked ioctl commands. Print error + * and return error if it does. + */ + dev_err(rtd->dev, + "%s: Invalid cmd for compat_ioctl\n", + __func__); + err = -EINVAL; + break; + default: + err = msm_cpe_lsm_ioctl_shared(substream, cmd, arg); + break; + } +done: + MSM_CPE_LSM_REL_LOCK(&lsm_d->lsm_api_lock, + "lsm_api_lock"); + return err; +} + +#else +#define msm_cpe_lsm_ioctl_compat NULL +#endif + +/* + * msm_cpe_lsm_prepare: prepare call from ASoC core for this platform + * @substream: ASoC substream for which the operation is invoked + * + * start the AFE port on CPE associated for this listen session + */ +static int msm_cpe_lsm_prepare(struct snd_pcm_substream *substream) +{ + int rc = 0; + struct cpe_priv *cpe = cpe_get_private_data(substream); + struct cpe_lsm_data *lsm_d = cpe_get_lsm_data(substream); + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct wcd_cpe_afe_ops *afe_ops; + struct wcd_cpe_afe_port_cfg *afe_cfg; + struct cpe_lsm_session *lsm_session; + struct cpe_lsm_lab *lab_d = &lsm_d->lab; + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_hw_params lsm_param; + struct wcd_cpe_lsm_ops *lsm_ops; + + if (!cpe || !cpe->core_handle) { + dev_err(rtd->dev, + "%s: Invalid private data\n", + __func__); + return -EINVAL; + } + + if (!lsm_d || !lsm_d->lsm_session) { + dev_err(rtd->dev, + "%s: Invalid session data\n", + __func__); + return -EINVAL; + } + if (runtime->status->state == SNDRV_PCM_STATE_XRUN || + runtime->status->state == SNDRV_PCM_STATE_PREPARED) { + pr_err("%s: XRUN ignore for now\n", __func__); + return 0; + } + + lsm_session = lsm_d->lsm_session; + lab_d->pcm_size = snd_pcm_lib_buffer_bytes(substream); + + dev_dbg(rtd->dev, + "%s: pcm_size 0x%x", __func__, lab_d->pcm_size); + + if (lsm_d->cpe_prepared) { + dev_dbg(rtd->dev, "%s: CPE is alredy prepared\n", + __func__); + return 0; + } + + lsm_ops = &cpe->lsm_ops; + afe_ops = &cpe->afe_ops; + afe_cfg = &(lsm_d->lsm_session->afe_port_cfg); + + switch (cpe->input_port_id) { + case AFE_PORT_ID_3: + afe_cfg->port_id = AFE_PORT_ID_3; + afe_cfg->bit_width = 16; + afe_cfg->num_channels = 1; + afe_cfg->sample_rate = SAMPLE_RATE_48KHZ; + rc = afe_ops->afe_port_cmd_cfg(cpe->core_handle, afe_cfg); + break; + case AFE_PORT_ID_1: + default: + afe_cfg->port_id = AFE_PORT_ID_1; + afe_cfg->bit_width = 16; + afe_cfg->num_channels = 1; + afe_cfg->sample_rate = SAMPLE_RATE_16KHZ; + rc = afe_ops->afe_set_params(cpe->core_handle, + afe_cfg, cpe->afe_mad_ctl); + break; + } + + if (rc != 0) { + dev_err(rtd->dev, + "%s: cpe afe params failed for port = %d, err = %d\n", + __func__, afe_cfg->port_id, rc); + return rc; + } + lsm_param.sample_rate = afe_cfg->sample_rate; + lsm_param.num_chs = afe_cfg->num_channels; + lsm_param.bit_width = afe_cfg->bit_width; + rc = lsm_ops->lsm_set_media_fmt_params(cpe->core_handle, lsm_session, + &lsm_param); + if (rc) + dev_dbg(rtd->dev, + "%s: failed to set lsm media fmt params, err = %d\n", + __func__, rc); + + /* Send connect to port (input) */ + rc = lsm_ops->lsm_set_port(cpe->core_handle, lsm_session, + &cpe->input_port_id); + if (rc) { + dev_err(rtd->dev, + "%s: Failed to set connect input port, err=%d\n", + __func__, rc); + return rc; + } + + if (cpe->input_port_id != 3) { + rc = lsm_ops->lsm_get_afe_out_port_id(cpe->core_handle, + lsm_session); + if (rc != 0) { + dev_err(rtd->dev, + "%s: failed to get port id, err = %d\n", + __func__, rc); + return rc; + } + /* Send connect to port (output) */ + rc = lsm_ops->lsm_set_port(cpe->core_handle, lsm_session, + &lsm_session->afe_out_port_id); + if (rc) { + dev_err(rtd->dev, + "%s: Failed to set connect output port, err=%d\n", + __func__, rc); + return rc; + } + } + rc = msm_cpe_afe_port_cntl(substream, + cpe->core_handle, + afe_ops, afe_cfg, + AFE_CMD_PORT_START); + if (rc) + dev_err(rtd->dev, + "%s: cpe_afe_port start failed, err = %d\n", + __func__, rc); + else + lsm_d->cpe_prepared = true; + + return rc; +} + +/* + * msm_cpe_lsm_trigger: trigger call from ASoC core for this platform + * @substream: ASoC substream for which the operation is invoked + * @cmd: the trigger command from framework + * + * suspend/resume the AFE port on CPE associated with listen session + */ +static int msm_cpe_lsm_trigger(struct snd_pcm_substream *substream, + int cmd) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct cpe_priv *cpe = cpe_get_private_data(substream); + struct cpe_lsm_data *lsm_d = cpe_get_lsm_data(substream); + struct wcd_cpe_afe_ops *afe_ops; + struct wcd_cpe_afe_port_cfg *afe_cfg; + int afe_cmd = AFE_CMD_INVALID; + int rc = 0; + + if (!cpe || !cpe->core_handle) { + dev_err(rtd->dev, + "%s: Invalid private data\n", + __func__); + return -EINVAL; + } + + if (!lsm_d || !lsm_d->lsm_session) { + dev_err(rtd->dev, + "%s: Invalid session data\n", + __func__); + return -EINVAL; + } + + afe_ops = &cpe->afe_ops; + afe_cfg = &(lsm_d->lsm_session->afe_port_cfg); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + afe_cmd = AFE_CMD_PORT_SUSPEND; + break; + + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + afe_cmd = AFE_CMD_PORT_RESUME; + break; + + default: + afe_cmd = AFE_CMD_INVALID; + dev_dbg(rtd->dev, + "%s: unhandled trigger cmd %d\n", + __func__, cmd); + break; + } + + if (afe_cmd != AFE_CMD_INVALID) + rc = msm_cpe_afe_port_cntl(substream, + cpe->core_handle, + afe_ops, afe_cfg, + afe_cmd); + + return rc; +} + +static int msm_cpe_lsm_hwparams(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct cpe_lsm_data *lsm_d = cpe_get_lsm_data(substream); + struct cpe_priv *cpe = cpe_get_private_data(substream); + struct cpe_lsm_session *session = NULL; + struct cpe_hw_params *hw_params = NULL; + + if (!cpe || !cpe->core_handle) { + dev_err(rtd->dev, + "%s: Invalid %s\n", + __func__, + (!cpe) ? "cpe" : "core"); + return -EINVAL; + } + + if (!lsm_d || !lsm_d->lsm_session) { + dev_err(rtd->dev, + "%s: Invalid %s\n", + __func__, + (!lsm_d) ? "priv_data" : "session"); + return -EINVAL; + } + + session = lsm_d->lsm_session; + hw_params = &lsm_d->hw_params; + hw_params->buf_sz = (params_buffer_bytes(params) + / params_periods(params)); + hw_params->period_count = params_periods(params); + hw_params->channels = params_channels(params); + hw_params->sample_rate = params_rate(params); + + if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE) + hw_params->sample_size = 16; + else if (params_format(params) == + SNDRV_PCM_FORMAT_S24_LE) + hw_params->sample_size = 24; + else if (params_format(params) == + SNDRV_PCM_FORMAT_S32_LE) + hw_params->sample_size = 32; + else { + dev_err(rtd->dev, + "%s: Invalid Format 0x%x\n", + __func__, params_format(params)); + return -EINVAL; + } + + dev_dbg(rtd->dev, + "%s: Format %d buffer size(bytes) %d period count %d\n" + " Channel %d period in bytes 0x%x Period Size 0x%x rate = %d\n", + __func__, params_format(params), params_buffer_bytes(params), + params_periods(params), params_channels(params), + params_period_bytes(params), params_period_size(params), + params_rate(params)); + + return 0; +} + +static snd_pcm_uframes_t msm_cpe_lsm_pointer( + struct snd_pcm_substream *substream) +{ + + struct cpe_lsm_data *lsm_d = cpe_get_lsm_data(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct cpe_lsm_session *session; + struct cpe_lsm_lab *lab_d = &lsm_d->lab; + + session = lsm_d->lsm_session; + if (lab_d->dma_write >= lab_d->pcm_size) + lab_d->dma_write = 0; + dev_dbg(rtd->dev, + "%s:pcm_dma_pos = %d\n", + __func__, lab_d->dma_write); + + return bytes_to_frames(runtime, (lab_d->dma_write)); +} + +static int msm_cpe_lsm_copy(struct snd_pcm_substream *substream, int a, + snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames) +{ + struct cpe_lsm_data *lsm_d = cpe_get_lsm_data(substream); + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_pcm_runtime *runtime = substream->runtime; + struct cpe_lsm_session *session; + struct cpe_lsm_lab *lab_d = &lsm_d->lab; + char *pcm_buf; + int fbytes = 0; + int rc = 0; + + fbytes = frames_to_bytes(runtime, frames); + if (runtime->status->state == SNDRV_PCM_STATE_XRUN || + runtime->status->state == SNDRV_PCM_STATE_PREPARED) { + pr_err("%s: XRUN ignore for now\n", __func__); + return 0; + } + session = lsm_d->lsm_session; + + /* Check if buffer reading is already in error state */ + if (lab_d->thread_status == MSM_LSM_LAB_THREAD_ERROR) { + dev_err(rtd->dev, + "%s: Bufferring is in error state\n", + __func__); + /* + * Advance the period so there is no wait in case + * read is invoked even after error is propogated + */ + atomic_inc(&lab_d->in_count); + lab_d->dma_write += snd_pcm_lib_period_bytes(substream); + snd_pcm_period_elapsed(substream); + return -ENETRESET; + } else if (lab_d->thread_status == MSM_LSM_LAB_THREAD_STOP) { + dev_err(rtd->dev, + "%s: Buferring is in stopped\n", + __func__); + return -EIO; + } + + rc = wait_event_timeout(lab_d->period_wait, + (atomic_read(&lab_d->in_count) || + atomic_read(&lab_d->abort_read)), + (2 * HZ)); + if (atomic_read(&lab_d->abort_read)) { + pr_debug("%s: LSM LAB Abort read\n", __func__); + return -EIO; + } + if (lab_d->thread_status != MSM_LSM_LAB_THREAD_RUNNING) { + pr_err("%s: Lab stopped\n", __func__); + return -EIO; + } + if (!rc) { + pr_err("%s:LAB err wait_event_timeout\n", __func__); + rc = -EAGAIN; + goto fail; + } + if (lab_d->buf_idx >= (lsm_d->hw_params.period_count)) + lab_d->buf_idx = 0; + pcm_buf = (lab_d->pcm_buf[lab_d->buf_idx].mem); + pr_debug("%s: Buf IDX = 0x%x pcm_buf %pK\n", + __func__, lab_d->buf_idx, pcm_buf); + if (pcm_buf) { + if (copy_to_user(buf, pcm_buf, fbytes)) { + pr_err("Failed to copy buf to user\n"); + rc = -EFAULT; + goto fail; + } + } + lab_d->buf_idx++; + atomic_dec(&lab_d->in_count); + return 0; +fail: + return rc; +} + +/* + * msm_asoc_cpe_lsm_probe: ASoC framework for lsm platform driver + * @platform: platform registered with ASoC core + * + * Allocate the private data for this platform and obtain the ops for + * lsm and afe modules from underlying driver. Also find the codec + * for this platform as specified by machine driver for ASoC framework. + */ +static int msm_asoc_cpe_lsm_probe(struct snd_soc_platform *platform) +{ + struct snd_soc_card *card; + struct snd_soc_pcm_runtime *rtd; + struct snd_soc_codec *codec; + struct cpe_priv *cpe_priv; + const struct snd_kcontrol_new *kcontrol; + bool found_runtime = false; + const char *cpe_dev_id = "qcom,msm-cpe-lsm-id"; + u32 port_id = 0; + int ret = 0; + + if (!platform || !platform->component.card) { + pr_err("%s: Invalid platform or card\n", + __func__); + return -EINVAL; + } + + card = platform->component.card; + + /* Match platform to codec */ + list_for_each_entry(rtd, &card->rtd_list, list) { + if (!rtd->platform) + continue; + if (!strcmp(rtd->platform->component.name, + platform->component.name)) { + found_runtime = true; + break; + } + } + + if (!found_runtime) { + dev_err(platform->dev, + "%s: Failed to find runtime for platform\n", + __func__); + return -EINVAL; + } + + ret = of_property_read_u32(platform->dev->of_node, cpe_dev_id, + &port_id); + if (ret) { + dev_dbg(platform->dev, + "%s: missing 0x%x in dt node\n", __func__, port_id); + port_id = 1; + } + + codec = rtd->codec; + + cpe_priv = kzalloc(sizeof(struct cpe_priv), + GFP_KERNEL); + if (!cpe_priv) + return -ENOMEM; + + cpe_priv->codec = codec; + cpe_priv->input_port_id = port_id; + wcd_cpe_get_lsm_ops(&cpe_priv->lsm_ops); + wcd_cpe_get_afe_ops(&cpe_priv->afe_ops); + + snd_soc_platform_set_drvdata(platform, cpe_priv); + kcontrol = &msm_cpe_kcontrols[0]; + snd_ctl_add(card->snd_card, snd_ctl_new1(kcontrol, cpe_priv)); + return 0; +} + +static const struct snd_pcm_ops msm_cpe_lsm_ops = { + .open = msm_cpe_lsm_open, + .close = msm_cpe_lsm_close, + .ioctl = msm_cpe_lsm_ioctl, + .prepare = msm_cpe_lsm_prepare, + .trigger = msm_cpe_lsm_trigger, + .pointer = msm_cpe_lsm_pointer, + .copy = msm_cpe_lsm_copy, + .hw_params = msm_cpe_lsm_hwparams, + .compat_ioctl = msm_cpe_lsm_ioctl_compat, +}; + +static struct snd_soc_platform_driver msm_soc_cpe_platform = { + .ops = &msm_cpe_lsm_ops, + .probe = msm_asoc_cpe_lsm_probe, +}; + +/* + * msm_cpe_lsm_probe: platform driver probe + * @pdev: platform device + * + * Register the ASoC platform driver with ASoC core + */ +static int msm_cpe_lsm_probe(struct platform_device *pdev) +{ + + return snd_soc_register_platform(&pdev->dev, + &msm_soc_cpe_platform); +} + +/* + * msm_cpe_lsm_remove: platform driver remove + * @pdev: platform device + * + * Deregister the ASoC platform driver + */ +static int msm_cpe_lsm_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_cpe_lsm_dt_match[] = { + {.compatible = "qcom,msm-cpe-lsm" }, + { } +}; + +static struct platform_driver msm_cpe_lsm_driver = { + .driver = { + .name = "msm-cpe-lsm", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(msm_cpe_lsm_dt_match), + }, + .probe = msm_cpe_lsm_probe, + .remove = msm_cpe_lsm_remove, +}; +module_platform_driver(msm_cpe_lsm_driver); + +MODULE_DESCRIPTION("CPE LSM platform driver"); +MODULE_DEVICE_TABLE(of, msm_cpe_lsm_dt_match); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c new file mode 100644 index 000000000000..c319ccf43feb --- /dev/null +++ b/sound/soc/msm/msm-dai-fe.c @@ -0,0 +1,2690 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct snd_soc_dai_ops msm_fe_dai_ops = {}; + +/* Conventional and unconventional sample rate supported */ +static unsigned int supported_sample_rates[] = { + 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, + 88200, 96000, 176400, 192000, 352800, 384000 +}; + +static struct snd_pcm_hw_constraint_list constraints_sample_rates = { + .count = ARRAY_SIZE(supported_sample_rates), + .list = supported_sample_rates, + .mask = 0, +}; + +static int multimedia_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_sample_rates); + return 0; +} + +static int fe_dai_probe(struct snd_soc_dai *dai) +{ + struct snd_soc_dapm_route intercon; + struct snd_soc_dapm_context *dapm; + + if (!dai || !dai->driver) { + pr_err("%s invalid params\n", __func__); + return -EINVAL; + } + dapm = snd_soc_component_get_dapm(dai->component); + memset(&intercon, 0, sizeof(intercon)); + if (dai->driver->playback.stream_name && + dai->driver->playback.aif_name) { + dev_dbg(dai->dev, "%s add route for widget %s", + __func__, dai->driver->playback.stream_name); + intercon.source = dai->driver->playback.stream_name; + intercon.sink = dai->driver->playback.aif_name; + dev_dbg(dai->dev, "%s src %s sink %s\n", + __func__, intercon.source, intercon.sink); + snd_soc_dapm_add_routes(dapm, &intercon, 1); + snd_soc_dapm_ignore_suspend(dapm, intercon.source); + } + if (dai->driver->capture.stream_name && + dai->driver->capture.aif_name) { + dev_dbg(dai->dev, "%s add route for widget %s", + __func__, dai->driver->capture.stream_name); + intercon.sink = dai->driver->capture.stream_name; + intercon.source = dai->driver->capture.aif_name; + dev_dbg(dai->dev, "%s src %s sink %s\n", + __func__, intercon.source, intercon.sink); + snd_soc_dapm_add_routes(dapm, &intercon, 1); + snd_soc_dapm_ignore_suspend(dapm, intercon.sink); + } + return 0; +} + +static struct snd_soc_dai_ops msm_fe_Multimedia_dai_ops = { + .startup = multimedia_startup, +}; + +static const struct snd_soc_component_driver msm_fe_dai_component = { + .name = "msm-dai-fe", +}; + +static struct snd_soc_dai_driver msm_fe_dais[] = { + { + .playback = { + .stream_name = "MultiMedia1 Playback", + .aif_name = "MM_DL1", + .rates = (SNDRV_PCM_RATE_8000_384000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "MultiMedia1 Capture", + .aif_name = "MM_UL1", + .rates = (SNDRV_PCM_RATE_8000_384000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .name = "MultiMedia1", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MultiMedia2 Playback", + .aif_name = "MM_DL2", + .rates = (SNDRV_PCM_RATE_8000_384000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "MultiMedia2 Capture", + .aif_name = "MM_UL2", + .rates = (SNDRV_PCM_RATE_8000_384000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .name = "MultiMedia2", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "CS-VOICE Playback", + .aif_name = "CS-VOICE_DL1", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "CS-VOICE Capture", + .aif_name = "CS-VOICE_UL1", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "CS-VOICE", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "VoIP Playback", + .aif_name = "VOIP_DL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_SPECIAL, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "VoIP Capture", + .aif_name = "VOIP_UL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_SPECIAL, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "VoIP", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MultiMedia3 Playback", + .aif_name = "MM_DL3", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 6, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "MultiMedia3 Capture", + .aif_name = "MM_UL3", + .rates = (SNDRV_PCM_RATE_8000_384000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .name = "MultiMedia3", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MultiMedia4 Playback", + .aif_name = "MM_DL4", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia4", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MultiMedia5 Playback", + .aif_name = "MM_DL5", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "MultiMedia5 Capture", + .aif_name = "MM_UL5", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .name = "MultiMedia5", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MultiMedia6 Playback", + .aif_name = "MM_DL6", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "MultiMedia6 Capture", + .aif_name = "MM_UL6", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .name = "MultiMedia6", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MultiMedia7 Playback", + .aif_name = "MM_DL7", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia7", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MultiMedia8 Playback", + .aif_name = "MM_DL8", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "MultiMedia8 Capture", + .aif_name = "MM_UL8", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .name = "MultiMedia8", + .probe = fe_dai_probe, + }, + /* FE DAIs created for hostless operation purpose */ + { + .playback = { + .stream_name = "SLIMBUS0_HOSTLESS Playback", + .aif_name = "SLIM0_DL_HL", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "SLIMBUS0_HOSTLESS Capture", + .aif_name = "SLIM0_UL_HL", + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_dai_ops, + .name = "SLIMBUS0_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "SLIMBUS1_HOSTLESS Playback", + .aif_name = "SLIM1_DL_HL", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "SLIMBUS1_HOSTLESS Capture", + .aif_name = "SLIM1_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SLIMBUS1_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "SLIMBUS3_HOSTLESS Playback", + .aif_name = "SLIM3_DL_HL", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "SLIMBUS3_HOSTLESS Capture", + .aif_name = "SLIM3_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SLIMBUS3_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "SLIMBUS4_HOSTLESS Playback", + .aif_name = "SLIM4_DL_HL", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "SLIMBUS4_HOSTLESS Capture", + .aif_name = "SLIM4_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SLIMBUS4_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "SLIMBUS6_HOSTLESS Playback", + .aif_name = "SLIM6_DL_HL", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_dai_ops, + .name = "SLIMBUS6_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "SLIMBUS7_HOSTLESS Playback", + .aif_name = "SLIM7_DL_HL", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "SLIMBUS7_HOSTLESS Capture", + .aif_name = "SLIM7_UL_HL", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_dai_ops, + .name = "SLIMBUS7_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "SLIMBUS8_HOSTLESS Playback", + .aif_name = "SLIM8_DL_HL", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "SLIMBUS8_HOSTLESS Capture", + .aif_name = "SLIM8_UL_HL", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_dai_ops, + .name = "SLIMBUS8_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "INT_FM_HOSTLESS Playback", + .aif_name = "INTFM_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "INT_FM_HOSTLESS Capture", + .aif_name = "INTFM_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "INT_FM_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "INT_HFP_BT Hostless Playback", + .aif_name = "INTHFP_DL_HL", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 16000, + }, + .capture = { + .stream_name = "INT_HFP_BT Hostless Capture", + .aif_name = "INTHFP_UL_HL", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 16000, + }, + .ops = &msm_fe_dai_ops, + .name = "INT_HFP_BT_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "USBAUDIO_HOSTLESS Playback", + .aif_name = "USBAUDIO_DL_HL", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "USBAUDIO_HOSTLESS Capture", + .aif_name = "USBAUDIO_UL_HL", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_dai_ops, + .name = "USBAUDIO_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "AFE Playback", + .aif_name = "PCM_RX", + .rates = (SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "AFE Capture", + .aif_name = "PCM_TX", + .rates = (SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "AFE-PROXY", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "HDMI_HOSTLESS Playback", + .aif_name = "HDMI_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "HDMI_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "AUXPCM_HOSTLESS Playback", + .aif_name = "AUXPCM_DL_HL", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_min = 8000, + .rate_max = 16000, + }, + .capture = { + .stream_name = "AUXPCM_HOSTLESS Capture", + .aif_name = "AUXPCM_UL_HL", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_min = 8000, + .rate_max = 16000, + }, + .ops = &msm_fe_dai_ops, + .name = "AUXPCM_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "VOICE_STUB Playback", + .aif_name = "VOICE_STUB_DL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "VOICE_STUB Capture", + .aif_name = "VOICE_STUB_UL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "VOICE_STUB", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "VoLTE Playback", + .aif_name = "VoLTE_DL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "VoLTE Capture", + .aif_name = "VoLTE_UL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "VoLTE", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MI2S_RX_HOSTLESS Playback", + .aif_name = "MI2S_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "MI2S_TX_HOSTLESS Capture", + .aif_name = "MI2S_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "MI2S_TX_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "SEC_I2S_RX_HOSTLESS Playback", + .aif_name = "SEC_I2S_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_I2S_RX_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Primary MI2S_TX Hostless Capture", + .aif_name = "PRI_MI2S_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_MI2S_TX_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Primary MI2S_RX Hostless Playback", + .aif_name = "PRI_MI2S_DL_HL", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_MI2S_RX_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Secondary MI2S_TX Hostless Capture", + .aif_name = "SEC_MI2S_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_MI2S_TX_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Secondary MI2S_RX Hostless Playback", + .aif_name = "SEC_MI2S_DL_HL", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_MI2S_RX_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Tertiary MI2S_TX Hostless Capture", + .aif_name = "TERT_MI2S_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_MI2S_TX_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Tertiary MI2S_RX Hostless Playback", + .aif_name = "TERT_MI2S_DL_HL", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_MI2S_RX_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Quaternary MI2S_TX Hostless Capture", + .aif_name = "QUAT_MI2S_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_MI2S_TX_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Quaternary MI2S_RX Hostless Playback", + .aif_name = "QUAT_MI2S_DL_HL", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_MI2S_RX_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "INT0 MI2S_RX Hostless Playback", + .aif_name = "INT0_MI2S_DL_HL", + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_fe_dai_ops, + .name = "INT0_MI2S_RX_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "INT4 MI2S_RX Hostless Playback", + .aif_name = "INT4_MI2S_DL_HL", + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 4, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_fe_dai_ops, + .name = "INT4_MI2S_RX_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "INT3 MI2S_TX Hostless Capture", + .aif_name = "INT3_MI2S_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "INT3_MI2S_TX_HOSTLESS", + .probe = fe_dai_probe, + }, + /* TDM Hostless */ + { + .capture = { + .stream_name = "Primary TDM0 Hostless Capture", + .aif_name = "PRI_TDM_TX_0_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_TDM_TX_0_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Primary TDM0 Hostless Playback", + .aif_name = "PRI_TDM_RX_0_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_TDM_RX_0_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Primary TDM1 Hostless Capture", + .aif_name = "PRI_TDM_TX_1_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_TDM_TX_1_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Primary TDM1 Hostless Playback", + .aif_name = "PRI_TDM_RX_1_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_TDM_RX_1_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Primary TDM2 Hostless Capture", + .aif_name = "PRI_TDM_TX_2_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_TDM_TX_2_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Primary TDM2 Hostless Playback", + .aif_name = "PRI_TDM_RX_2_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_TDM_RX_2_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Primary TDM3 Hostless Capture", + .aif_name = "PRI_TDM_TX_3_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_TDM_TX_3_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Primary TDM3 Hostless Playback", + .aif_name = "PRI_TDM_RX_3_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_TDM_RX_3_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Primary TDM4 Hostless Capture", + .aif_name = "PRI_TDM_TX_4_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_TDM_TX_4_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Primary TDM4 Hostless Playback", + .aif_name = "PRI_TDM_RX_4_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_TDM_RX_4_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Primary TDM5 Hostless Capture", + .aif_name = "PRI_TDM_TX_5_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_TDM_TX_5_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Primary TDM5 Hostless Playback", + .aif_name = "PRI_TDM_RX_5_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_TDM_RX_5_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Primary TDM6 Hostless Capture", + .aif_name = "PRI_TDM_TX_6_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_TDM_TX_6_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Primary TDM6 Hostless Playback", + .aif_name = "PRI_TDM_RX_6_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_TDM_RX_6_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Primary TDM7 Hostless Capture", + .aif_name = "PRI_TDM_TX_7_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_TDM_TX_7_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Primary TDM7 Hostless Playback", + .aif_name = "PRI_TDM_RX_7_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "PRI_TDM_RX_7_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Secondary TDM0 Hostless Capture", + .aif_name = "SEC_TDM_TX_0_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_TDM_TX_0_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Secondary TDM0 Hostless Playback", + .aif_name = "SEC_TDM_RX_0_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_TDM_RX_0_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Secondary TDM1 Hostless Capture", + .aif_name = "SEC_TDM_TX_1_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_TDM_TX_1_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Secondary TDM1 Hostless Playback", + .aif_name = "SEC_TDM_RX_1_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_TDM_RX_1_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Secondary TDM2 Hostless Capture", + .aif_name = "SEC_TDM_TX_2_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_TDM_TX_2_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Secondary TDM2 Hostless Playback", + .aif_name = "SEC_TDM_RX_2_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_TDM_RX_2_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Secondary TDM3 Hostless Capture", + .aif_name = "SEC_TDM_TX_3_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_TDM_TX_3_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Secondary TDM3 Hostless Playback", + .aif_name = "SEC_TDM_RX_3_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_TDM_RX_3_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Secondary TDM4 Hostless Capture", + .aif_name = "SEC_TDM_TX_4_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_TDM_TX_4_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Secondary TDM4 Hostless Playback", + .aif_name = "SEC_TDM_RX_4_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_TDM_RX_4_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Secondary TDM5 Hostless Capture", + .aif_name = "SEC_TDM_TX_5_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_TDM_TX_5_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Secondary TDM5 Hostless Playback", + .aif_name = "SEC_TDM_RX_5_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_TDM_RX_5_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Secondary TDM6 Hostless Capture", + .aif_name = "SEC_TDM_TX_6_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_TDM_TX_6_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Secondary TDM6 Hostless Playback", + .aif_name = "SEC_TDM_RX_6_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_TDM_RX_6_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Secondary TDM7 Hostless Capture", + .aif_name = "SEC_TDM_TX_7_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_TDM_TX_7_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Secondary TDM7 Hostless Playback", + .aif_name = "SEC_TDM_RX_7_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_TDM_RX_7_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Tertiary TDM0 Hostless Capture", + .aif_name = "TERT_TDM_TX_0_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_TDM_TX_0_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Tertiary TDM0 Hostless Playback", + .aif_name = "TERT_TDM_RX_0_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_TDM_RX_0_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Tertiary TDM1 Hostless Capture", + .aif_name = "TERT_TDM_TX_1_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_TDM_TX_1_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Tertiary TDM1 Hostless Playback", + .aif_name = "TERT_TDM_RX_1_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_TDM_RX_1_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Tertiary TDM2 Hostless Capture", + .aif_name = "TERT_TDM_TX_2_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_TDM_TX_2_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Tertiary TDM2 Hostless Playback", + .aif_name = "TERT_TDM_RX_2_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_TDM_RX_2_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Tertiary TDM3 Hostless Capture", + .aif_name = "TERT_TDM_TX_3_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_TDM_TX_3_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Tertiary TDM3 Hostless Playback", + .aif_name = "TERT_TDM_RX_3_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_TDM_RX_3_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Tertiary TDM4 Hostless Capture", + .aif_name = "TERT_TDM_TX_4_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_TDM_TX_4_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Tertiary TDM4 Hostless Playback", + .aif_name = "TERT_TDM_RX_4_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_TDM_RX_4_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Tertiary TDM5 Hostless Capture", + .aif_name = "TERT_TDM_TX_5_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_TDM_TX_5_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Tertiary TDM5 Hostless Playback", + .aif_name = "TERT_TDM_RX_5_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_TDM_RX_5_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Tertiary TDM6 Hostless Capture", + .aif_name = "TERT_TDM_TX_6_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_TDM_TX_6_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Tertiary TDM6 Hostless Playback", + .aif_name = "TERT_TDM_RX_6_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_TDM_RX_6_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Tertiary TDM7 Hostless Capture", + .aif_name = "TERT_TDM_TX_7_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_TDM_TX_7_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Tertiary TDM7 Hostless Playback", + .aif_name = "TERT_TDM_RX_7_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "TERT_TDM_RX_7_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Quaternary TDM0 Hostless Capture", + .aif_name = "QUAT_TDM_TX_0_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_TDM_TX_0_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Quaternary TDM0 Hostless Playback", + .aif_name = "QUAT_TDM_RX_0_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_TDM_RX_0_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Quaternary TDM1 Hostless Capture", + .aif_name = "QUAT_TDM_TX_1_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_TDM_TX_1_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Quaternary TDM1 Hostless Playback", + .aif_name = "QUAT_TDM_RX_1_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_TDM_RX_1_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Quaternary TDM2 Hostless Capture", + .aif_name = "QUAT_TDM_TX_2_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_TDM_TX_2_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Quaternary TDM2 Hostless Playback", + .aif_name = "QUAT_TDM_RX_2_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_TDM_RX_2_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Quaternary TDM3 Hostless Capture", + .aif_name = "QUAT_TDM_TX_3_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_TDM_TX_3_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Quaternary TDM3 Hostless Playback", + .aif_name = "QUAT_TDM_RX_3_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_TDM_RX_3_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Quaternary TDM4 Hostless Capture", + .aif_name = "QUAT_TDM_TX_4_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_TDM_TX_4_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Quaternary TDM4 Hostless Playback", + .aif_name = "QUAT_TDM_RX_4_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_TDM_RX_4_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Quaternary TDM5 Hostless Capture", + .aif_name = "QUAT_TDM_TX_5_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_TDM_TX_5_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Quaternary TDM5 Hostless Playback", + .aif_name = "QUAT_TDM_RX_5_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_TDM_RX_5_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Quaternary TDM6 Hostless Capture", + .aif_name = "QUAT_TDM_TX_6_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_TDM_TX_6_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Quaternary TDM6 Hostless Playback", + .aif_name = "QUAT_TDM_RX_6_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_TDM_RX_6_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Quaternary TDM7 Hostless Capture", + .aif_name = "QUAT_TDM_TX_7_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_TDM_TX_7_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Quaternary TDM7 Hostless Playback", + .aif_name = "QUAT_TDM_RX_7_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUAT_TDM_RX_7_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Voice2 Playback", + .aif_name = "VOICE2_DL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "Voice2 Capture", + .aif_name = "VOICE2_UL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "Voice2", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Pseudo Playback", + .aif_name = "MM_DL9", + .rates = (SNDRV_PCM_RATE_8000_48000 | + SNDRV_PCM_RATE_KNOT), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "Pseudo Capture", + .aif_name = "MM_UL9", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .name = "Pseudo", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "DTMF_RX_HOSTLESS Playback", + .aif_name = "DTMF_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "DTMF_RX_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "CPE Listen Audio capture", + .aif_name = "CPE_LSM_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 1, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "CPE_LSM_NOHOST", + }, + { + .playback = { + .stream_name = "VOLTE_STUB Playback", + .aif_name = "VOLTE_STUB_DL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "VOLTE_STUB Capture", + .aif_name = "VOLTE_STUB_UL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "VOLTE_STUB", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "VOICE2_STUB Playback", + .aif_name = "VOICE2_STUB_DL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "VOICE2_STUB Capture", + .aif_name = "VOICE2_STUB_UL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "VOICE2_STUB", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MultiMedia9 Playback", + .aif_name = "MM_DL9", + .rates = (SNDRV_PCM_RATE_8000_384000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "MultiMedia9 Capture", + .aif_name = "MM_UL9", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .name = "MultiMedia9", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "QCHAT Playback", + .aif_name = "QCHAT_DL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "QCHAT Capture", + .aif_name = "QCHAT_UL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QCHAT", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Listen 1 Audio Service Capture", + .aif_name = "LSM1_UL_HL", + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 4, + .rate_min = 16000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "LSM1", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Listen 2 Audio Service Capture", + .aif_name = "LSM2_UL_HL", + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 4, + .rate_min = 16000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "LSM2", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Listen 3 Audio Service Capture", + .aif_name = "LSM3_UL_HL", + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 4, + .rate_min = 16000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "LSM3", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Listen 4 Audio Service Capture", + .aif_name = "LSM4_UL_HL", + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 4, + .rate_min = 16000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "LSM4", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Listen 5 Audio Service Capture", + .aif_name = "LSM5_UL_HL", + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 4, + .rate_min = 16000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "LSM5", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Listen 6 Audio Service Capture", + .aif_name = "LSM6_UL_HL", + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 4, + .rate_min = 16000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "LSM6", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Listen 7 Audio Service Capture", + .aif_name = "LSM7_UL_HL", + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 4, + .rate_min = 16000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "LSM7", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "Listen 8 Audio Service Capture", + .aif_name = "LSM8_UL_HL", + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 4, + .rate_min = 16000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "LSM8", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "VoWLAN Playback", + .aif_name = "VoWLAN_DL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "VoWLAN Capture", + .aif_name = "VoWLAN_UL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "VoWLAN", + .probe = fe_dai_probe, + }, + /* FE DAIs created for multiple instances of offload playback */ + { + .playback = { + .stream_name = "MultiMedia10 Playback", + .aif_name = "MM_DL10", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia10", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MultiMedia11 Playback", + .aif_name = "MM_DL11", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia11", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MultiMedia12 Playback", + .aif_name = "MM_DL12", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia12", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MultiMedia13 Playback", + .aif_name = "MM_DL13", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia13", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MultiMedia14 Playback", + .aif_name = "MM_DL14", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia14", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MultiMedia15 Playback", + .aif_name = "MM_DL15", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia15", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MultiMedia16 Playback", + .aif_name = "MM_DL16", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia16", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "VoiceMMode1 Playback", + .aif_name = "VOICEMMODE1_DL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "VoiceMMode1 Capture", + .aif_name = "VOICEMMODE1_UL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "VoiceMMode1", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "VoiceMMode2 Playback", + .aif_name = "VOICEMMODE2_DL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "VoiceMMode2 Capture", + .aif_name = "VOICEMMODE2_UL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "VoiceMMode2", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "MultiMedia17 Capture", + .aif_name = "MM_UL17", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia17", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "MultiMedia18 Capture", + .aif_name = "MM_UL18", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia18", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "MultiMedia19 Capture", + .aif_name = "MM_UL19", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia19", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MultiMedia20 Playback", + .aif_name = "MM_DL20", + .rates = (SNDRV_PCM_RATE_8000_384000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "MultiMedia20 Capture", + .aif_name = "MM_UL20", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .name = "MultiMedia20", + .probe = fe_dai_probe, + }, +}; + +static int msm_fe_dai_dev_probe(struct platform_device *pdev) +{ + + dev_dbg(&pdev->dev, "%s: dev name %s\n", __func__, + dev_name(&pdev->dev)); + return snd_soc_register_component(&pdev->dev, &msm_fe_dai_component, + msm_fe_dais, ARRAY_SIZE(msm_fe_dais)); +} + +static int msm_fe_dai_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_component(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_dai_fe_dt_match[] = { + {.compatible = "qcom,msm-dai-fe"}, + {} +}; + +static struct platform_driver msm_fe_dai_driver = { + .probe = msm_fe_dai_dev_probe, + .remove = msm_fe_dai_dev_remove, + .driver = { + .name = "msm-dai-fe", + .owner = THIS_MODULE, + .of_match_table = msm_dai_fe_dt_match, + }, +}; + +static int __init msm_fe_dai_init(void) +{ + return platform_driver_register(&msm_fe_dai_driver); +} +module_init(msm_fe_dai_init); + +static void __exit msm_fe_dai_exit(void) +{ + platform_driver_unregister(&msm_fe_dai_driver); +} +module_exit(msm_fe_dai_exit); + +/* Module information */ +MODULE_DESCRIPTION("MSM Frontend DAI driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/msm-pcm-hostless.c b/sound/soc/msm/msm-pcm-hostless.c new file mode 100644 index 000000000000..35766b44981c --- /dev/null +++ b/sound/soc/msm/msm-pcm-hostless.c @@ -0,0 +1,82 @@ +/* Copyright (c) 2011-2014, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + + +static int msm_pcm_hostless_prepare(struct snd_pcm_substream *substream) +{ + if (!substream) { + pr_err("%s: invalid params\n", __func__); + return -EINVAL; + } + pm_qos_remove_request(&substream->latency_pm_qos_req); + return 0; +} + +static const struct snd_pcm_ops msm_pcm_hostless_ops = { + .prepare = msm_pcm_hostless_prepare +}; + +static struct snd_soc_platform_driver msm_soc_hostless_platform = { + .ops = &msm_pcm_hostless_ops, +}; + +static int msm_pcm_hostless_probe(struct platform_device *pdev) +{ + + pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev)); + return snd_soc_register_platform(&pdev->dev, + &msm_soc_hostless_platform); +} + +static int msm_pcm_hostless_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_pcm_hostless_dt_match[] = { + {.compatible = "qcom,msm-pcm-hostless"}, + {} +}; + +static struct platform_driver msm_pcm_hostless_driver = { + .driver = { + .name = "msm-pcm-hostless", + .owner = THIS_MODULE, + .of_match_table = msm_pcm_hostless_dt_match, + }, + .probe = msm_pcm_hostless_probe, + .remove = msm_pcm_hostless_remove, +}; + +static int __init msm_soc_platform_init(void) +{ + return platform_driver_register(&msm_pcm_hostless_driver); +} +module_init(msm_soc_platform_init); + +static void __exit msm_soc_platform_exit(void) +{ + platform_driver_unregister(&msm_pcm_hostless_driver); +} +module_exit(msm_soc_platform_exit); + +MODULE_DESCRIPTION("Hostless platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/msm8996.c b/sound/soc/msm/msm8996.c new file mode 100644 index 000000000000..45c5479884a2 --- /dev/null +++ b/sound/soc/msm/msm8996.c @@ -0,0 +1,4006 @@ +/* + * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qdsp6v2/msm-pcm-routing-v2.h" +#include "../codecs/wcd9xxx-common.h" +#include "../codecs/wcd9330.h" +#include "../codecs/wcd9335.h" +#include "../codecs/wsa881x.h" + +#define DRV_NAME "msm8996-asoc-snd" + +#define SAMPLING_RATE_8KHZ 8000 +#define SAMPLING_RATE_16KHZ 16000 +#define SAMPLING_RATE_32KHZ 32000 +#define SAMPLING_RATE_48KHZ 48000 +#define SAMPLING_RATE_96KHZ 96000 +#define SAMPLING_RATE_192KHZ 192000 +#define SAMPLING_RATE_44P1KHZ 44100 + +#define MSM8996_SPK_ON 1 +#define MSM8996_HIFI_ON 1 + +#define WCD9XXX_MBHC_DEF_BUTTONS 8 +#define WCD9XXX_MBHC_DEF_RLOADS 5 +#define CODEC_EXT_CLK_RATE 9600000 +#define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define DEV_NAME_STR_LEN 32 + +#define WSA8810_NAME_1 "wsa881x.20170211" +#define WSA8810_NAME_2 "wsa881x.20170212" + +static int slim0_rx_sample_rate = SAMPLING_RATE_48KHZ; +static int slim0_tx_sample_rate = SAMPLING_RATE_48KHZ; +static int slim1_tx_sample_rate = SAMPLING_RATE_48KHZ; +static int slim0_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int slim0_tx_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int slim1_tx_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int hdmi_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm8996_auxpcm_rate = SAMPLING_RATE_8KHZ; +static int slim5_rx_sample_rate = SAMPLING_RATE_48KHZ; +static int slim5_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int slim6_rx_sample_rate = SAMPLING_RATE_48KHZ; +static int slim6_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; + +static struct platform_device *spdev; +static int ext_us_amp_gpio = -1; +static int msm8996_spk_control = 1; +static int msm_slim_0_rx_ch = 1; +static int msm_slim_0_tx_ch = 1; +static int msm_slim_1_tx_ch = 1; +static int msm_slim_5_rx_ch = 1; +static int msm_slim_6_rx_ch = 1; +static int msm_hifi_control; +static int msm_vi_feed_tx_ch = 2; + +static int msm_hdmi_rx_ch = 2; +static int msm_proxy_rx_ch = 2; +static int hdmi_rx_sample_rate = SAMPLING_RATE_48KHZ; +static int msm_tert_mi2s_tx_ch = 2; + +static bool codec_reg_done; + +static const char *const hifi_function[] = {"Off", "On"}; +static const char *const pin_states[] = {"Disable", "active"}; +static const char *const spk_function[] = {"Off", "On"}; +static const char *const slim0_rx_ch_text[] = {"One", "Two"}; +static const char *const slim5_rx_ch_text[] = {"One", "Two"}; +static const char *const slim6_rx_ch_text[] = {"One", "Two"}; +static const char *const slim0_tx_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static const char *const vi_feed_ch_text[] = {"One", "Two"}; +static char const *hdmi_rx_ch_text[] = {"Two", "Three", "Four", "Five", + "Six", "Seven", "Eight"}; +static char const *rx_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"}; +static char const *slim5_rx_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"}; +static char const *slim6_rx_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"}; +static char const *slim0_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_44P1", "KHZ_8", + "KHZ_16", "KHZ_32"}; +static char const *slim5_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_44P1"}; +static char const *slim6_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_44P1"}; +static const char *const proxy_rx_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", "Eight"}; + +static char const *hdmi_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96", + "KHZ_192"}; + +static const char *const auxpcm_rate_text[] = {"8000", "16000"}; +static const struct soc_enum msm8996_auxpcm_enum[] = { + SOC_ENUM_SINGLE_EXT(2, auxpcm_rate_text), +}; + +static struct afe_clk_set mi2s_tx_clk = { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, +}; + +struct msm8996_wsa881x_dev_info { + struct device_node *of_node; + u32 index; +}; + +static struct snd_soc_aux_dev *msm8996_aux_dev; +static struct snd_soc_codec_conf *msm8996_codec_conf; + +struct msm8996_asoc_mach_data { + u32 mclk_freq; + int us_euro_gpio; + int hph_en1_gpio; + int hph_en0_gpio; + struct snd_info_entry *codec_root; +}; + +struct msm8996_asoc_wcd93xx_codec { + void* (*get_afe_config_fn)(struct snd_soc_codec *codec, + enum afe_config_type config_type); + void (*mbhc_hs_detect_exit)(struct snd_soc_codec *codec); +}; + +static struct msm8996_asoc_wcd93xx_codec msm8996_codec_fn; + +struct msm8996_liquid_dock_dev { + int dock_plug_gpio; + int dock_plug_irq; + int dock_plug_det; + struct work_struct irq_work; + struct switch_dev audio_sdev; +}; +static struct msm8996_liquid_dock_dev *msm8996_liquid_dock_dev; + +static void *adsp_state_notifier; +static void *def_tasha_mbhc_cal(void); +static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, + int enable, bool dapm); +static int msm8996_wsa881x_init(struct snd_soc_component *component); + +/* + * Need to report LINEIN + * if R/L channel impedance is larger than 5K ohm + */ +static struct wcd_mbhc_config wcd_mbhc_cfg = { + .read_fw_bin = false, + .calibration = NULL, + .detect_extn_cable = true, + .mono_stero_detection = false, + .swap_gnd_mic = NULL, + .hs_ext_micbias = true, + .key_code[0] = KEY_MEDIA, + .key_code[1] = KEY_VOICECOMMAND, + .key_code[2] = KEY_VOLUMEUP, + .key_code[3] = KEY_VOLUMEDOWN, + .key_code[4] = 0, + .key_code[5] = 0, + .key_code[6] = 0, + .key_code[7] = 0, + .linein_th = 5000, + .moisture_en = true, + .mbhc_micbias = MIC_BIAS_2, + .anc_micbias = MIC_BIAS_2, + .enable_anc_mic_detect = false, +}; + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, + int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +static void msm8996_liquid_docking_irq_work(struct work_struct *work) +{ + struct msm8996_liquid_dock_dev *dock_dev = + container_of(work, struct msm8996_liquid_dock_dev, + irq_work); + + dock_dev->dock_plug_det = + gpio_get_value(dock_dev->dock_plug_gpio); + + switch_set_state(&dock_dev->audio_sdev, dock_dev->dock_plug_det); + /* notify to audio daemon */ + sysfs_notify(&dock_dev->audio_sdev.dev->kobj, NULL, "state"); +} + +static irqreturn_t msm8996_liquid_docking_irq_handler(int irq, void *dev) +{ + struct msm8996_liquid_dock_dev *dock_dev = dev; + + /* switch speakers should not run in interrupt context */ + schedule_work(&dock_dev->irq_work); + return IRQ_HANDLED; +} + +static int msm8996_liquid_init_docking(void) +{ + int ret = 0; + int dock_plug_gpio = 0; + + /* plug in docking speaker+plug in device OR unplug one of them */ + u32 dock_plug_irq_flags = IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | + IRQF_SHARED; + + dock_plug_gpio = of_get_named_gpio(spdev->dev.of_node, + "qcom,dock-plug-det-irq", 0); + + if (dock_plug_gpio >= 0) { + msm8996_liquid_dock_dev = + kzalloc(sizeof(*msm8996_liquid_dock_dev), GFP_KERNEL); + if (!msm8996_liquid_dock_dev) { + ret = -ENOMEM; + goto exit; + } + + msm8996_liquid_dock_dev->dock_plug_gpio = dock_plug_gpio; + + ret = gpio_request(msm8996_liquid_dock_dev->dock_plug_gpio, + "dock-plug-det-irq"); + if (ret) { + pr_err("%s:failed request msm8996_liquid_dock_plug_gpio err = %d\n", + __func__, ret); + ret = -EINVAL; + goto fail_dock_gpio; + } + + msm8996_liquid_dock_dev->dock_plug_det = + gpio_get_value( + msm8996_liquid_dock_dev->dock_plug_gpio); + msm8996_liquid_dock_dev->dock_plug_irq = + gpio_to_irq( + msm8996_liquid_dock_dev->dock_plug_gpio); + + ret = request_irq(msm8996_liquid_dock_dev->dock_plug_irq, + msm8996_liquid_docking_irq_handler, + dock_plug_irq_flags, + "liquid_dock_plug_irq", + msm8996_liquid_dock_dev); + if (ret < 0) { + pr_err("%s: Request Irq Failed err = %d\n", + __func__, ret); + goto fail_dock_gpio; + } + + msm8996_liquid_dock_dev->audio_sdev.name = + QC_AUDIO_EXTERNAL_SPK_1_EVENT; + + if (switch_dev_register( + &msm8996_liquid_dock_dev->audio_sdev) < 0) { + pr_err("%s: dock device register in switch diretory failed\n", + __func__); + goto fail_switch_dev; + } + + INIT_WORK( + &msm8996_liquid_dock_dev->irq_work, + msm8996_liquid_docking_irq_work); + } + return 0; + +fail_switch_dev: + free_irq(msm8996_liquid_dock_dev->dock_plug_irq, + msm8996_liquid_dock_dev); +fail_dock_gpio: + gpio_free(msm8996_liquid_dock_dev->dock_plug_gpio); +exit: + kfree(msm8996_liquid_dock_dev); + msm8996_liquid_dock_dev = NULL; + return ret; +} + +static void msm8996_ext_control(struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + + pr_debug("%s: msm8996_spk_control = %d", __func__, + msm8996_spk_control); + if (msm8996_spk_control == MSM8996_SPK_ON) { + snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp"); + snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp"); + } else { + snd_soc_dapm_disable_pin(dapm, "Lineout_1 amp"); + snd_soc_dapm_disable_pin(dapm, "Lineout_2 amp"); + } + snd_soc_dapm_sync(dapm); +} + +static int msm8996_get_spk(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm8996_spk_control = %d\n", + __func__, msm8996_spk_control); + ucontrol->value.integer.value[0] = msm8996_spk_control; + return 0; +} + +static int msm8996_set_spk(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + if (msm8996_spk_control == ucontrol->value.integer.value[0]) + return 0; + + msm8996_spk_control = ucontrol->value.integer.value[0]; + msm8996_ext_control(codec); + return 1; +} + +static int msm8996_hifi_ctrl(struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_card *card = codec->component.card; + struct msm8996_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + + pr_debug("%s: msm_hifi_control = %d", __func__, + msm_hifi_control); + if (pdata->hph_en1_gpio < 0) { + pr_err("%s: hph_en1_gpio is invalid\n", __func__); + return -EINVAL; + } + if (msm_hifi_control == MSM8996_HIFI_ON) { + gpio_direction_output(pdata->hph_en1_gpio, 1); + /* 5msec delay needed as per HW requirement */ + usleep_range(5000, 5010); + } else { + gpio_direction_output(pdata->hph_en1_gpio, 0); + } + snd_soc_dapm_sync(dapm); + return 0; +} + +static int msm8996_hifi_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_hifi_control = %d\n", + __func__, msm_hifi_control); + ucontrol->value.integer.value[0] = msm_hifi_control; + return 0; +} + +static int msm8996_hifi_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + msm_hifi_control = ucontrol->value.integer.value[0]; + msm8996_hifi_ctrl(codec); + return 1; +} + +static int msm8996_ext_us_amp_init(void) +{ + int ret = 0; + + ext_us_amp_gpio = of_get_named_gpio(spdev->dev.of_node, + "qcom,ext-ult-spk-amp-gpio", 0); + if (ext_us_amp_gpio >= 0) { + ret = gpio_request(ext_us_amp_gpio, "ext_us_amp_gpio"); + if (ret) { + pr_err("%s: ext_us_amp_gpio request failed, ret:%d\n", + __func__, ret); + return ret; + } + gpio_direction_output(ext_us_amp_gpio, 0); + } + return ret; +} + +static void msm8996_ext_us_amp_enable(u32 on) +{ + if (on) + gpio_direction_output(ext_us_amp_gpio, 1); + else + gpio_direction_output(ext_us_amp_gpio, 0); + + pr_debug("%s: US Emitter GPIO enable:%s\n", __func__, + on ? "Enable" : "Disable"); +} + +static int msm_ext_ultrasound_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + pr_debug("%s()\n", __func__); + if (strcmp(w->name, "ultrasound amp")) { + if (!gpio_is_valid(ext_us_amp_gpio)) { + pr_err("%s: ext_us_amp_gpio isn't configured\n", + __func__); + return -EINVAL; + } + if (SND_SOC_DAPM_EVENT_ON(event)) + msm8996_ext_us_amp_enable(1); + else + msm8996_ext_us_amp_enable(0); + } else { + pr_err("%s() Invalid Widget = %s\n", + __func__, w->name); + return -EINVAL; + } + return 0; +} + +static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, + int enable, bool dapm) +{ + int ret = 0; + + if (!strcmp(dev_name(codec->dev), "tasha_codec")) { + ret = tasha_cdc_mclk_enable(codec, enable, dapm); + } else { + dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", + __func__); + ret = -EINVAL; + } + + return ret; +} + +static int msm8996_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + pr_debug("%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return msm_snd_enable_codec_ext_clk(codec, 1, true); + case SND_SOC_DAPM_POST_PMD: + return msm_snd_enable_codec_ext_clk(codec, 0, true); + } + return 0; +} + +static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, + int enable, bool dapm) +{ + int ret = 0; + + if (!strcmp(dev_name(codec->dev), "tasha_codec")) + ret = tasha_cdc_mclk_tx_enable(codec, enable, dapm); + else { + dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", + __func__); + ret = -EINVAL; + } + return ret; +} + +static int msm8996_mclk_tx_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + pr_debug("%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return msm_snd_enable_codec_ext_tx_clk(codec, 1, true); + case SND_SOC_DAPM_POST_PMD: + return msm_snd_enable_codec_ext_tx_clk(codec, 0, true); + } + return 0; +} + +static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_card *card = codec->component.card; + struct msm8996_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + int ret = 0; + + pr_debug("%s: msm_hifi_control = %d", __func__, + msm_hifi_control); + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (msm_hifi_control == MSM8996_HIFI_ON) { + if (pdata->hph_en0_gpio < 0) { + pr_err("%s: hph_en0_gpio is invalid\n", + __func__); + ret = -EINVAL; + goto err; + } + gpio_direction_output(pdata->hph_en0_gpio, 1); + } + break; + case SND_SOC_DAPM_PRE_PMD: + if (msm_hifi_control == MSM8996_HIFI_ON) { + if (pdata->hph_en0_gpio < 0) { + pr_err("%s: hph_en0_gpio is invalid\n", + __func__); + ret = -EINVAL; + goto err; + } + gpio_direction_output(pdata->hph_en0_gpio, 0); + } + break; + } +err: + return ret; +} + +static const struct snd_soc_dapm_widget msm8996_dapm_widgets[] = { + + SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, + msm8996_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0, + msm8996_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SPK("Lineout_1 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_3 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_4 amp", NULL), + SND_SOC_DAPM_SPK("ultrasound amp", msm_ext_ultrasound_event), + SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event), + SND_SOC_DAPM_MIC("Handset Mic", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), + SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL), + SND_SOC_DAPM_MIC("Analog Mic4", NULL), + SND_SOC_DAPM_MIC("Analog Mic6", NULL), + SND_SOC_DAPM_MIC("Analog Mic7", NULL), + SND_SOC_DAPM_MIC("Analog Mic8", NULL), + + SND_SOC_DAPM_MIC("Digital Mic0", NULL), + SND_SOC_DAPM_MIC("Digital Mic1", NULL), + SND_SOC_DAPM_MIC("Digital Mic2", NULL), + SND_SOC_DAPM_MIC("Digital Mic3", NULL), + SND_SOC_DAPM_MIC("Digital Mic4", NULL), + SND_SOC_DAPM_MIC("Digital Mic5", NULL), + SND_SOC_DAPM_MIC("Digital Mic6", NULL), +}; + +static struct snd_soc_dapm_route wcd9335_audio_paths[] = { + {"MIC BIAS1", NULL, "MCLK TX"}, + {"MIC BIAS2", NULL, "MCLK TX"}, + {"MIC BIAS3", NULL, "MCLK TX"}, + {"MIC BIAS4", NULL, "MCLK TX"}, +}; + +static int slim5_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val = 0; + + switch (slim5_rx_sample_rate) { + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: slim5_rx_sample_rate = %d\n", __func__, + slim5_rx_sample_rate); + + return 0; +} + +static int slim5_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: ucontrol value = %ld\n", __func__, + ucontrol->value.integer.value[0]); + + switch (ucontrol->value.integer.value[0]) { + case 3: + slim5_rx_sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 2: + slim5_rx_sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + slim5_rx_sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim5_rx_sample_rate = SAMPLING_RATE_48KHZ; + } + + pr_debug("%s: slim5_rx_sample_rate = %d\n", __func__, + slim5_rx_sample_rate); + + return 0; +} + +static int slim6_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val = 0; + + switch (slim6_rx_sample_rate) { + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: slim6_rx_sample_rate = %d\n", __func__, + slim6_rx_sample_rate); + + return 0; +} + +static int slim6_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 3: + slim6_rx_sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 2: + slim6_rx_sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + slim6_rx_sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim6_rx_sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: ucontrol value = %ld, slim6_rx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + slim6_rx_sample_rate); + + return 0; +} + +static int slim0_tx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (slim0_tx_bit_format) { + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: slim0_tx_bit_format = %d, ucontrol value = %ld\n", + __func__, slim0_tx_bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int slim0_tx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 2: + slim0_tx_bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + slim0_tx_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + slim0_tx_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + default: + pr_err("%s: invalid value %ld\n", __func__, + ucontrol->value.integer.value[0]); + rc = -EINVAL; + break; + } + + pr_debug("%s: ucontrol value = %ld, slim0_tx_bit_format = %d\n", + __func__, ucontrol->value.integer.value[0], + slim0_tx_bit_format); + + return rc; +} + +static int slim0_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val = 0; + + switch (slim0_rx_sample_rate) { + case SAMPLING_RATE_32KHZ: + sample_rate_val = 6; + break; + + case SAMPLING_RATE_16KHZ: + sample_rate_val = 5; + break; + + case SAMPLING_RATE_8KHZ: + sample_rate_val = 4; + break; + + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: slim0_rx_sample_rate = %d\n", __func__, + slim0_rx_sample_rate); + + return 0; +} + +static int slim0_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: ucontrol value = %ld\n", __func__, + ucontrol->value.integer.value[0]); + + switch (ucontrol->value.integer.value[0]) { + case 6: + slim0_rx_sample_rate = SAMPLING_RATE_32KHZ; + break; + case 5: + slim0_rx_sample_rate = SAMPLING_RATE_16KHZ; + break; + case 4: + slim0_rx_sample_rate = SAMPLING_RATE_8KHZ; + break; + case 3: + slim0_rx_sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 2: + slim0_rx_sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + slim0_rx_sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim0_rx_sample_rate = SAMPLING_RATE_48KHZ; + } + + pr_debug("%s: slim0_rx_sample_rate = %d\n", __func__, + slim0_rx_sample_rate); + + return 0; +} + +static int slim0_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val = 0; + + switch (slim0_tx_sample_rate) { + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: slim0_tx_sample_rate = %d\n", __func__, + slim0_tx_sample_rate); + return 0; +} + +static int slim0_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + pr_debug("%s: ucontrol value = %ld\n", __func__, + ucontrol->value.integer.value[0]); + + switch (ucontrol->value.integer.value[0]) { + case 2: + slim0_tx_sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + slim0_tx_sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + slim0_tx_sample_rate = SAMPLING_RATE_48KHZ; + break; + default: + rc = -EINVAL; + pr_err("%s: invalid sample rate being passed\n", __func__); + break; + } + + pr_debug("%s: slim0_tx_sample_rate = %d\n", __func__, + slim0_tx_sample_rate); + return rc; +} + +static int slim5_rx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + switch (slim5_rx_bit_format) { + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: slim5_rx_bit_format = %d, ucontrol value = %ld\n", + __func__, slim5_rx_bit_format, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int slim5_rx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 2: + slim5_rx_bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + slim5_rx_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + slim5_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return 0; +} + +static int slim6_rx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + switch (slim6_rx_bit_format) { + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: slim6_rx_bit_format = %d, ucontrol value = %ld\n", + __func__, slim6_rx_bit_format, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int slim6_rx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 2: + slim6_rx_bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + slim6_rx_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + slim6_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return 0; +} + +static int slim0_rx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + switch (slim0_rx_bit_format) { + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: slim0_rx_bit_format = %d, ucontrol value = %ld\n", + __func__, slim0_rx_bit_format, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int slim0_rx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 2: + slim0_rx_bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + slim0_rx_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + slim0_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return 0; +} + +static int msm_slim_5_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_slim_5_rx_ch = %d\n", __func__, + msm_slim_5_rx_ch); + ucontrol->value.integer.value[0] = msm_slim_5_rx_ch - 1; + return 0; +} + +static int msm_slim_5_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_slim_5_rx_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_slim_5_rx_ch = %d\n", __func__, + msm_slim_5_rx_ch); + return 1; +} + +static int msm_slim_6_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_slim_6_rx_ch = %d\n", __func__, + msm_slim_6_rx_ch); + ucontrol->value.integer.value[0] = msm_slim_6_rx_ch - 1; + return 0; +} + +static int msm_slim_6_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_slim_6_rx_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_slim_6_rx_ch = %d\n", __func__, + msm_slim_6_rx_ch); + return 1; +} + +static int msm_slim_0_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_slim_0_rx_ch = %d\n", __func__, + msm_slim_0_rx_ch); + ucontrol->value.integer.value[0] = msm_slim_0_rx_ch - 1; + return 0; +} + +static int msm_slim_0_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_slim_0_rx_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_slim_0_rx_ch = %d\n", __func__, + msm_slim_0_rx_ch); + return 1; +} + +static int msm_slim_0_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_slim_0_tx_ch = %d\n", __func__, + msm_slim_0_tx_ch); + ucontrol->value.integer.value[0] = msm_slim_0_tx_ch - 1; + return 0; +} + +static int msm_slim_0_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_slim_0_tx_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_slim_0_tx_ch = %d\n", __func__, msm_slim_0_tx_ch); + return 1; +} + +static int msm_slim_1_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_slim_1_tx_ch = %d\n", __func__, + msm_slim_1_tx_ch); + ucontrol->value.integer.value[0] = msm_slim_1_tx_ch - 1; + return 0; +} + +static int msm_slim_1_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_slim_1_tx_ch = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: msm_slim_1_tx_ch = %d\n", __func__, msm_slim_1_tx_ch); + return 1; +} + +static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1; + pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch); + return 1; +} + +static int hdmi_rx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + switch (hdmi_rx_bit_format) { + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: hdmi_rx_bit_format = %d, ucontrol value = %ld\n", + __func__, hdmi_rx_bit_format, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int hdmi_rx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 2: + hdmi_rx_bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + hdmi_rx_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + hdmi_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: hdmi_rx_bit_format = %d, ucontrol value = %ld\n", + __func__, hdmi_rx_bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_hdmi_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_hdmi_rx_ch = %d\n", __func__, + msm_hdmi_rx_ch); + ucontrol->value.integer.value[0] = msm_hdmi_rx_ch - 2; + + return 0; +} + +static int msm_hdmi_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_hdmi_rx_ch = ucontrol->value.integer.value[0] + 2; + if (msm_hdmi_rx_ch > 8) { + pr_err("%s: channels %d exceeded 8.Limiting to max chs-8\n", + __func__, msm_hdmi_rx_ch); + msm_hdmi_rx_ch = 8; + } + pr_debug("%s: msm_hdmi_rx_ch = %d\n", __func__, msm_hdmi_rx_ch); + + return 1; +} + +static int hdmi_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val = 0; + + switch (hdmi_rx_sample_rate) { + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: hdmi_rx_sample_rate = %d\n", __func__, + hdmi_rx_sample_rate); + + return 0; +} + +static int hdmi_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: ucontrol value = %ld\n", __func__, + ucontrol->value.integer.value[0]); + + switch (ucontrol->value.integer.value[0]) { + case 2: + hdmi_rx_sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + hdmi_rx_sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + hdmi_rx_sample_rate = SAMPLING_RATE_48KHZ; + } + + pr_debug("%s: hdmi_rx_sample_rate = %d\n", __func__, + hdmi_rx_sample_rate); + + return 0; +} + +static int msm8996_auxpcm_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm8996_auxpcm_rate; + return 0; +} + +static int msm8996_auxpcm_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm8996_auxpcm_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + msm8996_auxpcm_rate = SAMPLING_RATE_16KHZ; + break; + default: + msm8996_auxpcm_rate = SAMPLING_RATE_8KHZ; + break; + } + return 0; +} + +static int msm_proxy_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_proxy_rx_ch = %d\n", __func__, msm_proxy_rx_ch); + ucontrol->value.integer.value[0] = msm_proxy_rx_ch - 1; + return 0; +} + +static int msm_proxy_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_proxy_rx_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_proxy_rx_ch = %d\n", __func__, msm_proxy_rx_ch); + return 1; +} + +static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = + hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); + + struct snd_interval *channels = + hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + + rate->min = rate->max = msm8996_auxpcm_rate; + channels->min = channels->max = 1; + + return 0; +} + +static int msm_proxy_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + pr_debug("%s: msm_proxy_rx_ch =%d\n", __func__, msm_proxy_rx_ch); + + if (channels->max < 2) + channels->min = channels->max = 2; + channels->min = channels->max = msm_proxy_rx_ch; + rate->min = rate->max = SAMPLING_RATE_48KHZ; + return 0; +} + +static int msm_proxy_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + + rate->min = rate->max = SAMPLING_RATE_48KHZ; + return 0; +} + +static int msm8996_hdmi_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + pr_debug("%s channels->min %u channels->max %u ()\n", __func__, + channels->min, channels->max); + + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + hdmi_rx_bit_format); + if (channels->max < 2) + channels->min = channels->max = 2; + rate->min = rate->max = hdmi_rx_sample_rate; + channels->min = channels->max = msm_hdmi_rx_ch; + + return 0; +} + +static int msm_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + pr_debug("%s: channel:%d\n", __func__, msm_tert_mi2s_tx_ch); + rate->min = rate->max = SAMPLING_RATE_48KHZ; + channels->min = channels->max = msm_tert_mi2s_tx_ch; + return 0; +} + +static int msm8996_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + + pr_debug("%s: substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + mi2s_tx_clk.enable = 1; + ret = afe_set_lpass_clock_v2(AFE_PORT_ID_TERTIARY_MI2S_TX, + &mi2s_tx_clk); + if (ret < 0) { + pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret); + goto err; + } + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + pr_err("%s: set fmt cpu dai failed, err:%d\n", __func__, ret); +err: + return ret; +} + +static void msm8996_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret = 0; + + pr_debug("%s: substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + mi2s_tx_clk.enable = 0; + ret = afe_set_lpass_clock_v2(AFE_PORT_ID_TERTIARY_MI2S_TX, + &mi2s_tx_clk); + if (ret < 0) + pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret); +} + +static struct snd_soc_ops msm8996_mi2s_be_ops = { + .startup = msm8996_mi2s_snd_startup, + .shutdown = msm8996_mi2s_snd_shutdown, +}; + +static int msm_slim_5_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim5_rx_bit_format); + rate->min = rate->max = slim5_rx_sample_rate; + channels->min = channels->max = msm_slim_5_rx_ch; + + pr_debug("%s: format = %d, rate = %d, channels = %d\n", + __func__, params_format(params), params_rate(params), + msm_slim_5_rx_ch); + + return 0; +} + +static int msm_slim_6_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim6_rx_bit_format); + rate->min = rate->max = slim6_rx_sample_rate; + channels->min = channels->max = msm_slim_6_rx_ch; + + pr_debug("%s: format = %d, rate = %d, channels = %d\n", + __func__, params_format(params), params_rate(params), + msm_slim_6_rx_ch); + + return 0; +} + +static int msm_slim_0_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim0_rx_bit_format); + rate->min = rate->max = slim0_rx_sample_rate; + channels->min = channels->max = msm_slim_0_rx_ch; + + pr_debug("%s: format = %d, rate = %d, channels = %d\n", + __func__, params_format(params), params_rate(params), + msm_slim_0_rx_ch); + + return 0; +} + +static int msm_slim_0_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + pr_debug("%s()\n", __func__); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, slim0_tx_bit_format); + rate->min = rate->max = slim0_tx_sample_rate; + channels->min = channels->max = msm_slim_0_tx_ch; + + return 0; +} + +static int msm_slim_1_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + pr_debug("%s()\n", __func__); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, slim1_tx_bit_format); + rate->min = rate->max = slim1_tx_sample_rate; + channels->min = channels->max = msm_slim_1_tx_ch; + + return 0; +} + +static int msm_slim_4_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + SNDRV_PCM_FORMAT_S32_LE); + + rate->min = rate->max = SAMPLING_RATE_8KHZ; + channels->min = channels->max = msm_vi_feed_tx_ch; + pr_debug("%s: msm_vi_feed_tx_ch: %d\n", __func__, msm_vi_feed_tx_ch); + + return 0; +} + +static int msm_slim_5_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + int rc = 0; + void *config = NULL; + struct snd_soc_codec *codec = rtd->codec; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + pr_debug("%s: enter\n", __func__); + rate->min = rate->max = SAMPLING_RATE_16KHZ; + channels->min = channels->max = 1; + + config = msm8996_codec_fn.get_afe_config_fn(codec, + AFE_SLIMBUS_SLAVE_PORT_CONFIG); + if (config) { + rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, config, + SLIMBUS_5_TX); + if (rc) { + pr_err("%s: Failed to set slimbus slave port config %d\n", + __func__, rc); + } + } + + return rc; +} + +static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + + pr_debug("%s:\n", __func__); + rate->min = rate->max = SAMPLING_RATE_48KHZ; + return 0; +} + +static const struct soc_enum msm_snd_enum[] = { + SOC_ENUM_SINGLE_EXT(2, spk_function), + SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text), + SOC_ENUM_SINGLE_EXT(8, slim0_tx_ch_text), + SOC_ENUM_SINGLE_EXT(7, hdmi_rx_ch_text), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_bit_format_text), + rx_bit_format_text), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim0_rx_sample_rate_text), + slim0_rx_sample_rate_text), + SOC_ENUM_SINGLE_EXT(8, proxy_rx_ch_text), + SOC_ENUM_SINGLE_EXT(3, hdmi_rx_sample_rate_text), + SOC_ENUM_SINGLE_EXT(4, slim5_rx_sample_rate_text), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim5_rx_bit_format_text), + slim5_rx_bit_format_text), + SOC_ENUM_SINGLE_EXT(2, slim5_rx_ch_text), + SOC_ENUM_SINGLE_EXT(2, hifi_function), + SOC_ENUM_SINGLE_EXT(2, vi_feed_ch_text), + SOC_ENUM_SINGLE_EXT(4, slim6_rx_sample_rate_text), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim6_rx_bit_format_text), + slim6_rx_bit_format_text), + SOC_ENUM_SINGLE_EXT(2, slim6_rx_ch_text), +}; + +static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("Speaker Function", msm_snd_enum[0], msm8996_get_spk, + msm8996_set_spk), + SOC_ENUM_EXT("SLIM_0_RX Channels", msm_snd_enum[1], + msm_slim_0_rx_ch_get, msm_slim_0_rx_ch_put), + SOC_ENUM_EXT("SLIM_5_RX Channels", msm_snd_enum[10], + msm_slim_5_rx_ch_get, msm_slim_5_rx_ch_put), + SOC_ENUM_EXT("SLIM_6_RX Channels", msm_snd_enum[15], + msm_slim_6_rx_ch_get, msm_slim_6_rx_ch_put), + SOC_ENUM_EXT("SLIM_0_TX Channels", msm_snd_enum[2], + msm_slim_0_tx_ch_get, msm_slim_0_tx_ch_put), + SOC_ENUM_EXT("SLIM_1_TX Channels", msm_snd_enum[2], + msm_slim_1_tx_ch_get, msm_slim_1_tx_ch_put), + SOC_ENUM_EXT("AUX PCM SampleRate", msm8996_auxpcm_enum[0], + msm8996_auxpcm_rate_get, + msm8996_auxpcm_rate_put), + SOC_ENUM_EXT("HDMI_RX Channels", msm_snd_enum[3], + msm_hdmi_rx_ch_get, msm_hdmi_rx_ch_put), + SOC_ENUM_EXT("SLIM_0_RX Format", msm_snd_enum[4], + slim0_rx_bit_format_get, slim0_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_5_RX Format", msm_snd_enum[9], + slim5_rx_bit_format_get, slim5_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_6_RX Format", msm_snd_enum[14], + slim6_rx_bit_format_get, slim6_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_0_RX SampleRate", msm_snd_enum[5], + slim0_rx_sample_rate_get, slim0_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_5_RX SampleRate", msm_snd_enum[8], + slim5_rx_sample_rate_get, slim5_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_6_RX SampleRate", msm_snd_enum[13], + slim6_rx_sample_rate_get, slim6_rx_sample_rate_put), + SOC_ENUM_EXT("HDMI_RX Bit Format", msm_snd_enum[4], + hdmi_rx_bit_format_get, hdmi_rx_bit_format_put), + SOC_ENUM_EXT("PROXY_RX Channels", msm_snd_enum[6], + msm_proxy_rx_ch_get, msm_proxy_rx_ch_put), + SOC_ENUM_EXT("HDMI_RX SampleRate", msm_snd_enum[7], + hdmi_rx_sample_rate_get, hdmi_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_0_TX SampleRate", msm_snd_enum[5], + slim0_tx_sample_rate_get, slim0_tx_sample_rate_put), + SOC_ENUM_EXT("SLIM_0_TX Format", msm_snd_enum[4], + slim0_tx_bit_format_get, slim0_tx_bit_format_put), + SOC_ENUM_EXT("HiFi Function", msm_snd_enum[11], msm8996_hifi_get, + msm8996_hifi_put), + SOC_ENUM_EXT("VI_FEED_TX Channels", msm_snd_enum[12], + msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), +}; + +static bool msm8996_swap_gnd_mic(struct snd_soc_codec *codec) +{ + struct snd_soc_card *card = codec->component.card; + struct msm8996_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + int value = gpio_get_value_cansleep(pdata->us_euro_gpio); + + pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value); + gpio_set_value_cansleep(pdata->us_euro_gpio, !value); + return true; +} + +static int msm_afe_set_config(struct snd_soc_codec *codec) +{ + int rc; + void *config_data = NULL; + + pr_debug("%s: enter\n", __func__); + + if (!msm8996_codec_fn.get_afe_config_fn) { + dev_err(codec->dev, "%s: codec get afe config not init'ed\n", + __func__); + return -EINVAL; + } + + config_data = msm8996_codec_fn.get_afe_config_fn(codec, + AFE_CDC_REGISTERS_CONFIG); + if (config_data) { + rc = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0); + if (rc) { + pr_err("%s: Failed to set codec registers config %d\n", + __func__, rc); + return rc; + } + } + + config_data = msm8996_codec_fn.get_afe_config_fn(codec, + AFE_CDC_REGISTER_PAGE_CONFIG); + if (config_data) { + rc = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, + 0); + if (rc) + pr_err("%s: Failed to set cdc register page config\n", + __func__); + } + + config_data = msm8996_codec_fn.get_afe_config_fn(codec, + AFE_SLIMBUS_SLAVE_CONFIG); + if (config_data) { + rc = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0); + if (rc) { + pr_err("%s: Failed to set slimbus slave config %d\n", + __func__, rc); + return rc; + } + } + + return 0; +} + +static void msm_afe_clear_config(void) +{ + afe_clear_config(AFE_CDC_REGISTERS_CONFIG); + afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); +} + +static int msm8996_adsp_state_callback(struct notifier_block *nb, + unsigned long value, void *priv) +{ + if (value == SUBSYS_BEFORE_SHUTDOWN) { + pr_debug("%s: ADSP is about to shutdown. Clearing AFE config\n", + __func__); + msm_afe_clear_config(); + } else if (value == SUBSYS_AFTER_POWERUP) { + pr_debug("%s: ADSP is up\n", __func__); + } + + return NOTIFY_OK; +} + +static struct notifier_block adsp_state_notifier_block = { + .notifier_call = msm8996_adsp_state_callback, + .priority = -INT_MAX, +}; + +static int msm8996_wcd93xx_codec_up(struct snd_soc_codec *codec) +{ + int err; + unsigned long timeout; + int adsp_ready = 0; + + timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + + do { + if (!q6core_is_adsp_ready()) { + pr_err_ratelimited("%s: ADSP Audio isn't ready\n", + __func__); + /* + * ADSP will be coming up after subsystem restart and + * it might not be fully up when the control reaches + * here. So, wait for 50msec before checking ADSP state + */ + msleep(50); + } else { + pr_debug("%s: ADSP Audio is ready\n", __func__); + adsp_ready = 1; + break; + } + } while (time_after(timeout, jiffies)); + + if (!adsp_ready) { + pr_err("%s: timed out waiting for ADSP Audio\n", __func__); + return -ETIMEDOUT; + } + + err = msm_afe_set_config(codec); + if (err) + pr_err("%s: Failed to set AFE config. err %d\n", + __func__, err); + return err; +} + +static int msm8996_tasha_codec_event_cb(struct snd_soc_codec *codec, + enum wcd9335_codec_event codec_event) +{ + switch (codec_event) { + case WCD9335_CODEC_EVENT_CODEC_UP: + return msm8996_wcd93xx_codec_up(codec); + default: + pr_err("%s: UnSupported codec event %d\n", + __func__, codec_event); + return -EINVAL; + } +} + +static int msm8996_config_hph_en0_gpio(struct snd_soc_codec *codec, bool high) +{ + struct snd_soc_card *card = codec->component.card; + struct msm8996_asoc_mach_data *pdata; + int val; + + if (!card) + return 0; + + pdata = snd_soc_card_get_drvdata(card); + if (!pdata || !gpio_is_valid(pdata->hph_en0_gpio)) + return 0; + + val = gpio_get_value_cansleep(pdata->hph_en0_gpio); + if ((!!val) == high) + return 0; + + gpio_direction_output(pdata->hph_en0_gpio, (int)high); + + return 1; +} + +static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) +{ + int err; + void *config_data; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_component *aux_comp; + void *mbhc_calibration; + struct snd_card *card; + struct snd_info_entry *entry; + struct msm8996_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); + + /* Codec SLIMBUS configuration + * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13 + * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 + * TX14, TX15, TX16 + */ + unsigned int rx_ch[TASHA_RX_MAX] = {144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156}; + unsigned int tx_ch[TASHA_TX_MAX] = {128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143}; + + pr_info("%s: dev_name%s\n", __func__, dev_name(cpu_dai->dev)); + + rtd->pmdown_time = 0; + + err = snd_soc_add_codec_controls(codec, msm_snd_controls, + ARRAY_SIZE(msm_snd_controls)); + if (err < 0) { + pr_err("%s: add_codec_controls failed, err %d\n", + __func__, err); + return err; + } + + err = msm8996_liquid_init_docking(); + if (err) { + pr_err("%s: 8996 init Docking stat IRQ failed (%d)\n", + __func__, err); + return err; + } + + err = msm8996_ext_us_amp_init(); + if (err) { + pr_err("%s: 8996 US Emitter GPIO init failed (%d)\n", + __func__, err); + return err; + } + + snd_soc_dapm_new_controls(dapm, msm8996_dapm_widgets, + ARRAY_SIZE(msm8996_dapm_widgets)); + + snd_soc_dapm_add_routes(dapm, wcd9335_audio_paths, + ARRAY_SIZE(wcd9335_audio_paths)); + snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp"); + snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp"); + snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp"); + snd_soc_dapm_enable_pin(dapm, "Lineout_4 amp"); + + snd_soc_dapm_ignore_suspend(dapm, "Lineout_1 amp"); + snd_soc_dapm_ignore_suspend(dapm, "Lineout_3 amp"); + snd_soc_dapm_ignore_suspend(dapm, "Lineout_2 amp"); + snd_soc_dapm_ignore_suspend(dapm, "Lineout_4 amp"); + snd_soc_dapm_ignore_suspend(dapm, "ultrasound amp"); + snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic7"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic8"); + snd_soc_dapm_ignore_suspend(dapm, "MADINPUT"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT"); + snd_soc_dapm_ignore_suspend(dapm, "EAR"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4"); + snd_soc_dapm_ignore_suspend(dapm, "ANC EAR"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC4"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC5"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC6"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC4"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC5"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC0"); + snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT1"); + snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT2"); + snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); + snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); + + snd_soc_dapm_sync(dapm); + + snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); + + msm8996_codec_fn.get_afe_config_fn = tasha_get_afe_config; + msm8996_codec_fn.mbhc_hs_detect_exit = tasha_mbhc_hs_detect_exit; + + err = msm_afe_set_config(codec); + if (err) { + pr_err("%s: Failed to set AFE config %d\n", __func__, err); + goto out; + } + + config_data = msm8996_codec_fn.get_afe_config_fn(codec, + AFE_AANC_VERSION); + if (config_data) { + err = afe_set_config(AFE_AANC_VERSION, config_data, 0); + if (err) { + pr_err("%s: Failed to set aanc version %d\n", + __func__, err); + goto out; + } + } + config_data = msm8996_codec_fn.get_afe_config_fn(codec, + AFE_CDC_CLIP_REGISTERS_CONFIG); + if (config_data) { + err = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG, + config_data, 0); + if (err) { + pr_err("%s: Failed to set clip registers %d\n", + __func__, err); + goto out; + } + } + config_data = msm8996_codec_fn.get_afe_config_fn(codec, + AFE_CLIP_BANK_SEL); + if (config_data) { + err = afe_set_config(AFE_CLIP_BANK_SEL, config_data, 0); + if (err) { + pr_err("%s: Failed to set AFE bank selection %d\n", + __func__, err); + goto out; + } + } + /* Start mbhc */ + tasha_mbhc_zdet_gpio_ctrl(msm8996_config_hph_en0_gpio, rtd->codec); + mbhc_calibration = def_tasha_mbhc_cal(); + if (mbhc_calibration) { + wcd_mbhc_cfg.calibration = mbhc_calibration; + err = tasha_mbhc_hs_detect(codec, &wcd_mbhc_cfg); + if (err) { + pr_err("%s: mbhc hs detect failed, err:%d\n", + __func__, err); + goto out; + } + } else { + pr_err("%s: mbhc_cfg calibration is NULL\n", __func__); + err = -ENOMEM; + goto out; + } + adsp_state_notifier = subsys_notif_register_notifier("adsp", + &adsp_state_notifier_block); + if (!adsp_state_notifier) { + pr_err("%s: Failed to register adsp state notifier\n", + __func__); + err = -EFAULT; + msm8996_codec_fn.mbhc_hs_detect_exit(codec); + goto out; + } + + tasha_event_register(msm8996_tasha_codec_event_cb, rtd->codec); + + /* + * Send speaker configuration only for WSA8810. + * Defalut configuration is for WSA8815. + */ + if (!list_empty(&rtd->card->aux_comp_list)) { + aux_comp = list_first_entry(&rtd->card->aux_comp_list, + struct snd_soc_component, list_aux); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { + tasha_set_spkr_mode(rtd->codec, SPKR_MODE_1); + tasha_set_spkr_gain_offset(rtd->codec, + RX_GAIN_OFFSET_M1P5_DB); + } + } + codec_reg_done = true; + + card = rtd->card->snd_card; + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + err = 0; + goto out; + } + pdata->codec_root = entry; + tasha_codec_info_create_codec_entry(pdata->codec_root, codec); + + return 0; +out: + return err; +} + +static void *def_tasha_mbhc_cal(void) +{ + void *tasha_wcd_cal; + struct wcd_mbhc_btn_detect_cfg *btn_cfg; + u16 *btn_high; + + tasha_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, + WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); + if (!tasha_wcd_cal) + return NULL; + +#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(tasha_wcd_cal)->X) = (Y)) + S(v_hs_max, 1500); +#undef S +#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(tasha_wcd_cal)->X) = (Y)) + S(num_btn, WCD_MBHC_DEF_BUTTONS); +#undef S + + btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(tasha_wcd_cal); + btn_high = ((void *)&btn_cfg->_v_btn_low) + + (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); + + btn_high[0] = 75; + btn_high[1] = 150; + btn_high[2] = 237; + btn_high[3] = 500; + btn_high[4] = 500; + btn_high[5] = 500; + btn_high[6] = 500; + btn_high[7] = 500; + + return tasha_wcd_cal; +} + +static int msm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + int ret = 0; + u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + u32 user_set_tx_ch = 0; + u32 rx_ch_count; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto end; + } + if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_5_RX) { + pr_debug("%s: rx_5_ch=%d\n", __func__, + msm_slim_5_rx_ch); + rx_ch_count = msm_slim_5_rx_ch; + } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_6_RX) { + pr_debug("%s: rx_6_ch=%d\n", __func__, + msm_slim_6_rx_ch); + rx_ch_count = msm_slim_6_rx_ch; + } else { + pr_debug("%s: rx_0_ch=%d\n", __func__, + msm_slim_0_rx_ch); + rx_ch_count = msm_slim_0_rx_ch; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + rx_ch_count, rx_ch); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto end; + } + } else { + + pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__, + codec_dai->name, codec_dai->id, user_set_tx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map\n, err:%d\n", + __func__, ret); + goto end; + } + /* For _tx1 case */ + if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_0_TX) + user_set_tx_ch = msm_slim_0_tx_ch; + /* For _tx3 case */ + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_1_TX) + user_set_tx_ch = msm_slim_1_tx_ch; + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_3_TX) + /* DAI 5 is used for external EC reference from codec. + * Since Rx is fed as reference for EC, the config of + * this DAI is based on that of the Rx path. + */ + user_set_tx_ch = msm_slim_0_rx_ch; + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_4_TX) + user_set_tx_ch = msm_vi_feed_tx_ch; + else + user_set_tx_ch = tx_ch_cnt; + + pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), BE id (%d)\n", + __func__, msm_slim_0_tx_ch, user_set_tx_ch, + tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + user_set_tx_ch, tx_ch, 0, 0); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto end; + } + } +end: + return ret; +} + +static int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + int ret = 0; + u32 tx_ch[SLIM_MAX_TX_PORTS]; + u32 tx_ch_cnt = 0; + u32 user_set_tx_ch = 0; + + if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) { + pr_err("%s: Invalid stream type %d\n", + __func__, substream->stream); + ret = -EINVAL; + goto end; + } + + pr_debug("%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, NULL, NULL); + if (ret < 0) { + pr_err("%s: failed to get codec chan map\n, err:%d\n", + __func__, ret); + goto end; + } + + user_set_tx_ch = tx_ch_cnt; + + pr_debug("%s: tx_ch_cnt(%d) BE id %d\n", + __func__, tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + user_set_tx_ch, tx_ch, 0, 0); + if (ret < 0) + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); +end: + return ret; +} + +static struct snd_soc_ops msm8996_be_ops = { + .hw_params = msm_snd_hw_params, +}; + +static struct snd_soc_ops msm8996_cpe_ops = { + .hw_params = msm_snd_cpe_hw_params, +}; + +static int msm8996_slimbus_2_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; + unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0; + unsigned int num_tx_ch = 0; + unsigned int num_rx_ch = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + num_rx_ch = params_channels(params); + pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__, + codec_dai->name, codec_dai->id, num_rx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto end; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + num_rx_ch, rx_ch); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto end; + } + } else { + num_tx_ch = params_channels(params); + pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__, + codec_dai->name, codec_dai->id, num_tx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto end; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, + num_tx_ch, tx_ch, 0, 0); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto end; + } + } +end: + return ret; +} + +static struct snd_soc_ops msm8996_slimbus_2_be_ops = { + .hw_params = msm8996_slimbus_2_hw_params, +}; + +static int msm8996_get_ll_qos_val(struct snd_pcm_runtime *runtime) +{ + int usecs; + + /* take 10% of period time as the deadline */ + usecs = (100000 / runtime->rate) * runtime->period_size; + usecs += ((100000 % runtime->rate) * runtime->period_size) / + runtime->rate; + + return usecs; +} + +static int msm8996_mm5_prepare(struct snd_pcm_substream *substream) +{ + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + msm8996_get_ll_qos_val(substream->runtime)); + return 0; +} + +static struct snd_soc_ops msm8996_mm5_ops = { + .prepare = msm8996_mm5_prepare, +}; + +/* Digital audio interface glue - connects codec <---> CPU */ +static struct snd_soc_dai_link msm8996_common_dai_links[] = { + /* FrontEnd DAI Links */ + { + .name = "MSM8996 Media1", + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, + { + .name = "MSM8996 Media2", + .stream_name = "MultiMedia2", + .cpu_dai_name = "MultiMedia2", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, + }, + { + .name = "VoiceMMode1", + .stream_name = "VoiceMMode1", + .cpu_dai_name = "VoiceMMode1", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE1, + }, + { + .name = "MSM VoIP", + .stream_name = "VoIP", + .cpu_dai_name = "VoIP", + .platform_name = "msm-voip-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_VOIP, + }, + { + .name = "MSM8996 ULL", + .stream_name = "MultiMedia3", + .cpu_dai_name = "MultiMedia3", + .platform_name = "msm-pcm-dsp.2", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA3, + }, + /* Hostless PCM purpose */ + { + .name = "SLIMBUS_0 Hostless", + .stream_name = "SLIMBUS_0 Hostless", + .cpu_dai_name = "SLIMBUS0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Tertiary MI2S TX_Hostless", + .stream_name = "Tertiary MI2S_TX Hostless Capture", + .cpu_dai_name = "TERT_MI2S_TX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "MSM AFE-PCM RX", + .stream_name = "AFE-PROXY RX", + .cpu_dai_name = "msm-dai-q6-dev.241", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .platform_name = "msm-pcm-afe", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + }, + { + .name = "MSM AFE-PCM TX", + .stream_name = "AFE-PROXY TX", + .cpu_dai_name = "msm-dai-q6-dev.240", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .platform_name = "msm-pcm-afe", + .ignore_suspend = 1, + }, + { + .name = "MSM8996 Compress1", + .stream_name = "Compress1", + .cpu_dai_name = "MultiMedia4", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA4, + }, + { + .name = "AUXPCM Hostless", + .stream_name = "AUXPCM Hostless", + .cpu_dai_name = "AUXPCM_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_1 Hostless", + .stream_name = "SLIMBUS_1 Hostless", + .cpu_dai_name = "SLIMBUS1_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_3 Hostless", + .stream_name = "SLIMBUS_3 Hostless", + .cpu_dai_name = "SLIMBUS3_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_4 Hostless", + .stream_name = "SLIMBUS_4 Hostless", + .cpu_dai_name = "SLIMBUS4_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "VoLTE", + .stream_name = "VoLTE", + .cpu_dai_name = "VoLTE", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOLTE, + }, + { + .name = "MSM8996 LowLatency", + .stream_name = "MultiMedia5", + .cpu_dai_name = "MultiMedia5", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .ops = &msm8996_mm5_ops, + }, + { + .name = "Listen 1 Audio Service", + .stream_name = "Listen 1 Audio Service", + .cpu_dai_name = "LSM1", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM1, + }, + /* Multiple Tunnel instances */ + { + .name = "MSM8996 Compress2", + .stream_name = "Compress2", + .cpu_dai_name = "MultiMedia7", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA7, + }, + { + .name = "MSM8996 Compress3", + .stream_name = "Compress3", + .cpu_dai_name = "MultiMedia10", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA10, + }, + { + .name = "MSM8996 ULL NOIRQ", + .stream_name = "MM_NOIRQ", + .cpu_dai_name = "MultiMedia8", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + }, + { + .name = "QCHAT", + .stream_name = "QCHAT", + .cpu_dai_name = "QCHAT", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_QCHAT, + }, + /* HDMI Hostless */ + { + .name = "HDMI_RX_HOSTLESS", + .stream_name = "HDMI_RX_HOSTLESS", + .cpu_dai_name = "HDMI_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "VoiceMMode2", + .stream_name = "VoiceMMode2", + .cpu_dai_name = "VoiceMMode2", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE2, + }, + { + .name = "INT_HFP_BT Hostless", + .stream_name = "INT_HFP_BT Hostless", + .cpu_dai_name = "INT_HFP_BT_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "MSM8996 HFP TX", + .stream_name = "MultiMedia6", + .cpu_dai_name = "MultiMedia6", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA6, + }, + /* LSM FE */ + { + .name = "Listen 2 Audio Service", + .stream_name = "Listen 2 Audio Service", + .cpu_dai_name = "LSM2", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM2, + }, + { + .name = "Listen 3 Audio Service", + .stream_name = "Listen 3 Audio Service", + .cpu_dai_name = "LSM3", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM3, + }, + { + .name = "Listen 4 Audio Service", + .stream_name = "Listen 4 Audio Service", + .cpu_dai_name = "LSM4", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM4, + }, + { + .name = "Listen 5 Audio Service", + .stream_name = "Listen 5 Audio Service", + .cpu_dai_name = "LSM5", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM5, + }, + { + .name = "Listen 6 Audio Service", + .stream_name = "Listen 6 Audio Service", + .cpu_dai_name = "LSM6", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM6, + }, + { + .name = "Listen 7 Audio Service", + .stream_name = "Listen 7 Audio Service", + .cpu_dai_name = "LSM7", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM7, + }, + { + .name = "Listen 8 Audio Service", + .stream_name = "Listen 8 Audio Service", + .cpu_dai_name = "LSM8", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM8, + }, + { + .name = "MSM8996 Media9", + .stream_name = "MultiMedia9", + .cpu_dai_name = "MultiMedia9", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA9, + }, + { + .name = "VoWLAN", + .stream_name = "VoWLAN", + .cpu_dai_name = "VoWLAN", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOWLAN, + }, + { + .name = "MSM8996 Compress4", + .stream_name = "Compress4", + .cpu_dai_name = "MultiMedia11", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA11, + }, + { + .name = "MSM8996 Compress5", + .stream_name = "Compress5", + .cpu_dai_name = "MultiMedia12", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA12, + }, + { + .name = "MSM8996 Compress6", + .stream_name = "Compress6", + .cpu_dai_name = "MultiMedia13", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA13, + }, + { + .name = "MSM8996 Compress7", + .stream_name = "Compress7", + .cpu_dai_name = "MultiMedia14", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA14, + }, + { + .name = "MSM8996 Compress8", + .stream_name = "Compress8", + .cpu_dai_name = "MultiMedia15", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA15, + }, + { + .name = "MSM8996 Compress9", + .stream_name = "Compress9", + .cpu_dai_name = "MultiMedia16", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA16, + }, + { + .name = "Circuit-Switch Voice", + .stream_name = "CS-Voice", + .cpu_dai_name = "CS-VOICE", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_CS_VOICE, + }, + { + .name = "Voice2", + .stream_name = "Voice2", + .cpu_dai_name = "Voice2", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICE2, + }, +}; + +static struct snd_soc_dai_link msm8996_tasha_fe_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_4_TX, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_vifeedback", + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_slim_4_tx_be_hw_params_fixup, + .ops = &msm8996_be_ops, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + }, + /* Ultrasound RX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Playback", + .stream_name = "SLIMBUS_2 Hostless Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx2", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm8996_slimbus_2_be_ops, + }, + /* Ultrasound TX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Capture", + .stream_name = "SLIMBUS_2 Hostless Capture", + .cpu_dai_name = "msm-dai-q6-dev.16389", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx2", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm8996_slimbus_2_be_ops, + }, + /* CPE LSM direct dai-link */ + { + .name = "CPE Listen service", + .stream_name = "CPE Listen Audio Service", + .cpu_dai_name = "msm-dai-slim", + .platform_name = "msm-cpe-lsm", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "tasha_mad1", + .codec_name = "tasha_codec", + .ops = &msm8996_cpe_ops, + }, + /* slimbus rx 6 hostless */ + { + .name = "SLIMBUS_6 Hostless Playback", + .stream_name = "SLIMBUS_6 Hostless", + .cpu_dai_name = "SLIMBUS6_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + /* CPE LSM EC PP direct dai-link */ + { + .name = "CPE Listen service ECPP", + .stream_name = "CPE Listen Audio Service ECPP", + .cpu_dai_name = "CPE_LSM_NOHOST", + .platform_name = "msm-cpe-lsm.3", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "tasha_cpe", + .codec_name = "tasha_codec", + }, +}; + +static struct snd_soc_dai_link msm8996_common_be_dai_links[] = { + /* Backend AFE DAI Links */ + { + .name = LPASS_BE_AFE_PCM_RX, + .stream_name = "AFE Playback", + .cpu_dai_name = "msm-dai-q6-dev.224", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_RX, + .be_hw_params_fixup = msm_proxy_rx_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AFE_PCM_TX, + .stream_name = "AFE Capture", + .cpu_dai_name = "msm-dai-q6-dev.225", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_TX, + .be_hw_params_fixup = msm_proxy_tx_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Primary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_AUXPCM_RX, + .stream_name = "AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AUXPCM_RX, + .be_hw_params_fixup = msm_auxpcm_be_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + /* this dainlink has playback support */ + }, + { + .name = LPASS_BE_AUXPCM_TX, + .stream_name = "AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AUXPCM_TX, + .be_hw_params_fixup = msm_auxpcm_be_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Uplink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_TX, + .stream_name = "Voice Uplink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32772", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Downlink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_RX, + .stream_name = "Voice Downlink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32771", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music BACK END DAI Link */ + { + .name = LPASS_BE_VOICE_PLAYBACK_TX, + .stream_name = "Voice Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32773", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music 2 BACK END DAI Link */ + { + .name = LPASS_BE_VOICE2_PLAYBACK_TX, + .stream_name = "Voice2 Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32770", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX, + .stream_name = "Tertiary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + .be_hw_params_fixup = msm_tx_be_hw_params_fixup, + .ops = &msm8996_mi2s_be_ops, + .ignore_suspend = 1, + } +}; + +static struct snd_soc_dai_link msm8996_tasha_be_dai_links[] = { + /* Backend DAI Links */ + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_init, + .be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm8996_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm8996_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_1_RX, + .stream_name = "Slimbus1 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16386", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, + .be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup, + .ops = &msm8996_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_1_TX, + .stream_name = "Slimbus1 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16387", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx3", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, + .be_hw_params_fixup = msm_slim_1_tx_be_hw_params_fixup, + .ops = &msm8996_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_RX, + .stream_name = "Slimbus3 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16390", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, + .be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup, + .ops = &msm8996_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_TX, + .stream_name = "Slimbus3 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16391", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, + .be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup, + .ops = &msm8996_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_4_RX, + .stream_name = "Slimbus4 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16392", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, + .be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup, + .ops = &msm8996_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_5_RX, + .stream_name = "Slimbus5 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16394", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx3", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, + .be_hw_params_fixup = msm_slim_5_rx_be_hw_params_fixup, + .ops = &msm8996_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* MAD BE */ + { + .name = LPASS_BE_SLIMBUS_5_TX, + .stream_name = "Slimbus5 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16395", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mad1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, + .be_hw_params_fixup = msm_slim_5_tx_be_hw_params_fixup, + .ops = &msm8996_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_6_RX, + .stream_name = "Slimbus6 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16396", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx4", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, + .be_hw_params_fixup = msm_slim_6_rx_be_hw_params_fixup, + .ops = &msm8996_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm8996_hdmi_dai_link[] = { + /* HDMI BACK END DAI Link */ + { + .name = LPASS_BE_HDMI, + .stream_name = "HDMI Playback", + .cpu_dai_name = "msm-dai-q6-hdmi.8", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-hdmi-audio-codec-rx", + .codec_dai_name = "msm_hdmi_audio_codec_rx_dai", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_HDMI_RX, + .be_hw_params_fixup = msm8996_hdmi_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm8996_tasha_dai_links[ + ARRAY_SIZE(msm8996_common_dai_links) + + ARRAY_SIZE(msm8996_tasha_fe_dai_links) + + ARRAY_SIZE(msm8996_common_be_dai_links) + + ARRAY_SIZE(msm8996_tasha_be_dai_links) + + ARRAY_SIZE(msm8996_hdmi_dai_link)]; + +static int msm8996_wsa881x_init(struct snd_soc_component *component) +{ + u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106}; + u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107}; + unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; + unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + struct msm8996_asoc_mach_data *pdata; + struct snd_soc_dapm_context *dapm; + + if (!codec) { + pr_err("%s codec is NULL\n", __func__); + return -EINVAL; + } + + dapm = snd_soc_codec_get_dapm(codec); + + if (!strcmp(component->name_prefix, "SpkrLeft")) { + dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n", + __func__, codec->component.name); + wsa881x_set_channel_map(codec, &spkleft_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0]); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); + } + } else if (!strcmp(component->name_prefix, "SpkrRight")) { + dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n", + __func__, codec->component.name); + wsa881x_set_channel_map(codec, &spkright_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0]); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); + } + } else { + dev_err(codec->dev, "%s: wrong codec name %s\n", __func__, + codec->component.name); + return -EINVAL; + } + pdata = snd_soc_card_get_drvdata(component->card); + if (pdata && pdata->codec_root) + wsa881x_codec_info_create_codec_entry(pdata->codec_root, + codec); + + return 0; +} + +struct snd_soc_card snd_soc_card_tasha_msm8996 = { + .name = "msm8996-tasha-snd-card", +}; + +static int msm8996_populate_dai_link_component_of_node( + struct snd_soc_card *card) +{ + int i, index, ret = 0; + struct device *cdev = card->dev; + struct snd_soc_dai_link *dai_link = card->dai_link; + struct device_node *np; + + if (!cdev) { + pr_err("%s: Sound card device memory NULL\n", __func__); + return -ENODEV; + } + + for (i = 0; i < card->num_links; i++) { + if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) + continue; + + /* populate platform_of_node for snd card dai links */ + if (dai_link[i].platform_name && + !dai_link[i].platform_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-platform-names", + dai_link[i].platform_name); + if (index < 0) { + pr_err("%s: No match found for platform name: %s\n", + __func__, dai_link[i].platform_name); + ret = index; + goto err; + } + np = of_parse_phandle(cdev->of_node, "asoc-platform", + index); + if (!np) { + pr_err("%s: retrieving phandle for platform %s, index %d failed\n", + __func__, dai_link[i].platform_name, + index); + ret = -ENODEV; + goto err; + } + dai_link[i].platform_of_node = np; + dai_link[i].platform_name = NULL; + } + + /* populate cpu_of_node for snd card dai links */ + if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-cpu-names", + dai_link[i].cpu_dai_name); + if (index >= 0) { + np = of_parse_phandle(cdev->of_node, "asoc-cpu", + index); + if (!np) { + pr_err("%s: retrieving phandle for cpu dai %s failed\n", + __func__, + dai_link[i].cpu_dai_name); + ret = -ENODEV; + goto err; + } + dai_link[i].cpu_of_node = np; + dai_link[i].cpu_dai_name = NULL; + } + } + + /* populate codec_of_node for snd card dai links */ + if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-codec-names", + dai_link[i].codec_name); + if (index < 0) + continue; + np = of_parse_phandle(cdev->of_node, "asoc-codec", + index); + if (!np) { + pr_err("%s: retrieving phandle for codec %s failed\n", + __func__, dai_link[i].codec_name); + ret = -ENODEV; + goto err; + } + dai_link[i].codec_of_node = np; + dai_link[i].codec_name = NULL; + } + } + +err: + return ret; +} + +static int msm8996_prepare_us_euro(struct snd_soc_card *card) +{ + struct msm8996_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + int ret; + + if (pdata->us_euro_gpio >= 0) { + dev_dbg(card->dev, "%s: us_euro gpio request %d", __func__, + pdata->us_euro_gpio); + ret = gpio_request(pdata->us_euro_gpio, "TASHA_CODEC_US_EURO"); + if (ret) { + dev_err(card->dev, + "%s: Failed to request codec US/EURO gpio %d error %d\n", + __func__, pdata->us_euro_gpio, ret); + return ret; + } + } + + return 0; +} + +static int msm8996_prepare_hifi(struct snd_soc_card *card) +{ + struct msm8996_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + int ret; + + if (gpio_is_valid(pdata->hph_en1_gpio)) { + dev_dbg(card->dev, "%s: hph_en1_gpio request %d\n", __func__, + pdata->hph_en1_gpio); + ret = gpio_request(pdata->hph_en1_gpio, "hph_en1_gpio"); + if (ret) { + dev_err(card->dev, + "%s: hph_en1_gpio request failed, ret:%d\n", + __func__, ret); + return ret; + } + } + if (gpio_is_valid(pdata->hph_en0_gpio)) { + dev_dbg(card->dev, "%s: hph_en0_gpio request %d\n", __func__, + pdata->hph_en0_gpio); + ret = gpio_request(pdata->hph_en0_gpio, "hph_en0_gpio"); + if (ret) { + dev_err(card->dev, + "%s: hph_en0_gpio request failed, ret:%d\n", + __func__, ret); + return ret; + } + } + return 0; +} + +static const struct of_device_id msm8996_asoc_machine_of_match[] = { + { .compatible = "qcom,msm8996-asoc-snd-tasha", + .data = "tasha_codec"}, + {}, +}; + +static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) +{ + struct snd_soc_card *card = NULL; + struct snd_soc_dai_link *dailink; + int len_1, len_2, len_3, len_4; + const struct of_device_id *match; + + match = of_match_node(msm8996_asoc_machine_of_match, dev->of_node); + if (!match) { + dev_err(dev, "%s: No DT match found for sound card\n", + __func__); + return NULL; + } + + if (!strcmp(match->data, "tasha_codec")) { + card = &snd_soc_card_tasha_msm8996; + len_1 = ARRAY_SIZE(msm8996_common_dai_links); + len_2 = len_1 + ARRAY_SIZE(msm8996_tasha_fe_dai_links); + len_3 = len_2 + ARRAY_SIZE(msm8996_common_be_dai_links); + + memcpy(msm8996_tasha_dai_links, + msm8996_common_dai_links, + sizeof(msm8996_common_dai_links)); + memcpy(msm8996_tasha_dai_links + len_1, + msm8996_tasha_fe_dai_links, + sizeof(msm8996_tasha_fe_dai_links)); + memcpy(msm8996_tasha_dai_links + len_2, + msm8996_common_be_dai_links, + sizeof(msm8996_common_be_dai_links)); + memcpy(msm8996_tasha_dai_links + len_3, + msm8996_tasha_be_dai_links, + sizeof(msm8996_tasha_be_dai_links)); + + dailink = msm8996_tasha_dai_links; + len_4 = len_3 + ARRAY_SIZE(msm8996_tasha_be_dai_links); + } + + if (of_property_read_bool(dev->of_node, "qcom,hdmi-audio-rx")) { + dev_dbg(dev, "%s(): hdmi audio support present\n", + __func__); + memcpy(dailink + len_4, msm8996_hdmi_dai_link, + sizeof(msm8996_hdmi_dai_link)); + len_4 += ARRAY_SIZE(msm8996_hdmi_dai_link); + } else { + dev_dbg(dev, "%s(): No hdmi audio support\n", __func__); + } + + if (card) { + card->dai_link = dailink; + card->num_links = len_4; + } + + return card; +} + +static int msm8996_init_wsa_dev(struct platform_device *pdev, + struct snd_soc_card *card) +{ + struct device_node *wsa_of_node; + u32 wsa_max_devs; + u32 wsa_dev_cnt; + char *dev_name_str = NULL; + struct msm8996_wsa881x_dev_info *wsa881x_dev_info; + const char *wsa_auxdev_name_prefix[1]; + int found = 0; + int i; + int ret; + + /* Get maximum WSA device count for this platform */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,wsa-max-devs", &wsa_max_devs); + if (ret) { + dev_dbg(&pdev->dev, + "%s: wsa-max-devs property missing in DT %s, ret = %d\n", + __func__, pdev->dev.of_node->full_name, ret); + return 0; + } + if (wsa_max_devs == 0) { + dev_warn(&pdev->dev, + "%s: Max WSA devices is 0 for this target?\n", + __func__); + return 0; + } + + /* Get count of WSA device phandles for this platform */ + wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node, + "qcom,wsa-devs", NULL); + if (wsa_dev_cnt == -ENOENT) { + dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n", + __func__); + return 0; + } else if (wsa_dev_cnt <= 0) { + dev_err(&pdev->dev, + "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n", + __func__, wsa_dev_cnt); + return -EINVAL; + } + + /* + * Expect total phandles count to be NOT less than maximum possible + * WSA count. However, if it is less, then assign same value to + * max count as well. + */ + if (wsa_dev_cnt < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n", + __func__, wsa_max_devs, wsa_dev_cnt); + wsa_max_devs = wsa_dev_cnt; + } + + /* Make sure prefix string passed for each WSA device */ + ret = of_property_count_strings(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix"); + if (ret != wsa_dev_cnt) { + dev_err(&pdev->dev, + "%s: expecting %d wsa prefix. Defined only %d in DT\n", + __func__, wsa_dev_cnt, ret); + return -EINVAL; + } + + /* + * Alloc mem to store phandle and index info of WSA device, if already + * registered with ALSA core + */ + wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs, + sizeof(struct msm8996_wsa881x_dev_info), + GFP_KERNEL); + if (!wsa881x_dev_info) + return -ENOMEM; + + /* + * search and check whether all WSA devices are already + * registered with ALSA core or not. If found a node, store + * the node and the index in a local array of struct for later + * use. + */ + for (i = 0; i < wsa_dev_cnt; i++) { + wsa_of_node = of_parse_phandle(pdev->dev.of_node, + "qcom,wsa-devs", i); + if (unlikely(!wsa_of_node)) { + /* we should not be here */ + dev_err(&pdev->dev, + "%s: wsa dev node is not present\n", + __func__); + return -EINVAL; + } + if (soc_find_component(wsa_of_node, NULL)) { + /* WSA device registered with ALSA core */ + wsa881x_dev_info[found].of_node = wsa_of_node; + wsa881x_dev_info[found].index = i; + found++; + if (found == wsa_max_devs) + break; + } + } + + if (found < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: failed to find %d components. Found only %d\n", + __func__, wsa_max_devs, found); + return -EPROBE_DEFER; + } + dev_info(&pdev->dev, + "%s: found %d wsa881x devices registered with ALSA core\n", + __func__, found); + + card->num_aux_devs = wsa_max_devs; + card->num_configs = wsa_max_devs; + + /* Alloc array of AUX devs struct */ + msm8996_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_aux_dev), + GFP_KERNEL); + if (!msm8996_aux_dev) + return -ENOMEM; + + /* Alloc array of codec conf struct */ + msm8996_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_codec_conf), + GFP_KERNEL); + if (!msm8996_codec_conf) + return -ENOMEM; + + for (i = 0; i < card->num_aux_devs; i++) { + dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN, + GFP_KERNEL); + if (!dev_name_str) + return -ENOMEM; + + ret = of_property_read_string_index(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix", + wsa881x_dev_info[i].index, + wsa_auxdev_name_prefix); + if (ret) { + dev_err(&pdev->dev, + "%s: failed to read wsa aux dev prefix, ret = %d\n", + __func__, ret); + return -EINVAL; + } + + snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i); + msm8996_aux_dev[i].name = dev_name_str; + msm8996_aux_dev[i].codec_name = NULL; + msm8996_aux_dev[i].codec_of_node = + wsa881x_dev_info[i].of_node; + msm8996_aux_dev[i].init = msm8996_wsa881x_init; + msm8996_codec_conf[i].dev_name = NULL; + msm8996_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0]; + msm8996_codec_conf[i].of_node = + wsa881x_dev_info[i].of_node; + } + card->codec_conf = msm8996_codec_conf; + card->aux_dev = msm8996_aux_dev; + + return 0; +} + +static int msm8996_asoc_machine_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card; + struct msm8996_asoc_mach_data *pdata; + const char *mbhc_audio_jack_type = NULL; + char *mclk_freq_prop_name; + const struct of_device_id *match; + int ret; + + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, "No platform supplied from device tree\n"); + return -EINVAL; + } + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct msm8996_asoc_mach_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + card = populate_snd_card_dailinks(&pdev->dev); + if (!card) { + dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); + ret = -EINVAL; + goto err; + } + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, pdata); + + ret = snd_soc_of_parse_card_name(card, "qcom,model"); + if (ret) { + dev_err(&pdev->dev, "parse card name failed, err:%d\n", + ret); + goto err; + } + + ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing"); + if (ret) { + dev_err(&pdev->dev, "parse audio routing failed, err:%d\n", + ret); + goto err; + } + + match = of_match_node(msm8996_asoc_machine_of_match, + pdev->dev.of_node); + if (!match) { + dev_err(&pdev->dev, "%s: no matched codec is found.\n", + __func__); + goto err; + } + + mclk_freq_prop_name = "qcom,tasha-mclk-clk-freq"; + + ret = of_property_read_u32(pdev->dev.of_node, + mclk_freq_prop_name, &pdata->mclk_freq); + if (ret) { + dev_err(&pdev->dev, + "Looking up %s property in node %s failed, err%d\n", + mclk_freq_prop_name, + pdev->dev.of_node->full_name, ret); + goto err; + } + + if (pdata->mclk_freq != CODEC_EXT_CLK_RATE) { + dev_err(&pdev->dev, "unsupported mclk freq %u\n", + pdata->mclk_freq); + ret = -EINVAL; + goto err; + } + + spdev = pdev; + + ret = msm8996_populate_dai_link_component_of_node(card); + if (ret) { + ret = -EPROBE_DEFER; + goto err; + } + + ret = msm8996_init_wsa_dev(pdev, card); + if (ret) + goto err; + + pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,hph-en1-gpio", 0); + if (pdata->hph_en1_gpio < 0) { + dev_dbg(&pdev->dev, "%s: %s property not found %d\n", + __func__, "qcom,hph-en1-gpio", pdata->hph_en1_gpio); + } + + pdata->hph_en0_gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,hph-en0-gpio", 0); + if (pdata->hph_en0_gpio < 0) { + dev_dbg(&pdev->dev, "%s: %s property not found %d\n", + __func__, "qcom,hph-en0-gpio", pdata->hph_en0_gpio); + } + ret = msm8996_prepare_hifi(card); + if (ret) + dev_dbg(&pdev->dev, "msm8996_prepare_hifi failed (%d)\n", + ret); + + ret = snd_soc_register_card(card); + if (ret == -EPROBE_DEFER) { + if (codec_reg_done) + ret = -EINVAL; + goto err; + } else if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); + goto err; + } + dev_info(&pdev->dev, "Sound card %s registered\n", card->name); + + ret = of_property_read_string(pdev->dev.of_node, + "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type); + if (ret) { + dev_dbg(&pdev->dev, "Looking up %s property in node %s failed", + "qcom,mbhc-audio-jack-type", + pdev->dev.of_node->full_name); + dev_dbg(&pdev->dev, "Jack type properties set to default"); + } else { + if (!strcmp(mbhc_audio_jack_type, "4-pole-jack")) + dev_dbg(&pdev->dev, "This hardware has 4 pole jack"); + else if (!strcmp(mbhc_audio_jack_type, "5-pole-jack")) + dev_dbg(&pdev->dev, "This hardware has 5 pole jack"); + else if (!strcmp(mbhc_audio_jack_type, "6-pole-jack")) + dev_dbg(&pdev->dev, "This hardware has 6 pole jack"); + else + dev_dbg(&pdev->dev, "Unknown value, set to default"); + } + /* + * Parse US-Euro gpio info from DT. Report no error if us-euro + * entry is not found in DT file as some targets do not support + * US-Euro detection + */ + pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,us-euro-gpios", 0); + if (pdata->us_euro_gpio < 0) { + dev_info(&pdev->dev, "property %s not detected in node %s", + "qcom,us-euro-gpios", + pdev->dev.of_node->full_name); + } else { + dev_dbg(&pdev->dev, "%s detected %d", + "qcom,us-euro-gpios", pdata->us_euro_gpio); + wcd_mbhc_cfg.swap_gnd_mic = msm8996_swap_gnd_mic; + } + + ret = msm8996_prepare_us_euro(card); + if (ret) + dev_info(&pdev->dev, "msm8996_prepare_us_euro failed (%d)\n", + ret); + return 0; +err: + if (pdata->us_euro_gpio > 0) { + dev_dbg(&pdev->dev, "%s free us_euro gpio %d\n", + __func__, pdata->us_euro_gpio); + gpio_free(pdata->us_euro_gpio); + pdata->us_euro_gpio = 0; + } + if (pdata->hph_en1_gpio > 0) { + dev_dbg(&pdev->dev, "%s free hph_en1_gpio %d\n", + __func__, pdata->hph_en1_gpio); + gpio_free(pdata->hph_en1_gpio); + pdata->hph_en1_gpio = 0; + } + if (pdata->hph_en0_gpio > 0) { + dev_dbg(&pdev->dev, "%s free hph_en0_gpio %d\n", + __func__, pdata->hph_en0_gpio); + gpio_free(pdata->hph_en0_gpio); + pdata->hph_en0_gpio = 0; + } + devm_kfree(&pdev->dev, pdata); + return ret; +} + +static int msm8996_asoc_machine_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm8996_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + + if (gpio_is_valid(ext_us_amp_gpio)) + gpio_free(ext_us_amp_gpio); + + gpio_free(pdata->us_euro_gpio); + gpio_free(pdata->hph_en1_gpio); + gpio_free(pdata->hph_en0_gpio); + + if (msm8996_liquid_dock_dev != NULL) { + switch_dev_unregister(&msm8996_liquid_dock_dev->audio_sdev); + + if (msm8996_liquid_dock_dev->dock_plug_irq) + free_irq(msm8996_liquid_dock_dev->dock_plug_irq, + msm8996_liquid_dock_dev); + + if (msm8996_liquid_dock_dev->dock_plug_gpio) + gpio_free(msm8996_liquid_dock_dev->dock_plug_gpio); + + kfree(msm8996_liquid_dock_dev); + msm8996_liquid_dock_dev = NULL; + } + snd_soc_unregister_card(card); + + return 0; +} + +static struct platform_driver msm8996_asoc_machine_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = msm8996_asoc_machine_of_match, + }, + .probe = msm8996_asoc_machine_probe, + .remove = msm8996_asoc_machine_remove, +}; +module_platform_driver(msm8996_asoc_machine_driver); + +MODULE_DESCRIPTION("ALSA SoC msm"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, msm8996_asoc_machine_of_match); diff --git a/sound/soc/msm/msm8998.c b/sound/soc/msm/msm8998.c new file mode 100644 index 000000000000..222c65a3182d --- /dev/null +++ b/sound/soc/msm/msm8998.c @@ -0,0 +1,7481 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qdsp6v2/msm-pcm-routing-v2.h" +#include "../codecs/wcd9335.h" +#include "../codecs/wcd934x/wcd934x.h" +#include "../codecs/wcd934x/wcd934x-mbhc.h" +#include "../codecs/wsa881x.h" + +#define DRV_NAME "msm8998-asoc-snd" + +#define __CHIPSET__ "MSM8998 " +#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) + +#define SAMPLING_RATE_8KHZ 8000 +#define SAMPLING_RATE_11P025KHZ 11025 +#define SAMPLING_RATE_16KHZ 16000 +#define SAMPLING_RATE_22P05KHZ 22050 +#define SAMPLING_RATE_32KHZ 32000 +#define SAMPLING_RATE_44P1KHZ 44100 +#define SAMPLING_RATE_48KHZ 48000 +#define SAMPLING_RATE_88P2KHZ 88200 +#define SAMPLING_RATE_96KHZ 96000 +#define SAMPLING_RATE_176P4KHZ 176400 +#define SAMPLING_RATE_192KHZ 192000 +#define SAMPLING_RATE_352P8KHZ 352800 +#define SAMPLING_RATE_384KHZ 384000 + +#define WCD9XXX_MBHC_DEF_BUTTONS 8 +#define WCD9XXX_MBHC_DEF_RLOADS 5 +#define CODEC_EXT_CLK_RATE 9600000 +#define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define DEV_NAME_STR_LEN 32 + +#define WSA8810_NAME_1 "wsa881x.20170211" +#define WSA8810_NAME_2 "wsa881x.20170212" + +#define WCN_CDC_SLIM_RX_CH_MAX 2 +#define WCN_CDC_SLIM_TX_CH_MAX 3 + +#define TDM_CHANNEL_MAX 8 +#define TDM_SLOT_OFFSET_MAX 8 + +#define MSM_HIFI_ON 1 + +enum { + SLIM_RX_0 = 0, + SLIM_RX_1, + SLIM_RX_2, + SLIM_RX_3, + SLIM_RX_4, + SLIM_RX_5, + SLIM_RX_6, + SLIM_RX_7, + SLIM_RX_MAX, +}; + +enum { + SLIM_TX_0 = 0, + SLIM_TX_1, + SLIM_TX_2, + SLIM_TX_3, + SLIM_TX_4, + SLIM_TX_5, + SLIM_TX_6, + SLIM_TX_7, + SLIM_TX_8, + SLIM_TX_MAX, +}; + +enum { + PRIM_MI2S = 0, + SEC_MI2S, + TERT_MI2S, + QUAT_MI2S, + MI2S_MAX, +}; + +enum { + PRIM_AUX_PCM = 0, + SEC_AUX_PCM, + TERT_AUX_PCM, + QUAT_AUX_PCM, + AUX_PCM_MAX, +}; + +enum { + PCM_I2S_SEL_PRIM = 0, + PCM_I2S_SEL_SEC, + PCM_I2S_SEL_TERT, + PCM_I2S_SEL_QUAT, + PCM_I2S_SEL_MAX, +}; + +struct mi2s_aux_pcm_common_conf { + struct mutex lock; + void *pcm_i2s_sel_vt_addr; +}; + +struct mi2s_conf { + struct mutex lock; + u32 ref_cnt; + u32 msm_is_mi2s_master; +}; + +struct auxpcm_conf { + struct mutex lock; + u32 ref_cnt; +}; + +struct dev_config { + u32 sample_rate; + u32 bit_format; + u32 channels; +}; + +enum { + HDMI_RX_IDX = 0, + DP_RX_IDX, + EXT_DISP_RX_IDX_MAX, +}; + +struct msm_wsa881x_dev_info { + struct device_node *of_node; + u32 index; +}; + +enum pinctrl_pin_state { + STATE_DISABLE = 0, /* All pins are in sleep state */ + STATE_MI2S_ACTIVE, /* IS2 = active, TDM = sleep */ + STATE_TDM_ACTIVE, /* IS2 = sleep, TDM = active */ +}; + +struct msm_pinctrl_info { + struct pinctrl *pinctrl; + struct pinctrl_state *mi2s_disable; + struct pinctrl_state *tdm_disable; + struct pinctrl_state *mi2s_active; + struct pinctrl_state *tdm_active; + enum pinctrl_pin_state curr_state; +}; + +struct msm_asoc_mach_data { + u32 mclk_freq; + int us_euro_gpio; /* used by gpio driver API */ + struct device_node *us_euro_gpio_p; /* used by pinctrl API */ + struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ + struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ + struct snd_info_entry *codec_root; + struct msm_pinctrl_info pinctrl_info; +}; + +struct msm_asoc_wcd93xx_codec { + void* (*get_afe_config_fn)(struct snd_soc_codec *codec, + enum afe_config_type config_type); + void (*mbhc_hs_detect_exit)(struct snd_soc_codec *codec); +}; + +static const char *const pin_states[] = {"sleep", "i2s-active", + "tdm-active"}; + +enum { + TDM_0 = 0, + TDM_1, + TDM_2, + TDM_3, + TDM_4, + TDM_5, + TDM_6, + TDM_7, + TDM_PORT_MAX, +}; + +enum { + TDM_PRI = 0, + TDM_SEC, + TDM_TERT, + TDM_QUAT, + TDM_INTERFACE_MAX, +}; + +struct tdm_port { + u32 mode; + u32 channel; +}; + +/* TDM default config */ +static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + } +}; + +/* TDM default config */ +static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + } +}; + +/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */ +static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { + {0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */ +}; + +/* Default configuration of slimbus channels */ +static struct dev_config slim_rx_cfg[] = { + [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config slim_tx_cfg[] = { + [SLIM_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + + +/* Default configuration of external display BE */ +static struct dev_config ext_disp_rx_cfg[] = { + [HDMI_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [DP_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config usb_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +static struct dev_config usb_tx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 1, +}; + +static struct dev_config proxy_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +/* Default configuration of MI2S channels */ +static struct dev_config mi2s_rx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config mi2s_tx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_rx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_tx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static int msm_vi_feed_tx_ch = 2; +static const char *const slim_rx_ch_text[] = {"One", "Two"}; +static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static const char *const vi_feed_ch_text[] = {"One", "Two"}; +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; +static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE"}; +static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_48"}; +static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *ch_text[] = {"Two", "Three", "Four", "Five", + "Six", "Seven", "Eight"}; +static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_32", "KHZ_44P1", + "KHZ_88P2", "KHZ_176P4"}; +static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", "Eight"}; +static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; +static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", + "KHZ_44P1", "KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; +static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_96", "KHZ_192"}; +static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static const char *const hifi_text[] = {"Off", "On"}; + +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_1_tx_chs, slim_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, + ext_disp_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(hifi_function, hifi_text); + +static struct platform_device *spdev; +static int msm_hifi_control; + +static bool is_initial_boot; +static bool codec_reg_done; +static struct snd_soc_aux_dev *msm_aux_dev; +static struct snd_soc_codec_conf *msm_codec_conf; +static struct msm_asoc_wcd93xx_codec msm_codec_fn; + +static void *def_tasha_mbhc_cal(void); +static void *def_tavil_mbhc_cal(void); +static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, + int enable, bool dapm); +static int msm_wsa881x_init(struct snd_soc_component *component); + +/* + * Need to report LINEIN + * if R/L channel impedance is larger than 5K ohm + */ +static struct wcd_mbhc_config wcd_mbhc_cfg = { + .read_fw_bin = false, + .calibration = NULL, + .detect_extn_cable = true, + .mono_stero_detection = false, + .swap_gnd_mic = NULL, + .hs_ext_micbias = true, + .key_code[0] = KEY_MEDIA, + .key_code[1] = KEY_VOICECOMMAND, + .key_code[2] = KEY_VOLUMEUP, + .key_code[3] = KEY_VOLUMEDOWN, + .key_code[4] = 0, + .key_code[5] = 0, + .key_code[6] = 0, + .key_code[7] = 0, + .linein_th = 5000, + .moisture_en = true, + .mbhc_micbias = MIC_BIAS_2, + .anc_micbias = MIC_BIAS_2, + .enable_anc_mic_detect = false, +}; + +static struct snd_soc_dapm_route wcd_audio_paths_tasha[] = { + {"MIC BIAS1", NULL, "MCLK TX"}, + {"MIC BIAS2", NULL, "MCLK TX"}, + {"MIC BIAS3", NULL, "MCLK TX"}, + {"MIC BIAS4", NULL, "MCLK TX"}, +}; + +static struct snd_soc_dapm_route wcd_audio_paths[] = { + {"MIC BIAS1", NULL, "MCLK"}, + {"MIC BIAS2", NULL, "MCLK"}, + {"MIC BIAS3", NULL, "MCLK"}, + {"MIC BIAS4", NULL, "MCLK"}, +}; + +static struct afe_clk_set mi2s_clk[MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + } +}; + +static struct mi2s_aux_pcm_common_conf mi2s_auxpcm_conf[PCM_I2S_SEL_MAX]; +static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; +static struct auxpcm_conf auxpcm_intf_conf[AUX_PCM_MAX]; + +static int slim_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 10; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int slim_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + sample_rate = SAMPLING_RATE_384KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int slim_get_bit_format_val(int bit_format) +{ + int val = 0; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + val = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + val = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + val = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + val = 0; + break; + } + return val; +} + +static int slim_get_bit_format(int val) +{ + int bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + + switch (val) { + case 0: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + bit_fmt = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + bit_fmt = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + bit_fmt = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return bit_fmt; +} + +static int slim_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int port_id = 0; + + if (strnstr(kcontrol->id.name, "SLIM_0_RX", sizeof("SLIM_0_RX"))) + port_id = SLIM_RX_0; + else if (strnstr(kcontrol->id.name, "SLIM_2_RX", sizeof("SLIM_2_RX"))) + port_id = SLIM_RX_2; + else if (strnstr(kcontrol->id.name, "SLIM_5_RX", sizeof("SLIM_5_RX"))) + port_id = SLIM_RX_5; + else if (strnstr(kcontrol->id.name, "SLIM_6_RX", sizeof("SLIM_6_RX"))) + port_id = SLIM_RX_6; + else if (strnstr(kcontrol->id.name, "SLIM_0_TX", sizeof("SLIM_0_TX"))) + port_id = SLIM_TX_0; + else if (strnstr(kcontrol->id.name, "SLIM_1_TX", sizeof("SLIM_1_TX"))) + port_id = SLIM_TX_1; + else { + pr_err("%s: unsupported channel: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + + return port_id; +} + +static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_sample_rate_val(slim_rx_cfg[ch_num].sample_rate); + + pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].sample_rate = + slim_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_sample_rate_val(slim_tx_cfg[ch_num].sample_rate); + + pr_debug("%s: slim[%d]_tx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate = 0; + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + sample_rate = slim_get_sample_rate(ucontrol->value.enumerated.item[0]); + if (sample_rate == SAMPLING_RATE_44P1KHZ) { + pr_err("%s: Unsupported sample rate %d: for Tx path\n", + __func__, sample_rate); + return -EINVAL; + } + slim_tx_cfg[ch_num].sample_rate = sample_rate; + + pr_debug("%s: slim[%d]_tx_sample_rate = %d, value = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_bit_format_val(slim_rx_cfg[ch_num].bit_format); + + pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_rx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].bit_format = + slim_get_bit_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_rx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_bit_format_val(slim_tx_cfg[ch_num].bit_format); + + pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_tx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_tx_cfg[ch_num].bit_format = + slim_get_bit_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_tx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_slim_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].channels); + ucontrol->value.enumerated.item[0] = slim_rx_cfg[ch_num].channels - 1; + + return 0; +} + +static int msm_slim_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].channels); + + return 1; +} + +static int msm_slim_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].channels); + ucontrol->value.enumerated.item[0] = slim_tx_cfg[ch_num].channels - 1; + + return 0; +} + +static int msm_slim_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_tx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].channels); + + return 1; +} + +static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1; + pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch); + return 1; +} + +static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* + * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) + * when used for BT_SCO use case. Return either Rx or Tx sample rate + * value. + */ + switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate = %d", __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 0: + default: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n", + __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate, + slim_tx_cfg[SLIM_TX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, + usb_rx_cfg.channels); + ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1; + return 0; +} + +static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels); + return 1; +} + +static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_rx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__, + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_rx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_rx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_rx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_rx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, + usb_tx_cfg.channels); + ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1; + return 0; +} + +static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels); + return 1; +} + +static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_tx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + default: + sample_rate_val = 6; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__, + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_tx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_tx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_tx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_tx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "HDMI_RX", sizeof("HDMI_RX"))) + idx = HDMI_RX_IDX; + else if (strnstr(kcontrol->id.name, "Display Port RX", + sizeof("Display Port RX"))) + idx = DP_RX_IDX; + else { + pr_err("%s: unsupported BE: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].bit_format) { + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 1: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int ext_disp_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.integer.value[0] = + ext_disp_rx_cfg[idx].channels - 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + + return 0; +} + +static int ext_disp_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ext_disp_rx_cfg[idx].channels = + ucontrol->value.integer.value[0] + 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + return 1; +} + +static int ext_disp_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].sample_rate) { + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 6; + break; + + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 4; + break; + + case SAMPLING_RATE_32KHZ: + sample_rate_val = 3; + break; + + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: ext_disp_rx[%d].sample_rate = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].sample_rate); + + return 0; +} + +static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 6: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 5: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 4: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_32KHZ; + break; + case 2: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, ext_disp_rx[%d].sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], idx, + ext_disp_rx_cfg[idx].sample_rate); + return 0; +} + +static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2; + + return 0; +} + +static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2; + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + + return 1; +} + +static int tdm_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_384KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int aux_pcm_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 0: + default: + sample_rate = SAMPLING_RATE_8KHZ; + break; + } + return sample_rate; +} + +static int tdm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 8; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int aux_pcm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + return sample_rate_val; +} + +static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, + struct tdm_port *port) +{ + if (port) { + if (strnstr(kcontrol->id.name, "PRI", + sizeof(kcontrol->id.name))) { + port->mode = TDM_PRI; + } else if (strnstr(kcontrol->id.name, "SEC", + sizeof(kcontrol->id.name))) { + port->mode = TDM_SEC; + } else if (strnstr(kcontrol->id.name, "TERT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_TERT; + } else if (strnstr(kcontrol->id.name, "QUAT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_QUAT; + } else { + pr_err("%s: unsupported mode in: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + + if (strnstr(kcontrol->id.name, "RX_0", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_0", + sizeof(kcontrol->id.name))) { + port->channel = TDM_0; + } else if (strnstr(kcontrol->id.name, "RX_1", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_1", + sizeof(kcontrol->id.name))) { + port->channel = TDM_1; + } else if (strnstr(kcontrol->id.name, "RX_2", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_2", + sizeof(kcontrol->id.name))) { + port->channel = TDM_2; + } else if (strnstr(kcontrol->id.name, "RX_3", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_3", + sizeof(kcontrol->id.name))) { + port->channel = TDM_3; + } else if (strnstr(kcontrol->id.name, "RX_4", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_4", + sizeof(kcontrol->id.name))) { + port->channel = TDM_4; + } else if (strnstr(kcontrol->id.name, "RX_5", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_5", + sizeof(kcontrol->id.name))) { + port->channel = TDM_5; + } else if (strnstr(kcontrol->id.name, "RX_6", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_6", + sizeof(kcontrol->id.name))) { + port->channel = TDM_6; + } else if (strnstr(kcontrol->id.name, "RX_7", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_7", + sizeof(kcontrol->id.name))) { + port->channel = TDM_7; + } else { + pr_err("%s: unsupported channel in: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + } else + return -EINVAL; + return 0; +} + +static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_rx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_tx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_get_format(int value) +{ + int format = 0; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int tdm_get_format_val(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 2; + break; + default: + value = 0; + break; + } + return value; +} + +static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_rx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_tx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + + ucontrol->value.enumerated.item[0] = + tdm_rx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = + tdm_tx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", + sizeof("PRIM_AUX_PCM"))) + idx = PRIM_AUX_PCM; + else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM", + sizeof("SEC_AUX_PCM"))) + idx = SEC_AUX_PCM; + else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", + sizeof("TERT_AUX_PCM"))) + idx = TERT_AUX_PCM; + else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", + sizeof("QUAT_AUX_PCM"))) + idx = QUAT_AUX_PCM; + else { + pr_err("%s: unsupported port: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX", + sizeof("PRIM_MI2S_RX"))) + idx = PRIM_MI2S; + else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX", + sizeof("SEC_MI2S_RX"))) + idx = SEC_MI2S; + else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", + sizeof("TERT_MI2S_RX"))) + idx = TERT_MI2S; + else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", + sizeof("QUAT_MI2S_RX"))) + idx = QUAT_MI2S; + else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", + sizeof("PRIM_MI2S_TX"))) + idx = PRIM_MI2S; + else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX", + sizeof("SEC_MI2S_TX"))) + idx = SEC_MI2S; + else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", + sizeof("TERT_MI2S_TX"))) + idx = TERT_MI2S; + else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", + sizeof("QUAT_MI2S_TX"))) + idx = QUAT_MI2S; + else { + pr_err("%s: unsupported channel: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int mi2s_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 6; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int mi2s_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_192KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int mi2s_get_format(int value) +{ + int format; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int mi2s_get_format_value(int format) +{ + int value; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + value = 2; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 3; + break; + default: + value = 0; + break; + } + return value; +} + +static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_format_value(mi2s_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].bit_format = + mi2s_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_format_value(mi2s_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].bit_format = + mi2s_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_hifi_ctrl(struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + + pr_debug("%s: msm_hifi_control = %d", __func__, + msm_hifi_control); + + if (!pdata || !pdata->hph_en1_gpio_p) { + pr_err("%s: hph_en1_gpio is invalid\n", __func__); + return -EINVAL; + } + if (msm_hifi_control == MSM_HIFI_ON) { + msm_cdc_pinctrl_select_active_state(pdata->hph_en1_gpio_p); + /* 5msec delay needed as per HW requirement */ + usleep_range(5000, 5010); + } else { + msm_cdc_pinctrl_select_sleep_state(pdata->hph_en1_gpio_p); + } + snd_soc_dapm_sync(dapm); + + return 0; +} + +static int msm_hifi_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_hifi_control = %d\n", + __func__, msm_hifi_control); + ucontrol->value.integer.value[0] = msm_hifi_control; + + return 0; +} + +static int msm_hifi_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + msm_hifi_control = ucontrol->value.integer.value[0]; + msm_hifi_ctrl(codec); + + return 0; +} + +static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, + msm_slim_rx_ch_get, msm_slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs, + msm_slim_rx_ch_get, msm_slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs, + msm_slim_tx_ch_get, msm_slim_tx_ch_put), + SOC_ENUM_EXT("SLIM_1_TX Channels", slim_1_tx_chs, + msm_slim_tx_ch_get, msm_slim_tx_ch_put), + SOC_ENUM_EXT("SLIM_5_RX Channels", slim_5_rx_chs, + msm_slim_rx_ch_get, msm_slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_6_RX Channels", slim_6_rx_chs, + msm_slim_rx_ch_get, msm_slim_rx_ch_put), + SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, + msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, + usb_audio_rx_ch_get, usb_audio_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, + usb_audio_tx_ch_get, usb_audio_tx_ch_put), + SOC_ENUM_EXT("HDMI_RX Channels", ext_disp_rx_chs, + ext_disp_rx_ch_get, ext_disp_rx_ch_put), + SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, + ext_disp_rx_ch_get, ext_disp_rx_ch_put), + SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, + proxy_rx_ch_get, proxy_rx_ch_put), + SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_5_RX Format", slim_5_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_6_RX Format", slim_6_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format, + slim_tx_bit_format_get, slim_tx_bit_format_put), + SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, + usb_audio_rx_format_get, usb_audio_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, + usb_audio_tx_format_get, usb_audio_tx_format_put), + SOC_ENUM_EXT("HDMI_RX Bit Format", ext_disp_rx_format, + ext_disp_rx_format_get, ext_disp_rx_format_put), + SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, + ext_disp_rx_format_get, ext_disp_rx_format_put), + SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate, + slim_tx_sample_rate_get, slim_tx_sample_rate_put), + SOC_ENUM_EXT("SLIM_5_RX SampleRate", slim_5_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_6_RX SampleRate", slim_6_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, + usb_audio_rx_sample_rate_get, + usb_audio_rx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, + usb_audio_tx_sample_rate_get, + usb_audio_tx_sample_rate_put), + SOC_ENUM_EXT("HDMI_RX SampleRate", ext_disp_rx_sample_rate, + ext_disp_rx_sample_rate_get, + ext_disp_rx_sample_rate_put), + SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, + ext_disp_rx_sample_rate_get, + ext_disp_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("SEC_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("TERT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("TERT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get, + msm_hifi_put), +}; + +static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, + int enable, bool dapm) +{ + int ret = 0; + + if (!strcmp(dev_name(codec->dev), "tasha_codec")) + ret = tasha_cdc_mclk_enable(codec, enable, dapm); + else if (!strcmp(dev_name(codec->dev), "tavil_codec")) + ret = tavil_cdc_mclk_enable(codec, enable); + else { + dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", + __func__); + ret = -EINVAL; + } + return ret; +} + +static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, + int enable, bool dapm) +{ + int ret = 0; + + if (!strcmp(dev_name(codec->dev), "tasha_codec")) + ret = tasha_cdc_mclk_tx_enable(codec, enable, dapm); + else { + dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", + __func__); + ret = -EINVAL; + } + return ret; +} + +static int msm_mclk_tx_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + pr_debug("%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return msm_snd_enable_codec_ext_tx_clk(codec, 1, true); + case SND_SOC_DAPM_POST_PMD: + return msm_snd_enable_codec_ext_tx_clk(codec, 0, true); + } + return 0; +} + +static int msm_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + pr_debug("%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return msm_snd_enable_codec_ext_clk(codec, 1, true); + case SND_SOC_DAPM_POST_PMD: + return msm_snd_enable_codec_ext_clk(codec, 0, true); + } + return 0; +} + +static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + + pr_debug("%s: msm_hifi_control = %d", __func__, msm_hifi_control); + + if (!pdata || !pdata->hph_en0_gpio_p) { + pr_err("%s: hph_en0_gpio is invalid\n", __func__); + return -EINVAL; + } + + if (msm_hifi_control != MSM_HIFI_ON) { + pr_debug("%s: HiFi mixer control is not set\n", + __func__); + return 0; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + msm_cdc_pinctrl_select_active_state(pdata->hph_en0_gpio_p); + break; + case SND_SOC_DAPM_PRE_PMD: + msm_cdc_pinctrl_select_sleep_state(pdata->hph_en0_gpio_p); + break; + } + + return 0; +} + +static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { + + SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, + msm_mclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0, + msm_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SPK("Lineout_1 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_3 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_4 amp", NULL), + SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event), + SND_SOC_DAPM_MIC("Handset Mic", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), + SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL), + SND_SOC_DAPM_MIC("Analog Mic5", NULL), + SND_SOC_DAPM_MIC("Analog Mic6", NULL), + + SND_SOC_DAPM_MIC("Digital Mic0", NULL), + SND_SOC_DAPM_MIC("Digital Mic1", NULL), + SND_SOC_DAPM_MIC("Digital Mic2", NULL), + SND_SOC_DAPM_MIC("Digital Mic3", NULL), + SND_SOC_DAPM_MIC("Digital Mic4", NULL), + SND_SOC_DAPM_MIC("Digital Mic5", NULL), +}; + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, + int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +static int msm_slim_get_ch_from_beid(int32_t be_id) +{ + int ch_id = 0; + + switch (be_id) { + case MSM_BACKEND_DAI_SLIMBUS_0_RX: + ch_id = SLIM_RX_0; + break; + case MSM_BACKEND_DAI_SLIMBUS_1_RX: + ch_id = SLIM_RX_1; + break; + case MSM_BACKEND_DAI_SLIMBUS_2_RX: + ch_id = SLIM_RX_2; + break; + case MSM_BACKEND_DAI_SLIMBUS_3_RX: + ch_id = SLIM_RX_3; + break; + case MSM_BACKEND_DAI_SLIMBUS_4_RX: + ch_id = SLIM_RX_4; + break; + case MSM_BACKEND_DAI_SLIMBUS_6_RX: + ch_id = SLIM_RX_6; + break; + case MSM_BACKEND_DAI_SLIMBUS_0_TX: + ch_id = SLIM_TX_0; + break; + case MSM_BACKEND_DAI_SLIMBUS_3_TX: + ch_id = SLIM_TX_3; + break; + default: + ch_id = SLIM_RX_0; + break; + } + + return ch_id; +} + +static int msm_ext_disp_get_idx_from_beid(int32_t be_id) +{ + int idx; + + switch (be_id) { + case MSM_BACKEND_DAI_HDMI_RX: + idx = HDMI_RX_IDX; + break; + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = DP_RX_IDX; + break; + default: + pr_err("%s: Incorrect ext_disp BE id %d\n", __func__, be_id); + idx = -EINVAL; + break; + } + + return idx; +} + +static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int rc = 0; + int idx; + void *config = NULL; + struct snd_soc_codec *codec = NULL; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->id) { + case MSM_BACKEND_DAI_SLIMBUS_0_RX: + case MSM_BACKEND_DAI_SLIMBUS_1_RX: + case MSM_BACKEND_DAI_SLIMBUS_2_RX: + case MSM_BACKEND_DAI_SLIMBUS_3_RX: + case MSM_BACKEND_DAI_SLIMBUS_4_RX: + case MSM_BACKEND_DAI_SLIMBUS_6_RX: + idx = msm_slim_get_ch_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[idx].bit_format); + rate->min = rate->max = slim_rx_cfg[idx].sample_rate; + channels->min = channels->max = slim_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_0_TX: + case MSM_BACKEND_DAI_SLIMBUS_3_TX: + idx = msm_slim_get_ch_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[idx].bit_format); + rate->min = rate->max = slim_tx_cfg[idx].sample_rate; + channels->min = channels->max = slim_tx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_1_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[1].bit_format); + rate->min = rate->max = slim_tx_cfg[1].sample_rate; + channels->min = channels->max = slim_tx_cfg[1].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_4_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + SNDRV_PCM_FORMAT_S32_LE); + rate->min = rate->max = SAMPLING_RATE_8KHZ; + channels->min = channels->max = msm_vi_feed_tx_ch; + break; + + case MSM_BACKEND_DAI_SLIMBUS_5_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[5].bit_format); + rate->min = rate->max = slim_rx_cfg[5].sample_rate; + channels->min = channels->max = slim_rx_cfg[5].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_5_TX: + codec = rtd->codec; + rate->min = rate->max = SAMPLING_RATE_16KHZ; + channels->min = channels->max = 1; + + config = msm_codec_fn.get_afe_config_fn(codec, + AFE_SLIMBUS_SLAVE_PORT_CONFIG); + if (config) { + rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, + config, SLIMBUS_5_TX); + if (rc) + pr_err("%s: Failed to set slimbus slave port config %d\n", + __func__, rc); + } + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[SLIM_RX_7].bit_format); + rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate; + channels->min = channels->max = + slim_rx_cfg[SLIM_RX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_8_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_8].channels; + break; + + case MSM_BACKEND_DAI_USB_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_rx_cfg.bit_format); + rate->min = rate->max = usb_rx_cfg.sample_rate; + channels->min = channels->max = usb_rx_cfg.channels; + break; + + case MSM_BACKEND_DAI_USB_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_tx_cfg.bit_format); + rate->min = rate->max = usb_tx_cfg.sample_rate; + channels->min = channels->max = usb_tx_cfg.channels; + break; + + case MSM_BACKEND_DAI_HDMI_RX: + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = msm_ext_disp_get_idx_from_beid(dai_link->id); + if (idx < 0) { + pr_err("%s: Incorrect ext disp idx %d\n", + __func__, idx); + rc = idx; + goto done; + } + + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + ext_disp_rx_cfg[idx].bit_format); + rate->min = rate->max = ext_disp_rx_cfg[idx].sample_rate; + channels->min = channels->max = ext_disp_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_AFE_PCM_RX: + channels->min = channels->max = proxy_rx_cfg.channels; + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + + case MSM_BACKEND_DAI_PRI_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_PRI_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUAT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUAT_MI2S].channels; + break; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + +done: + return rc; +} + +static bool msm_swap_gnd_mic(struct snd_soc_codec *codec) +{ + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + int value = 0; + + if (pdata->us_euro_gpio_p) { + value = msm_cdc_pinctrl_get_state(pdata->us_euro_gpio_p); + if (value) + msm_cdc_pinctrl_select_sleep_state( + pdata->us_euro_gpio_p); + else + msm_cdc_pinctrl_select_active_state( + pdata->us_euro_gpio_p); + } else if (pdata->us_euro_gpio >= 0) { + value = gpio_get_value_cansleep(pdata->us_euro_gpio); + gpio_set_value_cansleep(pdata->us_euro_gpio, !value); + } + pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value); + return true; +} + +static int msm_afe_set_config(struct snd_soc_codec *codec) +{ + int ret = 0; + void *config_data = NULL; + + if (!msm_codec_fn.get_afe_config_fn) { + dev_err(codec->dev, "%s: codec get afe config not init'ed\n", + __func__); + return -EINVAL; + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CDC_REGISTERS_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0); + if (ret) { + dev_err(codec->dev, + "%s: Failed to set codec registers config %d\n", + __func__, ret); + return ret; + } + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CDC_REGISTER_PAGE_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, + 0); + if (ret) + dev_err(codec->dev, + "%s: Failed to set cdc register page config\n", + __func__); + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_SLIMBUS_SLAVE_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0); + if (ret) { + dev_err(codec->dev, + "%s: Failed to set slimbus slave config %d\n", + __func__, ret); + return ret; + } + } + + return 0; +} + +static void msm_afe_clear_config(void) +{ + afe_clear_config(AFE_CDC_REGISTERS_CONFIG); + afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); +} + +static int msm_adsp_power_up_config(struct snd_soc_codec *codec) +{ + int ret = 0; + unsigned long timeout; + int adsp_ready = 0; + + timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + + do { + if (q6core_is_adsp_ready()) { + pr_debug("%s: ADSP Audio is ready\n", __func__); + adsp_ready = 1; + break; + } + /* + * ADSP will be coming up after subsystem restart and + * it might not be fully up when the control reaches + * here. So, wait for 50msec before checking ADSP state + */ + msleep(50); + } while (time_after(timeout, jiffies)); + + if (!adsp_ready) { + pr_err("%s: timed out waiting for ADSP Audio\n", __func__); + ret = -ETIMEDOUT; + goto err_fail; + } + + ret = msm_afe_set_config(codec); + if (ret) + pr_err("%s: Failed to set AFE config. err %d\n", + __func__, ret); + + return 0; + +err_fail: + return ret; +} + +static int msm8998_notifier_service_cb(struct notifier_block *this, + unsigned long opcode, void *ptr) +{ + int ret; + struct snd_soc_card *card = NULL; + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + struct snd_soc_codec *codec; + + pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); + + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + /* + * Use flag to ignore initial boot notifications + * On initial boot msm_adsp_power_up_config is + * called on init. There is no need to clear + * and set the config again on initial boot. + */ + if (is_initial_boot) + break; + msm_afe_clear_config(); + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (is_initial_boot) { + is_initial_boot = false; + break; + } + if (!spdev) + return -EINVAL; + + card = platform_get_drvdata(spdev); + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto done; + } + codec = rtd->codec; + + ret = msm_adsp_power_up_config(codec); + if (ret < 0) { + dev_err(card->dev, + "%s: msm_adsp_power_up_config failed ret = %d!\n", + __func__, ret); + goto done; + } + break; + default: + break; + } +done: + return NOTIFY_OK; +} + +static struct notifier_block service_nb = { + .notifier_call = msm8998_notifier_service_cb, + .priority = -INT_MAX, +}; + +static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + void *config_data; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_component *aux_comp; + struct snd_card *card; + struct snd_info_entry *entry; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); + + /* Codec SLIMBUS configuration + * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13 + * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 + * TX14, TX15, TX16 + */ + unsigned int rx_ch[TASHA_RX_MAX] = {144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156}; + unsigned int tx_ch[TASHA_TX_MAX] = {128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143}; + + /* Tavil Codec SLIMBUS configuration + * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8 + * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 + * TX14, TX15, TX16 + */ + unsigned int rx_ch_tavil[WCD934X_RX_MAX] = {144, 145, 146, 147, 148, + 149, 150, 151}; + unsigned int tx_ch_tavil[WCD934X_TX_MAX] = {128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, + 143}; + + pr_info("%s: dev_name%s\n", __func__, dev_name(cpu_dai->dev)); + + rtd->pmdown_time = 0; + + ret = snd_soc_add_codec_controls(codec, msm_snd_controls, + ARRAY_SIZE(msm_snd_controls)); + if (ret < 0) { + pr_err("%s: add_codec_controls failed, err %d\n", + __func__, ret); + return ret; + } + + snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, + ARRAY_SIZE(msm_dapm_widgets)); + + if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) + snd_soc_dapm_add_routes(dapm, wcd_audio_paths_tasha, + ARRAY_SIZE(wcd_audio_paths_tasha)); + else + snd_soc_dapm_add_routes(dapm, wcd_audio_paths, + ARRAY_SIZE(wcd_audio_paths)); + + snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic5"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6"); + snd_soc_dapm_ignore_suspend(dapm, "MADINPUT"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT1"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT2"); + snd_soc_dapm_ignore_suspend(dapm, "EAR"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2"); + snd_soc_dapm_ignore_suspend(dapm, "ANC EAR"); + snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); + snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR"); + + if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) { + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4"); + snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT1"); + snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT2"); + } + + snd_soc_dapm_sync(dapm); + + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { + snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch_tavil), + tx_ch_tavil, ARRAY_SIZE(rx_ch_tavil), + rx_ch_tavil); + } else { + snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), + rx_ch); + } + + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { + msm_codec_fn.get_afe_config_fn = tavil_get_afe_config; + } else { + msm_codec_fn.get_afe_config_fn = tasha_get_afe_config; + msm_codec_fn.mbhc_hs_detect_exit = tasha_mbhc_hs_detect_exit; + } + + ret = msm_adsp_power_up_config(codec); + if (ret) { + pr_err("%s: Failed to set AFE config %d\n", __func__, ret); + goto err_afe_cfg; + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_AANC_VERSION); + if (config_data) { + ret = afe_set_config(AFE_AANC_VERSION, config_data, 0); + if (ret) { + pr_err("%s: Failed to set aanc version %d\n", + __func__, ret); + goto err_afe_cfg; + } + } + + if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) { + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CDC_CLIP_REGISTERS_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG, + config_data, 0); + if (ret) { + pr_err("%s: Failed to set clip registers %d\n", + __func__, ret); + goto err_afe_cfg; + } + } + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CLIP_BANK_SEL); + if (config_data) { + ret = afe_set_config(AFE_CLIP_BANK_SEL, config_data, 0); + if (ret) { + pr_err("%s: Failed to set AFE bank selection %d\n", + __func__, ret); + goto err_afe_cfg; + } + } + } + + /* + * Send speaker configuration only for WSA8810. + * Defalut configuration is for WSA8815. + */ + pr_debug("%s: Number of aux devices: %d\n", + __func__, rtd->card->num_aux_devs); + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->aux_comp_list)) { + aux_comp = list_first_entry(&rtd->card->aux_comp_list, + struct snd_soc_component, list_aux); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { + tavil_set_spkr_mode(rtd->codec, + WCD934X_SPKR_MODE_1); + tavil_set_spkr_gain_offset(rtd->codec, + WCD934X_RX_GAIN_OFFSET_M1P5_DB); + } + } + card = rtd->card->snd_card; + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + pdata->codec_root = NULL; + goto done; + } + pdata->codec_root = entry; + tavil_codec_info_create_codec_entry(pdata->codec_root, codec); + } else { + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->aux_comp_list)) { + aux_comp = list_first_entry(&rtd->card->aux_comp_list, + struct snd_soc_component, list_aux); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { + tasha_set_spkr_mode(rtd->codec, SPKR_MODE_1); + tasha_set_spkr_gain_offset(rtd->codec, + RX_GAIN_OFFSET_M1P5_DB); + } + } + card = rtd->card->snd_card; + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto err_snd_module; + } + pdata->codec_root = entry; + tasha_codec_info_create_codec_entry(pdata->codec_root, codec); + } +done: + codec_reg_done = true; + return 0; + +err_snd_module: +err_afe_cfg: + return ret; +} + +static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) +{ + unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; + unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); +} + +static void *def_tasha_mbhc_cal(void) +{ + void *tasha_wcd_cal; + struct wcd_mbhc_btn_detect_cfg *btn_cfg; + u16 *btn_high; + + tasha_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, + WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); + if (!tasha_wcd_cal) + return NULL; + +#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(tasha_wcd_cal)->X) = (Y)) + S(v_hs_max, 1600); +#undef S +#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(tasha_wcd_cal)->X) = (Y)) + S(num_btn, WCD_MBHC_DEF_BUTTONS); +#undef S + + btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(tasha_wcd_cal); + btn_high = ((void *)&btn_cfg->_v_btn_low) + + (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); + + btn_high[0] = 75; + btn_high[1] = 150; + btn_high[2] = 237; + btn_high[3] = 500; + btn_high[4] = 500; + btn_high[5] = 500; + btn_high[6] = 500; + btn_high[7] = 500; + + return tasha_wcd_cal; +} + +static void *def_tavil_mbhc_cal(void) +{ + void *tavil_wcd_cal; + struct wcd_mbhc_btn_detect_cfg *btn_cfg; + u16 *btn_high; + + tavil_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, + WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); + if (!tavil_wcd_cal) + return NULL; + +#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(tavil_wcd_cal)->X) = (Y)) + S(v_hs_max, 1600); +#undef S +#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal)->X) = (Y)) + S(num_btn, WCD_MBHC_DEF_BUTTONS); +#undef S + + btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal); + btn_high = ((void *)&btn_cfg->_v_btn_low) + + (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); + + btn_high[0] = 75; + btn_high[1] = 150; + btn_high[2] = 237; + btn_high[3] = 500; + btn_high[4] = 500; + btn_high[5] = 500; + btn_high[6] = 500; + btn_high[7] = 500; + + return tavil_wcd_cal; +} + +static int msm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + int ret = 0; + u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + u32 user_set_tx_ch = 0; + u32 rx_ch_count; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err_ch_map; + } + if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_5_RX) { + pr_debug("%s: rx_5_ch=%d\n", __func__, + slim_rx_cfg[5].channels); + rx_ch_count = slim_rx_cfg[5].channels; + } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_2_RX) { + pr_debug("%s: rx_2_ch=%d\n", __func__, + slim_rx_cfg[2].channels); + rx_ch_count = slim_rx_cfg[2].channels; + } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_6_RX) { + pr_debug("%s: rx_6_ch=%d\n", __func__, + slim_rx_cfg[6].channels); + rx_ch_count = slim_rx_cfg[6].channels; + } else { + pr_debug("%s: rx_0_ch=%d\n", __func__, + slim_rx_cfg[0].channels); + rx_ch_count = slim_rx_cfg[0].channels; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + rx_ch_count, rx_ch); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err_ch_map; + } + } else { + + pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__, + codec_dai->name, codec_dai->id, user_set_tx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map\n, err:%d\n", + __func__, ret); + goto err_ch_map; + } + /* For _tx1 case */ + if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_0_TX) + user_set_tx_ch = slim_tx_cfg[0].channels; + /* For _tx3 case */ + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_1_TX) + user_set_tx_ch = slim_tx_cfg[1].channels; + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_4_TX) + user_set_tx_ch = msm_vi_feed_tx_ch; + else + user_set_tx_ch = tx_ch_cnt; + + pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), BE id (%d)\n", + __func__, slim_tx_cfg[0].channels, user_set_tx_ch, + tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + user_set_tx_ch, tx_ch, 0, 0); + if (ret < 0) + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + } + +err_ch_map: + return ret; +} + +static int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + int ret = 0; + u32 tx_ch[SLIM_MAX_TX_PORTS]; + u32 tx_ch_cnt = 0; + u32 user_set_tx_ch = 0; + + if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) { + pr_err("%s: Invalid stream type %d\n", + __func__, substream->stream); + ret = -EINVAL; + goto err_stream_type; + } + + pr_debug("%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, NULL, NULL); + if (ret < 0) { + pr_err("%s: failed to get codec chan map\n, err:%d\n", + __func__, ret); + goto err_ch_map; + } + + user_set_tx_ch = tx_ch_cnt; + + pr_debug("%s: tx_ch_cnt(%d) BE id %d\n", + __func__, tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + user_set_tx_ch, tx_ch, 0, 0); + if (ret < 0) + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); +err_ch_map: +err_stream_type: + return ret; +} + +static int msm_slimbus_2_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; + unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0; + unsigned int num_tx_ch = 0; + unsigned int num_rx_ch = 0; + int ret = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + num_rx_ch = params_channels(params); + pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__, + codec_dai->name, codec_dai->id, num_rx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err_ch_map; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + num_rx_ch, rx_ch); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err_ch_map; + } + } else { + num_tx_ch = params_channels(params); + pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__, + codec_dai->name, codec_dai->id, num_tx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err_ch_map; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, + num_tx_ch, tx_ch, 0, 0); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err_ch_map; + } + } + +err_ch_map: + return ret; +} + +static int msm_wcn_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + int ret; + + dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret) { + dev_err(rtd->dev, + "%s: failed to get BTFM codec chan map\n, err:%d\n", + __func__, ret); + goto exit; + } + + dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) BE id %d\n", + __func__, tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); + if (ret) + dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + +exit: + return ret; +} + +static int msm_aux_pcm_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int index = cpu_dai->id - 1; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + if (index < PRIM_AUX_PCM || index > QUAT_AUX_PCM) { + ret = -EINVAL; + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto done; + } + + mutex_lock(&auxpcm_intf_conf[index].lock); + if (++auxpcm_intf_conf[index].ref_cnt == 1) { + if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) { + mutex_lock(&mi2s_auxpcm_conf[index].lock); + iowrite32(1, + mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr); + mutex_unlock(&mi2s_auxpcm_conf[index].lock); + } else { + dev_err(rtd->card->dev, + "%s lpaif_tert_muxsel_virt_addr is NULL\n", + __func__); + ret = -EINVAL; + } + } + if (ret < 0) + auxpcm_intf_conf[index].ref_cnt--; + + mutex_unlock(&auxpcm_intf_conf[index].lock); + +done: + return ret; +} + +static void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int index = rtd->cpu_dai->id - 1; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, + substream->name, substream->stream, + rtd->cpu_dai->name, rtd->cpu_dai->id); + + if (index < PRIM_AUX_PCM || index > QUAT_AUX_PCM) { + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, rtd->cpu_dai->id); + return; + } + + mutex_lock(&auxpcm_intf_conf[index].lock); + if (--auxpcm_intf_conf[index].ref_cnt == 0) { + if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) { + mutex_lock(&mi2s_auxpcm_conf[index].lock); + iowrite32(0, + mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr); + mutex_unlock(&mi2s_auxpcm_conf[index].lock); + } else { + dev_err(rtd->card->dev, + "%s lpaif_tert_muxsel_virt_addr is NULL\n", + __func__); + } + } + mutex_unlock(&auxpcm_intf_conf[index].lock); +} + +static int msm_get_port_id(int be_id) +{ + int afe_port_id; + + switch (be_id) { + case MSM_BACKEND_DAI_PRI_MI2S_RX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_PRI_MI2S_TX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + default: + pr_err("%s: Invalid BE id: %d\n", __func__, be_id); + afe_port_id = -EINVAL; + } + + return afe_port_id; +} + +static u32 get_mi2s_bits_per_sample(u32 bit_format) +{ + u32 bit_per_sample; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + case SNDRV_PCM_FORMAT_S24_LE: + bit_per_sample = 32; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bit_per_sample = 16; + break; + } + + return bit_per_sample; +} + +static void update_mi2s_clk_val(int dai_id, int stream) +{ + u32 bit_per_sample; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } else { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } +} + +static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int port_id = 0; + int index = cpu_dai->id; + + port_id = msm_get_port_id(rtd->dai_link->id); + if (port_id < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto done; + } + + if (enable) { + update_mi2s_clk_val(index, substream->stream); + dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, + mi2s_clk[index].clk_freq_in_hz); + } + + mi2s_clk[index].enable = enable; + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_clk[index]); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed for port 0x%x , err:%d\n", + __func__, port_id, ret); + goto done; + } + +done: + return ret; +} + +static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, + enum pinctrl_pin_state new_state) +{ + int ret = 0; + int curr_state = 0; + + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + if (pinctrl_info->pinctrl == NULL) { + pr_err("%s: pinctrl_info->pinctrl is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + curr_state = pinctrl_info->curr_state; + pinctrl_info->curr_state = new_state; + pr_debug("%s: curr_state = %s new_state = %s\n", __func__, + pin_states[curr_state], pin_states[pinctrl_info->curr_state]); + + if (curr_state == pinctrl_info->curr_state) { + pr_debug("%s: Already in same state\n", __func__); + goto err; + } + + if (curr_state != STATE_DISABLE && + pinctrl_info->curr_state != STATE_DISABLE) { + pr_debug("%s: state already active cannot switch\n", __func__); + ret = -EIO; + goto err; + } + + switch (pinctrl_info->curr_state) { + case STATE_MI2S_ACTIVE: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_active); + if (ret) { + pr_err("%s: MI2S state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + case STATE_TDM_ACTIVE: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->tdm_active); + if (ret) { + pr_err("%s: TDM state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + case STATE_DISABLE: + if (curr_state == STATE_MI2S_ACTIVE) { + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_disable); + } else { + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->tdm_disable); + } + if (ret) { + pr_err("%s: state disable failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + default: + pr_err("%s: TLMM pin state is invalid\n", __func__); + return -EINVAL; + } + +err: + return ret; +} + +static void msm_release_pinctrl(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + if (pinctrl_info->pinctrl) { + devm_pinctrl_put(pinctrl_info->pinctrl); + pinctrl_info->pinctrl = NULL; + } +} + +static int msm_get_pinctrl(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = NULL; + struct pinctrl *pinctrl; + int ret; + + pinctrl_info = &pdata->pinctrl_info; + + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + return -EINVAL; + } + + pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR_OR_NULL(pinctrl)) { + pr_err("%s: Unable to get pinctrl handle\n", __func__); + return -EINVAL; + } + pinctrl_info->pinctrl = pinctrl; + + /* get all the states handles from Device Tree */ + pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl, + "quat-mi2s-sleep"); + if (IS_ERR(pinctrl_info->mi2s_disable)) { + pr_err("%s: could not get mi2s_disable pinstate\n", __func__); + goto err; + } + pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl, + "quat-mi2s-active"); + if (IS_ERR(pinctrl_info->mi2s_active)) { + pr_err("%s: could not get mi2s_active pinstate\n", __func__); + goto err; + } + pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl, + "quat-tdm-sleep"); + if (IS_ERR(pinctrl_info->tdm_disable)) { + pr_err("%s: could not get tdm_disable pinstate\n", __func__); + goto err; + } + pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl, + "quat-tdm-active"); + if (IS_ERR(pinctrl_info->tdm_active)) { + pr_err("%s: could not get tdm_active pinstate\n", + __func__); + goto err; + } + /* Reset the TLMM pins to a default state */ + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_disable); + if (ret != 0) { + pr_err("%s: Disable TLMM pins failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + pinctrl_info->curr_state = STATE_DISABLE; + + return 0; + +err: + devm_pinctrl_put(pinctrl); + pinctrl_info->pinctrl = NULL; + return -EINVAL; +} + +static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + if (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) { + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + } else if (cpu_dai->id == AFE_PORT_ID_SECONDARY_TDM_RX) { + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + } else { + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n", + __func__, cpu_dai->id, channels->max, rate->max, + params_format(params)); + + return 0; +} + +static int msm8998_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + int channels, slot_width, slots; + unsigned int slot_mask; + unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; + + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + + slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + /*2 slot config - bits 0 and 1 set for the first two slots */ + slot_mask = 0x0000FFFF >> (16-slots); + slot_width = 32; + channels = slots; + + pr_debug("%s: slot_width %d slots %d\n", __func__, slot_width, slots); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + pr_debug("%s: slot_width %d\n", __func__, slot_width); + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + 0, NULL, channels, slot_offset); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } else { + pr_err("%s: invalid use case, err:%d\n", + __func__, ret); + } + +end: + return ret; +} + +static int msm8998_tdm_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); + if (ret) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret); + + return ret; +} + +static void msm8998_tdm_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); + if (ret) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret); + +} + +static struct snd_soc_ops msm8998_tdm_be_ops = { + .hw_params = msm8998_tdm_snd_hw_params, + .startup = msm8998_tdm_snd_startup, + .shutdown = msm8998_tdm_snd_shutdown +}; + +static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int index = cpu_dai->id; + unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret_pinctrl = 0; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + if (index < PRIM_MI2S || index > QUAT_MI2S) { + ret = -EINVAL; + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto done; + } + if (index == QUAT_MI2S) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, STATE_MI2S_ACTIVE); + if (ret_pinctrl) { + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } + } + + /* + * Muxtex protection in case the same MI2S + * interface using for both TX and RX so + * that the same clock won't be enable twice. + */ + mutex_lock(&mi2s_intf_conf[index].lock); + if (++mi2s_intf_conf[index].ref_cnt == 1) { + ret = msm_mi2s_set_sclk(substream, true); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed to enable MI2S clock, err:%d\n", + __func__, ret); + goto clean_up; + } + if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) { + mutex_lock(&mi2s_auxpcm_conf[index].lock); + iowrite32(0, + mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr); + mutex_unlock(&mi2s_auxpcm_conf[index].lock); + } else { + dev_err(rtd->card->dev, + "%s lpaif_muxsel_virt_addr is NULL for dai %d\n", + __func__, index); + ret = -EINVAL; + goto clk_off; + } + /* Check if msm needs to provide the clock to the interface */ + if (!mi2s_intf_conf[index].msm_is_mi2s_master) + fmt = SND_SOC_DAIFMT_CBM_CFM; + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) { + pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n", + __func__, index, ret); + goto clk_off; + } + } +clk_off: + if (ret < 0) + msm_mi2s_set_sclk(substream, false); +clean_up: + if (ret < 0) + mi2s_intf_conf[index].ref_cnt--; + mutex_unlock(&mi2s_intf_conf[index].lock); +done: + return ret; +} + +static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int index = rtd->cpu_dai->id; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret_pinctrl = 0; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + if (index < PRIM_MI2S || index > QUAT_MI2S) { + pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); + return; + } + + mutex_lock(&mi2s_intf_conf[index].lock); + if (--mi2s_intf_conf[index].ref_cnt == 0) { + ret = msm_mi2s_set_sclk(substream, false); + if (ret < 0) + pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", + __func__, index, ret); + } + mutex_unlock(&mi2s_intf_conf[index].lock); + + if (index == QUAT_MI2S) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } +} + +static struct snd_soc_ops msm_mi2s_be_ops = { + .startup = msm_mi2s_snd_startup, + .shutdown = msm_mi2s_snd_shutdown, +}; + +static struct snd_soc_ops msm_aux_pcm_be_ops = { + .startup = msm_aux_pcm_snd_startup, + .shutdown = msm_aux_pcm_snd_shutdown, +}; + +static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width, + int slots) +{ + unsigned int slot_mask = 0; + int i, j; + unsigned int *slot_offset; + + for (i = TDM_0; i < TDM_PORT_MAX; i++) { + slot_offset = tdm_slot_offset[i]; + + for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) { + if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID) + slot_mask |= + (1 << ((slot_offset[j] * 8) / slot_width)); + else + break; + } + } + + return slot_mask; +} + +static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + int channels, slot_width, slots; + unsigned int slot_mask; + unsigned int *slot_offset; + int offset_channels = 0; + int i; + + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + + channels = params_channels(params); + switch (channels) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S16_LE: + /* + * up to 8 channels HW config should + * use 32 bit slot width for max support of + * stream bit width. (slot_width > bit_width) + */ + slot_width = 32; + break; + default: + pr_err("%s: invalid param format 0x%x\n", + __func__, params_format(params)); + return -EINVAL; + } + slots = 8; + slot_mask = tdm_param_set_slot_mask(cpu_dai->id, + slot_width, + slots); + if (!slot_mask) { + pr_err("%s: invalid slot_mask 0x%x\n", + __func__, slot_mask); + return -EINVAL; + } + break; + default: + pr_err("%s: invalid param channels %d\n", + __func__, channels); + return -EINVAL; + } + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + slot_offset = tdm_slot_offset[TDM_0]; + break; + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) + offset_channels++; + else + break; + } + + if (offset_channels == 0) { + pr_err("%s: slot offset not supported, offset_channels %d\n", + __func__, offset_channels); + return -EINVAL; + } + + if (channels > offset_channels) { + pr_err("%s: channels %d exceed offset_channels %d\n", + __func__, channels, offset_channels); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, + channels, slot_offset); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } else { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, channels, + slot_offset, 0, NULL); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } +end: + return ret; +} + +static struct snd_soc_ops msm_be_ops = { + .hw_params = msm_snd_hw_params, +}; + +static struct snd_soc_ops msm_cpe_ops = { + .hw_params = msm_snd_cpe_hw_params, +}; + +static struct snd_soc_ops msm_slimbus_2_be_ops = { + .hw_params = msm_slimbus_2_hw_params, +}; + +static struct snd_soc_ops msm_wcn_ops = { + .hw_params = msm_wcn_hw_params, +}; + +static struct snd_soc_ops msm_tdm_be_ops = { + .hw_params = msm_tdm_snd_hw_params +}; + +/* Digital audio interface glue - connects codec <---> CPU */ +static struct snd_soc_dai_link msm_common_dai_links[] = { + /* FrontEnd DAI Links */ + { + .name = MSM_DAILINK_NAME(Media1), + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, + { + .name = MSM_DAILINK_NAME(Media2), + .stream_name = "MultiMedia2", + .cpu_dai_name = "MultiMedia2", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, + }, + { + .name = "VoiceMMode1", + .stream_name = "VoiceMMode1", + .cpu_dai_name = "VoiceMMode1", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE1, + }, + { + .name = "MSM VoIP", + .stream_name = "VoIP", + .cpu_dai_name = "VoIP", + .platform_name = "msm-voip-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_VOIP, + }, + { + .name = MSM_DAILINK_NAME(ULL), + .stream_name = "MultiMedia3", + .cpu_dai_name = "MultiMedia3", + .platform_name = "msm-pcm-dsp.2", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA3, + }, + /* Hostless PCM purpose */ + { + .name = "SLIMBUS_0 Hostless", + .stream_name = "SLIMBUS_0 Hostless", + .cpu_dai_name = "SLIMBUS0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "MSM AFE-PCM RX", + .stream_name = "AFE-PROXY RX", + .cpu_dai_name = "msm-dai-q6-dev.241", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .platform_name = "msm-pcm-afe", + .dpcm_playback = 1, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + }, + { + .name = "MSM AFE-PCM TX", + .stream_name = "AFE-PROXY TX", + .cpu_dai_name = "msm-dai-q6-dev.240", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .platform_name = "msm-pcm-afe", + .dpcm_capture = 1, + .ignore_suspend = 1, + }, + { + .name = MSM_DAILINK_NAME(Compress1), + .stream_name = "Compress1", + .cpu_dai_name = "MultiMedia4", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA4, + }, + { + .name = "AUXPCM Hostless", + .stream_name = "AUXPCM Hostless", + .cpu_dai_name = "AUXPCM_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_1 Hostless", + .stream_name = "SLIMBUS_1 Hostless", + .cpu_dai_name = "SLIMBUS1_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_3 Hostless", + .stream_name = "SLIMBUS_3 Hostless", + .cpu_dai_name = "SLIMBUS3_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_4 Hostless", + .stream_name = "SLIMBUS_4 Hostless", + .cpu_dai_name = "SLIMBUS4_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = MSM_DAILINK_NAME(LowLatency), + .stream_name = "MultiMedia5", + .cpu_dai_name = "MultiMedia5", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + }, + { + .name = "Listen 1 Audio Service", + .stream_name = "Listen 1 Audio Service", + .cpu_dai_name = "LSM1", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM1, + }, + /* Multiple Tunnel instances */ + { + .name = MSM_DAILINK_NAME(Compress2), + .stream_name = "Compress2", + .cpu_dai_name = "MultiMedia7", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA7, + }, + { + .name = MSM_DAILINK_NAME(Compress3), + .stream_name = "Compress3", + .cpu_dai_name = "MultiMedia10", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA10, + }, + { + .name = MSM_DAILINK_NAME(ULL_NOIRQ), + .stream_name = "MM_NOIRQ", + .cpu_dai_name = "MultiMedia8", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + }, + /* HDMI Hostless */ + { + .name = "HDMI_RX_HOSTLESS", + .stream_name = "HDMI_RX_HOSTLESS", + .cpu_dai_name = "HDMI_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "VoiceMMode2", + .stream_name = "VoiceMMode2", + .cpu_dai_name = "VoiceMMode2", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE2, + }, + /* LSM FE */ + { + .name = "Listen 2 Audio Service", + .stream_name = "Listen 2 Audio Service", + .cpu_dai_name = "LSM2", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM2, + }, + { + .name = "Listen 3 Audio Service", + .stream_name = "Listen 3 Audio Service", + .cpu_dai_name = "LSM3", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM3, + }, + { + .name = "Listen 4 Audio Service", + .stream_name = "Listen 4 Audio Service", + .cpu_dai_name = "LSM4", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM4, + }, + { + .name = "Listen 5 Audio Service", + .stream_name = "Listen 5 Audio Service", + .cpu_dai_name = "LSM5", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM5, + }, + { + .name = "Listen 6 Audio Service", + .stream_name = "Listen 6 Audio Service", + .cpu_dai_name = "LSM6", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM6, + }, + { + .name = "Listen 7 Audio Service", + .stream_name = "Listen 7 Audio Service", + .cpu_dai_name = "LSM7", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM7, + }, + { + .name = "Listen 8 Audio Service", + .stream_name = "Listen 8 Audio Service", + .cpu_dai_name = "LSM8", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM8, + }, + { + .name = MSM_DAILINK_NAME(Media9), + .stream_name = "MultiMedia9", + .cpu_dai_name = "MultiMedia9", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA9, + }, + { + .name = MSM_DAILINK_NAME(Compress4), + .stream_name = "Compress4", + .cpu_dai_name = "MultiMedia11", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA11, + }, + { + .name = MSM_DAILINK_NAME(Compress5), + .stream_name = "Compress5", + .cpu_dai_name = "MultiMedia12", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA12, + }, + { + .name = MSM_DAILINK_NAME(Compress6), + .stream_name = "Compress6", + .cpu_dai_name = "MultiMedia13", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA13, + }, + { + .name = MSM_DAILINK_NAME(Compress7), + .stream_name = "Compress7", + .cpu_dai_name = "MultiMedia14", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA14, + }, + { + .name = MSM_DAILINK_NAME(Compress8), + .stream_name = "Compress8", + .cpu_dai_name = "MultiMedia15", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA15, + }, + { + .name = MSM_DAILINK_NAME(Compress9), + .stream_name = "Compress9", + .cpu_dai_name = "MultiMedia16", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA16, + }, + { + .name = "SLIMBUS_8 Hostless", + .stream_name = "SLIMBUS8_HOSTLESS Capture", + .cpu_dai_name = "SLIMBUS8_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +}; + +static struct snd_soc_dai_link msm_tasha_fe_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_4_TX, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_vifeedback", + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + }, + /* Ultrasound RX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Playback", + .stream_name = "SLIMBUS_2 Hostless Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx2", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_slimbus_2_be_ops, + }, + /* Ultrasound TX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Capture", + .stream_name = "SLIMBUS_2 Hostless Capture", + .cpu_dai_name = "msm-dai-q6-dev.16389", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx2", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_slimbus_2_be_ops, + }, + /* CPE LSM direct dai-link */ + { + .name = "CPE Listen service", + .stream_name = "CPE Listen Audio Service", + .cpu_dai_name = "msm-dai-slim", + .platform_name = "msm-cpe-lsm", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "tasha_mad1", + .codec_name = "tasha_codec", + .ops = &msm_cpe_ops, + }, + { + .name = "SLIMBUS_6 Hostless Playback", + .stream_name = "SLIMBUS_6 Hostless", + .cpu_dai_name = "SLIMBUS6_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + /* CPE LSM EC PP direct dai-link */ + { + .name = "CPE Listen service ECPP", + .stream_name = "CPE Listen Audio Service ECPP", + .cpu_dai_name = "CPE_LSM_NOHOST", + .platform_name = "msm-cpe-lsm.3", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "tasha_cpe", + .codec_name = "tasha_codec", + }, +}; + +static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_4_TX, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_vifeedback", + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + }, + /* Ultrasound RX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Playback", + .stream_name = "SLIMBUS_2 Hostless Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx2", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_slimbus_2_be_ops, + }, + /* Ultrasound TX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Capture", + .stream_name = "SLIMBUS_2 Hostless Capture", + .cpu_dai_name = "msm-dai-q6-dev.16389", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx2", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_slimbus_2_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { + { + .name = MSM_DAILINK_NAME(ASM Loopback), + .stream_name = "MultiMedia6", + .cpu_dai_name = "MultiMedia6", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA6, + }, + { + .name = "USB Audio Hostless", + .stream_name = "USB Audio Hostless", + .cpu_dai_name = "USBAUDIO_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = MSM_DAILINK_NAME(Transcode Loopback Playback), + .stream_name = "Transcode Loopback Playback", + .cpu_dai_name = "MultiMedia14", + .platform_name = "msm-transcode-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA14, + }, + { + .name = MSM_DAILINK_NAME(Transcode Loopback Capture), + .stream_name = "Transcode Loopback Capture", + .cpu_dai_name = "MultiMedia18", + .platform_name = "msm-transcode-loopback", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA18, + }, +}; + +static struct snd_soc_dai_link msm_common_be_dai_links[] = { + /* Backend AFE DAI Links */ + { + .name = LPASS_BE_AFE_PCM_RX, + .stream_name = "AFE Playback", + .cpu_dai_name = "msm-dai-q6-dev.224", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AFE_PCM_TX, + .stream_name = "AFE Capture", + .cpu_dai_name = "msm-dai-q6-dev.225", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Uplink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_TX, + .stream_name = "Voice Uplink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32772", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Downlink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_RX, + .stream_name = "Voice Downlink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32771", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music BACK END DAI Link */ + { + .name = LPASS_BE_VOICE_PLAYBACK_TX, + .stream_name = "Voice Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32773", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music 2 BACK END DAI Link */ + { + .name = LPASS_BE_VOICE2_PLAYBACK_TX, + .stream_name = "Voice2 Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32770", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_RX, + .stream_name = "USB Audio Playback", + .cpu_dai_name = "msm-dai-q6-dev.28672", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_USB_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_TX, + .stream_name = "USB Audio Capture", + .cpu_dai_name = "msm-dai-q6-dev.28673", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_USB_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_0, + .stream_name = "Primary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36864", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_0, + .stream_name = "Primary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36865", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_0, + .stream_name = "Secondary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36880", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_0, + .stream_name = "Secondary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36881", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_0, + .stream_name = "Tertiary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36896", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_0, + .stream_name = "Tertiary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36897", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_0, + .stream_name = "Quaternary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36912", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8998_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_0, + .stream_name = "Quaternary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36913", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_tasha_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_init, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_1_RX, + .stream_name = "Slimbus1 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16386", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_1_TX, + .stream_name = "Slimbus1 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16387", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx3", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_RX, + .stream_name = "Slimbus3 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16390", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_TX, + .stream_name = "Slimbus3 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16391", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_4_RX, + .stream_name = "Slimbus4 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16392", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_5_RX, + .stream_name = "Slimbus5 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16394", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx3", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* MAD BE */ + { + .name = LPASS_BE_SLIMBUS_5_TX, + .stream_name = "Slimbus5 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16395", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mad1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_6_RX, + .stream_name = "Slimbus6 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16396", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx4", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* Slimbus VI Recording */ + { + .name = LPASS_BE_SLIMBUS_TX_VI, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_vifeedback", + .be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + .no_pcm = 1, + .dpcm_capture = 1, + .ignore_pmdown_time = 1, + }, +}; + +static struct snd_soc_dai_link msm_tavil_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_init, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_1_RX, + .stream_name = "Slimbus1 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16386", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_1_TX, + .stream_name = "Slimbus1 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16387", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx3", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_2_RX, + .stream_name = "Slimbus2 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx2", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_2_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_RX, + .stream_name = "Slimbus3 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16390", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_TX, + .stream_name = "Slimbus3 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16391", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_4_RX, + .stream_name = "Slimbus4 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16392", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_5_RX, + .stream_name = "Slimbus5 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16394", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx3", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* MAD BE */ + { + .name = LPASS_BE_SLIMBUS_5_TX, + .stream_name = "Slimbus5 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16395", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_mad1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_6_RX, + .stream_name = "Slimbus6 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16396", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx4", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* Slimbus VI Recording */ + { + .name = LPASS_BE_SLIMBUS_TX_VI, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_vifeedback", + .be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + .no_pcm = 1, + .dpcm_capture = 1, + .ignore_pmdown_time = 1, + }, +}; + +static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_7_RX, + .stream_name = "Slimbus7 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16398", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + /* BT codec driver determines capabilities based on + * dai name, bt codecdai name should always contains + * supported usecase information + */ + .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_7_TX, + .stream_name = "Slimbus7 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16399", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_bt_sco_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_8_TX, + .stream_name = "Slimbus8 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16401", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_fm_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_8_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .init = &msm_wcn_init, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link ext_disp_be_dai_link[] = { + /* HDMI BACK END DAI Link */ + { + .name = LPASS_BE_HDMI, + .stream_name = "HDMI Playback", + .cpu_dai_name = "msm-dai-q6-hdmi.8", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-ext-disp-audio-codec-rx", + .codec_dai_name = "msm_hdmi_audio_codec_rx_dai", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_HDMI_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* DISP PORT BACK END DAI Link */ + { + .name = LPASS_BE_DISPLAY_PORT, + .stream_name = "Display Port Playback", + .cpu_dai_name = "msm-dai-q6-dp.24608", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-ext-disp-audio-codec-rx", + .codec_dai_name = "msm_dp_audio_codec_rx_dai", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { + { + .name = LPASS_BE_PRI_MI2S_RX, + .stream_name = "Primary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_MI2S_TX, + .stream_name = "Primary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX, + .stream_name = "Secondary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX, + .stream_name = "Secondary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX, + .stream_name = "Tertiary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX, + .stream_name = "Tertiary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX, + .stream_name = "Quaternary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { + /* Primary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_AUXPCM_RX, + .stream_name = "AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_AUXPCM_TX, + .stream_name = "AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Secondary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_SEC_AUXPCM_RX, + .stream_name = "Sec AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_SEC_AUXPCM_TX, + .stream_name = "Sec AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Tertiary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_TERT_AUXPCM_RX, + .stream_name = "Tert AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_TERT_AUXPCM_TX, + .stream_name = "Tert AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Quaternary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUAT_AUXPCM_RX, + .stream_name = "Quat AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_QUAT_AUXPCM_TX, + .stream_name = "Quat AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .ops = &msm_aux_pcm_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_tasha_dai_links[ + ARRAY_SIZE(msm_common_dai_links) + + ARRAY_SIZE(msm_tasha_fe_dai_links) + + ARRAY_SIZE(msm_common_misc_fe_dai_links) + + ARRAY_SIZE(msm_common_be_dai_links) + + ARRAY_SIZE(msm_tasha_be_dai_links) + + ARRAY_SIZE(msm_wcn_be_dai_links) + + ARRAY_SIZE(ext_disp_be_dai_link) + + ARRAY_SIZE(msm_mi2s_be_dai_links) + + ARRAY_SIZE(msm_auxpcm_be_dai_links)]; + +static struct snd_soc_dai_link msm_tavil_dai_links[ + ARRAY_SIZE(msm_common_dai_links) + + ARRAY_SIZE(msm_tavil_fe_dai_links) + + ARRAY_SIZE(msm_common_misc_fe_dai_links) + + ARRAY_SIZE(msm_common_be_dai_links) + + ARRAY_SIZE(msm_tavil_be_dai_links) + + ARRAY_SIZE(msm_wcn_be_dai_links) + + ARRAY_SIZE(ext_disp_be_dai_link) + + ARRAY_SIZE(msm_mi2s_be_dai_links) + + ARRAY_SIZE(msm_auxpcm_be_dai_links)]; + +static int msm_snd_card_late_probe(struct snd_soc_card *card) +{ + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + void *mbhc_calibration; + + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err_pcm_runtime; + } + + mbhc_calibration = def_tasha_mbhc_cal(); + if (!mbhc_calibration) { + ret = -ENOMEM; + goto err_mbhc_cal; + } + wcd_mbhc_cfg.calibration = mbhc_calibration; + ret = tasha_mbhc_hs_detect(rtd->codec, &wcd_mbhc_cfg); + if (ret) { + dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", + __func__, ret); + goto err_hs_detect; + } + return 0; + +err_hs_detect: + kfree(mbhc_calibration); +err_mbhc_cal: +err_pcm_runtime: + return ret; +} + +static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) +{ + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + void *mbhc_calibration; + + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err_pcm_runtime; + } + + mbhc_calibration = def_tavil_mbhc_cal(); + if (!mbhc_calibration) { + ret = -ENOMEM; + goto err_mbhc_cal; + } + wcd_mbhc_cfg.calibration = mbhc_calibration; + ret = tavil_mbhc_hs_detect(rtd->codec, &wcd_mbhc_cfg); + if (ret) { + dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", + __func__, ret); + goto err_hs_detect; + } + return 0; + +err_hs_detect: + kfree(mbhc_calibration); +err_mbhc_cal: +err_pcm_runtime: + return ret; +} + +struct snd_soc_card snd_soc_card_tasha_msm = { + .name = "msm8998-tasha-snd-card", + .late_probe = msm_snd_card_late_probe, +}; + +struct snd_soc_card snd_soc_card_tavil_msm = { + .name = "msm8998-tavil-snd-card", + .late_probe = msm_snd_card_tavil_late_probe, +}; + +static int msm_populate_dai_link_component_of_node( + struct snd_soc_card *card) +{ + int i, index, ret = 0; + struct device *cdev = card->dev; + struct snd_soc_dai_link *dai_link = card->dai_link; + struct device_node *np; + + if (!cdev) { + pr_err("%s: Sound card device memory NULL\n", __func__); + return -ENODEV; + } + + for (i = 0; i < card->num_links; i++) { + if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) + continue; + + /* populate platform_of_node for snd card dai links */ + if (dai_link[i].platform_name && + !dai_link[i].platform_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-platform-names", + dai_link[i].platform_name); + if (index < 0) { + pr_err("%s: No match found for platform name: %s\n", + __func__, dai_link[i].platform_name); + ret = index; + goto err; + } + np = of_parse_phandle(cdev->of_node, "asoc-platform", + index); + if (!np) { + pr_err("%s: retrieving phandle for platform %s, index %d failed\n", + __func__, dai_link[i].platform_name, + index); + ret = -ENODEV; + goto err; + } + dai_link[i].platform_of_node = np; + dai_link[i].platform_name = NULL; + } + + /* populate cpu_of_node for snd card dai links */ + if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-cpu-names", + dai_link[i].cpu_dai_name); + if (index >= 0) { + np = of_parse_phandle(cdev->of_node, "asoc-cpu", + index); + if (!np) { + pr_err("%s: retrieving phandle for cpu dai %s failed\n", + __func__, + dai_link[i].cpu_dai_name); + ret = -ENODEV; + goto err; + } + dai_link[i].cpu_of_node = np; + dai_link[i].cpu_dai_name = NULL; + } + } + + /* populate codec_of_node for snd card dai links */ + if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-codec-names", + dai_link[i].codec_name); + if (index < 0) + continue; + np = of_parse_phandle(cdev->of_node, "asoc-codec", + index); + if (!np) { + pr_err("%s: retrieving phandle for codec %s failed\n", + __func__, dai_link[i].codec_name); + ret = -ENODEV; + goto err; + } + dai_link[i].codec_of_node = np; + dai_link[i].codec_name = NULL; + } + } + +err: + return ret; +} + +static int msm_prepare_us_euro(struct snd_soc_card *card) +{ + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + int ret = 0; + + if (pdata->us_euro_gpio >= 0) { + dev_dbg(card->dev, "%s: us_euro gpio request %d", __func__, + pdata->us_euro_gpio); + ret = gpio_request(pdata->us_euro_gpio, "TASHA_CODEC_US_EURO"); + if (ret) { + dev_err(card->dev, + "%s: Failed to request codec US/EURO gpio %d error %d\n", + __func__, pdata->us_euro_gpio, ret); + } + } + + return ret; +} + +static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + + ret = snd_soc_add_codec_controls(codec, msm_snd_controls, + ARRAY_SIZE(msm_snd_controls)); + if (ret < 0) { + dev_err(codec->dev, "%s: add_codec_controls failed, err%d\n", + __func__, ret); + return ret; + } + + snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, + ARRAY_SIZE(msm_dapm_widgets)); + + return 0; +} + +static int msm_snd_stub_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + + int ret = 0; + unsigned int rx_ch[] = {144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156}; + unsigned int tx_ch[] = {128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143}; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + slim_rx_cfg[0].channels, + rx_ch); + if (ret < 0) + pr_err("%s: RX failed to set cpu chan map error %d\n", + __func__, ret); + } else { + ret = snd_soc_dai_set_channel_map(cpu_dai, + slim_tx_cfg[0].channels, + tx_ch, 0, 0); + if (ret < 0) + pr_err("%s: TX failed to set cpu chan map error %d\n", + __func__, ret); + } + + return ret; +} + +static struct snd_soc_ops msm_stub_be_ops = { + .hw_params = msm_snd_stub_hw_params, +}; + +static struct snd_soc_dai_link msm_stub_fe_dai_links[] = { + + /* FrontEnd DAI Links */ + { + .name = "MSMSTUB Media1", + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, +}; + +static struct snd_soc_dai_link msm_stub_be_dai_links[] = { + + /* Backend DAI Links */ + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_stub_init, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, /* dai link has playback support */ + .ignore_suspend = 1, + .ops = &msm_stub_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_stub_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_stub_dai_links[ + ARRAY_SIZE(msm_stub_fe_dai_links) + + ARRAY_SIZE(msm_stub_be_dai_links)]; + +struct snd_soc_card snd_soc_card_stub_msm = { + .name = "msm8998-stub-snd-card", +}; + +static const struct of_device_id msm8998_asoc_machine_of_match[] = { + { .compatible = "qcom,msm8998-asoc-snd-tasha", + .data = "tasha_codec"}, + { .compatible = "qcom,msm8998-asoc-snd-tavil", + .data = "tavil_codec"}, + { .compatible = "qcom,msm8998-asoc-snd-stub", + .data = "stub_codec"}, + {}, +}; + +static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) +{ + struct snd_soc_card *card = NULL; + struct snd_soc_dai_link *dailink; + int len_1, len_2, len_3, len_4; + int total_links; + const struct of_device_id *match; + + match = of_match_node(msm8998_asoc_machine_of_match, dev->of_node); + if (!match) { + dev_err(dev, "%s: No DT match found for sound card\n", + __func__); + return NULL; + } + + if (!strcmp(match->data, "tasha_codec")) { + card = &snd_soc_card_tasha_msm; + len_1 = ARRAY_SIZE(msm_common_dai_links); + len_2 = len_1 + ARRAY_SIZE(msm_tasha_fe_dai_links); + len_3 = len_2 + ARRAY_SIZE(msm_common_misc_fe_dai_links); + len_4 = len_3 + ARRAY_SIZE(msm_common_be_dai_links); + total_links = len_4 + ARRAY_SIZE(msm_tasha_be_dai_links); + memcpy(msm_tasha_dai_links, + msm_common_dai_links, + sizeof(msm_common_dai_links)); + memcpy(msm_tasha_dai_links + len_1, + msm_tasha_fe_dai_links, + sizeof(msm_tasha_fe_dai_links)); + memcpy(msm_tasha_dai_links + len_2, + msm_common_misc_fe_dai_links, + sizeof(msm_common_misc_fe_dai_links)); + memcpy(msm_tasha_dai_links + len_3, + msm_common_be_dai_links, + sizeof(msm_common_be_dai_links)); + memcpy(msm_tasha_dai_links + len_4, + msm_tasha_be_dai_links, + sizeof(msm_tasha_be_dai_links)); + + if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + dev_dbg(dev, "%s(): WCN BTFM support present\n", + __func__); + memcpy(msm_tasha_dai_links + total_links, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + total_links += ARRAY_SIZE(msm_wcn_be_dai_links); + } + + if (of_property_read_bool(dev->of_node, + "qcom,ext-disp-audio-rx")) { + dev_dbg(dev, "%s(): External display audio support present\n", + __func__); + memcpy(msm_tasha_dai_links + total_links, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + total_links += ARRAY_SIZE(ext_disp_be_dai_link); + } + if (of_property_read_bool(dev->of_node, + "qcom,mi2s-audio-intf")) { + memcpy(msm_tasha_dai_links + total_links, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,auxpcm-audio-intf")) { + memcpy(msm_tasha_dai_links + total_links, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + dailink = msm_tasha_dai_links; + } else if (!strcmp(match->data, "tavil_codec")) { + card = &snd_soc_card_tavil_msm; + len_1 = ARRAY_SIZE(msm_common_dai_links); + len_2 = len_1 + ARRAY_SIZE(msm_tavil_fe_dai_links); + len_3 = len_2 + ARRAY_SIZE(msm_common_misc_fe_dai_links); + len_4 = len_3 + ARRAY_SIZE(msm_common_be_dai_links); + total_links = len_4 + ARRAY_SIZE(msm_tavil_be_dai_links); + memcpy(msm_tavil_dai_links, + msm_common_dai_links, + sizeof(msm_common_dai_links)); + memcpy(msm_tavil_dai_links + len_1, + msm_tavil_fe_dai_links, + sizeof(msm_tavil_fe_dai_links)); + memcpy(msm_tavil_dai_links + len_2, + msm_common_misc_fe_dai_links, + sizeof(msm_common_misc_fe_dai_links)); + memcpy(msm_tavil_dai_links + len_3, + msm_common_be_dai_links, + sizeof(msm_common_be_dai_links)); + memcpy(msm_tavil_dai_links + len_4, + msm_tavil_be_dai_links, + sizeof(msm_tavil_be_dai_links)); + + if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + dev_dbg(dev, "%s(): WCN BTFM support present\n", + __func__); + memcpy(msm_tavil_dai_links + total_links, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + total_links += ARRAY_SIZE(msm_wcn_be_dai_links); + } + + if (of_property_read_bool(dev->of_node, + "qcom,ext-disp-audio-rx")) { + dev_dbg(dev, "%s(): ext disp audio support present\n", + __func__); + memcpy(msm_tavil_dai_links + total_links, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + total_links += ARRAY_SIZE(ext_disp_be_dai_link); + } + if (of_property_read_bool(dev->of_node, + "qcom,mi2s-audio-intf")) { + memcpy(msm_tavil_dai_links + total_links, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,auxpcm-audio-intf")) { + memcpy(msm_tavil_dai_links + total_links, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + dailink = msm_tavil_dai_links; + } else if (!strcmp(match->data, "stub_codec")) { + card = &snd_soc_card_stub_msm; + len_1 = ARRAY_SIZE(msm_stub_fe_dai_links); + len_2 = len_1 + ARRAY_SIZE(msm_stub_be_dai_links); + + memcpy(msm_stub_dai_links, + msm_stub_fe_dai_links, + sizeof(msm_stub_fe_dai_links)); + memcpy(msm_stub_dai_links + len_1, + msm_stub_be_dai_links, + sizeof(msm_stub_be_dai_links)); + + dailink = msm_stub_dai_links; + total_links = len_2; + } + + if (card) { + card->dai_link = dailink; + card->num_links = total_links; + } + + return card; +} + +static int msm_wsa881x_init(struct snd_soc_component *component) +{ + u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106}; + u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107}; + unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; + unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + struct msm_asoc_mach_data *pdata; + struct snd_soc_dapm_context *dapm; + int ret = 0; + + if (!codec) { + pr_err("%s codec is NULL\n", __func__); + return -EINVAL; + } + + dapm = snd_soc_codec_get_dapm(codec); + + if (!strcmp(component->name_prefix, "SpkrLeft")) { + dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n", + __func__, codec->component.name); + wsa881x_set_channel_map(codec, &spkleft_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0]); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); + } + } else if (!strcmp(component->name_prefix, "SpkrRight")) { + dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n", + __func__, codec->component.name); + wsa881x_set_channel_map(codec, &spkright_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0]); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); + } + } else { + dev_err(codec->dev, "%s: wrong codec name %s\n", __func__, + codec->component.name); + ret = -EINVAL; + goto err_codec; + } + pdata = snd_soc_card_get_drvdata(component->card); + if (pdata && pdata->codec_root) + wsa881x_codec_info_create_codec_entry(pdata->codec_root, + codec); + +err_codec: + return ret; +} + +static int msm_init_wsa_dev(struct platform_device *pdev, + struct snd_soc_card *card) +{ + struct device_node *wsa_of_node; + u32 wsa_max_devs; + u32 wsa_dev_cnt; + int i; + struct msm_wsa881x_dev_info *wsa881x_dev_info; + const char *wsa_auxdev_name_prefix[1]; + char *dev_name_str = NULL; + int found = 0; + int ret = 0; + + /* Get maximum WSA device count for this platform */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,wsa-max-devs", &wsa_max_devs); + if (ret) { + dev_dbg(&pdev->dev, + "%s: wsa-max-devs property missing in DT %s, ret = %d\n", + __func__, pdev->dev.of_node->full_name, ret); + goto err_dt; + } + if (wsa_max_devs == 0) { + dev_warn(&pdev->dev, + "%s: Max WSA devices is 0 for this target?\n", + __func__); + goto err_dt; + } + + /* Get count of WSA device phandles for this platform */ + wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node, + "qcom,wsa-devs", NULL); + if (wsa_dev_cnt == -ENOENT) { + dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n", + __func__); + goto err_dt; + } else if (wsa_dev_cnt <= 0) { + dev_err(&pdev->dev, + "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n", + __func__, wsa_dev_cnt); + ret = -EINVAL; + goto err_dt; + } + + /* + * Expect total phandles count to be NOT less than maximum possible + * WSA count. However, if it is less, then assign same value to + * max count as well. + */ + if (wsa_dev_cnt < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n", + __func__, wsa_max_devs, wsa_dev_cnt); + wsa_max_devs = wsa_dev_cnt; + } + + /* Make sure prefix string passed for each WSA device */ + ret = of_property_count_strings(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix"); + if (ret != wsa_dev_cnt) { + dev_err(&pdev->dev, + "%s: expecting %d wsa prefix. Defined only %d in DT\n", + __func__, wsa_dev_cnt, ret); + ret = -EINVAL; + goto err_dt; + } + + /* + * Alloc mem to store phandle and index info of WSA device, if already + * registered with ALSA core + */ + wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs, + sizeof(struct msm_wsa881x_dev_info), + GFP_KERNEL); + if (!wsa881x_dev_info) { + ret = -ENOMEM; + goto err_mem; + } + + /* + * search and check whether all WSA devices are already + * registered with ALSA core or not. If found a node, store + * the node and the index in a local array of struct for later + * use. + */ + for (i = 0; i < wsa_dev_cnt; i++) { + wsa_of_node = of_parse_phandle(pdev->dev.of_node, + "qcom,wsa-devs", i); + if (unlikely(!wsa_of_node)) { + /* we should not be here */ + dev_err(&pdev->dev, + "%s: wsa dev node is not present\n", + __func__); + ret = -EINVAL; + goto err_dev_node; + } + if (soc_find_component(wsa_of_node, NULL)) { + /* WSA device registered with ALSA core */ + wsa881x_dev_info[found].of_node = wsa_of_node; + wsa881x_dev_info[found].index = i; + found++; + if (found == wsa_max_devs) + break; + } + } + + if (found < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: failed to find %d components. Found only %d\n", + __func__, wsa_max_devs, found); + return -EPROBE_DEFER; + } + dev_info(&pdev->dev, + "%s: found %d wsa881x devices registered with ALSA core\n", + __func__, found); + + card->num_aux_devs = wsa_max_devs; + card->num_configs = wsa_max_devs; + + /* Alloc array of AUX devs struct */ + msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_aux_dev), + GFP_KERNEL); + if (!msm_aux_dev) { + ret = -ENOMEM; + goto err_auxdev_mem; + } + + /* Alloc array of codec conf struct */ + msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_codec_conf), + GFP_KERNEL); + if (!msm_codec_conf) { + ret = -ENOMEM; + goto err_codec_conf; + } + + for (i = 0; i < card->num_aux_devs; i++) { + dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN, + GFP_KERNEL); + if (!dev_name_str) { + ret = -ENOMEM; + goto err_dev_str; + } + + ret = of_property_read_string_index(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix", + wsa881x_dev_info[i].index, + wsa_auxdev_name_prefix); + if (ret) { + dev_err(&pdev->dev, + "%s: failed to read wsa aux dev prefix, ret = %d\n", + __func__, ret); + ret = -EINVAL; + goto err_dt_prop; + } + + snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i); + msm_aux_dev[i].name = dev_name_str; + msm_aux_dev[i].codec_name = NULL; + msm_aux_dev[i].codec_of_node = + wsa881x_dev_info[i].of_node; + msm_aux_dev[i].init = msm_wsa881x_init; + msm_codec_conf[i].dev_name = NULL; + msm_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0]; + msm_codec_conf[i].of_node = + wsa881x_dev_info[i].of_node; + } + card->codec_conf = msm_codec_conf; + card->aux_dev = msm_aux_dev; + + return 0; + +err_dt_prop: + devm_kfree(&pdev->dev, dev_name_str); +err_dev_str: + devm_kfree(&pdev->dev, msm_codec_conf); +err_codec_conf: + devm_kfree(&pdev->dev, msm_aux_dev); +err_auxdev_mem: +err_dev_node: + devm_kfree(&pdev->dev, wsa881x_dev_info); +err_mem: +err_dt: + return ret; +} + +static void i2s_auxpcm_init(struct platform_device *pdev) +{ + struct resource *muxsel; + int count; + u32 mi2s_master_slave[MI2S_MAX]; + int ret; + char *str[PCM_I2S_SEL_MAX] = { + "lpaif_pri_mode_muxsel", + "lpaif_sec_mode_muxsel", + "lpaif_tert_mode_muxsel", + "lpaif_quat_mode_muxsel" + }; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_init(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + } + + for (count = 0; count < AUX_PCM_MAX; count++) { + mutex_init(&auxpcm_intf_conf[count].lock); + auxpcm_intf_conf[count].ref_cnt = 0; + } + + for (count = 0; count < PCM_I2S_SEL_MAX; count++) { + mutex_init(&mi2s_auxpcm_conf[count].lock); + mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr = NULL; + } + + for (count = 0; count < PCM_I2S_SEL_MAX; count++) { + muxsel = platform_get_resource_byname(pdev, IORESOURCE_MEM, + str[count]); + if (muxsel) { + mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr + = ioremap(muxsel->start, resource_size(muxsel)); + } + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-master", + mi2s_master_slave, MI2S_MAX); + if (ret) { + dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n", + __func__); + } else { + for (count = 0; count < MI2S_MAX; count++) { + mi2s_intf_conf[count].msm_is_mi2s_master = + mi2s_master_slave[count]; + } + } +} + +static void i2s_auxpcm_deinit(void) +{ + int count; + + for (count = 0; count < PCM_I2S_SEL_MAX; count++) + if (mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr != + NULL) + iounmap( + mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr); +} + +static int msm_asoc_machine_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card; + struct msm_asoc_mach_data *pdata; + const char *mbhc_audio_jack_type = NULL; + char *mclk_freq_prop_name; + const struct of_device_id *match; + int ret; + + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, "No platform supplied from device tree\n"); + return -EINVAL; + } + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct msm_asoc_mach_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + card = populate_snd_card_dailinks(&pdev->dev); + if (!card) { + dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); + ret = -EINVAL; + goto err; + } + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, pdata); + + ret = snd_soc_of_parse_card_name(card, "qcom,model"); + if (ret) { + dev_err(&pdev->dev, "parse card name failed, err:%d\n", + ret); + goto err; + } + + ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing"); + if (ret) { + dev_err(&pdev->dev, "parse audio routing failed, err:%d\n", + ret); + goto err; + } + + match = of_match_node(msm8998_asoc_machine_of_match, + pdev->dev.of_node); + if (!match) { + dev_err(&pdev->dev, "%s: no matched codec is found.\n", + __func__); + goto err; + } + + if (!strcmp(match->data, "tasha_codec")) + mclk_freq_prop_name = "qcom,tasha-mclk-clk-freq"; + else + mclk_freq_prop_name = "qcom,tavil-mclk-clk-freq"; + + ret = of_property_read_u32(pdev->dev.of_node, + mclk_freq_prop_name, &pdata->mclk_freq); + if (ret) { + dev_err(&pdev->dev, + "Looking up %s property in node %s failed, err%d\n", + mclk_freq_prop_name, + pdev->dev.of_node->full_name, ret); + goto err; + } + + if (pdata->mclk_freq != CODEC_EXT_CLK_RATE) { + dev_err(&pdev->dev, "unsupported mclk freq %u\n", + pdata->mclk_freq); + ret = -EINVAL; + goto err; + } + + ret = msm_populate_dai_link_component_of_node(card); + if (ret) { + ret = -EPROBE_DEFER; + goto err; + } + ret = msm_init_wsa_dev(pdev, card); + if (ret) + goto err; + + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret == -EPROBE_DEFER) { + if (codec_reg_done) + ret = -EINVAL; + goto err; + } else if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); + goto err; + } + dev_info(&pdev->dev, "Sound card %s registered\n", card->name); + spdev = pdev; + + ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); + if (ret) { + dev_dbg(&pdev->dev, "%s: failed to add child nodes, ret=%d\n", + __func__, ret); + } else { + pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en1-gpio", 0); + if (!pdata->hph_en1_gpio_p) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,hph-en1-gpio", + pdev->dev.of_node->full_name); + } + + pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en0-gpio", 0); + if (!pdata->hph_en0_gpio_p) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,hph-en0-gpio", + pdev->dev.of_node->full_name); + } + } + + ret = of_property_read_string(pdev->dev.of_node, + "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type); + if (ret) { + dev_dbg(&pdev->dev, "Looking up %s property in node %s failed", + "qcom,mbhc-audio-jack-type", + pdev->dev.of_node->full_name); + dev_dbg(&pdev->dev, "Jack type properties set to default"); + } else { + if (!strcmp(mbhc_audio_jack_type, "4-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = false; + dev_dbg(&pdev->dev, "This hardware has 4 pole jack"); + } else if (!strcmp(mbhc_audio_jack_type, "5-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = true; + dev_dbg(&pdev->dev, "This hardware has 5 pole jack"); + } else if (!strcmp(mbhc_audio_jack_type, "6-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = true; + dev_dbg(&pdev->dev, "This hardware has 6 pole jack"); + } else { + wcd_mbhc_cfg.enable_anc_mic_detect = false; + dev_dbg(&pdev->dev, "Unknown value, set to default"); + } + } + /* + * Parse US-Euro gpio info from DT. Report no error if us-euro + * entry is not found in DT file as some targets do not support + * US-Euro detection + */ + pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,us-euro-gpios", 0); + if (!gpio_is_valid(pdata->us_euro_gpio)) + pdata->us_euro_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,us-euro-gpios", 0); + if (!gpio_is_valid(pdata->us_euro_gpio) && (!pdata->us_euro_gpio_p)) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,us-euro-gpios", pdev->dev.of_node->full_name); + } else { + dev_dbg(&pdev->dev, "%s detected", + "qcom,us-euro-gpios"); + wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; + } + + ret = msm_prepare_us_euro(card); + if (ret) + dev_dbg(&pdev->dev, "msm_prepare_us_euro failed (%d)\n", + ret); + + /* Parse pinctrl info from devicetree */ + ret = msm_get_pinctrl(pdev); + if (!ret) { + pr_debug("%s: pinctrl parsing successful\n", __func__); + } else { + dev_dbg(&pdev->dev, + "%s: Parsing pinctrl failed with %d. Cannot use Ports\n", + __func__, ret); + ret = 0; + } + + i2s_auxpcm_init(pdev); + + is_initial_boot = true; + ret = audio_notifier_register("msm8998", AUDIO_NOTIFIER_ADSP_DOMAIN, + &service_nb); + if (ret < 0) + pr_err("%s: Audio notifier register failed ret = %d\n", + __func__, ret); + + return 0; +err: + if (pdata->us_euro_gpio > 0) { + dev_dbg(&pdev->dev, "%s free us_euro gpio %d\n", + __func__, pdata->us_euro_gpio); + gpio_free(pdata->us_euro_gpio); + pdata->us_euro_gpio = 0; + } + msm_release_pinctrl(pdev); + devm_kfree(&pdev->dev, pdata); + return ret; +} + +static int msm_asoc_machine_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + + if (gpio_is_valid(pdata->us_euro_gpio)) + gpio_free(pdata->us_euro_gpio); + i2s_auxpcm_deinit(); + + snd_soc_unregister_card(card); + audio_notifier_deregister("msm8998"); + return 0; +} + +static struct platform_driver msm8998_asoc_machine_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = msm8998_asoc_machine_of_match, + }, + .probe = msm_asoc_machine_probe, + .remove = msm_asoc_machine_remove, +}; +module_platform_driver(msm8998_asoc_machine_driver); + +MODULE_DESCRIPTION("ALSA SoC msm"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, msm8998_asoc_machine_of_match); diff --git a/sound/soc/msm/qdsp6v2/Makefile b/sound/soc/msm/qdsp6v2/Makefile new file mode 100644 index 000000000000..da2b2c783a83 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/Makefile @@ -0,0 +1,19 @@ +snd-soc-qdsp6v2-objs += msm-dai-q6-v2.o msm-pcm-q6-v2.o \ + msm-pcm-routing-v2.o msm-compress-q6-v2.o \ + msm-pcm-afe-v2.o msm-pcm-voip-v2.o \ + msm-pcm-voice-v2.o msm-dai-q6-hdmi-v2.o \ + msm-lsm-client.o msm-pcm-host-voice-v2.o \ + msm-audio-effects-q6-v2.o msm-pcm-loopback-v2.o \ + msm-dai-slim.o msm-transcode-loopback-q6-v2.o \ + adsp_err.o +obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o msm-pcm-dtmf-v2.o \ + msm-dai-stub-v2.o +obj-$(CONFIG_SND_HWDEP) += msm-pcm-routing-devdep.o +obj-$(CONFIG_DOLBY_DAP) += msm-dolby-dap-config.o +obj-$(CONFIG_DOLBY_DS2) += msm-ds2-dap-config.o +obj-$(CONFIG_DOLBY_LICENSE) += msm-ds2-dap-config.o +obj-$(CONFIG_DTS_SRS_TM) += msm-dts-srs-tm-config.o +obj-$(CONFIG_QTI_PP) += msm-qti-pp-config.o +obj-y += audio_calibration.o audio_cal_utils.o q6adm.o q6afe.o q6asm.o \ + q6audio-v2.o q6voice.o q6core.o rtac.o q6lsm.o audio_slimslave.o \ + msm-pcm-q6-noirq.o diff --git a/sound/soc/msm/qdsp6v2/adsp_err.c b/sound/soc/msm/qdsp6v2/adsp_err.c new file mode 100644 index 000000000000..d17bd6ab58be --- /dev/null +++ b/sound/soc/msm/qdsp6v2/adsp_err.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + + +/* ERROR STRING */ +/* Success. The operation completed with no errors. */ +#define ADSP_EOK_STR "ADSP_EOK" +/* General failure. */ +#define ADSP_EFAILED_STR "ADSP_EFAILED" +/* Bad operation parameter. */ +#define ADSP_EBADPARAM_STR "ADSP_EBADPARAM" +/* Unsupported routine or operation. */ +#define ADSP_EUNSUPPORTED_STR "ADSP_EUNSUPPORTED" +/* Unsupported version. */ +#define ADSP_EVERSION_STR "ADSP_EVERSION" +/* Unexpected problem encountered. */ +#define ADSP_EUNEXPECTED_STR "ADSP_EUNEXPECTED" +/* Unhandled problem occurred. */ +#define ADSP_EPANIC_STR "ADSP_EPANIC" +/* Unable to allocate resource. */ +#define ADSP_ENORESOURCE_STR "ADSP_ENORESOURCE" +/* Invalid handle. */ +#define ADSP_EHANDLE_STR "ADSP_EHANDLE" +/* Operation is already processed. */ +#define ADSP_EALREADY_STR "ADSP_EALREADY" +/* Operation is not ready to be processed. */ +#define ADSP_ENOTREADY_STR "ADSP_ENOTREADY" +/* Operation is pending completion. */ +#define ADSP_EPENDING_STR "ADSP_EPENDING" +/* Operation could not be accepted or processed. */ +#define ADSP_EBUSY_STR "ADSP_EBUSY" +/* Operation aborted due to an error. */ +#define ADSP_EABORTED_STR "ADSP_EABORTED" +/* Operation preempted by a higher priority. */ +#define ADSP_EPREEMPTED_STR "ADSP_EPREEMPTED" +/* Operation requests intervention to complete. */ +#define ADSP_ECONTINUE_STR "ADSP_ECONTINUE" +/* Operation requests immediate intervention to complete. */ +#define ADSP_EIMMEDIATE_STR "ADSP_EIMMEDIATE" +/* Operation is not implemented. */ +#define ADSP_ENOTIMPL_STR "ADSP_ENOTIMPL" +/* Operation needs more data or resources. */ +#define ADSP_ENEEDMORE_STR "ADSP_ENEEDMORE" +/* Operation does not have memory. */ +#define ADSP_ENOMEMORY_STR "ADSP_ENOMEMORY" +/* Item does not exist. */ +#define ADSP_ENOTEXIST_STR "ADSP_ENOTEXIST" +/* Unexpected error code. */ +#define ADSP_ERR_MAX_STR "ADSP_ERR_MAX" + +#ifdef CONFIG_SND_SOC_QDSP_DEBUG +static bool adsp_err_panic; + +#ifdef CONFIG_DEBUG_FS +static struct dentry *debugfs_adsp_err; + +static ssize_t adsp_err_debug_write(struct file *filp, + const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char cmd; + + if (copy_from_user(&cmd, ubuf, 1)) + return -EFAULT; + + if (cmd == '0') + adsp_err_panic = false; + else + adsp_err_panic = true; + + return cnt; +} + +static const struct file_operations adsp_err_debug_ops = { + .write = adsp_err_debug_write, +}; +#endif +#endif + +struct adsp_err_code { + int lnx_err_code; + char *adsp_err_str; +}; + + +static struct adsp_err_code adsp_err_code_info[ADSP_ERR_MAX+1] = { + { 0, ADSP_EOK_STR}, + { -ENOTRECOVERABLE, ADSP_EFAILED_STR}, + { -EINVAL, ADSP_EBADPARAM_STR}, + { -EOPNOTSUPP, ADSP_EUNSUPPORTED_STR}, + { -ENOPROTOOPT, ADSP_EVERSION_STR}, + { -ENOTRECOVERABLE, ADSP_EUNEXPECTED_STR}, + { -ENOTRECOVERABLE, ADSP_EPANIC_STR}, + { -ENOSPC, ADSP_ENORESOURCE_STR}, + { -EBADR, ADSP_EHANDLE_STR}, + { -EALREADY, ADSP_EALREADY_STR}, + { -EPERM, ADSP_ENOTREADY_STR}, + { -EINPROGRESS, ADSP_EPENDING_STR}, + { -EBUSY, ADSP_EBUSY_STR}, + { -ECANCELED, ADSP_EABORTED_STR}, + { -EAGAIN, ADSP_EPREEMPTED_STR}, + { -EAGAIN, ADSP_ECONTINUE_STR}, + { -EAGAIN, ADSP_EIMMEDIATE_STR}, + { -EAGAIN, ADSP_ENOTIMPL_STR}, + { -ENODATA, ADSP_ENEEDMORE_STR}, + { -EADV, ADSP_ERR_MAX_STR}, + { -ENOMEM, ADSP_ENOMEMORY_STR}, + { -ENODEV, ADSP_ENOTEXIST_STR}, + { -EADV, ADSP_ERR_MAX_STR}, +}; + +#ifdef CONFIG_SND_SOC_QDSP_DEBUG +static inline void adsp_err_check_panic(u32 adsp_error) +{ + if (adsp_err_panic && adsp_error != ADSP_EALREADY) + panic("%s: encounter adsp_err=0x%x\n", __func__, adsp_error); +} +#else +static inline void adsp_err_check_panic(u32 adsp_error) {} +#endif + +int adsp_err_get_lnx_err_code(u32 adsp_error) +{ + adsp_err_check_panic(adsp_error); + + if (adsp_error > ADSP_ERR_MAX) + return adsp_err_code_info[ADSP_ERR_MAX].lnx_err_code; + else + return adsp_err_code_info[adsp_error].lnx_err_code; +} + +char *adsp_err_get_err_str(u32 adsp_error) +{ + if (adsp_error > ADSP_ERR_MAX) + return adsp_err_code_info[ADSP_ERR_MAX].adsp_err_str; + else + return adsp_err_code_info[adsp_error].adsp_err_str; +} + +#if defined(CONFIG_SND_SOC_QDSP_DEBUG) && defined(CONFIG_DEBUG_FS) +static int __init adsp_err_init(void) +{ + + + debugfs_adsp_err = debugfs_create_file("msm_adsp_audio_debug", + S_IFREG | 0444, NULL, NULL, + &adsp_err_debug_ops); + + return 0; +} + +device_initcall(adsp_err_init); +#endif diff --git a/sound/soc/msm/qdsp6v2/audio_cal_utils.c b/sound/soc/msm/qdsp6v2/audio_cal_utils.c new file mode 100644 index 000000000000..7e69a7fe28f5 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/audio_cal_utils.c @@ -0,0 +1,1030 @@ +/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include + +static int unmap_memory(struct cal_type_data *cal_type, + struct cal_block_data *cal_block); + +size_t get_cal_info_size(int32_t cal_type) +{ + size_t size = 0; + + switch (cal_type) { + case CVP_VOC_RX_TOPOLOGY_CAL_TYPE: + size = sizeof(struct audio_cal_info_voc_top); + break; + case CVP_VOC_TX_TOPOLOGY_CAL_TYPE: + size = sizeof(struct audio_cal_info_voc_top); + break; + case CVP_VOCPROC_STATIC_CAL_TYPE: + size = sizeof(struct audio_cal_info_vocproc); + break; + case CVP_VOCPROC_DYNAMIC_CAL_TYPE: + size = sizeof(struct audio_cal_info_vocvol); + break; + case CVS_VOCSTRM_STATIC_CAL_TYPE: + size = 0; + break; + case CVP_VOCDEV_CFG_CAL_TYPE: + size = sizeof(struct audio_cal_info_vocdev_cfg); + break; + case CVP_VOCPROC_STATIC_COL_CAL_TYPE: + size = sizeof(struct audio_cal_info_voc_col); + break; + case CVP_VOCPROC_DYNAMIC_COL_CAL_TYPE: + size = sizeof(struct audio_cal_info_voc_col); + break; + case CVS_VOCSTRM_STATIC_COL_CAL_TYPE: + size = sizeof(struct audio_cal_info_voc_col); + break; + case ADM_TOPOLOGY_CAL_TYPE: + size = sizeof(struct audio_cal_info_adm_top); + break; + case ADM_CUST_TOPOLOGY_CAL_TYPE: + case CORE_CUSTOM_TOPOLOGIES_CAL_TYPE: + size = 0; + break; + case ADM_AUDPROC_CAL_TYPE: + size = sizeof(struct audio_cal_info_audproc); + break; + case ADM_AUDVOL_CAL_TYPE: + case ADM_RTAC_AUDVOL_CAL_TYPE: + size = sizeof(struct audio_cal_info_audvol); + break; + case ASM_TOPOLOGY_CAL_TYPE: + size = sizeof(struct audio_cal_info_asm_top); + break; + case ASM_CUST_TOPOLOGY_CAL_TYPE: + size = 0; + break; + case ASM_AUDSTRM_CAL_TYPE: + size = sizeof(struct audio_cal_info_audstrm); + break; + case AFE_TOPOLOGY_CAL_TYPE: + size = sizeof(struct audio_cal_info_afe_top); + break; + case AFE_CUST_TOPOLOGY_CAL_TYPE: + size = 0; + break; + case AFE_COMMON_RX_CAL_TYPE: + size = sizeof(struct audio_cal_info_afe); + break; + case AFE_COMMON_TX_CAL_TYPE: + size = sizeof(struct audio_cal_info_afe); + break; + case AFE_FB_SPKR_PROT_CAL_TYPE: + size = sizeof(struct audio_cal_info_spk_prot_cfg); + break; + case AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE: + /* + * Since get and set parameter structures are different in size + * use the maximum size of get and set parameter structure + */ + size = max(sizeof(struct audio_cal_info_sp_th_vi_ftm_cfg), + sizeof(struct audio_cal_info_sp_th_vi_param)); + break; + case AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE: + /* + * Since get and set parameter structures are different in size + * use the maximum size of get and set parameter structure + */ + size = max(sizeof(struct audio_cal_info_sp_ex_vi_ftm_cfg), + sizeof(struct audio_cal_info_sp_ex_vi_param)); + break; + case AFE_ANC_CAL_TYPE: + size = 0; + break; + case AFE_AANC_CAL_TYPE: + size = sizeof(struct audio_cal_info_aanc); + break; + case AFE_HW_DELAY_CAL_TYPE: + size = sizeof(struct audio_cal_info_hw_delay); + break; + case AFE_SIDETONE_CAL_TYPE: + size = sizeof(struct audio_cal_info_sidetone); + break; + case AFE_SIDETONE_IIR_CAL_TYPE: + size = sizeof(struct audio_cal_info_sidetone_iir); + break; + case LSM_CUST_TOPOLOGY_CAL_TYPE: + size = 0; + break; + case LSM_TOPOLOGY_CAL_TYPE: + size = sizeof(struct audio_cal_info_lsm_top); + break; + case ULP_LSM_TOPOLOGY_ID_CAL_TYPE: + size = sizeof(struct audio_cal_info_lsm_top); + break; + case LSM_CAL_TYPE: + size = sizeof(struct audio_cal_info_lsm); + break; + case ADM_RTAC_INFO_CAL_TYPE: + size = 0; + break; + case VOICE_RTAC_INFO_CAL_TYPE: + size = 0; + break; + case ADM_RTAC_APR_CAL_TYPE: + size = 0; + break; + case ASM_RTAC_APR_CAL_TYPE: + size = 0; + break; + case VOICE_RTAC_APR_CAL_TYPE: + size = 0; + break; + case MAD_CAL_TYPE: + size = 0; + break; + case ULP_AFE_CAL_TYPE: + size = sizeof(struct audio_cal_info_afe); + break; + case ULP_LSM_CAL_TYPE: + size = sizeof(struct audio_cal_info_lsm); + break; + case AUDIO_CORE_METAINFO_CAL_TYPE: + size = sizeof(struct audio_cal_info_metainfo); + break; + case SRS_TRUMEDIA_CAL_TYPE: + size = 0; + break; + default: + pr_err("%s:Invalid cal type %d!", + __func__, cal_type); + } + return size; +} + +size_t get_user_cal_type_size(int32_t cal_type) +{ + size_t size = 0; + + switch (cal_type) { + case CVP_VOC_RX_TOPOLOGY_CAL_TYPE: + size = sizeof(struct audio_cal_type_voc_top); + break; + case CVP_VOC_TX_TOPOLOGY_CAL_TYPE: + size = sizeof(struct audio_cal_type_voc_top); + break; + case CVP_VOCPROC_STATIC_CAL_TYPE: + size = sizeof(struct audio_cal_type_vocproc); + break; + case CVP_VOCPROC_DYNAMIC_CAL_TYPE: + size = sizeof(struct audio_cal_type_vocvol); + break; + case CVS_VOCSTRM_STATIC_CAL_TYPE: + size = sizeof(struct audio_cal_type_basic); + break; + case CVP_VOCDEV_CFG_CAL_TYPE: + size = sizeof(struct audio_cal_type_vocdev_cfg); + break; + case CVP_VOCPROC_STATIC_COL_CAL_TYPE: + case CVP_VOCPROC_DYNAMIC_COL_CAL_TYPE: + case CVS_VOCSTRM_STATIC_COL_CAL_TYPE: + size = sizeof(struct audio_cal_type_voc_col); + break; + case ADM_TOPOLOGY_CAL_TYPE: + size = sizeof(struct audio_cal_type_adm_top); + break; + case ADM_CUST_TOPOLOGY_CAL_TYPE: + case CORE_CUSTOM_TOPOLOGIES_CAL_TYPE: + size = sizeof(struct audio_cal_type_basic); + break; + case ADM_AUDPROC_CAL_TYPE: + size = sizeof(struct audio_cal_type_audproc); + break; + case ADM_AUDVOL_CAL_TYPE: + case ADM_RTAC_AUDVOL_CAL_TYPE: + size = sizeof(struct audio_cal_type_audvol); + break; + case ASM_TOPOLOGY_CAL_TYPE: + size = sizeof(struct audio_cal_type_asm_top); + break; + case ASM_CUST_TOPOLOGY_CAL_TYPE: + size = sizeof(struct audio_cal_type_basic); + break; + case ASM_AUDSTRM_CAL_TYPE: + size = sizeof(struct audio_cal_type_audstrm); + break; + case AFE_TOPOLOGY_CAL_TYPE: + size = sizeof(struct audio_cal_type_afe_top); + break; + case AFE_CUST_TOPOLOGY_CAL_TYPE: + size = sizeof(struct audio_cal_type_basic); + break; + case AFE_COMMON_RX_CAL_TYPE: + size = sizeof(struct audio_cal_type_afe); + break; + case AFE_COMMON_TX_CAL_TYPE: + size = sizeof(struct audio_cal_type_afe); + break; + case AFE_FB_SPKR_PROT_CAL_TYPE: + size = sizeof(struct audio_cal_type_fb_spk_prot_cfg); + break; + case AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE: + /* + * Since get and set parameter structures are different in size + * use the maximum size of get and set parameter structure + */ + size = max(sizeof(struct audio_cal_type_sp_th_vi_ftm_cfg), + sizeof(struct audio_cal_type_sp_th_vi_param)); + break; + case AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE: + /* + * Since get and set parameter structures are different in size + * use the maximum size of get and set parameter structure + */ + size = max(sizeof(struct audio_cal_type_sp_ex_vi_ftm_cfg), + sizeof(struct audio_cal_type_sp_ex_vi_param)); + break; + case AFE_ANC_CAL_TYPE: + size = 0; + break; + case AFE_AANC_CAL_TYPE: + size = sizeof(struct audio_cal_type_aanc); + break; + case AFE_HW_DELAY_CAL_TYPE: + size = sizeof(struct audio_cal_type_hw_delay); + break; + case AFE_SIDETONE_CAL_TYPE: + size = sizeof(struct audio_cal_type_sidetone); + break; + case AFE_SIDETONE_IIR_CAL_TYPE: + size = sizeof(struct audio_cal_type_sidetone_iir); + break; + case LSM_CUST_TOPOLOGY_CAL_TYPE: + size = sizeof(struct audio_cal_type_basic); + break; + case LSM_TOPOLOGY_CAL_TYPE: + size = sizeof(struct audio_cal_type_lsm_top); + break; + case ULP_LSM_TOPOLOGY_ID_CAL_TYPE: + size = sizeof(struct audio_cal_type_lsm_top); + break; + case LSM_CAL_TYPE: + size = sizeof(struct audio_cal_type_lsm); + break; + case ADM_RTAC_INFO_CAL_TYPE: + size = 0; + break; + case VOICE_RTAC_INFO_CAL_TYPE: + size = 0; + break; + case ADM_RTAC_APR_CAL_TYPE: + size = 0; + break; + case ASM_RTAC_APR_CAL_TYPE: + size = 0; + break; + case VOICE_RTAC_APR_CAL_TYPE: + size = 0; + break; + case MAD_CAL_TYPE: + size = 0; + break; + case ULP_AFE_CAL_TYPE: + size = sizeof(struct audio_cal_type_afe); + break; + case ULP_LSM_CAL_TYPE: + size = sizeof(struct audio_cal_type_lsm); + break; + case AUDIO_CORE_METAINFO_CAL_TYPE: + size = sizeof(struct audio_cal_type_metainfo); + break; + case SRS_TRUMEDIA_CAL_TYPE: + size = 0; + break; + default: + pr_err("%s:Invalid cal type %d!", + __func__, cal_type); + } + return size; +} + +int32_t cal_utils_get_cal_type_version(void *cal_type_data) +{ + struct audio_cal_type_basic *data = NULL; + + data = (struct audio_cal_type_basic *)cal_type_data; + + return data->cal_hdr.version; +} + +static struct cal_type_data *create_cal_type_data( + struct cal_type_info *info) +{ + struct cal_type_data *cal_type = NULL; + + if ((info->reg.cal_type < 0) || + (info->reg.cal_type >= MAX_CAL_TYPES)) { + pr_err("%s: cal type %d is Invalid!\n", + __func__, info->reg.cal_type); + goto done; + } + + if (info->cal_util_callbacks.match_block == NULL) { + pr_err("%s: cal type %d no method to match blocks!\n", + __func__, info->reg.cal_type); + goto done; + } + + cal_type = kmalloc(sizeof(*cal_type), GFP_KERNEL); + if (cal_type == NULL) + goto done; + + INIT_LIST_HEAD(&cal_type->cal_blocks); + mutex_init(&cal_type->lock); + memcpy(&cal_type->info, info, + sizeof(cal_type->info)); +done: + return cal_type; +} + +/** + * cal_utils_create_cal_types + * + * @num_cal_types: number of types + * @cal_type: pointer to the cal types pointer + * @info: pointer to info + * + * Returns 0 on success, EINVAL otherwise + */ +int cal_utils_create_cal_types(int num_cal_types, + struct cal_type_data **cal_type, + struct cal_type_info *info) +{ + int ret = 0; + int i; + + pr_debug("%s\n", __func__); + + if (cal_type == NULL) { + pr_err("%s: cal_type is NULL!\n", __func__); + ret = -EINVAL; + goto done; + } else if (info == NULL) { + pr_err("%s: info is NULL!\n", __func__); + ret = -EINVAL; + goto done; + } else if ((num_cal_types <= 0) || + (num_cal_types > MAX_CAL_TYPES)) { + pr_err("%s: num_cal_types of %d is Invalid!\n", + __func__, num_cal_types); + ret = -EINVAL; + goto done; + } + + for (i = 0; i < num_cal_types; i++) { + if ((info[i].reg.cal_type < 0) || + (info[i].reg.cal_type >= MAX_CAL_TYPES)) { + pr_err("%s: cal type %d at index %d is Invalid!\n", + __func__, info[i].reg.cal_type, i); + ret = -EINVAL; + goto done; + } + + cal_type[i] = create_cal_type_data(&info[i]); + if (cal_type[i] == NULL) { + pr_err("%s: Could not allocate cal_type of index %d!\n", + __func__, i); + ret = -EINVAL; + goto done; + } + + ret = audio_cal_register(1, &info[i].reg); + if (ret < 0) { + pr_err("%s: audio_cal_register failed, ret = %d!\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + pr_debug("%s: cal type %d at index %d!\n", + __func__, info[i].reg.cal_type, i); + } +done: + return ret; +} +EXPORT_SYMBOL(cal_utils_create_cal_types); + +static void delete_cal_block(struct cal_block_data *cal_block) +{ + pr_debug("%s\n", __func__); + + if (cal_block == NULL) + goto done; + + list_del(&cal_block->list); + kfree(cal_block->client_info); + cal_block->client_info = NULL; + kfree(cal_block->cal_info); + cal_block->cal_info = NULL; + if (cal_block->map_data.ion_client != NULL) { + msm_audio_ion_free(cal_block->map_data.ion_client, + cal_block->map_data.ion_handle); + cal_block->map_data.ion_client = NULL; + cal_block->map_data.ion_handle = NULL; + } + kfree(cal_block); +done: + return; +} + +static void destroy_all_cal_blocks(struct cal_type_data *cal_type) +{ + int ret = 0; + struct list_head *ptr, *next; + struct cal_block_data *cal_block; + + list_for_each_safe(ptr, next, + &cal_type->cal_blocks) { + + cal_block = list_entry(ptr, + struct cal_block_data, list); + + ret = unmap_memory(cal_type, cal_block); + if (ret < 0) { + pr_err("%s: unmap_memory failed, cal type %d, ret = %d!\n", + __func__, + cal_type->info.reg.cal_type, + ret); + } + delete_cal_block(cal_block); + cal_block = NULL; + } +} + +static void destroy_cal_type_data(struct cal_type_data *cal_type) +{ + if (cal_type == NULL) + goto done; + + destroy_all_cal_blocks(cal_type); + list_del(&cal_type->cal_blocks); + kfree(cal_type); +done: + return; +} + +void cal_utils_destroy_cal_types(int num_cal_types, + struct cal_type_data **cal_type) +{ + int i; + + pr_debug("%s\n", __func__); + + if (cal_type == NULL) { + pr_err("%s: cal_type is NULL!\n", __func__); + goto done; + } else if ((num_cal_types <= 0) || + (num_cal_types > MAX_CAL_TYPES)) { + pr_err("%s: num_cal_types of %d is Invalid!\n", + __func__, num_cal_types); + goto done; + } + + for (i = 0; i < num_cal_types; i++) { + audio_cal_deregister(1, &cal_type[i]->info.reg); + destroy_cal_type_data(cal_type[i]); + cal_type[i] = NULL; + } +done: + return; +} + +/** + * cal_utils_get_only_cal_block + * + * @cal_type: pointer to the cal type + * + * Returns cal_block structure + */ +struct cal_block_data *cal_utils_get_only_cal_block( + struct cal_type_data *cal_type) +{ + struct list_head *ptr, *next; + struct cal_block_data *cal_block = NULL; + + if (cal_type == NULL) + goto done; + + list_for_each_safe(ptr, next, + &cal_type->cal_blocks) { + + cal_block = list_entry(ptr, + struct cal_block_data, list); + break; + } +done: + return cal_block; +} +EXPORT_SYMBOL(cal_utils_get_only_cal_block); + +/** + * cal_utils_get_only_cal_block + * + * @cal_block: pointer to cal block struct + * @user_data: pointer to user data + * + * Returns true on match + */ +bool cal_utils_match_buf_num(struct cal_block_data *cal_block, + void *user_data) +{ + bool ret = false; + struct audio_cal_type_basic *data = user_data; + + if (cal_block->buffer_number == data->cal_hdr.buffer_number) + ret = true; + + return ret; +} +EXPORT_SYMBOL(cal_utils_match_buf_num); + +static struct cal_block_data *get_matching_cal_block( + struct cal_type_data *cal_type, + void *data) +{ + struct list_head *ptr, *next; + struct cal_block_data *cal_block = NULL; + + list_for_each_safe(ptr, next, + &cal_type->cal_blocks) { + + cal_block = list_entry(ptr, + struct cal_block_data, list); + + if (cal_type->info.cal_util_callbacks. + match_block(cal_block, data)) + return cal_block; + } + + return NULL; +} + +static int cal_block_ion_alloc(struct cal_block_data *cal_block) +{ + int ret = 0; + + if (cal_block == NULL) { + pr_err("%s: cal_block is NULL!\n", __func__); + ret = -EINVAL; + goto done; + } + + ret = msm_audio_ion_import("audio_cal_client", + &cal_block->map_data.ion_client, + &cal_block->map_data.ion_handle, + cal_block->map_data.ion_map_handle, + NULL, 0, + &cal_block->cal_data.paddr, + &cal_block->map_data.map_size, + &cal_block->cal_data.kvaddr); + if (ret) { + pr_err("%s: audio ION import failed, rc = %d\n", + __func__, ret); + ret = -ENOMEM; + goto done; + } +done: + return ret; +} + +static struct cal_block_data *create_cal_block(struct cal_type_data *cal_type, + struct audio_cal_type_basic *basic_cal, + size_t client_info_size, void *client_info) +{ + struct cal_block_data *cal_block = NULL; + + if (cal_type == NULL) { + pr_err("%s: cal_type is NULL!\n", __func__); + goto done; + } else if (basic_cal == NULL) { + pr_err("%s: basic_cal is NULL!\n", __func__); + goto done; + } + + cal_block = kzalloc(sizeof(*cal_block), + GFP_KERNEL); + if (cal_block == NULL) + goto done; + + INIT_LIST_HEAD(&cal_block->list); + + cal_block->map_data.ion_map_handle = basic_cal->cal_data.mem_handle; + if (basic_cal->cal_data.mem_handle > 0) { + if (cal_block_ion_alloc(cal_block)) { + pr_err("%s: cal_block_ion_alloc failed!\n", + __func__); + goto err; + } + } + if (client_info_size > 0) { + cal_block->client_info_size = client_info_size; + cal_block->client_info = kmalloc(client_info_size, GFP_KERNEL); + if (cal_block->client_info == NULL) { + pr_err("%s: could not allocats client_info!\n", + __func__); + goto err; + } + if (client_info != NULL) + memcpy(cal_block->client_info, client_info, + client_info_size); + } + + cal_block->cal_info = kzalloc( + get_cal_info_size(cal_type->info.reg.cal_type), + GFP_KERNEL); + if (cal_block->cal_info == NULL) { + pr_err("%s: could not allocats cal_info!\n", + __func__); + goto err; + } + cal_block->buffer_number = basic_cal->cal_hdr.buffer_number; + list_add_tail(&cal_block->list, &cal_type->cal_blocks); + pr_debug("%s: created block for cal type %d, buf num %d, map handle %d, map size %zd paddr 0x%pK!\n", + __func__, cal_type->info.reg.cal_type, + cal_block->buffer_number, + cal_block->map_data.ion_map_handle, + cal_block->map_data.map_size, + &cal_block->cal_data.paddr); +done: + return cal_block; +err: + kfree(cal_block->cal_info); + cal_block->cal_info = NULL; + kfree(cal_block->client_info); + cal_block->client_info = NULL; + kfree(cal_block); + cal_block = NULL; + return cal_block; +} + +void cal_utils_clear_cal_block_q6maps(int num_cal_types, + struct cal_type_data **cal_type) +{ + int i = 0; + struct list_head *ptr, *next; + struct cal_block_data *cal_block; + + pr_debug("%s\n", __func__); + + if (cal_type == NULL) { + pr_err("%s: cal_type is NULL!\n", __func__); + goto done; + } else if ((num_cal_types <= 0) || + (num_cal_types > MAX_CAL_TYPES)) { + pr_err("%s: num_cal_types of %d is Invalid!\n", + __func__, num_cal_types); + goto done; + } + + for (; i < num_cal_types; i++) { + if (cal_type[i] == NULL) + continue; + + mutex_lock(&cal_type[i]->lock); + list_for_each_safe(ptr, next, + &cal_type[i]->cal_blocks) { + + cal_block = list_entry(ptr, + struct cal_block_data, list); + + cal_block->map_data.q6map_handle = 0; + } + mutex_unlock(&cal_type[i]->lock); + } +done: + return; +} + + + +static int realloc_memory(struct cal_block_data *cal_block) +{ + int ret = 0; + + msm_audio_ion_free(cal_block->map_data.ion_client, + cal_block->map_data.ion_handle); + cal_block->map_data.ion_client = NULL; + cal_block->map_data.ion_handle = NULL; + cal_block->cal_data.size = 0; + + ret = cal_block_ion_alloc(cal_block); + if (ret < 0) + pr_err("%s: realloc_memory failed!\n", + __func__); + return ret; +} + +static int map_memory(struct cal_type_data *cal_type, + struct cal_block_data *cal_block) +{ + int ret = 0; + + + if (cal_type->info.cal_util_callbacks.map_cal != NULL) { + if ((cal_block->map_data.ion_map_handle < 0) || + (cal_block->map_data.map_size <= 0) || + (cal_block->map_data.q6map_handle != 0)) { + goto done; + } + + pr_debug("%s: cal type %d call map\n", + __func__, cal_type->info.reg.cal_type); + ret = cal_type->info.cal_util_callbacks. + map_cal(cal_type->info.reg.cal_type, cal_block); + if (ret < 0) { + pr_err("%s: map_cal failed, cal type %d, ret = %d!\n", + __func__, cal_type->info.reg.cal_type, + ret); + goto done; + } + } +done: + return ret; +} + +static int unmap_memory(struct cal_type_data *cal_type, + struct cal_block_data *cal_block) +{ + int ret = 0; + + if (cal_type->info.cal_util_callbacks.unmap_cal != NULL) { + if ((cal_block->map_data.ion_map_handle < 0) || + (cal_block->map_data.map_size <= 0) || + (cal_block->map_data.q6map_handle == 0)) { + goto done; + } + pr_debug("%s: cal type %d call unmap\n", + __func__, cal_type->info.reg.cal_type); + ret = cal_type->info.cal_util_callbacks. + unmap_cal(cal_type->info.reg.cal_type, cal_block); + if (ret < 0) { + pr_err("%s: unmap_cal failed, cal type %d, ret = %d!\n", + __func__, cal_type->info.reg.cal_type, + ret); + goto done; + } + } +done: + return ret; +} + +/** + * cal_utils_alloc_cal + * + * @data_size: size of data to allocate + * @data: data pointer + * @cal_type: pointer to the cal type + * @client_info_size: client info size + * @client_info: pointer to client info + * + * Returns 0 on success, appropriate error code otherwise + */ +int cal_utils_alloc_cal(size_t data_size, void *data, + struct cal_type_data *cal_type, + size_t client_info_size, void *client_info) +{ + int ret = 0; + struct cal_block_data *cal_block; + struct audio_cal_type_alloc *alloc_data = data; + + pr_debug("%s\n", __func__); + + if (cal_type == NULL) { + pr_err("%s: cal_type is NULL!\n", + __func__); + ret = -EINVAL; + goto done; + } + if (data_size < sizeof(struct audio_cal_type_alloc)) { + pr_err("%s: data_size of %zd does not equal alloc struct size of %zd!\n", + __func__, data_size, + sizeof(struct audio_cal_type_alloc)); + ret = -EINVAL; + goto done; + } + if ((client_info_size > 0) && (client_info == NULL)) { + pr_err("%s: User info pointer is NULL but size is %zd!\n", + __func__, client_info_size); + ret = -EINVAL; + goto done; + } + + if (alloc_data->cal_data.mem_handle < 0) { + pr_err("%s: mem_handle %d invalid!\n", + __func__, alloc_data->cal_data.mem_handle); + ret = -EINVAL; + goto done; + } + + mutex_lock(&cal_type->lock); + + cal_block = get_matching_cal_block(cal_type, + data); + if (cal_block != NULL) { + ret = unmap_memory(cal_type, cal_block); + if (ret < 0) + goto err; + ret = realloc_memory(cal_block); + if (ret < 0) + goto err; + } else { + cal_block = create_cal_block(cal_type, + (struct audio_cal_type_basic *)alloc_data, + client_info_size, client_info); + if (cal_block == NULL) { + pr_err("%s: create_cal_block failed for %d!\n", + __func__, alloc_data->cal_data.mem_handle); + ret = -EINVAL; + goto err; + } + } + + ret = map_memory(cal_type, cal_block); + if (ret < 0) + goto err; +err: + mutex_unlock(&cal_type->lock); +done: + return ret; +} +EXPORT_SYMBOL(cal_utils_alloc_cal); + +/** + * cal_utils_dealloc_cal + * + * @data_size: size of data to allocate + * @data: data pointer + * @cal_type: pointer to the cal type + * + * Returns 0 on success, appropriate error code otherwise + */ +int cal_utils_dealloc_cal(size_t data_size, void *data, + struct cal_type_data *cal_type) +{ + int ret = 0; + struct cal_block_data *cal_block; + struct audio_cal_type_dealloc *dealloc_data = data; + + pr_debug("%s\n", __func__); + + + if (cal_type == NULL) { + pr_err("%s: cal_type is NULL!\n", + __func__); + ret = -EINVAL; + goto done; + } + + if (data_size < sizeof(struct audio_cal_type_dealloc)) { + pr_err("%s: data_size of %zd does not equal struct size of %zd!\n", + __func__, data_size, + sizeof(struct audio_cal_type_dealloc)); + ret = -EINVAL; + goto done; + } + + if ((dealloc_data->cal_data.mem_handle == -1) && + (dealloc_data->cal_hdr.buffer_number == ALL_CAL_BLOCKS)) { + destroy_all_cal_blocks(cal_type); + goto done; + } + + if (dealloc_data->cal_data.mem_handle < 0) { + pr_err("%s: mem_handle %d invalid!\n", + __func__, dealloc_data->cal_data.mem_handle); + ret = -EINVAL; + goto done; + } + + mutex_lock(&cal_type->lock); + cal_block = get_matching_cal_block( + cal_type, + data); + if (cal_block == NULL) { + pr_err("%s: allocation does not exist for %d!\n", + __func__, dealloc_data->cal_data.mem_handle); + ret = -EINVAL; + goto err; + } + + ret = unmap_memory(cal_type, cal_block); + if (ret < 0) + goto err; + + delete_cal_block(cal_block); +err: + mutex_unlock(&cal_type->lock); +done: + return ret; +} +EXPORT_SYMBOL(cal_utils_dealloc_cal); + +/** + * cal_utils_set_cal + * + * @data_size: size of data to allocate + * @data: data pointer + * @cal_type: pointer to the cal type + * @client_info_size: client info size + * @client_info: pointer to client info + * + * Returns 0 on success, appropriate error code otherwise + */ +int cal_utils_set_cal(size_t data_size, void *data, + struct cal_type_data *cal_type, + size_t client_info_size, void *client_info) +{ + int ret = 0; + struct cal_block_data *cal_block; + struct audio_cal_type_basic *basic_data = data; + + pr_debug("%s\n", __func__); + + if (cal_type == NULL) { + pr_err("%s: cal_type is NULL!\n", + __func__); + ret = -EINVAL; + goto done; + } + + if ((client_info_size > 0) && (client_info == NULL)) { + pr_err("%s: User info pointer is NULL but size is %zd!\n", + __func__, client_info_size); + ret = -EINVAL; + goto done; + } + + if ((data_size > get_user_cal_type_size( + cal_type->info.reg.cal_type)) || (data_size < 0)) { + pr_err("%s: cal_type %d, data_size of %zd is invalid, expecting %zd!\n", + __func__, cal_type->info.reg.cal_type, data_size, + get_user_cal_type_size(cal_type->info.reg.cal_type)); + ret = -EINVAL; + goto done; + } + + mutex_lock(&cal_type->lock); + cal_block = get_matching_cal_block( + cal_type, + data); + if (cal_block == NULL) { + if (basic_data->cal_data.mem_handle > 0) { + pr_err("%s: allocation does not exist for %d!\n", + __func__, basic_data->cal_data.mem_handle); + ret = -EINVAL; + goto err; + } else { + cal_block = create_cal_block( + cal_type, + basic_data, + client_info_size, client_info); + if (cal_block == NULL) { + pr_err("%s: create_cal_block failed for cal type %d!\n", + __func__, + cal_type->info.reg.cal_type); + ret = -EINVAL; + goto err; + } + } + } + + ret = map_memory(cal_type, cal_block); + if (ret < 0) + goto err; + + cal_block->cal_data.size = basic_data->cal_data.cal_size; + + if (client_info_size > 0) { + memcpy(cal_block->client_info, + client_info, + client_info_size); + } + + memcpy(cal_block->cal_info, + ((uint8_t *)data + sizeof(struct audio_cal_type_basic)), + data_size - sizeof(struct audio_cal_type_basic)); + +err: + mutex_unlock(&cal_type->lock); +done: + return ret; +} +EXPORT_SYMBOL(cal_utils_set_cal); diff --git a/sound/soc/msm/qdsp6v2/audio_calibration.c b/sound/soc/msm/qdsp6v2/audio_calibration.c new file mode 100644 index 000000000000..808a0e4b72d1 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/audio_calibration.c @@ -0,0 +1,636 @@ +/* Copyright (c) 2014, 2016-2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct audio_cal_client_info { + struct list_head list; + struct audio_cal_callbacks *callbacks; +}; + +struct audio_cal_info { + struct mutex common_lock; + struct mutex cal_mutex[MAX_CAL_TYPES]; + struct list_head client_info[MAX_CAL_TYPES]; + int ref_count; +}; + +static struct audio_cal_info audio_cal; + + +static bool callbacks_are_equal(struct audio_cal_callbacks *callback1, + struct audio_cal_callbacks *callback2) +{ + bool ret = true; + struct audio_cal_callbacks *call1 = callback1; + struct audio_cal_callbacks *call2 = callback2; + + pr_debug("%s\n", __func__); + + if ((call1 == NULL) && (call2 == NULL)) + ret = true; + else if ((call1 == NULL) || (call2 == NULL)) + ret = false; + else if ((call1->alloc != call2->alloc) || + (call1->dealloc != call2->dealloc) || + (call1->pre_cal != call2->pre_cal) || + (call1->set_cal != call2->set_cal) || + (call1->get_cal != call2->get_cal) || + (call1->post_cal != call2->post_cal)) + ret = false; + return ret; +} + +int audio_cal_deregister(int num_cal_types, + struct audio_cal_reg *reg_data) +{ + int ret = 0; + int i = 0; + struct list_head *ptr, *next; + struct audio_cal_client_info *client_info_node = NULL; + + pr_debug("%s\n", __func__); + + if (reg_data == NULL) { + pr_err("%s: reg_data is NULL!\n", __func__); + ret = -EINVAL; + goto done; + } else if ((num_cal_types <= 0) || + (num_cal_types > MAX_CAL_TYPES)) { + pr_err("%s: num_cal_types of %d is Invalid!\n", + __func__, num_cal_types); + ret = -EINVAL; + goto done; + } + + for (; i < num_cal_types; i++) { + if ((reg_data[i].cal_type < 0) || + (reg_data[i].cal_type >= MAX_CAL_TYPES)) { + pr_err("%s: cal type %d at index %d is Invalid!\n", + __func__, reg_data[i].cal_type, i); + ret = -EINVAL; + continue; + } + + mutex_lock(&audio_cal.cal_mutex[reg_data[i].cal_type]); + list_for_each_safe(ptr, next, + &audio_cal.client_info[reg_data[i].cal_type]) { + + client_info_node = list_entry(ptr, + struct audio_cal_client_info, list); + if (callbacks_are_equal(client_info_node->callbacks, + ®_data[i].callbacks)) { + list_del(&client_info_node->list); + kfree(client_info_node->callbacks); + client_info_node->callbacks = NULL; + kfree(client_info_node); + client_info_node = NULL; + break; + } + } + mutex_unlock(&audio_cal.cal_mutex[reg_data[i].cal_type]); + } +done: + return ret; +} + + +int audio_cal_register(int num_cal_types, + struct audio_cal_reg *reg_data) +{ + int ret = 0; + int i = 0; + struct audio_cal_client_info *client_info_node = NULL; + struct audio_cal_callbacks *callback_node = NULL; + + pr_debug("%s\n", __func__); + + if (reg_data == NULL) { + pr_err("%s: callbacks are NULL!\n", __func__); + ret = -EINVAL; + goto done; + } else if ((num_cal_types <= 0) || + (num_cal_types > MAX_CAL_TYPES)) { + pr_err("%s: num_cal_types of %d is Invalid!\n", + __func__, num_cal_types); + ret = -EINVAL; + goto done; + } + + for (; i < num_cal_types; i++) { + if ((reg_data[i].cal_type < 0) || + (reg_data[i].cal_type >= MAX_CAL_TYPES)) { + pr_err("%s: cal type %d at index %d is Invalid!\n", + __func__, reg_data[i].cal_type, i); + ret = -EINVAL; + goto err; + } + + client_info_node = kmalloc(sizeof(*client_info_node), + GFP_KERNEL); + if (client_info_node == NULL) { + ret = -ENOMEM; + goto err; + } + INIT_LIST_HEAD(&client_info_node->list); + + callback_node = kmalloc(sizeof(*callback_node), + GFP_KERNEL); + if (callback_node == NULL) { + ret = -ENOMEM; + goto err; + } + + memcpy(callback_node, ®_data[i].callbacks, + sizeof(*callback_node)); + client_info_node->callbacks = callback_node; + + mutex_lock(&audio_cal.cal_mutex[reg_data[i].cal_type]); + list_add_tail(&client_info_node->list, + &audio_cal.client_info[reg_data[i].cal_type]); + mutex_unlock(&audio_cal.cal_mutex[reg_data[i].cal_type]); + } +done: + return ret; +err: + audio_cal_deregister(num_cal_types, reg_data); + return ret; +} + +static int call_allocs(int32_t cal_type, + size_t cal_type_size, void *data) +{ + int ret = 0; + int ret2 = 0; + struct list_head *ptr, *next; + struct audio_cal_client_info *client_info_node = NULL; + + pr_debug("%s\n", __func__); + + list_for_each_safe(ptr, next, + &audio_cal.client_info[cal_type]) { + + client_info_node = list_entry(ptr, + struct audio_cal_client_info, list); + + if (client_info_node->callbacks->alloc == NULL) + continue; + + ret2 = client_info_node->callbacks-> + alloc(cal_type, cal_type_size, data); + if (ret2 < 0) { + pr_err("%s: alloc failed!\n", __func__); + ret = ret2; + } + } + return ret; +} + +static int call_deallocs(int32_t cal_type, + size_t cal_type_size, void *data) +{ + int ret = 0; + int ret2 = 0; + struct list_head *ptr, *next; + struct audio_cal_client_info *client_info_node = NULL; + + pr_debug("%s cal type %d\n", __func__, cal_type); + + list_for_each_safe(ptr, next, + &audio_cal.client_info[cal_type]) { + + client_info_node = list_entry(ptr, + struct audio_cal_client_info, list); + + if (client_info_node->callbacks->dealloc == NULL) + continue; + + ret2 = client_info_node->callbacks-> + dealloc(cal_type, cal_type_size, data); + if (ret2 < 0) { + pr_err("%s: dealloc failed!\n", __func__); + ret = ret2; + } + } + return ret; +} + +static int call_pre_cals(int32_t cal_type, + size_t cal_type_size, void *data) +{ + int ret = 0; + int ret2 = 0; + struct list_head *ptr, *next; + struct audio_cal_client_info *client_info_node = NULL; + + pr_debug("%s cal type %d\n", __func__, cal_type); + + list_for_each_safe(ptr, next, + &audio_cal.client_info[cal_type]) { + + client_info_node = list_entry(ptr, + struct audio_cal_client_info, list); + + if (client_info_node->callbacks->pre_cal == NULL) + continue; + + ret2 = client_info_node->callbacks-> + pre_cal(cal_type, cal_type_size, data); + if (ret2 < 0) { + pr_err("%s: pre_cal failed!\n", __func__); + ret = ret2; + } + } + return ret; +} + +static int call_post_cals(int32_t cal_type, + size_t cal_type_size, void *data) +{ + int ret = 0; + int ret2 = 0; + struct list_head *ptr, *next; + struct audio_cal_client_info *client_info_node = NULL; + + pr_debug("%s cal type %d\n", __func__, cal_type); + + list_for_each_safe(ptr, next, + &audio_cal.client_info[cal_type]) { + + client_info_node = list_entry(ptr, + struct audio_cal_client_info, list); + + if (client_info_node->callbacks->post_cal == NULL) + continue; + + ret2 = client_info_node->callbacks-> + post_cal(cal_type, cal_type_size, data); + if (ret2 < 0) { + pr_err("%s: post_cal failed!\n", __func__); + ret = ret2; + } + } + return ret; +} + +static int call_set_cals(int32_t cal_type, + size_t cal_type_size, void *data) +{ + int ret = 0; + int ret2 = 0; + struct list_head *ptr, *next; + struct audio_cal_client_info *client_info_node = NULL; + + pr_debug("%s cal type %d\n", __func__, cal_type); + + list_for_each_safe(ptr, next, + &audio_cal.client_info[cal_type]) { + + client_info_node = list_entry(ptr, + struct audio_cal_client_info, list); + + if (client_info_node->callbacks->set_cal == NULL) + continue; + + ret2 = client_info_node->callbacks-> + set_cal(cal_type, cal_type_size, data); + if (ret2 < 0) { + pr_err("%s: set_cal failed!\n", __func__); + ret = ret2; + } + } + return ret; +} + +static int call_get_cals(int32_t cal_type, + size_t cal_type_size, void *data) +{ + int ret = 0; + int ret2 = 0; + struct list_head *ptr, *next; + struct audio_cal_client_info *client_info_node = NULL; + + pr_debug("%s cal type %d\n", __func__, cal_type); + + list_for_each_safe(ptr, next, + &audio_cal.client_info[cal_type]) { + + client_info_node = list_entry(ptr, + struct audio_cal_client_info, list); + + if (client_info_node->callbacks->get_cal == NULL) + continue; + + ret2 = client_info_node->callbacks-> + get_cal(cal_type, cal_type_size, data); + if (ret2 < 0) { + pr_err("%s: get_cal failed!\n", __func__); + ret = ret2; + } + } + return ret; +} + +static int audio_cal_open(struct inode *inode, struct file *f) +{ + int ret = 0; + + pr_debug("%s\n", __func__); + + mutex_lock(&audio_cal.common_lock); + audio_cal.ref_count++; + mutex_unlock(&audio_cal.common_lock); + + return ret; +} + +static void dealloc_all_clients(void) +{ + int i = 0; + struct audio_cal_type_dealloc dealloc_data; + + pr_debug("%s\n", __func__); + + dealloc_data.cal_hdr.version = VERSION_0_0; + dealloc_data.cal_hdr.buffer_number = ALL_CAL_BLOCKS; + dealloc_data.cal_data.mem_handle = -1; + + for (; i < MAX_CAL_TYPES; i++) + call_deallocs(i, sizeof(dealloc_data), &dealloc_data); +} + +static int audio_cal_release(struct inode *inode, struct file *f) +{ + int ret = 0; + + pr_debug("%s\n", __func__); + + mutex_lock(&audio_cal.common_lock); + audio_cal.ref_count--; + if (audio_cal.ref_count <= 0) { + audio_cal.ref_count = 0; + dealloc_all_clients(); + } + mutex_unlock(&audio_cal.common_lock); + + return ret; +} + +static long audio_cal_shared_ioctl(struct file *file, unsigned int cmd, + void __user *arg) +{ + int ret = 0; + int32_t size; + struct audio_cal_basic *data = NULL; + + pr_debug("%s\n", __func__); + + switch (cmd) { + case AUDIO_ALLOCATE_CALIBRATION: + case AUDIO_DEALLOCATE_CALIBRATION: + case AUDIO_PREPARE_CALIBRATION: + case AUDIO_SET_CALIBRATION: + case AUDIO_GET_CALIBRATION: + case AUDIO_POST_CALIBRATION: + break; + default: + pr_err("%s: ioctl not found!\n", __func__); + ret = -EFAULT; + goto done; + } + + if (copy_from_user(&size, (void *)arg, sizeof(size))) { + pr_err("%s: Could not copy size value from user\n", __func__); + ret = -EFAULT; + goto done; + } else if ((size < sizeof(struct audio_cal_basic)) + || (size > MAX_IOCTL_CMD_SIZE)) { + pr_err("%s: Invalid size sent to driver: %d, max size is %d, min size is %zd\n", + __func__, size, MAX_IOCTL_CMD_SIZE, + sizeof(struct audio_cal_basic)); + ret = -EINVAL; + goto done; + } + + data = kmalloc(size, GFP_KERNEL); + if (data == NULL) { + ret = -ENOMEM; + goto done; + } else if (copy_from_user(data, (void *)arg, size)) { + pr_err("%s: Could not copy data from user\n", + __func__); + ret = -EFAULT; + goto done; + } else if ((data->hdr.cal_type < 0) || + (data->hdr.cal_type >= MAX_CAL_TYPES)) { + pr_err("%s: cal type %d is Invalid!\n", + __func__, data->hdr.cal_type); + ret = -EINVAL; + goto done; + } else if ((data->hdr.cal_type_size < + sizeof(struct audio_cal_type_basic)) || + (data->hdr.cal_type_size > + get_user_cal_type_size(data->hdr.cal_type))) { + pr_err("%s: cal type size %d is Invalid! Max is %zd!\n", + __func__, data->hdr.cal_type_size, + get_user_cal_type_size(data->hdr.cal_type)); + ret = -EINVAL; + goto done; + } else if (data->cal_type.cal_hdr.buffer_number < 0) { + pr_err("%s: cal type %d Invalid buffer number %d!\n", + __func__, data->hdr.cal_type, + data->cal_type.cal_hdr.buffer_number); + ret = -EINVAL; + goto done; + } + + + mutex_lock(&audio_cal.cal_mutex[data->hdr.cal_type]); + + switch (cmd) { + case AUDIO_ALLOCATE_CALIBRATION: + ret = call_allocs(data->hdr.cal_type, + data->hdr.cal_type_size, &data->cal_type); + break; + case AUDIO_DEALLOCATE_CALIBRATION: + ret = call_deallocs(data->hdr.cal_type, + data->hdr.cal_type_size, &data->cal_type); + break; + case AUDIO_PREPARE_CALIBRATION: + ret = call_pre_cals(data->hdr.cal_type, + data->hdr.cal_type_size, &data->cal_type); + break; + case AUDIO_SET_CALIBRATION: + ret = call_set_cals(data->hdr.cal_type, + data->hdr.cal_type_size, &data->cal_type); + break; + case AUDIO_GET_CALIBRATION: + ret = call_get_cals(data->hdr.cal_type, + data->hdr.cal_type_size, &data->cal_type); + break; + case AUDIO_POST_CALIBRATION: + ret = call_post_cals(data->hdr.cal_type, + data->hdr.cal_type_size, &data->cal_type); + break; + } + + if (cmd == AUDIO_GET_CALIBRATION) { + if (data->hdr.cal_type_size == 0) + goto unlock; + if (data == NULL) + goto unlock; + if ((sizeof(data->hdr) + data->hdr.cal_type_size) > size) { + pr_err("%s: header size %zd plus cal type size %d are greater than data buffer size %d\n", + __func__, sizeof(data->hdr), + data->hdr.cal_type_size, size); + ret = -EFAULT; + goto unlock; + } else if (copy_to_user((void *)arg, data, + sizeof(data->hdr) + data->hdr.cal_type_size)) { + pr_err("%s: Could not copy cal type to user\n", + __func__); + ret = -EFAULT; + goto unlock; + } + } + +unlock: + mutex_unlock(&audio_cal.cal_mutex[data->hdr.cal_type]); +done: + kfree(data); + return ret; +} + +static long audio_cal_ioctl(struct file *f, + unsigned int cmd, unsigned long arg) +{ + return audio_cal_shared_ioctl(f, cmd, (void __user *)arg); +} + +#ifdef CONFIG_COMPAT + +#define AUDIO_ALLOCATE_CALIBRATION32 _IOWR(CAL_IOCTL_MAGIC, \ + 200, compat_uptr_t) +#define AUDIO_DEALLOCATE_CALIBRATION32 _IOWR(CAL_IOCTL_MAGIC, \ + 201, compat_uptr_t) +#define AUDIO_PREPARE_CALIBRATION32 _IOWR(CAL_IOCTL_MAGIC, \ + 202, compat_uptr_t) +#define AUDIO_SET_CALIBRATION32 _IOWR(CAL_IOCTL_MAGIC, \ + 203, compat_uptr_t) +#define AUDIO_GET_CALIBRATION32 _IOWR(CAL_IOCTL_MAGIC, \ + 204, compat_uptr_t) +#define AUDIO_POST_CALIBRATION32 _IOWR(CAL_IOCTL_MAGIC, \ + 205, compat_uptr_t) + +static long audio_cal_compat_ioctl(struct file *f, + unsigned int cmd, unsigned long arg) +{ + unsigned int cmd64; + int ret = 0; + + switch (cmd) { + case AUDIO_ALLOCATE_CALIBRATION32: + cmd64 = AUDIO_ALLOCATE_CALIBRATION; + break; + case AUDIO_DEALLOCATE_CALIBRATION32: + cmd64 = AUDIO_DEALLOCATE_CALIBRATION; + break; + case AUDIO_PREPARE_CALIBRATION32: + cmd64 = AUDIO_PREPARE_CALIBRATION; + break; + case AUDIO_SET_CALIBRATION32: + cmd64 = AUDIO_SET_CALIBRATION; + break; + case AUDIO_GET_CALIBRATION32: + cmd64 = AUDIO_GET_CALIBRATION; + break; + case AUDIO_POST_CALIBRATION32: + cmd64 = AUDIO_POST_CALIBRATION; + break; + default: + pr_err("%s: ioctl not found!\n", __func__); + ret = -EFAULT; + goto done; + } + + ret = audio_cal_shared_ioctl(f, cmd64, compat_ptr(arg)); +done: + return ret; +} +#endif + +static const struct file_operations audio_cal_fops = { + .owner = THIS_MODULE, + .open = audio_cal_open, + .release = audio_cal_release, + .unlocked_ioctl = audio_cal_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = audio_cal_compat_ioctl, +#endif +}; + +struct miscdevice audio_cal_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_audio_cal", + .fops = &audio_cal_fops, +}; + +static int __init audio_cal_init(void) +{ + int i = 0; + + pr_debug("%s\n", __func__); + + memset(&audio_cal, 0, sizeof(audio_cal)); + mutex_init(&audio_cal.common_lock); + for (; i < MAX_CAL_TYPES; i++) { + INIT_LIST_HEAD(&audio_cal.client_info[i]); + mutex_init(&audio_cal.cal_mutex[i]); + } + + return misc_register(&audio_cal_misc); +} + +static void __exit audio_cal_exit(void) +{ + int i = 0; + struct list_head *ptr, *next; + struct audio_cal_client_info *client_info_node; + + for (; i < MAX_CAL_TYPES; i++) { + list_for_each_safe(ptr, next, + &audio_cal.client_info[i]) { + client_info_node = list_entry(ptr, + struct audio_cal_client_info, list); + list_del(&client_info_node->list); + kfree(client_info_node->callbacks); + client_info_node->callbacks = NULL; + kfree(client_info_node); + client_info_node = NULL; + } + } +} + +subsys_initcall(audio_cal_init); +module_exit(audio_cal_exit); + +MODULE_DESCRIPTION("SoC QDSP6v2 Audio Calibration driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/audio_slimslave.c b/sound/soc/msm/qdsp6v2/audio_slimslave.c new file mode 100644 index 000000000000..e9ecfd5b2e44 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/audio_slimslave.c @@ -0,0 +1,177 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct slim_device *slim; +static int vote_count; +struct mutex suspend_lock; +bool suspend; + +static int audio_slim_open(struct inode *inode, struct file *file) +{ + pr_debug("%s:\n", __func__); + + if (vote_count) { + pr_debug("%s: unvote: vote_count=%d\n", __func__, vote_count); + pm_runtime_mark_last_busy(slim->dev.parent); + pm_runtime_put(slim->dev.parent); + vote_count--; + } + return 0; +}; + +static int audio_slim_release(struct inode *inode, struct file *file) +{ + pr_debug("%s:\n", __func__); + + if (vote_count) { + pr_debug("%s: unvote: vote_count=%d\n", __func__, vote_count); + pm_runtime_mark_last_busy(slim->dev.parent); + pm_runtime_put(slim->dev.parent); + vote_count--; + } else { + pr_debug("%s: vote: vote_count=%d\n", __func__, vote_count); + pm_runtime_get_sync(slim->dev.parent); + vote_count++; + } + return 0; +}; + +static long audio_slim_ioctl(struct file *file, unsigned int cmd, + unsigned long u_arg) +{ + switch (cmd) { + case AUDIO_SLIMSLAVE_VOTE: + mutex_lock(&suspend_lock); + if (!vote_count && !suspend) { + pr_debug("%s:AUDIO_SLIMSLAVE_VOTE\n", __func__); + pm_runtime_get_sync(slim->dev.parent); + vote_count++; + } else { + pr_err("%s:Invalid vote: vote_count=%d suspend=%d\n", + __func__, vote_count, suspend); + } + mutex_unlock(&suspend_lock); + break; + case AUDIO_SLIMSLAVE_UNVOTE: + mutex_lock(&suspend_lock); + if (vote_count && !suspend) { + pr_debug("%s:AUDIO_SLIMSLAVE_UNVOTE\n", __func__); + pm_runtime_mark_last_busy(slim->dev.parent); + pm_runtime_put(slim->dev.parent); + vote_count--; + } else { + pr_err("%s:Invalid unvote: vote_count=%d suspend=%d\n", + __func__, vote_count, suspend); + } + mutex_unlock(&suspend_lock); + break; + default: + pr_debug("%s: Invalid ioctl cmd: %d\n", __func__, cmd); + break; + } + return 0; +} + +static const struct file_operations audio_slimslave_fops = { + .open = audio_slim_open, + .unlocked_ioctl = audio_slim_ioctl, + .release = audio_slim_release, +}; + +struct miscdevice audio_slimslave_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = AUDIO_SLIMSLAVE_IOCTL_NAME, + .fops = &audio_slimslave_fops, +}; + +static int audio_slimslave_probe(struct slim_device *audio_slim) +{ + pr_debug("%s:\n", __func__); + + mutex_init(&suspend_lock); + suspend = false; + slim = audio_slim; + misc_register(&audio_slimslave_misc); + return 0; +} + +static int audio_slimslave_remove(struct slim_device *audio_slim) +{ + pr_debug("%s:\n", __func__); + + misc_deregister(&audio_slimslave_misc); + return 0; +} + +static int audio_slimslave_resume(struct slim_device *audio_slim) +{ + pr_debug("%s:\n", __func__); + + mutex_lock(&suspend_lock); + suspend = false; + mutex_unlock(&suspend_lock); + return 0; +} + +static int audio_slimslave_suspend(struct slim_device *audio_slim, + pm_message_t pmesg) +{ + pr_debug("%s:\n", __func__); + + mutex_lock(&suspend_lock); + suspend = true; + mutex_unlock(&suspend_lock); + return 0; +} + +static const struct slim_device_id audio_slimslave_dt_match[] = { + {"audio-slimslave", 0}, + {} +}; + +static struct slim_driver audio_slimslave_driver = { + .driver = { + .name = "audio-slimslave", + .owner = THIS_MODULE, + }, + .probe = audio_slimslave_probe, + .remove = audio_slimslave_remove, + .id_table = audio_slimslave_dt_match, + .resume = audio_slimslave_resume, + .suspend = audio_slimslave_suspend, +}; + +static int __init audio_slimslave_init(void) +{ + return slim_driver_register(&audio_slimslave_driver); +} +module_init(audio_slimslave_init); + +static void __exit audio_slimslave_exit(void) +{ + +} +module_exit(audio_slimslave_exit); + +/* Module information */ +MODULE_DESCRIPTION("Audio side Slimbus slave driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c new file mode 100644 index 000000000000..9f082226ca35 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c @@ -0,0 +1,1378 @@ +/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include + +#define MAX_ENABLE_CMD_SIZE 32 + +#define GET_NEXT(ptr, upper_limit, rc) \ +({ \ + if (((ptr) + 1) > (upper_limit)) { \ + pr_err("%s: param list out of boundary\n", __func__); \ + (rc) = -EINVAL; \ + } \ + ((rc) == 0) ? *(ptr)++ : -EINVAL; \ +}) + +#define CHECK_PARAM_LEN(len, max_len, tag, rc) \ +do { \ + if ((len) > (max_len)) { \ + pr_err("%s: params length overflows\n", (tag)); \ + (rc) = -EINVAL; \ + } \ +} while (0) + + +bool msm_audio_effects_is_effmodule_supp_in_top(int effect_module, + int topology) +{ + switch (effect_module) { + case VIRTUALIZER_MODULE: + case REVERB_MODULE: + case BASS_BOOST_MODULE: + case PBE_MODULE: + case EQ_MODULE: + switch (topology) { + case ASM_STREAM_POSTPROC_TOPO_ID_SA_PLUS: + return true; + default: + return false; + } + default: + return false; + } +} + +int msm_audio_effects_enable_extn(struct audio_client *ac, + struct msm_nt_eff_all_config *effects, + bool flag) +{ + uint32_t updt_params[MAX_ENABLE_CMD_SIZE] = {0}; + uint32_t params_length; + int rc = 0; + + pr_debug("%s\n", __func__); + if (!ac) { + pr_err("%s: cannot set audio effects\n", __func__); + return -EINVAL; + } + params_length = 0; + updt_params[0] = AUDPROC_MODULE_ID_VIRTUALIZER; + updt_params[1] = AUDPROC_PARAM_ID_ENABLE; + updt_params[2] = VIRTUALIZER_ENABLE_PARAM_SZ; + updt_params[3] = flag; + params_length += COMMAND_PAYLOAD_SZ + VIRTUALIZER_ENABLE_PARAM_SZ; + if (effects->virtualizer.enable_flag) + q6asm_send_audio_effects_params(ac, (char *)&updt_params[0], + params_length); + memset(updt_params, 0, MAX_ENABLE_CMD_SIZE); + params_length = 0; + updt_params[0] = AUDPROC_MODULE_ID_BASS_BOOST; + updt_params[1] = AUDPROC_PARAM_ID_ENABLE; + updt_params[2] = BASS_BOOST_ENABLE_PARAM_SZ; + updt_params[3] = flag; + params_length += COMMAND_PAYLOAD_SZ + BASS_BOOST_ENABLE_PARAM_SZ; + if (effects->bass_boost.enable_flag) + q6asm_send_audio_effects_params(ac, (char *)&updt_params[0], + params_length); + memset(updt_params, 0, MAX_ENABLE_CMD_SIZE); + params_length = 0; + updt_params[0] = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; + updt_params[1] = AUDPROC_PARAM_ID_ENABLE; + updt_params[2] = EQ_ENABLE_PARAM_SZ; + updt_params[3] = flag; + params_length += COMMAND_PAYLOAD_SZ + EQ_ENABLE_PARAM_SZ; + if (effects->equalizer.enable_flag) + q6asm_send_audio_effects_params(ac, (char *)&updt_params[0], + params_length); + return rc; +} + +int msm_audio_effects_virtualizer_handler(struct audio_client *ac, + struct virtualizer_params *virtualizer, + long *values) +{ + long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; + char *params = NULL; + int rc = 0; + int devices = GET_NEXT(values, param_max_offset, rc); + int num_commands = GET_NEXT(values, param_max_offset, rc); + int *updt_params, i, prev_enable_flag; + uint32_t params_length = (MAX_INBAND_PARAM_SZ); + + pr_debug("%s\n", __func__); + if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { + pr_err("%s: cannot set audio effects\n", __func__); + return -EINVAL; + } + params = kzalloc(params_length, GFP_KERNEL); + if (!params) + return -ENOMEM; + + pr_debug("%s: device: %d\n", __func__, devices); + updt_params = (int *)params; + params_length = 0; + for (i = 0; i < num_commands; i++) { + uint32_t command_id = + GET_NEXT(values, param_max_offset, rc); + uint32_t command_config_state = + GET_NEXT(values, param_max_offset, rc); + uint32_t index_offset = + GET_NEXT(values, param_max_offset, rc); + uint32_t length = + GET_NEXT(values, param_max_offset, rc); + switch (command_id) { + case VIRTUALIZER_ENABLE: + if (length != 1 || index_offset != 0) { + pr_err("VIRT ENABLE:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + prev_enable_flag = virtualizer->enable_flag; + virtualizer->enable_flag = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s:VIRT ENABLE prev:%d, new:%d\n", __func__, + prev_enable_flag, virtualizer->enable_flag); + if (prev_enable_flag != virtualizer->enable_flag) { + params_length += COMMAND_PAYLOAD_SZ + + VIRTUALIZER_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "VIRT ENABLE", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_VIRTUALIZER; + *updt_params++ = + AUDPROC_PARAM_ID_VIRTUALIZER_ENABLE; + *updt_params++ = + VIRTUALIZER_ENABLE_PARAM_SZ; + *updt_params++ = + virtualizer->enable_flag; + } + break; + case VIRTUALIZER_STRENGTH: + if (length != 1 || index_offset != 0) { + pr_err("VIRT STRENGTH:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + virtualizer->strength = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: VIRT STRENGTH val: %d\n", + __func__, virtualizer->strength); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + VIRTUALIZER_STRENGTH_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "VIRT STRENGTH", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_VIRTUALIZER; + *updt_params++ = + AUDPROC_PARAM_ID_VIRTUALIZER_STRENGTH; + *updt_params++ = + VIRTUALIZER_STRENGTH_PARAM_SZ; + *updt_params++ = + virtualizer->strength; + } + break; + case VIRTUALIZER_OUT_TYPE: + if (length != 1 || index_offset != 0) { + pr_err("VIRT OUT_TYPE:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + virtualizer->out_type = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: VIRT OUT_TYPE val:%d\n", + __func__, virtualizer->out_type); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + VIRTUALIZER_OUT_TYPE_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "VIRT OUT_TYPE", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_VIRTUALIZER; + *updt_params++ = + AUDPROC_PARAM_ID_VIRTUALIZER_OUT_TYPE; + *updt_params++ = + VIRTUALIZER_OUT_TYPE_PARAM_SZ; + *updt_params++ = + virtualizer->out_type; + } + break; + case VIRTUALIZER_GAIN_ADJUST: + if (length != 1 || index_offset != 0) { + pr_err("VIRT GAIN_ADJUST: invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + virtualizer->gain_adjust = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: VIRT GAIN_ADJUST val:%d\n", + __func__, virtualizer->gain_adjust); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + VIRTUALIZER_GAIN_ADJUST_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "VIRT GAIN_ADJUST", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_VIRTUALIZER; + *updt_params++ = + AUDPROC_PARAM_ID_VIRTUALIZER_GAIN_ADJUST; + *updt_params++ = + VIRTUALIZER_GAIN_ADJUST_PARAM_SZ; + *updt_params++ = + virtualizer->gain_adjust; + } + break; + default: + pr_err("%s: Invalid command to set config\n", __func__); + break; + } + } + if (params_length && (rc == 0)) + q6asm_send_audio_effects_params(ac, params, + params_length); + else + pr_debug("%s: did not send pp params\n", __func__); +invalid_config: + kfree(params); + return rc; +} + +int msm_audio_effects_reverb_handler(struct audio_client *ac, + struct reverb_params *reverb, + long *values) +{ + long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; + char *params = NULL; + int rc = 0; + int devices = GET_NEXT(values, param_max_offset, rc); + int num_commands = GET_NEXT(values, param_max_offset, rc); + int *updt_params, i, prev_enable_flag; + uint32_t params_length = (MAX_INBAND_PARAM_SZ); + + pr_debug("%s\n", __func__); + if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { + pr_err("%s: cannot set audio effects\n", __func__); + return -EINVAL; + } + params = kzalloc(params_length, GFP_KERNEL); + if (!params) + return -ENOMEM; + + pr_debug("%s: device: %d\n", __func__, devices); + updt_params = (int *)params; + params_length = 0; + for (i = 0; i < num_commands; i++) { + uint32_t command_id = + GET_NEXT(values, param_max_offset, rc); + uint32_t command_config_state = + GET_NEXT(values, param_max_offset, rc); + uint32_t index_offset = + GET_NEXT(values, param_max_offset, rc); + uint32_t length = + GET_NEXT(values, param_max_offset, rc); + switch (command_id) { + case REVERB_ENABLE: + if (length != 1 || index_offset != 0) { + pr_err("REVERB_ENABLE:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + prev_enable_flag = reverb->enable_flag; + reverb->enable_flag = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s:REVERB_ENABLE prev:%d,new:%d\n", __func__, + prev_enable_flag, reverb->enable_flag); + if (prev_enable_flag != reverb->enable_flag) { + params_length += COMMAND_PAYLOAD_SZ + + REVERB_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "REVERB_ENABLE", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_REVERB; + *updt_params++ = + AUDPROC_PARAM_ID_REVERB_ENABLE; + *updt_params++ = + REVERB_ENABLE_PARAM_SZ; + *updt_params++ = + reverb->enable_flag; + } + break; + case REVERB_MODE: + if (length != 1 || index_offset != 0) { + pr_err("REVERB_MODE:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + reverb->mode = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: REVERB_MODE val:%d\n", + __func__, reverb->mode); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + REVERB_MODE_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "REVERB_MODE", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_REVERB; + *updt_params++ = + AUDPROC_PARAM_ID_REVERB_MODE; + *updt_params++ = + REVERB_MODE_PARAM_SZ; + *updt_params++ = + reverb->mode; + } + break; + case REVERB_PRESET: + if (length != 1 || index_offset != 0) { + pr_err("REVERB_PRESET:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + reverb->preset = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: REVERB_PRESET val:%d\n", + __func__, reverb->preset); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + REVERB_PRESET_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "REVERB_PRESET", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_REVERB; + *updt_params++ = + AUDPROC_PARAM_ID_REVERB_PRESET; + *updt_params++ = + REVERB_PRESET_PARAM_SZ; + *updt_params++ = + reverb->preset; + } + break; + case REVERB_WET_MIX: + if (length != 1 || index_offset != 0) { + pr_err("REVERB_WET_MIX:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + reverb->wet_mix = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: REVERB_WET_MIX val:%d\n", + __func__, reverb->wet_mix); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + REVERB_WET_MIX_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "REVERB_WET_MIX", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_REVERB; + *updt_params++ = + AUDPROC_PARAM_ID_REVERB_WET_MIX; + *updt_params++ = + REVERB_WET_MIX_PARAM_SZ; + *updt_params++ = + reverb->wet_mix; + } + break; + case REVERB_GAIN_ADJUST: + if (length != 1 || index_offset != 0) { + pr_err("REVERB_GAIN_ADJUST:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + reverb->gain_adjust = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: REVERB_GAIN_ADJUST val:%d\n", + __func__, reverb->gain_adjust); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + REVERB_GAIN_ADJUST_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "REVERB_GAIN_ADJUST", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_REVERB; + *updt_params++ = + AUDPROC_PARAM_ID_REVERB_GAIN_ADJUST; + *updt_params++ = + REVERB_GAIN_ADJUST_PARAM_SZ; + *updt_params++ = + reverb->gain_adjust; + } + break; + case REVERB_ROOM_LEVEL: + if (length != 1 || index_offset != 0) { + pr_err("REVERB_ROOM_LEVEL:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + reverb->room_level = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: REVERB_ROOM_LEVEL val:%d\n", + __func__, reverb->room_level); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + REVERB_ROOM_LEVEL_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "REVERB_ROOM_LEVEL", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_REVERB; + *updt_params++ = + AUDPROC_PARAM_ID_REVERB_ROOM_LEVEL; + *updt_params++ = + REVERB_ROOM_LEVEL_PARAM_SZ; + *updt_params++ = + reverb->room_level; + } + break; + case REVERB_ROOM_HF_LEVEL: + if (length != 1 || index_offset != 0) { + pr_err("REVERB_ROOM_HF_LEVEL:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + reverb->room_hf_level = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: REVERB_ROOM_HF_LEVEL val%d\n", + __func__, reverb->room_hf_level); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + REVERB_ROOM_HF_LEVEL_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "REVERB_ROOM_HF_LEVEL", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_REVERB; + *updt_params++ = + AUDPROC_PARAM_ID_REVERB_ROOM_HF_LEVEL; + *updt_params++ = + REVERB_ROOM_HF_LEVEL_PARAM_SZ; + *updt_params++ = + reverb->room_hf_level; + } + break; + case REVERB_DECAY_TIME: + if (length != 1 || index_offset != 0) { + pr_err("REVERB_DECAY_TIME:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + reverb->decay_time = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: REVERB_DECAY_TIME val:%d\n", + __func__, reverb->decay_time); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + REVERB_DECAY_TIME_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "REVERB_DECAY_TIME", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_REVERB; + *updt_params++ = + AUDPROC_PARAM_ID_REVERB_DECAY_TIME; + *updt_params++ = + REVERB_DECAY_TIME_PARAM_SZ; + *updt_params++ = + reverb->decay_time; + } + break; + case REVERB_DECAY_HF_RATIO: + if (length != 1 || index_offset != 0) { + pr_err("REVERB_DECAY_HF_RATIOinvalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + reverb->decay_hf_ratio = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: REVERB_DECAY_HF_RATIO val%d\n", + __func__, reverb->decay_hf_ratio); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + REVERB_DECAY_HF_RATIO_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "REVERB_DECAY_HF_RATIO", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_REVERB; + *updt_params++ = + AUDPROC_PARAM_ID_REVERB_DECAY_HF_RATIO; + *updt_params++ = + REVERB_DECAY_HF_RATIO_PARAM_SZ; + *updt_params++ = + reverb->decay_hf_ratio; + } + break; + case REVERB_REFLECTIONS_LEVEL: + if (length != 1 || index_offset != 0) { + pr_err("REVERB_REFLECTION_LVLinvalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + reverb->reflections_level = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: REVERB_REFLECTIONS_LEVEL val:%d\n", + __func__, reverb->reflections_level); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + REVERB_REFLECTIONS_LEVEL_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "REVERB_REFLECTIONS_LEVEL", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_REVERB; + *updt_params++ = + AUDPROC_PARAM_ID_REVERB_REFLECTIONS_LEVEL; + *updt_params++ = + REVERB_REFLECTIONS_LEVEL_PARAM_SZ; + *updt_params++ = + reverb->reflections_level; + } + break; + case REVERB_REFLECTIONS_DELAY: + if (length != 1 || index_offset != 0) { + pr_err("REVERB_REFLECTION_DLYinvalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + reverb->reflections_delay = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: REVERB_REFLECTIONS_DELAY val:%d\n", + __func__, reverb->reflections_delay); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + REVERB_REFLECTIONS_DELAY_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "REVERB_REFLECTIONS_DELAY", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_REVERB; + *updt_params++ = + AUDPROC_PARAM_ID_REVERB_REFLECTIONS_DELAY; + *updt_params++ = + REVERB_REFLECTIONS_DELAY_PARAM_SZ; + *updt_params++ = + reverb->reflections_delay; + } + break; + case REVERB_LEVEL: + if (length != 1 || index_offset != 0) { + pr_err("REVERB_LEVEL:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + reverb->level = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: REVERB_LEVEL val:%d\n", + __func__, reverb->level); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + REVERB_LEVEL_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "REVERB_LEVEL", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_REVERB; + *updt_params++ = + AUDPROC_PARAM_ID_REVERB_LEVEL; + *updt_params++ = + REVERB_LEVEL_PARAM_SZ; + *updt_params++ = + reverb->level; + } + break; + case REVERB_DELAY: + if (length != 1 || index_offset != 0) { + pr_err("REVERB_DELAY:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + reverb->delay = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s:REVERB_DELAY val:%d\n", + __func__, reverb->delay); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + REVERB_DELAY_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "REVERB_DELAY", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_REVERB; + *updt_params++ = + AUDPROC_PARAM_ID_REVERB_DELAY; + *updt_params++ = + REVERB_DELAY_PARAM_SZ; + *updt_params++ = + reverb->delay; + } + break; + case REVERB_DIFFUSION: + if (length != 1 || index_offset != 0) { + pr_err("REVERB_DIFFUSION:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + reverb->diffusion = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: REVERB_DIFFUSION val:%d\n", + __func__, reverb->diffusion); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + REVERB_DIFFUSION_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "REVERB_DIFFUSION", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_REVERB; + *updt_params++ = + AUDPROC_PARAM_ID_REVERB_DIFFUSION; + *updt_params++ = + REVERB_DIFFUSION_PARAM_SZ; + *updt_params++ = + reverb->diffusion; + } + break; + case REVERB_DENSITY: + if (length != 1 || index_offset != 0) { + pr_err("REVERB_DENSITY:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + reverb->density = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: REVERB_DENSITY val:%d\n", + __func__, reverb->density); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + REVERB_DENSITY_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "REVERB_DENSITY", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_REVERB; + *updt_params++ = + AUDPROC_PARAM_ID_REVERB_DENSITY; + *updt_params++ = + REVERB_DENSITY_PARAM_SZ; + *updt_params++ = + reverb->density; + } + break; + default: + pr_err("%s: Invalid command to set config\n", __func__); + break; + } + } + if (params_length && (rc == 0)) + q6asm_send_audio_effects_params(ac, params, + params_length); + else + pr_debug("%s: did not send pp params\n", __func__); +invalid_config: + kfree(params); + return rc; +} + +int msm_audio_effects_bass_boost_handler(struct audio_client *ac, + struct bass_boost_params *bass_boost, + long *values) +{ + long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; + char *params = NULL; + int rc = 0; + int devices = GET_NEXT(values, param_max_offset, rc); + int num_commands = GET_NEXT(values, param_max_offset, rc); + int *updt_params, i, prev_enable_flag; + uint32_t params_length = (MAX_INBAND_PARAM_SZ); + + pr_debug("%s\n", __func__); + if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { + pr_err("%s: cannot set audio effects\n", __func__); + return -EINVAL; + } + params = kzalloc(params_length, GFP_KERNEL); + if (!params) + return -ENOMEM; + + pr_debug("%s: device: %d\n", __func__, devices); + updt_params = (int *)params; + params_length = 0; + for (i = 0; i < num_commands; i++) { + uint32_t command_id = + GET_NEXT(values, param_max_offset, rc); + uint32_t command_config_state = + GET_NEXT(values, param_max_offset, rc); + uint32_t index_offset = + GET_NEXT(values, param_max_offset, rc); + uint32_t length = + GET_NEXT(values, param_max_offset, rc); + switch (command_id) { + case BASS_BOOST_ENABLE: + if (length != 1 || index_offset != 0) { + pr_err("BASS_BOOST_ENABLE:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + prev_enable_flag = bass_boost->enable_flag; + bass_boost->enable_flag = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: BASS_BOOST_ENABLE prev:%d new:%d\n", + __func__, prev_enable_flag, + bass_boost->enable_flag); + if (prev_enable_flag != bass_boost->enable_flag) { + params_length += COMMAND_PAYLOAD_SZ + + BASS_BOOST_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "BASS_BOOST_ENABLE", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_BASS_BOOST; + *updt_params++ = + AUDPROC_PARAM_ID_BASS_BOOST_ENABLE; + *updt_params++ = + BASS_BOOST_ENABLE_PARAM_SZ; + *updt_params++ = + bass_boost->enable_flag; + } + break; + case BASS_BOOST_MODE: + if (length != 1 || index_offset != 0) { + pr_err("BASS_BOOST_MODE:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + bass_boost->mode = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: BASS_BOOST_MODE val:%d\n", + __func__, bass_boost->mode); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + BASS_BOOST_MODE_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "BASS_BOOST_MODE", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_BASS_BOOST; + *updt_params++ = + AUDPROC_PARAM_ID_BASS_BOOST_MODE; + *updt_params++ = + BASS_BOOST_MODE_PARAM_SZ; + *updt_params++ = + bass_boost->mode; + } + break; + case BASS_BOOST_STRENGTH: + if (length != 1 || index_offset != 0) { + pr_err("BASS_BOOST_STRENGTH:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + bass_boost->strength = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: BASS_BOOST_STRENGTH val:%d\n", + __func__, bass_boost->strength); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + BASS_BOOST_STRENGTH_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "BASS_BOOST_STRENGTH", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_BASS_BOOST; + *updt_params++ = + AUDPROC_PARAM_ID_BASS_BOOST_STRENGTH; + *updt_params++ = + BASS_BOOST_STRENGTH_PARAM_SZ; + *updt_params++ = + bass_boost->strength; + } + break; + default: + pr_err("%s: Invalid command to set config\n", __func__); + break; + } + } + if (params_length && (rc == 0)) + q6asm_send_audio_effects_params(ac, params, + params_length); + else + pr_debug("%s: did not send pp params\n", __func__); +invalid_config: + kfree(params); + return rc; +} + +int msm_audio_effects_pbe_handler(struct audio_client *ac, + struct pbe_params *pbe, + long *values) +{ + long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; + char *params = NULL; + int rc = 0; + int devices = GET_NEXT(values, param_max_offset, rc); + int num_commands = GET_NEXT(values, param_max_offset, rc); + int *updt_params, i, j, prev_enable_flag; + uint32_t params_length = (MAX_INBAND_PARAM_SZ); + + pr_debug("%s\n", __func__); + if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { + pr_err("%s: cannot set audio effects\n", __func__); + return -EINVAL; + } + params = kzalloc(params_length, GFP_KERNEL); + if (!params) + return -ENOMEM; + + pr_debug("%s: device: %d\n", __func__, devices); + updt_params = (int *)params; + params_length = 0; + for (i = 0; i < num_commands; i++) { + uint32_t command_id = + GET_NEXT(values, param_max_offset, rc); + uint32_t command_config_state = + GET_NEXT(values, param_max_offset, rc); + uint32_t index_offset = + GET_NEXT(values, param_max_offset, rc); + uint32_t length = + GET_NEXT(values, param_max_offset, rc); + switch (command_id) { + case PBE_ENABLE: + pr_debug("%s: PBE_ENABLE\n", __func__); + if (length != 1 || index_offset != 0) { + pr_err("no valid params\n"); + rc = -EINVAL; + goto invalid_config; + } + prev_enable_flag = pbe->enable_flag; + pbe->enable_flag = + GET_NEXT(values, param_max_offset, rc); + if (prev_enable_flag != pbe->enable_flag) { + params_length += COMMAND_PAYLOAD_SZ + + PBE_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "PBE_ENABLE", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_PBE; + *updt_params++ = + AUDPROC_PARAM_ID_PBE_ENABLE; + *updt_params++ = + PBE_ENABLE_PARAM_SZ; + *updt_params++ = + pbe->enable_flag; + } + break; + case PBE_CONFIG: + pr_debug("%s: PBE_PARAM length %u\n", __func__, length); + if (length > sizeof(struct pbe_config_t) || + length < PBE_CONFIG_PARAM_LEN || + index_offset != 0) { + pr_err("no valid params, len %d\n", length); + rc = -EINVAL; + goto invalid_config; + } + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + length; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "PBE_PARAM", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_PBE; + *updt_params++ = + AUDPROC_PARAM_ID_PBE_PARAM_CONFIG; + *updt_params++ = + length; + for (j = 0; j < length; ) { + j += sizeof(*updt_params); + *updt_params++ = + GET_NEXT( + values, + param_max_offset, + rc); + } + } + break; + default: + pr_err("%s: Invalid command to set config\n", __func__); + break; + } + } + if (params_length && (rc == 0)) + q6asm_send_audio_effects_params(ac, params, + params_length); +invalid_config: + kfree(params); + return rc; +} + +int msm_audio_effects_popless_eq_handler(struct audio_client *ac, + struct eq_params *eq, + long *values) +{ + long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; + char *params = NULL; + int rc = 0; + int devices = GET_NEXT(values, param_max_offset, rc); + int num_commands = GET_NEXT(values, param_max_offset, rc); + int *updt_params, i, prev_enable_flag; + uint32_t params_length = (MAX_INBAND_PARAM_SZ); + + pr_debug("%s\n", __func__); + if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { + pr_err("%s: cannot set audio effects\n", __func__); + return -EINVAL; + } + params = kzalloc(params_length, GFP_KERNEL); + if (!params) + return -ENOMEM; + + pr_debug("%s: device: %d\n", __func__, devices); + updt_params = (int *)params; + params_length = 0; + for (i = 0; i < num_commands; i++) { + uint32_t command_id = + GET_NEXT(values, param_max_offset, rc); + uint32_t command_config_state = + GET_NEXT(values, param_max_offset, rc); + uint32_t index_offset = + GET_NEXT(values, param_max_offset, rc); + uint32_t length = + GET_NEXT(values, param_max_offset, rc); + uint32_t idx; + int j; + + switch (command_id) { + case EQ_ENABLE: + if (length != 1 || index_offset != 0) { + pr_err("EQ_ENABLE:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + prev_enable_flag = eq->enable_flag; + eq->enable_flag = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: EQ_ENABLE prev:%d new:%d\n", __func__, + prev_enable_flag, eq->enable_flag); + if (prev_enable_flag != eq->enable_flag) { + params_length += COMMAND_PAYLOAD_SZ + + EQ_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "EQ_ENABLE", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_POPLESS_EQUALIZER; + *updt_params++ = + AUDPROC_PARAM_ID_EQ_ENABLE; + *updt_params++ = + EQ_ENABLE_PARAM_SZ; + *updt_params++ = + eq->enable_flag; + } + break; + case EQ_CONFIG: + if (length < EQ_CONFIG_PARAM_LEN || index_offset != 0) { + pr_err("EQ_CONFIG:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + pr_debug("%s: EQ_CONFIG bands:%d, pgain:%d, pset:%d\n", + __func__, eq->config.num_bands, + eq->config.eq_pregain, eq->config.preset_id); + for (idx = 0; idx < MAX_EQ_BANDS; idx++) + eq->per_band_cfg[idx].band_idx = -1; + eq->config.eq_pregain = + GET_NEXT(values, param_max_offset, rc); + eq->config.preset_id = + GET_NEXT(values, param_max_offset, rc); + eq->config.num_bands = + GET_NEXT(values, param_max_offset, rc); + if (eq->config.num_bands > MAX_EQ_BANDS) { + pr_err("EQ_CONFIG:invalid num of bands\n"); + rc = -EINVAL; + goto invalid_config; + } + if (eq->config.num_bands && + (((length - EQ_CONFIG_PARAM_LEN)/ + EQ_CONFIG_PER_BAND_PARAM_LEN) + != eq->config.num_bands)) { + pr_err("EQ_CONFIG:invalid length per band\n"); + rc = -EINVAL; + goto invalid_config; + } + for (j = 0; j < eq->config.num_bands; j++) { + idx = GET_NEXT(values, param_max_offset, rc); + if (idx >= MAX_EQ_BANDS) { + pr_err("EQ_CONFIG:invalid band index\n"); + rc = -EINVAL; + goto invalid_config; + } + eq->per_band_cfg[idx].band_idx = idx; + eq->per_band_cfg[idx].filter_type = + GET_NEXT(values, param_max_offset, rc); + eq->per_band_cfg[idx].freq_millihertz = + GET_NEXT(values, param_max_offset, rc); + eq->per_band_cfg[idx].gain_millibels = + GET_NEXT(values, param_max_offset, rc); + eq->per_band_cfg[idx].quality_factor = + GET_NEXT(values, param_max_offset, rc); + } + if (command_config_state == CONFIG_SET) { + int config_param_length = EQ_CONFIG_PARAM_SZ + + (EQ_CONFIG_PER_BAND_PARAM_SZ* + eq->config.num_bands); + params_length += COMMAND_PAYLOAD_SZ + + config_param_length; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "EQ_CONFIG", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_POPLESS_EQUALIZER; + *updt_params++ = + AUDPROC_PARAM_ID_EQ_CONFIG; + *updt_params++ = + config_param_length; + *updt_params++ = + eq->config.eq_pregain; + *updt_params++ = + eq->config.preset_id; + *updt_params++ = + eq->config.num_bands; + for (idx = 0; idx < MAX_EQ_BANDS; idx++) { + if (eq->per_band_cfg[idx].band_idx < 0) + continue; + *updt_params++ = + eq->per_band_cfg[idx].filter_type; + *updt_params++ = + eq->per_band_cfg[idx].freq_millihertz; + *updt_params++ = + eq->per_band_cfg[idx].gain_millibels; + *updt_params++ = + eq->per_band_cfg[idx].quality_factor; + *updt_params++ = + eq->per_band_cfg[idx].band_idx; + } + } + break; + case EQ_BAND_INDEX: + if (length != 1 || index_offset != 0) { + pr_err("EQ_BAND_INDEX:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + idx = GET_NEXT(values, param_max_offset, rc); + if (idx > MAX_EQ_BANDS) { + pr_err("EQ_BAND_INDEX:invalid band index\n"); + rc = -EINVAL; + goto invalid_config; + } + eq->band_index = idx; + pr_debug("%s: EQ_BAND_INDEX val:%d\n", + __func__, eq->band_index); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + EQ_BAND_INDEX_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "EQ_BAND_INDEX", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_POPLESS_EQUALIZER; + *updt_params++ = + AUDPROC_PARAM_ID_EQ_BAND_INDEX; + *updt_params++ = + EQ_BAND_INDEX_PARAM_SZ; + *updt_params++ = + eq->band_index; + } + break; + case EQ_SINGLE_BAND_FREQ: + if (length != 1 || index_offset != 0) { + pr_err("EQ_SINGLE_BAND_FREQ:invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + if (eq->band_index > MAX_EQ_BANDS) { + pr_err("EQ_SINGLE_BAND_FREQ:invalid index\n"); + break; + } + eq->freq_millihertz = + GET_NEXT(values, param_max_offset, rc); + pr_debug("%s: EQ_SINGLE_BAND_FREQ idx:%d, val:%d\n", + __func__, eq->band_index, eq->freq_millihertz); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + EQ_SINGLE_BAND_FREQ_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "EQ_SINGLE_BAND_FREQ", rc); + if (rc != 0) + break; + *updt_params++ = + AUDPROC_MODULE_ID_POPLESS_EQUALIZER; + *updt_params++ = + AUDPROC_PARAM_ID_EQ_SINGLE_BAND_FREQ; + *updt_params++ = + EQ_SINGLE_BAND_FREQ_PARAM_SZ; + *updt_params++ = + eq->freq_millihertz; + } + break; + default: + pr_err("%s: Invalid command to set config\n", __func__); + break; + } + } + if (params_length && (rc == 0)) + q6asm_send_audio_effects_params(ac, params, + params_length); + else + pr_debug("%s: did not send pp params\n", __func__); +invalid_config: + kfree(params); + return rc; +} + +static int __msm_audio_effects_volume_handler(struct audio_client *ac, + struct soft_volume_params *vol, + long *values, + int instance) +{ + int devices; + int num_commands; + char *params = NULL; + int *updt_params, i; + uint32_t params_length = (MAX_INBAND_PARAM_SZ); + long *param_max_offset; + int rc = 0; + + pr_debug("%s: instance: %d\n", __func__, instance); + if (!values) { + pr_err("%s: set audio effects failed, no valid data\n", + __func__); + return -EINVAL; + } + param_max_offset = values + MAX_PP_PARAMS_SZ - 1; + devices = GET_NEXT(values, param_max_offset, rc); + num_commands = GET_NEXT(values, param_max_offset, rc); + if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { + pr_err("%s: cannot set audio effects\n", __func__); + return -EINVAL; + } + params = kzalloc(params_length, GFP_KERNEL); + if (!params) + return -ENOMEM; + + updt_params = (int *)params; + params_length = 0; + for (i = 0; i < num_commands; i++) { + uint32_t command_id = + GET_NEXT(values, param_max_offset, rc); + uint32_t command_config_state = + GET_NEXT(values, param_max_offset, rc); + uint32_t index_offset = + GET_NEXT(values, param_max_offset, rc); + uint32_t length = + GET_NEXT(values, param_max_offset, rc); + switch (command_id) { + case SOFT_VOLUME_GAIN_2CH: + case SOFT_VOLUME2_GAIN_2CH: + if (length != 2 || index_offset != 0) { + pr_err("VOLUME_GAIN_2CH: invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + vol->left_gain = GET_NEXT(values, param_max_offset, rc); + vol->right_gain = + GET_NEXT(values, param_max_offset, rc); + vol->master_gain = 0x2000; + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + SOFT_VOLUME_GAIN_2CH_PARAM_SZ; + params_length += COMMAND_PAYLOAD_SZ + + SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "VOLUME/VOLUME2_GAIN_2CH", + rc); + if (rc != 0) + break; + if (instance == SOFT_VOLUME_INSTANCE_2) + *updt_params++ = + ASM_MODULE_ID_VOL_CTRL2; + else + *updt_params++ = + ASM_MODULE_ID_VOL_CTRL; + *updt_params++ = + ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN; + *updt_params++ = + SOFT_VOLUME_GAIN_2CH_PARAM_SZ; + *updt_params++ = + (vol->left_gain << 16) | + vol->right_gain; + if (instance == SOFT_VOLUME_INSTANCE_2) + *updt_params++ = + ASM_MODULE_ID_VOL_CTRL2; + else + *updt_params++ = + ASM_MODULE_ID_VOL_CTRL; + *updt_params++ = + ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; + *updt_params++ = + SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; + *updt_params++ = + vol->master_gain; + } + break; + case SOFT_VOLUME_GAIN_MASTER: + case SOFT_VOLUME2_GAIN_MASTER: + if (length != 1 || index_offset != 0) { + pr_err("VOLUME_GAIN_MASTER: invalid params\n"); + rc = -EINVAL; + goto invalid_config; + } + vol->left_gain = 0x2000; + vol->right_gain = 0x2000; + vol->master_gain = + GET_NEXT(values, param_max_offset, rc); + if (command_config_state == CONFIG_SET) { + params_length += COMMAND_PAYLOAD_SZ + + SOFT_VOLUME_GAIN_2CH_PARAM_SZ; + params_length += COMMAND_PAYLOAD_SZ + + SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; + CHECK_PARAM_LEN(params_length, + MAX_INBAND_PARAM_SZ, + "VOLUME/VOLUME2_GAIN_MASTER", + rc); + if (rc != 0) + break; + if (instance == SOFT_VOLUME_INSTANCE_2) + *updt_params++ = + ASM_MODULE_ID_VOL_CTRL2; + else + *updt_params++ = + ASM_MODULE_ID_VOL_CTRL; + *updt_params++ = + ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN; + *updt_params++ = + SOFT_VOLUME_GAIN_2CH_PARAM_SZ; + *updt_params++ = + (vol->left_gain << 16) | + vol->right_gain; + if (instance == SOFT_VOLUME_INSTANCE_2) + *updt_params++ = + ASM_MODULE_ID_VOL_CTRL2; + else + *updt_params++ = + ASM_MODULE_ID_VOL_CTRL; + *updt_params++ = + ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; + *updt_params++ = + SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; + *updt_params++ = + vol->master_gain; + } + break; + default: + pr_err("%s: Invalid command id: %d to set config\n", + __func__, command_id); + break; + } + } + if (params_length && (rc == 0)) + q6asm_send_audio_effects_params(ac, params, + params_length); +invalid_config: + kfree(params); + return rc; +} + +int msm_audio_effects_volume_handler(struct audio_client *ac, + struct soft_volume_params *vol, + long *values) +{ + return __msm_audio_effects_volume_handler(ac, vol, values, + SOFT_VOLUME_INSTANCE_1); +} + +int msm_audio_effects_volume_handler_v2(struct audio_client *ac, + struct soft_volume_params *vol, + long *values, int instance) +{ + return __msm_audio_effects_volume_handler(ac, vol, values, instance); +} diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c new file mode 100644 index 000000000000..c88526564d79 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c @@ -0,0 +1,4541 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include "msm-pcm-routing-v2.h" +#include "msm-qti-pp-config.h" + +#define DSP_PP_BUFFERING_IN_MSEC 25 +#define PARTIAL_DRAIN_ACK_EARLY_BY_MSEC 150 +#define MP3_OUTPUT_FRAME_SZ 1152 +#define AAC_OUTPUT_FRAME_SZ 1024 +#define AC3_OUTPUT_FRAME_SZ 1536 +#define EAC3_OUTPUT_FRAME_SZ 1536 +#define DSP_NUM_OUTPUT_FRAME_BUFFERED 2 +#define FLAC_BLK_SIZE_LIMIT 65535 + +/* Timestamp mode payload offsets */ +#define CAPTURE_META_DATA_TS_OFFSET_LSW 6 +#define CAPTURE_META_DATA_TS_OFFSET_MSW 7 + +/* decoder parameter length */ +#define DDP_DEC_MAX_NUM_PARAM 18 + +/* Default values used if user space does not set */ +#define COMPR_PLAYBACK_MIN_FRAGMENT_SIZE (8 * 1024) +#define COMPR_PLAYBACK_MAX_FRAGMENT_SIZE (128 * 1024) +#define COMPR_PLAYBACK_MIN_NUM_FRAGMENTS (4) +#define COMPR_PLAYBACK_MAX_NUM_FRAGMENTS (16 * 4) + +#define COMPRESSED_LR_VOL_MAX_STEPS 0x2000 +const DECLARE_TLV_DB_LINEAR(msm_compr_vol_gain, 0, + COMPRESSED_LR_VOL_MAX_STEPS); + +/* Stream id switches between 1 and 2 */ +#define NEXT_STREAM_ID(stream_id) ((stream_id & 1) + 1) + +#define STREAM_ARRAY_INDEX(stream_id) (stream_id - 1) + +#define MAX_NUMBER_OF_STREAMS 2 + +struct msm_compr_gapless_state { + bool set_next_stream_id; + int32_t stream_opened[MAX_NUMBER_OF_STREAMS]; + uint32_t initial_samples_drop; + uint32_t trailing_samples_drop; + uint32_t gapless_transition; + bool use_dsp_gapless_mode; + union snd_codec_options codec_options; +}; + +static unsigned int supported_sample_rates[] = { + 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, + 88200, 96000, 128000, 144000, 176400, 192000, 352800, 384000, 2822400, + 5644800 +}; + +struct msm_compr_pdata { + struct snd_compr_stream *cstream[MSM_FRONTEND_DAI_MAX]; + uint32_t volume[MSM_FRONTEND_DAI_MAX][2]; /* For both L & R */ + struct msm_compr_audio_effects *audio_effects[MSM_FRONTEND_DAI_MAX]; + bool use_dsp_gapless_mode; + bool use_legacy_api; /* indicates use older asm apis*/ + struct msm_compr_dec_params *dec_params[MSM_FRONTEND_DAI_MAX]; + struct msm_compr_ch_map *ch_map[MSM_FRONTEND_DAI_MAX]; +}; + +struct msm_compr_audio { + struct snd_compr_stream *cstream; + struct snd_compr_caps compr_cap; + struct snd_compr_codec_caps codec_caps; + struct snd_compr_params codec_param; + struct audio_client *audio_client; + + uint32_t codec; + uint32_t compr_passthr; + void *buffer; /* virtual address */ + phys_addr_t buffer_paddr; /* physical address */ + uint32_t app_pointer; + uint32_t buffer_size; + uint32_t byte_offset; + uint64_t copied_total; /* bytes consumed by DSP */ + uint64_t bytes_received; /* from userspace */ + uint64_t bytes_sent; /* to DSP */ + + uint64_t received_total; /* bytes received from DSP */ + uint64_t bytes_copied; /* to userspace */ + uint64_t bytes_read; /* from DSP */ + uint32_t bytes_read_offset; /* bytes read offset */ + + uint32_t ts_header_offset; /* holds the timestamp header offset */ + + int32_t first_buffer; + int32_t last_buffer; + int32_t partial_drain_delay; + + uint16_t session_id; + + uint32_t sample_rate; + uint32_t num_channels; + + /* + * convention - commands coming from the same thread + * can use the common cmd_ack var. Others (e.g drain/EOS) + * must use separate vars to track command status. + */ + uint32_t cmd_ack; + uint32_t cmd_interrupt; + uint32_t drain_ready; + uint32_t eos_ack; + + uint32_t stream_available; + uint32_t next_stream; + + uint32_t run_mode; + uint32_t start_delay_lsw; + uint32_t start_delay_msw; + + uint64_t marker_timestamp; + + struct msm_compr_gapless_state gapless_state; + + atomic_t start; + atomic_t eos; + atomic_t drain; + atomic_t xrun; + atomic_t close; + atomic_t wait_on_close; + atomic_t error; + + wait_queue_head_t eos_wait; + wait_queue_head_t drain_wait; + wait_queue_head_t close_wait; + wait_queue_head_t wait_for_stream_avail; + + spinlock_t lock; +}; + +const u32 compr_codecs[] = { + SND_AUDIOCODEC_AC3, SND_AUDIOCODEC_EAC3, SND_AUDIOCODEC_DTS, + SND_AUDIOCODEC_DSD, SND_AUDIOCODEC_TRUEHD, SND_AUDIOCODEC_IEC61937}; + +struct query_audio_effect { + uint32_t mod_id; + uint32_t parm_id; + uint32_t size; + uint32_t offset; + uint32_t device; +}; + +struct msm_compr_audio_effects { + struct bass_boost_params bass_boost; + struct pbe_params pbe; + struct virtualizer_params virtualizer; + struct reverb_params reverb; + struct eq_params equalizer; + struct soft_volume_params volume; + struct query_audio_effect query; +}; + +struct msm_compr_dec_params { + struct snd_dec_ddp ddp_params; +}; + +struct msm_compr_ch_map { + bool set_ch_map; + char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL]; +}; + +static int msm_compr_send_dec_params(struct snd_compr_stream *cstream, + struct msm_compr_dec_params *dec_params, + int stream_id); + +static int msm_compr_set_render_mode(struct msm_compr_audio *prtd, + uint32_t render_mode) { + int ret = -EINVAL; + struct audio_client *ac = prtd->audio_client; + + pr_debug("%s, got render mode %u\n", __func__, render_mode); + + if (render_mode == SNDRV_COMPRESS_RENDER_MODE_AUDIO_MASTER) { + render_mode = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_DEFAULT; + } else if (render_mode == SNDRV_COMPRESS_RENDER_MODE_STC_MASTER) { + render_mode = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_LOCAL_STC; + prtd->run_mode = ASM_SESSION_CMD_RUN_STARTIME_RUN_WITH_DELAY; + } else { + pr_err("%s, Invalid render mode %u\n", __func__, + render_mode); + ret = -EINVAL; + goto exit; + } + + ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode); + if (ret) { + pr_err("%s, Render mode can't be set error %d\n", __func__, + ret); + } +exit: + return ret; +} + +static int msm_compr_set_clk_rec_mode(struct audio_client *ac, + uint32_t clk_rec_mode) { + int ret = -EINVAL; + + pr_debug("%s, got clk rec mode %u\n", __func__, clk_rec_mode); + + if (clk_rec_mode == SNDRV_COMPRESS_CLK_REC_MODE_NONE) { + clk_rec_mode = ASM_SESSION_MTMX_STRTR_PARAM_CLK_REC_NONE; + } else if (clk_rec_mode == SNDRV_COMPRESS_CLK_REC_MODE_AUTO) { + clk_rec_mode = ASM_SESSION_MTMX_STRTR_PARAM_CLK_REC_AUTO; + } else { + pr_err("%s, Invalid clk rec_mode mode %u\n", __func__, + clk_rec_mode); + ret = -EINVAL; + goto exit; + } + + ret = q6asm_send_mtmx_strtr_clk_rec_mode(ac, clk_rec_mode); + if (ret) { + pr_err("%s, clk rec mode can't be set, error %d\n", __func__, + ret); + } + +exit: + return ret; +} + +static int msm_compr_set_render_window(struct audio_client *ac, + uint32_t ws_lsw, uint32_t ws_msw, + uint32_t we_lsw, uint32_t we_msw) +{ + int ret = -EINVAL; + struct asm_session_mtmx_strtr_param_window_v2_t asm_mtmx_strtr_window; + uint32_t param_id; + + pr_debug("%s, ws_lsw 0x%x ws_msw 0x%x we_lsw 0x%x we_ms 0x%x\n", + __func__, ws_lsw, ws_msw, we_lsw, we_msw); + + memset(&asm_mtmx_strtr_window, 0, + sizeof(struct asm_session_mtmx_strtr_param_window_v2_t)); + asm_mtmx_strtr_window.window_lsw = ws_lsw; + asm_mtmx_strtr_window.window_msw = ws_msw; + param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_START_V2; + ret = q6asm_send_mtmx_strtr_window(ac, &asm_mtmx_strtr_window, + param_id); + if (ret) { + pr_err("%s, start window can't be set error %d\n", __func__, + ret); + goto exit; + } + + asm_mtmx_strtr_window.window_lsw = we_lsw; + asm_mtmx_strtr_window.window_msw = we_msw; + param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_END_V2; + ret = q6asm_send_mtmx_strtr_window(ac, &asm_mtmx_strtr_window, + param_id); + if (ret) { + pr_err("%s, end window can't be set error %d\n", __func__, + ret); + } + +exit: + return ret; +} + +static int msm_compr_enable_adjust_session_clock(struct audio_client *ac, + bool enable) +{ + int ret; + + pr_debug("%s, enable adjust_session %d\n", __func__, enable); + + ret = q6asm_send_mtmx_strtr_enable_adjust_session_clock(ac, enable); + if (ret) + pr_err("%s, adjust session clock can't be set error %d\n", + __func__, ret); + + return ret; +} + +static int msm_compr_adjust_session_clock(struct audio_client *ac, + uint32_t adjust_session_lsw, uint32_t adjust_session_msw) +{ + int ret; + + pr_debug("%s, adjust_session_time_msw 0x%x adjust_session_time_lsw 0x%x\n", + __func__, adjust_session_msw, adjust_session_lsw); + + ret = q6asm_adjust_session_clock(ac, + adjust_session_lsw, + adjust_session_msw); + if (ret) + pr_err("%s, adjust session clock can't be set error %d\n", + __func__, ret); + + return ret; +} + +static int msm_compr_set_volume(struct snd_compr_stream *cstream, + uint32_t volume_l, uint32_t volume_r) +{ + struct msm_compr_audio *prtd; + int rc = 0; + uint32_t avg_vol, gain_list[VOLUME_CONTROL_MAX_CHANNELS]; + uint32_t num_channels; + struct snd_soc_pcm_runtime *rtd; + struct msm_compr_pdata *pdata; + bool use_default = true; + u8 *chmap = NULL; + + pr_debug("%s: volume_l %d volume_r %d\n", + __func__, volume_l, volume_r); + if (!cstream || !cstream->runtime) { + pr_err("%s: session not active\n", __func__); + return -EPERM; + } + rtd = cstream->private_data; + prtd = cstream->runtime->private_data; + + if (!rtd || !rtd->platform || !prtd || !prtd->audio_client) { + pr_err("%s: invalid rtd, prtd or audio client", __func__); + return rc; + } + pdata = snd_soc_platform_get_drvdata(rtd->platform); + + if (prtd->compr_passthr != LEGACY_PCM) { + pr_debug("%s: No volume config for passthrough %d\n", + __func__, prtd->compr_passthr); + return rc; + } + + use_default = !(pdata->ch_map[rtd->dai_link->id]->set_ch_map); + chmap = pdata->ch_map[rtd->dai_link->id]->channel_map; + num_channels = prtd->num_channels; + + if (prtd->num_channels > 2) { + /* + * Currently the left and right gains are averaged an applied + * to all channels. This might not be desirable. But currently, + * there exists no API in userspace to send a list of gains for + * each channel either. If such an API does become available, + * the mixer control must be updated to accept more than 2 + * channel gains. + * + */ + avg_vol = (volume_l + volume_r) / 2; + rc = q6asm_set_volume(prtd->audio_client, avg_vol); + } else { + gain_list[0] = volume_l; + gain_list[1] = volume_r; + /* force sending FR/FL/FC volume for mono */ + if (prtd->num_channels == 1) { + gain_list[2] = volume_l; + num_channels = 3; + use_default = true; + } + rc = q6asm_set_multich_gain(prtd->audio_client, num_channels, + gain_list, chmap, use_default); + } + + if (rc < 0) + pr_err("%s: Send vol gain command failed rc=%d\n", + __func__, rc); + + return rc; +} + +static int msm_compr_send_ddp_cfg(struct audio_client *ac, + struct snd_dec_ddp *ddp, + int stream_id) +{ + int i, rc; + + pr_debug("%s\n", __func__); + for (i = 0; i < ddp->params_length; i++) { + rc = q6asm_ds1_set_stream_endp_params(ac, ddp->params_id[i], + ddp->params_value[i], + stream_id); + if (rc) { + pr_err("sending params_id: %d failed\n", + ddp->params_id[i]); + return rc; + } + } + return 0; +} + +static int msm_compr_send_buffer(struct msm_compr_audio *prtd) +{ + int buffer_length; + uint64_t bytes_available; + struct audio_aio_write_param param; + struct snd_codec_metadata *buff_addr; + + if (!atomic_read(&prtd->start)) { + pr_err("%s: stream is not in started state\n", __func__); + return -EINVAL; + } + + + if (atomic_read(&prtd->xrun)) { + WARN(1, "%s called while xrun is true", __func__); + return -EPERM; + } + + pr_debug("%s: bytes_received = %llu copied_total = %llu\n", + __func__, prtd->bytes_received, prtd->copied_total); + if (prtd->first_buffer && prtd->gapless_state.use_dsp_gapless_mode && + prtd->compr_passthr == LEGACY_PCM) + q6asm_stream_send_meta_data(prtd->audio_client, + prtd->audio_client->stream_id, + prtd->gapless_state.initial_samples_drop, + prtd->gapless_state.trailing_samples_drop); + + buffer_length = prtd->codec_param.buffer.fragment_size; + bytes_available = prtd->bytes_received - prtd->copied_total; + if (bytes_available < prtd->codec_param.buffer.fragment_size) + buffer_length = bytes_available; + + if (prtd->byte_offset + buffer_length > prtd->buffer_size) { + buffer_length = (prtd->buffer_size - prtd->byte_offset); + pr_debug("%s: wrap around situation, send partial data %d now", + __func__, buffer_length); + } + + if (buffer_length) { + param.paddr = prtd->buffer_paddr + prtd->byte_offset; + WARN(prtd->byte_offset % 32 != 0, "offset %x not multiple of 32\n", + prtd->byte_offset); + } else { + param.paddr = prtd->buffer_paddr; + } + param.len = buffer_length; + if (prtd->ts_header_offset) { + buff_addr = (struct snd_codec_metadata *) + (prtd->buffer + prtd->byte_offset); + param.len = buff_addr->length; + param.msw_ts = (uint32_t) + ((buff_addr->timestamp & 0xFFFFFFFF00000000LL) >> 32); + param.lsw_ts = (uint32_t) (buff_addr->timestamp & 0xFFFFFFFFLL); + param.paddr += prtd->ts_header_offset; + param.flags = SET_TIMESTAMP; + param.metadata_len = prtd->ts_header_offset; + } else { + param.msw_ts = 0; + param.lsw_ts = 0; + param.flags = NO_TIMESTAMP; + param.metadata_len = 0; + } + param.uid = buffer_length; + param.last_buffer = prtd->last_buffer; + + pr_debug("%s: sending %d bytes to DSP byte_offset = %d\n", + __func__, param.len, prtd->byte_offset); + if (q6asm_async_write(prtd->audio_client, ¶m) < 0) { + pr_err("%s:q6asm_async_write failed\n", __func__); + } else { + prtd->bytes_sent += buffer_length; + if (prtd->first_buffer) + prtd->first_buffer = 0; + } + + return 0; +} + +static int msm_compr_read_buffer(struct msm_compr_audio *prtd) +{ + int buffer_length; + uint64_t bytes_available; + uint64_t buffer_sent; + struct audio_aio_read_param param; + int ret; + + if (!atomic_read(&prtd->start)) { + pr_err("%s: stream is not in started state\n", __func__); + return -EINVAL; + } + + buffer_length = prtd->codec_param.buffer.fragment_size - + prtd->ts_header_offset; + bytes_available = prtd->received_total - prtd->bytes_copied; + buffer_sent = prtd->bytes_read - prtd->bytes_copied; + if (buffer_sent + buffer_length + prtd->ts_header_offset + > prtd->buffer_size) { + pr_debug(" %s : Buffer is Full bytes_available: %llu\n", + __func__, bytes_available); + return 0; + } + + memset(¶m, 0x0, sizeof(struct audio_aio_read_param)); + param.paddr = prtd->buffer_paddr + prtd->bytes_read_offset + + prtd->ts_header_offset; + param.len = buffer_length; + param.uid = buffer_length; + param.flags = prtd->codec_param.codec.flags; + + pr_debug("%s: reading %d bytes from DSP byte_offset = %llu\n", + __func__, buffer_length, prtd->bytes_read); + ret = q6asm_async_read(prtd->audio_client, ¶m); + if (ret < 0) { + pr_err("%s: q6asm_async_read failed - %d\n", + __func__, ret); + return ret; + } + prtd->bytes_read += buffer_length; + prtd->bytes_read_offset += buffer_length; + if (prtd->bytes_read_offset >= prtd->buffer_size) + prtd->bytes_read_offset -= prtd->buffer_size; + + return 0; +} + +static void compr_event_handler(uint32_t opcode, + uint32_t token, uint32_t *payload, void *priv) +{ + struct msm_compr_audio *prtd = priv; + struct snd_compr_stream *cstream; + struct audio_client *ac; + uint32_t chan_mode = 0; + uint32_t sample_rate = 0; + uint64_t bytes_available; + int stream_id; + uint32_t stream_index; + unsigned long flags; + uint64_t read_size; + uint32_t *buff_addr; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + + if (!prtd) { + pr_err("%s: prtd is NULL\n", __func__); + return; + } + cstream = prtd->cstream; + if (!cstream) { + pr_err("%s: cstream is NULL\n", __func__); + return; + } + + ac = prtd->audio_client; + + /* + * Token for rest of the compressed commands use to set + * session id, stream id, dir etc. + */ + stream_id = q6asm_get_stream_id_from_token(token); + + pr_debug("%s opcode =%08x\n", __func__, opcode); + switch (opcode) { + case ASM_DATA_EVENT_WRITE_DONE_V2: + spin_lock_irqsave(&prtd->lock, flags); + + if (payload[3]) { + pr_err("%s: WRITE FAILED w/ err 0x%x !, paddr 0x%x, byte_offset=%d,copied_total=%llu,token=%d\n", + __func__, + payload[3], + payload[0], + prtd->byte_offset, + prtd->copied_total, token); + + if (atomic_cmpxchg(&prtd->drain, 1, 0) && + prtd->last_buffer) { + pr_debug("%s: wake up on drain\n", __func__); + prtd->drain_ready = 1; + wake_up(&prtd->drain_wait); + prtd->last_buffer = 0; + } else { + atomic_set(&prtd->start, 0); + } + } else { + pr_debug("ASM_DATA_EVENT_WRITE_DONE_V2 offset %d, length %d\n", + prtd->byte_offset, token); + } + + /* + * Token for WRITE command represents the amount of data + * written to ADSP in the last write, update offset and + * total copied data accordingly. + */ + if (prtd->ts_header_offset) { + /* Always assume that the data will be sent to DSP on + * frame boundary. + * i.e, one frame of userspace write will result in + * one kernel write to DSP. This is needed as + * timestamp will be sent per frame. + */ + prtd->byte_offset += + prtd->codec_param.buffer.fragment_size; + prtd->copied_total += + prtd->codec_param.buffer.fragment_size; + } else { + prtd->byte_offset += token; + prtd->copied_total += token; + } + if (prtd->byte_offset >= prtd->buffer_size) + prtd->byte_offset -= prtd->buffer_size; + + snd_compr_fragment_elapsed(cstream); + + if (!atomic_read(&prtd->start)) { + /* Writes must be restarted from _copy() */ + pr_debug("write_done received while not started, treat as xrun"); + atomic_set(&prtd->xrun, 1); + spin_unlock_irqrestore(&prtd->lock, flags); + break; + } + + bytes_available = prtd->bytes_received - prtd->copied_total; + if (bytes_available < cstream->runtime->fragment_size) { + pr_debug("WRITE_DONE Insufficient data to send. break out\n"); + atomic_set(&prtd->xrun, 1); + + if (prtd->last_buffer) + prtd->last_buffer = 0; + if (atomic_read(&prtd->drain)) { + pr_debug("wake up on drain\n"); + prtd->drain_ready = 1; + wake_up(&prtd->drain_wait); + atomic_set(&prtd->drain, 0); + } + } else if ((bytes_available == cstream->runtime->fragment_size) + && atomic_read(&prtd->drain)) { + prtd->last_buffer = 1; + msm_compr_send_buffer(prtd); + prtd->last_buffer = 0; + } else + msm_compr_send_buffer(prtd); + + spin_unlock_irqrestore(&prtd->lock, flags); + break; + + case ASM_DATA_EVENT_READ_DONE_V2: + spin_lock_irqsave(&prtd->lock, flags); + + pr_debug("ASM_DATA_EVENT_READ_DONE_V2 offset %d, length %d\n", + prtd->byte_offset, payload[4]); + + if (prtd->ts_header_offset) { + /* Update the header for received buffer */ + buff_addr = prtd->buffer + prtd->byte_offset; + /* Write the length of the buffer */ + *buff_addr = prtd->codec_param.buffer.fragment_size + - prtd->ts_header_offset; + buff_addr++; + /* Write the offset */ + *buff_addr = prtd->ts_header_offset; + buff_addr++; + /* Write the TS LSW */ + *buff_addr = payload[CAPTURE_META_DATA_TS_OFFSET_LSW]; + buff_addr++; + /* Write the TS MSW */ + *buff_addr = payload[CAPTURE_META_DATA_TS_OFFSET_MSW]; + } + /* Always assume read_size is same as fragment_size */ + read_size = prtd->codec_param.buffer.fragment_size; + prtd->byte_offset += read_size; + prtd->received_total += read_size; + if (prtd->byte_offset >= prtd->buffer_size) + prtd->byte_offset -= prtd->buffer_size; + + snd_compr_fragment_elapsed(cstream); + + if (!atomic_read(&prtd->start)) { + pr_debug("read_done received while not started, treat as xrun"); + atomic_set(&prtd->xrun, 1); + spin_unlock_irqrestore(&prtd->lock, flags); + break; + } + msm_compr_read_buffer(prtd); + + spin_unlock_irqrestore(&prtd->lock, flags); + break; + + case ASM_DATA_EVENT_RENDERED_EOS: + spin_lock_irqsave(&prtd->lock, flags); + pr_debug("%s: ASM_DATA_CMDRSP_EOS token 0x%x,stream id %d\n", + __func__, token, stream_id); + if (atomic_read(&prtd->eos) && + !prtd->gapless_state.set_next_stream_id) { + pr_debug("ASM_DATA_CMDRSP_EOS wake up\n"); + prtd->eos_ack = 1; + wake_up(&prtd->eos_wait); + } + atomic_set(&prtd->eos, 0); + stream_index = STREAM_ARRAY_INDEX(stream_id); + if (stream_index >= MAX_NUMBER_OF_STREAMS || + stream_index < 0) { + pr_err("%s: Invalid stream index %d", __func__, + stream_index); + spin_unlock_irqrestore(&prtd->lock, flags); + break; + } + + if (prtd->gapless_state.set_next_stream_id && + prtd->gapless_state.stream_opened[stream_index]) { + pr_debug("%s: CMD_CLOSE stream_id %d\n", + __func__, stream_id); + q6asm_stream_cmd_nowait(ac, CMD_CLOSE, stream_id); + atomic_set(&prtd->close, 1); + prtd->gapless_state.stream_opened[stream_index] = 0; + prtd->gapless_state.set_next_stream_id = false; + } + if (prtd->gapless_state.gapless_transition) + prtd->gapless_state.gapless_transition = 0; + spin_unlock_irqrestore(&prtd->lock, flags); + break; + case ASM_STREAM_PP_EVENT: + case ASM_STREAM_CMD_ENCDEC_EVENTS: + pr_debug("%s: ASM_STREAM_EVENT(0x%x)\n", __func__, opcode); + rtd = cstream->private_data; + if (!rtd) { + pr_err("%s: rtd is NULL\n", __func__); + return; + } + + ret = msm_adsp_inform_mixer_ctl(rtd, payload); + if (ret) { + pr_err("%s: failed to inform mixer ctrl. err = %d\n", + __func__, ret); + return; + } + break; + case ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY: + case ASM_DATA_EVENT_ENC_SR_CM_CHANGE_NOTIFY: { + pr_debug("ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY\n"); + chan_mode = payload[1] >> 16; + sample_rate = payload[2] >> 16; + if (prtd && (chan_mode != prtd->num_channels || + sample_rate != prtd->sample_rate)) { + prtd->num_channels = chan_mode; + prtd->sample_rate = sample_rate; + } + } + /* Fallthrough here */ + case APR_BASIC_RSP_RESULT: { + switch (payload[0]) { + case ASM_SESSION_CMD_RUN_V2: + /* check if the first buffer need to be sent to DSP */ + pr_debug("ASM_SESSION_CMD_RUN_V2\n"); + + /* FIXME: A state is a better way, dealing with this */ + spin_lock_irqsave(&prtd->lock, flags); + + if (cstream->direction == SND_COMPRESS_CAPTURE) { + atomic_set(&prtd->start, 1); + msm_compr_read_buffer(prtd); + spin_unlock_irqrestore(&prtd->lock, flags); + break; + } + + if (!prtd->bytes_sent) { + bytes_available = prtd->bytes_received - + prtd->copied_total; + if (bytes_available < + cstream->runtime->fragment_size) { + pr_debug("CMD_RUN_V2 Insufficient data to send. break out\n"); + atomic_set(&prtd->xrun, 1); + } else { + msm_compr_send_buffer(prtd); + } + } + + /* + * The condition below ensures playback finishes in the + * follow cornercase + * WRITE(last buffer) + * WAIT_FOR_DRAIN + * PAUSE + * WRITE_DONE(X) + * RESUME + */ + if ((prtd->copied_total == prtd->bytes_sent) && + atomic_read(&prtd->drain)) { + pr_debug("RUN ack, wake up & continue pending drain\n"); + + if (prtd->last_buffer) + prtd->last_buffer = 0; + + prtd->drain_ready = 1; + wake_up(&prtd->drain_wait); + atomic_set(&prtd->drain, 0); + } + + spin_unlock_irqrestore(&prtd->lock, flags); + break; + case ASM_STREAM_CMD_FLUSH: + pr_debug("%s: ASM_STREAM_CMD_FLUSH:", __func__); + pr_debug("token 0x%x, stream id %d\n", token, + stream_id); + prtd->cmd_ack = 1; + break; + case ASM_DATA_CMD_REMOVE_INITIAL_SILENCE: + pr_debug("%s: ASM_DATA_CMD_REMOVE_INITIAL_SILENCE:", + __func__); + pr_debug("token 0x%x, stream id = %d\n", token, + stream_id); + break; + case ASM_DATA_CMD_REMOVE_TRAILING_SILENCE: + pr_debug("%s: ASM_DATA_CMD_REMOVE_TRAILING_SILENCE:", + __func__); + pr_debug("token = 0x%x, stream id = %d\n", token, + stream_id); + break; + case ASM_STREAM_CMD_CLOSE: + pr_debug("%s: ASM_DATA_CMD_CLOSE:", __func__); + pr_debug("token 0x%x, stream id %d\n", token, + stream_id); + /* + * wakeup wait for stream avail on stream 3 + * after stream 1 ends. + */ + if (prtd->next_stream) { + pr_debug("%s:CLOSE:wakeup wait for stream\n", + __func__); + prtd->stream_available = 1; + wake_up(&prtd->wait_for_stream_avail); + prtd->next_stream = 0; + } + if (atomic_read(&prtd->close) && + atomic_read(&prtd->wait_on_close)) { + prtd->cmd_ack = 1; + wake_up(&prtd->close_wait); + } + atomic_set(&prtd->close, 0); + break; + case ASM_STREAM_CMD_REGISTER_PP_EVENTS: + pr_debug("%s: ASM_STREAM_CMD_REGISTER_PP_EVENTS:", + __func__); + break; + default: + break; + } + break; + } + case ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3: + pr_debug("%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3\n", + __func__); + break; + case RESET_EVENTS: + pr_err("%s: Received reset events CB, move to error state", + __func__); + spin_lock_irqsave(&prtd->lock, flags); + /* + * Since ADSP is down, let this driver pretend that it copied + * all the bytes received, so that next write will be triggered + */ + prtd->copied_total = prtd->bytes_received; + snd_compr_fragment_elapsed(cstream); + atomic_set(&prtd->error, 1); + wake_up(&prtd->drain_wait); + if (atomic_cmpxchg(&prtd->eos, 1, 0)) { + pr_debug("%s:unblock eos wait queues", __func__); + wake_up(&prtd->eos_wait); + } + spin_unlock_irqrestore(&prtd->lock, flags); + break; + default: + pr_debug("%s: Not Supported Event opcode[0x%x]\n", + __func__, opcode); + break; + } +} + +static int msm_compr_get_partial_drain_delay(int frame_sz, int sample_rate) +{ + int delay_time_ms = 0; + + delay_time_ms = ((DSP_NUM_OUTPUT_FRAME_BUFFERED * frame_sz * 1000) / + sample_rate) + DSP_PP_BUFFERING_IN_MSEC; + delay_time_ms = delay_time_ms > PARTIAL_DRAIN_ACK_EARLY_BY_MSEC ? + delay_time_ms - PARTIAL_DRAIN_ACK_EARLY_BY_MSEC : 0; + + pr_debug("%s: frame_sz %d, sample_rate %d, partial drain delay %d\n", + __func__, frame_sz, sample_rate, delay_time_ms); + return delay_time_ms; +} + +static void populate_codec_list(struct msm_compr_audio *prtd) +{ + pr_debug("%s\n", __func__); + prtd->compr_cap.direction = SND_COMPRESS_PLAYBACK; + prtd->compr_cap.min_fragment_size = + COMPR_PLAYBACK_MIN_FRAGMENT_SIZE; + prtd->compr_cap.max_fragment_size = + COMPR_PLAYBACK_MAX_FRAGMENT_SIZE; + prtd->compr_cap.min_fragments = + COMPR_PLAYBACK_MIN_NUM_FRAGMENTS; + prtd->compr_cap.max_fragments = + COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; + prtd->compr_cap.num_codecs = 17; + prtd->compr_cap.codecs[0] = SND_AUDIOCODEC_MP3; + prtd->compr_cap.codecs[1] = SND_AUDIOCODEC_AAC; + prtd->compr_cap.codecs[2] = SND_AUDIOCODEC_AC3; + prtd->compr_cap.codecs[3] = SND_AUDIOCODEC_EAC3; + prtd->compr_cap.codecs[4] = SND_AUDIOCODEC_MP2; + prtd->compr_cap.codecs[5] = SND_AUDIOCODEC_PCM; + prtd->compr_cap.codecs[6] = SND_AUDIOCODEC_WMA; + prtd->compr_cap.codecs[7] = SND_AUDIOCODEC_WMA_PRO; + prtd->compr_cap.codecs[8] = SND_AUDIOCODEC_FLAC; + prtd->compr_cap.codecs[9] = SND_AUDIOCODEC_VORBIS; + prtd->compr_cap.codecs[10] = SND_AUDIOCODEC_ALAC; + prtd->compr_cap.codecs[11] = SND_AUDIOCODEC_APE; + prtd->compr_cap.codecs[12] = SND_AUDIOCODEC_DTS; + prtd->compr_cap.codecs[13] = SND_AUDIOCODEC_DSD; + prtd->compr_cap.codecs[14] = SND_AUDIOCODEC_APTX; + prtd->compr_cap.codecs[15] = SND_AUDIOCODEC_TRUEHD; + prtd->compr_cap.codecs[16] = SND_AUDIOCODEC_IEC61937; +} + +static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, + int stream_id, + bool use_gapless_codec_options) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct msm_compr_audio *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = cstream->private_data; + struct msm_compr_pdata *pdata = + snd_soc_platform_get_drvdata(rtd->platform); + struct asm_aac_cfg aac_cfg; + struct asm_wma_cfg wma_cfg; + struct asm_wmapro_cfg wma_pro_cfg; + struct asm_flac_cfg flac_cfg; + struct asm_vorbis_cfg vorbis_cfg; + struct asm_alac_cfg alac_cfg; + struct asm_ape_cfg ape_cfg; + struct asm_dsd_cfg dsd_cfg; + struct aptx_dec_bt_addr_cfg aptx_cfg; + union snd_codec_options *codec_options; + + int ret = 0; + uint16_t bit_width; + bool use_default_chmap = true; + char *chmap = NULL; + uint16_t sample_word_size; + + pr_debug("%s: use_gapless_codec_options %d\n", + __func__, use_gapless_codec_options); + + if (use_gapless_codec_options) + codec_options = &(prtd->gapless_state.codec_options); + else + codec_options = &(prtd->codec_param.codec.options); + + if (!codec_options) { + pr_err("%s: codec_options is NULL\n", __func__); + return -EINVAL; + } + + switch (prtd->codec) { + case FORMAT_LINEAR_PCM: + pr_debug("SND_AUDIOCODEC_PCM\n"); + if (pdata->ch_map[rtd->dai_link->id]) { + use_default_chmap = + !(pdata->ch_map[rtd->dai_link->id]->set_ch_map); + chmap = + pdata->ch_map[rtd->dai_link->id]->channel_map; + } + + switch (prtd->codec_param.codec.format) { + case SNDRV_PCM_FORMAT_S32_LE: + bit_width = 32; + sample_word_size = 32; + break; + case SNDRV_PCM_FORMAT_S24_LE: + bit_width = 24; + sample_word_size = 32; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + bit_width = 24; + sample_word_size = 24; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bit_width = 16; + sample_word_size = 16; + break; + } + ret = q6asm_media_format_block_pcm_format_support_v4( + prtd->audio_client, + prtd->sample_rate, + prtd->num_channels, + bit_width, stream_id, + use_default_chmap, + chmap, + sample_word_size, + ASM_LITTLE_ENDIAN, + DEFAULT_QF); + if (ret < 0) + pr_err("%s: CMD Format block failed\n", __func__); + + break; + case FORMAT_MP3: + pr_debug("SND_AUDIOCODEC_MP3\n"); + /* no media format block needed */ + break; + case FORMAT_MPEG4_AAC: + pr_debug("SND_AUDIOCODEC_AAC\n"); + memset(&aac_cfg, 0x0, sizeof(struct asm_aac_cfg)); + aac_cfg.aot = AAC_ENC_MODE_EAAC_P; + if (prtd->codec_param.codec.format == + SND_AUDIOSTREAMFORMAT_MP4ADTS) + aac_cfg.format = 0x0; + else if (prtd->codec_param.codec.format == + SND_AUDIOSTREAMFORMAT_MP4LATM) + aac_cfg.format = 0x04; + else + aac_cfg.format = 0x03; + aac_cfg.ch_cfg = prtd->num_channels; + aac_cfg.sample_rate = prtd->sample_rate; + ret = q6asm_stream_media_format_block_aac(prtd->audio_client, + &aac_cfg, stream_id); + if (ret < 0) + pr_err("%s: CMD Format block failed\n", __func__); + break; + case FORMAT_AC3: + pr_debug("SND_AUDIOCODEC_AC3\n"); + break; + case FORMAT_EAC3: + pr_debug("SND_AUDIOCODEC_EAC3\n"); + break; + case FORMAT_WMA_V9: + pr_debug("SND_AUDIOCODEC_WMA\n"); + memset(&wma_cfg, 0x0, sizeof(struct asm_wma_cfg)); + wma_cfg.format_tag = prtd->codec_param.codec.format; + wma_cfg.ch_cfg = prtd->codec_param.codec.ch_in; + wma_cfg.sample_rate = prtd->sample_rate; + wma_cfg.avg_bytes_per_sec = codec_options->wma.avg_bit_rate/8; + wma_cfg.block_align = codec_options->wma.super_block_align; + wma_cfg.valid_bits_per_sample = + codec_options->wma.bits_per_sample; + wma_cfg.ch_mask = codec_options->wma.channelmask; + wma_cfg.encode_opt = codec_options->wma.encodeopt; + ret = q6asm_media_format_block_wma(prtd->audio_client, + &wma_cfg, stream_id); + if (ret < 0) + pr_err("%s: CMD Format block failed\n", __func__); + break; + case FORMAT_WMA_V10PRO: + pr_debug("SND_AUDIOCODEC_WMA_PRO\n"); + memset(&wma_pro_cfg, 0x0, sizeof(struct asm_wmapro_cfg)); + wma_pro_cfg.format_tag = prtd->codec_param.codec.format; + wma_pro_cfg.ch_cfg = prtd->codec_param.codec.ch_in; + wma_pro_cfg.sample_rate = prtd->sample_rate; + wma_cfg.avg_bytes_per_sec = codec_options->wma.avg_bit_rate/8; + wma_pro_cfg.block_align = codec_options->wma.super_block_align; + wma_pro_cfg.valid_bits_per_sample = + codec_options->wma.bits_per_sample; + wma_pro_cfg.ch_mask = codec_options->wma.channelmask; + wma_pro_cfg.encode_opt = codec_options->wma.encodeopt; + wma_pro_cfg.adv_encode_opt = codec_options->wma.encodeopt1; + wma_pro_cfg.adv_encode_opt2 = codec_options->wma.encodeopt2; + ret = q6asm_media_format_block_wmapro(prtd->audio_client, + &wma_pro_cfg, stream_id); + if (ret < 0) + pr_err("%s: CMD Format block failed\n", __func__); + break; + case FORMAT_MP2: + pr_debug("%s: SND_AUDIOCODEC_MP2\n", __func__); + break; + case FORMAT_FLAC: + pr_debug("%s: SND_AUDIOCODEC_FLAC\n", __func__); + memset(&flac_cfg, 0x0, sizeof(struct asm_flac_cfg)); + flac_cfg.ch_cfg = prtd->num_channels; + flac_cfg.sample_rate = prtd->sample_rate; + flac_cfg.stream_info_present = 1; + flac_cfg.sample_size = codec_options->flac_dec.sample_size; + flac_cfg.min_blk_size = codec_options->flac_dec.min_blk_size; + flac_cfg.max_blk_size = codec_options->flac_dec.max_blk_size; + flac_cfg.max_frame_size = + codec_options->flac_dec.max_frame_size; + flac_cfg.min_frame_size = + codec_options->flac_dec.min_frame_size; + + ret = q6asm_stream_media_format_block_flac(prtd->audio_client, + &flac_cfg, stream_id); + if (ret < 0) + pr_err("%s: CMD Format block failed ret %d\n", + __func__, ret); + + break; + case FORMAT_VORBIS: + pr_debug("%s: SND_AUDIOCODEC_VORBIS\n", __func__); + memset(&vorbis_cfg, 0x0, sizeof(struct asm_vorbis_cfg)); + vorbis_cfg.bit_stream_fmt = + codec_options->vorbis_dec.bit_stream_fmt; + + ret = q6asm_stream_media_format_block_vorbis( + prtd->audio_client, &vorbis_cfg, + stream_id); + if (ret < 0) + pr_err("%s: CMD Format block failed ret %d\n", + __func__, ret); + + break; + case FORMAT_ALAC: + pr_debug("%s: SND_AUDIOCODEC_ALAC\n", __func__); + memset(&alac_cfg, 0x0, sizeof(struct asm_alac_cfg)); + alac_cfg.num_channels = prtd->num_channels; + alac_cfg.sample_rate = prtd->sample_rate; + alac_cfg.frame_length = codec_options->alac.frame_length; + alac_cfg.compatible_version = + codec_options->alac.compatible_version; + alac_cfg.bit_depth = codec_options->alac.bit_depth; + alac_cfg.pb = codec_options->alac.pb; + alac_cfg.mb = codec_options->alac.mb; + alac_cfg.kb = codec_options->alac.kb; + alac_cfg.max_run = codec_options->alac.max_run; + alac_cfg.max_frame_bytes = codec_options->alac.max_frame_bytes; + alac_cfg.avg_bit_rate = codec_options->alac.avg_bit_rate; + alac_cfg.channel_layout_tag = + codec_options->alac.channel_layout_tag; + + ret = q6asm_media_format_block_alac(prtd->audio_client, + &alac_cfg, stream_id); + if (ret < 0) + pr_err("%s: CMD Format block failed ret %d\n", + __func__, ret); + break; + case FORMAT_APE: + pr_debug("%s: SND_AUDIOCODEC_APE\n", __func__); + memset(&ape_cfg, 0x0, sizeof(struct asm_ape_cfg)); + ape_cfg.num_channels = prtd->num_channels; + ape_cfg.sample_rate = prtd->sample_rate; + ape_cfg.compatible_version = + codec_options->ape.compatible_version; + ape_cfg.compression_level = + codec_options->ape.compression_level; + ape_cfg.format_flags = codec_options->ape.format_flags; + ape_cfg.blocks_per_frame = codec_options->ape.blocks_per_frame; + ape_cfg.final_frame_blocks = + codec_options->ape.final_frame_blocks; + ape_cfg.total_frames = codec_options->ape.total_frames; + ape_cfg.bits_per_sample = codec_options->ape.bits_per_sample; + ape_cfg.seek_table_present = + codec_options->ape.seek_table_present; + + ret = q6asm_media_format_block_ape(prtd->audio_client, + &ape_cfg, stream_id); + + if (ret < 0) + pr_err("%s: CMD Format block failed ret %d\n", + __func__, ret); + break; + case FORMAT_DTS: + pr_debug("SND_AUDIOCODEC_DTS\n"); + /* no media format block needed */ + break; + case FORMAT_DSD: + pr_debug("%s: SND_AUDIOCODEC_DSD\n", __func__); + memset(&dsd_cfg, 0x0, sizeof(struct asm_dsd_cfg)); + dsd_cfg.num_channels = prtd->num_channels; + dsd_cfg.dsd_data_rate = prtd->sample_rate; + dsd_cfg.num_version = 0; + dsd_cfg.is_bitwise_big_endian = 1; + dsd_cfg.dsd_channel_block_size = 1; + ret = q6asm_media_format_block_dsd(prtd->audio_client, + &dsd_cfg, stream_id); + if (ret < 0) + pr_err("%s: CMD DSD Format block failed ret %d\n", + __func__, ret); + break; + case FORMAT_TRUEHD: + pr_debug("SND_AUDIOCODEC_TRUEHD\n"); + /* no media format block needed */ + break; + case FORMAT_IEC61937: + pr_debug("SND_AUDIOCODEC_IEC61937\n"); + ret = q6asm_media_format_block_iec(prtd->audio_client, + prtd->sample_rate, + prtd->num_channels); + if (ret < 0) + pr_err("%s: CMD IEC61937 Format block failed ret %d\n", + __func__, ret); + break; + case FORMAT_APTX: + pr_debug("SND_AUDIOCODEC_APTX\n"); + memset(&aptx_cfg, 0x0, sizeof(struct aptx_dec_bt_addr_cfg)); + ret = q6asm_stream_media_format_block_aptx_dec( + prtd->audio_client, + prtd->sample_rate, + stream_id); + if (ret >= 0) { + aptx_cfg.nap = codec_options->aptx_dec.nap; + aptx_cfg.uap = codec_options->aptx_dec.uap; + aptx_cfg.lap = codec_options->aptx_dec.lap; + q6asm_set_aptx_dec_bt_addr(prtd->audio_client, + &aptx_cfg); + } else { + pr_err("%s: CMD Format block failed ret %d\n", + __func__, ret); + } + break; + default: + pr_debug("%s, unsupported format, skip", __func__); + break; + } + return ret; +} + +static int msm_compr_init_pp_params(struct snd_compr_stream *cstream, + struct audio_client *ac) +{ + int ret = 0; + struct asm_softvolume_params softvol = { + .period = SOFT_VOLUME_PERIOD, + .step = SOFT_VOLUME_STEP, + .rampingcurve = SOFT_VOLUME_CURVE_LINEAR, + }; + + switch (ac->topology) { + default: + ret = q6asm_set_softvolume_v2(ac, &softvol, + SOFT_VOLUME_INSTANCE_1); + if (ret < 0) + pr_err("%s: Send SoftVolume Param failed ret=%d\n", + __func__, ret); + + break; + } + return ret; +} + +static int msm_compr_configure_dsp_for_playback + (struct snd_compr_stream *cstream) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct msm_compr_audio *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *soc_prtd = cstream->private_data; + uint16_t bits_per_sample = 16; + int dir = IN, ret = 0; + struct audio_client *ac = prtd->audio_client; + uint32_t stream_index; + struct asm_softpause_params softpause = { + .enable = SOFT_PAUSE_ENABLE, + .period = SOFT_PAUSE_PERIOD, + .step = SOFT_PAUSE_STEP, + .rampingcurve = SOFT_PAUSE_CURVE_LINEAR, + }; + struct asm_softvolume_params softvol = { + .period = SOFT_VOLUME_PERIOD, + .step = SOFT_VOLUME_STEP, + .rampingcurve = SOFT_VOLUME_CURVE_LINEAR, + }; + + pr_debug("%s: stream_id %d\n", __func__, ac->stream_id); + stream_index = STREAM_ARRAY_INDEX(ac->stream_id); + if (stream_index >= MAX_NUMBER_OF_STREAMS || stream_index < 0) { + pr_err("%s: Invalid stream index:%d", __func__, stream_index); + return -EINVAL; + } + + if ((prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S24_LE) || + (prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S24_3LE)) + bits_per_sample = 24; + else if (prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S32_LE) + bits_per_sample = 32; + + if (prtd->compr_passthr != LEGACY_PCM) { + ret = q6asm_open_write_compressed(ac, prtd->codec, + prtd->compr_passthr); + if (ret < 0) { + pr_err("%s:ASM open write err[%d] for compr_type[%d]\n", + __func__, ret, prtd->compr_passthr); + return ret; + } + prtd->gapless_state.stream_opened[stream_index] = 1; + + ret = msm_pcm_routing_reg_phy_compr_stream( + soc_prtd->dai_link->id, + ac->perf_mode, + prtd->session_id, + SNDRV_PCM_STREAM_PLAYBACK, + prtd->compr_passthr); + if (ret) { + pr_err("%s: compr stream reg failed:%d\n", __func__, + ret); + return ret; + } + } else { + pr_debug("%s: stream_id %d bits_per_sample %d\n", + __func__, ac->stream_id, bits_per_sample); + ret = q6asm_stream_open_write_v4(ac, + prtd->codec, bits_per_sample, + ac->stream_id, + prtd->gapless_state.use_dsp_gapless_mode); + if (ret < 0) { + pr_err("%s:ASM open write err[%d] for compr type[%d]\n", + __func__, ret, prtd->compr_passthr); + return -ENOMEM; + } + prtd->gapless_state.stream_opened[stream_index] = 1; + + pr_debug("%s: BE id %d\n", __func__, soc_prtd->dai_link->id); + ret = msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->id, + ac->perf_mode, + prtd->session_id, + SNDRV_PCM_STREAM_PLAYBACK); + if (ret) { + pr_err("%s: stream reg failed:%d\n", __func__, ret); + return ret; + } + } + + ret = msm_compr_set_volume(cstream, 0, 0); + if (ret < 0) + pr_err("%s : Set Volume failed : %d", __func__, ret); + + if (prtd->compr_passthr != LEGACY_PCM) { + pr_debug("%s : Don't send cal and PP params for compress path", + __func__); + } else { + ret = q6asm_send_cal(ac); + if (ret < 0) + pr_debug("%s : Send cal failed : %d", __func__, ret); + + ret = q6asm_set_softpause(ac, &softpause); + if (ret < 0) + pr_err("%s: Send SoftPause Param failed ret=%d\n", + __func__, ret); + + ret = q6asm_set_softvolume(ac, &softvol); + if (ret < 0) + pr_err("%s: Send SoftVolume Param failed ret=%d\n", + __func__, ret); + } + ret = q6asm_set_io_mode(ac, (COMPRESSED_STREAM_IO | ASYNC_IO_MODE)); + if (ret < 0) { + pr_err("%s: Set IO mode failed\n", __func__); + return -EINVAL; + } + + runtime->fragments = prtd->codec_param.buffer.fragments; + runtime->fragment_size = prtd->codec_param.buffer.fragment_size; + pr_debug("allocate %d buffers each of size %d\n", + runtime->fragments, + runtime->fragment_size); + ret = q6asm_audio_client_buf_alloc_contiguous(dir, ac, + runtime->fragment_size, + runtime->fragments); + if (ret < 0) { + pr_err("Audio Start: Buffer Allocation failed rc = %d\n", ret); + return -ENOMEM; + } + + prtd->byte_offset = 0; + prtd->copied_total = 0; + prtd->app_pointer = 0; + prtd->bytes_received = 0; + prtd->bytes_sent = 0; + prtd->buffer = ac->port[dir].buf[0].data; + prtd->buffer_paddr = ac->port[dir].buf[0].phys; + prtd->buffer_size = runtime->fragments * runtime->fragment_size; + + /* Bit-0 of flags represent timestamp mode */ + if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG) + prtd->ts_header_offset = sizeof(struct snd_codec_metadata); + else + prtd->ts_header_offset = 0; + + ret = msm_compr_send_media_format_block(cstream, ac->stream_id, false); + if (ret < 0) + pr_err("%s, failed to send media format block\n", __func__); + + return ret; +} + +static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct msm_compr_audio *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *soc_prtd = cstream->private_data; + uint16_t bits_per_sample; + uint16_t sample_word_size; + int dir = OUT, ret = 0; + struct audio_client *ac = prtd->audio_client; + uint32_t stream_index; + + switch (prtd->codec_param.codec.format) { + case SNDRV_PCM_FORMAT_S24_LE: + bits_per_sample = 24; + sample_word_size = 32; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + bits_per_sample = 24; + sample_word_size = 24; + break; + case SNDRV_PCM_FORMAT_S32_LE: + bits_per_sample = 32; + sample_word_size = 32; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bits_per_sample = 16; + sample_word_size = 16; + break; + } + + pr_debug("%s: stream_id %d bits_per_sample %d\n", + __func__, ac->stream_id, bits_per_sample); + + if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG) { + ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM, + bits_per_sample, true); + } else { + ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM, + bits_per_sample, false); + } + if (ret < 0) { + pr_err("%s: q6asm_open_read failed:%d\n", __func__, ret); + return ret; + } + + ret = msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->id, + ac->perf_mode, + prtd->session_id, + SNDRV_PCM_STREAM_CAPTURE); + if (ret) { + pr_err("%s: stream reg failed:%d\n", __func__, ret); + return ret; + } + + ret = q6asm_set_io_mode(ac, (COMPRESSED_STREAM_IO | ASYNC_IO_MODE)); + if (ret < 0) { + pr_err("%s: Set IO mode failed\n", __func__); + return -EINVAL; + } + + stream_index = STREAM_ARRAY_INDEX(ac->stream_id); + if (stream_index >= MAX_NUMBER_OF_STREAMS || stream_index < 0) { + pr_err("%s: Invalid stream index:%d", __func__, stream_index); + return -EINVAL; + } + + runtime->fragments = prtd->codec_param.buffer.fragments; + runtime->fragment_size = prtd->codec_param.buffer.fragment_size; + pr_debug("%s: allocate %d buffers each of size %d\n", + __func__, runtime->fragments, + runtime->fragment_size); + ret = q6asm_audio_client_buf_alloc_contiguous(dir, ac, + runtime->fragment_size, + runtime->fragments); + if (ret < 0) { + pr_err("Audio Start: Buffer Allocation failed rc = %d\n", ret); + return -ENOMEM; + } + + prtd->byte_offset = 0; + prtd->received_total = 0; + prtd->app_pointer = 0; + prtd->bytes_copied = 0; + prtd->bytes_read = 0; + prtd->bytes_read_offset = 0; + prtd->buffer = ac->port[dir].buf[0].data; + prtd->buffer_paddr = ac->port[dir].buf[0].phys; + prtd->buffer_size = runtime->fragments * runtime->fragment_size; + + /* Bit-0 of flags represent timestamp mode */ + if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG) + prtd->ts_header_offset = sizeof(struct snd_codec_metadata); + else + prtd->ts_header_offset = 0; + + pr_debug("%s: sample_rate = %d channels = %d bps = %d sample_word_size = %d\n", + __func__, prtd->sample_rate, prtd->num_channels, + bits_per_sample, sample_word_size); + ret = q6asm_enc_cfg_blk_pcm_format_support_v3(prtd->audio_client, + prtd->sample_rate, prtd->num_channels, + bits_per_sample, sample_word_size); + + return ret; +} + +static int msm_compr_playback_open(struct snd_compr_stream *cstream) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct snd_soc_pcm_runtime *rtd = cstream->private_data; + struct msm_compr_audio *prtd; + struct msm_compr_pdata *pdata = + snd_soc_platform_get_drvdata(rtd->platform); + + pr_debug("%s\n", __func__); + prtd = kzalloc(sizeof(struct msm_compr_audio), GFP_KERNEL); + if (prtd == NULL) { + pr_err("Failed to allocate memory for msm_compr_audio\n"); + return -ENOMEM; + } + + runtime->private_data = NULL; + prtd->cstream = cstream; + pdata->cstream[rtd->dai_link->id] = cstream; + pdata->audio_effects[rtd->dai_link->id] = + kzalloc(sizeof(struct msm_compr_audio_effects), GFP_KERNEL); + if (!pdata->audio_effects[rtd->dai_link->id]) { + pr_err("%s: Could not allocate memory for effects\n", __func__); + pdata->cstream[rtd->dai_link->id] = NULL; + kfree(prtd); + return -ENOMEM; + } + pdata->dec_params[rtd->dai_link->id] = + kzalloc(sizeof(struct msm_compr_dec_params), GFP_KERNEL); + if (!pdata->dec_params[rtd->dai_link->id]) { + pr_err("%s: Could not allocate memory for dec params\n", + __func__); + kfree(pdata->audio_effects[rtd->dai_link->id]); + pdata->cstream[rtd->dai_link->id] = NULL; + kfree(prtd); + return -ENOMEM; + } + prtd->codec = FORMAT_MP3; + prtd->bytes_received = 0; + prtd->bytes_sent = 0; + prtd->copied_total = 0; + prtd->byte_offset = 0; + prtd->sample_rate = 44100; + prtd->num_channels = 2; + prtd->drain_ready = 0; + prtd->last_buffer = 0; + prtd->first_buffer = 1; + prtd->partial_drain_delay = 0; + prtd->next_stream = 0; + memset(&prtd->gapless_state, 0, sizeof(struct msm_compr_gapless_state)); + /* + * Update the use_dsp_gapless_mode from gapless struture with the value + * part of platform data. + */ + prtd->gapless_state.use_dsp_gapless_mode = pdata->use_dsp_gapless_mode; + + pr_debug("%s: gapless mode %d", __func__, pdata->use_dsp_gapless_mode); + + spin_lock_init(&prtd->lock); + + atomic_set(&prtd->eos, 0); + atomic_set(&prtd->start, 0); + atomic_set(&prtd->drain, 0); + atomic_set(&prtd->xrun, 0); + atomic_set(&prtd->close, 0); + atomic_set(&prtd->wait_on_close, 0); + atomic_set(&prtd->error, 0); + + init_waitqueue_head(&prtd->eos_wait); + init_waitqueue_head(&prtd->drain_wait); + init_waitqueue_head(&prtd->close_wait); + init_waitqueue_head(&prtd->wait_for_stream_avail); + + runtime->private_data = prtd; + populate_codec_list(prtd); + prtd->audio_client = q6asm_audio_client_alloc( + (app_cb)compr_event_handler, prtd); + if (!prtd->audio_client) { + pr_err("%s: Could not allocate memory for client\n", __func__); + kfree(pdata->audio_effects[rtd->dai_link->id]); + kfree(pdata->dec_params[rtd->dai_link->id]); + pdata->cstream[rtd->dai_link->id] = NULL; + runtime->private_data = NULL; + kfree(prtd); + return -ENOMEM; + } + pr_debug("%s: session ID %d\n", __func__, prtd->audio_client->session); + prtd->audio_client->perf_mode = false; + prtd->session_id = prtd->audio_client->session; + msm_adsp_init_mixer_ctl_pp_event_queue(rtd); + + return 0; +} + +static int msm_compr_capture_open(struct snd_compr_stream *cstream) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct snd_soc_pcm_runtime *rtd = cstream->private_data; + struct msm_compr_audio *prtd; + struct msm_compr_pdata *pdata = + snd_soc_platform_get_drvdata(rtd->platform); + + pr_debug("%s\n", __func__); + prtd = kzalloc(sizeof(struct msm_compr_audio), GFP_KERNEL); + if (prtd == NULL) { + pr_err("Failed to allocate memory for msm_compr_audio\n"); + return -ENOMEM; + } + + runtime->private_data = NULL; + prtd->cstream = cstream; + pdata->cstream[rtd->dai_link->id] = cstream; + + prtd->audio_client = q6asm_audio_client_alloc( + (app_cb)compr_event_handler, prtd); + if (!prtd->audio_client) { + pr_err("%s: Could not allocate memory for client\n", __func__); + pdata->cstream[rtd->dai_link->id] = NULL; + kfree(prtd); + return -ENOMEM; + } + pr_debug("%s: session ID %d\n", __func__, prtd->audio_client->session); + prtd->audio_client->perf_mode = false; + prtd->session_id = prtd->audio_client->session; + prtd->codec = FORMAT_LINEAR_PCM; + prtd->bytes_copied = 0; + prtd->bytes_read = 0; + prtd->bytes_read_offset = 0; + prtd->received_total = 0; + prtd->byte_offset = 0; + prtd->sample_rate = 48000; + prtd->num_channels = 2; + prtd->first_buffer = 0; + + spin_lock_init(&prtd->lock); + + atomic_set(&prtd->eos, 0); + atomic_set(&prtd->start, 0); + atomic_set(&prtd->drain, 0); + atomic_set(&prtd->xrun, 0); + atomic_set(&prtd->close, 0); + atomic_set(&prtd->wait_on_close, 0); + atomic_set(&prtd->error, 0); + + runtime->private_data = prtd; + + return 0; +} + +static int msm_compr_open(struct snd_compr_stream *cstream) +{ + int ret = 0; + + if (cstream->direction == SND_COMPRESS_PLAYBACK) + ret = msm_compr_playback_open(cstream); + else if (cstream->direction == SND_COMPRESS_CAPTURE) + ret = msm_compr_capture_open(cstream); + return ret; +} + +static int msm_compr_playback_free(struct snd_compr_stream *cstream) +{ + struct snd_compr_runtime *runtime; + struct msm_compr_audio *prtd; + struct snd_soc_pcm_runtime *soc_prtd; + struct msm_compr_pdata *pdata; + struct audio_client *ac; + int dir = IN, ret = 0, stream_id; + unsigned long flags; + uint32_t stream_index; + + pr_debug("%s\n", __func__); + + if (!cstream) { + pr_err("%s cstream is null\n", __func__); + return 0; + } + runtime = cstream->runtime; + soc_prtd = cstream->private_data; + if (!runtime || !soc_prtd || !(soc_prtd->platform)) { + pr_err("%s runtime or soc_prtd or platform is null\n", + __func__); + return 0; + } + prtd = runtime->private_data; + if (!prtd) { + pr_err("%s prtd is null\n", __func__); + return 0; + } + prtd->cmd_interrupt = 1; + wake_up(&prtd->drain_wait); + pdata = snd_soc_platform_get_drvdata(soc_prtd->platform); + ac = prtd->audio_client; + if (!pdata || !ac) { + pr_err("%s pdata or ac is null\n", __func__); + return 0; + } + if (atomic_read(&prtd->eos)) { + ret = wait_event_timeout(prtd->eos_wait, + prtd->eos_ack, 5 * HZ); + if (!ret) + pr_err("%s: CMD_EOS failed\n", __func__); + } + if (atomic_read(&prtd->close)) { + prtd->cmd_ack = 0; + atomic_set(&prtd->wait_on_close, 1); + ret = wait_event_timeout(prtd->close_wait, + prtd->cmd_ack, 5 * HZ); + if (!ret) + pr_err("%s: CMD_CLOSE failed\n", __func__); + } + + spin_lock_irqsave(&prtd->lock, flags); + stream_id = ac->stream_id; + stream_index = STREAM_ARRAY_INDEX(NEXT_STREAM_ID(stream_id)); + + if ((stream_index < MAX_NUMBER_OF_STREAMS && stream_index >= 0) && + (prtd->gapless_state.stream_opened[stream_index])) { + prtd->gapless_state.stream_opened[stream_index] = 0; + spin_unlock_irqrestore(&prtd->lock, flags); + pr_debug(" close stream %d", NEXT_STREAM_ID(stream_id)); + q6asm_stream_cmd(ac, CMD_CLOSE, NEXT_STREAM_ID(stream_id)); + spin_lock_irqsave(&prtd->lock, flags); + } + + stream_index = STREAM_ARRAY_INDEX(stream_id); + if ((stream_index < MAX_NUMBER_OF_STREAMS && stream_index >= 0) && + (prtd->gapless_state.stream_opened[stream_index])) { + prtd->gapless_state.stream_opened[stream_index] = 0; + spin_unlock_irqrestore(&prtd->lock, flags); + pr_debug("close stream %d", stream_id); + q6asm_stream_cmd(ac, CMD_CLOSE, stream_id); + spin_lock_irqsave(&prtd->lock, flags); + } + spin_unlock_irqrestore(&prtd->lock, flags); + + pdata->cstream[soc_prtd->dai_link->id] = NULL; + if (cstream->direction == SND_COMPRESS_PLAYBACK) { + msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->id, + SNDRV_PCM_STREAM_PLAYBACK); + } + + q6asm_audio_client_buf_free_contiguous(dir, ac); + + q6asm_audio_client_free(ac); + msm_adsp_clean_mixer_ctl_pp_event_queue(soc_prtd); + kfree(pdata->audio_effects[soc_prtd->dai_link->id]); + pdata->audio_effects[soc_prtd->dai_link->id] = NULL; + kfree(pdata->dec_params[soc_prtd->dai_link->id]); + pdata->dec_params[soc_prtd->dai_link->id] = NULL; + kfree(prtd); + runtime->private_data = NULL; + + return 0; +} + +static int msm_compr_capture_free(struct snd_compr_stream *cstream) +{ + struct snd_compr_runtime *runtime; + struct msm_compr_audio *prtd; + struct snd_soc_pcm_runtime *soc_prtd; + struct msm_compr_pdata *pdata; + struct audio_client *ac; + int dir = OUT, stream_id; + unsigned long flags; + uint32_t stream_index; + + if (!cstream) { + pr_err("%s cstream is null\n", __func__); + return 0; + } + runtime = cstream->runtime; + soc_prtd = cstream->private_data; + if (!runtime || !soc_prtd || !(soc_prtd->platform)) { + pr_err("%s runtime or soc_prtd or platform is null\n", + __func__); + return 0; + } + prtd = runtime->private_data; + if (!prtd) { + pr_err("%s prtd is null\n", __func__); + return 0; + } + pdata = snd_soc_platform_get_drvdata(soc_prtd->platform); + ac = prtd->audio_client; + if (!pdata || !ac) { + pr_err("%s pdata or ac is null\n", __func__); + return 0; + } + + spin_lock_irqsave(&prtd->lock, flags); + stream_id = ac->stream_id; + + stream_index = STREAM_ARRAY_INDEX(stream_id); + if ((stream_index < MAX_NUMBER_OF_STREAMS && stream_index >= 0)) { + spin_unlock_irqrestore(&prtd->lock, flags); + pr_debug("close stream %d", stream_id); + q6asm_stream_cmd(ac, CMD_CLOSE, stream_id); + spin_lock_irqsave(&prtd->lock, flags); + } + spin_unlock_irqrestore(&prtd->lock, flags); + + pdata->cstream[soc_prtd->dai_link->id] = NULL; + msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->id, + SNDRV_PCM_STREAM_CAPTURE); + + q6asm_audio_client_buf_free_contiguous(dir, ac); + + q6asm_audio_client_free(ac); + + kfree(prtd); + runtime->private_data = NULL; + + return 0; +} + +static int msm_compr_free(struct snd_compr_stream *cstream) +{ + int ret = 0; + + if (cstream->direction == SND_COMPRESS_PLAYBACK) + ret = msm_compr_playback_free(cstream); + else if (cstream->direction == SND_COMPRESS_CAPTURE) + ret = msm_compr_capture_free(cstream); + return ret; +} + +static bool msm_compr_validate_codec_compr(__u32 codec_id) +{ + int32_t i; + + for (i = 0; i < ARRAY_SIZE(compr_codecs); i++) { + if (compr_codecs[i] == codec_id) + return true; + } + return false; +} + +/* compress stream operations */ +static int msm_compr_set_params(struct snd_compr_stream *cstream, + struct snd_compr_params *params) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct msm_compr_audio *prtd = runtime->private_data; + int ret = 0, frame_sz = 0; + int i, num_rates; + bool is_format_gapless = false; + + pr_debug("%s\n", __func__); + + num_rates = sizeof(supported_sample_rates)/sizeof(unsigned int); + for (i = 0; i < num_rates; i++) + if (params->codec.sample_rate == supported_sample_rates[i]) + break; + if (i == num_rates) + return -EINVAL; + + memcpy(&prtd->codec_param, params, sizeof(struct snd_compr_params)); + /* ToDo: remove duplicates */ + prtd->num_channels = prtd->codec_param.codec.ch_in; + prtd->sample_rate = prtd->codec_param.codec.sample_rate; + pr_debug("%s: sample_rate %d\n", __func__, prtd->sample_rate); + + if ((prtd->codec_param.codec.compr_passthr >= LEGACY_PCM && + prtd->codec_param. + codec.compr_passthr <= COMPRESSED_PASSTHROUGH_DSD) || + (prtd->codec_param. + codec.compr_passthr == COMPRESSED_PASSTHROUGH_IEC61937)) + prtd->compr_passthr = prtd->codec_param.codec.compr_passthr; + else + prtd->compr_passthr = LEGACY_PCM; + pr_debug("%s: compr_passthr = %d", __func__, prtd->compr_passthr); + if (prtd->compr_passthr != LEGACY_PCM) { + pr_debug("%s: Reset gapless mode playback for compr_type[%d]\n", + __func__, prtd->compr_passthr); + prtd->gapless_state.use_dsp_gapless_mode = 0; + if (!msm_compr_validate_codec_compr(params->codec.id)) { + pr_err("%s codec not supported in passthrough,id =%d\n", + __func__, params->codec.id); + return -EINVAL; + } + } + + switch (params->codec.id) { + case SND_AUDIOCODEC_PCM: { + pr_debug("SND_AUDIOCODEC_PCM\n"); + prtd->codec = FORMAT_LINEAR_PCM; + is_format_gapless = true; + break; + } + + case SND_AUDIOCODEC_MP3: { + pr_debug("SND_AUDIOCODEC_MP3\n"); + prtd->codec = FORMAT_MP3; + frame_sz = MP3_OUTPUT_FRAME_SZ; + is_format_gapless = true; + break; + } + + case SND_AUDIOCODEC_AAC: { + pr_debug("SND_AUDIOCODEC_AAC\n"); + prtd->codec = FORMAT_MPEG4_AAC; + frame_sz = AAC_OUTPUT_FRAME_SZ; + is_format_gapless = true; + break; + } + + case SND_AUDIOCODEC_AC3: { + pr_debug("SND_AUDIOCODEC_AC3\n"); + prtd->codec = FORMAT_AC3; + frame_sz = AC3_OUTPUT_FRAME_SZ; + is_format_gapless = true; + break; + } + + case SND_AUDIOCODEC_EAC3: { + pr_debug("SND_AUDIOCODEC_EAC3\n"); + prtd->codec = FORMAT_EAC3; + frame_sz = EAC3_OUTPUT_FRAME_SZ; + is_format_gapless = true; + break; + } + + case SND_AUDIOCODEC_MP2: { + pr_debug("SND_AUDIOCODEC_MP2\n"); + prtd->codec = FORMAT_MP2; + break; + } + + case SND_AUDIOCODEC_WMA: { + pr_debug("SND_AUDIOCODEC_WMA\n"); + prtd->codec = FORMAT_WMA_V9; + break; + } + + case SND_AUDIOCODEC_WMA_PRO: { + pr_debug("SND_AUDIOCODEC_WMA_PRO\n"); + prtd->codec = FORMAT_WMA_V10PRO; + break; + } + + case SND_AUDIOCODEC_FLAC: { + pr_debug("%s: SND_AUDIOCODEC_FLAC\n", __func__); + prtd->codec = FORMAT_FLAC; + /* + * DSP bufferring is based on blk size, + * consider mininum buffering to rule out any false wait + */ + frame_sz = + prtd->codec_param.codec.options.flac_dec.min_blk_size; + is_format_gapless = true; + break; + } + + case SND_AUDIOCODEC_VORBIS: { + pr_debug("%s: SND_AUDIOCODEC_VORBIS\n", __func__); + prtd->codec = FORMAT_VORBIS; + break; + } + + case SND_AUDIOCODEC_ALAC: { + pr_debug("%s: SND_AUDIOCODEC_ALAC\n", __func__); + prtd->codec = FORMAT_ALAC; + break; + } + + case SND_AUDIOCODEC_APE: { + pr_debug("%s: SND_AUDIOCODEC_APE\n", __func__); + prtd->codec = FORMAT_APE; + break; + } + + case SND_AUDIOCODEC_DTS: { + pr_debug("%s: SND_AUDIOCODEC_DTS\n", __func__); + prtd->codec = FORMAT_DTS; + break; + } + + case SND_AUDIOCODEC_DSD: { + pr_debug("%s: SND_AUDIOCODEC_DSD\n", __func__); + prtd->codec = FORMAT_DSD; + break; + } + + case SND_AUDIOCODEC_TRUEHD: { + pr_debug("%s: SND_AUDIOCODEC_TRUEHD\n", __func__); + prtd->codec = FORMAT_TRUEHD; + break; + } + + case SND_AUDIOCODEC_IEC61937: { + pr_debug("%s: SND_AUDIOCODEC_IEC61937\n", __func__); + prtd->codec = FORMAT_IEC61937; + break; + } + + case SND_AUDIOCODEC_APTX: { + pr_debug("%s: SND_AUDIOCODEC_APTX\n", __func__); + prtd->codec = FORMAT_APTX; + break; + } + + default: + pr_err("codec not supported, id =%d\n", params->codec.id); + return -EINVAL; + } + + if (!is_format_gapless) + prtd->gapless_state.use_dsp_gapless_mode = false; + + prtd->partial_drain_delay = + msm_compr_get_partial_drain_delay(frame_sz, prtd->sample_rate); + + if (cstream->direction == SND_COMPRESS_PLAYBACK) + ret = msm_compr_configure_dsp_for_playback(cstream); + else if (cstream->direction == SND_COMPRESS_CAPTURE) + ret = msm_compr_configure_dsp_for_capture(cstream); + + return ret; +} + +static int msm_compr_drain_buffer(struct msm_compr_audio *prtd, + unsigned long *flags) +{ + int rc = 0; + + atomic_set(&prtd->drain, 1); + prtd->drain_ready = 0; + spin_unlock_irqrestore(&prtd->lock, *flags); + pr_debug("%s: wait for buffer to be drained\n", __func__); + rc = wait_event_interruptible(prtd->drain_wait, + prtd->drain_ready || + prtd->cmd_interrupt || + atomic_read(&prtd->xrun) || + atomic_read(&prtd->error)); + pr_debug("%s: out of buffer drain wait with ret %d\n", __func__, rc); + spin_lock_irqsave(&prtd->lock, *flags); + if (prtd->cmd_interrupt) { + pr_debug("%s: buffer drain interrupted by flush)\n", __func__); + rc = -EINTR; + prtd->cmd_interrupt = 0; + } + if (atomic_read(&prtd->error)) { + pr_err("%s: Got RESET EVENTS notification, return\n", + __func__); + rc = -ENETRESET; + } + return rc; +} + +static int msm_compr_wait_for_stream_avail(struct msm_compr_audio *prtd, + unsigned long *flags) +{ + int rc = 0; + + pr_debug("next session is already in opened state\n"); + prtd->next_stream = 1; + prtd->cmd_interrupt = 0; + spin_unlock_irqrestore(&prtd->lock, *flags); + /* + * Wait for stream to be available, or the wait to be interrupted by + * commands like flush or till a timeout of one second. + */ + rc = wait_event_timeout(prtd->wait_for_stream_avail, + prtd->stream_available || prtd->cmd_interrupt, 1 * HZ); + pr_err("%s:prtd->stream_available %d, prtd->cmd_interrupt %d rc %d\n", + __func__, prtd->stream_available, prtd->cmd_interrupt, rc); + + spin_lock_irqsave(&prtd->lock, *flags); + if (rc == 0) { + pr_err("%s: wait_for_stream_avail timed out\n", + __func__); + rc = -ETIMEDOUT; + } else if (prtd->cmd_interrupt == 1) { + /* + * This scenario might not happen as we do not allow + * flush in transition state. + */ + pr_debug("%s: wait_for_stream_avail interrupted\n", __func__); + prtd->cmd_interrupt = 0; + prtd->stream_available = 0; + rc = -EINTR; + } else { + prtd->stream_available = 0; + rc = 0; + } + pr_debug("%s : rc = %d", __func__, rc); + return rc; +} + +static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct msm_compr_audio *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = cstream->private_data; + struct msm_compr_pdata *pdata = + snd_soc_platform_get_drvdata(rtd->platform); + uint32_t *volume = pdata->volume[rtd->dai_link->id]; + struct audio_client *ac = prtd->audio_client; + unsigned long fe_id = rtd->dai_link->id; + int rc = 0; + int bytes_to_write; + unsigned long flags; + int stream_id; + uint32_t stream_index; + uint16_t bits_per_sample = 16; + + spin_lock_irqsave(&prtd->lock, flags); + if (atomic_read(&prtd->error)) { + pr_err("%s Got RESET EVENTS notification, return immediately", + __func__); + spin_unlock_irqrestore(&prtd->lock, flags); + return 0; + } + spin_unlock_irqrestore(&prtd->lock, flags); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + pr_debug("%s: SNDRV_PCM_TRIGGER_START\n", __func__); + atomic_set(&prtd->start, 1); + + /* + * compr_set_volume and compr_init_pp_params + * are used to configure ASM volume hence not + * needed for compress passthrough playback. + * + * compress passthrough volume is controlled in + * ADM by adm_send_compressed_device_mute() + */ + if (prtd->compr_passthr == LEGACY_PCM && + cstream->direction == SND_COMPRESS_PLAYBACK) { + /* set volume for the stream before RUN */ + rc = msm_compr_set_volume(cstream, + volume[0], volume[1]); + if (rc) + pr_err("%s : Set Volume failed : %d\n", + __func__, rc); + + rc = msm_compr_init_pp_params(cstream, ac); + if (rc) + pr_err("%s : init PP params failed : %d\n", + __func__, rc); + } else { + msm_compr_read_buffer(prtd); + } + /* issue RUN command for the stream */ + q6asm_run_nowait(prtd->audio_client, prtd->run_mode, + prtd->start_delay_msw, prtd->start_delay_lsw); + break; + case SNDRV_PCM_TRIGGER_STOP: + spin_lock_irqsave(&prtd->lock, flags); + pr_debug("%s: SNDRV_PCM_TRIGGER_STOP transition %d\n", __func__, + prtd->gapless_state.gapless_transition); + stream_id = ac->stream_id; + atomic_set(&prtd->start, 0); + if (cstream->direction == SND_COMPRESS_CAPTURE) { + q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE); + atomic_set(&prtd->xrun, 0); + prtd->received_total = 0; + prtd->bytes_copied = 0; + prtd->bytes_read = 0; + prtd->bytes_read_offset = 0; + prtd->byte_offset = 0; + prtd->app_pointer = 0; + spin_unlock_irqrestore(&prtd->lock, flags); + break; + } + if (prtd->next_stream) { + pr_debug("%s: interrupt next track wait queues\n", + __func__); + prtd->cmd_interrupt = 1; + wake_up(&prtd->wait_for_stream_avail); + prtd->next_stream = 0; + } + if (atomic_read(&prtd->eos)) { + pr_debug("%s: interrupt eos wait queues", __func__); + /* + * Gapless playback does not wait for eos, do not set + * cmd_int and do not wake up eos_wait during gapless + * transition + */ + if (!prtd->gapless_state.gapless_transition) { + prtd->cmd_interrupt = 1; + wake_up(&prtd->eos_wait); + } + atomic_set(&prtd->eos, 0); + } + if (atomic_read(&prtd->drain)) { + pr_debug("%s: interrupt drain wait queues", __func__); + prtd->cmd_interrupt = 1; + prtd->drain_ready = 1; + wake_up(&prtd->drain_wait); + atomic_set(&prtd->drain, 0); + } + prtd->last_buffer = 0; + prtd->cmd_ack = 0; + if (!prtd->gapless_state.gapless_transition) { + pr_debug("issue CMD_FLUSH stream_id %d\n", stream_id); + spin_unlock_irqrestore(&prtd->lock, flags); + q6asm_stream_cmd( + prtd->audio_client, CMD_FLUSH, stream_id); + spin_lock_irqsave(&prtd->lock, flags); + } else { + prtd->first_buffer = 0; + } + /* FIXME. only reset if flush was successful */ + prtd->byte_offset = 0; + prtd->copied_total = 0; + prtd->app_pointer = 0; + prtd->bytes_received = 0; + prtd->bytes_sent = 0; + prtd->marker_timestamp = 0; + + atomic_set(&prtd->xrun, 0); + spin_unlock_irqrestore(&prtd->lock, flags); + break; + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + pr_debug("SNDRV_PCM_TRIGGER_PAUSE_PUSH transition %d\n", + prtd->gapless_state.gapless_transition); + if (!prtd->gapless_state.gapless_transition) { + pr_debug("issue CMD_PAUSE stream_id %d\n", + ac->stream_id); + q6asm_stream_cmd_nowait(ac, CMD_PAUSE, ac->stream_id); + atomic_set(&prtd->start, 0); + } + break; + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + pr_debug("SNDRV_PCM_TRIGGER_PAUSE_RELEASE transition %d\n", + prtd->gapless_state.gapless_transition); + if (!prtd->gapless_state.gapless_transition) { + atomic_set(&prtd->start, 1); + q6asm_run_nowait(prtd->audio_client, prtd->run_mode, + 0, 0); + } + break; + case SND_COMPR_TRIGGER_PARTIAL_DRAIN: + pr_debug("%s: SND_COMPR_TRIGGER_PARTIAL_DRAIN\n", __func__); + if (!prtd->gapless_state.use_dsp_gapless_mode) { + pr_debug("%s: set partial drain as drain\n", __func__); + cmd = SND_COMPR_TRIGGER_DRAIN; + } + case SND_COMPR_TRIGGER_DRAIN: + pr_debug("%s: SNDRV_COMPRESS_DRAIN\n", __func__); + /* Make sure all the data is sent to DSP before sending EOS */ + spin_lock_irqsave(&prtd->lock, flags); + + if (!atomic_read(&prtd->start)) { + pr_err("%s: stream is not in started state\n", + __func__); + rc = -EPERM; + spin_unlock_irqrestore(&prtd->lock, flags); + break; + } + if (prtd->bytes_received > prtd->copied_total) { + pr_debug("%s: wait till all the data is sent to dsp\n", + __func__); + rc = msm_compr_drain_buffer(prtd, &flags); + if (rc || !atomic_read(&prtd->start)) { + if (rc != -ENETRESET) + rc = -EINTR; + spin_unlock_irqrestore(&prtd->lock, flags); + break; + } + /* + * FIXME: Bug. + * Write(32767) + * Start + * Drain <- Indefinite wait + * sol1 : if (prtd->copied_total) then wait? + * sol2 : (prtd->cmd_interrupt || prtd->drain_ready || + * atomic_read(xrun) + */ + bytes_to_write = prtd->bytes_received + - prtd->copied_total; + WARN(bytes_to_write > runtime->fragment_size, + "last write %d cannot be > than fragment_size", + bytes_to_write); + + if (bytes_to_write > 0) { + pr_debug("%s: send %d partial bytes at the end", + __func__, bytes_to_write); + atomic_set(&prtd->xrun, 0); + prtd->last_buffer = 1; + msm_compr_send_buffer(prtd); + } + } + + if ((cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN) && + (prtd->gapless_state.set_next_stream_id)) { + /* wait for the last buffer to be returned */ + + if (prtd->last_buffer) { + pr_debug("%s: last buffer drain\n", __func__); + rc = msm_compr_drain_buffer(prtd, &flags); + if (rc || !atomic_read(&prtd->start)) { + spin_unlock_irqrestore(&prtd->lock, + flags); + break; + } + } + /* send EOS */ + prtd->eos_ack = 0; + atomic_set(&prtd->eos, 1); + pr_debug("issue CMD_EOS stream_id %d\n", ac->stream_id); + q6asm_stream_cmd_nowait(ac, CMD_EOS, ac->stream_id); + pr_info("PARTIAL DRAIN, do not wait for EOS ack\n"); + + /* send a zero length buffer */ + atomic_set(&prtd->xrun, 0); + msm_compr_send_buffer(prtd); + + /* wait for the zero length buffer to be returned */ + pr_debug("%s: zero length buffer drain\n", __func__); + rc = msm_compr_drain_buffer(prtd, &flags); + if (rc || !atomic_read(&prtd->start)) { + spin_unlock_irqrestore(&prtd->lock, flags); + break; + } + + /* sleep for additional duration partial drain */ + atomic_set(&prtd->drain, 1); + prtd->drain_ready = 0; + pr_debug("%s, additional sleep: %d\n", __func__, + prtd->partial_drain_delay); + spin_unlock_irqrestore(&prtd->lock, flags); + rc = wait_event_timeout(prtd->drain_wait, + prtd->drain_ready || prtd->cmd_interrupt, + msecs_to_jiffies(prtd->partial_drain_delay)); + pr_debug("%s: out of additional wait for low sample rate\n", + __func__); + spin_lock_irqsave(&prtd->lock, flags); + if (prtd->cmd_interrupt) { + pr_debug("%s: additional wait interrupted by flush)\n", + __func__); + rc = -EINTR; + prtd->cmd_interrupt = 0; + spin_unlock_irqrestore(&prtd->lock, flags); + break; + } + + /* move to next stream and reset vars */ + pr_debug("%s: Moving to next stream in gapless\n", + __func__); + ac->stream_id = NEXT_STREAM_ID(ac->stream_id); + prtd->byte_offset = 0; + prtd->app_pointer = 0; + prtd->first_buffer = 1; + prtd->last_buffer = 0; + /* + * Set gapless transition flag only if EOS hasn't been + * acknowledged already. + */ + if (atomic_read(&prtd->eos)) + prtd->gapless_state.gapless_transition = 1; + prtd->marker_timestamp = 0; + + /* + * Don't reset these as these vars map to + * total_bytes_transferred and total_bytes_available + * directly, only total_bytes_transferred will be + * updated in the next avail() ioctl + * prtd->copied_total = 0; + * prtd->bytes_received = 0; + */ + atomic_set(&prtd->drain, 0); + atomic_set(&prtd->xrun, 1); + pr_debug("%s: issue CMD_RUN", __func__); + q6asm_run_nowait(prtd->audio_client, 0, 0, 0); + spin_unlock_irqrestore(&prtd->lock, flags); + break; + } + /* + * moving to next stream failed, so reset the gapless state + * set next stream id for the same session so that the same + * stream can be used for gapless playback + */ + prtd->gapless_state.set_next_stream_id = false; + prtd->gapless_state.gapless_transition = 0; + pr_debug("%s:CMD_EOS stream_id %d\n", __func__, ac->stream_id); + + prtd->eos_ack = 0; + atomic_set(&prtd->eos, 1); + q6asm_stream_cmd_nowait(ac, CMD_EOS, ac->stream_id); + + spin_unlock_irqrestore(&prtd->lock, flags); + + + /* Wait indefinitely for DRAIN. Flush can also signal this*/ + rc = wait_event_interruptible(prtd->eos_wait, + (prtd->eos_ack || + prtd->cmd_interrupt || + atomic_read(&prtd->error))); + + if (rc < 0) + pr_err("%s: EOS wait failed\n", __func__); + + pr_debug("%s: SNDRV_COMPRESS_DRAIN out of wait for EOS\n", + __func__); + + if (prtd->cmd_interrupt) + rc = -EINTR; + + if (atomic_read(&prtd->error)) { + pr_err("%s: Got RESET EVENTS notification, return\n", + __func__); + rc = -ENETRESET; + } + + /*FIXME : what if a flush comes while PC is here */ + if (rc == 0) { + /* + * Failed to open second stream in DSP for gapless + * so prepare the current stream in session + * for gapless playback + */ + spin_lock_irqsave(&prtd->lock, flags); + pr_debug("%s:issue CMD_PAUSE stream_id %d", + __func__, ac->stream_id); + q6asm_stream_cmd_nowait(ac, CMD_PAUSE, ac->stream_id); + prtd->cmd_ack = 0; + spin_unlock_irqrestore(&prtd->lock, flags); + + /* + * Cache this time as last known time + */ + if (pdata->use_legacy_api) + q6asm_get_session_time_legacy( + prtd->audio_client, + &prtd->marker_timestamp); + else + q6asm_get_session_time(prtd->audio_client, + &prtd->marker_timestamp); + + spin_lock_irqsave(&prtd->lock, flags); + /* + * Don't reset these as these vars map to + * total_bytes_transferred and total_bytes_available. + * Just total_bytes_transferred will be updated + * in the next avail() ioctl. + * prtd->copied_total = 0; + * prtd->bytes_received = 0; + * do not reset prtd->bytes_sent as well as the same + * session is used for gapless playback + */ + prtd->byte_offset = 0; + + prtd->app_pointer = 0; + prtd->first_buffer = 1; + prtd->last_buffer = 0; + atomic_set(&prtd->drain, 0); + atomic_set(&prtd->xrun, 1); + spin_unlock_irqrestore(&prtd->lock, flags); + + pr_debug("%s:issue CMD_FLUSH ac->stream_id %d", + __func__, ac->stream_id); + q6asm_stream_cmd(ac, CMD_FLUSH, ac->stream_id); + + q6asm_run_nowait(prtd->audio_client, 0, 0, 0); + } + prtd->cmd_interrupt = 0; + break; + case SND_COMPR_TRIGGER_NEXT_TRACK: + if (!prtd->gapless_state.use_dsp_gapless_mode) { + pr_debug("%s: ignore trigger next track\n", __func__); + rc = 0; + break; + } + pr_debug("%s: SND_COMPR_TRIGGER_NEXT_TRACK\n", __func__); + spin_lock_irqsave(&prtd->lock, flags); + rc = 0; + /* next stream in gapless */ + stream_id = NEXT_STREAM_ID(ac->stream_id); + /* + * Wait if stream 1 has not completed before honoring next + * track for stream 3. Scenario happens if second clip is + * small and fills in one buffer so next track will be + * called immediately. + */ + stream_index = STREAM_ARRAY_INDEX(stream_id); + if (stream_index >= MAX_NUMBER_OF_STREAMS || + stream_index < 0) { + pr_err("%s: Invalid stream index: %d", __func__, + stream_index); + spin_unlock_irqrestore(&prtd->lock, flags); + rc = -EINVAL; + break; + } + + if (prtd->gapless_state.stream_opened[stream_index]) { + if (prtd->gapless_state.gapless_transition) { + rc = msm_compr_wait_for_stream_avail(prtd, + &flags); + } else { + /* + * If session is already opened break out if + * the state is not gapless transition. This + * is when seek happens after the last buffer + * is sent to the driver. Next track would be + * called again after last buffer is sent. + */ + pr_debug("next session is in opened state\n"); + spin_unlock_irqrestore(&prtd->lock, flags); + break; + } + } + spin_unlock_irqrestore(&prtd->lock, flags); + if (rc < 0) { + /* + * if return type EINTR then reset to zero. Tiny + * compress treats EINTR as error and prevents PARTIAL + * DRAIN. EINTR is not an error. wait for stream avail + * is interrupted by some other command like FLUSH. + */ + if (rc == -EINTR) { + pr_debug("%s: EINTR reset rc to 0\n", __func__); + rc = 0; + } + break; + } + + if (prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S24_LE) + bits_per_sample = 24; + else if (prtd->codec_param.codec.format == + SNDRV_PCM_FORMAT_S32_LE) + bits_per_sample = 32; + + pr_debug("%s: open_write stream_id %d bits_per_sample %d", + __func__, stream_id, bits_per_sample); + rc = q6asm_stream_open_write_v4(prtd->audio_client, + prtd->codec, bits_per_sample, + stream_id, + prtd->gapless_state.use_dsp_gapless_mode); + if (rc < 0) { + pr_err("%s: Session out open failed for gapless\n", + __func__); + break; + } + + spin_lock_irqsave(&prtd->lock, flags); + prtd->gapless_state.stream_opened[stream_index] = 1; + prtd->gapless_state.set_next_stream_id = true; + spin_unlock_irqrestore(&prtd->lock, flags); + + rc = msm_compr_send_media_format_block(cstream, + stream_id, false); + if (rc < 0) { + pr_err("%s, failed to send media format block\n", + __func__); + break; + } + msm_compr_send_dec_params(cstream, pdata->dec_params[fe_id], + stream_id); + break; + } + + return rc; +} + +static int msm_compr_pointer(struct snd_compr_stream *cstream, + struct snd_compr_tstamp *arg) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct snd_soc_pcm_runtime *rtd = cstream->private_data; + struct msm_compr_audio *prtd = runtime->private_data; + struct msm_compr_pdata *pdata = NULL; + struct snd_compr_tstamp tstamp; + uint64_t timestamp = 0; + int rc = 0, first_buffer; + unsigned long flags; + uint32_t gapless_transition; + + pdata = snd_soc_platform_get_drvdata(rtd->platform); + pr_debug("%s\n", __func__); + memset(&tstamp, 0x0, sizeof(struct snd_compr_tstamp)); + + spin_lock_irqsave(&prtd->lock, flags); + tstamp.sampling_rate = prtd->sample_rate; + tstamp.byte_offset = prtd->byte_offset; + if (cstream->direction == SND_COMPRESS_PLAYBACK) + tstamp.copied_total = prtd->copied_total; + else if (cstream->direction == SND_COMPRESS_CAPTURE) + tstamp.copied_total = prtd->received_total; + first_buffer = prtd->first_buffer; + if (atomic_read(&prtd->error)) { + pr_err("%s Got RESET EVENTS notification, return error\n", + __func__); + if (cstream->direction == SND_COMPRESS_PLAYBACK) + runtime->total_bytes_transferred = tstamp.copied_total; + else + runtime->total_bytes_available = tstamp.copied_total; + tstamp.pcm_io_frames = 0; + memcpy(arg, &tstamp, sizeof(struct snd_compr_tstamp)); + spin_unlock_irqrestore(&prtd->lock, flags); + return -ENETRESET; + } + if (cstream->direction == SND_COMPRESS_PLAYBACK) { + + gapless_transition = prtd->gapless_state.gapless_transition; + spin_unlock_irqrestore(&prtd->lock, flags); + if (gapless_transition) + pr_debug("%s session time in gapless transition", + __func__); + /* + *- Do not query if no buffer has been given. + *- Do not query on a gapless transition. + * Playback for the 2nd stream can start (thus returning time + * starting from 0) before the driver knows about EOS of first + * stream. + */ + if (!first_buffer || gapless_transition) { + + if (pdata->use_legacy_api) + rc = q6asm_get_session_time_legacy( + prtd->audio_client, &prtd->marker_timestamp); + else + rc = q6asm_get_session_time( + prtd->audio_client, &prtd->marker_timestamp); + if (rc < 0) { + pr_err("%s: Get Session Time return =%lld\n", + __func__, timestamp); + if (atomic_read(&prtd->error)) + return -ENETRESET; + else + return -EAGAIN; + } + } + } else { + spin_unlock_irqrestore(&prtd->lock, flags); + } + timestamp = prtd->marker_timestamp; + + /* DSP returns timestamp in usec */ + pr_debug("%s: timestamp = %lld usec\n", __func__, timestamp); + timestamp *= prtd->sample_rate; + tstamp.pcm_io_frames = (snd_pcm_uframes_t)div64_u64(timestamp, 1000000); + memcpy(arg, &tstamp, sizeof(struct snd_compr_tstamp)); + + return 0; +} + +static int msm_compr_ack(struct snd_compr_stream *cstream, + size_t count) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct msm_compr_audio *prtd = runtime->private_data; + void *src, *dstn; + size_t copy; + unsigned long flags; + + WARN(1, "This path is untested"); + return -EINVAL; + + pr_debug("%s: count = %zd\n", __func__, count); + if (!prtd->buffer) { + pr_err("%s: Buffer is not allocated yet ??\n", __func__); + return -EINVAL; + } + src = runtime->buffer + prtd->app_pointer; + dstn = prtd->buffer + prtd->app_pointer; + if (count < prtd->buffer_size - prtd->app_pointer) { + memcpy(dstn, src, count); + prtd->app_pointer += count; + } else { + copy = prtd->buffer_size - prtd->app_pointer; + memcpy(dstn, src, copy); + memcpy(prtd->buffer, runtime->buffer, count - copy); + prtd->app_pointer = count - copy; + } + + /* + * If the stream is started and all the bytes received were + * copied to DSP, the newly received bytes should be + * sent right away + */ + spin_lock_irqsave(&prtd->lock, flags); + + if (atomic_read(&prtd->start) && + prtd->bytes_received == prtd->copied_total) { + prtd->bytes_received += count; + msm_compr_send_buffer(prtd); + } else + prtd->bytes_received += count; + + spin_unlock_irqrestore(&prtd->lock, flags); + + return 0; +} + +static int msm_compr_playback_copy(struct snd_compr_stream *cstream, + char __user *buf, size_t count) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct msm_compr_audio *prtd = runtime->private_data; + void *dstn; + size_t copy; + uint64_t bytes_available = 0; + unsigned long flags; + + pr_debug("%s: count = %zd\n", __func__, count); + if (!prtd->buffer) { + pr_err("%s: Buffer is not allocated yet ??", __func__); + return 0; + } + + spin_lock_irqsave(&prtd->lock, flags); + if (atomic_read(&prtd->error)) { + pr_err("%s Got RESET EVENTS notification", __func__); + spin_unlock_irqrestore(&prtd->lock, flags); + return -ENETRESET; + } + spin_unlock_irqrestore(&prtd->lock, flags); + + dstn = prtd->buffer + prtd->app_pointer; + if (count < prtd->buffer_size - prtd->app_pointer) { + if (copy_from_user(dstn, buf, count)) + return -EFAULT; + prtd->app_pointer += count; + } else { + copy = prtd->buffer_size - prtd->app_pointer; + if (copy_from_user(dstn, buf, copy)) + return -EFAULT; + if (copy_from_user(prtd->buffer, buf + copy, count - copy)) + return -EFAULT; + prtd->app_pointer = count - copy; + } + + /* + * If stream is started and there has been an xrun, + * since the available bytes fits fragment_size, copy the data + * right away. + */ + spin_lock_irqsave(&prtd->lock, flags); + prtd->bytes_received += count; + if (atomic_read(&prtd->start)) { + if (atomic_read(&prtd->xrun)) { + pr_debug("%s: in xrun, count = %zd\n", __func__, count); + bytes_available = prtd->bytes_received - + prtd->copied_total; + if (bytes_available >= runtime->fragment_size) { + pr_debug("%s: handle xrun, bytes_to_write = %llu\n", + __func__, bytes_available); + atomic_set(&prtd->xrun, 0); + msm_compr_send_buffer(prtd); + } /* else not sufficient data */ + } /* writes will continue on the next write_done */ + } + + spin_unlock_irqrestore(&prtd->lock, flags); + + return count; +} + +static int msm_compr_capture_copy(struct snd_compr_stream *cstream, + char __user *buf, size_t count) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct msm_compr_audio *prtd = runtime->private_data; + void *source; + unsigned long flags; + + pr_debug("%s: count = %zd\n", __func__, count); + if (!prtd->buffer) { + pr_err("%s: Buffer is not allocated yet ??", __func__); + return 0; + } + + spin_lock_irqsave(&prtd->lock, flags); + if (atomic_read(&prtd->error)) { + pr_err("%s Got RESET EVENTS notification", __func__); + spin_unlock_irqrestore(&prtd->lock, flags); + return -ENETRESET; + } + + source = prtd->buffer + prtd->app_pointer; + /* check if we have requested amount of data to copy to user*/ + if (count <= prtd->received_total - prtd->bytes_copied) { + spin_unlock_irqrestore(&prtd->lock, flags); + if (copy_to_user(buf, source, count)) { + pr_err("copy_to_user failed"); + return -EFAULT; + } + spin_lock_irqsave(&prtd->lock, flags); + prtd->app_pointer += count; + if (prtd->app_pointer >= prtd->buffer_size) + prtd->app_pointer -= prtd->buffer_size; + prtd->bytes_copied += count; + } + msm_compr_read_buffer(prtd); + + spin_unlock_irqrestore(&prtd->lock, flags); + return count; +} + +static int msm_compr_copy(struct snd_compr_stream *cstream, + char __user *buf, size_t count) +{ + int ret = 0; + + pr_debug(" In %s\n", __func__); + if (cstream->direction == SND_COMPRESS_PLAYBACK) + ret = msm_compr_playback_copy(cstream, buf, count); + else if (cstream->direction == SND_COMPRESS_CAPTURE) + ret = msm_compr_capture_copy(cstream, buf, count); + return ret; +} + +static int msm_compr_get_caps(struct snd_compr_stream *cstream, + struct snd_compr_caps *arg) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct msm_compr_audio *prtd = runtime->private_data; + int ret = 0; + + pr_debug("%s\n", __func__); + if ((arg != NULL) && (prtd != NULL)) { + memcpy(arg, &prtd->compr_cap, sizeof(struct snd_compr_caps)); + } else { + ret = -EINVAL; + pr_err("%s: arg (0x%pK), prtd (0x%pK)\n", __func__, arg, prtd); + } + + return ret; +} + +static int msm_compr_get_codec_caps(struct snd_compr_stream *cstream, + struct snd_compr_codec_caps *codec) +{ + pr_debug("%s\n", __func__); + + switch (codec->codec) { + case SND_AUDIOCODEC_MP3: + codec->num_descriptors = 2; + codec->descriptor[0].max_ch = 2; + memcpy(codec->descriptor[0].sample_rates, + supported_sample_rates, + sizeof(supported_sample_rates)); + codec->descriptor[0].num_sample_rates = + sizeof(supported_sample_rates)/sizeof(unsigned int); + codec->descriptor[0].bit_rate[0] = 320; /* 320kbps */ + codec->descriptor[0].bit_rate[1] = 128; + codec->descriptor[0].num_bitrates = 2; + codec->descriptor[0].profiles = 0; + codec->descriptor[0].modes = SND_AUDIOCHANMODE_MP3_STEREO; + codec->descriptor[0].formats = 0; + break; + case SND_AUDIOCODEC_AAC: + codec->num_descriptors = 2; + codec->descriptor[1].max_ch = 2; + memcpy(codec->descriptor[1].sample_rates, + supported_sample_rates, + sizeof(supported_sample_rates)); + codec->descriptor[1].num_sample_rates = + sizeof(supported_sample_rates)/sizeof(unsigned int); + codec->descriptor[1].bit_rate[0] = 320; /* 320kbps */ + codec->descriptor[1].bit_rate[1] = 128; + codec->descriptor[1].num_bitrates = 2; + codec->descriptor[1].profiles = 0; + codec->descriptor[1].modes = 0; + codec->descriptor[1].formats = + (SND_AUDIOSTREAMFORMAT_MP4ADTS | + SND_AUDIOSTREAMFORMAT_RAW); + break; + case SND_AUDIOCODEC_AC3: + case SND_AUDIOCODEC_EAC3: + case SND_AUDIOCODEC_FLAC: + case SND_AUDIOCODEC_VORBIS: + case SND_AUDIOCODEC_ALAC: + case SND_AUDIOCODEC_APE: + case SND_AUDIOCODEC_DTS: + case SND_AUDIOCODEC_DSD: + case SND_AUDIOCODEC_TRUEHD: + case SND_AUDIOCODEC_IEC61937: + case SND_AUDIOCODEC_APTX: + break; + default: + pr_err("%s: Unsupported audio codec %d\n", + __func__, codec->codec); + return -EINVAL; + } + + return 0; +} + +static int msm_compr_set_metadata(struct snd_compr_stream *cstream, + struct snd_compr_metadata *metadata) +{ + struct msm_compr_audio *prtd; + struct audio_client *ac; + pr_debug("%s\n", __func__); + + if (!metadata || !cstream) + return -EINVAL; + + prtd = cstream->runtime->private_data; + if (!prtd || !prtd->audio_client) { + pr_err("%s: prtd or audio client is NULL\n", __func__); + return -EINVAL; + } + + if (((metadata->key == SNDRV_COMPRESS_ENCODER_PADDING) || + (metadata->key == SNDRV_COMPRESS_ENCODER_DELAY)) && + (prtd->compr_passthr != LEGACY_PCM)) { + pr_debug("%s: No trailing silence for compress_type[%d]\n", + __func__, prtd->compr_passthr); + return 0; + } + + ac = prtd->audio_client; + if (metadata->key == SNDRV_COMPRESS_ENCODER_PADDING) { + pr_debug("%s, got encoder padding %u", + __func__, metadata->value[0]); + prtd->gapless_state.trailing_samples_drop = metadata->value[0]; + } else if (metadata->key == SNDRV_COMPRESS_ENCODER_DELAY) { + pr_debug("%s, got encoder delay %u", + __func__, metadata->value[0]); + prtd->gapless_state.initial_samples_drop = metadata->value[0]; + } else if (metadata->key == SNDRV_COMPRESS_RENDER_MODE) { + return msm_compr_set_render_mode(prtd, metadata->value[0]); + } else if (metadata->key == SNDRV_COMPRESS_CLK_REC_MODE) { + return msm_compr_set_clk_rec_mode(ac, metadata->value[0]); + } else if (metadata->key == SNDRV_COMPRESS_RENDER_WINDOW) { + return msm_compr_set_render_window( + ac, + metadata->value[0], + metadata->value[1], + metadata->value[2], + metadata->value[3]); + } else if (metadata->key == SNDRV_COMPRESS_START_DELAY) { + prtd->start_delay_lsw = metadata->value[0]; + prtd->start_delay_msw = metadata->value[1]; + } else if (metadata->key == + SNDRV_COMPRESS_ENABLE_ADJUST_SESSION_CLOCK) { + return msm_compr_enable_adjust_session_clock(ac, + metadata->value[0]); + } else if (metadata->key == SNDRV_COMPRESS_ADJUST_SESSION_CLOCK) { + return msm_compr_adjust_session_clock(ac, + metadata->value[0], + metadata->value[1]); + } + + return 0; +} + +static int msm_compr_get_metadata(struct snd_compr_stream *cstream, + struct snd_compr_metadata *metadata) +{ + struct msm_compr_audio *prtd; + struct audio_client *ac; + int ret = -EINVAL; + + pr_debug("%s\n", __func__); + + if (!metadata || !cstream || !cstream->runtime) + return ret; + + if (metadata->key != SNDRV_COMPRESS_PATH_DELAY) { + pr_err("%s, unsupported key %d\n", __func__, metadata->key); + return ret; + } + + prtd = cstream->runtime->private_data; + if (!prtd || !prtd->audio_client) { + pr_err("%s: prtd or audio client is NULL\n", __func__); + return ret; + } + + ac = prtd->audio_client; + ret = q6asm_get_path_delay(prtd->audio_client); + if (ret) { + pr_err("%s: get_path_delay failed, ret=%d\n", __func__, ret); + return ret; + } + + pr_debug("%s, path delay(in us) %u\n", __func__, ac->path_delay); + + metadata->value[0] = ac->path_delay; + + return ret; +} + + +static int msm_compr_set_next_track_param(struct snd_compr_stream *cstream, + union snd_codec_options *codec_options) +{ + struct msm_compr_audio *prtd; + struct audio_client *ac; + int ret = 0; + + if (!codec_options || !cstream) + return -EINVAL; + + prtd = cstream->runtime->private_data; + if (!prtd || !prtd->audio_client) { + pr_err("%s: prtd or audio client is NULL\n", __func__); + return -EINVAL; + } + + ac = prtd->audio_client; + + pr_debug("%s: got codec options for codec type %u", + __func__, prtd->codec); + switch (prtd->codec) { + case FORMAT_WMA_V9: + case FORMAT_WMA_V10PRO: + case FORMAT_FLAC: + case FORMAT_VORBIS: + case FORMAT_ALAC: + case FORMAT_APE: + memcpy(&(prtd->gapless_state.codec_options), + codec_options, + sizeof(union snd_codec_options)); + ret = msm_compr_send_media_format_block(cstream, + ac->stream_id, true); + if (ret < 0) { + pr_err("%s: failed to send media format block\n", + __func__); + } + break; + + default: + pr_debug("%s: Ignore sending CMD Format block\n", + __func__); + break; + } + + return ret; +} + +static int msm_compr_volume_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + struct snd_compr_stream *cstream = NULL; + uint32_t *volume = NULL; + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bounds fe_id %lu\n", + __func__, fe_id); + return -EINVAL; + } + + cstream = pdata->cstream[fe_id]; + volume = pdata->volume[fe_id]; + + volume[0] = ucontrol->value.integer.value[0]; + volume[1] = ucontrol->value.integer.value[1]; + pr_debug("%s: fe_id %lu left_vol %d right_vol %d\n", + __func__, fe_id, volume[0], volume[1]); + if (cstream) + msm_compr_set_volume(cstream, volume[0], volume[1]); + return 0; +} + +static int msm_compr_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + + struct msm_compr_pdata *pdata = + snd_soc_component_get_drvdata(comp); + uint32_t *volume = NULL; + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bound fe_id %lu\n", __func__, fe_id); + return -EINVAL; + } + + volume = pdata->volume[fe_id]; + pr_debug("%s: fe_id %lu\n", __func__, fe_id); + ucontrol->value.integer.value[0] = volume[0]; + ucontrol->value.integer.value[1] = volume[1]; + + return 0; +} + +static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + struct msm_compr_audio_effects *audio_effects = NULL; + struct snd_compr_stream *cstream = NULL; + struct msm_compr_audio *prtd = NULL; + long *values = &(ucontrol->value.integer.value[0]); + int effects_module; + + pr_debug("%s\n", __func__); + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bounds fe_id %lu\n", + __func__, fe_id); + return -EINVAL; + } + cstream = pdata->cstream[fe_id]; + audio_effects = pdata->audio_effects[fe_id]; + if (!cstream || !audio_effects) { + pr_err("%s: stream or effects inactive\n", __func__); + return -EINVAL; + } + prtd = cstream->runtime->private_data; + if (!prtd) { + pr_err("%s: cannot set audio effects\n", __func__); + return -EINVAL; + } + if (prtd->compr_passthr != LEGACY_PCM) { + pr_debug("%s: No effects for compr_type[%d]\n", + __func__, prtd->compr_passthr); + return 0; + } + pr_debug("%s: Effects supported for compr_type[%d]\n", + __func__, prtd->compr_passthr); + + effects_module = *values++; + switch (effects_module) { + case VIRTUALIZER_MODULE: + pr_debug("%s: VIRTUALIZER_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top(effects_module, + prtd->audio_client->topology)) + msm_audio_effects_virtualizer_handler( + prtd->audio_client, + &(audio_effects->virtualizer), + values); + break; + case REVERB_MODULE: + pr_debug("%s: REVERB_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top(effects_module, + prtd->audio_client->topology)) + msm_audio_effects_reverb_handler(prtd->audio_client, + &(audio_effects->reverb), + values); + break; + case BASS_BOOST_MODULE: + pr_debug("%s: BASS_BOOST_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top(effects_module, + prtd->audio_client->topology)) + msm_audio_effects_bass_boost_handler(prtd->audio_client, + &(audio_effects->bass_boost), + values); + break; + case PBE_MODULE: + pr_debug("%s: PBE_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top(effects_module, + prtd->audio_client->topology)) + msm_audio_effects_pbe_handler(prtd->audio_client, + &(audio_effects->pbe), + values); + break; + case EQ_MODULE: + pr_debug("%s: EQ_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top(effects_module, + prtd->audio_client->topology)) + msm_audio_effects_popless_eq_handler(prtd->audio_client, + &(audio_effects->equalizer), + values); + break; + case SOFT_VOLUME_MODULE: + pr_debug("%s: SOFT_VOLUME_MODULE\n", __func__); + break; + case SOFT_VOLUME2_MODULE: + pr_debug("%s: SOFT_VOLUME2_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top(effects_module, + prtd->audio_client->topology)) + msm_audio_effects_volume_handler_v2(prtd->audio_client, + &(audio_effects->volume), + values, SOFT_VOLUME_INSTANCE_2); + break; + default: + pr_err("%s Invalid effects config module\n", __func__); + return -EINVAL; + } + return 0; +} + +static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + struct msm_compr_audio_effects *audio_effects = NULL; + struct snd_compr_stream *cstream = NULL; + struct msm_compr_audio *prtd = NULL; + + pr_debug("%s\n", __func__); + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bounds fe_id %lu\n", + __func__, fe_id); + return -EINVAL; + } + cstream = pdata->cstream[fe_id]; + audio_effects = pdata->audio_effects[fe_id]; + if (!cstream || !audio_effects) { + pr_err("%s: stream or effects inactive\n", __func__); + return -EINVAL; + } + prtd = cstream->runtime->private_data; + if (!prtd) { + pr_err("%s: cannot set audio effects\n", __func__); + return -EINVAL; + } + + return 0; +} + +static int msm_compr_query_audio_effect_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + struct msm_compr_audio_effects *audio_effects = NULL; + struct snd_compr_stream *cstream = NULL; + struct msm_compr_audio *prtd = NULL; + long *values = &(ucontrol->value.integer.value[0]); + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bounds fe_id %lu\n", + __func__, fe_id); + return -EINVAL; + } + cstream = pdata->cstream[fe_id]; + audio_effects = pdata->audio_effects[fe_id]; + if (!cstream || !audio_effects) { + pr_err("%s: stream or effects inactive\n", __func__); + return -EINVAL; + } + prtd = cstream->runtime->private_data; + if (!prtd) { + pr_err("%s: cannot set audio effects\n", __func__); + return -EINVAL; + } + if (prtd->compr_passthr != LEGACY_PCM) { + pr_err("%s: No effects for compr_type[%d]\n", + __func__, prtd->compr_passthr); + return -EPERM; + } + audio_effects->query.mod_id = (u32)*values++; + audio_effects->query.parm_id = (u32)*values++; + audio_effects->query.size = (u32)*values++; + audio_effects->query.offset = (u32)*values++; + audio_effects->query.device = (u32)*values++; + return 0; +} + +static int msm_compr_query_audio_effect_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + struct msm_compr_audio_effects *audio_effects = NULL; + struct snd_compr_stream *cstream = NULL; + struct msm_compr_audio *prtd = NULL; + long *values = &(ucontrol->value.integer.value[0]); + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bounds fe_id %lu\n", + __func__, fe_id); + return -EINVAL; + } + cstream = pdata->cstream[fe_id]; + audio_effects = pdata->audio_effects[fe_id]; + if (!cstream || !audio_effects) { + pr_debug("%s: stream or effects inactive\n", __func__); + return -EINVAL; + } + prtd = cstream->runtime->private_data; + if (!prtd) { + pr_err("%s: cannot set audio effects\n", __func__); + return -EINVAL; + } + values[0] = (long)audio_effects->query.mod_id; + values[1] = (long)audio_effects->query.parm_id; + values[2] = (long)audio_effects->query.size; + values[3] = (long)audio_effects->query.offset; + values[4] = (long)audio_effects->query.device; + return 0; +} + +static int msm_compr_send_dec_params(struct snd_compr_stream *cstream, + struct msm_compr_dec_params *dec_params, + int stream_id) +{ + + int rc = 0; + struct msm_compr_audio *prtd = NULL; + struct snd_dec_ddp *ddp = &dec_params->ddp_params; + + if (!cstream || !dec_params) { + pr_err("%s: stream or dec_params inactive\n", __func__); + rc = -EINVAL; + goto end; + } + prtd = cstream->runtime->private_data; + if (!prtd) { + pr_err("%s: cannot set dec_params\n", __func__); + rc = -EINVAL; + goto end; + } + switch (prtd->codec) { + case FORMAT_MP3: + case FORMAT_MPEG4_AAC: + case FORMAT_TRUEHD: + case FORMAT_IEC61937: + case FORMAT_APTX: + pr_debug("%s: no runtime parameters for codec: %d\n", __func__, + prtd->codec); + break; + case FORMAT_AC3: + case FORMAT_EAC3: + if (prtd->compr_passthr != LEGACY_PCM) { + pr_debug("%s: No DDP param for compr_type[%d]\n", + __func__, prtd->compr_passthr); + break; + } + rc = msm_compr_send_ddp_cfg(prtd->audio_client, ddp, stream_id); + if (rc < 0) + pr_err("%s: DDP CMD CFG failed %d\n", __func__, rc); + break; + default: + break; + } +end: + return rc; + +} +static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + struct msm_compr_dec_params *dec_params = NULL; + struct snd_compr_stream *cstream = NULL; + struct msm_compr_audio *prtd = NULL; + long *values = &(ucontrol->value.integer.value[0]); + int rc = 0; + + pr_debug("%s\n", __func__); + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bounds fe_id %lu\n", + __func__, fe_id); + rc = -EINVAL; + goto end; + } + + cstream = pdata->cstream[fe_id]; + dec_params = pdata->dec_params[fe_id]; + + if (!cstream || !dec_params) { + pr_err("%s: stream or dec_params inactive\n", __func__); + rc = -EINVAL; + goto end; + } + prtd = cstream->runtime->private_data; + if (!prtd) { + pr_err("%s: cannot set dec_params\n", __func__); + rc = -EINVAL; + goto end; + } + + switch (prtd->codec) { + case FORMAT_MP3: + case FORMAT_MPEG4_AAC: + case FORMAT_FLAC: + case FORMAT_VORBIS: + case FORMAT_ALAC: + case FORMAT_APE: + case FORMAT_DTS: + case FORMAT_DSD: + case FORMAT_TRUEHD: + case FORMAT_IEC61937: + case FORMAT_APTX: + pr_debug("%s: no runtime parameters for codec: %d\n", __func__, + prtd->codec); + break; + case FORMAT_AC3: + case FORMAT_EAC3: { + struct snd_dec_ddp *ddp = &dec_params->ddp_params; + int cnt; + + if (prtd->compr_passthr != LEGACY_PCM) { + pr_debug("%s: No DDP param for compr_type[%d]\n", + __func__, prtd->compr_passthr); + break; + } + + ddp->params_length = (*values++); + if (ddp->params_length > DDP_DEC_MAX_NUM_PARAM) { + pr_err("%s: invalid num of params:: %d\n", __func__, + ddp->params_length); + rc = -EINVAL; + goto end; + } + for (cnt = 0; cnt < ddp->params_length; cnt++) { + ddp->params_id[cnt] = *values++; + ddp->params_value[cnt] = *values++; + } + prtd = cstream->runtime->private_data; + if (prtd && prtd->audio_client) + rc = msm_compr_send_dec_params(cstream, dec_params, + prtd->audio_client->stream_id); + break; + } + default: + break; + } +end: + pr_debug("%s: ret %d\n", __func__, rc); + return rc; +} + +static int msm_compr_dec_params_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* dummy function */ + return 0; +} + +static int msm_compr_playback_app_type_cfg_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_RX; + int be_id = ucontrol->value.integer.value[3]; + struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000}; + int ret = 0; + + cfg_data.app_type = ucontrol->value.integer.value[0]; + cfg_data.acdb_dev_id = ucontrol->value.integer.value[1]; + if (ucontrol->value.integer.value[2] != 0) + cfg_data.sample_rate = ucontrol->value.integer.value[2]; + pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, &cfg_data); + if (ret < 0) + pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n", + __func__, ret); + + return ret; +} + +static int msm_compr_playback_app_type_cfg_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_RX; + int be_id = 0; + struct msm_pcm_stream_app_type_cfg cfg_data = {0}; + int ret = 0; + + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + &be_id, &cfg_data); + if (ret < 0) { + pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n", + __func__, ret); + goto done; + } + + ucontrol->value.integer.value[0] = cfg_data.app_type; + ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id; + ucontrol->value.integer.value[2] = cfg_data.sample_rate; + ucontrol->value.integer.value[3] = be_id; + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); +done: + return ret; +} + +static int msm_compr_capture_app_type_cfg_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = ucontrol->value.integer.value[3]; + struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000}; + int ret = 0; + + cfg_data.app_type = ucontrol->value.integer.value[0]; + cfg_data.acdb_dev_id = ucontrol->value.integer.value[1]; + if (ucontrol->value.integer.value[2] != 0) + cfg_data.sample_rate = ucontrol->value.integer.value[2]; + pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, &cfg_data); + if (ret < 0) + pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n", + __func__, ret); + + return ret; +} + +static int msm_compr_capture_app_type_cfg_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = 0; + struct msm_pcm_stream_app_type_cfg cfg_data = {0}; + int ret = 0; + + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + &be_id, &cfg_data); + if (ret < 0) { + pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n", + __func__, ret); + goto done; + } + + ucontrol->value.integer.value[0] = cfg_data.app_type; + ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id; + ucontrol->value.integer.value[2] = cfg_data.sample_rate; + ucontrol->value.integer.value[3] = be_id; + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); +done: + return ret; +} + +static int msm_compr_channel_map_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + u64 fe_id = kcontrol->private_value; + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + int rc = 0, i; + + pr_debug("%s: fe_id- %llu\n", __func__, fe_id); + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bounds fe_id %llu\n", + __func__, fe_id); + rc = -EINVAL; + goto end; + } + + if (pdata->ch_map[fe_id]) { + pdata->ch_map[fe_id]->set_ch_map = true; + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + pdata->ch_map[fe_id]->channel_map[i] = + (char)(ucontrol->value.integer.value[i]); + } else { + pr_debug("%s: no memory for ch_map, default will be set\n", + __func__); + } +end: + pr_debug("%s: ret %d\n", __func__, rc); + return rc; +} + +static int msm_compr_channel_map_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + u64 fe_id = kcontrol->private_value; + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + int rc = 0, i; + + pr_debug("%s: fe_id- %llu\n", __func__, fe_id); + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s: Received out of bounds fe_id %llu\n", + __func__, fe_id); + rc = -EINVAL; + goto end; + } + if (pdata->ch_map[fe_id]) { + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + ucontrol->value.integer.value[i] = + pdata->ch_map[fe_id]->channel_map[i]; + } +end: + pr_debug("%s: ret %d\n", __func__, rc); + return rc; +} + +static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + struct snd_compr_stream *cstream = NULL; + struct msm_compr_audio *prtd; + int ret = 0; + struct msm_adsp_event_data *event_data = NULL; + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received invalid fe_id %lu\n", + __func__, fe_id); + ret = -EINVAL; + goto done; + } + + cstream = pdata->cstream[fe_id]; + if (cstream == NULL) { + pr_err("%s cstream is null\n", __func__); + ret = -EINVAL; + goto done; + } + + prtd = cstream->runtime->private_data; + if (!prtd) { + pr_err("%s: prtd is null\n", __func__); + ret = -EINVAL; + goto done; + } + + if (prtd->audio_client == NULL) { + pr_err("%s: audio_client is null\n", __func__); + ret = -EINVAL; + goto done; + } + + event_data = (struct msm_adsp_event_data *)ucontrol->value.bytes.data; + if ((event_data->event_type < ADSP_STREAM_PP_EVENT) || + (event_data->event_type >= ADSP_STREAM_EVENT_MAX)) { + pr_err("%s: invalid event_type=%d", + __func__, event_data->event_type); + ret = -EINVAL; + goto done; + } + + if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >= + sizeof(ucontrol->value.bytes.data)) { + pr_err("%s param length=%d exceeds limit", + __func__, event_data->payload_len); + ret = -EINVAL; + goto done; + } + + ret = q6asm_send_stream_cmd(prtd->audio_client, event_data); + if (ret < 0) + pr_err("%s: failed to send stream event cmd, err = %d\n", + __func__, ret); +done: + return ret; +} + +static int msm_compr_ion_fd_map_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + struct snd_compr_stream *cstream = NULL; + struct msm_compr_audio *prtd; + int fd; + int ret = 0; + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bounds invalid fe_id %lu\n", + __func__, fe_id); + ret = -EINVAL; + goto done; + } + + cstream = pdata->cstream[fe_id]; + if (cstream == NULL) { + pr_err("%s cstream is null\n", __func__); + ret = -EINVAL; + goto done; + } + + prtd = cstream->runtime->private_data; + if (!prtd) { + pr_err("%s: prtd is null\n", __func__); + ret = -EINVAL; + goto done; + } + + if (prtd->audio_client == NULL) { + pr_err("%s: audio_client is null\n", __func__); + ret = -EINVAL; + goto done; + } + + memcpy(&fd, ucontrol->value.bytes.data, sizeof(fd)); + ret = q6asm_send_ion_fd(prtd->audio_client, fd); + if (ret < 0) + pr_err("%s: failed to register ion fd\n", __func__); +done: + return ret; +} + +static int msm_compr_rtic_event_ack_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + struct snd_compr_stream *cstream = NULL; + struct msm_compr_audio *prtd; + int ret = 0; + int param_length = 0; + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received invalid fe_id %lu\n", + __func__, fe_id); + ret = -EINVAL; + goto done; + } + + cstream = pdata->cstream[fe_id]; + if (cstream == NULL) { + pr_err("%s cstream is null\n", __func__); + ret = -EINVAL; + goto done; + } + + prtd = cstream->runtime->private_data; + if (!prtd) { + pr_err("%s: prtd is null\n", __func__); + ret = -EINVAL; + goto done; + } + + if (prtd->audio_client == NULL) { + pr_err("%s: audio_client is null\n", __func__); + ret = -EINVAL; + goto done; + } + + memcpy(¶m_length, ucontrol->value.bytes.data, + sizeof(param_length)); + if ((param_length + sizeof(param_length)) + >= sizeof(ucontrol->value.bytes.data)) { + pr_err("%s param length=%d exceeds limit", + __func__, param_length); + ret = -EINVAL; + goto done; + } + + ret = q6asm_send_rtic_event_ack(prtd->audio_client, + ucontrol->value.bytes.data + sizeof(param_length), + param_length); + if (ret < 0) + pr_err("%s: failed to send rtic event ack, err = %d\n", + __func__, ret); +done: + return ret; +} + +static int msm_compr_gapless_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + pdata->use_dsp_gapless_mode = ucontrol->value.integer.value[0]; + pr_debug("%s: value: %ld\n", __func__, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_compr_gapless_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + struct msm_compr_pdata *pdata = + snd_soc_component_get_drvdata(comp); + pr_debug("%s:gapless mode %d\n", __func__, pdata->use_dsp_gapless_mode); + ucontrol->value.integer.value[0] = pdata->use_dsp_gapless_mode; + + return 0; +} + +static const struct snd_kcontrol_new msm_compr_gapless_controls[] = { + SOC_SINGLE_EXT("Compress Gapless Playback", + 0, 0, 1, 0, + msm_compr_gapless_get, + msm_compr_gapless_put), +}; + +static int msm_compr_probe(struct snd_soc_platform *platform) +{ + struct msm_compr_pdata *pdata; + int i; + int rc; + const char *qdsp_version; + + pr_debug("%s\n", __func__); + pdata = (struct msm_compr_pdata *) + kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + snd_soc_platform_set_drvdata(platform, pdata); + + for (i = 0; i < MSM_FRONTEND_DAI_MAX; i++) { + pdata->volume[i][0] = COMPRESSED_LR_VOL_MAX_STEPS; + pdata->volume[i][1] = COMPRESSED_LR_VOL_MAX_STEPS; + pdata->audio_effects[i] = NULL; + pdata->dec_params[i] = NULL; + pdata->cstream[i] = NULL; + pdata->ch_map[i] = NULL; + } + + snd_soc_add_platform_controls(platform, msm_compr_gapless_controls, + ARRAY_SIZE(msm_compr_gapless_controls)); + + rc = of_property_read_string(platform->dev->of_node, + "qcom,adsp-version", &qdsp_version); + if (!rc) { + if (!strcmp(qdsp_version, "MDSP 1.2")) + pdata->use_legacy_api = true; + else + pdata->use_legacy_api = false; + } else + pdata->use_legacy_api = false; + + pr_debug("%s: use legacy api %d\n", __func__, pdata->use_legacy_api); + /* + * use_dsp_gapless_mode part of platform data(pdata) is updated from HAL + * through a mixer control before compress driver is opened. The mixer + * control is used to decide if dsp gapless mode needs to be enabled. + * Gapless is disabled by default. + */ + pdata->use_dsp_gapless_mode = false; + return 0; +} + +static int msm_compr_volume_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 2; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = COMPRESSED_LR_VOL_MAX_STEPS; + return 0; +} + +static int msm_compr_audio_effects_config_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = MAX_PP_PARAMS_SZ; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0xFFFFFFFF; + return 0; +} + +static int msm_compr_query_audio_effect_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 128; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0xFFFFFFFF; + return 0; +} + +static int msm_compr_dec_params_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 128; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0xFFFFFFFF; + return 0; +} + +static int msm_compr_app_type_cfg_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 5; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0xFFFFFFFF; + return 0; +} + +static int msm_compr_channel_map_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 8; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0xFFFFFFFF; + return 0; +} + +static int msm_compr_add_volume_control(struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = "Compress Playback"; + const char *deviceNo = "NN"; + const char *suffix = "Volume"; + char *mixer_str = NULL; + int ctl_len; + struct snd_kcontrol_new fe_volume_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | + SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_compr_volume_info, + .tlv.p = msm_compr_vol_gain, + .get = msm_compr_volume_get, + .put = msm_compr_volume_put, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s NULL rtd\n", __func__); + return 0; + } + pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n", + __func__, rtd->dai_link->name, rtd->dai_link->id, + rtd->dai_link->cpu_dai_name, rtd->pcm->device); + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 + + strlen(suffix) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + if (!mixer_str) { + pr_err("failed to allocate mixer ctrl str of len %d", ctl_len); + return 0; + } + snprintf(mixer_str, ctl_len, "%s %d %s", mixer_ctl_name, + rtd->pcm->device, suffix); + fe_volume_control[0].name = mixer_str; + fe_volume_control[0].private_value = rtd->dai_link->id; + pr_debug("Registering new mixer ctl %s", mixer_str); + snd_soc_add_platform_controls(rtd->platform, fe_volume_control, + ARRAY_SIZE(fe_volume_control)); + kfree(mixer_str); + return 0; +} + +static int msm_compr_add_audio_effects_control(struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = "Audio Effects Config"; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len; + struct snd_kcontrol_new fe_audio_effects_config_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_compr_audio_effects_config_info, + .get = msm_compr_audio_effects_config_get, + .put = msm_compr_audio_effects_config_put, + .private_value = 0, + } + }; + + + if (!rtd) { + pr_err("%s NULL rtd\n", __func__); + return 0; + } + + pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n", + __func__, rtd->dai_link->name, rtd->dai_link->id, + rtd->dai_link->cpu_dai_name, rtd->pcm->device); + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + + if (!mixer_str) + return 0; + + snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device); + + fe_audio_effects_config_control[0].name = mixer_str; + fe_audio_effects_config_control[0].private_value = rtd->dai_link->id; + pr_debug("Registering new mixer ctl %s\n", mixer_str); + snd_soc_add_platform_controls(rtd->platform, + fe_audio_effects_config_control, + ARRAY_SIZE(fe_audio_effects_config_control)); + kfree(mixer_str); + return 0; +} + +static int msm_compr_add_query_audio_effect_control( + struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = "Query Audio Effect Param"; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len; + struct snd_kcontrol_new fe_query_audio_effect_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_compr_query_audio_effect_info, + .get = msm_compr_query_audio_effect_get, + .put = msm_compr_query_audio_effect_put, + .private_value = 0, + } + }; + if (!rtd) { + pr_err("%s NULL rtd\n", __func__); + return 0; + } + pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n", + __func__, rtd->dai_link->name, rtd->dai_link->id, + rtd->dai_link->cpu_dai_name, rtd->pcm->device); + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + if (!mixer_str) { + pr_err("failed to allocate mixer ctrl str of len %d", ctl_len); + return 0; + } + snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device); + fe_query_audio_effect_control[0].name = mixer_str; + fe_query_audio_effect_control[0].private_value = rtd->dai_link->id; + pr_debug("%s: registering new mixer ctl %s\n", __func__, mixer_str); + snd_soc_add_platform_controls(rtd->platform, + fe_query_audio_effect_control, + ARRAY_SIZE(fe_query_audio_effect_control)); + kfree(mixer_str); + return 0; +} + +static int msm_compr_add_audio_adsp_stream_cmd_control( + struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = DSP_STREAM_CMD; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len = 0, ret = 0; + struct snd_kcontrol_new fe_audio_adsp_stream_cmd_config_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_adsp_stream_cmd_info, + .put = msm_compr_adsp_stream_cmd_put, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s NULL rtd\n", __func__); + ret = -EINVAL; + goto done; + } + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + if (!mixer_str) { + ret = -ENOMEM; + goto done; + } + + snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device); + fe_audio_adsp_stream_cmd_config_control[0].name = mixer_str; + fe_audio_adsp_stream_cmd_config_control[0].private_value = + rtd->dai_link->id; + pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); + ret = snd_soc_add_platform_controls(rtd->platform, + fe_audio_adsp_stream_cmd_config_control, + ARRAY_SIZE(fe_audio_adsp_stream_cmd_config_control)); + if (ret < 0) + pr_err("%s: failed to add ctl %s. err = %d\n", + __func__, mixer_str, ret); + + kfree(mixer_str); +done: + return ret; +} + +static int msm_compr_add_audio_adsp_stream_callback_control( + struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = DSP_STREAM_CALLBACK; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len = 0, ret = 0; + struct snd_kcontrol *kctl; + + struct snd_kcontrol_new fe_audio_adsp_callback_config_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_adsp_stream_callback_info, + .get = msm_adsp_stream_callback_get, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s: rtd is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + if (!mixer_str) { + ret = -ENOMEM; + goto done; + } + + snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device); + fe_audio_adsp_callback_config_control[0].name = mixer_str; + fe_audio_adsp_callback_config_control[0].private_value = + rtd->dai_link->id; + pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); + ret = snd_soc_add_platform_controls(rtd->platform, + fe_audio_adsp_callback_config_control, + ARRAY_SIZE(fe_audio_adsp_callback_config_control)); + if (ret < 0) { + pr_err("%s: failed to add ctl %s. err = %d\n", + __func__, mixer_str, ret); + ret = -EINVAL; + goto free_mixer_str; + } + + kctl = snd_soc_card_get_kcontrol(rtd->card, mixer_str); + if (!kctl) { + pr_err("%s: failed to get kctl %s.\n", __func__, mixer_str); + ret = -EINVAL; + goto free_mixer_str; + } + + kctl->private_data = NULL; + +free_mixer_str: + kfree(mixer_str); +done: + return ret; +} + +static int msm_compr_add_dec_runtime_params_control( + struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = "Audio Stream"; + const char *deviceNo = "NN"; + const char *suffix = "Dec Params"; + char *mixer_str = NULL; + int ctl_len; + struct snd_kcontrol_new fe_dec_params_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_compr_dec_params_info, + .get = msm_compr_dec_params_get, + .put = msm_compr_dec_params_put, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s NULL rtd\n", __func__); + return 0; + } + + pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n", + __func__, rtd->dai_link->name, rtd->dai_link->id, + rtd->dai_link->cpu_dai_name, rtd->pcm->device); + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 + + strlen(suffix) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + + if (!mixer_str) + return 0; + + snprintf(mixer_str, ctl_len, "%s %d %s", mixer_ctl_name, + rtd->pcm->device, suffix); + + fe_dec_params_control[0].name = mixer_str; + fe_dec_params_control[0].private_value = rtd->dai_link->id; + pr_debug("Registering new mixer ctl %s", mixer_str); + snd_soc_add_platform_controls(rtd->platform, + fe_dec_params_control, + ARRAY_SIZE(fe_dec_params_control)); + kfree(mixer_str); + return 0; +} + +static int msm_compr_add_app_type_cfg_control(struct snd_soc_pcm_runtime *rtd) +{ + const char *playback_mixer_ctl_name = "Audio Stream"; + const char *capture_mixer_ctl_name = "Audio Stream Capture"; + const char *deviceNo = "NN"; + const char *suffix = "App Type Cfg"; + char *mixer_str = NULL; + int ctl_len; + struct snd_kcontrol_new fe_app_type_cfg_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_compr_app_type_cfg_info, + .put = msm_compr_playback_app_type_cfg_put, + .get = msm_compr_playback_app_type_cfg_get, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s NULL rtd\n", __func__); + return 0; + } + + pr_debug("%s: added new compr FE ctl with name %s, id %d, cpu dai %s, device no %d\n", + __func__, rtd->dai_link->name, rtd->dai_link->id, + rtd->dai_link->cpu_dai_name, rtd->pcm->device); + if (rtd->compr->direction == SND_COMPRESS_PLAYBACK) + ctl_len = strlen(playback_mixer_ctl_name) + 1 + strlen(deviceNo) + + 1 + strlen(suffix) + 1; + else + ctl_len = strlen(capture_mixer_ctl_name) + 1 + strlen(deviceNo) + + 1 + strlen(suffix) + 1; + + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + + if (!mixer_str) + return 0; + + if (rtd->compr->direction == SND_COMPRESS_PLAYBACK) + snprintf(mixer_str, ctl_len, "%s %d %s", + playback_mixer_ctl_name, rtd->pcm->device, suffix); + else + snprintf(mixer_str, ctl_len, "%s %d %s", + capture_mixer_ctl_name, rtd->pcm->device, suffix); + + fe_app_type_cfg_control[0].name = mixer_str; + fe_app_type_cfg_control[0].private_value = rtd->dai_link->id; + + if (rtd->compr->direction == SND_COMPRESS_PLAYBACK) { + fe_app_type_cfg_control[0].put = + msm_compr_playback_app_type_cfg_put; + fe_app_type_cfg_control[0].get = + msm_compr_playback_app_type_cfg_get; + } else { + fe_app_type_cfg_control[0].put = + msm_compr_capture_app_type_cfg_put; + fe_app_type_cfg_control[0].get = + msm_compr_capture_app_type_cfg_get; + } + pr_debug("Registering new mixer ctl %s", mixer_str); + snd_soc_add_platform_controls(rtd->platform, + fe_app_type_cfg_control, + ARRAY_SIZE(fe_app_type_cfg_control)); + kfree(mixer_str); + return 0; +} + +static int msm_compr_add_channel_map_control(struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = "Playback Channel Map"; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + struct msm_compr_pdata *pdata = NULL; + int ctl_len; + struct snd_kcontrol_new fe_channel_map_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_compr_channel_map_info, + .get = msm_compr_channel_map_get, + .put = msm_compr_channel_map_put, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s: NULL rtd\n", __func__); + return -EINVAL; + } + + pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n", + __func__, rtd->dai_link->name, rtd->dai_link->id, + rtd->dai_link->cpu_dai_name, rtd->pcm->device); + + ctl_len = strlen(mixer_ctl_name) + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + + if (!mixer_str) + return -ENOMEM; + + snprintf(mixer_str, ctl_len, "%s%d", mixer_ctl_name, rtd->pcm->device); + + fe_channel_map_control[0].name = mixer_str; + fe_channel_map_control[0].private_value = rtd->dai_link->id; + pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); + snd_soc_add_platform_controls(rtd->platform, + fe_channel_map_control, + ARRAY_SIZE(fe_channel_map_control)); + + pdata = snd_soc_platform_get_drvdata(rtd->platform); + pdata->ch_map[rtd->dai_link->id] = + kzalloc(sizeof(struct msm_compr_ch_map), GFP_KERNEL); + if (!pdata->ch_map[rtd->dai_link->id]) { + pr_err("%s: Could not allocate memory for channel map\n", + __func__); + kfree(mixer_str); + return -ENOMEM; + } + kfree(mixer_str); + return 0; +} + +static int msm_compr_add_io_fd_cmd_control(struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = "Playback ION FD"; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len = 0, ret = 0; + struct snd_kcontrol_new fe_ion_fd_config_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_adsp_stream_cmd_info, + .put = msm_compr_ion_fd_map_put, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s NULL rtd\n", __func__); + ret = -EINVAL; + goto done; + } + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + if (!mixer_str) { + ret = -ENOMEM; + goto done; + } + + snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device); + fe_ion_fd_config_control[0].name = mixer_str; + fe_ion_fd_config_control[0].private_value = rtd->dai_link->id; + pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); + ret = snd_soc_add_platform_controls(rtd->platform, + fe_ion_fd_config_control, + ARRAY_SIZE(fe_ion_fd_config_control)); + if (ret < 0) + pr_err("%s: failed to add ctl %s\n", __func__, mixer_str); + + kfree(mixer_str); +done: + return ret; +} + +static int msm_compr_add_event_ack_cmd_control(struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = "Playback Event Ack"; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len = 0, ret = 0; + struct snd_kcontrol_new fe_event_ack_config_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_adsp_stream_cmd_info, + .put = msm_compr_rtic_event_ack_put, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s NULL rtd\n", __func__); + ret = -EINVAL; + goto done; + } + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + if (!mixer_str) { + ret = -ENOMEM; + goto done; + } + + snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device); + fe_event_ack_config_control[0].name = mixer_str; + fe_event_ack_config_control[0].private_value = rtd->dai_link->id; + pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); + ret = snd_soc_add_platform_controls(rtd->platform, + fe_event_ack_config_control, + ARRAY_SIZE(fe_event_ack_config_control)); + if (ret < 0) + pr_err("%s: failed to add ctl %s\n", __func__, mixer_str); + + kfree(mixer_str); +done: + return ret; +} + +static int msm_compr_new(struct snd_soc_pcm_runtime *rtd) +{ + int rc; + + rc = msm_compr_add_volume_control(rtd); + if (rc) + pr_err("%s: Could not add Compr Volume Control\n", __func__); + + rc = msm_compr_add_audio_effects_control(rtd); + if (rc) + pr_err("%s: Could not add Compr Audio Effects Control\n", + __func__); + + rc = msm_compr_add_audio_adsp_stream_cmd_control(rtd); + if (rc) + pr_err("%s: Could not add Compr ADSP Stream Cmd Control\n", + __func__); + + rc = msm_compr_add_audio_adsp_stream_callback_control(rtd); + if (rc) + pr_err("%s: Could not add Compr ADSP Stream Callback Control\n", + __func__); + + rc = msm_compr_add_io_fd_cmd_control(rtd); + if (rc) + pr_err("%s: Could not add Compr ion fd Control\n", + __func__); + + rc = msm_compr_add_event_ack_cmd_control(rtd); + if (rc) + pr_err("%s: Could not add Compr event ack Control\n", + __func__); + + rc = msm_compr_add_query_audio_effect_control(rtd); + if (rc) + pr_err("%s: Could not add Compr Query Audio Effect Control\n", + __func__); + + rc = msm_compr_add_dec_runtime_params_control(rtd); + if (rc) + pr_err("%s: Could not add Compr Dec runtime params Control\n", + __func__); + rc = msm_compr_add_app_type_cfg_control(rtd); + if (rc) + pr_err("%s: Could not add Compr App Type Cfg Control\n", + __func__); + rc = msm_compr_add_channel_map_control(rtd); + if (rc) + pr_err("%s: Could not add Compr Channel Map Control\n", + __func__); + return 0; +} + +static struct snd_compr_ops msm_compr_ops = { + .open = msm_compr_open, + .free = msm_compr_free, + .trigger = msm_compr_trigger, + .pointer = msm_compr_pointer, + .set_params = msm_compr_set_params, + .set_metadata = msm_compr_set_metadata, + .get_metadata = msm_compr_get_metadata, + .set_next_track_param = msm_compr_set_next_track_param, + .ack = msm_compr_ack, + .copy = msm_compr_copy, + .get_caps = msm_compr_get_caps, + .get_codec_caps = msm_compr_get_codec_caps, +}; + +static struct snd_soc_platform_driver msm_soc_platform = { + .probe = msm_compr_probe, + .compr_ops = &msm_compr_ops, + .pcm_new = msm_compr_new, +}; + +static int msm_compr_dev_probe(struct platform_device *pdev) +{ + + pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev)); + return snd_soc_register_platform(&pdev->dev, + &msm_soc_platform); +} + +static int msm_compr_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_compr_dt_match[] = { + {.compatible = "qcom,msm-compress-dsp"}, + {} +}; +MODULE_DEVICE_TABLE(of, msm_compr_dt_match); + +static struct platform_driver msm_compr_driver = { + .driver = { + .name = "msm-compress-dsp", + .owner = THIS_MODULE, + .of_match_table = msm_compr_dt_match, + }, + .probe = msm_compr_dev_probe, + .remove = msm_compr_remove, +}; + +static int __init msm_soc_platform_init(void) +{ + return platform_driver_register(&msm_compr_driver); +} +module_init(msm_soc_platform_init); + +static void __exit msm_soc_platform_exit(void) +{ + platform_driver_unregister(&msm_compr_driver); +} +module_exit(msm_soc_platform_exit); + +MODULE_DESCRIPTION("Compress Offload platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c new file mode 100644 index 000000000000..deb179898b6a --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c @@ -0,0 +1,551 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HDMI_RX_CA_MAX 0x32 + +enum { + STATUS_PORT_STARTED, /* track if AFE port has started */ + STATUS_MAX +}; + +struct msm_ext_disp_ca { + bool set_ca; + u32 ca; +}; + +struct msm_dai_q6_hdmi_dai_data { + DECLARE_BITMAP(status_mask, STATUS_MAX); + u32 rate; + u32 channels; + struct msm_ext_disp_ca ca; + union afe_port_config port_config; +}; + +static int msm_dai_q6_ext_disp_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_hdmi_dai_data *dai_data = kcontrol->private_data; + int value = ucontrol->value.integer.value[0]; + + if (!dai_data) { + pr_err("%s: dai_data is NULL\n", __func__); + return -EINVAL; + } + + dai_data->port_config.hdmi_multi_ch.datatype = value; + pr_debug("%s: value = %d\n", __func__, value); + + return 0; +} + +static int msm_dai_q6_ext_disp_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_hdmi_dai_data *dai_data = kcontrol->private_data; + + if (!dai_data) { + pr_err("%s: dai_data is NULL\n", __func__); + return -EINVAL; + } + + ucontrol->value.integer.value[0] = + dai_data->port_config.hdmi_multi_ch.datatype; + pr_debug("%s: value = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_dai_q6_ext_disp_ca_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_hdmi_dai_data *dai_data = kcontrol->private_data; + + if (!dai_data) { + pr_err("%s: dai_data is NULL\n", __func__); + return -EINVAL; + } + + dai_data->ca.ca = ucontrol->value.integer.value[0]; + dai_data->ca.set_ca = true; + pr_debug("%s: ca = %d\n", __func__, dai_data->ca.ca); + return 0; +} + +static int msm_dai_q6_ext_disp_ca_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_hdmi_dai_data *dai_data = kcontrol->private_data; + + if (!dai_data) { + pr_err("%s: dai_data is NULL\n", __func__); + return -EINVAL; + } + + ucontrol->value.integer.value[0] = dai_data->ca.ca; + pr_debug("%s: ca = %d\n", __func__, dai_data->ca.ca); + return 0; +} + +/* HDMI format field for AFE_PORT_MULTI_CHAN_HDMI_AUDIO_IF_CONFIG command + * 0: linear PCM + * 1: non-linear PCM + */ +static const char * const hdmi_format[] = { + "LPCM", + "Compr" +}; + +static const struct soc_enum hdmi_config_enum[] = { + SOC_ENUM_SINGLE_EXT(2, hdmi_format), +}; + +static int msm_dai_q6_ext_disp_drift_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(struct afe_param_id_dev_timing_stats); + + return 0; +} + +static int msm_dai_q6_ext_disp_drift_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = -EINVAL; + struct afe_param_id_dev_timing_stats timing_stats; + struct snd_soc_dai *dai = kcontrol->private_data; + struct msm_dai_q6_hdmi_dai_data *dai_data = dev_get_drvdata(dai->dev); + + if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + pr_err("%s: afe port not started. status_mask = %ld\n", + __func__, *dai_data->status_mask); + goto done; + } + + memset(&timing_stats, 0, sizeof(struct afe_param_id_dev_timing_stats)); + ret = afe_get_av_dev_drift(&timing_stats, dai->id); + if (ret) { + pr_err("%s: Error getting AFE Drift for port %d, err=%d\n", + __func__, dai->id, ret); + + ret = -EINVAL; + goto done; + } + + memcpy(ucontrol->value.bytes.data, (void *)&timing_stats, + sizeof(struct afe_param_id_dev_timing_stats)); +done: + return ret; +} + +static const struct snd_kcontrol_new hdmi_config_controls[] = { + SOC_ENUM_EXT("HDMI RX Format", hdmi_config_enum[0], + msm_dai_q6_ext_disp_format_get, + msm_dai_q6_ext_disp_format_put), + SOC_SINGLE_MULTI_EXT("HDMI RX CA", SND_SOC_NOPM, 0, + HDMI_RX_CA_MAX, 0, 1, + msm_dai_q6_ext_disp_ca_get, + msm_dai_q6_ext_disp_ca_put), + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "HDMI DRIFT", + .info = msm_dai_q6_ext_disp_drift_info, + .get = msm_dai_q6_ext_disp_drift_get, + }, +}; + +static const struct snd_kcontrol_new display_port_config_controls[] = { + SOC_ENUM_EXT("Display Port RX Format", hdmi_config_enum[0], + msm_dai_q6_ext_disp_format_get, + msm_dai_q6_ext_disp_format_put), + SOC_SINGLE_MULTI_EXT("Display Port RX CA", SND_SOC_NOPM, 0, + HDMI_RX_CA_MAX, 0, 1, + msm_dai_q6_ext_disp_ca_get, + msm_dai_q6_ext_disp_ca_put), + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "DISPLAY_PORT DRIFT", + .info = msm_dai_q6_ext_disp_drift_info, + .get = msm_dai_q6_ext_disp_drift_get, + }, +}; + +/* Current implementation assumes hw_param is called once + * This may not be the case but what to do when ADM and AFE + * port are already opened and parameter changes + */ +static int msm_dai_q6_hdmi_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_hdmi_dai_data *dai_data = dev_get_drvdata(dai->dev); + + dai_data->channels = params_channels(params); + dai_data->rate = params_rate(params); + dai_data->port_config.hdmi_multi_ch.reserved = 0; + dai_data->port_config.hdmi_multi_ch.hdmi_cfg_minor_version = 1; + dai_data->port_config.hdmi_multi_ch.sample_rate = dai_data->rate; + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + dai_data->port_config.hdmi_multi_ch.bit_width = 16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + dai_data->port_config.hdmi_multi_ch.bit_width = 24; + break; + } + + /*refer to HDMI spec CEA-861-E: Table 28 Audio InfoFrame Data Byte 4*/ + switch (dai_data->channels) { + case 2: + dai_data->port_config.hdmi_multi_ch.channel_allocation = 0; + break; + case 3: + dai_data->port_config.hdmi_multi_ch.channel_allocation = 0x02; + break; + case 4: + dai_data->port_config.hdmi_multi_ch.channel_allocation = 0x06; + break; + case 5: + dai_data->port_config.hdmi_multi_ch.channel_allocation = 0x0A; + break; + case 6: + dai_data->port_config.hdmi_multi_ch.channel_allocation = 0x0B; + break; + case 7: + dai_data->port_config.hdmi_multi_ch.channel_allocation = 0x12; + break; + case 8: + dai_data->port_config.hdmi_multi_ch.channel_allocation = 0x13; + break; + default: + dev_err(dai->dev, "invalid Channels = %u\n", + dai_data->channels); + return -EINVAL; + } + dev_dbg(dai->dev, "%s() minor version: %u samplerate: %u bitwidth: %u\n" + "num_ch = %u channel_allocation = %u datatype = %d\n", __func__, + dai_data->port_config.hdmi_multi_ch.hdmi_cfg_minor_version, + dai_data->port_config.hdmi_multi_ch.sample_rate, + dai_data->port_config.hdmi_multi_ch.bit_width, + dai_data->channels, + dai_data->port_config.hdmi_multi_ch.channel_allocation, + dai_data->port_config.hdmi_multi_ch.datatype); + + return 0; +} + + +static void msm_dai_q6_hdmi_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_hdmi_dai_data *dai_data = dev_get_drvdata(dai->dev); + int rc = 0; + + if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + pr_info("%s: afe port not started. dai_data->status_mask = %ld\n", + __func__, *dai_data->status_mask); + return; + } + + rc = afe_close(dai->id); /* can block */ + if (rc < 0) + dev_err(dai->dev, "fail to close AFE port\n"); + + pr_debug("%s: dai_data->status_mask = %ld\n", __func__, + *dai_data->status_mask); + + clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); +} + + +static int msm_dai_q6_hdmi_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_hdmi_dai_data *dai_data = dev_get_drvdata(dai->dev); + int rc = 0; + + if (dai_data->ca.set_ca) + dai_data->port_config.hdmi_multi_ch.channel_allocation = + dai_data->ca.ca; + + if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + rc = afe_port_start(dai->id, &dai_data->port_config, + dai_data->rate); + if (rc < 0) + dev_err(dai->dev, "fail to open AFE port %x\n", + dai->id); + else + set_bit(STATUS_PORT_STARTED, + dai_data->status_mask); + } + + return rc; +} + +static inline void msm_dai_q6_hdmi_set_dai_id(struct snd_soc_dai *dai) +{ + if (!dai->driver->id) { + dev_warn(dai->dev, "DAI driver id is not set\n"); + return; + } + dai->id = dai->driver->id; +} + +static int msm_dai_q6_hdmi_dai_probe(struct snd_soc_dai *dai) +{ + struct msm_dai_q6_hdmi_dai_data *dai_data; + const struct snd_kcontrol_new *kcontrol; + int rc = 0; + struct snd_soc_dapm_route intercon; + struct snd_soc_dapm_context *dapm; + + if (!dai || !dai->driver) { + pr_err("%s: dai or dai->driver is NULL\n", __func__); + return -EINVAL; + } + dai_data = kzalloc(sizeof(struct msm_dai_q6_hdmi_dai_data), + GFP_KERNEL); + + if (!dai_data) { + dev_err(dai->dev, "DAI-%d: fail to allocate dai data\n", + dai->id); + rc = -ENOMEM; + } else + dev_set_drvdata(dai->dev, dai_data); + + msm_dai_q6_hdmi_set_dai_id(dai); + + if (dai->driver->id == HDMI_RX) { + kcontrol = &hdmi_config_controls[0]; + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(kcontrol, dai_data)); + + kcontrol = &hdmi_config_controls[1]; + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(kcontrol, dai_data)); + + kcontrol = &hdmi_config_controls[2]; + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(kcontrol, dai)); + } else if (dai->driver->id == DISPLAY_PORT_RX) { + kcontrol = &display_port_config_controls[0]; + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(kcontrol, dai_data)); + + kcontrol = &display_port_config_controls[1]; + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(kcontrol, dai_data)); + + kcontrol = &display_port_config_controls[2]; + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(kcontrol, dai)); + } else { + dev_err(dai->dev, "%s: Invalid id:%d\n", + __func__, dai->driver->id); + kfree(dai_data); + dev_set_drvdata(dai->dev, NULL); + return -EINVAL; + } + + dapm = snd_soc_component_get_dapm(dai->component); + memset(&intercon, 0, sizeof(intercon)); + if (!rc) { + if (dai->driver->playback.stream_name && + dai->driver->playback.aif_name) { + dev_dbg(dai->dev, "%s add route for widget %s", + __func__, dai->driver->playback.stream_name); + intercon.source = dai->driver->playback.aif_name; + intercon.sink = dai->driver->playback.stream_name; + dev_dbg(dai->dev, "%s src %s sink %s\n", + __func__, intercon.source, intercon.sink); + snd_soc_dapm_add_routes(dapm, &intercon, 1); + } + if (dai->driver->capture.stream_name && + dai->driver->capture.aif_name) { + dev_dbg(dai->dev, "%s add route for widget %s", + __func__, dai->driver->capture.stream_name); + intercon.sink = dai->driver->capture.aif_name; + intercon.source = dai->driver->capture.stream_name; + dev_dbg(dai->dev, "%s src %s sink %s\n", + __func__, intercon.source, intercon.sink); + snd_soc_dapm_add_routes(dapm, &intercon, 1); + } + } + return rc; +} + +static int msm_dai_q6_hdmi_dai_remove(struct snd_soc_dai *dai) +{ + struct msm_dai_q6_hdmi_dai_data *dai_data; + int rc; + + dai_data = dev_get_drvdata(dai->dev); + + /* If AFE port is still up, close it */ + if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + rc = afe_close(dai->id); /* can block */ + if (rc < 0) + dev_err(dai->dev, "fail to close AFE port\n"); + + clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); + } + kfree(dai_data); + + return 0; +} + +static struct snd_soc_dai_ops msm_dai_q6_hdmi_ops = { + .prepare = msm_dai_q6_hdmi_prepare, + .hw_params = msm_dai_q6_hdmi_hw_params, + .shutdown = msm_dai_q6_hdmi_shutdown, +}; + +static struct snd_soc_dai_driver msm_dai_q6_hdmi_hdmi_rx_dai = { + .playback = { + .stream_name = "HDMI Playback", + .aif_name = "HDMI", + .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 2, + .channels_max = 8, + .rate_max = 192000, + .rate_min = 48000, + }, + .ops = &msm_dai_q6_hdmi_ops, + .id = HDMI_RX, + .probe = msm_dai_q6_hdmi_dai_probe, + .remove = msm_dai_q6_hdmi_dai_remove, +}; + +static struct snd_soc_dai_driver msm_dai_q6_display_port_rx_dai[] = { + { + .playback = { + .stream_name = "Display Port Playback", + .aif_name = "DISPLAY_PORT", + .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 2, + .channels_max = 8, + .rate_max = 192000, + .rate_min = 48000, + }, + .ops = &msm_dai_q6_hdmi_ops, + .id = DISPLAY_PORT_RX, + .probe = msm_dai_q6_hdmi_dai_probe, + .remove = msm_dai_q6_hdmi_dai_remove, + }, +}; + +static const struct snd_soc_component_driver msm_dai_hdmi_q6_component = { + .name = "msm-dai-q6-hdmi", +}; + +/* To do: change to register DAIs as batch */ +static int msm_dai_q6_hdmi_dev_probe(struct platform_device *pdev) +{ + int rc, id; + const char *q6_dev_id = "qcom,msm-dai-q6-dev-id"; + + rc = of_property_read_u32(pdev->dev.of_node, q6_dev_id, &id); + if (rc) { + dev_err(&pdev->dev, + "%s: missing %s in dt node\n", __func__, q6_dev_id); + return rc; + } + + pdev->id = id; + + pr_debug("%s: dev name %s, id:%d\n", __func__, + dev_name(&pdev->dev), pdev->id); + + switch (pdev->id) { + case HDMI_RX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_hdmi_q6_component, + &msm_dai_q6_hdmi_hdmi_rx_dai, 1); + break; + case DISPLAY_PORT_RX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_hdmi_q6_component, + &msm_dai_q6_display_port_rx_dai[0], + ARRAY_SIZE(msm_dai_q6_display_port_rx_dai)); + break; + default: + dev_err(&pdev->dev, "invalid device ID %d\n", pdev->id); + rc = -ENODEV; + break; + } + return rc; +} + +static int msm_dai_q6_hdmi_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_component(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_dai_q6_hdmi_dt_match[] = { + {.compatible = "qcom,msm-dai-q6-hdmi"}, + {} +}; +MODULE_DEVICE_TABLE(of, msm_dai_q6_hdmi_dt_match); + +static struct platform_driver msm_dai_q6_hdmi_driver = { + .probe = msm_dai_q6_hdmi_dev_probe, + .remove = msm_dai_q6_hdmi_dev_remove, + .driver = { + .name = "msm-dai-q6-hdmi", + .owner = THIS_MODULE, + .of_match_table = msm_dai_q6_hdmi_dt_match, + }, +}; + +static int __init msm_dai_q6_hdmi_init(void) +{ + return platform_driver_register(&msm_dai_q6_hdmi_driver); +} +module_init(msm_dai_q6_hdmi_init); + +static void __exit msm_dai_q6_hdmi_exit(void) +{ + platform_driver_unregister(&msm_dai_q6_hdmi_driver); +} +module_exit(msm_dai_q6_hdmi_exit); + +/* Module information */ +MODULE_DESCRIPTION("MSM DSP HDMI DAI driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c new file mode 100644 index 000000000000..c8b01c679788 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c @@ -0,0 +1,8253 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MSM_DAI_PRI_AUXPCM_DT_DEV_ID 1 +#define MSM_DAI_SEC_AUXPCM_DT_DEV_ID 2 +#define MSM_DAI_TERT_AUXPCM_DT_DEV_ID 3 +#define MSM_DAI_QUAT_AUXPCM_DT_DEV_ID 4 + + +#define spdif_clock_value(rate) (2*rate*32*2) +#define CHANNEL_STATUS_SIZE 24 +#define CHANNEL_STATUS_MASK_INIT 0x0 +#define CHANNEL_STATUS_MASK 0x4 +#define AFE_API_VERSION_CLOCK_SET 1 + +#define DAI_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +enum { + ENC_FMT_NONE, + ENC_FMT_SBC = ASM_MEDIA_FMT_SBC, + ENC_FMT_AAC_V2 = ASM_MEDIA_FMT_AAC_V2, + ENC_FMT_APTX = ASM_MEDIA_FMT_APTX, + ENC_FMT_APTX_HD = ASM_MEDIA_FMT_APTX_HD, +}; + +enum { + SPKR_1, + SPKR_2, +}; + +static const struct afe_clk_set lpass_clk_set_default = { + AFE_API_VERSION_CLOCK_SET, + Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT, + Q6AFE_LPASS_OSR_CLK_2_P048_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, +}; + +static const struct afe_clk_cfg lpass_clk_cfg_default = { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_OSR_CLK_2_P048_MHZ, + 0, + Q6AFE_LPASS_CLK_SRC_INTERNAL, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + Q6AFE_LPASS_MODE_CLK1_VALID, + 0, +}; +enum { + STATUS_PORT_STARTED, /* track if AFE port has started */ + /* track AFE Tx port status for bi-directional transfers */ + STATUS_TX_PORT, + /* track AFE Rx port status for bi-directional transfers */ + STATUS_RX_PORT, + STATUS_MAX +}; + +enum { + RATE_8KHZ, + RATE_16KHZ, + RATE_MAX_NUM_OF_AUX_PCM_RATES, +}; + +enum { + IDX_PRIMARY_TDM_RX_0, + IDX_PRIMARY_TDM_RX_1, + IDX_PRIMARY_TDM_RX_2, + IDX_PRIMARY_TDM_RX_3, + IDX_PRIMARY_TDM_RX_4, + IDX_PRIMARY_TDM_RX_5, + IDX_PRIMARY_TDM_RX_6, + IDX_PRIMARY_TDM_RX_7, + IDX_PRIMARY_TDM_TX_0, + IDX_PRIMARY_TDM_TX_1, + IDX_PRIMARY_TDM_TX_2, + IDX_PRIMARY_TDM_TX_3, + IDX_PRIMARY_TDM_TX_4, + IDX_PRIMARY_TDM_TX_5, + IDX_PRIMARY_TDM_TX_6, + IDX_PRIMARY_TDM_TX_7, + IDX_SECONDARY_TDM_RX_0, + IDX_SECONDARY_TDM_RX_1, + IDX_SECONDARY_TDM_RX_2, + IDX_SECONDARY_TDM_RX_3, + IDX_SECONDARY_TDM_RX_4, + IDX_SECONDARY_TDM_RX_5, + IDX_SECONDARY_TDM_RX_6, + IDX_SECONDARY_TDM_RX_7, + IDX_SECONDARY_TDM_TX_0, + IDX_SECONDARY_TDM_TX_1, + IDX_SECONDARY_TDM_TX_2, + IDX_SECONDARY_TDM_TX_3, + IDX_SECONDARY_TDM_TX_4, + IDX_SECONDARY_TDM_TX_5, + IDX_SECONDARY_TDM_TX_6, + IDX_SECONDARY_TDM_TX_7, + IDX_TERTIARY_TDM_RX_0, + IDX_TERTIARY_TDM_RX_1, + IDX_TERTIARY_TDM_RX_2, + IDX_TERTIARY_TDM_RX_3, + IDX_TERTIARY_TDM_RX_4, + IDX_TERTIARY_TDM_RX_5, + IDX_TERTIARY_TDM_RX_6, + IDX_TERTIARY_TDM_RX_7, + IDX_TERTIARY_TDM_TX_0, + IDX_TERTIARY_TDM_TX_1, + IDX_TERTIARY_TDM_TX_2, + IDX_TERTIARY_TDM_TX_3, + IDX_TERTIARY_TDM_TX_4, + IDX_TERTIARY_TDM_TX_5, + IDX_TERTIARY_TDM_TX_6, + IDX_TERTIARY_TDM_TX_7, + IDX_QUATERNARY_TDM_RX_0, + IDX_QUATERNARY_TDM_RX_1, + IDX_QUATERNARY_TDM_RX_2, + IDX_QUATERNARY_TDM_RX_3, + IDX_QUATERNARY_TDM_RX_4, + IDX_QUATERNARY_TDM_RX_5, + IDX_QUATERNARY_TDM_RX_6, + IDX_QUATERNARY_TDM_RX_7, + IDX_QUATERNARY_TDM_TX_0, + IDX_QUATERNARY_TDM_TX_1, + IDX_QUATERNARY_TDM_TX_2, + IDX_QUATERNARY_TDM_TX_3, + IDX_QUATERNARY_TDM_TX_4, + IDX_QUATERNARY_TDM_TX_5, + IDX_QUATERNARY_TDM_TX_6, + IDX_QUATERNARY_TDM_TX_7, + IDX_TDM_MAX, +}; + +enum { + IDX_GROUP_PRIMARY_TDM_RX, + IDX_GROUP_PRIMARY_TDM_TX, + IDX_GROUP_SECONDARY_TDM_RX, + IDX_GROUP_SECONDARY_TDM_TX, + IDX_GROUP_TERTIARY_TDM_RX, + IDX_GROUP_TERTIARY_TDM_TX, + IDX_GROUP_QUATERNARY_TDM_RX, + IDX_GROUP_QUATERNARY_TDM_TX, + IDX_GROUP_TDM_MAX, +}; + +struct msm_dai_q6_dai_data { + DECLARE_BITMAP(status_mask, STATUS_MAX); + DECLARE_BITMAP(hwfree_status, STATUS_MAX); + u32 rate; + u32 channels; + u32 bitwidth; + u32 cal_mode; + u32 afe_in_channels; + u16 afe_in_bitformat; + struct afe_enc_config enc_config; + union afe_port_config port_config; + u16 vi_feed_mono; +}; + +struct msm_dai_q6_spdif_dai_data { + DECLARE_BITMAP(status_mask, STATUS_MAX); + u32 rate; + u32 channels; + u32 bitwidth; + struct afe_spdif_port_config spdif_port; +}; + +struct msm_dai_q6_mi2s_dai_config { + u16 pdata_mi2s_lines; + struct msm_dai_q6_dai_data mi2s_dai_data; +}; + +struct msm_dai_q6_mi2s_dai_data { + struct msm_dai_q6_mi2s_dai_config tx_dai; + struct msm_dai_q6_mi2s_dai_config rx_dai; +}; + +struct msm_dai_q6_auxpcm_dai_data { + /* BITMAP to track Rx and Tx port usage count */ + DECLARE_BITMAP(auxpcm_port_status, STATUS_MAX); + struct mutex rlock; /* auxpcm dev resource lock */ + u16 rx_pid; /* AUXPCM RX AFE port ID */ + u16 tx_pid; /* AUXPCM TX AFE port ID */ + u16 afe_clk_ver; + struct afe_clk_cfg clk_cfg; /* hold LPASS clock configuration */ + struct afe_clk_set clk_set; /* hold LPASS clock configuration */ + struct msm_dai_q6_dai_data bdai_data; /* incoporate base DAI data */ +}; + +struct msm_dai_q6_tdm_dai_data { + DECLARE_BITMAP(status_mask, STATUS_MAX); + u32 rate; + u32 channels; + u32 bitwidth; + u32 num_group_ports; + struct afe_clk_set clk_set; /* hold LPASS clock config. */ + union afe_port_group_config group_cfg; /* hold tdm group config */ + struct afe_tdm_port_config port_cfg; /* hold tdm config */ +}; + +/* MI2S format field for AFE_PORT_CMD_I2S_CONFIG command + * 0: linear PCM + * 1: non-linear PCM + * 2: PCM data in IEC 60968 container + * 3: compressed data in IEC 60958 container + */ +static const char *const mi2s_format[] = { + "LPCM", + "Compr", + "LPCM-60958", + "Compr-60958" +}; + +static const char *const mi2s_vi_feed_mono[] = { + "Left", + "Right", +}; + +static const struct soc_enum mi2s_config_enum[] = { + SOC_ENUM_SINGLE_EXT(4, mi2s_format), + SOC_ENUM_SINGLE_EXT(2, mi2s_vi_feed_mono), +}; + +static const char *const sb_format[] = { + "UNPACKED", + "PACKED_16B", + "DSD_DOP", +}; + +static const struct soc_enum sb_config_enum[] = { + SOC_ENUM_SINGLE_EXT(3, sb_format), +}; + +static const char *const tdm_data_format[] = { + "LPCM", + "Compr", + "Gen Compr" +}; + +static const char *const tdm_header_type[] = { + "Invalid", + "Default", + "Entertainment", +}; + +static const struct soc_enum tdm_config_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_data_format), tdm_data_format), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_header_type), tdm_header_type), +}; + +static DEFINE_MUTEX(tdm_mutex); + +static atomic_t tdm_group_ref[IDX_GROUP_TDM_MAX]; + +/* cache of group cfg per parent node */ +static struct afe_param_id_group_device_tdm_cfg tdm_group_cfg = { + AFE_API_VERSION_GROUP_DEVICE_TDM_CONFIG, + AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_RX, + 0, + {AFE_PORT_ID_QUATERNARY_TDM_RX, + AFE_PORT_ID_QUATERNARY_TDM_RX_1, + AFE_PORT_ID_QUATERNARY_TDM_RX_2, + AFE_PORT_ID_QUATERNARY_TDM_RX_3, + AFE_PORT_ID_QUATERNARY_TDM_RX_4, + AFE_PORT_ID_QUATERNARY_TDM_RX_5, + AFE_PORT_ID_QUATERNARY_TDM_RX_6, + AFE_PORT_ID_QUATERNARY_TDM_RX_7}, + 8, + 48000, + 32, + 8, + 32, + 0xFF, +}; + +static u32 num_tdm_group_ports; + +static struct afe_clk_set tdm_clk_set = { + AFE_API_VERSION_CLOCK_SET, + Q6AFE_LPASS_CLK_ID_QUAD_TDM_EBIT, + Q6AFE_LPASS_IBIT_CLK_DISABLE, + Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, +}; + +int msm_dai_q6_get_group_idx(u16 id) +{ + switch (id) { + case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + return IDX_GROUP_PRIMARY_TDM_RX; + case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + return IDX_GROUP_PRIMARY_TDM_TX; + case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + return IDX_GROUP_SECONDARY_TDM_RX; + case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + return IDX_GROUP_SECONDARY_TDM_TX; + case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + return IDX_GROUP_TERTIARY_TDM_RX; + case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + return IDX_GROUP_TERTIARY_TDM_TX; + case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + return IDX_GROUP_QUATERNARY_TDM_RX; + case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + return IDX_GROUP_QUATERNARY_TDM_TX; + default: return -EINVAL; + } +} + +int msm_dai_q6_get_port_idx(u16 id) +{ + switch (id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + return IDX_PRIMARY_TDM_RX_0; + case AFE_PORT_ID_PRIMARY_TDM_TX: + return IDX_PRIMARY_TDM_TX_0; + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + return IDX_PRIMARY_TDM_RX_1; + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + return IDX_PRIMARY_TDM_TX_1; + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + return IDX_PRIMARY_TDM_RX_2; + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + return IDX_PRIMARY_TDM_TX_2; + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + return IDX_PRIMARY_TDM_RX_3; + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + return IDX_PRIMARY_TDM_TX_3; + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + return IDX_PRIMARY_TDM_RX_4; + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + return IDX_PRIMARY_TDM_TX_4; + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + return IDX_PRIMARY_TDM_RX_5; + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + return IDX_PRIMARY_TDM_TX_5; + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + return IDX_PRIMARY_TDM_RX_6; + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + return IDX_PRIMARY_TDM_TX_6; + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + return IDX_PRIMARY_TDM_RX_7; + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + return IDX_PRIMARY_TDM_TX_7; + case AFE_PORT_ID_SECONDARY_TDM_RX: + return IDX_SECONDARY_TDM_RX_0; + case AFE_PORT_ID_SECONDARY_TDM_TX: + return IDX_SECONDARY_TDM_TX_0; + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + return IDX_SECONDARY_TDM_RX_1; + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + return IDX_SECONDARY_TDM_TX_1; + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + return IDX_SECONDARY_TDM_RX_2; + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + return IDX_SECONDARY_TDM_TX_2; + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + return IDX_SECONDARY_TDM_RX_3; + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + return IDX_SECONDARY_TDM_TX_3; + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + return IDX_SECONDARY_TDM_RX_4; + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + return IDX_SECONDARY_TDM_TX_4; + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + return IDX_SECONDARY_TDM_RX_5; + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + return IDX_SECONDARY_TDM_TX_5; + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + return IDX_SECONDARY_TDM_RX_6; + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + return IDX_SECONDARY_TDM_TX_6; + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + return IDX_SECONDARY_TDM_RX_7; + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + return IDX_SECONDARY_TDM_TX_7; + case AFE_PORT_ID_TERTIARY_TDM_RX: + return IDX_TERTIARY_TDM_RX_0; + case AFE_PORT_ID_TERTIARY_TDM_TX: + return IDX_TERTIARY_TDM_TX_0; + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + return IDX_TERTIARY_TDM_RX_1; + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + return IDX_TERTIARY_TDM_TX_1; + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + return IDX_TERTIARY_TDM_RX_2; + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + return IDX_TERTIARY_TDM_TX_2; + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + return IDX_TERTIARY_TDM_RX_3; + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + return IDX_TERTIARY_TDM_TX_3; + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + return IDX_TERTIARY_TDM_RX_4; + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + return IDX_TERTIARY_TDM_TX_4; + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + return IDX_TERTIARY_TDM_RX_5; + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + return IDX_TERTIARY_TDM_TX_5; + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + return IDX_TERTIARY_TDM_RX_6; + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + return IDX_TERTIARY_TDM_TX_6; + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + return IDX_TERTIARY_TDM_RX_7; + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + return IDX_TERTIARY_TDM_TX_7; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + return IDX_QUATERNARY_TDM_RX_0; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + return IDX_QUATERNARY_TDM_TX_0; + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + return IDX_QUATERNARY_TDM_RX_1; + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + return IDX_QUATERNARY_TDM_TX_1; + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + return IDX_QUATERNARY_TDM_RX_2; + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + return IDX_QUATERNARY_TDM_TX_2; + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + return IDX_QUATERNARY_TDM_RX_3; + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + return IDX_QUATERNARY_TDM_TX_3; + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + return IDX_QUATERNARY_TDM_RX_4; + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + return IDX_QUATERNARY_TDM_TX_4; + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + return IDX_QUATERNARY_TDM_RX_5; + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + return IDX_QUATERNARY_TDM_TX_5; + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + return IDX_QUATERNARY_TDM_RX_6; + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + return IDX_QUATERNARY_TDM_TX_6; + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + return IDX_QUATERNARY_TDM_RX_7; + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + return IDX_QUATERNARY_TDM_TX_7; + default: return -EINVAL; + } +} + +static u16 msm_dai_q6_max_num_slot(int frame_rate) +{ + /* Max num of slots is bits per frame divided + * by bits per sample which is 16 + */ + switch (frame_rate) { + case AFE_PORT_PCM_BITS_PER_FRAME_8: + return 0; + case AFE_PORT_PCM_BITS_PER_FRAME_16: + return 1; + case AFE_PORT_PCM_BITS_PER_FRAME_32: + return 2; + case AFE_PORT_PCM_BITS_PER_FRAME_64: + return 4; + case AFE_PORT_PCM_BITS_PER_FRAME_128: + return 8; + case AFE_PORT_PCM_BITS_PER_FRAME_256: + return 16; + default: + pr_err("%s Invalid bits per frame %d\n", + __func__, frame_rate); + return 0; + } +} + +static int msm_dai_q6_dai_add_route(struct snd_soc_dai *dai) +{ + struct snd_soc_dapm_route intercon; + struct snd_soc_dapm_context *dapm; + + if (!dai) { + pr_err("%s: Invalid params dai\n", __func__); + return -EINVAL; + } + if (!dai->driver) { + pr_err("%s: Invalid params dai driver\n", __func__); + return -EINVAL; + } + dapm = snd_soc_component_get_dapm(dai->component); + memset(&intercon, 0, sizeof(intercon)); + if (dai->driver->playback.stream_name && + dai->driver->playback.aif_name) { + dev_dbg(dai->dev, "%s: add route for widget %s", + __func__, dai->driver->playback.stream_name); + intercon.source = dai->driver->playback.aif_name; + intercon.sink = dai->driver->playback.stream_name; + dev_dbg(dai->dev, "%s: src %s sink %s\n", + __func__, intercon.source, intercon.sink); + snd_soc_dapm_add_routes(dapm, &intercon, 1); + } + if (dai->driver->capture.stream_name && + dai->driver->capture.aif_name) { + dev_dbg(dai->dev, "%s: add route for widget %s", + __func__, dai->driver->capture.stream_name); + intercon.sink = dai->driver->capture.aif_name; + intercon.source = dai->driver->capture.stream_name; + dev_dbg(dai->dev, "%s: src %s sink %s\n", + __func__, intercon.source, intercon.sink); + snd_soc_dapm_add_routes(dapm, &intercon, 1); + } + return 0; +} + +static int msm_dai_q6_auxpcm_hw_params( + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_auxpcm_dai_data *aux_dai_data = + dev_get_drvdata(dai->dev); + struct msm_dai_q6_dai_data *dai_data = &aux_dai_data->bdai_data; + struct msm_dai_auxpcm_pdata *auxpcm_pdata = + (struct msm_dai_auxpcm_pdata *) dai->dev->platform_data; + int rc = 0, slot_mapping_copy_len = 0; + + if (params_channels(params) != 1 || (params_rate(params) != 8000 && + params_rate(params) != 16000)) { + dev_err(dai->dev, "%s: invalid param chan %d rate %d\n", + __func__, params_channels(params), params_rate(params)); + return -EINVAL; + } + + mutex_lock(&aux_dai_data->rlock); + + if (test_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status) || + test_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status)) { + /* AUXPCM DAI in use */ + if (dai_data->rate != params_rate(params)) { + dev_err(dai->dev, "%s: rate mismatch of running DAI\n", + __func__); + rc = -EINVAL; + } + mutex_unlock(&aux_dai_data->rlock); + return rc; + } + + dai_data->channels = params_channels(params); + dai_data->rate = params_rate(params); + + if (dai_data->rate == 8000) { + dai_data->port_config.pcm.pcm_cfg_minor_version = + AFE_API_VERSION_PCM_CONFIG; + dai_data->port_config.pcm.aux_mode = auxpcm_pdata->mode_8k.mode; + dai_data->port_config.pcm.sync_src = auxpcm_pdata->mode_8k.sync; + dai_data->port_config.pcm.frame_setting = + auxpcm_pdata->mode_8k.frame; + dai_data->port_config.pcm.quantype = + auxpcm_pdata->mode_8k.quant; + dai_data->port_config.pcm.ctrl_data_out_enable = + auxpcm_pdata->mode_8k.data; + dai_data->port_config.pcm.sample_rate = dai_data->rate; + dai_data->port_config.pcm.num_channels = dai_data->channels; + dai_data->port_config.pcm.bit_width = 16; + if (ARRAY_SIZE(dai_data->port_config.pcm.slot_number_mapping) <= + auxpcm_pdata->mode_8k.num_slots) + slot_mapping_copy_len = + ARRAY_SIZE( + dai_data->port_config.pcm.slot_number_mapping) + * sizeof(uint16_t); + else + slot_mapping_copy_len = auxpcm_pdata->mode_8k.num_slots + * sizeof(uint16_t); + + if (auxpcm_pdata->mode_8k.slot_mapping) { + memcpy(dai_data->port_config.pcm.slot_number_mapping, + auxpcm_pdata->mode_8k.slot_mapping, + slot_mapping_copy_len); + } else { + dev_err(dai->dev, "%s 8khz slot mapping is NULL\n", + __func__); + mutex_unlock(&aux_dai_data->rlock); + return -EINVAL; + } + } else { + dai_data->port_config.pcm.pcm_cfg_minor_version = + AFE_API_VERSION_PCM_CONFIG; + dai_data->port_config.pcm.aux_mode = + auxpcm_pdata->mode_16k.mode; + dai_data->port_config.pcm.sync_src = + auxpcm_pdata->mode_16k.sync; + dai_data->port_config.pcm.frame_setting = + auxpcm_pdata->mode_16k.frame; + dai_data->port_config.pcm.quantype = + auxpcm_pdata->mode_16k.quant; + dai_data->port_config.pcm.ctrl_data_out_enable = + auxpcm_pdata->mode_16k.data; + dai_data->port_config.pcm.sample_rate = dai_data->rate; + dai_data->port_config.pcm.num_channels = dai_data->channels; + dai_data->port_config.pcm.bit_width = 16; + if (ARRAY_SIZE(dai_data->port_config.pcm.slot_number_mapping) <= + auxpcm_pdata->mode_16k.num_slots) + slot_mapping_copy_len = + ARRAY_SIZE( + dai_data->port_config.pcm.slot_number_mapping) + * sizeof(uint16_t); + else + slot_mapping_copy_len = auxpcm_pdata->mode_16k.num_slots + * sizeof(uint16_t); + + if (auxpcm_pdata->mode_16k.slot_mapping) { + memcpy(dai_data->port_config.pcm.slot_number_mapping, + auxpcm_pdata->mode_16k.slot_mapping, + slot_mapping_copy_len); + } else { + dev_err(dai->dev, "%s 16khz slot mapping is NULL\n", + __func__); + mutex_unlock(&aux_dai_data->rlock); + return -EINVAL; + } + } + + dev_dbg(dai->dev, "%s: aux_mode 0x%x sync_src 0x%x frame_setting 0x%x\n", + __func__, dai_data->port_config.pcm.aux_mode, + dai_data->port_config.pcm.sync_src, + dai_data->port_config.pcm.frame_setting); + dev_dbg(dai->dev, "%s: qtype 0x%x dout 0x%x num_map[0] 0x%x\n" + "num_map[1] 0x%x num_map[2] 0x%x num_map[3] 0x%x\n", + __func__, dai_data->port_config.pcm.quantype, + dai_data->port_config.pcm.ctrl_data_out_enable, + dai_data->port_config.pcm.slot_number_mapping[0], + dai_data->port_config.pcm.slot_number_mapping[1], + dai_data->port_config.pcm.slot_number_mapping[2], + dai_data->port_config.pcm.slot_number_mapping[3]); + + mutex_unlock(&aux_dai_data->rlock); + return rc; +} + +static int msm_dai_q6_auxpcm_set_clk( + struct msm_dai_q6_auxpcm_dai_data *aux_dai_data, + u16 port_id, bool enable) +{ + int rc; + + pr_debug("%s: afe_clk_ver: %d, port_id: %d, enable: %d\n", __func__, + aux_dai_data->afe_clk_ver, port_id, enable); + if (aux_dai_data->afe_clk_ver == AFE_CLK_VERSION_V2) { + aux_dai_data->clk_set.enable = enable; + rc = afe_set_lpass_clock_v2(port_id, + &aux_dai_data->clk_set); + } else { + if (!enable) + aux_dai_data->clk_cfg.clk_val1 = 0; + rc = afe_set_lpass_clock(port_id, + &aux_dai_data->clk_cfg); + } + return rc; +} + +static void msm_dai_q6_auxpcm_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + int rc = 0; + struct msm_dai_q6_auxpcm_dai_data *aux_dai_data = + dev_get_drvdata(dai->dev); + + mutex_lock(&aux_dai_data->rlock); + + if (!(test_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status) || + test_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status))) { + dev_dbg(dai->dev, "%s(): dai->id %d PCM ports already closed\n", + __func__, dai->id); + goto exit; + } + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (test_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status)) + clear_bit(STATUS_TX_PORT, + aux_dai_data->auxpcm_port_status); + else { + dev_dbg(dai->dev, "%s: PCM_TX port already closed\n", + __func__); + goto exit; + } + } else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + if (test_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status)) + clear_bit(STATUS_RX_PORT, + aux_dai_data->auxpcm_port_status); + else { + dev_dbg(dai->dev, "%s: PCM_RX port already closed\n", + __func__); + goto exit; + } + } + if (test_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status) || + test_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status)) { + dev_dbg(dai->dev, "%s: cannot shutdown PCM ports\n", + __func__); + goto exit; + } + + dev_dbg(dai->dev, "%s: dai->id = %d closing PCM AFE ports\n", + __func__, dai->id); + + rc = afe_close(aux_dai_data->rx_pid); /* can block */ + if (rc < 0) + dev_err(dai->dev, "fail to close PCM_RX AFE port\n"); + + rc = afe_close(aux_dai_data->tx_pid); + if (rc < 0) + dev_err(dai->dev, "fail to close AUX PCM TX port\n"); + + msm_dai_q6_auxpcm_set_clk(aux_dai_data, aux_dai_data->rx_pid, false); + msm_dai_q6_auxpcm_set_clk(aux_dai_data, aux_dai_data->tx_pid, false); +exit: + mutex_unlock(&aux_dai_data->rlock); +} + +static int msm_dai_q6_auxpcm_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_auxpcm_dai_data *aux_dai_data = + dev_get_drvdata(dai->dev); + struct msm_dai_q6_dai_data *dai_data = &aux_dai_data->bdai_data; + struct msm_dai_auxpcm_pdata *auxpcm_pdata = NULL; + int rc = 0; + u32 pcm_clk_rate; + + auxpcm_pdata = dai->dev->platform_data; + mutex_lock(&aux_dai_data->rlock); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (test_bit(STATUS_TX_PORT, + aux_dai_data->auxpcm_port_status)) { + dev_dbg(dai->dev, "%s: PCM_TX port already ON\n", + __func__); + goto exit; + } else + set_bit(STATUS_TX_PORT, + aux_dai_data->auxpcm_port_status); + } else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + if (test_bit(STATUS_RX_PORT, + aux_dai_data->auxpcm_port_status)) { + dev_dbg(dai->dev, "%s: PCM_RX port already ON\n", + __func__); + goto exit; + } else + set_bit(STATUS_RX_PORT, + aux_dai_data->auxpcm_port_status); + } + if (test_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status) && + test_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status)) { + dev_dbg(dai->dev, "%s: PCM ports already set\n", __func__); + goto exit; + } + + dev_dbg(dai->dev, "%s: dai->id:%d opening afe ports\n", + __func__, dai->id); + + rc = afe_q6_interface_prepare(); + if (rc < 0) { + dev_err(dai->dev, "fail to open AFE APR\n"); + goto fail; + } + + /* + * For AUX PCM Interface the below sequence of clk + * settings and afe_open is a strict requirement. + * + * Also using afe_open instead of afe_port_start_nowait + * to make sure the port is open before deasserting the + * clock line. This is required because pcm register is + * not written before clock deassert. Hence the hw does + * not get updated with new setting if the below clock + * assert/deasset and afe_open sequence is not followed. + */ + + if (dai_data->rate == 8000) { + pcm_clk_rate = auxpcm_pdata->mode_8k.pcm_clk_rate; + } else if (dai_data->rate == 16000) { + pcm_clk_rate = (auxpcm_pdata->mode_16k.pcm_clk_rate); + } else { + dev_err(dai->dev, "%s: Invalid AUX PCM rate %d\n", __func__, + dai_data->rate); + rc = -EINVAL; + goto fail; + } + if (aux_dai_data->afe_clk_ver == AFE_CLK_VERSION_V2) { + memcpy(&aux_dai_data->clk_set, &lpass_clk_set_default, + sizeof(struct afe_clk_set)); + aux_dai_data->clk_set.clk_freq_in_hz = pcm_clk_rate; + + switch (dai->id) { + case MSM_DAI_PRI_AUXPCM_DT_DEV_ID: + if (pcm_clk_rate) + aux_dai_data->clk_set.clk_id = + Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT; + else + aux_dai_data->clk_set.clk_id = + Q6AFE_LPASS_CLK_ID_PRI_PCM_EBIT; + break; + case MSM_DAI_SEC_AUXPCM_DT_DEV_ID: + if (pcm_clk_rate) + aux_dai_data->clk_set.clk_id = + Q6AFE_LPASS_CLK_ID_SEC_PCM_IBIT; + else + aux_dai_data->clk_set.clk_id = + Q6AFE_LPASS_CLK_ID_SEC_PCM_EBIT; + break; + case MSM_DAI_TERT_AUXPCM_DT_DEV_ID: + if (pcm_clk_rate) + aux_dai_data->clk_set.clk_id = + Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT; + else + aux_dai_data->clk_set.clk_id = + Q6AFE_LPASS_CLK_ID_TER_PCM_EBIT; + break; + case MSM_DAI_QUAT_AUXPCM_DT_DEV_ID: + if (pcm_clk_rate) + aux_dai_data->clk_set.clk_id = + Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT; + else + aux_dai_data->clk_set.clk_id = + Q6AFE_LPASS_CLK_ID_QUAD_PCM_EBIT; + break; + default: + dev_err(dai->dev, "%s: AUXPCM id: %d not supported\n", + __func__, dai->id); + break; + } + } else { + memcpy(&aux_dai_data->clk_cfg, &lpass_clk_cfg_default, + sizeof(struct afe_clk_cfg)); + aux_dai_data->clk_cfg.clk_val1 = pcm_clk_rate; + } + + rc = msm_dai_q6_auxpcm_set_clk(aux_dai_data, + aux_dai_data->rx_pid, true); + if (rc < 0) { + dev_err(dai->dev, + "%s:afe_set_lpass_clock on RX pcm_src_clk failed\n", + __func__); + goto fail; + } + + rc = msm_dai_q6_auxpcm_set_clk(aux_dai_data, + aux_dai_data->tx_pid, true); + if (rc < 0) { + dev_err(dai->dev, + "%s:afe_set_lpass_clock on TX pcm_src_clk failed\n", + __func__); + goto fail; + } + + afe_open(aux_dai_data->rx_pid, &dai_data->port_config, dai_data->rate); + afe_open(aux_dai_data->tx_pid, &dai_data->port_config, dai_data->rate); + goto exit; + +fail: + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + clear_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status); + else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + clear_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status); + +exit: + mutex_unlock(&aux_dai_data->rlock); + return rc; +} + +static int msm_dai_q6_auxpcm_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + int rc = 0; + + pr_debug("%s:port:%d cmd:%d\n", + __func__, dai->id, cmd); + + switch (cmd) { + + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + /* afe_open will be called from prepare */ + return 0; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + return 0; + + default: + pr_err("%s: cmd %d\n", __func__, cmd); + rc = -EINVAL; + } + + return rc; + +} + +static int msm_dai_q6_dai_auxpcm_remove(struct snd_soc_dai *dai) +{ + struct msm_dai_q6_auxpcm_dai_data *aux_dai_data; + int rc; + + aux_dai_data = dev_get_drvdata(dai->dev); + + dev_dbg(dai->dev, "%s: dai->id %d closing afe\n", + __func__, dai->id); + + if (test_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status) || + test_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status)) { + rc = afe_close(aux_dai_data->rx_pid); /* can block */ + if (rc < 0) + dev_err(dai->dev, "fail to close AUXPCM RX AFE port\n"); + rc = afe_close(aux_dai_data->tx_pid); + if (rc < 0) + dev_err(dai->dev, "fail to close AUXPCM TX AFE port\n"); + clear_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status); + clear_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status); + } + msm_dai_q6_auxpcm_set_clk(aux_dai_data, aux_dai_data->rx_pid, false); + msm_dai_q6_auxpcm_set_clk(aux_dai_data, aux_dai_data->tx_pid, false); + return 0; +} + +static int msm_dai_q6_aux_pcm_probe(struct snd_soc_dai *dai) +{ + int rc = 0; + + if (!dai) { + pr_err("%s: Invalid params dai\n", __func__); + return -EINVAL; + } + if (!dai->dev) { + pr_err("%s: Invalid params dai dev\n", __func__); + return -EINVAL; + } + if (!dai->driver->id) { + dev_warn(dai->dev, "DAI driver id is not set\n"); + return -EINVAL; + } + dai->id = dai->driver->id; + rc = msm_dai_q6_dai_add_route(dai); + return rc; +} + +static struct snd_soc_dai_ops msm_dai_q6_auxpcm_ops = { + .prepare = msm_dai_q6_auxpcm_prepare, + .trigger = msm_dai_q6_auxpcm_trigger, + .hw_params = msm_dai_q6_auxpcm_hw_params, + .shutdown = msm_dai_q6_auxpcm_shutdown, +}; + +static const struct snd_soc_component_driver + msm_dai_q6_aux_pcm_dai_component = { + .name = "msm-auxpcm-dev", +}; + +static struct snd_soc_dai_driver msm_dai_q6_aux_pcm_dai[] = { + { + .playback = { + .stream_name = "AUX PCM Playback", + .aif_name = "AUX_PCM_RX", + .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_max = 16000, + .rate_min = 8000, + }, + .capture = { + .stream_name = "AUX PCM Capture", + .aif_name = "AUX_PCM_TX", + .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_max = 16000, + .rate_min = 8000, + }, + .id = MSM_DAI_PRI_AUXPCM_DT_DEV_ID, + .ops = &msm_dai_q6_auxpcm_ops, + .probe = msm_dai_q6_aux_pcm_probe, + .remove = msm_dai_q6_dai_auxpcm_remove, + }, + { + .playback = { + .stream_name = "Sec AUX PCM Playback", + .aif_name = "SEC_AUX_PCM_RX", + .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_max = 16000, + .rate_min = 8000, + }, + .capture = { + .stream_name = "Sec AUX PCM Capture", + .aif_name = "SEC_AUX_PCM_TX", + .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_max = 16000, + .rate_min = 8000, + }, + .id = MSM_DAI_SEC_AUXPCM_DT_DEV_ID, + .ops = &msm_dai_q6_auxpcm_ops, + .probe = msm_dai_q6_aux_pcm_probe, + .remove = msm_dai_q6_dai_auxpcm_remove, + }, + { + .playback = { + .stream_name = "Tert AUX PCM Playback", + .aif_name = "TERT_AUX_PCM_RX", + .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_max = 16000, + .rate_min = 8000, + }, + .capture = { + .stream_name = "Tert AUX PCM Capture", + .aif_name = "TERT_AUX_PCM_TX", + .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_max = 16000, + .rate_min = 8000, + }, + .id = MSM_DAI_TERT_AUXPCM_DT_DEV_ID, + .ops = &msm_dai_q6_auxpcm_ops, + .probe = msm_dai_q6_aux_pcm_probe, + .remove = msm_dai_q6_dai_auxpcm_remove, + }, + { + .playback = { + .stream_name = "Quat AUX PCM Playback", + .aif_name = "QUAT_AUX_PCM_RX", + .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_max = 16000, + .rate_min = 8000, + }, + .capture = { + .stream_name = "Quat AUX PCM Capture", + .aif_name = "QUAT_AUX_PCM_TX", + .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_max = 16000, + .rate_min = 8000, + }, + .id = MSM_DAI_QUAT_AUXPCM_DT_DEV_ID, + .ops = &msm_dai_q6_auxpcm_ops, + .probe = msm_dai_q6_aux_pcm_probe, + .remove = msm_dai_q6_dai_auxpcm_remove, + }, +}; + +static int msm_dai_q6_spdif_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; + int value = ucontrol->value.integer.value[0]; + + dai_data->spdif_port.cfg.data_format = value; + pr_debug("%s: value = %d\n", __func__, value); + return 0; +} + +static int msm_dai_q6_spdif_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; + + ucontrol->value.integer.value[0] = + dai_data->spdif_port.cfg.data_format; + return 0; +} + +static const char * const spdif_format[] = { + "LPCM", + "Compr" +}; + +static const struct soc_enum spdif_config_enum[] = { + SOC_ENUM_SINGLE_EXT(2, spdif_format), +}; + +static int msm_dai_q6_spdif_chstatus_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; + int ret = 0; + + dai_data->spdif_port.ch_status.status_type = + AFE_API_VERSION_SPDIF_CH_STATUS_CONFIG; + memset(dai_data->spdif_port.ch_status.status_mask, + CHANNEL_STATUS_MASK_INIT, CHANNEL_STATUS_SIZE); + dai_data->spdif_port.ch_status.status_mask[0] = + CHANNEL_STATUS_MASK; + + memcpy(dai_data->spdif_port.ch_status.status_bits, + ucontrol->value.iec958.status, CHANNEL_STATUS_SIZE); + + if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + pr_debug("%s: Port already started. Dynamic update\n", + __func__); + ret = afe_send_spdif_ch_status_cfg( + &dai_data->spdif_port.ch_status, + AFE_PORT_ID_SPDIF_RX); + } + return ret; +} + +static int msm_dai_q6_spdif_chstatus_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; + + memcpy(ucontrol->value.iec958.status, + dai_data->spdif_port.ch_status.status_bits, + CHANNEL_STATUS_SIZE); + return 0; +} + +static int msm_dai_q6_spdif_chstatus_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; + uinfo->count = 1; + return 0; +} + +static const struct snd_kcontrol_new spdif_config_controls[] = { + { + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_INACTIVE), + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM), + .info = msm_dai_q6_spdif_chstatus_info, + .get = msm_dai_q6_spdif_chstatus_get, + .put = msm_dai_q6_spdif_chstatus_put, + }, + SOC_ENUM_EXT("SPDIF RX Format", spdif_config_enum[0], + msm_dai_q6_spdif_format_get, + msm_dai_q6_spdif_format_put) +}; + + +static int msm_dai_q6_spdif_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dai->dev); + + dai->id = AFE_PORT_ID_SPDIF_RX; + dai_data->channels = params_channels(params); + dai_data->spdif_port.cfg.num_channels = dai_data->channels; + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + dai_data->spdif_port.cfg.bit_width = 16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + dai_data->spdif_port.cfg.bit_width = 24; + break; + default: + pr_err("%s: format %d\n", + __func__, params_format(params)); + return -EINVAL; + } + + dai_data->rate = params_rate(params); + dai_data->bitwidth = dai_data->spdif_port.cfg.bit_width; + dai_data->spdif_port.cfg.sample_rate = dai_data->rate; + dai_data->spdif_port.cfg.spdif_cfg_minor_version = + AFE_API_VERSION_SPDIF_CONFIG; + dev_dbg(dai->dev, " channel %d sample rate %d bit width %d\n", + dai_data->channels, dai_data->rate, + dai_data->spdif_port.cfg.bit_width); + dai_data->spdif_port.cfg.reserved = 0; + return 0; +} + +static void msm_dai_q6_spdif_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dai->dev); + int rc = 0; + + if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + pr_info("%s: afe port not started. dai_data->status_mask = %ld\n", + __func__, *dai_data->status_mask); + return; + } + + rc = afe_close(dai->id); + if (rc < 0) + dev_err(dai->dev, "fail to close AFE port\n"); + + pr_debug("%s: dai_data->status_mask = %ld\n", __func__, + *dai_data->status_mask); + + clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); +} + + +static int msm_dai_q6_spdif_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dai->dev); + int rc = 0; + + if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + rc = afe_spdif_port_start(dai->id, &dai_data->spdif_port, + dai_data->rate); + if (rc < 0) + dev_err(dai->dev, "fail to open AFE port 0x%x\n", + dai->id); + else + set_bit(STATUS_PORT_STARTED, + dai_data->status_mask); + } + + return rc; +} + +static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai) +{ + struct msm_dai_q6_spdif_dai_data *dai_data; + const struct snd_kcontrol_new *kcontrol; + int rc = 0; + struct snd_soc_dapm_route intercon; + struct snd_soc_dapm_context *dapm; + + if (!dai) { + pr_err("%s: dai not found!!\n", __func__); + return -EINVAL; + } + dai_data = kzalloc(sizeof(struct msm_dai_q6_spdif_dai_data), + GFP_KERNEL); + + if (!dai_data) { + dev_err(dai->dev, "DAI-%d: fail to allocate dai data\n", + AFE_PORT_ID_SPDIF_RX); + rc = -ENOMEM; + } else + dev_set_drvdata(dai->dev, dai_data); + + kcontrol = &spdif_config_controls[1]; + dapm = snd_soc_component_get_dapm(dai->component); + + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(kcontrol, dai_data)); + + memset(&intercon, 0, sizeof(intercon)); + if (!rc && dai && dai->driver) { + if (dai->driver->playback.stream_name && + dai->driver->playback.aif_name) { + dev_dbg(dai->dev, "%s: add route for widget %s", + __func__, dai->driver->playback.stream_name); + intercon.source = dai->driver->playback.aif_name; + intercon.sink = dai->driver->playback.stream_name; + dev_dbg(dai->dev, "%s: src %s sink %s\n", + __func__, intercon.source, intercon.sink); + snd_soc_dapm_add_routes(dapm, &intercon, 1); + } + if (dai->driver->capture.stream_name && + dai->driver->capture.aif_name) { + dev_dbg(dai->dev, "%s: add route for widget %s", + __func__, dai->driver->capture.stream_name); + intercon.sink = dai->driver->capture.aif_name; + intercon.source = dai->driver->capture.stream_name; + dev_dbg(dai->dev, "%s: src %s sink %s\n", + __func__, intercon.source, intercon.sink); + snd_soc_dapm_add_routes(dapm, &intercon, 1); + } + } + return rc; +} + +static int msm_dai_q6_spdif_dai_remove(struct snd_soc_dai *dai) +{ + struct msm_dai_q6_spdif_dai_data *dai_data; + int rc; + + dai_data = dev_get_drvdata(dai->dev); + + /* If AFE port is still up, close it */ + if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + rc = afe_close(dai->id); /* can block */ + if (rc < 0) + dev_err(dai->dev, "fail to close AFE port\n"); + + clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); + } + kfree(dai_data); + + return 0; +} + + +static struct snd_soc_dai_ops msm_dai_q6_spdif_ops = { + .prepare = msm_dai_q6_spdif_prepare, + .hw_params = msm_dai_q6_spdif_hw_params, + .shutdown = msm_dai_q6_spdif_shutdown, +}; + +static struct snd_soc_dai_driver msm_dai_q6_spdif_spdif_rx_dai = { + .playback = { + .stream_name = "SPDIF Playback", + .aif_name = "SPDIF_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 1, + .channels_max = 4, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_spdif_ops, + .probe = msm_dai_q6_spdif_dai_probe, + .remove = msm_dai_q6_spdif_dai_remove, +}; + +static const struct snd_soc_component_driver msm_dai_spdif_q6_component = { + .name = "msm-dai-q6-spdif", +}; + +static int msm_dai_q6_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + int rc = 0; + + if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + if (dai_data->enc_config.format != ENC_FMT_NONE) { + int bitwidth = 0; + + if (dai_data->afe_in_bitformat == + SNDRV_PCM_FORMAT_S24_LE) + bitwidth = 24; + else if (dai_data->afe_in_bitformat == + SNDRV_PCM_FORMAT_S16_LE) + bitwidth = 16; + pr_debug("%s: calling AFE_PORT_START_V2 with enc_format: %d\n", + __func__, dai_data->enc_config.format); + rc = afe_port_start_v2(dai->id, &dai_data->port_config, + dai_data->rate, + dai_data->afe_in_channels, + bitwidth, + &dai_data->enc_config); + if (rc < 0) + pr_err("%s: afe_port_start_v2 failed error: %d\n", + __func__, rc); + } else { + rc = afe_port_start(dai->id, &dai_data->port_config, + dai_data->rate); + } + if (rc < 0) + dev_err(dai->dev, "fail to open AFE port 0x%x\n", + dai->id); + else + set_bit(STATUS_PORT_STARTED, + dai_data->status_mask); + } + return rc; +} + +static int msm_dai_q6_cdc_hw_params(struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai, int stream) +{ + struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + + dai_data->channels = params_channels(params); + switch (dai_data->channels) { + case 2: + dai_data->port_config.i2s.mono_stereo = MSM_AFE_STEREO; + break; + case 1: + dai_data->port_config.i2s.mono_stereo = MSM_AFE_MONO; + break; + default: + return -EINVAL; + pr_err("%s: err channels %d\n", + __func__, dai_data->channels); + break; + } + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + case SNDRV_PCM_FORMAT_SPECIAL: + dai_data->port_config.i2s.bit_width = 16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + dai_data->port_config.i2s.bit_width = 24; + break; + default: + pr_err("%s: format %d\n", + __func__, params_format(params)); + return -EINVAL; + } + + dai_data->rate = params_rate(params); + dai_data->port_config.i2s.sample_rate = dai_data->rate; + dai_data->port_config.i2s.i2s_cfg_minor_version = + AFE_API_VERSION_I2S_CONFIG; + dai_data->port_config.i2s.data_format = AFE_LINEAR_PCM_DATA; + dev_dbg(dai->dev, " channel %d sample rate %d entered\n", + dai_data->channels, dai_data->rate); + + dai_data->port_config.i2s.channel_mode = 1; + return 0; +} + +static u8 num_of_bits_set(u8 sd_line_mask) +{ + u8 num_bits_set = 0; + + while (sd_line_mask) { + num_bits_set++; + sd_line_mask = sd_line_mask & (sd_line_mask - 1); + } + return num_bits_set; +} + +static int msm_dai_q6_i2s_hw_params(struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai, int stream) +{ + struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + struct msm_i2s_data *i2s_pdata = + (struct msm_i2s_data *) dai->dev->platform_data; + + dai_data->channels = params_channels(params); + if (num_of_bits_set(i2s_pdata->sd_lines) == 1) { + switch (dai_data->channels) { + case 2: + dai_data->port_config.i2s.mono_stereo = MSM_AFE_STEREO; + break; + case 1: + dai_data->port_config.i2s.mono_stereo = MSM_AFE_MONO; + break; + default: + pr_warn("%s: greater than stereo has not been validated %d", + __func__, dai_data->channels); + break; + } + } + dai_data->rate = params_rate(params); + dai_data->port_config.i2s.sample_rate = dai_data->rate; + dai_data->port_config.i2s.i2s_cfg_minor_version = + AFE_API_VERSION_I2S_CONFIG; + dai_data->port_config.i2s.data_format = AFE_LINEAR_PCM_DATA; + /* Q6 only supports 16 as now */ + dai_data->port_config.i2s.bit_width = 16; + dai_data->port_config.i2s.channel_mode = 1; + + return 0; +} + +static int msm_dai_q6_slim_bus_hw_params(struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai, int stream) +{ + struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + + dai_data->channels = params_channels(params); + dai_data->rate = params_rate(params); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + case SNDRV_PCM_FORMAT_SPECIAL: + dai_data->port_config.slim_sch.bit_width = 16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + dai_data->port_config.slim_sch.bit_width = 24; + break; + case SNDRV_PCM_FORMAT_S32_LE: + dai_data->port_config.slim_sch.bit_width = 32; + break; + default: + pr_err("%s: format %d\n", + __func__, params_format(params)); + return -EINVAL; + } + + dai_data->port_config.slim_sch.sb_cfg_minor_version = + AFE_API_VERSION_SLIMBUS_CONFIG; + dai_data->port_config.slim_sch.sample_rate = dai_data->rate; + dai_data->port_config.slim_sch.num_channels = dai_data->channels; + + switch (dai->id) { + case SLIMBUS_7_RX: + case SLIMBUS_7_TX: + case SLIMBUS_8_RX: + case SLIMBUS_8_TX: + dai_data->port_config.slim_sch.slimbus_dev_id = + AFE_SLIMBUS_DEVICE_2; + break; + default: + dai_data->port_config.slim_sch.slimbus_dev_id = + AFE_SLIMBUS_DEVICE_1; + break; + } + + dev_dbg(dai->dev, "%s:slimbus_dev_id[%hu] bit_wd[%hu] format[%hu]\n" + "num_channel %hu shared_ch_mapping[0] %hu\n" + "slave_port_mapping[1] %hu slave_port_mapping[2] %hu\n" + "sample_rate %d\n", __func__, + dai_data->port_config.slim_sch.slimbus_dev_id, + dai_data->port_config.slim_sch.bit_width, + dai_data->port_config.slim_sch.data_format, + dai_data->port_config.slim_sch.num_channels, + dai_data->port_config.slim_sch.shared_ch_mapping[0], + dai_data->port_config.slim_sch.shared_ch_mapping[1], + dai_data->port_config.slim_sch.shared_ch_mapping[2], + dai_data->rate); + + return 0; +} + +static int msm_dai_q6_usb_audio_hw_params(struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai, int stream) +{ + struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + + dai_data->channels = params_channels(params); + dai_data->rate = params_rate(params); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + case SNDRV_PCM_FORMAT_SPECIAL: + dai_data->port_config.usb_audio.bit_width = 16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + dai_data->port_config.usb_audio.bit_width = 24; + break; + case SNDRV_PCM_FORMAT_S32_LE: + dai_data->port_config.usb_audio.bit_width = 32; + break; + + default: + dev_err(dai->dev, "%s: invalid format %d\n", + __func__, params_format(params)); + return -EINVAL; + } + dai_data->port_config.usb_audio.cfg_minor_version = + AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG; + dai_data->port_config.usb_audio.num_channels = dai_data->channels; + dai_data->port_config.usb_audio.sample_rate = dai_data->rate; + + dev_dbg(dai->dev, "%s: dev_id[0x%x] bit_wd[%hu] format[%hu]\n" + "num_channel %hu sample_rate %d\n", __func__, + dai_data->port_config.usb_audio.dev_token, + dai_data->port_config.usb_audio.bit_width, + dai_data->port_config.usb_audio.data_format, + dai_data->port_config.usb_audio.num_channels, + dai_data->port_config.usb_audio.sample_rate); + + return 0; +} + +static int msm_dai_q6_bt_fm_hw_params(struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai, int stream) +{ + struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + + dai_data->channels = params_channels(params); + dai_data->rate = params_rate(params); + + dev_dbg(dai->dev, "channels %d sample rate %d entered\n", + dai_data->channels, dai_data->rate); + + memset(&dai_data->port_config, 0, sizeof(dai_data->port_config)); + + pr_debug("%s: setting bt_fm parameters\n", __func__); + + dai_data->port_config.int_bt_fm.bt_fm_cfg_minor_version = + AFE_API_VERSION_INTERNAL_BT_FM_CONFIG; + dai_data->port_config.int_bt_fm.num_channels = dai_data->channels; + dai_data->port_config.int_bt_fm.sample_rate = dai_data->rate; + dai_data->port_config.int_bt_fm.bit_width = 16; + + return 0; +} + +static int msm_dai_q6_afe_rtproxy_hw_params(struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + + dai_data->rate = params_rate(params); + dai_data->port_config.rtproxy.num_channels = params_channels(params); + dai_data->port_config.rtproxy.sample_rate = params_rate(params); + + pr_debug("channel %d entered,dai_id: %d,rate: %d\n", + dai_data->port_config.rtproxy.num_channels, dai->id, dai_data->rate); + + dai_data->port_config.rtproxy.rt_proxy_cfg_minor_version = + AFE_API_VERSION_RT_PROXY_CONFIG; + dai_data->port_config.rtproxy.bit_width = 16; /* Q6 only supports 16 */ + dai_data->port_config.rtproxy.interleaved = 1; + dai_data->port_config.rtproxy.frame_size = params_period_bytes(params); + dai_data->port_config.rtproxy.jitter_allowance = + dai_data->port_config.rtproxy.frame_size/2; + dai_data->port_config.rtproxy.low_water_mark = 0; + dai_data->port_config.rtproxy.high_water_mark = 0; + + return 0; +} + +static int msm_dai_q6_pseudo_port_hw_params(struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai, int stream) +{ + struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + + dai_data->channels = params_channels(params); + dai_data->rate = params_rate(params); + + /* Q6 only supports 16 as now */ + dai_data->port_config.pseudo_port.pseud_port_cfg_minor_version = + AFE_API_VERSION_PSEUDO_PORT_CONFIG; + dai_data->port_config.pseudo_port.num_channels = + params_channels(params); + dai_data->port_config.pseudo_port.bit_width = 16; + dai_data->port_config.pseudo_port.data_format = 0; + dai_data->port_config.pseudo_port.timing_mode = + AFE_PSEUDOPORT_TIMING_MODE_TIMER; + dai_data->port_config.pseudo_port.sample_rate = params_rate(params); + + dev_dbg(dai->dev, "%s: bit_wd[%hu] num_channels [%hu] format[%hu]\n" + "timing Mode %hu sample_rate %d\n", __func__, + dai_data->port_config.pseudo_port.bit_width, + dai_data->port_config.pseudo_port.num_channels, + dai_data->port_config.pseudo_port.data_format, + dai_data->port_config.pseudo_port.timing_mode, + dai_data->port_config.pseudo_port.sample_rate); + + return 0; +} + +/* Current implementation assumes hw_param is called once + * This may not be the case but what to do when ADM and AFE + * port are already opened and parameter changes + */ +static int msm_dai_q6_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + int rc = 0; + + switch (dai->id) { + case PRIMARY_I2S_TX: + case PRIMARY_I2S_RX: + case SECONDARY_I2S_RX: + rc = msm_dai_q6_cdc_hw_params(params, dai, substream->stream); + break; + case MI2S_RX: + rc = msm_dai_q6_i2s_hw_params(params, dai, substream->stream); + break; + case SLIMBUS_0_RX: + case SLIMBUS_1_RX: + case SLIMBUS_2_RX: + case SLIMBUS_3_RX: + case SLIMBUS_4_RX: + case SLIMBUS_5_RX: + case SLIMBUS_6_RX: + case SLIMBUS_7_RX: + case SLIMBUS_8_RX: + case SLIMBUS_0_TX: + case SLIMBUS_1_TX: + case SLIMBUS_2_TX: + case SLIMBUS_3_TX: + case SLIMBUS_4_TX: + case SLIMBUS_5_TX: + case SLIMBUS_6_TX: + case SLIMBUS_7_TX: + case SLIMBUS_8_TX: + rc = msm_dai_q6_slim_bus_hw_params(params, dai, + substream->stream); + break; + case INT_BT_SCO_RX: + case INT_BT_SCO_TX: + case INT_BT_A2DP_RX: + case INT_FM_RX: + case INT_FM_TX: + rc = msm_dai_q6_bt_fm_hw_params(params, dai, substream->stream); + break; + case AFE_PORT_ID_USB_RX: + case AFE_PORT_ID_USB_TX: + rc = msm_dai_q6_usb_audio_hw_params(params, dai, + substream->stream); + break; + case RT_PROXY_DAI_001_TX: + case RT_PROXY_DAI_001_RX: + case RT_PROXY_DAI_002_TX: + case RT_PROXY_DAI_002_RX: + rc = msm_dai_q6_afe_rtproxy_hw_params(params, dai); + break; + case VOICE_PLAYBACK_TX: + case VOICE2_PLAYBACK_TX: + case VOICE_RECORD_RX: + case VOICE_RECORD_TX: + rc = msm_dai_q6_pseudo_port_hw_params(params, + dai, substream->stream); + break; + default: + dev_err(dai->dev, "invalid AFE port ID 0x%x\n", dai->id); + rc = -EINVAL; + break; + } + + return rc; +} + +static void msm_dai_q6_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + int rc = 0; + + if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + pr_debug("%s: stop pseudo port:%d\n", __func__, dai->id); + rc = afe_close(dai->id); /* can block */ + if (rc < 0) + dev_err(dai->dev, "fail to close AFE port\n"); + pr_debug("%s: dai_data->status_mask = %ld\n", __func__, + *dai_data->status_mask); + clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); + } +} + +static int msm_dai_q6_cdc_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + dai_data->port_config.i2s.ws_src = 1; /* CPU is master */ + break; + case SND_SOC_DAIFMT_CBM_CFM: + dai_data->port_config.i2s.ws_src = 0; /* CPU is slave */ + break; + default: + pr_err("%s: fmt 0x%x\n", + __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK); + return -EINVAL; + } + + return 0; +} + +static int msm_dai_q6_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + int rc = 0; + + dev_dbg(dai->dev, "%s: id = %d fmt[%d]\n", __func__, + dai->id, fmt); + switch (dai->id) { + case PRIMARY_I2S_TX: + case PRIMARY_I2S_RX: + case MI2S_RX: + case SECONDARY_I2S_RX: + rc = msm_dai_q6_cdc_set_fmt(dai, fmt); + break; + default: + dev_err(dai->dev, "invalid cpu_dai id 0x%x\n", dai->id); + rc = -EINVAL; + break; + } + + return rc; +} + +static int msm_dai_q6_set_channel_map(struct snd_soc_dai *dai, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot) + +{ + int rc = 0; + struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + unsigned int i = 0; + + dev_dbg(dai->dev, "%s: id = %d\n", __func__, dai->id); + switch (dai->id) { + case SLIMBUS_0_RX: + case SLIMBUS_1_RX: + case SLIMBUS_2_RX: + case SLIMBUS_3_RX: + case SLIMBUS_4_RX: + case SLIMBUS_5_RX: + case SLIMBUS_6_RX: + case SLIMBUS_7_RX: + case SLIMBUS_8_RX: + /* + * channel number to be between 128 and 255. + * For RX port use channel numbers + * from 138 to 144 for pre-Taiko + * from 144 to 159 for Taiko + */ + if (!rx_slot) { + pr_err("%s: rx slot not found\n", __func__); + return -EINVAL; + } + if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) { + pr_err("%s: invalid rx num %d\n", __func__, rx_num); + return -EINVAL; + } + + for (i = 0; i < rx_num; i++) { + dai_data->port_config.slim_sch.shared_ch_mapping[i] = + rx_slot[i]; + pr_debug("%s: find number of channels[%d] ch[%d]\n", + __func__, i, rx_slot[i]); + } + dai_data->port_config.slim_sch.num_channels = rx_num; + pr_debug("%s: SLIMBUS_%d_RX cnt[%d] ch[%d %d]\n", __func__, + (dai->id - SLIMBUS_0_RX) / 2, rx_num, + dai_data->port_config.slim_sch.shared_ch_mapping[0], + dai_data->port_config.slim_sch.shared_ch_mapping[1]); + + break; + case SLIMBUS_0_TX: + case SLIMBUS_1_TX: + case SLIMBUS_2_TX: + case SLIMBUS_3_TX: + case SLIMBUS_4_TX: + case SLIMBUS_5_TX: + case SLIMBUS_6_TX: + case SLIMBUS_7_TX: + case SLIMBUS_8_TX: + /* + * channel number to be between 128 and 255. + * For TX port use channel numbers + * from 128 to 137 for pre-Taiko + * from 128 to 143 for Taiko + */ + if (!tx_slot) { + pr_err("%s: tx slot not found\n", __func__); + return -EINVAL; + } + if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) { + pr_err("%s: invalid tx num %d\n", __func__, tx_num); + return -EINVAL; + } + + for (i = 0; i < tx_num; i++) { + dai_data->port_config.slim_sch.shared_ch_mapping[i] = + tx_slot[i]; + pr_debug("%s: find number of channels[%d] ch[%d]\n", + __func__, i, tx_slot[i]); + } + dai_data->port_config.slim_sch.num_channels = tx_num; + pr_debug("%s:SLIMBUS_%d_TX cnt[%d] ch[%d %d]\n", __func__, + (dai->id - SLIMBUS_0_TX) / 2, tx_num, + dai_data->port_config.slim_sch.shared_ch_mapping[0], + dai_data->port_config.slim_sch.shared_ch_mapping[1]); + break; + default: + dev_err(dai->dev, "invalid cpu_dai id 0x%x\n", dai->id); + rc = -EINVAL; + break; + } + return rc; +} + +static struct snd_soc_dai_ops msm_dai_q6_ops = { + .prepare = msm_dai_q6_prepare, + .hw_params = msm_dai_q6_hw_params, + .shutdown = msm_dai_q6_shutdown, + .set_fmt = msm_dai_q6_set_fmt, + .set_channel_map = msm_dai_q6_set_channel_map, +}; + +/* + * For single CPU DAI registration, the dai id needs to be + * set explicitly in the dai probe as ASoC does not read + * the cpu->driver->id field rather it assigns the dai id + * from the device name that is in the form %s.%d. This dai + * id should be assigned to back-end AFE port id and used + * during dai prepare. For multiple dai registration, it + * is not required to call this function, however the dai-> + * driver->id field must be defined and set to corresponding + * AFE Port id. + */ +static inline void msm_dai_q6_set_dai_id(struct snd_soc_dai *dai) +{ + if (!dai->driver->id) { + dev_warn(dai->dev, "DAI driver id is not set\n"); + return; + } + dai->id = dai->driver->id; +} + +static int msm_dai_q6_cal_info_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + u16 port_id = ((struct soc_enum *) + kcontrol->private_value)->reg; + + dai_data->cal_mode = ucontrol->value.integer.value[0]; + pr_debug("%s: setting cal_mode to %d\n", + __func__, dai_data->cal_mode); + afe_set_cal_mode(port_id, dai_data->cal_mode); + + return 0; +} + +static int msm_dai_q6_cal_info_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + ucontrol->value.integer.value[0] = dai_data->cal_mode; + return 0; +} + +static int msm_dai_q6_sb_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + int value = ucontrol->value.integer.value[0]; + + if (dai_data) { + dai_data->port_config.slim_sch.data_format = value; + pr_debug("%s: format = %d\n", __func__, value); + } + + return 0; +} + +static int msm_dai_q6_sb_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (dai_data) + ucontrol->value.integer.value[0] = + dai_data->port_config.slim_sch.data_format; + + return 0; +} + +static int msm_dai_q6_usb_audio_cfg_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + u32 val = ucontrol->value.integer.value[0]; + + if (dai_data) { + dai_data->port_config.usb_audio.dev_token = val; + pr_debug("%s: dev_token = 0x%x\n", __func__, + dai_data->port_config.usb_audio.dev_token); + } else { + pr_err("%s: dai_data is NULL\n", __func__); + } + + return 0; +} + +static int msm_dai_q6_usb_audio_cfg_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (dai_data) { + ucontrol->value.integer.value[0] = + dai_data->port_config.usb_audio.dev_token; + pr_debug("%s: dev_token = 0x%x\n", __func__, + dai_data->port_config.usb_audio.dev_token); + } else { + pr_err("%s: dai_data is NULL\n", __func__); + } + + return 0; +} + +static int msm_dai_q6_usb_audio_endian_cfg_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + u32 val = ucontrol->value.integer.value[0]; + + if (dai_data) { + dai_data->port_config.usb_audio.endian = val; + pr_debug("%s: endian = 0x%x\n", __func__, + dai_data->port_config.usb_audio.endian); + } else { + pr_err("%s: dai_data is NULL\n", __func__); + return -EINVAL; + } + + return 0; +} + +static int msm_dai_q6_usb_audio_endian_cfg_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (dai_data) { + ucontrol->value.integer.value[0] = + dai_data->port_config.usb_audio.endian; + pr_debug("%s: endian = 0x%x\n", __func__, + dai_data->port_config.usb_audio.endian); + } else { + pr_err("%s: dai_data is NULL\n", __func__); + return -EINVAL; + } + + return 0; +} + +static int msm_dai_q6_afe_enc_cfg_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(struct afe_enc_config); + + return 0; +} + +static int msm_dai_q6_afe_enc_cfg_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (dai_data) { + int format_size = sizeof(dai_data->enc_config.format); + + pr_debug("%s:encoder config for %d format\n", + __func__, dai_data->enc_config.format); + memcpy(ucontrol->value.bytes.data, + &dai_data->enc_config.format, + format_size); + switch (dai_data->enc_config.format) { + case ENC_FMT_SBC: + memcpy(ucontrol->value.bytes.data + format_size, + &dai_data->enc_config.data, + sizeof(struct asm_sbc_enc_cfg_t)); + break; + case ENC_FMT_AAC_V2: + memcpy(ucontrol->value.bytes.data + format_size, + &dai_data->enc_config.data, + sizeof(struct asm_aac_enc_cfg_v2_t)); + break; + case ENC_FMT_APTX: + case ENC_FMT_APTX_HD: + memcpy(ucontrol->value.bytes.data + format_size, + &dai_data->enc_config.data, + sizeof(struct asm_aac_enc_cfg_v2_t)); + break; + default: + pr_debug("%s: unknown format = %d\n", + __func__, dai_data->enc_config.format); + ret = -EINVAL; + break; + } + } + + return ret; +} + +static int msm_dai_q6_afe_enc_cfg_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (dai_data) { + int format_size = sizeof(dai_data->enc_config.format); + + memset(&dai_data->enc_config, 0x0, + sizeof(struct afe_enc_config)); + memcpy(&dai_data->enc_config.format, + ucontrol->value.bytes.data, + format_size); + pr_debug("%s: Received encoder config for %d format\n", + __func__, dai_data->enc_config.format); + switch (dai_data->enc_config.format) { + case ENC_FMT_SBC: + memcpy(&dai_data->enc_config.data, + ucontrol->value.bytes.data + format_size, + sizeof(struct asm_sbc_enc_cfg_t)); + break; + case ENC_FMT_AAC_V2: + memcpy(&dai_data->enc_config.data, + ucontrol->value.bytes.data + format_size, + sizeof(struct asm_aac_enc_cfg_v2_t)); + break; + case ENC_FMT_APTX: + case ENC_FMT_APTX_HD: + memcpy(&dai_data->enc_config.data, + ucontrol->value.bytes.data + format_size, + sizeof(struct asm_custom_enc_cfg_aptx_t)); + break; + default: + pr_debug("%s: Ignore enc config for unknown format = %d\n", + __func__, dai_data->enc_config.format); + ret = -EINVAL; + break; + } + } else + ret = -EINVAL; + + return ret; +} + +static const char *const afe_input_chs_text[] = {"Zero", "One", "Two"}; + +static const struct soc_enum afe_input_chs_enum[] = { + SOC_ENUM_SINGLE_EXT(3, afe_input_chs_text), +}; + +static const char *const afe_input_bit_format_text[] = {"S16_LE", "S24_LE"}; + +static const struct soc_enum afe_input_bit_format_enum[] = { + SOC_ENUM_SINGLE_EXT(2, afe_input_bit_format_text), +}; + +static int msm_dai_q6_afe_input_channel_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (dai_data) { + ucontrol->value.integer.value[0] = dai_data->afe_in_channels; + pr_debug("%s:afe input channel = %d\n", + __func__, dai_data->afe_in_channels); + } + + return 0; +} + +static int msm_dai_q6_afe_input_channel_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (dai_data) { + dai_data->afe_in_channels = ucontrol->value.integer.value[0]; + pr_debug("%s: updating afe input channel : %d\n", + __func__, dai_data->afe_in_channels); + } + + return 0; +} + +static int msm_dai_q6_afe_input_bit_format_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (!dai_data) { + pr_err("%s: Invalid dai data\n", __func__); + return -EINVAL; + } + + switch (dai_data->afe_in_bitformat) { + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: afe input bit format : %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_dai_q6_afe_input_bit_format_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (!dai_data) { + pr_err("%s: Invalid dai data\n", __func__); + return -EINVAL; + } + switch (ucontrol->value.integer.value[0]) { + case 1: + dai_data->afe_in_bitformat = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + dai_data->afe_in_bitformat = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: updating afe input bit format : %d\n", + __func__, dai_data->afe_in_bitformat); + + return 0; +} + + +static const struct snd_kcontrol_new afe_enc_config_controls[] = { + { + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_INACTIVE), + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "SLIM_7_RX Encoder Config", + .info = msm_dai_q6_afe_enc_cfg_info, + .get = msm_dai_q6_afe_enc_cfg_get, + .put = msm_dai_q6_afe_enc_cfg_put, + }, + SOC_ENUM_EXT("AFE Input Channels", afe_input_chs_enum[0], + msm_dai_q6_afe_input_channel_get, + msm_dai_q6_afe_input_channel_put), + SOC_ENUM_EXT("AFE Input Bit Format", afe_input_bit_format_enum[0], + msm_dai_q6_afe_input_bit_format_get, + msm_dai_q6_afe_input_bit_format_put), +}; + +static int msm_dai_q6_slim_rx_drift_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(struct afe_param_id_dev_timing_stats); + + return 0; +} + +static int msm_dai_q6_slim_rx_drift_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = -EINVAL; + struct afe_param_id_dev_timing_stats timing_stats; + struct snd_soc_dai *dai = kcontrol->private_data; + struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + + if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + pr_err("%s: afe port not started. dai_data->status_mask = %ld\n", + __func__, *dai_data->status_mask); + goto done; + } + + memset(&timing_stats, 0, sizeof(struct afe_param_id_dev_timing_stats)); + ret = afe_get_av_dev_drift(&timing_stats, dai->id); + if (ret) { + pr_err("%s: Error getting AFE Drift for port %d, err=%d\n", + __func__, dai->id, ret); + + goto done; + } + + memcpy(ucontrol->value.bytes.data, (void *)&timing_stats, + sizeof(struct afe_param_id_dev_timing_stats)); +done: + return ret; +} + +static const char * const afe_cal_mode_text[] = { + "CAL_MODE_DEFAULT", "CAL_MODE_NONE" +}; + +static const struct soc_enum slim_2_rx_enum = + SOC_ENUM_SINGLE(SLIMBUS_2_RX, 0, ARRAY_SIZE(afe_cal_mode_text), + afe_cal_mode_text); + +static const struct soc_enum rt_proxy_1_rx_enum = + SOC_ENUM_SINGLE(RT_PROXY_PORT_001_RX, 0, ARRAY_SIZE(afe_cal_mode_text), + afe_cal_mode_text); + +static const struct soc_enum rt_proxy_1_tx_enum = + SOC_ENUM_SINGLE(RT_PROXY_PORT_001_TX, 0, ARRAY_SIZE(afe_cal_mode_text), + afe_cal_mode_text); + +static const struct snd_kcontrol_new sb_config_controls[] = { + SOC_ENUM_EXT("SLIM_4_TX Format", sb_config_enum[0], + msm_dai_q6_sb_format_get, + msm_dai_q6_sb_format_put), + SOC_ENUM_EXT("SLIM_2_RX SetCalMode", slim_2_rx_enum, + msm_dai_q6_cal_info_get, + msm_dai_q6_cal_info_put), + SOC_ENUM_EXT("SLIM_2_RX Format", sb_config_enum[0], + msm_dai_q6_sb_format_get, + msm_dai_q6_sb_format_put) +}; + +static const struct snd_kcontrol_new rt_proxy_config_controls[] = { + SOC_ENUM_EXT("RT_PROXY_1_RX SetCalMode", rt_proxy_1_rx_enum, + msm_dai_q6_cal_info_get, + msm_dai_q6_cal_info_put), + SOC_ENUM_EXT("RT_PROXY_1_TX SetCalMode", rt_proxy_1_tx_enum, + msm_dai_q6_cal_info_get, + msm_dai_q6_cal_info_put), +}; + +static const struct snd_kcontrol_new usb_audio_cfg_controls[] = { + SOC_SINGLE_EXT("USB_AUDIO_RX dev_token", 0, 0, UINT_MAX, 0, + msm_dai_q6_usb_audio_cfg_get, + msm_dai_q6_usb_audio_cfg_put), + SOC_SINGLE_EXT("USB_AUDIO_RX endian", 0, 0, 1, 0, + msm_dai_q6_usb_audio_endian_cfg_get, + msm_dai_q6_usb_audio_endian_cfg_put), + SOC_SINGLE_EXT("USB_AUDIO_TX dev_token", 0, 0, UINT_MAX, 0, + msm_dai_q6_usb_audio_cfg_get, + msm_dai_q6_usb_audio_cfg_put), + SOC_SINGLE_EXT("USB_AUDIO_TX endian", 0, 0, 1, 0, + msm_dai_q6_usb_audio_endian_cfg_get, + msm_dai_q6_usb_audio_endian_cfg_put), +}; + +static const struct snd_kcontrol_new avd_drift_config_controls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "SLIMBUS_0_RX DRIFT", + .info = msm_dai_q6_slim_rx_drift_info, + .get = msm_dai_q6_slim_rx_drift_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "SLIMBUS_6_RX DRIFT", + .info = msm_dai_q6_slim_rx_drift_info, + .get = msm_dai_q6_slim_rx_drift_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "SLIMBUS_7_RX DRIFT", + .info = msm_dai_q6_slim_rx_drift_info, + .get = msm_dai_q6_slim_rx_drift_get, + }, +}; +static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) +{ + struct msm_dai_q6_dai_data *dai_data; + int rc = 0; + + if (!dai) { + pr_err("%s: Invalid params dai\n", __func__); + return -EINVAL; + } + if (!dai->dev) { + pr_err("%s: Invalid params dai dev\n", __func__); + return -EINVAL; + } + + dai_data = kzalloc(sizeof(struct msm_dai_q6_dai_data), GFP_KERNEL); + + if (!dai_data) + rc = -ENOMEM; + else + dev_set_drvdata(dai->dev, dai_data); + + msm_dai_q6_set_dai_id(dai); + + switch (dai->id) { + case SLIMBUS_4_TX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&sb_config_controls[0], + dai_data)); + break; + case SLIMBUS_2_RX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&sb_config_controls[1], + dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&sb_config_controls[2], + dai_data)); + break; + case SLIMBUS_7_RX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&afe_enc_config_controls[0], + dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&afe_enc_config_controls[1], + dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&afe_enc_config_controls[2], + dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&avd_drift_config_controls[2], + dai)); + break; + case RT_PROXY_DAI_001_RX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&rt_proxy_config_controls[0], + dai_data)); + break; + case RT_PROXY_DAI_001_TX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&rt_proxy_config_controls[1], + dai_data)); + break; + case AFE_PORT_ID_USB_RX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&usb_audio_cfg_controls[0], + dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&usb_audio_cfg_controls[1], + dai_data)); + break; + case AFE_PORT_ID_USB_TX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&usb_audio_cfg_controls[2], + dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&usb_audio_cfg_controls[3], + dai_data)); + break; + case SLIMBUS_0_RX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&avd_drift_config_controls[0], + dai)); + break; + case SLIMBUS_6_RX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&avd_drift_config_controls[1], + dai)); + break; + } + if (rc < 0) + dev_err(dai->dev, "%s: err add config ctl, DAI = %s\n", + __func__, dai->name); + + rc = msm_dai_q6_dai_add_route(dai); + return rc; +} + +static int msm_dai_q6_dai_remove(struct snd_soc_dai *dai) +{ + struct msm_dai_q6_dai_data *dai_data; + int rc; + + dai_data = dev_get_drvdata(dai->dev); + + /* If AFE port is still up, close it */ + if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + pr_debug("%s: stop pseudo port:%d\n", __func__, dai->id); + rc = afe_close(dai->id); /* can block */ + if (rc < 0) + dev_err(dai->dev, "fail to close AFE port\n"); + clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); + } + kfree(dai_data); + + return 0; +} + +static struct snd_soc_dai_driver msm_dai_q6_afe_rx_dai[] = { + { + .playback = { + .stream_name = "AFE Playback", + .aif_name = "PCM_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_ops, + .id = RT_PROXY_DAI_001_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .playback = { + .stream_name = "AFE-PROXY RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_ops, + .id = RT_PROXY_DAI_002_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, +}; + +static struct snd_soc_dai_driver msm_dai_q6_afe_tx_dai[] = { + { + .capture = { + .stream_name = "AFE Capture", + .aif_name = "PCM_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_ops, + .id = RT_PROXY_DAI_002_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .capture = { + .stream_name = "AFE-PROXY TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_ops, + .id = RT_PROXY_DAI_001_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, +}; + +static struct snd_soc_dai_driver msm_dai_q6_bt_sco_rx_dai = { + .playback = { + .stream_name = "Internal BT-SCO Playback", + .aif_name = "INT_BT_SCO_RX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_max = 16000, + .rate_min = 8000, + }, + .ops = &msm_dai_q6_ops, + .id = INT_BT_SCO_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, +}; + +static struct snd_soc_dai_driver msm_dai_q6_bt_a2dp_rx_dai = { + .playback = { + .stream_name = "Internal BT-A2DP Playback", + .aif_name = "INT_BT_A2DP_RX", + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_max = 48000, + .rate_min = 48000, + }, + .ops = &msm_dai_q6_ops, + .id = INT_BT_A2DP_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, +}; + +static struct snd_soc_dai_driver msm_dai_q6_bt_sco_tx_dai = { + .capture = { + .stream_name = "Internal BT-SCO Capture", + .aif_name = "INT_BT_SCO_TX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_max = 16000, + .rate_min = 8000, + }, + .ops = &msm_dai_q6_ops, + .id = INT_BT_SCO_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, +}; + +static struct snd_soc_dai_driver msm_dai_q6_fm_rx_dai = { + .playback = { + .stream_name = "Internal FM Playback", + .aif_name = "INT_FM_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 2, + .channels_max = 2, + .rate_max = 48000, + .rate_min = 8000, + }, + .ops = &msm_dai_q6_ops, + .id = INT_FM_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, +}; + +static struct snd_soc_dai_driver msm_dai_q6_fm_tx_dai = { + .capture = { + .stream_name = "Internal FM Capture", + .aif_name = "INT_FM_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 2, + .channels_max = 2, + .rate_max = 48000, + .rate_min = 8000, + }, + .ops = &msm_dai_q6_ops, + .id = INT_FM_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, +}; + +static struct snd_soc_dai_driver msm_dai_q6_voc_playback_dai[] = { + { + .playback = { + .stream_name = "Voice Farend Playback", + .aif_name = "VOICE_PLAYBACK_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_ops, + .id = VOICE_PLAYBACK_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .playback = { + .stream_name = "Voice2 Farend Playback", + .aif_name = "VOICE2_PLAYBACK_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_ops, + .id = VOICE2_PLAYBACK_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, +}; + +static struct snd_soc_dai_driver msm_dai_q6_incall_record_dai[] = { + { + .capture = { + .stream_name = "Voice Uplink Capture", + .aif_name = "INCALL_RECORD_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_ops, + .id = VOICE_RECORD_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .capture = { + .stream_name = "Voice Downlink Capture", + .aif_name = "INCALL_RECORD_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_ops, + .id = VOICE_RECORD_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, +}; + +static struct snd_soc_dai_driver msm_dai_q6_usb_rx_dai = { + .playback = { + .stream_name = "USB Audio Playback", + .aif_name = "USB_AUDIO_RX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_max = 384000, + .rate_min = 8000, + }, + .ops = &msm_dai_q6_ops, + .id = AFE_PORT_ID_USB_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, +}; + +static struct snd_soc_dai_driver msm_dai_q6_usb_tx_dai = { + .capture = { + .stream_name = "USB Audio Capture", + .aif_name = "USB_AUDIO_TX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_max = 384000, + .rate_min = 8000, + }, + .ops = &msm_dai_q6_ops, + .id = AFE_PORT_ID_USB_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, +}; + +static int msm_auxpcm_dev_probe(struct platform_device *pdev) +{ + struct msm_dai_q6_auxpcm_dai_data *dai_data; + struct msm_dai_auxpcm_pdata *auxpcm_pdata; + uint32_t val_array[RATE_MAX_NUM_OF_AUX_PCM_RATES]; + uint32_t val = 0; + const char *intf_name; + int rc = 0, i = 0, len = 0; + const uint32_t *slot_mapping_array = NULL; + u32 array_length = 0; + + dai_data = kzalloc(sizeof(struct msm_dai_q6_auxpcm_dai_data), + GFP_KERNEL); + if (!dai_data) + return -ENOMEM; + + auxpcm_pdata = kzalloc(sizeof(struct msm_dai_auxpcm_pdata), + GFP_KERNEL); + + if (!auxpcm_pdata) { + dev_err(&pdev->dev, "Failed to allocate memory for platform data\n"); + goto fail_pdata_nomem; + } + + dev_dbg(&pdev->dev, "%s: dev %pK, dai_data %pK, auxpcm_pdata %pK\n", + __func__, &pdev->dev, dai_data, auxpcm_pdata); + + rc = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-cpudai-auxpcm-mode", + val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES); + if (rc) { + dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-mode missing in DT node\n", + __func__); + goto fail_invalid_dt; + } + auxpcm_pdata->mode_8k.mode = (u16)val_array[RATE_8KHZ]; + auxpcm_pdata->mode_16k.mode = (u16)val_array[RATE_16KHZ]; + + rc = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-cpudai-auxpcm-sync", + val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES); + if (rc) { + dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-sync missing in DT node\n", + __func__); + goto fail_invalid_dt; + } + auxpcm_pdata->mode_8k.sync = (u16)val_array[RATE_8KHZ]; + auxpcm_pdata->mode_16k.sync = (u16)val_array[RATE_16KHZ]; + + rc = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-cpudai-auxpcm-frame", + val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES); + + if (rc) { + dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-frame missing in DT node\n", + __func__); + goto fail_invalid_dt; + } + auxpcm_pdata->mode_8k.frame = (u16)val_array[RATE_8KHZ]; + auxpcm_pdata->mode_16k.frame = (u16)val_array[RATE_16KHZ]; + + rc = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-cpudai-auxpcm-quant", + val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES); + if (rc) { + dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-quant missing in DT node\n", + __func__); + goto fail_invalid_dt; + } + auxpcm_pdata->mode_8k.quant = (u16)val_array[RATE_8KHZ]; + auxpcm_pdata->mode_16k.quant = (u16)val_array[RATE_16KHZ]; + + rc = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-cpudai-auxpcm-num-slots", + val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES); + if (rc) { + dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-num-slots missing in DT node\n", + __func__); + goto fail_invalid_dt; + } + auxpcm_pdata->mode_8k.num_slots = (u16)val_array[RATE_8KHZ]; + + if (auxpcm_pdata->mode_8k.num_slots > + msm_dai_q6_max_num_slot(auxpcm_pdata->mode_8k.frame)) { + dev_err(&pdev->dev, "%s Max slots %d greater than DT node %d\n", + __func__, + msm_dai_q6_max_num_slot(auxpcm_pdata->mode_8k.frame), + auxpcm_pdata->mode_8k.num_slots); + rc = -EINVAL; + goto fail_invalid_dt; + } + auxpcm_pdata->mode_16k.num_slots = (u16)val_array[RATE_16KHZ]; + + if (auxpcm_pdata->mode_16k.num_slots > + msm_dai_q6_max_num_slot(auxpcm_pdata->mode_16k.frame)) { + dev_err(&pdev->dev, "%s Max slots %d greater than DT node %d\n", + __func__, + msm_dai_q6_max_num_slot(auxpcm_pdata->mode_16k.frame), + auxpcm_pdata->mode_16k.num_slots); + rc = -EINVAL; + goto fail_invalid_dt; + } + + slot_mapping_array = of_get_property(pdev->dev.of_node, + "qcom,msm-cpudai-auxpcm-slot-mapping", &len); + + if (slot_mapping_array == NULL) { + dev_err(&pdev->dev, "%s slot_mapping_array is not valid\n", + __func__); + rc = -EINVAL; + goto fail_invalid_dt; + } + + array_length = auxpcm_pdata->mode_8k.num_slots + + auxpcm_pdata->mode_16k.num_slots; + + if (len != sizeof(uint32_t) * array_length) { + dev_err(&pdev->dev, "%s Length is %d and expected is %zd\n", + __func__, len, sizeof(uint32_t) * array_length); + rc = -EINVAL; + goto fail_invalid_dt; + } + + auxpcm_pdata->mode_8k.slot_mapping = + kzalloc(sizeof(uint16_t) * + auxpcm_pdata->mode_8k.num_slots, + GFP_KERNEL); + if (!auxpcm_pdata->mode_8k.slot_mapping) { + dev_err(&pdev->dev, "%s No mem for mode_8k slot mapping\n", + __func__); + rc = -ENOMEM; + goto fail_invalid_dt; + } + + for (i = 0; i < auxpcm_pdata->mode_8k.num_slots; i++) + auxpcm_pdata->mode_8k.slot_mapping[i] = + (u16)be32_to_cpu(slot_mapping_array[i]); + + auxpcm_pdata->mode_16k.slot_mapping = + kzalloc(sizeof(uint16_t) * + auxpcm_pdata->mode_16k.num_slots, + GFP_KERNEL); + + if (!auxpcm_pdata->mode_16k.slot_mapping) { + dev_err(&pdev->dev, "%s No mem for mode_16k slot mapping\n", + __func__); + rc = -ENOMEM; + goto fail_invalid_16k_slot_mapping; + } + + for (i = 0; i < auxpcm_pdata->mode_16k.num_slots; i++) + auxpcm_pdata->mode_16k.slot_mapping[i] = + (u16)be32_to_cpu(slot_mapping_array[i + + auxpcm_pdata->mode_8k.num_slots]); + + rc = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-cpudai-auxpcm-data", + val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES); + if (rc) { + dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-data missing in DT node\n", + __func__); + goto fail_invalid_dt1; + } + auxpcm_pdata->mode_8k.data = (u16)val_array[RATE_8KHZ]; + auxpcm_pdata->mode_16k.data = (u16)val_array[RATE_16KHZ]; + + rc = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-cpudai-auxpcm-pcm-clk-rate", + val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES); + if (rc) { + dev_err(&pdev->dev, + "%s: qcom,msm-cpudai-auxpcm-pcm-clk-rate missing in DT\n", + __func__); + goto fail_invalid_dt1; + } + auxpcm_pdata->mode_8k.pcm_clk_rate = (int)val_array[RATE_8KHZ]; + auxpcm_pdata->mode_16k.pcm_clk_rate = (int)val_array[RATE_16KHZ]; + + rc = of_property_read_string(pdev->dev.of_node, + "qcom,msm-auxpcm-interface", &intf_name); + if (rc) { + dev_err(&pdev->dev, + "%s: qcom,msm-auxpcm-interface missing in DT node\n", + __func__); + goto fail_nodev_intf; + } + + if (!strcmp(intf_name, "primary")) { + dai_data->rx_pid = AFE_PORT_ID_PRIMARY_PCM_RX; + dai_data->tx_pid = AFE_PORT_ID_PRIMARY_PCM_TX; + pdev->id = MSM_DAI_PRI_AUXPCM_DT_DEV_ID; + i = 0; + } else if (!strcmp(intf_name, "secondary")) { + dai_data->rx_pid = AFE_PORT_ID_SECONDARY_PCM_RX; + dai_data->tx_pid = AFE_PORT_ID_SECONDARY_PCM_TX; + pdev->id = MSM_DAI_SEC_AUXPCM_DT_DEV_ID; + i = 1; + } else if (!strcmp(intf_name, "tertiary")) { + dai_data->rx_pid = AFE_PORT_ID_TERTIARY_PCM_RX; + dai_data->tx_pid = AFE_PORT_ID_TERTIARY_PCM_TX; + pdev->id = MSM_DAI_TERT_AUXPCM_DT_DEV_ID; + i = 2; + } else if (!strcmp(intf_name, "quaternary")) { + dai_data->rx_pid = AFE_PORT_ID_QUATERNARY_PCM_RX; + dai_data->tx_pid = AFE_PORT_ID_QUATERNARY_PCM_TX; + pdev->id = MSM_DAI_QUAT_AUXPCM_DT_DEV_ID; + i = 3; + } else { + dev_err(&pdev->dev, "%s: invalid DT intf name %s\n", + __func__, intf_name); + goto fail_invalid_intf; + } + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-cpudai-afe-clk-ver", &val); + if (rc) + dai_data->afe_clk_ver = AFE_CLK_VERSION_V1; + else + dai_data->afe_clk_ver = val; + + mutex_init(&dai_data->rlock); + dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev)); + + dev_set_drvdata(&pdev->dev, dai_data); + pdev->dev.platform_data = (void *) auxpcm_pdata; + + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_aux_pcm_dai_component, + &msm_dai_q6_aux_pcm_dai[i], 1); + if (rc) { + dev_err(&pdev->dev, "%s: auxpcm dai reg failed, rc=%d\n", + __func__, rc); + goto fail_reg_dai; + } + + return rc; + +fail_reg_dai: +fail_invalid_intf: +fail_nodev_intf: +fail_invalid_dt1: + kfree(auxpcm_pdata->mode_16k.slot_mapping); +fail_invalid_16k_slot_mapping: + kfree(auxpcm_pdata->mode_8k.slot_mapping); +fail_invalid_dt: + kfree(auxpcm_pdata); +fail_pdata_nomem: + kfree(dai_data); + return rc; +} + +static int msm_auxpcm_dev_remove(struct platform_device *pdev) +{ + struct msm_dai_q6_auxpcm_dai_data *dai_data; + + dai_data = dev_get_drvdata(&pdev->dev); + + snd_soc_unregister_component(&pdev->dev); + + mutex_destroy(&dai_data->rlock); + kfree(dai_data); + kfree(pdev->dev.platform_data); + + return 0; +} + +static const struct of_device_id msm_auxpcm_dev_dt_match[] = { + { .compatible = "qcom,msm-auxpcm-dev", }, + {} +}; + + +static struct platform_driver msm_auxpcm_dev_driver = { + .probe = msm_auxpcm_dev_probe, + .remove = msm_auxpcm_dev_remove, + .driver = { + .name = "msm-auxpcm-dev", + .owner = THIS_MODULE, + .of_match_table = msm_auxpcm_dev_dt_match, + }, +}; + +static struct snd_soc_dai_driver msm_dai_q6_slimbus_rx_dai[] = { + { + .playback = { + .stream_name = "Slimbus Playback", + .aif_name = "SLIMBUS_0_RX", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = DAI_FORMATS_S16_S24_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_0_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .playback = { + .stream_name = "Slimbus1 Playback", + .aif_name = "SLIMBUS_1_RX", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = DAI_FORMATS_S16_S24_S32_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_1_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .playback = { + .stream_name = "Slimbus2 Playback", + .aif_name = "SLIMBUS_2_RX", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = DAI_FORMATS_S16_S24_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_2_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .playback = { + .stream_name = "Slimbus3 Playback", + .aif_name = "SLIMBUS_3_RX", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = DAI_FORMATS_S16_S24_S32_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_3_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .playback = { + .stream_name = "Slimbus4 Playback", + .aif_name = "SLIMBUS_4_RX", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = DAI_FORMATS_S16_S24_S32_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_4_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .playback = { + .stream_name = "Slimbus6 Playback", + .aif_name = "SLIMBUS_6_RX", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = DAI_FORMATS_S16_S24_S32_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_6_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .playback = { + .stream_name = "Slimbus5 Playback", + .aif_name = "SLIMBUS_5_RX", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = DAI_FORMATS_S16_S24_S32_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_5_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .playback = { + .stream_name = "Slimbus7 Playback", + .aif_name = "SLIMBUS_7_RX", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = DAI_FORMATS_S16_S24_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_7_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .playback = { + .stream_name = "Slimbus8 Playback", + .aif_name = "SLIMBUS_8_RX", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = DAI_FORMATS_S16_S24_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_8_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, +}; + +static struct snd_soc_dai_driver msm_dai_q6_slimbus_tx_dai[] = { + { + .capture = { + .stream_name = "Slimbus Capture", + .aif_name = "SLIMBUS_0_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_0_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .capture = { + .stream_name = "Slimbus1 Capture", + .aif_name = "SLIMBUS_1_TX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_1_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .capture = { + .stream_name = "Slimbus2 Capture", + .aif_name = "SLIMBUS_2_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_2_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .capture = { + .stream_name = "Slimbus3 Capture", + .aif_name = "SLIMBUS_3_TX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 2, + .channels_max = 4, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_3_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .capture = { + .stream_name = "Slimbus4 Capture", + .aif_name = "SLIMBUS_4_TX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 2, + .channels_max = 4, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_4_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .capture = { + .stream_name = "Slimbus5 Capture", + .aif_name = "SLIMBUS_5_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_5_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .capture = { + .stream_name = "Slimbus6 Capture", + .aif_name = "SLIMBUS_6_TX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_6_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .capture = { + .stream_name = "Slimbus7 Capture", + .aif_name = "SLIMBUS_7_TX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_7_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, + { + .capture = { + .stream_name = "Slimbus8 Capture", + .aif_name = "SLIMBUS_8_TX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_8_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, +}; + +static int msm_dai_q6_mi2s_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + int value = ucontrol->value.integer.value[0]; + + dai_data->port_config.i2s.data_format = value; + pr_debug("%s: value = %d, channel = %d, line = %d\n", + __func__, value, dai_data->port_config.i2s.mono_stereo, + dai_data->port_config.i2s.channel_mode); + return 0; +} + +static int msm_dai_q6_mi2s_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + ucontrol->value.integer.value[0] = + dai_data->port_config.i2s.data_format; + return 0; +} + +static int msm_dai_q6_mi2s_vi_feed_mono_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + int value = ucontrol->value.integer.value[0]; + + dai_data->vi_feed_mono = value; + pr_debug("%s: value = %d\n", __func__, value); + return 0; +} + +static int msm_dai_q6_mi2s_vi_feed_mono_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + ucontrol->value.integer.value[0] = dai_data->vi_feed_mono; + return 0; +} + +static const struct snd_kcontrol_new mi2s_config_controls[] = { + SOC_ENUM_EXT("PRI MI2S RX Format", mi2s_config_enum[0], + msm_dai_q6_mi2s_format_get, + msm_dai_q6_mi2s_format_put), + SOC_ENUM_EXT("SEC MI2S RX Format", mi2s_config_enum[0], + msm_dai_q6_mi2s_format_get, + msm_dai_q6_mi2s_format_put), + SOC_ENUM_EXT("TERT MI2S RX Format", mi2s_config_enum[0], + msm_dai_q6_mi2s_format_get, + msm_dai_q6_mi2s_format_put), + SOC_ENUM_EXT("QUAT MI2S RX Format", mi2s_config_enum[0], + msm_dai_q6_mi2s_format_get, + msm_dai_q6_mi2s_format_put), + SOC_ENUM_EXT("QUIN MI2S RX Format", mi2s_config_enum[0], + msm_dai_q6_mi2s_format_get, + msm_dai_q6_mi2s_format_put), + SOC_ENUM_EXT("PRI MI2S TX Format", mi2s_config_enum[0], + msm_dai_q6_mi2s_format_get, + msm_dai_q6_mi2s_format_put), + SOC_ENUM_EXT("SEC MI2S TX Format", mi2s_config_enum[0], + msm_dai_q6_mi2s_format_get, + msm_dai_q6_mi2s_format_put), + SOC_ENUM_EXT("TERT MI2S TX Format", mi2s_config_enum[0], + msm_dai_q6_mi2s_format_get, + msm_dai_q6_mi2s_format_put), + SOC_ENUM_EXT("QUAT MI2S TX Format", mi2s_config_enum[0], + msm_dai_q6_mi2s_format_get, + msm_dai_q6_mi2s_format_put), + SOC_ENUM_EXT("QUIN MI2S TX Format", mi2s_config_enum[0], + msm_dai_q6_mi2s_format_get, + msm_dai_q6_mi2s_format_put), + SOC_ENUM_EXT("SENARY MI2S TX Format", mi2s_config_enum[0], + msm_dai_q6_mi2s_format_get, + msm_dai_q6_mi2s_format_put), + SOC_ENUM_EXT("INT5 MI2S TX Format", mi2s_config_enum[0], + msm_dai_q6_mi2s_format_get, + msm_dai_q6_mi2s_format_put), +}; + +static const struct snd_kcontrol_new mi2s_vi_feed_controls[] = { + SOC_ENUM_EXT("INT5 MI2S VI MONO", mi2s_config_enum[1], + msm_dai_q6_mi2s_vi_feed_mono_get, + msm_dai_q6_mi2s_vi_feed_mono_put), +}; + +static int msm_dai_q6_dai_mi2s_probe(struct snd_soc_dai *dai) +{ + struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data = + dev_get_drvdata(dai->dev); + struct msm_mi2s_pdata *mi2s_pdata = + (struct msm_mi2s_pdata *) dai->dev->platform_data; + struct snd_kcontrol *kcontrol = NULL; + int rc = 0; + const struct snd_kcontrol_new *ctrl = NULL; + const struct snd_kcontrol_new *vi_feed_ctrl = NULL; + + dai->id = mi2s_pdata->intf_id; + + if (mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.i2s.channel_mode) { + if (dai->id == MSM_PRIM_MI2S) + ctrl = &mi2s_config_controls[0]; + if (dai->id == MSM_SEC_MI2S) + ctrl = &mi2s_config_controls[1]; + if (dai->id == MSM_TERT_MI2S) + ctrl = &mi2s_config_controls[2]; + if (dai->id == MSM_QUAT_MI2S) + ctrl = &mi2s_config_controls[3]; + if (dai->id == MSM_QUIN_MI2S) + ctrl = &mi2s_config_controls[4]; + } + + if (ctrl) { + kcontrol = snd_ctl_new1(ctrl, + &mi2s_dai_data->rx_dai.mi2s_dai_data); + rc = snd_ctl_add(dai->component->card->snd_card, kcontrol); + if (rc < 0) { + dev_err(dai->dev, "%s: err add RX fmt ctl DAI = %s\n", + __func__, dai->name); + goto rtn; + } + } + + ctrl = NULL; + if (mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.channel_mode) { + if (dai->id == MSM_PRIM_MI2S) + ctrl = &mi2s_config_controls[4]; + if (dai->id == MSM_SEC_MI2S) + ctrl = &mi2s_config_controls[5]; + if (dai->id == MSM_TERT_MI2S) + ctrl = &mi2s_config_controls[6]; + if (dai->id == MSM_QUAT_MI2S) + ctrl = &mi2s_config_controls[7]; + if (dai->id == MSM_QUIN_MI2S) + ctrl = &mi2s_config_controls[9]; + if (dai->id == MSM_SENARY_MI2S) + ctrl = &mi2s_config_controls[10]; + if (dai->id == MSM_INT5_MI2S) + ctrl = &mi2s_config_controls[11]; + } + + if (ctrl) { + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(ctrl, + &mi2s_dai_data->tx_dai.mi2s_dai_data)); + if (rc < 0) { + if (kcontrol) + snd_ctl_remove(dai->component->card->snd_card, + kcontrol); + dev_err(dai->dev, "%s: err add TX fmt ctl DAI = %s\n", + __func__, dai->name); + } + } + + if (dai->id == MSM_INT5_MI2S) + vi_feed_ctrl = &mi2s_vi_feed_controls[0]; + + if (vi_feed_ctrl) { + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(vi_feed_ctrl, + &mi2s_dai_data->tx_dai.mi2s_dai_data)); + + if (rc < 0) { + dev_err(dai->dev, "%s: err add TX vi feed channel ctl DAI = %s\n", + __func__, dai->name); + } + } + + rc = msm_dai_q6_dai_add_route(dai); +rtn: + return rc; +} + + +static int msm_dai_q6_dai_mi2s_remove(struct snd_soc_dai *dai) +{ + struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data = + dev_get_drvdata(dai->dev); + int rc; + + /* If AFE port is still up, close it */ + if (test_bit(STATUS_PORT_STARTED, + mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask)) { + rc = afe_close(MI2S_RX); /* can block */ + if (rc < 0) + dev_err(dai->dev, "fail to close MI2S_RX port\n"); + clear_bit(STATUS_PORT_STARTED, + mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask); + } + if (test_bit(STATUS_PORT_STARTED, + mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask)) { + rc = afe_close(MI2S_TX); /* can block */ + if (rc < 0) + dev_err(dai->dev, "fail to close MI2S_TX port\n"); + clear_bit(STATUS_PORT_STARTED, + mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask); + } + kfree(mi2s_dai_data); + return 0; +} + +static int msm_dai_q6_mi2s_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + + return 0; +} + + +static int msm_mi2s_get_port_id(u32 mi2s_id, int stream, u16 *port_id) +{ + int ret = 0; + + switch (stream) { + case SNDRV_PCM_STREAM_PLAYBACK: + switch (mi2s_id) { + case MSM_PRIM_MI2S: + *port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; + break; + case MSM_SEC_MI2S: + *port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; + break; + case MSM_TERT_MI2S: + *port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; + break; + case MSM_QUAT_MI2S: + *port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; + break; + case MSM_SEC_MI2S_SD1: + *port_id = AFE_PORT_ID_SECONDARY_MI2S_RX_SD1; + break; + case MSM_QUIN_MI2S: + *port_id = AFE_PORT_ID_QUINARY_MI2S_RX; + break; + case MSM_INT0_MI2S: + *port_id = AFE_PORT_ID_INT0_MI2S_RX; + break; + case MSM_INT1_MI2S: + *port_id = AFE_PORT_ID_INT1_MI2S_RX; + break; + case MSM_INT2_MI2S: + *port_id = AFE_PORT_ID_INT2_MI2S_RX; + break; + case MSM_INT3_MI2S: + *port_id = AFE_PORT_ID_INT3_MI2S_RX; + break; + case MSM_INT4_MI2S: + *port_id = AFE_PORT_ID_INT4_MI2S_RX; + break; + case MSM_INT5_MI2S: + *port_id = AFE_PORT_ID_INT5_MI2S_RX; + break; + case MSM_INT6_MI2S: + *port_id = AFE_PORT_ID_INT6_MI2S_RX; + break; + default: + pr_err("%s: playback err id 0x%x\n", + __func__, mi2s_id); + ret = -1; + break; + } + break; + case SNDRV_PCM_STREAM_CAPTURE: + switch (mi2s_id) { + case MSM_PRIM_MI2S: + *port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; + break; + case MSM_SEC_MI2S: + *port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; + break; + case MSM_TERT_MI2S: + *port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + break; + case MSM_QUAT_MI2S: + *port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + case MSM_QUIN_MI2S: + *port_id = AFE_PORT_ID_QUINARY_MI2S_TX; + break; + case MSM_SENARY_MI2S: + *port_id = AFE_PORT_ID_SENARY_MI2S_TX; + break; + case MSM_INT0_MI2S: + *port_id = AFE_PORT_ID_INT0_MI2S_TX; + break; + case MSM_INT1_MI2S: + *port_id = AFE_PORT_ID_INT1_MI2S_TX; + break; + case MSM_INT2_MI2S: + *port_id = AFE_PORT_ID_INT2_MI2S_TX; + break; + case MSM_INT3_MI2S: + *port_id = AFE_PORT_ID_INT3_MI2S_TX; + break; + case MSM_INT4_MI2S: + *port_id = AFE_PORT_ID_INT4_MI2S_TX; + break; + case MSM_INT5_MI2S: + *port_id = AFE_PORT_ID_INT5_MI2S_TX; + break; + case MSM_INT6_MI2S: + *port_id = AFE_PORT_ID_INT6_MI2S_TX; + break; + default: + pr_err("%s: capture err id 0x%x\n", __func__, mi2s_id); + ret = -1; + break; + } + break; + default: + pr_err("%s: default err %d\n", __func__, stream); + ret = -1; + break; + } + pr_debug("%s: port_id = 0x%x\n", __func__, *port_id); + return ret; +} + +static int msm_dai_q6_mi2s_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data = + dev_get_drvdata(dai->dev); + struct msm_dai_q6_dai_data *dai_data = + (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? + &mi2s_dai_data->rx_dai.mi2s_dai_data : + &mi2s_dai_data->tx_dai.mi2s_dai_data); + u16 port_id = 0; + int rc = 0; + + if (msm_mi2s_get_port_id(dai->id, substream->stream, + &port_id) != 0) { + dev_err(dai->dev, "%s: Invalid Port ID 0x%x\n", + __func__, port_id); + return -EINVAL; + } + + dev_dbg(dai->dev, "%s: dai id %d, afe port id = 0x%x\n" + "dai_data->channels = %u sample_rate = %u\n", __func__, + dai->id, port_id, dai_data->channels, dai_data->rate); + + if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + /* PORT START should be set if prepare called + * in active state. + */ + rc = afe_port_start(port_id, &dai_data->port_config, + dai_data->rate); + if (rc < 0) + dev_err(dai->dev, "fail to open AFE port 0x%x\n", + dai->id); + else + set_bit(STATUS_PORT_STARTED, + dai_data->status_mask); + } + if (!test_bit(STATUS_PORT_STARTED, dai_data->hwfree_status)) { + set_bit(STATUS_PORT_STARTED, dai_data->hwfree_status); + dev_dbg(dai->dev, "%s: set hwfree_status to started\n", + __func__); + } + return rc; +} + +static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data = + dev_get_drvdata(dai->dev); + struct msm_dai_q6_mi2s_dai_config *mi2s_dai_config = + (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? + &mi2s_dai_data->rx_dai : &mi2s_dai_data->tx_dai); + struct msm_dai_q6_dai_data *dai_data = &mi2s_dai_config->mi2s_dai_data; + struct afe_param_id_i2s_cfg *i2s = &dai_data->port_config.i2s; + + dai_data->channels = params_channels(params); + switch (dai_data->channels) { + case 8: + case 7: + if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_8CHS) + goto error_invalid_data; + dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_8CHS; + break; + case 6: + case 5: + if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_6CHS) + goto error_invalid_data; + dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_6CHS; + break; + case 4: + case 3: + if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_QUAD01) + goto error_invalid_data; + if (mi2s_dai_config->pdata_mi2s_lines == AFE_PORT_I2S_QUAD23) + dai_data->port_config.i2s.channel_mode = + mi2s_dai_config->pdata_mi2s_lines; + else + dai_data->port_config.i2s.channel_mode = + AFE_PORT_I2S_QUAD01; + break; + case 2: + case 1: + if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_SD0) + goto error_invalid_data; + switch (mi2s_dai_config->pdata_mi2s_lines) { + case AFE_PORT_I2S_SD0: + case AFE_PORT_I2S_SD1: + case AFE_PORT_I2S_SD2: + case AFE_PORT_I2S_SD3: + dai_data->port_config.i2s.channel_mode = + mi2s_dai_config->pdata_mi2s_lines; + break; + case AFE_PORT_I2S_QUAD01: + case AFE_PORT_I2S_6CHS: + case AFE_PORT_I2S_8CHS: + if (dai_data->vi_feed_mono == SPKR_1) + dai_data->port_config.i2s.channel_mode = + AFE_PORT_I2S_SD0; + else + dai_data->port_config.i2s.channel_mode = + AFE_PORT_I2S_SD1; + break; + case AFE_PORT_I2S_QUAD23: + dai_data->port_config.i2s.channel_mode = + AFE_PORT_I2S_SD2; + break; + } + if (dai_data->channels == 2) + dai_data->port_config.i2s.mono_stereo = + MSM_AFE_CH_STEREO; + else + dai_data->port_config.i2s.mono_stereo = MSM_AFE_MONO; + break; + default: + pr_err("%s: default err channels %d\n", + __func__, dai_data->channels); + goto error_invalid_data; + } + dai_data->rate = params_rate(params); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + case SNDRV_PCM_FORMAT_SPECIAL: + dai_data->port_config.i2s.bit_width = 16; + dai_data->bitwidth = 16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + dai_data->port_config.i2s.bit_width = 24; + dai_data->bitwidth = 24; + break; + default: + pr_err("%s: format %d\n", + __func__, params_format(params)); + return -EINVAL; + } + + dai_data->port_config.i2s.i2s_cfg_minor_version = + AFE_API_VERSION_I2S_CONFIG; + dai_data->port_config.i2s.sample_rate = dai_data->rate; + if ((test_bit(STATUS_PORT_STARTED, + mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask) && + test_bit(STATUS_PORT_STARTED, + mi2s_dai_data->rx_dai.mi2s_dai_data.hwfree_status)) || + (test_bit(STATUS_PORT_STARTED, + mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask) && + test_bit(STATUS_PORT_STARTED, + mi2s_dai_data->tx_dai.mi2s_dai_data.hwfree_status))) { + if ((mi2s_dai_data->tx_dai.mi2s_dai_data.rate != + mi2s_dai_data->rx_dai.mi2s_dai_data.rate) || + (mi2s_dai_data->rx_dai.mi2s_dai_data.bitwidth != + mi2s_dai_data->tx_dai.mi2s_dai_data.bitwidth)) { + dev_err(dai->dev, "%s: Error mismatch in HW params\n" + "Tx sample_rate = %u bit_width = %hu\n" + "Rx sample_rate = %u bit_width = %hu\n" + , __func__, + mi2s_dai_data->tx_dai.mi2s_dai_data.rate, + mi2s_dai_data->tx_dai.mi2s_dai_data.bitwidth, + mi2s_dai_data->rx_dai.mi2s_dai_data.rate, + mi2s_dai_data->rx_dai.mi2s_dai_data.bitwidth); + return -EINVAL; + } + } + dev_dbg(dai->dev, "%s: dai id %d dai_data->channels = %d\n" + "sample_rate = %u i2s_cfg_minor_version = 0x%x\n" + "bit_width = %hu channel_mode = 0x%x mono_stereo = %#x\n" + "ws_src = 0x%x sample_rate = %u data_format = 0x%x\n" + "reserved = %u\n", __func__, dai->id, dai_data->channels, + dai_data->rate, i2s->i2s_cfg_minor_version, i2s->bit_width, + i2s->channel_mode, i2s->mono_stereo, i2s->ws_src, + i2s->sample_rate, i2s->data_format, i2s->reserved); + + return 0; + +error_invalid_data: + pr_err("%s: dai_data->channels = %d channel_mode = %d\n", __func__, + dai_data->channels, dai_data->port_config.i2s.channel_mode); + return -EINVAL; +} + + +static int msm_dai_q6_mi2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data = + dev_get_drvdata(dai->dev); + + if (test_bit(STATUS_PORT_STARTED, + mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask) || + test_bit(STATUS_PORT_STARTED, + mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask)) { + dev_err(dai->dev, "%s: err chg i2s mode while dai running", + __func__); + return -EPERM; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.i2s.ws_src = 1; + mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.ws_src = 1; + break; + case SND_SOC_DAIFMT_CBM_CFM: + mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.i2s.ws_src = 0; + mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.ws_src = 0; + break; + default: + pr_err("%s: fmt %d\n", + __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK); + return -EINVAL; + } + + return 0; +} + +static int msm_dai_q6_mi2s_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data = + dev_get_drvdata(dai->dev); + struct msm_dai_q6_dai_data *dai_data = + (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? + &mi2s_dai_data->rx_dai.mi2s_dai_data : + &mi2s_dai_data->tx_dai.mi2s_dai_data); + + if (test_bit(STATUS_PORT_STARTED, dai_data->hwfree_status)) { + clear_bit(STATUS_PORT_STARTED, dai_data->hwfree_status); + dev_dbg(dai->dev, "%s: clear hwfree_status\n", __func__); + } + return 0; +} + +static void msm_dai_q6_mi2s_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data = + dev_get_drvdata(dai->dev); + struct msm_dai_q6_dai_data *dai_data = + (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? + &mi2s_dai_data->rx_dai.mi2s_dai_data : + &mi2s_dai_data->tx_dai.mi2s_dai_data); + u16 port_id = 0; + int rc = 0; + + if (msm_mi2s_get_port_id(dai->id, substream->stream, + &port_id) != 0) { + dev_err(dai->dev, "%s: Invalid Port ID 0x%x\n", + __func__, port_id); + } + + dev_dbg(dai->dev, "%s: closing afe port id = 0x%x\n", + __func__, port_id); + + if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + rc = afe_close(port_id); + if (rc < 0) + dev_err(dai->dev, "fail to close AFE port\n"); + clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); + } + if (test_bit(STATUS_PORT_STARTED, dai_data->hwfree_status)) + clear_bit(STATUS_PORT_STARTED, dai_data->hwfree_status); +} + +static struct snd_soc_dai_ops msm_dai_q6_mi2s_ops = { + .startup = msm_dai_q6_mi2s_startup, + .prepare = msm_dai_q6_mi2s_prepare, + .hw_params = msm_dai_q6_mi2s_hw_params, + .hw_free = msm_dai_q6_mi2s_hw_free, + .set_fmt = msm_dai_q6_mi2s_set_fmt, + .shutdown = msm_dai_q6_mi2s_shutdown, +}; + +/* Channel min and max are initialized base on platform data */ +static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { + { + .playback = { + .stream_name = "Primary MI2S Playback", + .aif_name = "PRI_MI2S_RX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .capture = { + .stream_name = "Primary MI2S Capture", + .aif_name = "PRI_MI2S_TX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_mi2s_ops, + .id = MSM_PRIM_MI2S, + .probe = msm_dai_q6_dai_mi2s_probe, + .remove = msm_dai_q6_dai_mi2s_remove, + }, + { + .playback = { + .stream_name = "Secondary MI2S Playback", + .aif_name = "SEC_MI2S_RX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .capture = { + .stream_name = "Secondary MI2S Capture", + .aif_name = "SEC_MI2S_TX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_mi2s_ops, + .id = MSM_SEC_MI2S, + .probe = msm_dai_q6_dai_mi2s_probe, + .remove = msm_dai_q6_dai_mi2s_remove, + }, + { + .playback = { + .stream_name = "Tertiary MI2S Playback", + .aif_name = "TERT_MI2S_RX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .capture = { + .stream_name = "Tertiary MI2S Capture", + .aif_name = "TERT_MI2S_TX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_mi2s_ops, + .id = MSM_TERT_MI2S, + .probe = msm_dai_q6_dai_mi2s_probe, + .remove = msm_dai_q6_dai_mi2s_remove, + }, + { + .playback = { + .stream_name = "Quaternary MI2S Playback", + .aif_name = "QUAT_MI2S_RX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .capture = { + .stream_name = "Quaternary MI2S Capture", + .aif_name = "QUAT_MI2S_TX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_mi2s_ops, + .id = MSM_QUAT_MI2S, + .probe = msm_dai_q6_dai_mi2s_probe, + .remove = msm_dai_q6_dai_mi2s_remove, + }, + { + .playback = { + .stream_name = "Secondary MI2S Playback SD1", + .aif_name = "SEC_MI2S_RX_SD1", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .id = MSM_SEC_MI2S_SD1, + }, + { + .playback = { + .stream_name = "Quinary MI2S Playback", + .aif_name = "QUIN_MI2S_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .capture = { + .stream_name = "Quinary MI2S Capture", + .aif_name = "QUIN_MI2S_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_mi2s_ops, + .id = MSM_QUIN_MI2S, + .probe = msm_dai_q6_dai_mi2s_probe, + .remove = msm_dai_q6_dai_mi2s_remove, + }, + { + .capture = { + .stream_name = "Senary_mi2s Capture", + .aif_name = "SENARY_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_mi2s_ops, + .id = MSM_SENARY_MI2S, + .probe = msm_dai_q6_dai_mi2s_probe, + .remove = msm_dai_q6_dai_mi2s_remove, + }, + { + .playback = { + .stream_name = "INT0 MI2S Playback", + .aif_name = "INT0_MI2S_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .capture = { + .stream_name = "INT0 MI2S Capture", + .aif_name = "INT0_MI2S_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_mi2s_ops, + .id = MSM_INT0_MI2S, + .probe = msm_dai_q6_dai_mi2s_probe, + .remove = msm_dai_q6_dai_mi2s_remove, + }, + { + .playback = { + .stream_name = "INT1 MI2S Playback", + .aif_name = "INT1_MI2S_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "INT1 MI2S Capture", + .aif_name = "INT1_MI2S_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_mi2s_ops, + .id = MSM_INT1_MI2S, + .probe = msm_dai_q6_dai_mi2s_probe, + .remove = msm_dai_q6_dai_mi2s_remove, + }, + { + .playback = { + .stream_name = "INT2 MI2S Playback", + .aif_name = "INT2_MI2S_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "INT2 MI2S Capture", + .aif_name = "INT2_MI2S_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_mi2s_ops, + .id = MSM_INT2_MI2S, + .probe = msm_dai_q6_dai_mi2s_probe, + .remove = msm_dai_q6_dai_mi2s_remove, + }, + { + .playback = { + .stream_name = "INT3 MI2S Playback", + .aif_name = "INT3_MI2S_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "INT3 MI2S Capture", + .aif_name = "INT3_MI2S_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_mi2s_ops, + .id = MSM_INT3_MI2S, + .probe = msm_dai_q6_dai_mi2s_probe, + .remove = msm_dai_q6_dai_mi2s_remove, + }, + { + .playback = { + .stream_name = "INT4 MI2S Playback", + .aif_name = "INT4_MI2S_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .capture = { + .stream_name = "INT4 MI2S Capture", + .aif_name = "INT4_MI2S_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_mi2s_ops, + .id = MSM_INT4_MI2S, + .probe = msm_dai_q6_dai_mi2s_probe, + .remove = msm_dai_q6_dai_mi2s_remove, + }, + { + .playback = { + .stream_name = "INT5 MI2S Playback", + .aif_name = "INT5_MI2S_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "INT5 MI2S Capture", + .aif_name = "INT5_MI2S_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_mi2s_ops, + .id = MSM_INT5_MI2S, + .probe = msm_dai_q6_dai_mi2s_probe, + .remove = msm_dai_q6_dai_mi2s_remove, + }, + { + .playback = { + .stream_name = "INT6 MI2S Playback", + .aif_name = "INT6_MI2S_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .capture = { + .stream_name = "INT6 MI2S Capture", + .aif_name = "INT6_MI2S_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_mi2s_ops, + .id = MSM_INT6_MI2S, + .probe = msm_dai_q6_dai_mi2s_probe, + .remove = msm_dai_q6_dai_mi2s_remove, + }, +}; + + +static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr, + unsigned int *ch_cnt) +{ + u8 num_of_sd_lines; + + num_of_sd_lines = num_of_bits_set(sd_lines); + switch (num_of_sd_lines) { + case 0: + pr_debug("%s: no line is assigned\n", __func__); + break; + case 1: + switch (sd_lines) { + case MSM_MI2S_SD0: + *config_ptr = AFE_PORT_I2S_SD0; + break; + case MSM_MI2S_SD1: + *config_ptr = AFE_PORT_I2S_SD1; + break; + case MSM_MI2S_SD2: + *config_ptr = AFE_PORT_I2S_SD2; + break; + case MSM_MI2S_SD3: + *config_ptr = AFE_PORT_I2S_SD3; + break; + default: + pr_err("%s: invalid SD lines %d\n", + __func__, sd_lines); + goto error_invalid_data; + } + break; + case 2: + switch (sd_lines) { + case MSM_MI2S_SD0 | MSM_MI2S_SD1: + *config_ptr = AFE_PORT_I2S_QUAD01; + break; + case MSM_MI2S_SD2 | MSM_MI2S_SD3: + *config_ptr = AFE_PORT_I2S_QUAD23; + break; + default: + pr_err("%s: invalid SD lines %d\n", + __func__, sd_lines); + goto error_invalid_data; + } + break; + case 3: + switch (sd_lines) { + case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2: + *config_ptr = AFE_PORT_I2S_6CHS; + break; + default: + pr_err("%s: invalid SD lines %d\n", + __func__, sd_lines); + goto error_invalid_data; + } + break; + case 4: + switch (sd_lines) { + case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3: + *config_ptr = AFE_PORT_I2S_8CHS; + break; + default: + pr_err("%s: invalid SD lines %d\n", + __func__, sd_lines); + goto error_invalid_data; + } + break; + default: + pr_err("%s: invalid SD lines %d\n", __func__, num_of_sd_lines); + goto error_invalid_data; + } + *ch_cnt = num_of_sd_lines; + return 0; + +error_invalid_data: + pr_err("%s: invalid data\n", __func__); + return -EINVAL; +} + +static int msm_dai_q6_mi2s_platform_data_validation( + struct platform_device *pdev, struct snd_soc_dai_driver *dai_driver) +{ + struct msm_dai_q6_mi2s_dai_data *dai_data = dev_get_drvdata(&pdev->dev); + struct msm_mi2s_pdata *mi2s_pdata = + (struct msm_mi2s_pdata *) pdev->dev.platform_data; + unsigned int ch_cnt; + int rc = 0; + u16 sd_line; + + if (mi2s_pdata == NULL) { + pr_err("%s: mi2s_pdata NULL", __func__); + return -EINVAL; + } + + rc = msm_dai_q6_mi2s_get_lineconfig(mi2s_pdata->rx_sd_lines, + &sd_line, &ch_cnt); + if (rc < 0) { + dev_err(&pdev->dev, "invalid MI2S RX sd line config\n"); + goto rtn; + } + + if (ch_cnt) { + dai_data->rx_dai.mi2s_dai_data.port_config.i2s.channel_mode = + sd_line; + dai_data->rx_dai.pdata_mi2s_lines = sd_line; + dai_driver->playback.channels_min = 1; + dai_driver->playback.channels_max = ch_cnt << 1; + } else { + dai_driver->playback.channels_min = 0; + dai_driver->playback.channels_max = 0; + } + rc = msm_dai_q6_mi2s_get_lineconfig(mi2s_pdata->tx_sd_lines, + &sd_line, &ch_cnt); + if (rc < 0) { + dev_err(&pdev->dev, "invalid MI2S TX sd line config\n"); + goto rtn; + } + + if (ch_cnt) { + dai_data->tx_dai.mi2s_dai_data.port_config.i2s.channel_mode = + sd_line; + dai_data->tx_dai.pdata_mi2s_lines = sd_line; + dai_driver->capture.channels_min = 1; + dai_driver->capture.channels_max = ch_cnt << 1; + } else { + dai_driver->capture.channels_min = 0; + dai_driver->capture.channels_max = 0; + } + + dev_dbg(&pdev->dev, "%s: playback sdline 0x%x capture sdline 0x%x\n", + __func__, dai_data->rx_dai.pdata_mi2s_lines, + dai_data->tx_dai.pdata_mi2s_lines); + dev_dbg(&pdev->dev, "%s: playback ch_max %d capture ch_mx %d\n", + __func__, dai_driver->playback.channels_max, + dai_driver->capture.channels_max); +rtn: + return rc; +} + +static const struct snd_soc_component_driver msm_q6_mi2s_dai_component = { + .name = "msm-dai-q6-mi2s", +}; +static int msm_dai_q6_mi2s_dev_probe(struct platform_device *pdev) +{ + struct msm_dai_q6_mi2s_dai_data *dai_data; + const char *q6_mi2s_dev_id = "qcom,msm-dai-q6-mi2s-dev-id"; + u32 tx_line = 0; + u32 rx_line = 0; + u32 mi2s_intf = 0; + struct msm_mi2s_pdata *mi2s_pdata; + int rc; + + rc = of_property_read_u32(pdev->dev.of_node, q6_mi2s_dev_id, + &mi2s_intf); + if (rc) { + dev_err(&pdev->dev, + "%s: missing 0x%x in dt node\n", __func__, mi2s_intf); + goto rtn; + } + + dev_dbg(&pdev->dev, "dev name %s dev id 0x%x\n", dev_name(&pdev->dev), + mi2s_intf); + + if ((mi2s_intf < MSM_MI2S_MIN || mi2s_intf > MSM_MI2S_MAX) + || (mi2s_intf >= ARRAY_SIZE(msm_dai_q6_mi2s_dai))) { + dev_err(&pdev->dev, + "%s: Invalid MI2S ID %u from Device Tree\n", + __func__, mi2s_intf); + rc = -ENXIO; + goto rtn; + } + + pdev->id = mi2s_intf; + + mi2s_pdata = kzalloc(sizeof(struct msm_mi2s_pdata), GFP_KERNEL); + if (!mi2s_pdata) { + rc = -ENOMEM; + goto rtn; + } + + rc = of_property_read_u32(pdev->dev.of_node, "qcom,msm-mi2s-rx-lines", + &rx_line); + if (rc) { + dev_err(&pdev->dev, "%s: Rx line from DT file %s\n", __func__, + "qcom,msm-mi2s-rx-lines"); + goto free_pdata; + } + + rc = of_property_read_u32(pdev->dev.of_node, "qcom,msm-mi2s-tx-lines", + &tx_line); + if (rc) { + dev_err(&pdev->dev, "%s: Tx line from DT file %s\n", __func__, + "qcom,msm-mi2s-tx-lines"); + goto free_pdata; + } + dev_dbg(&pdev->dev, "dev name %s Rx line 0x%x , Tx ine 0x%x\n", + dev_name(&pdev->dev), rx_line, tx_line); + mi2s_pdata->rx_sd_lines = rx_line; + mi2s_pdata->tx_sd_lines = tx_line; + mi2s_pdata->intf_id = mi2s_intf; + + dai_data = kzalloc(sizeof(struct msm_dai_q6_mi2s_dai_data), + GFP_KERNEL); + if (!dai_data) { + rc = -ENOMEM; + goto free_pdata; + } else + dev_set_drvdata(&pdev->dev, dai_data); + + pdev->dev.platform_data = mi2s_pdata; + + rc = msm_dai_q6_mi2s_platform_data_validation(pdev, + &msm_dai_q6_mi2s_dai[mi2s_intf]); + if (rc < 0) + goto free_dai_data; + + rc = snd_soc_register_component(&pdev->dev, &msm_q6_mi2s_dai_component, + &msm_dai_q6_mi2s_dai[mi2s_intf], 1); + if (rc < 0) + goto err_register; + return 0; + +err_register: + dev_err(&pdev->dev, "fail to msm_dai_q6_mi2s_dev_probe\n"); +free_dai_data: + kfree(dai_data); +free_pdata: + kfree(mi2s_pdata); +rtn: + return rc; +} + +static int msm_dai_q6_mi2s_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_component(&pdev->dev); + return 0; +} + +static const struct snd_soc_component_driver msm_dai_q6_component = { + .name = "msm-dai-q6-dev", +}; + +static int msm_dai_q6_dev_probe(struct platform_device *pdev) +{ + int rc, id, i, len; + const char *q6_dev_id = "qcom,msm-dai-q6-dev-id"; + char stream_name[80]; + + rc = of_property_read_u32(pdev->dev.of_node, q6_dev_id, &id); + if (rc) { + dev_err(&pdev->dev, + "%s: missing %s in dt node\n", __func__, q6_dev_id); + return rc; + } + + pdev->id = id; + + pr_debug("%s: dev name %s, id:%d\n", __func__, + dev_name(&pdev->dev), pdev->id); + + switch (id) { + case SLIMBUS_0_RX: + strlcpy(stream_name, "Slimbus Playback", 80); + goto register_slim_playback; + case SLIMBUS_2_RX: + strlcpy(stream_name, "Slimbus2 Playback", 80); + goto register_slim_playback; + case SLIMBUS_1_RX: + strlcpy(stream_name, "Slimbus1 Playback", 80); + goto register_slim_playback; + case SLIMBUS_3_RX: + strlcpy(stream_name, "Slimbus3 Playback", 80); + goto register_slim_playback; + case SLIMBUS_4_RX: + strlcpy(stream_name, "Slimbus4 Playback", 80); + goto register_slim_playback; + case SLIMBUS_5_RX: + strlcpy(stream_name, "Slimbus5 Playback", 80); + goto register_slim_playback; + case SLIMBUS_6_RX: + strlcpy(stream_name, "Slimbus6 Playback", 80); + goto register_slim_playback; + case SLIMBUS_7_RX: + strlcpy(stream_name, "Slimbus7 Playback", sizeof(stream_name)); + goto register_slim_playback; + case SLIMBUS_8_RX: + strlcpy(stream_name, "Slimbus8 Playback", sizeof(stream_name)); + goto register_slim_playback; +register_slim_playback: + rc = -ENODEV; + len = strnlen(stream_name, 80); + for (i = 0; i < ARRAY_SIZE(msm_dai_q6_slimbus_rx_dai); i++) { + if (msm_dai_q6_slimbus_rx_dai[i].playback.stream_name && + !strcmp(stream_name, + msm_dai_q6_slimbus_rx_dai[i] + .playback.stream_name)) { + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, + &msm_dai_q6_slimbus_rx_dai[i], 1); + break; + } + } + if (rc) + pr_err("%s: Device not found stream name %s\n", + __func__, stream_name); + break; + case SLIMBUS_0_TX: + strlcpy(stream_name, "Slimbus Capture", 80); + goto register_slim_capture; + case SLIMBUS_1_TX: + strlcpy(stream_name, "Slimbus1 Capture", 80); + goto register_slim_capture; + case SLIMBUS_2_TX: + strlcpy(stream_name, "Slimbus2 Capture", 80); + goto register_slim_capture; + case SLIMBUS_3_TX: + strlcpy(stream_name, "Slimbus3 Capture", 80); + goto register_slim_capture; + case SLIMBUS_4_TX: + strlcpy(stream_name, "Slimbus4 Capture", 80); + goto register_slim_capture; + case SLIMBUS_5_TX: + strlcpy(stream_name, "Slimbus5 Capture", 80); + goto register_slim_capture; + case SLIMBUS_6_TX: + strlcpy(stream_name, "Slimbus6 Capture", 80); + goto register_slim_capture; + case SLIMBUS_7_TX: + strlcpy(stream_name, "Slimbus7 Capture", sizeof(stream_name)); + goto register_slim_capture; + case SLIMBUS_8_TX: + strlcpy(stream_name, "Slimbus8 Capture", sizeof(stream_name)); + goto register_slim_capture; +register_slim_capture: + rc = -ENODEV; + len = strnlen(stream_name, 80); + for (i = 0; i < ARRAY_SIZE(msm_dai_q6_slimbus_tx_dai); i++) { + if (msm_dai_q6_slimbus_tx_dai[i].capture.stream_name && + !strcmp(stream_name, + msm_dai_q6_slimbus_tx_dai[i] + .capture.stream_name)) { + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, + &msm_dai_q6_slimbus_tx_dai[i], 1); + break; + } + } + if (rc) + pr_err("%s: Device not found stream name %s\n", + __func__, stream_name); + break; + case INT_BT_SCO_RX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, &msm_dai_q6_bt_sco_rx_dai, 1); + break; + case INT_BT_SCO_TX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, &msm_dai_q6_bt_sco_tx_dai, 1); + break; + case INT_BT_A2DP_RX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, &msm_dai_q6_bt_a2dp_rx_dai, 1); + break; + case INT_FM_RX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, &msm_dai_q6_fm_rx_dai, 1); + break; + case INT_FM_TX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, &msm_dai_q6_fm_tx_dai, 1); + break; + case AFE_PORT_ID_USB_RX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, &msm_dai_q6_usb_rx_dai, 1); + break; + case AFE_PORT_ID_USB_TX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, &msm_dai_q6_usb_tx_dai, 1); + break; + case RT_PROXY_DAI_001_RX: + strlcpy(stream_name, "AFE Playback", 80); + goto register_afe_playback; + case RT_PROXY_DAI_002_RX: + strlcpy(stream_name, "AFE-PROXY RX", 80); +register_afe_playback: + rc = -ENODEV; + len = strnlen(stream_name, 80); + for (i = 0; i < ARRAY_SIZE(msm_dai_q6_afe_rx_dai); i++) { + if (msm_dai_q6_afe_rx_dai[i].playback.stream_name && + !strcmp(stream_name, + msm_dai_q6_afe_rx_dai[i].playback.stream_name)) { + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, + &msm_dai_q6_afe_rx_dai[i], 1); + break; + } + } + if (rc) + pr_err("%s: Device not found stream name %s\n", + __func__, stream_name); + break; + case RT_PROXY_DAI_001_TX: + strlcpy(stream_name, "AFE-PROXY TX", 80); + goto register_afe_capture; + case RT_PROXY_DAI_002_TX: + strlcpy(stream_name, "AFE Capture", 80); +register_afe_capture: + rc = -ENODEV; + len = strnlen(stream_name, 80); + for (i = 0; i < ARRAY_SIZE(msm_dai_q6_afe_tx_dai); i++) { + if (msm_dai_q6_afe_tx_dai[i].capture.stream_name && + !strcmp(stream_name, + msm_dai_q6_afe_tx_dai[i].capture.stream_name)) { + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, + &msm_dai_q6_afe_tx_dai[i], 1); + break; + } + } + if (rc) + pr_err("%s: Device not found stream name %s\n", + __func__, stream_name); + break; + case VOICE_PLAYBACK_TX: + strlcpy(stream_name, "Voice Farend Playback", 80); + goto register_voice_playback; + case VOICE2_PLAYBACK_TX: + strlcpy(stream_name, "Voice2 Farend Playback", 80); +register_voice_playback: + rc = -ENODEV; + len = strnlen(stream_name, 80); + for (i = 0; i < ARRAY_SIZE(msm_dai_q6_voc_playback_dai); i++) { + if (msm_dai_q6_voc_playback_dai[i].playback.stream_name + && !strcmp(stream_name, + msm_dai_q6_voc_playback_dai[i].playback.stream_name)) { + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, + &msm_dai_q6_voc_playback_dai[i], 1); + break; + } + } + if (rc) + pr_err("%s Device not found stream name %s\n", + __func__, stream_name); + break; + case VOICE_RECORD_RX: + strlcpy(stream_name, "Voice Downlink Capture", 80); + goto register_uplink_capture; + case VOICE_RECORD_TX: + strlcpy(stream_name, "Voice Uplink Capture", 80); +register_uplink_capture: + rc = -ENODEV; + len = strnlen(stream_name, 80); + for (i = 0; i < ARRAY_SIZE(msm_dai_q6_incall_record_dai); i++) { + if (msm_dai_q6_incall_record_dai[i].capture.stream_name + && !strcmp(stream_name, + msm_dai_q6_incall_record_dai[i]. + capture.stream_name)) { + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, + &msm_dai_q6_incall_record_dai[i], 1); + break; + } + } + if (rc) + pr_err("%s: Device not found stream name %s\n", + __func__, stream_name); + break; + + default: + rc = -ENODEV; + break; + } + + return rc; +} + +static int msm_dai_q6_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_component(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_dai_q6_dev_dt_match[] = { + { .compatible = "qcom,msm-dai-q6-dev", }, + { } +}; +MODULE_DEVICE_TABLE(of, msm_dai_q6_dev_dt_match); + +static struct platform_driver msm_dai_q6_dev = { + .probe = msm_dai_q6_dev_probe, + .remove = msm_dai_q6_dev_remove, + .driver = { + .name = "msm-dai-q6-dev", + .owner = THIS_MODULE, + .of_match_table = msm_dai_q6_dev_dt_match, + }, +}; + +static int msm_dai_q6_probe(struct platform_device *pdev) +{ + int rc; + + pr_debug("%s: dev name %s, id:%d\n", __func__, + dev_name(&pdev->dev), pdev->id); + rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); + if (rc) { + dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n", + __func__, rc); + } else + dev_dbg(&pdev->dev, "%s: added child node\n", __func__); + + return rc; +} + +static int msm_dai_q6_remove(struct platform_device *pdev) +{ + return 0; +} + +static const struct of_device_id msm_dai_q6_dt_match[] = { + { .compatible = "qcom,msm-dai-q6", }, + { } +}; +MODULE_DEVICE_TABLE(of, msm_dai_q6_dt_match); +static struct platform_driver msm_dai_q6 = { + .probe = msm_dai_q6_probe, + .remove = msm_dai_q6_remove, + .driver = { + .name = "msm-dai-q6", + .owner = THIS_MODULE, + .of_match_table = msm_dai_q6_dt_match, + }, +}; + +static int msm_dai_mi2s_q6_probe(struct platform_device *pdev) +{ + int rc; + + rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); + if (rc) { + dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n", + __func__, rc); + } else + dev_dbg(&pdev->dev, "%s: added child node\n", __func__); + return rc; +} + +static int msm_dai_mi2s_q6_remove(struct platform_device *pdev) +{ + return 0; +} + +static const struct of_device_id msm_dai_mi2s_dt_match[] = { + { .compatible = "qcom,msm-dai-mi2s", }, + { } +}; + +MODULE_DEVICE_TABLE(of, msm_dai_mi2s_dt_match); + +static struct platform_driver msm_dai_mi2s_q6 = { + .probe = msm_dai_mi2s_q6_probe, + .remove = msm_dai_mi2s_q6_remove, + .driver = { + .name = "msm-dai-mi2s", + .owner = THIS_MODULE, + .of_match_table = msm_dai_mi2s_dt_match, + }, +}; + +static const struct of_device_id msm_dai_q6_mi2s_dev_dt_match[] = { + { .compatible = "qcom,msm-dai-q6-mi2s", }, + { } +}; + +MODULE_DEVICE_TABLE(of, msm_dai_q6_mi2s_dev_dt_match); + +static struct platform_driver msm_dai_q6_mi2s_driver = { + .probe = msm_dai_q6_mi2s_dev_probe, + .remove = msm_dai_q6_mi2s_dev_remove, + .driver = { + .name = "msm-dai-q6-mi2s", + .owner = THIS_MODULE, + .of_match_table = msm_dai_q6_mi2s_dev_dt_match, + }, +}; + +static int msm_dai_q6_spdif_dev_probe(struct platform_device *pdev) +{ + int rc; + + pdev->id = AFE_PORT_ID_SPDIF_RX; + + pr_debug("%s: dev name %s, id:%d\n", __func__, + dev_name(&pdev->dev), pdev->id); + + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_spdif_q6_component, + &msm_dai_q6_spdif_spdif_rx_dai, 1); + return rc; +} + +static int msm_dai_q6_spdif_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_component(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_dai_q6_spdif_dt_match[] = { + {.compatible = "qcom,msm-dai-q6-spdif"}, + {} +}; +MODULE_DEVICE_TABLE(of, msm_dai_q6_spdif_dt_match); + +static struct platform_driver msm_dai_q6_spdif_driver = { + .probe = msm_dai_q6_spdif_dev_probe, + .remove = msm_dai_q6_spdif_dev_remove, + .driver = { + .name = "msm-dai-q6-spdif", + .owner = THIS_MODULE, + .of_match_table = msm_dai_q6_spdif_dt_match, + }, +}; + +static int msm_dai_q6_tdm_set_clk_param(u32 group_id, + struct afe_clk_set *clk_set, u32 mode) +{ + switch (group_id) { + case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX: + case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX: + if (mode) + clk_set->clk_id = Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT; + else + clk_set->clk_id = Q6AFE_LPASS_CLK_ID_PRI_TDM_EBIT; + break; + case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_RX: + case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_TX: + if (mode) + clk_set->clk_id = Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT; + else + clk_set->clk_id = Q6AFE_LPASS_CLK_ID_SEC_TDM_EBIT; + break; + case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_RX: + case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_TX: + if (mode) + clk_set->clk_id = Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT; + else + clk_set->clk_id = Q6AFE_LPASS_CLK_ID_TER_TDM_EBIT; + break; + case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_RX: + case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_TX: + if (mode) + clk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT; + else + clk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUAD_TDM_EBIT; + break; + default: + return -EINVAL; + } + return 0; +} + +static int msm_dai_tdm_q6_probe(struct platform_device *pdev) +{ + int rc = 0; + const uint32_t *port_id_array = NULL; + uint32_t array_length = 0; + int i = 0; + int group_idx = 0; + u32 clk_mode = 0; + + /* extract tdm group info into static */ + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-group-id", + (u32 *)&tdm_group_cfg.group_id); + if (rc) { + dev_err(&pdev->dev, "%s: Group ID from DT file %s\n", + __func__, "qcom,msm-cpudai-tdm-group-id"); + goto rtn; + } + dev_dbg(&pdev->dev, "%s: Group ID from DT file 0x%x\n", + __func__, tdm_group_cfg.group_id); + + dev_info(&pdev->dev, "%s: dev_name: %s group_id: 0x%x\n", + __func__, dev_name(&pdev->dev), tdm_group_cfg.group_id); + + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-group-num-ports", + &num_tdm_group_ports); + if (rc) { + dev_err(&pdev->dev, "%s: Group Num Ports from DT file %s\n", + __func__, "qcom,msm-cpudai-tdm-group-num-ports"); + goto rtn; + } + dev_dbg(&pdev->dev, "%s: Group Num Ports from DT file 0x%x\n", + __func__, num_tdm_group_ports); + + if (num_tdm_group_ports > AFE_GROUP_DEVICE_NUM_PORTS) { + dev_err(&pdev->dev, "%s Group Num Ports %d greater than Max %d\n", + __func__, num_tdm_group_ports, + AFE_GROUP_DEVICE_NUM_PORTS); + rc = -EINVAL; + goto rtn; + } + + port_id_array = of_get_property(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-group-port-id", + &array_length); + if (port_id_array == NULL) { + dev_err(&pdev->dev, "%s port_id_array is not valid\n", + __func__); + rc = -EINVAL; + goto rtn; + } + if (array_length != sizeof(uint32_t) * num_tdm_group_ports) { + dev_err(&pdev->dev, "%s array_length is %d, expected is %zd\n", + __func__, array_length, + sizeof(uint32_t) * num_tdm_group_ports); + rc = -EINVAL; + goto rtn; + } + + for (i = 0; i < num_tdm_group_ports; i++) + tdm_group_cfg.port_id[i] = + (u16)be32_to_cpu(port_id_array[i]); + /* Unused index should be filled with 0 or AFE_PORT_INVALID */ + for (i = num_tdm_group_ports; i < AFE_GROUP_DEVICE_NUM_PORTS; i++) + tdm_group_cfg.port_id[i] = + AFE_PORT_INVALID; + + /* extract tdm clk info into static */ + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-clk-rate", + &tdm_clk_set.clk_freq_in_hz); + if (rc) { + dev_err(&pdev->dev, "%s: Clk Rate from DT file %s\n", + __func__, "qcom,msm-cpudai-tdm-clk-rate"); + goto rtn; + } + dev_dbg(&pdev->dev, "%s: Clk Rate from DT file %d\n", + __func__, tdm_clk_set.clk_freq_in_hz); + + /* extract tdm clk src master/slave info into static */ + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-clk-internal", + &clk_mode); + if (rc) { + dev_err(&pdev->dev, "%s: Clk id from DT file %s\n", + __func__, "qcom,msm-cpudai-tdm-clk-internal"); + goto rtn; + } + dev_dbg(&pdev->dev, "%s: Clk id from DT file %d\n", + __func__, clk_mode); + + rc = msm_dai_q6_tdm_set_clk_param(tdm_group_cfg.group_id, + &tdm_clk_set, clk_mode); + if (rc) { + dev_err(&pdev->dev, "%s: group id not supported 0x%x\n", + __func__, tdm_group_cfg.group_id); + goto rtn; + } + + /* other initializations within device group */ + group_idx = msm_dai_q6_get_group_idx(tdm_group_cfg.group_id); + if (group_idx < 0) { + dev_err(&pdev->dev, "%s: group id 0x%x not supported\n", + __func__, tdm_group_cfg.group_id); + rc = -EINVAL; + goto rtn; + } + atomic_set(&tdm_group_ref[group_idx], 0); + + /* probe child node info */ + rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); + if (rc) { + dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n", + __func__, rc); + goto rtn; + } else + dev_dbg(&pdev->dev, "%s: added child node\n", __func__); + +rtn: + return rc; +} + +static int msm_dai_tdm_q6_remove(struct platform_device *pdev) +{ + return 0; +} + +static const struct of_device_id msm_dai_tdm_dt_match[] = { + { .compatible = "qcom,msm-dai-tdm", }, + {} +}; + +MODULE_DEVICE_TABLE(of, msm_dai_tdm_dt_match); + +static struct platform_driver msm_dai_tdm_q6 = { + .probe = msm_dai_tdm_q6_probe, + .remove = msm_dai_tdm_q6_remove, + .driver = { + .name = "msm-dai-tdm", + .owner = THIS_MODULE, + .of_match_table = msm_dai_tdm_dt_match, + }, +}; + +static int msm_dai_q6_tdm_data_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data; + int value = ucontrol->value.integer.value[0]; + + switch (value) { + case 0: + dai_data->port_cfg.tdm.data_format = AFE_LINEAR_PCM_DATA; + break; + case 1: + dai_data->port_cfg.tdm.data_format = AFE_NON_LINEAR_DATA; + break; + case 2: + dai_data->port_cfg.tdm.data_format = AFE_GENERIC_COMPRESSED; + break; + default: + pr_err("%s: data_format invalid\n", __func__); + break; + } + pr_debug("%s: data_format = %d\n", + __func__, dai_data->port_cfg.tdm.data_format); + return 0; +} + +static int msm_dai_q6_tdm_data_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data; + + ucontrol->value.integer.value[0] = + dai_data->port_cfg.tdm.data_format; + pr_debug("%s: data_format = %d\n", + __func__, dai_data->port_cfg.tdm.data_format); + return 0; +} + +static int msm_dai_q6_tdm_header_type_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data; + int value = ucontrol->value.integer.value[0]; + + dai_data->port_cfg.custom_tdm_header.header_type = value; + pr_debug("%s: header_type = %d\n", + __func__, + dai_data->port_cfg.custom_tdm_header.header_type); + return 0; +} + +static int msm_dai_q6_tdm_header_type_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data; + + ucontrol->value.integer.value[0] = + dai_data->port_cfg.custom_tdm_header.header_type; + pr_debug("%s: header_type = %d\n", + __func__, + dai_data->port_cfg.custom_tdm_header.header_type); + return 0; +} + +static int msm_dai_q6_tdm_header_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data; + int i = 0; + + for (i = 0; i < AFE_CUSTOM_TDM_HEADER_MAX_CNT; i++) { + dai_data->port_cfg.custom_tdm_header.header[i] = + (u16)ucontrol->value.integer.value[i]; + pr_debug("%s: header #%d = 0x%x\n", + __func__, i, + dai_data->port_cfg.custom_tdm_header.header[i]); + } + return 0; +} + +static int msm_dai_q6_tdm_header_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data; + int i = 0; + + for (i = 0; i < AFE_CUSTOM_TDM_HEADER_MAX_CNT; i++) { + ucontrol->value.integer.value[i] = + dai_data->port_cfg.custom_tdm_header.header[i]; + pr_debug("%s: header #%d = 0x%x\n", + __func__, i, + dai_data->port_cfg.custom_tdm_header.header[i]); + } + return 0; +} + +static const struct snd_kcontrol_new tdm_config_controls_data_format[] = { + SOC_ENUM_EXT("PRI_TDM_RX_0 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_1 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_2 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_3 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_4 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_5 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_6 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_7 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_1 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_2 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_3 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_4 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_5 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_6 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_7 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_1 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_2 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_3 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_4 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_5 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_6 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_7 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_1 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_2 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_3 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_4 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_5 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_6 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_7 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_1 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_2 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_3 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_4 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_5 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_6 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_7 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_1 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_2 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_3 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_4 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_5 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_6 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_7 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_1 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_2 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_3 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_4 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_5 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_6 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_7 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_1 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_2 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_3 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_4 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_5 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_6 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_7 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), +}; + +static const struct snd_kcontrol_new tdm_config_controls_header_type[] = { + SOC_ENUM_EXT("PRI_TDM_RX_0 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("PRI_TDM_RX_1 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("PRI_TDM_RX_2 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("PRI_TDM_RX_3 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("PRI_TDM_RX_4 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("PRI_TDM_RX_5 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("PRI_TDM_RX_6 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("PRI_TDM_RX_7 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("PRI_TDM_TX_1 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("PRI_TDM_TX_2 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("PRI_TDM_TX_3 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("PRI_TDM_TX_4 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("PRI_TDM_TX_5 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("PRI_TDM_TX_6 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("PRI_TDM_TX_7 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEC_TDM_RX_1 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEC_TDM_RX_2 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEC_TDM_RX_3 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEC_TDM_RX_4 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEC_TDM_RX_5 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEC_TDM_RX_6 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEC_TDM_RX_7 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEC_TDM_TX_1 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEC_TDM_TX_2 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEC_TDM_TX_3 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEC_TDM_TX_4 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEC_TDM_TX_5 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEC_TDM_TX_6 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEC_TDM_TX_7 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("TERT_TDM_RX_1 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("TERT_TDM_RX_2 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("TERT_TDM_RX_3 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("TERT_TDM_RX_4 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("TERT_TDM_RX_5 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("TERT_TDM_RX_6 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("TERT_TDM_RX_7 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("TERT_TDM_TX_1 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("TERT_TDM_TX_2 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("TERT_TDM_TX_3 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("TERT_TDM_TX_4 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("TERT_TDM_TX_5 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("TERT_TDM_TX_6 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("TERT_TDM_TX_7 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUAT_TDM_RX_1 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUAT_TDM_RX_2 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUAT_TDM_RX_3 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUAT_TDM_RX_4 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUAT_TDM_RX_5 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUAT_TDM_RX_6 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUAT_TDM_RX_7 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUAT_TDM_TX_1 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUAT_TDM_TX_2 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUAT_TDM_TX_3 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUAT_TDM_TX_4 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUAT_TDM_TX_5 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUAT_TDM_TX_6 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUAT_TDM_TX_7 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), +}; + +static const struct snd_kcontrol_new tdm_config_controls_header[] = { + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_0 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_1 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_2 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_3 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_4 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_5 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_6 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_7 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_0 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_1 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_2 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_3 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_4 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_5 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_6 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_7 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_0 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_1 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_2 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_3 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_4 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_5 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_6 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_7 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_0 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_1 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_2 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_3 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_4 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_5 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_6 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_7 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_0 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_1 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_2 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_3 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_4 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_5 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_6 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_7 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_0 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_1 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_2 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_3 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_4 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_5 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_6 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_7 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_0 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_1 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_2 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_3 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_4 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_5 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_6 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_7 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_0 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_1 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_2 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_3 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_4 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_5 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_6 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_7 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), +}; + +static int msm_dai_q6_tdm_set_clk( + struct msm_dai_q6_tdm_dai_data *dai_data, + u16 port_id, bool enable) +{ + int rc = 0; + + dai_data->clk_set.enable = enable; + + rc = afe_set_lpass_clock_v2(port_id, + &dai_data->clk_set); + if (rc < 0) + pr_err("%s: afe lpass clock failed, err:%d\n", + __func__, rc); + + return rc; +} + +static int msm_dai_q6_dai_tdm_probe(struct snd_soc_dai *dai) +{ + int rc = 0; + struct msm_dai_q6_tdm_dai_data *tdm_dai_data = + dev_get_drvdata(dai->dev); + struct snd_kcontrol *data_format_kcontrol = NULL; + struct snd_kcontrol *header_type_kcontrol = NULL; + struct snd_kcontrol *header_kcontrol = NULL; + int port_idx = 0; + const struct snd_kcontrol_new *data_format_ctrl = NULL; + const struct snd_kcontrol_new *header_type_ctrl = NULL; + const struct snd_kcontrol_new *header_ctrl = NULL; + + msm_dai_q6_set_dai_id(dai); + + port_idx = msm_dai_q6_get_port_idx(dai->id); + if (port_idx < 0) { + dev_err(dai->dev, "%s port id 0x%x not supported\n", + __func__, dai->id); + rc = -EINVAL; + goto rtn; + } + + data_format_ctrl = + &tdm_config_controls_data_format[port_idx]; + header_type_ctrl = + &tdm_config_controls_header_type[port_idx]; + header_ctrl = + &tdm_config_controls_header[port_idx]; + + if (data_format_ctrl) { + data_format_kcontrol = snd_ctl_new1(data_format_ctrl, + tdm_dai_data); + rc = snd_ctl_add(dai->component->card->snd_card, + data_format_kcontrol); + if (rc < 0) { + dev_err(dai->dev, "%s: err add data format ctrl DAI = %s\n", + __func__, dai->name); + goto rtn; + } + } + + if (header_type_ctrl) { + header_type_kcontrol = snd_ctl_new1(header_type_ctrl, + tdm_dai_data); + rc = snd_ctl_add(dai->component->card->snd_card, + header_type_kcontrol); + if (rc < 0) { + if (data_format_kcontrol) + snd_ctl_remove(dai->component->card->snd_card, + data_format_kcontrol); + dev_err(dai->dev, "%s: err add header type ctrl DAI = %s\n", + __func__, dai->name); + goto rtn; + } + } + + if (header_ctrl) { + header_kcontrol = snd_ctl_new1(header_ctrl, + tdm_dai_data); + rc = snd_ctl_add(dai->component->card->snd_card, + header_kcontrol); + if (rc < 0) { + if (header_type_kcontrol) + snd_ctl_remove(dai->component->card->snd_card, + header_type_kcontrol); + if (data_format_kcontrol) + snd_ctl_remove(dai->component->card->snd_card, + data_format_kcontrol); + dev_err(dai->dev, "%s: err add header ctrl DAI = %s\n", + __func__, dai->name); + goto rtn; + } + } + + rc = msm_dai_q6_dai_add_route(dai); + +rtn: + return rc; +} + + +static int msm_dai_q6_dai_tdm_remove(struct snd_soc_dai *dai) +{ + int rc = 0; + struct msm_dai_q6_tdm_dai_data *tdm_dai_data = + dev_get_drvdata(dai->dev); + u16 group_id = tdm_dai_data->group_cfg.tdm_cfg.group_id; + int group_idx = 0; + atomic_t *group_ref = NULL; + + group_idx = msm_dai_q6_get_group_idx(dai->id); + if (group_idx < 0) { + dev_err(dai->dev, "%s port id 0x%x not supported\n", + __func__, dai->id); + return -EINVAL; + } + + group_ref = &tdm_group_ref[group_idx]; + + /* If AFE port is still up, close it */ + if (test_bit(STATUS_PORT_STARTED, tdm_dai_data->status_mask)) { + rc = afe_close(dai->id); /* can block */ + if (rc < 0) { + dev_err(dai->dev, "%s: fail to close AFE port 0x%x\n", + __func__, dai->id); + } + atomic_dec(group_ref); + clear_bit(STATUS_PORT_STARTED, + tdm_dai_data->status_mask); + + if (atomic_read(group_ref) == 0) { + rc = afe_port_group_enable(group_id, + NULL, false); + if (rc < 0) { + dev_err(dai->dev, "fail to disable AFE group 0x%x\n", + group_id); + } + rc = msm_dai_q6_tdm_set_clk(tdm_dai_data, + dai->id, false); + if (rc < 0) { + dev_err(dai->dev, "%s: fail to disable AFE clk 0x%x\n", + __func__, dai->id); + } + } + } + + return 0; +} + +static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai, + unsigned int tx_mask, + unsigned int rx_mask, + int slots, int slot_width) +{ + int rc = 0; + struct msm_dai_q6_tdm_dai_data *dai_data = + dev_get_drvdata(dai->dev); + struct afe_param_id_group_device_tdm_cfg *tdm_group = + &dai_data->group_cfg.tdm_cfg; + unsigned int cap_mask; + + dev_dbg(dai->dev, "%s: dai id = 0x%x\n", __func__, dai->id); + + /* HW only supports 16 and 32 bit slot width configuration */ + if ((slot_width != 16) && (slot_width != 32)) { + dev_err(dai->dev, "%s: invalid slot_width %d\n", + __func__, slot_width); + return -EINVAL; + } + + /* HW only supports 16 and 8 slots configuration */ + switch (slots) { + case 2: + cap_mask = 0x03; + break; + case 8: + cap_mask = 0xFF; + break; + case 16: + cap_mask = 0xFFFF; + break; + default: + dev_err(dai->dev, "%s: invalid slots %d\n", + __func__, slots); + return -EINVAL; + } + + switch (dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + tdm_group->nslots_per_frame = slots; + tdm_group->slot_width = slot_width; + tdm_group->slot_mask = rx_mask & cap_mask; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + case AFE_PORT_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + case AFE_PORT_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + tdm_group->nslots_per_frame = slots; + tdm_group->slot_width = slot_width; + tdm_group->slot_mask = tx_mask & cap_mask; + break; + default: + dev_err(dai->dev, "%s: invalid dai id 0x%x\n", + __func__, dai->id); + return -EINVAL; + } + + return rc; +} + +static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot) +{ + int rc = 0; + struct msm_dai_q6_tdm_dai_data *dai_data = + dev_get_drvdata(dai->dev); + struct afe_param_id_slot_mapping_cfg *slot_mapping = + &dai_data->port_cfg.slot_mapping; + int i = 0; + + dev_dbg(dai->dev, "%s: dai id = 0x%x\n", __func__, dai->id); + + switch (dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + if (!rx_slot) { + dev_err(dai->dev, "%s: rx slot not found\n", __func__); + return -EINVAL; + } + if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) { + dev_err(dai->dev, "%s: invalid rx num %d\n", __func__, + rx_num); + return -EINVAL; + } + + for (i = 0; i < rx_num; i++) + slot_mapping->offset[i] = rx_slot[i]; + for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++) + slot_mapping->offset[i] = + AFE_SLOT_MAPPING_OFFSET_INVALID; + + slot_mapping->num_channel = rx_num; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + case AFE_PORT_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + case AFE_PORT_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + if (!tx_slot) { + dev_err(dai->dev, "%s: tx slot not found\n", __func__); + return -EINVAL; + } + if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) { + dev_err(dai->dev, "%s: invalid tx num %d\n", __func__, + tx_num); + return -EINVAL; + } + + for (i = 0; i < tx_num; i++) + slot_mapping->offset[i] = tx_slot[i]; + for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++) + slot_mapping->offset[i] = + AFE_SLOT_MAPPING_OFFSET_INVALID; + + slot_mapping->num_channel = tx_num; + break; + default: + dev_err(dai->dev, "%s: invalid dai id 0x%x\n", + __func__, dai->id); + return -EINVAL; + } + + return rc; +} + +static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_tdm_dai_data *dai_data = + dev_get_drvdata(dai->dev); + + struct afe_param_id_group_device_tdm_cfg *tdm_group = + &dai_data->group_cfg.tdm_cfg; + struct afe_param_id_tdm_cfg *tdm = + &dai_data->port_cfg.tdm; + struct afe_param_id_slot_mapping_cfg *slot_mapping = + &dai_data->port_cfg.slot_mapping; + struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header = + &dai_data->port_cfg.custom_tdm_header; + + pr_debug("%s: dev_name: %s\n", + __func__, dev_name(dai->dev)); + + if ((params_channels(params) == 0) || + (params_channels(params) > 8)) { + dev_err(dai->dev, "%s: invalid param channels %d\n", + __func__, params_channels(params)); + return -EINVAL; + } + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + dai_data->bitwidth = 16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + dai_data->bitwidth = 24; + break; + case SNDRV_PCM_FORMAT_S32_LE: + dai_data->bitwidth = 32; + break; + default: + dev_err(dai->dev, "%s: invalid param format 0x%x\n", + __func__, params_format(params)); + return -EINVAL; + } + dai_data->channels = params_channels(params); + dai_data->rate = params_rate(params); + + /* + * update tdm group config param + * NOTE: group config is set to the same as slot config. + */ + tdm_group->bit_width = tdm_group->slot_width; + tdm_group->num_channels = tdm_group->nslots_per_frame; + tdm_group->sample_rate = dai_data->rate; + + pr_debug("%s: TDM GROUP:\n" + "num_channels=%d sample_rate=%d bit_width=%d\n" + "nslots_per_frame=%d slot_width=%d slot_mask=0x%x\n", + __func__, + tdm_group->num_channels, + tdm_group->sample_rate, + tdm_group->bit_width, + tdm_group->nslots_per_frame, + tdm_group->slot_width, + tdm_group->slot_mask); + pr_debug("%s: TDM GROUP:\n" + "port_id[0]=0x%x port_id[1]=0x%x port_id[2]=0x%x port_id[3]=0x%x\n" + "port_id[4]=0x%x port_id[5]=0x%x port_id[6]=0x%x port_id[7]=0x%x\n", + __func__, + tdm_group->port_id[0], + tdm_group->port_id[1], + tdm_group->port_id[2], + tdm_group->port_id[3], + tdm_group->port_id[4], + tdm_group->port_id[5], + tdm_group->port_id[6], + tdm_group->port_id[7]); + + /* + * update tdm config param + * NOTE: channels/rate/bitwidth are per stream property + */ + tdm->num_channels = dai_data->channels; + tdm->sample_rate = dai_data->rate; + tdm->bit_width = dai_data->bitwidth; + /* + * port slot config is the same as group slot config + * port slot mask should be set according to offset + */ + tdm->nslots_per_frame = tdm_group->nslots_per_frame; + tdm->slot_width = tdm_group->slot_width; + tdm->slot_mask = tdm_group->slot_mask; + + pr_debug("%s: TDM:\n" + "num_channels=%d sample_rate=%d bit_width=%d\n" + "nslots_per_frame=%d slot_width=%d slot_mask=0x%x\n" + "data_format=0x%x sync_mode=0x%x sync_src=0x%x\n" + "data_out=0x%x invert_sync=0x%x data_delay=0x%x\n", + __func__, + tdm->num_channels, + tdm->sample_rate, + tdm->bit_width, + tdm->nslots_per_frame, + tdm->slot_width, + tdm->slot_mask, + tdm->data_format, + tdm->sync_mode, + tdm->sync_src, + tdm->ctrl_data_out_enable, + tdm->ctrl_invert_sync_pulse, + tdm->ctrl_sync_data_delay); + + /* + * update slot mapping config param + * NOTE: channels/rate/bitwidth are per stream property + */ + slot_mapping->bitwidth = dai_data->bitwidth; + + pr_debug("%s: SLOT MAPPING:\n" + "num_channel=%d bitwidth=%d data_align=0x%x\n", + __func__, + slot_mapping->num_channel, + slot_mapping->bitwidth, + slot_mapping->data_align_type); + pr_debug("%s: SLOT MAPPING:\n" + "offset[0]=0x%x offset[1]=0x%x offset[2]=0x%x offset[3]=0x%x\n" + "offset[4]=0x%x offset[5]=0x%x offset[6]=0x%x offset[7]=0x%x\n", + __func__, + slot_mapping->offset[0], + slot_mapping->offset[1], + slot_mapping->offset[2], + slot_mapping->offset[3], + slot_mapping->offset[4], + slot_mapping->offset[5], + slot_mapping->offset[6], + slot_mapping->offset[7]); + + /* + * update custom header config param + * NOTE: channels/rate/bitwidth are per playback stream property. + * custom tdm header only applicable to playback stream. + */ + if (custom_tdm_header->header_type != + AFE_CUSTOM_TDM_HEADER_TYPE_INVALID) { + pr_debug("%s: CUSTOM TDM HEADER:\n" + "start_offset=0x%x header_width=%d\n" + "num_frame_repeat=%d header_type=0x%x\n", + __func__, + custom_tdm_header->start_offset, + custom_tdm_header->header_width, + custom_tdm_header->num_frame_repeat, + custom_tdm_header->header_type); + pr_debug("%s: CUSTOM TDM HEADER:\n" + "header[0]=0x%x header[1]=0x%x header[2]=0x%x header[3]=0x%x\n" + "header[4]=0x%x header[5]=0x%x header[6]=0x%x header[7]=0x%x\n", + __func__, + custom_tdm_header->header[0], + custom_tdm_header->header[1], + custom_tdm_header->header[2], + custom_tdm_header->header[3], + custom_tdm_header->header[4], + custom_tdm_header->header[5], + custom_tdm_header->header[6], + custom_tdm_header->header[7]); + } + + return 0; +} + +static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + int rc = 0; + struct msm_dai_q6_tdm_dai_data *dai_data = + dev_get_drvdata(dai->dev); + u16 group_id = dai_data->group_cfg.tdm_cfg.group_id; + int group_idx = 0; + atomic_t *group_ref = NULL; + + group_idx = msm_dai_q6_get_group_idx(dai->id); + if (group_idx < 0) { + dev_err(dai->dev, "%s port id 0x%x not supported\n", + __func__, dai->id); + return -EINVAL; + } + + mutex_lock(&tdm_mutex); + + group_ref = &tdm_group_ref[group_idx]; + + if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + /* PORT START should be set if prepare called + * in active state. + */ + if (atomic_read(group_ref) == 0) { + /* TX and RX share the same clk. + * AFE clk is enabled per group to simplify the logic. + * DSP will monitor the clk count. + */ + rc = msm_dai_q6_tdm_set_clk(dai_data, + dai->id, true); + if (rc < 0) { + dev_err(dai->dev, "%s: fail to enable AFE clk 0x%x\n", + __func__, dai->id); + goto rtn; + } + + /* + * if only one port, don't do group enable as there + * is no group need for only one port + */ + if (dai_data->num_group_ports > 1) { + rc = afe_port_group_enable(group_id, + &dai_data->group_cfg, true); + if (rc < 0) { + dev_err(dai->dev, + "%s: fail to enable AFE group 0x%x\n", + __func__, group_id); + goto rtn; + } + } + } + + rc = afe_tdm_port_start(dai->id, &dai_data->port_cfg, + dai_data->rate, dai_data->num_group_ports); + if (rc < 0) { + if (atomic_read(group_ref) == 0) { + afe_port_group_enable(group_id, + NULL, false); + msm_dai_q6_tdm_set_clk(dai_data, + dai->id, false); + } + dev_err(dai->dev, "%s: fail to open AFE port 0x%x\n", + __func__, dai->id); + } else { + set_bit(STATUS_PORT_STARTED, + dai_data->status_mask); + atomic_inc(group_ref); + } + + /* TODO: need to monitor PCM/MI2S/TDM HW status */ + /* NOTE: AFE should error out if HW resource contention */ + + } + +rtn: + mutex_unlock(&tdm_mutex); + return rc; +} + +static void msm_dai_q6_tdm_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + int rc = 0; + struct msm_dai_q6_tdm_dai_data *dai_data = + dev_get_drvdata(dai->dev); + u16 group_id = dai_data->group_cfg.tdm_cfg.group_id; + int group_idx = 0; + atomic_t *group_ref = NULL; + + group_idx = msm_dai_q6_get_group_idx(dai->id); + if (group_idx < 0) { + dev_err(dai->dev, "%s port id 0x%x not supported\n", + __func__, dai->id); + return; + } + + mutex_lock(&tdm_mutex); + + group_ref = &tdm_group_ref[group_idx]; + + if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + rc = afe_close(dai->id); + if (rc < 0) { + dev_err(dai->dev, "%s: fail to close AFE port 0x%x\n", + __func__, dai->id); + } + atomic_dec(group_ref); + clear_bit(STATUS_PORT_STARTED, + dai_data->status_mask); + + if (atomic_read(group_ref) == 0) { + rc = afe_port_group_enable(group_id, + NULL, false); + if (rc < 0) { + dev_err(dai->dev, "%s: fail to disable AFE group 0x%x\n", + __func__, group_id); + } + rc = msm_dai_q6_tdm_set_clk(dai_data, + dai->id, false); + if (rc < 0) { + dev_err(dai->dev, "%s: fail to disable AFE clk 0x%x\n", + __func__, dai->id); + } + } + + /* TODO: need to monitor PCM/MI2S/TDM HW status */ + /* NOTE: AFE should error out if HW resource contention */ + + } + + mutex_unlock(&tdm_mutex); +} + +static struct snd_soc_dai_ops msm_dai_q6_tdm_ops = { + .prepare = msm_dai_q6_tdm_prepare, + .hw_params = msm_dai_q6_tdm_hw_params, + .set_tdm_slot = msm_dai_q6_tdm_set_tdm_slot, + .set_channel_map = msm_dai_q6_tdm_set_channel_map, + .shutdown = msm_dai_q6_tdm_shutdown, +}; + +static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { + { + .playback = { + .stream_name = "Primary TDM0 Playback", + .aif_name = "PRI_TDM_RX_0", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_PRIMARY_TDM_RX, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Primary TDM1 Playback", + .aif_name = "PRI_TDM_RX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_PRIMARY_TDM_RX_1, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Primary TDM2 Playback", + .aif_name = "PRI_TDM_RX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_PRIMARY_TDM_RX_2, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Primary TDM3 Playback", + .aif_name = "PRI_TDM_RX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_PRIMARY_TDM_RX_3, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Primary TDM4 Playback", + .aif_name = "PRI_TDM_RX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_PRIMARY_TDM_RX_4, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Primary TDM5 Playback", + .aif_name = "PRI_TDM_RX_5", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_PRIMARY_TDM_RX_5, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Primary TDM6 Playback", + .aif_name = "PRI_TDM_RX_6", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_PRIMARY_TDM_RX_6, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Primary TDM7 Playback", + .aif_name = "PRI_TDM_RX_7", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_PRIMARY_TDM_RX_7, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Primary TDM0 Capture", + .aif_name = "PRI_TDM_TX_0", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_PRIMARY_TDM_TX, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Primary TDM1 Capture", + .aif_name = "PRI_TDM_TX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_PRIMARY_TDM_TX_1, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Primary TDM2 Capture", + .aif_name = "PRI_TDM_TX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_PRIMARY_TDM_TX_2, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Primary TDM3 Capture", + .aif_name = "PRI_TDM_TX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_PRIMARY_TDM_TX_3, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Primary TDM4 Capture", + .aif_name = "PRI_TDM_TX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_PRIMARY_TDM_TX_4, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Primary TDM5 Capture", + .aif_name = "PRI_TDM_TX_5", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_PRIMARY_TDM_TX_5, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Primary TDM6 Capture", + .aif_name = "PRI_TDM_TX_6", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_PRIMARY_TDM_TX_6, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Primary TDM7 Capture", + .aif_name = "PRI_TDM_TX_7", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_PRIMARY_TDM_TX_7, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Secondary TDM0 Playback", + .aif_name = "SEC_TDM_RX_0", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SECONDARY_TDM_RX, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Secondary TDM1 Playback", + .aif_name = "SEC_TDM_RX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SECONDARY_TDM_RX_1, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Secondary TDM2 Playback", + .aif_name = "SEC_TDM_RX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SECONDARY_TDM_RX_2, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Secondary TDM3 Playback", + .aif_name = "SEC_TDM_RX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SECONDARY_TDM_RX_3, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Secondary TDM4 Playback", + .aif_name = "SEC_TDM_RX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SECONDARY_TDM_RX_4, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Secondary TDM5 Playback", + .aif_name = "SEC_TDM_RX_5", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SECONDARY_TDM_RX_5, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Secondary TDM6 Playback", + .aif_name = "SEC_TDM_RX_6", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SECONDARY_TDM_RX_6, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Secondary TDM7 Playback", + .aif_name = "SEC_TDM_RX_7", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SECONDARY_TDM_RX_7, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Secondary TDM0 Capture", + .aif_name = "SEC_TDM_TX_0", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SECONDARY_TDM_TX, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Secondary TDM1 Capture", + .aif_name = "SEC_TDM_TX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SECONDARY_TDM_TX_1, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Secondary TDM2 Capture", + .aif_name = "SEC_TDM_TX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SECONDARY_TDM_TX_2, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Secondary TDM3 Capture", + .aif_name = "SEC_TDM_TX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SECONDARY_TDM_TX_3, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Secondary TDM4 Capture", + .aif_name = "SEC_TDM_TX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SECONDARY_TDM_TX_4, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Secondary TDM5 Capture", + .aif_name = "SEC_TDM_TX_5", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SECONDARY_TDM_TX_5, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Secondary TDM6 Capture", + .aif_name = "SEC_TDM_TX_6", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SECONDARY_TDM_TX_6, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Secondary TDM7 Capture", + .aif_name = "SEC_TDM_TX_7", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SECONDARY_TDM_TX_7, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Tertiary TDM0 Playback", + .aif_name = "TERT_TDM_RX_0", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_TERTIARY_TDM_RX, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Tertiary TDM1 Playback", + .aif_name = "TERT_TDM_RX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_TERTIARY_TDM_RX_1, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Tertiary TDM2 Playback", + .aif_name = "TERT_TDM_RX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_TERTIARY_TDM_RX_2, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Tertiary TDM3 Playback", + .aif_name = "TERT_TDM_RX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_TERTIARY_TDM_RX_3, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Tertiary TDM4 Playback", + .aif_name = "TERT_TDM_RX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_TERTIARY_TDM_RX_4, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Tertiary TDM5 Playback", + .aif_name = "TERT_TDM_RX_5", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_TERTIARY_TDM_RX_5, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Tertiary TDM6 Playback", + .aif_name = "TERT_TDM_RX_6", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_TERTIARY_TDM_RX_6, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Tertiary TDM7 Playback", + .aif_name = "TERT_TDM_RX_7", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_TERTIARY_TDM_RX_7, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Tertiary TDM0 Capture", + .aif_name = "TERT_TDM_TX_0", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_TERTIARY_TDM_TX, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Tertiary TDM1 Capture", + .aif_name = "TERT_TDM_TX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_TERTIARY_TDM_TX_1, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Tertiary TDM2 Capture", + .aif_name = "TERT_TDM_TX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_TERTIARY_TDM_TX_2, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Tertiary TDM3 Capture", + .aif_name = "TERT_TDM_TX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_TERTIARY_TDM_TX_3, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Tertiary TDM4 Capture", + .aif_name = "TERT_TDM_TX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_TERTIARY_TDM_TX_4, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Tertiary TDM5 Capture", + .aif_name = "TERT_TDM_TX_5", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_TERTIARY_TDM_TX_5, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Tertiary TDM6 Capture", + .aif_name = "TERT_TDM_TX_6", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_TERTIARY_TDM_TX_6, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Tertiary TDM7 Capture", + .aif_name = "TERT_TDM_TX_7", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_TERTIARY_TDM_TX_7, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Quaternary TDM0 Playback", + .aif_name = "QUAT_TDM_RX_0", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUATERNARY_TDM_RX, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Quaternary TDM1 Playback", + .aif_name = "QUAT_TDM_RX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUATERNARY_TDM_RX_1, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Quaternary TDM2 Playback", + .aif_name = "QUAT_TDM_RX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUATERNARY_TDM_RX_2, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Quaternary TDM3 Playback", + .aif_name = "QUAT_TDM_RX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUATERNARY_TDM_RX_3, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Quaternary TDM4 Playback", + .aif_name = "QUAT_TDM_RX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUATERNARY_TDM_RX_4, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Quaternary TDM5 Playback", + .aif_name = "QUAT_TDM_RX_5", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUATERNARY_TDM_RX_5, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Quaternary TDM6 Playback", + .aif_name = "QUAT_TDM_RX_6", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUATERNARY_TDM_RX_6, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Quaternary TDM7 Playback", + .aif_name = "QUAT_TDM_RX_7", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUATERNARY_TDM_RX_7, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Quaternary TDM0 Capture", + .aif_name = "QUAT_TDM_TX_0", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUATERNARY_TDM_TX, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Quaternary TDM1 Capture", + .aif_name = "QUAT_TDM_TX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUATERNARY_TDM_TX_1, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Quaternary TDM2 Capture", + .aif_name = "QUAT_TDM_TX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUATERNARY_TDM_TX_2, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Quaternary TDM3 Capture", + .aif_name = "QUAT_TDM_TX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUATERNARY_TDM_TX_3, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Quaternary TDM4 Capture", + .aif_name = "QUAT_TDM_TX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUATERNARY_TDM_TX_4, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Quaternary TDM5 Capture", + .aif_name = "QUAT_TDM_TX_5", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUATERNARY_TDM_TX_5, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Quaternary TDM6 Capture", + .aif_name = "QUAT_TDM_TX_6", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUATERNARY_TDM_TX_6, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Quaternary TDM7 Capture", + .aif_name = "QUAT_TDM_TX_7", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUATERNARY_TDM_TX_7, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, +}; + +static const struct snd_soc_component_driver msm_q6_tdm_dai_component = { + .name = "msm-dai-q6-tdm", +}; + +static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev) +{ + struct msm_dai_q6_tdm_dai_data *dai_data = NULL; + struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header = NULL; + int rc = 0; + u32 tdm_dev_id = 0; + int port_idx = 0; + struct device_node *tdm_parent_node = NULL; + + /* retrieve device/afe id */ + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-dev-id", + &tdm_dev_id); + if (rc) { + dev_err(&pdev->dev, "%s: Device ID missing in DT file\n", + __func__); + goto rtn; + } + if ((tdm_dev_id < AFE_PORT_ID_TDM_PORT_RANGE_START) || + (tdm_dev_id > AFE_PORT_ID_TDM_PORT_RANGE_END)) { + dev_err(&pdev->dev, "%s: Invalid TDM Device ID 0x%x in DT file\n", + __func__, tdm_dev_id); + rc = -ENXIO; + goto rtn; + } + pdev->id = tdm_dev_id; + + dev_info(&pdev->dev, "%s: dev_name: %s dev_id: 0x%x\n", + __func__, dev_name(&pdev->dev), tdm_dev_id); + + dai_data = kzalloc(sizeof(struct msm_dai_q6_tdm_dai_data), + GFP_KERNEL); + if (!dai_data) { + rc = -ENOMEM; + dev_err(&pdev->dev, + "%s Failed to allocate memory for tdm dai_data\n", + __func__); + goto rtn; + } + memset(dai_data, 0, sizeof(*dai_data)); + + /* TDM CFG */ + tdm_parent_node = of_get_parent(pdev->dev.of_node); + rc = of_property_read_u32(tdm_parent_node, + "qcom,msm-cpudai-tdm-sync-mode", + (u32 *)&dai_data->port_cfg.tdm.sync_mode); + if (rc) { + dev_err(&pdev->dev, "%s: Sync Mode from DT file %s\n", + __func__, "qcom,msm-cpudai-tdm-sync-mode"); + goto free_dai_data; + } + dev_dbg(&pdev->dev, "%s: Sync Mode from DT file 0x%x\n", + __func__, dai_data->port_cfg.tdm.sync_mode); + + rc = of_property_read_u32(tdm_parent_node, + "qcom,msm-cpudai-tdm-sync-src", + (u32 *)&dai_data->port_cfg.tdm.sync_src); + if (rc) { + dev_err(&pdev->dev, "%s: Sync Src from DT file %s\n", + __func__, "qcom,msm-cpudai-tdm-sync-src"); + goto free_dai_data; + } + dev_dbg(&pdev->dev, "%s: Sync Src from DT file 0x%x\n", + __func__, dai_data->port_cfg.tdm.sync_src); + + rc = of_property_read_u32(tdm_parent_node, + "qcom,msm-cpudai-tdm-data-out", + (u32 *)&dai_data->port_cfg.tdm.ctrl_data_out_enable); + if (rc) { + dev_err(&pdev->dev, "%s: Data Out from DT file %s\n", + __func__, "qcom,msm-cpudai-tdm-data-out"); + goto free_dai_data; + } + dev_dbg(&pdev->dev, "%s: Data Out from DT file 0x%x\n", + __func__, dai_data->port_cfg.tdm.ctrl_data_out_enable); + + rc = of_property_read_u32(tdm_parent_node, + "qcom,msm-cpudai-tdm-invert-sync", + (u32 *)&dai_data->port_cfg.tdm.ctrl_invert_sync_pulse); + if (rc) { + dev_err(&pdev->dev, "%s: Invert Sync from DT file %s\n", + __func__, "qcom,msm-cpudai-tdm-invert-sync"); + goto free_dai_data; + } + dev_dbg(&pdev->dev, "%s: Invert Sync from DT file 0x%x\n", + __func__, dai_data->port_cfg.tdm.ctrl_invert_sync_pulse); + + rc = of_property_read_u32(tdm_parent_node, + "qcom,msm-cpudai-tdm-data-delay", + (u32 *)&dai_data->port_cfg.tdm.ctrl_sync_data_delay); + if (rc) { + dev_err(&pdev->dev, "%s: Data Delay from DT file %s\n", + __func__, "qcom,msm-cpudai-tdm-data-delay"); + goto free_dai_data; + } + dev_dbg(&pdev->dev, "%s: Data Delay from DT file 0x%x\n", + __func__, dai_data->port_cfg.tdm.ctrl_sync_data_delay); + + /* TDM CFG -- set default */ + dai_data->port_cfg.tdm.data_format = AFE_LINEAR_PCM_DATA; + dai_data->port_cfg.tdm.tdm_cfg_minor_version = + AFE_API_VERSION_TDM_CONFIG; + + /* TDM SLOT MAPPING CFG */ + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-data-align", + &dai_data->port_cfg.slot_mapping.data_align_type); + if (rc) { + dev_err(&pdev->dev, "%s: Data Align from DT file %s\n", + __func__, + "qcom,msm-cpudai-tdm-data-align"); + goto free_dai_data; + } + dev_dbg(&pdev->dev, "%s: Data Align from DT file 0x%x\n", + __func__, dai_data->port_cfg.slot_mapping.data_align_type); + + /* TDM SLOT MAPPING CFG -- set default */ + dai_data->port_cfg.slot_mapping.minor_version = + AFE_API_VERSION_SLOT_MAPPING_CONFIG; + + /* CUSTOM TDM HEADER CFG */ + custom_tdm_header = &dai_data->port_cfg.custom_tdm_header; + if (of_find_property(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-header-start-offset", NULL) && + of_find_property(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-header-width", NULL) && + of_find_property(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-header-num-frame-repeat", NULL)) { + /* if the property exist */ + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-header-start-offset", + (u32 *)&custom_tdm_header->start_offset); + if (rc) { + dev_err(&pdev->dev, "%s: Header Start Offset from DT file %s\n", + __func__, + "qcom,msm-cpudai-tdm-header-start-offset"); + goto free_dai_data; + } + dev_dbg(&pdev->dev, "%s: Header Start Offset from DT file 0x%x\n", + __func__, custom_tdm_header->start_offset); + + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-header-width", + (u32 *)&custom_tdm_header->header_width); + if (rc) { + dev_err(&pdev->dev, "%s: Header Width from DT file %s\n", + __func__, "qcom,msm-cpudai-tdm-header-width"); + goto free_dai_data; + } + dev_dbg(&pdev->dev, "%s: Header Width from DT file 0x%x\n", + __func__, custom_tdm_header->header_width); + + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-header-num-frame-repeat", + (u32 *)&custom_tdm_header->num_frame_repeat); + if (rc) { + dev_err(&pdev->dev, "%s: Header Num Frame Repeat from DT file %s\n", + __func__, + "qcom,msm-cpudai-tdm-header-num-frame-repeat"); + goto free_dai_data; + } + dev_dbg(&pdev->dev, "%s: Header Num Frame Repeat from DT file 0x%x\n", + __func__, custom_tdm_header->num_frame_repeat); + + /* CUSTOM TDM HEADER CFG -- set default */ + custom_tdm_header->minor_version = + AFE_API_VERSION_CUSTOM_TDM_HEADER_CONFIG; + custom_tdm_header->header_type = + AFE_CUSTOM_TDM_HEADER_TYPE_INVALID; + } else { + dev_info(&pdev->dev, + "%s: Custom tdm header not supported\n", __func__); + /* CUSTOM TDM HEADER CFG -- set default */ + custom_tdm_header->header_type = + AFE_CUSTOM_TDM_HEADER_TYPE_INVALID; + /* proceed with probe */ + } + + /* copy static clk per parent node */ + dai_data->clk_set = tdm_clk_set; + /* copy static group cfg per parent node */ + dai_data->group_cfg.tdm_cfg = tdm_group_cfg; + /* copy static num group ports per parent node */ + dai_data->num_group_ports = num_tdm_group_ports; + + + dev_set_drvdata(&pdev->dev, dai_data); + + port_idx = msm_dai_q6_get_port_idx(tdm_dev_id); + if (port_idx < 0) { + dev_err(&pdev->dev, "%s Port id 0x%x not supported\n", + __func__, tdm_dev_id); + rc = -EINVAL; + goto free_dai_data; + } + + rc = snd_soc_register_component(&pdev->dev, + &msm_q6_tdm_dai_component, + &msm_dai_q6_tdm_dai[port_idx], 1); + + if (rc) { + dev_err(&pdev->dev, "%s: TDM dai 0x%x register failed, rc=%d\n", + __func__, tdm_dev_id, rc); + goto err_register; + } + + return 0; + +err_register: +free_dai_data: + kfree(dai_data); +rtn: + return rc; +} + +static int msm_dai_q6_tdm_dev_remove(struct platform_device *pdev) +{ + struct msm_dai_q6_tdm_dai_data *dai_data = + dev_get_drvdata(&pdev->dev); + + snd_soc_unregister_component(&pdev->dev); + + kfree(dai_data); + + return 0; +} + +static const struct of_device_id msm_dai_q6_tdm_dev_dt_match[] = { + { .compatible = "qcom,msm-dai-q6-tdm", }, + {} +}; + +MODULE_DEVICE_TABLE(of, msm_dai_q6_tdm_dev_dt_match); + +static struct platform_driver msm_dai_q6_tdm_driver = { + .probe = msm_dai_q6_tdm_dev_probe, + .remove = msm_dai_q6_tdm_dev_remove, + .driver = { + .name = "msm-dai-q6-tdm", + .owner = THIS_MODULE, + .of_match_table = msm_dai_q6_tdm_dev_dt_match, + }, +}; + +static int __init msm_dai_q6_init(void) +{ + int rc; + + rc = platform_driver_register(&msm_auxpcm_dev_driver); + if (rc) { + pr_err("%s: fail to register auxpcm dev driver", __func__); + goto fail; + } + + rc = platform_driver_register(&msm_dai_q6); + if (rc) { + pr_err("%s: fail to register dai q6 driver", __func__); + goto dai_q6_fail; + } + + rc = platform_driver_register(&msm_dai_q6_dev); + if (rc) { + pr_err("%s: fail to register dai q6 dev driver", __func__); + goto dai_q6_dev_fail; + } + + rc = platform_driver_register(&msm_dai_q6_mi2s_driver); + if (rc) { + pr_err("%s: fail to register dai MI2S dev drv\n", __func__); + goto dai_q6_mi2s_drv_fail; + } + + rc = platform_driver_register(&msm_dai_mi2s_q6); + if (rc) { + pr_err("%s: fail to register dai MI2S\n", __func__); + goto dai_mi2s_q6_fail; + } + + rc = platform_driver_register(&msm_dai_q6_spdif_driver); + if (rc) { + pr_err("%s: fail to register dai SPDIF\n", __func__); + goto dai_spdif_q6_fail; + } + + rc = platform_driver_register(&msm_dai_q6_tdm_driver); + if (rc) { + pr_err("%s: fail to register dai TDM dev drv\n", __func__); + goto dai_q6_tdm_drv_fail; + } + + rc = platform_driver_register(&msm_dai_tdm_q6); + if (rc) { + pr_err("%s: fail to register dai TDM\n", __func__); + goto dai_tdm_q6_fail; + } + return rc; + +dai_tdm_q6_fail: + platform_driver_unregister(&msm_dai_q6_tdm_driver); +dai_q6_tdm_drv_fail: + platform_driver_unregister(&msm_dai_q6_spdif_driver); +dai_spdif_q6_fail: + platform_driver_unregister(&msm_dai_mi2s_q6); +dai_mi2s_q6_fail: + platform_driver_unregister(&msm_dai_q6_mi2s_driver); +dai_q6_mi2s_drv_fail: + platform_driver_unregister(&msm_dai_q6_dev); +dai_q6_dev_fail: + platform_driver_unregister(&msm_dai_q6); +dai_q6_fail: + platform_driver_unregister(&msm_auxpcm_dev_driver); +fail: + return rc; +} +module_init(msm_dai_q6_init); + +static void __exit msm_dai_q6_exit(void) +{ + platform_driver_unregister(&msm_dai_q6_dev); + platform_driver_unregister(&msm_dai_q6); + platform_driver_unregister(&msm_auxpcm_dev_driver); + platform_driver_unregister(&msm_dai_q6_spdif_driver); +} +module_exit(msm_dai_q6_exit); + +/* Module information */ +MODULE_DESCRIPTION("MSM DSP DAI driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/msm-dai-slim.c b/sound/soc/msm/qdsp6v2/msm-dai-slim.c new file mode 100644 index 000000000000..8115feef846e --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-dai-slim.c @@ -0,0 +1,664 @@ +/* + * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SLIM_DEV_NAME "msm-dai-slim" + +#define SLIM_DAI_RATES (SNDRV_PCM_RATE_48000 | \ + SNDRV_PCM_RATE_8000 | \ + SNDRV_PCM_RATE_16000 | \ + SNDRV_PCM_RATE_96000 | \ + SNDRV_PCM_RATE_192000 | \ + SNDRV_PCM_RATE_384000) + +#define SLIM_DAI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +#define DAI_STATE_INITIALIZED (0x01 << 0) +#define DAI_STATE_PREPARED (0x01 << 1) +#define DAI_STATE_RUNNING (0x01 << 2) + +#define SET_DAI_STATE(status, state) \ + (status |= state) + +#define CLR_DAI_STATE(status, state) \ + (status = status & (~state)) + +enum { + MSM_DAI_SLIM0 = 0, + NUM_SLIM_DAIS, +}; + +struct msm_slim_dai_data { + unsigned int dai_id; + u16 *chan_h; + u16 *sh_ch; + u16 grph; + u32 rate; + u16 bits; + u16 ch_cnt; + u8 status; + struct snd_soc_dai_driver *dai_drv; + struct msm_slim_dma_data dma_data; + struct slim_port_cfg port_cfg; +}; + +struct msm_dai_slim_drv_data { + struct slim_device *sdev; + u16 num_dais; + struct msm_slim_dai_data slim_dai_data[NUM_SLIM_DAIS]; +}; + +struct msm_slim_dai_data *msm_slim_get_dai_data( + struct msm_dai_slim_drv_data *drv_data, + struct snd_soc_dai *dai) +{ + struct msm_slim_dai_data *dai_data_t; + int i; + + for (i = 0; i < drv_data->num_dais; i++) { + dai_data_t = &drv_data->slim_dai_data[i]; + if (dai_data_t->dai_id == dai->id) + return dai_data_t; + } + + dev_err(dai->dev, + "%s: no dai data found for dai_id %d\n", + __func__, dai->id); + return NULL; +} + +static int msm_dai_slim_ch_ctl(struct msm_slim_dma_data *dma_data, + struct snd_soc_dai *dai, bool enable) +{ + struct slim_device *sdev; + struct msm_dai_slim_drv_data *drv_data; + struct msm_slim_dai_data *dai_data; + int rc, rc1, i; + + if (!dma_data || !dma_data->sdev) { + pr_err("%s: Invalid %s\n", __func__, + (!dma_data) ? "dma_data" : "slim_device"); + return -EINVAL; + } + + sdev = dma_data->sdev; + drv_data = dev_get_drvdata(&sdev->dev); + dai_data = msm_slim_get_dai_data(drv_data, dai); + + if (!dai_data) { + dev_err(dai->dev, + "%s: Invalid dai_data for dai_id %d\n", + __func__, dai->id); + return -EINVAL; + } + + dev_dbg(&sdev->dev, + "%s: enable = %s, rate = %u\n", __func__, + enable ? "true" : "false", + dai_data->rate); + + if (enable) { + if (!(dai_data->status & DAI_STATE_PREPARED)) { + dev_err(&sdev->dev, + "%s: dai id (%d) has invalid state 0x%x\n", + __func__, dai->id, dai_data->status); + return -EINVAL; + } + + rc = slim_alloc_mgrports(sdev, + SLIM_REQ_DEFAULT, dai_data->ch_cnt, + &(dma_data->ph), + sizeof(dma_data->ph)); + if (rc < 0) { + dev_err(&sdev->dev, + "%s:alloc mgrport failed rc %d\n", + __func__, rc); + goto done; + } + + rc = slim_config_mgrports(sdev, &(dma_data->ph), + dai_data->ch_cnt, + &(dai_data->port_cfg)); + if (rc < 0) { + dev_err(&sdev->dev, + "%s: config mgrport failed rc %d\n", + __func__, rc); + goto err_done; + } + + for (i = 0; i < dai_data->ch_cnt; i++) { + rc = slim_connect_sink(sdev, + &dma_data->ph, 1, + dai_data->chan_h[i]); + if (rc < 0) { + dev_err(&sdev->dev, + "%s: slim_connect_sink failed, ch = %d, err = %d\n", + __func__, i, rc); + goto err_done; + } + } + + rc = slim_control_ch(sdev, + dai_data->grph, + SLIM_CH_ACTIVATE, true); + if (rc < 0) { + dev_err(&sdev->dev, + "%s: slim activate ch failed, err = %d\n", + __func__, rc); + goto err_done; + } + /* Mark dai status as running */ + SET_DAI_STATE(dai_data->status, DAI_STATE_RUNNING); + } else { + if (!(dai_data->status & DAI_STATE_RUNNING)) { + dev_err(&sdev->dev, + "%s: dai id (%d) has invalid state 0x%x\n", + __func__, dai->id, dai_data->status); + return -EINVAL; + } + + rc = slim_control_ch(sdev, + dai_data->grph, + SLIM_CH_REMOVE, true); + if (rc < 0) { + dev_err(&sdev->dev, + "%s: slim activate ch failed, err = %d\n", + __func__, rc); + goto done; + } + + rc = slim_dealloc_mgrports(sdev, + &dma_data->ph, 1); + if (rc < 0) { + dev_err(&sdev->dev, + "%s: dealloc mgrport failed, err = %d\n", + __func__, rc); + goto done; + } + /* clear running state for dai*/ + CLR_DAI_STATE(dai_data->status, DAI_STATE_RUNNING); + } + + return rc; + +err_done: + rc1 = slim_dealloc_mgrports(sdev, + &dma_data->ph, 1); + if (rc1 < 0) + dev_err(&sdev->dev, + "%s: dealloc mgrport failed, err = %d\n", + __func__, rc1); +done: + return rc; +} + +static int msm_dai_slim_hw_params( + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct msm_dai_slim_drv_data *drv_data = dev_get_drvdata(dai->dev); + struct msm_slim_dai_data *dai_data; + int rc = 0; + + dai_data = msm_slim_get_dai_data(drv_data, dai); + if (!dai_data) { + dev_err(dai->dev, + "%s: Invalid dai_data for dai_id %d\n", + __func__, dai->id); + rc = -EINVAL; + goto done; + } + + if (!dai_data->ch_cnt || dai_data->ch_cnt != params_channels(params)) { + dev_err(dai->dev, "%s: invalid ch_cnt %d %d\n", + __func__, dai_data->ch_cnt, params_channels(params)); + rc = -EINVAL; + goto done; + } + + dai_data->rate = params_rate(params); + dai_data->port_cfg.port_opts = SLIM_OPT_NONE; + if (dai_data->rate >= SNDRV_PCM_RATE_48000) + dai_data->port_cfg.watermark = 16; + else + dai_data->port_cfg.watermark = 8; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + dai_data->bits = 16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + dai_data->bits = 24; + break; + case SNDRV_PCM_FORMAT_S32_LE: + dai_data->bits = 32; + break; + default: + dev_err(dai->dev, "%s: invalid format %d\n", __func__, + params_format(params)); + rc = -EINVAL; + goto done; + } + + dev_dbg(dai->dev, "%s: ch_cnt=%u rate=%u, bit_width = %u\n", + __func__, dai_data->ch_cnt, dai_data->rate, + dai_data->bits); +done: + return rc; +} + +static int msm_dai_slim_set_channel_map(struct snd_soc_dai *dai, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot) +{ + struct msm_dai_slim_drv_data *drv_data = dev_get_drvdata(dai->dev); + struct msm_slim_dai_data *dai_data; + struct snd_soc_dai_driver *dai_drv; + u8 i = 0; + + dev_dbg(dai->dev, + "%s: tx_num=%u, rx_num=%u\n", + __func__, tx_num, rx_num); + + dai_data = msm_slim_get_dai_data(drv_data, dai); + if (!dai_data) { + dev_err(dai->dev, + "%s: Invalid dai_data for dai_id %d\n", + __func__, dai->id); + return -EINVAL; + } + + dai_drv = dai_data->dai_drv; + + if (tx_num > dai_drv->capture.channels_max) { + dev_err(dai->dev, "%s: tx_num %u max out master port cnt\n", + __func__, tx_num); + return -EINVAL; + } + + for (i = 0; i < tx_num; i++) + dai_data->sh_ch[i] = tx_slot[i]; + + dai_data->ch_cnt = tx_num; + return 0; +} + +static int msm_dai_slim_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct msm_dai_slim_drv_data *drv_data = dev_get_drvdata(dai->dev); + struct msm_slim_dma_data *dma_data; + struct msm_slim_dai_data *dai_data = NULL; + struct slim_ch prop; + int rc; + u8 i, j; + + dai_data = msm_slim_get_dai_data(drv_data, dai); + if (!dai_data) { + dev_err(dai->dev, + "%s: Invalid dai_data for dai %d\n", + __func__, dai->id); + return -EINVAL; + } + + if (!(dai_data->status & DAI_STATE_INITIALIZED)) { + dev_err(dai->dev, + "%s: dai id (%d) has invalid state 0x%x\n", + __func__, dai->id, dai_data->status); + return -EINVAL; + } + + if (dai_data->status & DAI_STATE_PREPARED) { + dev_dbg(dai->dev, + "%s: dai id (%d) has already prepared.\n", + __func__, dai->id); + return 0; + } + + dma_data = &dai_data->dma_data; + snd_soc_dai_set_dma_data(dai, substream, dma_data); + + for (i = 0; i < dai_data->ch_cnt; i++) { + rc = slim_query_ch(drv_data->sdev, dai_data->sh_ch[i], + &dai_data->chan_h[i]); + if (rc) { + dev_err(dai->dev, "%s:query chan handle failed rc %d\n", + __func__, rc); + goto error_chan_query; + } + } + + prop.prot = SLIM_AUTO_ISO; + prop.baser = SLIM_RATE_4000HZ; + prop.dataf = SLIM_CH_DATAF_NOT_DEFINED; + prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE; + prop.ratem = (dai_data->rate/4000); + prop.sampleszbits = dai_data->bits; + + rc = slim_define_ch(drv_data->sdev, &prop, dai_data->chan_h, + dai_data->ch_cnt, true, &dai_data->grph); + + if (rc) { + dev_err(dai->dev, "%s:define chan failed rc %d\n", + __func__, rc); + goto error_define_chan; + } + + /* Mark stream status as prepared */ + SET_DAI_STATE(dai_data->status, DAI_STATE_PREPARED); + + return rc; + +error_define_chan: +error_chan_query: + for (j = 0; j < i; j++) + slim_dealloc_ch(drv_data->sdev, dai_data->chan_h[j]); + return rc; +} + +static void msm_dai_slim_shutdown(struct snd_pcm_substream *stream, + struct snd_soc_dai *dai) +{ + struct msm_dai_slim_drv_data *drv_data = dev_get_drvdata(dai->dev); + struct msm_slim_dma_data *dma_data = NULL; + struct msm_slim_dai_data *dai_data; + int i, rc = 0; + + dai_data = msm_slim_get_dai_data(drv_data, dai); + dma_data = snd_soc_dai_get_dma_data(dai, stream); + if (!dma_data || !dai_data) { + dev_err(dai->dev, + "%s: Invalid %s\n", __func__, + (!dma_data) ? "dma_data" : "dai_data"); + return; + } + + if ((!(dai_data->status & DAI_STATE_PREPARED)) || + dai_data->status & DAI_STATE_RUNNING) { + dev_err(dai->dev, + "%s: dai id (%d) has invalid state 0x%x\n", + __func__, dai->id, dai_data->status); + return; + } + + for (i = 0; i < dai_data->ch_cnt; i++) { + rc = slim_dealloc_ch(drv_data->sdev, dai_data->chan_h[i]); + if (rc) { + dev_err(dai->dev, + "%s: dealloc_ch failed, err = %d\n", + __func__, rc); + } + } + + snd_soc_dai_set_dma_data(dai, stream, NULL); + /* clear prepared state for the dai */ + CLR_DAI_STATE(dai_data->status, DAI_STATE_PREPARED); +} + +static const struct snd_soc_component_driver msm_dai_slim_component = { + .name = "msm-dai-slim-cmpnt", +}; + +static struct snd_soc_dai_ops msm_dai_slim_ops = { + .prepare = msm_dai_slim_prepare, + .hw_params = msm_dai_slim_hw_params, + .shutdown = msm_dai_slim_shutdown, + .set_channel_map = msm_dai_slim_set_channel_map, +}; + +static struct snd_soc_dai_driver msm_slim_dais[] = { + { + /* + * The first dai name should be same as device name + * to support registering single and multile dais. + */ + .name = SLIM_DEV_NAME, + .id = MSM_DAI_SLIM0, + .capture = { + .rates = SLIM_DAI_RATES, + .formats = SLIM_DAI_FORMATS, + .channels_min = 1, + /* + * max channels allowed is + * dependent on platform and + * will be updated before this + * dai driver is registered. + */ + .channels_max = 1, + .rate_min = 8000, + .rate_max = 384000, + .stream_name = "SLIM_DAI0 Capture", + }, + .ops = &msm_dai_slim_ops, + }, + /* + * If multiple dais are needed, + * add dais here and update the + * dai_id enum. + */ +}; + +static void msm_dai_slim_remove_dai_data( + struct device *dev, + struct msm_dai_slim_drv_data *drv_data) +{ + int i; + struct msm_slim_dai_data *dai_data_t; + + for (i = 0; i < drv_data->num_dais; i++) { + dai_data_t = &drv_data->slim_dai_data[i]; + + kfree(dai_data_t->chan_h); + dai_data_t->chan_h = NULL; + kfree(dai_data_t->sh_ch); + dai_data_t->sh_ch = NULL; + } +} + +static int msm_dai_slim_populate_dai_data(struct device *dev, + struct msm_dai_slim_drv_data *drv_data) +{ + struct snd_soc_dai_driver *dai_drv; + struct msm_slim_dai_data *dai_data_t; + u8 num_ch; + int i, j, rc; + + for (i = 0; i < drv_data->num_dais; i++) { + num_ch = 0; + dai_drv = &msm_slim_dais[i]; + num_ch += dai_drv->capture.channels_max; + num_ch += dai_drv->playback.channels_max; + + dai_data_t = &drv_data->slim_dai_data[i]; + dai_data_t->dai_drv = dai_drv; + dai_data_t->dai_id = dai_drv->id; + dai_data_t->dma_data.sdev = drv_data->sdev; + dai_data_t->dma_data.dai_channel_ctl = + msm_dai_slim_ch_ctl; + SET_DAI_STATE(dai_data_t->status, + DAI_STATE_INITIALIZED); + + dai_data_t->chan_h = devm_kzalloc(dev, + sizeof(u16) * num_ch, + GFP_KERNEL); + if (!dai_data_t->chan_h) { + dev_err(dev, + "%s: DAI ID %d, Failed to alloc channel handles\n", + __func__, i); + rc = -ENOMEM; + goto err_mem_alloc; + } + + dai_data_t->sh_ch = devm_kzalloc(dev, + sizeof(u16) * num_ch, + GFP_KERNEL); + if (!dai_data_t->sh_ch) { + dev_err(dev, + "%s: DAI ID %d, Failed to alloc sh_ch\n", + __func__, i); + rc = -ENOMEM; + goto err_mem_alloc; + } + } + return 0; + +err_mem_alloc: + for (j = 0; j < i; j++) { + dai_data_t = &drv_data->slim_dai_data[i]; + + devm_kfree(dev, dai_data_t->chan_h); + dai_data_t->chan_h = NULL; + + devm_kfree(dev, dai_data_t->sh_ch); + dai_data_t->sh_ch = NULL; + } + return rc; +} + +static int msm_dai_slim_dev_probe(struct slim_device *sdev) +{ + int rc, i; + u8 max_channels; + u32 apps_ch_pipes; + struct msm_dai_slim_drv_data *drv_data; + struct device *dev = &sdev->dev; + struct snd_soc_dai_driver *dai_drv; + + if (!dev->of_node || + !dev->of_node->parent) { + dev_err(dev, + "%s: Invalid %s\n", __func__, + (!dev->of_node) ? "of_node" : "parent_of_node"); + return -EINVAL; + } + + rc = of_property_read_u32(dev->of_node->parent, + "qcom,apps-ch-pipes", + &apps_ch_pipes); + if (rc) { + dev_err(dev, + "%s: Failed to lookup property %s in node %s, err = %d\n", + __func__, "qcom,apps-ch-pipes", + dev->of_node->parent->full_name, rc); + goto err_ret; + } + + max_channels = hweight_long(apps_ch_pipes); + if (max_channels <= 0) { + dev_err(dev, + "%s: Invalid apps owned ports %d\n", + __func__, max_channels); + goto err_ret; + } + + dev_dbg(dev, "%s: max channels = %u\n", + __func__, max_channels); + + for (i = 0; i < ARRAY_SIZE(msm_slim_dais); i++) { + dai_drv = &msm_slim_dais[i]; + dai_drv->capture.channels_max = max_channels; + dai_drv->playback.channels_max = max_channels; + } + + drv_data = devm_kzalloc(dev, sizeof(*drv_data), + GFP_KERNEL); + if (!drv_data) { + rc = -ENOMEM; + goto err_ret; + } + + drv_data->sdev = sdev; + drv_data->num_dais = NUM_SLIM_DAIS; + + rc = msm_dai_slim_populate_dai_data(dev, drv_data); + if (rc) { + dev_err(dev, + "%s: failed to setup dai_data, err = %d\n", + __func__, rc); + goto err_populate_dai; + } + + rc = snd_soc_register_component(&sdev->dev, &msm_dai_slim_component, + msm_slim_dais, NUM_SLIM_DAIS); + if (rc < 0) { + dev_err(dev, "%s: failed to register DAI, err = %d\n", + __func__, rc); + goto err_reg_comp; + } + + dev_set_drvdata(dev, drv_data); + return rc; + +err_reg_comp: + msm_dai_slim_remove_dai_data(dev, drv_data); + +err_populate_dai: + devm_kfree(dev, drv_data); + +err_ret: + return rc; +} + +static int msm_dai_slim_dev_remove(struct slim_device *sdev) +{ + snd_soc_unregister_component(&sdev->dev); + return 0; +} + +static const struct slim_device_id msm_dai_slim_dt_match[] = { + {SLIM_DEV_NAME, 0 }, + {} +}; + +static struct slim_driver msm_dai_slim_driver = { + .driver = { + .name = SLIM_DEV_NAME, + .owner = THIS_MODULE, + }, + .probe = msm_dai_slim_dev_probe, + .remove = msm_dai_slim_dev_remove, + .id_table = msm_dai_slim_dt_match, +}; + +static int __init msm_dai_slim_init(void) +{ + int rc; + + rc = slim_driver_register(&msm_dai_slim_driver); + if (rc) + pr_err("%s: failed to register with slimbus driver rc = %d", + __func__, rc); + return rc; +} +module_init(msm_dai_slim_init); + +static void __exit msm_dai_slim_exit(void) +{ +} +module_exit(msm_dai_slim_exit); + +/* Module information */ +MODULE_DESCRIPTION("Slimbus apps-owned channel handling driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/msm-dai-stub-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-stub-v2.c new file mode 100644 index 000000000000..3a2c3d3dbbcf --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-dai-stub-v2.c @@ -0,0 +1,394 @@ +/* Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +enum { + STUB_RX, + STUB_TX, + STUB_1_RX, + STUB_1_TX, + STUB_DTMF_TX, + STUB_HOST_RX_CAPTURE_TX, + STUB_HOST_RX_PLAYBACK_RX, + STUB_HOST_TX_CAPTURE_TX, + STUB_HOST_TX_PLAYBACK_RX, +}; + +static int msm_dai_stub_set_channel_map(struct snd_soc_dai *dai, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot) +{ + pr_debug("%s:\n", __func__); + + return 0; +} + +static struct snd_soc_dai_ops msm_dai_stub_ops = { + .set_channel_map = msm_dai_stub_set_channel_map, +}; + +static int msm_dai_stub_add_route(struct snd_soc_dai *dai) +{ + struct snd_soc_dapm_route intercon; + struct snd_soc_dapm_context *dapm; + + if (!dai || !dai->driver) { + pr_err("%s Invalid params\n", __func__); + return -EINVAL; + } + dapm = snd_soc_component_get_dapm(dai->component); + memset(&intercon, 0, sizeof(intercon)); + if (dai->driver->playback.stream_name && + dai->driver->playback.aif_name) { + dev_dbg(dai->dev, "%s add route for widget %s", + __func__, dai->driver->playback.stream_name); + intercon.source = dai->driver->playback.aif_name; + intercon.sink = dai->driver->playback.stream_name; + dev_dbg(dai->dev, "%s src %s sink %s\n", + __func__, intercon.source, intercon.sink); + snd_soc_dapm_add_routes(dapm, &intercon, 1); + } + if (dai->driver->capture.stream_name && + dai->driver->capture.aif_name) { + dev_dbg(dai->dev, "%s add route for widget %s", + __func__, dai->driver->capture.stream_name); + intercon.sink = dai->driver->capture.aif_name; + intercon.source = dai->driver->capture.stream_name; + dev_dbg(dai->dev, "%s src %s sink %s\n", + __func__, intercon.source, intercon.sink); + snd_soc_dapm_add_routes(dapm, &intercon, 1); + } + return 0; +} + +static int msm_dai_stub_dai_probe(struct snd_soc_dai *dai) +{ + return msm_dai_stub_add_route(dai); +} + +static int msm_dai_stub_dai_remove(struct snd_soc_dai *dai) +{ + pr_debug("%s:\n", __func__); + return 0; +} + +static struct snd_soc_dai_driver msm_dai_stub_dai_rx = { + .playback = { + .stream_name = "Stub Playback", + .aif_name = "STUB_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_stub_ops, + .probe = &msm_dai_stub_dai_probe, + .remove = &msm_dai_stub_dai_remove, +}; + +static struct snd_soc_dai_driver msm_dai_stub_dai_tx[] = { + { + .capture = { + .stream_name = "Stub Capture", + .aif_name = "STUB_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_stub_ops, + .probe = &msm_dai_stub_dai_probe, + .remove = &msm_dai_stub_dai_remove, + }, + { + .capture = { + .stream_name = "Stub1 Capture", + .aif_name = "STUB_1_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_stub_ops, + .probe = &msm_dai_stub_dai_probe, + .remove = &msm_dai_stub_dai_remove, + } +}; + +static struct snd_soc_dai_driver msm_dai_stub_dtmf_tx_dai = { + .capture = { + .stream_name = "DTMF TX", + .aif_name = "STUB_DTMF_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_stub_ops, + .probe = &msm_dai_stub_dai_probe, + .remove = &msm_dai_stub_dai_remove, +}; + +static struct snd_soc_dai_driver msm_dai_stub_host_capture_tx_dai[] = { + { + .capture = { + .stream_name = "CS-VOICE HOST RX CAPTURE", + .aif_name = "STUB_HOST_RX_CAPTURE_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_stub_ops, + .probe = &msm_dai_stub_dai_probe, + .remove = &msm_dai_stub_dai_remove, + }, + { + .capture = { + .stream_name = "CS-VOICE HOST TX CAPTURE", + .aif_name = "STUB_HOST_TX_CAPTURE_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_stub_ops, + .probe = &msm_dai_stub_dai_probe, + .remove = &msm_dai_stub_dai_remove, + }, +}; + +static struct snd_soc_dai_driver msm_dai_stub_host_playback_rx_dai[] = { + { + .playback = { + .stream_name = "CS-VOICE HOST RX PLAYBACK", + .aif_name = "STUB_HOST_RX_PLAYBACK_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_stub_ops, + .probe = &msm_dai_stub_dai_probe, + .remove = &msm_dai_stub_dai_remove, + }, + { + .playback = { + .stream_name = "CS-VOICE HOST TX PLAYBACK", + .aif_name = "STUB_HOST_TX_PLAYBACK_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_stub_ops, + .probe = &msm_dai_stub_dai_probe, + .remove = &msm_dai_stub_dai_remove, + }, +}; + +static const struct snd_soc_component_driver msm_dai_stub_component = { + .name = "msm-dai-stub-dev", +}; + +static int msm_dai_stub_dev_probe(struct platform_device *pdev) +{ + int rc, id = -1; + const char *stub_dev_id = "qcom,msm-dai-stub-dev-id"; + + rc = of_property_read_u32(pdev->dev.of_node, stub_dev_id, &id); + if (rc) { + dev_err(&pdev->dev, + "%s: missing %s in dt node\n", __func__, stub_dev_id); + return rc; + } + + pdev->id = id; + + pr_debug("%s: dev name %s, id:%d\n", __func__, + dev_name(&pdev->dev), pdev->id); + + switch (id) { + case STUB_RX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_stub_component, &msm_dai_stub_dai_rx, 1); + break; + case STUB_TX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_stub_component, &msm_dai_stub_dai_tx[0], 1); + break; + case STUB_1_TX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_stub_component, &msm_dai_stub_dai_tx[1], 1); + break; + case STUB_DTMF_TX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_stub_component, + &msm_dai_stub_dtmf_tx_dai, 1); + break; + case STUB_HOST_RX_CAPTURE_TX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_stub_component, + &msm_dai_stub_host_capture_tx_dai[0], 1); + break; + case STUB_HOST_TX_CAPTURE_TX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_stub_component, + &msm_dai_stub_host_capture_tx_dai[1], 1); + break; + case STUB_HOST_RX_PLAYBACK_RX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_stub_component, + &msm_dai_stub_host_playback_rx_dai[0], 1); + break; + case STUB_HOST_TX_PLAYBACK_RX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_stub_component, + &msm_dai_stub_host_playback_rx_dai[1], 1); + break; + } + + return rc; +} + +static int msm_dai_stub_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_component(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_dai_stub_dev_dt_match[] = { + { .compatible = "qcom,msm-dai-stub-dev", }, + { } +}; +MODULE_DEVICE_TABLE(of, msm_dai_stub_dev_dt_match); + +static struct platform_driver msm_dai_stub_dev = { + .probe = msm_dai_stub_dev_probe, + .remove = msm_dai_stub_dev_remove, + .driver = { + .name = "msm-dai-stub-dev", + .owner = THIS_MODULE, + .of_match_table = msm_dai_stub_dev_dt_match, + }, +}; + +static int msm_dai_stub_probe(struct platform_device *pdev) +{ + int rc = 0; + + dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev)); + + rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); + if (rc) { + dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n", + __func__, rc); + } else + dev_dbg(&pdev->dev, "%s: added child node\n", __func__); + + return rc; +} + +static int msm_dai_stub_remove(struct platform_device *pdev) +{ + pr_debug("%s:\n", __func__); + + return 0; +} + +static const struct of_device_id msm_dai_stub_dt_match[] = { + {.compatible = "qcom,msm-dai-stub"}, + {} +}; + +MODULE_DEVICE_TABLE(of, msm_dai_stub_dt_match); + + +static struct platform_driver msm_dai_stub_driver = { + .probe = msm_dai_stub_probe, + .remove = msm_dai_stub_remove, + .driver = { + .name = "msm-dai-stub", + .owner = THIS_MODULE, + .of_match_table = msm_dai_stub_dt_match, + }, +}; + +static int __init msm_dai_stub_init(void) +{ + int rc = 0; + + pr_debug("%s:\n", __func__); + + rc = platform_driver_register(&msm_dai_stub_driver); + if (rc) { + pr_err("%s: fail to register dai q6 driver", __func__); + goto fail; + } + + rc = platform_driver_register(&msm_dai_stub_dev); + if (rc) { + pr_err("%s: fail to register dai q6 dev driver", __func__); + goto dai_stub_dev_fail; + } + return rc; + +dai_stub_dev_fail: + platform_driver_unregister(&msm_dai_stub_driver); +fail: + return rc; +} +module_init(msm_dai_stub_init); + +static void __exit msm_dai_stub_exit(void) +{ + pr_debug("%s:\n", __func__); + + platform_driver_unregister(&msm_dai_stub_dev); + platform_driver_unregister(&msm_dai_stub_driver); +} +module_exit(msm_dai_stub_exit); + +/* Module information */ +MODULE_DESCRIPTION("MSM Stub DSP DAI driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/msm-dolby-common.h b/sound/soc/msm/qdsp6v2/msm-dolby-common.h new file mode 100644 index 000000000000..b43ff15e7649 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-dolby-common.h @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2013-2014, 2016 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _MSM_DOLBY_COMMON_H_ +#define _MSM_DOLBY_COMMON_H_ + +#include + + +#define DOLBY_BUNDLE_MODULE_ID 0x00010723 +#define DOLBY_VISUALIZER_MODULE_ID 0x0001072B + +#define DOLBY_PARAM_ID_VDHE 0x0001074D +#define DOLBY_PARAM_ID_VSPE 0x00010750 +#define DOLBY_PARAM_ID_DSSF 0x00010753 +#define DOLBY_PARAM_ID_DVLI 0x0001073E +#define DOLBY_PARAM_ID_DVLO 0x0001073F +#define DOLBY_PARAM_ID_DVLE 0x0001073C +#define DOLBY_PARAM_ID_DVMC 0x00010741 +#define DOLBY_PARAM_ID_DVME 0x00010740 +#define DOLBY_PARAM_ID_IENB 0x00010744 +#define DOLBY_PARAM_ID_IEBF 0x00010745 +#define DOLBY_PARAM_ID_IEON 0x00010743 +#define DOLBY_PARAM_ID_DEON 0x00010738 +#define DOLBY_PARAM_ID_NGON 0x00010736 +#define DOLBY_PARAM_ID_GEON 0x00010748 +#define DOLBY_PARAM_ID_GENB 0x00010749 +#define DOLBY_PARAM_ID_GEBF 0x0001074A +#define DOLBY_PARAM_ID_AONB 0x0001075B +#define DOLBY_PARAM_ID_AOBF 0x0001075C +#define DOLBY_PARAM_ID_AOBG 0x0001075D +#define DOLBY_PARAM_ID_AOON 0x00010759 +#define DOLBY_PARAM_ID_ARNB 0x0001075F +#define DOLBY_PARAM_ID_ARBF 0x00010760 +#define DOLBY_PARAM_ID_PLB 0x00010768 +#define DOLBY_PARAM_ID_PLMD 0x00010767 +#define DOLBY_PARAM_ID_DHSB 0x0001074E +#define DOLBY_PARAM_ID_DHRG 0x0001074F +#define DOLBY_PARAM_ID_DSSB 0x00010751 +#define DOLBY_PARAM_ID_DSSA 0x00010752 +#define DOLBY_PARAM_ID_DVLA 0x0001073D +#define DOLBY_PARAM_ID_IEBT 0x00010746 +#define DOLBY_PARAM_ID_IEA 0x0001076A +#define DOLBY_PARAM_ID_DEA 0x00010739 +#define DOLBY_PARAM_ID_DED 0x0001073A +#define DOLBY_PARAM_ID_GEBG 0x0001074B +#define DOLBY_PARAM_ID_AOCC 0x0001075A +#define DOLBY_PARAM_ID_ARBI 0x00010761 +#define DOLBY_PARAM_ID_ARBL 0x00010762 +#define DOLBY_PARAM_ID_ARBH 0x00010763 +#define DOLBY_PARAM_ID_AROD 0x00010764 +#define DOLBY_PARAM_ID_ARTP 0x00010765 +#define DOLBY_PARAM_ID_VMON 0x00010756 +#define DOLBY_PARAM_ID_VMB 0x00010757 +#define DOLBY_PARAM_ID_VCNB 0x00010733 +#define DOLBY_PARAM_ID_VCBF 0x00010734 +#define DOLBY_PARAM_ID_PREG 0x00010728 +#define DOLBY_PARAM_ID_VEN 0x00010732 +#define DOLBY_PARAM_ID_PSTG 0x00010729 +#define DOLBY_PARAM_ID_INIT_ENDP 0x00010727 + +/* Not Used with Set Param kcontrol, only to query using Get Param */ +#define DOLBY_PARAM_ID_VER 0x00010726 + +#define DOLBY_PARAM_ID_VCBG 0x00010730 +#define DOLBY_PARAM_ID_VCBE 0x00010731 + +/* DOLBY DAP control params */ +#define DOLBY_COMMIT_ALL_TO_DSP 0x70000001 +#define DOLBY_COMMIT_TO_DSP 0x70000002 +#define DOLBY_USE_CACHE 0x70000003 +#define DOLBY_AUTO_ENDP 0x70000004 +#define DOLBY_AUTO_ENDDEP_PARAMS 0x70000005 +#define DOLBY_DAP_BYPASS 0x70000006 + +#define DOLBY_ENABLE_CUSTOM_STEREO 0x000108c7 + +/* DOLBY DAP offsets start */ +#define DOLBY_PARAM_VDHE_LENGTH 1 +#define DOLBY_PARAM_VDHE_OFFSET 0 +#define DOLBY_PARAM_VSPE_LENGTH 1 +#define DOLBY_PARAM_VSPE_OFFSET (DOLBY_PARAM_VDHE_OFFSET + \ + DOLBY_PARAM_VDHE_LENGTH) +#define DOLBY_PARAM_DSSF_LENGTH 1 +#define DOLBY_PARAM_DSSF_OFFSET (DOLBY_PARAM_VSPE_OFFSET + \ + DOLBY_PARAM_VSPE_LENGTH) +#define DOLBY_PARAM_DVLI_LENGTH 1 +#define DOLBY_PARAM_DVLI_OFFSET (DOLBY_PARAM_DSSF_OFFSET + \ + DOLBY_PARAM_DSSF_LENGTH) +#define DOLBY_PARAM_DVLO_LENGTH 1 +#define DOLBY_PARAM_DVLO_OFFSET (DOLBY_PARAM_DVLI_OFFSET + \ + DOLBY_PARAM_DVLI_LENGTH) +#define DOLBY_PARAM_DVLE_LENGTH 1 +#define DOLBY_PARAM_DVLE_OFFSET (DOLBY_PARAM_DVLO_OFFSET + \ + DOLBY_PARAM_DVLO_LENGTH) +#define DOLBY_PARAM_DVMC_LENGTH 1 +#define DOLBY_PARAM_DVMC_OFFSET (DOLBY_PARAM_DVLE_OFFSET + \ + DOLBY_PARAM_DVLE_LENGTH) +#define DOLBY_PARAM_DVME_LENGTH 1 +#define DOLBY_PARAM_DVME_OFFSET (DOLBY_PARAM_DVMC_OFFSET + \ + DOLBY_PARAM_DVMC_LENGTH) +#define DOLBY_PARAM_IENB_LENGTH 1 +#define DOLBY_PARAM_IENB_OFFSET (DOLBY_PARAM_DVME_OFFSET + \ + DOLBY_PARAM_DVME_LENGTH) +#define DOLBY_PARAM_IEBF_LENGTH 40 +#define DOLBY_PARAM_IEBF_OFFSET (DOLBY_PARAM_IENB_OFFSET + \ + DOLBY_PARAM_IENB_LENGTH) +#define DOLBY_PARAM_IEON_LENGTH 1 +#define DOLBY_PARAM_IEON_OFFSET (DOLBY_PARAM_IEBF_OFFSET + \ + DOLBY_PARAM_IEBF_LENGTH) +#define DOLBY_PARAM_DEON_LENGTH 1 +#define DOLBY_PARAM_DEON_OFFSET (DOLBY_PARAM_IEON_OFFSET + \ + DOLBY_PARAM_IEON_LENGTH) +#define DOLBY_PARAM_NGON_LENGTH 1 +#define DOLBY_PARAM_NGON_OFFSET (DOLBY_PARAM_DEON_OFFSET + \ + DOLBY_PARAM_DEON_LENGTH) +#define DOLBY_PARAM_GEON_LENGTH 1 +#define DOLBY_PARAM_GEON_OFFSET (DOLBY_PARAM_NGON_OFFSET + \ + DOLBY_PARAM_NGON_LENGTH) +#define DOLBY_PARAM_GENB_LENGTH 1 +#define DOLBY_PARAM_GENB_OFFSET (DOLBY_PARAM_GEON_OFFSET + \ + DOLBY_PARAM_GEON_LENGTH) +#define DOLBY_PARAM_GEBF_LENGTH 40 +#define DOLBY_PARAM_GEBF_OFFSET (DOLBY_PARAM_GENB_OFFSET + \ + DOLBY_PARAM_GENB_LENGTH) +#define DOLBY_PARAM_AONB_LENGTH 1 +#define DOLBY_PARAM_AONB_OFFSET (DOLBY_PARAM_GEBF_OFFSET + \ + DOLBY_PARAM_GEBF_LENGTH) +#define DOLBY_PARAM_AOBF_LENGTH 40 +#define DOLBY_PARAM_AOBF_OFFSET (DOLBY_PARAM_AONB_OFFSET + \ + DOLBY_PARAM_AONB_LENGTH) +#define DOLBY_PARAM_AOBG_LENGTH 329 +#define DOLBY_PARAM_AOBG_OFFSET (DOLBY_PARAM_AOBF_OFFSET + \ + DOLBY_PARAM_AOBF_LENGTH) +#define DOLBY_PARAM_AOON_LENGTH 1 +#define DOLBY_PARAM_AOON_OFFSET (DOLBY_PARAM_AOBG_OFFSET + \ + DOLBY_PARAM_AOBG_LENGTH) +#define DOLBY_PARAM_ARNB_LENGTH 1 +#define DOLBY_PARAM_ARNB_OFFSET (DOLBY_PARAM_AOON_OFFSET + \ + DOLBY_PARAM_AOON_LENGTH) +#define DOLBY_PARAM_ARBF_LENGTH 40 +#define DOLBY_PARAM_ARBF_OFFSET (DOLBY_PARAM_ARNB_OFFSET + \ + DOLBY_PARAM_ARNB_LENGTH) +#define DOLBY_PARAM_PLB_LENGTH 1 +#define DOLBY_PARAM_PLB_OFFSET (DOLBY_PARAM_ARBF_OFFSET + \ + DOLBY_PARAM_ARBF_LENGTH) +#define DOLBY_PARAM_PLMD_LENGTH 1 +#define DOLBY_PARAM_PLMD_OFFSET (DOLBY_PARAM_PLB_OFFSET + \ + DOLBY_PARAM_PLB_LENGTH) +#define DOLBY_PARAM_DHSB_LENGTH 1 +#define DOLBY_PARAM_DHSB_OFFSET (DOLBY_PARAM_PLMD_OFFSET + \ + DOLBY_PARAM_PLMD_LENGTH) +#define DOLBY_PARAM_DHRG_LENGTH 1 +#define DOLBY_PARAM_DHRG_OFFSET (DOLBY_PARAM_DHSB_OFFSET + \ + DOLBY_PARAM_DHSB_LENGTH) +#define DOLBY_PARAM_DSSB_LENGTH 1 +#define DOLBY_PARAM_DSSB_OFFSET (DOLBY_PARAM_DHRG_OFFSET + \ + DOLBY_PARAM_DHRG_LENGTH) +#define DOLBY_PARAM_DSSA_LENGTH 1 +#define DOLBY_PARAM_DSSA_OFFSET (DOLBY_PARAM_DSSB_OFFSET + \ + DOLBY_PARAM_DSSB_LENGTH) +#define DOLBY_PARAM_DVLA_LENGTH 1 +#define DOLBY_PARAM_DVLA_OFFSET (DOLBY_PARAM_DSSA_OFFSET + \ + DOLBY_PARAM_DSSA_LENGTH) +#define DOLBY_PARAM_IEBT_LENGTH 40 +#define DOLBY_PARAM_IEBT_OFFSET (DOLBY_PARAM_DVLA_OFFSET + \ + DOLBY_PARAM_DVLA_LENGTH) +#define DOLBY_PARAM_IEA_LENGTH 1 +#define DOLBY_PARAM_IEA_OFFSET (DOLBY_PARAM_IEBT_OFFSET + \ + DOLBY_PARAM_IEBT_LENGTH) +#define DOLBY_PARAM_DEA_LENGTH 1 +#define DOLBY_PARAM_DEA_OFFSET (DOLBY_PARAM_IEA_OFFSET + \ + DOLBY_PARAM_IEA_LENGTH) +#define DOLBY_PARAM_DED_LENGTH 1 +#define DOLBY_PARAM_DED_OFFSET (DOLBY_PARAM_DEA_OFFSET + \ + DOLBY_PARAM_DEA_LENGTH) +#define DOLBY_PARAM_GEBG_LENGTH 40 +#define DOLBY_PARAM_GEBG_OFFSET (DOLBY_PARAM_DED_OFFSET + \ + DOLBY_PARAM_DED_LENGTH) +#define DOLBY_PARAM_AOCC_LENGTH 1 +#define DOLBY_PARAM_AOCC_OFFSET (DOLBY_PARAM_GEBG_OFFSET + \ + DOLBY_PARAM_GEBG_LENGTH) +#define DOLBY_PARAM_ARBI_LENGTH 40 +#define DOLBY_PARAM_ARBI_OFFSET (DOLBY_PARAM_AOCC_OFFSET + \ + DOLBY_PARAM_AOCC_LENGTH) +#define DOLBY_PARAM_ARBL_LENGTH 40 +#define DOLBY_PARAM_ARBL_OFFSET (DOLBY_PARAM_ARBI_OFFSET + \ + DOLBY_PARAM_ARBI_LENGTH) +#define DOLBY_PARAM_ARBH_LENGTH 40 +#define DOLBY_PARAM_ARBH_OFFSET (DOLBY_PARAM_ARBL_OFFSET + \ + DOLBY_PARAM_ARBL_LENGTH) +#define DOLBY_PARAM_AROD_LENGTH 1 +#define DOLBY_PARAM_AROD_OFFSET (DOLBY_PARAM_ARBH_OFFSET + \ + DOLBY_PARAM_ARBH_LENGTH) +#define DOLBY_PARAM_ARTP_LENGTH 1 +#define DOLBY_PARAM_ARTP_OFFSET (DOLBY_PARAM_AROD_OFFSET + \ + DOLBY_PARAM_AROD_LENGTH) +#define DOLBY_PARAM_VMON_LENGTH 1 +#define DOLBY_PARAM_VMON_OFFSET (DOLBY_PARAM_ARTP_OFFSET + \ + DOLBY_PARAM_ARTP_LENGTH) +#define DOLBY_PARAM_VMB_LENGTH 1 +#define DOLBY_PARAM_VMB_OFFSET (DOLBY_PARAM_VMON_OFFSET + \ + DOLBY_PARAM_VMON_LENGTH) +#define DOLBY_PARAM_VCNB_LENGTH 1 +#define DOLBY_PARAM_VCNB_OFFSET (DOLBY_PARAM_VMB_OFFSET + \ + DOLBY_PARAM_VMB_LENGTH) +#define DOLBY_PARAM_VCBF_LENGTH 20 +#define DOLBY_PARAM_VCBF_OFFSET (DOLBY_PARAM_VCNB_OFFSET + \ + DOLBY_PARAM_VCNB_LENGTH) +#define DOLBY_PARAM_PREG_LENGTH 1 +#define DOLBY_PARAM_PREG_OFFSET (DOLBY_PARAM_VCBF_OFFSET + \ + DOLBY_PARAM_VCBF_LENGTH) +#define DOLBY_PARAM_VEN_LENGTH 1 +#define DOLBY_PARAM_VEN_OFFSET (DOLBY_PARAM_PREG_OFFSET + \ + DOLBY_PARAM_PREG_LENGTH) +#define DOLBY_PARAM_PSTG_LENGTH 1 +#define DOLBY_PARAM_PSTG_OFFSET (DOLBY_PARAM_VEN_OFFSET + \ + DOLBY_PARAM_VEN_LENGTH) + +#define DOLBY_PARAM_INT_ENDP_LENGTH 1 +#define DOLBY_PARAM_PAYLOAD_SIZE 3 +#define DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM 329 + +#define TOTAL_LENGTH_DOLBY_PARAM 745 +#define DOLBY_VIS_PARAM_HEADER_SIZE 25 +#define DOLBY_PARAM_VCNB_MAX_LENGTH 40 + +#define DOLBY_INVALID_PORT_ID -1 + +enum { + DEVICE_NONE = 0x0, + /* output devices */ + EARPIECE = 0x1, + SPEAKER = 0x2, + WIRED_HEADSET = 0x4, + WIRED_HEADPHONE = 0x8, + BLUETOOTH_SCO = 0x10, + BLUETOOTH_SCO_HEADSET = 0x20, + BLUETOOTH_SCO_CARKIT = 0x40, + BLUETOOTH_A2DP = 0x80, + BLUETOOTH_A2DP_HEADPHONES = 0x100, + BLUETOOTH_A2DP_SPEAKER = 0x200, + AUX_DIGITAL = 0x400, + ANLG_DOCK_HEADSET = 0x800, + DGTL_DOCK_HEADSET = 0x1000, + USB_ACCESSORY = 0x2000, + USB_DEVICE = 0x4000, + REMOTE_SUBMIX = 0x8000, + ANC_HEADSET = 0x10000, + ANC_HEADPHONE = 0x20000, + PROXY = 0x2000000, + FM = 0x100000, + FM_TX = 0x1000000, + DEVICE_OUT_DEFAULT = 0x40000000, + DEVICE_OUT_ALL = 0x403FFFFF, +}; +#endif diff --git a/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h b/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h new file mode 100644 index 000000000000..6204cb15857d --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _MSM_DOLBY_DAP_CONFIG_H_ +#define _MSM_DOLBY_DAP_CONFIG_H_ + +#include +#include "msm-dolby-common.h" + +#ifdef CONFIG_DOLBY_DAP +/* DOLBY DOLBY GUIDS */ +#define DOLBY_ADM_COPP_TOPOLOGY_ID 0x0001033B +#define NUM_DOLBY_ENDP_DEVICE 23 + +#define DOLBY_NUM_ENDP_DEPENDENT_PARAMS 3 +#define DOLBY_ENDDEP_PARAM_DVLO_OFFSET 0 +#define DOLBY_ENDDEP_PARAM_DVLO_LENGTH 1 +#define DOLBY_ENDDEP_PARAM_DVLI_OFFSET (DOLBY_ENDDEP_PARAM_DVLO_OFFSET + \ + DOLBY_ENDDEP_PARAM_DVLO_LENGTH) +#define DOLBY_ENDDEP_PARAM_DVLI_LENGTH 1 +#define DOLBY_ENDDEP_PARAM_VMB_OFFSET (DOLBY_ENDDEP_PARAM_DVLI_OFFSET + \ + DOLBY_ENDDEP_PARAM_DVLI_LENGTH) +#define DOLBY_ENDDEP_PARAM_VMB_LENGTH 1 +#define DOLBY_ENDDEP_PARAM_LENGTH (DOLBY_ENDDEP_PARAM_DVLO_LENGTH + \ + DOLBY_ENDDEP_PARAM_DVLI_LENGTH + DOLBY_ENDDEP_PARAM_VMB_LENGTH) + +#define MAX_DOLBY_PARAMS 47 +#define MAX_DOLBY_CTRL_PARAMS 5 +#define ALL_DOLBY_PARAMS (MAX_DOLBY_PARAMS + \ + MAX_DOLBY_CTRL_PARAMS) +#define DOLBY_COMMIT_ALL_IDX MAX_DOLBY_PARAMS +#define DOLBY_COMMIT_IDX (MAX_DOLBY_PARAMS+1) +#define DOLBY_USE_CACHE_IDX (MAX_DOLBY_PARAMS+2) +#define DOLBY_AUTO_ENDP_IDX (MAX_DOLBY_PARAMS+3) +#define DOLBY_AUTO_ENDDEP_IDX (MAX_DOLBY_PARAMS+4) + +/* DOLBY device definitions */ +enum { + DOLBY_ENDP_INT_SPEAKERS = 0, + DOLBY_ENDP_EXT_SPEAKERS, + DOLBY_ENDP_HEADPHONES, + DOLBY_ENDP_HDMI, + DOLBY_ENDP_SPDIF, + DOLBY_ENDP_DLNA, + DOLBY_ENDP_ANALOG, +}; + +/* DOLBY device definitions end */ + +struct dolby_dap_params { + uint32_t value[TOTAL_LENGTH_DOLBY_PARAM + MAX_DOLBY_PARAMS]; +} __packed; + +int msm_dolby_dap_init(int port_id, int copp_idx, int channels, + bool is_custom_stereo_on); +void msm_dolby_dap_deinit(int port_id); +void msm_dolby_dap_add_controls(struct snd_soc_platform *platform); +int dolby_dap_set_custom_stereo_onoff(int port_id, int copp_idx, + bool is_custom_stereo_enabled); +/* Dolby DOLBY end */ +#else +int msm_dolby_dap_init(int port_id, int copp_idx, int channels, + bool is_custom_stereo_on) +{ + return 0; +} +void msm_dolby_dap_deinit(int port_id) { } +void msm_dolby_dap_add_controls(struct snd_soc_platform *platform) { } +int dolby_dap_set_custom_stereo_onoff(int port_id, int copp_idx, + bool is_custom_stereo_enabled) +{ + return 0; +} +#endif + +#endif diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c new file mode 100644 index 000000000000..5c9393f7e407 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -0,0 +1,2317 @@ +/* + * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +#include "msm-ds2-dap-config.h" +#include "msm-pcm-routing-v2.h" +#include + + +#if defined(CONFIG_DOLBY_DS2) || defined(CONFIG_DOLBY_LICENSE) + +/* ramp up/down for 30ms */ +#define DOLBY_SOFT_VOLUME_PERIOD 40 +/* Step value 0ms or 0us */ +#define DOLBY_SOFT_VOLUME_STEP 1000 +#define DOLBY_ADDITIONAL_RAMP_WAIT 10 +#define SOFT_VOLUME_PARAM_SIZE 3 +#define PARAM_PAYLOAD_SIZE 3 + +enum { + DOLBY_SOFT_VOLUME_CURVE_LINEAR = 0, + DOLBY_SOFT_VOLUME_CURVE_EXP, + DOLBY_SOFT_VOLUME_CURVE_LOG, +}; + +#define VOLUME_ZERO_GAIN 0x0 +#define VOLUME_UNITY_GAIN 0x2000 +/* Wait time for module enable/disble */ +#define DOLBY_MODULE_ENABLE_PERIOD 50 + +/* DOLBY device definitions end */ +enum { + DOLBY_OFF_CACHE = 0, + DOLBY_SPEAKER_CACHE, + DOLBY_HEADPHONE_CACHE, + DOLBY_HDMI_CACHE, + DOLBY_WFD_CACHE, + DOLBY_FM_CACHE, + DOLBY_MAX_CACHE, +}; + +enum { + DAP_SOFT_BYPASS = 0, + DAP_HARD_BYPASS, +}; + +enum { + MODULE_DISABLE = 0, + MODULE_ENABLE, +}; +/* dolby param ids to/from dsp */ +static uint32_t ds2_dap_params_id[MAX_DS2_PARAMS] = { + DOLBY_PARAM_ID_VDHE, DOLBY_PARAM_ID_VSPE, DOLBY_PARAM_ID_DSSF, + DOLBY_PARAM_ID_DVLI, DOLBY_PARAM_ID_DVLO, DOLBY_PARAM_ID_DVLE, + DOLBY_PARAM_ID_DVMC, DOLBY_PARAM_ID_DVME, DOLBY_PARAM_ID_IENB, + DOLBY_PARAM_ID_IEBF, DOLBY_PARAM_ID_IEON, DOLBY_PARAM_ID_DEON, + DOLBY_PARAM_ID_NGON, DOLBY_PARAM_ID_GEON, DOLBY_PARAM_ID_GENB, + DOLBY_PARAM_ID_GEBF, DOLBY_PARAM_ID_AONB, DOLBY_PARAM_ID_AOBF, + DOLBY_PARAM_ID_AOBG, DOLBY_PARAM_ID_AOON, DOLBY_PARAM_ID_ARNB, + DOLBY_PARAM_ID_ARBF, DOLBY_PARAM_ID_PLB, DOLBY_PARAM_ID_PLMD, + DOLBY_PARAM_ID_DHSB, DOLBY_PARAM_ID_DHRG, DOLBY_PARAM_ID_DSSB, + DOLBY_PARAM_ID_DSSA, DOLBY_PARAM_ID_DVLA, DOLBY_PARAM_ID_IEBT, + DOLBY_PARAM_ID_IEA, DOLBY_PARAM_ID_DEA, DOLBY_PARAM_ID_DED, + DOLBY_PARAM_ID_GEBG, DOLBY_PARAM_ID_AOCC, DOLBY_PARAM_ID_ARBI, + DOLBY_PARAM_ID_ARBL, DOLBY_PARAM_ID_ARBH, DOLBY_PARAM_ID_AROD, + DOLBY_PARAM_ID_ARTP, DOLBY_PARAM_ID_VMON, DOLBY_PARAM_ID_VMB, + DOLBY_PARAM_ID_VCNB, DOLBY_PARAM_ID_VCBF, DOLBY_PARAM_ID_PREG, + DOLBY_PARAM_ID_VEN, DOLBY_PARAM_ID_PSTG, DOLBY_PARAM_ID_INIT_ENDP, +}; + +/* modifed state: 0x00000000 - Not updated + * > 0x00000000 && < 0x00010000 + * Updated and not committed to DSP + * 0x00010001 - Updated and committed to DSP + * > 0x00010001 - Modified the committed value + */ +/* param offset */ +static uint32_t ds2_dap_params_offset[MAX_DS2_PARAMS] = { + DOLBY_PARAM_VDHE_OFFSET, DOLBY_PARAM_VSPE_OFFSET, + DOLBY_PARAM_DSSF_OFFSET, DOLBY_PARAM_DVLI_OFFSET, + DOLBY_PARAM_DVLO_OFFSET, DOLBY_PARAM_DVLE_OFFSET, + DOLBY_PARAM_DVMC_OFFSET, DOLBY_PARAM_DVME_OFFSET, + DOLBY_PARAM_IENB_OFFSET, DOLBY_PARAM_IEBF_OFFSET, + DOLBY_PARAM_IEON_OFFSET, DOLBY_PARAM_DEON_OFFSET, + DOLBY_PARAM_NGON_OFFSET, DOLBY_PARAM_GEON_OFFSET, + DOLBY_PARAM_GENB_OFFSET, DOLBY_PARAM_GEBF_OFFSET, + DOLBY_PARAM_AONB_OFFSET, DOLBY_PARAM_AOBF_OFFSET, + DOLBY_PARAM_AOBG_OFFSET, DOLBY_PARAM_AOON_OFFSET, + DOLBY_PARAM_ARNB_OFFSET, DOLBY_PARAM_ARBF_OFFSET, + DOLBY_PARAM_PLB_OFFSET, DOLBY_PARAM_PLMD_OFFSET, + DOLBY_PARAM_DHSB_OFFSET, DOLBY_PARAM_DHRG_OFFSET, + DOLBY_PARAM_DSSB_OFFSET, DOLBY_PARAM_DSSA_OFFSET, + DOLBY_PARAM_DVLA_OFFSET, DOLBY_PARAM_IEBT_OFFSET, + DOLBY_PARAM_IEA_OFFSET, DOLBY_PARAM_DEA_OFFSET, + DOLBY_PARAM_DED_OFFSET, DOLBY_PARAM_GEBG_OFFSET, + DOLBY_PARAM_AOCC_OFFSET, DOLBY_PARAM_ARBI_OFFSET, + DOLBY_PARAM_ARBL_OFFSET, DOLBY_PARAM_ARBH_OFFSET, + DOLBY_PARAM_AROD_OFFSET, DOLBY_PARAM_ARTP_OFFSET, + DOLBY_PARAM_VMON_OFFSET, DOLBY_PARAM_VMB_OFFSET, + DOLBY_PARAM_VCNB_OFFSET, DOLBY_PARAM_VCBF_OFFSET, + DOLBY_PARAM_PREG_OFFSET, DOLBY_PARAM_VEN_OFFSET, + DOLBY_PARAM_PSTG_OFFSET, DOLBY_PARAM_INT_ENDP_OFFSET, +}; +/* param_length */ +static uint32_t ds2_dap_params_length[MAX_DS2_PARAMS] = { + DOLBY_PARAM_VDHE_LENGTH, DOLBY_PARAM_VSPE_LENGTH, + DOLBY_PARAM_DSSF_LENGTH, DOLBY_PARAM_DVLI_LENGTH, + DOLBY_PARAM_DVLO_LENGTH, DOLBY_PARAM_DVLE_LENGTH, + DOLBY_PARAM_DVMC_LENGTH, DOLBY_PARAM_DVME_LENGTH, + DOLBY_PARAM_IENB_LENGTH, DOLBY_PARAM_IEBF_LENGTH, + DOLBY_PARAM_IEON_LENGTH, DOLBY_PARAM_DEON_LENGTH, + DOLBY_PARAM_NGON_LENGTH, DOLBY_PARAM_GEON_LENGTH, + DOLBY_PARAM_GENB_LENGTH, DOLBY_PARAM_GEBF_LENGTH, + DOLBY_PARAM_AONB_LENGTH, DOLBY_PARAM_AOBF_LENGTH, + DOLBY_PARAM_AOBG_LENGTH, DOLBY_PARAM_AOON_LENGTH, + DOLBY_PARAM_ARNB_LENGTH, DOLBY_PARAM_ARBF_LENGTH, + DOLBY_PARAM_PLB_LENGTH, DOLBY_PARAM_PLMD_LENGTH, + DOLBY_PARAM_DHSB_LENGTH, DOLBY_PARAM_DHRG_LENGTH, + DOLBY_PARAM_DSSB_LENGTH, DOLBY_PARAM_DSSA_LENGTH, + DOLBY_PARAM_DVLA_LENGTH, DOLBY_PARAM_IEBT_LENGTH, + DOLBY_PARAM_IEA_LENGTH, DOLBY_PARAM_DEA_LENGTH, + DOLBY_PARAM_DED_LENGTH, DOLBY_PARAM_GEBG_LENGTH, + DOLBY_PARAM_AOCC_LENGTH, DOLBY_PARAM_ARBI_LENGTH, + DOLBY_PARAM_ARBL_LENGTH, DOLBY_PARAM_ARBH_LENGTH, + DOLBY_PARAM_AROD_LENGTH, DOLBY_PARAM_ARTP_LENGTH, + DOLBY_PARAM_VMON_LENGTH, DOLBY_PARAM_VMB_LENGTH, + DOLBY_PARAM_VCNB_LENGTH, DOLBY_PARAM_VCBF_LENGTH, + DOLBY_PARAM_PREG_LENGTH, DOLBY_PARAM_VEN_LENGTH, + DOLBY_PARAM_PSTG_LENGTH, DOLBY_PARAM_INT_ENDP_LENGTH, +}; + +struct ds2_dap_params_s { + int32_t params_val[TOTAL_LENGTH_DS2_PARAM]; + int32_t dap_params_modified[MAX_DS2_PARAMS]; +}; + +struct audio_rx_cal_data { + char aud_proc_data[AUD_PROC_BLOCK_SIZE]; + int32_t aud_proc_size; + char aud_vol_data[AUD_VOL_BLOCK_SIZE]; + int32_t aud_vol_size; +}; + +static struct ds2_dap_params_s ds2_dap_params[DOLBY_MAX_CACHE]; + +struct ds2_device_mapping { + int32_t device_id; /* audio_out_... */ + int port_id; /* afe port. constant for a target variant. routing-v2*/ + /*Only one Dolby COPP for a specific port*/ + int copp_idx; /* idx for the copp port on which ds2 is active */ + int cache_dev; /* idx to a shared parameter array dependent on device*/ + uint32_t stream_ref_count; + bool active; + void *cal_data; +}; + +static struct ds2_device_mapping dev_map[DS2_DEVICES_ALL]; + +struct ds2_dap_params_states_s { + bool use_cache; + bool dap_bypass; + bool dap_bypass_type; + bool node_opened; + int32_t device; + bool custom_stereo_onoff; +}; + +static struct ds2_dap_params_states_s ds2_dap_params_states = {true, false, + false, DEVICE_NONE}; + +static int all_supported_devices = EARPIECE|SPEAKER|WIRED_HEADSET| + WIRED_HEADPHONE|BLUETOOTH_SCO|AUX_DIGITAL| + ANLG_DOCK_HEADSET|DGTL_DOCK_HEADSET| + REMOTE_SUBMIX|ANC_HEADSET|ANC_HEADPHONE| + PROXY|FM|FM_TX|DEVICE_NONE| + BLUETOOTH_SCO_HEADSET|BLUETOOTH_SCO_CARKIT; + + +static void msm_ds2_dap_check_and_update_ramp_wait(int port_id, int copp_idx, + int *ramp_wait) +{ + + int32_t *update_params_value = NULL; + uint32_t params_length = SOFT_VOLUME_PARAM_SIZE * sizeof(uint32_t); + uint32_t param_payload_len = PARAM_PAYLOAD_SIZE * sizeof(uint32_t); + int rc = 0; + + update_params_value = kzalloc(params_length + param_payload_len, + GFP_KERNEL); + if (!update_params_value) + goto end; + + rc = adm_get_params(port_id, copp_idx, + AUDPROC_MODULE_ID_VOL_CTRL, + AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS, + params_length + param_payload_len, + (char *) update_params_value); + if (rc == 0) { + pr_debug("%s: params_value [0x%x, 0x%x, 0x%x]\n", + __func__, update_params_value[0], + update_params_value[1], + update_params_value[2]); + *ramp_wait = update_params_value[0]; + } +end: + kfree(update_params_value); + /* + * No error returned as we do not need to error out from dap on/dap + * bypass. The default ramp parameter will be used to wait during + * ramp down. + */ +} + +static int msm_ds2_dap_set_vspe_vdhe(int dev_map_idx, + bool is_custom_stereo_enabled) +{ + int32_t *update_params_value = NULL; + int32_t *param_val = NULL; + int idx, i, j, rc = 0, cdev; + uint32_t params_length = (TOTAL_LENGTH_DOLBY_PARAM + + 2 * DOLBY_PARAM_PAYLOAD_SIZE) * + sizeof(uint32_t); + + if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { + pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); + rc = -EINVAL; + goto end; + } + + if (dev_map[dev_map_idx].port_id == DOLBY_INVALID_PORT_ID) { + pr_err("%s: Invalid port id\n", __func__); + rc = -EINVAL; + goto end; + } + + if ((dev_map[dev_map_idx].copp_idx < 0) || + (dev_map[dev_map_idx].copp_idx >= MAX_COPPS_PER_PORT)) { + pr_err("%s: Invalid copp_idx\n", __func__); + rc = -EINVAL; + goto end; + } + + if ((dev_map[dev_map_idx].port_id != SLIMBUS_0_RX) && + (dev_map[dev_map_idx].port_id != RT_PROXY_PORT_001_RX)) { + pr_debug("%s:No Custom stereo for port:0x%x\n", + __func__, dev_map[dev_map_idx].port_id); + goto end; + } + + update_params_value = kzalloc(params_length, GFP_KERNEL); + if (!update_params_value) { + rc = -ENOMEM; + goto end; + } + params_length = 0; + param_val = update_params_value; + cdev = dev_map[dev_map_idx].cache_dev; + /* for VDHE and VSPE DAP params at index 0 and 1 in table */ + for (i = 0; i < 2; i++) { + *update_params_value++ = DOLBY_BUNDLE_MODULE_ID; + *update_params_value++ = ds2_dap_params_id[i]; + *update_params_value++ = ds2_dap_params_length[i] * + sizeof(uint32_t); + idx = ds2_dap_params_offset[i]; + for (j = 0; j < ds2_dap_params_length[i]; j++) { + if (is_custom_stereo_enabled) + *update_params_value++ = 0; + else + *update_params_value++ = + ds2_dap_params[cdev].params_val[idx+j]; + } + params_length += (DOLBY_PARAM_PAYLOAD_SIZE + + ds2_dap_params_length[i]) * + sizeof(uint32_t); + } + + pr_debug("%s: valid param length: %d\n", __func__, params_length); + if (params_length) { + rc = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, + (char *)param_val, + params_length); + if (rc) { + pr_err("%s: send vdhe/vspe params failed with rc=%d\n", + __func__, rc); + rc = -EINVAL; + goto end; + } + } +end: + kfree(param_val); + return rc; +} + +int qti_set_custom_stereo_on(int port_id, int copp_idx, + bool is_custom_stereo_on) +{ + + uint16_t op_FL_ip_FL_weight; + uint16_t op_FL_ip_FR_weight; + uint16_t op_FR_ip_FL_weight; + uint16_t op_FR_ip_FR_weight; + + int32_t *update_params_value32 = NULL, rc = 0; + int32_t *param_val = NULL; + int16_t *update_params_value16 = 0; + uint32_t params_length_bytes = CUSTOM_STEREO_PAYLOAD_SIZE * + sizeof(uint32_t); + uint32_t avail_length = params_length_bytes; + + if ((port_id != SLIMBUS_0_RX) && + (port_id != RT_PROXY_PORT_001_RX)) { + pr_debug("%s:No Custom stereo for port:0x%x\n", + __func__, port_id); + goto skip_send_cmd; + } + + pr_debug("%s: port 0x%x, copp_idx %d, is_custom_stereo_on %d\n", + __func__, port_id, copp_idx, is_custom_stereo_on); + if (is_custom_stereo_on) { + op_FL_ip_FL_weight = + Q14_GAIN_ZERO_POINT_FIVE; + op_FL_ip_FR_weight = + Q14_GAIN_ZERO_POINT_FIVE; + op_FR_ip_FL_weight = + Q14_GAIN_ZERO_POINT_FIVE; + op_FR_ip_FR_weight = + Q14_GAIN_ZERO_POINT_FIVE; + } else { + op_FL_ip_FL_weight = Q14_GAIN_UNITY; + op_FL_ip_FR_weight = 0; + op_FR_ip_FL_weight = 0; + op_FR_ip_FR_weight = Q14_GAIN_UNITY; + } + + update_params_value32 = kzalloc(params_length_bytes, GFP_KERNEL); + if (!update_params_value32) { + rc = -ENOMEM; + goto skip_send_cmd; + } + param_val = update_params_value32; + if (avail_length < 2 * sizeof(uint32_t)) + goto skip_send_cmd; + *update_params_value32++ = MTMX_MODULE_ID_DEFAULT_CHMIXER; + *update_params_value32++ = DEFAULT_CHMIXER_PARAM_ID_COEFF; + avail_length = avail_length - (2 * sizeof(uint32_t)); + + update_params_value16 = (int16_t *)update_params_value32; + if (avail_length < 10 * sizeof(uint16_t)) + goto skip_send_cmd; + *update_params_value16++ = CUSTOM_STEREO_CMD_PARAM_SIZE; + /* for alignment only*/ + *update_params_value16++ = 0; + /* index is 32-bit param in little endian*/ + *update_params_value16++ = CUSTOM_STEREO_INDEX_PARAM; + *update_params_value16++ = 0; + /* for stereo mixing num out ch*/ + *update_params_value16++ = CUSTOM_STEREO_NUM_OUT_CH; + /* for stereo mixing num in ch*/ + *update_params_value16++ = CUSTOM_STEREO_NUM_IN_CH; + + /* Out ch map FL/FR*/ + *update_params_value16++ = PCM_CHANNEL_FL; + *update_params_value16++ = PCM_CHANNEL_FR; + + /* In ch map FL/FR*/ + *update_params_value16++ = PCM_CHANNEL_FL; + *update_params_value16++ = PCM_CHANNEL_FR; + avail_length = avail_length - (10 * sizeof(uint16_t)); + /* weighting coefficients as name suggests, + * mixing will be done according to these coefficients + */ + if (avail_length < 4 * sizeof(uint16_t)) + goto skip_send_cmd; + *update_params_value16++ = op_FL_ip_FL_weight; + *update_params_value16++ = op_FL_ip_FR_weight; + *update_params_value16++ = op_FR_ip_FL_weight; + *update_params_value16++ = op_FR_ip_FR_weight; + avail_length = avail_length - (4 * sizeof(uint16_t)); + if (params_length_bytes != 0) { + rc = adm_dolby_dap_send_params(port_id, copp_idx, + (char *)param_val, + params_length_bytes); + if (rc) { + pr_err("%s: send params failed rc=%d\n", __func__, rc); + rc = -EINVAL; + goto skip_send_cmd; + } + } + kfree(param_val); + return 0; +skip_send_cmd: + pr_err("%s: insufficient memory, send cmd failed\n", + __func__); + kfree(param_val); + return rc; +} +static int dap_set_custom_stereo_onoff(int dev_map_idx, + bool is_custom_stereo_enabled) +{ + + int32_t *update_params_value = NULL, rc = 0; + int32_t *param_val = NULL; + uint32_t params_length_bytes = (TOTAL_LENGTH_DOLBY_PARAM + + DOLBY_PARAM_PAYLOAD_SIZE) * sizeof(uint32_t); + if ((dev_map[dev_map_idx].port_id != SLIMBUS_0_RX) && + (dev_map[dev_map_idx].port_id != RT_PROXY_PORT_001_RX)) { + pr_debug("%s:No Custom stereo for port:0x%x\n", + __func__, dev_map[dev_map_idx].port_id); + goto end; + } + + if ((dev_map[dev_map_idx].copp_idx < 0) || + (dev_map[dev_map_idx].copp_idx >= MAX_COPPS_PER_PORT)) { + rc = -EINVAL; + goto end; + } + + /* DAP custom stereo */ + msm_ds2_dap_set_vspe_vdhe(dev_map_idx, + is_custom_stereo_enabled); + update_params_value = kzalloc(params_length_bytes, GFP_KERNEL); + if (!update_params_value) { + pr_err("%s: params memory alloc failed\n", __func__); + rc = -ENOMEM; + goto end; + } + params_length_bytes = 0; + param_val = update_params_value; + *update_params_value++ = DOLBY_BUNDLE_MODULE_ID; + *update_params_value++ = DOLBY_ENABLE_CUSTOM_STEREO; + *update_params_value++ = sizeof(uint32_t); + if (is_custom_stereo_enabled) + *update_params_value++ = 1; + else + *update_params_value++ = 0; + params_length_bytes += (DOLBY_PARAM_PAYLOAD_SIZE + 1) * + sizeof(uint32_t); + pr_debug("%s: valid param length: %d\n", __func__, params_length_bytes); + if (params_length_bytes) { + rc = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, + (char *)param_val, + params_length_bytes); + if (rc) { + pr_err("%s: custom stereo param failed with rc=%d\n", + __func__, rc); + rc = -EINVAL; + goto end; + } + } +end: + kfree(param_val); + return rc; + +} + + +static int set_custom_stereo_onoff(int dev_map_idx, + bool is_custom_stereo_enabled) +{ + int rc = 0; + + pr_debug("%s: map index %d, custom stereo %d\n", __func__, dev_map_idx, + is_custom_stereo_enabled); + + if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { + pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); + rc = -EINVAL; + goto end; + } + + if (dev_map[dev_map_idx].port_id == DOLBY_INVALID_PORT_ID) { + pr_err("%s: invalid port id\n", __func__); + rc = -EINVAL; + goto end; + } + + if ((dev_map[dev_map_idx].copp_idx < 0) || + (dev_map[dev_map_idx].copp_idx >= MAX_COPPS_PER_PORT)) { + pr_err("%s: invalid copp idx\n", __func__); + rc = -EINVAL; + goto end; + } + + if (ds2_dap_params_states.dap_bypass == true && + ds2_dap_params_states.dap_bypass_type == DAP_HARD_BYPASS) { + + rc = qti_set_custom_stereo_on(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, + is_custom_stereo_enabled); + if (rc < 0) { + pr_err("%s:qti_set_custom_stereo_on_copp failed C.S %d", + __func__, is_custom_stereo_enabled); + } + goto end; + + } + + if (ds2_dap_params_states.dap_bypass == false) { + rc = dap_set_custom_stereo_onoff(dev_map_idx, + is_custom_stereo_enabled); + if (rc < 0) { + pr_err("%s:qti_set_custom_stereo_on_copp failed C.S %d", + __func__, is_custom_stereo_enabled); + } + goto end; + } +end: + return rc; +} + +static int msm_ds2_dap_alloc_and_store_cal_data(int dev_map_idx, int path, + int perf_mode) +{ + int rc = 0; + struct audio_rx_cal_data *aud_cal_data; + + pr_debug("%s: path %d, perf_mode %d, dev_map_idx %d\n", + __func__, path, perf_mode, dev_map_idx); + + if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { + pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); + rc = -EINVAL; + goto end; + } + + aud_cal_data = kzalloc(sizeof(struct audio_rx_cal_data), GFP_KERNEL); + if (!aud_cal_data) { + rc = -ENOMEM; + goto end; + } + + rc = adm_store_cal_data(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, path, perf_mode, + ADM_AUDPROC_CAL, aud_cal_data->aud_proc_data, + &aud_cal_data->aud_proc_size); + if (rc < 0) { + pr_err("%s: store cal data err %d\n", __func__, rc); + kfree(aud_cal_data); + goto end; + } + + rc = adm_store_cal_data(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, path, perf_mode, + ADM_AUDVOL_CAL, aud_cal_data->aud_vol_data, + &aud_cal_data->aud_vol_size); + if (rc < 0) { + pr_err("%s: store cal data err %d\n", __func__, rc); + kfree(aud_cal_data); + goto end; + } + + dev_map[dev_map_idx].cal_data = (void *)aud_cal_data; + +end: + pr_debug("%s: ret %d\n", __func__, rc); + return rc; +} + +static int msm_ds2_dap_free_cal_data(int dev_map_idx) +{ + int rc = 0; + struct audio_rx_cal_data *aud_cal_data; + + pr_debug("%s: dev_map_idx %d\n", __func__, dev_map_idx); + if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { + pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); + rc = -EINVAL; + goto end; + } + aud_cal_data = (struct audio_rx_cal_data *) + dev_map[dev_map_idx].cal_data; + kfree(aud_cal_data); + dev_map[dev_map_idx].cal_data = NULL; + +end: + return rc; +} + +static int msm_ds2_dap_send_cal_data(int dev_map_idx) +{ + int rc = 0; + struct audio_rx_cal_data *aud_cal_data = NULL; + + pr_debug("%s: devmap index %d\n", __func__, dev_map_idx); + if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { + pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); + rc = -EINVAL; + goto end; + } + + if (dev_map[dev_map_idx].cal_data == NULL) { + pr_err("%s: No valid calibration data stored for idx %d\n", + __func__, dev_map_idx); + rc = -EINVAL; + goto end; + } + + /* send aud proc cal */ + aud_cal_data = (struct audio_rx_cal_data *) + dev_map[dev_map_idx].cal_data; + rc = adm_send_calibration(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, + ADM_PATH_PLAYBACK, 0, + ADM_AUDPROC_CAL, + aud_cal_data->aud_proc_data, + aud_cal_data->aud_proc_size); + if (rc < 0) { + pr_err("%s: adm_send_calibration failed %d\n", __func__, rc); + goto end; + } + + /* send aud volume cal*/ + rc = adm_send_calibration(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, + ADM_PATH_PLAYBACK, 0, + ADM_AUDVOL_CAL, + aud_cal_data->aud_vol_data, + aud_cal_data->aud_vol_size); + if (rc < 0) + pr_err("%s: adm_send_calibration failed %d\n", __func__, rc); +end: + pr_debug("%s: return %d\n", __func__, rc); + return rc; +} + +static inline int msm_ds2_dap_can_enable_module(int32_t module_id) +{ + if (module_id == MTMX_MODULE_ID_DEFAULT_CHMIXER || + module_id == AUDPROC_MODULE_ID_RESAMPLER || + module_id == AUDPROC_MODULE_ID_VOL_CTRL) { + return false; + } + return true; +} + +static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) +{ + int rc = 0, i = 0, port_id, copp_idx; + /* Account for 32 bit integer allocation */ + int32_t param_sz = (ADM_GET_TOPO_MODULE_LIST_LENGTH / sizeof(uint32_t)); + int32_t *update_param_val = NULL; + + if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { + pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); + rc = -EINVAL; + goto end; + } + + port_id = dev_map[dev_map_idx].port_id; + copp_idx = dev_map[dev_map_idx].copp_idx; + pr_debug("%s: port_id 0x%x copp_idx %d\n", __func__, port_id, copp_idx); + update_param_val = kzalloc(ADM_GET_TOPO_MODULE_LIST_LENGTH, GFP_KERNEL); + if (!update_param_val) { + pr_err("%s, param memory alloc failed\n", __func__); + rc = -ENOMEM; + goto end; + } + + if (!ds2_dap_params_states.dap_bypass) { + /* get modules from dsp */ + rc = adm_get_pp_topo_module_list(port_id, copp_idx, + ADM_GET_TOPO_MODULE_LIST_LENGTH, + (char *)update_param_val); + if (rc < 0) { + pr_err("%s:topo list port %d, err %d,copp_idx %d\n", + __func__, port_id, copp_idx, rc); + goto end; + } + + if (update_param_val[0] > (param_sz - 1)) { + pr_err("%s:max modules exp/ret [%d: %d]\n", + __func__, (param_sz - 1), + update_param_val[0]); + rc = -EINVAL; + goto end; + } + /* Turn off modules */ + for (i = 1; i < update_param_val[0]; i++) { + if (!msm_ds2_dap_can_enable_module( + update_param_val[i]) || + (update_param_val[i] == DS2_MODULE_ID)) { + pr_debug("%s: Do not enable/disable %d\n", + __func__, update_param_val[i]); + continue; + } + + pr_debug("%s: param disable %d\n", + __func__, update_param_val[i]); + adm_param_enable(port_id, copp_idx, update_param_val[i], + MODULE_DISABLE); + } + } else { + msm_ds2_dap_send_cal_data(dev_map_idx); + + } + adm_param_enable(port_id, copp_idx, DS2_MODULE_ID, + !ds2_dap_params_states.dap_bypass); +end: + kfree(update_param_val); + return rc; +} + +static bool msm_ds2_dap_check_is_param_modified(int32_t *dap_params_modified, + int32_t idx, int32_t commit) +{ + if ((dap_params_modified[idx] == 0) || + (commit && + ((dap_params_modified[idx] & 0x00010000) && + ((dap_params_modified[idx] & 0x0000FFFF) <= 1)))) { + pr_debug("%s: not modified at idx %d\n", __func__, idx); + return false; + } + pr_debug("%s: modified at idx %d\n", __func__, idx); + return true; +} + +static int msm_ds2_dap_map_device_to_dolby_cache_devices(int32_t device_id) +{ + int32_t cache_dev = -1; + + switch (device_id) { + case DEVICE_NONE: + cache_dev = DOLBY_OFF_CACHE; + break; + case EARPIECE: + case SPEAKER: + cache_dev = DOLBY_SPEAKER_CACHE; + break; + case WIRED_HEADSET: + case WIRED_HEADPHONE: + case ANLG_DOCK_HEADSET: + case DGTL_DOCK_HEADSET: + case ANC_HEADSET: + case ANC_HEADPHONE: + case BLUETOOTH_SCO: + case BLUETOOTH_SCO_HEADSET: + case BLUETOOTH_SCO_CARKIT: + cache_dev = DOLBY_HEADPHONE_CACHE; + break; + case FM: + case FM_TX: + cache_dev = DOLBY_FM_CACHE; + break; + case AUX_DIGITAL: + cache_dev = DOLBY_HDMI_CACHE; + break; + case PROXY: + case REMOTE_SUBMIX: + cache_dev = DOLBY_WFD_CACHE; + break; + default: + pr_err("%s: invalid cache device\n", __func__); + } + pr_debug("%s: cache device %d\n", __func__, cache_dev); + return cache_dev; +} + +static int msm_ds2_dap_update_num_devices(struct dolby_param_data *dolby_data, + int32_t *num_device, int32_t *dev_arr, + int32_t array_size) +{ + int32_t idx = 0; + int supported_devices = 0; + + if (!array_size) { + pr_err("%s: array size zero\n", __func__); + return -EINVAL; + } + + if (dolby_data->device_id == DEVICE_OUT_ALL || + dolby_data->device_id == DEVICE_OUT_DEFAULT) + supported_devices = all_supported_devices; + else + supported_devices = dolby_data->device_id; + + if ((idx < array_size) && (supported_devices & EARPIECE)) + dev_arr[idx++] = EARPIECE; + if ((idx < array_size) && (supported_devices & SPEAKER)) + dev_arr[idx++] = SPEAKER; + if ((idx < array_size) && (supported_devices & WIRED_HEADSET)) + dev_arr[idx++] = WIRED_HEADSET; + if ((idx < array_size) && (supported_devices & WIRED_HEADPHONE)) + dev_arr[idx++] = WIRED_HEADPHONE; + if ((idx < array_size) && (supported_devices & BLUETOOTH_SCO)) + dev_arr[idx++] = BLUETOOTH_SCO; + if ((idx < array_size) && (supported_devices & BLUETOOTH_SCO_CARKIT)) + dev_arr[idx++] = BLUETOOTH_SCO_CARKIT; + if ((idx < array_size) && (supported_devices & BLUETOOTH_SCO_HEADSET)) + dev_arr[idx++] = BLUETOOTH_SCO_HEADSET; + if ((idx < array_size) && (supported_devices & AUX_DIGITAL)) + dev_arr[idx++] = AUX_DIGITAL; + if ((idx < array_size) && (supported_devices & ANLG_DOCK_HEADSET)) + dev_arr[idx++] = ANLG_DOCK_HEADSET; + if ((idx < array_size) && (supported_devices & DGTL_DOCK_HEADSET)) + dev_arr[idx++] = DGTL_DOCK_HEADSET; + if ((idx < array_size) && (supported_devices & REMOTE_SUBMIX)) + dev_arr[idx++] = REMOTE_SUBMIX; + if ((idx < array_size) && (supported_devices & ANC_HEADSET)) + dev_arr[idx++] = ANC_HEADSET; + if ((idx < array_size) && (supported_devices & ANC_HEADPHONE)) + dev_arr[idx++] = ANC_HEADPHONE; + if ((idx < array_size) && (supported_devices & PROXY)) + dev_arr[idx++] = PROXY; + if ((idx < array_size) && (supported_devices & FM)) + dev_arr[idx++] = FM; + if ((idx < array_size) && (supported_devices & FM_TX)) + dev_arr[idx++] = FM_TX; + /* CHECK device none separately */ + if ((idx < array_size) && (supported_devices == DEVICE_NONE)) + dev_arr[idx++] = DEVICE_NONE; + pr_debug("%s: dev id 0x%x, idx %d\n", __func__, + supported_devices, idx); + *num_device = idx; + return 0; +} + +static int msm_ds2_dap_get_port_id( + int32_t device_id, int32_t be_id) +{ + struct msm_pcm_routing_bdai_data bedais; + int port_id = DOLBY_INVALID_PORT_ID; + int port_type = 0; + + if (be_id < 0) { + port_id = -1; + goto end; + } + + msm_pcm_routing_get_bedai_info(be_id, &bedais); + pr_debug("%s: be port_id %d\n", __func__, bedais.port_id); + port_id = bedais.port_id; + port_type = afe_get_port_type(bedais.port_id); + if (port_type != MSM_AFE_PORT_TYPE_RX) + port_id = DOLBY_INVALID_PORT_ID; +end: + pr_debug("%s: device_id 0x%x, be_id %d, port_id %d\n", + __func__, device_id, be_id, port_id); + return port_id; +} + +static int msm_ds2_dap_update_dev_map_port_id(int32_t device_id, int port_id) +{ + int i; + + for (i = 0; i < DS2_DEVICES_ALL; i++) { + if (dev_map[i].device_id == device_id) + dev_map[i].port_id = port_id; + } + pr_debug("%s: port_id %d, device_id 0x%x\n", + __func__, port_id, device_id); + return 0; +} + +static int msm_ds2_dap_handle_bypass_wait(int port_id, int copp_idx, + int wait_time) +{ + int ret = 0; + + adm_set_wait_parameters(port_id, copp_idx); + msm_pcm_routing_release_lock(); + ret = adm_wait_timeout(port_id, copp_idx, wait_time); + msm_pcm_routing_acquire_lock(); + /* Reset the parameters if wait has timed out */ + if (ret == 0) + adm_reset_wait_parameters(port_id, copp_idx); + return ret; +} + +static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) +{ + int rc = 0, i = 0, j = 0; + /*Account for 32 bit integer allocation */ + int32_t param_sz = (ADM_GET_TOPO_MODULE_LIST_LENGTH / sizeof(uint32_t)); + int32_t *mod_list = NULL; + int port_id = 0, copp_idx = -1; + bool cs_onoff = ds2_dap_params_states.custom_stereo_onoff; + int ramp_wait = DOLBY_SOFT_VOLUME_PERIOD; + + pr_debug("%s: bypass type %d bypass %d custom stereo %d\n", __func__, + ds2_dap_params_states.dap_bypass_type, + ds2_dap_params_states.dap_bypass, + ds2_dap_params_states.custom_stereo_onoff); + mod_list = kzalloc(ADM_GET_TOPO_MODULE_LIST_LENGTH, GFP_KERNEL); + if (!mod_list) { + pr_err("%s: param memory alloc failed\n", __func__); + rc = -ENOMEM; + goto end; + } + + for (i = 0; i < DS2_DEVICES_ALL; i++) { + pr_debug("%s: active dev %d\n", __func__, dev_map[i].active); + if (dev_map[i].active) { + port_id = dev_map[i].port_id; + copp_idx = dev_map[i].copp_idx; + + if (port_id == DOLBY_INVALID_PORT_ID) { + pr_err("%s: invalid port\n", __func__); + rc = 0; + goto end; + } + + if ((copp_idx < 0) || + (copp_idx >= MAX_COPPS_PER_PORT)) { + pr_err("%s: Invalid copp_idx\n", __func__); + rc = 0; + goto end; + } + + /* getmodules from dsp */ + rc = adm_get_pp_topo_module_list(port_id, copp_idx, + ADM_GET_TOPO_MODULE_LIST_LENGTH, + (char *)mod_list); + if (rc < 0) { + pr_err("%s:adm get topo list port %d", + __func__, port_id); + pr_err("copp_idx %d, err %d\n", + copp_idx, rc); + goto end; + } + if (mod_list[0] > (param_sz - 1)) { + pr_err("%s:max modules exp/ret [%d: %d]\n", + __func__, (param_sz - 1), + mod_list[0]); + rc = -EINVAL; + goto end; + } + /* + * get ramp parameters + * check for change in ramp parameters + * update ramp wait + */ + msm_ds2_dap_check_and_update_ramp_wait(port_id, + copp_idx, + &ramp_wait); + + /* Mute before switching modules */ + rc = adm_set_volume(port_id, copp_idx, + VOLUME_ZERO_GAIN); + if (rc < 0) { + /* + * Not Fatal can continue bypass operations. + * Do not need to block playback + */ + pr_info("%s :Set volume port_id %d", + __func__, port_id); + pr_info("copp_idx %d, error %d\n", + copp_idx, rc); + } + + rc = msm_ds2_dap_handle_bypass_wait(port_id, copp_idx, + (ramp_wait + + DOLBY_ADDITIONAL_RAMP_WAIT)); + if (rc == -EINTR) { + pr_info("%s:bypass interrupted-ignore,port %d", + __func__, port_id); + pr_info("copp_idx %d\n", copp_idx); + rc = 0; + continue; + } + + /* if dap bypass is set */ + if (ds2_dap_params_states.dap_bypass) { + /* Turn off dap module */ + adm_param_enable(port_id, copp_idx, + DS2_MODULE_ID, MODULE_DISABLE); + /* + * If custom stereo is on at the time of bypass, + * switch off custom stereo on dap and turn on + * custom stereo on qti channel mixer. + */ + if (cs_onoff) { + rc = dap_set_custom_stereo_onoff(i, + !cs_onoff); + if (rc < 0) { + pr_info("%s:D_CS i %d,rc %d\n", + __func__, i, rc); + } + rc = qti_set_custom_stereo_on(port_id, + copp_idx, + cs_onoff); + if (rc < 0) { + pr_info("%s:Q_CS port id 0x%x", + __func__, port_id); + pr_info("copp idx %d, rc %d\n", + copp_idx, rc); + } + } + /* Turn on qti modules */ + for (j = 1; j < mod_list[0]; j++) { + if (!msm_ds2_dap_can_enable_module( + mod_list[j]) || + mod_list[j] == + DS2_MODULE_ID) + continue; + pr_debug("%s: param enable %d\n", + __func__, mod_list[j]); + adm_param_enable(port_id, copp_idx, + mod_list[j], + MODULE_ENABLE); + } + + /* Add adm api to resend calibration on port */ + rc = msm_ds2_dap_send_cal_data(i); + if (rc < 0) { + /* + * Not fatal,continue bypass operations. + * Do not need to block playback + */ + pr_info("%s:send cal err %d index %d\n", + __func__, rc, i); + } + } else { + /* Turn off qti modules */ + for (j = 1; j < mod_list[0]; j++) { + if (!msm_ds2_dap_can_enable_module( + mod_list[j]) || + mod_list[j] == + DS2_MODULE_ID) + continue; + pr_debug("%s: param disable %d\n", + __func__, mod_list[j]); + adm_param_enable(port_id, copp_idx, + mod_list[j], + MODULE_DISABLE); + } + + /* Enable DAP modules */ + pr_debug("%s:DS2 param enable\n", __func__); + adm_param_enable(port_id, copp_idx, + DS2_MODULE_ID, MODULE_ENABLE); + /* + * If custom stereo is on at the time of dap on, + * switch off custom stereo on qti channel mixer + * and turn on custom stereo on DAP. + * mixer(qti). + */ + if (cs_onoff) { + rc = qti_set_custom_stereo_on(port_id, + copp_idx, + !cs_onoff); + if (rc < 0) { + pr_info("%s:Q_CS port_id 0x%x", + __func__, port_id); + pr_info("copp_idx %d rc %d\n", + copp_idx, rc); + } + rc = dap_set_custom_stereo_onoff(i, + cs_onoff); + if (rc < 0) { + pr_info("%s:D_CS i %d,rc %d\n", + __func__, i, rc); + } + } + } + + rc = msm_ds2_dap_handle_bypass_wait(port_id, copp_idx, + DOLBY_MODULE_ENABLE_PERIOD); + if (rc == -EINTR) { + pr_info("%s:bypass interrupted port_id %d copp_idx %d\n", + __func__, port_id, copp_idx); + /* Interrupted ignore bypass */ + rc = 0; + continue; + } + + /* set volume to unity gain after module on/off */ + rc = adm_set_volume(port_id, copp_idx, + VOLUME_UNITY_GAIN); + if (rc < 0) { + /* + * Not Fatal can continue bypass operations. + * Do not need to block playback + */ + pr_info("%s: Set vol port %d copp %d, rc %d\n", + __func__, port_id, copp_idx, rc); + rc = 0; + } + } + } + +end: + kfree(mod_list); + pr_debug("%s:return rc=%d\n", __func__, rc); + return rc; +} + +static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) +{ + int rc = 0; + int32_t *update_params_value = NULL, *params_value = NULL; + uint32_t params_length = (DOLBY_PARAM_INT_ENDP_LENGTH + + DOLBY_PARAM_PAYLOAD_SIZE) * sizeof(uint32_t); + int cache_device = 0; + struct ds2_dap_params_s *ds2_ap_params_obj = NULL; + int32_t *modified_param = NULL; + + if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { + pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); + rc = -EINVAL; + goto end; + } + cache_device = dev_map[dev_map_idx].cache_dev; + + ds2_ap_params_obj = &ds2_dap_params[cache_device]; + pr_debug("%s: cache dev %d, dev_map_idx %d\n", __func__, + cache_device, dev_map_idx); + pr_debug("%s: endp - %pK %pK\n", __func__, + &ds2_dap_params[cache_device], ds2_ap_params_obj); + + params_value = kzalloc(params_length, GFP_KERNEL); + if (!params_value) { + rc = -ENOMEM; + goto end; + } + + if (dev_map[dev_map_idx].port_id == DOLBY_INVALID_PORT_ID) { + pr_err("%s: invalid port\n", __func__); + rc = -EINVAL; + goto end; + } + + if ((dev_map[dev_map_idx].copp_idx < 0) || + (dev_map[dev_map_idx].copp_idx >= MAX_COPPS_PER_PORT)) { + pr_err("%s: Invalid copp_idx\n", __func__); + rc = -EINVAL; + goto end; + } + + update_params_value = params_value; + *update_params_value++ = DOLBY_BUNDLE_MODULE_ID; + *update_params_value++ = DOLBY_PARAM_ID_INIT_ENDP; + *update_params_value++ = DOLBY_PARAM_INT_ENDP_LENGTH * sizeof(uint32_t); + *update_params_value++ = ds2_ap_params_obj->params_val[ + ds2_dap_params_offset[endp_idx]]; + pr_debug("%s: off %d, length %d\n", __func__, + ds2_dap_params_offset[endp_idx], + ds2_dap_params_length[endp_idx]); + pr_debug("%s: param 0x%x, param val %d\n", __func__, + ds2_dap_params_id[endp_idx], ds2_ap_params_obj-> + params_val[ds2_dap_params_offset[endp_idx]]); + rc = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, + (char *)params_value, params_length); + if (rc) { + pr_err("%s: send dolby params failed rc %d\n", __func__, rc); + rc = -EINVAL; + } + modified_param = ds2_ap_params_obj->dap_params_modified; + if (modified_param == NULL) { + pr_err("%s: modified param structure invalid\n", + __func__); + rc = -EINVAL; + goto end; + } + + if (msm_ds2_dap_check_is_param_modified(modified_param, endp_idx, 0)) + ds2_ap_params_obj->dap_params_modified[endp_idx] = 0x00010001; + +end: + kfree(params_value); + return rc; +} + +static int msm_ds2_dap_send_cached_params(int dev_map_idx, + int commit) +{ + int32_t *update_params_value = NULL, *params_value = NULL; + uint32_t idx, i, j, ret = 0; + uint32_t params_length = (TOTAL_LENGTH_DOLBY_PARAM + + (MAX_DS2_PARAMS - 1) * + DOLBY_PARAM_PAYLOAD_SIZE) * + sizeof(uint32_t); + int cache_device = 0; + struct ds2_dap_params_s *ds2_ap_params_obj = NULL; + int32_t *modified_param = NULL; + + if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { + pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); + ret = -EINVAL; + goto end; + } + cache_device = dev_map[dev_map_idx].cache_dev; + + /* Use off profile cache in only for soft bypass */ + if (ds2_dap_params_states.dap_bypass_type == DAP_SOFT_BYPASS && + ds2_dap_params_states.dap_bypass == true) { + pr_debug("%s: use bypass cache 0\n", __func__); + cache_device = dev_map[0].cache_dev; + } + + ds2_ap_params_obj = &ds2_dap_params[cache_device]; + pr_debug("%s: cached param - %pK %pK, cache_device %d\n", __func__, + &ds2_dap_params[cache_device], ds2_ap_params_obj, + cache_device); + params_value = kzalloc(params_length, GFP_KERNEL); + if (!params_value) { + pr_err("%s: params memory alloc failed\n", __func__); + ret = -ENOMEM; + goto end; + } + + if (dev_map[dev_map_idx].port_id == DOLBY_INVALID_PORT_ID) { + pr_err("%s: invalid port id\n", __func__); + ret = -EINVAL; + goto end; + } + + if ((dev_map[dev_map_idx].copp_idx < 0) || + (dev_map[dev_map_idx].copp_idx >= MAX_COPPS_PER_PORT)) { + pr_err("%s: Invalid copp_idx\n", __func__); + ret = -EINVAL; + goto end; + } + + update_params_value = params_value; + params_length = 0; + for (i = 0; i < (MAX_DS2_PARAMS-1); i++) { + /*get the pointer to the param modified array in the cache*/ + modified_param = ds2_ap_params_obj->dap_params_modified; + if (modified_param == NULL) { + pr_err("%s: modified param structure invalid\n", + __func__); + ret = -EINVAL; + goto end; + } + if (!msm_ds2_dap_check_is_param_modified(modified_param, i, + commit)) + continue; + *update_params_value++ = DOLBY_BUNDLE_MODULE_ID; + *update_params_value++ = ds2_dap_params_id[i]; + *update_params_value++ = ds2_dap_params_length[i] * + sizeof(uint32_t); + idx = ds2_dap_params_offset[i]; + for (j = 0; j < ds2_dap_params_length[i]; j++) { + *update_params_value++ = + ds2_ap_params_obj->params_val[idx+j]; + pr_debug("%s: id 0x%x,val %d\n", __func__, + ds2_dap_params_id[i], + ds2_ap_params_obj->params_val[idx+j]); + } + params_length += (DOLBY_PARAM_PAYLOAD_SIZE + + ds2_dap_params_length[i]) * sizeof(uint32_t); + } + + pr_debug("%s: valid param length: %d\n", __func__, params_length); + if (params_length) { + ret = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, + (char *)params_value, + params_length); + if (ret) { + pr_err("%s: send dolby params failed ret %d\n", + __func__, ret); + ret = -EINVAL; + goto end; + } + for (i = 0; i < MAX_DS2_PARAMS-1; i++) { + /*get pointer to the param modified array in the cache*/ + modified_param = ds2_ap_params_obj->dap_params_modified; + if (modified_param == NULL) { + pr_err("%s: modified param struct invalid\n", + __func__); + ret = -EINVAL; + goto end; + } + if (!msm_ds2_dap_check_is_param_modified( + modified_param, i, commit)) + continue; + ds2_ap_params_obj->dap_params_modified[i] = 0x00010001; + } + } +end: + kfree(params_value); + return ret; +} + +static int msm_ds2_dap_commit_params(struct dolby_param_data *dolby_data, + int commit) +{ + int ret = 0, i, idx; + struct ds2_dap_params_s *ds2_ap_params_obj = NULL; + int32_t *modified_param = NULL; + + /* Do not commit params if in hard bypass */ + if (ds2_dap_params_states.dap_bypass_type == DAP_HARD_BYPASS && + ds2_dap_params_states.dap_bypass == true) { + pr_debug("%s: called in bypass", __func__); + ret = -EINVAL; + goto end; + } + for (idx = 0; idx < MAX_DS2_PARAMS; idx++) { + if (ds2_dap_params_id[idx] == DOLBY_PARAM_ID_INIT_ENDP) + break; + } + if (idx >= MAX_DS2_PARAMS || idx < 0) { + pr_err("%s: index of DS2 Param not found idx %d\n", + __func__, idx); + ret = -EINVAL; + goto end; + } + pr_debug("%s: found endp - idx %d 0x%x\n", __func__, idx, + ds2_dap_params_id[idx]); + for (i = 0; i < DS2_DEVICES_ALL; i++) { + pr_debug("%s:dev[0x%x,0x%x],i:%d,active:%d,bypass:%d,type:%d\n", + __func__, dolby_data->device_id, dev_map[i].device_id, + i, dev_map[i].active, ds2_dap_params_states.dap_bypass, + ds2_dap_params_states.dap_bypass_type); + + if (((dev_map[i].device_id & ds2_dap_params_states.device) || + ((ds2_dap_params_states.dap_bypass_type == + DAP_SOFT_BYPASS) && + (ds2_dap_params_states.dap_bypass == true))) && + (dev_map[i].active == true)) { + + /*get ptr to the cache storing the params for device*/ + if ((ds2_dap_params_states.dap_bypass_type == + DAP_SOFT_BYPASS) && + (ds2_dap_params_states.dap_bypass == true)) + ds2_ap_params_obj = + &ds2_dap_params[dev_map[0].cache_dev]; + else + ds2_ap_params_obj = + &ds2_dap_params[dev_map[i].cache_dev]; + + /*get the pointer to the param modified array in cache*/ + modified_param = ds2_ap_params_obj->dap_params_modified; + if (modified_param == NULL) { + pr_err("%s: modified_param NULL\n", __func__); + ret = -EINVAL; + goto end; + } + + /* + * Send the endp param if use cache is set + * or if param is modified + */ + if (!commit || msm_ds2_dap_check_is_param_modified( + modified_param, idx, commit)) { + msm_ds2_dap_send_end_point(i, idx); + commit = 0; + } + ret = msm_ds2_dap_send_cached_params(i, commit); + if (ret < 0) { + pr_err("%s: send cached param %d\n", + __func__, ret); + goto end; + } + } + } +end: + return ret; +} + +static int msm_ds2_dap_handle_commands(u32 cmd, void *arg) +{ + int ret = 0, port_id = 0; + int32_t data; + struct dolby_param_data *dolby_data = (struct dolby_param_data *)arg; + + if (get_user(data, &dolby_data->data[0])) { + pr_debug("%s error getting data\n", __func__); + ret = -EFAULT; + goto end; + } + + pr_debug("%s: param_id %d,be_id %d,device_id 0x%x,length %d,data %d\n", + __func__, dolby_data->param_id, dolby_data->be_id, + dolby_data->device_id, dolby_data->length, data); + + switch (dolby_data->param_id) { + case DAP_CMD_COMMIT_ALL: + msm_ds2_dap_commit_params(dolby_data, 0); + break; + + case DAP_CMD_COMMIT_CHANGED: + msm_ds2_dap_commit_params(dolby_data, 1); + break; + + case DAP_CMD_USE_CACHE_FOR_INIT: + ds2_dap_params_states.use_cache = data; + break; + + case DAP_CMD_SET_BYPASS: + pr_debug("%s: bypass %d bypass type %d, data %d\n", __func__, + ds2_dap_params_states.dap_bypass, + ds2_dap_params_states.dap_bypass_type, + data); + /* Do not perform bypass operation if bypass state is same*/ + if (ds2_dap_params_states.dap_bypass == data) + break; + ds2_dap_params_states.dap_bypass = data; + /* hard bypass */ + if (ds2_dap_params_states.dap_bypass_type == DAP_HARD_BYPASS) + msm_ds2_dap_handle_bypass(dolby_data); + /* soft bypass */ + msm_ds2_dap_commit_params(dolby_data, 0); + break; + + case DAP_CMD_SET_BYPASS_TYPE: + if (data == true) + ds2_dap_params_states.dap_bypass_type = + DAP_HARD_BYPASS; + else + ds2_dap_params_states.dap_bypass_type = + DAP_SOFT_BYPASS; + pr_debug("%s: bypass type %d", __func__, + ds2_dap_params_states.dap_bypass_type); + break; + + case DAP_CMD_SET_ACTIVE_DEVICE: + pr_debug("%s: DAP_CMD_SET_ACTIVE_DEVICE length %d\n", + __func__, dolby_data->length); + /* TODO: need to handle multiple instance*/ + ds2_dap_params_states.device |= dolby_data->device_id; + port_id = msm_ds2_dap_get_port_id( + dolby_data->device_id, + dolby_data->be_id); + pr_debug("%s: device id 0x%x all_dev 0x%x port_id %d\n", + __func__, dolby_data->device_id, + ds2_dap_params_states.device, port_id); + msm_ds2_dap_update_dev_map_port_id(dolby_data->device_id, + port_id); + if (port_id == DOLBY_INVALID_PORT_ID) { + pr_err("%s: invalid port id %d\n", __func__, port_id); + ret = -EINVAL; + goto end; + } + break; + } +end: + return ret; + +} + +static int msm_ds2_dap_set_param(u32 cmd, void *arg) +{ + int rc = 0, idx, i, j, off, port_id = 0, cdev = 0; + int32_t num_device = 0; + int32_t data = 0; + int32_t dev_arr[DS2_DSP_SUPPORTED_ENDP_DEVICE] = {0}; + struct dolby_param_data *dolby_data = (struct dolby_param_data *)arg; + + rc = msm_ds2_dap_update_num_devices(dolby_data, &num_device, dev_arr, + DS2_DSP_SUPPORTED_ENDP_DEVICE); + if (num_device == 0 || rc < 0) { + pr_err("%s: num devices 0\n", __func__); + rc = -EINVAL; + goto end; + } + for (i = 0; i < num_device; i++) { + port_id = msm_ds2_dap_get_port_id(dev_arr[i], + dolby_data->be_id); + if (port_id != DOLBY_INVALID_PORT_ID) + msm_ds2_dap_update_dev_map_port_id(dev_arr[i], port_id); + + cdev = msm_ds2_dap_map_device_to_dolby_cache_devices( + dev_arr[i]); + if (cdev < 0 || cdev >= DOLBY_MAX_CACHE) { + pr_err("%s: Invalid cache device %d for device 0x%x\n", + __func__, cdev, dev_arr[i]); + rc = -EINVAL; + goto end; + } + pr_debug("%s:port:%d,be:%d,dev:0x%x,cdev:%d,param:0x%x,len:%d\n" + , __func__, port_id, dolby_data->be_id, dev_arr[i], + cdev, dolby_data->param_id, dolby_data->length); + for (idx = 0; idx < MAX_DS2_PARAMS; idx++) { + /*paramid from user space*/ + if (dolby_data->param_id == ds2_dap_params_id[idx]) + break; + } + if (idx > MAX_DS2_PARAMS-1) { + pr_err("%s: invalid param id 0x%x at idx %d\n", + __func__, dolby_data->param_id, idx); + rc = -EINVAL; + goto end; + } + + off = ds2_dap_params_offset[idx]; + if ((dolby_data->length <= 0) || + (dolby_data->length > TOTAL_LENGTH_DS2_PARAM - off)) { + pr_err("%s: invalid length %d at idx %d\n", + __func__, dolby_data->length, idx); + rc = -EINVAL; + goto end; + } + + /* cache the parameters */ + ds2_dap_params[cdev].dap_params_modified[idx] += 1; + for (j = 0; j < dolby_data->length; j++) { + if (get_user(data, &dolby_data->data[j])) { + pr_debug("%s:error getting data\n", __func__); + rc = -EFAULT; + goto end; + } + ds2_dap_params[cdev].params_val[off + j] = data; + pr_debug("%s:off %d,val[i/p:o/p]-[%d / %d]\n", + __func__, off, data, + ds2_dap_params[cdev]. + params_val[off + j]); + } + } +end: + return rc; +} + +static int msm_ds2_dap_get_param(u32 cmd, void *arg) +{ + int rc = 0, i, port_id = 0, copp_idx = -1; + struct dolby_param_data *dolby_data = (struct dolby_param_data *)arg; + int32_t *update_params_value = NULL, *params_value = NULL; + uint32_t params_length = DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM * + sizeof(uint32_t); + uint32_t param_payload_len = + DOLBY_PARAM_PAYLOAD_SIZE * sizeof(uint32_t); + + /* Return error on get param in soft or hard bypass */ + if (ds2_dap_params_states.dap_bypass == true) { + pr_err("%s: called in bypass_type %d bypass %d\n", __func__, + ds2_dap_params_states.dap_bypass_type, + ds2_dap_params_states.dap_bypass); + rc = -EINVAL; + goto end; + } + + /* Return if invalid length */ + if ((dolby_data->length > + (DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM - DOLBY_PARAM_PAYLOAD_SIZE)) || + (dolby_data->length <= 0)) { + pr_err("Invalid length %d", dolby_data->length); + rc = -EINVAL; + goto end; + } + + for (i = 0; i < DS2_DEVICES_ALL; i++) { + if ((dev_map[i].active) && + (dev_map[i].device_id & dolby_data->device_id)) { + port_id = dev_map[i].port_id; + copp_idx = dev_map[i].copp_idx; + break; + } + } + + if (port_id == DOLBY_INVALID_PORT_ID) { + pr_err("%s: Invalid port\n", __func__); + rc = -EINVAL; + goto end; + } + + if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { + pr_err("%s: Invalid copp_idx\n", __func__); + rc = -EINVAL; + goto end; + } + + pr_debug("%s: port_id 0x%x, copp_idx %d, dev_map[i].device_id %x\n", + __func__, port_id, copp_idx, dev_map[i].device_id); + + params_value = kzalloc(params_length + param_payload_len, + GFP_KERNEL); + if (!params_value) { + rc = -ENOMEM; + goto end; + } + + if (dolby_data->param_id == DOLBY_PARAM_ID_VER) { + rc = adm_get_params(port_id, copp_idx, + DOLBY_BUNDLE_MODULE_ID, + DOLBY_PARAM_ID_VER, + params_length + param_payload_len, + (char *)params_value); + } else { + for (i = 0; i < MAX_DS2_PARAMS; i++) + if (ds2_dap_params_id[i] == + dolby_data->param_id) + break; + if (i > MAX_DS2_PARAMS-1) { + pr_err("%s: invalid param id 0x%x at id %d\n", __func__, + dolby_data->param_id, i); + rc = -EINVAL; + goto end; + } else { + params_length = + ds2_dap_params_length[i] * sizeof(uint32_t); + + rc = adm_get_params(port_id, copp_idx, + DOLBY_BUNDLE_MODULE_ID, + ds2_dap_params_id[i], + params_length + + param_payload_len, + (char *)params_value); + } + } + if (rc) { + pr_err("%s: get parameters failed rc %d\n", __func__, rc); + rc = -EINVAL; + goto end; + } + update_params_value = params_value; + if (copy_to_user((void *)dolby_data->data, + &update_params_value[DOLBY_PARAM_PAYLOAD_SIZE], + (dolby_data->length * sizeof(uint32_t)))) { + pr_err("%s: error getting param\n", __func__); + rc = -EFAULT; + goto end; + } +end: + kfree(params_value); + return rc; +} + +static int msm_ds2_dap_param_visualizer_control_get(u32 cmd, void *arg) +{ + int32_t *visualizer_data = NULL; + int i = 0, ret = 0, port_id = -1, cache_dev = -1, copp_idx = -1; + int32_t *update_visualizer_data = NULL; + struct dolby_param_data *dolby_data = (struct dolby_param_data *)arg; + uint32_t offset, length, params_length; + uint32_t param_payload_len = + DOLBY_PARAM_PAYLOAD_SIZE * sizeof(uint32_t); + + for (i = 0; i < DS2_DEVICES_ALL; i++) { + if ((dev_map[i].active)) { + port_id = dev_map[i].port_id; + cache_dev = dev_map[i].cache_dev; + copp_idx = dev_map[i].copp_idx; + break; + } + } + + if (port_id == DOLBY_INVALID_PORT_ID || + (copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { + ret = 0; + dolby_data->length = 0; + pr_err("%s: no device active\n", __func__); + goto end; + } + + length = ds2_dap_params[cache_dev].params_val[DOLBY_PARAM_VCNB_OFFSET]; + + if (length > DOLBY_PARAM_VCNB_MAX_LENGTH || length <= 0) { + ret = 0; + dolby_data->length = 0; + pr_err("%s Incorrect VCNB length", __func__); + return -EINVAL; + } + + params_length = (2*length + DOLBY_VIS_PARAM_HEADER_SIZE) * + sizeof(uint32_t); + + visualizer_data = kzalloc(params_length, GFP_KERNEL); + if (!visualizer_data) { + ret = -ENOMEM; + dolby_data->length = 0; + goto end; + } + memset(visualizer_data, 0x0, params_length); + + /* Return error on get param in soft or hard bypass */ + if (ds2_dap_params_states.dap_bypass == true) { + pr_debug("%s: visualizer called in bypass, return 0\n", + __func__); + ret = 0; + dolby_data->length = 0; + goto end; + } + + offset = 0; + params_length = length * sizeof(uint32_t); + ret = adm_get_params(port_id, copp_idx, + DOLBY_BUNDLE_MODULE_ID, + DOLBY_PARAM_ID_VCBG, + params_length + param_payload_len, + (((char *)(visualizer_data)) + offset)); + if (ret) { + pr_err("%s: get parameters failed ret %d\n", __func__, ret); + ret = -EINVAL; + dolby_data->length = 0; + goto end; + } + offset = length * sizeof(uint32_t); + ret = adm_get_params(port_id, copp_idx, + DOLBY_BUNDLE_MODULE_ID, + DOLBY_PARAM_ID_VCBE, + params_length + param_payload_len, + (((char *)(visualizer_data)) + offset)); + if (ret) { + pr_err("%s: get parameters failed ret %d\n", __func__, ret); + ret = -EINVAL; + dolby_data->length = 0; + goto end; + } + update_visualizer_data = visualizer_data; + dolby_data->length = 2 * length; + + if (copy_to_user((void *)dolby_data->data, + (void *)update_visualizer_data, + (dolby_data->length * sizeof(uint32_t)))) { + pr_err("%s: copy to user failed for data\n", __func__); + dolby_data->length = 0; + ret = -EFAULT; + goto end; + } + +end: + kfree(visualizer_data); + return ret; +} + +int msm_ds2_dap_set_security_control(u32 cmd, void *arg) +{ + struct dolby_param_license *dolby_license = + ((struct dolby_param_license *)arg); + pr_debug("%s: dmid %d license key %d\n", __func__, + dolby_license->dmid, dolby_license->license_key); + core_set_dolby_manufacturer_id(dolby_license->dmid); + core_set_license(dolby_license->license_key, DOLBY_DS1_LICENSE_ID); + return 0; +} + +int msm_ds2_dap_update_port_parameters(struct snd_hwdep *hw, struct file *file, + bool open) +{ + int i = 0, dev_id = 0; + + pr_debug("%s: open %d\n", __func__, open); + ds2_dap_params_states.node_opened = open; + ds2_dap_params_states.dap_bypass = true; + ds2_dap_params_states.dap_bypass_type = 0; + ds2_dap_params_states.use_cache = 0; + ds2_dap_params_states.device = 0; + ds2_dap_params_states.custom_stereo_onoff = 0; + for (i = 0; i < DS2_DEVICES_ALL; i++) { + if (i == 0) + dev_map[i].device_id = 0; + else { + dev_id = (1 << (i-1)); + if (all_supported_devices & dev_id) + dev_map[i].device_id = dev_id; + else + continue; + } + dev_map[i].cache_dev = + msm_ds2_dap_map_device_to_dolby_cache_devices( + dev_map[i].device_id); + if (dev_map[i].cache_dev < 0 || + dev_map[i].cache_dev >= DOLBY_MAX_CACHE) + pr_err("%s: Invalid cache device %d for device 0x%x\n", + __func__, + dev_map[i].cache_dev, + dev_map[i].device_id); + dev_map[i].port_id = -1; + dev_map[i].active = false; + dev_map[i].stream_ref_count = 0; + dev_map[i].cal_data = NULL; + dev_map[i].copp_idx = -1; + pr_debug("%s: device_id 0x%x, cache_dev %d act %d\n", __func__, + dev_map[i].device_id, dev_map[i].cache_dev, + dev_map[i].active); + } + return 0; + +} + +int msm_ds2_dap_ioctl_shared(struct snd_hwdep *hw, struct file *file, + u32 cmd, void *arg) +{ + int ret = 0; + + pr_debug("%s: cmd: 0x%x\n", __func__, cmd); + switch (cmd) { + case SNDRV_DEVDEP_DAP_IOCTL_SET_PARAM: + ret = msm_ds2_dap_set_param(cmd, arg); + break; + case SNDRV_DEVDEP_DAP_IOCTL_GET_PARAM: + ret = msm_ds2_dap_get_param(cmd, arg); + break; + case SNDRV_DEVDEP_DAP_IOCTL_DAP_COMMAND: + ret = msm_ds2_dap_handle_commands(cmd, arg); + break; + case SNDRV_DEVDEP_DAP_IOCTL_DAP_LICENSE: + ret = msm_ds2_dap_set_security_control(cmd, arg); + break; + case SNDRV_DEVDEP_DAP_IOCTL_GET_VISUALIZER: + ret = msm_ds2_dap_param_visualizer_control_get(cmd, arg); + break; + default: + pr_err("%s: called with invalid control 0x%x\n", __func__, cmd); + ret = -EINVAL; + } + return ret; +} + +int msm_ds2_dap_ioctl(struct snd_hwdep *hw, struct file *file, + u32 cmd, void *arg) +{ + + int ret = 0; + + pr_debug("%s: cmd: 0x%x\n", __func__, cmd); + if (!arg) { + pr_err("%s: Invalid params event status\n", __func__); + ret = -EINVAL; + goto end; + } + switch (cmd) { + case SNDRV_DEVDEP_DAP_IOCTL_SET_PARAM: + case SNDRV_DEVDEP_DAP_IOCTL_DAP_COMMAND: { + struct dolby_param_data dolby_data; + + if (copy_from_user((void *)&dolby_data, (void *)arg, + sizeof(struct dolby_param_data))) { + pr_err("%s: Copy from user failed\n", __func__); + ret = -EFAULT; + goto end; + } + ret = msm_ds2_dap_ioctl_shared(hw, file, cmd, &dolby_data); + break; + } + case SNDRV_DEVDEP_DAP_IOCTL_DAP_LICENSE: { + struct dolby_param_license dolby_license; + + if (copy_from_user((void *)&dolby_license, (void *)arg, + sizeof(struct dolby_param_license))) { + pr_err("%s: Copy from user failed\n", __func__); + ret = -EFAULT; + goto end; + } + ret = msm_ds2_dap_ioctl_shared(hw, file, cmd, &dolby_license); + break; + } + case SNDRV_DEVDEP_DAP_IOCTL_GET_PARAM: + case SNDRV_DEVDEP_DAP_IOCTL_GET_VISUALIZER: { + struct dolby_param_data dolby_data; + + if (copy_from_user((void *)&dolby_data, (void *)arg, + sizeof(struct dolby_param_data))) { + pr_err("%s: Copy from user failed\n", __func__); + ret = -EFAULT; + goto end; + } + ret = msm_ds2_dap_ioctl_shared(hw, file, cmd, &dolby_data); + if (ret < 0) + pr_err("%s: ioctl cmd %d returned err %d\n", + __func__, cmd, ret); + if (copy_to_user((void *)arg, &dolby_data, + sizeof(struct dolby_param_data))) { + pr_err("%s: Copy to user failed\n", __func__); + ret = -EFAULT; + goto end; + } + break; + } + default: + pr_err("%s: called with invalid control 0x%x\n", __func__, cmd); + ret = -EINVAL; + } +end: + return ret; + +} +#ifdef CONFIG_COMPAT +int msm_ds2_dap_compat_ioctl(struct snd_hwdep *hw, struct file *file, + u32 cmd, void *arg) +{ + int ret = 0; + + pr_debug("%s: cmd: 0x%x\n", __func__, cmd); + switch (cmd) { + case SNDRV_DEVDEP_DAP_IOCTL_SET_PARAM32: + cmd = SNDRV_DEVDEP_DAP_IOCTL_SET_PARAM; + goto handle_set_ioctl; + case SNDRV_DEVDEP_DAP_IOCTL_DAP_COMMAND32: + cmd = SNDRV_DEVDEP_DAP_IOCTL_DAP_COMMAND; +handle_set_ioctl: + { + struct dolby_param_data32 dolby_data32; + struct dolby_param_data dolby_data; + + memset(&dolby_data32, 0, sizeof(dolby_data32)); + memset(&dolby_data, 0, sizeof(dolby_data)); + if (copy_from_user(&dolby_data32, (void *)arg, + sizeof(struct dolby_param_data32))) { + pr_err("%s: Copy from user failed\n", __func__); + ret = -EFAULT; + goto end; + } + dolby_data.version = dolby_data32.version; + dolby_data.device_id = dolby_data32.device_id; + dolby_data.be_id = dolby_data32.be_id; + dolby_data.param_id = dolby_data32.param_id; + dolby_data.length = dolby_data32.length; + dolby_data.data = compat_ptr(dolby_data32.data); + + ret = msm_ds2_dap_ioctl_shared(hw, file, cmd, &dolby_data); + break; + } + case SNDRV_DEVDEP_DAP_IOCTL_GET_PARAM32: + cmd = SNDRV_DEVDEP_DAP_IOCTL_GET_PARAM; + goto handle_get_ioctl; + case SNDRV_DEVDEP_DAP_IOCTL_GET_VISUALIZER32: + cmd = SNDRV_DEVDEP_DAP_IOCTL_GET_VISUALIZER; +handle_get_ioctl: + { + struct dolby_param_data32 dolby_data32; + struct dolby_param_data dolby_data; + + memset(&dolby_data32, 0, sizeof(dolby_data32)); + memset(&dolby_data, 0, sizeof(dolby_data)); + if (copy_from_user(&dolby_data32, (void *)arg, + sizeof(struct dolby_param_data32))) { + pr_err("%s: Copy from user failed\n", __func__); + ret = -EFAULT; + goto end; + } + dolby_data.version = dolby_data32.version; + dolby_data.device_id = dolby_data32.device_id; + dolby_data.be_id = dolby_data32.be_id; + dolby_data.param_id = dolby_data32.param_id; + dolby_data.length = dolby_data32.length; + dolby_data.data = compat_ptr(dolby_data32.data); + + ret = msm_ds2_dap_ioctl_shared(hw, file, cmd, &dolby_data); + if (ret < 0) + pr_err("%s: ioctl cmd %d, returned err %d\n", + __func__, cmd, ret); + dolby_data32.length = dolby_data.length; + if (copy_to_user((void *)arg, &dolby_data32, + sizeof(struct dolby_param_data32))) { + pr_err("%s: Copy to user failed\n", __func__); + ret = -EFAULT; + goto end; + } + break; + } + case SNDRV_DEVDEP_DAP_IOCTL_DAP_LICENSE32: { + struct dolby_param_license32 dolby_license32; + struct dolby_param_license dolby_license; + + cmd = SNDRV_DEVDEP_DAP_IOCTL_DAP_LICENSE; + if (copy_from_user((void *)&dolby_license32, (void *)arg, + sizeof(struct dolby_param_license32))) { + pr_err("%s: Copy from user failed\n", __func__); + ret = -EFAULT; + goto end; + } + dolby_license.dmid = dolby_license32.dmid; + dolby_license.license_key = dolby_license32.license_key; + ret = msm_ds2_dap_ioctl_shared(hw, file, cmd, &dolby_license); + break; + } + default: + pr_err("%s: called with invalid control 0x%x\n", + __func__, cmd); + ret = -EINVAL; + } +end: + return ret; + +} +#endif + +int msm_ds2_dap_init(int port_id, int copp_idx, int channels, + bool is_custom_stereo_on) +{ + int ret = 0, idx = -1, i; + struct dolby_param_data dolby_data; + + struct audproc_softvolume_params softvol = { + .period = DOLBY_SOFT_VOLUME_PERIOD, + .step = DOLBY_SOFT_VOLUME_STEP, + .rampingcurve = DOLBY_SOFT_VOLUME_CURVE_EXP, + }; + + pr_debug("%s: port id %d, copp_idx %d\n", __func__, port_id, copp_idx); + + if (port_id != DOLBY_INVALID_PORT_ID) { + for (i = 0; i < DS2_DEVICES_ALL; i++) { + if ((dev_map[i].port_id == port_id) && + /* device part of active device */ + (dev_map[i].device_id & + ds2_dap_params_states.device)) { + idx = i; + /* Give priority to headset in case of + * combo device + */ + if (dev_map[i].device_id == SPEAKER) + continue; + else + break; + } + } + if (idx < 0) { + pr_err("%s: invalid index for port %d\n", + __func__, port_id); + ret = -EINVAL; + goto end; + } + pr_debug("%s:index %d, dev[0x%x,0x%x]\n", __func__, idx, + dev_map[idx].device_id, ds2_dap_params_states.device); + dev_map[idx].active = true; + dev_map[idx].copp_idx = copp_idx; + dolby_data.param_id = DOLBY_COMMIT_ALL_TO_DSP; + dolby_data.length = 0; + dolby_data.data = NULL; + dolby_data.device_id = dev_map[idx].device_id; + pr_debug("%s: idx %d, active %d, dev id 0x%x, ref count %d\n", + __func__, idx, dev_map[idx].active, + dev_map[idx].device_id, + dev_map[idx].stream_ref_count); + if (dev_map[idx].stream_ref_count == 0) { + /*perform next 3 func only if hard bypass enabled*/ + if (ds2_dap_params_states.dap_bypass_type == + DAP_HARD_BYPASS) { + ret = msm_ds2_dap_alloc_and_store_cal_data(idx, + ADM_PATH_PLAYBACK, 0); + if (ret < 0) { + pr_err("%s: Failed to alloc and store cal data for idx %d, device %d, copp_idx %d", + __func__, + idx, dev_map[idx].device_id, + dev_map[idx].copp_idx); + dev_map[idx].active = false; + dev_map[idx].copp_idx = -1; + goto end; + } + + ret = adm_set_softvolume(port_id, copp_idx, + &softvol); + if (ret < 0) { + pr_err("%s: Soft volume ret error %d\n", + __func__, ret); + dev_map[idx].active = false; + dev_map[idx].copp_idx = -1; + goto end; + } + + ret = msm_ds2_dap_init_modules_in_topology( + idx); + if (ret < 0) { + pr_err("%s: Failed to init modules in topolofy for idx %d, device %d, copp_idx %d\n", + __func__, idx, + dev_map[idx].device_id, + dev_map[idx].copp_idx); + dev_map[idx].active = false; + dev_map[idx].copp_idx = -1; + goto end; + } + } + + ret = msm_ds2_dap_commit_params(&dolby_data, 0); + if (ret < 0) { + pr_debug("%s: commit params ret %d\n", + __func__, ret); + ret = 0; + } + } + dev_map[idx].stream_ref_count++; + if (is_custom_stereo_on) { + ds2_dap_params_states.custom_stereo_onoff = + is_custom_stereo_on; + set_custom_stereo_onoff(idx, + is_custom_stereo_on); + } + } + +end: + return ret; +} + +void msm_ds2_dap_deinit(int port_id) +{ + /* + * Get the active port corrresponding to the active device + * Check if this is same as incoming port + * Set it to invalid + */ + int idx = -1, i; + + pr_debug("%s: port_id %d\n", __func__, port_id); + if (port_id != DOLBY_INVALID_PORT_ID) { + for (i = 0; i < DS2_DEVICES_ALL; i++) { + /* Active port */ + if ((dev_map[i].port_id == port_id) && + /* device part of active device */ + (dev_map[i].device_id & + ds2_dap_params_states.device) && + /* + * Need this check to avoid race condition of + * active device being set and playback + * instance opened + */ + /* active device*/ + dev_map[i].active) { + idx = i; + if (dev_map[i].device_id == SPEAKER) + continue; + else + break; + } + } + if (idx < 0) { + pr_err("%s: invalid index for port %d\n", + __func__, port_id); + return; + } + pr_debug("%s:index %d, dev [0x%x, 0x%x]\n", __func__, idx, + dev_map[idx].device_id, ds2_dap_params_states.device); + dev_map[idx].stream_ref_count--; + if (dev_map[idx].stream_ref_count == 0) { + /*perform next func only if hard bypass enabled*/ + if (ds2_dap_params_states.dap_bypass_type == + DAP_HARD_BYPASS) { + msm_ds2_dap_free_cal_data(idx); + } + ds2_dap_params_states.device &= ~dev_map[idx].device_id; + dev_map[idx].active = false; + dev_map[idx].copp_idx = -1; + } + pr_debug("%s:idx %d, active %d, dev id 0x%x ref count %d\n", + __func__, idx, dev_map[idx].active, + dev_map[idx].device_id, dev_map[idx].stream_ref_count); + } +} + +int msm_ds2_dap_set_custom_stereo_onoff(int port_id, int copp_idx, + bool is_custom_stereo_enabled) +{ + int idx = -1, rc = 0, i; + + pr_debug("%s: port_id %d\n", __func__, port_id); + if (port_id != DOLBY_INVALID_PORT_ID) { + for (i = 0; i < DS2_DEVICES_ALL; i++) { + if ((dev_map[i].port_id == port_id) && + /* device part of active device */ + (dev_map[i].device_id & + ds2_dap_params_states.device)) { + idx = i; + if (dev_map[i].device_id == SPEAKER) + continue; + else + break; + } + } + if (idx < 0) { + pr_err("%s: invalid index for port %d\n", + __func__, port_id); + return rc; + } + ds2_dap_params_states.custom_stereo_onoff = + is_custom_stereo_enabled; + rc = set_custom_stereo_onoff(idx, + is_custom_stereo_enabled); + if (rc < 0) { + pr_err("%s: Custom stereo err %d on port %d\n", + __func__, rc, port_id); + } + } + return rc; +} + +#else + +static int msm_ds2_dap_alloc_and_store_cal_data(int dev_map_idx, int path, + int perf_mode) +{ + return 0; +} + +static int msm_ds2_dap_free_cal_data(int dev_map_idx) +{ + return 0; +} + +static int msm_ds2_dap_send_cal_data(int dev_map_idx) +{ + return 0; +} + +static int msm_ds2_dap_can_enable_module(int32_t module_id) +{ + return 0; +} + +static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) +{ + return 0; +} + +static bool msm_ds2_dap_check_is_param_modified(int32_t *dap_params_modified, + int32_t idx, int32_t commit) +{ + return false; +} + + +static int msm_ds2_dap_map_device_to_dolby_cache_devices(int32_t device_id) +{ + return 0; +} + +static int msm_ds2_dap_update_num_devices(struct dolby_param_data *dolby_data, + int32_t *num_device, int32_t *dev_arr, + int32_t array_size) +{ + return 0; +} + +static int msm_ds2_dap_commit_params(struct dolby_param_data *dolby_data, + int commit) +{ + return 0; +} + +static int msm_ds2_dap_handle_commands(u32 cmd, void *arg) +{ + return 0; +} + +static int msm_ds2_dap_set_param(u32 cmd, void *arg) +{ + return 0; +} + +static int msm_ds2_dap_get_param(u32 cmd, void *arg) +{ + return 0; +} + +static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) +{ + return 0; +} + +static int msm_ds2_dap_send_cached_params(int dev_map_idx, + int commit) +{ + return 0; +} + +static int msm_ds2_dap_set_vspe_vdhe(int dev_map_idx, + bool is_custom_stereo_enabled) +{ + return 0; +} + +static int msm_ds2_dap_param_visualizer_control_get( + u32 cmd, void *arg, + struct msm_pcm_routing_bdai_data *bedais) +{ + return 0; +} + +static int msm_ds2_dap_set_security_control(u32 cmd, void *arg) +{ + return 0 +} + +static int msm_ds2_dap_update_dev_map_port_id(int32_t device_id, int port_id) +{ + return 0; +} + +static int32_t msm_ds2_dap_get_port_id( + int32_t device_id, int32_t be_id) +{ + return 0; +} + +static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) +{ + return 0; +} + +static int msm_ds2_dap_handle_bypass_wait(int port_id, int copp_idx, + int wait_time) +{ + return 0; +} + +static int dap_set_custom_stereo_onoff(int dev_map_idx, + bool is_custom_stereo_enabled) +{ + return 0; +} +int qti_set_custom_stereo_on(int port_id, int copp_idx, + bool is_custom_stereo_on) +{ + return 0; +} +int set_custom_stereo_onoff(int dev_map_idx, + bool is_custom_stereo_enabled) +{ + return 0; +} +int msm_ds2_dap_ioctl_shared(struct snd_hwdep *hw, struct file *file, + u32 cmd, void *arg) +{ + return 0; +} +#endif /* CONFIG_DOLBY_DS2 || CONFIG_DOLBY_LICENSE */ diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h new file mode 100644 index 000000000000..5804a64f5d48 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _MSM_DS2_DAP_CONFIG_H_ +#define _MSM_DS2_DAP_CONFIG_H_ + +#include +#include "msm-dolby-common.h" +#include +#include + +#ifdef CONFIG_COMPAT +struct dolby_param_data32 { + s32 version; + s32 device_id; + s32 be_id; + s32 param_id; + s32 length; + compat_uptr_t data; +}; + +struct dolby_param_license32 { + compat_uptr_t dmid; + compat_uptr_t license_key; +}; + + +#define SNDRV_DEVDEP_DAP_IOCTL_SET_PARAM32\ + _IOWR('U', 0x10, struct dolby_param_data32) +#define SNDRV_DEVDEP_DAP_IOCTL_GET_PARAM32\ + _IOR('U', 0x11, struct dolby_param_data32) +#define SNDRV_DEVDEP_DAP_IOCTL_DAP_COMMAND32\ + _IOWR('U', 0x13, struct dolby_param_data32) +#define SNDRV_DEVDEP_DAP_IOCTL_DAP_LICENSE32\ + _IOWR('U', 0x14, struct dolby_param_license32) +#define SNDRV_DEVDEP_DAP_IOCTL_GET_VISUALIZER32\ + _IOR('U', 0x15, struct dolby_param_data32) +#endif + +#if defined(CONFIG_DOLBY_DS2) || defined(CONFIG_DOLBY_LICENSE) +/* DOLBY DOLBY GUIDS */ +#define DS2_MODULE_ID 0x00010775 + +#define DS2_DSP_SUPPORTED_ENDP_DEVICE 17 +#define DS2_DEVICES_ALL 32 /* enum val is 4 bytes */ + +enum { + + DAP_CMD_COMMIT_ALL = 0, + DAP_CMD_COMMIT_CHANGED = 1, + DAP_CMD_USE_CACHE_FOR_INIT = 2, + DAP_CMD_SET_BYPASS = 3, + DAP_CMD_SET_ACTIVE_DEVICE = 4, + DAP_CMD_SET_BYPASS_TYPE = 5, +}; + +#define DOLBY_PARAM_INT_ENDP_LENGTH 1 +#define DOLBY_PARAM_INT_ENDP_OFFSET (DOLBY_PARAM_PSTG_OFFSET + \ + DOLBY_PARAM_PSTG_LENGTH) +#define MAX_DS2_PARAMS 48 +#define MAX_DS2_CTRL_PARAMS 4 +#define ALL_DS2_PARAMS (MAX_DS2_PARAMS + \ + MAX_DS2_CTRL_PARAMS) +#define TOTAL_LENGTH_DS2_PARAM (TOTAL_LENGTH_DOLBY_PARAM + 1) + +int msm_ds2_dap_update_port_parameters(struct snd_hwdep *hw, struct file *file, + bool open); +int msm_ds2_dap_ioctl(struct snd_hwdep *hw, struct file *file, + u32 cmd, void *arg); +int msm_ds2_dap_compat_ioctl(struct snd_hwdep *hw, + struct file *file, + u32 cmd, void *arg); +int msm_ds2_dap_init(int port_id, int copp_idx, int channels, + bool is_custom_stereo_on); +void msm_ds2_dap_deinit(int port_id); +int msm_ds2_dap_set_custom_stereo_onoff(int port_id, int copp_idx, + bool is_custom_stereo_enabled); +/* Dolby DOLBY end */ +#else + +static inline int msm_ds2_dap_update_port_parameters(struct snd_hwdep *hw, + struct file *file, + bool open) +{ + return 0; +} + +static inline int msm_ds2_dap_ioctl(struct snd_hwdep *hw, struct file *file, + u32 cmd, void *arg) +{ + return 0; +} + +static inline int msm_ds2_dap_compat_ioctl(struct snd_hwdep *hw, + struct file *file, + u32 cmd, void *arg) +{ + return 0; +} +static inline int msm_ds2_dap_init(int port_id, int copp_idx, int channels, + bool is_custom_stereo_on) +{ + return 0; +} + +static inline void msm_ds2_dap_deinit(int port_id) { } + +static inline int msm_ds2_dap_set_custom_stereo_onoff(int port_id, int copp_idx, + bool is_custom_stereo_enabled) +{ + return 0; +} +#endif +#endif diff --git a/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c b/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c new file mode 100644 index 000000000000..437cd979359d --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2012-2014, 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm-dts-srs-tm-config.h" +#include "msm-pcm-routing-v2.h" + +static int srs_port_id[AFE_MAX_PORTS] = {-1}; +static int srs_copp_idx[AFE_MAX_PORTS] = {-1}; +static union srs_trumedia_params_u msm_srs_trumedia_params; +static struct ion_client *ion_client; +static struct ion_handle *ion_handle; +static struct param_outband po; +static atomic_t ref_cnt; +#define ION_MEM_SIZE (8 * 1024) + +static int set_port_id(int port_id, int copp_idx) +{ + int index = adm_validate_and_get_port_index(port_id); + + if (index < 0) { + pr_err("%s: Invalid port idx %d port_id %#x\n", __func__, index, + port_id); + return -EINVAL; + } + srs_port_id[index] = port_id; + srs_copp_idx[index] = copp_idx; + return 0; +} + +static void msm_dts_srs_tm_send_params(__s32 port_id, __u32 techs) +{ + __s32 index = adm_validate_and_get_port_index(port_id); + + if (index < 0) { + pr_err("%s: Invalid port idx %d port_id 0x%x\n", + __func__, index, port_id); + return; + } + if ((srs_copp_idx[index] < 0) || + (srs_copp_idx[index] >= MAX_COPPS_PER_PORT)) { + pr_debug("%s: send params called before copp open. so, caching\n", + __func__); + return; + } + pr_debug("SRS %s: called, port_id = %d, techs flags = %u\n", + __func__, port_id, techs); + /* force all if techs is set to 1 */ + if (techs == 1) + techs = 0xFFFFFFFF; + + if (techs & (1 << SRS_ID_WOWHD)) + srs_trumedia_open(port_id, srs_copp_idx[index], SRS_ID_WOWHD, + (void *)&msm_srs_trumedia_params.srs_params.wowhd); + if (techs & (1 << SRS_ID_CSHP)) + srs_trumedia_open(port_id, srs_copp_idx[index], SRS_ID_CSHP, + (void *)&msm_srs_trumedia_params.srs_params.cshp); + if (techs & (1 << SRS_ID_HPF)) + srs_trumedia_open(port_id, srs_copp_idx[index], SRS_ID_HPF, + (void *)&msm_srs_trumedia_params.srs_params.hpf); + if (techs & (1 << SRS_ID_AEQ)) + srs_trumedia_open(port_id, srs_copp_idx[index], SRS_ID_AEQ, + (void *)&msm_srs_trumedia_params.srs_params.aeq); + if (techs & (1 << SRS_ID_HL)) + srs_trumedia_open(port_id, srs_copp_idx[index], SRS_ID_HL, + (void *)&msm_srs_trumedia_params.srs_params.hl); + if (techs & (1 << SRS_ID_GEQ)) + srs_trumedia_open(port_id, srs_copp_idx[index], SRS_ID_GEQ, + (void *)&msm_srs_trumedia_params.srs_params.geq); + if (techs & (1 << SRS_ID_GLOBAL)) + srs_trumedia_open(port_id, srs_copp_idx[index], SRS_ID_GLOBAL, + (void *)&msm_srs_trumedia_params.srs_params.global); +} + + +static int msm_dts_srs_trumedia_control_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = 0; + return 0; +} + +static int msm_dts_srs_trumedia_control_set_(int port_id, + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + __u16 offset, value, max = sizeof(msm_srs_trumedia_params) >> 1; + + if (SRS_CMD_UPLOAD == + (ucontrol->value.integer.value[0] & SRS_CMD_UPLOAD)) { + __u32 techs = ucontrol->value.integer.value[0] & 0xFF; + __s32 index = adm_validate_and_get_port_index(port_id); + + if (index < 0) { + pr_err("%s: Invalid port idx %d port_id 0x%x\n", + __func__, index, port_id); + return -EINVAL; + } + pr_debug("SRS %s: send params request, flag = %u\n", + __func__, techs); + if (srs_port_id[index] >= 0 && techs) + msm_dts_srs_tm_send_params(port_id, techs); + return 0; + } + offset = (__u16)((ucontrol->value.integer.value[0] & + SRS_PARAM_OFFSET_MASK) >> 16); + value = (__u16)(ucontrol->value.integer.value[0] & + SRS_PARAM_VALUE_MASK); + if (offset < max) { + msm_srs_trumedia_params.raw_params[offset] = value; + pr_debug("SRS %s: index set... (max %d, requested %d, value 0x%X)\n", + __func__, max, offset, value); + } else { + pr_err("SRS %s: index out of bounds! (max %d, requested %d)\n", + __func__, max, offset); + } + return 0; +} + +static int msm_dts_srs_trumedia_control_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret, port_id; + + pr_debug("SRS control normal called\n"); + msm_pcm_routing_acquire_lock(); + port_id = SLIMBUS_0_RX; + ret = msm_dts_srs_trumedia_control_set_(port_id, kcontrol, ucontrol); + msm_pcm_routing_release_lock(); + return ret; +} + +static int msm_dts_srs_trumedia_control_i2s_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret, port_id; + + pr_debug("SRS control I2S called\n"); + msm_pcm_routing_acquire_lock(); + port_id = PRIMARY_I2S_RX; + ret = msm_dts_srs_trumedia_control_set_(port_id, kcontrol, ucontrol); + msm_pcm_routing_release_lock(); + return ret; +} + +static int msm_dts_srs_trumedia_control_mi2s_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret, port_id; + + pr_debug("SRS control MI2S called\n"); + msm_pcm_routing_acquire_lock(); + port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; + ret = msm_dts_srs_trumedia_control_set_(port_id, kcontrol, ucontrol); + msm_pcm_routing_release_lock(); + return ret; +} + +static int msm_dts_srs_trumedia_control_hdmi_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret, port_id; + + pr_debug("SRS control HDMI called\n"); + msm_pcm_routing_acquire_lock(); + port_id = HDMI_RX; + ret = msm_dts_srs_trumedia_control_set_(port_id, kcontrol, ucontrol); + msm_pcm_routing_release_lock(); + return ret; +} + +static const struct snd_kcontrol_new lpa_srs_trumedia_controls[] = { + {.iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "SRS TruMedia", + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | + SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = snd_soc_info_volsw, + .get = msm_dts_srs_trumedia_control_get, + .put = msm_dts_srs_trumedia_control_set, + .private_value = ((unsigned long)&(struct soc_mixer_control) + {.reg = SND_SOC_NOPM, + .rreg = SND_SOC_NOPM, + .shift = 0, + .rshift = 0, + .max = 0xFFFFFFFF, + .platform_max = 0xFFFFFFFF, + .invert = 0 + }) + } +}; + +static const struct snd_kcontrol_new lpa_srs_trumedia_controls_hdmi[] = { + {.iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "SRS TruMedia HDMI", + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | + SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = snd_soc_info_volsw, + .get = msm_dts_srs_trumedia_control_get, + .put = msm_dts_srs_trumedia_control_hdmi_set, + .private_value = ((unsigned long)&(struct soc_mixer_control) + {.reg = SND_SOC_NOPM, + .rreg = SND_SOC_NOPM, + .shift = 0, + .rshift = 0, + .max = 0xFFFFFFFF, + .platform_max = 0xFFFFFFFF, + .invert = 0 + }) + } +}; + +static const struct snd_kcontrol_new lpa_srs_trumedia_controls_i2s[] = { + {.iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "SRS TruMedia I2S", + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | + SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = snd_soc_info_volsw, + .get = msm_dts_srs_trumedia_control_get, + .put = msm_dts_srs_trumedia_control_i2s_set, + .private_value = ((unsigned long)&(struct soc_mixer_control) + {.reg = SND_SOC_NOPM, + .rreg = SND_SOC_NOPM, + .shift = 0, + .rshift = 0, + .max = 0xFFFFFFFF, + .platform_max = 0xFFFFFFFF, + .invert = 0 + }) + } +}; + +static const struct snd_kcontrol_new lpa_srs_trumedia_controls_mi2s[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "SRS TruMedia MI2S", + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | + SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = snd_soc_info_volsw, + .get = msm_dts_srs_trumedia_control_get, + .put = msm_dts_srs_trumedia_control_mi2s_set, + .private_value = ((unsigned long)&(struct soc_mixer_control) + { + .reg = SND_SOC_NOPM, + .rreg = SND_SOC_NOPM, + .shift = 0, + .rshift = 0, + .max = 0xFFFFFFFF, + .platform_max = 0xFFFFFFFF, + .invert = 0 + }) + } +}; + +void msm_dts_srs_tm_add_controls(struct snd_soc_platform *platform) +{ + snd_soc_add_platform_controls(platform, + lpa_srs_trumedia_controls, + ARRAY_SIZE(lpa_srs_trumedia_controls)); + + snd_soc_add_platform_controls(platform, + lpa_srs_trumedia_controls_hdmi, + ARRAY_SIZE(lpa_srs_trumedia_controls_hdmi)); + + snd_soc_add_platform_controls(platform, + lpa_srs_trumedia_controls_i2s, + ARRAY_SIZE(lpa_srs_trumedia_controls_i2s)); + snd_soc_add_platform_controls(platform, + lpa_srs_trumedia_controls_mi2s, + ARRAY_SIZE(lpa_srs_trumedia_controls_mi2s)); +} + +static int reg_ion_mem(void) +{ + int rc; + + rc = msm_audio_ion_alloc("SRS_TRUMEDIA", &ion_client, &ion_handle, + ION_MEM_SIZE, &po.paddr, (size_t *)&po.size, + &po.kvaddr); + if (rc != 0) + pr_err("%s: failed to allocate memory.\n", __func__); + pr_debug("%s: exited ion_client = %pK, ion_handle = %pK, phys_addr = %lu, length = %d, vaddr = %pK, rc = 0x%x\n", + __func__, ion_client, ion_handle, (long)po.paddr, + (unsigned int)po.size, po.kvaddr, rc); + return rc; +} + +void msm_dts_srs_tm_ion_memmap(struct param_outband *po_) +{ + if (po.kvaddr == NULL) { + pr_debug("%s: callingreg_ion_mem()\n", __func__); + reg_ion_mem(); + } + po_->size = ION_MEM_SIZE; + po_->kvaddr = po.kvaddr; + po_->paddr = po.paddr; +} + +static void unreg_ion_mem(void) +{ + msm_audio_ion_free(ion_client, ion_handle); + po.kvaddr = NULL; + po.paddr = 0; + po.size = 0; +} + +void msm_dts_srs_tm_deinit(int port_id) +{ + set_port_id(port_id, -1); + atomic_dec(&ref_cnt); + if (po.kvaddr != NULL) { + if (!atomic_read(&ref_cnt)) { + pr_debug("%s: calling unreg_ion_mem()\n", __func__); + unreg_ion_mem(); + } + } +} + +void msm_dts_srs_tm_init(int port_id, int copp_idx) +{ + int cur_ref_cnt = 0; + + if (set_port_id(port_id, copp_idx) < 0) { + pr_err("%s: Invalid port_id: %d\n", __func__, port_id); + return; + } + + cur_ref_cnt = atomic_read(&ref_cnt); + atomic_inc(&ref_cnt); + if (!cur_ref_cnt && po.kvaddr == NULL) { + pr_debug("%s: calling reg_ion_mem()\n", __func__); + if (reg_ion_mem() != 0) { + atomic_dec(&ref_cnt); + po.kvaddr = NULL; + return; + } + } + msm_dts_srs_tm_send_params(port_id, 1); +} diff --git a/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.h b/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.h new file mode 100644 index 000000000000..e3c75b3bd755 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _MSM_DTS_SRS_TM_CONFIG_H_ +#define _MSM_DTS_SRS_TM_CONFIG_H_ + +#include + +struct param_outband; + +#ifdef CONFIG_DTS_SRS_TM + +union srs_trumedia_params_u { + struct srs_trumedia_params srs_params; + __u16 raw_params[1]; +}; + +void msm_dts_srs_tm_ion_memmap(struct param_outband *po_); +void msm_dts_srs_tm_init(int port_id, int copp_idx); +void msm_dts_srs_tm_deinit(int port_id); +void msm_dts_srs_tm_add_controls(struct snd_soc_platform *platform); +#else +static inline void msm_dts_srs_tm_ion_memmap(struct param_outband *po_) { } +static inline void msm_dts_srs_tm_init(int port_id, int copp_idx) { } +static inline void msm_dts_srs_tm_deinit(int port_id) { } +static inline void msm_dts_srs_tm_add_controls( + struct snd_soc_platform *platform) { } + +#endif + +#endif diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c new file mode 100644 index 000000000000..3a6cbe6937c4 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c @@ -0,0 +1,2414 @@ +/* + * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm-pcm-routing-v2.h" + +#define CAPTURE_MIN_NUM_PERIODS 2 +#define CAPTURE_MAX_NUM_PERIODS 8 +#define CAPTURE_MAX_PERIOD_SIZE 61440 +#define CAPTURE_MIN_PERIOD_SIZE 320 +#define LISTEN_MAX_STATUS_PAYLOAD_SIZE 256 + +#define LAB_BUFFER_ALLOC 1 +#define LAB_BUFFER_DEALLOC 0 + +static struct snd_pcm_hardware msm_pcm_hardware_capture = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .rates = (SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .rate_min = 16000, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 4, + .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * + CAPTURE_MAX_PERIOD_SIZE, + .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE, + .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE, + .periods_min = CAPTURE_MIN_NUM_PERIODS, + .periods_max = CAPTURE_MAX_NUM_PERIODS, + .fifo_size = 0, +}; + +/* Conventional and unconventional sample rate supported */ +static unsigned int supported_sample_rates[] = { + 16000, 48000, +}; + +static struct snd_pcm_hw_constraint_list constraints_sample_rates = { + .count = ARRAY_SIZE(supported_sample_rates), + .list = supported_sample_rates, + .mask = 0, +}; + +struct lsm_priv { + struct snd_pcm_substream *substream; + struct lsm_client *lsm_client; + struct snd_lsm_event_status_v3 *event_status; + spinlock_t event_lock; + wait_queue_head_t event_wait; + unsigned long event_avail; + atomic_t event_wait_stop; + atomic_t buf_count; + atomic_t read_abort; + wait_queue_head_t period_wait; + struct mutex lsm_api_lock; + int appl_cnt; + int dma_write; +}; + +enum { /* lsm session states */ + IDLE = 0, + RUNNING, +}; + +static int msm_lsm_queue_lab_buffer(struct lsm_priv *prtd, int i) +{ + int rc = 0; + struct lsm_cmd_read cmd_read; + struct snd_soc_pcm_runtime *rtd; + + if (!prtd || !prtd->lsm_client) { + pr_err("%s: Invalid params prtd %pK lsm client %pK\n", + __func__, prtd, ((!prtd) ? NULL : prtd->lsm_client)); + return -EINVAL; + } + if (!prtd->substream || !prtd->substream->private_data) { + pr_err("%s: Invalid %s\n", __func__, + (!prtd->substream) ? "substream" : "private_data"); + return -EINVAL; + } + rtd = prtd->substream->private_data; + + if (!prtd->lsm_client->lab_buffer || + i >= prtd->lsm_client->hw_params.period_count) { + dev_err(rtd->dev, + "%s: Lab buffer not setup %pK incorrect index %d period count %d\n", + __func__, prtd->lsm_client->lab_buffer, i, + prtd->lsm_client->hw_params.period_count); + return -EINVAL; + } + cmd_read.buf_addr_lsw = + lower_32_bits(prtd->lsm_client->lab_buffer[i].phys); + cmd_read.buf_addr_msw = + msm_audio_populate_upper_32_bits( + prtd->lsm_client->lab_buffer[i].phys); + cmd_read.buf_size = prtd->lsm_client->lab_buffer[i].size; + cmd_read.mem_map_handle = + prtd->lsm_client->lab_buffer[i].mem_map_handle; + rc = q6lsm_read(prtd->lsm_client, &cmd_read); + if (rc) + dev_err(rtd->dev, + "%s: error in queuing the lab buffer rc %d\n", + __func__, rc); + return rc; +} + +static int lsm_lab_buffer_sanity(struct lsm_priv *prtd, + struct lsm_cmd_read_done *read_done, int *index) +{ + int i = 0, rc = -EINVAL; + struct snd_soc_pcm_runtime *rtd; + + if (!prtd || !read_done || !index) { + pr_err("%s: Invalid params prtd %pK read_done %pK index %pK\n", + __func__, prtd, read_done, index); + return -EINVAL; + } + + if (!prtd->substream || !prtd->substream->private_data) { + pr_err("%s: Invalid %s\n", __func__, + (!prtd->substream) ? "substream" : "private_data"); + return -EINVAL; + } + rtd = prtd->substream->private_data; + + if (!prtd->lsm_client->lab_enable || !prtd->lsm_client->lab_buffer) { + dev_err(rtd->dev, + "%s: Lab not enabled %d invalid lab buffer %pK\n", + __func__, prtd->lsm_client->lab_enable, + prtd->lsm_client->lab_buffer); + return -EINVAL; + } + for (i = 0; i < prtd->lsm_client->hw_params.period_count; i++) { + if ((lower_32_bits(prtd->lsm_client->lab_buffer[i].phys) == + read_done->buf_addr_lsw) && + (msm_audio_populate_upper_32_bits + (prtd->lsm_client->lab_buffer[i].phys) == + read_done->buf_addr_msw) && + (prtd->lsm_client->lab_buffer[i].mem_map_handle == + read_done->mem_map_handle)) { + dev_dbg(rtd->dev, + "%s: Buffer found %pK memmap handle %d\n", + __func__, &prtd->lsm_client->lab_buffer[i].phys, + prtd->lsm_client->lab_buffer[i].mem_map_handle); + if (read_done->total_size > + prtd->lsm_client->lab_buffer[i].size) { + dev_err(rtd->dev, + "%s: Size mismatch call back size %d actual size %zd\n", + __func__, read_done->total_size, + prtd->lsm_client->lab_buffer[i].size); + rc = -EINVAL; + break; + } else { + *index = i; + rc = 0; + break; + } + } + } + return rc; +} + +static void lsm_event_handler(uint32_t opcode, uint32_t token, + void *payload, void *priv) +{ + unsigned long flags; + struct lsm_priv *prtd = priv; + struct snd_pcm_substream *substream = prtd->substream; + struct snd_soc_pcm_runtime *rtd; + struct snd_lsm_event_status_v3 *temp; + uint16_t status = 0; + uint16_t payload_size = 0; + uint16_t index = 0; + uint32_t event_ts_lsw = 0; + uint32_t event_ts_msw = 0; + + if (!substream || !substream->private_data) { + pr_err("%s: Invalid %s\n", __func__, + (!substream) ? "substream" : "private_data"); + return; + } + rtd = substream->private_data; + + switch (opcode) { + case LSM_DATA_EVENT_READ_DONE: { + int rc; + struct lsm_cmd_read_done *read_done = payload; + int buf_index = 0; + + if (prtd->lsm_client->session != token || + !read_done) { + dev_err(rtd->dev, + "%s: EVENT_READ_DONE invalid callback, session %d callback %d payload %pK", + __func__, prtd->lsm_client->session, + token, read_done); + return; + } + if (atomic_read(&prtd->read_abort)) { + dev_dbg(rtd->dev, + "%s: read abort set skip data\n", __func__); + return; + } + if (!lsm_lab_buffer_sanity(prtd, read_done, &buf_index)) { + dev_dbg(rtd->dev, + "%s: process read done index %d\n", + __func__, buf_index); + if (buf_index >= + prtd->lsm_client->hw_params.period_count) { + dev_err(rtd->dev, + "%s: Invalid index %d buf_index max cnt %d\n", + __func__, buf_index, + prtd->lsm_client->hw_params.period_count); + return; + } + prtd->dma_write += read_done->total_size; + atomic_inc(&prtd->buf_count); + snd_pcm_period_elapsed(substream); + wake_up(&prtd->period_wait); + /* queue the next period buffer */ + buf_index = (buf_index + 1) % + prtd->lsm_client->hw_params.period_count; + rc = msm_lsm_queue_lab_buffer(prtd, buf_index); + if (rc) + dev_err(rtd->dev, + "%s: error in queuing the lab buffer rc %d\n", + __func__, rc); + } else + dev_err(rtd->dev, "%s: Invalid lab buffer returned by dsp\n", + __func__); + break; + } + + case LSM_SESSION_EVENT_DETECTION_STATUS: + status = (uint16_t)((uint8_t *)payload)[0]; + payload_size = (uint16_t)((uint8_t *)payload)[2]; + index = 4; + dev_dbg(rtd->dev, + "%s: event detect status = %d payload size = %d\n", + __func__, status, payload_size); + break; + + case LSM_SESSION_EVENT_DETECTION_STATUS_V2: + status = (uint16_t)((uint8_t *)payload)[0]; + payload_size = (uint16_t)((uint8_t *)payload)[1]; + index = 2; + dev_dbg(rtd->dev, + "%s: event detect status = %d payload size = %d\n", + __func__, status, payload_size); + break; + + case LSM_SESSION_EVENT_DETECTION_STATUS_V3: + event_ts_lsw = ((uint32_t *)payload)[0]; + event_ts_msw = ((uint32_t *)payload)[1]; + status = (uint16_t)((uint8_t *)payload)[8]; + payload_size = (uint16_t)((uint8_t *)payload)[9]; + index = 10; + dev_dbg(rtd->dev, + "%s: ts_msw = %u, ts_lsw = %u, event detect status = %d payload size = %d\n", + __func__, event_ts_msw, event_ts_lsw, status, + payload_size); + break; + + default: + break; + } + + if (opcode == LSM_SESSION_EVENT_DETECTION_STATUS || + opcode == LSM_SESSION_EVENT_DETECTION_STATUS_V2 || + opcode == LSM_SESSION_EVENT_DETECTION_STATUS_V3) { + spin_lock_irqsave(&prtd->event_lock, flags); + temp = krealloc(prtd->event_status, + sizeof(struct snd_lsm_event_status_v3) + + payload_size, GFP_ATOMIC); + if (!temp) { + dev_err(rtd->dev, "%s: no memory for event status\n", + __func__); + return; + } + /* + * event status timestamp will be non-zero and valid if + * opcode is LSM_SESSION_EVENT_DETECTION_STATUS_V3 + */ + prtd->event_status = temp; + prtd->event_status->timestamp_lsw = event_ts_lsw; + prtd->event_status->timestamp_msw = event_ts_msw; + prtd->event_status->status = status; + prtd->event_status->payload_size = payload_size; + + if (likely(prtd->event_status)) { + memcpy(prtd->event_status->payload, + &((uint8_t *)payload)[index], + payload_size); + prtd->event_avail = 1; + spin_unlock_irqrestore(&prtd->event_lock, flags); + wake_up(&prtd->event_wait); + } else { + spin_unlock_irqrestore(&prtd->event_lock, flags); + dev_err(rtd->dev, + "%s: Couldn't allocate %d bytes of memory\n", + __func__, payload_size); + } + if (substream->timer_running) + snd_timer_interrupt(substream->timer, 1); + } +} + +static int msm_lsm_lab_buffer_alloc(struct lsm_priv *lsm, int alloc) +{ + int ret = 0; + struct snd_dma_buffer *dma_buf = NULL; + + if (!lsm) { + pr_err("%s: Invalid param lsm %pK\n", __func__, lsm); + return -EINVAL; + } + if (alloc) { + if (!lsm->substream) { + pr_err("%s: substream is NULL\n", __func__); + return -EINVAL; + } + ret = q6lsm_lab_buffer_alloc(lsm->lsm_client, alloc); + if (ret) { + pr_err("%s: alloc lab buffer failed ret %d\n", + __func__, ret); + goto exit; + } + dma_buf = &lsm->substream->dma_buffer; + dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; + dma_buf->dev.dev = lsm->substream->pcm->card->dev; + dma_buf->private_data = NULL; + dma_buf->area = lsm->lsm_client->lab_buffer[0].data; + dma_buf->addr = lsm->lsm_client->lab_buffer[0].phys; + dma_buf->bytes = lsm->lsm_client->hw_params.buf_sz * + lsm->lsm_client->hw_params.period_count; + snd_pcm_set_runtime_buffer(lsm->substream, dma_buf); + } else { + ret = q6lsm_lab_buffer_alloc(lsm->lsm_client, alloc); + if (ret) + pr_err("%s: free lab buffer failed ret %d\n", + __func__, ret); + kfree(lsm->lsm_client->lab_buffer); + lsm->lsm_client->lab_buffer = NULL; + } +exit: + return ret; +} + +static int msm_lsm_get_conf_levels(struct lsm_client *client, + u8 *conf_levels_ptr) +{ + int rc = 0; + + if (client->num_confidence_levels == 0) { + pr_debug("%s: no confidence levels provided\n", + __func__); + client->confidence_levels = NULL; + goto done; + } + + client->confidence_levels = + kzalloc((sizeof(uint8_t) * client->num_confidence_levels), + GFP_KERNEL); + if (!client->confidence_levels) { + pr_err("%s: No memory for confidence\n" + "levels num of level from user = %d\n", + __func__, client->num_confidence_levels); + rc = -ENOMEM; + goto done; + } + + if (copy_from_user(client->confidence_levels, + conf_levels_ptr, + client->num_confidence_levels)) { + pr_err("%s: copy from user failed, size = %d\n", + __func__, client->num_confidence_levels); + rc = -EFAULT; + goto copy_err; + } + + return rc; + +copy_err: + kfree(client->confidence_levels); + client->confidence_levels = NULL; +done: + return rc; + +} + +static int msm_lsm_set_epd(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int rc = 0; + struct snd_lsm_ep_det_thres epd_th; + + if (p_info->param_size != sizeof(epd_th)) { + dev_err(rtd->dev, + "%s: Invalid param_size %d\n", + __func__, p_info->param_size); + rc = -EINVAL; + goto done; + } + + if (copy_from_user(&epd_th, p_info->param_data, + p_info->param_size)) { + dev_err(rtd->dev, + "%s: copy_from_user failed, size = %d\n", + __func__, p_info->param_size); + rc = -EFAULT; + goto done; + } + + rc = q6lsm_set_one_param(prtd->lsm_client, p_info, + &epd_th, LSM_ENDPOINT_DETECT_THRESHOLD); + if (rc) + dev_err(rtd->dev, + "%s: Failed to set epd param, err = %d\n", + __func__, rc); +done: + return rc; +} + +static int msm_lsm_set_mode(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_lsm_detect_mode mode; + int rc = 0; + + if (p_info->param_size != sizeof(mode)) { + dev_err(rtd->dev, + "%s: Invalid param_size %d\n", + __func__, p_info->param_size); + rc = -EINVAL; + goto done; + } + + if (copy_from_user(&mode, p_info->param_data, + sizeof(mode))) { + dev_err(rtd->dev, + "%s: copy_from_user failed, size = %zd\n", + __func__, sizeof(mode)); + rc = -EFAULT; + goto done; + } + + rc = q6lsm_set_one_param(prtd->lsm_client, p_info, + &mode, LSM_OPERATION_MODE); + if (rc) + dev_err(rtd->dev, + "%s: Failed to set det_mode param, err = %d\n", + __func__, rc); +done: + return rc; +} + +static int msm_lsm_set_gain(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_lsm_gain gain; + int rc = 0; + + if (p_info->param_size != sizeof(gain)) { + dev_err(rtd->dev, + "%s: Invalid param_size %d\n", + __func__, p_info->param_size); + rc = -EINVAL; + goto done; + } + + if (copy_from_user(&gain, p_info->param_data, + sizeof(gain))) { + dev_err(rtd->dev, + "%s: copy_from_user failed, size = %zd\n", + __func__, sizeof(gain)); + rc = -EFAULT; + goto done; + } + + rc = q6lsm_set_one_param(prtd->lsm_client, p_info, + &gain, LSM_GAIN); + if (rc) + dev_err(rtd->dev, + "%s: Failed to set det_mode param, err = %d\n", + __func__, rc); +done: + return rc; +} + +static int msm_lsm_set_conf(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int rc = 0; + + if (p_info->param_size > MAX_NUM_CONFIDENCE) { + dev_err(rtd->dev, + "%s: invalid confidence levels %d\n", + __func__, p_info->param_size); + return -EINVAL; + } + + prtd->lsm_client->num_confidence_levels = + p_info->param_size; + rc = msm_lsm_get_conf_levels(prtd->lsm_client, + p_info->param_data); + if (rc) { + dev_err(rtd->dev, + "%s: get_conf_levels failed, err = %d\n", + __func__, rc); + return rc; + } + + rc = q6lsm_set_one_param(prtd->lsm_client, p_info, + prtd->lsm_client->confidence_levels, + LSM_MIN_CONFIDENCE_LEVELS); + if (rc) + dev_err(rtd->dev, + "%s: Failed to set min_conf_levels, err = %d\n", + __func__, rc); + + return rc; +} + +static int msm_lsm_reg_model(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int rc = 0; + u8 *snd_model_ptr; + size_t offset; + + rc = q6lsm_snd_model_buf_alloc(prtd->lsm_client, + p_info->param_size, + true); + if (rc) { + dev_err(rtd->dev, + "%s: snd_model buf alloc failed, size = %d\n", + __func__, p_info->param_size); + return rc; + } + + q6lsm_sm_set_param_data(prtd->lsm_client, p_info, &offset); + + /* + * For set_param, advance the sound model data with the + * number of bytes required by param_data. + */ + snd_model_ptr = ((u8 *) prtd->lsm_client->sound_model.data) + offset; + + if (copy_from_user(snd_model_ptr, + p_info->param_data, p_info->param_size)) { + dev_err(rtd->dev, + "%s: copy_from_user for snd_model failed, size = %d\n", + __func__, p_info->param_size); + rc = -EFAULT; + goto err_copy; + } + rc = q6lsm_set_one_param(prtd->lsm_client, p_info, NULL, + LSM_REG_SND_MODEL); + if (rc) { + dev_err(rtd->dev, + "%s: Failed to set sound_model, err = %d\n", + __func__, rc); + goto err_copy; + } + return rc; + +err_copy: + q6lsm_snd_model_buf_free(prtd->lsm_client); + return rc; +} + +static int msm_lsm_dereg_model(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int rc = 0; + + rc = q6lsm_set_one_param(prtd->lsm_client, p_info, + NULL, LSM_DEREG_SND_MODEL); + if (rc) + dev_err(rtd->dev, + "%s: Failed to set det_mode param, err = %d\n", + __func__, rc); + + q6lsm_snd_model_buf_free(prtd->lsm_client); + + return rc; +} + +static int msm_lsm_set_custom(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + u8 *data; + int rc = 0; + + data = kzalloc(p_info->param_size, GFP_KERNEL); + if (!data) + return -ENOMEM; + + if (copy_from_user(data, p_info->param_data, + p_info->param_size)) { + dev_err(rtd->dev, + "%s: copy_from_user failed for custom params, size = %d\n", + __func__, p_info->param_size); + rc = -EFAULT; + goto err_ret; + } + + rc = q6lsm_set_one_param(prtd->lsm_client, p_info, + data, LSM_CUSTOM_PARAMS); + if (rc) + dev_err(rtd->dev, + "%s: Failed to set custom param, err = %d\n", + __func__, rc); + +err_ret: + kfree(data); + return rc; +} + +static int msm_lsm_set_poll_enable(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_lsm_poll_enable poll_enable; + int rc = 0; + + if (p_info->param_size != sizeof(poll_enable)) { + dev_err(rtd->dev, + "%s: Invalid param_size %d\n", + __func__, p_info->param_size); + rc = -EINVAL; + goto done; + } + + if (copy_from_user(&poll_enable, p_info->param_data, + sizeof(poll_enable))) { + dev_err(rtd->dev, + "%s: copy_from_user failed, size = %zd\n", + __func__, sizeof(poll_enable)); + rc = -EFAULT; + goto done; + } + + if (prtd->lsm_client->poll_enable == poll_enable.poll_en) { + dev_dbg(rtd->dev, + "%s: Polling for session %d already %s\n", + __func__, prtd->lsm_client->session, + (poll_enable.poll_en ? "enabled" : "disabled")); + rc = 0; + goto done; + } + + rc = q6lsm_set_one_param(prtd->lsm_client, p_info, + &poll_enable, LSM_POLLING_ENABLE); + if (!rc) { + prtd->lsm_client->poll_enable = poll_enable.poll_en; + } else { + dev_err(rtd->dev, + "%s: Failed to set poll enable, err = %d\n", + __func__, rc); + } +done: + return rc; +} + +static int msm_lsm_process_params(struct snd_pcm_substream *substream, + struct snd_lsm_module_params *p_data, + void *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct lsm_params_info *p_info; + int i; + int rc = 0; + + p_info = (struct lsm_params_info *) params; + + for (i = 0; i < p_data->num_params; i++) { + dev_dbg(rtd->dev, + "%s: param (%d), module_id = 0x%x, param_id = 0x%x, param_size = 0x%x, param_type = 0x%x\n", + __func__, i, p_info->module_id, + p_info->param_id, p_info->param_size, + p_info->param_type); + + switch (p_info->param_type) { + case LSM_ENDPOINT_DETECT_THRESHOLD: + rc = msm_lsm_set_epd(substream, p_info); + break; + case LSM_OPERATION_MODE: + rc = msm_lsm_set_mode(substream, p_info); + break; + case LSM_GAIN: + rc = msm_lsm_set_gain(substream, p_info); + break; + case LSM_MIN_CONFIDENCE_LEVELS: + rc = msm_lsm_set_conf(substream, p_info); + break; + case LSM_REG_SND_MODEL: + rc = msm_lsm_reg_model(substream, p_info); + break; + case LSM_DEREG_SND_MODEL: + rc = msm_lsm_dereg_model(substream, p_info); + break; + case LSM_CUSTOM_PARAMS: + rc = msm_lsm_set_custom(substream, p_info); + break; + case LSM_POLLING_ENABLE: + rc = msm_lsm_set_poll_enable(substream, p_info); + break; + default: + dev_err(rtd->dev, + "%s: Invalid param_type %d\n", + __func__, p_info->param_type); + rc = -EINVAL; + break; + } + if (rc) { + pr_err("%s: set_param fail for param_type %d\n", + __func__, p_info->param_type); + return rc; + } + + p_info++; + } + + return rc; +} + +static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, + unsigned int cmd, void *arg) +{ + struct snd_soc_pcm_runtime *rtd; + unsigned long flags; + int ret; + struct snd_lsm_sound_model_v2 snd_model_v2; + struct snd_lsm_session_data session_data; + int rc = 0; + int xchg = 0; + struct snd_pcm_runtime *runtime; + struct lsm_priv *prtd; + struct snd_lsm_detection_params det_params; + uint8_t *confidence_level = NULL; + + if (!substream || !substream->private_data) { + pr_err("%s: Invalid %s\n", __func__, + (!substream) ? "substream" : "private_data"); + return -EINVAL; + } + + runtime = substream->runtime; + prtd = runtime->private_data; + rtd = substream->private_data; + + switch (cmd) { + case SNDRV_LSM_SET_SESSION_DATA: + dev_dbg(rtd->dev, "%s: set session data\n", __func__); + if (copy_from_user(&session_data, arg, + sizeof(session_data))) { + dev_err(rtd->dev, "%s: %s: copy_from_user failed\n", + __func__, "LSM_SET_SESSION_DATA"); + return -EFAULT; + } + + if (session_data.app_id != LSM_VOICE_WAKEUP_APP_ID_V2) { + dev_err(rtd->dev, + "%s:Invalid App id %d for Listen client\n", + __func__, session_data.app_id); + rc = -EINVAL; + break; + } + + prtd->lsm_client->app_id = session_data.app_id; + ret = q6lsm_open(prtd->lsm_client, + prtd->lsm_client->app_id); + if (ret < 0) { + dev_err(rtd->dev, + "%s: lsm open failed, %d\n", + __func__, ret); + return ret; + } + prtd->lsm_client->opened = true; + dev_dbg(rtd->dev, "%s: Session_ID = %d, APP ID = %d\n", + __func__, + prtd->lsm_client->session, + prtd->lsm_client->app_id); + break; + case SNDRV_LSM_REG_SND_MODEL_V2: + dev_dbg(rtd->dev, "%s: Registering sound model V2\n", + __func__); + memcpy(&snd_model_v2, arg, + sizeof(struct snd_lsm_sound_model_v2)); + if (snd_model_v2.num_confidence_levels > + MAX_NUM_CONFIDENCE) { + dev_err(rtd->dev, + "%s: Invalid conf_levels = %d, maximum allowed = %d\n", + __func__, snd_model_v2.num_confidence_levels, + MAX_NUM_CONFIDENCE); + rc = -EINVAL; + break; + } + rc = q6lsm_snd_model_buf_alloc(prtd->lsm_client, + snd_model_v2.data_size, false); + if (rc) { + dev_err(rtd->dev, + "%s: q6lsm buffer alloc failed V2, size %d\n", + __func__, snd_model_v2.data_size); + break; + } + if (copy_from_user(prtd->lsm_client->sound_model.data, + snd_model_v2.data, snd_model_v2.data_size)) { + dev_err(rtd->dev, + "%s: copy from user data failed\n" + "data %pK size %d\n", __func__, + snd_model_v2.data, snd_model_v2.data_size); + q6lsm_snd_model_buf_free(prtd->lsm_client); + rc = -EFAULT; + break; + } + + dev_dbg(rtd->dev, "SND Model Magic no byte[0] %x,\n" + "byte[1] %x, byte[2] %x byte[3] %x\n", + snd_model_v2.data[0], snd_model_v2.data[1], + snd_model_v2.data[2], snd_model_v2.data[3]); + prtd->lsm_client->num_confidence_levels = + snd_model_v2.num_confidence_levels; + + rc = msm_lsm_get_conf_levels(prtd->lsm_client, + snd_model_v2.confidence_level); + if (rc) { + dev_err(rtd->dev, + "%s: get_conf_levels failed, err = %d\n", + __func__, rc); + break; + } + + rc = q6lsm_register_sound_model(prtd->lsm_client, + snd_model_v2.detection_mode, + snd_model_v2.detect_failure); + if (rc < 0) { + dev_err(rtd->dev, + "%s: Register snd Model v2 failed =%d\n", + __func__, rc); + kfree(confidence_level); + q6lsm_snd_model_buf_free(prtd->lsm_client); + } + + kfree(prtd->lsm_client->confidence_levels); + prtd->lsm_client->confidence_levels = NULL; + break; + + case SNDRV_LSM_SET_PARAMS: + dev_dbg(rtd->dev, "%s: set_params\n", __func__); + memcpy(&det_params, arg, + sizeof(det_params)); + if (det_params.num_confidence_levels > + MAX_NUM_CONFIDENCE) { + rc = -EINVAL; + break; + } + + prtd->lsm_client->num_confidence_levels = + det_params.num_confidence_levels; + + rc = msm_lsm_get_conf_levels(prtd->lsm_client, + det_params.conf_level); + if (rc) { + dev_err(rtd->dev, + "%s: Failed to get conf_levels, err = %d\n", + __func__, rc); + break; + } + + rc = q6lsm_set_data(prtd->lsm_client, + det_params.detect_mode, + det_params.detect_failure); + if (rc) + dev_err(rtd->dev, + "%s: Failed to set params, err = %d\n", + __func__, rc); + + kfree(prtd->lsm_client->confidence_levels); + prtd->lsm_client->confidence_levels = NULL; + + break; + + case SNDRV_LSM_DEREG_SND_MODEL: + dev_dbg(rtd->dev, "%s: Deregistering sound model\n", + __func__); + rc = q6lsm_deregister_sound_model(prtd->lsm_client); + if (rc) + dev_err(rtd->dev, + "%s: Sound model de-register failed, err = %d\n", + __func__, rc); + break; + + case SNDRV_LSM_EVENT_STATUS: + case SNDRV_LSM_EVENT_STATUS_V3: { + uint32_t ts_lsw, ts_msw; + uint16_t status = 0, payload_size = 0; + + dev_dbg(rtd->dev, "%s: Get event status\n", __func__); + atomic_set(&prtd->event_wait_stop, 0); + + /* + * Release the api lock before wait to allow + * other IOCTLs to be invoked while waiting + * for event + */ + mutex_unlock(&prtd->lsm_api_lock); + rc = wait_event_freezable(prtd->event_wait, + (cmpxchg(&prtd->event_avail, 1, 0) || + (xchg = atomic_cmpxchg(&prtd->event_wait_stop, + 1, 0)))); + mutex_lock(&prtd->lsm_api_lock); + dev_dbg(rtd->dev, "%s: wait_event_freezable %d event_wait_stop %d\n", + __func__, rc, xchg); + if (!rc && !xchg) { + dev_dbg(rtd->dev, "%s: New event available %ld\n", + __func__, prtd->event_avail); + spin_lock_irqsave(&prtd->event_lock, flags); + + if (prtd->event_status) { + payload_size = prtd->event_status->payload_size; + ts_lsw = prtd->event_status->timestamp_lsw; + ts_msw = prtd->event_status->timestamp_msw; + status = prtd->event_status->status; + spin_unlock_irqrestore(&prtd->event_lock, + flags); + } else { + spin_unlock_irqrestore(&prtd->event_lock, + flags); + rc = -EINVAL; + dev_err(rtd->dev, + "%s: prtd->event_status is NULL\n", + __func__); + break; + } + + if (cmd == SNDRV_LSM_EVENT_STATUS) { + struct snd_lsm_event_status *user = arg; + + if (user->payload_size < payload_size) { + dev_dbg(rtd->dev, + "%s: provided %d bytes isn't enough, needs %d bytes\n", + __func__, user->payload_size, + payload_size); + rc = -ENOMEM; + } else { + user->status = status; + user->payload_size = payload_size; + memcpy(user->payload, + prtd->event_status->payload, + payload_size); + } + } else { + struct snd_lsm_event_status_v3 *user_v3 = arg; + + if (user_v3->payload_size < payload_size) { + dev_dbg(rtd->dev, + "%s: provided %d bytes isn't enough, needs %d bytes\n", + __func__, user_v3->payload_size, + payload_size); + rc = -ENOMEM; + } else { + user_v3->timestamp_lsw = ts_lsw; + user_v3->timestamp_msw = ts_msw; + user_v3->status = status; + user_v3->payload_size = payload_size; + memcpy(user_v3->payload, + prtd->event_status->payload, + payload_size); + } + } + if (!rc) { + if (prtd->lsm_client->lab_enable + && !prtd->lsm_client->lab_started + && prtd->event_status->status == + LSM_VOICE_WAKEUP_STATUS_DETECTED) { + atomic_set(&prtd->read_abort, 0); + atomic_set(&prtd->buf_count, 0); + prtd->appl_cnt = 0; + prtd->dma_write = 0; + rc = msm_lsm_queue_lab_buffer(prtd, + 0); + if (rc) + dev_err(rtd->dev, + "%s: Queue buffer failed for lab rc = %d\n", + __func__, rc); + else + prtd->lsm_client->lab_started + = true; + } + } + } else if (xchg) { + dev_dbg(rtd->dev, "%s: Wait aborted\n", __func__); + rc = 0; + } + break; + } + + case SNDRV_LSM_ABORT_EVENT: + dev_dbg(rtd->dev, "%s: Aborting event status wait\n", + __func__); + atomic_set(&prtd->event_wait_stop, 1); + wake_up(&prtd->event_wait); + break; + + case SNDRV_LSM_START: + dev_dbg(rtd->dev, "%s: Starting LSM client session\n", + __func__); + if (!prtd->lsm_client->started) { + ret = q6lsm_start(prtd->lsm_client, true); + if (!ret) { + prtd->lsm_client->started = true; + dev_dbg(rtd->dev, "%s: LSM client session started\n", + __func__); + } + } + break; + + case SNDRV_LSM_STOP: { + dev_dbg(rtd->dev, + "%s: Stopping LSM client session\n", + __func__); + if (prtd->lsm_client->started) { + if (prtd->lsm_client->lab_enable) { + atomic_set(&prtd->read_abort, 1); + if (prtd->lsm_client->lab_started) { + ret = q6lsm_stop_lab(prtd->lsm_client); + if (ret) + dev_err(rtd->dev, + "%s: stop lab failed ret %d\n", + __func__, ret); + prtd->lsm_client->lab_started = false; + } + } + ret = q6lsm_stop(prtd->lsm_client, true); + if (!ret) + dev_dbg(rtd->dev, + "%s: LSM client session stopped %d\n", + __func__, ret); + prtd->lsm_client->started = false; + } + break; + } + case SNDRV_LSM_LAB_CONTROL: { + u32 enable; + + if (copy_from_user(&enable, arg, sizeof(enable))) { + dev_err(rtd->dev, "%s: %s: copy_frm_user failed\n", + __func__, "LSM_LAB_CONTROL"); + return -EFAULT; + } + + dev_dbg(rtd->dev, "%s: ioctl %s, enable = %d\n", + __func__, "SNDRV_LSM_LAB_CONTROL", enable); + if (!prtd->lsm_client->started) { + if (prtd->lsm_client->lab_enable == enable) { + dev_dbg(rtd->dev, + "%s: Lab for session %d already %s\n", + __func__, prtd->lsm_client->session, + enable ? "enabled" : "disabled"); + rc = 0; + break; + } + rc = q6lsm_lab_control(prtd->lsm_client, enable); + if (rc) { + dev_err(rtd->dev, + "%s: ioctl %s failed rc %d to %s lab for session %d\n", + __func__, "SNDRV_LAB_CONTROL", rc, + enable ? "enable" : "disable", + prtd->lsm_client->session); + } else { + rc = msm_lsm_lab_buffer_alloc(prtd, + enable ? LAB_BUFFER_ALLOC + : LAB_BUFFER_DEALLOC); + if (rc) + dev_err(rtd->dev, + "%s: msm_lsm_lab_buffer_alloc failed rc %d for %s", + __func__, rc, + enable ? "ALLOC" : "DEALLOC"); + if (!rc) + prtd->lsm_client->lab_enable = enable; + } + } else { + dev_err(rtd->dev, "%s: ioctl %s issued after start", + __func__, "SNDRV_LSM_LAB_CONTROL"); + rc = -EINVAL; + } + break; + } + case SNDRV_LSM_STOP_LAB: + dev_dbg(rtd->dev, "%s: stopping LAB\n", __func__); + if (prtd->lsm_client->lab_enable && + prtd->lsm_client->lab_started) { + atomic_set(&prtd->read_abort, 1); + rc = q6lsm_stop_lab(prtd->lsm_client); + if (rc) + dev_err(rtd->dev, + "%s: Lab stop failed for session %d rc %d\n", + __func__, + prtd->lsm_client->session, rc); + prtd->lsm_client->lab_started = false; + } + break; + + case SNDRV_LSM_SET_PORT: + dev_dbg(rtd->dev, "%s: set LSM port\n", __func__); + rc = q6lsm_set_port_connected(prtd->lsm_client); + break; + + case SNDRV_LSM_SET_FWK_MODE_CONFIG: { + u32 mode; + + if (copy_from_user(&mode, arg, sizeof(mode))) { + dev_err(rtd->dev, "%s: %s: copy_frm_user failed\n", + __func__, "LSM_SET_FWK_MODE_CONFIG"); + return -EFAULT; + } + + dev_dbg(rtd->dev, "%s: ioctl %s, enable = %d\n", + __func__, "SNDRV_LSM_SET_FWK_MODE_CONFIG", mode); + if (prtd->lsm_client->event_mode == mode) { + dev_dbg(rtd->dev, + "%s: mode for %d already set to %d\n", + __func__, prtd->lsm_client->session, mode); + rc = 0; + } else { + dev_dbg(rtd->dev, "%s: Event mode = %d\n", + __func__, mode); + rc = q6lsm_set_fwk_mode_cfg(prtd->lsm_client, mode); + if (!rc) + prtd->lsm_client->event_mode = mode; + else + dev_err(rtd->dev, + "%s: set event mode failed %d\n", + __func__, rc); + } + break; + } + + default: + dev_dbg(rtd->dev, + "%s: Falling into default snd_lib_ioctl cmd 0x%x\n", + __func__, cmd); + rc = snd_pcm_lib_ioctl(substream, cmd, arg); + break; + } + + if (!rc) + dev_dbg(rtd->dev, "%s: leave (%d)\n", + __func__, rc); + else + dev_err(rtd->dev, "%s: cmd 0x%x failed %d\n", + __func__, cmd, rc); + + return rc; +} +#ifdef CONFIG_COMPAT + +struct snd_lsm_event_status32 { + u16 status; + u16 payload_size; + u8 payload[0]; +}; + +struct snd_lsm_event_status_v3_32 { + u32 timestamp_lsw; + u32 timestamp_msw; + u16 status; + u16 payload_size; + u8 payload[0]; +}; + +struct snd_lsm_sound_model_v2_32 { + compat_uptr_t data; + compat_uptr_t confidence_level; + u32 data_size; + enum lsm_detection_mode detection_mode; + u8 num_confidence_levels; + bool detect_failure; +}; + +struct snd_lsm_detection_params_32 { + compat_uptr_t conf_level; + enum lsm_detection_mode detect_mode; + u8 num_confidence_levels; + bool detect_failure; +}; + +struct lsm_params_info_32 { + u32 module_id; + u32 param_id; + u32 param_size; + compat_uptr_t param_data; + uint32_t param_type; +}; + +struct snd_lsm_module_params_32 { + compat_uptr_t params; + u32 num_params; + u32 data_size; +}; + +enum { + SNDRV_LSM_REG_SND_MODEL_V2_32 = + _IOW('U', 0x07, struct snd_lsm_sound_model_v2_32), + SNDRV_LSM_SET_PARAMS_32 = + _IOW('U', 0x0A, struct snd_lsm_detection_params_32), + SNDRV_LSM_SET_MODULE_PARAMS_32 = + _IOW('U', 0x0B, struct snd_lsm_module_params_32), + SNDRV_LSM_EVENT_STATUS_V3_32 = + _IOW('U', 0x0F, struct snd_lsm_event_status_v3_32), +}; + +static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, + unsigned int cmd, void __user *arg) +{ + struct snd_pcm_runtime *runtime; + struct lsm_priv *prtd; + struct snd_soc_pcm_runtime *rtd; + int err = 0; + u32 size = 0; + + if (PCM_RUNTIME_CHECK(substream)) + return -ENXIO; + + if (!substream || !substream->private_data) { + pr_err("%s: Invalid %s\n", __func__, + (!substream) ? "substream" : "private_data"); + return -EINVAL; + } + runtime = substream->runtime; + rtd = substream->private_data; + prtd = runtime->private_data; + + mutex_lock(&prtd->lsm_api_lock); + + switch (cmd) { + case SNDRV_LSM_EVENT_STATUS: { + struct snd_lsm_event_status *user = NULL, userarg32; + struct snd_lsm_event_status *user32 = NULL; + + if (copy_from_user(&userarg32, arg, sizeof(userarg32))) { + dev_err(rtd->dev, "%s: err copyuser ioctl %s\n", + __func__, "SNDRV_LSM_EVENT_STATUS"); + err = -EFAULT; + goto done; + } + + if (userarg32.payload_size > + LISTEN_MAX_STATUS_PAYLOAD_SIZE) { + pr_err("%s: payload_size %d is invalid, max allowed = %d\n", + __func__, userarg32.payload_size, + LISTEN_MAX_STATUS_PAYLOAD_SIZE); + err = -EINVAL; + goto done; + } + + size = sizeof(*user) + userarg32.payload_size; + user = kzalloc(size, GFP_KERNEL); + if (!user) { + dev_err(rtd->dev, + "%s: Allocation failed event status size %d\n", + __func__, size); + err = -EFAULT; + goto done; + } else { + cmd = SNDRV_LSM_EVENT_STATUS; + user->payload_size = userarg32.payload_size; + err = msm_lsm_ioctl_shared(substream, cmd, user); + } + + /* Update size with actual payload size */ + size = sizeof(userarg32) + user->payload_size; + if (!err && !access_ok(VERIFY_WRITE, arg, size)) { + dev_err(rtd->dev, + "%s: write verify failed size %d\n", + __func__, size); + err = -EFAULT; + } + if (!err) { + user32 = kzalloc(size, GFP_KERNEL); + if (!user32) { + dev_err(rtd->dev, + "%s: Allocation event user status size %d\n", + __func__, size); + err = -EFAULT; + } else { + user32->status = user->status; + user32->payload_size = user->payload_size; + memcpy(user32->payload, + user->payload, user32->payload_size); + } + } + if (!err && (copy_to_user(arg, user32, size))) { + dev_err(rtd->dev, "%s: failed to copy payload %d", + __func__, size); + err = -EFAULT; + } + kfree(user); + kfree(user32); + if (err) + dev_err(rtd->dev, "%s: lsmevent failed %d", + __func__, err); + break; + } + + case SNDRV_LSM_EVENT_STATUS_V3_32: { + struct snd_lsm_event_status_v3_32 userarg32, *user32 = NULL; + struct snd_lsm_event_status_v3 *user = NULL; + + if (copy_from_user(&userarg32, arg, sizeof(userarg32))) { + dev_err(rtd->dev, "%s: err copyuser ioctl %s\n", + __func__, "SNDRV_LSM_EVENT_STATUS_V3_32"); + return -EFAULT; + } + + if (userarg32.payload_size > + LISTEN_MAX_STATUS_PAYLOAD_SIZE) { + pr_err("%s: payload_size %d is invalid, max allowed = %d\n", + __func__, userarg32.payload_size, + LISTEN_MAX_STATUS_PAYLOAD_SIZE); + return -EINVAL; + } + + size = sizeof(*user) + userarg32.payload_size; + user = kzalloc(size, GFP_KERNEL); + if (!user) { + dev_err(rtd->dev, + "%s: Allocation failed event status size %d\n", + __func__, size); + return -EFAULT; + } + cmd = SNDRV_LSM_EVENT_STATUS_V3; + user->payload_size = userarg32.payload_size; + err = msm_lsm_ioctl_shared(substream, cmd, user); + + /* Update size with actual payload size */ + size = sizeof(userarg32) + user->payload_size; + if (!err && !access_ok(VERIFY_WRITE, arg, size)) { + dev_err(rtd->dev, + "%s: write verify failed size %d\n", + __func__, size); + err = -EFAULT; + } + if (!err) { + user32 = kzalloc(size, GFP_KERNEL); + if (!user32) { + dev_err(rtd->dev, + "%s: Allocation event user status size %d\n", + __func__, size); + err = -EFAULT; + } else { + user32->timestamp_lsw = user->timestamp_lsw; + user32->timestamp_msw = user->timestamp_msw; + user32->status = user->status; + user32->payload_size = user->payload_size; + memcpy(user32->payload, + user->payload, user32->payload_size); + } + } + if (!err && (copy_to_user(arg, user32, size))) { + dev_err(rtd->dev, "%s: failed to copy payload %d", + __func__, size); + err = -EFAULT; + } + kfree(user); + kfree(user32); + if (err) + dev_err(rtd->dev, "%s: lsmevent failed %d", + __func__, err); + break; + } + + case SNDRV_LSM_REG_SND_MODEL_V2_32: { + struct snd_lsm_sound_model_v2_32 snd_modelv232; + struct snd_lsm_sound_model_v2 snd_modelv2; + + if (prtd->lsm_client->use_topology) { + dev_err(rtd->dev, + "%s: %s: not supported if using topology\n", + __func__, "REG_SND_MODEL_V2"); + err = -EINVAL; + goto done; + } + + if (copy_from_user(&snd_modelv232, arg, + sizeof(snd_modelv232))) { + err = -EFAULT; + dev_err(rtd->dev, + "%s: copy user failed, size %zd %s\n", + __func__, + sizeof(struct snd_lsm_sound_model_v2_32), + "SNDRV_LSM_REG_SND_MODEL_V2_32"); + } else { + snd_modelv2.confidence_level = + compat_ptr(snd_modelv232.confidence_level); + snd_modelv2.data = compat_ptr(snd_modelv232.data); + snd_modelv2.data_size = snd_modelv232.data_size; + snd_modelv2.detect_failure = + snd_modelv232.detect_failure; + snd_modelv2.detection_mode = + snd_modelv232.detection_mode; + snd_modelv2.num_confidence_levels = + snd_modelv232.num_confidence_levels; + cmd = SNDRV_LSM_REG_SND_MODEL_V2; + err = msm_lsm_ioctl_shared(substream, cmd, + &snd_modelv2); + if (err) + dev_err(rtd->dev, + "%s: ioctl %s failed\n", __func__, + "SNDDRV_LSM_REG_SND_MODEL_V2_32"); + } + break; + } + + case SNDRV_LSM_SET_PARAMS_32:{ + struct snd_lsm_detection_params_32 det_params32; + struct snd_lsm_detection_params det_params; + + if (prtd->lsm_client->use_topology) { + dev_err(rtd->dev, + "%s: %s: not supported if using topology\n", + __func__, "SET_PARAMS_32"); + err = -EINVAL; + } + + if (copy_from_user(&det_params32, arg, + sizeof(det_params32))) { + err = -EFAULT; + dev_err(rtd->dev, + "%s: %s: copy_from_user failed, size = %zd\n", + __func__, "SNDRV_LSM_SET_PARAMS_32", + sizeof(det_params32)); + } else { + det_params.conf_level = + compat_ptr(det_params32.conf_level); + det_params.detect_mode = + det_params32.detect_mode; + det_params.num_confidence_levels = + det_params32.num_confidence_levels; + det_params.detect_failure = + det_params32.detect_failure; + cmd = SNDRV_LSM_SET_PARAMS; + err = msm_lsm_ioctl_shared(substream, cmd, + &det_params); + if (err) + dev_err(rtd->dev, + "%s: ioctl %s failed\n", __func__, + "SNDRV_LSM_SET_PARAMS"); + } + break; + } + + case SNDRV_LSM_SET_MODULE_PARAMS_32: { + struct snd_lsm_module_params_32 p_data_32; + struct snd_lsm_module_params p_data; + u8 *params, *params32; + size_t p_size; + struct lsm_params_info_32 *p_info_32; + struct lsm_params_info *p_info; + int i; + + if (!prtd->lsm_client->use_topology) { + dev_err(rtd->dev, + "%s: %s: not supported if not using topology\n", + __func__, "SET_MODULE_PARAMS_32"); + err = -EINVAL; + goto done; + } + + if (copy_from_user(&p_data_32, arg, + sizeof(p_data_32))) { + dev_err(rtd->dev, + "%s: %s: copy_from_user failed, size = %zd\n", + __func__, "SET_MODULE_PARAMS_32", + sizeof(p_data_32)); + err = -EFAULT; + goto done; + } + + p_data.params = compat_ptr(p_data_32.params); + p_data.num_params = p_data_32.num_params; + p_data.data_size = p_data_32.data_size; + + if (p_data.num_params > LSM_PARAMS_MAX) { + dev_err(rtd->dev, + "%s: %s: Invalid num_params %d\n", + __func__, "SET_MODULE_PARAMS_32", + p_data.num_params); + err = -EINVAL; + goto done; + } + + if (p_data.data_size != + (p_data.num_params * sizeof(struct lsm_params_info_32))) { + dev_err(rtd->dev, + "%s: %s: Invalid size %d\n", + __func__, "SET_MODULE_PARAMS_32", + p_data.data_size); + err = -EINVAL; + goto done; + } + + p_size = sizeof(struct lsm_params_info_32) * + p_data.num_params; + + params32 = kzalloc(p_size, GFP_KERNEL); + if (!params32) { + err = -ENOMEM; + goto done; + } + + p_size = sizeof(struct lsm_params_info) * p_data.num_params; + params = kzalloc(p_size, GFP_KERNEL); + if (!params) { + dev_err(rtd->dev, + "%s: no memory for params, size = %zd\n", + __func__, p_size); + kfree(params32); + err = -ENOMEM; + goto done; + } + + if (copy_from_user(params32, p_data.params, + p_data.data_size)) { + dev_err(rtd->dev, + "%s: %s: copy_from_user failed, size = %d\n", + __func__, "params32", p_data.data_size); + kfree(params32); + kfree(params); + err = -EFAULT; + goto done; + } + + p_info_32 = (struct lsm_params_info_32 *) params32; + p_info = (struct lsm_params_info *) params; + for (i = 0; i < p_data.num_params; i++) { + p_info->module_id = p_info_32->module_id; + p_info->param_id = p_info_32->param_id; + p_info->param_size = p_info_32->param_size; + p_info->param_data = compat_ptr(p_info_32->param_data); + p_info->param_type = p_info_32->param_type; + + p_info_32++; + p_info++; + } + + err = msm_lsm_process_params(substream, + &p_data, params); + if (err) + dev_err(rtd->dev, + "%s: Failed to process params, err = %d\n", + __func__, err); + kfree(params); + kfree(params32); + break; + } + case SNDRV_LSM_REG_SND_MODEL_V2: + case SNDRV_LSM_SET_PARAMS: + case SNDRV_LSM_SET_MODULE_PARAMS: + /* + * In ideal cases, the compat_ioctl should never be called + * with the above unlocked ioctl commands. Print error + * and return error if it does. + */ + dev_err(rtd->dev, + "%s: Invalid cmd for compat_ioctl\n", + __func__); + err = -EINVAL; + break; + default: + err = msm_lsm_ioctl_shared(substream, cmd, arg); + break; + } +done: + mutex_unlock(&prtd->lsm_api_lock); + return err; +} +#else +#define msm_lsm_ioctl_compat NULL +#endif + +static int msm_lsm_ioctl(struct snd_pcm_substream *substream, + unsigned int cmd, void *arg) +{ + int err = 0; + u32 size = 0; + struct snd_pcm_runtime *runtime; + struct snd_soc_pcm_runtime *rtd; + struct lsm_priv *prtd; + + if (!substream || !substream->private_data) { + pr_err("%s: Invalid %s\n", __func__, + (!substream) ? "substream" : "private_data"); + return -EINVAL; + } + runtime = substream->runtime; + prtd = runtime->private_data; + rtd = substream->private_data; + + mutex_lock(&prtd->lsm_api_lock); + switch (cmd) { + case SNDRV_LSM_REG_SND_MODEL_V2: { + struct snd_lsm_sound_model_v2 snd_model_v2; + + if (prtd->lsm_client->use_topology) { + dev_err(rtd->dev, + "%s: %s: not supported if using topology\n", + __func__, "REG_SND_MODEL_V2"); + err = -EINVAL; + goto done; + } + + if (copy_from_user(&snd_model_v2, arg, sizeof(snd_model_v2))) { + err = -EFAULT; + dev_err(rtd->dev, + "%s: copy from user failed, size %zd\n", + __func__, + sizeof(struct snd_lsm_sound_model_v2)); + } + if (!err) + err = msm_lsm_ioctl_shared(substream, cmd, + &snd_model_v2); + if (err) + dev_err(rtd->dev, + "%s REG_SND_MODEL failed err %d\n", + __func__, err); + return err; + } + break; + case SNDRV_LSM_SET_PARAMS: { + struct snd_lsm_detection_params det_params; + + if (prtd->lsm_client->use_topology) { + dev_err(rtd->dev, + "%s: %s: not supported if using topology\n", + __func__, "SET_PARAMS"); + err = -EINVAL; + goto done; + } + + pr_debug("%s: SNDRV_LSM_SET_PARAMS\n", __func__); + + if (copy_from_user(&det_params, arg, + sizeof(det_params))) { + dev_err(rtd->dev, + "%s: %s: copy_from_user failed, size %zd\n", + __func__, "SNDRV_LSM_SET_PARAMS", + sizeof(det_params)); + err = -EFAULT; + } + + if (!err) + err = msm_lsm_ioctl_shared(substream, cmd, + &det_params); + else + dev_err(rtd->dev, + "%s: LSM_SET_PARAMS failed, err %d\n", + __func__, err); + + goto done; + } + + case SNDRV_LSM_SET_MODULE_PARAMS: { + struct snd_lsm_module_params p_data; + size_t p_size; + u8 *params; + + if (!prtd->lsm_client->use_topology) { + dev_err(rtd->dev, + "%s: %s: not supported if not using topology\n", + __func__, "SET_MODULE_PARAMS"); + err = -EINVAL; + goto done; + } + + if (copy_from_user(&p_data, arg, + sizeof(p_data))) { + dev_err(rtd->dev, + "%s: %s: copy_from_user failed, size = %zd\n", + __func__, "p_data", sizeof(p_data)); + err = -EFAULT; + goto done; + } + + if (p_data.num_params > LSM_PARAMS_MAX) { + dev_err(rtd->dev, + "%s: %s: Invalid num_params %d\n", + __func__, "SET_MODULE_PARAMS", + p_data.num_params); + err = -EINVAL; + goto done; + } + + p_size = p_data.num_params * + sizeof(struct lsm_params_info); + + if (p_data.data_size != p_size) { + dev_err(rtd->dev, + "%s: %s: Invalid size %zd\n", + __func__, "SET_MODULE_PARAMS", p_size); + + err = -EFAULT; + goto done; + } + + params = kzalloc(p_size, GFP_KERNEL); + if (!params) { + err = -ENOMEM; + goto done; + } + + if (copy_from_user(params, p_data.params, + p_data.data_size)) { + dev_err(rtd->dev, + "%s: %s: copy_from_user failed, size = %d\n", + __func__, "params", p_data.data_size); + kfree(params); + err = -EFAULT; + goto done; + } + + err = msm_lsm_process_params(substream, &p_data, params); + if (err) + dev_err(rtd->dev, + "%s: %s: Failed to set params, err = %d\n", + __func__, "SET_MODULE_PARAMS", err); + kfree(params); + break; + } + + case SNDRV_LSM_EVENT_STATUS: { + struct snd_lsm_event_status *user = NULL, userarg; + + dev_dbg(rtd->dev, + "%s: SNDRV_LSM_EVENT_STATUS\n", __func__); + if (copy_from_user(&userarg, arg, sizeof(userarg))) { + dev_err(rtd->dev, + "%s: err copyuser event_status\n", + __func__); + err = -EFAULT; + goto done; + } + + if (userarg.payload_size > + LISTEN_MAX_STATUS_PAYLOAD_SIZE) { + pr_err("%s: payload_size %d is invalid, max allowed = %d\n", + __func__, userarg.payload_size, + LISTEN_MAX_STATUS_PAYLOAD_SIZE); + err = -EINVAL; + goto done; + } + + size = sizeof(struct snd_lsm_event_status) + + userarg.payload_size; + user = kzalloc(size, GFP_KERNEL); + if (!user) { + dev_err(rtd->dev, + "%s: Allocation failed event status size %d\n", + __func__, size); + err = -EFAULT; + goto done; + } + user->payload_size = userarg.payload_size; + err = msm_lsm_ioctl_shared(substream, cmd, user); + + /* Update size with actual payload size */ + size = sizeof(*user) + user->payload_size; + if (!err && !access_ok(VERIFY_WRITE, arg, size)) { + dev_err(rtd->dev, + "%s: write verify failed size %d\n", + __func__, size); + err = -EFAULT; + } + if (!err && (copy_to_user(arg, user, size))) { + dev_err(rtd->dev, + "%s: failed to copy payload %d", + __func__, size); + err = -EFAULT; + } + kfree(user); + if (err) + dev_err(rtd->dev, + "%s: lsmevent failed %d", __func__, err); + goto done; + } + + case SNDRV_LSM_EVENT_STATUS_V3: { + struct snd_lsm_event_status_v3 *user = NULL; + struct snd_lsm_event_status_v3 userarg; + + dev_dbg(rtd->dev, + "%s: SNDRV_LSM_EVENT_STATUS_V3\n", __func__); + if (!arg) { + dev_err(rtd->dev, + "%s: Invalid params event_status_v3\n", + __func__); + return -EINVAL; + } + if (copy_from_user(&userarg, arg, sizeof(userarg))) { + dev_err(rtd->dev, + "%s: err copyuser event_status_v3\n", + __func__); + return -EFAULT; + } + + if (userarg.payload_size > + LISTEN_MAX_STATUS_PAYLOAD_SIZE) { + pr_err("%s: payload_size %d is invalid, max allowed = %d\n", + __func__, userarg.payload_size, + LISTEN_MAX_STATUS_PAYLOAD_SIZE); + return -EINVAL; + } + + size = sizeof(struct snd_lsm_event_status_v3) + + userarg.payload_size; + user = kzalloc(size, GFP_KERNEL); + if (!user) { + dev_err(rtd->dev, + "%s: Allocation failed event status size %d\n", + __func__, size); + return -EFAULT; + } + user->payload_size = userarg.payload_size; + err = msm_lsm_ioctl_shared(substream, cmd, user); + + /* Update size with actual payload size */ + size = sizeof(*user) + user->payload_size; + if (!err && !access_ok(VERIFY_WRITE, arg, size)) { + dev_err(rtd->dev, + "%s: write verify failed size %d\n", + __func__, size); + err = -EFAULT; + } + if (!err && (copy_to_user(arg, user, size))) { + dev_err(rtd->dev, + "%s: failed to copy payload %d", + __func__, size); + err = -EFAULT; + } + kfree(user); + if (err) + dev_err(rtd->dev, + "%s: lsm_event_v3 failed %d", __func__, err); + break; + } + + default: + err = msm_lsm_ioctl_shared(substream, cmd, arg); + break; + } +done: + mutex_unlock(&prtd->lsm_api_lock); + return err; +} + +static int msm_lsm_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd; + int ret = 0; + + pr_debug("%s\n", __func__); + prtd = kzalloc(sizeof(struct lsm_priv), GFP_KERNEL); + if (!prtd) { + pr_err("%s: Failed to allocate memory for lsm_priv\n", + __func__); + return -ENOMEM; + } + mutex_init(&prtd->lsm_api_lock); + spin_lock_init(&prtd->event_lock); + init_waitqueue_head(&prtd->event_wait); + init_waitqueue_head(&prtd->period_wait); + prtd->substream = substream; + runtime->private_data = prtd; + runtime->hw = msm_pcm_hardware_capture; + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_sample_rates); + if (ret < 0) + pr_info("%s: snd_pcm_hw_constraint_list failed ret %d\n", + __func__, ret); + /* Ensure that buffer size is a multiple of period size */ + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) + pr_info("%s: snd_pcm_hw_constraint_integer failed ret %d\n", + __func__, ret); + + ret = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, + CAPTURE_MIN_NUM_PERIODS * CAPTURE_MIN_PERIOD_SIZE, + CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE); + if (ret < 0) + pr_info("%s: constraint for buffer bytes min max ret = %d\n", + __func__, ret); + ret = snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); + if (ret < 0) { + pr_info("%s: constraint for period bytes step ret = %d\n", + __func__, ret); + } + ret = snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); + if (ret < 0) + pr_info("%s: constraint for buffer bytes step ret = %d\n", + __func__, ret); + prtd->lsm_client = q6lsm_client_alloc( + (lsm_app_cb)lsm_event_handler, prtd); + if (!prtd->lsm_client) { + pr_err("%s: Could not allocate memory\n", __func__); + kfree(prtd); + runtime->private_data = NULL; + return -ENOMEM; + } + prtd->lsm_client->opened = false; + prtd->lsm_client->session_state = IDLE; + prtd->lsm_client->poll_enable = true; + prtd->lsm_client->perf_mode = 0; + prtd->lsm_client->event_mode = LSM_EVENT_NON_TIME_STAMP_MODE; + + return 0; +} + +static int msm_lsm_prepare(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + + if (!substream->private_data) { + pr_err("%s: Invalid private_data", __func__); + return -EINVAL; + } + + rtd = prtd->substream->private_data; + + if (!prtd->lsm_client) { + dev_err(rtd->dev, + "%s: LSM client data ptr is NULL\n", __func__); + return -EINVAL; + } + + if (q6lsm_set_media_fmt_params(prtd->lsm_client)) + dev_dbg(rtd->dev, + "%s: failed to set lsm media fmt params\n", __func__); + + if (prtd->lsm_client->session_state == IDLE) { + ret = msm_pcm_routing_reg_phy_compr_stream( + rtd->dai_link->id, + prtd->lsm_client->perf_mode, + prtd->lsm_client->session, + SNDRV_PCM_STREAM_CAPTURE, + LISTEN); + if (ret) { + dev_err(rtd->dev, + "%s: register phy compr stream failed %d\n", + __func__, ret); + return ret; + } + } + + prtd->lsm_client->session_state = RUNNING; + prtd->lsm_client->started = false; + runtime->private_data = prtd; + return ret; +} + +static int msm_lsm_close(struct snd_pcm_substream *substream) +{ + unsigned long flags; + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + + if (!substream->private_data) { + pr_err("%s: Invalid private_data", __func__); + return -EINVAL; + } + if (!prtd || !prtd->lsm_client) { + pr_err("%s: No LSM session active\n", __func__); + return -EINVAL; + } + rtd = substream->private_data; + + dev_dbg(rtd->dev, "%s\n", __func__); + if (prtd->lsm_client->started) { + ret = q6lsm_stop(prtd->lsm_client, true); + if (ret) + dev_err(rtd->dev, + "%s: session stop failed, err = %d\n", + __func__, ret); + else + dev_dbg(rtd->dev, + "%s: LSM client session stopped %d\n", + __func__, ret); + + /* + * Go Ahead and try de-register sound model, + * even if stop failed + */ + prtd->lsm_client->started = false; + + ret = q6lsm_deregister_sound_model(prtd->lsm_client); + if (ret) + dev_err(rtd->dev, + "%s: dereg_snd_model failed, err = %d\n", + __func__, ret); + else + dev_dbg(rtd->dev, "%s: dereg_snd_model successful\n", + __func__); + } + + msm_pcm_routing_dereg_phy_stream(rtd->dai_link->id, + SNDRV_PCM_STREAM_CAPTURE); + + if (prtd->lsm_client->opened) { + q6lsm_close(prtd->lsm_client); + prtd->lsm_client->opened = false; + } + q6lsm_client_free(prtd->lsm_client); + + spin_lock_irqsave(&prtd->event_lock, flags); + kfree(prtd->event_status); + prtd->event_status = NULL; + spin_unlock_irqrestore(&prtd->event_lock, flags); + mutex_destroy(&prtd->lsm_api_lock); + kfree(prtd); + runtime->private_data = NULL; + + return 0; +} + +static int msm_lsm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct lsm_hw_params *hw_params = NULL; + struct snd_soc_pcm_runtime *rtd; + + if (!substream->private_data) { + pr_err("%s: Invalid private_data", __func__); + return -EINVAL; + } + rtd = substream->private_data; + + if (!prtd || !params) { + dev_err(rtd->dev, + "%s: invalid params prtd %pK params %pK", + __func__, prtd, params); + return -EINVAL; + } + hw_params = &prtd->lsm_client->hw_params; + hw_params->num_chs = params_channels(params); + hw_params->period_count = params_periods(params); + hw_params->sample_rate = params_rate(params); + if (((hw_params->sample_rate != 16000) && + (hw_params->sample_rate != 48000)) || + (hw_params->period_count == 0)) { + dev_err(rtd->dev, + "%s: Invalid Params sample rate %d period count %d\n", + __func__, hw_params->sample_rate, + hw_params->period_count); + return -EINVAL; + } + + if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE) { + hw_params->sample_size = 16; + } else if (params_format(params) == SNDRV_PCM_FORMAT_S24_LE) { + hw_params->sample_size = 24; + } else { + dev_err(rtd->dev, "%s: Invalid Format 0x%x\n", + __func__, params_format(params)); + return -EINVAL; + } + + hw_params->buf_sz = params_buffer_bytes(params) / + hw_params->period_count; + dev_dbg(rtd->dev, + "%s: channels %d sample rate %d sample size %d buffer size %d period count %d\n", + __func__, hw_params->num_chs, hw_params->sample_rate, + hw_params->sample_size, hw_params->buf_sz, + hw_params->period_count); + return 0; +} + +static snd_pcm_uframes_t msm_lsm_pcm_pointer( + struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd; + + if (!substream->private_data) { + pr_err("%s: Invalid private_data", __func__); + return -EINVAL; + } + rtd = substream->private_data; + + if (!prtd) { + dev_err(rtd->dev, + "%s: Invalid param %pK\n", __func__, prtd); + return 0; + } + + if (prtd->dma_write >= snd_pcm_lib_buffer_bytes(substream)) + prtd->dma_write = 0; + dev_dbg(rtd->dev, + "%s: dma post = %d\n", __func__, prtd->dma_write); + return bytes_to_frames(runtime, prtd->dma_write); +} + +static int msm_lsm_pcm_copy(struct snd_pcm_substream *substream, int ch, + snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + char *pcm_buf = NULL; + int fbytes = 0, rc = 0; + struct snd_soc_pcm_runtime *rtd; + + if (!substream->private_data) { + pr_err("%s: Invalid private_data", __func__); + return -EINVAL; + } + rtd = substream->private_data; + + if (!prtd) { + dev_err(rtd->dev, + "%s: Invalid param %pK\n", __func__, prtd); + return -EINVAL; + } + + fbytes = frames_to_bytes(runtime, frames); + if (runtime->status->state == SNDRV_PCM_STATE_XRUN || + runtime->status->state == SNDRV_PCM_STATE_PREPARED) { + dev_err(rtd->dev, + "%s: runtime state incorrect %d", __func__, + runtime->status->state); + return 0; + } + rc = wait_event_timeout(prtd->period_wait, + (atomic_read(&prtd->buf_count) | + atomic_read(&prtd->read_abort)), (2 * HZ)); + if (!rc) { + dev_err(rtd->dev, + "%s: timeout for read retry\n", __func__); + return -EAGAIN; + } + if (atomic_read(&prtd->read_abort)) { + dev_err(rtd->dev, + "%s: Read abort received\n", __func__); + return -EIO; + } + prtd->appl_cnt = prtd->appl_cnt % + prtd->lsm_client->hw_params.period_count; + pcm_buf = prtd->lsm_client->lab_buffer[prtd->appl_cnt].data; + dev_dbg(rtd->dev, + "%s: copy the pcm data size %d\n", + __func__, fbytes); + if (pcm_buf) { + if (copy_to_user(buf, pcm_buf, fbytes)) { + dev_err(rtd->dev, + "%s: failed to copy bytes %d\n", + __func__, fbytes); + return -EINVAL; + } + } else { + dev_err(rtd->dev, + "%s: Invalid pcm buffer\n", __func__); + return -EINVAL; + } + prtd->appl_cnt = (prtd->appl_cnt + 1) % + prtd->lsm_client->hw_params.period_count; + atomic_dec(&prtd->buf_count); + return 0; +} + +static int msm_lsm_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = ucontrol->value.integer.value[3]; + struct msm_pcm_stream_app_type_cfg cfg_data = {0}; + int ret = 0; + + cfg_data.app_type = ucontrol->value.integer.value[0]; + cfg_data.acdb_dev_id = ucontrol->value.integer.value[1]; + cfg_data.sample_rate = ucontrol->value.integer.value[2]; + + pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, &cfg_data); + if (ret < 0) + pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n", + __func__, ret); + + return 0; +} + +static int msm_lsm_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = 0; + struct msm_pcm_stream_app_type_cfg cfg_data = {0}; + int ret = 0; + + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + &be_id, &cfg_data); + if (ret < 0) { + pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n", + __func__, ret); + goto done; + } + + ucontrol->value.integer.value[0] = cfg_data.app_type; + ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id; + ucontrol->value.integer.value[2] = cfg_data.sample_rate; + ucontrol->value.integer.value[3] = be_id; + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); +done: + return ret; +} + +static int msm_lsm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm *pcm = rtd->pcm; + struct snd_pcm_usr *app_type_info; + struct snd_kcontrol *kctl; + const char *mixer_ctl_name = "Listen Stream"; + const char *deviceNo = "NN"; + const char *suffix = "App Type Cfg"; + int ctl_len, ret = 0; + + ctl_len = strlen(mixer_ctl_name) + 1 + + strlen(deviceNo) + 1 + strlen(suffix) + 1; + pr_debug("%s: Listen app type cntrl add\n", __func__); + ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE, + NULL, 1, ctl_len, rtd->dai_link->id, + &app_type_info); + if (ret < 0) { + pr_err("%s: Listen app type cntrl add failed: %d\n", + __func__, ret); + return ret; + } + kctl = app_type_info->kctl; + snprintf(kctl->id.name, ctl_len, "%s %d %s", + mixer_ctl_name, rtd->pcm->device, suffix); + kctl->put = msm_lsm_app_type_cfg_ctl_put; + kctl->get = msm_lsm_app_type_cfg_ctl_get; + return 0; +} + +static int msm_lsm_add_controls(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + + ret = msm_lsm_add_app_type_controls(rtd); + if (ret) + pr_err("%s, add app type controls failed:%d\n", __func__, ret); + + return ret; +} + +static const struct snd_pcm_ops msm_lsm_ops = { + .open = msm_lsm_open, + .close = msm_lsm_close, + .ioctl = msm_lsm_ioctl, + .prepare = msm_lsm_prepare, + .compat_ioctl = msm_lsm_ioctl_compat, + .hw_params = msm_lsm_hw_params, + .copy = msm_lsm_pcm_copy, + .pointer = msm_lsm_pcm_pointer, +}; + +static int msm_asoc_lsm_new(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_card *card = rtd->card->snd_card; + int ret = 0; + + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); + + ret = msm_lsm_add_controls(rtd); + if (ret) + pr_err("%s, kctl add failed:%d\n", __func__, ret); + + return ret; +} + +static int msm_asoc_lsm_probe(struct snd_soc_platform *platform) +{ + pr_debug("enter %s\n", __func__); + + return 0; +} + +static struct snd_soc_platform_driver msm_soc_platform = { + .ops = &msm_lsm_ops, + .pcm_new = msm_asoc_lsm_new, + .probe = msm_asoc_lsm_probe, +}; + +static int msm_lsm_probe(struct platform_device *pdev) +{ + + return snd_soc_register_platform(&pdev->dev, &msm_soc_platform); +} + +static int msm_lsm_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + + return 0; +} + +static const struct of_device_id msm_lsm_client_dt_match[] = { + {.compatible = "qcom,msm-lsm-client" }, + { } +}; + +static struct platform_driver msm_lsm_driver = { + .driver = { + .name = "msm-lsm-client", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(msm_lsm_client_dt_match), + }, + .probe = msm_lsm_probe, + .remove = msm_lsm_remove, +}; + +static int __init msm_soc_platform_init(void) +{ + return platform_driver_register(&msm_lsm_driver); +} +module_init(msm_soc_platform_init); + +static void __exit msm_soc_platform_exit(void) +{ + platform_driver_unregister(&msm_lsm_driver); +} +module_exit(msm_soc_platform_exit); + +MODULE_DESCRIPTION("LSM client platform driver"); +MODULE_DEVICE_TABLE(of, msm_lsm_client_dt_match); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c new file mode 100644 index 000000000000..ab9b3107665f --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c @@ -0,0 +1,922 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm-pcm-afe-v2.h" + +#define MIN_PLAYBACK_PERIOD_SIZE (128 * 2) +#define MAX_PLAYBACK_PERIOD_SIZE (128 * 2 * 2 * 6) +#define MIN_PLAYBACK_NUM_PERIODS (4) +#define MAX_PLAYBACK_NUM_PERIODS (384) + +#define MIN_CAPTURE_PERIOD_SIZE (128 * 2) +#define MAX_CAPTURE_PERIOD_SIZE (192 * 2 * 2 * 8 * 4) +#define MIN_CAPTURE_NUM_PERIODS (4) +#define MAX_CAPTURE_NUM_PERIODS (384) + +static struct snd_pcm_hardware msm_afe_hardware_playback = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED), + .formats = SNDRV_PCM_FMTBIT_S16_LE| + SNDRV_PCM_FMTBIT_S24_LE, + .rates = (SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 6, + .buffer_bytes_max = MAX_PLAYBACK_PERIOD_SIZE * + MAX_PLAYBACK_NUM_PERIODS, + .period_bytes_min = MIN_PLAYBACK_PERIOD_SIZE, + .period_bytes_max = MAX_PLAYBACK_PERIOD_SIZE, + .periods_min = MIN_PLAYBACK_NUM_PERIODS, + .periods_max = MAX_PLAYBACK_NUM_PERIODS, + .fifo_size = 0, +}; + +static struct snd_pcm_hardware msm_afe_hardware_capture = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED), + .formats = SNDRV_PCM_FMTBIT_S16_LE| + SNDRV_PCM_FMTBIT_S24_LE, + .rates = (SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000), + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 6, + .buffer_bytes_max = MAX_CAPTURE_PERIOD_SIZE * + MAX_CAPTURE_NUM_PERIODS, + .period_bytes_min = MIN_CAPTURE_PERIOD_SIZE, + .period_bytes_max = MAX_CAPTURE_PERIOD_SIZE, + .periods_min = MIN_CAPTURE_NUM_PERIODS, + .periods_max = MAX_CAPTURE_NUM_PERIODS, + .fifo_size = 0, +}; + + +static enum hrtimer_restart afe_hrtimer_callback(struct hrtimer *hrt); +static enum hrtimer_restart afe_hrtimer_rec_callback(struct hrtimer *hrt); + +static enum hrtimer_restart afe_hrtimer_callback(struct hrtimer *hrt) +{ + struct pcm_afe_info *prtd = + container_of(hrt, struct pcm_afe_info, hrt); + struct snd_pcm_substream *substream = prtd->substream; + struct snd_pcm_runtime *runtime = substream->runtime; + u32 mem_map_handle = 0; + + mem_map_handle = afe_req_mmap_handle(prtd->audio_client); + if (!mem_map_handle) + pr_err("%s: mem_map_handle is NULL\n", __func__); + + if (prtd->start) { + pr_debug("sending frame to DSP: poll_time: %d\n", + prtd->poll_time); + if (prtd->dsp_cnt == runtime->periods) + prtd->dsp_cnt = 0; + pr_debug("%s: mem_map_handle 0x%x\n", __func__, mem_map_handle); + afe_rt_proxy_port_write( + (prtd->dma_addr + + (prtd->dsp_cnt * + snd_pcm_lib_period_bytes(prtd->substream))), mem_map_handle, + snd_pcm_lib_period_bytes(prtd->substream)); + prtd->dsp_cnt++; + hrtimer_forward_now(hrt, ns_to_ktime(prtd->poll_time + * 1000)); + + return HRTIMER_RESTART; + } else + return HRTIMER_NORESTART; +} +static enum hrtimer_restart afe_hrtimer_rec_callback(struct hrtimer *hrt) +{ + struct pcm_afe_info *prtd = + container_of(hrt, struct pcm_afe_info, hrt); + struct snd_pcm_substream *substream = prtd->substream; + struct snd_pcm_runtime *runtime = substream->runtime; + u32 mem_map_handle = 0; + int ret; + + mem_map_handle = afe_req_mmap_handle(prtd->audio_client); + if (!mem_map_handle) + pr_err("%s: mem_map_handle is NULL\n", __func__); + + if (prtd->start) { + if (prtd->dsp_cnt == runtime->periods) + prtd->dsp_cnt = 0; + pr_debug("%s: mem_map_handle 0x%x\n", __func__, mem_map_handle); + ret = afe_rt_proxy_port_read( + (prtd->dma_addr + (prtd->dsp_cnt + * snd_pcm_lib_period_bytes(prtd->substream))), mem_map_handle, + snd_pcm_lib_period_bytes(prtd->substream)); + if (ret < 0) { + pr_err("%s: AFE port read fails: %d\n", __func__, ret); + prtd->start = 0; + return HRTIMER_NORESTART; + } + prtd->dsp_cnt++; + pr_debug("sending frame rec to DSP: poll_time: %d\n", + prtd->poll_time); + hrtimer_forward_now(hrt, ns_to_ktime(prtd->poll_time + * 1000)); + + return HRTIMER_RESTART; + } else + return HRTIMER_NORESTART; +} +static void pcm_afe_process_tx_pkt(uint32_t opcode, + uint32_t token, uint32_t *payload, + void *priv) +{ + struct pcm_afe_info *prtd = priv; + unsigned long dsp_flags; + struct snd_pcm_substream *substream = NULL; + struct snd_pcm_runtime *runtime = NULL; + uint16_t event; + uint64_t period_bytes; + uint64_t bytes_one_sec; + + if (prtd == NULL) + return; + substream = prtd->substream; + runtime = substream->runtime; + pr_debug("%s\n", __func__); + spin_lock_irqsave(&prtd->dsp_lock, dsp_flags); + switch (opcode) { + case AFE_EVENT_RT_PROXY_PORT_STATUS: { + event = (uint16_t)((0xFFFF0000 & payload[0]) >> 0x10); + switch (event) { + case AFE_EVENT_RTPORT_START: { + prtd->dsp_cnt = 0; + /* Calculate poll time. + * Split steps to avoid overflow. + * Poll time-time corresponding to one period + * in bytes. + * (Samplerate * channelcount * format) = + * bytes in 1 sec. + * Poll time = + * (period bytes / bytes in one sec) * + * 1000000 micro seconds. + * Multiplication by 1000000 is done in two + * steps to keep the accuracy of poll time. + */ + if (prtd->mmap_flag) { + period_bytes = ((uint64_t)( + (snd_pcm_lib_period_bytes( + prtd->substream)) * + 1000)); + bytes_one_sec = (runtime->rate + * runtime->channels * 2); + bytes_one_sec = + div_u64(bytes_one_sec, 1000); + prtd->poll_time = + div_u64(period_bytes, + bytes_one_sec); + pr_debug("prtd->poll_time: %d", + prtd->poll_time); + } + break; + } + case AFE_EVENT_RTPORT_STOP: + pr_debug("%s: event!=0\n", __func__); + prtd->start = 0; + snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); + break; + case AFE_EVENT_RTPORT_LOW_WM: + pr_debug("%s: Underrun\n", __func__); + break; + case AFE_EVENT_RTPORT_HI_WM: + pr_debug("%s: Overrun\n", __func__); + break; + default: + break; + } + break; + } + case APR_BASIC_RSP_RESULT: { + switch (payload[0]) { + case AFE_PORT_DATA_CMD_RT_PROXY_PORT_WRITE_V2: + pr_debug("write done\n"); + prtd->pcm_irq_pos += snd_pcm_lib_period_bytes + (prtd->substream); + snd_pcm_period_elapsed(prtd->substream); + break; + default: + break; + } + break; + } + case RESET_EVENTS: + prtd->pcm_irq_pos += snd_pcm_lib_period_bytes + (prtd->substream); + prtd->reset_event = true; + snd_pcm_period_elapsed(prtd->substream); + break; + default: + break; + } + spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags); +} + +static void pcm_afe_process_rx_pkt(uint32_t opcode, + uint32_t token, uint32_t *payload, + void *priv) +{ + struct pcm_afe_info *prtd = priv; + unsigned long dsp_flags; + struct snd_pcm_substream *substream = NULL; + struct snd_pcm_runtime *runtime = NULL; + uint16_t event; + uint64_t period_bytes; + uint64_t bytes_one_sec; + uint32_t mem_map_handle = 0; + + if (prtd == NULL) + return; + substream = prtd->substream; + runtime = substream->runtime; + pr_debug("%s\n", __func__); + spin_lock_irqsave(&prtd->dsp_lock, dsp_flags); + switch (opcode) { + case AFE_EVENT_RT_PROXY_PORT_STATUS: { + event = (uint16_t)((0xFFFF0000 & payload[0]) >> 0x10); + switch (event) { + case AFE_EVENT_RTPORT_START: { + prtd->dsp_cnt = 0; + /* Calculate poll time. Split steps to avoid overflow. + * Poll time-time corresponding to one period in bytes. + * (Samplerate * channelcount * format)=bytes in 1 sec. + * Poll time = (period bytes / bytes in one sec) * + * 1000000 micro seconds. + * Multiplication by 1000000 is done in two steps to + * keep the accuracy of poll time. + */ + if (prtd->mmap_flag) { + period_bytes = ((uint64_t)( + (snd_pcm_lib_period_bytes( + prtd->substream)) * 1000)); + bytes_one_sec = (runtime->rate * + runtime->channels * 2); + bytes_one_sec = div_u64(bytes_one_sec, 1000); + prtd->poll_time = + div_u64(period_bytes, bytes_one_sec); + pr_debug("prtd->poll_time : %d\n", + prtd->poll_time); + } else { + mem_map_handle = + afe_req_mmap_handle(prtd->audio_client); + if (!mem_map_handle) + pr_err("%s:mem_map_handle is NULL\n", + __func__); + /* Do initial read to start transfer */ + afe_rt_proxy_port_read((prtd->dma_addr + + (prtd->dsp_cnt * + snd_pcm_lib_period_bytes( + prtd->substream))), + mem_map_handle, + snd_pcm_lib_period_bytes( + prtd->substream)); + prtd->dsp_cnt++; + } + break; + } + case AFE_EVENT_RTPORT_STOP: + pr_debug("%s: event!=0\n", __func__); + prtd->start = 0; + snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); + break; + case AFE_EVENT_RTPORT_LOW_WM: + pr_debug("%s: Underrun\n", __func__); + break; + case AFE_EVENT_RTPORT_HI_WM: + pr_debug("%s: Overrun\n", __func__); + break; + default: + break; + } + break; + } + case APR_BASIC_RSP_RESULT: { + switch (payload[0]) { + case AFE_PORT_DATA_CMD_RT_PROXY_PORT_READ_V2: + pr_debug("%s :Read done\n", __func__); + prtd->pcm_irq_pos += snd_pcm_lib_period_bytes + (prtd->substream); + if (!prtd->mmap_flag) { + atomic_set(&prtd->rec_bytes_avail, 1); + wake_up(&prtd->read_wait); + } + snd_pcm_period_elapsed(prtd->substream); + break; + default: + break; + } + break; + } + case RESET_EVENTS: + prtd->pcm_irq_pos += snd_pcm_lib_period_bytes + (prtd->substream); + prtd->reset_event = true; + if (!prtd->mmap_flag) { + atomic_set(&prtd->rec_bytes_avail, 1); + wake_up(&prtd->read_wait); + } + snd_pcm_period_elapsed(prtd->substream); + break; + default: + break; + } + spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags); +} + +static int msm_afe_playback_prepare(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct pcm_afe_info *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *dai = rtd->cpu_dai; + int ret = 0; + + pr_debug("%s: sample_rate=%d\n", __func__, runtime->rate); + + pr_debug("%s: dai->id =%x\n", __func__, dai->id); + ret = afe_register_get_events(dai->id, + pcm_afe_process_tx_pkt, prtd); + if (ret < 0) { + pr_err("afe-pcm:register for events failed\n"); + return ret; + } + pr_debug("%s:success\n", __func__); + prtd->prepared++; + return ret; +} + +static int msm_afe_capture_prepare(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct pcm_afe_info *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *dai = rtd->cpu_dai; + int ret = 0; + + pr_debug("%s\n", __func__); + + pr_debug("%s: dai->id =%x\n", __func__, dai->id); + ret = afe_register_get_events(dai->id, + pcm_afe_process_rx_pkt, prtd); + if (ret < 0) { + pr_err("afe-pcm:register for events failed\n"); + return ret; + } + pr_debug("%s:success\n", __func__); + prtd->prepared++; + return 0; +} + +/* Conventional and unconventional sample rate supported */ +static unsigned int supported_sample_rates[] = { + 8000, 16000, 48000 +}; + +static struct snd_pcm_hw_constraint_list constraints_sample_rates = { + .count = ARRAY_SIZE(supported_sample_rates), + .list = supported_sample_rates, + .mask = 0, +}; + +static int msm_afe_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct pcm_afe_info *prtd = NULL; + int ret = 0; + + prtd = kzalloc(sizeof(struct pcm_afe_info), GFP_KERNEL); + if (prtd == NULL) + return -ENOMEM; + pr_debug("prtd %pK\n", prtd); + + mutex_init(&prtd->lock); + spin_lock_init(&prtd->dsp_lock); + prtd->dsp_cnt = 0; + + mutex_lock(&prtd->lock); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + runtime->hw = msm_afe_hardware_playback; + else + runtime->hw = msm_afe_hardware_capture; + + prtd->substream = substream; + runtime->private_data = prtd; + prtd->audio_client = q6afe_audio_client_alloc(prtd); + if (!prtd->audio_client) { + pr_debug("%s: Could not allocate memory\n", __func__); + mutex_unlock(&prtd->lock); + kfree(prtd); + return -ENOMEM; + } + + atomic_set(&prtd->rec_bytes_avail, 0); + init_waitqueue_head(&prtd->read_wait); + + hrtimer_init(&prtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + prtd->hrt.function = afe_hrtimer_callback; + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + prtd->hrt.function = afe_hrtimer_rec_callback; + + mutex_unlock(&prtd->lock); + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_sample_rates); + if (ret < 0) + pr_err("snd_pcm_hw_constraint_list failed\n"); + /* Ensure that buffer size is a multiple of period size */ + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) + pr_err("snd_pcm_hw_constraint_integer failed\n"); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + ret = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, + MIN_CAPTURE_NUM_PERIODS * MIN_CAPTURE_PERIOD_SIZE, + MAX_CAPTURE_NUM_PERIODS * MAX_CAPTURE_PERIOD_SIZE); + + if (ret < 0) { + pr_err("constraint for buffer bytes min max ret = %d\n", + ret); + } + } + + prtd->reset_event = false; + return 0; +} + +static int msm_afe_playback_copy(struct snd_pcm_substream *substream, + int channel, snd_pcm_uframes_t hwoff, + void __user *buf, snd_pcm_uframes_t frames) +{ + int ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct pcm_afe_info *prtd = runtime->private_data; + char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); + u32 mem_map_handle = 0; + + pr_debug("%s : appl_ptr 0x%lx hw_ptr 0x%lx dest_to_copy 0x%pK\n", + __func__, + runtime->control->appl_ptr, runtime->status->hw_ptr, hwbuf); + + if (copy_from_user(hwbuf, buf, frames_to_bytes(runtime, frames))) { + pr_err("%s :Failed to copy audio from user buffer\n", + __func__); + + ret = -EFAULT; + goto fail; + } + + if (!prtd->mmap_flag) { + mem_map_handle = afe_req_mmap_handle(prtd->audio_client); + if (!mem_map_handle) { + pr_err("%s: mem_map_handle is NULL\n", __func__); + ret = -EFAULT; + goto fail; + } + + pr_debug("%s : prtd-> dma_addr 0x%lx dsp_cnt %d\n", __func__, + prtd->dma_addr, prtd->dsp_cnt); + + if (prtd->dsp_cnt == runtime->periods) + prtd->dsp_cnt = 0; + + ret = afe_rt_proxy_port_write( + (prtd->dma_addr + (prtd->dsp_cnt * + snd_pcm_lib_period_bytes(prtd->substream))), + mem_map_handle, + snd_pcm_lib_period_bytes(prtd->substream)); + + if (ret) { + pr_err("%s: AFE proxy port write failed %d\n", + __func__, ret); + goto fail; + } + prtd->dsp_cnt++; + } +fail: + return ret; +} + +static int msm_afe_capture_copy(struct snd_pcm_substream *substream, + int channel, snd_pcm_uframes_t hwoff, + void __user *buf, snd_pcm_uframes_t frames) +{ + int ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct pcm_afe_info *prtd = runtime->private_data; + char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); + u32 mem_map_handle = 0; + + if (!prtd->mmap_flag) { + mem_map_handle = afe_req_mmap_handle(prtd->audio_client); + + if (!mem_map_handle) { + pr_err("%s: mem_map_handle is NULL\n", __func__); + ret = -EFAULT; + goto fail; + } + + if (prtd->dsp_cnt == runtime->periods) + prtd->dsp_cnt = 0; + + ret = afe_rt_proxy_port_read((prtd->dma_addr + + (prtd->dsp_cnt * + snd_pcm_lib_period_bytes(prtd->substream))), + mem_map_handle, + snd_pcm_lib_period_bytes(prtd->substream)); + + if (ret) { + pr_err("%s: AFE proxy port read failed %d\n", + __func__, ret); + goto fail; + } + + prtd->dsp_cnt++; + ret = wait_event_timeout(prtd->read_wait, + atomic_read(&prtd->rec_bytes_avail), 5 * HZ); + if (ret < 0) { + pr_err("%s: wait_event_timeout failed\n", __func__); + + ret = -ETIMEDOUT; + goto fail; + } + atomic_set(&prtd->rec_bytes_avail, 0); + } + pr_debug("%s:appl_ptr 0x%lx hw_ptr 0x%lx src_to_copy 0x%pK\n", + __func__, runtime->control->appl_ptr, + runtime->status->hw_ptr, hwbuf); + + if (copy_to_user(buf, hwbuf, frames_to_bytes(runtime, frames))) { + pr_err("%s: copy to user failed\n", __func__); + + goto fail; + ret = -EFAULT; + } + +fail: + return ret; +} + +static int msm_afe_copy(struct snd_pcm_substream *substream, int channel, + snd_pcm_uframes_t hwoff, void __user *buf, + snd_pcm_uframes_t frames) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct pcm_afe_info *prtd = runtime->private_data; + + int ret = 0; + + if (prtd->reset_event) { + pr_debug("%s: reset events received from ADSP, return error\n", + __func__); + return -ENETRESET; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ret = msm_afe_playback_copy(substream, channel, hwoff, + buf, frames); + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ret = msm_afe_capture_copy(substream, channel, hwoff, + buf, frames); + return ret; +} + +static int msm_afe_close(struct snd_pcm_substream *substream) +{ + int rc = 0; + struct snd_dma_buffer *dma_buf; + struct snd_pcm_runtime *runtime; + struct pcm_afe_info *prtd; + struct snd_soc_pcm_runtime *rtd = NULL; + struct snd_soc_dai *dai = NULL; + int dir = IN; + int ret = 0; + + pr_debug("%s\n", __func__); + if (substream == NULL) { + pr_err("substream is NULL\n"); + return -EINVAL; + } + rtd = substream->private_data; + dai = rtd->cpu_dai; + runtime = substream->runtime; + prtd = runtime->private_data; + + mutex_lock(&prtd->lock); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + dir = IN; + ret = afe_unregister_get_events(dai->id); + if (ret < 0) + pr_err("AFE unregister for events failed\n"); + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + dir = OUT; + ret = afe_unregister_get_events(dai->id); + if (ret < 0) + pr_err("AFE unregister for events failed\n"); + } + if (prtd->mmap_flag) + hrtimer_cancel(&prtd->hrt); + + rc = afe_cmd_memory_unmap(afe_req_mmap_handle(prtd->audio_client)); + if (rc < 0) + pr_err("AFE memory unmap failed\n"); + + pr_debug("release all buffer\n"); + dma_buf = &substream->dma_buffer; + if (dma_buf == NULL) { + pr_debug("dma_buf is NULL\n"); + goto done; + } + + if (dma_buf->area) + dma_buf->area = NULL; + q6afe_audio_client_buf_free_contiguous(dir, prtd->audio_client); +done: + pr_debug("%s: dai->id =%x\n", __func__, dai->id); + q6afe_audio_client_free(prtd->audio_client); + mutex_unlock(&prtd->lock); + prtd->prepared--; + kfree(prtd); + runtime->private_data = NULL; + return 0; +} +static int msm_afe_prepare(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct pcm_afe_info *prtd = runtime->private_data; + + prtd->pcm_irq_pos = 0; + if (prtd->prepared) + return 0; + mutex_lock(&prtd->lock); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ret = msm_afe_playback_prepare(substream); + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ret = msm_afe_capture_prepare(substream); + mutex_unlock(&prtd->lock); + return ret; +} +static int msm_afe_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct pcm_afe_info *prtd = runtime->private_data; + struct afe_audio_client *ac = prtd->audio_client; + struct afe_audio_port_data *apd = ac->port; + struct afe_audio_buffer *ab; + int dir = -1; + + pr_debug("%s\n", __func__); + prtd->mmap_flag = 1; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dir = IN; + else + dir = OUT; + ab = &(apd[dir].buf[0]); + + return msm_audio_ion_mmap((struct audio_buffer *)ab, vma); +} +static int msm_afe_trigger(struct snd_pcm_substream *substream, int cmd) +{ + int ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct pcm_afe_info *prtd = runtime->private_data; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + pr_debug("%s: SNDRV_PCM_TRIGGER_START\n", __func__); + prtd->start = 1; + if (prtd->mmap_flag) + hrtimer_start(&prtd->hrt, ns_to_ktime(0), + HRTIMER_MODE_REL); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + pr_debug("%s: SNDRV_PCM_TRIGGER_STOP\n", __func__); + prtd->start = 0; + break; + default: + ret = -EINVAL; + break; + } + return ret; +} +static int msm_afe_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_dma_buffer *dma_buf = &substream->dma_buffer; + struct pcm_afe_info *prtd = runtime->private_data; + struct afe_audio_buffer *buf; + int dir, rc; + + pr_debug("%s:\n", __func__); + + mutex_lock(&prtd->lock); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dir = IN; + else + dir = OUT; + + rc = q6afe_audio_client_buf_alloc_contiguous(dir, + prtd->audio_client, + (params_buffer_bytes(params) / params_periods(params)), + params_periods(params)); + pr_debug("params_buffer_bytes(params) = %d\n", + (params_buffer_bytes(params))); + pr_debug("params_periods(params) = %d\n", + (params_periods(params))); + pr_debug("params_periodsize(params) = %d\n", + (params_buffer_bytes(params) / params_periods(params))); + + if (rc < 0) { + pr_err("Audio Start: Buffer Allocation failed rc = %d\n", rc); + mutex_unlock(&prtd->lock); + return -ENOMEM; + } + buf = prtd->audio_client->port[dir].buf; + + if (buf == NULL || buf[0].data == NULL) { + mutex_unlock(&prtd->lock); + return -ENOMEM; + } + + pr_debug("%s:buf = %pK\n", __func__, buf); + dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; + dma_buf->dev.dev = substream->pcm->card->dev; + dma_buf->private_data = NULL; + dma_buf->area = buf[0].data; + dma_buf->addr = buf[0].phys; + + dma_buf->bytes = params_buffer_bytes(params); + + if (!dma_buf->area) { + pr_err("%s:MSM AFE physical memory allocation failed\n", + __func__); + mutex_unlock(&prtd->lock); + return -ENOMEM; + } + + memset(dma_buf->area, 0, params_buffer_bytes(params)); + + prtd->dma_addr = (phys_addr_t) dma_buf->addr; + + mutex_unlock(&prtd->lock); + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + + rc = afe_memory_map(dma_buf->addr, dma_buf->bytes, prtd->audio_client); + if (rc < 0) + pr_err("fail to map memory to DSP\n"); + + return rc; +} +static snd_pcm_uframes_t msm_afe_pointer(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct pcm_afe_info *prtd = runtime->private_data; + + if (prtd->pcm_irq_pos >= snd_pcm_lib_buffer_bytes(substream)) + prtd->pcm_irq_pos = 0; + + if (prtd->reset_event) { + pr_debug("%s: reset events received from ADSP, return XRUN\n", + __func__); + return SNDRV_PCM_POS_XRUN; + } + + pr_debug("pcm_irq_pos = %d\n", prtd->pcm_irq_pos); + return bytes_to_frames(runtime, (prtd->pcm_irq_pos)); +} + +static const struct snd_pcm_ops msm_afe_ops = { + .open = msm_afe_open, + .copy = msm_afe_copy, + .hw_params = msm_afe_hw_params, + .trigger = msm_afe_trigger, + .close = msm_afe_close, + .prepare = msm_afe_prepare, + .mmap = msm_afe_mmap, + .pointer = msm_afe_pointer, +}; + + +static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_card *card = rtd->card->snd_card; + int ret = 0; + + pr_debug("%s\n", __func__); + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); + return ret; +} + +static int msm_afe_afe_probe(struct snd_soc_platform *platform) +{ + pr_debug("%s\n", __func__); + return 0; +} + +static struct snd_soc_platform_driver msm_soc_platform = { + .ops = &msm_afe_ops, + .pcm_new = msm_asoc_pcm_new, + .probe = msm_afe_afe_probe, +}; + +static int msm_afe_probe(struct platform_device *pdev) +{ + + pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev)); + return snd_soc_register_platform(&pdev->dev, + &msm_soc_platform); +} + +static int msm_afe_remove(struct platform_device *pdev) +{ + pr_debug("%s\n", __func__); + snd_soc_unregister_platform(&pdev->dev); + return 0; +} +static const struct of_device_id msm_pcm_afe_dt_match[] = { + {.compatible = "qcom,msm-pcm-afe"}, + {} +}; +MODULE_DEVICE_TABLE(of, msm_pcm_afe_dt_match); + +static struct platform_driver msm_afe_driver = { + .driver = { + .name = "msm-pcm-afe", + .owner = THIS_MODULE, + .of_match_table = msm_pcm_afe_dt_match, + }, + .probe = msm_afe_probe, + .remove = msm_afe_remove, +}; + +static int __init msm_soc_platform_init(void) +{ + pr_debug("%s\n", __func__); + return platform_driver_register(&msm_afe_driver); +} +module_init(msm_soc_platform_init); + +static void __exit msm_soc_platform_exit(void) +{ + pr_debug("%s\n", __func__); + platform_driver_unregister(&msm_afe_driver); +} +module_exit(msm_soc_platform_exit); + +MODULE_DESCRIPTION("AFE PCM module platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h new file mode 100644 index 000000000000..84a4c3c6c275 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h @@ -0,0 +1,49 @@ +/* Copyright (c) 2012,2015-2016 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef _MSM_PCM_AFE_H +#define _MSM_PCM_AFE_H +#include +#include + + +struct pcm_afe_info { + unsigned long dma_addr; + struct snd_pcm_substream *substream; + unsigned int pcm_irq_pos; /* IRQ position */ + struct mutex lock; + spinlock_t dsp_lock; + uint32_t samp_rate; + uint32_t channel_mode; + uint8_t start; + uint32_t dsp_cnt; + uint32_t buf_phys; + int32_t mmap_flag; + int prepared; + struct hrtimer hrt; + int poll_time; + struct afe_audio_client *audio_client; + wait_queue_head_t read_wait; + atomic_t rec_bytes_avail; + bool reset_event; +}; + + +#define MSM_EXT(xname, fp_info, fp_get, fp_put, addr) \ + {.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ + .name = xname, \ + .info = fp_info,\ + .get = fp_get, .put = fp_put, \ + .private_value = addr, \ + } + +#endif /*_MSM_PCM_AFE_H*/ diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-dtmf-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-dtmf-v2.c new file mode 100644 index 000000000000..f4e03fe2e4cf --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-pcm-dtmf-v2.c @@ -0,0 +1,596 @@ +/* Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "msm-pcm-q6-v2.h" +#include "msm-pcm-routing-v2.h" +#include "q6voice.h" + +enum { + DTMF_IN_RX, + DTMF_IN_TX, +}; + +enum format { + FORMAT_S16_LE = 2 +}; + +struct dtmf_det_info { + char session[MAX_SESSION_NAME_LEN]; + uint8_t dir; + uint16_t high_freq; + uint16_t low_freq; +}; + +struct dtmf_buf_node { + struct list_head list; + struct dtmf_det_info dtmf_det_pkt; +}; + +enum dtmf_state { + DTMF_GEN_RX_STOPPED, + DTMF_GEN_RX_STARTED, +}; + +#define DTMF_MAX_Q_LEN 10 +#define DTMF_PKT_SIZE sizeof(struct dtmf_det_info) + +struct dtmf_drv_info { + enum dtmf_state state; + struct snd_pcm_substream *capture_substream; + + struct list_head out_queue; + struct list_head free_out_queue; + + wait_queue_head_t out_wait; + + struct mutex lock; + spinlock_t dsp_lock; + + uint8_t capture_start; + uint8_t capture_instance; + + unsigned int pcm_capture_size; + unsigned int pcm_capture_count; + unsigned int pcm_capture_irq_pos; + unsigned int pcm_capture_buf_pos; +}; + +static struct snd_pcm_hardware msm_pcm_hardware = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .buffer_bytes_max = (sizeof(struct dtmf_buf_node) * DTMF_MAX_Q_LEN), + .period_bytes_min = DTMF_PKT_SIZE, + .period_bytes_max = DTMF_PKT_SIZE, + .periods_min = DTMF_MAX_Q_LEN, + .periods_max = DTMF_MAX_Q_LEN, + .fifo_size = 0, +}; + +static int msm_dtmf_rx_generate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + uint16_t low_freq = ucontrol->value.integer.value[0]; + uint16_t high_freq = ucontrol->value.integer.value[1]; + int64_t duration = ucontrol->value.integer.value[2]; + uint16_t gain = ucontrol->value.integer.value[3]; + + pr_debug("%s: low_freq=%d high_freq=%d duration=%d gain=%d\n", + __func__, low_freq, high_freq, (int)duration, gain); + afe_dtmf_generate_rx(duration, high_freq, low_freq, gain); + return 0; +} + +static int msm_dtmf_rx_generate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s:\n", __func__); + ucontrol->value.integer.value[0] = 0; + return 0; +} + +static int msm_dtmf_detect_voice_rx_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int enable = ucontrol->value.integer.value[0]; + + pr_debug("%s: enable=%d\n", __func__, enable); + voc_enable_dtmf_rx_detection(voc_get_session_id(VOICE_SESSION_NAME), + enable); + + return 0; +} + +static int msm_dtmf_detect_voice_rx_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = 0; + return 0; +} + +static int msm_dtmf_detect_volte_rx_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int enable = ucontrol->value.integer.value[0]; + + pr_debug("%s: enable=%d\n", __func__, enable); + voc_enable_dtmf_rx_detection(voc_get_session_id(VOLTE_SESSION_NAME), + enable); + + return 0; +} + +static int msm_dtmf_detect_volte_rx_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = 0; + return 0; +} + +static struct snd_kcontrol_new msm_dtmf_controls[] = { + SOC_SINGLE_MULTI_EXT("DTMF_Generate Rx Low High Duration Gain", + SND_SOC_NOPM, 0, 5000, 0, 4, + msm_dtmf_rx_generate_get, + msm_dtmf_rx_generate_put), + SOC_SINGLE_EXT("DTMF_Detect Rx Voice enable", SND_SOC_NOPM, 0, 1, 0, + msm_dtmf_detect_voice_rx_get, + msm_dtmf_detect_voice_rx_put), + SOC_SINGLE_EXT("DTMF_Detect Rx VoLTE enable", SND_SOC_NOPM, 0, 1, 0, + msm_dtmf_detect_volte_rx_get, + msm_dtmf_detect_volte_rx_put), +}; + +static int msm_pcm_dtmf_probe(struct snd_soc_platform *platform) +{ + snd_soc_add_platform_controls(platform, msm_dtmf_controls, + ARRAY_SIZE(msm_dtmf_controls)); + return 0; +} + +static void dtmf_rx_detected_cb(uint8_t *pkt, + char *session, + void *private_data) +{ + struct dtmf_buf_node *buf_node = NULL; + struct vss_istream_evt_rx_dtmf_detected *dtmf_det_pkt = + (struct vss_istream_evt_rx_dtmf_detected *)pkt; + struct dtmf_drv_info *prtd = private_data; + unsigned long dsp_flags; + + pr_debug("%s\n", __func__); + if (prtd->capture_substream == NULL) + return; + + /* Copy dtmf detected info into out_queue. */ + spin_lock_irqsave(&prtd->dsp_lock, dsp_flags); + /* discarding dtmf detection info till start is received */ + if (!list_empty(&prtd->free_out_queue) && prtd->capture_start) { + buf_node = list_first_entry(&prtd->free_out_queue, + struct dtmf_buf_node, list); + list_del(&buf_node->list); + buf_node->dtmf_det_pkt.high_freq = dtmf_det_pkt->high_freq; + buf_node->dtmf_det_pkt.low_freq = dtmf_det_pkt->low_freq; + if (session != NULL) + strlcpy(buf_node->dtmf_det_pkt.session, + session, MAX_SESSION_NAME_LEN); + + buf_node->dtmf_det_pkt.dir = DTMF_IN_RX; + pr_debug("high =%d, low=%d session=%s\n", + buf_node->dtmf_det_pkt.high_freq, + buf_node->dtmf_det_pkt.low_freq, + buf_node->dtmf_det_pkt.session); + list_add_tail(&buf_node->list, &prtd->out_queue); + prtd->pcm_capture_irq_pos += prtd->pcm_capture_count; + spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags); + snd_pcm_period_elapsed(prtd->capture_substream); + } else { + spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags); + pr_err("DTMF detection pkt in Rx dropped, no free node available\n"); + } + + wake_up(&prtd->out_wait); +} + +static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, + int channel, snd_pcm_uframes_t hwoff, + void __user *buf, snd_pcm_uframes_t frames) +{ + int ret = 0; + int count = 0; + struct dtmf_buf_node *buf_node = NULL; + struct snd_pcm_runtime *runtime = substream->runtime; + struct dtmf_drv_info *prtd = runtime->private_data; + unsigned long dsp_flags; + + count = frames_to_bytes(runtime, frames); + + ret = wait_event_interruptible_timeout(prtd->out_wait, + (!list_empty(&prtd->out_queue)), + 1 * HZ); + + if (ret > 0) { + if (count <= DTMF_PKT_SIZE) { + spin_lock_irqsave(&prtd->dsp_lock, dsp_flags); + buf_node = list_first_entry(&prtd->out_queue, + struct dtmf_buf_node, list); + list_del(&buf_node->list); + spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags); + ret = copy_to_user(buf, + &buf_node->dtmf_det_pkt, + count); + if (ret) { + pr_err("%s: Copy to user returned %d\n", + __func__, ret); + ret = -EFAULT; + } + spin_lock_irqsave(&prtd->dsp_lock, dsp_flags); + list_add_tail(&buf_node->list, + &prtd->free_out_queue); + spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags); + + } else { + pr_err("%s: Read count %d > DTMF_PKT_SIZE\n", + __func__, count); + ret = -ENOMEM; + } + } else if (ret == 0) { + pr_err("%s: No UL data available\n", __func__); + ret = -ETIMEDOUT; + } else { + pr_err("%s: Read was interrupted\n", __func__); + ret = -ERESTARTSYS; + } + return ret; +} + +static int msm_pcm_copy(struct snd_pcm_substream *substream, int a, + snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames) +{ + int ret = 0; + + pr_debug("%s() DTMF\n", __func__); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ret = msm_pcm_capture_copy(substream, a, hwoff, buf, frames); + + return ret; +} + +static int msm_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct dtmf_drv_info *prtd = NULL; + int ret = 0; + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + prtd = kzalloc(sizeof(struct dtmf_drv_info), GFP_KERNEL); + + if (prtd == NULL) { + ret = -ENOMEM; + goto done; + } + + mutex_init(&prtd->lock); + spin_lock_init(&prtd->dsp_lock); + init_waitqueue_head(&prtd->out_wait); + INIT_LIST_HEAD(&prtd->out_queue); + INIT_LIST_HEAD(&prtd->free_out_queue); + + runtime->hw = msm_pcm_hardware; + + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) + pr_info("snd_pcm_hw_constraint_integer failed\n"); + + prtd->capture_substream = substream; + prtd->capture_instance++; + runtime->private_data = prtd; + } + +done: + return ret; +} + +static int msm_pcm_close(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct list_head *ptr = NULL; + struct list_head *next = NULL; + struct dtmf_buf_node *buf_node = NULL; + struct snd_dma_buffer *c_dma_buf; + struct snd_pcm_substream *c_substream; + struct snd_pcm_runtime *runtime = substream->runtime; + struct dtmf_drv_info *prtd = runtime->private_data; + unsigned long dsp_flags; + + pr_debug("%s() DTMF\n", __func__); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + mutex_lock(&prtd->lock); + wake_up(&prtd->out_wait); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + prtd->capture_instance--; + + if (!prtd->capture_instance) { + if (prtd->state == DTMF_GEN_RX_STARTED) { + prtd->state = DTMF_GEN_RX_STOPPED; + voc_disable_dtmf_det_on_active_sessions(); + voc_register_dtmf_rx_detection_cb(NULL, NULL); + } + /* release all buffer */ + /* release out_queue and free_out_queue */ + pr_debug("release all buffer\n"); + c_substream = prtd->capture_substream; + if (c_substream == NULL) { + pr_debug("c_substream is NULL\n"); + mutex_unlock(&prtd->lock); + return -EINVAL; + } + + c_dma_buf = &c_substream->dma_buffer; + if (c_dma_buf == NULL) { + pr_debug("c_dma_buf is NULL.\n"); + mutex_unlock(&prtd->lock); + return -EINVAL; + } + + if (c_dma_buf->area != NULL) { + spin_lock_irqsave(&prtd->dsp_lock, dsp_flags); + list_for_each_safe(ptr, next, + &prtd->out_queue) { + buf_node = list_entry(ptr, + struct dtmf_buf_node, list); + list_del(&buf_node->list); + } + + list_for_each_safe(ptr, next, + &prtd->free_out_queue) { + buf_node = list_entry(ptr, + struct dtmf_buf_node, list); + list_del(&buf_node->list); + } + + spin_unlock_irqrestore(&prtd->dsp_lock, + dsp_flags); + dma_free_coherent(c_substream->pcm->card->dev, + runtime->hw.buffer_bytes_max, + c_dma_buf->area, + c_dma_buf->addr); + c_dma_buf->area = NULL; + } + } + prtd->capture_substream = NULL; + mutex_unlock(&prtd->lock); + } + + return ret; +} + +static int msm_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct dtmf_drv_info *prtd = runtime->private_data; + struct snd_dma_buffer *dma_buf = &substream->dma_buffer; + struct dtmf_buf_node *buf_node = NULL; + int i = 0, offset = 0; + int ret = 0; + + pr_debug("%s: DTMF\n", __func__); + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + mutex_lock(&prtd->lock); + dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; + dma_buf->dev.dev = substream->pcm->card->dev; + dma_buf->private_data = NULL; + + dma_buf->area = dma_alloc_coherent(substream->pcm->card->dev, + runtime->hw.buffer_bytes_max, + &dma_buf->addr, GFP_KERNEL); + if (!dma_buf->area) { + pr_err("%s:MSM DTMF dma_alloc failed\n", __func__); + mutex_unlock(&prtd->lock); + return -ENOMEM; + } + + dma_buf->bytes = runtime->hw.buffer_bytes_max; + memset(dma_buf->area, 0, runtime->hw.buffer_bytes_max); + + for (i = 0; i < DTMF_MAX_Q_LEN; i++) { + pr_debug("node =%d\n", i); + buf_node = (void *) dma_buf->area + offset; + list_add_tail(&buf_node->list, + &prtd->free_out_queue); + offset = offset + sizeof(struct dtmf_buf_node); + } + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + mutex_unlock(&prtd->lock); + } + + return ret; +} + +static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct dtmf_drv_info *prtd = runtime->private_data; + + pr_debug("%s: DTMF\n", __func__); + prtd->pcm_capture_size = snd_pcm_lib_buffer_bytes(substream); + prtd->pcm_capture_count = snd_pcm_lib_period_bytes(substream); + prtd->pcm_capture_irq_pos = 0; + prtd->pcm_capture_buf_pos = 0; + return 0; +} + +static int msm_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct dtmf_drv_info *prtd = runtime->private_data; + + pr_debug("%s: DTMF\n", __func__); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + mutex_lock(&prtd->lock); + + msm_pcm_capture_prepare(substream); + + if (runtime->format != FORMAT_S16_LE) { + pr_err("format:%u doesn't match %d\n", + (uint32_t)runtime->format, FORMAT_S16_LE); + mutex_unlock(&prtd->lock); + return -EINVAL; + } + + if (prtd->capture_instance && + (prtd->state != DTMF_GEN_RX_STARTED)) { + voc_register_dtmf_rx_detection_cb(dtmf_rx_detected_cb, + prtd); + prtd->state = DTMF_GEN_RX_STARTED; + } + mutex_unlock(&prtd->lock); + } + + return 0; +} + +static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + int ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct dtmf_drv_info *prtd = runtime->private_data; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + pr_debug("%s: Trigger start\n", __func__); + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + prtd->capture_start = 1; + break; + case SNDRV_PCM_TRIGGER_STOP: + pr_debug("SNDRV_PCM_TRIGGER_STOP\n"); + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + prtd->capture_start = 0; + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream) +{ + snd_pcm_uframes_t ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct dtmf_drv_info *prtd = runtime->private_data; + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (prtd->pcm_capture_irq_pos >= prtd->pcm_capture_size) + prtd->pcm_capture_irq_pos = 0; + ret = bytes_to_frames(runtime, (prtd->pcm_capture_irq_pos)); + } + + return ret; +} + +static const struct snd_pcm_ops msm_pcm_ops = { + .open = msm_pcm_open, + .copy = msm_pcm_copy, + .hw_params = msm_pcm_hw_params, + .close = msm_pcm_close, + .prepare = msm_pcm_prepare, + .trigger = msm_pcm_trigger, + .pointer = msm_pcm_pointer, +}; + +static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_card *card = rtd->card->snd_card; + int ret = 0; + + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); + return ret; +} + +static struct snd_soc_platform_driver msm_soc_platform = { + .ops = &msm_pcm_ops, + .pcm_new = msm_asoc_pcm_new, + .probe = msm_pcm_dtmf_probe, +}; + +static int msm_pcm_probe(struct platform_device *pdev) +{ + pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev)); + + return snd_soc_register_platform(&pdev->dev, + &msm_soc_platform); +} + +static int msm_pcm_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_pcm_dtmf_dt_match[] = { + {.compatible = "qcom,msm-pcm-dtmf"}, + {} +}; + +MODULE_DEVICE_TABLE(of, msm_pcm_dtmf_dt_match); + + +static struct platform_driver msm_pcm_driver = { + .driver = { + .name = "msm-pcm-dtmf", + .owner = THIS_MODULE, + .of_match_table = msm_pcm_dtmf_dt_match, + }, + .probe = msm_pcm_probe, + .remove = msm_pcm_remove, +}; + +static int __init msm_soc_platform_init(void) +{ + return platform_driver_register(&msm_pcm_driver); +} +module_init(msm_soc_platform_init); + +static void __exit msm_soc_platform_exit(void) +{ + platform_driver_unregister(&msm_pcm_driver); +} +module_exit(msm_soc_platform_exit); + +MODULE_DESCRIPTION("DTMF platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c new file mode 100644 index 000000000000..2f60db993895 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c @@ -0,0 +1,1553 @@ +/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "q6voice.h" + +#define HPCM_MAX_Q_LEN 2 +#define HPCM_MIN_VOC_PKT_SIZE 320 +#define HPCM_MAX_VOC_PKT_SIZE 640 +#define VHPCM_BLOCK_SIZE 4096 +#define CACHE_ALIGNMENT_SIZE 128 +#define CACHE_ALIGNMENT_MASK 0xFFFFFF80 + +#define VOICE_TX_CAPTURE_DAI_ID "CS-VOICE HOST TX CAPTURE" +#define VOICE_TX_PLAYBACK_DAI_ID "CS-VOICE HOST TX PLAYBACK" +#define VOICE_RX_CAPTURE_DAI_ID "CS-VOICE HOST RX CAPTURE" +#define VOICE_RX_PLAYBACK_DAI_ID "CS-VOICE HOST RX PLAYBACK" + +#define VOLTE_TX_CAPTURE_DAI_ID "VOLTE HOST TX CAPTURE" +#define VOLTE_TX_PLAYBACK_DAI_ID "VOLTE HOST TX PLAYBACK" +#define VOLTE_RX_CAPTURE_DAI_ID "VOLTE HOST RX CAPTURE" +#define VOLTE_RX_PLAYBACK_DAI_ID "VOLTE HOST RX PLAYBACK" + + +#define VoMMode1_TX_CAPTURE_DAI_ID "VoiceMMode1 HOST TX CAPTURE" +#define VoMMode1_TX_PLAYBACK_DAI_ID "VoiceMMode1 HOST TX PLAYBACK" +#define VoMMode1_RX_CAPTURE_DAI_ID "VoiceMMode1 HOST RX CAPTURE" +#define VoMMode1_RX_PLAYBACK_DAI_ID "VoiceMMode1 HOST RX PLAYBACK" + +#define VoMMode2_TX_CAPTURE_DAI_ID "VoiceMMode2 HOST TX CAPTURE" +#define VoMMode2_TX_PLAYBACK_DAI_ID "VoiceMMode2 HOST TX PLAYBACK" +#define VoMMode2_RX_CAPTURE_DAI_ID "VoiceMMode2 HOST RX CAPTURE" +#define VoMMode2_RX_PLAYBACK_DAI_ID "VoiceMMode2 HOST RX PLAYBACK" + +enum { + RX = 1, + TX, +}; + +enum { + VOICE_INDEX = 0, + VOLTE_INDEX, + VOMMODE1_INDEX, + VOMMODE2_INDEX, + MAX_SESSION +}; + +enum hpcm_state { + HPCM_STOPPED = 1, + HPCM_CLOSED, + HPCM_PREPARED, + HPCM_STARTED, +}; + +struct hpcm_frame { + uint32_t len; + uint8_t voc_pkt[HPCM_MAX_VOC_PKT_SIZE]; +}; + +struct hpcm_buf_node { + struct list_head list; + struct hpcm_frame frame; +}; + +struct vocpcm_ion_buffer { + /* Physical address */ + phys_addr_t paddr; + /* Kernel virtual address */ + void *kvaddr; +}; + +struct dai_data { + enum hpcm_state state; + struct snd_pcm_substream *substream; + struct list_head filled_queue; + struct list_head free_queue; + wait_queue_head_t queue_wait; + spinlock_t dsp_lock; + uint32_t pcm_size; + uint32_t pcm_count; + /* IRQ position */ + uint32_t pcm_irq_pos; + /* Position in buffer */ + uint32_t pcm_buf_pos; + struct vocpcm_ion_buffer vocpcm_ion_buffer; +}; + +struct tap_point { + struct dai_data playback_dai_data; + struct dai_data capture_dai_data; +}; + +struct session { + struct tap_point tx_tap_point; + struct tap_point rx_tap_point; + phys_addr_t sess_paddr; + void *sess_kvaddr; + struct ion_handle *ion_handle; + struct mem_map_table tp_mem_table; +}; + +struct tappnt_mxr_data { + bool enable; + uint16_t direction; + uint16_t sample_rate; +}; + +/* Values from mixer ctl are cached in this structure */ +struct mixer_conf { + int8_t sess_indx; + struct tappnt_mxr_data rx; + struct tappnt_mxr_data tx; +}; + +struct start_cmd { + struct vss_ivpcm_tap_point tap_pnt[2]; + uint32_t no_of_tapoints; +}; + +struct hpcm_drv { + struct mutex lock; + struct session session[MAX_SESSION]; + struct mixer_conf mixer_conf; + struct ion_client *ion_client; + struct start_cmd start_cmd; +}; + +static struct hpcm_drv hpcm_drv; + +static struct snd_pcm_hardware msm_pcm_hardware = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED), + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_SPECIAL, + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .rate_min = 8000, + .rate_max = 16000, + .channels_min = 1, + .channels_max = 1, + .buffer_bytes_max = sizeof(struct hpcm_buf_node) * HPCM_MAX_Q_LEN, + .period_bytes_min = HPCM_MIN_VOC_PKT_SIZE, + .period_bytes_max = HPCM_MAX_VOC_PKT_SIZE, + .periods_min = HPCM_MAX_Q_LEN, + .periods_max = HPCM_MAX_Q_LEN, + .fifo_size = 0, +}; + +static char *hpcm_get_sess_name(int sess_indx) +{ + char *sess_name = NULL; + + if (sess_indx == VOICE_INDEX) + sess_name = VOICE_SESSION_NAME; + else if (sess_indx == VOLTE_INDEX) + sess_name = VOLTE_SESSION_NAME; + else if (sess_indx == VOMMODE1_INDEX) + sess_name = VOICEMMODE1_NAME; + else if (sess_indx == VOMMODE2_INDEX) + sess_name = VOICEMMODE2_NAME; + else + pr_err("%s:, Invalid sess_index\n", __func__); + + return sess_name; +} + +static void hpcm_reset_mixer_config(struct hpcm_drv *prtd) +{ + prtd->mixer_conf.sess_indx = -1; + prtd->mixer_conf.rx.enable = false; + prtd->mixer_conf.rx.direction = -1; + prtd->mixer_conf.rx.sample_rate = 0; + + prtd->mixer_conf.tx.enable = false; + prtd->mixer_conf.tx.direction = -1; + prtd->mixer_conf.tx.sample_rate = 0; +} + +/* Check for valid mixer control values */ +static bool hpcm_is_valid_config(int sess_indx, int tap_point, + uint16_t direction, uint16_t samplerate) +{ + if (sess_indx < VOICE_INDEX || sess_indx > VOMMODE2_INDEX) { + pr_err("%s: invalid sess_indx :%d\n", __func__, sess_indx); + goto error; + } + + if (samplerate != VSS_IVPCM_SAMPLING_RATE_8K && + samplerate != VSS_IVPCM_SAMPLING_RATE_16K) { + pr_err("%s: invalid sample rate :%d\n", __func__, samplerate); + goto error; + } + + if ((tap_point != RX) && (tap_point != TX)) { + pr_err("%s: invalid tappoint :%d\n", __func__, tap_point); + goto error; + } + + if ((direction != VSS_IVPCM_TAP_POINT_DIR_IN) && + (direction != VSS_IVPCM_TAP_POINT_DIR_OUT) && + (direction != VSS_IVPCM_TAP_POINT_DIR_OUT_IN)) { + pr_err("%s: invalid direction :%d\n", __func__, direction); + goto error; + } + + return true; + +error: + return false; +} + + +static struct dai_data *hpcm_get_dai_data(char *pcm_id, struct hpcm_drv *prtd) +{ + struct dai_data *dai_data = NULL; + size_t size = 0; + + if (pcm_id) { + size = strlen(pcm_id); + /* Check for Voice DAI */ + if (strnstr(pcm_id, VOICE_TX_CAPTURE_DAI_ID, size)) { + dai_data = + &prtd->session[VOICE_INDEX].tx_tap_point.capture_dai_data; + } else if (strnstr(pcm_id, VOICE_TX_PLAYBACK_DAI_ID, size)) { + dai_data = + &prtd->session[VOICE_INDEX].tx_tap_point.playback_dai_data; + } else if (strnstr(pcm_id, VOICE_RX_CAPTURE_DAI_ID, size)) { + dai_data = + &prtd->session[VOICE_INDEX].rx_tap_point.capture_dai_data; + } else if (strnstr(pcm_id, VOICE_RX_PLAYBACK_DAI_ID, size)) { + dai_data = + &prtd->session[VOICE_INDEX].rx_tap_point.playback_dai_data; + /* Check for VoLTE DAI */ + } else if (strnstr(pcm_id, VOLTE_TX_CAPTURE_DAI_ID, size)) { + dai_data = + &prtd->session[VOLTE_INDEX].tx_tap_point.capture_dai_data; + } else if (strnstr(pcm_id, VOLTE_TX_PLAYBACK_DAI_ID, size)) { + dai_data = + &prtd->session[VOLTE_INDEX].tx_tap_point.playback_dai_data; + } else if (strnstr(pcm_id, VOLTE_RX_CAPTURE_DAI_ID, size)) { + dai_data = + &prtd->session[VOLTE_INDEX].rx_tap_point.capture_dai_data; + } else if (strnstr(pcm_id, VOLTE_RX_PLAYBACK_DAI_ID, size)) { + dai_data = + &prtd->session[VOLTE_INDEX].rx_tap_point.playback_dai_data; + /* check for VoiceMMode1 DAI */ + } else if (strnstr(pcm_id, VoMMode1_TX_CAPTURE_DAI_ID, size)) { + dai_data = + &prtd->session[VOMMODE1_INDEX].tx_tap_point.capture_dai_data; + } else if (strnstr(pcm_id, VoMMode1_TX_PLAYBACK_DAI_ID, size)) { + dai_data = + &prtd->session[VOMMODE1_INDEX].tx_tap_point.playback_dai_data; + } else if (strnstr(pcm_id, VoMMode1_RX_CAPTURE_DAI_ID, size)) { + dai_data = + &prtd->session[VOMMODE1_INDEX].rx_tap_point.capture_dai_data; + } else if (strnstr(pcm_id, VoMMode1_RX_PLAYBACK_DAI_ID, size)) { + dai_data = + &prtd->session[VOMMODE1_INDEX].rx_tap_point.playback_dai_data; + /* check for VOiceMMode2 DAI */ + } else if (strnstr(pcm_id, VoMMode2_TX_CAPTURE_DAI_ID, size)) { + dai_data = + &prtd->session[VOMMODE2_INDEX].tx_tap_point.capture_dai_data; + } else if (strnstr(pcm_id, VoMMode2_TX_PLAYBACK_DAI_ID, size)) { + dai_data = + &prtd->session[VOMMODE2_INDEX].tx_tap_point.playback_dai_data; + } else if (strnstr(pcm_id, VoMMode2_RX_CAPTURE_DAI_ID, size)) { + dai_data = + &prtd->session[VOMMODE2_INDEX].rx_tap_point.capture_dai_data; + } else if (strnstr(pcm_id, VoMMode2_RX_PLAYBACK_DAI_ID, size)) { + dai_data = + &prtd->session[VOMMODE2_INDEX].rx_tap_point.playback_dai_data; + + } else { + pr_err("%s: Wrong dai id\n", __func__); + } + } + + return dai_data; +} + +static struct tap_point *hpcm_get_tappoint_data(char *pcm_id, + struct hpcm_drv *prtd) +{ + struct tap_point *tp = NULL; + size_t size = 0; + + if (pcm_id) { + size = strlen(pcm_id); + /* Check for Voice DAI */ + if (strnstr(pcm_id, VOICE_TX_CAPTURE_DAI_ID, size)) { + tp = &prtd->session[VOICE_INDEX].tx_tap_point; + } else if (strnstr(pcm_id, VOICE_TX_PLAYBACK_DAI_ID, size)) { + tp = &prtd->session[VOICE_INDEX].tx_tap_point; + } else if (strnstr(pcm_id, VOICE_RX_CAPTURE_DAI_ID, size)) { + tp = &prtd->session[VOICE_INDEX].rx_tap_point; + } else if (strnstr(pcm_id, VOICE_RX_PLAYBACK_DAI_ID, size)) { + tp = &prtd->session[VOICE_INDEX].rx_tap_point; + /* Check for VoLTE DAI */ + } else if (strnstr(pcm_id, VOLTE_TX_CAPTURE_DAI_ID, size)) { + tp = &prtd->session[VOLTE_INDEX].tx_tap_point; + } else if (strnstr(pcm_id, VOLTE_TX_PLAYBACK_DAI_ID, size)) { + tp = &prtd->session[VOLTE_INDEX].tx_tap_point; + } else if (strnstr(pcm_id, VOLTE_RX_CAPTURE_DAI_ID, size)) { + tp = &prtd->session[VOLTE_INDEX].rx_tap_point; + } else if (strnstr(pcm_id, VOLTE_RX_PLAYBACK_DAI_ID, size)) { + tp = &prtd->session[VOLTE_INDEX].rx_tap_point; + /* check for VoiceMMode1 */ + } else if (strnstr(pcm_id, VoMMode1_TX_CAPTURE_DAI_ID, size)) { + tp = &prtd->session[VOMMODE1_INDEX].tx_tap_point; + } else if (strnstr(pcm_id, VoMMode1_TX_PLAYBACK_DAI_ID, size)) { + tp = &prtd->session[VOMMODE1_INDEX].tx_tap_point; + } else if (strnstr(pcm_id, VoMMode1_RX_CAPTURE_DAI_ID, size)) { + tp = &prtd->session[VOMMODE1_INDEX].rx_tap_point; + } else if (strnstr(pcm_id, VoMMode1_RX_PLAYBACK_DAI_ID, size)) { + tp = &prtd->session[VOMMODE1_INDEX].rx_tap_point; + /* check for VoiceMMode2 */ + } else if (strnstr(pcm_id, VoMMode2_TX_CAPTURE_DAI_ID, size)) { + tp = &prtd->session[VOMMODE2_INDEX].tx_tap_point; + } else if (strnstr(pcm_id, VoMMode2_TX_PLAYBACK_DAI_ID, size)) { + tp = &prtd->session[VOMMODE2_INDEX].tx_tap_point; + } else if (strnstr(pcm_id, VoMMode2_RX_CAPTURE_DAI_ID, size)) { + tp = &prtd->session[VOMMODE2_INDEX].rx_tap_point; + } else if (strnstr(pcm_id, VoMMode2_RX_PLAYBACK_DAI_ID, size)) { + tp = &prtd->session[VOMMODE2_INDEX].rx_tap_point; + } else { + pr_err("%s: wrong dai id\n", __func__); + } + } + + return tp; +} + +static struct tappnt_mxr_data *hpcm_get_tappnt_mixer_data(char *pcm_id, + struct hpcm_drv *prtd) +{ + + if (strnstr(pcm_id, VOICE_TX_CAPTURE_DAI_ID, strlen(pcm_id)) || + strnstr(pcm_id, VOICE_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) || + strnstr(pcm_id, VOLTE_TX_CAPTURE_DAI_ID, strlen(pcm_id)) || + strnstr(pcm_id, VOLTE_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) || + strnstr(pcm_id, VoMMode1_TX_CAPTURE_DAI_ID, strlen(pcm_id)) || + strnstr(pcm_id, VoMMode1_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) || + strnstr(pcm_id, VoMMode2_TX_CAPTURE_DAI_ID, strlen(pcm_id)) || + strnstr(pcm_id, VoMMode2_TX_PLAYBACK_DAI_ID, strlen(pcm_id))) { + return &prtd->mixer_conf.tx; + } else { + return &prtd->mixer_conf.rx; + } +} + +static int get_tappnt_value(char *pcm_id) +{ + + if (strnstr(pcm_id, VOICE_TX_CAPTURE_DAI_ID, strlen(pcm_id)) || + strnstr(pcm_id, VOICE_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) || + strnstr(pcm_id, VOLTE_TX_CAPTURE_DAI_ID, strlen(pcm_id)) || + strnstr(pcm_id, VOLTE_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) || + strnstr(pcm_id, VoMMode1_TX_CAPTURE_DAI_ID, strlen(pcm_id)) || + strnstr(pcm_id, VoMMode1_TX_PLAYBACK_DAI_ID, strlen(pcm_id)) || + strnstr(pcm_id, VoMMode2_TX_CAPTURE_DAI_ID, strlen(pcm_id)) || + strnstr(pcm_id, VoMMode2_TX_PLAYBACK_DAI_ID, strlen(pcm_id))) { + return TX; + } else { + return RX; + } +} + +static bool hpcm_all_dais_are_ready(uint16_t direction, struct tap_point *tp, + enum hpcm_state state) +{ + bool dais_started = false; + + /* + * Based on the direction set per tap point in the mixer control, + * all the dais per tap point should meet the required state for the + * commands such as vpcm_map_memory/vpcm_start to be executed. + */ + switch (direction) { + case VSS_IVPCM_TAP_POINT_DIR_OUT_IN: + if ((tp->playback_dai_data.state >= state) && + (tp->capture_dai_data.state >= state)) { + dais_started = true; + } + break; + + case VSS_IVPCM_TAP_POINT_DIR_IN: + if (tp->playback_dai_data.state >= state) + dais_started = true; + break; + + case VSS_IVPCM_TAP_POINT_DIR_OUT: + if (tp->capture_dai_data.state >= state) + dais_started = true; + break; + + default: + pr_err("invalid direction\n"); + } + + return dais_started; +} + +static void hpcm_create_free_queue(struct snd_dma_buffer *dma_buf, + struct dai_data *dai_data) +{ + struct hpcm_buf_node *buf_node = NULL; + int i = 0, offset = 0; + + for (i = 0; i < HPCM_MAX_Q_LEN; i++) { + buf_node = (void *)dma_buf->area + offset; + list_add_tail(&buf_node->list, + &dai_data->free_queue); + offset = offset + sizeof(struct hpcm_buf_node); + } +} + +static void hpcm_free_allocated_mem(struct hpcm_drv *prtd) +{ + phys_addr_t paddr = 0; + struct tap_point *txtp = NULL; + struct tap_point *rxtp = NULL; + struct session *sess = NULL; + + sess = &prtd->session[prtd->mixer_conf.sess_indx]; + txtp = &sess->tx_tap_point; + rxtp = &sess->rx_tap_point; + paddr = sess->sess_paddr; + + if (paddr) { + msm_audio_ion_free(prtd->ion_client, sess->ion_handle); + prtd->ion_client = NULL; + sess->ion_handle = NULL; + msm_audio_ion_free(sess->tp_mem_table.client, + sess->tp_mem_table.handle); + sess->tp_mem_table.client = NULL; + sess->tp_mem_table.handle = NULL; + sess->sess_paddr = 0; + sess->sess_kvaddr = 0; + sess->ion_handle = 0; + prtd->ion_client = 0; + sess->tp_mem_table.client = 0; + sess->tp_mem_table.handle = 0; + + txtp->capture_dai_data.vocpcm_ion_buffer.paddr = 0; + txtp->capture_dai_data.vocpcm_ion_buffer.kvaddr = 0; + + txtp->playback_dai_data.vocpcm_ion_buffer.paddr = 0; + txtp->playback_dai_data.vocpcm_ion_buffer.kvaddr = 0; + + rxtp->capture_dai_data.vocpcm_ion_buffer.paddr = 0; + rxtp->capture_dai_data.vocpcm_ion_buffer.kvaddr = 0; + + rxtp->playback_dai_data.vocpcm_ion_buffer.paddr = 0; + rxtp->playback_dai_data.vocpcm_ion_buffer.kvaddr = 0; + } else { + pr_debug("%s, paddr = 0, nothing to free\n", __func__); + } +} + +static void hpcm_unmap_and_free_shared_memory(struct hpcm_drv *prtd) + +{ + phys_addr_t paddr = 0; + char *sess_name = hpcm_get_sess_name(prtd->mixer_conf.sess_indx); + + if (prtd->mixer_conf.sess_indx >= 0) + paddr = prtd->session[prtd->mixer_conf.sess_indx].sess_paddr; + else + paddr = 0; + + if (paddr) { + voc_send_cvp_unmap_vocpcm_memory(voc_get_session_id(sess_name)); + hpcm_free_allocated_mem(prtd); + } else { + pr_debug("%s, paddr = 0, nothing to unmap/free\n", __func__); + } +} + +static int hpcm_map_vocpcm_memory(struct hpcm_drv *prtd) +{ + int ret = 0; + char *sess_name = hpcm_get_sess_name(prtd->mixer_conf.sess_indx); + struct session *sess = NULL; + + sess = &prtd->session[prtd->mixer_conf.sess_indx]; + + ret = voc_send_cvp_map_vocpcm_memory(voc_get_session_id(sess_name), + &sess->tp_mem_table, + sess->sess_paddr, + VHPCM_BLOCK_SIZE); + + return ret; +} + +static int hpcm_allocate_shared_memory(struct hpcm_drv *prtd) +{ + int result; + int ret = 0; + size_t mem_len; + size_t len; + struct tap_point *txtp = NULL; + struct tap_point *rxtp = NULL; + struct session *sess = NULL; + + sess = &prtd->session[prtd->mixer_conf.sess_indx]; + txtp = &sess->tx_tap_point; + rxtp = &sess->rx_tap_point; + + result = msm_audio_ion_alloc("host_pcm_buffer", + &prtd->ion_client, + &sess->ion_handle, + VHPCM_BLOCK_SIZE, + &sess->sess_paddr, + &mem_len, + &sess->sess_kvaddr); + if (result) { + pr_err("%s: msm_audio_ion_alloc error, rc = %d\n", + __func__, result); + sess->sess_paddr = 0; + sess->sess_kvaddr = 0; + ret = -ENOMEM; + goto done; + } + pr_debug("%s: Host PCM memory block allocated\n", __func__); + + /* Allocate mem_map_table for tap point */ + result = msm_audio_ion_alloc("host_pcm_table", + &sess->tp_mem_table.client, + &sess->tp_mem_table.handle, + sizeof(struct vss_imemory_table_t), + &sess->tp_mem_table.phys, + &len, + &sess->tp_mem_table.data); + + if (result) { + pr_err("%s: msm_audio_ion_alloc error, rc = %d\n", + __func__, result); + msm_audio_ion_free(prtd->ion_client, sess->ion_handle); + prtd->ion_client = NULL; + sess->ion_handle = NULL; + sess->sess_paddr = 0; + sess->sess_kvaddr = 0; + ret = -ENOMEM; + goto done; + } + pr_debug("%s: Host PCM memory table allocated\n", __func__); + + memset(sess->tp_mem_table.data, 0, + sizeof(struct vss_imemory_table_t)); + + sess->tp_mem_table.size = sizeof(struct vss_imemory_table_t); + + pr_debug("%s: data %pK phys %pK\n", __func__, + sess->tp_mem_table.data, &sess->tp_mem_table.phys); + + /* Split 4096 block into four 1024 byte blocks for each dai */ + txtp->capture_dai_data.vocpcm_ion_buffer.paddr = + sess->sess_paddr; + txtp->capture_dai_data.vocpcm_ion_buffer.kvaddr = + sess->sess_kvaddr; + + txtp->playback_dai_data.vocpcm_ion_buffer.paddr = + sess->sess_paddr + VHPCM_BLOCK_SIZE/4; + txtp->playback_dai_data.vocpcm_ion_buffer.kvaddr = + sess->sess_kvaddr + VHPCM_BLOCK_SIZE/4; + + rxtp->capture_dai_data.vocpcm_ion_buffer.paddr = + sess->sess_paddr + (VHPCM_BLOCK_SIZE/4) * 2; + rxtp->capture_dai_data.vocpcm_ion_buffer.kvaddr = + sess->sess_kvaddr + (VHPCM_BLOCK_SIZE/4) * 2; + + rxtp->playback_dai_data.vocpcm_ion_buffer.paddr = + sess->sess_paddr + (VHPCM_BLOCK_SIZE/4) * 3; + rxtp->playback_dai_data.vocpcm_ion_buffer.kvaddr = + sess->sess_kvaddr + (VHPCM_BLOCK_SIZE/4) * 3; + +done: + return ret; +} + +static int hpcm_start_vocpcm(char *pcm_id, struct hpcm_drv *prtd, + struct tap_point *tp) +{ + int indx = prtd->mixer_conf.sess_indx; + uint32_t *no_of_tp = &prtd->start_cmd.no_of_tapoints; + struct vss_ivpcm_tap_point *tap_pnt = &prtd->start_cmd.tap_pnt[0]; + uint32_t no_of_tp_req = 0; + char *sess_name = hpcm_get_sess_name(indx); + + if (prtd->mixer_conf.rx.enable) + no_of_tp_req++; + if (prtd->mixer_conf.tx.enable) + no_of_tp_req++; + + if (prtd->mixer_conf.rx.enable && (get_tappnt_value(pcm_id) == RX)) { + if (hpcm_all_dais_are_ready(prtd->mixer_conf.rx.direction, + tp, HPCM_PREPARED)) { + pr_debug("%s: RX conditions met\n", __func__); + tap_pnt[*no_of_tp].tap_point = + VSS_IVPCM_TAP_POINT_RX_DEFAULT; + tap_pnt[*no_of_tp].direction = + prtd->mixer_conf.rx.direction; + tap_pnt[*no_of_tp].sampling_rate = + prtd->mixer_conf.rx.sample_rate; + (*no_of_tp)++; + } + } + + if (prtd->mixer_conf.tx.enable && (get_tappnt_value(pcm_id) == TX)) { + if (hpcm_all_dais_are_ready(prtd->mixer_conf.tx.direction, + tp, HPCM_PREPARED)) { + pr_debug("%s: TX conditions met\n", __func__); + tap_pnt[*no_of_tp].tap_point = + VSS_IVPCM_TAP_POINT_TX_DEFAULT; + tap_pnt[*no_of_tp].direction = + prtd->mixer_conf.tx.direction; + tap_pnt[*no_of_tp].sampling_rate = + prtd->mixer_conf.tx.sample_rate; + (*no_of_tp)++; + } + } + + if ((prtd->mixer_conf.tx.enable || prtd->mixer_conf.rx.enable) && + *no_of_tp == no_of_tp_req) { + voc_send_cvp_start_vocpcm(voc_get_session_id(sess_name), + tap_pnt, *no_of_tp); + /* Reset the start command so that it is not called twice */ + memset(&prtd->start_cmd, 0, sizeof(struct start_cmd)); + } else { + pr_debug("%s: required pcm handles not opened yet\n", __func__); + } + + return 0; +} + +/* Playback path*/ +static void hpcm_copy_playback_data_from_queue(struct dai_data *dai_data, + uint32_t *len) +{ + struct hpcm_buf_node *buf_node = NULL; + unsigned long dsp_flags; + + if (dai_data->substream == NULL) + return; + + spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags); + + if (!list_empty(&dai_data->filled_queue)) { + buf_node = list_first_entry(&dai_data->filled_queue, + struct hpcm_buf_node, list); + list_del(&buf_node->list); + *len = buf_node->frame.len; + memcpy((u8 *)dai_data->vocpcm_ion_buffer.kvaddr, + &buf_node->frame.voc_pkt[0], + buf_node->frame.len); + + list_add_tail(&buf_node->list, &dai_data->free_queue); + dai_data->pcm_irq_pos += dai_data->pcm_count; + spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags); + snd_pcm_period_elapsed(dai_data->substream); + } else { + *len = 0; + spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags); + pr_err("IN data not available\n"); + } + + wake_up(&dai_data->queue_wait); +} + +/* Capture path*/ +static void hpcm_copy_capture_data_to_queue(struct dai_data *dai_data, + uint32_t len) +{ + struct hpcm_buf_node *buf_node = NULL; + unsigned long dsp_flags; + + if (dai_data->substream == NULL) + return; + + /* Copy out buffer packet into free_queue */ + spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags); + + if (!list_empty(&dai_data->free_queue)) { + buf_node = list_first_entry(&dai_data->free_queue, + struct hpcm_buf_node, list); + list_del(&buf_node->list); + buf_node->frame.len = len; + memcpy(&buf_node->frame.voc_pkt[0], + (uint8_t *)dai_data->vocpcm_ion_buffer.kvaddr, + buf_node->frame.len); + list_add_tail(&buf_node->list, &dai_data->filled_queue); + dai_data->pcm_irq_pos += dai_data->pcm_count; + spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags); + snd_pcm_period_elapsed(dai_data->substream); + } else { + spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags); + pr_err("OUTPUT data dropped\n"); + } + + wake_up(&dai_data->queue_wait); +} + +void hpcm_notify_evt_processing(uint8_t *data, char *session, + void *private_data) +{ + struct hpcm_drv *prtd = (struct hpcm_drv *)private_data; + struct vss_ivpcm_evt_notify_v2_t *notify_evt = + (struct vss_ivpcm_evt_notify_v2_t *)data; + struct vss_ivpcm_evt_push_buffer_v2_t push_buff_event; + struct tap_point *tp = NULL; + int in_buf_len = 0; + struct tappnt_mxr_data *tmd = NULL; + char *sess_name = hpcm_get_sess_name(prtd->mixer_conf.sess_indx); + + /* If it's not a timetick, it's a error notification, drop the event */ + if ((notify_evt->notify_mask & VSS_IVPCM_NOTIFY_MASK_TIMETICK) == 0) { + pr_err("%s: Error notification. mask=%d\n", __func__, + notify_evt->notify_mask); + return; + } + + if (notify_evt->tap_point == VSS_IVPCM_TAP_POINT_TX_DEFAULT) { + tp = &prtd->session[prtd->mixer_conf.sess_indx].tx_tap_point; + tmd = &prtd->mixer_conf.tx; + } else if (notify_evt->tap_point == VSS_IVPCM_TAP_POINT_RX_DEFAULT) { + tp = &prtd->session[prtd->mixer_conf.sess_indx].rx_tap_point; + tmd = &prtd->mixer_conf.rx; + } + + if (tp == NULL || tmd == NULL) { + pr_err("%s: tp = %pK or tmd = %pK is null\n", __func__, + tp, tmd); + + return; + } + + if (notify_evt->notify_mask & VSS_IVPCM_NOTIFY_MASK_OUTPUT_BUFFER) { + hpcm_copy_capture_data_to_queue(&tp->capture_dai_data, + notify_evt->filled_out_size); + } + + if (notify_evt->notify_mask & VSS_IVPCM_NOTIFY_MASK_INPUT_BUFFER) { + hpcm_copy_playback_data_from_queue(&tp->playback_dai_data, + &in_buf_len); + } + + switch (tmd->direction) { + /* + * When the dir is OUT_IN, for the first notify mask, pushbuf mask + * should be set to VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER since we + * atleast need one buffer's worth data before we can send IN buffer. + * For the consecutive notify evts, the push buf mask will set for both + * VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER and + * VSS_IVPCM_PUSH_BUFFER_MASK_IN_BUFFER. + */ + case VSS_IVPCM_TAP_POINT_DIR_OUT_IN: + if (notify_evt->notify_mask == + VSS_IVPCM_NOTIFY_MASK_TIMETICK) { + push_buff_event.push_buf_mask = + VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER; + } else { + push_buff_event.push_buf_mask = + VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER | + VSS_IVPCM_PUSH_BUFFER_MASK_INPUT_BUFFER; + } + break; + + case VSS_IVPCM_TAP_POINT_DIR_IN: + push_buff_event.push_buf_mask = + VSS_IVPCM_PUSH_BUFFER_MASK_INPUT_BUFFER; + break; + + case VSS_IVPCM_TAP_POINT_DIR_OUT: + push_buff_event.push_buf_mask = + VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER; + break; + } + + push_buff_event.tap_point = notify_evt->tap_point; + push_buff_event.out_buf_mem_address = + tp->capture_dai_data.vocpcm_ion_buffer.paddr; + push_buff_event.in_buf_mem_address = + tp->playback_dai_data.vocpcm_ion_buffer.paddr; + push_buff_event.sampling_rate = notify_evt->sampling_rate; + push_buff_event.num_in_channels = 1; + + /* + * ADSP must read and write from a cache aligned (128 byte) location, + * and in blocks of the cache alignment size. The 128 byte cache + * alignment requirement is guaranteed due to 4096 byte memory + * alignment requirement during memory allocation/mapping. The output + * buffer (ADSP write) size mask ensures that a 128 byte multiple + * worth of will be written. Internally, the input buffer (ADSP read) + * size will also be a multiple of 128 bytes. However it is the + * application's responsibility to ensure no other data is written in + * the specified length of memory. + */ + push_buff_event.out_buf_mem_size = ((notify_evt->request_buf_size) + + CACHE_ALIGNMENT_SIZE) & CACHE_ALIGNMENT_MASK; + push_buff_event.in_buf_mem_size = in_buf_len; + + voc_send_cvp_vocpcm_push_buf_evt(voc_get_session_id(sess_name), + &push_buff_event); +} + +static int msm_hpcm_configure_voice_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + int tap_point = ucontrol->value.integer.value[0]; + uint16_t direction = ucontrol->value.integer.value[1]; + uint16_t sample_rate = ucontrol->value.integer.value[2]; + struct tappnt_mxr_data *tmd = NULL; + int ret = 0; + + mutex_lock(&hpcm_drv.lock); + pr_debug("%s: tap_point = %d direction = %d sample_rate = %d\n", + __func__, tap_point, direction, sample_rate); + + if (!hpcm_is_valid_config(VOICE_INDEX, tap_point, direction, + sample_rate)) { + pr_err("Invalid vpcm mixer control voice values\n"); + ret = -EINVAL; + goto done; + } + + if (tap_point == RX) + tmd = &hpcm_drv.mixer_conf.rx; + else + tmd = &hpcm_drv.mixer_conf.tx; + + tmd->enable = true; + tmd->direction = direction; + tmd->sample_rate = sample_rate; + hpcm_drv.mixer_conf.sess_indx = VOICE_INDEX; + +done: + mutex_unlock(&hpcm_drv.lock); + return ret; +} + +static int msm_hpcm_configure_vmmode1_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + int tap_point = ucontrol->value.integer.value[0]; + uint16_t direction = ucontrol->value.integer.value[1]; + uint16_t sample_rate = ucontrol->value.integer.value[2]; + struct tappnt_mxr_data *tmd = NULL; + int ret = 0; + + mutex_lock(&hpcm_drv.lock); + pr_debug("%s: tap_point = %d direction = %d sample_rate = %d\n", + __func__, tap_point, direction, sample_rate); + + if (!hpcm_is_valid_config(VOMMODE1_INDEX, tap_point, direction, + sample_rate)) { + pr_err("Invalid vpcm mixer control voice values\n"); + ret = -EINVAL; + goto done; + } + + if (tap_point == RX) + tmd = &hpcm_drv.mixer_conf.rx; + else + tmd = &hpcm_drv.mixer_conf.tx; + + tmd->enable = true; + tmd->direction = direction; + tmd->sample_rate = sample_rate; + hpcm_drv.mixer_conf.sess_indx = VOMMODE1_INDEX; + +done: + mutex_unlock(&hpcm_drv.lock); + return ret; +} + +static int msm_hpcm_configure_vmmode2_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + int tap_point = ucontrol->value.integer.value[0]; + uint16_t direction = ucontrol->value.integer.value[1]; + uint16_t sample_rate = ucontrol->value.integer.value[2]; + struct tappnt_mxr_data *tmd = NULL; + int ret = 0; + + mutex_lock(&hpcm_drv.lock); + pr_debug("%s: tap_point = %d direction = %d sample_rate = %d\n", + __func__, tap_point, direction, sample_rate); + + if (!hpcm_is_valid_config(VOMMODE2_INDEX, tap_point, direction, + sample_rate)) { + pr_err("Invalid vpcm mixer control voice values\n"); + ret = -EINVAL; + goto done; + } + + if (tap_point == RX) + tmd = &hpcm_drv.mixer_conf.rx; + else + tmd = &hpcm_drv.mixer_conf.tx; + + tmd->enable = true; + tmd->direction = direction; + tmd->sample_rate = sample_rate; + hpcm_drv.mixer_conf.sess_indx = VOMMODE2_INDEX; + +done: + mutex_unlock(&hpcm_drv.lock); + return ret; +} + +static int msm_hpcm_configure_volte_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + int tap_point = ucontrol->value.integer.value[0]; + uint16_t direction = ucontrol->value.integer.value[1]; + uint16_t sample_rate = ucontrol->value.integer.value[2]; + struct tappnt_mxr_data *tmd = NULL; + int ret = 0; + + mutex_lock(&hpcm_drv.lock); + pr_debug("%s: tap_point=%d direction=%d sample_rate=%d\n", + __func__, tap_point, direction, sample_rate); + + if (!hpcm_is_valid_config(VOLTE_INDEX, tap_point, direction, + sample_rate)) { + pr_err("Invalid vpcm mixer control volte values\n"); + ret = -EINVAL; + goto done; + } + + if (tap_point == RX) + tmd = &hpcm_drv.mixer_conf.rx; + else + tmd = &hpcm_drv.mixer_conf.tx; + + tmd->enable = true; + tmd->direction = direction; + tmd->sample_rate = sample_rate; + hpcm_drv.mixer_conf.sess_indx = VOLTE_INDEX; + +done: + mutex_unlock(&hpcm_drv.lock); + return ret; + +} + +static struct snd_kcontrol_new msm_hpcm_controls[] = { + SOC_SINGLE_MULTI_EXT("HPCM_Voice tappoint direction samplerate", + SND_SOC_NOPM, 0, 16000, 0, 3, + NULL, msm_hpcm_configure_voice_put), + SOC_SINGLE_MULTI_EXT("HPCM_VoLTE tappoint direction samplerate", + SND_SOC_NOPM, 0, 16000, 0, 3, + NULL, msm_hpcm_configure_volte_put), + SOC_SINGLE_MULTI_EXT("HPCM_VMMode1 tappoint direction samplerate", + SND_SOC_NOPM, 0, 16000, 0, 3, + NULL, msm_hpcm_configure_vmmode1_put), + SOC_SINGLE_MULTI_EXT("HPCM_VMMode2 tappoint direction samplerate", + SND_SOC_NOPM, 0, 16000, 0, 3, + NULL, msm_hpcm_configure_vmmode2_put), +}; + +/* Sample rates supported */ +static unsigned int supported_sample_rates[] = {8000, 16000}; + +static struct snd_pcm_hw_constraint_list constraints_sample_rates = { + .count = ARRAY_SIZE(supported_sample_rates), + .list = supported_sample_rates, + .mask = 0, +}; + +static int msm_pcm_close(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct list_head *ptr = NULL; + struct list_head *next = NULL; + struct hpcm_buf_node *buf_node = NULL; + struct snd_dma_buffer *dma_buf; + struct snd_pcm_runtime *runtime; + struct hpcm_drv *prtd; + unsigned long dsp_flags; + struct dai_data *dai_data = NULL; + struct tap_point *tp = NULL; + struct tappnt_mxr_data *tmd = NULL; + char *sess_name = NULL; + + if (substream == NULL) { + pr_err("substream is NULL\n"); + return -EINVAL; + } + + pr_debug("%s, %s\n", __func__, substream->pcm->id); + runtime = substream->runtime; + prtd = runtime->private_data; + sess_name = hpcm_get_sess_name(prtd->mixer_conf.sess_indx); + dai_data = hpcm_get_dai_data(substream->pcm->id, prtd); + + if (dai_data == NULL) { + pr_err("%s, dai_data is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + wake_up(&dai_data->queue_wait); + mutex_lock(&prtd->lock); + + tmd = hpcm_get_tappnt_mixer_data(substream->pcm->id, prtd); + + tp = hpcm_get_tappoint_data(substream->pcm->id, prtd); + /* Send stop command */ + voc_send_cvp_stop_vocpcm(voc_get_session_id(sess_name)); + /* Memory unmap/free takes place only when called the first time */ + hpcm_unmap_and_free_shared_memory(prtd); + /* Unregister host PCM event callback function */ + voc_deregister_hpcm_evt_cb(); + /* Reset the cached start cmd */ + memset(&prtd->start_cmd, 0, sizeof(struct start_cmd)); + /* Release all buffer */ + pr_debug("%s: Release all buffer\n", __func__); + substream = dai_data->substream; + if (substream == NULL) { + pr_debug("%s: substream is NULL\n", __func__); + goto done; + } + dma_buf = &substream->dma_buffer; + if (dma_buf == NULL) { + pr_debug("%s: dma_buf is NULL\n", __func__); + goto done; + } + if (dma_buf->area != NULL) { + spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags); + list_for_each_safe(ptr, next, &dai_data->filled_queue) { + buf_node = list_entry(ptr, + struct hpcm_buf_node, list); + list_del(&buf_node->list); + } + list_for_each_safe(ptr, next, &dai_data->free_queue) { + buf_node = list_entry(ptr, + struct hpcm_buf_node, list); + list_del(&buf_node->list); + } + spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags); + dma_free_coherent(substream->pcm->card->dev, + runtime->hw.buffer_bytes_max, dma_buf->area, + dma_buf->addr); + dma_buf->area = NULL; + } + dai_data->substream = NULL; + dai_data->pcm_buf_pos = 0; + dai_data->pcm_count = 0; + dai_data->pcm_irq_pos = 0; + dai_data->pcm_size = 0; + dai_data->state = HPCM_CLOSED; + hpcm_reset_mixer_config(prtd); + +done: + mutex_unlock(&prtd->lock); + return ret; +} + +static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, + snd_pcm_uframes_t hwoff, void __user *buf, + snd_pcm_uframes_t frames) +{ + int ret = 0; + struct hpcm_buf_node *buf_node = NULL; + struct snd_pcm_runtime *runtime = substream->runtime; + struct hpcm_drv *prtd = runtime->private_data; + struct dai_data *dai_data = hpcm_get_dai_data(substream->pcm->id, prtd); + unsigned long dsp_flags; + + int count = frames_to_bytes(runtime, frames); + + if (dai_data == NULL) { + pr_err("%s, dai_data is null\n", __func__); + + ret = -EINVAL; + goto done; + } + + ret = wait_event_interruptible_timeout(dai_data->queue_wait, + (!list_empty(&dai_data->free_queue) || + dai_data->state == HPCM_STOPPED), + 1 * HZ); + if (ret > 0) { + if (count <= HPCM_MAX_VOC_PKT_SIZE) { + spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags); + buf_node = + list_first_entry(&dai_data->free_queue, + struct hpcm_buf_node, list); + list_del(&buf_node->list); + spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags); + ret = copy_from_user(&buf_node->frame.voc_pkt, buf, + count); + buf_node->frame.len = count; + spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags); + list_add_tail(&buf_node->list, &dai_data->filled_queue); + spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags); + } else { + pr_err("%s: Write cnt %d is > HPCM_MAX_VOC_PKT_SIZE\n", + __func__, count); + ret = -ENOMEM; + } + } else if (ret == 0) { + pr_err("%s: No free Playback buffer\n", __func__); + ret = -ETIMEDOUT; + } else { + pr_err("%s: playback copy was interrupted\n", __func__); + } + +done: + return ret; +} + +static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, + int channel, snd_pcm_uframes_t hwoff, + void __user *buf, snd_pcm_uframes_t frames) +{ + int ret = 0; + int count = 0; + struct hpcm_buf_node *buf_node = NULL; + struct snd_pcm_runtime *runtime = substream->runtime; + struct hpcm_drv *prtd = runtime->private_data; + struct dai_data *dai_data = hpcm_get_dai_data(substream->pcm->id, prtd); + unsigned long dsp_flags; + + if (dai_data == NULL) { + pr_err("%s, dai_data is null\n", __func__); + + ret = -EINVAL; + goto done; + } + + count = frames_to_bytes(runtime, frames); + + ret = wait_event_interruptible_timeout(dai_data->queue_wait, + (!list_empty(&dai_data->filled_queue) || + dai_data->state == HPCM_STOPPED), + 1 * HZ); + + if (ret > 0) { + if (count <= HPCM_MAX_VOC_PKT_SIZE) { + spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags); + buf_node = list_first_entry(&dai_data->filled_queue, + struct hpcm_buf_node, list); + list_del(&buf_node->list); + spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags); + ret = copy_to_user(buf, &buf_node->frame.voc_pkt, + buf_node->frame.len); + if (ret) { + pr_err("%s: Copy to user returned %d\n", + __func__, ret); + ret = -EFAULT; + } + spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags); + list_add_tail(&buf_node->list, &dai_data->free_queue); + spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags); + + } else { + pr_err("%s: Read count %d > HPCM_MAX_VOC_PKT_SIZE\n", + __func__, count); + ret = -ENOMEM; + } + + } else if (ret == 0) { + pr_err("%s: No Caputre data available\n", __func__); + ret = -ETIMEDOUT; + } else { + pr_err("%s: Read was interrupted\n", __func__); + ret = -ERESTARTSYS; + } + +done: + return ret; +} + +static int msm_pcm_copy(struct snd_pcm_substream *substream, int channel, + snd_pcm_uframes_t hwoff, void __user *buf, + snd_pcm_uframes_t frames) +{ + int ret = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ret = msm_pcm_playback_copy(substream, channel, + hwoff, buf, frames); + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ret = msm_pcm_capture_copy(substream, channel, + hwoff, buf, frames); + + return ret; +} + +static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream) +{ + struct dai_data *dai_data = NULL; + struct snd_pcm_runtime *runtime = substream->runtime; + struct hpcm_drv *prtd = runtime->private_data; + snd_pcm_uframes_t ret; + + dai_data = hpcm_get_dai_data(substream->pcm->id, prtd); + + if (dai_data == NULL) { + pr_err("%s, dai_data is null\n", __func__); + + ret = 0; + goto done; + } + + if (dai_data->pcm_irq_pos >= dai_data->pcm_size) + dai_data->pcm_irq_pos = 0; + + ret = bytes_to_frames(runtime, (dai_data->pcm_irq_pos)); + +done: + return ret; +} + +static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + int ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct hpcm_drv *prtd = runtime->private_data; + struct dai_data *dai_data = + hpcm_get_dai_data(substream->pcm->id, prtd); + + if (dai_data == NULL) { + pr_err("%s, dai_data is null\n", __func__); + + ret = -EINVAL; + goto done; + } + + pr_debug("%s, %s\n", __func__, substream->pcm->id); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + pr_debug("SNDRV_PCM_TRIGGER_START\n"); + dai_data->state = HPCM_STARTED; + break; + + case SNDRV_PCM_TRIGGER_STOP: + pr_debug("SNDRV_PCM_TRIGGER_STOP\n"); + dai_data->state = HPCM_STOPPED; + break; + + default: + ret = -EINVAL; + break; + } + +done: + return ret; +} + +static int msm_pcm_prepare(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct hpcm_drv *prtd = runtime->private_data; + struct dai_data *dai_data = NULL; + struct tap_point *tp = NULL; + + pr_debug("%s, %s\n", __func__, substream->pcm->id); + mutex_lock(&prtd->lock); + + dai_data = hpcm_get_dai_data(substream->pcm->id, prtd); + + if (dai_data == NULL) { + pr_err("%s, dai_data is null\n", __func__); + + ret = -EINVAL; + goto done; + } + + dai_data->pcm_size = snd_pcm_lib_buffer_bytes(substream); + dai_data->pcm_count = snd_pcm_lib_period_bytes(substream); + dai_data->pcm_irq_pos = 0; + dai_data->pcm_buf_pos = 0; + dai_data->state = HPCM_PREPARED; + + /* Register event notify processing callback in prepare instead of + * init() as q6voice module's init() can be called at a later point + */ + voc_register_hpcm_evt_cb(hpcm_notify_evt_processing, &hpcm_drv); + + tp = hpcm_get_tappoint_data(substream->pcm->id, prtd); + if (tp != NULL) { + ret = hpcm_start_vocpcm(substream->pcm->id, prtd, tp); + if (ret) { + pr_err("error sending start cmd err=%d\n", ret); + goto done; + } + } else { + pr_err("%s tp is NULL\n", __func__); + } +done: + mutex_unlock(&prtd->lock); + return ret; +} + +static int msm_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_dma_buffer *dma_buf = &substream->dma_buffer; + struct hpcm_drv *prtd = (struct hpcm_drv *)runtime->private_data; + int ret = 0; + + pr_debug("%s: %s\n", __func__, substream->pcm->id); + mutex_lock(&prtd->lock); + + /* Allocate and map voice host PCM ion buffer */ + if (prtd->session[prtd->mixer_conf.sess_indx].sess_paddr == 0) { + ret = hpcm_allocate_shared_memory(prtd); + if (ret) { + pr_err("error creating shared memory err=%d\n", ret); + goto done; + } + + ret = hpcm_map_vocpcm_memory(prtd); + if (ret) { + pr_err("error mapping shared memory err=%d\n", ret); + hpcm_free_allocated_mem(prtd); + goto done; + } + } else { + pr_debug("%s, VHPCM memory allocation/mapping not performed\n" + , __func__); + } + + dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; + dma_buf->dev.dev = substream->pcm->card->dev; + dma_buf->private_data = NULL; + + dma_buf->area = dma_alloc_coherent(substream->pcm->card->dev, + runtime->hw.buffer_bytes_max, + &dma_buf->addr, GFP_KERNEL); + + if (!dma_buf->area) { + pr_err("%s:MSM dma_alloc failed\n", __func__); + ret = -ENOMEM; + goto done; + } + + dma_buf->bytes = runtime->hw.buffer_bytes_max; + memset(dma_buf->area, 0, runtime->hw.buffer_bytes_max); + + hpcm_create_free_queue(dma_buf, + hpcm_get_dai_data(substream->pcm->id, prtd)); + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + +done: + mutex_unlock(&prtd->lock); + return ret; +} + +static int msm_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct hpcm_drv *prtd = &hpcm_drv; + struct tappnt_mxr_data *tmd = NULL; + struct dai_data *dai_data = NULL; + int ret = 0; + int tp_val = 0; + + pr_debug("%s, %s\n", __func__, substream->pcm->id); + mutex_lock(&prtd->lock); + + dai_data = hpcm_get_dai_data(substream->pcm->id, prtd); + + if (dai_data == NULL) { + pr_err("%s, dai_data is null\n", __func__); + + ret = -EINVAL; + goto done; + } + + runtime->hw = msm_pcm_hardware; + + ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + &constraints_sample_rates); + if (ret < 0) + pr_debug("snd_pcm_hw_constraint_list failed\n"); + + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) { + pr_debug("snd_pcm_hw_constraint_integer failed\n"); + goto done; + } + + tp_val = get_tappnt_value(substream->pcm->id); + tmd = hpcm_get_tappnt_mixer_data(substream->pcm->id, prtd); + + /* Check wheather the kcontrol values set are valid */ + if (!tmd || + !(tmd->enable) || + !hpcm_is_valid_config(prtd->mixer_conf.sess_indx, + tp_val, tmd->direction, + tmd->sample_rate)) { + ret = -EINVAL; + goto done; + } + + dai_data->substream = substream; + runtime->private_data = prtd; + +done: + mutex_unlock(&prtd->lock); + return ret; +} + +static const struct snd_pcm_ops msm_pcm_ops = { + .open = msm_pcm_open, + .hw_params = msm_pcm_hw_params, + .prepare = msm_pcm_prepare, + .trigger = msm_pcm_trigger, + .pointer = msm_pcm_pointer, + .copy = msm_pcm_copy, + .close = msm_pcm_close, +}; + +static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_card *card = rtd->card->snd_card; + + pr_debug("%s:\n", __func__); + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); + + return 0; +} + +static int msm_pcm_hpcm_probe(struct snd_soc_platform *platform) +{ + snd_soc_add_platform_controls(platform, msm_hpcm_controls, + ARRAY_SIZE(msm_hpcm_controls)); + + return 0; +} + +static struct snd_soc_platform_driver msm_soc_platform = { + .ops = &msm_pcm_ops, + .pcm_new = msm_asoc_pcm_new, + .probe = msm_pcm_hpcm_probe, +}; + +static int msm_pcm_probe(struct platform_device *pdev) +{ + + pr_info("%s: dev name %s\n", __func__, dev_name(&pdev->dev)); + return snd_soc_register_platform(&pdev->dev, &msm_soc_platform); +} + +static int msm_pcm_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_voice_host_pcm_dt_match[] = { + {.compatible = "qcom,msm-voice-host-pcm"}, + {} +}; +MODULE_DEVICE_TABLE(of, msm_voice_host_pcm_dt_match); + +static struct platform_driver msm_pcm_driver = { + .driver = { + .name = "msm-voice-host-pcm", + .owner = THIS_MODULE, + .of_match_table = msm_voice_host_pcm_dt_match, + }, + .probe = msm_pcm_probe, + .remove = msm_pcm_remove, +}; + +static int __init msm_soc_platform_init(void) +{ + int i = 0; + struct session *s = NULL; + + memset(&hpcm_drv, 0, sizeof(hpcm_drv)); + mutex_init(&hpcm_drv.lock); + + for (i = 0; i < MAX_SESSION; i++) { + s = &hpcm_drv.session[i]; + spin_lock_init(&s->rx_tap_point.capture_dai_data.dsp_lock); + spin_lock_init(&s->rx_tap_point.playback_dai_data.dsp_lock); + spin_lock_init(&s->tx_tap_point.capture_dai_data.dsp_lock); + spin_lock_init(&s->tx_tap_point.playback_dai_data.dsp_lock); + + init_waitqueue_head( + &s->rx_tap_point.capture_dai_data.queue_wait); + init_waitqueue_head( + &s->rx_tap_point.playback_dai_data.queue_wait); + init_waitqueue_head( + &s->tx_tap_point.capture_dai_data.queue_wait); + init_waitqueue_head( + &s->tx_tap_point.playback_dai_data.queue_wait); + + INIT_LIST_HEAD(&s->rx_tap_point.capture_dai_data.filled_queue); + INIT_LIST_HEAD(&s->rx_tap_point.capture_dai_data.free_queue); + INIT_LIST_HEAD(&s->rx_tap_point.playback_dai_data.filled_queue); + INIT_LIST_HEAD(&s->rx_tap_point.playback_dai_data.free_queue); + + INIT_LIST_HEAD(&s->tx_tap_point.capture_dai_data.filled_queue); + INIT_LIST_HEAD(&s->tx_tap_point.capture_dai_data.free_queue); + INIT_LIST_HEAD(&s->tx_tap_point.playback_dai_data.filled_queue); + INIT_LIST_HEAD(&s->tx_tap_point.playback_dai_data.free_queue); + } + + return platform_driver_register(&msm_pcm_driver); +} +module_init(msm_soc_platform_init); + +static void __exit msm_soc_platform_exit(void) +{ + platform_driver_unregister(&msm_pcm_driver); +} +module_exit(msm_soc_platform_exit); + +MODULE_DESCRIPTION("PCM module platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c new file mode 100644 index 000000000000..7ef1ca8f1ae1 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c @@ -0,0 +1,801 @@ +/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "msm-pcm-routing-v2.h" + +#define LOOPBACK_VOL_MAX_STEPS 0x2000 +#define LOOPBACK_SESSION_MAX 4 + +static DEFINE_MUTEX(loopback_session_lock); +static const DECLARE_TLV_DB_LINEAR(loopback_rx_vol_gain, 0, + LOOPBACK_VOL_MAX_STEPS); + +struct msm_pcm_loopback { + struct snd_pcm_substream *playback_substream; + struct snd_pcm_substream *capture_substream; + + int instance; + + struct mutex lock; + + uint32_t samp_rate; + uint32_t channel_mode; + + int playback_start; + int capture_start; + int session_id; + struct audio_client *audio_client; + uint32_t volume; +}; + +struct fe_dai_session_map { + char stream_name[32]; + struct msm_pcm_loopback *loopback_priv; +}; + +static struct fe_dai_session_map session_map[LOOPBACK_SESSION_MAX] = { + { {}, NULL}, + { {}, NULL}, + { {}, NULL}, + { {}, NULL}, +}; + +static u32 hfp_tx_mute; + +struct msm_pcm_pdata { + int perf_mode; +}; + +static void stop_pcm(struct msm_pcm_loopback *pcm); +static int msm_pcm_loopback_get_session(struct snd_soc_pcm_runtime *rtd, + struct msm_pcm_loopback **pcm); + +static void msm_pcm_route_event_handler(enum msm_pcm_routing_event event, + void *priv_data) +{ + struct msm_pcm_loopback *pcm = priv_data; + + WARN_ON(!pcm); + + pr_debug("%s: event 0x%x\n", __func__, event); + + switch (event) { + case MSM_PCM_RT_EVT_DEVSWITCH: + q6asm_cmd(pcm->audio_client, CMD_PAUSE); + q6asm_cmd(pcm->audio_client, CMD_FLUSH); + q6asm_run(pcm->audio_client, 0, 0, 0); + /* fallthrough */ + default: + pr_err("%s: default event 0x%x\n", __func__, event); + break; + } +} + +static void msm_pcm_loopback_event_handler(uint32_t opcode, uint32_t token, + uint32_t *payload, void *priv) +{ + pr_debug("%s:\n", __func__); + switch (opcode) { + case APR_BASIC_RSP_RESULT: { + switch (payload[0]) { + break; + default: + break; + } + } + break; + default: + pr_err("%s: Not Supported Event opcode[0x%x]\n", + __func__, opcode); + break; + } +} + +static int msm_loopback_session_mute_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = hfp_tx_mute; + return 0; +} + +static int msm_loopback_session_mute_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0, n = 0; + int mute = ucontrol->value.integer.value[0]; + struct msm_pcm_loopback *pcm = NULL; + + if ((mute < 0) || (mute > 1)) { + pr_err(" %s Invalid arguments", __func__); + ret = -EINVAL; + goto done; + } + + pr_debug("%s: mute=%d\n", __func__, mute); + hfp_tx_mute = mute; + for (n = 0; n < LOOPBACK_SESSION_MAX; n++) { + if (!strcmp(session_map[n].stream_name, "MultiMedia6")) + pcm = session_map[n].loopback_priv; + } + if (pcm && pcm->audio_client) { + ret = q6asm_set_mute(pcm->audio_client, mute); + if (ret < 0) + pr_err("%s: Send mute command failed rc=%d\n", + __func__, ret); + } +done: + return ret; +} + +static struct snd_kcontrol_new msm_loopback_controls[] = { + SOC_SINGLE_EXT("HFP TX Mute", SND_SOC_NOPM, 0, 1, 0, + msm_loopback_session_mute_get, + msm_loopback_session_mute_put), +}; + +static int msm_pcm_loopback_probe(struct snd_soc_platform *platform) +{ + snd_soc_add_platform_controls(platform, msm_loopback_controls, + ARRAY_SIZE(msm_loopback_controls)); + + return 0; +} +static int pcm_loopback_set_volume(struct msm_pcm_loopback *prtd, + uint32_t volume) +{ + int rc = -EINVAL; + + pr_debug("%s: Setting volume 0x%x\n", __func__, volume); + + if (prtd && prtd->audio_client) { + rc = q6asm_set_volume(prtd->audio_client, volume); + if (rc < 0) { + pr_err("%s: Send Volume command failed rc = %d\n", + __func__, rc); + return rc; + } + prtd->volume = volume; + } + return rc; +} + +static int msm_pcm_loopback_get_session(struct snd_soc_pcm_runtime *rtd, + struct msm_pcm_loopback **pcm) +{ + int ret = 0; + int n, index = -1; + + dev_dbg(rtd->platform->dev, "%s: stream %s\n", __func__, + rtd->dai_link->stream_name); + + mutex_lock(&loopback_session_lock); + for (n = 0; n < LOOPBACK_SESSION_MAX; n++) { + if (!strcmp(rtd->dai_link->stream_name, + session_map[n].stream_name)) { + *pcm = session_map[n].loopback_priv; + goto exit; + } + /* + * Store the min index value for allocating a new session. + * Here, if session stream name is not found in the + * existing entries after the loop iteration, then this + * index will be used to allocate the new session. + * This index variable is expected to point to the topmost + * available free session. + */ + if (!(session_map[n].stream_name[0]) && (index < 0)) + index = n; + } + + if (index < 0) { + dev_err(rtd->platform->dev, "%s: Max Sessions allocated\n", + __func__); + ret = -EAGAIN; + goto exit; + } + + session_map[index].loopback_priv = kzalloc( + sizeof(struct msm_pcm_loopback), GFP_KERNEL); + if (!session_map[index].loopback_priv) { + ret = -ENOMEM; + goto exit; + } + + strlcpy(session_map[index].stream_name, + rtd->dai_link->stream_name, + sizeof(session_map[index].stream_name)); + dev_dbg(rtd->platform->dev, "%s: stream %s index %d\n", + __func__, session_map[index].stream_name, index); + + mutex_init(&session_map[index].loopback_priv->lock); + *pcm = session_map[index].loopback_priv; +exit: + mutex_unlock(&loopback_session_lock); + return ret; +} + +static int msm_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); + struct msm_pcm_loopback *pcm = NULL; + int ret = 0; + uint16_t bits_per_sample = 16; + struct msm_pcm_routing_evt event; + struct asm_session_mtmx_strtr_param_window_v2_t asm_mtmx_strtr_window; + uint32_t param_id; + struct msm_pcm_pdata *pdata; + + ret = msm_pcm_loopback_get_session(rtd, &pcm); + if (ret) + return ret; + + mutex_lock(&pcm->lock); + + pcm->volume = 0x2000; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + pcm->playback_substream = substream; + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + pcm->capture_substream = substream; + + pcm->instance++; + dev_dbg(rtd->platform->dev, "%s: pcm out open: %d,%d\n", __func__, + pcm->instance, substream->stream); + if (pcm->instance == 2) { + struct snd_soc_pcm_runtime *soc_pcm_rx = + pcm->playback_substream->private_data; + struct snd_soc_pcm_runtime *soc_pcm_tx = + pcm->capture_substream->private_data; + if (pcm->audio_client != NULL) + stop_pcm(pcm); + + pdata = (struct msm_pcm_pdata *) + dev_get_drvdata(rtd->platform->dev); + if (!pdata) { + dev_err(rtd->platform->dev, + "%s: platform data not populated\n", __func__); + mutex_unlock(&pcm->lock); + return -EINVAL; + } + + pcm->audio_client = q6asm_audio_client_alloc( + (app_cb)msm_pcm_loopback_event_handler, pcm); + if (!pcm->audio_client) { + dev_err(rtd->platform->dev, + "%s: Could not allocate memory\n", __func__); + mutex_unlock(&pcm->lock); + return -ENOMEM; + } + pcm->session_id = pcm->audio_client->session; + pcm->audio_client->perf_mode = pdata->perf_mode; + ret = q6asm_open_loopback_v2(pcm->audio_client, + bits_per_sample); + if (ret < 0) { + dev_err(rtd->platform->dev, + "%s: pcm out open failed\n", __func__); + q6asm_audio_client_free(pcm->audio_client); + mutex_unlock(&pcm->lock); + return -ENOMEM; + } + event.event_func = msm_pcm_route_event_handler; + event.priv_data = (void *) pcm; + msm_pcm_routing_reg_phy_stream(soc_pcm_tx->dai_link->id, + pcm->audio_client->perf_mode, + pcm->session_id, pcm->capture_substream->stream); + msm_pcm_routing_reg_phy_stream_v2(soc_pcm_rx->dai_link->id, + pcm->audio_client->perf_mode, + pcm->session_id, pcm->playback_substream->stream, + event); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + pcm->playback_substream = substream; + ret = pcm_loopback_set_volume(pcm, pcm->volume); + if (ret < 0) + dev_err(rtd->platform->dev, + "Error %d setting volume", ret); + } + /* Set to largest negative value */ + asm_mtmx_strtr_window.window_lsw = 0x00000000; + asm_mtmx_strtr_window.window_msw = 0x80000000; + param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_START_V2; + q6asm_send_mtmx_strtr_window(pcm->audio_client, + &asm_mtmx_strtr_window, + param_id); + /* Set to largest positive value */ + asm_mtmx_strtr_window.window_lsw = 0xffffffff; + asm_mtmx_strtr_window.window_msw = 0x7fffffff; + param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_END_V2; + q6asm_send_mtmx_strtr_window(pcm->audio_client, + &asm_mtmx_strtr_window, + param_id); + } + dev_info(rtd->platform->dev, "%s: Instance = %d, Stream ID = %s\n", + __func__, pcm->instance, substream->pcm->id); + runtime->private_data = pcm; + + mutex_unlock(&pcm->lock); + + return 0; +} + +static void stop_pcm(struct msm_pcm_loopback *pcm) +{ + struct snd_soc_pcm_runtime *soc_pcm_rx; + struct snd_soc_pcm_runtime *soc_pcm_tx; + + if (pcm->audio_client == NULL) + return; + q6asm_cmd(pcm->audio_client, CMD_CLOSE); + + if (pcm->playback_substream != NULL) { + soc_pcm_rx = pcm->playback_substream->private_data; + msm_pcm_routing_dereg_phy_stream(soc_pcm_rx->dai_link->id, + SNDRV_PCM_STREAM_PLAYBACK); + } + if (pcm->capture_substream != NULL) { + soc_pcm_tx = pcm->capture_substream->private_data; + msm_pcm_routing_dereg_phy_stream(soc_pcm_tx->dai_link->id, + SNDRV_PCM_STREAM_CAPTURE); + } + q6asm_audio_client_free(pcm->audio_client); + pcm->audio_client = NULL; +} + +static int msm_pcm_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_pcm_loopback *pcm = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); + int ret = 0, n; + bool found = false; + + mutex_lock(&pcm->lock); + + dev_dbg(rtd->platform->dev, "%s: end pcm call:%d\n", + __func__, substream->stream); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + pcm->playback_start = 0; + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + pcm->capture_start = 0; + + pcm->instance--; + if (!pcm->playback_start || !pcm->capture_start) { + dev_dbg(rtd->platform->dev, "%s: end pcm call\n", __func__); + stop_pcm(pcm); + } + + if (!pcm->instance) { + mutex_lock(&loopback_session_lock); + for (n = 0; n < LOOPBACK_SESSION_MAX; n++) { + if (!strcmp(rtd->dai_link->stream_name, + session_map[n].stream_name)) { + found = true; + break; + } + } + if (found) { + memset(session_map[n].stream_name, 0, + sizeof(session_map[n].stream_name)); + mutex_unlock(&pcm->lock); + mutex_destroy(&session_map[n].loopback_priv->lock); + session_map[n].loopback_priv = NULL; + kfree(pcm); + dev_dbg(rtd->platform->dev, "%s: stream freed %s\n", + __func__, rtd->dai_link->stream_name); + mutex_unlock(&loopback_session_lock); + return 0; + } + mutex_unlock(&loopback_session_lock); + } + mutex_unlock(&pcm->lock); + return ret; +} + +static int msm_pcm_prepare(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_pcm_loopback *pcm = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); + + mutex_lock(&pcm->lock); + + dev_dbg(rtd->platform->dev, "%s: ASM loopback stream:%d\n", + __func__, substream->stream); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + if (!pcm->playback_start) + pcm->playback_start = 1; + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (!pcm->capture_start) + pcm->capture_start = 1; + } + mutex_unlock(&pcm->lock); + + return ret; +} + +static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_pcm_loopback *pcm = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + dev_dbg(rtd->platform->dev, + "%s: playback_start:%d,capture_start:%d\n", __func__, + pcm->playback_start, pcm->capture_start); + if (pcm->playback_start && pcm->capture_start) + q6asm_run_nowait(pcm->audio_client, 0, 0, 0); + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_STOP: + dev_dbg(rtd->platform->dev, + "%s:Pause/Stop - playback_start:%d,capture_start:%d\n", + __func__, pcm->playback_start, pcm->capture_start); + if (pcm->playback_start && pcm->capture_start) + q6asm_cmd_nowait(pcm->audio_client, CMD_PAUSE); + break; + default: + pr_err("%s: default cmd %d\n", __func__, cmd); + break; + } + + return 0; +} + +static const struct snd_pcm_ops msm_pcm_ops = { + .open = msm_pcm_open, + .close = msm_pcm_close, + .prepare = msm_pcm_prepare, + .trigger = msm_pcm_trigger, +}; + +static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + struct snd_pcm_volume *vol = kcontrol->private_data; + struct snd_pcm_substream *substream = vol->pcm->streams[0].substream; + struct msm_pcm_loopback *prtd; + int volume = ucontrol->value.integer.value[0]; + + pr_debug("%s: volume : 0x%x\n", __func__, volume); + if ((!substream) || (!substream->runtime)) { + pr_err("%s substream or runtime not found\n", __func__); + rc = -ENODEV; + goto exit; + } + prtd = substream->runtime->private_data; + if (!prtd) { + rc = -ENODEV; + goto exit; + } + rc = pcm_loopback_set_volume(prtd, volume); + +exit: + return rc; +} + +static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol); + struct snd_pcm_substream *substream = + vol->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + struct msm_pcm_loopback *prtd; + + pr_debug("%s\n", __func__); + if ((!substream) || (!substream->runtime)) { + pr_err("%s substream or runtime not found\n", __func__); + rc = -ENODEV; + goto exit; + } + prtd = substream->runtime->private_data; + if (!prtd) { + rc = -ENODEV; + goto exit; + } + ucontrol->value.integer.value[0] = prtd->volume; + +exit: + return rc; +} + +static int msm_pcm_add_volume_controls(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm *pcm = rtd->pcm->streams[0].pcm; + struct snd_pcm_volume *volume_info; + struct snd_kcontrol *kctl; + int ret = 0; + + dev_dbg(rtd->dev, "%s, Volume cntrl add\n", __func__); + ret = snd_pcm_add_volume_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, + NULL, 1, + rtd->dai_link->id, + &volume_info); + if (ret < 0) + return ret; + kctl = volume_info->kctl; + kctl->put = msm_pcm_volume_ctl_put; + kctl->get = msm_pcm_volume_ctl_get; + kctl->tlv.p = loopback_rx_vol_gain; + return 0; +} + +static int msm_pcm_playback_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_RX; + int be_id = ucontrol->value.integer.value[3]; + struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000}; + int ret = 0; + + cfg_data.app_type = ucontrol->value.integer.value[0]; + cfg_data.acdb_dev_id = ucontrol->value.integer.value[1]; + if (ucontrol->value.integer.value[2] != 0) + cfg_data.sample_rate = ucontrol->value.integer.value[2]; + pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, &cfg_data); + if (ret < 0) + pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n", + __func__, ret); + + return ret; +} + +static int msm_pcm_playback_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_RX; + int be_id = 0; + struct msm_pcm_stream_app_type_cfg cfg_data = {0}; + int ret = 0; + + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + &be_id, &cfg_data); + if (ret < 0) { + pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n", + __func__, ret); + goto done; + } + + ucontrol->value.integer.value[0] = cfg_data.app_type; + ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id; + ucontrol->value.integer.value[2] = cfg_data.sample_rate; + ucontrol->value.integer.value[3] = be_id; + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); +done: + return ret; +} + +static int msm_pcm_capture_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = ucontrol->value.integer.value[3]; + struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000}; + int ret = 0; + + cfg_data.app_type = ucontrol->value.integer.value[0]; + cfg_data.acdb_dev_id = ucontrol->value.integer.value[1]; + if (ucontrol->value.integer.value[2] != 0) + cfg_data.sample_rate = ucontrol->value.integer.value[2]; + pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, &cfg_data); + if (ret < 0) + pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n", + __func__, ret); + + return ret; +} + +static int msm_pcm_capture_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = 0; + struct msm_pcm_stream_app_type_cfg cfg_data = {0}; + int ret = 0; + + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + &be_id, &cfg_data); + if (ret < 0) { + pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n", + __func__, ret); + goto done; + } + + ucontrol->value.integer.value[0] = cfg_data.app_type; + ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id; + ucontrol->value.integer.value[2] = cfg_data.sample_rate; + ucontrol->value.integer.value[3] = be_id; + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); +done: + return ret; +} + +static int msm_pcm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm *pcm = rtd->pcm->streams[0].pcm; + struct snd_pcm_usr *app_type_info; + struct snd_kcontrol *kctl; + const char *playback_mixer_ctl_name = "Audio Stream"; + const char *capture_mixer_ctl_name = "Audio Stream Capture"; + const char *deviceNo = "NN"; + const char *suffix = "App Type Cfg"; + int ctl_len, ret = 0; + + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { + ctl_len = strlen(playback_mixer_ctl_name) + 1 + + strlen(deviceNo) + 1 + strlen(suffix) + 1; + pr_debug("%s: Playback app type cntrl add\n", __func__); + ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, + NULL, 1, ctl_len, rtd->dai_link->id, + &app_type_info); + if (ret < 0) + return ret; + kctl = app_type_info->kctl; + snprintf(kctl->id.name, ctl_len, "%s %d %s", + playback_mixer_ctl_name, rtd->pcm->device, suffix); + kctl->put = msm_pcm_playback_app_type_cfg_ctl_put; + kctl->get = msm_pcm_playback_app_type_cfg_ctl_get; + } + + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { + ctl_len = strlen(capture_mixer_ctl_name) + 1 + + strlen(deviceNo) + 1 + strlen(suffix) + 1; + pr_debug("%s: Capture app type cntrl add\n", __func__); + ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE, + NULL, 1, ctl_len, rtd->dai_link->id, + &app_type_info); + if (ret < 0) + return ret; + kctl = app_type_info->kctl; + snprintf(kctl->id.name, ctl_len, "%s %d %s", + capture_mixer_ctl_name, rtd->pcm->device, suffix); + kctl->put = msm_pcm_capture_app_type_cfg_ctl_put; + kctl->get = msm_pcm_capture_app_type_cfg_ctl_get; + } + + return 0; +} + +static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + + pr_debug("%s\n", __func__); + ret = msm_pcm_add_volume_controls(rtd); + if (ret) + pr_err("%s: pcm add volume controls failed:%d\n", + __func__, ret); + ret = msm_pcm_add_app_type_controls(rtd); + if (ret) + pr_err("%s: pcm add app type controls failed:%d\n", + __func__, ret); + return ret; +} + +static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_card *card = rtd->card->snd_card; + int ret = 0; + + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); + + ret = msm_pcm_add_controls(rtd); + if (ret) + dev_err(rtd->dev, "%s, kctl add failed\n", __func__); + return ret; +} + +static struct snd_soc_platform_driver msm_soc_platform = { + .ops = &msm_pcm_ops, + .pcm_new = msm_asoc_pcm_new, + .probe = msm_pcm_loopback_probe, +}; + +static int msm_pcm_probe(struct platform_device *pdev) +{ + struct msm_pcm_pdata *pdata; + + dev_dbg(&pdev->dev, "%s: dev name %s\n", + __func__, dev_name(&pdev->dev)); + + pdata = kzalloc(sizeof(struct msm_pcm_pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + if (of_property_read_bool(pdev->dev.of_node, + "qcom,msm-pcm-loopback-low-latency")) + pdata->perf_mode = LOW_LATENCY_PCM_MODE; + else + pdata->perf_mode = LEGACY_PCM_MODE; + + dev_set_drvdata(&pdev->dev, pdata); + + return snd_soc_register_platform(&pdev->dev, + &msm_soc_platform); +} + +static int msm_pcm_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_pcm_loopback_dt_match[] = { + {.compatible = "qcom,msm-pcm-loopback"}, + {} +}; + +static struct platform_driver msm_pcm_driver = { + .driver = { + .name = "msm-pcm-loopback", + .owner = THIS_MODULE, + .of_match_table = msm_pcm_loopback_dt_match, + }, + .probe = msm_pcm_probe, + .remove = msm_pcm_remove, +}; + +static int __init msm_soc_platform_init(void) +{ + return platform_driver_register(&msm_pcm_driver); +} +module_init(msm_soc_platform_init); + +static void __exit msm_soc_platform_exit(void) +{ + platform_driver_unregister(&msm_pcm_driver); +} +module_exit(msm_soc_platform_exit); + +MODULE_DESCRIPTION("PCM loopback platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c new file mode 100644 index 000000000000..325d642b7d7c --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c @@ -0,0 +1,1136 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "msm-pcm-q6-v2.h" +#include "msm-pcm-routing-v2.h" + +#define PCM_MASTER_VOL_MAX_STEPS 0x2000 +static const DECLARE_TLV_DB_LINEAR(msm_pcm_vol_gain, 0, + PCM_MASTER_VOL_MAX_STEPS); + +struct snd_msm { + struct snd_card *card; + struct snd_pcm *pcm; +}; + +#define CMD_EOS_MIN_TIMEOUT_LENGTH 50 +#define CMD_EOS_TIMEOUT_MULTIPLIER (HZ * 50) + +#define ATRACE_END() \ + trace_printk("tracing_mark_write: E\n") +#define ATRACE_BEGIN(name) \ + trace_printk("tracing_mark_write: B|%d|%s\n", current->tgid, name) +#define ATRACE_FUNC() ATRACE_BEGIN(__func__) +#define ATRACE_INT(name, value) \ + trace_printk("tracing_mark_write: C|%d|%s|%d\n", \ + current->tgid, name, (int)(value)) + +#define SIO_PLAYBACK_MAX_PERIOD_SIZE PLAYBACK_MAX_PERIOD_SIZE +#define SIO_PLAYBACK_MIN_PERIOD_SIZE 48 +#define SIO_PLAYBACK_MAX_NUM_PERIODS 512 +#define SIO_PLAYBACK_MIN_NUM_PERIODS PLAYBACK_MIN_NUM_PERIODS +#define SIO_PLAYBACK_MIN_BYTES (SIO_PLAYBACK_MIN_NUM_PERIODS * \ + SIO_PLAYBACK_MIN_PERIOD_SIZE) + +#define SIO_PLAYBACK_MAX_BYTES ((SIO_PLAYBACK_MAX_NUM_PERIODS) * \ + (SIO_PLAYBACK_MAX_PERIOD_SIZE)) + +#define SIO_CAPTURE_MAX_PERIOD_SIZE CAPTURE_MAX_PERIOD_SIZE +#define SIO_CAPTURE_MIN_PERIOD_SIZE 48 +#define SIO_CAPTURE_MAX_NUM_PERIODS 512 +#define SIO_CAPTURE_MIN_NUM_PERIODS CAPTURE_MIN_NUM_PERIODS + +#define SIO_CAPTURE_MIN_BYTES (SIO_CAPTURE_MIN_NUM_PERIODS * \ + SIO_CAPTURE_MIN_PERIOD_SIZE) + +#define SIO_CAPTURE_MAX_BYTES (SIO_CAPTURE_MAX_NUM_PERIODS * \ + SIO_CAPTURE_MAX_PERIOD_SIZE) + +static struct snd_pcm_hardware msm_pcm_hardware_playback = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE), + .rates = SNDRV_PCM_RATE_8000_192000, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 8, + .buffer_bytes_max = SIO_PLAYBACK_MAX_NUM_PERIODS * + SIO_PLAYBACK_MAX_PERIOD_SIZE, + .period_bytes_min = SIO_PLAYBACK_MIN_PERIOD_SIZE, + .period_bytes_max = SIO_PLAYBACK_MAX_PERIOD_SIZE, + .periods_min = SIO_PLAYBACK_MIN_NUM_PERIODS, + .periods_max = SIO_PLAYBACK_MAX_NUM_PERIODS, + .fifo_size = 0, +}; + +static struct snd_pcm_hardware msm_pcm_hardware_capture = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE), + .rates = SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 4, + .buffer_bytes_max = SIO_CAPTURE_MAX_NUM_PERIODS * + SIO_CAPTURE_MAX_PERIOD_SIZE, + .period_bytes_min = SIO_CAPTURE_MIN_PERIOD_SIZE, + .period_bytes_max = SIO_CAPTURE_MAX_PERIOD_SIZE, + .periods_min = SIO_CAPTURE_MIN_NUM_PERIODS, + .periods_max = SIO_CAPTURE_MAX_NUM_PERIODS, + .fifo_size = 0, +}; + +/* Conventional and unconventional sample rate supported */ +static unsigned int supported_sample_rates[] = { + 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, + 88200, 96000, 176400, 192000 +}; + +static struct snd_pcm_hw_constraint_list constraints_sample_rates = { + .count = ARRAY_SIZE(supported_sample_rates), + .list = supported_sample_rates, + .mask = 0, +}; + +static unsigned long msm_pcm_fe_topology[MSM_FRONTEND_DAI_MAX]; + +/* default value is DTS (i.e read from device tree) */ +static char const *msm_pcm_fe_topology_text[] = { + "DTS", "ULL", "ULL_PP", "LL" }; + +static const struct soc_enum msm_pcm_fe_topology_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(msm_pcm_fe_topology_text), + msm_pcm_fe_topology_text), +}; + +static void event_handler(uint32_t opcode, + uint32_t token, uint32_t *payload, void *priv) +{ + uint32_t *ptrmem = (uint32_t *)payload; + + switch (opcode) { + case ASM_DATA_EVENT_WATERMARK: + pr_debug("%s: Watermark level = 0x%08x\n", __func__, *ptrmem); + break; + case APR_BASIC_RSP_RESULT: + pr_debug("%s: Payload = [0x%x]stat[0x%x]\n", + __func__, payload[0], payload[1]); + switch (payload[0]) { + case ASM_SESSION_CMD_RUN_V2: + case ASM_SESSION_CMD_PAUSE: + case ASM_STREAM_CMD_FLUSH: + break; + default: + break; + } + break; + default: + pr_debug("Not Supported Event opcode[0x%x]\n", opcode); + break; + } +} + +static int msm_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_audio *prtd; + int ret = 0; + + prtd = kzalloc(sizeof(struct msm_audio), GFP_KERNEL); + + if (prtd == NULL) + return -ENOMEM; + + prtd->substream = substream; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + runtime->hw = msm_pcm_hardware_playback; + else + runtime->hw = msm_pcm_hardware_capture; + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_sample_rates); + if (ret) + pr_info("snd_pcm_hw_constraint_list failed\n"); + + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret) + pr_info("snd_pcm_hw_constraint_integer failed\n"); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, + SIO_PLAYBACK_MIN_BYTES, + SIO_PLAYBACK_MAX_BYTES); + if (ret) { + pr_info("%s: P buffer bytes minmax constraint ret %d\n", + __func__, ret); + } + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + ret = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, + SIO_CAPTURE_MIN_BYTES, + SIO_CAPTURE_MAX_BYTES); + if (ret) { + pr_info("%s: C buffer bytes minmax constraint ret %d\n", + __func__, ret); + } + } + + ret = snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); + if (ret) { + pr_err("%s: Constraint for period bytes step ret = %d\n", + __func__, ret); + } + ret = snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); + if (ret) { + pr_err("%s: Constraint for buffer bytes step ret = %d\n", + __func__, ret); + } + prtd->audio_client = q6asm_audio_client_alloc( + (app_cb)event_handler, prtd); + if (!prtd->audio_client) { + pr_err("%s: client alloc failed\n", __func__); + ret = -ENOMEM; + goto fail_cmd; + } + prtd->dsp_cnt = 0; + prtd->set_channel_map = false; + runtime->private_data = prtd; + return 0; + +fail_cmd: + kfree(prtd); + return ret; +} + +static int msm_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) + +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; + struct msm_audio *prtd = runtime->private_data; + struct msm_plat_data *pdata; + struct snd_dma_buffer *dma_buf = &substream->dma_buffer; + struct audio_buffer *buf; + struct shared_io_config config; + uint16_t sample_word_size; + uint16_t bits_per_sample; + int ret; + int dir = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? IN : OUT; + unsigned long topology; + int perf_mode; + + pdata = (struct msm_plat_data *) + dev_get_drvdata(soc_prtd->platform->dev); + if (!pdata) { + ret = -EINVAL; + pr_err("%s: platform data not populated ret: %d\n", __func__, + ret); + return ret; + } + + topology = msm_pcm_fe_topology[soc_prtd->dai_link->id]; + + if (!strcmp(msm_pcm_fe_topology_text[topology], "ULL_PP")) + perf_mode = ULL_POST_PROCESSING_PCM_MODE; + else if (!strcmp(msm_pcm_fe_topology_text[topology], "ULL")) + perf_mode = ULTRA_LOW_LATENCY_PCM_MODE; + else if (!strcmp(msm_pcm_fe_topology_text[topology], "LL")) + perf_mode = LOW_LATENCY_PCM_MODE; + else + /* use the default from the device tree */ + perf_mode = pdata->perf_mode; + + + /* need to set LOW_LATENCY_PCM_MODE for capture since + * push mode does not support ULL + */ + prtd->audio_client->perf_mode = (dir == IN) ? + perf_mode : + LOW_LATENCY_PCM_MODE; + + /* rate and channels are sent to audio driver */ + prtd->samp_rate = params_rate(params); + prtd->channel_mode = params_channels(params); + if (prtd->enabled) + return 0; + + switch (runtime->format) { + case SNDRV_PCM_FORMAT_S24_LE: + bits_per_sample = 24; + sample_word_size = 32; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + bits_per_sample = 24; + sample_word_size = 24; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bits_per_sample = 16; + sample_word_size = 16; + break; + } + + config.format = FORMAT_LINEAR_PCM; + config.bits_per_sample = bits_per_sample; + config.rate = params_rate(params); + config.channels = params_channels(params); + config.sample_word_size = sample_word_size; + config.bufsz = params_buffer_bytes(params) / params_periods(params); + config.bufcnt = params_periods(params); + + ret = q6asm_open_shared_io(prtd->audio_client, &config, dir); + if (ret) { + pr_err("%s: q6asm_open_write_shared_io failed ret: %d\n", + __func__, ret); + return ret; + } + + prtd->pcm_size = params_buffer_bytes(params); + prtd->pcm_count = params_buffer_bytes(params); + prtd->pcm_irq_pos = 0; + + buf = prtd->audio_client->port[dir].buf; + dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; + dma_buf->dev.dev = substream->pcm->card->dev; + dma_buf->private_data = NULL; + dma_buf->area = buf->data; + dma_buf->addr = buf->phys; + dma_buf->bytes = prtd->pcm_size; + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + + pr_debug("%s: session ID %d, perf %d\n", __func__, + prtd->audio_client->session, + prtd->audio_client->perf_mode); + prtd->session_id = prtd->audio_client->session; + + pr_debug("msm_pcm_routing_reg_phy_stream w/ id %d\n", + soc_prtd->dai_link->id); + ret = msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->id, + prtd->audio_client->perf_mode, + prtd->session_id, substream->stream); + + if (ret) { + pr_err("%s: stream reg failed ret:%d\n", __func__, ret); + return ret; + } + + atomic_set(&prtd->out_count, runtime->periods); + prtd->enabled = 1; + prtd->cmd_pending = 0; + prtd->cmd_interrupt = 0; + + return 0; +} + +static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + int ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_audio *prtd = runtime->private_data; + int dir = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 0 : 1; + struct audio_buffer *buf; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + pr_debug("%s: %s Trigger start\n", __func__, + dir == 0 ? "P" : "C"); + ret = q6asm_run(prtd->audio_client, 0, 0, 0); + if (ret) + break; + atomic_set(&prtd->start, 1); + break; + case SNDRV_PCM_TRIGGER_STOP: + pr_debug("%s: SNDRV_PCM_TRIGGER_STOP\n", __func__); + atomic_set(&prtd->start, 0); + q6asm_cmd(prtd->audio_client, CMD_PAUSE); + q6asm_cmd(prtd->audio_client, CMD_FLUSH); + buf = q6asm_shared_io_buf(prtd->audio_client, dir); + if (buf == NULL) { + pr_err("%s: shared IO buffer is null\n", __func__); + ret = -EINVAL; + break; + } + memset(buf->data, 0, buf->actual_size); + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + pr_debug("%s: SNDRV_PCM_TRIGGER_PAUSE\n", __func__); + ret = q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE); + atomic_set(&prtd->start, 0); + break; + default: + ret = -EINVAL; + break; + } + return ret; +} + +static int msm_pcm_ioctl(struct snd_pcm_substream *substream, + unsigned int cmd, void *arg) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_audio *prtd = runtime->private_data; + int dir = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 0 : 1; + struct audio_buffer *buf; + + switch (cmd) { + case SNDRV_PCM_IOCTL1_RESET: + pr_debug("%s: %s SNDRV_PCM_IOCTL1_RESET\n", __func__, + dir == 0 ? "P" : "C"); + buf = q6asm_shared_io_buf(prtd->audio_client, dir); + + if (buf && buf->data) + memset(buf->data, 0, buf->actual_size); + break; + default: + break; + } + + return snd_pcm_lib_ioctl(substream, cmd, arg); +} + +static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + uint32_t read_index, wall_clk_msw, wall_clk_lsw; + /*these are offsets, unlike ASoC's full values*/ + snd_pcm_sframes_t hw_ptr; + snd_pcm_sframes_t period_size; + int ret; + int retries = 10; + struct msm_audio *prtd = runtime->private_data; + + period_size = runtime->period_size; + + do { + ret = q6asm_get_shared_pos(prtd->audio_client, + &read_index, &wall_clk_msw, + &wall_clk_lsw); + } while (ret == -EAGAIN && --retries); + + if (ret || !period_size) { + pr_err("get_shared_pos error or zero period size\n"); + return 0; + } + + hw_ptr = bytes_to_frames(substream->runtime, + read_index); + + if (runtime->control->appl_ptr == 0) { + pr_debug("ptr(%s): appl(0), hw = %lu read_index = %u\n", + prtd->substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? + "P" : "C", + hw_ptr, read_index); + } + return (hw_ptr/period_size) * period_size; +} + +static int msm_pcm_copy(struct snd_pcm_substream *substream, int a, + snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames) +{ + return -EINVAL; +} + +static int msm_pcm_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_audio *prtd = runtime->private_data; + struct audio_client *ac = prtd->audio_client; + struct audio_port_data *apd = ac->port; + struct audio_buffer *ab; + int dir = -1; + int ret; + + pr_debug("%s: mmap begin\n", __func__); + prtd->mmap_flag = 1; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dir = IN; + else + dir = OUT; + + ab = &(apd[dir].buf[0]); + + ret = msm_audio_ion_mmap(ab, vma); + + if (ret) + prtd->mmap_flag = 0; + + return ret; +} + +static int msm_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_audio *prtd = runtime->private_data; + + if (!prtd || !prtd->mmap_flag) + return -EIO; + + return 0; +} + +static int msm_pcm_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; + struct msm_audio *prtd = runtime->private_data; + struct audio_client *ac = prtd->audio_client; + uint32_t timeout; + int dir = 0; + int ret = 0; + + if (ac) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dir = IN; + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + dir = OUT; + + /* determine timeout length */ + if (runtime->frame_bits == 0 || runtime->rate == 0) { + timeout = CMD_EOS_MIN_TIMEOUT_LENGTH; + } else { + timeout = (runtime->period_size * + CMD_EOS_TIMEOUT_MULTIPLIER) / + ((runtime->frame_bits / 8) * + runtime->rate); + if (timeout < CMD_EOS_MIN_TIMEOUT_LENGTH) + timeout = CMD_EOS_MIN_TIMEOUT_LENGTH; + } + + q6asm_cmd(ac, CMD_CLOSE); + + ret = q6asm_shared_io_free(ac, dir); + + if (ret) { + pr_err("%s: Failed to close pull mode, ret %d\n", + __func__, ret); + } + q6asm_audio_client_free(ac); + } + msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->id, + dir == IN ? + SNDRV_PCM_STREAM_PLAYBACK : + SNDRV_PCM_STREAM_CAPTURE); + kfree(prtd); + runtime->private_data = NULL; + + return 0; +} + +static int msm_pcm_set_volume(struct msm_audio *prtd, uint32_t volume) +{ + int rc = 0; + + if (prtd && prtd->audio_client) { + pr_debug("%s: channels %d volume 0x%x\n", __func__, + prtd->channel_mode, volume); + rc = q6asm_set_volume(prtd->audio_client, volume); + if (rc < 0) { + pr_err("%s: Send Volume command failed rc=%d\n", + __func__, rc); + } + } + return rc; +} + +static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol); + struct snd_pcm_substream *substream = + vol->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + struct msm_audio *prtd; + + pr_debug("%s\n", __func__); + if (!substream) { + pr_err("%s substream not found\n", __func__); + return -ENODEV; + } + if (!substream->runtime) { + pr_err("%s substream runtime not found\n", __func__); + return 0; + } + prtd = substream->runtime->private_data; + if (prtd) + ucontrol->value.integer.value[0] = prtd->volume; + return 0; +} + +static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol); + struct snd_pcm_substream *substream = + vol->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + struct msm_audio *prtd; + int volume = ucontrol->value.integer.value[0]; + + pr_debug("%s: volume : 0x%x\n", __func__, volume); + if (!substream) { + pr_err("%s substream not found\n", __func__); + return -ENODEV; + } + if (!substream->runtime) { + pr_err("%s substream runtime not found\n", __func__); + return 0; + } + prtd = substream->runtime->private_data; + if (prtd) { + rc = msm_pcm_set_volume(prtd, volume); + prtd->volume = volume; + } + return rc; +} + +static int msm_pcm_add_volume_control(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + struct snd_pcm *pcm = rtd->pcm; + struct snd_pcm_volume *volume_info; + struct snd_kcontrol *kctl; + + dev_dbg(rtd->dev, "%s, Volume control add\n", __func__); + ret = snd_pcm_add_volume_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, + NULL, 1, rtd->dai_link->id, + &volume_info); + if (ret < 0) { + pr_err("%s volume control failed ret %d\n", __func__, ret); + return ret; + } + kctl = volume_info->kctl; + kctl->put = msm_pcm_volume_ctl_put; + kctl->get = msm_pcm_volume_ctl_get; + kctl->tlv.p = msm_pcm_vol_gain; + return 0; +} + +static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int i; + struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); + unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + struct snd_pcm_substream *substream; + struct msm_audio *prtd; + + pr_debug("%s", __func__); + substream = snd_pcm_chmap_substream(info, idx); + if (!substream) + return -ENODEV; + if (!substream->runtime) + return 0; + + prtd = substream->runtime->private_data; + if (prtd) { + prtd->set_channel_map = true; + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + prtd->channel_map[i] = + (char)(ucontrol->value.integer.value[i]); + } + return 0; +} + +static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int i; + struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); + unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + struct snd_pcm_substream *substream; + struct msm_audio *prtd; + + pr_debug("%s", __func__); + substream = snd_pcm_chmap_substream(info, idx); + if (!substream) + return -ENODEV; + memset(ucontrol->value.integer.value, 0, + sizeof(ucontrol->value.integer.value)); + if (!substream->runtime) + return 0; /* no channels set */ + + prtd = substream->runtime->private_data; + + if (prtd && prtd->set_channel_map == true) { + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + ucontrol->value.integer.value[i] = + (int)prtd->channel_map[i]; + } else { + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + ucontrol->value.integer.value[i] = 0; + } + + return 0; +} + +static int msm_pcm_add_chmap_control(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm *pcm = rtd->pcm; + struct snd_pcm_chmap *chmap_info; + struct snd_kcontrol *kctl; + char device_num[12]; + int i, ret; + + pr_debug("%s, Channel map cntrl add\n", __func__); + ret = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, + snd_pcm_std_chmaps, + PCM_FORMAT_MAX_NUM_CHANNEL, 0, + &chmap_info); + if (ret) + return ret; + + kctl = chmap_info->kctl; + for (i = 0; i < kctl->count; i++) + kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE; + snprintf(device_num, sizeof(device_num), "%d", pcm->device); + strlcat(kctl->id.name, device_num, sizeof(kctl->id.name)); + pr_debug("%s, Overwriting channel map control name to: %s", + __func__, kctl->id.name); + kctl->put = msm_pcm_chmap_ctl_put; + kctl->get = msm_pcm_chmap_ctl_get; + return 0; +} + +static int msm_pcm_fe_topology_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + const struct soc_enum *e = &msm_pcm_fe_topology_enum[0]; + + return snd_ctl_enum_info(uinfo, 1, e->items, e->texts); +} + +static int msm_pcm_fe_topology_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned long fe_id = kcontrol->private_value; + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bound fe_id %lu\n", __func__, fe_id); + return -EINVAL; + } + + pr_debug("%s: %lu topology %s\n", __func__, fe_id, + msm_pcm_fe_topology_text[msm_pcm_fe_topology[fe_id]]); + ucontrol->value.enumerated.item[0] = msm_pcm_fe_topology[fe_id]; + return 0; +} + +static int msm_pcm_fe_topology_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned long fe_id = kcontrol->private_value; + unsigned int item; + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bound fe_id %lu\n", __func__, fe_id); + return -EINVAL; + } + + item = ucontrol->value.enumerated.item[0]; + if (item >= ARRAY_SIZE(msm_pcm_fe_topology_text)) { + pr_err("%s Received out of bound topology %lu\n", __func__, + fe_id); + return -EINVAL; + } + + pr_debug("%s: %lu new topology %s\n", __func__, fe_id, + msm_pcm_fe_topology_text[item]); + msm_pcm_fe_topology[fe_id] = item; + return 0; +} + +static int msm_pcm_add_fe_topology_control(struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = "PCM_Dev"; + const char *deviceNo = "NN"; + const char *topo_text = "Topology"; + char *mixer_str = NULL; + int ctl_len; + int ret; + struct snd_kcontrol_new topology_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "?", + .info = msm_pcm_fe_topology_info, + .get = msm_pcm_fe_topology_get, + .put = msm_pcm_fe_topology_put, + .private_value = 0, + }, + }; + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 + + strlen(topo_text) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + + if (!mixer_str) + return -ENOMEM; + + snprintf(mixer_str, ctl_len, "%s %d %s", mixer_ctl_name, + rtd->pcm->device, topo_text); + + topology_control[0].name = mixer_str; + topology_control[0].private_value = rtd->dai_link->id; + ret = snd_soc_add_platform_controls(rtd->platform, topology_control, + ARRAY_SIZE(topology_control)); + msm_pcm_fe_topology[rtd->dai_link->id] = 0; + kfree(mixer_str); + return ret; +} + +static int msm_pcm_playback_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_RX; + int be_id = ucontrol->value.integer.value[3]; + struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000}; + int ret = 0; + + cfg_data.app_type = ucontrol->value.integer.value[0]; + cfg_data.acdb_dev_id = ucontrol->value.integer.value[1]; + if (ucontrol->value.integer.value[2] != 0) + cfg_data.sample_rate = ucontrol->value.integer.value[2]; + pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, &cfg_data); + if (ret < 0) + pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n", + __func__, ret); + return ret; +} + +static int msm_pcm_playback_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_RX; + int be_id = 0; + struct msm_pcm_stream_app_type_cfg cfg_data = {0}; + int ret = 0; + + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + &be_id, &cfg_data); + if (ret < 0) { + pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n", + __func__, ret); + goto done; + } + + ucontrol->value.integer.value[0] = cfg_data.app_type; + ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id; + ucontrol->value.integer.value[2] = cfg_data.sample_rate; + ucontrol->value.integer.value[3] = be_id; + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); +done: + return ret; +} + +static int msm_pcm_capture_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = ucontrol->value.integer.value[3]; + struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000}; + int ret = 0; + + cfg_data.app_type = ucontrol->value.integer.value[0]; + cfg_data.acdb_dev_id = ucontrol->value.integer.value[1]; + if (ucontrol->value.integer.value[2] != 0) + cfg_data.sample_rate = ucontrol->value.integer.value[2]; + pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, &cfg_data); + if (ret < 0) + pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n", + __func__, ret); + + return ret; +} + +static int msm_pcm_capture_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = 0; + struct msm_pcm_stream_app_type_cfg cfg_data = {0}; + int ret = 0; + + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + &be_id, &cfg_data); + if (ret < 0) { + pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n", + __func__, ret); + goto done; + } + + ucontrol->value.integer.value[0] = cfg_data.app_type; + ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id; + ucontrol->value.integer.value[2] = cfg_data.sample_rate; + ucontrol->value.integer.value[3] = be_id; + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); +done: + return ret; +} + +static int msm_pcm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm *pcm = rtd->pcm; + struct snd_pcm_usr *app_type_info; + struct snd_kcontrol *kctl; + const char *playback_mixer_ctl_name = "Audio Stream"; + const char *capture_mixer_ctl_name = "Audio Stream Capture"; + const char *deviceNo = "NN"; + const char *suffix = "App Type Cfg"; + int ctl_len, ret = 0; + + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { + ctl_len = strlen(playback_mixer_ctl_name) + 1 + + strlen(deviceNo) + 1 + + strlen(suffix) + 1; + pr_debug("%s: Playback app type cntrl add\n", __func__); + ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, + NULL, 1, ctl_len, rtd->dai_link->id, + &app_type_info); + if (ret < 0) { + pr_err("%s: playback app type cntrl add failed, err: %d\n", + __func__, ret); + return ret; + } + kctl = app_type_info->kctl; + snprintf(kctl->id.name, ctl_len, "%s %d %s", + playback_mixer_ctl_name, rtd->pcm->device, suffix); + kctl->put = msm_pcm_playback_app_type_cfg_ctl_put; + kctl->get = msm_pcm_playback_app_type_cfg_ctl_get; + } + + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { + ctl_len = strlen(capture_mixer_ctl_name) + 1 + + strlen(deviceNo) + 1 + strlen(suffix) + 1; + pr_debug("%s: Capture app type cntrl add\n", __func__); + ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE, + NULL, 1, ctl_len, rtd->dai_link->id, + &app_type_info); + if (ret < 0) { + pr_err("%s: capture app type cntrl add failed, err: %d\n", + __func__, ret); + return ret; + } + kctl = app_type_info->kctl; + snprintf(kctl->id.name, ctl_len, "%s %d %s", + capture_mixer_ctl_name, rtd->pcm->device, suffix); + kctl->put = msm_pcm_capture_app_type_cfg_ctl_put; + kctl->get = msm_pcm_capture_app_type_cfg_ctl_get; + } + + return 0; +} + + +static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_card *card = rtd->card->snd_card; + struct snd_pcm *pcm = rtd->pcm; + int ret; + + pr_debug("%s , register new control\n", __func__); + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); + + ret = msm_pcm_add_chmap_control(rtd); + if (ret) { + pr_err("%s failed to add chmap cntls\n", __func__); + goto exit; + } + ret = msm_pcm_add_volume_control(rtd); + if (ret) { + pr_err("%s: Could not add pcm Volume Control %d\n", + __func__, ret); + } + + ret = msm_pcm_add_fe_topology_control(rtd); + if (ret) { + pr_err("%s: Could not add pcm topology control %d\n", + __func__, ret); + } + + ret = msm_pcm_add_app_type_controls(rtd); + if (ret) { + pr_err("%s: Could not add app type controls failed %d\n", + __func__, ret); + } + + pcm->nonatomic = true; +exit: + return ret; +} + + +static const struct snd_pcm_ops msm_pcm_ops = { + .open = msm_pcm_open, + .prepare = msm_pcm_prepare, + .copy = msm_pcm_copy, + .hw_params = msm_pcm_hw_params, + .ioctl = msm_pcm_ioctl, + .trigger = msm_pcm_trigger, + .pointer = msm_pcm_pointer, + .mmap = msm_pcm_mmap, + .close = msm_pcm_close, +}; + +static struct snd_soc_platform_driver msm_soc_platform = { + .ops = &msm_pcm_ops, + .pcm_new = msm_asoc_pcm_new, +}; + +static int msm_pcm_probe(struct platform_device *pdev) +{ + int rc; + struct msm_plat_data *pdata; + const char *latency_level; + int perf_mode = LOW_LATENCY_PCM_MODE; + + dev_dbg(&pdev->dev, "Pull mode driver probe\n"); + + if (of_property_read_bool(pdev->dev.of_node, + "qcom,msm-pcm-low-latency")) { + + rc = of_property_read_string(pdev->dev.of_node, + "qcom,latency-level", &latency_level); + if (!rc) { + if (!strcmp(latency_level, "ultra")) + perf_mode = ULTRA_LOW_LATENCY_PCM_MODE; + else if (!strcmp(latency_level, "ull-pp")) + perf_mode = ULL_POST_PROCESSING_PCM_MODE; + } + } + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct msm_plat_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + pdata->perf_mode = perf_mode; + + dev_set_drvdata(&pdev->dev, pdata); + + dev_dbg(&pdev->dev, "%s: dev name %s\n", + __func__, dev_name(&pdev->dev)); + dev_dbg(&pdev->dev, "Pull mode driver register\n"); + rc = snd_soc_register_platform(&pdev->dev, + &msm_soc_platform); + + if (rc) + dev_err(&pdev->dev, "Failed to register pull mode driver\n"); + + return rc; +} + +static int msm_pcm_remove(struct platform_device *pdev) +{ + struct msm_plat_data *pdata; + + dev_dbg(&pdev->dev, "Pull mode remove\n"); + pdata = dev_get_drvdata(&pdev->dev); + devm_kfree(&pdev->dev, pdata); + snd_soc_unregister_platform(&pdev->dev); + return 0; +} +static const struct of_device_id msm_pcm_dt_match[] = { + {.compatible = "qcom,msm-pcm-dsp-noirq"}, + {} +}; +MODULE_DEVICE_TABLE(of, msm_pcm_dt_match); + +static struct platform_driver msm_pcm_driver_noirq = { + .driver = { + .name = "msm-pcm-dsp-noirq", + .owner = THIS_MODULE, + .of_match_table = msm_pcm_dt_match, + }, + .probe = msm_pcm_probe, + .remove = msm_pcm_remove, +}; + +static int __init msm_soc_platform_init(void) +{ + return platform_driver_register(&msm_pcm_driver_noirq); +} +module_init(msm_soc_platform_init); + +static void __exit msm_soc_platform_exit(void) +{ + platform_driver_unregister(&msm_pcm_driver_noirq); +} +module_exit(msm_soc_platform_exit); + +MODULE_DESCRIPTION("PCM NOIRQ module platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c new file mode 100644 index 000000000000..74e99d376049 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c @@ -0,0 +1,1884 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "msm-pcm-q6-v2.h" +#include "msm-pcm-routing-v2.h" +#include "msm-qti-pp-config.h" + +enum stream_state { + IDLE = 0, + STOPPED, + RUNNING, +}; + +static struct audio_locks the_locks; + +#define PCM_MASTER_VOL_MAX_STEPS 0x2000 +static const DECLARE_TLV_DB_LINEAR(msm_pcm_vol_gain, 0, + PCM_MASTER_VOL_MAX_STEPS); + +struct snd_msm { + struct snd_card *card; + struct snd_pcm *pcm; +}; + +#define CMD_EOS_MIN_TIMEOUT_LENGTH 50 +#define CMD_EOS_TIMEOUT_MULTIPLIER (HZ * 50) +#define MAX_PB_COPY_RETRIES 3 + +static struct snd_pcm_hardware msm_pcm_hardware_capture = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .rates = SNDRV_PCM_RATE_8000_384000, + .rate_min = 8000, + .rate_max = 384000, + .channels_min = 1, + .channels_max = 4, + .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * + CAPTURE_MAX_PERIOD_SIZE, + .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE, + .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE, + .periods_min = CAPTURE_MIN_NUM_PERIODS, + .periods_max = CAPTURE_MAX_NUM_PERIODS, + .fifo_size = 0, +}; + +static struct snd_pcm_hardware msm_pcm_hardware_playback = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .rates = SNDRV_PCM_RATE_8000_384000, + .rate_min = 8000, + .rate_max = 384000, + .channels_min = 1, + .channels_max = 8, + .buffer_bytes_max = PLAYBACK_MAX_NUM_PERIODS * + PLAYBACK_MAX_PERIOD_SIZE, + .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE, + .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE, + .periods_min = PLAYBACK_MIN_NUM_PERIODS, + .periods_max = PLAYBACK_MAX_NUM_PERIODS, + .fifo_size = 0, +}; + +/* Conventional and unconventional sample rate supported */ +static unsigned int supported_sample_rates[] = { + 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, + 88200, 96000, 176400, 192000, 352800, 384000 +}; + +static struct snd_pcm_hw_constraint_list constraints_sample_rates = { + .count = ARRAY_SIZE(supported_sample_rates), + .list = supported_sample_rates, + .mask = 0, +}; + +static void msm_pcm_route_event_handler(enum msm_pcm_routing_event event, + void *priv_data) +{ + struct msm_audio *prtd = priv_data; + + WARN_ON(!prtd); + + pr_debug("%s: event %x\n", __func__, event); + + switch (event) { + case MSM_PCM_RT_EVT_BUF_RECFG: + q6asm_cmd(prtd->audio_client, CMD_PAUSE); + q6asm_cmd(prtd->audio_client, CMD_FLUSH); + q6asm_run(prtd->audio_client, 0, 0, 0); + /* fallthrough */ + default: + break; + } +} + +static void event_handler(uint32_t opcode, + uint32_t token, uint32_t *payload, void *priv) +{ + struct msm_audio *prtd = priv; + struct snd_pcm_substream *substream = prtd->substream; + uint32_t *ptrmem = (uint32_t *)payload; + uint32_t idx = 0; + uint32_t size = 0; + uint8_t buf_index; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + + switch (opcode) { + case ASM_DATA_EVENT_WRITE_DONE_V2: { + pr_debug("ASM_DATA_EVENT_WRITE_DONE_V2\n"); + pr_debug("Buffer Consumed = 0x%08x\n", *ptrmem); + prtd->pcm_irq_pos += prtd->pcm_count; + if (atomic_read(&prtd->start)) + snd_pcm_period_elapsed(substream); + atomic_inc(&prtd->out_count); + wake_up(&the_locks.write_wait); + if (!atomic_read(&prtd->start)) + break; + if (!prtd->mmap_flag || prtd->reset_event) + break; + if (q6asm_is_cpu_buf_avail_nolock(IN, + prtd->audio_client, + &size, &idx)) { + pr_debug("%s:writing %d bytes of buffer to dsp 2\n", + __func__, prtd->pcm_count); + q6asm_write_nolock(prtd->audio_client, + prtd->pcm_count, 0, 0, NO_TIMESTAMP); + } + break; + } + case ASM_DATA_EVENT_RENDERED_EOS: + pr_debug("ASM_DATA_EVENT_RENDERED_EOS\n"); + clear_bit(CMD_EOS, &prtd->cmd_pending); + wake_up(&the_locks.eos_wait); + break; + case ASM_DATA_EVENT_READ_DONE_V2: { + pr_debug("ASM_DATA_EVENT_READ_DONE_V2\n"); + buf_index = q6asm_get_buf_index_from_token(token); + pr_debug("%s: token=0x%08x buf_index=0x%08x\n", + __func__, token, buf_index); + prtd->in_frame_info[buf_index].size = payload[4]; + prtd->in_frame_info[buf_index].offset = payload[5]; + /* assume data size = 0 during flushing */ + if (prtd->in_frame_info[buf_index].size) { + prtd->pcm_irq_pos += + prtd->in_frame_info[buf_index].size; + pr_debug("pcm_irq_pos=%d\n", prtd->pcm_irq_pos); + if (atomic_read(&prtd->start)) + snd_pcm_period_elapsed(substream); + if (atomic_read(&prtd->in_count) <= prtd->periods) + atomic_inc(&prtd->in_count); + wake_up(&the_locks.read_wait); + if (prtd->mmap_flag && + q6asm_is_cpu_buf_avail_nolock(OUT, + prtd->audio_client, + &size, &idx) && + (substream->runtime->status->state == + SNDRV_PCM_STATE_RUNNING)) + q6asm_read_nolock(prtd->audio_client); + } else { + pr_debug("%s: reclaim flushed buf in_count %x\n", + __func__, atomic_read(&prtd->in_count)); + prtd->pcm_irq_pos += prtd->pcm_count; + if (prtd->mmap_flag) { + if (q6asm_is_cpu_buf_avail_nolock(OUT, + prtd->audio_client, + &size, &idx) && + (substream->runtime->status->state == + SNDRV_PCM_STATE_RUNNING)) + q6asm_read_nolock(prtd->audio_client); + } else { + atomic_inc(&prtd->in_count); + } + if (atomic_read(&prtd->in_count) == prtd->periods) { + pr_info("%s: reclaimed all bufs\n", __func__); + if (atomic_read(&prtd->start)) + snd_pcm_period_elapsed(substream); + wake_up(&the_locks.read_wait); + } + } + break; + } + case ASM_STREAM_PP_EVENT: + case ASM_STREAM_CMD_ENCDEC_EVENTS: { + pr_debug("%s: ASM_STREAM_EVENT (0x%x)\n", __func__, opcode); + if (!substream) { + pr_err("%s: substream is NULL.\n", __func__); + return; + } + + rtd = substream->private_data; + if (!rtd) { + pr_err("%s: rtd is NULL\n", __func__); + return; + } + + ret = msm_adsp_inform_mixer_ctl(rtd, payload); + if (ret) { + pr_err("%s: failed to inform mixer ctl. err = %d\n", + __func__, ret); + return; + } + + break; + } + case APR_BASIC_RSP_RESULT: { + switch (payload[0]) { + case ASM_SESSION_CMD_RUN_V2: + if (substream->stream + != SNDRV_PCM_STREAM_PLAYBACK) { + atomic_set(&prtd->start, 1); + break; + } + if (prtd->mmap_flag) { + pr_debug("%s:writing %d bytes of buffer to dsp\n", + __func__, + prtd->pcm_count); + q6asm_write_nolock(prtd->audio_client, + prtd->pcm_count, + 0, 0, NO_TIMESTAMP); + } else { + while (atomic_read(&prtd->out_needed)) { + pr_debug("%s:writing %d bytes of buffer to dsp\n", + __func__, + prtd->pcm_count); + q6asm_write_nolock(prtd->audio_client, + prtd->pcm_count, + 0, 0, NO_TIMESTAMP); + atomic_dec(&prtd->out_needed); + wake_up(&the_locks.write_wait); + }; + } + atomic_set(&prtd->start, 1); + break; + case ASM_STREAM_CMD_REGISTER_PP_EVENTS: + pr_debug("%s: ASM_STREAM_CMD_REGISTER_PP_EVENTS:", + __func__); + break; + default: + pr_debug("%s:Payload = [0x%x]stat[0x%x]\n", + __func__, payload[0], payload[1]); + break; + } + } + break; + case RESET_EVENTS: + pr_debug("%s RESET_EVENTS\n", __func__); + prtd->pcm_irq_pos += prtd->pcm_count; + atomic_inc(&prtd->out_count); + atomic_inc(&prtd->in_count); + prtd->reset_event = true; + if (atomic_read(&prtd->start)) + snd_pcm_period_elapsed(substream); + wake_up(&the_locks.eos_wait); + wake_up(&the_locks.write_wait); + wake_up(&the_locks.read_wait); + break; + default: + pr_debug("Not Supported Event opcode[0x%x]\n", opcode); + break; + } +} + +static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; + struct msm_audio *prtd = runtime->private_data; + struct msm_plat_data *pdata; + struct snd_pcm_hw_params *params; + int ret; + uint32_t fmt_type = FORMAT_LINEAR_PCM; + uint16_t bits_per_sample; + uint16_t sample_word_size; + + pdata = (struct msm_plat_data *) + dev_get_drvdata(soc_prtd->platform->dev); + if (!pdata) { + pr_err("%s: platform data not populated\n", __func__); + return -EINVAL; + } + if (!prtd || !prtd->audio_client) { + pr_err("%s: private data null or audio client freed\n", + __func__); + return -EINVAL; + } + params = &soc_prtd->dpcm[substream->stream].hw_params; + + pr_debug("%s\n", __func__); + prtd->pcm_size = snd_pcm_lib_buffer_bytes(substream); + prtd->pcm_count = snd_pcm_lib_period_bytes(substream); + prtd->pcm_irq_pos = 0; + /* rate and channels are sent to audio driver */ + prtd->samp_rate = runtime->rate; + prtd->channel_mode = runtime->channels; + if (prtd->enabled) + return 0; + + prtd->audio_client->perf_mode = pdata->perf_mode; + pr_debug("%s: perf: %x\n", __func__, pdata->perf_mode); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S32_LE: + bits_per_sample = 32; + sample_word_size = 32; + break; + case SNDRV_PCM_FORMAT_S24_LE: + bits_per_sample = 24; + sample_word_size = 32; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + bits_per_sample = 24; + sample_word_size = 24; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bits_per_sample = 16; + sample_word_size = 16; + break; + } + if (prtd->compress_enable) { + fmt_type = FORMAT_GEN_COMPR; + pr_debug("%s: Compressed enabled!\n", __func__); + ret = q6asm_open_write_compressed(prtd->audio_client, fmt_type, + COMPRESSED_PASSTHROUGH_GEN); + if (ret < 0) { + pr_err("%s: q6asm_open_write_compressed failed (%d)\n", + __func__, ret); + q6asm_audio_client_free(prtd->audio_client); + prtd->audio_client = NULL; + return -ENOMEM; + } + } else { + ret = q6asm_open_write_v4(prtd->audio_client, + fmt_type, bits_per_sample); + + if (ret < 0) { + pr_err("%s: q6asm_open_write_v4 failed (%d)\n", + __func__, ret); + q6asm_audio_client_free(prtd->audio_client); + prtd->audio_client = NULL; + return -ENOMEM; + } + + ret = q6asm_send_cal(prtd->audio_client); + if (ret < 0) + pr_debug("%s : Send cal failed : %d", __func__, ret); + } + pr_debug("%s: session ID %d\n", __func__, + prtd->audio_client->session); + prtd->session_id = prtd->audio_client->session; + + if (prtd->compress_enable) { + ret = msm_pcm_routing_reg_phy_compr_stream( + soc_prtd->dai_link->id, + prtd->audio_client->perf_mode, + prtd->session_id, + SNDRV_PCM_STREAM_PLAYBACK, + COMPRESSED_PASSTHROUGH_GEN); + } else { + ret = msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->id, + prtd->audio_client->perf_mode, + prtd->session_id, substream->stream); + } + if (ret) { + pr_err("%s: stream reg failed ret:%d\n", __func__, ret); + return ret; + } + if (prtd->compress_enable) { + ret = q6asm_media_format_block_gen_compr( + prtd->audio_client, runtime->rate, + runtime->channels, !prtd->set_channel_map, + prtd->channel_map, bits_per_sample); + } else { + ret = q6asm_media_format_block_multi_ch_pcm_v4( + prtd->audio_client, runtime->rate, + runtime->channels, !prtd->set_channel_map, + prtd->channel_map, bits_per_sample, + sample_word_size, ASM_LITTLE_ENDIAN, + DEFAULT_QF); + } + if (ret < 0) + pr_info("%s: CMD Format block failed\n", __func__); + + atomic_set(&prtd->out_count, runtime->periods); + + prtd->enabled = 1; + prtd->cmd_pending = 0; + prtd->cmd_interrupt = 0; + + return 0; +} + +static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_audio *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; + struct msm_plat_data *pdata; + struct snd_pcm_hw_params *params; + struct msm_pcm_routing_evt event; + int ret = 0; + int i = 0; + uint16_t bits_per_sample = 16; + uint16_t sample_word_size; + + pdata = (struct msm_plat_data *) + dev_get_drvdata(soc_prtd->platform->dev); + if (!pdata) { + pr_err("%s: platform data not populated\n", __func__); + return -EINVAL; + } + if (!prtd || !prtd->audio_client) { + pr_err("%s: private data null or audio client freed\n", + __func__); + return -EINVAL; + } + + if (prtd->enabled == IDLE) { + pr_debug("%s:perf_mode=%d periods=%d\n", __func__, + pdata->perf_mode, runtime->periods); + params = &soc_prtd->dpcm[substream->stream].hw_params; + if ((params_format(params) == SNDRV_PCM_FORMAT_S24_LE) || + (params_format(params) == SNDRV_PCM_FORMAT_S24_3LE)) + bits_per_sample = 24; + else if (params_format(params) == SNDRV_PCM_FORMAT_S32_LE) + bits_per_sample = 32; + + /* ULL mode is not supported in capture path */ + if (pdata->perf_mode == LEGACY_PCM_MODE) + prtd->audio_client->perf_mode = LEGACY_PCM_MODE; + else + prtd->audio_client->perf_mode = LOW_LATENCY_PCM_MODE; + + pr_debug("%s Opening %d-ch PCM read stream, perf_mode %d\n", + __func__, params_channels(params), + prtd->audio_client->perf_mode); + + ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM, + bits_per_sample, false); + if (ret < 0) { + pr_err("%s: q6asm_open_read failed\n", __func__); + q6asm_audio_client_free(prtd->audio_client); + prtd->audio_client = NULL; + return -ENOMEM; + } + + ret = q6asm_send_cal(prtd->audio_client); + if (ret < 0) + pr_debug("%s : Send cal failed : %d", __func__, ret); + + pr_debug("%s: session ID %d\n", + __func__, prtd->audio_client->session); + prtd->session_id = prtd->audio_client->session; + event.event_func = msm_pcm_route_event_handler; + event.priv_data = (void *) prtd; + ret = msm_pcm_routing_reg_phy_stream_v2( + soc_prtd->dai_link->id, + prtd->audio_client->perf_mode, + prtd->session_id, substream->stream, + event); + if (ret) { + pr_err("%s: stream reg failed ret:%d\n", __func__, ret); + return ret; + } + } + + prtd->pcm_size = snd_pcm_lib_buffer_bytes(substream); + prtd->pcm_count = snd_pcm_lib_period_bytes(substream); + prtd->pcm_irq_pos = 0; + /* rate and channels are sent to audio driver */ + prtd->samp_rate = runtime->rate; + prtd->channel_mode = runtime->channels; + + if (prtd->enabled == IDLE || prtd->enabled == STOPPED) { + for (i = 0; i < runtime->periods; i++) + q6asm_read(prtd->audio_client); + prtd->periods = runtime->periods; + } + + if (prtd->enabled != IDLE) + return 0; + + switch (runtime->format) { + case SNDRV_PCM_FORMAT_S32_LE: + bits_per_sample = 32; + sample_word_size = 32; + break; + case SNDRV_PCM_FORMAT_S24_LE: + bits_per_sample = 24; + sample_word_size = 32; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + bits_per_sample = 24; + sample_word_size = 24; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bits_per_sample = 16; + sample_word_size = 16; + break; + } + + pr_debug("%s: Samp_rate = %d Channel = %d bit width = %d, word size = %d\n", + __func__, prtd->samp_rate, prtd->channel_mode, + bits_per_sample, sample_word_size); + ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client, + prtd->samp_rate, + prtd->channel_mode, + bits_per_sample, + sample_word_size, + ASM_LITTLE_ENDIAN, + DEFAULT_QF); + if (ret < 0) + pr_debug("%s: cmd cfg pcm was block failed", __func__); + + prtd->enabled = RUNNING; + + return ret; +} + +static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + int ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_audio *prtd = runtime->private_data; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + pr_debug("%s: Trigger start\n", __func__); + ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0); + break; + case SNDRV_PCM_TRIGGER_STOP: + pr_debug("SNDRV_PCM_TRIGGER_STOP\n"); + atomic_set(&prtd->start, 0); + if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) { + prtd->enabled = STOPPED; + ret = q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE); + break; + } + /* pending CMD_EOS isn't expected */ + WARN_ON_ONCE(test_bit(CMD_EOS, &prtd->cmd_pending)); + set_bit(CMD_EOS, &prtd->cmd_pending); + ret = q6asm_cmd_nowait(prtd->audio_client, CMD_EOS); + if (ret) + clear_bit(CMD_EOS, &prtd->cmd_pending); + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + pr_debug("SNDRV_PCM_TRIGGER_PAUSE\n"); + ret = q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE); + atomic_set(&prtd->start, 0); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int msm_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; + struct msm_audio *prtd; + int ret = 0; + + prtd = kzalloc(sizeof(struct msm_audio), GFP_KERNEL); + if (prtd == NULL) + return -ENOMEM; + + prtd->substream = substream; + prtd->audio_client = q6asm_audio_client_alloc( + (app_cb)event_handler, prtd); + if (!prtd->audio_client) { + pr_info("%s: Could not allocate memory\n", __func__); + kfree(prtd); + return -ENOMEM; + } + + prtd->audio_client->dev = soc_prtd->platform->dev; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + runtime->hw = msm_pcm_hardware_playback; + + /* Capture path */ + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + runtime->hw = msm_pcm_hardware_capture; + else { + pr_err("Invalid Stream type %d\n", substream->stream); + return -EINVAL; + } + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_sample_rates); + if (ret < 0) + pr_info("snd_pcm_hw_constraint_list failed\n"); + /* Ensure that buffer size is a multiple of period size */ + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) + pr_info("snd_pcm_hw_constraint_integer failed\n"); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, + PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE, + PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE); + if (ret < 0) { + pr_err("constraint for buffer bytes min max ret = %d\n", + ret); + } + } + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + ret = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, + CAPTURE_MIN_NUM_PERIODS * CAPTURE_MIN_PERIOD_SIZE, + CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE); + if (ret < 0) { + pr_err("constraint for buffer bytes min max ret = %d\n", + ret); + } + } + ret = snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); + if (ret < 0) { + pr_err("constraint for period bytes step ret = %d\n", + ret); + } + ret = snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); + if (ret < 0) { + pr_err("constraint for buffer bytes step ret = %d\n", + ret); + } + + prtd->enabled = IDLE; + prtd->dsp_cnt = 0; + prtd->set_channel_map = false; + prtd->reset_event = false; + runtime->private_data = prtd; + msm_adsp_init_mixer_ctl_pp_event_queue(soc_prtd); + + return 0; +} + +static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, + snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames) +{ + int ret = 0; + int fbytes = 0; + int xfer = 0; + char *bufptr = NULL; + void *data = NULL; + uint32_t idx = 0; + uint32_t size = 0; + uint32_t retries = 0; + + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_audio *prtd = runtime->private_data; + + fbytes = frames_to_bytes(runtime, frames); + pr_debug("%s: prtd->out_count = %d\n", + __func__, atomic_read(&prtd->out_count)); + + while ((fbytes > 0) && (retries < MAX_PB_COPY_RETRIES)) { + if (prtd->reset_event) { + pr_err("%s: In SSR return ENETRESET before wait\n", + __func__); + return -ENETRESET; + } + + ret = wait_event_timeout(the_locks.write_wait, + (atomic_read(&prtd->out_count)), 5 * HZ); + if (!ret) { + pr_err("%s: wait_event_timeout failed\n", __func__); + ret = -ETIMEDOUT; + goto fail; + } + ret = 0; + + if (prtd->reset_event) { + pr_err("%s: In SSR return ENETRESET after wait\n", + __func__); + return -ENETRESET; + } + + if (!atomic_read(&prtd->out_count)) { + pr_err("%s: pcm stopped out_count 0\n", __func__); + return 0; + } + + data = q6asm_is_cpu_buf_avail(IN, prtd->audio_client, &size, + &idx); + if (data == NULL) { + retries++; + continue; + } else { + retries = 0; + } + + if (fbytes > size) + xfer = size; + else + xfer = fbytes; + + bufptr = data; + if (bufptr) { + pr_debug("%s:fbytes =%d: xfer=%d size=%d\n", + __func__, fbytes, xfer, size); + if (copy_from_user(bufptr, buf, xfer)) { + ret = -EFAULT; + pr_err("%s: copy_from_user failed\n", + __func__); + q6asm_cpu_buf_release(IN, prtd->audio_client); + goto fail; + } + buf += xfer; + fbytes -= xfer; + pr_debug("%s:fbytes = %d: xfer=%d\n", __func__, fbytes, + xfer); + if (atomic_read(&prtd->start)) { + pr_debug("%s:writing %d bytes of buffer to dsp\n", + __func__, xfer); + ret = q6asm_write(prtd->audio_client, xfer, + 0, 0, NO_TIMESTAMP); + if (ret < 0) { + ret = -EFAULT; + q6asm_cpu_buf_release(IN, + prtd->audio_client); + goto fail; + } + } else + atomic_inc(&prtd->out_needed); + atomic_dec(&prtd->out_count); + } + } +fail: + if (retries >= MAX_PB_COPY_RETRIES) + ret = -ENOMEM; + + return ret; +} + +static int msm_pcm_playback_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; + struct msm_audio *prtd = runtime->private_data; + uint32_t timeout; + int dir = 0; + int ret = 0; + + pr_debug("%s: cmd_pending 0x%lx\n", __func__, prtd->cmd_pending); + + if (prtd->audio_client) { + dir = IN; + + /* determine timeout length */ + if (runtime->frame_bits == 0 || runtime->rate == 0) { + timeout = CMD_EOS_MIN_TIMEOUT_LENGTH; + } else { + timeout = (runtime->period_size * + CMD_EOS_TIMEOUT_MULTIPLIER) / + ((runtime->frame_bits / 8) * + runtime->rate); + if (timeout < CMD_EOS_MIN_TIMEOUT_LENGTH) + timeout = CMD_EOS_MIN_TIMEOUT_LENGTH; + } + pr_debug("%s: CMD_EOS timeout is %d\n", __func__, timeout); + + ret = wait_event_timeout(the_locks.eos_wait, + !test_bit(CMD_EOS, &prtd->cmd_pending), + timeout); + if (!ret) + pr_err("%s: CMD_EOS failed, cmd_pending 0x%lx\n", + __func__, prtd->cmd_pending); + q6asm_cmd(prtd->audio_client, CMD_CLOSE); + q6asm_audio_client_buf_free_contiguous(dir, + prtd->audio_client); + q6asm_audio_client_free(prtd->audio_client); + } + msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->id, + SNDRV_PCM_STREAM_PLAYBACK); + msm_adsp_clean_mixer_ctl_pp_event_queue(soc_prtd); + kfree(prtd); + runtime->private_data = NULL; + + return 0; +} + +static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, + int channel, snd_pcm_uframes_t hwoff, void __user *buf, + snd_pcm_uframes_t frames) +{ + int ret = 0; + int fbytes = 0; + int xfer; + char *bufptr; + void *data = NULL; + static uint32_t idx; + static uint32_t size; + uint32_t offset = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_audio *prtd = substream->runtime->private_data; + + + pr_debug("%s\n", __func__); + fbytes = frames_to_bytes(runtime, frames); + + pr_debug("appl_ptr %d\n", (int)runtime->control->appl_ptr); + pr_debug("hw_ptr %d\n", (int)runtime->status->hw_ptr); + pr_debug("avail_min %d\n", (int)runtime->control->avail_min); + + if (prtd->reset_event) { + pr_err("%s: In SSR return ENETRESET before wait\n", __func__); + return -ENETRESET; + } + ret = wait_event_timeout(the_locks.read_wait, + (atomic_read(&prtd->in_count)), 5 * HZ); + if (!ret) { + pr_debug("%s: wait_event_timeout failed\n", __func__); + goto fail; + } + if (prtd->reset_event) { + pr_err("%s: In SSR return ENETRESET after wait\n", __func__); + return -ENETRESET; + } + if (!atomic_read(&prtd->in_count)) { + pr_debug("%s: pcm stopped in_count 0\n", __func__); + return 0; + } + pr_debug("Checking if valid buffer is available...%pK\n", + data); + data = q6asm_is_cpu_buf_avail(OUT, prtd->audio_client, &size, &idx); + bufptr = data; + pr_debug("Size = %d\n", size); + pr_debug("fbytes = %d\n", fbytes); + pr_debug("idx = %d\n", idx); + if (bufptr) { + xfer = fbytes; + if (xfer > size) + xfer = size; + offset = prtd->in_frame_info[idx].offset; + pr_debug("Offset value = %d\n", offset); + if (copy_to_user(buf, bufptr+offset, xfer)) { + pr_err("Failed to copy buf to user\n"); + ret = -EFAULT; + q6asm_cpu_buf_release(OUT, prtd->audio_client); + goto fail; + } + fbytes -= xfer; + size -= xfer; + prtd->in_frame_info[idx].offset += xfer; + pr_debug("%s:fbytes = %d: size=%d: xfer=%d\n", + __func__, fbytes, size, xfer); + pr_debug(" Sending next buffer to dsp\n"); + memset(&prtd->in_frame_info[idx], 0, + sizeof(struct msm_audio_in_frame_info)); + atomic_dec(&prtd->in_count); + ret = q6asm_read(prtd->audio_client); + if (ret < 0) { + pr_err("q6asm read failed\n"); + ret = -EFAULT; + q6asm_cpu_buf_release(OUT, prtd->audio_client); + goto fail; + } + } else + pr_err("No valid buffer\n"); + + pr_debug("Returning from capture_copy... %d\n", ret); +fail: + return ret; +} + +static int msm_pcm_capture_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; + struct msm_audio *prtd = runtime->private_data; + int dir = OUT; + + pr_debug("%s\n", __func__); + if (prtd->audio_client) { + q6asm_cmd(prtd->audio_client, CMD_CLOSE); + q6asm_audio_client_buf_free_contiguous(dir, + prtd->audio_client); + q6asm_audio_client_free(prtd->audio_client); + } + + msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->id, + SNDRV_PCM_STREAM_CAPTURE); + kfree(prtd); + runtime->private_data = NULL; + + return 0; +} + +static int msm_pcm_copy(struct snd_pcm_substream *substream, int a, + snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames) +{ + int ret = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ret = msm_pcm_playback_copy(substream, a, hwoff, buf, frames); + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ret = msm_pcm_capture_copy(substream, a, hwoff, buf, frames); + return ret; +} + +static int msm_pcm_close(struct snd_pcm_substream *substream) +{ + int ret = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ret = msm_pcm_playback_close(substream); + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ret = msm_pcm_capture_close(substream); + return ret; +} + +static int msm_pcm_prepare(struct snd_pcm_substream *substream) +{ + int ret = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ret = msm_pcm_playback_prepare(substream); + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ret = msm_pcm_capture_prepare(substream); + return ret; +} + +static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream) +{ + + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_audio *prtd = runtime->private_data; + + if (prtd->pcm_irq_pos >= prtd->pcm_size) + prtd->pcm_irq_pos = 0; + + pr_debug("pcm_irq_pos = %d\n", prtd->pcm_irq_pos); + return bytes_to_frames(runtime, (prtd->pcm_irq_pos)); +} + +static int msm_pcm_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_audio *prtd = runtime->private_data; + struct audio_client *ac = prtd->audio_client; + struct audio_port_data *apd = ac->port; + struct audio_buffer *ab; + int dir = -1; + + prtd->mmap_flag = 1; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dir = IN; + else + dir = OUT; + ab = &(apd[dir].buf[0]); + + return msm_audio_ion_mmap(ab, vma); +} + +static int msm_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_audio *prtd = runtime->private_data; + struct snd_dma_buffer *dma_buf = &substream->dma_buffer; + struct audio_buffer *buf; + int dir, ret; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dir = IN; + else + dir = OUT; + ret = q6asm_audio_client_buf_alloc_contiguous(dir, + prtd->audio_client, + (params_buffer_bytes(params) / params_periods(params)), + params_periods(params)); + if (ret < 0) { + pr_err("Audio Start: Buffer Allocation failed rc = %d\n", + ret); + return -ENOMEM; + } + buf = prtd->audio_client->port[dir].buf; + if (buf == NULL || buf[0].data == NULL) + return -ENOMEM; + + pr_debug("%s:buf = %pK\n", __func__, buf); + dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; + dma_buf->dev.dev = substream->pcm->card->dev; + dma_buf->private_data = NULL; + dma_buf->area = buf[0].data; + dma_buf->addr = buf[0].phys; + dma_buf->bytes = params_buffer_bytes(params); + if (!dma_buf->area) + return -ENOMEM; + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + return 0; +} + +static const struct snd_pcm_ops msm_pcm_ops = { + .open = msm_pcm_open, + .copy = msm_pcm_copy, + .hw_params = msm_pcm_hw_params, + .close = msm_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .prepare = msm_pcm_prepare, + .trigger = msm_pcm_trigger, + .pointer = msm_pcm_pointer, + .mmap = msm_pcm_mmap, +}; + +static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *pcm = snd_kcontrol_chip(kcontrol); + struct snd_soc_platform *platform = snd_soc_component_to_platform(pcm); + struct msm_plat_data *pdata = dev_get_drvdata(platform->dev); + struct snd_pcm_substream *substream; + struct msm_audio *prtd; + int ret = 0; + struct msm_adsp_event_data *event_data = NULL; + + if (!pdata) { + pr_err("%s pdata is NULL\n", __func__); + ret = -ENODEV; + goto done; + } + + substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + if (!substream) { + pr_err("%s substream not found\n", __func__); + ret = -EINVAL; + goto done; + } + + if (!substream->runtime) { + pr_err("%s substream runtime not found\n", __func__); + ret = -EINVAL; + goto done; + } + + prtd = substream->runtime->private_data; + if (prtd->audio_client == NULL) { + pr_err("%s prtd is null.\n", __func__); + ret = -EINVAL; + goto done; + } + + event_data = (struct msm_adsp_event_data *)ucontrol->value.bytes.data; + if ((event_data->event_type < ADSP_STREAM_PP_EVENT) || + (event_data->event_type >= ADSP_STREAM_EVENT_MAX)) { + pr_err("%s: invalid event_type=%d", + __func__, event_data->event_type); + ret = -EINVAL; + goto done; + } + + if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >= + sizeof(ucontrol->value.bytes.data)) { + pr_err("%s param length=%d exceeds limit", + __func__, event_data->payload_len); + ret = -EINVAL; + goto done; + } + + ret = q6asm_send_stream_cmd(prtd->audio_client, event_data); + if (ret < 0) + pr_err("%s: failed to send stream event cmd, err = %d\n", + __func__, ret); +done: + return ret; +} + +static int msm_pcm_add_audio_adsp_stream_cmd_control( + struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = DSP_STREAM_CMD; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len = 0, ret = 0; + struct snd_kcontrol_new fe_audio_adsp_stream_cmd_config_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_adsp_stream_cmd_info, + .put = msm_pcm_adsp_stream_cmd_put, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s rtd is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + if (!mixer_str) { + ret = -ENOMEM; + goto done; + } + + snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device); + fe_audio_adsp_stream_cmd_config_control[0].name = mixer_str; + fe_audio_adsp_stream_cmd_config_control[0].private_value = + rtd->dai_link->id; + pr_debug("Registering new mixer ctl %s\n", mixer_str); + ret = snd_soc_add_platform_controls(rtd->platform, + fe_audio_adsp_stream_cmd_config_control, + ARRAY_SIZE(fe_audio_adsp_stream_cmd_config_control)); + if (ret < 0) + pr_err("%s: failed add ctl %s. err = %d\n", + __func__, mixer_str, ret); + + kfree(mixer_str); +done: + return ret; +} + +static int msm_pcm_add_audio_adsp_stream_callback_control( + struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = DSP_STREAM_CALLBACK; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len = 0, ret = 0; + struct snd_kcontrol *kctl; + + struct snd_kcontrol_new fe_audio_adsp_callback_config_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_adsp_stream_callback_info, + .get = msm_adsp_stream_callback_get, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s NULL rtd\n", __func__); + ret = -EINVAL; + goto done; + } + + pr_debug("%s: added new pcm FE with name %s, id %d, cpu dai %s, device no %d\n", + __func__, rtd->dai_link->name, rtd->dai_link->id, + rtd->dai_link->cpu_dai_name, rtd->pcm->device); + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + if (!mixer_str) { + ret = -ENOMEM; + goto done; + } + + snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device); + fe_audio_adsp_callback_config_control[0].name = mixer_str; + fe_audio_adsp_callback_config_control[0].private_value = + rtd->dai_link->id; + pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); + ret = snd_soc_add_platform_controls(rtd->platform, + fe_audio_adsp_callback_config_control, + ARRAY_SIZE(fe_audio_adsp_callback_config_control)); + if (ret < 0) { + pr_err("%s: failed to add ctl %s. err = %d\n", + __func__, mixer_str, ret); + ret = -EINVAL; + goto free_mixer_str; + } + + kctl = snd_soc_card_get_kcontrol(rtd->card, mixer_str); + if (!kctl) { + pr_err("%s: failed to get kctl %s.\n", __func__, mixer_str); + ret = -EINVAL; + goto free_mixer_str; + } + + kctl->private_data = NULL; + +free_mixer_str: + kfree(mixer_str); +done: + return ret; +} + +static int msm_pcm_set_volume(struct msm_audio *prtd, uint32_t volume) +{ + int rc = 0; + + if (prtd && prtd->audio_client) { + pr_debug("%s: channels %d volume 0x%x\n", __func__, + prtd->channel_mode, volume); + rc = q6asm_set_volume(prtd->audio_client, volume); + if (rc < 0) { + pr_err("%s: Send Volume command failed rc=%d\n", + __func__, rc); + } + } + return rc; +} + +static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol); + struct snd_pcm_substream *substream = + vol->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + struct msm_audio *prtd; + + pr_debug("%s\n", __func__); + if (!substream) { + pr_err("%s substream not found\n", __func__); + return -ENODEV; + } + if (!substream->runtime) { + pr_err("%s substream runtime not found\n", __func__); + return 0; + } + prtd = substream->runtime->private_data; + if (prtd) + ucontrol->value.integer.value[0] = prtd->volume; + return 0; +} + +static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol); + struct snd_pcm_substream *substream = + vol->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + struct msm_audio *prtd; + int volume = ucontrol->value.integer.value[0]; + + pr_debug("%s: volume : 0x%x\n", __func__, volume); + if (!substream) { + pr_err("%s substream not found\n", __func__); + return -ENODEV; + } + if (!substream->runtime) { + pr_err("%s substream runtime not found\n", __func__); + return 0; + } + prtd = substream->runtime->private_data; + if (prtd) { + rc = msm_pcm_set_volume(prtd, volume); + prtd->volume = volume; + } + return rc; +} + +static int msm_pcm_add_volume_control(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + struct snd_pcm *pcm = rtd->pcm; + struct snd_pcm_volume *volume_info; + struct snd_kcontrol *kctl; + + dev_dbg(rtd->dev, "%s, Volume control add\n", __func__); + ret = snd_pcm_add_volume_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, + NULL, 1, rtd->dai_link->id, + &volume_info); + if (ret < 0) { + pr_err("%s volume control failed ret %d\n", __func__, ret); + return ret; + } + kctl = volume_info->kctl; + kctl->put = msm_pcm_volume_ctl_put; + kctl->get = msm_pcm_volume_ctl_get; + kctl->tlv.p = msm_pcm_vol_gain; + return 0; +} + +static int msm_pcm_compress_ctl_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0x2000; + return 0; +} + +static int msm_pcm_compress_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + struct snd_soc_platform *platform = snd_soc_component_to_platform(comp); + struct msm_plat_data *pdata = dev_get_drvdata(platform->dev); + struct snd_pcm_substream *substream; + struct msm_audio *prtd; + + if (!pdata) { + pr_err("%s pdata is NULL\n", __func__); + return -ENODEV; + } + substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + if (!substream) { + pr_err("%s substream not found\n", __func__); + return -EINVAL; + } + if (!substream->runtime) { + pr_err("%s substream runtime not found\n", __func__); + return 0; + } + prtd = substream->runtime->private_data; + if (prtd) + ucontrol->value.integer.value[0] = prtd->compress_enable; + return 0; +} + +static int msm_pcm_compress_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + struct snd_soc_platform *platform = snd_soc_component_to_platform(comp); + struct msm_plat_data *pdata = dev_get_drvdata(platform->dev); + struct snd_pcm_substream *substream; + struct msm_audio *prtd; + int compress = ucontrol->value.integer.value[0]; + + if (!pdata) { + pr_err("%s pdata is NULL\n", __func__); + return -ENODEV; + } + substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + pr_debug("%s: compress : 0x%x\n", __func__, compress); + if (!substream) { + pr_err("%s substream not found\n", __func__); + return -EINVAL; + } + if (!substream->runtime) { + pr_err("%s substream runtime not found\n", __func__); + return 0; + } + prtd = substream->runtime->private_data; + if (prtd) { + pr_debug("%s: setting compress flag to 0x%x\n", + __func__, compress); + prtd->compress_enable = compress; + } + return rc; +} + +static int msm_pcm_add_compress_control(struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = "Playback "; + const char *mixer_ctl_end_name = " Compress"; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len; + int ret = 0; + struct msm_plat_data *pdata; + struct snd_kcontrol_new pcm_compress_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_pcm_compress_ctl_info, + .get = msm_pcm_compress_ctl_get, + .put = msm_pcm_compress_ctl_put, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s: NULL rtd\n", __func__); + return -EINVAL; + } + + ctl_len = strlen(mixer_ctl_name) + strlen(deviceNo) + + strlen(mixer_ctl_end_name) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + + if (!mixer_str) + return -ENOMEM; + + snprintf(mixer_str, ctl_len, "%s%d%s", mixer_ctl_name, + rtd->pcm->device, mixer_ctl_end_name); + + pcm_compress_control[0].name = mixer_str; + pcm_compress_control[0].private_value = rtd->dai_link->id; + pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); + pdata = dev_get_drvdata(rtd->platform->dev); + if (pdata) { + if (!pdata->pcm) { + pdata->pcm = rtd->pcm; + snd_soc_add_platform_controls(rtd->platform, + pcm_compress_control, + ARRAY_SIZE + (pcm_compress_control)); + pr_debug("%s: add control success plt = %pK\n", + __func__, rtd->platform); + } + } else { + pr_err("%s: NULL pdata\n", __func__); + ret = -EINVAL; + } + kfree(mixer_str); + return ret; +} + +static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int i; + struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); + unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + struct snd_pcm_substream *substream; + struct msm_audio *prtd; + + pr_debug("%s", __func__); + substream = snd_pcm_chmap_substream(info, idx); + if (!substream) + return -ENODEV; + if (!substream->runtime) + return 0; + + prtd = substream->runtime->private_data; + if (prtd) { + prtd->set_channel_map = true; + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + prtd->channel_map[i] = + (char)(ucontrol->value.integer.value[i]); + } + return 0; +} + +static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int i; + struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); + unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + struct snd_pcm_substream *substream; + struct msm_audio *prtd; + + pr_debug("%s", __func__); + substream = snd_pcm_chmap_substream(info, idx); + if (!substream) + return -ENODEV; + memset(ucontrol->value.integer.value, 0, + sizeof(ucontrol->value.integer.value)); + if (!substream->runtime) + return 0; /* no channels set */ + + prtd = substream->runtime->private_data; + + if (prtd && prtd->set_channel_map == true) { + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + ucontrol->value.integer.value[i] = + (int)prtd->channel_map[i]; + } else { + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + ucontrol->value.integer.value[i] = 0; + } + + return 0; +} + +static int msm_pcm_add_chmap_controls(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm *pcm = rtd->pcm; + struct snd_pcm_chmap *chmap_info; + struct snd_kcontrol *kctl; + char device_num[12]; + int i, ret = 0; + + pr_debug("%s, Channel map cntrl add\n", __func__); + ret = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, + snd_pcm_std_chmaps, + PCM_FORMAT_MAX_NUM_CHANNEL, 0, + &chmap_info); + if (ret < 0) { + pr_err("%s, channel map cntrl add failed\n", __func__); + return ret; + } + kctl = chmap_info->kctl; + for (i = 0; i < kctl->count; i++) + kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE; + snprintf(device_num, sizeof(device_num), "%d", pcm->device); + strlcat(kctl->id.name, device_num, sizeof(kctl->id.name)); + pr_debug("%s, Overwriting channel map control name to: %s\n", + __func__, kctl->id.name); + kctl->put = msm_pcm_chmap_ctl_put; + kctl->get = msm_pcm_chmap_ctl_get; + return 0; +} + +static int msm_pcm_playback_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_RX; + int be_id = ucontrol->value.integer.value[3]; + struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000}; + int ret = 0; + + cfg_data.app_type = ucontrol->value.integer.value[0]; + cfg_data.acdb_dev_id = ucontrol->value.integer.value[1]; + if (ucontrol->value.integer.value[2] != 0) + cfg_data.sample_rate = ucontrol->value.integer.value[2]; + pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, &cfg_data); + if (ret < 0) + pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n", + __func__, ret); + + return ret; +} + +static int msm_pcm_playback_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_RX; + int be_id = 0; + struct msm_pcm_stream_app_type_cfg cfg_data = {0}; + int ret = 0; + + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + &be_id, &cfg_data); + if (ret < 0) { + pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n", + __func__, ret); + goto done; + } + + ucontrol->value.integer.value[0] = cfg_data.app_type; + ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id; + ucontrol->value.integer.value[2] = cfg_data.sample_rate; + ucontrol->value.integer.value[3] = be_id; + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); +done: + return ret; +} + +static int msm_pcm_capture_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = ucontrol->value.integer.value[3]; + struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000}; + int ret = 0; + + cfg_data.app_type = ucontrol->value.integer.value[0]; + cfg_data.acdb_dev_id = ucontrol->value.integer.value[1]; + if (ucontrol->value.integer.value[2] != 0) + cfg_data.sample_rate = ucontrol->value.integer.value[2]; + pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, &cfg_data); + if (ret < 0) + pr_err("%s: msm_pcm_routing_reg_stream_app_type_cfg failed returned %d\n", + __func__, ret); + + return ret; +} + +static int msm_pcm_capture_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = 0; + struct msm_pcm_stream_app_type_cfg cfg_data = {0}; + int ret = 0; + + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + &be_id, &cfg_data); + if (ret < 0) { + pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n", + __func__, ret); + goto done; + } + + ucontrol->value.integer.value[0] = cfg_data.app_type; + ucontrol->value.integer.value[1] = cfg_data.acdb_dev_id; + ucontrol->value.integer.value[2] = cfg_data.sample_rate; + ucontrol->value.integer.value[3] = be_id; + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); +done: + return ret; +} + +static int msm_pcm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm *pcm = rtd->pcm; + struct snd_pcm_usr *app_type_info; + struct snd_kcontrol *kctl; + const char *playback_mixer_ctl_name = "Audio Stream"; + const char *capture_mixer_ctl_name = "Audio Stream Capture"; + const char *deviceNo = "NN"; + const char *suffix = "App Type Cfg"; + int ctl_len, ret = 0; + + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { + ctl_len = strlen(playback_mixer_ctl_name) + 1 + + strlen(deviceNo) + 1 + strlen(suffix) + 1; + pr_debug("%s: Playback app type cntrl add\n", __func__); + ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, + NULL, 1, ctl_len, rtd->dai_link->id, + &app_type_info); + if (ret < 0) { + pr_err("%s: playback app type cntrl add failed: %d\n", + __func__, ret); + return ret; + } + kctl = app_type_info->kctl; + snprintf(kctl->id.name, ctl_len, "%s %d %s", + playback_mixer_ctl_name, rtd->pcm->device, suffix); + kctl->put = msm_pcm_playback_app_type_cfg_ctl_put; + kctl->get = msm_pcm_playback_app_type_cfg_ctl_get; + } + + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { + ctl_len = strlen(capture_mixer_ctl_name) + 1 + + strlen(deviceNo) + 1 + strlen(suffix) + 1; + pr_debug("%s: Capture app type cntrl add\n", __func__); + ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE, + NULL, 1, ctl_len, rtd->dai_link->id, + &app_type_info); + if (ret < 0) { + pr_err("%s: capture app type cntrl add failed: %d\n", + __func__, ret); + return ret; + } + kctl = app_type_info->kctl; + snprintf(kctl->id.name, ctl_len, "%s %d %s", + capture_mixer_ctl_name, rtd->pcm->device, suffix); + kctl->put = msm_pcm_capture_app_type_cfg_ctl_put; + kctl->get = msm_pcm_capture_app_type_cfg_ctl_get; + } + + return 0; +} + +static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + + pr_debug("%s\n", __func__); + ret = msm_pcm_add_chmap_controls(rtd); + if (ret) + pr_err("%s: pcm add controls failed:%d\n", __func__, ret); + ret = msm_pcm_add_app_type_controls(rtd); + if (ret) + pr_err("%s: pcm add app type controls failed:%d\n", + __func__, ret); + return ret; +} + +static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_card *card = rtd->card->snd_card; + int ret = 0; + + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); + + ret = msm_pcm_add_controls(rtd); + if (ret) { + pr_err("%s, kctl add failed:%d\n", __func__, ret); + return ret; + } + + ret = msm_pcm_add_volume_control(rtd); + if (ret) + pr_err("%s: Could not add pcm Volume Control %d\n", + __func__, ret); + + ret = msm_pcm_add_compress_control(rtd); + if (ret) + pr_err("%s: Could not add pcm Compress Control %d\n", + __func__, ret); + + ret = msm_pcm_add_audio_adsp_stream_cmd_control(rtd); + if (ret) + pr_err("%s: Could not add pcm ADSP Stream Cmd Control\n", + __func__); + + ret = msm_pcm_add_audio_adsp_stream_callback_control(rtd); + if (ret) + pr_err("%s: Could not add pcm ADSP Stream Callback Control\n", + __func__); + + return ret; +} + +static snd_pcm_sframes_t msm_pcm_delay_blk(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_audio *prtd = runtime->private_data; + struct audio_client *ac = prtd->audio_client; + snd_pcm_sframes_t frames; + int ret; + + ret = q6asm_get_path_delay(prtd->audio_client); + if (ret) { + pr_err("%s: get_path_delay failed, ret=%d\n", __func__, ret); + return 0; + } + + /* convert microseconds to frames */ + frames = ac->path_delay / 1000 * runtime->rate / 1000; + + /* also convert the remainder from the initial division */ + frames += ac->path_delay % 1000 * runtime->rate / 1000000; + + /* overcompensate for the loss of precision (empirical) */ + frames += 2; + + return frames; +} + +static struct snd_soc_platform_driver msm_soc_platform = { + .ops = &msm_pcm_ops, + .pcm_new = msm_asoc_pcm_new, + .delay_blk = msm_pcm_delay_blk, +}; + +static int msm_pcm_probe(struct platform_device *pdev) +{ + int rc; + int id; + struct msm_plat_data *pdata; + const char *latency_level; + + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-pcm-dsp-id", &id); + if (rc) { + dev_err(&pdev->dev, "%s: qcom,msm-pcm-dsp-id missing in DT node\n", + __func__); + return rc; + } + + pdata = kzalloc(sizeof(struct msm_plat_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + if (of_property_read_bool(pdev->dev.of_node, + "qcom,msm-pcm-low-latency")) { + + pdata->perf_mode = LOW_LATENCY_PCM_MODE; + rc = of_property_read_string(pdev->dev.of_node, + "qcom,latency-level", &latency_level); + if (!rc) { + if (!strcmp(latency_level, "ultra")) + pdata->perf_mode = ULTRA_LOW_LATENCY_PCM_MODE; + else if (!strcmp(latency_level, "ull-pp")) + pdata->perf_mode = + ULL_POST_PROCESSING_PCM_MODE; + } + } else { + pdata->perf_mode = LEGACY_PCM_MODE; + } + + dev_set_drvdata(&pdev->dev, pdata); + + + dev_dbg(&pdev->dev, "%s: dev name %s\n", + __func__, dev_name(&pdev->dev)); + return snd_soc_register_platform(&pdev->dev, + &msm_soc_platform); +} + +static int msm_pcm_remove(struct platform_device *pdev) +{ + struct msm_plat_data *pdata; + + pdata = dev_get_drvdata(&pdev->dev); + kfree(pdata); + snd_soc_unregister_platform(&pdev->dev); + return 0; +} +static const struct of_device_id msm_pcm_dt_match[] = { + {.compatible = "qcom,msm-pcm-dsp"}, + {} +}; +MODULE_DEVICE_TABLE(of, msm_pcm_dt_match); + +static struct platform_driver msm_pcm_driver = { + .driver = { + .name = "msm-pcm-dsp", + .owner = THIS_MODULE, + .of_match_table = msm_pcm_dt_match, + }, + .probe = msm_pcm_probe, + .remove = msm_pcm_remove, +}; + +static int __init msm_soc_platform_init(void) +{ + init_waitqueue_head(&the_locks.enable_wait); + init_waitqueue_head(&the_locks.eos_wait); + init_waitqueue_head(&the_locks.write_wait); + init_waitqueue_head(&the_locks.read_wait); + + return platform_driver_register(&msm_pcm_driver); +} +module_init(msm_soc_platform_init); + +static void __exit msm_soc_platform_exit(void) +{ + platform_driver_unregister(&msm_pcm_driver); +} +module_exit(msm_soc_platform_exit); + +MODULE_DESCRIPTION("PCM module platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h new file mode 100644 index 000000000000..3b3f0480d33c --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2008 HTC Corporation + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, you can find it at http://www.fsf.org. + */ + +#ifndef _MSM_PCM_H +#define _MSM_PCM_H +#include +#include + + + +/* Support unconventional sample rates 12000, 24000 as well */ +#define USE_RATE \ + (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT) + +extern int copy_count; + +struct buffer { + void *data; + unsigned int size; + unsigned int used; + unsigned int addr; +}; + +struct buffer_rec { + void *data; + unsigned int size; + unsigned int read; + unsigned int addr; +}; + +struct audio_locks { + spinlock_t event_lock; + wait_queue_head_t read_wait; + wait_queue_head_t write_wait; + wait_queue_head_t eos_wait; + wait_queue_head_t enable_wait; + wait_queue_head_t flush_wait; +}; + +struct msm_audio_in_frame_info { + uint32_t size; + uint32_t offset; +}; + +#define PLAYBACK_MIN_NUM_PERIODS 2 +#define PLAYBACK_MAX_NUM_PERIODS 8 +#define PLAYBACK_MAX_PERIOD_SIZE 122880 +#define PLAYBACK_MIN_PERIOD_SIZE 128 +#define CAPTURE_MIN_NUM_PERIODS 2 +#define CAPTURE_MAX_NUM_PERIODS 8 +#define CAPTURE_MAX_PERIOD_SIZE 122880 +#define CAPTURE_MIN_PERIOD_SIZE 320 + +struct msm_audio { + struct snd_pcm_substream *substream; + unsigned int pcm_size; + unsigned int pcm_count; + unsigned int pcm_irq_pos; /* IRQ position */ + uint16_t source; /* Encoding source bit mask */ + + struct audio_client *audio_client; + + uint16_t session_id; + + uint32_t samp_rate; + uint32_t channel_mode; + uint32_t dsp_cnt; + + int abort; /* set when error, like sample rate mismatch */ + + bool reset_event; + int enabled; + int close_ack; + int cmd_ack; + /* + * cmd_ack doesn't tell if paticular command has been sent so can't + * determine if it needs to wait for completion. + * Use cmd_pending instead when checking whether a command is been + * sent or not. + */ + unsigned long cmd_pending; + atomic_t start; + atomic_t stop; + atomic_t out_count; + atomic_t in_count; + atomic_t out_needed; + atomic_t eos; + int out_head; + int periods; + int mmap_flag; + atomic_t pending_buffer; + bool set_channel_map; + char channel_map[8]; + int cmd_interrupt; + bool meta_data_mode; + uint32_t volume; + bool compress_enable; + /* array of frame info */ + struct msm_audio_in_frame_info in_frame_info[CAPTURE_MAX_NUM_PERIODS]; +}; + +struct output_meta_data_st { + uint32_t meta_data_length; + uint32_t frame_size; + uint32_t timestamp_lsw; + uint32_t timestamp_msw; + uint32_t reserved[12]; +}; + +struct msm_plat_data { + int perf_mode; + struct snd_pcm *pcm; +}; + +#endif /*_MSM_PCM_H*/ diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.c new file mode 100644 index 000000000000..7335951522b3 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.c @@ -0,0 +1,139 @@ +/* Copyright (c) 2014, 2016-2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include "msm-pcm-routing-devdep.h" +#include "msm-ds2-dap-config.h" + +#ifdef CONFIG_SND_HWDEP +static int msm_pcm_routing_hwdep_open(struct snd_hwdep *hw, struct file *file) +{ + pr_debug("%s\n", __func__); + msm_ds2_dap_update_port_parameters(hw, file, true); + return 0; +} + +static int msm_pcm_routing_hwdep_release(struct snd_hwdep *hw, + struct file *file) +{ + pr_debug("%s\n", __func__); + msm_ds2_dap_update_port_parameters(hw, file, false); + return 0; +} + +static int msm_pcm_routing_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int ret = 0; + void __user *argp = (void __user *)arg; + + pr_debug("%s:cmd %x\n", __func__, cmd); + switch (cmd) { + case SNDRV_DEVDEP_DAP_IOCTL_SET_PARAM: + case SNDRV_DEVDEP_DAP_IOCTL_GET_PARAM: + case SNDRV_DEVDEP_DAP_IOCTL_DAP_COMMAND: + case SNDRV_DEVDEP_DAP_IOCTL_DAP_LICENSE: + msm_pcm_routing_acquire_lock(); + ret = msm_ds2_dap_ioctl(hw, file, cmd, argp); + msm_pcm_routing_release_lock(); + break; + case SNDRV_DEVDEP_DAP_IOCTL_GET_VISUALIZER: + ret = msm_ds2_dap_ioctl(hw, file, cmd, argp); + break; + default: + pr_err("%s called with invalid control 0x%X\n", __func__, cmd); + ret = -EINVAL; + break; + } + return ret; +} + +void msm_pcm_routing_hwdep_free(struct snd_pcm *pcm) +{ + pr_debug("%s\n", __func__); +} + +#ifdef CONFIG_COMPAT +static int msm_pcm_routing_hwdep_compat_ioctl(struct snd_hwdep *hw, + struct file *file, + unsigned int cmd, + unsigned long arg) +{ + int ret = 0; + void __user *argp = (void __user *)arg; + + pr_debug("%s:cmd %x\n", __func__, cmd); + switch (cmd) { + case SNDRV_DEVDEP_DAP_IOCTL_SET_PARAM32: + case SNDRV_DEVDEP_DAP_IOCTL_GET_PARAM32: + case SNDRV_DEVDEP_DAP_IOCTL_DAP_COMMAND32: + case SNDRV_DEVDEP_DAP_IOCTL_DAP_LICENSE32: + msm_pcm_routing_acquire_lock(); + ret = msm_ds2_dap_compat_ioctl(hw, file, cmd, argp); + msm_pcm_routing_release_lock(); + break; + case SNDRV_DEVDEP_DAP_IOCTL_GET_VISUALIZER32: + ret = msm_ds2_dap_compat_ioctl(hw, file, cmd, argp); + break; + default: + pr_err("%s called with invalid control 0x%X\n", __func__, cmd); + ret = -EINVAL; + break; + } + return ret; +} +#endif + +int msm_pcm_routing_hwdep_new(struct snd_soc_pcm_runtime *runtime, + struct msm_pcm_routing_bdai_data *msm_bedais) +{ + struct snd_hwdep *hwdep; + struct snd_soc_dai_link *dai_link = runtime->dai_link; + int rc; + + if (dai_link->id < 0 || + dai_link->id >= MSM_BACKEND_DAI_MAX) { + pr_err("%s:BE id %d invalid index\n", + __func__, dai_link->id); + return -EINVAL; + } + pr_debug("%s BE id %d\n", __func__, dai_link->id); + rc = snd_hwdep_new(runtime->card->snd_card, + msm_bedais[dai_link->id].name, + dai_link->id, &hwdep); + if (hwdep == NULL) { + pr_err("%s: hwdep intf failed to create %s- hwdep NULL\n", + __func__, msm_bedais[dai_link->id].name); + return rc; + } + if (rc < 0) { + pr_err("%s: hwdep intf failed to create %s rc %d\n", __func__, + msm_bedais[dai_link->id].name, rc); + return rc; + } + + hwdep->iface = SNDRV_HWDEP_IFACE_AUDIO_BE; + hwdep->private_data = &msm_bedais[dai_link->id]; + hwdep->ops.open = msm_pcm_routing_hwdep_open; + hwdep->ops.ioctl = msm_pcm_routing_hwdep_ioctl; + hwdep->ops.release = msm_pcm_routing_hwdep_release; +#ifdef CONFIG_COMPAT + hwdep->ops.ioctl_compat = msm_pcm_routing_hwdep_compat_ioctl; +#endif + return rc; +} +#endif diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.h new file mode 100644 index 000000000000..8a0b96700329 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014-2015, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _MSM_PCM_ROUTING_DEVDEP_H_ +#define _MSM_PCM_ROUTING_DEVDEP_H_ + +#include +#include "msm-pcm-routing-v2.h" + +#ifdef CONFIG_SND_HWDEP +int msm_pcm_routing_hwdep_new(struct snd_soc_pcm_runtime *runtime, + struct msm_pcm_routing_bdai_data *msm_bedais); +void msm_pcm_routing_hwdep_free(struct snd_pcm *pcm); +#else +static inline int msm_pcm_routing_hwdep_new(struct snd_soc_pcm_runtime *runtime, + struct msm_pcm_routing_bdai_data *msm_bedais) +{ + return 0; +} + +static inline void msm_pcm_routing_hwdep_free(struct snd_pcm *pcm) +{ +} +#endif +#endif diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c new file mode 100644 index 000000000000..d67296f238f0 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -0,0 +1,15765 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "msm-pcm-routing-v2.h" +#include "msm-pcm-routing-devdep.h" +#include "msm-qti-pp-config.h" +#include "msm-dts-srs-tm-config.h" +#include "msm-dolby-dap-config.h" +#include "msm-ds2-dap-config.h" +#include "q6voice.h" +#include "sound/q6lsm.h" + +#ifndef CONFIG_DOLBY_DAP +#undef DOLBY_ADM_COPP_TOPOLOGY_ID +#define DOLBY_ADM_COPP_TOPOLOGY_ID 0xFFFFFFFE +#endif + +#ifndef CONFIG_DOLBY_DS2 +#undef DS2_ADM_COPP_TOPOLOGY_ID +#define DS2_ADM_COPP_TOPOLOGY_ID 0xFFFFFFFF +#endif + +static struct mutex routing_lock; + +static struct cal_type_data *cal_data; + +static int fm_switch_enable; +static int hfp_switch_enable; +static int int0_mi2s_switch_enable; +static int int4_mi2s_switch_enable; +static int pri_mi2s_switch_enable; +static int sec_mi2s_switch_enable; +static int tert_mi2s_switch_enable; +static int quat_mi2s_switch_enable; +static int fm_pcmrx_switch_enable; +static int usb_switch_enable; +static int lsm_port_index; +static int slim0_rx_aanc_fb_port; +static int msm_route_ec_ref_rx; +static int msm_ec_ref_ch = 4; +static int msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_ec_ref_sampling_rate = 48000; +static uint32_t voc_session_id = ALL_SESSION_VSID; +static int msm_route_ext_ec_ref; +static bool is_custom_stereo_on; +static bool is_ds2_on; +static bool swap_ch; + +#define WEIGHT_0_DB 0x4000 +/* all the FEs which can support channel mixer */ +static struct msm_pcm_channel_mixer channel_mixer[MSM_FRONTEND_DAI_MM_SIZE]; +/* input BE for each FE */ +static int channel_input[MSM_FRONTEND_DAI_MM_SIZE][ADM_MAX_CHANNELS]; + +enum { + MADNONE, + MADAUDIO, + MADBEACON, + MADULTRASOUND, + MADSWAUDIO, +}; + +#define ADM_LSM_PORT_INDEX 9 + +#define SLIMBUS_0_TX_TEXT "SLIMBUS_0_TX" +#define SLIMBUS_1_TX_TEXT "SLIMBUS_1_TX" +#define SLIMBUS_2_TX_TEXT "SLIMBUS_2_TX" +#define SLIMBUS_3_TX_TEXT "SLIMBUS_3_TX" +#define SLIMBUS_4_TX_TEXT "SLIMBUS_4_TX" +#define SLIMBUS_5_TX_TEXT "SLIMBUS_5_TX" +#define TERT_MI2S_TX_TEXT "TERT_MI2S_TX" +#define QUAT_MI2S_TX_TEXT "QUAT_MI2S_TX" +#define ADM_LSM_TX_TEXT "ADM_LSM_TX" +#define INT3_MI2S_TX_TEXT "INT3_MI2S_TX" + +#define LSM_FUNCTION_TEXT "LSM Function" +static const char * const lsm_port_text[] = { + "None", + SLIMBUS_0_TX_TEXT, SLIMBUS_1_TX_TEXT, SLIMBUS_2_TX_TEXT, + SLIMBUS_3_TX_TEXT, SLIMBUS_4_TX_TEXT, SLIMBUS_5_TX_TEXT, + TERT_MI2S_TX_TEXT, QUAT_MI2S_TX_TEXT, ADM_LSM_TX_TEXT, + INT3_MI2S_TX_TEXT +}; + +struct msm_pcm_route_bdai_pp_params { + u16 port_id; /* AFE port ID */ + unsigned long pp_params_config; + bool mute_on; + int latency; +}; + +static struct msm_pcm_route_bdai_pp_params + msm_bedais_pp_params[MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX] = { + {HDMI_RX, 0, 0, 0}, + {DISPLAY_PORT_RX, 0, 0, 0}, +}; + +/* + * The be_dai_name_table is passed to HAL so that it can specify the + * BE ID for the BE it wants to enable based on the name. Thus there + * is a matching table and structure in HAL that need to be updated + * if any changes to these are made. + */ +struct msm_pcm_route_bdai_name { + unsigned int be_id; + char be_name[LPASS_BE_NAME_MAX_LENGTH]; +}; +static struct msm_pcm_route_bdai_name be_dai_name_table[MSM_BACKEND_DAI_MAX]; + +static int msm_routing_send_device_pp_params(int port_id, int copp_idx, + int fe_id); + +static int msm_routing_get_bit_width(unsigned int format) +{ + int bit_width; + + switch (format) { + case SNDRV_PCM_FORMAT_S32_LE: + bit_width = 32; + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + bit_width = 24; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bit_width = 16; + } + return bit_width; +} + +static bool msm_is_resample_needed(int input_sr, int output_sr) +{ + bool rc = false; + + if (input_sr != output_sr) + rc = true; + + pr_debug("perform resampling (%s) for copp rate (%d)afe rate (%d)", + (rc ? "oh yes" : "not really"), + input_sr, output_sr); + + return rc; +} + +static void msm_pcm_routing_cfg_pp(int port_id, int copp_idx, int topology, + int channels) +{ + int rc = 0; + + switch (topology) { + case SRS_TRUMEDIA_TOPOLOGY_ID: + pr_debug("%s: SRS_TRUMEDIA_TOPOLOGY_ID\n", __func__); + msm_dts_srs_tm_init(port_id, copp_idx); + break; + case DS2_ADM_COPP_TOPOLOGY_ID: + pr_debug("%s: DS2_ADM_COPP_TOPOLOGY %d\n", + __func__, DS2_ADM_COPP_TOPOLOGY_ID); + rc = msm_ds2_dap_init(port_id, copp_idx, channels, + is_custom_stereo_on); + if (rc < 0) + pr_err("%s: DS2 topo_id 0x%x, port %d, CS %d rc %d\n", + __func__, topology, port_id, + is_custom_stereo_on, rc); + break; + case DOLBY_ADM_COPP_TOPOLOGY_ID: + if (is_ds2_on) { + pr_debug("%s: DS2_ADM_COPP_TOPOLOGY\n", __func__); + rc = msm_ds2_dap_init(port_id, copp_idx, channels, + is_custom_stereo_on); + if (rc < 0) + pr_err("%s:DS2 topo_id 0x%x, port %d, rc %d\n", + __func__, topology, port_id, rc); + } else { + pr_debug("%s: DOLBY_ADM_COPP_TOPOLOGY_ID\n", __func__); + rc = msm_dolby_dap_init(port_id, copp_idx, channels, + is_custom_stereo_on); + if (rc < 0) + pr_err("%s: DS1 topo_id 0x%x, port %d, rc %d\n", + __func__, topology, port_id, rc); + } + break; + case ADM_CMD_COPP_OPEN_TOPOLOGY_ID_AUDIOSPHERE: + pr_debug("%s: TOPOLOGY_ID_AUDIOSPHERE\n", __func__); + rc = msm_qti_pp_asphere_init(port_id, copp_idx); + if (rc < 0) + pr_err("%s: topo_id 0x%x, port %d, copp %d, rc %d\n", + __func__, topology, port_id, copp_idx, rc); + break; + default: + /* custom topology specific feature param handlers */ + break; + } +} + +static void msm_pcm_routing_deinit_pp(int port_id, int topology) +{ + switch (topology) { + case SRS_TRUMEDIA_TOPOLOGY_ID: + pr_debug("%s: SRS_TRUMEDIA_TOPOLOGY_ID\n", __func__); + msm_dts_srs_tm_deinit(port_id); + break; + case DS2_ADM_COPP_TOPOLOGY_ID: + pr_debug("%s: DS2_ADM_COPP_TOPOLOGY_ID %d\n", + __func__, DS2_ADM_COPP_TOPOLOGY_ID); + msm_ds2_dap_deinit(port_id); + break; + case DOLBY_ADM_COPP_TOPOLOGY_ID: + if (is_ds2_on) { + pr_debug("%s: DS2_ADM_COPP_TOPOLOGY_ID\n", __func__); + msm_ds2_dap_deinit(port_id); + } else { + pr_debug("%s: DOLBY_ADM_COPP_TOPOLOGY_ID\n", __func__); + msm_dolby_dap_deinit(port_id); + } + break; + case ADM_CMD_COPP_OPEN_TOPOLOGY_ID_AUDIOSPHERE: + pr_debug("%s: TOPOLOGY_ID_AUDIOSPHERE\n", __func__); + msm_qti_pp_asphere_deinit(port_id); + break; + default: + /* custom topology specific feature deinit handlers */ + break; + } +} + +static void msm_pcm_routng_cfg_matrix_map_pp(struct route_payload payload, + int path_type, int perf_mode) +{ + int itr = 0, rc = 0; + + if ((path_type == ADM_PATH_PLAYBACK) && + (perf_mode == LEGACY_PCM_MODE) && + is_custom_stereo_on) { + for (itr = 0; itr < payload.num_copps; itr++) { + if ((payload.port_id[itr] != SLIMBUS_0_RX) && + (payload.port_id[itr] != RT_PROXY_PORT_001_RX)) { + continue; + } + + rc = msm_qti_pp_send_stereo_to_custom_stereo_cmd( + payload.port_id[itr], + payload.copp_idx[itr], + payload.session_id, + Q14_GAIN_ZERO_POINT_FIVE, + Q14_GAIN_ZERO_POINT_FIVE, + Q14_GAIN_ZERO_POINT_FIVE, + Q14_GAIN_ZERO_POINT_FIVE); + if (rc < 0) + pr_err("%s: err setting custom stereo\n", + __func__); + } + } +} + +#define SLIMBUS_EXTPROC_RX AFE_PORT_INVALID +struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { + { PRIMARY_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_PRI_I2S_RX}, + { PRIMARY_I2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_PRI_I2S_TX}, + { SLIMBUS_0_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_0_RX}, + { SLIMBUS_0_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_0_TX}, + { HDMI_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_HDMI}, + { INT_BT_SCO_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_INT_BT_SCO_RX}, + { INT_BT_SCO_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_INT_BT_SCO_TX}, + { INT_FM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_INT_FM_RX}, + { INT_FM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_INT_FM_TX}, + { RT_PROXY_PORT_001_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_AFE_PCM_RX}, + { RT_PROXY_PORT_001_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_AFE_PCM_TX}, + { AFE_PORT_ID_PRIMARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_AUXPCM_RX}, + { AFE_PORT_ID_PRIMARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_AUXPCM_TX}, + { VOICE_PLAYBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_VOICE_PLAYBACK_TX}, + { VOICE2_PLAYBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_VOICE2_PLAYBACK_TX}, + { VOICE_RECORD_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INCALL_RECORD_RX}, + { VOICE_RECORD_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INCALL_RECORD_TX}, + { MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_MI2S_RX}, + { MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_MI2S_TX}, + { SECONDARY_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SEC_I2S_RX}, + { SLIMBUS_1_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_1_RX}, + { SLIMBUS_1_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_1_TX}, + { SLIMBUS_2_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_2_RX}, + { SLIMBUS_2_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_2_TX}, + { SLIMBUS_3_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_3_RX}, + { SLIMBUS_3_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_3_TX}, + { SLIMBUS_4_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_4_RX}, + { SLIMBUS_4_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_4_TX}, + { SLIMBUS_5_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_5_RX}, + { SLIMBUS_5_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_5_TX}, + { SLIMBUS_6_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_6_RX}, + { SLIMBUS_6_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_6_TX}, + { SLIMBUS_7_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_7_RX}, + { SLIMBUS_7_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_7_TX}, + { SLIMBUS_8_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_8_RX}, + { SLIMBUS_8_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_8_TX}, + { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_STUB_RX}, + { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_STUB_TX}, + { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_STUB_1_TX}, + { AFE_PORT_ID_QUATERNARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_MI2S_RX}, + { AFE_PORT_ID_QUATERNARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_MI2S_TX}, + { AFE_PORT_ID_SECONDARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_MI2S_RX}, + { AFE_PORT_ID_SECONDARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_MI2S_TX}, + { AFE_PORT_ID_PRIMARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_MI2S_RX}, + { AFE_PORT_ID_PRIMARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_MI2S_TX}, + { AFE_PORT_ID_TERTIARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_MI2S_RX}, + { AFE_PORT_ID_TERTIARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_MI2S_TX}, + { AUDIO_PORT_ID_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_AUDIO_I2S_RX}, + { AFE_PORT_ID_SECONDARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_AUXPCM_RX}, + { AFE_PORT_ID_SECONDARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_AUXPCM_TX}, + { AFE_PORT_ID_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SPDIF_RX}, + { AFE_PORT_ID_SECONDARY_MI2S_RX_SD1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_MI2S_RX_SD1}, + { AFE_PORT_ID_QUINARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_MI2S_RX}, + { AFE_PORT_ID_QUINARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_MI2S_TX}, + { AFE_PORT_ID_SENARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SENARY_MI2S_TX}, + { AFE_PORT_ID_PRIMARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_TDM_RX_0}, + { AFE_PORT_ID_PRIMARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_TDM_TX_0}, + { AFE_PORT_ID_PRIMARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_TDM_RX_1}, + { AFE_PORT_ID_PRIMARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_TDM_TX_1}, + { AFE_PORT_ID_PRIMARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_TDM_RX_2}, + { AFE_PORT_ID_PRIMARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_TDM_TX_2}, + { AFE_PORT_ID_PRIMARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_TDM_RX_3}, + { AFE_PORT_ID_PRIMARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_TDM_TX_3}, + { AFE_PORT_ID_PRIMARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_TDM_RX_4}, + { AFE_PORT_ID_PRIMARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_TDM_TX_4}, + { AFE_PORT_ID_PRIMARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_TDM_RX_5}, + { AFE_PORT_ID_PRIMARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_TDM_TX_5}, + { AFE_PORT_ID_PRIMARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_TDM_RX_6}, + { AFE_PORT_ID_PRIMARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_TDM_TX_6}, + { AFE_PORT_ID_PRIMARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_TDM_RX_7}, + { AFE_PORT_ID_PRIMARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_TDM_TX_7}, + { AFE_PORT_ID_SECONDARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_TDM_RX_0}, + { AFE_PORT_ID_SECONDARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_TDM_TX_0}, + { AFE_PORT_ID_SECONDARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_TDM_RX_1}, + { AFE_PORT_ID_SECONDARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_TDM_TX_1}, + { AFE_PORT_ID_SECONDARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_TDM_RX_2}, + { AFE_PORT_ID_SECONDARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_TDM_TX_2}, + { AFE_PORT_ID_SECONDARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_TDM_RX_3}, + { AFE_PORT_ID_SECONDARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_TDM_TX_3}, + { AFE_PORT_ID_SECONDARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_TDM_RX_4}, + { AFE_PORT_ID_SECONDARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_TDM_TX_4}, + { AFE_PORT_ID_SECONDARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_TDM_RX_5}, + { AFE_PORT_ID_SECONDARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_TDM_TX_5}, + { AFE_PORT_ID_SECONDARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_TDM_RX_6}, + { AFE_PORT_ID_SECONDARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_TDM_TX_6}, + { AFE_PORT_ID_SECONDARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_TDM_RX_7}, + { AFE_PORT_ID_SECONDARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_TDM_TX_7}, + { AFE_PORT_ID_TERTIARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_TDM_RX_0}, + { AFE_PORT_ID_TERTIARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_TDM_TX_0}, + { AFE_PORT_ID_TERTIARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_TDM_RX_1}, + { AFE_PORT_ID_TERTIARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_TDM_TX_1}, + { AFE_PORT_ID_TERTIARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_TDM_RX_2}, + { AFE_PORT_ID_TERTIARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_TDM_TX_2}, + { AFE_PORT_ID_TERTIARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_TDM_RX_3}, + { AFE_PORT_ID_TERTIARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_TDM_TX_3}, + { AFE_PORT_ID_TERTIARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_TDM_RX_4}, + { AFE_PORT_ID_TERTIARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_TDM_TX_4}, + { AFE_PORT_ID_TERTIARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_TDM_RX_5}, + { AFE_PORT_ID_TERTIARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_TDM_TX_5}, + { AFE_PORT_ID_TERTIARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_TDM_RX_6}, + { AFE_PORT_ID_TERTIARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_TDM_TX_6}, + { AFE_PORT_ID_TERTIARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_TDM_RX_7}, + { AFE_PORT_ID_TERTIARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_TDM_TX_7}, + { AFE_PORT_ID_QUATERNARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_TDM_RX_0}, + { AFE_PORT_ID_QUATERNARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_TDM_TX_0}, + { AFE_PORT_ID_QUATERNARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_TDM_RX_1}, + { AFE_PORT_ID_QUATERNARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_TDM_TX_1}, + { AFE_PORT_ID_QUATERNARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_TDM_RX_2}, + { AFE_PORT_ID_QUATERNARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_TDM_TX_2}, + { AFE_PORT_ID_QUATERNARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_TDM_RX_3}, + { AFE_PORT_ID_QUATERNARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_TDM_TX_3}, + { AFE_PORT_ID_QUATERNARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_TDM_RX_4}, + { AFE_PORT_ID_QUATERNARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_TDM_TX_4}, + { AFE_PORT_ID_QUATERNARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_TDM_RX_5}, + { AFE_PORT_ID_QUATERNARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_TDM_TX_5}, + { AFE_PORT_ID_QUATERNARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_TDM_RX_6}, + { AFE_PORT_ID_QUATERNARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_TDM_TX_6}, + { AFE_PORT_ID_QUATERNARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_TDM_RX_7}, + { AFE_PORT_ID_QUATERNARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_TDM_TX_7}, + { INT_BT_A2DP_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INT_BT_A2DP_RX}, + { AFE_PORT_ID_USB_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_USB_AUDIO_RX}, + { AFE_PORT_ID_USB_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_USB_AUDIO_TX}, + { DISPLAY_PORT_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_DISPLAY_PORT}, + { AFE_PORT_ID_TERTIARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_AUXPCM_RX}, + { AFE_PORT_ID_TERTIARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_AUXPCM_TX}, + { AFE_PORT_ID_QUATERNARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_AUXPCM_RX}, + { AFE_PORT_ID_QUATERNARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_AUXPCM_TX}, + { AFE_PORT_ID_INT0_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INT0_MI2S_RX}, + { AFE_PORT_ID_INT0_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INT0_MI2S_TX}, + { AFE_PORT_ID_INT1_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INT1_MI2S_RX}, + { AFE_PORT_ID_INT1_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INT1_MI2S_TX}, + { AFE_PORT_ID_INT2_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INT2_MI2S_RX}, + { AFE_PORT_ID_INT2_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INT2_MI2S_TX}, + { AFE_PORT_ID_INT3_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INT3_MI2S_RX}, + { AFE_PORT_ID_INT3_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INT3_MI2S_TX}, + { AFE_PORT_ID_INT4_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INT4_MI2S_RX}, + { AFE_PORT_ID_INT4_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INT4_MI2S_TX}, + { AFE_PORT_ID_INT5_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INT5_MI2S_RX}, + { AFE_PORT_ID_INT5_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INT5_MI2S_TX}, + { AFE_PORT_ID_INT6_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INT6_MI2S_RX}, + { AFE_PORT_ID_INT6_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_INT6_MI2S_TX}, +}; + +/* Track ASM playback & capture sessions of DAI + * Track LSM listen sessions + */ +static struct msm_pcm_routing_fdai_data + fe_dai_map[MSM_FRONTEND_DAI_MAX][2] = { + /* MULTIMEDIA1 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA2 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA3 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA4 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA5 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA6 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA7*/ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA8 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA9 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA10 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA11 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA12 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA13 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA14 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA15 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA16 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA17 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA18 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA19 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA20 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* CS_VOICE */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOIP */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* AFE_RX */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* AFE_TX */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOICE_STUB */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOLTE */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* DTMF_RX */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOICE2 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* QCHAT */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOLTE_STUB */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM1 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM2 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM3 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM4 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM5 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM6 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM7 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* LSM8 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOICE2_STUB */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOWLAN */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOICEMMODE1 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* VOICEMMODE2 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, +}; + +static unsigned long session_copp_map[MSM_FRONTEND_DAI_MAX][2] + [MSM_BACKEND_DAI_MAX]; +static struct msm_pcm_routing_app_type_data app_type_cfg[MAX_APP_TYPES]; +static struct msm_pcm_routing_app_type_data lsm_app_type_cfg[MAX_APP_TYPES]; +static struct msm_pcm_stream_app_type_cfg + fe_dai_app_type_cfg[MSM_FRONTEND_DAI_MAX][2][MSM_BACKEND_DAI_MAX]; + +static int last_be_id_configured[MSM_FRONTEND_DAI_MAX][MAX_SESSION_TYPES]; + +/* The caller of this should aqcuire routing lock */ +void msm_pcm_routing_get_bedai_info(int be_idx, + struct msm_pcm_routing_bdai_data *be_dai) +{ + if (be_idx >= 0 && be_idx < MSM_BACKEND_DAI_MAX) + memcpy(be_dai, &msm_bedais[be_idx], + sizeof(struct msm_pcm_routing_bdai_data)); +} + +/* The caller of this should aqcuire routing lock */ +void msm_pcm_routing_get_fedai_info(int fe_idx, int sess_type, + struct msm_pcm_routing_fdai_data *fe_dai) +{ + if ((sess_type == SESSION_TYPE_TX) || (sess_type == SESSION_TYPE_RX)) + memcpy(fe_dai, &fe_dai_map[fe_idx][sess_type], + sizeof(struct msm_pcm_routing_fdai_data)); +} + +void msm_pcm_routing_acquire_lock(void) +{ + mutex_lock(&routing_lock); +} + +void msm_pcm_routing_release_lock(void) +{ + mutex_unlock(&routing_lock); +} + +static int msm_pcm_routing_get_app_type_idx(int app_type) +{ + int idx; + + pr_debug("%s: app_type: %d\n", __func__, app_type); + for (idx = 0; idx < MAX_APP_TYPES; idx++) { + if (app_type_cfg[idx].app_type == app_type) + return idx; + } + pr_info("%s: App type not available, fallback to default\n", __func__); + return 0; +} + +static int msm_pcm_routing_get_lsm_app_type_idx(int app_type) +{ + int idx; + + pr_debug("%s: app_type: %d\n", __func__, app_type); + for (idx = 0; idx < MAX_APP_TYPES; idx++) { + if (lsm_app_type_cfg[idx].app_type == app_type) + return idx; + } + pr_debug("%s: App type not available, fallback to default\n", __func__); + return 0; +} + +static bool is_mm_lsm_fe_id(int fe_id) +{ + bool rc = true; + + if (fe_id > MSM_FRONTEND_DAI_MM_MAX_ID && + ((fe_id < MSM_FRONTEND_DAI_LSM1) || + (fe_id > MSM_FRONTEND_DAI_LSM8))) { + rc = false; + } + return rc; +} + +int msm_pcm_routing_reg_stream_app_type_cfg( + int fedai_id, int session_type, int be_id, + struct msm_pcm_stream_app_type_cfg *cfg_data) +{ + int ret = 0; + + if (cfg_data == NULL) { + pr_err("%s: Received NULL pointer for cfg_data\n", __func__); + ret = -EINVAL; + goto done; + } + + pr_debug("%s: fedai_id %d, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fedai_id, session_type, be_id, + cfg_data->app_type, cfg_data->acdb_dev_id, + cfg_data->sample_rate); + + if (!is_mm_lsm_fe_id(fedai_id)) { + pr_err("%s: Invalid machine driver ID %d\n", + __func__, fedai_id); + ret = -EINVAL; + goto done; + } + if (session_type != SESSION_TYPE_RX && + session_type != SESSION_TYPE_TX) { + pr_err("%s: Invalid session type %d\n", + __func__, session_type); + ret = -EINVAL; + goto done; + } + if (be_id < 0 || be_id >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: Received out of bounds be_id %d\n", + __func__, be_id); + ret = -EINVAL; + goto done; + } + + fe_dai_app_type_cfg[fedai_id][session_type][be_id] = *cfg_data; + + /* + * Store the BE ID of the configuration information set as the latest so + * the get mixer control knows what to return. + */ + last_be_id_configured[fedai_id][session_type] = be_id; + +done: + return ret; +} +EXPORT_SYMBOL(msm_pcm_routing_reg_stream_app_type_cfg); + +/** + * msm_pcm_routing_get_stream_app_type_cfg + * + * Receives fedai_id, session_type, be_id, and populates app_type, + * acdb_dev_id, & sample rate. Returns 0 on success. On failure returns + * -EINVAL and does not alter passed values. + * + * fedai_id - Passed value, front end ID for which app type config is wanted + * session_type - Passed value, session type for which app type config + * is wanted + * be_id - Returned value, back end device id the app type config data is for + * cfg_data - Returned value, configuration data used by app type config + */ +int msm_pcm_routing_get_stream_app_type_cfg( + int fedai_id, int session_type, int *bedai_id, + struct msm_pcm_stream_app_type_cfg *cfg_data) +{ + int be_id; + int ret = 0; + + if (bedai_id == NULL) { + pr_err("%s: Received NULL pointer for backend ID\n", __func__); + ret = -EINVAL; + goto done; + } else if (cfg_data == NULL) { + pr_err("%s: NULL pointer sent for cfg_data\n", __func__); + ret = -EINVAL; + goto done; + } else if (!is_mm_lsm_fe_id(fedai_id)) { + pr_err("%s: Invalid FE ID %d\n", __func__, fedai_id); + ret = -EINVAL; + goto done; + } else if (session_type != SESSION_TYPE_RX && + session_type != SESSION_TYPE_TX) { + pr_err("%s: Invalid session type %d\n", __func__, session_type); + ret = -EINVAL; + goto done; + } + + be_id = last_be_id_configured[fedai_id][session_type]; + if (be_id < 0 || be_id >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: Invalid BE ID %d\n", __func__, be_id); + ret = -EINVAL; + goto done; + } + + *bedai_id = be_id; + *cfg_data = fe_dai_app_type_cfg[fedai_id][session_type][be_id]; + pr_debug("%s: fedai_id %d, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fedai_id, session_type, *bedai_id, + cfg_data->app_type, cfg_data->acdb_dev_id, + cfg_data->sample_rate); +done: + return ret; +} +EXPORT_SYMBOL(msm_pcm_routing_get_stream_app_type_cfg); + +static struct cal_block_data *msm_routing_find_topology_by_path(int path) +{ + struct list_head *ptr, *next; + struct cal_block_data *cal_block = NULL; + + pr_debug("%s\n", __func__); + + list_for_each_safe(ptr, next, + &cal_data->cal_blocks) { + + cal_block = list_entry(ptr, + struct cal_block_data, list); + + if (((struct audio_cal_info_adm_top *)cal_block->cal_info) + ->path == path) { + return cal_block; + } + } + pr_debug("%s: Can't find topology for path %d\n", __func__, path); + return NULL; +} + +static struct cal_block_data *msm_routing_find_topology(int path, + int app_type, + int acdb_id) +{ + struct list_head *ptr, *next; + struct cal_block_data *cal_block = NULL; + struct audio_cal_info_adm_top *cal_info; + + pr_debug("%s\n", __func__); + + list_for_each_safe(ptr, next, + &cal_data->cal_blocks) { + + cal_block = list_entry(ptr, + struct cal_block_data, list); + + cal_info = (struct audio_cal_info_adm_top *) + cal_block->cal_info; + if ((cal_info->path == path) && + (cal_info->app_type == app_type) && + (cal_info->acdb_id == acdb_id)) { + return cal_block; + } + } + pr_debug("%s: Can't find topology for path %d, app %d, acdb_id %d defaulting to search by path\n", + __func__, path, app_type, acdb_id); + return msm_routing_find_topology_by_path(path); +} + +static int msm_routing_get_adm_topology(int fedai_id, int session_type, + int be_id) +{ + int topology = NULL_COPP_TOPOLOGY; + struct cal_block_data *cal_block = NULL; + int app_type = 0, acdb_dev_id = 0; + + + pr_debug("%s: fedai_id %d, session_type %d, be_id %d\n", + __func__, fedai_id, session_type, be_id); + + if (cal_data == NULL) + goto done; + + mutex_lock(&cal_data->lock); + + app_type = fe_dai_app_type_cfg[fedai_id][session_type][be_id].app_type; + acdb_dev_id = + fe_dai_app_type_cfg[fedai_id][session_type][be_id].acdb_dev_id; + + cal_block = msm_routing_find_topology(session_type, app_type, + acdb_dev_id); + if (cal_block == NULL) + goto unlock; + + topology = ((struct audio_cal_info_adm_top *) + cal_block->cal_info)->topology; +unlock: + mutex_unlock(&cal_data->lock); +done: + pr_debug("%s: Using topology %d\n", __func__, topology); + return topology; +} + +static uint8_t is_be_dai_extproc(int be_dai) +{ + if (be_dai == MSM_BACKEND_DAI_EXTPROC_RX || + be_dai == MSM_BACKEND_DAI_EXTPROC_TX || + be_dai == MSM_BACKEND_DAI_EXTPROC_EC_TX) + return 1; + else + return 0; +} + +static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type, + int path_type, int perf_mode, + uint32_t passthr_mode) +{ + int i, port_type, j, num_copps = 0; + struct route_payload payload; + + port_type = ((path_type == ADM_PATH_PLAYBACK || + path_type == ADM_PATH_COMPRESSED_RX) ? + MSM_AFE_PORT_TYPE_RX : MSM_AFE_PORT_TYPE_TX); + + for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) { + if (!is_be_dai_extproc(i) && + (afe_get_port_type(msm_bedais[i].port_id) == port_type) && + (msm_bedais[i].active) && + (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) { + for (j = 0; j < MAX_COPPS_PER_PORT; j++) { + unsigned long copp = + session_copp_map[fedai_id][sess_type][i]; + if (test_bit(j, &copp)) { + payload.port_id[num_copps] = + msm_bedais[i].port_id; + payload.copp_idx[num_copps] = j; + payload.app_type[num_copps] = + fe_dai_app_type_cfg + [fedai_id][sess_type][i] + .app_type; + payload.acdb_dev_id[num_copps] = + fe_dai_app_type_cfg + [fedai_id][sess_type][i] + .acdb_dev_id; + payload.sample_rate[num_copps] = + fe_dai_app_type_cfg + [fedai_id][sess_type][i] + .sample_rate; + num_copps++; + } + } + } + } + + if (num_copps) { + payload.num_copps = num_copps; + payload.session_id = fe_dai_map[fedai_id][sess_type].strm_id; + adm_matrix_map(path_type, payload, perf_mode, passthr_mode); + msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode); + } +} + +void msm_pcm_routing_reg_psthr_stream(int fedai_id, int dspst_id, + int stream_type) +{ + int i, session_type, path_type, port_type; + u32 mode = 0; + + if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) { + /* bad ID assigned in machine driver */ + pr_err("%s: bad MM ID\n", __func__); + return; + } + + if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) { + session_type = SESSION_TYPE_RX; + path_type = ADM_PATH_PLAYBACK; + port_type = MSM_AFE_PORT_TYPE_RX; + } else { + session_type = SESSION_TYPE_TX; + path_type = ADM_PATH_LIVE_REC; + port_type = MSM_AFE_PORT_TYPE_TX; + } + + mutex_lock(&routing_lock); + + fe_dai_map[fedai_id][session_type].strm_id = dspst_id; + for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) { + if (!is_be_dai_extproc(i) && + (afe_get_port_type(msm_bedais[i].port_id) == port_type) && + (msm_bedais[i].active) && + (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) { + mode = afe_get_port_type(msm_bedais[i].port_id); + adm_connect_afe_port(mode, dspst_id, + msm_bedais[i].port_id); + break; + } + } + mutex_unlock(&routing_lock); +} + +static bool route_check_fe_id_adm_support(int fe_id) +{ + bool rc = true; + + if ((fe_id >= MSM_FRONTEND_DAI_LSM1) && + (fe_id <= MSM_FRONTEND_DAI_LSM8)) { + /* fe id is listen while port is set to afe */ + if (lsm_port_index != ADM_LSM_PORT_INDEX) { + pr_debug("%s: fe_id %d, lsm mux slim port %d\n", + __func__, fe_id, lsm_port_index); + rc = false; + } + } + + return rc; +} + +int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, + int dspst_id, int stream_type, + uint32_t passthr_mode) +{ + int i, j, session_type, path_type, port_type, topology; + int num_copps = 0; + struct route_payload payload; + u32 channels, sample_rate; + u16 bit_width = 16; + bool is_lsm; + + pr_debug("%s:fe_id[%d] perf_mode[%d] id[%d] stream_type[%d] passt[%d]", + __func__, fe_id, perf_mode, dspst_id, + stream_type, passthr_mode); + if (!is_mm_lsm_fe_id(fe_id)) { + /* bad ID assigned in machine driver */ + pr_err("%s: bad MM ID %d\n", __func__, fe_id); + return -EINVAL; + } + + if (!route_check_fe_id_adm_support(fe_id)) { + /* ignore adm open if not supported for fe_id */ + pr_debug("%s: No ADM support for fe id %d\n", __func__, fe_id); + return 0; + } + + if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) { + session_type = SESSION_TYPE_RX; + if (passthr_mode != LEGACY_PCM) + path_type = ADM_PATH_COMPRESSED_RX; + else + path_type = ADM_PATH_PLAYBACK; + port_type = MSM_AFE_PORT_TYPE_RX; + } else if (stream_type == SNDRV_PCM_STREAM_CAPTURE) { + session_type = SESSION_TYPE_TX; + if (passthr_mode != LEGACY_PCM) + path_type = ADM_PATH_COMPRESSED_TX; + else + path_type = ADM_PATH_LIVE_REC; + port_type = MSM_AFE_PORT_TYPE_TX; + } else { + pr_err("%s: invalid stream type %d\n", __func__, stream_type); + return -EINVAL; + } + + is_lsm = (fe_id >= MSM_FRONTEND_DAI_LSM1) && + (fe_id <= MSM_FRONTEND_DAI_LSM8); + mutex_lock(&routing_lock); + + payload.num_copps = 0; /* only RX needs to use payload */ + fe_dai_map[fe_id][session_type].strm_id = dspst_id; + /* re-enable EQ if active */ + msm_qti_pp_send_eq_values(fe_id); + for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) { + if (test_bit(fe_id, &msm_bedais[i].fe_sessions[0])) + msm_bedais[i].passthr_mode[fe_id] = passthr_mode; + + if (!is_be_dai_extproc(i) && + (afe_get_port_type(msm_bedais[i].port_id) == + port_type) && + (msm_bedais[i].active) && + (test_bit(fe_id, &msm_bedais[i].fe_sessions[0]))) { + int app_type, app_type_idx, copp_idx, acdb_dev_id; + + /* + * check if ADM needs to be configured with different + * channel mapping than backend + */ + if (!msm_bedais[i].adm_override_ch) + channels = msm_bedais[i].channel; + else + channels = msm_bedais[i].adm_override_ch; + + bit_width = msm_routing_get_bit_width( + msm_bedais[i].format); + app_type = + fe_dai_app_type_cfg[fe_id][session_type][i].app_type; + if (app_type && is_lsm) { + app_type_idx = + msm_pcm_routing_get_lsm_app_type_idx(app_type); + sample_rate = + fe_dai_app_type_cfg[fe_id][session_type][i] + .sample_rate; + bit_width = + lsm_app_type_cfg[app_type_idx].bit_width; + } else if (app_type) { + app_type_idx = + msm_pcm_routing_get_app_type_idx( + app_type); + sample_rate = + fe_dai_app_type_cfg[fe_id][session_type][i].sample_rate; + bit_width = + app_type_cfg[app_type_idx].bit_width; + } else { + sample_rate = msm_bedais[i].sample_rate; + } + acdb_dev_id = + fe_dai_app_type_cfg[fe_id][session_type][i].acdb_dev_id; + topology = msm_routing_get_adm_topology(fe_id, + session_type, + i); + if ((passthr_mode == COMPRESSED_PASSTHROUGH_DSD) + || (passthr_mode == + COMPRESSED_PASSTHROUGH_GEN)) + topology = COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY; + pr_debug("%s: Before adm open topology %d\n", __func__, + topology); + + copp_idx = + adm_open(msm_bedais[i].port_id, + path_type, sample_rate, channels, + topology, perf_mode, bit_width, + app_type, acdb_dev_id); + if ((copp_idx < 0) || + (copp_idx >= MAX_COPPS_PER_PORT)) { + pr_err("%s:adm open failed coppid:%d\n", + __func__, copp_idx); + mutex_unlock(&routing_lock); + return -EINVAL; + } + pr_debug("%s: set idx bit of fe:%d, type: %d, be:%d\n", + __func__, fe_id, session_type, i); + set_bit(copp_idx, + &session_copp_map[fe_id][session_type][i]); + + if (msm_is_resample_needed( + sample_rate, + msm_bedais[i].sample_rate)) + adm_copp_mfc_cfg( + msm_bedais[i].port_id, copp_idx, + msm_bedais[i].sample_rate); + + for (j = 0; j < MAX_COPPS_PER_PORT; j++) { + unsigned long copp = + session_copp_map[fe_id][session_type][i]; + if (test_bit(j, &copp)) { + payload.port_id[num_copps] = + msm_bedais[i].port_id; + payload.copp_idx[num_copps] = j; + payload.app_type[num_copps] = + fe_dai_app_type_cfg + [fe_id][session_type][i] + .app_type; + payload.acdb_dev_id[num_copps] = + fe_dai_app_type_cfg + [fe_id][session_type][i] + .acdb_dev_id; + payload.sample_rate[num_copps] = + fe_dai_app_type_cfg + [fe_id][session_type][i] + .sample_rate; + num_copps++; + } + } + if (passthr_mode != COMPRESSED_PASSTHROUGH_DSD + && passthr_mode != + COMPRESSED_PASSTHROUGH_GEN) { + msm_routing_send_device_pp_params( + msm_bedais[i].port_id, + copp_idx, fe_id); + } + } + } + if (num_copps) { + payload.num_copps = num_copps; + payload.session_id = fe_dai_map[fe_id][session_type].strm_id; + adm_matrix_map(path_type, payload, perf_mode, passthr_mode); + msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode); + } + mutex_unlock(&routing_lock); + return 0; +} + +static u32 msm_pcm_routing_get_voc_sessionid(u16 val) +{ + u32 session_id; + + switch (val) { + case MSM_FRONTEND_DAI_CS_VOICE: + session_id = voc_get_session_id(VOICE_SESSION_NAME); + break; + case MSM_FRONTEND_DAI_VOLTE: + session_id = voc_get_session_id(VOLTE_SESSION_NAME); + break; + case MSM_FRONTEND_DAI_VOWLAN: + session_id = voc_get_session_id(VOWLAN_SESSION_NAME); + break; + case MSM_FRONTEND_DAI_VOICE2: + session_id = voc_get_session_id(VOICE2_SESSION_NAME); + break; + case MSM_FRONTEND_DAI_QCHAT: + session_id = voc_get_session_id(QCHAT_SESSION_NAME); + break; + case MSM_FRONTEND_DAI_VOIP: + session_id = voc_get_session_id(VOIP_SESSION_NAME); + break; + case MSM_FRONTEND_DAI_VOICEMMODE1: + session_id = voc_get_session_id(VOICEMMODE1_NAME); + break; + case MSM_FRONTEND_DAI_VOICEMMODE2: + session_id = voc_get_session_id(VOICEMMODE2_NAME); + break; + default: + session_id = 0; + } + + pr_debug("%s session_id 0x%x", __func__, session_id); + return session_id; +} + +static int msm_pcm_routing_channel_mixer(int fe_id, bool perf_mode, + int dspst_id, int stream_type) +{ + int copp_idx = 0; + int sess_type = 0; + int i = 0, j = 0, be_id; + int ret = 0; + + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %d\n", __func__, fe_id); + return 0; + } + + if (!(channel_mixer[fe_id].enable)) { + pr_debug("%s: channel mixer not enabled for FE %d\n", + __func__, fe_id); + return 0; + } + + if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) + sess_type = SESSION_TYPE_RX; + else + sess_type = SESSION_TYPE_TX; + + for (i = 0; i < ADM_MAX_CHANNELS && channel_input[fe_id][i] > 0; + ++i) { + be_id = channel_input[fe_id][i] - 1; + channel_mixer[fe_id].input_channels[i] = + msm_bedais[be_id].channel; + + if ((msm_bedais[be_id].active) && + test_bit(fe_id, + &msm_bedais[be_id].fe_sessions[0])) { + unsigned long copp = + session_copp_map[fe_id][sess_type][be_id]; + for (j = 0; j < MAX_COPPS_PER_PORT; j++) { + if (test_bit(j, &copp)) { + copp_idx = j; + break; + } + } + + pr_debug("%s: fe %d, be %d, channel %d, copp %d\n", + __func__, + fe_id, be_id, msm_bedais[be_id].channel, + copp_idx); + ret = adm_programable_channel_mixer( + msm_bedais[be_id].port_id, + copp_idx, dspst_id, sess_type, + channel_mixer + fe_id, i); + } + } + + return ret; +} + +int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, + int dspst_id, int stream_type) +{ + int i, j, session_type, path_type, port_type, topology, num_copps = 0; + struct route_payload payload; + u32 channels, sample_rate; + uint16_t bits_per_sample = 16; + uint32_t passthr_mode = LEGACY_PCM; + int ret = 0; + + if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) { + /* bad ID assigned in machine driver */ + pr_err("%s: bad MM ID %d\n", __func__, fedai_id); + return -EINVAL; + } + + if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) { + session_type = SESSION_TYPE_RX; + path_type = ADM_PATH_PLAYBACK; + port_type = MSM_AFE_PORT_TYPE_RX; + } else { + session_type = SESSION_TYPE_TX; + path_type = ADM_PATH_LIVE_REC; + port_type = MSM_AFE_PORT_TYPE_TX; + } + + mutex_lock(&routing_lock); + + payload.num_copps = 0; /* only RX needs to use payload */ + fe_dai_map[fedai_id][session_type].strm_id = dspst_id; + fe_dai_map[fedai_id][session_type].perf_mode = perf_mode; + + /* re-enable EQ if active */ + msm_qti_pp_send_eq_values(fedai_id); + for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) { + if (!is_be_dai_extproc(i) && + (afe_get_port_type(msm_bedais[i].port_id) == port_type) && + (msm_bedais[i].active) && + (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) { + int app_type, app_type_idx, copp_idx, acdb_dev_id; + /* + * check if ADM needs to be configured with different + * channel mapping than backend + */ + if (!msm_bedais[i].adm_override_ch) + channels = msm_bedais[i].channel; + else + channels = msm_bedais[i].adm_override_ch; + msm_bedais[i].passthr_mode[fedai_id] = + LEGACY_PCM; + + bits_per_sample = msm_routing_get_bit_width( + msm_bedais[i].format); + + app_type = + fe_dai_app_type_cfg[fedai_id][session_type][i].app_type; + if (app_type) { + app_type_idx = + msm_pcm_routing_get_app_type_idx(app_type); + sample_rate = + fe_dai_app_type_cfg[fedai_id][session_type][i] + .sample_rate; + bits_per_sample = + app_type_cfg[app_type_idx].bit_width; + } else + sample_rate = msm_bedais[i].sample_rate; + + acdb_dev_id = + fe_dai_app_type_cfg[fedai_id][session_type][i] + .acdb_dev_id; + topology = msm_routing_get_adm_topology(fedai_id, + session_type, + i); + copp_idx = adm_open(msm_bedais[i].port_id, path_type, + sample_rate, channels, topology, + perf_mode, bits_per_sample, + app_type, acdb_dev_id); + if ((copp_idx < 0) || + (copp_idx >= MAX_COPPS_PER_PORT)) { + pr_err("%s: adm open failed copp_idx:%d\n", + __func__, copp_idx); + mutex_unlock(&routing_lock); + return -EINVAL; + } + pr_debug("%s: setting idx bit of fe:%d, type: %d, be:%d\n", + __func__, fedai_id, session_type, i); + set_bit(copp_idx, + &session_copp_map[fedai_id][session_type][i]); + + if (msm_is_resample_needed( + sample_rate, + msm_bedais[i].sample_rate)) + adm_copp_mfc_cfg( + msm_bedais[i].port_id, copp_idx, + msm_bedais[i].sample_rate); + + for (j = 0; j < MAX_COPPS_PER_PORT; j++) { + unsigned long copp = + session_copp_map[fedai_id][session_type][i]; + if (test_bit(j, &copp)) { + payload.port_id[num_copps] = + msm_bedais[i].port_id; + payload.copp_idx[num_copps] = j; + payload.app_type[num_copps] = + fe_dai_app_type_cfg + [fedai_id][session_type] + [i].app_type; + payload.acdb_dev_id[num_copps] = + fe_dai_app_type_cfg + [fedai_id][session_type] + [i].acdb_dev_id; + payload.sample_rate[num_copps] = + fe_dai_app_type_cfg + [fedai_id][session_type] + [i].sample_rate; + num_copps++; + } + } + if ((perf_mode == LEGACY_PCM_MODE) && + (msm_bedais[i].passthr_mode[fedai_id] == + LEGACY_PCM)) + msm_pcm_routing_cfg_pp(msm_bedais[i].port_id, + copp_idx, topology, + channels); + } + } + if (num_copps) { + payload.num_copps = num_copps; + payload.session_id = fe_dai_map[fedai_id][session_type].strm_id; + adm_matrix_map(path_type, payload, perf_mode, passthr_mode); + msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode); + } + + ret = msm_pcm_routing_channel_mixer(fedai_id, perf_mode, + dspst_id, stream_type); + mutex_unlock(&routing_lock); + return ret; +} + +int msm_pcm_routing_reg_phy_stream_v2(int fedai_id, int perf_mode, + int dspst_id, int stream_type, + struct msm_pcm_routing_evt event_info) +{ + if (msm_pcm_routing_reg_phy_stream(fedai_id, perf_mode, dspst_id, + stream_type)) { + pr_err("%s: failed to reg phy stream\n", __func__); + return -EINVAL; + } + + if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) + fe_dai_map[fedai_id][SESSION_TYPE_RX].event_info = event_info; + else + fe_dai_map[fedai_id][SESSION_TYPE_TX].event_info = event_info; + return 0; +} + +void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type) +{ + int i, port_type, session_type, path_type, topology; + struct msm_pcm_routing_fdai_data *fdai; + + if (!is_mm_lsm_fe_id(fedai_id)) { + /* bad ID assigned in machine driver */ + pr_err("%s: bad MM ID\n", __func__); + return; + } + + if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) { + port_type = MSM_AFE_PORT_TYPE_RX; + session_type = SESSION_TYPE_RX; + path_type = ADM_PATH_PLAYBACK; + } else { + port_type = MSM_AFE_PORT_TYPE_TX; + session_type = SESSION_TYPE_TX; + path_type = ADM_PATH_LIVE_REC; + } + + mutex_lock(&routing_lock); + for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) { + if (!is_be_dai_extproc(i) && + (afe_get_port_type(msm_bedais[i].port_id) == port_type) && + (msm_bedais[i].active) && + (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) { + int idx; + unsigned long copp = + session_copp_map[fedai_id][session_type][i]; + fdai = &fe_dai_map[fedai_id][session_type]; + + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) + if (test_bit(idx, &copp)) + break; + + if (idx >= MAX_COPPS_PER_PORT || idx < 0) { + pr_debug("%s: copp idx is invalid, exiting\n", + __func__); + continue; + } + topology = adm_get_topology_for_port_copp_idx( + msm_bedais[i].port_id, idx); + adm_close(msm_bedais[i].port_id, fdai->perf_mode, idx); + pr_debug("%s:copp:%ld,idx bit fe:%d,type:%d,be:%d\n", + __func__, copp, fedai_id, session_type, i); + clear_bit(idx, + &session_copp_map[fedai_id][session_type][i]); + if ((topology == DOLBY_ADM_COPP_TOPOLOGY_ID || + topology == DS2_ADM_COPP_TOPOLOGY_ID) && + (fdai->perf_mode == LEGACY_PCM_MODE) && + (msm_bedais[i].passthr_mode[fedai_id] == + LEGACY_PCM)) + msm_pcm_routing_deinit_pp(msm_bedais[i].port_id, + topology); + } + } + + fe_dai_map[fedai_id][session_type].strm_id = INVALID_SESSION; + fe_dai_map[fedai_id][session_type].be_srate = 0; + mutex_unlock(&routing_lock); +} + +/* Check if FE/BE route is set */ +static bool msm_pcm_routing_route_is_set(u16 be_id, u16 fe_id) +{ + bool rc = false; + + if (!is_mm_lsm_fe_id(fe_id)) { + /* recheck FE ID in the mixer control defined in this file */ + pr_err("%s: bad MM ID\n", __func__); + return rc; + } + + if (test_bit(fe_id, &msm_bedais[be_id].fe_sessions[0])) + rc = true; + + return rc; +} + +static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) +{ + int session_type, path_type, topology; + u32 channels, sample_rate; + uint16_t bits_per_sample = 16; + struct msm_pcm_routing_fdai_data *fdai; + uint32_t passthr_mode; + bool is_lsm; + + pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set); + + if (!is_mm_lsm_fe_id(val)) { + /* recheck FE ID in the mixer control defined in this file */ + pr_err("%s: bad MM ID\n", __func__); + return; + } + + if (!route_check_fe_id_adm_support(val)) { + /* ignore adm open if not supported for fe_id */ + pr_debug("%s: No ADM support for fe id %d\n", __func__, val); + return; + } + + passthr_mode = msm_bedais[reg].passthr_mode[val]; + if (afe_get_port_type(msm_bedais[reg].port_id) == + MSM_AFE_PORT_TYPE_RX) { + session_type = SESSION_TYPE_RX; + if (passthr_mode != LEGACY_PCM) + path_type = ADM_PATH_COMPRESSED_RX; + else + path_type = ADM_PATH_PLAYBACK; + } else { + session_type = SESSION_TYPE_TX; + if (passthr_mode != LEGACY_PCM) + path_type = ADM_PATH_COMPRESSED_TX; + else + path_type = ADM_PATH_LIVE_REC; + } + is_lsm = (val >= MSM_FRONTEND_DAI_LSM1) && + (val <= MSM_FRONTEND_DAI_LSM8); + + mutex_lock(&routing_lock); + if (set) { + if (!test_bit(val, &msm_bedais[reg].fe_sessions[0]) && + ((msm_bedais[reg].port_id == VOICE_PLAYBACK_TX) || + (msm_bedais[reg].port_id == VOICE2_PLAYBACK_TX))) + voc_start_playback(set, msm_bedais[reg].port_id); + + set_bit(val, &msm_bedais[reg].fe_sessions[0]); + fdai = &fe_dai_map[val][session_type]; + if (msm_bedais[reg].active && fdai->strm_id != + INVALID_SESSION) { + int app_type, app_type_idx, copp_idx, acdb_dev_id; + /* + * check if ADM needs to be configured with different + * channel mapping than backend + */ + if (!msm_bedais[reg].adm_override_ch) + channels = msm_bedais[reg].channel; + else + channels = msm_bedais[reg].adm_override_ch; + if (session_type == SESSION_TYPE_TX && + fdai->be_srate && + (fdai->be_srate != msm_bedais[reg].sample_rate)) { + pr_debug("%s: flush strm %d diff BE rates\n", + __func__, fdai->strm_id); + + if (fdai->event_info.event_func) + fdai->event_info.event_func( + MSM_PCM_RT_EVT_BUF_RECFG, + fdai->event_info.priv_data); + fdai->be_srate = 0; /* might not need it */ + } + + bits_per_sample = msm_routing_get_bit_width( + msm_bedais[reg].format); + + app_type = + fe_dai_app_type_cfg[val][session_type][reg].app_type; + if (app_type && is_lsm) { + app_type_idx = + msm_pcm_routing_get_lsm_app_type_idx(app_type); + sample_rate = + fe_dai_app_type_cfg[val][session_type][reg] + .sample_rate; + bits_per_sample = + lsm_app_type_cfg[app_type_idx].bit_width; + } else if (app_type) { + app_type_idx = + msm_pcm_routing_get_app_type_idx(app_type); + sample_rate = + fe_dai_app_type_cfg[val][session_type][reg] + .sample_rate; + bits_per_sample = + app_type_cfg[app_type_idx].bit_width; + } else + sample_rate = msm_bedais[reg].sample_rate; + + topology = msm_routing_get_adm_topology(val, + session_type, + reg); + acdb_dev_id = + fe_dai_app_type_cfg[val][session_type][reg].acdb_dev_id; + copp_idx = adm_open(msm_bedais[reg].port_id, path_type, + sample_rate, channels, topology, + fdai->perf_mode, bits_per_sample, + app_type, acdb_dev_id); + if ((copp_idx < 0) || + (copp_idx >= MAX_COPPS_PER_PORT)) { + pr_err("%s: adm open failed\n", __func__); + mutex_unlock(&routing_lock); + return; + } + pr_debug("%s: setting idx bit of fe:%d, type: %d, be:%d\n", + __func__, val, session_type, reg); + set_bit(copp_idx, + &session_copp_map[val][session_type][reg]); + + if (msm_is_resample_needed( + sample_rate, + msm_bedais[reg].sample_rate)) + adm_copp_mfc_cfg( + msm_bedais[reg].port_id, copp_idx, + msm_bedais[reg].sample_rate); + + if (session_type == SESSION_TYPE_RX && + fdai->event_info.event_func) + fdai->event_info.event_func( + MSM_PCM_RT_EVT_DEVSWITCH, + fdai->event_info.priv_data); + + msm_pcm_routing_build_matrix(val, session_type, + path_type, + fdai->perf_mode, + passthr_mode); + if ((fdai->perf_mode == LEGACY_PCM_MODE) && + (passthr_mode == LEGACY_PCM)) + msm_pcm_routing_cfg_pp(msm_bedais[reg].port_id, + copp_idx, topology, + channels); + } + } else { + if (test_bit(val, &msm_bedais[reg].fe_sessions[0]) && + ((msm_bedais[reg].port_id == VOICE_PLAYBACK_TX) || + (msm_bedais[reg].port_id == VOICE2_PLAYBACK_TX))) + voc_start_playback(set, msm_bedais[reg].port_id); + clear_bit(val, &msm_bedais[reg].fe_sessions[0]); + fdai = &fe_dai_map[val][session_type]; + if (msm_bedais[reg].active && fdai->strm_id != + INVALID_SESSION) { + int idx; + int port_id; + unsigned long copp = + session_copp_map[val][session_type][reg]; + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) + if (test_bit(idx, &copp)) + break; + + port_id = msm_bedais[reg].port_id; + topology = adm_get_topology_for_port_copp_idx(port_id, + idx); + adm_close(msm_bedais[reg].port_id, fdai->perf_mode, + idx); + pr_debug("%s: copp: %ld, reset idx bit fe:%d, type: %d, be:%d topology=0x%x\n", + __func__, copp, val, session_type, reg, + topology); + clear_bit(idx, + &session_copp_map[val][session_type][reg]); + if ((topology == DOLBY_ADM_COPP_TOPOLOGY_ID || + topology == DS2_ADM_COPP_TOPOLOGY_ID) && + (fdai->perf_mode == LEGACY_PCM_MODE) && + (passthr_mode == LEGACY_PCM)) + msm_pcm_routing_deinit_pp( + msm_bedais[reg].port_id, + topology); + msm_pcm_routing_build_matrix(val, session_type, + path_type, + fdai->perf_mode, + passthr_mode); + } + } + if ((msm_bedais[reg].port_id == VOICE_RECORD_RX) + || (msm_bedais[reg].port_id == VOICE_RECORD_TX)) + voc_start_record(msm_bedais[reg].port_id, set, voc_session_id); + + mutex_unlock(&routing_lock); +} + +static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + + if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0])) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; + + pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + + if (ucontrol->value.integer.value[0] && + msm_pcm_routing_route_is_set(mc->reg, mc->shift) == false) { + msm_pcm_routing_process_audio(mc->reg, mc->shift, 1); + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, + update); + } else if (!ucontrol->value.integer.value[0] && + msm_pcm_routing_route_is_set(mc->reg, mc->shift) == true) { + msm_pcm_routing_process_audio(mc->reg, mc->shift, 0); + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, + update); + } + + return 1; +} + +static int msm_routing_get_listen_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + + if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0])) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; + + pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_routing_put_listen_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + ucontrol->value.integer.value[0]); + + if (ucontrol->value.integer.value[0]) { + if (msm_pcm_routing_route_is_set(mc->reg, mc->shift) == false) + msm_pcm_routing_process_audio(mc->reg, mc->shift, 1); + snd_soc_dapm_mixer_update_power(widget->dapm, + kcontrol, 1, update); + } else if (!ucontrol->value.integer.value[0]) { + if (msm_pcm_routing_route_is_set(mc->reg, mc->shift) == true) + msm_pcm_routing_process_audio(mc->reg, mc->shift, 0); + snd_soc_dapm_mixer_update_power(widget->dapm, + kcontrol, 0, update); + } + + return 1; +} + +static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set) +{ + u32 session_id = 0; + u16 path_type; + struct media_format_info voc_be_media_format; + + pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set); + + session_id = msm_pcm_routing_get_voc_sessionid(val); + + pr_debug("%s: FE DAI 0x%x session_id 0x%x\n", + __func__, val, session_id); + + mutex_lock(&routing_lock); + + if (set) + set_bit(val, &msm_bedais[reg].fe_sessions[0]); + else + clear_bit(val, &msm_bedais[reg].fe_sessions[0]); + + if (val == MSM_FRONTEND_DAI_DTMF_RX && + afe_get_port_type(msm_bedais[reg].port_id) == + MSM_AFE_PORT_TYPE_RX) { + pr_debug("%s(): set=%d port id=0x%x for dtmf generation\n", + __func__, set, msm_bedais[reg].port_id); + afe_set_dtmf_gen_rx_portid(msm_bedais[reg].port_id, set); + } + + if (afe_get_port_type(msm_bedais[reg].port_id) == + MSM_AFE_PORT_TYPE_RX) + path_type = RX_PATH; + else + path_type = TX_PATH; + + if (set) { + if (msm_bedais[reg].active) { + voc_set_route_flag(session_id, path_type, 1); + + memset(&voc_be_media_format, 0, + sizeof(struct media_format_info)); + + voc_be_media_format.port_id = msm_bedais[reg].port_id; + voc_be_media_format.num_channels = + msm_bedais[reg].channel; + voc_be_media_format.sample_rate = + msm_bedais[reg].sample_rate; + voc_be_media_format.bits_per_sample = + msm_bedais[reg].format; + /* Defaulting this to 1 for voice call usecases */ + voc_be_media_format.channel_mapping[0] = 1; + + voc_set_device_config(session_id, path_type, + &voc_be_media_format); + + if (voc_get_route_flag(session_id, TX_PATH) && + voc_get_route_flag(session_id, RX_PATH)) + voc_enable_device(session_id); + } else { + pr_debug("%s BE is not active\n", __func__); + } + } else { + voc_set_route_flag(session_id, path_type, 0); + voc_disable_device(session_id); + } + + mutex_unlock(&routing_lock); + +} + +static int msm_routing_get_voice_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + + mutex_lock(&routing_lock); + + if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0])) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; + + mutex_unlock(&routing_lock); + + pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_routing_put_voice_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + + if (ucontrol->value.integer.value[0]) { + msm_pcm_routing_process_voice(mc->reg, mc->shift, 1); + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, + update); + } else { + msm_pcm_routing_process_voice(mc->reg, mc->shift, 0); + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, + update); + } + + return 1; +} + +static int msm_routing_get_voice_stub_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + + mutex_lock(&routing_lock); + + if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0])) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; + + mutex_unlock(&routing_lock); + + pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_routing_put_voice_stub_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + + if (ucontrol->value.integer.value[0]) { + mutex_lock(&routing_lock); + set_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0]); + mutex_unlock(&routing_lock); + + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, + update); + } else { + mutex_lock(&routing_lock); + clear_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0]); + mutex_unlock(&routing_lock); + + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, + update); + } + + pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + ucontrol->value.integer.value[0]); + + return 1; +} + +/* + * Return the mapping between port ID and backend ID to enable the AFE callback + * to determine the acdb_dev_id from the port id + */ +int msm_pcm_get_be_id_from_port_id(int port_id) +{ + int i; + int be_id = -EINVAL; + + for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) { + if (msm_bedais[i].port_id == port_id) { + be_id = i; + break; + } + } + + return be_id; +} + +/* + * Return the registered dev_acdb_id given a port ID to enable identifying the + * correct AFE calibration information by comparing the header information. + */ +static int msm_pcm_get_dev_acdb_id_by_port_id(int port_id) +{ + int acdb_id = -EINVAL; + int i = 0; + int session; + int port_type = afe_get_port_type(port_id); + int be_id = msm_pcm_get_be_id_from_port_id(port_id); + + pr_debug("%s:port_id %d be_id %d, port_type 0x%x\n", + __func__, port_id, be_id, port_type); + + if (port_type == MSM_AFE_PORT_TYPE_TX) { + session = SESSION_TYPE_TX; + } else if (port_type == MSM_AFE_PORT_TYPE_RX) { + session = SESSION_TYPE_RX; + } else { + pr_err("%s: Invalid port type %d\n", __func__, port_type); + acdb_id = -EINVAL; + goto exit; + } + + if (be_id < 0) { + pr_err("%s: Error getting backend id %d\n", __func__, be_id); + goto exit; + } + + mutex_lock(&routing_lock); + i = find_first_bit(&msm_bedais[be_id].fe_sessions[0], + MSM_FRONTEND_DAI_MAX); + if (i < MSM_FRONTEND_DAI_MAX) + acdb_id = fe_dai_app_type_cfg[i][session][be_id].acdb_dev_id; + + pr_debug("%s: FE[%d] session[%d] BE[%d] acdb_id(%d)\n", + __func__, i, session, be_id, acdb_id); + mutex_unlock(&routing_lock); +exit: + return acdb_id; +} + +static int msm_routing_get_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = fm_switch_enable; + pr_debug("%s: FM Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_put_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: FM Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + if (ucontrol->value.integer.value[0]) + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, + update); + else + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, + update); + fm_switch_enable = ucontrol->value.integer.value[0]; + return 1; +} + +static int msm_routing_get_hfp_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = hfp_switch_enable; + pr_debug("%s: HFP Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_put_hfp_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: HFP Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + if (ucontrol->value.integer.value[0]) + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, + 1, update); + else + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, + 0, update); + hfp_switch_enable = ucontrol->value.integer.value[0]; + return 1; +} + +static int msm_routing_get_int0_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = int0_mi2s_switch_enable; + pr_debug("%s: INT0 MI2S Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_put_int0_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: INT0 MI2S Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + if (ucontrol->value.integer.value[0]) + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, + update); + else + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, + update); + int0_mi2s_switch_enable = ucontrol->value.integer.value[0]; + return 1; +} + +static int msm_routing_get_int4_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = int4_mi2s_switch_enable; + pr_debug("%s: INT4 MI2S Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_put_int4_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: INT4 MI2S Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + if (ucontrol->value.integer.value[0]) + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, + update); + else + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, + update); + int4_mi2s_switch_enable = ucontrol->value.integer.value[0]; + return 1; +} + +static int msm_routing_get_usb_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = usb_switch_enable; + pr_debug("%s: HFP Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_put_usb_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: USB Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + if (ucontrol->value.integer.value[0]) + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, + 1, update); + else + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, + 0, update); + usb_switch_enable = ucontrol->value.integer.value[0]; + return 1; +} + +static int msm_routing_get_pri_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = pri_mi2s_switch_enable; + pr_debug("%s: PRI MI2S Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_put_pri_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: PRI MI2S Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + if (ucontrol->value.integer.value[0]) + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, + update); + else + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, + update); + pri_mi2s_switch_enable = ucontrol->value.integer.value[0]; + return 1; +} + +static int msm_routing_get_sec_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = sec_mi2s_switch_enable; + pr_debug("%s: SEC MI2S Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_put_sec_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: SEC MI2S Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + if (ucontrol->value.integer.value[0]) + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, + update); + else + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, + update); + sec_mi2s_switch_enable = ucontrol->value.integer.value[0]; + return 1; +} + +static int msm_routing_get_tert_mi2s_switch_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = tert_mi2s_switch_enable; + pr_debug("%s: TERT MI2S Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_put_tert_mi2s_switch_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: TERT MI2S Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + if (ucontrol->value.integer.value[0]) + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, + update); + else + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, + update); + tert_mi2s_switch_enable = ucontrol->value.integer.value[0]; + return 1; +} + +static int msm_routing_get_quat_mi2s_switch_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = quat_mi2s_switch_enable; + pr_debug("%s: QUAT MI2S Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_put_quat_mi2s_switch_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: QUAT MI2S Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + if (ucontrol->value.integer.value[0]) + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, + update); + else + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, + update); + quat_mi2s_switch_enable = ucontrol->value.integer.value[0]; + return 1; +} + +static int msm_routing_get_fm_pcmrx_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = fm_pcmrx_switch_enable; + pr_debug("%s: FM Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_put_fm_pcmrx_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: FM Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + if (ucontrol->value.integer.value[0]) + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, + update); + else + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, + update); + fm_pcmrx_switch_enable = ucontrol->value.integer.value[0]; + return 1; +} + +static int msm_routing_lsm_port_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = lsm_port_index; + return 0; +} + +static int msm_routing_lsm_port_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int mux = ucontrol->value.enumerated.item[0]; + int lsm_port = AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX; + + if (mux >= e->items) { + pr_err("%s: Invalid mux value %d\n", __func__, mux); + return -EINVAL; + } + + pr_debug("%s: LSM enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + switch (ucontrol->value.integer.value[0]) { + case 1: + lsm_port = AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX; + break; + case 2: + lsm_port = AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX; + break; + case 3: + lsm_port = AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX; + break; + case 4: + lsm_port = AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX; + break; + case 5: + lsm_port = AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX; + break; + case 6: + lsm_port = AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX; + break; + case 7: + lsm_port = AFE_PORT_ID_TERTIARY_MI2S_TX; + break; + case 8: + lsm_port = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + case 9: + lsm_port = ADM_LSM_PORT_ID; + break; + case 10: + lsm_port = AFE_PORT_ID_INT3_MI2S_TX; + break; + default: + pr_err("Default lsm port"); + break; + } + set_lsm_port(lsm_port); + lsm_port_index = ucontrol->value.integer.value[0]; + + return 0; +} + +static int msm_routing_lsm_func_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int i; + u16 port_id; + enum afe_mad_type mad_type; + + pr_debug("%s: enter\n", __func__); + for (i = 0; i < ARRAY_SIZE(lsm_port_text); i++) + if (!strnstr(kcontrol->id.name, lsm_port_text[i], + strlen(lsm_port_text[i]))) + break; + + if (i-- == ARRAY_SIZE(lsm_port_text)) { + WARN(1, "Invalid id name %s\n", kcontrol->id.name); + return -EINVAL; + } + + port_id = i * 2 + 1 + SLIMBUS_0_RX; + + /*Check for Tertiary/Quaternary/INT3 TX port*/ + if (strnstr(kcontrol->id.name, lsm_port_text[7], + strlen(lsm_port_text[7]))) + port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + + if (strnstr(kcontrol->id.name, lsm_port_text[8], + strlen(lsm_port_text[8]))) + port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + + if (strnstr(kcontrol->id.name, lsm_port_text[10], + strlen(lsm_port_text[10]))) + port_id = AFE_PORT_ID_INT3_MI2S_TX; + + mad_type = afe_port_get_mad_type(port_id); + pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, + mad_type); + switch (mad_type) { + case MAD_HW_NONE: + ucontrol->value.integer.value[0] = MADNONE; + break; + case MAD_HW_AUDIO: + ucontrol->value.integer.value[0] = MADAUDIO; + break; + case MAD_HW_BEACON: + ucontrol->value.integer.value[0] = MADBEACON; + break; + case MAD_HW_ULTRASOUND: + ucontrol->value.integer.value[0] = MADULTRASOUND; + break; + case MAD_SW_AUDIO: + ucontrol->value.integer.value[0] = MADSWAUDIO; + break; + default: + WARN(1, "Unknown\n"); + return -EINVAL; + } + return 0; +} + +static int msm_routing_lsm_func_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int i; + u16 port_id; + enum afe_mad_type mad_type; + + pr_debug("%s: enter\n", __func__); + for (i = 0; i < ARRAY_SIZE(lsm_port_text); i++) + if (strnstr(kcontrol->id.name, lsm_port_text[i], + strlen(lsm_port_text[i]))) + break; + + if (i-- == ARRAY_SIZE(lsm_port_text)) { + WARN(1, "Invalid id name %s\n", kcontrol->id.name); + return -EINVAL; + } + + port_id = i * 2 + 1 + SLIMBUS_0_RX; + switch (ucontrol->value.integer.value[0]) { + case MADNONE: + mad_type = MAD_HW_NONE; + break; + case MADAUDIO: + mad_type = MAD_HW_AUDIO; + break; + case MADBEACON: + mad_type = MAD_HW_BEACON; + break; + case MADULTRASOUND: + mad_type = MAD_HW_ULTRASOUND; + break; + case MADSWAUDIO: + mad_type = MAD_SW_AUDIO; + break; + default: + WARN(1, "Unknown\n"); + return -EINVAL; + } + + /*Check for Tertiary/Quaternary/INT3 TX port*/ + if (strnstr(kcontrol->id.name, lsm_port_text[7], + strlen(lsm_port_text[7]))) + port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + + if (strnstr(kcontrol->id.name, lsm_port_text[8], + strlen(lsm_port_text[8]))) + port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + + if (strnstr(kcontrol->id.name, lsm_port_text[10], + strlen(lsm_port_text[10]))) + port_id = AFE_PORT_ID_INT3_MI2S_TX; + + pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, + mad_type); + return afe_port_set_mad_type(port_id, mad_type); +} + +static const char *const adm_override_chs_text[] = {"Zero", "One", "Two"}; + +static SOC_ENUM_SINGLE_EXT_DECL(slim_7_rx_adm_override_chs, + adm_override_chs_text); + +static int msm_routing_adm_get_backend_idx(struct snd_kcontrol *kcontrol) +{ + int backend_id; + + if (strnstr(kcontrol->id.name, "SLIM7_RX", sizeof("SLIM7_RX"))) { + backend_id = MSM_BACKEND_DAI_SLIMBUS_7_RX; + } else { + pr_err("%s: unsupported backend id: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + + return backend_id; +} +static int msm_routing_adm_channel_config_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int backend_id = msm_routing_adm_get_backend_idx(kcontrol); + + if (backend_id >= 0) { + mutex_lock(&routing_lock); + ucontrol->value.integer.value[0] = + msm_bedais[backend_id].adm_override_ch; + pr_debug("%s: adm channel count %ld for BE:%d\n", __func__, + ucontrol->value.integer.value[0], backend_id); + mutex_unlock(&routing_lock); + } + + return 0; +} + +static int msm_routing_adm_channel_config_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int backend_id = msm_routing_adm_get_backend_idx(kcontrol); + + if (backend_id >= 0) { + mutex_lock(&routing_lock); + msm_bedais[backend_id].adm_override_ch = + ucontrol->value.integer.value[0]; + pr_debug("%s:updating BE :%d adm channels: %d\n", + __func__, backend_id, + msm_bedais[backend_id].adm_override_ch); + mutex_unlock(&routing_lock); + } + + return 0; +} + +static const struct snd_kcontrol_new adm_channel_config_controls[] = { + SOC_ENUM_EXT("SLIM7_RX ADM Channels", slim_7_rx_adm_override_chs, + msm_routing_adm_channel_config_get, + msm_routing_adm_channel_config_put), +}; + +static int msm_routing_slim_0_rx_aanc_mux_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + mutex_lock(&routing_lock); + ucontrol->value.integer.value[0] = slim0_rx_aanc_fb_port; + mutex_unlock(&routing_lock); + pr_debug("%s: AANC Mux Port %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +}; + +static int msm_routing_slim_0_rx_aanc_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct aanc_data aanc_info; + + mutex_lock(&routing_lock); + memset(&aanc_info, 0x00, sizeof(aanc_info)); + pr_debug("%s: AANC Mux Port %ld\n", __func__, + ucontrol->value.integer.value[0]); + slim0_rx_aanc_fb_port = ucontrol->value.integer.value[0]; + if (ucontrol->value.integer.value[0] == 0) { + aanc_info.aanc_active = false; + aanc_info.aanc_tx_port = 0; + aanc_info.aanc_rx_port = 0; + } else { + aanc_info.aanc_active = true; + aanc_info.aanc_rx_port = SLIMBUS_0_RX; + aanc_info.aanc_tx_port = + (SLIMBUS_0_RX - 1 + (slim0_rx_aanc_fb_port * 2)); + } + afe_set_aanc_info(&aanc_info); + mutex_unlock(&routing_lock); + return 0; +}; +static int msm_routing_get_port_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = 0, shift = 0; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + + idx = mc->shift/(sizeof(msm_bedais[mc->reg].port_sessions[0]) * 8); + shift = mc->shift%(sizeof(msm_bedais[mc->reg].port_sessions[0]) * 8); + + if (idx >= BE_DAI_PORT_SESSIONS_IDX_MAX) { + pr_err("%s: Invalid idx = %d\n", __func__, idx); + return -EINVAL; + } + + if (test_bit(shift, + (unsigned long *)&msm_bedais[mc->reg].port_sessions[idx])) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; + + pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_routing_put_port_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = 0, shift = 0; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + + idx = mc->shift/(sizeof(msm_bedais[mc->reg].port_sessions[0]) * 8); + shift = mc->shift%(sizeof(msm_bedais[mc->reg].port_sessions[0]) * 8); + + if (idx >= BE_DAI_PORT_SESSIONS_IDX_MAX) { + pr_err("%s: Invalid idx = %d\n", __func__, idx); + return -EINVAL; + } + + pr_debug("%s: reg 0x%x shift 0x%x val %ld idx %d reminder shift %d\n", + __func__, mc->reg, mc->shift, + ucontrol->value.integer.value[0], idx, shift); + + if (ucontrol->value.integer.value[0]) { + afe_loopback(1, msm_bedais[mc->reg].port_id, + msm_bedais[mc->shift].port_id); + set_bit(shift, + (unsigned long *)&msm_bedais[mc->reg].port_sessions[idx]); + } else { + afe_loopback(0, msm_bedais[mc->reg].port_id, + msm_bedais[mc->shift].port_id); + clear_bit(shift, + (unsigned long *)&msm_bedais[mc->reg].port_sessions[idx]); + } + + return 1; +} + +static int msm_pcm_get_channel_rule_index(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u16 fe_id = 0; + + fe_id = ((struct soc_mixer_control *) + kcontrol->private_value)->shift; + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %d\n", __func__, fe_id); + return -EINVAL; + } + + ucontrol->value.integer.value[0] = channel_mixer[fe_id].rule; + + return 0; +} + +static int msm_pcm_put_channel_rule_index(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u16 fe_id = 0; + + fe_id = ((struct soc_mixer_control *) + kcontrol->private_value)->shift; + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %d\n", __func__, fe_id); + return -EINVAL; + } + + channel_mixer[fe_id].rule = ucontrol->value.integer.value[0]; + + return 1; +} + +static int msm_pcm_get_out_chs(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u16 fe_id = 0; + + fe_id = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %d\n", __func__, fe_id); + return -EINVAL; + } + + ucontrol->value.integer.value[0] = + channel_mixer[fe_id].output_channel; + return 0; +} + +static int msm_pcm_put_out_chs(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u16 fe_id = 0; + + fe_id = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %d\n", __func__, fe_id); + return -EINVAL; + } + + pr_debug("%s: fe_id is %d, output channels = %d\n", __func__, + fe_id, + (unsigned int)(ucontrol->value.integer.value[0])); + channel_mixer[fe_id].output_channel = + (unsigned int)(ucontrol->value.integer.value[0]); + + return 1; +} + +static const char *const ch_mixer[] = {"Disable", "Enable"}; + +/* If new backend is added, need update this array */ +static const char *const be_name[] = { +"ZERO", "PRI_I2S_RX", "PRI_I2S_TX", "SLIM_0_RX", +"SLIM_0_TX", "HDMI_RX", "INT_BT_SCO_RX", "INT_BT_SCO_TX", +"INT_FM_RX", "INT_FM_TX", "AFE_PCM_RX", "AFE_PCM_TX", +"AUXPCM_RX", "AUXPCM_TX", "VOICE_PLAYBACK_TX", "VOICE2_PLAYBACK_TX", +"INCALL_RECORD_RX", "INCALL_RECORD_TX", "MI2S_RX", "MI2S_TX", +"SEC_I2S_RX", "SLIM_1_RX", "SLIM_1_TX", "SLIM_2_RX", +"SLIM_2_TX", "SLIM_3_RX", "SLIM_3_TX", "SLIM_4_RX", +"SLIM_4_TX", "SLIM_5_RX", "SLIM_5_TX", "SLIM_6_RX", +"SLIM_6_TX", "SLIM_7_RX", "SLIM_7_TX", "SLIM_8_RX", +"SLIM_8_TX", "EXTPROC_RX", "EXTPROC_TX", "EXPROC_EC_TX", +"QUAT_MI2S_RX", "QUAT_MI2S_TX", "SECOND_MI2S_RX", "SECOND_MI2S_TX", +"PRI_MI2S_RX", "PRI_MI2S_TX", "TERT_MI2S_RX", "TERT_MI2S_TX", +"AUDIO_I2S_RX", "SEC_AUXPCM_RX", "SEC_AUXPCM_TX", "SPDIF_RX", +"SECOND_MI2S_RX_SD1", "QUIN_MI2S_RX", "QUIN_MI2S_TX", "SENARY_MI2S_TX", +"PRI_TDM_RX_0", "PRI_TDM_TX_0", "PRI_TDM_RX_1", "PRI_TDM_TX_1", +"PRI_TDM_RX_2", "PRI_TDM_TX_2", "PRI_TDM_RX_3", "PRI_TDM_TX_3", +"PRI_TDM_RX_4", "PRI_TDM_TX_4", "PRI_TDM_RX_5", "PRI_TDM_TX_5", +"PRI_TDM_RX_6", "PRI_TDM_TX_6", "PRI_TDM_RX_7", "PRI_TDM_TX_7", +"SEC_TDM_RX_0", "SEC_TDM_TX_0", "SEC_TDM_RX_1", "SEC_TDM_TX_1", +"SEC_TDM_RX_2", "SEC_TDM_TX_2", "SEC_TDM_RX_3", "SEC_TDM_TX_3", +"SEC_TDM_RX_4", "SEC_TDM_TX_4", "SEC_TDM_RX_5", "SEC_TDM_TX_5", +"SEC_TDM_RX_6", "SEC_TDM_TX_6", "SEC_TDM_RX_7", "SEC_TDM_TX_7", +"TERT_TDM_RX_0", "TERT_TDM_TX_0", "TERT_TDM_RX_1", "TERT_TDM_TX_1", +"TERT_TDM_RX_2", "TERT_TDM_TX_2", "TERT_TDM_RX_3", "TERT_TDM_TX_3", +"TERT_TDM_RX_4", "TERT_TDM_TX_4", "TERT_TDM_RX_5", "TERT_TDM_TX_5", +"TERT_TDM_RX_6", "TERT_TDM_TX_6", "TERT_TDM_RX_7", "TERT_TDM_TX_7", +"QUAT_TDM_RX_0", "QUAT_TDM_TX_0", "QUAT_TDM_RX_1", "QUAT_TDM_TX_1", +"QUAT_TDM_RX_2", "QUAT_TDM_TX_2", "QUAT_TDM_RX_3", "QUAT_TDM_TX_3", +"QUAT_TDM_RX_4", "QUAT_TDM_TX_4", "QUAT_TDM_RX_5", "QUAT_TDM_TX_5", +"QUAT_TDM_RX_6", "QUAT_TDM_TX_6", "QUAT_TDM_RX_7", "QUAT_TDM_TX_7", +"INT_BT_A2DP_RX", "USB_RX", "USB_TX", "DISPLAY_PORT_RX", +"TERT_AUXPCM_RX", "TERT_AUXPCM_TX", "QUAT_AUXPCM_RX", "QUAT_AUXPCM_TX", +"INT0_MI2S_RX", "INT0_MI2S_TX", "INT1_MI2S_RX", "INT1_MI2S_TX", +"INT2_MI2S_RX", "INT2_MI2S_TX", "INT3_MI2S_RX", "INT3_MI2S_TX", +"INT4_MI2S_RX", "INT4_MI2S_TX", "INT5_MI2S_RX", "INT5_MI2S_TX", +"INT6_MI2S_RX", "INT6_MI2S_TX" +}; + +static SOC_ENUM_SINGLE_DECL(mm1_channel_mux, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA1, ch_mixer); +static SOC_ENUM_SINGLE_DECL(mm2_channel_mux, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA2, ch_mixer); +static SOC_ENUM_SINGLE_DECL(mm3_channel_mux, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA3, ch_mixer); +static SOC_ENUM_SINGLE_DECL(mm4_channel_mux, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA4, ch_mixer); + +static SOC_ENUM_DOUBLE_DECL(mm1_ch1_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA1, 0, be_name); +static SOC_ENUM_DOUBLE_DECL(mm1_ch2_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, be_name); +static SOC_ENUM_DOUBLE_DECL(mm1_ch3_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA1, 2, be_name); +static SOC_ENUM_DOUBLE_DECL(mm1_ch4_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA1, 3, be_name); +static SOC_ENUM_DOUBLE_DECL(mm1_ch5_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA1, 4, be_name); +static SOC_ENUM_DOUBLE_DECL(mm1_ch6_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA1, 5, be_name); +static SOC_ENUM_DOUBLE_DECL(mm1_ch7_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA1, 6, be_name); +static SOC_ENUM_DOUBLE_DECL(mm1_ch8_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA1, 7, be_name); + +static int msm_pcm_get_ctl_enum_info(struct snd_ctl_elem_info *uinfo, + unsigned int channels, + unsigned int items, const char *const names[]) +{ + if (uinfo->value.enumerated.item >= items) + uinfo->value.enumerated.item = items - 1; + + WARN(strlen(names[uinfo->value.enumerated.item]) >= + sizeof(uinfo->value.enumerated.name), + "ALSA: too long item name '%s'\n", + names[uinfo->value.enumerated.item]); + strlcpy(uinfo->value.enumerated.name, + names[uinfo->value.enumerated.item], + sizeof(uinfo->value.enumerated.name)); + return 0; +} + +static int msm_pcm_channel_mixer_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + + uinfo->value.enumerated.items = ARRAY_SIZE(ch_mixer); + msm_pcm_get_ctl_enum_info(uinfo, 1, e->items, e->texts); + + return 0; +} +static int msm_pcm_channel_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u16 fe_id = 0; + + fe_id = ((struct soc_enum *) + kcontrol->private_value)->shift_l; + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %d\n", __func__, fe_id); + return -EINVAL; + } + + pr_debug("%s: FE %d %s\n", __func__, + fe_id, + channel_mixer[fe_id].enable ? "Enabled" : "Disabled"); + ucontrol->value.enumerated.item[0] = channel_mixer[fe_id].enable; + return 0; +} + +static int msm_pcm_channel_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u16 fe_id = 0; + + fe_id = ((struct soc_enum *) + kcontrol->private_value)->shift_l; + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %d\n", __func__, fe_id); + return -EINVAL; + } + + channel_mixer[fe_id].enable = ucontrol->value.enumerated.item[0]; + pr_debug("%s: %s FE %d\n", __func__, + channel_mixer[fe_id].enable ? "Enable" : "Disable", + fe_id); + return 0; +} + +static int msm_pcm_channel_input_be_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + + uinfo->value.enumerated.items = ARRAY_SIZE(be_name); + msm_pcm_get_ctl_enum_info(uinfo, 1, e->items, e->texts); + + return 0; +} + +static int msm_pcm_channel_input_be_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + u16 fe_id = 0, in_ch = 0; + + fe_id = e->shift_l; + in_ch = e->shift_r; + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %d\n", __func__, fe_id); + return -EINVAL; + } + if (in_ch >= ADM_MAX_CHANNELS) { + pr_err("%s: invalid input channel %d\n", __func__, in_ch); + return -EINVAL; + } + + channel_input[fe_id][in_ch] = ucontrol->value.enumerated.item[0]; + return 1; +} + +static int msm_pcm_channel_input_be_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + u16 fe_id = 0, in_ch = 0; + + fe_id = e->shift_l; + in_ch = e->shift_r; + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %d\n", __func__, fe_id); + return -EINVAL; + } + if (in_ch >= ADM_MAX_CHANNELS) { + pr_err("%s: invalid input channel %d\n", __func__, in_ch); + return -EINVAL; + } + + ucontrol->value.enumerated.item[0] = channel_input[fe_id][in_ch]; + return 1; +} + + +static int msm_pcm_channel_weight_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = ADM_MAX_CHANNELS; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = WEIGHT_0_DB; + + return 0; +} + +static int msm_pcm_channel_weight_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u16 fe_id = 0, out_ch = 0; + int i, weight; + + fe_id = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + out_ch = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->rshift; + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %d\n", __func__, fe_id); + return -EINVAL; + } + if (out_ch >= ADM_MAX_CHANNELS) { + pr_err("%s: invalid input channel %d\n", __func__, out_ch); + return -EINVAL; + } + + pr_debug("%s: FE_ID: %d, channel weight %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld\n", + __func__, fe_id, + ucontrol->value.integer.value[0], + ucontrol->value.integer.value[1], + ucontrol->value.integer.value[2], + ucontrol->value.integer.value[3], + ucontrol->value.integer.value[4], + ucontrol->value.integer.value[5], + ucontrol->value.integer.value[6], + ucontrol->value.integer.value[7]); + + for (i = 0; i < ADM_MAX_CHANNELS; ++i) { + weight = ucontrol->value.integer.value[i]; + channel_mixer[fe_id].channel_weight[out_ch][i] = weight; + pr_debug("%s: FE_ID %d, output %d input %d weight %d\n", + __func__, fe_id, out_ch, i, + channel_mixer[fe_id].channel_weight[out_ch][i]); + } + + return 0; +} + +static int msm_pcm_channel_weight_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u16 fe_id = 0, out_ch = 0; + int i; + + fe_id = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + out_ch = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->rshift; + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %d\n", __func__, fe_id); + return -EINVAL; + } + if (out_ch >= ADM_MAX_CHANNELS) { + pr_err("%s: invalid input channel %d\n", __func__, out_ch); + return -EINVAL; + } + + for (i = 0; i < ADM_MAX_CHANNELS; ++i) + ucontrol->value.integer.value[i] = + channel_mixer[fe_id].channel_weight[out_ch][i]; + + pr_debug("%s: FE_ID: %d, weight %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld", + __func__, fe_id, + ucontrol->value.integer.value[0], + ucontrol->value.integer.value[1], + ucontrol->value.integer.value[2], + ucontrol->value.integer.value[3], + ucontrol->value.integer.value[4], + ucontrol->value.integer.value[5], + ucontrol->value.integer.value[6], + ucontrol->value.integer.value[7]); + + return 0; +} + +static const struct snd_kcontrol_new channel_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1 Channel Rule", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA1, 8, 0, + msm_pcm_get_channel_rule_index, + msm_pcm_put_channel_rule_index), + SOC_SINGLE_EXT("MultiMedia2 Channel Rule", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA2, 8, 0, + msm_pcm_get_channel_rule_index, + msm_pcm_put_channel_rule_index), + SOC_SINGLE_EXT("MultiMedia3 Channel Rule", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA3, 8, 0, + msm_pcm_get_channel_rule_index, + msm_pcm_put_channel_rule_index), + SOC_SINGLE_EXT("MultiMedia4 Channel Rule", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA4, 8, 0, + msm_pcm_get_channel_rule_index, + msm_pcm_put_channel_rule_index), + SOC_SINGLE_EXT("MultiMedia5 Channel Rule", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA5, 8, 0, + msm_pcm_get_channel_rule_index, + msm_pcm_put_channel_rule_index), + SOC_SINGLE_EXT("MultiMedia6 Channel Rule", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA6, 8, 0, + msm_pcm_get_channel_rule_index, + msm_pcm_put_channel_rule_index), + + SOC_SINGLE_EXT("MultiMedia1 Channels", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA1, 8, 0, + msm_pcm_get_out_chs, + msm_pcm_put_out_chs), + SOC_SINGLE_EXT("MultiMedia2 Channels", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA2, 8, 0, + msm_pcm_get_out_chs, + msm_pcm_put_out_chs), + SOC_SINGLE_EXT("MultiMedia3 Channels", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA3, 8, 0, + msm_pcm_get_out_chs, + msm_pcm_put_out_chs), + SOC_SINGLE_EXT("MultiMedia4 Channels", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA4, 8, 0, + msm_pcm_get_out_chs, + msm_pcm_put_out_chs), + SOC_SINGLE_EXT("MultiMedia5 Channels", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA5, 8, 0, + msm_pcm_get_out_chs, + msm_pcm_put_out_chs), + SOC_SINGLE_EXT("MultiMedia6 Channels", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA6, 8, 0, + msm_pcm_get_out_chs, + msm_pcm_put_out_chs), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel Mixer", + .info = msm_pcm_channel_mixer_info, + .get = msm_pcm_channel_mixer_get, + .put = msm_pcm_channel_mixer_put, + .private_value = (unsigned long)&(mm1_channel_mux) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia2 Channel Mixer", + .info = msm_pcm_channel_mixer_info, + .get = msm_pcm_channel_mixer_get, + .put = msm_pcm_channel_mixer_put, + .private_value = (unsigned long)&(mm2_channel_mux) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia3 Channel Mixer", + .info = msm_pcm_channel_mixer_info, + .get = msm_pcm_channel_mixer_get, + .put = msm_pcm_channel_mixer_put, + .private_value = (unsigned long)&(mm3_channel_mux) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia4 Channel Mixer", + .info = msm_pcm_channel_mixer_info, + .get = msm_pcm_channel_mixer_get, + .put = msm_pcm_channel_mixer_put, + .private_value = (unsigned long)&(mm4_channel_mux) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Output Channel1", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1, .rshift = 0,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Output Channel2", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1, .rshift = 1, } + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Output Channel3", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1, .rshift = 2,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Output Channel4", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1, .rshift = 3,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Output Channel5", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1, .rshift = 4,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Output Channel6", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1, .rshift = 5,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Output Channel7", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1, .rshift = 6,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Output Channel8", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1, .rshift = 7,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia2 Output Channel1", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + {.shift = MSM_FRONTEND_DAI_MULTIMEDIA2, .rshift = 0,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia2 Output Channel2", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + {.shift = MSM_FRONTEND_DAI_MULTIMEDIA2, .rshift = 1,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia2 Output Channel3", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + {.shift = MSM_FRONTEND_DAI_MULTIMEDIA2, .rshift = 2,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia3 Output Channel1", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + {.shift = MSM_FRONTEND_DAI_MULTIMEDIA3, .rshift = 0,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia3 Output Channel2", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + {.shift = MSM_FRONTEND_DAI_MULTIMEDIA3, .rshift = 1,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel1", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm1_ch1_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel2", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm1_ch2_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel3", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm1_ch3_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel4", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm1_ch4_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel5", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm1_ch5_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel6", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm1_ch6_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel7", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm1_ch7_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel8", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm1_ch8_enum) + }, +}; +static int msm_ec_ref_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_ec_ref_ch; + pr_debug("%s: msm_ec_ref_ch = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_ec_ref_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_ec_ref_ch = ucontrol->value.integer.value[0]; + pr_debug("%s: msm_ec_ref_ch = %d\n", __func__, msm_ec_ref_ch); + adm_num_ec_ref_rx_chans(msm_ec_ref_ch); + return 0; +} + +static const char *const ec_ref_ch_text[] = {"Zero", "One", "Two", "Three", + "Four", "Five", "Six", "Seven", "Eight"}; + +static int msm_ec_ref_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_ec_ref_bit_format) { + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S16_LE: + ucontrol->value.integer.value[0] = 1; + break; + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: msm_ec_ref_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_ec_ref_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u16 bit_width = 0; + + switch (ucontrol->value.integer.value[0]) { + case 2: + msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 1: + msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + default: + msm_ec_ref_bit_format = 0; + break; + } + + if (msm_ec_ref_bit_format == SNDRV_PCM_FORMAT_S16_LE) + bit_width = 16; + else if (msm_ec_ref_bit_format == SNDRV_PCM_FORMAT_S24_LE) + bit_width = 24; + + pr_debug("%s: msm_ec_ref_bit_format = %d\n", + __func__, msm_ec_ref_bit_format); + adm_ec_ref_rx_bit_width(bit_width); + return 0; +} + +static char const *ec_ref_bit_format_text[] = {"0", "S16_LE", "S24_LE"}; + +static int msm_ec_ref_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_ec_ref_sampling_rate; + pr_debug("%s: msm_ec_ref_sampling_rate = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_ec_ref_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_ec_ref_sampling_rate = 0; + break; + case 1: + msm_ec_ref_sampling_rate = 8000; + break; + case 2: + msm_ec_ref_sampling_rate = 16000; + break; + case 3: + msm_ec_ref_sampling_rate = 32000; + break; + case 4: + msm_ec_ref_sampling_rate = 44100; + break; + case 5: + msm_ec_ref_sampling_rate = 48000; + break; + case 6: + msm_ec_ref_sampling_rate = 96000; + break; + case 7: + msm_ec_ref_sampling_rate = 192000; + break; + case 8: + msm_ec_ref_sampling_rate = 384000; + break; + default: + msm_ec_ref_sampling_rate = 48000; + break; + } + pr_debug("%s: msm_ec_ref_sampling_rate = %d\n", + __func__, msm_ec_ref_sampling_rate); + adm_ec_ref_rx_sampling_rate(msm_ec_ref_sampling_rate); + return 0; +} + +static const char *const ec_ref_rate_text[] = {"0", "8000", "16000", + "32000", "44100", "48000", "96000", "192000", "384000"}; + +static const struct soc_enum msm_route_ec_ref_params_enum[] = { + SOC_ENUM_SINGLE_EXT(9, ec_ref_ch_text), + SOC_ENUM_SINGLE_EXT(3, ec_ref_bit_format_text), + SOC_ENUM_SINGLE_EXT(9, ec_ref_rate_text), +}; + +static const struct snd_kcontrol_new ec_ref_param_controls[] = { + SOC_ENUM_EXT("EC Reference Channels", msm_route_ec_ref_params_enum[0], + msm_ec_ref_ch_get, msm_ec_ref_ch_put), + SOC_ENUM_EXT("EC Reference Bit Format", msm_route_ec_ref_params_enum[1], + msm_ec_ref_bit_format_get, msm_ec_ref_bit_format_put), + SOC_ENUM_EXT("EC Reference SampleRate", msm_route_ec_ref_params_enum[2], + msm_ec_ref_rate_get, msm_ec_ref_rate_put), +}; + +static int msm_routing_ec_ref_rx_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: ec_ref_rx = %d", __func__, msm_route_ec_ref_rx); + mutex_lock(&routing_lock); + ucontrol->value.integer.value[0] = msm_route_ec_ref_rx; + mutex_unlock(&routing_lock); + return 0; +} + +static int msm_routing_ec_ref_rx_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ec_ref_port_id; + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + + + mutex_lock(&routing_lock); + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_route_ec_ref_rx = 0; + ec_ref_port_id = AFE_PORT_INVALID; + break; + case 1: + msm_route_ec_ref_rx = 1; + ec_ref_port_id = SLIMBUS_0_RX; + break; + case 2: + msm_route_ec_ref_rx = 2; + ec_ref_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; + break; + case 3: + msm_route_ec_ref_rx = 3; + ec_ref_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; + break; + case 4: + msm_route_ec_ref_rx = 4; + ec_ref_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; + break; + case 5: + msm_route_ec_ref_rx = 5; + ec_ref_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + break; + case 6: + msm_route_ec_ref_rx = 6; + ec_ref_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + case 7: + msm_route_ec_ref_rx = 7; + ec_ref_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; + break; + case 9: + msm_route_ec_ref_rx = 9; + ec_ref_port_id = SLIMBUS_5_RX; + break; + case 10: + msm_route_ec_ref_rx = 10; + ec_ref_port_id = SLIMBUS_1_TX; + break; + case 11: + msm_route_ec_ref_rx = 11; + ec_ref_port_id = AFE_PORT_ID_QUATERNARY_TDM_TX_1; + break; + case 12: + msm_route_ec_ref_rx = 12; + ec_ref_port_id = AFE_PORT_ID_QUATERNARY_TDM_RX; + break; + case 13: + msm_route_ec_ref_rx = 13; + ec_ref_port_id = AFE_PORT_ID_QUATERNARY_TDM_RX_1; + break; + case 14: + msm_route_ec_ref_rx = 14; + ec_ref_port_id = AFE_PORT_ID_QUATERNARY_TDM_RX_2; + break; + case 15: + msm_route_ec_ref_rx = 15; + ec_ref_port_id = SLIMBUS_6_RX; + break; + case 16: + msm_route_ec_ref_rx = 16; + ec_ref_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; + break; + case 17: + msm_route_ec_ref_rx = 17; + ec_ref_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; + break; + case 18: + msm_route_ec_ref_rx = 18; + ec_ref_port_id = AFE_PORT_ID_TERTIARY_TDM_TX; + break; + case 19: + msm_route_ec_ref_rx = 19; + ec_ref_port_id = AFE_PORT_ID_USB_RX; + break; + case 20: + msm_route_ec_ref_rx = 20; + ec_ref_port_id = AFE_PORT_ID_INT0_MI2S_RX; + break; + case 21: + msm_route_ec_ref_rx = 21; + ec_ref_port_id = AFE_PORT_ID_INT4_MI2S_RX; + break; + case 22: + msm_route_ec_ref_rx = 22; + ec_ref_port_id = AFE_PORT_ID_INT3_MI2S_TX; + break; + default: + msm_route_ec_ref_rx = 0; /* NONE */ + pr_err("%s EC ref rx %ld not valid\n", + __func__, ucontrol->value.integer.value[0]); + ec_ref_port_id = AFE_PORT_INVALID; + break; + } + adm_ec_ref_rx_id(ec_ref_port_id); + pr_debug("%s: msm_route_ec_ref_rx = %d\n", + __func__, msm_route_ec_ref_rx); + mutex_unlock(&routing_lock); + snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, + msm_route_ec_ref_rx, e, update); + return 0; +} + +static const char *const ec_ref_rx[] = { "None", "SLIM_RX", "I2S_RX", + "PRI_MI2S_TX", "SEC_MI2S_TX", + "TERT_MI2S_TX", "QUAT_MI2S_TX", "SEC_I2S_RX", "PROXY_RX", + "SLIM_5_RX", "SLIM_1_TX", "QUAT_TDM_TX_1", + "QUAT_TDM_RX_0", "QUAT_TDM_RX_1", "QUAT_TDM_RX_2", "SLIM_6_RX", + "TERT_MI2S_RX", "QUAT_MI2S_RX", "TERT_TDM_TX_0", "USB_AUDIO_RX", + "INT0_MI2S_RX", "INT4_MI2S_RX", "INT3_MI2S_TX"}; + +static const struct soc_enum msm_route_ec_ref_rx_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ec_ref_rx), ec_ref_rx), +}; + +static const struct snd_kcontrol_new ext_ec_ref_mux_ul1 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL1 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + +static const struct snd_kcontrol_new ext_ec_ref_mux_ul2 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL2 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + +static const struct snd_kcontrol_new ext_ec_ref_mux_ul3 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL3 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + +static const struct snd_kcontrol_new ext_ec_ref_mux_ul4 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL4 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + +static const struct snd_kcontrol_new ext_ec_ref_mux_ul5 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL5 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + +static const struct snd_kcontrol_new ext_ec_ref_mux_ul6 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL6 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + +static const struct snd_kcontrol_new ext_ec_ref_mux_ul8 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL8 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + +static const struct snd_kcontrol_new ext_ec_ref_mux_ul9 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL9 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + +static const struct snd_kcontrol_new ext_ec_ref_mux_ul17 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL17 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + +static const struct snd_kcontrol_new ext_ec_ref_mux_ul18 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL18 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + +static const struct snd_kcontrol_new ext_ec_ref_mux_ul19 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL19 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + +static int msm_routing_ext_ec_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: ext_ec_ref_rx = %x\n", __func__, msm_route_ext_ec_ref); + + mutex_lock(&routing_lock); + ucontrol->value.integer.value[0] = msm_route_ext_ec_ref; + mutex_unlock(&routing_lock); + return 0; +} + +static int msm_routing_ext_ec_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + int mux = ucontrol->value.enumerated.item[0]; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int ret = 1; + bool state = true; + uint16_t ext_ec_ref_port_id; + struct snd_soc_dapm_update *update = NULL; + + if (mux >= e->items) { + pr_err("%s: Invalid mux value %d\n", __func__, mux); + return -EINVAL; + } + + mutex_lock(&routing_lock); + msm_route_ext_ec_ref = ucontrol->value.integer.value[0]; + + switch (msm_route_ext_ec_ref) { + case EXT_EC_REF_PRI_MI2S_TX: + ext_ec_ref_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; + break; + case EXT_EC_REF_SEC_MI2S_TX: + ext_ec_ref_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; + break; + case EXT_EC_REF_TERT_MI2S_TX: + ext_ec_ref_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + break; + case EXT_EC_REF_QUAT_MI2S_TX: + ext_ec_ref_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + case EXT_EC_REF_QUIN_MI2S_TX: + ext_ec_ref_port_id = AFE_PORT_ID_QUINARY_MI2S_TX; + break; + case EXT_EC_REF_SLIM_1_TX: + ext_ec_ref_port_id = SLIMBUS_1_TX; + break; + case EXT_EC_REF_NONE: + default: + ext_ec_ref_port_id = AFE_PORT_INVALID; + state = false; + break; + } + + pr_debug("%s: val = %d ext_ec_ref_port_id = 0x%0x state = %d\n", + __func__, msm_route_ext_ec_ref, ext_ec_ref_port_id, state); + + if (!voc_set_ext_ec_ref_port_id(ext_ec_ref_port_id, state)) { + mutex_unlock(&routing_lock); + snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, mux, e, + update); + } else { + ret = -EINVAL; + mutex_unlock(&routing_lock); + } + return ret; +} + +static const char * const ext_ec_ref_rx[] = {"NONE", "PRI_MI2S_TX", + "SEC_MI2S_TX", "TERT_MI2S_TX", + "QUAT_MI2S_TX", "QUIN_MI2S_TX", + "SLIM_1_TX"}; + +static const struct soc_enum msm_route_ext_ec_ref_rx_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ext_ec_ref_rx), ext_ec_ref_rx), +}; + +static const struct snd_kcontrol_new voc_ext_ec_mux = + SOC_DAPM_ENUM_EXT("VOC_EXT_EC MUX Mux", msm_route_ext_ec_ref_rx_enum[0], + msm_routing_ext_ec_get, msm_routing_ext_ec_put); + + +static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new spdif_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + +}; + +static const struct snd_kcontrol_new slimbus_2_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new slimbus_5_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quinary_mi2s_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new tertiary_mi2s_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new secondary_mi2s_rx2_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_SD1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new int0_mi2s_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new int4_mi2s_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new hdmi_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new display_port_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + + /* incall music delivery mixer */ +static const struct snd_kcontrol_new incall_music_delivery_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new incall_music2_delivery_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new slimbus_4_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_4_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_4_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SLIMBUS_4_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SLIMBUS_4_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new slimbus_6_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new slimbus_7_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new usb_audio_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new int_bt_a2dp_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new tert_auxpcm_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quat_auxpcm_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_tx_0_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_tx_0_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_0_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_tx_0_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_1_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_tx_0_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_1_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul1_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_TX", MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul2_mixer_controls[] = { + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul3_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AUX_PCM_TX", MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_AUX_PCM_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_AUX_PCM_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul4_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul5_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_AUX_PCM_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_AUX_PCM_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul6_mixer_controls[] = { + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul8_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul9_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul17_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul18_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul19_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul20_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new sec_mi2s_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new slimbus_6_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new usb_audio_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new mi2s_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new pri_mi2s_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new int0_mi2s_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new int4_mi2s_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tert_mi2s_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new quat_mi2s_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new quin_mi2s_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new sec_aux_pcm_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tert_aux_pcm_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new quat_aux_pcm_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new slimbus_7_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new slimbus_8_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_2_voice_mixer_controls[] = { + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new stub_rx_mixer_controls[] = { + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_EXTPROC_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_EXTPROC_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_EXTPROC_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +}; + +static const struct snd_kcontrol_new slimbus_1_rx_mixer_controls[] = { + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +}; + +static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = { + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +}; + +static const struct snd_kcontrol_new tx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_TX_Voice", MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("MI2S_TX_Voice", MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_0_TX_Voice", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice", + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_CS_VOICE, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX_Voice", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("AUX_PCM_TX_Voice", MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_TX_Voice", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("TERT_AUX_PCM_TX_Voice", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_Voice", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX_Voice", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_Voice", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_Voice", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_7_TX_Voice", MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_8_TX_Voice", MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX_Voice", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tx_voice2_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_TX_Voice2", MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("MI2S_TX_Voice2", MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_0_TX_Voice2", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice2", + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICE2, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX_Voice2", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("TERT_AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX_Voice2", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_Voice2", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_7_TX_Voice2", MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_8_TX_Voice2", MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX_Voice2", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tx_volte_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_TX_VoLTE", MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_0_TX_VoLTE", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_VoLTE", + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOLTE, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX_VoLTE", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("AUX_PCM_TX_VoLTE", MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_TX_VoLTE", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("TERT_AUX_PCM_TX_VoLTE", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_VoLTE", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("MI2S_TX_VoLTE", MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX_VoLTE", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_VoLTE", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_7_TX_VoLTE", MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_8_TX_VoLTE", MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX_VoLTE", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tx_vowlan_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_TX_VoWLAN", MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_0_TX_VoWLAN", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_VoWLAN", + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOWLAN, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX_VoWLAN", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("AUX_PCM_TX_VoWLAN", MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_TX_VoWLAN", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("TERT_AUX_PCM_TX_VoWLAN", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_VoWLAN", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("MI2S_TX_VoWLAN", MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX_VoWLAN", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_VoWLAN", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_7_TX_VoWLAN", MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_8_TX_VoWLAN", MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX_VoWLAN", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_TX_MMode1", MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("MI2S_TX_MMode1", MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_0_TX_MMode1", + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("INT_BT_SCO_TX_MMode1", + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX_MMode1", + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("AUX_PCM_TX_MMode1", + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_TX_MMode1", + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("TERT_AUX_PCM_TX_MMode1", + MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_MMode1", + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX_MMode1", + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_MMode1", + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX_MMode1", + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_7_TX_MMode1", + MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_8_TX_MMode1", + MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX_MMode1", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0_MMode1", + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_TX_MMode2", MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("MI2S_TX_MMode2", MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_0_TX_MMode2", + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("INT_BT_SCO_TX_MMode2", + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX_MMode2", + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("AUX_PCM_TX_MMode2", + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_TX_MMode2", + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("TERT_AUX_PCM_TX_MMode2", + MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_MMode2", + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX_MMode2", + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_MMode2", + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX_MMode2", + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_7_TX_MMode2", + MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_8_TX_MMode2", + MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX_MMode2", + MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_TX_Voip", MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("MI2S_TX_Voip", MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_0_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voip", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX_Voip", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("AUX_PCM_TX_Voip", MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_TX_Voip", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("TERT_AUX_PCM_TX_Voip", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_Voip", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX_Voip", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_Voip", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX_Voip", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_7_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_8_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX_Voip", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { + SOC_SINGLE_EXT("STUB_TX_HL", MSM_BACKEND_DAI_EXTPROC_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("STUB_1_TX_HL", MSM_BACKEND_DAI_EXTPROC_EC_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SLIM_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +}; + +static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = { + SOC_SINGLE_EXT("STUB_TX_HL", MSM_BACKEND_DAI_EXTPROC_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("STUB_1_TX_HL", MSM_BACKEND_DAI_EXTPROC_EC_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SLIM_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +}; + +static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = { + SOC_SINGLE_EXT("STUB_TX_HL", MSM_BACKEND_DAI_EXTPROC_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("STUB_1_TX_HL", MSM_BACKEND_DAI_EXTPROC_EC_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SLIM_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +}; + +static const struct snd_kcontrol_new tx_qchat_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_TX_QCHAT", MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_0_TX_QCHAT", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_QCHAT", + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX_QCHAT", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("AUX_PCM_TX_QCHAT", MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_TX_QCHAT", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("TERT_AUX_PCM_TX_QCHAT", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_QCHAT", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("MI2S_TX_QCHAT", MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX_QCHAT", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_QCHAT", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX_QCHAT", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_7_TX_QCHAT", MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("SLIM_8_TX_QCHAT", MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX_QCHAT", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new int0_mi2s_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_INT3_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new int4_mi2s_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_INT3_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_MI2S_RX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_PRI_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_RX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_RX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_RX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new aux_pcm_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_auxpcm_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_auxpcm_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_auxpcm_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sbus_1_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sbus_3_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("INTERNAL_BT_SCO_RX", MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_RX", MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_RX", MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_BACKEND_DAI_AUXPCM_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_0_RX", MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_BACKEND_DAI_SLIMBUS_0_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sbus_6_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new bt_sco_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new afe_pcm_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + + +static const struct snd_kcontrol_new hdmi_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_HDMI_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new display_port_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_i2s_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new mi2s_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new primary_mi2s_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new usb_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_USB_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_mi2s_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_0_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_1_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_2_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_3_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_0_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_1_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_2_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_3_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_0_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_1_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_2_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_3_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_0_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_1_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_2_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_3_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_mi2s_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_mi2s_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new lsm1_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm2_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm3_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm4_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm5_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm6_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm7_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new lsm8_mixer_controls[] = { + SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +}; + +static const struct snd_kcontrol_new slim_fm_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new slim1_fm_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new slim3_fm_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new slim4_fm_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new slim6_fm_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new pcm_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_fm_pcmrx_switch_mixer, + msm_routing_put_fm_pcmrx_switch_mixer); + +static const struct snd_kcontrol_new int0_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_int0_mi2s_switch_mixer, + msm_routing_put_int0_mi2s_switch_mixer); + +static const struct snd_kcontrol_new int4_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_int4_mi2s_switch_mixer, + msm_routing_put_int4_mi2s_switch_mixer); + +static const struct snd_kcontrol_new pri_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_pri_mi2s_switch_mixer, + msm_routing_put_pri_mi2s_switch_mixer); + +static const struct snd_kcontrol_new sec_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_sec_mi2s_switch_mixer, + msm_routing_put_sec_mi2s_switch_mixer); + +static const struct snd_kcontrol_new tert_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_tert_mi2s_switch_mixer, + msm_routing_put_tert_mi2s_switch_mixer); + +static const struct snd_kcontrol_new quat_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_quat_mi2s_switch_mixer, + msm_routing_put_quat_mi2s_switch_mixer); + +static const struct snd_kcontrol_new hfp_pri_aux_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_hfp_switch_mixer, + msm_routing_put_hfp_switch_mixer); + +static const struct snd_kcontrol_new hfp_aux_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_hfp_switch_mixer, + msm_routing_put_hfp_switch_mixer); + +static const struct snd_kcontrol_new hfp_int_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_hfp_switch_mixer, + msm_routing_put_hfp_switch_mixer); + +static const struct snd_kcontrol_new hfp_slim7_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_hfp_switch_mixer, + msm_routing_put_hfp_switch_mixer); + +static const struct snd_kcontrol_new usb_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_usb_switch_mixer, + msm_routing_put_usb_switch_mixer); + +static const struct soc_enum lsm_port_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_port_text), lsm_port_text); + +static const char * const lsm_func_text[] = { + "None", "AUDIO", "BEACON", "ULTRASOUND", "SWAUDIO", +}; +static const struct soc_enum lsm_func_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_func_text), lsm_func_text); + +static const struct snd_kcontrol_new lsm_controls[] = { + /* kcontrol of lsm_function */ + SOC_ENUM_EXT(SLIMBUS_0_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(SLIMBUS_1_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(SLIMBUS_2_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(SLIMBUS_3_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(SLIMBUS_4_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(SLIMBUS_5_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(TERT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(QUAT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(INT3_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + /* kcontrol of lsm_port */ + SOC_ENUM_EXT("LSM1 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM2 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM3 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM4 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM5 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM6 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM7 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM8 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), +}; + +static const char * const aanc_slim_0_rx_text[] = { + "ZERO", "SLIMBUS_0_TX", "SLIMBUS_1_TX", "SLIMBUS_2_TX", "SLIMBUS_3_TX", + "SLIMBUS_4_TX", "SLIMBUS_5_TX", "SLIMBUS_6_TX" +}; + +static const struct soc_enum aanc_slim_0_rx_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(aanc_slim_0_rx_text), + aanc_slim_0_rx_text); + +static const struct snd_kcontrol_new aanc_slim_0_rx_mux[] = { + SOC_ENUM_EXT("AANC_SLIM_0_RX MUX", aanc_slim_0_rx_enum, + msm_routing_slim_0_rx_aanc_mux_get, + msm_routing_slim_0_rx_aanc_mux_put) +}; + +static int msm_routing_get_stereo_to_custom_stereo_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = is_custom_stereo_on; + return 0; +} + +static int msm_routing_put_stereo_to_custom_stereo_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int flag = 0, i = 0, rc = 0, idx = 0; + int be_index = 0, port_id, topo_id; + unsigned int session_id = 0; + uint16_t op_FL_ip_FL_weight = 0; + uint16_t op_FL_ip_FR_weight = 0; + uint16_t op_FR_ip_FL_weight = 0; + uint16_t op_FR_ip_FR_weight = 0; + + flag = ucontrol->value.integer.value[0]; + pr_debug("%s E flag %d\n", __func__, flag); + + if ((is_custom_stereo_on && flag) || (!is_custom_stereo_on && !flag)) { + pr_err("%s: is_custom_stereo_on %d, flag %d\n", + __func__, is_custom_stereo_on, flag); + return 0; + } + is_custom_stereo_on = flag ? true : false; + pr_debug("%s:is_custom_stereo_on %d\n", __func__, is_custom_stereo_on); + for (be_index = 0; be_index < MSM_BACKEND_DAI_MAX; be_index++) { + port_id = msm_bedais[be_index].port_id; + if (!msm_bedais[be_index].active) + continue; + if ((port_id != SLIMBUS_0_RX) && + (port_id != RT_PROXY_PORT_001_RX) && + (port_id != AFE_PORT_ID_PRIMARY_MI2S_RX) && + (port_id != AFE_PORT_ID_INT4_MI2S_RX)) + continue; + + for_each_set_bit(i, &msm_bedais[be_index].fe_sessions[0], + MSM_FRONTEND_DAI_MM_SIZE) { + if (fe_dai_map[i][SESSION_TYPE_RX].perf_mode != + LEGACY_PCM_MODE) + goto skip_send_custom_stereo; + session_id = + fe_dai_map[i][SESSION_TYPE_RX].strm_id; + if (is_custom_stereo_on) { + op_FL_ip_FL_weight = + Q14_GAIN_ZERO_POINT_FIVE; + op_FL_ip_FR_weight = + Q14_GAIN_ZERO_POINT_FIVE; + op_FR_ip_FL_weight = + Q14_GAIN_ZERO_POINT_FIVE; + op_FR_ip_FR_weight = + Q14_GAIN_ZERO_POINT_FIVE; + } else { + op_FL_ip_FL_weight = Q14_GAIN_UNITY; + op_FL_ip_FR_weight = 0; + op_FR_ip_FL_weight = 0; + op_FR_ip_FR_weight = Q14_GAIN_UNITY; + } + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { + unsigned long copp = + session_copp_map[i] + [SESSION_TYPE_RX][be_index]; + if (!test_bit(idx, &copp)) + goto skip_send_custom_stereo; + topo_id = adm_get_topology_for_port_copp_idx( + msm_bedais[be_index].port_id, idx); + if (topo_id < 0) + pr_debug("%s:Err:custom stereo topo %d", + __func__, topo_id); + pr_debug("idx %d\n", idx); + if (topo_id == DS2_ADM_COPP_TOPOLOGY_ID) + rc = msm_ds2_dap_set_custom_stereo_onoff + (msm_bedais[be_index].port_id, + idx, is_custom_stereo_on); + else if (topo_id == DOLBY_ADM_COPP_TOPOLOGY_ID) + rc = dolby_dap_set_custom_stereo_onoff( + msm_bedais[be_index].port_id, + idx, is_custom_stereo_on); + else + rc = msm_qti_pp_send_stereo_to_custom_stereo_cmd + (msm_bedais[be_index].port_id, + idx, session_id, + op_FL_ip_FL_weight, + op_FL_ip_FR_weight, + op_FR_ip_FL_weight, + op_FR_ip_FR_weight); + if (rc < 0) +skip_send_custom_stereo: + pr_err("%s: err setting custom stereo\n", + __func__); + } + + } + } + return 0; +} + +static const struct snd_kcontrol_new stereo_to_custom_stereo_controls[] = { + SOC_SINGLE_EXT("Set Custom Stereo OnOff", SND_SOC_NOPM, 0, + 1, 0, msm_routing_get_stereo_to_custom_stereo_control, + msm_routing_put_stereo_to_custom_stereo_control), +}; + +static int msm_routing_get_app_type_cfg_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static int msm_routing_put_app_type_cfg_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int i = 0, j; + int num_app_types = ucontrol->value.integer.value[i++]; + + pr_debug("%s\n", __func__); + + memset(app_type_cfg, 0, MAX_APP_TYPES* + sizeof(struct msm_pcm_routing_app_type_data)); + if (num_app_types > MAX_APP_TYPES) { + pr_err("%s: number of app types exceed the max supported\n", + __func__); + return -EINVAL; + } + for (j = 0; j < num_app_types; j++) { + app_type_cfg[j].app_type = + ucontrol->value.integer.value[i++]; + app_type_cfg[j].sample_rate = + ucontrol->value.integer.value[i++]; + app_type_cfg[j].bit_width = + ucontrol->value.integer.value[i++]; + } + + return 0; +} + +static int msm_routing_put_app_type_gain_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int j, fe_id, be_id, port_type; + int ret = 0; + unsigned long copp; + struct msm_pcm_routing_bdai_data *bedai; + int dir = ucontrol->value.integer.value[0] ? SESSION_TYPE_TX : + SESSION_TYPE_RX; + int app_type = ucontrol->value.integer.value[1]; + int gain = (ucontrol->value.integer.value[2] + + ucontrol->value.integer.value[3])/2; + + port_type = (dir == SESSION_TYPE_RX) ? MSM_AFE_PORT_TYPE_RX : + MSM_AFE_PORT_TYPE_TX; + + mutex_lock(&routing_lock); + for (be_id = 0; be_id < MSM_BACKEND_DAI_MAX; be_id++) { + if (is_be_dai_extproc(be_id)) + continue; + + bedai = &msm_bedais[be_id]; + if (afe_get_port_type(bedai->port_id) != port_type) + continue; + + if (!bedai->active) + continue; + + for (fe_id = 0; fe_id < MSM_FRONTEND_DAI_MAX; fe_id++) { + if (!test_bit(fe_id, &bedai->fe_sessions[0])) + continue; + + if (app_type != + fe_dai_app_type_cfg[fe_id][dir][be_id].app_type) + continue; + + copp = session_copp_map[fe_id][dir][be_id]; + for (j = 0; j < MAX_COPPS_PER_PORT; j++) { + if (!test_bit(j, &copp)) + continue; + ret |= adm_set_volume(bedai->port_id, j, gain); + } + } + } + mutex_unlock(&routing_lock); + return ret ? -EINVAL : 0; +} + +static const struct snd_kcontrol_new app_type_cfg_controls[] = { + SOC_SINGLE_MULTI_EXT("App Type Config", SND_SOC_NOPM, 0, + 0xFFFFFFFF, 0, 128, msm_routing_get_app_type_cfg_control, + msm_routing_put_app_type_cfg_control), + SOC_SINGLE_MULTI_EXT("App Type Gain", SND_SOC_NOPM, 0, + 0x2000, 0, 4, NULL, msm_routing_put_app_type_gain_control) +}; + +static int msm_routing_get_lsm_app_type_cfg_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static int msm_routing_put_lsm_app_type_cfg_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int i = 0, j; + int num_app_types = ucontrol->value.integer.value[i++]; + + memset(lsm_app_type_cfg, 0, MAX_APP_TYPES* + sizeof(struct msm_pcm_routing_app_type_data)); + if (num_app_types > MAX_APP_TYPES) { + pr_err("%s: number of app types exceed the max supported\n", + __func__); + return -EINVAL; + } + for (j = 0; j < num_app_types; j++) { + lsm_app_type_cfg[j].app_type = + ucontrol->value.integer.value[i++]; + lsm_app_type_cfg[j].sample_rate = + ucontrol->value.integer.value[i++]; + lsm_app_type_cfg[j].bit_width = + ucontrol->value.integer.value[i++]; + } + + return 0; +} + +static const struct snd_kcontrol_new lsm_app_type_cfg_controls[] = { + SOC_SINGLE_MULTI_EXT("Listen App Type Config", SND_SOC_NOPM, 0, + 0xFFFFFFFF, 0, 128, msm_routing_get_lsm_app_type_cfg_control, + msm_routing_put_lsm_app_type_cfg_control), +}; + +static int msm_routing_get_use_ds1_or_ds2_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = is_ds2_on; + return 0; +} + +static int msm_routing_put_use_ds1_or_ds2_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + is_ds2_on = ucontrol->value.integer.value[0]; + return 0; +} + +static const struct snd_kcontrol_new use_ds1_or_ds2_controls[] = { + SOC_SINGLE_EXT("DS2 OnOff", SND_SOC_NOPM, 0, + 1, 0, msm_routing_get_use_ds1_or_ds2_control, + msm_routing_put_use_ds1_or_ds2_control), +}; + +int msm_routing_get_rms_value_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { + int rc = 0; + int be_idx = 0; + char *param_value; + int *update_param_value; + uint32_t param_length = sizeof(uint32_t); + uint32_t param_payload_len = RMS_PAYLOAD_LEN * sizeof(uint32_t); + + param_value = kzalloc(param_length + param_payload_len, GFP_KERNEL); + if (!param_value) + return -ENOMEM; + + for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) + if (msm_bedais[be_idx].port_id == SLIMBUS_0_TX) + break; + if ((be_idx < MSM_BACKEND_DAI_MAX) && msm_bedais[be_idx].active) { + rc = adm_get_params(SLIMBUS_0_TX, 0, + RMS_MODULEID_APPI_PASSTHRU, + RMS_PARAM_FIRST_SAMPLE, + param_length + param_payload_len, + param_value); + if (rc) { + pr_err("%s: get parameters failed:%d\n", __func__, rc); + kfree(param_value); + return -EINVAL; + } + update_param_value = (int *)param_value; + ucontrol->value.integer.value[0] = update_param_value[0]; + + pr_debug("%s: FROM DSP value[0] 0x%x\n", + __func__, update_param_value[0]); + } + kfree(param_value); + return 0; +} + +static int msm_voc_session_id_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + voc_session_id = ucontrol->value.integer.value[0]; + + pr_debug("%s: voc_session_id=%u\n", __func__, voc_session_id); + + return 0; +} + +static int msm_voc_session_id_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = voc_session_id; + + return 0; +} + +static struct snd_kcontrol_new msm_voc_session_controls[] = { + SOC_SINGLE_MULTI_EXT("Voc VSID", SND_SOC_NOPM, 0, + 0xFFFFFFFF, 0, 1, msm_voc_session_id_get, + msm_voc_session_id_put), +}; + +static int msm_sound_focus_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(struct sound_focus_param); + + return 0; +} + +static int msm_voice_sound_focus_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct sound_focus_param soundFocusData; + + memcpy((void *)&soundFocusData, ucontrol->value.bytes.data, + sizeof(struct sound_focus_param)); + ret = voc_set_sound_focus(soundFocusData); + if (ret) { + pr_err("%s: Error setting Sound Focus Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + } + + return ret; +} + +static int msm_voice_sound_focus_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct sound_focus_param soundFocusData; + + memset(&soundFocusData, 0, sizeof(struct sound_focus_param)); + + ret = voc_get_sound_focus(&soundFocusData); + if (ret) { + pr_err("%s: Error getting Sound Focus Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + memcpy(ucontrol->value.bytes.data, (void *)&soundFocusData, + sizeof(struct sound_focus_param)); + +done: + return ret; +} + +static int msm_source_tracking_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(struct source_tracking_param); + + return 0; +} + +static int msm_voice_source_tracking_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct source_tracking_param sourceTrackingData; + + memset(&sourceTrackingData, 0, sizeof(struct source_tracking_param)); + + ret = voc_get_source_tracking(&sourceTrackingData); + if (ret) { + pr_err("%s: Error getting Source Tracking Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + memcpy(ucontrol->value.bytes.data, (void *)&sourceTrackingData, + sizeof(struct source_tracking_param)); + +done: + return ret; +} + +static int msm_audio_get_copp_idx_from_port_id(int port_id, int session_type, + int *copp_idx) +{ + int i, idx, be_idx; + int ret = 0; + unsigned long copp; + + pr_debug("%s: Enter, port_id=%d\n", __func__, port_id); + + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: port validation failed id 0x%x ret %d\n", + __func__, port_id, ret); + + ret = -EINVAL; + goto done; + } + + for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) { + if (msm_bedais[be_idx].port_id == port_id) + break; + } + if (be_idx >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: Invalid be id %d\n", __func__, be_idx); + + ret = -EINVAL; + goto done; + } + + for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0], + MSM_FRONTEND_DAI_MM_SIZE) { + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { + copp = session_copp_map[i] + [session_type][be_idx]; + if (test_bit(idx, &copp)) + break; + } + if (idx >= MAX_COPPS_PER_PORT) + continue; + else + break; + } + if (i >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: Invalid FE, exiting\n", __func__); + + ret = -EINVAL; + goto done; + } + *copp_idx = idx; + pr_debug("%s: copp_idx=%d\n", __func__, *copp_idx); + +done: + return ret; +} + +static int msm_audio_sound_focus_derive_port_id(struct snd_kcontrol *kcontrol, + const char *prefix, int *port_id) +{ + int ret = 0; + + pr_debug("%s: Enter, prefix:%s\n", __func__, prefix); + + /* + * Mixer control name will be like "Sound Focus Audio Tx SLIMBUS_0" + * where the prefix is "Sound Focus Audio Tx ". Skip the prefix + * and compare the string with the backend name to derive the port id. + */ + if (!strcmp(kcontrol->id.name + strlen(prefix), + "SLIMBUS_0")) { + *port_id = SLIMBUS_0_TX; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "TERT_MI2S")) { + *port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "INT3_MI2S")) { + *port_id = AFE_PORT_ID_INT3_MI2S_TX; + } else { + pr_err("%s: mixer ctl name=%s, could not derive valid port id\n", + __func__, kcontrol->id.name); + + ret = -EINVAL; + goto done; + } + pr_debug("%s: mixer ctl name=%s, derived port_id=%d\n", + __func__, kcontrol->id.name, *port_id); + +done: + return ret; +} + +static int msm_audio_sound_focus_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct sound_focus_param soundFocusData; + int port_id, copp_idx; + + ret = msm_audio_sound_focus_derive_port_id(kcontrol, + "Sound Focus Audio Tx ", &port_id); + if (ret != 0) { + pr_err("%s: Error in deriving port id, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, + &copp_idx); + if (ret) { + pr_err("%s: Could not get copp idx for port_id=%d\n", + __func__, port_id); + + ret = -EINVAL; + goto done; + } + + memcpy((void *)&soundFocusData, ucontrol->value.bytes.data, + sizeof(struct sound_focus_param)); + + ret = adm_set_sound_focus(port_id, copp_idx, soundFocusData); + if (ret) { + pr_err("%s: Error setting Sound Focus Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + +done: + return ret; +} + +static int msm_audio_sound_focus_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct sound_focus_param soundFocusData; + int port_id, copp_idx; + + ret = msm_audio_sound_focus_derive_port_id(kcontrol, + "Sound Focus Audio Tx ", &port_id); + if (ret) { + pr_err("%s: Error in deriving port id, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, + &copp_idx); + if (ret) { + pr_err("%s: Could not get copp idx for port_id=%d\n", + __func__, port_id); + + ret = -EINVAL; + goto done; + } + + ret = adm_get_sound_focus(port_id, copp_idx, &soundFocusData); + if (ret) { + pr_err("%s: Error getting Sound Focus Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + memcpy(ucontrol->value.bytes.data, (void *)&soundFocusData, + sizeof(struct sound_focus_param)); + +done: + return ret; +} + +static int msm_audio_source_tracking_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct source_tracking_param sourceTrackingData; + int port_id, copp_idx; + + ret = msm_audio_sound_focus_derive_port_id(kcontrol, + "Source Tracking Audio Tx ", &port_id); + if (ret) { + pr_err("%s: Error in deriving port id, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, + &copp_idx); + if (ret) { + pr_err("%s: Could not get copp idx for port_id=%d\n", + __func__, port_id); + + ret = -EINVAL; + goto done; + } + + ret = adm_get_source_tracking(port_id, copp_idx, &sourceTrackingData); + if (ret) { + pr_err("%s: Error getting Source Tracking Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + memcpy(ucontrol->value.bytes.data, (void *)&sourceTrackingData, + sizeof(struct source_tracking_param)); + +done: + return ret; +} + +static const struct snd_kcontrol_new msm_source_tracking_controls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx SLIMBUS_0", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx SLIMBUS_0", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx SLIMBUS_0", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx SLIMBUS_0", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx TERT_MI2S", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx TERT_MI2S", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx TERT_MI2S", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx TERT_MI2S", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx INT3_MI2S", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx INT3_MI2S", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx INT3_MI2S", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx INT3_MI2S", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, +}; + +static int spkr_prot_put_vi_lch_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int item; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + + pr_debug("%s item is %d\n", __func__, + ucontrol->value.enumerated.item[0]); + mutex_lock(&routing_lock); + item = ucontrol->value.enumerated.item[0]; + if (item < e->items) { + pr_debug("%s RX DAI ID %d TX DAI id %d\n", + __func__, e->shift_l, e->values[item]); + if (e->shift_l < MSM_BACKEND_DAI_MAX && + e->values[item] < MSM_BACKEND_DAI_MAX) + /* Enable feedback TX path */ + ret = afe_spk_prot_feed_back_cfg( + msm_bedais[e->values[item]].port_id, + msm_bedais[e->shift_l].port_id, 1, 0, 1); + else { + pr_debug("%s values are out of range item %d\n", + __func__, e->values[item]); + /* Disable feedback TX path */ + if (e->values[item] == MSM_BACKEND_DAI_MAX) + ret = afe_spk_prot_feed_back_cfg(0, 0, 0, 0, 0); + else + ret = -EINVAL; + } + } else { + pr_err("%s item value is out of range item\n", __func__); + ret = -EINVAL; + } + mutex_unlock(&routing_lock); + return ret; +} + +static int spkr_prot_put_vi_rch_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int item; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + + pr_debug("%s item is %d\n", __func__, + ucontrol->value.enumerated.item[0]); + mutex_lock(&routing_lock); + item = ucontrol->value.enumerated.item[0]; + if (item < e->items) { + pr_debug("%s RX DAI ID %d TX DAI id %d\n", + __func__, e->shift_l, e->values[item]); + if (e->shift_l < MSM_BACKEND_DAI_MAX && + e->values[item] < MSM_BACKEND_DAI_MAX) + /* Enable feedback TX path */ + ret = afe_spk_prot_feed_back_cfg( + msm_bedais[e->values[item]].port_id, + msm_bedais[e->shift_l].port_id, + 1, 1, 1); + else { + pr_debug("%s values are out of range item %d\n", + __func__, e->values[item]); + /* Disable feedback TX path */ + if (e->values[item] == MSM_BACKEND_DAI_MAX) + ret = afe_spk_prot_feed_back_cfg(0, + 0, 0, 0, 0); + else + ret = -EINVAL; + } + } else { + pr_err("%s item value is out of range item\n", __func__); + ret = -EINVAL; + } + mutex_unlock(&routing_lock); + return ret; +} + +static int spkr_prot_get_vi_lch_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s\n", __func__); + return 0; +} + +static int spkr_prot_get_vi_rch_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s\n", __func__); + ucontrol->value.enumerated.item[0] = 0; + return 0; +} + +static const char * const slim0_rx_vi_fb_tx_lch_mux_text[] = { + "ZERO", "SLIM4_TX" +}; + +static const char * const slim0_rx_vi_fb_tx_rch_mux_text[] = { + "ZERO", "SLIM4_TX" +}; + +static const char * const mi2s_rx_vi_fb_tx_mux_text[] = { + "ZERO", "SENARY_TX" +}; + +static const char * const int4_mi2s_rx_vi_fb_tx_mono_mux_text[] = { + "ZERO", "INT5_MI2S_TX" +}; + +static const char * const int4_mi2s_rx_vi_fb_tx_stereo_mux_text[] = { + "ZERO", "INT5_MI2S_TX" +}; + +static const int const slim0_rx_vi_fb_tx_lch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SLIMBUS_4_TX +}; + +static const int const slim0_rx_vi_fb_tx_rch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SLIMBUS_4_TX +}; + +static const int const mi2s_rx_vi_fb_tx_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SENARY_MI2S_TX +}; + +static const int const int4_mi2s_rx_vi_fb_tx_mono_ch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_INT5_MI2S_TX +}; + +static const int const int4_mi2s_rx_vi_fb_tx_stereo_ch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_INT5_MI2S_TX +}; + +static const struct soc_enum slim0_rx_vi_fb_lch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_SLIMBUS_0_RX, 0, 0, + ARRAY_SIZE(slim0_rx_vi_fb_tx_lch_mux_text), + slim0_rx_vi_fb_tx_lch_mux_text, slim0_rx_vi_fb_tx_lch_value); + +static const struct soc_enum slim0_rx_vi_fb_rch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_SLIMBUS_0_RX, 0, 0, + ARRAY_SIZE(slim0_rx_vi_fb_tx_rch_mux_text), + slim0_rx_vi_fb_tx_rch_mux_text, slim0_rx_vi_fb_tx_rch_value); + +static const struct soc_enum mi2s_rx_vi_fb_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_PRI_MI2S_RX, 0, 0, + ARRAY_SIZE(mi2s_rx_vi_fb_tx_mux_text), + mi2s_rx_vi_fb_tx_mux_text, mi2s_rx_vi_fb_tx_value); + +static const struct soc_enum int4_mi2s_rx_vi_fb_mono_ch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_INT4_MI2S_RX, 0, 0, + ARRAY_SIZE(int4_mi2s_rx_vi_fb_tx_mono_mux_text), + int4_mi2s_rx_vi_fb_tx_mono_mux_text, + int4_mi2s_rx_vi_fb_tx_mono_ch_value); + +static const struct soc_enum int4_mi2s_rx_vi_fb_stereo_ch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_INT4_MI2S_RX, 0, 0, + ARRAY_SIZE(int4_mi2s_rx_vi_fb_tx_stereo_mux_text), + int4_mi2s_rx_vi_fb_tx_stereo_mux_text, + int4_mi2s_rx_vi_fb_tx_stereo_ch_value); + +static const struct snd_kcontrol_new slim0_rx_vi_fb_lch_mux = + SOC_DAPM_ENUM_EXT("SLIM0_RX_VI_FB_LCH_MUX", + slim0_rx_vi_fb_lch_mux_enum, spkr_prot_get_vi_lch_port, + spkr_prot_put_vi_lch_port); + +static const struct snd_kcontrol_new slim0_rx_vi_fb_rch_mux = + SOC_DAPM_ENUM_EXT("SLIM0_RX_VI_FB_RCH_MUX", + slim0_rx_vi_fb_rch_mux_enum, spkr_prot_get_vi_rch_port, + spkr_prot_put_vi_rch_port); + +static const struct snd_kcontrol_new mi2s_rx_vi_fb_mux = + SOC_DAPM_ENUM_EXT("PRI_MI2S_RX_VI_FB_MUX", + mi2s_rx_vi_fb_mux_enum, spkr_prot_get_vi_lch_port, + spkr_prot_put_vi_lch_port); + +static const struct snd_kcontrol_new int4_mi2s_rx_vi_fb_mono_ch_mux = + SOC_DAPM_ENUM_EXT("INT4_MI2S_RX_VI_FB_MONO_CH_MUX", + int4_mi2s_rx_vi_fb_mono_ch_mux_enum, spkr_prot_get_vi_lch_port, + spkr_prot_put_vi_lch_port); + +static const struct snd_kcontrol_new int4_mi2s_rx_vi_fb_stereo_ch_mux = + SOC_DAPM_ENUM_EXT("INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", + int4_mi2s_rx_vi_fb_stereo_ch_mux_enum, spkr_prot_get_vi_rch_port, + spkr_prot_put_vi_rch_port); + +static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { + /* Frontend AIF */ + /* Widget name equals to Front-End DAI name, + * Stream name must contains substring of front-end dai name + */ + SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL5", "MultiMedia5 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL6", "MultiMedia6 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL7", "MultiMedia7 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL8", "MultiMedia8 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL9", "MultiMedia9 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL10", "MultiMedia10 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL11", "MultiMedia11 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL12", "MultiMedia12 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL13", "MultiMedia13 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL14", "MultiMedia14 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL15", "MultiMedia15 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL16", "MultiMedia16 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL20", "MultiMedia20 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL3", "MultiMedia3 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL4", "MultiMedia4 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL5", "MultiMedia5 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL9", "MultiMedia9 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL17", "MultiMedia17 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL18", "MultiMedia18 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL19", "MultiMedia19 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL20", "MultiMedia20 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("CS-VOICE_DL1", "CS-VOICE Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOICE2_DL", "Voice2 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICE2_UL", "Voice2 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VoLTE_DL", "VoLTE Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VoLTE_UL", "VoLTE Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VoWLAN_DL", "VoWLAN Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VoWLAN_UL", "VoWLAN Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOICEMMODE1_DL", + "VoiceMMode1 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICEMMODE1_UL", + "VoiceMMode1 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOICEMMODE2_DL", + "VoiceMMode2 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICEMMODE2_UL", + "VoiceMMode2 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM0_DL_HL", "SLIMBUS0_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM0_UL_HL", "SLIMBUS0_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("CPE_LSM_UL_HL", "CPE LSM capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM1_DL_HL", "SLIMBUS1_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM1_UL_HL", "SLIMBUS1_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM3_DL_HL", "SLIMBUS3_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM3_UL_HL", "SLIMBUS3_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM4_DL_HL", "SLIMBUS4_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM4_UL_HL", "SLIMBUS4_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM6_DL_HL", "SLIMBUS6_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM6_UL_HL", "SLIMBUS6_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM7_DL_HL", "SLIMBUS7_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM7_UL_HL", "SLIMBUS7_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM8_DL_HL", "SLIMBUS8_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM8_UL_HL", "SLIMBUS8_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INTFM_DL_HL", "INT_FM_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INTHFP_DL_HL", "INT_HFP_BT_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INTHFP_UL_HL", "INT_HFP_BT_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("USBAUDIO_DL_HL", "USBAUDIO_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("USBAUDIO_UL_HL", "USBAUDIO_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("HDMI_DL_HL", "HDMI_HOSTLESS Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_I2S_DL_HL", "SEC_I2S_RX_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT0_MI2S_DL_HL", + "INT0 MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT4_MI2S_DL_HL", + "INT4 MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_MI2S_DL_HL", + "Primary MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_MI2S_DL_HL", + "Secondary MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_MI2S_DL_HL", + "Tertiary MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_MI2S_DL_HL", + "Quaternary MI2S_RX Hostless Playback", + 0, 0, 0, 0), + + SND_SOC_DAPM_AIF_IN("AUXPCM_DL_HL", "AUXPCM_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("AUXPCM_UL_HL", "AUXPCM_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MI2S_UL_HL", "MI2S_TX_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT3_MI2S_UL_HL", + "INT3 MI2S_TX Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_MI2S_UL_HL", + "Tertiary MI2S_TX Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_MI2S_UL_HL", + "Secondary MI2S_TX Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_MI2S_UL_HL", + "Primary MI2S_TX Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MI2S_DL_HL", "MI2S_RX_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("DTMF_DL_HL", "DTMF_RX_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_UL_HL", + "Quaternary MI2S_TX Hostless Capture", + 0, 0, 0, 0), + + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_0_DL_HL", + "Primary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_0_UL_HL", + "Primary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_1_DL_HL", + "Primary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_1_UL_HL", + "Primary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_2_DL_HL", + "Primary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_2_UL_HL", + "Primary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_3_DL_HL", + "Primary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_3_UL_HL", + "Primary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_4_DL_HL", + "Primary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_4_UL_HL", + "Primary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_5_DL_HL", + "Primary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_5_UL_HL", + "Primary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_6_DL_HL", + "Primary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_6_UL_HL", + "Primary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_7_DL_HL", + "Primary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_7_UL_HL", + "Primary TDM7 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_0_DL_HL", + "Secondary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_0_UL_HL", + "Secondary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_1_DL_HL", + "Secondary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_1_UL_HL", + "Secondary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_2_DL_HL", + "Secondary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_2_UL_HL", + "Secondary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_3_DL_HL", + "Secondary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_3_UL_HL", + "Secondary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_4_DL_HL", + "Secondary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_4_UL_HL", + "Secondary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_5_DL_HL", + "Secondary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_5_UL_HL", + "Secondary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_6_DL_HL", + "Secondary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_6_UL_HL", + "Secondary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_7_DL_HL", + "Secondary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_7_UL_HL", + "Secondary TDM7 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_0_DL_HL", + "Tertiary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_0_UL_HL", + "Tertiary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_1_DL_HL", + "Tertiary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_1_UL_HL", + "Tertiary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_2_DL_HL", + "Tertiary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_2_UL_HL", + "Tertiary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_3_DL_HL", + "Tertiary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_3_UL_HL", + "Tertiary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_4_DL_HL", + "Tertiary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_4_UL_HL", + "Tertiary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_5_DL_HL", + "Tertiary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_5_UL_HL", + "Tertiary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_6_DL_HL", + "Tertiary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_6_UL_HL", + "Tertiary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_7_DL_HL", + "Tertiary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_7_UL_HL", + "Tertiary TDM7 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_0_DL_HL", + "Quaternary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_0_UL_HL", + "Quaternary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_1_DL_HL", + "Quaternary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_1_UL_HL", + "Quaternary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_2_DL_HL", + "Quaternary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_2_UL_HL", + "Quaternary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_3_DL_HL", + "Quaternary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_3_UL_HL", + "Quaternary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_4_DL_HL", + "Quaternary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_4_UL_HL", + "Quaternary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_5_DL_HL", + "Quaternary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_5_UL_HL", + "Quaternary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_6_DL_HL", + "Quaternary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_6_UL_HL", + "Quaternary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_7_DL_HL", + "Quaternary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_7_UL_HL", + "Quaternary TDM7 Hostless Capture", + 0, 0, 0, 0), + + /* LSM */ + SND_SOC_DAPM_AIF_OUT("LSM1_UL_HL", "Listen 1 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM2_UL_HL", "Listen 2 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM3_UL_HL", "Listen 3 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM4_UL_HL", "Listen 4 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM5_UL_HL", "Listen 5 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM6_UL_HL", "Listen 6 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM7_UL_HL", "Listen 7 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM8_UL_HL", "Listen 8 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QCHAT_DL", "QCHAT Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QCHAT_UL", "QCHAT Capture", 0, 0, 0, 0), + /* Backend AIF */ + /* Stream name equals to backend dai link stream name */ + SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_I2S_RX", "Secondary I2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SPDIF_RX", "SPDIF Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_RX", "Slimbus2 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_RX", "Slimbus5 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT", "Display Port Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX", "Quaternary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX", "Tertiary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX", "Secondary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_SD1", + "Secondary MI2S Playback SD1", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_MI2S_RX", "Primary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT0_MI2S_RX", "INT0 MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT4_MI2S_RX", "INT4 MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_MI2S_RX", "Quinary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MI2S_TX", "MI2S Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX", "Quaternary MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_MI2S_TX", "Primary MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX", "Tertiary MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT2_MI2S_TX", "INT2 MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT3_MI2S_TX", "INT3 MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX", "Secondary MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_2_TX", "Slimbus2 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_MI2S_TX", "Quinary MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SENARY_MI2S_TX", "Senary MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT_BT_SCO_TX", "Internal BT-SCO Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT_BT_A2DP_RX", "Internal BT-A2DP Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT_FM_RX", "Internal FM Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT_FM_TX", "Internal FM Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PCM_RX", "AFE Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PCM_TX", "AFE Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_0", "Primary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_0", "Primary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_1", "Primary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_1", "Primary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_2", "Primary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_2", "Primary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_3", "Primary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_3", "Primary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_4", "Primary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_4", "Primary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_5", "Primary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_5", "Primary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_6", "Primary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_6", "Primary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_7", "Primary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_7", "Primary TDM7 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_0", "Secondary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_0", "Secondary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_1", "Secondary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_1", "Secondary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_2", "Secondary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_2", "Secondary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_3", "Secondary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_3", "Secondary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_4", "Secondary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_4", "Secondary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_5", "Secondary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_5", "Secondary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_6", "Secondary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_6", "Secondary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_7", "Secondary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_7", "Secondary TDM7 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_0", "Tertiary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_0", "Tertiary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_1", "Tertiary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_1", "Tertiary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_2", "Tertiary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_2", "Tertiary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_3", "Tertiary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_3", "Tertiary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_4", "Tertiary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_4", "Tertiary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_5", "Tertiary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_5", "Tertiary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_6", "Tertiary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_6", "Tertiary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_7", "Tertiary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_7", "Tertiary TDM7 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_0", "Quaternary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_0", "Quaternary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_1", "Quaternary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_1", "Quaternary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_2", "Quaternary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_2", "Quaternary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_3", "Quaternary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_3", "Quaternary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_4", "Quaternary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_4", "Quaternary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_5", "Quaternary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_5", "Quaternary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_6", "Quaternary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_6", "Quaternary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_7", "Quaternary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_7", "Quaternary TDM7 Capture", + 0, 0, 0, 0), + /* incall */ + SND_SOC_DAPM_AIF_OUT("VOICE_PLAYBACK_TX", "Voice Farend Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICE2_PLAYBACK_TX", "Voice2 Farend Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_4_RX", "Slimbus4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INCALL_RECORD_TX", "Voice Uplink Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INCALL_RECORD_RX", "Voice Downlink Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_4_TX", "Slimbus4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SENARY_TX", "Senary_mi2s Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT5_MI2S_TX", "INT5 MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_5_TX", "Slimbus5 Capture", 0, 0, 0, 0), + + SND_SOC_DAPM_AIF_OUT("AUX_PCM_RX", "AUX PCM Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("AUX_PCM_TX", "AUX PCM Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_AUX_PCM_RX", "Sec AUX PCM Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_AUX_PCM_TX", "Sec AUX PCM Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_AUX_PCM_RX", "Tert AUX PCM Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_AUX_PCM_TX", "Tert AUX PCM Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_AUX_PCM_RX", "Quat AUX PCM Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_AUX_PCM_TX", "Quat AUX PCM Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOICE_STUB_DL", "VOICE_STUB Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICE_STUB_UL", "VOICE_STUB Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOICE2_STUB_DL", "VOICE2_STUB Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICE2_STUB_UL", "VOICE2_STUB Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOLTE_STUB_DL", "VOLTE_STUB Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOLTE_STUB_UL", "VOLTE_STUB Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("STUB_RX", "Stub Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("STUB_TX", "Stub Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_RX", "Slimbus1 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_1_TX", "Slimbus1 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("STUB_1_TX", "Stub1 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_3_RX", "Slimbus3 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_3_TX", "Slimbus3 Capture", 0, 0, 0, 0), + /* In- call recording */ + SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_RX", "Slimbus6 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_6_TX", "Slimbus6 Capture", 0, 0, 0, 0), + + SND_SOC_DAPM_AIF_OUT("SLIMBUS_7_RX", "Slimbus7 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_7_TX", "Slimbus7 Capture", 0, 0, 0, 0), + + SND_SOC_DAPM_AIF_OUT("SLIMBUS_8_RX", "Slimbus8 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_8_TX", "Slimbus8 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("USB_AUDIO_RX", "USB Audio Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("USB_AUDIO_TX", "USB Audio Capture", 0, 0, 0, 0), + + /* Switch Definitions */ + SND_SOC_DAPM_SWITCH("SLIMBUS_DL_HL", SND_SOC_NOPM, 0, 0, + &slim_fm_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SLIMBUS1_DL_HL", SND_SOC_NOPM, 0, 0, + &slim1_fm_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SLIMBUS3_DL_HL", SND_SOC_NOPM, 0, 0, + &slim3_fm_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SLIMBUS4_DL_HL", SND_SOC_NOPM, 0, 0, + &slim4_fm_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SLIMBUS6_DL_HL", SND_SOC_NOPM, 0, 0, + &slim6_fm_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("PCM_RX_DL_HL", SND_SOC_NOPM, 0, 0, + &pcm_rx_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("INT0_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, + &int0_mi2s_rx_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("INT4_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, + &int4_mi2s_rx_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("PRI_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, + &pri_mi2s_rx_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SEC_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, + &sec_mi2s_rx_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("TERT_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, + &tert_mi2s_rx_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("QUAT_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, + &quat_mi2s_rx_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("HFP_PRI_AUX_UL_HL", SND_SOC_NOPM, 0, 0, + &hfp_pri_aux_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("HFP_AUX_UL_HL", SND_SOC_NOPM, 0, 0, + &hfp_aux_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("HFP_INT_UL_HL", SND_SOC_NOPM, 0, 0, + &hfp_int_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("HFP_SLIM7_UL_HL", SND_SOC_NOPM, 0, 0, + &hfp_slim7_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("USB_DL_HL", SND_SOC_NOPM, 0, 0, + &usb_switch_mixer_controls), + + /* Mixer definitions */ + SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_i2s_rx_mixer_controls, ARRAY_SIZE(sec_i2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_2_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_2_rx_mixer_controls, ARRAY_SIZE(slimbus_2_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_5_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_5_rx_mixer_controls, ARRAY_SIZE(slimbus_5_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_7_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_7_rx_mixer_controls, ARRAY_SIZE(slimbus_7_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0, + hdmi_mixer_controls, ARRAY_SIZE(hdmi_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT Mixer", SND_SOC_NOPM, 0, 0, + display_port_mixer_controls, ARRAY_SIZE(display_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SPDIF_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + spdif_rx_mixer_controls, ARRAY_SIZE(spdif_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + mi2s_rx_mixer_controls, ARRAY_SIZE(mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + quaternary_mi2s_rx_mixer_controls, + ARRAY_SIZE(quaternary_mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + tertiary_mi2s_rx_mixer_controls, + ARRAY_SIZE(tertiary_mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + secondary_mi2s_rx_mixer_controls, + ARRAY_SIZE(secondary_mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_MI2S_RX_SD1 Audio Mixer", SND_SOC_NOPM, 0, 0, + secondary_mi2s_rx2_mixer_controls, + ARRAY_SIZE(secondary_mi2s_rx2_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + primary_mi2s_rx_mixer_controls, + ARRAY_SIZE(primary_mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("INT0_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + int0_mi2s_rx_mixer_controls, + ARRAY_SIZE(int0_mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("INT4_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + int4_mi2s_rx_mixer_controls, + ARRAY_SIZE(int4_mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + quinary_mi2s_rx_mixer_controls, + ARRAY_SIZE(quinary_mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_0_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_1_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_2_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_3_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_tx_0_mixer_controls, + ARRAY_SIZE(pri_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_0_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_1_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_2_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_3_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_tx_0_mixer_controls, + ARRAY_SIZE(sec_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_0_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_tx_0_mixer_controls, + ARRAY_SIZE(tert_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_1_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_2_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_3_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_4_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_4_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_0_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_tx_0_mixer_controls, + ARRAY_SIZE(quat_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_1_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_2_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_3_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0, + mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0, + mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia3 Mixer", SND_SOC_NOPM, 0, 0, + mmul3_mixer_controls, ARRAY_SIZE(mmul3_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia4 Mixer", SND_SOC_NOPM, 0, 0, + mmul4_mixer_controls, ARRAY_SIZE(mmul4_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia5 Mixer", SND_SOC_NOPM, 0, 0, + mmul5_mixer_controls, ARRAY_SIZE(mmul5_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia6 Mixer", SND_SOC_NOPM, 0, 0, + mmul6_mixer_controls, ARRAY_SIZE(mmul6_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia8 Mixer", SND_SOC_NOPM, 0, 0, + mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia9 Mixer", SND_SOC_NOPM, 0, 0, + mmul9_mixer_controls, ARRAY_SIZE(mmul9_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia17 Mixer", SND_SOC_NOPM, 0, 0, + mmul17_mixer_controls, ARRAY_SIZE(mmul17_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia18 Mixer", SND_SOC_NOPM, 0, 0, + mmul18_mixer_controls, ARRAY_SIZE(mmul18_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia19 Mixer", SND_SOC_NOPM, 0, 0, + mmul19_mixer_controls, ARRAY_SIZE(mmul19_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia20 Mixer", SND_SOC_NOPM, 0, 0, + mmul20_mixer_controls, ARRAY_SIZE(mmul20_mixer_controls)), + SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_auxpcm_rx_mixer_controls, ARRAY_SIZE(sec_auxpcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_auxpcm_rx_mixer_controls, + ARRAY_SIZE(tert_auxpcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_auxpcm_rx_mixer_controls, + ARRAY_SIZE(quat_auxpcm_rx_mixer_controls)), + /* incall */ + SND_SOC_DAPM_MIXER("Incall_Music Audio Mixer", SND_SOC_NOPM, 0, 0, + incall_music_delivery_mixer_controls, + ARRAY_SIZE(incall_music_delivery_mixer_controls)), + SND_SOC_DAPM_MIXER("Incall_Music_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + incall_music2_delivery_mixer_controls, + ARRAY_SIZE(incall_music2_delivery_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_4_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_4_rx_mixer_controls, + ARRAY_SIZE(slimbus_4_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_6_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_6_rx_mixer_controls, + ARRAY_SIZE(slimbus_6_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("USB_AUDIO_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + usb_audio_rx_mixer_controls, + ARRAY_SIZE(usb_audio_rx_mixer_controls)), + /* Voice Mixer */ + SND_SOC_DAPM_MIXER("PRI_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, pri_rx_voice_mixer_controls, + ARRAY_SIZE(pri_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + sec_i2s_rx_voice_mixer_controls, + ARRAY_SIZE(sec_i2s_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_MI2S_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + sec_mi2s_rx_voice_mixer_controls, + ARRAY_SIZE(sec_mi2s_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIM_0_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + slimbus_rx_voice_mixer_controls, + ARRAY_SIZE(slimbus_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + bt_sco_rx_voice_mixer_controls, + ARRAY_SIZE(bt_sco_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("AFE_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + afe_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(afe_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(aux_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + sec_aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(sec_aux_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + tert_aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(tert_aux_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + quat_aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(quat_aux_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("HDMI_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + hdmi_rx_voice_mixer_controls, + ARRAY_SIZE(hdmi_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("MI2S_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + mi2s_rx_voice_mixer_controls, + ARRAY_SIZE(mi2s_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_MI2S_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + pri_mi2s_rx_voice_mixer_controls, + ARRAY_SIZE(pri_mi2s_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("INT0_MI2S_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + int0_mi2s_rx_voice_mixer_controls, + ARRAY_SIZE(int0_mi2s_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("INT4_MI2S_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + int4_mi2s_rx_voice_mixer_controls, + ARRAY_SIZE(int4_mi2s_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_MI2S_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + tert_mi2s_rx_voice_mixer_controls, + ARRAY_SIZE(tert_mi2s_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_MI2S_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + quat_mi2s_rx_voice_mixer_controls, + ARRAY_SIZE(quat_mi2s_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_MI2S_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + quin_mi2s_rx_voice_mixer_controls, + ARRAY_SIZE(quin_mi2s_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_2_Voice Mixer", + SND_SOC_NOPM, 0, 0, + quat_tdm_rx_2_voice_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_2_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("Voice_Tx Mixer", + SND_SOC_NOPM, 0, 0, tx_voice_mixer_controls, + ARRAY_SIZE(tx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("Voice2_Tx Mixer", + SND_SOC_NOPM, 0, 0, tx_voice2_mixer_controls, + ARRAY_SIZE(tx_voice2_mixer_controls)), + SND_SOC_DAPM_MIXER("Voip_Tx Mixer", + SND_SOC_NOPM, 0, 0, tx_voip_mixer_controls, + ARRAY_SIZE(tx_voip_mixer_controls)), + SND_SOC_DAPM_MIXER("VoLTE_Tx Mixer", + SND_SOC_NOPM, 0, 0, tx_volte_mixer_controls, + ARRAY_SIZE(tx_volte_mixer_controls)), + SND_SOC_DAPM_MIXER("VoWLAN_Tx Mixer", + SND_SOC_NOPM, 0, 0, tx_vowlan_mixer_controls, + ARRAY_SIZE(tx_vowlan_mixer_controls)), + SND_SOC_DAPM_MIXER("VoiceMMode1_Tx Mixer", + SND_SOC_NOPM, 0, 0, tx_voicemmode1_mixer_controls, + ARRAY_SIZE(tx_voicemmode1_mixer_controls)), + SND_SOC_DAPM_MIXER("VoiceMMode2_Tx Mixer", + SND_SOC_NOPM, 0, 0, tx_voicemmode2_mixer_controls, + ARRAY_SIZE(tx_voicemmode2_mixer_controls)), + SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + int_bt_sco_rx_mixer_controls, ARRAY_SIZE(int_bt_sco_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("INTERNAL_A2DP_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + int_bt_a2dp_rx_mixer_controls, + ARRAY_SIZE(int_bt_a2dp_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("INTERNAL_FM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + int_fm_rx_mixer_controls, ARRAY_SIZE(int_fm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("AFE_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + afe_pcm_rx_mixer_controls, ARRAY_SIZE(afe_pcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("Voice Stub Tx Mixer", SND_SOC_NOPM, 0, 0, + tx_voice_stub_mixer_controls, ARRAY_SIZE(tx_voice_stub_mixer_controls)), + SND_SOC_DAPM_MIXER("Voice2 Stub Tx Mixer", SND_SOC_NOPM, 0, 0, + tx_voice2_stub_mixer_controls, + ARRAY_SIZE(tx_voice2_stub_mixer_controls)), + SND_SOC_DAPM_MIXER("VoLTE Stub Tx Mixer", SND_SOC_NOPM, 0, 0, + tx_volte_stub_mixer_controls, ARRAY_SIZE(tx_volte_stub_mixer_controls)), + SND_SOC_DAPM_MIXER("STUB_RX Mixer", SND_SOC_NOPM, 0, 0, + stub_rx_mixer_controls, ARRAY_SIZE(stub_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Mixer", SND_SOC_NOPM, 0, 0, + slimbus_1_rx_mixer_controls, ARRAY_SIZE(slimbus_1_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_3_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, + slimbus_3_rx_mixer_controls, ARRAY_SIZE(slimbus_3_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIM_6_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + slimbus_6_rx_voice_mixer_controls, + ARRAY_SIZE(slimbus_6_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIM_7_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, + slimbus_7_rx_voice_mixer_controls, + ARRAY_SIZE(slimbus_7_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIM_8_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, + slimbus_8_rx_voice_mixer_controls, + ARRAY_SIZE(slimbus_8_rx_voice_mixer_controls)), + /* port mixer */ + SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Port Mixer", + SND_SOC_NOPM, 0, 0, sbus_0_rx_port_mixer_controls, + ARRAY_SIZE(sbus_0_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("AUX_PCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, aux_pcm_rx_port_mixer_controls, + ARRAY_SIZE(aux_pcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_AUXPCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, sec_auxpcm_rx_port_mixer_controls, + ARRAY_SIZE(sec_auxpcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_AUXPCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, tert_auxpcm_rx_port_mixer_controls, + ARRAY_SIZE(tert_auxpcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_AUXPCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, quat_auxpcm_rx_port_mixer_controls, + ARRAY_SIZE(quat_auxpcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Port Mixer", SND_SOC_NOPM, 0, 0, + sbus_1_rx_port_mixer_controls, + ARRAY_SIZE(sbus_1_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Port Mixer", SND_SOC_NOPM, 0, 0, + bt_sco_rx_port_mixer_controls, + ARRAY_SIZE(bt_sco_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("AFE_PCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, afe_pcm_rx_port_mixer_controls, + ARRAY_SIZE(afe_pcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("HDMI_RX Port Mixer", + SND_SOC_NOPM, 0, 0, hdmi_rx_port_mixer_controls, + ARRAY_SIZE(hdmi_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX Port Mixer", + SND_SOC_NOPM, 0, 0, display_port_rx_port_mixer_controls, + ARRAY_SIZE(display_port_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_I2S_RX Port Mixer", + SND_SOC_NOPM, 0, 0, sec_i2s_rx_port_mixer_controls, + ARRAY_SIZE(sec_i2s_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_3_RX Port Mixer", + SND_SOC_NOPM, 0, 0, sbus_3_rx_port_mixer_controls, + ARRAY_SIZE(sbus_3_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_6_RX Port Mixer", + SND_SOC_NOPM, 0, 0, sbus_6_rx_port_mixer_controls, + ARRAY_SIZE(sbus_6_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, + mi2s_rx_port_mixer_controls, ARRAY_SIZE(mi2s_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, + primary_mi2s_rx_port_mixer_controls, + ARRAY_SIZE(primary_mi2s_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, + sec_mi2s_rx_port_mixer_controls, + ARRAY_SIZE(sec_mi2s_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, + tert_mi2s_rx_port_mixer_controls, + ARRAY_SIZE(tert_mi2s_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, + quat_mi2s_rx_port_mixer_controls, + ARRAY_SIZE(quat_mi2s_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_0_port_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_0_port_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_1 Port Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_1_port_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_1_port_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_2 Port Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_2_port_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_2_port_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_3_port_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_3_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_0_port_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_0_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_1 Port Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_1_port_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_1_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_2 Port Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_2_port_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_2_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_3_port_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_3_port_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_0_port_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_0_port_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_1 Port Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_1_port_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_1_port_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_2 Port Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_2_port_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_2_port_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_3_port_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_3_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_0_port_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_0_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_1 Port Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_1_port_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_1_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_2 Port Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_2_port_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_2_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_3_port_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_3_port_mixer_controls)), + SND_SOC_DAPM_MIXER("INT0_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, + int0_mi2s_rx_port_mixer_controls, + ARRAY_SIZE(int0_mi2s_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("INT4_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, + int4_mi2s_rx_port_mixer_controls, + ARRAY_SIZE(int4_mi2s_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QCHAT_Tx Mixer", + SND_SOC_NOPM, 0, 0, tx_qchat_mixer_controls, + ARRAY_SIZE(tx_qchat_mixer_controls)), + SND_SOC_DAPM_MIXER("USB_AUDIO_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, usb_audio_rx_voice_mixer_controls, + ARRAY_SIZE(usb_audio_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("USB_AUDIO_RX Port Mixer", + SND_SOC_NOPM, 0, 0, usb_rx_port_mixer_controls, + ARRAY_SIZE(usb_rx_port_mixer_controls)), + /* lsm mixer definitions */ + SND_SOC_DAPM_MIXER("LSM1 Mixer", SND_SOC_NOPM, 0, 0, + lsm1_mixer_controls, ARRAY_SIZE(lsm1_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM2 Mixer", SND_SOC_NOPM, 0, 0, + lsm2_mixer_controls, ARRAY_SIZE(lsm2_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM3 Mixer", SND_SOC_NOPM, 0, 0, + lsm3_mixer_controls, ARRAY_SIZE(lsm3_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM4 Mixer", SND_SOC_NOPM, 0, 0, + lsm4_mixer_controls, ARRAY_SIZE(lsm4_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM5 Mixer", SND_SOC_NOPM, 0, 0, + lsm5_mixer_controls, ARRAY_SIZE(lsm5_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM6 Mixer", SND_SOC_NOPM, 0, 0, + lsm6_mixer_controls, ARRAY_SIZE(lsm6_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM7 Mixer", SND_SOC_NOPM, 0, 0, + lsm7_mixer_controls, ARRAY_SIZE(lsm7_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM8 Mixer", SND_SOC_NOPM, 0, 0, + lsm8_mixer_controls, ARRAY_SIZE(lsm8_mixer_controls)), + /* Virtual Pins to force backends ON atm */ + SND_SOC_DAPM_OUTPUT("BE_OUT"), + SND_SOC_DAPM_INPUT("BE_IN"), + + SND_SOC_DAPM_MUX("SLIM0_RX_VI_FB_LCH_MUX", SND_SOC_NOPM, 0, 0, + &slim0_rx_vi_fb_lch_mux), + SND_SOC_DAPM_MUX("SLIM0_RX_VI_FB_RCH_MUX", SND_SOC_NOPM, 0, 0, + &slim0_rx_vi_fb_rch_mux), + SND_SOC_DAPM_MUX("PRI_MI2S_RX_VI_FB_MUX", SND_SOC_NOPM, 0, 0, + &mi2s_rx_vi_fb_mux), + SND_SOC_DAPM_MUX("INT4_MI2S_RX_VI_FB_MONO_CH_MUX", SND_SOC_NOPM, 0, 0, + &int4_mi2s_rx_vi_fb_mono_ch_mux), + SND_SOC_DAPM_MUX("INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", SND_SOC_NOPM, 0, 0, + &int4_mi2s_rx_vi_fb_stereo_ch_mux), + + SND_SOC_DAPM_MUX("VOC_EXT_EC MUX", SND_SOC_NOPM, 0, 0, + &voc_ext_ec_mux), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL1 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul1), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL2 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul2), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL3 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul3), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL4 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul4), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL5 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul5), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL6 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul6), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL8 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul8), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL9 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul9), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL17 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul17), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL18 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul18), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL19 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul19), +}; + +static const struct snd_soc_dapm_route intercon[] = { + {"PRI_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"}, + + {"SEC_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_I2S_RX", NULL, "SEC_RX Audio Mixer"}, + + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"}, + + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_2_RX", NULL, "SLIMBUS_2_RX Audio Mixer"}, + + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_5_RX", NULL, "SLIMBUS_5_RX Audio Mixer"}, + + {"HDMI Mixer", "MultiMedia1", "MM_DL1"}, + {"HDMI Mixer", "MultiMedia2", "MM_DL2"}, + {"HDMI Mixer", "MultiMedia3", "MM_DL3"}, + {"HDMI Mixer", "MultiMedia4", "MM_DL4"}, + {"HDMI Mixer", "MultiMedia5", "MM_DL5"}, + {"HDMI Mixer", "MultiMedia6", "MM_DL6"}, + {"HDMI Mixer", "MultiMedia7", "MM_DL7"}, + {"HDMI Mixer", "MultiMedia8", "MM_DL8"}, + {"HDMI Mixer", "MultiMedia9", "MM_DL9"}, + {"HDMI Mixer", "MultiMedia10", "MM_DL10"}, + {"HDMI Mixer", "MultiMedia11", "MM_DL11"}, + {"HDMI Mixer", "MultiMedia12", "MM_DL12"}, + {"HDMI Mixer", "MultiMedia13", "MM_DL13"}, + {"HDMI Mixer", "MultiMedia14", "MM_DL14"}, + {"HDMI Mixer", "MultiMedia15", "MM_DL15"}, + {"HDMI Mixer", "MultiMedia16", "MM_DL16"}, + {"HDMI", NULL, "HDMI Mixer"}, + + {"DISPLAY_PORT Mixer", "MultiMedia1", "MM_DL1"}, + {"DISPLAY_PORT Mixer", "MultiMedia2", "MM_DL2"}, + {"DISPLAY_PORT Mixer", "MultiMedia3", "MM_DL3"}, + {"DISPLAY_PORT Mixer", "MultiMedia4", "MM_DL4"}, + {"DISPLAY_PORT Mixer", "MultiMedia5", "MM_DL5"}, + {"DISPLAY_PORT Mixer", "MultiMedia6", "MM_DL6"}, + {"DISPLAY_PORT Mixer", "MultiMedia7", "MM_DL7"}, + {"DISPLAY_PORT Mixer", "MultiMedia8", "MM_DL8"}, + {"DISPLAY_PORT Mixer", "MultiMedia9", "MM_DL9"}, + {"DISPLAY_PORT Mixer", "MultiMedia10", "MM_DL10"}, + {"DISPLAY_PORT Mixer", "MultiMedia11", "MM_DL11"}, + {"DISPLAY_PORT Mixer", "MultiMedia12", "MM_DL12"}, + {"DISPLAY_PORT Mixer", "MultiMedia13", "MM_DL13"}, + {"DISPLAY_PORT Mixer", "MultiMedia14", "MM_DL14"}, + {"DISPLAY_PORT Mixer", "MultiMedia15", "MM_DL15"}, + {"DISPLAY_PORT Mixer", "MultiMedia16", "MM_DL16"}, + {"DISPLAY_PORT", NULL, "DISPLAY_PORT Mixer"}, + + {"SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SPDIF_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SPDIF_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SPDIF_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SPDIF_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SPDIF_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SPDIF_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SPDIF_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SPDIF_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SPDIF_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SPDIF_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SPDIF_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SPDIF_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SPDIF_RX", NULL, "SPDIF_RX Audio Mixer"}, + + /* incall */ + {"Incall_Music Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"Incall_Music Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"Incall_Music Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"Incall_Music Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"VOICE_PLAYBACK_TX", NULL, "Incall_Music Audio Mixer"}, + {"Incall_Music_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"Incall_Music_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"Incall_Music_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"Incall_Music_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"VOICE2_PLAYBACK_TX", NULL, "Incall_Music_2 Audio Mixer"}, + {"SLIMBUS_4_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_4_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_4_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_4_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_4_RX", NULL, "SLIMBUS_4_RX Audio Mixer"}, + + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_6_RX", NULL, "SLIMBUS_6_RX Audio Mixer"}, + + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_7_RX", NULL, "SLIMBUS_7_RX Audio Mixer"}, + + {"USB_AUDIO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX Audio Mixer"}, + + {"MultiMedia1 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, + {"MultiMedia4 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, + {"MultiMedia8 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, + {"MultiMedia1 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, + {"MultiMedia4 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, + {"MultiMedia8 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, + {"MultiMedia1 Mixer", "SLIM_4_TX", "SLIMBUS_4_TX"}, + {"MultiMedia1 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, + {"MultiMedia1 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia1 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"MultiMedia8 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, + {"MultiMedia8 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia4 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia17 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia18 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia19 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia8 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia2 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia4 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia17 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia18 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia19 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia8 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia18 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia8 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia5 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia5 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"MI2S_RX", NULL, "MI2S_RX Audio Mixer"}, + + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX Audio Mixer"}, + + {"TERT_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX Audio Mixer"}, + + {"SEC_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Audio Mixer"}, + + {"SEC_MI2S_RX_SD1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_MI2S_RX_SD1", NULL, "SEC_MI2S_RX_SD1 Audio Mixer"}, + + {"SEC_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + + {"PRI_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Audio Mixer"}, + + {"INT0_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX Audio Mixer"}, + + {"INT4_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX Audio Mixer"}, + + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX Audio Mixer"}, + + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Audio Mixer"}, + + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Audio Mixer"}, + + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Audio Mixer"}, + + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Audio Mixer"}, + + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_TX_0", NULL, "PRI_TDM_TX_0 Audio Mixer"}, + + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Audio Mixer"}, + + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Audio Mixer"}, + + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Audio Mixer"}, + + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Audio Mixer"}, + + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_TX_0", NULL, "SEC_TDM_TX_0 Audio Mixer"}, + + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Audio Mixer"}, + + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_TX_0", NULL, "TERT_TDM_TX_0 Audio Mixer"}, + + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Audio Mixer"}, + + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Audio Mixer"}, + + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Audio Mixer"}, + + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_4", NULL, "TERT_TDM_RX_4 Audio Mixer"}, + + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Audio Mixer"}, + + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Audio Mixer"}, + + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Audio Mixer"}, + + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_TDM_TX_0", NULL, "QUAT_TDM_TX_0 Audio Mixer"}, + + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Audio Mixer"}, + + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Audio Mixer"}, + + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Audio Mixer"}, + + {"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"}, + {"MultiMedia1 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia3 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia5 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia1 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia2 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia1 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia2 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia1 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia2 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia2 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia2 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, + {"MultiMedia2 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia2 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"MultiMedia1 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia1 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia2 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia6 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia6 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia6 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia3 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia5 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia6 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia6 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"MultiMedia6 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia6 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + + {"MultiMedia1 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia1 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia1 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia1 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia1 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia1 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia1 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia1 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia1 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia1 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia1 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia1 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia1 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia1 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia1 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia1 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + + {"MultiMedia2 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia2 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia2 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia2 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia2 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia2 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia2 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia2 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia2 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia2 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia2 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia2 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia2 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia2 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia2 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia2 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + + {"MultiMedia3 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia3 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia3 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia3 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia3 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia3 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia3 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia3 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia3 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia3 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia3 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia3 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia3 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia3 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia3 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia3 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + + {"MultiMedia4 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia4 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia4 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia4 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia4 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia4 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia4 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia4 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia4 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia4 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia4 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia4 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia4 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia4 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia4 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia4 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + + {"MultiMedia5 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia5 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia5 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia5 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia5 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia5 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia5 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia5 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia5 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia5 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia5 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia5 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia5 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia5 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia5 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia5 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + + {"MultiMedia6 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia6 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia6 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia6 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia6 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia6 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia6 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia6 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia6 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia6 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia6 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia6 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia6 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia6 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia6 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia6 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + + {"MultiMedia8 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia8 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia8 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia8 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia8 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia8 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia8 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia8 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia8 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia8 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia8 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia8 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia8 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia8 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia8 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia8 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + + {"MultiMedia9 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia9 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia9 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia9 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia9 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia9 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia9 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia9 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + + {"MultiMedia20 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia20 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia20 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia20 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia20 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia20 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia20 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia20 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia20 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia20 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia20 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia20 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia20 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia20 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia20 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia20 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia20 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia20 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia20 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia20 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + + {"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia4 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia5 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia6 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia8 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia6", "MM_UL6"}, + {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"}, + + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia6", "MM_UL6"}, + {"INT_BT_A2DP_RX", NULL, "INTERNAL_A2DP_RX Audio Mixer"}, + + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"}, + + {"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"}, + + {"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia3 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia4 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia17 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia18 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia19 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia5 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia8 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia4 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia17 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia18 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia19 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia5 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia6 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia8 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + + {"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia3 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia4 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia17 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia18 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia19 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia5 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia8 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MM_UL1", NULL, "MultiMedia1 Mixer"}, + {"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MM_UL2", NULL, "MultiMedia2 Mixer"}, + {"MM_UL3", NULL, "MultiMedia3 Mixer"}, + {"MM_UL4", NULL, "MultiMedia4 Mixer"}, + {"MM_UL5", NULL, "MultiMedia5 Mixer"}, + {"MM_UL6", NULL, "MultiMedia6 Mixer"}, + {"MM_UL8", NULL, "MultiMedia8 Mixer"}, + {"MM_UL9", NULL, "MultiMedia9 Mixer"}, + {"MM_UL17", NULL, "MultiMedia17 Mixer"}, + {"MM_UL18", NULL, "MultiMedia18 Mixer"}, + {"MM_UL19", NULL, "MultiMedia19 Mixer"}, + {"MM_UL20", NULL, "MultiMedia20 Mixer"}, + + {"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"}, + + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX Audio Mixer"}, + + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_AUX_PCM_RX", NULL, "TERT_AUX_PCM_RX Audio Mixer"}, + + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUX_PCM_RX Audio Mixer"}, + + {"MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"MI2S_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"}, + + {"PRI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"PRI_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"PRI_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"PRI_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"}, + + {"SEC_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"SEC_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"SEC_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"SEC_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SEC_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SEC_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"}, + + {"SEC_MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"SEC_MI2S_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SEC_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX_Voice Mixer"}, + + {"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"SLIM_0_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"SLIM_0_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"SLIM_0_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SLIM_0_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SLIM_0_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"SLIM_0_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"SLIM_0_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"SLIM_0_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SLIM_0_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIM_0_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"}, + + {"SLIM_6_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"SLIM_6_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"SLIM_6_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"SLIM_6_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"SLIM_6_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SLIM_6_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SLIM_6_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"SLIM_6_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"SLIM_6_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"SLIM_6_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SLIM_6_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIM_6_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SLIMBUS_6_RX", NULL, "SLIM_6_RX_Voice Mixer"}, + + {"USB_AUDIO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"USB_AUDIO_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"USB_AUDIO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX_Voice Mixer"}, + + {"INTERNAL_BT_SCO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"}, + + {"AFE_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"AFE_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"AFE_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"AFE_PCM_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"AFE_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"AFE_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"AFE_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"AFE_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"}, + + {"AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"AUX_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"AUX_PCM_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"AUX_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"AUX_PCM_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"AUX_PCM_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"}, + + {"SEC_AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX_Voice Mixer"}, + + {"TERT_AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"TERT_AUX_PCM_RX", NULL, "TERT_AUX_PCM_RX_Voice Mixer"}, + + {"QUAT_AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUX_PCM_RX_Voice Mixer"}, + + {"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"HDMI_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"HDMI_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"HDMI_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"HDMI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"HDMI_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"HDMI_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"HDMI_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"HDMI", NULL, "HDMI_RX_Voice Mixer"}, + {"HDMI", NULL, "HDMI_DL_HL"}, + + {"MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"MI2S_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"MI2S_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"MI2S_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"}, + + {"PRI_MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"PRI_MI2S_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_Voice Mixer"}, + + {"INT0_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"INT0_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"INT0_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"INT0_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"INT0_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX_Voice Mixer"}, + + {"INT4_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"INT4_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"INT4_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"INT4_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"INT4_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_Voice Mixer"}, + + {"TERT_MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"TERT_MI2S_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"TERT_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX_Voice Mixer"}, + + {"QUAT_MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"QUAT_MI2S_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_Voice Mixer"}, + + {"QUIN_MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"QUIN_MI2S_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_Voice Mixer"}, + + {"QUAT_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_Voice Mixer"}, + + {"VOC_EXT_EC MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"VOC_EXT_EC MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"VOC_EXT_EC MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"VOC_EXT_EC MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"VOC_EXT_EC MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"CS-VOICE_UL1", NULL, "VOC_EXT_EC MUX"}, + {"VOIP_UL", NULL, "VOC_EXT_EC MUX"}, + {"VoLTE_UL", NULL, "VOC_EXT_EC MUX"}, + {"VOICE2_UL", NULL, "VOC_EXT_EC MUX"}, + {"VoWLAN_UL", NULL, "VOC_EXT_EC MUX"}, + {"VOICEMMODE1_UL", NULL, "VOC_EXT_EC MUX"}, + {"VOICEMMODE2_UL", NULL, "VOC_EXT_EC MUX"}, + + {"AUDIO_REF_EC_UL1 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL1 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL1 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL1 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"AUDIO_REF_EC_UL1 MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_0", "QUAT_TDM_RX_0"}, + {"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_1", "QUAT_TDM_RX_1"}, + {"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_2", "QUAT_TDM_RX_2"}, + {"AUDIO_REF_EC_UL1 MUX", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + + {"AUDIO_REF_EC_UL2 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL2 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL2 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL2 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"AUDIO_REF_EC_UL3 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL3 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL3 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL3 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"AUDIO_REF_EC_UL4 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL4 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL4 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL4 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"AUDIO_REF_EC_UL5 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL5 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL5 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL5 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"AUDIO_REF_EC_UL6 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL6 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL6 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL6 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"AUDIO_REF_EC_UL8 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL8 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL8 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL8 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"AUDIO_REF_EC_UL9 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL9 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL9 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL9 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"AUDIO_REF_EC_UL17 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL17 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL17 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL17 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"AUDIO_REF_EC_UL18 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL18 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL18 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL18 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"AUDIO_REF_EC_UL19 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL19 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL19 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL19 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"MM_UL1", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"MM_UL2", NULL, "AUDIO_REF_EC_UL2 MUX"}, + {"MM_UL3", NULL, "AUDIO_REF_EC_UL3 MUX"}, + {"MM_UL4", NULL, "AUDIO_REF_EC_UL4 MUX"}, + {"MM_UL5", NULL, "AUDIO_REF_EC_UL5 MUX"}, + {"MM_UL6", NULL, "AUDIO_REF_EC_UL6 MUX"}, + {"MM_UL8", NULL, "AUDIO_REF_EC_UL8 MUX"}, + {"MM_UL9", NULL, "AUDIO_REF_EC_UL9 MUX"}, + {"MM_UL17", NULL, "AUDIO_REF_EC_UL17 MUX"}, + {"MM_UL18", NULL, "AUDIO_REF_EC_UL18 MUX"}, + {"MM_UL19", NULL, "AUDIO_REF_EC_UL19 MUX"}, + + {"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"}, + {"Voice_Tx Mixer", "PRI_MI2S_TX_Voice", "PRI_MI2S_TX"}, + {"Voice_Tx Mixer", "MI2S_TX_Voice", "MI2S_TX"}, + {"Voice_Tx Mixer", "TERT_MI2S_TX_Voice", "TERT_MI2S_TX"}, + {"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"}, + {"Voice_Tx Mixer", "SLIM_7_TX_Voice", "SLIMBUS_7_TX"}, + {"Voice_Tx Mixer", "SLIM_8_TX_Voice", "SLIMBUS_8_TX"}, + {"Voice_Tx Mixer", "USB_AUDIO_TX_Voice", "USB_AUDIO_TX"}, + {"Voice_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice", "INT_BT_SCO_TX"}, + {"Voice_Tx Mixer", "AFE_PCM_TX_Voice", "PCM_TX"}, + {"Voice_Tx Mixer", "AUX_PCM_TX_Voice", "AUX_PCM_TX"}, + {"Voice_Tx Mixer", "SEC_AUX_PCM_TX_Voice", "SEC_AUX_PCM_TX"}, + {"Voice_Tx Mixer", "TERT_AUX_PCM_TX_Voice", "TERT_AUX_PCM_TX"}, + {"Voice_Tx Mixer", "QUAT_AUX_PCM_TX_Voice", "QUAT_AUX_PCM_TX"}, + {"Voice_Tx Mixer", "SEC_MI2S_TX_Voice", "SEC_MI2S_TX"}, + {"CS-VOICE_UL1", NULL, "Voice_Tx Mixer"}, + + {"Voice2_Tx Mixer", "PRI_TX_Voice2", "PRI_I2S_TX"}, + {"Voice2_Tx Mixer", "PRI_MI2S_TX_Voice2", "PRI_MI2S_TX"}, + {"Voice2_Tx Mixer", "MI2S_TX_Voice2", "MI2S_TX"}, + {"Voice2_Tx Mixer", "TERT_MI2S_TX_Voice2", "TERT_MI2S_TX"}, + {"Voice2_Tx Mixer", "SLIM_0_TX_Voice2", "SLIMBUS_0_TX"}, + {"Voice2_Tx Mixer", "SLIM_7_TX_Voice2", "SLIMBUS_7_TX"}, + {"Voice2_Tx Mixer", "SLIM_8_TX_Voice2", "SLIMBUS_8_TX"}, + {"Voice2_Tx Mixer", "USB_AUDIO_TX_Voice2", "USB_AUDIO_TX"}, + {"Voice2_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice2", "INT_BT_SCO_TX"}, + {"Voice2_Tx Mixer", "AFE_PCM_TX_Voice2", "PCM_TX"}, + {"Voice2_Tx Mixer", "AUX_PCM_TX_Voice2", "AUX_PCM_TX"}, + {"Voice2_Tx Mixer", "SEC_AUX_PCM_TX_Voice2", "SEC_AUX_PCM_TX"}, + {"Voice2_Tx Mixer", "TERT_AUX_PCM_TX_Voice2", "TERT_AUX_PCM_TX"}, + {"Voice2_Tx Mixer", "QUAT_AUX_PCM_TX_Voice2", "QUAT_AUX_PCM_TX"}, + {"VOICE2_UL", NULL, "Voice2_Tx Mixer"}, + + {"VoLTE_Tx Mixer", "PRI_TX_VoLTE", "PRI_I2S_TX"}, + {"VoLTE_Tx Mixer", "SLIM_0_TX_VoLTE", "SLIMBUS_0_TX"}, + {"VoLTE_Tx Mixer", "SLIM_7_TX_VoLTE", "SLIMBUS_7_TX"}, + {"VoLTE_Tx Mixer", "SLIM_8_TX_VoLTE", "SLIMBUS_8_TX"}, + {"VoLTE_Tx Mixer", "USB_AUDIO_TX_VoLTE", "USB_AUDIO_TX"}, + {"VoLTE_Tx Mixer", "INTERNAL_BT_SCO_TX_VoLTE", "INT_BT_SCO_TX"}, + {"VoLTE_Tx Mixer", "AFE_PCM_TX_VoLTE", "PCM_TX"}, + {"VoLTE_Tx Mixer", "AUX_PCM_TX_VoLTE", "AUX_PCM_TX"}, + {"VoLTE_Tx Mixer", "SEC_AUX_PCM_TX_VoLTE", "SEC_AUX_PCM_TX"}, + {"VoLTE_Tx Mixer", "TERT_AUX_PCM_TX_VoLTE", "TERT_AUX_PCM_TX"}, + {"VoLTE_Tx Mixer", "QUAT_AUX_PCM_TX_VoLTE", "QUAT_AUX_PCM_TX"}, + {"VoLTE_Tx Mixer", "MI2S_TX_VoLTE", "MI2S_TX"}, + {"VoLTE_Tx Mixer", "PRI_MI2S_TX_VoLTE", "PRI_MI2S_TX"}, + {"VoLTE_Tx Mixer", "TERT_MI2S_TX_VoLTE", "TERT_MI2S_TX"}, + {"VoLTE_UL", NULL, "VoLTE_Tx Mixer"}, + + {"VoWLAN_Tx Mixer", "PRI_TX_VoWLAN", "PRI_I2S_TX"}, + {"VoWLAN_Tx Mixer", "SLIM_0_TX_VoWLAN", "SLIMBUS_0_TX"}, + {"VoWLAN_Tx Mixer", "SLIM_7_TX_VoWLAN", "SLIMBUS_7_TX"}, + {"VoWLAN_Tx Mixer", "SLIM_8_TX_VoWLAN", "SLIMBUS_8_TX"}, + {"VoWLAN_Tx Mixer", "USB_AUDIO_TX_VoWLAN", "USB_AUDIO_TX"}, + {"VoWLAN_Tx Mixer", "INTERNAL_BT_SCO_TX_VoWLAN", "INT_BT_SCO_TX"}, + {"VoWLAN_Tx Mixer", "AFE_PCM_TX_VoWLAN", "PCM_TX"}, + {"VoWLAN_Tx Mixer", "AUX_PCM_TX_VoWLAN", "AUX_PCM_TX"}, + {"VoWLAN_Tx Mixer", "SEC_AUX_PCM_TX_VoWLAN", "SEC_AUX_PCM_TX"}, + {"VoWLAN_Tx Mixer", "TERT_AUX_PCM_TX_VoWLAN", "TERT_AUX_PCM_TX"}, + {"VoWLAN_Tx Mixer", "QUAT_AUX_PCM_TX_VoWLAN", "QUAT_AUX_PCM_TX"}, + {"VoWLAN_Tx Mixer", "MI2S_TX_VoWLAN", "MI2S_TX"}, + {"VoWLAN_Tx Mixer", "PRI_MI2S_TX_VoWLAN", "PRI_MI2S_TX"}, + {"VoWLAN_Tx Mixer", "TERT_MI2S_TX_VoWLAN", "TERT_MI2S_TX"}, + {"VoWLAN_UL", NULL, "VoWLAN_Tx Mixer"}, + + {"VoiceMMode1_Tx Mixer", "PRI_TX_MMode1", "PRI_I2S_TX"}, + {"VoiceMMode1_Tx Mixer", "PRI_MI2S_TX_MMode1", "PRI_MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "MI2S_TX_MMode1", "MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "TERT_MI2S_TX_MMode1", "TERT_MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "INT3_MI2S_TX_MMode1", "INT3_MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "SLIM_0_TX_MMode1", "SLIMBUS_0_TX"}, + {"VoiceMMode1_Tx Mixer", "SLIM_7_TX_MMode1", "SLIMBUS_7_TX"}, + {"VoiceMMode1_Tx Mixer", "SLIM_8_TX_MMode1", "SLIMBUS_8_TX"}, + {"VoiceMMode1_Tx Mixer", "USB_AUDIO_TX_MMode1", "USB_AUDIO_TX"}, + {"VoiceMMode1_Tx Mixer", "INT_BT_SCO_TX_MMode1", "INT_BT_SCO_TX"}, + {"VoiceMMode1_Tx Mixer", "AFE_PCM_TX_MMode1", "PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "AUX_PCM_TX_MMode1", "AUX_PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "SEC_AUX_PCM_TX_MMode1", "SEC_AUX_PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "TERT_AUX_PCM_TX_MMode1", "TERT_AUX_PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "QUAT_AUX_PCM_TX_MMode1", "QUAT_AUX_PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "QUAT_TDM_TX_0_MMode1", "QUAT_TDM_TX_0"}, + {"VOICEMMODE1_UL", NULL, "VoiceMMode1_Tx Mixer"}, + + {"VoiceMMode2_Tx Mixer", "PRI_TX_MMode2", "PRI_I2S_TX"}, + {"VoiceMMode2_Tx Mixer", "PRI_MI2S_TX_MMode2", "PRI_MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "MI2S_TX_MMode2", "MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "TERT_MI2S_TX_MMode2", "TERT_MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "INT3_MI2S_TX_MMode2", "INT3_MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "SLIM_0_TX_MMode2", "SLIMBUS_0_TX"}, + {"VoiceMMode2_Tx Mixer", "SLIM_7_TX_MMode2", "SLIMBUS_7_TX"}, + {"VoiceMMode2_Tx Mixer", "SLIM_8_TX_MMode2", "SLIMBUS_8_TX"}, + {"VoiceMMode2_Tx Mixer", "USB_AUDIO_TX_MMode2", "USB_AUDIO_TX"}, + {"VoiceMMode2_Tx Mixer", "INT_BT_SCO_TX_MMode2", "INT_BT_SCO_TX"}, + {"VoiceMMode2_Tx Mixer", "AFE_PCM_TX_MMode2", "PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "AUX_PCM_TX_MMode2", "AUX_PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "SEC_AUX_PCM_TX_MMode2", "SEC_AUX_PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "TERT_AUX_PCM_TX_MMode2", "TERT_AUX_PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "QUAT_AUX_PCM_TX_MMode2", "QUAT_AUX_PCM_TX"}, + {"VOICEMMODE2_UL", NULL, "VoiceMMode2_Tx Mixer"}, + + {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"}, + {"Voip_Tx Mixer", "MI2S_TX_Voip", "MI2S_TX"}, + {"Voip_Tx Mixer", "TERT_MI2S_TX_Voip", "TERT_MI2S_TX"}, + {"Voip_Tx Mixer", "INT3_MI2S_TX_Voip", "INT3_MI2S_TX"}, + {"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"}, + {"Voip_Tx Mixer", "SLIM_7_TX_Voip", "SLIMBUS_7_TX"}, + {"Voip_Tx Mixer", "SLIM_8_TX_Voip", "SLIMBUS_8_TX"}, + {"Voip_Tx Mixer", "USB_AUDIO_TX_Voip", "USB_AUDIO_TX"}, + {"Voip_Tx Mixer", "INTERNAL_BT_SCO_TX_Voip", "INT_BT_SCO_TX"}, + {"Voip_Tx Mixer", "AFE_PCM_TX_Voip", "PCM_TX"}, + {"Voip_Tx Mixer", "AUX_PCM_TX_Voip", "AUX_PCM_TX"}, + {"Voip_Tx Mixer", "SEC_AUX_PCM_TX_Voip", "SEC_AUX_PCM_TX"}, + {"Voip_Tx Mixer", "TERT_AUX_PCM_TX_Voip", "TERT_AUX_PCM_TX"}, + {"Voip_Tx Mixer", "QUAT_AUX_PCM_TX_Voip", "QUAT_AUX_PCM_TX"}, + {"Voip_Tx Mixer", "PRI_MI2S_TX_Voip", "PRI_MI2S_TX"}, + {"VOIP_UL", NULL, "Voip_Tx Mixer"}, + + {"SLIMBUS_DL_HL", "Switch", "SLIM0_DL_HL"}, + {"SLIMBUS_0_RX", NULL, "SLIMBUS_DL_HL"}, + {"SLIMBUS1_DL_HL", "Switch", "SLIM1_DL_HL"}, + {"SLIMBUS_1_RX", NULL, "SLIMBUS1_DL_HL"}, + {"SLIMBUS3_DL_HL", "Switch", "SLIM3_DL_HL"}, + {"SLIMBUS_3_RX", NULL, "SLIMBUS3_DL_HL"}, + {"SLIMBUS4_DL_HL", "Switch", "SLIM4_DL_HL"}, + {"SLIMBUS_4_RX", NULL, "SLIMBUS4_DL_HL"}, + {"SLIMBUS6_DL_HL", "Switch", "SLIM0_DL_HL"}, + {"SLIMBUS_6_RX", NULL, "SLIMBUS6_DL_HL"}, + {"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"}, + {"SLIM1_UL_HL", NULL, "SLIMBUS_1_TX"}, + {"SLIM3_UL_HL", NULL, "SLIMBUS_3_TX"}, + {"SLIM4_UL_HL", NULL, "SLIMBUS_4_TX"}, + {"SLIM8_UL_HL", NULL, "SLIMBUS_8_TX"}, + + {"LSM1 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM1 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM1 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM1 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM1 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM1 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM1_UL_HL", NULL, "LSM1 Mixer"}, + + {"LSM2 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM2 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM2 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM2 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM2 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM2 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM2_UL_HL", NULL, "LSM2 Mixer"}, + + + {"LSM3 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM3 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM3 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM3 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM3 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM3 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM3_UL_HL", NULL, "LSM3 Mixer"}, + + + {"LSM4 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM4 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM4 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM4 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM4 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM4 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM4 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM4 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM4_UL_HL", NULL, "LSM4 Mixer"}, + + {"LSM5 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM5 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM5 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM5 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM5 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM5_UL_HL", NULL, "LSM5 Mixer"}, + + {"LSM6 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM6 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM6 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM6 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM6 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM6_UL_HL", NULL, "LSM6 Mixer"}, + + {"LSM7 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM7 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM7 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM7 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM7 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM7 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM7_UL_HL", NULL, "LSM7 Mixer"}, + + {"LSM8 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM8 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM8 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM8 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM8 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM8 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM8_UL_HL", NULL, "LSM8 Mixer"}, + + + {"CPE_LSM_UL_HL", NULL, "BE_IN"}, + {"QCHAT_Tx Mixer", "PRI_TX_QCHAT", "PRI_I2S_TX"}, + {"QCHAT_Tx Mixer", "SLIM_0_TX_QCHAT", "SLIMBUS_0_TX"}, + {"QCHAT_Tx Mixer", "SLIM_7_TX_QCHAT", "SLIMBUS_7_TX"}, + {"QCHAT_Tx Mixer", "SLIM_8_TX_QCHAT", "SLIMBUS_8_TX"}, + {"QCHAT_Tx Mixer", "INTERNAL_BT_SCO_TX_QCHAT", "INT_BT_SCO_TX"}, + {"QCHAT_Tx Mixer", "AFE_PCM_TX_QCHAT", "PCM_TX"}, + {"QCHAT_Tx Mixer", "AUX_PCM_TX_QCHAT", "AUX_PCM_TX"}, + {"QCHAT_Tx Mixer", "SEC_AUX_PCM_TX_QCHAT", "SEC_AUX_PCM_TX"}, + {"QCHAT_Tx Mixer", "TERT_AUX_PCM_TX_QCHAT", "TERT_AUX_PCM_TX"}, + {"QCHAT_Tx Mixer", "QUAT_AUX_PCM_TX_QCHAT", "QUAT_AUX_PCM_TX"}, + {"QCHAT_Tx Mixer", "MI2S_TX_QCHAT", "MI2S_TX"}, + {"QCHAT_Tx Mixer", "PRI_MI2S_TX_QCHAT", "PRI_MI2S_TX"}, + {"QCHAT_Tx Mixer", "TERT_MI2S_TX_QCHAT", "TERT_MI2S_TX"}, + {"QCHAT_Tx Mixer", "INT3_MI2S_TX_QCHAT", "INT3_MI2S_TX"}, + {"QCHAT_Tx Mixer", "USB_AUDIO_TX_QCHAT", "USB_AUDIO_TX"}, + {"QCHAT_UL", NULL, "QCHAT_Tx Mixer"}, + + {"INT_FM_RX", NULL, "INTFM_DL_HL"}, + {"INTFM_UL_HL", NULL, "INT_FM_TX"}, + {"INTHFP_UL_HL", NULL, "HFP_PRI_AUX_UL_HL"}, + {"HFP_PRI_AUX_UL_HL", "Switch", "AUX_PCM_TX"}, + {"INTHFP_UL_HL", NULL, "HFP_AUX_UL_HL"}, + {"HFP_AUX_UL_HL", "Switch", "SEC_AUX_PCM_TX"}, + {"INTHFP_UL_HL", NULL, "HFP_INT_UL_HL"}, + {"HFP_INT_UL_HL", "Switch", "INT_BT_SCO_TX"}, + {"SLIM7_UL_HL", NULL, "HFP_SLIM7_UL_HL"}, + {"HFP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"}, + {"AUX_PCM_RX", NULL, "AUXPCM_DL_HL"}, + {"AUX_PCM_RX", NULL, "INTHFP_DL_HL"}, + {"AUXPCM_UL_HL", NULL, "AUX_PCM_TX"}, + {"MI2S_RX", NULL, "MI2S_DL_HL"}, + {"MI2S_UL_HL", NULL, "MI2S_TX"}, + {"PCM_RX_DL_HL", "Switch", "SLIM0_DL_HL"}, + {"PCM_RX", NULL, "PCM_RX_DL_HL"}, + + /* connect to INT4_MI2S_DL_HL since same pcm_id */ + {"INT0_MI2S_RX_DL_HL", "Switch", "INT4_MI2S_DL_HL"}, + {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX_DL_HL"}, + {"INT4_MI2S_RX_DL_HL", "Switch", "INT4_MI2S_DL_HL"}, + {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_DL_HL"}, + {"PRI_MI2S_RX_DL_HL", "Switch", "PRI_MI2S_DL_HL"}, + {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_DL_HL"}, + {"SEC_MI2S_RX_DL_HL", "Switch", "SEC_MI2S_DL_HL"}, + {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX_DL_HL"}, + {"TERT_MI2S_RX_DL_HL", "Switch", "TERT_MI2S_DL_HL"}, + {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX_DL_HL"}, + + {"QUAT_MI2S_RX_DL_HL", "Switch", "QUAT_MI2S_DL_HL"}, + {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_DL_HL"}, + {"MI2S_UL_HL", NULL, "TERT_MI2S_TX"}, + {"INT3_MI2S_UL_HL", NULL, "INT3_MI2S_TX"}, + {"TERT_MI2S_UL_HL", NULL, "TERT_MI2S_TX"}, + {"SEC_I2S_RX", NULL, "SEC_I2S_DL_HL"}, + {"PRI_MI2S_UL_HL", NULL, "PRI_MI2S_TX"}, + {"SEC_MI2S_UL_HL", NULL, "SEC_MI2S_TX"}, + {"SEC_MI2S_RX", NULL, "SEC_MI2S_DL_HL"}, + {"PRI_MI2S_RX", NULL, "PRI_MI2S_DL_HL"}, + {"TERT_MI2S_RX", NULL, "TERT_MI2S_DL_HL"}, + {"QUAT_MI2S_UL_HL", NULL, "QUAT_MI2S_TX"}, + + {"PRI_TDM_TX_0_UL_HL", NULL, "PRI_TDM_TX_0"}, + {"PRI_TDM_TX_1_UL_HL", NULL, "PRI_TDM_TX_1"}, + {"PRI_TDM_TX_2_UL_HL", NULL, "PRI_TDM_TX_2"}, + {"PRI_TDM_TX_3_UL_HL", NULL, "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0_DL_HL"}, + {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1_DL_HL"}, + {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2_DL_HL"}, + {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3_DL_HL"}, + {"SEC_TDM_TX_0_UL_HL", NULL, "SEC_TDM_TX_0"}, + {"SEC_TDM_TX_1_UL_HL", NULL, "SEC_TDM_TX_1"}, + {"SEC_TDM_TX_2_UL_HL", NULL, "SEC_TDM_TX_2"}, + {"SEC_TDM_TX_3_UL_HL", NULL, "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0_DL_HL"}, + {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1_DL_HL"}, + {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2_DL_HL"}, + {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3_DL_HL"}, + {"TERT_TDM_TX_0_UL_HL", NULL, "TERT_TDM_TX_0"}, + {"TERT_TDM_TX_1_UL_HL", NULL, "TERT_TDM_TX_1"}, + {"TERT_TDM_TX_2_UL_HL", NULL, "TERT_TDM_TX_2"}, + {"TERT_TDM_TX_3_UL_HL", NULL, "TERT_TDM_TX_3"}, + {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0_DL_HL"}, + {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1_DL_HL"}, + {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2_DL_HL"}, + {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3_DL_HL"}, + {"QUAT_TDM_TX_0_UL_HL", NULL, "QUAT_TDM_TX_0"}, + {"QUAT_TDM_TX_1_UL_HL", NULL, "QUAT_TDM_TX_1"}, + {"QUAT_TDM_TX_2_UL_HL", NULL, "QUAT_TDM_TX_2"}, + {"QUAT_TDM_TX_3_UL_HL", NULL, "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0_DL_HL"}, + {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1_DL_HL"}, + {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_DL_HL"}, + {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3_DL_HL"}, + + {"PRI_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Port Mixer"}, + + {"PRI_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Port Mixer"}, + + {"PRI_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Port Mixer"}, + + {"PRI_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Port Mixer"}, + + {"SEC_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Port Mixer"}, + + {"SEC_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Port Mixer"}, + + {"SEC_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Port Mixer"}, + + {"SEC_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Port Mixer"}, + + {"TERT_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Port Mixer"}, + + {"TERT_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Port Mixer"}, + + {"TERT_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Port Mixer"}, + + {"TERT_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Port Mixer"}, + + {"QUAT_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Port Mixer"}, + + {"QUAT_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Port Mixer"}, + + {"QUAT_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Port Mixer"}, + + {"QUAT_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Port Mixer"}, + + {"INT0_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"INT0_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"INT0_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"INT0_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX Port Mixer"}, + + {"INT4_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"INT4_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"INT4_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"INT4_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX Port Mixer"}, + + {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"SLIMBUS_0_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"SLIMBUS_0_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SLIMBUS_0_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"SLIMBUS_0_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"SLIMBUS_0_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"}, + {"AFE_PCM_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"AFE_PCM_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"PCM_RX", NULL, "AFE_PCM_RX Port Mixer"}, + {"USB_AUDIO_RX Port Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX Port Mixer"}, + {"USB_DL_HL", "Switch", "USBAUDIO_DL_HL"}, + {"USB_AUDIO_RX", NULL, "USB_DL_HL"}, + {"USBAUDIO_UL_HL", NULL, "USB_AUDIO_TX"}, + + + {"AUX_PCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"AUX_PCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"AUX_PCM_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"AUX_PCM_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"AUX_PCM_RX Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"AUX_PCM_RX", NULL, "AUX_PCM_RX Port Mixer"}, + + {"SEC_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_AUXPCM_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SEC_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_RX Port Mixer"}, + + {"TERT_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"TERT_AUXPCM_RX Port Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, + {"TERT_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"TERT_AUX_PCM_RX", NULL, "TERT_AUXPCM_RX Port Mixer"}, + + {"QUAT_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUAT_AUXPCM_RX Port Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"QUAT_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUXPCM_RX Port Mixer"}, + + {"Voice Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, + {"Voice Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"Voice Stub Tx Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"Voice Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"}, + {"Voice Stub Tx Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "MI2S_TX", "MI2S_TX"}, + {"Voice Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"Voice Stub Tx Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"Voice Stub Tx Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"Voice Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"Voice Stub Tx Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"Voice Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"}, + {"Voice Stub Tx Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"Voice Stub Tx Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"Voice Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"VOICE_STUB_UL", NULL, "Voice Stub Tx Mixer"}, + + {"VoLTE Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, + {"VoLTE Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"VoLTE Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"}, + {"VoLTE Stub Tx Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"VoLTE Stub Tx Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"VoLTE Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"}, + {"VoLTE Stub Tx Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"VoLTE Stub Tx Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"VoLTE Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"VoLTE Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"VoLTE Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"VOLTE_STUB_UL", NULL, "VoLTE Stub Tx Mixer"}, + + {"Voice2 Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, + {"Voice2 Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"Voice2 Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"}, + {"Voice2 Stub Tx Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"Voice2 Stub Tx Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"Voice2 Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"}, + {"Voice2 Stub Tx Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"Voice2 Stub Tx Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"Voice2 Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"Voice2 Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"Voice2 Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"VOICE2_STUB_UL", NULL, "Voice2 Stub Tx Mixer"}, + + {"STUB_RX Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"STUB_RX Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"STUB_RX Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"STUB_RX", NULL, "STUB_RX Mixer"}, + {"SLIMBUS_1_RX Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"SLIMBUS_1_RX Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"SLIMBUS_1_RX Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Mixer"}, + {"AFE_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"AFE_PCM_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"AFE_PCM_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"SLIMBUS_3_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"SLIMBUS_3_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"SLIMBUS_3_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX_Voice Mixer"}, + + {"SLIM_7_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"SLIM_7_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"SLIM_7_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"SLIM_7_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"SLIM_7_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SLIM_7_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SLIM_7_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"SLIM_7_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"SLIM_7_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"SLIM_7_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SLIM_7_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIM_7_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SLIMBUS_7_RX", NULL, "SLIM_7_RX_Voice Mixer"}, + + {"SLIM_8_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"SLIM_8_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"SLIM_8_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"SLIM_8_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"SLIM_8_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SLIM_8_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SLIM_8_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"SLIM_8_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"SLIM_8_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"SLIM_8_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SLIM_8_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIM_8_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SLIMBUS_8_RX", NULL, "SLIM_8_RX_Voice Mixer"}, + + {"SLIMBUS_1_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SLIMBUS_1_RX Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"SLIMBUS_1_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Port Mixer"}, + {"INTERNAL_BT_SCO_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"INTERNAL_BT_SCO_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Port Mixer"}, + {"SLIMBUS_3_RX Port Mixer", "INTERNAL_BT_SCO_RX", "INT_BT_SCO_RX"}, + {"SLIMBUS_3_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"SLIMBUS_3_RX Port Mixer", "AFE_PCM_RX", "PCM_RX"}, + {"SLIMBUS_3_RX Port Mixer", "AUX_PCM_RX", "AUX_PCM_RX"}, + {"SLIMBUS_3_RX Port Mixer", "SLIM_0_RX", "SLIMBUS_0_RX"}, + {"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX Port Mixer"}, + + {"SLIMBUS_6_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"SLIMBUS_6_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SLIMBUS_6_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"SLIMBUS_6_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SLIMBUS_6_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"SLIMBUS_6_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"SLIMBUS_6_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SLIMBUS_6_RX", NULL, "SLIMBUS_6_RX Port Mixer"}, + + {"HDMI_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"HDMI", NULL, "HDMI_RX Port Mixer"}, + + {"DISPLAY_PORT_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"DISPLAY_PORT", NULL, "DISPLAY_PORT_RX Port Mixer"}, + + {"SEC_I2S_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"SEC_I2S_RX", NULL, "SEC_I2S_RX Port Mixer"}, + + {"MI2S_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MI2S_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"MI2S_RX", NULL, "MI2S_RX Port Mixer"}, + + {"PRI_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"PRI_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"PRI_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"PRI_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Port Mixer"}, + + {"SEC_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"SEC_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"SEC_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"SEC_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Port Mixer"}, + + {"TERT_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"TERT_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"TERT_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"TERT_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"TERT_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"TERT_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX Port Mixer"}, + + {"QUAT_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUAT_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUAT_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"QUAT_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"QUAT_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"QUAT_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUAT_MI2S_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUAT_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX Port Mixer"}, + + /* Backend Enablement */ + + {"BE_OUT", NULL, "PRI_I2S_RX"}, + {"BE_OUT", NULL, "SEC_I2S_RX"}, + {"BE_OUT", NULL, "SLIMBUS_0_RX"}, + {"BE_OUT", NULL, "SLIMBUS_1_RX"}, + {"BE_OUT", NULL, "SLIMBUS_2_RX"}, + {"BE_OUT", NULL, "SLIMBUS_3_RX"}, + {"BE_OUT", NULL, "SLIMBUS_4_RX"}, + {"BE_OUT", NULL, "SLIMBUS_5_RX"}, + {"BE_OUT", NULL, "SLIMBUS_6_RX"}, + {"BE_OUT", NULL, "SLIMBUS_7_RX"}, + {"BE_OUT", NULL, "SLIMBUS_8_RX"}, + {"BE_OUT", NULL, "USB_AUDIO_RX"}, + {"BE_OUT", NULL, "HDMI"}, + {"BE_OUT", NULL, "DISPLAY_PORT"}, + {"BE_OUT", NULL, "SPDIF_RX"}, + {"BE_OUT", NULL, "MI2S_RX"}, + {"BE_OUT", NULL, "QUAT_MI2S_RX"}, + {"BE_OUT", NULL, "QUIN_MI2S_RX"}, + {"BE_OUT", NULL, "TERT_MI2S_RX"}, + {"BE_OUT", NULL, "SEC_MI2S_RX"}, + {"BE_OUT", NULL, "SEC_MI2S_RX_SD1"}, + {"BE_OUT", NULL, "PRI_MI2S_RX"}, + {"BE_OUT", NULL, "INT0_MI2S_RX"}, + {"BE_OUT", NULL, "INT4_MI2S_RX"}, + {"BE_OUT", NULL, "INT_BT_SCO_RX"}, + {"BE_OUT", NULL, "INT_BT_A2DP_RX"}, + {"BE_OUT", NULL, "INT_FM_RX"}, + {"BE_OUT", NULL, "PCM_RX"}, + {"BE_OUT", NULL, "SLIMBUS_3_RX"}, + {"BE_OUT", NULL, "AUX_PCM_RX"}, + {"BE_OUT", NULL, "SEC_AUX_PCM_RX"}, + {"BE_OUT", NULL, "TERT_AUX_PCM_RX"}, + {"BE_OUT", NULL, "QUAT_AUX_PCM_RX"}, + {"BE_OUT", NULL, "INT_BT_SCO_RX"}, + {"BE_OUT", NULL, "INT_FM_RX"}, + {"BE_OUT", NULL, "PCM_RX"}, + {"BE_OUT", NULL, "SLIMBUS_3_RX"}, + {"BE_OUT", NULL, "VOICE_PLAYBACK_TX"}, + {"BE_OUT", NULL, "VOICE2_PLAYBACK_TX"}, + {"BE_OUT", NULL, "PRI_TDM_RX_0"}, + {"BE_OUT", NULL, "PRI_TDM_RX_1"}, + {"BE_OUT", NULL, "PRI_TDM_RX_2"}, + {"BE_OUT", NULL, "PRI_TDM_RX_3"}, + {"BE_OUT", NULL, "SEC_TDM_RX_0"}, + {"BE_OUT", NULL, "SEC_TDM_RX_1"}, + {"BE_OUT", NULL, "SEC_TDM_RX_2"}, + {"BE_OUT", NULL, "SEC_TDM_RX_3"}, + {"BE_OUT", NULL, "TERT_TDM_RX_0"}, + {"BE_OUT", NULL, "TERT_TDM_RX_1"}, + {"BE_OUT", NULL, "TERT_TDM_RX_2"}, + {"BE_OUT", NULL, "TERT_TDM_RX_3"}, + {"BE_OUT", NULL, "TERT_TDM_RX_4"}, + {"BE_OUT", NULL, "QUAT_TDM_RX_0"}, + {"BE_OUT", NULL, "QUAT_TDM_RX_1"}, + {"BE_OUT", NULL, "QUAT_TDM_RX_2"}, + {"BE_OUT", NULL, "QUAT_TDM_RX_3"}, + + {"PRI_I2S_TX", NULL, "BE_IN"}, + {"MI2S_TX", NULL, "BE_IN"}, + {"QUAT_MI2S_TX", NULL, "BE_IN"}, + {"QUIN_MI2S_TX", NULL, "BE_IN"}, + {"PRI_MI2S_TX", NULL, "BE_IN"}, + {"TERT_MI2S_TX", NULL, "BE_IN"}, + {"INT2_MI2S_TX", NULL, "BE_IN"}, + {"INT3_MI2S_TX", NULL, "BE_IN"}, + {"INT5_MI2S_TX", NULL, "BE_IN"}, + {"SEC_MI2S_TX", NULL, "BE_IN"}, + {"SENARY_MI2S_TX", NULL, "BE_IN" }, + {"SLIMBUS_0_TX", NULL, "BE_IN" }, + {"SLIMBUS_1_TX", NULL, "BE_IN" }, + {"SLIMBUS_3_TX", NULL, "BE_IN" }, + {"SLIMBUS_4_TX", NULL, "BE_IN" }, + {"SLIMBUS_5_TX", NULL, "BE_IN" }, + {"SLIMBUS_6_TX", NULL, "BE_IN" }, + {"SLIMBUS_7_TX", NULL, "BE_IN" }, + {"SLIMBUS_8_TX", NULL, "BE_IN" }, + {"USB_AUDIO_TX", NULL, "BE_IN" }, + {"INT_BT_SCO_TX", NULL, "BE_IN"}, + {"INT_FM_TX", NULL, "BE_IN"}, + {"PCM_TX", NULL, "BE_IN"}, + {"BE_OUT", NULL, "SLIMBUS_3_RX"}, + {"BE_OUT", NULL, "STUB_RX"}, + {"STUB_TX", NULL, "BE_IN"}, + {"STUB_1_TX", NULL, "BE_IN"}, + {"BE_OUT", NULL, "AUX_PCM_RX"}, + {"AUX_PCM_TX", NULL, "BE_IN"}, + {"SEC_AUX_PCM_TX", NULL, "BE_IN"}, + {"TERT_AUX_PCM_TX", NULL, "BE_IN"}, + {"QUAT_AUX_PCM_TX", NULL, "BE_IN"}, + {"INCALL_RECORD_TX", NULL, "BE_IN"}, + {"INCALL_RECORD_RX", NULL, "BE_IN"}, + {"SLIM0_RX_VI_FB_LCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"}, + {"SLIM0_RX_VI_FB_RCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"}, + {"PRI_MI2S_RX_VI_FB_MUX", "SENARY_TX", "SENARY_TX"}, + {"INT4_MI2S_RX_VI_FB_MONO_CH_MUX", "INT5_MI2S_TX", "INT5_MI2S_TX"}, + {"INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", "INT5_MI2S_TX", "INT5_MI2S_TX"}, + {"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_LCH_MUX"}, + {"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_RCH_MUX"}, + {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_VI_FB_MUX"}, + {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_MONO_CH_MUX"}, + {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_STEREO_CH_MUX"}, + {"PRI_TDM_TX_0", NULL, "BE_IN"}, + {"PRI_TDM_TX_1", NULL, "BE_IN"}, + {"PRI_TDM_TX_2", NULL, "BE_IN"}, + {"PRI_TDM_TX_3", NULL, "BE_IN"}, + {"SEC_TDM_TX_0", NULL, "BE_IN"}, + {"SEC_TDM_TX_1", NULL, "BE_IN"}, + {"SEC_TDM_TX_2", NULL, "BE_IN"}, + {"SEC_TDM_TX_3", NULL, "BE_IN"}, + {"TERT_TDM_TX_0", NULL, "BE_IN"}, + {"TERT_TDM_TX_1", NULL, "BE_IN"}, + {"TERT_TDM_TX_2", NULL, "BE_IN"}, + {"TERT_TDM_TX_3", NULL, "BE_IN"}, + {"QUAT_TDM_TX_0", NULL, "BE_IN"}, + {"QUAT_TDM_TX_1", NULL, "BE_IN"}, + {"QUAT_TDM_TX_2", NULL, "BE_IN"}, + {"QUAT_TDM_TX_3", NULL, "BE_IN"}, +}; + +static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + unsigned int be_id = rtd->dai_link->id; + + if (be_id >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: unexpected BE id %d\n", __func__, be_id); + return -EINVAL; + } + + mutex_lock(&routing_lock); + msm_bedais[be_id].sample_rate = params_rate(params); + msm_bedais[be_id].channel = params_channels(params); + msm_bedais[be_id].format = params_format(params); + pr_debug("%s: BE Sample Rate (%d) format (%d) BE id %d\n", + __func__, msm_bedais[be_id].sample_rate, + msm_bedais[be_id].format, be_id); + mutex_unlock(&routing_lock); + return 0; +} + +static int msm_pcm_routing_close(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + unsigned int be_id = rtd->dai_link->id; + int i, session_type, path_type, topology; + struct msm_pcm_routing_bdai_data *bedai; + struct msm_pcm_routing_fdai_data *fdai; + + pr_debug("%s: substream->pcm->id:%s\n", + __func__, substream->pcm->id); + + if (be_id >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: unexpected BE id %d\n", __func__, be_id); + return -EINVAL; + } + + bedai = &msm_bedais[be_id]; + session_type = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? + 0 : 1); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + path_type = ADM_PATH_PLAYBACK; + else + path_type = ADM_PATH_LIVE_REC; + + mutex_lock(&routing_lock); + for_each_set_bit(i, &bedai->fe_sessions[0], MSM_FRONTEND_DAI_MAX) { + if (!is_mm_lsm_fe_id(i)) + continue; + fdai = &fe_dai_map[i][session_type]; + if (fdai->strm_id != INVALID_SESSION) { + int idx; + int port_id; + unsigned long copp = + session_copp_map[i][session_type][be_id]; + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) + if (test_bit(idx, &copp)) + break; + fdai->be_srate = bedai->sample_rate; + port_id = bedai->port_id; + topology = adm_get_topology_for_port_copp_idx(port_id, + idx); + adm_close(bedai->port_id, fdai->perf_mode, idx); + pr_debug("%s: copp:%ld,idx bit fe:%d, type:%d,be:%d topology=0x%x\n", + __func__, copp, i, session_type, be_id, + topology); + clear_bit(idx, + &session_copp_map[i][session_type][be_id]); + if ((fdai->perf_mode == LEGACY_PCM_MODE) && + (bedai->passthr_mode[i] == LEGACY_PCM)) + msm_pcm_routing_deinit_pp(bedai->port_id, + topology); + } + } + + bedai->active = 0; + bedai->sample_rate = 0; + bedai->channel = 0; + for (i = 0; i < MSM_FRONTEND_DAI_MAX; i++) { + if (bedai->passthr_mode[i] != LISTEN) + bedai->passthr_mode[i] = LEGACY_PCM; + } + mutex_unlock(&routing_lock); + + return 0; +} + +static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + unsigned int be_id = rtd->dai_link->id; + int i, path_type, topology; + int session_type = INVALID_SESSION; + struct msm_pcm_routing_bdai_data *bedai; + u32 channels, sample_rate; + uint16_t bits_per_sample = 16, voc_path_type; + struct msm_pcm_routing_fdai_data *fdai; + u32 session_id; + struct media_format_info voc_be_media_format; + bool is_lsm; + + pr_debug("%s: substream->pcm->id:%s\n", + __func__, substream->pcm->id); + + if (be_id >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: unexpected BE id %d\n", __func__, be_id); + return -EINVAL; + } + + bedai = &msm_bedais[be_id]; + + mutex_lock(&routing_lock); + if (bedai->active == 1) + goto done; /* Ignore prepare if back-end already active */ + + /* AFE port is not active at this point. However, still + * go ahead setting active flag under the notion that + * QDSP6 is able to handle ADM starting before AFE port + * is started. + */ + bedai->active = 1; + + for_each_set_bit(i, &bedai->fe_sessions[0], MSM_FRONTEND_DAI_MAX) { + if (!(is_mm_lsm_fe_id(i) && + route_check_fe_id_adm_support(i))) + continue; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + if (bedai->passthr_mode[i] != LEGACY_PCM) + path_type = ADM_PATH_COMPRESSED_RX; + else + path_type = ADM_PATH_PLAYBACK; + session_type = SESSION_TYPE_RX; + } else { + path_type = ADM_PATH_LIVE_REC; + session_type = SESSION_TYPE_TX; + } + + is_lsm = (i >= MSM_FRONTEND_DAI_LSM1) && + (i <= MSM_FRONTEND_DAI_LSM8); + fdai = &fe_dai_map[i][session_type]; + if (fdai->strm_id != INVALID_SESSION) { + int app_type, app_type_idx, copp_idx, acdb_dev_id; + + if (session_type == SESSION_TYPE_TX && + fdai->be_srate && + (fdai->be_srate != bedai->sample_rate)) { + pr_debug("%s: flush strm %d diff BE rates\n", + __func__, + fdai->strm_id); + + if (fdai->event_info.event_func) + fdai->event_info.event_func( + MSM_PCM_RT_EVT_BUF_RECFG, + fdai->event_info.priv_data); + fdai->be_srate = 0; /* might not need it */ + } + bits_per_sample = msm_routing_get_bit_width( + bedai->format); + + app_type = + fe_dai_app_type_cfg[i][session_type][be_id].app_type; + if (app_type && is_lsm) { + app_type_idx = + msm_pcm_routing_get_lsm_app_type_idx(app_type); + sample_rate = + fe_dai_app_type_cfg[i][session_type][be_id] + .sample_rate; + bits_per_sample = + lsm_app_type_cfg[app_type_idx].bit_width; + } else if (app_type) { + app_type_idx = + msm_pcm_routing_get_app_type_idx(app_type); + sample_rate = + fe_dai_app_type_cfg[i][session_type] + [be_id].sample_rate; + bits_per_sample = + app_type_cfg[app_type_idx].bit_width; + } else + sample_rate = bedai->sample_rate; + /* + * check if ADM needs to be configured with different + * channel mapping than backend + */ + if (!bedai->adm_override_ch) + channels = bedai->channel; + else + channels = bedai->adm_override_ch; + acdb_dev_id = + fe_dai_app_type_cfg[i][session_type][be_id].acdb_dev_id; + topology = msm_routing_get_adm_topology(i, session_type, + be_id); + copp_idx = adm_open(bedai->port_id, path_type, + sample_rate, channels, topology, + fdai->perf_mode, bits_per_sample, + app_type, acdb_dev_id); + if ((copp_idx < 0) || + (copp_idx >= MAX_COPPS_PER_PORT)) { + pr_err("%s: adm open failed\n", __func__); + mutex_unlock(&routing_lock); + return -EINVAL; + } + pr_debug("%s: setting idx bit of fe:%d, type: %d, be:%d\n", + __func__, i, session_type, be_id); + set_bit(copp_idx, + &session_copp_map[i][session_type][be_id]); + + if (msm_is_resample_needed( + sample_rate, + bedai->sample_rate)) + adm_copp_mfc_cfg( + bedai->port_id, copp_idx, + bedai->sample_rate); + + msm_pcm_routing_build_matrix(i, session_type, path_type, + fdai->perf_mode, + bedai->passthr_mode[i]); + if ((fdai->perf_mode == LEGACY_PCM_MODE) && + (bedai->passthr_mode[i] == LEGACY_PCM)) + msm_pcm_routing_cfg_pp(bedai->port_id, copp_idx, + topology, channels); + } + } + + for_each_set_bit(i, &bedai->fe_sessions[0], MSM_FRONTEND_DAI_MAX) { + session_id = msm_pcm_routing_get_voc_sessionid(i); + if (session_id) { + pr_debug("%s voice session_id: 0x%x\n", __func__, + session_id); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + voc_path_type = RX_PATH; + else + voc_path_type = TX_PATH; + + voc_set_route_flag(session_id, voc_path_type, 1); + + memset(&voc_be_media_format, 0, + sizeof(struct media_format_info)); + + voc_be_media_format.port_id = bedai->port_id; + voc_be_media_format.num_channels = bedai->channel; + voc_be_media_format.sample_rate = bedai->sample_rate; + voc_be_media_format.bits_per_sample = bedai->format; + /* Defaulting this to 1 for voice call usecases */ + voc_be_media_format.channel_mapping[0] = 1; + + voc_set_device_config(session_id, voc_path_type, + &voc_be_media_format); + + if (voc_get_route_flag(session_id, RX_PATH) && + voc_get_route_flag(session_id, TX_PATH)) + voc_enable_device(session_id); + } + } + + /* Check if backend is an external ec ref port and set as needed */ + if (unlikely(bedai->port_id == voc_get_ext_ec_ref_port_id())) { + + memset(&voc_be_media_format, 0, + sizeof(struct media_format_info)); + + /* Get format info for ec ref port from msm_bedais[] */ + voc_be_media_format.port_id = bedai->port_id; + voc_be_media_format.num_channels = bedai->channel; + voc_be_media_format.bits_per_sample = bedai->format; + voc_be_media_format.sample_rate = bedai->sample_rate; + /* Defaulting this to 1 for voice call usecases */ + voc_be_media_format.channel_mapping[0] = 1; + voc_set_ext_ec_ref_media_fmt_info(&voc_be_media_format); + pr_debug("%s: EC Ref media format info set to port_id=%d, num_channels=%d, bits_per_sample=%d, sample_rate=%d\n", + __func__, voc_be_media_format.port_id, + voc_be_media_format.num_channels, + voc_be_media_format.bits_per_sample, + voc_be_media_format.sample_rate); + } + +done: + mutex_unlock(&routing_lock); + + return 0; +} + +static int msm_routing_send_device_pp_params(int port_id, int copp_idx, + int fe_id) +{ + int index, topo_id, be_idx; + unsigned long pp_config = 0; + bool mute_on; + int latency; + bool compr_passthr_mode = true; + + pr_debug("%s: port_id %d, copp_idx %d\n", __func__, port_id, copp_idx); + + if (port_id != HDMI_RX && port_id != DISPLAY_PORT_RX) { + pr_err("%s: Device pp params on invalid port %d\n", + __func__, port_id); + return -EINVAL; + } + + for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) { + if (port_id == msm_bedais[be_idx].port_id) + break; + } + + if (be_idx >= MSM_BACKEND_DAI_MAX) { + pr_debug("%s: Invalid be id %d\n", __func__, be_idx); + return -EINVAL; + } + + for (index = 0; index < MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX; index++) { + if (msm_bedais_pp_params[index].port_id == port_id) + break; + } + if (index >= MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX) { + pr_err("%s: Invalid backend pp params index %d\n", + __func__, index); + return -EINVAL; + } + + topo_id = adm_get_topology_for_port_copp_idx(port_id, copp_idx); + if (topo_id != COMPRESSED_PASSTHROUGH_DEFAULT_TOPOLOGY) { + pr_err("%s: Invalid passthrough topology 0x%x\n", + __func__, topo_id); + return -EINVAL; + } + + if ((msm_bedais[be_idx].passthr_mode[fe_id] == LEGACY_PCM) || + (msm_bedais[be_idx].passthr_mode[fe_id] == LISTEN)) + compr_passthr_mode = false; + + pp_config = msm_bedais_pp_params[index].pp_params_config; + if (test_bit(ADM_PP_PARAM_MUTE_BIT, &pp_config)) { + pr_debug("%s: ADM_PP_PARAM_MUTE\n", __func__); + clear_bit(ADM_PP_PARAM_MUTE_BIT, &pp_config); + mute_on = msm_bedais_pp_params[index].mute_on; + if ((msm_bedais[be_idx].active) && compr_passthr_mode) + adm_send_compressed_device_mute(port_id, + copp_idx, + mute_on); + } + if (test_bit(ADM_PP_PARAM_LATENCY_BIT, &pp_config)) { + pr_debug("%s: ADM_PP_PARAM_LATENCY\n", __func__); + clear_bit(ADM_PP_PARAM_LATENCY_BIT, + &pp_config); + latency = msm_bedais_pp_params[index].latency; + if ((msm_bedais[be_idx].active) && compr_passthr_mode) + adm_send_compressed_device_latency(port_id, + copp_idx, + latency); + } + return 0; +} + +static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int pp_id = ucontrol->value.integer.value[0]; + int port_id = 0; + int index, be_idx, i, topo_id, idx; + bool mute; + int latency; + bool compr_passthr_mode = true; + + pr_debug("%s: pp_id: 0x%x\n", __func__, pp_id); + + for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) { + port_id = msm_bedais[be_idx].port_id; + if (port_id == HDMI_RX || port_id == DISPLAY_PORT_RX) + break; + } + + if (be_idx >= MSM_BACKEND_DAI_MAX) { + pr_debug("%s: Invalid be id %d\n", __func__, be_idx); + return -EINVAL; + } + + for (index = 0; index < MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX; index++) { + if (msm_bedais_pp_params[index].port_id == port_id) + break; + } + if (index >= MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX) { + pr_err("%s: Invalid pp params backend index %d\n", + __func__, index); + return -EINVAL; + } + + for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0], + MSM_FRONTEND_DAI_MM_SIZE) { + if ((msm_bedais[be_idx].passthr_mode[i] == LEGACY_PCM) || + (msm_bedais[be_idx].passthr_mode[i] == LISTEN)) + compr_passthr_mode = false; + + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { + unsigned long copp = + session_copp_map[i] + [SESSION_TYPE_RX][be_idx]; + if (!test_bit(idx, &copp)) + continue; + topo_id = adm_get_topology_for_port_copp_idx(port_id, + idx); + if (topo_id != COMPRESSED_PASSTHROUGH_DEFAULT_TOPOLOGY) + continue; + pr_debug("%s: port: 0x%x, copp %ld, be active: %d, passt: %d\n", + __func__, port_id, copp, msm_bedais[be_idx].active, + msm_bedais[be_idx].passthr_mode[i]); + switch (pp_id) { + case ADM_PP_PARAM_MUTE_ID: + pr_debug("%s: ADM_PP_PARAM_MUTE\n", __func__); + mute = ucontrol->value.integer.value[1] ? true : false; + msm_bedais_pp_params[index].mute_on = mute; + set_bit(ADM_PP_PARAM_MUTE_BIT, + &msm_bedais_pp_params[index].pp_params_config); + if ((msm_bedais[be_idx].active) && compr_passthr_mode) + adm_send_compressed_device_mute(port_id, + idx, mute); + break; + case ADM_PP_PARAM_LATENCY_ID: + pr_debug("%s: ADM_PP_PARAM_LATENCY\n", __func__); + msm_bedais_pp_params[index].latency = + ucontrol->value.integer.value[1]; + set_bit(ADM_PP_PARAM_LATENCY_BIT, + &msm_bedais_pp_params[index].pp_params_config); + latency = msm_bedais_pp_params[index].latency = + ucontrol->value.integer.value[1]; + if ((msm_bedais[be_idx].active) && compr_passthr_mode) + adm_send_compressed_device_latency(port_id, + idx, latency); + break; + default: + pr_info("%s, device pp param %d not supported\n", + __func__, pp_id); + break; + } + } + } + return 0; +} + +static int msm_routing_get_device_pp_params_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s:msm_routing_get_device_pp_params_mixer", __func__); + return 0; +} + +static const struct snd_kcontrol_new device_pp_params_mixer_controls[] = { + SOC_SINGLE_MULTI_EXT("Device PP Params", SND_SOC_NOPM, 0, 0xFFFFFFFF, + 0, 3, msm_routing_get_device_pp_params_mixer, + msm_routing_put_device_pp_params_mixer), +}; + +static int msm_aptx_dec_license_control_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = + core_get_license_status(ASM_MEDIA_FMT_APTX); + pr_debug("%s: status %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_aptx_dec_license_control_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int32_t status = 0; + + status = core_set_license(ucontrol->value.integer.value[0], + APTX_CLASSIC_DEC_LICENSE_ID); + pr_debug("%s: status %d\n", __func__, status); + return status; +} + +static const struct snd_kcontrol_new aptx_dec_license_controls[] = { + SOC_SINGLE_EXT("APTX Dec License", SND_SOC_NOPM, 0, + 0xFFFF, 0, msm_aptx_dec_license_control_get, + msm_aptx_dec_license_control_put), +}; + +static int msm_routing_be_dai_name_table_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(be_dai_name_table); + return 0; +} + +static int msm_routing_be_dai_name_table_tlv_get(struct snd_kcontrol *kcontrol, + unsigned int __user *bytes, + unsigned int size) +{ + int i; + int ret; + + if (size < sizeof(be_dai_name_table)) { + pr_err("%s: invalid size %d requested, returning\n", + __func__, size); + ret = -EINVAL; + goto done; + } + + /* + * Fill be_dai_name_table from msm_bedais table to reduce code changes + * needed when adding new backends + */ + for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) { + be_dai_name_table[i].be_id = i; + strlcpy(be_dai_name_table[i].be_name, + msm_bedais[i].name, + LPASS_BE_NAME_MAX_LENGTH); + } + + ret = copy_to_user(bytes, &be_dai_name_table, + sizeof(be_dai_name_table)); + if (ret) { + pr_err("%s: failed to copy be_dai_name_table\n", __func__); + ret = -EFAULT; + } + +done: + return ret; +} + +static const struct snd_kcontrol_new + msm_routing_be_dai_name_table_mixer_controls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | + SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, + .info = msm_routing_be_dai_name_table_info, + .name = "Backend DAI Name Table", + .tlv.c = snd_soc_bytes_tlv_callback, + .private_value = (unsigned long) &(struct soc_bytes_ext) { + .max = sizeof(be_dai_name_table), + .get = msm_routing_be_dai_name_table_tlv_get, + } + }, +}; + +static int msm_routing_stereo_channel_reverse_control_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = swap_ch; + pr_debug("%s: Swap channel value: %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_stereo_channel_reverse_control_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int i, idx, be_index, port_id; + int ret = 0; + unsigned long copp; + + pr_debug("%s Swap channel value:%ld\n", __func__, + ucontrol->value.integer.value[0]); + + swap_ch = ucontrol->value.integer.value[0]; + + mutex_lock(&routing_lock); + for (be_index = 0; be_index < MSM_BACKEND_DAI_MAX; be_index++) { + port_id = msm_bedais[be_index].port_id; + if (!msm_bedais[be_index].active) + continue; + + for_each_set_bit(i, &msm_bedais[be_index].fe_sessions[0], + MSM_FRONTEND_DAI_MM_SIZE) { + copp = session_copp_map[i][SESSION_TYPE_RX][be_index]; + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { + if (!test_bit(idx, &copp)) + continue; + + pr_debug("%s: swap channel control of portid:%d, coppid:%d\n", + __func__, port_id, idx); + ret = adm_swap_speaker_channels( + port_id, idx, + msm_bedais[be_index].sample_rate, + swap_ch); + if (ret) { + pr_err("%s:Swap_channel failed, err=%d\n", + __func__, ret); + goto done; + } + } + } + } +done: + mutex_unlock(&routing_lock); + return ret; +} + +static const struct snd_kcontrol_new stereo_channel_reverse_control[] = { + SOC_SINGLE_EXT("Swap channel", SND_SOC_NOPM, 0, + 1, 0, msm_routing_stereo_channel_reverse_control_get, + msm_routing_stereo_channel_reverse_control_put), +}; + +static const struct snd_pcm_ops msm_routing_pcm_ops = { + .hw_params = msm_pcm_routing_hw_params, + .close = msm_pcm_routing_close, + .prepare = msm_pcm_routing_prepare, +}; + +/* Not used but frame seems to require it */ +static int msm_routing_probe(struct snd_soc_platform *platform) +{ + snd_soc_dapm_new_controls(&platform->component.dapm, msm_qdsp6_widgets, + ARRAY_SIZE(msm_qdsp6_widgets)); + snd_soc_dapm_add_routes(&platform->component.dapm, intercon, + ARRAY_SIZE(intercon)); + + snd_soc_dapm_new_widgets(platform->component.dapm.card); + + snd_soc_add_platform_controls(platform, lsm_controls, + ARRAY_SIZE(lsm_controls)); + + snd_soc_add_platform_controls(platform, aanc_slim_0_rx_mux, + ARRAY_SIZE(aanc_slim_0_rx_mux)); + + snd_soc_add_platform_controls(platform, msm_voc_session_controls, + ARRAY_SIZE(msm_voc_session_controls)); + + snd_soc_add_platform_controls(platform, app_type_cfg_controls, + ARRAY_SIZE(app_type_cfg_controls)); + + snd_soc_add_platform_controls(platform, lsm_app_type_cfg_controls, + ARRAY_SIZE(lsm_app_type_cfg_controls)); + + snd_soc_add_platform_controls(platform, + stereo_to_custom_stereo_controls, + ARRAY_SIZE(stereo_to_custom_stereo_controls)); + + snd_soc_add_platform_controls(platform, ec_ref_param_controls, + ARRAY_SIZE(ec_ref_param_controls)); + + snd_soc_add_platform_controls(platform, channel_mixer_controls, + ARRAY_SIZE(channel_mixer_controls)); + + msm_qti_pp_add_controls(platform); + + msm_dts_srs_tm_add_controls(platform); + + msm_dolby_dap_add_controls(platform); + + snd_soc_add_platform_controls(platform, + use_ds1_or_ds2_controls, + ARRAY_SIZE(use_ds1_or_ds2_controls)); + + snd_soc_add_platform_controls(platform, + device_pp_params_mixer_controls, + ARRAY_SIZE(device_pp_params_mixer_controls)); + + snd_soc_add_platform_controls(platform, + msm_routing_be_dai_name_table_mixer_controls, + ARRAY_SIZE(msm_routing_be_dai_name_table_mixer_controls)); + + snd_soc_add_platform_controls(platform, msm_source_tracking_controls, + ARRAY_SIZE(msm_source_tracking_controls)); + snd_soc_add_platform_controls(platform, adm_channel_config_controls, + ARRAY_SIZE(adm_channel_config_controls)); + + snd_soc_add_platform_controls(platform, aptx_dec_license_controls, + ARRAY_SIZE(aptx_dec_license_controls)); + snd_soc_add_platform_controls(platform, stereo_channel_reverse_control, + ARRAY_SIZE(stereo_channel_reverse_control)); + return 0; +} + +int msm_routing_pcm_new(struct snd_soc_pcm_runtime *runtime) +{ + return msm_pcm_routing_hwdep_new(runtime, msm_bedais); +} + +void msm_routing_pcm_free(struct snd_pcm *pcm) +{ + msm_pcm_routing_hwdep_free(pcm); +} + +static struct snd_soc_platform_driver msm_soc_routing_platform = { + .ops = &msm_routing_pcm_ops, + .probe = msm_routing_probe, + .pcm_new = msm_routing_pcm_new, + .pcm_free = msm_routing_pcm_free, +}; + +static int msm_routing_pcm_probe(struct platform_device *pdev) +{ + + dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev)); + return snd_soc_register_platform(&pdev->dev, + &msm_soc_routing_platform); +} + +static int msm_routing_pcm_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_pcm_routing_dt_match[] = { + {.compatible = "qcom,msm-pcm-routing"}, + {} +}; +MODULE_DEVICE_TABLE(of, msm_pcm_routing_dt_match); + +static struct platform_driver msm_routing_pcm_driver = { + .driver = { + .name = "msm-pcm-routing", + .owner = THIS_MODULE, + .of_match_table = msm_pcm_routing_dt_match, + }, + .probe = msm_routing_pcm_probe, + .remove = msm_routing_pcm_remove, +}; + +int msm_routing_check_backend_enabled(int fedai_id) +{ + int i; + + if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) { + /* bad ID assigned in machine driver */ + pr_err("%s: bad MM ID\n", __func__); + return 0; + } + for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) { + if (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0])) + return msm_bedais[i].active; + } + return 0; +} + +static int msm_routing_set_cal(int32_t cal_type, + size_t data_size, void *data) +{ + int ret = 0; + + pr_debug("%s\n", __func__); + + ret = cal_utils_set_cal(data_size, data, cal_data, 0, NULL); + if (ret < 0) { + pr_err("%s: cal_utils_set_cal failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + ret = -EINVAL; + goto done; + } +done: + return ret; +} + +static void msm_routing_delete_cal_data(void) +{ + pr_debug("%s\n", __func__); + + cal_utils_destroy_cal_types(1, &cal_data); +} + +static int msm_routing_init_cal_data(void) +{ + int ret = 0; + struct cal_type_info cal_type_info = { + {ADM_TOPOLOGY_CAL_TYPE, + {NULL, NULL, NULL, + msm_routing_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} + }; + pr_debug("%s\n", __func__); + + ret = cal_utils_create_cal_types(1, &cal_data, + &cal_type_info); + if (ret < 0) { + pr_err("%s: could not create cal type!\n", + __func__); + ret = -EINVAL; + goto err; + } + + return ret; +err: + msm_routing_delete_cal_data(); + return ret; +} + +static int __init msm_soc_routing_platform_init(void) +{ + mutex_init(&routing_lock); + if (msm_routing_init_cal_data()) + pr_err("%s: could not init cal data!\n", __func__); + + afe_set_routing_callback( + (routing_cb)msm_pcm_get_dev_acdb_id_by_port_id); + + memset(&be_dai_name_table, 0, sizeof(be_dai_name_table)); + memset(&last_be_id_configured, 0, sizeof(last_be_id_configured)); + + return platform_driver_register(&msm_routing_pcm_driver); +} +module_init(msm_soc_routing_platform_init); + +static void __exit msm_soc_routing_platform_exit(void) +{ + msm_routing_delete_cal_data(); + memset(&be_dai_name_table, 0, sizeof(be_dai_name_table)); + mutex_destroy(&routing_lock); + platform_driver_unregister(&msm_routing_pcm_driver); +} +module_exit(msm_soc_routing_platform_exit); + +MODULE_DESCRIPTION("MSM routing platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h new file mode 100644 index 000000000000..19e726001d25 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h @@ -0,0 +1,486 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef _MSM_PCM_ROUTING_H +#define _MSM_PCM_ROUTING_H +#include + +/* + * These names are used by HAL to specify the BE. If any changes are + * made to the string names or the max name length corresponding + * changes need to be made in the HAL to ensure they still match. + */ +#define LPASS_BE_NAME_MAX_LENGTH 24 +#define LPASS_BE_PRI_I2S_RX "PRIMARY_I2S_RX" +#define LPASS_BE_PRI_I2S_TX "PRIMARY_I2S_TX" +#define LPASS_BE_SLIMBUS_0_RX "SLIMBUS_0_RX" +#define LPASS_BE_SLIMBUS_0_TX "SLIMBUS_0_TX" +#define LPASS_BE_HDMI "HDMI" +#define LPASS_BE_DISPLAY_PORT "DISPLAY_PORT" +#define LPASS_BE_INT_BT_SCO_RX "INT_BT_SCO_RX" +#define LPASS_BE_INT_BT_SCO_TX "INT_BT_SCO_TX" +#define LPASS_BE_INT_BT_A2DP_RX "INT_BT_A2DP_RX" +#define LPASS_BE_INT_FM_RX "INT_FM_RX" +#define LPASS_BE_INT_FM_TX "INT_FM_TX" +#define LPASS_BE_AFE_PCM_RX "RT_PROXY_DAI_001_RX" +#define LPASS_BE_AFE_PCM_TX "RT_PROXY_DAI_002_TX" +#define LPASS_BE_AUXPCM_RX "AUX_PCM_RX" +#define LPASS_BE_AUXPCM_TX "AUX_PCM_TX" +#define LPASS_BE_SEC_AUXPCM_RX "SEC_AUX_PCM_RX" +#define LPASS_BE_SEC_AUXPCM_TX "SEC_AUX_PCM_TX" +#define LPASS_BE_TERT_AUXPCM_RX "TERT_AUX_PCM_RX" +#define LPASS_BE_TERT_AUXPCM_TX "TERT_AUX_PCM_TX" +#define LPASS_BE_QUAT_AUXPCM_RX "QUAT_AUX_PCM_RX" +#define LPASS_BE_QUAT_AUXPCM_TX "QUAT_AUX_PCM_TX" +#define LPASS_BE_VOICE_PLAYBACK_TX "VOICE_PLAYBACK_TX" +#define LPASS_BE_VOICE2_PLAYBACK_TX "VOICE2_PLAYBACK_TX" +#define LPASS_BE_INCALL_RECORD_RX "INCALL_RECORD_RX" +#define LPASS_BE_INCALL_RECORD_TX "INCALL_RECORD_TX" +#define LPASS_BE_SEC_I2S_RX "SECONDARY_I2S_RX" +#define LPASS_BE_SPDIF_RX "SPDIF_RX" + +#define LPASS_BE_MI2S_RX "MI2S_RX" +#define LPASS_BE_MI2S_TX "MI2S_TX" +#define LPASS_BE_QUAT_MI2S_RX "QUAT_MI2S_RX" +#define LPASS_BE_QUAT_MI2S_TX "QUAT_MI2S_TX" +#define LPASS_BE_SEC_MI2S_RX "SEC_MI2S_RX" +#define LPASS_BE_SEC_MI2S_RX_SD1 "SEC_MI2S_RX_SD1" +#define LPASS_BE_SEC_MI2S_TX "SEC_MI2S_TX" +#define LPASS_BE_PRI_MI2S_RX "PRI_MI2S_RX" +#define LPASS_BE_PRI_MI2S_TX "PRI_MI2S_TX" +#define LPASS_BE_TERT_MI2S_RX "TERTIARY_MI2S_RX" +#define LPASS_BE_TERT_MI2S_TX "TERTIARY_MI2S_TX" +#define LPASS_BE_AUDIO_I2S_RX "AUDIO_I2S_RX" +#define LPASS_BE_STUB_RX "STUB_RX" +#define LPASS_BE_STUB_TX "STUB_TX" +#define LPASS_BE_SLIMBUS_1_RX "SLIMBUS_1_RX" +#define LPASS_BE_SLIMBUS_1_TX "SLIMBUS_1_TX" +#define LPASS_BE_STUB_1_TX "STUB_1_TX" +#define LPASS_BE_SLIMBUS_2_RX "SLIMBUS_2_RX" +#define LPASS_BE_SLIMBUS_2_TX "SLIMBUS_2_TX" +#define LPASS_BE_SLIMBUS_3_RX "SLIMBUS_3_RX" +#define LPASS_BE_SLIMBUS_3_TX "SLIMBUS_3_TX" +#define LPASS_BE_SLIMBUS_4_RX "SLIMBUS_4_RX" +#define LPASS_BE_SLIMBUS_4_TX "SLIMBUS_4_TX" +#define LPASS_BE_SLIMBUS_TX_VI "SLIMBUS_TX_VI" +#define LPASS_BE_SLIMBUS_5_RX "SLIMBUS_5_RX" +#define LPASS_BE_SLIMBUS_5_TX "SLIMBUS_5_TX" +#define LPASS_BE_SLIMBUS_6_RX "SLIMBUS_6_RX" +#define LPASS_BE_SLIMBUS_6_TX "SLIMBUS_6_TX" +#define LPASS_BE_QUIN_MI2S_RX "QUIN_MI2S_RX" +#define LPASS_BE_QUIN_MI2S_TX "QUIN_MI2S_TX" +#define LPASS_BE_SENARY_MI2S_TX "SENARY_MI2S_TX" + +#define LPASS_BE_PRI_TDM_RX_0 "PRI_TDM_RX_0" +#define LPASS_BE_PRI_TDM_TX_0 "PRI_TDM_TX_0" +#define LPASS_BE_PRI_TDM_RX_1 "PRI_TDM_RX_1" +#define LPASS_BE_PRI_TDM_TX_1 "PRI_TDM_TX_1" +#define LPASS_BE_PRI_TDM_RX_2 "PRI_TDM_RX_2" +#define LPASS_BE_PRI_TDM_TX_2 "PRI_TDM_TX_2" +#define LPASS_BE_PRI_TDM_RX_3 "PRI_TDM_RX_3" +#define LPASS_BE_PRI_TDM_TX_3 "PRI_TDM_TX_3" +#define LPASS_BE_PRI_TDM_RX_4 "PRI_TDM_RX_4" +#define LPASS_BE_PRI_TDM_TX_4 "PRI_TDM_TX_4" +#define LPASS_BE_PRI_TDM_RX_5 "PRI_TDM_RX_5" +#define LPASS_BE_PRI_TDM_TX_5 "PRI_TDM_TX_5" +#define LPASS_BE_PRI_TDM_RX_6 "PRI_TDM_RX_6" +#define LPASS_BE_PRI_TDM_TX_6 "PRI_TDM_TX_6" +#define LPASS_BE_PRI_TDM_RX_7 "PRI_TDM_RX_7" +#define LPASS_BE_PRI_TDM_TX_7 "PRI_TDM_TX_7" +#define LPASS_BE_SEC_TDM_RX_0 "SEC_TDM_RX_0" +#define LPASS_BE_SEC_TDM_TX_0 "SEC_TDM_TX_0" +#define LPASS_BE_SEC_TDM_RX_1 "SEC_TDM_RX_1" +#define LPASS_BE_SEC_TDM_TX_1 "SEC_TDM_TX_1" +#define LPASS_BE_SEC_TDM_RX_2 "SEC_TDM_RX_2" +#define LPASS_BE_SEC_TDM_TX_2 "SEC_TDM_TX_2" +#define LPASS_BE_SEC_TDM_RX_3 "SEC_TDM_RX_3" +#define LPASS_BE_SEC_TDM_TX_3 "SEC_TDM_TX_3" +#define LPASS_BE_SEC_TDM_RX_4 "SEC_TDM_RX_4" +#define LPASS_BE_SEC_TDM_TX_4 "SEC_TDM_TX_4" +#define LPASS_BE_SEC_TDM_RX_5 "SEC_TDM_RX_5" +#define LPASS_BE_SEC_TDM_TX_5 "SEC_TDM_TX_5" +#define LPASS_BE_SEC_TDM_RX_6 "SEC_TDM_RX_6" +#define LPASS_BE_SEC_TDM_TX_6 "SEC_TDM_TX_6" +#define LPASS_BE_SEC_TDM_RX_7 "SEC_TDM_RX_7" +#define LPASS_BE_SEC_TDM_TX_7 "SEC_TDM_TX_7" +#define LPASS_BE_TERT_TDM_RX_0 "TERT_TDM_RX_0" +#define LPASS_BE_TERT_TDM_TX_0 "TERT_TDM_TX_0" +#define LPASS_BE_TERT_TDM_RX_1 "TERT_TDM_RX_1" +#define LPASS_BE_TERT_TDM_TX_1 "TERT_TDM_TX_1" +#define LPASS_BE_TERT_TDM_RX_2 "TERT_TDM_RX_2" +#define LPASS_BE_TERT_TDM_TX_2 "TERT_TDM_TX_2" +#define LPASS_BE_TERT_TDM_RX_3 "TERT_TDM_RX_3" +#define LPASS_BE_TERT_TDM_TX_3 "TERT_TDM_TX_3" +#define LPASS_BE_TERT_TDM_RX_4 "TERT_TDM_RX_4" +#define LPASS_BE_TERT_TDM_TX_4 "TERT_TDM_TX_4" +#define LPASS_BE_TERT_TDM_RX_5 "TERT_TDM_RX_5" +#define LPASS_BE_TERT_TDM_TX_5 "TERT_TDM_TX_5" +#define LPASS_BE_TERT_TDM_RX_6 "TERT_TDM_RX_6" +#define LPASS_BE_TERT_TDM_TX_6 "TERT_TDM_TX_6" +#define LPASS_BE_TERT_TDM_RX_7 "TERT_TDM_RX_7" +#define LPASS_BE_TERT_TDM_TX_7 "TERT_TDM_TX_7" +#define LPASS_BE_QUAT_TDM_RX_0 "QUAT_TDM_RX_0" +#define LPASS_BE_QUAT_TDM_TX_0 "QUAT_TDM_TX_0" +#define LPASS_BE_QUAT_TDM_RX_1 "QUAT_TDM_RX_1" +#define LPASS_BE_QUAT_TDM_TX_1 "QUAT_TDM_TX_1" +#define LPASS_BE_QUAT_TDM_RX_2 "QUAT_TDM_RX_2" +#define LPASS_BE_QUAT_TDM_TX_2 "QUAT_TDM_TX_2" +#define LPASS_BE_QUAT_TDM_RX_3 "QUAT_TDM_RX_3" +#define LPASS_BE_QUAT_TDM_TX_3 "QUAT_TDM_TX_3" +#define LPASS_BE_QUAT_TDM_RX_4 "QUAT_TDM_RX_4" +#define LPASS_BE_QUAT_TDM_TX_4 "QUAT_TDM_TX_4" +#define LPASS_BE_QUAT_TDM_RX_5 "QUAT_TDM_RX_5" +#define LPASS_BE_QUAT_TDM_TX_5 "QUAT_TDM_TX_5" +#define LPASS_BE_QUAT_TDM_RX_6 "QUAT_TDM_RX_6" +#define LPASS_BE_QUAT_TDM_TX_6 "QUAT_TDM_TX_6" +#define LPASS_BE_QUAT_TDM_RX_7 "QUAT_TDM_RX_7" +#define LPASS_BE_QUAT_TDM_TX_7 "QUAT_TDM_TX_7" + +#define LPASS_BE_SLIMBUS_7_RX "SLIMBUS_7_RX" +#define LPASS_BE_SLIMBUS_7_TX "SLIMBUS_7_TX" +#define LPASS_BE_SLIMBUS_8_RX "SLIMBUS_8_RX" +#define LPASS_BE_SLIMBUS_8_TX "SLIMBUS_8_TX" + +#define LPASS_BE_USB_AUDIO_RX "USB_AUDIO_RX" +#define LPASS_BE_USB_AUDIO_TX "USB_AUDIO_TX" + +#define LPASS_BE_INT0_MI2S_RX "INT0_MI2S_RX" +#define LPASS_BE_INT0_MI2S_TX "INT0_MI2S_TX" +#define LPASS_BE_INT1_MI2S_RX "INT1_MI2S_RX" +#define LPASS_BE_INT1_MI2S_TX "INT1_MI2S_TX" +#define LPASS_BE_INT2_MI2S_RX "INT2_MI2S_RX" +#define LPASS_BE_INT2_MI2S_TX "INT2_MI2S_TX" +#define LPASS_BE_INT3_MI2S_RX "INT3_MI2S_RX" +#define LPASS_BE_INT3_MI2S_TX "INT3_MI2S_TX" +#define LPASS_BE_INT4_MI2S_RX "INT4_MI2S_RX" +#define LPASS_BE_INT4_MI2S_TX "INT4_MI2S_TX" +#define LPASS_BE_INT5_MI2S_RX "INT5_MI2S_RX" +#define LPASS_BE_INT5_MI2S_TX "INT5_MI2S_TX" +#define LPASS_BE_INT6_MI2S_RX "INT6_MI2S_RX" +#define LPASS_BE_INT6_MI2S_TX "INT6_MI2S_TX" +/* For multimedia front-ends, asm session is allocated dynamically. + * Hence, asm session/multimedia front-end mapping has to be maintained. + * Due to this reason, additional multimedia front-end must be placed before + * non-multimedia front-ends. + */ + +enum { + MSM_FRONTEND_DAI_MULTIMEDIA1 = 0, + MSM_FRONTEND_DAI_MULTIMEDIA2, + MSM_FRONTEND_DAI_MULTIMEDIA3, + MSM_FRONTEND_DAI_MULTIMEDIA4, + MSM_FRONTEND_DAI_MULTIMEDIA5, + MSM_FRONTEND_DAI_MULTIMEDIA6, + MSM_FRONTEND_DAI_MULTIMEDIA7, + MSM_FRONTEND_DAI_MULTIMEDIA8, + MSM_FRONTEND_DAI_MULTIMEDIA9, + MSM_FRONTEND_DAI_MULTIMEDIA10, + MSM_FRONTEND_DAI_MULTIMEDIA11, + MSM_FRONTEND_DAI_MULTIMEDIA12, + MSM_FRONTEND_DAI_MULTIMEDIA13, + MSM_FRONTEND_DAI_MULTIMEDIA14, + MSM_FRONTEND_DAI_MULTIMEDIA15, + MSM_FRONTEND_DAI_MULTIMEDIA16, + MSM_FRONTEND_DAI_MULTIMEDIA17, + MSM_FRONTEND_DAI_MULTIMEDIA18, + MSM_FRONTEND_DAI_MULTIMEDIA19, + MSM_FRONTEND_DAI_MULTIMEDIA20, + MSM_FRONTEND_DAI_CS_VOICE, + MSM_FRONTEND_DAI_VOIP, + MSM_FRONTEND_DAI_AFE_RX, + MSM_FRONTEND_DAI_AFE_TX, + MSM_FRONTEND_DAI_VOICE_STUB, + MSM_FRONTEND_DAI_VOLTE, + MSM_FRONTEND_DAI_DTMF_RX, + MSM_FRONTEND_DAI_VOICE2, + MSM_FRONTEND_DAI_QCHAT, + MSM_FRONTEND_DAI_VOLTE_STUB, + MSM_FRONTEND_DAI_LSM1, + MSM_FRONTEND_DAI_LSM2, + MSM_FRONTEND_DAI_LSM3, + MSM_FRONTEND_DAI_LSM4, + MSM_FRONTEND_DAI_LSM5, + MSM_FRONTEND_DAI_LSM6, + MSM_FRONTEND_DAI_LSM7, + MSM_FRONTEND_DAI_LSM8, + MSM_FRONTEND_DAI_VOICE2_STUB, + MSM_FRONTEND_DAI_VOWLAN, + MSM_FRONTEND_DAI_VOICEMMODE1, + MSM_FRONTEND_DAI_VOICEMMODE2, + MSM_FRONTEND_DAI_MAX, +}; + +#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA20 + 1) +#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA20 + +enum { + MSM_BACKEND_DAI_PRI_I2S_RX = 0, + MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_BACKEND_DAI_HDMI_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_BACKEND_DAI_MI2S_RX, + MSM_BACKEND_DAI_MI2S_TX, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_BACKEND_DAI_SLIMBUS_2_TX, + MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_BACKEND_DAI_SLIMBUS_4_RX, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_BACKEND_DAI_EXTPROC_RX, + MSM_BACKEND_DAI_EXTPROC_TX, + MSM_BACKEND_DAI_EXTPROC_EC_TX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_BACKEND_DAI_AUDIO_I2S_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX_SD1, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_BACKEND_DAI_PRI_TDM_RX_4, + MSM_BACKEND_DAI_PRI_TDM_TX_4, + MSM_BACKEND_DAI_PRI_TDM_RX_5, + MSM_BACKEND_DAI_PRI_TDM_TX_5, + MSM_BACKEND_DAI_PRI_TDM_RX_6, + MSM_BACKEND_DAI_PRI_TDM_TX_6, + MSM_BACKEND_DAI_PRI_TDM_RX_7, + MSM_BACKEND_DAI_PRI_TDM_TX_7, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_4, + MSM_BACKEND_DAI_SEC_TDM_TX_4, + MSM_BACKEND_DAI_SEC_TDM_RX_5, + MSM_BACKEND_DAI_SEC_TDM_TX_5, + MSM_BACKEND_DAI_SEC_TDM_RX_6, + MSM_BACKEND_DAI_SEC_TDM_TX_6, + MSM_BACKEND_DAI_SEC_TDM_RX_7, + MSM_BACKEND_DAI_SEC_TDM_TX_7, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_4, + MSM_BACKEND_DAI_TERT_TDM_RX_5, + MSM_BACKEND_DAI_TERT_TDM_TX_5, + MSM_BACKEND_DAI_TERT_TDM_RX_6, + MSM_BACKEND_DAI_TERT_TDM_TX_6, + MSM_BACKEND_DAI_TERT_TDM_RX_7, + MSM_BACKEND_DAI_TERT_TDM_TX_7, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_4, + MSM_BACKEND_DAI_QUAT_TDM_TX_4, + MSM_BACKEND_DAI_QUAT_TDM_RX_5, + MSM_BACKEND_DAI_QUAT_TDM_TX_5, + MSM_BACKEND_DAI_QUAT_TDM_RX_6, + MSM_BACKEND_DAI_QUAT_TDM_TX_6, + MSM_BACKEND_DAI_QUAT_TDM_RX_7, + MSM_BACKEND_DAI_QUAT_TDM_TX_7, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_USB_TX, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_INT0_MI2S_TX, + MSM_BACKEND_DAI_INT1_MI2S_RX, + MSM_BACKEND_DAI_INT1_MI2S_TX, + MSM_BACKEND_DAI_INT2_MI2S_RX, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_BACKEND_DAI_INT3_MI2S_RX, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_INT4_MI2S_TX, + MSM_BACKEND_DAI_INT5_MI2S_RX, + MSM_BACKEND_DAI_INT5_MI2S_TX, + MSM_BACKEND_DAI_INT6_MI2S_RX, + MSM_BACKEND_DAI_INT6_MI2S_TX, + MSM_BACKEND_DAI_MAX, +}; + +enum msm_pcm_routing_event { + MSM_PCM_RT_EVT_BUF_RECFG, + MSM_PCM_RT_EVT_DEVSWITCH, + MSM_PCM_RT_EVT_MAX, +}; + +enum { + EXT_EC_REF_NONE = 0, + EXT_EC_REF_PRI_MI2S_TX, + EXT_EC_REF_SEC_MI2S_TX, + EXT_EC_REF_TERT_MI2S_TX, + EXT_EC_REF_QUAT_MI2S_TX, + EXT_EC_REF_QUIN_MI2S_TX, + EXT_EC_REF_SLIM_1_TX, +}; + +#define INVALID_SESSION -1 +#define SESSION_TYPE_RX 0 +#define SESSION_TYPE_TX 1 +#define MAX_SESSION_TYPES 2 +#define INT_RX_VOL_MAX_STEPS 0x2000 +#define INT_RX_VOL_GAIN 0x2000 + +#define RELEASE_LOCK 0 +#define ACQUIRE_LOCK 1 + +#define MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX 2 +#define HDMI_RX_ID 0x8001 +#define ADM_PP_PARAM_MUTE_ID 0 +#define ADM_PP_PARAM_MUTE_BIT 1 +#define ADM_PP_PARAM_LATENCY_ID 1 +#define ADM_PP_PARAM_LATENCY_BIT 2 +#define BE_DAI_PORT_SESSIONS_IDX_MAX 4 +#define BE_DAI_FE_SESSIONS_IDX_MAX 2 + +struct msm_pcm_routing_evt { + void (*event_func)(enum msm_pcm_routing_event, void *); + void *priv_data; +}; + +struct msm_pcm_routing_bdai_data { + u16 port_id; /* AFE port ID */ + u8 active; /* track if this backend is enabled */ + + /* Front-end sessions */ + unsigned long fe_sessions[BE_DAI_FE_SESSIONS_IDX_MAX]; + /* + * Track Tx BE ports -> Rx BE ports. + * port_sessions[0] used to track BE 0 to BE 63. + * port_sessions[1] used to track BE 64 to BE 127. + * port_sessions[2] used to track BE 128 to BE 191. + * port_sessions[3] used to track BE 192 to BE 255. + */ + u64 port_sessions[BE_DAI_PORT_SESSIONS_IDX_MAX]; + + unsigned int sample_rate; + unsigned int channel; + unsigned int format; + unsigned int adm_override_ch; + u32 passthr_mode[MSM_FRONTEND_DAI_MAX]; + char *name; +}; + +struct msm_pcm_routing_fdai_data { + u16 be_srate; /* track prior backend sample rate for flushing purpose */ + int strm_id; /* ASM stream ID */ + int perf_mode; + struct msm_pcm_routing_evt event_info; +}; + +#define MAX_APP_TYPES 16 +struct msm_pcm_routing_app_type_data { + int app_type; + u32 sample_rate; + int bit_width; +}; + +struct msm_pcm_stream_app_type_cfg { + int app_type; + int acdb_dev_id; + int sample_rate; +}; + +/* dai_id: front-end ID, + * dspst_id: DSP audio stream ID + * stream_type: playback or capture + */ +int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, int dspst_id, + int stream_type); +void msm_pcm_routing_reg_psthr_stream(int fedai_id, int dspst_id, + int stream_type); +int msm_pcm_routing_reg_phy_compr_stream(int fedai_id, int perf_mode, + int dspst_id, int stream_type, + uint32_t compr_passthr); + +int msm_pcm_routing_reg_phy_stream_v2(int fedai_id, int perf_mode, + int dspst_id, int stream_type, + struct msm_pcm_routing_evt event_info); + +void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type); + +int msm_routing_check_backend_enabled(int fedai_id); + + +void msm_pcm_routing_get_bedai_info(int be_idx, + struct msm_pcm_routing_bdai_data *bedai); +void msm_pcm_routing_get_fedai_info(int fe_idx, int sess_type, + struct msm_pcm_routing_fdai_data *fe_dai); +void msm_pcm_routing_acquire_lock(void); +void msm_pcm_routing_release_lock(void); + +int msm_pcm_routing_reg_stream_app_type_cfg( + int fedai_id, int session_type, int be_id, + struct msm_pcm_stream_app_type_cfg *cfg_data); +int msm_pcm_routing_get_stream_app_type_cfg( + int fedai_id, int session_type, int *be_id, + struct msm_pcm_stream_app_type_cfg *cfg_data); +#endif /*_MSM_PCM_H*/ diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c new file mode 100644 index 000000000000..654806e9795e --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c @@ -0,0 +1,781 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "msm-pcm-voice-v2.h" +#include "q6voice.h" + +static struct msm_voice voice_info[VOICE_SESSION_INDEX_MAX]; + +static struct snd_pcm_hardware msm_pcm_hardware = { + + .info = (SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .rate_min = 8000, + .rate_max = 16000, + .channels_min = 1, + .channels_max = 1, + + .buffer_bytes_max = 4096 * 2, + .period_bytes_min = 2048, + .period_bytes_max = 4096, + .periods_min = 2, + .periods_max = 4, + + .fifo_size = 0, +}; +static bool is_volte(struct msm_voice *pvolte) +{ + if (pvolte == &voice_info[VOLTE_SESSION_INDEX]) + return true; + else + return false; +} + +static bool is_voice2(struct msm_voice *pvoice2) +{ + if (pvoice2 == &voice_info[VOICE2_SESSION_INDEX]) + return true; + else + return false; +} + +static bool is_qchat(struct msm_voice *pqchat) +{ + if (pqchat == &voice_info[QCHAT_SESSION_INDEX]) + return true; + else + return false; +} + +static bool is_vowlan(struct msm_voice *pvowlan) +{ + if (pvowlan == &voice_info[VOWLAN_SESSION_INDEX]) + return true; + else + return false; +} + +static bool is_voicemmode1(struct msm_voice *pvoicemmode1) +{ + if (pvoicemmode1 == &voice_info[VOICEMMODE1_INDEX]) + return true; + else + return false; +} + +static bool is_voicemmode2(struct msm_voice *pvoicemmode2) +{ + if (pvoicemmode2 == &voice_info[VOICEMMODE2_INDEX]) + return true; + else + return false; +} + +static uint32_t get_session_id(struct msm_voice *pvoc) +{ + uint32_t session_id = 0; + + if (is_volte(pvoc)) + session_id = voc_get_session_id(VOLTE_SESSION_NAME); + else if (is_voice2(pvoc)) + session_id = voc_get_session_id(VOICE2_SESSION_NAME); + else if (is_qchat(pvoc)) + session_id = voc_get_session_id(QCHAT_SESSION_NAME); + else if (is_vowlan(pvoc)) + session_id = voc_get_session_id(VOWLAN_SESSION_NAME); + else if (is_voicemmode1(pvoc)) + session_id = voc_get_session_id(VOICEMMODE1_NAME); + else if (is_voicemmode2(pvoc)) + session_id = voc_get_session_id(VOICEMMODE2_NAME); + else + session_id = voc_get_session_id(VOICE_SESSION_NAME); + + return session_id; +} + + +static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_voice *prtd = runtime->private_data; + + pr_debug("%s\n", __func__); + + if (!prtd->playback_start) + prtd->playback_start = 1; + + return 0; +} + +static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_voice *prtd = runtime->private_data; + + pr_debug("%s\n", __func__); + + if (!prtd->capture_start) + prtd->capture_start = 1; + + return 0; +} +static int msm_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_voice *voice; + + if (!strncmp("VoLTE", substream->pcm->id, 5)) { + voice = &voice_info[VOLTE_SESSION_INDEX]; + pr_debug("%s: Open VoLTE Substream Id=%s\n", + __func__, substream->pcm->id); + } else if (!strncmp("Voice2", substream->pcm->id, 6)) { + voice = &voice_info[VOICE2_SESSION_INDEX]; + pr_debug("%s: Open Voice2 Substream Id=%s\n", + __func__, substream->pcm->id); + } else if (!strncmp("QCHAT", substream->pcm->id, 5)) { + voice = &voice_info[QCHAT_SESSION_INDEX]; + pr_debug("%s: Open QCHAT Substream Id=%s\n", + __func__, substream->pcm->id); + } else if (!strncmp("VoWLAN", substream->pcm->id, 6)) { + voice = &voice_info[VOWLAN_SESSION_INDEX]; + pr_debug("%s: Open VoWLAN Substream Id=%s\n", + __func__, substream->pcm->id); + } else if (!strncmp("VoiceMMode1", substream->pcm->id, 11)) { + voice = &voice_info[VOICEMMODE1_INDEX]; + pr_debug("%s: Open VoiceMMode1 Substream Id=%s\n", + __func__, substream->pcm->id); + } else if (!strncmp("VoiceMMode2", substream->pcm->id, 11)) { + voice = &voice_info[VOICEMMODE2_INDEX]; + pr_debug("%s: Open VoiceMMode2 Substream Id=%s\n", + __func__, substream->pcm->id); + } else { + voice = &voice_info[VOICE_SESSION_INDEX]; + pr_debug("%s: Open VOICE Substream Id=%s\n", + __func__, substream->pcm->id); + } + mutex_lock(&voice->lock); + + runtime->hw = msm_pcm_hardware; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + voice->playback_substream = substream; + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + voice->capture_substream = substream; + + voice->instance++; + pr_debug("%s: Instance = %d, Stream ID = %s\n", + __func__, voice->instance, substream->pcm->id); + runtime->private_data = voice; + + mutex_unlock(&voice->lock); + + return 0; +} +static int msm_pcm_playback_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_voice *prtd = runtime->private_data; + + pr_debug("%s\n", __func__); + + if (prtd->playback_start) + prtd->playback_start = 0; + + prtd->playback_substream = NULL; + + return 0; +} +static int msm_pcm_capture_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_voice *prtd = runtime->private_data; + + pr_debug("%s\n", __func__); + + if (prtd->capture_start) + prtd->capture_start = 0; + prtd->capture_substream = NULL; + + return 0; +} +static int msm_pcm_close(struct snd_pcm_substream *substream) +{ + + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_voice *prtd = runtime->private_data; + uint32_t session_id = 0; + int ret = 0; + + mutex_lock(&prtd->lock); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ret = msm_pcm_playback_close(substream); + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ret = msm_pcm_capture_close(substream); + + prtd->instance--; + if (!prtd->playback_start && !prtd->capture_start) { + pr_debug("end voice call\n"); + + session_id = get_session_id(prtd); + if (session_id) + voc_end_voice_call(session_id); + } + mutex_unlock(&prtd->lock); + + return ret; +} +static int msm_pcm_prepare(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_voice *prtd = runtime->private_data; + uint32_t session_id = 0; + + mutex_lock(&prtd->lock); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ret = msm_pcm_playback_prepare(substream); + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ret = msm_pcm_capture_prepare(substream); + + if (prtd->playback_start && prtd->capture_start) { + session_id = get_session_id(prtd); + if (session_id) + voc_start_voice_call(session_id); + } + mutex_unlock(&prtd->lock); + + return ret; +} + +static int msm_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + + pr_debug("%s: Voice\n", __func__); + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + + return 0; +} + +static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + int ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_voice *prtd = runtime->private_data; + uint32_t session_id = 0; + + pr_debug("%s: cmd = %d\n", __func__, cmd); + + session_id = get_session_id(prtd); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_STOP: + pr_debug("Start & Stop Voice call not handled in Trigger.\n"); + break; + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + pr_debug("%s: resume call session_id = %d\n", __func__, + session_id); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ret = msm_pcm_playback_prepare(substream); + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ret = msm_pcm_capture_prepare(substream); + if (prtd->playback_start && prtd->capture_start) { + if (session_id) + voc_resume_voice_call(session_id); + } + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + pr_debug("%s: pause call session_id=%d\n", + __func__, session_id); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + if (prtd->playback_start) + prtd->playback_start = 0; + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (prtd->capture_start) + prtd->capture_start = 0; + } + if (session_id) + voc_standby_voice_call(session_id); + break; + default: + ret = -EINVAL; + break; + } + return ret; +} + +static int msm_pcm_ioctl(struct snd_pcm_substream *substream, + unsigned int cmd, void *arg) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct msm_voice *prtd = runtime->private_data; + uint32_t session_id = get_session_id(prtd); + enum voice_lch_mode lch_mode; + int ret = 0; + + switch (cmd) { + case SNDRV_VOICE_IOCTL_LCH: + if (copy_from_user(&lch_mode, (void *)arg, + sizeof(enum voice_lch_mode))) { + pr_err("%s: Copy from user failed, size %zd\n", + __func__, sizeof(enum voice_lch_mode)); + + ret = -EFAULT; + break; + } + + pr_debug("%s: %s lch_mode:%d\n", + __func__, substream->pcm->id, lch_mode); + + switch (lch_mode) { + case VOICE_LCH_START: + case VOICE_LCH_STOP: + ret = voc_set_lch(session_id, lch_mode); + break; + + default: + pr_err("%s: Invalid LCH MODE %d\n", __func__, lch_mode); + + ret = -EFAULT; + } + + break; + default: + pr_debug("%s: Falling into default snd_lib_ioctl cmd 0x%x\n", + __func__, cmd); + + ret = snd_pcm_lib_ioctl(substream, cmd, arg); + break; + } + + if (!ret) + pr_debug("%s: ret %d\n", __func__, ret); + else + pr_err("%s: cmd 0x%x failed %d\n", __func__, cmd, ret); + + return ret; +} + +static int msm_voice_sidetone_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret; + long value = ucontrol->value.integer.value[0]; + bool sidetone_enable = value; + uint32_t session_id = ALL_SESSION_VSID; + + if (value < 0) { + pr_err("%s: Invalid arguments sidetone enable %ld\n", + __func__, value); + ret = -EINVAL; + return ret; + } + ret = voc_set_afe_sidetone(session_id, sidetone_enable); + pr_debug("%s: AFE Sidetone enable=%d session_id=0x%x ret=%d\n", + __func__, sidetone_enable, session_id, ret); + return ret; +} + +static int msm_voice_sidetone_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = voc_get_afe_sidetone(); + return 0; +} + +static int msm_voice_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int volume = ucontrol->value.integer.value[0]; + uint32_t session_id = ucontrol->value.integer.value[1]; + int ramp_duration = ucontrol->value.integer.value[2]; + + if ((volume < 0) || (ramp_duration < 0) + || (ramp_duration > MAX_RAMP_DURATION)) { + pr_err(" %s Invalid arguments", __func__); + + ret = -EINVAL; + goto done; + } + + pr_debug("%s: volume: %d session_id: %#x ramp_duration: %d\n", __func__, + volume, session_id, ramp_duration); + + voc_set_rx_vol_step(session_id, RX_PATH, volume, ramp_duration); + +done: + return ret; +} + +static int msm_voice_mute_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int mute = ucontrol->value.integer.value[0]; + uint32_t session_id = ucontrol->value.integer.value[1]; + int ramp_duration = ucontrol->value.integer.value[2]; + + if ((mute < 0) || (mute > 1) || (ramp_duration < 0) + || (ramp_duration > MAX_RAMP_DURATION)) { + pr_err(" %s Invalid arguments", __func__); + + ret = -EINVAL; + goto done; + } + + pr_debug("%s: mute=%d session_id=%#x ramp_duration=%d\n", __func__, + mute, session_id, ramp_duration); + + ret = voc_set_tx_mute(session_id, TX_PATH, mute, ramp_duration); + +done: + return ret; +} + +static int msm_voice_tx_device_mute_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int mute = ucontrol->value.integer.value[0]; + uint32_t session_id = ucontrol->value.integer.value[1]; + int ramp_duration = ucontrol->value.integer.value[2]; + + if ((mute < 0) || (mute > 1) || (ramp_duration < 0) || + (ramp_duration > MAX_RAMP_DURATION)) { + pr_err(" %s Invalid arguments", __func__); + + ret = -EINVAL; + goto done; + } + + pr_debug("%s: mute=%d session_id=%#x ramp_duration=%d\n", __func__, + mute, session_id, ramp_duration); + + ret = voc_set_device_mute(session_id, VSS_IVOLUME_DIRECTION_TX, + mute, ramp_duration); + +done: + return ret; +} + +static int msm_voice_rx_device_mute_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int mute = ucontrol->value.integer.value[0]; + uint32_t session_id = ucontrol->value.integer.value[1]; + int ramp_duration = ucontrol->value.integer.value[2]; + + if ((mute < 0) || (mute > 1) || (ramp_duration < 0) || + (ramp_duration > MAX_RAMP_DURATION)) { + pr_err(" %s Invalid arguments", __func__); + + ret = -EINVAL; + goto done; + } + + pr_debug("%s: mute=%d session_id=%#x ramp_duration=%d\n", __func__, + mute, session_id, ramp_duration); + + voc_set_device_mute(session_id, VSS_IVOLUME_DIRECTION_RX, + mute, ramp_duration); + +done: + return ret; +} + + + +static const char * const tty_mode[] = {"OFF", "HCO", "VCO", "FULL"}; +static const struct soc_enum msm_tty_mode_enum[] = { + SOC_ENUM_SINGLE_EXT(4, tty_mode), +}; + +static int msm_voice_tty_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = + voc_get_tty_mode(voc_get_session_id(VOICE_SESSION_NAME)); + return 0; +} + +static int msm_voice_tty_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int tty_mode = ucontrol->value.integer.value[0]; + + pr_debug("%s: tty_mode=%d\n", __func__, tty_mode); + + voc_set_tty_mode(voc_get_session_id(VOICE_SESSION_NAME), tty_mode); + voc_set_tty_mode(voc_get_session_id(VOICE2_SESSION_NAME), tty_mode); + voc_set_tty_mode(voc_get_session_id(VOLTE_SESSION_NAME), tty_mode); + voc_set_tty_mode(voc_get_session_id(VOWLAN_SESSION_NAME), tty_mode); + voc_set_tty_mode(voc_get_session_id(VOICEMMODE1_NAME), tty_mode); + voc_set_tty_mode(voc_get_session_id(VOICEMMODE2_NAME), tty_mode); + + return 0; +} + +static int msm_voice_slowtalk_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int st_enable = ucontrol->value.integer.value[0]; + uint32_t session_id = ucontrol->value.integer.value[1]; + + pr_debug("%s: st enable=%d session_id=%#x\n", __func__, st_enable, + session_id); + + voc_set_pp_enable(session_id, + MODULE_ID_VOICE_MODULE_ST, st_enable); + + return 0; +} + +static int msm_voice_hd_voice_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + uint32_t hd_enable = ucontrol->value.integer.value[0]; + uint32_t session_id = ucontrol->value.integer.value[1]; + + pr_debug("%s: HD Voice enable=%d session_id=%#x\n", __func__, hd_enable, + session_id); + + ret = voc_set_hd_enable(session_id, hd_enable); + + return ret; +} + +static int msm_voice_topology_disable_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int disable = ucontrol->value.integer.value[0]; + uint32_t session_id = ucontrol->value.integer.value[1]; + + if ((disable < 0) || (disable > 1)) { + pr_err(" %s Invalid arguments: %d\n", __func__, disable); + + ret = -EINVAL; + goto done; + } + pr_debug("%s: disable = %d, session_id = %d\n", __func__, disable, + session_id); + + ret = voc_disable_topology(session_id, disable); + +done: + return ret; +} + +static int msm_voice_cvd_version_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + int ret = 0; + + pr_debug("%s:\n", __func__); + + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = CVD_VERSION_STRING_MAX_SIZE; + + return ret; +} + +static int msm_voice_cvd_version_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + char cvd_version[CVD_VERSION_STRING_MAX_SIZE] = CVD_VERSION_DEFAULT; + int ret; + + pr_debug("%s:\n", __func__); + + ret = voc_get_cvd_version(cvd_version); + + if (ret) + pr_err("%s: Error retrieving CVD version, error:%d\n", + __func__, ret); + + memcpy(ucontrol->value.bytes.data, cvd_version, sizeof(cvd_version)); + + return 0; +} +static struct snd_kcontrol_new msm_voice_controls[] = { + SOC_SINGLE_MULTI_EXT("Voice Rx Device Mute", SND_SOC_NOPM, 0, VSID_MAX, + 0, 3, NULL, msm_voice_rx_device_mute_put), + SOC_SINGLE_MULTI_EXT("Voice Tx Device Mute", SND_SOC_NOPM, 0, VSID_MAX, + 0, 3, NULL, msm_voice_tx_device_mute_put), + SOC_SINGLE_MULTI_EXT("Voice Tx Mute", SND_SOC_NOPM, 0, VSID_MAX, + 0, 3, NULL, msm_voice_mute_put), + SOC_SINGLE_MULTI_EXT("Voice Rx Gain", SND_SOC_NOPM, 0, VSID_MAX, 0, 3, + NULL, msm_voice_gain_put), + SOC_ENUM_EXT("TTY Mode", msm_tty_mode_enum[0], msm_voice_tty_mode_get, + msm_voice_tty_mode_put), + SOC_SINGLE_MULTI_EXT("Slowtalk Enable", SND_SOC_NOPM, 0, VSID_MAX, 0, 2, + NULL, msm_voice_slowtalk_put), + SOC_SINGLE_MULTI_EXT("Voice Topology Disable", SND_SOC_NOPM, 0, + VSID_MAX, 0, 2, NULL, + msm_voice_topology_disable_put), + SOC_SINGLE_MULTI_EXT("HD Voice Enable", SND_SOC_NOPM, 0, VSID_MAX, 0, 2, + NULL, msm_voice_hd_voice_put), + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "CVD Version", + .info = msm_voice_cvd_version_info, + .get = msm_voice_cvd_version_get, + }, + SOC_SINGLE_MULTI_EXT("Voice Sidetone Enable", SND_SOC_NOPM, 0, 1, 0, 1, + msm_voice_sidetone_get, msm_voice_sidetone_put), +}; + +static const struct snd_pcm_ops msm_pcm_ops = { + .open = msm_pcm_open, + .hw_params = msm_pcm_hw_params, + .close = msm_pcm_close, + .prepare = msm_pcm_prepare, + .trigger = msm_pcm_trigger, + .ioctl = msm_pcm_ioctl, + .compat_ioctl = msm_pcm_ioctl, +}; + + +static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_card *card = rtd->card->snd_card; + int ret = 0; + + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); + return ret; +} + +static int msm_pcm_voice_probe(struct snd_soc_platform *platform) +{ + snd_soc_add_platform_controls(platform, msm_voice_controls, + ARRAY_SIZE(msm_voice_controls)); + + return 0; +} + +static struct snd_soc_platform_driver msm_soc_platform = { + .ops = &msm_pcm_ops, + .pcm_new = msm_asoc_pcm_new, + .probe = msm_pcm_voice_probe, +}; + +static int msm_pcm_probe(struct platform_device *pdev) +{ + int rc; + bool destroy_cvd = false; + const char *is_destroy_cvd = "qcom,destroy-cvd"; + + if (!is_voc_initialized()) { + pr_debug("%s: voice module not initialized yet, deferring probe()\n", + __func__); + + rc = -EPROBE_DEFER; + goto done; + } + + rc = voc_alloc_cal_shared_memory(); + if (rc == -EPROBE_DEFER) { + pr_debug("%s: memory allocation for calibration deferred %d\n", + __func__, rc); + + goto done; + } else if (rc < 0) { + pr_err("%s: memory allocation for calibration failed %d\n", + __func__, rc); + } + + pr_debug("%s: dev name %s\n", + __func__, dev_name(&pdev->dev)); + destroy_cvd = of_property_read_bool(pdev->dev.of_node, + is_destroy_cvd); + voc_set_destroy_cvd_flag(destroy_cvd); + + rc = snd_soc_register_platform(&pdev->dev, + &msm_soc_platform); + +done: + return rc; +} + +static int msm_pcm_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_voice_dt_match[] = { + {.compatible = "qcom,msm-pcm-voice"}, + {} +}; +MODULE_DEVICE_TABLE(of, msm_voice_dt_match); + +static struct platform_driver msm_pcm_driver = { + .driver = { + .name = "msm-pcm-voice", + .owner = THIS_MODULE, + .of_match_table = msm_voice_dt_match, + }, + .probe = msm_pcm_probe, + .remove = msm_pcm_remove, +}; + +static int __init msm_soc_platform_init(void) +{ + int i = 0; + + memset(&voice_info, 0, sizeof(voice_info)); + + for (i = 0; i < VOICE_SESSION_INDEX_MAX; i++) + mutex_init(&voice_info[i].lock); + + return platform_driver_register(&msm_pcm_driver); +} +module_init(msm_soc_platform_init); + +static void __exit msm_soc_platform_exit(void) +{ + platform_driver_unregister(&msm_pcm_driver); +} +module_exit(msm_soc_platform_exit); + +MODULE_DESCRIPTION("Voice PCM module platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.h new file mode 100644 index 000000000000..e00cebc51e7e --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.h @@ -0,0 +1,42 @@ +/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef _MSM_PCM_VOICE_H +#define _MSM_PCM_VOICE_H +#include + +enum { + VOICE_SESSION_INDEX, + VOLTE_SESSION_INDEX, + VOICE2_SESSION_INDEX, + QCHAT_SESSION_INDEX, + VOWLAN_SESSION_INDEX, + VOICEMMODE1_INDEX, + VOICEMMODE2_INDEX, + VOICE_SESSION_INDEX_MAX, +}; + +struct msm_voice { + struct snd_pcm_substream *playback_substream; + struct snd_pcm_substream *capture_substream; + + int instance; + + struct mutex lock; + + uint32_t samp_rate; + uint32_t channel_mode; + + int playback_start; + int capture_start; +}; + +#endif /*_MSM_PCM_VOICE_H*/ diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c new file mode 100644 index 000000000000..02225f0dcef4 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c @@ -0,0 +1,1715 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "msm-pcm-q6-v2.h" +#include "msm-pcm-routing-v2.h" +#include "q6voice.h" + +#define SHARED_MEM_BUF 2 +#define VOIP_MAX_Q_LEN 10 +#define VOIP_MAX_VOC_PKT_SIZE 4096 +#define VOIP_MIN_VOC_PKT_SIZE 320 + +/* Length of the DSP frame info header added to the voc packet. */ +#define DSP_FRAME_HDR_LEN 1 + +#define MODE_IS127 0x2 +#define MODE_4GV_NB 0x3 +#define MODE_4GV_WB 0x4 +#define MODE_AMR 0x5 +#define MODE_AMR_WB 0xD +#define MODE_PCM 0xC +#define MODE_4GV_NW 0xE +#define MODE_G711 0xA +#define MODE_G711A 0xF + +enum msm_audio_g711a_frame_type { + MVS_G711A_SPEECH_GOOD, + MVS_G711A_SID, + MVS_G711A_NO_DATA, + MVS_G711A_ERASURE +}; + +enum msm_audio_g711a_mode { + MVS_G711A_MODE_MULAW, + MVS_G711A_MODE_ALAW +}; + +enum msm_audio_g711_mode { + MVS_G711_MODE_MULAW, + MVS_G711_MODE_ALAW +}; + +#define VOIP_MODE_MAX MODE_G711A +#define VOIP_RATE_MAX 23850 + +enum format { + FORMAT_S16_LE = 2, + FORMAT_SPECIAL = 31, +}; + + +enum amr_rate_type { + AMR_RATE_4750, /* AMR 4.75 kbps */ + AMR_RATE_5150, /* AMR 5.15 kbps */ + AMR_RATE_5900, /* AMR 5.90 kbps */ + AMR_RATE_6700, /* AMR 6.70 kbps */ + AMR_RATE_7400, /* AMR 7.40 kbps */ + AMR_RATE_7950, /* AMR 7.95 kbps */ + AMR_RATE_10200, /* AMR 10.20 kbps */ + AMR_RATE_12200, /* AMR 12.20 kbps */ + AMR_RATE_6600, /* AMR-WB 6.60 kbps */ + AMR_RATE_8850, /* AMR-WB 8.85 kbps */ + AMR_RATE_12650, /* AMR-WB 12.65 kbps */ + AMR_RATE_14250, /* AMR-WB 14.25 kbps */ + AMR_RATE_15850, /* AMR-WB 15.85 kbps */ + AMR_RATE_18250, /* AMR-WB 18.25 kbps */ + AMR_RATE_19850, /* AMR-WB 19.85 kbps */ + AMR_RATE_23050, /* AMR-WB 23.05 kbps */ + AMR_RATE_23850, /* AMR-WB 23.85 kbps */ + AMR_RATE_UNDEF +}; + +enum voip_state { + VOIP_STOPPED, + VOIP_STARTED, +}; + +struct voip_frame_hdr { + uint32_t timestamp; + union { + /* + * Bits 0-3: Frame type + * [optional] Bits 16-19: Frame rate + */ + uint32_t frame_type; + uint32_t packet_rate; + }; +}; +struct voip_frame { + struct voip_frame_hdr frm_hdr; + uint32_t pktlen; + uint8_t voc_pkt[VOIP_MAX_VOC_PKT_SIZE]; +}; + +struct voip_buf_node { + struct list_head list; + struct voip_frame frame; +}; + +struct voip_drv_info { + enum voip_state state; + + struct snd_pcm_substream *playback_substream; + struct snd_pcm_substream *capture_substream; + + struct list_head in_queue; + struct list_head free_in_queue; + + struct list_head out_queue; + struct list_head free_out_queue; + + wait_queue_head_t out_wait; + wait_queue_head_t in_wait; + + struct mutex lock; + + spinlock_t dsp_lock; + spinlock_t dsp_ul_lock; + + bool voip_reset; + uint32_t mode; + uint32_t rate_type; + uint32_t rate; + uint32_t dtx_mode; + + uint8_t capture_start; + uint8_t playback_start; + + uint8_t playback_prepare; + uint8_t capture_prepare; + + unsigned int play_samp_rate; + unsigned int cap_samp_rate; + + unsigned int pcm_size; + unsigned int pcm_count; + unsigned int pcm_playback_irq_pos; /* IRQ position */ + unsigned int pcm_playback_buf_pos; /* position in buffer */ + + unsigned int pcm_capture_size; + unsigned int pcm_capture_count; + unsigned int pcm_capture_irq_pos; /* IRQ position */ + unsigned int pcm_capture_buf_pos; /* position in buffer */ + + uint32_t evrc_min_rate; + uint32_t evrc_max_rate; +}; + +static int voip_get_media_type(uint32_t mode, uint32_t rate_type, + unsigned int samp_rate, + unsigned int *media_type); +static int voip_get_rate_type(uint32_t mode, + uint32_t rate, + uint32_t *rate_type); +static int voip_config_vocoder(struct snd_pcm_substream *substream); +static int msm_voip_mode_config_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int msm_voip_mode_config_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int msm_voip_rate_config_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int msm_voip_evrc_min_max_rate_config_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int msm_voip_evrc_min_max_rate_config_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + +static struct voip_drv_info voip_info; + +static struct snd_pcm_hardware msm_pcm_hardware = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED), + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_SPECIAL, + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000, + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 1, + .buffer_bytes_max = sizeof(struct voip_buf_node) * VOIP_MAX_Q_LEN, + .period_bytes_min = VOIP_MIN_VOC_PKT_SIZE, + .period_bytes_max = VOIP_MAX_VOC_PKT_SIZE, + .periods_min = VOIP_MAX_Q_LEN, + .periods_max = VOIP_MAX_Q_LEN, + .fifo_size = 0, +}; + + +static int msm_voip_mute_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int mute = ucontrol->value.integer.value[0]; + int ramp_duration = ucontrol->value.integer.value[1]; + + if ((mute < 0) || (mute > 1) || (ramp_duration < 0)) { + pr_err(" %s Invalid arguments", __func__); + + ret = -EINVAL; + goto done; + } + + pr_debug("%s: mute=%d ramp_duration=%d\n", __func__, mute, + ramp_duration); + + voc_set_tx_mute(voc_get_session_id(VOIP_SESSION_NAME), TX_PATH, mute, + ramp_duration); + +done: + return ret; +} + +static int msm_voip_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int volume = ucontrol->value.integer.value[0]; + int ramp_duration = ucontrol->value.integer.value[1]; + + if ((volume < 0) || (ramp_duration < 0)) { + pr_err(" %s Invalid arguments", __func__); + + ret = -EINVAL; + goto done; + } + + pr_debug("%s: volume: %d ramp_duration: %d\n", __func__, volume, + ramp_duration); + + voc_set_rx_vol_step(voc_get_session_id(VOIP_SESSION_NAME), + RX_PATH, + volume, + ramp_duration); + +done: + return ret; +} + +static int msm_voip_dtx_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + mutex_lock(&voip_info.lock); + + voip_info.dtx_mode = ucontrol->value.integer.value[0]; + + pr_debug("%s: dtx: %d\n", __func__, voip_info.dtx_mode); + + mutex_unlock(&voip_info.lock); + + return 0; +} +static int msm_voip_dtx_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + mutex_lock(&voip_info.lock); + + ucontrol->value.integer.value[0] = voip_info.dtx_mode; + + mutex_unlock(&voip_info.lock); + + return 0; +} + +static struct snd_kcontrol_new msm_voip_controls[] = { + SOC_SINGLE_MULTI_EXT("Voip Tx Mute", SND_SOC_NOPM, 0, + MAX_RAMP_DURATION, + 0, 2, NULL, msm_voip_mute_put), + SOC_SINGLE_MULTI_EXT("Voip Rx Gain", SND_SOC_NOPM, 0, + MAX_RAMP_DURATION, + 0, 2, NULL, msm_voip_gain_put), + SOC_SINGLE_EXT("Voip Mode Config", SND_SOC_NOPM, 0, VOIP_MODE_MAX, 0, + msm_voip_mode_config_get, msm_voip_mode_config_put), + SOC_SINGLE_EXT("Voip Rate Config", SND_SOC_NOPM, 0, VOIP_RATE_MAX, 0, + NULL, msm_voip_rate_config_put), + SOC_SINGLE_MULTI_EXT("Voip Evrc Min Max Rate Config", SND_SOC_NOPM, + 0, VOC_1_RATE, 0, 2, + msm_voip_evrc_min_max_rate_config_get, + msm_voip_evrc_min_max_rate_config_put), + SOC_SINGLE_EXT("Voip Dtx Mode", SND_SOC_NOPM, 0, 1, 0, + msm_voip_dtx_mode_get, msm_voip_dtx_mode_put), +}; + +static int msm_pcm_voip_probe(struct snd_soc_platform *platform) +{ + snd_soc_add_platform_controls(platform, msm_voip_controls, + ARRAY_SIZE(msm_voip_controls)); + + return 0; +} + +/* sample rate supported */ +static unsigned int supported_sample_rates[] = {8000, 16000, 32000, 48000}; + +static void voip_ssr_cb_fn(uint32_t opcode, void *private_data) +{ + + /* Notify ASoC to send next playback/Capture to unblock write/read */ + struct voip_drv_info *prtd = private_data; + + if (opcode == 0xFFFFFFFF) { + + prtd->voip_reset = true; + pr_debug("%s: Notify ASoC to send next playback/Capture\n", + __func__); + + prtd->pcm_playback_irq_pos += prtd->pcm_count; + if (prtd->state == VOIP_STARTED) + snd_pcm_period_elapsed(prtd->playback_substream); + wake_up(&prtd->out_wait); + + prtd->pcm_capture_irq_pos += prtd->pcm_capture_count; + if (prtd->state == VOIP_STARTED) + snd_pcm_period_elapsed(prtd->capture_substream); + wake_up(&prtd->in_wait); + + } else { + pr_err("%s: Invalid opcode during reset : %d\n", + __func__, opcode); + } +} + +/* capture path */ +static void voip_process_ul_pkt(uint8_t *voc_pkt, + uint32_t pkt_len, + uint32_t timestamp, + void *private_data) +{ + struct voip_buf_node *buf_node = NULL; + struct voip_drv_info *prtd = private_data; + unsigned long dsp_flags; + + if (prtd->capture_substream == NULL) + return; + + /* Copy up-link packet into out_queue. */ + spin_lock_irqsave(&prtd->dsp_ul_lock, dsp_flags); + + /* discarding UL packets till start is received */ + if (!list_empty(&prtd->free_out_queue) && prtd->capture_start) { + buf_node = list_first_entry(&prtd->free_out_queue, + struct voip_buf_node, list); + list_del(&buf_node->list); + switch (prtd->mode) { + case MODE_AMR_WB: + case MODE_AMR: { + /* Remove the DSP frame info header. Header format: + * Bits 0-3: Frame rate + * Bits 4-7: Frame type + */ + buf_node->frame.frm_hdr.timestamp = timestamp; + buf_node->frame.frm_hdr.frame_type = + ((*voc_pkt) & 0xF0) >> 4; + voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN; + buf_node->frame.pktlen = pkt_len - DSP_FRAME_HDR_LEN; + memcpy(&buf_node->frame.voc_pkt[0], + voc_pkt, + buf_node->frame.pktlen); + + list_add_tail(&buf_node->list, &prtd->out_queue); + break; + } + case MODE_IS127: + case MODE_4GV_NB: + case MODE_4GV_WB: + case MODE_4GV_NW: { + /* Remove the DSP frame info header. + * Header format: + * Bits 0-3: frame rate + */ + buf_node->frame.frm_hdr.timestamp = timestamp; + buf_node->frame.frm_hdr.packet_rate = (*voc_pkt) & 0x0F; + voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN; + buf_node->frame.pktlen = pkt_len - DSP_FRAME_HDR_LEN; + + memcpy(&buf_node->frame.voc_pkt[0], + voc_pkt, + buf_node->frame.pktlen); + + list_add_tail(&buf_node->list, &prtd->out_queue); + break; + } + case MODE_G711: + case MODE_G711A:{ + /* G711 frames are 10ms each, but the DSP works with + * 20ms frames and sends two 10ms frames per buffer. + * Extract the two frames and put them in separate + * buffers. + */ + /* Remove the first DSP frame info header. + * Header format: G711A + * Bits 0-1: Frame type + * Bits 2-3: Frame rate + * + * Header format: G711 + * Bits 2-3: Frame rate + */ + if (prtd->mode == MODE_G711A) + buf_node->frame.frm_hdr.frame_type = + (*voc_pkt) & 0x03; + buf_node->frame.frm_hdr.timestamp = timestamp; + voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN; + + /* There are two frames in the buffer. Length of the + * first frame: + */ + buf_node->frame.pktlen = (pkt_len - + 2 * DSP_FRAME_HDR_LEN) / 2; + + memcpy(&buf_node->frame.voc_pkt[0], + voc_pkt, + buf_node->frame.pktlen); + voc_pkt = voc_pkt + buf_node->frame.pktlen; + + list_add_tail(&buf_node->list, &prtd->out_queue); + + /* Get another buffer from the free Q and fill in the + * second frame. + */ + if (!list_empty(&prtd->free_out_queue)) { + buf_node = + list_first_entry(&prtd->free_out_queue, + struct voip_buf_node, + list); + list_del(&buf_node->list); + + /* Remove the second DSP frame info header. + * Header format: + * Bits 0-1: Frame type + * Bits 2-3: Frame rate + */ + + if (prtd->mode == MODE_G711A) + buf_node->frame.frm_hdr.frame_type = + (*voc_pkt) & 0x03; + buf_node->frame.frm_hdr.timestamp = timestamp; + voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN; + + /* There are two frames in the buffer. Length + * of the second frame: + */ + buf_node->frame.pktlen = (pkt_len - + 2 * DSP_FRAME_HDR_LEN) / 2; + + memcpy(&buf_node->frame.voc_pkt[0], + voc_pkt, + buf_node->frame.pktlen); + + list_add_tail(&buf_node->list, + &prtd->out_queue); + } else { + /* Drop the second frame */ + pr_err("%s: UL data dropped, read is slow\n", + __func__); + } + break; + } + default: { + buf_node->frame.frm_hdr.timestamp = timestamp; + buf_node->frame.pktlen = pkt_len; + memcpy(&buf_node->frame.voc_pkt[0], + voc_pkt, + buf_node->frame.pktlen); + list_add_tail(&buf_node->list, &prtd->out_queue); + } + } + pr_debug("%s: pkt_len =%d, frame.pktlen=%d, timestamp=%d\n", + __func__, pkt_len, buf_node->frame.pktlen, timestamp); + + if (prtd->mode == MODE_PCM) + prtd->pcm_capture_irq_pos += buf_node->frame.pktlen; + else + prtd->pcm_capture_irq_pos += prtd->pcm_capture_count; + + spin_unlock_irqrestore(&prtd->dsp_ul_lock, dsp_flags); + snd_pcm_period_elapsed(prtd->capture_substream); + } else { + spin_unlock_irqrestore(&prtd->dsp_ul_lock, dsp_flags); + pr_err("UL data dropped\n"); + } + + wake_up(&prtd->out_wait); +} + +/* playback path */ +static void voip_process_dl_pkt(uint8_t *voc_pkt, void *private_data) +{ + struct voip_buf_node *buf_node = NULL; + struct voip_drv_info *prtd = private_data; + unsigned long dsp_flags; + uint32_t rate_type; + uint32_t frame_rate; + u32 pkt_len; + u8 *voc_addr = NULL; + + if (prtd->playback_substream == NULL) + return; + + spin_lock_irqsave(&prtd->dsp_lock, dsp_flags); + + if (!list_empty(&prtd->in_queue) && prtd->playback_start) { + buf_node = list_first_entry(&prtd->in_queue, + struct voip_buf_node, list); + list_del(&buf_node->list); + switch (prtd->mode) { + case MODE_AMR: + case MODE_AMR_WB: { + *((uint32_t *)voc_pkt) = buf_node->frame.pktlen + + DSP_FRAME_HDR_LEN; + /* Advance to the header of voip packet */ + voc_pkt = voc_pkt + sizeof(uint32_t); + /* + * Add the DSP frame info header. Header format: + * Bits 0-3: Frame rate + * Bits 4-7: Frame type + */ + *voc_pkt = ((buf_node->frame.frm_hdr.frame_type & + 0x0F) << 4); + frame_rate = (buf_node->frame.frm_hdr.frame_type & + 0xFFFF0000) >> 16; + if (frame_rate) { + if (voip_get_rate_type(prtd->mode, frame_rate, + &rate_type)) { + pr_err("%s(): fail at getting rate_type\n", + __func__); + } else + prtd->rate_type = rate_type; + } + *voc_pkt |= prtd->rate_type & 0x0F; + + voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN; + memcpy(voc_pkt, + &buf_node->frame.voc_pkt[0], + buf_node->frame.pktlen); + list_add_tail(&buf_node->list, &prtd->free_in_queue); + break; + } + case MODE_IS127: + case MODE_4GV_NB: + case MODE_4GV_WB: + case MODE_4GV_NW: { + *((uint32_t *)voc_pkt) = buf_node->frame.pktlen + + DSP_FRAME_HDR_LEN; + /* Advance to the header of voip packet */ + voc_pkt = voc_pkt + sizeof(uint32_t); + /* + * Add the DSP frame info header. Header format: + * Bits 0-3 : Frame rate + */ + *voc_pkt = buf_node->frame.frm_hdr.packet_rate & 0x0F; + voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN; + + memcpy(voc_pkt, + &buf_node->frame.voc_pkt[0], + buf_node->frame.pktlen); + + list_add_tail(&buf_node->list, &prtd->free_in_queue); + break; + } + case MODE_G711: + case MODE_G711A:{ + /* G711 frames are 10ms each but the DSP expects 20ms + * worth of data, so send two 10ms frames per buffer. + */ + /* Add the first DSP frame info header. Header format: + * Bits 0-1: Frame type + * Bits 2-3: Frame rate + */ + voc_addr = voc_pkt; + voc_pkt = voc_pkt + sizeof(uint32_t); + + *voc_pkt = ((prtd->rate_type & 0x0F) << 2) | + (buf_node->frame.frm_hdr.frame_type & 0x03); + voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN; + + pkt_len = buf_node->frame.pktlen + DSP_FRAME_HDR_LEN; + + memcpy(voc_pkt, + &buf_node->frame.voc_pkt[0], + buf_node->frame.pktlen); + voc_pkt = voc_pkt + buf_node->frame.pktlen; + + list_add_tail(&buf_node->list, &prtd->free_in_queue); + + if (!list_empty(&prtd->in_queue)) { + /* Get the second buffer. */ + buf_node = list_first_entry(&prtd->in_queue, + struct voip_buf_node, + list); + list_del(&buf_node->list); + + /* Add the second DSP frame info header. + * Header format: + * Bits 0-1: Frame type + * Bits 2-3: Frame rate + */ + *voc_pkt = ((prtd->rate_type & 0x0F) << 2) | + (buf_node->frame.frm_hdr.frame_type & 0x03); + voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN; + + pkt_len = pkt_len + buf_node->frame.pktlen + + DSP_FRAME_HDR_LEN; + + memcpy(voc_pkt, + &buf_node->frame.voc_pkt[0], + buf_node->frame.pktlen); + + list_add_tail(&buf_node->list, + &prtd->free_in_queue); + } else { + /* Only 10ms worth of data is available, signal + * erasure frame. + */ + *voc_pkt = ((prtd->rate_type & 0x0F) << 2) | + (MVS_G711A_ERASURE & 0x03); + + pkt_len = pkt_len + DSP_FRAME_HDR_LEN; + pr_debug("%s, Only 10ms read, erase 2nd frame\n", + __func__); + } + *((uint32_t *)voc_addr) = pkt_len; + break; + } + default: { + *((uint32_t *)voc_pkt) = buf_node->frame.pktlen; + voc_pkt = voc_pkt + sizeof(uint32_t); + memcpy(voc_pkt, + &buf_node->frame.voc_pkt[0], + buf_node->frame.pktlen); + list_add_tail(&buf_node->list, &prtd->free_in_queue); + } + } + pr_debug("%s: frame.pktlen=%d\n", __func__, + buf_node->frame.pktlen); + + if (prtd->mode == MODE_PCM) + prtd->pcm_playback_irq_pos += buf_node->frame.pktlen; + else + prtd->pcm_playback_irq_pos += prtd->pcm_count; + + spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags); + snd_pcm_period_elapsed(prtd->playback_substream); + } else { + *((uint32_t *)voc_pkt) = 0; + spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags); + pr_err_ratelimited("DL data not available\n"); + } + wake_up(&prtd->in_wait); +} + +static struct snd_pcm_hw_constraint_list constraints_sample_rates = { + .count = ARRAY_SIZE(supported_sample_rates), + .list = supported_sample_rates, + .mask = 0, +}; + +static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct voip_drv_info *prtd = runtime->private_data; + + prtd->play_samp_rate = runtime->rate; + prtd->pcm_size = snd_pcm_lib_buffer_bytes(substream); + prtd->pcm_count = snd_pcm_lib_period_bytes(substream); + prtd->pcm_playback_irq_pos = 0; + prtd->pcm_playback_buf_pos = 0; + prtd->playback_prepare = 1; + + return 0; +} + +static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct voip_drv_info *prtd = runtime->private_data; + int ret = 0; + + prtd->cap_samp_rate = runtime->rate; + prtd->pcm_capture_size = snd_pcm_lib_buffer_bytes(substream); + prtd->pcm_capture_count = snd_pcm_lib_period_bytes(substream); + prtd->pcm_capture_irq_pos = 0; + prtd->pcm_capture_buf_pos = 0; + prtd->capture_prepare = 1; + return ret; +} + +static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + int ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct voip_drv_info *prtd = runtime->private_data; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + pr_debug("%s: Trigger start\n", __func__); + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + prtd->capture_start = 1; + else + prtd->playback_start = 1; + break; + case SNDRV_PCM_TRIGGER_STOP: + pr_debug("SNDRV_PCM_TRIGGER_STOP\n"); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + prtd->playback_start = 0; + else + prtd->capture_start = 0; + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int msm_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct voip_drv_info *prtd = &voip_info; + int ret = 0; + + pr_debug("%s, VoIP\n", __func__); + mutex_lock(&prtd->lock); + + runtime->hw = msm_pcm_hardware; + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_sample_rates); + if (ret < 0) + pr_debug("snd_pcm_hw_constraint_list failed\n"); + + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) { + pr_debug("snd_pcm_hw_constraint_integer failed\n"); + goto err; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + prtd->playback_substream = substream; + else + prtd->capture_substream = substream; + + runtime->private_data = prtd; +err: + mutex_unlock(&prtd->lock); + + return ret; +} + +static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, + snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames) +{ + int ret = 0; + struct voip_buf_node *buf_node = NULL; + struct snd_pcm_runtime *runtime = substream->runtime; + struct voip_drv_info *prtd = runtime->private_data; + unsigned long dsp_flags; + + int count = frames_to_bytes(runtime, frames); + + pr_debug("%s: count = %d, frames=%d\n", __func__, count, (int)frames); + + if (prtd->voip_reset) { + pr_debug("%s: RESET event happened during VoIP\n", __func__); + return -ENETRESET; + } + + ret = wait_event_interruptible_timeout(prtd->in_wait, + (!list_empty(&prtd->free_in_queue) || + prtd->state == VOIP_STOPPED), + 1 * HZ); + if (prtd->voip_reset) { + pr_debug("%s: RESET event happened during VoIP\n", __func__); + return -ENETRESET; + } + + if (ret > 0) { + if (count <= VOIP_MAX_VOC_PKT_SIZE) { + spin_lock_irqsave(&prtd->dsp_lock, dsp_flags); + buf_node = + list_first_entry(&prtd->free_in_queue, + struct voip_buf_node, list); + list_del(&buf_node->list); + spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags); + if (prtd->mode == MODE_PCM) { + ret = copy_from_user(&buf_node->frame.voc_pkt, + buf, count); + if (ret) { + pr_err("%s: copy from user failed %d\n", + __func__, ret); + return -EFAULT; + } + buf_node->frame.pktlen = count; + } else { + ret = copy_from_user(&buf_node->frame, + buf, count); + if (ret) { + pr_err("%s: copy from user failed %d\n", + __func__, ret); + return -EFAULT; + } + if (buf_node->frame.pktlen >= count) + buf_node->frame.pktlen = count - + (sizeof(buf_node->frame.frm_hdr) + + sizeof(buf_node->frame.pktlen)); + } + spin_lock_irqsave(&prtd->dsp_lock, dsp_flags); + list_add_tail(&buf_node->list, &prtd->in_queue); + spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags); + } else { + pr_err("%s: Write cnt %d is > VOIP_MAX_VOC_PKT_SIZE\n", + __func__, count); + ret = -ENOMEM; + } + + } else if (ret == 0) { + pr_err("%s: No free DL buffs\n", __func__); + ret = -ETIMEDOUT; + } else { + pr_err("%s: playback copy was interrupted %d\n", __func__, ret); + } + + return ret; +} +static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, + int channel, snd_pcm_uframes_t hwoff, void __user *buf, + snd_pcm_uframes_t frames) +{ + int ret = 0; + int count = 0; + struct voip_buf_node *buf_node = NULL; + struct snd_pcm_runtime *runtime = substream->runtime; + struct voip_drv_info *prtd = runtime->private_data; + unsigned long dsp_flags; + int size; + + count = frames_to_bytes(runtime, frames); + + pr_debug("%s: count = %d\n", __func__, count); + + if (prtd->voip_reset) { + pr_debug("%s: RESET event happened during VoIP\n", __func__); + return -ENETRESET; + } + + ret = wait_event_interruptible_timeout(prtd->out_wait, + (!list_empty(&prtd->out_queue) || + prtd->state == VOIP_STOPPED), + 1 * HZ); + + if (prtd->voip_reset) { + pr_debug("%s: RESET event happened during VoIP\n", __func__); + return -ENETRESET; + } + + if (ret > 0) { + + if (count <= VOIP_MAX_VOC_PKT_SIZE) { + spin_lock_irqsave(&prtd->dsp_ul_lock, dsp_flags); + buf_node = list_first_entry(&prtd->out_queue, + struct voip_buf_node, list); + list_del(&buf_node->list); + spin_unlock_irqrestore(&prtd->dsp_ul_lock, dsp_flags); + if (prtd->mode == MODE_PCM) { + ret = copy_to_user(buf, + &buf_node->frame.voc_pkt, + buf_node->frame.pktlen); + } else { + size = sizeof(buf_node->frame.frm_hdr) + + sizeof(buf_node->frame.pktlen) + + buf_node->frame.pktlen; + + ret = copy_to_user(buf, + &buf_node->frame, + size); + } + if (ret) { + pr_err("%s: Copy to user returned %d\n", + __func__, ret); + ret = -EFAULT; + } + spin_lock_irqsave(&prtd->dsp_ul_lock, dsp_flags); + list_add_tail(&buf_node->list, + &prtd->free_out_queue); + spin_unlock_irqrestore(&prtd->dsp_ul_lock, dsp_flags); + } else { + pr_err("%s: Read count %d > VOIP_MAX_VOC_PKT_SIZE\n", + __func__, count); + ret = -ENOMEM; + } + + + } else if (ret == 0) { + pr_err_ratelimited("%s: No UL data available\n", __func__); + ret = -ETIMEDOUT; + } else { + pr_err("%s: Read was interrupted\n", __func__); + ret = -ERESTARTSYS; + } + return ret; +} +static int msm_pcm_copy(struct snd_pcm_substream *substream, int a, + snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames) +{ + int ret = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ret = msm_pcm_playback_copy(substream, a, hwoff, buf, frames); + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ret = msm_pcm_capture_copy(substream, a, hwoff, buf, frames); + + return ret; +} + +static int msm_pcm_close(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct list_head *ptr = NULL; + struct list_head *next = NULL; + struct voip_buf_node *buf_node = NULL; + struct snd_dma_buffer *p_dma_buf, *c_dma_buf; + struct snd_pcm_substream *p_substream, *c_substream; + struct snd_pcm_runtime *runtime; + struct voip_drv_info *prtd; + unsigned long dsp_flags; + + if (substream == NULL) { + pr_err("substream is NULL\n"); + return -EINVAL; + } + runtime = substream->runtime; + prtd = runtime->private_data; + + wake_up(&prtd->out_wait); + + mutex_lock(&prtd->lock); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + prtd->playback_prepare = 0; + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + prtd->capture_prepare = 0; + + if (!prtd->playback_prepare && !prtd->capture_prepare) { + if (prtd->state == VOIP_STARTED) { + prtd->voip_reset = false; + prtd->state = VOIP_STOPPED; + voc_end_voice_call( + voc_get_session_id(VOIP_SESSION_NAME)); + voc_register_mvs_cb(NULL, NULL, NULL, prtd); + } + /* release all buffer */ + /* release in_queue and free_in_queue */ + pr_debug("release all buffer\n"); + p_substream = prtd->playback_substream; + if (p_substream == NULL) { + pr_debug("p_substream is NULL\n"); + goto capt; + } + p_dma_buf = &p_substream->dma_buffer; + if (p_dma_buf == NULL) { + pr_debug("p_dma_buf is NULL\n"); + goto capt; + } + if (p_dma_buf->area != NULL) { + spin_lock_irqsave(&prtd->dsp_lock, dsp_flags); + list_for_each_safe(ptr, next, &prtd->in_queue) { + buf_node = list_entry(ptr, + struct voip_buf_node, list); + list_del(&buf_node->list); + } + list_for_each_safe(ptr, next, &prtd->free_in_queue) { + buf_node = list_entry(ptr, + struct voip_buf_node, list); + list_del(&buf_node->list); + } + spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags); + dma_free_coherent(p_substream->pcm->card->dev, + runtime->hw.buffer_bytes_max, p_dma_buf->area, + p_dma_buf->addr); + p_dma_buf->area = NULL; + } + /* release out_queue and free_out_queue */ +capt: c_substream = prtd->capture_substream; + if (c_substream == NULL) { + pr_debug("c_substream is NULL\n"); + goto done; + } + c_dma_buf = &c_substream->dma_buffer; + if (c_substream == NULL) { + pr_debug("c_dma_buf is NULL.\n"); + goto done; + } + if (c_dma_buf->area != NULL) { + spin_lock_irqsave(&prtd->dsp_ul_lock, dsp_flags); + list_for_each_safe(ptr, next, &prtd->out_queue) { + buf_node = list_entry(ptr, + struct voip_buf_node, list); + list_del(&buf_node->list); + } + list_for_each_safe(ptr, next, &prtd->free_out_queue) { + buf_node = list_entry(ptr, + struct voip_buf_node, list); + list_del(&buf_node->list); + } + spin_unlock_irqrestore(&prtd->dsp_ul_lock, dsp_flags); + dma_free_coherent(c_substream->pcm->card->dev, + runtime->hw.buffer_bytes_max, c_dma_buf->area, + c_dma_buf->addr); + c_dma_buf->area = NULL; + } +done: + prtd->capture_substream = NULL; + prtd->playback_substream = NULL; + } + mutex_unlock(&prtd->lock); + + return ret; +} + +static int voip_config_vocoder(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct voip_drv_info *prtd = runtime->private_data; + uint32_t media_type = 0; + uint32_t rate_type = 0; + uint32_t evrc_min_rate_type = 0; + uint32_t evrc_max_rate_type = 0; + + pr_debug("%s(): mode=%d, playback rate=%d, capture rate=%d\n", + __func__, prtd->mode, prtd->play_samp_rate, + prtd->cap_samp_rate); + + if ((runtime->format != FORMAT_S16_LE && + runtime->format != FORMAT_SPECIAL) && + ((prtd->mode == MODE_AMR) || (prtd->mode == MODE_AMR_WB) || + (prtd->mode == MODE_IS127) || (prtd->mode == MODE_4GV_NB) || + (prtd->mode == MODE_4GV_WB) || (prtd->mode == MODE_4GV_NW) || + (prtd->mode == MODE_G711) || (prtd->mode == MODE_G711A))) { + pr_err("%s(): mode:%d and format:%u are not matched\n", + __func__, prtd->mode, (uint32_t)runtime->format); + + ret = -EINVAL; + goto done; + } + + if (runtime->format != FORMAT_S16_LE && (prtd->mode == MODE_PCM)) { + pr_err("%s(): mode:%d and format:%u are not matched\n", + __func__, prtd->mode, runtime->format); + + ret = -EINVAL; + goto done; + } + + if ((prtd->mode == MODE_PCM) || + (prtd->mode == MODE_AMR) || + (prtd->mode == MODE_AMR_WB) || + (prtd->mode == MODE_G711) || + (prtd->mode == MODE_G711A)) { + ret = voip_get_rate_type(prtd->mode, + prtd->rate, + &rate_type); + if (ret < 0) { + pr_err("%s(): fail at getting rate_type, ret=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + prtd->rate_type = rate_type; + pr_debug("rate_type=%d\n", rate_type); + + } else if ((prtd->mode == MODE_IS127) || + (prtd->mode == MODE_4GV_NB) || + (prtd->mode == MODE_4GV_WB) || + (prtd->mode == MODE_4GV_NW)) { + ret = voip_get_rate_type(prtd->mode, + prtd->evrc_min_rate, + &evrc_min_rate_type); + if (ret < 0) { + pr_err("%s(): fail at getting min rate, ret=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + if (evrc_min_rate_type == VOC_0_RATE) + evrc_min_rate_type = VOC_8_RATE; + + ret = voip_get_rate_type(prtd->mode, + prtd->evrc_max_rate, + &evrc_max_rate_type); + if (ret < 0) { + pr_err("%s(): fail at getting max rate, ret=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + if (evrc_max_rate_type == VOC_0_RATE) + evrc_max_rate_type = VOC_1_RATE; + + if (evrc_max_rate_type < evrc_min_rate_type) { + pr_err("%s(): Invalid EVRC min max rates: %d, %d\n", + __func__, evrc_min_rate_type, + evrc_max_rate_type); + + ret = -EINVAL; + goto done; + } + pr_debug("%s(): min rate=%d, max rate=%d\n", + __func__, evrc_min_rate_type, evrc_max_rate_type); + } + ret = voip_get_media_type(prtd->mode, + prtd->rate_type, + prtd->play_samp_rate, + &media_type); + if (ret < 0) { + pr_err("%s(): fail at getting media_type, ret=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + pr_debug("%s(): media_type=%d\n", __func__, media_type); + + if ((prtd->play_samp_rate == 8000 && prtd->cap_samp_rate == 8000) || + (prtd->play_samp_rate == 16000 && prtd->cap_samp_rate == 16000) || + (prtd->play_samp_rate == 32000 && prtd->cap_samp_rate == 32000) || + (prtd->play_samp_rate == 48000 && prtd->cap_samp_rate == 48000)) { + voc_config_vocoder(media_type, rate_type, + VSS_NETWORK_ID_VOIP, + voip_info.dtx_mode, + evrc_min_rate_type, + evrc_max_rate_type); + } else { + pr_debug("%s: Invalid rate playback %d, capture %d\n", + __func__, prtd->play_samp_rate, + prtd->cap_samp_rate); + + ret = -EINVAL; + } +done: + + return ret; +} + +static int msm_pcm_prepare(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + struct voip_drv_info *prtd = runtime->private_data; + + mutex_lock(&prtd->lock); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ret = msm_pcm_playback_prepare(substream); + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ret = msm_pcm_capture_prepare(substream); + + if (prtd->playback_prepare && prtd->capture_prepare + && (prtd->state != VOIP_STARTED)) { + ret = voip_config_vocoder(substream); + if (ret < 0) { + pr_err("%s(): fail at configuring vocoder for voip, ret=%d\n", + __func__, ret); + + goto done; + } + + /* Initialaizing cb variables */ + voc_register_mvs_cb(voip_process_ul_pkt, + voip_process_dl_pkt, + voip_ssr_cb_fn, prtd); + + ret = voc_start_voice_call( + voc_get_session_id(VOIP_SESSION_NAME)); + + if (ret < 0) { + pr_err("%s: voc_start_voice_call() failed err %d", + __func__, ret); + + goto done; + } + prtd->state = VOIP_STARTED; + } +done: + mutex_unlock(&prtd->lock); + + return ret; +} + +static snd_pcm_uframes_t +msm_pcm_playback_pointer(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct voip_drv_info *prtd = runtime->private_data; + + pr_debug("%s\n", __func__); + if (prtd->pcm_playback_irq_pos >= prtd->pcm_size) + prtd->pcm_playback_irq_pos = 0; + return bytes_to_frames(runtime, (prtd->pcm_playback_irq_pos)); +} + +static snd_pcm_uframes_t +msm_pcm_capture_pointer(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct voip_drv_info *prtd = runtime->private_data; + + if (prtd->pcm_capture_irq_pos >= prtd->pcm_capture_size) + prtd->pcm_capture_irq_pos = 0; + return bytes_to_frames(runtime, (prtd->pcm_capture_irq_pos)); +} + +static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream) +{ + snd_pcm_uframes_t ret = 0; + + pr_debug("%s\n", __func__); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ret = msm_pcm_playback_pointer(substream); + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ret = msm_pcm_capture_pointer(substream); + return ret; +} + +static int msm_pcm_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + pr_debug("%s\n", __func__); + dma_mmap_coherent(substream->pcm->card->dev, vma, + runtime->dma_area, + runtime->dma_addr, + runtime->dma_bytes); + return 0; +} + +static int msm_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_dma_buffer *dma_buf = &substream->dma_buffer; + struct voip_buf_node *buf_node = NULL; + int i = 0, offset = 0; + + pr_debug("%s: voip\n", __func__); + + mutex_lock(&voip_info.lock); + + dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; + dma_buf->dev.dev = substream->pcm->card->dev; + dma_buf->private_data = NULL; + + dma_buf->area = dma_alloc_coherent(substream->pcm->card->dev, + runtime->hw.buffer_bytes_max, + &dma_buf->addr, GFP_KERNEL); + if (!dma_buf->area) { + pr_err("%s:MSM VOIP dma_alloc failed\n", __func__); + mutex_unlock(&voip_info.lock); + return -ENOMEM; + } + + dma_buf->bytes = runtime->hw.buffer_bytes_max; + memset(dma_buf->area, 0, runtime->hw.buffer_bytes_max); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + for (i = 0; i < VOIP_MAX_Q_LEN; i++) { + buf_node = (void *)dma_buf->area + offset; + + list_add_tail(&buf_node->list, + &voip_info.free_in_queue); + offset = offset + sizeof(struct voip_buf_node); + } + } else { + for (i = 0; i < VOIP_MAX_Q_LEN; i++) { + buf_node = (void *) dma_buf->area + offset; + list_add_tail(&buf_node->list, + &voip_info.free_out_queue); + offset = offset + sizeof(struct voip_buf_node); + } + } + + mutex_unlock(&voip_info.lock); + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + + return 0; +} + +static int msm_voip_mode_config_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + mutex_lock(&voip_info.lock); + + ucontrol->value.integer.value[0] = voip_info.mode; + + mutex_unlock(&voip_info.lock); + + return 0; +} + +static int msm_voip_mode_config_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + mutex_lock(&voip_info.lock); + + voip_info.mode = ucontrol->value.integer.value[0]; + + pr_debug("%s: mode=%d\n", __func__, voip_info.mode); + + mutex_unlock(&voip_info.lock); + + return 0; +} + +static int msm_voip_rate_config_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int rate = ucontrol->value.integer.value[0]; + + mutex_lock(&voip_info.lock); + + if (voip_info.rate != rate) { + voip_info.rate = rate; + pr_debug("%s: rate=%d\n", __func__, voip_info.rate); + + if (voip_info.state == VOIP_STARTED && + (voip_info.mode == MODE_AMR || + voip_info.mode == MODE_AMR_WB)) { + ret = voip_config_vocoder( + voip_info.capture_substream); + if (ret) { + pr_err("%s:Failed to configure vocoder, ret=%d\n", + __func__, ret); + + goto done; + } + + ret = voc_update_amr_vocoder_rate( + voc_get_session_id(VOIP_SESSION_NAME)); + if (ret) { + pr_err("%s:Failed to update AMR rate, ret=%d\n", + __func__, ret); + } + } + } + +done: + mutex_unlock(&voip_info.lock); + + return ret; +} + +static int msm_voip_evrc_min_max_rate_config_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + mutex_lock(&voip_info.lock); + + ucontrol->value.integer.value[0] = voip_info.evrc_min_rate; + ucontrol->value.integer.value[1] = voip_info.evrc_max_rate; + + mutex_unlock(&voip_info.lock); + + return 0; +} + +static int msm_voip_evrc_min_max_rate_config_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + mutex_lock(&voip_info.lock); + + voip_info.evrc_min_rate = ucontrol->value.integer.value[0]; + voip_info.evrc_max_rate = ucontrol->value.integer.value[1]; + + pr_debug("%s(): evrc_min_rate=%d,evrc_max_rate=%d\n", __func__, + voip_info.evrc_min_rate, voip_info.evrc_max_rate); + + mutex_unlock(&voip_info.lock); + + return 0; +} + +static int voip_get_rate_type(uint32_t mode, uint32_t rate, + uint32_t *rate_type) +{ + int ret = 0; + + switch (mode) { + case MODE_AMR: { + switch (rate) { + case 4750: + *rate_type = AMR_RATE_4750; + break; + case 5150: + *rate_type = AMR_RATE_5150; + break; + case 5900: + *rate_type = AMR_RATE_5900; + break; + case 6700: + *rate_type = AMR_RATE_6700; + break; + case 7400: + *rate_type = AMR_RATE_7400; + break; + case 7950: + *rate_type = AMR_RATE_7950; + break; + case 10200: + *rate_type = AMR_RATE_10200; + break; + case 12200: + *rate_type = AMR_RATE_12200; + break; + default: + pr_err("wrong rate for AMR NB.\n"); + ret = -EINVAL; + break; + } + break; + } + case MODE_AMR_WB: { + switch (rate) { + case 6600: + *rate_type = AMR_RATE_6600 - AMR_RATE_6600; + break; + case 8850: + *rate_type = AMR_RATE_8850 - AMR_RATE_6600; + break; + case 12650: + *rate_type = AMR_RATE_12650 - AMR_RATE_6600; + break; + case 14250: + *rate_type = AMR_RATE_14250 - AMR_RATE_6600; + break; + case 15850: + *rate_type = AMR_RATE_15850 - AMR_RATE_6600; + break; + case 18250: + *rate_type = AMR_RATE_18250 - AMR_RATE_6600; + break; + case 19850: + *rate_type = AMR_RATE_19850 - AMR_RATE_6600; + break; + case 23050: + *rate_type = AMR_RATE_23050 - AMR_RATE_6600; + break; + case 23850: + *rate_type = AMR_RATE_23850 - AMR_RATE_6600; + break; + default: + pr_err("wrong rate for AMR_WB.\n"); + ret = -EINVAL; + break; + } + break; + } + case MODE_PCM: { + *rate_type = 0; + break; + } + case MODE_IS127: + case MODE_4GV_NB: + case MODE_4GV_WB: { + switch (rate) { + case VOC_0_RATE: + case VOC_8_RATE: + case VOC_4_RATE: + case VOC_2_RATE: + case VOC_1_RATE: + *rate_type = rate; + break; + default: + pr_err("wrong rate for IS127/4GV_NB/WB.\n"); + ret = -EINVAL; + break; + } + break; + } + case MODE_4GV_NW: { + switch (rate) { + case VOC_0_RATE: + case VOC_8_RATE: + case VOC_4_RATE: + case VOC_2_RATE: + case VOC_1_RATE: + case VOC_8_RATE_NC: + *rate_type = rate; + break; + default: + pr_err("wrong rate for 4GV_NW.\n"); + ret = -EINVAL; + break; + } + break; + } + case MODE_G711: + case MODE_G711A: + *rate_type = rate; + break; + default: + pr_err("wrong mode type.\n"); + ret = -EINVAL; + } + pr_debug("%s, mode=%d, rate=%u, rate_type=%d\n", + __func__, mode, rate, *rate_type); + return ret; +} + +static int voip_get_media_type(uint32_t mode, uint32_t rate_type, + unsigned int samp_rate, + unsigned int *media_type) +{ + int ret = 0; + + pr_debug("%s: mode=%d, samp_rate=%d\n", __func__, + mode, samp_rate); + switch (mode) { + case MODE_AMR: + *media_type = VSS_MEDIA_ID_AMR_NB_MODEM; + break; + case MODE_AMR_WB: + *media_type = VSS_MEDIA_ID_AMR_WB_MODEM; + break; + case MODE_PCM: + if (samp_rate == 8000) + *media_type = VSS_MEDIA_ID_PCM_8_KHZ; + else if (samp_rate == 16000) + *media_type = VSS_MEDIA_ID_PCM_16_KHZ; + else if (samp_rate == 32000) + *media_type = VSS_MEDIA_ID_PCM_32_KHZ; + else + *media_type = VSS_MEDIA_ID_PCM_48_KHZ; + break; + case MODE_IS127: /* EVRC-A */ + *media_type = VSS_MEDIA_ID_EVRC_MODEM; + break; + case MODE_4GV_NB: /* EVRC-B */ + *media_type = VSS_MEDIA_ID_4GV_NB_MODEM; + break; + case MODE_4GV_WB: /* EVRC-WB */ + *media_type = VSS_MEDIA_ID_4GV_WB_MODEM; + break; + case MODE_4GV_NW: /* EVRC-NW */ + *media_type = VSS_MEDIA_ID_4GV_NW_MODEM; + break; + case MODE_G711: + case MODE_G711A: + if (rate_type == MVS_G711A_MODE_MULAW) + *media_type = VSS_MEDIA_ID_G711_MULAW; + else + *media_type = VSS_MEDIA_ID_G711_ALAW; + break; + default: + pr_debug(" input mode is not supported\n"); + ret = -EINVAL; + } + + pr_debug("%s: media_type is 0x%x\n", __func__, *media_type); + + return ret; +} + + +static const struct snd_pcm_ops msm_pcm_ops = { + .open = msm_pcm_open, + .copy = msm_pcm_copy, + .hw_params = msm_pcm_hw_params, + .close = msm_pcm_close, + .prepare = msm_pcm_prepare, + .trigger = msm_pcm_trigger, + .pointer = msm_pcm_pointer, + .mmap = msm_pcm_mmap, +}; + +static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_card *card = rtd->card->snd_card; + int ret = 0; + + pr_debug("msm_asoc_pcm_new\n"); + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = DMA_BIT_MASK(32); + return ret; +} + +static struct snd_soc_platform_driver msm_soc_platform = { + .ops = &msm_pcm_ops, + .pcm_new = msm_asoc_pcm_new, + .probe = msm_pcm_voip_probe, +}; + +static int msm_pcm_probe(struct platform_device *pdev) +{ + int rc; + + if (!is_voc_initialized()) { + pr_debug("%s: voice module not initialized yet, deferring probe()\n", + __func__); + + rc = -EPROBE_DEFER; + goto done; + } + + rc = voc_alloc_cal_shared_memory(); + if (rc == -EPROBE_DEFER) { + pr_debug("%s: memory allocation for calibration deferred %d\n", + __func__, rc); + + goto done; + } else if (rc < 0) { + pr_err("%s: memory allocation for calibration failed %d\n", + __func__, rc); + } + + rc = voc_alloc_voip_shared_memory(); + if (rc < 0) { + pr_err("%s: error allocating shared mem err %d\n", + __func__, rc); + } + + + pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev)); + rc = snd_soc_register_platform(&pdev->dev, + &msm_soc_platform); + +done: + return rc; +} + +static int msm_pcm_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_voip_dt_match[] = { + {.compatible = "qcom,msm-voip-dsp"}, + {} +}; +MODULE_DEVICE_TABLE(of, msm_voip_dt_match); + +static struct platform_driver msm_pcm_driver = { + .driver = { + .name = "msm-voip-dsp", + .owner = THIS_MODULE, + .of_match_table = msm_voip_dt_match, + }, + .probe = msm_pcm_probe, + .remove = msm_pcm_remove, +}; + +static int __init msm_soc_platform_init(void) +{ + memset(&voip_info, 0, sizeof(voip_info)); + voip_info.mode = MODE_PCM; + mutex_init(&voip_info.lock); + + spin_lock_init(&voip_info.dsp_lock); + spin_lock_init(&voip_info.dsp_ul_lock); + + init_waitqueue_head(&voip_info.out_wait); + init_waitqueue_head(&voip_info.in_wait); + + INIT_LIST_HEAD(&voip_info.in_queue); + INIT_LIST_HEAD(&voip_info.free_in_queue); + INIT_LIST_HEAD(&voip_info.out_queue); + INIT_LIST_HEAD(&voip_info.free_out_queue); + + return platform_driver_register(&msm_pcm_driver); +} +module_init(msm_soc_platform_init); + +static void __exit msm_soc_platform_exit(void) +{ + platform_driver_unregister(&msm_pcm_driver); +} +module_exit(msm_soc_platform_exit); + +MODULE_DESCRIPTION("PCM module platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c b/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c new file mode 100644 index 000000000000..a885e1e3aa86 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c @@ -0,0 +1,1407 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "msm-qti-pp-config.h" +#include "msm-pcm-routing-v2.h" + +/* EQUALIZER */ +/* Equal to Frontend after last of the MULTIMEDIA SESSIONS */ +#define MAX_EQ_SESSIONS MSM_FRONTEND_DAI_CS_VOICE + +enum { + EQ_BAND1 = 0, + EQ_BAND2, + EQ_BAND3, + EQ_BAND4, + EQ_BAND5, + EQ_BAND6, + EQ_BAND7, + EQ_BAND8, + EQ_BAND9, + EQ_BAND10, + EQ_BAND11, + EQ_BAND12, + EQ_BAND_MAX, +}; + +/* Audio Sphere data structures */ +struct msm_audio_pp_asphere_state_s { + uint32_t enabled; + uint32_t strength; + uint32_t mode; + uint32_t version; + int port_id[AFE_MAX_PORTS]; + int copp_idx[AFE_MAX_PORTS]; + bool initialized; + uint32_t enabled_prev; + uint32_t strength_prev; +}; + +static struct msm_audio_pp_asphere_state_s asphere_state; + +struct msm_audio_eq_stream_config eq_data[MAX_EQ_SESSIONS]; + +static int msm_route_hfp_vol_control; +static const DECLARE_TLV_DB_LINEAR(hfp_rx_vol_gain, 0, + INT_RX_VOL_MAX_STEPS); + +static int msm_route_icc_vol_control; +static const DECLARE_TLV_DB_LINEAR(icc_rx_vol_gain, 0, + INT_RX_VOL_MAX_STEPS); + +static int msm_route_pri_auxpcm_lb_vol_ctrl; +static const DECLARE_TLV_DB_LINEAR(pri_auxpcm_lb_vol_gain, 0, + INT_RX_VOL_MAX_STEPS); + +static int msm_route_sec_auxpcm_lb_vol_ctrl; +static const DECLARE_TLV_DB_LINEAR(sec_auxpcm_lb_vol_gain, 0, + INT_RX_VOL_MAX_STEPS); + +static int msm_multichannel_ec_primary_mic_ch; + +static void msm_qti_pp_send_eq_values_(int eq_idx) +{ + int result; + struct msm_pcm_routing_fdai_data fe_dai; + struct audio_client *ac = NULL; + + msm_pcm_routing_get_fedai_info(eq_idx, SESSION_TYPE_RX, &fe_dai); + ac = q6asm_get_audio_client(fe_dai.strm_id); + + if (ac == NULL) { + pr_err("%s: Could not get audio client for session: %d\n", + __func__, fe_dai.strm_id); + goto done; + } + + result = q6asm_equalizer(ac, &eq_data[eq_idx]); + + if (result < 0) + pr_err("%s: Call to ASM equalizer failed, returned = %d\n", + __func__, result); +done: + return; +} + +static int msm_qti_pp_get_eq_enable_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int eq_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + + if ((eq_idx < 0) || (eq_idx >= MAX_EQ_SESSIONS)) + return -EINVAL; + + ucontrol->value.integer.value[0] = eq_data[eq_idx].enable; + + pr_debug("%s: EQ #%d enable %d\n", __func__, + eq_idx, eq_data[eq_idx].enable); + return 0; +} + +static int msm_qti_pp_put_eq_enable_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int eq_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int value = ucontrol->value.integer.value[0]; + + if ((eq_idx < 0) || (eq_idx >= MAX_EQ_SESSIONS)) + return -EINVAL; + pr_debug("%s: EQ #%d enable %d\n", __func__, + eq_idx, value); + eq_data[eq_idx].enable = value; + msm_pcm_routing_acquire_lock(); + msm_qti_pp_send_eq_values_(eq_idx); + msm_pcm_routing_release_lock(); + return 0; +} + +static int msm_qti_pp_get_eq_band_count_audio_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int eq_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + + if ((eq_idx < 0) || (eq_idx >= MAX_EQ_SESSIONS)) + return -EINVAL; + ucontrol->value.integer.value[0] = eq_data[eq_idx].num_bands; + + pr_debug("%s: EQ #%d bands %d\n", __func__, + eq_idx, eq_data[eq_idx].num_bands); + return eq_data[eq_idx].num_bands; +} + +static int msm_qti_pp_put_eq_band_count_audio_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int eq_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int value = ucontrol->value.integer.value[0]; + + if ((eq_idx < 0) || (eq_idx >= MAX_EQ_SESSIONS)) + return -EINVAL; + + pr_debug("%s: EQ #%d bands %d\n", __func__, + eq_idx, value); + eq_data[eq_idx].num_bands = value; + return 0; +} + +static int msm_qti_pp_get_eq_band_audio_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int eq_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + if ((eq_idx < 0) || (eq_idx >= MAX_EQ_SESSIONS) || + (band_idx < EQ_BAND1) || (band_idx >= EQ_BAND_MAX)) + return -EINVAL; + + ucontrol->value.integer.value[0] = + eq_data[eq_idx].eq_bands[band_idx].band_idx; + ucontrol->value.integer.value[1] = + eq_data[eq_idx].eq_bands[band_idx].filter_type; + ucontrol->value.integer.value[2] = + eq_data[eq_idx].eq_bands[band_idx].center_freq_hz; + ucontrol->value.integer.value[3] = + eq_data[eq_idx].eq_bands[band_idx].filter_gain; + ucontrol->value.integer.value[4] = + eq_data[eq_idx].eq_bands[band_idx].q_factor; + + pr_debug("%s: band_idx = %d\n", __func__, + eq_data[eq_idx].eq_bands[band_idx].band_idx); + pr_debug("%s: filter_type = %d\n", __func__, + eq_data[eq_idx].eq_bands[band_idx].filter_type); + pr_debug("%s: center_freq_hz = %d\n", __func__, + eq_data[eq_idx].eq_bands[band_idx].center_freq_hz); + pr_debug("%s: filter_gain = %d\n", __func__, + eq_data[eq_idx].eq_bands[band_idx].filter_gain); + pr_debug("%s: q_factor = %d\n", __func__, + eq_data[eq_idx].eq_bands[band_idx].q_factor); + return 0; +} + +static int msm_qti_pp_put_eq_band_audio_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int eq_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + if ((eq_idx < 0) || (eq_idx >= MAX_EQ_SESSIONS) || + (band_idx < EQ_BAND1) || (band_idx >= EQ_BAND_MAX)) + return -EINVAL; + + eq_data[eq_idx].eq_bands[band_idx].band_idx = + ucontrol->value.integer.value[0]; + eq_data[eq_idx].eq_bands[band_idx].filter_type = + ucontrol->value.integer.value[1]; + eq_data[eq_idx].eq_bands[band_idx].center_freq_hz = + ucontrol->value.integer.value[2]; + eq_data[eq_idx].eq_bands[band_idx].filter_gain = + ucontrol->value.integer.value[3]; + eq_data[eq_idx].eq_bands[band_idx].q_factor = + ucontrol->value.integer.value[4]; + return 0; +} + +#ifdef CONFIG_QTI_PP +void msm_qti_pp_send_eq_values(int fedai_id) +{ + if (eq_data[fedai_id].enable) + msm_qti_pp_send_eq_values_(fedai_id); +} + +/* CUSTOM MIXING */ +int msm_qti_pp_send_stereo_to_custom_stereo_cmd(int port_id, int copp_idx, + unsigned int session_id, + uint16_t op_FL_ip_FL_weight, + uint16_t op_FL_ip_FR_weight, + uint16_t op_FR_ip_FL_weight, + uint16_t op_FR_ip_FR_weight) +{ + char *params_value; + int *update_params_value32, rc = 0; + int16_t *update_params_value16 = 0; + uint32_t params_length = CUSTOM_STEREO_PAYLOAD_SIZE * sizeof(uint32_t); + uint32_t avail_length = params_length; + + pr_debug("%s: port_id - %d, session id - %d\n", __func__, port_id, + session_id); + params_value = kzalloc(params_length, GFP_KERNEL); + if (!params_value) { + pr_err("%s, params memory alloc failed\n", __func__); + return -ENOMEM; + } + update_params_value32 = (int *)params_value; + if (avail_length < 2 * sizeof(uint32_t)) + goto skip_send_cmd; + *update_params_value32++ = MTMX_MODULE_ID_DEFAULT_CHMIXER; + *update_params_value32++ = DEFAULT_CHMIXER_PARAM_ID_COEFF; + avail_length = avail_length - (2 * sizeof(uint32_t)); + + update_params_value16 = (int16_t *)update_params_value32; + if (avail_length < 10 * sizeof(uint16_t)) + goto skip_send_cmd; + *update_params_value16++ = CUSTOM_STEREO_CMD_PARAM_SIZE; + /*for alignment only*/ + *update_params_value16++ = 0; + /*index is 32-bit param in little endian*/ + *update_params_value16++ = CUSTOM_STEREO_INDEX_PARAM; + *update_params_value16++ = 0; + /*for stereo mixing num out ch*/ + *update_params_value16++ = CUSTOM_STEREO_NUM_OUT_CH; + /*for stereo mixing num in ch*/ + *update_params_value16++ = CUSTOM_STEREO_NUM_IN_CH; + + /* Out ch map FL/FR*/ + *update_params_value16++ = PCM_CHANNEL_FL; + *update_params_value16++ = PCM_CHANNEL_FR; + + /* In ch map FL/FR*/ + *update_params_value16++ = PCM_CHANNEL_FL; + *update_params_value16++ = PCM_CHANNEL_FR; + avail_length = avail_length - (10 * sizeof(uint16_t)); + /* weighting coefficients as name suggests, + * mixing will be done according to these coefficients + */ + if (avail_length < 4 * sizeof(uint16_t)) + goto skip_send_cmd; + *update_params_value16++ = op_FL_ip_FL_weight; + *update_params_value16++ = op_FL_ip_FR_weight; + *update_params_value16++ = op_FR_ip_FL_weight; + *update_params_value16++ = op_FR_ip_FR_weight; + avail_length = avail_length - (4 * sizeof(uint16_t)); + if (params_length) { + rc = adm_set_stereo_to_custom_stereo(port_id, + copp_idx, + session_id, + params_value, + params_length); + if (rc) { + pr_err("%s: send params failed rc=%d\n", __func__, rc); + kfree(params_value); + return -EINVAL; + } + } + kfree(params_value); + return 0; +skip_send_cmd: + pr_err("%s: insufficient memory, send cmd failed\n", + __func__); + kfree(params_value); + return -ENOMEM; +} +#endif /* CONFIG_QTI_PP */ + +/* RMS */ +static int msm_qti_pp_get_rms_value_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + int be_idx = 0, copp_idx; + char *param_value; + int *update_param_value; + uint32_t param_length = sizeof(uint32_t); + uint32_t param_payload_len = RMS_PAYLOAD_LEN * sizeof(uint32_t); + struct msm_pcm_routing_bdai_data msm_bedai; + + param_value = kzalloc(param_length + param_payload_len, GFP_KERNEL); + if (!param_value) + return -ENOMEM; + + msm_pcm_routing_acquire_lock(); + for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) { + msm_pcm_routing_get_bedai_info(be_idx, &msm_bedai); + if (msm_bedai.port_id == SLIMBUS_0_TX) + break; + } + if ((be_idx >= MSM_BACKEND_DAI_MAX) || !msm_bedai.active) { + pr_err("%s, back not active to query rms be_idx:%d\n", + __func__, be_idx); + rc = -EINVAL; + goto get_rms_value_err; + } + copp_idx = adm_get_default_copp_idx(SLIMBUS_0_TX); + if ((copp_idx < 0) || (copp_idx > MAX_COPPS_PER_PORT)) { + pr_err("%s, no active copp to query rms copp_idx:%d\n", + __func__, copp_idx); + rc = -EINVAL; + goto get_rms_value_err; + } + rc = adm_get_params(SLIMBUS_0_TX, copp_idx, + RMS_MODULEID_APPI_PASSTHRU, + RMS_PARAM_FIRST_SAMPLE, + param_length + param_payload_len, + param_value); + if (rc) { + pr_err("%s: get parameters failed rc=%d\n", __func__, rc); + rc = -EINVAL; + goto get_rms_value_err; + } + update_param_value = (int *)param_value; + ucontrol->value.integer.value[0] = update_param_value[0]; + + pr_debug("%s: FROM DSP value[0] 0x%x\n", + __func__, update_param_value[0]); +get_rms_value_err: + msm_pcm_routing_release_lock(); + kfree(param_value); + return rc; +} + +static int msm_qti_pp_put_rms_value_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* not used */ + return 0; +} + +/* VOLUME */ +static int msm_route_fm_vol_control; +static int msm_afe_lb_vol_ctrl; +static int msm_afe_sec_mi2s_lb_vol_ctrl; +static int msm_afe_tert_mi2s_lb_vol_ctrl; +static int msm_afe_quat_mi2s_lb_vol_ctrl; +static int msm_afe_slimbus_7_lb_vol_ctrl; +static int msm_afe_slimbus_8_lb_vol_ctrl; +static const DECLARE_TLV_DB_LINEAR(fm_rx_vol_gain, 0, INT_RX_VOL_MAX_STEPS); +static const DECLARE_TLV_DB_LINEAR(afe_lb_vol_gain, 0, INT_RX_VOL_MAX_STEPS); + +static int msm_qti_pp_get_fm_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_route_fm_vol_control; + return 0; +} + +static int msm_qti_pp_set_fm_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + afe_loopback_gain(INT_FM_TX, ucontrol->value.integer.value[0]); + + msm_route_fm_vol_control = ucontrol->value.integer.value[0]; + + return 0; +} + +static int msm_qti_pp_get_pri_mi2s_lb_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_afe_lb_vol_ctrl; + return 0; +} + +static int msm_qti_pp_set_pri_mi2s_lb_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + afe_loopback_gain(AFE_PORT_ID_PRIMARY_MI2S_TX, + ucontrol->value.integer.value[0]); + + msm_afe_lb_vol_ctrl = ucontrol->value.integer.value[0]; + + return 0; +} + +static int msm_qti_pp_get_sec_mi2s_lb_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_afe_sec_mi2s_lb_vol_ctrl; + return 0; +} + +static int msm_qti_pp_set_sec_mi2s_lb_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + afe_loopback_gain(AFE_PORT_ID_SECONDARY_MI2S_TX, + ucontrol->value.integer.value[0]); + msm_afe_sec_mi2s_lb_vol_ctrl = ucontrol->value.integer.value[0]; + + return 0; +} + +static int msm_qti_pp_get_tert_mi2s_lb_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_afe_tert_mi2s_lb_vol_ctrl; + return 0; +} + +static int msm_qti_pp_set_tert_mi2s_lb_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + afe_loopback_gain(AFE_PORT_ID_TERTIARY_MI2S_TX, + ucontrol->value.integer.value[0]); + msm_afe_tert_mi2s_lb_vol_ctrl = ucontrol->value.integer.value[0]; + return 0; +} + +static int msm_qti_pp_get_slimbus_7_lb_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_afe_slimbus_7_lb_vol_ctrl; + return 0; +} + +static int msm_qti_pp_set_slimbus_7_lb_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = afe_loopback_gain(SLIMBUS_7_TX, + ucontrol->value.integer.value[0]); + + if (ret) + pr_err("%s: failed to set LB vol for SLIMBUS_7_TX, err %d\n", + __func__, ret); + else + msm_afe_slimbus_7_lb_vol_ctrl = + ucontrol->value.integer.value[0]; + + return ret; +} + +static int msm_qti_pp_get_slimbus_8_lb_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_afe_slimbus_8_lb_vol_ctrl; + return 0; +} + +static int msm_qti_pp_set_slimbus_8_lb_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + + ret = afe_loopback_gain(SLIMBUS_8_TX, + ucontrol->value.integer.value[0]); + + if (ret) + pr_err("%s: failed to set LB vol for SLIMBUS_8_TX", __func__); + else + msm_afe_slimbus_8_lb_vol_ctrl = + ucontrol->value.integer.value[0]; + + return ret; +} + +static int msm_qti_pp_get_icc_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_route_icc_vol_control; + return 0; +} + +static int msm_qti_pp_set_icc_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + adm_set_mic_gain(AFE_PORT_ID_QUATERNARY_TDM_TX, + adm_get_default_copp_idx(AFE_PORT_ID_QUATERNARY_TDM_TX), + ucontrol->value.integer.value[0]); + msm_route_icc_vol_control = ucontrol->value.integer.value[0]; + return 0; +} + +static int msm_qti_pp_get_quat_mi2s_fm_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_afe_quat_mi2s_lb_vol_ctrl; + return 0; +} + +static int msm_qti_pp_set_quat_mi2s_fm_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + afe_loopback_gain(AFE_PORT_ID_QUATERNARY_MI2S_TX, + ucontrol->value.integer.value[0]); + + msm_afe_quat_mi2s_lb_vol_ctrl = ucontrol->value.integer.value[0]; + + return 0; +} + +static int msm_qti_pp_get_hfp_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_route_hfp_vol_control; + return 0; +} + +static int msm_qti_pp_set_hfp_vol_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + afe_loopback_gain(INT_BT_SCO_TX, ucontrol->value.integer.value[0]); + + msm_route_hfp_vol_control = ucontrol->value.integer.value[0]; + + return 0; +} + +static int msm_qti_pp_get_pri_auxpcm_lb_vol_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_route_pri_auxpcm_lb_vol_ctrl; + pr_debug("%s: Volume = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_qti_pp_set_pri_auxpcm_lb_vol_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + + afe_loopback_gain(mc->reg, ucontrol->value.integer.value[0]); + + msm_route_pri_auxpcm_lb_vol_ctrl = ucontrol->value.integer.value[0]; + + return 0; +} + +static int msm_qti_pp_get_sec_auxpcm_lb_vol_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_route_sec_auxpcm_lb_vol_ctrl; + pr_debug("%s: Volume = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_qti_pp_set_sec_auxpcm_lb_vol_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + + afe_loopback_gain(mc->reg, ucontrol->value.integer.value[0]); + + msm_route_sec_auxpcm_lb_vol_ctrl = ucontrol->value.integer.value[0]; + + return 0; +} + +static int msm_qti_pp_get_channel_map_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL] = {0}; + int i; + + adm_get_multi_ch_map(channel_map, ADM_PATH_PLAYBACK); + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + ucontrol->value.integer.value[i] = + (unsigned int) channel_map[i]; + return 0; +} + +static int msm_qti_pp_put_channel_map_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL]; + int i; + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + channel_map[i] = (char)(ucontrol->value.integer.value[i]); + adm_set_multi_ch_map(channel_map, ADM_PATH_PLAYBACK); + + return 0; +} + +/* Audio Sphere functions */ + +static void msm_qti_pp_asphere_init_state(void) +{ + int i; + + if (asphere_state.initialized) + return; + asphere_state.initialized = true; + for (i = 0; i < AFE_MAX_PORTS; i++) { + asphere_state.port_id[i] = -1; + asphere_state.copp_idx[i] = -1; + } + asphere_state.enabled = 0; + asphere_state.strength = 0; + asphere_state.mode = 0; + asphere_state.version = 0; + asphere_state.enabled_prev = 0; + asphere_state.strength_prev = 0; +} + +static int msm_qti_pp_asphere_send_params(int port_id, int copp_idx, bool force) +{ + char *params_value = NULL; + uint32_t *update_params_value = NULL; + uint32_t param_size = sizeof(uint32_t) + + sizeof(struct adm_param_data_v5); + int params_length = 0, param_count = 0, ret = 0; + bool set_enable = force || + (asphere_state.enabled != asphere_state.enabled_prev); + bool set_strength = asphere_state.enabled == 1 && (set_enable || + (asphere_state.strength != asphere_state.strength_prev)); + + if (set_enable) + param_count++; + if (set_strength) + param_count++; + params_length = param_count * param_size; + + pr_debug("%s: port_id %d, copp_id %d, forced %d, param_count %d\n", + __func__, port_id, copp_idx, force, param_count); + pr_debug("%s: enable prev:%u cur:%u, strength prev:%u cur:%u\n", + __func__, asphere_state.enabled_prev, asphere_state.enabled, + asphere_state.strength_prev, asphere_state.strength); + + if (params_length > 0) + params_value = kzalloc(params_length, GFP_KERNEL); + if (!params_value) { + pr_err("%s, params memory alloc failed\n", __func__); + return -ENOMEM; + } + update_params_value = (uint32_t *)params_value; + params_length = 0; + if (set_strength) { + /* add strength command */ + *update_params_value++ = AUDPROC_MODULE_ID_AUDIOSPHERE; + *update_params_value++ = AUDPROC_PARAM_ID_AUDIOSPHERE_STRENGTH; + *update_params_value++ = sizeof(uint32_t); + *update_params_value++ = asphere_state.strength; + params_length += param_size; + } + if (set_enable) { + /* add enable command */ + *update_params_value++ = AUDPROC_MODULE_ID_AUDIOSPHERE; + *update_params_value++ = AUDPROC_PARAM_ID_AUDIOSPHERE_ENABLE; + *update_params_value++ = sizeof(uint32_t); + *update_params_value++ = asphere_state.enabled; + params_length += param_size; + } + pr_debug("%s, param length: %d\n", __func__, params_length); + if (params_length) { + ret = adm_send_params_v5(port_id, copp_idx, + params_value, params_length); + if (ret) { + pr_err("%s: setting param failed with err=%d\n", + __func__, ret); + kfree(params_value); + return -EINVAL; + } + } + kfree(params_value); + return 0; +} + +#if defined(CONFIG_QTI_PP) && defined(CONFIG_QTI_PP_AUDIOSPHERE) +int msm_qti_pp_asphere_init(int port_id, int copp_idx) +{ + int index = adm_validate_and_get_port_index(port_id); + + pr_debug("%s, port_id %d, copp_id %d\n", __func__, port_id, copp_idx); + if (index < 0) { + pr_err("%s: Invalid port idx %d port_id %#x\n", __func__, index, + port_id); + return -EINVAL; + } + msm_qti_pp_asphere_init_state(); + + asphere_state.port_id[index] = port_id; + asphere_state.copp_idx[index] = copp_idx; + + if (asphere_state.enabled) + msm_qti_pp_asphere_send_params(port_id, copp_idx, true); + + return 0; +} + +void msm_qti_pp_asphere_deinit(int port_id) +{ + int index = adm_validate_and_get_port_index(port_id); + + pr_debug("%s, port_id %d\n", __func__, port_id); + if (index < 0) { + pr_err("%s: Invalid port idx %d port_id %#x\n", __func__, index, + port_id); + return; + } + + if (asphere_state.port_id[index] == port_id) { + asphere_state.port_id[index] = -1; + asphere_state.copp_idx[index] = -1; + } +} +#endif + +static int msm_qti_pp_asphere_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + if (!asphere_state.initialized) + return -EAGAIN; + ucontrol->value.integer.value[0] = asphere_state.enabled; + ucontrol->value.integer.value[1] = asphere_state.strength; + pr_debug("%s, enable %u, strength %u\n", __func__, + asphere_state.enabled, asphere_state.strength); + return 0; +} + +static int msm_qti_pp_asphere_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int32_t enable = ucontrol->value.integer.value[0]; + int32_t strength = ucontrol->value.integer.value[1]; + int i; + + pr_debug("%s, enable %u, strength %u\n", __func__, enable, strength); + + msm_qti_pp_asphere_init_state(); + + if (enable == 0 || enable == 1) { + asphere_state.enabled_prev = asphere_state.enabled; + asphere_state.enabled = enable; + } + + if (strength >= 0 && strength <= 1000) { + asphere_state.strength_prev = asphere_state.strength; + asphere_state.strength = strength; + } + + if (asphere_state.strength != asphere_state.strength_prev || + asphere_state.enabled != asphere_state.enabled_prev) { + for (i = 0; i < AFE_MAX_PORTS; i++) { + if (asphere_state.port_id[i] >= 0) + msm_qti_pp_asphere_send_params( + asphere_state.port_id[i], + asphere_state.copp_idx[i], + false); + } + } + return 0; +} + +int msm_adsp_init_mixer_ctl_pp_event_queue(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_kcontrol *kctl; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len = 0, ret = 0; + const char *mixer_ctl_name = DSP_STREAM_CALLBACK; + struct dsp_stream_callback_prtd *kctl_prtd = NULL; + + if (!rtd) { + pr_err("%s: rtd is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + if (!mixer_str) { + ret = -EINVAL; + goto done; + } + + snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, + rtd->pcm->device); + kctl = snd_soc_card_get_kcontrol(rtd->card, mixer_str); + kfree(mixer_str); + if (!kctl) { + pr_err("%s: failed to get kctl.\n", __func__); + ret = -EINVAL; + goto done; + } + + if (kctl->private_data != NULL) { + pr_err("%s: kctl_prtd is not NULL at initialization.\n", + __func__); + return -EINVAL; + } + + kctl_prtd = kzalloc(sizeof(struct dsp_stream_callback_prtd), + GFP_KERNEL); + if (!kctl_prtd) { + ret = -ENOMEM; + goto done; + } + + spin_lock_init(&kctl_prtd->prtd_spin_lock); + INIT_LIST_HEAD(&kctl_prtd->event_queue); + kctl_prtd->event_count = 0; + kctl->private_data = kctl_prtd; + +done: + return ret; +} + +int msm_adsp_clean_mixer_ctl_pp_event_queue(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_kcontrol *kctl; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len = 0, ret = 0; + struct dsp_stream_callback_list *node, *n; + unsigned long spin_flags; + const char *mixer_ctl_name = DSP_STREAM_CALLBACK; + struct dsp_stream_callback_prtd *kctl_prtd = NULL; + + if (!rtd) { + pr_err("%s: rtd is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + if (!mixer_str) { + ret = -EINVAL; + goto done; + } + + snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, + rtd->pcm->device); + kctl = snd_soc_card_get_kcontrol(rtd->card, mixer_str); + kfree(mixer_str); + if (!kctl) { + pr_err("%s: failed to get kctl.\n", __func__); + ret = -EINVAL; + goto done; + } + + kctl_prtd = (struct dsp_stream_callback_prtd *) + kctl->private_data; + if (kctl_prtd != NULL) { + spin_lock_irqsave(&kctl_prtd->prtd_spin_lock, spin_flags); + /* clean the queue */ + list_for_each_entry_safe(node, n, + &kctl_prtd->event_queue, list) { + list_del(&node->list); + kctl_prtd->event_count--; + pr_debug("%s: %d remaining events after del.\n", + __func__, kctl_prtd->event_count); + kfree(node); + } + spin_unlock_irqrestore(&kctl_prtd->prtd_spin_lock, spin_flags); + } + + kfree(kctl_prtd); + kctl->private_data = NULL; + +done: + return ret; +} + +int msm_adsp_inform_mixer_ctl(struct snd_soc_pcm_runtime *rtd, + uint32_t *payload) +{ + /* adsp pp event notifier */ + struct snd_kcontrol *kctl; + struct snd_ctl_elem_value control; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len = 0, ret = 0; + struct dsp_stream_callback_list *new_event; + struct dsp_stream_callback_list *oldest_event; + unsigned long spin_flags; + struct dsp_stream_callback_prtd *kctl_prtd = NULL; + struct msm_adsp_event_data *event_data = NULL; + const char *mixer_ctl_name = DSP_STREAM_CALLBACK; + struct snd_ctl_elem_info kctl_info; + + if (!rtd || !payload) { + pr_err("%s: %s is NULL\n", __func__, + (!rtd) ? "rtd" : "payload"); + ret = -EINVAL; + goto done; + } + + if (rtd->card->snd_card == NULL) { + pr_err("%s: snd_card is null.\n", __func__); + ret = -EINVAL; + goto done; + } + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_ATOMIC); + if (!mixer_str) { + ret = -EINVAL; + goto done; + } + + snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, + rtd->pcm->device); + kctl = snd_soc_card_get_kcontrol(rtd->card, mixer_str); + kfree(mixer_str); + if (!kctl) { + pr_err("%s: failed to get kctl.\n", __func__); + ret = -EINVAL; + goto done; + } + + event_data = (struct msm_adsp_event_data *)payload; + kctl->info(kctl, &kctl_info); + if (sizeof(struct msm_adsp_event_data) + + event_data->payload_len > kctl_info.count) { + pr_err("%s: payload length exceeds limit of %u bytes.\n", + __func__, kctl_info.count); + ret = -EINVAL; + goto done; + } + + kctl_prtd = (struct dsp_stream_callback_prtd *) + kctl->private_data; + if (kctl_prtd == NULL) { + /* queue is not initialized */ + ret = -EINVAL; + pr_err("%s: event queue is not initialized.\n", __func__); + goto done; + } + + new_event = kzalloc(sizeof(struct dsp_stream_callback_list) + + event_data->payload_len, + GFP_ATOMIC); + if (new_event == NULL) { + ret = -ENOMEM; + goto done; + } + memcpy((void *)&new_event->event, (void *)payload, + event_data->payload_len + + sizeof(struct msm_adsp_event_data)); + + spin_lock_irqsave(&kctl_prtd->prtd_spin_lock, spin_flags); + while (kctl_prtd->event_count >= DSP_STREAM_CALLBACK_QUEUE_SIZE) { + pr_info("%s: queue of size %d is full. delete oldest one.\n", + __func__, DSP_STREAM_CALLBACK_QUEUE_SIZE); + oldest_event = list_first_entry(&kctl_prtd->event_queue, + struct dsp_stream_callback_list, list); + pr_info("%s: event deleted: type %d length %d\n", + __func__, oldest_event->event.event_type, + oldest_event->event.payload_len); + list_del(&oldest_event->list); + kctl_prtd->event_count--; + kfree(oldest_event); + } + + list_add_tail(&new_event->list, &kctl_prtd->event_queue); + kctl_prtd->event_count++; + spin_unlock_irqrestore(&kctl_prtd->prtd_spin_lock, spin_flags); + + control.id = kctl->id; + snd_ctl_notify(rtd->card->snd_card, + SNDRV_CTL_EVENT_MASK_INFO, + &control.id); + +done: + return ret; +} + +int msm_adsp_stream_cmd_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = + sizeof(((struct snd_ctl_elem_value *)0)->value.bytes.data); + + return 0; +} + +int msm_adsp_stream_callback_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + uint32_t payload_size = 0; + struct dsp_stream_callback_list *oldest_event; + unsigned long spin_flags; + struct dsp_stream_callback_prtd *kctl_prtd = NULL; + int ret = 0; + + kctl_prtd = (struct dsp_stream_callback_prtd *) + kcontrol->private_data; + if (kctl_prtd == NULL) { + pr_err("%s: ASM Stream PP event queue is not initialized.\n", + __func__); + ret = -EINVAL; + goto done; + } + + spin_lock_irqsave(&kctl_prtd->prtd_spin_lock, spin_flags); + pr_debug("%s: %d events in queue.\n", __func__, kctl_prtd->event_count); + if (list_empty(&kctl_prtd->event_queue)) { + pr_err("%s: ASM Stream PP event queue is empty.\n", __func__); + ret = -EINVAL; + spin_unlock_irqrestore(&kctl_prtd->prtd_spin_lock, spin_flags); + goto done; + } + + oldest_event = list_first_entry(&kctl_prtd->event_queue, + struct dsp_stream_callback_list, list); + list_del(&oldest_event->list); + kctl_prtd->event_count--; + spin_unlock_irqrestore(&kctl_prtd->prtd_spin_lock, spin_flags); + + payload_size = oldest_event->event.payload_len; + pr_debug("%s: event fetched: type %d length %d\n", + __func__, oldest_event->event.event_type, + oldest_event->event.payload_len); + memcpy(ucontrol->value.bytes.data, &oldest_event->event, + sizeof(struct msm_adsp_event_data) + payload_size); + kfree(oldest_event); + +done: + return ret; +} + +int msm_adsp_stream_callback_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = + sizeof(((struct snd_ctl_elem_value *)0)->value.bytes.data); + + return 0; +} + +static int msm_multichannel_ec_primary_mic_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int copp_idx = 0; + int port_id = AFE_PORT_ID_QUATERNARY_TDM_TX; + + msm_multichannel_ec_primary_mic_ch = ucontrol->value.integer.value[0]; + pr_debug("%s: msm_multichannel_ec_primary_mic_ch = %u\n", + __func__, msm_multichannel_ec_primary_mic_ch); + copp_idx = adm_get_default_copp_idx(port_id); + if ((copp_idx < 0) || (copp_idx > MAX_COPPS_PER_PORT)) { + pr_err("%s : no active copp to query multichannel ec copp_idx: %u\n", + __func__, copp_idx); + return -EINVAL; + } + adm_send_set_multichannel_ec_primary_mic_ch(port_id, copp_idx, + msm_multichannel_ec_primary_mic_ch); + + return ret; +} + +static int msm_multichannel_ec_primary_mic_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_multichannel_ec_primary_mic_ch; + pr_debug("%s: msm_multichannel_ec_primary_mic_ch = %lu\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static const struct snd_kcontrol_new msm_multichannel_ec_controls[] = { + SOC_SINGLE_EXT("Multichannel EC Primary Mic Ch", SND_SOC_NOPM, 0, + 0xFFFFFFFF, 0, msm_multichannel_ec_primary_mic_ch_get, + msm_multichannel_ec_primary_mic_ch_put), +}; + +static const struct snd_kcontrol_new int_fm_vol_mixer_controls[] = { + SOC_SINGLE_EXT_TLV("Internal FM RX Volume", SND_SOC_NOPM, 0, + INT_RX_VOL_GAIN, 0, msm_qti_pp_get_fm_vol_mixer, + msm_qti_pp_set_fm_vol_mixer, fm_rx_vol_gain), + SOC_SINGLE_EXT_TLV("Quat MI2S FM RX Volume", SND_SOC_NOPM, 0, + INT_RX_VOL_GAIN, 0, msm_qti_pp_get_quat_mi2s_fm_vol_mixer, + msm_qti_pp_set_quat_mi2s_fm_vol_mixer, fm_rx_vol_gain), +}; + +static const struct snd_kcontrol_new pri_mi2s_lb_vol_mixer_controls[] = { + SOC_SINGLE_EXT_TLV("PRI MI2S LOOPBACK Volume", SND_SOC_NOPM, 0, + INT_RX_VOL_GAIN, 0, msm_qti_pp_get_pri_mi2s_lb_vol_mixer, + msm_qti_pp_set_pri_mi2s_lb_vol_mixer, afe_lb_vol_gain), +}; + +static const struct snd_kcontrol_new sec_mi2s_lb_vol_mixer_controls[] = { + SOC_SINGLE_EXT_TLV("SEC MI2S LOOPBACK Volume", SND_SOC_NOPM, 0, + INT_RX_VOL_GAIN, 0, msm_qti_pp_get_sec_mi2s_lb_vol_mixer, + msm_qti_pp_set_sec_mi2s_lb_vol_mixer, afe_lb_vol_gain), +}; + +static const struct snd_kcontrol_new tert_mi2s_lb_vol_mixer_controls[] = { + SOC_SINGLE_EXT_TLV("Tert MI2S LOOPBACK Volume", SND_SOC_NOPM, 0, + INT_RX_VOL_GAIN, 0, msm_qti_pp_get_tert_mi2s_lb_vol_mixer, + msm_qti_pp_set_tert_mi2s_lb_vol_mixer, afe_lb_vol_gain), +}; + +static const struct snd_kcontrol_new slimbus_7_lb_vol_mixer_controls[] = { + SOC_SINGLE_EXT_TLV("SLIMBUS_7 LOOPBACK Volume", SND_SOC_NOPM, 0, + INT_RX_VOL_GAIN, 0, + msm_qti_pp_get_slimbus_7_lb_vol_mixer, + msm_qti_pp_set_slimbus_7_lb_vol_mixer, + afe_lb_vol_gain), +}; + +static const struct snd_kcontrol_new slimbus_8_lb_vol_mixer_controls[] = { + SOC_SINGLE_EXT_TLV("SLIMBUS_8 LOOPBACK Volume", SND_SOC_NOPM, 0, + INT_RX_VOL_GAIN, 0, msm_qti_pp_get_slimbus_8_lb_vol_mixer, + msm_qti_pp_set_slimbus_8_lb_vol_mixer, afe_lb_vol_gain), +}; + +static const struct snd_kcontrol_new int_hfp_vol_mixer_controls[] = { + SOC_SINGLE_EXT_TLV("Internal HFP RX Volume", SND_SOC_NOPM, 0, + INT_RX_VOL_GAIN, 0, msm_qti_pp_get_hfp_vol_mixer, + msm_qti_pp_set_hfp_vol_mixer, hfp_rx_vol_gain), +}; + +static const struct snd_kcontrol_new int_icc_vol_mixer_controls[] = { + SOC_SINGLE_EXT_TLV("Internal ICC Volume", SND_SOC_NOPM, 0, + INT_RX_VOL_GAIN, 0, msm_qti_pp_get_icc_vol_mixer, + msm_qti_pp_set_icc_vol_mixer, icc_rx_vol_gain), +}; + +static const struct snd_kcontrol_new pri_auxpcm_lb_vol_mixer_controls[] = { + SOC_SINGLE_EXT_TLV("PRI AUXPCM LOOPBACK Volume", + AFE_PORT_ID_PRIMARY_PCM_TX, 0, INT_RX_VOL_GAIN, 0, + msm_qti_pp_get_pri_auxpcm_lb_vol_mixer, + msm_qti_pp_set_pri_auxpcm_lb_vol_mixer, + pri_auxpcm_lb_vol_gain), +}; + +static const struct snd_kcontrol_new sec_auxpcm_lb_vol_mixer_controls[] = { + SOC_SINGLE_EXT_TLV("SEC AUXPCM LOOPBACK Volume", + AFE_PORT_ID_SECONDARY_PCM_TX, 0, INT_RX_VOL_GAIN, 0, + msm_qti_pp_get_sec_auxpcm_lb_vol_mixer, + msm_qti_pp_set_sec_auxpcm_lb_vol_mixer, + sec_auxpcm_lb_vol_gain), +}; + +static const struct snd_kcontrol_new multi_ch_channel_map_mixer_controls[] = { + SOC_SINGLE_MULTI_EXT("Playback Device Channel Map", SND_SOC_NOPM, 0, 16, + 0, 8, msm_qti_pp_get_channel_map_mixer, + msm_qti_pp_put_channel_map_mixer), +}; + + +static const struct snd_kcontrol_new get_rms_controls[] = { + SOC_SINGLE_EXT("Get RMS", SND_SOC_NOPM, 0, 0xFFFFFFFF, + 0, msm_qti_pp_get_rms_value_control, msm_qti_pp_put_rms_value_control), +}; + +static const struct snd_kcontrol_new eq_enable_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1 EQ Enable", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_qti_pp_get_eq_enable_mixer, + msm_qti_pp_put_eq_enable_mixer), + SOC_SINGLE_EXT("MultiMedia2 EQ Enable", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_qti_pp_get_eq_enable_mixer, + msm_qti_pp_put_eq_enable_mixer), + SOC_SINGLE_EXT("MultiMedia3 EQ Enable", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_qti_pp_get_eq_enable_mixer, + msm_qti_pp_put_eq_enable_mixer), +}; + +static const struct snd_kcontrol_new eq_band_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1 EQ Band Count", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA1, 11, 0, + msm_qti_pp_get_eq_band_count_audio_mixer, + msm_qti_pp_put_eq_band_count_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2 EQ Band Count", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA2, 11, 0, + msm_qti_pp_get_eq_band_count_audio_mixer, + msm_qti_pp_put_eq_band_count_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3 EQ Band Count", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA3, 11, 0, + msm_qti_pp_get_eq_band_count_audio_mixer, + msm_qti_pp_put_eq_band_count_audio_mixer), +}; + +static const struct snd_kcontrol_new eq_coeff_mixer_controls[] = { + SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band1", EQ_BAND1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band2", EQ_BAND2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band3", EQ_BAND3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band4", EQ_BAND4, + MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band5", EQ_BAND5, + MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band6", EQ_BAND6, + MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band7", EQ_BAND7, + MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band8", EQ_BAND8, + MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band9", EQ_BAND9, + MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band10", EQ_BAND10, + MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band11", EQ_BAND11, + MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia1 EQ Band12", EQ_BAND12, + MSM_FRONTEND_DAI_MULTIMEDIA1, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band1", EQ_BAND1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band2", EQ_BAND2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band3", EQ_BAND3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band4", EQ_BAND4, + MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band5", EQ_BAND5, + MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band6", EQ_BAND6, + MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band7", EQ_BAND7, + MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band8", EQ_BAND8, + MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band9", EQ_BAND9, + MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band10", EQ_BAND10, + MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band11", EQ_BAND11, + MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia2 EQ Band12", EQ_BAND12, + MSM_FRONTEND_DAI_MULTIMEDIA2, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band1", EQ_BAND1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band2", EQ_BAND2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band3", EQ_BAND3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band4", EQ_BAND4, + MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band5", EQ_BAND5, + MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band6", EQ_BAND6, + MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band7", EQ_BAND7, + MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band8", EQ_BAND8, + MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band9", EQ_BAND9, + MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band10", EQ_BAND10, + MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band11", EQ_BAND11, + MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("MultiMedia3 EQ Band12", EQ_BAND12, + MSM_FRONTEND_DAI_MULTIMEDIA3, 255, 0, 5, + msm_qti_pp_get_eq_band_audio_mixer, msm_qti_pp_put_eq_band_audio_mixer), +}; + +static const struct snd_kcontrol_new asphere_mixer_controls[] = { + SOC_SINGLE_MULTI_EXT("MSM ASphere Set Param", SND_SOC_NOPM, 0, + 0xFFFFFFFF, 0, 2, msm_qti_pp_asphere_get, msm_qti_pp_asphere_set), +}; + +#ifdef CONFIG_QTI_PP +void msm_qti_pp_add_controls(struct snd_soc_platform *platform) +{ + snd_soc_add_platform_controls(platform, int_fm_vol_mixer_controls, + ARRAY_SIZE(int_fm_vol_mixer_controls)); + + snd_soc_add_platform_controls(platform, pri_mi2s_lb_vol_mixer_controls, + ARRAY_SIZE(pri_mi2s_lb_vol_mixer_controls)); + + snd_soc_add_platform_controls(platform, sec_mi2s_lb_vol_mixer_controls, + ARRAY_SIZE(sec_mi2s_lb_vol_mixer_controls)); + + snd_soc_add_platform_controls(platform, tert_mi2s_lb_vol_mixer_controls, + ARRAY_SIZE(tert_mi2s_lb_vol_mixer_controls)); + + snd_soc_add_platform_controls(platform, slimbus_7_lb_vol_mixer_controls, + ARRAY_SIZE(slimbus_7_lb_vol_mixer_controls)); + + snd_soc_add_platform_controls(platform, slimbus_8_lb_vol_mixer_controls, + ARRAY_SIZE(slimbus_8_lb_vol_mixer_controls)); + + snd_soc_add_platform_controls(platform, int_hfp_vol_mixer_controls, + ARRAY_SIZE(int_hfp_vol_mixer_controls)); + + snd_soc_add_platform_controls(platform, int_icc_vol_mixer_controls, + ARRAY_SIZE(int_icc_vol_mixer_controls)); + + snd_soc_add_platform_controls(platform, + pri_auxpcm_lb_vol_mixer_controls, + ARRAY_SIZE(pri_auxpcm_lb_vol_mixer_controls)); + + snd_soc_add_platform_controls(platform, + sec_auxpcm_lb_vol_mixer_controls, + ARRAY_SIZE(sec_auxpcm_lb_vol_mixer_controls)); + + snd_soc_add_platform_controls(platform, + multi_ch_channel_map_mixer_controls, + ARRAY_SIZE(multi_ch_channel_map_mixer_controls)); + + snd_soc_add_platform_controls(platform, get_rms_controls, + ARRAY_SIZE(get_rms_controls)); + + snd_soc_add_platform_controls(platform, eq_enable_mixer_controls, + ARRAY_SIZE(eq_enable_mixer_controls)); + + snd_soc_add_platform_controls(platform, eq_band_mixer_controls, + ARRAY_SIZE(eq_band_mixer_controls)); + + snd_soc_add_platform_controls(platform, eq_coeff_mixer_controls, + ARRAY_SIZE(eq_coeff_mixer_controls)); + + snd_soc_add_platform_controls(platform, asphere_mixer_controls, + ARRAY_SIZE(asphere_mixer_controls)); + + snd_soc_add_platform_controls(platform, msm_multichannel_ec_controls, + ARRAY_SIZE(msm_multichannel_ec_controls)); +} +#endif /* CONFIG_QTI_PP */ diff --git a/sound/soc/msm/qdsp6v2/msm-qti-pp-config.h b/sound/soc/msm/qdsp6v2/msm-qti-pp-config.h new file mode 100644 index 000000000000..01a06a4965ef --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-qti-pp-config.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _MSM_QTI_PP_H_ +#define _MSM_QTI_PP_H_ + +#include +int msm_adsp_inform_mixer_ctl(struct snd_soc_pcm_runtime *rtd, + uint32_t *payload); +int msm_adsp_init_mixer_ctl_pp_event_queue(struct snd_soc_pcm_runtime *rtd); +int msm_adsp_clean_mixer_ctl_pp_event_queue(struct snd_soc_pcm_runtime *rtd); +int msm_adsp_stream_cmd_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); +int msm_adsp_stream_callback_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int msm_adsp_stream_callback_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); +#ifdef CONFIG_QTI_PP +void msm_qti_pp_send_eq_values(int fedai_id); +int msm_qti_pp_send_stereo_to_custom_stereo_cmd(int port_id, int copp_idx, + unsigned int session_id, + uint16_t op_FL_ip_FL_weight, + uint16_t op_FL_ip_FR_weight, + uint16_t op_FR_ip_FL_weight, + uint16_t op_FR_ip_FR_weight); +void msm_qti_pp_add_controls(struct snd_soc_platform *platform); +#else /* CONFIG_QTI_PP */ +#define msm_qti_pp_send_eq_values(fedai_id) do {} while (0) +#define msm_qti_pp_send_stereo_to_custom_stereo_cmd(port_id, copp_idx, \ + session_id, op_FL_ip_FL_weight, op_FL_ip_FR_weight, \ + op_FR_ip_FL_weight, op_FR_ip_FR_weight) (0) +#define msm_qti_pp_add_controls(platform) do {} while (0) +#endif /* CONFIG_QTI_PP */ + + +#if defined(CONFIG_QTI_PP) && defined(CONFIG_QTI_PP_AUDIOSPHERE) +int msm_qti_pp_asphere_init(int port_id, int copp_idx); +void msm_qti_pp_asphere_deinit(int port_id); +#else +#define msm_qti_pp_asphere_init(port_id, copp_idx) (0) +#define msm_qti_pp_asphere_deinit(port_id) do {} while (0) +#endif + +#endif /* _MSM_QTI_PP_H_ */ diff --git a/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c new file mode 100644 index 000000000000..b1bb27248714 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c @@ -0,0 +1,971 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "msm-pcm-routing-v2.h" +#include "msm-qti-pp-config.h" + +#define LOOPBACK_SESSION_MAX_NUM_STREAMS 2 + +static DEFINE_MUTEX(transcode_loopback_session_lock); + +struct trans_loopback_pdata { + struct snd_compr_stream *cstream[MSM_FRONTEND_DAI_MAX]; +}; + +struct loopback_stream { + struct snd_compr_stream *cstream; + uint32_t codec_format; + bool start; +}; + +enum loopback_session_state { + /* One or both streams not opened */ + LOOPBACK_SESSION_CLOSE = 0, + /* Loopback streams opened */ + LOOPBACK_SESSION_READY, + /* Loopback streams opened and formats configured */ + LOOPBACK_SESSION_START, + /* Trigger issued on either of streams when in START state */ + LOOPBACK_SESSION_RUN +}; + +struct msm_transcode_loopback { + struct loopback_stream source; + struct loopback_stream sink; + + struct snd_compr_caps source_compr_cap; + struct snd_compr_caps sink_compr_cap; + + uint32_t instance; + uint32_t num_streams; + int session_state; + + struct mutex lock; + + int session_id; + struct audio_client *audio_client; +}; + +/* Transcode loopback global info struct */ +static struct msm_transcode_loopback transcode_info; + +static void loopback_event_handler(uint32_t opcode, + uint32_t token, uint32_t *payload, void *priv) +{ + struct msm_transcode_loopback *trans = + (struct msm_transcode_loopback *)priv; + struct snd_soc_pcm_runtime *rtd; + struct snd_compr_stream *cstream; + struct audio_client *ac; + int stream_id; + int ret; + + if (!trans || !payload) { + pr_err("%s: rtd or payload is NULL\n", __func__); + return; + } + + cstream = trans->source.cstream; + ac = trans->audio_client; + + /* + * Token for rest of the compressed commands use to set + * session id, stream id, dir etc. + */ + stream_id = q6asm_get_stream_id_from_token(token); + + switch (opcode) { + case ASM_STREAM_CMD_ENCDEC_EVENTS: + case ASM_IEC_61937_MEDIA_FMT_EVENT: + pr_debug("%s: ASM_IEC_61937_MEDIA_FMT_EVENT\n", __func__); + rtd = cstream->private_data; + if (!rtd) { + pr_err("%s: rtd is NULL\n", __func__); + return; + } + + ret = msm_adsp_inform_mixer_ctl(rtd, payload); + if (ret) { + pr_err("%s: failed to inform mixer ctrl. err = %d\n", + __func__, ret); + return; + } + break; + case APR_BASIC_RSP_RESULT: { + switch (payload[0]) { + case ASM_SESSION_CMD_RUN_V2: + pr_debug("%s: ASM_SESSION_CMD_RUN_V2:", __func__); + pr_debug("token 0x%x, stream id %d\n", token, + stream_id); + break; + case ASM_STREAM_CMD_CLOSE: + pr_debug("%s: ASM_DATA_CMD_CLOSE:", __func__); + pr_debug("token 0x%x, stream id %d\n", token, + stream_id); + break; + default: + break; + } + break; + } + default: + pr_debug("%s: Not Supported Event opcode[0x%x]\n", + __func__, opcode); + break; + } +} + +static void populate_codec_list(struct msm_transcode_loopback *trans, + struct snd_compr_stream *cstream) +{ + struct snd_compr_caps compr_cap; + + pr_debug("%s\n", __func__); + + memset(&compr_cap, 0, sizeof(struct snd_compr_caps)); + + if (cstream->direction == SND_COMPRESS_CAPTURE) { + compr_cap.direction = SND_COMPRESS_CAPTURE; + compr_cap.num_codecs = 3; + compr_cap.codecs[0] = SND_AUDIOCODEC_PCM; + compr_cap.codecs[1] = SND_AUDIOCODEC_AC3; + compr_cap.codecs[2] = SND_AUDIOCODEC_EAC3; + memcpy(&trans->source_compr_cap, &compr_cap, + sizeof(struct snd_compr_caps)); + } + + if (cstream->direction == SND_COMPRESS_PLAYBACK) { + compr_cap.direction = SND_COMPRESS_PLAYBACK; + compr_cap.num_codecs = 1; + compr_cap.codecs[0] = SND_AUDIOCODEC_PCM; + memcpy(&trans->sink_compr_cap, &compr_cap, + sizeof(struct snd_compr_caps)); + } +} + +static int msm_transcode_loopback_open(struct snd_compr_stream *cstream) +{ + int ret = 0; + struct snd_compr_runtime *runtime; + struct snd_soc_pcm_runtime *rtd; + struct msm_transcode_loopback *trans = &transcode_info; + struct trans_loopback_pdata *pdata; + + if (cstream == NULL) { + pr_err("%s: Invalid substream\n", __func__); + return -EINVAL; + } + runtime = cstream->runtime; + rtd = snd_pcm_substream_chip(cstream); + pdata = snd_soc_platform_get_drvdata(rtd->platform); + pdata->cstream[rtd->dai_link->id] = cstream; + + mutex_lock(&trans->lock); + if (trans->num_streams > LOOPBACK_SESSION_MAX_NUM_STREAMS) { + pr_err("msm_transcode_open failed..invalid stream\n"); + ret = -EINVAL; + goto exit; + } + + if (cstream->direction == SND_COMPRESS_CAPTURE) { + if (trans->source.cstream == NULL) { + trans->source.cstream = cstream; + trans->num_streams++; + } else { + pr_err("%s: capture stream already opened\n", + __func__); + ret = -EINVAL; + goto exit; + } + } else if (cstream->direction == SND_COMPRESS_PLAYBACK) { + if (trans->sink.cstream == NULL) { + trans->sink.cstream = cstream; + trans->num_streams++; + } else { + pr_debug("%s: playback stream already opened\n", + __func__); + ret = -EINVAL; + goto exit; + } + } + + pr_debug("%s: num stream%d, stream name %s\n", __func__, + trans->num_streams, cstream->name); + + populate_codec_list(trans, cstream); + + if (trans->num_streams == LOOPBACK_SESSION_MAX_NUM_STREAMS) { + pr_debug("%s: Moving loopback session to READY state %d\n", + __func__, trans->session_state); + trans->session_state = LOOPBACK_SESSION_READY; + } + + runtime->private_data = trans; + if (trans->num_streams == 1) + msm_adsp_init_mixer_ctl_pp_event_queue(rtd); +exit: + mutex_unlock(&trans->lock); + return ret; +} + +static void stop_transcoding(struct msm_transcode_loopback *trans) +{ + struct snd_soc_pcm_runtime *soc_pcm_rx; + struct snd_soc_pcm_runtime *soc_pcm_tx; + + if (trans->audio_client != NULL) { + q6asm_cmd(trans->audio_client, CMD_CLOSE); + + if (trans->sink.cstream != NULL) { + soc_pcm_rx = trans->sink.cstream->private_data; + msm_pcm_routing_dereg_phy_stream( + soc_pcm_rx->dai_link->id, + SND_COMPRESS_PLAYBACK); + } + if (trans->source.cstream != NULL) { + soc_pcm_tx = trans->source.cstream->private_data; + msm_pcm_routing_dereg_phy_stream( + soc_pcm_tx->dai_link->id, + SND_COMPRESS_CAPTURE); + } + q6asm_audio_client_free(trans->audio_client); + trans->audio_client = NULL; + } +} + +static int msm_transcode_loopback_free(struct snd_compr_stream *cstream) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct msm_transcode_loopback *trans = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(cstream); + int ret = 0; + + mutex_lock(&trans->lock); + + pr_debug("%s: Transcode loopback end:%d, streams %d\n", __func__, + cstream->direction, trans->num_streams); + trans->num_streams--; + stop_transcoding(trans); + + if (cstream->direction == SND_COMPRESS_PLAYBACK) + memset(&trans->sink, 0, sizeof(struct loopback_stream)); + else if (cstream->direction == SND_COMPRESS_CAPTURE) + memset(&trans->source, 0, sizeof(struct loopback_stream)); + + trans->session_state = LOOPBACK_SESSION_CLOSE; + if (trans->num_streams == 1) + msm_adsp_clean_mixer_ctl_pp_event_queue(rtd); + mutex_unlock(&trans->lock); + return ret; +} + +static int msm_transcode_loopback_trigger(struct snd_compr_stream *cstream, + int cmd) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct msm_transcode_loopback *trans = runtime->private_data; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + + if (trans->session_state == LOOPBACK_SESSION_START) { + pr_debug("%s: Issue Loopback session %d RUN\n", + __func__, trans->instance); + q6asm_run_nowait(trans->audio_client, 0, 0, 0); + trans->session_state = LOOPBACK_SESSION_RUN; + } + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_STOP: + pr_debug("%s: Issue Loopback session %d STOP\n", __func__, + trans->instance); + if (trans->session_state == LOOPBACK_SESSION_RUN) + q6asm_cmd_nowait(trans->audio_client, CMD_PAUSE); + trans->session_state = LOOPBACK_SESSION_START; + break; + + default: + break; + } + return 0; +} + +static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, + struct snd_compr_params *codec_param) +{ + + struct snd_compr_runtime *runtime = cstream->runtime; + struct msm_transcode_loopback *trans = runtime->private_data; + struct snd_soc_pcm_runtime *soc_pcm_rx; + struct snd_soc_pcm_runtime *soc_pcm_tx; + uint32_t bit_width = 16; + int ret = 0; + + if (trans == NULL) { + pr_err("%s: Invalid param\n", __func__); + return -EINVAL; + } + + mutex_lock(&trans->lock); + + if (cstream->direction == SND_COMPRESS_PLAYBACK) { + if (codec_param->codec.id == SND_AUDIOCODEC_PCM) { + trans->sink.codec_format = + FORMAT_LINEAR_PCM; + switch (codec_param->codec.format) { + case SNDRV_PCM_FORMAT_S32_LE: + bit_width = 32; + break; + case SNDRV_PCM_FORMAT_S24_LE: + bit_width = 24; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + bit_width = 24; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bit_width = 16; + break; + } + } else { + pr_debug("%s: unknown sink codec\n", __func__); + ret = -EINVAL; + goto exit; + } + trans->sink.start = true; + } + + if (cstream->direction == SND_COMPRESS_CAPTURE) { + switch (codec_param->codec.id) { + case SND_AUDIOCODEC_PCM: + pr_debug("Source SND_AUDIOCODEC_PCM\n"); + trans->source.codec_format = + FORMAT_LINEAR_PCM; + break; + case SND_AUDIOCODEC_AC3: + pr_debug("Source SND_AUDIOCODEC_AC3\n"); + trans->source.codec_format = + FORMAT_AC3; + break; + case SND_AUDIOCODEC_EAC3: + pr_debug("Source SND_AUDIOCODEC_EAC3\n"); + trans->source.codec_format = + FORMAT_EAC3; + break; + default: + pr_debug("%s: unknown source codec\n", __func__); + ret = -EINVAL; + goto exit; + } + trans->source.start = true; + } + + pr_debug("%s: trans->source.start %d trans->sink.start %d trans->source.cstream %pK trans->sink.cstream %pK trans->session_state %d\n", + __func__, trans->source.start, trans->sink.start, + trans->source.cstream, trans->sink.cstream, + trans->session_state); + + if ((trans->session_state == LOOPBACK_SESSION_READY) && + trans->source.start && trans->sink.start) { + pr_debug("%s: Moving loopback session to start state\n", + __func__); + trans->session_state = LOOPBACK_SESSION_START; + } + + if (trans->session_state == LOOPBACK_SESSION_START) { + if (trans->audio_client != NULL) { + pr_debug("%s: ASM client already opened, closing\n", + __func__); + stop_transcoding(trans); + } + + trans->audio_client = q6asm_audio_client_alloc( + (app_cb)loopback_event_handler, trans); + if (!trans->audio_client) { + pr_err("%s: Could not allocate memory\n", __func__); + ret = -EINVAL; + goto exit; + } + pr_debug("%s: ASM client allocated, callback %pK\n", __func__, + loopback_event_handler); + trans->session_id = trans->audio_client->session; + trans->audio_client->perf_mode = false; + ret = q6asm_open_transcode_loopback(trans->audio_client, + bit_width, + trans->source.codec_format, + trans->sink.codec_format); + if (ret < 0) { + pr_err("%s: Session transcode loopback open failed\n", + __func__); + q6asm_audio_client_free(trans->audio_client); + trans->audio_client = NULL; + goto exit; + } + + pr_debug("%s: Starting ADM open for loopback\n", __func__); + soc_pcm_rx = trans->sink.cstream->private_data; + soc_pcm_tx = trans->source.cstream->private_data; + if (trans->source.codec_format != FORMAT_LINEAR_PCM) + msm_pcm_routing_reg_phy_compr_stream( + soc_pcm_tx->dai_link->id, + trans->audio_client->perf_mode, + trans->session_id, + SNDRV_PCM_STREAM_CAPTURE, + true); + else + msm_pcm_routing_reg_phy_stream( + soc_pcm_tx->dai_link->id, + trans->audio_client->perf_mode, + trans->session_id, + SNDRV_PCM_STREAM_CAPTURE); + + msm_pcm_routing_reg_phy_stream( + soc_pcm_rx->dai_link->id, + trans->audio_client->perf_mode, + trans->session_id, + SNDRV_PCM_STREAM_PLAYBACK); + pr_debug("%s: Successfully opened ADM sessions\n", __func__); + } +exit: + mutex_unlock(&trans->lock); + return ret; +} + +static int msm_transcode_loopback_get_caps(struct snd_compr_stream *cstream, + struct snd_compr_caps *arg) +{ + struct snd_compr_runtime *runtime; + struct msm_transcode_loopback *trans; + + if (!arg || !cstream) { + pr_err("%s: Invalid arguments\n", __func__); + return -EINVAL; + } + + runtime = cstream->runtime; + trans = runtime->private_data; + pr_debug("%s\n", __func__); + if (cstream->direction == SND_COMPRESS_CAPTURE) + memcpy(arg, &trans->source_compr_cap, + sizeof(struct snd_compr_caps)); + else + memcpy(arg, &trans->sink_compr_cap, + sizeof(struct snd_compr_caps)); + return 0; +} + +static int msm_transcode_stream_cmd_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + struct trans_loopback_pdata *pdata = (struct trans_loopback_pdata *) + snd_soc_component_get_drvdata(comp); + struct snd_compr_stream *cstream = NULL; + struct msm_transcode_loopback *prtd; + int ret = 0; + struct msm_adsp_event_data *event_data = NULL; + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received invalid fe_id %lu\n", + __func__, fe_id); + ret = -EINVAL; + goto done; + } + + cstream = pdata->cstream[fe_id]; + if (cstream == NULL) { + pr_err("%s cstream is null.\n", __func__); + ret = -EINVAL; + goto done; + } + + prtd = cstream->runtime->private_data; + if (!prtd) { + pr_err("%s: prtd is null.\n", __func__); + ret = -EINVAL; + goto done; + } + + if (prtd->audio_client == NULL) { + pr_err("%s: audio_client is null.\n", __func__); + ret = -EINVAL; + goto done; + } + + event_data = (struct msm_adsp_event_data *)ucontrol->value.bytes.data; + if ((event_data->event_type < ADSP_STREAM_PP_EVENT) || + (event_data->event_type >= ADSP_STREAM_EVENT_MAX)) { + pr_err("%s: invalid event_type=%d", + __func__, event_data->event_type); + ret = -EINVAL; + goto done; + } + + if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >= + sizeof(ucontrol->value.bytes.data)) { + pr_err("%s param length=%d exceeds limit", + __func__, event_data->payload_len); + ret = -EINVAL; + goto done; + } + + ret = q6asm_send_stream_cmd(prtd->audio_client, event_data); + if (ret < 0) + pr_err("%s: failed to send stream event cmd, err = %d\n", + __func__, ret); +done: + return ret; +} + +static int msm_transcode_ion_fd_map_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + struct trans_loopback_pdata *pdata = (struct trans_loopback_pdata *) + snd_soc_component_get_drvdata(comp); + struct snd_compr_stream *cstream = NULL; + struct msm_transcode_loopback *prtd; + int fd; + int ret = 0; + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bounds invalid fe_id %lu\n", + __func__, fe_id); + ret = -EINVAL; + goto done; + } + + cstream = pdata->cstream[fe_id]; + if (cstream == NULL) { + pr_err("%s cstream is null\n", __func__); + ret = -EINVAL; + goto done; + } + + prtd = cstream->runtime->private_data; + if (!prtd) { + pr_err("%s: prtd is null\n", __func__); + ret = -EINVAL; + goto done; + } + + if (prtd->audio_client == NULL) { + pr_err("%s: audio_client is null\n", __func__); + ret = -EINVAL; + goto done; + } + + memcpy(&fd, ucontrol->value.bytes.data, sizeof(fd)); + ret = q6asm_send_ion_fd(prtd->audio_client, fd); + if (ret < 0) + pr_err("%s: failed to register ion fd\n", __func__); +done: + return ret; +} + +static int msm_transcode_rtic_event_ack_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + struct trans_loopback_pdata *pdata = (struct trans_loopback_pdata *) + snd_soc_component_get_drvdata(comp); + struct snd_compr_stream *cstream = NULL; + struct msm_transcode_loopback *prtd; + int ret = 0; + int param_length = 0; + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received invalid fe_id %lu\n", + __func__, fe_id); + ret = -EINVAL; + goto done; + } + + cstream = pdata->cstream[fe_id]; + if (cstream == NULL) { + pr_err("%s cstream is null\n", __func__); + ret = -EINVAL; + goto done; + } + + prtd = cstream->runtime->private_data; + if (!prtd) { + pr_err("%s: prtd is null\n", __func__); + ret = -EINVAL; + goto done; + } + + if (prtd->audio_client == NULL) { + pr_err("%s: audio_client is null\n", __func__); + ret = -EINVAL; + goto done; + } + + memcpy(¶m_length, ucontrol->value.bytes.data, + sizeof(param_length)); + if ((param_length + sizeof(param_length)) + >= sizeof(ucontrol->value.bytes.data)) { + pr_err("%s param length=%d exceeds limit", + __func__, param_length); + ret = -EINVAL; + goto done; + } + + ret = q6asm_send_rtic_event_ack(prtd->audio_client, + ucontrol->value.bytes.data + sizeof(param_length), + param_length); + if (ret < 0) + pr_err("%s: failed to send rtic event ack, err = %d\n", + __func__, ret); +done: + return ret; +} + +static int msm_transcode_stream_cmd_control( + struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = DSP_STREAM_CMD; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len = 0, ret = 0; + struct snd_kcontrol_new fe_loopback_stream_cmd_config_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_adsp_stream_cmd_info, + .put = msm_transcode_stream_cmd_put, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s NULL rtd\n", __func__); + ret = -EINVAL; + goto done; + } + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + if (!mixer_str) { + ret = -ENOMEM; + goto done; + } + + snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device); + fe_loopback_stream_cmd_config_control[0].name = mixer_str; + fe_loopback_stream_cmd_config_control[0].private_value = + rtd->dai_link->id; + pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); + ret = snd_soc_add_platform_controls(rtd->platform, + fe_loopback_stream_cmd_config_control, + ARRAY_SIZE(fe_loopback_stream_cmd_config_control)); + if (ret < 0) + pr_err("%s: failed to add ctl %s. err = %d\n", + __func__, mixer_str, ret); + + kfree(mixer_str); +done: + return ret; +} + +static int msm_transcode_stream_callback_control( + struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = DSP_STREAM_CALLBACK; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len = 0, ret = 0; + struct snd_kcontrol *kctl; + + struct snd_kcontrol_new fe_loopback_callback_config_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_adsp_stream_callback_info, + .get = msm_adsp_stream_callback_get, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s: rtd is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + if (!mixer_str) { + ret = -ENOMEM; + goto done; + } + + snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device); + fe_loopback_callback_config_control[0].name = mixer_str; + fe_loopback_callback_config_control[0].private_value = + rtd->dai_link->id; + pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); + ret = snd_soc_add_platform_controls(rtd->platform, + fe_loopback_callback_config_control, + ARRAY_SIZE(fe_loopback_callback_config_control)); + if (ret < 0) { + pr_err("%s: failed to add ctl %s. err = %d\n", + __func__, mixer_str, ret); + ret = -EINVAL; + goto free_mixer_str; + } + + kctl = snd_soc_card_get_kcontrol(rtd->card, mixer_str); + if (!kctl) { + pr_err("%s: failed to get kctl %s.\n", __func__, mixer_str); + ret = -EINVAL; + goto free_mixer_str; + } + + kctl->private_data = NULL; +free_mixer_str: + kfree(mixer_str); +done: + return ret; +} + +static int msm_transcode_add_ion_fd_cmd_control(struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = "Playback ION FD"; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len = 0, ret = 0; + struct snd_kcontrol_new fe_ion_fd_config_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_adsp_stream_cmd_info, + .put = msm_transcode_ion_fd_map_put, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s NULL rtd\n", __func__); + ret = -EINVAL; + goto done; + } + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + if (!mixer_str) { + ret = -ENOMEM; + goto done; + } + + snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device); + fe_ion_fd_config_control[0].name = mixer_str; + fe_ion_fd_config_control[0].private_value = rtd->dai_link->id; + pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); + ret = snd_soc_add_platform_controls(rtd->platform, + fe_ion_fd_config_control, + ARRAY_SIZE(fe_ion_fd_config_control)); + if (ret < 0) + pr_err("%s: failed to add ctl %s\n", __func__, mixer_str); + + kfree(mixer_str); +done: + return ret; +} + +static int msm_transcode_add_event_ack_cmd_control( + struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = "Playback Event Ack"; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len = 0, ret = 0; + struct snd_kcontrol_new fe_event_ack_config_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_adsp_stream_cmd_info, + .put = msm_transcode_rtic_event_ack_put, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s NULL rtd\n", __func__); + ret = -EINVAL; + goto done; + } + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + if (!mixer_str) { + ret = -ENOMEM; + goto done; + } + + snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device); + fe_event_ack_config_control[0].name = mixer_str; + fe_event_ack_config_control[0].private_value = rtd->dai_link->id; + pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); + ret = snd_soc_add_platform_controls(rtd->platform, + fe_event_ack_config_control, + ARRAY_SIZE(fe_event_ack_config_control)); + if (ret < 0) + pr_err("%s: failed to add ctl %s\n", __func__, mixer_str); + + kfree(mixer_str); +done: + return ret; +} + +static int msm_transcode_loopback_new(struct snd_soc_pcm_runtime *rtd) +{ + int rc; + + rc = msm_transcode_stream_cmd_control(rtd); + if (rc) + pr_err("%s: ADSP Stream Cmd Control open failed\n", __func__); + + rc = msm_transcode_stream_callback_control(rtd); + if (rc) + pr_err("%s: ADSP Stream callback Control open failed\n", + __func__); + + rc = msm_transcode_add_ion_fd_cmd_control(rtd); + if (rc) + pr_err("%s: Could not add transcode ion fd Control\n", + __func__); + + rc = msm_transcode_add_event_ack_cmd_control(rtd); + if (rc) + pr_err("%s: Could not add transcode event ack Control\n", + __func__); + + return 0; +} + +static struct snd_compr_ops msm_transcode_loopback_ops = { + .open = msm_transcode_loopback_open, + .free = msm_transcode_loopback_free, + .trigger = msm_transcode_loopback_trigger, + .set_params = msm_transcode_loopback_set_params, + .get_caps = msm_transcode_loopback_get_caps, +}; + + +static int msm_transcode_loopback_probe(struct snd_soc_platform *platform) +{ + struct trans_loopback_pdata *pdata = NULL; + + pr_debug("%s\n", __func__); + pdata = (struct trans_loopback_pdata *) + kzalloc(sizeof(struct trans_loopback_pdata), + GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + snd_soc_platform_set_drvdata(platform, pdata); + return 0; +} + +static struct snd_soc_platform_driver msm_soc_platform = { + .probe = msm_transcode_loopback_probe, + .compr_ops = &msm_transcode_loopback_ops, + .pcm_new = msm_transcode_loopback_new, +}; + +static int msm_transcode_dev_probe(struct platform_device *pdev) +{ + + pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev)); + if (pdev->dev.of_node) + dev_set_name(&pdev->dev, "%s", "msm-transcode-loopback"); + + return snd_soc_register_platform(&pdev->dev, + &msm_soc_platform); +} + +static int msm_transcode_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_transcode_loopback_dt_match[] = { + {.compatible = "qcom,msm-transcode-loopback"}, + {} +}; +MODULE_DEVICE_TABLE(of, msm_transcode_loopback_dt_match); + +static struct platform_driver msm_transcode_loopback_driver = { + .driver = { + .name = "msm-transcode-loopback", + .owner = THIS_MODULE, + .of_match_table = msm_transcode_loopback_dt_match, + }, + .probe = msm_transcode_dev_probe, + .remove = msm_transcode_remove, +}; + +static int __init msm_soc_platform_init(void) +{ + memset(&transcode_info, 0, sizeof(struct msm_transcode_loopback)); + mutex_init(&transcode_info.lock); + return platform_driver_register(&msm_transcode_loopback_driver); +} +module_init(msm_soc_platform_init); + +static void __exit msm_soc_platform_exit(void) +{ + mutex_destroy(&transcode_info.lock); + platform_driver_unregister(&msm_transcode_loopback_driver); +} +module_exit(msm_soc_platform_exit); + +MODULE_DESCRIPTION("Transcode loopback platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c new file mode 100644 index 000000000000..15906054f2b8 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/q6adm.c @@ -0,0 +1,4860 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm-dts-srs-tm-config.h" +#include + +#define TIMEOUT_MS 1000 + +#define RESET_COPP_ID 99 +#define INVALID_COPP_ID 0xFF +/* Used for inband payload copy, max size is 4k */ +/* 2 is to account for module & param ID in payload */ +#define ADM_GET_PARAMETER_LENGTH (4096 - APR_HDR_SIZE - 2 * sizeof(uint32_t)) + +#define ULL_SUPPORTED_BITS_PER_SAMPLE 16 +#define ULL_SUPPORTED_SAMPLE_RATE 48000 + +#ifndef CONFIG_DOLBY_DAP +#undef DOLBY_ADM_COPP_TOPOLOGY_ID +#define DOLBY_ADM_COPP_TOPOLOGY_ID 0xFFFFFFFE +#endif + +#ifndef CONFIG_DOLBY_DS2 +#undef DS2_ADM_COPP_TOPOLOGY_ID +#define DS2_ADM_COPP_TOPOLOGY_ID 0xFFFFFFFF +#endif + +/* ENUM for adm_status */ +enum adm_cal_status { + ADM_STATUS_CALIBRATION_REQUIRED = 0, + ADM_STATUS_MAX, +}; + +struct adm_copp { + + atomic_t id[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; + atomic_t cnt[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; + atomic_t topology[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; + atomic_t mode[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; + atomic_t stat[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; + atomic_t rate[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; + atomic_t bit_width[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; + atomic_t channels[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; + atomic_t app_type[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; + atomic_t acdb_id[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; + wait_queue_head_t wait[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; + wait_queue_head_t adm_delay_wait[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; + atomic_t adm_delay_stat[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; + uint32_t adm_delay[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; + unsigned long adm_status[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; +}; + +struct source_tracking_data { + struct ion_client *ion_client; + struct ion_handle *ion_handle; + struct param_outband memmap; + int apr_cmd_status; +}; + +struct adm_ctl { + void *apr; + + struct adm_copp copp; + + atomic_t matrix_map_stat; + wait_queue_head_t matrix_map_wait; + + atomic_t adm_stat; + wait_queue_head_t adm_wait; + + struct cal_type_data *cal_data[ADM_MAX_CAL_TYPES]; + + atomic_t mem_map_handles[ADM_MEM_MAP_INDEX_MAX]; + atomic_t mem_map_index; + + struct param_outband outband_memmap; + struct source_tracking_data sourceTrackingData; + + int set_custom_topology; + int ec_ref_rx; + int num_ec_ref_rx_chans; + int ec_ref_rx_bit_width; + int ec_ref_rx_sampling_rate; +}; + +static struct adm_ctl this_adm; + +struct adm_multi_ch_map { + bool set_channel_map; + char channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL]; +}; + +#define ADM_MCH_MAP_IDX_PLAYBACK 0 +#define ADM_MCH_MAP_IDX_REC 1 +static struct adm_multi_ch_map multi_ch_maps[2] = { + { false, + {0, 0, 0, 0, 0, 0, 0, 0} + }, + { false, + {0, 0, 0, 0, 0, 0, 0, 0} + } +}; + +static int adm_get_parameters[MAX_COPPS_PER_PORT * ADM_GET_PARAMETER_LENGTH]; +static int adm_module_topo_list[ + MAX_COPPS_PER_PORT * ADM_GET_TOPO_MODULE_LIST_LENGTH]; + +int adm_validate_and_get_port_index(int port_id) +{ + int index; + int ret; + + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: port validation failed id 0x%x ret %d\n", + __func__, port_id, ret); + return -EINVAL; + } + + index = afe_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: Invalid port idx %d port_id 0x%x\n", + __func__, index, + port_id); + return -EINVAL; + } + pr_debug("%s: port_idx- %d\n", __func__, index); + return index; +} + +int adm_get_default_copp_idx(int port_id) +{ + int port_idx = adm_validate_and_get_port_index(port_id), idx; + + if (port_idx < 0) { + pr_err("%s: Invalid port id: 0x%x", __func__, port_id); + return -EINVAL; + } + pr_debug("%s: port_idx:%d\n", __func__, port_idx); + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { + if (atomic_read(&this_adm.copp.id[port_idx][idx]) != + RESET_COPP_ID) + return idx; + } + return -EINVAL; +} + +int adm_get_topology_for_port_from_copp_id(int port_id, int copp_id) +{ + int port_idx = adm_validate_and_get_port_index(port_id), idx; + + if (port_idx < 0) { + pr_err("%s: Invalid port id: 0x%x", __func__, port_id); + return 0; + } + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) + if (atomic_read(&this_adm.copp.id[port_idx][idx]) == copp_id) + return atomic_read(&this_adm.copp.topology[port_idx] + [idx]); + pr_err("%s: Invalid copp_id %d port_id 0x%x\n", + __func__, copp_id, port_id); + return 0; +} + +int adm_get_topology_for_port_copp_idx(int port_id, int copp_idx) +{ + int port_idx = adm_validate_and_get_port_index(port_id); + + if (port_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid port: 0x%x copp id: 0x%x", + __func__, port_id, copp_idx); + return 0; + } + return atomic_read(&this_adm.copp.topology[port_idx][copp_idx]); +} + +int adm_get_indexes_from_copp_id(int copp_id, int *copp_idx, int *port_idx) +{ + int p_idx, c_idx; + + for (p_idx = 0; p_idx < AFE_MAX_PORTS; p_idx++) { + for (c_idx = 0; c_idx < MAX_COPPS_PER_PORT; c_idx++) { + if (atomic_read(&this_adm.copp.id[p_idx][c_idx]) + == copp_id) { + if (copp_idx != NULL) + *copp_idx = c_idx; + if (port_idx != NULL) + *port_idx = p_idx; + return 0; + } + } + } + return -EINVAL; +} + +static int adm_get_copp_id(int port_idx, int copp_idx) +{ + pr_debug("%s: port_idx:%d copp_idx:%d\n", __func__, port_idx, copp_idx); + + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); + return -EINVAL; + } + return atomic_read(&this_adm.copp.id[port_idx][copp_idx]); +} + +static int adm_get_idx_if_copp_exists(int port_idx, int topology, int mode, + int rate, int bit_width, int app_type) +{ + int idx; + + pr_debug("%s: port_idx-%d, topology-0x%x, mode-%d, rate-%d, bit_width-%d\n", + __func__, port_idx, topology, mode, rate, bit_width); + + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) + if ((topology == + atomic_read(&this_adm.copp.topology[port_idx][idx])) && + (mode == atomic_read(&this_adm.copp.mode[port_idx][idx])) && + (rate == atomic_read(&this_adm.copp.rate[port_idx][idx])) && + (bit_width == + atomic_read(&this_adm.copp.bit_width[port_idx][idx])) && + (app_type == + atomic_read(&this_adm.copp.app_type[port_idx][idx]))) + return idx; + return -EINVAL; +} + +static int adm_get_next_available_copp(int port_idx) +{ + int idx; + + pr_debug("%s:\n", __func__); + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { + pr_debug("%s: copp_id:0x%x port_idx:%d idx:%d\n", __func__, + atomic_read(&this_adm.copp.id[port_idx][idx]), + port_idx, idx); + if (atomic_read(&this_adm.copp.id[port_idx][idx]) == + RESET_COPP_ID) + break; + } + return idx; +} + +int srs_trumedia_open(int port_id, int copp_idx, __s32 srs_tech_id, + void *srs_params) +{ + struct adm_cmd_set_pp_params_inband_v5 *adm_params = NULL; + struct adm_cmd_set_pp_params_v5 *adm_params_ = NULL; + __s32 sz = 0, param_id, module_id = SRS_TRUMEDIA_MODULE_ID, outband = 0; + int ret = 0, port_idx; + + pr_debug("SRS - %s", __func__); + + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id %#x\n", __func__, port_id); + return -EINVAL; + } + switch (srs_tech_id) { + case SRS_ID_GLOBAL: { + struct srs_trumedia_params_GLOBAL *glb_params = NULL; + + sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + + sizeof(struct srs_trumedia_params_GLOBAL); + adm_params = kzalloc(sz, GFP_KERNEL); + if (!adm_params) { + pr_err("%s, adm params memory alloc failed\n", + __func__); + return -ENOMEM; + } + adm_params->payload_size = + sizeof(struct srs_trumedia_params_GLOBAL) + + sizeof(struct adm_param_data_v5); + param_id = SRS_TRUMEDIA_PARAMS; + adm_params->params.param_size = + sizeof(struct srs_trumedia_params_GLOBAL); + glb_params = (struct srs_trumedia_params_GLOBAL *) + ((u8 *)adm_params + + sizeof(struct adm_cmd_set_pp_params_inband_v5)); + memcpy(glb_params, srs_params, + sizeof(struct srs_trumedia_params_GLOBAL)); + break; + } + case SRS_ID_WOWHD: { + struct srs_trumedia_params_WOWHD *whd_params = NULL; + + sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + + sizeof(struct srs_trumedia_params_WOWHD); + adm_params = kzalloc(sz, GFP_KERNEL); + if (!adm_params) { + pr_err("%s, adm params memory alloc failed\n", + __func__); + return -ENOMEM; + } + adm_params->payload_size = + sizeof(struct srs_trumedia_params_WOWHD) + + sizeof(struct adm_param_data_v5); + param_id = SRS_TRUMEDIA_PARAMS_WOWHD; + adm_params->params.param_size = + sizeof(struct srs_trumedia_params_WOWHD); + whd_params = (struct srs_trumedia_params_WOWHD *) + ((u8 *)adm_params + + sizeof(struct adm_cmd_set_pp_params_inband_v5)); + memcpy(whd_params, srs_params, + sizeof(struct srs_trumedia_params_WOWHD)); + break; + } + case SRS_ID_CSHP: { + struct srs_trumedia_params_CSHP *chp_params = NULL; + + sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + + sizeof(struct srs_trumedia_params_CSHP); + adm_params = kzalloc(sz, GFP_KERNEL); + if (!adm_params) { + pr_err("%s, adm params memory alloc failed\n", + __func__); + return -ENOMEM; + } + adm_params->payload_size = + sizeof(struct srs_trumedia_params_CSHP) + + sizeof(struct adm_param_data_v5); + param_id = SRS_TRUMEDIA_PARAMS_CSHP; + adm_params->params.param_size = + sizeof(struct srs_trumedia_params_CSHP); + chp_params = (struct srs_trumedia_params_CSHP *) + ((u8 *)adm_params + + sizeof(struct adm_cmd_set_pp_params_inband_v5)); + memcpy(chp_params, srs_params, + sizeof(struct srs_trumedia_params_CSHP)); + break; + } + case SRS_ID_HPF: { + struct srs_trumedia_params_HPF *hpf_params = NULL; + + sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + + sizeof(struct srs_trumedia_params_HPF); + adm_params = kzalloc(sz, GFP_KERNEL); + if (!adm_params) { + pr_err("%s, adm params memory alloc failed\n", + __func__); + return -ENOMEM; + } + adm_params->payload_size = + sizeof(struct srs_trumedia_params_HPF) + + sizeof(struct adm_param_data_v5); + param_id = SRS_TRUMEDIA_PARAMS_HPF; + adm_params->params.param_size = + sizeof(struct srs_trumedia_params_HPF); + hpf_params = (struct srs_trumedia_params_HPF *) + ((u8 *)adm_params + + sizeof(struct adm_cmd_set_pp_params_inband_v5)); + memcpy(hpf_params, srs_params, + sizeof(struct srs_trumedia_params_HPF)); + break; + } + case SRS_ID_AEQ: { + int *update_params_ptr = (int *)this_adm.outband_memmap.kvaddr; + + outband = 1; + adm_params = kzalloc(sizeof(struct adm_cmd_set_pp_params_v5), + GFP_KERNEL); + adm_params_ = (struct adm_cmd_set_pp_params_v5 *)adm_params; + if (!adm_params_) { + pr_err("%s, adm params memory alloc failed\n", + __func__); + return -ENOMEM; + } + + sz = sizeof(struct srs_trumedia_params_AEQ); + if (update_params_ptr == NULL) { + pr_err("ADM_SRS_TRUMEDIA - %s: null memmap for AEQ params\n", + __func__); + ret = -EINVAL; + goto fail_cmd; + } + param_id = SRS_TRUMEDIA_PARAMS_AEQ; + *update_params_ptr++ = module_id; + *update_params_ptr++ = param_id; + *update_params_ptr++ = sz; + memcpy(update_params_ptr, srs_params, sz); + + adm_params_->payload_size = sz + 12; + + break; + } + case SRS_ID_HL: { + struct srs_trumedia_params_HL *hl_params = NULL; + + sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + + sizeof(struct srs_trumedia_params_HL); + adm_params = kzalloc(sz, GFP_KERNEL); + if (!adm_params) { + pr_err("%s, adm params memory alloc failed\n", + __func__); + return -ENOMEM; + } + adm_params->payload_size = + sizeof(struct srs_trumedia_params_HL) + + sizeof(struct adm_param_data_v5); + param_id = SRS_TRUMEDIA_PARAMS_HL; + adm_params->params.param_size = + sizeof(struct srs_trumedia_params_HL); + hl_params = (struct srs_trumedia_params_HL *) + ((u8 *)adm_params + + sizeof(struct adm_cmd_set_pp_params_inband_v5)); + memcpy(hl_params, srs_params, + sizeof(struct srs_trumedia_params_HL)); + break; + } + case SRS_ID_GEQ: { + struct srs_trumedia_params_GEQ *geq_params = NULL; + + sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + + sizeof(struct srs_trumedia_params_GEQ); + adm_params = kzalloc(sz, GFP_KERNEL); + if (!adm_params) { + pr_err("%s, adm params memory alloc failed\n", + __func__); + return -ENOMEM; + } + adm_params->payload_size = + sizeof(struct srs_trumedia_params_GEQ) + + sizeof(struct adm_param_data_v5); + param_id = SRS_TRUMEDIA_PARAMS_GEQ; + adm_params->params.param_size = + sizeof(struct srs_trumedia_params_GEQ); + geq_params = (struct srs_trumedia_params_GEQ *) + ((u8 *)adm_params + + sizeof(struct adm_cmd_set_pp_params_inband_v5)); + memcpy(geq_params, srs_params, + sizeof(struct srs_trumedia_params_GEQ)); + pr_debug("SRS - %s: GEQ params prepared\n", __func__); + break; + } + default: + goto fail_cmd; + } + + adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + adm_params->hdr.src_svc = APR_SVC_ADM; + adm_params->hdr.src_domain = APR_DOMAIN_APPS; + adm_params->hdr.src_port = port_id; + adm_params->hdr.dest_svc = APR_SVC_ADM; + adm_params->hdr.dest_domain = APR_DOMAIN_ADSP; + adm_params->hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + adm_params->hdr.token = port_idx << 16 | copp_idx; + adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + if (outband && this_adm.outband_memmap.paddr) { + adm_params->hdr.pkt_size = + sizeof(struct adm_cmd_set_pp_params_v5); + adm_params->payload_addr_lsw = lower_32_bits( + this_adm.outband_memmap.paddr); + adm_params->payload_addr_msw = msm_audio_populate_upper_32_bits( + this_adm.outband_memmap.paddr); + adm_params->mem_map_handle = atomic_read(&this_adm. + mem_map_handles[ADM_SRS_TRUMEDIA]); + } else { + adm_params->hdr.pkt_size = sz; + adm_params->payload_addr_lsw = 0; + adm_params->payload_addr_msw = 0; + adm_params->mem_map_handle = 0; + + adm_params->params.module_id = module_id; + adm_params->params.param_id = param_id; + adm_params->params.reserved = 0; + } + + pr_debug("SRS - %s: Command was sent now check Q6 - port id = %d, size %d, module id %x, param id %x.\n", + __func__, adm_params->hdr.dest_port, + adm_params->payload_size, module_id, param_id); + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + ret = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); + if (ret < 0) { + pr_err("SRS - %s: ADM enable for port %d failed\n", __func__, + port_id); + ret = -EINVAL; + goto fail_cmd; + } + /* Wait for the callback with copp id */ + ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: SRS set params timed out port = %d\n", + __func__, port_id); + ret = -EINVAL; + goto fail_cmd; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto fail_cmd; + } + +fail_cmd: + kfree(adm_params); + return ret; +} + +static int adm_populate_channel_weight(u16 *ptr, + struct msm_pcm_channel_mixer *ch_mixer, + int channel_index) +{ + u16 i, j, start_index = 0; + + if (channel_index > ch_mixer->output_channel) { + pr_err("%s: channel index %d is larger than output_channel %d\n", + __func__, channel_index, ch_mixer->output_channel); + return -EINVAL; + } + + for (i = 0; i < ch_mixer->output_channel; i++) { + pr_debug("%s: weight for output %d:", __func__, i); + for (j = 0; j < ADM_MAX_CHANNELS; j++) + pr_debug(" %d", + ch_mixer->channel_weight[i][j]); + pr_debug("\n"); + } + + for (i = 0; i < channel_index; ++i) + start_index += ch_mixer->input_channels[i]; + + for (i = 0; i < ch_mixer->output_channel; ++i) { + for (j = start_index; + j < start_index + + ch_mixer->input_channels[channel_index]; j++) { + *ptr = ch_mixer->channel_weight[i][j]; + pr_debug("%s: ptr[%d][%d] = %d\n", + __func__, i, j, *ptr); + ptr++; + } + } + + return 0; +} + +/* + * adm_programable_channel_mixer + * + * Receives port_id, copp_idx, session_id, session_type, ch_mixer + * and channel_index to send ADM command to mix COPP data. + * + * port_id - Passed value, port_id for which backend is wanted + * copp_idx - Passed value, copp_idx for which COPP is wanted + * session_id - Passed value, session_id for which session is needed + * session_type - Passed value, session_type for RX or TX + * ch_mixer - Passed value, ch_mixer for which channel mixer config is needed + * channel_index - Passed value, channel_index for which channel is needed + */ +int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, + int session_type, + struct msm_pcm_channel_mixer *ch_mixer, + int channel_index) +{ + struct adm_cmd_set_pspd_mtmx_strtr_params_v5 *adm_params = NULL; + struct adm_param_data_v5 data_v5; + int ret = 0, port_idx, sz = 0, param_size = 0; + u16 *adm_pspd_params; + u16 *ptr; + int index = 0; + + pr_debug("%s: port_id = %d\n", __func__, port_id); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id %#x\n", __func__, port_id); + return -EINVAL; + } + /* + * First 8 bytes are 4 bytes as rule number, 2 bytes as output + * channel and 2 bytes as input channel. + * 2 * ch_mixer->output_channel means output channel mapping. + * 2 * ch_mixer->input_channels[channel_index]) means input + * channel mapping. + * 2 * ch_mixer->input_channels[channel_index] * + * ch_mixer->output_channel) means the channel mixer weighting + * coefficients. + * param_size needs to be a multiple of 4 bytes. + */ + + param_size = 2 * (4 + ch_mixer->output_channel + + ch_mixer->input_channels[channel_index] + + ch_mixer->input_channels[channel_index] * + ch_mixer->output_channel); + roundup(param_size, 4); + + sz = sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v5) + + sizeof(struct default_chmixer_param_id_coeff) + + sizeof(struct adm_param_data_v5) + param_size; + pr_debug("%s: sz = %d\n", __func__, sz); + adm_params = kzalloc(sz, GFP_KERNEL); + if (!adm_params) + return -ENOMEM; + + adm_params->payload_addr_lsw = 0; + adm_params->payload_addr_msw = 0; + adm_params->mem_map_handle = 0; + adm_params->direction = session_type; + adm_params->sessionid = session_id; + pr_debug("%s: copp_id = %d, session id %d\n", __func__, + atomic_read(&this_adm.copp.id[port_idx][copp_idx]), + session_id); + adm_params->deviceid = atomic_read( + &this_adm.copp.id[port_idx][copp_idx]); + adm_params->reserved = 0; + + data_v5.module_id = MTMX_MODULE_ID_DEFAULT_CHMIXER; + data_v5.param_id = DEFAULT_CHMIXER_PARAM_ID_COEFF; + data_v5.reserved = 0; + data_v5.param_size = param_size; + adm_params->payload_size = + sizeof(struct default_chmixer_param_id_coeff) + + sizeof(struct adm_param_data_v5) + data_v5.param_size; + adm_pspd_params = (u16 *)((u8 *)adm_params + + sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v5)); + memcpy(adm_pspd_params, &data_v5, sizeof(data_v5)); + + adm_pspd_params = (u16 *)((u8 *)adm_params + + sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v5) + + sizeof(data_v5)); + + adm_pspd_params[0] = ch_mixer->rule; + adm_pspd_params[2] = ch_mixer->output_channel; + adm_pspd_params[3] = ch_mixer->input_channels[channel_index]; + index = 4; + + if (ch_mixer->output_channel == 1) { + adm_pspd_params[index] = PCM_CHANNEL_FC; + } else if (ch_mixer->output_channel == 2) { + adm_pspd_params[index] = PCM_CHANNEL_FL; + adm_pspd_params[index + 1] = PCM_CHANNEL_FR; + } else if (ch_mixer->output_channel == 3) { + adm_pspd_params[index] = PCM_CHANNEL_FL; + adm_pspd_params[index + 1] = PCM_CHANNEL_FR; + adm_pspd_params[index + 2] = PCM_CHANNEL_FC; + } else if (ch_mixer->output_channel == 4) { + adm_pspd_params[index] = PCM_CHANNEL_FL; + adm_pspd_params[index + 1] = PCM_CHANNEL_FR; + adm_pspd_params[index + 2] = PCM_CHANNEL_LS; + adm_pspd_params[index + 3] = PCM_CHANNEL_RS; + } else if (ch_mixer->output_channel == 5) { + adm_pspd_params[index] = PCM_CHANNEL_FL; + adm_pspd_params[index + 1] = PCM_CHANNEL_FR; + adm_pspd_params[index + 2] = PCM_CHANNEL_FC; + adm_pspd_params[index + 3] = PCM_CHANNEL_LS; + adm_pspd_params[index + 4] = PCM_CHANNEL_RS; + } else if (ch_mixer->output_channel == 6) { + adm_pspd_params[index] = PCM_CHANNEL_FL; + adm_pspd_params[index + 1] = PCM_CHANNEL_FR; + adm_pspd_params[index + 2] = PCM_CHANNEL_LFE; + adm_pspd_params[index + 3] = PCM_CHANNEL_FC; + adm_pspd_params[index + 4] = PCM_CHANNEL_LS; + adm_pspd_params[index + 5] = PCM_CHANNEL_RS; + } else if (ch_mixer->output_channel == 8) { + adm_pspd_params[index] = PCM_CHANNEL_FL; + adm_pspd_params[index + 1] = PCM_CHANNEL_FR; + adm_pspd_params[index + 2] = PCM_CHANNEL_LFE; + adm_pspd_params[index + 3] = PCM_CHANNEL_FC; + adm_pspd_params[index + 4] = PCM_CHANNEL_LS; + adm_pspd_params[index + 5] = PCM_CHANNEL_RS; + adm_pspd_params[index + 6] = PCM_CHANNEL_LB; + adm_pspd_params[index + 7] = PCM_CHANNEL_RB; + } + + index = index + ch_mixer->output_channel; + if (ch_mixer->input_channels[channel_index] == 1) { + adm_pspd_params[index] = PCM_CHANNEL_FC; + } else if (ch_mixer->input_channels[channel_index] == 2) { + adm_pspd_params[index] = PCM_CHANNEL_FL; + adm_pspd_params[index + 1] = PCM_CHANNEL_FR; + } else if (ch_mixer->input_channels[channel_index] == 3) { + adm_pspd_params[index] = PCM_CHANNEL_FL; + adm_pspd_params[index + 1] = PCM_CHANNEL_FR; + adm_pspd_params[index + 2] = PCM_CHANNEL_FC; + } else if (ch_mixer->input_channels[channel_index] == 4) { + adm_pspd_params[index] = PCM_CHANNEL_FL; + adm_pspd_params[index + 1] = PCM_CHANNEL_FR; + adm_pspd_params[index + 2] = PCM_CHANNEL_LS; + adm_pspd_params[index + 3] = PCM_CHANNEL_RS; + } else if (ch_mixer->input_channels[channel_index] == 5) { + adm_pspd_params[index] = PCM_CHANNEL_FL; + adm_pspd_params[index + 1] = PCM_CHANNEL_FR; + adm_pspd_params[index + 2] = PCM_CHANNEL_FC; + adm_pspd_params[index + 3] = PCM_CHANNEL_LS; + adm_pspd_params[index + 4] = PCM_CHANNEL_RS; + } else if (ch_mixer->input_channels[channel_index] == 6) { + adm_pspd_params[index] = PCM_CHANNEL_FL; + adm_pspd_params[index + 1] = PCM_CHANNEL_FR; + adm_pspd_params[index + 2] = PCM_CHANNEL_LFE; + adm_pspd_params[index + 3] = PCM_CHANNEL_FC; + adm_pspd_params[index + 4] = PCM_CHANNEL_LS; + adm_pspd_params[index + 5] = PCM_CHANNEL_RS; + } else if (ch_mixer->input_channels[channel_index] == 8) { + adm_pspd_params[index] = PCM_CHANNEL_FL; + adm_pspd_params[index + 1] = PCM_CHANNEL_FR; + adm_pspd_params[index + 2] = PCM_CHANNEL_LFE; + adm_pspd_params[index + 3] = PCM_CHANNEL_FC; + adm_pspd_params[index + 4] = PCM_CHANNEL_LS; + adm_pspd_params[index + 5] = PCM_CHANNEL_RS; + adm_pspd_params[index + 6] = PCM_CHANNEL_LB; + adm_pspd_params[index + 7] = PCM_CHANNEL_RB; + } + + index = index + ch_mixer->input_channels[channel_index]; + ret = adm_populate_channel_weight(&adm_pspd_params[index], + ch_mixer, channel_index); + if (!ret) { + pr_err("%s: fail to get channel weight with error %d\n", + __func__, ret); + goto fail_cmd; + } + + adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + adm_params->hdr.src_svc = APR_SVC_ADM; + adm_params->hdr.src_domain = APR_DOMAIN_APPS; + adm_params->hdr.src_port = port_id; + adm_params->hdr.dest_svc = APR_SVC_ADM; + adm_params->hdr.dest_domain = APR_DOMAIN_ADSP; + adm_params->hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + adm_params->hdr.token = port_idx << 16 | copp_idx; + adm_params->hdr.opcode = ADM_CMD_SET_PSPD_MTMX_STRTR_PARAMS_V5; + adm_params->hdr.pkt_size = sz; + adm_params->payload_addr_lsw = 0; + adm_params->payload_addr_msw = 0; + adm_params->mem_map_handle = 0; + adm_params->reserved = 0; + + ptr = (u16 *)adm_params; + for (index = 0; index < (sz / 2); index++) + pr_debug("%s: adm_params[%d] = 0x%x\n", + __func__, index, (unsigned int)ptr[index]); + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], 0); + ret = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); + if (ret < 0) { + pr_err("%s: Set params failed port %d rc %d\n", __func__, + port_id, ret); + ret = -EINVAL; + goto fail_cmd; + } + + ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read( + &this_adm.copp.stat[port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: set params timed out port = %d\n", + __func__, port_id); + ret = -ETIMEDOUT; + goto fail_cmd; + } + ret = 0; +fail_cmd: + kfree(adm_params); + + return ret; +} + +int adm_set_stereo_to_custom_stereo(int port_id, int copp_idx, + unsigned int session_id, char *params, + uint32_t params_length) +{ + struct adm_cmd_set_pspd_mtmx_strtr_params_v5 *adm_params = NULL; + int sz, rc = 0, port_idx; + + pr_debug("%s:\n", __func__); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + return -EINVAL; + } + + sz = sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v5) + + params_length; + adm_params = kzalloc(sz, GFP_KERNEL); + if (!adm_params) { + pr_err("%s, adm params memory alloc failed\n", __func__); + return -ENOMEM; + } + + memcpy(((u8 *)adm_params + + sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v5)), + params, params_length); + adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + adm_params->hdr.pkt_size = sz; + adm_params->hdr.src_svc = APR_SVC_ADM; + adm_params->hdr.src_domain = APR_DOMAIN_APPS; + adm_params->hdr.src_port = port_id; + adm_params->hdr.dest_svc = APR_SVC_ADM; + adm_params->hdr.dest_domain = APR_DOMAIN_ADSP; + adm_params->hdr.dest_port = 0; /* Ignored */; + adm_params->hdr.token = port_idx << 16 | copp_idx; + adm_params->hdr.opcode = ADM_CMD_SET_PSPD_MTMX_STRTR_PARAMS_V5; + adm_params->payload_addr_lsw = 0; + adm_params->payload_addr_msw = 0; + adm_params->mem_map_handle = 0; + adm_params->payload_size = params_length; + /* direction RX as 0 */ + adm_params->direction = ADM_MATRIX_ID_AUDIO_RX; + /* session id for this cmd to be applied on */ + adm_params->sessionid = session_id; + adm_params->deviceid = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + adm_params->reserved = 0; + pr_debug("%s: deviceid %d, session_id %d, src_port %d, dest_port %d\n", + __func__, adm_params->deviceid, adm_params->sessionid, + adm_params->hdr.src_port, adm_params->hdr.dest_port); + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); + if (rc < 0) { + pr_err("%s: Set params failed port = 0x%x rc %d\n", + __func__, port_id, rc); + rc = -EINVAL; + goto set_stereo_to_custom_stereo_return; + } + /* Wait for the callback */ + rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!rc) { + pr_err("%s: Set params timed out port = 0x%x\n", __func__, + port_id); + rc = -EINVAL; + goto set_stereo_to_custom_stereo_return; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(atomic_read( + &this_adm.copp.stat + [port_idx][copp_idx]))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto set_stereo_to_custom_stereo_return; + } + rc = 0; +set_stereo_to_custom_stereo_return: + kfree(adm_params); + return rc; +} + +int adm_dolby_dap_send_params(int port_id, int copp_idx, char *params, + uint32_t params_length) +{ + struct adm_cmd_set_pp_params_v5 *adm_params = NULL; + int sz, rc = 0; + int port_idx; + + pr_debug("%s:\n", __func__); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + return -EINVAL; + } + + sz = sizeof(struct adm_cmd_set_pp_params_v5) + params_length; + adm_params = kzalloc(sz, GFP_KERNEL); + if (!adm_params) { + pr_err("%s, adm params memory alloc failed", __func__); + return -ENOMEM; + } + + memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_set_pp_params_v5)), + params, params_length); + adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + adm_params->hdr.pkt_size = sz; + adm_params->hdr.src_svc = APR_SVC_ADM; + adm_params->hdr.src_domain = APR_DOMAIN_APPS; + adm_params->hdr.src_port = port_id; + adm_params->hdr.dest_svc = APR_SVC_ADM; + adm_params->hdr.dest_domain = APR_DOMAIN_ADSP; + adm_params->hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + adm_params->hdr.token = port_idx << 16 | copp_idx; + adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + adm_params->payload_addr_lsw = 0; + adm_params->payload_addr_msw = 0; + adm_params->mem_map_handle = 0; + adm_params->payload_size = params_length; + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); + if (rc < 0) { + pr_err("%s: Set params failed port = 0x%x rc %d\n", + __func__, port_id, rc); + rc = -EINVAL; + goto dolby_dap_send_param_return; + } + /* Wait for the callback */ + rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!rc) { + pr_err("%s: Set params timed out port = 0x%x\n", + __func__, port_id); + rc = -EINVAL; + goto dolby_dap_send_param_return; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto dolby_dap_send_param_return; + } + rc = 0; +dolby_dap_send_param_return: + kfree(adm_params); + return rc; +} + +int adm_send_params_v5(int port_id, int copp_idx, char *params, + uint32_t params_length) +{ + struct adm_cmd_set_pp_params_v5 *adm_params = NULL; + int rc = 0; + int sz, port_idx; + + pr_debug("%s:\n", __func__); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + return -EINVAL; + } + + sz = sizeof(struct adm_cmd_set_pp_params_v5) + params_length; + adm_params = kzalloc(sz, GFP_KERNEL); + if (!adm_params) { + pr_err("%s, adm params memory alloc failed", __func__); + return -ENOMEM; + } + + memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_set_pp_params_v5)), + params, params_length); + adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + adm_params->hdr.pkt_size = sz; + adm_params->hdr.src_svc = APR_SVC_ADM; + adm_params->hdr.src_domain = APR_DOMAIN_APPS; + adm_params->hdr.src_port = port_id; + adm_params->hdr.dest_svc = APR_SVC_ADM; + adm_params->hdr.dest_domain = APR_DOMAIN_ADSP; + adm_params->hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + adm_params->hdr.token = port_idx << 16 | copp_idx; + adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + adm_params->payload_addr_lsw = 0; + adm_params->payload_addr_msw = 0; + adm_params->mem_map_handle = 0; + adm_params->payload_size = params_length; + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); + if (rc < 0) { + pr_err("%s: Set params failed port = 0x%x rc %d\n", + __func__, port_id, rc); + rc = -EINVAL; + goto send_param_return; + } + /* Wait for the callback */ + rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!rc) { + pr_err("%s: Set params timed out port = 0x%x\n", + __func__, port_id); + rc = -EINVAL; + goto send_param_return; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto send_param_return; + } + rc = 0; +send_param_return: + kfree(adm_params); + return rc; +} + +int adm_get_params_v2(int port_id, int copp_idx, uint32_t module_id, + uint32_t param_id, uint32_t params_length, + char *params, uint32_t client_id) +{ + struct adm_cmd_get_pp_params_v5 *adm_params = NULL; + int rc = 0, i = 0; + int port_idx, idx; + int *params_data = (int *)params; + uint64_t sz = 0; + + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + return -EINVAL; + } + + sz = (uint64_t)sizeof(struct adm_cmd_get_pp_params_v5) + + (uint64_t)params_length; + /* + * Check if the value of "sz" (which is ultimately assigned to + * "hdr.pkt_size") crosses U16_MAX. + */ + if (sz > U16_MAX) { + pr_err("%s: Invalid params_length\n", __func__); + return -EINVAL; + } + adm_params = kzalloc(sz, GFP_KERNEL); + if (!adm_params) { + pr_err("%s: adm params memory alloc failed", __func__); + return -ENOMEM; + } + + memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_get_pp_params_v5)), + params, params_length); + adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + adm_params->hdr.pkt_size = sz; + adm_params->hdr.src_svc = APR_SVC_ADM; + adm_params->hdr.src_domain = APR_DOMAIN_APPS; + adm_params->hdr.src_port = port_id; + adm_params->hdr.dest_svc = APR_SVC_ADM; + adm_params->hdr.dest_domain = APR_DOMAIN_ADSP; + adm_params->hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + adm_params->hdr.token = port_idx << 16 | client_id << 8 | copp_idx; + adm_params->hdr.opcode = ADM_CMD_GET_PP_PARAMS_V5; + adm_params->data_payload_addr_lsw = 0; + adm_params->data_payload_addr_msw = 0; + adm_params->mem_map_handle = 0; + adm_params->module_id = module_id; + adm_params->param_id = param_id; + adm_params->param_max_size = params_length; + adm_params->reserved = 0; + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); + if (rc < 0) { + pr_err("%s: Failed to Get Params on port_id 0x%x %d\n", + __func__, port_id, rc); + rc = -EINVAL; + goto adm_get_param_return; + } + /* Wait for the callback with copp id */ + rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!rc) { + pr_err("%s: get params timed out port_id = 0x%x\n", __func__, + port_id); + rc = -EINVAL; + goto adm_get_param_return; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto adm_get_param_return; + } + idx = ADM_GET_PARAMETER_LENGTH * copp_idx; + + if (adm_get_parameters[idx] < 0) { + pr_err("%s: Size is invalid %d\n", __func__, + adm_get_parameters[idx]); + rc = -EINVAL; + goto adm_get_param_return; + } + if ((params_data) && + (ARRAY_SIZE(adm_get_parameters) > + idx) && + (ARRAY_SIZE(adm_get_parameters) >= + 1+adm_get_parameters[idx]+idx) && + (params_length/sizeof(uint32_t) >= + adm_get_parameters[idx])) { + for (i = 0; i < adm_get_parameters[idx]; i++) + params_data[i] = adm_get_parameters[1+i+idx]; + + } else { + pr_err("%s: Get param data not copied! get_param array size %zd, index %d, params array size %zd, index %d\n", + __func__, ARRAY_SIZE(adm_get_parameters), + (1+adm_get_parameters[idx]+idx), + params_length/sizeof(int), + adm_get_parameters[idx]); + } + rc = 0; +adm_get_param_return: + kfree(adm_params); + + return rc; +} + +int adm_get_params(int port_id, int copp_idx, uint32_t module_id, + uint32_t param_id, uint32_t params_length, char *params) +{ + return adm_get_params_v2(port_id, copp_idx, module_id, param_id, + params_length, params, 0); +} + +int adm_get_pp_topo_module_list(int port_id, int copp_idx, int32_t param_length, + char *params) +{ + struct adm_cmd_get_pp_topo_module_list_t *adm_pp_module_list = NULL; + int sz, rc = 0, i = 0; + int port_idx, idx; + int32_t *params_data = (int32_t *)params; + int *topo_list; + + pr_debug("%s : port_id %x", __func__, port_id); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + return -EINVAL; + } + + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); + return -EINVAL; + } + + sz = sizeof(struct adm_cmd_get_pp_topo_module_list_t) + param_length; + adm_pp_module_list = kzalloc(sz, GFP_KERNEL); + if (!adm_pp_module_list) { + pr_err("%s, adm params memory alloc failed", __func__); + return -ENOMEM; + } + + memcpy(((u8 *)adm_pp_module_list + + sizeof(struct adm_cmd_get_pp_topo_module_list_t)), + params, param_length); + adm_pp_module_list->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + adm_pp_module_list->hdr.pkt_size = sz; + adm_pp_module_list->hdr.src_svc = APR_SVC_ADM; + adm_pp_module_list->hdr.src_domain = APR_DOMAIN_APPS; + adm_pp_module_list->hdr.src_port = port_id; + adm_pp_module_list->hdr.dest_svc = APR_SVC_ADM; + adm_pp_module_list->hdr.dest_domain = APR_DOMAIN_ADSP; + adm_pp_module_list->hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + adm_pp_module_list->hdr.token = port_idx << 16 | copp_idx; + adm_pp_module_list->hdr.opcode = ADM_CMD_GET_PP_TOPO_MODULE_LIST; + adm_pp_module_list->param_max_size = param_length; + /* Payload address and mmap handle set to zero by kzalloc */ + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + + rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_pp_module_list); + if (rc < 0) { + pr_err("%s: Failed to Get Params on port %d\n", __func__, + port_id); + rc = -EINVAL; + goto adm_pp_module_list_l; + } + /* Wait for the callback with copp id */ + rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!rc) { + pr_err("%s: get params timed out port = %d\n", __func__, + port_id); + rc = -EINVAL; + goto adm_pp_module_list_l; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto adm_pp_module_list_l; + } + if (params_data) { + idx = ADM_GET_TOPO_MODULE_LIST_LENGTH * copp_idx; + topo_list = (int *)(adm_module_topo_list + idx); + if (param_length <= ADM_GET_TOPO_MODULE_LIST_LENGTH && + idx < + (MAX_COPPS_PER_PORT * ADM_GET_TOPO_MODULE_LIST_LENGTH)) + memcpy(params_data, topo_list, param_length); + else + pr_debug("%s: i/p size:%d > MAX param size:%d\n", + __func__, param_length, + (int)ADM_GET_TOPO_MODULE_LIST_LENGTH); + for (i = 1; i <= params_data[0]; i++) + pr_debug("module = 0x%x\n", params_data[i]); + } + rc = 0; +adm_pp_module_list_l: + kfree(adm_pp_module_list); + pr_debug("%s : rc = %d ", __func__, rc); + return rc; +} +static void adm_callback_debug_print(struct apr_client_data *data) +{ + uint32_t *payload; + + payload = data->payload; + + if (data->payload_size >= 8) + pr_debug("%s: code = 0x%x PL#0[0x%x], PL#1[0x%x], size = %d\n", + __func__, data->opcode, payload[0], payload[1], + data->payload_size); + else if (data->payload_size >= 4) + pr_debug("%s: code = 0x%x PL#0[0x%x], size = %d\n", + __func__, data->opcode, payload[0], + data->payload_size); + else + pr_debug("%s: code = 0x%x, size = %d\n", + __func__, data->opcode, data->payload_size); +} + +int adm_set_multi_ch_map(char *channel_map, int path) +{ + int idx; + + if (path == ADM_PATH_PLAYBACK) { + idx = ADM_MCH_MAP_IDX_PLAYBACK; + } else if (path == ADM_PATH_LIVE_REC) { + idx = ADM_MCH_MAP_IDX_REC; + } else { + pr_err("%s: invalid attempt to set path %d\n", __func__, path); + return -EINVAL; + } + + memcpy(multi_ch_maps[idx].channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL); + multi_ch_maps[idx].set_channel_map = true; + + return 0; +} + +int adm_get_multi_ch_map(char *channel_map, int path) +{ + int idx; + + if (path == ADM_PATH_PLAYBACK) { + idx = ADM_MCH_MAP_IDX_PLAYBACK; + } else if (path == ADM_PATH_LIVE_REC) { + idx = ADM_MCH_MAP_IDX_REC; + } else { + pr_err("%s: invalid attempt to get path %d\n", __func__, path); + return -EINVAL; + } + + if (multi_ch_maps[idx].set_channel_map) { + memcpy(channel_map, multi_ch_maps[idx].channel_mapping, + PCM_FORMAT_MAX_NUM_CHANNEL); + } + + return 0; +} + +static int32_t adm_callback(struct apr_client_data *data, void *priv) +{ + uint32_t *payload; + int i, j, port_idx, copp_idx, idx, client_id; + + if (data == NULL) { + pr_err("%s: data parameter is null\n", __func__); + return -EINVAL; + } + + payload = data->payload; + + if (data->opcode == RESET_EVENTS) { + pr_debug("%s: Reset event is received: %d %d apr[%pK]\n", + __func__, + data->reset_event, data->reset_proc, this_adm.apr); + if (this_adm.apr) { + apr_reset(this_adm.apr); + for (i = 0; i < AFE_MAX_PORTS; i++) { + for (j = 0; j < MAX_COPPS_PER_PORT; j++) { + atomic_set(&this_adm.copp.id[i][j], + RESET_COPP_ID); + atomic_set(&this_adm.copp.cnt[i][j], 0); + atomic_set( + &this_adm.copp.topology[i][j], 0); + atomic_set(&this_adm.copp.mode[i][j], + 0); + atomic_set(&this_adm.copp.stat[i][j], + 0); + atomic_set(&this_adm.copp.rate[i][j], + 0); + atomic_set( + &this_adm.copp.channels[i][j], + 0); + atomic_set( + &this_adm.copp.bit_width[i][j], 0); + atomic_set( + &this_adm.copp.app_type[i][j], 0); + atomic_set( + &this_adm.copp.acdb_id[i][j], 0); + this_adm.copp.adm_status[i][j] = + ADM_STATUS_CALIBRATION_REQUIRED; + } + } + this_adm.apr = NULL; + cal_utils_clear_cal_block_q6maps(ADM_MAX_CAL_TYPES, + this_adm.cal_data); + mutex_lock(&this_adm.cal_data + [ADM_CUSTOM_TOP_CAL]->lock); + this_adm.set_custom_topology = 1; + mutex_unlock(&this_adm.cal_data[ + ADM_CUSTOM_TOP_CAL]->lock); + rtac_clear_mapping(ADM_RTAC_CAL); + /* + * Free the ION memory and clear the map handles + * for Source Tracking + */ + if (this_adm.sourceTrackingData.memmap.paddr != 0) { + msm_audio_ion_free( + this_adm.sourceTrackingData.ion_client, + this_adm.sourceTrackingData.ion_handle); + this_adm.sourceTrackingData.ion_client = NULL; + this_adm.sourceTrackingData.ion_handle = NULL; + this_adm.sourceTrackingData.memmap.size = 0; + this_adm.sourceTrackingData.memmap.kvaddr = + NULL; + this_adm.sourceTrackingData.memmap.paddr = 0; + this_adm.sourceTrackingData.apr_cmd_status = -1; + atomic_set(&this_adm.mem_map_handles[ + ADM_MEM_MAP_INDEX_SOURCE_TRACKING], 0); + } + } + return 0; + } + + adm_callback_debug_print(data); + if (data->payload_size) { + copp_idx = (data->token) & 0XFF; + port_idx = ((data->token) >> 16) & 0xFF; + client_id = ((data->token) >> 8) & 0xFF; + if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { + pr_err("%s: Invalid port idx %d token %d\n", + __func__, port_idx, data->token); + return 0; + } + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp idx %d token %d\n", + __func__, copp_idx, data->token); + return 0; + } + if (client_id < 0 || client_id >= ADM_CLIENT_ID_MAX) { + pr_err("%s: Invalid client id %d\n", __func__, + client_id); + return 0; + } + if (data->opcode == APR_BASIC_RSP_RESULT) { + pr_debug("%s: APR_BASIC_RSP_RESULT id 0x%x\n", + __func__, payload[0]); + if (payload[1] != 0) { + pr_err("%s: cmd = 0x%x returned error = 0x%x\n", + __func__, payload[0], payload[1]); + } + switch (payload[0]) { + case ADM_CMD_SET_PP_PARAMS_V5: + pr_debug("%s: ADM_CMD_SET_PP_PARAMS_V5\n", + __func__); + if (client_id == ADM_CLIENT_ID_SOURCE_TRACKING) + this_adm.sourceTrackingData. + apr_cmd_status = payload[1]; + else if (rtac_make_adm_callback(payload, + data->payload_size)) + break; + /* + * if soft volume is called and already + * interrupted break out of the sequence here + */ + case ADM_CMD_DEVICE_OPEN_V5: + case ADM_CMD_DEVICE_CLOSE_V5: + case ADM_CMD_DEVICE_OPEN_V6: + pr_debug("%s: Basic callback received, wake up.\n", + __func__); + atomic_set(&this_adm.copp.stat[port_idx] + [copp_idx], payload[1]); + wake_up( + &this_adm.copp.wait[port_idx][copp_idx]); + break; + case ADM_CMD_ADD_TOPOLOGIES: + pr_debug("%s: callback received, ADM_CMD_ADD_TOPOLOGIES.\n", + __func__); + atomic_set(&this_adm.adm_stat, payload[1]); + wake_up(&this_adm.adm_wait); + break; + case ADM_CMD_MATRIX_MAP_ROUTINGS_V5: + case ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5: + pr_debug("%s: Basic callback received, wake up.\n", + __func__); + atomic_set(&this_adm.matrix_map_stat, + payload[1]); + wake_up(&this_adm.matrix_map_wait); + break; + case ADM_CMD_SHARED_MEM_UNMAP_REGIONS: + pr_debug("%s: ADM_CMD_SHARED_MEM_UNMAP_REGIONS\n", + __func__); + atomic_set(&this_adm.adm_stat, payload[1]); + wake_up(&this_adm.adm_wait); + break; + case ADM_CMD_SHARED_MEM_MAP_REGIONS: + pr_debug("%s: ADM_CMD_SHARED_MEM_MAP_REGIONS\n", + __func__); + /* Should only come here if there is an APR */ + /* error or malformed APR packet. Otherwise */ + /* response will be returned as */ + if (payload[1] != 0) { + pr_err("%s: ADM map error, resuming\n", + __func__); + atomic_set(&this_adm.adm_stat, + payload[1]); + wake_up(&this_adm.adm_wait); + } + break; + case ADM_CMD_GET_PP_PARAMS_V5: + pr_debug("%s: ADM_CMD_GET_PP_PARAMS_V5\n", + __func__); + /* Should only come here if there is an APR */ + /* error or malformed APR packet. Otherwise */ + /* response will be returned as */ + /* ADM_CMDRSP_GET_PP_PARAMS_V5 */ + if (client_id == + ADM_CLIENT_ID_SOURCE_TRACKING) { + this_adm.sourceTrackingData. + apr_cmd_status = payload[1]; + if (payload[1] != 0) + pr_err("%s: ADM get param error = %d\n", + __func__, payload[1]); + + atomic_set(&this_adm.copp.stat + [port_idx][copp_idx], + payload[1]); + wake_up(&this_adm.copp.wait + [port_idx][copp_idx]); + } else { + if (payload[1] != 0) { + pr_err("%s: ADM get param error = %d, resuming\n", + __func__, payload[1]); + + rtac_make_adm_callback(payload, + data->payload_size); + } + } + break; + case ADM_CMD_SET_PSPD_MTMX_STRTR_PARAMS_V5: + pr_debug("%s: ADM_CMD_SET_PSPD_MTMX_STRTR_PARAMS_V5\n", + __func__); + atomic_set(&this_adm.copp.stat[port_idx] + [copp_idx], payload[1]); + wake_up( + &this_adm.copp.wait[port_idx][copp_idx]); + break; + case ADM_CMD_GET_PP_TOPO_MODULE_LIST: + pr_debug("%s:ADM_CMD_GET_PP_TOPO_MODULE_LIST\n", + __func__); + if (payload[1] != 0) + pr_err("%s: ADM get topo list error = %d,\n", + __func__, payload[1]); + break; + default: + pr_err("%s: Unknown Cmd: 0x%x\n", __func__, + payload[0]); + break; + } + return 0; + } + + switch (data->opcode) { + case ADM_CMDRSP_DEVICE_OPEN_V5: + case ADM_CMDRSP_DEVICE_OPEN_V6: { + struct adm_cmd_rsp_device_open_v5 *open = + (struct adm_cmd_rsp_device_open_v5 *)data->payload; + + if (open->copp_id == INVALID_COPP_ID) { + pr_err("%s: invalid coppid rxed %d\n", + __func__, open->copp_id); + atomic_set(&this_adm.copp.stat[port_idx] + [copp_idx], ADSP_EBADPARAM); + wake_up( + &this_adm.copp.wait[port_idx][copp_idx]); + break; + } + atomic_set(&this_adm.copp.stat + [port_idx][copp_idx], payload[0]); + atomic_set(&this_adm.copp.id[port_idx][copp_idx], + open->copp_id); + pr_debug("%s: coppid rxed=%d\n", __func__, + open->copp_id); + wake_up(&this_adm.copp.wait[port_idx][copp_idx]); + } + break; + case ADM_CMDRSP_GET_PP_PARAMS_V5: + pr_debug("%s: ADM_CMDRSP_GET_PP_PARAMS_V5\n", __func__); + if (payload[0] != 0) + pr_err("%s: ADM_CMDRSP_GET_PP_PARAMS_V5 returned error = 0x%x\n", + __func__, payload[0]); + if (client_id == ADM_CLIENT_ID_SOURCE_TRACKING) + this_adm.sourceTrackingData.apr_cmd_status = + payload[0]; + else if (rtac_make_adm_callback(payload, + data->payload_size)) + break; + + idx = ADM_GET_PARAMETER_LENGTH * copp_idx; + if ((payload[0] == 0) && (data->payload_size > + (4 * sizeof(*payload))) && + (data->payload_size - 4 >= + payload[3]) && + (ARRAY_SIZE(adm_get_parameters) > + idx) && + (ARRAY_SIZE(adm_get_parameters)-idx-1 >= + payload[3])) { + adm_get_parameters[idx] = payload[3] / + sizeof(uint32_t); + /* + * payload[3] is param_size which is + * expressed in number of bytes + */ + pr_debug("%s: GET_PP PARAM:received parameter length: 0x%x\n", + __func__, adm_get_parameters[idx]); + /* storing param size then params */ + for (i = 0; i < payload[3] / + sizeof(uint32_t); i++) + adm_get_parameters[idx+1+i] = + payload[4+i]; + } else if (payload[0] == 0) { + adm_get_parameters[idx] = -1; + pr_err("%s: Out of band case, setting size to %d\n", + __func__, adm_get_parameters[idx]); + } else { + adm_get_parameters[idx] = -1; + pr_err("%s: GET_PP_PARAMS failed, setting size to %d\n", + __func__, adm_get_parameters[idx]); + } + atomic_set(&this_adm.copp.stat + [port_idx][copp_idx], payload[0]); + wake_up(&this_adm.copp.wait[port_idx][copp_idx]); + break; + case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST: + pr_debug("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST\n", + __func__); + if (payload[0] != 0) { + pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST", + __func__); + pr_err(":err = 0x%x\n", payload[0]); + } else if (payload[1] > + ((ADM_GET_TOPO_MODULE_LIST_LENGTH / + sizeof(uint32_t)) - 1)) { + pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST", + __func__); + pr_err(":size = %d\n", payload[1]); + } else { + idx = ADM_GET_TOPO_MODULE_LIST_LENGTH * + copp_idx; + pr_debug("%s:Num modules payload[1] %d\n", + __func__, payload[1]); + adm_module_topo_list[idx] = payload[1]; + for (i = 1; i <= payload[1]; i++) { + adm_module_topo_list[idx+i] = + payload[1+i]; + pr_debug("%s:payload[%d] = %x\n", + __func__, (i+1), payload[1+i]); + } + } + atomic_set(&this_adm.copp.stat + [port_idx][copp_idx], payload[0]); + wake_up(&this_adm.copp.wait[port_idx][copp_idx]); + break; + case ADM_CMDRSP_SHARED_MEM_MAP_REGIONS: + pr_debug("%s: ADM_CMDRSP_SHARED_MEM_MAP_REGIONS\n", + __func__); + atomic_set(&this_adm.mem_map_handles[ + atomic_read(&this_adm.mem_map_index)], + *payload); + atomic_set(&this_adm.adm_stat, 0); + wake_up(&this_adm.adm_wait); + break; + default: + pr_err("%s: Unknown cmd:0x%x\n", __func__, + data->opcode); + break; + } + } + return 0; +} + +static int adm_memory_map_regions(phys_addr_t *buf_add, uint32_t mempool_id, + uint32_t *bufsz, uint32_t bufcnt) +{ + struct avs_cmd_shared_mem_map_regions *mmap_regions = NULL; + struct avs_shared_map_region_payload *mregions = NULL; + void *mmap_region_cmd = NULL; + void *payload = NULL; + int ret = 0; + int i = 0; + int cmd_size = 0; + + pr_debug("%s:\n", __func__); + if (this_adm.apr == NULL) { + this_adm.apr = apr_register("ADSP", "ADM", adm_callback, + 0xFFFFFFFF, &this_adm); + if (this_adm.apr == NULL) { + pr_err("%s: Unable to register ADM\n", __func__); + ret = -ENODEV; + return ret; + } + rtac_set_adm_handle(this_adm.apr); + } + + cmd_size = sizeof(struct avs_cmd_shared_mem_map_regions) + + sizeof(struct avs_shared_map_region_payload) + * bufcnt; + + mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL); + if (!mmap_region_cmd) + return -ENOMEM; + + mmap_regions = (struct avs_cmd_shared_mem_map_regions *)mmap_region_cmd; + mmap_regions->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mmap_regions->hdr.pkt_size = cmd_size; + mmap_regions->hdr.src_port = 0; + + mmap_regions->hdr.dest_port = 0; + mmap_regions->hdr.token = 0; + mmap_regions->hdr.opcode = ADM_CMD_SHARED_MEM_MAP_REGIONS; + mmap_regions->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL & 0x00ff; + mmap_regions->num_regions = bufcnt & 0x00ff; + mmap_regions->property_flag = 0x00; + + pr_debug("%s: map_regions->num_regions = %d\n", __func__, + mmap_regions->num_regions); + payload = ((u8 *) mmap_region_cmd + + sizeof(struct avs_cmd_shared_mem_map_regions)); + mregions = (struct avs_shared_map_region_payload *)payload; + + for (i = 0; i < bufcnt; i++) { + mregions->shm_addr_lsw = lower_32_bits(buf_add[i]); + mregions->shm_addr_msw = + msm_audio_populate_upper_32_bits(buf_add[i]); + mregions->mem_size_bytes = bufsz[i]; + ++mregions; + } + + atomic_set(&this_adm.adm_stat, -1); + ret = apr_send_pkt(this_adm.apr, (uint32_t *) mmap_region_cmd); + if (ret < 0) { + pr_err("%s: mmap_regions op[0x%x]rc[%d]\n", __func__, + mmap_regions->hdr.opcode, ret); + ret = -EINVAL; + goto fail_cmd; + } + + ret = wait_event_timeout(this_adm.adm_wait, + atomic_read(&this_adm.adm_stat) >= 0, + 5 * HZ); + if (!ret) { + pr_err("%s: timeout. waited for memory_map\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } else if (atomic_read(&this_adm.adm_stat) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.adm_stat))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.adm_stat)); + goto fail_cmd; + } +fail_cmd: + kfree(mmap_region_cmd); + return ret; +} + +static int adm_memory_unmap_regions(void) +{ + struct avs_cmd_shared_mem_unmap_regions unmap_regions; + int ret = 0; + + pr_debug("%s:\n", __func__); + if (this_adm.apr == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + + unmap_regions.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + unmap_regions.hdr.pkt_size = sizeof(unmap_regions); + unmap_regions.hdr.src_port = 0; + unmap_regions.hdr.dest_port = 0; + unmap_regions.hdr.token = 0; + unmap_regions.hdr.opcode = ADM_CMD_SHARED_MEM_UNMAP_REGIONS; + unmap_regions.mem_map_handle = atomic_read(&this_adm. + mem_map_handles[atomic_read(&this_adm.mem_map_index)]); + atomic_set(&this_adm.adm_stat, -1); + ret = apr_send_pkt(this_adm.apr, (uint32_t *) &unmap_regions); + if (ret < 0) { + pr_err("%s: mmap_regions op[0x%x]rc[%d]\n", __func__, + unmap_regions.hdr.opcode, ret); + ret = -EINVAL; + goto fail_cmd; + } + + ret = wait_event_timeout(this_adm.adm_wait, + atomic_read(&this_adm.adm_stat) >= 0, + 5 * HZ); + if (!ret) { + pr_err("%s: timeout. waited for memory_unmap\n", + __func__); + ret = -EINVAL; + goto fail_cmd; + } else if (atomic_read(&this_adm.adm_stat) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.adm_stat))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.adm_stat)); + goto fail_cmd; + } else { + pr_debug("%s: Unmap handle 0x%x succeeded\n", __func__, + unmap_regions.mem_map_handle); + } +fail_cmd: + return ret; +} + +static int remap_cal_data(struct cal_block_data *cal_block, int cal_index) +{ + int ret = 0; + + if (cal_block->map_data.ion_client == NULL) { + pr_err("%s: No ION allocation for cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + if ((cal_block->map_data.map_size > 0) && + (cal_block->map_data.q6map_handle == 0)) { + atomic_set(&this_adm.mem_map_index, cal_index); + ret = adm_memory_map_regions(&cal_block->cal_data.paddr, 0, + (uint32_t *)&cal_block->map_data.map_size, 1); + if (ret < 0) { + pr_err("%s: ADM mmap did not work! size = %zd ret %d\n", + __func__, + cal_block->map_data.map_size, ret); + pr_debug("%s: ADM mmap did not work! addr = 0x%pK, size = %zd ret %d\n", + __func__, + &cal_block->cal_data.paddr, + cal_block->map_data.map_size, ret); + goto done; + } + cal_block->map_data.q6map_handle = atomic_read(&this_adm. + mem_map_handles[cal_index]); + } +done: + return ret; +} + +static void send_adm_custom_topology(void) +{ + struct cal_block_data *cal_block = NULL; + struct cmd_set_topologies adm_top; + int cal_index = ADM_CUSTOM_TOP_CAL; + int result; + + if (this_adm.cal_data[cal_index] == NULL) + goto done; + + mutex_lock(&this_adm.cal_data[cal_index]->lock); + if (!this_adm.set_custom_topology) + goto unlock; + this_adm.set_custom_topology = 0; + + cal_block = cal_utils_get_only_cal_block(this_adm.cal_data[cal_index]); + if (cal_block == NULL) + goto unlock; + + pr_debug("%s: Sending cal_index %d\n", __func__, cal_index); + + result = remap_cal_data(cal_block, cal_index); + if (result) { + pr_err("%s: Remap_cal_data failed for cal %d!\n", + __func__, cal_index); + goto unlock; + } + atomic_set(&this_adm.mem_map_index, cal_index); + atomic_set(&this_adm.mem_map_handles[cal_index], + cal_block->map_data.q6map_handle); + + if (cal_block->cal_data.size == 0) { + pr_debug("%s: No ADM cal to send\n", __func__); + goto unlock; + } + + adm_top.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(20), APR_PKT_VER); + adm_top.hdr.pkt_size = sizeof(adm_top); + adm_top.hdr.src_svc = APR_SVC_ADM; + adm_top.hdr.src_domain = APR_DOMAIN_APPS; + adm_top.hdr.src_port = 0; + adm_top.hdr.dest_svc = APR_SVC_ADM; + adm_top.hdr.dest_domain = APR_DOMAIN_ADSP; + adm_top.hdr.dest_port = 0; + adm_top.hdr.token = 0; + adm_top.hdr.opcode = ADM_CMD_ADD_TOPOLOGIES; + adm_top.payload_addr_lsw = lower_32_bits(cal_block->cal_data.paddr); + adm_top.payload_addr_msw = msm_audio_populate_upper_32_bits( + cal_block->cal_data.paddr); + adm_top.mem_map_handle = cal_block->map_data.q6map_handle; + adm_top.payload_size = cal_block->cal_data.size; + + atomic_set(&this_adm.adm_stat, -1); + pr_debug("%s: Sending ADM_CMD_ADD_TOPOLOGIES payload = 0x%pK, size = %d\n", + __func__, &cal_block->cal_data.paddr, + adm_top.payload_size); + result = apr_send_pkt(this_adm.apr, (uint32_t *)&adm_top); + if (result < 0) { + pr_err("%s: Set topologies failed payload size = %zd result %d\n", + __func__, cal_block->cal_data.size, result); + goto unlock; + } + /* Wait for the callback */ + result = wait_event_timeout(this_adm.adm_wait, + atomic_read(&this_adm.adm_stat) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!result) { + pr_err("%s: Set topologies timed out payload size = %zd\n", + __func__, cal_block->cal_data.size); + goto unlock; + } else if (atomic_read(&this_adm.adm_stat) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.adm_stat))); + result = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.adm_stat)); + goto unlock; + } +unlock: + mutex_unlock(&this_adm.cal_data[cal_index]->lock); +done: + return; +} + +static int send_adm_cal_block(int port_id, int copp_idx, + struct cal_block_data *cal_block, int perf_mode, + int app_type, int acdb_id, int sample_rate) +{ + s32 result = 0; + struct adm_cmd_set_pp_params_v5 adm_params; + int port_idx; + + pr_debug("%s: Port id 0x%x sample_rate %d ,\n", __func__, + port_id, sample_rate); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + return -EINVAL; + } + if (!cal_block) { + pr_debug("%s: No ADM cal to send for port_id = 0x%x!\n", + __func__, port_id); + result = -EINVAL; + goto done; + } + if (cal_block->cal_data.size <= 0) { + pr_debug("%s: No ADM cal send for port_id = 0x%x!\n", + __func__, port_id); + result = -EINVAL; + goto done; + } + + if (perf_mode == LEGACY_PCM_MODE && + ((atomic_read(&this_adm.copp.topology[port_idx][copp_idx])) == + DS2_ADM_COPP_TOPOLOGY_ID)) { + pr_err("%s: perf_mode %d, topology 0x%x\n", __func__, perf_mode, + atomic_read( + &this_adm.copp.topology[port_idx][copp_idx])); + goto done; + } + + adm_params.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(20), APR_PKT_VER); + adm_params.hdr.pkt_size = sizeof(adm_params); + adm_params.hdr.src_svc = APR_SVC_ADM; + adm_params.hdr.src_domain = APR_DOMAIN_APPS; + adm_params.hdr.src_port = port_id; + adm_params.hdr.dest_svc = APR_SVC_ADM; + adm_params.hdr.dest_domain = APR_DOMAIN_ADSP; + + adm_params.hdr.token = port_idx << 16 | copp_idx; + adm_params.hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + adm_params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + adm_params.payload_addr_lsw = lower_32_bits(cal_block->cal_data.paddr); + adm_params.payload_addr_msw = msm_audio_populate_upper_32_bits( + cal_block->cal_data.paddr); + adm_params.mem_map_handle = cal_block->map_data.q6map_handle; + adm_params.payload_size = cal_block->cal_data.size; + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + pr_debug("%s: Sending SET_PARAMS payload = 0x%pK, size = %d\n", + __func__, &cal_block->cal_data.paddr, + adm_params.payload_size); + result = apr_send_pkt(this_adm.apr, (uint32_t *)&adm_params); + if (result < 0) { + pr_err("%s: Set params failed port 0x%x result %d\n", + __func__, port_id, result); + pr_debug("%s: Set params failed port = 0x%x payload = 0x%pK result %d\n", + __func__, port_id, &cal_block->cal_data.paddr, result); + result = -EINVAL; + goto done; + } + /* Wait for the callback */ + result = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!result) { + pr_err("%s: Set params timed out port = 0x%x\n", + __func__, port_id); + pr_debug("%s: Set params timed out port = 0x%x, payload = 0x%pK\n", + __func__, port_id, &cal_block->cal_data.paddr); + result = -EINVAL; + goto done; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + result = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto done; + } + +done: + return result; +} + +static struct cal_block_data *adm_find_cal_by_path(int cal_index, int path) +{ + struct list_head *ptr, *next; + struct cal_block_data *cal_block = NULL; + struct audio_cal_info_audproc *audproc_cal_info = NULL; + struct audio_cal_info_audvol *audvol_cal_info = NULL; + + pr_debug("%s:\n", __func__); + + list_for_each_safe(ptr, next, + &this_adm.cal_data[cal_index]->cal_blocks) { + + cal_block = list_entry(ptr, + struct cal_block_data, list); + + if (cal_index == ADM_AUDPROC_CAL) { + audproc_cal_info = cal_block->cal_info; + if ((audproc_cal_info->path == path) && + (cal_block->cal_data.size > 0)) + return cal_block; + } else if (cal_index == ADM_AUDVOL_CAL) { + audvol_cal_info = cal_block->cal_info; + if ((audvol_cal_info->path == path) && + (cal_block->cal_data.size > 0)) + return cal_block; + } + } + pr_debug("%s: Can't find ADM cal for cal_index %d, path %d\n", + __func__, cal_index, path); + return NULL; +} + +static struct cal_block_data *adm_find_cal_by_app_type(int cal_index, int path, + int app_type) +{ + struct list_head *ptr, *next; + struct cal_block_data *cal_block = NULL; + struct audio_cal_info_audproc *audproc_cal_info = NULL; + struct audio_cal_info_audvol *audvol_cal_info = NULL; + + pr_debug("%s\n", __func__); + + list_for_each_safe(ptr, next, + &this_adm.cal_data[cal_index]->cal_blocks) { + + cal_block = list_entry(ptr, + struct cal_block_data, list); + + if (cal_index == ADM_AUDPROC_CAL) { + audproc_cal_info = cal_block->cal_info; + if ((audproc_cal_info->path == path) && + (audproc_cal_info->app_type == app_type) && + (cal_block->cal_data.size > 0)) + return cal_block; + } else if (cal_index == ADM_AUDVOL_CAL) { + audvol_cal_info = cal_block->cal_info; + if ((audvol_cal_info->path == path) && + (audvol_cal_info->app_type == app_type) && + (cal_block->cal_data.size > 0)) + return cal_block; + } + } + pr_debug("%s: Can't find ADM cali for cal_index %d, path %d, app %d, defaulting to search by path\n", + __func__, cal_index, path, app_type); + return adm_find_cal_by_path(cal_index, path); +} + + +static struct cal_block_data *adm_find_cal(int cal_index, int path, + int app_type, int acdb_id, + int sample_rate) +{ + struct list_head *ptr, *next; + struct cal_block_data *cal_block = NULL; + struct audio_cal_info_audproc *audproc_cal_info = NULL; + struct audio_cal_info_audvol *audvol_cal_info = NULL; + + pr_debug("%s:\n", __func__); + + list_for_each_safe(ptr, next, + &this_adm.cal_data[cal_index]->cal_blocks) { + + cal_block = list_entry(ptr, + struct cal_block_data, list); + + if (cal_index == ADM_AUDPROC_CAL) { + audproc_cal_info = cal_block->cal_info; + if ((audproc_cal_info->path == path) && + (audproc_cal_info->app_type == app_type) && + (audproc_cal_info->acdb_id == acdb_id) && + (audproc_cal_info->sample_rate == sample_rate) && + (cal_block->cal_data.size > 0)) + return cal_block; + } else if (cal_index == ADM_AUDVOL_CAL) { + audvol_cal_info = cal_block->cal_info; + if ((audvol_cal_info->path == path) && + (audvol_cal_info->app_type == app_type) && + (audvol_cal_info->acdb_id == acdb_id) && + (cal_block->cal_data.size > 0)) + return cal_block; + } + } + pr_debug("%s: Can't find ADM cal for cal_index %d, path %d, app %d, acdb_id %d sample_rate %d defaulting to search by app type\n", + __func__, cal_index, path, app_type, acdb_id, sample_rate); + return adm_find_cal_by_app_type(cal_index, path, app_type); +} + +static int adm_remap_and_send_cal_block(int cal_index, int port_id, + int copp_idx, struct cal_block_data *cal_block, int perf_mode, + int app_type, int acdb_id, int sample_rate) +{ + int ret = 0; + + pr_debug("%s: Sending cal_index cal %d\n", __func__, cal_index); + ret = remap_cal_data(cal_block, cal_index); + if (ret) { + pr_err("%s: Remap_cal_data failed for cal %d!\n", + __func__, cal_index); + goto done; + } + ret = send_adm_cal_block(port_id, copp_idx, cal_block, perf_mode, + app_type, acdb_id, sample_rate); + if (ret < 0) + pr_debug("%s: No cal sent for cal_index %d, port_id = 0x%x! ret %d sample_rate %d\n", + __func__, cal_index, port_id, ret, sample_rate); +done: + return ret; +} + +static void send_adm_cal_type(int cal_index, int path, int port_id, + int copp_idx, int perf_mode, int app_type, + int acdb_id, int sample_rate) +{ + struct cal_block_data *cal_block = NULL; + int ret; + + pr_debug("%s: cal index %d\n", __func__, cal_index); + + if (this_adm.cal_data[cal_index] == NULL) { + pr_debug("%s: cal_index %d not allocated!\n", + __func__, cal_index); + goto done; + } + + mutex_lock(&this_adm.cal_data[cal_index]->lock); + cal_block = adm_find_cal(cal_index, path, app_type, acdb_id, + sample_rate); + if (cal_block == NULL) + goto unlock; + + ret = adm_remap_and_send_cal_block(cal_index, port_id, copp_idx, + cal_block, perf_mode, app_type, acdb_id, sample_rate); +unlock: + mutex_unlock(&this_adm.cal_data[cal_index]->lock); +done: + return; +} + +static int get_cal_path(int path) +{ + if (path == 0x1) + return RX_DEVICE; + else + return TX_DEVICE; +} + +static void send_adm_cal(int port_id, int copp_idx, int path, int perf_mode, + int app_type, int acdb_id, int sample_rate) +{ + pr_debug("%s: port id 0x%x copp_idx %d\n", __func__, port_id, copp_idx); + + send_adm_cal_type(ADM_AUDPROC_CAL, path, port_id, copp_idx, perf_mode, + app_type, acdb_id, sample_rate); + send_adm_cal_type(ADM_AUDVOL_CAL, path, port_id, copp_idx, perf_mode, + app_type, acdb_id, sample_rate); +} + +int adm_connect_afe_port(int mode, int session_id, int port_id) +{ + struct adm_cmd_connect_afe_port_v5 cmd; + int ret = 0; + int port_idx, copp_idx = 0; + + pr_debug("%s: port_id: 0x%x session id:%d mode:%d\n", __func__, + port_id, session_id, mode); + + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + return -EINVAL; + } + + if (this_adm.apr == NULL) { + this_adm.apr = apr_register("ADSP", "ADM", adm_callback, + 0xFFFFFFFF, &this_adm); + if (this_adm.apr == NULL) { + pr_err("%s: Unable to register ADM\n", __func__); + ret = -ENODEV; + return ret; + } + rtac_set_adm_handle(this_adm.apr); + } + pr_debug("%s: Port ID 0x%x, index %d\n", __func__, port_id, port_idx); + + cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cmd.hdr.pkt_size = sizeof(cmd); + cmd.hdr.src_svc = APR_SVC_ADM; + cmd.hdr.src_domain = APR_DOMAIN_APPS; + cmd.hdr.src_port = port_id; + cmd.hdr.dest_svc = APR_SVC_ADM; + cmd.hdr.dest_domain = APR_DOMAIN_ADSP; + cmd.hdr.dest_port = 0; /* Ignored */ + cmd.hdr.token = port_idx << 16 | copp_idx; + cmd.hdr.opcode = ADM_CMD_CONNECT_AFE_PORT_V5; + + cmd.mode = mode; + cmd.session_id = session_id; + cmd.afe_port_id = port_id; + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + ret = apr_send_pkt(this_adm.apr, (uint32_t *)&cmd); + if (ret < 0) { + pr_err("%s: ADM enable for port_id: 0x%x failed ret %d\n", + __func__, port_id, ret); + ret = -EINVAL; + goto fail_cmd; + } + /* Wait for the callback with copp id */ + ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: ADM connect timedout for port_id: 0x%x\n", + __func__, port_id); + ret = -EINVAL; + goto fail_cmd; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto fail_cmd; + } + atomic_inc(&this_adm.copp.cnt[port_idx][copp_idx]); + return 0; + +fail_cmd: + + return ret; +} + +int adm_arrange_mch_map(struct adm_cmd_device_open_v5 *open, int path, + int channel_mode) +{ + int rc = 0, idx; + + memset(open->dev_channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + switch (path) { + case ADM_PATH_PLAYBACK: + idx = ADM_MCH_MAP_IDX_PLAYBACK; + break; + case ADM_PATH_LIVE_REC: + case ADM_PATH_NONLIVE_REC: + idx = ADM_MCH_MAP_IDX_REC; + break; + default: + goto non_mch_path; + }; + if ((open->dev_num_channel > 2) && multi_ch_maps[idx].set_channel_map) { + memcpy(open->dev_channel_mapping, + multi_ch_maps[idx].channel_mapping, + PCM_FORMAT_MAX_NUM_CHANNEL); + } else { + if (channel_mode == 1) { + open->dev_channel_mapping[0] = PCM_CHANNEL_FC; + } else if (channel_mode == 2) { + open->dev_channel_mapping[0] = PCM_CHANNEL_FL; + open->dev_channel_mapping[1] = PCM_CHANNEL_FR; + } else if (channel_mode == 3) { + open->dev_channel_mapping[0] = PCM_CHANNEL_FL; + open->dev_channel_mapping[1] = PCM_CHANNEL_FR; + open->dev_channel_mapping[2] = PCM_CHANNEL_FC; + } else if (channel_mode == 4) { + open->dev_channel_mapping[0] = PCM_CHANNEL_FL; + open->dev_channel_mapping[1] = PCM_CHANNEL_FR; + open->dev_channel_mapping[2] = PCM_CHANNEL_LS; + open->dev_channel_mapping[3] = PCM_CHANNEL_RS; + } else if (channel_mode == 5) { + open->dev_channel_mapping[0] = PCM_CHANNEL_FL; + open->dev_channel_mapping[1] = PCM_CHANNEL_FR; + open->dev_channel_mapping[2] = PCM_CHANNEL_FC; + open->dev_channel_mapping[3] = PCM_CHANNEL_LS; + open->dev_channel_mapping[4] = PCM_CHANNEL_RS; + } else if (channel_mode == 6) { + open->dev_channel_mapping[0] = PCM_CHANNEL_FL; + open->dev_channel_mapping[1] = PCM_CHANNEL_FR; + open->dev_channel_mapping[2] = PCM_CHANNEL_LFE; + open->dev_channel_mapping[3] = PCM_CHANNEL_FC; + open->dev_channel_mapping[4] = PCM_CHANNEL_LS; + open->dev_channel_mapping[5] = PCM_CHANNEL_RS; + } else if (channel_mode == 7) { + open->dev_channel_mapping[0] = PCM_CHANNEL_FL; + open->dev_channel_mapping[1] = PCM_CHANNEL_FR; + open->dev_channel_mapping[2] = PCM_CHANNEL_FC; + open->dev_channel_mapping[3] = PCM_CHANNEL_LFE; + open->dev_channel_mapping[4] = PCM_CHANNEL_LB; + open->dev_channel_mapping[5] = PCM_CHANNEL_RB; + open->dev_channel_mapping[6] = PCM_CHANNEL_CS; + } else if (channel_mode == 8) { + open->dev_channel_mapping[0] = PCM_CHANNEL_FL; + open->dev_channel_mapping[1] = PCM_CHANNEL_FR; + open->dev_channel_mapping[2] = PCM_CHANNEL_LFE; + open->dev_channel_mapping[3] = PCM_CHANNEL_FC; + open->dev_channel_mapping[4] = PCM_CHANNEL_LS; + open->dev_channel_mapping[5] = PCM_CHANNEL_RS; + open->dev_channel_mapping[6] = PCM_CHANNEL_LB; + open->dev_channel_mapping[7] = PCM_CHANNEL_RB; + } else { + pr_err("%s: invalid num_chan %d\n", __func__, + channel_mode); + rc = -EINVAL; + goto inval_ch_mod; + } + } + +non_mch_path: +inval_ch_mod: + return rc; +} + +int adm_arrange_mch_ep2_map(struct adm_cmd_device_open_v6 *open_v6, + int channel_mode) +{ + int rc = 0; + + memset(open_v6->dev_channel_mapping_eid2, 0, + PCM_FORMAT_MAX_NUM_CHANNEL); + + if (channel_mode == 1) { + open_v6->dev_channel_mapping_eid2[0] = PCM_CHANNEL_FC; + } else if (channel_mode == 2) { + open_v6->dev_channel_mapping_eid2[0] = PCM_CHANNEL_FL; + open_v6->dev_channel_mapping_eid2[1] = PCM_CHANNEL_FR; + } else if (channel_mode == 3) { + open_v6->dev_channel_mapping_eid2[0] = PCM_CHANNEL_FL; + open_v6->dev_channel_mapping_eid2[1] = PCM_CHANNEL_FR; + open_v6->dev_channel_mapping_eid2[2] = PCM_CHANNEL_FC; + } else if (channel_mode == 4) { + open_v6->dev_channel_mapping_eid2[0] = PCM_CHANNEL_FL; + open_v6->dev_channel_mapping_eid2[1] = PCM_CHANNEL_FR; + open_v6->dev_channel_mapping_eid2[2] = PCM_CHANNEL_LS; + open_v6->dev_channel_mapping_eid2[3] = PCM_CHANNEL_RS; + } else if (channel_mode == 5) { + open_v6->dev_channel_mapping_eid2[0] = PCM_CHANNEL_FL; + open_v6->dev_channel_mapping_eid2[1] = PCM_CHANNEL_FR; + open_v6->dev_channel_mapping_eid2[2] = PCM_CHANNEL_FC; + open_v6->dev_channel_mapping_eid2[3] = PCM_CHANNEL_LS; + open_v6->dev_channel_mapping_eid2[4] = PCM_CHANNEL_RS; + } else if (channel_mode == 6) { + open_v6->dev_channel_mapping_eid2[0] = PCM_CHANNEL_FL; + open_v6->dev_channel_mapping_eid2[1] = PCM_CHANNEL_FR; + open_v6->dev_channel_mapping_eid2[2] = PCM_CHANNEL_LFE; + open_v6->dev_channel_mapping_eid2[3] = PCM_CHANNEL_FC; + open_v6->dev_channel_mapping_eid2[4] = PCM_CHANNEL_LS; + open_v6->dev_channel_mapping_eid2[5] = PCM_CHANNEL_RS; + } else if (channel_mode == 8) { + open_v6->dev_channel_mapping_eid2[0] = PCM_CHANNEL_FL; + open_v6->dev_channel_mapping_eid2[1] = PCM_CHANNEL_FR; + open_v6->dev_channel_mapping_eid2[2] = PCM_CHANNEL_LFE; + open_v6->dev_channel_mapping_eid2[3] = PCM_CHANNEL_FC; + open_v6->dev_channel_mapping_eid2[4] = PCM_CHANNEL_LS; + open_v6->dev_channel_mapping_eid2[5] = PCM_CHANNEL_RS; + open_v6->dev_channel_mapping_eid2[6] = PCM_CHANNEL_LB; + open_v6->dev_channel_mapping_eid2[7] = PCM_CHANNEL_RB; + } else { + pr_err("%s: invalid num_chan %d\n", __func__, + channel_mode); + rc = -EINVAL; + } + + return rc; +} + +int adm_open(int port_id, int path, int rate, int channel_mode, int topology, + int perf_mode, uint16_t bit_width, int app_type, int acdb_id) +{ + struct adm_cmd_device_open_v5 open; + struct adm_cmd_device_open_v6 open_v6; + int ret = 0; + int port_idx, copp_idx, flags; + int tmp_port = q6audio_get_port_id(port_id); + + pr_debug("%s:port %#x path:%d rate:%d mode:%d perf_mode:%d,topo_id %d\n", + __func__, port_id, path, rate, channel_mode, perf_mode, + topology); + + port_id = q6audio_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + return -EINVAL; + } + + if (this_adm.apr == NULL) { + this_adm.apr = apr_register("ADSP", "ADM", adm_callback, + 0xFFFFFFFF, &this_adm); + if (this_adm.apr == NULL) { + pr_err("%s: Unable to register ADM\n", __func__); + return -ENODEV; + } + rtac_set_adm_handle(this_adm.apr); + } + + if (perf_mode == ULL_POST_PROCESSING_PCM_MODE) { + flags = ADM_ULL_POST_PROCESSING_DEVICE_SESSION; + if ((topology == DOLBY_ADM_COPP_TOPOLOGY_ID) || + (topology == DS2_ADM_COPP_TOPOLOGY_ID) || + (topology == SRS_TRUMEDIA_TOPOLOGY_ID)) + topology = DEFAULT_COPP_TOPOLOGY; + } else if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE) { + flags = ADM_ULTRA_LOW_LATENCY_DEVICE_SESSION; + topology = NULL_COPP_TOPOLOGY; + rate = ULL_SUPPORTED_SAMPLE_RATE; + bit_width = ULL_SUPPORTED_BITS_PER_SAMPLE; + } else if (perf_mode == LOW_LATENCY_PCM_MODE) { + flags = ADM_LOW_LATENCY_DEVICE_SESSION; + if ((topology == DOLBY_ADM_COPP_TOPOLOGY_ID) || + (topology == DS2_ADM_COPP_TOPOLOGY_ID) || + (topology == SRS_TRUMEDIA_TOPOLOGY_ID)) + topology = DEFAULT_COPP_TOPOLOGY; + } else { + if ((path == ADM_PATH_COMPRESSED_RX) || + (path == ADM_PATH_COMPRESSED_TX)) + flags = 0; + else + flags = ADM_LEGACY_DEVICE_SESSION; + } + + if ((topology == VPM_TX_SM_ECNS_COPP_TOPOLOGY) || + (topology == VPM_TX_DM_FLUENCE_COPP_TOPOLOGY) || + (topology == VPM_TX_DM_RFECNS_COPP_TOPOLOGY)) + rate = 16000; + + copp_idx = adm_get_idx_if_copp_exists(port_idx, topology, perf_mode, + rate, bit_width, app_type); + if (copp_idx < 0) { + copp_idx = adm_get_next_available_copp(port_idx); + if (copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: exceeded copp id %d\n", + __func__, copp_idx); + return -EINVAL; + } + atomic_set(&this_adm.copp.cnt[port_idx][copp_idx], 0); + atomic_set(&this_adm.copp.topology[port_idx][copp_idx], + topology); + atomic_set(&this_adm.copp.mode[port_idx][copp_idx], + perf_mode); + atomic_set(&this_adm.copp.rate[port_idx][copp_idx], + rate); + atomic_set(&this_adm.copp.channels[port_idx][copp_idx], + channel_mode); + atomic_set(&this_adm.copp.bit_width[port_idx][copp_idx], + bit_width); + atomic_set(&this_adm.copp.app_type[port_idx][copp_idx], + app_type); + atomic_set(&this_adm.copp.acdb_id[port_idx][copp_idx], + acdb_id); + set_bit(ADM_STATUS_CALIBRATION_REQUIRED, + (void *)&this_adm.copp.adm_status[port_idx][copp_idx]); + if ((path != ADM_PATH_COMPRESSED_RX) && + (path != ADM_PATH_COMPRESSED_TX)) + send_adm_custom_topology(); + } + + if (this_adm.copp.adm_delay[port_idx][copp_idx] && + perf_mode == LEGACY_PCM_MODE) { + atomic_set(&this_adm.copp.adm_delay_stat[port_idx][copp_idx], + 1); + this_adm.copp.adm_delay[port_idx][copp_idx] = 0; + wake_up(&this_adm.copp.adm_delay_wait[port_idx][copp_idx]); + } + + /* Create a COPP if port id are not enabled */ + if (atomic_read(&this_adm.copp.cnt[port_idx][copp_idx]) == 0) { + pr_debug("%s: open ADM: port_idx: %d, copp_idx: %d\n", __func__, + port_idx, copp_idx); + if ((topology == SRS_TRUMEDIA_TOPOLOGY_ID) && + perf_mode == LEGACY_PCM_MODE) { + int res; + + atomic_set(&this_adm.mem_map_index, ADM_SRS_TRUMEDIA); + msm_dts_srs_tm_ion_memmap(&this_adm.outband_memmap); + res = adm_memory_map_regions(&this_adm.outband_memmap.paddr, 0, + (uint32_t *)&this_adm.outband_memmap.size, 1); + if (res < 0) { + pr_err("%s: SRS adm_memory_map_regions failed ! addr = 0x%pK, size = %d\n", + __func__, (void *)this_adm.outband_memmap.paddr, + (uint32_t)this_adm.outband_memmap.size); + } + } + open.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + open.hdr.pkt_size = sizeof(open); + open.hdr.src_svc = APR_SVC_ADM; + open.hdr.src_domain = APR_DOMAIN_APPS; + open.hdr.src_port = tmp_port; + open.hdr.dest_svc = APR_SVC_ADM; + open.hdr.dest_domain = APR_DOMAIN_ADSP; + open.hdr.dest_port = tmp_port; + open.hdr.token = port_idx << 16 | copp_idx; + open.hdr.opcode = ADM_CMD_DEVICE_OPEN_V5; + open.flags = flags; + open.mode_of_operation = path; + open.endpoint_id_1 = tmp_port; + open.endpoint_id_2 = 0xFFFF; + + if (this_adm.ec_ref_rx && (path != 1)) { + open.endpoint_id_2 = this_adm.ec_ref_rx; + this_adm.ec_ref_rx = -1; + } + + open.topology_id = topology; + + open.dev_num_channel = channel_mode & 0x00FF; + open.bit_width = bit_width; + WARN_ON((perf_mode == ULTRA_LOW_LATENCY_PCM_MODE) && + (rate != ULL_SUPPORTED_SAMPLE_RATE)); + open.sample_rate = rate; + + ret = adm_arrange_mch_map(&open, path, channel_mode); + + if (ret) + return ret; + + pr_debug("%s: port_id=0x%x rate=%d topology_id=0x%X\n", + __func__, open.endpoint_id_1, open.sample_rate, + open.topology_id); + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + + if ((this_adm.num_ec_ref_rx_chans != 0) && (path != 1) && + (open.endpoint_id_2 != 0xFFFF)) { + memset(&open_v6, 0, + sizeof(struct adm_cmd_device_open_v6)); + memcpy(&open_v6, &open, + sizeof(struct adm_cmd_device_open_v5)); + open_v6.hdr.opcode = ADM_CMD_DEVICE_OPEN_V6; + open_v6.hdr.pkt_size = sizeof(open_v6); + open_v6.dev_num_channel_eid2 = + this_adm.num_ec_ref_rx_chans; + this_adm.num_ec_ref_rx_chans = 0; + + if (this_adm.ec_ref_rx_bit_width != 0) { + open_v6.bit_width_eid2 = + this_adm.ec_ref_rx_bit_width; + this_adm.ec_ref_rx_bit_width = 0; + } else { + open_v6.bit_width_eid2 = bit_width; + } + + if (this_adm.ec_ref_rx_sampling_rate != 0) { + open_v6.sample_rate_eid2 = + this_adm.ec_ref_rx_sampling_rate; + this_adm.ec_ref_rx_sampling_rate = 0; + } else { + open_v6.sample_rate_eid2 = rate; + } + + pr_debug("%s: eid2_channels=%d eid2_bit_width=%d eid2_rate=%d\n", + __func__, open_v6.dev_num_channel_eid2, + open_v6.bit_width_eid2, + open_v6.sample_rate_eid2); + + ret = adm_arrange_mch_ep2_map(&open_v6, + open_v6.dev_num_channel_eid2); + + if (ret) + return ret; + + ret = apr_send_pkt(this_adm.apr, (uint32_t *)&open_v6); + } else { + ret = apr_send_pkt(this_adm.apr, (uint32_t *)&open); + } + if (ret < 0) { + pr_err("%s: port_id: 0x%x for[0x%x] failed %d\n", + __func__, tmp_port, port_id, ret); + return -EINVAL; + } + /* Wait for the callback with copp id */ + ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: ADM open timedout for port_id: 0x%x for [0x%x]\n", + __func__, tmp_port, port_id); + return -EINVAL; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + return adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + } + } + atomic_inc(&this_adm.copp.cnt[port_idx][copp_idx]); + return copp_idx; +} + +void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate) +{ + struct audproc_mfc_output_media_fmt mfc_cfg; + struct adm_cmd_device_open_v5 open; + int port_idx; + int sz = 0; + int rc = 0; + int i = 0; + + port_id = q6audio_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + + if (port_idx < 0) { + pr_err("%s: Invalid port_id %#x\n", __func__, port_id); + goto fail_cmd; + } + + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); + goto fail_cmd; + } + + sz = sizeof(struct audproc_mfc_output_media_fmt); + + mfc_cfg.params.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + mfc_cfg.params.hdr.pkt_size = sz; + mfc_cfg.params.hdr.src_svc = APR_SVC_ADM; + mfc_cfg.params.hdr.src_domain = APR_DOMAIN_APPS; + mfc_cfg.params.hdr.src_port = port_id; + mfc_cfg.params.hdr.dest_svc = APR_SVC_ADM; + mfc_cfg.params.hdr.dest_domain = APR_DOMAIN_ADSP; + mfc_cfg.params.hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + mfc_cfg.params.hdr.token = port_idx << 16 | copp_idx; + mfc_cfg.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + mfc_cfg.params.payload_addr_lsw = 0; + mfc_cfg.params.payload_addr_msw = 0; + mfc_cfg.params.mem_map_handle = 0; + mfc_cfg.params.payload_size = sizeof(mfc_cfg) - + sizeof(mfc_cfg.params); + mfc_cfg.data.module_id = AUDPROC_MODULE_ID_MFC; + mfc_cfg.data.param_id = + AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; + mfc_cfg.data.param_size = mfc_cfg.params.payload_size - + sizeof(mfc_cfg.data); + mfc_cfg.data.reserved = 0; + mfc_cfg.sampling_rate = dst_sample_rate; + mfc_cfg.bits_per_sample = + atomic_read(&this_adm.copp.bit_width[port_idx][copp_idx]); + open.dev_num_channel = mfc_cfg.num_channels = + atomic_read(&this_adm.copp.channels[port_idx][copp_idx]); + + rc = adm_arrange_mch_map(&open, ADM_PATH_PLAYBACK, + mfc_cfg.num_channels); + if (rc < 0) { + pr_err("%s: unable to get channal map\n", __func__); + goto fail_cmd; + } + + for (i = 0; i < mfc_cfg.num_channels; i++) + mfc_cfg.channel_type[i] = + (uint16_t) open.dev_channel_mapping[i]; + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + + pr_debug("%s: mfc config: port_idx %d copp_idx %d copp SR %d copp BW %d copp chan %d o/p SR %d\n", + __func__, port_idx, copp_idx, + atomic_read(&this_adm.copp.rate[port_idx][copp_idx]), + mfc_cfg.bits_per_sample, mfc_cfg.num_channels, + mfc_cfg.sampling_rate); + + rc = apr_send_pkt(this_adm.apr, (uint32_t *)&mfc_cfg); + + if (rc < 0) { + pr_err("%s: port_id: for[0x%x] failed %d\n", + __func__, port_id, rc); + goto fail_cmd; + } + /* Wait for the callback with copp id */ + rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!rc) { + pr_err("%s: mfc_cfg Set params timed out for port_id: for [0x%x]\n", + __func__, port_id); + goto fail_cmd; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + goto fail_cmd; + } + rc = 0; +fail_cmd: + return; +} + +static void route_set_opcode_matrix_id( + struct adm_cmd_matrix_map_routings_v5 **route_addr, + int path, uint32_t passthr_mode) +{ + struct adm_cmd_matrix_map_routings_v5 *route = *route_addr; + + switch (path) { + case ADM_PATH_PLAYBACK: + route->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5; + route->matrix_id = ADM_MATRIX_ID_AUDIO_RX; + break; + case ADM_PATH_LIVE_REC: + if (passthr_mode == LISTEN) { + route->hdr.opcode = + ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5; + route->matrix_id = ADM_MATRIX_ID_LISTEN_TX; + break; + } + /* fall through to set matrix id for non-listen case */ + case ADM_PATH_NONLIVE_REC: + route->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5; + route->matrix_id = ADM_MATRIX_ID_AUDIO_TX; + break; + case ADM_PATH_COMPRESSED_RX: + route->hdr.opcode = ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5; + route->matrix_id = ADM_MATRIX_ID_COMPRESSED_AUDIO_RX; + break; + case ADM_PATH_COMPRESSED_TX: + route->hdr.opcode = ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5; + route->matrix_id = ADM_MATRIX_ID_COMPRESSED_AUDIO_TX; + break; + default: + pr_err("%s: Wrong path set[%d]\n", __func__, path); + break; + } + pr_debug("%s: opcode 0x%x, matrix id %d\n", + __func__, route->hdr.opcode, route->matrix_id); +} + +int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode, + uint32_t passthr_mode) +{ + struct adm_cmd_matrix_map_routings_v5 *route; + struct adm_session_map_node_v5 *node; + uint16_t *copps_list; + int cmd_size = 0; + int ret = 0, i = 0; + void *payload = NULL; + void *matrix_map = NULL; + int port_idx, copp_idx; + + /* Assumes port_ids have already been validated during adm_open */ + cmd_size = (sizeof(struct adm_cmd_matrix_map_routings_v5) + + sizeof(struct adm_session_map_node_v5) + + (sizeof(uint32_t) * payload_map.num_copps)); + matrix_map = kzalloc(cmd_size, GFP_KERNEL); + if (matrix_map == NULL) { + pr_err("%s: Mem alloc failed\n", __func__); + ret = -EINVAL; + return ret; + } + route = (struct adm_cmd_matrix_map_routings_v5 *)matrix_map; + + route->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + route->hdr.pkt_size = cmd_size; + route->hdr.src_svc = 0; + route->hdr.src_domain = APR_DOMAIN_APPS; + route->hdr.src_port = 0; /* Ignored */; + route->hdr.dest_svc = APR_SVC_ADM; + route->hdr.dest_domain = APR_DOMAIN_ADSP; + route->hdr.dest_port = 0; /* Ignored */; + route->hdr.token = 0; + route->num_sessions = 1; + route_set_opcode_matrix_id(&route, path, passthr_mode); + + payload = ((u8 *)matrix_map + + sizeof(struct adm_cmd_matrix_map_routings_v5)); + node = (struct adm_session_map_node_v5 *)payload; + + node->session_id = payload_map.session_id; + node->num_copps = payload_map.num_copps; + payload = (u8 *)node + sizeof(struct adm_session_map_node_v5); + copps_list = (uint16_t *)payload; + for (i = 0; i < payload_map.num_copps; i++) { + port_idx = + adm_validate_and_get_port_index(payload_map.port_id[i]); + if (port_idx < 0) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, + payload_map.port_id[i]); + ret = -EINVAL; + goto fail_cmd; + } + copp_idx = payload_map.copp_idx[i]; + copps_list[i] = atomic_read(&this_adm.copp.id[port_idx] + [copp_idx]); + } + atomic_set(&this_adm.matrix_map_stat, -1); + + ret = apr_send_pkt(this_adm.apr, (uint32_t *)matrix_map); + if (ret < 0) { + pr_err("%s: routing for syream %d failed ret %d\n", + __func__, payload_map.session_id, ret); + ret = -EINVAL; + goto fail_cmd; + } + ret = wait_event_timeout(this_adm.matrix_map_wait, + atomic_read(&this_adm.matrix_map_stat) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: routing for syream %d failed\n", __func__, + payload_map.session_id); + ret = -EINVAL; + goto fail_cmd; + } else if (atomic_read(&this_adm.matrix_map_stat) > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(atomic_read( + &this_adm.matrix_map_stat))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.matrix_map_stat)); + goto fail_cmd; + } + + if ((perf_mode != ULTRA_LOW_LATENCY_PCM_MODE) && + (path != ADM_PATH_COMPRESSED_RX)) { + for (i = 0; i < payload_map.num_copps; i++) { + port_idx = afe_get_port_index(payload_map.port_id[i]); + copp_idx = payload_map.copp_idx[i]; + if (port_idx < 0 || copp_idx < 0 || + (copp_idx > MAX_COPPS_PER_PORT - 1)) { + pr_err("%s: Invalid idx port_idx %d copp_idx %d\n", + __func__, port_idx, copp_idx); + continue; + } + rtac_add_adm_device(payload_map.port_id[i], + atomic_read(&this_adm.copp.id + [port_idx][copp_idx]), + get_cal_path(path), + payload_map.session_id, + payload_map.app_type[i], + payload_map.acdb_dev_id[i]); + + if (!test_bit(ADM_STATUS_CALIBRATION_REQUIRED, + (void *)&this_adm.copp.adm_status[port_idx] + [copp_idx])) { + pr_debug("%s: adm copp[0x%x][%d] already sent", + __func__, port_idx, copp_idx); + continue; + } + send_adm_cal(payload_map.port_id[i], copp_idx, + get_cal_path(path), perf_mode, + payload_map.app_type[i], + payload_map.acdb_dev_id[i], + payload_map.sample_rate[i]); + /* ADM COPP calibration is already sent */ + clear_bit(ADM_STATUS_CALIBRATION_REQUIRED, + (void *)&this_adm.copp. + adm_status[port_idx][copp_idx]); + pr_debug("%s: copp_id: %d\n", __func__, + atomic_read(&this_adm.copp.id[port_idx] + [copp_idx])); + } + } + +fail_cmd: + kfree(matrix_map); + return ret; +} + +void adm_ec_ref_rx_id(int port_id) +{ + this_adm.ec_ref_rx = port_id; + pr_debug("%s: ec_ref_rx:%d\n", __func__, this_adm.ec_ref_rx); +} + +void adm_num_ec_ref_rx_chans(int num_chans) +{ + this_adm.num_ec_ref_rx_chans = num_chans; + pr_debug("%s: num_ec_ref_rx_chans:%d\n", + __func__, this_adm.num_ec_ref_rx_chans); +} + +void adm_ec_ref_rx_bit_width(int bit_width) +{ + this_adm.ec_ref_rx_bit_width = bit_width; + pr_debug("%s: ec_ref_rx_bit_width:%d\n", + __func__, this_adm.ec_ref_rx_bit_width); +} + +void adm_ec_ref_rx_sampling_rate(int sampling_rate) +{ + this_adm.ec_ref_rx_sampling_rate = sampling_rate; + pr_debug("%s: ec_ref_rx_sampling_rate:%d\n", + __func__, this_adm.ec_ref_rx_sampling_rate); +} + +int adm_close(int port_id, int perf_mode, int copp_idx) +{ + struct apr_hdr close; + + int ret = 0, port_idx; + int copp_id = RESET_COPP_ID; + + pr_debug("%s: port_id=0x%x perf_mode: %d copp_idx: %d\n", __func__, + port_id, perf_mode, copp_idx); + + port_id = q6audio_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id 0x%x\n", + __func__, port_id); + return -EINVAL; + } + + if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { + pr_err("%s: Invalid copp idx: %d\n", __func__, copp_idx); + return -EINVAL; + } + + if (this_adm.copp.adm_delay[port_idx][copp_idx] && perf_mode + == LEGACY_PCM_MODE) { + atomic_set(&this_adm.copp.adm_delay_stat[port_idx][copp_idx], + 1); + this_adm.copp.adm_delay[port_idx][copp_idx] = 0; + wake_up(&this_adm.copp.adm_delay_wait[port_idx][copp_idx]); + } + + atomic_dec(&this_adm.copp.cnt[port_idx][copp_idx]); + if (!(atomic_read(&this_adm.copp.cnt[port_idx][copp_idx]))) { + copp_id = adm_get_copp_id(port_idx, copp_idx); + pr_debug("%s: Closing ADM port_idx:%d copp_idx:%d copp_id:0x%x\n", + __func__, port_idx, copp_idx, copp_id); + if ((!perf_mode) && (this_adm.outband_memmap.paddr != 0) && + (atomic_read(&this_adm.copp.topology[port_idx][copp_idx]) == + SRS_TRUMEDIA_TOPOLOGY_ID)) { + atomic_set(&this_adm.mem_map_index, + ADM_SRS_TRUMEDIA); + ret = adm_memory_unmap_regions(); + if (ret < 0) { + pr_err("%s: adm mem unmmap err %d", + __func__, ret); + } else { + atomic_set(&this_adm.mem_map_handles + [ADM_SRS_TRUMEDIA], 0); + } + } + + + if ((afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX) && + this_adm.sourceTrackingData.memmap.paddr) { + atomic_set(&this_adm.mem_map_index, + ADM_MEM_MAP_INDEX_SOURCE_TRACKING); + ret = adm_memory_unmap_regions(); + if (ret < 0) { + pr_err("%s: adm mem unmmap err %d", + __func__, ret); + } + msm_audio_ion_free( + this_adm.sourceTrackingData.ion_client, + this_adm.sourceTrackingData.ion_handle); + this_adm.sourceTrackingData.ion_client = NULL; + this_adm.sourceTrackingData.ion_handle = NULL; + this_adm.sourceTrackingData.memmap.size = 0; + this_adm.sourceTrackingData.memmap.kvaddr = NULL; + this_adm.sourceTrackingData.memmap.paddr = 0; + this_adm.sourceTrackingData.apr_cmd_status = -1; + atomic_set(&this_adm.mem_map_handles[ + ADM_MEM_MAP_INDEX_SOURCE_TRACKING], 0); + } + + close.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + close.pkt_size = sizeof(close); + close.src_svc = APR_SVC_ADM; + close.src_domain = APR_DOMAIN_APPS; + close.src_port = port_id; + close.dest_svc = APR_SVC_ADM; + close.dest_domain = APR_DOMAIN_ADSP; + close.dest_port = copp_id; + close.token = port_idx << 16 | copp_idx; + close.opcode = ADM_CMD_DEVICE_CLOSE_V5; + + atomic_set(&this_adm.copp.id[port_idx][copp_idx], + RESET_COPP_ID); + atomic_set(&this_adm.copp.cnt[port_idx][copp_idx], 0); + atomic_set(&this_adm.copp.topology[port_idx][copp_idx], 0); + atomic_set(&this_adm.copp.mode[port_idx][copp_idx], 0); + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + atomic_set(&this_adm.copp.rate[port_idx][copp_idx], 0); + atomic_set(&this_adm.copp.channels[port_idx][copp_idx], 0); + atomic_set(&this_adm.copp.bit_width[port_idx][copp_idx], 0); + atomic_set(&this_adm.copp.app_type[port_idx][copp_idx], 0); + + clear_bit(ADM_STATUS_CALIBRATION_REQUIRED, + (void *)&this_adm.copp.adm_status[port_idx][copp_idx]); + + ret = apr_send_pkt(this_adm.apr, (uint32_t *)&close); + if (ret < 0) { + pr_err("%s: ADM close failed %d\n", __func__, ret); + return -EINVAL; + } + + ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: ADM cmd Route timedout for port 0x%x\n", + __func__, port_id); + return -EINVAL; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + return adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + } + } + + if (perf_mode != ULTRA_LOW_LATENCY_PCM_MODE) { + pr_debug("%s: remove adm device from rtac\n", __func__); + rtac_remove_adm_device(port_id, copp_id); + } + return 0; +} + +int send_rtac_audvol_cal(void) +{ + int ret = 0; + int ret2 = 0; + int i = 0; + int copp_idx, port_idx, acdb_id, app_id, path; + struct cal_block_data *cal_block = NULL; + struct audio_cal_info_audvol *audvol_cal_info = NULL; + struct rtac_adm rtac_adm_data; + + mutex_lock(&this_adm.cal_data[ADM_RTAC_AUDVOL_CAL]->lock); + + cal_block = cal_utils_get_only_cal_block( + this_adm.cal_data[ADM_RTAC_AUDVOL_CAL]); + if (cal_block == NULL) { + pr_err("%s: can't find cal block!\n", __func__); + goto unlock; + } + + audvol_cal_info = cal_block->cal_info; + if (audvol_cal_info == NULL) { + pr_err("%s: audvol_cal_info is NULL!\n", __func__); + goto unlock; + } + + get_rtac_adm_data(&rtac_adm_data); + for (; i < rtac_adm_data.num_of_dev; i++) { + + acdb_id = rtac_adm_data.device[i].acdb_dev_id; + if (acdb_id == 0) + acdb_id = audvol_cal_info->acdb_id; + + app_id = rtac_adm_data.device[i].app_type; + if (app_id == 0) + app_id = audvol_cal_info->app_type; + + path = afe_get_port_type(rtac_adm_data.device[i].afe_port); + if ((acdb_id == audvol_cal_info->acdb_id) && + (app_id == audvol_cal_info->app_type) && + (path == audvol_cal_info->path)) { + + if (adm_get_indexes_from_copp_id(rtac_adm_data. + device[i].copp, &copp_idx, &port_idx) != 0) { + pr_debug("%s: Copp Id %d is not active\n", + __func__, + rtac_adm_data.device[i].copp); + continue; + } + + ret2 = adm_remap_and_send_cal_block(ADM_RTAC_AUDVOL_CAL, + rtac_adm_data.device[i].afe_port, + copp_idx, cal_block, + atomic_read(&this_adm.copp. + mode[port_idx][copp_idx]), + audvol_cal_info->app_type, + audvol_cal_info->acdb_id, + atomic_read(&this_adm.copp. + rate[port_idx][copp_idx])); + if (ret2 < 0) { + pr_debug("%s: remap and send failed for copp Id %d, acdb id %d, app type %d, path %d\n", + __func__, rtac_adm_data.device[i].copp, + audvol_cal_info->acdb_id, + audvol_cal_info->app_type, + audvol_cal_info->path); + ret = ret2; + } + } + } +unlock: + mutex_unlock(&this_adm.cal_data[ADM_RTAC_AUDVOL_CAL]->lock); + return ret; +} + +int adm_map_rtac_block(struct rtac_cal_block_data *cal_block) +{ + int result = 0; + + pr_debug("%s:\n", __func__); + + if (cal_block == NULL) { + pr_err("%s: cal_block is NULL!\n", + __func__); + result = -EINVAL; + goto done; + } + + if (cal_block->cal_data.paddr == 0) { + pr_debug("%s: No address to map!\n", + __func__); + result = -EINVAL; + goto done; + } + + if (cal_block->map_data.map_size == 0) { + pr_debug("%s: map size is 0!\n", + __func__); + result = -EINVAL; + goto done; + } + + /* valid port ID needed for callback use primary I2S */ + atomic_set(&this_adm.mem_map_index, ADM_RTAC_APR_CAL); + result = adm_memory_map_regions(&cal_block->cal_data.paddr, 0, + &cal_block->map_data.map_size, 1); + if (result < 0) { + pr_err("%s: RTAC mmap did not work! size = %d result %d\n", + __func__, + cal_block->map_data.map_size, result); + pr_debug("%s: RTAC mmap did not work! addr = 0x%pK, size = %d\n", + __func__, + &cal_block->cal_data.paddr, + cal_block->map_data.map_size); + goto done; + } + + cal_block->map_data.map_handle = atomic_read( + &this_adm.mem_map_handles[ADM_RTAC_APR_CAL]); +done: + return result; +} + +int adm_unmap_rtac_block(uint32_t *mem_map_handle) +{ + int result = 0; + + pr_debug("%s:\n", __func__); + + if (mem_map_handle == NULL) { + pr_debug("%s: Map handle is NULL, nothing to unmap\n", + __func__); + goto done; + } + + if (*mem_map_handle == 0) { + pr_debug("%s: Map handle is 0, nothing to unmap\n", + __func__); + goto done; + } + + if (*mem_map_handle != atomic_read( + &this_adm.mem_map_handles[ADM_RTAC_APR_CAL])) { + pr_err("%s: Map handles do not match! Unmapping RTAC, RTAC map 0x%x, ADM map 0x%x\n", + __func__, *mem_map_handle, atomic_read( + &this_adm.mem_map_handles[ADM_RTAC_APR_CAL])); + + /* if mismatch use handle passed in to unmap */ + atomic_set(&this_adm.mem_map_handles[ADM_RTAC_APR_CAL], + *mem_map_handle); + } + + /* valid port ID needed for callback use primary I2S */ + atomic_set(&this_adm.mem_map_index, ADM_RTAC_APR_CAL); + result = adm_memory_unmap_regions(); + if (result < 0) { + pr_debug("%s: adm_memory_unmap_regions failed, error %d\n", + __func__, result); + } else { + atomic_set(&this_adm.mem_map_handles[ADM_RTAC_APR_CAL], 0); + *mem_map_handle = 0; + } +done: + return result; +} + +static int get_cal_type_index(int32_t cal_type) +{ + int ret = -EINVAL; + + switch (cal_type) { + case ADM_AUDPROC_CAL_TYPE: + ret = ADM_AUDPROC_CAL; + break; + case ADM_AUDVOL_CAL_TYPE: + ret = ADM_AUDVOL_CAL; + break; + case ADM_CUST_TOPOLOGY_CAL_TYPE: + ret = ADM_CUSTOM_TOP_CAL; + break; + case ADM_RTAC_INFO_CAL_TYPE: + ret = ADM_RTAC_INFO_CAL; + break; + case ADM_RTAC_APR_CAL_TYPE: + ret = ADM_RTAC_APR_CAL; + break; + case ADM_RTAC_AUDVOL_CAL_TYPE: + ret = ADM_RTAC_AUDVOL_CAL; + break; + default: + pr_err("%s: invalid cal type %d!\n", __func__, cal_type); + } + return ret; +} + +static int adm_alloc_cal(int32_t cal_type, size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + + pr_debug("%s:\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + ret = cal_utils_alloc_cal(data_size, data, + this_adm.cal_data[cal_index], 0, NULL); + if (ret < 0) { + pr_err("%s: cal_utils_alloc_block failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + ret = -EINVAL; + goto done; + } +done: + return ret; +} + +static int adm_dealloc_cal(int32_t cal_type, size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + + pr_debug("%s:\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + ret = cal_utils_dealloc_cal(data_size, data, + this_adm.cal_data[cal_index]); + if (ret < 0) { + pr_err("%s: cal_utils_dealloc_block failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + ret = -EINVAL; + goto done; + } +done: + return ret; +} + +static int adm_set_cal(int32_t cal_type, size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + + pr_debug("%s:\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + ret = cal_utils_set_cal(data_size, data, + this_adm.cal_data[cal_index], 0, NULL); + if (ret < 0) { + pr_err("%s: cal_utils_set_cal failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + ret = -EINVAL; + goto done; + } + + if (cal_index == ADM_CUSTOM_TOP_CAL) { + mutex_lock(&this_adm.cal_data[ADM_CUSTOM_TOP_CAL]->lock); + this_adm.set_custom_topology = 1; + mutex_unlock(&this_adm.cal_data[ADM_CUSTOM_TOP_CAL]->lock); + } else if (cal_index == ADM_RTAC_AUDVOL_CAL) { + send_rtac_audvol_cal(); + } +done: + return ret; +} + +static int adm_map_cal_data(int32_t cal_type, + struct cal_block_data *cal_block) +{ + int ret = 0; + int cal_index; + + pr_debug("%s:\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + atomic_set(&this_adm.mem_map_index, cal_index); + ret = adm_memory_map_regions(&cal_block->cal_data.paddr, 0, + (uint32_t *)&cal_block->map_data.map_size, 1); + if (ret < 0) { + pr_err("%s: map did not work! cal_type %i ret %d\n", + __func__, cal_index, ret); + ret = -ENODEV; + goto done; + } + cal_block->map_data.q6map_handle = atomic_read(&this_adm. + mem_map_handles[cal_index]); +done: + return ret; +} + +static int adm_unmap_cal_data(int32_t cal_type, + struct cal_block_data *cal_block) +{ + int ret = 0; + int cal_index; + + pr_debug("%s:\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + if (cal_block == NULL) { + pr_err("%s: Cal block is NULL!\n", + __func__); + goto done; + } + + if (cal_block->map_data.q6map_handle == 0) { + pr_err("%s: Map handle is NULL, nothing to unmap\n", + __func__); + goto done; + } + + atomic_set(&this_adm.mem_map_handles[cal_index], + cal_block->map_data.q6map_handle); + atomic_set(&this_adm.mem_map_index, cal_index); + ret = adm_memory_unmap_regions(); + if (ret < 0) { + pr_err("%s: unmap did not work! cal_type %i ret %d\n", + __func__, cal_index, ret); + ret = -ENODEV; + goto done; + } + cal_block->map_data.q6map_handle = 0; +done: + return ret; +} + +static void adm_delete_cal_data(void) +{ + pr_debug("%s:\n", __func__); + + cal_utils_destroy_cal_types(ADM_MAX_CAL_TYPES, this_adm.cal_data); +} + +static int adm_init_cal_data(void) +{ + int ret = 0; + struct cal_type_info cal_type_info[] = { + {{ADM_CUST_TOPOLOGY_CAL_TYPE, + {adm_alloc_cal, adm_dealloc_cal, NULL, + adm_set_cal, NULL, NULL} }, + {adm_map_cal_data, adm_unmap_cal_data, + cal_utils_match_buf_num} }, + + {{ADM_AUDPROC_CAL_TYPE, + {adm_alloc_cal, adm_dealloc_cal, NULL, + adm_set_cal, NULL, NULL} }, + {adm_map_cal_data, adm_unmap_cal_data, + cal_utils_match_buf_num} }, + + {{ADM_AUDVOL_CAL_TYPE, + {adm_alloc_cal, adm_dealloc_cal, NULL, + adm_set_cal, NULL, NULL} }, + {adm_map_cal_data, adm_unmap_cal_data, + cal_utils_match_buf_num} }, + + {{ADM_RTAC_INFO_CAL_TYPE, + {NULL, NULL, NULL, NULL, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{ADM_RTAC_APR_CAL_TYPE, + {NULL, NULL, NULL, NULL, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{SRS_TRUMEDIA_CAL_TYPE, + {NULL, NULL, NULL, NULL, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{ADM_RTAC_AUDVOL_CAL_TYPE, + {adm_alloc_cal, adm_dealloc_cal, NULL, + adm_set_cal, NULL, NULL} }, + {adm_map_cal_data, adm_unmap_cal_data, + cal_utils_match_buf_num} }, + }; + pr_debug("%s:\n", __func__); + + ret = cal_utils_create_cal_types(ADM_MAX_CAL_TYPES, this_adm.cal_data, + cal_type_info); + if (ret < 0) { + pr_err("%s: could not create cal type! ret %d\n", + __func__, ret); + ret = -EINVAL; + goto err; + } + + return ret; +err: + adm_delete_cal_data(); + return ret; +} + +int adm_set_volume(int port_id, int copp_idx, int volume) +{ + struct audproc_volume_ctrl_master_gain audproc_vol; + int sz = 0; + int rc = 0; + int port_idx; + + pr_debug("%s: port_id %d, volume %d\n", __func__, port_id, volume); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id %#x\n", __func__, port_id); + rc = -EINVAL; + goto fail_cmd; + } + + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); + return -EINVAL; + } + + sz = sizeof(struct audproc_volume_ctrl_master_gain); + audproc_vol.params.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + audproc_vol.params.hdr.pkt_size = sz; + audproc_vol.params.hdr.src_svc = APR_SVC_ADM; + audproc_vol.params.hdr.src_domain = APR_DOMAIN_APPS; + audproc_vol.params.hdr.src_port = port_id; + audproc_vol.params.hdr.dest_svc = APR_SVC_ADM; + audproc_vol.params.hdr.dest_domain = APR_DOMAIN_ADSP; + audproc_vol.params.hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + audproc_vol.params.hdr.token = port_idx << 16 | copp_idx; + audproc_vol.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + audproc_vol.params.payload_addr_lsw = 0; + audproc_vol.params.payload_addr_msw = 0; + audproc_vol.params.mem_map_handle = 0; + audproc_vol.params.payload_size = sizeof(audproc_vol) - + sizeof(audproc_vol.params); + audproc_vol.data.module_id = AUDPROC_MODULE_ID_VOL_CTRL; + audproc_vol.data.param_id = AUDPROC_PARAM_ID_VOL_CTRL_MASTER_GAIN; + audproc_vol.data.param_size = audproc_vol.params.payload_size - + sizeof(audproc_vol.data); + audproc_vol.data.reserved = 0; + audproc_vol.master_gain = volume; + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + rc = apr_send_pkt(this_adm.apr, (uint32_t *)&audproc_vol); + if (rc < 0) { + pr_err("%s: Set params failed port = %#x\n", + __func__, port_id); + rc = -EINVAL; + goto fail_cmd; + } + /* Wait for the callback */ + rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!rc) { + pr_err("%s: Vol cntrl Set params timed out port = %#x\n", + __func__, port_id); + rc = -EINVAL; + goto fail_cmd; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto fail_cmd; + } + rc = 0; +fail_cmd: + return rc; +} + +int adm_set_softvolume(int port_id, int copp_idx, + struct audproc_softvolume_params *softvol_param) +{ + struct audproc_soft_step_volume_params audproc_softvol; + int sz = 0; + int rc = 0; + int port_idx; + + pr_debug("%s: period %d step %d curve %d\n", __func__, + softvol_param->period, softvol_param->step, + softvol_param->rampingcurve); + + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id %#x\n", __func__, port_id); + rc = -EINVAL; + goto fail_cmd; + } + + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); + return -EINVAL; + } + + sz = sizeof(struct audproc_soft_step_volume_params); + + audproc_softvol.params.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + audproc_softvol.params.hdr.pkt_size = sz; + audproc_softvol.params.hdr.src_svc = APR_SVC_ADM; + audproc_softvol.params.hdr.src_domain = APR_DOMAIN_APPS; + audproc_softvol.params.hdr.src_port = port_id; + audproc_softvol.params.hdr.dest_svc = APR_SVC_ADM; + audproc_softvol.params.hdr.dest_domain = APR_DOMAIN_ADSP; + audproc_softvol.params.hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + audproc_softvol.params.hdr.token = port_idx << 16 | copp_idx; + audproc_softvol.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + audproc_softvol.params.payload_addr_lsw = 0; + audproc_softvol.params.payload_addr_msw = 0; + audproc_softvol.params.mem_map_handle = 0; + audproc_softvol.params.payload_size = sizeof(audproc_softvol) - + sizeof(audproc_softvol.params); + audproc_softvol.data.module_id = AUDPROC_MODULE_ID_VOL_CTRL; + audproc_softvol.data.param_id = + AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS; + audproc_softvol.data.param_size = audproc_softvol.params.payload_size - + sizeof(audproc_softvol.data); + audproc_softvol.data.reserved = 0; + audproc_softvol.period = softvol_param->period; + audproc_softvol.step = softvol_param->step; + audproc_softvol.ramping_curve = softvol_param->rampingcurve; + + pr_debug("%s: period %d, step %d, curve %d\n", __func__, + audproc_softvol.period, audproc_softvol.step, + audproc_softvol.ramping_curve); + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + rc = apr_send_pkt(this_adm.apr, (uint32_t *)&audproc_softvol); + if (rc < 0) { + pr_err("%s: Set params failed port = %#x\n", + __func__, port_id); + rc = -EINVAL; + goto fail_cmd; + } + /* Wait for the callback */ + rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!rc) { + pr_err("%s: Soft volume Set params timed out port = %#x\n", + __func__, port_id); + rc = -EINVAL; + goto fail_cmd; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto fail_cmd; + } + rc = 0; +fail_cmd: + return rc; +} + +int adm_set_mic_gain(int port_id, int copp_idx, int volume) +{ + struct adm_set_mic_gain_params mic_gain_params; + int rc = 0; + int sz, port_idx; + + pr_debug("%s:\n", __func__); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + return -EINVAL; + } + + sz = sizeof(struct adm_set_mic_gain_params); + + mic_gain_params.params.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + mic_gain_params.params.hdr.pkt_size = sz; + mic_gain_params.params.hdr.src_svc = APR_SVC_ADM; + mic_gain_params.params.hdr.src_domain = APR_DOMAIN_APPS; + mic_gain_params.params.hdr.src_port = port_id; + mic_gain_params.params.hdr.dest_svc = APR_SVC_ADM; + mic_gain_params.params.hdr.dest_domain = APR_DOMAIN_ADSP; + mic_gain_params.params.hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + mic_gain_params.params.hdr.token = port_idx << 16 | copp_idx; + mic_gain_params.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + mic_gain_params.params.payload_addr_lsw = 0; + mic_gain_params.params.payload_addr_msw = 0; + mic_gain_params.params.mem_map_handle = 0; + mic_gain_params.params.payload_size = + sizeof(struct adm_param_data_v5) + + sizeof(struct admx_mic_gain); + mic_gain_params.data.module_id = ADM_MODULE_IDX_MIC_GAIN_CTRL; + mic_gain_params.data.param_id = ADM_PARAM_IDX_MIC_GAIN; + mic_gain_params.data.param_size = + sizeof(struct admx_mic_gain); + mic_gain_params.data.reserved = 0; + mic_gain_params.mic_gain_data.tx_mic_gain = volume; + mic_gain_params.mic_gain_data.reserved = 0; + pr_debug("%s: Mic Gain set to %d at port_id 0x%x\n", + __func__, volume, port_id); + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + rc = apr_send_pkt(this_adm.apr, (uint32_t *)&mic_gain_params); + if (rc < 0) { + pr_err("%s: Set params failed port = %#x\n", + __func__, port_id); + rc = -EINVAL; + goto fail_cmd; + } + /* Wait for the callback */ + rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!rc) { + pr_err("%s: Mic Gain Set params timed out port = %#x\n", + __func__, port_id); + rc = -EINVAL; + goto fail_cmd; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto fail_cmd; + } + rc = 0; +fail_cmd: + return rc; +} + +int adm_send_set_multichannel_ec_primary_mic_ch(int port_id, int copp_idx, + int primary_mic_ch) +{ + struct adm_set_sec_primary_ch_params sec_primary_ch_params; + int rc = 0; + int sz, port_idx; + + pr_debug("%s port_id 0x%x, copp_idx 0x%x, primary_mic_ch %d\n", + __func__, port_id, copp_idx, primary_mic_ch); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + return -EINVAL; + } + + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_idx 0x%x\n", __func__, copp_idx); + return -EINVAL; + } + + sz = sizeof(struct adm_set_sec_primary_ch_params); + + sec_primary_ch_params.params.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + sec_primary_ch_params.params.hdr.pkt_size = sz; + sec_primary_ch_params.params.hdr.src_svc = APR_SVC_ADM; + sec_primary_ch_params.params.hdr.src_domain = APR_DOMAIN_APPS; + sec_primary_ch_params.params.hdr.src_port = port_id; + sec_primary_ch_params.params.hdr.dest_svc = APR_SVC_ADM; + sec_primary_ch_params.params.hdr.dest_domain = APR_DOMAIN_ADSP; + sec_primary_ch_params.params.hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + sec_primary_ch_params.params.hdr.token = port_idx << 16 | copp_idx; + sec_primary_ch_params.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + sec_primary_ch_params.params.payload_addr_lsw = 0; + sec_primary_ch_params.params.payload_addr_msw = 0; + sec_primary_ch_params.params.mem_map_handle = 0; + sec_primary_ch_params.params.payload_size = + sizeof(struct adm_param_data_v5) + + sizeof(struct admx_sec_primary_mic_ch); + sec_primary_ch_params.data.module_id = + AUDPROC_MODULE_ID_VOICE_TX_SECNS; + sec_primary_ch_params.data.param_id = + AUDPROC_PARAM_IDX_SEC_PRIMARY_MIC_CH; + sec_primary_ch_params.data.param_size = + sizeof(struct admx_sec_primary_mic_ch); + sec_primary_ch_params.data.reserved = 0; + sec_primary_ch_params.sec_primary_mic_ch_data.version = 0; + sec_primary_ch_params.sec_primary_mic_ch_data.reserved = 0; + sec_primary_ch_params.sec_primary_mic_ch_data.sec_primary_mic_ch = + primary_mic_ch; + sec_primary_ch_params.sec_primary_mic_ch_data.reserved1 = 0; + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + rc = apr_send_pkt(this_adm.apr, (uint32_t *)&sec_primary_ch_params); + if (rc < 0) { + pr_err("%s: Set params failed port = %#x\n", + __func__, port_id); + rc = -EINVAL; + goto fail_cmd; + } + /* Wait for the callback */ + rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!rc) { + pr_err("%s: Mic Set params timed out port = %#x\n", + __func__, port_id); + rc = -EINVAL; + goto fail_cmd; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto fail_cmd; + } + rc = 0; +fail_cmd: + return rc; +} + +int adm_param_enable(int port_id, int copp_idx, int module_id, int enable) +{ + struct audproc_enable_param_t adm_mod_enable; + int sz = 0; + int rc = 0; + int port_idx; + + pr_debug("%s port_id %d, module_id 0x%x, enable %d\n", + __func__, port_id, module_id, enable); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id %#x\n", __func__, port_id); + rc = -EINVAL; + goto fail_cmd; + } + + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); + return -EINVAL; + } + + sz = sizeof(struct audproc_enable_param_t); + + adm_mod_enable.pp_params.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + adm_mod_enable.pp_params.hdr.pkt_size = sz; + adm_mod_enable.pp_params.hdr.src_svc = APR_SVC_ADM; + adm_mod_enable.pp_params.hdr.src_domain = APR_DOMAIN_APPS; + adm_mod_enable.pp_params.hdr.src_port = port_id; + adm_mod_enable.pp_params.hdr.dest_svc = APR_SVC_ADM; + adm_mod_enable.pp_params.hdr.dest_domain = APR_DOMAIN_ADSP; + adm_mod_enable.pp_params.hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + adm_mod_enable.pp_params.hdr.token = port_idx << 16 | copp_idx; + adm_mod_enable.pp_params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + adm_mod_enable.pp_params.payload_addr_lsw = 0; + adm_mod_enable.pp_params.payload_addr_msw = 0; + adm_mod_enable.pp_params.mem_map_handle = 0; + adm_mod_enable.pp_params.payload_size = sizeof(adm_mod_enable) - + sizeof(adm_mod_enable.pp_params) + + sizeof(adm_mod_enable.pp_params.params); + adm_mod_enable.pp_params.params.module_id = module_id; + adm_mod_enable.pp_params.params.param_id = AUDPROC_PARAM_ID_ENABLE; + adm_mod_enable.pp_params.params.param_size = + adm_mod_enable.pp_params.payload_size - + sizeof(adm_mod_enable.pp_params.params); + adm_mod_enable.pp_params.params.reserved = 0; + adm_mod_enable.enable = enable; + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + + rc = apr_send_pkt(this_adm.apr, (uint32_t *)&adm_mod_enable); + if (rc < 0) { + pr_err("%s: Set params failed port = %#x\n", + __func__, port_id); + rc = -EINVAL; + goto fail_cmd; + } + /* Wait for the callback */ + rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!rc) { + pr_err("%s: module %x enable %d timed out on port = %#x\n", + __func__, module_id, enable, port_id); + rc = -EINVAL; + goto fail_cmd; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto fail_cmd; + } + rc = 0; +fail_cmd: + return rc; + +} + +int adm_send_calibration(int port_id, int copp_idx, int path, int perf_mode, + int cal_type, char *params, int size) +{ + + struct adm_cmd_set_pp_params_v5 *adm_params = NULL; + int sz, rc = 0; + int port_idx; + + pr_debug("%s:port_id %d, path %d, perf_mode %d, cal_type %d, size %d\n", + __func__, port_id, path, perf_mode, cal_type, size); + + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id %#x\n", __func__, port_id); + rc = -EINVAL; + goto end; + } + + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); + return -EINVAL; + } + + /* Maps audio_dev_ctrl path definition to ACDB definition */ + if (get_cal_path(path) != RX_DEVICE) { + pr_err("%s: acdb_path %d\n", __func__, path); + rc = -EINVAL; + goto end; + } + + sz = sizeof(struct adm_cmd_set_pp_params_v5) + size; + adm_params = kzalloc(sz, GFP_KERNEL); + if (!adm_params) { + pr_err("%s, adm params memory alloc failed", __func__); + rc = -ENOMEM; + goto end; + } + + memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_set_pp_params_v5)), + params, size); + + adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + adm_params->hdr.pkt_size = sz; + adm_params->hdr.src_svc = APR_SVC_ADM; + adm_params->hdr.src_domain = APR_DOMAIN_APPS; + adm_params->hdr.src_port = port_id; + adm_params->hdr.dest_svc = APR_SVC_ADM; + adm_params->hdr.dest_domain = APR_DOMAIN_ADSP; + adm_params->hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + adm_params->hdr.token = port_idx << 16 | copp_idx; + adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + /* payload address and mmap handle initialized to zero by kzalloc */ + adm_params->payload_size = size; + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); + if (rc < 0) { + pr_err("%s: Set params failed port = %#x\n", + __func__, port_id); + rc = -EINVAL; + goto end; + } + /* Wait for the callback */ + rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!rc) { + pr_err("%s: Set params timed out port = %#x\n", + __func__, port_id); + rc = -EINVAL; + goto end; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto end; + } + rc = 0; + +end: + kfree(adm_params); + return rc; +} + +/* + * adm_update_wait_parameters must be called with routing driver locks. + * adm_reset_wait_parameters must be called with routing driver locks. + * set and reset parmeters are separated to make sure it is always called + * under routing driver lock. + * adm_wait_timeout is to block until timeout or interrupted. Timeout is + * not a an error. + */ +int adm_set_wait_parameters(int port_id, int copp_idx) +{ + + int ret = 0, port_idx; + + pr_debug("%s: port_id 0x%x, copp_idx %d\n", __func__, port_id, + copp_idx); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id %#x\n", __func__, port_id); + ret = -EINVAL; + goto end; + } + + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); + return -EINVAL; + } + + this_adm.copp.adm_delay[port_idx][copp_idx] = 1; + atomic_set(&this_adm.copp.adm_delay_stat[port_idx][copp_idx], 0); + +end: + return ret; + +} + +int adm_reset_wait_parameters(int port_id, int copp_idx) +{ + int ret = 0, port_idx; + + pr_debug("%s: port_id 0x%x copp_idx %d\n", __func__, port_id, + copp_idx); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id %#x\n", __func__, port_id); + ret = -EINVAL; + goto end; + } + + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); + return -EINVAL; + } + + atomic_set(&this_adm.copp.adm_delay_stat[port_idx][copp_idx], 1); + this_adm.copp.adm_delay[port_idx][copp_idx] = 0; + +end: + return ret; +} + +int adm_wait_timeout(int port_id, int copp_idx, int wait_time) +{ + int ret = 0, port_idx; + + pr_debug("%s: port_id 0x%x, copp_idx %d, wait_time %d\n", __func__, + port_id, copp_idx, wait_time); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id %#x\n", __func__, port_id); + ret = -EINVAL; + goto end; + } + + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); + return -EINVAL; + } + + ret = wait_event_timeout( + this_adm.copp.adm_delay_wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.adm_delay_stat[port_idx][copp_idx]), + msecs_to_jiffies(wait_time)); + pr_debug("%s: return %d\n", __func__, ret); + if (ret != 0) + ret = -EINTR; +end: + pr_debug("%s: return %d--\n", __func__, ret); + return ret; +} + +int adm_store_cal_data(int port_id, int copp_idx, int path, int perf_mode, + int cal_index, char *params, int *size) +{ + int rc = 0; + struct cal_block_data *cal_block = NULL; + int app_type, acdb_id, port_idx, sample_rate; + + if (this_adm.cal_data[cal_index] == NULL) { + pr_debug("%s: cal_index %d not allocated!\n", + __func__, cal_index); + goto end; + } + + if (get_cal_path(path) != RX_DEVICE) { + pr_debug("%s: Invalid path to store calibration %d\n", + __func__, path); + rc = -EINVAL; + goto end; + } + + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + rc = -EINVAL; + goto end; + } + + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); + return -EINVAL; + } + + acdb_id = atomic_read(&this_adm.copp.acdb_id[port_idx][copp_idx]); + app_type = atomic_read(&this_adm.copp.app_type[port_idx][copp_idx]); + sample_rate = atomic_read(&this_adm.copp.rate[port_idx][copp_idx]); + + mutex_lock(&this_adm.cal_data[cal_index]->lock); + cal_block = adm_find_cal(cal_index, get_cal_path(path), app_type, + acdb_id, sample_rate); + if (cal_block == NULL) + goto unlock; + + if (cal_block->cal_data.size <= 0) { + pr_debug("%s: No ADM cal send for port_id = 0x%x!\n", + __func__, port_id); + rc = -EINVAL; + goto unlock; + } + + if (cal_index == ADM_AUDPROC_CAL) { + if (cal_block->cal_data.size > AUD_PROC_BLOCK_SIZE) { + pr_err("%s:audproc:invalid size exp/actual[%zd, %d]\n", + __func__, cal_block->cal_data.size, *size); + rc = -ENOMEM; + goto unlock; + } + } else if (cal_index == ADM_AUDVOL_CAL) { + if (cal_block->cal_data.size > AUD_VOL_BLOCK_SIZE) { + pr_err("%s:aud_vol:invalid size exp/actual[%zd, %d]\n", + __func__, cal_block->cal_data.size, *size); + rc = -ENOMEM; + goto unlock; + } + } else { + pr_debug("%s: Not valid calibration for dolby topolgy\n", + __func__); + rc = -EINVAL; + goto unlock; + } + memcpy(params, cal_block->cal_data.kvaddr, cal_block->cal_data.size); + *size = cal_block->cal_data.size; + + pr_debug("%s:port_id %d, copp_idx %d, path %d", + __func__, port_id, copp_idx, path); + pr_debug("perf_mode %d, cal_type %d, size %d\n", + perf_mode, cal_index, *size); + +unlock: + mutex_unlock(&this_adm.cal_data[cal_index]->lock); +end: + return rc; +} + +int adm_send_compressed_device_mute(int port_id, int copp_idx, bool mute_on) +{ + struct adm_set_compressed_device_mute mute_params; + int ret = 0; + int port_idx; + + pr_debug("%s port_id: 0x%x, copp_idx %d, mute_on: %d\n", + __func__, port_id, copp_idx, mute_on); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { + pr_err("%s: Invalid port_id %#x copp_idx %d\n", + __func__, port_id, copp_idx); + ret = -EINVAL; + goto end; + } + + mute_params.command.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + mute_params.command.hdr.pkt_size = + sizeof(struct adm_set_compressed_device_mute); + mute_params.command.hdr.src_svc = APR_SVC_ADM; + mute_params.command.hdr.src_domain = APR_DOMAIN_APPS; + mute_params.command.hdr.src_port = port_id; + mute_params.command.hdr.dest_svc = APR_SVC_ADM; + mute_params.command.hdr.dest_domain = APR_DOMAIN_ADSP; + mute_params.command.hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + mute_params.command.hdr.token = port_idx << 16 | copp_idx; + mute_params.command.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + mute_params.command.payload_addr_lsw = 0; + mute_params.command.payload_addr_msw = 0; + mute_params.command.mem_map_handle = 0; + mute_params.command.payload_size = sizeof(mute_params) - + sizeof(mute_params.command); + mute_params.params.module_id = AUDPROC_MODULE_ID_COMPRESSED_MUTE; + mute_params.params.param_id = AUDPROC_PARAM_ID_COMPRESSED_MUTE; + mute_params.params.param_size = mute_params.command.payload_size - + sizeof(mute_params.params); + mute_params.params.reserved = 0; + mute_params.mute_on = mute_on; + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + ret = apr_send_pkt(this_adm.apr, (uint32_t *)&mute_params); + if (ret < 0) { + pr_err("%s: device mute for port %d copp %d failed, ret %d\n", + __func__, port_id, copp_idx, ret); + ret = -EINVAL; + goto end; + } + + /* Wait for the callback */ + ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: send device mute for port %d copp %d failed\n", + __func__, port_id, copp_idx); + ret = -EINVAL; + goto end; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto end; + } + ret = 0; +end: + return ret; +} + +int adm_send_compressed_device_latency(int port_id, int copp_idx, int latency) +{ + struct adm_set_compressed_device_latency latency_params; + int port_idx; + int ret = 0; + + pr_debug("%s port_id: 0x%x, copp_idx %d latency: %d\n", __func__, + port_id, copp_idx, latency); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { + pr_err("%s: Invalid port_id %#x copp_idx %d\n", + __func__, port_id, copp_idx); + ret = -EINVAL; + goto end; + } + + latency_params.command.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + latency_params.command.hdr.pkt_size = + sizeof(struct adm_set_compressed_device_latency); + latency_params.command.hdr.src_svc = APR_SVC_ADM; + latency_params.command.hdr.src_domain = APR_DOMAIN_APPS; + latency_params.command.hdr.src_port = port_id; + latency_params.command.hdr.dest_svc = APR_SVC_ADM; + latency_params.command.hdr.dest_domain = APR_DOMAIN_ADSP; + latency_params.command.hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + latency_params.command.hdr.token = port_idx << 16 | copp_idx; + latency_params.command.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + latency_params.command.payload_addr_lsw = 0; + latency_params.command.payload_addr_msw = 0; + latency_params.command.mem_map_handle = 0; + latency_params.command.payload_size = sizeof(latency_params) - + sizeof(latency_params.command); + latency_params.params.module_id = AUDPROC_MODULE_ID_COMPRESSED_LATENCY; + latency_params.params.param_id = AUDPROC_PARAM_ID_COMPRESSED_LATENCY; + latency_params.params.param_size = latency_params.command.payload_size - + sizeof(latency_params.params); + latency_params.params.reserved = 0; + latency_params.latency = latency; + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + ret = apr_send_pkt(this_adm.apr, (uint32_t *)&latency_params); + if (ret < 0) { + pr_err("%s: send device latency err %d for port %d copp %d\n", + __func__, port_id, copp_idx, ret); + ret = -EINVAL; + goto end; + } + + /* Wait for the callback */ + ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: send device latency for port %d failed\n", __func__, + port_id); + ret = -EINVAL; + goto end; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto end; + } + ret = 0; +end: + return ret; +} + +/** + * adm_swap_speaker_channels + * + * Receives port_id, copp_idx, sample rate, spk_swap and + * send MFC command to swap speaker channel. + * Return zero on success. On failure returns nonzero. + * + * port_id - Passed value, port_id for which channels swap is wanted + * copp_idx - Passed value, copp_idx for which channels swap is wanted + * sample_rate - Passed value, sample rate used by app type config + * spk_swap - Passed value, spk_swap for check if swap flag is set + */ +int adm_swap_speaker_channels(int port_id, int copp_idx, + int sample_rate, bool spk_swap) +{ + struct audproc_mfc_output_media_fmt mfc_cfg; + uint16_t num_channels; + int port_idx; + int ret = 0; + + pr_debug("%s: Enter, port_id %d, copp_idx %d\n", + __func__, port_id, copp_idx); + port_id = q6audio_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { + pr_err("%s: Invalid port_id %#x\n", __func__, port_id); + ret = -EINVAL; + goto done; + } + + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); + ret = -EINVAL; + goto done; + } + + num_channels = atomic_read( + &this_adm.copp.channels[port_idx][copp_idx]); + if (num_channels != 2) { + pr_debug("%s: Invalid number of channels: %d\n", + __func__, num_channels); + ret = -EINVAL; + goto done; + } + + memset(&mfc_cfg, 0, sizeof(mfc_cfg)); + mfc_cfg.params.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + mfc_cfg.params.hdr.pkt_size = + sizeof(mfc_cfg); + mfc_cfg.params.hdr.src_svc = APR_SVC_ADM; + mfc_cfg.params.hdr.src_domain = APR_DOMAIN_APPS; + mfc_cfg.params.hdr.src_port = port_id; + mfc_cfg.params.hdr.dest_svc = APR_SVC_ADM; + mfc_cfg.params.hdr.dest_domain = APR_DOMAIN_ADSP; + mfc_cfg.params.hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + mfc_cfg.params.hdr.token = port_idx << 16 | copp_idx; + mfc_cfg.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + mfc_cfg.params.payload_addr_lsw = 0; + mfc_cfg.params.payload_addr_msw = 0; + mfc_cfg.params.mem_map_handle = 0; + mfc_cfg.params.payload_size = sizeof(mfc_cfg) - + sizeof(mfc_cfg.params); + mfc_cfg.data.module_id = AUDPROC_MODULE_ID_MFC; + mfc_cfg.data.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; + mfc_cfg.data.param_size = mfc_cfg.params.payload_size - + sizeof(mfc_cfg.data); + mfc_cfg.data.reserved = 0; + mfc_cfg.sampling_rate = sample_rate; + mfc_cfg.bits_per_sample = + atomic_read(&this_adm.copp.bit_width[port_idx][copp_idx]); + mfc_cfg.num_channels = num_channels; + + /* Currently applying speaker swap for only 2 channel use case */ + if (spk_swap) { + mfc_cfg.channel_type[0] = + (uint16_t) PCM_CHANNEL_FR; + mfc_cfg.channel_type[1] = + (uint16_t) PCM_CHANNEL_FL; + } else { + mfc_cfg.channel_type[0] = + (uint16_t) PCM_CHANNEL_FL; + mfc_cfg.channel_type[1] = + (uint16_t) PCM_CHANNEL_FR; + } + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + pr_debug("%s: mfc config: port_idx %d copp_idx %d copp SR %d copp BW %d copp chan %d\n", + __func__, port_idx, copp_idx, mfc_cfg.sampling_rate, + mfc_cfg.bits_per_sample, mfc_cfg.num_channels); + + ret = apr_send_pkt(this_adm.apr, (uint32_t *)&mfc_cfg); + if (ret < 0) { + pr_err("%s: port_id: for[0x%x] failed %d\n", + __func__, port_id, ret); + goto done; + } + /* Wait for the callback with copp id */ + ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: mfc_cfg Set params timed out for port_id: for [0x%x]\n", + __func__, port_id); + ret = -ETIMEDOUT; + goto done; + } + + if (atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto done; + } + + pr_debug("%s: mfc_cfg Set params returned success", __func__); + ret = 0; + +done: + return ret; +} +EXPORT_SYMBOL(adm_swap_speaker_channels); + +int adm_set_sound_focus(int port_id, int copp_idx, + struct sound_focus_param soundFocusData) +{ + struct adm_set_fluence_soundfocus_param soundfocus_params; + int sz = 0; + int ret = 0; + int port_idx; + int i; + + pr_debug("%s: Enter, port_id %d, copp_idx %d\n", + __func__, port_id, copp_idx); + + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id %#x\n", __func__, port_id); + + ret = -EINVAL; + goto done; + } + + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); + + ret = -EINVAL; + goto done; + } + + sz = sizeof(struct adm_set_fluence_soundfocus_param); + soundfocus_params.params.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + soundfocus_params.params.hdr.pkt_size = sz; + soundfocus_params.params.hdr.src_svc = APR_SVC_ADM; + soundfocus_params.params.hdr.src_domain = APR_DOMAIN_APPS; + soundfocus_params.params.hdr.src_port = port_id; + soundfocus_params.params.hdr.dest_svc = APR_SVC_ADM; + soundfocus_params.params.hdr.dest_domain = APR_DOMAIN_ADSP; + soundfocus_params.params.hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + soundfocus_params.params.hdr.token = port_idx << 16 | + ADM_CLIENT_ID_SOURCE_TRACKING << 8 | copp_idx; + soundfocus_params.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + soundfocus_params.params.payload_addr_lsw = 0; + soundfocus_params.params.payload_addr_msw = 0; + soundfocus_params.params.mem_map_handle = 0; + soundfocus_params.params.payload_size = sizeof(soundfocus_params) - + sizeof(soundfocus_params.params); + soundfocus_params.data.module_id = VOICEPROC_MODULE_ID_GENERIC_TX; + soundfocus_params.data.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS; + soundfocus_params.data.param_size = + soundfocus_params.params.payload_size - + sizeof(soundfocus_params.data); + soundfocus_params.data.reserved = 0; + + memset(&(soundfocus_params.soundfocus_data), 0xFF, + sizeof(struct adm_param_fluence_soundfocus_t)); + for (i = 0; i < MAX_SECTORS; i++) { + soundfocus_params.soundfocus_data.start_angles[i] = + soundFocusData.start_angle[i]; + soundfocus_params.soundfocus_data.enables[i] = + soundFocusData.enable[i]; + pr_debug("%s: start_angle[%d] = %d\n", + __func__, i, soundFocusData.start_angle[i]); + pr_debug("%s: enable[%d] = %d\n", + __func__, i, soundFocusData.enable[i]); + } + soundfocus_params.soundfocus_data.gain_step = + soundFocusData.gain_step; + pr_debug("%s: gain_step = %d\n", __func__, soundFocusData.gain_step); + + soundfocus_params.soundfocus_data.reserved = 0; + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + ret = apr_send_pkt(this_adm.apr, (uint32_t *)&soundfocus_params); + if (ret < 0) { + pr_err("%s: Set params failed\n", __func__); + + ret = -EINVAL; + goto done; + } + /* Wait for the callback */ + ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Set params timed out\n", __func__); + + ret = -EINVAL; + goto done; + } + + if (this_adm.sourceTrackingData.apr_cmd_status != 0) { + pr_err("%s - set params returned error [%s]\n", + __func__, adsp_err_get_err_str( + this_adm.sourceTrackingData.apr_cmd_status)); + + ret = adsp_err_get_lnx_err_code( + this_adm.sourceTrackingData.apr_cmd_status); + goto done; + } + + ret = 0; + +done: + pr_debug("%s: Exit, ret=%d\n", __func__, ret); + + return ret; +} + +int adm_get_sound_focus(int port_id, int copp_idx, + struct sound_focus_param *soundFocusData) +{ + int ret = 0, i; + char *params_value; + uint32_t param_payload_len = sizeof(struct adm_param_data_v5) + + sizeof(struct adm_param_fluence_soundfocus_t); + struct adm_param_fluence_soundfocus_t *soundfocus_params; + + pr_debug("%s: Enter, port_id %d, copp_idx %d\n", + __func__, port_id, copp_idx); + + params_value = kzalloc(param_payload_len, GFP_KERNEL); + if (!params_value) { + ret = -ENOMEM; + goto done; + } + ret = adm_get_params_v2(port_id, copp_idx, + VOICEPROC_MODULE_ID_GENERIC_TX, + VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS, + param_payload_len, + params_value, + ADM_CLIENT_ID_SOURCE_TRACKING); + if (ret) { + pr_err("%s: get parameters failed ret:%d\n", __func__, ret); + + kfree(params_value); + ret = -EINVAL; + goto done; + } + + if (this_adm.sourceTrackingData.apr_cmd_status != 0) { + pr_err("%s - get params returned error [%s]\n", + __func__, adsp_err_get_err_str( + this_adm.sourceTrackingData.apr_cmd_status)); + + kfree(params_value); + ret = adsp_err_get_lnx_err_code( + this_adm.sourceTrackingData.apr_cmd_status); + goto done; + } + + soundfocus_params = (struct adm_param_fluence_soundfocus_t *) + params_value; + for (i = 0; i < MAX_SECTORS; i++) { + soundFocusData->start_angle[i] = + soundfocus_params->start_angles[i]; + soundFocusData->enable[i] = soundfocus_params->enables[i]; + pr_debug("%s: start_angle[%d] = %d\n", + __func__, i, soundFocusData->start_angle[i]); + pr_debug("%s: enable[%d] = %d\n", + __func__, i, soundFocusData->enable[i]); + } + soundFocusData->gain_step = soundfocus_params->gain_step; + pr_debug("%s: gain_step = %d\n", __func__, soundFocusData->gain_step); + + kfree(params_value); + +done: + pr_debug("%s: Exit, ret = %d\n", __func__, ret); + + return ret; +} + +static int adm_source_tracking_alloc_map_memory(void) +{ + int ret; + + pr_debug("%s: Enter\n", __func__); + + ret = msm_audio_ion_alloc("SOURCE_TRACKING", + &this_adm.sourceTrackingData.ion_client, + &this_adm.sourceTrackingData.ion_handle, + AUD_PROC_BLOCK_SIZE, + &this_adm.sourceTrackingData.memmap.paddr, + &this_adm.sourceTrackingData.memmap.size, + &this_adm.sourceTrackingData.memmap.kvaddr); + if (ret) { + pr_err("%s: failed to allocate memory\n", __func__); + + ret = -EINVAL; + goto done; + } + + atomic_set(&this_adm.mem_map_index, ADM_MEM_MAP_INDEX_SOURCE_TRACKING); + ret = adm_memory_map_regions(&this_adm.sourceTrackingData.memmap.paddr, + 0, + (uint32_t *)&this_adm.sourceTrackingData.memmap.size, + 1); + if (ret < 0) { + pr_err("%s: failed to map memory, paddr = 0x%pK, size = %d\n", + __func__, + (void *)this_adm.sourceTrackingData.memmap.paddr, + (uint32_t)this_adm.sourceTrackingData.memmap.size); + + msm_audio_ion_free(this_adm.sourceTrackingData.ion_client, + this_adm.sourceTrackingData.ion_handle); + this_adm.sourceTrackingData.ion_client = NULL; + this_adm.sourceTrackingData.ion_handle = NULL; + this_adm.sourceTrackingData.memmap.size = 0; + this_adm.sourceTrackingData.memmap.kvaddr = NULL; + this_adm.sourceTrackingData.memmap.paddr = 0; + this_adm.sourceTrackingData.apr_cmd_status = -1; + atomic_set(&this_adm.mem_map_handles + [ADM_MEM_MAP_INDEX_SOURCE_TRACKING], 0); + + ret = -EINVAL; + goto done; + } + ret = 0; + pr_debug("%s: paddr = 0x%pK, size = %d, mem_map_handle = 0x%x\n", + __func__, (void *)this_adm.sourceTrackingData.memmap.paddr, + (uint32_t)this_adm.sourceTrackingData.memmap.size, + atomic_read(&this_adm.mem_map_handles + [ADM_MEM_MAP_INDEX_SOURCE_TRACKING])); + +done: + pr_debug("%s: Exit, ret = %d\n", __func__, ret); + + return ret; +} + +int adm_get_source_tracking(int port_id, int copp_idx, + struct source_tracking_param *sourceTrackingData) +{ + struct adm_cmd_get_pp_params_v5 admp; + int p_idx, ret = 0, i; + struct adm_param_fluence_sourcetracking_t *source_tracking_params; + + pr_debug("%s: Enter, port_id %d, copp_idx %d\n", + __func__, port_id, copp_idx); + + if (!this_adm.sourceTrackingData.memmap.paddr) { + /* Allocate and map shared memory for out of band usage */ + ret = adm_source_tracking_alloc_map_memory(); + if (ret != 0) { + ret = -EINVAL; + goto done; + } + } + + port_id = afe_convert_virtual_to_portid(port_id); + p_idx = adm_validate_and_get_port_index(port_id); + if (p_idx < 0) { + pr_err("%s - invalid port index %i, port id %i, copp idx %i\n", + __func__, p_idx, port_id, copp_idx); + + ret = -EINVAL; + goto done; + } + + admp.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + admp.hdr.pkt_size = sizeof(admp); + admp.hdr.src_svc = APR_SVC_ADM; + admp.hdr.src_domain = APR_DOMAIN_APPS; + admp.hdr.src_port = port_id; + admp.hdr.dest_svc = APR_SVC_ADM; + admp.hdr.dest_domain = APR_DOMAIN_ADSP; + admp.hdr.dest_port = atomic_read(&this_adm.copp.id[p_idx][copp_idx]); + admp.hdr.token = p_idx << 16 | ADM_CLIENT_ID_SOURCE_TRACKING << 8 | + copp_idx; + admp.hdr.opcode = ADM_CMD_GET_PP_PARAMS_V5; + admp.data_payload_addr_lsw = + lower_32_bits(this_adm.sourceTrackingData.memmap.paddr); + admp.data_payload_addr_msw = + msm_audio_populate_upper_32_bits( + this_adm.sourceTrackingData.memmap.paddr); + admp.mem_map_handle = atomic_read(&this_adm.mem_map_handles[ + ADM_MEM_MAP_INDEX_SOURCE_TRACKING]); + admp.module_id = VOICEPROC_MODULE_ID_GENERIC_TX; + admp.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOURCETRACKING; + admp.param_max_size = sizeof(struct adm_param_fluence_sourcetracking_t) + + sizeof(struct adm_param_data_v5); + admp.reserved = 0; + + atomic_set(&this_adm.copp.stat[p_idx][copp_idx], -1); + + ret = apr_send_pkt(this_adm.apr, (uint32_t *)&admp); + if (ret < 0) { + pr_err("%s - failed to get Source Tracking Params\n", + __func__); + + ret = -EINVAL; + goto done; + } + ret = wait_event_timeout(this_adm.copp.wait[p_idx][copp_idx], + atomic_read(&this_adm.copp.stat[p_idx][copp_idx]) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s - get params timed out\n", __func__); + + ret = -EINVAL; + goto done; + } else if (atomic_read(&this_adm.copp.stat + [p_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_adm.copp.stat + [p_idx][copp_idx]))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [p_idx][copp_idx])); + goto done; + } + + if (this_adm.sourceTrackingData.apr_cmd_status != 0) { + pr_err("%s - get params returned error [%s]\n", + __func__, adsp_err_get_err_str( + this_adm.sourceTrackingData.apr_cmd_status)); + + ret = adsp_err_get_lnx_err_code( + this_adm.sourceTrackingData.apr_cmd_status); + goto done; + } + + source_tracking_params = (struct adm_param_fluence_sourcetracking_t *) + (this_adm.sourceTrackingData.memmap.kvaddr + + sizeof(struct adm_param_data_v5)); + for (i = 0; i < MAX_SECTORS; i++) { + sourceTrackingData->vad[i] = source_tracking_params->vad[i]; + pr_debug("%s: vad[%d] = %d\n", + __func__, i, sourceTrackingData->vad[i]); + } + sourceTrackingData->doa_speech = source_tracking_params->doa_speech; + pr_debug("%s: doa_speech = %d\n", + __func__, sourceTrackingData->doa_speech); + + for (i = 0; i < MAX_NOISE_SOURCE_INDICATORS; i++) { + sourceTrackingData->doa_noise[i] = + source_tracking_params->doa_noise[i]; + pr_debug("%s: doa_noise[%d] = %d\n", + __func__, i, sourceTrackingData->doa_noise[i]); + } + for (i = 0; i < MAX_POLAR_ACTIVITY_INDICATORS; i++) { + sourceTrackingData->polar_activity[i] = + source_tracking_params->polar_activity[i]; + pr_debug("%s: polar_activity[%d] = %d\n", + __func__, i, sourceTrackingData->polar_activity[i]); + } + + ret = 0; + +done: + pr_debug("%s: Exit, ret=%d\n", __func__, ret); + + return ret; +} + +static int __init adm_init(void) +{ + int i = 0, j; + + this_adm.apr = NULL; + this_adm.ec_ref_rx = -1; + this_adm.num_ec_ref_rx_chans = 0; + this_adm.ec_ref_rx_bit_width = 0; + this_adm.ec_ref_rx_sampling_rate = 0; + atomic_set(&this_adm.matrix_map_stat, 0); + init_waitqueue_head(&this_adm.matrix_map_wait); + atomic_set(&this_adm.adm_stat, 0); + init_waitqueue_head(&this_adm.adm_wait); + + for (i = 0; i < AFE_MAX_PORTS; i++) { + for (j = 0; j < MAX_COPPS_PER_PORT; j++) { + atomic_set(&this_adm.copp.id[i][j], RESET_COPP_ID); + atomic_set(&this_adm.copp.cnt[i][j], 0); + atomic_set(&this_adm.copp.topology[i][j], 0); + atomic_set(&this_adm.copp.mode[i][j], 0); + atomic_set(&this_adm.copp.stat[i][j], 0); + atomic_set(&this_adm.copp.rate[i][j], 0); + atomic_set(&this_adm.copp.channels[i][j], 0); + atomic_set(&this_adm.copp.bit_width[i][j], 0); + atomic_set(&this_adm.copp.app_type[i][j], 0); + atomic_set(&this_adm.copp.acdb_id[i][j], 0); + init_waitqueue_head(&this_adm.copp.wait[i][j]); + atomic_set(&this_adm.copp.adm_delay_stat[i][j], 0); + init_waitqueue_head( + &this_adm.copp.adm_delay_wait[i][j]); + atomic_set(&this_adm.copp.topology[i][j], 0); + this_adm.copp.adm_delay[i][j] = 0; + this_adm.copp.adm_status[i][j] = + ADM_STATUS_CALIBRATION_REQUIRED; + } + } + + if (adm_init_cal_data()) + pr_err("%s: could not init cal data!\n", __func__); + + this_adm.sourceTrackingData.ion_client = NULL; + this_adm.sourceTrackingData.ion_handle = NULL; + this_adm.sourceTrackingData.memmap.size = 0; + this_adm.sourceTrackingData.memmap.kvaddr = NULL; + this_adm.sourceTrackingData.memmap.paddr = 0; + this_adm.sourceTrackingData.apr_cmd_status = -1; + atomic_set(&this_adm.mem_map_handles[ADM_MEM_MAP_INDEX_SOURCE_TRACKING], + 0); + + return 0; +} + +static void __exit adm_exit(void) +{ + adm_delete_cal_data(); +} + +device_initcall(adm_init); +module_exit(adm_exit); diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c new file mode 100644 index 000000000000..e1ce947cba48 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -0,0 +1,7150 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm-pcm-routing-v2.h" +#include +#include +#include + +#define WAKELOCK_TIMEOUT 5000 +enum { + AFE_COMMON_RX_CAL = 0, + AFE_COMMON_TX_CAL, + AFE_AANC_CAL, + AFE_FB_SPKR_PROT_CAL, + AFE_HW_DELAY_CAL, + AFE_SIDETONE_CAL, + AFE_SIDETONE_IIR_CAL, + AFE_TOPOLOGY_CAL, + AFE_CUST_TOPOLOGY_CAL, + AFE_FB_SPKR_PROT_TH_VI_CAL, + AFE_FB_SPKR_PROT_EX_VI_CAL, + MAX_AFE_CAL_TYPES +}; + +enum fbsp_state { + FBSP_INCORRECT_OP_MODE, + FBSP_INACTIVE, + FBSP_WARMUP, + FBSP_IN_PROGRESS, + FBSP_SUCCESS, + FBSP_FAILED, + MAX_FBSP_STATE +}; + +static char fbsp_state[MAX_FBSP_STATE][50] = { + [FBSP_INCORRECT_OP_MODE] = "incorrect operation mode", + [FBSP_INACTIVE] = "port not started", + [FBSP_WARMUP] = "waiting for warmup", + [FBSP_IN_PROGRESS] = "in progress state", + [FBSP_SUCCESS] = "success", + [FBSP_FAILED] = "failed" +}; + +enum { + USE_CALIBRATED_R0TO, + USE_SAFE_R0TO +}; + +enum { + QUICK_CALIB_DISABLE, + QUICK_CALIB_ENABLE +}; + +enum { + Q6AFE_MSM_SPKR_PROCESSING = 0, + Q6AFE_MSM_SPKR_CALIBRATION, + Q6AFE_MSM_SPKR_FTM_MODE +}; + +struct wlock { + struct wakeup_source ws; +}; + +static struct wlock wl; + +struct afe_ctl { + void *apr; + atomic_t state; + atomic_t status; + wait_queue_head_t wait[AFE_MAX_PORTS]; + struct task_struct *task; + void (*tx_cb)(uint32_t opcode, + uint32_t token, uint32_t *payload, void *priv); + void (*rx_cb)(uint32_t opcode, + uint32_t token, uint32_t *payload, void *priv); + void *tx_private_data; + void *rx_private_data; + uint32_t mmap_handle; + + int topology[AFE_MAX_PORTS]; + struct cal_type_data *cal_data[MAX_AFE_CAL_TYPES]; + + atomic_t mem_map_cal_handles[MAX_AFE_CAL_TYPES]; + atomic_t mem_map_cal_index; + u32 afe_cal_mode[AFE_MAX_PORTS]; + + u16 dtmf_gen_rx_portid; + struct audio_cal_info_spk_prot_cfg prot_cfg; + struct afe_spkr_prot_calib_get_resp calib_data; + struct audio_cal_info_sp_th_vi_ftm_cfg th_ftm_cfg; + struct audio_cal_info_sp_ex_vi_ftm_cfg ex_ftm_cfg; + struct afe_sp_th_vi_get_param_resp th_vi_resp; + struct afe_sp_ex_vi_get_param_resp ex_vi_resp; + struct afe_av_dev_drift_get_param_resp av_dev_drift_resp; + int vi_tx_port; + int vi_rx_port; + uint32_t afe_sample_rates[AFE_MAX_PORTS]; + struct aanc_data aanc_info; + struct mutex afe_cmd_lock; + int set_custom_topology; + int dev_acdb_id[AFE_MAX_PORTS]; + routing_cb rt_cb; +}; + +static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX]; +static unsigned long afe_configured_cmd; + +static struct afe_ctl this_afe; + +#define TIMEOUT_MS 1000 +#define Q6AFE_MAX_VOLUME 0x3FFF + +static int pcm_afe_instance[2]; +static int proxy_afe_instance[2]; +bool afe_close_done[2] = {true, true}; + +#define SIZEOF_CFG_CMD(y) \ + (sizeof(struct apr_hdr) + sizeof(u16) + (sizeof(struct y))) + +static int afe_get_cal_hw_delay(int32_t path, + struct audio_cal_hw_delay_entry *entry); +static int remap_cal_data(struct cal_block_data *cal_block, int cal_index); + +int afe_get_topology(int port_id) +{ + int topology; + int port_index = afe_get_port_index(port_id); + + if ((port_index < 0) || (port_index >= AFE_MAX_PORTS)) { + pr_err("%s: Invalid port index %d\n", __func__, port_index); + topology = -EINVAL; + goto done; + } + + topology = this_afe.topology[port_index]; +done: + return topology; +} + +void afe_set_aanc_info(struct aanc_data *q6_aanc_info) +{ + this_afe.aanc_info.aanc_active = q6_aanc_info->aanc_active; + this_afe.aanc_info.aanc_rx_port = q6_aanc_info->aanc_rx_port; + this_afe.aanc_info.aanc_tx_port = q6_aanc_info->aanc_tx_port; + + pr_debug("%s: aanc active is %d rx port is 0x%x, tx port is 0x%x\n", + __func__, + this_afe.aanc_info.aanc_active, + this_afe.aanc_info.aanc_rx_port, + this_afe.aanc_info.aanc_tx_port); +} + +static void afe_callback_debug_print(struct apr_client_data *data) +{ + uint32_t *payload; + + payload = data->payload; + + if (data->payload_size >= 8) + pr_debug("%s: code = 0x%x PL#0[0x%x], PL#1[0x%x], size = %d\n", + __func__, data->opcode, payload[0], payload[1], + data->payload_size); + else if (data->payload_size >= 4) + pr_debug("%s: code = 0x%x PL#0[0x%x], size = %d\n", + __func__, data->opcode, payload[0], + data->payload_size); + else + pr_debug("%s: code = 0x%x, size = %d\n", + __func__, data->opcode, data->payload_size); +} + +static void av_dev_drift_afe_cb_handler(uint32_t *payload, + uint32_t payload_size) +{ + u32 param_id; + struct afe_av_dev_drift_get_param_resp *resp = + (struct afe_av_dev_drift_get_param_resp *) payload; + + if (!(&(resp->pdata))) { + pr_err("%s: Error: resp pdata is NULL\n", __func__); + return; + } + + param_id = resp->pdata.param_id; + if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) { + if (payload_size < sizeof(this_afe.av_dev_drift_resp)) { + pr_err("%s: Error: received size %d, resp size %zu\n", + __func__, payload_size, + sizeof(this_afe.av_dev_drift_resp)); + return; + } + memcpy(&this_afe.av_dev_drift_resp, payload, + sizeof(this_afe.av_dev_drift_resp)); + if (!this_afe.av_dev_drift_resp.status) { + atomic_set(&this_afe.state, 0); + } else { + pr_debug("%s: av_dev_drift_resp status: %d", __func__, + this_afe.av_dev_drift_resp.status); + atomic_set(&this_afe.state, -1); + } + } +} + +static int32_t sp_make_afe_callback(uint32_t *payload, uint32_t payload_size) +{ + u32 param_id; + struct afe_spkr_prot_calib_get_resp *resp = + (struct afe_spkr_prot_calib_get_resp *) payload; + + if (!(&(resp->pdata))) { + pr_err("%s: Error: resp pdata is NULL\n", __func__); + return -EINVAL; + } + + param_id = resp->pdata.param_id; + if (param_id == AFE_PARAM_ID_CALIB_RES_CFG_V2) { + if (payload_size < sizeof(this_afe.calib_data)) { + pr_err("%s: Error: received size %d, calib_data size %zu\n", + __func__, payload_size, + sizeof(this_afe.calib_data)); + return -EINVAL; + } + memcpy(&this_afe.calib_data, payload, + sizeof(this_afe.calib_data)); + if (!this_afe.calib_data.status) { + atomic_set(&this_afe.state, 0); + } else { + pr_debug("%s: calib resp status: %d", __func__, + this_afe.calib_data.status); + atomic_set(&this_afe.state, -1); + } + } + if (param_id == AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS) { + if (payload_size < sizeof(this_afe.th_vi_resp)) { + pr_err("%s: Error: received size %d, th_vi_resp size %zu\n", + __func__, payload_size, + sizeof(this_afe.th_vi_resp)); + return -EINVAL; + } + memcpy(&this_afe.th_vi_resp, payload, + sizeof(this_afe.th_vi_resp)); + if (!this_afe.th_vi_resp.status) { + atomic_set(&this_afe.state, 0); + } else { + pr_debug("%s: th vi resp status: %d", __func__, + this_afe.th_vi_resp.status); + atomic_set(&this_afe.state, -1); + } + } + if (param_id == AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS) { + if (payload_size < sizeof(this_afe.ex_vi_resp)) { + pr_err("%s: Error: received size %d, ex_vi_resp size %zu\n", + __func__, payload_size, + sizeof(this_afe.ex_vi_resp)); + return -EINVAL; + } + memcpy(&this_afe.ex_vi_resp, payload, + sizeof(this_afe.ex_vi_resp)); + if (!this_afe.ex_vi_resp.status) { + atomic_set(&this_afe.state, 0); + } else { + pr_debug("%s: ex vi resp status: %d", __func__, + this_afe.ex_vi_resp.status); + atomic_set(&this_afe.state, -1); + } + } + + return 0; +} + +static int32_t afe_callback(struct apr_client_data *data, void *priv) +{ + if (!data) { + pr_err("%s: Invalid param data\n", __func__); + return -EINVAL; + } + if (data->opcode == RESET_EVENTS) { + pr_debug("%s: reset event = %d %d apr[%pK]\n", + __func__, + data->reset_event, data->reset_proc, this_afe.apr); + + cal_utils_clear_cal_block_q6maps(MAX_AFE_CAL_TYPES, + this_afe.cal_data); + + /* Reset the custom topology mode: to resend again to AFE. */ + mutex_lock(&this_afe.cal_data[AFE_CUST_TOPOLOGY_CAL]->lock); + this_afe.set_custom_topology = 1; + mutex_unlock(&this_afe.cal_data[AFE_CUST_TOPOLOGY_CAL]->lock); + rtac_clear_mapping(AFE_RTAC_CAL); + + if (this_afe.apr) { + apr_reset(this_afe.apr); + atomic_set(&this_afe.state, 0); + this_afe.apr = NULL; + rtac_set_afe_handle(this_afe.apr); + } + /* send info to user */ + if (this_afe.task == NULL) + this_afe.task = current; + pr_debug("%s: task_name = %s pid = %d\n", + __func__, + this_afe.task->comm, this_afe.task->pid); + + /* + * Pass reset events to proxy driver, if cb is registered + */ + if (this_afe.tx_cb) { + this_afe.tx_cb(data->opcode, data->token, + data->payload, + this_afe.tx_private_data); + this_afe.tx_cb = NULL; + } + if (this_afe.rx_cb) { + this_afe.rx_cb(data->opcode, data->token, + data->payload, + this_afe.rx_private_data); + this_afe.rx_cb = NULL; + } + + return 0; + } + afe_callback_debug_print(data); + if (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V2) { + uint32_t *payload = data->payload; + + if (!payload || (data->token >= AFE_MAX_PORTS)) { + pr_err("%s: Error: size %d payload %pK token %d\n", + __func__, data->payload_size, + payload, data->token); + return -EINVAL; + } + + if (payload[2] == AFE_PARAM_ID_DEV_TIMING_STATS) { + av_dev_drift_afe_cb_handler(data->payload, + data->payload_size); + } else { + if (rtac_make_afe_callback(data->payload, + data->payload_size)) + return 0; + + if (sp_make_afe_callback(data->payload, + data->payload_size)) + return -EINVAL; + } + wake_up(&this_afe.wait[data->token]); + } else if (data->payload_size) { + uint32_t *payload; + uint16_t port_id = 0; + + payload = data->payload; + if (data->opcode == APR_BASIC_RSP_RESULT) { + pr_debug("%s:opcode = 0x%x cmd = 0x%x status = 0x%x token=%d\n", + __func__, data->opcode, + payload[0], payload[1], data->token); + /* payload[1] contains the error status for response */ + if (payload[1] != 0) { + atomic_set(&this_afe.status, payload[1]); + pr_err("%s: cmd = 0x%x returned error = 0x%x\n", + __func__, payload[0], payload[1]); + } + switch (payload[0]) { + case AFE_PORT_CMD_SET_PARAM_V2: + if (rtac_make_afe_callback(payload, + data->payload_size)) + return 0; + case AFE_PORT_CMD_DEVICE_STOP: + case AFE_PORT_CMD_DEVICE_START: + case AFE_PSEUDOPORT_CMD_START: + case AFE_PSEUDOPORT_CMD_STOP: + case AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS: + case AFE_SERVICE_CMD_SHARED_MEM_UNMAP_REGIONS: + case AFE_SERVICE_CMD_UNREGISTER_RT_PORT_DRIVER: + case AFE_PORTS_CMD_DTMF_CTL: + case AFE_SVC_CMD_SET_PARAM: + atomic_set(&this_afe.state, 0); + wake_up(&this_afe.wait[data->token]); + break; + case AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER: + break; + case AFE_PORT_DATA_CMD_RT_PROXY_PORT_WRITE_V2: + port_id = RT_PROXY_PORT_001_TX; + break; + case AFE_PORT_DATA_CMD_RT_PROXY_PORT_READ_V2: + port_id = RT_PROXY_PORT_001_RX; + break; + case AFE_CMD_ADD_TOPOLOGIES: + atomic_set(&this_afe.state, 0); + wake_up(&this_afe.wait[data->token]); + pr_debug("%s: AFE_CMD_ADD_TOPOLOGIES cmd 0x%x\n", + __func__, payload[1]); + break; + default: + pr_err("%s: Unknown cmd 0x%x\n", __func__, + payload[0]); + break; + } + } else if (data->opcode == + AFE_SERVICE_CMDRSP_SHARED_MEM_MAP_REGIONS) { + pr_debug("%s: mmap_handle: 0x%x, cal index %d\n", + __func__, payload[0], + atomic_read(&this_afe.mem_map_cal_index)); + if (atomic_read(&this_afe.mem_map_cal_index) != -1) + atomic_set(&this_afe.mem_map_cal_handles[ + atomic_read( + &this_afe.mem_map_cal_index)], + (uint32_t)payload[0]); + else + this_afe.mmap_handle = payload[0]; + atomic_set(&this_afe.state, 0); + wake_up(&this_afe.wait[data->token]); + } else if (data->opcode == AFE_EVENT_RT_PROXY_PORT_STATUS) { + port_id = (uint16_t)(0x0000FFFF & payload[0]); + } + pr_debug("%s: port_id = 0x%x\n", __func__, port_id); + switch (port_id) { + case RT_PROXY_PORT_001_TX: { + if (this_afe.tx_cb) { + this_afe.tx_cb(data->opcode, data->token, + data->payload, + this_afe.tx_private_data); + } + break; + } + case RT_PROXY_PORT_001_RX: { + if (this_afe.rx_cb) { + this_afe.rx_cb(data->opcode, data->token, + data->payload, + this_afe.rx_private_data); + } + break; + } + default: + pr_debug("%s: default case 0x%x\n", __func__, port_id); + break; + } + } + return 0; +} + +int afe_get_port_type(u16 port_id) +{ + int ret; + + switch (port_id) { + case PRIMARY_I2S_RX: + case SECONDARY_I2S_RX: + case MI2S_RX: + case HDMI_RX: + case DISPLAY_PORT_RX: + case AFE_PORT_ID_SPDIF_RX: + case SLIMBUS_0_RX: + case SLIMBUS_1_RX: + case SLIMBUS_2_RX: + case SLIMBUS_3_RX: + case SLIMBUS_4_RX: + case SLIMBUS_5_RX: + case SLIMBUS_6_RX: + case SLIMBUS_7_RX: + case SLIMBUS_8_RX: + case INT_BT_SCO_RX: + case INT_BT_A2DP_RX: + case INT_FM_RX: + case VOICE_PLAYBACK_TX: + case VOICE2_PLAYBACK_TX: + case RT_PROXY_PORT_001_RX: + case AUDIO_PORT_ID_I2S_RX: + case AFE_PORT_ID_PRIMARY_MI2S_RX: + case AFE_PORT_ID_SECONDARY_MI2S_RX: + case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1: + case AFE_PORT_ID_TERTIARY_MI2S_RX: + case AFE_PORT_ID_QUATERNARY_MI2S_RX: + case AFE_PORT_ID_QUINARY_MI2S_RX: + case AFE_PORT_ID_PRIMARY_PCM_RX: + case AFE_PORT_ID_SECONDARY_PCM_RX: + case AFE_PORT_ID_TERTIARY_PCM_RX: + case AFE_PORT_ID_QUATERNARY_PCM_RX: + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + case AFE_PORT_ID_USB_RX: + case AFE_PORT_ID_INT0_MI2S_RX: + case AFE_PORT_ID_INT1_MI2S_RX: + case AFE_PORT_ID_INT2_MI2S_RX: + case AFE_PORT_ID_INT3_MI2S_RX: + case AFE_PORT_ID_INT4_MI2S_RX: + case AFE_PORT_ID_INT5_MI2S_RX: + case AFE_PORT_ID_INT6_MI2S_RX: + ret = MSM_AFE_PORT_TYPE_RX; + break; + + case PRIMARY_I2S_TX: + case SECONDARY_I2S_TX: + case MI2S_TX: + case DIGI_MIC_TX: + case VOICE_RECORD_TX: + case SLIMBUS_0_TX: + case SLIMBUS_1_TX: + case SLIMBUS_2_TX: + case SLIMBUS_3_TX: + case SLIMBUS_4_TX: + case SLIMBUS_5_TX: + case SLIMBUS_6_TX: + case SLIMBUS_7_TX: + case SLIMBUS_8_TX: + case INT_FM_TX: + case VOICE_RECORD_RX: + case INT_BT_SCO_TX: + case RT_PROXY_PORT_001_TX: + case AFE_PORT_ID_PRIMARY_MI2S_TX: + case AFE_PORT_ID_SECONDARY_MI2S_TX: + case AFE_PORT_ID_TERTIARY_MI2S_TX: + case AFE_PORT_ID_QUATERNARY_MI2S_TX: + case AFE_PORT_ID_QUINARY_MI2S_TX: + case AFE_PORT_ID_SENARY_MI2S_TX: + case AFE_PORT_ID_PRIMARY_PCM_TX: + case AFE_PORT_ID_SECONDARY_PCM_TX: + case AFE_PORT_ID_TERTIARY_PCM_TX: + case AFE_PORT_ID_QUATERNARY_PCM_TX: + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + case AFE_PORT_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + case AFE_PORT_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + case AFE_PORT_ID_USB_TX: + case AFE_PORT_ID_INT0_MI2S_TX: + case AFE_PORT_ID_INT1_MI2S_TX: + case AFE_PORT_ID_INT2_MI2S_TX: + case AFE_PORT_ID_INT3_MI2S_TX: + case AFE_PORT_ID_INT4_MI2S_TX: + case AFE_PORT_ID_INT5_MI2S_TX: + case AFE_PORT_ID_INT6_MI2S_TX: + ret = MSM_AFE_PORT_TYPE_TX; + break; + + default: + WARN_ON(1); + pr_err("%s: Invalid port id = 0x%x\n", + __func__, port_id); + ret = -EINVAL; + } + + return ret; +} + +int afe_sizeof_cfg_cmd(u16 port_id) +{ + int ret_size; + + switch (port_id) { + case PRIMARY_I2S_RX: + case PRIMARY_I2S_TX: + case SECONDARY_I2S_RX: + case SECONDARY_I2S_TX: + case MI2S_RX: + case MI2S_TX: + case AFE_PORT_ID_PRIMARY_MI2S_RX: + case AFE_PORT_ID_PRIMARY_MI2S_TX: + case AFE_PORT_ID_QUATERNARY_MI2S_RX: + case AFE_PORT_ID_QUATERNARY_MI2S_TX: + case AFE_PORT_ID_QUINARY_MI2S_RX: + case AFE_PORT_ID_QUINARY_MI2S_TX: + ret_size = SIZEOF_CFG_CMD(afe_param_id_i2s_cfg); + break; + case HDMI_RX: + case DISPLAY_PORT_RX: + ret_size = + SIZEOF_CFG_CMD(afe_param_id_hdmi_multi_chan_audio_cfg); + break; + case SLIMBUS_0_RX: + case SLIMBUS_0_TX: + case SLIMBUS_1_RX: + case SLIMBUS_1_TX: + case SLIMBUS_2_RX: + case SLIMBUS_2_TX: + case SLIMBUS_3_RX: + case SLIMBUS_3_TX: + case SLIMBUS_4_RX: + case SLIMBUS_4_TX: + case SLIMBUS_5_RX: + case SLIMBUS_5_TX: + case SLIMBUS_6_RX: + case SLIMBUS_6_TX: + case SLIMBUS_7_RX: + case SLIMBUS_7_TX: + case SLIMBUS_8_RX: + case SLIMBUS_8_TX: + ret_size = SIZEOF_CFG_CMD(afe_param_id_slimbus_cfg); + break; + case VOICE_PLAYBACK_TX: + case VOICE2_PLAYBACK_TX: + case VOICE_RECORD_RX: + case VOICE_RECORD_TX: + ret_size = SIZEOF_CFG_CMD(afe_param_id_pseudo_port_cfg); + break; + case RT_PROXY_PORT_001_RX: + case RT_PROXY_PORT_001_TX: + ret_size = SIZEOF_CFG_CMD(afe_param_id_rt_proxy_port_cfg); + break; + case AFE_PORT_ID_USB_RX: + case AFE_PORT_ID_USB_TX: + ret_size = SIZEOF_CFG_CMD(afe_param_id_usb_audio_cfg); + break; + case AFE_PORT_ID_PRIMARY_PCM_RX: + case AFE_PORT_ID_PRIMARY_PCM_TX: + case AFE_PORT_ID_SECONDARY_PCM_RX: + case AFE_PORT_ID_SECONDARY_PCM_TX: + case AFE_PORT_ID_TERTIARY_PCM_RX: + case AFE_PORT_ID_TERTIARY_PCM_TX: + case AFE_PORT_ID_QUATERNARY_PCM_RX: + case AFE_PORT_ID_QUATERNARY_PCM_TX: + default: + pr_debug("%s: default case 0x%x\n", __func__, port_id); + ret_size = SIZEOF_CFG_CMD(afe_param_id_pcm_cfg); + break; + } + return ret_size; +} + +int afe_q6_interface_prepare(void) +{ + int ret = 0; + + pr_debug("%s:\n", __func__); + + if (this_afe.apr == NULL) { + this_afe.apr = apr_register("ADSP", "AFE", afe_callback, + 0xFFFFFFFF, &this_afe); + if (this_afe.apr == NULL) { + pr_err("%s: Unable to register AFE\n", __func__); + ret = -ENODEV; + } + rtac_set_afe_handle(this_afe.apr); + } + return ret; +} + +/* + * afe_apr_send_pkt : returns 0 on success, negative otherwise. + */ +static int afe_apr_send_pkt(void *data, wait_queue_head_t *wait) +{ + int ret; + + if (wait) + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, data); + if (ret > 0) { + if (wait) { + ret = wait_event_timeout(*wait, + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + ret = -ETIMEDOUT; + } else if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(atomic_read( + &this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + } else { + ret = 0; + } + } else { + ret = 0; + } + } else if (ret == 0) { + pr_err("%s: packet not transmitted\n", __func__); + /* apr_send_pkt can return 0 when nothing is transmitted */ + ret = -EINVAL; + } + + pr_debug("%s: leave %d\n", __func__, ret); + return ret; +} + +static int afe_send_cal_block(u16 port_id, struct cal_block_data *cal_block) +{ + int result = 0; + int index = 0; + struct afe_audioif_config_command_no_payload afe_cal; + + if (!cal_block) { + pr_debug("%s: No AFE cal to send!\n", __func__); + result = -EINVAL; + goto done; + } + if (cal_block->cal_data.size <= 0) { + pr_debug("%s: AFE cal has invalid size!\n", __func__); + result = -EINVAL; + goto done; + } + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + result = -EINVAL; + goto done; + } + + afe_cal.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + afe_cal.hdr.pkt_size = sizeof(afe_cal); + afe_cal.hdr.src_port = 0; + afe_cal.hdr.dest_port = 0; + afe_cal.hdr.token = index; + afe_cal.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + afe_cal.param.port_id = port_id; + afe_cal.param.payload_size = cal_block->cal_data.size; + afe_cal.param.payload_address_lsw = + lower_32_bits(cal_block->cal_data.paddr); + afe_cal.param.payload_address_msw = + msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr); + afe_cal.param.mem_map_handle = cal_block->map_data.q6map_handle; + + pr_debug("%s: AFE cal sent for device port = 0x%x, cal size = %zd, cal addr = 0x%pK\n", + __func__, port_id, + cal_block->cal_data.size, &cal_block->cal_data.paddr); + + result = afe_apr_send_pkt(&afe_cal, &this_afe.wait[index]); + if (result) + pr_err("%s: AFE cal for port 0x%x failed %d\n", + __func__, port_id, result); + +done: + return result; +} + + +static int afe_send_custom_topology_block(struct cal_block_data *cal_block) +{ + int result = 0; + int index = 0; + struct cmd_set_topologies afe_cal; + + if (!cal_block) { + pr_err("%s: No AFE SVC cal to send!\n", __func__); + return -EINVAL; + } + if (cal_block->cal_data.size <= 0) { + pr_err("%s: AFE SVC cal has invalid size: %zd!\n", + __func__, cal_block->cal_data.size); + return -EINVAL; + } + + afe_cal.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + afe_cal.hdr.pkt_size = sizeof(afe_cal); + afe_cal.hdr.src_port = 0; + afe_cal.hdr.dest_port = 0; + afe_cal.hdr.token = index; + afe_cal.hdr.opcode = AFE_CMD_ADD_TOPOLOGIES; + + afe_cal.payload_size = cal_block->cal_data.size; + afe_cal.payload_addr_lsw = + lower_32_bits(cal_block->cal_data.paddr); + afe_cal.payload_addr_msw = + msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr); + afe_cal.mem_map_handle = cal_block->map_data.q6map_handle; + + pr_debug("%s:cmd_id:0x%x calsize:%zd memmap_hdl:0x%x caladdr:0x%pK", + __func__, AFE_CMD_ADD_TOPOLOGIES, cal_block->cal_data.size, + afe_cal.mem_map_handle, &cal_block->cal_data.paddr); + + result = afe_apr_send_pkt(&afe_cal, &this_afe.wait[index]); + if (result) + pr_err("%s: AFE send topology for command 0x%x failed %d\n", + __func__, AFE_CMD_ADD_TOPOLOGIES, result); + + return result; +} + +static void afe_send_custom_topology(void) +{ + struct cal_block_data *cal_block = NULL; + int cal_index = AFE_CUST_TOPOLOGY_CAL; + int ret; + + if (this_afe.cal_data[cal_index] == NULL) { + pr_err("%s: cal_index %d not allocated!\n", + __func__, cal_index); + return; + } + mutex_lock(&this_afe.cal_data[cal_index]->lock); + + if (!this_afe.set_custom_topology) + goto unlock; + this_afe.set_custom_topology = 0; + cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); + if (cal_block == NULL) { + pr_err("%s cal_block not found!!\n", __func__); + goto unlock; + } + + pr_debug("%s: Sending cal_index cal %d\n", __func__, cal_index); + + ret = remap_cal_data(cal_block, cal_index); + if (ret) { + pr_err("%s: Remap_cal_data failed for cal %d!\n", + __func__, cal_index); + goto unlock; + } + ret = afe_send_custom_topology_block(cal_block); + if (ret < 0) { + pr_err("%s: No cal sent for cal_index %d! ret %d\n", + __func__, cal_index, ret); + goto unlock; + } + pr_debug("%s:sent custom topology for AFE\n", __func__); +unlock: + mutex_unlock(&this_afe.cal_data[cal_index]->lock); +} + +static int afe_spk_ramp_dn_cfg(int port) +{ + int ret = -EINVAL; + int index = 0; + struct afe_spkr_prot_config_command config; + + if (afe_get_port_type(port) != MSM_AFE_PORT_TYPE_RX) { + pr_debug("%s: port doesn't match 0x%x\n", __func__, port); + return 0; + } + if (this_afe.prot_cfg.mode == MSM_SPKR_PROT_DISABLED || + (this_afe.vi_rx_port != port)) { + pr_debug("%s: spkr protection disabled port 0x%x %d 0x%x\n", + __func__, port, ret, this_afe.vi_rx_port); + return 0; + } + memset(&config, 0, sizeof(config)); + ret = q6audio_validate_port(port); + if (ret < 0) { + pr_err("%s: Invalid port 0x%x ret %d", __func__, port, ret); + ret = -EINVAL; + goto fail_cmd; + } + index = q6audio_get_port_index(port); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + ret = -EINVAL; + goto fail_cmd; + } + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = index; + + config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + config.param.port_id = q6audio_get_port_id(port); + config.param.payload_size = + sizeof(config) - sizeof(config.hdr) - sizeof(config.param) + - sizeof(config.prot_config); + config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; + config.pdata.param_id = AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG; + config.pdata.param_size = 0; + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config); + if (ret < 0) { + pr_err("%s: port = 0x%x param = 0x%x failed %d\n", + __func__, port, config.pdata.param_id, ret); + goto fail_cmd; + } + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto fail_cmd; + } + /* dsp needs atleast 15ms to ramp down pilot tone*/ + usleep_range(15000, 15010); + ret = 0; +fail_cmd: + pr_debug("%s: config.pdata.param_id 0x%x status %d\n", + __func__, config.pdata.param_id, ret); +return ret; +} + +static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, + union afe_spkr_prot_config *prot_config) +{ + int ret = -EINVAL; + int index = 0; + struct afe_spkr_prot_config_command config; + + memset(&config, 0, sizeof(config)); + if (!prot_config) { + pr_err("%s: Invalid params\n", __func__); + goto fail_cmd; + } + ret = q6audio_validate_port(src_port); + if (ret < 0) { + pr_err("%s: Invalid src port 0x%x ret %d", + __func__, src_port, ret); + ret = -EINVAL; + goto fail_cmd; + } + ret = q6audio_validate_port(dst_port); + if (ret < 0) { + pr_err("%s: Invalid dst port 0x%x ret %d", __func__, + dst_port, ret); + ret = -EINVAL; + goto fail_cmd; + } + index = q6audio_get_port_index(src_port); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + ret = -EINVAL; + goto fail_cmd; + } + switch (param_id) { + case AFE_PARAM_ID_FBSP_MODE_RX_CFG: + config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; + break; + case AFE_PARAM_ID_FEEDBACK_PATH_CFG: + this_afe.vi_tx_port = src_port; + this_afe.vi_rx_port = dst_port; + config.pdata.module_id = AFE_MODULE_FEEDBACK; + break; + /* + * AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2 is same as + * AFE_PARAM_ID_SP_V2_TH_VI_MODE_CFG + */ + case AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2: + case AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG: + config.pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; + break; + case AFE_PARAM_ID_SP_V2_EX_VI_MODE_CFG: + case AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG: + config.pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; + break; + default: + pr_err("%s: default case 0x%x\n", __func__, param_id); + goto fail_cmd; + } + + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = index; + + config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + config.param.port_id = q6audio_get_port_id(src_port); + config.param.payload_size = sizeof(config) - sizeof(config.hdr) + - sizeof(config.param); + config.pdata.param_id = param_id; + config.pdata.param_size = sizeof(config.prot_config); + config.prot_config = *prot_config; + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config); + if (ret < 0) { + pr_err("%s: port = 0x%x param = 0x%x failed %d\n", + __func__, src_port, param_id, ret); + goto fail_cmd; + } + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto fail_cmd; + } + ret = 0; +fail_cmd: + pr_debug("%s: config.pdata.param_id 0x%x status %d 0x%x\n", + __func__, config.pdata.param_id, ret, src_port); + return ret; +} + +static void afe_send_cal_spkr_prot_tx(int port_id) +{ + union afe_spkr_prot_config afe_spk_config; + + if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL || + this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL || + this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL) + return; + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); + if ((this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED) && + (this_afe.vi_tx_port == port_id)) { + if (this_afe.prot_cfg.mode == + MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) { + afe_spk_config.vi_proc_cfg.operation_mode = + Q6AFE_MSM_SPKR_CALIBRATION; + afe_spk_config.vi_proc_cfg.quick_calib_flag = + this_afe.prot_cfg.quick_calib_flag; + } else { + afe_spk_config.vi_proc_cfg.operation_mode = + Q6AFE_MSM_SPKR_PROCESSING; + } + + if (this_afe.th_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) + afe_spk_config.vi_proc_cfg.operation_mode = + Q6AFE_MSM_SPKR_FTM_MODE; + afe_spk_config.vi_proc_cfg.minor_version = 1; + afe_spk_config.vi_proc_cfg.r0_cali_q24[SP_V2_SPKR_1] = + (uint32_t) this_afe.prot_cfg.r0[SP_V2_SPKR_1]; + afe_spk_config.vi_proc_cfg.r0_cali_q24[SP_V2_SPKR_2] = + (uint32_t) this_afe.prot_cfg.r0[SP_V2_SPKR_2]; + afe_spk_config.vi_proc_cfg.t0_cali_q6[SP_V2_SPKR_1] = + (uint32_t) this_afe.prot_cfg.t0[SP_V2_SPKR_1]; + afe_spk_config.vi_proc_cfg.t0_cali_q6[SP_V2_SPKR_2] = + (uint32_t) this_afe.prot_cfg.t0[SP_V2_SPKR_2]; + if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_NOT_CALIBRATED) { + struct asm_spkr_calib_vi_proc_cfg *vi_proc_cfg; + + vi_proc_cfg = &afe_spk_config.vi_proc_cfg; + vi_proc_cfg->r0_t0_selection_flag[SP_V2_SPKR_1] = + USE_CALIBRATED_R0TO; + vi_proc_cfg->r0_t0_selection_flag[SP_V2_SPKR_2] = + USE_CALIBRATED_R0TO; + } else { + struct asm_spkr_calib_vi_proc_cfg *vi_proc_cfg; + + vi_proc_cfg = &afe_spk_config.vi_proc_cfg; + vi_proc_cfg->r0_t0_selection_flag[SP_V2_SPKR_1] = + USE_SAFE_R0TO; + vi_proc_cfg->r0_t0_selection_flag[SP_V2_SPKR_2] = + USE_SAFE_R0TO; + } + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2, + &afe_spk_config)) + pr_err("%s: SPKR_CALIB_VI_PROC_CFG failed\n", + __func__); + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + if ((this_afe.th_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) && + (this_afe.vi_tx_port == port_id)) { + afe_spk_config.th_vi_ftm_cfg.minor_version = 1; + afe_spk_config.th_vi_ftm_cfg.wait_time_ms[SP_V2_SPKR_1] = + this_afe.th_ftm_cfg.wait_time[SP_V2_SPKR_1]; + afe_spk_config.th_vi_ftm_cfg.wait_time_ms[SP_V2_SPKR_2] = + this_afe.th_ftm_cfg.wait_time[SP_V2_SPKR_2]; + afe_spk_config.th_vi_ftm_cfg.ftm_time_ms[SP_V2_SPKR_1] = + this_afe.th_ftm_cfg.ftm_time[SP_V2_SPKR_1]; + afe_spk_config.th_vi_ftm_cfg.ftm_time_ms[SP_V2_SPKR_2] = + this_afe.th_ftm_cfg.ftm_time[SP_V2_SPKR_2]; + + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG, + &afe_spk_config)) + pr_err("%s: th vi ftm cfg failed\n", __func__); + this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); + if ((this_afe.ex_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) && + (this_afe.vi_tx_port == port_id)) { + afe_spk_config.ex_vi_mode_cfg.minor_version = 1; + afe_spk_config.ex_vi_mode_cfg.operation_mode = + Q6AFE_MSM_SPKR_FTM_MODE; + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V2_EX_VI_MODE_CFG, + &afe_spk_config)) + pr_err("%s: ex vi mode cfg failed\n", __func__); + + afe_spk_config.ex_vi_ftm_cfg.minor_version = 1; + afe_spk_config.ex_vi_ftm_cfg.wait_time_ms[SP_V2_SPKR_1] = + this_afe.ex_ftm_cfg.wait_time[SP_V2_SPKR_1]; + afe_spk_config.ex_vi_ftm_cfg.wait_time_ms[SP_V2_SPKR_2] = + this_afe.ex_ftm_cfg.wait_time[SP_V2_SPKR_2]; + afe_spk_config.ex_vi_ftm_cfg.ftm_time_ms[SP_V2_SPKR_1] = + this_afe.ex_ftm_cfg.ftm_time[SP_V2_SPKR_1]; + afe_spk_config.ex_vi_ftm_cfg.ftm_time_ms[SP_V2_SPKR_2] = + this_afe.ex_ftm_cfg.ftm_time[SP_V2_SPKR_2]; + + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG, + &afe_spk_config)) + pr_err("%s: ex vi ftm cfg failed\n", __func__); + this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); + +} + +static void afe_send_cal_spkr_prot_rx(int port_id) +{ + union afe_spkr_prot_config afe_spk_config; + + if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL) + goto done; + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); + + if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED && + (this_afe.vi_rx_port == port_id)) { + if (this_afe.prot_cfg.mode == + MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) + afe_spk_config.mode_rx_cfg.mode = + Q6AFE_MSM_SPKR_CALIBRATION; + else + afe_spk_config.mode_rx_cfg.mode = + Q6AFE_MSM_SPKR_PROCESSING; + afe_spk_config.mode_rx_cfg.minor_version = 1; + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_FBSP_MODE_RX_CFG, + &afe_spk_config)) + pr_err("%s: RX MODE_VI_PROC_CFG failed\n", + __func__); + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); +done: + return; +} + +static int afe_send_hw_delay(u16 port_id, u32 rate) +{ + struct audio_cal_hw_delay_entry delay_entry; + struct afe_audioif_config_command config; + int index = 0; + int ret = -EINVAL; + + pr_debug("%s:\n", __func__); + + memset(&delay_entry, 0, sizeof(delay_entry)); + delay_entry.sample_rate = rate; + if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX) + ret = afe_get_cal_hw_delay(TX_DEVICE, &delay_entry); + else if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) + ret = afe_get_cal_hw_delay(RX_DEVICE, &delay_entry); + + /* + * HW delay is only used for IMS calls to sync audio with video + * It is only needed for devices & sample rates used for IMS video + * calls. Values are received from ACDB calbration files + */ + if (ret != 0) { + pr_debug("%s: debug: HW delay info not available %d\n", + __func__, ret); + goto fail_cmd; + } + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + ret = -EINVAL; + goto fail_cmd; + } + + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = index; + + config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + config.param.port_id = q6audio_get_port_id(port_id); + config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - + sizeof(config.param); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + config.pdata.param_id = AFE_PARAM_ID_DEVICE_HW_DELAY; + config.pdata.param_size = sizeof(config.port); + + config.port.hw_delay.delay_in_us = delay_entry.delay_usec; + config.port.hw_delay.device_hw_delay_minor_version = + AFE_API_VERSION_DEVICE_HW_DELAY; + + ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE hw delay for port 0x%x failed %d\n", + __func__, port_id, ret); + goto fail_cmd; + } + +fail_cmd: + pr_debug("%s: port_id 0x%x rate %u delay_usec %d status %d\n", + __func__, port_id, rate, delay_entry.delay_usec, ret); + return ret; +} + +static struct cal_block_data *afe_find_cal_topo_id_by_port( + struct cal_type_data *cal_type, u16 port_id) +{ + struct list_head *ptr, *next; + struct cal_block_data *cal_block = NULL; + int32_t path; + struct audio_cal_info_afe_top *afe_top; + int afe_port_index = q6audio_get_port_index(port_id); + + if (afe_port_index < 0) + goto err_exit; + + list_for_each_safe(ptr, next, + &cal_type->cal_blocks) { + cal_block = list_entry(ptr, + struct cal_block_data, list); + + path = ((afe_get_port_type(port_id) == + MSM_AFE_PORT_TYPE_TX)?(TX_DEVICE):(RX_DEVICE)); + afe_top = + (struct audio_cal_info_afe_top *)cal_block->cal_info; + if (afe_top->path == path) { + if (this_afe.dev_acdb_id[afe_port_index] > 0) { + if (afe_top->acdb_id == + this_afe.dev_acdb_id[afe_port_index]) { + pr_debug("%s: top_id:%x acdb_id:%d afe_port_id:%d\n", + __func__, afe_top->topology, + afe_top->acdb_id, + q6audio_get_port_id(port_id)); + return cal_block; + } + } else { + pr_debug("%s: top_id:%x acdb_id:%d afe_port:%d\n", + __func__, afe_top->topology, afe_top->acdb_id, + q6audio_get_port_id(port_id)); + return cal_block; + } + } + } + +err_exit: + return NULL; +} + +static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id) +{ + int ret = 0; + + struct cal_block_data *cal_block = NULL; + struct audio_cal_info_afe_top *afe_top_info = NULL; + + if (this_afe.cal_data[AFE_TOPOLOGY_CAL] == NULL) { + pr_err("%s: [AFE_TOPOLOGY_CAL] not initialized\n", __func__); + return -EINVAL; + } + if (topology_id == NULL) { + pr_err("%s: topology_id is NULL\n", __func__); + return -EINVAL; + } + *topology_id = 0; + + mutex_lock(&this_afe.cal_data[AFE_TOPOLOGY_CAL]->lock); + cal_block = afe_find_cal_topo_id_by_port( + this_afe.cal_data[AFE_TOPOLOGY_CAL], port_id); + if (cal_block == NULL) { + pr_err("%s: [AFE_TOPOLOGY_CAL] not initialized for this port %d\n", + __func__, port_id); + ret = -EINVAL; + goto unlock; + } + + afe_top_info = ((struct audio_cal_info_afe_top *) + cal_block->cal_info); + if (!afe_top_info->topology) { + pr_err("%s: invalid topology id : [%d, %d]\n", + __func__, afe_top_info->acdb_id, afe_top_info->topology); + ret = -EINVAL; + goto unlock; + } + *topology_id = (u32)afe_top_info->topology; + + pr_debug("%s: port_id = %u acdb_id = %d topology_id = %u ret=%d\n", + __func__, port_id, afe_top_info->acdb_id, + afe_top_info->topology, ret); +unlock: + mutex_unlock(&this_afe.cal_data[AFE_TOPOLOGY_CAL]->lock); + return ret; +} + +static int afe_send_port_topology_id(u16 port_id) +{ + struct afe_audioif_config_command config; + int index = 0; + int ret = 0; + u32 topology_id = 0; + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + + ret = afe_get_cal_topology_id(port_id, &topology_id); + if (ret || !topology_id) { + pr_debug("%s: AFE port[%d] get_cal_topology[%d] invalid!\n", + __func__, port_id, topology_id); + goto done; + } + + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = index; + + config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + config.param.port_id = q6audio_get_port_id(port_id); + config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - + sizeof(config.param); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + config.pdata.param_id = AFE_PARAM_ID_SET_TOPOLOGY; + config.pdata.param_size = sizeof(config.port); + config.port.topology.minor_version = AFE_API_VERSION_TOPOLOGY_V1; + config.port.topology.topology_id = topology_id; + + pr_debug("%s: param PL size=%d iparam_size[%d][%zd %zd %zd %zd] param_id[0x%x]\n", + __func__, config.param.payload_size, config.pdata.param_size, + sizeof(config), sizeof(config.param), sizeof(config.port), + sizeof(struct apr_hdr), config.pdata.param_id); + + ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE set topology id enable for port 0x%x failed %d\n", + __func__, port_id, ret); + goto done; + } + + this_afe.topology[index] = topology_id; + rtac_update_afe_topology(port_id); +done: + pr_debug("%s: AFE set topology id 0x%x enable for port 0x%x ret %d\n", + __func__, topology_id, port_id, ret); + return ret; + +} + +static int remap_cal_data(struct cal_block_data *cal_block, int cal_index) +{ + int ret = 0; + + if (cal_block->map_data.ion_client == NULL) { + pr_err("%s: No ION allocation for cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + if ((cal_block->map_data.map_size > 0) && + (cal_block->map_data.q6map_handle == 0)) { + atomic_set(&this_afe.mem_map_cal_index, cal_index); + ret = afe_cmd_memory_map(cal_block->cal_data.paddr, + cal_block->map_data.map_size); + atomic_set(&this_afe.mem_map_cal_index, -1); + if (ret < 0) { + pr_err("%s: mmap did not work! size = %zd ret %d\n", + __func__, + cal_block->map_data.map_size, ret); + pr_debug("%s: mmap did not work! addr = 0x%pK, size = %zd\n", + __func__, + &cal_block->cal_data.paddr, + cal_block->map_data.map_size); + goto done; + } + cal_block->map_data.q6map_handle = atomic_read(&this_afe. + mem_map_cal_handles[cal_index]); + } +done: + return ret; +} + +static struct cal_block_data *afe_find_cal(int cal_index, int port_id) +{ + struct list_head *ptr, *next; + struct cal_block_data *cal_block = NULL; + struct audio_cal_info_afe *afe_cal_info = NULL; + int afe_port_index = q6audio_get_port_index(port_id); + + pr_debug("%s: cal_index %d port_id %d port_index %d\n", __func__, + cal_index, port_id, afe_port_index); + if (afe_port_index < 0) { + pr_err("%s: Error getting AFE port index %d\n", + __func__, afe_port_index); + goto exit; + } + + list_for_each_safe(ptr, next, + &this_afe.cal_data[cal_index]->cal_blocks) { + cal_block = list_entry(ptr, struct cal_block_data, list); + afe_cal_info = cal_block->cal_info; + if ((afe_cal_info->acdb_id == + this_afe.dev_acdb_id[afe_port_index]) && + (afe_cal_info->sample_rate == + this_afe.afe_sample_rates[afe_port_index])) { + pr_debug("%s: cal block is a match, size is %zd\n", + __func__, cal_block->cal_data.size); + goto exit; + } + } + pr_err("%s: no matching cal_block found\n", __func__); + cal_block = NULL; + +exit: + return cal_block; +} + +static void send_afe_cal_type(int cal_index, int port_id) +{ + struct cal_block_data *cal_block = NULL; + int ret; + int afe_port_index = q6audio_get_port_index(port_id); + + pr_debug("%s:\n", __func__); + + if (this_afe.cal_data[cal_index] == NULL) { + pr_warn("%s: cal_index %d not allocated!\n", + __func__, cal_index); + goto done; + } + + if (afe_port_index < 0) { + pr_err("%s: Error getting AFE port index %d\n", + __func__, afe_port_index); + goto done; + } + + mutex_lock(&this_afe.cal_data[cal_index]->lock); + + if (((cal_index == AFE_COMMON_RX_CAL) || + (cal_index == AFE_COMMON_TX_CAL)) && + (this_afe.dev_acdb_id[afe_port_index] > 0)) + cal_block = afe_find_cal(cal_index, port_id); + else + cal_block = cal_utils_get_only_cal_block( + this_afe.cal_data[cal_index]); + + if (cal_block == NULL) { + pr_err("%s cal_block not found!!\n", __func__); + goto unlock; + } + + pr_debug("%s: Sending cal_index cal %d\n", __func__, cal_index); + + ret = remap_cal_data(cal_block, cal_index); + if (ret) { + pr_err("%s: Remap_cal_data failed for cal %d!\n", + __func__, cal_index); + goto unlock; + } + ret = afe_send_cal_block(port_id, cal_block); + if (ret < 0) + pr_debug("%s: No cal sent for cal_index %d, port_id = 0x%x! ret %d\n", + __func__, cal_index, port_id, ret); +unlock: + mutex_unlock(&this_afe.cal_data[cal_index]->lock); +done: + return; +} + +void afe_send_cal(u16 port_id) +{ + pr_debug("%s: port_id=0x%x\n", __func__, port_id); + + if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX) { + afe_send_cal_spkr_prot_tx(port_id); + send_afe_cal_type(AFE_COMMON_TX_CAL, port_id); + } else if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) { + afe_send_cal_spkr_prot_rx(port_id); + send_afe_cal_type(AFE_COMMON_RX_CAL, port_id); + } +} + +int afe_turn_onoff_hw_mad(u16 mad_type, u16 enable) +{ + int ret; + struct afe_cmd_hw_mad_ctrl config; + + pr_debug("%s: enter\n", __func__); + memset(&config, 0, sizeof(config)); + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = IDX_GLOBAL_CFG; + config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + config.param.port_id = SLIMBUS_5_TX; + config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - + sizeof(config.param); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_HW_MAD; + config.pdata.param_id = AFE_PARAM_ID_HW_MAD_CTRL; + config.pdata.param_size = sizeof(config.payload); + config.payload.minor_version = 1; + config.payload.mad_type = mad_type; + config.payload.mad_enable = enable; + + ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + if (ret) + pr_err("%s: AFE_PARAM_ID_HW_MAD_CTRL failed %d\n", __func__, + ret); + return ret; +} + +static int afe_send_slimbus_slave_cfg( + struct afe_param_cdc_slimbus_slave_cfg *sb_slave_cfg) +{ + int ret; + struct afe_svc_cmd_sb_slave_cfg config; + + pr_debug("%s: enter\n", __func__); + + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = IDX_GLOBAL_CFG; + config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; + config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - + sizeof(config.param); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG; + config.pdata.param_id = AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG; + config.pdata.param_size = + sizeof(struct afe_param_cdc_slimbus_slave_cfg); + config.sb_slave_cfg = *sb_slave_cfg; + + ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + if (ret) + pr_err("%s: AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG failed %d\n", + __func__, ret); + + pr_debug("%s: leave %d\n", __func__, ret); + return ret; +} + +static int afe_send_codec_reg_page_config( + struct afe_param_cdc_reg_page_cfg *cdc_reg_page_cfg) +{ + struct afe_svc_cmd_cdc_reg_page_cfg config; + int ret; + + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = IDX_GLOBAL_CFG; + config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; + config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - + sizeof(config.param); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG; + config.pdata.param_id = AFE_PARAM_ID_CDC_REG_PAGE_CFG; + config.pdata.param_size = + sizeof(struct afe_param_cdc_reg_page_cfg); + config.cdc_reg_page_cfg = *cdc_reg_page_cfg; + + ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + if (ret) + pr_err("%s: AFE_PARAM_ID_CDC_REG_PAGE_CFG failed %d\n", + __func__, ret); + + return ret; +} + +static int afe_send_codec_reg_config( + struct afe_param_cdc_reg_cfg_data *cdc_reg_cfg) +{ + int i, j, ret = -EINVAL; + int pkt_size, payload_size, reg_per_pkt, num_pkts, num_regs; + struct afe_svc_cmd_cdc_reg_cfg *config; + struct afe_svc_cmd_set_param *param; + + reg_per_pkt = (APR_MAX_BUF - sizeof(*config)) / + sizeof(struct afe_param_cdc_reg_cfg_payload); + if (reg_per_pkt > 0) { + num_pkts = (cdc_reg_cfg->num_registers / reg_per_pkt) + + (cdc_reg_cfg->num_registers % reg_per_pkt == 0 ? 0 : 1); + } else { + pr_err("%s: Failed to build codec reg config APR packet\n", + __func__); + return -EINVAL; + } + + for (j = 0; j < num_pkts; ++j) { + /* + * num_regs is set to reg_per_pkt on each pass through the loop + * except the last, when it is set to the number of registers + * remaining from the total + */ + num_regs = (j < (num_pkts - 1) ? reg_per_pkt : + cdc_reg_cfg->num_registers - (reg_per_pkt * j)); + payload_size = sizeof(struct afe_param_cdc_reg_cfg_payload) * + num_regs; + pkt_size = sizeof(*config) + payload_size; + pr_debug("%s: pkt_size %d, payload_size %d\n", __func__, + pkt_size, payload_size); + config = kzalloc(pkt_size, GFP_KERNEL); + if (!config) + return -ENOMEM; + + config->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + config->hdr.pkt_size = pkt_size; + config->hdr.src_port = 0; + config->hdr.dest_port = 0; + config->hdr.token = IDX_GLOBAL_CFG; + config->hdr.opcode = AFE_SVC_CMD_SET_PARAM; + + param = &config->param; + param->payload_size = payload_size; + param->payload_address_lsw = 0x00; + param->payload_address_msw = 0x00; + param->mem_map_handle = 0x00; + + for (i = 0; i < num_regs; i++) { + config->reg_data[i].common.module_id = + AFE_MODULE_CDC_DEV_CFG; + config->reg_data[i].common.param_id = + AFE_PARAM_ID_CDC_REG_CFG; + config->reg_data[i].common.param_size = + sizeof(config->reg_data[i].reg_cfg); + config->reg_data[i].reg_cfg = + cdc_reg_cfg->reg_data[i + (j * reg_per_pkt)]; + } + + ret = afe_apr_send_pkt(config, &this_afe.wait[IDX_GLOBAL_CFG]); + if (ret) { + pr_err("%s: AFE_PARAM_ID_CDC_REG_CFG failed %d\n", + __func__, ret); + kfree(config); + break; + } + kfree(config); + } + + return ret; +} + +static int afe_init_cdc_reg_config(void) +{ + int ret; + struct afe_svc_cmd_init_cdc_reg_cfg config; + + pr_debug("%s: enter\n", __func__); + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = IDX_GLOBAL_CFG; + config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; + + config.param.payload_size = sizeof(struct afe_port_param_data_v2); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + + config.init.module_id = AFE_MODULE_CDC_DEV_CFG; + config.init.param_id = AFE_PARAM_ID_CDC_REG_CFG_INIT; + config.init.param_size = 0; + + ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + if (ret) { + pr_err("%s: AFE_PARAM_ID_CDC_INIT_REG_CFG failed %d\n", + __func__, ret); + } + + return ret; +} + +static int afe_send_slimbus_slave_port_cfg( + struct afe_param_slimbus_slave_port_cfg *port_config, u16 port_id) +{ + int ret, index; + struct afe_cmd_hw_mad_slimbus_slave_port_cfg config; + + pr_debug("%s: enter, port_id = 0x%x\n", __func__, port_id); + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: port id = 0x%x ret %d\n", __func__, port_id, ret); + return -EINVAL; + } + + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = index; + config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + config.param.port_id = port_id; + config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - + sizeof(config.param); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_HW_MAD; + config.pdata.param_id = AFE_PARAM_ID_SLIMBUS_SLAVE_PORT_CFG; + config.pdata.param_size = sizeof(*port_config); + config.sb_port_cfg = *port_config; + + ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE_PARAM_ID_SLIMBUS_SLAVE_PORT_CFG failed %d\n", + __func__, ret); + } + pr_debug("%s: leave %d\n", __func__, ret); + return ret; +} +static int afe_aanc_port_cfg(void *apr, uint16_t tx_port, uint16_t rx_port) +{ + struct afe_port_cmd_set_aanc_param cfg; + int ret = 0; + int index = 0; + + pr_debug("%s: tx_port 0x%x, rx_port 0x%x\n", + __func__, tx_port, rx_port); + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return -EINVAL; + } + + index = q6audio_get_port_index(tx_port); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(tx_port); + if (ret < 0) { + pr_err("%s: port id: 0x%x ret %d\n", __func__, tx_port, ret); + return -EINVAL; + } + pr_debug("%s: AANC sample rate tx rate: %d rx rate %d\n", + __func__, this_afe.aanc_info.aanc_tx_port_sample_rate, + this_afe.aanc_info.aanc_rx_port_sample_rate); + /* + * If aanc tx sample rate or rx sample rate is zero, skip aanc + * configuration as AFE resampler will fail for invalid sample + * rates. + */ + if (!this_afe.aanc_info.aanc_tx_port_sample_rate || + !this_afe.aanc_info.aanc_rx_port_sample_rate) { + return -EINVAL; + } + + cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cfg.hdr.pkt_size = sizeof(cfg); + cfg.hdr.src_port = 0; + cfg.hdr.dest_port = 0; + cfg.hdr.token = index; + cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + + cfg.param.port_id = tx_port; + cfg.param.payload_size = sizeof(struct afe_port_param_data_v2) + + sizeof(struct afe_param_aanc_port_cfg); + cfg.param.payload_address_lsw = 0; + cfg.param.payload_address_msw = 0; + cfg.param.mem_map_handle = 0; + + cfg.pdata.module_id = AFE_MODULE_AANC; + cfg.pdata.param_id = AFE_PARAM_ID_AANC_PORT_CONFIG; + cfg.pdata.param_size = sizeof(struct afe_param_aanc_port_cfg); + cfg.pdata.reserved = 0; + + cfg.data.aanc_port_cfg.aanc_port_cfg_minor_version = + AFE_API_VERSION_AANC_PORT_CONFIG; + cfg.data.aanc_port_cfg.tx_port_sample_rate = + this_afe.aanc_info.aanc_tx_port_sample_rate; + cfg.data.aanc_port_cfg.tx_port_channel_map[0] = AANC_TX_VOICE_MIC; + cfg.data.aanc_port_cfg.tx_port_channel_map[1] = AANC_TX_NOISE_MIC; + cfg.data.aanc_port_cfg.tx_port_channel_map[2] = AANC_TX_ERROR_MIC; + cfg.data.aanc_port_cfg.tx_port_channel_map[3] = AANC_TX_MIC_UNUSED; + cfg.data.aanc_port_cfg.tx_port_channel_map[4] = AANC_TX_MIC_UNUSED; + cfg.data.aanc_port_cfg.tx_port_channel_map[5] = AANC_TX_MIC_UNUSED; + cfg.data.aanc_port_cfg.tx_port_channel_map[6] = AANC_TX_MIC_UNUSED; + cfg.data.aanc_port_cfg.tx_port_channel_map[7] = AANC_TX_MIC_UNUSED; + cfg.data.aanc_port_cfg.tx_port_num_channels = 3; + cfg.data.aanc_port_cfg.rx_path_ref_port_id = rx_port; + cfg.data.aanc_port_cfg.ref_port_sample_rate = + this_afe.aanc_info.aanc_rx_port_sample_rate; + + ret = afe_apr_send_pkt((uint32_t *) &cfg, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE AANC port config failed for tx_port 0x%x, rx_port 0x%x ret %d\n", + __func__, tx_port, rx_port, ret); + } + + return ret; +} + +static int afe_aanc_mod_enable(void *apr, uint16_t tx_port, uint16_t enable) +{ + struct afe_port_cmd_set_aanc_param cfg; + int ret = 0; + int index = 0; + + pr_debug("%s: tx_port 0x%x\n", + __func__, tx_port); + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return -EINVAL; + } + + index = q6audio_get_port_index(tx_port); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(tx_port); + if (ret < 0) { + pr_err("%s: port id: 0x%x ret %d\n", __func__, tx_port, ret); + return -EINVAL; + } + + cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cfg.hdr.pkt_size = sizeof(cfg); + cfg.hdr.src_port = 0; + cfg.hdr.dest_port = 0; + cfg.hdr.token = index; + cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + + cfg.param.port_id = tx_port; + cfg.param.payload_size = sizeof(struct afe_port_param_data_v2) + + sizeof(struct afe_mod_enable_param); + cfg.param.payload_address_lsw = 0; + cfg.param.payload_address_lsw = 0; + cfg.param.mem_map_handle = 0; + + cfg.pdata.module_id = AFE_MODULE_AANC; + cfg.pdata.param_id = AFE_PARAM_ID_ENABLE; + cfg.pdata.param_size = sizeof(struct afe_mod_enable_param); + cfg.pdata.reserved = 0; + + cfg.data.mod_enable.enable = enable; + cfg.data.mod_enable.reserved = 0; + + ret = afe_apr_send_pkt((uint32_t *) &cfg, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE AANC enable failed for tx_port 0x%x ret %d\n", + __func__, tx_port, ret); + } + return ret; +} + +static int afe_send_bank_selection_clip( + struct afe_param_id_clip_bank_sel *param) +{ + int ret; + struct afe_svc_cmd_set_clip_bank_selection config; + + if (!param) { + pr_err("%s: Invalid params", __func__); + return -EINVAL; + } + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = IDX_GLOBAL_CFG; + config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; + + config.param.payload_size = sizeof(struct afe_port_param_data_v2) + + sizeof(struct afe_param_id_clip_bank_sel); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + + config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG; + config.pdata.param_id = AFE_PARAM_ID_CLIP_BANK_SEL_CFG; + config.pdata.param_size = + sizeof(struct afe_param_id_clip_bank_sel); + config.bank_sel = *param; + ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + if (ret) { + pr_err("%s: AFE_PARAM_ID_CLIP_BANK_SEL_CFG failed %d\n", + __func__, ret); + } + return ret; +} +int afe_send_aanc_version( + struct afe_param_id_cdc_aanc_version *version_cfg) +{ + int ret; + struct afe_svc_cmd_cdc_aanc_version config; + + pr_debug("%s: enter\n", __func__); + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = IDX_GLOBAL_CFG; + config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; + + config.param.payload_size = sizeof(struct afe_port_param_data_v2) + + sizeof(struct afe_param_id_cdc_aanc_version); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + + config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG; + config.pdata.param_id = AFE_PARAM_ID_CDC_AANC_VERSION; + config.pdata.param_size = + sizeof(struct afe_param_id_cdc_aanc_version); + config.version = *version_cfg; + ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + if (ret) { + pr_err("%s: AFE_PARAM_ID_CDC_AANC_VERSION failed %d\n", + __func__, ret); + } + return ret; +} + +int afe_port_set_mad_type(u16 port_id, enum afe_mad_type mad_type) +{ + int i; + + if (port_id == AFE_PORT_ID_TERTIARY_MI2S_TX || + port_id == AFE_PORT_ID_INT3_MI2S_TX) { + mad_type = MAD_SW_AUDIO; + return 0; + } + + i = port_id - SLIMBUS_0_RX; + if (i < 0 || i >= ARRAY_SIZE(afe_ports_mad_type)) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + return -EINVAL; + } + atomic_set(&afe_ports_mad_type[i], mad_type); + return 0; +} + +enum afe_mad_type afe_port_get_mad_type(u16 port_id) +{ + int i; + + if (port_id == AFE_PORT_ID_TERTIARY_MI2S_TX || + port_id == AFE_PORT_ID_INT3_MI2S_TX) + return MAD_SW_AUDIO; + + i = port_id - SLIMBUS_0_RX; + if (i < 0 || i >= ARRAY_SIZE(afe_ports_mad_type)) { + pr_debug("%s: Non Slimbus port_id 0x%x\n", __func__, port_id); + return MAD_HW_NONE; + } + return (enum afe_mad_type) atomic_read(&afe_ports_mad_type[i]); +} + +int afe_set_config(enum afe_config_type config_type, void *config_data, int arg) +{ + int ret; + + pr_debug("%s: enter config_type %d\n", __func__, config_type); + ret = afe_q6_interface_prepare(); + if (ret) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + switch (config_type) { + case AFE_SLIMBUS_SLAVE_CONFIG: + ret = afe_send_slimbus_slave_cfg(config_data); + if (!ret) + ret = afe_init_cdc_reg_config(); + else + pr_err("%s: Sending slimbus slave config failed %d\n", + __func__, ret); + break; + case AFE_CDC_REGISTERS_CONFIG: + ret = afe_send_codec_reg_config(config_data); + break; + case AFE_SLIMBUS_SLAVE_PORT_CONFIG: + ret = afe_send_slimbus_slave_port_cfg(config_data, arg); + break; + case AFE_AANC_VERSION: + ret = afe_send_aanc_version(config_data); + break; + case AFE_CLIP_BANK_SEL: + ret = afe_send_bank_selection_clip(config_data); + break; + case AFE_CDC_CLIP_REGISTERS_CONFIG: + ret = afe_send_codec_reg_config(config_data); + break; + case AFE_CDC_REGISTER_PAGE_CONFIG: + ret = afe_send_codec_reg_page_config(config_data); + break; + default: + pr_err("%s: unknown configuration type %d", + __func__, config_type); + ret = -EINVAL; + } + + if (!ret) + set_bit(config_type, &afe_configured_cmd); + + return ret; +} +EXPORT_SYMBOL(afe_set_config); + +/* + * afe_clear_config - If SSR happens ADSP loses AFE configs, let AFE driver know + * about the state so client driver can wait until AFE is + * reconfigured. + */ +void afe_clear_config(enum afe_config_type config) +{ + clear_bit(config, &afe_configured_cmd); +} +EXPORT_SYMBOL(afe_clear_config); + +bool afe_has_config(enum afe_config_type config) +{ + return !!test_bit(config, &afe_configured_cmd); +} + +int afe_send_spdif_clk_cfg(struct afe_param_id_spdif_clk_cfg *cfg, + u16 port_id) +{ + struct afe_spdif_clk_config_command clk_cfg; + int ret = 0; + int index = 0; + + if (!cfg) { + pr_err("%s: Error, no configuration data\n", __func__); + ret = -EINVAL; + return ret; + } + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); + return -EINVAL; + } + + ret = afe_q6_interface_prepare(); + if (ret) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + clk_cfg.hdr.pkt_size = sizeof(clk_cfg); + clk_cfg.hdr.src_port = 0; + clk_cfg.hdr.dest_port = 0; + clk_cfg.hdr.token = index; + + clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + clk_cfg.param.port_id = q6audio_get_port_id(port_id); + clk_cfg.param.payload_address_lsw = 0x00; + clk_cfg.param.payload_address_msw = 0x00; + clk_cfg.param.mem_map_handle = 0x00; + clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + clk_cfg.pdata.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG; + clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); + clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) + - sizeof(clk_cfg.param); + clk_cfg.clk_cfg = *cfg; + + pr_debug("%s: Minor version = 0x%x clk val = %d\n" + "clk root = 0x%x\n port id = 0x%x\n", + __func__, cfg->clk_cfg_minor_version, + cfg->clk_value, cfg->clk_root, + q6audio_get_port_id(port_id)); + + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); + if (ret < 0) { + pr_err("%s: AFE send clock config for port 0x%x failed ret = %d\n", + __func__, port_id, ret); + ret = -EINVAL; + goto fail_cmd; + } + + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", + __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto fail_cmd; + } + +fail_cmd: + return ret; +} + +int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg + *ch_status_cfg, u16 port_id) +{ + struct afe_spdif_chstatus_config_command ch_status; + int ret = 0; + int index = 0; + + if (!ch_status_cfg) { + pr_err("%s: Error, no configuration data\n", __func__); + ret = -EINVAL; + return ret; + } + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); + return -EINVAL; + } + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + ch_status.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + ch_status.hdr.pkt_size = sizeof(ch_status_cfg); + ch_status.hdr.src_port = 0; + ch_status.hdr.dest_port = 0; + ch_status.hdr.token = index; + + ch_status.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + ch_status.param.port_id = q6audio_get_port_id(port_id); + ch_status.param.payload_address_lsw = 0x00; + ch_status.param.payload_address_msw = 0x00; + ch_status.param.mem_map_handle = 0x00; + ch_status.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + ch_status.pdata.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG; + ch_status.pdata.param_size = sizeof(ch_status.ch_status); + ch_status.param.payload_size = sizeof(ch_status) + - sizeof(struct apr_hdr) - sizeof(ch_status.param); + ch_status.ch_status = *ch_status_cfg; + + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) &ch_status); + if (ret < 0) { + pr_err("%s: AFE send channel status for port 0x%x failed ret = %d\n", + __func__, port_id, ret); + ret = -EINVAL; + goto fail_cmd; + } + + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", + __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto fail_cmd; + } + +fail_cmd: + return ret; +} + +static int afe_send_cmd_port_start(u16 port_id) +{ + struct afe_port_cmd_device_start start; + int ret, index; + + pr_debug("%s: enter\n", __func__); + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); + return -EINVAL; + } + + start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + start.hdr.pkt_size = sizeof(start); + start.hdr.src_port = 0; + start.hdr.dest_port = 0; + start.hdr.token = index; + start.hdr.opcode = AFE_PORT_CMD_DEVICE_START; + start.port_id = q6audio_get_port_id(port_id); + pr_debug("%s: cmd device start opcode[0x%x] port id[0x%x]\n", + __func__, start.hdr.opcode, start.port_id); + + ret = afe_apr_send_pkt(&start, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE enable for port 0x%x failed %d\n", __func__, + port_id, ret); + } else if (this_afe.task != current) { + this_afe.task = current; + pr_debug("task_name = %s pid = %d\n", + this_afe.task->comm, this_afe.task->pid); + } + + return ret; +} + +static int afe_aanc_start(uint16_t tx_port_id, uint16_t rx_port_id) +{ + int ret; + + pr_debug("%s: Tx port is 0x%x, Rx port is 0x%x\n", + __func__, tx_port_id, rx_port_id); + ret = afe_aanc_port_cfg(this_afe.apr, tx_port_id, rx_port_id); + if (ret) { + pr_err("%s: Send AANC Port Config failed %d\n", + __func__, ret); + goto fail_cmd; + } + send_afe_cal_type(AFE_AANC_CAL, tx_port_id); + +fail_cmd: + return ret; +} + +int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port, + u32 rate) +{ + struct afe_audioif_config_command config; + int ret = 0; + int index = 0; + uint16_t port_index; + + if (!spdif_port) { + pr_err("%s: Error, no configuration data\n", __func__); + ret = -EINVAL; + return ret; + } + + pr_debug("%s: port id: 0x%x\n", __func__, port_id); + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); + return -EINVAL; + } + + afe_send_cal(port_id); + afe_send_hw_delay(port_id, rate); + + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = index; + config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + config.param.port_id = q6audio_get_port_id(port_id); + config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - + sizeof(config.param); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + config.pdata.param_id = AFE_PARAM_ID_SPDIF_CONFIG; + config.pdata.param_size = sizeof(config.port); + config.port.spdif = spdif_port->cfg; + ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE enable for port 0x%x failed ret = %d\n", + __func__, port_id, ret); + goto fail_cmd; + } + + port_index = afe_get_port_index(port_id); + if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) { + this_afe.afe_sample_rates[port_index] = rate; + } else { + pr_err("%s: Invalid port index %d\n", __func__, port_index); + ret = -EINVAL; + goto fail_cmd; + } + + ret = afe_send_spdif_ch_status_cfg(&spdif_port->ch_status, port_id); + if (ret < 0) { + pr_err("%s: afe send failed %d\n", __func__, ret); + goto fail_cmd; + } + + return afe_send_cmd_port_start(port_id); + +fail_cmd: + return ret; +} + +int afe_send_slot_mapping_cfg( + struct afe_param_id_slot_mapping_cfg *slot_mapping_cfg, + u16 port_id) +{ + struct afe_slot_mapping_config_command config; + int ret = 0; + int index = 0; + + if (!slot_mapping_cfg) { + pr_err("%s: Error, no configuration data\n", __func__); + return -EINVAL; + } + + pr_debug("%s: port id: 0x%x\n", __func__, port_id); + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); + return -EINVAL; + } + + memset(&config, 0, sizeof(config)); + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = index; + + config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + config.param.port_id = q6audio_get_port_id(port_id); + config.param.payload_size = sizeof(config) + - sizeof(struct apr_hdr) - sizeof(config.param); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_TDM; + config.pdata.param_id = AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG; + config.pdata.param_size = sizeof(config.slot_mapping); + config.slot_mapping = *slot_mapping_cfg; + + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config); + if (ret < 0) { + pr_err("%s: AFE send slot mapping for port 0x%x failed ret = %d\n", + __func__, port_id, ret); + ret = -EINVAL; + goto fail_cmd; + } + + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", + __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto fail_cmd; + } + +fail_cmd: + return ret; +} + +int afe_send_custom_tdm_header_cfg( + struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header_cfg, + u16 port_id) +{ + struct afe_custom_tdm_header_config_command config; + int ret = 0; + int index = 0; + + if (!custom_tdm_header_cfg) { + pr_err("%s: Error, no configuration data\n", __func__); + return -EINVAL; + } + + pr_debug("%s: port id: 0x%x\n", __func__, port_id); + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); + return -EINVAL; + } + + memset(&config, 0, sizeof(config)); + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = index; + + config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + config.param.port_id = q6audio_get_port_id(port_id); + config.param.payload_size = sizeof(config) + - sizeof(struct apr_hdr) - sizeof(config.param); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_TDM; + config.pdata.param_id = AFE_PARAM_ID_CUSTOM_TDM_HEADER_CONFIG; + config.pdata.param_size = sizeof(config.custom_tdm_header); + config.custom_tdm_header = *custom_tdm_header_cfg; + + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config); + if (ret < 0) { + pr_err("%s: AFE send custom tdm header for port 0x%x failed ret = %d\n", + __func__, port_id, ret); + ret = -EINVAL; + goto fail_cmd; + } + + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", + __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto fail_cmd; + } + +fail_cmd: + return ret; +} + +int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, + u32 rate, u16 num_groups) +{ + struct afe_audioif_config_command config; + int ret = 0; + int index = 0; + uint16_t port_index = 0; + enum afe_mad_type mad_type = MAD_HW_NONE; + + if (!tdm_port) { + pr_err("%s: Error, no configuration data\n", __func__); + return -EINVAL; + } + + pr_debug("%s: port id: 0x%x\n", __func__, port_id); + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); + return -EINVAL; + } + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + if ((index >= 0) && (index < AFE_MAX_PORTS)) { + this_afe.afe_sample_rates[index] = rate; + + if (this_afe.rt_cb) + this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id); + } + + /* Also send the topology id here if multiple ports: */ + port_index = afe_get_port_index(port_id); + if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE) && + num_groups > 1) { + /* One time call: only for first time */ + afe_send_custom_topology(); + afe_send_port_topology_id(port_id); + afe_send_cal(port_id); + afe_send_hw_delay(port_id, rate); + } + + /* Start SW MAD module */ + mad_type = afe_port_get_mad_type(port_id); + pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, + mad_type); + if (mad_type != MAD_HW_NONE && mad_type != MAD_SW_AUDIO) { + if (!afe_has_config(AFE_CDC_REGISTERS_CONFIG) || + !afe_has_config(AFE_SLIMBUS_SLAVE_CONFIG)) { + pr_err("%s: AFE isn't configured yet for\n" + "HW MAD try Again\n", __func__); + ret = -EAGAIN; + goto fail_cmd; + } + ret = afe_turn_onoff_hw_mad(mad_type, true); + if (ret) { + pr_err("%s: afe_turn_onoff_hw_mad failed %d\n", + __func__, ret); + goto fail_cmd; + } + } + + memset(&config, 0, sizeof(config)); + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = index; + config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + config.param.port_id = q6audio_get_port_id(port_id); + config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - + sizeof(config.param); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + config.pdata.param_id = AFE_PARAM_ID_TDM_CONFIG; + config.pdata.param_size = sizeof(config.port); + config.port.tdm = tdm_port->tdm; + + ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE enable for port 0x%x failed ret = %d\n", + __func__, port_id, ret); + goto fail_cmd; + } + + port_index = afe_get_port_index(port_id); + if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) { + this_afe.afe_sample_rates[port_index] = rate; + } else { + pr_err("%s: Invalid port index %d\n", __func__, port_index); + ret = -EINVAL; + goto fail_cmd; + } + /* slot mapping is not need if there is only one group */ + if (num_groups > 1) { + ret = afe_send_slot_mapping_cfg(&tdm_port->slot_mapping, + port_id); + if (ret < 0) { + pr_err("%s: afe send failed %d\n", __func__, ret); + goto fail_cmd; + } + } + + if (tdm_port->custom_tdm_header.header_type) { + ret = afe_send_custom_tdm_header_cfg( + &tdm_port->custom_tdm_header, port_id); + if (ret < 0) { + pr_err("%s: afe send failed %d\n", __func__, ret); + goto fail_cmd; + } + } + + ret = afe_send_cmd_port_start(port_id); + +fail_cmd: + return ret; +} + +void afe_set_cal_mode(u16 port_id, enum afe_cal_mode afe_cal_mode) +{ + uint16_t port_index; + + port_index = afe_get_port_index(port_id); + this_afe.afe_cal_mode[port_index] = afe_cal_mode; +} + +void afe_set_routing_callback(routing_cb cb) +{ + this_afe.rt_cb = cb; +} + +int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) +{ + struct afe_usb_audio_dev_param_command config; + int ret = 0, index = 0; + + if (!afe_config) { + pr_err("%s: Error, no configuration data\n", __func__); + ret = -EINVAL; + goto exit; + } + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid! for port ID 0x%x\n", + __func__, index, port_id); + ret = -EINVAL; + goto exit; + } + memset(&config, 0, sizeof(config)); + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = index; + config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + config.param.port_id = q6audio_get_port_id(port_id); + config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - + sizeof(config.param); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + config.pdata.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS; + config.pdata.param_size = sizeof(config.usb_dev); + config.usb_dev.cfg_minor_version = + AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG; + config.usb_dev.dev_token = afe_config->usb_audio.dev_token; + + ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE device param cmd failed %d\n", + __func__, ret); + ret = -EINVAL; + goto exit; + } + + config.pdata.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_LPCM_FMT; + config.pdata.param_size = sizeof(config.lpcm_fmt); + config.lpcm_fmt.cfg_minor_version = + AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG; + config.lpcm_fmt.endian = afe_config->usb_audio.endian; + + ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE device param cmd LPCM_FMT failed %d\n", + __func__, ret); + ret = -EINVAL; + goto exit; + } + +exit: + return ret; +} + +static int q6afe_send_enc_config(u16 port_id, + union afe_enc_config_data *cfg, u32 format, + union afe_port_config afe_config, + u16 afe_in_channels, u16 afe_in_bit_width) +{ + struct afe_audioif_config_command config; + int index; + int ret; + int payload_size = sizeof(config) - sizeof(struct apr_hdr) - + sizeof(config.param) - sizeof(config.port); + + pr_debug("%s:update DSP for enc format = %d\n", __func__, format); + if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 && + format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD) { + pr_err("%s:Unsuppported format Ignore AFE config\n", __func__); + return 0; + } + memset(&config, 0, sizeof(config)); + index = q6audio_get_port_index(port_id); + if (index < 0) { + pr_err("%s: Invalid index number: %d\n", __func__, index); + return -EINVAL; + } + + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = index; + + config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + config.param.port_id = q6audio_get_port_id(port_id); + config.param.payload_size = payload_size + sizeof(config.port.enc_fmt); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_ID_ENCODER; + config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENC_FMT_ID; + config.pdata.param_size = sizeof(config.port.enc_fmt); + config.port.enc_fmt.fmt_id = format; + pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENC_FMT_ID payload: %d\n", + __func__, config.param.payload_size); + ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + if (ret) { + pr_err("%s:unable to send AFE_ENCODER_PARAM_ID_ENC_FMT_ID", + __func__); + goto exit; + } + + config.param.payload_size = payload_size + + sizeof(config.port.enc_blk_param); + pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payload:%d\n", + __func__, config.param.payload_size); + config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK; + config.pdata.param_size = sizeof(config.port.enc_blk_param); + config.port.enc_blk_param.enc_cfg_blk_size = + sizeof(config.port.enc_blk_param.enc_blk_config); + config.port.enc_blk_param.enc_blk_config = *cfg; + ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE_ENCODER_PARAM_ID_ENC_CFG_BLK for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + + config.param.payload_size = + payload_size + sizeof(config.port.enc_pkt_id_param); + pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP payload = %d", + __func__, config.param.payload_size); + config.pdata.param_id = AFE_ENCODER_PARAM_ID_PACKETIZER_ID; + config.pdata.param_size = sizeof(config.port.enc_pkt_id_param); + config.port.enc_pkt_id_param.enc_packetizer_id = + AFE_MODULE_ID_PACKETIZER_COP; + ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE_ENCODER_PARAM_ID_PACKETIZER for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + + config.param.payload_size = + payload_size + sizeof(config.port.media_type); + config.pdata.param_size = sizeof(config.port.media_type); + + pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __func__); + config.pdata.module_id = AFE_MODULE_PORT; + config.pdata.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE; + config.port.media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE; + config.port.media_type.sample_rate = afe_config.slim_sch.sample_rate; + if (afe_in_bit_width) + config.port.media_type.bit_width = afe_in_bit_width; + else + config.port.media_type.bit_width = + afe_config.slim_sch.bit_width; + + if (afe_in_channels) + config.port.media_type.num_channels = afe_in_channels; + else + config.port.media_type.num_channels = + afe_config.slim_sch.num_channels; + config.port.media_type.data_format = AFE_PORT_DATA_FORMAT_PCM; + config.port.media_type.reserved = 0; + + ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE_API_VERSION_PORT_MEDIA_TYPE for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + +exit: + return ret; +} + +static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, + u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, + union afe_enc_config_data *cfg, u32 enc_format) +{ + struct afe_audioif_config_command config; + int ret = 0; + int cfg_type; + int index = 0; + enum afe_mad_type mad_type; + uint16_t port_index; + + if (!afe_config) { + pr_err("%s: Error, no configuration data\n", __func__); + ret = -EINVAL; + return ret; + } + + if ((port_id == RT_PROXY_DAI_001_RX) || + (port_id == RT_PROXY_DAI_002_TX)) { + pr_debug("%s: before incrementing pcm_afe_instance %d port_id 0x%x\n", + __func__, + pcm_afe_instance[port_id & 0x1], port_id); + port_id = VIRTUAL_ID_TO_PORTID(port_id); + pcm_afe_instance[port_id & 0x1]++; + return 0; + } + if ((port_id == RT_PROXY_DAI_002_RX) || + (port_id == RT_PROXY_DAI_001_TX)) { + pr_debug("%s: before incrementing proxy_afe_instance %d port_id 0x%x\n", + __func__, + proxy_afe_instance[port_id & 0x1], port_id); + + if (!afe_close_done[port_id & 0x1]) { + /*close pcm dai corresponding to the proxy dai*/ + afe_close(port_id - 0x10); + pcm_afe_instance[port_id & 0x1]++; + pr_debug("%s: reconfigure afe port again\n", __func__); + } + proxy_afe_instance[port_id & 0x1]++; + afe_close_done[port_id & 0x1] = false; + port_id = VIRTUAL_ID_TO_PORTID(port_id); + } + + pr_debug("%s: port id: 0x%x\n", __func__, port_id); + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); + return -EINVAL; + } + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + if ((index >= 0) && (index < AFE_MAX_PORTS)) { + this_afe.afe_sample_rates[index] = rate; + + if (this_afe.rt_cb) + this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id); + } + + mutex_lock(&this_afe.afe_cmd_lock); + /* Also send the topology id here: */ + port_index = afe_get_port_index(port_id); + if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) { + /* One time call: only for first time */ + afe_send_custom_topology(); + afe_send_port_topology_id(port_id); + afe_send_cal(port_id); + afe_send_hw_delay(port_id, rate); + } + + /* Start SW MAD module */ + mad_type = afe_port_get_mad_type(port_id); + pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, + mad_type); + if (mad_type != MAD_HW_NONE && mad_type != MAD_SW_AUDIO) { + if (!afe_has_config(AFE_CDC_REGISTERS_CONFIG) || + !afe_has_config(AFE_SLIMBUS_SLAVE_CONFIG)) { + pr_err("%s: AFE isn't configured yet for\n" + "HW MAD try Again\n", __func__); + ret = -EAGAIN; + goto fail_cmd; + } + ret = afe_turn_onoff_hw_mad(mad_type, true); + if (ret) { + pr_err("%s: afe_turn_onoff_hw_mad failed %d\n", + __func__, ret); + goto fail_cmd; + } + } + + if ((this_afe.aanc_info.aanc_active) && + (this_afe.aanc_info.aanc_tx_port == port_id)) { + this_afe.aanc_info.aanc_tx_port_sample_rate = rate; + port_index = + afe_get_port_index(this_afe.aanc_info.aanc_rx_port); + if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) { + this_afe.aanc_info.aanc_rx_port_sample_rate = + this_afe.afe_sample_rates[port_index]; + } else { + pr_err("%s: Invalid port index %d\n", + __func__, port_index); + ret = -EINVAL; + goto fail_cmd; + } + ret = afe_aanc_start(this_afe.aanc_info.aanc_tx_port, + this_afe.aanc_info.aanc_rx_port); + pr_debug("%s: afe_aanc_start ret %d\n", __func__, ret); + } + + if ((port_id == AFE_PORT_ID_USB_RX) || + (port_id == AFE_PORT_ID_USB_TX)) { + ret = afe_port_send_usb_dev_param(port_id, afe_config); + if (ret) { + pr_err("%s: AFE device param for port 0x%x failed %d\n", + __func__, port_id, ret); + ret = -EINVAL; + goto fail_cmd; + } + } + + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = index; + + switch (port_id) { + case AFE_PORT_ID_PRIMARY_PCM_RX: + case AFE_PORT_ID_PRIMARY_PCM_TX: + case AFE_PORT_ID_SECONDARY_PCM_RX: + case AFE_PORT_ID_SECONDARY_PCM_TX: + case AFE_PORT_ID_TERTIARY_PCM_RX: + case AFE_PORT_ID_TERTIARY_PCM_TX: + case AFE_PORT_ID_QUATERNARY_PCM_RX: + case AFE_PORT_ID_QUATERNARY_PCM_TX: + cfg_type = AFE_PARAM_ID_PCM_CONFIG; + break; + case PRIMARY_I2S_RX: + case PRIMARY_I2S_TX: + case SECONDARY_I2S_RX: + case SECONDARY_I2S_TX: + case MI2S_RX: + case MI2S_TX: + case AFE_PORT_ID_PRIMARY_MI2S_RX: + case AFE_PORT_ID_PRIMARY_MI2S_TX: + case AFE_PORT_ID_SECONDARY_MI2S_RX: + case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1: + case AFE_PORT_ID_SECONDARY_MI2S_TX: + case AFE_PORT_ID_TERTIARY_MI2S_RX: + case AFE_PORT_ID_TERTIARY_MI2S_TX: + case AFE_PORT_ID_QUATERNARY_MI2S_RX: + case AFE_PORT_ID_QUATERNARY_MI2S_TX: + case AFE_PORT_ID_QUINARY_MI2S_RX: + case AFE_PORT_ID_QUINARY_MI2S_TX: + case AFE_PORT_ID_SENARY_MI2S_TX: + case AFE_PORT_ID_INT0_MI2S_RX: + case AFE_PORT_ID_INT0_MI2S_TX: + case AFE_PORT_ID_INT1_MI2S_RX: + case AFE_PORT_ID_INT1_MI2S_TX: + case AFE_PORT_ID_INT2_MI2S_RX: + case AFE_PORT_ID_INT2_MI2S_TX: + case AFE_PORT_ID_INT3_MI2S_RX: + case AFE_PORT_ID_INT3_MI2S_TX: + case AFE_PORT_ID_INT4_MI2S_RX: + case AFE_PORT_ID_INT4_MI2S_TX: + case AFE_PORT_ID_INT5_MI2S_RX: + case AFE_PORT_ID_INT5_MI2S_TX: + case AFE_PORT_ID_INT6_MI2S_RX: + case AFE_PORT_ID_INT6_MI2S_TX: + cfg_type = AFE_PARAM_ID_I2S_CONFIG; + break; + case HDMI_RX: + case DISPLAY_PORT_RX: + cfg_type = AFE_PARAM_ID_HDMI_CONFIG; + break; + case VOICE_PLAYBACK_TX: + case VOICE2_PLAYBACK_TX: + case VOICE_RECORD_RX: + case VOICE_RECORD_TX: + cfg_type = AFE_PARAM_ID_PSEUDO_PORT_CONFIG; + break; + case SLIMBUS_0_RX: + case SLIMBUS_0_TX: + case SLIMBUS_1_RX: + case SLIMBUS_1_TX: + case SLIMBUS_2_RX: + case SLIMBUS_2_TX: + case SLIMBUS_3_RX: + case SLIMBUS_3_TX: + case SLIMBUS_4_RX: + case SLIMBUS_4_TX: + case SLIMBUS_5_RX: + case SLIMBUS_5_TX: + case SLIMBUS_6_RX: + case SLIMBUS_6_TX: + case SLIMBUS_7_RX: + case SLIMBUS_7_TX: + case SLIMBUS_8_RX: + case SLIMBUS_8_TX: + cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG; + break; + case AFE_PORT_ID_USB_RX: + case AFE_PORT_ID_USB_TX: + cfg_type = AFE_PARAM_ID_USB_AUDIO_CONFIG; + break; + case RT_PROXY_PORT_001_RX: + case RT_PROXY_PORT_001_TX: + cfg_type = AFE_PARAM_ID_RT_PROXY_CONFIG; + break; + case INT_BT_SCO_RX: + case INT_BT_A2DP_RX: + case INT_BT_SCO_TX: + case INT_FM_RX: + case INT_FM_TX: + cfg_type = AFE_PARAM_ID_INTERNAL_BT_FM_CONFIG; + break; + default: + pr_err("%s: Invalid port id 0x%x\n", __func__, port_id); + ret = -EINVAL; + goto fail_cmd; + } + config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + config.param.port_id = q6audio_get_port_id(port_id); + config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - + sizeof(config.param); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + config.pdata.param_id = cfg_type; + config.pdata.param_size = sizeof(config.port); + + config.port = *afe_config; + if ((enc_format != ASM_MEDIA_FMT_NONE) && + (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) { + config.port.slim_sch.data_format = + AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED; + } + ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE enable for port 0x%x failed %d\n", + __func__, port_id, ret); + goto fail_cmd; + } + + if ((enc_format != ASM_MEDIA_FMT_NONE) && + (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) { + pr_debug("%s: Found AFE encoder support for SLIMBUS enc_format = %d\n", + __func__, enc_format); + ret = q6afe_send_enc_config(port_id, cfg, enc_format, + *afe_config, afe_in_channels, + afe_in_bit_width); + if (ret) { + pr_err("%s: AFE encoder config for port 0x%x failed %d\n", + __func__, port_id, ret); + goto fail_cmd; + } + } + + port_index = afe_get_port_index(port_id); + if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) { + /* + * If afe_port_start() for tx port called before + * rx port, then aanc rx sample rate is zero. So, + * AANC state machine in AFE will not get triggered. + * Make sure to check whether aanc is active during + * afe_port_start() for rx port and if aanc rx + * sample rate is zero, call afe_aanc_start to configure + * aanc with valid sample rates. + */ + if (this_afe.aanc_info.aanc_active && + !this_afe.aanc_info.aanc_rx_port_sample_rate) { + this_afe.aanc_info.aanc_rx_port_sample_rate = + this_afe.afe_sample_rates[port_index]; + ret = afe_aanc_start(this_afe.aanc_info.aanc_tx_port, + this_afe.aanc_info.aanc_rx_port); + pr_debug("%s: afe_aanc_start ret %d\n", __func__, ret); + } + } else { + pr_err("%s: Invalid port index %d\n", __func__, port_index); + ret = -EINVAL; + goto fail_cmd; + } + ret = afe_send_cmd_port_start(port_id); + +fail_cmd: + mutex_unlock(&this_afe.afe_cmd_lock); + return ret; +} + +/** + * afe_port_start - to configure AFE session with + * specified port configuration + * + * @port_id: AFE port id number + * @afe_config: port configutation + * @rate: sampling rate of port + * + * Returns 0 on success or error value on port start failure. + */ +int afe_port_start(u16 port_id, union afe_port_config *afe_config, + u32 rate) +{ + return __afe_port_start(port_id, afe_config, rate, + 0, 0, NULL, ASM_MEDIA_FMT_NONE); +} +EXPORT_SYMBOL(afe_port_start); + +/** + * afe_port_start_v2 - to configure AFE session with + * specified port configuration and encoder params + * + * @port_id: AFE port id number + * @afe_config: port configutation + * @rate: sampling rate of port + * @cfg: AFE encoder configuration information to setup encoder + * @afe_in_channels: AFE input channel configuration, this needs + * update only if input channel is differ from AFE output + * + * Returns 0 on success or error value on port start failure. + */ +int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, + u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, + struct afe_enc_config *enc_cfg) +{ + return __afe_port_start(port_id, afe_config, rate, + afe_in_channels, afe_in_bit_width, + &enc_cfg->data, enc_cfg->format); +} +EXPORT_SYMBOL(afe_port_start_v2); + +int afe_get_port_index(u16 port_id) +{ + switch (port_id) { + case PRIMARY_I2S_RX: return IDX_PRIMARY_I2S_RX; + case PRIMARY_I2S_TX: return IDX_PRIMARY_I2S_TX; + case AFE_PORT_ID_PRIMARY_PCM_RX: + return IDX_AFE_PORT_ID_PRIMARY_PCM_RX; + case AFE_PORT_ID_PRIMARY_PCM_TX: + return IDX_AFE_PORT_ID_PRIMARY_PCM_TX; + case AFE_PORT_ID_SECONDARY_PCM_RX: + return IDX_AFE_PORT_ID_SECONDARY_PCM_RX; + case AFE_PORT_ID_SECONDARY_PCM_TX: + return IDX_AFE_PORT_ID_SECONDARY_PCM_TX; + case AFE_PORT_ID_TERTIARY_PCM_RX: + return IDX_AFE_PORT_ID_TERTIARY_PCM_RX; + case AFE_PORT_ID_TERTIARY_PCM_TX: + return IDX_AFE_PORT_ID_TERTIARY_PCM_TX; + case AFE_PORT_ID_QUATERNARY_PCM_RX: + return IDX_AFE_PORT_ID_QUATERNARY_PCM_RX; + case AFE_PORT_ID_QUATERNARY_PCM_TX: + return IDX_AFE_PORT_ID_QUATERNARY_PCM_TX; + case SECONDARY_I2S_RX: return IDX_SECONDARY_I2S_RX; + case SECONDARY_I2S_TX: return IDX_SECONDARY_I2S_TX; + case MI2S_RX: return IDX_MI2S_RX; + case MI2S_TX: return IDX_MI2S_TX; + case HDMI_RX: return IDX_HDMI_RX; + case DISPLAY_PORT_RX: return IDX_DISPLAY_PORT_RX; + case AFE_PORT_ID_SPDIF_RX: return IDX_SPDIF_RX; + case RSVD_2: return IDX_RSVD_2; + case RSVD_3: return IDX_RSVD_3; + case DIGI_MIC_TX: return IDX_DIGI_MIC_TX; + case VOICE_RECORD_RX: return IDX_VOICE_RECORD_RX; + case VOICE_RECORD_TX: return IDX_VOICE_RECORD_TX; + case VOICE_PLAYBACK_TX: return IDX_VOICE_PLAYBACK_TX; + case VOICE2_PLAYBACK_TX: return IDX_VOICE2_PLAYBACK_TX; + case SLIMBUS_0_RX: return IDX_SLIMBUS_0_RX; + case SLIMBUS_0_TX: return IDX_SLIMBUS_0_TX; + case SLIMBUS_1_RX: return IDX_SLIMBUS_1_RX; + case SLIMBUS_1_TX: return IDX_SLIMBUS_1_TX; + case SLIMBUS_2_RX: return IDX_SLIMBUS_2_RX; + case SLIMBUS_2_TX: return IDX_SLIMBUS_2_TX; + case SLIMBUS_3_RX: return IDX_SLIMBUS_3_RX; + case SLIMBUS_3_TX: return IDX_SLIMBUS_3_TX; + case INT_BT_SCO_RX: return IDX_INT_BT_SCO_RX; + case INT_BT_SCO_TX: return IDX_INT_BT_SCO_TX; + case INT_BT_A2DP_RX: return IDX_INT_BT_A2DP_RX; + case INT_FM_RX: return IDX_INT_FM_RX; + case INT_FM_TX: return IDX_INT_FM_TX; + case RT_PROXY_PORT_001_RX: return IDX_RT_PROXY_PORT_001_RX; + case RT_PROXY_PORT_001_TX: return IDX_RT_PROXY_PORT_001_TX; + case SLIMBUS_4_RX: return IDX_SLIMBUS_4_RX; + case SLIMBUS_4_TX: return IDX_SLIMBUS_4_TX; + case SLIMBUS_5_RX: return IDX_SLIMBUS_5_RX; + case SLIMBUS_5_TX: return IDX_SLIMBUS_5_TX; + case SLIMBUS_6_RX: return IDX_SLIMBUS_6_RX; + case SLIMBUS_6_TX: return IDX_SLIMBUS_6_TX; + case SLIMBUS_7_RX: return IDX_SLIMBUS_7_RX; + case SLIMBUS_7_TX: return IDX_SLIMBUS_7_TX; + case SLIMBUS_8_RX: return IDX_SLIMBUS_8_RX; + case SLIMBUS_8_TX: return IDX_SLIMBUS_8_TX; + case AFE_PORT_ID_USB_RX: return IDX_AFE_PORT_ID_USB_RX; + case AFE_PORT_ID_USB_TX: return IDX_AFE_PORT_ID_USB_TX; + case AFE_PORT_ID_PRIMARY_MI2S_RX: + return IDX_AFE_PORT_ID_PRIMARY_MI2S_RX; + case AFE_PORT_ID_PRIMARY_MI2S_TX: + return IDX_AFE_PORT_ID_PRIMARY_MI2S_TX; + case AFE_PORT_ID_QUATERNARY_MI2S_RX: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX; + case AFE_PORT_ID_QUATERNARY_MI2S_TX: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX; + case AFE_PORT_ID_SECONDARY_MI2S_RX: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX; + case AFE_PORT_ID_SECONDARY_MI2S_TX: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX; + case AFE_PORT_ID_TERTIARY_MI2S_RX: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX; + case AFE_PORT_ID_TERTIARY_MI2S_TX: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX; + case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_SD1; + case AFE_PORT_ID_QUINARY_MI2S_RX: + return IDX_AFE_PORT_ID_QUINARY_MI2S_RX; + case AFE_PORT_ID_QUINARY_MI2S_TX: + return IDX_AFE_PORT_ID_QUINARY_MI2S_TX; + case AFE_PORT_ID_SENARY_MI2S_TX: + return IDX_AFE_PORT_ID_SENARY_MI2S_TX; + case AFE_PORT_ID_PRIMARY_TDM_RX: + return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_0; + case AFE_PORT_ID_PRIMARY_TDM_TX: + return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_0; + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_1; + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_1; + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_2; + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_2; + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_3; + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_3; + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_4; + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_4; + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_5; + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_5; + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_6; + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_6; + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_7; + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_7; + case AFE_PORT_ID_SECONDARY_TDM_RX: + return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_0; + case AFE_PORT_ID_SECONDARY_TDM_TX: + return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_0; + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_1; + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_1; + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_2; + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_2; + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_3; + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_3; + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_4; + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_4; + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_5; + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_5; + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_6; + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_6; + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_7; + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_7; + case AFE_PORT_ID_TERTIARY_TDM_RX: + return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_0; + case AFE_PORT_ID_TERTIARY_TDM_TX: + return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_0; + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_1; + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_1; + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_2; + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_2; + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_3; + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_3; + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_4; + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_4; + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_5; + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_5; + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_6; + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_6; + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_7; + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_7; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_0; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_0; + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_1; + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_1; + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_2; + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_2; + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_3; + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_3; + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_4; + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_4; + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_5; + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_5; + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_6; + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_6; + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_7; + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_7; + case AFE_PORT_ID_INT0_MI2S_RX: + return IDX_AFE_PORT_ID_INT0_MI2S_RX; + case AFE_PORT_ID_INT0_MI2S_TX: + return IDX_AFE_PORT_ID_INT0_MI2S_TX; + case AFE_PORT_ID_INT1_MI2S_RX: + return IDX_AFE_PORT_ID_INT1_MI2S_RX; + case AFE_PORT_ID_INT1_MI2S_TX: + return IDX_AFE_PORT_ID_INT1_MI2S_TX; + case AFE_PORT_ID_INT2_MI2S_RX: + return IDX_AFE_PORT_ID_INT2_MI2S_RX; + case AFE_PORT_ID_INT2_MI2S_TX: + return IDX_AFE_PORT_ID_INT2_MI2S_TX; + case AFE_PORT_ID_INT3_MI2S_RX: + return IDX_AFE_PORT_ID_INT3_MI2S_RX; + case AFE_PORT_ID_INT3_MI2S_TX: + return IDX_AFE_PORT_ID_INT3_MI2S_TX; + case AFE_PORT_ID_INT4_MI2S_RX: + return IDX_AFE_PORT_ID_INT4_MI2S_RX; + case AFE_PORT_ID_INT4_MI2S_TX: + return IDX_AFE_PORT_ID_INT4_MI2S_TX; + case AFE_PORT_ID_INT5_MI2S_RX: + return IDX_AFE_PORT_ID_INT5_MI2S_RX; + case AFE_PORT_ID_INT5_MI2S_TX: + return IDX_AFE_PORT_ID_INT5_MI2S_TX; + case AFE_PORT_ID_INT6_MI2S_RX: + return IDX_AFE_PORT_ID_INT6_MI2S_RX; + case AFE_PORT_ID_INT6_MI2S_TX: + return IDX_AFE_PORT_ID_INT6_MI2S_TX; + default: + pr_err("%s: port 0x%x\n", __func__, port_id); + return -EINVAL; + } +} + +int afe_open(u16 port_id, + union afe_port_config *afe_config, int rate) +{ + struct afe_port_cmd_device_start start; + struct afe_audioif_config_command config; + int ret = 0; + int cfg_type; + int index = 0; + + if (!afe_config) { + pr_err("%s: Error, no configuration data\n", __func__); + ret = -EINVAL; + return ret; + } + + pr_err("%s: port_id 0x%x rate %d\n", __func__, port_id, rate); + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Invalid port 0x%x ret %d", __func__, port_id, ret); + return -EINVAL; + } + + if ((port_id == RT_PROXY_DAI_001_RX) || + (port_id == RT_PROXY_DAI_002_TX)) { + pr_err("%s: wrong port 0x%x\n", __func__, port_id); + return -EINVAL; + } + if ((port_id == RT_PROXY_DAI_002_RX) || + (port_id == RT_PROXY_DAI_001_TX)) + port_id = VIRTUAL_ID_TO_PORTID(port_id); + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return -EINVAL; + } + + if ((index >= 0) && (index < AFE_MAX_PORTS)) { + this_afe.afe_sample_rates[index] = rate; + + if (this_afe.rt_cb) + this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id); + } + + /* Also send the topology id here: */ + afe_send_custom_topology(); /* One time call: only for first time */ + afe_send_port_topology_id(port_id); + + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Failed : Invalid Port id = 0x%x ret %d\n", + __func__, port_id, ret); + return -EINVAL; + } + mutex_lock(&this_afe.afe_cmd_lock); + + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = index; + switch (port_id) { + case PRIMARY_I2S_RX: + case PRIMARY_I2S_TX: + cfg_type = AFE_PARAM_ID_I2S_CONFIG; + break; + case AFE_PORT_ID_PRIMARY_PCM_RX: + case AFE_PORT_ID_PRIMARY_PCM_TX: + case AFE_PORT_ID_SECONDARY_PCM_RX: + case AFE_PORT_ID_SECONDARY_PCM_TX: + case AFE_PORT_ID_TERTIARY_PCM_RX: + case AFE_PORT_ID_TERTIARY_PCM_TX: + case AFE_PORT_ID_QUATERNARY_PCM_RX: + case AFE_PORT_ID_QUATERNARY_PCM_TX: + cfg_type = AFE_PARAM_ID_PCM_CONFIG; + break; + case SECONDARY_I2S_RX: + case SECONDARY_I2S_TX: + case AFE_PORT_ID_PRIMARY_MI2S_RX: + case AFE_PORT_ID_PRIMARY_MI2S_TX: + case AFE_PORT_ID_QUATERNARY_MI2S_RX: + case AFE_PORT_ID_QUATERNARY_MI2S_TX: + case MI2S_RX: + case MI2S_TX: + case AFE_PORT_ID_QUINARY_MI2S_RX: + case AFE_PORT_ID_QUINARY_MI2S_TX: + case AFE_PORT_ID_SENARY_MI2S_TX: + cfg_type = AFE_PARAM_ID_I2S_CONFIG; + break; + case HDMI_RX: + case DISPLAY_PORT_RX: + cfg_type = AFE_PARAM_ID_HDMI_CONFIG; + break; + case SLIMBUS_0_RX: + case SLIMBUS_0_TX: + case SLIMBUS_1_RX: + case SLIMBUS_1_TX: + case SLIMBUS_2_RX: + case SLIMBUS_2_TX: + case SLIMBUS_3_RX: + case SLIMBUS_3_TX: + case SLIMBUS_4_RX: + case SLIMBUS_4_TX: + case SLIMBUS_5_RX: + case SLIMBUS_6_RX: + case SLIMBUS_6_TX: + case SLIMBUS_7_RX: + case SLIMBUS_7_TX: + case SLIMBUS_8_RX: + case SLIMBUS_8_TX: + cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG; + break; + case AFE_PORT_ID_USB_RX: + case AFE_PORT_ID_USB_TX: + cfg_type = AFE_PARAM_ID_USB_AUDIO_CONFIG; + break; + default: + pr_err("%s: Invalid port id 0x%x\n", + __func__, port_id); + ret = -EINVAL; + goto fail_cmd; + } + config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + config.param.port_id = q6audio_get_port_id(port_id); + config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) + - sizeof(config.param); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + config.pdata.param_id = cfg_type; + config.pdata.param_size = sizeof(config.port); + + config.port = *afe_config; + pr_debug("%s: param PL size=%d iparam_size[%d][%zd %zd %zd %zd] param_id[0x%x]\n", + __func__, config.param.payload_size, config.pdata.param_size, + sizeof(config), sizeof(config.param), sizeof(config.port), + sizeof(struct apr_hdr), config.pdata.param_id); + + ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE enable for port 0x%x opcode[0x%x]failed %d\n", + __func__, port_id, cfg_type, ret); + goto fail_cmd; + } + start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + start.hdr.pkt_size = sizeof(start); + start.hdr.src_port = 0; + start.hdr.dest_port = 0; + start.hdr.token = index; + start.hdr.opcode = AFE_PORT_CMD_DEVICE_START; + start.port_id = q6audio_get_port_id(port_id); + pr_debug("%s: cmd device start opcode[0x%x] port id[0x%x]\n", + __func__, start.hdr.opcode, start.port_id); + + ret = afe_apr_send_pkt(&start, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE enable for port 0x%x failed %d\n", __func__, + port_id, ret); + goto fail_cmd; + } + +fail_cmd: + mutex_unlock(&this_afe.afe_cmd_lock); + return ret; +} + +int afe_loopback(u16 enable, u16 rx_port, u16 tx_port) +{ + struct afe_loopback_cfg_v1 lb_cmd; + int ret = 0; + int index = 0; + + if (rx_port == MI2S_RX) + rx_port = AFE_PORT_ID_PRIMARY_MI2S_RX; + if (tx_port == MI2S_TX) + tx_port = AFE_PORT_ID_PRIMARY_MI2S_TX; + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + index = q6audio_get_port_index(rx_port); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(rx_port); + if (ret < 0) { + pr_err("%s: Invalid port 0x%x ret %d", __func__, rx_port, ret); + return -EINVAL; + } + + lb_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(20), APR_PKT_VER); + lb_cmd.hdr.pkt_size = sizeof(lb_cmd); + lb_cmd.hdr.src_port = 0; + lb_cmd.hdr.dest_port = 0; + lb_cmd.hdr.token = index; + lb_cmd.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + lb_cmd.param.port_id = tx_port; + lb_cmd.param.payload_size = (sizeof(lb_cmd) - sizeof(struct apr_hdr) - + sizeof(struct afe_port_cmd_set_param_v2)); + lb_cmd.param.payload_address_lsw = 0x00; + lb_cmd.param.payload_address_msw = 0x00; + lb_cmd.param.mem_map_handle = 0x00; + lb_cmd.pdata.module_id = AFE_MODULE_LOOPBACK; + lb_cmd.pdata.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG; + lb_cmd.pdata.param_size = lb_cmd.param.payload_size - + sizeof(struct afe_port_param_data_v2); + + lb_cmd.dst_port_id = rx_port; + lb_cmd.routing_mode = LB_MODE_DEFAULT; + lb_cmd.enable = (enable ? 1 : 0); + lb_cmd.loopback_cfg_minor_version = AFE_API_VERSION_LOOPBACK_CONFIG; + + ret = afe_apr_send_pkt(&lb_cmd, &this_afe.wait[index]); + if (ret) + pr_err("%s: AFE loopback failed %d\n", __func__, ret); + return ret; +} + +int afe_loopback_gain(u16 port_id, u16 volume) +{ + struct afe_loopback_gain_per_path_param set_param; + int ret = 0; + int index = 0; + + if (this_afe.apr == NULL) { + this_afe.apr = apr_register("ADSP", "AFE", afe_callback, + 0xFFFFFFFF, &this_afe); + pr_debug("%s: Register AFE\n", __func__); + if (this_afe.apr == NULL) { + pr_err("%s: Unable to register AFE\n", __func__); + ret = -ENODEV; + return ret; + } + rtac_set_afe_handle(this_afe.apr); + } + + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Failed : Invalid Port id = 0x%x ret %d\n", + __func__, port_id, ret); + ret = -EINVAL; + goto fail_cmd; + } + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Invalid port 0x%x ret %d", + __func__, port_id, ret); + return -EINVAL; + } + + /* RX ports numbers are even .TX ports numbers are odd. */ + if (port_id % 2 == 0) { + pr_err("%s: Failed : afe loopback gain only for TX ports. port_id %d\n", + __func__, port_id); + ret = -EINVAL; + goto fail_cmd; + } + + pr_debug("%s: port 0x%x volume %d\n", __func__, port_id, volume); + + set_param.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + set_param.hdr.pkt_size = sizeof(set_param); + set_param.hdr.src_port = 0; + set_param.hdr.dest_port = 0; + set_param.hdr.token = index; + set_param.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + + set_param.param.port_id = port_id; + set_param.param.payload_size = + (sizeof(struct afe_loopback_gain_per_path_param) - + sizeof(struct apr_hdr) - sizeof(struct afe_port_cmd_set_param_v2)); + set_param.param.payload_address_lsw = 0; + set_param.param.payload_address_msw = 0; + set_param.param.mem_map_handle = 0; + + set_param.pdata.module_id = AFE_MODULE_LOOPBACK; + set_param.pdata.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH; + set_param.pdata.param_size = + (set_param.param.payload_size - + sizeof(struct afe_port_param_data_v2)); + set_param.rx_port_id = port_id; + set_param.gain = volume; + + ret = afe_apr_send_pkt(&set_param, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE param set failed for port 0x%x ret %d\n", + __func__, port_id, ret); + goto fail_cmd; + } + +fail_cmd: + return ret; +} + +int afe_pseudo_port_start_nowait(u16 port_id) +{ + struct afe_pseudoport_start_command start; + int ret = 0; + + pr_debug("%s: port_id=0x%x\n", __func__, port_id); + if (this_afe.apr == NULL) { + pr_err("%s: AFE APR is not registered\n", __func__); + return -ENODEV; + } + + + start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + start.hdr.pkt_size = sizeof(start); + start.hdr.src_port = 0; + start.hdr.dest_port = 0; + start.hdr.token = 0; + start.hdr.opcode = AFE_PSEUDOPORT_CMD_START; + start.port_id = port_id; + start.timing = 1; + + ret = afe_apr_send_pkt(&start, NULL); + if (ret) { + pr_err("%s: AFE enable for port 0x%x failed %d\n", + __func__, port_id, ret); + return ret; + } + return 0; +} + +int afe_start_pseudo_port(u16 port_id) +{ + int ret = 0; + struct afe_pseudoport_start_command start; + int index = 0; + + pr_debug("%s: port_id = 0x%x\n", __func__, port_id); + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Invalid port 0x%x ret %d", + __func__, port_id, ret); + return -EINVAL; + } + + start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + start.hdr.pkt_size = sizeof(start); + start.hdr.src_port = 0; + start.hdr.dest_port = 0; + start.hdr.token = 0; + start.hdr.opcode = AFE_PSEUDOPORT_CMD_START; + start.port_id = port_id; + start.timing = 1; + start.hdr.token = index; + + ret = afe_apr_send_pkt(&start, &this_afe.wait[index]); + if (ret) + pr_err("%s: AFE enable for port 0x%x failed %d\n", + __func__, port_id, ret); + return ret; +} + +int afe_pseudo_port_stop_nowait(u16 port_id) +{ + int ret = 0; + struct afe_pseudoport_stop_command stop; + int index = 0; + + pr_debug("%s: port_id = 0x%x\n", __func__, port_id); + + if (this_afe.apr == NULL) { + pr_err("%s: AFE is already closed\n", __func__); + return -EINVAL; + } + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Invalid port 0x%x ret %d", + __func__, port_id, ret); + return -EINVAL; + } + + stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + stop.hdr.pkt_size = sizeof(stop); + stop.hdr.src_port = 0; + stop.hdr.dest_port = 0; + stop.hdr.token = 0; + stop.hdr.opcode = AFE_PSEUDOPORT_CMD_STOP; + stop.port_id = port_id; + stop.reserved = 0; + stop.hdr.token = index; + + ret = afe_apr_send_pkt(&stop, NULL); + if (ret) + pr_err("%s: AFE close failed %d\n", __func__, ret); + + return ret; +} + +int afe_port_group_set_param(u16 group_id, + union afe_port_group_config *afe_group_config) +{ + int ret; + struct afe_port_group_create config; + int cfg_type; + + if (!afe_group_config) { + pr_err("%s: Error, no configuration data\n", __func__); + return -EINVAL; + } + + pr_debug("%s: group id: 0x%x\n", __func__, group_id); + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + switch (group_id) { + case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX: + case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX: + case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_RX: + case AFE_GROUP_DEVICE_ID_SECONDARY_TDM_TX: + case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_RX: + case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_TX: + case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_RX: + case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_TX: + cfg_type = AFE_PARAM_ID_GROUP_DEVICE_TDM_CONFIG; + break; + default: + pr_err("%s: Invalid group id 0x%x\n", __func__, group_id); + return -EINVAL; + } + + memset(&config, 0, sizeof(config)); + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = IDX_GLOBAL_CFG; + config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; + + config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - + sizeof(config.param); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_GROUP_DEVICE; + config.pdata.param_id = cfg_type; + config.pdata.param_size = sizeof(config.data); + config.data = *afe_group_config; + + ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + if (ret) + pr_err("%s: AFE_PARAM_ID_GROUP_DEVICE_CFG failed %d\n", + __func__, ret); + + return ret; +} + +int afe_port_group_enable(u16 group_id, + union afe_port_group_config *afe_group_config, + u16 enable) +{ + int ret; + struct afe_port_group_create config; + + pr_debug("%s: group id: 0x%x enable: %d\n", __func__, + group_id, enable); + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + if (enable) { + ret = afe_port_group_set_param(group_id, afe_group_config); + if (ret < 0) { + pr_err("%s: afe send failed %d\n", __func__, ret); + return ret; + } + } + + memset(&config, 0, sizeof(config)); + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = IDX_GLOBAL_CFG; + config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; + + config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - + sizeof(config.param); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_GROUP_DEVICE; + config.pdata.param_id = AFE_PARAM_ID_GROUP_DEVICE_ENABLE; + config.pdata.param_size = sizeof(config.data); + config.data.group_enable.group_id = group_id; + config.data.group_enable.enable = enable; + + ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + if (ret) + pr_err("%s: AFE_PARAM_ID_GROUP_DEVICE_ENABLE failed %d\n", + __func__, ret); + + return ret; +} + +int afe_stop_pseudo_port(u16 port_id) +{ + int ret = 0; + struct afe_pseudoport_stop_command stop; + int index = 0; + + pr_debug("%s: port_id = 0x%x\n", __func__, port_id); + + if (this_afe.apr == NULL) { + pr_err("%s: AFE is already closed\n", __func__); + return -EINVAL; + } + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Invalid port 0x%x ret %d\n", + __func__, port_id, ret); + return -EINVAL; + } + + stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + stop.hdr.pkt_size = sizeof(stop); + stop.hdr.src_port = 0; + stop.hdr.dest_port = 0; + stop.hdr.token = 0; + stop.hdr.opcode = AFE_PSEUDOPORT_CMD_STOP; + stop.port_id = port_id; + stop.reserved = 0; + stop.hdr.token = index; + + ret = afe_apr_send_pkt(&stop, &this_afe.wait[index]); + if (ret) + pr_err("%s: AFE close failed %d\n", __func__, ret); + + return ret; +} + +uint32_t afe_req_mmap_handle(struct afe_audio_client *ac) +{ + return ac->mem_map_handle; +} + +struct afe_audio_client *q6afe_audio_client_alloc(void *priv) +{ + struct afe_audio_client *ac; + int lcnt = 0; + + ac = kzalloc(sizeof(struct afe_audio_client), GFP_KERNEL); + if (!ac) + return NULL; + + ac->priv = priv; + + init_waitqueue_head(&ac->cmd_wait); + INIT_LIST_HEAD(&ac->port[0].mem_map_handle); + INIT_LIST_HEAD(&ac->port[1].mem_map_handle); + pr_debug("%s: mem_map_handle list init'ed\n", __func__); + mutex_init(&ac->cmd_lock); + for (lcnt = 0; lcnt <= OUT; lcnt++) { + mutex_init(&ac->port[lcnt].lock); + spin_lock_init(&ac->port[lcnt].dsp_lock); + } + atomic_set(&ac->cmd_state, 0); + + return ac; +} + +int q6afe_audio_client_buf_alloc_contiguous(unsigned int dir, + struct afe_audio_client *ac, + unsigned int bufsz, + unsigned int bufcnt) +{ + int cnt = 0; + int rc = 0; + struct afe_audio_buffer *buf; + size_t len; + + if (!(ac) || ((dir != IN) && (dir != OUT))) { + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); + return -EINVAL; + } + + pr_debug("%s: bufsz[%d]bufcnt[%d]\n", + __func__, + bufsz, bufcnt); + + if (ac->port[dir].buf) { + pr_debug("%s: buffer already allocated\n", __func__); + return 0; + } + mutex_lock(&ac->cmd_lock); + buf = kzalloc(((sizeof(struct afe_audio_buffer))*bufcnt), + GFP_KERNEL); + + if (!buf) { + pr_err("%s: null buf\n", __func__); + mutex_unlock(&ac->cmd_lock); + goto fail; + } + + ac->port[dir].buf = buf; + + rc = msm_audio_ion_alloc("afe_client", &buf[0].client, + &buf[0].handle, bufsz*bufcnt, + &buf[0].phys, &len, + &buf[0].data); + if (rc) { + pr_err("%s: audio ION alloc failed, rc = %d\n", + __func__, rc); + mutex_unlock(&ac->cmd_lock); + goto fail; + } + + buf[0].used = dir ^ 1; + buf[0].size = bufsz; + buf[0].actual_size = bufsz; + cnt = 1; + while (cnt < bufcnt) { + if (bufsz > 0) { + buf[cnt].data = buf[0].data + (cnt * bufsz); + buf[cnt].phys = buf[0].phys + (cnt * bufsz); + if (!buf[cnt].data) { + pr_err("%s: Buf alloc failed\n", + __func__); + mutex_unlock(&ac->cmd_lock); + goto fail; + } + buf[cnt].used = dir ^ 1; + buf[cnt].size = bufsz; + buf[cnt].actual_size = bufsz; + pr_debug("%s: data[%pK]phys[%pK][%pK]\n", __func__, + buf[cnt].data, + &buf[cnt].phys, + &buf[cnt].phys); + } + cnt++; + } + ac->port[dir].max_buf_cnt = cnt; + mutex_unlock(&ac->cmd_lock); + return 0; +fail: + pr_err("%s: jump fail\n", __func__); + q6afe_audio_client_buf_free_contiguous(dir, ac); + return -EINVAL; +} + +int afe_memory_map(phys_addr_t dma_addr_p, u32 dma_buf_sz, + struct afe_audio_client *ac) +{ + int ret = 0; + + mutex_lock(&this_afe.afe_cmd_lock); + ac->mem_map_handle = 0; + ret = afe_cmd_memory_map(dma_addr_p, dma_buf_sz); + if (ret < 0) { + pr_err("%s: afe_cmd_memory_map failed %d\n", + __func__, ret); + + mutex_unlock(&this_afe.afe_cmd_lock); + return ret; + } + ac->mem_map_handle = this_afe.mmap_handle; + mutex_unlock(&this_afe.afe_cmd_lock); + + return ret; +} + +int afe_cmd_memory_map(phys_addr_t dma_addr_p, u32 dma_buf_sz) +{ + int ret = 0; + int cmd_size = 0; + void *payload = NULL; + void *mmap_region_cmd = NULL; + struct afe_service_cmd_shared_mem_map_regions *mregion = NULL; + struct afe_service_shared_map_region_payload *mregion_pl = NULL; + int index = 0; + + pr_debug("%s:\n", __func__); + + if (this_afe.apr == NULL) { + this_afe.apr = apr_register("ADSP", "AFE", afe_callback, + 0xFFFFFFFF, &this_afe); + pr_debug("%s: Register AFE\n", __func__); + if (this_afe.apr == NULL) { + pr_err("%s: Unable to register AFE\n", __func__); + ret = -ENODEV; + return ret; + } + rtac_set_afe_handle(this_afe.apr); + } + if (dma_buf_sz % SZ_4K != 0) { + /* + * The memory allocated by msm_audio_ion_alloc is always 4kB + * aligned, ADSP expects the size to be 4kB aligned as well + * so re-adjusts the buffer size before passing to ADSP. + */ + dma_buf_sz = PAGE_ALIGN(dma_buf_sz); + } + + cmd_size = sizeof(struct afe_service_cmd_shared_mem_map_regions) + + sizeof(struct afe_service_shared_map_region_payload); + + mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL); + if (!mmap_region_cmd) + return -ENOMEM; + + mregion = (struct afe_service_cmd_shared_mem_map_regions *) + mmap_region_cmd; + mregion->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + mregion->hdr.pkt_size = cmd_size; + mregion->hdr.src_port = 0; + mregion->hdr.dest_port = 0; + mregion->hdr.token = 0; + mregion->hdr.opcode = AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS; + mregion->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL; + mregion->num_regions = 1; + mregion->property_flag = 0x00; + /* Todo */ + index = mregion->hdr.token = IDX_RSVD_2; + + payload = ((u8 *) mmap_region_cmd + + sizeof(struct afe_service_cmd_shared_mem_map_regions)); + + mregion_pl = (struct afe_service_shared_map_region_payload *)payload; + + mregion_pl->shm_addr_lsw = lower_32_bits(dma_addr_p); + mregion_pl->shm_addr_msw = msm_audio_populate_upper_32_bits(dma_addr_p); + mregion_pl->mem_size_bytes = dma_buf_sz; + + pr_debug("%s: dma_addr_p 0x%pK , size %d\n", __func__, + &dma_addr_p, dma_buf_sz); + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + this_afe.mmap_handle = 0; + ret = apr_send_pkt(this_afe.apr, (uint32_t *) mmap_region_cmd); + if (ret < 0) { + pr_err("%s: AFE memory map cmd failed %d\n", + __func__, ret); + ret = -EINVAL; + goto fail_cmd; + } + + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto fail_cmd; + } + + kfree(mmap_region_cmd); + return 0; +fail_cmd: + kfree(mmap_region_cmd); + pr_err("%s: fail_cmd\n", __func__); + return ret; +} + +int afe_cmd_memory_map_nowait(int port_id, phys_addr_t dma_addr_p, + u32 dma_buf_sz) +{ + int ret = 0; + int cmd_size = 0; + void *payload = NULL; + void *mmap_region_cmd = NULL; + struct afe_service_cmd_shared_mem_map_regions *mregion = NULL; + struct afe_service_shared_map_region_payload *mregion_pl = NULL; + int index = 0; + + pr_debug("%s:\n", __func__); + + if (this_afe.apr == NULL) { + this_afe.apr = apr_register("ADSP", "AFE", afe_callback, + 0xFFFFFFFF, &this_afe); + pr_debug("%s: Register AFE\n", __func__); + if (this_afe.apr == NULL) { + pr_err("%s: Unable to register AFE\n", __func__); + ret = -ENODEV; + return ret; + } + rtac_set_afe_handle(this_afe.apr); + } + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Invalid port 0x%x ret %d", + __func__, port_id, ret); + return -EINVAL; + } + + cmd_size = sizeof(struct afe_service_cmd_shared_mem_map_regions) + + sizeof(struct afe_service_shared_map_region_payload); + + mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL); + if (!mmap_region_cmd) + return -ENOMEM; + + mregion = (struct afe_service_cmd_shared_mem_map_regions *) + mmap_region_cmd; + mregion->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + mregion->hdr.pkt_size = sizeof(mregion); + mregion->hdr.src_port = 0; + mregion->hdr.dest_port = 0; + mregion->hdr.token = 0; + mregion->hdr.opcode = AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS; + mregion->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL; + mregion->num_regions = 1; + mregion->property_flag = 0x00; + + payload = ((u8 *) mmap_region_cmd + + sizeof(struct afe_service_cmd_shared_mem_map_regions)); + mregion_pl = (struct afe_service_shared_map_region_payload *)payload; + + mregion_pl->shm_addr_lsw = lower_32_bits(dma_addr_p); + mregion_pl->shm_addr_msw = msm_audio_populate_upper_32_bits(dma_addr_p); + mregion_pl->mem_size_bytes = dma_buf_sz; + + ret = afe_apr_send_pkt(mmap_region_cmd, NULL); + if (ret) + pr_err("%s: AFE memory map cmd failed %d\n", + __func__, ret); + kfree(mmap_region_cmd); + return ret; +} +int q6afe_audio_client_buf_free_contiguous(unsigned int dir, + struct afe_audio_client *ac) +{ + struct afe_audio_port_data *port; + int cnt = 0; + + mutex_lock(&ac->cmd_lock); + port = &ac->port[dir]; + if (!port->buf) { + pr_err("%s: buf is null\n", __func__); + mutex_unlock(&ac->cmd_lock); + return 0; + } + cnt = port->max_buf_cnt - 1; + + if (port->buf[0].data) { + pr_debug("%s: data[%pK]phys[%pK][%pK] , client[%pK] handle[%pK]\n", + __func__, + port->buf[0].data, + &port->buf[0].phys, + &port->buf[0].phys, + port->buf[0].client, + port->buf[0].handle); + msm_audio_ion_free(port->buf[0].client, port->buf[0].handle); + port->buf[0].client = NULL; + port->buf[0].handle = NULL; + } + + while (cnt >= 0) { + port->buf[cnt].data = NULL; + port->buf[cnt].phys = 0; + cnt--; + } + port->max_buf_cnt = 0; + kfree(port->buf); + port->buf = NULL; + mutex_unlock(&ac->cmd_lock); + return 0; +} + +void q6afe_audio_client_free(struct afe_audio_client *ac) +{ + int loopcnt; + struct afe_audio_port_data *port; + + if (!ac) { + pr_err("%s: audio client is NULL\n", __func__); + return; + } + for (loopcnt = 0; loopcnt <= OUT; loopcnt++) { + port = &ac->port[loopcnt]; + if (!port->buf) + continue; + pr_debug("%s: loopcnt = %d\n", __func__, loopcnt); + q6afe_audio_client_buf_free_contiguous(loopcnt, ac); + } + kfree(ac); +} + +int afe_cmd_memory_unmap(u32 mem_map_handle) +{ + int ret = 0; + struct afe_service_cmd_shared_mem_unmap_regions mregion; + int index = 0; + + pr_debug("%s: handle 0x%x\n", __func__, mem_map_handle); + + if (this_afe.apr == NULL) { + this_afe.apr = apr_register("ADSP", "AFE", afe_callback, + 0xFFFFFFFF, &this_afe); + pr_debug("%s: Register AFE\n", __func__); + if (this_afe.apr == NULL) { + pr_err("%s: Unable to register AFE\n", __func__); + ret = -ENODEV; + return ret; + } + rtac_set_afe_handle(this_afe.apr); + } + + mregion.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + mregion.hdr.pkt_size = sizeof(mregion); + mregion.hdr.src_port = 0; + mregion.hdr.dest_port = 0; + mregion.hdr.token = 0; + mregion.hdr.opcode = AFE_SERVICE_CMD_SHARED_MEM_UNMAP_REGIONS; + mregion.mem_map_handle = mem_map_handle; + + /* Todo */ + index = mregion.hdr.token = IDX_RSVD_2; + + atomic_set(&this_afe.status, 0); + ret = afe_apr_send_pkt(&mregion, &this_afe.wait[index]); + if (ret) + pr_err("%s: AFE memory unmap cmd failed %d\n", + __func__, ret); + + return ret; +} + +int afe_cmd_memory_unmap_nowait(u32 mem_map_handle) +{ + int ret = 0; + struct afe_service_cmd_shared_mem_unmap_regions mregion; + + pr_debug("%s: handle 0x%x\n", __func__, mem_map_handle); + + if (this_afe.apr == NULL) { + this_afe.apr = apr_register("ADSP", "AFE", afe_callback, + 0xFFFFFFFF, &this_afe); + pr_debug("%s: Register AFE\n", __func__); + if (this_afe.apr == NULL) { + pr_err("%s: Unable to register AFE\n", __func__); + ret = -ENODEV; + return ret; + } + rtac_set_afe_handle(this_afe.apr); + } + + mregion.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + mregion.hdr.pkt_size = sizeof(mregion); + mregion.hdr.src_port = 0; + mregion.hdr.dest_port = 0; + mregion.hdr.token = 0; + mregion.hdr.opcode = AFE_SERVICE_CMD_SHARED_MEM_UNMAP_REGIONS; + mregion.mem_map_handle = mem_map_handle; + + ret = afe_apr_send_pkt(&mregion, NULL); + if (ret) + pr_err("%s: AFE memory unmap cmd failed %d\n", + __func__, ret); + return ret; +} + +int afe_register_get_events(u16 port_id, + void (*cb)(uint32_t opcode, + uint32_t token, uint32_t *payload, void *priv), + void *private_data) +{ + int ret = 0; + struct afe_service_cmd_register_rt_port_driver rtproxy; + + pr_debug("%s: port_id: 0x%x\n", __func__, port_id); + + if (this_afe.apr == NULL) { + this_afe.apr = apr_register("ADSP", "AFE", afe_callback, + 0xFFFFFFFF, &this_afe); + pr_debug("%s: Register AFE\n", __func__); + if (this_afe.apr == NULL) { + pr_err("%s: Unable to register AFE\n", __func__); + ret = -ENODEV; + return ret; + } + rtac_set_afe_handle(this_afe.apr); + } + if ((port_id == RT_PROXY_DAI_002_RX) || + (port_id == RT_PROXY_DAI_001_TX)) { + port_id = VIRTUAL_ID_TO_PORTID(port_id); + } else { + pr_err("%s: wrong port id 0x%x\n", __func__, port_id); + return -EINVAL; + } + + if (port_id == RT_PROXY_PORT_001_TX) { + this_afe.tx_cb = cb; + this_afe.tx_private_data = private_data; + } else if (port_id == RT_PROXY_PORT_001_RX) { + this_afe.rx_cb = cb; + this_afe.rx_private_data = private_data; + } + + rtproxy.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + rtproxy.hdr.pkt_size = sizeof(rtproxy); + rtproxy.hdr.src_port = 1; + rtproxy.hdr.dest_port = 1; + rtproxy.hdr.opcode = AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER; + rtproxy.port_id = port_id; + rtproxy.reserved = 0; + + ret = afe_apr_send_pkt(&rtproxy, NULL); + if (ret) + pr_err("%s: AFE reg. rtproxy_event failed %d\n", + __func__, ret); + return ret; +} + +int afe_unregister_get_events(u16 port_id) +{ + int ret = 0; + struct afe_service_cmd_unregister_rt_port_driver rtproxy; + int index = 0; + + pr_debug("%s:\n", __func__); + + if (this_afe.apr == NULL) { + this_afe.apr = apr_register("ADSP", "AFE", afe_callback, + 0xFFFFFFFF, &this_afe); + pr_debug("%s: Register AFE\n", __func__); + if (this_afe.apr == NULL) { + pr_err("%s: Unable to register AFE\n", __func__); + ret = -ENODEV; + return ret; + } + rtac_set_afe_handle(this_afe.apr); + } + + if ((port_id == RT_PROXY_DAI_002_RX) || + (port_id == RT_PROXY_DAI_001_TX)) { + port_id = VIRTUAL_ID_TO_PORTID(port_id); + } else { + pr_err("%s: wrong port id 0x%x\n", __func__, port_id); + return -EINVAL; + } + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Invalid port 0x%x ret %d", __func__, port_id, ret); + return -EINVAL; + } + + rtproxy.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + rtproxy.hdr.pkt_size = sizeof(rtproxy); + rtproxy.hdr.src_port = 0; + rtproxy.hdr.dest_port = 0; + rtproxy.hdr.token = 0; + rtproxy.hdr.opcode = AFE_SERVICE_CMD_UNREGISTER_RT_PORT_DRIVER; + rtproxy.port_id = port_id; + rtproxy.reserved = 0; + + rtproxy.hdr.token = index; + + if (port_id == RT_PROXY_PORT_001_TX) { + this_afe.tx_cb = NULL; + this_afe.tx_private_data = NULL; + } else if (port_id == RT_PROXY_PORT_001_RX) { + this_afe.rx_cb = NULL; + this_afe.rx_private_data = NULL; + } + + ret = afe_apr_send_pkt(&rtproxy, &this_afe.wait[index]); + if (ret) + pr_err("%s: AFE enable Unreg. rtproxy_event failed %d\n", + __func__, ret); + return ret; +} + +int afe_rt_proxy_port_write(phys_addr_t buf_addr_p, + u32 mem_map_handle, int bytes) +{ + int ret = 0; + struct afe_port_data_cmd_rt_proxy_port_write_v2 afecmd_wr; + + if (this_afe.apr == NULL) { + pr_err("%s: register to AFE is not done\n", __func__); + ret = -ENODEV; + return ret; + } + pr_debug("%s: buf_addr_p = 0x%pK bytes = %d\n", __func__, + &buf_addr_p, bytes); + + afecmd_wr.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + afecmd_wr.hdr.pkt_size = sizeof(afecmd_wr); + afecmd_wr.hdr.src_port = 0; + afecmd_wr.hdr.dest_port = 0; + afecmd_wr.hdr.token = 0; + afecmd_wr.hdr.opcode = AFE_PORT_DATA_CMD_RT_PROXY_PORT_WRITE_V2; + afecmd_wr.port_id = RT_PROXY_PORT_001_TX; + afecmd_wr.buffer_address_lsw = lower_32_bits(buf_addr_p); + afecmd_wr.buffer_address_msw = + msm_audio_populate_upper_32_bits(buf_addr_p); + afecmd_wr.mem_map_handle = mem_map_handle; + afecmd_wr.available_bytes = bytes; + afecmd_wr.reserved = 0; + + ret = afe_apr_send_pkt(&afecmd_wr, NULL); + if (ret) + pr_err("%s: AFE rtproxy write to port 0x%x failed %d\n", + __func__, afecmd_wr.port_id, ret); + return ret; + +} + +int afe_rt_proxy_port_read(phys_addr_t buf_addr_p, + u32 mem_map_handle, int bytes) +{ + int ret = 0; + struct afe_port_data_cmd_rt_proxy_port_read_v2 afecmd_rd; + + if (this_afe.apr == NULL) { + pr_err("%s: register to AFE is not done\n", __func__); + ret = -ENODEV; + return ret; + } + pr_debug("%s: buf_addr_p = 0x%pK bytes = %d\n", __func__, + &buf_addr_p, bytes); + + afecmd_rd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + afecmd_rd.hdr.pkt_size = sizeof(afecmd_rd); + afecmd_rd.hdr.src_port = 0; + afecmd_rd.hdr.dest_port = 0; + afecmd_rd.hdr.token = 0; + afecmd_rd.hdr.opcode = AFE_PORT_DATA_CMD_RT_PROXY_PORT_READ_V2; + afecmd_rd.port_id = RT_PROXY_PORT_001_RX; + afecmd_rd.buffer_address_lsw = lower_32_bits(buf_addr_p); + afecmd_rd.buffer_address_msw = + msm_audio_populate_upper_32_bits(buf_addr_p); + afecmd_rd.available_bytes = bytes; + afecmd_rd.mem_map_handle = mem_map_handle; + + ret = afe_apr_send_pkt(&afecmd_rd, NULL); + if (ret) + pr_err("%s: AFE rtproxy read cmd to port 0x%x failed %d\n", + __func__, afecmd_rd.port_id, ret); + return ret; +} + +#ifdef CONFIG_DEBUG_FS +static struct dentry *debugfs_afelb; +static struct dentry *debugfs_afelb_gain; + +static int afe_debug_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + pr_info("%s: debug intf %s\n", __func__, (char *) file->private_data); + return 0; +} + +static int afe_get_parameters(char *buf, long int *param1, int num_of_par) +{ + char *token; + int base, cnt; + + token = strsep(&buf, " "); + + for (cnt = 0; cnt < num_of_par; cnt++) { + if (token != NULL) { + if ((token[1] == 'x') || (token[1] == 'X')) + base = 16; + else + base = 10; + + if (kstrtoul(token, base, ¶m1[cnt]) != 0) { + pr_err("%s: kstrtoul failed\n", + __func__); + return -EINVAL; + } + + token = strsep(&buf, " "); + } else { + pr_err("%s: token NULL\n", __func__); + return -EINVAL; + } + } + return 0; +} +#define AFE_LOOPBACK_ON (1) +#define AFE_LOOPBACK_OFF (0) +static ssize_t afe_debug_write(struct file *filp, + const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char *lb_str = filp->private_data; + char lbuf[32]; + int rc; + unsigned long param[5]; + + if (cnt > sizeof(lbuf) - 1) { + pr_err("%s: cnt %zd size %zd\n", __func__, cnt, sizeof(lbuf)-1); + return -EINVAL; + } + + rc = copy_from_user(lbuf, ubuf, cnt); + if (rc) { + pr_err("%s: copy from user failed %d\n", __func__, rc); + return -EFAULT; + } + + lbuf[cnt] = '\0'; + + if (!strcmp(lb_str, "afe_loopback")) { + rc = afe_get_parameters(lbuf, param, 3); + if (!rc) { + pr_info("%s: %lu %lu %lu\n", lb_str, param[0], param[1], + param[2]); + + if ((param[0] != AFE_LOOPBACK_ON) && (param[0] != + AFE_LOOPBACK_OFF)) { + pr_err("%s: Error, parameter 0 incorrect\n", + __func__); + rc = -EINVAL; + goto afe_error; + } + if ((q6audio_validate_port(param[1]) < 0) || + (q6audio_validate_port(param[2])) < 0) { + pr_err("%s: Error, invalid afe port\n", + __func__); + } + if (this_afe.apr == NULL) { + pr_err("%s: Error, AFE not opened\n", __func__); + rc = -EINVAL; + } else { + rc = afe_loopback(param[0], param[1], param[2]); + } + } else { + pr_err("%s: Error, invalid parameters\n", __func__); + rc = -EINVAL; + } + + } else if (!strcmp(lb_str, "afe_loopback_gain")) { + rc = afe_get_parameters(lbuf, param, 2); + if (!rc) { + pr_info("%s: %s %lu %lu\n", + __func__, lb_str, param[0], param[1]); + + rc = q6audio_validate_port(param[0]); + if (rc < 0) { + pr_err("%s: Error, invalid afe port %d %lu\n", + __func__, rc, param[0]); + rc = -EINVAL; + goto afe_error; + } + + if (param[1] > 100) { + pr_err("%s: Error, volume should be 0 to 100 percentage param = %lu\n", + __func__, param[1]); + rc = -EINVAL; + goto afe_error; + } + + param[1] = (Q6AFE_MAX_VOLUME * param[1]) / 100; + + if (this_afe.apr == NULL) { + pr_err("%s: Error, AFE not opened\n", __func__); + rc = -EINVAL; + } else { + rc = afe_loopback_gain(param[0], param[1]); + } + } else { + pr_err("%s: Error, invalid parameters\n", __func__); + rc = -EINVAL; + } + } + +afe_error: + if (rc == 0) + rc = cnt; + else + pr_err("%s: rc = %d\n", __func__, rc); + + return rc; +} + +static const struct file_operations afe_debug_fops = { + .open = afe_debug_open, + .write = afe_debug_write +}; + +static void config_debug_fs_init(void) +{ + debugfs_afelb = debugfs_create_file("afe_loopback", + 0664, NULL, (void *) "afe_loopback", + &afe_debug_fops); + + debugfs_afelb_gain = debugfs_create_file("afe_loopback_gain", + 0664, NULL, (void *) "afe_loopback_gain", + &afe_debug_fops); +} +static void config_debug_fs_exit(void) +{ + debugfs_remove(debugfs_afelb); + debugfs_remove(debugfs_afelb_gain); +} +#else +static void config_debug_fs_init(void) +{ +} +static void config_debug_fs_exit(void) +{ +} +#endif + +void afe_set_dtmf_gen_rx_portid(u16 port_id, int set) +{ + if (set) + this_afe.dtmf_gen_rx_portid = port_id; + else if (this_afe.dtmf_gen_rx_portid == port_id) + this_afe.dtmf_gen_rx_portid = -1; +} + +int afe_dtmf_generate_rx(int64_t duration_in_ms, + uint16_t high_freq, + uint16_t low_freq, uint16_t gain) +{ + int ret = 0; + int index = 0; + struct afe_dtmf_generation_command cmd_dtmf; + + pr_debug("%s: DTMF AFE Gen\n", __func__); + + if (afe_validate_port(this_afe.dtmf_gen_rx_portid) < 0) { + pr_err("%s: Failed : Invalid Port id = 0x%x\n", + __func__, this_afe.dtmf_gen_rx_portid); + ret = -EINVAL; + goto fail_cmd; + } + + if (this_afe.apr == NULL) { + this_afe.apr = apr_register("ADSP", "AFE", afe_callback, + 0xFFFFFFFF, &this_afe); + pr_debug("%s: Register AFE\n", __func__); + if (this_afe.apr == NULL) { + pr_err("%s: Unable to register AFE\n", __func__); + ret = -ENODEV; + return ret; + } + rtac_set_afe_handle(this_afe.apr); + } + + pr_debug("%s: dur=%lld: hfreq=%d lfreq=%d gain=%d portid=0x%x\n", + __func__, + duration_in_ms, high_freq, low_freq, gain, + this_afe.dtmf_gen_rx_portid); + + cmd_dtmf.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cmd_dtmf.hdr.pkt_size = sizeof(cmd_dtmf); + cmd_dtmf.hdr.src_port = 0; + cmd_dtmf.hdr.dest_port = 0; + cmd_dtmf.hdr.token = 0; + cmd_dtmf.hdr.opcode = AFE_PORTS_CMD_DTMF_CTL; + cmd_dtmf.duration_in_ms = duration_in_ms; + cmd_dtmf.high_freq = high_freq; + cmd_dtmf.low_freq = low_freq; + cmd_dtmf.gain = gain; + cmd_dtmf.num_ports = 1; + cmd_dtmf.port_ids = q6audio_get_port_id(this_afe.dtmf_gen_rx_portid); + + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) &cmd_dtmf); + if (ret < 0) { + pr_err("%s: AFE DTMF failed for num_ports:%d ids:0x%x\n", + __func__, cmd_dtmf.num_ports, cmd_dtmf.port_ids); + ret = -EINVAL; + goto fail_cmd; + } + index = q6audio_get_port_index(this_afe.dtmf_gen_rx_portid); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + ret = -EINVAL; + goto fail_cmd; + } + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto fail_cmd; + } + return 0; + +fail_cmd: + pr_err("%s: failed %d\n", __func__, ret); + return ret; +} + +static int afe_sidetone_iir(u16 tx_port_id) +{ + struct afe_loopback_iir_cfg_v2 iir_sidetone; + int ret; + int index = 0; + uint16_t size = 0; + int cal_index = AFE_SIDETONE_IIR_CAL; + int iir_pregain = 0; + int iir_num_biquad_stages = 0; + int iir_enable; + struct cal_block_data *cal_block; + int mid; + + memset(&iir_sidetone, 0, sizeof(iir_sidetone)); + index = q6audio_get_port_index(tx_port_id); + iir_sidetone.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + iir_sidetone.hdr.pkt_size = sizeof(iir_sidetone); + iir_sidetone.hdr.src_port = 0; + iir_sidetone.hdr.dest_port = 0; + iir_sidetone.hdr.token = index; + iir_sidetone.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + iir_sidetone.param.port_id = tx_port_id; + iir_sidetone.param.payload_address_lsw = 0x00; + iir_sidetone.param.payload_address_msw = 0x00; + iir_sidetone.param.mem_map_handle = 0x00; + + if (this_afe.cal_data[cal_index] == NULL) { + pr_err("%s: cal data is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + mutex_lock(&this_afe.cal_data[cal_index]->lock); + cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); + if (cal_block == NULL) { + pr_err("%s: cal_block not found\n ", __func__); + mutex_unlock(&this_afe.cal_data[cal_index]->lock); + ret = -EINVAL; + goto done; + } + + iir_pregain = ((struct audio_cal_info_sidetone_iir *) + cal_block->cal_info)->pregain; + iir_enable = ((struct audio_cal_info_sidetone_iir *) + cal_block->cal_info)->iir_enable; + iir_num_biquad_stages = ((struct audio_cal_info_sidetone_iir *) + cal_block->cal_info)->num_biquad_stages; + mid = ((struct audio_cal_info_sidetone_iir *) + cal_block->cal_info)->mid; + + /* + * calculate the actual size of payload based on no of stages + * enabled in calibration + */ + size = (MAX_SIDETONE_IIR_DATA_SIZE / MAX_NO_IIR_FILTER_STAGE) * + iir_num_biquad_stages; + /* + * For an odd number of stages, 2 bytes of padding are + * required at the end of the payload. + */ + if (iir_num_biquad_stages % 2) { + pr_debug("%s: adding 2 to size:%d\n", __func__, size); + size = size + 2; + } + memcpy(&iir_sidetone.st_iir_filter_config_data.iir_config, + &((struct audio_cal_info_sidetone_iir *) + cal_block->cal_info)->iir_config, + sizeof(iir_sidetone.st_iir_filter_config_data.iir_config)); + mutex_unlock(&this_afe.cal_data[cal_index]->lock); + + /* + * Calculate the payload size for setparams command + */ + iir_sidetone.param.payload_size = (sizeof(iir_sidetone) - + sizeof(struct apr_hdr) - + sizeof(struct afe_port_cmd_set_param_v2) - + (MAX_SIDETONE_IIR_DATA_SIZE - size)); + + pr_debug("%s: payload size :%d\n", __func__, + iir_sidetone.param.payload_size); + + /* + * Set IIR enable params + */ + iir_sidetone.st_iir_enable_pdata.module_id = mid; + iir_sidetone.st_iir_enable_pdata.param_id = + AFE_PARAM_ID_ENABLE; + iir_sidetone.st_iir_enable_pdata.param_size = + sizeof(iir_sidetone.st_iir_mode_enable_data); + iir_sidetone.st_iir_mode_enable_data.enable = iir_enable; + + /* + * Set IIR filter config params + */ + iir_sidetone.st_iir_filter_config_pdata.module_id = mid; + iir_sidetone.st_iir_filter_config_pdata.param_id = + AFE_PARAM_ID_SIDETONE_IIR_FILTER_CONFIG; + iir_sidetone.st_iir_filter_config_pdata.param_size = + sizeof(iir_sidetone.st_iir_filter_config_data.num_biquad_stages) + + + sizeof(iir_sidetone.st_iir_filter_config_data.pregain) + size; + iir_sidetone.st_iir_filter_config_pdata.reserved = 0; + iir_sidetone.st_iir_filter_config_data.num_biquad_stages = + iir_num_biquad_stages; + iir_sidetone.st_iir_filter_config_data.pregain = iir_pregain; + pr_debug("%s: tx(0x%x)mid(0x%x)iir_en(%d)stg(%d)gain(0x%x)size(%d)\n", + __func__, tx_port_id, mid, + iir_sidetone.st_iir_mode_enable_data.enable, + iir_sidetone.st_iir_filter_config_data.num_biquad_stages, + iir_sidetone.st_iir_filter_config_data.pregain, + iir_sidetone.st_iir_filter_config_pdata.param_size); + ret = afe_apr_send_pkt(&iir_sidetone, &this_afe.wait[index]); + if (ret) + pr_err("%s: AFE sidetone failed for tx_port(0x%x)\n", + __func__, tx_port_id); + +done: + return ret; + +} + +static int afe_sidetone(u16 tx_port_id, u16 rx_port_id, bool enable) +{ + struct afe_st_loopback_cfg_v1 cmd_sidetone; + int ret; + int index; + int cal_index = AFE_SIDETONE_CAL; + int sidetone_gain; + int sidetone_enable; + struct cal_block_data *cal_block; + int mid = 0; + + memset(&cmd_sidetone, 0, sizeof(cmd_sidetone)); + if (this_afe.cal_data[cal_index] == NULL) { + pr_err("%s: cal data is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + mutex_lock(&this_afe.cal_data[cal_index]->lock); + cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); + if (cal_block == NULL) { + pr_err("%s: cal_block not found\n", __func__); + mutex_unlock(&this_afe.cal_data[cal_index]->lock); + ret = -EINVAL; + goto done; + } + sidetone_gain = ((struct audio_cal_info_sidetone *) + cal_block->cal_info)->gain; + sidetone_enable = ((struct audio_cal_info_sidetone *) + cal_block->cal_info)->enable; + mid = ((struct audio_cal_info_sidetone *) + cal_block->cal_info)->mid; + mutex_unlock(&this_afe.cal_data[cal_index]->lock); + + index = q6audio_get_port_index(tx_port_id); + cmd_sidetone.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cmd_sidetone.hdr.pkt_size = sizeof(cmd_sidetone); + cmd_sidetone.hdr.src_port = 0; + cmd_sidetone.hdr.dest_port = 0; + cmd_sidetone.hdr.token = index; + cmd_sidetone.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + cmd_sidetone.param.port_id = tx_port_id; + cmd_sidetone.param.payload_size = (sizeof(cmd_sidetone) - + sizeof(struct apr_hdr) - + sizeof(struct afe_port_cmd_set_param_v2)); + cmd_sidetone.param.payload_address_lsw = 0x00; + cmd_sidetone.param.payload_address_msw = 0x00; + cmd_sidetone.param.mem_map_handle = 0x00; + cmd_sidetone.gain_pdata.module_id = AFE_MODULE_LOOPBACK; + cmd_sidetone.gain_pdata.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH; + /* + * size of actual payload only + */ + cmd_sidetone.gain_pdata.param_size = sizeof( + struct afe_loopback_sidetone_gain); + cmd_sidetone.gain_data.rx_port_id = rx_port_id; + cmd_sidetone.gain_data.gain = sidetone_gain; + + cmd_sidetone.cfg_pdata.module_id = AFE_MODULE_LOOPBACK; + cmd_sidetone.cfg_pdata.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG; + /* + * size of actual payload only + */ + cmd_sidetone.cfg_pdata.param_size = sizeof(struct loopback_cfg_data); + cmd_sidetone.cfg_data.loopback_cfg_minor_version = + AFE_API_VERSION_LOOPBACK_CONFIG; + cmd_sidetone.cfg_data.dst_port_id = rx_port_id; + cmd_sidetone.cfg_data.routing_mode = LB_MODE_SIDETONE; + cmd_sidetone.cfg_data.enable = enable; + + pr_debug("%s rx(0x%x) tx(0x%x) enable(%d) mid(0x%x) gain(%d) sidetone_enable(%d)\n", + __func__, rx_port_id, tx_port_id, + enable, mid, sidetone_gain, sidetone_enable); + + ret = afe_apr_send_pkt(&cmd_sidetone, &this_afe.wait[index]); + if (ret) + pr_err("%s: AFE sidetone send failed for tx_port:%d rx_port:%d ret:%d\n", + __func__, tx_port_id, rx_port_id, ret); +done: + return ret; +} + +int afe_sidetone_enable(u16 tx_port_id, u16 rx_port_id, bool enable) +{ + int ret; + int index; + + index = q6audio_get_port_index(rx_port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + ret = -EINVAL; + goto done; + } + if (q6audio_validate_port(rx_port_id) < 0) { + pr_err("%s: Invalid port 0x%x\n", + __func__, rx_port_id); + ret = -EINVAL; + goto done; + } + index = q6audio_get_port_index(tx_port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + ret = -EINVAL; + goto done; + } + if (q6audio_validate_port(tx_port_id) < 0) { + pr_err("%s: Invalid port 0x%x\n", + __func__, tx_port_id); + ret = -EINVAL; + goto done; + } + if (enable) { + ret = afe_sidetone_iir(tx_port_id); + if (ret) + goto done; + } + + ret = afe_sidetone(tx_port_id, rx_port_id, enable); + +done: + return ret; +} + +int afe_validate_port(u16 port_id) +{ + int ret; + + switch (port_id) { + case PRIMARY_I2S_RX: + case PRIMARY_I2S_TX: + case AFE_PORT_ID_PRIMARY_PCM_RX: + case AFE_PORT_ID_PRIMARY_PCM_TX: + case AFE_PORT_ID_SECONDARY_PCM_RX: + case AFE_PORT_ID_SECONDARY_PCM_TX: + case AFE_PORT_ID_TERTIARY_PCM_RX: + case AFE_PORT_ID_TERTIARY_PCM_TX: + case AFE_PORT_ID_QUATERNARY_PCM_RX: + case AFE_PORT_ID_QUATERNARY_PCM_TX: + case SECONDARY_I2S_RX: + case SECONDARY_I2S_TX: + case MI2S_RX: + case MI2S_TX: + case HDMI_RX: + case DISPLAY_PORT_RX: + case AFE_PORT_ID_SPDIF_RX: + case RSVD_2: + case RSVD_3: + case DIGI_MIC_TX: + case VOICE_RECORD_RX: + case VOICE_RECORD_TX: + case VOICE_PLAYBACK_TX: + case VOICE2_PLAYBACK_TX: + case SLIMBUS_0_RX: + case SLIMBUS_0_TX: + case SLIMBUS_1_RX: + case SLIMBUS_1_TX: + case SLIMBUS_2_RX: + case SLIMBUS_2_TX: + case SLIMBUS_3_RX: + case INT_BT_SCO_RX: + case INT_BT_SCO_TX: + case INT_BT_A2DP_RX: + case INT_FM_RX: + case INT_FM_TX: + case RT_PROXY_PORT_001_RX: + case RT_PROXY_PORT_001_TX: + case SLIMBUS_4_RX: + case SLIMBUS_4_TX: + case SLIMBUS_5_RX: + case SLIMBUS_6_RX: + case SLIMBUS_6_TX: + case SLIMBUS_7_RX: + case SLIMBUS_7_TX: + case SLIMBUS_8_RX: + case SLIMBUS_8_TX: + case AFE_PORT_ID_USB_RX: + case AFE_PORT_ID_USB_TX: + case AFE_PORT_ID_PRIMARY_MI2S_RX: + case AFE_PORT_ID_PRIMARY_MI2S_TX: + case AFE_PORT_ID_SECONDARY_MI2S_RX: + case AFE_PORT_ID_SECONDARY_MI2S_TX: + case AFE_PORT_ID_QUATERNARY_MI2S_RX: + case AFE_PORT_ID_QUATERNARY_MI2S_TX: + case AFE_PORT_ID_TERTIARY_MI2S_RX: + case AFE_PORT_ID_TERTIARY_MI2S_TX: + case AFE_PORT_ID_QUINARY_MI2S_RX: + case AFE_PORT_ID_QUINARY_MI2S_TX: + case AFE_PORT_ID_SENARY_MI2S_TX: + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + case AFE_PORT_ID_INT0_MI2S_RX: + case AFE_PORT_ID_INT1_MI2S_RX: + case AFE_PORT_ID_INT2_MI2S_RX: + case AFE_PORT_ID_INT3_MI2S_RX: + case AFE_PORT_ID_INT4_MI2S_RX: + case AFE_PORT_ID_INT5_MI2S_RX: + case AFE_PORT_ID_INT6_MI2S_RX: + case AFE_PORT_ID_INT0_MI2S_TX: + case AFE_PORT_ID_INT1_MI2S_TX: + case AFE_PORT_ID_INT2_MI2S_TX: + case AFE_PORT_ID_INT3_MI2S_TX: + case AFE_PORT_ID_INT4_MI2S_TX: + case AFE_PORT_ID_INT5_MI2S_TX: + case AFE_PORT_ID_INT6_MI2S_TX: + { + ret = 0; + break; + } + + default: + pr_err("%s: default ret 0x%x\n", __func__, port_id); + ret = -EINVAL; + } + + return ret; +} + +int afe_convert_virtual_to_portid(u16 port_id) +{ + int ret; + + /* + * if port_id is virtual, convert to physical.. + * if port_id is already physical, return physical + */ + if (afe_validate_port(port_id) < 0) { + if (port_id == RT_PROXY_DAI_001_RX || + port_id == RT_PROXY_DAI_001_TX || + port_id == RT_PROXY_DAI_002_RX || + port_id == RT_PROXY_DAI_002_TX) { + ret = VIRTUAL_ID_TO_PORTID(port_id); + } else { + pr_err("%s: wrong port 0x%x\n", + __func__, port_id); + ret = -EINVAL; + } + } else + ret = port_id; + + return ret; +} +int afe_port_stop_nowait(int port_id) +{ + struct afe_port_cmd_device_stop stop; + int ret = 0; + + if (this_afe.apr == NULL) { + pr_err("%s: AFE is already closed\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + pr_debug("%s: port_id = 0x%x\n", __func__, port_id); + port_id = q6audio_convert_virtual_to_portid(port_id); + + stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + stop.hdr.pkt_size = sizeof(stop); + stop.hdr.src_port = 0; + stop.hdr.dest_port = 0; + stop.hdr.token = 0; + stop.hdr.opcode = AFE_PORT_CMD_DEVICE_STOP; + stop.port_id = port_id; + stop.reserved = 0; + + ret = afe_apr_send_pkt(&stop, NULL); + if (ret) + pr_err("%s: AFE close failed %d\n", __func__, ret); + +fail_cmd: + return ret; + +} + +int afe_close(int port_id) +{ + struct afe_port_cmd_device_stop stop; + enum afe_mad_type mad_type; + int ret = 0; + int index = 0; + uint16_t port_index; + + if (this_afe.apr == NULL) { + pr_err("%s: AFE is already closed\n", __func__); + if ((port_id == RT_PROXY_DAI_001_RX) || + (port_id == RT_PROXY_DAI_002_TX)) + pcm_afe_instance[port_id & 0x1] = 0; + if ((port_id == RT_PROXY_DAI_002_RX) || + (port_id == RT_PROXY_DAI_001_TX)) + proxy_afe_instance[port_id & 0x1] = 0; + afe_close_done[port_id & 0x1] = true; + ret = -EINVAL; + goto fail_cmd; + } + pr_debug("%s: port_id = 0x%x\n", __func__, port_id); + if ((port_id == RT_PROXY_DAI_001_RX) || + (port_id == RT_PROXY_DAI_002_TX)) { + pr_debug("%s: before decrementing pcm_afe_instance %d\n", + __func__, pcm_afe_instance[port_id & 0x1]); + port_id = VIRTUAL_ID_TO_PORTID(port_id); + pcm_afe_instance[port_id & 0x1]--; + if ((!(pcm_afe_instance[port_id & 0x1] == 0 && + proxy_afe_instance[port_id & 0x1] == 0)) || + afe_close_done[port_id & 0x1] == true) + return 0; + + afe_close_done[port_id & 0x1] = true; + } + + if ((port_id == RT_PROXY_DAI_002_RX) || + (port_id == RT_PROXY_DAI_001_TX)) { + pr_debug("%s: before decrementing proxy_afe_instance %d\n", + __func__, proxy_afe_instance[port_id & 0x1]); + port_id = VIRTUAL_ID_TO_PORTID(port_id); + proxy_afe_instance[port_id & 0x1]--; + if ((!(pcm_afe_instance[port_id & 0x1] == 0 && + proxy_afe_instance[port_id & 0x1] == 0)) || + afe_close_done[port_id & 0x1] == true) + return 0; + + afe_close_done[port_id & 0x1] = true; + } + + port_id = q6audio_convert_virtual_to_portid(port_id); + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_warn("%s: Not a valid port id 0x%x ret %d\n", + __func__, port_id, ret); + return -EINVAL; + } + + mad_type = afe_port_get_mad_type(port_id); + pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, + mad_type); + if (mad_type != MAD_HW_NONE && mad_type != MAD_SW_AUDIO) { + pr_debug("%s: Turn off MAD\n", __func__); + ret = afe_turn_onoff_hw_mad(mad_type, false); + if (ret) { + pr_err("%s: afe_turn_onoff_hw_mad failed %d\n", + __func__, ret); + return ret; + } + } else { + pr_debug("%s: Not a MAD port\n", __func__); + } + + port_index = afe_get_port_index(port_id); + if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) { + this_afe.afe_sample_rates[port_index] = 0; + this_afe.topology[port_index] = 0; + this_afe.dev_acdb_id[port_index] = 0; + } else { + pr_err("%s: port %d\n", __func__, port_index); + ret = -EINVAL; + goto fail_cmd; + } + + if ((port_id == this_afe.aanc_info.aanc_tx_port) && + (this_afe.aanc_info.aanc_active)) { + memset(&this_afe.aanc_info, 0x00, sizeof(this_afe.aanc_info)); + ret = afe_aanc_mod_enable(this_afe.apr, port_id, 0); + if (ret) + pr_err("%s: AFE mod disable failed %d\n", + __func__, ret); + } + + /* + * even if ramp down configuration failed it is not serious enough to + * warrant bailaing out. + */ + if (afe_spk_ramp_dn_cfg(port_id) < 0) + pr_err("%s: ramp down configuration failed\n", __func__); + + stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + stop.hdr.pkt_size = sizeof(stop); + stop.hdr.src_port = 0; + stop.hdr.dest_port = 0; + stop.hdr.token = index; + stop.hdr.opcode = AFE_PORT_CMD_DEVICE_STOP; + stop.port_id = q6audio_get_port_id(port_id); + stop.reserved = 0; + + ret = afe_apr_send_pkt(&stop, &this_afe.wait[index]); + if (ret) + pr_err("%s: AFE close failed %d\n", __func__, ret); + +fail_cmd: + return ret; +} + +int afe_set_digital_codec_core_clock(u16 port_id, + struct afe_digital_clk_cfg *cfg) +{ + struct afe_lpass_digital_clk_config_command clk_cfg; + int index = 0; + int ret = 0; + + if (!cfg) { + pr_err("%s: clock cfg is NULL\n", __func__); + ret = -EINVAL; + return ret; + } + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + clk_cfg.hdr.pkt_size = sizeof(clk_cfg); + clk_cfg.hdr.src_port = 0; + clk_cfg.hdr.dest_port = 0; + clk_cfg.hdr.token = index; + + clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + /*default rx port is taken to enable the codec digital clock*/ + clk_cfg.param.port_id = q6audio_get_port_id(port_id); + clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) + - sizeof(clk_cfg.param); + clk_cfg.param.payload_address_lsw = 0x00; + clk_cfg.param.payload_address_msw = 0x00; + clk_cfg.param.mem_map_handle = 0x00; + clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + clk_cfg.pdata.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG; + clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); + clk_cfg.clk_cfg = *cfg; + + pr_debug("%s: Minor version =0x%x clk val = %d\n" + "clk root = 0x%x resrv = 0x%x\n", + __func__, cfg->i2s_cfg_minor_version, + cfg->clk_val, cfg->clk_root, cfg->reserved); + + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); + if (ret < 0) { + pr_err("%s: AFE enable for port 0x%x ret %d\n", + __func__, port_id, ret); + ret = -EINVAL; + goto fail_cmd; + } + + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto fail_cmd; + } + +fail_cmd: + return ret; +} + +int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg) +{ + struct afe_lpass_clk_config_command clk_cfg; + int index = 0; + int ret = 0; + + if (!cfg) { + pr_err("%s: clock cfg is NULL\n", __func__); + ret = -EINVAL; + return ret; + } + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_is_digital_pcm_interface(port_id); + if (ret < 0) { + pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n", + __func__, ret); + return -EINVAL; + } + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + mutex_lock(&this_afe.afe_cmd_lock); + clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + clk_cfg.hdr.pkt_size = sizeof(clk_cfg); + clk_cfg.hdr.src_port = 0; + clk_cfg.hdr.dest_port = 0; + clk_cfg.hdr.token = index; + + clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + clk_cfg.param.port_id = q6audio_get_port_id(port_id); + clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) + - sizeof(clk_cfg.param); + clk_cfg.param.payload_address_lsw = 0x00; + clk_cfg.param.payload_address_msw = 0x00; + clk_cfg.param.mem_map_handle = 0x00; + clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + clk_cfg.pdata.param_id = AFE_PARAM_ID_LPAIF_CLK_CONFIG; + clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); + clk_cfg.clk_cfg = *cfg; + + pr_debug("%s: Minor version =0x%x clk val1 = %d\n" + "clk val2 = %d, clk src = 0x%x\n" + "clk root = 0x%x clk mode = 0x%x resrv = 0x%x\n" + "port id = 0x%x\n", + __func__, cfg->i2s_cfg_minor_version, + cfg->clk_val1, cfg->clk_val2, cfg->clk_src, + cfg->clk_root, cfg->clk_set_mode, + cfg->reserved, q6audio_get_port_id(port_id)); + + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); + if (ret < 0) { + pr_err("%s: AFE enable for port 0x%x ret %d\n", + __func__, port_id, ret); + ret = -EINVAL; + goto fail_cmd; + } + + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto fail_cmd; + } + +fail_cmd: + mutex_unlock(&this_afe.afe_cmd_lock); + return ret; +} + +/** + * afe_set_lpass_clk_cfg - Set AFE clk config + * + * @index: port index + * @cfg: pointer to clk set struct + * + * Returns 0 on success, appropriate error code otherwise + */ +int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg) +{ + struct afe_lpass_clk_config_command_v2 clk_cfg; + int ret = 0; + + if (!cfg) { + pr_err("%s: clock cfg is NULL\n", __func__); + ret = -EINVAL; + return ret; + } + + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: index[%d] invalid!\n", __func__, index); + return -EINVAL; + } + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + mutex_lock(&this_afe.afe_cmd_lock); + clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + clk_cfg.hdr.pkt_size = sizeof(clk_cfg); + clk_cfg.hdr.src_port = 0; + clk_cfg.hdr.dest_port = 0; + clk_cfg.hdr.token = index; + + clk_cfg.hdr.opcode = AFE_SVC_CMD_SET_PARAM; + clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) + - sizeof(clk_cfg.param); + clk_cfg.param.payload_address_lsw = 0x00; + clk_cfg.param.payload_address_msw = 0x00; + clk_cfg.param.mem_map_handle = 0x00; + clk_cfg.pdata.module_id = AFE_MODULE_CLOCK_SET; + clk_cfg.pdata.param_id = AFE_PARAM_ID_CLOCK_SET; + clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); + clk_cfg.clk_cfg = *cfg; + + + pr_debug("%s: Minor version =0x%x clk id = %d\n" + "clk freq (Hz) = %d, clk attri = 0x%x\n" + "clk root = 0x%x clk enable = 0x%x\n", + __func__, cfg->clk_set_minor_version, + cfg->clk_id, cfg->clk_freq_in_hz, cfg->clk_attri, + cfg->clk_root, cfg->enable); + + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); + if (ret < 0) { + pr_err("%s: AFE clk cfg failed with ret %d\n", + __func__, ret); + ret = -EINVAL; + goto fail_cmd; + } + + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } else { + /* set ret to 0 as no timeout happened */ + ret = 0; + } + if (atomic_read(&this_afe.status) != 0) { + pr_err("%s: config cmd failed\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + +fail_cmd: + mutex_unlock(&this_afe.afe_cmd_lock); + return ret; +} +EXPORT_SYMBOL(afe_set_lpass_clk_cfg); + +/** + * afe_set_lpass_clock_v2 - Enable AFE lpass clock + * + * @port_id: AFE port id + * @cfg: pointer to clk set struct + * + * Returns 0 on success, appropriate error code otherwise + */ +int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg) +{ + int index = 0; + int ret = 0; + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_is_digital_pcm_interface(port_id); + if (ret < 0) { + pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n", + __func__, ret); + return -EINVAL; + } + + ret = afe_set_lpass_clk_cfg(index, cfg); + if (ret) + pr_err("%s: afe_set_lpass_clk_cfg_v2 failed %d\n", + __func__, ret); + + return ret; +} +EXPORT_SYMBOL(afe_set_lpass_clock_v2); + +int afe_set_lpass_internal_digital_codec_clock(u16 port_id, + struct afe_digital_clk_cfg *cfg) +{ + struct afe_lpass_digital_clk_config_command clk_cfg; + int index = 0; + int ret = 0; + + if (!cfg) { + pr_err("%s: clock cfg is NULL\n", __func__); + ret = -EINVAL; + return ret; + } + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_is_digital_pcm_interface(port_id); + if (ret < 0) { + pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n", + __func__, ret); + return -EINVAL; + } + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + clk_cfg.hdr.pkt_size = sizeof(clk_cfg); + clk_cfg.hdr.src_port = 0; + clk_cfg.hdr.dest_port = 0; + clk_cfg.hdr.token = index; + + clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + clk_cfg.param.port_id = q6audio_get_port_id(port_id); + clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) + - sizeof(clk_cfg.param); + clk_cfg.param.payload_address_lsw = 0x00; + clk_cfg.param.payload_address_msw = 0x00; + clk_cfg.param.mem_map_handle = 0x00; + clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + clk_cfg.pdata.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG; + clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); + clk_cfg.clk_cfg = *cfg; + + pr_debug("%s: Minor version =0x%x clk val = %d\n" + "clk root = 0x%x resrv = 0x%x port id = 0x%x\n", + __func__, cfg->i2s_cfg_minor_version, + cfg->clk_val, cfg->clk_root, cfg->reserved, + q6audio_get_port_id(port_id)); + + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); + if (ret < 0) { + pr_err("%s: AFE enable for port 0x0x%x ret %d\n", + __func__, port_id, ret); + ret = -EINVAL; + goto fail_cmd; + } + + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto fail_cmd; + } + +fail_cmd: + return ret; +} + +int afe_enable_lpass_core_shared_clock(u16 port_id, u32 enable) +{ + struct afe_lpass_core_shared_clk_config_command clk_cfg; + int index = 0; + int ret = 0; + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_is_digital_pcm_interface(port_id); + if (ret < 0) { + pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n", + __func__, ret); + return -EINVAL; + } + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + mutex_lock(&this_afe.afe_cmd_lock); + clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + clk_cfg.hdr.pkt_size = sizeof(clk_cfg); + clk_cfg.hdr.src_port = 0; + clk_cfg.hdr.dest_port = 0; + clk_cfg.hdr.token = index; + + clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + clk_cfg.param.port_id = q6audio_get_port_id(port_id); + clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) + - sizeof(clk_cfg.param); + clk_cfg.param.payload_address_lsw = 0x00; + clk_cfg.param.payload_address_msw = 0x00; + clk_cfg.param.mem_map_handle = 0x00; + clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + clk_cfg.pdata.param_id = AFE_PARAM_ID_LPASS_CORE_SHARED_CLOCK_CONFIG; + clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); + clk_cfg.clk_cfg.lpass_core_shared_clk_cfg_minor_version = + AFE_API_VERSION_LPASS_CORE_SHARED_CLK_CONFIG; + clk_cfg.clk_cfg.enable = enable; + + pr_debug("%s: port id = %d, enable = %d\n", + __func__, q6audio_get_port_id(port_id), enable); + + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); + if (ret < 0) { + pr_err("%s: AFE enable for port 0x%x ret %d\n", + __func__, port_id, ret); + ret = -EINVAL; + goto fail_cmd; + } + + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto fail_cmd; + } + +fail_cmd: + mutex_unlock(&this_afe.afe_cmd_lock); + return ret; +} + +int q6afe_check_osr_clk_freq(u32 freq) +{ + int ret = 0; + + switch (freq) { + case Q6AFE_LPASS_OSR_CLK_12_P288_MHZ: + case Q6AFE_LPASS_OSR_CLK_8_P192_MHZ: + case Q6AFE_LPASS_OSR_CLK_6_P144_MHZ: + case Q6AFE_LPASS_OSR_CLK_4_P096_MHZ: + case Q6AFE_LPASS_OSR_CLK_3_P072_MHZ: + case Q6AFE_LPASS_OSR_CLK_2_P048_MHZ: + case Q6AFE_LPASS_OSR_CLK_1_P536_MHZ: + case Q6AFE_LPASS_OSR_CLK_1_P024_MHZ: + case Q6AFE_LPASS_OSR_CLK_768_kHZ: + case Q6AFE_LPASS_OSR_CLK_512_kHZ: + break; + default: + pr_err("%s: deafault freq 0x%x\n", + __func__, freq); + ret = -EINVAL; + } + return ret; +} + +int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) +{ + int ret = -EINVAL; + int index = 0, port = SLIMBUS_4_TX; + + if (!th_vi) { + pr_err("%s: Invalid params\n", __func__); + goto done; + } + if (this_afe.vi_tx_port != -1) + port = this_afe.vi_tx_port; + + ret = q6audio_validate_port(port); + if (ret < 0) { + pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret); + goto done; + } + index = q6audio_get_port_index(port); + if (index < 0) { + pr_err("%s: invalid port 0x%x, index %d\n", + __func__, port, index); + ret = -EINVAL; + goto done; + } + th_vi->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + th_vi->hdr.pkt_size = sizeof(*th_vi); + th_vi->hdr.src_port = 0; + th_vi->hdr.dest_port = 0; + th_vi->hdr.token = index; + th_vi->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; + th_vi->get_param.mem_map_handle = 0; + th_vi->get_param.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; + th_vi->get_param.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS; + th_vi->get_param.payload_address_lsw = 0; + th_vi->get_param.payload_address_msw = 0; + th_vi->get_param.payload_size = sizeof(*th_vi) + - sizeof(th_vi->get_param) - sizeof(th_vi->hdr); + th_vi->get_param.port_id = q6audio_get_port_id(port); + th_vi->pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; + th_vi->pdata.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS; + th_vi->pdata.param_size = sizeof(th_vi->param); + atomic_set(&this_afe.status, 0); + atomic_set(&this_afe.state, 1); + ret = apr_send_pkt(this_afe.apr, (uint32_t *)th_vi); + if (ret < 0) { + pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", + __func__, port, th_vi->get_param.param_id, ret); + goto done; + } + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto done; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code(atomic_read(&this_afe.status)); + goto done; + } + memcpy(&th_vi->param, &this_afe.th_vi_resp.param, + sizeof(this_afe.th_vi_resp.param)); + pr_debug("%s: DC resistance %d %d temp %d %d status %d %d\n", + __func__, th_vi->param.dc_res_q24[SP_V2_SPKR_1], + th_vi->param.dc_res_q24[SP_V2_SPKR_2], + th_vi->param.temp_q22[SP_V2_SPKR_1], + th_vi->param.temp_q22[SP_V2_SPKR_2], + th_vi->param.status[SP_V2_SPKR_1], + th_vi->param.status[SP_V2_SPKR_2]); + ret = 0; +done: + return ret; +} + +int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) +{ + int ret = -EINVAL; + int index = 0, port = SLIMBUS_4_TX; + + if (!ex_vi) { + pr_err("%s: Invalid params\n", __func__); + goto done; + } + if (this_afe.vi_tx_port != -1) + port = this_afe.vi_tx_port; + + ret = q6audio_validate_port(port); + if (ret < 0) { + pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret); + goto done; + } + + index = q6audio_get_port_index(port); + if (index < 0) { + pr_err("%s: invalid index %d port 0x%x\n", __func__, + index, port); + ret = -EINVAL; + goto done; + } + + ex_vi->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + ex_vi->hdr.pkt_size = sizeof(*ex_vi); + ex_vi->hdr.src_port = 0; + ex_vi->hdr.dest_port = 0; + ex_vi->hdr.token = index; + ex_vi->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; + ex_vi->get_param.mem_map_handle = 0; + ex_vi->get_param.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; + ex_vi->get_param.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS; + ex_vi->get_param.payload_address_lsw = 0; + ex_vi->get_param.payload_address_msw = 0; + ex_vi->get_param.payload_size = sizeof(*ex_vi) + - sizeof(ex_vi->get_param) - sizeof(ex_vi->hdr); + ex_vi->get_param.port_id = q6audio_get_port_id(port); + ex_vi->pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; + ex_vi->pdata.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS; + ex_vi->pdata.param_size = sizeof(ex_vi->param); + atomic_set(&this_afe.status, 0); + atomic_set(&this_afe.state, 1); + ret = apr_send_pkt(this_afe.apr, (uint32_t *)ex_vi); + if (ret < 0) { + pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", + __func__, port, ex_vi->get_param.param_id, ret); + goto done; + } + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto done; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code(atomic_read(&this_afe.status)); + goto done; + } + memcpy(&ex_vi->param, &this_afe.ex_vi_resp.param, + sizeof(this_afe.ex_vi_resp.param)); + pr_debug("%s: freq %d %d resistance %d %d qfactor %d %d state %d %d\n", + __func__, ex_vi->param.freq_q20[SP_V2_SPKR_1], + ex_vi->param.freq_q20[SP_V2_SPKR_2], + ex_vi->param.resis_q24[SP_V2_SPKR_1], + ex_vi->param.resis_q24[SP_V2_SPKR_2], + ex_vi->param.qmct_q24[SP_V2_SPKR_1], + ex_vi->param.qmct_q24[SP_V2_SPKR_2], + ex_vi->param.status[SP_V2_SPKR_1], + ex_vi->param.status[SP_V2_SPKR_2]); + ret = 0; +done: + return ret; +} + +int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats, + u16 port) +{ + int ret = -EINVAL; + int index = 0; + struct afe_av_dev_drift_get_param av_dev_drift; + + if (!timing_stats) { + pr_err("%s: Invalid params\n", __func__); + goto exit; + } + + ret = q6audio_validate_port(port); + if (ret < 0) { + pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret); + ret = -EINVAL; + goto exit; + } + + index = q6audio_get_port_index(port); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: Invalid AFE port index[%d]\n", + __func__, index); + ret = -EINVAL; + goto exit; + } + + memset(&av_dev_drift, 0, sizeof(struct afe_av_dev_drift_get_param)); + + av_dev_drift.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + av_dev_drift.hdr.pkt_size = sizeof(av_dev_drift); + av_dev_drift.hdr.src_port = 0; + av_dev_drift.hdr.dest_port = 0; + av_dev_drift.hdr.token = index; + av_dev_drift.hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; + av_dev_drift.get_param.mem_map_handle = 0; + av_dev_drift.get_param.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + av_dev_drift.get_param.param_id = AFE_PARAM_ID_DEV_TIMING_STATS; + av_dev_drift.get_param.payload_address_lsw = 0; + av_dev_drift.get_param.payload_address_msw = 0; + av_dev_drift.get_param.payload_size = sizeof(av_dev_drift) + - sizeof(av_dev_drift.get_param) - sizeof(av_dev_drift.hdr); + av_dev_drift.get_param.port_id = q6audio_get_port_id(port); + av_dev_drift.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + av_dev_drift.pdata.param_id = AFE_PARAM_ID_DEV_TIMING_STATS; + av_dev_drift.pdata.param_size = sizeof(av_dev_drift.timing_stats); + atomic_set(&this_afe.status, 0); + atomic_set(&this_afe.state, 1); + ret = apr_send_pkt(this_afe.apr, (uint32_t *)&av_dev_drift); + if (ret < 0) { + pr_err("%s: get param port 0x%x param id[0x%x] failed %d\n", + __func__, port, av_dev_drift.get_param.param_id, ret); + goto exit; + } + + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto exit; + } + + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto exit; + } + + memcpy(timing_stats, &this_afe.av_dev_drift_resp.timing_stats, + sizeof(this_afe.av_dev_drift_resp.timing_stats)); + ret = 0; +exit: + return ret; +} + +int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) +{ + int ret = -EINVAL; + int index = 0, port = SLIMBUS_4_TX; + + if (!calib_resp) { + pr_err("%s: Invalid params\n", __func__); + goto fail_cmd; + } + if (this_afe.vi_tx_port != -1) + port = this_afe.vi_tx_port; + + ret = q6audio_validate_port(port); + if (ret < 0) { + pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret); + ret = -EINVAL; + goto fail_cmd; + } + index = q6audio_get_port_index(port); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + ret = -EINVAL; + goto fail_cmd; + } + calib_resp->hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + calib_resp->hdr.pkt_size = sizeof(*calib_resp); + calib_resp->hdr.src_port = 0; + calib_resp->hdr.dest_port = 0; + calib_resp->hdr.token = index; + calib_resp->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; + calib_resp->get_param.mem_map_handle = 0; + calib_resp->get_param.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2; + calib_resp->get_param.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2; + calib_resp->get_param.payload_address_lsw = 0; + calib_resp->get_param.payload_address_msw = 0; + calib_resp->get_param.payload_size = sizeof(*calib_resp) + - sizeof(calib_resp->get_param) - sizeof(calib_resp->hdr); + calib_resp->get_param.port_id = q6audio_get_port_id(port); + calib_resp->pdata.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2; + calib_resp->pdata.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2; + calib_resp->pdata.param_size = sizeof(calib_resp->res_cfg); + atomic_set(&this_afe.status, 0); + atomic_set(&this_afe.state, 1); + ret = apr_send_pkt(this_afe.apr, (uint32_t *)calib_resp); + if (ret < 0) { + pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", + __func__, port, calib_resp->get_param.param_id, ret); + goto fail_cmd; + } + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto fail_cmd; + } + memcpy(&calib_resp->res_cfg, &this_afe.calib_data.res_cfg, + sizeof(this_afe.calib_data.res_cfg)); + pr_info("%s: state %s resistance %d %d\n", __func__, + fbsp_state[calib_resp->res_cfg.th_vi_ca_state], + calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_1], + calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_2]); + ret = 0; +fail_cmd: + return ret; +} + +int afe_spk_prot_feed_back_cfg(int src_port, int dst_port, + int l_ch, int r_ch, u32 enable) +{ + int ret = -EINVAL; + union afe_spkr_prot_config prot_config; + int index = 0; + + if (!enable) { + pr_debug("%s: Disable Feedback tx path", __func__); + this_afe.vi_tx_port = -1; + this_afe.vi_rx_port = -1; + return 0; + } + + if ((q6audio_validate_port(src_port) < 0) || + (q6audio_validate_port(dst_port) < 0)) { + pr_err("%s: invalid ports src 0x%x dst 0x%x", + __func__, src_port, dst_port); + goto fail_cmd; + } + if (!l_ch && !r_ch) { + pr_err("%s: error ch values zero\n", __func__); + goto fail_cmd; + } + pr_debug("%s: src_port 0x%x dst_port 0x%x l_ch %d r_ch %d\n", + __func__, src_port, dst_port, l_ch, r_ch); + memset(&prot_config, 0, sizeof(prot_config)); + prot_config.feedback_path_cfg.dst_portid = + q6audio_get_port_id(dst_port); + if (l_ch) { + prot_config.feedback_path_cfg.chan_info[index++] = 1; + prot_config.feedback_path_cfg.chan_info[index++] = 2; + } + if (r_ch) { + prot_config.feedback_path_cfg.chan_info[index++] = 3; + prot_config.feedback_path_cfg.chan_info[index++] = 4; + } + prot_config.feedback_path_cfg.num_channels = index; + pr_debug("%s no of channels: %d\n", __func__, index); + prot_config.feedback_path_cfg.minor_version = 1; + ret = afe_spk_prot_prepare(src_port, dst_port, + AFE_PARAM_ID_FEEDBACK_PATH_CFG, &prot_config); +fail_cmd: + return ret; +} + +static int get_cal_type_index(int32_t cal_type) +{ + int ret = -EINVAL; + + switch (cal_type) { + case AFE_COMMON_RX_CAL_TYPE: + ret = AFE_COMMON_RX_CAL; + break; + case AFE_COMMON_TX_CAL_TYPE: + ret = AFE_COMMON_TX_CAL; + break; + case AFE_AANC_CAL_TYPE: + ret = AFE_AANC_CAL; + break; + case AFE_HW_DELAY_CAL_TYPE: + ret = AFE_HW_DELAY_CAL; + break; + case AFE_FB_SPKR_PROT_CAL_TYPE: + ret = AFE_FB_SPKR_PROT_CAL; + break; + case AFE_SIDETONE_CAL_TYPE: + ret = AFE_SIDETONE_CAL; + break; + case AFE_SIDETONE_IIR_CAL_TYPE: + ret = AFE_SIDETONE_IIR_CAL; + break; + case AFE_TOPOLOGY_CAL_TYPE: + ret = AFE_TOPOLOGY_CAL; + break; + case AFE_CUST_TOPOLOGY_CAL_TYPE: + ret = AFE_CUST_TOPOLOGY_CAL; + break; + default: + pr_err("%s: invalid cal type %d!\n", __func__, cal_type); + } + return ret; +} + +int afe_alloc_cal(int32_t cal_type, size_t data_size, + void *data) +{ + int ret = 0; + int cal_index; + + cal_index = get_cal_type_index(cal_type); + pr_debug("%s: cal_type = %d cal_index = %d\n", + __func__, cal_type, cal_index); + + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + ret = cal_utils_alloc_cal(data_size, data, + this_afe.cal_data[cal_index], 0, NULL); + if (ret < 0) { + pr_err("%s: cal_utils_alloc_block failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + ret = -EINVAL; + goto done; + } +done: + return ret; +} + +static int afe_dealloc_cal(int32_t cal_type, size_t data_size, + void *data) +{ + int ret = 0; + int cal_index; + + pr_debug("%s:\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + ret = cal_utils_dealloc_cal(data_size, data, + this_afe.cal_data[cal_index]); + if (ret < 0) { + pr_err("%s: cal_utils_dealloc_block failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + ret = -EINVAL; + goto done; + } +done: + return ret; +} + +static int afe_set_cal(int32_t cal_type, size_t data_size, + void *data) +{ + int ret = 0; + int cal_index; + + pr_debug("%s:\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + ret = cal_utils_set_cal(data_size, data, + this_afe.cal_data[cal_index], 0, NULL); + if (ret < 0) { + pr_err("%s: cal_utils_set_cal failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + ret = -EINVAL; + goto done; + } + + if (cal_index == AFE_CUST_TOPOLOGY_CAL) { + mutex_lock(&this_afe.cal_data[AFE_CUST_TOPOLOGY_CAL]->lock); + this_afe.set_custom_topology = 1; + pr_debug("%s:[AFE_CUSTOM_TOPOLOGY] ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + mutex_unlock(&this_afe.cal_data[AFE_CUST_TOPOLOGY_CAL]->lock); + } + +done: + return ret; +} + +static struct cal_block_data *afe_find_hw_delay_by_path( + struct cal_type_data *cal_type, int path) +{ + struct list_head *ptr, *next; + struct cal_block_data *cal_block = NULL; + + pr_debug("%s:\n", __func__); + + list_for_each_safe(ptr, next, + &cal_type->cal_blocks) { + + cal_block = list_entry(ptr, + struct cal_block_data, list); + + if (((struct audio_cal_info_hw_delay *)cal_block->cal_info) + ->path == path) { + return cal_block; + } + } + return NULL; +} + +static int afe_get_cal_hw_delay(int32_t path, + struct audio_cal_hw_delay_entry *entry) +{ + int ret = 0; + int i; + struct cal_block_data *cal_block = NULL; + struct audio_cal_hw_delay_data *hw_delay_info = NULL; + + pr_debug("%s:\n", __func__); + + if (this_afe.cal_data[AFE_HW_DELAY_CAL] == NULL) { + pr_err("%s: AFE_HW_DELAY_CAL not initialized\n", __func__); + ret = -EINVAL; + goto done; + } + if (entry == NULL) { + pr_err("%s: entry is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + if ((path >= MAX_PATH_TYPE) || (path < 0)) { + pr_err("%s: bad path: %d\n", + __func__, path); + ret = -EINVAL; + goto done; + } + + mutex_lock(&this_afe.cal_data[AFE_HW_DELAY_CAL]->lock); + cal_block = afe_find_hw_delay_by_path( + this_afe.cal_data[AFE_HW_DELAY_CAL], path); + if (cal_block == NULL) + goto unlock; + + hw_delay_info = &((struct audio_cal_info_hw_delay *) + cal_block->cal_info)->data; + if (hw_delay_info->num_entries > MAX_HW_DELAY_ENTRIES) { + pr_err("%s: invalid num entries: %d\n", + __func__, hw_delay_info->num_entries); + ret = -EINVAL; + goto unlock; + } + + for (i = 0; i < hw_delay_info->num_entries; i++) { + if (hw_delay_info->entry[i].sample_rate == + entry->sample_rate) { + entry->delay_usec = hw_delay_info->entry[i].delay_usec; + break; + } + } + if (i == hw_delay_info->num_entries) { + pr_err("%s: Unable to find delay for sample rate %d\n", + __func__, entry->sample_rate); + ret = -EFAULT; + goto unlock; + } + pr_debug("%s: Path = %d samplerate = %u usec = %u status %d\n", + __func__, path, entry->sample_rate, entry->delay_usec, ret); +unlock: + mutex_unlock(&this_afe.cal_data[AFE_HW_DELAY_CAL]->lock); +done: + return ret; +} + +static int afe_set_cal_sp_th_vi_ftm_cfg(int32_t cal_type, size_t data_size, + void *data) +{ + int ret = 0; + struct audio_cal_type_sp_th_vi_ftm_cfg *cal_data = data; + + if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL || + cal_data == NULL || + data_size != sizeof(*cal_data)) + goto done; + + pr_debug("%s: cal_type = %d\n", __func__, cal_type); + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + memcpy(&this_afe.th_ftm_cfg, &cal_data->cal_info, + sizeof(this_afe.th_ftm_cfg)); + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); +done: + return ret; +} + +static int afe_set_cal_sp_ex_vi_ftm_cfg(int32_t cal_type, size_t data_size, + void *data) +{ + int ret = 0; + struct audio_cal_type_sp_ex_vi_ftm_cfg *cal_data = data; + + if (this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL || + cal_data == NULL || + data_size != sizeof(*cal_data)) + goto done; + + pr_debug("%s: cal_type = %d\n", __func__, cal_type); + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); + memcpy(&this_afe.ex_ftm_cfg, &cal_data->cal_info, + sizeof(this_afe.ex_ftm_cfg)); + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); +done: + return ret; +} + +static int afe_set_cal_fb_spkr_prot(int32_t cal_type, size_t data_size, + void *data) +{ + int ret = 0; + struct audio_cal_type_fb_spk_prot_cfg *cal_data = data; + + pr_debug("%s:\n", __func__); + + if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL) + goto done; + if (cal_data == NULL) + goto done; + if (data_size != sizeof(*cal_data)) + goto done; + + if (cal_data->cal_info.mode == MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) + __pm_wakeup_event(&wl.ws, jiffies_to_msecs(WAKELOCK_TIMEOUT)); + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); + memcpy(&this_afe.prot_cfg, &cal_data->cal_info, + sizeof(this_afe.prot_cfg)); + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); +done: + return ret; +} + +static int afe_get_cal_sp_th_vi_ftm_param(int32_t cal_type, size_t data_size, + void *data) +{ + int i, ret = 0; + struct audio_cal_type_sp_th_vi_param *cal_data = data; + struct afe_sp_th_vi_get_param th_vi; + + pr_debug("%s: cal_type = %d\n", __func__, cal_type); + if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL || + cal_data == NULL || + data_size != sizeof(*cal_data)) + goto done; + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + cal_data->cal_info.status[i] = -EINVAL; + cal_data->cal_info.r_dc_q24[i] = -1; + cal_data->cal_info.temp_q22[i] = -1; + } + if (!afe_get_sp_th_vi_ftm_data(&th_vi)) { + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + pr_debug("%s: ftm param status = %d\n", + __func__, th_vi.param.status[i]); + if (th_vi.param.status[i] == FBSP_IN_PROGRESS) { + cal_data->cal_info.status[i] = -EAGAIN; + } else if (th_vi.param.status[i] == FBSP_SUCCESS) { + cal_data->cal_info.status[i] = 0; + cal_data->cal_info.r_dc_q24[i] = + th_vi.param.dc_res_q24[i]; + cal_data->cal_info.temp_q22[i] = + th_vi.param.temp_q22[i]; + } + } + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); +done: + return ret; +} + +static int afe_get_cal_sp_ex_vi_ftm_param(int32_t cal_type, size_t data_size, + void *data) +{ + int i, ret = 0; + struct audio_cal_type_sp_ex_vi_param *cal_data = data; + struct afe_sp_ex_vi_get_param ex_vi; + + pr_debug("%s: cal_type = %d\n", __func__, cal_type); + if (this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL || + cal_data == NULL || + data_size != sizeof(*cal_data)) + goto done; + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + cal_data->cal_info.status[i] = -EINVAL; + cal_data->cal_info.freq_q20[i] = -1; + cal_data->cal_info.resis_q24[i] = -1; + cal_data->cal_info.qmct_q24[i] = -1; + } + if (!afe_get_sp_ex_vi_ftm_data(&ex_vi)) { + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + pr_debug("%s: ftm param status = %d\n", + __func__, ex_vi.param.status[i]); + if (ex_vi.param.status[i] == FBSP_IN_PROGRESS) { + cal_data->cal_info.status[i] = -EAGAIN; + } else if (ex_vi.param.status[i] == FBSP_SUCCESS) { + cal_data->cal_info.status[i] = 0; + cal_data->cal_info.freq_q20[i] = + ex_vi.param.freq_q20[i]; + cal_data->cal_info.resis_q24[i] = + ex_vi.param.resis_q24[i]; + cal_data->cal_info.qmct_q24[i] = + ex_vi.param.qmct_q24[i]; + } + } + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); +done: + return ret; +} + +static int afe_get_cal_fb_spkr_prot(int32_t cal_type, size_t data_size, + void *data) +{ + int ret = 0; + struct audio_cal_type_fb_spk_prot_status *cal_data = data; + struct afe_spkr_prot_get_vi_calib calib_resp; + + pr_debug("%s:\n", __func__); + + if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL) + goto done; + if (cal_data == NULL) + goto done; + if (data_size != sizeof(*cal_data)) + goto done; + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); + if (this_afe.prot_cfg.mode == MSM_SPKR_PROT_CALIBRATED) { + cal_data->cal_info.r0[SP_V2_SPKR_1] = + this_afe.prot_cfg.r0[SP_V2_SPKR_1]; + cal_data->cal_info.r0[SP_V2_SPKR_2] = + this_afe.prot_cfg.r0[SP_V2_SPKR_2]; + cal_data->cal_info.status = 0; + } else if (this_afe.prot_cfg.mode == + MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) { + /*Call AFE to query the status*/ + cal_data->cal_info.status = -EINVAL; + cal_data->cal_info.r0[SP_V2_SPKR_1] = -1; + cal_data->cal_info.r0[SP_V2_SPKR_2] = -1; + if (!afe_spk_prot_get_calib_data(&calib_resp)) { + if (calib_resp.res_cfg.th_vi_ca_state == + FBSP_IN_PROGRESS) + cal_data->cal_info.status = -EAGAIN; + else if (calib_resp.res_cfg.th_vi_ca_state == + FBSP_SUCCESS) { + cal_data->cal_info.status = 0; + cal_data->cal_info.r0[SP_V2_SPKR_1] = + calib_resp.res_cfg.r0_cali_q24[SP_V2_SPKR_1]; + cal_data->cal_info.r0[SP_V2_SPKR_2] = + calib_resp.res_cfg.r0_cali_q24[SP_V2_SPKR_2]; + } + } + if (!cal_data->cal_info.status) { + this_afe.prot_cfg.mode = + MSM_SPKR_PROT_CALIBRATED; + this_afe.prot_cfg.r0[SP_V2_SPKR_1] = + cal_data->cal_info.r0[SP_V2_SPKR_1]; + this_afe.prot_cfg.r0[SP_V2_SPKR_2] = + cal_data->cal_info.r0[SP_V2_SPKR_2]; + } + } else { + /*Indicates calibration data is invalid*/ + cal_data->cal_info.status = -EINVAL; + cal_data->cal_info.r0[SP_V2_SPKR_1] = -1; + cal_data->cal_info.r0[SP_V2_SPKR_2] = -1; + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); + __pm_relax(&wl.ws); +done: + return ret; +} + +static int afe_map_cal_data(int32_t cal_type, + struct cal_block_data *cal_block) +{ + int ret = 0; + int cal_index; + + pr_debug("%s:\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + + mutex_lock(&this_afe.afe_cmd_lock); + atomic_set(&this_afe.mem_map_cal_index, cal_index); + ret = afe_cmd_memory_map(cal_block->cal_data.paddr, + cal_block->map_data.map_size); + atomic_set(&this_afe.mem_map_cal_index, -1); + if (ret < 0) { + pr_err("%s: mmap did not work! size = %zd ret %d\n", + __func__, + cal_block->map_data.map_size, ret); + pr_debug("%s: mmap did not work! addr = 0x%pK, size = %zd\n", + __func__, + &cal_block->cal_data.paddr, + cal_block->map_data.map_size); + mutex_unlock(&this_afe.afe_cmd_lock); + goto done; + } + cal_block->map_data.q6map_handle = atomic_read(&this_afe. + mem_map_cal_handles[cal_index]); + mutex_unlock(&this_afe.afe_cmd_lock); +done: + return ret; +} + +static int afe_unmap_cal_data(int32_t cal_type, + struct cal_block_data *cal_block) +{ + int ret = 0; + int cal_index; + + pr_debug("%s:\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + if (cal_block == NULL) { + pr_err("%s: Cal block is NULL!\n", + __func__); + goto done; + } + + if (cal_block->map_data.q6map_handle == 0) { + pr_err("%s: Map handle is NULL, nothing to unmap\n", + __func__); + goto done; + } + + atomic_set(&this_afe.mem_map_cal_handles[cal_index], + cal_block->map_data.q6map_handle); + atomic_set(&this_afe.mem_map_cal_index, cal_index); + ret = afe_cmd_memory_unmap_nowait( + cal_block->map_data.q6map_handle); + atomic_set(&this_afe.mem_map_cal_index, -1); + if (ret < 0) { + pr_err("%s: unmap did not work! cal_type %i ret %d\n", + __func__, cal_index, ret); + } + cal_block->map_data.q6map_handle = 0; +done: + return ret; +} + +static void afe_delete_cal_data(void) +{ + pr_debug("%s:\n", __func__); + + cal_utils_destroy_cal_types(MAX_AFE_CAL_TYPES, this_afe.cal_data); +} + +static int afe_init_cal_data(void) +{ + int ret = 0; + struct cal_type_info cal_type_info[] = { + {{AFE_COMMON_RX_CAL_TYPE, + {afe_alloc_cal, afe_dealloc_cal, NULL, + afe_set_cal, NULL, NULL} }, + {afe_map_cal_data, afe_unmap_cal_data, + cal_utils_match_buf_num} }, + + {{AFE_COMMON_TX_CAL_TYPE, + {afe_alloc_cal, afe_dealloc_cal, NULL, + afe_set_cal, NULL, NULL} }, + {afe_map_cal_data, afe_unmap_cal_data, + cal_utils_match_buf_num} }, + + {{AFE_AANC_CAL_TYPE, + {afe_alloc_cal, afe_dealloc_cal, NULL, + afe_set_cal, NULL, NULL} }, + {afe_map_cal_data, afe_unmap_cal_data, + cal_utils_match_buf_num} }, + + {{AFE_FB_SPKR_PROT_CAL_TYPE, + {NULL, NULL, NULL, afe_set_cal_fb_spkr_prot, + afe_get_cal_fb_spkr_prot, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{AFE_HW_DELAY_CAL_TYPE, + {NULL, NULL, NULL, + afe_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{AFE_SIDETONE_CAL_TYPE, + {NULL, NULL, NULL, + afe_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{AFE_SIDETONE_IIR_CAL_TYPE, + {NULL, NULL, NULL, + afe_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{AFE_TOPOLOGY_CAL_TYPE, + {NULL, NULL, NULL, + afe_set_cal, NULL, NULL} }, + {NULL, NULL, + cal_utils_match_buf_num} }, + + {{AFE_CUST_TOPOLOGY_CAL_TYPE, + {afe_alloc_cal, afe_dealloc_cal, NULL, + afe_set_cal, NULL, NULL} }, + {afe_map_cal_data, afe_unmap_cal_data, + cal_utils_match_buf_num} }, + + {{AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE, + {NULL, NULL, NULL, afe_set_cal_sp_th_vi_ftm_cfg, + afe_get_cal_sp_th_vi_ftm_param, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE, + {NULL, NULL, NULL, afe_set_cal_sp_ex_vi_ftm_cfg, + afe_get_cal_sp_ex_vi_ftm_param, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + }; + pr_debug("%s:\n", __func__); + + ret = cal_utils_create_cal_types(MAX_AFE_CAL_TYPES, this_afe.cal_data, + cal_type_info); + if (ret < 0) { + pr_err("%s: could not create cal type! %d\n", + __func__, ret); + ret = -EINVAL; + goto err; + } + + return ret; +err: + afe_delete_cal_data(); + return ret; +} + +int afe_map_rtac_block(struct rtac_cal_block_data *cal_block) +{ + int result = 0; + + pr_debug("%s:\n", __func__); + + if (cal_block == NULL) { + pr_err("%s: cal_block is NULL!\n", + __func__); + result = -EINVAL; + goto done; + } + + if (cal_block->cal_data.paddr == 0) { + pr_debug("%s: No address to map!\n", + __func__); + result = -EINVAL; + goto done; + } + + if (cal_block->map_data.map_size == 0) { + pr_debug("%s: map size is 0!\n", + __func__); + result = -EINVAL; + goto done; + } + + result = afe_cmd_memory_map(cal_block->cal_data.paddr, + cal_block->map_data.map_size); + if (result < 0) { + pr_err("%s: afe_cmd_memory_map failed for addr = 0x%pK, size = %d, err %d\n", + __func__, &cal_block->cal_data.paddr, + cal_block->map_data.map_size, result); + return result; + } + cal_block->map_data.map_handle = this_afe.mmap_handle; + +done: + return result; +} + +int afe_unmap_rtac_block(uint32_t *mem_map_handle) +{ + int result = 0; + + pr_debug("%s:\n", __func__); + + if (mem_map_handle == NULL) { + pr_err("%s: Map handle is NULL, nothing to unmap\n", + __func__); + goto done; + } + + if (*mem_map_handle == 0) { + pr_debug("%s: Map handle is 0, nothing to unmap\n", + __func__); + goto done; + } + + result = afe_cmd_memory_unmap(*mem_map_handle); + if (result) { + pr_err("%s: AFE memory unmap failed %d, handle 0x%x\n", + __func__, result, *mem_map_handle); + goto done; + } else { + *mem_map_handle = 0; + } + +done: + return result; +} + +static int __init afe_init(void) +{ + int i = 0, ret; + + atomic_set(&this_afe.state, 0); + atomic_set(&this_afe.status, 0); + atomic_set(&this_afe.mem_map_cal_index, -1); + this_afe.apr = NULL; + this_afe.dtmf_gen_rx_portid = -1; + this_afe.mmap_handle = 0; + this_afe.vi_tx_port = -1; + this_afe.vi_rx_port = -1; + this_afe.prot_cfg.mode = MSM_SPKR_PROT_DISABLED; + this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; + this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; + mutex_init(&this_afe.afe_cmd_lock); + for (i = 0; i < AFE_MAX_PORTS; i++) { + this_afe.afe_cal_mode[i] = AFE_CAL_MODE_DEFAULT; + this_afe.afe_sample_rates[i] = 0; + this_afe.dev_acdb_id[i] = 0; + init_waitqueue_head(&this_afe.wait[i]); + } + wakeup_source_init(&wl.ws, "spkr-prot"); + ret = afe_init_cal_data(); + if (ret) + pr_err("%s: could not init cal data! %d\n", __func__, ret); + + config_debug_fs_init(); + return 0; +} + +static void __exit afe_exit(void) +{ + afe_delete_cal_data(); + + config_debug_fs_exit(); + mutex_destroy(&this_afe.afe_cmd_lock); + wakeup_source_trash(&wl.ws); +} + +device_initcall(afe_init); +__exitcall(afe_exit); diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c new file mode 100644 index 000000000000..e7e161849ff5 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -0,0 +1,9396 @@ +/* + * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * Author: Brian Swetland + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define TRUE 0x01 +#define FALSE 0x00 +#define SESSION_MAX 8 + +enum { + ASM_TOPOLOGY_CAL = 0, + ASM_CUSTOM_TOP_CAL, + ASM_AUDSTRM_CAL, + ASM_RTAC_APR_CAL, + ASM_MAX_CAL_TYPES +}; + +union asm_token_struct { + struct { + u8 stream_id; + u8 session_id; + u8 buf_index; + u8 flags; + } _token; + u32 token; +} __packed; + + +enum { + ASM_DIRECTION_OFFSET, + ASM_CMD_NO_WAIT_OFFSET, + /* + * Offset is limited to 7 because flags is stored in u8 + * field in asm_token_structure defined above. The offset + * starts from 0. + */ + ASM_MAX_OFFSET = 7, +}; + +enum { + WAIT_CMD, + NO_WAIT_CMD +}; + +#define ASM_SET_BIT(n, x) (n |= 1 << x) +#define ASM_TEST_BIT(n, x) ((n >> x) & 1) + +/* TODO, combine them together */ +static DEFINE_MUTEX(session_lock); +struct asm_mmap { + atomic_t ref_cnt; + void *apr; +}; + +static struct asm_mmap this_mmap; +/* session id: 0 reserved */ +static struct audio_client *session[ASM_ACTIVE_STREAMS_ALLOWED + 1]; + +struct asm_buffer_node { + struct list_head list; + phys_addr_t buf_phys_addr; + uint32_t mmap_hdl; +}; +static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv); +static int32_t q6asm_callback(struct apr_client_data *data, void *priv); +static void q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr, + uint32_t pkt_size, uint32_t cmd_flg); +static void q6asm_add_hdr_custom_topology(struct audio_client *ac, + struct apr_hdr *hdr, + uint32_t pkt_size); +static void q6asm_add_hdr_async(struct audio_client *ac, struct apr_hdr *hdr, + uint32_t pkt_size, uint32_t cmd_flg); +static int q6asm_memory_map_regions(struct audio_client *ac, int dir, + uint32_t bufsz, uint32_t bufcnt, + bool is_contiguous); +static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir); +static void q6asm_reset_buf_state(struct audio_client *ac); + +static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, + bool use_back_flavor); +void *q6asm_mmap_apr_reg(void); + +static int q6asm_is_valid_session(struct apr_client_data *data, void *priv); +static int q6asm_get_asm_topology_cal(void); +static int q6asm_get_asm_app_type_cal(void); + +/* for ASM custom topology */ +static struct cal_type_data *cal_data[ASM_MAX_CAL_TYPES]; +static struct audio_buffer common_buf[2]; +static struct audio_client common_client; +static int set_custom_topology; +static int topology_map_handle; + +struct generic_get_data_ { + int valid; + int is_inband; + int size_in_ints; + int ints[]; +}; +static struct generic_get_data_ *generic_get_data; + +#ifdef CONFIG_DEBUG_FS +#define OUT_BUFFER_SIZE 56 +#define IN_BUFFER_SIZE 24 + +static struct timeval out_cold_tv; +static struct timeval out_warm_tv; +static struct timeval out_cont_tv; +static struct timeval in_cont_tv; +static long out_enable_flag; +static long in_enable_flag; +static struct dentry *out_dentry; +static struct dentry *in_dentry; +static int in_cont_index; +/*This var is used to keep track of first write done for cold output latency */ +static int out_cold_index; +static char *out_buffer; +static char *in_buffer; + +static uint32_t adsp_reg_event_opcode[] = { + ASM_STREAM_CMD_REGISTER_PP_EVENTS, + ASM_STREAM_CMD_REGISTER_ENCDEC_EVENTS, + ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE }; + +static uint32_t adsp_raise_event_opcode[] = { + ASM_STREAM_PP_EVENT, + ASM_STREAM_CMD_ENCDEC_EVENTS, + ASM_IEC_61937_MEDIA_FMT_EVENT }; + +static int is_adsp_reg_event(uint32_t cmd) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(adsp_reg_event_opcode); i++) { + if (cmd == adsp_reg_event_opcode[i]) + return i; + } + return -EINVAL; +} + +static int is_adsp_raise_event(uint32_t cmd) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(adsp_raise_event_opcode); i++) { + if (cmd == adsp_raise_event_opcode[i]) + return i; + } + return -EINVAL; +} + +static inline void q6asm_set_flag_in_token(union asm_token_struct *asm_token, + int flag, int flag_offset) +{ + if (flag) + ASM_SET_BIT(asm_token->_token.flags, flag_offset); +} + +static inline int q6asm_get_flag_from_token(union asm_token_struct *asm_token, + int flag_offset) +{ + return ASM_TEST_BIT(asm_token->_token.flags, flag_offset); +} + +static inline void q6asm_update_token(u32 *token, u8 session_id, u8 stream_id, + u8 buf_index, u8 dir, u8 nowait_flag) +{ + union asm_token_struct asm_token; + + asm_token.token = 0; + asm_token._token.session_id = session_id; + asm_token._token.stream_id = stream_id; + asm_token._token.buf_index = buf_index; + q6asm_set_flag_in_token(&asm_token, dir, ASM_DIRECTION_OFFSET); + q6asm_set_flag_in_token(&asm_token, nowait_flag, + ASM_CMD_NO_WAIT_OFFSET); + *token = asm_token.token; +} + +static inline uint32_t q6asm_get_pcm_format_id(uint32_t media_format_block_ver) +{ + uint32_t pcm_format_id; + + switch (media_format_block_ver) { + case PCM_MEDIA_FORMAT_V4: + pcm_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V4; + break; + case PCM_MEDIA_FORMAT_V3: + pcm_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3; + break; + case PCM_MEDIA_FORMAT_V2: + default: + pcm_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2; + break; + } + return pcm_format_id; +} + +/* + * q6asm_get_buf_index_from_token: + * Retrieve buffer index from token. + * + * @token: token value sent to ASM service on q6. + * Returns buffer index in the read/write commands. + */ +uint8_t q6asm_get_buf_index_from_token(uint32_t token) +{ + union asm_token_struct asm_token; + + asm_token.token = token; + return asm_token._token.buf_index; +} +EXPORT_SYMBOL(q6asm_get_buf_index_from_token); + +/* + * q6asm_get_stream_id_from_token: + * Retrieve stream id from token. + * + * @token: token value sent to ASM service on q6. + * Returns stream id. + */ +uint8_t q6asm_get_stream_id_from_token(uint32_t token) +{ + union asm_token_struct asm_token; + + asm_token.token = token; + return asm_token._token.stream_id; +} +EXPORT_SYMBOL(q6asm_get_stream_id_from_token); + +static int audio_output_latency_dbgfs_open(struct inode *inode, + struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} +static ssize_t audio_output_latency_dbgfs_read(struct file *file, + char __user *buf, size_t count, loff_t *ppos) +{ + if (out_buffer == NULL) { + pr_err("%s: out_buffer is null\n", __func__); + return 0; + } + snprintf(out_buffer, OUT_BUFFER_SIZE, "%ld,%ld,%ld,%ld,%ld,%ld,", + out_cold_tv.tv_sec, out_cold_tv.tv_usec, out_warm_tv.tv_sec, + out_warm_tv.tv_usec, out_cont_tv.tv_sec, out_cont_tv.tv_usec); + return simple_read_from_buffer(buf, OUT_BUFFER_SIZE, ppos, + out_buffer, OUT_BUFFER_SIZE); +} +static ssize_t audio_output_latency_dbgfs_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + char *temp; + + if (count > 2*sizeof(char)) { + pr_err("%s: err count is more %zd\n", __func__, count); + return -EINVAL; + } + temp = kmalloc(2*sizeof(char), GFP_KERNEL); + + out_cold_index = 0; + + if (temp) { + if (copy_from_user(temp, buf, 2*sizeof(char))) { + pr_err("%s: copy from user failed for size %zd\n", + __func__, 2*sizeof(char)); + kfree(temp); + return -EFAULT; + } + if (!kstrtol(temp, 10, &out_enable_flag)) { + kfree(temp); + return count; + } + kfree(temp); + } + return -EINVAL; +} +static const struct file_operations audio_output_latency_debug_fops = { + .open = audio_output_latency_dbgfs_open, + .read = audio_output_latency_dbgfs_read, + .write = audio_output_latency_dbgfs_write +}; +static int audio_input_latency_dbgfs_open(struct inode *inode, + struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} +static ssize_t audio_input_latency_dbgfs_read(struct file *file, + char __user *buf, size_t count, loff_t *ppos) +{ + if (in_buffer == NULL) { + pr_err("%s: in_buffer is null\n", __func__); + return 0; + } + snprintf(in_buffer, IN_BUFFER_SIZE, "%ld,%ld,", + in_cont_tv.tv_sec, in_cont_tv.tv_usec); + return simple_read_from_buffer(buf, IN_BUFFER_SIZE, ppos, + in_buffer, IN_BUFFER_SIZE); +} +static ssize_t audio_input_latency_dbgfs_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + char *temp; + + if (count > 2*sizeof(char)) { + pr_err("%s: err count is more %zd\n", __func__, count); + return -EINVAL; + } + temp = kmalloc(2*sizeof(char), GFP_KERNEL); + + if (temp) { + if (copy_from_user(temp, buf, 2*sizeof(char))) { + pr_err("%s: copy from user failed for size %zd\n", + __func__, 2*sizeof(char)); + kfree(temp); + return -EFAULT; + } + if (!kstrtol(temp, 10, &in_enable_flag)) { + kfree(temp); + return count; + } + kfree(temp); + } + return -EINVAL; +} +static const struct file_operations audio_input_latency_debug_fops = { + .open = audio_input_latency_dbgfs_open, + .read = audio_input_latency_dbgfs_read, + .write = audio_input_latency_dbgfs_write +}; + +static void config_debug_fs_write_cb(void) +{ + if (out_enable_flag) { + /* For first Write done log the time and reset + * out_cold_index + */ + if (out_cold_index != 1) { + do_gettimeofday(&out_cold_tv); + pr_debug("COLD: apr_send_pkt at %ld sec %ld microsec\n", + out_cold_tv.tv_sec, + out_cold_tv.tv_usec); + out_cold_index = 1; + } + pr_debug("%s: out_enable_flag %ld\n", + __func__, out_enable_flag); + } +} +static void config_debug_fs_read_cb(void) +{ + if (in_enable_flag) { + /* when in_cont_index == 7, DSP would be + * writing into the 8th 512 byte buffer and this + * timestamp is tapped here.Once done it then writes + * to 9th 512 byte buffer.These two buffers(8th, 9th) + * reach the test application in 5th iteration and that + * timestamp is tapped at user level. The difference + * of these two timestamps gives us the time between + * the time at which dsp started filling the sample + * required and when it reached the test application. + * Hence continuous input latency + */ + if (in_cont_index == 7) { + do_gettimeofday(&in_cont_tv); + pr_info("%s: read buffer at %ld sec %ld microsec\n", + __func__, + in_cont_tv.tv_sec, in_cont_tv.tv_usec); + } + in_cont_index++; + } +} + +static void config_debug_fs_reset_index(void) +{ + in_cont_index = 0; +} + +static void config_debug_fs_run(void) +{ + if (out_enable_flag) { + do_gettimeofday(&out_cold_tv); + pr_debug("%s: COLD apr_send_pkt at %ld sec %ld microsec\n", + __func__, out_cold_tv.tv_sec, out_cold_tv.tv_usec); + } +} + +static void config_debug_fs_write(struct audio_buffer *ab) +{ + if (out_enable_flag) { + char zero_pattern[2] = {0x00, 0x00}; + /* If First two byte is non zero and last two byte + * is zero then it is warm output pattern + */ + if ((strcmp(((char *)ab->data), zero_pattern)) && + (!strcmp(((char *)ab->data + 2), zero_pattern))) { + do_gettimeofday(&out_warm_tv); + pr_debug("%s: WARM:apr_send_pkt at %ld sec %ld microsec\n", + __func__, + out_warm_tv.tv_sec, + out_warm_tv.tv_usec); + pr_debug("%s: Warm Pattern Matched\n", __func__); + } + /* If First two byte is zero and last two byte is + * non zero then it is cont output pattern + */ + else if ((!strcmp(((char *)ab->data), zero_pattern)) + && (strcmp(((char *)ab->data + 2), zero_pattern))) { + do_gettimeofday(&out_cont_tv); + pr_debug("%s: CONT:apr_send_pkt at %ld sec %ld microsec\n", + __func__, + out_cont_tv.tv_sec, + out_cont_tv.tv_usec); + pr_debug("%s: Cont Pattern Matched\n", __func__); + } + } +} +static void config_debug_fs_init(void) +{ + out_buffer = kzalloc(OUT_BUFFER_SIZE, GFP_KERNEL); + if (out_buffer == NULL) + goto outbuf_fail; + + in_buffer = kzalloc(IN_BUFFER_SIZE, GFP_KERNEL); + if (in_buffer == NULL) + goto inbuf_fail; + + out_dentry = debugfs_create_file("audio_out_latency_measurement_node", + 0664, + NULL, NULL, &audio_output_latency_debug_fops); + if (IS_ERR(out_dentry)) { + pr_err("%s: debugfs_create_file failed\n", __func__); + goto file_fail; + } + in_dentry = debugfs_create_file("audio_in_latency_measurement_node", + 0664, + NULL, NULL, &audio_input_latency_debug_fops); + if (IS_ERR(in_dentry)) { + pr_err("%s: debugfs_create_file failed\n", __func__); + goto file_fail; + } + return; +file_fail: + kfree(in_buffer); +inbuf_fail: + kfree(out_buffer); +outbuf_fail: + in_buffer = NULL; + out_buffer = NULL; +} +#else +static void config_debug_fs_write(struct audio_buffer *ab) +{ +} +static void config_debug_fs_run(void) +{ +} +static void config_debug_fs_reset_index(void) +{ +} +static void config_debug_fs_read_cb(void) +{ +} +static void config_debug_fs_write_cb(void) +{ +} +static void config_debug_fs_init(void) +{ +} +#endif + +int q6asm_mmap_apr_dereg(void) +{ + int c; + + c = atomic_sub_return(1, &this_mmap.ref_cnt); + if (c == 0) { + apr_deregister(this_mmap.apr); + common_client.mmap_apr = NULL; + pr_debug("%s: APR De-Register common port\n", __func__); + } else if (c < 0) { + pr_err("%s: APR Common Port Already Closed %d\n", + __func__, c); + atomic_set(&this_mmap.ref_cnt, 0); + } + + return 0; +} + +static int q6asm_session_alloc(struct audio_client *ac) +{ + int n; + + for (n = 1; n <= ASM_ACTIVE_STREAMS_ALLOWED; n++) { + if (!session[n]) { + session[n] = ac; + return n; + } + } + pr_err("%s: session not available\n", __func__); + return -ENOMEM; +} + +static bool q6asm_is_valid_audio_client(struct audio_client *ac) +{ + int n; + + for (n = 1; n <= ASM_ACTIVE_STREAMS_ALLOWED; n++) { + if (session[n] == ac) + return 1; + } + return 0; +} + +static void q6asm_session_free(struct audio_client *ac) +{ + pr_debug("%s: sessionid[%d]\n", __func__, ac->session); + rtac_remove_popp_from_adm_devices(ac->session); + session[ac->session] = 0; + ac->session = 0; + ac->perf_mode = LEGACY_PCM_MODE; + ac->fptr_cache_ops = NULL; +} + +static uint32_t q6asm_get_next_buf(struct audio_client *ac, + uint32_t curr_buf, uint32_t max_buf_cnt) +{ + dev_vdbg(ac->dev, "%s: curr_buf = %d, max_buf_cnt = %d\n", + __func__, curr_buf, max_buf_cnt); + curr_buf += 1; + return (curr_buf >= max_buf_cnt) ? 0 : curr_buf; +} + +static int q6asm_map_cal_memory(int32_t cal_type, + struct cal_block_data *cal_block) +{ + int result = 0; + struct asm_buffer_node *buf_node = NULL; + struct list_head *ptr, *next; + + if (cal_block == NULL) { + pr_err("%s: cal_block is NULL!\n", + __func__); + goto done; + } + + if (cal_block->cal_data.paddr == 0) { + pr_debug("%s: No address to map!\n", + __func__); + goto done; + } + + common_client.mmap_apr = q6asm_mmap_apr_reg(); + if (common_client.mmap_apr == NULL) { + pr_err("%s: q6asm_mmap_apr_reg failed\n", + __func__); + result = -EPERM; + goto done; + } + common_client.apr = common_client.mmap_apr; + if (cal_block->map_data.map_size == 0) { + pr_debug("%s: map size is 0!\n", + __func__); + goto done; + } + + /* Use second asm buf to map memory */ + if (common_client.port[IN].buf == NULL) { + pr_err("%s: common buf is NULL\n", + __func__); + result = -EINVAL; + goto done; + } + + common_client.port[IN].buf->phys = cal_block->cal_data.paddr; + + result = q6asm_memory_map_regions(&common_client, + IN, cal_block->map_data.map_size, 1, 1); + if (result < 0) { + pr_err("%s: mmap did not work! size = %zd result %d\n", + __func__, + cal_block->map_data.map_size, result); + pr_debug("%s: mmap did not work! addr = 0x%pK, size = %zd\n", + __func__, + &cal_block->cal_data.paddr, + cal_block->map_data.map_size); + goto done; + } + + list_for_each_safe(ptr, next, + &common_client.port[IN].mem_map_handle) { + buf_node = list_entry(ptr, struct asm_buffer_node, + list); + if (buf_node->buf_phys_addr == cal_block->cal_data.paddr) { + cal_block->map_data.q6map_handle = buf_node->mmap_hdl; + break; + } + } +done: + return result; +} + +static int remap_cal_data(int32_t cal_type, struct cal_block_data *cal_block) +{ + int ret = 0; + + if (cal_block->map_data.ion_client == NULL) { + pr_err("%s: No ION allocation for cal type %d!\n", + __func__, cal_type); + ret = -EINVAL; + goto done; + } + + if ((cal_block->map_data.map_size > 0) && + (cal_block->map_data.q6map_handle == 0)) { + + ret = q6asm_map_cal_memory(cal_type, cal_block); + if (ret < 0) { + pr_err("%s: mmap did not work! size = %zd ret %d\n", + __func__, cal_block->map_data.map_size, ret); + goto done; + } + } +done: + return ret; +} + +static int q6asm_unmap_cal_memory(int32_t cal_type, + struct cal_block_data *cal_block) +{ + int result = 0; + int result2 = 0; + + if (cal_block == NULL) { + pr_err("%s: cal_block is NULL!\n", + __func__); + result = -EINVAL; + goto done; + } + + if (cal_block->map_data.q6map_handle == 0) { + pr_debug("%s: No address to unmap!\n", + __func__); + result = -EINVAL; + goto done; + } + + if (common_client.mmap_apr == NULL) { + common_client.mmap_apr = q6asm_mmap_apr_reg(); + if (common_client.mmap_apr == NULL) { + pr_err("%s: q6asm_mmap_apr_reg failed\n", + __func__); + result = -EPERM; + goto done; + } + } + + result2 = q6asm_memory_unmap_regions(&common_client, IN); + if (result2 < 0) { + pr_err("%s: unmap failed, err %d\n", + __func__, result2); + result = result2; + } + + cal_block->map_data.q6map_handle = 0; +done: + return result; +} + +int q6asm_unmap_cal_data(int cal_type, struct cal_block_data *cal_block) +{ + int ret = 0; + + if ((cal_block->map_data.map_size > 0) && + (cal_block->map_data.q6map_handle != 0)) { + + ret = q6asm_unmap_cal_memory(cal_type, cal_block); + if (ret < 0) { + pr_err("%s: unmap did not work! size = %zd ret %d\n", + __func__, cal_block->map_data.map_size, ret); + goto done; + } + } +done: + return ret; +} + +int send_asm_custom_topology(struct audio_client *ac) +{ + struct cal_block_data *cal_block = NULL; + struct cmd_set_topologies asm_top; + int result = 0; + int result1 = 0; + + if (cal_data[ASM_CUSTOM_TOP_CAL] == NULL) + goto done; + + mutex_lock(&cal_data[ASM_CUSTOM_TOP_CAL]->lock); + if (!set_custom_topology) + goto unlock; + set_custom_topology = 0; + + cal_block = cal_utils_get_only_cal_block(cal_data[ASM_CUSTOM_TOP_CAL]); + if (cal_block == NULL) + goto unlock; + + if (cal_block->cal_data.size == 0) { + pr_debug("%s: No cal to send!\n", __func__); + goto unlock; + } + + pr_debug("%s: Sending cal_index %d\n", __func__, ASM_CUSTOM_TOP_CAL); + + result = remap_cal_data(ASM_CUST_TOPOLOGY_CAL_TYPE, cal_block); + if (result) { + pr_err("%s: Remap_cal_data failed for cal %d!\n", + __func__, ASM_CUSTOM_TOP_CAL); + goto unlock; + } + + q6asm_add_hdr_custom_topology(ac, &asm_top.hdr, sizeof(asm_top)); + atomic_set(&ac->mem_state, -1); + asm_top.hdr.opcode = ASM_CMD_ADD_TOPOLOGIES; + asm_top.payload_addr_lsw = lower_32_bits(cal_block->cal_data.paddr); + asm_top.payload_addr_msw = msm_audio_populate_upper_32_bits( + cal_block->cal_data.paddr); + asm_top.mem_map_handle = cal_block->map_data.q6map_handle; + asm_top.payload_size = cal_block->cal_data.size; + + pr_debug("%s: Sending ASM_CMD_ADD_TOPOLOGIES payload = %pK, size = %d, map handle = 0x%x\n", + __func__, &cal_block->cal_data.paddr, + asm_top.payload_size, asm_top.mem_map_handle); + + result = apr_send_pkt(ac->apr, (uint32_t *) &asm_top); + if (result < 0) { + pr_err("%s: Set topologies failed result %d\n", + __func__, result); + pr_debug("%s: Set topologies failed payload = 0x%pK\n", + __func__, &cal_block->cal_data.paddr); + goto unmap; + + } + + result = wait_event_timeout(ac->mem_wait, + (atomic_read(&ac->mem_state) >= 0), 5*HZ); + if (!result) { + pr_err("%s: Set topologies failed timeout\n", __func__); + pr_debug("%s: Set topologies failed after timedout payload = 0x%pK\n", + __func__, &cal_block->cal_data.paddr); + result = -ETIMEDOUT; + goto unmap; + } + if (atomic_read(&ac->mem_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->mem_state))); + result = adsp_err_get_lnx_err_code( + atomic_read(&ac->mem_state)); + goto unmap; + } + +unmap: + result1 = q6asm_unmap_cal_memory(ASM_CUST_TOPOLOGY_CAL_TYPE, + cal_block); + if (result1 < 0) { + result = result1; + pr_debug("%s: unmap cal failed! %d\n", __func__, result); + } +unlock: + mutex_unlock(&cal_data[ASM_CUSTOM_TOP_CAL]->lock); +done: + return result; +} + +int q6asm_map_rtac_block(struct rtac_cal_block_data *cal_block) +{ + int result = 0; + struct asm_buffer_node *buf_node = NULL; + struct list_head *ptr, *next; + + pr_debug("%s:\n", __func__); + + if (cal_block == NULL) { + pr_err("%s: cal_block is NULL!\n", + __func__); + result = -EINVAL; + goto done; + } + + if (cal_block->cal_data.paddr == 0) { + pr_debug("%s: No address to map!\n", + __func__); + result = -EINVAL; + goto done; + } + + if (common_client.mmap_apr == NULL) { + common_client.mmap_apr = q6asm_mmap_apr_reg(); + if (common_client.mmap_apr == NULL) { + pr_err("%s: q6asm_mmap_apr_reg failed\n", + __func__); + result = -EPERM; + goto done; + } + } + + if (cal_block->map_data.map_size == 0) { + pr_debug("%s: map size is 0!\n", + __func__); + result = -EINVAL; + goto done; + } + + /* Use second asm buf to map memory */ + if (common_client.port[OUT].buf == NULL) { + pr_err("%s: common buf is NULL\n", + __func__); + result = -EINVAL; + goto done; + } + + common_client.port[OUT].buf->phys = cal_block->cal_data.paddr; + + result = q6asm_memory_map_regions(&common_client, + OUT, cal_block->map_data.map_size, 1, 1); + if (result < 0) { + pr_err("%s: mmap did not work! size = %d result %d\n", + __func__, + cal_block->map_data.map_size, result); + pr_debug("%s: mmap did not work! addr = 0x%pK, size = %d\n", + __func__, + &cal_block->cal_data.paddr, + cal_block->map_data.map_size); + goto done; + } + + list_for_each_safe(ptr, next, + &common_client.port[OUT].mem_map_handle) { + buf_node = list_entry(ptr, struct asm_buffer_node, + list); + if (buf_node->buf_phys_addr == cal_block->cal_data.paddr) { + cal_block->map_data.map_handle = buf_node->mmap_hdl; + break; + } + } +done: + return result; +} + +int q6asm_unmap_rtac_block(uint32_t *mem_map_handle) +{ + int result = 0; + int result2 = 0; + + pr_debug("%s:\n", __func__); + + if (mem_map_handle == NULL) { + pr_debug("%s: Map handle is NULL, nothing to unmap\n", + __func__); + goto done; + } + + if (*mem_map_handle == 0) { + pr_debug("%s: Map handle is 0, nothing to unmap\n", + __func__); + goto done; + } + + if (common_client.mmap_apr == NULL) { + common_client.mmap_apr = q6asm_mmap_apr_reg(); + if (common_client.mmap_apr == NULL) { + pr_err("%s: q6asm_mmap_apr_reg failed\n", + __func__); + result = -EPERM; + goto done; + } + } + + + result2 = q6asm_memory_unmap_regions(&common_client, OUT); + if (result2 < 0) { + pr_err("%s: unmap failed, err %d\n", + __func__, result2); + result = result2; + } else { + mem_map_handle = 0; + } + + result2 = q6asm_mmap_apr_dereg(); + if (result2 < 0) { + pr_err("%s: q6asm_mmap_apr_dereg failed, err %d\n", + __func__, result2); + result = result2; + } +done: + return result; +} + +int q6asm_audio_client_buf_free(unsigned int dir, + struct audio_client *ac) +{ + struct audio_port_data *port; + int cnt = 0; + int rc = 0; + + pr_debug("%s: Session id %d\n", __func__, ac->session); + mutex_lock(&ac->cmd_lock); + if (ac->io_mode & SYNC_IO_MODE) { + port = &ac->port[dir]; + if (!port->buf) { + pr_err("%s: buf NULL\n", __func__); + mutex_unlock(&ac->cmd_lock); + return 0; + } + cnt = port->max_buf_cnt - 1; + + if (cnt >= 0) { + rc = q6asm_memory_unmap_regions(ac, dir); + if (rc < 0) + pr_err("%s: Memory_unmap_regions failed %d\n", + __func__, rc); + } + + while (cnt >= 0) { + if (port->buf[cnt].data) { + if (!rc || atomic_read(&ac->reset)) + msm_audio_ion_free( + port->buf[cnt].client, + port->buf[cnt].handle); + + port->buf[cnt].client = NULL; + port->buf[cnt].handle = NULL; + port->buf[cnt].data = NULL; + port->buf[cnt].phys = 0; + --(port->max_buf_cnt); + } + --cnt; + } + kfree(port->buf); + port->buf = NULL; + } + mutex_unlock(&ac->cmd_lock); + return 0; +} + +int q6asm_audio_client_buf_free_contiguous(unsigned int dir, + struct audio_client *ac) +{ + struct audio_port_data *port; + int cnt = 0; + int rc = 0; + + pr_debug("%s: Session id %d\n", __func__, ac->session); + mutex_lock(&ac->cmd_lock); + port = &ac->port[dir]; + if (!port->buf) { + mutex_unlock(&ac->cmd_lock); + return 0; + } + cnt = port->max_buf_cnt - 1; + + if (cnt >= 0) { + rc = q6asm_memory_unmap(ac, port->buf[0].phys, dir); + if (rc < 0) + pr_err("%s: Memory_unmap_regions failed %d\n", + __func__, rc); + } + + if (port->buf[0].data) { + pr_debug("%s: data[%pK]phys[%pK][%pK] , client[%pK] handle[%pK]\n", + __func__, + port->buf[0].data, + &port->buf[0].phys, + &port->buf[0].phys, + port->buf[0].client, + port->buf[0].handle); + if (!rc || atomic_read(&ac->reset)) + msm_audio_ion_free(port->buf[0].client, + port->buf[0].handle); + port->buf[0].client = NULL; + port->buf[0].handle = NULL; + } + + while (cnt >= 0) { + port->buf[cnt].data = NULL; + port->buf[cnt].phys = 0; + cnt--; + } + port->max_buf_cnt = 0; + kfree(port->buf); + port->buf = NULL; + mutex_unlock(&ac->cmd_lock); + return 0; +} + +void q6asm_audio_client_free(struct audio_client *ac) +{ + int loopcnt; + struct audio_port_data *port; + + if (!ac) { + pr_err("%s: ac %pK\n", __func__, ac); + return; + } + if (!ac->session) { + pr_err("%s: ac session invalid\n", __func__); + return; + } + + mutex_lock(&session_lock); + + pr_debug("%s: Session id %d\n", __func__, ac->session); + if (ac->io_mode & SYNC_IO_MODE) { + for (loopcnt = 0; loopcnt <= OUT; loopcnt++) { + port = &ac->port[loopcnt]; + if (!port->buf) + continue; + pr_debug("%s: loopcnt = %d\n", + __func__, loopcnt); + q6asm_audio_client_buf_free(loopcnt, ac); + } + } + + rtac_set_asm_handle(ac->session, NULL); + apr_deregister(ac->apr2); + apr_deregister(ac->apr); + q6asm_mmap_apr_dereg(); + ac->apr2 = NULL; + ac->apr = NULL; + ac->mmap_apr = NULL; + q6asm_session_free(ac); + + pr_debug("%s: APR De-Register\n", __func__); + +/*done:*/ + kfree(ac); + ac = NULL; + mutex_unlock(&session_lock); +} + +int q6asm_set_io_mode(struct audio_client *ac, uint32_t mode1) +{ + uint32_t mode; + int ret = 0; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + + ac->io_mode &= 0xFF00; + mode = (mode1 & 0xF); + + pr_debug("%s: ac->mode after anding with FF00:0x%x,\n", + __func__, ac->io_mode); + + if ((mode == ASYNC_IO_MODE) || (mode == SYNC_IO_MODE)) { + ac->io_mode |= mode1; + pr_debug("%s: Set Mode to 0x%x\n", __func__, ac->io_mode); + } else { + pr_err("%s: Not an valid IO Mode:%d\n", __func__, ac->io_mode); + ret = -EINVAL; + } + + return ret; +} + +void *q6asm_mmap_apr_reg(void) +{ + if ((atomic_read(&this_mmap.ref_cnt) == 0) || + (this_mmap.apr == NULL)) { + this_mmap.apr = apr_register("ADSP", "ASM", + (apr_fn)q6asm_srvc_callback, + 0x0FFFFFFFF, &this_mmap); + if (this_mmap.apr == NULL) { + pr_debug("%s: Unable to register APR ASM common port\n", + __func__); + goto fail; + } + } + atomic_inc(&this_mmap.ref_cnt); + + return this_mmap.apr; +fail: + return NULL; +} + +int q6asm_send_stream_cmd(struct audio_client *ac, + struct msm_adsp_event_data *data) +{ + char *asm_params = NULL; + struct apr_hdr hdr; + int sz, rc; + + if (!data || !ac) { + pr_err("%s: %s is NULL\n", __func__, + (!data) ? "data" : "ac"); + rc = -EINVAL; + goto done; + } + + if (data->event_type >= ARRAY_SIZE(adsp_reg_event_opcode)) { + pr_err("%s: event %u out of boundary of array size of (%lu)\n", + __func__, data->event_type, + (long)ARRAY_SIZE(adsp_reg_event_opcode)); + rc = -EINVAL; + goto done; + } + + sz = sizeof(struct apr_hdr) + data->payload_len; + asm_params = kzalloc(sz, GFP_KERNEL); + if (!asm_params) { + rc = -ENOMEM; + goto done; + } + + q6asm_add_hdr_async(ac, &hdr, sz, TRUE); + atomic_set(&ac->cmd_state_pp, -1); + hdr.opcode = adsp_reg_event_opcode[data->event_type]; + memcpy(asm_params, &hdr, sizeof(struct apr_hdr)); + memcpy(asm_params + sizeof(struct apr_hdr), + data->payload, data->payload_len); + rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params); + if (rc < 0) { + pr_err("%s: stream event cmd apr pkt failed\n", __func__); + rc = -EINVAL; + goto fail_send_param; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state_pp) >= 0), 1 * HZ); + if (!rc) { + pr_err("%s: timeout for stream event cmd resp\n", __func__); + rc = -ETIMEDOUT; + goto fail_send_param; + } + + if (atomic_read(&ac->cmd_state_pp) > 0) { + pr_err("%s: DSP returned error[%s] for stream event cmd\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state_pp))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state_pp)); + goto fail_send_param; + } + + rc = 0; +fail_send_param: + kfree(asm_params); +done: + return rc; +} + +struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv) +{ + struct audio_client *ac; + int n; + int lcnt = 0; + int rc = 0; + + ac = kzalloc(sizeof(struct audio_client), GFP_KERNEL); + if (!ac) + return NULL; + + mutex_lock(&session_lock); + n = q6asm_session_alloc(ac); + if (n <= 0) { + pr_err("%s: ASM Session alloc fail n=%d\n", __func__, n); + mutex_unlock(&session_lock); + goto fail_session; + } + ac->session = n; + ac->cb = cb; + ac->path_delay = UINT_MAX; + ac->priv = priv; + ac->io_mode = SYNC_IO_MODE; + ac->perf_mode = LEGACY_PCM_MODE; + ac->fptr_cache_ops = NULL; + /* DSP expects stream id from 1 */ + ac->stream_id = 1; + ac->apr = apr_register("ADSP", "ASM", + (apr_fn)q6asm_callback, + ((ac->session) << 8 | 0x0001), + ac); + + if (ac->apr == NULL) { + pr_err("%s: Registration with APR failed\n", __func__); + mutex_unlock(&session_lock); + goto fail_apr1; + } + ac->apr2 = apr_register("ADSP", "ASM", + (apr_fn)q6asm_callback, + ((ac->session) << 8 | 0x0002), + ac); + + if (ac->apr2 == NULL) { + pr_err("%s: Registration with APR-2 failed\n", __func__); + mutex_unlock(&session_lock); + goto fail_apr2; + } + + rtac_set_asm_handle(n, ac->apr); + + pr_debug("%s: Registering the common port with APR\n", __func__); + ac->mmap_apr = q6asm_mmap_apr_reg(); + if (ac->mmap_apr == NULL) { + mutex_unlock(&session_lock); + goto fail_mmap; + } + + init_waitqueue_head(&ac->cmd_wait); + init_waitqueue_head(&ac->time_wait); + init_waitqueue_head(&ac->mem_wait); + atomic_set(&ac->time_flag, 1); + atomic_set(&ac->reset, 0); + INIT_LIST_HEAD(&ac->port[0].mem_map_handle); + INIT_LIST_HEAD(&ac->port[1].mem_map_handle); + pr_debug("%s: mem_map_handle list init'ed\n", __func__); + mutex_init(&ac->cmd_lock); + for (lcnt = 0; lcnt <= OUT; lcnt++) { + mutex_init(&ac->port[lcnt].lock); + spin_lock_init(&ac->port[lcnt].dsp_lock); + } + atomic_set(&ac->cmd_state, 0); + atomic_set(&ac->cmd_state_pp, 0); + atomic_set(&ac->mem_state, 0); + + rc = send_asm_custom_topology(ac); + if (rc < 0) { + mutex_unlock(&session_lock); + goto fail_mmap; + } + + pr_debug("%s: session[%d]\n", __func__, ac->session); + + mutex_unlock(&session_lock); + + return ac; +fail_mmap: + apr_deregister(ac->apr2); +fail_apr2: + apr_deregister(ac->apr); +fail_apr1: + q6asm_session_free(ac); +fail_session: + kfree(ac); + return NULL; +} + +struct audio_client *q6asm_get_audio_client(int session_id) +{ + if (session_id == ASM_CONTROL_SESSION) + return &common_client; + + if ((session_id <= 0) || (session_id > ASM_ACTIVE_STREAMS_ALLOWED)) { + pr_err("%s: invalid session: %d\n", __func__, session_id); + goto err; + } + + if (!session[session_id]) { + pr_err("%s: session not active: %d\n", __func__, session_id); + goto err; + } + return session[session_id]; +err: + return NULL; +} + +int q6asm_audio_client_buf_alloc(unsigned int dir, + struct audio_client *ac, + unsigned int bufsz, + uint32_t bufcnt) +{ + int cnt = 0; + int rc = 0; + struct audio_buffer *buf; + size_t len; + + if (!(ac) || !(bufsz) || ((dir != IN) && (dir != OUT))) { + pr_err("%s: ac %pK bufsz %d dir %d\n", __func__, ac, bufsz, + dir); + return -EINVAL; + } + + pr_debug("%s: session[%d]bufsz[%d]bufcnt[%d]\n", __func__, ac->session, + bufsz, bufcnt); + + if (ac->session <= 0 || ac->session > 8) { + pr_err("%s: Session ID is invalid, session = %d\n", __func__, + ac->session); + goto fail; + } + + if (ac->io_mode & SYNC_IO_MODE) { + if (ac->port[dir].buf) { + pr_debug("%s: buffer already allocated\n", __func__); + return 0; + } + mutex_lock(&ac->cmd_lock); + if (bufcnt > (U32_MAX/sizeof(struct audio_buffer))) { + pr_err("%s: Buffer size overflows", __func__); + mutex_unlock(&ac->cmd_lock); + goto fail; + } + buf = kzalloc(((sizeof(struct audio_buffer))*bufcnt), + GFP_KERNEL); + + if (!buf) { + mutex_unlock(&ac->cmd_lock); + goto fail; + } + + ac->port[dir].buf = buf; + + while (cnt < bufcnt) { + if (bufsz > 0) { + if (!buf[cnt].data) { + rc = msm_audio_ion_alloc("asm_client", + &buf[cnt].client, &buf[cnt].handle, + bufsz, + (ion_phys_addr_t *)&buf[cnt].phys, + &len, + &buf[cnt].data); + if (rc) { + pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", + __func__, rc); + mutex_unlock(&ac->cmd_lock); + goto fail; + } + + buf[cnt].used = 1; + buf[cnt].size = bufsz; + buf[cnt].actual_size = bufsz; + pr_debug("%s: data[%pK]phys[%pK][%pK]\n", + __func__, + buf[cnt].data, + &buf[cnt].phys, + &buf[cnt].phys); + cnt++; + } + } + } + ac->port[dir].max_buf_cnt = cnt; + + mutex_unlock(&ac->cmd_lock); + rc = q6asm_memory_map_regions(ac, dir, bufsz, cnt, 0); + if (rc < 0) { + pr_err("%s: CMD Memory_map_regions failed %d for size %d\n", + __func__, rc, bufsz); + goto fail; + } + } + return 0; +fail: + q6asm_audio_client_buf_free(dir, ac); + return -EINVAL; +} + +int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir, + struct audio_client *ac, + unsigned int bufsz, + unsigned int bufcnt) +{ + int cnt = 0; + int rc = 0; + struct audio_buffer *buf; + size_t len; + int bytes_to_alloc; + + if (!(ac) || ((dir != IN) && (dir != OUT))) { + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); + return -EINVAL; + } + + pr_debug("%s: session[%d]bufsz[%d]bufcnt[%d]\n", + __func__, ac->session, + bufsz, bufcnt); + + if (ac->session <= 0 || ac->session > 8) { + pr_err("%s: Session ID is invalid, session = %d\n", __func__, + ac->session); + goto fail; + } + + if (ac->port[dir].buf) { + pr_err("%s: buffer already allocated\n", __func__); + return 0; + } + mutex_lock(&ac->cmd_lock); + buf = kzalloc(((sizeof(struct audio_buffer))*bufcnt), + GFP_KERNEL); + + if (!buf) { + pr_err("%s: buffer allocation failed\n", __func__); + mutex_unlock(&ac->cmd_lock); + goto fail; + } + + ac->port[dir].buf = buf; + + /* check for integer overflow */ + if ((bufcnt > 0) && ((INT_MAX / bufcnt) < bufsz)) { + pr_err("%s: integer overflow\n", __func__); + mutex_unlock(&ac->cmd_lock); + goto fail; + } + bytes_to_alloc = bufsz * bufcnt; + + /* The size to allocate should be multiple of 4K bytes */ + bytes_to_alloc = PAGE_ALIGN(bytes_to_alloc); + + rc = msm_audio_ion_alloc("asm_client", &buf[0].client, &buf[0].handle, + bytes_to_alloc, + (ion_phys_addr_t *)&buf[0].phys, &len, + &buf[0].data); + if (rc) { + pr_err("%s: Audio ION alloc is failed, rc = %d\n", + __func__, rc); + mutex_unlock(&ac->cmd_lock); + goto fail; + } + + buf[0].used = dir ^ 1; + buf[0].size = bufsz; + buf[0].actual_size = bufsz; + cnt = 1; + while (cnt < bufcnt) { + if (bufsz > 0) { + buf[cnt].data = buf[0].data + (cnt * bufsz); + buf[cnt].phys = buf[0].phys + (cnt * bufsz); + if (!buf[cnt].data) { + pr_err("%s: Buf alloc failed\n", + __func__); + mutex_unlock(&ac->cmd_lock); + goto fail; + } + buf[cnt].used = dir ^ 1; + buf[cnt].size = bufsz; + buf[cnt].actual_size = bufsz; + pr_debug("%s: data[%pK]phys[%pK][%pK]\n", + __func__, + buf[cnt].data, + &buf[cnt].phys, + &buf[cnt].phys); + } + cnt++; + } + ac->port[dir].max_buf_cnt = cnt; + mutex_unlock(&ac->cmd_lock); + rc = q6asm_memory_map_regions(ac, dir, bufsz, cnt, 1); + if (rc < 0) { + pr_err("%s: CMD Memory_map_regions failed %d for size %d\n", + __func__, rc, bufsz); + goto fail; + } + return 0; +fail: + q6asm_audio_client_buf_free_contiguous(dir, ac); + return -EINVAL; +} + +static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) +{ + uint32_t dir = 0; + uint32_t i = IN; + uint32_t *payload; + unsigned long dsp_flags; + struct asm_buffer_node *buf_node = NULL; + struct list_head *ptr, *next; + union asm_token_struct asm_token; + + struct audio_client *ac = NULL; + struct audio_port_data *port; + + if (!data) { + pr_err("%s: Invalid CB\n", __func__); + return 0; + } + + payload = data->payload; + + if (data->opcode == RESET_EVENTS) { + pr_debug("%s: Reset event is received: %d %d apr[%pK]\n", + __func__, + data->reset_event, + data->reset_proc, + this_mmap.apr); + atomic_set(&this_mmap.ref_cnt, 0); + apr_reset(this_mmap.apr); + this_mmap.apr = NULL; + for (; i <= OUT; i++) { + list_for_each_safe(ptr, next, + &common_client.port[i].mem_map_handle) { + buf_node = list_entry(ptr, + struct asm_buffer_node, + list); + if (buf_node->buf_phys_addr == + common_client.port[i].buf->phys) { + list_del(&buf_node->list); + kfree(buf_node); + } + } + pr_debug("%s: Clearing custom topology\n", __func__); + } + + cal_utils_clear_cal_block_q6maps(ASM_MAX_CAL_TYPES, cal_data); + common_client.mmap_apr = NULL; + mutex_lock(&cal_data[ASM_CUSTOM_TOP_CAL]->lock); + set_custom_topology = 1; + mutex_unlock(&cal_data[ASM_CUSTOM_TOP_CAL]->lock); + topology_map_handle = 0; + rtac_clear_mapping(ASM_RTAC_CAL); + return 0; + } + asm_token.token = data->token; + ac = q6asm_get_audio_client(asm_token._token.session_id); + dir = q6asm_get_flag_from_token(&asm_token, ASM_DIRECTION_OFFSET); + + if (!ac) { + pr_debug("%s: session[%d] already freed\n", + __func__, asm_token._token.session_id); + return 0; + } + + if (data->payload_size > sizeof(int)) { + pr_debug("%s:ptr0[0x%x]ptr1[0x%x]opcode[0x%x] token[0x%x]payload_s[%d] src[%d] dest[%d]sid[%d]dir[%d]\n", + __func__, payload[0], payload[1], data->opcode, + data->token, data->payload_size, data->src_port, + data->dest_port, asm_token._token.session_id, dir); + pr_debug("%s:Payload = [0x%x] status[0x%x]\n", + __func__, payload[0], payload[1]); + } else if (data->payload_size == sizeof(int)) { + pr_debug("%s:ptr0[0x%x]opcode[0x%x] token[0x%x]payload_s[%d] src[%d] dest[%d]sid[%d]dir[%d]\n", + __func__, payload[0], data->opcode, + data->token, data->payload_size, data->src_port, + data->dest_port, asm_token._token.session_id, dir); + pr_debug("%s:Payload = [0x%x]\n", + __func__, payload[0]); + } + + if (data->opcode == APR_BASIC_RSP_RESULT) { + switch (payload[0]) { + case ASM_CMD_SHARED_MEM_MAP_REGIONS: + case ASM_CMD_SHARED_MEM_UNMAP_REGIONS: + case ASM_CMD_ADD_TOPOLOGIES: + if (payload[1] != 0) { + pr_err("%s: cmd = 0x%x returned error = 0x%x sid:%d\n", + __func__, payload[0], payload[1], + asm_token._token.session_id); + if (payload[0] == + ASM_CMD_SHARED_MEM_UNMAP_REGIONS) + atomic_set(&ac->unmap_cb_success, 0); + + atomic_set(&ac->mem_state, payload[1]); + wake_up(&ac->mem_wait); + } else { + if (payload[0] == + ASM_CMD_SHARED_MEM_UNMAP_REGIONS) + atomic_set(&ac->unmap_cb_success, 1); + } + + if (atomic_cmpxchg(&ac->mem_state, -1, 0) == -1) + wake_up(&ac->mem_wait); + dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x]\n", + __func__, payload[0], payload[1]); + break; + default: + pr_debug("%s: command[0x%x] not expecting rsp\n", + __func__, payload[0]); + break; + } + return 0; + } + + port = &ac->port[dir]; + + switch (data->opcode) { + case ASM_CMDRSP_SHARED_MEM_MAP_REGIONS:{ + pr_debug("%s:PL#0[0x%x] dir=0x%x s_id=0x%x\n", + __func__, payload[0], dir, asm_token._token.session_id); + spin_lock_irqsave(&port->dsp_lock, dsp_flags); + if (atomic_cmpxchg(&ac->mem_state, -1, 0) == -1) { + ac->port[dir].tmp_hdl = payload[0]; + wake_up(&ac->mem_wait); + } + spin_unlock_irqrestore(&port->dsp_lock, dsp_flags); + break; + } + case ASM_CMD_SHARED_MEM_UNMAP_REGIONS:{ + pr_debug("%s: PL#0[0x%x]PL#1 [0x%x]\n", + __func__, payload[0], payload[1]); + spin_lock_irqsave(&port->dsp_lock, dsp_flags); + if (atomic_cmpxchg(&ac->mem_state, -1, 0) == -1) + wake_up(&ac->mem_wait); + spin_unlock_irqrestore(&port->dsp_lock, dsp_flags); + + break; + } + default: + pr_debug("%s: command[0x%x]success [0x%x]\n", + __func__, payload[0], payload[1]); + } + if (ac->cb) + ac->cb(data->opcode, data->token, + data->payload, ac->priv); + return 0; +} + +static void q6asm_process_mtmx_get_param_rsp(struct audio_client *ac, + struct asm_mtmx_strtr_get_params_cmdrsp *cmdrsp) +{ + struct asm_session_mtmx_strtr_param_session_time_v3_t *time; + + if (cmdrsp->err_code) { + dev_err_ratelimited(ac->dev, + "%s: err=%x, mod_id=%x, param_id=%x\n", + __func__, cmdrsp->err_code, + cmdrsp->param_info.module_id, + cmdrsp->param_info.param_id); + return; + } + dev_dbg_ratelimited(ac->dev, + "%s: mod_id=%x, param_id=%x\n", __func__, + cmdrsp->param_info.module_id, + cmdrsp->param_info.param_id); + + switch (cmdrsp->param_info.module_id) { + case ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC: + switch (cmdrsp->param_info.param_id) { + case ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3: + time = &cmdrsp->param_data.session_time; + dev_vdbg(ac->dev, "%s: GET_TIME_V3, time_lsw=%x, time_msw=%x\n", + __func__, time->session_time_lsw, + time->session_time_msw); + ac->time_stamp = (uint64_t)(((uint64_t) + time->session_time_msw << 32) | + time->session_time_lsw); + if (time->flags & + ASM_SESSION_MTMX_STRTR_PARAM_STIME_TSTMP_FLG_BMASK) + dev_warn_ratelimited(ac->dev, + "%s: recv inval tstmp\n", + __func__); + if (atomic_cmpxchg(&ac->time_flag, 1, 0)) + wake_up(&ac->time_wait); + + break; + default: + dev_err(ac->dev, "%s: unexpected param_id %x\n", + __func__, cmdrsp->param_info.param_id); + break; + } + break; + default: + dev_err(ac->dev, "%s: unexpected mod_id %x\n", __func__, + cmdrsp->param_info.module_id); + break; + } +} + +static int32_t q6asm_callback(struct apr_client_data *data, void *priv) +{ + int i = 0; + struct audio_client *ac = (struct audio_client *)priv; + unsigned long dsp_flags; + uint32_t *payload; + uint32_t wakeup_flag = 1; + int32_t ret = 0; + union asm_token_struct asm_token; + uint8_t buf_index; + struct msm_adsp_event_data *pp_event_package = NULL; + uint32_t payload_size = 0; + + if (ac == NULL) { + pr_err("%s: ac NULL\n", __func__); + return -EINVAL; + } + if (data == NULL) { + pr_err("%s: data NULL\n", __func__); + return -EINVAL; + } + if (!q6asm_is_valid_audio_client(ac)) { + pr_err("%s: audio client pointer is invalid, ac = %pK\n", + __func__, ac); + return -EINVAL; + } + + if (ac->session <= 0 || ac->session > 8) { + pr_err("%s: Session ID is invalid, session = %d\n", __func__, + ac->session); + return -EINVAL; + } + + payload = data->payload; + asm_token.token = data->token; + if (q6asm_get_flag_from_token(&asm_token, ASM_CMD_NO_WAIT_OFFSET)) { + pr_debug("%s: No wait command opcode[0x%x] cmd_opcode:%x\n", + __func__, data->opcode, payload ? payload[0] : 0); + wakeup_flag = 0; + } + + if (data->opcode == RESET_EVENTS) { + mutex_lock(&ac->cmd_lock); + atomic_set(&ac->reset, 1); + if (ac->apr == NULL) { + ac->apr = ac->apr2; + ac->apr2 = NULL; + } + pr_debug("%s: Reset event is received: %d %d apr[%pK]\n", + __func__, + data->reset_event, data->reset_proc, ac->apr); + if (ac->cb) + ac->cb(data->opcode, data->token, + (uint32_t *)data->payload, ac->priv); + apr_reset(ac->apr); + ac->apr = NULL; + atomic_set(&ac->time_flag, 0); + atomic_set(&ac->cmd_state, 0); + atomic_set(&ac->mem_state, 0); + atomic_set(&ac->cmd_state_pp, 0); + wake_up(&ac->time_wait); + wake_up(&ac->cmd_wait); + wake_up(&ac->mem_wait); + mutex_unlock(&ac->cmd_lock); + return 0; + } + + dev_vdbg(ac->dev, "%s: session[%d]opcode[0x%x] token[0x%x]payload_size[%d] src[%d] dest[%d]\n", + __func__, + ac->session, data->opcode, + data->token, data->payload_size, data->src_port, + data->dest_port); + if ((data->opcode != ASM_DATA_EVENT_RENDERED_EOS) && + (data->opcode != ASM_DATA_EVENT_EOS) && + (data->opcode != ASM_SESSION_EVENT_RX_UNDERFLOW)) { + if (payload == NULL) { + pr_err("%s: payload is null\n", __func__); + return -EINVAL; + } + dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x] opcode 0x%x\n", + __func__, payload[0], payload[1], data->opcode); + } + if (data->opcode == APR_BASIC_RSP_RESULT) { + switch (payload[0]) { + case ASM_STREAM_CMD_SET_PP_PARAMS_V2: + if (rtac_make_asm_callback(ac->session, payload, + data->payload_size)) + break; + case ASM_SESSION_CMD_PAUSE: + case ASM_SESSION_CMD_SUSPEND: + case ASM_DATA_CMD_EOS: + case ASM_STREAM_CMD_CLOSE: + case ASM_STREAM_CMD_FLUSH: + case ASM_SESSION_CMD_RUN_V2: + case ASM_SESSION_CMD_REGISTER_FORX_OVERFLOW_EVENTS: + case ASM_STREAM_CMD_FLUSH_READBUFS: + pr_debug("%s: session %d opcode 0x%x token 0x%x Payload = [0x%x] src %d dest %d\n", + __func__, ac->session, data->opcode, data->token, + payload[0], data->src_port, data->dest_port); + ret = q6asm_is_valid_session(data, priv); + if (ret != 0) { + pr_err("%s: session invalid %d\n", __func__, ret); + return ret; + } + case ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2: + case ASM_STREAM_CMD_OPEN_READ_V3: + case ASM_STREAM_CMD_OPEN_WRITE_V3: + case ASM_STREAM_CMD_OPEN_PULL_MODE_WRITE: + case ASM_STREAM_CMD_OPEN_PUSH_MODE_READ: + case ASM_STREAM_CMD_OPEN_READWRITE_V2: + case ASM_STREAM_CMD_OPEN_LOOPBACK_V2: + case ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK: + case ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2: + case ASM_DATA_CMD_IEC_60958_MEDIA_FMT: + case ASM_STREAM_CMD_SET_ENCDEC_PARAM: + case ASM_STREAM_CMD_SET_ENCDEC_PARAM_V2: + case ASM_STREAM_CMD_REGISTER_ENCDEC_EVENTS: + case ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE: + case ASM_DATA_CMD_REMOVE_INITIAL_SILENCE: + case ASM_DATA_CMD_REMOVE_TRAILING_SILENCE: + case ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS: + case ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED: + pr_debug("%s: session %d opcode 0x%x token 0x%x Payload = [0x%x] stat 0x%x src %d dest %d\n", + __func__, ac->session, + data->opcode, data->token, + payload[0], payload[1], + data->src_port, data->dest_port); + if (payload[1] != 0) { + pr_err("%s: cmd = 0x%x returned error = 0x%x\n", + __func__, payload[0], payload[1]); + if (wakeup_flag) { + if ((is_adsp_reg_event(payload[0]) >= 0) + || (payload[0] == + ASM_STREAM_CMD_SET_PP_PARAMS_V2)) + atomic_set(&ac->cmd_state_pp, + payload[1]); + else + atomic_set(&ac->cmd_state, + payload[1]); + wake_up(&ac->cmd_wait); + } + return 0; + } + if ((is_adsp_reg_event(payload[0]) >= 0) || + (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2)) { + if (atomic_read(&ac->cmd_state_pp) && + wakeup_flag) { + atomic_set(&ac->cmd_state_pp, 0); + wake_up(&ac->cmd_wait); + } + } else { + if (atomic_read(&ac->cmd_state) && + wakeup_flag) { + atomic_set(&ac->cmd_state, 0); + wake_up(&ac->cmd_wait); + } + } + if (ac->cb) + ac->cb(data->opcode, data->token, + (uint32_t *)data->payload, ac->priv); + break; + case ASM_CMD_ADD_TOPOLOGIES: + pr_debug("%s:Payload = [0x%x]stat[0x%x]\n", + __func__, payload[0], payload[1]); + if (payload[1] != 0) { + pr_err("%s: cmd = 0x%x returned error = 0x%x\n", + __func__, payload[0], payload[1]); + if (wakeup_flag) { + atomic_set(&ac->mem_state, payload[1]); + wake_up(&ac->mem_wait); + } + return 0; + } + if (atomic_read(&ac->mem_state) && wakeup_flag) { + atomic_set(&ac->mem_state, 0); + wake_up(&ac->mem_wait); + } + if (ac->cb) + ac->cb(data->opcode, data->token, + (uint32_t *)data->payload, ac->priv); + break; + case ASM_DATA_EVENT_WATERMARK: { + pr_debug("%s: Watermark opcode[0x%x] status[0x%x]", + __func__, payload[0], payload[1]); + break; + } + case ASM_STREAM_CMD_GET_PP_PARAMS_V2: + pr_debug("%s: ASM_STREAM_CMD_GET_PP_PARAMS_V2 session %d opcode 0x%x token 0x%x src %d dest %d\n", + __func__, ac->session, + data->opcode, data->token, + data->src_port, data->dest_port); + /* Should only come here if there is an APR */ + /* error or malformed APR packet. Otherwise */ + /* response will be returned as */ + /* ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 */ + if (payload[1] != 0) { + pr_err("%s: ASM get param error = %d, resuming\n", + __func__, payload[1]); + rtac_make_asm_callback(ac->session, payload, + data->payload_size); + } + break; + case ASM_STREAM_CMD_REGISTER_PP_EVENTS: + pr_debug("%s: ASM_STREAM_CMD_REGISTER_PP_EVENTS session %d opcode 0x%x token 0x%x src %d dest %d\n", + __func__, ac->session, + data->opcode, data->token, + data->src_port, data->dest_port); + if (payload[1] != 0) + pr_err("%s: ASM get param error = %d, resuming\n", + __func__, payload[1]); + atomic_set(&ac->cmd_state_pp, payload[1]); + wake_up(&ac->cmd_wait); + break; + default: + pr_debug("%s: command[0x%x] not expecting rsp\n", + __func__, payload[0]); + break; + } + return 0; + } + + switch (data->opcode) { + case ASM_DATA_EVENT_WRITE_DONE_V2:{ + struct audio_port_data *port = &ac->port[IN]; + + dev_vdbg(ac->dev, "%s: Rxed opcode[0x%x] status[0x%x] token[%d]", + __func__, payload[0], payload[1], + data->token); + if (ac->io_mode & SYNC_IO_MODE) { + if (port->buf == NULL) { + pr_err("%s: Unexpected Write Done\n", + __func__); + return -EINVAL; + } + spin_lock_irqsave(&port->dsp_lock, dsp_flags); + buf_index = asm_token._token.buf_index; + if (lower_32_bits(port->buf[buf_index].phys) != + payload[0] || + msm_audio_populate_upper_32_bits( + port->buf[buf_index].phys) != payload[1]) { + pr_debug("%s: Expected addr %pK\n", + __func__, &port->buf[buf_index].phys); + pr_err("%s: rxedl[0x%x] rxedu [0x%x]\n", + __func__, payload[0], payload[1]); + spin_unlock_irqrestore(&port->dsp_lock, + dsp_flags); + return -EINVAL; + } + port->buf[buf_index].used = 1; + spin_unlock_irqrestore(&port->dsp_lock, dsp_flags); + + config_debug_fs_write_cb(); + + for (i = 0; i < port->max_buf_cnt; i++) + dev_vdbg(ac->dev, "%s %d\n", + __func__, port->buf[i].used); + + } + break; + } + case ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2: + pr_debug("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 session %d opcode 0x%x token 0x%x src %d dest %d\n", + __func__, ac->session, data->opcode, + data->token, + data->src_port, data->dest_port); + if (payload[0] != 0) { + pr_err("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 returned error = 0x%x\n", + __func__, payload[0]); + } else if (generic_get_data) { + generic_get_data->valid = 1; + if (generic_get_data->is_inband) { + pr_debug("%s: payload[1] = 0x%x, payload[2]=0x%x, payload[3]=0x%x\n", + __func__, payload[1], payload[2], payload[3]); + generic_get_data->size_in_ints = payload[3]>>2; + for (i = 0; i < payload[3]>>2; i++) { + generic_get_data->ints[i] = + payload[4+i]; + pr_debug("%s: ASM callback val %i = %i\n", + __func__, i, payload[4+i]); + } + pr_debug("%s: callback size in ints = %i\n", + __func__, + generic_get_data->size_in_ints); + } + if (atomic_read(&ac->cmd_state) && wakeup_flag) { + atomic_set(&ac->cmd_state, 0); + wake_up(&ac->cmd_wait); + } + break; + } + rtac_make_asm_callback(ac->session, payload, + data->payload_size); + break; + case ASM_DATA_EVENT_READ_DONE_V2:{ + + struct audio_port_data *port = &ac->port[OUT]; + + config_debug_fs_read_cb(); + + dev_vdbg(ac->dev, "%s: ReadDone: status=%d buff_add=0x%x act_size=%d offset=%d\n", + __func__, payload[READDONE_IDX_STATUS], + payload[READDONE_IDX_BUFADD_LSW], + payload[READDONE_IDX_SIZE], + payload[READDONE_IDX_OFFSET]); + + dev_vdbg(ac->dev, "%s: ReadDone:msw_ts=%d lsw_ts=%d memmap_hdl=0x%x flags=%d id=%d num=%d\n", + __func__, payload[READDONE_IDX_MSW_TS], + payload[READDONE_IDX_LSW_TS], + payload[READDONE_IDX_MEMMAP_HDL], + payload[READDONE_IDX_FLAGS], + payload[READDONE_IDX_SEQ_ID], + payload[READDONE_IDX_NUMFRAMES]); + + if (ac->io_mode & SYNC_IO_MODE) { + if (port->buf == NULL) { + pr_err("%s: Unexpected Write Done\n", __func__); + return -EINVAL; + } + spin_lock_irqsave(&port->dsp_lock, dsp_flags); + buf_index = asm_token._token.buf_index; + port->buf[buf_index].used = 0; + if (lower_32_bits(port->buf[buf_index].phys) != + payload[READDONE_IDX_BUFADD_LSW] || + msm_audio_populate_upper_32_bits( + port->buf[buf_index].phys) != + payload[READDONE_IDX_BUFADD_MSW]) { + dev_vdbg(ac->dev, "%s: Expected addr %pK\n", + __func__, &port->buf[buf_index].phys); + pr_err("%s: rxedl[0x%x] rxedu[0x%x]\n", + __func__, + payload[READDONE_IDX_BUFADD_LSW], + payload[READDONE_IDX_BUFADD_MSW]); + spin_unlock_irqrestore(&port->dsp_lock, + dsp_flags); + break; + } + port->buf[buf_index].actual_size = + payload[READDONE_IDX_SIZE]; + spin_unlock_irqrestore(&port->dsp_lock, dsp_flags); + } + break; + } + case ASM_DATA_EVENT_EOS: + case ASM_DATA_EVENT_RENDERED_EOS: + pr_debug("%s: EOS ACK received: rxed session %d opcode 0x%x token 0x%x src %d dest %d\n", + __func__, ac->session, + data->opcode, data->token, + data->src_port, data->dest_port); + break; + case ASM_SESSION_EVENTX_OVERFLOW: + pr_debug("%s: ASM_SESSION_EVENTX_OVERFLOW session %d opcode 0x%x token 0x%x src %d dest %d\n", + __func__, ac->session, + data->opcode, data->token, + data->src_port, data->dest_port); + break; + case ASM_SESSION_EVENT_RX_UNDERFLOW: + pr_debug("%s: ASM_SESSION_EVENT_RX_UNDERFLOW session %d opcode 0x%x token 0x%x src %d dest %d\n", + __func__, ac->session, + data->opcode, data->token, + data->src_port, data->dest_port); + break; + case ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3: + dev_vdbg(ac->dev, "%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3, payload[0] = %d, payload[1] = %d, payload[2] = %d\n", + __func__, + payload[0], payload[1], payload[2]); + ac->time_stamp = (uint64_t)(((uint64_t)payload[2] << 32) | + payload[1]); + if (atomic_cmpxchg(&ac->time_flag, 1, 0)) + wake_up(&ac->time_wait); + break; + case ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY: + case ASM_DATA_EVENT_ENC_SR_CM_CHANGE_NOTIFY: + pr_debug("%s: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY session %d opcode 0x%x token 0x%x src %d dest %d\n", + __func__, ac->session, + data->opcode, data->token, + data->src_port, data->dest_port); + pr_debug("%s: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, payload[0] = %d, payload[1] = %d, payload[2] = %d, payload[3] = %d\n", + __func__, + payload[0], payload[1], payload[2], + payload[3]); + break; + case ASM_SESSION_CMDRSP_GET_MTMX_STRTR_PARAMS_V2: + q6asm_process_mtmx_get_param_rsp(ac, (void *) payload); + break; + case ASM_STREAM_PP_EVENT: + case ASM_STREAM_CMD_ENCDEC_EVENTS: + case ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE: + pr_debug("%s: ASM_STREAM_EVENT payload[0][0x%x] payload[1][0x%x]", + __func__, payload[0], payload[1]); + i = is_adsp_raise_event(data->opcode); + if (i < 0) + return 0; + + /* repack payload for asm_stream_pp_event + * package is composed of event type + size + actual payload + */ + payload_size = data->payload_size; + pp_event_package = kzalloc(payload_size + + sizeof(struct msm_adsp_event_data), + GFP_ATOMIC); + if (!pp_event_package) + return -ENOMEM; + + pp_event_package->event_type = i; + pp_event_package->payload_len = payload_size; + memcpy((void *)pp_event_package->payload, + data->payload, payload_size); + ac->cb(data->opcode, data->token, + (void *)pp_event_package, ac->priv); + kfree(pp_event_package); + return 0; + case ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2: + pr_debug("%s: ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2 sesion %d status 0x%x msw %u lsw %u\n", + __func__, ac->session, payload[0], payload[2], + payload[1]); + wake_up(&ac->cmd_wait); + break; + case ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2: + pr_debug("%s: ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2 session %d status 0x%x msw %u lsw %u\n", + __func__, ac->session, payload[0], payload[2], + payload[1]); + if (payload[0] == 0) { + atomic_set(&ac->cmd_state, 0); + /* ignore msw, as a delay that large shouldn't happen */ + ac->path_delay = payload[1]; + } else { + atomic_set(&ac->cmd_state, payload[0]); + ac->path_delay = UINT_MAX; + } + wake_up(&ac->cmd_wait); + break; + } + if (ac->cb) + ac->cb(data->opcode, data->token, + data->payload, ac->priv); + + return 0; +} + +void *q6asm_is_cpu_buf_avail(int dir, struct audio_client *ac, uint32_t *size, + uint32_t *index) +{ + void *data; + unsigned char idx; + struct audio_port_data *port; + + if (!ac || ((dir != IN) && (dir != OUT))) { + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); + return NULL; + } + + if (ac->io_mode & SYNC_IO_MODE) { + port = &ac->port[dir]; + + mutex_lock(&port->lock); + idx = port->cpu_buf; + if (port->buf == NULL) { + pr_err("%s: Buffer pointer null\n", __func__); + mutex_unlock(&port->lock); + return NULL; + } + /* dir 0: used = 0 means buf in use + * dir 1: used = 1 means buf in use + */ + if (port->buf[idx].used == dir) { + /* To make it more robust, we could loop and get the + * next avail buf, its risky though + */ + pr_err("%s: Next buf idx[0x%x] not available, dir[%d]\n", + __func__, idx, dir); + mutex_unlock(&port->lock); + return NULL; + } + *size = port->buf[idx].actual_size; + *index = port->cpu_buf; + data = port->buf[idx].data; + dev_vdbg(ac->dev, "%s: session[%d]index[%d] data[%pK]size[%d]\n", + __func__, + ac->session, + port->cpu_buf, + data, *size); + /* By default increase the cpu_buf cnt + * user accesses this function,increase cpu + * buf(to avoid another api) + */ + port->buf[idx].used = dir; + port->cpu_buf = q6asm_get_next_buf(ac, port->cpu_buf, + port->max_buf_cnt); + mutex_unlock(&port->lock); + return data; + } + return NULL; +} + +int q6asm_cpu_buf_release(int dir, struct audio_client *ac) +{ + struct audio_port_data *port; + int ret = 0; + int idx; + + if (!ac || ((dir != IN) && (dir != OUT))) { + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); + ret = -EINVAL; + goto exit; + } + + if (ac->io_mode & SYNC_IO_MODE) { + port = &ac->port[dir]; + mutex_lock(&port->lock); + idx = port->cpu_buf; + if (port->cpu_buf == 0) { + port->cpu_buf = port->max_buf_cnt - 1; + } else if (port->cpu_buf < port->max_buf_cnt) { + port->cpu_buf = port->cpu_buf - 1; + } else { + pr_err("%s: buffer index(%d) out of range\n", + __func__, port->cpu_buf); + ret = -EINVAL; + mutex_unlock(&port->lock); + goto exit; + } + port->buf[port->cpu_buf].used = dir ^ 1; + mutex_unlock(&port->lock); + } +exit: + return ret; +} + +void *q6asm_is_cpu_buf_avail_nolock(int dir, struct audio_client *ac, + uint32_t *size, uint32_t *index) +{ + void *data; + unsigned char idx; + struct audio_port_data *port; + + if (!ac || ((dir != IN) && (dir != OUT))) { + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); + return NULL; + } + + port = &ac->port[dir]; + + idx = port->cpu_buf; + if (port->buf == NULL) { + pr_err("%s: Buffer pointer null\n", __func__); + return NULL; + } + /* + * dir 0: used = 0 means buf in use + * dir 1: used = 1 means buf in use + */ + if (port->buf[idx].used == dir) { + /* + * To make it more robust, we could loop and get the + * next avail buf, its risky though + */ + pr_err("%s: Next buf idx[0x%x] not available, dir[%d]\n", + __func__, idx, dir); + return NULL; + } + *size = port->buf[idx].actual_size; + *index = port->cpu_buf; + data = port->buf[idx].data; + dev_vdbg(ac->dev, "%s: session[%d]index[%d] data[%pK]size[%d]\n", + __func__, ac->session, port->cpu_buf, + data, *size); + /* + * By default increase the cpu_buf cnt + * user accesses this function,increase cpu + * buf(to avoid another api) + */ + port->buf[idx].used = dir; + port->cpu_buf = q6asm_get_next_buf(ac, port->cpu_buf, + port->max_buf_cnt); + return data; +} + +int q6asm_is_dsp_buf_avail(int dir, struct audio_client *ac) +{ + int ret = -1; + struct audio_port_data *port; + uint32_t idx; + + if (!ac || (dir != OUT)) { + pr_err("%s: ac %pK dir %d\n", __func__, ac, dir); + return ret; + } + + if (ac->io_mode & SYNC_IO_MODE) { + port = &ac->port[dir]; + + mutex_lock(&port->lock); + idx = port->dsp_buf; + + if (port->buf[idx].used == (dir ^ 1)) { + /* To make it more robust, we could loop and get the + * next avail buf, its risky though + */ + pr_err("%s: Next buf idx[0x%x] not available, dir[%d]\n", + __func__, idx, dir); + mutex_unlock(&port->lock); + return ret; + } + dev_vdbg(ac->dev, "%s: session[%d]dsp_buf=%d cpu_buf=%d\n", + __func__, + ac->session, port->dsp_buf, port->cpu_buf); + ret = ((port->dsp_buf != port->cpu_buf) ? 0 : -1); + mutex_unlock(&port->lock); + } + return ret; +} + +static void __q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr, + uint32_t pkt_size, uint32_t cmd_flg, uint32_t stream_id) +{ + dev_vdbg(ac->dev, "%s: pkt_size=%d cmd_flg=%d session=%d stream_id=%d\n", + __func__, pkt_size, cmd_flg, ac->session, stream_id); + mutex_lock(&ac->cmd_lock); + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL", __func__); + mutex_unlock(&ac->cmd_lock); + return; + } + + hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(sizeof(struct apr_hdr)), + APR_PKT_VER); + hdr->src_svc = ((struct apr_svc *)ac->apr)->id; + hdr->src_domain = APR_DOMAIN_APPS; + hdr->dest_svc = APR_SVC_ASM; + hdr->dest_domain = APR_DOMAIN_ADSP; + hdr->src_port = ((ac->session << 8) & 0xFF00) | (stream_id); + hdr->dest_port = ((ac->session << 8) & 0xFF00) | (stream_id); + if (cmd_flg) + q6asm_update_token(&hdr->token, + ac->session, + 0, /* Stream ID is NA */ + 0, /* Buffer index is NA */ + 0, /* Direction flag is NA */ + WAIT_CMD); + + hdr->pkt_size = pkt_size; + mutex_unlock(&ac->cmd_lock); +} + +static void q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr, + uint32_t pkt_size, uint32_t cmd_flg) +{ + __q6asm_add_hdr(ac, hdr, pkt_size, cmd_flg, ac->stream_id); +} + +static void q6asm_stream_add_hdr(struct audio_client *ac, struct apr_hdr *hdr, + uint32_t pkt_size, uint32_t cmd_flg, int32_t stream_id) +{ + __q6asm_add_hdr(ac, hdr, pkt_size, cmd_flg, stream_id); +} + +static void __q6asm_add_hdr_async(struct audio_client *ac, struct apr_hdr *hdr, + uint32_t pkt_size, uint32_t cmd_flg, + uint32_t stream_id, u8 no_wait_flag) +{ + dev_vdbg(ac->dev, "%s: pkt_size = %d, cmd_flg = %d, session = %d stream_id=%d\n", + __func__, pkt_size, cmd_flg, ac->session, stream_id); + hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(sizeof(struct apr_hdr)), + APR_PKT_VER); + if (ac->apr == NULL) { + pr_err("%s: AC APR is NULL", __func__); + return; + } + hdr->src_svc = ((struct apr_svc *)ac->apr)->id; + hdr->src_domain = APR_DOMAIN_APPS; + hdr->dest_svc = APR_SVC_ASM; + hdr->dest_domain = APR_DOMAIN_ADSP; + hdr->src_port = ((ac->session << 8) & 0xFF00) | (stream_id); + hdr->dest_port = ((ac->session << 8) & 0xFF00) | (stream_id); + if (cmd_flg) { + q6asm_update_token(&hdr->token, + ac->session, + 0, /* Stream ID is NA */ + 0, /* Buffer index is NA */ + 0, /* Direction flag is NA */ + no_wait_flag); + + } + hdr->pkt_size = pkt_size; +} + +static void q6asm_add_hdr_async(struct audio_client *ac, struct apr_hdr *hdr, + uint32_t pkt_size, uint32_t cmd_flg) +{ + __q6asm_add_hdr_async(ac, hdr, pkt_size, cmd_flg, + ac->stream_id, WAIT_CMD); +} + +static void q6asm_stream_add_hdr_async(struct audio_client *ac, + struct apr_hdr *hdr, uint32_t pkt_size, + uint32_t cmd_flg, int32_t stream_id) +{ + __q6asm_add_hdr_async(ac, hdr, pkt_size, cmd_flg, + stream_id, NO_WAIT_CMD); +} + +static void q6asm_add_hdr_custom_topology(struct audio_client *ac, + struct apr_hdr *hdr, + uint32_t pkt_size) +{ + pr_debug("%s: pkt_size=%d session=%d\n", + __func__, pkt_size, ac->session); + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return; + } + + mutex_lock(&ac->cmd_lock); + hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(sizeof(struct apr_hdr)), + APR_PKT_VER); + hdr->src_svc = ((struct apr_svc *)ac->apr)->id; + hdr->src_domain = APR_DOMAIN_APPS; + hdr->dest_svc = APR_SVC_ASM; + hdr->dest_domain = APR_DOMAIN_ADSP; + hdr->src_port = ((ac->session << 8) & 0xFF00) | 0x01; + hdr->dest_port = 0; + q6asm_update_token(&hdr->token, + ac->session, + 0, /* Stream ID is NA */ + 0, /* Buffer index is NA */ + 0, /* Direction flag is NA */ + WAIT_CMD); + hdr->pkt_size = pkt_size; + mutex_unlock(&ac->cmd_lock); +} + +static void q6asm_add_mmaphdr(struct audio_client *ac, struct apr_hdr *hdr, + u32 pkt_size, int dir) +{ + pr_debug("%s: pkt size=%d\n", + __func__, pkt_size); + hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + hdr->src_port = 0; + hdr->dest_port = 0; + q6asm_update_token(&hdr->token, + ac->session, + 0, /* Stream ID is NA */ + 0, /* Buffer index is NA */ + dir, + WAIT_CMD); + hdr->pkt_size = pkt_size; +} + +static int __q6asm_open_read(struct audio_client *ac, + uint32_t format, uint16_t bits_per_sample, + uint32_t pcm_format_block_ver, + bool ts_mode) +{ + int rc = 0x00; + struct asm_stream_cmd_open_read_v3 open; + + config_debug_fs_reset_index(); + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: session[%d]\n", __func__, ac->session); + + q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE); + atomic_set(&ac->cmd_state, -1); + open.hdr.opcode = ASM_STREAM_CMD_OPEN_READ_V3; + /* Stream prio : High, provide meta info with encoded frames */ + open.src_endpointype = ASM_END_POINT_DEVICE_MATRIX; + + open.preprocopo_id = q6asm_get_asm_topology_cal(); + open.bits_per_sample = bits_per_sample; + open.mode_flags = 0x0; + + ac->topology = open.preprocopo_id; + ac->app_type = q6asm_get_asm_app_type_cal(); + if (ac->perf_mode == LOW_LATENCY_PCM_MODE) { + open.mode_flags |= ASM_LOW_LATENCY_TX_STREAM_SESSION << + ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ; + } else { + open.mode_flags |= ASM_LEGACY_STREAM_SESSION << + ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ; + } + + switch (format) { + case FORMAT_LINEAR_PCM: + open.mode_flags |= 0x00; + open.enc_cfg_id = q6asm_get_pcm_format_id(pcm_format_block_ver); + if (ts_mode) + open.mode_flags |= ABSOLUTE_TIMESTAMP_ENABLE; + break; + case FORMAT_MPEG4_AAC: + open.mode_flags |= BUFFER_META_ENABLE; + open.enc_cfg_id = ASM_MEDIA_FMT_AAC_V2; + break; + case FORMAT_G711_ALAW_FS: + open.mode_flags |= BUFFER_META_ENABLE; + open.enc_cfg_id = ASM_MEDIA_FMT_G711_ALAW_FS; + break; + case FORMAT_G711_MLAW_FS: + open.mode_flags |= BUFFER_META_ENABLE; + open.enc_cfg_id = ASM_MEDIA_FMT_G711_MLAW_FS; + break; + case FORMAT_V13K: + open.mode_flags |= BUFFER_META_ENABLE; + open.enc_cfg_id = ASM_MEDIA_FMT_V13K_FS; + break; + case FORMAT_EVRC: + open.mode_flags |= BUFFER_META_ENABLE; + open.enc_cfg_id = ASM_MEDIA_FMT_EVRC_FS; + break; + case FORMAT_AMRNB: + open.mode_flags |= BUFFER_META_ENABLE; + open.enc_cfg_id = ASM_MEDIA_FMT_AMRNB_FS; + break; + case FORMAT_AMRWB: + open.mode_flags |= BUFFER_META_ENABLE; + open.enc_cfg_id = ASM_MEDIA_FMT_AMRWB_FS; + break; + default: + pr_err("%s: Invalid format 0x%x\n", + __func__, format); + rc = -EINVAL; + goto fail_cmd; + } + rc = apr_send_pkt(ac->apr, (uint32_t *) &open); + if (rc < 0) { + pr_err("%s: open failed op[0x%x]rc[%d]\n", + __func__, open.hdr.opcode, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for open read\n", + __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + + ac->io_mode |= TUN_READ_IO_MODE; + + return 0; +fail_cmd: + return rc; +} + +int q6asm_open_read(struct audio_client *ac, + uint32_t format) +{ + return __q6asm_open_read(ac, format, 16, + PCM_MEDIA_FORMAT_V2 /*media fmt block ver*/, + false/*ts_mode*/); +} + +int q6asm_open_read_v2(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample) +{ + return __q6asm_open_read(ac, format, bits_per_sample, + PCM_MEDIA_FORMAT_V2 /*media fmt block ver*/, + false/*ts_mode*/); +} + +/* + * asm_open_read_v3 - Opens audio capture session + * + * @ac: Client session handle + * @format: encoder format + * @bits_per_sample: bit width of capture session + */ +int q6asm_open_read_v3(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample) +{ + return __q6asm_open_read(ac, format, bits_per_sample, + PCM_MEDIA_FORMAT_V3/*media fmt block ver*/, + false/*ts_mode*/); +} +EXPORT_SYMBOL(q6asm_open_read_v3); + +/* + * asm_open_read_v4 - Opens audio capture session + * + * @ac: Client session handle + * @format: encoder format + * @bits_per_sample: bit width of capture session + * @ts_mode: timestamp mode + */ +int q6asm_open_read_v4(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample, bool ts_mode) +{ + return __q6asm_open_read(ac, format, bits_per_sample, + PCM_MEDIA_FORMAT_V4 /*media fmt block ver*/, + ts_mode); +} +EXPORT_SYMBOL(q6asm_open_read_v4); + +int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format, + uint32_t passthrough_flag) +{ + int rc = 0; + struct asm_stream_cmd_open_write_compressed open; + + if (ac == NULL) { + pr_err("%s: ac[%pK] NULL\n", __func__, ac); + rc = -EINVAL; + goto fail_cmd; + } + + if (ac->apr == NULL) { + pr_err("%s: APR handle[%pK] NULL\n", __func__, ac->apr); + rc = -EINVAL; + goto fail_cmd; + } + pr_debug("%s: session[%d] wr_format[0x%x]", __func__, ac->session, + format); + + q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE); + open.hdr.opcode = ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED; + atomic_set(&ac->cmd_state, -1); + + switch (format) { + case FORMAT_AC3: + open.fmt_id = ASM_MEDIA_FMT_AC3; + break; + case FORMAT_EAC3: + open.fmt_id = ASM_MEDIA_FMT_EAC3; + break; + case FORMAT_DTS: + open.fmt_id = ASM_MEDIA_FMT_DTS; + break; + case FORMAT_DSD: + open.fmt_id = ASM_MEDIA_FMT_DSD; + break; + case FORMAT_GEN_COMPR: + open.fmt_id = ASM_MEDIA_FMT_GENERIC_COMPRESSED; + break; + case FORMAT_TRUEHD: + open.fmt_id = ASM_MEDIA_FMT_TRUEHD; + break; + case FORMAT_IEC61937: + open.fmt_id = ASM_MEDIA_FMT_IEC; + break; + default: + pr_err("%s: Invalid format[%d]\n", __func__, format); + rc = -EINVAL; + goto fail_cmd; + } + /* Below flag indicates the DSP that Compressed audio input + * stream is not IEC 61937 or IEC 60958 packetizied + */ + if (passthrough_flag == COMPRESSED_PASSTHROUGH || + passthrough_flag == COMPRESSED_PASSTHROUGH_DSD || + passthrough_flag == COMPRESSED_PASSTHROUGH_GEN) { + open.flags = 0x0; + pr_debug("%s: Flag 0 COMPRESSED_PASSTHROUGH\n", __func__); + } else if (passthrough_flag == COMPRESSED_PASSTHROUGH_CONVERT) { + open.flags = 0x8; + pr_debug("%s: Flag 8 - COMPRESSED_PASSTHROUGH_CONVERT\n", + __func__); + } else if (passthrough_flag == COMPRESSED_PASSTHROUGH_IEC61937) { + open.flags = 0x1; + pr_debug("%s: Flag 1 - COMPRESSED_PASSTHROUGH_IEC61937\n", + __func__); + } else { + pr_err("%s: Invalid passthrough type[%d]\n", + __func__, passthrough_flag); + rc = -EINVAL; + goto fail_cmd; + } + rc = apr_send_pkt(ac->apr, (uint32_t *) &open); + if (rc < 0) { + pr_err("%s: open failed op[0x%x]rc[%d]\n", + __func__, open.hdr.opcode, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 1*HZ); + if (!rc) { + pr_err("%s: timeout. waited for OPEN_WRITE_COMPR rc[%d]\n", + __func__, rc); + rc = -ETIMEDOUT; + goto fail_cmd; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + + return 0; + +fail_cmd: + return rc; +} + +static int __q6asm_open_write(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample, uint32_t stream_id, + bool is_gapless_mode, + uint32_t pcm_format_block_ver) +{ + int rc = 0x00; + struct asm_stream_cmd_open_write_v3 open; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + + dev_vdbg(ac->dev, "%s: session[%d] wr_format[0x%x]\n", + __func__, ac->session, format); + + q6asm_stream_add_hdr(ac, &open.hdr, sizeof(open), TRUE, stream_id); + atomic_set(&ac->cmd_state, -1); + /* + * Updated the token field with stream/session for compressed playback + * Platform driver must know the the stream with which the command is + * associated + */ + if (ac->io_mode & COMPRESSED_STREAM_IO) + q6asm_update_token(&open.hdr.token, + ac->session, + stream_id, + 0, /* Buffer index is NA */ + 0, /* Direction flag is NA */ + WAIT_CMD); + + dev_vdbg(ac->dev, "%s: token = 0x%x, stream_id %d, session 0x%x\n", + __func__, open.hdr.token, stream_id, ac->session); + open.hdr.opcode = ASM_STREAM_CMD_OPEN_WRITE_V3; + open.mode_flags = 0x00; + if (ac->perf_mode == ULL_POST_PROCESSING_PCM_MODE) + open.mode_flags |= ASM_ULL_POST_PROCESSING_STREAM_SESSION; + else if (ac->perf_mode == ULTRA_LOW_LATENCY_PCM_MODE) + open.mode_flags |= ASM_ULTRA_LOW_LATENCY_STREAM_SESSION; + else if (ac->perf_mode == LOW_LATENCY_PCM_MODE) + open.mode_flags |= ASM_LOW_LATENCY_STREAM_SESSION; + else { + open.mode_flags |= ASM_LEGACY_STREAM_SESSION; + if (is_gapless_mode) + open.mode_flags |= 1 << ASM_SHIFT_GAPLESS_MODE_FLAG; + } + + /* source endpoint : matrix */ + open.sink_endpointype = ASM_END_POINT_DEVICE_MATRIX; + open.bits_per_sample = bits_per_sample; + + open.postprocopo_id = q6asm_get_asm_topology_cal(); + if (ac->perf_mode != LEGACY_PCM_MODE) + open.postprocopo_id = ASM_STREAM_POSTPROCOPO_ID_NONE; + + pr_debug("%s: perf_mode %d asm_topology 0x%x bps %d\n", __func__, + ac->perf_mode, open.postprocopo_id, open.bits_per_sample); + + /* + * For Gapless playback it will use the same session for next stream, + * So use the same topology + */ + if (!ac->topology) { + ac->topology = open.postprocopo_id; + ac->app_type = q6asm_get_asm_app_type_cal(); + } + switch (format) { + case FORMAT_LINEAR_PCM: + open.dec_fmt_id = q6asm_get_pcm_format_id(pcm_format_block_ver); + break; + case FORMAT_MPEG4_AAC: + open.dec_fmt_id = ASM_MEDIA_FMT_AAC_V2; + break; + case FORMAT_MPEG4_MULTI_AAC: + open.dec_fmt_id = ASM_MEDIA_FMT_AAC_V2; + break; + case FORMAT_WMA_V9: + open.dec_fmt_id = ASM_MEDIA_FMT_WMA_V9_V2; + break; + case FORMAT_WMA_V10PRO: + open.dec_fmt_id = ASM_MEDIA_FMT_WMA_V10PRO_V2; + break; + case FORMAT_MP3: + open.dec_fmt_id = ASM_MEDIA_FMT_MP3; + break; + case FORMAT_AC3: + open.dec_fmt_id = ASM_MEDIA_FMT_AC3; + break; + case FORMAT_EAC3: + open.dec_fmt_id = ASM_MEDIA_FMT_EAC3; + break; + case FORMAT_MP2: + open.dec_fmt_id = ASM_MEDIA_FMT_MP2; + break; + case FORMAT_FLAC: + open.dec_fmt_id = ASM_MEDIA_FMT_FLAC; + break; + case FORMAT_ALAC: + open.dec_fmt_id = ASM_MEDIA_FMT_ALAC; + break; + case FORMAT_VORBIS: + open.dec_fmt_id = ASM_MEDIA_FMT_VORBIS; + break; + case FORMAT_APE: + open.dec_fmt_id = ASM_MEDIA_FMT_APE; + break; + case FORMAT_DSD: + open.dec_fmt_id = ASM_MEDIA_FMT_DSD; + break; + case FORMAT_APTX: + open.dec_fmt_id = ASM_MEDIA_FMT_APTX; + break; + case FORMAT_GEN_COMPR: + open.dec_fmt_id = ASM_MEDIA_FMT_GENERIC_COMPRESSED; + break; + default: + pr_err("%s: Invalid format 0x%x\n", __func__, format); + rc = -EINVAL; + goto fail_cmd; + } + rc = apr_send_pkt(ac->apr, (uint32_t *) &open); + if (rc < 0) { + pr_err("%s: open failed op[0x%x]rc[%d]\n", + __func__, open.hdr.opcode, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for open write\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + ac->io_mode |= TUN_WRITE_IO_MODE; + + return 0; +fail_cmd: + return rc; +} + +int q6asm_open_write(struct audio_client *ac, uint32_t format) +{ + return __q6asm_open_write(ac, format, 16, ac->stream_id, + false /*gapless*/, + PCM_MEDIA_FORMAT_V2 /*pcm_format_block_ver*/); +} + +int q6asm_open_write_v2(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample) +{ + return __q6asm_open_write(ac, format, bits_per_sample, + ac->stream_id, false /*gapless*/, + PCM_MEDIA_FORMAT_V2 /*pcm_format_block_ver*/); +} + +/* + * q6asm_open_write_v3 - Opens audio playback session + * + * @ac: Client session handle + * @format: decoder format + * @bits_per_sample: bit width of playback session + */ +int q6asm_open_write_v3(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample) +{ + return __q6asm_open_write(ac, format, bits_per_sample, + ac->stream_id, false /*gapless*/, + PCM_MEDIA_FORMAT_V3 /*pcm_format_block_ver*/); +} +EXPORT_SYMBOL(q6asm_open_write_v3); + +/* + * q6asm_open_write_v4 - Opens audio playback session + * + * @ac: Client session handle + * @format: decoder format + * @bits_per_sample: bit width of playback session + */ +int q6asm_open_write_v4(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample) +{ + return __q6asm_open_write(ac, format, bits_per_sample, + ac->stream_id, false /*gapless*/, + PCM_MEDIA_FORMAT_V4 /*pcm_format_block_ver*/); +} +EXPORT_SYMBOL(q6asm_open_write_v4); + +int q6asm_stream_open_write_v2(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample, int32_t stream_id, + bool is_gapless_mode) +{ + return __q6asm_open_write(ac, format, bits_per_sample, + stream_id, is_gapless_mode, + PCM_MEDIA_FORMAT_V2 /*pcm_format_block_ver*/); +} + +/* + * q6asm_stream_open_write_v3 - Creates audio stream for playback + * + * @ac: Client session handle + * @format: asm playback format + * @bits_per_sample: bit width of requested stream + * @stream_id: stream id of stream to be associated with this session + * @is_gapless_mode: true if gapless mode needs to be enabled + */ +int q6asm_stream_open_write_v3(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample, int32_t stream_id, + bool is_gapless_mode) +{ + return __q6asm_open_write(ac, format, bits_per_sample, + stream_id, is_gapless_mode, + PCM_MEDIA_FORMAT_V3 /*pcm_format_block_ver*/); +} +EXPORT_SYMBOL(q6asm_stream_open_write_v3); + +/* + * q6asm_stream_open_write_v4 - Creates audio stream for playback + * + * @ac: Client session handle + * @format: asm playback format + * @bits_per_sample: bit width of requested stream + * @stream_id: stream id of stream to be associated with this session + * @is_gapless_mode: true if gapless mode needs to be enabled + */ +int q6asm_stream_open_write_v4(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample, int32_t stream_id, + bool is_gapless_mode) +{ + return __q6asm_open_write(ac, format, bits_per_sample, + stream_id, is_gapless_mode, + PCM_MEDIA_FORMAT_V4 /*pcm_format_block_ver*/); +} +EXPORT_SYMBOL(q6asm_stream_open_write_v4); + +static int __q6asm_open_read_write(struct audio_client *ac, uint32_t rd_format, + uint32_t wr_format, bool is_meta_data_mode, + uint32_t bits_per_sample, + bool overwrite_topology, int topology) +{ + int rc = 0x00; + struct asm_stream_cmd_open_readwrite_v2 open; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: session[%d]\n", __func__, ac->session); + pr_debug("%s: wr_format[0x%x]rd_format[0x%x]\n", + __func__, wr_format, rd_format); + + ac->io_mode |= NT_MODE; + q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE); + atomic_set(&ac->cmd_state, -1); + open.hdr.opcode = ASM_STREAM_CMD_OPEN_READWRITE_V2; + + open.mode_flags = is_meta_data_mode ? BUFFER_META_ENABLE : 0; + open.bits_per_sample = bits_per_sample; + /* source endpoint : matrix */ + open.postprocopo_id = q6asm_get_asm_topology_cal(); + + open.postprocopo_id = overwrite_topology ? + topology : open.postprocopo_id; + ac->topology = open.postprocopo_id; + ac->app_type = q6asm_get_asm_app_type_cal(); + + + switch (wr_format) { + case FORMAT_LINEAR_PCM: + case FORMAT_MULTI_CHANNEL_LINEAR_PCM: + open.dec_fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2; + break; + case FORMAT_MPEG4_AAC: + open.dec_fmt_id = ASM_MEDIA_FMT_AAC_V2; + break; + case FORMAT_MPEG4_MULTI_AAC: + open.dec_fmt_id = ASM_MEDIA_FMT_AAC_V2; + break; + case FORMAT_WMA_V9: + open.dec_fmt_id = ASM_MEDIA_FMT_WMA_V9_V2; + break; + case FORMAT_WMA_V10PRO: + open.dec_fmt_id = ASM_MEDIA_FMT_WMA_V10PRO_V2; + break; + case FORMAT_AMRNB: + open.dec_fmt_id = ASM_MEDIA_FMT_AMRNB_FS; + break; + case FORMAT_AMRWB: + open.dec_fmt_id = ASM_MEDIA_FMT_AMRWB_FS; + break; + case FORMAT_AMR_WB_PLUS: + open.dec_fmt_id = ASM_MEDIA_FMT_AMR_WB_PLUS_V2; + break; + case FORMAT_V13K: + open.dec_fmt_id = ASM_MEDIA_FMT_V13K_FS; + break; + case FORMAT_EVRC: + open.dec_fmt_id = ASM_MEDIA_FMT_EVRC_FS; + break; + case FORMAT_EVRCB: + open.dec_fmt_id = ASM_MEDIA_FMT_EVRCB_FS; + break; + case FORMAT_EVRCWB: + open.dec_fmt_id = ASM_MEDIA_FMT_EVRCWB_FS; + break; + case FORMAT_MP3: + open.dec_fmt_id = ASM_MEDIA_FMT_MP3; + break; + case FORMAT_ALAC: + open.dec_fmt_id = ASM_MEDIA_FMT_ALAC; + break; + case FORMAT_APE: + open.dec_fmt_id = ASM_MEDIA_FMT_APE; + break; + case FORMAT_DSD: + open.dec_fmt_id = ASM_MEDIA_FMT_DSD; + break; + case FORMAT_G711_ALAW_FS: + open.dec_fmt_id = ASM_MEDIA_FMT_G711_ALAW_FS; + break; + case FORMAT_G711_MLAW_FS: + open.dec_fmt_id = ASM_MEDIA_FMT_G711_MLAW_FS; + break; + default: + pr_err("%s: Invalid format 0x%x\n", + __func__, wr_format); + rc = -EINVAL; + goto fail_cmd; + } + + switch (rd_format) { + case FORMAT_LINEAR_PCM: + case FORMAT_MULTI_CHANNEL_LINEAR_PCM: + open.enc_cfg_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2; + break; + case FORMAT_MPEG4_AAC: + open.enc_cfg_id = ASM_MEDIA_FMT_AAC_V2; + break; + case FORMAT_G711_ALAW_FS: + open.enc_cfg_id = ASM_MEDIA_FMT_G711_ALAW_FS; + break; + case FORMAT_G711_MLAW_FS: + open.enc_cfg_id = ASM_MEDIA_FMT_G711_MLAW_FS; + break; + case FORMAT_V13K: + open.enc_cfg_id = ASM_MEDIA_FMT_V13K_FS; + break; + case FORMAT_EVRC: + open.enc_cfg_id = ASM_MEDIA_FMT_EVRC_FS; + break; + case FORMAT_AMRNB: + open.enc_cfg_id = ASM_MEDIA_FMT_AMRNB_FS; + break; + case FORMAT_AMRWB: + open.enc_cfg_id = ASM_MEDIA_FMT_AMRWB_FS; + break; + case FORMAT_ALAC: + open.enc_cfg_id = ASM_MEDIA_FMT_ALAC; + break; + case FORMAT_APE: + open.enc_cfg_id = ASM_MEDIA_FMT_APE; + break; + default: + pr_err("%s: Invalid format 0x%x\n", + __func__, rd_format); + rc = -EINVAL; + goto fail_cmd; + } + dev_vdbg(ac->dev, "%s: rdformat[0x%x]wrformat[0x%x]\n", __func__, + open.enc_cfg_id, open.dec_fmt_id); + + rc = apr_send_pkt(ac->apr, (uint32_t *) &open); + if (rc < 0) { + pr_err("%s: open failed op[0x%x]rc[%d]\n", + __func__, open.hdr.opcode, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for open read-write\n", + __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + + return 0; +fail_cmd: + return rc; +} + +int q6asm_open_read_write(struct audio_client *ac, uint32_t rd_format, + uint32_t wr_format) +{ + return __q6asm_open_read_write(ac, rd_format, wr_format, + true/*meta data mode*/, + 16 /*bits_per_sample*/, + false /*overwrite_topology*/, 0); +} + +int q6asm_open_read_write_v2(struct audio_client *ac, uint32_t rd_format, + uint32_t wr_format, bool is_meta_data_mode, + uint32_t bits_per_sample, bool overwrite_topology, + int topology) +{ + return __q6asm_open_read_write(ac, rd_format, wr_format, + is_meta_data_mode, bits_per_sample, + overwrite_topology, topology); +} + +int q6asm_open_loopback_v2(struct audio_client *ac, uint16_t bits_per_sample) +{ + int rc = 0x00; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: session[%d]\n", __func__, ac->session); + + if (ac->perf_mode == LOW_LATENCY_PCM_MODE) { + struct asm_stream_cmd_open_transcode_loopback_t open; + + q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE); + atomic_set(&ac->cmd_state, -1); + open.hdr.opcode = ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK; + + open.mode_flags = 0; + open.src_endpoint_type = 0; + open.sink_endpoint_type = 0; + open.src_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2; + open.sink_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2; + /* source endpoint : matrix */ + open.audproc_topo_id = q6asm_get_asm_topology_cal(); + + ac->app_type = q6asm_get_asm_app_type_cal(); + if (ac->perf_mode == LOW_LATENCY_PCM_MODE) + open.mode_flags |= ASM_LOW_LATENCY_STREAM_SESSION; + else + open.mode_flags |= ASM_LEGACY_STREAM_SESSION; + ac->topology = open.audproc_topo_id; + open.bits_per_sample = bits_per_sample; + open.reserved = 0; + pr_debug("%s: opening a transcode_loopback with mode_flags =[%d] session[%d]\n", + __func__, open.mode_flags, ac->session); + + rc = apr_send_pkt(ac->apr, (uint32_t *) &open); + if (rc < 0) { + pr_err("%s: open failed op[0x%x]rc[%d]\n", + __func__, open.hdr.opcode, rc); + rc = -EINVAL; + goto fail_cmd; + } + } else {/*if(ac->perf_mode == LEGACY_PCM_MODE)*/ + struct asm_stream_cmd_open_loopback_v2 open; + + q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE); + atomic_set(&ac->cmd_state, -1); + open.hdr.opcode = ASM_STREAM_CMD_OPEN_LOOPBACK_V2; + + open.mode_flags = 0; + open.src_endpointype = 0; + open.sink_endpointype = 0; + /* source endpoint : matrix */ + open.postprocopo_id = q6asm_get_asm_topology_cal(); + + ac->app_type = q6asm_get_asm_app_type_cal(); + ac->topology = open.postprocopo_id; + open.bits_per_sample = bits_per_sample; + open.reserved = 0; + pr_debug("%s: opening a loopback_v2 with mode_flags =[%d] session[%d]\n", + __func__, open.mode_flags, ac->session); + + rc = apr_send_pkt(ac->apr, (uint32_t *) &open); + if (rc < 0) { + pr_err("%s: open failed op[0x%x]rc[%d]\n", + __func__, open.hdr.opcode, rc); + rc = -EINVAL; + goto fail_cmd; + } + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for open_loopback\n", + __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + + return 0; +fail_cmd: + return rc; +} + + +int q6asm_open_transcode_loopback(struct audio_client *ac, + uint16_t bits_per_sample, + uint32_t source_format, uint32_t sink_format) +{ + int rc = 0x00; + struct asm_stream_cmd_open_transcode_loopback_t open; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + + pr_debug("%s: session[%d]\n", __func__, ac->session); + + q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE); + atomic_set(&ac->cmd_state, -1); + open.hdr.opcode = ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK; + + open.mode_flags = 0; + open.src_endpoint_type = 0; + open.sink_endpoint_type = 0; + switch (source_format) { + case FORMAT_LINEAR_PCM: + case FORMAT_MULTI_CHANNEL_LINEAR_PCM: + open.src_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3; + break; + case FORMAT_AC3: + open.src_format_id = ASM_MEDIA_FMT_AC3; + break; + case FORMAT_EAC3: + open.src_format_id = ASM_MEDIA_FMT_EAC3; + break; + default: + pr_err("%s: Unsupported src fmt [%d]\n", + __func__, source_format); + return -EINVAL; + } + switch (sink_format) { + case FORMAT_LINEAR_PCM: + case FORMAT_MULTI_CHANNEL_LINEAR_PCM: + open.sink_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3; + break; + default: + pr_err("%s: Unsupported sink fmt [%d]\n", + __func__, sink_format); + return -EINVAL; + } + + /* source endpoint : matrix */ + open.audproc_topo_id = q6asm_get_asm_topology_cal(); + + ac->app_type = q6asm_get_asm_app_type_cal(); + if (ac->perf_mode == LOW_LATENCY_PCM_MODE) + open.mode_flags |= ASM_LOW_LATENCY_STREAM_SESSION; + else + open.mode_flags |= ASM_LEGACY_STREAM_SESSION; + ac->topology = open.audproc_topo_id; + open.bits_per_sample = bits_per_sample; + open.reserved = 0; + pr_debug("%s: opening a transcode_loopback with mode_flags =[%d] session[%d]\n", + __func__, open.mode_flags, ac->session); + + rc = apr_send_pkt(ac->apr, (uint32_t *) &open); + if (rc < 0) { + pr_err("%s: open failed op[0x%x]rc[%d]\n", + __func__, open.hdr.opcode, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for open_transcode_loopback\n", + __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + + return 0; +fail_cmd: + return rc; +} + +static +int q6asm_set_shared_circ_buff(struct audio_client *ac, + struct asm_stream_cmd_open_shared_io *open, + int bufsz, int bufcnt, + int dir) +{ + struct audio_buffer *buf_circ; + int bytes_to_alloc, rc; + size_t len; + + buf_circ = kzalloc(sizeof(struct audio_buffer), GFP_KERNEL); + + if (!buf_circ) { + rc = -ENOMEM; + goto done; + } + + mutex_lock(&ac->cmd_lock); + + ac->port[dir].buf = buf_circ; + + bytes_to_alloc = bufsz * bufcnt; + bytes_to_alloc = PAGE_ALIGN(bytes_to_alloc); + + rc = msm_audio_ion_alloc("audio_client", &buf_circ->client, + &buf_circ->handle, bytes_to_alloc, + (ion_phys_addr_t *)&buf_circ->phys, + &len, &buf_circ->data); + + if (rc) { + pr_err("%s: Audio ION alloc is failed, rc = %d\n", __func__, + rc); + mutex_unlock(&ac->cmd_lock); + kfree(buf_circ); + goto done; + } + + buf_circ->used = dir ^ 1; + buf_circ->size = bytes_to_alloc; + buf_circ->actual_size = bytes_to_alloc; + memset(buf_circ->data, 0, buf_circ->actual_size); + + ac->port[dir].max_buf_cnt = 1; + + open->shared_circ_buf_mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL; + open->shared_circ_buf_num_regions = 1; + open->shared_circ_buf_property_flag = 0x00; + open->shared_circ_buf_start_phy_addr_lsw = + lower_32_bits(buf_circ->phys); + open->shared_circ_buf_start_phy_addr_msw = + msm_audio_populate_upper_32_bits(buf_circ->phys); + open->shared_circ_buf_size = bufsz * bufcnt; + + open->map_region_circ_buf.shm_addr_lsw = lower_32_bits(buf_circ->phys); + open->map_region_circ_buf.shm_addr_msw = + msm_audio_populate_upper_32_bits(buf_circ->phys); + open->map_region_circ_buf.mem_size_bytes = bytes_to_alloc; + + mutex_unlock(&ac->cmd_lock); +done: + return rc; +} + + +static +int q6asm_set_shared_pos_buff(struct audio_client *ac, + struct asm_stream_cmd_open_shared_io *open, + int dir) +{ + struct audio_buffer *buf_pos = &ac->shared_pos_buf; + int rc; + size_t len; + int bytes_to_alloc = sizeof(struct asm_shared_position_buffer); + + mutex_lock(&ac->cmd_lock); + + bytes_to_alloc = PAGE_ALIGN(bytes_to_alloc); + + rc = msm_audio_ion_alloc("audio_client", &buf_pos->client, + &buf_pos->handle, bytes_to_alloc, + (ion_phys_addr_t *)&buf_pos->phys, &len, + &buf_pos->data); + + if (rc) { + pr_err("%s: Audio pos buf ION alloc is failed, rc = %d\n", + __func__, rc); + goto done; + } + + buf_pos->used = dir ^ 1; + buf_pos->size = bytes_to_alloc; + buf_pos->actual_size = bytes_to_alloc; + + open->shared_pos_buf_mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL; + open->shared_pos_buf_num_regions = 1; + open->shared_pos_buf_property_flag = 0x00; + open->shared_pos_buf_phy_addr_lsw = lower_32_bits(buf_pos->phys); + open->shared_pos_buf_phy_addr_msw = + msm_audio_populate_upper_32_bits(buf_pos->phys); + + open->map_region_pos_buf.shm_addr_lsw = lower_32_bits(buf_pos->phys); + open->map_region_pos_buf.shm_addr_msw = + msm_audio_populate_upper_32_bits(buf_pos->phys); + open->map_region_pos_buf.mem_size_bytes = bytes_to_alloc; + +done: + mutex_unlock(&ac->cmd_lock); + return rc; +} + +/* + * q6asm_open_shared_io: Open an ASM session for pull mode (playback) + * or push mode (capture). + * parameters + * config - session parameters (channels, bits_per_sample, sr) + * dir - stream direction (IN for playback, OUT for capture) + * returns 0 if successful, error code otherwise + */ +int q6asm_open_shared_io(struct audio_client *ac, + struct shared_io_config *config, + int dir) +{ + struct asm_stream_cmd_open_shared_io *open; + u8 *channel_mapping; + int i, size_of_open, num_watermarks, bufsz, bufcnt, rc, flags = 0; + + if (!ac || !config) + return -EINVAL; + + bufsz = config->bufsz; + bufcnt = config->bufcnt; + num_watermarks = 0; + + ac->config = *config; + + if (ac->session <= 0 || ac->session > SESSION_MAX) { + pr_err("%s: Session %d is out of bounds\n", + __func__, ac->session); + return -EINVAL; + } + + size_of_open = sizeof(struct asm_stream_cmd_open_shared_io) + + (sizeof(struct asm_shared_watermark_level) * num_watermarks); + + open = kzalloc(PAGE_ALIGN(size_of_open), GFP_KERNEL); + if (!open) + return -ENOMEM; + + q6asm_stream_add_hdr(ac, &open->hdr, size_of_open, TRUE, + ac->stream_id); + + atomic_set(&ac->cmd_state, 1); + + pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x, perf %d\n", + __func__, open->hdr.token, ac->stream_id, ac->session, + ac->perf_mode); + + open->hdr.opcode = + dir == IN ? ASM_STREAM_CMD_OPEN_PULL_MODE_WRITE : + ASM_STREAM_CMD_OPEN_PUSH_MODE_READ; + + pr_debug("%s perf_mode %d\n", __func__, ac->perf_mode); + if (dir == IN) + if (ac->perf_mode == ULL_POST_PROCESSING_PCM_MODE) + flags = 4 << ASM_SHIFT_STREAM_PERF_FLAG_PULL_MODE_WRITE; + else if (ac->perf_mode == ULTRA_LOW_LATENCY_PCM_MODE) + flags = 2 << ASM_SHIFT_STREAM_PERF_FLAG_PULL_MODE_WRITE; + else if (ac->perf_mode == LOW_LATENCY_PCM_MODE) + flags = 1 << ASM_SHIFT_STREAM_PERF_FLAG_PULL_MODE_WRITE; + else + pr_err("Invalid perf mode for pull write\n"); + else + if (ac->perf_mode == LOW_LATENCY_PCM_MODE) + flags = ASM_LOW_LATENCY_TX_STREAM_SESSION << + ASM_SHIFT_STREAM_PERF_FLAG_PUSH_MODE_READ; + else + pr_err("Invalid perf mode for push read\n"); + + if (flags == 0) { + pr_err("%s: Invalid mode[%d]\n", __func__, + ac->perf_mode); + kfree(open); + return -EINVAL; + + } + + pr_debug("open.mode_flags = 0x%x\n", flags); + open->mode_flags = flags; + open->endpoint_type = ASM_END_POINT_DEVICE_MATRIX; + open->topo_bits_per_sample = config->bits_per_sample; + + open->topo_id = q6asm_get_asm_topology_cal(); + + if (config->format == FORMAT_LINEAR_PCM) + open->fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3; + else { + pr_err("%s: Invalid format[%d]\n", __func__, config->format); + rc = -EINVAL; + goto done; + } + + if (ac->port[dir].buf) { + pr_err("%s: Buffer already allocated\n", __func__); + rc = -EINVAL; + goto done; + } + + rc = q6asm_set_shared_circ_buff(ac, open, bufsz, bufcnt, dir); + + if (rc) + goto done; + + ac->port[dir].tmp_hdl = 0; + + rc = q6asm_set_shared_pos_buff(ac, open, dir); + + if (rc) + goto done; + + /* asm_multi_channel_pcm_fmt_blk_v3 */ + open->fmt.num_channels = config->channels; + open->fmt.bits_per_sample = config->bits_per_sample; + open->fmt.sample_rate = config->rate; + open->fmt.is_signed = 1; + open->fmt.sample_word_size = config->sample_word_size; + + channel_mapping = open->fmt.channel_mapping; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + + rc = q6asm_map_channels(channel_mapping, config->channels, false); + if (rc) { + pr_err("%s: Map channels failed, ret: %d\n", __func__, rc); + goto done; + } + + open->num_watermark_levels = num_watermarks; + for (i = 0; i < num_watermarks; i++) { + open->watermark[i].watermark_level_bytes = i * + ((bufsz * bufcnt) / num_watermarks); + pr_debug("%s: Watermark level set for %i\n", + __func__, + open->watermark[i].watermark_level_bytes); + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) open); + if (rc < 0) { + pr_err("%s: Open failed op[0x%x]rc[%d]\n", + __func__, open->hdr.opcode, rc); + goto done; + } + + pr_debug("%s: sent open apr pkt\n", __func__); + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) <= 0), 5*HZ); + if (!rc) { + pr_err("%s: Timeout. Waited for open write apr pkt rc[%d]\n", + __func__, rc); + rc = -ETIMEDOUT; + goto done; + } + + if (atomic_read(&ac->cmd_state) < 0) { + pr_err("%s: DSP returned error [%d]\n", __func__, + atomic_read(&ac->cmd_state)); + rc = -EINVAL; + goto done; + } + + ac->io_mode |= TUN_WRITE_IO_MODE; + rc = 0; +done: + kfree(open); + return rc; +} +EXPORT_SYMBOL(q6asm_open_shared_io); + +/* + * q6asm_shared_io_buf: Returns handle to the shared circular buffer being + * used for pull/push mode. + * parameters + * dir - used to identify input/output port + * returns buffer handle + */ +struct audio_buffer *q6asm_shared_io_buf(struct audio_client *ac, + int dir) +{ + struct audio_port_data *port; + + if (!ac) { + pr_err("%s: ac is null\n", __func__); + return NULL; + } + port = &ac->port[dir]; + return port->buf; +} +EXPORT_SYMBOL(q6asm_shared_io_buf); + +/* + * q6asm_shared_io_free: Frees memory allocated for a pull/push session + * parameters + * dir - port direction + * returns 0 if successful, error otherwise + */ +int q6asm_shared_io_free(struct audio_client *ac, int dir) +{ + struct audio_port_data *port; + + if (!ac) { + pr_err("%s: audio client is null\n", __func__); + return -EINVAL; + } + port = &ac->port[dir]; + mutex_lock(&ac->cmd_lock); + if (port->buf && port->buf->data) { + msm_audio_ion_free(port->buf->client, port->buf->handle); + port->buf->client = NULL; + port->buf->handle = NULL; + port->max_buf_cnt = 0; + kfree(port->buf); + port->buf = NULL; + } + if (ac->shared_pos_buf.data) { + msm_audio_ion_free(ac->shared_pos_buf.client, + ac->shared_pos_buf.handle); + ac->shared_pos_buf.client = NULL; + ac->shared_pos_buf.handle = NULL; + } + mutex_unlock(&ac->cmd_lock); + return 0; +} +EXPORT_SYMBOL(q6asm_shared_io_free); + +/* + * q6asm_get_shared_pos: Returns current read index/write index as observed + * by the DSP. Note that this is an offset and iterates from [0,BUF_SIZE - 1] + * parameters - (all output) + * read_index - offset + * wall_clk_msw1 - ADSP wallclock msw + * wall_clk_lsw1 - ADSP wallclock lsw + * returns 0 if successful, -EAGAIN if DSP failed to update after some + * retries + */ +int q6asm_get_shared_pos(struct audio_client *ac, uint32_t *read_index, + uint32_t *wall_clk_msw1, uint32_t *wall_clk_lsw1) +{ + struct asm_shared_position_buffer *pos_buf; + uint32_t frame_cnt1, frame_cnt2; + int i, j; + + if (!ac) { + pr_err("%s: audio client is null\n", __func__); + return -EINVAL; + } + + pos_buf = ac->shared_pos_buf.data; + + /* always try to get the latest update in the shared pos buffer */ + for (i = 0; i < 2; i++) { + /* retry until there is an update from DSP */ + for (j = 0; j < 5; j++) { + frame_cnt1 = pos_buf->frame_counter; + if (frame_cnt1 != 0) + break; + } + + *wall_clk_msw1 = pos_buf->wall_clock_us_msw; + *wall_clk_lsw1 = pos_buf->wall_clock_us_lsw; + *read_index = pos_buf->index; + frame_cnt2 = pos_buf->frame_counter; + + if (frame_cnt1 != frame_cnt2) + continue; + return 0; + } + pr_err("%s out of tries trying to get a good read, try again\n", + __func__); + return -EAGAIN; +} + +int q6asm_run(struct audio_client *ac, uint32_t flags, + uint32_t msw_ts, uint32_t lsw_ts) +{ + struct asm_session_cmd_run_v2 run; + int rc; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: session[%d]\n", __func__, ac->session); + + q6asm_add_hdr(ac, &run.hdr, sizeof(run), TRUE); + atomic_set(&ac->cmd_state, -1); + + run.hdr.opcode = ASM_SESSION_CMD_RUN_V2; + run.flags = flags; + run.time_lsw = lsw_ts; + run.time_msw = msw_ts; + + config_debug_fs_run(); + + rc = apr_send_pkt(ac->apr, (uint32_t *) &run); + if (rc < 0) { + pr_err("%s: Commmand run failed[%d]", + __func__, rc); + rc = -EINVAL; + goto fail_cmd; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for run success", + __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + + return 0; +fail_cmd: + return rc; +} + +static int __q6asm_run_nowait(struct audio_client *ac, uint32_t flags, + uint32_t msw_ts, uint32_t lsw_ts, uint32_t stream_id) +{ + struct asm_session_cmd_run_v2 run; + int rc; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: session[%d]\n", __func__, ac->session); + + q6asm_stream_add_hdr_async(ac, &run.hdr, sizeof(run), TRUE, stream_id); + atomic_set(&ac->cmd_state, 1); + run.hdr.opcode = ASM_SESSION_CMD_RUN_V2; + run.flags = flags; + run.time_lsw = lsw_ts; + run.time_msw = msw_ts; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &run); + if (rc < 0) { + pr_err("%s: Commmand run failed[%d]", __func__, rc); + return -EINVAL; + } + return 0; +} + +int q6asm_run_nowait(struct audio_client *ac, uint32_t flags, + uint32_t msw_ts, uint32_t lsw_ts) +{ + return __q6asm_run_nowait(ac, flags, msw_ts, lsw_ts, ac->stream_id); +} + +int q6asm_stream_run_nowait(struct audio_client *ac, uint32_t flags, + uint32_t msw_ts, uint32_t lsw_ts, uint32_t stream_id) +{ + return __q6asm_run_nowait(ac, flags, msw_ts, lsw_ts, stream_id); +} + +int q6asm_enc_cfg_blk_aac(struct audio_client *ac, + uint32_t frames_per_buf, + uint32_t sample_rate, uint32_t channels, + uint32_t bit_rate, uint32_t mode, uint32_t format) +{ + struct asm_aac_enc_cfg_v2 enc_cfg; + int rc = 0; + + pr_debug("%s: session[%d]frames[%d]SR[%d]ch[%d]bitrate[%d]mode[%d] format[%d]\n", + __func__, ac->session, frames_per_buf, + sample_rate, channels, bit_rate, mode, format); + + q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE); + atomic_set(&ac->cmd_state, -1); + + enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2; + enc_cfg.encdec.param_size = sizeof(struct asm_aac_enc_cfg_v2) - + sizeof(struct asm_stream_cmd_set_encdec_param); + enc_cfg.encblk.frames_per_buf = frames_per_buf; + enc_cfg.encblk.enc_cfg_blk_size = enc_cfg.encdec.param_size - + sizeof(struct asm_enc_cfg_blk_param_v2); + enc_cfg.bit_rate = bit_rate; + enc_cfg.enc_mode = mode; + enc_cfg.aac_fmt_flag = format; + enc_cfg.channel_cfg = channels; + enc_cfg.sample_rate = sample_rate; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg); + if (rc < 0) { + pr_err("%s: Comamnd %d failed %d\n", + __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for FORMAT_UPDATE\n", + __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_enc_cfg_blk_g711(struct audio_client *ac, + uint32_t frames_per_buf, + uint32_t sample_rate) +{ + struct asm_g711_enc_cfg_v2 enc_cfg; + int rc = 0; + + pr_debug("%s: session[%d]frames[%d]SR[%d]\n", + __func__, ac->session, frames_per_buf, + sample_rate); + + q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE); + atomic_set(&ac->cmd_state, -1); + + enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2; + enc_cfg.encdec.param_size = sizeof(struct asm_g711_enc_cfg_v2) - + sizeof(struct asm_stream_cmd_set_encdec_param); + enc_cfg.encblk.frames_per_buf = frames_per_buf; + enc_cfg.encblk.enc_cfg_blk_size = enc_cfg.encdec.param_size - + sizeof(struct asm_enc_cfg_blk_param_v2); + enc_cfg.sample_rate = sample_rate; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg); + if (rc < 0) { + pr_err("%s: Comamnd %d failed %d\n", + __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for FORMAT_UPDATE\n", + __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_set_encdec_chan_map(struct audio_client *ac, + uint32_t num_channels) +{ + struct asm_dec_out_chan_map_param chan_map; + u8 *channel_mapping; + int rc = 0; + + pr_debug("%s: Session %d, num_channels = %d\n", + __func__, ac->session, num_channels); + q6asm_add_hdr(ac, &chan_map.hdr, sizeof(chan_map), TRUE); + atomic_set(&ac->cmd_state, -1); + chan_map.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + chan_map.encdec.param_id = ASM_PARAM_ID_DEC_OUTPUT_CHAN_MAP; + chan_map.encdec.param_size = sizeof(struct asm_dec_out_chan_map_param) - + (sizeof(struct apr_hdr) + + sizeof(struct asm_stream_cmd_set_encdec_param)); + chan_map.num_channels = num_channels; + channel_mapping = chan_map.channel_mapping; + memset(channel_mapping, PCM_CHANNEL_NULL, MAX_CHAN_MAP_CHANNELS); + + if (q6asm_map_channels(channel_mapping, num_channels, false)) { + pr_err("%s: map channels failed %d\n", __func__, num_channels); + return -EINVAL; + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &chan_map); + if (rc < 0) { + pr_err("%s: Command opcode[0x%x]paramid[0x%x] failed %d\n", + __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM, + ASM_PARAM_ID_DEC_OUTPUT_CHAN_MAP, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout opcode[0x%x]\n", __func__, + chan_map.hdr.opcode); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +/* + * q6asm_enc_cfg_blk_pcm_v4 - sends encoder configuration parameters + * + * @ac: Client session handle + * @rate: sample rate + * @channels: number of channels + * @bits_per_sample: bit width of encoder session + * @use_default_chmap: true if default channel map to be used + * @use_back_flavor: to configure back left and right channel + * @channel_map: input channel map + * @sample_word_size: Size in bits of the word that holds a sample of a channel + * @endianness: endianness of the pcm data + * @mode: Mode to provide additional info about the pcm input data + */ +int q6asm_enc_cfg_blk_pcm_v4(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, bool use_default_chmap, + bool use_back_flavor, u8 *channel_map, + uint16_t sample_word_size, uint16_t endianness, + uint16_t mode) +{ + struct asm_multi_channel_pcm_enc_cfg_v4 enc_cfg; + struct asm_enc_cfg_blk_param_v2 enc_fg_blk; + u8 *channel_mapping; + u32 frames_per_buf = 0; + int rc; + + if (!use_default_chmap && (channel_map == NULL)) { + pr_err("%s: No valid chan map and can't use default\n", + __func__); + rc = -EINVAL; + goto fail_cmd; + } + + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, + ac->session, rate, channels, + bits_per_sample, sample_word_size); + + memset(&enc_cfg, 0, sizeof(enc_cfg)); + q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE); + atomic_set(&ac->cmd_state, -1); + enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2; + enc_cfg.encdec.param_size = sizeof(enc_cfg) - sizeof(enc_cfg.hdr) - + sizeof(enc_cfg.encdec); + enc_cfg.encblk.frames_per_buf = frames_per_buf; + enc_cfg.encblk.enc_cfg_blk_size = enc_cfg.encdec.param_size - + sizeof(enc_fg_blk); + enc_cfg.num_channels = channels; + enc_cfg.bits_per_sample = bits_per_sample; + enc_cfg.sample_rate = rate; + enc_cfg.is_signed = 1; + enc_cfg.sample_word_size = sample_word_size; + enc_cfg.endianness = endianness; + enc_cfg.mode = mode; + channel_mapping = enc_cfg.channel_mapping; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + + if (use_default_chmap) { + pr_debug("%s: setting default channel map for %d channels", + __func__, channels); + if (q6asm_map_channels(channel_mapping, channels, + use_back_flavor)) { + pr_err("%s: map channels failed %d\n", + __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + } else { + pr_debug("%s: Using pre-defined channel map", __func__); + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL); + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg); + if (rc < 0) { + pr_err("%s: Command open failed %d\n", __func__, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout opcode[0x%x]\n", + __func__, enc_cfg.hdr.opcode); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} +EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_v4); + +/* + * q6asm_enc_cfg_blk_pcm_v3 - sends encoder configuration parameters + * + * @ac: Client session handle + * @rate: sample rate + * @channels: number of channels + * @bits_per_sample: bit width of encoder session + * @use_default_chmap: true if default channel map to be used + * @use_back_flavor: to configure back left and right channel + * @channel_map: input channel map + * @sample_word_size: Size in bits of the word that holds a sample of a channel + */ +int q6asm_enc_cfg_blk_pcm_v3(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, bool use_default_chmap, + bool use_back_flavor, u8 *channel_map, + uint16_t sample_word_size) +{ + struct asm_multi_channel_pcm_enc_cfg_v3 enc_cfg; + struct asm_enc_cfg_blk_param_v2 enc_fg_blk; + u8 *channel_mapping; + u32 frames_per_buf = 0; + int rc; + + if (!use_default_chmap && (channel_map == NULL)) { + pr_err("%s: No valid chan map and can't use default\n", + __func__); + rc = -EINVAL; + goto fail_cmd; + } + + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, + ac->session, rate, channels, + bits_per_sample, sample_word_size); + + memset(&enc_cfg, 0, sizeof(enc_cfg)); + q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE); + atomic_set(&ac->cmd_state, -1); + enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2; + enc_cfg.encdec.param_size = sizeof(enc_cfg) - sizeof(enc_cfg.hdr) - + sizeof(enc_cfg.encdec); + enc_cfg.encblk.frames_per_buf = frames_per_buf; + enc_cfg.encblk.enc_cfg_blk_size = enc_cfg.encdec.param_size - + sizeof(enc_fg_blk); + enc_cfg.num_channels = channels; + enc_cfg.bits_per_sample = bits_per_sample; + enc_cfg.sample_rate = rate; + enc_cfg.is_signed = 1; + enc_cfg.sample_word_size = sample_word_size; + channel_mapping = enc_cfg.channel_mapping; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + + if (use_default_chmap) { + pr_debug("%s: setting default channel map for %d channels", + __func__, channels); + if (q6asm_map_channels(channel_mapping, channels, + use_back_flavor)) { + pr_err("%s: map channels failed %d\n", + __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + } else { + pr_debug("%s: Using pre-defined channel map", __func__); + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL); + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg); + if (rc < 0) { + pr_err("%s: Comamnd open failed %d\n", __func__, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout opcode[0x%x]\n", + __func__, enc_cfg.hdr.opcode); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} +EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_v3); + +int q6asm_enc_cfg_blk_pcm_v2(struct audio_client *ac, + uint32_t rate, uint32_t channels, uint16_t bits_per_sample, + bool use_default_chmap, bool use_back_flavor, u8 *channel_map) +{ + struct asm_multi_channel_pcm_enc_cfg_v2 enc_cfg; + u8 *channel_mapping; + u32 frames_per_buf = 0; + + int rc = 0; + + if (!use_default_chmap && (channel_map == NULL)) { + pr_err("%s: No valid chan map and can't use default\n", + __func__); + return -EINVAL; + } + + pr_debug("%s: Session %d, rate = %d, channels = %d\n", __func__, + ac->session, rate, channels); + + q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE); + atomic_set(&ac->cmd_state, -1); + enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2; + enc_cfg.encdec.param_size = sizeof(enc_cfg) - sizeof(enc_cfg.hdr) - + sizeof(enc_cfg.encdec); + enc_cfg.encblk.frames_per_buf = frames_per_buf; + enc_cfg.encblk.enc_cfg_blk_size = enc_cfg.encdec.param_size - + sizeof(struct asm_enc_cfg_blk_param_v2); + + enc_cfg.num_channels = channels; + enc_cfg.bits_per_sample = bits_per_sample; + enc_cfg.sample_rate = rate; + enc_cfg.is_signed = 1; + channel_mapping = enc_cfg.channel_mapping; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + + if (use_default_chmap) { + pr_debug("%s: setting default channel map for %d channels", + __func__, channels); + if (q6asm_map_channels(channel_mapping, channels, + use_back_flavor)) { + pr_err("%s: map channels failed %d\n", + __func__, channels); + return -EINVAL; + } + } else { + pr_debug("%s: Using pre-defined channel map", __func__); + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL); + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg); + if (rc < 0) { + pr_err("%s: Comamnd open failed %d\n", __func__, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout opcode[0x%x]\n", + __func__, enc_cfg.hdr.opcode); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +static int __q6asm_enc_cfg_blk_pcm_v4(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode) +{ + return q6asm_enc_cfg_blk_pcm_v4(ac, rate, channels, + bits_per_sample, true, false, NULL, + sample_word_size, endianness, mode); +} + +static int __q6asm_enc_cfg_blk_pcm_v3(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, + uint16_t sample_word_size) +{ + return q6asm_enc_cfg_blk_pcm_v3(ac, rate, channels, + bits_per_sample, true, false, NULL, + sample_word_size); +} + +static int __q6asm_enc_cfg_blk_pcm(struct audio_client *ac, + uint32_t rate, uint32_t channels, uint16_t bits_per_sample) +{ + return q6asm_enc_cfg_blk_pcm_v2(ac, rate, channels, + bits_per_sample, true, false, NULL); +} + +int q6asm_enc_cfg_blk_pcm(struct audio_client *ac, + uint32_t rate, uint32_t channels) +{ + return __q6asm_enc_cfg_blk_pcm(ac, rate, channels, 16); +} + +int q6asm_enc_cfg_blk_pcm_format_support(struct audio_client *ac, + uint32_t rate, uint32_t channels, uint16_t bits_per_sample) +{ + return __q6asm_enc_cfg_blk_pcm(ac, rate, channels, bits_per_sample); +} + +/* + * q6asm_enc_cfg_blk_pcm_format_support_v3 - sends encoder configuration + * parameters + * + * @ac: Client session handle + * @rate: sample rate + * @channels: number of channels + * @bits_per_sample: bit width of encoder session + * @sample_word_size: Size in bits of the word that holds a sample of a channel + */ +int q6asm_enc_cfg_blk_pcm_format_support_v3(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, + uint16_t sample_word_size) +{ + return __q6asm_enc_cfg_blk_pcm_v3(ac, rate, channels, + bits_per_sample, sample_word_size); +} +EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_format_support_v3); + +/* + * q6asm_enc_cfg_blk_pcm_format_support_v4 - sends encoder configuration + * parameters + * + * @ac: Client session handle + * @rate: sample rate + * @channels: number of channels + * @bits_per_sample: bit width of encoder session + * @sample_word_size: Size in bits of the word that holds a sample of a channel + * @endianness: endianness of the pcm data + * @mode: Mode to provide additional info about the pcm input data + */ +int q6asm_enc_cfg_blk_pcm_format_support_v4(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode) +{ + return __q6asm_enc_cfg_blk_pcm_v4(ac, rate, channels, + bits_per_sample, sample_word_size, + endianness, mode); +} +EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_format_support_v4); + +int q6asm_enc_cfg_blk_pcm_native(struct audio_client *ac, + uint32_t rate, uint32_t channels) +{ + struct asm_multi_channel_pcm_enc_cfg_v2 enc_cfg; + u8 *channel_mapping; + u32 frames_per_buf = 0; + + int rc = 0; + + pr_debug("%s: Session %d, rate = %d, channels = %d\n", __func__, + ac->session, rate, channels); + + q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE); + atomic_set(&ac->cmd_state, -1); + enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2; + enc_cfg.encdec.param_size = sizeof(enc_cfg) - sizeof(enc_cfg.hdr) - + sizeof(enc_cfg.encdec); + enc_cfg.encblk.frames_per_buf = frames_per_buf; + enc_cfg.encblk.enc_cfg_blk_size = enc_cfg.encdec.param_size - + sizeof(struct asm_enc_cfg_blk_param_v2); + + enc_cfg.num_channels = 0;/*channels;*/ + enc_cfg.bits_per_sample = 16; + enc_cfg.sample_rate = 0;/*rate;*/ + enc_cfg.is_signed = 1; + channel_mapping = enc_cfg.channel_mapping; + + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + + if (q6asm_map_channels(channel_mapping, channels, false)) { + pr_err("%s: map channels failed %d\n", __func__, channels); + return -EINVAL; + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg); + if (rc < 0) { + pr_err("%s: Comamnd open failed %d\n", __func__, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout opcode[0x%x]\n", + __func__, enc_cfg.hdr.opcode); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, + bool use_back_flavor) +{ + u8 *lchannel_mapping; + + lchannel_mapping = channel_mapping; + pr_debug("%s: channels passed: %d\n", __func__, channels); + if (channels == 1) { + lchannel_mapping[0] = PCM_CHANNEL_FC; + } else if (channels == 2) { + lchannel_mapping[0] = PCM_CHANNEL_FL; + lchannel_mapping[1] = PCM_CHANNEL_FR; + } else if (channels == 3) { + lchannel_mapping[0] = PCM_CHANNEL_FL; + lchannel_mapping[1] = PCM_CHANNEL_FR; + lchannel_mapping[2] = PCM_CHANNEL_FC; + } else if (channels == 4) { + lchannel_mapping[0] = PCM_CHANNEL_FL; + lchannel_mapping[1] = PCM_CHANNEL_FR; + lchannel_mapping[2] = use_back_flavor ? + PCM_CHANNEL_LB : PCM_CHANNEL_LS; + lchannel_mapping[3] = use_back_flavor ? + PCM_CHANNEL_RB : PCM_CHANNEL_RS; + } else if (channels == 5) { + lchannel_mapping[0] = PCM_CHANNEL_FL; + lchannel_mapping[1] = PCM_CHANNEL_FR; + lchannel_mapping[2] = PCM_CHANNEL_FC; + lchannel_mapping[3] = use_back_flavor ? + PCM_CHANNEL_LB : PCM_CHANNEL_LS; + lchannel_mapping[4] = use_back_flavor ? + PCM_CHANNEL_RB : PCM_CHANNEL_RS; + } else if (channels == 6) { + lchannel_mapping[0] = PCM_CHANNEL_FL; + lchannel_mapping[1] = PCM_CHANNEL_FR; + lchannel_mapping[2] = PCM_CHANNEL_FC; + lchannel_mapping[3] = PCM_CHANNEL_LFE; + lchannel_mapping[4] = use_back_flavor ? + PCM_CHANNEL_LB : PCM_CHANNEL_LS; + lchannel_mapping[5] = use_back_flavor ? + PCM_CHANNEL_RB : PCM_CHANNEL_RS; + } else if (channels == 7) { + /* + * Configured for 5.1 channel mapping + 1 channel for debug + * Can be customized based on DSP. + */ + lchannel_mapping[0] = PCM_CHANNEL_FL; + lchannel_mapping[1] = PCM_CHANNEL_FR; + lchannel_mapping[2] = PCM_CHANNEL_FC; + lchannel_mapping[3] = PCM_CHANNEL_LFE; + lchannel_mapping[4] = use_back_flavor ? + PCM_CHANNEL_LB : PCM_CHANNEL_LS; + lchannel_mapping[5] = use_back_flavor ? + PCM_CHANNEL_RB : PCM_CHANNEL_RS; + lchannel_mapping[6] = PCM_CHANNEL_CS; + } else if (channels == 8) { + lchannel_mapping[0] = PCM_CHANNEL_FL; + lchannel_mapping[1] = PCM_CHANNEL_FR; + lchannel_mapping[2] = PCM_CHANNEL_FC; + lchannel_mapping[3] = PCM_CHANNEL_LFE; + lchannel_mapping[4] = PCM_CHANNEL_LB; + lchannel_mapping[5] = PCM_CHANNEL_RB; + lchannel_mapping[6] = PCM_CHANNEL_LS; + lchannel_mapping[7] = PCM_CHANNEL_RS; + } else { + pr_err("%s: ERROR.unsupported num_ch = %u\n", + __func__, channels); + return -EINVAL; + } + return 0; +} + +int q6asm_enable_sbrps(struct audio_client *ac, + uint32_t sbr_ps_enable) +{ + struct asm_aac_sbr_ps_flag_param sbrps; + u32 frames_per_buf = 0; + + int rc = 0; + + pr_debug("%s: Session %d\n", __func__, ac->session); + + q6asm_add_hdr(ac, &sbrps.hdr, sizeof(sbrps), TRUE); + atomic_set(&ac->cmd_state, -1); + + sbrps.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + sbrps.encdec.param_id = ASM_PARAM_ID_AAC_SBR_PS_FLAG; + sbrps.encdec.param_size = sizeof(struct asm_aac_sbr_ps_flag_param) - + sizeof(struct asm_stream_cmd_set_encdec_param); + sbrps.encblk.frames_per_buf = frames_per_buf; + sbrps.encblk.enc_cfg_blk_size = sbrps.encdec.param_size - + sizeof(struct asm_enc_cfg_blk_param_v2); + + sbrps.sbr_ps_flag = sbr_ps_enable; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &sbrps); + if (rc < 0) { + pr_err("%s: Command opcode[0x%x]paramid[0x%x] failed %d\n", + __func__, + ASM_STREAM_CMD_SET_ENCDEC_PARAM, + ASM_PARAM_ID_AAC_SBR_PS_FLAG, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout opcode[0x%x] ", __func__, sbrps.hdr.opcode); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_cfg_dual_mono_aac(struct audio_client *ac, + uint16_t sce_left, uint16_t sce_right) +{ + struct asm_aac_dual_mono_mapping_param dual_mono; + + int rc = 0; + + pr_debug("%s: Session %d, sce_left = %d, sce_right = %d\n", + __func__, ac->session, sce_left, sce_right); + + q6asm_add_hdr(ac, &dual_mono.hdr, sizeof(dual_mono), TRUE); + atomic_set(&ac->cmd_state, -1); + + dual_mono.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + dual_mono.encdec.param_id = ASM_PARAM_ID_AAC_DUAL_MONO_MAPPING; + dual_mono.encdec.param_size = sizeof(dual_mono.left_channel_sce) + + sizeof(dual_mono.right_channel_sce); + dual_mono.left_channel_sce = sce_left; + dual_mono.right_channel_sce = sce_right; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &dual_mono); + if (rc < 0) { + pr_err("%s: Command opcode[0x%x]paramid[0x%x] failed %d\n", + __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM, + ASM_PARAM_ID_AAC_DUAL_MONO_MAPPING, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout opcode[0x%x]\n", __func__, + dual_mono.hdr.opcode); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +/* Support for selecting stereo mixing coefficients for B family not done */ +int q6asm_cfg_aac_sel_mix_coef(struct audio_client *ac, uint32_t mix_coeff) +{ + struct asm_aac_stereo_mix_coeff_selection_param_v2 aac_mix_coeff; + int rc = 0; + + q6asm_add_hdr(ac, &aac_mix_coeff.hdr, sizeof(aac_mix_coeff), TRUE); + atomic_set(&ac->cmd_state, -1); + aac_mix_coeff.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + aac_mix_coeff.param_id = + ASM_PARAM_ID_AAC_STEREO_MIX_COEFF_SELECTION_FLAG_V2; + aac_mix_coeff.param_size = + sizeof(struct asm_aac_stereo_mix_coeff_selection_param_v2); + aac_mix_coeff.aac_stereo_mix_coeff_flag = mix_coeff; + pr_debug("%s: mix_coeff = %u\n", __func__, mix_coeff); + rc = apr_send_pkt(ac->apr, (uint32_t *) &aac_mix_coeff); + if (rc < 0) { + pr_err("%s: Command opcode[0x%x]paramid[0x%x] failed %d\n", + __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM, + ASM_PARAM_ID_AAC_STEREO_MIX_COEFF_SELECTION_FLAG_V2, + rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout opcode[0x%x]\n", + __func__, aac_mix_coeff.hdr.opcode); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_enc_cfg_blk_qcelp(struct audio_client *ac, uint32_t frames_per_buf, + uint16_t min_rate, uint16_t max_rate, + uint16_t reduced_rate_level, uint16_t rate_modulation_cmd) +{ + struct asm_v13k_enc_cfg enc_cfg; + int rc = 0; + + pr_debug("%s: session[%d]frames[%d]min_rate[0x%4x]max_rate[0x%4x] reduced_rate_level[0x%4x]rate_modulation_cmd[0x%4x]\n", + __func__, + ac->session, frames_per_buf, min_rate, max_rate, + reduced_rate_level, rate_modulation_cmd); + + q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE); + atomic_set(&ac->cmd_state, -1); + enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2; + enc_cfg.encdec.param_size = sizeof(struct asm_v13k_enc_cfg) - + sizeof(struct asm_stream_cmd_set_encdec_param); + enc_cfg.encblk.frames_per_buf = frames_per_buf; + enc_cfg.encblk.enc_cfg_blk_size = enc_cfg.encdec.param_size - + sizeof(struct asm_enc_cfg_blk_param_v2); + + enc_cfg.min_rate = min_rate; + enc_cfg.max_rate = max_rate; + enc_cfg.reduced_rate_cmd = reduced_rate_level; + enc_cfg.rate_mod_cmd = rate_modulation_cmd; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg); + if (rc < 0) { + pr_err("%s: Comamnd %d failed %d\n", + __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for setencdec v13k resp\n", + __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_enc_cfg_blk_evrc(struct audio_client *ac, uint32_t frames_per_buf, + uint16_t min_rate, uint16_t max_rate, + uint16_t rate_modulation_cmd) +{ + struct asm_evrc_enc_cfg enc_cfg; + int rc = 0; + + pr_debug("%s: session[%d]frames[%d]min_rate[0x%4x]max_rate[0x%4x] rate_modulation_cmd[0x%4x]\n", + __func__, ac->session, + frames_per_buf, min_rate, max_rate, rate_modulation_cmd); + + q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE); + atomic_set(&ac->cmd_state, -1); + enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2; + enc_cfg.encdec.param_size = sizeof(struct asm_evrc_enc_cfg) - + sizeof(struct asm_stream_cmd_set_encdec_param); + enc_cfg.encblk.frames_per_buf = frames_per_buf; + enc_cfg.encblk.enc_cfg_blk_size = enc_cfg.encdec.param_size - + sizeof(struct asm_enc_cfg_blk_param_v2); + + enc_cfg.min_rate = min_rate; + enc_cfg.max_rate = max_rate; + enc_cfg.rate_mod_cmd = rate_modulation_cmd; + enc_cfg.reserved = 0; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg); + if (rc < 0) { + pr_err("%s: Comamnd %d failed %d\n", + __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for encdec evrc\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_enc_cfg_blk_amrnb(struct audio_client *ac, uint32_t frames_per_buf, + uint16_t band_mode, uint16_t dtx_enable) +{ + struct asm_amrnb_enc_cfg enc_cfg; + int rc = 0; + + pr_debug("%s: session[%d]frames[%d]band_mode[0x%4x]dtx_enable[0x%4x]\n", + __func__, ac->session, frames_per_buf, band_mode, dtx_enable); + + q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE); + atomic_set(&ac->cmd_state, -1); + enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2; + enc_cfg.encdec.param_size = sizeof(struct asm_amrnb_enc_cfg) - + sizeof(struct asm_stream_cmd_set_encdec_param); + enc_cfg.encblk.frames_per_buf = frames_per_buf; + enc_cfg.encblk.enc_cfg_blk_size = enc_cfg.encdec.param_size - + sizeof(struct asm_enc_cfg_blk_param_v2); + + enc_cfg.enc_mode = band_mode; + enc_cfg.dtx_mode = dtx_enable; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg); + if (rc < 0) { + pr_err("%s: Comamnd %d failed %d\n", + __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for set encdec amrnb\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_enc_cfg_blk_amrwb(struct audio_client *ac, uint32_t frames_per_buf, + uint16_t band_mode, uint16_t dtx_enable) +{ + struct asm_amrwb_enc_cfg enc_cfg; + int rc = 0; + + pr_debug("%s: session[%d]frames[%d]band_mode[0x%4x]dtx_enable[0x%4x]\n", + __func__, ac->session, frames_per_buf, band_mode, dtx_enable); + + q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE); + atomic_set(&ac->cmd_state, -1); + enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2; + enc_cfg.encdec.param_size = sizeof(struct asm_amrwb_enc_cfg) - + sizeof(struct asm_stream_cmd_set_encdec_param); + enc_cfg.encblk.frames_per_buf = frames_per_buf; + enc_cfg.encblk.enc_cfg_blk_size = enc_cfg.encdec.param_size - + sizeof(struct asm_enc_cfg_blk_param_v2); + + enc_cfg.enc_mode = band_mode; + enc_cfg.dtx_mode = dtx_enable; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg); + if (rc < 0) { + pr_err("%s: Comamnd %d failed %d\n", + __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for FORMAT_UPDATE\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + + +static int __q6asm_media_format_block_pcm(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, int stream_id, + bool use_default_chmap, char *channel_map) +{ + struct asm_multi_channel_pcm_fmt_blk_v2 fmt; + u8 *channel_mapping; + int rc = 0; + + pr_debug("%s: session[%d]rate[%d]ch[%d]\n", __func__, ac->session, rate, + channels); + + q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id); + atomic_set(&ac->cmd_state, -1); + /* + * Updated the token field with stream/session for compressed playback + * Platform driver must know the the stream with which the command is + * associated + */ + if (ac->io_mode & COMPRESSED_STREAM_IO) + q6asm_update_token(&fmt.hdr.token, + ac->session, + stream_id, + 0, /* Buffer index is NA */ + 0, /* Direction flag is NA */ + WAIT_CMD); + + pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x\n", + __func__, fmt.hdr.token, stream_id, ac->session); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmt_blk); + fmt.num_channels = channels; + fmt.bits_per_sample = bits_per_sample; + fmt.sample_rate = rate; + fmt.is_signed = 1; + + channel_mapping = fmt.channel_mapping; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + + if (use_default_chmap) { + if (q6asm_map_channels(channel_mapping, channels, false)) { + pr_err("%s: map channels failed %d\n", + __func__, channels); + return -EINVAL; + } + } else { + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL); + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s: Comamnd open failed %d\n", __func__, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for format update\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +static int __q6asm_media_format_block_pcm_v3(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, + int stream_id, + bool use_default_chmap, + char *channel_map, + uint16_t sample_word_size) +{ + struct asm_multi_channel_pcm_fmt_blk_param_v3 fmt; + u8 *channel_mapping; + int rc; + + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, + ac->session, rate, channels, + bits_per_sample, sample_word_size); + + memset(&fmt, 0, sizeof(fmt)); + q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id); + atomic_set(&ac->cmd_state, -1); + /* + * Updated the token field with stream/session for compressed playback + * Platform driver must know the the stream with which the command is + * associated + */ + if (ac->io_mode & COMPRESSED_STREAM_IO) + fmt.hdr.token = ((ac->session << 8) & 0xFFFF00) | + (stream_id & 0xFF); + + pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x\n", + __func__, fmt.hdr.token, stream_id, ac->session); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmt_blk); + fmt.param.num_channels = channels; + fmt.param.bits_per_sample = bits_per_sample; + fmt.param.sample_rate = rate; + fmt.param.is_signed = 1; + fmt.param.sample_word_size = sample_word_size; + channel_mapping = fmt.param.channel_mapping; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + + if (use_default_chmap) { + if (q6asm_map_channels(channel_mapping, channels, false)) { + pr_err("%s: map channels failed %d\n", + __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + } else { + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL); + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s: Comamnd open failed %d\n", __func__, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for format update\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +static int __q6asm_media_format_block_pcm_v4(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, + int stream_id, + bool use_default_chmap, + char *channel_map, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode) +{ + struct asm_multi_channel_pcm_fmt_blk_param_v4 fmt; + u8 *channel_mapping; + int rc; + + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, + ac->session, rate, channels, + bits_per_sample, sample_word_size); + + memset(&fmt, 0, sizeof(fmt)); + q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id); + atomic_set(&ac->cmd_state, -1); + /* + * Updated the token field with stream/session for compressed playback + * Platform driver must know the the stream with which the command is + * associated + */ + if (ac->io_mode & COMPRESSED_STREAM_IO) + fmt.hdr.token = ((ac->session << 8) & 0xFFFF00) | + (stream_id & 0xFF); + + pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x\n", + __func__, fmt.hdr.token, stream_id, ac->session); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmt_blk); + fmt.param.num_channels = channels; + fmt.param.bits_per_sample = bits_per_sample; + fmt.param.sample_rate = rate; + fmt.param.is_signed = 1; + fmt.param.sample_word_size = sample_word_size; + fmt.param.endianness = endianness; + fmt.param.mode = mode; + channel_mapping = fmt.param.channel_mapping; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + + if (use_default_chmap) { + if (q6asm_map_channels(channel_mapping, channels, false)) { + pr_err("%s: map channels failed %d\n", + __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + } else { + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL); + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s: Comamnd open failed %d\n", __func__, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for format update\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_media_format_block_pcm(struct audio_client *ac, + uint32_t rate, uint32_t channels) +{ + return __q6asm_media_format_block_pcm(ac, rate, + channels, 16, ac->stream_id, + true, NULL); +} + +int q6asm_media_format_block_pcm_format_support(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample) +{ + return __q6asm_media_format_block_pcm(ac, rate, + channels, bits_per_sample, ac->stream_id, + true, NULL); +} + +int q6asm_media_format_block_pcm_format_support_v2(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, int stream_id, + bool use_default_chmap, char *channel_map) +{ + if (!use_default_chmap && (channel_map == NULL)) { + pr_err("%s: No valid chan map and can't use default\n", + __func__); + return -EINVAL; + } + return __q6asm_media_format_block_pcm(ac, rate, + channels, bits_per_sample, stream_id, + use_default_chmap, channel_map); +} + +/* + * q6asm_media_format_block_pcm_format_support_v3- sends pcm decoder + * configuration parameters + * + * @ac: Client session handle + * @rate: sample rate + * @channels: number of channels + * @bits_per_sample: bit width of encoder session + * @stream_id: stream id of stream to be associated with this session + * @use_default_chmap: true if default channel map to be used + * @channel_map: input channel map + * @sample_word_size: Size in bits of the word that holds a sample of a channel + */ +int q6asm_media_format_block_pcm_format_support_v3(struct audio_client *ac, + uint32_t rate, + uint32_t channels, + uint16_t bits_per_sample, + int stream_id, + bool use_default_chmap, + char *channel_map, + uint16_t sample_word_size) +{ + if (!use_default_chmap && (channel_map == NULL)) { + pr_err("%s: No valid chan map and can't use default\n", + __func__); + return -EINVAL; + } + return __q6asm_media_format_block_pcm_v3(ac, rate, + channels, bits_per_sample, stream_id, + use_default_chmap, channel_map, + sample_word_size); + +} +EXPORT_SYMBOL(q6asm_media_format_block_pcm_format_support_v3); + +/* + * q6asm_media_format_block_pcm_format_support_v4- sends pcm decoder + * configuration parameters + * + * @ac: Client session handle + * @rate: sample rate + * @channels: number of channels + * @bits_per_sample: bit width of encoder session + * @stream_id: stream id of stream to be associated with this session + * @use_default_chmap: true if default channel map to be used + * @channel_map: input channel map + * @sample_word_size: Size in bits of the word that holds a sample of a channel + * @endianness: endianness of the pcm data + * @mode: Mode to provide additional info about the pcm input data + */ +int q6asm_media_format_block_pcm_format_support_v4(struct audio_client *ac, + uint32_t rate, + uint32_t channels, + uint16_t bits_per_sample, + int stream_id, + bool use_default_chmap, + char *channel_map, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode) +{ + if (!use_default_chmap && (channel_map == NULL)) { + pr_err("%s: No valid chan map and can't use default\n", + __func__); + return -EINVAL; + } + return __q6asm_media_format_block_pcm_v4(ac, rate, + channels, bits_per_sample, stream_id, + use_default_chmap, channel_map, + sample_word_size, endianness, + mode); + +} +EXPORT_SYMBOL(q6asm_media_format_block_pcm_format_support_v4); + + +static int __q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac, + uint32_t rate, uint32_t channels, + bool use_default_chmap, char *channel_map, + uint16_t bits_per_sample) +{ + struct asm_multi_channel_pcm_fmt_blk_v2 fmt; + u8 *channel_mapping; + int rc = 0; + + pr_debug("%s: session[%d]rate[%d]ch[%d]\n", __func__, ac->session, rate, + channels); + + q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE); + atomic_set(&ac->cmd_state, -1); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmt_blk); + fmt.num_channels = channels; + fmt.bits_per_sample = bits_per_sample; + fmt.sample_rate = rate; + fmt.is_signed = 1; + + channel_mapping = fmt.channel_mapping; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + + if (use_default_chmap) { + if (q6asm_map_channels(channel_mapping, channels, false)) { + pr_err("%s: map channels failed %d\n", + __func__, channels); + return -EINVAL; + } + } else { + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL); + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s: Comamnd open failed %d\n", __func__, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for format update\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +static int __q6asm_media_format_block_multi_ch_pcm_v3(struct audio_client *ac, + uint32_t rate, + uint32_t channels, + bool use_default_chmap, + char *channel_map, + uint16_t bits_per_sample, + uint16_t sample_word_size) +{ + struct asm_multi_channel_pcm_fmt_blk_param_v3 fmt; + u8 *channel_mapping; + int rc; + + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, + ac->session, rate, channels, + bits_per_sample, sample_word_size); + + memset(&fmt, 0, sizeof(fmt)); + q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE); + atomic_set(&ac->cmd_state, -1); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmt_blk); + fmt.param.num_channels = channels; + fmt.param.bits_per_sample = bits_per_sample; + fmt.param.sample_rate = rate; + fmt.param.is_signed = 1; + fmt.param.sample_word_size = sample_word_size; + channel_mapping = fmt.param.channel_mapping; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + + if (use_default_chmap) { + if (q6asm_map_channels(channel_mapping, channels, false)) { + pr_err("%s: map channels failed %d\n", + __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + } else { + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL); + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s: Comamnd open failed %d\n", __func__, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for format update\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +static int __q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac, + uint32_t rate, + uint32_t channels, + bool use_default_chmap, + char *channel_map, + uint16_t bits_per_sample, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode) +{ + struct asm_multi_channel_pcm_fmt_blk_param_v4 fmt; + u8 *channel_mapping; + int rc; + + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, + ac->session, rate, channels, + bits_per_sample, sample_word_size); + + memset(&fmt, 0, sizeof(fmt)); + q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE); + atomic_set(&ac->cmd_state, -1); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmt_blk); + fmt.param.num_channels = channels; + fmt.param.bits_per_sample = bits_per_sample; + fmt.param.sample_rate = rate; + fmt.param.is_signed = 1; + fmt.param.sample_word_size = sample_word_size; + fmt.param.endianness = endianness; + fmt.param.mode = mode; + channel_mapping = fmt.param.channel_mapping; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + + if (use_default_chmap) { + if (q6asm_map_channels(channel_mapping, channels, false)) { + pr_err("%s: map channels failed %d\n", + __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + } else { + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL); + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s: Comamnd open failed %d\n", __func__, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for format update\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac, + uint32_t rate, uint32_t channels, + bool use_default_chmap, char *channel_map) +{ + return __q6asm_media_format_block_multi_ch_pcm(ac, rate, + channels, use_default_chmap, channel_map, 16); +} + +int q6asm_media_format_block_multi_ch_pcm_v2( + struct audio_client *ac, + uint32_t rate, uint32_t channels, + bool use_default_chmap, char *channel_map, + uint16_t bits_per_sample) +{ + return __q6asm_media_format_block_multi_ch_pcm(ac, rate, + channels, use_default_chmap, channel_map, + bits_per_sample); +} + +/* + * q6asm_media_format_block_multi_ch_pcm_v3 - sends pcm decoder configuration + * parameters + * + * @ac: Client session handle + * @rate: sample rate + * @channels: number of channels + * @bits_per_sample: bit width of encoder session + * @use_default_chmap: true if default channel map to be used + * @channel_map: input channel map + * @sample_word_size: Size in bits of the word that holds a sample of a channel + */ +int q6asm_media_format_block_multi_ch_pcm_v3(struct audio_client *ac, + uint32_t rate, uint32_t channels, + bool use_default_chmap, + char *channel_map, + uint16_t bits_per_sample, + uint16_t sample_word_size) +{ + return __q6asm_media_format_block_multi_ch_pcm_v3(ac, rate, channels, + use_default_chmap, + channel_map, + bits_per_sample, + sample_word_size); +} +EXPORT_SYMBOL(q6asm_media_format_block_multi_ch_pcm_v3); + +/* + * q6asm_media_format_block_multi_ch_pcm_v4 - sends pcm decoder configuration + * parameters + * + * @ac: Client session handle + * @rate: sample rate + * @channels: number of channels + * @bits_per_sample: bit width of encoder session + * @use_default_chmap: true if default channel map to be used + * @channel_map: input channel map + * @sample_word_size: Size in bits of the word that holds a sample of a channel + * @endianness: endianness of the pcm data + * @mode: Mode to provide additional info about the pcm input data + */ +int q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac, + uint32_t rate, uint32_t channels, + bool use_default_chmap, + char *channel_map, + uint16_t bits_per_sample, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode) +{ + return __q6asm_media_format_block_multi_ch_pcm_v4(ac, rate, channels, + use_default_chmap, + channel_map, + bits_per_sample, + sample_word_size, + endianness, + mode); +} +EXPORT_SYMBOL(q6asm_media_format_block_multi_ch_pcm_v4); + +/* + * q6asm_media_format_block_gen_compr - set up generic compress format params + * + * @ac: Client session handle + * @rate: sample rate + * @channels: number of channels + * @use_default_chmap: true if default channel map to be used + * @channel_map: input channel map + * @bits_per_sample: bit width of gen compress stream + */ +int q6asm_media_format_block_gen_compr(struct audio_client *ac, + uint32_t rate, uint32_t channels, + bool use_default_chmap, char *channel_map, + uint16_t bits_per_sample) +{ + struct asm_generic_compressed_fmt_blk_t fmt; + u8 *channel_mapping; + int rc = 0; + + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]\n", + __func__, ac->session, rate, + channels, bits_per_sample); + + memset(&fmt, 0, sizeof(fmt)); + q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmt_blk); + fmt.num_channels = channels; + fmt.bits_per_sample = bits_per_sample; + fmt.sampling_rate = rate; + + channel_mapping = fmt.channel_mapping; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); + + if (use_default_chmap) { + if (q6asm_map_channels(channel_mapping, channels, false)) { + pr_err("%s: map channels failed %d\n", + __func__, channels); + return -EINVAL; + } + } else { + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL); + } + + atomic_set(&ac->cmd_state, -1); + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s: Comamnd open failed %d\n", __func__, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for format update\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + } + return 0; +fail_cmd: + return rc; +} +EXPORT_SYMBOL(q6asm_media_format_block_gen_compr); + + +/* + * q6asm_media_format_block_iec - set up IEC61937 (compressed) or IEC60958 + * (pcm) format params. Both audio standards + * use the same format and are used for + * HDMI or SPDIF. + * + * @ac: Client session handle + * @rate: sample rate + * @channels: number of channels + */ +int q6asm_media_format_block_iec(struct audio_client *ac, + uint32_t rate, uint32_t channels) +{ + struct asm_iec_compressed_fmt_blk_t fmt; + int rc = 0; + + pr_debug("%s: session[%d]rate[%d]ch[%d]\n", + __func__, ac->session, rate, + channels); + + memset(&fmt, 0, sizeof(fmt)); + q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE); + + fmt.hdr.opcode = ASM_DATA_CMD_IEC_60958_MEDIA_FMT; + fmt.num_channels = channels; + fmt.sampling_rate = rate; + + atomic_set(&ac->cmd_state, -1); + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s: Comamnd open failed %d\n", __func__, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for format update\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + } + return 0; +fail_cmd: + return rc; +} +EXPORT_SYMBOL(q6asm_media_format_block_iec); + +static int __q6asm_media_format_block_multi_aac(struct audio_client *ac, + struct asm_aac_cfg *cfg, int stream_id) +{ + struct asm_aac_fmt_blk_v2 fmt; + int rc = 0; + + pr_debug("%s: session[%d]rate[%d]ch[%d]\n", __func__, ac->session, + cfg->sample_rate, cfg->ch_cfg); + + q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id); + atomic_set(&ac->cmd_state, -1); + /* + * Updated the token field with stream/session for compressed playback + * Platform driver must know the the stream with which the command is + * associated + */ + if (ac->io_mode & COMPRESSED_STREAM_IO) + q6asm_update_token(&fmt.hdr.token, + ac->session, + stream_id, + 0, /* Buffer index is NA */ + 0, /* Direction flag is NA */ + WAIT_CMD); + + pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x\n", + __func__, fmt.hdr.token, stream_id, ac->session); + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmt_blk); + fmt.aac_fmt_flag = cfg->format; + fmt.audio_objype = cfg->aot; + /* If zero, PCE is assumed to be available in bitstream*/ + fmt.total_size_of_PCE_bits = 0; + fmt.channel_config = cfg->ch_cfg; + fmt.sample_rate = cfg->sample_rate; + + pr_debug("%s: format=0x%x cfg_size=%d aac-cfg=0x%x aot=%d ch=%d sr=%d\n", + __func__, fmt.aac_fmt_flag, fmt.fmt_blk.fmt_blk_size, + fmt.aac_fmt_flag, + fmt.audio_objype, + fmt.channel_config, + fmt.sample_rate); + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s: Comamnd open failed %d\n", __func__, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for FORMAT_UPDATE\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_media_format_block_multi_aac(struct audio_client *ac, + struct asm_aac_cfg *cfg) +{ + return __q6asm_media_format_block_multi_aac(ac, cfg, ac->stream_id); +} + +int q6asm_media_format_block_aac(struct audio_client *ac, + struct asm_aac_cfg *cfg) +{ + return __q6asm_media_format_block_multi_aac(ac, cfg, ac->stream_id); +} + +int q6asm_stream_media_format_block_aac(struct audio_client *ac, + struct asm_aac_cfg *cfg, int stream_id) +{ + return __q6asm_media_format_block_multi_aac(ac, cfg, stream_id); +} + +int q6asm_media_format_block_wma(struct audio_client *ac, + void *cfg, int stream_id) +{ + struct asm_wmastdv9_fmt_blk_v2 fmt; + struct asm_wma_cfg *wma_cfg = (struct asm_wma_cfg *)cfg; + int rc = 0; + + pr_debug("session[%d]format_tag[0x%4x] rate[%d] ch[0x%4x] bps[%d], balign[0x%4x], bit_sample[0x%4x], ch_msk[%d], enc_opt[0x%4x]\n", + ac->session, wma_cfg->format_tag, wma_cfg->sample_rate, + wma_cfg->ch_cfg, wma_cfg->avg_bytes_per_sec, + wma_cfg->block_align, wma_cfg->valid_bits_per_sample, + wma_cfg->ch_mask, wma_cfg->encode_opt); + + q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id); + atomic_set(&ac->cmd_state, -1); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmtblk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmtblk); + fmt.fmtag = wma_cfg->format_tag; + fmt.num_channels = wma_cfg->ch_cfg; + fmt.sample_rate = wma_cfg->sample_rate; + fmt.avg_bytes_per_sec = wma_cfg->avg_bytes_per_sec; + fmt.blk_align = wma_cfg->block_align; + fmt.bits_per_sample = + wma_cfg->valid_bits_per_sample; + fmt.channel_mask = wma_cfg->ch_mask; + fmt.enc_options = wma_cfg->encode_opt; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s: Comamnd open failed %d\n", __func__, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for FORMAT_UPDATE\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_media_format_block_wmapro(struct audio_client *ac, + void *cfg, int stream_id) +{ + struct asm_wmaprov10_fmt_blk_v2 fmt; + struct asm_wmapro_cfg *wmapro_cfg = (struct asm_wmapro_cfg *)cfg; + int rc = 0; + + pr_debug("%s: session[%d]format_tag[0x%4x] rate[%d] ch[0x%4x] bps[%d], balign[0x%4x], bit_sample[0x%4x], ch_msk[%d], enc_opt[0x%4x], adv_enc_opt[0x%4x], adv_enc_opt2[0x%8x]\n", + __func__, + ac->session, wmapro_cfg->format_tag, wmapro_cfg->sample_rate, + wmapro_cfg->ch_cfg, wmapro_cfg->avg_bytes_per_sec, + wmapro_cfg->block_align, wmapro_cfg->valid_bits_per_sample, + wmapro_cfg->ch_mask, wmapro_cfg->encode_opt, + wmapro_cfg->adv_encode_opt, wmapro_cfg->adv_encode_opt2); + + q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id); + atomic_set(&ac->cmd_state, -1); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmtblk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmtblk); + + fmt.fmtag = wmapro_cfg->format_tag; + fmt.num_channels = wmapro_cfg->ch_cfg; + fmt.sample_rate = wmapro_cfg->sample_rate; + fmt.avg_bytes_per_sec = + wmapro_cfg->avg_bytes_per_sec; + fmt.blk_align = wmapro_cfg->block_align; + fmt.bits_per_sample = wmapro_cfg->valid_bits_per_sample; + fmt.channel_mask = wmapro_cfg->ch_mask; + fmt.enc_options = wmapro_cfg->encode_opt; + fmt.usAdvancedEncodeOpt = wmapro_cfg->adv_encode_opt; + fmt.advanced_enc_options2 = wmapro_cfg->adv_encode_opt2; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s: Comamnd open failed %d\n", __func__, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for FORMAT_UPDATE\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_media_format_block_amrwbplus(struct audio_client *ac, + struct asm_amrwbplus_cfg *cfg) +{ + struct asm_amrwbplus_fmt_blk_v2 fmt; + int rc = 0; + + pr_debug("%s: session[%d]band-mode[%d]frame-fmt[%d]ch[%d]\n", + __func__, + ac->session, + cfg->amr_band_mode, + cfg->amr_frame_fmt, + cfg->num_channels); + + q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE); + atomic_set(&ac->cmd_state, -1); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmtblk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmtblk); + fmt.amr_frame_fmt = cfg->amr_frame_fmt; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s: Comamnd media format update failed.. %d\n", + __func__, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for FORMAT_UPDATE\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_stream_media_format_block_flac(struct audio_client *ac, + struct asm_flac_cfg *cfg, int stream_id) +{ + struct asm_flac_fmt_blk_v2 fmt; + int rc = 0; + + pr_debug("%s :session[%d] rate[%d] ch[%d] size[%d] stream_id[%d]\n", + __func__, ac->session, cfg->sample_rate, cfg->ch_cfg, + cfg->sample_size, stream_id); + + q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id); + atomic_set(&ac->cmd_state, -1); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmtblk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmtblk); + + fmt.is_stream_info_present = cfg->stream_info_present; + fmt.num_channels = cfg->ch_cfg; + fmt.min_blk_size = cfg->min_blk_size; + fmt.max_blk_size = cfg->max_blk_size; + fmt.sample_rate = cfg->sample_rate; + fmt.min_frame_size = cfg->min_frame_size; + fmt.max_frame_size = cfg->max_frame_size; + fmt.sample_size = cfg->sample_size; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s :Comamnd media format update failed %d\n", + __func__, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s :timeout. waited for FORMAT_UPDATE\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_media_format_block_alac(struct audio_client *ac, + struct asm_alac_cfg *cfg, int stream_id) +{ + struct asm_alac_fmt_blk_v2 fmt; + int rc = 0; + + pr_debug("%s :session[%d]rate[%d]ch[%d]\n", __func__, + ac->session, cfg->sample_rate, cfg->num_channels); + + q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id); + atomic_set(&ac->cmd_state, -1); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmtblk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmtblk); + + fmt.frame_length = cfg->frame_length; + fmt.compatible_version = cfg->compatible_version; + fmt.bit_depth = cfg->bit_depth; + fmt.pb = cfg->pb; + fmt.mb = cfg->mb; + fmt.kb = cfg->kb; + fmt.num_channels = cfg->num_channels; + fmt.max_run = cfg->max_run; + fmt.max_frame_bytes = cfg->max_frame_bytes; + fmt.avg_bit_rate = cfg->avg_bit_rate; + fmt.sample_rate = cfg->sample_rate; + fmt.channel_layout_tag = cfg->channel_layout_tag; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s :Comamnd media format update failed %d\n", + __func__, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s :timeout. waited for FORMAT_UPDATE\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +/* + * q6asm_media_format_block_g711 - sends g711 decoder configuration + * parameters + * @ac: Client session handle + * @cfg: Audio stream manager configuration parameters + * @stream_id: Stream id + */ +int q6asm_media_format_block_g711(struct audio_client *ac, + struct asm_g711_dec_cfg *cfg, int stream_id) +{ + struct asm_g711_dec_fmt_blk_v2 fmt; + int rc = 0; + + if (!ac) { + pr_err("%s: audio client is null\n", __func__); + return -EINVAL; + } + if (!cfg) { + pr_err("%s: Invalid ASM config\n", __func__); + return -EINVAL; + } + + if (stream_id <= 0) { + pr_err("%s: Invalid stream id\n", __func__); + return -EINVAL; + } + + pr_debug("%s :session[%d]rate[%d]\n", __func__, + ac->session, cfg->sample_rate); + + memset(&fmt, 0, sizeof(struct asm_g711_dec_fmt_blk_v2)); + + q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id); + atomic_set(&ac->cmd_state, -1); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmtblk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmtblk); + + fmt.sample_rate = cfg->sample_rate; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s :Command media format update failed %d\n", + __func__, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s :timeout. waited for FORMAT_UPDATE\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} +EXPORT_SYMBOL(q6asm_media_format_block_g711); + +int q6asm_stream_media_format_block_vorbis(struct audio_client *ac, + struct asm_vorbis_cfg *cfg, int stream_id) +{ + struct asm_vorbis_fmt_blk_v2 fmt; + int rc = 0; + + pr_debug("%s :session[%d] bit_stream_fmt[%d] stream_id[%d]\n", + __func__, ac->session, cfg->bit_stream_fmt, stream_id); + + q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id); + atomic_set(&ac->cmd_state, -1); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmtblk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmtblk); + + fmt.bit_stream_fmt = cfg->bit_stream_fmt; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s :Comamnd media format update failed %d\n", + __func__, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s :timeout. waited for FORMAT_UPDATE\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_media_format_block_ape(struct audio_client *ac, + struct asm_ape_cfg *cfg, int stream_id) +{ + struct asm_ape_fmt_blk_v2 fmt; + int rc = 0; + + pr_debug("%s :session[%d]rate[%d]ch[%d]\n", __func__, + ac->session, cfg->sample_rate, cfg->num_channels); + + q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id); + atomic_set(&ac->cmd_state, -1); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmtblk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmtblk); + + fmt.compatible_version = cfg->compatible_version; + fmt.compression_level = cfg->compression_level; + fmt.format_flags = cfg->format_flags; + fmt.blocks_per_frame = cfg->blocks_per_frame; + fmt.final_frame_blocks = cfg->final_frame_blocks; + fmt.total_frames = cfg->total_frames; + fmt.bits_per_sample = cfg->bits_per_sample; + fmt.num_channels = cfg->num_channels; + fmt.sample_rate = cfg->sample_rate; + fmt.seek_table_present = cfg->seek_table_present; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s :Comamnd media format update failed %d\n", + __func__, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s :timeout. waited for FORMAT_UPDATE\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +/* + * q6asm_media_format_block_dsd- Sends DSD Decoder + * configuration parameters + * + * @ac: Client session handle + * @cfg: DSD Media Format Configuration. + * @stream_id: stream id of stream to be associated with this session + * + * Return 0 on success or negative error code on failure + */ +int q6asm_media_format_block_dsd(struct audio_client *ac, + struct asm_dsd_cfg *cfg, int stream_id) +{ + struct asm_dsd_fmt_blk_v2 fmt; + int rc; + + pr_debug("%s: session[%d] data_rate[%d] ch[%d]\n", __func__, + ac->session, cfg->dsd_data_rate, cfg->num_channels); + + memset(&fmt, 0, sizeof(fmt)); + q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmtblk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmtblk); + + fmt.num_version = cfg->num_version; + fmt.is_bitwise_big_endian = cfg->is_bitwise_big_endian; + fmt.dsd_channel_block_size = cfg->dsd_channel_block_size; + fmt.num_channels = cfg->num_channels; + fmt.dsd_data_rate = cfg->dsd_data_rate; + atomic_set(&ac->cmd_state, -1); + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s: Command DSD media format update failed, err: %d\n", + __func__, rc); + goto done; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for DSD FORMAT_UPDATE\n", __func__); + rc = -ETIMEDOUT; + goto done; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto done; + } + return 0; +done: + return rc; +} +EXPORT_SYMBOL(q6asm_media_format_block_dsd); + +int q6asm_stream_media_format_block_aptx_dec(struct audio_client *ac, + uint32_t srate, int stream_id) +{ + struct asm_aptx_dec_fmt_blk_v2 aptx_fmt; + int rc = 0; + + if (!ac->session) { + pr_err("%s: ac session invalid\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + pr_debug("%s :session[%d] rate[%d] stream_id[%d]\n", + __func__, ac->session, srate, stream_id); + + q6asm_stream_add_hdr(ac, &aptx_fmt.hdr, sizeof(aptx_fmt), TRUE, + stream_id); + atomic_set(&ac->cmd_state, -1); + + aptx_fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + aptx_fmt.fmtblk.fmt_blk_size = sizeof(aptx_fmt) - sizeof(aptx_fmt.hdr) - + sizeof(aptx_fmt.fmtblk); + + aptx_fmt.sample_rate = srate; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &aptx_fmt); + if (rc < 0) { + pr_err("%s :Comamnd media format update failed %d\n", + __func__, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s :timeout. waited for FORMAT_UPDATE\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + rc = 0; +fail_cmd: + return rc; +} + +static int __q6asm_ds1_set_endp_params(struct audio_client *ac, int param_id, + int param_value, int stream_id) +{ + struct asm_dec_ddp_endp_param_v2 ddp_cfg; + int rc = 0; + + pr_debug("%s: session[%d] stream[%d],param_id[%d]param_value[%d]", + __func__, ac->session, stream_id, param_id, param_value); + + q6asm_stream_add_hdr(ac, &ddp_cfg.hdr, sizeof(ddp_cfg), TRUE, + stream_id); + atomic_set(&ac->cmd_state, -1); + /* + * Updated the token field with stream/session for compressed playback + * Platform driver must know the stream with which the command is + * associated + */ + if (ac->io_mode & COMPRESSED_STREAM_IO) + q6asm_update_token(&ddp_cfg.hdr.token, + ac->session, + stream_id, + 0, /* Buffer index is NA */ + 0, /* Direction flag is NA */ + WAIT_CMD); + ddp_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + ddp_cfg.encdec.param_id = param_id; + ddp_cfg.encdec.param_size = sizeof(struct asm_dec_ddp_endp_param_v2) - + (sizeof(struct apr_hdr) + + sizeof(struct asm_stream_cmd_set_encdec_param)); + ddp_cfg.endp_param_value = param_value; + rc = apr_send_pkt(ac->apr, (uint32_t *) &ddp_cfg); + if (rc < 0) { + pr_err("%s: Command opcode[0x%x] failed %d\n", + __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout opcode[0x%x]\n", __func__, + ddp_cfg.hdr.opcode); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_ds1_set_endp_params(struct audio_client *ac, + int param_id, int param_value) +{ + return __q6asm_ds1_set_endp_params(ac, param_id, param_value, + ac->stream_id); +} + +int q6asm_ds1_set_stream_endp_params(struct audio_client *ac, + int param_id, int param_value, + int stream_id) +{ + return __q6asm_ds1_set_endp_params(ac, param_id, param_value, + stream_id); +} + +int q6asm_memory_map(struct audio_client *ac, phys_addr_t buf_add, int dir, + uint32_t bufsz, uint32_t bufcnt) +{ + struct avs_cmd_shared_mem_map_regions *mmap_regions = NULL; + struct avs_shared_map_region_payload *mregions = NULL; + struct audio_port_data *port = NULL; + void *mmap_region_cmd = NULL; + void *payload = NULL; + struct asm_buffer_node *buffer_node = NULL; + int rc = 0; + int cmd_size = 0; + + if (!ac) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->mmap_apr == NULL) { + pr_err("%s: mmap APR handle NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: Session[%d]\n", __func__, ac->session); + + buffer_node = kmalloc(sizeof(struct asm_buffer_node), GFP_KERNEL); + if (!buffer_node) + return -ENOMEM; + + cmd_size = sizeof(struct avs_cmd_shared_mem_map_regions) + + sizeof(struct avs_shared_map_region_payload) * bufcnt; + + mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL); + if (mmap_region_cmd == NULL) { + rc = -EINVAL; + kfree(buffer_node); + return rc; + } + mmap_regions = (struct avs_cmd_shared_mem_map_regions *) + mmap_region_cmd; + q6asm_add_mmaphdr(ac, &mmap_regions->hdr, cmd_size, dir); + atomic_set(&ac->mem_state, -1); + mmap_regions->hdr.opcode = ASM_CMD_SHARED_MEM_MAP_REGIONS; + mmap_regions->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL; + mmap_regions->num_regions = bufcnt & 0x00ff; + mmap_regions->property_flag = 0x00; + payload = ((u8 *) mmap_region_cmd + + sizeof(struct avs_cmd_shared_mem_map_regions)); + mregions = (struct avs_shared_map_region_payload *)payload; + + ac->port[dir].tmp_hdl = 0; + port = &ac->port[dir]; + pr_debug("%s: buf_add 0x%pK, bufsz: %d\n", __func__, + &buf_add, bufsz); + mregions->shm_addr_lsw = lower_32_bits(buf_add); + mregions->shm_addr_msw = msm_audio_populate_upper_32_bits(buf_add); + mregions->mem_size_bytes = bufsz; + ++mregions; + + rc = apr_send_pkt(ac->mmap_apr, (uint32_t *) mmap_region_cmd); + if (rc < 0) { + pr_err("%s: mmap op[0x%x]rc[%d]\n", __func__, + mmap_regions->hdr.opcode, rc); + rc = -EINVAL; + kfree(buffer_node); + goto fail_cmd; + } + + rc = wait_event_timeout(ac->mem_wait, + (atomic_read(&ac->mem_state) >= 0 && + ac->port[dir].tmp_hdl), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for memory_map\n", __func__); + rc = -ETIMEDOUT; + kfree(buffer_node); + goto fail_cmd; + } + if (atomic_read(&ac->mem_state) > 0) { + pr_err("%s: DSP returned error[%s] for memory_map\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->mem_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->mem_state)); + kfree(buffer_node); + goto fail_cmd; + } + buffer_node->buf_phys_addr = buf_add; + buffer_node->mmap_hdl = ac->port[dir].tmp_hdl; + list_add_tail(&buffer_node->list, &ac->port[dir].mem_map_handle); + ac->port[dir].tmp_hdl = 0; + rc = 0; + +fail_cmd: + kfree(mmap_region_cmd); + return rc; +} + +int q6asm_memory_unmap(struct audio_client *ac, phys_addr_t buf_add, int dir) +{ + struct avs_cmd_shared_mem_unmap_regions mem_unmap; + struct asm_buffer_node *buf_node = NULL; + struct list_head *ptr, *next; + + int rc = 0; + + if (!ac) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (this_mmap.apr == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: Session[%d]\n", __func__, ac->session); + + q6asm_add_mmaphdr(ac, &mem_unmap.hdr, + sizeof(struct avs_cmd_shared_mem_unmap_regions), + dir); + atomic_set(&ac->mem_state, -1); + mem_unmap.hdr.opcode = ASM_CMD_SHARED_MEM_UNMAP_REGIONS; + mem_unmap.mem_map_handle = 0; + list_for_each_safe(ptr, next, &ac->port[dir].mem_map_handle) { + buf_node = list_entry(ptr, struct asm_buffer_node, + list); + if (buf_node->buf_phys_addr == buf_add) { + pr_debug("%s: Found the element\n", __func__); + mem_unmap.mem_map_handle = buf_node->mmap_hdl; + break; + } + } + pr_debug("%s: mem_unmap-mem_map_handle: 0x%x\n", + __func__, mem_unmap.mem_map_handle); + + if (mem_unmap.mem_map_handle == 0) { + pr_err("%s: Do not send null mem handle to DSP\n", __func__); + rc = 0; + goto fail_cmd; + } + rc = apr_send_pkt(ac->mmap_apr, (uint32_t *) &mem_unmap); + if (rc < 0) { + pr_err("%s: mem_unmap op[0x%x]rc[%d]\n", __func__, + mem_unmap.hdr.opcode, rc); + rc = -EINVAL; + goto fail_cmd; + } + + rc = wait_event_timeout(ac->mem_wait, + (atomic_read(&ac->mem_state) >= 0), 5 * HZ); + if (!rc) { + pr_err("%s: timeout. waited for memory_unmap of handle 0x%x\n", + __func__, mem_unmap.mem_map_handle); + rc = -ETIMEDOUT; + goto fail_cmd; + } else if (atomic_read(&ac->mem_state) > 0) { + pr_err("%s DSP returned error [%s] map handle 0x%x\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->mem_state)), + mem_unmap.mem_map_handle); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->mem_state)); + goto fail_cmd; + } else if (atomic_read(&ac->unmap_cb_success) == 0) { + pr_err("%s: Error in mem unmap callback of handle 0x%x\n", + __func__, mem_unmap.mem_map_handle); + rc = -EINVAL; + goto fail_cmd; + } + + rc = 0; +fail_cmd: + list_for_each_safe(ptr, next, &ac->port[dir].mem_map_handle) { + buf_node = list_entry(ptr, struct asm_buffer_node, + list); + if (buf_node->buf_phys_addr == buf_add) { + list_del(&buf_node->list); + kfree(buf_node); + break; + } + } + return rc; +} + + +static int q6asm_memory_map_regions(struct audio_client *ac, int dir, + uint32_t bufsz, uint32_t bufcnt, + bool is_contiguous) +{ + struct avs_cmd_shared_mem_map_regions *mmap_regions = NULL; + struct avs_shared_map_region_payload *mregions = NULL; + struct audio_port_data *port = NULL; + struct audio_buffer *ab = NULL; + void *mmap_region_cmd = NULL; + void *payload = NULL; + struct asm_buffer_node *buffer_node = NULL; + int rc = 0; + int i = 0; + uint32_t cmd_size = 0; + uint32_t bufcnt_t; + uint32_t bufsz_t; + + if (!ac) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->mmap_apr == NULL) { + pr_err("%s: mmap APR handle NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: Session[%d]\n", __func__, ac->session); + + bufcnt_t = (is_contiguous) ? 1 : bufcnt; + bufsz_t = (is_contiguous) ? (bufsz * bufcnt) : bufsz; + + if (is_contiguous) { + /* The size to memory map should be multiple of 4K bytes */ + bufsz_t = PAGE_ALIGN(bufsz_t); + } + + if (bufcnt_t > (UINT_MAX + - sizeof(struct avs_cmd_shared_mem_map_regions)) + / sizeof(struct avs_shared_map_region_payload)) { + pr_err("%s: Unsigned Integer Overflow. bufcnt_t = %u\n", + __func__, bufcnt_t); + return -EINVAL; + } + + cmd_size = sizeof(struct avs_cmd_shared_mem_map_regions) + + (sizeof(struct avs_shared_map_region_payload) + * bufcnt_t); + + + if (bufcnt > (UINT_MAX / sizeof(struct asm_buffer_node))) { + pr_err("%s: Unsigned Integer Overflow. bufcnt = %u\n", + __func__, bufcnt); + return -EINVAL; + } + + buffer_node = kzalloc(sizeof(struct asm_buffer_node) * bufcnt, + GFP_KERNEL); + if (!buffer_node) + return -ENOMEM; + + mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL); + if (mmap_region_cmd == NULL) { + rc = -EINVAL; + kfree(buffer_node); + return rc; + } + mmap_regions = (struct avs_cmd_shared_mem_map_regions *) + mmap_region_cmd; + q6asm_add_mmaphdr(ac, &mmap_regions->hdr, cmd_size, dir); + atomic_set(&ac->mem_state, -1); + pr_debug("%s: mmap_region=0x%pK token=0x%x\n", __func__, + mmap_regions, ((ac->session << 8) | dir)); + + mmap_regions->hdr.opcode = ASM_CMD_SHARED_MEM_MAP_REGIONS; + mmap_regions->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL; + mmap_regions->num_regions = bufcnt_t; /*bufcnt & 0x00ff; */ + mmap_regions->property_flag = 0x00; + pr_debug("%s: map_regions->nregions = %d\n", __func__, + mmap_regions->num_regions); + payload = ((u8 *) mmap_region_cmd + + sizeof(struct avs_cmd_shared_mem_map_regions)); + mregions = (struct avs_shared_map_region_payload *)payload; + + ac->port[dir].tmp_hdl = 0; + port = &ac->port[dir]; + for (i = 0; i < bufcnt_t; i++) { + ab = &port->buf[i]; + mregions->shm_addr_lsw = lower_32_bits(ab->phys); + mregions->shm_addr_msw = + msm_audio_populate_upper_32_bits(ab->phys); + mregions->mem_size_bytes = bufsz_t; + ++mregions; + } + + rc = apr_send_pkt(ac->mmap_apr, (uint32_t *) mmap_region_cmd); + if (rc < 0) { + pr_err("%s: mmap_regions op[0x%x]rc[%d]\n", __func__, + mmap_regions->hdr.opcode, rc); + rc = -EINVAL; + kfree(buffer_node); + goto fail_cmd; + } + + rc = wait_event_timeout(ac->mem_wait, + (atomic_read(&ac->mem_state) >= 0) + , 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for memory_map\n", __func__); + rc = -ETIMEDOUT; + kfree(buffer_node); + goto fail_cmd; + } + if (atomic_read(&ac->mem_state) > 0) { + pr_err("%s DSP returned error for memory_map [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->mem_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->mem_state)); + kfree(buffer_node); + goto fail_cmd; + } + mutex_lock(&ac->cmd_lock); + + for (i = 0; i < bufcnt; i++) { + ab = &port->buf[i]; + buffer_node[i].buf_phys_addr = ab->phys; + buffer_node[i].mmap_hdl = ac->port[dir].tmp_hdl; + list_add_tail(&buffer_node[i].list, + &ac->port[dir].mem_map_handle); + pr_debug("%s: i=%d, bufadd[i] = 0x%pK, maphdl[i] = 0x%x\n", + __func__, i, &buffer_node[i].buf_phys_addr, + buffer_node[i].mmap_hdl); + } + ac->port[dir].tmp_hdl = 0; + mutex_unlock(&ac->cmd_lock); + rc = 0; +fail_cmd: + kfree(mmap_region_cmd); + return rc; +} + +static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir) +{ + struct avs_cmd_shared_mem_unmap_regions mem_unmap; + struct audio_port_data *port = NULL; + struct asm_buffer_node *buf_node = NULL; + struct list_head *ptr, *next; + phys_addr_t buf_add; + int rc = 0; + int cmd_size = 0; + + if (!ac) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->mmap_apr == NULL) { + pr_err("%s: mmap APR handle NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: Session[%d]\n", __func__, ac->session); + + cmd_size = sizeof(struct avs_cmd_shared_mem_unmap_regions); + q6asm_add_mmaphdr(ac, &mem_unmap.hdr, cmd_size, dir); + atomic_set(&ac->mem_state, -1); + port = &ac->port[dir]; + buf_add = port->buf->phys; + mem_unmap.hdr.opcode = ASM_CMD_SHARED_MEM_UNMAP_REGIONS; + mem_unmap.mem_map_handle = 0; + list_for_each_safe(ptr, next, &ac->port[dir].mem_map_handle) { + buf_node = list_entry(ptr, struct asm_buffer_node, + list); + if (buf_node->buf_phys_addr == buf_add) { + pr_debug("%s: Found the element\n", __func__); + mem_unmap.mem_map_handle = buf_node->mmap_hdl; + break; + } + } + + pr_debug("%s: mem_unmap-mem_map_handle: 0x%x\n", + __func__, mem_unmap.mem_map_handle); + + if (mem_unmap.mem_map_handle == 0) { + pr_err("%s: Do not send null mem handle to DSP\n", __func__); + rc = 0; + goto fail_cmd; + } + rc = apr_send_pkt(ac->mmap_apr, (uint32_t *) &mem_unmap); + if (rc < 0) { + pr_err("mmap_regions op[0x%x]rc[%d]\n", + mem_unmap.hdr.opcode, rc); + goto fail_cmd; + } + + rc = wait_event_timeout(ac->mem_wait, + (atomic_read(&ac->mem_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for memory_unmap of handle 0x%x\n", + __func__, mem_unmap.mem_map_handle); + rc = -ETIMEDOUT; + goto fail_cmd; + } else if (atomic_read(&ac->mem_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->mem_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->mem_state)); + goto fail_cmd; + } else if (atomic_read(&ac->unmap_cb_success) == 0) { + pr_err("%s: Error in mem unmap callback of handle 0x%x\n", + __func__, mem_unmap.mem_map_handle); + rc = -EINVAL; + goto fail_cmd; + } + rc = 0; + +fail_cmd: + list_for_each_safe(ptr, next, &ac->port[dir].mem_map_handle) { + buf_node = list_entry(ptr, struct asm_buffer_node, + list); + if (buf_node->buf_phys_addr == buf_add) { + list_del(&buf_node->list); + kfree(buf_node); + break; + } + } + return rc; +} + +int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain) +{ + struct asm_volume_ctrl_multichannel_gain multi_ch_gain; + int sz = 0; + int rc = 0; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + + memset(&multi_ch_gain, 0, sizeof(multi_ch_gain)); + sz = sizeof(struct asm_volume_ctrl_multichannel_gain); + q6asm_add_hdr_async(ac, &multi_ch_gain.hdr, sz, TRUE); + atomic_set(&ac->cmd_state_pp, -1); + multi_ch_gain.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; + multi_ch_gain.param.data_payload_addr_lsw = 0; + multi_ch_gain.param.data_payload_addr_msw = 0; + multi_ch_gain.param.mem_map_handle = 0; + multi_ch_gain.param.data_payload_size = sizeof(multi_ch_gain) - + sizeof(multi_ch_gain.hdr) - sizeof(multi_ch_gain.param); + multi_ch_gain.data.module_id = ASM_MODULE_ID_VOL_CTRL; + multi_ch_gain.data.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN; + multi_ch_gain.data.param_size = multi_ch_gain.param.data_payload_size - + sizeof(multi_ch_gain.data); + multi_ch_gain.data.reserved = 0; + multi_ch_gain.gain_data[0].channeltype = PCM_CHANNEL_FL; + multi_ch_gain.gain_data[0].gain = left_gain << 15; + multi_ch_gain.gain_data[1].channeltype = PCM_CHANNEL_FR; + multi_ch_gain.gain_data[1].gain = right_gain << 15; + multi_ch_gain.num_channels = 2; + rc = apr_send_pkt(ac->apr, (uint32_t *) &multi_ch_gain); + if (rc < 0) { + pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", + __func__, multi_ch_gain.data.param_id, rc); + rc = -EINVAL; + goto fail_cmd; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, + multi_ch_gain.data.param_id); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state_pp) > 0) { + pr_err("%s: DSP returned error[%s] , set-params paramid[0x%x]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state_pp)), + multi_ch_gain.data.param_id); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state_pp)); + goto fail_cmd; + } + rc = 0; +fail_cmd: + return rc; +} + +/* + * q6asm_set_multich_gain: set multiple channel gains on an ASM session + * @ac: audio client handle + * @channels: number of channels caller intends to set gains + * @gains: list of gains of audio channels + * @ch_map: list of channel mapping. Only valid if use_default is false + * @use_default: flag to indicate whether to use default mapping + */ +int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, + uint32_t *gains, uint8_t *ch_map, bool use_default) +{ + struct asm_volume_ctrl_multichannel_gain multich_gain; + int sz = 0; + int rc = 0; + int i; + u8 default_chmap[VOLUME_CONTROL_MAX_CHANNELS]; + + if (ac == NULL) { + pr_err("%s: ac is NULL\n", __func__); + rc = -EINVAL; + goto done; + } + if (ac->apr == NULL) { + dev_err(ac->dev, "%s: AC APR handle NULL\n", __func__); + rc = -EINVAL; + goto done; + } + if (gains == NULL) { + dev_err(ac->dev, "%s: gain_list is NULL\n", __func__); + rc = -EINVAL; + goto done; + } + if (channels > VOLUME_CONTROL_MAX_CHANNELS) { + dev_err(ac->dev, "%s: Invalid channel count %d\n", + __func__, channels); + rc = -EINVAL; + goto done; + } + if (!use_default && ch_map == NULL) { + dev_err(ac->dev, "%s: NULL channel map\n", __func__); + rc = -EINVAL; + goto done; + } + + memset(&multich_gain, 0, sizeof(multich_gain)); + sz = sizeof(struct asm_volume_ctrl_multichannel_gain); + q6asm_add_hdr_async(ac, &multich_gain.hdr, sz, TRUE); + atomic_set(&ac->cmd_state_pp, -1); + multich_gain.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; + multich_gain.param.data_payload_addr_lsw = 0; + multich_gain.param.data_payload_addr_msw = 0; + multich_gain.param.mem_map_handle = 0; + multich_gain.param.data_payload_size = sizeof(multich_gain) - + sizeof(multich_gain.hdr) - sizeof(multich_gain.param); + multich_gain.data.module_id = ASM_MODULE_ID_VOL_CTRL; + multich_gain.data.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN; + multich_gain.data.param_size = multich_gain.param.data_payload_size - + sizeof(multich_gain.data); + multich_gain.data.reserved = 0; + + if (use_default) { + rc = q6asm_map_channels(default_chmap, channels, false); + if (rc < 0) + goto done; + for (i = 0; i < channels; i++) { + multich_gain.gain_data[i].channeltype = + default_chmap[i]; + multich_gain.gain_data[i].gain = gains[i] << 15; + } + } else { + for (i = 0; i < channels; i++) { + multich_gain.gain_data[i].channeltype = ch_map[i]; + multich_gain.gain_data[i].gain = gains[i] << 15; + } + } + multich_gain.num_channels = channels; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &multich_gain); + if (rc < 0) { + pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", + __func__, multich_gain.data.param_id, rc); + goto done; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, + multich_gain.data.param_id); + rc = -EINVAL; + goto done; + } + if (atomic_read(&ac->cmd_state_pp) > 0) { + pr_err("%s: DSP returned error[%d] , set-params paramid[0x%x]\n", + __func__, atomic_read(&ac->cmd_state_pp), + multich_gain.data.param_id); + rc = -EINVAL; + goto done; + } + rc = 0; +done: + return rc; +} + +int q6asm_set_mute(struct audio_client *ac, int muteflag) +{ + struct asm_volume_ctrl_mute_config mute; + int sz = 0; + int rc = 0; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + + sz = sizeof(struct asm_volume_ctrl_mute_config); + q6asm_add_hdr_async(ac, &mute.hdr, sz, TRUE); + atomic_set(&ac->cmd_state_pp, -1); + mute.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; + mute.param.data_payload_addr_lsw = 0; + mute.param.data_payload_addr_msw = 0; + mute.param.mem_map_handle = 0; + mute.param.data_payload_size = sizeof(mute) - + sizeof(mute.hdr) - sizeof(mute.param); + mute.data.module_id = ASM_MODULE_ID_VOL_CTRL; + mute.data.param_id = ASM_PARAM_ID_VOL_CTRL_MUTE_CONFIG; + mute.data.param_size = mute.param.data_payload_size - sizeof(mute.data); + mute.data.reserved = 0; + mute.mute_flag = muteflag; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &mute); + if (rc < 0) { + pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", + __func__, mute.data.param_id, rc); + rc = -EINVAL; + goto fail_cmd; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, + mute.data.param_id); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state_pp) > 0) { + pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state_pp)), + mute.data.param_id); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state_pp)); + goto fail_cmd; + } + rc = 0; +fail_cmd: + return rc; +} + +static int __q6asm_set_volume(struct audio_client *ac, int volume, int instance) +{ + struct asm_volume_ctrl_master_gain vol; + int sz = 0; + int rc = 0; + int module_id; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + + switch (instance) { + case SOFT_VOLUME_INSTANCE_2: + module_id = ASM_MODULE_ID_VOL_CTRL2; + break; + case SOFT_VOLUME_INSTANCE_1: + default: + module_id = ASM_MODULE_ID_VOL_CTRL; + break; + } + + sz = sizeof(struct asm_volume_ctrl_master_gain); + q6asm_add_hdr_async(ac, &vol.hdr, sz, TRUE); + atomic_set(&ac->cmd_state_pp, -1); + vol.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; + vol.param.data_payload_addr_lsw = 0; + vol.param.data_payload_addr_msw = 0; + vol.param.mem_map_handle = 0; + vol.param.data_payload_size = sizeof(vol) - + sizeof(vol.hdr) - sizeof(vol.param); + vol.data.module_id = module_id; + vol.data.param_id = ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; + vol.data.param_size = vol.param.data_payload_size - sizeof(vol.data); + vol.data.reserved = 0; + vol.master_gain = volume; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &vol); + if (rc < 0) { + pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", + __func__, vol.data.param_id, rc); + rc = -EINVAL; + goto fail_cmd; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, + vol.data.param_id); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state_pp) > 0) { + pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state_pp)), + vol.data.param_id); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state_pp)); + goto fail_cmd; + } + + rc = 0; +fail_cmd: + return rc; +} + +int q6asm_set_volume(struct audio_client *ac, int volume) +{ + return __q6asm_set_volume(ac, volume, SOFT_VOLUME_INSTANCE_1); +} + +int q6asm_set_volume_v2(struct audio_client *ac, int volume, int instance) +{ + return __q6asm_set_volume(ac, volume, instance); +} + +int q6asm_set_aptx_dec_bt_addr(struct audio_client *ac, + struct aptx_dec_bt_addr_cfg *cfg) +{ + struct aptx_dec_bt_dev_addr paylod; + int sz = 0; + int rc = 0; + + pr_debug("%s: BT addr nap %d, uap %d, lap %d\n", __func__, cfg->nap, + cfg->uap, cfg->lap); + + if (ac == NULL) { + pr_err("%s: AC handle NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + + sz = sizeof(struct aptx_dec_bt_dev_addr); + q6asm_add_hdr_async(ac, &paylod.hdr, sz, TRUE); + atomic_set(&ac->cmd_state, -1); + paylod.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + paylod.encdec.param_id = APTX_DECODER_BT_ADDRESS; + paylod.encdec.param_size = sz - sizeof(paylod.hdr) + - sizeof(paylod.encdec); + paylod.bt_addr_cfg.lap = cfg->lap; + paylod.bt_addr_cfg.uap = cfg->uap; + paylod.bt_addr_cfg.nap = cfg->nap; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &paylod); + if (rc < 0) { + pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", + __func__, paylod.encdec.param_id, rc); + rc = -EINVAL; + goto fail_cmd; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, + paylod.encdec.param_id); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state)), + paylod.encdec.param_id); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + pr_debug("%s: set BT addr is success\n", __func__); + rc = 0; +fail_cmd: + return rc; +} + +int q6asm_send_ion_fd(struct audio_client *ac, int fd) +{ + struct ion_client *client; + struct ion_handle *handle; + ion_phys_addr_t paddr; + size_t pa_len = 0; + void *vaddr; + int ret; + int sz = 0; + struct avs_rtic_shared_mem_addr shm; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + + ret = msm_audio_ion_import("audio_mem_client", + &client, + &handle, + fd, + NULL, + 0, + &paddr, + &pa_len, + &vaddr); + if (ret) { + pr_err("%s: audio ION import failed, rc = %d\n", + __func__, ret); + ret = -ENOMEM; + goto fail_cmd; + } + /* get payload length */ + sz = sizeof(struct avs_rtic_shared_mem_addr); + q6asm_add_hdr_async(ac, &shm.hdr, sz, TRUE); + atomic_set(&ac->cmd_state, -1); + shm.shm_buf_addr_lsw = lower_32_bits(paddr); + shm.shm_buf_addr_msw = msm_audio_populate_upper_32_bits(paddr); + shm.buf_size = pa_len; + shm.shm_buf_num_regions = 1; + shm.shm_buf_mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL; + shm.shm_buf_flag = 0x00; + shm.encdec.param_id = AVS_PARAM_ID_RTIC_SHARED_MEMORY_ADDR; + shm.encdec.param_size = sizeof(struct avs_rtic_shared_mem_addr) - + sizeof(struct apr_hdr) - + sizeof(struct asm_stream_cmd_set_encdec_param_v2); + shm.encdec.service_id = OUT; + shm.encdec.reserved = 0; + shm.map_region.shm_addr_lsw = shm.shm_buf_addr_lsw; + shm.map_region.shm_addr_msw = shm.shm_buf_addr_msw; + shm.map_region.mem_size_bytes = pa_len; + shm.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM_V2; + ret = apr_send_pkt(ac->apr, (uint32_t *) &shm); + if (ret < 0) { + pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", + __func__, shm.encdec.param_id, ret); + ret = -EINVAL; + goto fail_cmd; + } + + ret = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 1*HZ); + if (!ret) { + pr_err("%s: timeout, shm.encdec paramid[0x%x]\n", __func__, + shm.encdec.param_id); + ret = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s] shm.encdec paramid[0x%x]\n", + __func__, + adsp_err_get_err_str(atomic_read(&ac->cmd_state)), + shm.encdec.param_id); + ret = adsp_err_get_lnx_err_code(atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + ret = 0; +fail_cmd: + return ret; +} + +int q6asm_send_rtic_event_ack(struct audio_client *ac, + void *param, uint32_t params_length) +{ + char *asm_params = NULL; + int sz, rc; + struct avs_param_rtic_event_ack ack; + + if (!param || !ac) { + pr_err("%s: %s is NULL\n", __func__, + (!param) ? "param" : "ac"); + rc = -EINVAL; + goto done; + } + + sz = sizeof(struct avs_param_rtic_event_ack) + params_length; + asm_params = kzalloc(sz, GFP_KERNEL); + if (!asm_params) { + rc = -ENOMEM; + goto done; + } + + q6asm_add_hdr_async(ac, &ack.hdr, + sizeof(struct avs_param_rtic_event_ack) + + params_length, TRUE); + atomic_set(&ac->cmd_state, -1); + ack.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM_V2; + ack.encdec.param_id = AVS_PARAM_ID_RTIC_EVENT_ACK; + ack.encdec.param_size = params_length; + ack.encdec.reserved = 0; + ack.encdec.service_id = OUT; + memcpy(asm_params, &ack, sizeof(struct avs_param_rtic_event_ack)); + memcpy(asm_params + sizeof(struct avs_param_rtic_event_ack), + param, params_length); + rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params); + if (rc < 0) { + pr_err("%s: apr pkt failed for rtic event ack\n", __func__); + rc = -EINVAL; + goto fail_send_param; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 1 * HZ); + if (!rc) { + pr_err("%s: timeout for rtic event ack cmd\n", __func__); + rc = -ETIMEDOUT; + goto fail_send_param; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s] for rtic event ack cmd\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_send_param; + } + rc = 0; + +fail_send_param: + kfree(asm_params); +done: + return rc; +} + +int q6asm_set_softpause(struct audio_client *ac, + struct asm_softpause_params *pause_param) +{ + struct asm_soft_pause_params softpause; + int sz = 0; + int rc = 0; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + + sz = sizeof(struct asm_soft_pause_params); + q6asm_add_hdr_async(ac, &softpause.hdr, sz, TRUE); + atomic_set(&ac->cmd_state_pp, -1); + softpause.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; + + softpause.param.data_payload_addr_lsw = 0; + softpause.param.data_payload_addr_msw = 0; + softpause.param.mem_map_handle = 0; + softpause.param.data_payload_size = sizeof(softpause) - + sizeof(softpause.hdr) - sizeof(softpause.param); + softpause.data.module_id = ASM_MODULE_ID_VOL_CTRL; + softpause.data.param_id = ASM_PARAM_ID_SOFT_PAUSE_PARAMETERS; + softpause.data.param_size = softpause.param.data_payload_size - + sizeof(softpause.data); + softpause.data.reserved = 0; + softpause.enable_flag = pause_param->enable; + softpause.period = pause_param->period; + softpause.step = pause_param->step; + softpause.ramping_curve = pause_param->rampingcurve; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &softpause); + if (rc < 0) { + pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", + __func__, softpause.data.param_id, rc); + rc = -EINVAL; + goto fail_cmd; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, + softpause.data.param_id); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state_pp) > 0) { + pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state_pp)), + softpause.data.param_id); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state_pp)); + goto fail_cmd; + } + rc = 0; +fail_cmd: + return rc; +} + +static int __q6asm_set_softvolume(struct audio_client *ac, + struct asm_softvolume_params *softvol_param, + int instance) +{ + struct asm_soft_step_volume_params softvol; + int sz = 0; + int rc = 0; + int module_id; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + + switch (instance) { + case SOFT_VOLUME_INSTANCE_2: + module_id = ASM_MODULE_ID_VOL_CTRL2; + break; + case SOFT_VOLUME_INSTANCE_1: + default: + module_id = ASM_MODULE_ID_VOL_CTRL; + break; + } + + sz = sizeof(struct asm_soft_step_volume_params); + q6asm_add_hdr_async(ac, &softvol.hdr, sz, TRUE); + atomic_set(&ac->cmd_state_pp, -1); + softvol.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; + softvol.param.data_payload_addr_lsw = 0; + softvol.param.data_payload_addr_msw = 0; + softvol.param.mem_map_handle = 0; + softvol.param.data_payload_size = sizeof(softvol) - + sizeof(softvol.hdr) - sizeof(softvol.param); + softvol.data.module_id = module_id; + softvol.data.param_id = ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS; + softvol.data.param_size = softvol.param.data_payload_size - + sizeof(softvol.data); + softvol.data.reserved = 0; + softvol.period = softvol_param->period; + softvol.step = softvol_param->step; + softvol.ramping_curve = softvol_param->rampingcurve; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &softvol); + if (rc < 0) { + pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", + __func__, softvol.data.param_id, rc); + rc = -EINVAL; + goto fail_cmd; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, + softvol.data.param_id); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state_pp) > 0) { + pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state_pp)), + softvol.data.param_id); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state_pp)); + goto fail_cmd; + } + rc = 0; +fail_cmd: + return rc; +} + +int q6asm_set_softvolume(struct audio_client *ac, + struct asm_softvolume_params *softvol_param) +{ + return __q6asm_set_softvolume(ac, softvol_param, + SOFT_VOLUME_INSTANCE_1); +} + +int q6asm_set_softvolume_v2(struct audio_client *ac, + struct asm_softvolume_params *softvol_param, + int instance) +{ + return __q6asm_set_softvolume(ac, softvol_param, instance); +} + +int q6asm_equalizer(struct audio_client *ac, void *eq_p) +{ + struct asm_eq_params eq; + struct msm_audio_eq_stream_config *eq_params = NULL; + int i = 0; + int sz = 0; + int rc = 0; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + + if (eq_p == NULL) { + pr_err("%s: [%d]: Invalid Eq param\n", __func__, ac->session); + rc = -EINVAL; + goto fail_cmd; + } + sz = sizeof(struct asm_eq_params); + eq_params = (struct msm_audio_eq_stream_config *) eq_p; + q6asm_add_hdr(ac, &eq.hdr, sz, TRUE); + atomic_set(&ac->cmd_state_pp, -1); + + eq.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; + eq.param.data_payload_addr_lsw = 0; + eq.param.data_payload_addr_msw = 0; + eq.param.mem_map_handle = 0; + eq.param.data_payload_size = sizeof(eq) - + sizeof(eq.hdr) - sizeof(eq.param); + eq.data.module_id = ASM_MODULE_ID_EQUALIZER; + eq.data.param_id = ASM_PARAM_ID_EQUALIZER_PARAMETERS; + eq.data.param_size = eq.param.data_payload_size - sizeof(eq.data); + eq.enable_flag = eq_params->enable; + eq.num_bands = eq_params->num_bands; + + pr_debug("%s: enable:%d numbands:%d\n", __func__, eq_params->enable, + eq_params->num_bands); + for (i = 0; i < eq_params->num_bands; i++) { + eq.eq_bands[i].band_idx = + eq_params->eq_bands[i].band_idx; + eq.eq_bands[i].filterype = + eq_params->eq_bands[i].filter_type; + eq.eq_bands[i].center_freq_hz = + eq_params->eq_bands[i].center_freq_hz; + eq.eq_bands[i].filter_gain = + eq_params->eq_bands[i].filter_gain; + eq.eq_bands[i].q_factor = + eq_params->eq_bands[i].q_factor; + pr_debug("%s: filter_type:%u bandnum:%d\n", __func__, + eq_params->eq_bands[i].filter_type, i); + pr_debug("%s: center_freq_hz:%u bandnum:%d\n", __func__, + eq_params->eq_bands[i].center_freq_hz, i); + pr_debug("%s: filter_gain:%d bandnum:%d\n", __func__, + eq_params->eq_bands[i].filter_gain, i); + pr_debug("%s: q_factor:%d bandnum:%d\n", __func__, + eq_params->eq_bands[i].q_factor, i); + } + rc = apr_send_pkt(ac->apr, (uint32_t *)&eq); + if (rc < 0) { + pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", + __func__, eq.data.param_id, rc); + rc = -EINVAL; + goto fail_cmd; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, + eq.data.param_id); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state_pp) > 0) { + pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state_pp)), + eq.data.param_id); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state_pp)); + goto fail_cmd; + } + rc = 0; +fail_cmd: + return rc; +} + +static int __q6asm_read(struct audio_client *ac, bool is_custom_len_reqd, + int len) +{ + struct asm_data_cmd_read_v2 read; + struct asm_buffer_node *buf_node = NULL; + struct list_head *ptr, *next; + struct audio_buffer *ab; + int dsp_buf; + struct audio_port_data *port; + int rc; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + + if (ac->io_mode & SYNC_IO_MODE) { + port = &ac->port[OUT]; + + q6asm_add_hdr(ac, &read.hdr, sizeof(read), FALSE); + + mutex_lock(&port->lock); + + dsp_buf = port->dsp_buf; + if (port->buf == NULL) { + pr_err("%s: buf is NULL\n", __func__); + mutex_unlock(&port->lock); + return -EINVAL; + } + ab = &port->buf[dsp_buf]; + + dev_vdbg(ac->dev, "%s: session[%d]dsp-buf[%d][%pK]cpu_buf[%d][%pK]\n", + __func__, + ac->session, + dsp_buf, + port->buf[dsp_buf].data, + port->cpu_buf, + &port->buf[port->cpu_buf].phys); + + read.hdr.opcode = ASM_DATA_CMD_READ_V2; + read.buf_addr_lsw = lower_32_bits(ab->phys); + read.buf_addr_msw = msm_audio_populate_upper_32_bits(ab->phys); + + list_for_each_safe(ptr, next, &ac->port[OUT].mem_map_handle) { + buf_node = list_entry(ptr, struct asm_buffer_node, + list); + if (buf_node->buf_phys_addr == ab->phys) + read.mem_map_handle = buf_node->mmap_hdl; + } + dev_vdbg(ac->dev, "memory_map handle in q6asm_read: [%0x]:", + read.mem_map_handle); + read.buf_size = is_custom_len_reqd ? len : ab->size; + read.seq_id = port->dsp_buf; + q6asm_update_token(&read.hdr.token, + 0, /* Session ID is NA */ + 0, /* Stream ID is NA */ + port->dsp_buf, + 0, /* Direction flag is NA */ + WAIT_CMD); + port->dsp_buf = q6asm_get_next_buf(ac, port->dsp_buf, + port->max_buf_cnt); + mutex_unlock(&port->lock); + dev_vdbg(ac->dev, "%s: buf add[%pK] token[0x%x] uid[%d]\n", + __func__, &ab->phys, read.hdr.token, + read.seq_id); + rc = apr_send_pkt(ac->apr, (uint32_t *) &read); + if (rc < 0) { + pr_err("%s: read op[0x%x]rc[%d]\n", + __func__, read.hdr.opcode, rc); + goto fail_cmd; + } + return 0; + } +fail_cmd: + return -EINVAL; +} + +int q6asm_read(struct audio_client *ac) +{ + return __q6asm_read(ac, false/*is_custom_len_reqd*/, 0); +} +int q6asm_read_v2(struct audio_client *ac, uint32_t len) +{ + return __q6asm_read(ac, true /*is_custom_len_reqd*/, len); +} + +int q6asm_read_nolock(struct audio_client *ac) +{ + struct asm_data_cmd_read_v2 read; + struct asm_buffer_node *buf_node = NULL; + struct list_head *ptr, *next; + struct audio_buffer *ab; + int dsp_buf; + struct audio_port_data *port; + int rc; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + + if (ac->io_mode & SYNC_IO_MODE) { + port = &ac->port[OUT]; + + q6asm_add_hdr_async(ac, &read.hdr, sizeof(read), FALSE); + + + dsp_buf = port->dsp_buf; + ab = &port->buf[dsp_buf]; + + dev_vdbg(ac->dev, "%s: session[%d]dsp-buf[%d][%pK]cpu_buf[%d][%pK]\n", + __func__, + ac->session, + dsp_buf, + port->buf[dsp_buf].data, + port->cpu_buf, + &port->buf[port->cpu_buf].phys); + + read.hdr.opcode = ASM_DATA_CMD_READ_V2; + read.buf_addr_lsw = lower_32_bits(ab->phys); + read.buf_addr_msw = msm_audio_populate_upper_32_bits(ab->phys); + read.buf_size = ab->size; + read.seq_id = port->dsp_buf; + q6asm_update_token(&read.hdr.token, + 0, /* Session ID is NA */ + 0, /* Stream ID is NA */ + port->dsp_buf, + 0, /* Direction flag is NA */ + WAIT_CMD); + + list_for_each_safe(ptr, next, &ac->port[OUT].mem_map_handle) { + buf_node = list_entry(ptr, struct asm_buffer_node, + list); + if (buf_node->buf_phys_addr == ab->phys) { + read.mem_map_handle = buf_node->mmap_hdl; + break; + } + } + + port->dsp_buf = q6asm_get_next_buf(ac, port->dsp_buf, + port->max_buf_cnt); + dev_vdbg(ac->dev, "%s: buf add[%pK] token[0x%x] uid[%d]\n", + __func__, &ab->phys, read.hdr.token, + read.seq_id); + rc = apr_send_pkt(ac->apr, (uint32_t *) &read); + if (rc < 0) { + pr_err("%s: read op[0x%x]rc[%d]\n", + __func__, read.hdr.opcode, rc); + goto fail_cmd; + } + return 0; + } +fail_cmd: + return -EINVAL; +} + +int q6asm_async_write(struct audio_client *ac, + struct audio_aio_write_param *param) +{ + int rc = 0; + struct asm_data_cmd_write_v2 write; + struct asm_buffer_node *buf_node = NULL; + struct list_head *ptr, *next; + struct audio_buffer *ab; + struct audio_port_data *port; + phys_addr_t lbuf_phys_addr; + u32 liomode; + u32 io_compressed; + u32 io_compressed_stream; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + + q6asm_stream_add_hdr_async( + ac, &write.hdr, sizeof(write), TRUE, ac->stream_id); + port = &ac->port[IN]; + ab = &port->buf[port->dsp_buf]; + + /* Pass session id as token for AIO scheme */ + write.hdr.token = param->uid; + write.hdr.opcode = ASM_DATA_CMD_WRITE_V2; + write.buf_addr_lsw = lower_32_bits(param->paddr); + write.buf_addr_msw = msm_audio_populate_upper_32_bits(param->paddr); + write.buf_size = param->len; + write.timestamp_msw = param->msw_ts; + write.timestamp_lsw = param->lsw_ts; + liomode = (ASYNC_IO_MODE | NT_MODE); + io_compressed = (ASYNC_IO_MODE | COMPRESSED_IO); + io_compressed_stream = (ASYNC_IO_MODE | COMPRESSED_STREAM_IO); + + if (ac->io_mode == liomode) + lbuf_phys_addr = (param->paddr - 32); + else if (ac->io_mode == io_compressed || + ac->io_mode == io_compressed_stream) + lbuf_phys_addr = (param->paddr - param->metadata_len); + else { + if (param->flags & SET_TIMESTAMP) + lbuf_phys_addr = param->paddr - + sizeof(struct snd_codec_metadata); + else + lbuf_phys_addr = param->paddr; + } + dev_vdbg(ac->dev, "%s: token[0x%x], buf_addr[%pK], buf_size[0x%x], ts_msw[0x%x], ts_lsw[0x%x], lbuf_phys_addr: 0x[%pK]\n", + __func__, + write.hdr.token, ¶m->paddr, + write.buf_size, write.timestamp_msw, + write.timestamp_lsw, &lbuf_phys_addr); + + /* Use 0xFF00 for disabling timestamps */ + if (param->flags == 0xFF00) + write.flags = (0x00000000 | (param->flags & 0x800000FF)); + else + write.flags = (0x80000000 | param->flags); + write.flags |= param->last_buffer << ASM_SHIFT_LAST_BUFFER_FLAG; + write.seq_id = param->uid; + list_for_each_safe(ptr, next, &ac->port[IN].mem_map_handle) { + buf_node = list_entry(ptr, struct asm_buffer_node, + list); + if (buf_node->buf_phys_addr == lbuf_phys_addr) { + write.mem_map_handle = buf_node->mmap_hdl; + break; + } + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &write); + if (rc < 0) { + pr_err("%s: write op[0x%x]rc[%d]\n", __func__, + write.hdr.opcode, rc); + goto fail_cmd; + } + return 0; +fail_cmd: + return -EINVAL; +} + +int q6asm_async_read(struct audio_client *ac, + struct audio_aio_read_param *param) +{ + int rc = 0; + struct asm_data_cmd_read_v2 read; + struct asm_buffer_node *buf_node = NULL; + struct list_head *ptr, *next; + phys_addr_t lbuf_phys_addr; + u32 liomode; + u32 io_compressed; + int dir = 0; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + + q6asm_add_hdr_async(ac, &read.hdr, sizeof(read), FALSE); + + /* Pass session id as token for AIO scheme */ + read.hdr.token = param->uid; + read.hdr.opcode = ASM_DATA_CMD_READ_V2; + read.buf_addr_lsw = lower_32_bits(param->paddr); + read.buf_addr_msw = msm_audio_populate_upper_32_bits(param->paddr); + read.buf_size = param->len; + read.seq_id = param->uid; + liomode = (NT_MODE | ASYNC_IO_MODE); + io_compressed = (ASYNC_IO_MODE | COMPRESSED_IO); + if (ac->io_mode == liomode) { + lbuf_phys_addr = (param->paddr - 32); + /*legacy wma driver case*/ + dir = IN; + } else if (ac->io_mode == io_compressed) { + lbuf_phys_addr = (param->paddr - 64); + dir = OUT; + } else { + if (param->flags & COMPRESSED_TIMESTAMP_FLAG) + lbuf_phys_addr = param->paddr - + sizeof(struct snd_codec_metadata); + else + lbuf_phys_addr = param->paddr; + dir = OUT; + } + + list_for_each_safe(ptr, next, &ac->port[dir].mem_map_handle) { + buf_node = list_entry(ptr, struct asm_buffer_node, + list); + if (buf_node->buf_phys_addr == lbuf_phys_addr) { + read.mem_map_handle = buf_node->mmap_hdl; + break; + } + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &read); + if (rc < 0) { + pr_err("%s: read op[0x%x]rc[%d]\n", __func__, + read.hdr.opcode, rc); + goto fail_cmd; + } + return 0; +fail_cmd: + return -EINVAL; +} + +int q6asm_write(struct audio_client *ac, uint32_t len, uint32_t msw_ts, + uint32_t lsw_ts, uint32_t flags) +{ + int rc = 0; + struct asm_data_cmd_write_v2 write; + struct asm_buffer_node *buf_node = NULL; + struct audio_port_data *port; + struct audio_buffer *ab; + int dsp_buf = 0; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + + dev_vdbg(ac->dev, "%s: session[%d] len=%d\n", + __func__, ac->session, len); + if (ac->io_mode & SYNC_IO_MODE) { + port = &ac->port[IN]; + + q6asm_add_hdr(ac, &write.hdr, sizeof(write), + FALSE); + mutex_lock(&port->lock); + + dsp_buf = port->dsp_buf; + ab = &port->buf[dsp_buf]; + + q6asm_update_token(&write.hdr.token, + 0, /* Session ID is NA */ + 0, /* Stream ID is NA */ + port->dsp_buf, + 0, /* Direction flag is NA */ + NO_WAIT_CMD); + write.hdr.opcode = ASM_DATA_CMD_WRITE_V2; + write.buf_addr_lsw = lower_32_bits(ab->phys); + write.buf_addr_msw = msm_audio_populate_upper_32_bits(ab->phys); + write.buf_size = len; + write.seq_id = port->dsp_buf; + write.timestamp_lsw = lsw_ts; + write.timestamp_msw = msw_ts; + /* Use 0xFF00 for disabling timestamps */ + if (flags == 0xFF00) + write.flags = (0x00000000 | (flags & 0x800000FF)); + else + write.flags = (0x80000000 | flags); + port->dsp_buf = q6asm_get_next_buf(ac, port->dsp_buf, + port->max_buf_cnt); + buf_node = list_first_entry(&ac->port[IN].mem_map_handle, + struct asm_buffer_node, + list); + write.mem_map_handle = buf_node->mmap_hdl; + + dev_vdbg(ac->dev, "%s: ab->phys[%pK]bufadd[0x%x] token[0x%x]buf_id[0x%x]buf_size[0x%x]mmaphdl[0x%x]" + , __func__, + &ab->phys, + write.buf_addr_lsw, + write.hdr.token, + write.seq_id, + write.buf_size, + write.mem_map_handle); + mutex_unlock(&port->lock); + + config_debug_fs_write(ab); + + rc = apr_send_pkt(ac->apr, (uint32_t *) &write); + if (rc < 0) { + pr_err("%s: write op[0x%x]rc[%d]\n", + __func__, write.hdr.opcode, rc); + goto fail_cmd; + } + return 0; + } +fail_cmd: + return -EINVAL; +} + +int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts, + uint32_t lsw_ts, uint32_t flags) +{ + int rc = 0; + struct asm_data_cmd_write_v2 write; + struct asm_buffer_node *buf_node = NULL; + struct audio_port_data *port; + struct audio_buffer *ab; + int dsp_buf = 0; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + + dev_vdbg(ac->dev, "%s: session[%d] len=%d\n", + __func__, ac->session, len); + if (ac->io_mode & SYNC_IO_MODE) { + port = &ac->port[IN]; + + q6asm_add_hdr_async(ac, &write.hdr, sizeof(write), + FALSE); + + dsp_buf = port->dsp_buf; + ab = &port->buf[dsp_buf]; + + q6asm_update_token(&write.hdr.token, + 0, /* Session ID is NA */ + 0, /* Stream ID is NA */ + port->dsp_buf, + 0, /* Direction flag is NA */ + NO_WAIT_CMD); + + write.hdr.opcode = ASM_DATA_CMD_WRITE_V2; + write.buf_addr_lsw = lower_32_bits(ab->phys); + write.buf_addr_msw = msm_audio_populate_upper_32_bits(ab->phys); + write.buf_size = len; + write.seq_id = port->dsp_buf; + write.timestamp_lsw = lsw_ts; + write.timestamp_msw = msw_ts; + buf_node = list_first_entry(&ac->port[IN].mem_map_handle, + struct asm_buffer_node, + list); + write.mem_map_handle = buf_node->mmap_hdl; + /* Use 0xFF00 for disabling timestamps */ + if (flags == 0xFF00) + write.flags = (0x00000000 | (flags & 0x800000FF)); + else + write.flags = (0x80000000 | flags); + port->dsp_buf = q6asm_get_next_buf(ac, port->dsp_buf, + port->max_buf_cnt); + + dev_vdbg(ac->dev, "%s: ab->phys[%pK]bufadd[0x%x]token[0x%x] buf_id[0x%x]buf_size[0x%x]mmaphdl[0x%x]" + , __func__, + &ab->phys, + write.buf_addr_lsw, + write.hdr.token, + write.seq_id, + write.buf_size, + write.mem_map_handle); + + rc = apr_send_pkt(ac->apr, (uint32_t *) &write); + if (rc < 0) { + pr_err("%s: write op[0x%x]rc[%d]\n", + __func__, write.hdr.opcode, rc); + goto fail_cmd; + } + return 0; + } +fail_cmd: + return -EINVAL; +} + +int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) +{ + struct asm_mtmx_strtr_get_params mtmx_params; + int rc; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + if (tstamp == NULL) { + pr_err("%s: tstamp NULL\n", __func__); + return -EINVAL; + } + + q6asm_add_hdr(ac, &mtmx_params.hdr, sizeof(mtmx_params), TRUE); + mtmx_params.hdr.opcode = ASM_SESSION_CMD_GET_MTMX_STRTR_PARAMS_V2; + mtmx_params.param_info.data_payload_addr_lsw = 0; + mtmx_params.param_info.data_payload_addr_msw = 0; + mtmx_params.param_info.mem_map_handle = 0; + mtmx_params.param_info.direction = (ac->io_mode & TUN_READ_IO_MODE + ? 1 : 0); + mtmx_params.param_info.module_id = + ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; + mtmx_params.param_info.param_id = + ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3; + mtmx_params.param_info.param_max_size = + sizeof(struct asm_stream_param_data_v2) + + sizeof(struct asm_session_mtmx_strtr_param_session_time_v3_t); + atomic_set(&ac->time_flag, 1); + + dev_vdbg(ac->dev, "%s: session[%d]opcode[0x%x]\n", __func__, + ac->session, mtmx_params.hdr.opcode); + rc = apr_send_pkt(ac->apr, (uint32_t *) &mtmx_params); + if (rc < 0) { + pr_err("%s: Commmand 0x%x failed %d\n", __func__, + mtmx_params.hdr.opcode, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->time_wait, + (atomic_read(&ac->time_flag) == 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout in getting session time from DSP\n", + __func__); + goto fail_cmd; + } + + *tstamp = ac->time_stamp; + return 0; + +fail_cmd: + return -EINVAL; +} + +int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp) +{ + struct apr_hdr hdr; + int rc; + + if (ac == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + if (tstamp == NULL) { + pr_err("%s: tstamp NULL\n", __func__); + return -EINVAL; + } + + q6asm_add_hdr(ac, &hdr, sizeof(hdr), TRUE); + hdr.opcode = ASM_SESSION_CMD_GET_SESSIONTIME_V3; + atomic_set(&ac->time_flag, 1); + + dev_vdbg(ac->dev, "%s: session[%d]opcode[0x%x]\n", __func__, + ac->session, + hdr.opcode); + rc = apr_send_pkt(ac->apr, (uint32_t *) &hdr); + if (rc < 0) { + pr_err("%s: Commmand 0x%x failed %d\n", + __func__, hdr.opcode, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->time_wait, + (atomic_read(&ac->time_flag) == 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout in getting session time from DSP\n", + __func__); + goto fail_cmd; + } + + *tstamp = ac->time_stamp; + return 0; + +fail_cmd: + return -EINVAL; +} + + +int q6asm_send_audio_effects_params(struct audio_client *ac, char *params, + uint32_t params_length) +{ + char *asm_params = NULL; + struct apr_hdr hdr; + struct asm_stream_cmd_set_pp_params_v2 payload_params; + int sz, rc; + + pr_debug("%s:\n", __func__); + if (!ac) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + if (params == NULL) { + pr_err("%s: params NULL\n", __func__); + return -EINVAL; + } + sz = sizeof(struct apr_hdr) + + sizeof(struct asm_stream_cmd_set_pp_params_v2) + + params_length; + asm_params = kzalloc(sz, GFP_KERNEL); + if (!asm_params) { + pr_err("%s, asm params memory alloc failed", __func__); + return -ENOMEM; + } + q6asm_add_hdr_async(ac, &hdr, (sizeof(struct apr_hdr) + + sizeof(struct asm_stream_cmd_set_pp_params_v2) + + params_length), TRUE); + atomic_set(&ac->cmd_state_pp, -1); + hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; + payload_params.data_payload_addr_lsw = 0; + payload_params.data_payload_addr_msw = 0; + payload_params.mem_map_handle = 0; + payload_params.data_payload_size = params_length; + memcpy(((u8 *)asm_params), &hdr, sizeof(struct apr_hdr)); + memcpy(((u8 *)asm_params + sizeof(struct apr_hdr)), &payload_params, + sizeof(struct asm_stream_cmd_set_pp_params_v2)); + memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) + + sizeof(struct asm_stream_cmd_set_pp_params_v2)), + params, params_length); + rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params); + if (rc < 0) { + pr_err("%s: audio effects set-params send failed\n", __func__); + rc = -EINVAL; + goto fail_send_param; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state_pp) >= 0), 1*HZ); + if (!rc) { + pr_err("%s: timeout, audio effects set-params\n", __func__); + rc = -ETIMEDOUT; + goto fail_send_param; + } + if (atomic_read(&ac->cmd_state_pp) > 0) { + pr_err("%s: DSP returned error[%s] set-params\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state_pp))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state_pp)); + goto fail_send_param; + } + + rc = 0; +fail_send_param: + kfree(asm_params); + return rc; +} + +int q6asm_send_mtmx_strtr_window(struct audio_client *ac, + struct asm_session_mtmx_strtr_param_window_v2_t *window_param, + uint32_t param_id) +{ + struct asm_mtmx_strtr_params matrix; + int sz = 0; + int rc = 0; + + pr_debug("%s: Window lsw is %d, window msw is %d\n", __func__, + window_param->window_lsw, window_param->window_msw); + + if (!ac) { + pr_err("%s: audio client handle is NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + + if (ac->apr == NULL) { + pr_err("%s: ac->apr is NULL", __func__); + rc = -EINVAL; + goto fail_cmd; + } + + sz = sizeof(struct asm_mtmx_strtr_params); + q6asm_add_hdr(ac, &matrix.hdr, sz, TRUE); + atomic_set(&ac->cmd_state, -1); + matrix.hdr.opcode = ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2; + + matrix.param.data_payload_addr_lsw = 0; + matrix.param.data_payload_addr_msw = 0; + matrix.param.mem_map_handle = 0; + matrix.param.data_payload_size = + sizeof(struct asm_stream_param_data_v2) + + sizeof(struct asm_session_mtmx_strtr_param_window_v2_t); + matrix.param.direction = 0; /* RX */ + matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; + matrix.data.param_id = param_id; + matrix.data.param_size = + sizeof(struct asm_session_mtmx_strtr_param_window_v2_t); + matrix.data.reserved = 0; + memcpy(&(matrix.config.window_param), + window_param, + sizeof(struct asm_session_mtmx_strtr_param_window_v2_t)); + + rc = apr_send_pkt(ac->apr, (uint32_t *) &matrix); + if (rc < 0) { + pr_err("%s: Render window start send failed paramid [0x%x]\n", + __func__, matrix.data.param_id); + rc = -EINVAL; + goto fail_cmd; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout, Render window start paramid[0x%x]\n", + __func__, matrix.data.param_id); + rc = -ETIMEDOUT; + goto fail_cmd; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + rc = 0; +fail_cmd: + return rc; +} + +int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac, + uint32_t render_mode) +{ + struct asm_mtmx_strtr_params matrix; + struct asm_session_mtmx_strtr_param_render_mode_t render_param; + int sz = 0; + int rc = 0; + + pr_debug("%s: render mode is %d\n", __func__, render_mode); + + if (!ac) { + pr_err("%s: audio client handle is NULL\n", __func__); + rc = -EINVAL; + goto exit; + } + + if (ac->apr == NULL) { + pr_err("%s: ac->apr is NULL\n", __func__); + rc = -EINVAL; + goto exit; + } + + if ((render_mode != ASM_SESSION_MTMX_STRTR_PARAM_RENDER_DEFAULT) && + (render_mode != ASM_SESSION_MTMX_STRTR_PARAM_RENDER_LOCAL_STC)) { + pr_err("%s: Invalid render mode %d\n", __func__, render_mode); + rc = -EINVAL; + goto exit; + } + + memset(&render_param, 0, + sizeof(struct asm_session_mtmx_strtr_param_render_mode_t)); + render_param.flags = render_mode; + + memset(&matrix, 0, sizeof(struct asm_mtmx_strtr_params)); + sz = sizeof(struct asm_mtmx_strtr_params); + q6asm_add_hdr(ac, &matrix.hdr, sz, TRUE); + atomic_set(&ac->cmd_state, -1); + matrix.hdr.opcode = ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2; + + matrix.param.data_payload_addr_lsw = 0; + matrix.param.data_payload_addr_msw = 0; + matrix.param.mem_map_handle = 0; + matrix.param.data_payload_size = + sizeof(struct asm_stream_param_data_v2) + + sizeof(struct asm_session_mtmx_strtr_param_render_mode_t); + matrix.param.direction = 0; /* RX */ + matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; + matrix.data.param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_MODE_CMD; + matrix.data.param_size = + sizeof(struct asm_session_mtmx_strtr_param_render_mode_t); + matrix.data.reserved = 0; + memcpy(&(matrix.config.render_param), + &render_param, + sizeof(struct asm_session_mtmx_strtr_param_render_mode_t)); + + rc = apr_send_pkt(ac->apr, (uint32_t *) &matrix); + if (rc < 0) { + pr_err("%s: Render mode send failed paramid [0x%x]\n", + __func__, matrix.data.param_id); + rc = -EINVAL; + goto exit; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout, Render mode send paramid [0x%x]\n", + __func__, matrix.data.param_id); + rc = -ETIMEDOUT; + goto exit; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto exit; + } + rc = 0; +exit: + return rc; +} + +int q6asm_send_mtmx_strtr_clk_rec_mode(struct audio_client *ac, + uint32_t clk_rec_mode) +{ + struct asm_mtmx_strtr_params matrix; + struct asm_session_mtmx_strtr_param_clk_rec_t clk_rec_param; + int sz = 0; + int rc = 0; + + pr_debug("%s: clk rec mode is %d\n", __func__, clk_rec_mode); + + if (!ac) { + pr_err("%s: audio client handle is NULL\n", __func__); + rc = -EINVAL; + goto exit; + } + + if (ac->apr == NULL) { + pr_err("%s: ac->apr is NULL\n", __func__); + rc = -EINVAL; + goto exit; + } + + if ((clk_rec_mode != ASM_SESSION_MTMX_STRTR_PARAM_CLK_REC_NONE) && + (clk_rec_mode != ASM_SESSION_MTMX_STRTR_PARAM_CLK_REC_AUTO)) { + pr_err("%s: Invalid clk rec mode %d\n", __func__, clk_rec_mode); + rc = -EINVAL; + goto exit; + } + + memset(&clk_rec_param, 0, + sizeof(struct asm_session_mtmx_strtr_param_clk_rec_t)); + clk_rec_param.flags = clk_rec_mode; + + memset(&matrix, 0, sizeof(struct asm_mtmx_strtr_params)); + sz = sizeof(struct asm_mtmx_strtr_params); + q6asm_add_hdr(ac, &matrix.hdr, sz, TRUE); + atomic_set(&ac->cmd_state, -1); + matrix.hdr.opcode = ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2; + + matrix.param.data_payload_addr_lsw = 0; + matrix.param.data_payload_addr_msw = 0; + matrix.param.mem_map_handle = 0; + matrix.param.data_payload_size = + sizeof(struct asm_stream_param_data_v2) + + sizeof(struct asm_session_mtmx_strtr_param_clk_rec_t); + matrix.param.direction = 0; /* RX */ + matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; + matrix.data.param_id = ASM_SESSION_MTMX_STRTR_PARAM_CLK_REC_CMD; + matrix.data.param_size = + sizeof(struct asm_session_mtmx_strtr_param_clk_rec_t); + matrix.data.reserved = 0; + memcpy(&(matrix.config.clk_rec_param), + &clk_rec_param, + sizeof(struct asm_session_mtmx_strtr_param_clk_rec_t)); + + rc = apr_send_pkt(ac->apr, (uint32_t *) &matrix); + if (rc < 0) { + pr_err("%s: clk rec mode send failed paramid [0x%x]\n", + __func__, matrix.data.param_id); + rc = -EINVAL; + goto exit; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout, clk rec mode send paramid [0x%x]\n", + __func__, matrix.data.param_id); + rc = -ETIMEDOUT; + goto exit; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto exit; + } + rc = 0; +exit: + return rc; +} + +int q6asm_send_mtmx_strtr_enable_adjust_session_clock(struct audio_client *ac, + bool enable) +{ + struct asm_mtmx_strtr_params matrix; + struct asm_session_mtmx_param_adjust_session_time_ctl_t adjust_time; + int sz = 0; + int rc = 0; + + pr_debug("%s: adjust session enable %d\n", __func__, enable); + + if (!ac) { + pr_err("%s: audio client handle is NULL\n", __func__); + rc = -EINVAL; + goto exit; + } + + if (ac->apr == NULL) { + pr_err("%s: ac->apr is NULL\n", __func__); + rc = -EINVAL; + goto exit; + } + + adjust_time.enable = enable; + memset(&matrix, 0, sizeof(struct asm_mtmx_strtr_params)); + sz = sizeof(struct asm_mtmx_strtr_params); + q6asm_add_hdr(ac, &matrix.hdr, sz, TRUE); + atomic_set(&ac->cmd_state, -1); + matrix.hdr.opcode = ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2; + + matrix.param.data_payload_addr_lsw = 0; + matrix.param.data_payload_addr_msw = 0; + matrix.param.mem_map_handle = 0; + matrix.param.data_payload_size = + sizeof(struct asm_stream_param_data_v2) + + sizeof(struct asm_session_mtmx_param_adjust_session_time_ctl_t); + matrix.param.direction = 0; /* RX */ + matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; + matrix.data.param_id = ASM_SESSION_MTMX_PARAM_ADJUST_SESSION_TIME_CTL; + matrix.data.param_size = + sizeof(struct asm_session_mtmx_param_adjust_session_time_ctl_t); + matrix.data.reserved = 0; + matrix.config.adj_time_param.enable = adjust_time.enable; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &matrix); + if (rc < 0) { + pr_err("%s: enable adjust session failed failed paramid [0x%x]\n", + __func__, matrix.data.param_id); + rc = -EINVAL; + goto exit; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: enable adjust session failed failed paramid [0x%x]\n", + __func__, matrix.data.param_id); + rc = -ETIMEDOUT; + goto exit; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto exit; + } + rc = 0; +exit: + return rc; +} + + +static int __q6asm_cmd(struct audio_client *ac, int cmd, uint32_t stream_id) +{ + struct apr_hdr hdr; + int rc; + atomic_t *state; + int cnt = 0; + + if (!ac) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + q6asm_stream_add_hdr(ac, &hdr, sizeof(hdr), TRUE, stream_id); + atomic_set(&ac->cmd_state, -1); + /* + * Updated the token field with stream/session for compressed playback + * Platform driver must know the the stream with which the command is + * associated + */ + if (ac->io_mode & COMPRESSED_STREAM_IO) + q6asm_update_token(&hdr.token, + ac->session, + stream_id, + 0, /* Buffer index is NA */ + 0, /* Direction flag is NA */ + WAIT_CMD); + pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x\n", + __func__, hdr.token, stream_id, ac->session); + switch (cmd) { + case CMD_PAUSE: + pr_debug("%s: CMD_PAUSE\n", __func__); + hdr.opcode = ASM_SESSION_CMD_PAUSE; + state = &ac->cmd_state; + break; + case CMD_SUSPEND: + pr_debug("%s: CMD_SUSPEND\n", __func__); + hdr.opcode = ASM_SESSION_CMD_SUSPEND; + state = &ac->cmd_state; + break; + case CMD_FLUSH: + pr_debug("%s: CMD_FLUSH\n", __func__); + hdr.opcode = ASM_STREAM_CMD_FLUSH; + state = &ac->cmd_state; + break; + case CMD_OUT_FLUSH: + pr_debug("%s: CMD_OUT_FLUSH\n", __func__); + hdr.opcode = ASM_STREAM_CMD_FLUSH_READBUFS; + state = &ac->cmd_state; + break; + case CMD_EOS: + pr_debug("%s: CMD_EOS\n", __func__); + hdr.opcode = ASM_DATA_CMD_EOS; + atomic_set(&ac->cmd_state, 0); + state = &ac->cmd_state; + break; + case CMD_CLOSE: + pr_debug("%s: CMD_CLOSE\n", __func__); + hdr.opcode = ASM_STREAM_CMD_CLOSE; + state = &ac->cmd_state; + break; + default: + pr_err("%s: Invalid format[%d]\n", __func__, cmd); + rc = -EINVAL; + goto fail_cmd; + } + pr_debug("%s: session[%d]opcode[0x%x]\n", __func__, + ac->session, + hdr.opcode); + rc = apr_send_pkt(ac->apr, (uint32_t *) &hdr); + if (rc < 0) { + pr_err("%s: Commmand 0x%x failed %d\n", + __func__, hdr.opcode, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, (atomic_read(state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for response opcode[0x%x]\n", + __func__, hdr.opcode); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(state) > 0) { + pr_err("%s: DSP returned error[%s] opcode %d\n", + __func__, adsp_err_get_err_str( + atomic_read(state)), + hdr.opcode); + rc = adsp_err_get_lnx_err_code(atomic_read(state)); + goto fail_cmd; + } + + if (cmd == CMD_FLUSH) + q6asm_reset_buf_state(ac); + if (cmd == CMD_CLOSE) { + /* check if DSP return all buffers */ + if (ac->port[IN].buf) { + for (cnt = 0; cnt < ac->port[IN].max_buf_cnt; + cnt++) { + if (ac->port[IN].buf[cnt].used == IN) { + dev_vdbg(ac->dev, "Write Buf[%d] not returned\n", + cnt); + } + } + } + if (ac->port[OUT].buf) { + for (cnt = 0; cnt < ac->port[OUT].max_buf_cnt; cnt++) { + if (ac->port[OUT].buf[cnt].used == OUT) { + dev_vdbg(ac->dev, "Read Buf[%d] not returned\n", + cnt); + } + } + } + } + return 0; +fail_cmd: + return rc; +} + +int q6asm_cmd(struct audio_client *ac, int cmd) +{ + return __q6asm_cmd(ac, cmd, ac->stream_id); +} + +int q6asm_stream_cmd(struct audio_client *ac, int cmd, uint32_t stream_id) +{ + return __q6asm_cmd(ac, cmd, stream_id); +} + +static int __q6asm_cmd_nowait(struct audio_client *ac, int cmd, + uint32_t stream_id) +{ + struct apr_hdr hdr; + int rc; + + if (!ac) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + q6asm_stream_add_hdr_async(ac, &hdr, sizeof(hdr), TRUE, stream_id); + atomic_set(&ac->cmd_state, 1); + /* + * Updated the token field with stream/session for compressed playback + * Platform driver must know the the stream with which the command is + * associated + */ + if (ac->io_mode & COMPRESSED_STREAM_IO) + q6asm_update_token(&hdr.token, + ac->session, + stream_id, + 0, /* Buffer index is NA */ + 0, /* Direction flag is NA */ + NO_WAIT_CMD); + + pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x\n", + __func__, hdr.token, stream_id, ac->session); + switch (cmd) { + case CMD_PAUSE: + pr_debug("%s: CMD_PAUSE\n", __func__); + hdr.opcode = ASM_SESSION_CMD_PAUSE; + break; + case CMD_EOS: + pr_debug("%s: CMD_EOS\n", __func__); + hdr.opcode = ASM_DATA_CMD_EOS; + break; + case CMD_CLOSE: + pr_debug("%s: CMD_CLOSE\n", __func__); + hdr.opcode = ASM_STREAM_CMD_CLOSE; + break; + default: + pr_err("%s: Invalid format[%d]\n", __func__, cmd); + goto fail_cmd; + } + pr_debug("%s: session[%d]opcode[0x%x]\n", __func__, + ac->session, + hdr.opcode); + + rc = apr_send_pkt(ac->apr, (uint32_t *) &hdr); + if (rc < 0) { + pr_err("%s: Commmand 0x%x failed %d\n", + __func__, hdr.opcode, rc); + goto fail_cmd; + } + return 0; +fail_cmd: + return -EINVAL; +} + +int q6asm_cmd_nowait(struct audio_client *ac, int cmd) +{ + pr_debug("%s: stream_id: %d\n", __func__, ac->stream_id); + return __q6asm_cmd_nowait(ac, cmd, ac->stream_id); +} + +int q6asm_stream_cmd_nowait(struct audio_client *ac, int cmd, + uint32_t stream_id) +{ + pr_debug("%s: stream_id: %d\n", __func__, stream_id); + return __q6asm_cmd_nowait(ac, cmd, stream_id); +} + +int __q6asm_send_meta_data(struct audio_client *ac, uint32_t stream_id, + uint32_t initial_samples, uint32_t trailing_samples) +{ + struct asm_data_cmd_remove_silence silence; + int rc = 0; + + if (!ac) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: session[%d]\n", __func__, ac->session); + q6asm_stream_add_hdr_async(ac, &silence.hdr, sizeof(silence), TRUE, + stream_id); + + /* + * Updated the token field with stream/session for compressed playback + * Platform driver must know the the stream with which the command is + * associated + */ + if (ac->io_mode & COMPRESSED_STREAM_IO) + q6asm_update_token(&silence.hdr.token, + ac->session, + stream_id, + 0, /* Buffer index is NA */ + 0, /* Direction flag is NA */ + NO_WAIT_CMD); + pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x\n", + __func__, silence.hdr.token, stream_id, ac->session); + + silence.hdr.opcode = ASM_DATA_CMD_REMOVE_INITIAL_SILENCE; + silence.num_samples_to_remove = initial_samples; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &silence); + if (rc < 0) { + pr_err("%s: Commmand silence failed[%d]", __func__, rc); + + goto fail_cmd; + } + + silence.hdr.opcode = ASM_DATA_CMD_REMOVE_TRAILING_SILENCE; + silence.num_samples_to_remove = trailing_samples; + + + rc = apr_send_pkt(ac->apr, (uint32_t *) &silence); + if (rc < 0) { + pr_err("%s: Commmand silence failed[%d]", __func__, rc); + goto fail_cmd; + } + + return 0; +fail_cmd: + return -EINVAL; +} + +int q6asm_stream_send_meta_data(struct audio_client *ac, uint32_t stream_id, + uint32_t initial_samples, uint32_t trailing_samples) +{ + return __q6asm_send_meta_data(ac, stream_id, initial_samples, + trailing_samples); +} + +int q6asm_send_meta_data(struct audio_client *ac, uint32_t initial_samples, + uint32_t trailing_samples) +{ + return __q6asm_send_meta_data(ac, ac->stream_id, initial_samples, + trailing_samples); +} + +static void q6asm_reset_buf_state(struct audio_client *ac) +{ + int cnt = 0; + int loopcnt = 0; + int used; + struct audio_port_data *port = NULL; + + if (ac->io_mode & SYNC_IO_MODE) { + used = (ac->io_mode & TUN_WRITE_IO_MODE ? 1 : 0); + mutex_lock(&ac->cmd_lock); + for (loopcnt = 0; loopcnt <= OUT; loopcnt++) { + port = &ac->port[loopcnt]; + cnt = port->max_buf_cnt - 1; + port->dsp_buf = 0; + port->cpu_buf = 0; + while (cnt >= 0) { + if (!port->buf) + continue; + port->buf[cnt].used = used; + cnt--; + } + } + mutex_unlock(&ac->cmd_lock); + } +} + +int q6asm_reg_tx_overflow(struct audio_client *ac, uint16_t enable) +{ + struct asm_session_cmd_regx_overflow tx_overflow; + int rc; + + if (!ac) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: session[%d]enable[%d]\n", __func__, + ac->session, enable); + q6asm_add_hdr(ac, &tx_overflow.hdr, sizeof(tx_overflow), TRUE); + atomic_set(&ac->cmd_state, -1); + + tx_overflow.hdr.opcode = + ASM_SESSION_CMD_REGISTER_FORX_OVERFLOW_EVENTS; + /* tx overflow event: enable */ + tx_overflow.enable_flag = enable; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &tx_overflow); + if (rc < 0) { + pr_err("%s: tx overflow op[0x%x]rc[%d]\n", + __func__, tx_overflow.hdr.opcode, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for tx overflow\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + + return 0; +fail_cmd: + return rc; +} + +int q6asm_reg_rx_underflow(struct audio_client *ac, uint16_t enable) +{ + struct asm_session_cmd_rgstr_rx_underflow rx_underflow; + int rc; + + if (!ac) { + pr_err("%s: AC APR handle NULL\n", __func__); + return -EINVAL; + } + if (ac->apr == NULL) { + pr_err("%s: APR handle NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: session[%d]enable[%d]\n", __func__, + ac->session, enable); + q6asm_add_hdr_async(ac, &rx_underflow.hdr, sizeof(rx_underflow), FALSE); + + rx_underflow.hdr.opcode = + ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS; + /* tx overflow event: enable */ + rx_underflow.enable_flag = enable; + + rc = apr_send_pkt(ac->apr, (uint32_t *) &rx_underflow); + if (rc < 0) { + pr_err("%s: tx overflow op[0x%x]rc[%d]\n", + __func__, rx_underflow.hdr.opcode, rc); + goto fail_cmd; + } + return 0; +fail_cmd: + return -EINVAL; +} + +int q6asm_adjust_session_clock(struct audio_client *ac, + uint32_t adjust_time_lsw, + uint32_t adjust_time_msw) +{ + int rc = 0; + int sz = 0; + struct asm_session_cmd_adjust_session_clock_v2 adjust_clock; + + pr_debug("%s: adjust_time_lsw is %x, adjust_time_msw is %x\n", __func__, + adjust_time_lsw, adjust_time_msw); + + if (!ac) { + pr_err("%s: audio client handle is NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + + if (ac->apr == NULL) { + pr_err("%s: ac->apr is NULL", __func__); + rc = -EINVAL; + goto fail_cmd; + } + + sz = sizeof(struct asm_session_cmd_adjust_session_clock_v2); + q6asm_add_hdr(ac, &adjust_clock.hdr, sz, TRUE); + atomic_set(&ac->cmd_state, -1); + adjust_clock.hdr.opcode = ASM_SESSION_CMD_ADJUST_SESSION_CLOCK_V2; + + adjust_clock.adjustime_lsw = adjust_time_lsw; + adjust_clock.adjustime_msw = adjust_time_msw; + + + rc = apr_send_pkt(ac->apr, (uint32_t *) &adjust_clock); + if (rc < 0) { + pr_err("%s: adjust_clock send failed paramid [0x%x]\n", + __func__, adjust_clock.hdr.opcode); + rc = -EINVAL; + goto fail_cmd; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout, adjust_clock paramid[0x%x]\n", + __func__, adjust_clock.hdr.opcode); + rc = -ETIMEDOUT; + goto fail_cmd; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + rc = 0; +fail_cmd: + return rc; +} + +/* + * q6asm_get_path_delay() - get the path delay for an audio session + * @ac: audio client handle + * + * Retrieves the current audio DSP path delay for the given audio session. + * + * Return: 0 on success, error code otherwise + */ +int q6asm_get_path_delay(struct audio_client *ac) +{ + int rc = 0; + struct apr_hdr hdr; + + if (!ac || ac->apr == NULL) { + pr_err("%s: invalid audio client\n", __func__); + return -EINVAL; + } + + hdr.opcode = ASM_SESSION_CMD_GET_PATH_DELAY_V2; + q6asm_add_hdr(ac, &hdr, sizeof(hdr), TRUE); + atomic_set(&ac->cmd_state, -1); + + rc = apr_send_pkt(ac->apr, (uint32_t *) &hdr); + if (rc < 0) { + pr_err("%s: Commmand 0x%x failed %d\n", __func__, + hdr.opcode, rc); + return rc; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5 * HZ); + if (!rc) { + pr_err("%s: timeout. waited for response opcode[0x%x]\n", + __func__, hdr.opcode); + return -ETIMEDOUT; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + return rc; + } + + return 0; +} + +int q6asm_get_apr_service_id(int session_id) +{ + pr_debug("%s:\n", __func__); + + if (session_id <= 0 || session_id > ASM_ACTIVE_STREAMS_ALLOWED) { + pr_err("%s: invalid session_id = %d\n", __func__, session_id); + return -EINVAL; + } + + return ((struct apr_svc *)session[session_id]->apr)->id; +} + +int q6asm_get_asm_topology(int session_id) +{ + int topology = -EINVAL; + + if (session_id <= 0 || session_id > ASM_ACTIVE_STREAMS_ALLOWED) { + pr_err("%s: invalid session_id = %d\n", __func__, session_id); + goto done; + } + if (session[session_id] == NULL) { + pr_err("%s: session not created for session id = %d\n", + __func__, session_id); + goto done; + } + topology = session[session_id]->topology; +done: + return topology; +} + +int q6asm_get_asm_app_type(int session_id) +{ + int app_type = -EINVAL; + + if (session_id <= 0 || session_id > ASM_ACTIVE_STREAMS_ALLOWED) { + pr_err("%s: invalid session_id = %d\n", __func__, session_id); + goto done; + } + if (session[session_id] == NULL) { + pr_err("%s: session not created for session id = %d\n", + __func__, session_id); + goto done; + } + app_type = session[session_id]->app_type; +done: + return app_type; +} + +static int q6asm_get_asm_topology_cal(void) +{ + int topology = DEFAULT_POPP_TOPOLOGY; + struct cal_block_data *cal_block = NULL; + + if (cal_data[ASM_TOPOLOGY_CAL] == NULL) + goto done; + + mutex_lock(&cal_data[ASM_TOPOLOGY_CAL]->lock); + cal_block = cal_utils_get_only_cal_block(cal_data[ASM_TOPOLOGY_CAL]); + if (cal_block == NULL) + goto unlock; + + topology = ((struct audio_cal_info_asm_top *) + cal_block->cal_info)->topology; +unlock: + mutex_unlock(&cal_data[ASM_TOPOLOGY_CAL]->lock); +done: + pr_debug("%s: Using topology %d\n", __func__, topology); + return topology; +} + +static int q6asm_get_asm_app_type_cal(void) +{ + int app_type = DEFAULT_APP_TYPE; + struct cal_block_data *cal_block = NULL; + + if (cal_data[ASM_TOPOLOGY_CAL] == NULL) + goto done; + + mutex_lock(&cal_data[ASM_TOPOLOGY_CAL]->lock); + cal_block = cal_utils_get_only_cal_block(cal_data[ASM_TOPOLOGY_CAL]); + if (cal_block == NULL) + goto unlock; + + app_type = ((struct audio_cal_info_asm_top *) + cal_block->cal_info)->app_type; + + if (app_type == 0) + app_type = DEFAULT_APP_TYPE; +unlock: + mutex_unlock(&cal_data[ASM_TOPOLOGY_CAL]->lock); +done: + pr_debug("%s: Using app_type %d\n", __func__, app_type); + return app_type; +} + +int q6asm_send_cal(struct audio_client *ac) +{ + struct cal_block_data *cal_block = NULL; + struct apr_hdr hdr; + char *asm_params = NULL; + struct asm_stream_cmd_set_pp_params_v2 payload_params; + int sz, rc = -EINVAL; + + pr_debug("%s:\n", __func__); + + if (!ac) { + pr_err("%s: APR handle NULL\n", __func__); + goto done; + } + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + goto done; + } + if (ac->io_mode & NT_MODE) { + pr_debug("%s: called for NT MODE, exiting\n", __func__); + goto done; + } + + if (cal_data[ASM_AUDSTRM_CAL] == NULL) + goto done; + + if (ac->perf_mode == ULTRA_LOW_LATENCY_PCM_MODE) { + rc = 0; /* no cal is required, not error case */ + goto done; + } + + mutex_lock(&cal_data[ASM_AUDSTRM_CAL]->lock); + cal_block = cal_utils_get_only_cal_block(cal_data[ASM_AUDSTRM_CAL]); + if (cal_block == NULL) { + pr_err("%s: cal_block is NULL\n", + __func__); + goto unlock; + } + + if (cal_block->cal_data.size == 0) { + rc = 0; /* not error case */ + pr_debug("%s: cal_data.size is 0, don't send cal data\n", + __func__); + goto unlock; + } + + rc = remap_cal_data(ASM_AUDSTRM_CAL_TYPE, cal_block); + if (rc) { + pr_err("%s: Remap_cal_data failed for cal %d!\n", + __func__, ASM_AUDSTRM_CAL); + goto unlock; + } + + sz = sizeof(struct apr_hdr) + + sizeof(struct asm_stream_cmd_set_pp_params_v2); + asm_params = kzalloc(sz, GFP_KERNEL); + if (!asm_params) { + pr_err("%s, asm params memory alloc failed", __func__); + rc = -ENOMEM; + goto unlock; + } + + /* asm_stream_cmd_set_pp_params_v2 has no APR header in it */ + q6asm_add_hdr_async(ac, &hdr, (sizeof(struct apr_hdr) + + sizeof(struct asm_stream_cmd_set_pp_params_v2)), TRUE); + + atomic_set(&ac->cmd_state_pp, -1); + hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; + payload_params.data_payload_addr_lsw = + lower_32_bits(cal_block->cal_data.paddr); + payload_params.data_payload_addr_msw = + msm_audio_populate_upper_32_bits( + cal_block->cal_data.paddr); + payload_params.mem_map_handle = cal_block->map_data.q6map_handle; + payload_params.data_payload_size = cal_block->cal_data.size; + memcpy(((u8 *)asm_params), &hdr, sizeof(struct apr_hdr)); + memcpy(((u8 *)asm_params + sizeof(struct apr_hdr)), &payload_params, + sizeof(struct asm_stream_cmd_set_pp_params_v2)); + + pr_debug("%s: phyaddr lsw = %x msw = %x, maphdl = %x calsize = %d\n", + __func__, payload_params.data_payload_addr_lsw, + payload_params.data_payload_addr_msw, + payload_params.mem_map_handle, + payload_params.data_payload_size); + + rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params); + if (rc < 0) { + pr_err("%s: audio audstrm cal send failed\n", __func__); + rc = -EINVAL; + goto free; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state_pp) >= 0), 5 * HZ); + if (!rc) { + pr_err("%s: timeout, audio audstrm cal send\n", __func__); + rc = -ETIMEDOUT; + goto free; + } + if (atomic_read(&ac->cmd_state_pp) > 0) { + pr_err("%s: DSP returned error[%d] audio audstrm cal send\n", + __func__, atomic_read(&ac->cmd_state_pp)); + rc = -EINVAL; + goto free; + } + + rc = 0; + +free: + kfree(asm_params); +unlock: + mutex_unlock(&cal_data[ASM_AUDSTRM_CAL]->lock); +done: + return rc; +} + +static int get_cal_type_index(int32_t cal_type) +{ + int ret = -EINVAL; + + switch (cal_type) { + case ASM_TOPOLOGY_CAL_TYPE: + ret = ASM_TOPOLOGY_CAL; + break; + case ASM_CUST_TOPOLOGY_CAL_TYPE: + ret = ASM_CUSTOM_TOP_CAL; + break; + case ASM_AUDSTRM_CAL_TYPE: + ret = ASM_AUDSTRM_CAL; + break; + case ASM_RTAC_APR_CAL_TYPE: + ret = ASM_RTAC_APR_CAL; + break; + default: + pr_err("%s: invalid cal type %d!\n", __func__, cal_type); + } + return ret; +} + +static int q6asm_alloc_cal(int32_t cal_type, + size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + + pr_debug("%s:\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + ret = cal_utils_alloc_cal(data_size, data, + cal_data[cal_index], 0, NULL); + if (ret < 0) { + pr_err("%s: cal_utils_alloc_block failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + ret = -EINVAL; + goto done; + } +done: + return ret; +} + +static int q6asm_dealloc_cal(int32_t cal_type, + size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + + pr_debug("%s:\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + ret = cal_utils_dealloc_cal(data_size, data, + cal_data[cal_index]); + if (ret < 0) { + pr_err("%s: cal_utils_dealloc_block failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + ret = -EINVAL; + goto done; + } +done: + return ret; +} + +static int q6asm_set_cal(int32_t cal_type, + size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + + pr_debug("%s:\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + ret = cal_utils_set_cal(data_size, data, + cal_data[cal_index], 0, NULL); + if (ret < 0) { + pr_err("%s: cal_utils_set_cal failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + ret = -EINVAL; + goto done; + } + + if (cal_index == ASM_CUSTOM_TOP_CAL) { + mutex_lock(&cal_data[ASM_CUSTOM_TOP_CAL]->lock); + set_custom_topology = 1; + mutex_unlock(&cal_data[ASM_CUSTOM_TOP_CAL]->lock); + } +done: + return ret; +} + +static void q6asm_delete_cal_data(void) +{ + pr_debug("%s:\n", __func__); + cal_utils_destroy_cal_types(ASM_MAX_CAL_TYPES, cal_data); +} + +static int q6asm_init_cal_data(void) +{ + int ret = 0; + struct cal_type_info cal_type_info[] = { + {{ASM_TOPOLOGY_CAL_TYPE, + {NULL, NULL, NULL, + q6asm_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{ASM_CUST_TOPOLOGY_CAL_TYPE, + {q6asm_alloc_cal, q6asm_dealloc_cal, NULL, + q6asm_set_cal, NULL, NULL} }, + {NULL, q6asm_unmap_cal_memory, cal_utils_match_buf_num} }, + + {{ASM_AUDSTRM_CAL_TYPE, + {q6asm_alloc_cal, q6asm_dealloc_cal, NULL, + q6asm_set_cal, NULL, NULL} }, + {NULL, q6asm_unmap_cal_memory, cal_utils_match_buf_num} }, + + {{ASM_RTAC_APR_CAL_TYPE, + {NULL, NULL, NULL, NULL, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} } + }; + pr_debug("%s\n", __func__); + + ret = cal_utils_create_cal_types(ASM_MAX_CAL_TYPES, cal_data, + cal_type_info); + if (ret < 0) { + pr_err("%s: could not create cal type! %d\n", + __func__, ret); + ret = -EINVAL; + goto err; + } + + return ret; +err: + q6asm_delete_cal_data(); + return ret; +} + +static int q6asm_is_valid_session(struct apr_client_data *data, void *priv) +{ + struct audio_client *ac = (struct audio_client *)priv; + union asm_token_struct asm_token; + + asm_token.token = data->token; + if (asm_token._token.session_id != ac->session) { + pr_err("%s: Invalid session[%d] rxed expected[%d]", + __func__, asm_token._token.session_id, ac->session); + return -EINVAL; + } + return 0; +} + +static int __init q6asm_init(void) +{ + int lcnt, ret; + + pr_debug("%s:\n", __func__); + + memset(session, 0, sizeof(session)); + set_custom_topology = 1; + + /*setup common client used for cal mem map */ + common_client.session = ASM_CONTROL_SESSION; + common_client.port[0].buf = &common_buf[0]; + common_client.port[1].buf = &common_buf[1]; + init_waitqueue_head(&common_client.cmd_wait); + init_waitqueue_head(&common_client.time_wait); + init_waitqueue_head(&common_client.mem_wait); + atomic_set(&common_client.time_flag, 1); + INIT_LIST_HEAD(&common_client.port[0].mem_map_handle); + INIT_LIST_HEAD(&common_client.port[1].mem_map_handle); + mutex_init(&common_client.cmd_lock); + for (lcnt = 0; lcnt <= OUT; lcnt++) { + mutex_init(&common_client.port[lcnt].lock); + spin_lock_init(&common_client.port[lcnt].dsp_lock); + } + atomic_set(&common_client.cmd_state, 0); + atomic_set(&common_client.mem_state, 0); + + ret = q6asm_init_cal_data(); + if (ret) + pr_err("%s: could not init cal data! ret %d\n", + __func__, ret); + + config_debug_fs_init(); + + return 0; +} + +static void __exit q6asm_exit(void) +{ + q6asm_delete_cal_data(); +} + +device_initcall(q6asm_init); +__exitcall(q6asm_exit); diff --git a/sound/soc/msm/qdsp6v2/q6audio-v2.c b/sound/soc/msm/qdsp6v2/q6audio-v2.c new file mode 100644 index 000000000000..ea78e6a6538e --- /dev/null +++ b/sound/soc/msm/qdsp6v2/q6audio-v2.c @@ -0,0 +1,807 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int q6audio_get_port_index(u16 port_id) +{ + switch (port_id) { + case PRIMARY_I2S_RX: return IDX_PRIMARY_I2S_RX; + case PRIMARY_I2S_TX: return IDX_PRIMARY_I2S_TX; + case AFE_PORT_ID_PRIMARY_PCM_RX: + return IDX_AFE_PORT_ID_PRIMARY_PCM_RX; + case AFE_PORT_ID_PRIMARY_PCM_TX: + return IDX_AFE_PORT_ID_PRIMARY_PCM_TX; + case AFE_PORT_ID_SECONDARY_PCM_RX: + return IDX_AFE_PORT_ID_SECONDARY_PCM_RX; + case AFE_PORT_ID_SECONDARY_PCM_TX: + return IDX_AFE_PORT_ID_SECONDARY_PCM_TX; + case AFE_PORT_ID_TERTIARY_PCM_RX: + return IDX_AFE_PORT_ID_TERTIARY_PCM_RX; + case AFE_PORT_ID_TERTIARY_PCM_TX: + return IDX_AFE_PORT_ID_TERTIARY_PCM_TX; + case AFE_PORT_ID_QUATERNARY_PCM_RX: + return IDX_AFE_PORT_ID_QUATERNARY_PCM_RX; + case AFE_PORT_ID_QUATERNARY_PCM_TX: + return IDX_AFE_PORT_ID_QUATERNARY_PCM_TX; + case SECONDARY_I2S_RX: return IDX_SECONDARY_I2S_RX; + case SECONDARY_I2S_TX: return IDX_SECONDARY_I2S_TX; + case MI2S_RX: return IDX_MI2S_RX; + case MI2S_TX: return IDX_MI2S_TX; + case HDMI_RX: return IDX_HDMI_RX; + case DISPLAY_PORT_RX: return IDX_DISPLAY_PORT_RX; + case AFE_PORT_ID_SPDIF_RX: return IDX_SPDIF_RX; + case RSVD_2: return IDX_RSVD_2; + case RSVD_3: return IDX_RSVD_3; + case DIGI_MIC_TX: return IDX_DIGI_MIC_TX; + case VOICE_RECORD_RX: return IDX_VOICE_RECORD_RX; + case VOICE_RECORD_TX: return IDX_VOICE_RECORD_TX; + case VOICE_PLAYBACK_TX: return IDX_VOICE_PLAYBACK_TX; + case VOICE2_PLAYBACK_TX: return IDX_VOICE2_PLAYBACK_TX; + case SLIMBUS_0_RX: return IDX_SLIMBUS_0_RX; + case SLIMBUS_0_TX: return IDX_SLIMBUS_0_TX; + case SLIMBUS_1_RX: return IDX_SLIMBUS_1_RX; + case SLIMBUS_1_TX: return IDX_SLIMBUS_1_TX; + case SLIMBUS_2_RX: return IDX_SLIMBUS_2_RX; + case SLIMBUS_2_TX: return IDX_SLIMBUS_2_TX; + case SLIMBUS_3_RX: return IDX_SLIMBUS_3_RX; + case SLIMBUS_3_TX: return IDX_SLIMBUS_3_TX; + case SLIMBUS_4_RX: return IDX_SLIMBUS_4_RX; + case SLIMBUS_4_TX: return IDX_SLIMBUS_4_TX; + case SLIMBUS_5_RX: return IDX_SLIMBUS_5_RX; + case SLIMBUS_5_TX: return IDX_SLIMBUS_5_TX; + case SLIMBUS_6_RX: return IDX_SLIMBUS_6_RX; + case SLIMBUS_6_TX: return IDX_SLIMBUS_6_TX; + case SLIMBUS_7_RX: return IDX_SLIMBUS_7_RX; + case SLIMBUS_7_TX: return IDX_SLIMBUS_7_TX; + case SLIMBUS_8_RX: return IDX_SLIMBUS_8_RX; + case SLIMBUS_8_TX: return IDX_SLIMBUS_8_TX; + case INT_BT_SCO_RX: return IDX_INT_BT_SCO_RX; + case INT_BT_SCO_TX: return IDX_INT_BT_SCO_TX; + case INT_BT_A2DP_RX: return IDX_INT_BT_A2DP_RX; + case INT_FM_RX: return IDX_INT_FM_RX; + case INT_FM_TX: return IDX_INT_FM_TX; + case RT_PROXY_PORT_001_RX: return IDX_RT_PROXY_PORT_001_RX; + case RT_PROXY_PORT_001_TX: return IDX_RT_PROXY_PORT_001_TX; + case AFE_PORT_ID_PRIMARY_MI2S_RX: + return IDX_AFE_PORT_ID_PRIMARY_MI2S_RX; + case AFE_PORT_ID_PRIMARY_MI2S_TX: + return IDX_AFE_PORT_ID_PRIMARY_MI2S_TX; + case AFE_PORT_ID_QUATERNARY_MI2S_RX: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX; + case AFE_PORT_ID_QUATERNARY_MI2S_TX: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX; + case AFE_PORT_ID_SECONDARY_MI2S_RX: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX; + case AFE_PORT_ID_SECONDARY_MI2S_TX: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX; + case AFE_PORT_ID_TERTIARY_MI2S_RX: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX; + case AFE_PORT_ID_TERTIARY_MI2S_TX: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX; + case AUDIO_PORT_ID_I2S_RX: + return IDX_AUDIO_PORT_ID_I2S_RX; + case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_SD1; + case AFE_PORT_ID_PRIMARY_TDM_RX: + return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_0; + case AFE_PORT_ID_PRIMARY_TDM_TX: + return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_0; + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_1; + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_1; + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_2; + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_2; + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_3; + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_3; + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_4; + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_4; + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_5; + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_5; + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_6; + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_6; + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + return IDX_AFE_PORT_ID_PRIMARY_TDM_RX_7; + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + return IDX_AFE_PORT_ID_PRIMARY_TDM_TX_7; + case AFE_PORT_ID_SECONDARY_TDM_RX: + return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_0; + case AFE_PORT_ID_SECONDARY_TDM_TX: + return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_0; + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_1; + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_1; + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_2; + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_2; + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_3; + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_3; + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_4; + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_4; + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_5; + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_5; + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_6; + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_6; + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + return IDX_AFE_PORT_ID_SECONDARY_TDM_RX_7; + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + return IDX_AFE_PORT_ID_SECONDARY_TDM_TX_7; + case AFE_PORT_ID_TERTIARY_TDM_RX: + return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_0; + case AFE_PORT_ID_TERTIARY_TDM_TX: + return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_0; + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_1; + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_1; + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_2; + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_2; + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_3; + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_3; + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_4; + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_4; + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_5; + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_5; + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_6; + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_6; + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + return IDX_AFE_PORT_ID_TERTIARY_TDM_RX_7; + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + return IDX_AFE_PORT_ID_TERTIARY_TDM_TX_7; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_0; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_0; + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_1; + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_1; + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_2; + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_2; + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_3; + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_3; + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_4; + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_4; + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_5; + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_5; + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_6; + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_6; + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_7; + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_7; + case AFE_PORT_ID_SENARY_MI2S_TX: + return IDX_AFE_PORT_ID_SENARY_MI2S_TX; + case AFE_PORT_ID_USB_RX: + return IDX_AFE_PORT_ID_USB_RX; + case AFE_PORT_ID_USB_TX: + return IDX_AFE_PORT_ID_USB_TX; + case AFE_PORT_ID_INT0_MI2S_RX: + return IDX_AFE_PORT_ID_INT0_MI2S_RX; + case AFE_PORT_ID_INT0_MI2S_TX: + return IDX_AFE_PORT_ID_INT0_MI2S_TX; + case AFE_PORT_ID_INT1_MI2S_RX: + return IDX_AFE_PORT_ID_INT1_MI2S_RX; + case AFE_PORT_ID_INT1_MI2S_TX: + return IDX_AFE_PORT_ID_INT1_MI2S_TX; + case AFE_PORT_ID_INT2_MI2S_RX: + return IDX_AFE_PORT_ID_INT2_MI2S_RX; + case AFE_PORT_ID_INT2_MI2S_TX: + return IDX_AFE_PORT_ID_INT2_MI2S_TX; + case AFE_PORT_ID_INT3_MI2S_RX: + return IDX_AFE_PORT_ID_INT3_MI2S_RX; + case AFE_PORT_ID_INT3_MI2S_TX: + return IDX_AFE_PORT_ID_INT3_MI2S_TX; + case AFE_PORT_ID_INT4_MI2S_RX: + return IDX_AFE_PORT_ID_INT4_MI2S_RX; + case AFE_PORT_ID_INT4_MI2S_TX: + return IDX_AFE_PORT_ID_INT4_MI2S_TX; + case AFE_PORT_ID_INT5_MI2S_RX: + return IDX_AFE_PORT_ID_INT5_MI2S_RX; + case AFE_PORT_ID_INT5_MI2S_TX: + return IDX_AFE_PORT_ID_INT5_MI2S_TX; + case AFE_PORT_ID_INT6_MI2S_RX: + return IDX_AFE_PORT_ID_INT6_MI2S_RX; + case AFE_PORT_ID_INT6_MI2S_TX: + return IDX_AFE_PORT_ID_INT6_MI2S_TX; + default: return -EINVAL; + } +} + +int q6audio_get_port_id(u16 port_id) +{ + switch (port_id) { + case PRIMARY_I2S_RX: return PRIMARY_I2S_RX; + case PRIMARY_I2S_TX: return PRIMARY_I2S_TX; + case AFE_PORT_ID_PRIMARY_PCM_RX: + return AFE_PORT_ID_PRIMARY_PCM_RX; + case AFE_PORT_ID_PRIMARY_PCM_TX: + return AFE_PORT_ID_PRIMARY_PCM_TX; + case AFE_PORT_ID_SECONDARY_PCM_RX: + return AFE_PORT_ID_SECONDARY_PCM_RX; + case AFE_PORT_ID_SECONDARY_PCM_TX: + return AFE_PORT_ID_SECONDARY_PCM_TX; + case AFE_PORT_ID_TERTIARY_PCM_RX: + return AFE_PORT_ID_TERTIARY_PCM_RX; + case AFE_PORT_ID_TERTIARY_PCM_TX: + return AFE_PORT_ID_TERTIARY_PCM_TX; + case AFE_PORT_ID_QUATERNARY_PCM_RX: + return AFE_PORT_ID_QUATERNARY_PCM_RX; + case AFE_PORT_ID_QUATERNARY_PCM_TX: + return AFE_PORT_ID_QUATERNARY_PCM_TX; + case SECONDARY_I2S_RX: return AFE_PORT_ID_SECONDARY_MI2S_RX; + case SECONDARY_I2S_TX: return AFE_PORT_ID_SECONDARY_MI2S_TX; + case MI2S_RX: return AFE_PORT_ID_PRIMARY_MI2S_RX; + case MI2S_TX: return AFE_PORT_ID_PRIMARY_MI2S_TX; + case HDMI_RX: return AFE_PORT_ID_MULTICHAN_HDMI_RX; + case DISPLAY_PORT_RX: + return AFE_PORT_ID_HDMI_OVER_DP_RX; + case AFE_PORT_ID_SPDIF_RX: return AFE_PORT_ID_SPDIF_RX; + case RSVD_2: return IDX_RSVD_2; + case RSVD_3: return IDX_RSVD_3; + case DIGI_MIC_TX: return AFE_PORT_ID_DIGITAL_MIC_TX; + case VOICE_RECORD_RX: return AFE_PORT_ID_VOICE_RECORD_RX; + case VOICE_RECORD_TX: return AFE_PORT_ID_VOICE_RECORD_TX; + case VOICE_PLAYBACK_TX: return AFE_PORT_ID_VOICE_PLAYBACK_TX; + case VOICE2_PLAYBACK_TX: return AFE_PORT_ID_VOICE2_PLAYBACK_TX; + case SLIMBUS_0_RX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX; + case SLIMBUS_0_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX; + case SLIMBUS_1_RX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX; + case SLIMBUS_1_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX; + case SLIMBUS_2_RX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX; + case SLIMBUS_2_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX; + case SLIMBUS_3_RX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX; + case SLIMBUS_3_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX; + case SLIMBUS_4_RX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX; + case SLIMBUS_4_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX; + case SLIMBUS_5_RX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX; + case SLIMBUS_5_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX; + case SLIMBUS_6_RX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX; + case SLIMBUS_6_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX; + case SLIMBUS_7_RX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_7_RX; + case SLIMBUS_7_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_7_TX; + case SLIMBUS_8_RX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_8_RX; + case SLIMBUS_8_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_8_TX; + case INT_BT_SCO_RX: return AFE_PORT_ID_INTERNAL_BT_SCO_RX; + case INT_BT_SCO_TX: return AFE_PORT_ID_INTERNAL_BT_SCO_TX; + case INT_BT_A2DP_RX: return AFE_PORT_ID_INTERNAL_BT_A2DP_RX; + case INT_FM_RX: return AFE_PORT_ID_INTERNAL_FM_RX; + case INT_FM_TX: return AFE_PORT_ID_INTERNAL_FM_TX; + case RT_PROXY_PORT_001_RX: return AFE_PORT_ID_RT_PROXY_PORT_001_RX; + case RT_PROXY_PORT_001_TX: return AFE_PORT_ID_RT_PROXY_PORT_001_TX; + case AFE_PORT_ID_PRIMARY_MI2S_RX: + return AFE_PORT_ID_PRIMARY_MI2S_RX; + case AFE_PORT_ID_PRIMARY_MI2S_TX: + return AFE_PORT_ID_PRIMARY_MI2S_TX; + case AFE_PORT_ID_QUATERNARY_MI2S_RX: + return AFE_PORT_ID_QUATERNARY_MI2S_RX; + case AFE_PORT_ID_QUATERNARY_MI2S_TX: + return AFE_PORT_ID_QUATERNARY_MI2S_TX; + case AFE_PORT_ID_SECONDARY_MI2S_RX: + return AFE_PORT_ID_SECONDARY_MI2S_RX; + case AFE_PORT_ID_SECONDARY_MI2S_TX: + return AFE_PORT_ID_SECONDARY_MI2S_TX; + case AFE_PORT_ID_TERTIARY_MI2S_RX: + return AFE_PORT_ID_TERTIARY_MI2S_RX; + case AFE_PORT_ID_TERTIARY_MI2S_TX: + return AFE_PORT_ID_TERTIARY_MI2S_TX; + case AUDIO_PORT_ID_I2S_RX: + return AUDIO_PORT_ID_I2S_RX; + case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1: + return AFE_PORT_ID_SECONDARY_MI2S_RX_SD1; + case AFE_PORT_ID_PRIMARY_TDM_RX: + return AFE_PORT_ID_PRIMARY_TDM_RX; + case AFE_PORT_ID_PRIMARY_TDM_TX: + return AFE_PORT_ID_PRIMARY_TDM_TX; + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + return AFE_PORT_ID_PRIMARY_TDM_RX_1; + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + return AFE_PORT_ID_PRIMARY_TDM_TX_1; + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + return AFE_PORT_ID_PRIMARY_TDM_RX_2; + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + return AFE_PORT_ID_PRIMARY_TDM_TX_2; + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + return AFE_PORT_ID_PRIMARY_TDM_RX_3; + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + return AFE_PORT_ID_PRIMARY_TDM_TX_3; + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + return AFE_PORT_ID_PRIMARY_TDM_RX_4; + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + return AFE_PORT_ID_PRIMARY_TDM_TX_4; + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + return AFE_PORT_ID_PRIMARY_TDM_RX_5; + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + return AFE_PORT_ID_PRIMARY_TDM_TX_5; + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + return AFE_PORT_ID_PRIMARY_TDM_RX_6; + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + return AFE_PORT_ID_PRIMARY_TDM_TX_6; + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + return AFE_PORT_ID_PRIMARY_TDM_RX_7; + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + return AFE_PORT_ID_PRIMARY_TDM_TX_7; + case AFE_PORT_ID_SECONDARY_TDM_RX: + return AFE_PORT_ID_SECONDARY_TDM_RX; + case AFE_PORT_ID_SECONDARY_TDM_TX: + return AFE_PORT_ID_SECONDARY_TDM_TX; + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + return AFE_PORT_ID_SECONDARY_TDM_RX_1; + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + return AFE_PORT_ID_SECONDARY_TDM_TX_1; + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + return AFE_PORT_ID_SECONDARY_TDM_RX_2; + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + return AFE_PORT_ID_SECONDARY_TDM_TX_2; + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + return AFE_PORT_ID_SECONDARY_TDM_RX_3; + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + return AFE_PORT_ID_SECONDARY_TDM_TX_3; + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + return AFE_PORT_ID_SECONDARY_TDM_RX_4; + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + return AFE_PORT_ID_SECONDARY_TDM_TX_4; + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + return AFE_PORT_ID_SECONDARY_TDM_RX_5; + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + return AFE_PORT_ID_SECONDARY_TDM_TX_5; + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + return AFE_PORT_ID_SECONDARY_TDM_RX_6; + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + return AFE_PORT_ID_SECONDARY_TDM_TX_6; + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + return AFE_PORT_ID_SECONDARY_TDM_RX_7; + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + return AFE_PORT_ID_SECONDARY_TDM_TX_7; + case AFE_PORT_ID_TERTIARY_TDM_RX: + return AFE_PORT_ID_TERTIARY_TDM_RX; + case AFE_PORT_ID_TERTIARY_TDM_TX: + return AFE_PORT_ID_TERTIARY_TDM_TX; + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + return AFE_PORT_ID_TERTIARY_TDM_RX_1; + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + return AFE_PORT_ID_TERTIARY_TDM_TX_1; + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + return AFE_PORT_ID_TERTIARY_TDM_RX_2; + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + return AFE_PORT_ID_TERTIARY_TDM_TX_2; + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + return AFE_PORT_ID_TERTIARY_TDM_RX_3; + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + return AFE_PORT_ID_TERTIARY_TDM_TX_3; + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + return AFE_PORT_ID_TERTIARY_TDM_RX_4; + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + return AFE_PORT_ID_TERTIARY_TDM_TX_4; + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + return AFE_PORT_ID_TERTIARY_TDM_RX_5; + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + return AFE_PORT_ID_TERTIARY_TDM_TX_5; + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + return AFE_PORT_ID_TERTIARY_TDM_RX_6; + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + return AFE_PORT_ID_TERTIARY_TDM_TX_6; + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + return AFE_PORT_ID_TERTIARY_TDM_RX_7; + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + return AFE_PORT_ID_TERTIARY_TDM_TX_7; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + return AFE_PORT_ID_QUATERNARY_TDM_RX; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + return AFE_PORT_ID_QUATERNARY_TDM_TX; + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + return AFE_PORT_ID_QUATERNARY_TDM_RX_1; + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + return AFE_PORT_ID_QUATERNARY_TDM_TX_1; + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + return AFE_PORT_ID_QUATERNARY_TDM_RX_2; + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + return AFE_PORT_ID_QUATERNARY_TDM_TX_2; + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + return AFE_PORT_ID_QUATERNARY_TDM_RX_3; + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + return AFE_PORT_ID_QUATERNARY_TDM_TX_3; + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + return AFE_PORT_ID_QUATERNARY_TDM_RX_4; + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + return AFE_PORT_ID_QUATERNARY_TDM_TX_4; + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + return AFE_PORT_ID_QUATERNARY_TDM_RX_5; + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + return AFE_PORT_ID_QUATERNARY_TDM_TX_5; + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + return AFE_PORT_ID_QUATERNARY_TDM_RX_6; + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + return AFE_PORT_ID_QUATERNARY_TDM_TX_6; + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + return AFE_PORT_ID_QUATERNARY_TDM_RX_7; + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + return AFE_PORT_ID_QUATERNARY_TDM_TX_7; + case AFE_PORT_ID_SENARY_MI2S_TX: + return AFE_PORT_ID_SENARY_MI2S_TX; + case AFE_PORT_ID_USB_RX: + return AFE_PORT_ID_USB_RX; + case AFE_PORT_ID_USB_TX: + return AFE_PORT_ID_USB_TX; + case AFE_PORT_ID_INT0_MI2S_RX: + return AFE_PORT_ID_INT0_MI2S_RX; + case AFE_PORT_ID_INT0_MI2S_TX: + return AFE_PORT_ID_INT0_MI2S_TX; + case AFE_PORT_ID_INT1_MI2S_RX: + return AFE_PORT_ID_INT1_MI2S_RX; + case AFE_PORT_ID_INT1_MI2S_TX: + return AFE_PORT_ID_INT1_MI2S_TX; + case AFE_PORT_ID_INT2_MI2S_RX: + return AFE_PORT_ID_INT2_MI2S_RX; + case AFE_PORT_ID_INT2_MI2S_TX: + return AFE_PORT_ID_INT2_MI2S_TX; + case AFE_PORT_ID_INT3_MI2S_RX: + return AFE_PORT_ID_INT3_MI2S_RX; + case AFE_PORT_ID_INT3_MI2S_TX: + return AFE_PORT_ID_INT3_MI2S_TX; + case AFE_PORT_ID_INT4_MI2S_RX: + return AFE_PORT_ID_INT4_MI2S_RX; + case AFE_PORT_ID_INT4_MI2S_TX: + return AFE_PORT_ID_INT4_MI2S_TX; + case AFE_PORT_ID_INT5_MI2S_RX: + return AFE_PORT_ID_INT5_MI2S_RX; + case AFE_PORT_ID_INT5_MI2S_TX: + return AFE_PORT_ID_INT5_MI2S_TX; + case AFE_PORT_ID_INT6_MI2S_RX: + return AFE_PORT_ID_INT6_MI2S_RX; + case AFE_PORT_ID_INT6_MI2S_TX: + return AFE_PORT_ID_INT6_MI2S_TX; + default: + pr_warn("%s: Invalid port_id %d\n", __func__, port_id); + return -EINVAL; + } +} +int q6audio_convert_virtual_to_portid(u16 port_id) +{ + int ret; + + /* if port_id is virtual, convert to physical.. + * if port_id is already physical, return physical + */ + if (q6audio_validate_port(port_id) < 0) { + if (port_id == RT_PROXY_DAI_001_RX || + port_id == RT_PROXY_DAI_001_TX || + port_id == RT_PROXY_DAI_002_RX || + port_id == RT_PROXY_DAI_002_TX) + ret = VIRTUAL_ID_TO_PORTID(port_id); + else + ret = -EINVAL; + } else + ret = port_id; + + return ret; +} + +int q6audio_is_digital_pcm_interface(u16 port_id) +{ + int ret = 0; + + switch (port_id) { + case PRIMARY_I2S_RX: + case PRIMARY_I2S_TX: + case AFE_PORT_ID_PRIMARY_PCM_RX: + case AFE_PORT_ID_PRIMARY_PCM_TX: + case AFE_PORT_ID_SECONDARY_PCM_RX: + case AFE_PORT_ID_SECONDARY_PCM_TX: + case AFE_PORT_ID_TERTIARY_PCM_RX: + case AFE_PORT_ID_TERTIARY_PCM_TX: + case AFE_PORT_ID_QUATERNARY_PCM_RX: + case AFE_PORT_ID_QUATERNARY_PCM_TX: + case SECONDARY_I2S_RX: + case SECONDARY_I2S_TX: + case MI2S_RX: + case MI2S_TX: + case AFE_PORT_ID_TERTIARY_MI2S_TX: + case AFE_PORT_ID_TERTIARY_MI2S_RX: + case AFE_PORT_ID_QUATERNARY_MI2S_RX: + case AFE_PORT_ID_QUATERNARY_MI2S_TX: + case AFE_PORT_ID_PRIMARY_MI2S_RX: + case AFE_PORT_ID_PRIMARY_MI2S_TX: + case AFE_PORT_ID_SECONDARY_MI2S_RX: + case AFE_PORT_ID_SECONDARY_MI2S_TX: + case AUDIO_PORT_ID_I2S_RX: + case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1: + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + case AFE_PORT_ID_SENARY_MI2S_TX: + case AFE_PORT_ID_INT0_MI2S_RX: + case AFE_PORT_ID_INT0_MI2S_TX: + case AFE_PORT_ID_INT1_MI2S_RX: + case AFE_PORT_ID_INT1_MI2S_TX: + case AFE_PORT_ID_INT2_MI2S_RX: + case AFE_PORT_ID_INT2_MI2S_TX: + case AFE_PORT_ID_INT3_MI2S_RX: + case AFE_PORT_ID_INT3_MI2S_TX: + case AFE_PORT_ID_INT4_MI2S_RX: + case AFE_PORT_ID_INT4_MI2S_TX: + case AFE_PORT_ID_INT5_MI2S_RX: + case AFE_PORT_ID_INT5_MI2S_TX: + case AFE_PORT_ID_INT6_MI2S_RX: + case AFE_PORT_ID_INT6_MI2S_TX: + break; + default: + ret = -EINVAL; + } + + return ret; +} + +int q6audio_validate_port(u16 port_id) +{ + int ret; + + switch (port_id) { + case PRIMARY_I2S_RX: + case PRIMARY_I2S_TX: + case AFE_PORT_ID_PRIMARY_PCM_RX: + case AFE_PORT_ID_PRIMARY_PCM_TX: + case AFE_PORT_ID_SECONDARY_PCM_RX: + case AFE_PORT_ID_SECONDARY_PCM_TX: + case AFE_PORT_ID_TERTIARY_PCM_RX: + case AFE_PORT_ID_TERTIARY_PCM_TX: + case AFE_PORT_ID_QUATERNARY_PCM_RX: + case AFE_PORT_ID_QUATERNARY_PCM_TX: + case SECONDARY_I2S_RX: + case SECONDARY_I2S_TX: + case MI2S_RX: + case MI2S_TX: + case HDMI_RX: + case DISPLAY_PORT_RX: + case RSVD_2: + case RSVD_3: + case DIGI_MIC_TX: + case VOICE_RECORD_RX: + case VOICE_RECORD_TX: + case VOICE_PLAYBACK_TX: + case VOICE2_PLAYBACK_TX: + case SLIMBUS_0_RX: + case SLIMBUS_0_TX: + case SLIMBUS_1_RX: + case SLIMBUS_1_TX: + case SLIMBUS_2_RX: + case SLIMBUS_2_TX: + case SLIMBUS_3_RX: + case SLIMBUS_3_TX: + case SLIMBUS_4_RX: + case SLIMBUS_4_TX: + case SLIMBUS_5_RX: + case SLIMBUS_5_TX: + case SLIMBUS_6_RX: + case SLIMBUS_6_TX: + case SLIMBUS_7_RX: + case SLIMBUS_7_TX: + case SLIMBUS_8_RX: + case SLIMBUS_8_TX: + case INT_BT_SCO_RX: + case INT_BT_SCO_TX: + case INT_BT_A2DP_RX: + case INT_FM_RX: + case INT_FM_TX: + case RT_PROXY_PORT_001_RX: + case RT_PROXY_PORT_001_TX: + case AFE_PORT_ID_PRIMARY_MI2S_RX: + case AFE_PORT_ID_PRIMARY_MI2S_TX: + case AFE_PORT_ID_QUATERNARY_MI2S_RX: + case AFE_PORT_ID_QUATERNARY_MI2S_TX: + case AFE_PORT_ID_SECONDARY_MI2S_RX: + case AFE_PORT_ID_SECONDARY_MI2S_TX: + case AFE_PORT_ID_SPDIF_RX: + case AFE_PORT_ID_TERTIARY_MI2S_RX: + case AFE_PORT_ID_TERTIARY_MI2S_TX: + case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1: + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + case AFE_PORT_ID_SENARY_MI2S_TX: + case AFE_PORT_ID_USB_RX: + case AFE_PORT_ID_USB_TX: + case AFE_PORT_ID_INT0_MI2S_RX: + case AFE_PORT_ID_INT0_MI2S_TX: + case AFE_PORT_ID_INT1_MI2S_RX: + case AFE_PORT_ID_INT1_MI2S_TX: + case AFE_PORT_ID_INT2_MI2S_RX: + case AFE_PORT_ID_INT2_MI2S_TX: + case AFE_PORT_ID_INT3_MI2S_RX: + case AFE_PORT_ID_INT3_MI2S_TX: + case AFE_PORT_ID_INT4_MI2S_RX: + case AFE_PORT_ID_INT4_MI2S_TX: + case AFE_PORT_ID_INT5_MI2S_RX: + case AFE_PORT_ID_INT5_MI2S_TX: + case AFE_PORT_ID_INT6_MI2S_RX: + case AFE_PORT_ID_INT6_MI2S_TX: + { + ret = 0; + break; + } + + default: + ret = -EINVAL; + } + + return ret; +} diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c new file mode 100644 index 000000000000..3aaaa35e535b --- /dev/null +++ b/sound/soc/msm/qdsp6v2/q6core.c @@ -0,0 +1,853 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TIMEOUT_MS 1000 +/* + * AVS bring up in the modem is optimitized for the new + * Sub System Restart design and 100 milliseconds timeout + * is sufficient to make sure the Q6 will be ready. + */ +#define Q6_READY_TIMEOUT_MS 100 + +enum { + META_CAL, + CUST_TOP_CAL, + CORE_MAX_CAL +}; + +struct q6core_str { + struct apr_svc *core_handle_q; + wait_queue_head_t bus_bw_req_wait; + wait_queue_head_t cmd_req_wait; + u32 bus_bw_resp_received; + enum cmd_flags { + FLAG_NONE, + FLAG_CMDRSP_LICENSE_RESULT + } cmd_resp_received_flag; + struct mutex cmd_lock; + union { + struct avcs_cmdrsp_get_license_validation_result + cmdrsp_license_result; + } cmd_resp_payload; + u32 param; + struct cal_type_data *cal_data[CORE_MAX_CAL]; + uint32_t mem_map_cal_handle; + int32_t adsp_status; +}; + +static struct q6core_str q6core_lcl; + +struct generic_get_data_ { + int valid; + int size_in_ints; + int ints[]; +}; +static struct generic_get_data_ *generic_get_data; + +static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) +{ + uint32_t *payload1; + + if (data == NULL) { + pr_err("%s: data argument is null\n", __func__); + return -EINVAL; + } + + pr_debug("%s: core msg: payload len = %u, apr resp opcode = 0x%x\n", + __func__, + data->payload_size, data->opcode); + + switch (data->opcode) { + + case APR_BASIC_RSP_RESULT:{ + + if (data->payload_size == 0) { + pr_err("%s: APR_BASIC_RSP_RESULT No Payload ", + __func__); + return 0; + } + + payload1 = data->payload; + + switch (payload1[0]) { + + case AVCS_CMD_SHARED_MEM_UNMAP_REGIONS: + pr_debug("%s: Cmd = AVCS_CMD_SHARED_MEM_UNMAP_REGIONS status[0x%x]\n", + __func__, payload1[1]); + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; + case AVCS_CMD_SHARED_MEM_MAP_REGIONS: + pr_debug("%s: Cmd = AVCS_CMD_SHARED_MEM_MAP_REGIONS status[0x%x]\n", + __func__, payload1[1]); + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; + case AVCS_CMD_REGISTER_TOPOLOGIES: + pr_debug("%s: Cmd = AVCS_CMD_REGISTER_TOPOLOGIES status[0x%x]\n", + __func__, payload1[1]); + /* -ADSP status to match Linux error standard */ + q6core_lcl.adsp_status = -payload1[1]; + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; + case AVCS_CMD_DEREGISTER_TOPOLOGIES: + pr_debug("%s: Cmd = AVCS_CMD_DEREGISTER_TOPOLOGIES status[0x%x]\n", + __func__, payload1[1]); + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; + default: + pr_err("%s: Invalid cmd rsp[0x%x][0x%x] opcode %d\n", + __func__, + payload1[0], payload1[1], data->opcode); + break; + } + break; + } + + case RESET_EVENTS:{ + pr_debug("%s: Reset event received in Core service\n", + __func__); + apr_reset(q6core_lcl.core_handle_q); + q6core_lcl.core_handle_q = NULL; + break; + } + case AVCS_CMDRSP_SHARED_MEM_MAP_REGIONS: + payload1 = data->payload; + pr_debug("%s: AVCS_CMDRSP_SHARED_MEM_MAP_REGIONS handle %d\n", + __func__, payload1[0]); + q6core_lcl.mem_map_cal_handle = payload1[0]; + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; + case AVCS_CMDRSP_ADSP_EVENT_GET_STATE: + payload1 = data->payload; + q6core_lcl.param = payload1[0]; + pr_debug("%s: Received ADSP get state response 0x%x\n", + __func__, q6core_lcl.param); + /* ensure .param is updated prior to .bus_bw_resp_received */ + wmb(); + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; + case AVCS_CMDRSP_GET_LICENSE_VALIDATION_RESULT: + payload1 = data->payload; + pr_debug("%s: cmd = LICENSE_VALIDATION_RESULT, result = 0x%x\n", + __func__, payload1[0]); + q6core_lcl.cmd_resp_payload.cmdrsp_license_result.result + = payload1[0]; + q6core_lcl.cmd_resp_received_flag = FLAG_CMDRSP_LICENSE_RESULT; + wake_up(&q6core_lcl.cmd_req_wait); + break; + default: + pr_err("%s: Message id from adsp core svc: 0x%x\n", + __func__, data->opcode); + if (generic_get_data) { + generic_get_data->valid = 1; + generic_get_data->size_in_ints = + data->payload_size/sizeof(int); + pr_debug("callback size = %i\n", + data->payload_size); + memcpy(generic_get_data->ints, data->payload, + data->payload_size); + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; + } + break; + } + + return 0; +} + +void ocm_core_open(void) +{ + if (q6core_lcl.core_handle_q == NULL) + q6core_lcl.core_handle_q = apr_register("ADSP", "CORE", + aprv2_core_fn_q, 0xFFFFFFFF, NULL); + pr_debug("%s: Open_q %pK\n", __func__, q6core_lcl.core_handle_q); + if (q6core_lcl.core_handle_q == NULL) + pr_err("%s: Unable to register CORE\n", __func__); +} + +struct cal_block_data *cal_utils_get_cal_block_by_key( + struct cal_type_data *cal_type, uint32_t key) +{ + struct list_head *ptr, *next; + struct cal_block_data *cal_block = NULL; + struct audio_cal_info_metainfo *metainfo; + + list_for_each_safe(ptr, next, + &cal_type->cal_blocks) { + + cal_block = list_entry(ptr, + struct cal_block_data, list); + metainfo = (struct audio_cal_info_metainfo *) + cal_block->cal_info; + if (metainfo->nKey != key) { + pr_debug("%s: metainfo key mismatch!!! found:%x, needed:%x\n", + __func__, metainfo->nKey, key); + } else { + pr_debug("%s: metainfo key match found", __func__); + return cal_block; + } + } + return NULL; +} + +int32_t core_set_license(uint32_t key, uint32_t module_id) +{ + struct avcs_cmd_set_license *cmd_setl = NULL; + struct cal_block_data *cal_block = NULL; + int rc = 0, packet_size = 0; + + pr_debug("%s: key:0x%x, id:0x%x\n", __func__, key, module_id); + + mutex_lock(&(q6core_lcl.cmd_lock)); + if (q6core_lcl.cal_data[META_CAL] == NULL) { + pr_err("%s: cal_data not initialized yet!!\n", __func__); + rc = -EINVAL; + goto cmd_unlock; + } + + mutex_lock(&((q6core_lcl.cal_data[META_CAL])->lock)); + cal_block = cal_utils_get_cal_block_by_key( + q6core_lcl.cal_data[META_CAL], key); + if (cal_block == NULL || + cal_block->cal_data.kvaddr == NULL || + cal_block->cal_data.size <= 0) { + pr_err("%s: Invalid cal block to send", __func__); + rc = -EINVAL; + goto cal_data_unlock; + } + + packet_size = sizeof(struct avcs_cmd_set_license) + + cal_block->cal_data.size; + /*round up total packet_size to next 4 byte boundary*/ + packet_size = ((packet_size + 0x3)>>2)<<2; + + cmd_setl = kzalloc(packet_size, GFP_KERNEL); + if (cmd_setl == NULL) { + rc = -ENOMEM; + goto cal_data_unlock; + } + + ocm_core_open(); + if (q6core_lcl.core_handle_q == NULL) { + pr_err("%s: apr registration for CORE failed\n", __func__); + rc = -ENODEV; + goto fail_cmd; + } + + cmd_setl->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_EVENT, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cmd_setl->hdr.pkt_size = packet_size; + cmd_setl->hdr.src_port = 0; + cmd_setl->hdr.dest_port = 0; + cmd_setl->hdr.token = 0; + cmd_setl->hdr.opcode = AVCS_CMD_SET_LICENSE; + cmd_setl->id = module_id; + cmd_setl->overwrite = 1; + cmd_setl->size = cal_block->cal_data.size; + memcpy((uint8_t *)cmd_setl + sizeof(struct avcs_cmd_set_license), + cal_block->cal_data.kvaddr, + cal_block->cal_data.size); + pr_info("%s: Set license opcode=0x%x, id =0x%x, size = %d\n", + __func__, cmd_setl->hdr.opcode, + cmd_setl->id, cmd_setl->size); + rc = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *)cmd_setl); + if (rc < 0) + pr_err("%s: SET_LICENSE failed op[0x%x]rc[%d]\n", + __func__, cmd_setl->hdr.opcode, rc); + +fail_cmd: + kfree(cmd_setl); +cal_data_unlock: + mutex_unlock(&((q6core_lcl.cal_data[META_CAL])->lock)); +cmd_unlock: + mutex_unlock(&(q6core_lcl.cmd_lock)); + + return rc; +} + +int32_t core_get_license_status(uint32_t module_id) +{ + struct avcs_cmd_get_license_validation_result get_lvr_cmd; + int ret = 0; + + pr_debug("%s: module_id 0x%x", __func__, module_id); + + mutex_lock(&(q6core_lcl.cmd_lock)); + ocm_core_open(); + if (q6core_lcl.core_handle_q == NULL) { + pr_err("%s: apr registration for CORE failed\n", __func__); + ret = -ENODEV; + goto fail_cmd; + } + + get_lvr_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + get_lvr_cmd.hdr.pkt_size = + sizeof(struct avcs_cmd_get_license_validation_result); + + get_lvr_cmd.hdr.src_port = 0; + get_lvr_cmd.hdr.dest_port = 0; + get_lvr_cmd.hdr.token = 0; + get_lvr_cmd.hdr.opcode = AVCS_CMD_GET_LICENSE_VALIDATION_RESULT; + get_lvr_cmd.id = module_id; + + + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) &get_lvr_cmd); + if (ret < 0) { + pr_err("%s: license_validation request failed, err %d\n", + __func__, ret); + ret = -EREMOTE; + goto fail_cmd; + } + + q6core_lcl.cmd_resp_received_flag &= ~(FLAG_CMDRSP_LICENSE_RESULT); + mutex_unlock(&(q6core_lcl.cmd_lock)); + ret = wait_event_timeout(q6core_lcl.cmd_req_wait, + (q6core_lcl.cmd_resp_received_flag == + FLAG_CMDRSP_LICENSE_RESULT), + msecs_to_jiffies(TIMEOUT_MS)); + mutex_lock(&(q6core_lcl.cmd_lock)); + if (!ret) { + pr_err("%s: wait_event timeout for CMDRSP_LICENSE_RESULT\n", + __func__); + ret = -ETIME; + goto fail_cmd; + } + q6core_lcl.cmd_resp_received_flag &= ~(FLAG_CMDRSP_LICENSE_RESULT); + ret = q6core_lcl.cmd_resp_payload.cmdrsp_license_result.result; + +fail_cmd: + mutex_unlock(&(q6core_lcl.cmd_lock)); + pr_info("%s: cmdrsp_license_result.result = 0x%x for module 0x%x\n", + __func__, ret, module_id); + return ret; +} + +uint32_t core_set_dolby_manufacturer_id(int manufacturer_id) +{ + struct adsp_dolby_manufacturer_id payload; + int rc = 0; + + pr_debug("%s: manufacturer_id :%d\n", __func__, manufacturer_id); + mutex_lock(&(q6core_lcl.cmd_lock)); + ocm_core_open(); + if (q6core_lcl.core_handle_q) { + payload.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_EVENT, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + payload.hdr.pkt_size = + sizeof(struct adsp_dolby_manufacturer_id); + payload.hdr.src_port = 0; + payload.hdr.dest_port = 0; + payload.hdr.token = 0; + payload.hdr.opcode = ADSP_CMD_SET_DOLBY_MANUFACTURER_ID; + payload.manufacturer_id = manufacturer_id; + pr_debug("%s: Send Dolby security opcode=0x%x manufacturer ID = %d\n", + __func__, + payload.hdr.opcode, payload.manufacturer_id); + rc = apr_send_pkt(q6core_lcl.core_handle_q, + (uint32_t *)&payload); + if (rc < 0) + pr_err("%s: SET_DOLBY_MANUFACTURER_ID failed op[0x%x]rc[%d]\n", + __func__, payload.hdr.opcode, rc); + } + mutex_unlock(&(q6core_lcl.cmd_lock)); + return rc; +} + +/** + * q6core_is_adsp_ready - check adsp ready status + * + * Returns true if adsp is ready otherwise returns false + */ +bool q6core_is_adsp_ready(void) +{ + int rc = 0; + bool ret = false; + struct apr_hdr hdr; + + pr_debug("%s: enter\n", __func__); + memset(&hdr, 0, sizeof(hdr)); + hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, 0); + hdr.opcode = AVCS_CMD_ADSP_EVENT_GET_STATE; + + mutex_lock(&(q6core_lcl.cmd_lock)); + ocm_core_open(); + if (q6core_lcl.core_handle_q) { + q6core_lcl.bus_bw_resp_received = 0; + rc = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *)&hdr); + if (rc < 0) { + pr_err("%s: Get ADSP state APR packet send event %d\n", + __func__, rc); + goto bail; + } + + rc = wait_event_timeout(q6core_lcl.bus_bw_req_wait, + (q6core_lcl.bus_bw_resp_received == 1), + msecs_to_jiffies(Q6_READY_TIMEOUT_MS)); + if (rc > 0 && q6core_lcl.bus_bw_resp_received) { + /* ensure to read updated param by callback thread */ + rmb(); + ret = !!q6core_lcl.param; + } + } +bail: + pr_debug("%s: leave, rc %d, adsp ready %d\n", __func__, rc, ret); + mutex_unlock(&(q6core_lcl.cmd_lock)); + return ret; +} +EXPORT_SYMBOL(q6core_is_adsp_ready); + +static int q6core_map_memory_regions(phys_addr_t *buf_add, uint32_t mempool_id, + uint32_t *bufsz, uint32_t bufcnt, uint32_t *map_handle) +{ + struct avs_cmd_shared_mem_map_regions *mmap_regions = NULL; + struct avs_shared_map_region_payload *mregions = NULL; + void *mmap_region_cmd = NULL; + void *payload = NULL; + int ret = 0; + int i = 0; + int cmd_size = 0; + + cmd_size = sizeof(struct avs_cmd_shared_mem_map_regions) + + sizeof(struct avs_shared_map_region_payload) + * bufcnt; + + mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL); + if (mmap_region_cmd == NULL) + return -ENOMEM; + + mmap_regions = (struct avs_cmd_shared_mem_map_regions *)mmap_region_cmd; + mmap_regions->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mmap_regions->hdr.pkt_size = cmd_size; + mmap_regions->hdr.src_port = 0; + mmap_regions->hdr.dest_port = 0; + mmap_regions->hdr.token = 0; + mmap_regions->hdr.opcode = AVCS_CMD_SHARED_MEM_MAP_REGIONS; + mmap_regions->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL & 0x00ff; + mmap_regions->num_regions = bufcnt & 0x00ff; + mmap_regions->property_flag = 0x00; + + payload = ((u8 *) mmap_region_cmd + + sizeof(struct avs_cmd_shared_mem_map_regions)); + mregions = (struct avs_shared_map_region_payload *)payload; + + for (i = 0; i < bufcnt; i++) { + mregions->shm_addr_lsw = lower_32_bits(buf_add[i]); + mregions->shm_addr_msw = + msm_audio_populate_upper_32_bits(buf_add[i]); + mregions->mem_size_bytes = bufsz[i]; + ++mregions; + } + + pr_debug("%s: sending memory map, addr %pK, size %d, bufcnt = %d\n", + __func__, buf_add, bufsz[0], mmap_regions->num_regions); + + *map_handle = 0; + q6core_lcl.bus_bw_resp_received = 0; + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) + mmap_regions); + if (ret < 0) { + pr_err("%s: mmap regions failed %d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(q6core_lcl.bus_bw_req_wait, + (q6core_lcl.bus_bw_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: timeout. waited for memory map\n", __func__); + ret = -ETIME; + goto done; + } + + *map_handle = q6core_lcl.mem_map_cal_handle; +done: + kfree(mmap_region_cmd); + return ret; +} + +static int q6core_memory_unmap_regions(uint32_t mem_map_handle) +{ + struct avs_cmd_shared_mem_unmap_regions unmap_regions; + int ret = 0; + + memset(&unmap_regions, 0, sizeof(unmap_regions)); + unmap_regions.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + unmap_regions.hdr.pkt_size = sizeof(unmap_regions); + unmap_regions.hdr.src_svc = APR_SVC_ADSP_CORE; + unmap_regions.hdr.src_domain = APR_DOMAIN_APPS; + unmap_regions.hdr.src_port = 0; + unmap_regions.hdr.dest_svc = APR_SVC_ADSP_CORE; + unmap_regions.hdr.dest_domain = APR_DOMAIN_ADSP; + unmap_regions.hdr.dest_port = 0; + unmap_regions.hdr.token = 0; + unmap_regions.hdr.opcode = AVCS_CMD_SHARED_MEM_UNMAP_REGIONS; + unmap_regions.mem_map_handle = mem_map_handle; + + q6core_lcl.bus_bw_resp_received = 0; + + pr_debug("%s: unmap regions map handle %d\n", + __func__, mem_map_handle); + + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) + &unmap_regions); + if (ret < 0) { + pr_err("%s: unmap regions failed %d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(q6core_lcl.bus_bw_req_wait, + (q6core_lcl.bus_bw_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: timeout. waited for memory_unmap\n", + __func__); + ret = -ETIME; + goto done; + } +done: + return ret; +} + +static int q6core_dereg_all_custom_topologies(void) +{ + int ret = 0; + struct avcs_cmd_deregister_topologies dereg_top; + + memset(&dereg_top, 0, sizeof(dereg_top)); + dereg_top.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + dereg_top.hdr.pkt_size = sizeof(dereg_top); + dereg_top.hdr.src_svc = APR_SVC_ADSP_CORE; + dereg_top.hdr.src_domain = APR_DOMAIN_APPS; + dereg_top.hdr.src_port = 0; + dereg_top.hdr.dest_svc = APR_SVC_ADSP_CORE; + dereg_top.hdr.dest_domain = APR_DOMAIN_ADSP; + dereg_top.hdr.dest_port = 0; + dereg_top.hdr.token = 0; + dereg_top.hdr.opcode = AVCS_CMD_DEREGISTER_TOPOLOGIES; + dereg_top.payload_addr_lsw = 0; + dereg_top.payload_addr_msw = 0; + dereg_top.mem_map_handle = 0; + dereg_top.payload_size = 0; + dereg_top.mode = AVCS_MODE_DEREGISTER_ALL_CUSTOM_TOPOLOGIES; + + q6core_lcl.bus_bw_resp_received = 0; + + pr_debug("%s: Deregister topologies mode %d\n", + __func__, dereg_top.mode); + + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) &dereg_top); + if (ret < 0) { + pr_err("%s: Deregister topologies failed %d\n", + __func__, ret); + goto done; + } + + ret = wait_event_timeout(q6core_lcl.bus_bw_req_wait, + (q6core_lcl.bus_bw_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout for Deregister topologies\n", + __func__); + goto done; + } +done: + return ret; +} + +static int q6core_send_custom_topologies(void) +{ + int ret = 0; + int ret2 = 0; + struct cal_block_data *cal_block = NULL; + struct avcs_cmd_register_topologies reg_top; + + if (!q6core_is_adsp_ready()) { + pr_err("%s: ADSP is not ready!\n", __func__); + return -ENODEV; + } + + memset(®_top, 0, sizeof(reg_top)); + mutex_lock(&q6core_lcl.cal_data[CUST_TOP_CAL]->lock); + mutex_lock(&q6core_lcl.cmd_lock); + + cal_block = cal_utils_get_only_cal_block( + q6core_lcl.cal_data[CUST_TOP_CAL]); + if (cal_block == NULL) { + pr_debug("%s: cal block is NULL!\n", __func__); + goto unlock; + } + if (cal_block->cal_data.size <= 0) { + pr_debug("%s: cal size is %zd not sending\n", + __func__, cal_block->cal_data.size); + goto unlock; + } + + q6core_dereg_all_custom_topologies(); + + ret = q6core_map_memory_regions(&cal_block->cal_data.paddr, 0, + (uint32_t *)&cal_block->map_data.map_size, 1, + &cal_block->map_data.q6map_handle); + if (!ret) { + pr_err("%s: q6core_map_memory_regions failed\n", __func__); + goto unlock; + } + + reg_top.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + reg_top.hdr.pkt_size = sizeof(reg_top); + reg_top.hdr.src_svc = APR_SVC_ADSP_CORE; + reg_top.hdr.src_domain = APR_DOMAIN_APPS; + reg_top.hdr.src_port = 0; + reg_top.hdr.dest_svc = APR_SVC_ADSP_CORE; + reg_top.hdr.dest_domain = APR_DOMAIN_ADSP; + reg_top.hdr.dest_port = 0; + reg_top.hdr.token = 0; + reg_top.hdr.opcode = AVCS_CMD_REGISTER_TOPOLOGIES; + reg_top.payload_addr_lsw = + lower_32_bits(cal_block->cal_data.paddr); + reg_top.payload_addr_msw = + msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr); + reg_top.mem_map_handle = cal_block->map_data.q6map_handle; + reg_top.payload_size = cal_block->cal_data.size; + + q6core_lcl.adsp_status = 0; + q6core_lcl.bus_bw_resp_received = 0; + + pr_debug("%s: Register topologies addr %pK, size %zd, map handle %d\n", + __func__, &cal_block->cal_data.paddr, cal_block->cal_data.size, + cal_block->map_data.q6map_handle); + + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) ®_top); + if (ret < 0) { + pr_err("%s: Register topologies failed %d\n", + __func__, ret); + goto unmap; + } + + ret = wait_event_timeout(q6core_lcl.bus_bw_req_wait, + (q6core_lcl.bus_bw_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout for Register topologies\n", + __func__); + goto unmap; + } + + if (q6core_lcl.adsp_status < 0) + ret = q6core_lcl.adsp_status; +unmap: + ret2 = q6core_memory_unmap_regions(cal_block->map_data.q6map_handle); + if (!ret2) { + pr_err("%s: q6core_memory_unmap_regions failed for map handle %d\n", + __func__, cal_block->map_data.q6map_handle); + ret = ret2; + goto unlock; + } + +unlock: + mutex_unlock(&q6core_lcl.cmd_lock); + mutex_unlock(&q6core_lcl.cal_data[CUST_TOP_CAL]->lock); + + return ret; +} + +static int get_cal_type_index(int32_t cal_type) +{ + int ret = -EINVAL; + + switch (cal_type) { + case AUDIO_CORE_METAINFO_CAL_TYPE: + ret = META_CAL; + break; + case CORE_CUSTOM_TOPOLOGIES_CAL_TYPE: + ret = CUST_TOP_CAL; + break; + default: + pr_err("%s: invalid cal type %d!\n", __func__, cal_type); + } + return ret; +} + +static int q6core_alloc_cal(int32_t cal_type, + size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + + ret = cal_utils_alloc_cal(data_size, data, + q6core_lcl.cal_data[cal_index], 0, NULL); + if (ret < 0) { + pr_err("%s: cal_utils_alloc_block failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + goto done; + } +done: + return ret; +} + +static int q6core_dealloc_cal(int32_t cal_type, + size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + + ret = cal_utils_dealloc_cal(data_size, data, + q6core_lcl.cal_data[cal_index]); + if (ret < 0) { + pr_err("%s: cal_utils_dealloc_block failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + goto done; + } +done: + return ret; +} + +static int q6core_set_cal(int32_t cal_type, + size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + + ret = cal_utils_set_cal(data_size, data, + q6core_lcl.cal_data[cal_index], 0, NULL); + if (ret < 0) { + pr_err("%s: cal_utils_set_cal failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + goto done; + } + + if (cal_index == CUST_TOP_CAL) + ret = q6core_send_custom_topologies(); +done: + return ret; +} + +static void q6core_delete_cal_data(void) +{ + pr_debug("%s:\n", __func__); + + cal_utils_destroy_cal_types(CORE_MAX_CAL, q6core_lcl.cal_data); +} + + +static int q6core_init_cal_data(void) +{ + int ret = 0; + struct cal_type_info cal_type_info[] = { + {{AUDIO_CORE_METAINFO_CAL_TYPE, + {q6core_alloc_cal, q6core_dealloc_cal, NULL, + q6core_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{CORE_CUSTOM_TOPOLOGIES_CAL_TYPE, + {q6core_alloc_cal, q6core_dealloc_cal, NULL, + q6core_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} } + }; + pr_debug("%s:\n", __func__); + + ret = cal_utils_create_cal_types(CORE_MAX_CAL, + q6core_lcl.cal_data, cal_type_info); + if (ret < 0) { + pr_err("%s: could not create cal type!\n", + __func__); + goto err; + } + + return ret; +err: + q6core_delete_cal_data(); + return ret; +} + +static int __init core_init(void) +{ + init_waitqueue_head(&q6core_lcl.bus_bw_req_wait); + q6core_lcl.bus_bw_resp_received = 0; + + q6core_lcl.core_handle_q = NULL; + + init_waitqueue_head(&q6core_lcl.cmd_req_wait); + q6core_lcl.cmd_resp_received_flag = FLAG_NONE; + mutex_init(&q6core_lcl.cmd_lock); + q6core_lcl.mem_map_cal_handle = 0; + q6core_lcl.adsp_status = 0; + + q6core_init_cal_data(); + return 0; +} +module_init(core_init); + +static void __exit core_exit(void) +{ + mutex_destroy(&q6core_lcl.cmd_lock); + q6core_delete_cal_data(); +} +module_exit(core_exit); +MODULE_DESCRIPTION("ADSP core driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/qdsp6v2/q6lsm.c b/sound/soc/msm/qdsp6v2/q6lsm.c new file mode 100644 index 000000000000..799d1be97ffb --- /dev/null +++ b/sound/soc/msm/qdsp6v2/q6lsm.c @@ -0,0 +1,2173 @@ +/* + * Copyright (c) 2013-2017, Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define APR_TIMEOUT (5 * HZ) +#define LSM_ALIGN_BOUNDARY 512 +#define LSM_SAMPLE_RATE 16000 +#define QLSM_PARAM_ID_MINOR_VERSION 1 +#define QLSM_PARAM_ID_MINOR_VERSION_2 2 + +static int lsm_afe_port; + +enum { + LSM_CUSTOM_TOP_IDX, + LSM_TOP_IDX, + LSM_CAL_IDX, + LSM_MAX_CAL_IDX +}; + +enum { + CMD_STATE_CLEARED = 0, + CMD_STATE_WAIT_RESP = 1, +}; + +enum { + LSM_INVALID_SESSION_ID = 0, + LSM_MIN_SESSION_ID = 1, + LSM_MAX_SESSION_ID = 8, + LSM_CONTROL_SESSION = 0x0F, +}; + +#define CHECK_SESSION(x) (x < LSM_MIN_SESSION_ID || x > LSM_MAX_SESSION_ID) +struct lsm_common { + void *apr; + atomic_t apr_users; + struct lsm_client common_client[LSM_MAX_SESSION_ID + 1]; + + int set_custom_topology; + struct cal_type_data *cal_data[LSM_MAX_CAL_IDX]; + + struct mutex apr_lock; +}; + +struct lsm_module_param_ids { + uint32_t module_id; + uint32_t param_id; +}; + +static struct lsm_common lsm_common; +/* + * mmap_handle_p can point either client->sound_model.mem_map_handle or + * lsm_common.mmap_handle_for_cal. + * mmap_lock must be held while accessing this. + */ +static spinlock_t mmap_lock; +static uint32_t *mmap_handle_p; + +static spinlock_t lsm_session_lock; +static struct lsm_client *lsm_session[LSM_MAX_SESSION_ID + 1]; + +static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv); +static int q6lsm_send_cal(struct lsm_client *client, u32 set_params_opcode); +static int q6lsm_memory_map_regions(struct lsm_client *client, + dma_addr_t dma_addr_p, uint32_t dma_buf_sz, + uint32_t *mmap_p); +static int q6lsm_memory_unmap_regions(struct lsm_client *client, + uint32_t handle); + +static void q6lsm_set_param_hdr_info( + struct lsm_set_params_hdr *param_hdr, + u32 payload_size, u32 addr_lsw, u32 addr_msw, + u32 mmap_handle) +{ + param_hdr->data_payload_size = payload_size; + param_hdr->data_payload_addr_lsw = addr_lsw; + param_hdr->data_payload_addr_msw = addr_msw; + param_hdr->mem_map_handle = mmap_handle; +} + +static void q6lsm_set_param_common( + struct lsm_param_payload_common *common, + struct lsm_module_param_ids *ids, + u32 param_size, u32 set_param_version) +{ + common->module_id = ids->module_id; + common->param_id = ids->param_id; + + switch (set_param_version) { + case LSM_SESSION_CMD_SET_PARAMS_V2: + common->p_size.param_size = param_size; + break; + case LSM_SESSION_CMD_SET_PARAMS: + default: + common->p_size.sr.param_size = + (u16) param_size; + common->p_size.sr.reserved = 0; + break; + } +} + +static int q6lsm_callback(struct apr_client_data *data, void *priv) +{ + struct lsm_client *client = (struct lsm_client *)priv; + uint32_t token; + uint32_t *payload; + + if (!client || !data) { + pr_err("%s: client %pK data %pK\n", + __func__, client, data); + WARN_ON(1); + return -EINVAL; + } + + if (data->opcode == RESET_EVENTS) { + pr_debug("%s: SSR event received 0x%x, event 0x%x, proc 0x%x\n", + __func__, data->opcode, data->reset_event, + data->reset_proc); + + cal_utils_clear_cal_block_q6maps(LSM_MAX_CAL_IDX, + lsm_common.cal_data); + mutex_lock(&lsm_common.cal_data[LSM_CUSTOM_TOP_IDX]->lock); + lsm_common.set_custom_topology = 1; + mutex_unlock(&lsm_common.cal_data[LSM_CUSTOM_TOP_IDX]->lock); + return 0; + } + + payload = data->payload; + pr_debug("%s: Session %d opcode 0x%x token 0x%x payload size %d\n" + "payload [0] = 0x%x\n", __func__, client->session, + data->opcode, data->token, data->payload_size, payload[0]); + if (data->opcode == LSM_DATA_EVENT_READ_DONE) { + struct lsm_cmd_read_done read_done; + + token = data->token; + if (data->payload_size > sizeof(read_done)) { + pr_err("%s: read done error payload size %d expected size %zd\n", + __func__, data->payload_size, + sizeof(read_done)); + return -EINVAL; + } + pr_debug("%s: opcode %x status %x lsw %x msw %x mem_map handle %x\n", + __func__, data->opcode, payload[0], payload[1], + payload[2], payload[3]); + read_done.status = payload[0]; + read_done.buf_addr_lsw = payload[1]; + read_done.buf_addr_msw = payload[2]; + read_done.mem_map_handle = payload[3]; + read_done.total_size = payload[4]; + read_done.offset = payload[5]; + if (client->cb) + client->cb(data->opcode, data->token, + (void *)&read_done, + client->priv); + return 0; + } else if (data->opcode == APR_BASIC_RSP_RESULT) { + token = data->token; + switch (payload[0]) { + case LSM_SESSION_CMD_START: + case LSM_SESSION_CMD_STOP: + case LSM_SESSION_CMD_SET_PARAMS: + case LSM_SESSION_CMD_OPEN_TX: + case LSM_SESSION_CMD_CLOSE_TX: + case LSM_SESSION_CMD_REGISTER_SOUND_MODEL: + case LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL: + case LSM_SESSION_CMD_SHARED_MEM_UNMAP_REGIONS: + case LSM_SESSION_CMD_EOB: + case LSM_SESSION_CMD_READ: + case LSM_SESSION_CMD_OPEN_TX_V2: + case LSM_CMD_ADD_TOPOLOGIES: + case LSM_SESSION_CMD_SET_PARAMS_V2: + if (token != client->session && + payload[0] != + LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL) { + pr_err("%s: Invalid session %d receivced expected %d\n", + __func__, token, client->session); + return -EINVAL; + } + client->cmd_err_code = payload[1]; + if (client->cmd_err_code) + pr_err("%s: cmd 0x%x failed status %d\n", + __func__, payload[0], client->cmd_err_code); + if (atomic_cmpxchg(&client->cmd_state, + CMD_STATE_WAIT_RESP, + CMD_STATE_CLEARED) == + CMD_STATE_WAIT_RESP) + wake_up(&client->cmd_wait); + break; + default: + pr_debug("%s: Unknown command 0x%x\n", + __func__, payload[0]); + break; + } + return 0; + } + + if (client->cb) + client->cb(data->opcode, data->token, data->payload, + client->priv); + + return 0; +} + +static int q6lsm_session_alloc(struct lsm_client *client) +{ + unsigned long flags; + int n, ret = -ENOMEM; + + spin_lock_irqsave(&lsm_session_lock, flags); + for (n = LSM_MIN_SESSION_ID; n <= LSM_MAX_SESSION_ID; n++) { + if (!lsm_session[n]) { + lsm_session[n] = client; + ret = n; + break; + } + } + spin_unlock_irqrestore(&lsm_session_lock, flags); + pr_debug("%s: Alloc Session %d", __func__, n); + return ret; +} + +static void q6lsm_session_free(struct lsm_client *client) +{ + unsigned long flags; + + pr_debug("%s: Freeing session ID %d\n", __func__, client->session); + spin_lock_irqsave(&lsm_session_lock, flags); + lsm_session[client->session] = LSM_INVALID_SESSION_ID; + spin_unlock_irqrestore(&lsm_session_lock, flags); + client->session = LSM_INVALID_SESSION_ID; +} + +static void *q6lsm_mmap_apr_reg(void) +{ + if (atomic_inc_return(&lsm_common.apr_users) == 1) { + lsm_common.apr = + apr_register("ADSP", "LSM", q6lsm_mmapcallback, + 0x0FFFFFFFF, &lsm_common); + if (!lsm_common.apr) { + pr_debug("%s: Unable to register APR LSM common port\n", + __func__); + atomic_dec(&lsm_common.apr_users); + } + } + return lsm_common.apr; +} + +static int q6lsm_mmap_apr_dereg(void) +{ + if (atomic_read(&lsm_common.apr_users) <= 0) { + WARN("%s: APR common port already closed\n", __func__); + } else { + if (atomic_dec_return(&lsm_common.apr_users) == 0) { + apr_deregister(lsm_common.apr); + pr_debug("%s: APR De-Register common port\n", __func__); + } + } + return 0; +} + +struct lsm_client *q6lsm_client_alloc(lsm_app_cb cb, void *priv) +{ + struct lsm_client *client; + int n; + + client = kzalloc(sizeof(struct lsm_client), GFP_KERNEL); + if (!client) + return NULL; + n = q6lsm_session_alloc(client); + if (n <= 0) { + kfree(client); + return NULL; + } + client->session = n; + client->cb = cb; + client->priv = priv; + if (CHECK_SESSION(client->session)) { + pr_err("%s: Client session %d\n", + __func__, client->session); + kfree(client); + return NULL; + } + pr_debug("%s: Client Session %d\n", __func__, client->session); + client->apr = apr_register("ADSP", "LSM", q6lsm_callback, + ((client->session) << 8 | client->session), + client); + + if (client->apr == NULL) { + pr_err("%s: Registration with APR failed\n", __func__); + goto fail; + } + + pr_debug("%s: Registering the common port with APR\n", __func__); + client->mmap_apr = q6lsm_mmap_apr_reg(); + if (!client->mmap_apr) { + pr_err("%s: APR registration failed\n", __func__); + goto fail; + } + + init_waitqueue_head(&client->cmd_wait); + mutex_init(&client->cmd_lock); + atomic_set(&client->cmd_state, CMD_STATE_CLEARED); + pr_debug("%s: New client allocated\n", __func__); + return client; +fail: + q6lsm_client_free(client); + return NULL; +} + +void q6lsm_client_free(struct lsm_client *client) +{ + if (!client) + return; + if (CHECK_SESSION(client->session)) { + pr_err("%s: Invalid Session %d\n", __func__, client->session); + return; + } + apr_deregister(client->apr); + client->mmap_apr = NULL; + q6lsm_session_free(client); + q6lsm_mmap_apr_dereg(); + mutex_destroy(&client->cmd_lock); + kfree(client); + client = NULL; +} + +/* + * q6lsm_apr_send_pkt : If wait == true, hold mutex to prevent from preempting + * other thread's wait. + * If mmap_handle_p != NULL, disable irq and spin lock to + * protect mmap_handle_p + */ +static int q6lsm_apr_send_pkt(struct lsm_client *client, void *handle, + void *data, bool wait, uint32_t *mmap_p) +{ + int ret; + unsigned long flags = 0; + struct apr_hdr *msg_hdr = (struct apr_hdr *) data; + + pr_debug("%s: enter wait %d\n", __func__, wait); + if (wait) + mutex_lock(&lsm_common.apr_lock); + if (mmap_p) { + WARN_ON(!wait); + spin_lock_irqsave(&mmap_lock, flags); + mmap_handle_p = mmap_p; + } + atomic_set(&client->cmd_state, CMD_STATE_WAIT_RESP); + client->cmd_err_code = 0; + ret = apr_send_pkt(handle, data); + if (mmap_p) + spin_unlock_irqrestore(&mmap_lock, flags); + + if (ret < 0) { + pr_err("%s: apr_send_pkt failed %d\n", __func__, ret); + } else if (wait) { + ret = wait_event_timeout(client->cmd_wait, + (atomic_read(&client->cmd_state) == + CMD_STATE_CLEARED), + APR_TIMEOUT); + if (likely(ret)) { + /* q6 returned error */ + if (client->cmd_err_code) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + client->cmd_err_code)); + ret = adsp_err_get_lnx_err_code( + client->cmd_err_code); + } else { + ret = 0; + } + } else { + pr_err("%s: wait timedout, apr_opcode = 0x%x, size = %d\n", + __func__, msg_hdr->opcode, msg_hdr->pkt_size); + /* ret = 0 means wait timed out */ + ret = -ETIMEDOUT; + } + } else { + ret = 0; + } + if (wait) + mutex_unlock(&lsm_common.apr_lock); + + pr_debug("%s: leave ret %d\n", __func__, ret); + return ret; +} + +static void q6lsm_add_hdr(struct lsm_client *client, struct apr_hdr *hdr, + uint32_t pkt_size, bool cmd_flg) +{ + pr_debug("%s: pkt_size %d cmd_flg %d session %d\n", __func__, + pkt_size, cmd_flg, client->session); + hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(sizeof(struct apr_hdr)), + APR_PKT_VER); + hdr->src_svc = APR_SVC_LSM; + hdr->src_domain = APR_DOMAIN_APPS; + hdr->dest_svc = APR_SVC_LSM; + hdr->dest_domain = APR_DOMAIN_ADSP; + hdr->src_port = ((client->session << 8) & 0xFF00) | client->session; + hdr->dest_port = ((client->session << 8) & 0xFF00) | client->session; + hdr->pkt_size = pkt_size; + if (cmd_flg) + hdr->token = client->session; +} + + +static int q6lsm_send_custom_topologies(struct lsm_client *client) +{ + int rc; + struct cal_block_data *cal_block = NULL; + struct lsm_custom_topologies cstm_top; + + if (lsm_common.cal_data[LSM_CUSTOM_TOP_IDX] == NULL) { + pr_err("%s: LSM_CUSTOM_TOP_IDX invalid\n", __func__); + rc = -EINVAL; + goto done; + } + + lsm_common.set_custom_topology = 0; + + mutex_lock(&lsm_common.cal_data[LSM_CUSTOM_TOP_IDX]->lock); + cal_block = cal_utils_get_only_cal_block( + lsm_common.cal_data[LSM_CUSTOM_TOP_IDX]); + if (!cal_block) { + pr_err("%s: Cal block for LSM_CUSTOM_TOP_IDX not found\n", + __func__); + rc = -EINVAL; + goto unlock; + } + + if (cal_block->cal_data.size <= 0) { + pr_err("%s: Invalid size for LSM_CUSTOM_TOP %zd\n", + __func__, cal_block->cal_data.size); + rc = -EINVAL; + goto unlock; + } + + memset(&cstm_top, 0, sizeof(cstm_top)); + /* Map the memory for out-of-band data */ + rc = q6lsm_memory_map_regions(client, cal_block->cal_data.paddr, + cal_block->map_data.map_size, + &cal_block->map_data.q6map_handle); + if (rc < 0) { + pr_err("%s: Failed to map custom topologied, err = %d\n", + __func__, rc); + goto unlock; + } + + q6lsm_add_hdr(client, &cstm_top.hdr, + sizeof(cstm_top), true); + cstm_top.hdr.opcode = LSM_CMD_ADD_TOPOLOGIES; + + /* + * For ADD_TOPOLOGIES, the dest_port should be 0 + * Note that source port cannot be zero as it is used + * to route the response to a specific client registered + * on APR + */ + cstm_top.hdr.dest_port = 0; + + cstm_top.data_payload_addr_lsw = + lower_32_bits(cal_block->cal_data.paddr); + cstm_top.data_payload_addr_msw = + msm_audio_populate_upper_32_bits( + cal_block->cal_data.paddr); + cstm_top.mem_map_handle = cal_block->map_data.q6map_handle; + cstm_top.buffer_size = cal_block->cal_data.size; + + rc = q6lsm_apr_send_pkt(client, client->apr, + &cstm_top, true, NULL); + if (rc) + pr_err("%s: Failed to add custom top, err = %d\n", + __func__, rc); + /* go ahead and unmap even if custom top failed */ + rc = q6lsm_memory_unmap_regions(client, + cal_block->map_data.q6map_handle); + if (rc) { + pr_err("%s: Failed to unmap, err = %d\n", + __func__, rc); + /* Even if mem unmap failed, treat the cmd as success */ + rc = 0; + } + +unlock: + mutex_unlock(&lsm_common.cal_data[LSM_CUSTOM_TOP_IDX]->lock); +done: + return rc; +} + +static int q6lsm_do_open_v2(struct lsm_client *client, + uint16_t app_id) +{ + int rc; + struct cal_block_data *cal_block = NULL; + struct audio_cal_info_lsm_top *lsm_top; + struct lsm_stream_cmd_open_tx_v2 open_v2; + + if (lsm_common.cal_data[LSM_TOP_IDX] == NULL) { + pr_err("%s: LSM_TOP_IDX invalid\n", __func__); + rc = -EINVAL; + goto done; + } + + mutex_lock(&lsm_common.cal_data[LSM_TOP_IDX]->lock); + cal_block = cal_utils_get_only_cal_block( + lsm_common.cal_data[LSM_TOP_IDX]); + if (!cal_block) { + pr_err("%s: Cal block for LSM_TOP_IDX not found\n", + __func__); + rc = -EINVAL; + goto unlock; + } + + lsm_top = (struct audio_cal_info_lsm_top *) + cal_block->cal_info; + if (!lsm_top) { + pr_err("%s: cal_info for LSM_TOP_IDX not found\n", + __func__); + rc = -EINVAL; + goto unlock; + } + + pr_debug("%s: topology_id = 0x%x, acdb_id = 0x%x, app_type = 0x%x\n", + __func__, lsm_top->topology, lsm_top->acdb_id, + lsm_top->app_type); + + if (lsm_top->topology == 0) { + pr_err("%s: toplogy id not sent for app_type 0x%x\n", + __func__, lsm_top->app_type); + rc = -EINVAL; + goto unlock; + } + + client->app_id = lsm_top->app_type; + memset(&open_v2, 0, sizeof(open_v2)); + q6lsm_add_hdr(client, &open_v2.hdr, + sizeof(open_v2), true); + open_v2.topology_id = lsm_top->topology; + open_v2.hdr.opcode = LSM_SESSION_CMD_OPEN_TX_V2; + + rc = q6lsm_apr_send_pkt(client, client->apr, + &open_v2, true, NULL); + if (rc) + pr_err("%s: open_v2 failed, err = %d\n", + __func__, rc); + else + client->use_topology = true; +unlock: + mutex_unlock(&lsm_common.cal_data[LSM_TOP_IDX]->lock); +done: + return rc; + +} + +void q6lsm_sm_set_param_data(struct lsm_client *client, + struct lsm_params_info *p_info, + size_t *offset) +{ + struct lsm_param_payload_common *param; + + param = (struct lsm_param_payload_common *) + client->sound_model.data; + param->module_id = p_info->module_id; + param->param_id = p_info->param_id; + param->p_size.param_size = client->sound_model.size; + *offset = sizeof(*param); +} + +int q6lsm_open(struct lsm_client *client, uint16_t app_id) +{ + int rc = 0; + struct lsm_stream_cmd_open_tx open; + + /* Add Custom topologies if needed */ + if (lsm_common.set_custom_topology) { + rc = q6lsm_send_custom_topologies(client); + if (rc) + pr_err("%s: Failed to send cust_top, err = %d\n", + __func__, rc); + } + + /* Try to open with topology first */ + rc = q6lsm_do_open_v2(client, app_id); + if (!rc) + /* open_v2 was successful */ + goto done; + + pr_debug("%s: try without topology\n", + __func__); + + memset(&open, 0, sizeof(open)); + q6lsm_add_hdr(client, &open.hdr, sizeof(open), true); + switch (client->app_id) { + case LSM_VOICE_WAKEUP_APP_ID_V2: + open.app_id = client->app_id; + break; + default: + pr_err("%s: default err 0x%x\n", __func__, client->app_id); + rc = -EINVAL; + break; + } + + open.sampling_rate = LSM_SAMPLE_RATE; + open.hdr.opcode = LSM_SESSION_CMD_OPEN_TX; + rc = q6lsm_apr_send_pkt(client, client->apr, + &open, true, NULL); + if (rc) + pr_err("%s: Open failed opcode 0x%x, rc %d\n", + __func__, open.hdr.opcode, rc); + else + client->use_topology = false; +done: + pr_debug("%s: leave %d\n", __func__, rc); + return rc; +} + +static int q6lsm_send_confidence_levels( + struct lsm_client *client, + struct lsm_module_param_ids *ids, + u32 set_param_opcode) +{ + u8 *packet; + size_t pkt_size; + struct lsm_cmd_set_params_conf *conf_params; + struct apr_hdr *msg_hdr; + struct lsm_param_min_confidence_levels *cfl; + uint8_t i = 0; + uint8_t padd_size = 0; + u8 *conf_levels; + int rc; + u32 payload_size, param_size; + + padd_size = (4 - (client->num_confidence_levels % 4)) - 1; + pkt_size = sizeof(*conf_params) + padd_size + + client->num_confidence_levels; + + packet = kzalloc(pkt_size, GFP_KERNEL); + if (!packet) + return -ENOMEM; + + conf_params = (struct lsm_cmd_set_params_conf *) packet; + conf_levels = (u8 *) (packet + sizeof(*conf_params)); + msg_hdr = &conf_params->msg_hdr; + q6lsm_add_hdr(client, msg_hdr, + pkt_size, true); + msg_hdr->opcode = set_param_opcode; + payload_size = pkt_size - sizeof(*msg_hdr) - + sizeof(conf_params->params_hdr); + q6lsm_set_param_hdr_info(&conf_params->params_hdr, + payload_size, 0, 0, 0); + cfl = &conf_params->conf_payload; + param_size = ((sizeof(uint8_t) + padd_size + + client->num_confidence_levels)) * + sizeof(uint8_t); + q6lsm_set_param_common(&cfl->common, ids, + param_size, set_param_opcode); + cfl->num_confidence_levels = client->num_confidence_levels; + + pr_debug("%s: CMD PARAM SIZE = %d\n", + __func__, param_size); + pr_debug("%s: Num conf_level = %d\n", + __func__, client->num_confidence_levels); + + memcpy(conf_levels, client->confidence_levels, + client->num_confidence_levels); + for (i = 0; i < client->num_confidence_levels; i++) + pr_debug("%s: Confidence_level[%d] = %d\n", + __func__, i, conf_levels[i]); + + rc = q6lsm_apr_send_pkt(client, client->apr, + packet, true, NULL); + if (rc) + pr_err("%s: confidence_levels cmd failed, err = %d\n", + __func__, rc); + kfree(packet); + return rc; +} + +static int q6lsm_send_param_opmode(struct lsm_client *client, + struct lsm_module_param_ids *opmode_ids, + u32 set_param_opcode) +{ + int rc; + struct lsm_cmd_set_params_opmode opmode_params; + struct apr_hdr *msg_hdr; + + struct lsm_param_op_mode *op_mode; + u32 data_payload_size, param_size; + + msg_hdr = &opmode_params.msg_hdr; + q6lsm_add_hdr(client, msg_hdr, + sizeof(opmode_params), true); + msg_hdr->opcode = set_param_opcode; + data_payload_size = sizeof(opmode_params) - + sizeof(*msg_hdr) - + sizeof(opmode_params.params_hdr); + q6lsm_set_param_hdr_info(&opmode_params.params_hdr, + data_payload_size, 0, 0, 0); + op_mode = &opmode_params.op_mode; + + + param_size = sizeof(struct lsm_param_op_mode) - + sizeof(op_mode->common); + q6lsm_set_param_common(&op_mode->common, + opmode_ids, param_size, + set_param_opcode); + op_mode->minor_version = QLSM_PARAM_ID_MINOR_VERSION; + op_mode->mode = client->mode; + op_mode->reserved = 0; + pr_debug("%s: mode = 0x%x", __func__, op_mode->mode); + + rc = q6lsm_apr_send_pkt(client, client->apr, + &opmode_params, true, NULL); + if (rc) + pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", + __func__, msg_hdr->opcode, rc); + + pr_debug("%s: leave %d\n", __func__, rc); + return rc; +} + +void set_lsm_port(int lsm_port) +{ + lsm_afe_port = lsm_port; +} + +int get_lsm_port(void) +{ + return lsm_afe_port; +} + +int q6lsm_set_port_connected(struct lsm_client *client) +{ + int rc; + struct lsm_cmd_set_connectport connectport; + struct lsm_module_param_ids connectport_ids; + struct apr_hdr *msg_hdr; + struct lsm_param_connect_to_port *connect_to_port; + u32 data_payload_size, param_size, set_param_opcode; + + if (client->use_topology) { + set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2; + connectport_ids.module_id = LSM_MODULE_ID_FRAMEWORK; + connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; + } else { + set_param_opcode = LSM_SESSION_CMD_SET_PARAMS; + connectport_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP; + connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; + } + client->connect_to_port = get_lsm_port(); + + msg_hdr = &connectport.msg_hdr; + q6lsm_add_hdr(client, msg_hdr, + sizeof(connectport), true); + msg_hdr->opcode = set_param_opcode; + data_payload_size = sizeof(connectport) - + sizeof(*msg_hdr) - + sizeof(connectport.params_hdr); + q6lsm_set_param_hdr_info(&connectport.params_hdr, + data_payload_size, 0, 0, 0); + connect_to_port = &connectport.connect_to_port; + + param_size = (sizeof(struct lsm_param_connect_to_port) - + sizeof(connect_to_port->common)); + q6lsm_set_param_common(&connect_to_port->common, + &connectport_ids, param_size, + set_param_opcode); + connect_to_port->minor_version = QLSM_PARAM_ID_MINOR_VERSION; + connect_to_port->port_id = client->connect_to_port; + connect_to_port->reserved = 0; + pr_debug("%s: port= %d", __func__, connect_to_port->port_id); + + rc = q6lsm_apr_send_pkt(client, client->apr, + &connectport, true, NULL); + if (rc) + pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", + __func__, msg_hdr->opcode, rc); + + return rc; +} +static int q6lsm_send_param_polling_enable(struct lsm_client *client, + bool poll_en, + struct lsm_module_param_ids *poll_enable_ids, + u32 set_param_opcode) +{ + int rc = 0; + struct lsm_cmd_poll_enable cmd; + struct apr_hdr *msg_hdr; + struct lsm_param_poll_enable *poll_enable; + u32 data_payload_size, param_size; + + msg_hdr = &cmd.msg_hdr; + q6lsm_add_hdr(client, msg_hdr, + sizeof(struct lsm_cmd_poll_enable), true); + msg_hdr->opcode = set_param_opcode; + data_payload_size = sizeof(struct lsm_cmd_poll_enable) - + sizeof(struct apr_hdr) - + sizeof(struct lsm_set_params_hdr); + q6lsm_set_param_hdr_info(&cmd.params_hdr, + data_payload_size, 0, 0, 0); + poll_enable = &cmd.poll_enable; + + param_size = (sizeof(struct lsm_param_poll_enable) - + sizeof(poll_enable->common)); + q6lsm_set_param_common(&poll_enable->common, + poll_enable_ids, param_size, + set_param_opcode); + poll_enable->minor_version = QLSM_PARAM_ID_MINOR_VERSION; + poll_enable->polling_enable = (poll_en) ? 1 : 0; + pr_debug("%s: poll enable= %d", __func__, poll_enable->polling_enable); + + rc = q6lsm_apr_send_pkt(client, client->apr, + &cmd, true, NULL); + if (rc) + pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", + __func__, msg_hdr->opcode, rc); + + return rc; +} + +int q6lsm_set_fwk_mode_cfg(struct lsm_client *client, + uint32_t event_mode) +{ + int rc = 0; + struct lsm_cmd_set_fwk_mode_cfg cmd; + struct lsm_module_param_ids fwk_mode_cfg_ids; + struct apr_hdr *msg_hdr; + struct lsm_param_fwk_mode_cfg *fwk_mode_cfg; + u32 data_payload_size, param_size, set_param_opcode; + + if (client->use_topology) { + set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2; + fwk_mode_cfg_ids.module_id = LSM_MODULE_ID_FRAMEWORK; + fwk_mode_cfg_ids.param_id = LSM_PARAM_ID_FWK_MODE_CONFIG; + } else { + pr_debug("%s: Ignore sending event mode\n", __func__); + return rc; + } + + msg_hdr = &cmd.msg_hdr; + q6lsm_add_hdr(client, msg_hdr, + sizeof(struct lsm_cmd_set_fwk_mode_cfg), true); + msg_hdr->opcode = set_param_opcode; + data_payload_size = sizeof(struct lsm_cmd_set_fwk_mode_cfg) - + sizeof(struct apr_hdr) - + sizeof(struct lsm_set_params_hdr); + q6lsm_set_param_hdr_info(&cmd.params_hdr, + data_payload_size, 0, 0, 0); + fwk_mode_cfg = &cmd.fwk_mode_cfg; + + param_size = (sizeof(struct lsm_param_fwk_mode_cfg) - + sizeof(fwk_mode_cfg->common)); + q6lsm_set_param_common(&fwk_mode_cfg->common, + &fwk_mode_cfg_ids, param_size, + set_param_opcode); + + fwk_mode_cfg->minor_version = QLSM_PARAM_ID_MINOR_VERSION; + fwk_mode_cfg->mode = event_mode; + pr_debug("%s: mode = %d\n", __func__, fwk_mode_cfg->mode); + + rc = q6lsm_apr_send_pkt(client, client->apr, + &cmd, true, NULL); + if (rc) + pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", + __func__, msg_hdr->opcode, rc); + return rc; +} + +static int q6lsm_arrange_mch_map(struct lsm_param_media_fmt *media_fmt, + int channel_count) +{ + int rc = 0; + + memset(media_fmt->channel_mapping, 0, LSM_MAX_NUM_CHANNELS); + + switch (channel_count) { + case 1: + media_fmt->channel_mapping[0] = PCM_CHANNEL_FC; + break; + case 2: + media_fmt->channel_mapping[0] = PCM_CHANNEL_FL; + media_fmt->channel_mapping[1] = PCM_CHANNEL_FR; + break; + case 3: + media_fmt->channel_mapping[0] = PCM_CHANNEL_FL; + media_fmt->channel_mapping[1] = PCM_CHANNEL_FR; + media_fmt->channel_mapping[2] = PCM_CHANNEL_FC; + break; + case 4: + media_fmt->channel_mapping[0] = PCM_CHANNEL_FL; + media_fmt->channel_mapping[1] = PCM_CHANNEL_FR; + media_fmt->channel_mapping[2] = PCM_CHANNEL_LS; + media_fmt->channel_mapping[3] = PCM_CHANNEL_RS; + break; + default: + pr_err("%s: invalid num_chan %d\n", __func__, channel_count); + rc = -EINVAL; + break; + } + return rc; +} + +int q6lsm_set_media_fmt_params(struct lsm_client *client) +{ + int rc = 0; + struct lsm_cmd_set_media_fmt cmd; + struct lsm_module_param_ids media_fmt_ids; + struct apr_hdr *msg_hdr; + struct lsm_param_media_fmt *media_fmt; + u32 data_payload_size, param_size, set_param_opcode; + struct lsm_hw_params param = client->hw_params; + + if (client->use_topology) { + set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2; + media_fmt_ids.module_id = LSM_MODULE_ID_FRAMEWORK; + media_fmt_ids.param_id = LSM_PARAM_ID_MEDIA_FMT; + } else { + pr_debug("%s: Ignore sending media format\n", __func__); + goto err_ret; + } + + msg_hdr = &cmd.msg_hdr; + q6lsm_add_hdr(client, msg_hdr, + sizeof(struct lsm_cmd_set_media_fmt), true); + msg_hdr->opcode = set_param_opcode; + data_payload_size = sizeof(struct lsm_cmd_set_media_fmt) - + sizeof(struct apr_hdr) - + sizeof(struct lsm_set_params_hdr); + q6lsm_set_param_hdr_info(&cmd.params_hdr, + data_payload_size, 0, 0, 0); + media_fmt = &cmd.media_fmt; + + param_size = (sizeof(struct lsm_param_media_fmt) - + sizeof(media_fmt->common)); + q6lsm_set_param_common(&media_fmt->common, + &media_fmt_ids, param_size, + set_param_opcode); + + media_fmt->minor_version = QLSM_PARAM_ID_MINOR_VERSION_2; + media_fmt->sample_rate = param.sample_rate; + media_fmt->num_channels = param.num_chs; + media_fmt->bit_width = param.sample_size; + + rc = q6lsm_arrange_mch_map(media_fmt, media_fmt->num_channels); + if (rc) + goto err_ret; + + pr_debug("%s: sample rate= %d, channels %d bit width %d\n", + __func__, media_fmt->sample_rate, media_fmt->num_channels, + media_fmt->bit_width); + + rc = q6lsm_apr_send_pkt(client, client->apr, + &cmd, true, NULL); + if (rc) + pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", + __func__, msg_hdr->opcode, rc); +err_ret: + return rc; +} + +int q6lsm_set_data(struct lsm_client *client, + enum lsm_detection_mode mode, + bool detectfailure) +{ + int rc = 0; + struct lsm_module_param_ids opmode_ids; + struct lsm_module_param_ids conf_levels_ids; + + if (!client->confidence_levels) { + /* + * It is possible that confidence levels are + * not provided. This is not a error condition. + * Return gracefully without any error + */ + pr_debug("%s: no conf levels to set\n", + __func__); + return rc; + } + + if (mode == LSM_MODE_KEYWORD_ONLY_DETECTION) { + client->mode = 0x01; + } else if (mode == LSM_MODE_USER_KEYWORD_DETECTION) { + client->mode = 0x03; + } else { + pr_err("%s: Incorrect detection mode %d\n", __func__, mode); + rc = -EINVAL; + goto err_ret; + } + client->mode |= detectfailure << 2; + + opmode_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP; + opmode_ids.param_id = LSM_PARAM_ID_OPERATION_MODE; + + rc = q6lsm_send_param_opmode(client, &opmode_ids, + LSM_SESSION_CMD_SET_PARAMS); + if (rc) { + pr_err("%s: Failed to set lsm config params %d\n", + __func__, rc); + goto err_ret; + } + + conf_levels_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP; + conf_levels_ids.param_id = LSM_PARAM_ID_MIN_CONFIDENCE_LEVELS; + + rc = q6lsm_send_confidence_levels(client, &conf_levels_ids, + LSM_SESSION_CMD_SET_PARAMS); + if (rc) { + pr_err("%s: Failed to send conf_levels, err = %d\n", + __func__, rc); + goto err_ret; + } + + rc = q6lsm_send_cal(client, LSM_SESSION_CMD_SET_PARAMS); + if (rc) { + pr_err("%s: Failed to send calibration data %d\n", + __func__, rc); + goto err_ret; + } + +err_ret: + return rc; +} + +int q6lsm_register_sound_model(struct lsm_client *client, + enum lsm_detection_mode mode, + bool detectfailure) +{ + int rc; + struct lsm_cmd_reg_snd_model cmd; + + memset(&cmd, 0, sizeof(cmd)); + rc = q6lsm_set_data(client, mode, detectfailure); + if (rc) { + pr_err("%s: Failed to set lsm data, err = %d\n", + __func__, rc); + return rc; + } + + q6lsm_add_hdr(client, &cmd.hdr, sizeof(cmd), true); + cmd.hdr.opcode = LSM_SESSION_CMD_REGISTER_SOUND_MODEL; + cmd.model_addr_lsw = lower_32_bits(client->sound_model.phys); + cmd.model_addr_msw = msm_audio_populate_upper_32_bits( + client->sound_model.phys); + cmd.model_size = client->sound_model.size; + /* read updated mem_map_handle by q6lsm_mmapcallback */ + rmb(); + cmd.mem_map_handle = client->sound_model.mem_map_handle; + + pr_debug("%s: addr %pK, size %d, handle 0x%x\n", __func__, + &client->sound_model.phys, cmd.model_size, cmd.mem_map_handle); + rc = q6lsm_apr_send_pkt(client, client->apr, &cmd, true, NULL); + if (rc) + pr_err("%s: Failed cmd op[0x%x]rc[%d]\n", __func__, + cmd.hdr.opcode, rc); + else + pr_debug("%s: Register sound model succeeded\n", __func__); + + return rc; +} + +int q6lsm_deregister_sound_model(struct lsm_client *client) +{ + int rc; + struct lsm_cmd_reg_snd_model cmd; + + if (!client) { + pr_err("APR handle NULL\n"); + return -EINVAL; + } + if (!client->apr) { + pr_err("APR client handle NULL\n"); + return -EINVAL; + } + + if (CHECK_SESSION(client->session)) { + pr_err("%s: session[%d]", __func__, client->session); + return -EINVAL; + } + + memset(&cmd, 0, sizeof(cmd)); + q6lsm_add_hdr(client, &cmd.hdr, sizeof(cmd.hdr), false); + cmd.hdr.opcode = LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL; + + rc = q6lsm_apr_send_pkt(client, client->apr, &cmd.hdr, true, NULL); + if (rc) { + pr_err("%s: Failed cmd opcode 0x%x, rc %d\n", __func__, + cmd.hdr.opcode, rc); + } else { + pr_debug("%s: Deregister sound model succeeded\n", __func__); + } + + q6lsm_snd_model_buf_free(client); + + return rc; +} + +static void q6lsm_add_mmaphdr(struct lsm_client *client, struct apr_hdr *hdr, + u32 pkt_size, u32 cmd_flg, u32 token) +{ + pr_debug("%s: pkt size=%d cmd_flg=%d session=%d\n", __func__, pkt_size, + cmd_flg, client->session); + hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + hdr->src_port = 0x00; + hdr->dest_port = client->session; + if (cmd_flg) + hdr->token = token; + hdr->pkt_size = pkt_size; +} + +static int q6lsm_memory_map_regions(struct lsm_client *client, + dma_addr_t dma_addr_p, uint32_t dma_buf_sz, + uint32_t *mmap_p) +{ + struct avs_cmd_shared_mem_map_regions *mmap_regions = NULL; + struct avs_shared_map_region_payload *mregions = NULL; + void *mmap_region_cmd = NULL; + void *payload = NULL; + int rc; + int cmd_size = 0; + + pr_debug("%s: dma_addr_p 0x%pK, dma_buf_sz %d, mmap_p 0x%pK, session %d\n", + __func__, &dma_addr_p, dma_buf_sz, mmap_p, + client->session); + if (CHECK_SESSION(client->session)) { + pr_err("%s: session[%d]", __func__, client->session); + return -EINVAL; + } + cmd_size = sizeof(struct avs_cmd_shared_mem_map_regions) + + sizeof(struct avs_shared_map_region_payload); + + mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL); + if (!mmap_region_cmd) + return -ENOMEM; + + mmap_regions = (struct avs_cmd_shared_mem_map_regions *)mmap_region_cmd; + q6lsm_add_mmaphdr(client, &mmap_regions->hdr, cmd_size, true, + (client->session << 8)); + + mmap_regions->hdr.opcode = LSM_SESSION_CMD_SHARED_MEM_MAP_REGIONS; + mmap_regions->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL; + mmap_regions->num_regions = 1; + mmap_regions->property_flag = 0x00; + payload = ((u8 *)mmap_region_cmd + + sizeof(struct avs_cmd_shared_mem_map_regions)); + mregions = (struct avs_shared_map_region_payload *)payload; + + mregions->shm_addr_lsw = lower_32_bits(dma_addr_p); + mregions->shm_addr_msw = msm_audio_populate_upper_32_bits(dma_addr_p); + mregions->mem_size_bytes = dma_buf_sz; + + rc = q6lsm_apr_send_pkt(client, client->mmap_apr, mmap_region_cmd, + true, mmap_p); + if (rc) + pr_err("%s: Failed mmap_regions opcode 0x%x, rc %d\n", + __func__, mmap_regions->hdr.opcode, rc); + + pr_debug("%s: leave %d\n", __func__, rc); + kfree(mmap_region_cmd); + return rc; +} + +static int q6lsm_memory_unmap_regions(struct lsm_client *client, + uint32_t handle) +{ + struct avs_cmd_shared_mem_unmap_regions unmap; + int rc = 0; + int cmd_size = 0; + + if (CHECK_SESSION(client->session)) { + pr_err("%s: session[%d]", __func__, client->session); + return -EINVAL; + } + cmd_size = sizeof(struct avs_cmd_shared_mem_unmap_regions); + q6lsm_add_mmaphdr(client, &unmap.hdr, cmd_size, + true, (client->session << 8)); + unmap.hdr.opcode = LSM_SESSION_CMD_SHARED_MEM_UNMAP_REGIONS; + unmap.mem_map_handle = handle; + + pr_debug("%s: unmap handle 0x%x\n", __func__, unmap.mem_map_handle); + rc = q6lsm_apr_send_pkt(client, client->mmap_apr, &unmap, true, + NULL); + if (rc) + pr_err("%s: Failed mmap_regions opcode 0x%x rc %d\n", + __func__, unmap.hdr.opcode, rc); + + return rc; +} + +static int q6lsm_send_cal(struct lsm_client *client, + u32 set_params_opcode) +{ + int rc = 0; + struct lsm_cmd_set_params params; + struct lsm_set_params_hdr *params_hdr = ¶ms.param_hdr; + struct apr_hdr *msg_hdr = ¶ms.msg_hdr; + struct cal_block_data *cal_block = NULL; + + pr_debug("%s: Session id %d\n", __func__, client->session); + if (CHECK_SESSION(client->session)) { + pr_err("%s: session[%d]", __func__, client->session); + return -EINVAL; + } + + if (lsm_common.cal_data[LSM_CAL_IDX] == NULL) + goto done; + + mutex_lock(&lsm_common.cal_data[LSM_CAL_IDX]->lock); + cal_block = cal_utils_get_only_cal_block( + lsm_common.cal_data[LSM_CAL_IDX]); + + if (!cal_block || cal_block->cal_data.size <= 0) { + pr_debug("%s: No cal to send!\n", __func__); + goto unlock; + } + + if (cal_block->cal_data.size != client->lsm_cal_size) { + pr_err("%s: Cal size %zd doesn't match lsm cal size %d\n", + __func__, cal_block->cal_data.size, + client->lsm_cal_size); + rc = -EINVAL; + goto unlock; + } + /* Cache mmap address, only map once or if new addr */ + lsm_common.common_client[client->session].session = client->session; + q6lsm_add_hdr(client, msg_hdr, sizeof(params), true); + msg_hdr->opcode = set_params_opcode; + q6lsm_set_param_hdr_info(params_hdr, + cal_block->cal_data.size, + lower_32_bits(client->lsm_cal_phy_addr), + msm_audio_populate_upper_32_bits( + client->lsm_cal_phy_addr), + client->sound_model.mem_map_handle); + + pr_debug("%s: Cal Size = %zd", __func__, + cal_block->cal_data.size); + rc = q6lsm_apr_send_pkt(client, client->apr, ¶ms, true, NULL); + if (rc) + pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", + __func__, msg_hdr->opcode, rc); +unlock: + mutex_unlock(&lsm_common.cal_data[LSM_CAL_IDX]->lock); +done: + return rc; +} + + +int q6lsm_snd_model_buf_free(struct lsm_client *client) +{ + int rc; + + pr_debug("%s: Session id %d\n", __func__, client->session); + if (CHECK_SESSION(client->session)) { + pr_err("%s: session[%d]", __func__, client->session); + return -EINVAL; + } + + mutex_lock(&client->cmd_lock); + rc = q6lsm_memory_unmap_regions(client, + client->sound_model.mem_map_handle); + if (rc) + pr_err("%s: CMD Memory_unmap_regions failed %d\n", + __func__, rc); + + if (client->sound_model.data) { + msm_audio_ion_free(client->sound_model.client, + client->sound_model.handle); + client->sound_model.client = NULL; + client->sound_model.handle = NULL; + client->sound_model.data = NULL; + client->sound_model.phys = 0; + client->lsm_cal_phy_addr = 0; + client->lsm_cal_size = 0; + } + mutex_unlock(&client->cmd_lock); + return rc; +} + +static struct lsm_client *q6lsm_get_lsm_client(int session_id) +{ + unsigned long flags; + struct lsm_client *client = NULL; + + spin_lock_irqsave(&lsm_session_lock, flags); + if (session_id < LSM_MIN_SESSION_ID || session_id > LSM_MAX_SESSION_ID) + pr_err("%s: Invalid session %d\n", __func__, session_id); + else if (!lsm_session[session_id]) + pr_err("%s: Not an active session %d\n", __func__, session_id); + else + client = lsm_session[session_id]; + spin_unlock_irqrestore(&lsm_session_lock, flags); + return client; +} + +/* + * q6lsm_mmapcallback : atomic context + */ +static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv) +{ + unsigned long flags; + uint32_t command; + uint32_t retcode; + uint32_t sid; + const uint32_t *payload = data->payload; + struct lsm_client *client = NULL; + + if (data->opcode == RESET_EVENTS) { + sid = (data->token >> 8) & 0x0F; + pr_debug("%s: SSR event received 0x%x, event 0x%x,\n" + "proc 0x%x SID 0x%x\n", __func__, data->opcode, + data->reset_event, data->reset_proc, sid); + lsm_common.common_client[sid].lsm_cal_phy_addr = 0; + cal_utils_clear_cal_block_q6maps(LSM_MAX_CAL_IDX, + lsm_common.cal_data); + lsm_common.set_custom_topology = 1; + return 0; + } + + command = payload[0]; + retcode = payload[1]; + sid = (data->token >> 8) & 0x0F; + pr_debug("%s: opcode 0x%x command 0x%x return code 0x%x SID 0x%x\n", + __func__, data->opcode, command, retcode, sid); + client = q6lsm_get_lsm_client(sid); + if (!client) { + pr_debug("%s: Session %d already freed\n", __func__, sid); + return 0; + } + + switch (data->opcode) { + case LSM_SESSION_CMDRSP_SHARED_MEM_MAP_REGIONS: + if (atomic_read(&client->cmd_state) == CMD_STATE_WAIT_RESP) { + spin_lock_irqsave(&mmap_lock, flags); + *mmap_handle_p = command; + /* spin_unlock_irqrestore implies barrier */ + spin_unlock_irqrestore(&mmap_lock, flags); + atomic_set(&client->cmd_state, CMD_STATE_CLEARED); + wake_up(&client->cmd_wait); + } + break; + case APR_BASIC_RSP_RESULT: + switch (command) { + case LSM_SESSION_CMD_SHARED_MEM_UNMAP_REGIONS: + atomic_set(&client->cmd_state, CMD_STATE_CLEARED); + wake_up(&client->cmd_wait); + break; + case LSM_SESSION_CMD_SHARED_MEM_MAP_REGIONS: + if (retcode != 0) { + /* error state, signal to stop waiting */ + if (atomic_read(&client->cmd_state) == + CMD_STATE_WAIT_RESP) { + spin_lock_irqsave(&mmap_lock, flags); + /* implies barrier */ + spin_unlock_irqrestore(&mmap_lock, + flags); + atomic_set(&client->cmd_state, + CMD_STATE_CLEARED); + wake_up(&client->cmd_wait); + } + } + break; + default: + pr_warn("%s: Unexpected command 0x%x\n", __func__, + command); + } + /* fallthrough */ + default: + pr_debug("%s: command 0x%x return code 0x%x opcode 0x%x\n", + __func__, command, retcode, data->opcode); + break; + } + if (client->cb) + client->cb(data->opcode, data->token, + data->payload, client->priv); + return 0; +} + +int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len, + bool allocate_module_data) +{ + int rc = -EINVAL; + struct cal_block_data *cal_block = NULL; + + size_t pad_zero = 0, total_mem = 0; + + if (!client || len <= LSM_ALIGN_BOUNDARY) + return rc; + + mutex_lock(&client->cmd_lock); + + mutex_lock(&lsm_common.cal_data[LSM_CAL_IDX]->lock); + cal_block = cal_utils_get_only_cal_block( + lsm_common.cal_data[LSM_CAL_IDX]); + if (cal_block == NULL) + goto fail; + + pr_debug("%s:Snd Model len = %zd cal size %zd phys addr %pK", __func__, + len, cal_block->cal_data.size, + &cal_block->cal_data.paddr); + if (!cal_block->cal_data.paddr) { + pr_err("%s: No LSM calibration set for session", __func__); + rc = -EINVAL; + goto fail; + } + if (!client->sound_model.data) { + + /* + * if sound module is sent as set_param + * Then memory needs to be allocated for + * set_param payload as well. + */ + if (allocate_module_data) + len += sizeof(struct lsm_param_payload_common); + + client->sound_model.size = len; + pad_zero = (LSM_ALIGN_BOUNDARY - + (len % LSM_ALIGN_BOUNDARY)); + if ((len > SIZE_MAX - pad_zero) || + (len + pad_zero > + SIZE_MAX - cal_block->cal_data.size)) { + pr_err("%s: invalid allocation size, len = %zd, pad_zero =%zd, cal_size = %zd\n", + __func__, len, pad_zero, + cal_block->cal_data.size); + rc = -EINVAL; + goto fail; + } + + total_mem = PAGE_ALIGN(pad_zero + len + + cal_block->cal_data.size); + pr_debug("%s: Pad zeros sound model %zd Total mem %zd\n", + __func__, pad_zero, total_mem); + rc = msm_audio_ion_alloc("lsm_client", + &client->sound_model.client, + &client->sound_model.handle, + total_mem, + &client->sound_model.phys, + &len, + &client->sound_model.data); + if (rc) { + pr_err("%s: Audio ION alloc is failed, rc = %d\n", + __func__, rc); + goto fail; + } + pr_debug("%s: Length = %zd\n", __func__, len); + client->lsm_cal_phy_addr = (pad_zero + + client->sound_model.phys + + client->sound_model.size); + client->lsm_cal_size = cal_block->cal_data.size; + memcpy((client->sound_model.data + pad_zero + + client->sound_model.size), + (uint32_t *)cal_block->cal_data.kvaddr, client->lsm_cal_size); + pr_debug("%s: Copy cal start virt_addr %pK phy_addr %pK\n" + "Offset cal virtual Addr %pK\n", __func__, + client->sound_model.data, &client->sound_model.phys, + (pad_zero + client->sound_model.data + + client->sound_model.size)); + } else { + pr_err("%s: sound model busy\n", __func__); + rc = -EBUSY; + goto fail; + } + mutex_unlock(&lsm_common.cal_data[LSM_CAL_IDX]->lock); + mutex_unlock(&client->cmd_lock); + + rc = q6lsm_memory_map_regions(client, client->sound_model.phys, + len, + &client->sound_model.mem_map_handle); + if (rc) { + pr_err("%s: CMD Memory_map_regions failed %d\n", __func__, rc); + goto exit; + } + + return 0; +fail: + mutex_unlock(&lsm_common.cal_data[LSM_CAL_IDX]->lock); + mutex_unlock(&client->cmd_lock); +exit: + q6lsm_snd_model_buf_free(client); + return rc; +} + +static int q6lsm_cmd(struct lsm_client *client, int opcode, bool wait) +{ + struct apr_hdr hdr; + int rc; + + pr_debug("%s: enter opcode %x wait %d\n", __func__, opcode, wait); + q6lsm_add_hdr(client, &hdr, sizeof(hdr), true); + switch (opcode) { + case LSM_SESSION_CMD_START: + case LSM_SESSION_CMD_STOP: + case LSM_SESSION_CMD_CLOSE_TX: + case LSM_SESSION_CMD_EOB: + hdr.opcode = opcode; + break; + default: + pr_err("%s: Invalid opcode 0x%x\n", __func__, opcode); + return -EINVAL; + } + rc = q6lsm_apr_send_pkt(client, client->apr, &hdr, wait, NULL); + if (rc) + pr_err("%s: Failed commmand 0x%x\n", __func__, hdr.opcode); + + pr_debug("%s: leave %d\n", __func__, rc); + return rc; +} + +static int q6lsm_send_param_epd_thres( + struct lsm_client *client, + void *data, struct lsm_module_param_ids *ids) +{ + struct snd_lsm_ep_det_thres *ep_det_data; + struct lsm_cmd_set_epd_threshold epd_cmd; + struct apr_hdr *msg_hdr = &epd_cmd.msg_hdr; + struct lsm_set_params_hdr *param_hdr = + &epd_cmd.param_hdr; + struct lsm_param_epd_thres *epd_thres = + &epd_cmd.epd_thres; + int rc; + + ep_det_data = (struct snd_lsm_ep_det_thres *) data; + q6lsm_add_hdr(client, msg_hdr, + sizeof(epd_cmd), true); + msg_hdr->opcode = LSM_SESSION_CMD_SET_PARAMS_V2; + q6lsm_set_param_hdr_info(param_hdr, + sizeof(*epd_thres), 0, 0, 0); + q6lsm_set_param_common(&epd_thres->common, ids, + sizeof(*epd_thres) - sizeof(epd_thres->common), + LSM_SESSION_CMD_SET_PARAMS_V2); + epd_thres->minor_version = QLSM_PARAM_ID_MINOR_VERSION; + epd_thres->epd_begin = ep_det_data->epd_begin; + epd_thres->epd_end = ep_det_data->epd_end; + + rc = q6lsm_apr_send_pkt(client, client->apr, + &epd_cmd, true, NULL); + if (unlikely(rc)) + pr_err("%s: EPD_THRESHOLD failed, rc %d\n", + __func__, rc); + return rc; +} + +static int q6lsm_send_param_gain( + struct lsm_client *client, + u16 gain, struct lsm_module_param_ids *ids) +{ + struct lsm_cmd_set_gain lsm_cmd_gain; + struct apr_hdr *msg_hdr = &lsm_cmd_gain.msg_hdr; + struct lsm_param_gain *lsm_gain = &lsm_cmd_gain.lsm_gain; + int rc; + + q6lsm_add_hdr(client, msg_hdr, + sizeof(lsm_cmd_gain), true); + msg_hdr->opcode = LSM_SESSION_CMD_SET_PARAMS_V2; + q6lsm_set_param_hdr_info(&lsm_cmd_gain.param_hdr, + sizeof(*lsm_gain), 0, 0, 0); + q6lsm_set_param_common(&lsm_gain->common, ids, + sizeof(*lsm_gain) - sizeof(lsm_gain->common), + LSM_SESSION_CMD_SET_PARAMS_V2); + lsm_gain->minor_version = QLSM_PARAM_ID_MINOR_VERSION; + lsm_gain->gain = gain; + lsm_gain->reserved = 0; + + rc = q6lsm_apr_send_pkt(client, client->apr, + &lsm_cmd_gain, true, NULL); + if (unlikely(rc)) + pr_err("%s: LSM_GAIN CMD send failed, rc %d\n", + __func__, rc); + return rc; +} + +int q6lsm_set_one_param(struct lsm_client *client, + struct lsm_params_info *p_info, void *data, + uint32_t param_type) +{ + int rc = 0, pkt_sz; + struct lsm_module_param_ids ids; + u8 *packet; + + memset(&ids, 0, sizeof(ids)); + switch (param_type) { + case LSM_ENDPOINT_DETECT_THRESHOLD: { + ids.module_id = p_info->module_id; + ids.param_id = p_info->param_id; + rc = q6lsm_send_param_epd_thres(client, data, + &ids); + break; + } + + case LSM_OPERATION_MODE: { + struct snd_lsm_detect_mode *det_mode = data; + struct lsm_module_param_ids opmode_ids; + + if (det_mode->mode == LSM_MODE_KEYWORD_ONLY_DETECTION) { + client->mode = 0x01; + } else if (det_mode->mode == LSM_MODE_USER_KEYWORD_DETECTION) { + client->mode = 0x03; + } else { + pr_err("%s: Incorrect detection mode %d\n", + __func__, det_mode->mode); + return -EINVAL; + } + + client->mode |= det_mode->detect_failure << 2; + + opmode_ids.module_id = p_info->module_id; + opmode_ids.param_id = p_info->param_id; + + rc = q6lsm_send_param_opmode(client, &opmode_ids, + LSM_SESSION_CMD_SET_PARAMS_V2); + if (rc) + pr_err("%s: OPERATION_MODE failed, rc %d\n", + __func__, rc); + break; + } + + case LSM_GAIN: { + struct snd_lsm_gain *lsm_gain = (struct snd_lsm_gain *) data; + + ids.module_id = p_info->module_id; + ids.param_id = p_info->param_id; + rc = q6lsm_send_param_gain(client, lsm_gain->gain, &ids); + if (rc) + pr_err("%s: LSM_GAIN command failed, rc %d\n", + __func__, rc); + break; + } + + case LSM_MIN_CONFIDENCE_LEVELS: + ids.module_id = p_info->module_id; + ids.param_id = p_info->param_id; + rc = q6lsm_send_confidence_levels(client, &ids, + LSM_SESSION_CMD_SET_PARAMS_V2); + if (rc) + pr_err("%s: CONFIDENCE_LEVELS cmd failed, rc %d\n", + __func__, rc); + break; + case LSM_POLLING_ENABLE: { + struct snd_lsm_poll_enable *lsm_poll_enable = + (struct snd_lsm_poll_enable *) data; + ids.module_id = p_info->module_id; + ids.param_id = p_info->param_id; + rc = q6lsm_send_param_polling_enable(client, + lsm_poll_enable->poll_en, &ids, + LSM_SESSION_CMD_SET_PARAMS_V2); + if (rc) + pr_err("%s: POLLING ENABLE cmd failed, rc %d\n", + __func__, rc); + break; + } + + case LSM_REG_SND_MODEL: { + struct lsm_cmd_set_params model_param; + u32 payload_size; + + memset(&model_param, 0, sizeof(model_param)); + q6lsm_add_hdr(client, &model_param.msg_hdr, + sizeof(model_param), true); + model_param.msg_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS_V2; + payload_size = p_info->param_size + + sizeof(struct lsm_param_payload_common); + q6lsm_set_param_hdr_info(&model_param.param_hdr, + payload_size, + lower_32_bits(client->sound_model.phys), + msm_audio_populate_upper_32_bits( + client->sound_model.phys), + client->sound_model.mem_map_handle); + + rc = q6lsm_apr_send_pkt(client, client->apr, + &model_param, true, NULL); + if (rc) { + pr_err("%s: REG_SND_MODEL failed, rc %d\n", + __func__, rc); + return rc; + } + + rc = q6lsm_send_cal(client, LSM_SESSION_CMD_SET_PARAMS); + if (rc) + pr_err("%s: Failed to send lsm cal, err = %d\n", + __func__, rc); + break; + } + + case LSM_DEREG_SND_MODEL: { + struct lsm_param_payload_common *common; + struct lsm_cmd_set_params *param; + + pkt_sz = sizeof(*param) + sizeof(*common); + packet = kzalloc(pkt_sz, GFP_KERNEL); + if (!packet) { + pr_err("%s: No memory for DEREG_SND_MODEL pkt, size = %d\n", + __func__, pkt_sz); + return -ENOMEM; + } + + param = (struct lsm_cmd_set_params *) packet; + common = (struct lsm_param_payload_common *) + (packet + sizeof(*param)); + q6lsm_add_hdr(client, ¶m->msg_hdr, pkt_sz, true); + param->msg_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS_V2; + q6lsm_set_param_hdr_info(¶m->param_hdr, + sizeof(*common), + 0, 0, 0); + ids.module_id = p_info->module_id; + ids.param_id = p_info->param_id; + q6lsm_set_param_common(common, &ids, 0, + LSM_SESSION_CMD_SET_PARAMS_V2); + rc = q6lsm_apr_send_pkt(client, client->apr, + packet, true, NULL); + if (rc) + pr_err("%s: DEREG_SND_MODEL failed, rc %d\n", + __func__, rc); + kfree(packet); + break; + } + + case LSM_CUSTOM_PARAMS: { + struct apr_hdr *hdr; + u8 *custom_data; + + if (p_info->param_size < + sizeof(struct lsm_param_payload_common)) { + pr_err("%s: Invalid param_size %d\n", + __func__, p_info->param_size); + return -EINVAL; + } + + pkt_sz = p_info->param_size + sizeof(*hdr); + packet = kzalloc(pkt_sz, GFP_KERNEL); + if (!packet) { + pr_err("%s: no memory for CUSTOM_PARAMS, size = %d\n", + __func__, pkt_sz); + return -ENOMEM; + } + + hdr = (struct apr_hdr *) packet; + custom_data = (u8 *) (packet + sizeof(*hdr)); + q6lsm_add_hdr(client, hdr, pkt_sz, true); + hdr->opcode = LSM_SESSION_CMD_SET_PARAMS_V2; + memcpy(custom_data, data, p_info->param_size); + + rc = q6lsm_apr_send_pkt(client, client->apr, + packet, true, NULL); + if (rc) + pr_err("%s: CUSTOM_PARAMS failed, rc %d\n", + __func__, rc); + kfree(packet); + break; + } + default: + pr_err("%s: wrong param_type 0x%x\n", + __func__, p_info->param_type); + } + + return rc; +} + + +int q6lsm_start(struct lsm_client *client, bool wait) +{ + return q6lsm_cmd(client, LSM_SESSION_CMD_START, wait); +} + +int q6lsm_stop(struct lsm_client *client, bool wait) +{ + return q6lsm_cmd(client, LSM_SESSION_CMD_STOP, wait); +} + +int q6lsm_close(struct lsm_client *client) +{ + return q6lsm_cmd(client, LSM_SESSION_CMD_CLOSE_TX, true); +} + +int q6lsm_lab_control(struct lsm_client *client, u32 enable) +{ + int rc = 0; + struct lsm_params_lab_enable lab_enable; + struct lsm_params_lab_config lab_config; + struct lsm_module_param_ids lab_ids; + u32 param_size; + + if (!client) { + pr_err("%s: invalid param client %pK\n", __func__, client); + return -EINVAL; + } + /* enable/disable lab on dsp */ + q6lsm_add_hdr(client, &lab_enable.msg_hdr, sizeof(lab_enable), true); + lab_enable.msg_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS; + q6lsm_set_param_hdr_info(&lab_enable.params_hdr, + sizeof(struct lsm_lab_enable), + 0, 0, 0); + param_size = (sizeof(struct lsm_lab_enable) - + sizeof(struct lsm_param_payload_common)); + lab_ids.module_id = LSM_MODULE_ID_LAB; + lab_ids.param_id = LSM_PARAM_ID_LAB_ENABLE; + q6lsm_set_param_common(&lab_enable.lab_enable.common, + &lab_ids, param_size, + LSM_SESSION_CMD_SET_PARAMS); + lab_enable.lab_enable.enable = (enable) ? 1 : 0; + rc = q6lsm_apr_send_pkt(client, client->apr, &lab_enable, true, NULL); + if (rc) { + pr_err("%s: Lab enable failed rc %d\n", __func__, rc); + return rc; + } + if (!enable) + goto exit; + /* lab session is being enabled set the config values */ + q6lsm_add_hdr(client, &lab_config.msg_hdr, sizeof(lab_config), true); + lab_config.msg_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS; + q6lsm_set_param_hdr_info(&lab_config.params_hdr, + sizeof(struct lsm_lab_config), + 0, 0, 0); + lab_ids.module_id = LSM_MODULE_ID_LAB; + lab_ids.param_id = LSM_PARAM_ID_LAB_CONFIG; + param_size = (sizeof(struct lsm_lab_config) - + sizeof(struct lsm_param_payload_common)); + q6lsm_set_param_common(&lab_config.lab_config.common, + &lab_ids, param_size, + LSM_SESSION_CMD_SET_PARAMS); + lab_config.lab_config.minor_version = 1; + lab_config.lab_config.wake_up_latency_ms = 250; + rc = q6lsm_apr_send_pkt(client, client->apr, &lab_config, true, NULL); + if (rc) { + pr_err("%s: Lab config failed rc %d disable lab\n", + __func__, rc); + /* Lab config failed disable lab */ + lab_enable.lab_enable.enable = 0; + if (q6lsm_apr_send_pkt(client, client->apr, + &lab_enable, true, NULL)) + pr_err("%s: Lab disable failed\n", __func__); + } +exit: + return rc; +} + +int q6lsm_stop_lab(struct lsm_client *client) +{ + int rc = 0; + + if (!client) { + pr_err("%s: invalid param client %pK\n", __func__, client); + return -EINVAL; + } + rc = q6lsm_cmd(client, LSM_SESSION_CMD_EOB, true); + if (rc) + pr_err("%s: Lab stop failed %d\n", __func__, rc); + return rc; +} + +int q6lsm_read(struct lsm_client *client, struct lsm_cmd_read *read) +{ + int rc = 0; + + if (!client || !read) { + pr_err("%s: Invalid params client %pK read %pK\n", __func__, + client, read); + return -EINVAL; + } + pr_debug("%s: read call memmap handle %x address %x%x size %d\n", + __func__, read->mem_map_handle, read->buf_addr_msw, + read->buf_addr_lsw, read->buf_size); + q6lsm_add_hdr(client, &read->hdr, sizeof(struct lsm_cmd_read), true); + read->hdr.opcode = LSM_SESSION_CMD_READ; + rc = q6lsm_apr_send_pkt(client, client->apr, read, false, NULL); + if (rc) + pr_err("%s: read buffer call failed rc %d\n", __func__, rc); + return rc; +} + +int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc) +{ + int ret = 0, i = 0; + size_t allocate_size = 0, len = 0; + + if (!client) { + pr_err("%s: invalid client\n", __func__); + return -EINVAL; + } + if (alloc) { + if (client->lab_buffer) { + pr_err("%s: buffers are allocated period count %d period size %d\n", + __func__, + client->hw_params.period_count, + client->hw_params.buf_sz); + return -EINVAL; + } + allocate_size = client->hw_params.period_count * + client->hw_params.buf_sz; + allocate_size = PAGE_ALIGN(allocate_size); + client->lab_buffer = + kzalloc(sizeof(struct lsm_lab_buffer) * + client->hw_params.period_count, GFP_KERNEL); + if (!client->lab_buffer) { + pr_err("%s: memory allocation for lab buffer failed count %d\n" + , __func__, + client->hw_params.period_count); + return -ENOMEM; + } + ret = msm_audio_ion_alloc("lsm_lab", + &client->lab_buffer[0].client, + &client->lab_buffer[0].handle, + allocate_size, &client->lab_buffer[0].phys, + &len, + &client->lab_buffer[0].data); + if (ret) + pr_err("%s: ion alloc failed ret %d size %zd\n", + __func__, ret, allocate_size); + else { + ret = q6lsm_memory_map_regions(client, + client->lab_buffer[0].phys, len, + &client->lab_buffer[0].mem_map_handle); + if (ret) { + pr_err("%s: memory map filed ret %d size %zd\n", + __func__, ret, len); + msm_audio_ion_free( + client->lab_buffer[0].client, + client->lab_buffer[0].handle); + } + } + if (ret) { + pr_err("%s: alloc lab buffer failed ret %d\n", + __func__, ret); + kfree(client->lab_buffer); + client->lab_buffer = NULL; + } else { + pr_debug("%s: Memory map handle %x phys %pK size %d\n", + __func__, + client->lab_buffer[0].mem_map_handle, + &client->lab_buffer[0].phys, + client->hw_params.buf_sz); + for (i = 0; i < client->hw_params.period_count; i++) { + client->lab_buffer[i].phys = + client->lab_buffer[0].phys + + (i * client->hw_params.buf_sz); + client->lab_buffer[i].size = + client->hw_params.buf_sz; + client->lab_buffer[i].data = + (u8 *)(client->lab_buffer[0].data) + + (i * client->hw_params.buf_sz); + client->lab_buffer[i].mem_map_handle = + client->lab_buffer[0].mem_map_handle; + } + } + } else { + ret = q6lsm_memory_unmap_regions(client, + client->lab_buffer[0].mem_map_handle); + if (!ret) + msm_audio_ion_free( + client->lab_buffer[0].client, + client->lab_buffer[0].handle); + else + pr_err("%s: unmap failed not freeing memory\n", + __func__); + kfree(client->lab_buffer); + client->lab_buffer = NULL; + } + return ret; +} + +static int get_cal_type_index(int32_t cal_type) +{ + int ret = -EINVAL; + + switch (cal_type) { + case LSM_CUST_TOPOLOGY_CAL_TYPE: + ret = LSM_CUSTOM_TOP_IDX; + break; + case LSM_TOPOLOGY_CAL_TYPE: + ret = LSM_TOP_IDX; + break; + case LSM_CAL_TYPE: + ret = LSM_CAL_IDX; + break; + default: + pr_err("%s: invalid cal type %d!\n", __func__, cal_type); + } + return ret; +} + +static int q6lsm_alloc_cal(int32_t cal_type, + size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + + pr_debug("%s:\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + ret = cal_utils_alloc_cal(data_size, data, + lsm_common.cal_data[cal_index], 0, NULL); + if (ret < 0) { + pr_err("%s: cal_utils_alloc_block failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + ret = -EINVAL; + goto done; + } +done: + return ret; +} + +static int q6lsm_dealloc_cal(int32_t cal_type, + size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + + pr_debug("%s:\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + ret = cal_utils_dealloc_cal(data_size, data, + lsm_common.cal_data[cal_index]); + if (ret < 0) { + pr_err("%s: cal_utils_dealloc_block failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + ret = -EINVAL; + goto done; + } +done: + return ret; +} + +static int q6lsm_set_cal(int32_t cal_type, + size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + + pr_debug("%s:\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + ret = cal_utils_set_cal(data_size, data, + lsm_common.cal_data[cal_index], 0, NULL); + if (ret < 0) { + pr_err("%s: cal_utils_set_cal failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + ret = -EINVAL; + goto done; + } + + if (cal_index == LSM_CUSTOM_TOP_IDX) { + mutex_lock(&lsm_common.cal_data[LSM_CUSTOM_TOP_IDX]->lock); + lsm_common.set_custom_topology = 1; + mutex_unlock(&lsm_common.cal_data[LSM_CUSTOM_TOP_IDX]->lock); + } + +done: + return ret; +} + +static void lsm_delete_cal_data(void) +{ + pr_debug("%s:\n", __func__); + + cal_utils_destroy_cal_types(LSM_MAX_CAL_IDX, lsm_common.cal_data); +} + +static int q6lsm_init_cal_data(void) +{ + int ret = 0; + struct cal_type_info cal_type_info[] = { + {{LSM_CUST_TOPOLOGY_CAL_TYPE, + {q6lsm_alloc_cal, q6lsm_dealloc_cal, NULL, + q6lsm_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{LSM_TOPOLOGY_CAL_TYPE, + {NULL, NULL, NULL, + q6lsm_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{LSM_CAL_TYPE, + {q6lsm_alloc_cal, q6lsm_dealloc_cal, NULL, + q6lsm_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} } + }; + pr_debug("%s:\n", __func__); + + ret = cal_utils_create_cal_types(LSM_MAX_CAL_IDX, + lsm_common.cal_data, cal_type_info); + if (ret < 0) { + pr_err("%s: could not create cal type!\n", + __func__); + ret = -EINVAL; + goto err; + } + + return ret; +err: + lsm_delete_cal_data(); + return ret; +} + +static int __init q6lsm_init(void) +{ + int i = 0; + + pr_debug("%s:\n", __func__); + spin_lock_init(&lsm_session_lock); + spin_lock_init(&mmap_lock); + mutex_init(&lsm_common.apr_lock); + for (; i <= LSM_MAX_SESSION_ID; i++) { + lsm_common.common_client[i].session = LSM_CONTROL_SESSION; + init_waitqueue_head(&lsm_common.common_client[i].cmd_wait); + mutex_init(&lsm_common.common_client[i].cmd_lock); + atomic_set(&lsm_common.common_client[i].cmd_state, + CMD_STATE_CLEARED); + } + + if (q6lsm_init_cal_data()) + pr_err("%s: could not init cal data!\n", __func__); + + return 0; +} + +static void __exit q6lsm_exit(void) +{ + lsm_delete_cal_data(); +} + +device_initcall(q6lsm_init); +__exitcall(q6lsm_exit); diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c new file mode 100644 index 000000000000..15c9e130f4f4 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/q6voice.c @@ -0,0 +1,8661 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "sound/q6audio-v2.h" +#include "sound/apr_audio-v2.h" +#include "sound/q6afe-v2.h" +#include +#include "q6voice.h" +#include + +#define TIMEOUT_MS 300 + + +#define CMD_STATUS_SUCCESS 0 +#define CMD_STATUS_FAIL 1 + +enum { + VOC_TOKEN_NONE, + VOIP_MEM_MAP_TOKEN, + VOC_CAL_MEM_MAP_TOKEN, + VOC_VOICE_HOST_PCM_MAP_TOKEN, + VOC_RTAC_MEM_MAP_TOKEN, + VOC_SOURCE_TRACKING_MEM_MAP_TOKEN +}; + +struct cvd_version_table cvd_version_table_mapping[CVD_INT_VERSION_MAX] = { + {CVD_VERSION_DEFAULT, CVD_INT_VERSION_DEFAULT}, + {CVD_VERSION_0_0, CVD_INT_VERSION_0_0}, + {CVD_VERSION_2_1, CVD_INT_VERSION_2_1}, + {CVD_VERSION_2_2, CVD_INT_VERSION_2_2}, + {CVD_VERSION_2_3, CVD_INT_VERSION_2_3}, +}; + +static struct common_data common; +static bool module_initialized; + +static int voice_send_enable_vocproc_cmd(struct voice_data *v); +static int voice_send_netid_timing_cmd(struct voice_data *v); +static int voice_send_attach_vocproc_cmd(struct voice_data *v); +static int voice_send_set_device_cmd(struct voice_data *v); +static int voice_send_vol_step_cmd(struct voice_data *v); +static int voice_send_mvm_unmap_memory_physical_cmd(struct voice_data *v, + uint32_t mem_handle); +static int voice_send_mvm_cal_network_cmd(struct voice_data *v); +static int voice_send_mvm_media_type_cmd(struct voice_data *v); +static int voice_send_mvm_cvd_version_cmd(struct voice_data *v); +static int voice_send_cvs_data_exchange_mode_cmd(struct voice_data *v); +static int voice_send_cvs_packet_exchange_config_cmd(struct voice_data *v); +static int voice_set_packet_exchange_mode_and_config(uint32_t session_id, + uint32_t mode); + +static int voice_send_cvs_register_cal_cmd(struct voice_data *v); +static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v); +static int voice_send_cvp_create_cmd(struct voice_data *v); +static int voice_send_cvp_register_dev_cfg_cmd(struct voice_data *v); +static int voice_send_cvp_deregister_dev_cfg_cmd(struct voice_data *v); +static int voice_send_cvp_register_cal_cmd(struct voice_data *v); +static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v); +static int voice_send_cvp_register_vol_cal_cmd(struct voice_data *v); +static int voice_send_cvp_deregister_vol_cal_cmd(struct voice_data *v); +static int voice_send_cvp_media_fmt_info_cmd(struct voice_data *v); +static int voice_send_cvp_device_channels_cmd(struct voice_data *v); +static int voice_send_cvp_media_format_cmd(struct voice_data *v, + uint32_t param_type); +static int voice_send_cvp_topology_commit_cmd(struct voice_data *v); + +static int voice_cvs_stop_playback(struct voice_data *v); +static int voice_cvs_start_playback(struct voice_data *v); +static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode); +static int voice_cvs_stop_record(struct voice_data *v); + +static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv); +static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv); +static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv); + +static int voice_send_set_pp_enable_cmd(struct voice_data *v, + uint32_t module_id, int enable); +static int is_cal_memory_allocated(void); +static bool is_cvd_version_queried(void); +static int is_voip_memory_allocated(void); +static int voice_get_cvd_int_version(char *cvd_ver_string); +static int voice_alloc_cal_mem_map_table(void); +static int voice_alloc_rtac_mem_map_table(void); +static int voice_alloc_oob_shared_mem(void); +static int voice_free_oob_shared_mem(void); +static int voice_alloc_oob_mem_table(void); +static int voice_alloc_and_map_oob_mem(struct voice_data *v); + +static struct voice_data *voice_get_session_by_idx(int idx); + +static int remap_cal_data(struct cal_block_data *cal_block, + uint32_t session_id); +static int voice_unmap_cal_memory(int32_t cal_type, + struct cal_block_data *cal_block); + +static int is_source_tracking_shared_memomry_allocated(void); +static int voice_alloc_source_tracking_shared_memory(void); +static int voice_alloc_and_map_source_tracking_shared_memory( + struct voice_data *v); +static int voice_unmap_and_free_source_tracking_shared_memory( + struct voice_data *v); +static int voice_send_set_sound_focus_cmd(struct voice_data *v, + struct sound_focus_param soundFocusData); +static int voice_send_get_sound_focus_cmd(struct voice_data *v, + struct sound_focus_param *soundFocusData); +static int voice_send_get_source_tracking_cmd(struct voice_data *v, + struct source_tracking_param *sourceTrackingData); + +static void voice_itr_init(struct voice_session_itr *itr, + u32 session_id) +{ + if (itr == NULL) + return; + itr->session_idx = voice_get_idx_for_session(session_id); + if (session_id == ALL_SESSION_VSID) + itr->cur_idx = 0; + else + itr->cur_idx = itr->session_idx; + +} + +static bool voice_itr_get_next_session(struct voice_session_itr *itr, + struct voice_data **voice) +{ + bool ret = false; + + if (itr == NULL) + return false; + pr_debug("%s : cur idx = %d session idx = %d\n", + __func__, itr->cur_idx, itr->session_idx); + + if (itr->cur_idx <= itr->session_idx) { + ret = true; + *voice = voice_get_session_by_idx(itr->cur_idx); + itr->cur_idx++; + } else { + *voice = NULL; + } + + return ret; +} + +static bool voice_is_valid_session_id(uint32_t session_id) +{ + bool ret = false; + + switch (session_id) { + case VOICE_SESSION_VSID: + case VOICE2_SESSION_VSID: + case VOLTE_SESSION_VSID: + case VOIP_SESSION_VSID: + case QCHAT_SESSION_VSID: + case VOWLAN_SESSION_VSID: + case VOICEMMODE1_VSID: + case VOICEMMODE2_VSID: + case ALL_SESSION_VSID: + ret = true; + break; + default: + pr_err("%s: Invalid session_id : %x\n", __func__, session_id); + + break; + } + + return ret; +} + +static u16 voice_get_mvm_handle(struct voice_data *v) +{ + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return 0; + } + + pr_debug("%s: mvm_handle %d\n", __func__, v->mvm_handle); + + return v->mvm_handle; +} + +static void voice_set_mvm_handle(struct voice_data *v, u16 mvm_handle) +{ + pr_debug("%s: mvm_handle %d\n", __func__, mvm_handle); + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return; + } + + v->mvm_handle = mvm_handle; +} + +static u16 voice_get_cvs_handle(struct voice_data *v) +{ + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return 0; + } + + pr_debug("%s: cvs_handle %d\n", __func__, v->cvs_handle); + + return v->cvs_handle; +} + +static void voice_set_cvs_handle(struct voice_data *v, u16 cvs_handle) +{ + pr_debug("%s: cvs_handle %d\n", __func__, cvs_handle); + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return; + } + + v->cvs_handle = cvs_handle; +} + +static u16 voice_get_cvp_handle(struct voice_data *v) +{ + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return 0; + } + + pr_debug("%s: cvp_handle %d\n", __func__, v->cvp_handle); + + return v->cvp_handle; +} + +static void voice_set_cvp_handle(struct voice_data *v, u16 cvp_handle) +{ + pr_debug("%s: cvp_handle %d\n", __func__, cvp_handle); + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return; + } + + v->cvp_handle = cvp_handle; +} + +char *voc_get_session_name(u32 session_id) +{ + char *session_name = NULL; + + if (session_id == common.voice[VOC_PATH_PASSIVE].session_id) { + session_name = VOICE_SESSION_NAME; + } else if (session_id == + common.voice[VOC_PATH_VOLTE_PASSIVE].session_id) { + session_name = VOLTE_SESSION_NAME; + } else if (session_id == + common.voice[VOC_PATH_QCHAT_PASSIVE].session_id) { + session_name = QCHAT_SESSION_NAME; + } else if (session_id == + common.voice[VOC_PATH_VOWLAN_PASSIVE].session_id) { + session_name = VOWLAN_SESSION_NAME; + } else if (session_id == + common.voice[VOC_PATH_VOICEMMODE1_PASSIVE].session_id) { + session_name = VOICEMMODE1_NAME; + } else if (session_id == + common.voice[VOC_PATH_VOICEMMODE2_PASSIVE].session_id) { + session_name = VOICEMMODE2_NAME; + } else if (session_id == common.voice[VOC_PATH_FULL].session_id) { + session_name = VOIP_SESSION_NAME; + } + return session_name; +} + +uint32_t voc_get_session_id(char *name) +{ + u32 session_id = 0; + + if (name != NULL) { + if (!strcmp(name, "Voice session")) + session_id = common.voice[VOC_PATH_PASSIVE].session_id; + else if (!strcmp(name, "Voice2 session")) + session_id = + common.voice[VOC_PATH_VOICE2_PASSIVE].session_id; + else if (!strcmp(name, "VoLTE session")) + session_id = + common.voice[VOC_PATH_VOLTE_PASSIVE].session_id; + else if (!strcmp(name, "QCHAT session")) + session_id = + common.voice[VOC_PATH_QCHAT_PASSIVE].session_id; + else if (!strcmp(name, "VoWLAN session")) + session_id = + common.voice[VOC_PATH_VOWLAN_PASSIVE].session_id; + else if (!strcmp(name, "VoiceMMode1")) + session_id = + common.voice[VOC_PATH_VOICEMMODE1_PASSIVE].session_id; + else if (!strcmp(name, "VoiceMMode2")) + session_id = + common.voice[VOC_PATH_VOICEMMODE2_PASSIVE].session_id; + else + session_id = common.voice[VOC_PATH_FULL].session_id; + + pr_debug("%s: %s has session id 0x%x\n", __func__, name, + session_id); + } + + return session_id; +} + +static struct voice_data *voice_get_session(u32 session_id) +{ + struct voice_data *v = NULL; + + switch (session_id) { + case VOICE_SESSION_VSID: + v = &common.voice[VOC_PATH_PASSIVE]; + break; + + case VOICE2_SESSION_VSID: + v = &common.voice[VOC_PATH_VOICE2_PASSIVE]; + break; + + case VOLTE_SESSION_VSID: + v = &common.voice[VOC_PATH_VOLTE_PASSIVE]; + break; + + case VOIP_SESSION_VSID: + v = &common.voice[VOC_PATH_FULL]; + break; + + case QCHAT_SESSION_VSID: + v = &common.voice[VOC_PATH_QCHAT_PASSIVE]; + break; + + case VOWLAN_SESSION_VSID: + v = &common.voice[VOC_PATH_VOWLAN_PASSIVE]; + break; + + case VOICEMMODE1_VSID: + v = &common.voice[VOC_PATH_VOICEMMODE1_PASSIVE]; + break; + + case VOICEMMODE2_VSID: + v = &common.voice[VOC_PATH_VOICEMMODE2_PASSIVE]; + break; + + case ALL_SESSION_VSID: + break; + + default: + pr_err("%s: Invalid session_id : %x\n", __func__, session_id); + + break; + } + + pr_debug("%s:session_id 0x%x session handle %pK\n", + __func__, session_id, v); + + return v; +} + +int voice_get_idx_for_session(u32 session_id) +{ + int idx = 0; + + switch (session_id) { + case VOICE_SESSION_VSID: + idx = VOC_PATH_PASSIVE; + break; + + case VOICE2_SESSION_VSID: + idx = VOC_PATH_VOICE2_PASSIVE; + break; + + case VOLTE_SESSION_VSID: + idx = VOC_PATH_VOLTE_PASSIVE; + break; + + case VOIP_SESSION_VSID: + idx = VOC_PATH_FULL; + break; + + case QCHAT_SESSION_VSID: + idx = VOC_PATH_QCHAT_PASSIVE; + break; + + case VOWLAN_SESSION_VSID: + idx = VOC_PATH_VOWLAN_PASSIVE; + break; + + case VOICEMMODE1_VSID: + idx = VOC_PATH_VOICEMMODE1_PASSIVE; + break; + + case VOICEMMODE2_VSID: + idx = VOC_PATH_VOICEMMODE2_PASSIVE; + break; + + case ALL_SESSION_VSID: + idx = MAX_VOC_SESSIONS - 1; + break; + + default: + pr_err("%s: Invalid session_id : %x\n", __func__, session_id); + + break; + } + + return idx; +} + +static struct voice_data *voice_get_session_by_idx(int idx) +{ + return ((idx < 0 || idx >= MAX_VOC_SESSIONS) ? + NULL : &common.voice[idx]); +} + +static bool is_voip_session(u32 session_id) +{ + return (session_id == common.voice[VOC_PATH_FULL].session_id); +} + +static bool is_volte_session(u32 session_id) +{ + return (session_id == common.voice[VOC_PATH_VOLTE_PASSIVE].session_id); +} + +static bool is_voice2_session(u32 session_id) +{ + return (session_id == common.voice[VOC_PATH_VOICE2_PASSIVE].session_id); +} + +static bool is_qchat_session(u32 session_id) +{ + return (session_id == common.voice[VOC_PATH_QCHAT_PASSIVE].session_id); +} + +static bool is_vowlan_session(u32 session_id) +{ + return (session_id == common.voice[VOC_PATH_VOWLAN_PASSIVE].session_id); +} + +static bool is_voicemmode1(u32 session_id) +{ + return session_id == + common.voice[VOC_PATH_VOICEMMODE1_PASSIVE].session_id; +} + +static bool is_voicemmode2(u32 session_id) +{ + return session_id == + common.voice[VOC_PATH_VOICEMMODE2_PASSIVE].session_id; +} + +static bool is_voc_state_active(int voc_state) +{ + if ((voc_state == VOC_RUN) || + (voc_state == VOC_CHANGE) || + (voc_state == VOC_STANDBY)) + return true; + + return false; +} + +static void voc_set_error_state(uint16_t reset_proc) +{ + struct voice_data *v = NULL; + int i; + + for (i = 0; i < MAX_VOC_SESSIONS; i++) { + v = &common.voice[i]; + if (v != NULL) { + v->voc_state = VOC_ERROR; + v->rec_info.recording = 0; + } + } +} + +static bool is_other_session_active(u32 session_id) +{ + int i; + bool ret = false; + + /* Check if there is other active session except the input one */ + for (i = 0; i < MAX_VOC_SESSIONS; i++) { + if (common.voice[i].session_id == session_id) + continue; + + if (is_voc_state_active(common.voice[i].voc_state)) { + ret = true; + break; + } + } + pr_debug("%s: ret %d\n", __func__, ret); + + return ret; +} + +static bool is_sub1_vsid(u32 session_id) +{ + bool ret; + + switch (session_id) { + case VOICE_SESSION_VSID: + case VOLTE_SESSION_VSID: + case VOWLAN_SESSION_VSID: + case VOICEMMODE1_VSID: + ret = true; + break; + default: + ret = false; + } + + return ret; +} + +static bool is_sub2_vsid(u32 session_id) +{ + bool ret; + + switch (session_id) { + case VOICE2_SESSION_VSID: + case VOICEMMODE2_VSID: + ret = true; + break; + default: + ret = false; + } + + return ret; +} + +static bool is_voice_app_id(u32 session_id) +{ + return is_sub1_vsid(session_id) || is_sub2_vsid(session_id); +} + +static void init_session_id(void) +{ + common.voice[VOC_PATH_PASSIVE].session_id = VOICE_SESSION_VSID; + common.voice[VOC_PATH_VOLTE_PASSIVE].session_id = VOLTE_SESSION_VSID; + common.voice[VOC_PATH_VOICE2_PASSIVE].session_id = VOICE2_SESSION_VSID; + common.voice[VOC_PATH_FULL].session_id = VOIP_SESSION_VSID; + common.voice[VOC_PATH_QCHAT_PASSIVE].session_id = QCHAT_SESSION_VSID; + common.voice[VOC_PATH_VOWLAN_PASSIVE].session_id = VOWLAN_SESSION_VSID; + common.voice[VOC_PATH_VOICEMMODE1_PASSIVE].session_id = + VOICEMMODE1_VSID; + common.voice[VOC_PATH_VOICEMMODE2_PASSIVE].session_id = + VOICEMMODE2_VSID; +} + +static bool is_cvd_version_queried(void) +{ + bool ret = 0; + + if (!strcmp(common.cvd_version, CVD_VERSION_DEFAULT)) + ret = false; + else + ret = true; + + return ret; +} + +static int voice_get_cvd_int_version(char *cvd_ver_string) +{ + unsigned int idx; + int cvd_int_ver = CVD_INT_VERSION_DEFAULT; + + for (idx = 0; idx < CVD_INT_VERSION_MAX; idx++) { + if (strcmp((char *)cvd_ver_string, + cvd_version_table_mapping[idx].cvd_ver) == 0) { + cvd_int_ver = + cvd_version_table_mapping[idx].cvd_ver_int; + break; + } + } + return cvd_int_ver; +} + +static int voice_apr_register(uint32_t session_id) +{ + + pr_debug("%s\n", __func__); + + mutex_lock(&common.common_lock); + + /* register callback to APR */ + if (common.apr_q6_mvm == NULL) { + pr_debug("%s: Start to register MVM callback\n", __func__); + + common.apr_q6_mvm = apr_register("ADSP", "MVM", + qdsp_mvm_callback, + 0xFFFFFFFF, &common); + + if (common.apr_q6_mvm == NULL) { + pr_err("%s: Unable to register MVM\n", __func__); + goto err; + } + } + + if (common.apr_q6_cvs == NULL) { + pr_debug("%s: Start to register CVS callback\n", __func__); + + common.apr_q6_cvs = apr_register("ADSP", "CVS", + qdsp_cvs_callback, + 0xFFFFFFFF, &common); + + if (common.apr_q6_cvs == NULL) { + pr_err("%s: Unable to register CVS\n", __func__); + goto err; + } + rtac_set_voice_handle(RTAC_CVS, common.apr_q6_cvs); + } + + if (common.apr_q6_cvp == NULL) { + pr_debug("%s: Start to register CVP callback\n", __func__); + + common.apr_q6_cvp = apr_register("ADSP", "CVP", + qdsp_cvp_callback, + 0xFFFFFFFF, &common); + + if (common.apr_q6_cvp == NULL) { + pr_err("%s: Unable to register CVP\n", __func__); + goto err; + } + rtac_set_voice_handle(RTAC_CVP, common.apr_q6_cvp); + } + + mutex_unlock(&common.common_lock); + + return 0; + +err: + if (common.apr_q6_cvs != NULL) { + apr_deregister(common.apr_q6_cvs); + common.apr_q6_cvs = NULL; + rtac_set_voice_handle(RTAC_CVS, NULL); + } + if (common.apr_q6_mvm != NULL) { + apr_deregister(common.apr_q6_mvm); + common.apr_q6_mvm = NULL; + } + + mutex_unlock(&common.common_lock); + + return -ENODEV; +} + +static int voice_send_mvm_cvd_version_cmd(struct voice_data *v) +{ + int ret; + struct apr_hdr cvd_version_get_cmd; + void *apr_mvm; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + apr_mvm = common.apr_q6_mvm; + if (!apr_mvm) { + pr_err("%s: apr_mvm is NULL.\n", __func__); + + ret = -EINVAL; + goto done; + } + + /* Send command to CVD to retrieve Version */ + cvd_version_get_cmd.hdr_field = APR_HDR_FIELD( + APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvd_version_get_cmd.pkt_size = APR_PKT_SIZE( + APR_HDR_SIZE, + sizeof(cvd_version_get_cmd) - + APR_HDR_SIZE); + cvd_version_get_cmd.src_port = + voice_get_idx_for_session(v->session_id); + cvd_version_get_cmd.dest_port = 0; + cvd_version_get_cmd.token = 0; + cvd_version_get_cmd.opcode = VSS_IVERSION_CMD_GET; + + pr_debug("%s: send CVD version get cmd, pkt size = %d\n", + __func__, cvd_version_get_cmd.pkt_size); + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_mvm, + (uint32_t *) &cvd_version_get_cmd); + if (ret < 0) { + pr_err("%s: Error sending command\n", __func__); + + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout, fall back to default\n", + __func__); + + ret = -EINVAL; + goto done; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto done; + } + ret = 0; + +done: + if (ret) { + strlcpy(common.cvd_version, CVD_VERSION_0_0, + sizeof(common.cvd_version)); + } + pr_debug("%s: CVD Version retrieved=%s\n", + __func__, common.cvd_version); + + return ret; +} + +static int voice_send_dual_control_cmd(struct voice_data *v) +{ + int ret = 0; + struct mvm_modem_dual_control_session_cmd mvm_voice_ctl_cmd; + void *apr_mvm; + u16 mvm_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_mvm = common.apr_q6_mvm; + if (!apr_mvm) { + pr_err("%s: apr_mvm is NULL.\n", __func__); + return -EINVAL; + } + pr_debug("%s: Send Dual Control command to MVM\n", __func__); + if (!is_voip_session(v->session_id)) { + mvm_handle = voice_get_mvm_handle(v); + mvm_voice_ctl_cmd.hdr.hdr_field = APR_HDR_FIELD( + APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mvm_voice_ctl_cmd.hdr.pkt_size = APR_PKT_SIZE( + APR_HDR_SIZE, + sizeof(mvm_voice_ctl_cmd) - + APR_HDR_SIZE); + pr_debug("%s: send mvm Voice Ctl pkt size = %d\n", + __func__, mvm_voice_ctl_cmd.hdr.pkt_size); + mvm_voice_ctl_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + mvm_voice_ctl_cmd.hdr.dest_port = mvm_handle; + mvm_voice_ctl_cmd.hdr.token = 0; + mvm_voice_ctl_cmd.hdr.opcode = + VSS_IMVM_CMD_SET_POLICY_DUAL_CONTROL; + mvm_voice_ctl_cmd.voice_ctl.enable_flag = true; + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_voice_ctl_cmd); + if (ret < 0) { + pr_err("%s: Error sending MVM Voice CTL CMD\n", + __func__); + ret = -EINVAL; + goto fail; + } + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + } + ret = 0; +fail: + return ret; +} + + +static int voice_create_mvm_cvs_session(struct voice_data *v) +{ + int ret = 0; + struct mvm_create_ctl_session_cmd mvm_session_cmd; + struct cvs_create_passive_ctl_session_cmd cvs_session_cmd; + struct cvs_create_full_ctl_session_cmd cvs_full_ctl_cmd; + struct mvm_attach_stream_cmd attach_stream_cmd; + void *apr_mvm, *apr_cvs, *apr_cvp; + u16 mvm_handle, cvs_handle, cvp_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_mvm = common.apr_q6_mvm; + apr_cvs = common.apr_q6_cvs; + apr_cvp = common.apr_q6_cvp; + + if (!apr_mvm || !apr_cvs || !apr_cvp) { + pr_err("%s: apr_mvm or apr_cvs or apr_cvp is NULL\n", __func__); + return -EINVAL; + } + mvm_handle = voice_get_mvm_handle(v); + cvs_handle = voice_get_cvs_handle(v); + cvp_handle = voice_get_cvp_handle(v); + + pr_debug("%s: mvm_hdl=%d, cvs_hdl=%d\n", __func__, + mvm_handle, cvs_handle); + /* send cmd to create mvm session and wait for response */ + + if (!mvm_handle) { + memset(mvm_session_cmd.mvm_session.name, 0, + sizeof(mvm_session_cmd.mvm_session.name)); + if (!is_voip_session(v->session_id)) { + mvm_session_cmd.hdr.hdr_field = APR_HDR_FIELD( + APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mvm_session_cmd.hdr.pkt_size = APR_PKT_SIZE( + APR_HDR_SIZE, + sizeof(mvm_session_cmd) - + APR_HDR_SIZE); + pr_debug("%s: send mvm create session pkt size = %d\n", + __func__, mvm_session_cmd.hdr.pkt_size); + mvm_session_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + mvm_session_cmd.hdr.dest_port = 0; + mvm_session_cmd.hdr.token = 0; + mvm_session_cmd.hdr.opcode = + VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION; + if (is_volte_session(v->session_id)) { + strlcpy(mvm_session_cmd.mvm_session.name, + "default volte voice", + strlen("default volte voice")+1); + } else if (is_voice2_session(v->session_id)) { + strlcpy(mvm_session_cmd.mvm_session.name, + VOICE2_SESSION_VSID_STR, + strlen(VOICE2_SESSION_VSID_STR)+1); + } else if (is_qchat_session(v->session_id)) { + strlcpy(mvm_session_cmd.mvm_session.name, + QCHAT_SESSION_VSID_STR, + strlen(QCHAT_SESSION_VSID_STR)+1); + } else if (is_vowlan_session(v->session_id)) { + strlcpy(mvm_session_cmd.mvm_session.name, + VOWLAN_SESSION_VSID_STR, + strlen(VOWLAN_SESSION_VSID_STR)+1); + } else if (is_voicemmode1(v->session_id)) { + strlcpy(mvm_session_cmd.mvm_session.name, + VOICEMMODE1_VSID_STR, + strlen(VOICEMMODE1_VSID_STR) + 1); + } else if (is_voicemmode2(v->session_id)) { + strlcpy(mvm_session_cmd.mvm_session.name, + VOICEMMODE2_VSID_STR, + strlen(VOICEMMODE2_VSID_STR) + 1); + } else { + strlcpy(mvm_session_cmd.mvm_session.name, + "default modem voice", + strlen("default modem voice")+1); + } + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_mvm, + (uint32_t *) &mvm_session_cmd); + if (ret < 0) { + pr_err("%s: Error sending MVM_CONTROL_SESSION\n", + __func__); + goto fail; + } + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + } else { + pr_debug("%s: creating MVM full ctrl\n", __func__); + mvm_session_cmd.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + mvm_session_cmd.hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mvm_session_cmd) - + APR_HDR_SIZE); + mvm_session_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + mvm_session_cmd.hdr.dest_port = 0; + mvm_session_cmd.hdr.token = 0; + mvm_session_cmd.hdr.opcode = + VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION; + strlcpy(mvm_session_cmd.mvm_session.name, + "default voip", + strlen("default voip")+1); + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_mvm, + (uint32_t *) &mvm_session_cmd); + if (ret < 0) { + pr_err("Fail in sending MVM_CONTROL_SESSION\n"); + goto fail; + } + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + } + /* Get the created MVM handle. */ + mvm_handle = voice_get_mvm_handle(v); + } + /* send cmd to create cvs session */ + if (!cvs_handle) { + memset(cvs_session_cmd.cvs_session.name, 0, + sizeof(cvs_session_cmd.cvs_session.name)); + if (!is_voip_session(v->session_id)) { + pr_debug("%s: creating CVS passive session\n", + __func__); + + cvs_session_cmd.hdr.hdr_field = APR_HDR_FIELD( + APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvs_session_cmd.hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvs_session_cmd) - + APR_HDR_SIZE); + cvs_session_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvs_session_cmd.hdr.dest_port = 0; + cvs_session_cmd.hdr.token = 0; + cvs_session_cmd.hdr.opcode = + VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION; + if (is_volte_session(v->session_id)) { + strlcpy(cvs_session_cmd.cvs_session.name, + "default volte voice", + strlen("default volte voice")+1); + } else if (is_voice2_session(v->session_id)) { + strlcpy(cvs_session_cmd.cvs_session.name, + VOICE2_SESSION_VSID_STR, + strlen(VOICE2_SESSION_VSID_STR)+1); + } else if (is_qchat_session(v->session_id)) { + strlcpy(cvs_session_cmd.cvs_session.name, + QCHAT_SESSION_VSID_STR, + strlen(QCHAT_SESSION_VSID_STR)+1); + } else if (is_vowlan_session(v->session_id)) { + strlcpy(cvs_session_cmd.cvs_session.name, + VOWLAN_SESSION_VSID_STR, + strlen(VOWLAN_SESSION_VSID_STR)+1); + } else if (is_voicemmode1(v->session_id)) { + strlcpy(cvs_session_cmd.cvs_session.name, + VOICEMMODE1_VSID_STR, + strlen(VOICEMMODE1_VSID_STR) + 1); + } else if (is_voicemmode2(v->session_id)) { + strlcpy(cvs_session_cmd.cvs_session.name, + VOICEMMODE2_VSID_STR, + strlen(VOICEMMODE2_VSID_STR) + 1); + } else { + strlcpy(cvs_session_cmd.cvs_session.name, + "default modem voice", + strlen("default modem voice")+1); + } + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_cvs, + (uint32_t *) &cvs_session_cmd); + if (ret < 0) { + pr_err("Fail in sending STREAM_CONTROL_SESSION\n"); + goto fail; + } + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + /* Get the created CVS handle. */ + cvs_handle = voice_get_cvs_handle(v); + + } else { + pr_debug("%s: creating CVS full session\n", __func__); + + cvs_full_ctl_cmd.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + + cvs_full_ctl_cmd.hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvs_full_ctl_cmd) - + APR_HDR_SIZE); + + cvs_full_ctl_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvs_full_ctl_cmd.hdr.dest_port = 0; + cvs_full_ctl_cmd.hdr.token = 0; + cvs_full_ctl_cmd.hdr.opcode = + VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION; + cvs_full_ctl_cmd.cvs_session.direction = 2; + cvs_full_ctl_cmd.cvs_session.enc_media_type = + common.mvs_info.media_type; + cvs_full_ctl_cmd.cvs_session.dec_media_type = + common.mvs_info.media_type; + cvs_full_ctl_cmd.cvs_session.network_id = + common.mvs_info.network_type; + strlcpy(cvs_full_ctl_cmd.cvs_session.name, + "default q6 voice", + strlen("default q6 voice")+1); + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_cvs, + (uint32_t *) &cvs_full_ctl_cmd); + + if (ret < 0) { + pr_err("%s: Err %d sending CREATE_FULL_CTRL\n", + __func__, ret); + goto fail; + } + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + /* Get the created CVS handle. */ + cvs_handle = voice_get_cvs_handle(v); + + /* Attach MVM to CVS. */ + pr_debug("%s: Attach MVM to stream\n", __func__); + + attach_stream_cmd.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + attach_stream_cmd.hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(attach_stream_cmd) - + APR_HDR_SIZE); + attach_stream_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + attach_stream_cmd.hdr.dest_port = mvm_handle; + attach_stream_cmd.hdr.token = 0; + attach_stream_cmd.hdr.opcode = + VSS_IMVM_CMD_ATTACH_STREAM; + attach_stream_cmd.attach_stream.handle = cvs_handle; + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_mvm, + (uint32_t *) &attach_stream_cmd); + if (ret < 0) { + pr_err("%s: Error %d sending ATTACH_STREAM\n", + __func__, ret); + goto fail; + } + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + } + } + return 0; + +fail: + return ret; +} + +static int voice_unmap_cal_block(struct voice_data *v, int cal_index) +{ + int result = 0; + struct cal_block_data *cal_block; + + if (common.cal_data[cal_index] == NULL) { + pr_err("%s: Cal type is NULL, index %d!\n", + __func__, cal_index); + + goto done; + } + + mutex_lock(&common.cal_data[cal_index]->lock); + cal_block = cal_utils_get_only_cal_block( + common.cal_data[cal_index]); + if (cal_block == NULL) { + pr_err("%s: Cal block is NULL, index %d!\n", + __func__, cal_index); + + result = -EINVAL; + goto unlock; + } + + if (cal_block->map_data.q6map_handle == 0) { + pr_debug("%s: Q6 handle is not set!\n", __func__); + + result = -EINVAL; + goto unlock; + } + + mutex_lock(&common.common_lock); + result = voice_send_mvm_unmap_memory_physical_cmd( + v, cal_block->map_data.q6map_handle); + if (result) + pr_err("%s: Voice_send_mvm_unmap_memory_physical_cmd failed for session 0x%x, err %d!\n", + __func__, v->session_id, result); + + cal_block->map_data.q6map_handle = 0; + mutex_unlock(&common.common_lock); +unlock: + mutex_unlock(&common.cal_data[cal_index]->lock); +done: + return result; +} + +static int voice_destroy_mvm_cvs_session(struct voice_data *v) +{ + int ret = 0; + struct mvm_detach_stream_cmd detach_stream; + struct apr_hdr mvm_destroy; + struct apr_hdr cvs_destroy; + void *apr_mvm, *apr_cvs; + u16 mvm_handle, cvs_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_mvm = common.apr_q6_mvm; + apr_cvs = common.apr_q6_cvs; + + if (!apr_mvm || !apr_cvs) { + pr_err("%s: apr_mvm or apr_cvs is NULL\n", __func__); + return -EINVAL; + } + mvm_handle = voice_get_mvm_handle(v); + cvs_handle = voice_get_cvs_handle(v); + + /* MVM, CVS sessions are destroyed only for Full control sessions. */ + if (is_voip_session(v->session_id)) { + pr_debug("%s: MVM detach stream, VOC_STATE: %d\n", __func__, + v->voc_state); + + /* Detach voice stream. */ + detach_stream.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + detach_stream.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(detach_stream) - APR_HDR_SIZE); + detach_stream.hdr.src_port = + voice_get_idx_for_session(v->session_id); + detach_stream.hdr.dest_port = mvm_handle; + detach_stream.hdr.token = 0; + detach_stream.hdr.opcode = VSS_IMVM_CMD_DETACH_STREAM; + detach_stream.detach_stream.handle = cvs_handle; + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_mvm, (uint32_t *) &detach_stream); + if (ret < 0) { + pr_err("%s: Error %d sending DETACH_STREAM\n", + __func__, ret); + + goto fail; + } + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait event timeout\n", __func__); + + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + + /* Unmap memory */ + if (v->shmem_info.mem_handle != 0) { + ret = voice_send_mvm_unmap_memory_physical_cmd(v, + v->shmem_info.mem_handle); + if (ret < 0) { + pr_err("%s Memory_unmap for voip failed %d\n", + __func__, ret); + + goto fail; + } + v->shmem_info.mem_handle = 0; + } + } + + /* Unmap Source Tracking shared memory if mapped earlier */ + voice_unmap_and_free_source_tracking_shared_memory(v); + + if (is_voip_session(v->session_id) || + is_qchat_session(v->session_id) || + is_volte_session(v->session_id) || + is_vowlan_session(v->session_id) || + v->voc_state == VOC_ERROR || common.is_destroy_cvd) { + /* Destroy CVS. */ + pr_debug("%s: CVS destroy session\n", __func__); + + cvs_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvs_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvs_destroy) - APR_HDR_SIZE); + cvs_destroy.src_port = + voice_get_idx_for_session(v->session_id); + cvs_destroy.dest_port = cvs_handle; + cvs_destroy.token = 0; + cvs_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION; + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_destroy); + if (ret < 0) { + pr_err("%s: Error %d sending CVS DESTROY\n", + __func__, ret); + + goto fail; + } + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait event timeout\n", __func__); + + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + cvs_handle = 0; + voice_set_cvs_handle(v, cvs_handle); + + /* Unmap physical memory for all calibration buffers */ + if (!is_other_session_active(v->session_id)) { + if (voice_unmap_cal_block(v, CVP_VOCPROC_CAL)) + pr_err("%s: Unmap VOCPROC cal failed\n", + __func__); + if (voice_unmap_cal_block(v, CVP_VOCVOL_CAL)) + pr_err("%s: Unmap VOCVOL cal failed\n", + __func__); + if (voice_unmap_cal_block(v, CVP_VOCDEV_CFG_CAL)) + pr_err("%s: Unmap VOCDEV_CFG cal failed\n", + __func__); + if (voice_unmap_cal_block(v, CVS_VOCSTRM_CAL)) + pr_err("%s: Unmap VOCSTRM cal failed\n", + __func__); + } + + /* Destroy MVM. */ + pr_debug("%s: MVM destroy session\n", __func__); + + mvm_destroy.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mvm_destroy.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mvm_destroy) - APR_HDR_SIZE); + mvm_destroy.src_port = + voice_get_idx_for_session(v->session_id); + mvm_destroy.dest_port = mvm_handle; + mvm_destroy.token = 0; + mvm_destroy.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION; + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_destroy); + if (ret < 0) { + pr_err("%s: Error %d sending MVM DESTROY\n", + __func__, ret); + + goto fail; + } + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + mvm_handle = 0; + voice_set_mvm_handle(v, mvm_handle); + } + return 0; +fail: + return ret; +} + +static int voice_send_tty_mode_cmd(struct voice_data *v) +{ + int ret = 0; + struct mvm_set_tty_mode_cmd mvm_tty_mode_cmd; + void *apr_mvm; + u16 mvm_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_mvm = common.apr_q6_mvm; + + if (!apr_mvm) { + pr_err("%s: apr_mvm is NULL.\n", __func__); + return -EINVAL; + } + mvm_handle = voice_get_mvm_handle(v); + + /* send tty mode cmd to mvm */ + mvm_tty_mode_cmd.hdr.hdr_field = APR_HDR_FIELD( + APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mvm_tty_mode_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mvm_tty_mode_cmd) - + APR_HDR_SIZE); + pr_debug("%s: pkt size = %d\n", + __func__, mvm_tty_mode_cmd.hdr.pkt_size); + mvm_tty_mode_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + mvm_tty_mode_cmd.hdr.dest_port = mvm_handle; + mvm_tty_mode_cmd.hdr.token = 0; + mvm_tty_mode_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_TTY_MODE; + mvm_tty_mode_cmd.tty_mode.mode = v->tty_mode; + pr_debug("tty mode =%d\n", mvm_tty_mode_cmd.tty_mode.mode); + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_tty_mode_cmd); + if (ret < 0) { + pr_err("%s: Error %d sending SET_TTY_MODE\n", + __func__, ret); + goto fail; + } + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + return 0; +fail: + return ret; +} + +static int voice_send_set_pp_enable_cmd(struct voice_data *v, + uint32_t module_id, int enable) +{ + struct cvs_set_pp_enable_cmd cvs_set_pp_cmd; + int ret = 0; + void *apr_cvs; + u16 cvs_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_cvs = common.apr_q6_cvs; + + if (!apr_cvs) { + pr_err("%s: apr_cvs is NULL.\n", __func__); + return -EINVAL; + } + cvs_handle = voice_get_cvs_handle(v); + + cvs_set_pp_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvs_set_pp_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvs_set_pp_cmd) - + APR_HDR_SIZE); + cvs_set_pp_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id); + cvs_set_pp_cmd.hdr.dest_port = cvs_handle; + cvs_set_pp_cmd.hdr.token = 0; + cvs_set_pp_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_UI_PROPERTY; + + cvs_set_pp_cmd.vss_set_pp.module_id = module_id; + cvs_set_pp_cmd.vss_set_pp.param_id = VOICE_PARAM_MOD_ENABLE; + cvs_set_pp_cmd.vss_set_pp.param_size = MOD_ENABLE_PARAM_LEN; + cvs_set_pp_cmd.vss_set_pp.reserved = 0; + cvs_set_pp_cmd.vss_set_pp.enable = enable; + cvs_set_pp_cmd.vss_set_pp.reserved_field = 0; + pr_debug("voice_send_set_pp_enable_cmd, module_id=%d, enable=%d\n", + module_id, enable); + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_pp_cmd); + if (ret < 0) { + pr_err("Fail: sending cvs set pp enable,\n"); + goto fail; + } + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + return 0; +fail: + return ret; +} + +static int voice_send_hd_cmd(struct voice_data *v, int enable) +{ + struct mvm_set_hd_enable_cmd mvm_set_hd_cmd; + int ret = 0; + void *apr_mvm; + u16 mvm_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + apr_mvm = common.apr_q6_mvm; + if (!apr_mvm) { + pr_err("%s: apr_mvm is NULL.\n", __func__); + + ret = -EINVAL; + goto done; + } + + mvm_handle = voice_get_mvm_handle(v); + if (!mvm_handle) { + pr_err("%s: mvm_handle is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + mvm_set_hd_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mvm_set_hd_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mvm_set_hd_cmd) - + APR_HDR_SIZE); + mvm_set_hd_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id); + mvm_set_hd_cmd.hdr.dest_port = mvm_handle; + mvm_set_hd_cmd.hdr.token = 0; + + if (enable) + mvm_set_hd_cmd.hdr.opcode = VSS_IHDVOICE_CMD_ENABLE; + else + mvm_set_hd_cmd.hdr.opcode = VSS_IHDVOICE_CMD_DISABLE; + + pr_debug("%s: enable=%d\n", __func__, enable); + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_hd_cmd); + if (ret < 0) { + pr_err("%s: Failed to sending mvm set HD Voice enable %d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + + ret = -EINVAL; + goto done; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto done; + } + +done: + return ret; +} + +static int voice_set_dtx(struct voice_data *v) +{ + int ret = 0; + void *apr_cvs; + u16 cvs_handle; + struct cvs_set_enc_dtx_mode_cmd cvs_set_dtx; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_cvs = common.apr_q6_cvs; + + if (!apr_cvs) { + pr_err("%s: apr_cvs is NULL.\n", __func__); + return -EINVAL; + } + + cvs_handle = voice_get_cvs_handle(v); + + /* Set DTX */ + cvs_set_dtx.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvs_set_dtx.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvs_set_dtx) - APR_HDR_SIZE); + cvs_set_dtx.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvs_set_dtx.hdr.dest_port = cvs_handle; + cvs_set_dtx.hdr.token = 0; + cvs_set_dtx.hdr.opcode = VSS_ISTREAM_CMD_SET_ENC_DTX_MODE; + cvs_set_dtx.dtx_mode.enable = common.mvs_info.dtx_mode; + + pr_debug("%s: Setting DTX %d\n", __func__, common.mvs_info.dtx_mode); + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_dtx); + if (ret < 0) { + pr_err("%s: Error %d sending SET_DTX\n", __func__, ret); + return -EINVAL; + } + + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + return -EINVAL; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + return ret; + } + + return 0; +} + +static int voice_send_mvm_media_type_cmd(struct voice_data *v) +{ + struct vss_imvm_cmd_set_cal_media_type_t mvm_set_cal_media_type; + int ret = 0; + void *apr_mvm; + u16 mvm_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_mvm = common.apr_q6_mvm; + + if (!apr_mvm) { + pr_err("%s: apr_mvm is NULL.\n", __func__); + return -EINVAL; + } + mvm_handle = voice_get_mvm_handle(v); + + mvm_set_cal_media_type.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mvm_set_cal_media_type.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mvm_set_cal_media_type) - + APR_HDR_SIZE); + mvm_set_cal_media_type.hdr.src_port = + voice_get_idx_for_session(v->session_id); + mvm_set_cal_media_type.hdr.dest_port = mvm_handle; + mvm_set_cal_media_type.hdr.token = 0; + mvm_set_cal_media_type.hdr.opcode = VSS_IMVM_CMD_SET_CAL_MEDIA_TYPE; + mvm_set_cal_media_type.media_id = common.mvs_info.media_type; + pr_debug("%s: setting media_id as %x\n", + __func__, mvm_set_cal_media_type.media_id); + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_cal_media_type); + if (ret < 0) { + pr_err("%s: Error %d sending media type\n", __func__, ret); + goto fail; + } + + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout %d\n", __func__, ret); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + return 0; +fail: + return ret; +} + +static int voice_send_dtmf_rx_detection_cmd(struct voice_data *v, + uint32_t enable) +{ + int ret = 0; + void *apr_cvs; + u16 cvs_handle; + struct cvs_set_rx_dtmf_detection_cmd cvs_dtmf_rx_detection; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_cvs = common.apr_q6_cvs; + + if (!apr_cvs) { + pr_err("%s: apr_cvs is NULL.\n", __func__); + return -EINVAL; + } + + cvs_handle = voice_get_cvs_handle(v); + + /* Set SET_DTMF_RX_DETECTION */ + cvs_dtmf_rx_detection.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvs_dtmf_rx_detection.hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvs_dtmf_rx_detection) - APR_HDR_SIZE); + cvs_dtmf_rx_detection.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvs_dtmf_rx_detection.hdr.dest_port = cvs_handle; + cvs_dtmf_rx_detection.hdr.token = 0; + cvs_dtmf_rx_detection.hdr.opcode = + VSS_ISTREAM_CMD_SET_RX_DTMF_DETECTION; + cvs_dtmf_rx_detection.cvs_dtmf_det.enable = enable; + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_dtmf_rx_detection); + if (ret < 0) { + pr_err("%s: Error %d sending SET_DTMF_RX_DETECTION\n", + __func__, + ret); + return -EINVAL; + } + + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + return -EINVAL; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + return ret; + } + + return ret; +} + +void voc_disable_dtmf_det_on_active_sessions(void) +{ + struct voice_data *v = NULL; + int i; + + for (i = 0; i < MAX_VOC_SESSIONS; i++) { + v = &common.voice[i]; + if ((v->dtmf_rx_detect_en) && + is_voc_state_active(v->voc_state)) { + + pr_debug("disable dtmf det on ses_id=%d\n", + v->session_id); + voice_send_dtmf_rx_detection_cmd(v, 0); + } + } +} + +int voc_enable_dtmf_rx_detection(uint32_t session_id, uint32_t enable) +{ + struct voice_data *v = voice_get_session(session_id); + int ret = 0; + + if (v == NULL) { + pr_err("%s: invalid session_id 0x%x\n", __func__, session_id); + return -EINVAL; + } + + mutex_lock(&v->lock); + v->dtmf_rx_detect_en = enable; + + if (is_voc_state_active(v->voc_state)) + ret = voice_send_dtmf_rx_detection_cmd(v, + v->dtmf_rx_detect_en); + + mutex_unlock(&v->lock); + + return ret; +} + +void voc_set_destroy_cvd_flag(bool is_destroy_cvd) +{ + pr_debug("%s: %d\n", __func__, is_destroy_cvd); + common.is_destroy_cvd = is_destroy_cvd; +} + +int voc_alloc_cal_shared_memory(void) +{ + int rc = 0; + + mutex_lock(&common.common_lock); + if (is_cal_memory_allocated()) { + pr_debug("%s: Calibration shared buffer already allocated", + __func__); + } else { + /* Allocate memory for calibration memory map table. */ + rc = voice_alloc_cal_mem_map_table(); + if ((rc < 0) && (rc != -EPROBE_DEFER)) { + pr_err("%s: Failed to allocate cal memory, err=%d", + __func__, rc); + } + } + mutex_unlock(&common.common_lock); + + return rc; +} + +int voc_alloc_voip_shared_memory(void) +{ + int rc = 0; + + /* Allocate shared memory for OOB Voip */ + rc = voice_alloc_oob_shared_mem(); + if (rc < 0) { + pr_err("%s: Failed to alloc shared memory for OOB rc:%d\n", + __func__, rc); + } else { + /* Allocate mem map table for OOB */ + rc = voice_alloc_oob_mem_table(); + if (rc < 0) { + pr_err("%s: Failed to alloc mem map talbe rc:%d\n", + __func__, rc); + + voice_free_oob_shared_mem(); + } + } + + return rc; +} + +static int is_cal_memory_allocated(void) +{ + bool ret; + + if (common.cal_mem_map_table.client != NULL && + common.cal_mem_map_table.handle != NULL) + ret = true; + else + ret = false; + + return ret; +} + + +static int free_cal_map_table(void) +{ + int ret = 0; + + if ((common.cal_mem_map_table.client == NULL) || + (common.cal_mem_map_table.handle == NULL)) + goto done; + + ret = msm_audio_ion_free(common.cal_mem_map_table.client, + common.cal_mem_map_table.handle); + if (ret < 0) + pr_err("%s: msm_audio_ion_free failed:\n", __func__); + +done: + common.cal_mem_map_table.client = NULL; + common.cal_mem_map_table.handle = NULL; + return ret; +} + +static int is_rtac_memory_allocated(void) +{ + bool ret; + + if (common.rtac_mem_map_table.client != NULL && + common.rtac_mem_map_table.handle != NULL) + ret = true; + else + ret = false; + + return ret; +} + +static int free_rtac_map_table(void) +{ + int ret = 0; + + if ((common.rtac_mem_map_table.client == NULL) || + (common.rtac_mem_map_table.handle == NULL)) + goto done; + + ret = msm_audio_ion_free(common.rtac_mem_map_table.client, + common.rtac_mem_map_table.handle); + if (ret < 0) + pr_err("%s: msm_audio_ion_free failed:\n", __func__); + +done: + common.rtac_mem_map_table.client = NULL; + common.rtac_mem_map_table.handle = NULL; + return ret; +} + + +static int is_voip_memory_allocated(void) +{ + bool ret; + struct voice_data *v = voice_get_session( + common.voice[VOC_PATH_FULL].session_id); + + if (v == NULL) { + pr_err("%s: v is NULL, session_id:%d\n", __func__, + common.voice[VOC_PATH_FULL].session_id); + + ret = false; + goto done; + } + + mutex_lock(&common.common_lock); + if (v->shmem_info.sh_buf.client != NULL && + v->shmem_info.sh_buf.handle != NULL) + ret = true; + else + ret = false; + mutex_unlock(&common.common_lock); + +done: + return ret; +} + +static int voice_config_cvs_vocoder_amr_rate(struct voice_data *v) +{ + int ret = 0; + void *apr_cvs; + u16 cvs_handle; + struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + apr_cvs = common.apr_q6_cvs; + + if (!apr_cvs) { + pr_err("%s: apr_cvs is NULL.\n", __func__); + + ret = -EINVAL; + goto done; + } + + cvs_handle = voice_get_cvs_handle(v); + + pr_debug("%s: Setting AMR rate. Media Type: %d\n", __func__, + common.mvs_info.media_type); + + cvs_set_amr_rate.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvs_set_amr_rate) - APR_HDR_SIZE); + cvs_set_amr_rate.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvs_set_amr_rate.hdr.dest_port = cvs_handle; + cvs_set_amr_rate.hdr.token = 0; + + if (common.mvs_info.media_type == VSS_MEDIA_ID_AMR_NB_MODEM) + cvs_set_amr_rate.hdr.opcode = + VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE; + else if (common.mvs_info.media_type == VSS_MEDIA_ID_AMR_WB_MODEM) + cvs_set_amr_rate.hdr.opcode = + VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE; + + cvs_set_amr_rate.amr_rate.mode = common.mvs_info.rate; + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate); + if (ret < 0) { + pr_err("%s: Error %d sending SET_AMR_RATE\n", + __func__, ret); + + goto done; + } + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + + ret = -EINVAL; + goto done; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto done; + } + + return 0; +done: + return ret; +} + +static int voice_config_cvs_vocoder(struct voice_data *v) +{ + int ret = 0; + void *apr_cvs; + u16 cvs_handle; + /* Set media type. */ + struct cvs_set_media_type_cmd cvs_set_media_cmd; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_cvs = common.apr_q6_cvs; + + if (!apr_cvs) { + pr_err("%s: apr_cvs is NULL.\n", __func__); + return -EINVAL; + } + + cvs_handle = voice_get_cvs_handle(v); + + cvs_set_media_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvs_set_media_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvs_set_media_cmd) - + APR_HDR_SIZE); + cvs_set_media_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvs_set_media_cmd.hdr.dest_port = cvs_handle; + cvs_set_media_cmd.hdr.token = 0; + cvs_set_media_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MEDIA_TYPE; + cvs_set_media_cmd.media_type.tx_media_id = common.mvs_info.media_type; + cvs_set_media_cmd.media_type.rx_media_id = common.mvs_info.media_type; + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_media_cmd); + if (ret < 0) { + pr_err("%s: Error %d sending SET_MEDIA_TYPE\n", + __func__, ret); + + goto fail; + } + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + /* Set encoder properties. */ + switch (common.mvs_info.media_type) { + case VSS_MEDIA_ID_EVRC_MODEM: + case VSS_MEDIA_ID_4GV_NB_MODEM: + case VSS_MEDIA_ID_4GV_WB_MODEM: + case VSS_MEDIA_ID_4GV_NW_MODEM: { + struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate; + + pr_debug("Setting EVRC min-max rate\n"); + + cvs_set_cdma_rate.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvs_set_cdma_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvs_set_cdma_rate) - APR_HDR_SIZE); + cvs_set_cdma_rate.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvs_set_cdma_rate.hdr.dest_port = cvs_handle; + cvs_set_cdma_rate.hdr.token = 0; + cvs_set_cdma_rate.hdr.opcode = + VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE; + cvs_set_cdma_rate.cdma_rate.min_rate = + common.mvs_info.evrc_min_rate; + cvs_set_cdma_rate.cdma_rate.max_rate = + common.mvs_info.evrc_max_rate; + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate); + if (ret < 0) { + pr_err("%s: Error %d sending SET_EVRC_MINMAX_RATE\n", + __func__, ret); + goto fail; + } + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + + if (common.mvs_info.media_type != VSS_MEDIA_ID_EVRC_MODEM) { + ret = voice_set_dtx(v); + if (ret < 0) + goto fail; + } + + break; + } + case VSS_MEDIA_ID_AMR_NB_MODEM: + case VSS_MEDIA_ID_AMR_WB_MODEM: { + ret = voice_config_cvs_vocoder_amr_rate(v); + if (ret) { + pr_err("%s: Failed to update vocoder rate. %d\n", + __func__, ret); + + goto fail; + } + + ret = voice_set_dtx(v); + if (ret < 0) + goto fail; + + break; + } + case VSS_MEDIA_ID_G729: + case VSS_MEDIA_ID_G711_ALAW: + case VSS_MEDIA_ID_G711_MULAW: { + ret = voice_set_dtx(v); + + break; + } + default: + /* Do nothing. */ + break; + } + return 0; + +fail: + return ret; +} + +int voc_update_amr_vocoder_rate(uint32_t session_id) +{ + int ret = 0; + struct voice_data *v; + + pr_debug("%s: session_id:%d", __func__, session_id); + + v = voice_get_session(session_id); + + if (v == NULL) { + pr_err("%s: v is NULL, session_id:%d\n", __func__, + session_id); + + ret = -EINVAL; + goto done; + } + + mutex_lock(&v->lock); + ret = voice_config_cvs_vocoder_amr_rate(v); + mutex_unlock(&v->lock); + +done: + return ret; +} + +static int voice_send_start_voice_cmd(struct voice_data *v) +{ + struct apr_hdr mvm_start_voice_cmd; + int ret = 0; + void *apr_mvm; + u16 mvm_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_mvm = common.apr_q6_mvm; + + if (!apr_mvm) { + pr_err("%s: apr_mvm is NULL.\n", __func__); + return -EINVAL; + } + mvm_handle = voice_get_mvm_handle(v); + + mvm_start_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mvm_start_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mvm_start_voice_cmd) - APR_HDR_SIZE); + pr_debug("send mvm_start_voice_cmd pkt size = %d\n", + mvm_start_voice_cmd.pkt_size); + mvm_start_voice_cmd.src_port = + voice_get_idx_for_session(v->session_id); + mvm_start_voice_cmd.dest_port = mvm_handle; + mvm_start_voice_cmd.token = 0; + mvm_start_voice_cmd.opcode = VSS_IMVM_CMD_START_VOICE; + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_start_voice_cmd); + if (ret < 0) { + pr_err("Fail in sending VSS_IMVM_CMD_START_VOICE\n"); + goto fail; + } + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + return 0; +fail: + return ret; +} + +static void voc_get_tx_rx_topology(struct voice_data *v, + uint32_t *tx_topology_id, + uint32_t *rx_topology_id) +{ + uint32_t tx_id = 0; + uint32_t rx_id = 0; + + if (v->lch_mode == VOICE_LCH_START || v->disable_topology) { + pr_debug("%s: Setting TX and RX topology to NONE for LCH\n", + __func__); + + tx_id = VSS_IVOCPROC_TOPOLOGY_ID_NONE; + rx_id = VSS_IVOCPROC_TOPOLOGY_ID_NONE; + } else { + tx_id = voice_get_topology(CVP_VOC_TX_TOPOLOGY_CAL); + rx_id = voice_get_topology(CVP_VOC_RX_TOPOLOGY_CAL); + } + + *tx_topology_id = tx_id; + *rx_topology_id = rx_id; +} + +static int voice_send_set_device_cmd(struct voice_data *v) +{ + struct cvp_set_device_cmd cvp_setdev_cmd; + int ret = 0; + void *apr_cvp; + u16 cvp_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_cvp = common.apr_q6_cvp; + + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL.\n", __func__); + return -EINVAL; + } + cvp_handle = voice_get_cvp_handle(v); + + /* set device and wait for response */ + cvp_setdev_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_setdev_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_setdev_cmd) - APR_HDR_SIZE); + pr_debug(" send create cvp setdev, pkt size = %d\n", + cvp_setdev_cmd.hdr.pkt_size); + cvp_setdev_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_setdev_cmd.hdr.dest_port = cvp_handle; + cvp_setdev_cmd.hdr.token = 0; + + if (voice_get_cvd_int_version(common.cvd_version) >= + CVD_INT_VERSION_2_2) + cvp_setdev_cmd.hdr.opcode = + VSS_IVOCPROC_CMD_SET_DEVICE_V3; + else + cvp_setdev_cmd.hdr.opcode = + VSS_IVOCPROC_CMD_SET_DEVICE_V2; + + voc_get_tx_rx_topology(v, + &cvp_setdev_cmd.cvp_set_device_v2.tx_topology_id, + &cvp_setdev_cmd.cvp_set_device_v2.rx_topology_id); + + cvp_setdev_cmd.cvp_set_device_v2.tx_port_id = v->dev_tx.port_id; + cvp_setdev_cmd.cvp_set_device_v2.rx_port_id = v->dev_rx.port_id; + + if (common.ec_ref_ext) { + cvp_setdev_cmd.cvp_set_device_v2.vocproc_mode = + VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING; + cvp_setdev_cmd.cvp_set_device_v2.ec_ref_port_id = + common.ec_media_fmt_info.port_id; + } else { + cvp_setdev_cmd.cvp_set_device_v2.vocproc_mode = + VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING; + cvp_setdev_cmd.cvp_set_device_v2.ec_ref_port_id = + VSS_IVOCPROC_PORT_ID_NONE; + } + pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n", + cvp_setdev_cmd.cvp_set_device_v2.tx_topology_id, + cvp_setdev_cmd.cvp_set_device_v2.tx_port_id, + cvp_setdev_cmd.cvp_set_device_v2.rx_port_id); + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_setdev_cmd); + if (ret < 0) { + pr_err("Fail in sending VSS_IVOCPROC_CMD_SET_DEVICE\n"); + goto fail; + } + + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + + return 0; +fail: + return ret; +} + +static int voice_send_stop_voice_cmd(struct voice_data *v) +{ + struct apr_hdr mvm_stop_voice_cmd; + int ret = 0; + void *apr_mvm; + u16 mvm_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_mvm = common.apr_q6_mvm; + + if (!apr_mvm) { + pr_err("%s: apr_mvm is NULL.\n", __func__); + return -EINVAL; + } + mvm_handle = voice_get_mvm_handle(v); + + mvm_stop_voice_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mvm_stop_voice_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mvm_stop_voice_cmd) - APR_HDR_SIZE); + pr_debug("send mvm_stop_voice_cmd pkt size = %d\n", + mvm_stop_voice_cmd.pkt_size); + mvm_stop_voice_cmd.src_port = + voice_get_idx_for_session(v->session_id); + mvm_stop_voice_cmd.dest_port = mvm_handle; + mvm_stop_voice_cmd.token = 0; + mvm_stop_voice_cmd.opcode = VSS_IMVM_CMD_STOP_VOICE; + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_stop_voice_cmd); + if (ret < 0) { + pr_err("Fail in sending VSS_IMVM_CMD_STOP_VOICE\n"); + goto fail; + } + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + + return 0; +fail: + return ret; +} +static int voice_get_cal(struct cal_block_data **cal_block, + int cal_block_idx, + struct cal_block_data **col_data, + int col_data_idx, int session_id) +{ + int ret = 0; + + *cal_block = cal_utils_get_only_cal_block( + common.cal_data[cal_block_idx]); + if (*cal_block == NULL) { + pr_err("%s: No cal data for cal %d!\n", + __func__, cal_block_idx); + + ret = -ENODEV; + goto done; + } + ret = remap_cal_data(*cal_block, session_id); + if (ret < 0) { + pr_err("%s: Remap_cal_data failed for cal %d!\n", + __func__, cal_block_idx); + + ret = -ENODEV; + goto done; + } + + if (col_data == NULL) + goto done; + + *col_data = cal_utils_get_only_cal_block( + common.cal_data[col_data_idx]); + if (*col_data == NULL) { + pr_err("%s: No cal data for cal %d!\n", + __func__, col_data_idx); + + ret = -ENODEV; + goto done; + } +done: + return ret; +} + +static int voice_send_cvs_register_cal_cmd(struct voice_data *v) +{ + struct cvs_register_cal_data_cmd cvs_reg_cal_cmd; + struct cal_block_data *cal_block = NULL; + struct cal_block_data *col_data = NULL; + int ret = 0; + + memset(&cvs_reg_cal_cmd, 0, sizeof(cvs_reg_cal_cmd)); + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + if (!common.apr_q6_cvs) { + pr_err("%s: apr_cvs is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + mutex_lock(&common.cal_data[CVS_VOCSTRM_CAL]->lock); + mutex_lock(&common.cal_data[CVS_VOCSTRM_COL_CAL]->lock); + + ret = voice_get_cal(&cal_block, CVS_VOCSTRM_CAL, &col_data, + CVS_VOCSTRM_COL_CAL, v->session_id); + if (ret < 0) { + pr_err("%s: Voice_get_cal failed for cal %d!\n", + __func__, CVS_VOCSTRM_CAL); + + goto unlock; + } + + memcpy(&cvs_reg_cal_cmd.cvs_cal_data.column_info[0], + (void *) &((struct audio_cal_info_voc_col *) + col_data->cal_info)->data, + col_data->cal_data.size); + + cvs_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cvs_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvs_reg_cal_cmd) - APR_HDR_SIZE); + cvs_reg_cal_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvs_reg_cal_cmd.hdr.dest_port = voice_get_cvs_handle(v); + cvs_reg_cal_cmd.hdr.token = 0; + if (common.is_per_vocoder_cal_enabled) + cvs_reg_cal_cmd.hdr.opcode = + VSS_ISTREAM_CMD_REGISTER_STATIC_CALIBRATION_DATA; + else + cvs_reg_cal_cmd.hdr.opcode = + VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA_V2; + + cvs_reg_cal_cmd.cvs_cal_data.cal_mem_handle = + cal_block->map_data.q6map_handle; + cvs_reg_cal_cmd.cvs_cal_data.cal_mem_address_lsw = + lower_32_bits(cal_block->cal_data.paddr); + cvs_reg_cal_cmd.cvs_cal_data.cal_mem_address_msw = + msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr); + cvs_reg_cal_cmd.cvs_cal_data.cal_mem_size = + cal_block->cal_data.size; + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(common.apr_q6_cvs, (uint32_t *) &cvs_reg_cal_cmd); + if (ret < 0) { + pr_err("%s: Error %d registering CVS cal\n", __func__, ret); + + ret = -EINVAL; + goto unlock; + } + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Command timeout\n", __func__); + + ret = -EINVAL; + goto unlock; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto unlock; + } +unlock: + mutex_unlock(&common.cal_data[CVS_VOCSTRM_COL_CAL]->lock); + mutex_unlock(&common.cal_data[CVS_VOCSTRM_CAL]->lock); +done: + return ret; +} + +static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v) +{ + struct cvs_deregister_cal_data_cmd cvs_dereg_cal_cmd; + int ret = 0; + + memset(&cvs_dereg_cal_cmd, 0, sizeof(cvs_dereg_cal_cmd)); + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + if (!common.apr_q6_cvs) { + pr_err("%s: apr_cvs is NULL\n", __func__); + + ret = -EPERM; + goto done; + } + + cvs_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cvs_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvs_dereg_cal_cmd) - APR_HDR_SIZE); + cvs_dereg_cal_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvs_dereg_cal_cmd.hdr.dest_port = voice_get_cvs_handle(v); + cvs_dereg_cal_cmd.hdr.token = 0; + if (common.is_per_vocoder_cal_enabled) + cvs_dereg_cal_cmd.hdr.opcode = + VSS_ISTREAM_CMD_DEREGISTER_STATIC_CALIBRATION_DATA; + else + cvs_dereg_cal_cmd.hdr.opcode = + VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA; + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(common.apr_q6_cvs, (uint32_t *) &cvs_dereg_cal_cmd); + if (ret < 0) { + pr_err("%s: Error %d de-registering CVS cal\n", __func__, ret); + goto done; + } + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Command timeout\n", __func__); + goto done; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto done; + } + +done: + return ret; + +} + +static int voice_send_cvp_create_cmd(struct voice_data *v) +{ + struct cvp_create_full_ctl_session_cmd cvp_session_cmd; + void *apr_cvp; + int ret = 0; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + apr_cvp = common.apr_q6_cvp; + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL.\n", __func__); + + ret = -EINVAL; + goto done; + } + + /* create cvp session and wait for response */ + cvp_session_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_session_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_session_cmd) - APR_HDR_SIZE); + pr_debug("%s: send create cvp session, pkt size = %d\n", + __func__, cvp_session_cmd.hdr.pkt_size); + cvp_session_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_session_cmd.hdr.dest_port = 0; + cvp_session_cmd.hdr.token = 0; + + if (voice_get_cvd_int_version(common.cvd_version) >= + CVD_INT_VERSION_2_2) + cvp_session_cmd.hdr.opcode = + VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V3; + else + cvp_session_cmd.hdr.opcode = + VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V2; + + voc_get_tx_rx_topology(v, + &cvp_session_cmd.cvp_session.tx_topology_id, + &cvp_session_cmd.cvp_session.rx_topology_id); + + cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/ + cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.port_id; + cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.port_id; + cvp_session_cmd.cvp_session.profile_id = + VSS_ICOMMON_CAL_NETWORK_ID_NONE; + if (common.ec_ref_ext) { + cvp_session_cmd.cvp_session.vocproc_mode = + VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING; + cvp_session_cmd.cvp_session.ec_ref_port_id = + common.ec_media_fmt_info.port_id; + } else { + cvp_session_cmd.cvp_session.vocproc_mode = + VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING; + cvp_session_cmd.cvp_session.ec_ref_port_id = + VSS_IVOCPROC_PORT_ID_NONE; + } + + pr_debug("tx_topology: %d tx_port_id=%d, rx_port_id=%d, mode: 0x%x\n", + cvp_session_cmd.cvp_session.tx_topology_id, + cvp_session_cmd.cvp_session.tx_port_id, + cvp_session_cmd.cvp_session.rx_port_id, + cvp_session_cmd.cvp_session.vocproc_mode); + pr_debug("rx_topology: %d, profile_id: 0x%x, pkt_size: %d\n", + cvp_session_cmd.cvp_session.rx_topology_id, + cvp_session_cmd.cvp_session.profile_id, + cvp_session_cmd.hdr.pkt_size); + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_session_cmd); + if (ret < 0) { + pr_err("Fail in sending VOCPROC_FULL_CONTROL_SESSION\n"); + + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + + ret = -EINVAL; + goto done; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto done; + } + +done: + return ret; +} + +static int voice_send_cvp_register_dev_cfg_cmd(struct voice_data *v) +{ + struct cvp_register_dev_cfg_cmd cvp_reg_dev_cfg_cmd; + struct cal_block_data *cal_block = NULL; + int ret = 0; + + memset(&cvp_reg_dev_cfg_cmd, 0, sizeof(cvp_reg_dev_cfg_cmd)); + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + if (!common.apr_q6_cvp) { + pr_err("%s: apr_cvp is NULL\n", __func__); + + ret = -EPERM; + goto done; + } + + mutex_lock(&common.cal_data[CVP_VOCDEV_CFG_CAL]->lock); + + ret = voice_get_cal(&cal_block, CVP_VOCDEV_CFG_CAL, NULL, + 0, v->session_id); + if (ret < 0) { + pr_err("%s: Voice_get_cal failed for cal %d!\n", + __func__, CVP_VOCDEV_CFG_CAL); + + goto unlock; + } + + cvp_reg_dev_cfg_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cvp_reg_dev_cfg_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_reg_dev_cfg_cmd) - APR_HDR_SIZE); + cvp_reg_dev_cfg_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_reg_dev_cfg_cmd.hdr.dest_port = voice_get_cvp_handle(v); + cvp_reg_dev_cfg_cmd.hdr.token = 0; + cvp_reg_dev_cfg_cmd.hdr.opcode = + VSS_IVOCPROC_CMD_REGISTER_DEVICE_CONFIG; + + cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_handle = + cal_block->map_data.q6map_handle; + cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_address_lsw = + lower_32_bits(cal_block->cal_data.paddr); + cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_address_msw = + msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr); + cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_size = + cal_block->cal_data.size; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(common.apr_q6_cvp, + (uint32_t *) &cvp_reg_dev_cfg_cmd); + if (ret < 0) { + pr_err("%s: Error %d registering CVP dev cfg cal\n", + __func__, ret); + + ret = -EINVAL; + goto unlock; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Command timeout\n", __func__); + + ret = -EINVAL; + goto unlock; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto unlock; + } +unlock: + mutex_unlock(&common.cal_data[CVP_VOCDEV_CFG_CAL]->lock); +done: + return ret; +} + +static int voice_send_cvp_deregister_dev_cfg_cmd(struct voice_data *v) +{ + struct cvp_deregister_dev_cfg_cmd cvp_dereg_dev_cfg_cmd; + int ret = 0; + + memset(&cvp_dereg_dev_cfg_cmd, 0, sizeof(cvp_dereg_dev_cfg_cmd)); + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + if (!common.apr_q6_cvp) { + pr_err("%s: apr_cvp is NULL\n", __func__); + + ret = -EPERM; + goto done; + } + + cvp_dereg_dev_cfg_cmd.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cvp_dereg_dev_cfg_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_dereg_dev_cfg_cmd) - APR_HDR_SIZE); + cvp_dereg_dev_cfg_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_dereg_dev_cfg_cmd.hdr.dest_port = voice_get_cvp_handle(v); + cvp_dereg_dev_cfg_cmd.hdr.token = 0; + cvp_dereg_dev_cfg_cmd.hdr.opcode = + VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(common.apr_q6_cvp, + (uint32_t *) &cvp_dereg_dev_cfg_cmd); + if (ret < 0) { + pr_err("%s: Error %d de-registering CVP dev cfg cal\n", + __func__, ret); + goto done; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Command timeout\n", __func__); + goto done; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto done; + } + +done: + return ret; +} + +static int voice_send_cvp_register_cal_cmd(struct voice_data *v) +{ + struct cvp_register_cal_data_cmd cvp_reg_cal_cmd; + struct cal_block_data *cal_block = NULL; + struct cal_block_data *col_data = NULL; + int ret = 0; + + memset(&cvp_reg_cal_cmd, 0, sizeof(cvp_reg_cal_cmd)); + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + if (!common.apr_q6_cvp) { + pr_err("%s: apr_cvp is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + mutex_lock(&common.cal_data[CVP_VOCPROC_CAL]->lock); + mutex_lock(&common.cal_data[CVP_VOCPROC_COL_CAL]->lock); + + ret = voice_get_cal(&cal_block, CVP_VOCPROC_CAL, &col_data, + CVP_VOCPROC_COL_CAL, v->session_id); + if (ret < 0) { + pr_err("%s: Voice_get_cal failed for cal %d!\n", + __func__, CVP_VOCPROC_CAL); + + goto unlock; + } + + v->dev_tx.dev_id = ((struct audio_cal_info_vocproc *) + cal_block->cal_info)->tx_acdb_id; + v->dev_rx.dev_id = ((struct audio_cal_info_vocproc *) + cal_block->cal_info)->rx_acdb_id; + pr_debug("%s: %s: Tx acdb id = %d and Rx acdb id = %d", __func__, + voc_get_session_name(v->session_id), v->dev_tx.dev_id, + v->dev_rx.dev_id); + + memcpy(&cvp_reg_cal_cmd.cvp_cal_data.column_info[0], + (void *) &((struct audio_cal_info_voc_col *) + col_data->cal_info)->data, + col_data->cal_data.size); + + cvp_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cvp_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_reg_cal_cmd) - APR_HDR_SIZE); + cvp_reg_cal_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_reg_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v); + cvp_reg_cal_cmd.hdr.token = 0; + if (common.is_per_vocoder_cal_enabled) + cvp_reg_cal_cmd.hdr.opcode = + VSS_IVOCPROC_CMD_REGISTER_STATIC_CALIBRATION_DATA; + else + cvp_reg_cal_cmd.hdr.opcode = + VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2; + + cvp_reg_cal_cmd.cvp_cal_data.cal_mem_handle = + cal_block->map_data.q6map_handle; + cvp_reg_cal_cmd.cvp_cal_data.cal_mem_address_lsw = + lower_32_bits(cal_block->cal_data.paddr); + cvp_reg_cal_cmd.cvp_cal_data.cal_mem_address_msw = + msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr); + cvp_reg_cal_cmd.cvp_cal_data.cal_mem_size = + cal_block->cal_data.size; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(common.apr_q6_cvp, (uint32_t *) &cvp_reg_cal_cmd); + if (ret < 0) { + pr_err("%s: Error %d registering CVP cal\n", __func__, ret); + + ret = -EINVAL; + goto unlock; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Command timeout\n", __func__); + + ret = -EINVAL; + goto unlock; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto unlock; + } +unlock: + mutex_unlock(&common.cal_data[CVP_VOCPROC_COL_CAL]->lock); + mutex_unlock(&common.cal_data[CVP_VOCPROC_CAL]->lock); +done: + return ret; +} + +static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v) +{ + struct cvp_deregister_cal_data_cmd cvp_dereg_cal_cmd; + int ret = 0; + + memset(&cvp_dereg_cal_cmd, 0, sizeof(cvp_dereg_cal_cmd)); + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + if (!common.apr_q6_cvp) { + pr_err("%s: apr_cvp is NULL.\n", __func__); + + ret = -EPERM; + goto done; + } + + cvp_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cvp_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_dereg_cal_cmd) - APR_HDR_SIZE); + cvp_dereg_cal_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_dereg_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v); + cvp_dereg_cal_cmd.hdr.token = 0; + if (common.is_per_vocoder_cal_enabled) + cvp_dereg_cal_cmd.hdr.opcode = + VSS_IVOCPROC_CMD_DEREGISTER_STATIC_CALIBRATION_DATA; + else + cvp_dereg_cal_cmd.hdr.opcode = + VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(common.apr_q6_cvp, (uint32_t *) &cvp_dereg_cal_cmd); + if (ret < 0) { + pr_err("%s: Error %d de-registering CVP cal\n", __func__, ret); + goto done; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Command timeout\n", __func__); + goto done; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto done; + } + +done: + return ret; +} + +static int voice_send_cvp_register_vol_cal_cmd(struct voice_data *v) +{ + struct cvp_register_vol_cal_data_cmd cvp_reg_vol_cal_cmd; + struct cal_block_data *cal_block = NULL; + struct cal_block_data *col_data = NULL; + int ret = 0; + + memset(&cvp_reg_vol_cal_cmd, 0, sizeof(cvp_reg_vol_cal_cmd)); + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + if (!common.apr_q6_cvp) { + pr_err("%s: apr_cvp is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + mutex_lock(&common.cal_data[CVP_VOCVOL_CAL]->lock); + mutex_lock(&common.cal_data[CVP_VOCVOL_COL_CAL]->lock); + + ret = voice_get_cal(&cal_block, CVP_VOCVOL_CAL, &col_data, + CVP_VOCVOL_COL_CAL, v->session_id); + if (ret < 0) { + pr_err("%s: Voice_get_cal failed for cal %d!\n", + __func__, CVP_VOCVOL_CAL); + + goto unlock; + } + + memcpy(&cvp_reg_vol_cal_cmd.cvp_vol_cal_data.column_info[0], + (void *) &((struct audio_cal_info_voc_col *) + col_data->cal_info)->data, + col_data->cal_data.size); + + cvp_reg_vol_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cvp_reg_vol_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_reg_vol_cal_cmd) - APR_HDR_SIZE); + cvp_reg_vol_cal_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_reg_vol_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v); + cvp_reg_vol_cal_cmd.hdr.token = 0; + if (common.is_per_vocoder_cal_enabled) + cvp_reg_vol_cal_cmd.hdr.opcode = + VSS_IVOCPROC_CMD_REGISTER_DYNAMIC_CALIBRATION_DATA; + else + cvp_reg_vol_cal_cmd.hdr.opcode = + VSS_IVOCPROC_CMD_REGISTER_VOL_CALIBRATION_DATA; + + cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_handle = + cal_block->map_data.q6map_handle; + cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_address_lsw = + lower_32_bits(cal_block->cal_data.paddr); + cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_address_msw = + msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr); + cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_size = + cal_block->cal_data.size; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(common.apr_q6_cvp, + (uint32_t *) &cvp_reg_vol_cal_cmd); + if (ret < 0) { + pr_err("%s: Error %d registering CVP vol cal\n", __func__, ret); + + ret = -EINVAL; + goto unlock; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Command timeout\n", __func__); + + ret = -EINVAL; + goto unlock; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto unlock; + } +unlock: + mutex_unlock(&common.cal_data[CVP_VOCVOL_COL_CAL]->lock); + mutex_unlock(&common.cal_data[CVP_VOCVOL_CAL]->lock); +done: + return ret; +} + +static int voice_send_cvp_deregister_vol_cal_cmd(struct voice_data *v) +{ + struct cvp_deregister_vol_cal_data_cmd cvp_dereg_vol_cal_cmd; + int ret = 0; + + memset(&cvp_dereg_vol_cal_cmd, 0, sizeof(cvp_dereg_vol_cal_cmd)); + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + if (!common.apr_q6_cvp) { + pr_err("%s: apr_cvp is NULL\n", __func__); + + ret = -EPERM; + goto done; + } + + cvp_dereg_vol_cal_cmd.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cvp_dereg_vol_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_dereg_vol_cal_cmd) - APR_HDR_SIZE); + cvp_dereg_vol_cal_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_dereg_vol_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v); + cvp_dereg_vol_cal_cmd.hdr.token = 0; + if (common.is_per_vocoder_cal_enabled) + cvp_dereg_vol_cal_cmd.hdr.opcode = + VSS_IVOCPROC_CMD_DEREGISTER_DYNAMIC_CALIBRATION_DATA; + else + cvp_dereg_vol_cal_cmd.hdr.opcode = + VSS_IVOCPROC_CMD_DEREGISTER_VOL_CALIBRATION_DATA; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(common.apr_q6_cvp, + (uint32_t *) &cvp_dereg_vol_cal_cmd); + if (ret < 0) { + pr_err("%s: Error %d de-registering CVP vol cal\n", + __func__, ret); + goto done; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Command timeout\n", __func__); + goto done; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto done; + } + +done: + return ret; +} + +static int voice_map_memory_physical_cmd(struct voice_data *v, + struct mem_map_table *table_info, + dma_addr_t phys, + uint32_t size, + uint32_t token) +{ + struct vss_imemory_cmd_map_physical_t mvm_map_phys_cmd; + uint32_t *memtable; + int ret = 0; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + ret = -EINVAL; + goto fail; + } + + if (!common.apr_q6_mvm) { + pr_err("%s: apr_mvm is NULL.\n", __func__); + ret = -EINVAL; + goto fail; + } + + if (!table_info->data) { + pr_err("%s: memory table is NULL.\n", __func__); + ret = -EINVAL; + goto fail; + } + + memtable = (uint32_t *) table_info->data; + + /* + * Store next table descriptor's address(64 bit) as NULL as there + * is only one memory block + */ + memtable[0] = 0; + memtable[1] = 0; + + /* Store next table descriptor's size */ + memtable[2] = 0; + + /* Store shared mem adddress (64 bit) */ + memtable[3] = lower_32_bits(phys); + memtable[4] = msm_audio_populate_upper_32_bits(phys); + + /* Store shared memory size */ + memtable[5] = size; + + mvm_map_phys_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + mvm_map_phys_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mvm_map_phys_cmd) - APR_HDR_SIZE); + mvm_map_phys_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + mvm_map_phys_cmd.hdr.dest_port = voice_get_mvm_handle(v); + mvm_map_phys_cmd.hdr.token = token; + mvm_map_phys_cmd.hdr.opcode = VSS_IMEMORY_CMD_MAP_PHYSICAL; + + mvm_map_phys_cmd.table_descriptor.mem_address_lsw = + lower_32_bits(table_info->phys); + mvm_map_phys_cmd.table_descriptor.mem_address_msw = + msm_audio_populate_upper_32_bits(table_info->phys); + mvm_map_phys_cmd.table_descriptor.mem_size = + sizeof(struct vss_imemory_block_t) + + sizeof(struct vss_imemory_table_descriptor_t); + mvm_map_phys_cmd.is_cached = true; + mvm_map_phys_cmd.cache_line_size = 128; + mvm_map_phys_cmd.access_mask = 3; + mvm_map_phys_cmd.page_align = 4096; + mvm_map_phys_cmd.min_data_width = 8; + mvm_map_phys_cmd.max_data_width = 64; + + pr_debug("%s: next table desc: add: %lld, size: %d\n", + __func__, *((uint64_t *) memtable), + *(((uint32_t *) memtable) + 2)); + pr_debug("%s: phy add of of mem being mapped LSW:0x%x, MSW:0x%x size: %d\n", + __func__, *(((uint32_t *) memtable) + 3), + *(((uint32_t *) memtable) + 4), *(((uint32_t *) memtable) + 5)); + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(common.apr_q6_mvm, (uint32_t *) &mvm_map_phys_cmd); + if (ret < 0) { + pr_err("%s: Error %d sending mvm map phy cmd\n", __func__, ret); + + goto fail; + } + + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Command timeout\n", __func__); + + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + + return 0; + +fail: + return ret; +} + +static int voice_pause_voice_call(struct voice_data *v) +{ + struct apr_hdr mvm_pause_voice_cmd; + void *apr_mvm; + int ret = 0; + + pr_debug("%s\n", __func__); + + if (v == NULL) { + pr_err("%s: Voice data is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + apr_mvm = common.apr_q6_mvm; + if (!apr_mvm) { + pr_err("%s: apr_mvm is NULL.\n", __func__); + + ret = -EINVAL; + goto done; + } + + mvm_pause_voice_cmd.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + mvm_pause_voice_cmd.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mvm_pause_voice_cmd) - APR_HDR_SIZE); + mvm_pause_voice_cmd.src_port = + voice_get_idx_for_session(v->session_id); + mvm_pause_voice_cmd.dest_port = voice_get_mvm_handle(v); + mvm_pause_voice_cmd.token = 0; + mvm_pause_voice_cmd.opcode = VSS_IMVM_CMD_PAUSE_VOICE; + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + + pr_debug("%s: send mvm_pause_voice_cmd pkt size = %d\n", + __func__, mvm_pause_voice_cmd.pkt_size); + + ret = apr_send_pkt(apr_mvm, + (uint32_t *)&mvm_pause_voice_cmd); + if (ret < 0) { + pr_err("Fail in sending VSS_IMVM_CMD_PAUSE_VOICE\n"); + + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Command timeout\n", __func__); + + ret = -EINVAL; + goto done; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto done; + } + +done: + return ret; +} + +static int voice_map_cal_memory(struct cal_block_data *cal_block, + uint32_t session_id) +{ + int result = 0; + int voc_index; + struct voice_data *v = NULL; + + pr_debug("%s\n", __func__); + + if (cal_block == NULL) { + pr_err("%s: Cal block is NULL!\n", __func__); + + result = -EINVAL; + goto done; + } + + if (cal_block->cal_data.paddr == 0) { + pr_debug("%s: No address to map!\n", __func__); + + result = -EINVAL; + goto done; + } + + if (cal_block->map_data.map_size == 0) { + pr_debug("%s: Map size is 0!\n", __func__); + + result = -EINVAL; + goto done; + } + + voc_index = voice_get_idx_for_session(session_id); + if (voc_index < 0) { + pr_err("%s: Invalid session ID %d\n", __func__, session_id); + + goto done; + } + + mutex_lock(&common.common_lock); + v = &common.voice[voc_index]; + + result = voice_map_memory_physical_cmd(v, + &common.cal_mem_map_table, + (dma_addr_t)cal_block->cal_data.paddr, + cal_block->map_data.map_size, + VOC_CAL_MEM_MAP_TOKEN); + if (result < 0) { + pr_err("%s: Mmap did not work! addr = 0x%pK, size = %zd\n", + __func__, + &cal_block->cal_data.paddr, + cal_block->map_data.map_size); + + goto done_unlock; + } + + cal_block->map_data.q6map_handle = common.cal_mem_handle; +done_unlock: + mutex_unlock(&common.common_lock); +done: + return result; +} + +static int remap_cal_data(struct cal_block_data *cal_block, + uint32_t session_id) +{ + int ret = 0; + + pr_debug("%s\n", __func__); + + if (cal_block->map_data.ion_client == NULL) { + pr_err("%s: No ION allocation for session_id %d!\n", + __func__, session_id); + ret = -EINVAL; + goto done; + } + + if ((cal_block->map_data.map_size > 0) && + (cal_block->map_data.q6map_handle == 0)) { + + /* cal type not used */ + ret = voice_map_cal_memory(cal_block, session_id); + if (ret < 0) { + pr_err("%s: Mmap did not work! size = %zd\n", + __func__, cal_block->map_data.map_size); + + goto done; + } + } else { + pr_debug("%s: Cal block 0x%pK, size %zd already mapped. Q6 map handle = %d\n", + __func__, &cal_block->cal_data.paddr, + cal_block->map_data.map_size, + cal_block->map_data.q6map_handle); + } +done: + return ret; +} + +static int voice_unmap_cal_memory(int32_t cal_type, + struct cal_block_data *cal_block) +{ + int result = 0; + int result2 = 0; + int i; + struct voice_data *v = NULL; + + pr_debug("%s\n", __func__); + + if (cal_block == NULL) { + pr_err("%s: Cal block is NULL!\n", __func__); + + result = -EINVAL; + goto done; + } + + if (cal_block->map_data.q6map_handle == 0) { + pr_debug("%s: Q6 handle is not set!\n", __func__); + + result = -EINVAL; + goto done; + } + + mutex_lock(&common.common_lock); + + for (i = 0; i < MAX_VOC_SESSIONS; i++) { + v = &common.voice[i]; + + mutex_lock(&v->lock); + if (is_voc_state_active(v->voc_state)) { + result2 = voice_pause_voice_call(v); + if (result2 < 0) { + pr_err("%s: Voice_pause_voice_call failed for session 0x%x, err %d!\n", + __func__, v->session_id, result2); + + result = result2; + } + + if (cal_type == CVP_VOCPROC_DYNAMIC_CAL_TYPE) + voice_send_cvp_deregister_vol_cal_cmd(v); + else if (cal_type == CVP_VOCPROC_STATIC_CAL_TYPE) + voice_send_cvp_deregister_cal_cmd(v); + else if (cal_type == CVP_VOCDEV_CFG_CAL_TYPE) + voice_send_cvp_deregister_dev_cfg_cmd(v); + else if (cal_type == CVS_VOCSTRM_STATIC_CAL_TYPE) + voice_send_cvs_deregister_cal_cmd(v); + else + pr_err("%s: Invalid cal type %d!\n", + __func__, cal_type); + + result2 = voice_send_start_voice_cmd(v); + if (result2) { + pr_err("%s: Voice_send_start_voice_cmd failed for session 0x%x, err %d!\n", + __func__, v->session_id, result2); + + result = result2; + } + } + + if ((cal_block->map_data.q6map_handle != 0) && + (!is_other_session_active(v->session_id))) { + + result2 = voice_send_mvm_unmap_memory_physical_cmd( + v, cal_block->map_data.q6map_handle); + if (result2) { + pr_err("%s: Voice_send_mvm_unmap_memory_physical_cmd failed for session 0x%x, err %d!\n", + __func__, v->session_id, result2); + + result = result2; + } + cal_block->map_data.q6map_handle = 0; + } + mutex_unlock(&v->lock); + } + mutex_unlock(&common.common_lock); +done: + return result; +} + +int voc_register_vocproc_vol_table(void) +{ + int result = 0; + int result2 = 0; + int i; + struct voice_data *v = NULL; + + pr_debug("%s\n", __func__); + + mutex_lock(&common.common_lock); + for (i = 0; i < MAX_VOC_SESSIONS; i++) { + v = &common.voice[i]; + + mutex_lock(&v->lock); + if (is_voc_state_active(v->voc_state)) { + result2 = voice_send_cvp_register_vol_cal_cmd(v); + if (result2 < 0) { + pr_err("%s: Failed to register vocvol table for session 0x%x!\n", + __func__, v->session_id); + + result = result2; + /* Still try to register other sessions */ + } + } + mutex_unlock(&v->lock); + } + + mutex_unlock(&common.common_lock); + return result; +} + +int voc_deregister_vocproc_vol_table(void) +{ + int result = 0; + int success = 0; + int i; + struct voice_data *v = NULL; + + pr_debug("%s\n", __func__); + + mutex_lock(&common.common_lock); + for (i = 0; i < MAX_VOC_SESSIONS; i++) { + v = &common.voice[i]; + + mutex_lock(&v->lock); + if (is_voc_state_active(v->voc_state)) { + result = voice_send_cvp_deregister_vol_cal_cmd(v); + if (result < 0) { + pr_err("%s: Failed to deregister vocvol table for session 0x%x!\n", + __func__, v->session_id); + + mutex_unlock(&v->lock); + mutex_unlock(&common.common_lock); + if (success) { + pr_err("%s: Try to re-register all deregistered sessions!\n", + __func__); + + voc_register_vocproc_vol_table(); + } + goto done; + } else { + success = 1; + } + } + mutex_unlock(&v->lock); + } + mutex_unlock(&common.common_lock); +done: + return result; +} + +int voc_map_rtac_block(struct rtac_cal_block_data *cal_block) +{ + int result = 0; + struct voice_data *v = NULL; + + pr_debug("%s\n", __func__); + + if (cal_block == NULL) { + pr_err("%s: cal_block is NULL!\n", + __func__); + + result = -EINVAL; + goto done; + } + + if (cal_block->cal_data.paddr == 0) { + pr_debug("%s: No address to map!\n", + __func__); + + result = -EINVAL; + goto done; + } + + if (cal_block->map_data.map_size == 0) { + pr_debug("%s: map size is 0!\n", + __func__); + + result = -EINVAL; + goto done; + } + + mutex_lock(&common.common_lock); + /* use first session */ + v = &common.voice[0]; + mutex_lock(&v->lock); + + if (!is_rtac_memory_allocated()) { + result = voice_alloc_rtac_mem_map_table(); + if (result < 0) { + pr_err("%s: RTAC alloc mem map table did not work! addr = 0x%pK, size = %d\n", + __func__, + &cal_block->cal_data.paddr, + cal_block->map_data.map_size); + + goto done_unlock; + } + } + + result = voice_map_memory_physical_cmd(v, + &common.rtac_mem_map_table, + (dma_addr_t)cal_block->cal_data.paddr, + cal_block->map_data.map_size, + VOC_RTAC_MEM_MAP_TOKEN); + if (result < 0) { + pr_err("%s: RTAC mmap did not work! addr = 0x%pK, size = %d\n", + __func__, + &cal_block->cal_data.paddr, + cal_block->map_data.map_size); + + free_rtac_map_table(); + goto done_unlock; + } + + cal_block->map_data.map_handle = common.rtac_mem_handle; +done_unlock: + mutex_unlock(&v->lock); + mutex_unlock(&common.common_lock); +done: + return result; +} + +int voc_unmap_rtac_block(uint32_t *mem_map_handle) +{ + int result = 0; + struct voice_data *v = NULL; + + pr_debug("%s\n", __func__); + + if (mem_map_handle == NULL) { + pr_debug("%s: Map handle is NULL, nothing to unmap\n", + __func__); + + goto done; + } + + if (*mem_map_handle == 0) { + pr_debug("%s: Map handle is 0, nothing to unmap\n", + __func__); + + goto done; + } + + mutex_lock(&common.common_lock); + /* Use first session */ + /* Only used for apr wait lock */ + v = &common.voice[0]; + mutex_lock(&v->lock); + + result = voice_send_mvm_unmap_memory_physical_cmd( + v, *mem_map_handle); + if (result) { + pr_err("%s: voice_send_mvm_unmap_memory_physical_cmd Failed for session 0x%x!\n", + __func__, v->session_id); + } else { + *mem_map_handle = 0; + common.rtac_mem_handle = 0; + free_rtac_map_table(); + } + mutex_unlock(&v->lock); + mutex_unlock(&common.common_lock); +done: + return result; +} + +static int voice_setup_vocproc(struct voice_data *v) +{ + int ret = 0; + + ret = voice_send_cvp_create_cmd(v); + if (ret < 0) { + pr_err("%s: CVP create failed err:%d\n", __func__, ret); + goto fail; + } + + ret = voice_send_cvp_media_fmt_info_cmd(v); + if (ret < 0) { + pr_err("%s: Set media format info failed err:%d\n", __func__, + ret); + goto fail; + } + + ret = voice_send_cvp_topology_commit_cmd(v); + if (ret < 0) { + pr_err("%s: Set topology commit failed err:%d\n", + __func__, ret); + goto fail; + } + + voice_send_cvs_register_cal_cmd(v); + voice_send_cvp_register_dev_cfg_cmd(v); + voice_send_cvp_register_cal_cmd(v); + voice_send_cvp_register_vol_cal_cmd(v); + + /* enable vocproc */ + ret = voice_send_enable_vocproc_cmd(v); + if (ret < 0) + goto fail; + + /* attach vocproc */ + ret = voice_send_attach_vocproc_cmd(v); + if (ret < 0) + goto fail; + + /* send tty mode if tty device is used */ + voice_send_tty_mode_cmd(v); + + if (is_voip_session(v->session_id)) { + ret = voice_send_mvm_cal_network_cmd(v); + if (ret < 0) + pr_err("%s: voice_send_mvm_cal_network_cmd: %d\n", + __func__, ret); + + ret = voice_send_mvm_media_type_cmd(v); + if (ret < 0) + pr_err("%s: voice_send_mvm_media_type_cmd: %d\n", + __func__, ret); + + voice_send_netid_timing_cmd(v); + } + + if (v->st_enable && !v->tty_mode) + voice_send_set_pp_enable_cmd(v, + MODULE_ID_VOICE_MODULE_ST, + v->st_enable); + /* Start in-call music delivery if this feature is enabled */ + if (v->music_info.play_enable) + voice_cvs_start_playback(v); + + /* Start in-call recording if this feature is enabled */ + if (v->rec_info.rec_enable) + voice_cvs_start_record(v, v->rec_info.rec_mode); + + if (v->dtmf_rx_detect_en) + voice_send_dtmf_rx_detection_cmd(v, v->dtmf_rx_detect_en); + + if (v->hd_enable) + voice_send_hd_cmd(v, v->hd_enable); + + rtac_add_voice(voice_get_cvs_handle(v), + voice_get_cvp_handle(v), + v->dev_rx.port_id, v->dev_tx.port_id, + v->dev_rx.dev_id, v->dev_tx.dev_id, + v->session_id); + + return 0; + +fail: + return ret; +} + +static int voice_send_cvp_device_channels_cmd(struct voice_data *v) +{ + int ret = 0; + struct cvp_set_dev_channels_cmd cvp_set_dev_channels_cmd; + void *apr_cvp; + u16 cvp_handle; + + if (!(voice_get_cvd_int_version(common.cvd_version) >= + CVD_INT_VERSION_2_2)) { + pr_debug("%s CVD ver %s doesn't support send_device_channels cmd\n", + __func__, common.cvd_version); + + goto done; + } + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + apr_cvp = common.apr_q6_cvp; + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL.\n", __func__); + + ret = -EINVAL; + goto done; + } + + cvp_handle = voice_get_cvp_handle(v); + cvp_set_dev_channels_cmd.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_set_dev_channels_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_set_dev_channels_cmd) - APR_HDR_SIZE); + cvp_set_dev_channels_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_set_dev_channels_cmd.hdr.dest_port = cvp_handle; + cvp_set_dev_channels_cmd.hdr.token = 0; + cvp_set_dev_channels_cmd.hdr.opcode = + VSS_IVOCPROC_CMD_TOPOLOGY_SET_DEV_CHANNELS; + cvp_set_dev_channels_cmd.cvp_set_channels.rx_num_channels = + VSS_NUM_DEV_CHANNELS_1; + cvp_set_dev_channels_cmd.cvp_set_channels.tx_num_channels = + v->dev_tx.no_of_channels; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_set_dev_channels_cmd); + if (ret < 0) { + pr_err("%s: Fail in sending VSS_IVOCPROC_CMD_TOPOLOGY_SET_DEV_CHANNELS\n", + __func__); + + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + + ret = -EINVAL; + goto done; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto done; + } + +done: + return ret; +} + +static int voice_send_cvp_media_fmt_info_cmd(struct voice_data *v) +{ + int ret; + + ret = voice_send_cvp_device_channels_cmd(v); + if (ret < 0) + goto done; + + if (voice_get_cvd_int_version(common.cvd_version) >= + CVD_INT_VERSION_2_3) { + ret = voice_send_cvp_media_format_cmd(v, RX_PATH); + if (ret < 0) + goto done; + + ret = voice_send_cvp_media_format_cmd(v, TX_PATH); + if (ret < 0) + goto done; + + if (common.ec_ref_ext) + ret = voice_send_cvp_media_format_cmd(v, EC_REF_PATH); + } + +done: + return ret; +} + +static int voice_send_cvp_media_format_cmd(struct voice_data *v, + uint32_t param_type) +{ + int ret = 0; + struct cvp_set_media_format_cmd cvp_set_media_format_cmd; + void *apr_cvp; + u16 cvp_handle; + struct vss_icommon_param_data_t *media_fmt_param_data = + &cvp_set_media_format_cmd.cvp_set_param_v2.param_data; + struct vss_param_endpoint_media_format_info_t *media_fmt_info = + &media_fmt_param_data->media_format_info; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + apr_cvp = common.apr_q6_cvp; + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL.\n", __func__); + ret = -EINVAL; + goto done; + } + + cvp_handle = voice_get_cvp_handle(v); + memset(&cvp_set_media_format_cmd, 0, sizeof(cvp_set_media_format_cmd)); + + /* Fill header data */ + cvp_set_media_format_cmd.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_set_media_format_cmd.hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_set_media_format_cmd) - APR_HDR_SIZE); + cvp_set_media_format_cmd.hdr.src_svc = 0; + cvp_set_media_format_cmd.hdr.src_domain = APR_DOMAIN_APPS; + cvp_set_media_format_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_set_media_format_cmd.hdr.dest_svc = 0; + cvp_set_media_format_cmd.hdr.dest_domain = APR_DOMAIN_ADSP; + cvp_set_media_format_cmd.hdr.dest_port = cvp_handle; + cvp_set_media_format_cmd.hdr.token = VOC_SET_MEDIA_FORMAT_PARAM_TOKEN; + cvp_set_media_format_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2; + + /* Fill param data */ + cvp_set_media_format_cmd.cvp_set_param_v2.mem_size = + sizeof(struct vss_icommon_param_data_t); + media_fmt_param_data->module_id = VSS_MODULE_CVD_GENERIC; + media_fmt_param_data->param_size = + sizeof(struct vss_param_endpoint_media_format_info_t); + + /* Fill device specific data */ + switch (param_type) { + case RX_PATH: + media_fmt_param_data->param_id = + VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO; + media_fmt_info->port_id = v->dev_rx.port_id; + media_fmt_info->num_channels = v->dev_rx.no_of_channels; + media_fmt_info->bits_per_sample = v->dev_rx.bits_per_sample; + media_fmt_info->sample_rate = v->dev_rx.sample_rate; + memcpy(&media_fmt_info->channel_mapping, + &v->dev_rx.channel_mapping, VSS_CHANNEL_MAPPING_SIZE); + break; + + case TX_PATH: + media_fmt_param_data->param_id = + VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO; + media_fmt_info->port_id = v->dev_tx.port_id; + media_fmt_info->num_channels = v->dev_tx.no_of_channels; + media_fmt_info->bits_per_sample = v->dev_tx.bits_per_sample; + media_fmt_info->sample_rate = v->dev_tx.sample_rate; + memcpy(&media_fmt_info->channel_mapping, + &v->dev_tx.channel_mapping, VSS_CHANNEL_MAPPING_SIZE); + break; + + case EC_REF_PATH: + media_fmt_param_data->param_id = + VSS_PARAM_EC_REF_PORT_ENDPOINT_MEDIA_INFO; + media_fmt_info->port_id = common.ec_media_fmt_info.port_id; + media_fmt_info->num_channels = + common.ec_media_fmt_info.num_channels; + media_fmt_info->bits_per_sample = + common.ec_media_fmt_info.bits_per_sample; + media_fmt_info->sample_rate = + common.ec_media_fmt_info.sample_rate; + memcpy(&media_fmt_info->channel_mapping, + &common.ec_media_fmt_info.channel_mapping, + VSS_CHANNEL_MAPPING_SIZE); + break; + + default: + pr_err("%s: Invalid param type %d\n", __func__, param_type); + ret = -EINVAL; + goto done; + } + + /* Send command */ + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_set_media_format_cmd); + if (ret < 0) { + pr_err("%s: Fail in sending VSS_ICOMMON_CMD_SET_PARAM_V2\n", + __func__); + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto done; + } + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s] handle = %d\n", __func__, + adsp_err_get_err_str(v->async_err), cvp_handle); + ret = adsp_err_get_lnx_err_code(v->async_err); + goto done; + } + +done: + return ret; +} + +static int voice_send_cvp_topology_commit_cmd(struct voice_data *v) +{ + int ret = 0; + struct apr_hdr cvp_topology_commit_cmd; + void *apr_cvp; + u16 cvp_handle; + + if (!(voice_get_cvd_int_version(common.cvd_version) >= + CVD_INT_VERSION_2_2)) { + pr_debug("%s CVD version string %s doesn't support this command\n", + __func__, common.cvd_version); + + goto done; + } + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + apr_cvp = common.apr_q6_cvp; + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL.\n", __func__); + + ret = -EINVAL; + goto done; + } + + cvp_handle = voice_get_cvp_handle(v); + cvp_topology_commit_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_topology_commit_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_topology_commit_cmd) - APR_HDR_SIZE); + cvp_topology_commit_cmd.src_port = + voice_get_idx_for_session(v->session_id); + cvp_topology_commit_cmd.dest_port = cvp_handle; + cvp_topology_commit_cmd.token = 0; + cvp_topology_commit_cmd.opcode = VSS_IVOCPROC_CMD_TOPOLOGY_COMMIT; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_topology_commit_cmd); + if (ret < 0) { + pr_err("%s: Fail in sending VSS_IVOCPROC_CMD_TOPOLOGY_COMMIT\n", + __func__); + + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto done; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto done; + } + +done: + return ret; +} + +static int voice_send_enable_vocproc_cmd(struct voice_data *v) +{ + int ret = 0; + struct apr_hdr cvp_enable_cmd; + void *apr_cvp; + u16 cvp_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_cvp = common.apr_q6_cvp; + + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL.\n", __func__); + return -EINVAL; + } + cvp_handle = voice_get_cvp_handle(v); + + /* enable vocproc and wait for respose */ + cvp_enable_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_enable_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_enable_cmd) - APR_HDR_SIZE); + pr_debug("cvp_enable_cmd pkt size = %d, cvp_handle=%d\n", + cvp_enable_cmd.pkt_size, cvp_handle); + cvp_enable_cmd.src_port = + voice_get_idx_for_session(v->session_id); + cvp_enable_cmd.dest_port = cvp_handle; + cvp_enable_cmd.token = 0; + cvp_enable_cmd.opcode = VSS_IVOCPROC_CMD_ENABLE; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_enable_cmd); + if (ret < 0) { + pr_err("Fail in sending VSS_IVOCPROC_CMD_ENABLE\n"); + goto fail; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + + return 0; +fail: + return ret; +} + +static int voice_send_mvm_cal_network_cmd(struct voice_data *v) +{ + struct vss_imvm_cmd_set_cal_network_t mvm_set_cal_network; + int ret = 0; + void *apr_mvm; + u16 mvm_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_mvm = common.apr_q6_mvm; + + if (!apr_mvm) { + pr_err("%s: apr_mvm is NULL.\n", __func__); + return -EINVAL; + } + mvm_handle = voice_get_mvm_handle(v); + + mvm_set_cal_network.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mvm_set_cal_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mvm_set_cal_network) - APR_HDR_SIZE); + mvm_set_cal_network.hdr.src_port = + voice_get_idx_for_session(v->session_id); + mvm_set_cal_network.hdr.dest_port = mvm_handle; + mvm_set_cal_network.hdr.token = 0; + mvm_set_cal_network.hdr.opcode = VSS_IMVM_CMD_SET_CAL_NETWORK; + mvm_set_cal_network.network_id = VSS_ICOMMON_CAL_NETWORK_ID_NONE; + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_cal_network); + if (ret < 0) { + pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret); + goto fail; + } + + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout %d\n", __func__, ret); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + return 0; +fail: + return ret; +} + +static int voice_send_netid_timing_cmd(struct voice_data *v) +{ + int ret = 0; + void *apr_mvm; + u16 mvm_handle; + struct mvm_set_network_cmd mvm_set_network; + struct mvm_set_voice_timing_cmd mvm_set_voice_timing; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_mvm = common.apr_q6_mvm; + + if (!apr_mvm) { + pr_err("%s: apr_mvm is NULL.\n", __func__); + return -EINVAL; + } + mvm_handle = voice_get_mvm_handle(v); + + ret = voice_config_cvs_vocoder(v); + if (ret < 0) { + pr_err("%s: Error %d configuring CVS voc", + __func__, ret); + goto fail; + } + /* Set network ID. */ + pr_debug("Setting network ID %x\n", common.mvs_info.network_type); + + mvm_set_network.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mvm_set_network.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mvm_set_network) - APR_HDR_SIZE); + mvm_set_network.hdr.src_port = + voice_get_idx_for_session(v->session_id); + mvm_set_network.hdr.dest_port = mvm_handle; + mvm_set_network.hdr.token = 0; + mvm_set_network.hdr.opcode = VSS_IMVM_CMD_SET_CAL_NETWORK; + mvm_set_network.network.network_id = common.mvs_info.network_type; + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_network); + if (ret < 0) { + pr_err("%s: Error %d sending SET_NETWORK\n", __func__, ret); + goto fail; + } + + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + + /* Set voice timing. */ + pr_debug("Setting voice timing\n"); + + mvm_set_voice_timing.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mvm_set_voice_timing.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mvm_set_voice_timing) - + APR_HDR_SIZE); + mvm_set_voice_timing.hdr.src_port = + voice_get_idx_for_session(v->session_id); + mvm_set_voice_timing.hdr.dest_port = mvm_handle; + mvm_set_voice_timing.hdr.token = 0; + mvm_set_voice_timing.hdr.opcode = VSS_ICOMMON_CMD_SET_VOICE_TIMING; + mvm_set_voice_timing.timing.mode = 0; + mvm_set_voice_timing.timing.enc_offset = 8000; + mvm_set_voice_timing.timing.dec_req_offset = 3300; + mvm_set_voice_timing.timing.dec_offset = 8300; + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_set_voice_timing); + if (ret < 0) { + pr_err("%s: Error %d sending SET_TIMING\n", __func__, ret); + goto fail; + } + + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + + return 0; +fail: + return ret; +} + +static int voice_send_attach_vocproc_cmd(struct voice_data *v) +{ + int ret = 0; + struct mvm_attach_vocproc_cmd mvm_a_vocproc_cmd; + void *apr_mvm; + u16 mvm_handle, cvp_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_mvm = common.apr_q6_mvm; + + if (!apr_mvm) { + pr_err("%s: apr_mvm is NULL.\n", __func__); + return -EINVAL; + } + mvm_handle = voice_get_mvm_handle(v); + cvp_handle = voice_get_cvp_handle(v); + + /* attach vocproc and wait for response */ + mvm_a_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mvm_a_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mvm_a_vocproc_cmd) - APR_HDR_SIZE); + pr_debug("send mvm_a_vocproc_cmd pkt size = %d\n", + mvm_a_vocproc_cmd.hdr.pkt_size); + mvm_a_vocproc_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + mvm_a_vocproc_cmd.hdr.dest_port = mvm_handle; + mvm_a_vocproc_cmd.hdr.token = 0; + mvm_a_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_ATTACH_VOCPROC; + mvm_a_vocproc_cmd.mvm_attach_cvp_handle.handle = cvp_handle; + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_a_vocproc_cmd); + if (ret < 0) { + pr_err("Fail in sending VSS_IMVM_CMD_ATTACH_VOCPROC\n"); + goto fail; + } + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + + return 0; +fail: + return ret; +} + +static void voc_update_session_params(struct voice_data *v) +{ + /* reset LCH mode */ + v->lch_mode = 0; + + /* clear disable topology setting */ + v->disable_topology = false; + + /* clear mute setting */ + v->dev_rx.dev_mute = common.default_mute_val; + v->dev_tx.dev_mute = common.default_mute_val; + v->stream_rx.stream_mute = common.default_mute_val; + v->stream_tx.stream_mute = common.default_mute_val; +} + +static int voice_destroy_vocproc(struct voice_data *v) +{ + struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd; + struct apr_hdr cvp_destroy_session_cmd; + int ret = 0; + void *apr_mvm, *apr_cvp; + u16 mvm_handle, cvp_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_mvm = common.apr_q6_mvm; + apr_cvp = common.apr_q6_cvp; + + if (!apr_mvm || !apr_cvp) { + pr_err("%s: apr_mvm or apr_cvp is NULL.\n", __func__); + return -EINVAL; + } + mvm_handle = voice_get_mvm_handle(v); + cvp_handle = voice_get_cvp_handle(v); + + /* disable slowtalk if st_enable is set */ + if (v->st_enable) + voice_send_set_pp_enable_cmd(v, MODULE_ID_VOICE_MODULE_ST, 0); + + /* Disable HD Voice if hd_enable is set */ + if (v->hd_enable) + voice_send_hd_cmd(v, 0); + + /* stop playback or recording */ + v->music_info.force = 1; + voice_cvs_stop_playback(v); + voice_cvs_stop_record(v); + /* If voice call is active during VoLTE, SRVCC happens. + * Start recording on voice session if recording started during VoLTE. + */ + if (is_volte_session(v->session_id) && + ((common.voice[VOC_PATH_PASSIVE].voc_state == VOC_RUN) || + (common.voice[VOC_PATH_PASSIVE].voc_state == VOC_CHANGE))) { + if (v->rec_info.rec_enable) { + voice_cvs_start_record( + &common.voice[VOC_PATH_PASSIVE], + v->rec_info.rec_mode); + common.srvcc_rec_flag = true; + + pr_debug("%s: switch recording, srvcc_rec_flag %d\n", + __func__, common.srvcc_rec_flag); + } + } + + /* send stop voice cmd */ + voice_send_stop_voice_cmd(v); + + /* send stop dtmf detecton cmd */ + if (v->dtmf_rx_detect_en) + voice_send_dtmf_rx_detection_cmd(v, 0); + + /* detach VOCPROC and wait for response from mvm */ + mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mvm_d_vocproc_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mvm_d_vocproc_cmd) - APR_HDR_SIZE); + pr_debug("mvm_d_vocproc_cmd pkt size = %d\n", + mvm_d_vocproc_cmd.hdr.pkt_size); + mvm_d_vocproc_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + mvm_d_vocproc_cmd.hdr.dest_port = mvm_handle; + mvm_d_vocproc_cmd.hdr.token = 0; + mvm_d_vocproc_cmd.hdr.opcode = VSS_IMVM_CMD_DETACH_VOCPROC; + mvm_d_vocproc_cmd.mvm_detach_cvp_handle.handle = cvp_handle; + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_d_vocproc_cmd); + if (ret < 0) { + pr_err("Fail in sending VSS_IMVM_CMD_DETACH_VOCPROC\n"); + goto fail; + } + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + + voice_send_cvp_deregister_vol_cal_cmd(v); + voice_send_cvp_deregister_cal_cmd(v); + voice_send_cvp_deregister_dev_cfg_cmd(v); + voice_send_cvs_deregister_cal_cmd(v); + + /* destrop cvp session */ + cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_destroy_session_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_destroy_session_cmd) - APR_HDR_SIZE); + pr_debug("cvp_destroy_session_cmd pkt size = %d\n", + cvp_destroy_session_cmd.pkt_size); + cvp_destroy_session_cmd.src_port = + voice_get_idx_for_session(v->session_id); + cvp_destroy_session_cmd.dest_port = cvp_handle; + cvp_destroy_session_cmd.token = 0; + cvp_destroy_session_cmd.opcode = APRV2_IBASIC_CMD_DESTROY_SESSION; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_destroy_session_cmd); + if (ret < 0) { + pr_err("Fail in sending APRV2_IBASIC_CMD_DESTROY_SESSION\n"); + goto fail; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + + rtac_remove_voice(voice_get_cvs_handle(v)); + cvp_handle = 0; + voice_set_cvp_handle(v, cvp_handle); + return 0; +fail: + return ret; +} + +static int voice_send_mvm_unmap_memory_physical_cmd(struct voice_data *v, + uint32_t mem_handle) +{ + struct vss_imemory_cmd_unmap_t mem_unmap; + int ret = 0; + void *apr_mvm; + u16 mvm_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_mvm = common.apr_q6_mvm; + + if (!apr_mvm) { + pr_err("%s: apr_mvm is NULL.\n", __func__); + return -EINVAL; + } + mvm_handle = voice_get_mvm_handle(v); + + mem_unmap.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mem_unmap.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mem_unmap) - APR_HDR_SIZE); + mem_unmap.hdr.src_port = + voice_get_idx_for_session(v->session_id); + mem_unmap.hdr.dest_port = mvm_handle; + mem_unmap.hdr.token = 0; + mem_unmap.hdr.opcode = VSS_IMEMORY_CMD_UNMAP; + mem_unmap.mem_handle = mem_handle; + + pr_debug("%s: mem_handle: 0x%x\n", __func__, mem_unmap.mem_handle); + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_mvm, (uint32_t *) &mem_unmap); + if (ret < 0) { + pr_err("mem_unmap op[0x%x]ret[%d]\n", + mem_unmap.hdr.opcode, ret); + goto fail; + } + + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout %d\n", __func__, ret); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + return 0; + +fail: + return ret; +} + +static int voice_send_cvs_packet_exchange_config_cmd(struct voice_data *v) +{ + struct vss_istream_cmd_set_oob_packet_exchange_config_t + packet_exchange_config_pkt; + int ret = 0; + void *apr_cvs; + u16 cvs_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + + apr_cvs = common.apr_q6_cvs; + + if (!apr_cvs) { + pr_err("%s: apr_cvs is NULL.\n", __func__); + return -EINVAL; + } + cvs_handle = voice_get_cvs_handle(v); + + packet_exchange_config_pkt.hdr.hdr_field = APR_HDR_FIELD( + APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + packet_exchange_config_pkt.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(packet_exchange_config_pkt) - + APR_HDR_SIZE); + packet_exchange_config_pkt.hdr.src_port = + voice_get_idx_for_session(v->session_id); + packet_exchange_config_pkt.hdr.dest_port = cvs_handle; + packet_exchange_config_pkt.hdr.token = 0; + packet_exchange_config_pkt.hdr.opcode = + VSS_ISTREAM_CMD_SET_OOB_PACKET_EXCHANGE_CONFIG; + packet_exchange_config_pkt.mem_handle = v->shmem_info.mem_handle; + /* dec buffer address */ + packet_exchange_config_pkt.dec_buf_addr_lsw = + lower_32_bits(v->shmem_info.sh_buf.buf[0].phys); + packet_exchange_config_pkt.dec_buf_addr_msw = + msm_audio_populate_upper_32_bits( + v->shmem_info.sh_buf.buf[0].phys); + packet_exchange_config_pkt.dec_buf_size = 4096; + /* enc buffer address */ + packet_exchange_config_pkt.enc_buf_addr_lsw = + lower_32_bits(v->shmem_info.sh_buf.buf[1].phys); + packet_exchange_config_pkt.enc_buf_addr_msw = + msm_audio_populate_upper_32_bits( + v->shmem_info.sh_buf.buf[1].phys); + packet_exchange_config_pkt.enc_buf_size = 4096; + + pr_debug("%s: dec buf add: lsw %0x msw %0x, size %d, enc buf add: lsw %0x msw %0x, size %d\n", + __func__, + packet_exchange_config_pkt.dec_buf_addr_lsw, + packet_exchange_config_pkt.dec_buf_addr_msw, + packet_exchange_config_pkt.dec_buf_size, + packet_exchange_config_pkt.enc_buf_addr_lsw, + packet_exchange_config_pkt.enc_buf_addr_msw, + packet_exchange_config_pkt.enc_buf_size); + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvs, (uint32_t *) &packet_exchange_config_pkt); + if (ret < 0) { + pr_err("Failed to send packet exchange config cmd %d\n", ret); + goto fail; + } + + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) + pr_err("%s: wait_event timeout %d\n", __func__, ret); + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + + return 0; +fail: + return ret; +} + +static int voice_send_cvs_data_exchange_mode_cmd(struct voice_data *v) +{ + struct vss_istream_cmd_set_packet_exchange_mode_t data_exchange_pkt; + int ret = 0; + void *apr_cvs; + u16 cvs_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_cvs = common.apr_q6_cvs; + + if (!apr_cvs) { + pr_err("%s: apr_cvs is NULL.\n", __func__); + return -EINVAL; + } + cvs_handle = voice_get_cvs_handle(v); + + data_exchange_pkt.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + data_exchange_pkt.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(data_exchange_pkt) - APR_HDR_SIZE); + data_exchange_pkt.hdr.src_port = + voice_get_idx_for_session(v->session_id); + data_exchange_pkt.hdr.dest_port = cvs_handle; + data_exchange_pkt.hdr.token = 0; + data_exchange_pkt.hdr.opcode = VSS_ISTREAM_CMD_SET_PACKET_EXCHANGE_MODE; + data_exchange_pkt.mode = VSS_ISTREAM_PACKET_EXCHANGE_MODE_OUT_OF_BAND; + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvs, (uint32_t *) &data_exchange_pkt); + if (ret < 0) { + pr_err("Failed to send data exchange mode %d\n", ret); + goto fail; + } + + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) + pr_err("%s: wait_event timeout %d\n", __func__, ret); + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + return 0; +fail: + return ret; +} + +static int voice_send_stream_mute_cmd(struct voice_data *v, uint16_t direction, + uint16_t mute_flag, uint32_t ramp_duration) +{ + struct cvs_set_mute_cmd cvs_mute_cmd; + int ret = 0; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + ret = -EINVAL; + goto fail; + } + + if (!common.apr_q6_cvs) { + pr_err("%s: apr_cvs is NULL.\n", __func__); + ret = -EINVAL; + goto fail; + } + + /* send mute/unmute to cvs */ + cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvs_mute_cmd) - APR_HDR_SIZE); + cvs_mute_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvs_mute_cmd.hdr.dest_port = voice_get_cvs_handle(v); + cvs_mute_cmd.hdr.token = 0; + cvs_mute_cmd.hdr.opcode = VSS_IVOLUME_CMD_MUTE_V2; + cvs_mute_cmd.cvs_set_mute.direction = direction; + cvs_mute_cmd.cvs_set_mute.mute_flag = mute_flag; + cvs_mute_cmd.cvs_set_mute.ramp_duration_ms = ramp_duration; + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(common.apr_q6_cvs, (uint32_t *) &cvs_mute_cmd); + if (ret < 0) { + pr_err("%s: Error %d sending stream mute\n", __func__, ret); + + goto fail; + } + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Command timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + + return 0; + +fail: + return ret; +} + +static int voice_send_device_mute_cmd(struct voice_data *v, uint16_t direction, + uint16_t mute_flag, uint32_t ramp_duration) +{ + struct cvp_set_mute_cmd cvp_mute_cmd; + int ret = 0; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + ret = -EINVAL; + goto fail; + } + + if (!common.apr_q6_cvp) { + pr_err("%s: apr_cvp is NULL.\n", __func__); + ret = -EINVAL; + goto fail; + } + + cvp_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_mute_cmd) - APR_HDR_SIZE); + cvp_mute_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_mute_cmd.hdr.dest_port = voice_get_cvp_handle(v); + cvp_mute_cmd.hdr.token = 0; + cvp_mute_cmd.hdr.opcode = VSS_IVOLUME_CMD_MUTE_V2; + cvp_mute_cmd.cvp_set_mute.direction = direction; + cvp_mute_cmd.cvp_set_mute.mute_flag = mute_flag; + cvp_mute_cmd.cvp_set_mute.ramp_duration_ms = ramp_duration; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(common.apr_q6_cvp, (uint32_t *) &cvp_mute_cmd); + if (ret < 0) { + pr_err("%s: Error %d sending rx device cmd\n", __func__, ret); + + goto fail; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Command timeout\n", __func__); + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + + return 0; + +fail: + return ret; +} + +static int voice_send_vol_step_cmd(struct voice_data *v) +{ + struct cvp_set_rx_volume_step_cmd cvp_vol_step_cmd; + int ret = 0; + void *apr_cvp; + u16 cvp_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_cvp = common.apr_q6_cvp; + + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL.\n", __func__); + return -EINVAL; + } + cvp_handle = voice_get_cvp_handle(v); + + /* send volume index to cvp */ + cvp_vol_step_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_vol_step_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_vol_step_cmd) - APR_HDR_SIZE); + cvp_vol_step_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_vol_step_cmd.hdr.dest_port = cvp_handle; + cvp_vol_step_cmd.hdr.token = 0; + cvp_vol_step_cmd.hdr.opcode = VSS_IVOLUME_CMD_SET_STEP; + cvp_vol_step_cmd.cvp_set_vol_step.direction = VSS_IVOLUME_DIRECTION_RX; + cvp_vol_step_cmd.cvp_set_vol_step.value = v->dev_rx.volume_step_value; + cvp_vol_step_cmd.cvp_set_vol_step.ramp_duration_ms = + v->dev_rx.volume_ramp_duration_ms; + pr_debug("%s step_value:%d, ramp_duration_ms:%d", + __func__, + cvp_vol_step_cmd.cvp_set_vol_step.value, + cvp_vol_step_cmd.cvp_set_vol_step.ramp_duration_ms); + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_vol_step_cmd); + if (ret < 0) { + pr_err("Fail in sending RX VOL step\n"); + return -EINVAL; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + return -EINVAL; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + return ret; + } + return 0; +} + +static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode) +{ + int ret = 0; + void *apr_cvs; + u16 cvs_handle; + + struct cvs_start_record_cmd cvs_start_record; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_cvs = common.apr_q6_cvs; + + if (!apr_cvs) { + pr_err("%s: apr_cvs is NULL.\n", __func__); + return -EINVAL; + } + + cvs_handle = voice_get_cvs_handle(v); + + if (!v->rec_info.recording) { + cvs_start_record.hdr.hdr_field = APR_HDR_FIELD( + APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvs_start_record.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvs_start_record) - APR_HDR_SIZE); + cvs_start_record.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvs_start_record.hdr.dest_port = cvs_handle; + cvs_start_record.hdr.token = 0; + cvs_start_record.hdr.opcode = VSS_IRECORD_CMD_START; + + cvs_start_record.rec_mode.port_id = + VSS_IRECORD_PORT_ID_DEFAULT; + if (rec_mode == VOC_REC_UPLINK) { + cvs_start_record.rec_mode.rx_tap_point = + VSS_IRECORD_TAP_POINT_NONE; + cvs_start_record.rec_mode.tx_tap_point = + VSS_IRECORD_TAP_POINT_STREAM_END; + } else if (rec_mode == VOC_REC_DOWNLINK) { + cvs_start_record.rec_mode.rx_tap_point = + VSS_IRECORD_TAP_POINT_STREAM_END; + cvs_start_record.rec_mode.tx_tap_point = + VSS_IRECORD_TAP_POINT_NONE; + } else if (rec_mode == VOC_REC_BOTH) { + cvs_start_record.rec_mode.rx_tap_point = + VSS_IRECORD_TAP_POINT_STREAM_END; + cvs_start_record.rec_mode.tx_tap_point = + VSS_IRECORD_TAP_POINT_STREAM_END; + } else { + pr_err("%s: Invalid in-call rec_mode %d\n", __func__, + rec_mode); + + ret = -EINVAL; + goto fail; + } + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_record); + if (ret < 0) { + pr_err("%s: Error %d sending START_RECORD\n", __func__, + ret); + + goto fail; + } + + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + v->rec_info.recording = 1; + } else { + pr_debug("%s: Start record already sent\n", __func__); + } + + return 0; + +fail: + return ret; +} + +static int voice_cvs_stop_record(struct voice_data *v) +{ + int ret = 0; + void *apr_cvs; + u16 cvs_handle; + struct apr_hdr cvs_stop_record; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_cvs = common.apr_q6_cvs; + + if (!apr_cvs) { + pr_err("%s: apr_cvs is NULL.\n", __func__); + return -EINVAL; + } + + cvs_handle = voice_get_cvs_handle(v); + + if (v->rec_info.recording) { + cvs_stop_record.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cvs_stop_record.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvs_stop_record) - APR_HDR_SIZE); + cvs_stop_record.src_port = + voice_get_idx_for_session(v->session_id); + cvs_stop_record.dest_port = cvs_handle; + cvs_stop_record.token = 0; + cvs_stop_record.opcode = VSS_IRECORD_CMD_STOP; + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_record); + if (ret < 0) { + pr_err("%s: Error %d sending STOP_RECORD\n", + __func__, ret); + + goto fail; + } + + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + v->rec_info.recording = 0; + } else { + pr_debug("%s: Stop record already sent\n", __func__); + } + + return 0; + +fail: + return ret; +} + +int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id) +{ + int ret = 0; + int rec_mode = 0; + u16 cvs_handle; + int rec_set = 0; + struct voice_session_itr itr; + struct voice_data *v = NULL; + + /* check if session_id is valid */ + if (!voice_is_valid_session_id(session_id)) { + pr_err("%s: Invalid session id:%u\n", __func__, + session_id); + + return -EINVAL; + } + + voice_itr_init(&itr, session_id); + pr_debug("%s: session_id:%u\n", __func__, session_id); + + while (voice_itr_get_next_session(&itr, &v)) { + if (v == NULL) { + pr_err("%s: v is NULL, sessionid:%u\n", __func__, + session_id); + + break; + } + pr_debug("%s: port_id: %d, set: %d, v: %pK\n", + __func__, port_id, set, v); + + mutex_lock(&v->lock); + rec_mode = v->rec_info.rec_mode; + rec_set = set; + if (set) { + if ((v->rec_route_state.ul_flag != 0) && + (v->rec_route_state.dl_flag != 0)) { + pr_debug("%s: rec mode already set.\n", + __func__); + + mutex_unlock(&v->lock); + continue; + } + + if (port_id == VOICE_RECORD_TX) { + if ((v->rec_route_state.ul_flag == 0) + && (v->rec_route_state.dl_flag == 0)) { + rec_mode = VOC_REC_UPLINK; + v->rec_route_state.ul_flag = 1; + } else if ((v->rec_route_state.ul_flag == 0) + && (v->rec_route_state.dl_flag != 0)) { + voice_cvs_stop_record(v); + rec_mode = VOC_REC_BOTH; + v->rec_route_state.ul_flag = 1; + } + } else if (port_id == VOICE_RECORD_RX) { + if ((v->rec_route_state.ul_flag == 0) + && (v->rec_route_state.dl_flag == 0)) { + rec_mode = VOC_REC_DOWNLINK; + v->rec_route_state.dl_flag = 1; + } else if ((v->rec_route_state.ul_flag != 0) + && (v->rec_route_state.dl_flag == 0)) { + voice_cvs_stop_record(v); + rec_mode = VOC_REC_BOTH; + v->rec_route_state.dl_flag = 1; + } + } + rec_set = 1; + } else { + if ((v->rec_route_state.ul_flag == 0) && + (v->rec_route_state.dl_flag == 0)) { + pr_debug("%s: rec already stops.\n", + __func__); + mutex_unlock(&v->lock); + continue; + } + + if (port_id == VOICE_RECORD_TX) { + if ((v->rec_route_state.ul_flag != 0) + && (v->rec_route_state.dl_flag == 0)) { + v->rec_route_state.ul_flag = 0; + rec_set = 0; + } else if ((v->rec_route_state.ul_flag != 0) + && (v->rec_route_state.dl_flag != 0)) { + voice_cvs_stop_record(v); + v->rec_route_state.ul_flag = 0; + rec_mode = VOC_REC_DOWNLINK; + rec_set = 1; + } + } else if (port_id == VOICE_RECORD_RX) { + if ((v->rec_route_state.ul_flag == 0) + && (v->rec_route_state.dl_flag != 0)) { + v->rec_route_state.dl_flag = 0; + rec_set = 0; + } else if ((v->rec_route_state.ul_flag != 0) + && (v->rec_route_state.dl_flag != 0)) { + voice_cvs_stop_record(v); + v->rec_route_state.dl_flag = 0; + rec_mode = VOC_REC_UPLINK; + rec_set = 1; + } + } + } + pr_debug("%s: mode =%d, set =%d\n", __func__, + rec_mode, rec_set); + cvs_handle = voice_get_cvs_handle(v); + + if (cvs_handle != 0) { + if (rec_set) + ret = voice_cvs_start_record(v, rec_mode); + else + ret = voice_cvs_stop_record(v); + } + + /* During SRVCC, recording will switch from VoLTE session to + * voice session. + * Then stop recording, need to stop recording on voice session. + */ + if ((!rec_set) && common.srvcc_rec_flag) { + pr_debug("%s, srvcc_rec_flag:%d\n", __func__, + common.srvcc_rec_flag); + + voice_cvs_stop_record(&common.voice[VOC_PATH_PASSIVE]); + common.srvcc_rec_flag = false; + } + + /* Cache the value */ + v->rec_info.rec_enable = rec_set; + v->rec_info.rec_mode = rec_mode; + + mutex_unlock(&v->lock); + } + + return ret; +} + +static int voice_cvs_start_playback(struct voice_data *v) +{ + int ret = 0; + struct cvs_start_playback_cmd cvs_start_playback; + void *apr_cvs; + u16 cvs_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_cvs = common.apr_q6_cvs; + + if (!apr_cvs) { + pr_err("%s: apr_cvs is NULL.\n", __func__); + return -EINVAL; + } + + cvs_handle = voice_get_cvs_handle(v); + + if (!v->music_info.playing && v->music_info.count) { + cvs_start_playback.hdr.hdr_field = APR_HDR_FIELD( + APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvs_start_playback.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvs_start_playback) - APR_HDR_SIZE); + cvs_start_playback.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvs_start_playback.hdr.dest_port = cvs_handle; + cvs_start_playback.hdr.token = 0; + cvs_start_playback.hdr.opcode = VSS_IPLAYBACK_CMD_START; + cvs_start_playback.playback_mode.port_id = + v->music_info.port_id; + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_start_playback); + + if (ret < 0) { + pr_err("%s: Error %d sending START_PLAYBACK\n", + __func__, ret); + + goto fail; + } + + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + + v->music_info.playing = 1; + } else { + pr_debug("%s: Start playback already sent\n", __func__); + } + + return 0; + +fail: + return ret; +} + +static int voice_cvs_stop_playback(struct voice_data *v) +{ + int ret = 0; + struct apr_hdr cvs_stop_playback; + void *apr_cvs; + u16 cvs_handle; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_cvs = common.apr_q6_cvs; + + if (!apr_cvs) { + pr_err("%s: apr_cvs is NULL.\n", __func__); + return -EINVAL; + } + + cvs_handle = voice_get_cvs_handle(v); + + if (v->music_info.playing && ((!v->music_info.count) || + (v->music_info.force))) { + cvs_stop_playback.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cvs_stop_playback.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvs_stop_playback) - APR_HDR_SIZE); + cvs_stop_playback.src_port = + voice_get_idx_for_session(v->session_id); + cvs_stop_playback.dest_port = cvs_handle; + cvs_stop_playback.token = 0; + + cvs_stop_playback.opcode = VSS_IPLAYBACK_CMD_STOP; + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_stop_playback); + if (ret < 0) { + pr_err("%s: Error %d sending STOP_PLAYBACK\n", + __func__, ret); + + + goto fail; + } + + ret = wait_event_timeout(v->cvs_wait, + (v->cvs_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + + v->music_info.playing = 0; + v->music_info.force = 0; + } else { + pr_debug("%s: Stop playback already sent\n", __func__); + } + + return 0; + +fail: + return ret; +} + +static int voc_lch_ops(struct voice_data *v, enum voice_lch_mode lch_mode) +{ + int ret = 0; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + switch (lch_mode) { + case VOICE_LCH_START: + + ret = voc_end_voice_call(v->session_id); + if (ret < 0) + pr_err("%s: voice call end failed %d\n", + __func__, ret); + break; + case VOICE_LCH_STOP: + + ret = voc_start_voice_call(v->session_id); + if (ret < 0) { + pr_err("%s: voice call start failed %d\n", + __func__, ret); + goto done; + } + break; + default: + pr_err("%s: Invalid LCH mode: %d\n", + __func__, v->lch_mode); + break; + } +done: + return ret; +} + +int voc_start_playback(uint32_t set, uint16_t port_id) +{ + struct voice_data *v = NULL; + int ret = 0; + struct voice_session_itr itr; + u16 cvs_handle; + + pr_debug("%s port_id = %#x set = %d", __func__, port_id, set); + + voice_itr_init(&itr, ALL_SESSION_VSID); + while (voice_itr_get_next_session(&itr, &v)) { + if ((v != NULL) && + (((port_id == VOICE_PLAYBACK_TX) && + is_sub1_vsid(v->session_id)) || + ((port_id == VOICE2_PLAYBACK_TX) && + is_sub2_vsid(v->session_id)))) { + + mutex_lock(&v->lock); + v->music_info.port_id = port_id; + v->music_info.play_enable = set; + if (set) + v->music_info.count++; + else + v->music_info.count--; + pr_debug("%s: music_info count=%d\n", __func__, + v->music_info.count); + + cvs_handle = voice_get_cvs_handle(v); + if (cvs_handle != 0) { + if (set) + ret = voice_cvs_start_playback(v); + else + ret = voice_cvs_stop_playback(v); + } + mutex_unlock(&v->lock); + } else { + pr_err("%s: Invalid session\n", __func__); + } + } + + return ret; +} + +int voc_disable_topology(uint32_t session_id, uint32_t disable) +{ + struct voice_data *v = voice_get_session(session_id); + int ret = 0; + + if (v == NULL) { + pr_err("%s: invalid session_id 0x%x\n", __func__, session_id); + + return -EINVAL; + } + + mutex_lock(&v->lock); + + v->disable_topology = disable; + + mutex_unlock(&v->lock); + + return ret; +} + +static int voice_set_packet_exchange_mode_and_config(uint32_t session_id, + uint32_t mode) +{ + struct voice_data *v = voice_get_session(session_id); + int ret = 0; + + if (v == NULL) { + pr_err("%s: invalid session_id 0x%x\n", __func__, session_id); + return -EINVAL; + } + + if (v->voc_state != VOC_RUN) + ret = voice_send_cvs_data_exchange_mode_cmd(v); + + if (ret) { + pr_err("%s: Error voice_send_data_exchange_mode_cmd %d\n", + __func__, ret); + goto fail; + } + + ret = voice_send_cvs_packet_exchange_config_cmd(v); + if (ret) { + pr_err("%s: Error: voice_send_packet_exchange_config_cmd %d\n", + __func__, ret); + goto fail; + } + + return ret; +fail: + return -EINVAL; +} + +int voc_set_tx_mute(uint32_t session_id, uint32_t dir, uint32_t mute, + uint32_t ramp_duration) +{ + struct voice_data *v = NULL; + int ret = 0; + struct voice_session_itr itr; + + voice_itr_init(&itr, session_id); + while (voice_itr_get_next_session(&itr, &v)) { + if (v != NULL) { + mutex_lock(&v->lock); + v->stream_tx.stream_mute = mute; + v->stream_tx.stream_mute_ramp_duration_ms = + ramp_duration; + if (is_voc_state_active(v->voc_state) && + (v->lch_mode == 0)) + ret = voice_send_stream_mute_cmd(v, + VSS_IVOLUME_DIRECTION_TX, + v->stream_tx.stream_mute, + v->stream_tx.stream_mute_ramp_duration_ms); + mutex_unlock(&v->lock); + } else { + pr_err("%s: invalid session_id 0x%x\n", __func__, + session_id); + + ret = -EINVAL; + break; + } + } + + return ret; +} + +int voc_set_device_mute(uint32_t session_id, uint32_t dir, uint32_t mute, + uint32_t ramp_duration) +{ + struct voice_data *v = NULL; + int ret = 0; + struct voice_session_itr itr; + + voice_itr_init(&itr, session_id); + while (voice_itr_get_next_session(&itr, &v)) { + if (v != NULL) { + mutex_lock(&v->lock); + if (dir == VSS_IVOLUME_DIRECTION_TX) { + v->dev_tx.dev_mute = mute; + v->dev_tx.dev_mute_ramp_duration_ms = + ramp_duration; + } else { + v->dev_rx.dev_mute = mute; + v->dev_rx.dev_mute_ramp_duration_ms = + ramp_duration; + } + + if (((v->voc_state == VOC_RUN) || + (v->voc_state == VOC_STANDBY)) && + (v->lch_mode == 0)) + ret = voice_send_device_mute_cmd(v, + dir, + mute, + ramp_duration); + mutex_unlock(&v->lock); + } else { + pr_err("%s: invalid session_id 0x%x\n", __func__, + session_id); + + ret = -EINVAL; + break; + } + } + + return ret; +} + +int voc_get_rx_device_mute(uint32_t session_id) +{ + struct voice_data *v = voice_get_session(session_id); + int ret = 0; + + if (v == NULL) { + pr_err("%s: invalid session_id 0x%x\n", __func__, session_id); + + return -EINVAL; + } + + mutex_lock(&v->lock); + + ret = v->dev_rx.dev_mute; + + mutex_unlock(&v->lock); + + return ret; +} + +int voc_set_tty_mode(uint32_t session_id, uint8_t tty_mode) +{ + struct voice_data *v = voice_get_session(session_id); + int ret = 0; + + if (v == NULL) { + pr_err("%s: invalid session_id 0x%x\n", __func__, session_id); + + return -EINVAL; + } + + mutex_lock(&v->lock); + + v->tty_mode = tty_mode; + + mutex_unlock(&v->lock); + + return ret; +} + +uint8_t voc_get_tty_mode(uint32_t session_id) +{ + struct voice_data *v = voice_get_session(session_id); + int ret = 0; + + if (v == NULL) { + pr_err("%s: invalid session_id 0x%x\n", __func__, session_id); + + return -EINVAL; + } + + mutex_lock(&v->lock); + + ret = v->tty_mode; + + mutex_unlock(&v->lock); + + return ret; +} + +int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, uint32_t enable) +{ + struct voice_data *v = NULL; + int ret = 0; + struct voice_session_itr itr; + + voice_itr_init(&itr, session_id); + while (voice_itr_get_next_session(&itr, &v)) { + if (v != NULL) { + if (!(is_voice_app_id(v->session_id))) + continue; + + mutex_lock(&v->lock); + if (module_id == MODULE_ID_VOICE_MODULE_ST) + v->st_enable = enable; + + if (v->voc_state == VOC_RUN) { + if ((module_id == MODULE_ID_VOICE_MODULE_ST) && + (!v->tty_mode)) + ret = voice_send_set_pp_enable_cmd(v, + MODULE_ID_VOICE_MODULE_ST, + enable); + } + mutex_unlock(&v->lock); + } else { + pr_err("%s: invalid session_id 0x%x\n", __func__, + session_id); + ret = -EINVAL; + break; + } + } + + return ret; +} + +int voc_set_hd_enable(uint32_t session_id, uint32_t enable) +{ + struct voice_data *v = NULL; + int ret = 0; + struct voice_session_itr itr; + + voice_itr_init(&itr, session_id); + while (voice_itr_get_next_session(&itr, &v)) { + if (v != NULL) { + mutex_lock(&v->lock); + v->hd_enable = enable; + + if (v->voc_state == VOC_RUN) + ret = voice_send_hd_cmd(v, enable); + + mutex_unlock(&v->lock); + } else { + pr_err("%s: invalid session_id 0x%x\n", __func__, + session_id); + ret = -EINVAL; + break; + } + } + + return ret; +} + +int voc_set_afe_sidetone(uint32_t session_id, bool sidetone_enable) +{ + struct voice_data *v = NULL; + int ret = -EINVAL; + struct voice_session_itr itr; + u16 rx_port, tx_port; + + common.sidetone_enable = sidetone_enable; + voice_itr_init(&itr, session_id); + while (voice_itr_get_next_session(&itr, &v)) { + if (v == NULL) { + pr_err("%s: invalid session_id 0x%x\n", __func__, + session_id); + ret = -EINVAL; + break; + } + mutex_lock(&v->lock); + if (v->voc_state != VOC_RUN) { + mutex_unlock(&v->lock); + continue; + } + rx_port = v->dev_rx.port_id; + tx_port = v->dev_tx.port_id; + ret = afe_sidetone_enable(tx_port, rx_port, + sidetone_enable); + if (!ret) { + mutex_unlock(&v->lock); + break; + } + mutex_unlock(&v->lock); + } + return ret; +} + +bool voc_get_afe_sidetone(void) +{ + bool ret; + + ret = common.sidetone_enable; + return ret; +} + +int voc_get_pp_enable(uint32_t session_id, uint32_t module_id) +{ + struct voice_data *v = voice_get_session(session_id); + int ret = 0; + + if (v == NULL) { + pr_err("%s: invalid session_id 0x%x\n", __func__, session_id); + + return -EINVAL; + } + + mutex_lock(&v->lock); + if (module_id == MODULE_ID_VOICE_MODULE_ST) + ret = v->st_enable; + mutex_unlock(&v->lock); + + return ret; +} + +int voc_set_rx_vol_step(uint32_t session_id, uint32_t dir, uint32_t vol_step, + uint32_t ramp_duration) +{ + struct voice_data *v = NULL; + int ret = 0; + struct voice_session_itr itr; + + pr_debug("%s session id = %#x vol = %u", __func__, session_id, + vol_step); + + voice_itr_init(&itr, session_id); + while (voice_itr_get_next_session(&itr, &v)) { + if (v != NULL) { + mutex_lock(&v->lock); + v->dev_rx.volume_step_value = vol_step; + v->dev_rx.volume_ramp_duration_ms = ramp_duration; + if (is_voc_state_active(v->voc_state)) + ret = voice_send_vol_step_cmd(v); + mutex_unlock(&v->lock); + } else { + pr_err("%s: invalid session_id 0x%x\n", __func__, + session_id); + + ret = -EINVAL; + break; + } + } + + return ret; +} + +int voc_set_device_config(uint32_t session_id, uint8_t path_dir, + struct media_format_info *finfo) +{ + struct voice_data *v = voice_get_session(session_id); + + if (v == NULL) { + pr_err("%s: Invalid session_id 0x%x\n", __func__, session_id); + + return -EINVAL; + } + + pr_debug("%s: path_dir=%d port_id=%x, channels=%d, sample_rate=%d, bits_per_sample=%d\n", + __func__, path_dir, finfo->port_id, finfo->num_channels, + finfo->sample_rate, finfo->bits_per_sample); + + mutex_lock(&v->lock); + switch (path_dir) { + case RX_PATH: + v->dev_rx.port_id = q6audio_get_port_id(finfo->port_id); + v->dev_rx.no_of_channels = finfo->num_channels; + v->dev_rx.sample_rate = finfo->sample_rate; + v->dev_rx.bits_per_sample = finfo->bits_per_sample; + memcpy(&v->dev_rx.channel_mapping, &finfo->channel_mapping, + VSS_CHANNEL_MAPPING_SIZE); + break; + case TX_PATH: + v->dev_tx.port_id = q6audio_get_port_id(finfo->port_id); + v->dev_tx.no_of_channels = finfo->num_channels; + v->dev_tx.sample_rate = finfo->sample_rate; + v->dev_tx.bits_per_sample = finfo->bits_per_sample; + memcpy(&v->dev_tx.channel_mapping, &finfo->channel_mapping, + VSS_CHANNEL_MAPPING_SIZE); + break; + default: + pr_err("%s: Invalid path_dir %d\n", __func__, path_dir); + return -EINVAL; + } + + mutex_unlock(&v->lock); + + return 0; +} + +int voc_set_ext_ec_ref_media_fmt_info(struct media_format_info *finfo) +{ + mutex_lock(&common.common_lock); + if (common.ec_ref_ext) { + common.ec_media_fmt_info.num_channels = finfo->num_channels; + common.ec_media_fmt_info.bits_per_sample = + finfo->bits_per_sample; + common.ec_media_fmt_info.sample_rate = finfo->sample_rate; + memcpy(&common.ec_media_fmt_info.channel_mapping, + &finfo->channel_mapping, VSS_CHANNEL_MAPPING_SIZE); + } else { + pr_debug("%s: Ext Ec Ref not active, returning", __func__); + } + mutex_unlock(&common.common_lock); + return 0; +} + +int voc_set_route_flag(uint32_t session_id, uint8_t path_dir, uint8_t set) +{ + struct voice_data *v = voice_get_session(session_id); + + if (v == NULL) { + pr_err("%s: invalid session_id 0x%x\n", __func__, session_id); + + return -EINVAL; + } + + pr_debug("%s: path_dir=%d, set=%d\n", __func__, path_dir, set); + + mutex_lock(&v->lock); + + if (path_dir == RX_PATH) + v->voc_route_state.rx_route_flag = set; + else + v->voc_route_state.tx_route_flag = set; + + mutex_unlock(&v->lock); + + return 0; +} + +uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir) +{ + struct voice_data *v = voice_get_session(session_id); + int ret = 0; + + if (v == NULL) { + pr_err("%s: invalid session_id 0x%x\n", __func__, session_id); + + return 0; + } + + mutex_lock(&v->lock); + + if (path_dir == RX_PATH) + ret = v->voc_route_state.rx_route_flag; + else + ret = v->voc_route_state.tx_route_flag; + + mutex_unlock(&v->lock); + + return ret; +} + +int voc_end_voice_call(uint32_t session_id) +{ + struct voice_data *v = voice_get_session(session_id); + int ret = 0; + + if (v == NULL) { + pr_err("%s: invalid session_id 0x%x\n", __func__, session_id); + + return -EINVAL; + } + + mutex_lock(&v->lock); + + if (v->voc_state == VOC_RUN || v->voc_state == VOC_ERROR || + v->voc_state == VOC_CHANGE || v->voc_state == VOC_STANDBY) { + + pr_debug("%s: VOC_STATE: %d\n", __func__, v->voc_state); + + ret = voice_destroy_vocproc(v); + if (ret < 0) + pr_err("%s: destroy voice failed\n", __func__); + + voc_update_session_params(v); + + voice_destroy_mvm_cvs_session(v); + v->voc_state = VOC_RELEASE; + } else { + pr_err("%s: Error: End voice called in state %d\n", + __func__, v->voc_state); + + ret = -EINVAL; + } + + mutex_unlock(&v->lock); + return ret; +} + +int voc_standby_voice_call(uint32_t session_id) +{ + struct voice_data *v = voice_get_session(session_id); + struct apr_hdr mvm_standby_voice_cmd; + void *apr_mvm; + u16 mvm_handle; + int ret = 0; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: voc state=%d", __func__, v->voc_state); + + if (v->voc_state == VOC_RUN) { + apr_mvm = common.apr_q6_mvm; + if (!apr_mvm) { + pr_err("%s: apr_mvm is NULL.\n", __func__); + ret = -EINVAL; + goto fail; + } + mvm_handle = voice_get_mvm_handle(v); + mvm_standby_voice_cmd.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + mvm_standby_voice_cmd.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mvm_standby_voice_cmd) - APR_HDR_SIZE); + pr_debug("send mvm_standby_voice_cmd pkt size = %d\n", + mvm_standby_voice_cmd.pkt_size); + mvm_standby_voice_cmd.src_port = + voice_get_idx_for_session(v->session_id); + mvm_standby_voice_cmd.dest_port = mvm_handle; + mvm_standby_voice_cmd.token = 0; + mvm_standby_voice_cmd.opcode = VSS_IMVM_CMD_STANDBY_VOICE; + v->mvm_state = CMD_STATUS_FAIL; + ret = apr_send_pkt(apr_mvm, + (uint32_t *)&mvm_standby_voice_cmd); + if (ret < 0) { + pr_err("Fail in sending VSS_IMVM_CMD_STANDBY_VOICE\n"); + ret = -EINVAL; + goto fail; + } + v->voc_state = VOC_STANDBY; + } +fail: + return ret; +} + +int voc_disable_device(uint32_t session_id) +{ + struct voice_data *v = voice_get_session(session_id); + int ret = 0; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + + pr_debug("%s: voc state=%d\n", __func__, v->voc_state); + + mutex_lock(&v->lock); + if (v->voc_state == VOC_RUN) { + ret = voice_pause_voice_call(v); + if (ret < 0) { + pr_err("%s: Pause Voice Call failed for session 0x%x, err %d!\n", + __func__, v->session_id, ret); + goto done; + } + rtac_remove_voice(voice_get_cvs_handle(v)); + voice_send_cvp_deregister_vol_cal_cmd(v); + voice_send_cvp_deregister_cal_cmd(v); + voice_send_cvp_deregister_dev_cfg_cmd(v); + + v->voc_state = VOC_CHANGE; + } else { + pr_debug("%s: called in voc state=%d, No_OP\n", + __func__, v->voc_state); + } + +done: + mutex_unlock(&v->lock); + + return ret; +} + +int voc_enable_device(uint32_t session_id) +{ + struct voice_data *v = voice_get_session(session_id); + int ret = 0; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + + pr_debug("%s: voc state=%d\n", __func__, v->voc_state); + mutex_lock(&v->lock); + if (v->voc_state == VOC_CHANGE) { + ret = voice_send_tty_mode_cmd(v); + if (ret < 0) { + pr_err("%s: Sending TTY mode failed, ret=%d\n", + __func__, ret); + /* Not a critical error, allow voice call to continue */ + } + + if (v->tty_mode) { + /* disable slowtalk */ + voice_send_set_pp_enable_cmd(v, + MODULE_ID_VOICE_MODULE_ST, + 0); + } else { + /* restore slowtalk */ + voice_send_set_pp_enable_cmd(v, + MODULE_ID_VOICE_MODULE_ST, + v->st_enable); + } + + ret = voice_send_set_device_cmd(v); + if (ret < 0) { + pr_err("%s: Set device failed, ret=%d\n", + __func__, ret); + goto done; + } + + ret = voice_send_cvp_media_fmt_info_cmd(v); + if (ret < 0) { + pr_err("%s: Set format failed err:%d\n", __func__, ret); + goto done; + } + + ret = voice_send_cvp_topology_commit_cmd(v); + if (ret < 0) { + pr_err("%s: Set topology commit failed\n", __func__); + goto done; + } + + voice_send_cvp_register_dev_cfg_cmd(v); + voice_send_cvp_register_cal_cmd(v); + voice_send_cvp_register_vol_cal_cmd(v); + + rtac_add_voice(voice_get_cvs_handle(v), + voice_get_cvp_handle(v), + v->dev_rx.port_id, v->dev_tx.port_id, + v->dev_rx.dev_id, v->dev_tx.dev_id, + v->session_id); + + ret = voice_send_start_voice_cmd(v); + if (ret < 0) { + pr_err("%s: Fail in sending START_VOICE, ret=%d\n", + __func__, ret); + goto done; + } + v->voc_state = VOC_RUN; + } else { + pr_debug("%s: called in voc state=%d, No_OP\n", + __func__, v->voc_state); + } + +done: + mutex_unlock(&v->lock); + + return ret; +} + +int voc_set_lch(uint32_t session_id, enum voice_lch_mode lch_mode) +{ + struct voice_data *v = voice_get_session(session_id); + int ret = 0; + + if (v == NULL) { + pr_err("%s: Invalid session_id 0x%x\n", __func__, session_id); + + ret = -EINVAL; + goto done; + } + + mutex_lock(&v->lock); + if (v->lch_mode == lch_mode) { + pr_debug("%s: Session %d already in LCH mode %d\n", + __func__, session_id, lch_mode); + + mutex_unlock(&v->lock); + goto done; + } + + v->lch_mode = lch_mode; + mutex_unlock(&v->lock); + + ret = voc_lch_ops(v, v->lch_mode); + if (ret < 0) { + pr_err("%s: lch ops failed %d\n", __func__, ret); + goto done; + } + +done: + return ret; +} + +int voc_resume_voice_call(uint32_t session_id) +{ + struct voice_data *v = voice_get_session(session_id); + int ret = 0; + + ret = voice_send_start_voice_cmd(v); + if (ret < 0) { + pr_err("Fail in sending START_VOICE\n"); + goto fail; + } + v->voc_state = VOC_RUN; + return 0; +fail: + return -EINVAL; +} + +int voc_start_voice_call(uint32_t session_id) +{ + struct voice_data *v = voice_get_session(session_id); + int ret = 0; + + if (v == NULL) { + pr_err("%s: invalid session_id 0x%x\n", __func__, session_id); + + return -EINVAL; + } + + mutex_lock(&v->lock); + + if (v->voc_state == VOC_ERROR) { + pr_debug("%s: VOC in ERR state\n", __func__); + + voice_destroy_mvm_cvs_session(v); + v->voc_state = VOC_INIT; + } + + if ((v->voc_state == VOC_INIT) || + (v->voc_state == VOC_RELEASE)) { + ret = voice_apr_register(session_id); + if (ret < 0) { + pr_err("%s: apr register failed\n", __func__); + goto fail; + } + + if (is_cvd_version_queried()) { + pr_debug("%s: Returning the cached value %s\n", + __func__, common.cvd_version); + } else { + ret = voice_send_mvm_cvd_version_cmd(v); + if (ret < 0) + pr_debug("%s: Error retrieving CVD version %d\n", + __func__, ret); + } + + ret = voice_create_mvm_cvs_session(v); + if (ret < 0) { + pr_err("create mvm and cvs failed\n"); + goto fail; + } + + if (is_voip_session(session_id)) { + /* Allocate oob mem if not already allocated and + * memory map the oob memory block. + */ + ret = voice_alloc_and_map_oob_mem(v); + if (ret < 0) { + pr_err("%s: voice_alloc_and_map_oob_mem() failed, ret:%d\n", + __func__, ret); + + goto fail; + } + + ret = voice_set_packet_exchange_mode_and_config( + session_id, + VSS_ISTREAM_PACKET_EXCHANGE_MODE_OUT_OF_BAND); + if (ret) { + pr_err("%s: Err: exchange_mode_and_config %d\n", + __func__, ret); + + goto fail; + } + } + ret = voice_send_dual_control_cmd(v); + if (ret < 0) { + pr_err("Err Dual command failed\n"); + goto fail; + } + ret = voice_setup_vocproc(v); + if (ret < 0) { + pr_err("setup voice failed\n"); + goto fail; + } + + ret = voice_send_vol_step_cmd(v); + if (ret < 0) + pr_err("voice volume failed\n"); + + ret = voice_send_stream_mute_cmd(v, + VSS_IVOLUME_DIRECTION_TX, + v->stream_tx.stream_mute, + v->stream_tx.stream_mute_ramp_duration_ms); + if (ret < 0) + pr_err("voice mute failed\n"); + + ret = voice_send_start_voice_cmd(v); + if (ret < 0) { + pr_err("start voice failed\n"); + goto fail; + } + + v->voc_state = VOC_RUN; + } else { + pr_err("%s: Error: Start voice called in state %d\n", + __func__, v->voc_state); + + ret = -EINVAL; + goto fail; + } +fail: + mutex_unlock(&v->lock); + return ret; +} + +int voc_set_ext_ec_ref_port_id(uint16_t port_id, bool state) +{ + int ret = 0; + + mutex_lock(&common.common_lock); + if (state == true) { + if (port_id == AFE_PORT_INVALID) { + pr_err("%s: Invalid port id", __func__); + ret = -EINVAL; + goto exit; + } + common.ec_ref_ext = true; + } else { + common.ec_ref_ext = false; + } + /* Cache EC Fromat Info in common */ + common.ec_media_fmt_info.port_id = port_id; +exit: + mutex_unlock(&common.common_lock); + return ret; +} + +int voc_get_ext_ec_ref_port_id(void) +{ + if (common.ec_ref_ext) + return common.ec_media_fmt_info.port_id; + else + return AFE_PORT_INVALID; +} + +void voc_register_mvs_cb(ul_cb_fn ul_cb, + dl_cb_fn dl_cb, + voip_ssr_cb ssr_cb, + void *private_data) +{ + common.mvs_info.ul_cb = ul_cb; + common.mvs_info.dl_cb = dl_cb; + common.mvs_info.ssr_cb = ssr_cb; + common.mvs_info.private_data = private_data; +} + +void voc_register_dtmf_rx_detection_cb(dtmf_rx_det_cb_fn dtmf_rx_ul_cb, + void *private_data) +{ + common.dtmf_info.dtmf_rx_ul_cb = dtmf_rx_ul_cb; + common.dtmf_info.private_data = private_data; +} + +void voc_config_vocoder(uint32_t media_type, + uint32_t rate, + uint32_t network_type, + uint32_t dtx_mode, + uint32_t evrc_min_rate, + uint32_t evrc_max_rate) +{ + common.mvs_info.media_type = media_type; + common.mvs_info.rate = rate; + common.mvs_info.network_type = network_type; + common.mvs_info.dtx_mode = dtx_mode; + common.mvs_info.evrc_min_rate = evrc_min_rate; + common.mvs_info.evrc_max_rate = evrc_max_rate; +} + +static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) +{ + uint32_t *ptr = NULL; + struct common_data *c = NULL; + struct voice_data *v = NULL; + int i = 0; + struct vss_iversion_rsp_get_t *version_rsp = NULL; + + if ((data == NULL) || (priv == NULL)) { + pr_err("%s: data or priv is NULL\n", __func__); + return -EINVAL; + } + + c = priv; + + pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__, + data->payload_size, data->opcode); + + if (data->opcode == RESET_EVENTS) { + pr_debug("%s: Reset event received in Voice service\n", + __func__); + + if (common.mvs_info.ssr_cb) { + pr_debug("%s: Informing reset event to VoIP\n", + __func__); + common.mvs_info.ssr_cb(data->opcode, + common.mvs_info.private_data); + } + + apr_reset(c->apr_q6_mvm); + c->apr_q6_mvm = NULL; + + /* clean up memory handle */ + c->cal_mem_handle = 0; + c->rtac_mem_handle = 0; + cal_utils_clear_cal_block_q6maps(MAX_VOICE_CAL_TYPES, + common.cal_data); + rtac_clear_mapping(VOICE_RTAC_CAL); + + /* Sub-system restart is applicable to all sessions. */ + for (i = 0; i < MAX_VOC_SESSIONS; i++) { + c->voice[i].mvm_handle = 0; + c->voice[i].shmem_info.mem_handle = 0; + } + + /* Free the ION memory and clear handles for Source Tracking */ + if (is_source_tracking_shared_memomry_allocated()) { + msm_audio_ion_free( + common.source_tracking_sh_mem.sh_mem_block.client, + common.source_tracking_sh_mem.sh_mem_block.handle); + common.source_tracking_sh_mem.mem_handle = 0; + common.source_tracking_sh_mem.sh_mem_block.client = + NULL; + common.source_tracking_sh_mem.sh_mem_block.handle = + NULL; + } + /* clean up srvcc rec flag */ + c->srvcc_rec_flag = false; + voc_set_error_state(data->reset_proc); + return 0; + } + + pr_debug("%s: session_idx 0x%x\n", __func__, data->dest_port); + + v = voice_get_session_by_idx(data->dest_port); + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + return -EINVAL; + } + + if (data->opcode == APR_BASIC_RSP_RESULT) { + if (data->payload_size) { + ptr = data->payload; + + pr_debug("%x %x\n", ptr[0], ptr[1]); + /* ping mvm service ACK */ + switch (ptr[0]) { + case VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION: + case VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION: + /* Passive session is used for CS call + * Full session is used for VoIP call. + */ + pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]); + if (!ptr[1]) { + pr_debug("%s: MVM handle is %d\n", + __func__, data->src_port); + voice_set_mvm_handle(v, data->src_port); + } else + pr_err("got NACK for sending MVM create session\n"); + v->mvm_state = CMD_STATUS_SUCCESS; + v->async_err = ptr[1]; + wake_up(&v->mvm_wait); + break; + case VSS_IMVM_CMD_START_VOICE: + case VSS_IMVM_CMD_ATTACH_VOCPROC: + case VSS_IMVM_CMD_STOP_VOICE: + case VSS_IMVM_CMD_DETACH_VOCPROC: + case VSS_ISTREAM_CMD_SET_TTY_MODE: + case APRV2_IBASIC_CMD_DESTROY_SESSION: + case VSS_IMVM_CMD_ATTACH_STREAM: + case VSS_IMVM_CMD_DETACH_STREAM: + case VSS_ICOMMON_CMD_SET_NETWORK: + case VSS_ICOMMON_CMD_SET_VOICE_TIMING: + case VSS_IMVM_CMD_SET_POLICY_DUAL_CONTROL: + case VSS_IMVM_CMD_SET_CAL_NETWORK: + case VSS_IMVM_CMD_SET_CAL_MEDIA_TYPE: + case VSS_IMEMORY_CMD_MAP_PHYSICAL: + case VSS_IMEMORY_CMD_UNMAP: + case VSS_IMVM_CMD_PAUSE_VOICE: + case VSS_IMVM_CMD_STANDBY_VOICE: + case VSS_IHDVOICE_CMD_ENABLE: + case VSS_IHDVOICE_CMD_DISABLE: + pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]); + v->mvm_state = CMD_STATUS_SUCCESS; + v->async_err = ptr[1]; + wake_up(&v->mvm_wait); + break; + case VSS_IVERSION_CMD_GET: + pr_debug("%s: Error retrieving CVD Version, error:%d\n", + __func__, ptr[1]); + + strlcpy(common.cvd_version, CVD_VERSION_0_0, + sizeof(common.cvd_version)); + pr_debug("%s: Fall back to default value, CVD Version = %s\n", + __func__, common.cvd_version); + + v->mvm_state = CMD_STATUS_SUCCESS; + v->async_err = ptr[1]; + wake_up(&v->mvm_wait); + break; + default: + pr_debug("%s: not match cmd = 0x%x\n", + __func__, ptr[0]); + break; + } + } + } else if (data->opcode == VSS_IMEMORY_RSP_MAP) { + pr_debug("%s, Revd VSS_IMEMORY_RSP_MAP response\n", __func__); + + if (data->payload_size && data->token == VOIP_MEM_MAP_TOKEN) { + ptr = data->payload; + if (ptr[0]) { + v->shmem_info.mem_handle = ptr[0]; + pr_debug("%s: shared mem_handle: 0x[%x]\n", + __func__, v->shmem_info.mem_handle); + v->mvm_state = CMD_STATUS_SUCCESS; + wake_up(&v->mvm_wait); + } + } else if (data->payload_size && + data->token == VOC_CAL_MEM_MAP_TOKEN) { + ptr = data->payload; + if (ptr[0]) { + c->cal_mem_handle = ptr[0]; + + pr_debug("%s: cal mem handle 0x%x\n", + __func__, c->cal_mem_handle); + + v->mvm_state = CMD_STATUS_SUCCESS; + wake_up(&v->mvm_wait); + } + } else if (data->payload_size && + data->token == VOC_VOICE_HOST_PCM_MAP_TOKEN) { + ptr = data->payload; + if (ptr[0]) { + common.voice_host_pcm_mem_handle = ptr[0]; + + pr_debug("%s: vhpcm mem handle 0x%x\n", + __func__, + common.voice_host_pcm_mem_handle); + v->mvm_state = CMD_STATUS_SUCCESS; + wake_up(&v->mvm_wait); + } + } else if (data->payload_size && + data->token == VOC_RTAC_MEM_MAP_TOKEN) { + ptr = data->payload; + if (ptr[0]) { + c->rtac_mem_handle = ptr[0]; + + pr_debug("%s: cal mem handle 0x%x\n", + __func__, c->rtac_mem_handle); + + v->mvm_state = CMD_STATUS_SUCCESS; + wake_up(&v->mvm_wait); + } + } else if (data->payload_size && + data->token == VOC_SOURCE_TRACKING_MEM_MAP_TOKEN) { + ptr = data->payload; + if (ptr[0]) { + common.source_tracking_sh_mem.mem_handle = + ptr[0]; + + pr_debug("%s: Source Tracking shared mem handle 0x%x\n", + __func__, + common.source_tracking_sh_mem.mem_handle); + + v->mvm_state = CMD_STATUS_SUCCESS; + wake_up(&v->mvm_wait); + } + } else { + pr_err("%s: Unknown mem map token %d\n", + __func__, data->token); + } + } else if (data->opcode == VSS_IVERSION_RSP_GET) { + pr_debug("%s: Received VSS_IVERSION_RSP_GET\n", __func__); + + if (data->payload_size) { + version_rsp = + (struct vss_iversion_rsp_get_t *)data->payload; + memcpy(common.cvd_version, version_rsp->version, + CVD_VERSION_STRING_MAX_SIZE); + pr_debug("%s: CVD Version = %s\n", + __func__, common.cvd_version); + + v->mvm_state = CMD_STATUS_SUCCESS; + wake_up(&v->mvm_wait); + } + } + return 0; +} + +static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv) +{ + uint32_t *ptr = NULL; + struct common_data *c = NULL; + struct voice_data *v = NULL; + int i = 0; + + if ((data == NULL) || (priv == NULL)) { + pr_err("%s: data or priv is NULL\n", __func__); + return -EINVAL; + } + + c = priv; + + pr_debug("%s: session_id 0x%x\n", __func__, data->dest_port); + pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__, + data->payload_size, data->opcode); + + if (data->opcode == RESET_EVENTS) { + pr_debug("%s: Reset event received in Voice service\n", + __func__); + + apr_reset(c->apr_q6_cvs); + c->apr_q6_cvs = NULL; + + /* Sub-system restart is applicable to all sessions. */ + for (i = 0; i < MAX_VOC_SESSIONS; i++) + c->voice[i].cvs_handle = 0; + + cal_utils_clear_cal_block_q6maps(MAX_VOICE_CAL_TYPES, + common.cal_data); + + /* Free the ION memory and clear handles for Source Tracking */ + if (is_source_tracking_shared_memomry_allocated()) { + msm_audio_ion_free( + common.source_tracking_sh_mem.sh_mem_block.client, + common.source_tracking_sh_mem.sh_mem_block.handle); + common.source_tracking_sh_mem.mem_handle = 0; + common.source_tracking_sh_mem.sh_mem_block.client = + NULL; + common.source_tracking_sh_mem.sh_mem_block.handle = + NULL; + } + voc_set_error_state(data->reset_proc); + return 0; + } + + v = voice_get_session_by_idx(data->dest_port); + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + return -EINVAL; + } + + if (data->opcode == APR_BASIC_RSP_RESULT) { + if (data->payload_size) { + ptr = data->payload; + + pr_debug("%x %x\n", ptr[0], ptr[1]); + if (ptr[1] != 0) { + pr_err("%s: cmd = 0x%x returned error = 0x%x\n", + __func__, ptr[0], ptr[1]); + } + /*response from CVS */ + switch (ptr[0]) { + case VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION: + case VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION: + if (!ptr[1]) { + pr_debug("%s: CVS handle is %d\n", + __func__, data->src_port); + voice_set_cvs_handle(v, data->src_port); + } else + pr_err("got NACK for sending CVS create session\n"); + v->cvs_state = CMD_STATUS_SUCCESS; + v->async_err = ptr[1]; + wake_up(&v->cvs_wait); + break; + case VSS_IVOLUME_CMD_MUTE_V2: + case VSS_ISTREAM_CMD_SET_MEDIA_TYPE: + case VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE: + case VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE: + case VSS_ISTREAM_CMD_SET_ENC_DTX_MODE: + case VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE: + case APRV2_IBASIC_CMD_DESTROY_SESSION: + case VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA_V2: + case VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA: + case VSS_ISTREAM_CMD_REGISTER_STATIC_CALIBRATION_DATA: + case VSS_ISTREAM_CMD_DEREGISTER_STATIC_CALIBRATION_DATA: + case VSS_ICOMMON_CMD_MAP_MEMORY: + case VSS_ICOMMON_CMD_UNMAP_MEMORY: + case VSS_ICOMMON_CMD_SET_UI_PROPERTY: + case VSS_IPLAYBACK_CMD_START: + case VSS_IPLAYBACK_CMD_STOP: + case VSS_IRECORD_CMD_START: + case VSS_IRECORD_CMD_STOP: + case VSS_ISTREAM_CMD_SET_PACKET_EXCHANGE_MODE: + case VSS_ISTREAM_CMD_SET_OOB_PACKET_EXCHANGE_CONFIG: + case VSS_ISTREAM_CMD_SET_RX_DTMF_DETECTION: + pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]); + v->cvs_state = CMD_STATUS_SUCCESS; + v->async_err = ptr[1]; + wake_up(&v->cvs_wait); + break; + case VSS_ICOMMON_CMD_SET_PARAM_V2: + pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2\n", + __func__); + rtac_make_voice_callback(RTAC_CVS, ptr, + data->payload_size); + break; + case VSS_ICOMMON_CMD_GET_PARAM_V2: + pr_debug("%s: VSS_ICOMMON_CMD_GET_PARAM_V2\n", + __func__); + /* Should only come here if there is an APR */ + /* error or malformed APR packet. Otherwise */ + /* response will be returned as */ + /* VSS_ICOMMON_RSP_GET_PARAM */ + if (ptr[1] != 0) { + pr_err("%s: CVP get param error = %d, resuming\n", + __func__, ptr[1]); + rtac_make_voice_callback(RTAC_CVP, + data->payload, + data->payload_size); + } + break; + default: + pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]); + break; + } + } + } else if (data->opcode == + VSS_ISTREAM_EVT_OOB_NOTIFY_ENC_BUFFER_READY) { + int ret = 0; + u16 cvs_handle; + uint32_t *cvs_voc_pkt; + struct cvs_enc_buffer_consumed_cmd send_enc_buf_consumed_cmd; + void *apr_cvs; + + pr_debug("Encoder buffer is ready\n"); + + apr_cvs = common.apr_q6_cvs; + if (!apr_cvs) { + pr_err("%s: apr_cvs is NULL\n", __func__); + return -EINVAL; + } + cvs_handle = voice_get_cvs_handle(v); + + send_enc_buf_consumed_cmd.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + send_enc_buf_consumed_cmd.hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(send_enc_buf_consumed_cmd) - APR_HDR_SIZE); + + send_enc_buf_consumed_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + send_enc_buf_consumed_cmd.hdr.dest_port = cvs_handle; + send_enc_buf_consumed_cmd.hdr.token = 0; + send_enc_buf_consumed_cmd.hdr.opcode = + VSS_ISTREAM_EVT_OOB_NOTIFY_ENC_BUFFER_CONSUMED; + + cvs_voc_pkt = v->shmem_info.sh_buf.buf[1].data; + if (cvs_voc_pkt != NULL && common.mvs_info.ul_cb != NULL) { + /* cvs_voc_pkt[0] contains tx timestamp */ + common.mvs_info.ul_cb((uint8_t *)&cvs_voc_pkt[3], + cvs_voc_pkt[2], + cvs_voc_pkt[0], + common.mvs_info.private_data); + } else + pr_err("%s: cvs_voc_pkt or ul_cb is NULL\n", __func__); + + ret = apr_send_pkt(apr_cvs, + (uint32_t *) &send_enc_buf_consumed_cmd); + if (ret < 0) { + pr_err("%s: Err send ENC_BUF_CONSUMED_NOTIFY %d\n", + __func__, ret); + goto fail; + } + } else if (data->opcode == VSS_ISTREAM_EVT_SEND_ENC_BUFFER) { + pr_debug("Recd VSS_ISTREAM_EVT_SEND_ENC_BUFFER\n"); + } else if (data->opcode == + VSS_ISTREAM_EVT_OOB_NOTIFY_DEC_BUFFER_REQUEST) { + int ret = 0; + u16 cvs_handle; + uint32_t *cvs_voc_pkt; + struct cvs_dec_buffer_ready_cmd send_dec_buf; + void *apr_cvs; + + apr_cvs = common.apr_q6_cvs; + + if (!apr_cvs) { + pr_err("%s: apr_cvs is NULL\n", __func__); + return -EINVAL; + } + cvs_handle = voice_get_cvs_handle(v); + + send_dec_buf.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + + send_dec_buf.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(send_dec_buf) - APR_HDR_SIZE); + + send_dec_buf.hdr.src_port = + voice_get_idx_for_session(v->session_id); + send_dec_buf.hdr.dest_port = cvs_handle; + send_dec_buf.hdr.token = 0; + send_dec_buf.hdr.opcode = + VSS_ISTREAM_EVT_OOB_NOTIFY_DEC_BUFFER_READY; + + cvs_voc_pkt = (uint32_t *)(v->shmem_info.sh_buf.buf[0].data); + if (cvs_voc_pkt != NULL && common.mvs_info.dl_cb != NULL) { + /* Set timestamp to 0 and advance the pointer */ + cvs_voc_pkt[0] = 0; + /* Set media_type and advance the pointer */ + cvs_voc_pkt[1] = common.mvs_info.media_type; + common.mvs_info.dl_cb( + (uint8_t *)&cvs_voc_pkt[2], + common.mvs_info.private_data); + ret = apr_send_pkt(apr_cvs, (uint32_t *) &send_dec_buf); + if (ret < 0) { + pr_err("%s: Err send DEC_BUF_READY_NOTIFI %d\n", + __func__, ret); + goto fail; + } + } else { + pr_debug("%s: voc_pkt or dl_cb is NULL\n", __func__); + goto fail; + } + } else if (data->opcode == VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER) { + pr_debug("Recd VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER\n"); + } else if (data->opcode == VSS_ISTREAM_EVT_SEND_DEC_BUFFER) { + pr_debug("Send dec buf resp\n"); + } else if (data->opcode == APR_RSP_ACCEPTED) { + ptr = data->payload; + if (ptr[0]) + pr_debug("%s: APR_RSP_ACCEPTED for 0x%x:\n", + __func__, ptr[0]); + } else if (data->opcode == VSS_ISTREAM_EVT_NOT_READY) { + pr_debug("Recd VSS_ISTREAM_EVT_NOT_READY\n"); + } else if (data->opcode == VSS_ISTREAM_EVT_READY) { + pr_debug("Recd VSS_ISTREAM_EVT_READY\n"); + } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM) { + pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__); + ptr = data->payload; + if (ptr[0] != 0) { + pr_err("%s: VSS_ICOMMON_RSP_GET_PARAM returned error = 0x%x\n", + __func__, ptr[0]); + } + rtac_make_voice_callback(RTAC_CVS, data->payload, + data->payload_size); + } else if (data->opcode == VSS_ISTREAM_EVT_RX_DTMF_DETECTED) { + struct vss_istream_evt_rx_dtmf_detected *dtmf_rx_detected; + uint32_t *voc_pkt = data->payload; + uint32_t pkt_len = data->payload_size; + + if ((voc_pkt != NULL) && + (pkt_len == + sizeof(struct vss_istream_evt_rx_dtmf_detected))) { + + dtmf_rx_detected = + (struct vss_istream_evt_rx_dtmf_detected *) voc_pkt; + pr_debug("RX_DTMF_DETECTED low_freq=%d high_freq=%d\n", + dtmf_rx_detected->low_freq, + dtmf_rx_detected->high_freq); + if (c->dtmf_info.dtmf_rx_ul_cb) + c->dtmf_info.dtmf_rx_ul_cb((uint8_t *)voc_pkt, + voc_get_session_name(v->session_id), + c->dtmf_info.private_data); + } else { + pr_err("Invalid packet\n"); + } + } else + pr_debug("Unknown opcode 0x%x\n", data->opcode); + +fail: + return 0; +} + +static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv) +{ + uint32_t *ptr = NULL; + struct common_data *c = NULL; + struct voice_data *v = NULL; + int i = 0; + + if ((data == NULL) || (priv == NULL)) { + pr_err("%s: data or priv is NULL\n", __func__); + return -EINVAL; + } + + c = priv; + + if (data->opcode == RESET_EVENTS) { + pr_debug("%s: Reset event received in Voice service\n", + __func__); + + apr_reset(c->apr_q6_cvp); + c->apr_q6_cvp = NULL; + cal_utils_clear_cal_block_q6maps(MAX_VOICE_CAL_TYPES, + common.cal_data); + + /* Sub-system restart is applicable to all sessions. */ + for (i = 0; i < MAX_VOC_SESSIONS; i++) + c->voice[i].cvp_handle = 0; + + /* + * Free the ION memory and clear handles for + * Source Tracking + */ + if (is_source_tracking_shared_memomry_allocated()) { + msm_audio_ion_free( + common.source_tracking_sh_mem.sh_mem_block.client, + common.source_tracking_sh_mem.sh_mem_block.handle); + common.source_tracking_sh_mem.mem_handle = 0; + common.source_tracking_sh_mem.sh_mem_block.client = + NULL; + common.source_tracking_sh_mem.sh_mem_block.handle = + NULL; + } + voc_set_error_state(data->reset_proc); + return 0; + } + + v = voice_get_session_by_idx(data->dest_port); + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + return -EINVAL; + } + + if (data->opcode == APR_BASIC_RSP_RESULT) { + if (data->payload_size) { + ptr = data->payload; + + pr_debug("%x %x\n", ptr[0], ptr[1]); + if (ptr[1] != 0) { + pr_err("%s: cmd = 0x%x returned error = 0x%x\n", + __func__, ptr[0], ptr[1]); + } + switch (ptr[0]) { + case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V2: + case VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V3: + /*response from CVP */ + pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]); + if (!ptr[1]) { + voice_set_cvp_handle(v, data->src_port); + pr_debug("status: %d, cvphdl=%d\n", + ptr[1], data->src_port); + } else + pr_err("got NACK from CVP create session response\n"); + v->cvp_state = CMD_STATUS_SUCCESS; + v->async_err = ptr[1]; + wake_up(&v->cvp_wait); + break; + case VSS_IVOCPROC_CMD_SET_DEVICE_V2: + case VSS_IVOCPROC_CMD_SET_DEVICE_V3: + case VSS_IVOLUME_CMD_SET_STEP: + case VSS_IVOCPROC_CMD_ENABLE: + case VSS_IVOCPROC_CMD_DISABLE: + case APRV2_IBASIC_CMD_DESTROY_SESSION: + case VSS_IVOCPROC_CMD_REGISTER_VOL_CALIBRATION_DATA: + case VSS_IVOCPROC_CMD_DEREGISTER_VOL_CALIBRATION_DATA: + case VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2: + case VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA: + case VSS_IVOCPROC_CMD_REGISTER_DYNAMIC_CALIBRATION_DATA: + case VSS_IVOCPROC_CMD_DEREGISTER_DYNAMIC_CALIBRATION_DATA: + case VSS_IVOCPROC_CMD_REGISTER_STATIC_CALIBRATION_DATA: + case VSS_IVOCPROC_CMD_DEREGISTER_STATIC_CALIBRATION_DATA: + case VSS_IVOCPROC_CMD_REGISTER_DEVICE_CONFIG: + case VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG: + case VSS_ICOMMON_CMD_MAP_MEMORY: + case VSS_ICOMMON_CMD_UNMAP_MEMORY: + case VSS_IVOLUME_CMD_MUTE_V2: + case VSS_IVPCM_CMD_START_V2: + case VSS_IVPCM_CMD_STOP: + case VSS_IVOCPROC_CMD_TOPOLOGY_SET_DEV_CHANNELS: + case VSS_IVOCPROC_CMD_TOPOLOGY_COMMIT: + v->cvp_state = CMD_STATUS_SUCCESS; + v->async_err = ptr[1]; + wake_up(&v->cvp_wait); + break; + case VSS_IVPCM_EVT_PUSH_BUFFER_V2: + break; + case VSS_ICOMMON_CMD_SET_PARAM_V2: + switch (data->token) { + case VOC_SET_MEDIA_FORMAT_PARAM_TOKEN: + pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called by voice_send_cvp_media_format_cmd\n", + __func__); + v->cvp_state = CMD_STATUS_SUCCESS; + v->async_err = ptr[1]; + wake_up(&v->cvp_wait); + break; + case VOC_RTAC_SET_PARAM_TOKEN: + pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called by rtac\n", + __func__); + rtac_make_voice_callback( + RTAC_CVP, ptr, + data->payload_size); + break; + default: + pr_debug("%s: invalid token for command VSS_ICOMMON_CMD_SET_PARAM_V2: %d\n", + __func__, data->token); + break; + } + break; + case VSS_ICOMMON_CMD_GET_PARAM_V2: + pr_debug("%s: VSS_ICOMMON_CMD_GET_PARAM_V2\n", + __func__); + /* Should only come here if there is an APR */ + /* error or malformed APR packet. Otherwise */ + /* response will be returned as */ + /* VSS_ICOMMON_RSP_GET_PARAM */ + if (ptr[1] != 0) { + pr_err("%s: CVP get param error = %d, resuming\n", + __func__, ptr[1]); + rtac_make_voice_callback(RTAC_CVP, + data->payload, + data->payload_size); + } + break; + case VSS_ISOUNDFOCUS_CMD_SET_SECTORS: + if (!ptr[1]) + common.is_sound_focus_resp_success = + true; + else + common.is_sound_focus_resp_success = + false; + v->cvp_state = CMD_STATUS_SUCCESS; + v->async_err = ptr[1]; + wake_up(&v->cvp_wait); + break; + case VSS_ISOUNDFOCUS_CMD_GET_SECTORS: + /* + * Should only come here if there is an error + * response received from ADSP. Otherwise + * response will be returned as + * VSS_ISOUNDFOCUS_RSP_GET_SECTORS + */ + pr_err("%s: VSS_ISOUNDFOCUS_CMD_GET_SECTORS failed\n", + __func__); + + common.is_sound_focus_resp_success = false; + v->cvp_state = CMD_STATUS_SUCCESS; + v->async_err = ptr[1]; + wake_up(&v->cvp_wait); + break; + case VSS_ISOURCETRACK_CMD_GET_ACTIVITY: + if (!ptr[1]) { + /* Read data from shared memory */ + memcpy(&common.sourceTrackingResponse, + common.source_tracking_sh_mem. + sh_mem_block.data, + sizeof(struct + vss_isourcetrack_activity_data_t)); + common.is_source_tracking_resp_success = + true; + } else { + common.is_source_tracking_resp_success = + false; + pr_err("%s: Error received for source tracking params\n", + __func__); + } + v->cvp_state = CMD_STATUS_SUCCESS; + v->async_err = ptr[1]; + wake_up(&v->cvp_wait); + break; + default: + pr_debug("%s: not match cmd = 0x%x\n", + __func__, ptr[0]); + break; + } + } + } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM) { + pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__); + ptr = data->payload; + if (ptr[0] != 0) { + pr_err("%s: VSS_ICOMMON_RSP_GET_PARAM returned error = 0x%x\n", + __func__, ptr[0]); + } + rtac_make_voice_callback(RTAC_CVP, data->payload, + data->payload_size); + } else if (data->opcode == VSS_IVPCM_EVT_NOTIFY_V2) { + if ((data->payload != NULL) && data->payload_size == + sizeof(struct vss_ivpcm_evt_notify_v2_t) && + common.hostpcm_info.hostpcm_evt_cb != NULL) { + common.hostpcm_info.hostpcm_evt_cb(data->payload, + voc_get_session_name(v->session_id), + common.hostpcm_info.private_data); + } + } else if (data->opcode == VSS_ISOUNDFOCUS_RSP_GET_SECTORS) { + if (data->payload && (data->payload_size == + sizeof(struct vss_isoundfocus_rsp_get_sectors_t))) { + common.is_sound_focus_resp_success = true; + memcpy(&common.soundFocusResponse, + (struct vss_isoundfocus_rsp_get_sectors_t *) + data->payload, + sizeof(struct + vss_isoundfocus_rsp_get_sectors_t)); + } else { + common.is_sound_focus_resp_success = false; + pr_debug("%s: Invalid payload received from CVD\n", + __func__); + } + v->cvp_state = CMD_STATUS_SUCCESS; + wake_up(&v->cvp_wait); + } + return 0; +} + +static int voice_free_oob_shared_mem(void) +{ + int rc = 0; + int cnt = 0; + int bufcnt = NUM_OF_BUFFERS; + struct voice_data *v = voice_get_session( + common.voice[VOC_PATH_FULL].session_id); + + mutex_lock(&common.common_lock); + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + rc = -EINVAL; + goto done; + } + + rc = msm_audio_ion_free(v->shmem_info.sh_buf.client, + v->shmem_info.sh_buf.handle); + v->shmem_info.sh_buf.client = NULL; + v->shmem_info.sh_buf.handle = NULL; + if (rc < 0) { + pr_err("%s: Error:%d freeing memory\n", __func__, rc); + + goto done; + } + + + while (cnt < bufcnt) { + v->shmem_info.sh_buf.buf[cnt].data = NULL; + v->shmem_info.sh_buf.buf[cnt].phys = 0; + cnt++; + } + + v->shmem_info.sh_buf.client = NULL; + v->shmem_info.sh_buf.handle = NULL; + +done: + mutex_unlock(&common.common_lock); + return rc; +} + +static int voice_alloc_oob_shared_mem(void) +{ + int cnt = 0; + int rc = 0; + size_t len; + void *mem_addr; + dma_addr_t phys; + int bufsz = BUFFER_BLOCK_SIZE; + int bufcnt = NUM_OF_BUFFERS; + struct voice_data *v = voice_get_session( + common.voice[VOC_PATH_FULL].session_id); + + mutex_lock(&common.common_lock); + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + rc = -EINVAL; + goto done; + } + + rc = msm_audio_ion_alloc("voip_client", &(v->shmem_info.sh_buf.client), + &(v->shmem_info.sh_buf.handle), + bufsz*bufcnt, + &phys, &len, + &mem_addr); + if (rc < 0) { + pr_err("%s: audio ION alloc failed, rc = %d\n", + __func__, rc); + + goto done; + } + + while (cnt < bufcnt) { + v->shmem_info.sh_buf.buf[cnt].data = mem_addr + (cnt * bufsz); + v->shmem_info.sh_buf.buf[cnt].phys = phys + (cnt * bufsz); + v->shmem_info.sh_buf.buf[cnt].size = bufsz; + cnt++; + } + + pr_debug("%s buf[0].data:[%pK], buf[0].phys:[%pK], &buf[0].phys:[%pK],\n", + __func__, + (void *)v->shmem_info.sh_buf.buf[0].data, + &v->shmem_info.sh_buf.buf[0].phys, + (void *)&v->shmem_info.sh_buf.buf[0].phys); + pr_debug("%s: buf[1].data:[%pK], buf[1].phys[%pK], &buf[1].phys[%pK]\n", + __func__, + (void *)v->shmem_info.sh_buf.buf[1].data, + &v->shmem_info.sh_buf.buf[1].phys, + (void *)&v->shmem_info.sh_buf.buf[1].phys); + + memset((void *)v->shmem_info.sh_buf.buf[0].data, 0, (bufsz * bufcnt)); + +done: + mutex_unlock(&common.common_lock); + return rc; +} + +static int voice_alloc_oob_mem_table(void) +{ + int rc = 0; + size_t len; + struct voice_data *v = voice_get_session( + common.voice[VOC_PATH_FULL].session_id); + + mutex_lock(&common.common_lock); + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + rc = -EINVAL; + goto done; + } + + rc = msm_audio_ion_alloc("voip_client", &(v->shmem_info.memtbl.client), + &(v->shmem_info.memtbl.handle), + sizeof(struct vss_imemory_table_t), + &v->shmem_info.memtbl.phys, + &len, + &(v->shmem_info.memtbl.data)); + if (rc < 0) { + pr_err("%s: audio ION alloc failed, rc = %d\n", + __func__, rc); + + goto done; + } + + v->shmem_info.memtbl.size = sizeof(struct vss_imemory_table_t); + pr_debug("%s data[%pK]phys[%pK][%pK]\n", __func__, + (void *)v->shmem_info.memtbl.data, + &v->shmem_info.memtbl.phys, + (void *)&v->shmem_info.memtbl.phys); + +done: + mutex_unlock(&common.common_lock); + return rc; +} + +int voc_send_cvp_start_vocpcm(uint32_t session_id, + struct vss_ivpcm_tap_point *vpcm_tp, + uint32_t no_of_tp) +{ + struct cvp_start_cmd cvp_start_cmd; + int ret = 0; + void *apr_cvp; + u16 cvp_handle; + struct voice_data *v = voice_get_session(session_id); + int i = 0; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + apr_cvp = common.apr_q6_cvp; + + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL.\n", __func__); + ret = -EINVAL; + goto done; + } + + cvp_handle = voice_get_cvp_handle(v); + + /* Fill the header */ + cvp_start_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + cvp_start_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(struct vss_ivpcm_tap_point) * no_of_tp) + + sizeof(cvp_start_cmd.vpcm_start_cmd.num_tap_points) + + sizeof(cvp_start_cmd.vpcm_start_cmd.mem_handle); + cvp_start_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id); + cvp_start_cmd.hdr.dest_port = cvp_handle; + cvp_start_cmd.hdr.token = 0; + cvp_start_cmd.hdr.opcode = VSS_IVPCM_CMD_START_V2; + + for (i = 0; i < no_of_tp; i++) { + cvp_start_cmd.vpcm_start_cmd.tap_points[i].tap_point = + vpcm_tp[i].tap_point; + cvp_start_cmd.vpcm_start_cmd.tap_points[i].direction = + vpcm_tp[i].direction; + cvp_start_cmd.vpcm_start_cmd.tap_points[i].sampling_rate = + vpcm_tp[i].sampling_rate; + cvp_start_cmd.vpcm_start_cmd.tap_points[i].duration = 0; + } + + cvp_start_cmd.vpcm_start_cmd.mem_handle = + common.voice_host_pcm_mem_handle; + cvp_start_cmd.vpcm_start_cmd.num_tap_points = no_of_tp; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_start_cmd); + if (ret < 0) { + pr_err("%s: Fail: sending vocpcm map memory,\n", __func__); + goto done; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto done; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto done; + } + +done: + return ret; +} + +int voc_send_cvp_stop_vocpcm(uint32_t session_id) +{ + struct cvp_command vpcm_stop_cmd; + int ret = 0; + void *apr_cvp; + u16 cvp_handle; + struct voice_data *v = voice_get_session(session_id); + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + apr_cvp = common.apr_q6_cvp; + + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL.\n", __func__); + ret = -EINVAL; + goto done; + } + + cvp_handle = voice_get_cvp_handle(v); + + /* fill in the header */ + vpcm_stop_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + vpcm_stop_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(vpcm_stop_cmd) - APR_HDR_SIZE); + vpcm_stop_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id); + vpcm_stop_cmd.hdr.dest_port = cvp_handle; + vpcm_stop_cmd.hdr.token = 0; + vpcm_stop_cmd.hdr.opcode = VSS_IVPCM_CMD_STOP; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *) &vpcm_stop_cmd); + if (ret < 0) { + pr_err("Fail: sending vocpcm stop,\n"); + goto done; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + goto done; + } + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto done; + } + +done: + return ret; +} + +int voc_send_cvp_map_vocpcm_memory(uint32_t session_id, + struct mem_map_table *tp_mem_table, + phys_addr_t paddr, uint32_t bufsize) +{ + return voice_map_memory_physical_cmd(voice_get_session(session_id), + tp_mem_table, + (dma_addr_t) paddr, bufsize, + VOC_VOICE_HOST_PCM_MAP_TOKEN); +} + +int voc_send_cvp_unmap_vocpcm_memory(uint32_t session_id) +{ + int ret = 0; + + ret = voice_send_mvm_unmap_memory_physical_cmd( + voice_get_session(session_id), + common.voice_host_pcm_mem_handle); + + if (ret == 0) + common.voice_host_pcm_mem_handle = 0; + + return ret; +} + +int voc_send_cvp_vocpcm_push_buf_evt(uint32_t session_id, + struct vss_ivpcm_evt_push_buffer_v2_t *push_buff_evt) +{ + struct cvp_push_buf_cmd vpcm_push_buf_cmd; + int ret = 0; + void *apr_cvp; + u16 cvp_handle; + struct voice_data *v = voice_get_session(session_id); + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + apr_cvp = common.apr_q6_cvp; + + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL.\n", __func__); + ret = -EINVAL; + goto done; + } + + memset(&vpcm_push_buf_cmd, 0, sizeof(vpcm_push_buf_cmd)); + cvp_handle = voice_get_cvp_handle(v); + + /* fill in the header */ + vpcm_push_buf_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + vpcm_push_buf_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(vpcm_push_buf_cmd) - APR_HDR_SIZE); + vpcm_push_buf_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + vpcm_push_buf_cmd.hdr.dest_port = cvp_handle; + vpcm_push_buf_cmd.hdr.token = 0; + vpcm_push_buf_cmd.hdr.opcode = VSS_IVPCM_EVT_PUSH_BUFFER_V2; + + vpcm_push_buf_cmd.vpcm_evt_push_buffer.tap_point = + push_buff_evt->tap_point; + vpcm_push_buf_cmd.vpcm_evt_push_buffer.push_buf_mask = + push_buff_evt->push_buf_mask; + vpcm_push_buf_cmd.vpcm_evt_push_buffer.out_buf_mem_address = + push_buff_evt->out_buf_mem_address; + vpcm_push_buf_cmd.vpcm_evt_push_buffer.in_buf_mem_address = + push_buff_evt->in_buf_mem_address; + vpcm_push_buf_cmd.vpcm_evt_push_buffer.out_buf_mem_size = + push_buff_evt->out_buf_mem_size; + vpcm_push_buf_cmd.vpcm_evt_push_buffer.in_buf_mem_size = + push_buff_evt->in_buf_mem_size; + vpcm_push_buf_cmd.vpcm_evt_push_buffer.sampling_rate = + push_buff_evt->sampling_rate; + vpcm_push_buf_cmd.vpcm_evt_push_buffer.num_in_channels = + push_buff_evt->num_in_channels; + + ret = apr_send_pkt(apr_cvp, (uint32_t *) &vpcm_push_buf_cmd); + if (ret < 0) { + pr_err("Fail: sending vocpcm map memory,\n"); + goto done; + } + +done: + return ret; +} + +void voc_register_hpcm_evt_cb(hostpcm_cb_fn hostpcm_cb, + void *private_data) +{ + common.hostpcm_info.hostpcm_evt_cb = hostpcm_cb; + common.hostpcm_info.private_data = private_data; +} + +void voc_deregister_hpcm_evt_cb(void) +{ + common.hostpcm_info.hostpcm_evt_cb = NULL; + common.hostpcm_info.private_data = NULL; +} + +int voc_get_cvd_version(char *cvd_version) +{ + int ret = 0; + struct voice_data *v = voice_get_session(VOICE_SESSION_VSID); + + + if (v == NULL) { + pr_err("%s: invalid session_id 0x%x\n", + __func__, VOICE_SESSION_VSID); + + ret = -EINVAL; + goto done; + } + + if (is_cvd_version_queried()) { + pr_debug("%s: Returning the cached value %s\n", + __func__, common.cvd_version); + + goto done; + } + + /* Register callback to APR */ + ret = voice_apr_register(VOICE_SESSION_VSID); + if (ret < 0) { + pr_err("%s: apr register failed\n", __func__); + goto done; + } + + mutex_lock(&common.common_lock); + mutex_lock(&v->lock); + ret = voice_send_mvm_cvd_version_cmd(v); + if (ret < 0) { + pr_err("%s: voice_send_mvm_cvd_version_cmd failed\n", __func__); + goto unlock; + } + ret = 0; + +unlock: + mutex_unlock(&v->lock); + mutex_unlock(&common.common_lock); + +done: + if (cvd_version) + memcpy(cvd_version, common.cvd_version, + CVD_VERSION_STRING_MAX_SIZE); + + return ret; +} + +static int voice_alloc_cal_mem_map_table(void) +{ + int ret = 0; + size_t len; + + ret = msm_audio_ion_alloc("voc_cal", + &(common.cal_mem_map_table.client), + &(common.cal_mem_map_table.handle), + sizeof(struct vss_imemory_table_t), + &common.cal_mem_map_table.phys, + &len, + &(common.cal_mem_map_table.data)); + if ((ret < 0) && (ret != -EPROBE_DEFER)) { + pr_err("%s: audio ION alloc failed, rc = %d\n", + __func__, ret); + goto done; + } + + common.cal_mem_map_table.size = sizeof(struct vss_imemory_table_t); + pr_debug("%s: data %pK phys %pK\n", __func__, + common.cal_mem_map_table.data, + &common.cal_mem_map_table.phys); + +done: + return ret; +} + +static int voice_alloc_rtac_mem_map_table(void) +{ + int ret = 0; + size_t len; + + ret = msm_audio_ion_alloc("voc_rtac_cal", + &(common.rtac_mem_map_table.client), + &(common.rtac_mem_map_table.handle), + sizeof(struct vss_imemory_table_t), + &common.rtac_mem_map_table.phys, + &len, + &(common.rtac_mem_map_table.data)); + if (ret < 0) { + pr_err("%s: audio ION alloc failed, rc = %d\n", + __func__, ret); + goto done; + } + + common.rtac_mem_map_table.size = sizeof(struct vss_imemory_table_t); + pr_debug("%s: data %pK phys %pK\n", __func__, + common.rtac_mem_map_table.data, + &common.rtac_mem_map_table.phys); + +done: + return ret; +} + +static int voice_alloc_and_map_oob_mem(struct voice_data *v) +{ + int ret = 0; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + return -EINVAL; + } + + if (!is_voip_memory_allocated()) { + ret = voc_alloc_voip_shared_memory(); + if (ret < 0) { + pr_err("%s: Failed to create voip oob memory %d\n", + __func__, ret); + + goto done; + } + } + + ret = voice_map_memory_physical_cmd(v, + &v->shmem_info.memtbl, + v->shmem_info.sh_buf.buf[0].phys, + v->shmem_info.sh_buf.buf[0].size * NUM_OF_BUFFERS, + VOIP_MEM_MAP_TOKEN); + if (ret) { + pr_err("%s: mvm_map_memory_phy failed %d\n", + __func__, ret); + + goto done; + } + +done: + return ret; +} + +uint32_t voice_get_topology(uint32_t topology_idx) +{ + uint32_t topology = VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT; + struct cal_block_data *cal_block = NULL; + + /* initialize as default topology */ + if (topology_idx == CVP_VOC_RX_TOPOLOGY_CAL) { + topology = VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT; + } else if (topology_idx == CVP_VOC_TX_TOPOLOGY_CAL) { + topology = VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS; + } else { + pr_err("%s: cal index %x is invalid!\n", + __func__, topology_idx); + + goto done; + } + + if (common.cal_data[topology_idx] == NULL) { + pr_err("%s: cal type is NULL for cal index %x\n", + __func__, topology_idx); + + goto done; + } + + mutex_lock(&common.cal_data[topology_idx]->lock); + cal_block = cal_utils_get_only_cal_block( + common.cal_data[topology_idx]); + if (cal_block == NULL) { + pr_debug("%s: cal_block not found for cal index %x\n", + __func__, topology_idx); + + goto unlock; + } + + topology = ((struct audio_cal_info_voc_top *) + cal_block->cal_info)->topology; +unlock: + mutex_unlock(&common.cal_data[topology_idx]->lock); +done: + pr_debug("%s: Using topology %d\n", __func__, topology); + + return topology; +} + +static int get_cal_type_index(int32_t cal_type) +{ + int ret = -EINVAL; + + switch (cal_type) { + case CVP_VOC_RX_TOPOLOGY_CAL_TYPE: + ret = CVP_VOC_RX_TOPOLOGY_CAL; + break; + case CVP_VOC_TX_TOPOLOGY_CAL_TYPE: + ret = CVP_VOC_TX_TOPOLOGY_CAL; + break; + case CVP_VOCPROC_STATIC_CAL_TYPE: + ret = CVP_VOCPROC_CAL; + break; + case CVP_VOCPROC_DYNAMIC_CAL_TYPE: + ret = CVP_VOCVOL_CAL; + break; + case CVS_VOCSTRM_STATIC_CAL_TYPE: + ret = CVS_VOCSTRM_CAL; + break; + case CVP_VOCDEV_CFG_CAL_TYPE: + ret = CVP_VOCDEV_CFG_CAL; + break; + case CVP_VOCPROC_STATIC_COL_CAL_TYPE: + ret = CVP_VOCPROC_COL_CAL; + break; + case CVP_VOCPROC_DYNAMIC_COL_CAL_TYPE: + ret = CVP_VOCVOL_COL_CAL; + break; + case CVS_VOCSTRM_STATIC_COL_CAL_TYPE: + ret = CVS_VOCSTRM_COL_CAL; + break; + case VOICE_RTAC_INFO_CAL_TYPE: + ret = VOICE_RTAC_INFO_CAL; + break; + case VOICE_RTAC_APR_CAL_TYPE: + ret = VOICE_RTAC_APR_CAL; + break; + default: + pr_err("%s: Invalid cal type %d!\n", __func__, cal_type); + } + return ret; +} + +static int voice_prepare_volume_boost(int32_t cal_type, + size_t data_size, void *data) +{ + return voc_deregister_vocproc_vol_table(); +} + +static int voice_enable_volume_boost(int32_t cal_type, + size_t data_size, void *data) +{ + return voc_register_vocproc_vol_table(); +} + +static int voice_alloc_cal(int32_t cal_type, + size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + int cal_version; + + pr_debug("%s\n", __func__); + + cal_version = cal_utils_get_cal_type_version(data); + common.is_per_vocoder_cal_enabled = + !!(cal_version & PER_VOCODER_CAL_BIT_MASK); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: Could not get cal index %d!\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + ret = cal_utils_alloc_cal(data_size, data, + common.cal_data[cal_index], 0, NULL); + if (ret < 0) { + pr_err("%s: Cal_utils_alloc_block failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + ret = -EINVAL; + goto done; + } +done: + return ret; +} + +static int voice_dealloc_cal(int32_t cal_type, + size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + + pr_debug("%s\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: Could not get cal index %d!\n", + __func__, cal_index); + + ret = -EINVAL; + goto done; + } + + ret = cal_utils_dealloc_cal(data_size, data, + common.cal_data[cal_index]); + if (ret < 0) { + pr_err("%s: Cal_utils_dealloc_block failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + + ret = -EINVAL; + goto done; + } +done: + return ret; +} + +static int voice_set_cal(int32_t cal_type, + size_t data_size, void *data) +{ + int ret = 0; + int cal_index; + + pr_debug("%s\n", __func__); + + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: Could not get cal index %d!\n", + __func__, cal_index); + + ret = -EINVAL; + goto done; + } + + ret = cal_utils_set_cal(data_size, data, + common.cal_data[cal_index], 0, NULL); + if (ret < 0) { + pr_err("%s: Cal_utils_set_cal failed, ret = %d, cal type = %d!\n", + __func__, ret, cal_type); + + ret = -EINVAL; + goto done; + } +done: + return ret; +} + +static void voice_delete_cal_data(void) +{ + pr_debug("%s\n", __func__); + + cal_utils_destroy_cal_types(MAX_VOICE_CAL_TYPES, common.cal_data); +} + +static int voice_init_cal_data(void) +{ + int ret = 0; + struct cal_type_info cal_type_info[] = { + {{CVP_VOC_RX_TOPOLOGY_CAL_TYPE, + {NULL, NULL, NULL, voice_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{CVP_VOC_TX_TOPOLOGY_CAL_TYPE, + {NULL, NULL, NULL, voice_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{CVP_VOCPROC_STATIC_CAL_TYPE, + {voice_alloc_cal, voice_dealloc_cal, NULL, + voice_set_cal, NULL, NULL} }, + {NULL, voice_unmap_cal_memory, + cal_utils_match_buf_num} }, + + {{CVP_VOCPROC_DYNAMIC_CAL_TYPE, + {voice_alloc_cal, voice_dealloc_cal, + voice_prepare_volume_boost, + voice_set_cal, NULL, + voice_enable_volume_boost} }, + {NULL, voice_unmap_cal_memory, + cal_utils_match_buf_num} }, + + {{CVP_VOCDEV_CFG_CAL_TYPE, + {voice_alloc_cal, voice_dealloc_cal, NULL, + voice_set_cal, NULL, NULL} }, + {NULL, voice_unmap_cal_memory, + cal_utils_match_buf_num} }, + + {{CVP_VOCPROC_STATIC_COL_CAL_TYPE, + {NULL, NULL, NULL, voice_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{CVP_VOCPROC_DYNAMIC_COL_CAL_TYPE, + {NULL, NULL, NULL, voice_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{CVS_VOCSTRM_STATIC_CAL_TYPE, + {voice_alloc_cal, voice_dealloc_cal, NULL, + voice_set_cal, NULL, NULL} }, + {NULL, voice_unmap_cal_memory, + cal_utils_match_buf_num} }, + + {{CVS_VOCSTRM_STATIC_COL_CAL_TYPE, + {NULL, NULL, NULL, voice_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{VOICE_RTAC_INFO_CAL_TYPE, + {NULL, NULL, NULL, NULL, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{VOICE_RTAC_APR_CAL_TYPE, + {NULL, NULL, NULL, NULL, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + }; + + ret = cal_utils_create_cal_types(MAX_VOICE_CAL_TYPES, common.cal_data, + cal_type_info); + if (ret < 0) { + pr_err("%s: Could not create cal type!\n", + __func__); + + ret = -EINVAL; + goto err; + } + + return ret; +err: + voice_delete_cal_data(); + memset(&common, 0, sizeof(struct common_data)); + return ret; +} + +static int voice_send_set_sound_focus_cmd(struct voice_data *v, + struct sound_focus_param soundFocusData) +{ + struct cvp_set_sound_focus_param_cmd_t cvp_set_sound_focus_param_cmd; + int ret = 0; + void *apr_cvp; + u16 cvp_handle; + int i; + + pr_debug("%s: Enter\n", __func__); + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + apr_cvp = common.apr_q6_cvp; + + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL.\n", __func__); + + ret = -EINVAL; + goto done; + } + cvp_handle = voice_get_cvp_handle(v); + + /* send Sound Focus Params to cvp */ + cvp_set_sound_focus_param_cmd.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_set_sound_focus_param_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_set_sound_focus_param_cmd) - APR_HDR_SIZE); + cvp_set_sound_focus_param_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_set_sound_focus_param_cmd.hdr.dest_port = cvp_handle; + cvp_set_sound_focus_param_cmd.hdr.token = 0; + cvp_set_sound_focus_param_cmd.hdr.opcode = + VSS_ISOUNDFOCUS_CMD_SET_SECTORS; + + memset(&(cvp_set_sound_focus_param_cmd.cvp_set_sound_focus_param), 0xFF, + sizeof(struct vss_isoundfocus_cmd_set_sectors_t)); + for (i = 0; i < MAX_SECTORS; i++) { + cvp_set_sound_focus_param_cmd.cvp_set_sound_focus_param. + start_angles[i] = soundFocusData.start_angle[i]; + cvp_set_sound_focus_param_cmd.cvp_set_sound_focus_param. + enables[i] = soundFocusData.enable[i]; + pr_debug("%s: start_angle[%d] = %d\n", + __func__, i, soundFocusData.start_angle[i]); + pr_debug("%s: enable[%d] = %d\n", + __func__, i, soundFocusData.enable[i]); + } + cvp_set_sound_focus_param_cmd.cvp_set_sound_focus_param.gain_step = + soundFocusData.gain_step; + pr_debug("%s: gain_step = %d\n", __func__, soundFocusData.gain_step); + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + + ret = apr_send_pkt(apr_cvp, (uint32_t *)&cvp_set_sound_focus_param_cmd); + if (ret < 0) { + pr_err("%s: Error in sending APR command\n", __func__); + + ret = -EINVAL; + goto done; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + + ret = -EINVAL; + goto done; + } + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto done; + } + + if (common.is_sound_focus_resp_success) { + ret = 0; + } else { + pr_err("%s: Error in setting sound focus params\n", __func__); + + ret = -EINVAL; + } + +done: + pr_debug("%s: Exit, ret=%d\n", __func__, ret); + + return ret; +} + +int voc_set_sound_focus(struct sound_focus_param soundFocusData) +{ + struct voice_data *v = NULL; + int ret = -EINVAL; + struct voice_session_itr itr; + + pr_debug("%s: Enter\n", __func__); + + mutex_lock(&common.common_lock); + voice_itr_init(&itr, ALL_SESSION_VSID); + while (voice_itr_get_next_session(&itr, &v)) { + if (v != NULL) { + mutex_lock(&v->lock); + if (is_voc_state_active(v->voc_state) && + (v->lch_mode != VOICE_LCH_START) && + !v->disable_topology) + ret = voice_send_set_sound_focus_cmd(v, + soundFocusData); + mutex_unlock(&v->lock); + } else { + pr_err("%s: invalid session\n", __func__); + + ret = -EINVAL; + break; + } + } + mutex_unlock(&common.common_lock); + pr_debug("%s: Exit, ret=%d\n", __func__, ret); + + return ret; +} + +static int voice_send_get_sound_focus_cmd(struct voice_data *v, + struct sound_focus_param *soundFocusData) +{ + struct apr_hdr cvp_get_sound_focus_param_cmd; + int ret = 0; + void *apr_cvp; + u16 cvp_handle; + int i; + + pr_debug("%s: Enter\n", __func__); + + if (!v) { + pr_err("%s: v is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + apr_cvp = common.apr_q6_cvp; + + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL\n", __func__); + + ret = -EINVAL; + goto done; + } + + cvp_handle = voice_get_cvp_handle(v); + + /* send APR command to retrieve Sound Focus Params */ + cvp_get_sound_focus_param_cmd.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_get_sound_focus_param_cmd.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_get_sound_focus_param_cmd) - APR_HDR_SIZE); + cvp_get_sound_focus_param_cmd.src_port = + voice_get_idx_for_session(v->session_id); + cvp_get_sound_focus_param_cmd.dest_port = cvp_handle; + cvp_get_sound_focus_param_cmd.token = 0; + cvp_get_sound_focus_param_cmd.opcode = VSS_ISOUNDFOCUS_CMD_GET_SECTORS; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *)&cvp_get_sound_focus_param_cmd); + if (ret < 0) { + pr_err("%s: Error in sending APR command\n", __func__); + + ret = -EINVAL; + goto done; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + + ret = -EINVAL; + goto done; + } + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto done; + } + + if (common.is_sound_focus_resp_success) { + for (i = 0; i < MAX_SECTORS; i++) { + soundFocusData->start_angle[i] = + common.soundFocusResponse.start_angles[i]; + soundFocusData->enable[i] = + common.soundFocusResponse.enables[i]; + pr_debug("%s: start_angle[%d] = %d\n", + __func__, i, soundFocusData->start_angle[i]); + pr_debug("%s: enable[%d] = %d\n", + __func__, i, soundFocusData->enable[i]); + } + soundFocusData->gain_step = common.soundFocusResponse.gain_step; + pr_debug("%s: gain_step = %d\n", __func__, + soundFocusData->gain_step); + + common.is_sound_focus_resp_success = false; + ret = 0; + } else { + pr_err("%s: Invalid payload received from CVD\n", __func__); + + ret = -EINVAL; + } +done: + pr_debug("%s: Exit, ret=%d\n", __func__, ret); + + return ret; +} + +int voc_get_sound_focus(struct sound_focus_param *soundFocusData) +{ + struct voice_data *v = NULL; + int ret = -EINVAL; + struct voice_session_itr itr; + + pr_debug("%s: Enter\n", __func__); + + mutex_lock(&common.common_lock); + voice_itr_init(&itr, ALL_SESSION_VSID); + while (voice_itr_get_next_session(&itr, &v)) { + if (v) { + mutex_lock(&v->lock); + if (is_voc_state_active(v->voc_state) && + (v->lch_mode != VOICE_LCH_START) && + !v->disable_topology) + ret = voice_send_get_sound_focus_cmd(v, + soundFocusData); + mutex_unlock(&v->lock); + } else { + pr_err("%s: invalid session\n", __func__); + + ret = -EINVAL; + break; + } + } + mutex_unlock(&common.common_lock); + pr_debug("%s: Exit, ret=%d\n", __func__, ret); + + return ret; +} + +static int is_source_tracking_shared_memomry_allocated(void) +{ + bool ret; + + pr_debug("%s: Enter\n", __func__); + + if (common.source_tracking_sh_mem.sh_mem_block.client != NULL && + common.source_tracking_sh_mem.sh_mem_block.handle != NULL) + ret = true; + else + ret = false; + + pr_debug("%s: Exit\n", __func__); + + return ret; +} + +static int voice_alloc_source_tracking_shared_memory(void) +{ + int ret = 0; + + pr_debug("%s: Enter\n", __func__); + + ret = msm_audio_ion_alloc("source_tracking_sh_mem_block", + &(common.source_tracking_sh_mem.sh_mem_block.client), + &(common.source_tracking_sh_mem.sh_mem_block.handle), + BUFFER_BLOCK_SIZE, + &(common.source_tracking_sh_mem.sh_mem_block.phys), + (size_t *)&(common.source_tracking_sh_mem.sh_mem_block.size), + &(common.source_tracking_sh_mem.sh_mem_block.data)); + if (ret < 0) { + pr_err("%s: audio ION alloc failed for sh_mem block, ret = %d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + memset((void *)(common.source_tracking_sh_mem.sh_mem_block.data), 0, + common.source_tracking_sh_mem.sh_mem_block.size); + + pr_debug("%s: sh_mem_block: phys:[%pK], data:[0x%pK], size:[%zd]\n", + __func__, + &(common.source_tracking_sh_mem.sh_mem_block.phys), + (void *)(common.source_tracking_sh_mem.sh_mem_block.data), + (size_t)(common.source_tracking_sh_mem.sh_mem_block.size)); + + ret = msm_audio_ion_alloc("source_tracking_sh_mem_table", + &(common.source_tracking_sh_mem.sh_mem_table.client), + &(common.source_tracking_sh_mem.sh_mem_table.handle), + sizeof(struct vss_imemory_table_t), + &(common.source_tracking_sh_mem.sh_mem_table.phys), + (size_t *)&(common.source_tracking_sh_mem.sh_mem_table.size), + &(common.source_tracking_sh_mem.sh_mem_table.data)); + if (ret < 0) { + pr_err("%s: audio ION alloc failed for sh_mem table, ret = %d\n", + __func__, ret); + + ret = msm_audio_ion_free( + common.source_tracking_sh_mem.sh_mem_block.client, + common.source_tracking_sh_mem.sh_mem_block.handle); + common.source_tracking_sh_mem.sh_mem_block.client = NULL; + common.source_tracking_sh_mem.sh_mem_block.handle = NULL; + if (ret < 0) + pr_err("%s: Error:%d freeing memory\n", __func__, ret); + + ret = -EINVAL; + goto done; + } + memset((void *)(common.source_tracking_sh_mem.sh_mem_table.data), 0, + common.source_tracking_sh_mem.sh_mem_table.size); + + pr_debug("%s sh_mem_table: phys:[%pK], data:[0x%pK], size:[%zd],\n", + __func__, + &(common.source_tracking_sh_mem.sh_mem_table.phys), + (void *)(common.source_tracking_sh_mem.sh_mem_table.data), + (size_t)(common.source_tracking_sh_mem.sh_mem_table.size)); + +done: + pr_debug("%s: Exit, ret=%d\n", __func__, ret); + + return ret; +} + +static int voice_alloc_and_map_source_tracking_shared_memory( + struct voice_data *v) +{ + int ret = 0; + + pr_debug("%s: Enter\n", __func__); + + ret = voice_alloc_source_tracking_shared_memory(); + if (ret) { + pr_err("%s: Failed to allocate shared memory %d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + ret = voice_map_memory_physical_cmd(v, + &(common.source_tracking_sh_mem.sh_mem_table), + common.source_tracking_sh_mem.sh_mem_block.phys, + common.source_tracking_sh_mem.sh_mem_block.size, + VOC_SOURCE_TRACKING_MEM_MAP_TOKEN); + if (ret) { + pr_err("%s: memory mapping failed %d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + +done: + pr_debug("%s: Exit, ret=%d\n", __func__, ret); + + return ret; +} + +static int voice_unmap_and_free_source_tracking_shared_memory( + struct voice_data *v) +{ + int ret = 0; + + pr_debug("%s: Enter\n", __func__); + + if (common.source_tracking_sh_mem.mem_handle != 0) { + ret = voice_send_mvm_unmap_memory_physical_cmd(v, + common.source_tracking_sh_mem.mem_handle); + if (ret < 0) { + pr_err("%s: Memory_unmap failed err %d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + } + + if ((common.source_tracking_sh_mem.sh_mem_block.client == NULL) || + (common.source_tracking_sh_mem.sh_mem_block.handle == NULL)) + goto done; + + ret = msm_audio_ion_free( + common.source_tracking_sh_mem.sh_mem_block.client, + common.source_tracking_sh_mem.sh_mem_block.handle); + if (ret < 0) { + pr_err("%s: Error:%d freeing memory\n", __func__, ret); + + ret = -EINVAL; + goto done; + } + +done: + common.source_tracking_sh_mem.mem_handle = 0; + common.source_tracking_sh_mem.sh_mem_block.client = NULL; + common.source_tracking_sh_mem.sh_mem_block.handle = NULL; + pr_debug("%s: Exit, ret=%d\n", __func__, ret); + + return ret; +} + +static int voice_send_get_source_tracking_cmd(struct voice_data *v, + struct source_tracking_param *sourceTrackingData) +{ + struct cvp_get_source_tracking_param_cmd_t st_cmd; + int ret = 0; + void *apr_cvp; + u16 cvp_handle; + int i; + + pr_debug("%s: Enter\n", __func__); + + if (!v) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + apr_cvp = common.apr_q6_cvp; + + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL.\n", __func__); + return -EINVAL; + } + + cvp_handle = voice_get_cvp_handle(v); + + if (!is_source_tracking_shared_memomry_allocated()) { + ret = voice_alloc_and_map_source_tracking_shared_memory(v); + if (ret) { + pr_err("%s: Fail in allocating/mapping shared memory\n", + __func__); + + ret = -EINVAL; + goto done; + } + } + st_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + st_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(st_cmd) - APR_HDR_SIZE); + st_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id); + st_cmd.hdr.dest_port = cvp_handle; + st_cmd.hdr.token = 0; + st_cmd.hdr.opcode = VSS_ISOURCETRACK_CMD_GET_ACTIVITY; + + st_cmd.cvp_get_source_tracking_param.mem_handle = + common.source_tracking_sh_mem.mem_handle; + st_cmd.cvp_get_source_tracking_param.mem_address_lsw = + lower_32_bits(common.source_tracking_sh_mem.sh_mem_block.phys); + st_cmd.cvp_get_source_tracking_param.mem_address_msw = + msm_audio_populate_upper_32_bits(common.source_tracking_sh_mem. + sh_mem_block.phys); + st_cmd.cvp_get_source_tracking_param.mem_size = + (uint32_t)common.source_tracking_sh_mem.sh_mem_block.size; + pr_debug("%s: mem_handle=0x%x, mem_address_lsw=0x%x, msw=0x%x, mem_size=%d\n", + __func__, + st_cmd.cvp_get_source_tracking_param.mem_handle, + st_cmd.cvp_get_source_tracking_param.mem_address_lsw, + st_cmd.cvp_get_source_tracking_param.mem_address_msw, + (uint32_t)st_cmd.cvp_get_source_tracking_param.mem_size); + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, + (uint32_t *) &st_cmd); + if (ret < 0) { + pr_err("%s: Error in sending APR command\n", __func__); + + ret = -EINVAL; + goto done; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + + ret = -EINVAL; + goto done; + } + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto done; + } + + if (common.is_source_tracking_resp_success) { + for (i = 0; i < MAX_SECTORS; i++) { + sourceTrackingData->vad[i] = + common.sourceTrackingResponse.voice_active[i]; + pr_debug("%s: vad[%d] = %d\n", + __func__, i, sourceTrackingData->vad[i]); + } + sourceTrackingData->doa_speech = + common.sourceTrackingResponse.talker_doa; + pr_debug("%s: doa_speech = %d\n", + __func__, sourceTrackingData->doa_speech); + + for (i = 0; i < MAX_NOISE_SOURCE_INDICATORS; i++) { + sourceTrackingData->doa_noise[i] = + common.sourceTrackingResponse.interferer_doa[i]; + pr_debug("%s: doa_noise[%d] = %d\n", + __func__, i, sourceTrackingData->doa_noise[i]); + } + for (i = 0; i < MAX_POLAR_ACTIVITY_INDICATORS; i++) { + sourceTrackingData->polar_activity[i] = + common.sourceTrackingResponse.sound_strength[i]; + pr_debug("%s: polar_activity[%d] = %d\n", + __func__, i, sourceTrackingData->polar_activity[i]); + } + common.is_source_tracking_resp_success = false; + ret = 0; + } else { + pr_err("%s: Error response received from CVD\n", __func__); + + ret = -EINVAL; + } +done: + pr_debug("%s: Exit, ret=%d\n", __func__, ret); + + return ret; +} + +int voc_get_source_tracking(struct source_tracking_param *sourceTrackingData) +{ + struct voice_data *v = NULL; + int ret = -EINVAL; + struct voice_session_itr itr; + + pr_debug("%s: Enter\n", __func__); + + mutex_lock(&common.common_lock); + + voice_itr_init(&itr, ALL_SESSION_VSID); + while (voice_itr_get_next_session(&itr, &v)) { + if (v != NULL) { + mutex_lock(&v->lock); + if (is_voc_state_active(v->voc_state) && + (v->lch_mode != VOICE_LCH_START) && + !v->disable_topology) + ret = voice_send_get_source_tracking_cmd(v, + sourceTrackingData); + mutex_unlock(&v->lock); + } else { + pr_err("%s: invalid session\n", __func__); + + break; + } + } + + mutex_unlock(&common.common_lock); + pr_debug("%s: Exit, ret=%d\n", __func__, ret); + + return ret; +} + +int is_voc_initialized(void) +{ + return module_initialized; +} + +static int __init voice_init(void) +{ + int rc = 0, i = 0; + + memset(&common, 0, sizeof(struct common_data)); + + /* set default value */ + common.default_mute_val = 0; /* default is un-mute */ + common.default_sample_val = 8000; + common.default_vol_step_val = 0; + common.default_vol_ramp_duration_ms = DEFAULT_VOLUME_RAMP_DURATION; + common.default_mute_ramp_duration_ms = DEFAULT_MUTE_RAMP_DURATION; + + /* Initialize EC Ref media format info */ + common.ec_ref_ext = false; + common.ec_media_fmt_info.port_id = AFE_PORT_INVALID; + common.ec_media_fmt_info.num_channels = 0; + common.ec_media_fmt_info.bits_per_sample = 16; + common.ec_media_fmt_info.sample_rate = 8000; + memset(&common.ec_media_fmt_info.channel_mapping, 0, + VSS_CHANNEL_MAPPING_SIZE); + + /* Initialize AFE Sidetone Enable */ + common.sidetone_enable = false; + + /* Initialize MVS info. */ + common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT; + + /* Initialize is low memory flag */ + common.is_destroy_cvd = false; + + /* Initialize CVD version */ + strlcpy(common.cvd_version, CVD_VERSION_DEFAULT, + sizeof(common.cvd_version)); + /* Initialize Per-Vocoder Calibration flag */ + common.is_per_vocoder_cal_enabled = false; + + mutex_init(&common.common_lock); + + /* Initialize session id with vsid */ + init_session_id(); + + for (i = 0; i < MAX_VOC_SESSIONS; i++) { + + /* initialize dev_rx and dev_tx */ + common.voice[i].dev_rx.dev_mute = common.default_mute_val; + common.voice[i].dev_tx.dev_mute = common.default_mute_val; + common.voice[i].dev_rx.volume_step_value = + common.default_vol_step_val; + common.voice[i].dev_rx.volume_ramp_duration_ms = + common.default_vol_ramp_duration_ms; + common.voice[i].dev_rx.dev_mute_ramp_duration_ms = + common.default_mute_ramp_duration_ms; + common.voice[i].dev_tx.dev_mute_ramp_duration_ms = + common.default_mute_ramp_duration_ms; + common.voice[i].stream_rx.stream_mute = common.default_mute_val; + common.voice[i].stream_tx.stream_mute = common.default_mute_val; + + common.voice[i].dev_tx.port_id = 0x100B; + common.voice[i].dev_rx.port_id = 0x100A; + common.voice[i].dev_tx.dev_id = 0; + common.voice[i].dev_rx.dev_id = 0; + common.voice[i].dev_tx.no_of_channels = 0; + common.voice[i].dev_rx.no_of_channels = 0; + common.voice[i].dev_tx.sample_rate = 8000; + common.voice[i].dev_rx.sample_rate = 8000; + common.voice[i].dev_tx.bits_per_sample = 16; + common.voice[i].dev_rx.bits_per_sample = 16; + memset(&common.voice[i].dev_tx.channel_mapping, 0, + VSS_CHANNEL_MAPPING_SIZE); + memset(&common.voice[i].dev_rx.channel_mapping, 0, + VSS_CHANNEL_MAPPING_SIZE); + common.voice[i].sidetone_gain = 0x512; + common.voice[i].dtmf_rx_detect_en = 0; + common.voice[i].lch_mode = 0; + common.voice[i].disable_topology = false; + + common.voice[i].voc_state = VOC_INIT; + + init_waitqueue_head(&common.voice[i].mvm_wait); + init_waitqueue_head(&common.voice[i].cvs_wait); + init_waitqueue_head(&common.voice[i].cvp_wait); + + mutex_init(&common.voice[i].lock); + } + + if (voice_init_cal_data()) + pr_err("%s: Could not init cal data!\n", __func__); + + if (rc == 0) + module_initialized = true; + + pr_debug("%s: rc=%d\n", __func__, rc); + return rc; +} + +device_initcall(voice_init); + +static void __exit voice_exit(void) +{ + voice_delete_cal_data(); + free_cal_map_table(); +} + +__exitcall(voice_exit); diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h new file mode 100644 index 000000000000..74d80be57931 --- /dev/null +++ b/sound/soc/msm/qdsp6v2/q6voice.h @@ -0,0 +1,1900 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __QDSP6VOICE_H__ +#define __QDSP6VOICE_H__ + +#include +#include +#include +#include + +#define MAX_VOC_PKT_SIZE 642 +#define SESSION_NAME_LEN 20 +#define NUM_OF_MEMORY_BLOCKS 1 +#define NUM_OF_BUFFERS 2 +#define VSS_NUM_CHANNELS_MAX 8 +#define VSS_CHANNEL_MAPPING_SIZE (sizeof(uint8_t) * VSS_NUM_CHANNELS_MAX) +/* + * BUFFER BLOCK SIZE based on + * the supported page size + */ +#define BUFFER_BLOCK_SIZE 4096 + +#define MAX_COL_INFO_SIZE 324 + +#define VOC_REC_UPLINK 0x00 +#define VOC_REC_DOWNLINK 0x01 +#define VOC_REC_BOTH 0x02 + +#define VSS_IVERSION_CMD_GET 0x00011378 +#define VSS_IVERSION_RSP_GET 0x00011379 +#define CVD_VERSION_STRING_MAX_SIZE 31 +#define CVD_VERSION_DEFAULT "" +#define CVD_VERSION_0_0 "0.0" +#define CVD_VERSION_2_1 "2.1" +#define CVD_VERSION_2_2 "2.2" +#define CVD_VERSION_2_3 "2.3" + +#define CVD_INT_VERSION_DEFAULT 0 +#define CVD_INT_VERSION_0_0 1 +#define CVD_INT_VERSION_2_1 2 +#define CVD_INT_VERSION_2_2 3 +#define CVD_INT_VERSION_2_3 4 +#define CVD_INT_VERSION_LAST CVD_INT_VERSION_2_3 +#define CVD_INT_VERSION_MAX (CVD_INT_VERSION_LAST + 1) + +struct cvd_version_table { + char cvd_ver[CVD_VERSION_STRING_MAX_SIZE]; + int cvd_ver_int; +}; + +int voc_get_cvd_version(char *cvd_version); + +/* Payload structure for the VSS_IVERSION_RSP_GET command response */ +struct vss_iversion_rsp_get_t { + char version[CVD_VERSION_STRING_MAX_SIZE]; + /* NULL-terminated version string */ +}; + +enum { + CVP_VOC_RX_TOPOLOGY_CAL = 0, + CVP_VOC_TX_TOPOLOGY_CAL, + CVP_VOCPROC_CAL, + CVP_VOCVOL_CAL, + CVP_VOCDEV_CFG_CAL, + CVP_VOCPROC_COL_CAL, + CVP_VOCVOL_COL_CAL, + CVS_VOCSTRM_CAL, + CVS_VOCSTRM_COL_CAL, + VOICE_RTAC_INFO_CAL, + VOICE_RTAC_APR_CAL, + MAX_VOICE_CAL_TYPES +}; + +struct voice_header { + uint32_t id; + uint32_t data_len; +}; + +struct voice_init { + struct voice_header hdr; + void *cb_handle; +}; + +/* Stream information payload structure */ +struct stream_data { + uint32_t stream_mute; + uint32_t stream_mute_ramp_duration_ms; +}; + +/* Device information payload structure */ +struct device_data { + uint32_t dev_mute; + uint32_t sample_rate; + uint16_t bits_per_sample; + uint8_t channel_mapping[VSS_NUM_CHANNELS_MAX]; + uint32_t enabled; + uint32_t dev_id; + uint32_t port_id; + uint32_t volume_step_value; + uint32_t volume_ramp_duration_ms; + uint32_t dev_mute_ramp_duration_ms; + uint32_t no_of_channels; +}; + +/* + * Format information structure to match + * vss_param_endpoint_media_format_info_t + */ +struct media_format_info { + uint32_t port_id; + uint16_t num_channels; + uint16_t bits_per_sample; + uint32_t sample_rate; + uint8_t channel_mapping[VSS_NUM_CHANNELS_MAX]; +}; + +enum { + VOC_NO_SET_PARAM_TOKEN = 0, + VOC_RTAC_SET_PARAM_TOKEN, + VOC_SET_MEDIA_FORMAT_PARAM_TOKEN, + VOC_SET_PARAM_TOKEN_MAX +}; + +struct voice_dev_route_state { + u16 rx_route_flag; + u16 tx_route_flag; +}; + +struct voice_rec_route_state { + u16 ul_flag; + u16 dl_flag; +}; + +enum { + VOC_INIT = 0, + VOC_RUN, + VOC_CHANGE, + VOC_RELEASE, + VOC_ERROR, + VOC_STANDBY, +}; + +struct mem_buffer { + dma_addr_t phys; + void *data; + uint32_t size; /* size of buffer */ +}; + +struct share_mem_buf { + struct ion_handle *handle; + struct ion_client *client; + struct mem_buffer buf[NUM_OF_BUFFERS]; +}; + +struct mem_map_table { + dma_addr_t phys; + void *data; + size_t size; /* size of buffer */ + struct ion_handle *handle; + struct ion_client *client; +}; + +/* Common */ +#define VSS_ICOMMON_CMD_SET_UI_PROPERTY 0x00011103 +/* Set a UI property */ +#define VSS_ICOMMON_CMD_MAP_MEMORY 0x00011025 +#define VSS_ICOMMON_CMD_UNMAP_MEMORY 0x00011026 +/* General shared memory; byte-accessible, 4 kB-aligned. */ +#define VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL 3 + +struct vss_icommon_cmd_map_memory_t { + uint32_t phys_addr; + /* Physical address of a memory region; must be at least + * 4 kB aligned. + */ + + uint32_t mem_size; + /* Number of bytes in the region; should be a multiple of 32. */ + + uint16_t mem_pool_id; + /* Type of memory being provided. The memory ID implicitly defines + * the characteristics of the memory. The characteristics might include + * alignment type, permissions, etc. + * Memory pool ID. Possible values: + * 3 -- VSS_ICOMMON_MEM_TYPE_SHMEM8_4K_POOL. + */ +} __packed; + +struct vss_icommon_cmd_unmap_memory_t { + uint32_t phys_addr; + /* Physical address of a memory region; must be at least + * 4 kB aligned. + */ +} __packed; + +struct vss_map_memory_cmd { + struct apr_hdr hdr; + struct vss_icommon_cmd_map_memory_t vss_map_mem; +} __packed; + +struct vss_unmap_memory_cmd { + struct apr_hdr hdr; + struct vss_icommon_cmd_unmap_memory_t vss_unmap_mem; +} __packed; + +struct vss_param_endpoint_media_format_info_t { + /* AFE port ID to which this media format corresponds to. */ + uint32_t port_id; + /* + * Number of channels of data. + * Supported values: 1 to 8 + */ + uint16_t num_channels; + /* + * Bits per sample of data. + * Supported values: 16 and 24 + */ + uint16_t bits_per_sample; + /* + * Sampling rate in Hz. + * Supported values: 8000, 11025, 16000, 22050, 24000, 32000, + * 44100, 48000, 88200, 96000, 176400, and 192000 + */ + uint32_t sample_rate; + /* + * The channel[i] mapping describes channel i. Each element i + * of the array describes channel i inside the data buffer. An + * unused or unknown channel is set to 0. + */ + uint8_t channel_mapping[VSS_NUM_CHANNELS_MAX]; +} __packed; + +struct vss_icommon_param_data_t { + /* Valid ID of the module. */ + uint32_t module_id; + /* Valid ID of the parameter. */ + uint32_t param_id; + /* + * Data size of the structure relating to the param_id/module_id + * combination in uint8_t bytes. + */ + uint16_t param_size; + /* This field must be set to zero. */ + uint16_t reserved; + /* + * Parameter data payload when inband. Should have size param_size. + * Bit size of payload must be a multiple of 4. + */ + union { + struct vss_param_endpoint_media_format_info_t media_format_info; + }; +} __packed; + +/* Payload structure for the VSS_ICOMMON_CMD_SET_PARAM_V2 command. */ +struct vss_icommon_cmd_set_param_v2_t { + /* + * Pointer to the unique identifier for an address (physical/virtual). + * + * If the parameter data payload is within the message payload + * (in-band), set this field to 0. The parameter data begins at the + * specified data payload address. + * + * If the parameter data is out-of-band, this field is the handle to + * the physical address in the shared memory that holds the parameter + * data. + */ + uint32_t mem_handle; + /* + * Location of the parameter data payload. + * + * The payload is an array of vss_icommon_param_data_t. If the + * mem_handle is 0, this field is ignored. + */ + uint64_t mem_address; + /* Size of the parameter data payload in bytes. */ + uint32_t mem_size; + /* Parameter data payload when the data is inband. */ + struct vss_icommon_param_data_t param_data; +} __packed; + +/* TO MVM commands */ +#define VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION 0x000110FF +/**< No payload. Wait for APRV2_IBASIC_RSP_RESULT response. */ + +#define VSS_IMVM_CMD_SET_POLICY_DUAL_CONTROL 0x00011327 +/* + * VSS_IMVM_CMD_SET_POLICY_DUAL_CONTROL + * Description: This command is required to let MVM know + * who is in control of session. + * Payload: Defined by vss_imvm_cmd_set_policy_dual_control_t. + * Result: Wait for APRV2_IBASIC_RSP_RESULT response. + */ + +#define VSS_IMVM_CMD_CREATE_FULL_CONTROL_SESSION 0x000110FE +/* Create a new full control MVM session. */ + +#define APRV2_IBASIC_CMD_DESTROY_SESSION 0x0001003C +/**< No payload. Wait for APRV2_IBASIC_RSP_RESULT response. */ + +#define VSS_IMVM_CMD_ATTACH_STREAM 0x0001123C +/* Attach a stream to the MVM. */ + +#define VSS_IMVM_CMD_DETACH_STREAM 0x0001123D +/* Detach a stream from the MVM. */ + +#define VSS_IMVM_CMD_ATTACH_VOCPROC 0x0001123E +/* Attach a vocproc to the MVM. The MVM will symmetrically connect this vocproc + * to all the streams currently attached to it. + */ + +#define VSS_IMVM_CMD_DETACH_VOCPROC 0x0001123F +/* Detach a vocproc from the MVM. The MVM will symmetrically disconnect this + * vocproc from all the streams to which it is currently attached. + */ + +#define VSS_IMVM_CMD_START_VOICE 0x00011190 +/**< No payload. Wait for APRV2_IBASIC_RSP_RESULT response. */ + +#define VSS_IMVM_CMD_STANDBY_VOICE 0x00011191 +/**< No payload. Wait for APRV2_IBASIC_RSP_RESULT response. */ + +#define VSS_IMVM_CMD_STOP_VOICE 0x00011192 +/**< No payload. Wait for APRV2_IBASIC_RSP_RESULT response. */ + +#define VSS_IMVM_CMD_PAUSE_VOICE 0x0001137D +/* No payload. Wait for APRV2_IBASIC_RSP_RESULT response. */ + +#define VSS_ISTREAM_CMD_ATTACH_VOCPROC 0x000110F8 +/**< Wait for APRV2_IBASIC_RSP_RESULT response. */ + +#define VSS_ISTREAM_CMD_DETACH_VOCPROC 0x000110F9 +/**< Wait for APRV2_IBASIC_RSP_RESULT response. */ + + +#define VSS_ISTREAM_CMD_SET_TTY_MODE 0x00011196 +/**< Wait for APRV2_IBASIC_RSP_RESULT response. */ + +#define VSS_ICOMMON_CMD_SET_NETWORK 0x0001119C +/* Set the network type. */ + +#define VSS_ICOMMON_CMD_SET_VOICE_TIMING 0x000111E0 +/* Set the voice timing parameters. */ + +#define VSS_IMEMORY_CMD_MAP_PHYSICAL 0x00011334 +#define VSS_IMEMORY_RSP_MAP 0x00011336 +#define VSS_IMEMORY_CMD_UNMAP 0x00011337 +#define VSS_IMVM_CMD_SET_CAL_NETWORK 0x0001137A +#define VSS_IMVM_CMD_SET_CAL_MEDIA_TYPE 0x0001137B +#define VSS_IHDVOICE_CMD_ENABLE 0x000130A2 +#define VSS_IHDVOICE_CMD_DISABLE 0x000130A3 + +enum msm_audio_voc_rate { + VOC_0_RATE, /* Blank frame */ + VOC_8_RATE, /* 1/8 rate */ + VOC_4_RATE, /* 1/4 rate */ + VOC_2_RATE, /* 1/2 rate */ + VOC_1_RATE, /* Full rate */ + VOC_8_RATE_NC /* Noncritical 1/8 rate */ +}; + +struct vss_istream_cmd_set_tty_mode_t { + uint32_t mode; + /**< + * TTY mode. + * + * 0 : TTY disabled + * 1 : HCO + * 2 : VCO + * 3 : FULL + */ +} __packed; + +struct vss_istream_cmd_attach_vocproc_t { + uint16_t handle; + /**< Handle of vocproc being attached. */ +} __packed; + +struct vss_istream_cmd_detach_vocproc_t { + uint16_t handle; + /**< Handle of vocproc being detached. */ +} __packed; + +struct vss_imvm_cmd_attach_stream_t { + uint16_t handle; + /* The stream handle to attach. */ +} __packed; + +struct vss_imvm_cmd_detach_stream_t { + uint16_t handle; + /* The stream handle to detach. */ +} __packed; + +struct vss_icommon_cmd_set_network_t { + uint32_t network_id; + /* Network ID. (Refer to VSS_NETWORK_ID_XXX). */ +} __packed; + +struct vss_icommon_cmd_set_voice_timing_t { + uint16_t mode; + /* + * The vocoder frame synchronization mode. + * + * 0 : No frame sync. + * 1 : Hard VFR (20ms Vocoder Frame Reference interrupt). + */ + uint16_t enc_offset; + /* + * The offset in microseconds from the VFR to deliver a Tx vocoder + * packet. The offset should be less than 20000us. + */ + uint16_t dec_req_offset; + /* + * The offset in microseconds from the VFR to request for an Rx vocoder + * packet. The offset should be less than 20000us. + */ + uint16_t dec_offset; + /* + * The offset in microseconds from the VFR to indicate the deadline to + * receive an Rx vocoder packet. The offset should be less than 20000us. + * Rx vocoder packets received after this deadline are not guaranteed to + * be processed. + */ +} __packed; + +struct vss_imvm_cmd_create_control_session_t { + char name[SESSION_NAME_LEN]; + /* + * A variable-sized stream name. + * + * The stream name size is the payload size minus the size of the other + * fields. + */ +} __packed; + + +struct vss_imvm_cmd_set_policy_dual_control_t { + bool enable_flag; + /* Set to TRUE to enable modem state machine control */ +} __packed; + +struct mvm_attach_vocproc_cmd { + struct apr_hdr hdr; + struct vss_istream_cmd_attach_vocproc_t mvm_attach_cvp_handle; +} __packed; + +struct mvm_detach_vocproc_cmd { + struct apr_hdr hdr; + struct vss_istream_cmd_detach_vocproc_t mvm_detach_cvp_handle; +} __packed; + +struct mvm_create_ctl_session_cmd { + struct apr_hdr hdr; + struct vss_imvm_cmd_create_control_session_t mvm_session; +} __packed; + +struct mvm_modem_dual_control_session_cmd { + struct apr_hdr hdr; + struct vss_imvm_cmd_set_policy_dual_control_t voice_ctl; +} __packed; + +struct mvm_set_tty_mode_cmd { + struct apr_hdr hdr; + struct vss_istream_cmd_set_tty_mode_t tty_mode; +} __packed; + +struct mvm_attach_stream_cmd { + struct apr_hdr hdr; + struct vss_imvm_cmd_attach_stream_t attach_stream; +} __packed; + +struct mvm_detach_stream_cmd { + struct apr_hdr hdr; + struct vss_imvm_cmd_detach_stream_t detach_stream; +} __packed; + +struct mvm_set_network_cmd { + struct apr_hdr hdr; + struct vss_icommon_cmd_set_network_t network; +} __packed; + +struct mvm_set_voice_timing_cmd { + struct apr_hdr hdr; + struct vss_icommon_cmd_set_voice_timing_t timing; +} __packed; + +struct mvm_set_hd_enable_cmd { + struct apr_hdr hdr; +} __packed; + +struct vss_imemory_table_descriptor_t { + uint32_t mem_address_lsw; + uint32_t mem_address_msw; + /* + * Base physical address of the table. The address must be aligned + * to LCM( cache_line_size, page_align, max_data_width ), where the + * attributes are specified in #VSS_IMEMORY_CMD_MAP_PHYSICAL, and + * LCM = Least Common Multiple. The table at the address must have + * the format specified by #vss_imemory_table_t. + */ + uint32_t mem_size; + /* Size in bytes of the table. */ +} __packed; + +struct vss_imemory_block_t { + uint64_t mem_address; + /* + * Base address of the memory block. The address is virtual for virtual + * memory and physical for physical memory. The address must be aligned + * to LCM( cache_line_size, page_align, max_data_width ), where the + * attributes are specified in VSS_IMEMORY_CMD_MAP_VIRTUAL or + * VSS_IMEMORY_CMD_MAP_PHYSICAL, and LCM = Least Common Multiple. + */ + uint32_t mem_size; + /* + * Size in bytes of the memory block. The size must be multiple of + * page_align, where page_align is specified in + * VSS_IMEMORY_CMD_MAP_VIRTUAL or #VSS_IMEMORY_CMD_MAP_PHYSICAL. + */ +} __packed; + +struct vss_imemory_table_t { + struct vss_imemory_table_descriptor_t next_table_descriptor; + /* + * Specifies the next table. If there is no next table, + * set the size of the table to 0 and the table address is ignored. + */ + struct vss_imemory_block_t blocks[NUM_OF_MEMORY_BLOCKS]; + /* Specifies one ore more memory blocks. */ +} __packed; + +struct vss_imemory_cmd_map_physical_t { + struct apr_hdr hdr; + struct vss_imemory_table_descriptor_t table_descriptor; + bool is_cached; + /* + * Indicates cached or uncached memory. Supported values: + * TRUE - Cached. + */ + uint16_t cache_line_size; + /* Cache line size in bytes. Supported values: 128 */ + uint32_t access_mask; + /* + * CVD's access permission to the memory while it is mapped. + * Supported values: + * bit 0 - If set, the memory is readable. + * bit 1 - If set, the memory is writable. + */ + uint32_t page_align; + /* Page frame alignment in bytes. Supported values: 4096 */ + uint8_t min_data_width; + /* + * Minimum native data type width in bits that can be accessed. + * Supported values: 8 + */ + uint8_t max_data_width; + /* + * Maximum native data type width in bits that can be accessed. + * Supported values: 64 + */ +} __packed; + +struct vss_imvm_cmd_set_cal_network_t { + struct apr_hdr hdr; + uint32_t network_id; +} __packed; + +struct vss_imvm_cmd_set_cal_media_type_t { + struct apr_hdr hdr; + uint32_t media_id; +} __packed; + +struct vss_imemory_cmd_unmap_t { + struct apr_hdr hdr; + uint32_t mem_handle; +} __packed; + +/* TO CVS commands */ +#define VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION 0x00011140 +/**< Wait for APRV2_IBASIC_RSP_RESULT response. */ + +#define VSS_ISTREAM_CMD_CREATE_FULL_CONTROL_SESSION 0x000110F7 +/* Create a new full control stream session. */ + +#define APRV2_IBASIC_CMD_DESTROY_SESSION 0x0001003C + +/* + * This command changes the mute setting. The new mute setting will + * be applied over the specified ramp duration. + */ +#define VSS_IVOLUME_CMD_MUTE_V2 0x0001138B + +#define VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA_V2 0x00011369 + +#define VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA 0x0001127A + +#define VSS_ISTREAM_CMD_REGISTER_STATIC_CALIBRATION_DATA 0x0001307D +#define VSS_ISTREAM_CMD_DEREGISTER_STATIC_CALIBRATION_DATA 0x0001307E + +#define VSS_ISTREAM_CMD_SET_MEDIA_TYPE 0x00011186 +/* Set media type on the stream. */ + +#define VSS_ISTREAM_EVT_SEND_ENC_BUFFER 0x00011015 +/* Event sent by the stream to its client to provide an encoded packet. */ + +#define VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER 0x00011017 +/* Event sent by the stream to its client requesting for a decoder packet. + * The client should respond with a VSS_ISTREAM_EVT_SEND_DEC_BUFFER event. + */ + +#define VSS_ISTREAM_EVT_OOB_NOTIFY_DEC_BUFFER_REQUEST 0x0001136E + +#define VSS_ISTREAM_EVT_SEND_DEC_BUFFER 0x00011016 +/* Event sent by the client to the stream in response to a + * VSS_ISTREAM_EVT_REQUEST_DEC_BUFFER event, providing a decoder packet. + */ + +#define VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE 0x0001113E +/* Set AMR encoder rate. */ + +#define VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE 0x0001113F +/* Set AMR-WB encoder rate. */ + +#define VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE 0x00011019 +/* Set encoder minimum and maximum rate. */ + +#define VSS_ISTREAM_CMD_SET_ENC_DTX_MODE 0x0001101D +/* Set encoder DTX mode. */ + +#define MODULE_ID_VOICE_MODULE_ST 0x00010EE3 +#define VOICE_PARAM_MOD_ENABLE 0x00010E00 +#define MOD_ENABLE_PARAM_LEN 4 + +#define VSS_IPLAYBACK_CMD_START 0x000112BD +/* Start in-call music delivery on the Tx voice path. */ + +#define VSS_IPLAYBACK_CMD_STOP 0x00011239 +/* Stop the in-call music delivery on the Tx voice path. */ + +#define VSS_IPLAYBACK_PORT_ID_DEFAULT 0x0000FFFF +/* Default AFE port ID. */ + +#define VSS_IPLAYBACK_PORT_ID_VOICE 0x00008005 +/* AFE port ID for VOICE 1. */ + +#define VSS_IPLAYBACK_PORT_ID_VOICE2 0x00008002 +/* AFE port ID for VOICE 2. */ + +#define VSS_IRECORD_CMD_START 0x000112BE +/* Start in-call conversation recording. */ +#define VSS_IRECORD_CMD_STOP 0x00011237 +/* Stop in-call conversation recording. */ + +#define VSS_IRECORD_PORT_ID_DEFAULT 0x0000FFFF +/* Default AFE port ID. */ + +#define VSS_IRECORD_TAP_POINT_NONE 0x00010F78 +/* Indicates no tapping for specified path. */ + +#define VSS_IRECORD_TAP_POINT_STREAM_END 0x00010F79 +/* Indicates that specified path should be tapped at the end of the stream. */ + +#define VSS_IRECORD_MODE_TX_RX_STEREO 0x00010F7A +/* Select Tx on left channel and Rx on right channel. */ + +#define VSS_IRECORD_MODE_TX_RX_MIXING 0x00010F7B +/* Select mixed Tx and Rx paths. */ + +#define VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO 0x00013253 + +#define VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO 0x00013254 + +#define VSS_PARAM_EC_REF_PORT_ENDPOINT_MEDIA_INFO 0x00013255 + +#define VSS_MODULE_CVD_GENERIC 0x0001316E + +#define VSS_ISTREAM_EVT_NOT_READY 0x000110FD + +#define VSS_ISTREAM_EVT_READY 0x000110FC + +#define VSS_ISTREAM_EVT_OOB_NOTIFY_DEC_BUFFER_READY 0x0001136F +/*notify dsp that decoder buffer is ready*/ + +#define VSS_ISTREAM_EVT_OOB_NOTIFY_ENC_BUFFER_READY 0x0001136C +/*dsp notifying client that encoder buffer is ready*/ + +#define VSS_ISTREAM_EVT_OOB_NOTIFY_ENC_BUFFER_CONSUMED 0x0001136D +/*notify dsp that encoder buffer is consumed*/ + +#define VSS_ISTREAM_CMD_SET_OOB_PACKET_EXCHANGE_CONFIG 0x0001136B + +#define VSS_ISTREAM_PACKET_EXCHANGE_MODE_INBAND 0 +/* In-band packet exchange mode. */ + +#define VSS_ISTREAM_PACKET_EXCHANGE_MODE_OUT_OF_BAND 1 +/* Out-of-band packet exchange mode. */ + +#define VSS_ISTREAM_CMD_SET_PACKET_EXCHANGE_MODE 0x0001136A + +struct vss_iplayback_cmd_start_t { + uint16_t port_id; + /* + * AFE Port ID from which the audio samples are available. + * To use the default AFE pseudo port (0x8005), set this value to + * #VSS_IPLAYBACK_PORT_ID_DEFAULT. + */ +} __packed; + +struct vss_irecord_cmd_start_t { + uint32_t rx_tap_point; + /* Tap point to use on the Rx path. Supported values are: + * VSS_IRECORD_TAP_POINT_NONE : Do not record Rx path. + * VSS_IRECORD_TAP_POINT_STREAM_END : Rx tap point is at the end of + * the stream. + */ + uint32_t tx_tap_point; + /* Tap point to use on the Tx path. Supported values are: + * VSS_IRECORD_TAP_POINT_NONE : Do not record tx path. + * VSS_IRECORD_TAP_POINT_STREAM_END : Tx tap point is at the end of + * the stream. + */ + uint16_t port_id; + /* AFE Port ID to which the conversation recording stream needs to be + * sent. Set this to #VSS_IRECORD_PORT_ID_DEFAULT to use default AFE + * pseudo ports (0x8003 for Rx and 0x8004 for Tx). + */ + uint32_t mode; + /* Recording Mode. The mode parameter value is ignored if the port_id + * is set to #VSS_IRECORD_PORT_ID_DEFAULT. + * The supported values: + * #VSS_IRECORD_MODE_TX_RX_STEREO + * #VSS_IRECORD_MODE_TX_RX_MIXING + */ +} __packed; + +struct vss_istream_cmd_create_passive_control_session_t { + char name[SESSION_NAME_LEN]; + /**< + * A variable-sized stream name. + * + * The stream name size is the payload size minus the size of the other + * fields. + */ +} __packed; + +#define VSS_IVOLUME_DIRECTION_TX 0 +#define VSS_IVOLUME_DIRECTION_RX 1 + +#define VSS_IVOLUME_MUTE_OFF 0 +#define VSS_IVOLUME_MUTE_ON 1 + +#define DEFAULT_MUTE_RAMP_DURATION 500 +#define DEFAULT_VOLUME_RAMP_DURATION 20 +#define MAX_RAMP_DURATION 5000 + +struct vss_ivolume_cmd_mute_v2_t { + uint16_t direction; + /* + * The direction field sets the direction to apply the mute command. + * The Supported values: + * VSS_IVOLUME_DIRECTION_TX + * VSS_IVOLUME_DIRECTION_RX + */ + uint16_t mute_flag; + /* + * Turn mute on or off. The Supported values: + * VSS_IVOLUME_MUTE_OFF + * VSS_IVOLUME_MUTE_ON + */ + uint16_t ramp_duration_ms; + /* + * Mute change ramp duration in milliseconds. + * The Supported values: 0 to 5000. + */ +} __packed; + +struct vss_istream_cmd_create_full_control_session_t { + uint16_t direction; + /* + * Stream direction. + * + * 0 : TX only + * 1 : RX only + * 2 : TX and RX + * 3 : TX and RX loopback + */ + uint32_t enc_media_type; + /* Tx vocoder type. (Refer to VSS_MEDIA_ID_XXX). */ + uint32_t dec_media_type; + /* Rx vocoder type. (Refer to VSS_MEDIA_ID_XXX). */ + uint32_t network_id; + /* Network ID. (Refer to VSS_NETWORK_ID_XXX). */ + char name[SESSION_NAME_LEN]; + /* + * A variable-sized stream name. + * + * The stream name size is the payload size minus the size of the other + * fields. + */ +} __packed; + +struct vss_istream_cmd_set_media_type_t { + uint32_t rx_media_id; + /* Set the Rx vocoder type. (Refer to VSS_MEDIA_ID_XXX). */ + uint32_t tx_media_id; + /* Set the Tx vocoder type. (Refer to VSS_MEDIA_ID_XXX). */ +} __packed; + +struct vss_istream_evt_send_enc_buffer_t { + uint32_t media_id; + /* Media ID of the packet. */ + uint8_t packet_data[MAX_VOC_PKT_SIZE]; + /* Packet data buffer. */ +} __packed; + +struct vss_istream_evt_send_dec_buffer_t { + uint32_t media_id; + /* Media ID of the packet. */ + uint8_t packet_data[MAX_VOC_PKT_SIZE]; + /* Packet data. */ +} __packed; + +struct vss_istream_cmd_voc_amr_set_enc_rate_t { + uint32_t mode; + /* Set the AMR encoder rate. + * + * 0x00000000 : 4.75 kbps + * 0x00000001 : 5.15 kbps + * 0x00000002 : 5.90 kbps + * 0x00000003 : 6.70 kbps + * 0x00000004 : 7.40 kbps + * 0x00000005 : 7.95 kbps + * 0x00000006 : 10.2 kbps + * 0x00000007 : 12.2 kbps + */ +} __packed; + +struct vss_istream_cmd_voc_amrwb_set_enc_rate_t { + uint32_t mode; + /* Set the AMR-WB encoder rate. + * + * 0x00000000 : 6.60 kbps + * 0x00000001 : 8.85 kbps + * 0x00000002 : 12.65 kbps + * 0x00000003 : 14.25 kbps + * 0x00000004 : 15.85 kbps + * 0x00000005 : 18.25 kbps + * 0x00000006 : 19.85 kbps + * 0x00000007 : 23.05 kbps + * 0x00000008 : 23.85 kbps + */ +} __packed; + +struct vss_istream_cmd_cdma_set_enc_minmax_rate_t { + uint16_t min_rate; + /* Set the lower bound encoder rate. + * + * 0x0000 : Blank frame + * 0x0001 : Eighth rate + * 0x0002 : Quarter rate + * 0x0003 : Half rate + * 0x0004 : Full rate + */ + uint16_t max_rate; + /* Set the upper bound encoder rate. + * + * 0x0000 : Blank frame + * 0x0001 : Eighth rate + * 0x0002 : Quarter rate + * 0x0003 : Half rate + * 0x0004 : Full rate + */ +} __packed; + +struct vss_istream_cmd_set_enc_dtx_mode_t { + uint32_t enable; + /* Toggle DTX on or off. + * + * 0 : Disables DTX + * 1 : Enables DTX + */ +} __packed; + +struct vss_istream_cmd_register_calibration_data_v2_t { + uint32_t cal_mem_handle; + /* Handle to the shared memory that holds the calibration data. */ + uint32_t cal_mem_address_lsw; + uint32_t cal_mem_address_msw; + /* Location of calibration data. */ + uint32_t cal_mem_size; + /* Size of the calibration data in bytes. */ + uint8_t column_info[MAX_COL_INFO_SIZE]; + /* + * Column info contains the number of columns and the array of columns + * in the calibration table. The order in which the columns are provided + * here must match the order in which they exist in the calibration + * table provided. + */ +} __packed; + +struct vss_icommon_cmd_set_ui_property_enable_t { + uint32_t module_id; + /* Unique ID of the module. */ + uint32_t param_id; + /* Unique ID of the parameter. */ + uint16_t param_size; + /* Size of the parameter in bytes: MOD_ENABLE_PARAM_LEN */ + uint16_t reserved; + /* Reserved; set to 0. */ + uint16_t enable; + uint16_t reserved_field; + /* Reserved, set to 0. */ +}; + +/* + * Event sent by the stream to the client that enables Rx DTMF + * detection whenever DTMF is detected in the Rx path. + * + * The DTMF detection feature can only be used to detect DTMF + * frequencies as listed in the vss_istream_evt_rx_dtmf_detected_t + * structure. + */ + +#define VSS_ISTREAM_EVT_RX_DTMF_DETECTED 0x0001101A + +struct vss_istream_cmd_set_rx_dtmf_detection { + /* + * Enables/disables Rx DTMF detection + * + * Possible values are + * 0 - disable + * 1 - enable + * + */ + uint32_t enable; +}; + +#define VSS_ISTREAM_CMD_SET_RX_DTMF_DETECTION 0x00011027 + +struct vss_istream_evt_rx_dtmf_detected { + uint16_t low_freq; + /* + * Detected low frequency. Possible values: + * 697 Hz + * 770 Hz + * 852 Hz + * 941 Hz + */ + uint16_t high_freq; + /* + * Detected high frequency. Possible values: + * 1209 Hz + * 1336 Hz + * 1477 Hz + * 1633 Hz + */ +}; + +struct cvs_set_rx_dtmf_detection_cmd { + struct apr_hdr hdr; + struct vss_istream_cmd_set_rx_dtmf_detection cvs_dtmf_det; +} __packed; + + +struct cvs_create_passive_ctl_session_cmd { + struct apr_hdr hdr; + struct vss_istream_cmd_create_passive_control_session_t cvs_session; +} __packed; + +struct cvs_create_full_ctl_session_cmd { + struct apr_hdr hdr; + struct vss_istream_cmd_create_full_control_session_t cvs_session; +} __packed; + +struct cvs_destroy_session_cmd { + struct apr_hdr hdr; +} __packed; + +struct cvs_set_mute_cmd { + struct apr_hdr hdr; + struct vss_ivolume_cmd_mute_v2_t cvs_set_mute; +} __packed; + +struct cvs_set_media_type_cmd { + struct apr_hdr hdr; + struct vss_istream_cmd_set_media_type_t media_type; +} __packed; + +struct cvs_send_dec_buf_cmd { + struct apr_hdr hdr; + struct vss_istream_evt_send_dec_buffer_t dec_buf; +} __packed; + +struct cvs_set_amr_enc_rate_cmd { + struct apr_hdr hdr; + struct vss_istream_cmd_voc_amr_set_enc_rate_t amr_rate; +} __packed; + +struct cvs_set_amrwb_enc_rate_cmd { + struct apr_hdr hdr; + struct vss_istream_cmd_voc_amrwb_set_enc_rate_t amrwb_rate; +} __packed; + +struct cvs_set_cdma_enc_minmax_rate_cmd { + struct apr_hdr hdr; + struct vss_istream_cmd_cdma_set_enc_minmax_rate_t cdma_rate; +} __packed; + +struct cvs_set_enc_dtx_mode_cmd { + struct apr_hdr hdr; + struct vss_istream_cmd_set_enc_dtx_mode_t dtx_mode; +} __packed; + +struct cvs_register_cal_data_cmd { + struct apr_hdr hdr; + struct vss_istream_cmd_register_calibration_data_v2_t cvs_cal_data; +} __packed; + +struct cvs_deregister_cal_data_cmd { + struct apr_hdr hdr; +} __packed; + +struct cvs_set_pp_enable_cmd { + struct apr_hdr hdr; + struct vss_icommon_cmd_set_ui_property_enable_t vss_set_pp; +} __packed; +struct cvs_start_record_cmd { + struct apr_hdr hdr; + struct vss_irecord_cmd_start_t rec_mode; +} __packed; + +struct cvs_start_playback_cmd { + struct apr_hdr hdr; + struct vss_iplayback_cmd_start_t playback_mode; +} __packed; + +struct cvs_dec_buffer_ready_cmd { + struct apr_hdr hdr; +} __packed; + +struct cvs_enc_buffer_consumed_cmd { + struct apr_hdr hdr; +} __packed; + +struct vss_istream_cmd_set_oob_packet_exchange_config_t { + struct apr_hdr hdr; + uint32_t mem_handle; + uint32_t enc_buf_addr_lsw; + uint32_t enc_buf_addr_msw; + uint32_t enc_buf_size; + uint32_t dec_buf_addr_lsw; + uint32_t dec_buf_addr_msw; + uint32_t dec_buf_size; +} __packed; + +struct vss_istream_cmd_set_packet_exchange_mode_t { + struct apr_hdr hdr; + uint32_t mode; +} __packed; + +/* TO CVP commands */ + +#define VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION 0x000100C3 +/**< Wait for APRV2_IBASIC_RSP_RESULT response. */ + +#define APRV2_IBASIC_CMD_DESTROY_SESSION 0x0001003C + +#define VSS_IVOCPROC_CMD_SET_DEVICE_V2 0x000112C6 + +#define VSS_IVOCPROC_CMD_SET_DEVICE_V3 0x0001316A + +#define VSS_IVOCPROC_CMD_TOPOLOGY_SET_DEV_CHANNELS 0x00013199 + +#define VSS_IVOCPROC_CMD_TOPOLOGY_COMMIT 0x00013198 + +#define VSS_IVOCPROC_CMD_SET_VP3_DATA 0x000110EB + +#define VSS_IVOLUME_CMD_SET_STEP 0x000112C2 + +#define VSS_IVOCPROC_CMD_ENABLE 0x000100C6 +/**< No payload. Wait for APRV2_IBASIC_RSP_RESULT response. */ + +#define VSS_IVOCPROC_CMD_DISABLE 0x000110E1 +/**< No payload. Wait for APRV2_IBASIC_RSP_RESULT response. */ + +/* + * Registers the memory that contains device specific configuration data with + * the vocproc. The client must register device configuration data with the + * vocproc that corresponds with the device being set on the vocproc. + */ +#define VSS_IVOCPROC_CMD_REGISTER_DEVICE_CONFIG 0x00011371 + +/* + * Deregisters the memory that holds device configuration data from the + vocproc. +*/ +#define VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG 0x00011372 + +#define VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2 0x00011373 +#define VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA 0x00011276 + +#define VSS_IVOCPROC_CMD_REGISTER_VOL_CALIBRATION_DATA 0x00011374 +#define VSS_IVOCPROC_CMD_DEREGISTER_VOL_CALIBRATION_DATA 0x00011375 + +#define VSS_IVOCPROC_CMD_REGISTER_STATIC_CALIBRATION_DATA 0x00013079 +#define VSS_IVOCPROC_CMD_DEREGISTER_STATIC_CALIBRATION_DATA 0x0001307A + +#define VSS_IVOCPROC_CMD_REGISTER_DYNAMIC_CALIBRATION_DATA 0x0001307B +#define VSS_IVOCPROC_CMD_DEREGISTER_DYNAMIC_CALIBRATION_DATA 0x0001307C + +#define VSS_IVOCPROC_TOPOLOGY_ID_NONE 0x00010F70 +#define VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS 0x00010F71 +#define VSS_IVOCPROC_TOPOLOGY_ID_TX_DM_FLUENCE 0x00010F72 + +#define VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT 0x00010F77 + +/* Newtwork IDs */ +#define VSS_ICOMMON_CAL_NETWORK_ID_NONE 0x0001135E + +/* Select internal mixing mode. */ +#define VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING 0x00010F7C + +/* Select external mixing mode. */ +#define VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING 0x00010F7D + +/* Default AFE port ID. Applicable to Tx and Rx. */ +#define VSS_IVOCPROC_PORT_ID_NONE 0xFFFF + +#define VSS_NETWORK_ID_DEFAULT 0x00010037 + +/* Voice over Internet Protocol (VoIP) network ID. Common for all bands.*/ +#define VSS_NETWORK_ID_VOIP 0x00011362 + +/* Media types */ +#define VSS_MEDIA_ID_EVRC_MODEM 0x00010FC2 +/* 80-VF690-47 CDMA enhanced variable rate vocoder modem format. */ +#define VSS_MEDIA_ID_AMR_NB_MODEM 0x00010FC6 +/* 80-VF690-47 UMTS AMR-NB vocoder modem format. */ +#define VSS_MEDIA_ID_AMR_WB_MODEM 0x00010FC7 +/* 80-VF690-47 UMTS AMR-WB vocoder modem format. */ + +#define VSS_MEDIA_ID_PCM_8_KHZ 0x00010FCB +#define VSS_MEDIA_ID_PCM_16_KHZ 0x00010FCC +#define VSS_MEDIA_ID_PCM_32_KHZ 0x00010FD9 +#define VSS_MEDIA_ID_PCM_48_KHZ 0x00010FD6 + +/* Linear PCM (16-bit, little-endian). */ +#define VSS_MEDIA_ID_G711_ALAW 0x00010FCD +/* G.711 a-law (contains two 10ms vocoder frames). */ +#define VSS_MEDIA_ID_G711_MULAW 0x00010FCE +/* G.711 mu-law (contains two 10ms vocoder frames). */ +#define VSS_MEDIA_ID_G729 0x00010FD0 +/* G.729AB (contains two 10ms vocoder frames. */ +#define VSS_MEDIA_ID_4GV_NB_MODEM 0x00010FC3 +/*CDMA EVRC-B vocoder modem format */ +#define VSS_MEDIA_ID_4GV_WB_MODEM 0x00010FC4 +/*CDMA EVRC-WB vocoder modem format */ +#define VSS_MEDIA_ID_4GV_NW_MODEM 0x00010FC5 +/*CDMA EVRC-NW vocoder modem format */ + +#define VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V2 0x000112BF +#define VSS_IVOCPROC_CMD_CREATE_FULL_CONTROL_SESSION_V3 0x00013169 + +#define VSS_NUM_DEV_CHANNELS_1 1 +#define VSS_NUM_DEV_CHANNELS_2 2 +#define VSS_NUM_DEV_CHANNELS_3 3 +#define VSS_NUM_DEV_CHANNELS_4 4 + +struct vss_ivocproc_cmd_create_full_control_session_v2_t { + uint16_t direction; + /* + * Vocproc direction. The supported values: + * VSS_IVOCPROC_DIRECTION_RX + * VSS_IVOCPROC_DIRECTION_TX + * VSS_IVOCPROC_DIRECTION_RX_TX + */ + uint16_t tx_port_id; + /* + * Tx device port ID to which the vocproc connects. If a port ID is + * not being supplied, set this to #VSS_IVOCPROC_PORT_ID_NONE. + */ + uint32_t tx_topology_id; + /* + * Tx path topology ID. If a topology ID is not being supplied, set + * this to #VSS_IVOCPROC_TOPOLOGY_ID_NONE. + */ + uint16_t rx_port_id; + /* + * Rx device port ID to which the vocproc connects. If a port ID is + * not being supplied, set this to #VSS_IVOCPROC_PORT_ID_NONE. + */ + uint32_t rx_topology_id; + /* + * Rx path topology ID. If a topology ID is not being supplied, set + * this to #VSS_IVOCPROC_TOPOLOGY_ID_NONE. + */ + uint32_t profile_id; + /* Voice calibration profile ID. */ + uint32_t vocproc_mode; + /* + * Vocproc mode. The supported values: + * VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING + * VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING + */ + uint16_t ec_ref_port_id; + /* + * Port ID to which the vocproc connects for receiving echo + * cancellation reference signal. If a port ID is not being supplied, + * set this to #VSS_IVOCPROC_PORT_ID_NONE. This parameter value is + * ignored when the vocproc_mode parameter is set to + * VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING. + */ + char name[SESSION_NAME_LEN]; + /* + * Session name string used to identify a session that can be shared + * with passive controllers (optional). The string size, including the + * NULL termination character, is limited to 31 characters. + */ +} __packed; + +struct vss_ivocproc_cmd_set_volume_index_t { + uint16_t vol_index; + /* + * Volume index utilized by the vocproc to index into the volume table + * provided in VSS_IVOCPROC_CMD_CACHE_VOLUME_CALIBRATION_TABLE and set + * volume on the VDSP. + */ +} __packed; + +struct vss_ivolume_cmd_set_step_t { + uint16_t direction; + /* + * The direction field sets the direction to apply the volume command. + * The supported values: + * #VSS_IVOLUME_DIRECTION_RX + */ + uint32_t value; + /* + * Volume step used to find the corresponding linear volume and + * the best match index in the registered volume calibration table. + */ + uint16_t ramp_duration_ms; + /* + * Volume change ramp duration in milliseconds. + * The supported values: 0 to 5000. + */ +} __packed; + +struct vss_ivocproc_cmd_set_device_v2_t { + uint16_t tx_port_id; + /* + * TX device port ID which vocproc will connect to. + * VSS_IVOCPROC_PORT_ID_NONE means vocproc will not connect to any port. + */ + uint32_t tx_topology_id; + /* + * TX leg topology ID. + * VSS_IVOCPROC_TOPOLOGY_ID_NONE means vocproc does not contain any + * pre/post-processing blocks and is pass-through. + */ + uint16_t rx_port_id; + /* + * RX device port ID which vocproc will connect to. + * VSS_IVOCPROC_PORT_ID_NONE means vocproc will not connect to any port. + */ + uint32_t rx_topology_id; + /* + * RX leg topology ID. + * VSS_IVOCPROC_TOPOLOGY_ID_NONE means vocproc does not contain any + * pre/post-processing blocks and is pass-through. + */ + uint32_t vocproc_mode; + /* Vocproc mode. The supported values: + * VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING - 0x00010F7C + * VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING - 0x00010F7D + */ + uint16_t ec_ref_port_id; + /* Port ID to which the vocproc connects for receiving + * echo + */ +} __packed; + +struct vss_ivocproc_cmd_register_device_config_t { + uint32_t mem_handle; + /* + * Handle to the shared memory that holds the per-network calibration + * data. + */ + uint32_t mem_address_lsw; + uint32_t mem_address_msw; + /* Location of calibration data. */ + uint32_t mem_size; + /* Size of the calibration data in bytes. */ +} __packed; + +struct vss_ivocproc_cmd_register_calibration_data_v2_t { + uint32_t cal_mem_handle; + /* + * Handle to the shared memory that holds the per-network calibration + * data. + */ + uint32_t cal_mem_address_lsw; + uint32_t cal_mem_address_msw; + /* Location of calibration data. */ + uint32_t cal_mem_size; + /* Size of the calibration data in bytes. */ + uint8_t column_info[MAX_COL_INFO_SIZE]; + /* + * Column info contains the number of columns and the array of columns + * in the calibration table. The order in which the columns are provided + * here must match the order in which they exist in the calibration + * table provided. + */ +} __packed; + +struct vss_ivocproc_cmd_register_volume_cal_data_t { + uint32_t cal_mem_handle; + /* + * Handle to the shared memory that holds the volume calibration + * data. + */ + uint32_t cal_mem_address_lsw; + uint32_t cal_mem_address_msw; + /* Location of volume calibration data. */ + uint32_t cal_mem_size; + /* Size of the volume calibration data in bytes. */ + uint8_t column_info[MAX_COL_INFO_SIZE]; + /* + * Column info contains the number of columns and the array of columns + * in the calibration table. The order in which the columns are provided + * here must match the order in which they exist in the calibration + * table provided. + */ +} __packed; + +struct vss_ivocproc_cmd_topology_set_dev_channels_t { + uint16_t tx_num_channels; + /* + * Number of Mics. + * Supported values + * 1 VSS_NUM_DEV_CHANNELS_1 + * 2 VSS_NUM_DEV_CHANNELS_2 + * 3 VSS_NUM_DEV_CHANNELS_3 + * 4 VSS_NUM_DEV_CHANNELS_4 + */ + uint16_t rx_num_channels; + /* + * Number of speaker channels. + * Supported values + * 1 VSS_NUM_DEV_CHANNELS_1 + */ +} __packed; + +/* Starts a vocoder PCM session */ +#define VSS_IVPCM_CMD_START_V2 0x00011339 + +/* Default tap point location on the TX path. */ +#define VSS_IVPCM_TAP_POINT_TX_DEFAULT 0x00011289 + +/* Default tap point location on the RX path. */ +#define VSS_IVPCM_TAP_POINT_RX_DEFAULT 0x0001128A + +/* Indicates tap point direction is output. */ +#define VSS_IVPCM_TAP_POINT_DIR_OUT 0 + +/* Indicates tap point direction is input. */ +#define VSS_IVPCM_TAP_POINT_DIR_IN 1 + +/* Indicates tap point direction is output and input. */ +#define VSS_IVPCM_TAP_POINT_DIR_OUT_IN 2 + + +#define VSS_IVPCM_SAMPLING_RATE_AUTO 0 + +/* Indicates 8 KHz vocoder PCM sampling rate. */ +#define VSS_IVPCM_SAMPLING_RATE_8K 8000 + +/* Indicates 16 KHz vocoder PCM sampling rate. */ +#define VSS_IVPCM_SAMPLING_RATE_16K 16000 + +/* RX and TX */ +#define MAX_TAP_POINTS_SUPPORTED 2 + +struct vss_ivpcm_tap_point { + uint32_t tap_point; + uint16_t direction; + uint16_t sampling_rate; + uint16_t duration; +} __packed; + + +struct vss_ivpcm_cmd_start_v2_t { + uint32_t mem_handle; + uint32_t num_tap_points; + struct vss_ivpcm_tap_point tap_points[MAX_TAP_POINTS_SUPPORTED]; +} __packed; + +#define VSS_IVPCM_EVT_PUSH_BUFFER_V2 0x0001133A + +/* Push buffer event mask indicating output buffer is filled. */ +#define VSS_IVPCM_PUSH_BUFFER_MASK_OUTPUT_BUFFER 1 + +/* Push buffer event mask indicating input buffer is consumed. */ +#define VSS_IVPCM_PUSH_BUFFER_MASK_INPUT_BUFFER 2 + + +struct vss_ivpcm_evt_push_buffer_v2_t { + uint32_t tap_point; + uint32_t push_buf_mask; + uint64_t out_buf_mem_address; + uint16_t out_buf_mem_size; + uint64_t in_buf_mem_address; + uint16_t in_buf_mem_size; + uint16_t sampling_rate; + uint16_t num_in_channels; +} __packed; + +#define VSS_IVPCM_EVT_NOTIFY_V2 0x0001133B + +/* Notify event mask indicates output buffer is filled. */ +#define VSS_IVPCM_NOTIFY_MASK_OUTPUT_BUFFER 1 + +/* Notify event mask indicates input buffer is consumed. */ +#define VSS_IVPCM_NOTIFY_MASK_INPUT_BUFFER 2 + +/* Notify event mask indicates a timetick */ +#define VSS_IVPCM_NOTIFY_MASK_TIMETICK 4 + +/* Notify event mask indicates an error occurred in output buffer operation */ +#define VSS_IVPCM_NOTIFY_MASK_OUTPUT_ERROR 8 + +/* Notify event mask indicates an error occurred in input buffer operation */ +#define VSS_IVPCM_NOTIFY_MASK_INPUT_ERROR 16 + + +struct vss_ivpcm_evt_notify_v2_t { + uint32_t tap_point; + uint32_t notify_mask; + uint64_t out_buff_addr; + uint64_t in_buff_addr; + uint16_t filled_out_size; + uint16_t request_buf_size; + uint16_t sampling_rate; + uint16_t num_out_channels; +} __packed; + +struct cvp_start_cmd { + struct apr_hdr hdr; + struct vss_ivpcm_cmd_start_v2_t vpcm_start_cmd; +} __packed; + +struct cvp_push_buf_cmd { + struct apr_hdr hdr; + struct vss_ivpcm_evt_push_buffer_v2_t vpcm_evt_push_buffer; +} __packed; + +#define VSS_IVPCM_CMD_STOP 0x0001100B + +struct cvp_create_full_ctl_session_cmd { + struct apr_hdr hdr; + struct vss_ivocproc_cmd_create_full_control_session_v2_t cvp_session; +} __packed; + +struct cvp_command { + struct apr_hdr hdr; +} __packed; + +struct cvp_set_device_cmd { + struct apr_hdr hdr; + struct vss_ivocproc_cmd_set_device_v2_t cvp_set_device_v2; +} __packed; + +struct cvp_set_dev_channels_cmd { + struct apr_hdr hdr; + struct vss_ivocproc_cmd_topology_set_dev_channels_t cvp_set_channels; +} __packed; + +struct cvp_set_media_format_cmd { + struct apr_hdr hdr; + struct vss_icommon_cmd_set_param_v2_t cvp_set_param_v2; +} __packed; + +struct cvp_set_vp3_data_cmd { + struct apr_hdr hdr; +} __packed; + +struct cvp_set_rx_volume_index_cmd { + struct apr_hdr hdr; + struct vss_ivocproc_cmd_set_volume_index_t cvp_set_vol_idx; +} __packed; + +struct cvp_set_rx_volume_step_cmd { + struct apr_hdr hdr; + struct vss_ivolume_cmd_set_step_t cvp_set_vol_step; +} __packed; + +struct cvp_register_dev_cfg_cmd { + struct apr_hdr hdr; + struct vss_ivocproc_cmd_register_device_config_t cvp_dev_cfg_data; +} __packed; + +struct cvp_deregister_dev_cfg_cmd { + struct apr_hdr hdr; +} __packed; + +struct cvp_register_cal_data_cmd { + struct apr_hdr hdr; + struct vss_ivocproc_cmd_register_calibration_data_v2_t cvp_cal_data; +} __packed; + +struct cvp_deregister_cal_data_cmd { + struct apr_hdr hdr; +} __packed; + +struct cvp_register_vol_cal_data_cmd { + struct apr_hdr hdr; + struct vss_ivocproc_cmd_register_volume_cal_data_t cvp_vol_cal_data; +} __packed; + +struct cvp_deregister_vol_cal_data_cmd { + struct apr_hdr hdr; +} __packed; + +struct cvp_set_mute_cmd { + struct apr_hdr hdr; + struct vss_ivolume_cmd_mute_v2_t cvp_set_mute; +} __packed; + +/* CB for up-link packets. */ +typedef void (*ul_cb_fn)(uint8_t *voc_pkt, + uint32_t pkt_len, + uint32_t timestamp, + void *private_data); + +/* CB for down-link packets. */ +typedef void (*dl_cb_fn)(uint8_t *voc_pkt, + void *private_data); + +/* CB for DTMF RX Detection */ +typedef void (*dtmf_rx_det_cb_fn)(uint8_t *pkt, + char *session, + void *private_data); + +typedef void (*voip_ssr_cb) (uint32_t opcode, + void *private_data); + +typedef void (*hostpcm_cb_fn)(uint8_t *data, + char *session, + void *private_data); + +struct mvs_driver_info { + uint32_t media_type; + uint32_t rate; + uint32_t network_type; + uint32_t dtx_mode; + ul_cb_fn ul_cb; + dl_cb_fn dl_cb; + voip_ssr_cb ssr_cb; + void *private_data; + uint32_t evrc_min_rate; + uint32_t evrc_max_rate; +}; + +struct dtmf_driver_info { + dtmf_rx_det_cb_fn dtmf_rx_ul_cb; + void *private_data; +}; + +struct hostpcm_driver_info { + hostpcm_cb_fn hostpcm_evt_cb; + void *private_data; +}; + +struct incall_rec_info { + uint32_t rec_enable; + uint32_t rec_mode; + uint32_t recording; +}; + +struct incall_music_info { + uint32_t play_enable; + uint32_t playing; + int count; + int force; + uint16_t port_id; +}; + +struct share_memory_info { + u32 mem_handle; + struct share_mem_buf sh_buf; + struct mem_map_table memtbl; +}; + +#define VSS_ISOUNDFOCUS_CMD_SET_SECTORS 0x00013133 +#define VSS_ISOUNDFOCUS_CMD_GET_SECTORS 0x00013134 +#define VSS_ISOUNDFOCUS_RSP_GET_SECTORS 0x00013135 +#define VSS_ISOURCETRACK_CMD_GET_ACTIVITY 0x00013136 + +struct vss_isoundfocus_cmd_set_sectors_t { + uint16_t start_angles[8]; + uint8_t enables[8]; + uint16_t gain_step; +} __packed; + +/* Payload of the VSS_ISOUNDFOCUS_RSP_GET_SECTORS response */ +struct vss_isoundfocus_rsp_get_sectors_t { + uint16_t start_angles[8]; + uint8_t enables[8]; + uint16_t gain_step; +} __packed; + +struct cvp_set_sound_focus_param_cmd_t { + struct apr_hdr hdr; + struct vss_isoundfocus_cmd_set_sectors_t cvp_set_sound_focus_param; +} __packed; + +/* Payload structure for the VSS_ISOURCETRACK_CMD_GET_ACTIVITY command */ +struct vss_isourcetrack_cmd_get_activity_t { + uint32_t mem_handle; + uint32_t mem_address_lsw; + uint32_t mem_address_msw; + uint32_t mem_size; +} __packed; + +struct cvp_get_source_tracking_param_cmd_t { + struct apr_hdr hdr; + struct vss_isourcetrack_cmd_get_activity_t + cvp_get_source_tracking_param; +} __packed; + +/* Structure for the sound activity data */ +struct vss_isourcetrack_activity_data_t { + uint8_t voice_active[8]; + uint16_t talker_doa; + uint16_t interferer_doa[3]; + uint8_t sound_strength[360]; +} __packed; + +struct shared_mem_info { + uint32_t mem_handle; + struct mem_map_table sh_mem_block; + struct mem_map_table sh_mem_table; +}; + +struct voice_data { + int voc_state;/*INIT, CHANGE, RELEASE, RUN */ + + /* Shared mem to store decoder and encoder packets */ + struct share_memory_info shmem_info; + + wait_queue_head_t mvm_wait; + wait_queue_head_t cvs_wait; + wait_queue_head_t cvp_wait; + + /* Cache the values related to Rx and Tx devices */ + struct device_data dev_rx; + struct device_data dev_tx; + + /* Cache the values related to Rx and Tx streams */ + struct stream_data stream_rx; + struct stream_data stream_tx; + + u32 mvm_state; + u32 cvs_state; + u32 cvp_state; + + u32 async_err; + + /* Handle to MVM in the Q6 */ + u16 mvm_handle; + /* Handle to CVS in the Q6 */ + u16 cvs_handle; + /* Handle to CVP in the Q6 */ + u16 cvp_handle; + + struct mutex lock; + + bool disable_topology; + + uint16_t sidetone_gain; + uint8_t tty_mode; + /* slowtalk enable value */ + uint32_t st_enable; + uint32_t hd_enable; + uint32_t dtmf_rx_detect_en; + /* Local Call Hold mode */ + uint8_t lch_mode; + + struct voice_dev_route_state voc_route_state; + + u32 session_id; + + struct incall_rec_info rec_info; + + struct incall_music_info music_info; + + struct voice_rec_route_state rec_route_state; +}; + +struct cal_mem { + struct ion_handle *handle; + uint32_t phy; + void *buf; +}; + +#define MAX_VOC_SESSIONS 8 + +struct common_data { + /* these default values are for all devices */ + uint32_t default_mute_val; + uint32_t default_sample_val; + uint32_t default_vol_step_val; + uint32_t default_vol_ramp_duration_ms; + uint32_t default_mute_ramp_duration_ms; + bool ec_ref_ext; + struct media_format_info ec_media_fmt_info; + + /* APR to MVM in the Q6 */ + void *apr_q6_mvm; + /* APR to CVS in the Q6 */ + void *apr_q6_cvs; + /* APR to CVP in the Q6 */ + void *apr_q6_cvp; + + struct cal_type_data *cal_data[MAX_VOICE_CAL_TYPES]; + + struct mem_map_table cal_mem_map_table; + uint32_t cal_mem_handle; + + struct mem_map_table rtac_mem_map_table; + uint32_t rtac_mem_handle; + + uint32_t voice_host_pcm_mem_handle; + + struct cal_mem cvp_cal; + struct cal_mem cvs_cal; + + struct mutex common_lock; + + struct mvs_driver_info mvs_info; + + struct dtmf_driver_info dtmf_info; + + struct hostpcm_driver_info hostpcm_info; + + struct voice_data voice[MAX_VOC_SESSIONS]; + + bool srvcc_rec_flag; + bool is_destroy_cvd; + char cvd_version[CVD_VERSION_STRING_MAX_SIZE]; + bool is_per_vocoder_cal_enabled; + bool is_sound_focus_resp_success; + bool is_source_tracking_resp_success; + struct vss_isoundfocus_rsp_get_sectors_t soundFocusResponse; + struct shared_mem_info source_tracking_sh_mem; + struct vss_isourcetrack_activity_data_t sourceTrackingResponse; + bool sidetone_enable; +}; + +struct voice_session_itr { + int cur_idx; + int session_idx; +}; + +void voc_register_mvs_cb(ul_cb_fn ul_cb, + dl_cb_fn dl_cb, + voip_ssr_cb ssr_cb, + void *private_data); + +void voc_register_dtmf_rx_detection_cb(dtmf_rx_det_cb_fn dtmf_rx_ul_cb, + void *private_data); + +void voc_config_vocoder(uint32_t media_type, + uint32_t rate, + uint32_t network_type, + uint32_t dtx_mode, + uint32_t evrc_min_rate, + uint32_t evrc_max_rate); + +enum { + DEV_RX = 0, + DEV_TX, +}; + +enum { + RX_PATH = 0, + TX_PATH, + EC_REF_PATH, +}; + +#define VOC_PATH_PASSIVE 0 +#define VOC_PATH_FULL 1 +#define VOC_PATH_VOLTE_PASSIVE 2 +#define VOC_PATH_VOICE2_PASSIVE 3 +#define VOC_PATH_QCHAT_PASSIVE 4 +#define VOC_PATH_VOWLAN_PASSIVE 5 +#define VOC_PATH_VOICEMMODE1_PASSIVE 6 +#define VOC_PATH_VOICEMMODE2_PASSIVE 7 + +#define MAX_SESSION_NAME_LEN 32 +#define VOICE_SESSION_NAME "Voice session" +#define VOIP_SESSION_NAME "VoIP session" +#define VOLTE_SESSION_NAME "VoLTE session" +#define VOICE2_SESSION_NAME "Voice2 session" +#define QCHAT_SESSION_NAME "QCHAT session" +#define VOWLAN_SESSION_NAME "VoWLAN session" +#define VOICEMMODE1_NAME "VoiceMMode1" +#define VOICEMMODE2_NAME "VoiceMMode2" + +#define VOICE2_SESSION_VSID_STR "10DC1000" +#define QCHAT_SESSION_VSID_STR "10803000" +#define VOWLAN_SESSION_VSID_STR "10002000" +#define VOICEMMODE1_VSID_STR "11C05000" +#define VOICEMMODE2_VSID_STR "11DC5000" +#define VOICE_SESSION_VSID 0x10C01000 +#define VOICE2_SESSION_VSID 0x10DC1000 +#define VOLTE_SESSION_VSID 0x10C02000 +#define VOIP_SESSION_VSID 0x10004000 +#define QCHAT_SESSION_VSID 0x10803000 +#define VOWLAN_SESSION_VSID 0x10002000 +#define VOICEMMODE1_VSID 0x11C05000 +#define VOICEMMODE2_VSID 0x11DC5000 +#define ALL_SESSION_VSID 0xFFFFFFFF +#define VSID_MAX ALL_SESSION_VSID + +/* called by alsa driver */ +int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, + uint32_t enable); +int voc_get_pp_enable(uint32_t session_id, uint32_t module_id); +int voc_set_hd_enable(uint32_t session_id, uint32_t enable); +uint8_t voc_get_tty_mode(uint32_t session_id); +int voc_set_tty_mode(uint32_t session_id, uint8_t tty_mode); +int voc_start_voice_call(uint32_t session_id); +int voc_end_voice_call(uint32_t session_id); +int voc_standby_voice_call(uint32_t session_id); +int voc_resume_voice_call(uint32_t session_id); +int voc_set_lch(uint32_t session_id, enum voice_lch_mode lch_mode); +int voc_set_rx_vol_step(uint32_t session_id, uint32_t dir, uint32_t vol_step, + uint32_t ramp_duration); +int voc_set_tx_mute(uint32_t session_id, uint32_t dir, uint32_t mute, + uint32_t ramp_duration); +int voc_set_device_mute(uint32_t session_id, uint32_t dir, uint32_t mute, + uint32_t ramp_duration); +int voc_get_rx_device_mute(uint32_t session_id); +int voc_set_route_flag(uint32_t session_id, uint8_t path_dir, uint8_t set); +uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir); +int voc_enable_dtmf_rx_detection(uint32_t session_id, uint32_t enable); +void voc_disable_dtmf_det_on_active_sessions(void); +int voc_alloc_cal_shared_memory(void); +int voc_alloc_voip_shared_memory(void); +int is_voc_initialized(void); +int voc_register_vocproc_vol_table(void); +int voc_deregister_vocproc_vol_table(void); +int voc_send_cvp_map_vocpcm_memory(uint32_t session_id, + struct mem_map_table *tp_mem_table, + phys_addr_t paddr, uint32_t bufsize); +int voc_send_cvp_unmap_vocpcm_memory(uint32_t session_id); +int voc_send_cvp_start_vocpcm(uint32_t session_id, + struct vss_ivpcm_tap_point *vpcm_tp, + uint32_t no_of_tp); +int voc_send_cvp_vocpcm_push_buf_evt(uint32_t session_id, + struct vss_ivpcm_evt_push_buffer_v2_t *push_buff_evt); +int voc_send_cvp_stop_vocpcm(uint32_t session_id); +void voc_register_hpcm_evt_cb(hostpcm_cb_fn hostpcm_cb, + void *private_data); +void voc_deregister_hpcm_evt_cb(void); + +int voc_map_rtac_block(struct rtac_cal_block_data *cal_block); +int voc_unmap_rtac_block(uint32_t *mem_map_handle); + +uint32_t voc_get_session_id(char *name); + +int voc_start_playback(uint32_t set, uint16_t port_id); +int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id); +int voice_get_idx_for_session(u32 session_id); +int voc_set_ext_ec_ref_port_id(uint16_t port_id, bool state); +int voc_get_ext_ec_ref_port_id(void); +int voc_set_ext_ec_ref_media_fmt_info(struct media_format_info *finfo); +int voc_update_amr_vocoder_rate(uint32_t session_id); +int voc_disable_device(uint32_t session_id); +int voc_enable_device(uint32_t session_id); +void voc_set_destroy_cvd_flag(bool is_destroy_cvd); +int voc_disable_topology(uint32_t session_id, uint32_t disable); +int voc_set_device_config(uint32_t session_id, uint8_t path_dir, + struct media_format_info *finfo); +uint32_t voice_get_topology(uint32_t topology_idx); +int voc_set_sound_focus(struct sound_focus_param sound_focus_param); +int voc_get_sound_focus(struct sound_focus_param *soundFocusData); +int voc_get_source_tracking(struct source_tracking_param *sourceTrackingData); +int voc_set_afe_sidetone(uint32_t session_id, bool sidetone_enable); +bool voc_get_afe_sidetone(void); +#endif diff --git a/sound/soc/msm/qdsp6v2/rtac.c b/sound/soc/msm/qdsp6v2/rtac.c new file mode 100644 index 000000000000..cd02501bac7b --- /dev/null +++ b/sound/soc/msm/qdsp6v2/rtac.c @@ -0,0 +1,1924 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "q6voice.h" +#include "msm-pcm-routing-v2.h" +#include + + +/* Max size of payload (buf size - apr header) */ +#define MAX_PAYLOAD_SIZE 4076 +#define RTAC_MAX_ACTIVE_VOICE_COMBOS 2 +#define RTAC_MAX_ACTIVE_POPP 8 +#define RTAC_BUF_SIZE 163840 + +#define TIMEOUT_MS 1000 + +struct rtac_cal_block_data rtac_cal[MAX_RTAC_BLOCKS] = { +/* ADM_RTAC_CAL */ + {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} }, +/* ASM_RTAC_CAL */ + {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} }, +/* VOICE_RTAC_CAL */ + {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} }, +/* AFE_RTAC_CAL */ + {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} } +}; + +struct rtac_common_data { + atomic_t usage_count; + atomic_t apr_err_code; +}; + +static struct rtac_common_data rtac_common; + +/* APR data */ +struct rtac_apr_data { + void *apr_handle; + atomic_t cmd_state; + wait_queue_head_t cmd_wait; +}; + +static struct rtac_apr_data rtac_adm_apr_data; +static struct rtac_apr_data rtac_asm_apr_data[ASM_ACTIVE_STREAMS_ALLOWED + 1]; +static struct rtac_apr_data rtac_afe_apr_data; +static struct rtac_apr_data rtac_voice_apr_data[RTAC_VOICE_MODES]; + +/* ADM info & APR */ +static struct rtac_adm rtac_adm_data; +static u32 *rtac_adm_buffer; + + +/* ASM APR */ +static u32 *rtac_asm_buffer; + +static u32 *rtac_afe_buffer; + +/* Voice info & APR */ +struct rtac_voice_data_t { + uint32_t tx_topology_id; + uint32_t rx_topology_id; + uint32_t tx_afe_topology; + uint32_t rx_afe_topology; + uint32_t tx_afe_port; + uint32_t rx_afe_port; + uint16_t cvs_handle; + uint16_t cvp_handle; + uint32_t tx_acdb_id; + uint32_t rx_acdb_id; +}; + +struct rtac_voice { + uint32_t num_of_voice_combos; + struct rtac_voice_data_t voice[RTAC_MAX_ACTIVE_VOICE_COMBOS]; +}; + +struct rtac_afe_user_data { + uint32_t buf_size; + uint32_t cmd_size; + uint32_t port_id; + union { + struct rtac_afe_set { + struct afe_port_cmd_set_param_v2 cmd; + struct afe_port_param_data_v2 data; + } rtac_afe_set; + struct rtac_afe_get { + struct afe_port_cmd_get_param_v2 cmd; + struct afe_port_param_data_v2 data; + } rtac_afe_get; + }; +} __packed; + +static struct rtac_voice rtac_voice_data; +static u32 *rtac_voice_buffer; +static u32 voice_session_id[RTAC_MAX_ACTIVE_VOICE_COMBOS]; + + +struct mutex rtac_adm_mutex; +struct mutex rtac_adm_apr_mutex; +struct mutex rtac_asm_apr_mutex; +struct mutex rtac_voice_mutex; +struct mutex rtac_voice_apr_mutex; +struct mutex rtac_afe_apr_mutex; + +int rtac_clear_mapping(uint32_t cal_type) +{ + int result = 0; + + pr_debug("%s\n", __func__); + + if (cal_type >= MAX_RTAC_BLOCKS) { + pr_debug("%s: invalid cal type %d\n", __func__, cal_type); + result = -EINVAL; + goto done; + } + + rtac_cal[cal_type].map_data.map_handle = 0; +done: + return result; +} + +int rtac_allocate_cal_buffer(uint32_t cal_type) +{ + int result = 0; + size_t len; + + pr_debug("%s\n", __func__); + + if (cal_type >= MAX_RTAC_BLOCKS) { + pr_err("%s: cal_type %d is invalid!\n", + __func__, cal_type); + result = -EINVAL; + goto done; + } + + if (rtac_cal[cal_type].cal_data.paddr != 0) { + pr_err("%s: memory already allocated! cal_type %d, paddr 0x%pK\n", + __func__, cal_type, &rtac_cal[cal_type].cal_data.paddr); + result = -EPERM; + goto done; + } + + result = msm_audio_ion_alloc("rtac_client", + &rtac_cal[cal_type].map_data.ion_client, + &rtac_cal[cal_type].map_data.ion_handle, + rtac_cal[cal_type].map_data.map_size, + &rtac_cal[cal_type].cal_data.paddr, + &len, + &rtac_cal[cal_type].cal_data.kvaddr); + if (result < 0) { + pr_err("%s: ION create client for RTAC failed\n", + __func__); + goto done; + } + + pr_debug("%s: cal_type %d, paddr 0x%pK, kvaddr 0x%pK, map_size 0x%x\n", + __func__, cal_type, + &rtac_cal[cal_type].cal_data.paddr, + rtac_cal[cal_type].cal_data.kvaddr, + rtac_cal[cal_type].map_data.map_size); +done: + return result; +} + +int rtac_free_cal_buffer(uint32_t cal_type) +{ + int result = 0; + + pr_debug("%s\n", __func__); + + if (cal_type >= MAX_RTAC_BLOCKS) { + pr_err("%s: cal_type %d is invalid!\n", + __func__, cal_type); + result = -EINVAL; + goto done; + } + + if (rtac_cal[cal_type].map_data.ion_client == NULL) { + pr_debug("%s: cal_type %d not allocated!\n", + __func__, cal_type); + goto done; + } + + result = msm_audio_ion_free(rtac_cal[cal_type].map_data.ion_client, + rtac_cal[cal_type].map_data.ion_handle); + if (result < 0) { + pr_err("%s: ION free for RTAC failed! cal_type %d, paddr 0x%pK\n", + __func__, cal_type, &rtac_cal[cal_type].cal_data.paddr); + goto done; + } + + rtac_cal[cal_type].map_data.map_handle = 0; + rtac_cal[cal_type].map_data.ion_client = NULL; + rtac_cal[cal_type].map_data.ion_handle = NULL; + rtac_cal[cal_type].cal_data.size = 0; + rtac_cal[cal_type].cal_data.kvaddr = 0; + rtac_cal[cal_type].cal_data.paddr = 0; +done: + return result; +} + +int rtac_map_cal_buffer(uint32_t cal_type) +{ + int result = 0; + + pr_debug("%s\n", __func__); + + if (cal_type >= MAX_RTAC_BLOCKS) { + pr_err("%s: cal_type %d is invalid!\n", + __func__, cal_type); + result = -EINVAL; + goto done; + } + + if (rtac_cal[cal_type].map_data.map_handle != 0) { + pr_err("%s: already mapped cal_type %d\n", + __func__, cal_type); + result = -EPERM; + goto done; + } + + if (rtac_cal[cal_type].cal_data.paddr == 0) { + pr_err("%s: physical address is NULL cal_type %d\n", + __func__, cal_type); + result = -EPERM; + goto done; + } + + switch (cal_type) { + case ADM_RTAC_CAL: + result = adm_map_rtac_block(&rtac_cal[cal_type]); + break; + case ASM_RTAC_CAL: + result = q6asm_map_rtac_block(&rtac_cal[cal_type]); + break; + case VOICE_RTAC_CAL: + result = voc_map_rtac_block(&rtac_cal[cal_type]); + break; + case AFE_RTAC_CAL: + result = afe_map_rtac_block(&rtac_cal[cal_type]); + break; + } + if (result < 0) { + pr_err("%s: map RTAC failed! cal_type %d\n", + __func__, cal_type); + goto done; + } +done: + return result; +} + +int rtac_unmap_cal_buffer(uint32_t cal_type) +{ + int result = 0; + + pr_debug("%s\n", __func__); + + if (cal_type >= MAX_RTAC_BLOCKS) { + pr_err("%s: cal_type %d is invalid!\n", + __func__, cal_type); + result = -EINVAL; + goto done; + } + + if (rtac_cal[cal_type].map_data.map_handle == 0) { + pr_debug("%s: nothing to unmap cal_type %d\n", + __func__, cal_type); + goto done; + } + + switch (cal_type) { + case ADM_RTAC_CAL: + result = adm_unmap_rtac_block( + &rtac_cal[cal_type].map_data.map_handle); + break; + case ASM_RTAC_CAL: + result = q6asm_unmap_rtac_block( + &rtac_cal[cal_type].map_data.map_handle); + break; + case VOICE_RTAC_CAL: + result = voc_unmap_rtac_block( + &rtac_cal[cal_type].map_data.map_handle); + break; + case AFE_RTAC_CAL: + result = afe_unmap_rtac_block( + &rtac_cal[cal_type].map_data.map_handle); + break; + } + if (result < 0) { + pr_err("%s: unmap RTAC failed! cal_type %d\n", + __func__, cal_type); + goto done; + } +done: + return result; +} + +static int rtac_open(struct inode *inode, struct file *f) +{ + int result = 0; + + pr_debug("%s\n", __func__); + + atomic_inc(&rtac_common.usage_count); + return result; +} + +static int rtac_release(struct inode *inode, struct file *f) +{ + int result = 0; + int result2 = 0; + int i; + + pr_debug("%s\n", __func__); + + atomic_dec(&rtac_common.usage_count); + pr_debug("%s: ref count %d!\n", __func__, + atomic_read(&rtac_common.usage_count)); + + if (atomic_read(&rtac_common.usage_count) > 0) + goto done; + + for (i = 0; i < MAX_RTAC_BLOCKS; i++) { + result2 = rtac_unmap_cal_buffer(i); + if (result2 < 0) { + pr_err("%s: unmap buffer failed! error %d!\n", + __func__, result2); + result = result2; + } + + result2 = rtac_free_cal_buffer(i); + if (result2 < 0) { + pr_err("%s: free buffer failed! error %d!\n", + __func__, result2); + result = result2; + } + } +done: + return result; +} + + +/* ADM Info */ +void add_popp(u32 dev_idx, u32 port_id, u32 popp_id) +{ + u32 i = 0; + + for (; i < rtac_adm_data.device[dev_idx].num_of_popp; i++) + if (rtac_adm_data.device[dev_idx].popp[i].popp == popp_id) + goto done; + + if (rtac_adm_data.device[dev_idx].num_of_popp == + RTAC_MAX_ACTIVE_POPP) { + pr_err("%s, Max POPP!\n", __func__); + goto done; + } + rtac_adm_data.device[dev_idx].popp[ + rtac_adm_data.device[dev_idx].num_of_popp].popp = popp_id; + rtac_adm_data.device[dev_idx].popp[ + rtac_adm_data.device[dev_idx].num_of_popp].popp_topology = + q6asm_get_asm_topology(popp_id); + rtac_adm_data.device[dev_idx].popp[ + rtac_adm_data.device[dev_idx].num_of_popp++].app_type = + q6asm_get_asm_app_type(popp_id); + + pr_debug("%s: popp_id = %d, popp topology = 0x%x, popp app type = 0x%x\n", + __func__, + rtac_adm_data.device[dev_idx].popp[ + rtac_adm_data.device[dev_idx].num_of_popp - 1].popp, + rtac_adm_data.device[dev_idx].popp[ + rtac_adm_data.device[dev_idx].num_of_popp - 1].popp_topology, + rtac_adm_data.device[dev_idx].popp[ + rtac_adm_data.device[dev_idx].num_of_popp - 1].app_type); +done: + return; +} + +void rtac_update_afe_topology(u32 port_id) +{ + u32 i = 0; + + mutex_lock(&rtac_adm_mutex); + for (i = 0; i < rtac_adm_data.num_of_dev; i++) { + if (rtac_adm_data.device[i].afe_port == port_id) { + rtac_adm_data.device[i].afe_topology = + afe_get_topology(port_id); + pr_debug("%s: port_id = 0x%x topology_id = 0x%x copp_id = %d\n", + __func__, port_id, + rtac_adm_data.device[i].afe_topology, + rtac_adm_data.device[i].copp); + } + } + mutex_unlock(&rtac_adm_mutex); +} + +void rtac_add_adm_device(u32 port_id, u32 copp_id, u32 path_id, u32 popp_id, + u32 app_type, u32 acdb_id) +{ + u32 i = 0; + + pr_debug("%s: num rtac devices %d port_id = %d, copp_id = %d\n", + __func__, rtac_adm_data.num_of_dev, port_id, copp_id); + + mutex_lock(&rtac_adm_mutex); + if (rtac_adm_data.num_of_dev == RTAC_MAX_ACTIVE_DEVICES) { + pr_err("%s, Can't add anymore RTAC devices!\n", __func__); + goto done; + } + + /* Check if device already added */ + if (rtac_adm_data.num_of_dev != 0) { + for (; i < rtac_adm_data.num_of_dev; i++) { + if (rtac_adm_data.device[i].afe_port == port_id && + rtac_adm_data.device[i].copp == copp_id) { + add_popp(i, port_id, popp_id); + goto done; + } + if (rtac_adm_data.device[i].num_of_popp == + RTAC_MAX_ACTIVE_POPP) { + pr_err("%s, Max POPP!\n", __func__); + goto done; + } + } + } + + /* Add device */ + rtac_adm_data.num_of_dev++; + + rtac_adm_data.device[i].topology_id = + adm_get_topology_for_port_from_copp_id(port_id, copp_id); + rtac_adm_data.device[i].afe_topology = + afe_get_topology(port_id); + rtac_adm_data.device[i].afe_port = port_id; + rtac_adm_data.device[i].copp = copp_id; + rtac_adm_data.device[i].app_type = app_type; + rtac_adm_data.device[i].acdb_dev_id = acdb_id; + rtac_adm_data.device[i].popp[ + rtac_adm_data.device[i].num_of_popp].popp = popp_id; + rtac_adm_data.device[i].popp[ + rtac_adm_data.device[i].num_of_popp].popp_topology = + q6asm_get_asm_topology(popp_id); + rtac_adm_data.device[i].popp[ + rtac_adm_data.device[i].num_of_popp++].app_type = + q6asm_get_asm_app_type(popp_id); + + pr_debug("%s: topology = 0x%x, afe_topology = 0x%x, port_id = %d, copp_id = %d, app id = 0x%x, acdb id = %d, popp_id = %d, popp topology = 0x%x, popp app type = 0x%x\n", + __func__, + rtac_adm_data.device[i].topology_id, + rtac_adm_data.device[i].afe_topology, + rtac_adm_data.device[i].afe_port, + rtac_adm_data.device[i].copp, + rtac_adm_data.device[i].app_type, + rtac_adm_data.device[i].acdb_dev_id, + rtac_adm_data.device[i].popp[ + rtac_adm_data.device[i].num_of_popp - 1].popp, + rtac_adm_data.device[i].popp[ + rtac_adm_data.device[i].num_of_popp - 1].popp_topology, + rtac_adm_data.device[i].popp[ + rtac_adm_data.device[i].num_of_popp - 1].app_type); +done: + mutex_unlock(&rtac_adm_mutex); +} + +static void shift_adm_devices(u32 dev_idx) +{ + for (; dev_idx < rtac_adm_data.num_of_dev; dev_idx++) { + memcpy(&rtac_adm_data.device[dev_idx], + &rtac_adm_data.device[dev_idx + 1], + sizeof(rtac_adm_data.device[dev_idx])); + memset(&rtac_adm_data.device[dev_idx + 1], 0, + sizeof(rtac_adm_data.device[dev_idx])); + } +} + +static void shift_popp(u32 copp_idx, u32 popp_idx) +{ + for (; popp_idx < rtac_adm_data.device[copp_idx].num_of_popp; + popp_idx++) { + memcpy(&rtac_adm_data.device[copp_idx].popp[popp_idx].popp, + &rtac_adm_data.device[copp_idx].popp[popp_idx + 1]. + popp, sizeof(uint32_t)); + memcpy(&rtac_adm_data.device[copp_idx].popp[popp_idx]. + popp_topology, + &rtac_adm_data.device[copp_idx].popp[popp_idx + 1]. + popp_topology, + sizeof(uint32_t)); + memset(&rtac_adm_data.device[copp_idx].popp[popp_idx + 1]. + popp, 0, sizeof(uint32_t)); + memset(&rtac_adm_data.device[copp_idx].popp[popp_idx + 1]. + popp_topology, 0, sizeof(uint32_t)); + } +} + +void rtac_remove_adm_device(u32 port_id, u32 copp_id) +{ + s32 i; + + pr_debug("%s: num rtac devices %d port_id = %d, copp_id = %d\n", + __func__, rtac_adm_data.num_of_dev, port_id, copp_id); + + mutex_lock(&rtac_adm_mutex); + /* look for device */ + for (i = 0; i < rtac_adm_data.num_of_dev; i++) { + if (rtac_adm_data.device[i].afe_port == port_id && + rtac_adm_data.device[i].copp == copp_id) { + memset(&rtac_adm_data.device[i], 0, + sizeof(rtac_adm_data.device[i])); + rtac_adm_data.num_of_dev--; + + if (rtac_adm_data.num_of_dev >= 1) { + shift_adm_devices(i); + break; + } + } + } + + mutex_unlock(&rtac_adm_mutex); +} + +void rtac_remove_popp_from_adm_devices(u32 popp_id) +{ + s32 i, j; + + pr_debug("%s: popp_id = %d\n", __func__, popp_id); + + mutex_lock(&rtac_adm_mutex); + for (i = 0; i < rtac_adm_data.num_of_dev; i++) { + for (j = 0; j < rtac_adm_data.device[i].num_of_popp; j++) { + if (rtac_adm_data.device[i].popp[j].popp == + popp_id) { + rtac_adm_data.device[i].popp[j].popp = 0; + rtac_adm_data.device[i].popp[j]. + popp_topology = 0; + rtac_adm_data.device[i].num_of_popp--; + shift_popp(i, j); + } + } + } + mutex_unlock(&rtac_adm_mutex); +} + + +/* Voice Info */ +static void set_rtac_voice_data(int idx, u32 cvs_handle, u32 cvp_handle, + u32 rx_afe_port, u32 tx_afe_port, + u32 rx_acdb_id, u32 tx_acdb_id, + u32 session_id) +{ + rtac_voice_data.voice[idx].tx_topology_id = + voice_get_topology(CVP_VOC_TX_TOPOLOGY_CAL); + rtac_voice_data.voice[idx].rx_topology_id = + voice_get_topology(CVP_VOC_RX_TOPOLOGY_CAL); + rtac_voice_data.voice[idx].tx_afe_topology = + afe_get_topology(tx_afe_port); + rtac_voice_data.voice[idx].rx_afe_topology = + afe_get_topology(rx_afe_port); + rtac_voice_data.voice[idx].tx_afe_port = tx_afe_port; + rtac_voice_data.voice[idx].rx_afe_port = rx_afe_port; + rtac_voice_data.voice[idx].tx_acdb_id = tx_acdb_id; + rtac_voice_data.voice[idx].rx_acdb_id = rx_acdb_id; + rtac_voice_data.voice[idx].cvs_handle = cvs_handle; + rtac_voice_data.voice[idx].cvp_handle = cvp_handle; + pr_debug("%s\n%s: %x\n%s: %d %s: %d\n%s: %d %s: %d\n %s: %d\n %s: %d\n%s: %d %s: %d\n%s", + "<---- Voice Data Info ---->", "Session id", session_id, + "cvs_handle", cvs_handle, "cvp_handle", cvp_handle, + "rx_afe_topology", rtac_voice_data.voice[idx].rx_afe_topology, + "tx_afe_topology", rtac_voice_data.voice[idx].tx_afe_topology, + "rx_afe_port", rx_afe_port, "tx_afe_port", tx_afe_port, + "rx_acdb_id", rx_acdb_id, "tx_acdb_id", tx_acdb_id, + "<-----------End----------->"); + + /* Store session ID for voice RTAC */ + voice_session_id[idx] = session_id; +} + +void rtac_add_voice(u32 cvs_handle, u32 cvp_handle, u32 rx_afe_port, + u32 tx_afe_port, u32 rx_acdb_id, u32 tx_acdb_id, + u32 session_id) +{ + u32 i = 0; + + pr_debug("%s\n", __func__); + mutex_lock(&rtac_voice_mutex); + + if (rtac_voice_data.num_of_voice_combos == + RTAC_MAX_ACTIVE_VOICE_COMBOS) { + pr_err("%s, Can't add anymore RTAC devices!\n", __func__); + goto done; + } + + /* Check if device already added */ + if (rtac_voice_data.num_of_voice_combos != 0) { + for (; i < rtac_voice_data.num_of_voice_combos; i++) { + if (rtac_voice_data.voice[i].cvs_handle == + cvs_handle) { + set_rtac_voice_data(i, cvs_handle, cvp_handle, + rx_afe_port, tx_afe_port, rx_acdb_id, + tx_acdb_id, session_id); + goto done; + } + } + } + + /* Add device */ + rtac_voice_data.num_of_voice_combos++; + set_rtac_voice_data(i, cvs_handle, cvp_handle, + rx_afe_port, tx_afe_port, + rx_acdb_id, tx_acdb_id, + session_id); +done: + mutex_unlock(&rtac_voice_mutex); +} + +static void shift_voice_devices(u32 idx) +{ + for (; idx < rtac_voice_data.num_of_voice_combos - 1; idx++) { + memcpy(&rtac_voice_data.voice[idx], + &rtac_voice_data.voice[idx + 1], + sizeof(rtac_voice_data.voice[idx])); + voice_session_id[idx] = voice_session_id[idx + 1]; + } +} + +void rtac_remove_voice(u32 cvs_handle) +{ + u32 i = 0; + + pr_debug("%s\n", __func__); + + mutex_lock(&rtac_voice_mutex); + /* look for device */ + for (i = 0; i < rtac_voice_data.num_of_voice_combos; i++) { + if (rtac_voice_data.voice[i].cvs_handle == cvs_handle) { + shift_voice_devices(i); + rtac_voice_data.num_of_voice_combos--; + memset(&rtac_voice_data.voice[ + rtac_voice_data.num_of_voice_combos], 0, + sizeof(rtac_voice_data.voice + [rtac_voice_data.num_of_voice_combos])); + voice_session_id[rtac_voice_data.num_of_voice_combos] + = 0; + break; + } + } + mutex_unlock(&rtac_voice_mutex); +} + +static u32 get_voice_session_id_cvs(u32 cvs_handle) +{ + u32 i; + + for (i = 0; i < rtac_voice_data.num_of_voice_combos; i++) { + if (rtac_voice_data.voice[i].cvs_handle == cvs_handle) + return voice_session_id[i]; + } + + pr_err("%s: No voice index for CVS handle %d found returning 0\n", + __func__, cvs_handle); + return 0; +} + +static u32 get_voice_session_id_cvp(u32 cvp_handle) +{ + u32 i; + + for (i = 0; i < rtac_voice_data.num_of_voice_combos; i++) { + if (rtac_voice_data.voice[i].cvp_handle == cvp_handle) + return voice_session_id[i]; + } + + pr_err("%s: No voice index for CVP handle %d found returning 0\n", + __func__, cvp_handle); + return 0; +} + +static int get_voice_index(u32 mode, u32 handle) +{ + if (mode == RTAC_CVP) + return voice_get_idx_for_session( + get_voice_session_id_cvp(handle)); + if (mode == RTAC_CVS) + return voice_get_idx_for_session( + get_voice_session_id_cvs(handle)); + + pr_err("%s: Invalid mode %d, returning 0\n", + __func__, mode); + return 0; +} + + +/* ADM APR */ +void rtac_set_adm_handle(void *handle) +{ + pr_debug("%s: handle = %pK\n", __func__, handle); + + mutex_lock(&rtac_adm_apr_mutex); + rtac_adm_apr_data.apr_handle = handle; + mutex_unlock(&rtac_adm_apr_mutex); +} + +bool rtac_make_adm_callback(uint32_t *payload, u32 payload_size) +{ + pr_debug("%s:cmd_state = %d\n", __func__, + atomic_read(&rtac_adm_apr_data.cmd_state)); + if (atomic_read(&rtac_adm_apr_data.cmd_state) != 1) + return false; + + pr_debug("%s\n", __func__); + if (payload_size == sizeof(uint32_t)) + atomic_set(&rtac_common.apr_err_code, payload[0]); + else if (payload_size == (2*sizeof(uint32_t))) + atomic_set(&rtac_common.apr_err_code, payload[1]); + + atomic_set(&rtac_adm_apr_data.cmd_state, 0); + wake_up(&rtac_adm_apr_data.cmd_wait); + return true; +} + +int send_adm_apr(void *buf, u32 opcode) +{ + s32 result; + u32 user_buf_size = 0; + u32 bytes_returned = 0; + u32 copp_id; + u32 payload_size; + u32 data_size = 0; + int copp_idx; + int port_idx; + struct apr_hdr adm_params; + + pr_debug("%s\n", __func__); + + if (rtac_cal[ADM_RTAC_CAL].map_data.ion_handle == NULL) { + result = rtac_allocate_cal_buffer(ADM_RTAC_CAL); + if (result < 0) { + pr_err("%s: allocate buffer failed!", + __func__); + goto done; + } + } + + if (rtac_cal[ADM_RTAC_CAL].map_data.map_handle == 0) { + result = rtac_map_cal_buffer(ADM_RTAC_CAL); + if (result < 0) { + pr_err("%s: map buffer failed!", + __func__); + goto done; + } + } + + if (copy_from_user(&user_buf_size, (void *)buf, + sizeof(user_buf_size))) { + pr_err("%s: Copy from user failed! buf = 0x%pK\n", + __func__, buf); + goto done; + } + if (user_buf_size <= 0) { + pr_err("%s: Invalid buffer size = %d\n", + __func__, user_buf_size); + goto done; + } + + if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) { + pr_err("%s: Could not copy payload size from user buffer\n", + __func__); + goto done; + } + + if (copy_from_user(&copp_id, buf + 2 * sizeof(u32), sizeof(u32))) { + pr_err("%s: Could not copy port id from user buffer\n", + __func__); + goto done; + } + + if (adm_get_indexes_from_copp_id(copp_id, &copp_idx, &port_idx) != 0) { + pr_err("%s: Copp Id-%d is not active\n", __func__, copp_id); + goto done; + } + + mutex_lock(&rtac_adm_apr_mutex); + if (rtac_adm_apr_data.apr_handle == NULL) { + pr_err("%s: APR not initialized\n", __func__); + result = -EINVAL; + goto err; + } + + if (opcode == ADM_CMD_SET_PP_PARAMS_V5) { + /* set payload size to in-band payload */ + /* set data size to actual out of band payload size */ + data_size = payload_size - 4 * sizeof(u32); + if (data_size > rtac_cal[ADM_RTAC_CAL].map_data.map_size) { + pr_err("%s: Invalid data size = %d\n", + __func__, data_size); + result = -EINVAL; + goto err; + } + payload_size = 4 * sizeof(u32); + + /* Copy buffer to out-of-band payload */ + if (copy_from_user((void *) + rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr, + buf + 7 * sizeof(u32), data_size)) { + pr_err("%s: Could not copy payload from user buffer\n", + __func__); + result = -EINVAL; + goto err; + } + /* set payload size in packet */ + rtac_adm_buffer[8] = data_size; + } else { + if (payload_size > MAX_PAYLOAD_SIZE) { + pr_err("%s: Invalid payload size = %d\n", + __func__, payload_size); + result = -EINVAL; + goto err; + } + + /* Copy buffer to in-band payload */ + if (copy_from_user(rtac_adm_buffer + + sizeof(adm_params)/sizeof(u32), + buf + 3 * sizeof(u32), payload_size)) { + pr_err("%s: Could not copy payload from user buffer\n", + __func__); + result = -EINVAL; + goto err; + } + } + + /* Pack header */ + adm_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(20), APR_PKT_VER); + adm_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + payload_size); + adm_params.src_svc = APR_SVC_ADM; + adm_params.src_domain = APR_DOMAIN_APPS; + adm_params.src_port = copp_id; + adm_params.dest_svc = APR_SVC_ADM; + adm_params.dest_domain = APR_DOMAIN_ADSP; + adm_params.dest_port = copp_id; + adm_params.token = port_idx << 16 | copp_idx; + adm_params.opcode = opcode; + + /* fill for out-of-band */ + rtac_adm_buffer[5] = + lower_32_bits(rtac_cal[ADM_RTAC_CAL].cal_data.paddr); + rtac_adm_buffer[6] = + msm_audio_populate_upper_32_bits( + rtac_cal[ADM_RTAC_CAL].cal_data.paddr); + rtac_adm_buffer[7] = rtac_cal[ADM_RTAC_CAL].map_data.map_handle; + + memcpy(rtac_adm_buffer, &adm_params, sizeof(adm_params)); + atomic_set(&rtac_adm_apr_data.cmd_state, 1); + + pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n", + __func__, opcode, + &rtac_cal[ADM_RTAC_CAL].cal_data.paddr); + + result = apr_send_pkt(rtac_adm_apr_data.apr_handle, + (uint32_t *)rtac_adm_buffer); + if (result < 0) { + pr_err("%s: Set params failed copp = %d\n", __func__, copp_id); + goto err; + } + /* Wait for the callback */ + result = wait_event_timeout(rtac_adm_apr_data.cmd_wait, + (atomic_read(&rtac_adm_apr_data.cmd_state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!result) { + pr_err("%s: Set params timed out copp = %d\n", __func__, + copp_id); + goto err; + } + if (atomic_read(&rtac_common.apr_err_code)) { + pr_err("%s: DSP returned error code = [%s], opcode = 0x%x\n", + __func__, adsp_err_get_err_str(atomic_read( + &rtac_common.apr_err_code)), + opcode); + result = adsp_err_get_lnx_err_code( + atomic_read( + &rtac_common.apr_err_code)); + goto err; + } + + if (opcode == ADM_CMD_GET_PP_PARAMS_V5) { + bytes_returned = ((u32 *)rtac_cal[ADM_RTAC_CAL].cal_data. + kvaddr)[2] + 3 * sizeof(u32); + + if (bytes_returned > user_buf_size) { + pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n", + __func__, user_buf_size, bytes_returned); + result = -EINVAL; + goto err; + } + + if (copy_to_user(buf, (void *) + rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr, + bytes_returned)) { + pr_err("%s: Could not copy buffer to user,size = %d\n", + __func__, bytes_returned); + result = -EINVAL; + goto err; + } + } else { + bytes_returned = data_size; + } + mutex_unlock(&rtac_adm_apr_mutex); +done: + return bytes_returned; +err: + mutex_unlock(&rtac_adm_apr_mutex); + return result; +} + + +/* ASM APR */ +void rtac_set_asm_handle(u32 session_id, void *handle) +{ + pr_debug("%s\n", __func__); + + mutex_lock(&rtac_asm_apr_mutex); + rtac_asm_apr_data[session_id].apr_handle = handle; + mutex_unlock(&rtac_asm_apr_mutex); +} + +bool rtac_make_asm_callback(u32 session_id, uint32_t *payload, + u32 payload_size) +{ + if (atomic_read(&rtac_asm_apr_data[session_id].cmd_state) != 1) + return false; + + pr_debug("%s\n", __func__); + if (payload_size == sizeof(uint32_t)) + atomic_set(&rtac_common.apr_err_code, payload[0]); + else if (payload_size == (2*sizeof(uint32_t))) + atomic_set(&rtac_common.apr_err_code, payload[1]); + + atomic_set(&rtac_asm_apr_data[session_id].cmd_state, 0); + wake_up(&rtac_asm_apr_data[session_id].cmd_wait); + return true; +} + +int send_rtac_asm_apr(void *buf, u32 opcode) +{ + s32 result; + u32 user_buf_size = 0; + u32 bytes_returned = 0; + u32 session_id = 0; + u32 payload_size; + u32 data_size = 0; + struct apr_hdr asm_params; + + pr_debug("%s\n", __func__); + + if (rtac_cal[ASM_RTAC_CAL].map_data.ion_handle == NULL) { + result = rtac_allocate_cal_buffer(ASM_RTAC_CAL); + if (result < 0) { + pr_err("%s: allocate buffer failed!", + __func__); + goto done; + } + } + + if (rtac_cal[ASM_RTAC_CAL].map_data.map_handle == 0) { + result = rtac_map_cal_buffer(ASM_RTAC_CAL); + if (result < 0) { + pr_err("%s: map buffer failed!", + __func__); + goto done; + } + } + + if (copy_from_user(&user_buf_size, (void *)buf, + sizeof(user_buf_size))) { + pr_err("%s: Copy from user failed! buf = 0x%pK\n", + __func__, buf); + goto done; + } + if (user_buf_size <= 0) { + pr_err("%s: Invalid buffer size = %d\n", + __func__, user_buf_size); + goto done; + } + + if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) { + pr_err("%s: Could not copy payload size from user buffer\n", + __func__); + goto done; + } + + if (copy_from_user(&session_id, buf + 2 * sizeof(u32), sizeof(u32))) { + pr_err("%s: Could not copy session id from user buffer\n", + __func__); + goto done; + } + if (session_id >= (ASM_ACTIVE_STREAMS_ALLOWED + 1)) { + pr_err("%s: Invalid Session = %d\n", __func__, session_id); + goto done; + } + + mutex_lock(&rtac_asm_apr_mutex); + if (rtac_asm_apr_data[session_id].apr_handle == NULL) { + pr_err("%s: APR not initialized\n", __func__); + result = -EINVAL; + goto err; + } + + if (opcode == ASM_STREAM_CMD_SET_PP_PARAMS_V2) { + /* set payload size to in-band payload */ + /* set data size to actual out of band payload size */ + data_size = payload_size - 4 * sizeof(u32); + if (data_size > rtac_cal[ASM_RTAC_CAL].map_data.map_size) { + pr_err("%s: Invalid data size = %d\n", + __func__, data_size); + result = -EINVAL; + goto err; + } + payload_size = 4 * sizeof(u32); + + /* Copy buffer to out-of-band payload */ + if (copy_from_user((void *) + rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr, + buf + 7 * sizeof(u32), data_size)) { + pr_err("%s: Could not copy payload from user buffer\n", + __func__); + result = -EINVAL; + goto err; + } + /* set payload size in packet */ + rtac_asm_buffer[8] = data_size; + + } else { + if (payload_size > MAX_PAYLOAD_SIZE) { + pr_err("%s: Invalid payload size = %d\n", + __func__, payload_size); + result = -EINVAL; + goto err; + } + + /* Copy buffer to in-band payload */ + if (copy_from_user(rtac_asm_buffer + + sizeof(asm_params)/sizeof(u32), + buf + 3 * sizeof(u32), payload_size)) { + pr_err("%s: Could not copy payload from user buffer\n", + __func__); + result = -EINVAL; + goto err; + } + } + + /* Pack header */ + asm_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(20), APR_PKT_VER); + asm_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + payload_size); + asm_params.src_svc = q6asm_get_apr_service_id(session_id); + asm_params.src_domain = APR_DOMAIN_APPS; + asm_params.src_port = (session_id << 8) | 0x0001; + asm_params.dest_svc = APR_SVC_ASM; + asm_params.dest_domain = APR_DOMAIN_ADSP; + asm_params.dest_port = (session_id << 8) | 0x0001; + asm_params.token = session_id; + asm_params.opcode = opcode; + + /* fill for out-of-band */ + rtac_asm_buffer[5] = + lower_32_bits(rtac_cal[ASM_RTAC_CAL].cal_data.paddr); + rtac_asm_buffer[6] = + msm_audio_populate_upper_32_bits( + rtac_cal[ASM_RTAC_CAL].cal_data.paddr); + rtac_asm_buffer[7] = rtac_cal[ASM_RTAC_CAL].map_data.map_handle; + + memcpy(rtac_asm_buffer, &asm_params, sizeof(asm_params)); + atomic_set(&rtac_asm_apr_data[session_id].cmd_state, 1); + + pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n", + __func__, opcode, + &rtac_cal[ASM_RTAC_CAL].cal_data.paddr); + + result = apr_send_pkt(rtac_asm_apr_data[session_id].apr_handle, + (uint32_t *)rtac_asm_buffer); + if (result < 0) { + pr_err("%s: Set params failed session = %d\n", + __func__, session_id); + goto err; + } + + /* Wait for the callback */ + result = wait_event_timeout(rtac_asm_apr_data[session_id].cmd_wait, + (atomic_read(&rtac_asm_apr_data[session_id].cmd_state) == 0), + 5 * HZ); + if (!result) { + pr_err("%s: Set params timed out session = %d\n", + __func__, session_id); + goto err; + } + if (atomic_read(&rtac_common.apr_err_code)) { + pr_err("%s: DSP returned error code = [%s], opcode = 0x%x\n", + __func__, adsp_err_get_err_str(atomic_read( + &rtac_common.apr_err_code)), + opcode); + result = adsp_err_get_lnx_err_code( + atomic_read( + &rtac_common.apr_err_code)); + goto err; + } + + if (opcode == ASM_STREAM_CMD_GET_PP_PARAMS_V2) { + bytes_returned = ((u32 *)rtac_cal[ASM_RTAC_CAL].cal_data. + kvaddr)[2] + 3 * sizeof(u32); + + if (bytes_returned > user_buf_size) { + pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n", + __func__, user_buf_size, bytes_returned); + result = -EINVAL; + goto err; + } + + if (copy_to_user(buf, (void *) + rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr, + bytes_returned)) { + pr_err("%s: Could not copy buffer to user,size = %d\n", + __func__, bytes_returned); + result = -EINVAL; + goto err; + } + } else { + bytes_returned = data_size; + } + mutex_unlock(&rtac_asm_apr_mutex); +done: + return bytes_returned; +err: + mutex_unlock(&rtac_asm_apr_mutex); + return result; +} + +/* AFE APR */ +void rtac_set_afe_handle(void *handle) +{ + mutex_lock(&rtac_afe_apr_mutex); + rtac_afe_apr_data.apr_handle = handle; + mutex_unlock(&rtac_afe_apr_mutex); +} + +bool rtac_make_afe_callback(uint32_t *payload, uint32_t payload_size) +{ + pr_debug("%s:cmd_state = %d\n", __func__, + atomic_read(&rtac_afe_apr_data.cmd_state)); + if (atomic_read(&rtac_afe_apr_data.cmd_state) != 1) + return false; + + if (payload_size == sizeof(uint32_t)) + atomic_set(&rtac_common.apr_err_code, payload[0]); + else if (payload_size == (2*sizeof(uint32_t))) + atomic_set(&rtac_common.apr_err_code, payload[1]); + + atomic_set(&rtac_afe_apr_data.cmd_state, 0); + wake_up(&rtac_afe_apr_data.cmd_wait); + return true; +} + +static int fill_afe_apr_hdr(struct apr_hdr *apr_hdr, uint32_t port, + uint32_t opcode, uint32_t apr_msg_size) +{ + if (apr_hdr == NULL) { + pr_err("%s: invalid APR pointer", __func__); + return -EINVAL; + } + + apr_hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + apr_hdr->pkt_size = apr_msg_size; + apr_hdr->src_svc = APR_SVC_AFE; + apr_hdr->src_domain = APR_DOMAIN_APPS; + apr_hdr->src_port = 0; + apr_hdr->dest_svc = APR_SVC_AFE; + apr_hdr->dest_domain = APR_DOMAIN_ADSP; + apr_hdr->dest_port = 0; + apr_hdr->token = port; + apr_hdr->opcode = opcode; + + return 0; + +} +static int send_rtac_afe_apr(void *buf, uint32_t opcode) +{ + int32_t result; + uint32_t bytes_returned = 0; + uint32_t port_index = 0; + uint32_t apr_msg_size = 0; + struct rtac_afe_user_data user_afe_buf; + + pr_debug("%s\n", __func__); + + if (rtac_cal[AFE_RTAC_CAL].map_data.ion_handle == NULL) { + result = rtac_allocate_cal_buffer(AFE_RTAC_CAL); + if (result < 0) { + pr_err("%s: allocate buffer failed! ret = %d\n", + __func__, result); + goto done; + } + } + + if (rtac_cal[AFE_RTAC_CAL].map_data.map_handle == 0) { + result = rtac_map_cal_buffer(AFE_RTAC_CAL); + if (result < 0) { + pr_err("%s: map buffer failed! ret = %d\n", + __func__, result); + goto done; + } + } + + if (copy_from_user(&user_afe_buf, (void *)buf, + sizeof(struct rtac_afe_user_data))) { + pr_err("%s: Copy from user failed! buf = 0x%pK\n", + __func__, buf); + goto done; + } + + if (user_afe_buf.buf_size <= 0) { + pr_err("%s: Invalid buffer size = %d\n", + __func__, user_afe_buf.buf_size); + goto done; + } + + port_index = q6audio_get_port_index(user_afe_buf.port_id); + if (port_index >= AFE_MAX_PORTS) { + pr_err("%s: Invalid AFE port = 0x%x\n", + __func__, user_afe_buf.port_id); + goto done; + } + + mutex_lock(&rtac_afe_apr_mutex); + if (rtac_afe_apr_data.apr_handle == NULL) { + pr_err("%s: APR not initialized\n", __func__); + result = -EINVAL; + goto err; + } + if (opcode == AFE_PORT_CMD_SET_PARAM_V2) { + struct afe_port_cmd_set_param_v2 *afe_set_apr_msg; + + /* set data size to actual out of band payload size */ + if (user_afe_buf.rtac_afe_set.cmd.payload_size > + rtac_cal[AFE_RTAC_CAL].map_data.map_size) { + pr_err("%s: Invalid data size = %d\n", + __func__, + user_afe_buf.rtac_afe_set.cmd.payload_size); + result = -EINVAL; + goto err; + } + + /* Copy buffer to out-of-band payload */ + if (copy_from_user((void *) + rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr, + buf+offsetof(struct rtac_afe_user_data, + rtac_afe_set.data), + user_afe_buf.rtac_afe_set.cmd.payload_size)) { + pr_err("%s: Could not copy payload from user buffer\n", + __func__); + result = -EINVAL; + goto err; + } + + /* Copy AFE APR Message */ + afe_set_apr_msg = (struct afe_port_cmd_set_param_v2 *) + ((u8 *)rtac_afe_buffer + + sizeof(struct apr_hdr)); + if (copy_from_user((void *) + afe_set_apr_msg, + buf + offsetof(struct rtac_afe_user_data, + rtac_afe_set.cmd), + sizeof(struct afe_port_cmd_set_param_v2))) { + pr_err("%s: Could not copy payload from user buffer\n", + __func__); + result = -EINVAL; + goto err; + } + + afe_set_apr_msg->payload_address_lsw = + lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr); + afe_set_apr_msg->payload_address_msw = + msm_audio_populate_upper_32_bits( + rtac_cal[AFE_RTAC_CAL].cal_data.paddr); + afe_set_apr_msg->mem_map_handle = + rtac_cal[AFE_RTAC_CAL].map_data.map_handle; + + apr_msg_size = sizeof(struct apr_hdr) + + sizeof(struct afe_port_cmd_set_param_v2); + + } else { + struct afe_port_cmd_get_param_v2 *afe_get_apr_msg; + + if (user_afe_buf.cmd_size > MAX_PAYLOAD_SIZE) { + pr_err("%s: Invalid payload size = %d\n", + __func__, user_afe_buf.cmd_size); + result = -EINVAL; + goto err; + } + + /* Copy buffer to in-band payload */ + afe_get_apr_msg = (struct afe_port_cmd_get_param_v2 *) + ((u8 *) rtac_afe_buffer + + sizeof(struct apr_hdr)); + if (copy_from_user((void *)afe_get_apr_msg, + buf+offsetof(struct rtac_afe_user_data, + rtac_afe_get.cmd), + sizeof(struct afe_port_cmd_get_param_v2))) { + pr_err("%s: Could not copy payload from user buffer\n", + __func__); + result = -EINVAL; + goto err; + } + + afe_get_apr_msg->payload_address_lsw = + lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr); + afe_get_apr_msg->payload_address_msw = + msm_audio_populate_upper_32_bits( + rtac_cal[AFE_RTAC_CAL].cal_data.paddr); + afe_get_apr_msg->mem_map_handle = + rtac_cal[AFE_RTAC_CAL].map_data.map_handle; + afe_get_apr_msg->payload_size -= sizeof(struct apr_hdr); + apr_msg_size = sizeof(struct apr_hdr) + + sizeof(struct afe_port_cmd_get_param_v2); + } + + fill_afe_apr_hdr((struct apr_hdr *) rtac_afe_buffer, + port_index, opcode, apr_msg_size); + + atomic_set(&rtac_afe_apr_data.cmd_state, 1); + + pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n", + __func__, opcode, + &rtac_cal[AFE_RTAC_CAL].cal_data.paddr); + + result = apr_send_pkt(rtac_afe_apr_data.apr_handle, + (uint32_t *)rtac_afe_buffer); + if (result < 0) { + pr_err("%s: Set params failed port = 0x%x, ret = %d\n", + __func__, user_afe_buf.port_id, result); + goto err; + } + /* Wait for the callback */ + result = wait_event_timeout(rtac_afe_apr_data.cmd_wait, + (atomic_read(&rtac_afe_apr_data.cmd_state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!result) { + pr_err("%s: Set params timed out port = 0x%x, ret = %d\n", + __func__, user_afe_buf.port_id, result); + goto err; + } + if (atomic_read(&rtac_common.apr_err_code)) { + pr_err("%s: DSP returned error code = [%s], opcode = 0x%x\n", + __func__, adsp_err_get_err_str(atomic_read( + &rtac_common.apr_err_code)), + opcode); + result = adsp_err_get_lnx_err_code( + atomic_read( + &rtac_common.apr_err_code)); + goto err; + } + + if (opcode == AFE_PORT_CMD_GET_PARAM_V2) { + struct afe_port_param_data_v2 *get_resp; + + get_resp = (struct afe_port_param_data_v2 *) + rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr; + + bytes_returned = get_resp->param_size + + sizeof(struct afe_port_param_data_v2); + + if (bytes_returned > user_afe_buf.buf_size) { + pr_err("%s: user size = 0x%x, returned size = 0x%x\n", + __func__, user_afe_buf.buf_size, + bytes_returned); + result = -EINVAL; + goto err; + } + + if (copy_to_user(buf, (void *) + rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr, + bytes_returned)) { + pr_err("%s: Could not copy buffer to user,size = %d\n", + __func__, bytes_returned); + result = -EINVAL; + goto err; + } + } else { + bytes_returned = user_afe_buf.rtac_afe_set.cmd.payload_size; + } + mutex_unlock(&rtac_afe_apr_mutex); +done: + return bytes_returned; +err: + mutex_unlock(&rtac_afe_apr_mutex); + return result; +} + +/* Voice APR */ +void rtac_set_voice_handle(u32 mode, void *handle) +{ + pr_debug("%s\n", __func__); + + mutex_lock(&rtac_voice_apr_mutex); + rtac_voice_apr_data[mode].apr_handle = handle; + mutex_unlock(&rtac_voice_apr_mutex); +} + +bool rtac_make_voice_callback(u32 mode, uint32_t *payload, u32 payload_size) +{ + if ((atomic_read(&rtac_voice_apr_data[mode].cmd_state) != 1) || + (mode >= RTAC_VOICE_MODES)) + return false; + + pr_debug("%s\n", __func__); + if (payload_size == sizeof(uint32_t)) + atomic_set(&rtac_common.apr_err_code, payload[0]); + else if (payload_size == (2*sizeof(uint32_t))) + atomic_set(&rtac_common.apr_err_code, payload[1]); + + atomic_set(&rtac_voice_apr_data[mode].cmd_state, 0); + wake_up(&rtac_voice_apr_data[mode].cmd_wait); + return true; +} + +int send_voice_apr(u32 mode, void *buf, u32 opcode) +{ + s32 result; + u32 user_buf_size = 0; + u32 bytes_returned = 0; + u32 payload_size; + u32 dest_port; + u32 data_size = 0; + struct apr_hdr voice_params; + + pr_debug("%s\n", __func__); + + if (rtac_cal[VOICE_RTAC_CAL].map_data.ion_handle == NULL) { + result = rtac_allocate_cal_buffer(VOICE_RTAC_CAL); + if (result < 0) { + pr_err("%s: allocate buffer failed!", + __func__); + goto done; + } + } + + if (rtac_cal[VOICE_RTAC_CAL].map_data.map_handle == 0) { + result = rtac_map_cal_buffer(VOICE_RTAC_CAL); + if (result < 0) { + pr_err("%s: map buffer failed!", + __func__); + goto done; + } + } + + if (copy_from_user(&user_buf_size, (void *)buf, + sizeof(user_buf_size))) { + pr_err("%s: Copy from user failed! buf = 0x%pK\n", + __func__, buf); + goto done; + } + if (user_buf_size <= 0) { + pr_err("%s: Invalid buffer size = %d\n", + __func__, user_buf_size); + goto done; + } + + if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) { + pr_err("%s: Could not copy payload size from user buffer\n", + __func__); + goto done; + } + + if (copy_from_user(&dest_port, buf + 2 * sizeof(u32), sizeof(u32))) { + pr_err("%s: Could not copy port id from user buffer\n", + __func__); + goto done; + } + + if ((mode != RTAC_CVP) && (mode != RTAC_CVS)) { + pr_err("%s: Invalid Mode for APR, mode = %d\n", + __func__, mode); + goto done; + } + + mutex_lock(&rtac_voice_apr_mutex); + if (rtac_voice_apr_data[mode].apr_handle == NULL) { + pr_err("%s: APR not initialized\n", __func__); + result = -EINVAL; + goto err; + } + + if (opcode == VSS_ICOMMON_CMD_SET_PARAM_V2) { + /* set payload size to in-band payload */ + /* set data size to actual out of band payload size */ + data_size = payload_size - 4 * sizeof(u32); + if (data_size > rtac_cal[VOICE_RTAC_CAL].map_data.map_size) { + pr_err("%s: Invalid data size = %d\n", + __func__, data_size); + result = -EINVAL; + goto err; + } + payload_size = 4 * sizeof(u32); + + /* Copy buffer to out-of-band payload */ + if (copy_from_user((void *) + rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr, + buf + 7 * sizeof(u32), data_size)) { + pr_err("%s: Could not copy payload from user buffer\n", + __func__); + result = -EINVAL; + goto err; + } + /* set payload size in packet */ + rtac_voice_buffer[8] = data_size; + } else { + if (payload_size > MAX_PAYLOAD_SIZE) { + pr_err("%s: Invalid payload size = %d\n", + __func__, payload_size); + result = -EINVAL; + goto err; + } + + /* Copy buffer to in-band payload */ + if (copy_from_user(rtac_voice_buffer + + sizeof(voice_params)/sizeof(u32), + buf + 3 * sizeof(u32), payload_size)) { + pr_err("%s: Could not copy payload from user buffer\n", + __func__); + result = -EINVAL; + goto err; + } + } + + /* Pack header */ + voice_params.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(20), APR_PKT_VER); + voice_params.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + payload_size); + voice_params.src_svc = 0; + voice_params.src_domain = APR_DOMAIN_APPS; + voice_params.src_port = get_voice_index(mode, dest_port); + voice_params.dest_svc = 0; + voice_params.dest_domain = APR_DOMAIN_MODEM; + voice_params.dest_port = (u16)dest_port; + voice_params.token = (opcode == VSS_ICOMMON_CMD_SET_PARAM_V2) ? + VOC_RTAC_SET_PARAM_TOKEN : + 0; + voice_params.opcode = opcode; + + /* fill for out-of-band */ + rtac_voice_buffer[5] = rtac_cal[VOICE_RTAC_CAL].map_data.map_handle; + rtac_voice_buffer[6] = + lower_32_bits(rtac_cal[VOICE_RTAC_CAL].cal_data.paddr); + rtac_voice_buffer[7] = + msm_audio_populate_upper_32_bits( + rtac_cal[VOICE_RTAC_CAL].cal_data.paddr); + + memcpy(rtac_voice_buffer, &voice_params, sizeof(voice_params)); + atomic_set(&rtac_voice_apr_data[mode].cmd_state, 1); + + pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n", + __func__, opcode, + &rtac_cal[VOICE_RTAC_CAL].cal_data.paddr); + + result = apr_send_pkt(rtac_voice_apr_data[mode].apr_handle, + (uint32_t *)rtac_voice_buffer); + if (result < 0) { + pr_err("%s: apr_send_pkt failed opcode = %x\n", + __func__, opcode); + goto err; + } + /* Wait for the callback */ + result = wait_event_timeout(rtac_voice_apr_data[mode].cmd_wait, + (atomic_read(&rtac_voice_apr_data[mode].cmd_state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!result) { + pr_err("%s: apr_send_pkt timed out opcode = %x\n", + __func__, opcode); + goto err; + } + if (atomic_read(&rtac_common.apr_err_code)) { + pr_err("%s: DSP returned error code = [%s], opcode = 0x%x\n", + __func__, adsp_err_get_err_str(atomic_read( + &rtac_common.apr_err_code)), + opcode); + result = adsp_err_get_lnx_err_code( + atomic_read( + &rtac_common.apr_err_code)); + goto err; + } + + if (opcode == VSS_ICOMMON_CMD_GET_PARAM_V2) { + bytes_returned = ((u32 *)rtac_cal[VOICE_RTAC_CAL].cal_data. + kvaddr)[2] + 3 * sizeof(u32); + + if (bytes_returned > user_buf_size) { + pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n", + __func__, user_buf_size, bytes_returned); + result = -EINVAL; + goto err; + } + + if (copy_to_user(buf, (void *) + rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr, + bytes_returned)) { + pr_err("%s: Could not copy buffer to user, size = %d\n", + __func__, bytes_returned); + result = -EINVAL; + goto err; + } + } else { + bytes_returned = data_size; + } + mutex_unlock(&rtac_voice_apr_mutex); +done: + return bytes_returned; +err: + mutex_unlock(&rtac_voice_apr_mutex); + return result; +} + +void get_rtac_adm_data(struct rtac_adm *adm_data) +{ + mutex_lock(&rtac_adm_mutex); + memcpy(adm_data, &rtac_adm_data, sizeof(struct rtac_adm)); + mutex_unlock(&rtac_adm_mutex); +} + + +static long rtac_ioctl_shared(struct file *f, + unsigned int cmd, void *arg) +{ + int result = 0; + + if (!arg) { + pr_err("%s: No data sent to driver!\n", __func__); + result = -EFAULT; + goto done; + } + + switch (cmd) { + case AUDIO_GET_RTAC_ADM_INFO: { + mutex_lock(&rtac_adm_mutex); + if (copy_to_user((void *)arg, &rtac_adm_data, + sizeof(rtac_adm_data))) { + pr_err("%s: copy_to_user failed for AUDIO_GET_RTAC_ADM_INFO\n", + __func__); + mutex_unlock(&rtac_adm_mutex); + return -EFAULT; + } + result = sizeof(rtac_adm_data); + mutex_unlock(&rtac_adm_mutex); + break; + } + case AUDIO_GET_RTAC_VOICE_INFO: { + mutex_lock(&rtac_voice_mutex); + if (copy_to_user((void *)arg, &rtac_voice_data, + sizeof(rtac_voice_data))) { + pr_err("%s: copy_to_user failed for AUDIO_GET_RTAC_VOICE_INFO\n", + __func__); + mutex_unlock(&rtac_voice_mutex); + return -EFAULT; + } + result = sizeof(rtac_voice_data); + mutex_unlock(&rtac_voice_mutex); + break; + } + + case AUDIO_GET_RTAC_ADM_CAL: + result = send_adm_apr((void *)arg, ADM_CMD_GET_PP_PARAMS_V5); + break; + case AUDIO_SET_RTAC_ADM_CAL: + result = send_adm_apr((void *)arg, ADM_CMD_SET_PP_PARAMS_V5); + break; + case AUDIO_GET_RTAC_ASM_CAL: + result = send_rtac_asm_apr((void *)arg, + ASM_STREAM_CMD_GET_PP_PARAMS_V2); + break; + case AUDIO_SET_RTAC_ASM_CAL: + result = send_rtac_asm_apr((void *)arg, + ASM_STREAM_CMD_SET_PP_PARAMS_V2); + break; + case AUDIO_GET_RTAC_CVS_CAL: + result = send_voice_apr(RTAC_CVS, (void *) arg, + VSS_ICOMMON_CMD_GET_PARAM_V2); + break; + case AUDIO_SET_RTAC_CVS_CAL: + result = send_voice_apr(RTAC_CVS, (void *) arg, + VSS_ICOMMON_CMD_SET_PARAM_V2); + break; + case AUDIO_GET_RTAC_CVP_CAL: + result = send_voice_apr(RTAC_CVP, (void *) arg, + VSS_ICOMMON_CMD_GET_PARAM_V2); + break; + case AUDIO_SET_RTAC_CVP_CAL: + result = send_voice_apr(RTAC_CVP, (void *) arg, + VSS_ICOMMON_CMD_SET_PARAM_V2); + break; + case AUDIO_GET_RTAC_AFE_CAL: + result = send_rtac_afe_apr((void *)arg, + AFE_PORT_CMD_GET_PARAM_V2); + break; + case AUDIO_SET_RTAC_AFE_CAL: + result = send_rtac_afe_apr((void *)arg, + AFE_PORT_CMD_SET_PARAM_V2); + break; + default: + pr_err("%s: Invalid IOCTL, command = %d!\n", + __func__, cmd); + result = -EINVAL; + } +done: + return result; +} + +static long rtac_ioctl(struct file *f, + unsigned int cmd, unsigned long arg) +{ + int result = 0; + + if (!arg) { + pr_err("%s: No data sent to driver!\n", __func__); + result = -EFAULT; + } else { + result = rtac_ioctl_shared(f, cmd, (void __user *)arg); + } + + return result; +} + +#ifdef CONFIG_COMPAT +#define AUDIO_GET_RTAC_ADM_INFO_32 _IOR(CAL_IOCTL_MAGIC, 207, compat_uptr_t) +#define AUDIO_GET_RTAC_VOICE_INFO_32 _IOR(CAL_IOCTL_MAGIC, 208, compat_uptr_t) +#define AUDIO_GET_RTAC_ADM_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 209, compat_uptr_t) +#define AUDIO_SET_RTAC_ADM_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 210, compat_uptr_t) +#define AUDIO_GET_RTAC_ASM_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 211, compat_uptr_t) +#define AUDIO_SET_RTAC_ASM_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 212, compat_uptr_t) +#define AUDIO_GET_RTAC_CVS_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 213, compat_uptr_t) +#define AUDIO_SET_RTAC_CVS_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 214, compat_uptr_t) +#define AUDIO_GET_RTAC_CVP_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 215, compat_uptr_t) +#define AUDIO_SET_RTAC_CVP_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 216, compat_uptr_t) +#define AUDIO_GET_RTAC_AFE_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 217, compat_uptr_t) +#define AUDIO_SET_RTAC_AFE_CAL_32 _IOWR(CAL_IOCTL_MAGIC, 218, compat_uptr_t) + +static long rtac_compat_ioctl(struct file *f, + unsigned int cmd, unsigned long arg) +{ + int result = 0; + + if (!arg) { + pr_err("%s: No data sent to driver!\n", __func__); + result = -EINVAL; + goto done; + } + + switch (cmd) { + case AUDIO_GET_RTAC_ADM_INFO_32: + cmd = AUDIO_GET_RTAC_ADM_INFO; + goto process; + case AUDIO_GET_RTAC_VOICE_INFO_32: + cmd = AUDIO_GET_RTAC_VOICE_INFO; + goto process; + case AUDIO_GET_RTAC_AFE_CAL_32: + cmd = AUDIO_GET_RTAC_AFE_CAL; + goto process; + case AUDIO_SET_RTAC_AFE_CAL_32: + cmd = AUDIO_SET_RTAC_AFE_CAL; + goto process; + case AUDIO_GET_RTAC_ADM_CAL_32: + cmd = AUDIO_GET_RTAC_ADM_CAL; + goto process; + case AUDIO_SET_RTAC_ADM_CAL_32: + cmd = AUDIO_SET_RTAC_ADM_CAL; + goto process; + case AUDIO_GET_RTAC_ASM_CAL_32: + cmd = AUDIO_GET_RTAC_ASM_CAL; + goto process; + case AUDIO_SET_RTAC_ASM_CAL_32: + cmd = AUDIO_SET_RTAC_ASM_CAL; + goto process; + case AUDIO_GET_RTAC_CVS_CAL_32: + cmd = AUDIO_GET_RTAC_CVS_CAL; + goto process; + case AUDIO_SET_RTAC_CVS_CAL_32: + cmd = AUDIO_SET_RTAC_CVS_CAL; + goto process; + case AUDIO_GET_RTAC_CVP_CAL_32: + cmd = AUDIO_GET_RTAC_CVP_CAL; + goto process; + case AUDIO_SET_RTAC_CVP_CAL_32: + cmd = AUDIO_SET_RTAC_CVP_CAL; +process: + result = rtac_ioctl_shared(f, cmd, compat_ptr(arg)); + break; + default: + result = -EINVAL; + pr_err("%s: Invalid IOCTL, command = %d!\n", + __func__, cmd); + break; + } +done: + return result; +} +#else +#define rtac_compat_ioctl NULL +#endif + +static const struct file_operations rtac_fops = { + .owner = THIS_MODULE, + .open = rtac_open, + .release = rtac_release, + .unlocked_ioctl = rtac_ioctl, + .compat_ioctl = rtac_compat_ioctl, +}; + +struct miscdevice rtac_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_rtac", + .fops = &rtac_fops, +}; + +static int __init rtac_init(void) +{ + int i = 0; + + /* Driver */ + atomic_set(&rtac_common.usage_count, 0); + atomic_set(&rtac_common.apr_err_code, 0); + + /* ADM */ + memset(&rtac_adm_data, 0, sizeof(rtac_adm_data)); + rtac_adm_apr_data.apr_handle = NULL; + atomic_set(&rtac_adm_apr_data.cmd_state, 0); + init_waitqueue_head(&rtac_adm_apr_data.cmd_wait); + mutex_init(&rtac_adm_mutex); + mutex_init(&rtac_adm_apr_mutex); + + rtac_adm_buffer = kzalloc( + rtac_cal[ADM_RTAC_CAL].map_data.map_size, GFP_KERNEL); + if (rtac_adm_buffer == NULL) + goto nomem; + + /* ASM */ + for (i = 0; i < ASM_ACTIVE_STREAMS_ALLOWED+1; i++) { + rtac_asm_apr_data[i].apr_handle = NULL; + atomic_set(&rtac_asm_apr_data[i].cmd_state, 0); + init_waitqueue_head(&rtac_asm_apr_data[i].cmd_wait); + } + mutex_init(&rtac_asm_apr_mutex); + + rtac_asm_buffer = kzalloc( + rtac_cal[ASM_RTAC_CAL].map_data.map_size, GFP_KERNEL); + if (rtac_asm_buffer == NULL) { + kzfree(rtac_adm_buffer); + goto nomem; + } + + /* AFE */ + rtac_afe_apr_data.apr_handle = NULL; + atomic_set(&rtac_afe_apr_data.cmd_state, 0); + init_waitqueue_head(&rtac_afe_apr_data.cmd_wait); + mutex_init(&rtac_afe_apr_mutex); + + rtac_afe_buffer = kzalloc( + rtac_cal[AFE_RTAC_CAL].map_data.map_size, GFP_KERNEL); + if (rtac_afe_buffer == NULL) { + kzfree(rtac_adm_buffer); + kzfree(rtac_asm_buffer); + goto nomem; + } + + /* Voice */ + memset(&rtac_voice_data, 0, sizeof(rtac_voice_data)); + for (i = 0; i < RTAC_VOICE_MODES; i++) { + rtac_voice_apr_data[i].apr_handle = NULL; + atomic_set(&rtac_voice_apr_data[i].cmd_state, 0); + init_waitqueue_head(&rtac_voice_apr_data[i].cmd_wait); + } + mutex_init(&rtac_voice_mutex); + mutex_init(&rtac_voice_apr_mutex); + + rtac_voice_buffer = kzalloc( + rtac_cal[VOICE_RTAC_CAL].map_data.map_size, GFP_KERNEL); + if (rtac_voice_buffer == NULL) { + kzfree(rtac_adm_buffer); + kzfree(rtac_asm_buffer); + kzfree(rtac_afe_buffer); + goto nomem; + } + + return misc_register(&rtac_misc); +nomem: + return -ENOMEM; +} + +module_init(rtac_init); + +MODULE_DESCRIPTION("SoC QDSP6v2 Real-Time Audio Calibration driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/msm/sdm660-common.c b/sound/soc/msm/sdm660-common.c new file mode 100644 index 000000000000..eddcb45e9150 --- /dev/null +++ b/sound/soc/msm/sdm660-common.c @@ -0,0 +1,3210 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include "qdsp6v2/msm-pcm-routing-v2.h" +#include "sdm660-common.h" +#include "sdm660-internal.h" +#include "sdm660-external.h" +#include "../codecs/sdm660_cdc/msm-analog-cdc.h" +#include "../codecs/wsa881x.h" + +#define DRV_NAME "sdm660-asoc-snd" + +#define MSM_INT_DIGITAL_CODEC "msm-dig-codec" +#define PMIC_INT_ANALOG_CODEC "analog-codec" + +#define DEV_NAME_STR_LEN 32 +#define DEFAULT_MCLK_RATE 9600000 + +struct dev_config { + u32 sample_rate; + u32 bit_format; + u32 channels; +}; + +enum { + DP_RX_IDX, + EXT_DISP_RX_IDX_MAX, +}; + +/* TDM default config */ +static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + } +}; + +/* TDM default config */ +static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + } +}; + +/* Default configuration of external display BE */ +static struct dev_config ext_disp_rx_cfg[] = { + [DP_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; +static struct dev_config usb_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +static struct dev_config usb_tx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 1, +}; + +enum { + PRIM_MI2S = 0, + SEC_MI2S, + TERT_MI2S, + QUAT_MI2S, + MI2S_MAX, +}; + +enum { + PRIM_AUX_PCM = 0, + SEC_AUX_PCM, + TERT_AUX_PCM, + QUAT_AUX_PCM, + AUX_PCM_MAX, +}; + +enum { + PCM_I2S_SEL_PRIM = 0, + PCM_I2S_SEL_SEC, + PCM_I2S_SEL_TERT, + PCM_I2S_SEL_QUAT, + PCM_I2S_SEL_MAX, +}; + +struct mi2s_conf { + struct mutex lock; + u32 ref_cnt; + u32 msm_is_mi2s_master; + u32 msm_is_ext_mclk; +}; + +static u32 mi2s_ebit_clk[MI2S_MAX] = { + Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT +}; + +struct msm_wsa881x_dev_info { + struct device_node *of_node; + u32 index; +}; +static struct snd_soc_aux_dev *msm_aux_dev; +static struct snd_soc_codec_conf *msm_codec_conf; + +static bool msm_swap_gnd_mic(struct snd_soc_codec *codec); + +static struct wcd_mbhc_config mbhc_cfg = { + .read_fw_bin = false, + .calibration = NULL, + .detect_extn_cable = true, + .mono_stero_detection = false, + .swap_gnd_mic = NULL, + .hs_ext_micbias = true, + .key_code[0] = KEY_MEDIA, + .key_code[1] = KEY_VOICECOMMAND, + .key_code[2] = KEY_VOLUMEUP, + .key_code[3] = KEY_VOLUMEDOWN, + .key_code[4] = 0, + .key_code[5] = 0, + .key_code[6] = 0, + .key_code[7] = 0, + .linein_th = 5000, + .moisture_en = false, + .mbhc_micbias = 0, + .anc_micbias = 0, + .enable_anc_mic_detect = false, +}; + +static struct dev_config proxy_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +/* Default configuration of MI2S channels */ +static struct dev_config mi2s_rx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config mi2s_tx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_rx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_tx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static char const *ch_text[] = {"Two", "Three", "Four", "Five", + "Six", "Seven", "Eight"}; +static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; +static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_96", "KHZ_192"}; +static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; +static char const *mi2s_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; +static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", "Eight"}; +static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; +static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", + "KHZ_44P1", "KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_96", "KHZ_192", "KHZ_384"}; +static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE"}; +static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96", + "KHZ_192"}; + +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, + ext_disp_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); + +static struct afe_clk_set mi2s_clk[MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + } +}; + +static struct afe_clk_set mi2s_mclk[MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_MCLK_3, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_MCLK_4, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_MCLK_1, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_MCLK_2, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + } +}; + +static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; + +static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2; + + return 0; +} + +static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2; + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + + return 1; +} + +static int tdm_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_384KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int tdm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 8; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, + struct tdm_port *port) +{ + if (port) { + if (strnstr(kcontrol->id.name, "PRI", + sizeof(kcontrol->id.name))) { + port->mode = TDM_PRI; + } else if (strnstr(kcontrol->id.name, "SEC", + sizeof(kcontrol->id.name))) { + port->mode = TDM_SEC; + } else if (strnstr(kcontrol->id.name, "TERT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_TERT; + } else if (strnstr(kcontrol->id.name, "QUAT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_QUAT; + } else { + pr_err("%s: unsupported mode in: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + + if (strnstr(kcontrol->id.name, "RX_0", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_0", + sizeof(kcontrol->id.name))) { + port->channel = TDM_0; + } else if (strnstr(kcontrol->id.name, "RX_1", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_1", + sizeof(kcontrol->id.name))) { + port->channel = TDM_1; + } else if (strnstr(kcontrol->id.name, "RX_2", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_2", + sizeof(kcontrol->id.name))) { + port->channel = TDM_2; + } else if (strnstr(kcontrol->id.name, "RX_3", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_3", + sizeof(kcontrol->id.name))) { + port->channel = TDM_3; + } else if (strnstr(kcontrol->id.name, "RX_4", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_4", + sizeof(kcontrol->id.name))) { + port->channel = TDM_4; + } else if (strnstr(kcontrol->id.name, "RX_5", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_5", + sizeof(kcontrol->id.name))) { + port->channel = TDM_5; + } else if (strnstr(kcontrol->id.name, "RX_6", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_6", + sizeof(kcontrol->id.name))) { + port->channel = TDM_6; + } else if (strnstr(kcontrol->id.name, "RX_7", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_7", + sizeof(kcontrol->id.name))) { + port->channel = TDM_7; + } else { + pr_err("%s: unsupported channel in: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + } else + return -EINVAL; + return 0; +} + +static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_rx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_tx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_get_format(int value) +{ + int format = 0; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int tdm_get_format_val(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 2; + break; + default: + value = 0; + break; + } + return value; +} + +static int mi2s_get_format(int value) +{ + int format = 0; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int mi2s_get_format_value(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + value = 2; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 3; + break; + default: + value = 0; + break; + } + return value; +} + +static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_rx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_tx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + + ucontrol->value.enumerated.item[0] = + tdm_rx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = + tdm_tx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int aux_pcm_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 0: + default: + sample_rate = SAMPLING_RATE_8KHZ; + break; + } + return sample_rate; +} + +static int aux_pcm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + return sample_rate_val; +} + +static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", + sizeof("PRIM_AUX_PCM"))) + idx = PRIM_AUX_PCM; + else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM", + sizeof("SEC_AUX_PCM"))) + idx = SEC_AUX_PCM; + else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", + sizeof("TERT_AUX_PCM"))) + idx = TERT_AUX_PCM; + else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", + sizeof("QUAT_AUX_PCM"))) + idx = QUAT_AUX_PCM; + else { + pr_err("%s: unsupported port: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX", + sizeof("PRIM_MI2S_RX"))) + idx = PRIM_MI2S; + else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX", + sizeof("SEC_MI2S_RX"))) + idx = SEC_MI2S; + else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", + sizeof("TERT_MI2S_RX"))) + idx = TERT_MI2S; + else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", + sizeof("QUAT_MI2S_RX"))) + idx = QUAT_MI2S; + else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", + sizeof("PRIM_MI2S_TX"))) + idx = PRIM_MI2S; + else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX", + sizeof("SEC_MI2S_TX"))) + idx = SEC_MI2S; + else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", + sizeof("TERT_MI2S_TX"))) + idx = TERT_MI2S; + else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", + sizeof("QUAT_MI2S_TX"))) + idx = QUAT_MI2S; + else { + pr_err("%s: unsupported channel: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int mi2s_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 6; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int mi2s_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_192KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].bit_format = + mi2s_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d] _tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_format_value(mi2s_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].bit_format = + mi2s_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d] _rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_format_value(mi2s_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + + return 1; +} + +static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, + usb_rx_cfg.channels); + ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1; + return 0; +} + +static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels); + return 1; +} + +static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_rx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__, + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 9: + usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 8: + usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 7: + usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_rx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, + usb_tx_cfg.channels); + ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1; + return 0; +} + +static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels); + return 1; +} + +static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_tx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + default: + sample_rate_val = 6; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__, + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 9: + usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 8: + usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 7: + usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_tx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "Display Port RX", + sizeof("Display Port RX"))) + idx = DP_RX_IDX; + else { + pr_err("%s: unsupported BE: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].bit_format) { + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 1: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int ext_disp_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.integer.value[0] = + ext_disp_rx_cfg[idx].channels - 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + + return 0; +} + +static int ext_disp_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ext_disp_rx_cfg[idx].channels = + ucontrol->value.integer.value[0] + 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + return 1; +} + +static int ext_disp_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].sample_rate) { + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: ext_disp_rx[%d].sample_rate = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].sample_rate); + + return 0; +} + +static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 2: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, ext_disp_rx[%d].sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], idx, + ext_disp_rx_cfg[idx].sample_rate); + return 0; +} + +const struct snd_kcontrol_new msm_common_snd_controls[] = { + SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, + proxy_rx_ch_get, proxy_rx_ch_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Format", prim_mi2s_rx_format, + mi2s_rx_format_get, + mi2s_rx_format_put), + SOC_ENUM_EXT("SEC_MI2S_RX Format", sec_mi2s_rx_format, + mi2s_rx_format_get, + mi2s_rx_format_put), + SOC_ENUM_EXT("TERT_MI2S_RX Format", tert_mi2s_rx_format, + mi2s_rx_format_get, + mi2s_rx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Format", quat_mi2s_rx_format, + mi2s_rx_format_get, + mi2s_rx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Format", prim_mi2s_tx_format, + mi2s_tx_format_get, + mi2s_tx_format_put), + SOC_ENUM_EXT("SEC_MI2S_TX Format", sec_mi2s_tx_format, + mi2s_tx_format_get, + mi2s_tx_format_put), + SOC_ENUM_EXT("TERT_MI2S_TX Format", tert_mi2s_tx_format, + mi2s_tx_format_get, + mi2s_tx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Format", quat_mi2s_tx_format, + mi2s_tx_format_get, + mi2s_tx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, + usb_audio_rx_ch_get, usb_audio_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, + usb_audio_tx_ch_get, usb_audio_tx_ch_put), + SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, + ext_disp_rx_ch_get, ext_disp_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, + usb_audio_rx_format_get, usb_audio_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, + usb_audio_tx_format_get, usb_audio_tx_format_put), + SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, + ext_disp_rx_format_get, ext_disp_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, + usb_audio_rx_sample_rate_get, + usb_audio_rx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, + usb_audio_tx_sample_rate_get, + usb_audio_tx_sample_rate_put), + SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, + ext_disp_rx_sample_rate_get, + ext_disp_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), +}; + +/** + * msm_common_snd_controls_size - to return controls size + * + * Return: returns size of common controls array + */ +int msm_common_snd_controls_size(void) +{ + return ARRAY_SIZE(msm_common_snd_controls); +} +EXPORT_SYMBOL(msm_common_snd_controls_size); + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, + int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +static int msm_ext_disp_get_idx_from_beid(int32_t be_id) +{ + int idx; + + switch (be_id) { + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = DP_RX_IDX; + break; + default: + pr_err("%s: Incorrect ext_disp be_id %d\n", __func__, be_id); + idx = -EINVAL; + break; + } + + return idx; +} + +/** + * msm_common_be_hw_params_fixup - updates settings of ALSA BE hw params. + * + * @rtd: runtime dailink instance + * @params: HW params of associated backend dailink. + * + * Returns 0. + */ +int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int rc = 0; + int idx; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->be_id) { + case MSM_BACKEND_DAI_USB_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_rx_cfg.bit_format); + rate->min = rate->max = usb_rx_cfg.sample_rate; + channels->min = channels->max = usb_rx_cfg.channels; + break; + + case MSM_BACKEND_DAI_USB_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_tx_cfg.bit_format); + rate->min = rate->max = usb_tx_cfg.sample_rate; + channels->min = channels->max = usb_tx_cfg.channels; + break; + + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = msm_ext_disp_get_idx_from_beid(dai_link->be_id); + if (IS_ERR_VALUE(idx)) { + pr_err("%s: Incorrect ext disp idx %d\n", + __func__, idx); + rc = idx; + break; + } + + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + ext_disp_rx_cfg[idx].bit_format); + rate->min = rate->max = ext_disp_rx_cfg[idx].sample_rate; + channels->min = channels->max = ext_disp_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_AFE_PCM_RX: + channels->min = channels->max = proxy_rx_cfg.channels; + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + + case MSM_BACKEND_DAI_PRI_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_PRI_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_RX: + rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[PRIM_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[PRIM_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_PRI_MI2S_TX: + rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[PRIM_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[PRIM_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[SEC_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[SEC_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[SEC_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[SEC_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[TERT_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[TERT_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[TERT_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[TERT_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUAT_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUAT_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUAT_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUAT_MI2S].bit_format); + break; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + return rc; +} +EXPORT_SYMBOL(msm_common_be_hw_params_fixup); + +/** + * msm_aux_pcm_snd_startup - startup ops of auxpcm. + * + * @substream: PCM stream pointer of associated backend dailink + * + * Returns 0 on success or -EINVAL on error. + */ +int msm_aux_pcm_snd_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + rtd->cpu_dai->name, rtd->cpu_dai->id); + + return 0; +} +EXPORT_SYMBOL(msm_aux_pcm_snd_startup); + +/** + * msm_aux_pcm_snd_shutdown - shutdown ops of auxpcm. + * + * @substream: PCM stream pointer of associated backend dailink + */ +void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, + substream->name, substream->stream, + rtd->cpu_dai->name, rtd->cpu_dai->id); +} +EXPORT_SYMBOL(msm_aux_pcm_snd_shutdown); + +static int msm_get_port_id(int be_id) +{ + int afe_port_id; + + switch (be_id) { + case MSM_BACKEND_DAI_PRI_MI2S_RX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_PRI_MI2S_TX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + default: + pr_err("%s: Invalid be_id: %d\n", __func__, be_id); + afe_port_id = -EINVAL; + } + + return afe_port_id; +} + +static u32 get_mi2s_bits_per_sample(u32 bit_format) +{ + u32 bit_per_sample; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + case SNDRV_PCM_FORMAT_S24_LE: + bit_per_sample = 32; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bit_per_sample = 16; + break; + } + + return bit_per_sample; +} + +static void update_mi2s_clk_val(int dai_id, int stream) +{ + u32 bit_per_sample; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } else { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } +} + +static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int port_id = 0; + int index = cpu_dai->id; + + port_id = msm_get_port_id(rtd->dai_link->be_id); + if (port_id < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto done; + } + + if (enable) { + update_mi2s_clk_val(index, substream->stream); + dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, + mi2s_clk[index].clk_freq_in_hz); + } + + mi2s_clk[index].enable = enable; + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_clk[index]); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed for port 0x%x , err:%d\n", + __func__, port_id, ret); + goto done; + } + +done: + return ret; +} + +/** + * msm_mi2s_snd_startup - startup ops of mi2s. + * + * @substream: PCM stream pointer of associated backend dailink + * + * Returns 0 on success or -EINVAL on error. + */ +int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int port_id = msm_get_port_id(rtd->dai_link->be_id); + int index = cpu_dai->id; + unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + if (index < PRIM_MI2S || index > QUAT_MI2S) { + ret = -EINVAL; + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto done; + } + /* + * Muxtex protection in case the same MI2S + * interface using for both TX and RX so + * that the same clock won't be enable twice. + */ + mutex_lock(&mi2s_intf_conf[index].lock); + if (++mi2s_intf_conf[index].ref_cnt == 1) { + /* Check if msm needs to provide the clock to the interface */ + if (!mi2s_intf_conf[index].msm_is_mi2s_master) { + mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; + fmt = SND_SOC_DAIFMT_CBM_CFM; + } + ret = msm_mi2s_set_sclk(substream, true); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed to enable MI2S clock, err:%d\n", + __func__, ret); + goto clean_up; + } + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: set fmt cpu dai failed for MI2S (%d), err:%d\n", + __func__, index, ret); + goto clk_off; + } + if (mi2s_intf_conf[index].msm_is_ext_mclk) { + mi2s_mclk[index].enable = 1; + pr_debug("%s: Enabling mclk, clk_freq_in_hz = %u\n", + __func__, mi2s_mclk[index].clk_freq_in_hz); + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_mclk[index]); + if (ret < 0) { + pr_err("%s: afe lpass mclk failed, err:%d\n", + __func__, ret); + goto clk_off; + } + } + } + mutex_unlock(&mi2s_intf_conf[index].lock); + return 0; +clk_off: + if (ret < 0) + msm_mi2s_set_sclk(substream, false); +clean_up: + if (ret < 0) + mi2s_intf_conf[index].ref_cnt--; + mutex_unlock(&mi2s_intf_conf[index].lock); +done: + return ret; +} +EXPORT_SYMBOL(msm_mi2s_snd_startup); + +/** + * msm_mi2s_snd_shutdown - shutdown ops of mi2s. + * + * @substream: PCM stream pointer of associated backend dailink + */ +void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int port_id = msm_get_port_id(rtd->dai_link->be_id); + int index = rtd->cpu_dai->id; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + if (index < PRIM_MI2S || index > QUAT_MI2S) { + pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); + return; + } + + mutex_lock(&mi2s_intf_conf[index].lock); + if (--mi2s_intf_conf[index].ref_cnt == 0) { + ret = msm_mi2s_set_sclk(substream, false); + if (ret < 0) { + pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", + __func__, index, ret); + mi2s_intf_conf[index].ref_cnt++; + } + if (mi2s_intf_conf[index].msm_is_ext_mclk) { + mi2s_mclk[index].enable = 0; + pr_debug("%s: Disabling mclk, clk_freq_in_hz = %u\n", + __func__, mi2s_mclk[index].clk_freq_in_hz); + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_mclk[index]); + if (ret < 0) { + pr_err("%s: mclk disable failed for MCLK (%d); ret=%d\n", + __func__, index, ret); + } + } + } + mutex_unlock(&mi2s_intf_conf[index].lock); +} +EXPORT_SYMBOL(msm_mi2s_snd_shutdown); + +/* Validate whether US EU switch is present or not */ +static int msm_prepare_us_euro(struct snd_soc_card *card) +{ + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + int ret = 0; + + if (pdata->us_euro_gpio >= 0) { + dev_dbg(card->dev, "%s: us_euro gpio request %d", __func__, + pdata->us_euro_gpio); + ret = gpio_request(pdata->us_euro_gpio, "TASHA_CODEC_US_EURO"); + if (ret) { + dev_err(card->dev, + "%s: Failed to request codec US/EURO gpio %d error %d\n", + __func__, pdata->us_euro_gpio, ret); + } + } + + return ret; +} + +static bool msm_swap_gnd_mic(struct snd_soc_codec *codec) +{ + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + int value = 0; + + if (pdata->us_euro_gpio_p) { + value = msm_cdc_pinctrl_get_state(pdata->us_euro_gpio_p); + if (value) + msm_cdc_pinctrl_select_sleep_state( + pdata->us_euro_gpio_p); + else + msm_cdc_pinctrl_select_active_state( + pdata->us_euro_gpio_p); + } else if (pdata->us_euro_gpio >= 0) { + value = gpio_get_value_cansleep(pdata->us_euro_gpio); + gpio_set_value_cansleep(pdata->us_euro_gpio, !value); + } + pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value); + return true; +} + +static int msm_populate_dai_link_component_of_node( + struct msm_asoc_mach_data *pdata, + struct snd_soc_card *card) +{ + int i, index, ret = 0; + struct device *cdev = card->dev; + struct snd_soc_dai_link *dai_link = card->dai_link; + struct device_node *phandle; + + if (!cdev) { + pr_err("%s: Sound card device memory NULL\n", __func__); + return -ENODEV; + } + + for (i = 0; i < card->num_links; i++) { + if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) + continue; + + /* populate platform_of_node for snd card dai links */ + if (dai_link[i].platform_name && + !dai_link[i].platform_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-platform-names", + dai_link[i].platform_name); + if (index < 0) { + pr_err("%s: No match found for platform name: %s\n", + __func__, dai_link[i].platform_name); + ret = index; + goto cpu_dai; + } + phandle = of_parse_phandle(cdev->of_node, + "asoc-platform", + index); + if (!phandle) { + pr_err("%s: retrieving phandle for platform %s, index %d failed\n", + __func__, dai_link[i].platform_name, + index); + ret = -ENODEV; + goto err; + } + dai_link[i].platform_of_node = phandle; + dai_link[i].platform_name = NULL; + } +cpu_dai: + /* populate cpu_of_node for snd card dai links */ + if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-cpu-names", + dai_link[i].cpu_dai_name); + if (index < 0) + goto codec_dai; + phandle = of_parse_phandle(cdev->of_node, "asoc-cpu", + index); + if (!phandle) { + pr_err("%s: retrieving phandle for cpu dai %s failed\n", + __func__, dai_link[i].cpu_dai_name); + ret = -ENODEV; + goto err; + } + dai_link[i].cpu_of_node = phandle; + dai_link[i].cpu_dai_name = NULL; + } +codec_dai: + /* populate codec_of_node for snd card dai links */ + if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-codec-names", + dai_link[i].codec_name); + if (index < 0) + continue; + phandle = of_parse_phandle(cdev->of_node, "asoc-codec", + index); + if (!phandle) { + pr_err("%s: retrieving phandle for codec dai %s failed\n", + __func__, dai_link[i].codec_name); + ret = -ENODEV; + goto err; + } + dai_link[i].codec_of_node = phandle; + dai_link[i].codec_name = NULL; + } + if (pdata->snd_card_val == INT_SND_CARD) { + if ((dai_link[i].be_id == + MSM_BACKEND_DAI_INT0_MI2S_RX) || + (dai_link[i].be_id == + MSM_BACKEND_DAI_INT1_MI2S_RX) || + (dai_link[i].be_id == + MSM_BACKEND_DAI_INT2_MI2S_TX) || + (dai_link[i].be_id == + MSM_BACKEND_DAI_INT3_MI2S_TX)) { + index = of_property_match_string(cdev->of_node, + "asoc-codec-names", + MSM_INT_DIGITAL_CODEC); + phandle = of_parse_phandle(cdev->of_node, + "asoc-codec", + index); + dai_link[i].codecs[DIG_CDC].of_node = phandle; + index = of_property_match_string(cdev->of_node, + "asoc-codec-names", + PMIC_INT_ANALOG_CODEC); + phandle = of_parse_phandle(cdev->of_node, + "asoc-codec", + index); + dai_link[i].codecs[ANA_CDC].of_node = phandle; + } + } + } +err: + return ret; +} + +static int msm_wsa881x_init(struct snd_soc_component *component) +{ + u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106}; + u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107}; + unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; + unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + struct msm_asoc_mach_data *pdata; + struct snd_soc_dapm_context *dapm = + snd_soc_codec_get_dapm(codec); + + if (!codec) { + pr_err("%s codec is NULL\n", __func__); + return -EINVAL; + } + + if (!strcmp(component->name_prefix, "SpkrLeft")) { + dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n", + __func__, codec->component.name); + wsa881x_set_channel_map(codec, &spkleft_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0]); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); + } + } else if (!strcmp(component->name_prefix, "SpkrRight")) { + dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n", + __func__, codec->component.name); + wsa881x_set_channel_map(codec, &spkright_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0]); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); + } + } else { + dev_err(codec->dev, "%s: wrong codec name %s\n", __func__, + codec->component.name); + return -EINVAL; + } + + + pdata = snd_soc_card_get_drvdata(component->card); + if (pdata && pdata->codec_root) + wsa881x_codec_info_create_codec_entry(pdata->codec_root, + codec); + return 0; +} + + +static int msm_init_wsa_dev(struct platform_device *pdev, + struct snd_soc_card *card) +{ + struct device_node *wsa_of_node; + u32 wsa_max_devs; + u32 wsa_dev_cnt; + char *dev_name_str = NULL; + struct msm_wsa881x_dev_info *wsa881x_dev_info; + const char *wsa_auxdev_name_prefix[1]; + int found = 0; + int i; + int ret; + + /* Get maximum WSA device count for this platform */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,wsa-max-devs", &wsa_max_devs); + if (ret) { + dev_dbg(&pdev->dev, + "%s: wsa-max-devs property missing in DT %s, ret = %d\n", + __func__, pdev->dev.of_node->full_name, ret); + goto err_dt; + } + if (wsa_max_devs == 0) { + dev_warn(&pdev->dev, + "%s: Max WSA devices is 0 for this target?\n", + __func__); + goto err_dt; + } + + /* Get count of WSA device phandles for this platform */ + wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node, + "qcom,wsa-devs", NULL); + if (wsa_dev_cnt == -ENOENT) { + dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n", + __func__); + goto err_dt; + } else if (wsa_dev_cnt <= 0) { + dev_err(&pdev->dev, + "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n", + __func__, wsa_dev_cnt); + ret = -EINVAL; + goto err_dt; + } + + /* + * Expect total phandles count to be NOT less than maximum possible + * WSA count. However, if it is less, then assign same value to + * max count as well. + */ + if (wsa_dev_cnt < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n", + __func__, wsa_max_devs, wsa_dev_cnt); + wsa_max_devs = wsa_dev_cnt; + } + + /* Make sure prefix string passed for each WSA device */ + ret = of_property_count_strings(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix"); + if (ret != wsa_dev_cnt) { + dev_err(&pdev->dev, + "%s: expecting %d wsa prefix. Defined only %d in DT\n", + __func__, wsa_dev_cnt, ret); + ret = -EINVAL; + goto err_dt; + } + + /* + * Alloc mem to store phandle and index info of WSA device, if already + * registered with ALSA core + */ + wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs, + sizeof(struct msm_wsa881x_dev_info), + GFP_KERNEL); + if (!wsa881x_dev_info) { + ret = -ENOMEM; + goto err_mem; + } + + /* + * search and check whether all WSA devices are already + * registered with ALSA core or not. If found a node, store + * the node and the index in a local array of struct for later + * use. + */ + for (i = 0; i < wsa_dev_cnt; i++) { + wsa_of_node = of_parse_phandle(pdev->dev.of_node, + "qcom,wsa-devs", i); + if (unlikely(!wsa_of_node)) { + /* we should not be here */ + dev_err(&pdev->dev, + "%s: wsa dev node is not present\n", + __func__); + ret = -EINVAL; + goto err_dev_node; + } + if (soc_find_component(wsa_of_node, NULL)) { + /* WSA device registered with ALSA core */ + wsa881x_dev_info[found].of_node = wsa_of_node; + wsa881x_dev_info[found].index = i; + found++; + if (found == wsa_max_devs) + break; + } + } + + if (found < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: failed to find %d components. Found only %d\n", + __func__, wsa_max_devs, found); + return -EPROBE_DEFER; + } + dev_info(&pdev->dev, + "%s: found %d wsa881x devices registered with ALSA core\n", + __func__, found); + + card->num_aux_devs = wsa_max_devs; + card->num_configs = wsa_max_devs; + + /* Alloc array of AUX devs struct */ + msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_aux_dev), + GFP_KERNEL); + if (!msm_aux_dev) { + ret = -ENOMEM; + goto err_auxdev_mem; + } + + /* Alloc array of codec conf struct */ + msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_codec_conf), + GFP_KERNEL); + if (!msm_codec_conf) { + ret = -ENOMEM; + goto err_codec_conf; + } + + for (i = 0; i < card->num_aux_devs; i++) { + dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN, + GFP_KERNEL); + if (!dev_name_str) { + ret = -ENOMEM; + goto err_dev_str; + } + + ret = of_property_read_string_index(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix", + wsa881x_dev_info[i].index, + wsa_auxdev_name_prefix); + if (ret) { + dev_err(&pdev->dev, + "%s: failed to read wsa aux dev prefix, ret = %d\n", + __func__, ret); + ret = -EINVAL; + goto err_dt_prop; + } + + snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i); + msm_aux_dev[i].name = dev_name_str; + msm_aux_dev[i].codec_name = NULL; + msm_aux_dev[i].codec_of_node = + wsa881x_dev_info[i].of_node; + msm_aux_dev[i].init = msm_wsa881x_init; + msm_codec_conf[i].dev_name = NULL; + msm_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0]; + msm_codec_conf[i].of_node = wsa881x_dev_info[i].of_node; + } + card->codec_conf = msm_codec_conf; + card->aux_dev = msm_aux_dev; + + return 0; + +err_dt_prop: + devm_kfree(&pdev->dev, dev_name_str); +err_dev_str: + devm_kfree(&pdev->dev, msm_codec_conf); +err_codec_conf: + devm_kfree(&pdev->dev, msm_aux_dev); +err_auxdev_mem: +err_dev_node: + devm_kfree(&pdev->dev, wsa881x_dev_info); +err_mem: +err_dt: + return ret; +} + +static void msm_free_auxdev_mem(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + int i; + + if (card->num_aux_devs > 0) { + for (i = 0; i < card->num_aux_devs; i++) { + kfree(msm_aux_dev[i].codec_name); + kfree(msm_codec_conf[i].dev_name); + kfree(msm_codec_conf[i].name_prefix); + } + } +} + +static void i2s_auxpcm_init(struct platform_device *pdev) +{ + int count; + u32 mi2s_master_slave[MI2S_MAX]; + u32 mi2s_ext_mclk[MI2S_MAX]; + int ret; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_init(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-master", + mi2s_master_slave, MI2S_MAX); + if (ret) { + dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n", + __func__); + } else { + for (count = 0; count < MI2S_MAX; count++) { + mi2s_intf_conf[count].msm_is_mi2s_master = + mi2s_master_slave[count]; + } + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-ext-mclk", + mi2s_ext_mclk, MI2S_MAX); + if (ret) { + dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-ext-mclk in DT node\n", + __func__); + } else { + for (count = 0; count < MI2S_MAX; count++) + mi2s_intf_conf[count].msm_is_ext_mclk = + mi2s_ext_mclk[count]; + } +} + +static const struct of_device_id sdm660_asoc_machine_of_match[] = { + { .compatible = "qcom,sdm660-asoc-snd", + .data = "internal_codec"}, + { .compatible = "qcom,sdm660-asoc-snd-tasha", + .data = "tasha_codec"}, + { .compatible = "qcom,sdm660-asoc-snd-tavil", + .data = "tavil_codec"}, + {}, +}; + +static int msm_asoc_machine_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = NULL; + struct msm_asoc_mach_data *pdata = NULL; + const char *mclk = "qcom,msm-mclk-freq"; + int ret = -EINVAL, id; + const struct of_device_id *match; + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct msm_asoc_mach_data), + GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + match = of_match_node(sdm660_asoc_machine_of_match, + pdev->dev.of_node); + if (!match) + goto err; + + ret = of_property_read_u32(pdev->dev.of_node, mclk, &id); + if (ret) { + dev_err(&pdev->dev, + "%s: missing %s in dt node\n", __func__, mclk); + id = DEFAULT_MCLK_RATE; + } + pdata->mclk_freq = id; + + if (!strcmp(match->data, "tasha_codec") || + !strcmp(match->data, "tavil_codec")) { + if (!strcmp(match->data, "tasha_codec")) + pdata->snd_card_val = EXT_SND_CARD_TASHA; + else + pdata->snd_card_val = EXT_SND_CARD_TAVIL; + ret = msm_ext_cdc_init(pdev, pdata, &card, &mbhc_cfg); + if (ret) + goto err; + } else if (!strcmp(match->data, "internal_codec")) { + pdata->snd_card_val = INT_SND_CARD; + ret = msm_int_cdc_init(pdev, pdata, &card, &mbhc_cfg); + if (ret) + goto err; + } else { + dev_err(&pdev->dev, + "%s: Not a matching DT sound node\n", __func__); + goto err; + } + if (!card) + goto err; + + if (pdata->snd_card_val == INT_SND_CARD) { + /*reading the gpio configurations from dtsi file*/ + pdata->pdm_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-pdm-gpios", 0); + pdata->comp_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-comp-gpios", 0); + pdata->dmic_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-dmic-gpios", 0); + pdata->ext_spk_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-ext-spk-gpios", 0); + } + + /* + * Parse US-Euro gpio info from DT. Report no error if us-euro + * entry is not found in DT file as some targets do not support + * US-Euro detection + */ + pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,us-euro-gpios", 0); + if (!gpio_is_valid(pdata->us_euro_gpio)) + pdata->us_euro_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,us-euro-gpios", 0); + if (!gpio_is_valid(pdata->us_euro_gpio) && (!pdata->us_euro_gpio_p)) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,us-euro-gpios", pdev->dev.of_node->full_name); + } else { + dev_dbg(&pdev->dev, "%s detected", + "qcom,us-euro-gpios"); + mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; + } + + ret = msm_prepare_us_euro(card); + if (ret) + dev_dbg(&pdev->dev, "msm_prepare_us_euro failed (%d)\n", + ret); + + i2s_auxpcm_init(pdev); + + ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing"); + if (ret) + goto err; + + ret = msm_populate_dai_link_component_of_node(pdata, card); + if (ret) { + ret = -EPROBE_DEFER; + goto err; + } + + if (!of_property_read_bool(pdev->dev.of_node, "qcom,wsa-disable")) { + ret = msm_init_wsa_dev(pdev, card); + if (ret) + goto err; + } + + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret == -EPROBE_DEFER) { + if (codec_reg_done) { + /* + * return failure as EINVAL since other codec + * registered sound card successfully. + * This avoids any further probe calls. + */ + ret = -EINVAL; + } + goto err; + } else if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); + goto err; + } + if (pdata->snd_card_val != INT_SND_CARD) + msm_ext_register_audio_notifier(pdev); + + return 0; +err: + if (pdata->us_euro_gpio > 0) { + dev_dbg(&pdev->dev, "%s free us_euro gpio %d\n", + __func__, pdata->us_euro_gpio); + pdata->us_euro_gpio = 0; + } + if (pdata->hph_en1_gpio > 0) { + dev_dbg(&pdev->dev, "%s free hph_en1_gpio %d\n", + __func__, pdata->hph_en1_gpio); + gpio_free(pdata->hph_en1_gpio); + pdata->hph_en1_gpio = 0; + } + if (pdata->hph_en0_gpio > 0) { + dev_dbg(&pdev->dev, "%s free hph_en0_gpio %d\n", + __func__, pdata->hph_en0_gpio); + gpio_free(pdata->hph_en0_gpio); + pdata->hph_en0_gpio = 0; + } + if (pdata->snd_card_val != INT_SND_CARD) + msm_ext_cdc_deinit(pdata); + devm_kfree(&pdev->dev, pdata); + return ret; +} + +static int msm_asoc_machine_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + + if (pdata->snd_card_val == INT_SND_CARD) + mutex_destroy(&pdata->cdc_int_mclk0_mutex); + else + msm_ext_cdc_deinit(pdata); + msm_free_auxdev_mem(pdev); + + gpio_free(pdata->us_euro_gpio); + gpio_free(pdata->hph_en1_gpio); + gpio_free(pdata->hph_en0_gpio); + snd_soc_unregister_card(card); + return 0; +} + +static struct platform_driver sdm660_asoc_machine_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = sdm660_asoc_machine_of_match, + }, + .probe = msm_asoc_machine_probe, + .remove = msm_asoc_machine_remove, +}; +module_platform_driver(sdm660_asoc_machine_driver); + +MODULE_DESCRIPTION("ALSA SoC msm"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, sdm660_asoc_machine_of_match); diff --git a/sound/soc/msm/sdm660-common.h b/sound/soc/msm/sdm660-common.h new file mode 100644 index 000000000000..bca8cd788a39 --- /dev/null +++ b/sound/soc/msm/sdm660-common.h @@ -0,0 +1,125 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MSM_COMMON +#define __MSM_COMMON + +#include +#include +#include "../codecs/wcd-mbhc-v2.h" + +#define SAMPLING_RATE_8KHZ 8000 +#define SAMPLING_RATE_11P025KHZ 11025 +#define SAMPLING_RATE_16KHZ 16000 +#define SAMPLING_RATE_22P05KHZ 22050 +#define SAMPLING_RATE_32KHZ 32000 +#define SAMPLING_RATE_44P1KHZ 44100 +#define SAMPLING_RATE_48KHZ 48000 +#define SAMPLING_RATE_88P2KHZ 88200 +#define SAMPLING_RATE_96KHZ 96000 +#define SAMPLING_RATE_176P4KHZ 176400 +#define SAMPLING_RATE_192KHZ 192000 +#define SAMPLING_RATE_352P8KHZ 352800 +#define SAMPLING_RATE_384KHZ 384000 + +#define TDM_CHANNEL_MAX 8 +#define TDM_SLOT_OFFSET_MAX 8 + +enum { + TDM_0 = 0, + TDM_1, + TDM_2, + TDM_3, + TDM_4, + TDM_5, + TDM_6, + TDM_7, + TDM_PORT_MAX, +}; + +enum { + TDM_PRI = 0, + TDM_SEC, + TDM_TERT, + TDM_QUAT, + TDM_INTERFACE_MAX, +}; + +struct tdm_port { + u32 mode; + u32 channel; +}; + +enum { + DIG_CDC, + ANA_CDC, + CODECS_MAX, +}; + +extern const struct snd_kcontrol_new msm_common_snd_controls[]; +extern bool codec_reg_done; +struct sdm660_codec { + void* (*get_afe_config_fn)(struct snd_soc_codec *codec, + enum afe_config_type config_type); +}; + +enum { + INT_SND_CARD, + EXT_SND_CARD_TASHA, + EXT_SND_CARD_TAVIL, +}; + +struct msm_snd_interrupt { + void __iomem *mpm_wakeup; + void __iomem *intr1_cfg_apps; + void __iomem *lpi_gpio_intr_cfg; + void __iomem *lpi_gpio_cfg; + void __iomem *lpi_gpio_inout; +}; + +struct msm_asoc_mach_data { + int us_euro_gpio; /* used by gpio driver API */ + int hph_en1_gpio; + int hph_en0_gpio; + struct device_node *us_euro_gpio_p; /* used by pinctrl API */ + struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ + struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ + struct device_node *pdm_gpio_p; /* used by pinctrl API */ + struct device_node *comp_gpio_p; /* used by pinctrl API */ + struct device_node *dmic_gpio_p; /* used by pinctrl API */ + struct device_node *ext_spk_gpio_p; /* used by pinctrl API */ + struct snd_soc_codec *codec; + struct sdm660_codec sdm660_codec_fn; + struct snd_info_entry *codec_root; + int spk_ext_pa_gpio; + int mclk_freq; + bool native_clk_set; + int lb_mode; + int snd_card_val; + u8 micbias1_cap_mode; + u8 micbias2_cap_mode; + atomic_t int_mclk0_rsc_ref; + atomic_t int_mclk0_enabled; + struct mutex cdc_int_mclk0_mutex; + struct delayed_work disable_int_mclk0_work; + struct afe_clk_set digital_cdc_core_clk; + struct msm_snd_interrupt msm_snd_intr_lpi; +}; + +int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params); +int msm_aux_pcm_snd_startup(struct snd_pcm_substream *substream); +void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream); +int msm_mi2s_snd_startup(struct snd_pcm_substream *substream); +void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream); +int msm_common_snd_controls_size(void); +#endif diff --git a/sound/soc/msm/sdm660-ext-dai-links.c b/sound/soc/msm/sdm660-ext-dai-links.c new file mode 100644 index 000000000000..1c03d8c9e797 --- /dev/null +++ b/sound/soc/msm/sdm660-ext-dai-links.c @@ -0,0 +1,2038 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "qdsp6v2/msm-pcm-routing-v2.h" +#include "../codecs/wcd9335.h" +#include "sdm660-common.h" +#include "sdm660-external.h" + +#define DEV_NAME_STR_LEN 32 +#define __CHIPSET__ "SDM660 " +#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) + +#define WCN_CDC_SLIM_RX_CH_MAX 2 +#define WCN_CDC_SLIM_TX_CH_MAX 3 + +static struct snd_soc_card snd_soc_card_msm_card_tavil; +static struct snd_soc_card snd_soc_card_msm_card_tasha; + +static struct snd_soc_ops msm_ext_slimbus_be_ops = { + .hw_params = msm_snd_hw_params, +}; + +static struct snd_soc_ops msm_ext_cpe_ops = { + .hw_params = msm_snd_cpe_hw_params, +}; + +static struct snd_soc_ops msm_ext_slimbus_2_be_ops = { + .hw_params = msm_ext_slimbus_2_hw_params, +}; + +static struct snd_soc_ops msm_mi2s_be_ops = { + .startup = msm_mi2s_snd_startup, + .shutdown = msm_mi2s_snd_shutdown, +}; + +static struct snd_soc_ops msm_aux_pcm_be_ops = { + .startup = msm_aux_pcm_snd_startup, + .shutdown = msm_aux_pcm_snd_shutdown, +}; + +static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) +{ + unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; + unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); +} + +static int msm_wcn_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + int ret; + + dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret) { + dev_err(rtd->dev, + "%s: failed to get BTFM codec chan map\n, err:%d\n", + __func__, ret); + goto exit; + } + + dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) be_id %d\n", + __func__, tx_ch_cnt, dai_link->be_id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); + if (ret) + dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + +exit: + return ret; +} + +static struct snd_soc_ops msm_wcn_ops = { + .hw_params = msm_wcn_hw_params, +}; + +/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */ +static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { + {0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */ +}; + +static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width, + int slots) +{ + unsigned int slot_mask = 0; + int i, j; + unsigned int *slot_offset; + + for (i = TDM_0; i < TDM_PORT_MAX; i++) { + slot_offset = tdm_slot_offset[i]; + + for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) { + if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID) + slot_mask |= + (1 << ((slot_offset[j] * 8) / slot_width)); + else + break; + } + } + + return slot_mask; +} + +static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + int channels, slot_width, slots; + unsigned int slot_mask; + unsigned int *slot_offset; + int offset_channels = 0; + int i; + + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + + channels = params_channels(params); + switch (channels) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S16_LE: + /* + * up to 8 channels HW config should + * use 32 bit slot width for max support of + * stream bit width. (slot_width > bit_width) + */ + slot_width = 32; + break; + default: + pr_err("%s: invalid param format 0x%x\n", + __func__, params_format(params)); + return -EINVAL; + } + slots = 8; + slot_mask = tdm_param_set_slot_mask(cpu_dai->id, + slot_width, + slots); + if (!slot_mask) { + pr_err("%s: invalid slot_mask 0x%x\n", + __func__, slot_mask); + return -EINVAL; + } + break; + default: + pr_err("%s: invalid param channels %d\n", + __func__, channels); + return -EINVAL; + } + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + slot_offset = tdm_slot_offset[TDM_0]; + break; + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) + offset_channels++; + else + break; + } + + if (offset_channels == 0) { + pr_err("%s: slot offset not supported, offset_channels %d\n", + __func__, offset_channels); + return -EINVAL; + } + + if (channels > offset_channels) { + pr_err("%s: channels %d exceed offset_channels %d\n", + __func__, channels, offset_channels); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, + channels, slot_offset); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } else { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, channels, + slot_offset, 0, NULL); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } +end: + return ret; +} + +static struct snd_soc_ops msm_tdm_be_ops = { + .hw_params = msm_tdm_snd_hw_params +}; + +static struct snd_soc_dai_link msm_ext_tasha_fe_dai[] = { + /* tasha_vifeedback for speaker protection */ + { + .name = LPASS_BE_SLIMBUS_4_TX, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_vifeedback", + .be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + }, + /* Ultrasound RX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Playback", + .stream_name = "SLIMBUS_2 Hostless Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx2", + .ignore_suspend = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_ext_slimbus_2_be_ops, + }, + /* Ultrasound TX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Capture", + .stream_name = "SLIMBUS_2 Hostless Capture", + .cpu_dai_name = "msm-dai-q6-dev.16389", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx2", + .ignore_suspend = 1, + .dpcm_capture = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_ext_slimbus_2_be_ops, + }, + /* CPE LSM direct dai-link */ + { + .name = "CPE Listen service", + .stream_name = "CPE Listen Audio Service", + .cpu_dai_name = "msm-dai-slim", + .platform_name = "msm-cpe-lsm", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .dpcm_capture = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "tasha_mad1", + .codec_name = "tasha_codec", + .ops = &msm_ext_cpe_ops, + }, + { + .name = "SLIMBUS_6 Hostless Playback", + .stream_name = "SLIMBUS_6 Hostless", + .cpu_dai_name = "SLIMBUS6_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + /* CPE LSM EC PP direct dai-link */ + { + .name = "CPE Listen service ECPP", + .stream_name = "CPE Listen Audio Service ECPP", + .cpu_dai_name = "CPE_LSM_NOHOST", + .platform_name = "msm-cpe-lsm.3", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "tasha_cpe", + .codec_name = "tasha_codec", + }, +}; + +static struct snd_soc_dai_link msm_ext_tavil_fe_dai[] = { + { + .name = LPASS_BE_SLIMBUS_4_TX, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_vifeedback", + .be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + }, + /* Ultrasound RX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Playback", + .stream_name = "SLIMBUS_2 Hostless Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx2", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_ext_slimbus_2_be_ops, + }, + /* Ultrasound TX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Capture", + .stream_name = "SLIMBUS_2 Hostless Capture", + .cpu_dai_name = "msm-dai-q6-dev.16389", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx2", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_ext_slimbus_2_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_ext_tasha_be_dai[] = { + /* Backend DAI Links */ + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_init, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_ext_slimbus_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_ext_slimbus_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_1_RX, + .stream_name = "Slimbus1 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16386", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_1_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_1_TX, + .stream_name = "Slimbus1 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16387", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx3", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_1_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_RX, + .stream_name = "Slimbus3 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16390", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_3_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_TX, + .stream_name = "Slimbus3 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16391", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_3_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_4_RX, + .stream_name = "Slimbus4 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16392", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_4_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_5_RX, + .stream_name = "Slimbus5 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16394", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx3", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_5_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* MAD BE */ + { + .name = LPASS_BE_SLIMBUS_5_TX, + .stream_name = "Slimbus5 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16395", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mad1", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_5_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_6_RX, + .stream_name = "Slimbus6 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16396", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx4", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_6_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_ext_tavil_be_dai[] = { + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_init, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_ext_slimbus_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_ext_slimbus_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_1_RX, + .stream_name = "Slimbus1 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16386", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_1_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_1_TX, + .stream_name = "Slimbus1 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16387", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx3", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_1_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_2_RX, + .stream_name = "Slimbus2 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx2", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_2_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_RX, + .stream_name = "Slimbus3 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16390", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_3_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_TX, + .stream_name = "Slimbus3 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16391", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_3_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_4_RX, + .stream_name = "Slimbus4 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16392", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_4_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_5_RX, + .stream_name = "Slimbus5 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16394", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx3", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_5_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* MAD BE */ + { + .name = LPASS_BE_SLIMBUS_5_TX, + .stream_name = "Slimbus5 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16395", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_mad1", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_5_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_6_RX, + .stream_name = "Slimbus6 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16396", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx4", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_6_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { + /* FrontEnd DAI Links */ + {/* hw:x,0 */ + .name = MSM_DAILINK_NAME(Media1), + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, + {/* hw:x,1 */ + .name = MSM_DAILINK_NAME(Media2), + .stream_name = "MultiMedia2", + .cpu_dai_name = "MultiMedia2", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA2, + }, + {/* hw:x,2 */ + .name = "VoiceMMode1", + .stream_name = "VoiceMMode1", + .cpu_dai_name = "VoiceMMode1", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_VOICEMMODE1, + }, + {/* hw:x,3 */ + .name = "MSM VoIP", + .stream_name = "VoIP", + .cpu_dai_name = "VoIP", + .platform_name = "msm-voip-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .be_id = MSM_FRONTEND_DAI_VOIP, + }, + {/* hw:x,4 */ + .name = MSM_DAILINK_NAME(ULL), + .stream_name = "ULL", + .cpu_dai_name = "MultiMedia3", + .platform_name = "msm-pcm-dsp.2", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA3, + }, + /* Hostless PCM purpose */ + {/* hw:x,5 */ + .name = "SLIMBUS_0 Hostless", + .stream_name = "SLIMBUS_0 Hostless", + .cpu_dai_name = "SLIMBUS0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* This dai link has MI2S support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,6 */ + .name = "MSM AFE-PCM RX", + .stream_name = "AFE-PROXY RX", + .cpu_dai_name = "msm-dai-q6-dev.241", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .platform_name = "msm-pcm-afe", + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + }, + {/* hw:x,7 */ + .name = "MSM AFE-PCM TX", + .stream_name = "AFE-PROXY TX", + .cpu_dai_name = "msm-dai-q6-dev.240", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .platform_name = "msm-pcm-afe", + .ignore_suspend = 1, + }, + {/* hw:x,8 */ + .name = MSM_DAILINK_NAME(Compress1), + .stream_name = "Compress1", + .cpu_dai_name = "MultiMedia4", + .platform_name = "msm-compress-dsp", + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA4, + }, + {/* hw:x,9*/ + .name = "AUXPCM Hostless", + .stream_name = "AUXPCM Hostless", + .cpu_dai_name = "AUXPCM_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,10 */ + .name = "SLIMBUS_1 Hostless", + .stream_name = "SLIMBUS_1 Hostless", + .cpu_dai_name = "SLIMBUS1_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, /* dai link has playback support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,11 */ + .name = "SLIMBUS_3 Hostless", + .stream_name = "SLIMBUS_3 Hostless", + .cpu_dai_name = "SLIMBUS3_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, /* dai link has playback support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,12 */ + .name = "SLIMBUS_4 Hostless", + .stream_name = "SLIMBUS_4 Hostless", + .cpu_dai_name = "SLIMBUS4_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, /* dai link has playback support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,13 */ + .name = MSM_DAILINK_NAME(LowLatency), + .stream_name = "MultiMedia5", + .cpu_dai_name = "MultiMedia5", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA5, + }, + /* LSM FE */ + {/* hw:x,14 */ + .name = "Listen 1 Audio Service", + .stream_name = "Listen 1 Audio Service", + .cpu_dai_name = "LSM1", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_LSM1, + }, + {/* hw:x,15 */ + .name = MSM_DAILINK_NAME(Compress2), + .stream_name = "Compress2", + .cpu_dai_name = "MultiMedia7", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA7, + }, + {/* hw:x,16 */ + .name = MSM_DAILINK_NAME(Compress3), + .stream_name = "Compress3", + .cpu_dai_name = "MultiMedia10", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA10, + }, + {/* hw:x,17 */ + .name = MSM_DAILINK_NAME(ULL_NOIRQ), + .stream_name = "MM_NOIRQ", + .cpu_dai_name = "MultiMedia8", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA8, + }, + {/* hw:x,18 */ + .name = "HDMI_RX_HOSTLESS", + .stream_name = "HDMI_RX_HOSTLESS", + .cpu_dai_name = "HDMI_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,19 */ + .name = "VoiceMMode2", + .stream_name = "VoiceMMode2", + .cpu_dai_name = "VoiceMMode2", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_VOICEMMODE2, + }, + {/* hw:x,20 */ + .name = "Listen 2 Audio Service", + .stream_name = "Listen 2 Audio Service", + .cpu_dai_name = "LSM2", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_LSM2, + }, + {/* hw:x,21 */ + .name = "Listen 3 Audio Service", + .stream_name = "Listen 3 Audio Service", + .cpu_dai_name = "LSM3", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_LSM3, + }, + {/* hw:x,22 */ + .name = "Listen 4 Audio Service", + .stream_name = "Listen 4 Audio Service", + .cpu_dai_name = "LSM4", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_LSM4, + }, + {/* hw:x,23 */ + .name = "Listen 5 Audio Service", + .stream_name = "Listen 5 Audio Service", + .cpu_dai_name = "LSM5", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_LSM5, + }, + {/* hw:x,24 */ + .name = "Listen 6 Audio Service", + .stream_name = "Listen 6 Audio Service", + .cpu_dai_name = "LSM6", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_LSM6 + }, + {/* hw:x,25 */ + .name = "Listen 7 Audio Service", + .stream_name = "Listen 7 Audio Service", + .cpu_dai_name = "LSM7", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_LSM7, + }, + {/* hw:x,26 */ + .name = "Listen 8 Audio Service", + .stream_name = "Listen 8 Audio Service", + .cpu_dai_name = "LSM8", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_LSM8, + }, + {/* hw:x,27 */ + .name = MSM_DAILINK_NAME(Media9), + .stream_name = "MultiMedia9", + .cpu_dai_name = "MultiMedia9", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA9, + }, + {/* hw:x,28 */ + .name = MSM_DAILINK_NAME(Compress4), + .stream_name = "Compress4", + .cpu_dai_name = "MultiMedia11", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA11, + }, + {/* hw:x,29 */ + .name = MSM_DAILINK_NAME(Compress5), + .stream_name = "Compress5", + .cpu_dai_name = "MultiMedia12", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA12, + }, + {/* hw:x,30 */ + .name = MSM_DAILINK_NAME(Compress6), + .stream_name = "Compress6", + .cpu_dai_name = "MultiMedia13", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA13, + }, + {/* hw:x,31 */ + .name = MSM_DAILINK_NAME(Compress7), + .stream_name = "Compress7", + .cpu_dai_name = "MultiMedia14", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA14, + }, + {/* hw:x,32 */ + .name = MSM_DAILINK_NAME(Compress8), + .stream_name = "Compress8", + .cpu_dai_name = "MultiMedia15", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA15, + }, + {/* hw:x,33 */ + .name = MSM_DAILINK_NAME(Compress9), + .stream_name = "Compress9", + .cpu_dai_name = "MultiMedia16", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA16, + }, + {/* hw:x,34 */ + .name = "SLIMBUS_8 Hostless", + .stream_name = "SLIMBUS8_HOSTLESS Capture", + .cpu_dai_name = "SLIMBUS8_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,35 */ + .name = "SLIMBUS7 Hostless", + .stream_name = "SLIMBUS7 Hostless", + .cpu_dai_name = "SLIMBUS7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,36 */ + .name = "SDM660 HFP TX", + .stream_name = "MultiMedia6", + .cpu_dai_name = "MultiMedia6", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA6, + }, +}; + +static struct snd_soc_dai_link msm_ext_common_be_dai[] = { + { + .name = LPASS_BE_AFE_PCM_RX, + .stream_name = "AFE Playback", + .cpu_dai_name = "msm-dai-q6-dev.224", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_AFE_PCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AFE_PCM_TX, + .stream_name = "AFE Capture", + .cpu_dai_name = "msm-dai-q6-dev.225", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_AFE_PCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Uplink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_TX, + .stream_name = "Voice Uplink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32772", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_INCALL_RECORD_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Downlink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_RX, + .stream_name = "Voice Downlink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32771", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_INCALL_RECORD_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music BACK END DAI Link */ + { + .name = LPASS_BE_VOICE_PLAYBACK_TX, + .stream_name = "Voice Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32773", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music 2 BACK END DAI Link */ + { + .name = LPASS_BE_VOICE2_PLAYBACK_TX, + .stream_name = "Voice2 Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32770", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_RX, + .stream_name = "USB Audio Playback", + .cpu_dai_name = "msm-dai-q6-dev.28672", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_USB_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_TX, + .stream_name = "USB Audio Capture", + .cpu_dai_name = "msm-dai-q6-dev.28673", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_USB_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_0, + .stream_name = "Primary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36864", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_0, + .stream_name = "Primary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36865", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_0, + .stream_name = "Secondary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36880", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_0, + .stream_name = "Secondary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36881", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_0, + .stream_name = "Tertiary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36896", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_0, + .stream_name = "Tertiary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36897", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_0, + .stream_name = "Quaternary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36912", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_0, + .stream_name = "Quaternary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36913", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { + { + .name = LPASS_BE_PRI_MI2S_RX, + .stream_name = "Primary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_PRI_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_MI2S_TX, + .stream_name = "Primary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_PRI_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX, + .stream_name = "Secondary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX, + .stream_name = "Secondary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX, + .stream_name = "Tertiary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX, + .stream_name = "Tertiary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX, + .stream_name = "Quaternary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { + /* Primary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_AUXPCM_RX, + .stream_name = "AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_AUXPCM_TX, + .stream_name = "AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Secondary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_SEC_AUXPCM_RX, + .stream_name = "Sec AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_SEC_AUXPCM_TX, + .stream_name = "Sec AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Tertiary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_TERT_AUXPCM_RX, + .stream_name = "Tert AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_TERT_AUXPCM_TX, + .stream_name = "Tert AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Quaternary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUAT_AUXPCM_RX, + .stream_name = "Quat AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_QUAT_AUXPCM_TX, + .stream_name = "Quat AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .ops = &msm_aux_pcm_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_7_RX, + .stream_name = "Slimbus7 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16398", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + /* BT codec driver determines capabilities based on + * dai name, bt codecdai name should always contains + * supported usecase information + */ + .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_7_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_wcn_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_7_TX, + .stream_name = "Slimbus7 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16399", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_bt_sco_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_7_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_8_TX, + .stream_name = "Slimbus8 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16401", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_fm_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_8_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .init = &msm_wcn_init, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link ext_disp_be_dai_link[] = { + /* DISP PORT BACK END DAI Link */ + { + .name = LPASS_BE_DISPLAY_PORT, + .stream_name = "Display Port Playback", + .cpu_dai_name = "msm-dai-q6-dp.24608", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-ext-disp-audio-codec-rx", + .codec_dai_name = "msm_dp_audio_codec_rx_dai", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_ext_tasha_dai_links[ +ARRAY_SIZE(msm_ext_common_fe_dai) + +ARRAY_SIZE(msm_ext_tasha_fe_dai) + +ARRAY_SIZE(msm_ext_common_be_dai) + +ARRAY_SIZE(msm_ext_tasha_be_dai) + +ARRAY_SIZE(msm_mi2s_be_dai_links) + +ARRAY_SIZE(msm_auxpcm_be_dai_links) + +ARRAY_SIZE(msm_wcn_be_dai_links) + +ARRAY_SIZE(ext_disp_be_dai_link)]; + +static struct snd_soc_dai_link msm_ext_tavil_dai_links[ +ARRAY_SIZE(msm_ext_common_fe_dai) + +ARRAY_SIZE(msm_ext_tavil_fe_dai) + +ARRAY_SIZE(msm_ext_common_be_dai) + +ARRAY_SIZE(msm_ext_tavil_be_dai) + +ARRAY_SIZE(msm_mi2s_be_dai_links) + +ARRAY_SIZE(msm_auxpcm_be_dai_links) + +ARRAY_SIZE(msm_wcn_be_dai_links) + +ARRAY_SIZE(ext_disp_be_dai_link)]; + +/** + * populate_snd_card_dailinks - prepares dailink array and initializes card. + * + * @dev: device handle + * + * Returns card on success or NULL on failure. + */ +struct snd_soc_card *populate_snd_card_dailinks(struct device *dev, + int snd_card_val) +{ + struct snd_soc_card *card; + struct snd_soc_dai_link *msm_ext_dai_links = NULL; + int ret, len1, len2, len3, len4; + enum codec_variant codec_ver = 0; + + if (snd_card_val == EXT_SND_CARD_TASHA) { + card = &snd_soc_card_msm_card_tasha; + } else if (snd_card_val == EXT_SND_CARD_TAVIL) { + card = &snd_soc_card_msm_card_tavil; + } else { + dev_err(dev, "%s: failing as no matching card name\n", + __func__); + return NULL; + } + + card->dev = dev; + ret = snd_soc_of_parse_card_name(card, "qcom,model"); + if (ret) { + dev_err(dev, "%s: parse card name failed, err:%d\n", + __func__, ret); + return NULL; + } + + if (strnstr(card->name, "tasha", strlen(card->name))) { + codec_ver = tasha_codec_ver(); + if (codec_ver == WCD9326) + card->name = "sdm660-tashalite-snd-card"; + + len1 = ARRAY_SIZE(msm_ext_common_fe_dai); + len2 = len1 + ARRAY_SIZE(msm_ext_tasha_fe_dai); + len3 = len2 + ARRAY_SIZE(msm_ext_common_be_dai); + memcpy(msm_ext_tasha_dai_links, msm_ext_common_fe_dai, + sizeof(msm_ext_common_fe_dai)); + memcpy(msm_ext_tasha_dai_links + len1, + msm_ext_tasha_fe_dai, sizeof(msm_ext_tasha_fe_dai)); + memcpy(msm_ext_tasha_dai_links + len2, + msm_ext_common_be_dai, sizeof(msm_ext_common_be_dai)); + memcpy(msm_ext_tasha_dai_links + len3, + msm_ext_tasha_be_dai, sizeof(msm_ext_tasha_be_dai)); + len4 = len3 + ARRAY_SIZE(msm_ext_tasha_be_dai); + if (of_property_read_bool(dev->of_node, + "qcom,mi2s-audio-intf")) { + memcpy(msm_ext_tasha_dai_links + len4, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + len4 += ARRAY_SIZE(msm_mi2s_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,auxpcm-audio-intf")) { + memcpy(msm_ext_tasha_dai_links + len4, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + len4 += ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + dev_dbg(dev, "%s(): WCN BTFM support present\n", + __func__); + memcpy(msm_ext_tasha_dai_links + len4, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + len4 += ARRAY_SIZE(msm_wcn_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,ext-disp-audio-rx")) { + dev_dbg(dev, "%s(): ext disp audio support present\n", + __func__); + memcpy(msm_ext_tasha_dai_links + len4, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + len4 += ARRAY_SIZE(ext_disp_be_dai_link); + } + msm_ext_dai_links = msm_ext_tasha_dai_links; + } else if (strnstr(card->name, "tavil", strlen(card->name))) { + len1 = ARRAY_SIZE(msm_ext_common_fe_dai); + len2 = len1 + ARRAY_SIZE(msm_ext_tavil_fe_dai); + len3 = len2 + ARRAY_SIZE(msm_ext_common_be_dai); + memcpy(msm_ext_tavil_dai_links, msm_ext_common_fe_dai, + sizeof(msm_ext_common_fe_dai)); + memcpy(msm_ext_tavil_dai_links + len1, + msm_ext_tavil_fe_dai, sizeof(msm_ext_tavil_fe_dai)); + memcpy(msm_ext_tavil_dai_links + len2, + msm_ext_common_be_dai, sizeof(msm_ext_common_be_dai)); + memcpy(msm_ext_tavil_dai_links + len3, + msm_ext_tavil_be_dai, sizeof(msm_ext_tavil_be_dai)); + len4 = len3 + ARRAY_SIZE(msm_ext_tavil_be_dai); + if (of_property_read_bool(dev->of_node, + "qcom,mi2s-audio-intf")) { + memcpy(msm_ext_tavil_dai_links + len4, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + len4 += ARRAY_SIZE(msm_mi2s_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,auxpcm-audio-intf")) { + memcpy(msm_ext_tavil_dai_links + len4, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + len4 += ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + dev_dbg(dev, "%s(): WCN BTFM support present\n", + __func__); + memcpy(msm_ext_tavil_dai_links + len4, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + len4 += ARRAY_SIZE(msm_wcn_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,ext-disp-audio-rx")) { + dev_dbg(dev, "%s(): ext disp audio support present\n", + __func__); + memcpy(msm_ext_tavil_dai_links + len4, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + len4 += ARRAY_SIZE(ext_disp_be_dai_link); + } + msm_ext_dai_links = msm_ext_tavil_dai_links; + } else { + dev_err(dev, "%s: failing as no matching card name\n", + __func__); + return NULL; + } + card->dai_link = msm_ext_dai_links; + card->num_links = len4; + + return card; +} +EXPORT_SYMBOL(populate_snd_card_dailinks); diff --git a/sound/soc/msm/sdm660-external.c b/sound/soc/msm/sdm660-external.c new file mode 100644 index 000000000000..2c3d7fc3e63f --- /dev/null +++ b/sound/soc/msm/sdm660-external.c @@ -0,0 +1,1869 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qdsp6v2/msm-pcm-routing-v2.h" +#include "msm-audio-pinctrl.h" +#include "sdm660-common.h" +#include "sdm660-external.h" +#include "../codecs/wcd9335.h" +#include "../codecs/wcd934x/wcd934x.h" +#include "../codecs/wcd934x/wcd934x-mbhc.h" + +#define SDM660_SPK_ON 1 +#define SDM660_SPK_OFF 0 + +#define WCD9XXX_MBHC_DEF_BUTTONS 8 +#define WCD9XXX_MBHC_DEF_RLOADS 5 +#define CODEC_EXT_CLK_RATE 9600000 +#define ADSP_STATE_READY_TIMEOUT_MS 3000 + +#define TLMM_CENTER_MPM_WAKEUP_INT_EN_0 0x03596000 +#define LPI_GPIO_22_WAKEUP_VAL 0x00000002 + +#define TLMM_LPI_DIR_CONN_INTR1_CFG_APPS 0x0359D004 +#define LPI_GPIO_22_INTR1_CFG_VAL 0x01 +#define LPI_GPIO_22_INTR1_CFG_MASK 0x03 + +#define TLMM_LPI_GPIO_INTR_CFG1 0x0359B004 +#define LPI_GPIO_INTR_CFG1_VAL 0x00000113 + +#define TLMM_LPI_GPIO22_CFG 0x15078040 +#define LPI_GPIO22_CFG_VAL 0x0000009 + +#define TLMM_LPI_GPIO22_INOUT 0x179D1318 +#define LPI_GPIO22_INOUT_VAL 0x0020000 + +#define WSA8810_NAME_1 "wsa881x.20170211" +#define WSA8810_NAME_2 "wsa881x.20170212" + +static int msm_ext_spk_control = 1; +static struct wcd_mbhc_config *wcd_mbhc_cfg_ptr; +bool codec_reg_done; + +struct msm_asoc_wcd93xx_codec { + void* (*get_afe_config_fn)(struct snd_soc_codec *codec, + enum afe_config_type config_type); + void (*mbhc_hs_detect_exit)(struct snd_soc_codec *codec); +}; + +static struct msm_asoc_wcd93xx_codec msm_codec_fn; +static struct platform_device *spdev; + +static bool is_initial_boot; + +static void *def_ext_mbhc_cal(void); + +enum { + SLIM_RX_0 = 0, + SLIM_RX_1, + SLIM_RX_2, + SLIM_RX_3, + SLIM_RX_4, + SLIM_RX_5, + SLIM_RX_6, + SLIM_RX_7, + SLIM_RX_MAX, +}; + +enum { + SLIM_TX_0 = 0, + SLIM_TX_1, + SLIM_TX_2, + SLIM_TX_3, + SLIM_TX_4, + SLIM_TX_5, + SLIM_TX_6, + SLIM_TX_7, + SLIM_TX_8, + SLIM_TX_MAX, +}; + +struct dev_config { + u32 sample_rate; + u32 bit_format; + u32 channels; +}; + +/* Default configuration of slimbus channels */ +static struct dev_config slim_rx_cfg[] = { + [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config slim_tx_cfg[] = { + [SLIM_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static int msm_vi_feed_tx_ch = 2; +static const char *const slim_rx_ch_text[] = {"One", "Two"}; +static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static const char *const vi_feed_ch_text[] = {"One", "Two"}; +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; +static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static const char *const spk_function_text[] = {"Off", "On"}; +static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_48"}; + +static SOC_ENUM_SINGLE_EXT_DECL(spk_func_en, spk_function_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_1_tx_chs, slim_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); + +static int slim_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 10; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int slim_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + sample_rate = SAMPLING_RATE_384KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int slim_get_bit_format_val(int bit_format) +{ + int val = 0; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + val = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + val = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + val = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + val = 0; + break; + } + return val; +} + +static int slim_get_bit_format(int val) +{ + int bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + + switch (val) { + case 0: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + bit_fmt = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + bit_fmt = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + bit_fmt = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return bit_fmt; +} + +static int slim_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int port_id = 0; + + if (strnstr(kcontrol->id.name, "SLIM_0_RX", sizeof("SLIM_0_RX"))) + port_id = SLIM_RX_0; + else if (strnstr(kcontrol->id.name, "SLIM_2_RX", sizeof("SLIM_2_RX"))) + port_id = SLIM_RX_2; + else if (strnstr(kcontrol->id.name, "SLIM_5_RX", sizeof("SLIM_5_RX"))) + port_id = SLIM_RX_5; + else if (strnstr(kcontrol->id.name, "SLIM_6_RX", sizeof("SLIM_6_RX"))) + port_id = SLIM_RX_6; + else if (strnstr(kcontrol->id.name, "SLIM_0_TX", sizeof("SLIM_0_TX"))) + port_id = SLIM_TX_0; + else if (strnstr(kcontrol->id.name, "SLIM_1_TX", sizeof("SLIM_1_TX"))) + port_id = SLIM_TX_1; + else { + pr_err("%s: unsupported channel: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + + return port_id; +} + +static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* + * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) + * when used for BT_SCO use case. Return either Rx or Tx sample rate + * value. + */ + switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate = %d", __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 0: + default: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n", + __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate, + slim_tx_cfg[SLIM_TX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_sample_rate_val(slim_rx_cfg[ch_num].sample_rate); + + pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].sample_rate = + slim_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_sample_rate_val(slim_tx_cfg[ch_num].sample_rate); + + pr_debug("%s: slim[%d]_tx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate = 0; + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + sample_rate = slim_get_sample_rate(ucontrol->value.enumerated.item[0]); + if (sample_rate == SAMPLING_RATE_44P1KHZ) { + pr_err("%s: Unsupported sample rate %d: for Tx path\n", + __func__, sample_rate); + return -EINVAL; + } + slim_tx_cfg[ch_num].sample_rate = sample_rate; + + pr_debug("%s: slim[%d]_tx_sample_rate = %d, value = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_bit_format_val(slim_rx_cfg[ch_num].bit_format); + + pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_rx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].bit_format = + slim_get_bit_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_rx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_bit_format_val(slim_tx_cfg[ch_num].bit_format); + + pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_tx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_tx_cfg[ch_num].bit_format = + slim_get_bit_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_tx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_slim_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].channels); + ucontrol->value.enumerated.item[0] = slim_rx_cfg[ch_num].channels - 1; + + return 0; +} + +static int msm_slim_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].channels); + + return 1; +} + +static int msm_slim_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].channels); + ucontrol->value.enumerated.item[0] = slim_tx_cfg[ch_num].channels - 1; + + return 0; +} + +static int msm_slim_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_tx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].channels); + + return 1; +} + +static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1; + pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch); + return 1; +} + +static void *def_ext_mbhc_cal(void) +{ + void *tavil_wcd_cal; + struct wcd_mbhc_btn_detect_cfg *btn_cfg; + u16 *btn_high; + + tavil_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, + WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); + if (!tavil_wcd_cal) + return NULL; + +#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(tavil_wcd_cal)->X) = (Y)) + S(v_hs_max, 1600); +#undef S +#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal)->X) = (Y)) + S(num_btn, WCD_MBHC_DEF_BUTTONS); +#undef S + + btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal); + btn_high = ((void *)&btn_cfg->_v_btn_low) + + (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); + + btn_high[0] = 75; + btn_high[1] = 150; + btn_high[2] = 237; + btn_high[3] = 500; + btn_high[4] = 500; + btn_high[5] = 500; + btn_high[6] = 500; + btn_high[7] = 500; + + return tavil_wcd_cal; +} + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + + +static void msm_ext_control(struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm = + snd_soc_codec_get_dapm(codec); + + pr_debug("%s: msm_ext_spk_control = %d", __func__, msm_ext_spk_control); + if (msm_ext_spk_control == SDM660_SPK_ON) { + snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp"); + snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp"); + } else { + snd_soc_dapm_disable_pin(dapm, "Lineout_1 amp"); + snd_soc_dapm_disable_pin(dapm, "Lineout_3 amp"); + } + snd_soc_dapm_sync(dapm); +} + +static int msm_ext_get_spk(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_ext_spk_control = %d\n", + __func__, msm_ext_spk_control); + ucontrol->value.integer.value[0] = msm_ext_spk_control; + return 0; +} + +static int msm_ext_set_spk(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + pr_debug("%s()\n", __func__); + if (msm_ext_spk_control == ucontrol->value.integer.value[0]) + return 0; + + msm_ext_spk_control = ucontrol->value.integer.value[0]; + msm_ext_control(codec); + return 1; +} + + +int msm_ext_enable_codec_mclk(struct snd_soc_codec *codec, int enable, + bool dapm) +{ + int ret; + + pr_debug("%s: enable = %d\n", __func__, enable); + + if (!strcmp(dev_name(codec->dev), "tasha_codec")) + ret = tasha_cdc_mclk_enable(codec, enable, dapm); + else if (!strcmp(dev_name(codec->dev), "tavil_codec")) + ret = tavil_cdc_mclk_enable(codec, enable); + else { + dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", + __func__); + ret = -EINVAL; + } + return ret; +} + +static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("Speaker Function", spk_func_en, msm_ext_get_spk, + msm_ext_set_spk), + SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, + msm_slim_rx_ch_get, msm_slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs, + msm_slim_rx_ch_get, msm_slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs, + msm_slim_tx_ch_get, msm_slim_tx_ch_put), + SOC_ENUM_EXT("SLIM_1_TX Channels", slim_1_tx_chs, + msm_slim_tx_ch_get, msm_slim_tx_ch_put), + SOC_ENUM_EXT("SLIM_5_RX Channels", slim_5_rx_chs, + msm_slim_rx_ch_get, msm_slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_6_RX Channels", slim_6_rx_chs, + msm_slim_rx_ch_get, msm_slim_rx_ch_put), + SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, + msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), + SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_5_RX Format", slim_5_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_6_RX Format", slim_6_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format, + slim_tx_bit_format_get, slim_tx_bit_format_put), + SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate, + slim_tx_sample_rate_get, slim_tx_sample_rate_put), + SOC_ENUM_EXT("SLIM_5_RX SampleRate", slim_5_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_6_RX SampleRate", slim_6_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), +}; + +static int msm_slim_get_ch_from_beid(int32_t be_id) +{ + int ch_id = 0; + + switch (be_id) { + case MSM_BACKEND_DAI_SLIMBUS_0_RX: + ch_id = SLIM_RX_0; + break; + case MSM_BACKEND_DAI_SLIMBUS_1_RX: + ch_id = SLIM_RX_1; + break; + case MSM_BACKEND_DAI_SLIMBUS_2_RX: + ch_id = SLIM_RX_2; + break; + case MSM_BACKEND_DAI_SLIMBUS_3_RX: + ch_id = SLIM_RX_3; + break; + case MSM_BACKEND_DAI_SLIMBUS_4_RX: + ch_id = SLIM_RX_4; + break; + case MSM_BACKEND_DAI_SLIMBUS_6_RX: + ch_id = SLIM_RX_6; + break; + case MSM_BACKEND_DAI_SLIMBUS_0_TX: + ch_id = SLIM_TX_0; + break; + case MSM_BACKEND_DAI_SLIMBUS_3_TX: + ch_id = SLIM_TX_3; + break; + default: + ch_id = SLIM_RX_0; + break; + } + + return ch_id; +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +/** + * msm_ext_be_hw_params_fixup - updates settings of ALSA BE hw params. + * + * @rtd: runtime dailink instance + * @params: HW params of associated backend dailink. + * + * Returns 0 on success or rc on failure. + */ +int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int rc = 0; + int idx; + void *config = NULL; + struct snd_soc_codec *codec = rtd->codec; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->be_id) { + case MSM_BACKEND_DAI_SLIMBUS_0_RX: + case MSM_BACKEND_DAI_SLIMBUS_1_RX: + case MSM_BACKEND_DAI_SLIMBUS_2_RX: + case MSM_BACKEND_DAI_SLIMBUS_3_RX: + case MSM_BACKEND_DAI_SLIMBUS_4_RX: + case MSM_BACKEND_DAI_SLIMBUS_6_RX: + idx = msm_slim_get_ch_from_beid(dai_link->be_id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[idx].bit_format); + rate->min = rate->max = slim_rx_cfg[idx].sample_rate; + channels->min = channels->max = slim_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_0_TX: + case MSM_BACKEND_DAI_SLIMBUS_3_TX: + idx = msm_slim_get_ch_from_beid(dai_link->be_id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[idx].bit_format); + rate->min = rate->max = slim_tx_cfg[idx].sample_rate; + channels->min = channels->max = slim_tx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_1_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[1].bit_format); + rate->min = rate->max = slim_tx_cfg[1].sample_rate; + channels->min = channels->max = slim_tx_cfg[1].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_4_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + SNDRV_PCM_FORMAT_S32_LE); + rate->min = rate->max = SAMPLING_RATE_8KHZ; + channels->min = channels->max = msm_vi_feed_tx_ch; + break; + + case MSM_BACKEND_DAI_SLIMBUS_5_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[5].bit_format); + rate->min = rate->max = slim_rx_cfg[5].sample_rate; + channels->min = channels->max = slim_rx_cfg[5].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_5_TX: + rate->min = rate->max = SAMPLING_RATE_16KHZ; + channels->min = channels->max = 1; + + config = msm_codec_fn.get_afe_config_fn(codec, + AFE_SLIMBUS_SLAVE_PORT_CONFIG); + if (config) { + rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, + config, SLIMBUS_5_TX); + if (rc) + pr_err("%s: Failed to set slimbus slave port config %d\n", + __func__, rc); + } + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[SLIM_RX_7].bit_format); + rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate; + channels->min = channels->max = + slim_rx_cfg[SLIM_RX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_8_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_8].channels; + break; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + return rc; +} +EXPORT_SYMBOL(msm_ext_be_hw_params_fixup); + +/** + * msm_snd_hw_params - hw params ops of backend dailink. + * + * @substream: PCM stream of associated backend dailink. + * @params: HW params of associated backend dailink. + * + * Returns 0 on success or ret on failure. + */ +int msm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + int ret = 0; + u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + u32 user_set_tx_ch = 0; + u32 rx_ch_count; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err_ch_map; + } + if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_5_RX) { + pr_debug("%s: rx_5_ch=%d\n", __func__, + slim_rx_cfg[5].channels); + rx_ch_count = slim_rx_cfg[5].channels; + } else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_2_RX) { + pr_debug("%s: rx_2_ch=%d\n", __func__, + slim_rx_cfg[2].channels); + rx_ch_count = slim_rx_cfg[2].channels; + } else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_6_RX) { + pr_debug("%s: rx_6_ch=%d\n", __func__, + slim_rx_cfg[6].channels); + rx_ch_count = slim_rx_cfg[6].channels; + } else { + pr_debug("%s: rx_0_ch=%d\n", __func__, + slim_rx_cfg[0].channels); + rx_ch_count = slim_rx_cfg[0].channels; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + rx_ch_count, rx_ch); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err_ch_map; + } + } else { + pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__, + codec_dai->name, codec_dai->id, user_set_tx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map\n, err:%d\n", + __func__, ret); + goto err_ch_map; + } + /* For _tx1 case */ + if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_0_TX) + user_set_tx_ch = slim_tx_cfg[0].channels; + /* For _tx3 case */ + else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_1_TX) + user_set_tx_ch = slim_tx_cfg[1].channels; + else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_4_TX) + user_set_tx_ch = msm_vi_feed_tx_ch; + else + user_set_tx_ch = tx_ch_cnt; + + pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), be_id (%d)\n", + __func__, slim_tx_cfg[0].channels, user_set_tx_ch, + tx_ch_cnt, dai_link->be_id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + user_set_tx_ch, tx_ch, 0, 0); + if (ret < 0) + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + } + +err_ch_map: + return ret; +} +EXPORT_SYMBOL(msm_snd_hw_params); + +/** + * msm_ext_slimbus_2_hw_params - hw params ops of slimbus_2 BE. + * + * @substream: PCM stream of associated backend dailink. + * @params: HW params of associated backend dailink. + * + * Returns 0 on success or ret on failure. + */ +int msm_ext_slimbus_2_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; + unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0; + unsigned int num_tx_ch = 0; + unsigned int num_rx_ch = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + num_rx_ch = params_channels(params); + pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__, + codec_dai->name, codec_dai->id, num_rx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto end; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + num_rx_ch, rx_ch); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto end; + } + } else { + num_tx_ch = params_channels(params); + pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__, + codec_dai->name, codec_dai->id, num_tx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto end; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, + num_tx_ch, tx_ch, 0, 0); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto end; + } + } +end: + return ret; +} +EXPORT_SYMBOL(msm_ext_slimbus_2_hw_params); + +/** + * msm_snd_cpe_hw_params - hw params ops of CPE backend. + * + * @substream: PCM stream of associated backend dailink. + * @params: HW params of associated backend dailink. + * + * Returns 0 on success or ret on failure. + */ +int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + int ret = 0; + u32 tx_ch[SLIM_MAX_TX_PORTS]; + u32 tx_ch_cnt = 0; + + if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) { + pr_err("%s: Invalid stream type %d\n", + __func__, substream->stream); + ret = -EINVAL; + goto end; + } + + pr_debug("%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, NULL, NULL); + if (ret < 0) { + pr_err("%s: failed to get codec chan map\n, err:%d\n", + __func__, ret); + goto end; + } + + pr_debug("%s: tx_ch_cnt(%d) be_id %d\n", + __func__, tx_ch_cnt, dai_link->be_id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, 0, 0); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto end; + } +end: + return ret; +} +EXPORT_SYMBOL(msm_snd_cpe_hw_params); + +static int msm_afe_set_config(struct snd_soc_codec *codec) +{ + int rc; + void *config_data; + + pr_debug("%s: enter\n", __func__); + + if (!msm_codec_fn.get_afe_config_fn) { + dev_err(codec->dev, "%s: codec get afe config not init'ed\n", + __func__); + return -EINVAL; + } + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CDC_REGISTERS_CONFIG); + if (config_data) { + rc = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0); + if (rc) { + pr_err("%s: Failed to set codec registers config %d\n", + __func__, rc); + return rc; + } + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CDC_REGISTER_PAGE_CONFIG); + if (config_data) { + rc = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, + 0); + if (rc) + pr_err("%s: Failed to set cdc register page config\n", + __func__); + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_SLIMBUS_SLAVE_CONFIG); + if (config_data) { + rc = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0); + if (rc) { + pr_err("%s: Failed to set slimbus slave config %d\n", + __func__, rc); + return rc; + } + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_AANC_VERSION); + if (config_data) { + rc = afe_set_config(AFE_AANC_VERSION, config_data, 0); + if (rc) { + pr_err("%s: Failed to set AANC version %d\n", + __func__, rc); + return rc; + } + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CDC_CLIP_REGISTERS_CONFIG); + if (config_data) { + rc = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG, + config_data, 0); + if (rc) { + pr_err("%s: Failed to set clip registers %d\n", + __func__, rc); + return rc; + } + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CLIP_BANK_SEL); + if (config_data) { + rc = afe_set_config(AFE_CLIP_BANK_SEL, + config_data, 0); + if (rc) { + pr_err("%s: Failed to set AFE bank selection %d\n", + __func__, rc); + return rc; + } + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CDC_REGISTER_PAGE_CONFIG); + if (config_data) { + rc = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, + 0); + if (rc) + pr_err("%s: Failed to set cdc register page config\n", + __func__); + } + + return 0; +} + +static void msm_afe_clear_config(void) +{ + afe_clear_config(AFE_CDC_REGISTERS_CONFIG); + afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); +} + +static void msm_snd_interrupt_config(struct msm_asoc_mach_data *pdata) +{ + int val; + + val = ioread32(pdata->msm_snd_intr_lpi.mpm_wakeup); + val |= LPI_GPIO_22_WAKEUP_VAL; + iowrite32(val, pdata->msm_snd_intr_lpi.mpm_wakeup); + + val = ioread32(pdata->msm_snd_intr_lpi.intr1_cfg_apps); + val &= ~(LPI_GPIO_22_INTR1_CFG_MASK); + val |= LPI_GPIO_22_INTR1_CFG_VAL; + iowrite32(val, pdata->msm_snd_intr_lpi.intr1_cfg_apps); + + iowrite32(LPI_GPIO_INTR_CFG1_VAL, + pdata->msm_snd_intr_lpi.lpi_gpio_intr_cfg); + iowrite32(LPI_GPIO22_CFG_VAL, + pdata->msm_snd_intr_lpi.lpi_gpio_cfg); + val = ioread32(pdata->msm_snd_intr_lpi.lpi_gpio_inout); + val |= LPI_GPIO22_INOUT_VAL; + iowrite32(val, pdata->msm_snd_intr_lpi.lpi_gpio_inout); +} + +static int msm_adsp_power_up_config(struct snd_soc_codec *codec) +{ + int ret = 0; + unsigned long timeout; + int adsp_ready = 0; + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata; + + pdata = snd_soc_card_get_drvdata(card); + timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + + do { + if (q6core_is_adsp_ready()) { + pr_debug("%s: ADSP Audio is ready\n", __func__); + adsp_ready = 1; + break; + } + /* + * ADSP will be coming up after subsystem restart and + * it might not be fully up when the control reaches + * here. So, wait for 50msec before checking ADSP state + */ + msleep(50); + } while (time_after(timeout, jiffies)); + + if (!adsp_ready) { + pr_err("%s: timed out waiting for ADSP Audio\n", __func__); + ret = -ETIMEDOUT; + goto err_fail; + } + msm_snd_interrupt_config(pdata); + + ret = msm_afe_set_config(codec); + if (ret) + pr_err("%s: Failed to set AFE config. err %d\n", + __func__, ret); + + return 0; + +err_fail: + return ret; +} + +static int sdm660_notifier_service_cb(struct notifier_block *this, + unsigned long opcode, void *ptr) +{ + int ret; + struct snd_soc_card *card = NULL; + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + struct snd_soc_codec *codec; + + pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); + + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + /* + * Use flag to ignore initial boot notifications + * On initial boot msm_adsp_power_up_config is + * called on init. There is no need to clear + * and set the config again on initial boot. + */ + if (is_initial_boot) + break; + msm_afe_clear_config(); + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (is_initial_boot) { + is_initial_boot = false; + break; + } + if (!spdev) + return -EINVAL; + + card = platform_get_drvdata(spdev); + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto done; + } + codec = rtd->codec; + + ret = msm_adsp_power_up_config(codec); + if (ret < 0) { + dev_err(card->dev, + "%s: msm_adsp_power_up_config failed ret = %d!\n", + __func__, ret); + goto done; + } + break; + default: + break; + } +done: + return NOTIFY_OK; +} + +static struct notifier_block service_nb = { + .notifier_call = sdm660_notifier_service_cb, + .priority = -INT_MAX, +}; + +static int msm_config_hph_en0_gpio(struct snd_soc_codec *codec, bool high) +{ + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata; + int val; + + if (!card) + return 0; + + pdata = snd_soc_card_get_drvdata(card); + if (!pdata || !gpio_is_valid(pdata->hph_en0_gpio)) + return 0; + + val = gpio_get_value_cansleep(pdata->hph_en0_gpio); + if ((!!val) == high) + return 0; + + gpio_direction_output(pdata->hph_en0_gpio, (int)high); + + return 1; +} + +static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, + int enable, bool dapm) +{ + int ret = 0; + + if (!strcmp(dev_name(codec->dev), "tasha_codec")) + ret = tasha_cdc_mclk_tx_enable(codec, enable, dapm); + else { + dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", + __func__); + ret = -EINVAL; + } + return ret; +} + +static int msm_ext_mclk_tx_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + pr_debug("%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return msm_snd_enable_codec_ext_tx_clk(codec, 1, true); + case SND_SOC_DAPM_POST_PMD: + return msm_snd_enable_codec_ext_tx_clk(codec, 0, true); + } + return 0; +} + +static int msm_ext_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + pr_debug("%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return msm_ext_enable_codec_mclk(codec, 1, true); + case SND_SOC_DAPM_POST_PMD: + return msm_ext_enable_codec_mclk(codec, 0, true); + } + return 0; +} + +static int msm_ext_prepare_hifi(struct msm_asoc_mach_data *pdata) +{ + int ret = 0; + + if (gpio_is_valid(pdata->hph_en1_gpio)) { + pr_debug("%s: hph_en1_gpio request %d\n", __func__, + pdata->hph_en1_gpio); + ret = gpio_request(pdata->hph_en1_gpio, "hph_en1_gpio"); + if (ret) { + pr_err("%s: hph_en1_gpio request failed, ret:%d\n", + __func__, ret); + goto err; + } + } + if (gpio_is_valid(pdata->hph_en0_gpio)) { + pr_debug("%s: hph_en0_gpio request %d\n", __func__, + pdata->hph_en0_gpio); + ret = gpio_request(pdata->hph_en0_gpio, "hph_en0_gpio"); + if (ret) + pr_err("%s: hph_en0_gpio request failed, ret:%d\n", + __func__, ret); + } + +err: + return ret; +} + +static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { + + SND_SOC_DAPM_SUPPLY_S("MCLK", -1, SND_SOC_NOPM, 0, 0, + msm_ext_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("MCLK TX", -1, SND_SOC_NOPM, 0, 0, + msm_ext_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SPK("Lineout_1 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_3 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_4 amp", NULL), + SND_SOC_DAPM_MIC("Handset Mic", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Secondary Mic", NULL), + SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), + SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL), + SND_SOC_DAPM_MIC("Analog Mic4", NULL), + SND_SOC_DAPM_MIC("Analog Mic6", NULL), + SND_SOC_DAPM_MIC("Analog Mic7", NULL), + SND_SOC_DAPM_MIC("Analog Mic8", NULL), + + SND_SOC_DAPM_MIC("Digital Mic0", NULL), + SND_SOC_DAPM_MIC("Digital Mic1", NULL), + SND_SOC_DAPM_MIC("Digital Mic2", NULL), + SND_SOC_DAPM_MIC("Digital Mic3", NULL), + SND_SOC_DAPM_MIC("Digital Mic4", NULL), + SND_SOC_DAPM_MIC("Digital Mic5", NULL), + SND_SOC_DAPM_MIC("Digital Mic6", NULL), +}; + +static struct snd_soc_dapm_route wcd_audio_paths_tasha[] = { + {"MIC BIAS1", NULL, "MCLK TX"}, + {"MIC BIAS2", NULL, "MCLK TX"}, + {"MIC BIAS3", NULL, "MCLK TX"}, + {"MIC BIAS4", NULL, "MCLK TX"}, +}; + +static struct snd_soc_dapm_route wcd_audio_paths[] = { + {"MIC BIAS1", NULL, "MCLK"}, + {"MIC BIAS2", NULL, "MCLK"}, + {"MIC BIAS3", NULL, "MCLK"}, + {"MIC BIAS4", NULL, "MCLK"}, +}; + +/** + * msm_audrx_init - Audio init function of sound card instantiate. + * + * @rtd: runtime dailink instance + * + * Returns 0 on success or ret on failure. + */ +int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret; + void *config_data; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = + snd_soc_codec_get_dapm(codec); + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_pcm_runtime *rtd_aux = rtd->card->rtd_aux; + struct snd_card *card; + struct snd_info_entry *entry; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); + + /* Codec SLIMBUS configuration + * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13 + * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 + * TX14, TX15, TX16 + */ + unsigned int rx_ch[TASHA_RX_MAX] = {144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156}; + unsigned int tx_ch[TASHA_TX_MAX] = {128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143}; + + /* Tavil Codec SLIMBUS configuration + * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8 + * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 + * TX14, TX15, TX16 + */ + unsigned int rx_ch_tavil[WCD934X_RX_MAX] = {144, 145, 146, 147, 148, + 149, 150, 151}; + unsigned int tx_ch_tavil[WCD934X_TX_MAX] = {128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143}; + + pr_debug("%s: dev_name%s\n", __func__, dev_name(cpu_dai->dev)); + + rtd->pmdown_time = 0; + + ret = snd_soc_add_codec_controls(codec, msm_snd_controls, + ARRAY_SIZE(msm_snd_controls)); + if (ret < 0) { + pr_err("%s: add_codec_controls failed: %d\n", + __func__, ret); + return ret; + } + + ret = snd_soc_add_codec_controls(codec, msm_common_snd_controls, + msm_common_snd_controls_size()); + if (ret < 0) { + pr_err("%s: add_common_snd_controls failed: %d\n", + __func__, ret); + return ret; + } + + snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, + ARRAY_SIZE(msm_dapm_widgets)); + + if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) + snd_soc_dapm_add_routes(dapm, wcd_audio_paths_tasha, + ARRAY_SIZE(wcd_audio_paths_tasha)); + else + snd_soc_dapm_add_routes(dapm, wcd_audio_paths, + ARRAY_SIZE(wcd_audio_paths)); + + snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp"); + snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp"); + snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp"); + snd_soc_dapm_enable_pin(dapm, "Lineout_4 amp"); + + snd_soc_dapm_ignore_suspend(dapm, "MADINPUT"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT"); + snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Secondary Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Lineout_1 amp"); + snd_soc_dapm_ignore_suspend(dapm, "Lineout_3 amp"); + snd_soc_dapm_ignore_suspend(dapm, "Lineout_2 amp"); + snd_soc_dapm_ignore_suspend(dapm, "Lineout_4 amp"); + snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic7"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic8"); + + snd_soc_dapm_ignore_suspend(dapm, "EAR"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC4"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC5"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC0"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC4"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC5"); + snd_soc_dapm_ignore_suspend(dapm, "ANC EAR"); + snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); + snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); + + if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) { + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT1"); + snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT2"); + } else { + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT1"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT2"); + } + + snd_soc_dapm_sync(dapm); + + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { + snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch_tavil), + tx_ch_tavil, ARRAY_SIZE(rx_ch_tavil), + rx_ch_tavil); + } else { + snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), + rx_ch); + } + + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { + msm_codec_fn.get_afe_config_fn = tavil_get_afe_config; + } else { + msm_codec_fn.get_afe_config_fn = tasha_get_afe_config; + msm_codec_fn.mbhc_hs_detect_exit = tasha_mbhc_hs_detect_exit; + } + + ret = msm_adsp_power_up_config(codec); + if (ret) { + pr_err("%s: Failed to set AFE config %d\n", __func__, ret); + goto err_afe_cfg; + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_AANC_VERSION); + if (config_data) { + ret = afe_set_config(AFE_AANC_VERSION, config_data, 0); + if (ret) { + pr_err("%s: Failed to set aanc version %d\n", + __func__, ret); + goto err_afe_cfg; + } + } + + if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) { + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CDC_CLIP_REGISTERS_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG, + config_data, 0); + if (ret) { + pr_err("%s: Failed to set clip registers %d\n", + __func__, ret); + goto err_afe_cfg; + } + } + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CLIP_BANK_SEL); + if (config_data) { + ret = afe_set_config(AFE_CLIP_BANK_SEL, config_data, 0); + if (ret) { + pr_err("%s: Failed to set AFE bank selection %d\n", + __func__, ret); + goto err_afe_cfg; + } + } + } + + /* + * Send speaker configuration only for WSA8810. + * Defalut configuration is for WSA8815. + */ + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { + if (rtd_aux && rtd_aux->component) + if (!strcmp(rtd_aux->component->name, WSA8810_NAME_1) || + !strcmp(rtd_aux->component->name, WSA8810_NAME_2)) { + tavil_set_spkr_mode(rtd->codec, SPKR_MODE_1); + tavil_set_spkr_gain_offset(rtd->codec, + RX_GAIN_OFFSET_M1P5_DB); + } + card = rtd->card->snd_card; + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + pdata->codec_root = NULL; + goto done; + } + pdata->codec_root = entry; + tavil_codec_info_create_codec_entry(pdata->codec_root, codec); + } else { + if (rtd_aux && rtd_aux->component) + if (!strcmp(rtd_aux->component->name, WSA8810_NAME_1) || + !strcmp(rtd_aux->component->name, WSA8810_NAME_2)) { + tasha_set_spkr_mode(rtd->codec, SPKR_MODE_1); + tasha_set_spkr_gain_offset(rtd->codec, + RX_GAIN_OFFSET_M1P5_DB); + } + card = rtd->card->snd_card; + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto err_snd_module; + } + pdata->codec_root = entry; + tasha_codec_info_create_codec_entry(pdata->codec_root, codec); + tasha_mbhc_zdet_gpio_ctrl(msm_config_hph_en0_gpio, rtd->codec); + } + + wcd_mbhc_cfg_ptr->calibration = def_ext_mbhc_cal(); + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { + if (wcd_mbhc_cfg_ptr->calibration) { + pdata->codec = codec; + ret = tavil_mbhc_hs_detect(codec, wcd_mbhc_cfg_ptr); + if (ret < 0) + pr_err("%s: Failed to intialise mbhc %d\n", + __func__, ret); + } else { + pr_err("%s: wcd_mbhc_cfg calibration is NULL\n", + __func__); + ret = -ENOMEM; + goto err_mbhc_cal; + } + } else { + if (wcd_mbhc_cfg_ptr->calibration) { + pdata->codec = codec; + ret = tasha_mbhc_hs_detect(codec, wcd_mbhc_cfg_ptr); + if (ret < 0) + pr_err("%s: Failed to intialise mbhc %d\n", + __func__, ret); + } else { + pr_err("%s: wcd_mbhc_cfg calibration is NULL\n", + __func__); + ret = -ENOMEM; + goto err_mbhc_cal; + } + + } + codec_reg_done = true; +done: + return 0; + +err_snd_module: +err_afe_cfg: +err_mbhc_cal: + return ret; +} +EXPORT_SYMBOL(msm_audrx_init); + +/** + * msm_ext_register_audio_notifier - register SSR notifier. + */ +void msm_ext_register_audio_notifier(struct platform_device *pdev) +{ + int ret; + + is_initial_boot = true; + spdev = pdev; + ret = audio_notifier_register("sdm660", AUDIO_NOTIFIER_ADSP_DOMAIN, + &service_nb); + if (ret < 0) + pr_err("%s: Audio notifier register failed ret = %d\n", + __func__, ret); +} +EXPORT_SYMBOL(msm_ext_register_audio_notifier); + +/** + * msm_ext_cdc_init - external codec machine specific init. + * + * @pdev: platform device handle + * @pdata: private data of machine driver + * @card: sound card pointer reference + * @mbhc_cfg: MBHC config reference + * + * Returns 0 on success or ret on failure. + */ +int msm_ext_cdc_init(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata, + struct snd_soc_card **card, + struct wcd_mbhc_config *wcd_mbhc_cfg_ptr1) +{ + int ret = 0; + + wcd_mbhc_cfg_ptr = wcd_mbhc_cfg_ptr1; + pdev->id = 0; + wcd_mbhc_cfg_ptr->moisture_en = true; + wcd_mbhc_cfg_ptr->mbhc_micbias = MIC_BIAS_2; + wcd_mbhc_cfg_ptr->anc_micbias = MIC_BIAS_2; + wcd_mbhc_cfg_ptr->enable_anc_mic_detect = false; + + *card = populate_snd_card_dailinks(&pdev->dev, pdata->snd_card_val); + if (!(*card)) { + dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); + ret = -EPROBE_DEFER; + goto err; + } + platform_set_drvdata(pdev, *card); + snd_soc_card_set_drvdata(*card, pdata); + pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,hph-en1-gpio", 0); + if (!gpio_is_valid(pdata->hph_en1_gpio)) + pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en1-gpio", 0); + if (!gpio_is_valid(pdata->hph_en1_gpio) && (!pdata->hph_en1_gpio_p)) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,hph-en1-gpio", pdev->dev.of_node->full_name); + } + + pdata->hph_en0_gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,hph-en0-gpio", 0); + if (!gpio_is_valid(pdata->hph_en0_gpio)) + pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en0-gpio", 0); + if (!gpio_is_valid(pdata->hph_en0_gpio) && (!pdata->hph_en0_gpio_p)) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,hph-en0-gpio", pdev->dev.of_node->full_name); + } + + ret = msm_ext_prepare_hifi(pdata); + if (ret) { + dev_dbg(&pdev->dev, "msm_ext_prepare_hifi failed (%d)\n", + ret); + ret = 0; + } + pdata->msm_snd_intr_lpi.mpm_wakeup = + ioremap(TLMM_CENTER_MPM_WAKEUP_INT_EN_0, 4); + pdata->msm_snd_intr_lpi.intr1_cfg_apps = + ioremap(TLMM_LPI_DIR_CONN_INTR1_CFG_APPS, 4); + pdata->msm_snd_intr_lpi.lpi_gpio_intr_cfg = + ioremap(TLMM_LPI_GPIO_INTR_CFG1, 4); + pdata->msm_snd_intr_lpi.lpi_gpio_cfg = + ioremap(TLMM_LPI_GPIO22_CFG, 4); + pdata->msm_snd_intr_lpi.lpi_gpio_inout = + ioremap(TLMM_LPI_GPIO22_INOUT, 4); +err: + return ret; +} +EXPORT_SYMBOL(msm_ext_cdc_init); + +/** + * msm_ext_cdc_deinit - external codec machine specific deinit. + */ +void msm_ext_cdc_deinit(struct msm_asoc_mach_data *pdata) +{ + if (pdata->msm_snd_intr_lpi.mpm_wakeup) + iounmap(pdata->msm_snd_intr_lpi.mpm_wakeup); + if (pdata->msm_snd_intr_lpi.intr1_cfg_apps) + iounmap(pdata->msm_snd_intr_lpi.intr1_cfg_apps); + if (pdata->msm_snd_intr_lpi.lpi_gpio_intr_cfg) + iounmap(pdata->msm_snd_intr_lpi.lpi_gpio_intr_cfg); + if (pdata->msm_snd_intr_lpi.lpi_gpio_cfg) + iounmap(pdata->msm_snd_intr_lpi.lpi_gpio_cfg); + if (pdata->msm_snd_intr_lpi.lpi_gpio_inout) + iounmap(pdata->msm_snd_intr_lpi.lpi_gpio_inout); + +} +EXPORT_SYMBOL(msm_ext_cdc_deinit); diff --git a/sound/soc/msm/sdm660-external.h b/sound/soc/msm/sdm660-external.h new file mode 100644 index 000000000000..acf5735c2502 --- /dev/null +++ b/sound/soc/msm/sdm660-external.h @@ -0,0 +1,54 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __SDM660_EXTERNAL +#define __SDM660_EXTERNAL + +int msm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params); +int msm_ext_slimbus_2_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params); +int msm_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params); +int msm_proxy_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params); +int msm_proxy_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params); +int msm_audrx_init(struct snd_soc_pcm_runtime *rtd); +int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params); +struct snd_soc_card *populate_snd_card_dailinks(struct device *dev, + int snd_card_val); +int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params); +#ifdef CONFIG_SND_SOC_EXT_CODEC +int msm_ext_cdc_init(struct platform_device *, struct msm_asoc_mach_data *, + struct snd_soc_card **, struct wcd_mbhc_config *); +void msm_ext_register_audio_notifier(struct platform_device *pdev); +void msm_ext_cdc_deinit(struct msm_asoc_mach_data *pdata); +#else +inline int msm_ext_cdc_init(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata, + struct snd_soc_card **card, + struct wcd_mbhc_config *wcd_mbhc_cfg_ptr1) +{ + return 0; +} + +inline void msm_ext_register_audio_notifier(struct platform_device *pdev) +{ +} +inline void msm_ext_cdc_deinit(void) +{ +} +#endif +#endif diff --git a/sound/soc/msm/sdm660-internal.c b/sound/soc/msm/sdm660-internal.c new file mode 100644 index 000000000000..802137ba4b50 --- /dev/null +++ b/sound/soc/msm/sdm660-internal.c @@ -0,0 +1,3149 @@ +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include "qdsp6v2/msm-pcm-routing-v2.h" +#include "sdm660-common.h" +#include "../codecs/sdm660_cdc/msm-digital-cdc.h" +#include "../codecs/sdm660_cdc/msm-analog-cdc.h" +#include "../codecs/msm_sdw/msm_sdw.h" + +#define __CHIPSET__ "SDM660 " +#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) + +#define DEFAULT_MCLK_RATE 9600000 +#define NATIVE_MCLK_RATE 11289600 + +#define WCD_MBHC_DEF_RLOADS 5 + +#define WCN_CDC_SLIM_RX_CH_MAX 2 +#define WCN_CDC_SLIM_TX_CH_MAX 3 + +#define WSA8810_NAME_1 "wsa881x.20170211" +#define WSA8810_NAME_2 "wsa881x.20170212" + +enum { + INT0_MI2S = 0, + INT1_MI2S, + INT2_MI2S, + INT3_MI2S, + INT4_MI2S, + INT5_MI2S, + INT6_MI2S, + INT_MI2S_MAX, +}; + +enum { + BT_SLIM7, + FM_SLIM8, + SLIM_MAX, +}; + +/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */ +static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { + {0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */ +}; + +static struct afe_clk_set int_mi2s_clk[INT_MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_INT0_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_INT1_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_INT2_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_INT3_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_INT4_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_INT5_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_INT6_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, +}; + +struct dev_config { + u32 sample_rate; + u32 bit_format; + u32 channels; +}; + +/* Default configuration of MI2S channels */ +static struct dev_config int_mi2s_cfg[] = { + [INT0_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [INT1_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [INT2_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [INT3_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [INT4_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [INT5_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [INT6_MI2S] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config bt_fm_cfg[] = { + [BT_SLIM7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [FM_SLIM8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static char const *int_mi2s_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_96", "KHZ_192"}; +static const char *const int_mi2s_ch_text[] = {"One", "Two"}; +static const char *const int_mi2s_tx_ch_text[] = {"One", "Two", + "Three", "Four"}; +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"}; +static const char *const loopback_mclk_text[] = {"DISABLE", "ENABLE"}; +static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_48"}; + +static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_sample_rate, int_mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_chs, int_mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(int2_mi2s_tx_sample_rate, int_mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(int2_mi2s_tx_chs, int_mi2s_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(int2_mi2s_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(int3_mi2s_tx_sample_rate, int_mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(int3_mi2s_tx_chs, int_mi2s_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(int3_mi2s_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_sample_rate, int_mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_chs, int_mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(int5_mi2s_tx_chs, int_mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(loopback_mclk_en, loopback_mclk_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); + +static int msm_dmic_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); +static int msm_int_enable_dig_cdc_clk(struct snd_soc_codec *codec, int enable, + bool dapm); +static int msm_int_mclk0_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); +static int msm_int_mi2s_snd_startup(struct snd_pcm_substream *substream); +static void msm_int_mi2s_snd_shutdown(struct snd_pcm_substream *substream); + +static struct wcd_mbhc_config *mbhc_cfg_ptr; +static struct snd_info_entry *codec_root; + +static int int_mi2s_get_bit_format_val(int bit_format) +{ + int val = 0; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S24_3LE: + val = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + val = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + val = 0; + break; + } + return val; +} + +static int int_mi2s_get_bit_format(int val) +{ + int bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + + switch (val) { + case 0: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + bit_fmt = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + bit_fmt = SNDRV_PCM_FORMAT_S24_3LE; + break; + default: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return bit_fmt; +} + +static int int_mi2s_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int port_id = 0; + + if (strnstr(kcontrol->id.name, "INT0_MI2S", sizeof("INT0_MI2S"))) + port_id = INT0_MI2S; + else if (strnstr(kcontrol->id.name, "INT2_MI2S", sizeof("INT2_MI2S"))) + port_id = INT2_MI2S; + else if (strnstr(kcontrol->id.name, "INT3_MI2S", sizeof("INT3_MI2S"))) + port_id = INT3_MI2S; + else if (strnstr(kcontrol->id.name, "INT4_MI2S", sizeof("INT4_MI2S"))) + port_id = INT4_MI2S; + else { + pr_err("%s: unsupported channel: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + + return port_id; +} + +static int int_mi2s_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = int_mi2s_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + int_mi2s_get_bit_format_val(int_mi2s_cfg[ch_num].bit_format); + + pr_debug("%s: int_mi2s[%d]_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, int_mi2s_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int int_mi2s_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = int_mi2s_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + int_mi2s_cfg[ch_num].bit_format = + int_mi2s_get_bit_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: int_mi2s[%d]_rx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, int_mi2s_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, + int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +static int int_mi2s_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 6; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int int_mi2s_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_192KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int int_mi2s_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = int_mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + int_mi2s_cfg[idx].sample_rate = + int_mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_sample_rate = %d, item = %d\n", __func__, + idx, int_mi2s_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int int_mi2s_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = int_mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + int_mi2s_get_sample_rate_val(int_mi2s_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_sample_rate = %d, item = %d\n", __func__, + idx, int_mi2s_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int int_mi2s_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = int_mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: int_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, int_mi2s_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = int_mi2s_cfg[idx].channels - 1; + + return 0; +} + +static int int_mi2s_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = int_mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + int_mi2s_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: int_mi2s_[%d]_ch = %d\n", __func__, + idx, int_mi2s_cfg[idx].channels); + + return 1; +} + +static const struct snd_soc_dapm_widget msm_int_dapm_widgets[] = { + SND_SOC_DAPM_SUPPLY_S("INT_MCLK0", -1, SND_SOC_NOPM, 0, 0, + msm_int_mclk0_event, SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIC("Handset Mic", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Secondary Mic", NULL), + SND_SOC_DAPM_MIC("Digital Mic1", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic2", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic3", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic4", msm_dmic_event), +}; + +static int msm_config_hph_compander_gpio(bool enable, + struct snd_soc_codec *codec) +{ + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + int ret = 0; + + pr_debug("%s: %s HPH Compander\n", __func__, + enable ? "Enable" : "Disable"); + + if (enable) { + ret = msm_cdc_pinctrl_select_active_state(pdata->comp_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be activated %s\n", + __func__, "comp_gpio"); + goto done; + } + } else { + ret = msm_cdc_pinctrl_select_sleep_state(pdata->comp_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be de-activated %s\n", + __func__, "comp_gpio"); + goto done; + } + } + +done: + return ret; +} + +static int is_ext_spk_gpio_support(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata) +{ + const char *spk_ext_pa = "qcom,msm-spk-ext-pa"; + + pr_debug("%s:Enter\n", __func__); + + pdata->spk_ext_pa_gpio = of_get_named_gpio(pdev->dev.of_node, + spk_ext_pa, 0); + + if (pdata->spk_ext_pa_gpio < 0) { + dev_dbg(&pdev->dev, + "%s: missing %s in dt node\n", __func__, spk_ext_pa); + } else { + if (!gpio_is_valid(pdata->spk_ext_pa_gpio)) { + pr_err("%s: Invalid external speaker gpio: %d", + __func__, pdata->spk_ext_pa_gpio); + return -EINVAL; + } + } + return 0; +} + +static int enable_spk_ext_pa(struct snd_soc_codec *codec, int enable) +{ + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + int ret; + + if (!gpio_is_valid(pdata->spk_ext_pa_gpio)) { + pr_err("%s: Invalid gpio: %d\n", __func__, + pdata->spk_ext_pa_gpio); + return false; + } + + pr_debug("%s: %s external speaker PA\n", __func__, + enable ? "Enable" : "Disable"); + + if (enable) { + ret = msm_cdc_pinctrl_select_active_state( + pdata->ext_spk_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be de-activated %s\n", + __func__, "ext_spk_gpio"); + return ret; + } + gpio_set_value_cansleep(pdata->spk_ext_pa_gpio, enable); + } else { + gpio_set_value_cansleep(pdata->spk_ext_pa_gpio, enable); + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->ext_spk_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be de-activated %s\n", + __func__, "ext_spk_gpio"); + return ret; + } + } + return 0; +} + +static int int_mi2s_get_idx_from_beid(int32_t be_id) +{ + int idx = 0; + + switch (be_id) { + case MSM_BACKEND_DAI_INT0_MI2S_RX: + idx = INT0_MI2S; + break; + case MSM_BACKEND_DAI_INT2_MI2S_TX: + idx = INT2_MI2S; + break; + case MSM_BACKEND_DAI_INT3_MI2S_TX: + idx = INT3_MI2S; + break; + case MSM_BACKEND_DAI_INT4_MI2S_RX: + idx = INT4_MI2S; + break; + case MSM_BACKEND_DAI_INT5_MI2S_TX: + idx = INT5_MI2S; + break; + default: + idx = INT0_MI2S; + break; + } + + return idx; +} + +static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + pr_debug("%s()\n", __func__); + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + + return 0; +} + +static int int_mi2s_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int idx; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->be_id) { + case MSM_BACKEND_DAI_INT0_MI2S_RX: + case MSM_BACKEND_DAI_INT2_MI2S_TX: + case MSM_BACKEND_DAI_INT3_MI2S_TX: + case MSM_BACKEND_DAI_INT4_MI2S_RX: + case MSM_BACKEND_DAI_INT5_MI2S_TX: + idx = int_mi2s_get_idx_from_beid(dai_link->be_id); + rate->min = rate->max = int_mi2s_cfg[idx].sample_rate; + channels->min = channels->max = + int_mi2s_cfg[idx].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + int_mi2s_cfg[idx].bit_format); + break; + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + return 0; +} + +static int msm_btfm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + switch (dai_link->be_id) { + case MSM_BACKEND_DAI_SLIMBUS_7_RX: + case MSM_BACKEND_DAI_SLIMBUS_7_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + bt_fm_cfg[BT_SLIM7].bit_format); + rate->min = rate->max = bt_fm_cfg[BT_SLIM7].sample_rate; + channels->min = channels->max = + bt_fm_cfg[BT_SLIM7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_8_TX: + rate->min = rate->max = bt_fm_cfg[FM_SLIM8].sample_rate; + channels->min = channels->max = + bt_fm_cfg[FM_SLIM8].channels; + break; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + return 0; +} + +static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = + (int_mi2s_cfg[INT5_MI2S].channels/2 - 1); + pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int_mi2s_cfg[INT5_MI2S].channels = + roundup_pow_of_two(ucontrol->value.integer.value[0] + 2); + + pr_debug("%s: msm_vi_feed_tx_ch = %d\n", + __func__, int_mi2s_cfg[INT5_MI2S].channels); + return 1; +} + +static int msm_int_enable_dig_cdc_clk(struct snd_soc_codec *codec, + int enable, bool dapm) +{ + int ret = 0; + struct msm_asoc_mach_data *pdata = NULL; + int clk_freq_in_hz; + bool int_mclk0_freq_chg = false; + + pdata = snd_soc_card_get_drvdata(codec->component.card); + pr_debug("%s: enable %d mclk ref counter %d\n", + __func__, enable, + atomic_read(&pdata->int_mclk0_rsc_ref)); + if (enable) { + if (int_mi2s_cfg[INT0_MI2S].sample_rate == + SAMPLING_RATE_44P1KHZ) { + clk_freq_in_hz = NATIVE_MCLK_RATE; + pdata->native_clk_set = true; + } else { + clk_freq_in_hz = pdata->mclk_freq; + pdata->native_clk_set = false; + } + + if (pdata->digital_cdc_core_clk.clk_freq_in_hz + != clk_freq_in_hz) + int_mclk0_freq_chg = true; + if (!atomic_read(&pdata->int_mclk0_rsc_ref) || + int_mclk0_freq_chg) { + cancel_delayed_work_sync( + &pdata->disable_int_mclk0_work); + mutex_lock(&pdata->cdc_int_mclk0_mutex); + if (atomic_read(&pdata->int_mclk0_enabled) == false || + int_mclk0_freq_chg) { + if (atomic_read(&pdata->int_mclk0_enabled)) { + pdata->digital_cdc_core_clk.enable = 0; + afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + } + pdata->digital_cdc_core_clk.clk_freq_in_hz = + clk_freq_in_hz; + pdata->digital_cdc_core_clk.enable = 1; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + if (ret < 0) { + pr_err("%s: failed to enable CCLK\n", + __func__); + mutex_unlock( + &pdata->cdc_int_mclk0_mutex); + return ret; + } + pr_debug("enabled digital codec core clk\n"); + atomic_set(&pdata->int_mclk0_enabled, true); + } + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + } + atomic_inc(&pdata->int_mclk0_rsc_ref); + } else { + cancel_delayed_work_sync(&pdata->disable_int_mclk0_work); + mutex_lock(&pdata->cdc_int_mclk0_mutex); + if (atomic_read(&pdata->int_mclk0_enabled) == true) { + pdata->digital_cdc_core_clk.enable = 0; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + if (ret < 0) + pr_err("%s: failed to disable CCLK\n", + __func__); + atomic_set(&pdata->int_mclk0_enabled, false); + } + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + } + return ret; +} + +static int loopback_mclk_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s\n", __func__); + return 0; +} + +static int loopback_mclk_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = -EINVAL; + struct msm_asoc_mach_data *pdata = NULL; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + pdata = snd_soc_card_get_drvdata(codec->component.card); + pr_debug("%s: mclk_rsc_ref %d enable %ld\n", + __func__, atomic_read(&pdata->int_mclk0_rsc_ref), + ucontrol->value.integer.value[0]); + switch (ucontrol->value.integer.value[0]) { + case 1: + ret = msm_cdc_pinctrl_select_active_state(pdata->pdm_gpio_p); + if (ret) { + pr_err("%s: failed to enable the pri gpios: %d\n", + __func__, ret); + break; + } + mutex_lock(&pdata->cdc_int_mclk0_mutex); + if ((!atomic_read(&pdata->int_mclk0_rsc_ref)) && + (!atomic_read(&pdata->int_mclk0_enabled))) { + pdata->digital_cdc_core_clk.enable = 1; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + if (ret < 0) { + pr_err("%s: failed to enable the MCLK: %d\n", + __func__, ret); + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->pdm_gpio_p); + if (ret) + pr_err("%s: failed to disable the pri gpios: %d\n", + __func__, ret); + break; + } + atomic_set(&pdata->int_mclk0_enabled, true); + } + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + atomic_inc(&pdata->int_mclk0_rsc_ref); + msm_anlg_cdc_mclk_enable(codec, 1, true); + break; + case 0: + if (atomic_read(&pdata->int_mclk0_rsc_ref) <= 0) + break; + msm_anlg_cdc_mclk_enable(codec, 0, true); + mutex_lock(&pdata->cdc_int_mclk0_mutex); + if ((!atomic_dec_return(&pdata->int_mclk0_rsc_ref)) && + (atomic_read(&pdata->int_mclk0_enabled))) { + pdata->digital_cdc_core_clk.enable = 0; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + if (ret < 0) { + pr_err("%s: failed to disable the CCLK: %d\n", + __func__, ret); + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + break; + } + atomic_set(&pdata->int_mclk0_enabled, false); + } + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + ret = msm_cdc_pinctrl_select_sleep_state(pdata->pdm_gpio_p); + if (ret) + pr_err("%s: failed to disable the pri gpios: %d\n", + __func__, ret); + break; + default: + pr_err("%s: Unexpected input value\n", __func__); + break; + } + return ret; +} + +static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* + * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) + * when used for BT_SCO use case. Return either Rx or Tx sample rate + * value. + */ + switch (bt_fm_cfg[BT_SLIM7].sample_rate) { + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate = %d", __func__, + bt_fm_cfg[BT_SLIM7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 0: + default: + bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rates: slim7_rx = %d, value = %d\n", + __func__, + bt_fm_cfg[BT_SLIM7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("INT0_MI2S_RX Format", int0_mi2s_rx_format, + int_mi2s_bit_format_get, int_mi2s_bit_format_put), + SOC_ENUM_EXT("INT2_MI2S_TX Format", int2_mi2s_tx_format, + int_mi2s_bit_format_get, int_mi2s_bit_format_put), + SOC_ENUM_EXT("INT3_MI2S_TX Format", int3_mi2s_tx_format, + int_mi2s_bit_format_get, int_mi2s_bit_format_put), + SOC_ENUM_EXT("INT0_MI2S_RX SampleRate", int0_mi2s_rx_sample_rate, + int_mi2s_sample_rate_get, + int_mi2s_sample_rate_put), + SOC_ENUM_EXT("INT2_MI2S_TX SampleRate", int2_mi2s_tx_sample_rate, + int_mi2s_sample_rate_get, + int_mi2s_sample_rate_put), + SOC_ENUM_EXT("INT3_MI2S_TX SampleRate", int3_mi2s_tx_sample_rate, + int_mi2s_sample_rate_get, + int_mi2s_sample_rate_put), + SOC_ENUM_EXT("INT0_MI2S_RX Channels", int0_mi2s_rx_chs, + int_mi2s_ch_get, int_mi2s_ch_put), + SOC_ENUM_EXT("INT2_MI2S_TX Channels", int2_mi2s_tx_chs, + int_mi2s_ch_get, int_mi2s_ch_put), + SOC_ENUM_EXT("INT3_MI2S_TX Channels", int3_mi2s_tx_chs, + int_mi2s_ch_get, int_mi2s_ch_put), + SOC_ENUM_EXT("Loopback MCLK", loopback_mclk_en, + loopback_mclk_get, loopback_mclk_put), + SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), +}; + +static const struct snd_kcontrol_new msm_sdw_controls[] = { + SOC_ENUM_EXT("INT4_MI2S_RX Format", int4_mi2s_rx_format, + int_mi2s_bit_format_get, int_mi2s_bit_format_put), + SOC_ENUM_EXT("INT4_MI2S_RX SampleRate", int4_mi2s_rx_sample_rate, + int_mi2s_sample_rate_get, + int_mi2s_sample_rate_put), + SOC_ENUM_EXT("INT4_MI2S_RX Channels", int4_mi2s_rx_chs, + int_mi2s_ch_get, int_mi2s_ch_put), + SOC_ENUM_EXT("VI_FEED_TX Channels", int5_mi2s_tx_chs, + msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), +}; + +static int msm_dmic_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct msm_asoc_mach_data *pdata = NULL; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int ret = 0; + + pdata = snd_soc_card_get_drvdata(codec->component.card); + pr_debug("%s: event = %d\n", __func__, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = msm_cdc_pinctrl_select_active_state(pdata->dmic_gpio_p); + if (ret < 0) { + pr_err("%s: gpio set cannot be activated %sd", + __func__, "dmic_gpio"); + return ret; + } + break; + case SND_SOC_DAPM_POST_PMD: + ret = msm_cdc_pinctrl_select_sleep_state(pdata->dmic_gpio_p); + if (ret < 0) { + pr_err("%s: gpio set cannot be de-activated %sd", + __func__, "dmic_gpio"); + return ret; + } + break; + default: + pr_err("%s: invalid DAPM event %d\n", __func__, event); + return -EINVAL; + } + return 0; +} + +static int msm_int_mclk0_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct msm_asoc_mach_data *pdata = NULL; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int ret = 0; + + pdata = snd_soc_card_get_drvdata(codec->component.card); + pr_debug("%s: event = %d\n", __func__, event); + switch (event) { + case SND_SOC_DAPM_POST_PMD: + pr_debug("%s: mclk_res_ref = %d\n", + __func__, atomic_read(&pdata->int_mclk0_rsc_ref)); + ret = msm_cdc_pinctrl_select_sleep_state(pdata->pdm_gpio_p); + if (ret < 0) { + pr_err("%s: gpio set cannot be de-activated %sd", + __func__, "int_pdm"); + return ret; + } + if (atomic_read(&pdata->int_mclk0_rsc_ref) == 0) { + pr_debug("%s: disabling MCLK\n", __func__); + /* disable the codec mclk config*/ + msm_anlg_cdc_mclk_enable(codec, 0, true); + msm_int_enable_dig_cdc_clk(codec, 0, true); + } + break; + default: + pr_err("%s: invalid DAPM event %d\n", __func__, event); + return -EINVAL; + } + return 0; +} + +static int int_mi2s_get_port_id(int be_id) +{ + int afe_port_id; + + switch (be_id) { + case MSM_BACKEND_DAI_INT0_MI2S_RX: + afe_port_id = AFE_PORT_ID_INT0_MI2S_RX; + break; + case MSM_BACKEND_DAI_INT2_MI2S_TX: + afe_port_id = AFE_PORT_ID_INT2_MI2S_TX; + break; + case MSM_BACKEND_DAI_INT3_MI2S_TX: + afe_port_id = AFE_PORT_ID_INT3_MI2S_TX; + break; + case MSM_BACKEND_DAI_INT4_MI2S_RX: + afe_port_id = AFE_PORT_ID_INT4_MI2S_RX; + break; + case MSM_BACKEND_DAI_INT5_MI2S_TX: + afe_port_id = AFE_PORT_ID_INT5_MI2S_TX; + break; + default: + pr_err("%s: Invalid be_id: %d\n", __func__, be_id); + afe_port_id = -EINVAL; + } + + return afe_port_id; +} + +static int int_mi2s_get_index(int port_id) +{ + int index; + + switch (port_id) { + case AFE_PORT_ID_INT0_MI2S_RX: + index = INT0_MI2S; + break; + case AFE_PORT_ID_INT2_MI2S_TX: + index = INT2_MI2S; + break; + case AFE_PORT_ID_INT3_MI2S_TX: + index = INT3_MI2S; + break; + case AFE_PORT_ID_INT4_MI2S_RX: + index = INT4_MI2S; + break; + case AFE_PORT_ID_INT5_MI2S_TX: + index = INT5_MI2S; + break; + default: + pr_err("%s: Invalid port_id: %d\n", __func__, port_id); + index = -EINVAL; + } + + return index; +} + +static u32 get_int_mi2s_bits_per_sample(u32 bit_format) +{ + u32 bit_per_sample; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S24_3LE: + case SNDRV_PCM_FORMAT_S24_LE: + bit_per_sample = 32; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bit_per_sample = 16; + break; + } + + return bit_per_sample; +} + +static void update_int_mi2s_clk_val(int idx, int stream) +{ + u32 bit_per_sample; + + bit_per_sample = + get_int_mi2s_bits_per_sample(int_mi2s_cfg[idx].bit_format); + int_mi2s_clk[idx].clk_freq_in_hz = + (int_mi2s_cfg[idx].sample_rate * 2 * bit_per_sample); +} + +static int int_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int port_id = 0; + int index; + + port_id = int_mi2s_get_port_id(rtd->dai_link->be_id); + if (port_id < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto done; + } + index = int_mi2s_get_index(port_id); + if (index < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto done; + } + if (enable) { + update_int_mi2s_clk_val(index, substream->stream); + dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, + int_mi2s_clk[index].clk_freq_in_hz); + } + + int_mi2s_clk[index].enable = enable; + ret = afe_set_lpass_clock_v2(port_id, + &int_mi2s_clk[index]); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed for port 0x%x , err:%d\n", + __func__, port_id, ret); + goto done; + } + +done: + return ret; +} + +static int msm_sdw_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + ret = int_mi2s_set_sclk(substream, true); + if (ret < 0) { + pr_err("%s: failed to enable sclk %d\n", + __func__, ret); + return ret; + } + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + pr_err("%s: set fmt cpu dai failed; ret=%d\n", __func__, ret); + + return ret; +} + +static void msm_sdw_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + ret = int_mi2s_set_sclk(substream, false); + if (ret < 0) + pr_err("%s:clock disable failed; ret=%d\n", __func__, + ret); +} + +static int msm_int_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_codec *codec = rtd->codec_dais[ANA_CDC]->codec; + int ret = 0; + struct msm_asoc_mach_data *pdata = NULL; + + pdata = snd_soc_card_get_drvdata(codec->component.card); + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + ret = int_mi2s_set_sclk(substream, true); + if (ret < 0) { + pr_err("%s: failed to enable sclk %d\n", + __func__, ret); + return ret; + } + ret = msm_int_enable_dig_cdc_clk(codec, 1, true); + if (ret < 0) { + pr_err("failed to enable mclk\n"); + return ret; + } + /* Enable the codec mclk config */ + ret = msm_cdc_pinctrl_select_active_state(pdata->pdm_gpio_p); + if (ret < 0) { + pr_err("%s: gpio set cannot be activated %s\n", + __func__, "int_pdm"); + return ret; + } + msm_anlg_cdc_mclk_enable(codec, 1, true); + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + pr_err("%s: set fmt cpu dai failed; ret=%d\n", __func__, ret); + + return ret; +} + +static void msm_int_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + ret = int_mi2s_set_sclk(substream, false); + if (ret < 0) + pr_err("%s:clock disable failed; ret=%d\n", __func__, + ret); + if (atomic_read(&pdata->int_mclk0_rsc_ref) > 0) { + atomic_dec(&pdata->int_mclk0_rsc_ref); + pr_debug("%s: decrementing mclk_res_ref %d\n", + __func__, + atomic_read(&pdata->int_mclk0_rsc_ref)); + } +} + +static void *def_msm_int_wcd_mbhc_cal(void) +{ + void *msm_int_wcd_cal; + struct wcd_mbhc_btn_detect_cfg *btn_cfg; + u16 *btn_low, *btn_high; + + msm_int_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, + WCD_MBHC_DEF_RLOADS), GFP_KERNEL); + if (!msm_int_wcd_cal) + return NULL; + +#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(msm_int_wcd_cal)->X) = (Y)) + S(v_hs_max, 1500); +#undef S +#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(msm_int_wcd_cal)->X) = (Y)) + S(num_btn, WCD_MBHC_DEF_BUTTONS); +#undef S + + + btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(msm_int_wcd_cal); + btn_low = btn_cfg->_v_btn_low; + btn_high = ((void *)&btn_cfg->_v_btn_low) + + (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); + + /* + * In SW we are maintaining two sets of threshold register + * one for current source and another for Micbias. + * all btn_low corresponds to threshold for current source + * all bt_high corresponds to threshold for Micbias + * Below thresholds are based on following resistances + * 0-70 == Button 0 + * 110-180 == Button 1 + * 210-290 == Button 2 + * 360-680 == Button 3 + */ + btn_low[0] = 75; + btn_high[0] = 75; + btn_low[1] = 150; + btn_high[1] = 150; + btn_low[2] = 225; + btn_high[2] = 225; + btn_low[3] = 450; + btn_high[3] = 450; + btn_low[4] = 500; + btn_high[4] = 500; + + return msm_int_wcd_cal; +} + +static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *dig_cdc = rtd->codec_dais[DIG_CDC]->codec; + struct snd_soc_codec *ana_cdc = rtd->codec_dais[ANA_CDC]->codec; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(ana_cdc); + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); + struct snd_card *card; + int ret = -ENOMEM; + + pr_debug("%s(),dev_name%s\n", __func__, dev_name(cpu_dai->dev)); + + ret = snd_soc_add_codec_controls(ana_cdc, msm_snd_controls, + ARRAY_SIZE(msm_snd_controls)); + if (ret < 0) { + pr_err("%s: add_codec_controls failed: %d\n", + __func__, ret); + return ret; + } + ret = snd_soc_add_codec_controls(ana_cdc, msm_common_snd_controls, + msm_common_snd_controls_size()); + if (ret < 0) { + pr_err("%s: add common snd controls failed: %d\n", + __func__, ret); + return ret; + } + + snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets, + ARRAY_SIZE(msm_int_dapm_widgets)); + + snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Secondary Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); + + snd_soc_dapm_ignore_suspend(dapm, "EAR"); + snd_soc_dapm_ignore_suspend(dapm, "HEADPHONE"); + snd_soc_dapm_ignore_suspend(dapm, "SPK_OUT"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC4"); + + snd_soc_dapm_sync(dapm); + + msm_anlg_cdc_spk_ext_pa_cb(enable_spk_ext_pa, ana_cdc); + msm_dig_cdc_hph_comp_cb(msm_config_hph_compander_gpio, dig_cdc); + + card = rtd->card->snd_card; + if (!codec_root) + codec_root = snd_register_module_info(card->module, "codecs", + card->proc_root); + if (!codec_root) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + goto done; + } + pdata->codec_root = codec_root; + msm_dig_codec_info_create_codec_entry(codec_root, dig_cdc); + msm_anlg_codec_info_create_codec_entry(codec_root, ana_cdc); +done: + return 0; +} + +static int msm_sdw_audrx_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = + snd_soc_codec_get_dapm(codec); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_pcm_runtime *rtd_aux = rtd->card->rtd_aux; + struct snd_card *card; + + snd_soc_add_codec_controls(codec, msm_sdw_controls, + ARRAY_SIZE(msm_sdw_controls)); + + snd_soc_dapm_ignore_suspend(dapm, "AIF1_SDW Playback"); + snd_soc_dapm_ignore_suspend(dapm, "VIfeed_SDW"); + snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "AIF1_SDW VI"); + snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_SDW"); + + snd_soc_dapm_sync(dapm); + + /* + * Send speaker configuration only for WSA8810. + * Default configuration is for WSA8815. + */ + if (rtd_aux && rtd_aux->component) + if (!strcmp(rtd_aux->component->name, WSA8810_NAME_1) || + !strcmp(rtd_aux->component->name, WSA8810_NAME_2)) { + msm_sdw_set_spkr_mode(rtd->codec, SPKR_MODE_1); + msm_sdw_set_spkr_gain_offset(rtd->codec, + RX_GAIN_OFFSET_M1P5_DB); + } + card = rtd->card->snd_card; + if (!codec_root) + codec_root = snd_register_module_info(card->module, "codecs", + card->proc_root); + if (!codec_root) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + goto done; + } + pdata->codec_root = codec_root; + msm_sdw_codec_info_create_codec_entry(codec_root, codec); +done: + return 0; +} + +static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) +{ + unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; + unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); +} + +static int msm_wcn_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + int ret; + + dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret) { + dev_err(rtd->dev, + "%s: failed to get BTFM codec chan map\n, err:%d\n", + __func__, ret); + goto exit; + } + + dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) be_id %d\n", + __func__, tx_ch_cnt, dai_link->be_id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); + if (ret) + dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + +exit: + return ret; +} + +static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width, + int slots) +{ + unsigned int slot_mask = 0; + int i, j; + unsigned int *slot_offset; + + for (i = TDM_0; i < TDM_PORT_MAX; i++) { + slot_offset = tdm_slot_offset[i]; + + for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) { + if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID) + slot_mask |= + (1 << ((slot_offset[j] * 8) / slot_width)); + else + break; + } + } + + return slot_mask; +} + +static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + int channels, slot_width, slots; + unsigned int slot_mask; + unsigned int *slot_offset; + int offset_channels = 0; + int i; + + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + + channels = params_channels(params); + switch (channels) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S16_LE: + /* + * up to 8 channels HW config should + * use 32 bit slot width for max support of + * stream bit width. (slot_width > bit_width) + */ + slot_width = 32; + break; + default: + pr_err("%s: invalid param format 0x%x\n", + __func__, params_format(params)); + return -EINVAL; + } + slots = 8; + slot_mask = tdm_param_set_slot_mask(cpu_dai->id, + slot_width, + slots); + if (!slot_mask) { + pr_err("%s: invalid slot_mask 0x%x\n", + __func__, slot_mask); + return -EINVAL; + } + break; + default: + pr_err("%s: invalid param channels %d\n", + __func__, channels); + return -EINVAL; + } + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + slot_offset = tdm_slot_offset[TDM_0]; + break; + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) + offset_channels++; + else + break; + } + + if (offset_channels == 0) { + pr_err("%s: slot offset not supported, offset_channels %d\n", + __func__, offset_channels); + return -EINVAL; + } + + if (channels > offset_channels) { + pr_err("%s: channels %d exceed offset_channels %d\n", + __func__, channels, offset_channels); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, + channels, slot_offset); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } else { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, channels, + slot_offset, 0, NULL); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } +end: + return ret; +} + +static int msm_snd_card_late_probe(struct snd_soc_card *card) +{ + const char *be_dl_name = LPASS_BE_INT0_MI2S_RX; + struct snd_soc_codec *ana_cdc; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + return -EINVAL; + } + + ana_cdc = rtd->codec_dais[ANA_CDC]->codec; + mbhc_cfg_ptr->calibration = def_msm_int_wcd_mbhc_cal(); + if (!mbhc_cfg_ptr->calibration) + return -ENOMEM; + + ret = msm_anlg_cdc_hs_detect(ana_cdc, mbhc_cfg_ptr); + if (ret) { + dev_err(card->dev, + "%s: msm_anlg_cdc_hs_detect failed\n", __func__); + kfree(mbhc_cfg_ptr->calibration); + } + + return ret; +} + +static struct snd_soc_ops msm_tdm_be_ops = { + .hw_params = msm_tdm_snd_hw_params +}; + +static struct snd_soc_ops msm_wcn_ops = { + .hw_params = msm_wcn_hw_params, +}; + +static struct snd_soc_ops msm_mi2s_be_ops = { + .startup = msm_mi2s_snd_startup, + .shutdown = msm_mi2s_snd_shutdown, +}; + +static struct snd_soc_ops msm_aux_pcm_be_ops = { + .startup = msm_aux_pcm_snd_startup, + .shutdown = msm_aux_pcm_snd_shutdown, +}; + +static struct snd_soc_ops msm_int_mi2s_be_ops = { + .startup = msm_int_mi2s_snd_startup, + .shutdown = msm_int_mi2s_snd_shutdown, +}; + +static struct snd_soc_ops msm_sdw_mi2s_be_ops = { + .startup = msm_sdw_mi2s_snd_startup, + .shutdown = msm_sdw_mi2s_snd_shutdown, +}; + +struct snd_soc_dai_link_component dlc_rx1[] = { + { + .of_node = NULL, + .dai_name = "msm_dig_cdc_dai_rx1", + }, + { + .of_node = NULL, + .dai_name = "msm_anlg_cdc_i2s_rx1", + }, +}; + +struct snd_soc_dai_link_component dlc_tx1[] = { + { + .of_node = NULL, + .dai_name = "msm_dig_cdc_dai_tx1", + }, + { + .of_node = NULL, + .dai_name = "msm_anlg_cdc_i2s_tx1", + }, +}; + +struct snd_soc_dai_link_component dlc_tx2[] = { + { + .of_node = NULL, + .dai_name = "msm_dig_cdc_dai_tx2", + }, + { + .of_node = NULL, + .dai_name = "msm_anlg_cdc_i2s_tx2", + }, +}; + +/* Digital audio interface glue - connects codec <---> CPU */ +static struct snd_soc_dai_link msm_int_dai[] = { + /* FrontEnd DAI Links */ + {/* hw:x,0 */ + .name = MSM_DAILINK_NAME(Media1), + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, + {/* hw:x,1 */ + .name = MSM_DAILINK_NAME(Media2), + .stream_name = "MultiMedia2", + .cpu_dai_name = "MultiMedia2", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA2, + }, + {/* hw:x,2 */ + .name = "VoiceMMode1", + .stream_name = "VoiceMMode1", + .cpu_dai_name = "VoiceMMode1", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_VOICEMMODE1, + }, + {/* hw:x,3 */ + .name = "MSM VoIP", + .stream_name = "VoIP", + .cpu_dai_name = "VoIP", + .platform_name = "msm-voip-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .be_id = MSM_FRONTEND_DAI_VOIP, + }, + {/* hw:x,4 */ + .name = MSM_DAILINK_NAME(ULL), + .stream_name = "ULL", + .cpu_dai_name = "MultiMedia3", + .platform_name = "msm-pcm-dsp.2", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA3, + }, + /* Hostless PCM purpose */ + {/* hw:x,5 */ + .name = "INT4 MI2S_RX Hostless", + .stream_name = "INT4 MI2S_RX Hostless", + .cpu_dai_name = "INT4_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + /* This dainlink has MI2S support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,6 */ + .name = "MSM AFE-PCM RX", + .stream_name = "AFE-PROXY RX", + .cpu_dai_name = "msm-dai-q6-dev.241", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .platform_name = "msm-pcm-afe", + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + }, + {/* hw:x,7 */ + .name = "MSM AFE-PCM TX", + .stream_name = "AFE-PROXY TX", + .cpu_dai_name = "msm-dai-q6-dev.240", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .platform_name = "msm-pcm-afe", + .ignore_suspend = 1, + }, + {/* hw:x,8 */ + .name = MSM_DAILINK_NAME(Compress1), + .stream_name = "Compress1", + .cpu_dai_name = "MultiMedia4", + .platform_name = "msm-compress-dsp", + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA4, + }, + {/* hw:x,9*/ + .name = "AUXPCM Hostless", + .stream_name = "AUXPCM Hostless", + .cpu_dai_name = "AUXPCM_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,10 */ + .name = "SLIMBUS_1 Hostless", + .stream_name = "SLIMBUS_1 Hostless", + .cpu_dai_name = "SLIMBUS1_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, /* dai link has playback support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,11 */ + .name = "INT3 MI2S_TX Hostless", + .stream_name = "INT3 MI2S_TX Hostless", + .cpu_dai_name = "INT3_MI2S_TX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,12 */ + .name = "SLIMBUS_7 Hostless", + .stream_name = "SLIMBUS_7 Hostless", + .cpu_dai_name = "SLIMBUS7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, /* dai link has playback support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,13 */ + .name = MSM_DAILINK_NAME(LowLatency), + .stream_name = "MultiMedia5", + .cpu_dai_name = "MultiMedia5", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA5, + }, + /* LSM FE */ + {/* hw:x,14 */ + .name = "Listen 1 Audio Service", + .stream_name = "Listen 1 Audio Service", + .cpu_dai_name = "LSM1", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_LSM1, + }, + {/* hw:x,15 */ + .name = MSM_DAILINK_NAME(Compress2), + .stream_name = "Compress2", + .cpu_dai_name = "MultiMedia7", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA7, + }, + {/* hw:x,16 */ + .name = MSM_DAILINK_NAME(Compress3), + .stream_name = "Compress3", + .cpu_dai_name = "MultiMedia10", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA10, + }, + {/* hw:x,17 */ + .name = MSM_DAILINK_NAME(ULL_NOIRQ), + .stream_name = "MM_NOIRQ", + .cpu_dai_name = "MultiMedia8", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA8, + }, + {/* hw:x,18 */ + .name = "HDMI_RX_HOSTLESS", + .stream_name = "HDMI_RX_HOSTLESS", + .cpu_dai_name = "HDMI_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,19 */ + .name = "VoiceMMode2", + .stream_name = "VoiceMMode2", + .cpu_dai_name = "VoiceMMode2", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_VOICEMMODE2, + }, + {/* hw:x,20 */ + .name = "Listen 2 Audio Service", + .stream_name = "Listen 2 Audio Service", + .cpu_dai_name = "LSM2", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_LSM2, + }, + {/* hw:x,21 */ + .name = "Listen 3 Audio Service", + .stream_name = "Listen 3 Audio Service", + .cpu_dai_name = "LSM3", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_LSM3, + }, + {/* hw:x,22 */ + .name = "Listen 4 Audio Service", + .stream_name = "Listen 4 Audio Service", + .cpu_dai_name = "LSM4", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_LSM4, + }, + {/* hw:x,23 */ + .name = "Listen 5 Audio Service", + .stream_name = "Listen 5 Audio Service", + .cpu_dai_name = "LSM5", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_LSM5, + }, + {/* hw:x,24 */ + .name = "Listen 6 Audio Service", + .stream_name = "Listen 6 Audio Service", + .cpu_dai_name = "LSM6", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_LSM6 + }, + {/* hw:x,25 */ + .name = "Listen 7 Audio Service", + .stream_name = "Listen 7 Audio Service", + .cpu_dai_name = "LSM7", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_LSM7, + }, + {/* hw:x,26 */ + .name = "Listen 8 Audio Service", + .stream_name = "Listen 8 Audio Service", + .cpu_dai_name = "LSM8", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .be_id = MSM_FRONTEND_DAI_LSM8, + }, + {/* hw:x,27 */ + .name = MSM_DAILINK_NAME(Media9), + .stream_name = "MultiMedia9", + .cpu_dai_name = "MultiMedia9", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA9, + }, + {/* hw:x,28 */ + .name = MSM_DAILINK_NAME(Compress4), + .stream_name = "Compress4", + .cpu_dai_name = "MultiMedia11", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA11, + }, + {/* hw:x,29 */ + .name = MSM_DAILINK_NAME(Compress5), + .stream_name = "Compress5", + .cpu_dai_name = "MultiMedia12", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA12, + }, + {/* hw:x,30 */ + .name = MSM_DAILINK_NAME(Compress6), + .stream_name = "Compress6", + .cpu_dai_name = "MultiMedia13", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA13, + }, + {/* hw:x,31 */ + .name = MSM_DAILINK_NAME(Compress7), + .stream_name = "Compress7", + .cpu_dai_name = "MultiMedia14", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA14, + }, + {/* hw:x,32 */ + .name = MSM_DAILINK_NAME(Compress8), + .stream_name = "Compress8", + .cpu_dai_name = "MultiMedia15", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA15, + }, + {/* hw:x,33 */ + .name = MSM_DAILINK_NAME(Compress9), + .stream_name = "Compress9", + .cpu_dai_name = "MultiMedia16", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA16, + }, + {/* hw:x,34 */ + .name = "SLIMBUS_8 Hostless", + .stream_name = "SLIMBUS8_HOSTLESS Capture", + .cpu_dai_name = "SLIMBUS8_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,35 */ + .name = "Primary MI2S_RX Hostless", + .stream_name = "Primary MI2S_RX Hostless", + .cpu_dai_name = "PRI_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + /* This dainlink has MI2S support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,36 */ + .name = "Secondary MI2S_RX Hostless", + .stream_name = "Secondary MI2S_RX Hostless", + .cpu_dai_name = "SEC_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + /* This dainlink has MI2S support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,37 */ + .name = "Tertiary MI2S_RX Hostless", + .stream_name = "Tertiary MI2S_RX Hostless", + .cpu_dai_name = "TERT_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + /* This dainlink has MI2S support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,38 */ + .name = "INT0 MI2S_RX Hostless", + .stream_name = "INT0 MI2S_RX Hostless", + .cpu_dai_name = "INT0_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + /* This dainlink has MI2S support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,39 */ + .name = "SDM660 HFP TX", + .stream_name = "MultiMedia6", + .cpu_dai_name = "MultiMedia6", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .be_id = MSM_FRONTEND_DAI_MULTIMEDIA6, + }, +}; + + +static struct snd_soc_dai_link msm_int_wsa_dai[] = { + {/* hw:x,40 */ + .name = LPASS_BE_INT5_MI2S_TX, + .stream_name = "INT5_mi2s Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.12", + .platform_name = "msm-pcm-hostless", + .codec_name = "msm_sdw_codec", + .codec_dai_name = "msm_sdw_vifeedback", + .be_id = MSM_BACKEND_DAI_INT5_MI2S_TX, + .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, + .ops = &msm_sdw_mi2s_be_ops, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .dpcm_capture = 1, + .ignore_pmdown_time = 1, + }, +}; + +static struct snd_soc_dai_link msm_int_be_dai[] = { + /* Backend I2S DAI Links */ + { + .name = LPASS_BE_INT0_MI2S_RX, + .stream_name = "INT0 MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.7", + .platform_name = "msm-pcm-routing", + .codecs = dlc_rx1, + .num_codecs = CODECS_MAX, + .no_pcm = 1, + .dpcm_playback = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE | + ASYNC_DPCM_SND_SOC_HW_PARAMS, + .be_id = MSM_BACKEND_DAI_INT0_MI2S_RX, + .init = &msm_audrx_init, + .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, + .ops = &msm_int_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_INT3_MI2S_TX, + .stream_name = "INT3 MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.10", + .platform_name = "msm-pcm-routing", + .codecs = dlc_tx1, + .num_codecs = CODECS_MAX, + .no_pcm = 1, + .dpcm_capture = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE | + ASYNC_DPCM_SND_SOC_HW_PARAMS, + .be_id = MSM_BACKEND_DAI_INT3_MI2S_TX, + .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, + .ops = &msm_int_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_INT2_MI2S_TX, + .stream_name = "INT2 MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.9", + .platform_name = "msm-pcm-routing", + .codecs = dlc_tx2, + .num_codecs = CODECS_MAX, + .no_pcm = 1, + .dpcm_capture = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE | + ASYNC_DPCM_SND_SOC_HW_PARAMS, + .be_id = MSM_BACKEND_DAI_INT2_MI2S_TX, + .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, + .ops = &msm_int_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AFE_PCM_RX, + .stream_name = "AFE Playback", + .cpu_dai_name = "msm-dai-q6-dev.224", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_AFE_PCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AFE_PCM_TX, + .stream_name = "AFE Capture", + .cpu_dai_name = "msm-dai-q6-dev.225", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_AFE_PCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Uplink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_TX, + .stream_name = "Voice Uplink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32772", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_INCALL_RECORD_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Downlink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_RX, + .stream_name = "Voice Downlink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32771", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_INCALL_RECORD_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music BACK END DAI Link */ + { + .name = LPASS_BE_VOICE_PLAYBACK_TX, + .stream_name = "Voice Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32773", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music 2 BACK END DAI Link */ + { + .name = LPASS_BE_VOICE2_PLAYBACK_TX, + .stream_name = "Voice2 Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32770", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_RX, + .stream_name = "USB Audio Playback", + .cpu_dai_name = "msm-dai-q6-dev.28672", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_USB_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_TX, + .stream_name = "USB Audio Capture", + .cpu_dai_name = "msm-dai-q6-dev.28673", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_USB_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_0, + .stream_name = "Primary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36864", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_0, + .stream_name = "Primary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36865", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_0, + .stream_name = "Secondary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36880", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_0, + .stream_name = "Secondary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36881", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_0, + .stream_name = "Tertiary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36896", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_0, + .stream_name = "Tertiary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36897", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_0, + .stream_name = "Quaternary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36912", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_0, + .stream_name = "Quaternary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36913", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { + { + .name = LPASS_BE_PRI_MI2S_RX, + .stream_name = "Primary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_PRI_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_MI2S_TX, + .stream_name = "Primary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_PRI_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX, + .stream_name = "Secondary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX, + .stream_name = "Secondary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX, + .stream_name = "Tertiary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX, + .stream_name = "Tertiary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX, + .stream_name = "Quaternary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { + /* Primary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_AUXPCM_RX, + .stream_name = "AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_AUXPCM_TX, + .stream_name = "AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Secondary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_SEC_AUXPCM_RX, + .stream_name = "Sec AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_SEC_AUXPCM_TX, + .stream_name = "Sec AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Tertiary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_TERT_AUXPCM_RX, + .stream_name = "Tert AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_TERT_AUXPCM_TX, + .stream_name = "Tert AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Quaternary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUAT_AUXPCM_RX, + .stream_name = "Quat AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_QUAT_AUXPCM_TX, + .stream_name = "Quat AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .ops = &msm_aux_pcm_be_ops, + }, +}; + + +static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_7_RX, + .stream_name = "Slimbus7 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16398", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + /* BT codec driver determines capabilities based on + * dai name, bt codecdai name should always contains + * supported usecase information + */ + .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_7_RX, + .be_hw_params_fixup = msm_btfm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_7_TX, + .stream_name = "Slimbus7 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16399", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_bt_sco_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_7_TX, + .be_hw_params_fixup = msm_btfm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_8_TX, + .stream_name = "Slimbus8 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16401", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_fm_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_8_TX, + .be_hw_params_fixup = msm_btfm_be_hw_params_fixup, + .init = &msm_wcn_init, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_wsa_be_dai_links[] = { + { + .name = LPASS_BE_INT4_MI2S_RX, + .stream_name = "INT4 MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.11", + .platform_name = "msm-pcm-routing", + .codec_name = "msm_sdw_codec", + .codec_dai_name = "msm_sdw_i2s_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_INT4_MI2S_RX, + .init = &msm_sdw_audrx_init, + .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, + .ops = &msm_sdw_mi2s_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link ext_disp_be_dai_link[] = { + /* DISP PORT BACK END DAI Link */ + { + .name = LPASS_BE_DISPLAY_PORT, + .stream_name = "Display Port Playback", + .cpu_dai_name = "msm-dai-q6-dp.24608", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-ext-disp-audio-codec-rx", + .codec_dai_name = "msm_dp_audio_codec_rx_dai", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_int_dai_links[ +ARRAY_SIZE(msm_int_dai) + +ARRAY_SIZE(msm_int_wsa_dai) + +ARRAY_SIZE(msm_int_be_dai) + +ARRAY_SIZE(msm_mi2s_be_dai_links) + +ARRAY_SIZE(msm_auxpcm_be_dai_links)+ +ARRAY_SIZE(msm_wcn_be_dai_links) + +ARRAY_SIZE(msm_wsa_be_dai_links) + +ARRAY_SIZE(ext_disp_be_dai_link)]; + +static struct snd_soc_card sdm660_card = { + /* snd_soc_card_sdm660 */ + .name = "sdm660-snd-card", + .dai_link = msm_int_dai, + .num_links = ARRAY_SIZE(msm_int_dai), + .late_probe = msm_snd_card_late_probe, +}; + +static void msm_disable_int_mclk0(struct work_struct *work) +{ + struct msm_asoc_mach_data *pdata = NULL; + struct delayed_work *dwork; + int ret = 0; + + dwork = to_delayed_work(work); + pdata = container_of(dwork, struct msm_asoc_mach_data, + disable_int_mclk0_work); + mutex_lock(&pdata->cdc_int_mclk0_mutex); + pr_debug("%s: mclk_enabled %d mclk_rsc_ref %d\n", __func__, + atomic_read(&pdata->int_mclk0_enabled), + atomic_read(&pdata->int_mclk0_rsc_ref)); + + if (atomic_read(&pdata->int_mclk0_enabled) == true + && atomic_read(&pdata->int_mclk0_rsc_ref) == 0) { + pr_debug("Disable the mclk\n"); + pdata->digital_cdc_core_clk.enable = 0; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + if (ret < 0) + pr_err("%s failed to disable the CCLK\n", __func__); + atomic_set(&pdata->int_mclk0_enabled, false); + } + mutex_unlock(&pdata->cdc_int_mclk0_mutex); +} + +static void msm_int_dt_parse_cap_info(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata) +{ + const char *ext1_cap = "qcom,msm-micbias1-ext-cap"; + const char *ext2_cap = "qcom,msm-micbias2-ext-cap"; + + pdata->micbias1_cap_mode = + (of_property_read_bool(pdev->dev.of_node, ext1_cap) ? + MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); + + pdata->micbias2_cap_mode = + (of_property_read_bool(pdev->dev.of_node, ext2_cap) ? + MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); +} + +static struct snd_soc_card *msm_int_populate_sndcard_dailinks( + struct device *dev) +{ + struct snd_soc_card *card = &sdm660_card; + struct snd_soc_dai_link *dailink; + int len1; + + card->name = dev_name(dev); + len1 = ARRAY_SIZE(msm_int_dai); + memcpy(msm_int_dai_links, msm_int_dai, sizeof(msm_int_dai)); + dailink = msm_int_dai_links; + if (!of_property_read_bool(dev->of_node, + "qcom,wsa-disable")) { + memcpy(dailink + len1, + msm_int_wsa_dai, + sizeof(msm_int_wsa_dai)); + len1 += ARRAY_SIZE(msm_int_wsa_dai); + } + memcpy(dailink + len1, msm_int_be_dai, sizeof(msm_int_be_dai)); + len1 += ARRAY_SIZE(msm_int_be_dai); + + if (of_property_read_bool(dev->of_node, + "qcom,mi2s-audio-intf")) { + memcpy(dailink + len1, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + len1 += ARRAY_SIZE(msm_mi2s_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,auxpcm-audio-intf")) { + memcpy(dailink + len1, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + len1 += ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + dev_dbg(dev, "%s(): WCN BTFM support present\n", + __func__); + memcpy(dailink + len1, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + len1 += ARRAY_SIZE(msm_wcn_be_dai_links); + } + if (!of_property_read_bool(dev->of_node, "qcom,wsa-disable")) { + memcpy(dailink + len1, + msm_wsa_be_dai_links, + sizeof(msm_wsa_be_dai_links)); + len1 += ARRAY_SIZE(msm_wsa_be_dai_links); + } + if (of_property_read_bool(dev->of_node, "qcom,ext-disp-audio-rx")) { + dev_dbg(dev, "%s(): ext disp audio support present\n", + __func__); + memcpy(dailink + len1, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + len1 += ARRAY_SIZE(ext_disp_be_dai_link); + } + card->dai_link = dailink; + card->num_links = len1; + return card; +} + +static int msm_internal_init(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata, + struct snd_soc_card *card) +{ + const char *type = NULL; + const char *hs_micbias_type = "qcom,msm-hs-micbias-type"; + int ret; + + ret = is_ext_spk_gpio_support(pdev, pdata); + if (ret < 0) + dev_dbg(&pdev->dev, + "%s: doesn't support external speaker pa\n", + __func__); + + ret = of_property_read_string(pdev->dev.of_node, + hs_micbias_type, &type); + if (ret) { + dev_err(&pdev->dev, "%s: missing %s in dt node\n", + __func__, hs_micbias_type); + goto err; + } + if (!strcmp(type, "external")) { + dev_dbg(&pdev->dev, "Headset is using external micbias\n"); + mbhc_cfg_ptr->hs_ext_micbias = true; + } else { + dev_dbg(&pdev->dev, "Headset is using internal micbias\n"); + mbhc_cfg_ptr->hs_ext_micbias = false; + } + + /* initialize the int_mclk0 */ + pdata->digital_cdc_core_clk.clk_set_minor_version = + AFE_API_VERSION_I2S_CONFIG; + pdata->digital_cdc_core_clk.clk_id = + Q6AFE_LPASS_CLK_ID_INT_MCLK_0; + pdata->digital_cdc_core_clk.clk_freq_in_hz = pdata->mclk_freq; + pdata->digital_cdc_core_clk.clk_attri = + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO; + pdata->digital_cdc_core_clk.clk_root = + Q6AFE_LPASS_CLK_ROOT_DEFAULT; + pdata->digital_cdc_core_clk.enable = 1; + + /* Initialize loopback mode to false */ + pdata->lb_mode = false; + + msm_int_dt_parse_cap_info(pdev, pdata); + + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, pdata); + ret = snd_soc_of_parse_card_name(card, "qcom,model"); + if (ret) + goto err; + /* initialize timer */ + INIT_DELAYED_WORK(&pdata->disable_int_mclk0_work, + msm_disable_int_mclk0); + mutex_init(&pdata->cdc_int_mclk0_mutex); + atomic_set(&pdata->int_mclk0_rsc_ref, 0); + atomic_set(&pdata->int_mclk0_enabled, false); + + dev_info(&pdev->dev, "%s: default codec configured\n", __func__); + + return 0; +err: + return ret; +} + +/** + * msm_int_cdc_init - internal codec machine specific init. + * + * @pdev: platform device handle + * @pdata: private data of machine driver + * @card: sound card pointer reference + * @mbhc_cfg: MBHC config reference + * + * Returns 0. + */ +int msm_int_cdc_init(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata, + struct snd_soc_card **card, + struct wcd_mbhc_config *mbhc_cfg) +{ + mbhc_cfg_ptr = mbhc_cfg; + + *card = msm_int_populate_sndcard_dailinks(&pdev->dev); + msm_internal_init(pdev, pdata, *card); + return 0; +} +EXPORT_SYMBOL(msm_int_cdc_init); diff --git a/sound/soc/msm/sdm660-internal.h b/sound/soc/msm/sdm660-internal.h new file mode 100644 index 000000000000..ccc62b8f33dc --- /dev/null +++ b/sound/soc/msm/sdm660-internal.h @@ -0,0 +1,32 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __SDM660_INTERNAL +#define __SDM660_INTERNAL + +#include + +#ifdef CONFIG_SND_SOC_INT_CODEC +int msm_int_cdc_init(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata, + struct snd_soc_card **card, + struct wcd_mbhc_config *mbhc_cfg); +#else +int msm_int_cdc_init(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata, + struct snd_soc_card **card, + struct wcd_mbhc_config *mbhc_cfg) +{ + return 0; +} +#endif +#endif diff --git a/sound/soc/msm/sdm845.c b/sound/soc/msm/sdm845.c new file mode 100644 index 000000000000..d3c4e05c65c8 --- /dev/null +++ b/sound/soc/msm/sdm845.c @@ -0,0 +1,6951 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qdsp6v2/msm-pcm-routing-v2.h" +#include "../codecs/wcd934x/wcd934x.h" +#include "../codecs/wcd934x/wcd934x-mbhc.h" +#include "../codecs/wsa881x.h" + +#define DRV_NAME "sdm845-asoc-snd" + +#define __CHIPSET__ "SDM845 " +#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) + +#define SAMPLING_RATE_8KHZ 8000 +#define SAMPLING_RATE_11P025KHZ 11025 +#define SAMPLING_RATE_16KHZ 16000 +#define SAMPLING_RATE_22P05KHZ 22050 +#define SAMPLING_RATE_32KHZ 32000 +#define SAMPLING_RATE_44P1KHZ 44100 +#define SAMPLING_RATE_48KHZ 48000 +#define SAMPLING_RATE_88P2KHZ 88200 +#define SAMPLING_RATE_96KHZ 96000 +#define SAMPLING_RATE_176P4KHZ 176400 +#define SAMPLING_RATE_192KHZ 192000 +#define SAMPLING_RATE_352P8KHZ 352800 +#define SAMPLING_RATE_384KHZ 384000 + +#define WCD9XXX_MBHC_DEF_BUTTONS 8 +#define WCD9XXX_MBHC_DEF_RLOADS 5 +#define CODEC_EXT_CLK_RATE 9600000 +#define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define DEV_NAME_STR_LEN 32 + +#define WSA8810_NAME_1 "wsa881x.20170211" +#define WSA8810_NAME_2 "wsa881x.20170212" + +#define WCN_CDC_SLIM_RX_CH_MAX 2 +#define WCN_CDC_SLIM_TX_CH_MAX 3 + +#define TDM_CHANNEL_MAX 8 +#define TDM_SLOT_OFFSET_MAX 8 + +#define MSM_HIFI_ON 1 + +enum { + SLIM_RX_0 = 0, + SLIM_RX_1, + SLIM_RX_2, + SLIM_RX_3, + SLIM_RX_4, + SLIM_RX_5, + SLIM_RX_6, + SLIM_RX_7, + SLIM_RX_MAX, +}; + +enum { + SLIM_TX_0 = 0, + SLIM_TX_1, + SLIM_TX_2, + SLIM_TX_3, + SLIM_TX_4, + SLIM_TX_5, + SLIM_TX_6, + SLIM_TX_7, + SLIM_TX_8, + SLIM_TX_MAX, +}; + +enum { + PRIM_MI2S = 0, + SEC_MI2S, + TERT_MI2S, + QUAT_MI2S, + MI2S_MAX, +}; + +enum { + PRIM_AUX_PCM = 0, + SEC_AUX_PCM, + TERT_AUX_PCM, + QUAT_AUX_PCM, + AUX_PCM_MAX, +}; + +enum { + PCM_I2S_SEL_PRIM = 0, + PCM_I2S_SEL_SEC, + PCM_I2S_SEL_TERT, + PCM_I2S_SEL_QUAT, + PCM_I2S_SEL_MAX, +}; + +struct mi2s_aux_pcm_common_conf { + struct mutex lock; + void *pcm_i2s_sel_vt_addr; +}; + +struct mi2s_conf { + struct mutex lock; + u32 ref_cnt; + u32 msm_is_mi2s_master; +}; + +struct auxpcm_conf { + struct mutex lock; + u32 ref_cnt; +}; + +struct dev_config { + u32 sample_rate; + u32 bit_format; + u32 channels; +}; + +enum { + DP_RX_IDX = 0, + EXT_DISP_RX_IDX_MAX, +}; + +struct msm_wsa881x_dev_info { + struct device_node *of_node; + u32 index; +}; + +enum pinctrl_pin_state { + STATE_DISABLE = 0, /* All pins are in sleep state */ + STATE_MI2S_ACTIVE, /* IS2 = active, TDM = sleep */ + STATE_TDM_ACTIVE, /* IS2 = sleep, TDM = active */ +}; + +struct msm_pinctrl_info { + struct pinctrl *pinctrl; + struct pinctrl_state *mi2s_disable; + struct pinctrl_state *tdm_disable; + struct pinctrl_state *mi2s_active; + struct pinctrl_state *tdm_active; + enum pinctrl_pin_state curr_state; +}; + +struct msm_asoc_mach_data { + u32 mclk_freq; + int us_euro_gpio; /* used by gpio driver API */ + int usbc_en2_gpio; /* used by gpio driver API */ + struct device_node *us_euro_gpio_p; /* used by pinctrl API */ + struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */ + struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ + struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ + struct snd_info_entry *codec_root; + struct msm_pinctrl_info pinctrl_info; +}; + +struct msm_asoc_wcd93xx_codec { + void* (*get_afe_config_fn)(struct snd_soc_codec *codec, + enum afe_config_type config_type); + void (*mbhc_hs_detect_exit)(struct snd_soc_codec *codec); +}; + +static const char *const pin_states[] = {"sleep", "i2s-active", + "tdm-active"}; + +enum { + TDM_0 = 0, + TDM_1, + TDM_2, + TDM_3, + TDM_4, + TDM_5, + TDM_6, + TDM_7, + TDM_PORT_MAX, +}; + +enum { + TDM_PRI = 0, + TDM_SEC, + TDM_TERT, + TDM_QUAT, + TDM_INTERFACE_MAX, +}; + +struct tdm_port { + u32 mode; + u32 channel; +}; + +/* TDM default config */ +static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + } +}; + +/* TDM default config */ +static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + } +}; + +/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */ +static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { + {0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */ +}; + +/* Default configuration of slimbus channels */ +static struct dev_config slim_rx_cfg[] = { + [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config slim_tx_cfg[] = { + [SLIM_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + + +/* Default configuration of external display BE */ +static struct dev_config ext_disp_rx_cfg[] = { + [DP_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config usb_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +static struct dev_config usb_tx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 1, +}; + +static struct dev_config proxy_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +/* Default configuration of MI2S channels */ +static struct dev_config mi2s_rx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config mi2s_tx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_rx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_tx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static int msm_vi_feed_tx_ch = 2; +static const char *const slim_rx_ch_text[] = {"One", "Two"}; +static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static const char *const vi_feed_ch_text[] = {"One", "Two"}; +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; +static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE"}; +static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_48"}; +static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *ch_text[] = {"Two", "Three", "Four", "Five", + "Six", "Seven", "Eight"}; +static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_32", "KHZ_44P1", + "KHZ_88P2", "KHZ_176P4" }; +static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", "Eight"}; +static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; +static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", + "KHZ_44P1", "KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; +static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_96", "KHZ_192"}; +static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static const char *const hifi_text[] = {"Off", "On"}; + +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_1_tx_chs, slim_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, + ext_disp_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(hifi_function, hifi_text); + +static struct platform_device *spdev; +static int msm_hifi_control; + +static bool is_initial_boot; +static bool codec_reg_done; +static struct snd_soc_aux_dev *msm_aux_dev; +static struct snd_soc_codec_conf *msm_codec_conf; +static struct msm_asoc_wcd93xx_codec msm_codec_fn; + +static void *def_tavil_mbhc_cal(void); +static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, + int enable, bool dapm); +static int msm_wsa881x_init(struct snd_soc_component *component); + +/* + * Need to report LINEIN + * if R/L channel impedance is larger than 5K ohm + */ +static struct wcd_mbhc_config wcd_mbhc_cfg = { + .read_fw_bin = false, + .calibration = NULL, + .detect_extn_cable = true, + .mono_stero_detection = false, + .swap_gnd_mic = NULL, + .hs_ext_micbias = true, + .key_code[0] = KEY_MEDIA, + .key_code[1] = KEY_VOICECOMMAND, + .key_code[2] = KEY_VOLUMEUP, + .key_code[3] = KEY_VOLUMEDOWN, + .key_code[4] = 0, + .key_code[5] = 0, + .key_code[6] = 0, + .key_code[7] = 0, + .linein_th = 5000, + .moisture_en = true, + .mbhc_micbias = MIC_BIAS_2, + .anc_micbias = MIC_BIAS_2, + .enable_anc_mic_detect = false, +}; + +static struct snd_soc_dapm_route wcd_audio_paths[] = { + {"MIC BIAS1", NULL, "MCLK"}, + {"MIC BIAS2", NULL, "MCLK"}, + {"MIC BIAS3", NULL, "MCLK"}, + {"MIC BIAS4", NULL, "MCLK"}, +}; + +static struct afe_clk_set mi2s_clk[MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + } +}; + +static struct mi2s_aux_pcm_common_conf mi2s_auxpcm_conf[PCM_I2S_SEL_MAX]; +static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; +static struct auxpcm_conf auxpcm_intf_conf[AUX_PCM_MAX]; + +static int slim_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 10; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int slim_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + sample_rate = SAMPLING_RATE_384KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int slim_get_bit_format_val(int bit_format) +{ + int val = 0; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + val = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + val = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + val = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + val = 0; + break; + } + return val; +} + +static int slim_get_bit_format(int val) +{ + int bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + + switch (val) { + case 0: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + bit_fmt = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + bit_fmt = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + bit_fmt = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return bit_fmt; +} + +static int slim_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int port_id = 0; + + if (strnstr(kcontrol->id.name, "SLIM_0_RX", sizeof("SLIM_0_RX"))) + port_id = SLIM_RX_0; + else if (strnstr(kcontrol->id.name, "SLIM_2_RX", sizeof("SLIM_2_RX"))) + port_id = SLIM_RX_2; + else if (strnstr(kcontrol->id.name, "SLIM_5_RX", sizeof("SLIM_5_RX"))) + port_id = SLIM_RX_5; + else if (strnstr(kcontrol->id.name, "SLIM_6_RX", sizeof("SLIM_6_RX"))) + port_id = SLIM_RX_6; + else if (strnstr(kcontrol->id.name, "SLIM_0_TX", sizeof("SLIM_0_TX"))) + port_id = SLIM_TX_0; + else if (strnstr(kcontrol->id.name, "SLIM_1_TX", sizeof("SLIM_1_TX"))) + port_id = SLIM_TX_1; + else { + pr_err("%s: unsupported channel: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + + return port_id; +} + +static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_sample_rate_val(slim_rx_cfg[ch_num].sample_rate); + + pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].sample_rate = + slim_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_sample_rate_val(slim_tx_cfg[ch_num].sample_rate); + + pr_debug("%s: slim[%d]_tx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate = 0; + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + sample_rate = slim_get_sample_rate(ucontrol->value.enumerated.item[0]); + if (sample_rate == SAMPLING_RATE_44P1KHZ) { + pr_err("%s: Unsupported sample rate %d: for Tx path\n", + __func__, sample_rate); + return -EINVAL; + } + slim_tx_cfg[ch_num].sample_rate = sample_rate; + + pr_debug("%s: slim[%d]_tx_sample_rate = %d, value = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_bit_format_val(slim_rx_cfg[ch_num].bit_format); + + pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_rx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].bit_format = + slim_get_bit_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_rx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_bit_format_val(slim_tx_cfg[ch_num].bit_format); + + pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_tx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_tx_cfg[ch_num].bit_format = + slim_get_bit_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_tx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_slim_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].channels); + ucontrol->value.enumerated.item[0] = slim_rx_cfg[ch_num].channels - 1; + + return 0; +} + +static int msm_slim_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].channels); + + return 1; +} + +static int msm_slim_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].channels); + ucontrol->value.enumerated.item[0] = slim_tx_cfg[ch_num].channels - 1; + + return 0; +} + +static int msm_slim_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_tx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].channels); + + return 1; +} + +static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1; + pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch); + return 1; +} + +static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* + * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) + * when used for BT_SCO use case. Return either Rx or Tx sample rate + * value. + */ + switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate = %d", __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 0: + default: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n", + __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate, + slim_tx_cfg[SLIM_TX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, + usb_rx_cfg.channels); + ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1; + return 0; +} + +static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels); + return 1; +} + +static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_rx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__, + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_rx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_rx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_rx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_rx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, + usb_tx_cfg.channels); + ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1; + return 0; +} + +static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels); + return 1; +} + +static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_tx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + default: + sample_rate_val = 6; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__, + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_tx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_tx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_tx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_tx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "Display Port RX", + sizeof("Display Port RX"))) { + idx = DP_RX_IDX; + } else { + pr_err("%s: unsupported BE: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].bit_format) { + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 1: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int ext_disp_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.integer.value[0] = + ext_disp_rx_cfg[idx].channels - 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + + return 0; +} + +static int ext_disp_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ext_disp_rx_cfg[idx].channels = + ucontrol->value.integer.value[0] + 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + return 1; +} + +static int ext_disp_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].sample_rate) { + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 6; + break; + + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 4; + break; + + case SAMPLING_RATE_32KHZ: + sample_rate_val = 3; + break; + + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: ext_disp_rx[%d].sample_rate = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].sample_rate); + + return 0; +} + +static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 6: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 5: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 4: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_32KHZ; + break; + case 2: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, ext_disp_rx[%d].sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], idx, + ext_disp_rx_cfg[idx].sample_rate); + return 0; +} + +static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2; + + return 0; +} + +static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2; + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + + return 1; +} + +static int tdm_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_384KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int aux_pcm_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 0: + default: + sample_rate = SAMPLING_RATE_8KHZ; + break; + } + return sample_rate; +} + +static int tdm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 8; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int aux_pcm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + return sample_rate_val; +} + +static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, + struct tdm_port *port) +{ + if (port) { + if (strnstr(kcontrol->id.name, "PRI", + sizeof(kcontrol->id.name))) { + port->mode = TDM_PRI; + } else if (strnstr(kcontrol->id.name, "SEC", + sizeof(kcontrol->id.name))) { + port->mode = TDM_SEC; + } else if (strnstr(kcontrol->id.name, "TERT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_TERT; + } else if (strnstr(kcontrol->id.name, "QUAT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_QUAT; + } else { + pr_err("%s: unsupported mode in: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + + if (strnstr(kcontrol->id.name, "RX_0", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_0", + sizeof(kcontrol->id.name))) { + port->channel = TDM_0; + } else if (strnstr(kcontrol->id.name, "RX_1", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_1", + sizeof(kcontrol->id.name))) { + port->channel = TDM_1; + } else if (strnstr(kcontrol->id.name, "RX_2", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_2", + sizeof(kcontrol->id.name))) { + port->channel = TDM_2; + } else if (strnstr(kcontrol->id.name, "RX_3", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_3", + sizeof(kcontrol->id.name))) { + port->channel = TDM_3; + } else if (strnstr(kcontrol->id.name, "RX_4", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_4", + sizeof(kcontrol->id.name))) { + port->channel = TDM_4; + } else if (strnstr(kcontrol->id.name, "RX_5", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_5", + sizeof(kcontrol->id.name))) { + port->channel = TDM_5; + } else if (strnstr(kcontrol->id.name, "RX_6", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_6", + sizeof(kcontrol->id.name))) { + port->channel = TDM_6; + } else if (strnstr(kcontrol->id.name, "RX_7", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_7", + sizeof(kcontrol->id.name))) { + port->channel = TDM_7; + } else { + pr_err("%s: unsupported channel in: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + } else + return -EINVAL; + return 0; +} + +static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_rx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_tx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_get_format(int value) +{ + int format = 0; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int tdm_get_format_val(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 2; + break; + default: + value = 0; + break; + } + return value; +} + +static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_rx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_tx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + + ucontrol->value.enumerated.item[0] = + tdm_rx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = + tdm_tx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", + sizeof("PRIM_AUX_PCM"))) + idx = PRIM_AUX_PCM; + else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM", + sizeof("SEC_AUX_PCM"))) + idx = SEC_AUX_PCM; + else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", + sizeof("TERT_AUX_PCM"))) + idx = TERT_AUX_PCM; + else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", + sizeof("QUAT_AUX_PCM"))) + idx = QUAT_AUX_PCM; + else { + pr_err("%s: unsupported port: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX", + sizeof("PRIM_MI2S_RX"))) + idx = PRIM_MI2S; + else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX", + sizeof("SEC_MI2S_RX"))) + idx = SEC_MI2S; + else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", + sizeof("TERT_MI2S_RX"))) + idx = TERT_MI2S; + else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", + sizeof("QUAT_MI2S_RX"))) + idx = QUAT_MI2S; + else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", + sizeof("PRIM_MI2S_TX"))) + idx = PRIM_MI2S; + else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX", + sizeof("SEC_MI2S_TX"))) + idx = SEC_MI2S; + else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", + sizeof("TERT_MI2S_TX"))) + idx = TERT_MI2S; + else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", + sizeof("QUAT_MI2S_TX"))) + idx = QUAT_MI2S; + else { + pr_err("%s: unsupported channel: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int mi2s_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 6; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int mi2s_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_192KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int mi2s_get_format(int value) +{ + int format; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int mi2s_get_format_value(int format) +{ + int value; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + value = 2; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 3; + break; + default: + value = 0; + break; + } + return value; +} + +static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_format_value(mi2s_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].bit_format = + mi2s_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_format_value(mi2s_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].bit_format = + mi2s_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_hifi_ctrl(struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + + pr_debug("%s: msm_hifi_control = %d", __func__, + msm_hifi_control); + + if (!pdata || !pdata->hph_en1_gpio_p) { + pr_err("%s: hph_en1_gpio is invalid\n", __func__); + return -EINVAL; + } + if (msm_hifi_control == MSM_HIFI_ON) { + msm_cdc_pinctrl_select_active_state(pdata->hph_en1_gpio_p); + /* 5msec delay needed as per HW requirement */ + usleep_range(5000, 5010); + } else { + msm_cdc_pinctrl_select_sleep_state(pdata->hph_en1_gpio_p); + } + snd_soc_dapm_sync(dapm); + + return 0; +} + +static int msm_hifi_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_hifi_control = %d\n", + __func__, msm_hifi_control); + ucontrol->value.integer.value[0] = msm_hifi_control; + + return 0; +} + +static int msm_hifi_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + msm_hifi_control = ucontrol->value.integer.value[0]; + msm_hifi_ctrl(codec); + + return 0; +} + +static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, + msm_slim_rx_ch_get, msm_slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs, + msm_slim_rx_ch_get, msm_slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs, + msm_slim_tx_ch_get, msm_slim_tx_ch_put), + SOC_ENUM_EXT("SLIM_1_TX Channels", slim_1_tx_chs, + msm_slim_tx_ch_get, msm_slim_tx_ch_put), + SOC_ENUM_EXT("SLIM_5_RX Channels", slim_5_rx_chs, + msm_slim_rx_ch_get, msm_slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_6_RX Channels", slim_6_rx_chs, + msm_slim_rx_ch_get, msm_slim_rx_ch_put), + SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, + msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, + usb_audio_rx_ch_get, usb_audio_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, + usb_audio_tx_ch_get, usb_audio_tx_ch_put), + SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, + ext_disp_rx_ch_get, ext_disp_rx_ch_put), + SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, + proxy_rx_ch_get, proxy_rx_ch_put), + SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_5_RX Format", slim_5_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_6_RX Format", slim_6_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format, + slim_tx_bit_format_get, slim_tx_bit_format_put), + SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, + usb_audio_rx_format_get, usb_audio_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, + usb_audio_tx_format_get, usb_audio_tx_format_put), + SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, + ext_disp_rx_format_get, ext_disp_rx_format_put), + SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate, + slim_tx_sample_rate_get, slim_tx_sample_rate_put), + SOC_ENUM_EXT("SLIM_5_RX SampleRate", slim_5_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_6_RX SampleRate", slim_6_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, + usb_audio_rx_sample_rate_get, + usb_audio_rx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, + usb_audio_tx_sample_rate_get, + usb_audio_tx_sample_rate_put), + SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, + ext_disp_rx_sample_rate_get, + ext_disp_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("SEC_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("TERT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("TERT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get, + msm_hifi_put), +}; + +static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, + int enable, bool dapm) +{ + int ret = 0; + + if (!strcmp(dev_name(codec->dev), "tavil_codec")) { + ret = tavil_cdc_mclk_enable(codec, enable); + } else { + dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", + __func__); + ret = -EINVAL; + } + return ret; +} + +static int msm_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + pr_debug("%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return msm_snd_enable_codec_ext_clk(codec, 1, true); + case SND_SOC_DAPM_POST_PMD: + return msm_snd_enable_codec_ext_clk(codec, 0, true); + } + return 0; +} + +static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + + pr_debug("%s: msm_hifi_control = %d", __func__, msm_hifi_control); + + if (!pdata || !pdata->hph_en0_gpio_p) { + pr_err("%s: hph_en0_gpio is invalid\n", __func__); + return -EINVAL; + } + + if (msm_hifi_control != MSM_HIFI_ON) { + pr_debug("%s: HiFi mixer control is not set\n", + __func__); + return 0; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + msm_cdc_pinctrl_select_active_state(pdata->hph_en0_gpio_p); + break; + case SND_SOC_DAPM_PRE_PMD: + msm_cdc_pinctrl_select_sleep_state(pdata->hph_en0_gpio_p); + break; + } + + return 0; +} + +static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { + + SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, + msm_mclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0, + NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SPK("Lineout_1 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), + SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event), + SND_SOC_DAPM_MIC("Handset Mic", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), + SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL), + SND_SOC_DAPM_MIC("Analog Mic5", NULL), + + SND_SOC_DAPM_MIC("Digital Mic0", NULL), + SND_SOC_DAPM_MIC("Digital Mic1", NULL), + SND_SOC_DAPM_MIC("Digital Mic2", NULL), + SND_SOC_DAPM_MIC("Digital Mic3", NULL), + SND_SOC_DAPM_MIC("Digital Mic4", NULL), + SND_SOC_DAPM_MIC("Digital Mic5", NULL), +}; + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, + int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, + unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +static int msm_slim_get_ch_from_beid(int32_t be_id) +{ + int ch_id = 0; + + switch (be_id) { + case MSM_BACKEND_DAI_SLIMBUS_0_RX: + ch_id = SLIM_RX_0; + break; + case MSM_BACKEND_DAI_SLIMBUS_1_RX: + ch_id = SLIM_RX_1; + break; + case MSM_BACKEND_DAI_SLIMBUS_2_RX: + ch_id = SLIM_RX_2; + break; + case MSM_BACKEND_DAI_SLIMBUS_3_RX: + ch_id = SLIM_RX_3; + break; + case MSM_BACKEND_DAI_SLIMBUS_4_RX: + ch_id = SLIM_RX_4; + break; + case MSM_BACKEND_DAI_SLIMBUS_6_RX: + ch_id = SLIM_RX_6; + break; + case MSM_BACKEND_DAI_SLIMBUS_0_TX: + ch_id = SLIM_TX_0; + break; + case MSM_BACKEND_DAI_SLIMBUS_3_TX: + ch_id = SLIM_TX_3; + break; + default: + ch_id = SLIM_RX_0; + break; + } + + return ch_id; +} + +static int msm_ext_disp_get_idx_from_beid(int32_t be_id) +{ + int idx; + + switch (be_id) { + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = DP_RX_IDX; + break; + default: + pr_err("%s: Incorrect ext_disp BE id %d\n", __func__, be_id); + idx = -EINVAL; + break; + } + + return idx; +} + +static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int rc = 0; + int idx; + void *config = NULL; + struct snd_soc_codec *codec = NULL; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->id) { + case MSM_BACKEND_DAI_SLIMBUS_0_RX: + case MSM_BACKEND_DAI_SLIMBUS_1_RX: + case MSM_BACKEND_DAI_SLIMBUS_2_RX: + case MSM_BACKEND_DAI_SLIMBUS_3_RX: + case MSM_BACKEND_DAI_SLIMBUS_4_RX: + case MSM_BACKEND_DAI_SLIMBUS_6_RX: + idx = msm_slim_get_ch_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[idx].bit_format); + rate->min = rate->max = slim_rx_cfg[idx].sample_rate; + channels->min = channels->max = slim_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_0_TX: + case MSM_BACKEND_DAI_SLIMBUS_3_TX: + idx = msm_slim_get_ch_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[idx].bit_format); + rate->min = rate->max = slim_tx_cfg[idx].sample_rate; + channels->min = channels->max = slim_tx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_1_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[1].bit_format); + rate->min = rate->max = slim_tx_cfg[1].sample_rate; + channels->min = channels->max = slim_tx_cfg[1].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_4_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + SNDRV_PCM_FORMAT_S32_LE); + rate->min = rate->max = SAMPLING_RATE_8KHZ; + channels->min = channels->max = msm_vi_feed_tx_ch; + break; + + case MSM_BACKEND_DAI_SLIMBUS_5_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[5].bit_format); + rate->min = rate->max = slim_rx_cfg[5].sample_rate; + channels->min = channels->max = slim_rx_cfg[5].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_5_TX: + codec = rtd->codec; + rate->min = rate->max = SAMPLING_RATE_16KHZ; + channels->min = channels->max = 1; + + config = msm_codec_fn.get_afe_config_fn(codec, + AFE_SLIMBUS_SLAVE_PORT_CONFIG); + if (config) { + rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, + config, SLIMBUS_5_TX); + if (rc) + pr_err("%s: Failed to set slimbus slave port config %d\n", + __func__, rc); + } + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[SLIM_RX_7].bit_format); + rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate; + channels->min = channels->max = + slim_rx_cfg[SLIM_RX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_8_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_8].channels; + break; + + case MSM_BACKEND_DAI_USB_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_rx_cfg.bit_format); + rate->min = rate->max = usb_rx_cfg.sample_rate; + channels->min = channels->max = usb_rx_cfg.channels; + break; + + case MSM_BACKEND_DAI_USB_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_tx_cfg.bit_format); + rate->min = rate->max = usb_tx_cfg.sample_rate; + channels->min = channels->max = usb_tx_cfg.channels; + break; + + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = msm_ext_disp_get_idx_from_beid(dai_link->id); + if (idx < 0) { + pr_err("%s: Incorrect ext disp idx %d\n", + __func__, idx); + rc = idx; + goto done; + } + + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + ext_disp_rx_cfg[idx].bit_format); + rate->min = rate->max = ext_disp_rx_cfg[idx].sample_rate; + channels->min = channels->max = ext_disp_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_AFE_PCM_RX: + channels->min = channels->max = proxy_rx_cfg.channels; + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + + case MSM_BACKEND_DAI_PRI_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_PRI_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUAT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUAT_MI2S].channels; + break; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + +done: + return rc; +} + +static bool msm_usbc_swap_gnd_mic(struct snd_soc_codec *codec, bool active) +{ + int value = 0; + bool ret = 0; + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct pinctrl_state *en2_pinctrl_active; + struct pinctrl_state *en2_pinctrl_sleep; + + if (!pdata->usbc_en2_gpio_p) { + if (active) { + /* if active and usbc_en2_gpio undefined, get pin */ + pdata->usbc_en2_gpio_p = devm_pinctrl_get(card->dev); + if (IS_ERR_OR_NULL(pdata->usbc_en2_gpio_p)) { + dev_err(card->dev, + "%s: Can't get EN2 gpio pinctrl:%ld\n", + __func__, + PTR_ERR(pdata->usbc_en2_gpio_p)); + pdata->usbc_en2_gpio_p = NULL; + return false; + } + } else + /* if not active and usbc_en2_gpio undefined, return */ + return false; + } + + pdata->usbc_en2_gpio = of_get_named_gpio(card->dev->of_node, + "qcom,usbc-analog-en2-gpio", 0); + if (!gpio_is_valid(pdata->usbc_en2_gpio)) { + dev_err(card->dev, "%s, property %s not in node %s", + __func__, "qcom,usbc-analog-en2-gpio", + card->dev->of_node->full_name); + return false; + } + + en2_pinctrl_active = pinctrl_lookup_state( + pdata->usbc_en2_gpio_p, "aud_active"); + if (IS_ERR_OR_NULL(en2_pinctrl_active)) { + dev_err(card->dev, + "%s: Cannot get aud_active pinctrl state:%ld\n", + __func__, PTR_ERR(en2_pinctrl_active)); + ret = false; + goto err_lookup_state; + } + + en2_pinctrl_sleep = pinctrl_lookup_state( + pdata->usbc_en2_gpio_p, "aud_sleep"); + if (IS_ERR_OR_NULL(en2_pinctrl_sleep)) { + dev_err(card->dev, + "%s: Cannot get aud_sleep pinctrl state:%ld\n", + __func__, PTR_ERR(en2_pinctrl_sleep)); + ret = false; + goto err_lookup_state; + } + + /* if active and usbc_en2_gpio_p defined, swap using usbc_en2_gpio_p */ + if (active) { + dev_dbg(codec->dev, "%s: enter\n", __func__); + if (pdata->usbc_en2_gpio_p) { + value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); + if (value) + pinctrl_select_state(pdata->usbc_en2_gpio_p, + en2_pinctrl_sleep); + else + pinctrl_select_state(pdata->usbc_en2_gpio_p, + en2_pinctrl_active); + } else if (pdata->usbc_en2_gpio >= 0) { + value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); + gpio_set_value_cansleep(pdata->usbc_en2_gpio, !value); + } + pr_debug("%s: swap select switch %d to %d\n", __func__, + value, !value); + ret = true; + } else { + /* if not active, release usbc_en2_gpio_p pin */ + pinctrl_select_state(pdata->usbc_en2_gpio_p, + en2_pinctrl_sleep); + } + +err_lookup_state: + devm_pinctrl_put(pdata->usbc_en2_gpio_p); + pdata->usbc_en2_gpio_p = NULL; + return ret; +} + +static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) +{ + int value = 0; + int ret = 0; + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + + if (!pdata) + return false; + + if (!wcd_mbhc_cfg.enable_usbc_analog) { + /* if usbc is not defined, swap using us_euro_gpio_p */ + if (pdata->us_euro_gpio_p) { + value = msm_cdc_pinctrl_get_state( + pdata->us_euro_gpio_p); + if (value) + msm_cdc_pinctrl_select_sleep_state( + pdata->us_euro_gpio_p); + else + msm_cdc_pinctrl_select_active_state( + pdata->us_euro_gpio_p); + } else if (pdata->us_euro_gpio >= 0) { + value = gpio_get_value_cansleep( + pdata->us_euro_gpio); + gpio_set_value_cansleep( + pdata->us_euro_gpio, !value); + } + pr_debug("%s: swap select switch %d to %d\n", __func__, + value, !value); + ret = true; + } else { + /* if usbc is defined, swap using usbc_en2 */ + ret = msm_usbc_swap_gnd_mic(codec, active); + } + return ret; +} + +static int msm_afe_set_config(struct snd_soc_codec *codec) +{ + int ret = 0; + void *config_data = NULL; + + if (!msm_codec_fn.get_afe_config_fn) { + dev_err(codec->dev, "%s: codec get afe config not init'ed\n", + __func__); + return -EINVAL; + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CDC_REGISTERS_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0); + if (ret) { + dev_err(codec->dev, + "%s: Failed to set codec registers config %d\n", + __func__, ret); + return ret; + } + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CDC_REGISTER_PAGE_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, + 0); + if (ret) + dev_err(codec->dev, + "%s: Failed to set cdc register page config\n", + __func__); + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_SLIMBUS_SLAVE_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0); + if (ret) { + dev_err(codec->dev, + "%s: Failed to set slimbus slave config %d\n", + __func__, ret); + return ret; + } + } + + return 0; +} + +static void msm_afe_clear_config(void) +{ + afe_clear_config(AFE_CDC_REGISTERS_CONFIG); + afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); +} + +static int msm_adsp_power_up_config(struct snd_soc_codec *codec) +{ + int ret = 0; + unsigned long timeout; + int adsp_ready = 0; + + timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + + do { + if (q6core_is_adsp_ready()) { + pr_debug("%s: ADSP Audio is ready\n", __func__); + adsp_ready = 1; + break; + } + /* + * ADSP will be coming up after subsystem restart and + * it might not be fully up when the control reaches + * here. So, wait for 50msec before checking ADSP state + */ + msleep(50); + } while (time_after(timeout, jiffies)); + + if (!adsp_ready) { + pr_err("%s: timed out waiting for ADSP Audio\n", __func__); + ret = -ETIMEDOUT; + goto err; + } + + ret = msm_afe_set_config(codec); + if (ret) + pr_err("%s: Failed to set AFE config. err %d\n", + __func__, ret); + + return 0; + +err: + return ret; +} + +static int sdm845_notifier_service_cb(struct notifier_block *this, + unsigned long opcode, void *ptr) +{ + int ret; + struct snd_soc_card *card = NULL; + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + struct snd_soc_codec *codec; + + pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); + + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + /* + * Use flag to ignore initial boot notifications + * On initial boot msm_adsp_power_up_config is + * called on init. There is no need to clear + * and set the config again on initial boot. + */ + if (is_initial_boot) + break; + msm_afe_clear_config(); + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (is_initial_boot) { + is_initial_boot = false; + break; + } + if (!spdev) + return -EINVAL; + + card = platform_get_drvdata(spdev); + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err; + } + codec = rtd->codec; + + ret = msm_adsp_power_up_config(codec); + if (ret < 0) { + dev_err(card->dev, + "%s: msm_adsp_power_up_config failed ret = %d!\n", + __func__, ret); + goto err; + } + break; + default: + break; + } +err: + return NOTIFY_OK; +} + +static struct notifier_block service_nb = { + .notifier_call = sdm845_notifier_service_cb, + .priority = -INT_MAX, +}; + +static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + void *config_data; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_component *aux_comp; + struct snd_card *card; + struct snd_info_entry *entry; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); + + /* Codec SLIMBUS configuration + * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8 + * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 + * TX14, TX15, TX16 + */ + unsigned int rx_ch[WCD934X_RX_MAX] = {144, 145, 146, 147, 148, 149, + 150, 151}; + unsigned int tx_ch[WCD934X_TX_MAX] = {128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143}; + + pr_info("%s: dev_name%s\n", __func__, dev_name(cpu_dai->dev)); + + rtd->pmdown_time = 0; + + ret = snd_soc_add_codec_controls(codec, msm_snd_controls, + ARRAY_SIZE(msm_snd_controls)); + if (ret < 0) { + pr_err("%s: add_codec_controls failed, err %d\n", + __func__, ret); + return ret; + } + + snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, + ARRAY_SIZE(msm_dapm_widgets)); + + snd_soc_dapm_add_routes(dapm, wcd_audio_paths, + ARRAY_SIZE(wcd_audio_paths)); + + snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic5"); + snd_soc_dapm_ignore_suspend(dapm, "MADINPUT"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT1"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT2"); + snd_soc_dapm_ignore_suspend(dapm, "EAR"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2"); + snd_soc_dapm_ignore_suspend(dapm, "ANC EAR"); + snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); + snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR"); + + snd_soc_dapm_sync(dapm); + + snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); + + msm_codec_fn.get_afe_config_fn = tavil_get_afe_config; + + ret = msm_adsp_power_up_config(codec); + if (ret) { + pr_err("%s: Failed to set AFE config %d\n", __func__, ret); + goto err; + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_AANC_VERSION); + if (config_data) { + ret = afe_set_config(AFE_AANC_VERSION, config_data, 0); + if (ret) { + pr_err("%s: Failed to set aanc version %d\n", + __func__, ret); + goto err; + } + } + + /* + * Send speaker configuration only for WSA8810. + * Default configuration is for WSA8815. + */ + pr_debug("%s: Number of aux devices: %d\n", + __func__, rtd->card->num_aux_devs); + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->aux_comp_list)) { + aux_comp = list_first_entry(&rtd->card->aux_comp_list, + struct snd_soc_component, list_aux); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { + tavil_set_spkr_mode(rtd->codec, WCD934X_SPKR_MODE_1); + tavil_set_spkr_gain_offset(rtd->codec, + WCD934X_RX_GAIN_OFFSET_M1P5_DB); + } + } + card = rtd->card->snd_card; + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + pdata->codec_root = NULL; + goto done; + } + pdata->codec_root = entry; + tavil_codec_info_create_codec_entry(pdata->codec_root, codec); + +done: + codec_reg_done = true; + return 0; + +err: + return ret; +} + +static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) +{ + unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; + unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); +} + +static void *def_tavil_mbhc_cal(void) +{ + void *tavil_wcd_cal; + struct wcd_mbhc_btn_detect_cfg *btn_cfg; + u16 *btn_high; + + tavil_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, + WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); + if (!tavil_wcd_cal) + return NULL; + +#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(tavil_wcd_cal)->X) = (Y)) + S(v_hs_max, 1600); +#undef S +#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal)->X) = (Y)) + S(num_btn, WCD_MBHC_DEF_BUTTONS); +#undef S + + btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal); + btn_high = ((void *)&btn_cfg->_v_btn_low) + + (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); + + btn_high[0] = 75; + btn_high[1] = 150; + btn_high[2] = 237; + btn_high[3] = 500; + btn_high[4] = 500; + btn_high[5] = 500; + btn_high[6] = 500; + btn_high[7] = 500; + + return tavil_wcd_cal; +} + +static int msm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + int ret = 0; + u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + u32 user_set_tx_ch = 0; + u32 rx_ch_count; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err; + } + if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_5_RX) { + pr_debug("%s: rx_5_ch=%d\n", __func__, + slim_rx_cfg[5].channels); + rx_ch_count = slim_rx_cfg[5].channels; + } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_2_RX) { + pr_debug("%s: rx_2_ch=%d\n", __func__, + slim_rx_cfg[2].channels); + rx_ch_count = slim_rx_cfg[2].channels; + } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_6_RX) { + pr_debug("%s: rx_6_ch=%d\n", __func__, + slim_rx_cfg[6].channels); + rx_ch_count = slim_rx_cfg[6].channels; + } else { + pr_debug("%s: rx_0_ch=%d\n", __func__, + slim_rx_cfg[0].channels); + rx_ch_count = slim_rx_cfg[0].channels; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + rx_ch_count, rx_ch); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + } else { + + pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__, + codec_dai->name, codec_dai->id, user_set_tx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map\n, err:%d\n", + __func__, ret); + goto err; + } + /* For _tx1 case */ + if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_0_TX) + user_set_tx_ch = slim_tx_cfg[0].channels; + /* For _tx3 case */ + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_1_TX) + user_set_tx_ch = slim_tx_cfg[1].channels; + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_4_TX) + user_set_tx_ch = msm_vi_feed_tx_ch; + else + user_set_tx_ch = tx_ch_cnt; + + pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), BE id (%d)\n", + __func__, slim_tx_cfg[0].channels, user_set_tx_ch, + tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + user_set_tx_ch, tx_ch, 0, 0); + if (ret < 0) + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + } + +err: + return ret; +} + +static int msm_slimbus_2_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; + unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0; + unsigned int num_tx_ch = 0; + unsigned int num_rx_ch = 0; + int ret = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + num_rx_ch = params_channels(params); + pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__, + codec_dai->name, codec_dai->id, num_rx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + num_rx_ch, rx_ch); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + } else { + num_tx_ch = params_channels(params); + pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__, + codec_dai->name, codec_dai->id, num_tx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, + num_tx_ch, tx_ch, 0, 0); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + } + +err: + return ret; +} + +static int msm_wcn_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + int ret; + + dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret) { + dev_err(rtd->dev, + "%s: failed to get BTFM codec chan map\n, err:%d\n", + __func__, ret); + goto err; + } + + dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) BE id %d\n", + __func__, tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); + if (ret) + dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + +err: + return ret; +} + +static int msm_aux_pcm_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int index = cpu_dai->id - 1; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + if (index < PRIM_AUX_PCM || index > QUAT_AUX_PCM) { + ret = -EINVAL; + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto err; + } + + mutex_lock(&auxpcm_intf_conf[index].lock); + if (++auxpcm_intf_conf[index].ref_cnt == 1) { + if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) { + mutex_lock(&mi2s_auxpcm_conf[index].lock); + iowrite32(1, + mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr); + mutex_unlock(&mi2s_auxpcm_conf[index].lock); + } else { + dev_err(rtd->card->dev, + "%s lpaif_tert_muxsel_virt_addr is NULL\n", + __func__); + ret = -EINVAL; + } + } + if (ret < 0) + auxpcm_intf_conf[index].ref_cnt--; + + mutex_unlock(&auxpcm_intf_conf[index].lock); + +err: + return ret; +} + +static void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int index = rtd->cpu_dai->id - 1; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, + substream->name, substream->stream, + rtd->cpu_dai->name, rtd->cpu_dai->id); + + if (index < PRIM_AUX_PCM || index > QUAT_AUX_PCM) { + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, rtd->cpu_dai->id); + return; + } + + mutex_lock(&auxpcm_intf_conf[index].lock); + if (--auxpcm_intf_conf[index].ref_cnt == 0) { + if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) { + mutex_lock(&mi2s_auxpcm_conf[index].lock); + iowrite32(0, + mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr); + mutex_unlock(&mi2s_auxpcm_conf[index].lock); + } else { + dev_err(rtd->card->dev, + "%s lpaif_tert_muxsel_virt_addr is NULL\n", + __func__); + auxpcm_intf_conf[index].ref_cnt++; + } + } + mutex_unlock(&auxpcm_intf_conf[index].lock); +} + +static int msm_get_port_id(int be_id) +{ + int afe_port_id; + + switch (be_id) { + case MSM_BACKEND_DAI_PRI_MI2S_RX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_PRI_MI2S_TX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + default: + pr_err("%s: Invalid BE id: %d\n", __func__, be_id); + afe_port_id = -EINVAL; + } + + return afe_port_id; +} + +static u32 get_mi2s_bits_per_sample(u32 bit_format) +{ + u32 bit_per_sample; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + case SNDRV_PCM_FORMAT_S24_LE: + bit_per_sample = 32; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bit_per_sample = 16; + break; + } + + return bit_per_sample; +} + +static void update_mi2s_clk_val(int dai_id, int stream) +{ + u32 bit_per_sample; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } else { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } + + if (!mi2s_intf_conf[dai_id].msm_is_mi2s_master) + mi2s_clk[dai_id].clk_freq_in_hz = 0; +} + +static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int port_id = 0; + int index = cpu_dai->id; + + port_id = msm_get_port_id(rtd->dai_link->id); + if (port_id < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto err; + } + + if (enable) { + update_mi2s_clk_val(index, substream->stream); + dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, + mi2s_clk[index].clk_freq_in_hz); + } + + mi2s_clk[index].enable = enable; + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_clk[index]); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed for port 0x%x , err:%d\n", + __func__, port_id, ret); + goto err; + } + +err: + return ret; +} + +static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, + enum pinctrl_pin_state new_state) +{ + int ret = 0; + int curr_state = 0; + + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + if (pinctrl_info->pinctrl == NULL) { + pr_err("%s: pinctrl_info->pinctrl is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + curr_state = pinctrl_info->curr_state; + pinctrl_info->curr_state = new_state; + pr_debug("%s: curr_state = %s new_state = %s\n", __func__, + pin_states[curr_state], pin_states[pinctrl_info->curr_state]); + + if (curr_state == pinctrl_info->curr_state) { + pr_debug("%s: Already in same state\n", __func__); + goto err; + } + + if (curr_state != STATE_DISABLE && + pinctrl_info->curr_state != STATE_DISABLE) { + pr_debug("%s: state already active cannot switch\n", __func__); + ret = -EIO; + goto err; + } + + switch (pinctrl_info->curr_state) { + case STATE_MI2S_ACTIVE: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_active); + if (ret) { + pr_err("%s: MI2S state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + case STATE_TDM_ACTIVE: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->tdm_active); + if (ret) { + pr_err("%s: TDM state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + case STATE_DISABLE: + if (curr_state == STATE_MI2S_ACTIVE) { + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_disable); + } else { + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->tdm_disable); + } + if (ret) { + pr_err("%s: state disable failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + default: + pr_err("%s: TLMM pin state is invalid\n", __func__); + return -EINVAL; + } + +err: + return ret; +} + +static void msm_release_pinctrl(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + if (pinctrl_info->pinctrl) { + devm_pinctrl_put(pinctrl_info->pinctrl); + pinctrl_info->pinctrl = NULL; + } +} + +static int msm_get_pinctrl(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = NULL; + struct pinctrl *pinctrl; + int ret; + + pinctrl_info = &pdata->pinctrl_info; + + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + return -EINVAL; + } + + pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR_OR_NULL(pinctrl)) { + pr_err("%s: Unable to get pinctrl handle\n", __func__); + return -EINVAL; + } + pinctrl_info->pinctrl = pinctrl; + + /* get all the states handles from Device Tree */ + pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl, + "quat-mi2s-sleep"); + if (IS_ERR(pinctrl_info->mi2s_disable)) { + pr_err("%s: could not get mi2s_disable pinstate\n", __func__); + goto err; + } + pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl, + "quat-mi2s-active"); + if (IS_ERR(pinctrl_info->mi2s_active)) { + pr_err("%s: could not get mi2s_active pinstate\n", __func__); + goto err; + } + pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl, + "quat-tdm-sleep"); + if (IS_ERR(pinctrl_info->tdm_disable)) { + pr_err("%s: could not get tdm_disable pinstate\n", __func__); + goto err; + } + pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl, + "quat-tdm-active"); + if (IS_ERR(pinctrl_info->tdm_active)) { + pr_err("%s: could not get tdm_active pinstate\n", + __func__); + goto err; + } + /* Reset the TLMM pins to a default state */ + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_disable); + if (ret != 0) { + pr_err("%s: Disable TLMM pins failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + pinctrl_info->curr_state = STATE_DISABLE; + + return 0; + +err: + devm_pinctrl_put(pinctrl); + pinctrl_info->pinctrl = NULL; + return -EINVAL; +} + +static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + if (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) { + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + } else if (cpu_dai->id == AFE_PORT_ID_SECONDARY_TDM_RX) { + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + } else { + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n", + __func__, cpu_dai->id, channels->max, rate->max, + params_format(params)); + + return 0; +} + +static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + int channels, slot_width, slots; + unsigned int slot_mask; + unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; + + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + + slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + /*2 slot config - bits 0 and 1 set for the first two slots */ + slot_mask = 0x0000FFFF >> (16-slots); + slot_width = 32; + channels = slots; + + pr_debug("%s: slot_width %d slots %d\n", __func__, slot_width, slots); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + pr_debug("%s: slot_width %d\n", __func__, slot_width); + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + 0, NULL, channels, slot_offset); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } else { + pr_err("%s: invalid use case, err:%d\n", + __func__, ret); + } + +end: + return ret; +} + +static int sdm845_tdm_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); + if (ret) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret); + + return ret; +} + +static void sdm845_tdm_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); + if (ret) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret); + +} + +static struct snd_soc_ops sdm845_tdm_be_ops = { + .hw_params = sdm845_tdm_snd_hw_params, + .startup = sdm845_tdm_snd_startup, + .shutdown = sdm845_tdm_snd_shutdown +}; + +static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int index = cpu_dai->id; + unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret_pinctrl = 0; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + if (index < PRIM_MI2S || index > QUAT_MI2S) { + ret = -EINVAL; + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto err; + } + if (index == QUAT_MI2S) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, STATE_MI2S_ACTIVE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } + /* + * Muxtex protection in case the same MI2S + * interface using for both TX and RX so + * that the same clock won't be enable twice. + */ + mutex_lock(&mi2s_intf_conf[index].lock); + if (++mi2s_intf_conf[index].ref_cnt == 1) { + ret = msm_mi2s_set_sclk(substream, true); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed to enable MI2S clock, err:%d\n", + __func__, ret); + goto clean_up; + } + if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) { + mutex_lock(&mi2s_auxpcm_conf[index].lock); + iowrite32(0, + mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr); + mutex_unlock(&mi2s_auxpcm_conf[index].lock); + } else { + dev_err(rtd->card->dev, + "%s lpaif_muxsel_virt_addr is NULL for dai %d\n", + __func__, index); + ret = -EINVAL; + goto clk_off; + } + /* Check if msm needs to provide the clock to the interface */ + if (!mi2s_intf_conf[index].msm_is_mi2s_master) + fmt = SND_SOC_DAIFMT_CBM_CFM; + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) { + pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n", + __func__, index, ret); + goto clk_off; + } + } +clk_off: + if (ret < 0) + msm_mi2s_set_sclk(substream, false); +clean_up: + if (ret < 0) + mi2s_intf_conf[index].ref_cnt--; + mutex_unlock(&mi2s_intf_conf[index].lock); +err: + return ret; +} + +static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int index = rtd->cpu_dai->id; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret_pinctrl = 0; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + if (index < PRIM_MI2S || index > QUAT_MI2S) { + pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); + return; + } + + mutex_lock(&mi2s_intf_conf[index].lock); + if (--mi2s_intf_conf[index].ref_cnt == 0) { + ret = msm_mi2s_set_sclk(substream, false); + if (ret < 0) { + pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", + __func__, index, ret); + mi2s_intf_conf[index].ref_cnt++; + } + } + mutex_unlock(&mi2s_intf_conf[index].lock); + + if (index == QUAT_MI2S) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } +} + +static struct snd_soc_ops msm_mi2s_be_ops = { + .startup = msm_mi2s_snd_startup, + .shutdown = msm_mi2s_snd_shutdown, +}; + +static struct snd_soc_ops msm_aux_pcm_be_ops = { + .startup = msm_aux_pcm_snd_startup, + .shutdown = msm_aux_pcm_snd_shutdown, +}; + +static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width, + int slots) +{ + unsigned int slot_mask = 0; + int i, j; + unsigned int *slot_offset; + + for (i = TDM_0; i < TDM_PORT_MAX; i++) { + slot_offset = tdm_slot_offset[i]; + + for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) { + if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID) + slot_mask |= + (1 << ((slot_offset[j] * 8) / slot_width)); + else + break; + } + } + + return slot_mask; +} + +static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + int channels, slot_width, slots; + unsigned int slot_mask; + unsigned int *slot_offset; + int offset_channels = 0; + int i; + + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + + channels = params_channels(params); + switch (channels) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S16_LE: + /* + * Up to 8 channels HW config should + * use 32 bit slot width for max support of + * stream bit width. (slot_width > bit_width) + */ + slot_width = 32; + break; + default: + pr_err("%s: invalid param format 0x%x\n", + __func__, params_format(params)); + return -EINVAL; + } + slots = 8; + slot_mask = tdm_param_set_slot_mask(cpu_dai->id, + slot_width, + slots); + if (!slot_mask) { + pr_err("%s: invalid slot_mask 0x%x\n", + __func__, slot_mask); + return -EINVAL; + } + break; + default: + pr_err("%s: invalid param channels %d\n", + __func__, channels); + return -EINVAL; + } + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + slot_offset = tdm_slot_offset[TDM_0]; + break; + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) + offset_channels++; + else + break; + } + + if (offset_channels == 0) { + pr_err("%s: slot offset not supported, offset_channels %d\n", + __func__, offset_channels); + return -EINVAL; + } + + if (channels > offset_channels) { + pr_err("%s: channels %d exceed offset_channels %d\n", + __func__, channels, offset_channels); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto err; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, + channels, slot_offset); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto err; + } + } else { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto err; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, channels, + slot_offset, 0, NULL); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto err; + } + } +err: + return ret; +} + +static struct snd_soc_ops msm_be_ops = { + .hw_params = msm_snd_hw_params, +}; + +static struct snd_soc_ops msm_slimbus_2_be_ops = { + .hw_params = msm_slimbus_2_hw_params, +}; + +static struct snd_soc_ops msm_wcn_ops = { + .hw_params = msm_wcn_hw_params, +}; + +static struct snd_soc_ops msm_tdm_be_ops = { + .hw_params = msm_tdm_snd_hw_params +}; + +/* Digital audio interface glue - connects codec <---> CPU */ +static struct snd_soc_dai_link msm_common_dai_links[] = { + /* FrontEnd DAI Links */ + { + .name = MSM_DAILINK_NAME(Media1), + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, + { + .name = MSM_DAILINK_NAME(Media2), + .stream_name = "MultiMedia2", + .cpu_dai_name = "MultiMedia2", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, + }, + { + .name = "VoiceMMode1", + .stream_name = "VoiceMMode1", + .cpu_dai_name = "VoiceMMode1", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE1, + }, + { + .name = "MSM VoIP", + .stream_name = "VoIP", + .cpu_dai_name = "VoIP", + .platform_name = "msm-voip-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_VOIP, + }, + { + .name = MSM_DAILINK_NAME(ULL), + .stream_name = "MultiMedia3", + .cpu_dai_name = "MultiMedia3", + .platform_name = "msm-pcm-dsp.2", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA3, + }, + /* Hostless PCM purpose */ + { + .name = "SLIMBUS_0 Hostless", + .stream_name = "SLIMBUS_0 Hostless", + .cpu_dai_name = "SLIMBUS0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "MSM AFE-PCM RX", + .stream_name = "AFE-PROXY RX", + .cpu_dai_name = "msm-dai-q6-dev.241", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .platform_name = "msm-pcm-afe", + .dpcm_playback = 1, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + }, + { + .name = "MSM AFE-PCM TX", + .stream_name = "AFE-PROXY TX", + .cpu_dai_name = "msm-dai-q6-dev.240", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .platform_name = "msm-pcm-afe", + .dpcm_capture = 1, + .ignore_suspend = 1, + }, + { + .name = MSM_DAILINK_NAME(Compress1), + .stream_name = "Compress1", + .cpu_dai_name = "MultiMedia4", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA4, + }, + { + .name = "AUXPCM Hostless", + .stream_name = "AUXPCM Hostless", + .cpu_dai_name = "AUXPCM_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_1 Hostless", + .stream_name = "SLIMBUS_1 Hostless", + .cpu_dai_name = "SLIMBUS1_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_3 Hostless", + .stream_name = "SLIMBUS_3 Hostless", + .cpu_dai_name = "SLIMBUS3_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_4 Hostless", + .stream_name = "SLIMBUS_4 Hostless", + .cpu_dai_name = "SLIMBUS4_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = MSM_DAILINK_NAME(LowLatency), + .stream_name = "MultiMedia5", + .cpu_dai_name = "MultiMedia5", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + }, + { + .name = "Listen 1 Audio Service", + .stream_name = "Listen 1 Audio Service", + .cpu_dai_name = "LSM1", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM1, + }, + /* Multiple Tunnel instances */ + { + .name = MSM_DAILINK_NAME(Compress2), + .stream_name = "Compress2", + .cpu_dai_name = "MultiMedia7", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA7, + }, + { + .name = MSM_DAILINK_NAME(Compress3), + .stream_name = "Compress3", + .cpu_dai_name = "MultiMedia10", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA10, + }, + { + .name = MSM_DAILINK_NAME(ULL_NOIRQ), + .stream_name = "MM_NOIRQ", + .cpu_dai_name = "MultiMedia8", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + }, + /* HDMI Hostless */ + { + .name = "HDMI_RX_HOSTLESS", + .stream_name = "HDMI_RX_HOSTLESS", + .cpu_dai_name = "HDMI_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "VoiceMMode2", + .stream_name = "VoiceMMode2", + .cpu_dai_name = "VoiceMMode2", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE2, + }, + /* LSM FE */ + { + .name = "Listen 2 Audio Service", + .stream_name = "Listen 2 Audio Service", + .cpu_dai_name = "LSM2", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM2, + }, + { + .name = "Listen 3 Audio Service", + .stream_name = "Listen 3 Audio Service", + .cpu_dai_name = "LSM3", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM3, + }, + { + .name = "Listen 4 Audio Service", + .stream_name = "Listen 4 Audio Service", + .cpu_dai_name = "LSM4", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM4, + }, + { + .name = "Listen 5 Audio Service", + .stream_name = "Listen 5 Audio Service", + .cpu_dai_name = "LSM5", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM5, + }, + { + .name = "Listen 6 Audio Service", + .stream_name = "Listen 6 Audio Service", + .cpu_dai_name = "LSM6", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM6, + }, + { + .name = "Listen 7 Audio Service", + .stream_name = "Listen 7 Audio Service", + .cpu_dai_name = "LSM7", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM7, + }, + { + .name = "Listen 8 Audio Service", + .stream_name = "Listen 8 Audio Service", + .cpu_dai_name = "LSM8", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM8, + }, + { + .name = MSM_DAILINK_NAME(Media9), + .stream_name = "MultiMedia9", + .cpu_dai_name = "MultiMedia9", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA9, + }, + { + .name = MSM_DAILINK_NAME(Compress4), + .stream_name = "Compress4", + .cpu_dai_name = "MultiMedia11", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA11, + }, + { + .name = MSM_DAILINK_NAME(Compress5), + .stream_name = "Compress5", + .cpu_dai_name = "MultiMedia12", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA12, + }, + { + .name = MSM_DAILINK_NAME(Compress6), + .stream_name = "Compress6", + .cpu_dai_name = "MultiMedia13", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA13, + }, + { + .name = MSM_DAILINK_NAME(Compress7), + .stream_name = "Compress7", + .cpu_dai_name = "MultiMedia14", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA14, + }, + { + .name = MSM_DAILINK_NAME(Compress8), + .stream_name = "Compress8", + .cpu_dai_name = "MultiMedia15", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA15, + }, + { + .name = MSM_DAILINK_NAME(Compress9), + .stream_name = "Compress9", + .cpu_dai_name = "MultiMedia16", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA16, + }, + { + .name = "SLIMBUS_8 Hostless", + .stream_name = "SLIMBUS8_HOSTLESS Capture", + .cpu_dai_name = "SLIMBUS8_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +}; + +static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_4_TX, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_vifeedback", + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + }, + /* Ultrasound RX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Playback", + .stream_name = "SLIMBUS_2 Hostless Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx2", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_slimbus_2_be_ops, + }, + /* Ultrasound TX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Capture", + .stream_name = "SLIMBUS_2 Hostless Capture", + .cpu_dai_name = "msm-dai-q6-dev.16389", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx2", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_slimbus_2_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { + { + .name = MSM_DAILINK_NAME(ASM Loopback), + .stream_name = "MultiMedia6", + .cpu_dai_name = "MultiMedia6", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA6, + }, + { + .name = "USB Audio Hostless", + .stream_name = "USB Audio Hostless", + .cpu_dai_name = "USBAUDIO_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +}; + +static struct snd_soc_dai_link msm_common_be_dai_links[] = { + /* Backend AFE DAI Links */ + { + .name = LPASS_BE_AFE_PCM_RX, + .stream_name = "AFE Playback", + .cpu_dai_name = "msm-dai-q6-dev.224", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AFE_PCM_TX, + .stream_name = "AFE Capture", + .cpu_dai_name = "msm-dai-q6-dev.225", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Uplink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_TX, + .stream_name = "Voice Uplink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32772", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Downlink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_RX, + .stream_name = "Voice Downlink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32771", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music BACK END DAI Link */ + { + .name = LPASS_BE_VOICE_PLAYBACK_TX, + .stream_name = "Voice Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32773", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music 2 BACK END DAI Link */ + { + .name = LPASS_BE_VOICE2_PLAYBACK_TX, + .stream_name = "Voice2 Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32770", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_RX, + .stream_name = "USB Audio Playback", + .cpu_dai_name = "msm-dai-q6-dev.28672", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_USB_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_TX, + .stream_name = "USB Audio Capture", + .cpu_dai_name = "msm-dai-q6-dev.28673", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_USB_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_0, + .stream_name = "Primary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36864", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_0, + .stream_name = "Primary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36865", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_0, + .stream_name = "Secondary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36880", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_0, + .stream_name = "Secondary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36881", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_0, + .stream_name = "Tertiary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36896", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_0, + .stream_name = "Tertiary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36897", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_0, + .stream_name = "Quaternary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36912", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sdm845_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_0, + .stream_name = "Quaternary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36913", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_tavil_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_init, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_1_RX, + .stream_name = "Slimbus1 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16386", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_1_TX, + .stream_name = "Slimbus1 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16387", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx3", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_2_RX, + .stream_name = "Slimbus2 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx2", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_2_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_RX, + .stream_name = "Slimbus3 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16390", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_TX, + .stream_name = "Slimbus3 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16391", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_4_RX, + .stream_name = "Slimbus4 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16392", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_5_RX, + .stream_name = "Slimbus5 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16394", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx3", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* MAD BE */ + { + .name = LPASS_BE_SLIMBUS_5_TX, + .stream_name = "Slimbus5 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16395", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_mad1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_6_RX, + .stream_name = "Slimbus6 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16396", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx4", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* Slimbus VI Recording */ + { + .name = LPASS_BE_SLIMBUS_TX_VI, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_vifeedback", + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + .no_pcm = 1, + .dpcm_capture = 1, + .ignore_pmdown_time = 1, + }, +}; + +static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_7_RX, + .stream_name = "Slimbus7 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16398", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + /* BT codec driver determines capabilities based on + * dai name, bt codecdai name should always contains + * supported usecase information + */ + .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_7_TX, + .stream_name = "Slimbus7 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16399", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_bt_sco_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_8_TX, + .stream_name = "Slimbus8 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16401", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_fm_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_8_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .init = &msm_wcn_init, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link ext_disp_be_dai_link[] = { + /* DISP PORT BACK END DAI Link */ + { + .name = LPASS_BE_DISPLAY_PORT, + .stream_name = "Display Port Playback", + .cpu_dai_name = "msm-dai-q6-dp.24608", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-ext-disp-audio-codec-rx", + .codec_dai_name = "msm_dp_audio_codec_rx_dai", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { + { + .name = LPASS_BE_PRI_MI2S_RX, + .stream_name = "Primary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_MI2S_TX, + .stream_name = "Primary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX, + .stream_name = "Secondary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX, + .stream_name = "Secondary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX, + .stream_name = "Tertiary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX, + .stream_name = "Tertiary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX, + .stream_name = "Quaternary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { + /* Primary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_AUXPCM_RX, + .stream_name = "AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_AUXPCM_TX, + .stream_name = "AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Secondary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_SEC_AUXPCM_RX, + .stream_name = "Sec AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_SEC_AUXPCM_TX, + .stream_name = "Sec AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Tertiary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_TERT_AUXPCM_RX, + .stream_name = "Tert AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_TERT_AUXPCM_TX, + .stream_name = "Tert AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Quaternary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUAT_AUXPCM_RX, + .stream_name = "Quat AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_QUAT_AUXPCM_TX, + .stream_name = "Quat AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .ops = &msm_aux_pcm_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_tavil_snd_card_dai_links[ + ARRAY_SIZE(msm_common_dai_links) + + ARRAY_SIZE(msm_tavil_fe_dai_links) + + ARRAY_SIZE(msm_common_misc_fe_dai_links) + + ARRAY_SIZE(msm_common_be_dai_links) + + ARRAY_SIZE(msm_tavil_be_dai_links) + + ARRAY_SIZE(msm_wcn_be_dai_links) + + ARRAY_SIZE(ext_disp_be_dai_link) + + ARRAY_SIZE(msm_mi2s_be_dai_links) + + ARRAY_SIZE(msm_auxpcm_be_dai_links)]; + +static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) +{ + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + void *mbhc_calibration; + + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err; + } + + mbhc_calibration = def_tavil_mbhc_cal(); + if (!mbhc_calibration) { + ret = -ENOMEM; + goto err; + } + wcd_mbhc_cfg.calibration = mbhc_calibration; + ret = tavil_mbhc_hs_detect(rtd->codec, &wcd_mbhc_cfg); + if (ret) { + dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", + __func__, ret); + goto err_free_mbhc_cal; + } + return 0; + +err_free_mbhc_cal: + kfree(mbhc_calibration); +err: + return ret; +} + +struct snd_soc_card snd_soc_card_tavil_msm = { + .name = "sdm845-tavil-snd-card", + .late_probe = msm_snd_card_tavil_late_probe, +}; + +static int msm_populate_dai_link_component_of_node( + struct snd_soc_card *card) +{ + int i, index, ret = 0; + struct device *cdev = card->dev; + struct snd_soc_dai_link *dai_link = card->dai_link; + struct device_node *np; + + if (!cdev) { + pr_err("%s: Sound card device memory NULL\n", __func__); + return -ENODEV; + } + + for (i = 0; i < card->num_links; i++) { + if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) + continue; + + /* populate platform_of_node for snd card dai links */ + if (dai_link[i].platform_name && + !dai_link[i].platform_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-platform-names", + dai_link[i].platform_name); + if (index < 0) { + pr_err("%s: No match found for platform name: %s\n", + __func__, dai_link[i].platform_name); + ret = index; + goto err; + } + np = of_parse_phandle(cdev->of_node, "asoc-platform", + index); + if (!np) { + pr_err("%s: retrieving phandle for platform %s, index %d failed\n", + __func__, dai_link[i].platform_name, + index); + ret = -ENODEV; + goto err; + } + dai_link[i].platform_of_node = np; + dai_link[i].platform_name = NULL; + } + + /* populate cpu_of_node for snd card dai links */ + if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-cpu-names", + dai_link[i].cpu_dai_name); + if (index >= 0) { + np = of_parse_phandle(cdev->of_node, "asoc-cpu", + index); + if (!np) { + pr_err("%s: retrieving phandle for cpu dai %s failed\n", + __func__, + dai_link[i].cpu_dai_name); + ret = -ENODEV; + goto err; + } + dai_link[i].cpu_of_node = np; + dai_link[i].cpu_dai_name = NULL; + } + } + + /* populate codec_of_node for snd card dai links */ + if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-codec-names", + dai_link[i].codec_name); + if (index < 0) + continue; + np = of_parse_phandle(cdev->of_node, "asoc-codec", + index); + if (!np) { + pr_err("%s: retrieving phandle for codec %s failed\n", + __func__, dai_link[i].codec_name); + ret = -ENODEV; + goto err; + } + dai_link[i].codec_of_node = np; + dai_link[i].codec_name = NULL; + } + } + +err: + return ret; +} + +static int msm_prepare_us_euro(struct snd_soc_card *card) +{ + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + int ret = 0; + + if (pdata->us_euro_gpio >= 0) { + dev_dbg(card->dev, "%s: us_euro gpio request %d", __func__, + pdata->us_euro_gpio); + ret = gpio_request(pdata->us_euro_gpio, "TAVIL_CODEC_US_EURO"); + if (ret) { + dev_err(card->dev, + "%s: Failed to request codec US/EURO gpio %d error %d\n", + __func__, pdata->us_euro_gpio, ret); + } + } + + return ret; +} + +static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + + ret = snd_soc_add_codec_controls(codec, msm_snd_controls, + ARRAY_SIZE(msm_snd_controls)); + if (ret < 0) { + dev_err(codec->dev, + "%s: add_codec_controls failed, err = %d\n", + __func__, ret); + return ret; + } + + snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, + ARRAY_SIZE(msm_dapm_widgets)); + + return 0; +} + +static int msm_snd_stub_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + + int ret = 0; + unsigned int rx_ch[] = {144, 145, 146, 147, 148, 149, 150, + 151}; + unsigned int tx_ch[] = {128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143}; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + slim_rx_cfg[0].channels, + rx_ch); + if (ret < 0) + pr_err("%s: RX failed to set cpu chan map error %d\n", + __func__, ret); + } else { + ret = snd_soc_dai_set_channel_map(cpu_dai, + slim_tx_cfg[0].channels, + tx_ch, 0, 0); + if (ret < 0) + pr_err("%s: TX failed to set cpu chan map error %d\n", + __func__, ret); + } + + return ret; +} + +static struct snd_soc_ops msm_stub_be_ops = { + .hw_params = msm_snd_stub_hw_params, +}; + +static struct snd_soc_dai_link msm_stub_fe_dai_links[] = { + + /* FrontEnd DAI Links */ + { + .name = "MSMSTUB Media1", + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, +}; + +static struct snd_soc_dai_link msm_stub_be_dai_links[] = { + + /* Backend DAI Links */ + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_stub_init, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, /* dai link has playback support */ + .ignore_suspend = 1, + .ops = &msm_stub_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_stub_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_stub_dai_links[ + ARRAY_SIZE(msm_stub_fe_dai_links) + + ARRAY_SIZE(msm_stub_be_dai_links)]; + +struct snd_soc_card snd_soc_card_stub_msm = { + .name = "sdm845-stub-snd-card", +}; + +static const struct of_device_id sdm845_asoc_machine_of_match[] = { + { .compatible = "qcom,sdm845-asoc-snd-tavil", + .data = "tavil_codec"}, + { .compatible = "qcom,sdm845-asoc-snd-stub", + .data = "stub_codec"}, + {}, +}; + +static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) +{ + struct snd_soc_card *card = NULL; + struct snd_soc_dai_link *dailink; + int len_1, len_2, len_3, len_4; + int total_links; + const struct of_device_id *match; + + match = of_match_node(sdm845_asoc_machine_of_match, dev->of_node); + if (!match) { + dev_err(dev, "%s: No DT match found for sound card\n", + __func__); + return NULL; + } + + if (!strcmp(match->data, "tavil_codec")) { + card = &snd_soc_card_tavil_msm; + len_1 = ARRAY_SIZE(msm_common_dai_links); + len_2 = len_1 + ARRAY_SIZE(msm_tavil_fe_dai_links); + len_3 = len_2 + ARRAY_SIZE(msm_common_misc_fe_dai_links); + len_4 = len_3 + ARRAY_SIZE(msm_common_be_dai_links); + total_links = len_4 + ARRAY_SIZE(msm_tavil_be_dai_links); + memcpy(msm_tavil_snd_card_dai_links, + msm_common_dai_links, + sizeof(msm_common_dai_links)); + memcpy(msm_tavil_snd_card_dai_links + len_1, + msm_tavil_fe_dai_links, + sizeof(msm_tavil_fe_dai_links)); + memcpy(msm_tavil_snd_card_dai_links + len_2, + msm_common_misc_fe_dai_links, + sizeof(msm_common_misc_fe_dai_links)); + memcpy(msm_tavil_snd_card_dai_links + len_3, + msm_common_be_dai_links, + sizeof(msm_common_be_dai_links)); + memcpy(msm_tavil_snd_card_dai_links + len_4, + msm_tavil_be_dai_links, + sizeof(msm_tavil_be_dai_links)); + + if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + dev_dbg(dev, "%s(): WCN BTFM support present\n", + __func__); + memcpy(msm_tavil_snd_card_dai_links + total_links, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + total_links += ARRAY_SIZE(msm_wcn_be_dai_links); + } + + if (of_property_read_bool(dev->of_node, + "qcom,ext-disp-audio-rx")) { + dev_dbg(dev, "%s(): ext disp audio support present\n", + __func__); + memcpy(msm_tavil_snd_card_dai_links + total_links, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + total_links += ARRAY_SIZE(ext_disp_be_dai_link); + } + if (of_property_read_bool(dev->of_node, + "qcom,mi2s-audio-intf")) { + memcpy(msm_tavil_snd_card_dai_links + total_links, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,auxpcm-audio-intf")) { + memcpy(msm_tavil_snd_card_dai_links + total_links, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + dailink = msm_tavil_snd_card_dai_links; + } else if (!strcmp(match->data, "stub_codec")) { + card = &snd_soc_card_stub_msm; + len_1 = ARRAY_SIZE(msm_stub_fe_dai_links); + len_2 = len_1 + ARRAY_SIZE(msm_stub_be_dai_links); + + memcpy(msm_stub_dai_links, + msm_stub_fe_dai_links, + sizeof(msm_stub_fe_dai_links)); + memcpy(msm_stub_dai_links + len_1, + msm_stub_be_dai_links, + sizeof(msm_stub_be_dai_links)); + + dailink = msm_stub_dai_links; + total_links = len_2; + } + + if (card) { + card->dai_link = dailink; + card->num_links = total_links; + } + + return card; +} + +static int msm_wsa881x_init(struct snd_soc_component *component) +{ + u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106}; + u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107}; + unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; + unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + struct msm_asoc_mach_data *pdata; + struct snd_soc_dapm_context *dapm; + int ret = 0; + + if (!codec) { + pr_err("%s codec is NULL\n", __func__); + return -EINVAL; + } + + dapm = snd_soc_codec_get_dapm(codec); + + if (!strcmp(component->name_prefix, "SpkrLeft")) { + dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n", + __func__, codec->component.name); + wsa881x_set_channel_map(codec, &spkleft_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0]); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); + } + } else if (!strcmp(component->name_prefix, "SpkrRight")) { + dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n", + __func__, codec->component.name); + wsa881x_set_channel_map(codec, &spkright_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0]); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); + } + } else { + dev_err(codec->dev, "%s: wrong codec name %s\n", __func__, + codec->component.name); + ret = -EINVAL; + goto err; + } + pdata = snd_soc_card_get_drvdata(component->card); + if (pdata && pdata->codec_root) + wsa881x_codec_info_create_codec_entry(pdata->codec_root, + codec); + +err: + return ret; +} + +static int msm_init_wsa_dev(struct platform_device *pdev, + struct snd_soc_card *card) +{ + struct device_node *wsa_of_node; + u32 wsa_max_devs; + u32 wsa_dev_cnt; + int i; + struct msm_wsa881x_dev_info *wsa881x_dev_info; + const char *wsa_auxdev_name_prefix[1]; + char *dev_name_str = NULL; + int found = 0; + int ret = 0; + + /* Get maximum WSA device count for this platform */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,wsa-max-devs", &wsa_max_devs); + if (ret) { + dev_dbg(&pdev->dev, + "%s: wsa-max-devs property missing in DT %s, ret = %d\n", + __func__, pdev->dev.of_node->full_name, ret); + goto err; + } + if (wsa_max_devs == 0) { + dev_warn(&pdev->dev, + "%s: Max WSA devices is 0 for this target?\n", + __func__); + goto err; + } + + /* Get count of WSA device phandles for this platform */ + wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node, + "qcom,wsa-devs", NULL); + if (wsa_dev_cnt == -ENOENT) { + dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n", + __func__); + goto err; + } else if (wsa_dev_cnt <= 0) { + dev_err(&pdev->dev, + "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n", + __func__, wsa_dev_cnt); + ret = -EINVAL; + goto err; + } + + /* + * Expect total phandles count to be NOT less than maximum possible + * WSA count. However, if it is less, then assign same value to + * max count as well. + */ + if (wsa_dev_cnt < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n", + __func__, wsa_max_devs, wsa_dev_cnt); + wsa_max_devs = wsa_dev_cnt; + } + + /* Make sure prefix string passed for each WSA device */ + ret = of_property_count_strings(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix"); + if (ret != wsa_dev_cnt) { + dev_err(&pdev->dev, + "%s: expecting %d wsa prefix. Defined only %d in DT\n", + __func__, wsa_dev_cnt, ret); + ret = -EINVAL; + goto err; + } + + /* + * Alloc mem to store phandle and index info of WSA device, if already + * registered with ALSA core + */ + wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs, + sizeof(struct msm_wsa881x_dev_info), + GFP_KERNEL); + if (!wsa881x_dev_info) { + ret = -ENOMEM; + goto err; + } + + /* + * search and check whether all WSA devices are already + * registered with ALSA core or not. If found a node, store + * the node and the index in a local array of struct for later + * use. + */ + for (i = 0; i < wsa_dev_cnt; i++) { + wsa_of_node = of_parse_phandle(pdev->dev.of_node, + "qcom,wsa-devs", i); + if (unlikely(!wsa_of_node)) { + /* we should not be here */ + dev_err(&pdev->dev, + "%s: wsa dev node is not present\n", + __func__); + ret = -EINVAL; + goto err_free_dev_info; + } + if (soc_find_component(wsa_of_node, NULL)) { + /* WSA device registered with ALSA core */ + wsa881x_dev_info[found].of_node = wsa_of_node; + wsa881x_dev_info[found].index = i; + found++; + if (found == wsa_max_devs) + break; + } + } + + if (found < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: failed to find %d components. Found only %d\n", + __func__, wsa_max_devs, found); + return -EPROBE_DEFER; + } + dev_info(&pdev->dev, + "%s: found %d wsa881x devices registered with ALSA core\n", + __func__, found); + + card->num_aux_devs = wsa_max_devs; + card->num_configs = wsa_max_devs; + + /* Alloc array of AUX devs struct */ + msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_aux_dev), + GFP_KERNEL); + if (!msm_aux_dev) { + ret = -ENOMEM; + goto err_free_dev_info; + } + + /* Alloc array of codec conf struct */ + msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_codec_conf), + GFP_KERNEL); + if (!msm_codec_conf) { + ret = -ENOMEM; + goto err_free_aux_dev; + } + + for (i = 0; i < card->num_aux_devs; i++) { + dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN, + GFP_KERNEL); + if (!dev_name_str) { + ret = -ENOMEM; + goto err_free_cdc_conf; + } + + ret = of_property_read_string_index(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix", + wsa881x_dev_info[i].index, + wsa_auxdev_name_prefix); + if (ret) { + dev_err(&pdev->dev, + "%s: failed to read wsa aux dev prefix, ret = %d\n", + __func__, ret); + ret = -EINVAL; + goto err_free_dev_name_str; + } + + snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i); + msm_aux_dev[i].name = dev_name_str; + msm_aux_dev[i].codec_name = NULL; + msm_aux_dev[i].codec_of_node = + wsa881x_dev_info[i].of_node; + msm_aux_dev[i].init = msm_wsa881x_init; + msm_codec_conf[i].dev_name = NULL; + msm_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0]; + msm_codec_conf[i].of_node = + wsa881x_dev_info[i].of_node; + } + card->codec_conf = msm_codec_conf; + card->aux_dev = msm_aux_dev; + + return 0; + +err_free_dev_name_str: + devm_kfree(&pdev->dev, dev_name_str); +err_free_cdc_conf: + devm_kfree(&pdev->dev, msm_codec_conf); +err_free_aux_dev: + devm_kfree(&pdev->dev, msm_aux_dev); +err_free_dev_info: + devm_kfree(&pdev->dev, wsa881x_dev_info); +err: + return ret; +} + +static void msm_i2s_auxpcm_init(struct platform_device *pdev) +{ + struct resource *muxsel; + int count; + u32 mi2s_master_slave[MI2S_MAX]; + int ret; + char *str[PCM_I2S_SEL_MAX] = { + "lpaif_pri_mode_muxsel", + "lpaif_sec_mode_muxsel", + "lpaif_tert_mode_muxsel", + "lpaif_quat_mode_muxsel" + }; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_init(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + } + + for (count = 0; count < AUX_PCM_MAX; count++) { + mutex_init(&auxpcm_intf_conf[count].lock); + auxpcm_intf_conf[count].ref_cnt = 0; + } + + for (count = 0; count < PCM_I2S_SEL_MAX; count++) { + mutex_init(&mi2s_auxpcm_conf[count].lock); + mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr = NULL; + } + + for (count = 0; count < PCM_I2S_SEL_MAX; count++) { + muxsel = platform_get_resource_byname(pdev, IORESOURCE_MEM, + str[count]); + if (muxsel) { + mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr + = ioremap(muxsel->start, resource_size(muxsel)); + } + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-master", + mi2s_master_slave, MI2S_MAX); + if (ret) { + dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n", + __func__); + } else { + for (count = 0; count < MI2S_MAX; count++) { + mi2s_intf_conf[count].msm_is_mi2s_master = + mi2s_master_slave[count]; + } + } +} + +static void msm_i2s_auxpcm_deinit(void) +{ + int count; + + for (count = 0; count < PCM_I2S_SEL_MAX; count++) { + if (mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr != + NULL) { + iounmap( + mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr); + mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr = NULL; + } + mutex_destroy(&mi2s_auxpcm_conf[count].lock); + } + + for (count = 0; count < AUX_PCM_MAX; count++) { + mutex_destroy(&auxpcm_intf_conf[count].lock); + auxpcm_intf_conf[count].ref_cnt = 0; + } + + for (count = 0; count < MI2S_MAX; count++) { + mutex_destroy(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + mi2s_intf_conf[count].msm_is_mi2s_master = 0; + } +} + +static int msm_asoc_machine_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card; + struct msm_asoc_mach_data *pdata; + const char *mbhc_audio_jack_type = NULL; + char *mclk_freq_prop_name; + const struct of_device_id *match; + int ret; + const char *usb_c_dt = "qcom,msm-mbhc-usbc-audio-supported"; + + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, "No platform supplied from device tree\n"); + return -EINVAL; + } + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct msm_asoc_mach_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + card = populate_snd_card_dailinks(&pdev->dev); + if (!card) { + dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); + ret = -EINVAL; + goto err; + } + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, pdata); + + ret = snd_soc_of_parse_card_name(card, "qcom,model"); + if (ret) { + dev_err(&pdev->dev, "parse card name failed, err:%d\n", + ret); + goto err; + } + + ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing"); + if (ret) { + dev_err(&pdev->dev, "parse audio routing failed, err:%d\n", + ret); + goto err; + } + + match = of_match_node(sdm845_asoc_machine_of_match, + pdev->dev.of_node); + if (!match) { + dev_err(&pdev->dev, "%s: no matched codec is found.\n", + __func__); + goto err; + } + + mclk_freq_prop_name = "qcom,tavil-mclk-clk-freq"; + + ret = of_property_read_u32(pdev->dev.of_node, + mclk_freq_prop_name, &pdata->mclk_freq); + if (ret) { + dev_err(&pdev->dev, + "Looking up %s property in node %s failed, err%d\n", + mclk_freq_prop_name, + pdev->dev.of_node->full_name, ret); + goto err; + } + + if (pdata->mclk_freq != CODEC_EXT_CLK_RATE) { + dev_err(&pdev->dev, "unsupported mclk freq %u\n", + pdata->mclk_freq); + ret = -EINVAL; + goto err; + } + + ret = msm_populate_dai_link_component_of_node(card); + if (ret) { + ret = -EPROBE_DEFER; + goto err; + } + ret = msm_init_wsa_dev(pdev, card); + if (ret) + goto err; + + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret == -EPROBE_DEFER) { + if (codec_reg_done) + ret = -EINVAL; + goto err; + } else if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); + goto err; + } + dev_info(&pdev->dev, "Sound card %s registered\n", card->name); + spdev = pdev; + + ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); + if (ret) { + dev_dbg(&pdev->dev, "%s: failed to add child nodes, ret=%d\n", + __func__, ret); + } else { + pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en1-gpio", 0); + if (!pdata->hph_en1_gpio_p) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,hph-en1-gpio", + pdev->dev.of_node->full_name); + } + + pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en0-gpio", 0); + if (!pdata->hph_en0_gpio_p) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,hph-en0-gpio", + pdev->dev.of_node->full_name); + } + } + + ret = of_property_read_string(pdev->dev.of_node, + "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type); + if (ret) { + dev_dbg(&pdev->dev, "Looking up %s property in node %s failed", + "qcom,mbhc-audio-jack-type", + pdev->dev.of_node->full_name); + dev_dbg(&pdev->dev, "Jack type properties set to default"); + } else { + if (!strcmp(mbhc_audio_jack_type, "4-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = false; + dev_dbg(&pdev->dev, "This hardware has 4 pole jack"); + } else if (!strcmp(mbhc_audio_jack_type, "5-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = true; + dev_dbg(&pdev->dev, "This hardware has 5 pole jack"); + } else if (!strcmp(mbhc_audio_jack_type, "6-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = true; + dev_dbg(&pdev->dev, "This hardware has 6 pole jack"); + } else { + wcd_mbhc_cfg.enable_anc_mic_detect = false; + dev_dbg(&pdev->dev, "Unknown value, set to default"); + } + } + /* + * Parse US-Euro gpio info from DT. Report no error if us-euro + * entry is not found in DT file as some targets do not support + * US-Euro detection + */ + pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,us-euro-gpios", 0); + if (!gpio_is_valid(pdata->us_euro_gpio)) + pdata->us_euro_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,us-euro-gpios", 0); + if (!gpio_is_valid(pdata->us_euro_gpio) && (!pdata->us_euro_gpio_p)) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,us-euro-gpios", pdev->dev.of_node->full_name); + } else { + dev_dbg(&pdev->dev, "%s detected", + "qcom,us-euro-gpios"); + wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; + } + + if (of_find_property(pdev->dev.of_node, usb_c_dt, NULL)) + wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; + + ret = msm_prepare_us_euro(card); + if (ret) + dev_dbg(&pdev->dev, "msm_prepare_us_euro failed (%d)\n", + ret); + + /* Parse pinctrl info from devicetree */ + ret = msm_get_pinctrl(pdev); + if (!ret) { + pr_debug("%s: pinctrl parsing successful\n", __func__); + } else { + dev_dbg(&pdev->dev, + "%s: Parsing pinctrl failed with %d. Cannot use Ports\n", + __func__, ret); + ret = 0; + } + + msm_i2s_auxpcm_init(pdev); + + is_initial_boot = true; + ret = audio_notifier_register("sdm845", AUDIO_NOTIFIER_ADSP_DOMAIN, + &service_nb); + if (ret < 0) + pr_err("%s: Audio notifier register failed ret = %d\n", + __func__, ret); + + return 0; +err: + msm_release_pinctrl(pdev); + devm_kfree(&pdev->dev, pdata); + return ret; +} + +static int msm_asoc_machine_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + + if (pdata->us_euro_gpio > 0) { + gpio_free(pdata->us_euro_gpio); + pdata->us_euro_gpio = 0; + } + msm_i2s_auxpcm_deinit(); + + msm_release_pinctrl(pdev); + snd_soc_unregister_card(card); + return 0; +} + +static struct platform_driver sdm845_asoc_machine_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = sdm845_asoc_machine_of_match, + }, + .probe = msm_asoc_machine_probe, + .remove = msm_asoc_machine_remove, +}; +module_platform_driver(sdm845_asoc_machine_driver); + +MODULE_DESCRIPTION("ALSA SoC msm"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, sdm845_asoc_machine_of_match); -- GitLab From 3d0e01d5bef22fa3e2a2171a55343f644ede1480 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 28 Jul 2017 12:46:23 +0530 Subject: [PATCH 0003/1645] autoconf: config file support for audio techpack for sdm845 New conf files are required to enable config for audio techpack. Add respective files for SDM845. This provides required config to compile required files for SDM845 audio. Change-Id: Ic93d0df0da03d7f891267994380729602ce64c65 Signed-off-by: Laxminath Kasam --- config/sdm845auto.conf | 41 ++++++++++++++++++++++++++++++ config/sdm845autoconf.h | 55 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 config/sdm845auto.conf create mode 100644 config/sdm845autoconf.h diff --git a/config/sdm845auto.conf b/config/sdm845auto.conf new file mode 100644 index 000000000000..f9a7748a3fde --- /dev/null +++ b/config/sdm845auto.conf @@ -0,0 +1,41 @@ +CONFIG_WCD934X_CODEC=y +CONFIG_WCD9335_CODEC=y +CONFIG_PINCTRL_WCD=y +CONFIG_SND_SOC_WCD934X=y +CONFIG_AUDIO_EXT_CLK=y +CONFIG_SND_SOC_WCD9XXX_V2=y +CONFIG_SND_SOC_WCD_MBHC=y +CONFIG_SND_SOC_WSA881X=y +CONFIG_SND_SOC_WCD_DSP_MGR=y +CONFIG_SND_SOC_WCD_SPI=y +CONFIG_SND_SOC_WCD934X=y +CONFIG_SND_SOC_WCD934X_MBHC=y +CONFIG_SND_SOC_WCD934X_DSD=y +CONFIG_MSM_QDSP6V2_CODECS=y +CONFIG_MSM_ULTRASOUND=y +CONFIG_MSM_QDSP6_APRV2_GLINK=y +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y +CONFIG_MSM_ADSP_LOADER=y +CONFIG_REGMAP_SWR=y +CONFIG_MSM_QDSP6_SSR=y +CONFIG_MSM_QDSP6_PDR=y +CONFIG_MSM_QDSP6_NOTIFIER=y +CONFIG_MSM_CDSP_LOADER=y +CONFIG_SND_SOC_MSM_HOSTLESS_PCM=y +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y +CONFIG_SND_SOC_SDM845=y +CONFIG_MSM_GLINK_SPI_XPRT=y +CONFIG_SOUNDWIRE=y +CONFIG_SOUNDWIRE_WCD_CTRL=y +CONFIG_SND_SOC_QDSP6V2=y +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y +CONFIG_MSM_CDC_PINCTRL=y +CONFIG_WCD9XXX_CODEC_CORE=y +CONFIG_QTI_PP=y +CONFIG_SND_HWDEP=y +CONFIG_DTS_EAGLE=y +CONFIG_DOLBY_DS2=y +CONFIG_DOLBY_LICENSE=y +CONFIG_DTS_SRS_TM=y +CONFIG_SND_SOC_MACHINE_SDM845=y +CONFIG_SND_SOC_MSM_STUB=y diff --git a/config/sdm845autoconf.h b/config/sdm845autoconf.h new file mode 100644 index 000000000000..6c3bb330656d --- /dev/null +++ b/config/sdm845autoconf.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define CONFIG_WCD934X_CODEC 1 +#define CONFIG_WCD9335_CODEC 1 +#define CONFIG_PINCTRL_WCD 1 +#define CONFIG_SND_SOC_WCD934X 1 +#define CONFIG_AUDIO_EXT_CLK 1 +#define CONFIG_SND_SOC_WCD9XXX_V2 1 +#define CONFIG_SND_SOC_WCD_CPE 1 +#define CONFIG_SND_SOC_WCD_MBHC 1 +#define CONFIG_SND_SOC_WSA881X 1 +#define CONFIG_SND_SOC_WCD_DSP_MGR 1 +#define CONFIG_SND_SOC_WCD_SPI 1 +#define CONFIG_SND_SOC_WCD934X 1 +#define CONFIG_SND_SOC_WCD934X_MBHC 1 +#define CONFIG_SND_SOC_WCD934X_DSD 1 +#define CONFIG_MSM_QDSP6V2_CODECS 1 +#define CONFIG_MSM_ULTRASOUND 1 +#define CONFIG_MSM_QDSP6_APRV2_GLINK 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_MSM_ADSP_LOADER 1 +#define CONFIG_REGMAP_SWR 1 +#define CONFIG_MSM_QDSP6_SSR 1 +#define CONFIG_MSM_QDSP6_PDR 1 +#define CONFIG_MSM_QDSP6_NOTIFIER 1 +#define CONFIG_MSM_CDSP_LOADER 1 +#define CONFIG_SND_SOC_MSM_HOSTLESS_PCM 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_SND_SOC_SDM845 1 +#define CONFIG_MSM_GLINK_SPI_XPRT 1 +#define CONFIG_SOUNDWIRE 1 +#define CONFIG_SOUNDWIRE_WCD_CTRL 1 +#define CONFIG_SND_SOC_WCD_MBHC_ADC 1 +#define CONFIG_SND_SOC_QDSP6V2 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_MSM_CDC_PINCTRL 1 +#define CONFIG_QTI_PP 1 +#define CONFIG_SND_HWDEP 1 +#define CONFIG_DTS_EAGLE 1 +#define CONFIG_DOLBY_DS2 1 +#define CONFIG_DOLBY_LICENSE 1 +#define CONFIG_DTS_SRS_TM 1 +#define CONFIG_WCD9XXX_CODEC_CORE 1 +#define CONFIG_SND_SOC_MSM_STUB 1 -- GitLab From 366f750416cac34ccf369198ba38c4e9ff3799cc Mon Sep 17 00:00:00 2001 From: Asish Bhattacharya Date: Tue, 25 Jul 2017 15:15:56 +0530 Subject: [PATCH 0004/1645] audio-lnx: Propagate changes from kernel for msm_sdw/hdmi Add snapshot for msm_sdw codec/hdmi codec drivers for SDM targets. The code is migrated from msm-4.9 kernel at the below cutoff - (8efe4a8d64f: "ARM: dts: msm: add rotator vbif memtype setting to sdm845") This changes are done to migrate msm_sdw/hdmi codec drivers to this new audio kernel techpack. Change-Id: Ia807b87a7c67957512a6b38cc62ae9cb5223c8b2 Signed-off-by: Asish Bhattacharya --- sound/soc/codecs/msm_hdmi_codec_rx.c | 562 +++++ sound/soc/codecs/msm_sdw/Kconfig | 6 + sound/soc/codecs/msm_sdw/Makefile | 3 + sound/soc/codecs/msm_sdw/msm-sdw-tables.c | 319 +++ sound/soc/codecs/msm_sdw/msm_sdw.h | 170 ++ sound/soc/codecs/msm_sdw/msm_sdw_cdc.c | 2007 ++++++++++++++++++ sound/soc/codecs/msm_sdw/msm_sdw_cdc_utils.c | 211 ++ sound/soc/codecs/msm_sdw/msm_sdw_registers.h | 126 ++ sound/soc/codecs/msm_sdw/msm_sdw_regmap.c | 161 ++ 9 files changed, 3565 insertions(+) create mode 100644 sound/soc/codecs/msm_hdmi_codec_rx.c create mode 100644 sound/soc/codecs/msm_sdw/Kconfig create mode 100644 sound/soc/codecs/msm_sdw/Makefile create mode 100644 sound/soc/codecs/msm_sdw/msm-sdw-tables.c create mode 100644 sound/soc/codecs/msm_sdw/msm_sdw.h create mode 100644 sound/soc/codecs/msm_sdw/msm_sdw_cdc.c create mode 100644 sound/soc/codecs/msm_sdw/msm_sdw_cdc_utils.c create mode 100644 sound/soc/codecs/msm_sdw/msm_sdw_registers.h create mode 100644 sound/soc/codecs/msm_sdw/msm_sdw_regmap.c diff --git a/sound/soc/codecs/msm_hdmi_codec_rx.c b/sound/soc/codecs/msm_hdmi_codec_rx.c new file mode 100644 index 000000000000..46cfe7dede26 --- /dev/null +++ b/sound/soc/codecs/msm_hdmi_codec_rx.c @@ -0,0 +1,562 @@ +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MSM_EXT_DISP_PCM_RATES SNDRV_PCM_RATE_48000 +#define AUD_EXT_DISP_ACK_DISCONNECT (AUDIO_ACK_CONNECT ^ AUDIO_ACK_CONNECT) +#define AUD_EXT_DISP_ACK_CONNECT (AUDIO_ACK_CONNECT) +#define AUD_EXT_DISP_ACK_ENABLE (AUDIO_ACK_SET_ENABLE | AUDIO_ACK_ENABLE) + +static const char *const ext_disp_audio_type_text[] = {"None", "HDMI", "DP"}; +static const char *const ext_disp_audio_ack_text[] = {"Disconnect", "Connect", + "Ack_Enable"}; + +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_audio_type, ext_disp_audio_type_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_audio_ack_state, + ext_disp_audio_ack_text); + +struct msm_ext_disp_audio_codec_rx_data { + struct platform_device *ext_disp_core_pdev; + struct msm_ext_disp_audio_codec_ops ext_disp_ops; + int cable_status; +}; + +static int msm_ext_disp_edid_ctl_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct msm_ext_disp_audio_codec_rx_data *codec_data; + struct msm_ext_disp_audio_edid_blk edid_blk; + int rc; + + codec_data = snd_soc_codec_get_drvdata(codec); + + if (!codec_data) { + dev_err(codec->dev, "%s: codec_data is NULL\n", __func__); + return -EINVAL; + } + + if (!codec_data->ext_disp_ops.get_audio_edid_blk) { + dev_dbg(codec->dev, "%s: get_audio_edid_blk() is NULL\n", + __func__); + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = 0; + return 0; + } + + rc = codec_data->ext_disp_ops.get_audio_edid_blk( + codec_data->ext_disp_core_pdev, &edid_blk); + if (rc >= 0) { + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = edid_blk.audio_data_blk_size + + edid_blk.spk_alloc_data_blk_size; + } + + dev_dbg(codec->dev, "%s: count: %d\n", __func__, uinfo->count); + + return rc; +} + +static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct msm_ext_disp_audio_codec_rx_data *codec_data; + struct msm_ext_disp_audio_edid_blk edid_blk; + int rc; + + codec_data = snd_soc_codec_get_drvdata(codec); + if (!codec_data || !codec_data->ext_disp_ops.get_audio_edid_blk) { + dev_err(codec->dev, "%s: codec_data or get_audio_edid_blk() is NULL\n", + __func__); + return -EINVAL; + } + + rc = codec_data->ext_disp_ops.get_audio_edid_blk( + codec_data->ext_disp_core_pdev, &edid_blk); + if (rc >= 0) { + if (sizeof(ucontrol->value.bytes.data) < + (edid_blk.audio_data_blk_size + + edid_blk.spk_alloc_data_blk_size)) { + dev_err(codec->dev, + "%s: Not enough memory to copy EDID data\n", + __func__); + return -ENOMEM; + } + + memcpy(ucontrol->value.bytes.data, + edid_blk.audio_data_blk, + edid_blk.audio_data_blk_size); + memcpy((ucontrol->value.bytes.data + + edid_blk.audio_data_blk_size), + edid_blk.spk_alloc_data_blk, + edid_blk.spk_alloc_data_blk_size); + + dev_dbg(codec->dev, "%s: data_blk_size:%d, spk_alloc_data_blk_size:%d\n", + __func__, edid_blk.audio_data_blk_size, + edid_blk.spk_alloc_data_blk_size); + } + + return rc; +} + +static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct msm_ext_disp_audio_codec_rx_data *codec_data; + enum msm_ext_disp_cable_state cable_state; + enum msm_ext_disp_type disp_type; + int rc; + + codec_data = snd_soc_codec_get_drvdata(codec); + if (!codec_data || + !codec_data->ext_disp_ops.get_audio_edid_blk || + !codec_data->ext_disp_ops.get_intf_id) { + dev_err(codec->dev, "%s: codec_data, get_audio_edid_blk() or get_intf_id is NULL\n", + __func__); + return -EINVAL; + } + + cable_state = codec_data->ext_disp_ops.cable_status( + codec_data->ext_disp_core_pdev, 1); + if (cable_state < 0) { + dev_err(codec->dev, "%s: Error retrieving cable state from ext_disp, err:%d\n", + __func__, cable_state); + rc = cable_state; + goto done; + } + + codec_data->cable_status = cable_state; + if (cable_state == EXT_DISPLAY_CABLE_DISCONNECT) { + dev_err(codec->dev, "%s: Display cable disconnected\n", + __func__); + ucontrol->value.integer.value[0] = 0; + rc = 0; + goto done; + } + + disp_type = codec_data->ext_disp_ops.get_intf_id( + codec_data->ext_disp_core_pdev); + if (disp_type >= 0) { + switch (disp_type) { + case EXT_DISPLAY_TYPE_DP: + ucontrol->value.integer.value[0] = 2; + rc = 0; + break; + case EXT_DISPLAY_TYPE_HDMI: + ucontrol->value.integer.value[0] = 1; + rc = 0; + break; + default: + rc = -EINVAL; + dev_err(codec->dev, "%s: Invalid disp_type:%d\n", + __func__, disp_type); + goto done; + } + dev_dbg(codec->dev, "%s: Display type: %d\n", + __func__, disp_type); + } else { + dev_err(codec->dev, "%s: Error retrieving disp_type from ext_disp, err:%d\n", + __func__, disp_type); + rc = disp_type; + } + +done: + return rc; +} + +static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct msm_ext_disp_audio_codec_rx_data *codec_data; + u32 ack_state = 0; + int rc; + + codec_data = snd_soc_codec_get_drvdata(codec); + if (!codec_data || + !codec_data->ext_disp_ops.acknowledge) { + dev_err(codec->dev, + "%s: codec_data or ops acknowledge() is NULL\n", + __func__); + rc = -EINVAL; + goto done; + } + + switch (ucontrol->value.enumerated.item[0]) { + case 0: + ack_state = AUD_EXT_DISP_ACK_DISCONNECT; + break; + case 1: + ack_state = AUD_EXT_DISP_ACK_CONNECT; + break; + case 2: + ack_state = AUD_EXT_DISP_ACK_ENABLE; + break; + default: + rc = -EINVAL; + dev_err(codec->dev, + "%s: invalid value %d for mixer ctl\n", + __func__, ucontrol->value.enumerated.item[0]); + goto done; + } + dev_dbg(codec->dev, "%s: control %d, ack set value 0x%x\n", + __func__, ucontrol->value.enumerated.item[0], ack_state); + + rc = codec_data->ext_disp_ops.acknowledge( + codec_data->ext_disp_core_pdev, ack_state); + if (rc < 0) { + dev_err(codec->dev, "%s: error from acknowledge(), err:%d\n", + __func__, rc); + } + +done: + return rc; +} + +static const struct snd_kcontrol_new msm_ext_disp_codec_rx_controls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_READ | + SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "HDMI EDID", + .info = msm_ext_disp_edid_ctl_info, + .get = msm_ext_disp_edid_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ | + SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "Display Port EDID", + .info = msm_ext_disp_edid_ctl_info, + .get = msm_ext_disp_edid_get, + }, + SOC_ENUM_EXT("External Display Type", ext_disp_audio_type, + msm_ext_disp_audio_type_get, NULL), + SOC_ENUM_EXT("External Display Audio Ack", ext_disp_audio_ack_state, + NULL, msm_ext_disp_audio_ack_set), +}; + +static int msm_ext_disp_audio_codec_rx_dai_startup( + struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + int ret = 0; + struct msm_ext_disp_audio_codec_rx_data *codec_data = + dev_get_drvdata(dai->codec->dev); + + if (!codec_data || !codec_data->ext_disp_ops.cable_status) { + dev_err(dai->dev, "%s() codec_data or cable_status is null\n", + __func__); + return -EINVAL; + } + + codec_data->cable_status = + codec_data->ext_disp_ops.cable_status( + codec_data->ext_disp_core_pdev, 1); + if (codec_data->cable_status < 0) { + dev_err(dai->dev, + "%s() ext disp core is not ready (ret val = %d)\n", + __func__, codec_data->cable_status); + ret = codec_data->cable_status; + } else if (!codec_data->cable_status) { + dev_err(dai->dev, + "%s() ext disp cable is not connected (ret val = %d)\n", + __func__, codec_data->cable_status); + ret = -ENODEV; + } + + return ret; +} + +static int msm_ext_disp_audio_codec_rx_dai_hw_params( + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + u32 channel_allocation = 0; + u32 level_shift = 0; /* 0dB */ + bool down_mix = 0; + u32 num_channels = params_channels(params); + int rc = 0; + struct msm_ext_disp_audio_setup_params audio_setup_params = {0}; + + struct msm_ext_disp_audio_codec_rx_data *codec_data = + dev_get_drvdata(dai->codec->dev); + + if (!codec_data || !codec_data->ext_disp_ops.audio_info_setup) { + dev_err(dai->dev, "%s: codec_data or audio_info_setup is null\n", + __func__); + return -EINVAL; + } + + if (codec_data->cable_status < 0) { + dev_err_ratelimited(dai->dev, + "%s() ext disp core is not ready (ret val = %d)\n", + __func__, codec_data->cable_status); + return codec_data->cable_status; + } else if (!codec_data->cable_status) { + dev_err_ratelimited(dai->dev, + "%s() ext disp cable is not connected (ret val = %d)\n", + __func__, codec_data->cable_status); + return -ENODEV; + } + + /*refer to HDMI spec CEA-861-E: Table 28 Audio InfoFrame Data Byte 4*/ + switch (num_channels) { + case 2: + channel_allocation = 0; + break; + case 3: + channel_allocation = 0x02;/*default to FL/FR/FC*/ + audio_setup_params.sample_present = 0x3; + break; + case 4: + channel_allocation = 0x06;/*default to FL/FR/FC/RC*/ + audio_setup_params.sample_present = 0x7; + break; + case 5: + channel_allocation = 0x0A;/*default to FL/FR/FC/RR/RL*/ + audio_setup_params.sample_present = 0x7; + break; + case 6: + channel_allocation = 0x0B; + audio_setup_params.sample_present = 0x7; + break; + case 7: + channel_allocation = 0x12;/*default to FL/FR/FC/RL/RR/RRC/RLC*/ + audio_setup_params.sample_present = 0xf; + break; + case 8: + channel_allocation = 0x13; + audio_setup_params.sample_present = 0xf; + break; + default: + dev_err(dai->dev, "invalid Channels = %u\n", num_channels); + return -EINVAL; + } + + dev_dbg(dai->dev, + "%s() num_ch %u samplerate %u channel_allocation = %u\n", + __func__, num_channels, params_rate(params), + channel_allocation); + + audio_setup_params.sample_rate_hz = params_rate(params); + audio_setup_params.num_of_channels = num_channels; + audio_setup_params.channel_allocation = channel_allocation; + audio_setup_params.level_shift = level_shift; + audio_setup_params.down_mix = down_mix; + + rc = codec_data->ext_disp_ops.audio_info_setup( + codec_data->ext_disp_core_pdev, &audio_setup_params); + if (rc < 0) { + dev_err_ratelimited(dai->dev, + "%s() ext disp core is not ready, rc: %d\n", + __func__, rc); + } + + return rc; +} + +static void msm_ext_disp_audio_codec_rx_dai_shutdown( + struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + int rc; + + struct msm_ext_disp_audio_codec_rx_data *codec_data = + dev_get_drvdata(dai->codec->dev); + + if (!codec_data || !codec_data->ext_disp_ops.teardown_done || + !codec_data->ext_disp_ops.cable_status) { + dev_err(dai->dev, "%s: codec data or teardown_done or cable_status is null\n", + __func__); + return; + } + + rc = codec_data->ext_disp_ops.cable_status( + codec_data->ext_disp_core_pdev, 0); + if (rc < 0) { + dev_err(dai->dev, + "%s: ext disp core had problems releasing audio flag\n", + __func__); + } + + codec_data->ext_disp_ops.teardown_done( + codec_data->ext_disp_core_pdev); +} + +static int msm_ext_disp_audio_codec_rx_probe(struct snd_soc_codec *codec) +{ + struct msm_ext_disp_audio_codec_rx_data *codec_data; + struct device_node *of_node_parent = NULL; + + codec_data = kzalloc(sizeof(struct msm_ext_disp_audio_codec_rx_data), + GFP_KERNEL); + + if (!codec_data) { + dev_err(codec->dev, "%s(): fail to allocate dai data\n", + __func__); + return -ENOMEM; + } + + of_node_parent = of_get_parent(codec->dev->of_node); + if (!of_node_parent) { + dev_err(codec->dev, "%s(): Parent device tree node not found\n", + __func__); + kfree(codec_data); + return -ENODEV; + } + + codec_data->ext_disp_core_pdev = of_find_device_by_node(of_node_parent); + if (!codec_data->ext_disp_core_pdev) { + dev_err(codec->dev, "%s(): can't get parent pdev\n", __func__); + kfree(codec_data); + return -ENODEV; + } + + if (msm_ext_disp_register_audio_codec(codec_data->ext_disp_core_pdev, + &codec_data->ext_disp_ops)) { + dev_err(codec->dev, "%s(): can't register with ext disp core", + __func__); + kfree(codec_data); + return -ENODEV; + } + + dev_set_drvdata(codec->dev, codec_data); + + dev_dbg(codec->dev, "%s(): registered %s with ext disp core\n", + __func__, codec->component.name); + + return 0; +} + +static int msm_ext_disp_audio_codec_rx_remove(struct snd_soc_codec *codec) +{ + struct msm_ext_disp_audio_codec_rx_data *codec_data; + + codec_data = dev_get_drvdata(codec->dev); + kfree(codec_data); + + return 0; +} + +static struct snd_soc_dai_ops msm_ext_disp_audio_codec_rx_dai_ops = { + .startup = msm_ext_disp_audio_codec_rx_dai_startup, + .hw_params = msm_ext_disp_audio_codec_rx_dai_hw_params, + .shutdown = msm_ext_disp_audio_codec_rx_dai_shutdown +}; + +static struct snd_soc_dai_driver msm_ext_disp_audio_codec_rx_dais[] = { + { + .name = "msm_hdmi_audio_codec_rx_dai", + .playback = { + .stream_name = "HDMI Playback", + .channels_min = 1, + .channels_max = 8, + .rate_min = 48000, + .rate_max = 48000, + .rates = MSM_EXT_DISP_PCM_RATES, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = &msm_ext_disp_audio_codec_rx_dai_ops, + }, + { + .name = "msm_dp_audio_codec_rx_dai", + .playback = { + .stream_name = "Display Port Playback", + .channels_min = 1, + .channels_max = 8, + .rate_min = 48000, + .rate_max = 192000, + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + }, + .ops = &msm_ext_disp_audio_codec_rx_dai_ops, + }, +}; + +static struct snd_soc_codec_driver msm_ext_disp_audio_codec_rx_soc_driver = { + .probe = msm_ext_disp_audio_codec_rx_probe, + .remove = msm_ext_disp_audio_codec_rx_remove, + .component_driver = { + .controls = msm_ext_disp_codec_rx_controls, + .num_controls = ARRAY_SIZE(msm_ext_disp_codec_rx_controls), + }, +}; + +static int msm_ext_disp_audio_codec_rx_plat_probe( + struct platform_device *pdev) +{ + dev_dbg(&pdev->dev, "%s(): dev name %s\n", __func__, + dev_name(&pdev->dev)); + + return snd_soc_register_codec(&pdev->dev, + &msm_ext_disp_audio_codec_rx_soc_driver, + msm_ext_disp_audio_codec_rx_dais, + ARRAY_SIZE(msm_ext_disp_audio_codec_rx_dais)); +} + +static int msm_ext_disp_audio_codec_rx_plat_remove( + struct platform_device *pdev) +{ + snd_soc_unregister_codec(&pdev->dev); + return 0; +} +static const struct of_device_id msm_ext_disp_audio_codec_rx_dt_match[] = { + { .compatible = "qcom,msm-ext-disp-audio-codec-rx", }, + {} +}; +MODULE_DEVICE_TABLE(of, msm_ext_disp_audio_codec_rx_dt_match); + +static struct platform_driver msm_ext_disp_audio_codec_rx_driver = { + .driver = { + .name = "msm-ext-disp-audio-codec-rx", + .owner = THIS_MODULE, + .of_match_table = msm_ext_disp_audio_codec_rx_dt_match, + }, + .probe = msm_ext_disp_audio_codec_rx_plat_probe, + .remove = msm_ext_disp_audio_codec_rx_plat_remove, +}; + +static int __init msm_ext_disp_audio_codec_rx_init(void) +{ + int rc; + + rc = platform_driver_register(&msm_ext_disp_audio_codec_rx_driver); + if (rc) { + pr_err("%s: failed to register ext disp codec driver err:%d\n", + __func__, rc); + } + + return rc; +} +module_init(msm_ext_disp_audio_codec_rx_init); + +static void __exit msm_ext_disp_audio_codec_rx_exit(void) +{ + platform_driver_unregister(&msm_ext_disp_audio_codec_rx_driver); +} +module_exit(msm_ext_disp_audio_codec_rx_exit); + +MODULE_DESCRIPTION("MSM External Display Audio CODEC Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/msm_sdw/Kconfig b/sound/soc/codecs/msm_sdw/Kconfig new file mode 100644 index 000000000000..abd7c8c7dfb0 --- /dev/null +++ b/sound/soc/codecs/msm_sdw/Kconfig @@ -0,0 +1,6 @@ +config SND_SOC_MSM_SDW + tristate "MSM Internal soundwire codec" + help + MSM-based soundwire codec core driver + supported along with internal digital + codec core. diff --git a/sound/soc/codecs/msm_sdw/Makefile b/sound/soc/codecs/msm_sdw/Makefile new file mode 100644 index 000000000000..64e932b9d262 --- /dev/null +++ b/sound/soc/codecs/msm_sdw/Makefile @@ -0,0 +1,3 @@ +snd-soc-msm-sdw-objs := msm_sdw_cdc.o msm_sdw_regmap.o msm-sdw-tables.o msm_sdw_cdc_utils.o +obj-$(CONFIG_SND_SOC_MSM_SDW) += snd-soc-msm-sdw.o +ccflags-y += -I$(srctree)/sound/soc/msm diff --git a/sound/soc/codecs/msm_sdw/msm-sdw-tables.c b/sound/soc/codecs/msm_sdw/msm-sdw-tables.c new file mode 100644 index 000000000000..1b51805bb92e --- /dev/null +++ b/sound/soc/codecs/msm_sdw/msm-sdw-tables.c @@ -0,0 +1,319 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "msm_sdw.h" + +const u8 msm_sdw_page_map[MSM_SDW_MAX_REGISTER] = { + [MSM_SDW_TX9_SPKR_PROT_PATH_CTL] = 0xa, + [MSM_SDW_TX9_SPKR_PROT_PATH_CFG0] = 0xa, + [MSM_SDW_TX10_SPKR_PROT_PATH_CTL] = 0xa, + [MSM_SDW_TX10_SPKR_PROT_PATH_CFG0] = 0xa, + [MSM_SDW_TX11_SPKR_PROT_PATH_CTL] = 0xa, + [MSM_SDW_TX11_SPKR_PROT_PATH_CFG0] = 0xa, + [MSM_SDW_TX12_SPKR_PROT_PATH_CTL] = 0xa, + [MSM_SDW_TX12_SPKR_PROT_PATH_CFG0] = 0xa, + [MSM_SDW_COMPANDER7_CTL0] = 0xb, + [MSM_SDW_COMPANDER7_CTL1] = 0xb, + [MSM_SDW_COMPANDER7_CTL2] = 0xb, + [MSM_SDW_COMPANDER7_CTL3] = 0xb, + [MSM_SDW_COMPANDER7_CTL4] = 0xb, + [MSM_SDW_COMPANDER7_CTL5] = 0xb, + [MSM_SDW_COMPANDER7_CTL6] = 0xb, + [MSM_SDW_COMPANDER7_CTL7] = 0xb, + [MSM_SDW_COMPANDER8_CTL0] = 0xb, + [MSM_SDW_COMPANDER8_CTL1] = 0xb, + [MSM_SDW_COMPANDER8_CTL2] = 0xb, + [MSM_SDW_COMPANDER8_CTL3] = 0xb, + [MSM_SDW_COMPANDER8_CTL4] = 0xb, + [MSM_SDW_COMPANDER8_CTL5] = 0xb, + [MSM_SDW_COMPANDER8_CTL6] = 0xb, + [MSM_SDW_COMPANDER8_CTL7] = 0xb, + [MSM_SDW_RX7_RX_PATH_CTL] = 0xb, + [MSM_SDW_RX7_RX_PATH_CFG0] = 0xb, + [MSM_SDW_RX7_RX_PATH_CFG1] = 0xb, + [MSM_SDW_RX7_RX_PATH_CFG2] = 0xb, + [MSM_SDW_RX7_RX_VOL_CTL] = 0xb, + [MSM_SDW_RX7_RX_PATH_MIX_CTL] = 0xb, + [MSM_SDW_RX7_RX_PATH_MIX_CFG] = 0xb, + [MSM_SDW_RX7_RX_VOL_MIX_CTL] = 0xb, + [MSM_SDW_RX7_RX_PATH_SEC0] = 0xb, + [MSM_SDW_RX7_RX_PATH_SEC1] = 0xb, + [MSM_SDW_RX7_RX_PATH_SEC2] = 0xb, + [MSM_SDW_RX7_RX_PATH_SEC3] = 0xb, + [MSM_SDW_RX7_RX_PATH_SEC5] = 0xb, + [MSM_SDW_RX7_RX_PATH_SEC6] = 0xb, + [MSM_SDW_RX7_RX_PATH_SEC7] = 0xb, + [MSM_SDW_RX7_RX_PATH_MIX_SEC0] = 0xb, + [MSM_SDW_RX7_RX_PATH_MIX_SEC1] = 0xb, + [MSM_SDW_RX8_RX_PATH_CTL] = 0xb, + [MSM_SDW_RX8_RX_PATH_CFG0] = 0xb, + [MSM_SDW_RX8_RX_PATH_CFG1] = 0xb, + [MSM_SDW_RX8_RX_PATH_CFG2] = 0xb, + [MSM_SDW_RX8_RX_VOL_CTL] = 0xb, + [MSM_SDW_RX8_RX_PATH_MIX_CTL] = 0xb, + [MSM_SDW_RX8_RX_PATH_MIX_CFG] = 0xb, + [MSM_SDW_RX8_RX_VOL_MIX_CTL] = 0xb, + [MSM_SDW_RX8_RX_PATH_SEC0] = 0xb, + [MSM_SDW_RX8_RX_PATH_SEC1] = 0xb, + [MSM_SDW_RX8_RX_PATH_SEC2] = 0xb, + [MSM_SDW_RX8_RX_PATH_SEC3] = 0xb, + [MSM_SDW_RX8_RX_PATH_SEC5] = 0xb, + [MSM_SDW_RX8_RX_PATH_SEC6] = 0xb, + [MSM_SDW_RX8_RX_PATH_SEC7] = 0xb, + [MSM_SDW_RX8_RX_PATH_MIX_SEC0] = 0xb, + [MSM_SDW_RX8_RX_PATH_MIX_SEC1] = 0xb, + [MSM_SDW_BOOST0_BOOST_PATH_CTL] = 0xc, + [MSM_SDW_BOOST0_BOOST_CTL] = 0xc, + [MSM_SDW_BOOST0_BOOST_CFG1] = 0xc, + [MSM_SDW_BOOST0_BOOST_CFG2] = 0xc, + [MSM_SDW_BOOST1_BOOST_PATH_CTL] = 0xc, + [MSM_SDW_BOOST1_BOOST_CTL] = 0xc, + [MSM_SDW_BOOST1_BOOST_CFG1] = 0xc, + [MSM_SDW_BOOST1_BOOST_CFG2] = 0xc, + [MSM_SDW_AHB_BRIDGE_WR_DATA_0] = 0xc, + [MSM_SDW_AHB_BRIDGE_WR_DATA_1] = 0xc, + [MSM_SDW_AHB_BRIDGE_WR_DATA_2] = 0xc, + [MSM_SDW_AHB_BRIDGE_WR_DATA_3] = 0xc, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_0] = 0xc, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_1] = 0xc, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_2] = 0xc, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_3] = 0xc, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_0] = 0xc, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_1] = 0xc, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_2] = 0xc, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_3] = 0xc, + [MSM_SDW_AHB_BRIDGE_RD_DATA_0] = 0xc, + [MSM_SDW_AHB_BRIDGE_RD_DATA_1] = 0xc, + [MSM_SDW_AHB_BRIDGE_RD_DATA_2] = 0xc, + [MSM_SDW_AHB_BRIDGE_RD_DATA_3] = 0xc, + [MSM_SDW_AHB_BRIDGE_ACCESS_CFG] = 0xc, + [MSM_SDW_AHB_BRIDGE_ACCESS_STATUS] = 0xc, + [MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL] = 0xd, + [MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL] = 0xd, + [MSM_SDW_CLK_RST_CTRL_SWR_CONTROL] = 0xd, + [MSM_SDW_TOP_TOP_CFG0] = 0xd, + [MSM_SDW_TOP_TOP_CFG1] = 0xd, + [MSM_SDW_TOP_RX_I2S_CTL] = 0xd, + [MSM_SDW_TOP_TX_I2S_CTL] = 0xd, + [MSM_SDW_TOP_I2S_CLK] = 0xd, + [MSM_SDW_TOP_RX7_PATH_INPUT0_MUX] = 0xd, + [MSM_SDW_TOP_RX7_PATH_INPUT1_MUX] = 0xd, + [MSM_SDW_TOP_RX8_PATH_INPUT0_MUX] = 0xd, + [MSM_SDW_TOP_RX8_PATH_INPUT1_MUX] = 0xd, + [MSM_SDW_TOP_FREQ_MCLK] = 0xd, + [MSM_SDW_TOP_DEBUG_BUS_SEL] = 0xd, + [MSM_SDW_TOP_DEBUG_EN] = 0xd, + [MSM_SDW_TOP_I2S_RESET] = 0xd, + [MSM_SDW_TOP_BLOCKS_RESET] = 0xd, +}; + +const u8 msm_sdw_reg_readable[MSM_SDW_MAX_REGISTER] = { + [MSM_SDW_PAGE_REGISTER] = 1, + [MSM_SDW_TX9_SPKR_PROT_PATH_CTL] = 1, + [MSM_SDW_TX9_SPKR_PROT_PATH_CFG0] = 1, + [MSM_SDW_TX10_SPKR_PROT_PATH_CTL] = 1, + [MSM_SDW_TX10_SPKR_PROT_PATH_CFG0] = 1, + [MSM_SDW_TX11_SPKR_PROT_PATH_CTL] = 1, + [MSM_SDW_TX11_SPKR_PROT_PATH_CFG0] = 1, + [MSM_SDW_TX12_SPKR_PROT_PATH_CTL] = 1, + [MSM_SDW_TX12_SPKR_PROT_PATH_CFG0] = 1, + [MSM_SDW_COMPANDER7_CTL0] = 1, + [MSM_SDW_COMPANDER7_CTL1] = 1, + [MSM_SDW_COMPANDER7_CTL2] = 1, + [MSM_SDW_COMPANDER7_CTL3] = 1, + [MSM_SDW_COMPANDER7_CTL4] = 1, + [MSM_SDW_COMPANDER7_CTL5] = 1, + [MSM_SDW_COMPANDER7_CTL6] = 1, + [MSM_SDW_COMPANDER7_CTL7] = 1, + [MSM_SDW_COMPANDER8_CTL0] = 1, + [MSM_SDW_COMPANDER8_CTL1] = 1, + [MSM_SDW_COMPANDER8_CTL2] = 1, + [MSM_SDW_COMPANDER8_CTL3] = 1, + [MSM_SDW_COMPANDER8_CTL4] = 1, + [MSM_SDW_COMPANDER8_CTL5] = 1, + [MSM_SDW_COMPANDER8_CTL6] = 1, + [MSM_SDW_COMPANDER8_CTL7] = 1, + [MSM_SDW_RX7_RX_PATH_CTL] = 1, + [MSM_SDW_RX7_RX_PATH_CFG0] = 1, + [MSM_SDW_RX7_RX_PATH_CFG1] = 1, + [MSM_SDW_RX7_RX_PATH_CFG2] = 1, + [MSM_SDW_RX7_RX_VOL_CTL] = 1, + [MSM_SDW_RX7_RX_PATH_MIX_CTL] = 1, + [MSM_SDW_RX7_RX_PATH_MIX_CFG] = 1, + [MSM_SDW_RX7_RX_VOL_MIX_CTL] = 1, + [MSM_SDW_RX7_RX_PATH_SEC0] = 1, + [MSM_SDW_RX7_RX_PATH_SEC1] = 1, + [MSM_SDW_RX7_RX_PATH_SEC2] = 1, + [MSM_SDW_RX7_RX_PATH_SEC3] = 1, + [MSM_SDW_RX7_RX_PATH_SEC5] = 1, + [MSM_SDW_RX7_RX_PATH_SEC6] = 1, + [MSM_SDW_RX7_RX_PATH_SEC7] = 1, + [MSM_SDW_RX7_RX_PATH_MIX_SEC0] = 1, + [MSM_SDW_RX7_RX_PATH_MIX_SEC1] = 1, + [MSM_SDW_RX8_RX_PATH_CTL] = 1, + [MSM_SDW_RX8_RX_PATH_CFG0] = 1, + [MSM_SDW_RX8_RX_PATH_CFG1] = 1, + [MSM_SDW_RX8_RX_PATH_CFG2] = 1, + [MSM_SDW_RX8_RX_VOL_CTL] = 1, + [MSM_SDW_RX8_RX_PATH_MIX_CTL] = 1, + [MSM_SDW_RX8_RX_PATH_MIX_CFG] = 1, + [MSM_SDW_RX8_RX_VOL_MIX_CTL] = 1, + [MSM_SDW_RX8_RX_PATH_SEC0] = 1, + [MSM_SDW_RX8_RX_PATH_SEC1] = 1, + [MSM_SDW_RX8_RX_PATH_SEC2] = 1, + [MSM_SDW_RX8_RX_PATH_SEC3] = 1, + [MSM_SDW_RX8_RX_PATH_SEC5] = 1, + [MSM_SDW_RX8_RX_PATH_SEC6] = 1, + [MSM_SDW_RX8_RX_PATH_SEC7] = 1, + [MSM_SDW_RX8_RX_PATH_MIX_SEC0] = 1, + [MSM_SDW_RX8_RX_PATH_MIX_SEC1] = 1, + [MSM_SDW_BOOST0_BOOST_PATH_CTL] = 1, + [MSM_SDW_BOOST0_BOOST_CTL] = 1, + [MSM_SDW_BOOST0_BOOST_CFG1] = 1, + [MSM_SDW_BOOST0_BOOST_CFG2] = 1, + [MSM_SDW_BOOST1_BOOST_PATH_CTL] = 1, + [MSM_SDW_BOOST1_BOOST_CTL] = 1, + [MSM_SDW_BOOST1_BOOST_CFG1] = 1, + [MSM_SDW_BOOST1_BOOST_CFG2] = 1, + [MSM_SDW_AHB_BRIDGE_WR_DATA_0] = 1, + [MSM_SDW_AHB_BRIDGE_WR_DATA_1] = 1, + [MSM_SDW_AHB_BRIDGE_WR_DATA_2] = 1, + [MSM_SDW_AHB_BRIDGE_WR_DATA_3] = 1, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_0] = 1, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_1] = 1, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_2] = 1, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_3] = 1, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_0] = 1, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_1] = 1, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_2] = 1, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_3] = 1, + [MSM_SDW_AHB_BRIDGE_RD_DATA_0] = 1, + [MSM_SDW_AHB_BRIDGE_RD_DATA_1] = 1, + [MSM_SDW_AHB_BRIDGE_RD_DATA_2] = 1, + [MSM_SDW_AHB_BRIDGE_RD_DATA_3] = 1, + [MSM_SDW_AHB_BRIDGE_ACCESS_CFG] = 1, + [MSM_SDW_AHB_BRIDGE_ACCESS_STATUS] = 1, + [MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL] = 1, + [MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL] = 1, + [MSM_SDW_CLK_RST_CTRL_SWR_CONTROL] = 1, + [MSM_SDW_TOP_TOP_CFG0] = 1, + [MSM_SDW_TOP_TOP_CFG1] = 1, + [MSM_SDW_TOP_RX_I2S_CTL] = 1, + [MSM_SDW_TOP_TX_I2S_CTL] = 1, + [MSM_SDW_TOP_RX7_PATH_INPUT0_MUX] = 1, + [MSM_SDW_TOP_RX7_PATH_INPUT1_MUX] = 1, + [MSM_SDW_TOP_RX8_PATH_INPUT0_MUX] = 1, + [MSM_SDW_TOP_RX8_PATH_INPUT1_MUX] = 1, + [MSM_SDW_TOP_FREQ_MCLK] = 1, + [MSM_SDW_TOP_DEBUG_BUS_SEL] = 1, + [MSM_SDW_TOP_DEBUG_EN] = 1, + [MSM_SDW_TOP_I2S_RESET] = 1, + [MSM_SDW_TOP_BLOCKS_RESET] = 1, +}; + +const u8 msm_sdw_reg_writeable[MSM_SDW_MAX_REGISTER] = { + [MSM_SDW_PAGE_REGISTER] = 1, + [MSM_SDW_TX9_SPKR_PROT_PATH_CTL] = 1, + [MSM_SDW_TX9_SPKR_PROT_PATH_CFG0] = 1, + [MSM_SDW_TX10_SPKR_PROT_PATH_CTL] = 1, + [MSM_SDW_TX10_SPKR_PROT_PATH_CFG0] = 1, + [MSM_SDW_TX11_SPKR_PROT_PATH_CTL] = 1, + [MSM_SDW_TX11_SPKR_PROT_PATH_CFG0] = 1, + [MSM_SDW_TX12_SPKR_PROT_PATH_CTL] = 1, + [MSM_SDW_TX12_SPKR_PROT_PATH_CFG0] = 1, + [MSM_SDW_COMPANDER7_CTL0] = 1, + [MSM_SDW_COMPANDER7_CTL1] = 1, + [MSM_SDW_COMPANDER7_CTL2] = 1, + [MSM_SDW_COMPANDER7_CTL3] = 1, + [MSM_SDW_COMPANDER7_CTL4] = 1, + [MSM_SDW_COMPANDER7_CTL5] = 1, + [MSM_SDW_COMPANDER7_CTL7] = 1, + [MSM_SDW_COMPANDER8_CTL0] = 1, + [MSM_SDW_COMPANDER8_CTL1] = 1, + [MSM_SDW_COMPANDER8_CTL2] = 1, + [MSM_SDW_COMPANDER8_CTL3] = 1, + [MSM_SDW_COMPANDER8_CTL4] = 1, + [MSM_SDW_COMPANDER8_CTL5] = 1, + [MSM_SDW_COMPANDER8_CTL7] = 1, + [MSM_SDW_RX7_RX_PATH_CTL] = 1, + [MSM_SDW_RX7_RX_PATH_CFG0] = 1, + [MSM_SDW_RX7_RX_PATH_CFG1] = 1, + [MSM_SDW_RX7_RX_PATH_CFG2] = 1, + [MSM_SDW_RX7_RX_VOL_CTL] = 1, + [MSM_SDW_RX7_RX_PATH_MIX_CTL] = 1, + [MSM_SDW_RX7_RX_PATH_MIX_CFG] = 1, + [MSM_SDW_RX7_RX_VOL_MIX_CTL] = 1, + [MSM_SDW_RX7_RX_PATH_SEC0] = 1, + [MSM_SDW_RX7_RX_PATH_SEC1] = 1, + [MSM_SDW_RX7_RX_PATH_SEC2] = 1, + [MSM_SDW_RX7_RX_PATH_SEC3] = 1, + [MSM_SDW_RX7_RX_PATH_SEC5] = 1, + [MSM_SDW_RX7_RX_PATH_SEC6] = 1, + [MSM_SDW_RX7_RX_PATH_SEC7] = 1, + [MSM_SDW_RX7_RX_PATH_MIX_SEC0] = 1, + [MSM_SDW_RX7_RX_PATH_MIX_SEC1] = 1, + [MSM_SDW_RX8_RX_PATH_CTL] = 1, + [MSM_SDW_RX8_RX_PATH_CFG0] = 1, + [MSM_SDW_RX8_RX_PATH_CFG1] = 1, + [MSM_SDW_RX8_RX_PATH_CFG2] = 1, + [MSM_SDW_RX8_RX_VOL_CTL] = 1, + [MSM_SDW_RX8_RX_PATH_MIX_CTL] = 1, + [MSM_SDW_RX8_RX_PATH_MIX_CFG] = 1, + [MSM_SDW_RX8_RX_VOL_MIX_CTL] = 1, + [MSM_SDW_RX8_RX_PATH_SEC0] = 1, + [MSM_SDW_RX8_RX_PATH_SEC1] = 1, + [MSM_SDW_RX8_RX_PATH_SEC2] = 1, + [MSM_SDW_RX8_RX_PATH_SEC3] = 1, + [MSM_SDW_RX8_RX_PATH_SEC5] = 1, + [MSM_SDW_RX8_RX_PATH_SEC6] = 1, + [MSM_SDW_RX8_RX_PATH_SEC7] = 1, + [MSM_SDW_RX8_RX_PATH_MIX_SEC0] = 1, + [MSM_SDW_RX8_RX_PATH_MIX_SEC1] = 1, + [MSM_SDW_BOOST0_BOOST_PATH_CTL] = 1, + [MSM_SDW_BOOST0_BOOST_CTL] = 1, + [MSM_SDW_BOOST0_BOOST_CFG1] = 1, + [MSM_SDW_BOOST0_BOOST_CFG2] = 1, + [MSM_SDW_BOOST1_BOOST_PATH_CTL] = 1, + [MSM_SDW_BOOST1_BOOST_CTL] = 1, + [MSM_SDW_BOOST1_BOOST_CFG1] = 1, + [MSM_SDW_BOOST1_BOOST_CFG2] = 1, + [MSM_SDW_AHB_BRIDGE_WR_DATA_0] = 1, + [MSM_SDW_AHB_BRIDGE_WR_DATA_1] = 1, + [MSM_SDW_AHB_BRIDGE_WR_DATA_2] = 1, + [MSM_SDW_AHB_BRIDGE_WR_DATA_3] = 1, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_0] = 1, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_1] = 1, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_2] = 1, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_3] = 1, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_0] = 1, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_1] = 1, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_2] = 1, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_3] = 1, + [MSM_SDW_AHB_BRIDGE_ACCESS_CFG] = 1, + [MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL] = 1, + [MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL] = 1, + [MSM_SDW_CLK_RST_CTRL_SWR_CONTROL] = 1, + [MSM_SDW_TOP_TOP_CFG0] = 1, + [MSM_SDW_TOP_TOP_CFG1] = 1, + [MSM_SDW_TOP_RX_I2S_CTL] = 1, + [MSM_SDW_TOP_TX_I2S_CTL] = 1, + [MSM_SDW_TOP_RX7_PATH_INPUT0_MUX] = 1, + [MSM_SDW_TOP_RX7_PATH_INPUT1_MUX] = 1, + [MSM_SDW_TOP_RX8_PATH_INPUT0_MUX] = 1, + [MSM_SDW_TOP_RX8_PATH_INPUT1_MUX] = 1, + [MSM_SDW_TOP_FREQ_MCLK] = 1, + [MSM_SDW_TOP_DEBUG_BUS_SEL] = 1, + [MSM_SDW_TOP_DEBUG_EN] = 1, + [MSM_SDW_TOP_I2S_RESET] = 1, + [MSM_SDW_TOP_BLOCKS_RESET] = 1, +}; diff --git a/sound/soc/codecs/msm_sdw/msm_sdw.h b/sound/soc/codecs/msm_sdw/msm_sdw.h new file mode 100644 index 000000000000..376ebc6c38db --- /dev/null +++ b/sound/soc/codecs/msm_sdw/msm_sdw.h @@ -0,0 +1,170 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef MSM_SDW_H +#define MSM_SDW_H + +#include +#include +#include "msm_sdw_registers.h" + +#define MSM_SDW_MAX_REGISTER 0x400 + +extern const struct regmap_config msm_sdw_regmap_config; +extern const u8 msm_sdw_page_map[MSM_SDW_MAX_REGISTER]; +extern const u8 msm_sdw_reg_readable[MSM_SDW_MAX_REGISTER]; +extern const u8 msm_sdw_reg_writeable[MSM_SDW_MAX_REGISTER]; + +enum { + MSM_SDW_RX4 = 0, + MSM_SDW_RX5, + MSM_SDW_RX_MAX, +}; + +enum { + MSM_SDW_TX0 = 0, + MSM_SDW_TX1, + MSM_SDW_TX_MAX, +}; + +enum { + COMP1, /* SPK_L */ + COMP2, /* SPK_R */ + COMP_MAX +}; + +/* + * Structure used to update codec + * register defaults after reset + */ +struct msm_sdw_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + +/* + * Selects compander and smart boost settings + * for a given speaker mode + */ +enum { + SPKR_MODE_DEFAULT, + SPKR_MODE_1, /* COMP Gain = 12dB, Smartboost Max = 5.5V */ +}; + +/* Rx path gain offsets */ +enum { + RX_GAIN_OFFSET_M1P5_DB, + RX_GAIN_OFFSET_0_DB, +}; + +struct msm_sdw_reg_val { + unsigned short reg; /* register address */ + u8 *buf; /* buffer to be written to reg. addr */ + int bytes; /* number of bytes to be written */ +}; + +/* Hold instance to soundwire platform device */ +struct msm_sdw_ctrl_data { + struct platform_device *sdw_pdev; +}; + +struct wcd_sdw_ctrl_platform_data { + void *handle; /* holds codec private data */ + int (*read)(void *handle, int reg); + int (*write)(void *handle, int reg, int val); + int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); + int (*clk)(void *handle, bool enable); + int (*handle_irq)(void *handle, + irqreturn_t (*swrm_irq_handler)(int irq, + void *data), + void *swrm_handle, + int action); +}; + +struct msm_sdw_priv { + struct device *dev; + struct mutex io_lock; + + int (*read_dev)(struct msm_sdw_priv *msm_sdw, unsigned short reg, + int bytes, void *dest); + int (*write_dev)(struct msm_sdw_priv *msm_sdw, unsigned short reg, + int bytes, void *src); + int (*multi_reg_write)(struct msm_sdw_priv *msm_sdw, const void *data, + size_t count); + struct snd_soc_codec *codec; + struct device_node *sdw_gpio_p; /* used by pinctrl API */ + /* SoundWire data structure */ + struct msm_sdw_ctrl_data *sdw_ctrl_data; + int nr; + + /* compander */ + int comp_enabled[COMP_MAX]; + int ear_spkr_gain; + + /* to track the status */ + unsigned long status_mask; + + struct work_struct msm_sdw_add_child_devices_work; + struct wcd_sdw_ctrl_platform_data sdw_plat_data; + + unsigned int vi_feed_value; + + struct mutex sdw_read_lock; + struct mutex sdw_write_lock; + struct mutex sdw_clk_lock; + int sdw_clk_users; + int sdw_mclk_users; + + int sdw_irq; + int int_mclk1_rsc_ref; + bool int_mclk1_enabled; + bool sdw_npl_clk_enabled; + struct mutex cdc_int_mclk1_mutex; + struct mutex sdw_npl_clk_mutex; + struct delayed_work disable_int_mclk1_work; + struct afe_clk_set sdw_cdc_core_clk; + struct afe_clk_set sdw_npl_clk; + struct notifier_block service_nb; + int (*sdw_cdc_gpio_fn)(bool enable, struct snd_soc_codec *codec); + bool dev_up; + + int spkr_gain_offset; + int spkr_mode; + struct mutex codec_mutex; + int rx_4_count; + int rx_5_count; + u32 mclk_rate; + struct regmap *regmap; + + bool prev_pg_valid; + u8 prev_pg; + u32 sdw_base_addr; + char __iomem *sdw_base; + u32 version; + + /* Entry for version info */ + struct snd_info_entry *entry; + struct snd_info_entry *version_entry; +}; + +extern int msm_sdw_set_spkr_mode(struct snd_soc_codec *codec, int mode); +extern int msm_sdw_set_spkr_gain_offset(struct snd_soc_codec *codec, + int offset); +extern void msm_sdw_gpio_cb( + int (*sdw_cdc_gpio_fn)(bool enable, struct snd_soc_codec *codec), + struct snd_soc_codec *codec); +extern struct regmap *msm_sdw_regmap_init(struct device *dev, + const struct regmap_config *config); +extern int msm_sdw_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_codec *codec); +#endif diff --git a/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c b/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c new file mode 100644 index 000000000000..cfe42e00e358 --- /dev/null +++ b/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c @@ -0,0 +1,2007 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm_sdw.h" +#include "msm_sdw_registers.h" + +#define MSM_SDW_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000) +#define MSM_SDW_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_3LE) + +#define MSM_SDW_STRING_LEN 80 + +#define INT_MCLK1_FREQ 9600000 +#define SDW_NPL_FREQ 153600000 + +#define MSM_SDW_VERSION_1_0 0x0001 +#define MSM_SDW_VERSION_ENTRY_SIZE 32 + +/* + * 200 Milliseconds sufficient for DSP bring up in the modem + * after Sub System Restart + */ +#define ADSP_STATE_READY_TIMEOUT_MS 200 + +static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); +static struct snd_soc_dai_driver msm_sdw_dai[]; +static bool skip_irq = true; + +static int msm_sdw_config_ear_spkr_gain(struct snd_soc_codec *codec, + int event, int gain_reg); +static int msm_sdw_config_compander(struct snd_soc_codec *, int, int); +static int msm_sdw_mclk_enable(struct msm_sdw_priv *msm_sdw, + int mclk_enable, bool dapm); +static int msm_int_enable_sdw_cdc_clk(struct msm_sdw_priv *msm_sdw, + int enable, bool dapm); + +enum { + VI_SENSE_1, + VI_SENSE_2, +}; + +enum { + AIF1_SDW_PB = 0, + AIF1_SDW_VIFEED, + NUM_CODEC_DAIS, +}; + +static const struct msm_sdw_reg_mask_val msm_sdw_spkr_default[] = { + {MSM_SDW_COMPANDER7_CTL3, 0x80, 0x80}, + {MSM_SDW_COMPANDER8_CTL3, 0x80, 0x80}, + {MSM_SDW_COMPANDER7_CTL7, 0x01, 0x01}, + {MSM_SDW_COMPANDER8_CTL7, 0x01, 0x01}, + {MSM_SDW_BOOST0_BOOST_CTL, 0x7C, 0x50}, + {MSM_SDW_BOOST1_BOOST_CTL, 0x7C, 0x50}, +}; + +static const struct msm_sdw_reg_mask_val msm_sdw_spkr_mode1[] = { + {MSM_SDW_COMPANDER7_CTL3, 0x80, 0x00}, + {MSM_SDW_COMPANDER8_CTL3, 0x80, 0x00}, + {MSM_SDW_COMPANDER7_CTL7, 0x01, 0x00}, + {MSM_SDW_COMPANDER8_CTL7, 0x01, 0x00}, + {MSM_SDW_BOOST0_BOOST_CTL, 0x7C, 0x44}, + {MSM_SDW_BOOST1_BOOST_CTL, 0x7C, 0x44}, +}; + +/** + * msm_sdw_set_spkr_gain_offset - offset the speaker path + * gain with the given offset value. + * + * @codec: codec instance + * @offset: Indicates speaker path gain offset value. + * + * Returns 0 on success or -EINVAL on error. + */ +int msm_sdw_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset) +{ + struct msm_sdw_priv *priv; + + if (!codec) { + pr_err("%s: NULL codec pointer!\n", __func__); + return -EINVAL; + } + + priv = snd_soc_codec_get_drvdata(codec); + if (!priv) + return -EINVAL; + + priv->spkr_gain_offset = offset; + return 0; +} +EXPORT_SYMBOL(msm_sdw_set_spkr_gain_offset); + +/** + * msm_sdw_set_spkr_mode - Configures speaker compander and smartboost + * settings based on speaker mode. + * + * @codec: codec instance + * @mode: Indicates speaker configuration mode. + * + * Returns 0 on success or -EINVAL on error. + */ +int msm_sdw_set_spkr_mode(struct snd_soc_codec *codec, int mode) +{ + struct msm_sdw_priv *priv; + int i; + const struct msm_sdw_reg_mask_val *regs; + int size; + + if (!codec) { + pr_err("%s: NULL codec pointer!\n", __func__); + return -EINVAL; + } + + priv = snd_soc_codec_get_drvdata(codec); + if (!priv) + return -EINVAL; + + switch (mode) { + case SPKR_MODE_1: + regs = msm_sdw_spkr_mode1; + size = ARRAY_SIZE(msm_sdw_spkr_mode1); + break; + default: + regs = msm_sdw_spkr_default; + size = ARRAY_SIZE(msm_sdw_spkr_default); + break; + } + + priv->spkr_mode = mode; + for (i = 0; i < size; i++) + snd_soc_update_bits(codec, regs[i].reg, + regs[i].mask, regs[i].val); + return 0; +} +EXPORT_SYMBOL(msm_sdw_set_spkr_mode); + +static int msm_enable_sdw_npl_clk(struct msm_sdw_priv *msm_sdw, int enable) +{ + int ret = 0; + + dev_dbg(msm_sdw->dev, "%s: enable %d\n", __func__, enable); + + mutex_lock(&msm_sdw->sdw_npl_clk_mutex); + if (enable) { + if (msm_sdw->sdw_npl_clk_enabled == false) { + msm_sdw->sdw_npl_clk.enable = 1; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT4_MI2S_RX, + &msm_sdw->sdw_npl_clk); + if (ret < 0) { + dev_err(msm_sdw->dev, + "%s: failed to enable SDW NPL CLK\n", + __func__); + mutex_unlock(&msm_sdw->sdw_npl_clk_mutex); + return ret; + } + dev_dbg(msm_sdw->dev, "enabled sdw npl clk\n"); + msm_sdw->sdw_npl_clk_enabled = true; + } + } else { + if (msm_sdw->sdw_npl_clk_enabled == true) { + msm_sdw->sdw_npl_clk.enable = 0; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT4_MI2S_RX, + &msm_sdw->sdw_npl_clk); + if (ret < 0) + dev_err(msm_sdw->dev, + "%s: failed to disable SDW NPL CLK\n", + __func__); + msm_sdw->sdw_npl_clk_enabled = false; + } + } + mutex_unlock(&msm_sdw->sdw_npl_clk_mutex); + return ret; +} + +static int msm_int_enable_sdw_cdc_clk(struct msm_sdw_priv *msm_sdw, + int enable, bool dapm) +{ + int ret = 0; + + mutex_lock(&msm_sdw->cdc_int_mclk1_mutex); + dev_dbg(msm_sdw->dev, "%s: enable %d mclk1 ref counter %d\n", + __func__, enable, msm_sdw->int_mclk1_rsc_ref); + if (enable) { + if (msm_sdw->int_mclk1_rsc_ref == 0) { + cancel_delayed_work_sync( + &msm_sdw->disable_int_mclk1_work); + if (msm_sdw->int_mclk1_enabled == false) { + msm_sdw->sdw_cdc_core_clk.enable = 1; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT4_MI2S_RX, + &msm_sdw->sdw_cdc_core_clk); + if (ret < 0) { + dev_err(msm_sdw->dev, + "%s: failed to enable SDW MCLK\n", + __func__); + goto rtn; + } + dev_dbg(msm_sdw->dev, + "enabled sdw codec core mclk\n"); + msm_sdw->int_mclk1_enabled = true; + } + } + msm_sdw->int_mclk1_rsc_ref++; + } else { + cancel_delayed_work_sync(&msm_sdw->disable_int_mclk1_work); + if (msm_sdw->int_mclk1_rsc_ref > 0) { + msm_sdw->int_mclk1_rsc_ref--; + dev_dbg(msm_sdw->dev, + "%s: decrementing mclk_res_ref %d\n", + __func__, msm_sdw->int_mclk1_rsc_ref); + } + if (msm_sdw->int_mclk1_enabled == true && + msm_sdw->int_mclk1_rsc_ref == 0) { + msm_sdw->sdw_cdc_core_clk.enable = 0; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT4_MI2S_RX, + &msm_sdw->sdw_cdc_core_clk); + if (ret < 0) + dev_err(msm_sdw->dev, + "%s: failed to disable SDW MCLK\n", + __func__); + msm_sdw->int_mclk1_enabled = false; + } + } + mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); +rtn: + return ret; +} +EXPORT_SYMBOL(msm_int_enable_sdw_cdc_clk); + +static void msm_disable_int_mclk1(struct work_struct *work) +{ + struct msm_sdw_priv *msm_sdw = NULL; + struct delayed_work *dwork; + int ret = 0; + + dwork = to_delayed_work(work); + msm_sdw = container_of(dwork, struct msm_sdw_priv, + disable_int_mclk1_work); + mutex_lock(&msm_sdw->cdc_int_mclk1_mutex); + dev_dbg(msm_sdw->dev, "%s: mclk1_enabled %d mclk1_rsc_ref %d\n", + __func__, msm_sdw->int_mclk1_enabled, + msm_sdw->int_mclk1_rsc_ref); + if (msm_sdw->int_mclk1_enabled == true + && msm_sdw->int_mclk1_rsc_ref == 0) { + dev_dbg(msm_sdw->dev, "Disable the mclk1\n"); + msm_sdw->sdw_cdc_core_clk.enable = 0; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT4_MI2S_RX, + &msm_sdw->sdw_cdc_core_clk); + if (ret < 0) + dev_err(msm_sdw->dev, + "%s failed to disable the MCLK1\n", + __func__); + msm_sdw->int_mclk1_enabled = false; + } + mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); +} + +static int msm_int_mclk1_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + dev_dbg(msm_sdw->dev, "%s: event = %d\n", __func__, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* enable the codec mclk config */ + msm_int_enable_sdw_cdc_clk(msm_sdw, 1, true); + msm_sdw_mclk_enable(msm_sdw, 1, true); + break; + case SND_SOC_DAPM_POST_PMD: + /* disable the codec mclk config */ + msm_sdw_mclk_enable(msm_sdw, 0, true); + msm_int_enable_sdw_cdc_clk(msm_sdw, 0, true); + break; + default: + dev_err(msm_sdw->dev, + "%s: invalid DAPM event %d\n", __func__, event); + ret = -EINVAL; + } + return ret; +} + +static int msm_sdw_ahb_write_device(struct msm_sdw_priv *msm_sdw, + u16 reg, u8 *value) +{ + u32 temp = (u32)(*value) & 0x000000FF; + + if (!msm_sdw->dev_up) { + dev_err_ratelimited(msm_sdw->dev, "%s: q6 not ready\n", + __func__); + return 0; + } + + iowrite32(temp, msm_sdw->sdw_base + reg); + return 0; +} + +static int msm_sdw_ahb_read_device(struct msm_sdw_priv *msm_sdw, + u16 reg, u8 *value) +{ + u32 temp; + + if (!msm_sdw->dev_up) { + dev_err_ratelimited(msm_sdw->dev, "%s: q6 not ready\n", + __func__); + return 0; + } + + temp = ioread32(msm_sdw->sdw_base + reg); + *value = (u8)temp; + return 0; +} + +static int __msm_sdw_reg_read(struct msm_sdw_priv *msm_sdw, unsigned short reg, + int bytes, void *dest) +{ + int ret = -EINVAL, i; + u8 temp = 0; + + dev_dbg(msm_sdw->dev, "%s reg = %x\n", __func__, reg); + mutex_lock(&msm_sdw->cdc_int_mclk1_mutex); + if (msm_sdw->int_mclk1_enabled == false) { + msm_sdw->sdw_cdc_core_clk.enable = 1; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT4_MI2S_RX, + &msm_sdw->sdw_cdc_core_clk); + if (ret < 0) { + dev_err(msm_sdw->dev, + "%s:failed to enable the INT_MCLK1\n", + __func__); + goto unlock_exit; + } + dev_dbg(msm_sdw->dev, "%s:enabled sdw codec core clk\n", + __func__); + for (i = 0; i < bytes; i++) { + ret = msm_sdw_ahb_read_device( + msm_sdw, reg + (4 * i), &temp); + ((u8 *)dest)[i] = temp; + } + msm_sdw->int_mclk1_enabled = true; + schedule_delayed_work(&msm_sdw->disable_int_mclk1_work, 50); + goto unlock_exit; + } + for (i = 0; i < bytes; i++) { + ret = msm_sdw_ahb_read_device( + msm_sdw, reg + (4 * i), &temp); + ((u8 *)dest)[i] = temp; + } +unlock_exit: + mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); + if (ret < 0) { + dev_err_ratelimited(msm_sdw->dev, + "%s: codec read failed for reg 0x%x\n", + __func__, reg); + return ret; + } + dev_dbg(msm_sdw->dev, "Read 0x%02x from 0x%x\n", temp, reg); + + return 0; +} + +static int __msm_sdw_reg_write(struct msm_sdw_priv *msm_sdw, unsigned short reg, + int bytes, void *src) +{ + int ret = -EINVAL, i; + + mutex_lock(&msm_sdw->cdc_int_mclk1_mutex); + if (msm_sdw->int_mclk1_enabled == false) { + msm_sdw->sdw_cdc_core_clk.enable = 1; + ret = afe_set_lpass_clock_v2(AFE_PORT_ID_INT4_MI2S_RX, + &msm_sdw->sdw_cdc_core_clk); + if (ret < 0) { + dev_err(msm_sdw->dev, + "%s: failed to enable the INT_MCLK1\n", + __func__); + ret = 0; + goto unlock_exit; + } + dev_dbg(msm_sdw->dev, "%s: enabled INT_MCLK1\n", __func__); + for (i = 0; i < bytes; i++) + ret = msm_sdw_ahb_write_device(msm_sdw, reg + (4 * i), + &((u8 *)src)[i]); + msm_sdw->int_mclk1_enabled = true; + schedule_delayed_work(&msm_sdw->disable_int_mclk1_work, 50); + goto unlock_exit; + } + for (i = 0; i < bytes; i++) + ret = msm_sdw_ahb_write_device(msm_sdw, reg + (4 * i), + &((u8 *)src)[i]); +unlock_exit: + mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); + dev_dbg(msm_sdw->dev, "Write 0x%x val 0x%02x\n", + reg, (u32)(*(u32 *)src)); + + return ret; +} + +static int msm_sdw_codec_enable_vi_feedback(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = NULL; + struct msm_sdw_priv *msm_sdw_p = NULL; + int ret = 0; + + if (!w) { + pr_err("%s invalid params\n", __func__); + return -EINVAL; + } + codec = snd_soc_dapm_to_codec(w->dapm); + msm_sdw_p = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: num_dai %d stream name %s\n", + __func__, codec->component.num_dai, w->sname); + + dev_dbg(codec->dev, "%s(): w->name %s event %d w->shift %d\n", + __func__, w->name, event, w->shift); + if (w->shift != AIF1_SDW_VIFEED) { + dev_err(codec->dev, + "%s:Error in enabling the vi feedback path\n", + __func__); + ret = -EINVAL; + goto out_vi; + } + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (test_bit(VI_SENSE_1, &msm_sdw_p->status_mask)) { + dev_dbg(codec->dev, "%s: spkr1 enabled\n", __func__); + /* Enable V&I sensing */ + snd_soc_update_bits(codec, + MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); + snd_soc_update_bits(codec, + MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x0F, 0x04); + snd_soc_update_bits(codec, + MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x0F, 0x04); + snd_soc_update_bits(codec, + MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x10); + snd_soc_update_bits(codec, + MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x10, + 0x10); + snd_soc_update_bits(codec, + MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x00); + snd_soc_update_bits(codec, + MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x20, + 0x00); + } + if (test_bit(VI_SENSE_2, &msm_sdw_p->status_mask)) { + dev_dbg(codec->dev, "%s: spkr2 enabled\n", __func__); + /* Enable V&I sensing */ + snd_soc_update_bits(codec, + MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x0F, + 0x04); + snd_soc_update_bits(codec, + MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x0F, + 0x04); + snd_soc_update_bits(codec, + MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x10, + 0x10); + snd_soc_update_bits(codec, + MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x10, + 0x10); + snd_soc_update_bits(codec, + MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x20, + 0x00); + snd_soc_update_bits(codec, + MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x20, + 0x00); + } + break; + case SND_SOC_DAPM_POST_PMD: + if (test_bit(VI_SENSE_1, &msm_sdw_p->status_mask)) { + /* Disable V&I sensing */ + dev_dbg(codec->dev, "%s: spkr1 disabled\n", __func__); + snd_soc_update_bits(codec, + MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); + snd_soc_update_bits(codec, + MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x00); + snd_soc_update_bits(codec, + MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x10, + 0x00); + } + if (test_bit(VI_SENSE_2, &msm_sdw_p->status_mask)) { + /* Disable V&I sensing */ + dev_dbg(codec->dev, "%s: spkr2 disabled\n", __func__); + snd_soc_update_bits(codec, + MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x10, + 0x00); + snd_soc_update_bits(codec, + MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x10, + 0x00); + } + break; + } +out_vi: + return ret; +} + +static int msm_sdwm_handle_irq(void *handle, + irqreturn_t (*swrm_irq_handler)(int irq, + void *data), + void *swrm_handle, + int action) +{ + struct msm_sdw_priv *msm_sdw; + int ret = 0; + + if (!handle) { + pr_err("%s: null handle received\n", __func__); + return -EINVAL; + } + msm_sdw = (struct msm_sdw_priv *) handle; + + if (skip_irq) + return ret; + + if (action) { + ret = request_threaded_irq(msm_sdw->sdw_irq, NULL, + swrm_irq_handler, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "swr_master_irq", swrm_handle); + if (ret) + dev_err(msm_sdw->dev, "%s: Failed to request irq %d\n", + __func__, ret); + } else + free_irq(msm_sdw->sdw_irq, swrm_handle); + + return ret; +} + +static void msm_sdw_codec_hd2_control(struct snd_soc_codec *codec, + u16 reg, int event) +{ + u16 hd2_scale_reg; + u16 hd2_enable_reg = 0; + + if (reg == MSM_SDW_RX7_RX_PATH_CTL) { + hd2_scale_reg = MSM_SDW_RX7_RX_PATH_SEC3; + hd2_enable_reg = MSM_SDW_RX7_RX_PATH_CFG0; + } + if (reg == MSM_SDW_RX8_RX_PATH_CTL) { + hd2_scale_reg = MSM_SDW_RX8_RX_PATH_SEC3; + hd2_enable_reg = MSM_SDW_RX8_RX_PATH_CFG0; + } + + if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { + snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x10); + snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x01); + snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x04); + } + + if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x00); + snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x00); + snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x00); + } +} + +static int msm_sdw_enable_swr(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct msm_sdw_priv *msm_sdw; + int i, ch_cnt; + + msm_sdw = snd_soc_codec_get_drvdata(codec); + + if (!msm_sdw->nr) + return 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (!(strnstr(w->name, "RX4", sizeof("RX4 MIX"))) && + !msm_sdw->rx_4_count) + msm_sdw->rx_4_count++; + if (!(strnstr(w->name, "RX5", sizeof("RX5 MIX"))) && + !msm_sdw->rx_5_count) + msm_sdw->rx_5_count++; + ch_cnt = msm_sdw->rx_4_count + msm_sdw->rx_5_count; + + for (i = 0; i < msm_sdw->nr; i++) { + swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, + SWR_DEVICE_UP, NULL); + swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, + SWR_SET_NUM_RX_CH, &ch_cnt); + } + break; + case SND_SOC_DAPM_POST_PMD: + if (!(strnstr(w->name, "RX4", sizeof("RX4 MIX"))) && + msm_sdw->rx_4_count) + msm_sdw->rx_4_count--; + if (!(strnstr(w->name, "RX5", sizeof("RX5 MIX"))) && + msm_sdw->rx_5_count) + msm_sdw->rx_5_count--; + ch_cnt = msm_sdw->rx_4_count + msm_sdw->rx_5_count; + + for (i = 0; i < msm_sdw->nr; i++) + swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, + SWR_SET_NUM_RX_CH, &ch_cnt); + break; + } + dev_dbg(msm_sdw->dev, "%s: current swr ch cnt: %d\n", + __func__, msm_sdw->rx_4_count + msm_sdw->rx_5_count); + + return 0; +} + +static int msm_sdw_codec_enable_interpolator(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); + u16 gain_reg; + u16 reg; + int val; + int offset_val = 0; + + dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + + if (!(strcmp(w->name, "RX INT4 INTERP"))) { + reg = MSM_SDW_RX7_RX_PATH_CTL; + gain_reg = MSM_SDW_RX7_RX_VOL_CTL; + } else if (!(strcmp(w->name, "RX INT5 INTERP"))) { + reg = MSM_SDW_RX8_RX_PATH_CTL; + gain_reg = MSM_SDW_RX8_RX_VOL_CTL; + } else { + dev_err(codec->dev, "%s: Interpolator reg not found\n", + __func__); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, reg, 0x10, 0x10); + msm_sdw_codec_hd2_control(codec, reg, event); + snd_soc_update_bits(codec, reg, 1 << 0x5, 1 << 0x5); + break; + case SND_SOC_DAPM_POST_PMU: + msm_sdw_config_compander(codec, w->shift, event); + /* apply gain after int clk is enabled */ + if ((msm_sdw->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && + (msm_sdw->comp_enabled[COMP1] || + msm_sdw->comp_enabled[COMP2]) && + (gain_reg == MSM_SDW_RX7_RX_VOL_CTL || + gain_reg == MSM_SDW_RX8_RX_VOL_CTL)) { + snd_soc_update_bits(codec, MSM_SDW_RX7_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_update_bits(codec, + MSM_SDW_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x01); + snd_soc_update_bits(codec, MSM_SDW_RX8_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_update_bits(codec, + MSM_SDW_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x01); + offset_val = -2; + } + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + msm_sdw_config_ear_spkr_gain(codec, event, gain_reg); + snd_soc_update_bits(codec, reg, 0x10, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, reg, 1 << 0x5, 0 << 0x5); + snd_soc_update_bits(codec, reg, 0x40, 0x40); + snd_soc_update_bits(codec, reg, 0x40, 0x00); + msm_sdw_codec_hd2_control(codec, reg, event); + msm_sdw_config_compander(codec, w->shift, event); + if ((msm_sdw->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && + (msm_sdw->comp_enabled[COMP1] || + msm_sdw->comp_enabled[COMP2]) && + (gain_reg == MSM_SDW_RX7_RX_VOL_CTL || + gain_reg == MSM_SDW_RX8_RX_VOL_CTL)) { + snd_soc_update_bits(codec, MSM_SDW_RX7_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_update_bits(codec, + MSM_SDW_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x00); + snd_soc_update_bits(codec, MSM_SDW_RX8_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_update_bits(codec, + MSM_SDW_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x00); + offset_val = 2; + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + } + msm_sdw_config_ear_spkr_gain(codec, event, gain_reg); + break; + }; + + return 0; +} + +static int msm_sdw_config_ear_spkr_gain(struct snd_soc_codec *codec, + int event, int gain_reg) +{ + int comp_gain_offset, val; + struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); + + switch (msm_sdw->spkr_mode) { + /* Compander gain in SPKR_MODE1 case is 12 dB */ + case SPKR_MODE_1: + comp_gain_offset = -12; + break; + /* Default case compander gain is 15 dB */ + default: + comp_gain_offset = -15; + break; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* Apply ear spkr gain only if compander is enabled */ + if (msm_sdw->comp_enabled[COMP1] && + (gain_reg == MSM_SDW_RX7_RX_VOL_CTL) && + (msm_sdw->ear_spkr_gain != 0)) { + /* For example, val is -8(-12+5-1) for 4dB of gain */ + val = comp_gain_offset + msm_sdw->ear_spkr_gain - 1; + snd_soc_write(codec, gain_reg, val); + + dev_dbg(codec->dev, "%s: RX4 Volume %d dB\n", + __func__, val); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* + * Reset RX4 volume to 0 dB if compander is enabled and + * ear_spkr_gain is non-zero. + */ + if (msm_sdw->comp_enabled[COMP1] && + (gain_reg == MSM_SDW_RX7_RX_VOL_CTL) && + (msm_sdw->ear_spkr_gain != 0)) { + snd_soc_write(codec, gain_reg, 0x0); + + dev_dbg(codec->dev, "%s: Reset RX4 Volume to 0 dB\n", + __func__); + } + break; + } + + return 0; +} + +static int msm_sdw_codec_spk_boost_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 boost_path_ctl, boost_path_cfg1; + u16 reg; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + if (!strcmp(w->name, "RX INT4 CHAIN")) { + boost_path_ctl = MSM_SDW_BOOST0_BOOST_PATH_CTL; + boost_path_cfg1 = MSM_SDW_RX7_RX_PATH_CFG1; + reg = MSM_SDW_RX7_RX_PATH_CTL; + } else if (!strcmp(w->name, "RX INT5 CHAIN")) { + boost_path_ctl = MSM_SDW_BOOST1_BOOST_PATH_CTL; + boost_path_cfg1 = MSM_SDW_RX8_RX_PATH_CFG1; + reg = MSM_SDW_RX8_RX_PATH_CTL; + } else { + dev_err(codec->dev, "%s: boost reg not found\n", + __func__); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x10); + snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x01); + snd_soc_update_bits(codec, reg, 0x10, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x00); + snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x00); + break; + }; + + return 0; +} + +static int msm_sdw_config_compander(struct snd_soc_codec *codec, int comp, + int event) +{ + struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); + u16 comp_ctl0_reg, rx_path_cfg0_reg; + + if (comp < COMP1 || comp >= COMP_MAX) + return 0; + + dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n", + __func__, event, comp + 1, msm_sdw->comp_enabled[comp]); + + if (!msm_sdw->comp_enabled[comp]) + return 0; + + comp_ctl0_reg = MSM_SDW_COMPANDER7_CTL0 + (comp * 0x20); + rx_path_cfg0_reg = MSM_SDW_RX7_RX_PATH_CFG0 + (comp * 0x1E0); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Compander Clock */ + snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); + snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); + } + + return 0; +} + +static int msm_sdw_get_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = msm_sdw->comp_enabled[comp]; + return 0; +} + +static int msm_sdw_set_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int value = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n", + __func__, comp + 1, msm_sdw->comp_enabled[comp], value); + msm_sdw->comp_enabled[comp] = value; + + return 0; +} + +static int msm_sdw_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = msm_sdw->ear_spkr_gain; + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_sdw_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); + + msm_sdw->ear_spkr_gain = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: gain = %d\n", __func__, + msm_sdw->ear_spkr_gain); + + return 0; +} + +static int msm_sdw_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct msm_sdw_priv *msm_sdw_p = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = msm_sdw_p->vi_feed_value; + + return 0; +} + +static int msm_sdw_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget_list *wlist = + dapm_kcontrol_get_wlist(kcontrol); + struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct msm_sdw_priv *msm_sdw_p = snd_soc_codec_get_drvdata(codec); + struct soc_multi_mixer_control *mixer = + ((struct soc_multi_mixer_control *)kcontrol->private_value); + u32 dai_id = widget->shift; + u32 port_id = mixer->shift; + u32 enable = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: enable: %d, port_id:%d, dai_id: %d\n", + __func__, enable, port_id, dai_id); + + msm_sdw_p->vi_feed_value = ucontrol->value.integer.value[0]; + + mutex_lock(&msm_sdw_p->codec_mutex); + if (enable) { + if (port_id == MSM_SDW_TX0 && !test_bit(VI_SENSE_1, + &msm_sdw_p->status_mask)) + set_bit(VI_SENSE_1, &msm_sdw_p->status_mask); + if (port_id == MSM_SDW_TX1 && !test_bit(VI_SENSE_2, + &msm_sdw_p->status_mask)) + set_bit(VI_SENSE_2, &msm_sdw_p->status_mask); + } else { + if (port_id == MSM_SDW_TX0 && test_bit(VI_SENSE_1, + &msm_sdw_p->status_mask)) + clear_bit(VI_SENSE_1, &msm_sdw_p->status_mask); + if (port_id == MSM_SDW_TX1 && test_bit(VI_SENSE_2, + &msm_sdw_p->status_mask)) + clear_bit(VI_SENSE_2, &msm_sdw_p->status_mask); + } + mutex_unlock(&msm_sdw_p->codec_mutex); + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL); + + return 0; +} + +static int msm_sdw_mclk_enable(struct msm_sdw_priv *msm_sdw, + int mclk_enable, bool dapm) +{ + dev_dbg(msm_sdw->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", + __func__, mclk_enable, dapm, msm_sdw->sdw_mclk_users); + if (mclk_enable) { + msm_sdw->sdw_mclk_users++; + if (msm_sdw->sdw_mclk_users == 1) { + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + /* 9.6MHz MCLK, set value 0x00 if other frequency */ + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_TOP_FREQ_MCLK, 0x01, 0x01); + } + } else { + msm_sdw->sdw_mclk_users--; + if (msm_sdw->sdw_mclk_users == 0) { + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x00); + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x00); + } + } + return 0; +} +EXPORT_SYMBOL(msm_sdw_mclk_enable); + +static int msm_sdw_swrm_read(void *handle, int reg) +{ + struct msm_sdw_priv *msm_sdw; + unsigned short sdw_rd_addr_base; + unsigned short sdw_rd_data_base; + int val, ret; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + msm_sdw = (struct msm_sdw_priv *)handle; + + dev_dbg(msm_sdw->dev, "%s: Reading soundwire register, 0x%x\n", + __func__, reg); + sdw_rd_addr_base = MSM_SDW_AHB_BRIDGE_RD_ADDR_0; + sdw_rd_data_base = MSM_SDW_AHB_BRIDGE_RD_DATA_0; + /* + * Add sleep as SWR slave access read takes time. + * Allow for RD_DONE to complete for previous register if any. + */ + usleep_range(100, 105); + + /* read_lock */ + mutex_lock(&msm_sdw->sdw_read_lock); + ret = regmap_bulk_write(msm_sdw->regmap, sdw_rd_addr_base, + (u8 *)®, 4); + if (ret < 0) { + dev_err(msm_sdw->dev, "%s: RD Addr Failure\n", __func__); + goto err; + } + /* Add sleep for SWR register read value to get updated. */ + usleep_range(100, 105); + /* Check for RD value */ + ret = regmap_bulk_read(msm_sdw->regmap, sdw_rd_data_base, + (u8 *)&val, 4); + if (ret < 0) { + dev_err(msm_sdw->dev, "%s: RD Data Failure\n", __func__); + goto err; + } + ret = val; +err: + /* read_unlock */ + mutex_unlock(&msm_sdw->sdw_read_lock); + return ret; +} + +static int msm_sdw_bulk_write(struct msm_sdw_priv *msm_sdw, + struct msm_sdw_reg_val *bulk_reg, + size_t len) +{ + int i, ret = 0; + unsigned short sdw_wr_addr_base; + unsigned short sdw_wr_data_base; + + sdw_wr_addr_base = MSM_SDW_AHB_BRIDGE_WR_ADDR_0; + sdw_wr_data_base = MSM_SDW_AHB_BRIDGE_WR_DATA_0; + + for (i = 0; i < len; i += 2) { + /* + * Add sleep as SWR slave write takes time. + * Allow for any previous pending write to complete. + */ + usleep_range(100, 105); + /* First Write the Data to register */ + ret = regmap_bulk_write(msm_sdw->regmap, + sdw_wr_data_base, bulk_reg[i].buf, 4); + if (ret < 0) { + dev_err(msm_sdw->dev, "%s: WR Data Failure\n", + __func__); + break; + } + /* Next Write Address */ + ret = regmap_bulk_write(msm_sdw->regmap, + sdw_wr_addr_base, bulk_reg[i+1].buf, 4); + if (ret < 0) { + dev_err(msm_sdw->dev, + "%s: WR Addr Failure: 0x%x\n", + __func__, (u32)(bulk_reg[i+1].buf[0])); + break; + } + } + return ret; +} + +static int msm_sdw_swrm_bulk_write(void *handle, u32 *reg, u32 *val, size_t len) +{ + struct msm_sdw_priv *msm_sdw; + struct msm_sdw_reg_val *bulk_reg; + unsigned short sdw_wr_addr_base; + unsigned short sdw_wr_data_base; + int i, j, ret; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + + msm_sdw = (struct msm_sdw_priv *)handle; + if (len <= 0) { + dev_err(msm_sdw->dev, + "%s: Invalid size: %zu\n", __func__, len); + return -EINVAL; + } + + sdw_wr_addr_base = MSM_SDW_AHB_BRIDGE_WR_ADDR_0; + sdw_wr_data_base = MSM_SDW_AHB_BRIDGE_WR_DATA_0; + + bulk_reg = kzalloc((2 * len * sizeof(struct msm_sdw_reg_val)), + GFP_KERNEL); + if (!bulk_reg) + return -ENOMEM; + + for (i = 0, j = 0; i < (len * 2); i += 2, j++) { + bulk_reg[i].reg = sdw_wr_data_base; + bulk_reg[i].buf = (u8 *)(&val[j]); + bulk_reg[i].bytes = 4; + bulk_reg[i+1].reg = sdw_wr_addr_base; + bulk_reg[i+1].buf = (u8 *)(®[j]); + bulk_reg[i+1].bytes = 4; + } + mutex_lock(&msm_sdw->sdw_write_lock); + + ret = msm_sdw_bulk_write(msm_sdw, bulk_reg, (len * 2)); + if (ret) + dev_err(msm_sdw->dev, "%s: swrm bulk write failed, ret: %d\n", + __func__, ret); + + mutex_unlock(&msm_sdw->sdw_write_lock); + kfree(bulk_reg); + + return ret; +} + +static int msm_sdw_swrm_write(void *handle, int reg, int val) +{ + struct msm_sdw_priv *msm_sdw; + unsigned short sdw_wr_addr_base; + unsigned short sdw_wr_data_base; + struct msm_sdw_reg_val bulk_reg[2]; + int ret; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + msm_sdw = (struct msm_sdw_priv *)handle; + + sdw_wr_addr_base = MSM_SDW_AHB_BRIDGE_WR_ADDR_0; + sdw_wr_data_base = MSM_SDW_AHB_BRIDGE_WR_DATA_0; + + /* First Write the Data to register */ + bulk_reg[0].reg = sdw_wr_data_base; + bulk_reg[0].buf = (u8 *)(&val); + bulk_reg[0].bytes = 4; + bulk_reg[1].reg = sdw_wr_addr_base; + bulk_reg[1].buf = (u8 *)(®); + bulk_reg[1].bytes = 4; + + mutex_lock(&msm_sdw->sdw_write_lock); + + ret = msm_sdw_bulk_write(msm_sdw, bulk_reg, 2); + if (ret < 0) + dev_err(msm_sdw->dev, "%s: WR Data Failure\n", __func__); + + mutex_unlock(&msm_sdw->sdw_write_lock); + return ret; +} + +static int msm_sdw_swrm_clock(void *handle, bool enable) +{ + struct msm_sdw_priv *msm_sdw = (struct msm_sdw_priv *) handle; + + mutex_lock(&msm_sdw->sdw_clk_lock); + + dev_dbg(msm_sdw->dev, "%s: swrm clock %s\n", + __func__, (enable ? "enable" : "disable")); + if (enable) { + msm_sdw->sdw_clk_users++; + if (msm_sdw->sdw_clk_users == 1) { + msm_int_enable_sdw_cdc_clk(msm_sdw, 1, true); + msm_sdw_mclk_enable(msm_sdw, 1, true); + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x01); + msm_enable_sdw_npl_clk(msm_sdw, true); + msm_cdc_pinctrl_select_active_state( + msm_sdw->sdw_gpio_p); + } + } else { + msm_sdw->sdw_clk_users--; + if (msm_sdw->sdw_clk_users == 0) { + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x00); + msm_sdw_mclk_enable(msm_sdw, 0, true); + msm_int_enable_sdw_cdc_clk(msm_sdw, 0, true); + msm_enable_sdw_npl_clk(msm_sdw, false); + msm_cdc_pinctrl_select_sleep_state(msm_sdw->sdw_gpio_p); + } + } + dev_dbg(msm_sdw->dev, "%s: swrm clock users %d\n", + __func__, msm_sdw->sdw_clk_users); + mutex_unlock(&msm_sdw->sdw_clk_lock); + return 0; +} + +static int msm_sdw_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + dev_dbg(dai->codec->dev, "%s(): substream = %s stream = %d\n", + __func__, + substream->name, substream->stream); + return 0; +} + +static int msm_sdw_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + u8 clk_fs_rate, fs_rate; + + dev_dbg(dai->codec->dev, + "%s: dai_name = %s DAI-ID %x rate %d num_ch %d format %d\n", + __func__, dai->name, dai->id, params_rate(params), + params_channels(params), params_format(params)); + + switch (params_rate(params)) { + case 8000: + clk_fs_rate = 0x00; + fs_rate = 0x00; + break; + case 16000: + clk_fs_rate = 0x01; + fs_rate = 0x01; + break; + case 32000: + clk_fs_rate = 0x02; + fs_rate = 0x03; + break; + case 48000: + clk_fs_rate = 0x03; + fs_rate = 0x04; + break; + case 96000: + clk_fs_rate = 0x04; + fs_rate = 0x05; + break; + case 192000: + clk_fs_rate = 0x05; + fs_rate = 0x06; + break; + default: + dev_err(dai->codec->dev, + "%s: Invalid sampling rate %d\n", __func__, + params_rate(params)); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + snd_soc_update_bits(dai->codec, + MSM_SDW_TOP_TX_I2S_CTL, 0x1C, + (clk_fs_rate << 2)); + } else { + snd_soc_update_bits(dai->codec, + MSM_SDW_TOP_RX_I2S_CTL, 0x1C, + (clk_fs_rate << 2)); + snd_soc_update_bits(dai->codec, + MSM_SDW_RX7_RX_PATH_CTL, 0x0F, + fs_rate); + snd_soc_update_bits(dai->codec, + MSM_SDW_RX8_RX_PATH_CTL, 0x0F, + fs_rate); + } + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + snd_soc_update_bits(dai->codec, + MSM_SDW_TOP_TX_I2S_CTL, 0x20, 0x20); + else + snd_soc_update_bits(dai->codec, + MSM_SDW_TOP_RX_I2S_CTL, 0x20, 0x20); + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + snd_soc_update_bits(dai->codec, + MSM_SDW_TOP_TX_I2S_CTL, 0x20, 0x00); + else + snd_soc_update_bits(dai->codec, + MSM_SDW_TOP_RX_I2S_CTL, 0x20, 0x00); + break; + default: + dev_err(dai->codec->dev, "%s: wrong format selected\n", + __func__); + return -EINVAL; + } + + return 0; +} + +static void msm_sdw_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + dev_dbg(dai->codec->dev, + "%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); +} + +static ssize_t msm_sdw_codec_version_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, size_t count, + loff_t pos) +{ + struct msm_sdw_priv *msm_sdw; + char buffer[MSM_SDW_VERSION_ENTRY_SIZE]; + int len = 0; + + msm_sdw = (struct msm_sdw_priv *) entry->private_data; + if (!msm_sdw) { + pr_err("%s: msm_sdw priv is null\n", __func__); + return -EINVAL; + } + + switch (msm_sdw->version) { + case MSM_SDW_VERSION_1_0: + len = snprintf(buffer, sizeof(buffer), "SDW-CDC_1_0\n"); + break; + default: + len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + } + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops msm_sdw_codec_info_ops = { + .read = msm_sdw_codec_version_read, +}; + +/* + * msm_sdw_codec_info_create_codec_entry - creates msm_sdw module + * @codec_root: The parent directory + * @codec: Codec instance + * + * Creates msm_sdw module and version entry under the given + * parent directory. + * + * Return: 0 on success or negative error code on failure. + */ +int msm_sdw_codec_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + struct snd_info_entry *version_entry; + struct msm_sdw_priv *msm_sdw; + struct snd_soc_card *card; + + if (!codec_root || !codec) + return -EINVAL; + + msm_sdw = snd_soc_codec_get_drvdata(codec); + card = codec->component.card; + msm_sdw->entry = snd_info_create_subdir(codec_root->module, + "152c1000.msm-sdw-codec", + codec_root); + if (!msm_sdw->entry) { + dev_err(codec->dev, "%s: failed to create msm_sdw entry\n", + __func__); + return -ENOMEM; + } + + version_entry = snd_info_create_card_entry(card->snd_card, + "version", + msm_sdw->entry); + if (!version_entry) { + dev_err(codec->dev, "%s: failed to create msm_sdw version entry\n", + __func__); + return -ENOMEM; + } + + version_entry->private_data = msm_sdw; + version_entry->size = MSM_SDW_VERSION_ENTRY_SIZE; + version_entry->content = SNDRV_INFO_CONTENT_DATA; + version_entry->c.ops = &msm_sdw_codec_info_ops; + + if (snd_info_register(version_entry) < 0) { + snd_info_free_entry(version_entry); + return -ENOMEM; + } + msm_sdw->version_entry = version_entry; + + return 0; +} +EXPORT_SYMBOL(msm_sdw_codec_info_create_codec_entry); + +static struct snd_soc_dai_ops msm_sdw_dai_ops = { + .startup = msm_sdw_startup, + .shutdown = msm_sdw_shutdown, + .hw_params = msm_sdw_hw_params, +}; + +static struct snd_soc_dai_driver msm_sdw_dai[] = { + { + .name = "msm_sdw_i2s_rx1", + .id = AIF1_SDW_PB, + .playback = { + .stream_name = "AIF1_SDW Playback", + .rates = MSM_SDW_RATES, + .formats = MSM_SDW_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 4, + }, + .ops = &msm_sdw_dai_ops, + }, + { + .name = "msm_sdw_vifeedback", + .id = AIF1_SDW_VIFEED, + .capture = { + .stream_name = "VIfeed_SDW", + .rates = MSM_SDW_RATES, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_max = 48000, + .rate_min = 8000, + .channels_min = 2, + .channels_max = 4, + }, + .ops = &msm_sdw_dai_ops, + }, +}; + +static const char * const rx_mix1_text[] = { + "ZERO", "RX4", "RX5" +}; + +static const char * const msm_sdw_ear_spkr_pa_gain_text[] = { + "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB", + "G_4_DB", "G_5_DB", "G_6_DB" +}; + +static SOC_ENUM_SINGLE_EXT_DECL(msm_sdw_ear_spkr_pa_gain_enum, + msm_sdw_ear_spkr_pa_gain_text); +/* RX4 MIX1 */ +static const struct soc_enum rx4_mix1_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM_SDW_TOP_RX7_PATH_INPUT0_MUX, + 0, 3, rx_mix1_text); + +static const struct soc_enum rx4_mix1_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM_SDW_TOP_RX7_PATH_INPUT1_MUX, + 0, 3, rx_mix1_text); + +/* RX5 MIX1 */ +static const struct soc_enum rx5_mix1_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM_SDW_TOP_RX8_PATH_INPUT0_MUX, + 0, 3, rx_mix1_text); + +static const struct soc_enum rx5_mix1_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM_SDW_TOP_RX8_PATH_INPUT1_MUX, + 0, 3, rx_mix1_text); + +static const struct snd_kcontrol_new rx4_mix1_inp1_mux = + SOC_DAPM_ENUM("RX4 MIX1 INP1 Mux", rx4_mix1_inp1_chain_enum); + +static const struct snd_kcontrol_new rx4_mix1_inp2_mux = + SOC_DAPM_ENUM("RX4 MIX1 INP2 Mux", rx4_mix1_inp2_chain_enum); + +static const struct snd_kcontrol_new rx5_mix1_inp1_mux = + SOC_DAPM_ENUM("RX5 MIX1 INP1 Mux", rx5_mix1_inp1_chain_enum); + +static const struct snd_kcontrol_new rx5_mix1_inp2_mux = + SOC_DAPM_ENUM("RX5 MIX1 INP2 Mux", rx5_mix1_inp2_chain_enum); + +static const struct snd_kcontrol_new aif1_vi_mixer[] = { + SOC_SINGLE_EXT("SPKR_VI_1", SND_SOC_NOPM, MSM_SDW_TX0, 1, 0, + msm_sdw_vi_feed_mixer_get, msm_sdw_vi_feed_mixer_put), + SOC_SINGLE_EXT("SPKR_VI_2", SND_SOC_NOPM, MSM_SDW_TX1, 1, 0, + msm_sdw_vi_feed_mixer_get, msm_sdw_vi_feed_mixer_put), +}; + +static const struct snd_soc_dapm_widget msm_sdw_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN("I2S RX4", "AIF1_SDW Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_IN("I2S RX5", "AIF1_SDW Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_OUT_E("AIF1_SDW VI", "VIfeed_SDW", 0, SND_SOC_NOPM, + AIF1_SDW_VIFEED, 0, msm_sdw_codec_enable_vi_feedback, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("AIF1_VI_SDW Mixer", SND_SOC_NOPM, AIF1_SDW_VIFEED, + 0, aif1_vi_mixer, ARRAY_SIZE(aif1_vi_mixer)), + + SND_SOC_DAPM_MUX_E("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx4_mix1_inp1_mux, msm_sdw_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx4_mix1_inp2_mux, msm_sdw_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX5 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx5_mix1_inp1_mux, msm_sdw_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX5 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx5_mix1_inp2_mux, msm_sdw_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("RX4 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX5 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MIXER_E("RX INT4 INTERP", SND_SOC_NOPM, + COMP1, 0, NULL, 0, msm_sdw_codec_enable_interpolator, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX INT5 INTERP", SND_SOC_NOPM, + COMP2, 0, NULL, 0, msm_sdw_codec_enable_interpolator, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER_E("RX INT4 CHAIN", SND_SOC_NOPM, 0, 0, + NULL, 0, msm_sdw_codec_spk_boost_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX INT5 CHAIN", SND_SOC_NOPM, 0, 0, + NULL, 0, msm_sdw_codec_spk_boost_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_INPUT("VIINPUT_SDW"), + + SND_SOC_DAPM_OUTPUT("SPK1 OUT"), + SND_SOC_DAPM_OUTPUT("SPK2 OUT"), + + SND_SOC_DAPM_SUPPLY_S("SDW_CONN", -1, MSM_SDW_TOP_I2S_CLK, + 0, 0, NULL, 0), + + SND_SOC_DAPM_SUPPLY_S("INT_MCLK1", -2, SND_SOC_NOPM, 0, 0, + msm_int_mclk1_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("SDW_RX_I2S_CLK", + MSM_SDW_TOP_RX_I2S_CTL, 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("SDW_TX_I2S_CLK", + MSM_SDW_TOP_TX_I2S_CTL, 0, 0, NULL, 0), +}; + +static const struct snd_kcontrol_new msm_sdw_snd_controls[] = { + SOC_ENUM_EXT("EAR SPKR PA Gain", msm_sdw_ear_spkr_pa_gain_enum, + msm_sdw_ear_spkr_pa_gain_get, + msm_sdw_ear_spkr_pa_gain_put), + SOC_SINGLE_SX_TLV("RX4 Digital Volume", MSM_SDW_RX7_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX5 Digital Volume", MSM_SDW_RX8_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMP1, 1, 0, + msm_sdw_get_compander, msm_sdw_set_compander), + SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMP2, 1, 0, + msm_sdw_get_compander, msm_sdw_set_compander), +}; + +static const struct snd_soc_dapm_route audio_map[] = { + + {"AIF1_SDW VI", NULL, "SDW_TX_I2S_CLK"}, + {"SDW_TX_I2S_CLK", NULL, "INT_MCLK1"}, + {"SDW_TX_I2S_CLK", NULL, "SDW_CONN"}, + + /* VI Feedback */ + {"AIF1_VI_SDW Mixer", "SPKR_VI_1", "VIINPUT_SDW"}, + {"AIF1_VI_SDW Mixer", "SPKR_VI_2", "VIINPUT_SDW"}, + {"AIF1_SDW VI", NULL, "AIF1_VI_SDW Mixer"}, + + {"SDW_RX_I2S_CLK", NULL, "INT_MCLK1"}, + {"SDW_RX_I2S_CLK", NULL, "SDW_CONN"}, + {"I2S RX4", NULL, "SDW_RX_I2S_CLK"}, + {"I2S RX5", NULL, "SDW_RX_I2S_CLK"}, + + {"RX4 MIX1 INP1", "RX4", "I2S RX4"}, + {"RX4 MIX1 INP1", "RX5", "I2S RX5"}, + {"RX4 MIX1 INP2", "RX4", "I2S RX4"}, + {"RX4 MIX1 INP2", "RX5", "I2S RX5"}, + {"RX5 MIX1 INP1", "RX4", "I2S RX4"}, + {"RX5 MIX1 INP1", "RX5", "I2S RX5"}, + {"RX5 MIX1 INP2", "RX4", "I2S RX4"}, + {"RX5 MIX1 INP2", "RX5", "I2S RX5"}, + + {"RX4 MIX1", NULL, "RX4 MIX1 INP1"}, + {"RX4 MIX1", NULL, "RX4 MIX1 INP2"}, + {"RX5 MIX1", NULL, "RX5 MIX1 INP1"}, + {"RX5 MIX1", NULL, "RX5 MIX1 INP2"}, + + {"RX INT4 INTERP", NULL, "RX4 MIX1"}, + {"RX INT4 CHAIN", NULL, "RX INT4 INTERP"}, + {"SPK1 OUT", NULL, "RX INT4 CHAIN"}, + + {"RX INT5 INTERP", NULL, "RX5 MIX1"}, + {"RX INT5 CHAIN", NULL, "RX INT5 INTERP"}, + {"SPK2 OUT", NULL, "RX INT5 CHAIN"}, +}; + +static const struct msm_sdw_reg_mask_val msm_sdw_reg_init[] = { + {MSM_SDW_BOOST0_BOOST_CFG1, 0x3F, 0x12}, + {MSM_SDW_BOOST0_BOOST_CFG2, 0x1C, 0x08}, + {MSM_SDW_COMPANDER7_CTL7, 0x1E, 0x18}, + {MSM_SDW_BOOST1_BOOST_CFG1, 0x3F, 0x12}, + {MSM_SDW_BOOST1_BOOST_CFG2, 0x1C, 0x08}, + {MSM_SDW_COMPANDER8_CTL7, 0x1E, 0x18}, + {MSM_SDW_BOOST0_BOOST_CTL, 0x70, 0x50}, + {MSM_SDW_BOOST1_BOOST_CTL, 0x70, 0x50}, + {MSM_SDW_RX7_RX_PATH_CFG1, 0x08, 0x08}, + {MSM_SDW_RX8_RX_PATH_CFG1, 0x08, 0x08}, + {MSM_SDW_TOP_TOP_CFG1, 0x02, 0x02}, + {MSM_SDW_TOP_TOP_CFG1, 0x01, 0x01}, + {MSM_SDW_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_COMPANDER7_CTL3, 0x80, 0x80}, + {MSM_SDW_COMPANDER8_CTL3, 0x80, 0x80}, + {MSM_SDW_COMPANDER7_CTL7, 0x01, 0x01}, + {MSM_SDW_COMPANDER8_CTL7, 0x01, 0x01}, + {MSM_SDW_RX7_RX_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_RX8_RX_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_RX7_RX_PATH_MIX_CFG, 0x01, 0x01}, + {MSM_SDW_RX8_RX_PATH_MIX_CFG, 0x01, 0x01}, +}; + +static void msm_sdw_init_reg(struct snd_soc_codec *codec) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(msm_sdw_reg_init); i++) + snd_soc_update_bits(codec, + msm_sdw_reg_init[i].reg, + msm_sdw_reg_init[i].mask, + msm_sdw_reg_init[i].val); +} + +static int msm_sdw_notifier_service_cb(struct notifier_block *nb, + unsigned long opcode, void *ptr) +{ + int i; + struct msm_sdw_priv *msm_sdw = container_of(nb, + struct msm_sdw_priv, + service_nb); + bool adsp_ready = false; + unsigned long timeout; + static bool initial_boot = true; + + pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); + + mutex_lock(&msm_sdw->codec_mutex); + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + if (initial_boot) { + initial_boot = false; + break; + } + msm_sdw->int_mclk1_enabled = false; + msm_sdw->dev_up = false; + for (i = 0; i < msm_sdw->nr; i++) + swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, + SWR_DEVICE_DOWN, NULL); + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (initial_boot) + initial_boot = false; + if (!q6core_is_adsp_ready()) { + dev_dbg(msm_sdw->dev, "ADSP isn't ready\n"); + timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + while (!time_after(jiffies, timeout)) { + if (!q6core_is_adsp_ready()) { + dev_dbg(msm_sdw->dev, + "ADSP isn't ready\n"); + } else { + dev_dbg(msm_sdw->dev, + "ADSP is ready\n"); + adsp_ready = true; + goto powerup; + } + } + } else { + adsp_ready = true; + dev_dbg(msm_sdw->dev, "%s: DSP is ready\n", __func__); + } +powerup: + if (adsp_ready) { + msm_sdw->dev_up = true; + msm_sdw_init_reg(msm_sdw->codec); + regcache_mark_dirty(msm_sdw->regmap); + regcache_sync(msm_sdw->regmap); + msm_sdw_set_spkr_mode(msm_sdw->codec, + msm_sdw->spkr_mode); + } + break; + default: + break; + } + mutex_unlock(&msm_sdw->codec_mutex); + return NOTIFY_OK; +} + +static int msm_sdw_codec_probe(struct snd_soc_codec *codec) +{ + struct msm_sdw_priv *msm_sdw; + int i, ret; + + msm_sdw = snd_soc_codec_get_drvdata(codec); + if (!msm_sdw) { + pr_err("%s:SDW priv data null\n", __func__); + return -EINVAL; + } + msm_sdw->codec = codec; + for (i = 0; i < COMP_MAX; i++) + msm_sdw->comp_enabled[i] = 0; + + msm_sdw->spkr_gain_offset = RX_GAIN_OFFSET_0_DB; + msm_sdw_init_reg(codec); + msm_sdw->version = MSM_SDW_VERSION_1_0; + + msm_sdw->service_nb.notifier_call = msm_sdw_notifier_service_cb; + ret = audio_notifier_register("msm_sdw", + AUDIO_NOTIFIER_ADSP_DOMAIN, + &msm_sdw->service_nb); + if (ret < 0) + dev_err(msm_sdw->dev, + "%s: Audio notifier register failed ret = %d\n", + __func__, ret); + return 0; +} + +static int msm_sdw_codec_remove(struct snd_soc_codec *codec) +{ + return 0; +} + +static struct regmap *msm_sdw_get_regmap(struct device *dev) +{ + struct msm_sdw_priv *msm_sdw = dev_get_drvdata(dev); + + return msm_sdw->regmap; +} + +static struct snd_soc_codec_driver soc_codec_dev_msm_sdw = { + .probe = msm_sdw_codec_probe, + .remove = msm_sdw_codec_remove, + .get_regmap = msm_sdw_get_regmap, + .component_driver = { + .controls = msm_sdw_snd_controls, + .num_controls = ARRAY_SIZE(msm_sdw_snd_controls), + .dapm_widgets = msm_sdw_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(msm_sdw_dapm_widgets), + .dapm_routes = audio_map, + .num_dapm_routes = ARRAY_SIZE(audio_map), + }, +}; + +static void msm_sdw_add_child_devices(struct work_struct *work) +{ + struct msm_sdw_priv *msm_sdw; + struct platform_device *pdev; + struct device_node *node; + struct msm_sdw_ctrl_data *sdw_ctrl_data = NULL, *temp; + int ret, ctrl_num = 0; + struct wcd_sdw_ctrl_platform_data *platdata; + char plat_dev_name[MSM_SDW_STRING_LEN]; + + msm_sdw = container_of(work, struct msm_sdw_priv, + msm_sdw_add_child_devices_work); + if (!msm_sdw) { + pr_err("%s: Memory for msm_sdw does not exist\n", + __func__); + return; + } + if (!msm_sdw->dev->of_node) { + dev_err(msm_sdw->dev, + "%s: DT node for msm_sdw does not exist\n", __func__); + return; + } + + platdata = &msm_sdw->sdw_plat_data; + + for_each_available_child_of_node(msm_sdw->dev->of_node, node) { + if (!strcmp(node->name, "swr_master")) + strlcpy(plat_dev_name, "msm_sdw_swr_ctrl", + (MSM_SDW_STRING_LEN - 1)); + else if (strnstr(node->name, "msm_cdc_pinctrl", + strlen("msm_cdc_pinctrl")) != NULL) + strlcpy(plat_dev_name, node->name, + (MSM_SDW_STRING_LEN - 1)); + else + continue; + + pdev = platform_device_alloc(plat_dev_name, -1); + if (!pdev) { + dev_err(msm_sdw->dev, "%s: pdev memory alloc failed\n", + __func__); + ret = -ENOMEM; + goto err; + } + pdev->dev.parent = msm_sdw->dev; + pdev->dev.of_node = node; + + if (!strcmp(node->name, "swr_master")) { + ret = platform_device_add_data(pdev, platdata, + sizeof(*platdata)); + if (ret) { + dev_err(&pdev->dev, + "%s: cannot add plat data ctrl:%d\n", + __func__, ctrl_num); + goto fail_pdev_add; + } + } + + ret = platform_device_add(pdev); + if (ret) { + dev_err(&pdev->dev, + "%s: Cannot add platform device\n", + __func__); + goto fail_pdev_add; + } + + if (!strcmp(node->name, "swr_master")) { + temp = krealloc(sdw_ctrl_data, + (ctrl_num + 1) * sizeof( + struct msm_sdw_ctrl_data), + GFP_KERNEL); + if (!temp) { + dev_err(&pdev->dev, "out of memory\n"); + ret = -ENOMEM; + goto err; + } + sdw_ctrl_data = temp; + sdw_ctrl_data[ctrl_num].sdw_pdev = pdev; + ctrl_num++; + dev_dbg(&pdev->dev, + "%s: Added soundwire ctrl device(s)\n", + __func__); + msm_sdw->nr = ctrl_num; + msm_sdw->sdw_ctrl_data = sdw_ctrl_data; + } + } + + return; +fail_pdev_add: + platform_device_put(pdev); +err: + return; +} + +static int msm_sdw_probe(struct platform_device *pdev) +{ + int ret = 0; + struct msm_sdw_priv *msm_sdw; + int adsp_state; + + adsp_state = apr_get_subsys_state(); + if (adsp_state != APR_SUBSYS_LOADED) { + dev_err(&pdev->dev, "Adsp is not loaded yet %d\n", + adsp_state); + return -EPROBE_DEFER; + } + + msm_sdw = devm_kzalloc(&pdev->dev, sizeof(struct msm_sdw_priv), + GFP_KERNEL); + if (!msm_sdw) + return -ENOMEM; + dev_set_drvdata(&pdev->dev, msm_sdw); + msm_sdw->dev_up = true; + + msm_sdw->dev = &pdev->dev; + INIT_WORK(&msm_sdw->msm_sdw_add_child_devices_work, + msm_sdw_add_child_devices); + msm_sdw->sdw_plat_data.handle = (void *) msm_sdw; + msm_sdw->sdw_plat_data.read = msm_sdw_swrm_read; + msm_sdw->sdw_plat_data.write = msm_sdw_swrm_write; + msm_sdw->sdw_plat_data.bulk_write = msm_sdw_swrm_bulk_write; + msm_sdw->sdw_plat_data.clk = msm_sdw_swrm_clock; + msm_sdw->sdw_plat_data.handle_irq = msm_sdwm_handle_irq; + ret = of_property_read_u32(pdev->dev.of_node, "reg", + &msm_sdw->sdw_base_addr); + if (ret) { + dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "reg"); + goto err_sdw_cdc; + } + + msm_sdw->sdw_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-sdw-gpios", 0); + msm_sdw->sdw_base = ioremap(msm_sdw->sdw_base_addr, + MSM_SDW_MAX_REGISTER); + msm_sdw->read_dev = __msm_sdw_reg_read; + msm_sdw->write_dev = __msm_sdw_reg_write; + + msm_sdw->regmap = msm_sdw_regmap_init(msm_sdw->dev, + &msm_sdw_regmap_config); + msm_sdw->sdw_irq = platform_get_irq_byname(pdev, "swr_master_irq"); + if (msm_sdw->sdw_irq < 0) { + dev_err(msm_sdw->dev, "%s() error getting irq handle: %d\n", + __func__, msm_sdw->sdw_irq); + ret = -ENODEV; + goto err_sdw_cdc; + } + ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_msm_sdw, + msm_sdw_dai, ARRAY_SIZE(msm_sdw_dai)); + if (ret) { + dev_err(&pdev->dev, "%s: Codec registration failed, ret = %d\n", + __func__, ret); + goto err_sdw_cdc; + } + /* initialize the int_mclk1 */ + msm_sdw->sdw_cdc_core_clk.clk_set_minor_version = + AFE_API_VERSION_I2S_CONFIG; + msm_sdw->sdw_cdc_core_clk.clk_id = + Q6AFE_LPASS_CLK_ID_INT_MCLK_1; + msm_sdw->sdw_cdc_core_clk.clk_freq_in_hz = + INT_MCLK1_FREQ; + msm_sdw->sdw_cdc_core_clk.clk_attri = + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO; + msm_sdw->sdw_cdc_core_clk.clk_root = + Q6AFE_LPASS_CLK_ROOT_DEFAULT; + msm_sdw->sdw_cdc_core_clk.enable = 0; + + /* initialize the sdw_npl_clk */ + msm_sdw->sdw_npl_clk.clk_set_minor_version = + AFE_API_VERSION_I2S_CONFIG; + msm_sdw->sdw_npl_clk.clk_id = + AFE_CLOCK_SET_CLOCK_ID_SWR_NPL_CLK; + msm_sdw->sdw_npl_clk.clk_freq_in_hz = SDW_NPL_FREQ; + msm_sdw->sdw_npl_clk.clk_attri = + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO; + msm_sdw->sdw_npl_clk.clk_root = + Q6AFE_LPASS_CLK_ROOT_DEFAULT; + msm_sdw->sdw_npl_clk.enable = 0; + + INIT_DELAYED_WORK(&msm_sdw->disable_int_mclk1_work, + msm_disable_int_mclk1); + mutex_init(&msm_sdw->cdc_int_mclk1_mutex); + mutex_init(&msm_sdw->sdw_npl_clk_mutex); + mutex_init(&msm_sdw->io_lock); + mutex_init(&msm_sdw->sdw_read_lock); + mutex_init(&msm_sdw->sdw_write_lock); + mutex_init(&msm_sdw->sdw_clk_lock); + mutex_init(&msm_sdw->codec_mutex); + schedule_work(&msm_sdw->msm_sdw_add_child_devices_work); + + dev_dbg(&pdev->dev, "%s: msm_sdw driver probe done\n", __func__); + return ret; + +err_sdw_cdc: + devm_kfree(&pdev->dev, msm_sdw); + return ret; +} + +static int msm_sdw_remove(struct platform_device *pdev) +{ + struct msm_sdw_priv *msm_sdw; + + msm_sdw = dev_get_drvdata(&pdev->dev); + + mutex_destroy(&msm_sdw->io_lock); + mutex_destroy(&msm_sdw->sdw_read_lock); + mutex_destroy(&msm_sdw->sdw_write_lock); + mutex_destroy(&msm_sdw->sdw_clk_lock); + mutex_destroy(&msm_sdw->codec_mutex); + mutex_destroy(&msm_sdw->cdc_int_mclk1_mutex); + devm_kfree(&pdev->dev, msm_sdw); + snd_soc_unregister_codec(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_sdw_codec_dt_match[] = { + { .compatible = "qcom,msm-sdw-codec", }, + {} +}; + +static struct platform_driver msm_sdw_codec_driver = { + .probe = msm_sdw_probe, + .remove = msm_sdw_remove, + .driver = { + .name = "msm_sdw_codec", + .owner = THIS_MODULE, + .of_match_table = msm_sdw_codec_dt_match, + }, +}; +module_platform_driver(msm_sdw_codec_driver); + +MODULE_DESCRIPTION("MSM Soundwire Codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/msm_sdw/msm_sdw_cdc_utils.c b/sound/soc/codecs/msm_sdw/msm_sdw_cdc_utils.c new file mode 100644 index 000000000000..9a5c85bf0c6c --- /dev/null +++ b/sound/soc/codecs/msm_sdw/msm_sdw_cdc_utils.c @@ -0,0 +1,211 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "msm_sdw.h" + +#define REG_BYTES 2 +#define VAL_BYTES 1 +/* + * Page Register Address that APP Proc uses to + * access WCD9335 Codec registers is identified + * as 0x00 + */ +#define PAGE_REG_ADDR 0x00 + +/* + * msm_sdw_page_write: + * Retrieve page number from register and + * write that page number to the page address. + * Called under io_lock acquisition. + * + * @msm_sdw: pointer to msm_sdw + * @reg: Register address from which page number is retrieved + * + * Returns 0 for success and negative error code for failure. + */ +int msm_sdw_page_write(struct msm_sdw_priv *msm_sdw, unsigned short reg) +{ + int ret = 0; + u8 pg_num, prev_pg_num; + + pg_num = msm_sdw_page_map[reg]; + if (msm_sdw->prev_pg_valid) { + prev_pg_num = msm_sdw->prev_pg; + if (prev_pg_num != pg_num) { + ret = msm_sdw->write_dev(msm_sdw, PAGE_REG_ADDR, 1, + (void *) &pg_num); + if (ret < 0) { + dev_err(msm_sdw->dev, + "page write error, pg_num: 0x%x\n", + pg_num); + } else { + msm_sdw->prev_pg = pg_num; + dev_dbg(msm_sdw->dev, + "%s: Page 0x%x Write to 0x00\n", + __func__, pg_num); + } + } + } else { + ret = msm_sdw->write_dev(msm_sdw, PAGE_REG_ADDR, 1, + (void *) &pg_num); + if (ret < 0) { + dev_err(msm_sdw->dev, + "page write error, pg_num: 0x%x\n", pg_num); + } else { + msm_sdw->prev_pg = pg_num; + msm_sdw->prev_pg_valid = true; + dev_dbg(msm_sdw->dev, "%s: Page 0x%x Write to 0x00\n", + __func__, pg_num); + } + } + return ret; +} +EXPORT_SYMBOL(msm_sdw_page_write); + +static int regmap_bus_read(void *context, const void *reg, size_t reg_size, + void *val, size_t val_size) +{ + struct device *dev = context; + struct msm_sdw_priv *msm_sdw = dev_get_drvdata(dev); + unsigned short c_reg; + int ret, i; + + if (!msm_sdw) { + dev_err(dev, "%s: msm_sdw is NULL\n", __func__); + return -EINVAL; + } + if (!reg || !val) { + dev_err(dev, "%s: reg or val is NULL\n", __func__); + return -EINVAL; + } + if (reg_size != REG_BYTES) { + dev_err(dev, "%s: register size %zd bytes, not supported\n", + __func__, reg_size); + return -EINVAL; + } + if (!msm_sdw->dev_up) { + dev_dbg_ratelimited(dev, "%s: No read allowed. dev_up = %d\n", + __func__, msm_sdw->dev_up); + return 0; + } + + mutex_lock(&msm_sdw->io_lock); + c_reg = *(u16 *)reg; + ret = msm_sdw_page_write(msm_sdw, c_reg); + if (ret) + goto err; + ret = msm_sdw->read_dev(msm_sdw, c_reg, val_size, val); + if (ret < 0) + dev_err(dev, "%s: Codec read failed (%d), reg: 0x%x, size:%zd\n", + __func__, ret, c_reg, val_size); + else { + for (i = 0; i < val_size; i++) + dev_dbg(dev, "%s: Read 0x%02x from 0x%x\n", + __func__, ((u8 *)val)[i], c_reg + i); + } +err: + mutex_unlock(&msm_sdw->io_lock); + + return ret; +} + +static int regmap_bus_gather_write(void *context, + const void *reg, size_t reg_size, + const void *val, size_t val_size) +{ + struct device *dev = context; + struct msm_sdw_priv *msm_sdw = dev_get_drvdata(dev); + unsigned short c_reg; + int ret, i; + + if (!msm_sdw) { + dev_err(dev, "%s: msm_sdw is NULL\n", __func__); + return -EINVAL; + } + if (!reg || !val) { + dev_err(dev, "%s: reg or val is NULL\n", __func__); + return -EINVAL; + } + if (reg_size != REG_BYTES) { + dev_err(dev, "%s: register size %zd bytes, not supported\n", + __func__, reg_size); + return -EINVAL; + } + if (!msm_sdw->dev_up) { + dev_dbg_ratelimited(dev, "%s: No write allowed. dev_up = %d\n", + __func__, msm_sdw->dev_up); + return 0; + } + + mutex_lock(&msm_sdw->io_lock); + c_reg = *(u16 *)reg; + ret = msm_sdw_page_write(msm_sdw, c_reg); + if (ret) + goto err; + + for (i = 0; i < val_size; i++) + dev_dbg(dev, "Write %02x to 0x%x\n", ((u8 *)val)[i], + c_reg + i*4); + + ret = msm_sdw->write_dev(msm_sdw, c_reg, val_size, (void *) val); + if (ret < 0) + dev_err(dev, + "%s: Codec write failed (%d), reg:0x%x, size:%zd\n", + __func__, ret, c_reg, val_size); + +err: + mutex_unlock(&msm_sdw->io_lock); + return ret; +} + +static int regmap_bus_write(void *context, const void *data, size_t count) +{ + struct device *dev = context; + struct msm_sdw_priv *msm_sdw = dev_get_drvdata(dev); + + if (!msm_sdw) + return -EINVAL; + + WARN_ON(count < REG_BYTES); + + return regmap_bus_gather_write(context, data, REG_BYTES, + data + REG_BYTES, + count - REG_BYTES); + +} + +static struct regmap_bus regmap_bus_config = { + .write = regmap_bus_write, + .gather_write = regmap_bus_gather_write, + .read = regmap_bus_read, + .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, + .val_format_endian_default = REGMAP_ENDIAN_NATIVE, +}; + +/* + * msm_sdw_regmap_init: + * Initialize msm_sdw register map + * + * @dev: pointer to wcd device + * @config: pointer to register map config + * + * Returns pointer to regmap structure for success + * or NULL in case of failure. + */ +struct regmap *msm_sdw_regmap_init(struct device *dev, + const struct regmap_config *config) +{ + return devm_regmap_init(dev, ®map_bus_config, dev, config); +} +EXPORT_SYMBOL(msm_sdw_regmap_init); diff --git a/sound/soc/codecs/msm_sdw/msm_sdw_registers.h b/sound/soc/codecs/msm_sdw/msm_sdw_registers.h new file mode 100644 index 000000000000..1b7b0b01a6b2 --- /dev/null +++ b/sound/soc/codecs/msm_sdw/msm_sdw_registers.h @@ -0,0 +1,126 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef MSM_SDW_REGISTERS_H +#define MSM_SDW_REGISTERS_H + +#define MSM_SDW_PAGE_REGISTER 0x0000 + +/* Page-A Registers */ +#define MSM_SDW_TX9_SPKR_PROT_PATH_CTL 0x0308 +#define MSM_SDW_TX9_SPKR_PROT_PATH_CFG0 0x030c +#define MSM_SDW_TX10_SPKR_PROT_PATH_CTL 0x0318 +#define MSM_SDW_TX10_SPKR_PROT_PATH_CFG0 0x031c +#define MSM_SDW_TX11_SPKR_PROT_PATH_CTL 0x0328 +#define MSM_SDW_TX11_SPKR_PROT_PATH_CFG0 0x032c +#define MSM_SDW_TX12_SPKR_PROT_PATH_CTL 0x0338 +#define MSM_SDW_TX12_SPKR_PROT_PATH_CFG0 0x033c + +/* Page-B Registers */ +#define MSM_SDW_COMPANDER7_CTL0 0x0024 +#define MSM_SDW_COMPANDER7_CTL1 0x0028 +#define MSM_SDW_COMPANDER7_CTL2 0x002c +#define MSM_SDW_COMPANDER7_CTL3 0x0030 +#define MSM_SDW_COMPANDER7_CTL4 0x0034 +#define MSM_SDW_COMPANDER7_CTL5 0x0038 +#define MSM_SDW_COMPANDER7_CTL6 0x003c +#define MSM_SDW_COMPANDER7_CTL7 0x0040 +#define MSM_SDW_COMPANDER8_CTL0 0x0044 +#define MSM_SDW_COMPANDER8_CTL1 0x0048 +#define MSM_SDW_COMPANDER8_CTL2 0x004c +#define MSM_SDW_COMPANDER8_CTL3 0x0050 +#define MSM_SDW_COMPANDER8_CTL4 0x0054 +#define MSM_SDW_COMPANDER8_CTL5 0x0058 +#define MSM_SDW_COMPANDER8_CTL6 0x005c +#define MSM_SDW_COMPANDER8_CTL7 0x0060 +#define MSM_SDW_RX7_RX_PATH_CTL 0x01a4 +#define MSM_SDW_RX7_RX_PATH_CFG0 0x01a8 +#define MSM_SDW_RX7_RX_PATH_CFG1 0x01ac +#define MSM_SDW_RX7_RX_PATH_CFG2 0x01b0 +#define MSM_SDW_RX7_RX_VOL_CTL 0x01b4 +#define MSM_SDW_RX7_RX_PATH_MIX_CTL 0x01b8 +#define MSM_SDW_RX7_RX_PATH_MIX_CFG 0x01bc +#define MSM_SDW_RX7_RX_VOL_MIX_CTL 0x01c0 +#define MSM_SDW_RX7_RX_PATH_SEC0 0x01c4 +#define MSM_SDW_RX7_RX_PATH_SEC1 0x01c8 +#define MSM_SDW_RX7_RX_PATH_SEC2 0x01cc +#define MSM_SDW_RX7_RX_PATH_SEC3 0x01d0 +#define MSM_SDW_RX7_RX_PATH_SEC5 0x01d8 +#define MSM_SDW_RX7_RX_PATH_SEC6 0x01dc +#define MSM_SDW_RX7_RX_PATH_SEC7 0x01e0 +#define MSM_SDW_RX7_RX_PATH_MIX_SEC0 0x01e4 +#define MSM_SDW_RX7_RX_PATH_MIX_SEC1 0x01e8 +#define MSM_SDW_RX8_RX_PATH_CTL 0x0384 +#define MSM_SDW_RX8_RX_PATH_CFG0 0x0388 +#define MSM_SDW_RX8_RX_PATH_CFG1 0x038c +#define MSM_SDW_RX8_RX_PATH_CFG2 0x0390 +#define MSM_SDW_RX8_RX_VOL_CTL 0x0394 +#define MSM_SDW_RX8_RX_PATH_MIX_CTL 0x0398 +#define MSM_SDW_RX8_RX_PATH_MIX_CFG 0x039c +#define MSM_SDW_RX8_RX_VOL_MIX_CTL 0x03a0 +#define MSM_SDW_RX8_RX_PATH_SEC0 0x03a4 +#define MSM_SDW_RX8_RX_PATH_SEC1 0x03a8 +#define MSM_SDW_RX8_RX_PATH_SEC2 0x03ac +#define MSM_SDW_RX8_RX_PATH_SEC3 0x03b0 +#define MSM_SDW_RX8_RX_PATH_SEC5 0x03b8 +#define MSM_SDW_RX8_RX_PATH_SEC6 0x03bc +#define MSM_SDW_RX8_RX_PATH_SEC7 0x03c0 +#define MSM_SDW_RX8_RX_PATH_MIX_SEC0 0x03c4 +#define MSM_SDW_RX8_RX_PATH_MIX_SEC1 0x03c8 + +/* Page-C Registers */ +#define MSM_SDW_BOOST0_BOOST_PATH_CTL 0x0064 +#define MSM_SDW_BOOST0_BOOST_CTL 0x0068 +#define MSM_SDW_BOOST0_BOOST_CFG1 0x006c +#define MSM_SDW_BOOST0_BOOST_CFG2 0x0070 +#define MSM_SDW_BOOST1_BOOST_PATH_CTL 0x0084 +#define MSM_SDW_BOOST1_BOOST_CTL 0x0088 +#define MSM_SDW_BOOST1_BOOST_CFG1 0x008c +#define MSM_SDW_BOOST1_BOOST_CFG2 0x0090 +#define MSM_SDW_AHB_BRIDGE_WR_DATA_0 0x00a4 +#define MSM_SDW_AHB_BRIDGE_WR_DATA_1 0x00a8 +#define MSM_SDW_AHB_BRIDGE_WR_DATA_2 0x00ac +#define MSM_SDW_AHB_BRIDGE_WR_DATA_3 0x00b0 +#define MSM_SDW_AHB_BRIDGE_WR_ADDR_0 0x00b4 +#define MSM_SDW_AHB_BRIDGE_WR_ADDR_1 0x00b8 +#define MSM_SDW_AHB_BRIDGE_WR_ADDR_2 0x00bc +#define MSM_SDW_AHB_BRIDGE_WR_ADDR_3 0x00c0 +#define MSM_SDW_AHB_BRIDGE_RD_ADDR_0 0x00c4 +#define MSM_SDW_AHB_BRIDGE_RD_ADDR_1 0x00c8 +#define MSM_SDW_AHB_BRIDGE_RD_ADDR_2 0x00cc +#define MSM_SDW_AHB_BRIDGE_RD_ADDR_3 0x00d0 +#define MSM_SDW_AHB_BRIDGE_RD_DATA_0 0x00d4 +#define MSM_SDW_AHB_BRIDGE_RD_DATA_1 0x00d8 +#define MSM_SDW_AHB_BRIDGE_RD_DATA_2 0x00dc +#define MSM_SDW_AHB_BRIDGE_RD_DATA_3 0x00e0 +#define MSM_SDW_AHB_BRIDGE_ACCESS_CFG 0x00e4 +#define MSM_SDW_AHB_BRIDGE_ACCESS_STATUS 0x00e8 + +/* Page-D Registers */ +#define MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL 0x0104 +#define MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL 0x0108 +#define MSM_SDW_CLK_RST_CTRL_SWR_CONTROL 0x010c +#define MSM_SDW_TOP_TOP_CFG0 0x0204 +#define MSM_SDW_TOP_TOP_CFG1 0x0208 +#define MSM_SDW_TOP_RX_I2S_CTL 0x020c +#define MSM_SDW_TOP_TX_I2S_CTL 0x0210 +#define MSM_SDW_TOP_I2S_CLK 0x0214 +#define MSM_SDW_TOP_RX7_PATH_INPUT0_MUX 0x0218 +#define MSM_SDW_TOP_RX7_PATH_INPUT1_MUX 0x021c +#define MSM_SDW_TOP_RX8_PATH_INPUT0_MUX 0x0220 +#define MSM_SDW_TOP_RX8_PATH_INPUT1_MUX 0x0224 +#define MSM_SDW_TOP_FREQ_MCLK 0x0228 +#define MSM_SDW_TOP_DEBUG_BUS_SEL 0x022c +#define MSM_SDW_TOP_DEBUG_EN 0x0230 +#define MSM_SDW_TOP_I2S_RESET 0x0234 +#define MSM_SDW_TOP_BLOCKS_RESET 0x0238 + +#endif diff --git a/sound/soc/codecs/msm_sdw/msm_sdw_regmap.c b/sound/soc/codecs/msm_sdw/msm_sdw_regmap.c new file mode 100644 index 000000000000..22663384ec35 --- /dev/null +++ b/sound/soc/codecs/msm_sdw/msm_sdw_regmap.c @@ -0,0 +1,161 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "msm_sdw.h" + +static const struct reg_default msm_sdw_defaults[] = { + /* Page #10 registers */ + { MSM_SDW_PAGE_REGISTER, 0x00 }, + { MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x02 }, + { MSM_SDW_TX9_SPKR_PROT_PATH_CFG0, 0x00 }, + { MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x02 }, + { MSM_SDW_TX10_SPKR_PROT_PATH_CFG0, 0x00 }, + { MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x02 }, + { MSM_SDW_TX11_SPKR_PROT_PATH_CFG0, 0x00 }, + { MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x02 }, + { MSM_SDW_TX12_SPKR_PROT_PATH_CFG0, 0x00 }, + /* Page #11 registers */ + { MSM_SDW_COMPANDER7_CTL0, 0x60 }, + { MSM_SDW_COMPANDER7_CTL1, 0xdb }, + { MSM_SDW_COMPANDER7_CTL2, 0xff }, + { MSM_SDW_COMPANDER7_CTL3, 0x35 }, + { MSM_SDW_COMPANDER7_CTL4, 0xff }, + { MSM_SDW_COMPANDER7_CTL5, 0x00 }, + { MSM_SDW_COMPANDER7_CTL6, 0x01 }, + { MSM_SDW_COMPANDER8_CTL0, 0x60 }, + { MSM_SDW_COMPANDER8_CTL1, 0xdb }, + { MSM_SDW_COMPANDER8_CTL2, 0xff }, + { MSM_SDW_COMPANDER8_CTL3, 0x35 }, + { MSM_SDW_COMPANDER8_CTL4, 0xff }, + { MSM_SDW_COMPANDER8_CTL5, 0x00 }, + { MSM_SDW_COMPANDER8_CTL6, 0x01 }, + { MSM_SDW_RX7_RX_PATH_CTL, 0x04 }, + { MSM_SDW_RX7_RX_PATH_CFG0, 0x00 }, + { MSM_SDW_RX7_RX_PATH_CFG2, 0x8f }, + { MSM_SDW_RX7_RX_VOL_CTL, 0x00 }, + { MSM_SDW_RX7_RX_PATH_MIX_CTL, 0x04 }, + { MSM_SDW_RX7_RX_VOL_MIX_CTL, 0x00 }, + { MSM_SDW_RX7_RX_PATH_SEC2, 0x00 }, + { MSM_SDW_RX7_RX_PATH_SEC3, 0x00 }, + { MSM_SDW_RX7_RX_PATH_SEC5, 0x00 }, + { MSM_SDW_RX7_RX_PATH_SEC6, 0x00 }, + { MSM_SDW_RX7_RX_PATH_SEC7, 0x00 }, + { MSM_SDW_RX7_RX_PATH_MIX_SEC1, 0x00 }, + { MSM_SDW_RX8_RX_PATH_CTL, 0x04 }, + { MSM_SDW_RX8_RX_PATH_CFG0, 0x00 }, + { MSM_SDW_RX8_RX_PATH_CFG2, 0x8f }, + { MSM_SDW_RX8_RX_VOL_CTL, 0x00 }, + { MSM_SDW_RX8_RX_PATH_MIX_CTL, 0x04 }, + { MSM_SDW_RX8_RX_VOL_MIX_CTL, 0x00 }, + { MSM_SDW_RX8_RX_PATH_SEC2, 0x00 }, + { MSM_SDW_RX8_RX_PATH_SEC3, 0x00 }, + { MSM_SDW_RX8_RX_PATH_SEC5, 0x00 }, + { MSM_SDW_RX8_RX_PATH_SEC6, 0x00 }, + { MSM_SDW_RX8_RX_PATH_SEC7, 0x00 }, + { MSM_SDW_RX8_RX_PATH_MIX_SEC1, 0x00 }, + /* Page #12 registers */ + { MSM_SDW_BOOST0_BOOST_PATH_CTL, 0x00 }, + { MSM_SDW_BOOST0_BOOST_CTL, 0xb2 }, + { MSM_SDW_BOOST0_BOOST_CFG1, 0x00 }, + { MSM_SDW_BOOST0_BOOST_CFG2, 0x00 }, + { MSM_SDW_BOOST1_BOOST_PATH_CTL, 0x00 }, + { MSM_SDW_BOOST1_BOOST_CTL, 0xb2 }, + { MSM_SDW_BOOST1_BOOST_CFG1, 0x00 }, + { MSM_SDW_BOOST1_BOOST_CFG2, 0x00 }, + { MSM_SDW_AHB_BRIDGE_WR_DATA_0, 0x00 }, + { MSM_SDW_AHB_BRIDGE_WR_DATA_1, 0x00 }, + { MSM_SDW_AHB_BRIDGE_WR_DATA_2, 0x00 }, + { MSM_SDW_AHB_BRIDGE_WR_DATA_3, 0x00 }, + { MSM_SDW_AHB_BRIDGE_WR_ADDR_0, 0x00 }, + { MSM_SDW_AHB_BRIDGE_WR_ADDR_1, 0x00 }, + { MSM_SDW_AHB_BRIDGE_WR_ADDR_2, 0x00 }, + { MSM_SDW_AHB_BRIDGE_WR_ADDR_3, 0x00 }, + { MSM_SDW_AHB_BRIDGE_RD_ADDR_0, 0x00 }, + { MSM_SDW_AHB_BRIDGE_RD_ADDR_1, 0x00 }, + { MSM_SDW_AHB_BRIDGE_RD_ADDR_2, 0x00 }, + { MSM_SDW_AHB_BRIDGE_RD_ADDR_3, 0x00 }, + { MSM_SDW_AHB_BRIDGE_RD_DATA_0, 0x00 }, + { MSM_SDW_AHB_BRIDGE_RD_DATA_1, 0x00 }, + { MSM_SDW_AHB_BRIDGE_RD_DATA_2, 0x00 }, + { MSM_SDW_AHB_BRIDGE_RD_DATA_3, 0x00 }, + { MSM_SDW_AHB_BRIDGE_ACCESS_CFG, 0x0f }, + { MSM_SDW_AHB_BRIDGE_ACCESS_STATUS, 0x03 }, + /* Page #13 registers */ + { MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL, 0x00 }, + { MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00 }, + { MSM_SDW_CLK_RST_CTRL_SWR_CONTROL, 0x00 }, + { MSM_SDW_TOP_TOP_CFG0, 0x00 }, + { MSM_SDW_TOP_TOP_CFG1, 0x00 }, + { MSM_SDW_TOP_RX_I2S_CTL, 0x0C }, + { MSM_SDW_TOP_TX_I2S_CTL, 0x00 }, + { MSM_SDW_TOP_I2S_CLK, 0x00 }, + { MSM_SDW_TOP_RX7_PATH_INPUT0_MUX, 0x00 }, + { MSM_SDW_TOP_RX7_PATH_INPUT1_MUX, 0x00 }, + { MSM_SDW_TOP_RX8_PATH_INPUT0_MUX, 0x00 }, + { MSM_SDW_TOP_RX8_PATH_INPUT1_MUX, 0x00 }, + { MSM_SDW_TOP_FREQ_MCLK, 0x00 }, + { MSM_SDW_TOP_DEBUG_BUS_SEL, 0x00 }, + { MSM_SDW_TOP_DEBUG_EN, 0x00 }, + { MSM_SDW_TOP_I2S_RESET, 0x00 }, + { MSM_SDW_TOP_BLOCKS_RESET, 0x00 }, +}; + +static bool msm_sdw_is_readable_register(struct device *dev, unsigned int reg) +{ + return msm_sdw_reg_readable[reg]; +} + +static bool msm_sdw_is_writeable_register(struct device *dev, unsigned int reg) +{ + return msm_sdw_reg_writeable[reg]; +} + +static bool msm_sdw_is_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MSM_SDW_AHB_BRIDGE_WR_DATA_0: + case MSM_SDW_AHB_BRIDGE_WR_DATA_1: + case MSM_SDW_AHB_BRIDGE_WR_DATA_2: + case MSM_SDW_AHB_BRIDGE_WR_DATA_3: + case MSM_SDW_AHB_BRIDGE_WR_ADDR_0: + case MSM_SDW_AHB_BRIDGE_WR_ADDR_1: + case MSM_SDW_AHB_BRIDGE_WR_ADDR_2: + case MSM_SDW_AHB_BRIDGE_WR_ADDR_3: + case MSM_SDW_AHB_BRIDGE_RD_DATA_0: + case MSM_SDW_AHB_BRIDGE_RD_DATA_1: + case MSM_SDW_AHB_BRIDGE_RD_DATA_2: + case MSM_SDW_AHB_BRIDGE_RD_DATA_3: + case MSM_SDW_AHB_BRIDGE_RD_ADDR_0: + case MSM_SDW_AHB_BRIDGE_RD_ADDR_1: + case MSM_SDW_AHB_BRIDGE_RD_ADDR_2: + case MSM_SDW_AHB_BRIDGE_RD_ADDR_3: + case MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL: + case MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL: + return true; + default: + return false; + } +} + +const struct regmap_config msm_sdw_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .reg_stride = 4, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = msm_sdw_defaults, + .num_reg_defaults = ARRAY_SIZE(msm_sdw_defaults), + .max_register = MSM_SDW_MAX_REGISTER, + .writeable_reg = msm_sdw_is_writeable_register, + .volatile_reg = msm_sdw_is_volatile_register, + .readable_reg = msm_sdw_is_readable_register, +}; -- GitLab From 84f7f7314410065b7fb0cd4100e1073b6e2ca1a0 Mon Sep 17 00:00:00 2001 From: Asish Bhattacharya Date: Tue, 25 Jul 2017 16:29:27 +0530 Subject: [PATCH 0005/1645] audio-lnx: Add latest snapshot for audio drivers. Propagate the changes based on latest snapshot for audio kernel source tree. Change-Id: I15cdbf2651ee8bf70a56b08013e1fbce16859d9b Signed-off-by: Asish Bhattacharya --- drivers/mfd/wcd9xxx-core.c | 49 ++- drivers/pinctrl/qcom/pinctrl-lpi.c | 3 +- include/linux/mfd/wcd9xxx/core.h | 2 +- include/uapi/sound/devdep_params.h | 10 + sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c | 24 +- sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c | 16 +- sound/soc/codecs/wcd-dsp-mgr.c | 3 +- sound/soc/codecs/wcd-mbhc-v2.c | 44 ++- sound/soc/codecs/wcd-mbhc-v2.h | 18 +- sound/soc/codecs/wcd9335.c | 89 ++++-- sound/soc/codecs/wcd934x/wcd934x-mbhc.c | 56 +++- sound/soc/codecs/wcd934x/wcd934x-routing.h | 64 ++++ sound/soc/codecs/wcd934x/wcd934x.c | 187 ++++++++++++ sound/soc/codecs/wcd934x/wcd934x.h | 1 + sound/soc/codecs/wcd_cpe_services.c | 289 +----------------- sound/soc/msm/qdsp6v2/audio_calibration.c | 14 +- sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c | 150 ++++++++- sound/soc/msm/sdm660-common.c | 39 +-- sound/soc/msm/sdm660-ext-dai-links.c | 176 +++++------ sound/soc/msm/sdm660-external.c | 55 ++-- sound/soc/msm/sdm660-internal.c | 176 +++++------ sound/soc/msm/sdm845.c | 160 +++++++++- 22 files changed, 1041 insertions(+), 584 deletions(-) diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c index b373acb11005..232c290bfb55 100644 --- a/drivers/mfd/wcd9xxx-core.c +++ b/drivers/mfd/wcd9xxx-core.c @@ -228,7 +228,7 @@ static int wcd9xxx_slim_read_device(struct wcd9xxx *wcd9xxx, unsigned short reg, if (!wcd9xxx->dev_up) { dev_dbg_ratelimited( - wcd9xxx->dev, "%s: No read allowed. dev_up = %d\n", + wcd9xxx->dev, "%s: No read allowed. dev_up = %lu\n", __func__, wcd9xxx->dev_up); return 0; } @@ -268,7 +268,7 @@ static int wcd9xxx_slim_write_device(struct wcd9xxx *wcd9xxx, if (!wcd9xxx->dev_up) { dev_dbg_ratelimited( - wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n", + wcd9xxx->dev, "%s: No write allowed. dev_up = %lu\n", __func__, wcd9xxx->dev_up); return 0; } @@ -345,7 +345,7 @@ int wcd9xxx_slim_write_repeat(struct wcd9xxx *wcd9xxx, unsigned short reg, if (!wcd9xxx->dev_up) { dev_dbg_ratelimited( - wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n", + wcd9xxx->dev, "%s: No write allowed. dev_up = %lu\n", __func__, wcd9xxx->dev_up); ret = 0; goto done; @@ -426,7 +426,7 @@ int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx, if (!wcd9xxx->dev_up) { dev_dbg_ratelimited( - wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n", + wcd9xxx->dev, "%s: No write allowed. dev_up = %lu\n", __func__, wcd9xxx->dev_up); return 0; } @@ -1479,12 +1479,27 @@ static int wcd9xxx_slim_device_reset(struct slim_device *sldev) return -EINVAL; } - dev_info(wcd9xxx->dev, "%s: device reset, dev_up = %d\n", - __func__, wcd9xxx->dev_up); - if (wcd9xxx->dev_up) - return 0; + /* + * Wait for 500 ms for device down to complete. Observed delay + * of ~200ms for device down to complete after being called, + * due to context switch issue. + */ + ret = wait_on_bit_timeout(&wcd9xxx->dev_up, 0, + TASK_INTERRUPTIBLE, + msecs_to_jiffies(500)); + if (ret) + pr_err("%s: slim device down not complete in 500 msec\n", + __func__); mutex_lock(&wcd9xxx->reset_lock); + + dev_info(wcd9xxx->dev, "%s: device reset, dev_up = %lu\n", + __func__, wcd9xxx->dev_up); + if (wcd9xxx->dev_up) { + mutex_unlock(&wcd9xxx->reset_lock); + return 0; + } + ret = wcd9xxx_reset(wcd9xxx->dev); if (ret) dev_err(wcd9xxx->dev, "%s: Resetting Codec failed\n", __func__); @@ -1502,8 +1517,8 @@ static int wcd9xxx_slim_device_up(struct slim_device *sldev) pr_err("%s: wcd9xxx is NULL\n", __func__); return -EINVAL; } - dev_info(wcd9xxx->dev, "%s: slim device up, dev_up = %d\n", - __func__, wcd9xxx->dev_up); + dev_info(wcd9xxx->dev, "%s: slim device up, dev_up = %lu\n", + __func__, wcd9xxx->dev_up); if (wcd9xxx->dev_up) return 0; @@ -1525,18 +1540,20 @@ static int wcd9xxx_slim_device_down(struct slim_device *sldev) return -EINVAL; } - dev_info(wcd9xxx->dev, "%s: device down, dev_up = %d\n", - __func__, wcd9xxx->dev_up); - if (!wcd9xxx->dev_up) - return 0; + mutex_lock(&wcd9xxx->reset_lock); - wcd9xxx->dev_up = false; + dev_info(wcd9xxx->dev, "%s: device down, dev_up = %lu\n", + __func__, wcd9xxx->dev_up); + if (!wcd9xxx->dev_up) { + mutex_unlock(&wcd9xxx->reset_lock); + return 0; + } - mutex_lock(&wcd9xxx->reset_lock); if (wcd9xxx->dev_down) wcd9xxx->dev_down(wcd9xxx); wcd9xxx_irq_exit(&wcd9xxx->core_res); wcd9xxx_reset_low(wcd9xxx->dev); + wcd9xxx->dev_up = false; mutex_unlock(&wcd9xxx->reset_lock); return 0; diff --git a/drivers/pinctrl/qcom/pinctrl-lpi.c b/drivers/pinctrl/qcom/pinctrl-lpi.c index fedd5f0aee22..11f954e1eb6c 100644 --- a/drivers/pinctrl/qcom/pinctrl-lpi.c +++ b/drivers/pinctrl/qcom/pinctrl-lpi.c @@ -448,6 +448,7 @@ static void lpi_gpio_dbg_show_one(struct seq_file *s, unsigned int offset, unsigned int gpio) { + struct lpi_gpio_state *state = gpiochip_get_data(chip); struct pinctrl_pin_desc pindesc; struct lpi_gpio_pad *pad; unsigned int func; @@ -463,7 +464,7 @@ static void lpi_gpio_dbg_show_one(struct seq_file *s, "pull up" }; - pctldev = pctldev ? : to_gpio_state(chip)->ctrl; + pctldev = pctldev ? : state->ctrl; pindesc = pctldev->desc->pins[offset]; pad = pctldev->desc->pins[offset].drv_data; ctl_reg = lpi_gpio_read(pad, LPI_GPIO_REG_DIR_CTL); diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h index b4c1be40ff31..b994010f5222 100644 --- a/include/linux/mfd/wcd9xxx/core.h +++ b/include/linux/mfd/wcd9xxx/core.h @@ -350,7 +350,7 @@ struct wcd9xxx { int (*post_reset)(struct wcd9xxx *wcd9xxx); void *ssr_priv; - bool dev_up; + unsigned long dev_up; u32 num_of_supplies; struct regulator_bulk_data *supplies; diff --git a/include/uapi/sound/devdep_params.h b/include/uapi/sound/devdep_params.h index 6697eca288fe..66a9cacfcab9 100644 --- a/include/uapi/sound/devdep_params.h +++ b/include/uapi/sound/devdep_params.h @@ -53,4 +53,14 @@ struct dts_eagle_param_desc { uint32_t device; } __packed; +#define HWDEP_FE_BASE 3000 /*unique base for FE hw dep nodes*/ +struct snd_pcm_mmap_fd { + int32_t dir; + int32_t fd; + int32_t size; + int32_t actual_size; +}; + +#define SNDRV_PCM_IOCTL_MMAP_DATA_FD _IOWR('U', 0xd2, struct snd_pcm_mmap_fd) + #endif diff --git a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c index a8fcd347b38b..f126d35dee81 100644 --- a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c +++ b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c @@ -2055,6 +2055,9 @@ static const char * const rdac2_mux_text[] = { "ZERO", "RX2", "RX1" }; +static const struct snd_kcontrol_new adc1_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + static const struct soc_enum rdac2_mux_enum = SOC_ENUM_SINGLE(MSM89XX_PMIC_DIGITAL_CDC_CONN_HPHR_DAC_CTL, 0, 3, rdac2_mux_text); @@ -3105,7 +3108,8 @@ static const struct snd_soc_dapm_route audio_map[] = { {"ADC2 MUX", "INP2", "ADC2_INP2"}, {"ADC2 MUX", "INP3", "ADC2_INP3"}, - {"ADC1", NULL, "AMIC1"}, + {"ADC1", NULL, "ADC1_INP1"}, + {"ADC1_INP1", "Switch", "AMIC1"}, {"ADC2_INP2", NULL, "AMIC2"}, {"ADC2_INP3", NULL, "AMIC3"}, @@ -3446,6 +3450,8 @@ static const struct snd_soc_dapm_widget msm_anlg_cdc_dapm_widgets[] = { SND_SOC_DAPM_SPK("Ext Spk", msm_anlg_cdc_codec_enable_spk_ext_pa), + SND_SOC_DAPM_SWITCH("ADC1_INP1", SND_SOC_NOPM, 0, 0, + &adc1_switch), SND_SOC_DAPM_SUPPLY("RX1 CLK", MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("RX2 CLK", MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, @@ -4052,7 +4058,7 @@ int msm_anlg_codec_info_create_codec_entry(struct snd_info_entry *codec_root, sdm660_cdc_priv = snd_soc_codec_get_drvdata(codec); card = codec->component.card; - sdm660_cdc_priv->entry = snd_register_module_info(codec_root->module, + sdm660_cdc_priv->entry = snd_info_create_subdir(codec_root->module, "spmi0-03", codec_root); if (!sdm660_cdc_priv->entry) { @@ -4320,13 +4326,15 @@ static struct snd_soc_codec_driver soc_codec_dev_sdm660_cdc = { .suspend = msm_anlg_cdc_suspend, .resume = msm_anlg_cdc_resume, .reg_word_size = 1, - .controls = msm_anlg_cdc_snd_controls, - .num_controls = ARRAY_SIZE(msm_anlg_cdc_snd_controls), - .dapm_widgets = msm_anlg_cdc_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(msm_anlg_cdc_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), .get_regmap = msm_anlg_get_regmap, + .component_driver = { + .controls = msm_anlg_cdc_snd_controls, + .num_controls = ARRAY_SIZE(msm_anlg_cdc_snd_controls), + .dapm_widgets = msm_anlg_cdc_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(msm_anlg_cdc_dapm_widgets), + .dapm_routes = audio_map, + .num_dapm_routes = ARRAY_SIZE(audio_map), + }, }; static int msm_anlg_cdc_init_supplies(struct sdm660_cdc_priv *sdm660_cdc, diff --git a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c index 3f9c0b4a5b83..68a1d8d47b39 100644 --- a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c +++ b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -1157,7 +1157,7 @@ int msm_dig_codec_info_create_codec_entry(struct snd_info_entry *codec_root, msm_dig = snd_soc_codec_get_drvdata(codec); card = codec->component.card; - msm_dig->entry = snd_register_module_info(codec_root->module, + msm_dig->entry = snd_info_create_subdir(codec_root->module, "msm_digital_codec", codec_root); if (!msm_dig->entry) { @@ -2037,13 +2037,15 @@ static struct snd_soc_codec_driver soc_msm_dig_codec = { .remove = msm_dig_cdc_soc_remove, .suspend = msm_dig_cdc_suspend, .resume = msm_dig_cdc_resume, - .controls = msm_dig_snd_controls, - .num_controls = ARRAY_SIZE(msm_dig_snd_controls), - .dapm_widgets = msm_dig_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(msm_dig_dapm_widgets), - .dapm_routes = audio_dig_map, - .num_dapm_routes = ARRAY_SIZE(audio_dig_map), .get_regmap = msm_digital_get_regmap, + .component_driver = { + .controls = msm_dig_snd_controls, + .num_controls = ARRAY_SIZE(msm_dig_snd_controls), + .dapm_widgets = msm_dig_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(msm_dig_dapm_widgets), + .dapm_routes = audio_dig_map, + .num_dapm_routes = ARRAY_SIZE(audio_dig_map), + }, }; const struct regmap_config msm_digital_regmap_config = { diff --git a/sound/soc/codecs/wcd-dsp-mgr.c b/sound/soc/codecs/wcd-dsp-mgr.c index 661db2b66324..a6d46aef9724 100644 --- a/sound/soc/codecs/wcd-dsp-mgr.c +++ b/sound/soc/codecs/wcd-dsp-mgr.c @@ -26,7 +26,8 @@ static char *wdsp_get_cmpnt_type_string(enum wdsp_cmpnt_type); /* Component related macros */ -#define WDSP_GET_COMPONENT(wdsp, x) (&(wdsp->cmpnts[x])) +#define WDSP_GET_COMPONENT(wdsp, x) ((x >= WDSP_CMPNT_TYPE_MAX || x < 0) ? \ + NULL : (&(wdsp->cmpnts[x]))) #define WDSP_GET_CMPNT_TYPE_STR(x) wdsp_get_cmpnt_type_string(x) /* diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c index 3b2426dc7234..eb67de92871d 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/sound/soc/codecs/wcd-mbhc-v2.c @@ -329,6 +329,7 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, /* Disable micbias, pullup & enable cs */ wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_CS); mutex_unlock(&mbhc->hphl_pa_lock); + clear_bit(WCD_MBHC_ANC0_OFF_ACK, &mbhc->hph_anc_state); break; case WCD_EVENT_PRE_HPHR_PA_OFF: mutex_lock(&mbhc->hphr_pa_lock); @@ -346,6 +347,7 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, /* Disable micbias, pullup & enable cs */ wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_CS); mutex_unlock(&mbhc->hphr_pa_lock); + clear_bit(WCD_MBHC_ANC1_OFF_ACK, &mbhc->hph_anc_state); break; case WCD_EVENT_PRE_HPHL_PA_ON: set_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state); @@ -439,6 +441,25 @@ static void wcd_mbhc_clr_and_turnon_hph_padac(struct wcd_mbhc *mbhc) __func__); usleep_range(wg_time * 1000, wg_time * 1000 + 50); } + + if (test_and_clear_bit(WCD_MBHC_ANC0_OFF_ACK, + &mbhc->hph_anc_state)) { + usleep_range(20000, 20100); + pr_debug("%s: HPHL ANC clear flag and enable ANC_EN\n", + __func__); + if (mbhc->mbhc_cb->update_anc_state) + mbhc->mbhc_cb->update_anc_state(mbhc->codec, true, 0); + } + + if (test_and_clear_bit(WCD_MBHC_ANC1_OFF_ACK, + &mbhc->hph_anc_state)) { + usleep_range(20000, 20100); + pr_debug("%s: HPHR ANC clear flag and enable ANC_EN\n", + __func__); + if (mbhc->mbhc_cb->update_anc_state) + mbhc->mbhc_cb->update_anc_state(mbhc->codec, true, 1); + } + } static bool wcd_mbhc_is_hph_pa_on(struct wcd_mbhc *mbhc) @@ -471,6 +492,20 @@ static void wcd_mbhc_set_and_turnoff_hph_padac(struct wcd_mbhc *mbhc) } WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPH_PA_EN, 0); usleep_range(wg_time * 1000, wg_time * 1000 + 50); + + + if (mbhc->mbhc_cb->is_anc_on && mbhc->mbhc_cb->is_anc_on(mbhc)) { + usleep_range(20000, 20100); + pr_debug("%s ANC is on, setting ANC_OFF_ACK\n", __func__); + set_bit(WCD_MBHC_ANC0_OFF_ACK, &mbhc->hph_anc_state); + set_bit(WCD_MBHC_ANC1_OFF_ACK, &mbhc->hph_anc_state); + if (mbhc->mbhc_cb->update_anc_state) { + mbhc->mbhc_cb->update_anc_state(mbhc->codec, false, 0); + mbhc->mbhc_cb->update_anc_state(mbhc->codec, false, 1); + } else { + pr_debug("%s ANC is off\n", __func__); + } + } } int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, @@ -581,7 +616,8 @@ static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, jack_type == SND_JACK_LINEOUT) && (mbhc->hph_status && mbhc->hph_status != jack_type)) { - if (mbhc->micbias_enable) { + if (mbhc->micbias_enable && + mbhc->hph_status == SND_JACK_HEADSET) { if (mbhc->mbhc_cb->mbhc_micbias_control) mbhc->mbhc_cb->mbhc_micbias_control( codec, MIC_BIAS_2, @@ -1108,7 +1144,7 @@ static irqreturn_t wcd_mbhc_release_handler(int irq, void *data) * For ADC MBHC, ADC_COMPLETE interrupt will be generated * in this case. So skip the check here. */ - if (!WCD_MBHC_DETECTION && + if (mbhc->mbhc_detection_logic == WCD_DETECTION_LEGACY && mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) { wcd_mbhc_find_plug_and_report(mbhc, MBHC_PLUG_TYPE_HEADSET); goto exit; @@ -1922,7 +1958,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, init_waitqueue_head(&mbhc->wait_btn_press); mutex_init(&mbhc->codec_resource_lock); - switch (WCD_MBHC_DETECTION) { + switch (mbhc->mbhc_detection_logic) { case WCD_DETECTION_LEGACY: wcd_mbhc_legacy_init(mbhc); break; @@ -1931,7 +1967,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, break; default: pr_err("%s: Unknown detection logic type %d\n", - __func__, WCD_MBHC_DETECTION); + __func__, mbhc->mbhc_detection_logic); break; } diff --git a/sound/soc/codecs/wcd-mbhc-v2.h b/sound/soc/codecs/wcd-mbhc-v2.h index 7ed06c355990..c8714fc3abbc 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.h +++ b/sound/soc/codecs/wcd-mbhc-v2.h @@ -157,12 +157,6 @@ enum wcd_mbhc_detect_logic { WCD_DETECTION_ADC, }; -#ifdef CONFIG_SND_SOC_WCD_MBHC_ADC -#define WCD_MBHC_DETECTION WCD_DETECTION_ADC -#else -#define WCD_MBHC_DETECTION WCD_DETECTION_LEGACY -#endif - enum wcd_mbhc_cs_mb_en_flag { WCD_MBHC_EN_CS = 0, WCD_MBHC_EN_MB, @@ -240,6 +234,11 @@ enum pa_dac_ack_flags { WCD_MBHC_HPHR_PA_OFF_ACK, }; +enum anc_ack_flags { + WCD_MBHC_ANC0_OFF_ACK = 0, + WCD_MBHC_ANC1_OFF_ACK, +}; + enum wcd_mbhc_btn_det_mem { WCD_MBHC_BTN_DET_V_BTN_LOW, WCD_MBHC_BTN_DET_V_BTN_HIGH @@ -488,6 +487,9 @@ struct wcd_mbhc_cb { void (*hph_pull_down_ctrl)(struct snd_soc_codec *, bool); void (*mbhc_moisture_config)(struct wcd_mbhc *); bool (*hph_register_recovery)(struct wcd_mbhc *); + void (*update_anc_state)(struct snd_soc_codec *codec, + bool enable, int anc_num); + bool (*is_anc_on)(struct wcd_mbhc *mbhc); }; struct wcd_mbhc_fn { @@ -538,6 +540,7 @@ struct wcd_mbhc { /* track PA/DAC state to sync with userspace */ unsigned long hph_pa_dac_state; + unsigned long hph_anc_state; unsigned long event_state; unsigned long jiffies_atreport; @@ -565,6 +568,9 @@ struct wcd_mbhc { struct mutex hphl_pa_lock; struct mutex hphr_pa_lock; + /* Holds mbhc detection method - ADC/Legacy */ + unsigned int mbhc_detection_logic; + unsigned long intr_status; bool is_hph_ocp_pending; diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 329aa7a4c466..dedeaea55675 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -348,7 +348,6 @@ enum { AUDIO_NOMINAL, CPE_NOMINAL, HPH_PA_DELAY, - SB_CLK_GEAR, ANC_MIC_AMIC1, ANC_MIC_AMIC2, ANC_MIC_AMIC3, @@ -818,7 +817,10 @@ struct tasha_priv { int rx_8_count; bool clk_mode; bool clk_internal; - + /* Lock to prevent multiple functions voting at same time */ + struct mutex sb_clk_gear_lock; + /* Count for functions voting or un-voting */ + u32 ref_count; /* Lock to protect mclk enablement */ struct mutex mclk_lock; }; @@ -2012,6 +2014,32 @@ static void tasha_mbhc_moisture_config(struct wcd_mbhc *mbhc) tasha_mbhc_hph_l_pull_up_control(codec, mbhc->moist_iref); } +static void tasha_update_anc_state(struct snd_soc_codec *codec, bool enable, + int anc_num) +{ + if (enable) + snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CFG0 + + (20 * anc_num), 0x10, 0x10); + else + snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CFG0 + + (20 * anc_num), 0x10, 0x00); +} + +static bool tasha_is_anc_on(struct wcd_mbhc *mbhc) +{ + bool anc_on = false; + u16 ancl, ancr; + + ancl = + (snd_soc_read(mbhc->codec, WCD9335_CDC_RX1_RX_PATH_CFG0)) & 0x10; + ancr = + (snd_soc_read(mbhc->codec, WCD9335_CDC_RX2_RX_PATH_CFG0)) & 0x10; + + anc_on = !!(ancl | ancr); + + return anc_on; +} + static const struct wcd_mbhc_cb mbhc_cb = { .request_irq = tasha_mbhc_request_irq, .irq_control = tasha_mbhc_irq_control, @@ -2034,6 +2062,8 @@ static const struct wcd_mbhc_cb mbhc_cb = { .mbhc_gnd_det_ctrl = tasha_mbhc_gnd_det_ctrl, .hph_pull_down_ctrl = tasha_mbhc_hph_pull_down_ctrl, .mbhc_moisture_config = tasha_mbhc_moisture_config, + .update_anc_state = tasha_update_anc_state, + .is_anc_on = tasha_is_anc_on, }; static int tasha_get_anc_slot(struct snd_kcontrol *kcontrol, @@ -2948,10 +2978,7 @@ static int tasha_codec_enable_slimrx(struct snd_soc_dapm_widget *w, &dai->grph); break; case SND_SOC_DAPM_PRE_PMD: - if (!test_bit(SB_CLK_GEAR, &tasha_p->status_mask)) { - tasha_codec_vote_max_bw(codec, true); - set_bit(SB_CLK_GEAR, &tasha_p->status_mask); - } + tasha_codec_vote_max_bw(codec, true); break; case SND_SOC_DAPM_POST_PMD: ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list, @@ -5263,10 +5290,7 @@ static int tasha_codec_enable_interpolator(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - if (!test_bit(SB_CLK_GEAR, &tasha->status_mask)) { - tasha_codec_vote_max_bw(codec, true); - set_bit(SB_CLK_GEAR, &tasha->status_mask); - } + tasha_codec_vote_max_bw(codec, true); /* Reset if needed */ tasha_codec_enable_prim_interpolator(codec, reg, event); break; @@ -11127,11 +11151,8 @@ static void tasha_shutdown(struct snd_pcm_substream *substream, if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) return; - if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) && - test_bit(SB_CLK_GEAR, &tasha->status_mask)) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) tasha_codec_vote_max_bw(dai->codec, false); - clear_bit(SB_CLK_GEAR, &tasha->status_mask); - } } static int tasha_set_decimator_rate(struct snd_soc_dai *dai, @@ -11366,15 +11387,11 @@ static int tasha_set_interpolator_rate(struct snd_soc_dai *dai, static int tasha_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec); - pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); - if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) && - test_bit(SB_CLK_GEAR, &tasha->status_mask)) { + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) tasha_codec_vote_max_bw(dai->codec, false); - clear_bit(SB_CLK_GEAR, &tasha->status_mask); - } return 0; } @@ -13082,13 +13099,29 @@ static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec, if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) return 0; - if (vote) - bw_ops = SLIM_BW_CLK_GEAR_9; - else - bw_ops = SLIM_BW_UNVOTE; + mutex_lock(&tasha->sb_clk_gear_lock); + if (vote) { + tasha->ref_count++; + if (tasha->ref_count == 1) { + bw_ops = SLIM_BW_CLK_GEAR_9; + tasha_codec_slim_reserve_bw(codec, + bw_ops, true); + } + } else if (!vote && tasha->ref_count > 0) { + tasha->ref_count--; + if (tasha->ref_count == 0) { + bw_ops = SLIM_BW_UNVOTE; + tasha_codec_slim_reserve_bw(codec, + bw_ops, true); + } + }; - return tasha_codec_slim_reserve_bw(codec, - bw_ops, true); + dev_dbg(codec->dev, "%s Value of counter after vote or un-vote is %d\n", + __func__, tasha->ref_count); + + mutex_unlock(&tasha->sb_clk_gear_lock); + + return 0; } static int tasha_cpe_err_irq_control(struct snd_soc_codec *codec, @@ -13271,6 +13304,8 @@ static int tasha_post_reset_cb(struct wcd9xxx *wcd9xxx) if (ret < 0) dev_err(codec->dev, "%s: invalid pdata\n", __func__); + /* Reset reference counter for voting for max bw */ + tasha->ref_count = 0; /* MBHC Init */ wcd_mbhc_deinit(&tasha->mbhc); tasha->mbhc_started = false; @@ -14053,6 +14088,7 @@ static int tasha_probe(struct platform_device *pdev) mutex_init(&tasha->swr_read_lock); mutex_init(&tasha->swr_write_lock); mutex_init(&tasha->swr_clk_lock); + mutex_init(&tasha->sb_clk_gear_lock); mutex_init(&tasha->mclk_lock); cdc_pwr = devm_kzalloc(&pdev->dev, sizeof(struct wcd9xxx_power_region), @@ -14157,6 +14193,7 @@ static int tasha_remove(struct platform_device *pdev) mutex_destroy(&tasha->mclk_lock); devm_kfree(&pdev->dev, tasha); snd_soc_unregister_codec(&pdev->dev); + mutex_destroy(&tasha->sb_clk_gear_lock); return 0; } diff --git a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c b/sound/soc/codecs/wcd934x/wcd934x-mbhc.c index a1a5e2d65062..ea19caa14f8e 100644 --- a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c +++ b/sound/soc/codecs/wcd934x/wcd934x-mbhc.c @@ -829,6 +829,32 @@ static bool tavil_hph_register_recovery(struct wcd_mbhc *mbhc) return wcd934x_mbhc->is_hph_recover; } +static void tavil_update_anc_state(struct snd_soc_codec *codec, bool enable, + int anc_num) +{ + if (enable) + snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CFG0 + + (20 * anc_num), 0x10, 0x10); + else + snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CFG0 + + (20 * anc_num), 0x10, 0x00); +} + +static bool tavil_is_anc_on(struct wcd_mbhc *mbhc) +{ + bool anc_on = false; + u16 ancl, ancr; + + ancl = + (snd_soc_read(mbhc->codec, WCD934X_CDC_RX1_RX_PATH_CFG0)) & 0x10; + ancr = + (snd_soc_read(mbhc->codec, WCD934X_CDC_RX2_RX_PATH_CFG0)) & 0x10; + + anc_on = !!(ancl | ancr); + + return anc_on; +} + static const struct wcd_mbhc_cb mbhc_cb = { .request_irq = tavil_mbhc_request_irq, .irq_control = tavil_mbhc_irq_control, @@ -852,6 +878,8 @@ static const struct wcd_mbhc_cb mbhc_cb = { .hph_pull_down_ctrl = tavil_mbhc_hph_pull_down_ctrl, .mbhc_moisture_config = tavil_mbhc_moisture_config, .hph_register_recovery = tavil_hph_register_recovery, + .update_anc_state = tavil_update_anc_state, + .is_anc_on = tavil_is_anc_on, }; static struct regulator *tavil_codec_find_ondemand_regulator( @@ -998,19 +1026,26 @@ int tavil_mbhc_post_ssr_init(struct wcd934x_mbhc *mbhc, struct snd_soc_codec *codec) { int ret; + struct wcd_mbhc *wcd_mbhc; if (!mbhc || !codec) return -EINVAL; - wcd_mbhc_deinit(&mbhc->wcd_mbhc); - ret = wcd_mbhc_init(&mbhc->wcd_mbhc, codec, &mbhc_cb, &intr_ids, + wcd_mbhc = &mbhc->wcd_mbhc; + if (wcd_mbhc == NULL) { + pr_err("%s: wcd_mbhc is NULL\n", __func__); + return -EINVAL; + } + + wcd_mbhc_deinit(wcd_mbhc); + ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids, wcd_mbhc_registers, TAVIL_ZDET_SUPPORTED); if (ret) { dev_err(codec->dev, "%s: mbhc initialization failed\n", __func__); goto done; } - if (!WCD_MBHC_DETECTION) { + if (wcd_mbhc->mbhc_detection_logic == WCD_DETECTION_LEGACY) { snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_1, 0x04, 0x04); snd_soc_update_bits(codec, WCD934X_MBHC_CTL_BCS, 0x01, 0x01); } @@ -1033,6 +1068,7 @@ int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, struct snd_soc_codec *codec, { struct regulator *supply; struct wcd934x_mbhc *wcd934x_mbhc; + struct wcd_mbhc *wcd_mbhc; int ret; wcd934x_mbhc = devm_kzalloc(codec->dev, sizeof(struct wcd934x_mbhc), @@ -1043,8 +1079,18 @@ int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, struct snd_soc_codec *codec, wcd934x_mbhc->wcd9xxx = dev_get_drvdata(codec->dev->parent); wcd934x_mbhc->fw_data = fw_data; BLOCKING_INIT_NOTIFIER_HEAD(&wcd934x_mbhc->notifier); + wcd_mbhc = &wcd934x_mbhc->wcd_mbhc; + if (wcd_mbhc == NULL) { + pr_err("%s: wcd_mbhc is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + + /* Setting default mbhc detection logic to ADC for Tavil */ + wcd_mbhc->mbhc_detection_logic = WCD_DETECTION_ADC; - ret = wcd_mbhc_init(&wcd934x_mbhc->wcd_mbhc, codec, &mbhc_cb, + ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids, wcd_mbhc_registers, TAVIL_ZDET_SUPPORTED); if (ret) { @@ -1070,7 +1116,7 @@ int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, struct snd_soc_codec *codec, snd_soc_add_codec_controls(codec, hph_type_detect_controls, ARRAY_SIZE(hph_type_detect_controls)); - if (!WCD_MBHC_DETECTION) { + if (wcd_mbhc->mbhc_detection_logic == WCD_DETECTION_LEGACY) { snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_1, 0x04, 0x04); snd_soc_update_bits(codec, WCD934X_MBHC_CTL_BCS, 0x01, 0x01); } diff --git a/sound/soc/codecs/wcd934x/wcd934x-routing.h b/sound/soc/codecs/wcd934x/wcd934x-routing.h index afd93b2cf56d..93a1ad3bab90 100644 --- a/sound/soc/codecs/wcd934x/wcd934x-routing.h +++ b/sound/soc/codecs/wcd934x/wcd934x-routing.h @@ -117,6 +117,70 @@ const struct snd_soc_dapm_route tavil_slim_audio_map[] = { const struct snd_soc_dapm_route tavil_audio_map[] = { + /* WDMA3 */ + {"WDMA3 PORT0 MUX", "DEC0", "ADC MUX0"}, + {"WDMA3 PORT0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"}, + {"WDMA3 PORT1 MUX", "DEC1", "ADC MUX1"}, + {"WDMA3 PORT1 MUX", "RX_MIX_TX1", "RX MIX TX1 MUX"}, + {"WDMA3 PORT2 MUX", "DEC2", "ADC MUX2"}, + {"WDMA3 PORT2 MUX", "RX_MIX_TX2", "RX MIX TX2 MUX"}, + {"WDMA3 PORT3 MUX", "DEC3", "ADC MUX3"}, + {"WDMA3 PORT3 MUX", "RX_MIX_TX3", "RX MIX TX3 MUX"}, + {"WDMA3 PORT4 MUX", "DEC4", "ADC MUX4"}, + {"WDMA3 PORT4 MUX", "RX_MIX_TX4", "RX MIX TX4 MUX"}, + {"WDMA3 PORT5 MUX", "DEC5", "ADC MUX5"}, + {"WDMA3 PORT5 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"}, + {"WDMA3 PORT6 MUX", "DEC6", "ADC MUX6"}, + {"WDMA3 PORT6 MUX", "RX_MIX_TX6", "RX MIX TX6 MUX"}, + + {"WDMA3 CH0 MUX", "PORT_0", "WDMA3 PORT0 MUX"}, + {"WDMA3 CH0 MUX", "PORT_1", "WDMA3 PORT1 MUX"}, + {"WDMA3 CH0 MUX", "PORT_2", "WDMA3 PORT2 MUX"}, + {"WDMA3 CH0 MUX", "PORT_3", "WDMA3 PORT3 MUX"}, + {"WDMA3 CH0 MUX", "PORT_4", "WDMA3 PORT4 MUX"}, + {"WDMA3 CH0 MUX", "PORT_5", "WDMA3 PORT5 MUX"}, + {"WDMA3 CH0 MUX", "PORT_6", "WDMA3 PORT6 MUX"}, + {"WDMA3 CH0 MUX", "PORT_7", "ADC MUX7"}, + {"WDMA3 CH0 MUX", "PORT_8", "ADC MUX8"}, + + {"WDMA3 CH1 MUX", "PORT_0", "WDMA3 PORT0 MUX"}, + {"WDMA3 CH1 MUX", "PORT_1", "WDMA3 PORT1 MUX"}, + {"WDMA3 CH1 MUX", "PORT_2", "WDMA3 PORT2 MUX"}, + {"WDMA3 CH1 MUX", "PORT_3", "WDMA3 PORT3 MUX"}, + {"WDMA3 CH1 MUX", "PORT_4", "WDMA3 PORT4 MUX"}, + {"WDMA3 CH1 MUX", "PORT_5", "WDMA3 PORT5 MUX"}, + {"WDMA3 CH1 MUX", "PORT_6", "WDMA3 PORT6 MUX"}, + {"WDMA3 CH1 MUX", "PORT_7", "ADC MUX7"}, + {"WDMA3 CH1 MUX", "PORT_8", "ADC MUX8"}, + + {"WDMA3 CH2 MUX", "PORT_0", "WDMA3 PORT0 MUX"}, + {"WDMA3 CH2 MUX", "PORT_1", "WDMA3 PORT1 MUX"}, + {"WDMA3 CH2 MUX", "PORT_2", "WDMA3 PORT2 MUX"}, + {"WDMA3 CH2 MUX", "PORT_3", "WDMA3 PORT3 MUX"}, + {"WDMA3 CH2 MUX", "PORT_4", "WDMA3 PORT4 MUX"}, + {"WDMA3 CH2 MUX", "PORT_5", "WDMA3 PORT5 MUX"}, + {"WDMA3 CH2 MUX", "PORT_6", "WDMA3 PORT6 MUX"}, + {"WDMA3 CH2 MUX", "PORT_7", "ADC MUX7"}, + {"WDMA3 CH2 MUX", "PORT_8", "ADC MUX8"}, + + {"WDMA3 CH3 MUX", "PORT_0", "WDMA3 PORT0 MUX"}, + {"WDMA3 CH3 MUX", "PORT_1", "WDMA3 PORT1 MUX"}, + {"WDMA3 CH3 MUX", "PORT_2", "WDMA3 PORT2 MUX"}, + {"WDMA3 CH3 MUX", "PORT_3", "WDMA3 PORT3 MUX"}, + {"WDMA3 CH3 MUX", "PORT_4", "WDMA3 PORT4 MUX"}, + {"WDMA3 CH3 MUX", "PORT_5", "WDMA3 PORT5 MUX"}, + {"WDMA3 CH3 MUX", "PORT_6", "WDMA3 PORT6 MUX"}, + {"WDMA3 CH3 MUX", "PORT_7", "ADC MUX7"}, + {"WDMA3 CH3 MUX", "PORT_8", "ADC MUX8"}, + + {"WDMA3_CH_MIXER", NULL, "WDMA3 CH0 MUX"}, + {"WDMA3_CH_MIXER", NULL, "WDMA3 CH1 MUX"}, + {"WDMA3_CH_MIXER", NULL, "WDMA3 CH2 MUX"}, + {"WDMA3_CH_MIXER", NULL, "WDMA3 CH3 MUX"}, + + {"WDMA3_ON_OFF", "Switch", "WDMA3_CH_MIXER"}, + {"WDMA3_OUT", NULL, "WDMA3_ON_OFF"}, + /* MAD */ {"MAD_SEL MUX", "SPE", "MAD_CPE_INPUT"}, {"MAD_SEL MUX", "MSM", "MADINPUT"}, diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c index ca16ed8c8ae3..3079cca65e38 100644 --- a/sound/soc/codecs/wcd934x/wcd934x.c +++ b/sound/soc/codecs/wcd934x/wcd934x.c @@ -180,6 +180,8 @@ enum { ANC_MIC_AMIC2, ANC_MIC_AMIC3, ANC_MIC_AMIC4, + CLK_INTERNAL, + CLK_MODE, }; enum { @@ -1071,6 +1073,40 @@ static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w, return ret; } +static int tavil_get_clkmode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + + if (test_bit(CLK_MODE, &tavil_p->status_mask)) + ucontrol->value.enumerated.item[0] = 1; + else + ucontrol->value.enumerated.item[0] = 0; + + dev_dbg(codec->dev, "%s: is_low_power_clock: %s\n", __func__, + test_bit(CLK_MODE, &tavil_p->status_mask) ? "true" : "false"); + + return 0; +} + +static int tavil_put_clkmode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + + if (ucontrol->value.enumerated.item[0]) + set_bit(CLK_MODE, &tavil_p->status_mask); + else + clear_bit(CLK_MODE, &tavil_p->status_mask); + + dev_dbg(codec->dev, "%s: is_low_power_clock: %s\n", __func__, + test_bit(CLK_MODE, &tavil_p->status_mask) ? "true" : "false"); + + return 0; +} + static int tavil_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2809,6 +2845,35 @@ static int tavil_get_asrc_mode(struct tavil_priv *tavil, int asrc, return asrc_mode; } +static int tavil_codec_wdma3_ctl(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Fix to 16KHz */ + snd_soc_update_bits(codec, WCD934X_DMA_WDMA_CTL_3, + 0xF0, 0x10); + /* Select mclk_1 */ + snd_soc_update_bits(codec, WCD934X_DMA_WDMA_CTL_3, + 0x02, 0x00); + /* Enable DMA */ + snd_soc_update_bits(codec, WCD934X_DMA_WDMA_CTL_3, + 0x01, 0x01); + break; + + case SND_SOC_DAPM_POST_PMD: + /* Disable DMA */ + snd_soc_update_bits(codec, WCD934X_DMA_WDMA_CTL_3, + 0x01, 0x00); + break; + + }; + + return 0; +} + static int tavil_codec_enable_asrc(struct snd_soc_codec *codec, int asrc_in, int event) { @@ -5547,6 +5612,9 @@ static const char *const tavil_anc_func_text[] = {"OFF", "ON"}; static const struct soc_enum tavil_anc_func_enum = SOC_ENUM_SINGLE_EXT(2, tavil_anc_func_text); +static const char *const tavil_clkmode_text[] = {"EXTERNAL", "INTERNAL"}; +static SOC_ENUM_SINGLE_EXT_DECL(tavil_clkmode_enum, tavil_clkmode_text); + /* Cutoff frequency for high pass filter */ static const char * const cf_text[] = { "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ" @@ -5726,6 +5794,9 @@ static const struct snd_kcontrol_new tavil_snd_controls[] = { SOC_ENUM_EXT("ANC Function", tavil_anc_func_enum, tavil_get_anc_func, tavil_put_anc_func), + SOC_ENUM_EXT("CLK MODE", tavil_clkmode_enum, tavil_get_clkmode, + tavil_put_clkmode), + SOC_ENUM("TX0 HPF cut off", cf_dec0_enum), SOC_ENUM("TX1 HPF cut off", cf_dec1_enum), SOC_ENUM("TX2 HPF cut off", cf_dec2_enum), @@ -6165,6 +6236,39 @@ static const char * const native_mux_text[] = { "OFF", "ON", }; +static const char *const wdma3_port0_text[] = { + "RX_MIX_TX0", "DEC0" +}; + +static const char *const wdma3_port1_text[] = { + "RX_MIX_TX1", "DEC1" +}; + +static const char *const wdma3_port2_text[] = { + "RX_MIX_TX2", "DEC2" +}; + +static const char *const wdma3_port3_text[] = { + "RX_MIX_TX3", "DEC3" +}; + +static const char *const wdma3_port4_text[] = { + "RX_MIX_TX4", "DEC4" +}; + +static const char *const wdma3_port5_text[] = { + "RX_MIX_TX5", "DEC5" +}; + +static const char *const wdma3_port6_text[] = { + "RX_MIX_TX6", "DEC6" +}; + +static const char *const wdma3_ch_text[] = { + "PORT_0", "PORT_1", "PORT_2", "PORT_3", "PORT_4", + "PORT_5", "PORT_6", "PORT_7", "PORT_8", +}; + static const struct snd_kcontrol_new aif4_vi_mixer[] = { SOC_SINGLE_EXT("SPKR_VI_1", SND_SOC_NOPM, WCD934X_TX14, 1, 0, tavil_vi_feed_mixer_get, tavil_vi_feed_mixer_put), @@ -6570,6 +6674,20 @@ WCD_DAPM_ENUM(int8_2_native, SND_SOC_NOPM, 0, native_mux_text); WCD_DAPM_ENUM(anc0_fb, WCD934X_CDC_RX_INP_MUX_ANC_CFG0, 0, anc0_fb_mux_text); WCD_DAPM_ENUM(anc1_fb, WCD934X_CDC_RX_INP_MUX_ANC_CFG0, 3, anc1_fb_mux_text); + +WCD_DAPM_ENUM(wdma3_port0, WCD934X_DMA_WDMA3_PRT_CFG, 0, wdma3_port0_text); +WCD_DAPM_ENUM(wdma3_port1, WCD934X_DMA_WDMA3_PRT_CFG, 1, wdma3_port1_text); +WCD_DAPM_ENUM(wdma3_port2, WCD934X_DMA_WDMA3_PRT_CFG, 2, wdma3_port2_text); +WCD_DAPM_ENUM(wdma3_port3, WCD934X_DMA_WDMA3_PRT_CFG, 3, wdma3_port3_text); +WCD_DAPM_ENUM(wdma3_port4, WCD934X_DMA_WDMA3_PRT_CFG, 4, wdma3_port4_text); +WCD_DAPM_ENUM(wdma3_port5, WCD934X_DMA_WDMA3_PRT_CFG, 5, wdma3_port5_text); +WCD_DAPM_ENUM(wdma3_port6, WCD934X_DMA_WDMA3_PRT_CFG, 6, wdma3_port6_text); + +WCD_DAPM_ENUM(wdma3_ch0, WCD934X_DMA_CH_0_1_CFG_WDMA_3, 0, wdma3_ch_text); +WCD_DAPM_ENUM(wdma3_ch1, WCD934X_DMA_CH_0_1_CFG_WDMA_3, 4, wdma3_ch_text); +WCD_DAPM_ENUM(wdma3_ch2, WCD934X_DMA_CH_2_3_CFG_WDMA_3, 0, wdma3_ch_text); +WCD_DAPM_ENUM(wdma3_ch3, WCD934X_DMA_CH_2_3_CFG_WDMA_3, 4, wdma3_ch_text); + static const struct snd_kcontrol_new anc_ear_switch = SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); @@ -6637,6 +6755,9 @@ static const struct snd_kcontrol_new rx_int4_asrc_switch[] = { SOC_DAPM_SINGLE("LO2 Switch", SND_SOC_NOPM, 0, 1, 0), }; +static const struct snd_kcontrol_new wdma3_onoff_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + static int tavil_dsd_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -7319,6 +7440,28 @@ static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = { SND_SOC_DAPM_MUX_E("ASRC3 MUX", SND_SOC_NOPM, ASRC3, 0, &asrc3_mux, tavil_codec_enable_asrc_resampler, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /* WDMA3 widgets */ + WCD_DAPM_MUX("WDMA3 PORT0 MUX", 0, wdma3_port0), + WCD_DAPM_MUX("WDMA3 PORT1 MUX", 1, wdma3_port1), + WCD_DAPM_MUX("WDMA3 PORT2 MUX", 2, wdma3_port2), + WCD_DAPM_MUX("WDMA3 PORT3 MUX", 3, wdma3_port3), + WCD_DAPM_MUX("WDMA3 PORT4 MUX", 4, wdma3_port4), + WCD_DAPM_MUX("WDMA3 PORT5 MUX", 5, wdma3_port5), + WCD_DAPM_MUX("WDMA3 PORT6 MUX", 6, wdma3_port6), + + WCD_DAPM_MUX("WDMA3 CH0 MUX", 0, wdma3_ch0), + WCD_DAPM_MUX("WDMA3 CH1 MUX", 4, wdma3_ch1), + WCD_DAPM_MUX("WDMA3 CH2 MUX", 0, wdma3_ch2), + WCD_DAPM_MUX("WDMA3 CH3 MUX", 4, wdma3_ch3), + + SND_SOC_DAPM_MIXER("WDMA3_CH_MIXER", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_SWITCH_E("WDMA3_ON_OFF", SND_SOC_NOPM, 0, 0, + &wdma3_onoff_switch, tavil_codec_wdma3_ctl, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_OUTPUT("WDMA3_OUT"), }; static int tavil_get_channel_map(struct snd_soc_dai *dai, @@ -8316,6 +8459,50 @@ static int tavil_codec_internal_rco_ctrl(struct snd_soc_codec *codec, return ret; } +/* + * tavil_cdc_mclk_tx_enable: Enable/Disable codec's clock for TX path + * @codec: Handle to codec + * @enable: Indicates whether clock should be enabled or disabled + */ +int tavil_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable) +{ + struct tavil_priv *tavil_p; + int ret = 0; + bool clk_mode; + bool clk_internal; + + if (!codec) + return -EINVAL; + + tavil_p = snd_soc_codec_get_drvdata(codec); + clk_mode = test_bit(CLK_MODE, &tavil_p->status_mask); + clk_internal = test_bit(CLK_INTERNAL, &tavil_p->status_mask); + + dev_dbg(codec->dev, "%s: clkmode: %d, enable: %d, clk_internal: %d\n", + __func__, clk_mode, enable, clk_internal); + + if (clk_mode || clk_internal) { + if (enable) { + wcd_resmgr_enable_master_bias(tavil_p->resmgr); + tavil_dig_core_power_collapse(tavil_p, POWER_RESUME); + tavil_vote_svs(tavil_p, true); + ret = tavil_codec_internal_rco_ctrl(codec, enable); + set_bit(CLK_INTERNAL, &tavil_p->status_mask); + } else { + clear_bit(CLK_INTERNAL, &tavil_p->status_mask); + tavil_codec_internal_rco_ctrl(codec, enable); + tavil_vote_svs(tavil_p, false); + tavil_dig_core_power_collapse(tavil_p, POWER_COLLAPSE); + wcd_resmgr_disable_master_bias(tavil_p->resmgr); + } + } else { + ret = __tavil_cdc_mclk_enable(tavil_p, enable); + } + + return ret; +} +EXPORT_SYMBOL(tavil_cdc_mclk_tx_enable); + static const struct wcd_resmgr_cb tavil_resmgr_cb = { .cdc_rco_ctrl = __tavil_codec_internal_rco_ctrl, }; diff --git a/sound/soc/codecs/wcd934x/wcd934x.h b/sound/soc/codecs/wcd934x/wcd934x.h index c3bf50a4ffdb..27c21f103533 100644 --- a/sound/soc/codecs/wcd934x/wcd934x.h +++ b/sound/soc/codecs/wcd934x/wcd934x.h @@ -137,6 +137,7 @@ struct tavil_reg_mask_val { extern void *tavil_get_afe_config(struct snd_soc_codec *codec, enum afe_config_type config_type); extern int tavil_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable); +extern int tavil_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable); extern int tavil_set_spkr_mode(struct snd_soc_codec *codec, int mode); extern int tavil_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset); extern struct wcd_dsp_cntl *tavil_get_wcd_dsp_cntl(struct device *dev); diff --git a/sound/soc/codecs/wcd_cpe_services.c b/sound/soc/codecs/wcd_cpe_services.c index 0028ebc08d5f..ad8962b6f1fe 100644 --- a/sound/soc/codecs/wcd_cpe_services.c +++ b/sound/soc/codecs/wcd_cpe_services.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include "wcd_cpe_services.h" #include "wcd_cmi_api.h" @@ -46,9 +45,6 @@ #define LISTEN_CTL_SPE_VAL 0x0 #define LISTEN_CTL_MSM_VAL 0x1 -#define TOMTOM_A_SVASS_SPE_INBOX(N) (TOMTOM_A_SVASS_SPE_INBOX_0 + (N)) -#define TOMTOM_A_SVASS_SPE_OUTBOX(N) (TOMTOM_A_SVASS_SPE_OUTBOX_0 + (N)) - #define WCD9335_CPE_SS_SPE_DRAM_OFFSET 0x48000 #define WCD9335_CPE_SS_SPE_DRAM_SIZE 0x34000 #define WCD9335_CPE_SS_SPE_IRAM_OFFSET 0x80000 @@ -316,8 +312,7 @@ static int cpe_register_write(u32 reg, u32 val) { int ret = 0; - if (reg != TOMTOM_A_SVASS_MEM_BANK && - reg != WCD9335_CPE_SS_MEM_BANK_0) + if (reg != WCD9335_CPE_SS_MEM_BANK_0) pr_debug("%s: reg = 0x%x, value = 0x%x\n", __func__, reg, val); @@ -2149,73 +2144,27 @@ enum cpe_svc_result cpe_svc_ftm_test(void *cpe_handle, u32 *status) static enum cpe_svc_result cpe_tgt_tomtom_boot(int debug_mode) { - enum cpe_svc_result rc = CPE_SVC_SUCCESS; - - if (!debug_mode) - rc = cpe_update_bits(TOMTOM_A_SVASS_CPAR_WDOG_CFG, - 0x3F, 0x31); - else - pr_info("%s: CPE in debug mode, WDOG disabled\n", - __func__); - - rc = cpe_update_bits(TOMTOM_A_SVASS_CLKRST_CTL, - 0x02, 0x00); - rc = cpe_update_bits(TOMTOM_A_SVASS_CLKRST_CTL, - 0x0C, 0x04); - rc = cpe_update_bits(TOMTOM_A_SVASS_CPAR_CFG, - 0x01, 0x01); - - return rc; + return CPE_SVC_SUCCESS; } static u32 cpe_tgt_tomtom_is_cpar_init_done(void) { - u8 status = 0; - - cpe_register_read(TOMTOM_A_SVASS_STATUS, &status); - return status & 0x01; + return 0; } static u32 cpe_tgt_tomtom_is_active(void) { - u8 status = 0; - - cpe_register_read(TOMTOM_A_SVASS_STATUS, &status); - return status & 0x04; + return 0; } static enum cpe_svc_result cpe_tgt_tomtom_reset(void) { - enum cpe_svc_result rc = CPE_SVC_SUCCESS; - - rc = cpe_update_bits(TOMTOM_A_SVASS_CPAR_WDOG_CFG, - 0x30, 0x00); - - rc = cpe_update_bits(TOMTOM_A_SVASS_CPAR_CFG, - 0x01, 0x00); - rc = cpe_update_bits(TOMTOM_A_MEM_LEAKAGE_CTL, - 0x07, 0x03); - rc = cpe_update_bits(TOMTOM_A_SVASS_CLKRST_CTL, - 0x08, 0x08); - rc = cpe_update_bits(TOMTOM_A_SVASS_CLKRST_CTL, - 0x02, 0x02); - return rc; + return CPE_SVC_SUCCESS; } enum cpe_svc_result cpe_tgt_tomtom_voicetx(bool enable) { - enum cpe_svc_result rc = CPE_SVC_SUCCESS; - u8 val = 0; - - if (enable) - val = 0x02; - else - val = 0x00; - rc = cpe_update_bits(TOMTOM_A_SVASS_CFG, - 0x02, val); - val = 0; - cpe_register_read(TOMTOM_A_SVASS_CFG, &val); - return rc; + return CPE_SVC_SUCCESS; } enum cpe_svc_result cpe_svc_toggle_lab(void *cpe_handle, bool enable) @@ -2235,251 +2184,37 @@ enum cpe_svc_result cpe_svc_toggle_lab(void *cpe_handle, bool enable) static enum cpe_svc_result cpe_tgt_tomtom_read_mailbox(u8 *buffer, size_t size) { - enum cpe_svc_result rc = CPE_SVC_SUCCESS; - u32 cnt = 0; - - if (size >= TOMTOM_A_SVASS_SPE_OUTBOX_SIZE) - size = TOMTOM_A_SVASS_SPE_OUTBOX_SIZE - 1; - for (cnt = 0; (cnt < size) && (rc == CPE_SVC_SUCCESS); cnt++) { - rc = cpe_register_read(TOMTOM_A_SVASS_SPE_OUTBOX(cnt), - &(buffer[cnt])); - } - return rc; + return CPE_SVC_SUCCESS; } static enum cpe_svc_result cpe_tgt_tomtom_write_mailbox(u8 *buffer, size_t size) { - enum cpe_svc_result rc = CPE_SVC_SUCCESS; - u32 cnt = 0; - - if (size >= TOMTOM_A_SVASS_SPE_INBOX_SIZE) - size = TOMTOM_A_SVASS_SPE_INBOX_SIZE - 1; - for (cnt = 0; (cnt < size) && (rc == CPE_SVC_SUCCESS); cnt++) { - rc = cpe_register_write(TOMTOM_A_SVASS_SPE_INBOX(cnt), - buffer[cnt]); - } - - if (rc == CPE_SVC_SUCCESS) - rc = cpe_register_write(TOMTOM_A_SVASS_SPE_INBOX_TRG, 1); - - return rc; -} - -static enum cpe_svc_result cpe_get_mem_addr(struct cpe_info *t_info, - const struct cpe_svc_mem_segment *mem_seg, - u32 *addr, u8 *mem) -{ - enum cpe_svc_result rc = CPE_SVC_SUCCESS; - u32 offset, mem_sz, address; - u8 mem_type; - - switch (mem_seg->type) { - - case CPE_SVC_DATA_MEM: - mem_type = MEM_ACCESS_DRAM_VAL; - offset = TOMTOM_A_SVASS_SPE_DRAM_OFFSET; - mem_sz = TOMTOM_A_SVASS_SPE_DRAM_SIZE; - break; - - case CPE_SVC_INSTRUCTION_MEM: - mem_type = MEM_ACCESS_IRAM_VAL; - offset = TOMTOM_A_SVASS_SPE_IRAM_OFFSET; - mem_sz = TOMTOM_A_SVASS_SPE_IRAM_SIZE; - break; - - default: - pr_err("%s: Invalid mem type = %u\n", - __func__, mem_seg->type); - return CPE_SVC_INVALID_HANDLE; - } - - if (mem_seg->cpe_addr < offset) { - pr_err("%s: Invalid addr %x for mem type %u\n", - __func__, mem_seg->cpe_addr, mem_type); - return CPE_SVC_INVALID_HANDLE; - } - - address = mem_seg->cpe_addr - offset; - if (address + mem_seg->size > mem_sz) { - pr_err("%s: wrong size %zu, start address %x, mem_type %u\n", - __func__, mem_seg->size, address, mem_type); - return CPE_SVC_INVALID_HANDLE; - } - - (*addr) = address; - (*mem) = mem_type; - - return rc; + return CPE_SVC_SUCCESS; } static enum cpe_svc_result cpe_tgt_tomtom_read_RAM(struct cpe_info *t_info, struct cpe_svc_mem_segment *mem_seg) { - enum cpe_svc_result rc = CPE_SVC_SUCCESS; - u8 mem_reg_val = 0; - u32 cnt = 0; - bool autoinc; - u8 mem = MEM_ACCESS_NONE_VAL; - u32 addr = 0; - u32 ptr_update = true; - - if (!mem_seg) { - pr_err("%s: Invalid mem segment\n", - __func__); - return CPE_SVC_INVALID_HANDLE; - } - - rc = cpe_get_mem_addr(t_info, mem_seg, &addr, &mem); - - if (rc != CPE_SVC_SUCCESS) { - pr_err("%s: Cannot obtain address, mem_type %u\n", - __func__, mem_seg->type); - return rc; - } - - rc = cpe_register_write(TOMTOM_A_SVASS_MEM_CTL, 0); - autoinc = cpe_register_read_autoinc_supported(); - if (autoinc) - mem_reg_val |= 0x04; - - mem_reg_val |= 0x08; - mem_reg_val |= mem; - - do { - if (!autoinc || ptr_update) { - rc = cpe_register_write(TOMTOM_A_SVASS_MEM_PTR0, - (addr & 0xFF)); - rc = cpe_register_write(TOMTOM_A_SVASS_MEM_PTR1, - ((addr >> 8) & 0xFF)); - rc = cpe_register_write(TOMTOM_A_SVASS_MEM_PTR2, - ((addr >> 16) & 0xFF)); - - rc = cpe_register_write(TOMTOM_A_SVASS_MEM_CTL, - mem_reg_val); - - ptr_update = false; - } - rc = cpe_register_read(TOMTOM_A_SVASS_MEM_BANK, - &mem_seg->data[cnt]); - - if (!autoinc) - rc = cpe_register_write(TOMTOM_A_SVASS_MEM_CTL, 0); - } while (++cnt < mem_seg->size); - - rc = cpe_register_write(TOMTOM_A_SVASS_MEM_CTL, 0); - - return rc; + return CPE_SVC_SUCCESS; } static enum cpe_svc_result cpe_tgt_tomtom_write_RAM(struct cpe_info *t_info, const struct cpe_svc_mem_segment *mem_seg) { - enum cpe_svc_result rc = CPE_SVC_SUCCESS; - u8 mem_reg_val = 0; - u8 mem = MEM_ACCESS_NONE_VAL; - u32 addr = 0; - u8 *temp_ptr = NULL; - u32 temp_size = 0; - bool autoinc; - - if (!mem_seg) { - pr_err("%s: Invalid mem segment\n", - __func__); - return CPE_SVC_INVALID_HANDLE; - } - - rc = cpe_get_mem_addr(t_info, mem_seg, &addr, &mem); - - if (rc != CPE_SVC_SUCCESS) { - pr_err("%s: Cannot obtain address, mem_type %u\n", - __func__, mem_seg->type); - return rc; - } - - autoinc = cpe_register_read_autoinc_supported(); - if (autoinc) - mem_reg_val |= 0x04; - mem_reg_val |= mem; - - rc = cpe_update_bits(TOMTOM_A_SVASS_MEM_CTL, - 0x0F, mem_reg_val); - - rc = cpe_register_write(TOMTOM_A_SVASS_MEM_PTR0, - (addr & 0xFF)); - rc = cpe_register_write(TOMTOM_A_SVASS_MEM_PTR1, - ((addr >> 8) & 0xFF)); - - rc = cpe_register_write(TOMTOM_A_SVASS_MEM_PTR2, - ((addr >> 16) & 0xFF)); - - temp_size = 0; - temp_ptr = mem_seg->data; - - while (temp_size <= mem_seg->size) { - u32 to_write = (mem_seg->size >= temp_size+CHUNK_SIZE) - ? CHUNK_SIZE : (mem_seg->size-temp_size); - - if (t_info->state == CPE_STATE_OFFLINE) { - pr_err("%s: CPE is offline\n", __func__); - return CPE_SVC_FAILED; - } - - cpe_register_write_repeat(TOMTOM_A_SVASS_MEM_BANK, - temp_ptr, to_write); - temp_size += CHUNK_SIZE; - temp_ptr += CHUNK_SIZE; - } - - rc = cpe_register_write(TOMTOM_A_SVASS_MEM_CTL, 0); - return rc; + return CPE_SVC_SUCCESS; } static enum cpe_svc_result cpe_tgt_tomtom_route_notification( enum cpe_svc_module module, enum cpe_svc_route_dest dest) { - enum cpe_svc_result rc = CPE_SVC_SUCCESS; - u8 ctl_reg_val = 0; - - switch (module) { - case CPE_SVC_LISTEN_PROC: - switch (dest) { - case CPE_SVC_EXTERNAL: - ctl_reg_val = LISTEN_CTL_MSM_VAL; - break; - case CPE_SVC_INTERNAL: - ctl_reg_val = LISTEN_CTL_SPE_VAL; - break; - default: - pr_err("%s: Invalid dest %d\n", - __func__, dest); - return CPE_SVC_FAILED; - } - - rc = cpe_update_bits(TOMTOM_A_SVASS_CFG, - 0x01, ctl_reg_val); - break; - default: - pr_err("%s: Invalid module %d\n", - __func__, module); - rc = CPE_SVC_FAILED; - break; - } - - return rc; + return CPE_SVC_SUCCESS; } static enum cpe_svc_result cpe_tgt_tomtom_set_debug_mode(u32 enable) { - enum cpe_svc_result rc = CPE_SVC_SUCCESS; - u8 dbg_reg_val = 0x00; - - if (enable) - dbg_reg_val = 0x08; - rc = cpe_update_bits(TOMTOM_A_SVASS_DEBUG, - 0x08, dbg_reg_val); - return rc; + return CPE_SVC_SUCCESS; } static const struct cpe_svc_hw_cfg *cpe_tgt_tomtom_get_cpe_info(void) diff --git a/sound/soc/msm/qdsp6v2/audio_calibration.c b/sound/soc/msm/qdsp6v2/audio_calibration.c index 808a0e4b72d1..d709b091a799 100644 --- a/sound/soc/msm/qdsp6v2/audio_calibration.c +++ b/sound/soc/msm/qdsp6v2/audio_calibration.c @@ -460,6 +460,12 @@ static long audio_cal_shared_ioctl(struct file *file, unsigned int cmd, data->cal_type.cal_hdr.buffer_number); ret = -EINVAL; goto done; + } else if ((data->hdr.cal_type_size + sizeof(data->hdr)) > size) { + pr_err("%s: cal type hdr size %zd + cal type size %d is greater than user buffer size %d\n", + __func__, sizeof(data->hdr), data->hdr.cal_type_size, + size); + ret = -EFAULT; + goto done; } @@ -497,13 +503,7 @@ static long audio_cal_shared_ioctl(struct file *file, unsigned int cmd, goto unlock; if (data == NULL) goto unlock; - if ((sizeof(data->hdr) + data->hdr.cal_type_size) > size) { - pr_err("%s: header size %zd plus cal type size %d are greater than data buffer size %d\n", - __func__, sizeof(data->hdr), - data->hdr.cal_type_size, size); - ret = -EFAULT; - goto unlock; - } else if (copy_to_user((void *)arg, data, + if (copy_to_user(arg, data, sizeof(data->hdr) + data->hdr.cal_type_size)) { pr_err("%s: Could not copy cal type to user\n", __func__); diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c index 325d642b7d7c..75a2bffaa3ce 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c @@ -30,9 +30,12 @@ #include #include #include +#include + #include #include #include +#include #include "msm-pcm-q6-v2.h" #include "msm-pcm-routing-v2.h" @@ -421,6 +424,42 @@ static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd) return ret; } + +static int msm_pcm_mmap_fd(struct snd_pcm_substream *substream, + struct snd_pcm_mmap_fd *mmap_fd) +{ + struct msm_audio *prtd; + struct audio_port_data *apd; + struct audio_buffer *ab; + int dir = -1; + + if (!substream->runtime) { + pr_err("%s substream runtime not found\n", __func__); + return -EFAULT; + } + + prtd = substream->runtime->private_data; + if (!prtd || !prtd->audio_client || !prtd->mmap_flag) { + pr_err("%s no audio client or not an mmap session\n", __func__); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dir = IN; + else + dir = OUT; + + apd = prtd->audio_client->port; + ab = &(apd[dir].buf[0]); + mmap_fd->fd = ion_share_dma_buf_fd(ab->client, ab->handle); + if (mmap_fd->fd >= 0) { + mmap_fd->dir = dir; + mmap_fd->actual_size = ab->actual_size; + mmap_fd->size = ab->size; + } + return mmap_fd->fd < 0 ? -EFAULT : 0; +} + static int msm_pcm_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) { @@ -445,6 +484,15 @@ static int msm_pcm_ioctl(struct snd_pcm_substream *substream, return snd_pcm_lib_ioctl(substream, cmd, arg); } +#ifdef CONFIG_COMPAT +static int msm_pcm_compat_ioctl(struct snd_pcm_substream *substream, + unsigned int cmd, void *arg) +{ + /* we only handle RESET which is common for both modes */ + return msm_pcm_ioctl(substream, cmd, arg); +} +#endif + static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -994,6 +1042,101 @@ static int msm_pcm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd) return 0; } +static int msm_pcm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int ret = 0; + struct snd_pcm *pcm = hw->private_data; + struct snd_pcm_mmap_fd __user *_mmap_fd = NULL; + struct snd_pcm_mmap_fd mmap_fd; + struct snd_pcm_substream *substream = NULL; + int32_t dir = -1; + + switch (cmd) { + case SNDRV_PCM_IOCTL_MMAP_DATA_FD: + _mmap_fd = (struct snd_pcm_mmap_fd __user *)arg; + if (get_user(dir, (int32_t __user *)&(_mmap_fd->dir))) { + pr_err("%s: error copying mmap_fd from user\n", + __func__); + ret = -EFAULT; + break; + } + if (dir != OUT && dir != IN) { + pr_err("%s invalid stream dir\n", __func__); + ret = -EINVAL; + break; + } + substream = pcm->streams[dir].substream; + if (!substream) { + pr_err("%s substream not found\n", __func__); + ret = -ENODEV; + break; + } + pr_debug("%s : %s MMAP Data fd\n", __func__, + dir == 0 ? "P" : "C"); + if (msm_pcm_mmap_fd(substream, &mmap_fd) < 0) { + pr_err("%s: error getting fd\n", + __func__); + ret = -EFAULT; + break; + } + if (put_user(mmap_fd.fd, &_mmap_fd->fd) || + put_user(mmap_fd.size, &_mmap_fd->size) || + put_user(mmap_fd.actual_size, &_mmap_fd->actual_size)) { + pr_err("%s: error copying fd\n", __func__); + return -EFAULT; + } + break; + default: + ret = -EINVAL; + break; + } + return ret; +} + +#ifdef CONFIG_COMPAT +static int msm_pcm_hwdep_compat_ioctl(struct snd_hwdep *hw, + struct file *file, + unsigned int cmd, + unsigned long arg) +{ + /* we only support mmap fd. Handling is common in both modes */ + return msm_pcm_hwdep_ioctl(hw, file, cmd, arg); +} +#else +static int msm_pcm_hwdep_compat_ioctl(struct snd_hwdep *hw, + struct file *file, + unsigned int cmd, + unsigned long arg) +{ + return -EINVAL; +} +#endif + +static int msm_pcm_add_hwdep_dev(struct snd_soc_pcm_runtime *runtime) +{ + struct snd_hwdep *hwdep; + int rc; + char id[] = "NOIRQ_NN"; + + snprintf(id, sizeof(id), "NOIRQ_%d", runtime->pcm->device); + pr_debug("%s: pcm dev %d\n", __func__, runtime->pcm->device); + rc = snd_hwdep_new(runtime->card->snd_card, + &id[0], + HWDEP_FE_BASE + runtime->pcm->device, + &hwdep); + if (!hwdep || rc < 0) { + pr_err("%s: hwdep intf failed to create %s - hwdep\n", __func__, + id); + return rc; + } + + hwdep->iface = SNDRV_HWDEP_IFACE_AUDIO_BE; /* for lack of a FE iface */ + hwdep->private_data = runtime->pcm; /* of type struct snd_pcm */ + hwdep->ops.ioctl = msm_pcm_hwdep_ioctl; + hwdep->ops.ioctl_compat = msm_pcm_hwdep_compat_ioctl; + return 0; +} static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) { @@ -1027,7 +1170,9 @@ static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) pr_err("%s: Could not add app type controls failed %d\n", __func__, ret); } - + ret = msm_pcm_add_hwdep_dev(rtd); + if (ret) + pr_err("%s: Could not add hw dep node\n", __func__); pcm->nonatomic = true; exit: return ret; @@ -1040,6 +1185,9 @@ static const struct snd_pcm_ops msm_pcm_ops = { .copy = msm_pcm_copy, .hw_params = msm_pcm_hw_params, .ioctl = msm_pcm_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = msm_pcm_compat_ioctl, +#endif .trigger = msm_pcm_trigger, .pointer = msm_pcm_pointer, .mmap = msm_pcm_mmap, diff --git a/sound/soc/msm/sdm660-common.c b/sound/soc/msm/sdm660-common.c index eddcb45e9150..b34b04b83044 100644 --- a/sound/soc/msm/sdm660-common.c +++ b/sound/soc/msm/sdm660-common.c @@ -12,6 +12,9 @@ #include #include +#include +#include +#include #include #include #include @@ -190,7 +193,7 @@ struct msm_wsa881x_dev_info { static struct snd_soc_aux_dev *msm_aux_dev; static struct snd_soc_codec_conf *msm_codec_conf; -static bool msm_swap_gnd_mic(struct snd_soc_codec *codec); +static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active); static struct wcd_mbhc_config mbhc_cfg = { .read_fw_bin = false, @@ -2038,16 +2041,16 @@ static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit) } } -static int msm_ext_disp_get_idx_from_beid(int32_t be_id) +static int msm_ext_disp_get_idx_from_beid(int32_t id) { int idx; - switch (be_id) { + switch (id) { case MSM_BACKEND_DAI_DISPLAY_PORT_RX: idx = DP_RX_IDX; break; default: - pr_err("%s: Incorrect ext_disp be_id %d\n", __func__, be_id); + pr_err("%s: Incorrect ext_disp id %d\n", __func__, id); idx = -EINVAL; break; } @@ -2077,7 +2080,7 @@ int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, pr_debug("%s: format = %d, rate = %d\n", __func__, params_format(params), params_rate(params)); - switch (dai_link->be_id) { + switch (dai_link->id) { case MSM_BACKEND_DAI_USB_RX: param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, usb_rx_cfg.bit_format); @@ -2093,8 +2096,8 @@ int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; case MSM_BACKEND_DAI_DISPLAY_PORT_RX: - idx = msm_ext_disp_get_idx_from_beid(dai_link->be_id); - if (IS_ERR_VALUE(idx)) { + idx = msm_ext_disp_get_idx_from_beid(dai_link->id); + if (idx < 0) { pr_err("%s: Incorrect ext disp idx %d\n", __func__, idx); rc = idx; @@ -2341,11 +2344,11 @@ void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream) } EXPORT_SYMBOL(msm_aux_pcm_snd_shutdown); -static int msm_get_port_id(int be_id) +static int msm_get_port_id(int id) { int afe_port_id; - switch (be_id) { + switch (id) { case MSM_BACKEND_DAI_PRI_MI2S_RX: afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; break; @@ -2371,7 +2374,7 @@ static int msm_get_port_id(int be_id) afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; break; default: - pr_err("%s: Invalid be_id: %d\n", __func__, be_id); + pr_err("%s: Invalid id: %d\n", __func__, id); afe_port_id = -EINVAL; } @@ -2422,7 +2425,7 @@ static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) int port_id = 0; int index = cpu_dai->id; - port_id = msm_get_port_id(rtd->dai_link->be_id); + port_id = msm_get_port_id(rtd->dai_link->id); if (port_id < 0) { dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); ret = port_id; @@ -2461,7 +2464,7 @@ int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int port_id = msm_get_port_id(rtd->dai_link->be_id); + int port_id = msm_get_port_id(rtd->dai_link->id); int index = cpu_dai->id; unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; @@ -2539,7 +2542,7 @@ void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) { int ret; struct snd_soc_pcm_runtime *rtd = substream->private_data; - int port_id = msm_get_port_id(rtd->dai_link->be_id); + int port_id = msm_get_port_id(rtd->dai_link->id); int index = rtd->cpu_dai->id; pr_debug("%s(): substream = %s stream = %d\n", __func__, @@ -2594,7 +2597,7 @@ static int msm_prepare_us_euro(struct snd_soc_card *card) return ret; } -static bool msm_swap_gnd_mic(struct snd_soc_codec *codec) +static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) { struct snd_soc_card *card = codec->component.card; struct msm_asoc_mach_data *pdata = @@ -2699,13 +2702,13 @@ static int msm_populate_dai_link_component_of_node( dai_link[i].codec_name = NULL; } if (pdata->snd_card_val == INT_SND_CARD) { - if ((dai_link[i].be_id == + if ((dai_link[i].id == MSM_BACKEND_DAI_INT0_MI2S_RX) || - (dai_link[i].be_id == + (dai_link[i].id == MSM_BACKEND_DAI_INT1_MI2S_RX) || - (dai_link[i].be_id == + (dai_link[i].id == MSM_BACKEND_DAI_INT2_MI2S_TX) || - (dai_link[i].be_id == + (dai_link[i].id == MSM_BACKEND_DAI_INT3_MI2S_TX)) { index = of_property_match_string(cdev->of_node, "asoc-codec-names", diff --git a/sound/soc/msm/sdm660-ext-dai-links.c b/sound/soc/msm/sdm660-ext-dai-links.c index 1c03d8c9e797..77d3875d0a06 100644 --- a/sound/soc/msm/sdm660-ext-dai-links.c +++ b/sound/soc/msm/sdm660-ext-dai-links.c @@ -86,8 +86,8 @@ static int msm_wcn_hw_params(struct snd_pcm_substream *substream, goto exit; } - dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) be_id %d\n", - __func__, tx_ch_cnt, dai_link->be_id); + dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) id %d\n", + __func__, tx_ch_cnt, dai_link->id); ret = snd_soc_dai_set_channel_map(cpu_dai, tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); @@ -279,7 +279,7 @@ static struct snd_soc_dai_link msm_ext_tasha_fe_dai[] = { .platform_name = "msm-pcm-hostless", .codec_name = "tasha_codec", .codec_dai_name = "tasha_vifeedback", - .be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, @@ -368,7 +368,7 @@ static struct snd_soc_dai_link msm_ext_tavil_fe_dai[] = { .platform_name = "msm-pcm-hostless", .codec_name = "tavil_codec", .codec_dai_name = "tavil_vifeedback", - .be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, @@ -411,7 +411,7 @@ static struct snd_soc_dai_link msm_ext_tasha_be_dai[] = { .codec_dai_name = "tasha_mix_rx1", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, .init = &msm_audrx_init, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, /* this dainlink has playback support */ @@ -428,7 +428,7 @@ static struct snd_soc_dai_link msm_ext_tasha_be_dai[] = { .codec_dai_name = "tasha_tx1", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ignore_suspend = 1, .ops = &msm_ext_slimbus_be_ops, @@ -442,7 +442,7 @@ static struct snd_soc_dai_link msm_ext_tasha_be_dai[] = { .codec_dai_name = "tasha_mix_rx1", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_1_RX, + .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, /* dai link has playback support */ @@ -458,7 +458,7 @@ static struct snd_soc_dai_link msm_ext_tasha_be_dai[] = { .codec_dai_name = "tasha_tx3", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_1_TX, + .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, .ignore_suspend = 1, @@ -472,7 +472,7 @@ static struct snd_soc_dai_link msm_ext_tasha_be_dai[] = { .codec_dai_name = "tasha_mix_rx1", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_3_RX, + .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, /* dai link has playback support */ @@ -489,7 +489,7 @@ static struct snd_soc_dai_link msm_ext_tasha_be_dai[] = { .no_pcm = 1, .dpcm_capture = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_3_TX, + .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, .ignore_suspend = 1, @@ -503,7 +503,7 @@ static struct snd_soc_dai_link msm_ext_tasha_be_dai[] = { .codec_dai_name = "tasha_mix_rx1", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_4_RX, + .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, /* dai link has playback support */ @@ -519,7 +519,7 @@ static struct snd_soc_dai_link msm_ext_tasha_be_dai[] = { .codec_dai_name = "tasha_rx3", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_5_RX, + .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, /* dai link has playback support */ @@ -536,7 +536,7 @@ static struct snd_soc_dai_link msm_ext_tasha_be_dai[] = { .codec_dai_name = "tasha_mad1", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_5_TX, + .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, .ignore_suspend = 1, @@ -550,7 +550,7 @@ static struct snd_soc_dai_link msm_ext_tasha_be_dai[] = { .codec_dai_name = "tasha_rx4", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_6_RX, + .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, /* dai link has playback support */ @@ -569,7 +569,7 @@ static struct snd_soc_dai_link msm_ext_tavil_be_dai[] = { .codec_dai_name = "tavil_rx1", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, .init = &msm_audrx_init, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, /* this dainlink has playback support */ @@ -586,7 +586,7 @@ static struct snd_soc_dai_link msm_ext_tavil_be_dai[] = { .codec_dai_name = "tavil_tx1", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ignore_suspend = 1, .ops = &msm_ext_slimbus_be_ops, @@ -600,7 +600,7 @@ static struct snd_soc_dai_link msm_ext_tavil_be_dai[] = { .codec_dai_name = "tavil_rx1", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_1_RX, + .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, /* dai link has playback support */ @@ -616,7 +616,7 @@ static struct snd_soc_dai_link msm_ext_tavil_be_dai[] = { .codec_dai_name = "tavil_tx3", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_1_TX, + .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, .ignore_suspend = 1, @@ -630,7 +630,7 @@ static struct snd_soc_dai_link msm_ext_tavil_be_dai[] = { .codec_dai_name = "tavil_rx2", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_2_RX, + .id = MSM_BACKEND_DAI_SLIMBUS_2_RX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, .ignore_pmdown_time = 1, @@ -645,7 +645,7 @@ static struct snd_soc_dai_link msm_ext_tavil_be_dai[] = { .codec_dai_name = "tavil_rx1", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_3_RX, + .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, /* dai link has playback support */ @@ -661,7 +661,7 @@ static struct snd_soc_dai_link msm_ext_tavil_be_dai[] = { .codec_dai_name = "tavil_tx1", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_3_TX, + .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, .ignore_suspend = 1, @@ -675,7 +675,7 @@ static struct snd_soc_dai_link msm_ext_tavil_be_dai[] = { .codec_dai_name = "tavil_rx1", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_4_RX, + .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, /* dai link has playback support */ @@ -691,7 +691,7 @@ static struct snd_soc_dai_link msm_ext_tavil_be_dai[] = { .codec_dai_name = "tavil_rx3", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_5_RX, + .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, /* dai link has playback support */ @@ -708,7 +708,7 @@ static struct snd_soc_dai_link msm_ext_tavil_be_dai[] = { .codec_dai_name = "tavil_mad1", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_5_TX, + .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, .ignore_suspend = 1, @@ -722,7 +722,7 @@ static struct snd_soc_dai_link msm_ext_tavil_be_dai[] = { .codec_dai_name = "tavil_rx4", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_6_RX, + .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_ext_slimbus_be_ops, /* dai link has playback support */ @@ -748,7 +748,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .dpcm_capture = 1, /* this dai link has playback support */ .ignore_pmdown_time = 1, - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA1 + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 }, {/* hw:x,1 */ .name = MSM_DAILINK_NAME(Media2), @@ -765,7 +765,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_suspend = 1, /* this dai link has playback support */ .ignore_pmdown_time = 1, - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA2, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, }, {/* hw:x,2 */ .name = "VoiceMMode1", @@ -782,7 +782,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_VOICEMMODE1, + .id = MSM_FRONTEND_DAI_VOICEMMODE1, }, {/* hw:x,3 */ .name = "MSM VoIP", @@ -799,7 +799,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_suspend = 1, /* this dai link has playback support */ .ignore_pmdown_time = 1, - .be_id = MSM_FRONTEND_DAI_VOIP, + .id = MSM_FRONTEND_DAI_VOIP, }, {/* hw:x,4 */ .name = MSM_DAILINK_NAME(ULL), @@ -815,7 +815,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_suspend = 1, /* this dai link has playback support */ .ignore_pmdown_time = 1, - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA3, + .id = MSM_FRONTEND_DAI_MULTIMEDIA3, }, /* Hostless PCM purpose */ {/* hw:x,5 */ @@ -871,7 +871,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA4, + .id = MSM_FRONTEND_DAI_MULTIMEDIA4, }, {/* hw:x,9*/ .name = "AUXPCM Hostless", @@ -953,7 +953,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_suspend = 1, /* this dai link has playback support */ .ignore_pmdown_time = 1, - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .id = MSM_FRONTEND_DAI_MULTIMEDIA5, }, /* LSM FE */ {/* hw:x,14 */ @@ -970,7 +970,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_LSM1, + .id = MSM_FRONTEND_DAI_LSM1, }, {/* hw:x,15 */ .name = MSM_DAILINK_NAME(Compress2), @@ -987,7 +987,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_suspend = 1, /* this dai link has playback support */ .ignore_pmdown_time = 1, - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA7, + .id = MSM_FRONTEND_DAI_MULTIMEDIA7, }, {/* hw:x,16 */ .name = MSM_DAILINK_NAME(Compress3), @@ -1004,7 +1004,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA10, + .id = MSM_FRONTEND_DAI_MULTIMEDIA10, }, {/* hw:x,17 */ .name = MSM_DAILINK_NAME(ULL_NOIRQ), @@ -1021,7 +1021,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA8, + .id = MSM_FRONTEND_DAI_MULTIMEDIA8, }, {/* hw:x,18 */ .name = "HDMI_RX_HOSTLESS", @@ -1053,7 +1053,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_VOICEMMODE2, + .id = MSM_FRONTEND_DAI_VOICEMMODE2, }, {/* hw:x,20 */ .name = "Listen 2 Audio Service", @@ -1069,7 +1069,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_LSM2, + .id = MSM_FRONTEND_DAI_LSM2, }, {/* hw:x,21 */ .name = "Listen 3 Audio Service", @@ -1085,7 +1085,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_LSM3, + .id = MSM_FRONTEND_DAI_LSM3, }, {/* hw:x,22 */ .name = "Listen 4 Audio Service", @@ -1101,7 +1101,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_LSM4, + .id = MSM_FRONTEND_DAI_LSM4, }, {/* hw:x,23 */ .name = "Listen 5 Audio Service", @@ -1117,7 +1117,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_LSM5, + .id = MSM_FRONTEND_DAI_LSM5, }, {/* hw:x,24 */ .name = "Listen 6 Audio Service", @@ -1133,7 +1133,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_LSM6 + .id = MSM_FRONTEND_DAI_LSM6 }, {/* hw:x,25 */ .name = "Listen 7 Audio Service", @@ -1149,7 +1149,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_LSM7, + .id = MSM_FRONTEND_DAI_LSM7, }, {/* hw:x,26 */ .name = "Listen 8 Audio Service", @@ -1165,7 +1165,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_LSM8, + .id = MSM_FRONTEND_DAI_LSM8, }, {/* hw:x,27 */ .name = MSM_DAILINK_NAME(Media9), @@ -1182,7 +1182,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA9, + .id = MSM_FRONTEND_DAI_MULTIMEDIA9, }, {/* hw:x,28 */ .name = MSM_DAILINK_NAME(Compress4), @@ -1199,7 +1199,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA11, + .id = MSM_FRONTEND_DAI_MULTIMEDIA11, }, {/* hw:x,29 */ .name = MSM_DAILINK_NAME(Compress5), @@ -1216,7 +1216,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA12, + .id = MSM_FRONTEND_DAI_MULTIMEDIA12, }, {/* hw:x,30 */ .name = MSM_DAILINK_NAME(Compress6), @@ -1233,7 +1233,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA13, + .id = MSM_FRONTEND_DAI_MULTIMEDIA13, }, {/* hw:x,31 */ .name = MSM_DAILINK_NAME(Compress7), @@ -1250,7 +1250,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA14, + .id = MSM_FRONTEND_DAI_MULTIMEDIA14, }, {/* hw:x,32 */ .name = MSM_DAILINK_NAME(Compress8), @@ -1267,7 +1267,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA15, + .id = MSM_FRONTEND_DAI_MULTIMEDIA15, }, {/* hw:x,33 */ .name = MSM_DAILINK_NAME(Compress9), @@ -1284,7 +1284,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA16, + .id = MSM_FRONTEND_DAI_MULTIMEDIA16, }, {/* hw:x,34 */ .name = "SLIMBUS_8 Hostless", @@ -1332,7 +1332,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_suspend = 1, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_pmdown_time = 1, - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA6, + .id = MSM_FRONTEND_DAI_MULTIMEDIA6, }, }; @@ -1346,7 +1346,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_AFE_PCM_RX, + .id = MSM_BACKEND_DAI_AFE_PCM_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, /* this dai link has playback support */ .ignore_pmdown_time = 1, @@ -1361,7 +1361,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_AFE_PCM_TX, + .id = MSM_BACKEND_DAI_AFE_PCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, }, @@ -1375,7 +1375,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_INCALL_RECORD_TX, + .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ignore_suspend = 1, }, @@ -1389,7 +1389,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_INCALL_RECORD_RX, + .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ignore_suspend = 1, }, @@ -1403,7 +1403,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ignore_suspend = 1, }, @@ -1417,7 +1417,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ignore_suspend = 1, }, @@ -1430,7 +1430,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_USB_RX, + .id = MSM_BACKEND_DAI_USB_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, @@ -1444,7 +1444,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_USB_TX, + .id = MSM_BACKEND_DAI_USB_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, }, @@ -1457,7 +1457,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, @@ -1471,7 +1471,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, @@ -1485,7 +1485,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, @@ -1499,7 +1499,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, @@ -1513,7 +1513,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, @@ -1527,7 +1527,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, @@ -1541,7 +1541,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, @@ -1555,7 +1555,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, @@ -1572,7 +1572,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_PRI_MI2S_RX, + .id = MSM_BACKEND_DAI_PRI_MI2S_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, @@ -1587,7 +1587,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_PRI_MI2S_TX, + .id = MSM_BACKEND_DAI_PRI_MI2S_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, @@ -1601,7 +1601,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, @@ -1616,7 +1616,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, @@ -1630,7 +1630,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, @@ -1645,7 +1645,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, @@ -1659,7 +1659,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, @@ -1674,7 +1674,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, @@ -1692,7 +1692,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_AUXPCM_RX, + .id = MSM_BACKEND_DAI_AUXPCM_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, @@ -1707,7 +1707,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_AUXPCM_TX, + .id = MSM_BACKEND_DAI_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, @@ -1723,7 +1723,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, @@ -1738,7 +1738,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, .ignore_pmdown_time = 1, @@ -1754,7 +1754,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, @@ -1769,7 +1769,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, .ignore_pmdown_time = 1, @@ -1785,7 +1785,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, @@ -1800,7 +1800,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, .ignore_pmdown_time = 1, @@ -1822,7 +1822,7 @@ static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_7_RX, + .id = MSM_BACKEND_DAI_SLIMBUS_7_RX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_wcn_ops, /* dai link has playback support */ @@ -1838,7 +1838,7 @@ static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { .codec_dai_name = "btfm_bt_sco_slim_tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_7_TX, + .id = MSM_BACKEND_DAI_SLIMBUS_7_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ops = &msm_wcn_ops, .ignore_suspend = 1, @@ -1852,7 +1852,7 @@ static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { .codec_dai_name = "btfm_fm_slim_tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_8_TX, + .id = MSM_BACKEND_DAI_SLIMBUS_8_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .init = &msm_wcn_init, .ops = &msm_wcn_ops, @@ -1871,7 +1871,7 @@ static struct snd_soc_dai_link ext_disp_be_dai_link[] = { .codec_dai_name = "msm_dp_audio_codec_rx_dai", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, + .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, diff --git a/sound/soc/msm/sdm660-external.c b/sound/soc/msm/sdm660-external.c index 2c3d7fc3e63f..84d1c2ea9b18 100644 --- a/sound/soc/msm/sdm660-external.c +++ b/sound/soc/msm/sdm660-external.c @@ -747,11 +747,11 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_bt_sample_rate_put), }; -static int msm_slim_get_ch_from_beid(int32_t be_id) +static int msm_slim_get_ch_from_beid(int32_t id) { int ch_id = 0; - switch (be_id) { + switch (id) { case MSM_BACKEND_DAI_SLIMBUS_0_RX: ch_id = SLIM_RX_0; break; @@ -821,14 +821,14 @@ int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, pr_debug("%s: format = %d, rate = %d\n", __func__, params_format(params), params_rate(params)); - switch (dai_link->be_id) { + switch (dai_link->id) { case MSM_BACKEND_DAI_SLIMBUS_0_RX: case MSM_BACKEND_DAI_SLIMBUS_1_RX: case MSM_BACKEND_DAI_SLIMBUS_2_RX: case MSM_BACKEND_DAI_SLIMBUS_3_RX: case MSM_BACKEND_DAI_SLIMBUS_4_RX: case MSM_BACKEND_DAI_SLIMBUS_6_RX: - idx = msm_slim_get_ch_from_beid(dai_link->be_id); + idx = msm_slim_get_ch_from_beid(dai_link->id); param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, slim_rx_cfg[idx].bit_format); rate->min = rate->max = slim_rx_cfg[idx].sample_rate; @@ -837,7 +837,7 @@ int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, case MSM_BACKEND_DAI_SLIMBUS_0_TX: case MSM_BACKEND_DAI_SLIMBUS_3_TX: - idx = msm_slim_get_ch_from_beid(dai_link->be_id); + idx = msm_slim_get_ch_from_beid(dai_link->id); param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, slim_tx_cfg[idx].bit_format); rate->min = rate->max = slim_tx_cfg[idx].sample_rate; @@ -938,15 +938,15 @@ int msm_snd_hw_params(struct snd_pcm_substream *substream, __func__, ret); goto err_ch_map; } - if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_5_RX) { + if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_5_RX) { pr_debug("%s: rx_5_ch=%d\n", __func__, slim_rx_cfg[5].channels); rx_ch_count = slim_rx_cfg[5].channels; - } else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_2_RX) { + } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_2_RX) { pr_debug("%s: rx_2_ch=%d\n", __func__, slim_rx_cfg[2].channels); rx_ch_count = slim_rx_cfg[2].channels; - } else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_6_RX) { + } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_6_RX) { pr_debug("%s: rx_6_ch=%d\n", __func__, slim_rx_cfg[6].channels); rx_ch_count = slim_rx_cfg[6].channels; @@ -973,19 +973,19 @@ int msm_snd_hw_params(struct snd_pcm_substream *substream, goto err_ch_map; } /* For _tx1 case */ - if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_0_TX) + if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_0_TX) user_set_tx_ch = slim_tx_cfg[0].channels; /* For _tx3 case */ - else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_1_TX) + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_1_TX) user_set_tx_ch = slim_tx_cfg[1].channels; - else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_4_TX) + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_4_TX) user_set_tx_ch = msm_vi_feed_tx_ch; else user_set_tx_ch = tx_ch_cnt; - pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), be_id (%d)\n", + pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), id (%d)\n", __func__, slim_tx_cfg[0].channels, user_set_tx_ch, - tx_ch_cnt, dai_link->be_id); + tx_ch_cnt, dai_link->id); ret = snd_soc_dai_set_channel_map(cpu_dai, user_set_tx_ch, tx_ch, 0, 0); @@ -1097,8 +1097,8 @@ int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream, goto end; } - pr_debug("%s: tx_ch_cnt(%d) be_id %d\n", - __func__, tx_ch_cnt, dai_link->be_id); + pr_debug("%s: tx_ch_cnt(%d) id %d\n", + __func__, tx_ch_cnt, dai_link->id); ret = snd_soc_dai_set_channel_map(cpu_dai, tx_ch_cnt, tx_ch, 0, 0); @@ -1495,7 +1495,7 @@ int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_codec_get_dapm(codec); struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_pcm_runtime *rtd_aux = rtd->card->rtd_aux; + struct snd_soc_component *aux_comp; struct snd_card *card; struct snd_info_entry *entry; struct msm_asoc_mach_data *pdata = @@ -1678,13 +1678,20 @@ int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) * Send speaker configuration only for WSA8810. * Defalut configuration is for WSA8815. */ + pr_debug("%s: Number of aux devices: %d\n", + __func__, rtd->card->num_aux_devs); + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { - if (rtd_aux && rtd_aux->component) - if (!strcmp(rtd_aux->component->name, WSA8810_NAME_1) || - !strcmp(rtd_aux->component->name, WSA8810_NAME_2)) { + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->aux_comp_list)) { + aux_comp = list_first_entry(&rtd->card->aux_comp_list, + struct snd_soc_component, list_aux); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { tavil_set_spkr_mode(rtd->codec, SPKR_MODE_1); tavil_set_spkr_gain_offset(rtd->codec, RX_GAIN_OFFSET_M1P5_DB); + } } card = rtd->card->snd_card; entry = snd_info_create_subdir(card->module, "codecs", @@ -1698,12 +1705,16 @@ int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) pdata->codec_root = entry; tavil_codec_info_create_codec_entry(pdata->codec_root, codec); } else { - if (rtd_aux && rtd_aux->component) - if (!strcmp(rtd_aux->component->name, WSA8810_NAME_1) || - !strcmp(rtd_aux->component->name, WSA8810_NAME_2)) { + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->aux_comp_list)) { + aux_comp = list_first_entry(&rtd->card->aux_comp_list, + struct snd_soc_component, list_aux); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { tasha_set_spkr_mode(rtd->codec, SPKR_MODE_1); tasha_set_spkr_gain_offset(rtd->codec, RX_GAIN_OFFSET_M1P5_DB); + } } card = rtd->card->snd_card; entry = snd_info_create_subdir(card->module, "codecs", diff --git a/sound/soc/msm/sdm660-internal.c b/sound/soc/msm/sdm660-internal.c index 802137ba4b50..a57d6f611942 100644 --- a/sound/soc/msm/sdm660-internal.c +++ b/sound/soc/msm/sdm660-internal.c @@ -539,11 +539,11 @@ static int enable_spk_ext_pa(struct snd_soc_codec *codec, int enable) return 0; } -static int int_mi2s_get_idx_from_beid(int32_t be_id) +static int int_mi2s_get_idx_from_beid(int32_t id) { int idx = 0; - switch (be_id) { + switch (id) { case MSM_BACKEND_DAI_INT0_MI2S_RX: idx = INT0_MI2S; break; @@ -596,13 +596,13 @@ static int int_mi2s_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, pr_debug("%s: format = %d, rate = %d\n", __func__, params_format(params), params_rate(params)); - switch (dai_link->be_id) { + switch (dai_link->id) { case MSM_BACKEND_DAI_INT0_MI2S_RX: case MSM_BACKEND_DAI_INT2_MI2S_TX: case MSM_BACKEND_DAI_INT3_MI2S_TX: case MSM_BACKEND_DAI_INT4_MI2S_RX: case MSM_BACKEND_DAI_INT5_MI2S_TX: - idx = int_mi2s_get_idx_from_beid(dai_link->be_id); + idx = int_mi2s_get_idx_from_beid(dai_link->id); rate->min = rate->max = int_mi2s_cfg[idx].sample_rate; channels->min = channels->max = int_mi2s_cfg[idx].channels; @@ -625,7 +625,7 @@ static int msm_btfm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - switch (dai_link->be_id) { + switch (dai_link->id) { case MSM_BACKEND_DAI_SLIMBUS_7_RX: case MSM_BACKEND_DAI_SLIMBUS_7_TX: param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, @@ -982,11 +982,11 @@ static int msm_int_mclk0_event(struct snd_soc_dapm_widget *w, return 0; } -static int int_mi2s_get_port_id(int be_id) +static int int_mi2s_get_port_id(int id) { int afe_port_id; - switch (be_id) { + switch (id) { case MSM_BACKEND_DAI_INT0_MI2S_RX: afe_port_id = AFE_PORT_ID_INT0_MI2S_RX; break; @@ -1003,7 +1003,7 @@ static int int_mi2s_get_port_id(int be_id) afe_port_id = AFE_PORT_ID_INT5_MI2S_TX; break; default: - pr_err("%s: Invalid be_id: %d\n", __func__, be_id); + pr_err("%s: Invalid id: %d\n", __func__, id); afe_port_id = -EINVAL; } @@ -1073,7 +1073,7 @@ static int int_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) int port_id = 0; int index; - port_id = int_mi2s_get_port_id(rtd->dai_link->be_id); + port_id = int_mi2s_get_port_id(rtd->dai_link->id); if (port_id < 0) { dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); ret = port_id; @@ -1303,7 +1303,7 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) card = rtd->card->snd_card; if (!codec_root) - codec_root = snd_register_module_info(card->module, "codecs", + codec_root = snd_info_create_subdir(card->module, "codecs", card->proc_root); if (!codec_root) { pr_debug("%s: Cannot create codecs module entry\n", @@ -1323,7 +1323,7 @@ static int msm_sdw_audrx_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_pcm_runtime *rtd_aux = rtd->card->rtd_aux; + struct snd_soc_component *aux_comp; struct snd_card *card; snd_soc_add_codec_controls(codec, msm_sdw_controls, @@ -1342,16 +1342,22 @@ static int msm_sdw_audrx_init(struct snd_soc_pcm_runtime *rtd) * Send speaker configuration only for WSA8810. * Default configuration is for WSA8815. */ - if (rtd_aux && rtd_aux->component) - if (!strcmp(rtd_aux->component->name, WSA8810_NAME_1) || - !strcmp(rtd_aux->component->name, WSA8810_NAME_2)) { + pr_debug("%s: Number of aux devices: %d\n", + __func__, rtd->card->num_aux_devs); + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->aux_comp_list)) { + aux_comp = list_first_entry(&rtd->card->aux_comp_list, + struct snd_soc_component, list_aux); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { msm_sdw_set_spkr_mode(rtd->codec, SPKR_MODE_1); msm_sdw_set_spkr_gain_offset(rtd->codec, RX_GAIN_OFFSET_M1P5_DB); + } } card = rtd->card->snd_card; if (!codec_root) - codec_root = snd_register_module_info(card->module, "codecs", + codec_root = snd_info_create_subdir(card->module, "codecs", card->proc_root); if (!codec_root) { pr_debug("%s: Cannot create codecs module entry\n", @@ -1396,8 +1402,8 @@ static int msm_wcn_hw_params(struct snd_pcm_substream *substream, goto exit; } - dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) be_id %d\n", - __func__, tx_ch_cnt, dai_link->be_id); + dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) id %d\n", + __func__, tx_ch_cnt, dai_link->id); ret = snd_soc_dai_set_channel_map(cpu_dai, tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); @@ -1669,7 +1675,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .dpcm_capture = 1, /* this dai link has playback support */ .ignore_pmdown_time = 1, - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA1 + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 }, {/* hw:x,1 */ .name = MSM_DAILINK_NAME(Media2), @@ -1686,7 +1692,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_suspend = 1, /* this dai link has playback support */ .ignore_pmdown_time = 1, - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA2, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, }, {/* hw:x,2 */ .name = "VoiceMMode1", @@ -1703,7 +1709,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_VOICEMMODE1, + .id = MSM_FRONTEND_DAI_VOICEMMODE1, }, {/* hw:x,3 */ .name = "MSM VoIP", @@ -1720,7 +1726,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_suspend = 1, /* this dai link has playback support */ .ignore_pmdown_time = 1, - .be_id = MSM_FRONTEND_DAI_VOIP, + .id = MSM_FRONTEND_DAI_VOIP, }, {/* hw:x,4 */ .name = MSM_DAILINK_NAME(ULL), @@ -1736,7 +1742,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_suspend = 1, /* this dai link has playback support */ .ignore_pmdown_time = 1, - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA3, + .id = MSM_FRONTEND_DAI_MULTIMEDIA3, }, /* Hostless PCM purpose */ {/* hw:x,5 */ @@ -1792,7 +1798,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA4, + .id = MSM_FRONTEND_DAI_MULTIMEDIA4, }, {/* hw:x,9*/ .name = "AUXPCM Hostless", @@ -1873,7 +1879,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_suspend = 1, /* this dai link has playback support */ .ignore_pmdown_time = 1, - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .id = MSM_FRONTEND_DAI_MULTIMEDIA5, }, /* LSM FE */ {/* hw:x,14 */ @@ -1890,7 +1896,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_LSM1, + .id = MSM_FRONTEND_DAI_LSM1, }, {/* hw:x,15 */ .name = MSM_DAILINK_NAME(Compress2), @@ -1905,7 +1911,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .ignore_suspend = 1, - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA7, + .id = MSM_FRONTEND_DAI_MULTIMEDIA7, }, {/* hw:x,16 */ .name = MSM_DAILINK_NAME(Compress3), @@ -1922,7 +1928,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA10, + .id = MSM_FRONTEND_DAI_MULTIMEDIA10, }, {/* hw:x,17 */ .name = MSM_DAILINK_NAME(ULL_NOIRQ), @@ -1939,7 +1945,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA8, + .id = MSM_FRONTEND_DAI_MULTIMEDIA8, }, {/* hw:x,18 */ .name = "HDMI_RX_HOSTLESS", @@ -1971,7 +1977,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_VOICEMMODE2, + .id = MSM_FRONTEND_DAI_VOICEMMODE2, }, {/* hw:x,20 */ .name = "Listen 2 Audio Service", @@ -1987,7 +1993,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_LSM2, + .id = MSM_FRONTEND_DAI_LSM2, }, {/* hw:x,21 */ .name = "Listen 3 Audio Service", @@ -2003,7 +2009,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_LSM3, + .id = MSM_FRONTEND_DAI_LSM3, }, {/* hw:x,22 */ .name = "Listen 4 Audio Service", @@ -2019,7 +2025,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_LSM4, + .id = MSM_FRONTEND_DAI_LSM4, }, {/* hw:x,23 */ .name = "Listen 5 Audio Service", @@ -2035,7 +2041,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_LSM5, + .id = MSM_FRONTEND_DAI_LSM5, }, {/* hw:x,24 */ .name = "Listen 6 Audio Service", @@ -2051,7 +2057,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_LSM6 + .id = MSM_FRONTEND_DAI_LSM6 }, {/* hw:x,25 */ .name = "Listen 7 Audio Service", @@ -2067,7 +2073,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_LSM7, + .id = MSM_FRONTEND_DAI_LSM7, }, {/* hw:x,26 */ .name = "Listen 8 Audio Service", @@ -2083,7 +2089,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", - .be_id = MSM_FRONTEND_DAI_LSM8, + .id = MSM_FRONTEND_DAI_LSM8, }, {/* hw:x,27 */ .name = MSM_DAILINK_NAME(Media9), @@ -2100,7 +2106,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA9, + .id = MSM_FRONTEND_DAI_MULTIMEDIA9, }, {/* hw:x,28 */ .name = MSM_DAILINK_NAME(Compress4), @@ -2117,7 +2123,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA11, + .id = MSM_FRONTEND_DAI_MULTIMEDIA11, }, {/* hw:x,29 */ .name = MSM_DAILINK_NAME(Compress5), @@ -2134,7 +2140,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA12, + .id = MSM_FRONTEND_DAI_MULTIMEDIA12, }, {/* hw:x,30 */ .name = MSM_DAILINK_NAME(Compress6), @@ -2151,7 +2157,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA13, + .id = MSM_FRONTEND_DAI_MULTIMEDIA13, }, {/* hw:x,31 */ .name = MSM_DAILINK_NAME(Compress7), @@ -2168,7 +2174,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA14, + .id = MSM_FRONTEND_DAI_MULTIMEDIA14, }, {/* hw:x,32 */ .name = MSM_DAILINK_NAME(Compress8), @@ -2185,7 +2191,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA15, + .id = MSM_FRONTEND_DAI_MULTIMEDIA15, }, {/* hw:x,33 */ .name = MSM_DAILINK_NAME(Compress9), @@ -2202,7 +2208,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, /* this dai link has playback support */ - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA16, + .id = MSM_FRONTEND_DAI_MULTIMEDIA16, }, {/* hw:x,34 */ .name = "SLIMBUS_8 Hostless", @@ -2302,7 +2308,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_suspend = 1, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_pmdown_time = 1, - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA6, + .id = MSM_FRONTEND_DAI_MULTIMEDIA6, }, }; @@ -2315,7 +2321,7 @@ static struct snd_soc_dai_link msm_int_wsa_dai[] = { .platform_name = "msm-pcm-hostless", .codec_name = "msm_sdw_codec", .codec_dai_name = "msm_sdw_vifeedback", - .be_id = MSM_BACKEND_DAI_INT5_MI2S_TX, + .id = MSM_BACKEND_DAI_INT5_MI2S_TX, .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, .ops = &msm_sdw_mi2s_be_ops, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, @@ -2338,7 +2344,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .dpcm_playback = 1, .async_ops = ASYNC_DPCM_SND_SOC_PREPARE | ASYNC_DPCM_SND_SOC_HW_PARAMS, - .be_id = MSM_BACKEND_DAI_INT0_MI2S_RX, + .id = MSM_BACKEND_DAI_INT0_MI2S_RX, .init = &msm_audrx_init, .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, .ops = &msm_int_mi2s_be_ops, @@ -2355,7 +2361,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .dpcm_capture = 1, .async_ops = ASYNC_DPCM_SND_SOC_PREPARE | ASYNC_DPCM_SND_SOC_HW_PARAMS, - .be_id = MSM_BACKEND_DAI_INT3_MI2S_TX, + .id = MSM_BACKEND_DAI_INT3_MI2S_TX, .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, .ops = &msm_int_mi2s_be_ops, .ignore_suspend = 1, @@ -2371,7 +2377,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .dpcm_capture = 1, .async_ops = ASYNC_DPCM_SND_SOC_PREPARE | ASYNC_DPCM_SND_SOC_HW_PARAMS, - .be_id = MSM_BACKEND_DAI_INT2_MI2S_TX, + .id = MSM_BACKEND_DAI_INT2_MI2S_TX, .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, .ops = &msm_int_mi2s_be_ops, .ignore_suspend = 1, @@ -2385,7 +2391,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_AFE_PCM_RX, + .id = MSM_BACKEND_DAI_AFE_PCM_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, /* this dainlink has playback support */ .ignore_pmdown_time = 1, @@ -2400,7 +2406,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_AFE_PCM_TX, + .id = MSM_BACKEND_DAI_AFE_PCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, }, @@ -2414,7 +2420,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_INCALL_RECORD_TX, + .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_suspend = 1, }, @@ -2428,7 +2434,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_INCALL_RECORD_RX, + .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_suspend = 1, }, @@ -2442,7 +2448,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_suspend = 1, }, @@ -2456,7 +2462,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_suspend = 1, }, @@ -2469,7 +2475,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_USB_RX, + .id = MSM_BACKEND_DAI_USB_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, @@ -2483,7 +2489,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_USB_TX, + .id = MSM_BACKEND_DAI_USB_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, }, @@ -2496,7 +2502,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, @@ -2510,7 +2516,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, @@ -2524,7 +2530,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, @@ -2538,7 +2544,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, @@ -2552,7 +2558,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, @@ -2566,7 +2572,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, @@ -2580,7 +2586,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, @@ -2594,7 +2600,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, @@ -2611,7 +2617,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_PRI_MI2S_RX, + .id = MSM_BACKEND_DAI_PRI_MI2S_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, @@ -2626,7 +2632,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_PRI_MI2S_TX, + .id = MSM_BACKEND_DAI_PRI_MI2S_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, @@ -2640,7 +2646,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, @@ -2655,7 +2661,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, @@ -2669,7 +2675,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, @@ -2684,7 +2690,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, @@ -2698,7 +2704,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, @@ -2713,7 +2719,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, @@ -2731,7 +2737,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_AUXPCM_RX, + .id = MSM_BACKEND_DAI_AUXPCM_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, @@ -2746,7 +2752,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_AUXPCM_TX, + .id = MSM_BACKEND_DAI_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, @@ -2762,7 +2768,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, @@ -2777,7 +2783,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, .ignore_pmdown_time = 1, @@ -2793,7 +2799,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, @@ -2808,7 +2814,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, .ignore_pmdown_time = 1, @@ -2824,7 +2830,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .codec_dai_name = "msm-stub-rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, @@ -2839,7 +2845,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .codec_dai_name = "msm-stub-tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, .ignore_pmdown_time = 1, @@ -2862,7 +2868,7 @@ static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_7_RX, + .id = MSM_BACKEND_DAI_SLIMBUS_7_RX, .be_hw_params_fixup = msm_btfm_be_hw_params_fixup, .ops = &msm_wcn_ops, /* dai link has playback support */ @@ -2878,7 +2884,7 @@ static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { .codec_dai_name = "btfm_bt_sco_slim_tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_7_TX, + .id = MSM_BACKEND_DAI_SLIMBUS_7_TX, .be_hw_params_fixup = msm_btfm_be_hw_params_fixup, .ops = &msm_wcn_ops, .ignore_suspend = 1, @@ -2892,7 +2898,7 @@ static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { .codec_dai_name = "btfm_fm_slim_tx", .no_pcm = 1, .dpcm_capture = 1, - .be_id = MSM_BACKEND_DAI_SLIMBUS_8_TX, + .id = MSM_BACKEND_DAI_SLIMBUS_8_TX, .be_hw_params_fixup = msm_btfm_be_hw_params_fixup, .init = &msm_wcn_init, .ops = &msm_wcn_ops, @@ -2910,7 +2916,7 @@ static struct snd_soc_dai_link msm_wsa_be_dai_links[] = { .codec_dai_name = "msm_sdw_i2s_rx1", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_INT4_MI2S_RX, + .id = MSM_BACKEND_DAI_INT4_MI2S_RX, .init = &msm_sdw_audrx_init, .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, .ops = &msm_sdw_mi2s_be_ops, @@ -2929,7 +2935,7 @@ static struct snd_soc_dai_link ext_disp_be_dai_link[] = { .codec_dai_name = "msm_dp_audio_codec_rx_dai", .no_pcm = 1, .dpcm_playback = 1, - .be_id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, + .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, diff --git a/sound/soc/msm/sdm845.c b/sound/soc/msm/sdm845.c index d3c4e05c65c8..3be194cdc48d 100644 --- a/sound/soc/msm/sdm845.c +++ b/sound/soc/msm/sdm845.c @@ -495,6 +495,8 @@ static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(hifi_function, hifi_text); static struct platform_device *spdev; @@ -538,10 +540,10 @@ static struct wcd_mbhc_config wcd_mbhc_cfg = { }; static struct snd_soc_dapm_route wcd_audio_paths[] = { - {"MIC BIAS1", NULL, "MCLK"}, - {"MIC BIAS2", NULL, "MCLK"}, - {"MIC BIAS3", NULL, "MCLK"}, - {"MIC BIAS4", NULL, "MCLK"}, + {"MIC BIAS1", NULL, "MCLK TX"}, + {"MIC BIAS2", NULL, "MCLK TX"}, + {"MIC BIAS3", NULL, "MCLK TX"}, + {"MIC BIAS4", NULL, "MCLK TX"}, }; static struct afe_clk_set mi2s_clk[MI2S_MAX] = { @@ -2252,7 +2254,7 @@ static int mi2s_get_sample_rate(int value) return sample_rate; } -static int mi2s_get_format(int value) +static int mi2s_auxpcm_get_format(int value) { int format; @@ -2276,7 +2278,7 @@ static int mi2s_get_format(int value) return format; } -static int mi2s_get_format_value(int format) +static int mi2s_auxpcm_get_format_value(int format) { int value; @@ -2441,7 +2443,7 @@ static int msm_mi2s_rx_format_get(struct snd_kcontrol *kcontrol, return idx; ucontrol->value.enumerated.item[0] = - mi2s_get_format_value(mi2s_rx_cfg[idx].bit_format); + mi2s_auxpcm_get_format_value(mi2s_rx_cfg[idx].bit_format); pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, idx, mi2s_rx_cfg[idx].bit_format, @@ -2459,7 +2461,7 @@ static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol, return idx; mi2s_rx_cfg[idx].bit_format = - mi2s_get_format(ucontrol->value.enumerated.item[0]); + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, idx, mi2s_rx_cfg[idx].bit_format, @@ -2477,7 +2479,7 @@ static int msm_mi2s_tx_format_get(struct snd_kcontrol *kcontrol, return idx; ucontrol->value.enumerated.item[0] = - mi2s_get_format_value(mi2s_tx_cfg[idx].bit_format); + mi2s_auxpcm_get_format_value(mi2s_tx_cfg[idx].bit_format); pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, idx, mi2s_tx_cfg[idx].bit_format, @@ -2495,7 +2497,7 @@ static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol, return idx; mi2s_tx_cfg[idx].bit_format = - mi2s_get_format(ucontrol->value.enumerated.item[0]); + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, idx, mi2s_tx_cfg[idx].bit_format, @@ -2504,6 +2506,78 @@ static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol, return 0; } +static int msm_aux_pcm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(aux_pcm_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(aux_pcm_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + static int msm_hifi_ctrl(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); @@ -2765,6 +2839,22 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), SOC_ENUM_EXT("QUAT_MI2S_TX Format", mi2s_tx_format, msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get, msm_hifi_put), }; @@ -2784,6 +2874,38 @@ static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, return ret; } +static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, + int enable, bool dapm) +{ + int ret = 0; + + if (!strcmp(dev_name(codec->dev), "tavil_codec")) { + ret = tavil_cdc_mclk_tx_enable(codec, enable); + } else { + dev_err(codec->dev, "%s: unknown codec to enable TX ext clk\n", + __func__); + ret = -EINVAL; + } + + return ret; +} + +static int msm_mclk_tx_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + pr_debug("%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return msm_snd_enable_codec_ext_tx_clk(codec, 1, true); + case SND_SOC_DAPM_POST_PMD: + return msm_snd_enable_codec_ext_tx_clk(codec, 0, true); + } + return 0; +} + static int msm_mclk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -2840,7 +2962,7 @@ static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0, - NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + msm_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_SPK("Lineout_1 amp", NULL), SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), @@ -3134,6 +3256,8 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; case MSM_BACKEND_DAI_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format); rate->min = rate->max = aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; channels->min = channels->max = @@ -3141,6 +3265,8 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; case MSM_BACKEND_DAI_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[PRIM_AUX_PCM].bit_format); rate->min = rate->max = aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; channels->min = channels->max = @@ -3148,6 +3274,8 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; case MSM_BACKEND_DAI_SEC_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[SEC_AUX_PCM].bit_format); rate->min = rate->max = aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate; channels->min = channels->max = @@ -3155,6 +3283,8 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; case MSM_BACKEND_DAI_SEC_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[SEC_AUX_PCM].bit_format); rate->min = rate->max = aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate; channels->min = channels->max = @@ -3162,6 +3292,8 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; case MSM_BACKEND_DAI_TERT_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[TERT_AUX_PCM].bit_format); rate->min = rate->max = aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate; channels->min = channels->max = @@ -3169,6 +3301,8 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; case MSM_BACKEND_DAI_TERT_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[TERT_AUX_PCM].bit_format); rate->min = rate->max = aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate; channels->min = channels->max = @@ -3176,6 +3310,8 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; case MSM_BACKEND_DAI_QUAT_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[QUAT_AUX_PCM].bit_format); rate->min = rate->max = aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate; channels->min = channels->max = @@ -3183,6 +3319,8 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; case MSM_BACKEND_DAI_QUAT_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[QUAT_AUX_PCM].bit_format); rate->min = rate->max = aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate; channels->min = channels->max = -- GitLab From 605b42f92c7892864eb0a4ad42c043f656281d76 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 1 Aug 2017 22:02:15 +0530 Subject: [PATCH 0006/1645] audio-lnx: Rename folders to new flat structure. Kernel audio drivers can be categorised into below folders. asoc - ALSA based drivers, asoc/codecs - codec drivers, ipc - APR IPC communication drivers, dsp - DSP low level drivers/Audio ION/ADSP Loader, dsp/codecs - Native encoders and decoders, soc - SoC based drivers(pinctrl/regmap/soundwire) Restructure drivers to above folder format. Include directories also follow above format. Change-Id: I8fa0857baaacd47db126fb5c1f1f5ed7e886dbc0 Signed-off-by: Laxminath Kasam --- Makefile | 6 +- {sound/soc/msm => asoc}/Makefile | 18 +- {sound/soc => asoc}/codecs/Makefile | 8 +- {sound/soc => asoc}/codecs/audio-ext-clk-up.c | 2 +- {sound/soc => asoc}/codecs/audio-ext-clk-up.h | 0 {sound/soc => asoc}/codecs/audio-ext-clk.c | 0 .../linux/mfd/wcd9xxx => asoc/codecs}/core.h | 0 {include/sound => asoc/codecs}/cpe_cmi.h | 0 {include/sound => asoc/codecs}/cpe_core.h | 0 {include/sound => asoc/codecs}/cpe_err.h | 0 .../mfd => asoc/codecs}/msm-cdc-pinctrl.c | 2 +- .../mfd => asoc/codecs}/msm-cdc-pinctrl.h | 0 {drivers/mfd => asoc/codecs}/msm-cdc-supply.c | 2 +- .../mfd => asoc/codecs}/msm-cdc-supply.h | 0 .../soc => asoc}/codecs/msm_hdmi_codec_rx.c | 0 {sound/soc => asoc}/codecs/msm_sdw/Makefile | 0 .../codecs/msm_sdw/msm-sdw-tables.c | 0 {sound/soc => asoc}/codecs/msm_sdw/msm_sdw.h | 0 .../soc => asoc}/codecs/msm_sdw/msm_sdw_cdc.c | 0 .../codecs/msm_sdw/msm_sdw_cdc_utils.c | 0 .../codecs/msm_sdw/msm_sdw_registers.h | 0 .../codecs/msm_sdw/msm_sdw_regmap.c | 0 {sound/soc => asoc}/codecs/msm_stub.c | 0 .../linux/mfd/wcd9xxx => asoc/codecs}/pdata.h | 2 +- .../soc => asoc}/codecs/sdm660_cdc/Makefile | 0 .../codecs/sdm660_cdc/msm-analog-cdc.c | 12 +- .../codecs/sdm660_cdc/msm-analog-cdc.h | 2 +- .../codecs/sdm660_cdc/msm-cdc-common.h | 0 .../codecs/sdm660_cdc/msm-digital-cdc.c | 8 +- .../codecs/sdm660_cdc/msm-digital-cdc.h | 0 .../codecs/sdm660_cdc/sdm660-cdc-irq.c | 0 .../codecs/sdm660_cdc/sdm660-cdc-irq.h | 0 .../codecs/sdm660_cdc/sdm660-cdc-registers.h | 0 .../codecs/sdm660_cdc/sdm660-regmap.c | 0 {sound/soc => asoc}/codecs/wcd-dsp-mgr.c | 0 {sound/soc => asoc}/codecs/wcd-dsp-utils.c | 0 {sound/soc => asoc}/codecs/wcd-dsp-utils.h | 0 {sound/soc => asoc}/codecs/wcd-mbhc-adc.c | 0 {sound/soc => asoc}/codecs/wcd-mbhc-adc.h | 0 {sound/soc => asoc}/codecs/wcd-mbhc-legacy.c | 0 {sound/soc => asoc}/codecs/wcd-mbhc-legacy.h | 0 {sound/soc => asoc}/codecs/wcd-mbhc-v2-api.h | 0 {sound/soc => asoc}/codecs/wcd-mbhc-v2.c | 2 +- {sound/soc => asoc}/codecs/wcd-mbhc-v2.h | 0 .../soc => asoc}/codecs/wcd-spi-registers.h | 0 {sound/soc => asoc}/codecs/wcd-spi.c | 0 {drivers/mfd => asoc/codecs}/wcd9335-regmap.c | 4 +- {drivers/mfd => asoc/codecs}/wcd9335-tables.c | 2 +- {sound/soc => asoc}/codecs/wcd9335.c | 14 +- {sound/soc => asoc}/codecs/wcd9335.h | 4 +- .../irq.h => asoc/codecs/wcd9335_irq.h | 0 .../codecs/wcd9335_registers.h | 0 {sound/soc => asoc}/codecs/wcd934x/Makefile | 3 +- .../soc => asoc}/codecs/wcd934x/wcd934x-dsd.c | 2 +- .../soc => asoc}/codecs/wcd934x/wcd934x-dsd.h | 0 .../codecs/wcd934x/wcd934x-dsp-cntl.c | 6 +- .../codecs/wcd934x/wcd934x-dsp-cntl.h | 0 .../codecs/wcd934x/wcd934x-mbhc.c | 10 +- .../codecs/wcd934x/wcd934x-mbhc.h | 0 .../codecs/wcd934x}/wcd934x-regmap.c | 6 +- .../codecs/wcd934x/wcd934x-routing.h | 0 .../codecs/wcd934x}/wcd934x-tables.c | 2 +- {sound/soc => asoc}/codecs/wcd934x/wcd934x.c | 14 +- {sound/soc => asoc}/codecs/wcd934x/wcd934x.h | 4 +- .../codecs/wcd934x/wcd934x_irq.h | 0 .../soc => asoc}/codecs/wcd9xxx-common-v2.c | 2 +- .../soc => asoc}/codecs/wcd9xxx-common-v2.h | 0 .../mfd => asoc/codecs}/wcd9xxx-core-init.c | 6 +- {drivers/mfd => asoc/codecs}/wcd9xxx-core.c | 16 +- {drivers/mfd => asoc/codecs}/wcd9xxx-irq.c | 6 +- .../mfd/wcd9xxx => asoc/codecs}/wcd9xxx-irq.h | 2 +- {drivers/mfd => asoc/codecs}/wcd9xxx-regmap.h | 2 +- .../soc => asoc}/codecs/wcd9xxx-resmgr-v2.c | 6 +- .../soc => asoc}/codecs/wcd9xxx-resmgr-v2.h | 2 +- {drivers/mfd => asoc/codecs}/wcd9xxx-rst.c | 14 +- .../mfd => asoc/codecs}/wcd9xxx-slimslave.c | 2 +- .../codecs}/wcd9xxx-slimslave.h | 8 +- {sound/soc => asoc}/codecs/wcd9xxx-soc-init.c | 0 {drivers/mfd => asoc/codecs}/wcd9xxx-utils.c | 12 +- .../wcd9xxx => asoc/codecs}/wcd9xxx-utils.h | 4 +- {sound/soc => asoc}/codecs/wcd_cmi_api.h | 0 {sound/soc => asoc}/codecs/wcd_cpe_core.c | 10 +- {sound/soc => asoc}/codecs/wcd_cpe_core.h | 0 {sound/soc => asoc}/codecs/wcd_cpe_services.c | 5 +- {sound/soc => asoc}/codecs/wcd_cpe_services.h | 0 {sound/soc => asoc}/codecs/wcdcal-hwdep.c | 0 {sound/soc => asoc}/codecs/wcdcal-hwdep.h | 0 {sound/soc => asoc}/codecs/wsa881x-analog.c | 0 {sound/soc => asoc}/codecs/wsa881x-analog.h | 0 {sound/soc => asoc}/codecs/wsa881x-irq.c | 0 {sound/soc => asoc}/codecs/wsa881x-irq.h | 0 .../codecs/wsa881x-registers-analog.h | 0 .../soc => asoc}/codecs/wsa881x-registers.h | 0 .../codecs/wsa881x-regmap-analog.c | 0 {sound/soc => asoc}/codecs/wsa881x-regmap.c | 0 .../codecs/wsa881x-tables-analog.c | 0 {sound/soc => asoc}/codecs/wsa881x-tables.c | 0 .../soc => asoc}/codecs/wsa881x-temp-sensor.c | 0 .../soc => asoc}/codecs/wsa881x-temp-sensor.h | 0 {sound/soc => asoc}/codecs/wsa881x.c | 4 +- {sound/soc => asoc}/codecs/wsa881x.h | 0 {sound/soc/msm => asoc}/device_event.h | 0 .../msm-audio-effects-q6-v2.c | 6 +- {sound/soc/msm => asoc}/msm-audio-pinctrl.c | 0 {sound/soc/msm => asoc}/msm-audio-pinctrl.h | 0 .../msm/qdsp6v2 => asoc}/msm-compress-q6-v2.c | 11 +- {sound/soc/msm => asoc}/msm-cpe-lsm.c | 4 +- {sound/soc/msm => asoc}/msm-dai-fe.c | 0 .../msm/qdsp6v2 => asoc}/msm-dai-q6-hdmi-v2.c | 6 +- .../soc/msm/qdsp6v2 => asoc}/msm-dai-q6-v2.c | 8 +- {include/sound => asoc}/msm-dai-q6-v2.h | 0 .../soc/msm/qdsp6v2 => asoc}/msm-dai-slim.c | 2 +- .../msm/qdsp6v2 => asoc}/msm-dai-stub-v2.c | 0 .../msm/qdsp6v2 => asoc}/msm-dolby-common.h | 1 - .../qdsp6v2 => asoc}/msm-dolby-dap-config.h | 1 - .../msm/qdsp6v2 => asoc}/msm-ds2-dap-config.c | 4 +- .../msm/qdsp6v2 => asoc}/msm-ds2-dap-config.h | 1 - .../qdsp6v2 => asoc}/msm-dts-srs-tm-config.c | 8 +- .../soc/msm/qdsp6v2 => asoc}/msm-lsm-client.c | 4 +- .../soc/msm/qdsp6v2 => asoc}/msm-pcm-afe-v2.c | 4 +- .../soc/msm/qdsp6v2 => asoc}/msm-pcm-afe-v2.h | 4 +- .../msm/qdsp6v2 => asoc}/msm-pcm-dtmf-v2.c | 4 +- .../qdsp6v2 => asoc}/msm-pcm-host-voice-v2.c | 4 +- {sound/soc/msm => asoc}/msm-pcm-hostless.c | 0 .../qdsp6v2 => asoc}/msm-pcm-loopback-v2.c | 6 +- .../msm/qdsp6v2 => asoc}/msm-pcm-q6-noirq.c | 4 +- .../soc/msm/qdsp6v2 => asoc}/msm-pcm-q6-v2.c | 4 +- .../soc/msm/qdsp6v2 => asoc}/msm-pcm-q6-v2.h | 4 +- .../qdsp6v2 => asoc}/msm-pcm-routing-devdep.c | 0 .../qdsp6v2 => asoc}/msm-pcm-routing-devdep.h | 0 .../msm/qdsp6v2 => asoc}/msm-pcm-routing-v2.c | 18 +- .../msm/qdsp6v2 => asoc}/msm-pcm-routing-v2.h | 2 +- .../msm/qdsp6v2 => asoc}/msm-pcm-voice-v2.c | 2 +- .../msm/qdsp6v2 => asoc}/msm-pcm-voice-v2.h | 2 +- .../msm/qdsp6v2 => asoc}/msm-pcm-voip-v2.c | 2 +- .../msm/qdsp6v2 => asoc}/msm-qti-pp-config.c | 8 +- .../msm/qdsp6v2 => asoc}/msm-qti-pp-config.h | 1 - {include/sound => asoc}/msm-slim-dma.h | 0 .../msm-transcode-loopback-q6-v2.c | 7 +- {sound/soc/msm => asoc}/msm8996.c | 0 {sound/soc/msm => asoc}/msm8998.c | 18 +- {sound/soc/msm => asoc}/sdm660-common.c | 10 +- {sound/soc/msm => asoc}/sdm660-common.h | 4 +- .../soc/msm => asoc}/sdm660-ext-dai-links.c | 4 +- {sound/soc/msm => asoc}/sdm660-external.c | 12 +- {sound/soc/msm => asoc}/sdm660-external.h | 0 {sound/soc/msm => asoc}/sdm660-internal.c | 10 +- {sound/soc/msm => asoc}/sdm660-internal.h | 0 {sound/soc/msm => asoc}/sdm845.c | 16 +- drivers/Makefile | 7 - drivers/base/Makefile | 2 - drivers/base/regmap/Makefile | 2 - drivers/base/regmap/internal.h | 1 - drivers/mfd/Makefile | 8 - drivers/misc/Makefile | 5 - drivers/misc/qcom/Kconfig | 19 - drivers/misc/qcom/Makefile | 1 - drivers/misc/qcom/qdsp6v2/ultrasound/Makefile | 2 - drivers/pinctrl/Makefile | 2 - drivers/pinctrl/core.h | 1 - drivers/pinctrl/pinctrl-utils.h | 1 - drivers/pinctrl/qcom/Makefile | 3 - drivers/soc/Makefile | 5 - drivers/soc/qcom/Makefile | 1 - drivers/soc/qcom/qdsp6v2/Makefile | 8 - drivers/soundwire/Kconfig | 17 - drivers/soundwire/Makefile | 5 - dsp/Makefile | 10 + .../soc/qcom/qdsp6v2 => dsp}/adsp-loader.c | 2 +- {sound/soc/msm/qdsp6v2 => dsp}/adsp_err.c | 2 +- .../qdsp6v2/dsp_debug.h => dsp/adsp_err.h | 17 +- .../soc/msm/qdsp6v2 => dsp}/audio_cal_utils.c | 2 +- .../msm/qdsp6v2 => dsp}/audio_calibration.c | 6 +- .../soc/qcom/qdsp6v2 => dsp}/audio_notifier.c | 6 +- {drivers/soc/qcom/qdsp6v2 => dsp}/audio_pdr.c | 2 +- {include/linux/qdsp6v2 => dsp}/audio_pdr.h | 0 .../soc/msm/qdsp6v2 => dsp}/audio_slimslave.c | 0 {drivers/soc/qcom/qdsp6v2 => dsp}/audio_ssr.c | 2 +- {include/linux/qdsp6v2 => dsp}/audio_ssr.h | 0 .../soc/qcom/qdsp6v2 => dsp}/cdsp-loader.c | 0 .../misc/qcom/qdsp6v2 => dsp/codecs}/Makefile | 1 - .../misc/qcom/qdsp6v2 => dsp/codecs}/aac_in.c | 0 .../qcom/qdsp6v2 => dsp/codecs}/amrnb_in.c | 0 .../qcom/qdsp6v2 => dsp/codecs}/amrwb_in.c | 0 .../qcom/qdsp6v2 => dsp/codecs}/audio_aac.c | 0 .../qcom/qdsp6v2 => dsp/codecs}/audio_alac.c | 0 .../qcom/qdsp6v2 => dsp/codecs}/audio_amrnb.c | 0 .../qcom/qdsp6v2 => dsp/codecs}/audio_amrwb.c | 0 .../qdsp6v2 => dsp/codecs}/audio_amrwbplus.c | 0 .../qcom/qdsp6v2 => dsp/codecs}/audio_ape.c | 0 .../qcom/qdsp6v2 => dsp/codecs}/audio_evrc.c | 0 .../qdsp6v2 => dsp/codecs}/audio_g711alaw.c | 0 .../qdsp6v2 => dsp/codecs}/audio_g711mlaw.c | 0 .../codecs}/audio_hwacc_effects.c | 2 +- .../qcom/qdsp6v2 => dsp/codecs}/audio_mp3.c | 0 .../qdsp6v2 => dsp/codecs}/audio_multi_aac.c | 0 .../qcom/qdsp6v2 => dsp/codecs}/audio_qcelp.c | 0 .../qcom/qdsp6v2 => dsp/codecs}/audio_utils.c | 0 .../qcom/qdsp6v2 => dsp/codecs}/audio_utils.h | 0 .../qdsp6v2 => dsp/codecs}/audio_utils_aio.c | 2 +- .../qdsp6v2 => dsp/codecs}/audio_utils_aio.h | 0 .../qcom/qdsp6v2 => dsp/codecs}/audio_wma.c | 0 .../qdsp6v2 => dsp/codecs}/audio_wmapro.c | 0 .../qcom/qdsp6v2 => dsp/codecs}/evrc_in.c | 0 .../qcom/qdsp6v2 => dsp/codecs}/g711alaw_in.c | 0 .../qcom/qdsp6v2 => dsp/codecs}/g711mlaw_in.c | 0 .../qdsp6v2 => dsp/codecs}/q6audio_common.h | 4 +- .../qcom/qdsp6v2 => dsp/codecs}/q6audio_v2.c | 0 .../qdsp6v2 => dsp/codecs}/q6audio_v2_aio.c | 0 .../qcom/qdsp6v2 => dsp/codecs}/qcelp_in.c | 0 .../soc/qcom/qdsp6v2 => dsp}/msm_audio_ion.c | 4 +- {sound/soc/msm/qdsp6v2 => dsp}/q6adm.c | 16 +- {sound/soc/msm/qdsp6v2 => dsp}/q6afe.c | 15 +- {sound/soc/msm/qdsp6v2 => dsp}/q6asm.c | 14 +- {sound/soc/msm/qdsp6v2 => dsp}/q6audio-v2.c | 4 +- {sound/soc/msm/qdsp6v2 => dsp}/q6core.c | 6 +- {sound/soc/msm/qdsp6v2 => dsp}/q6lsm.c | 14 +- .../qcom/qdsp6v2/ultrasound => dsp}/q6usm.c | 7 +- .../qcom/qdsp6v2/ultrasound => dsp}/q6usm.h | 2 +- {sound/soc/msm/qdsp6v2 => dsp}/q6voice.c | 18 +- {sound/soc/msm/qdsp6v2 => dsp}/rtac.c | 17 +- .../qcom/qdsp6v2/ultrasound => dsp}/usf.c | 4 +- {include/linux/qdsp6v2 => dsp}/usf.h | 0 .../qcom/qdsp6v2/ultrasound => dsp}/usfcdev.c | 0 .../qcom/qdsp6v2/ultrasound => dsp}/usfcdev.h | 0 .../asoc}/msm-dts-srs-tm-config.h | 2 +- .../registers.h => asoc/wcd934x_registers.h} | 0 include/{sound => dsp}/apr_audio-v2.h | 2 +- include/{sound => dsp}/audio_cal_utils.h | 4 +- include/{sound => dsp}/audio_calibration.h | 0 .../{linux/qdsp6v2 => dsp}/audio_notifier.h | 0 .../{sound => dsp}/msm-audio-effects-q6-v2.h | 0 include/dsp/msm_audio_ion.h | 45 + include/{sound => dsp}/q6adm-v2.h | 6 +- include/{sound => dsp}/q6afe-v2.h | 4 +- include/{sound => dsp}/q6asm-v2.h | 6 +- include/{sound => dsp}/q6audio-v2.h | 2 +- include/{sound => dsp}/q6core.h | 2 +- include/{sound => dsp}/q6lsm.h | 4 +- .../soc/msm/qdsp6v2 => include/dsp}/q6voice.h | 4 +- include/{linux/qdsp6v2 => dsp}/rtac.h | 3 +- include/{linux/qdsp6v2 => ipc}/apr.h | 0 include/{linux/qdsp6v2 => ipc}/apr_tal.h | 0 include/{linux/qdsp6v2 => ipc}/apr_us.h | 2 +- include/linux/avtimer_kernel.h | 24 - include/soc/internal.h | 1 + include/{linux/soundwire => soc}/soundwire.h | 0 include/{linux/soundwire => soc}/swr-wcd.h | 0 include/sound/apr_audio.h | 1931 ----------------- ipc/Makefile | 2 + {drivers/soc/qcom/qdsp6v2 => ipc}/apr.c | 11 +- .../soc/qcom/qdsp6v2 => ipc}/apr_tal_glink.c | 2 +- {drivers/soc/qcom/qdsp6v2 => ipc}/apr_v2.c | 7 +- {drivers/soc/qcom/qdsp6v2 => ipc}/apr_v3.c | 7 +- soc/Makefile | 6 + soc/core.h | 1 + {drivers/pinctrl/qcom => soc}/pinctrl-lpi.c | 6 +- soc/pinctrl-utils.h | 1 + {drivers/pinctrl/qcom => soc}/pinctrl-wcd.c | 6 +- {drivers/base/regmap => soc}/regmap-swr.c | 4 +- {drivers/soundwire => soc}/soundwire.c | 2 +- {drivers/soundwire => soc}/swr-wcd-ctrl.c | 4 +- {drivers/soundwire => soc}/swr-wcd-ctrl.h | 2 +- {drivers/soundwire => soc}/swrm_registers.h | 0 sound/Makefile | 4 - sound/soc/codecs/msm_sdw/Kconfig | 6 - sound/soc/codecs/sdm660_cdc/Kconfig | 5 - sound/soc/msm/Kconfig | 283 --- sound/soc/msm/qdsp6v2/Makefile | 19 - 269 files changed, 424 insertions(+), 2707 deletions(-) rename {sound/soc/msm => asoc}/Makefile (61%) rename {sound/soc => asoc}/codecs/Makefile (80%) rename {sound/soc => asoc}/codecs/audio-ext-clk-up.c (99%) rename {sound/soc => asoc}/codecs/audio-ext-clk-up.h (100%) rename {sound/soc => asoc}/codecs/audio-ext-clk.c (100%) rename {include/linux/mfd/wcd9xxx => asoc/codecs}/core.h (100%) rename {include/sound => asoc/codecs}/cpe_cmi.h (100%) rename {include/sound => asoc/codecs}/cpe_core.h (100%) rename {include/sound => asoc/codecs}/cpe_err.h (100%) rename {drivers/mfd => asoc/codecs}/msm-cdc-pinctrl.c (99%) rename {include/linux/mfd => asoc/codecs}/msm-cdc-pinctrl.h (100%) rename {drivers/mfd => asoc/codecs}/msm-cdc-supply.c (99%) rename {include/linux/mfd => asoc/codecs}/msm-cdc-supply.h (100%) rename {sound/soc => asoc}/codecs/msm_hdmi_codec_rx.c (100%) rename {sound/soc => asoc}/codecs/msm_sdw/Makefile (100%) rename {sound/soc => asoc}/codecs/msm_sdw/msm-sdw-tables.c (100%) rename {sound/soc => asoc}/codecs/msm_sdw/msm_sdw.h (100%) rename {sound/soc => asoc}/codecs/msm_sdw/msm_sdw_cdc.c (100%) rename {sound/soc => asoc}/codecs/msm_sdw/msm_sdw_cdc_utils.c (100%) rename {sound/soc => asoc}/codecs/msm_sdw/msm_sdw_registers.h (100%) rename {sound/soc => asoc}/codecs/msm_sdw/msm_sdw_regmap.c (100%) rename {sound/soc => asoc}/codecs/msm_stub.c (100%) rename {include/linux/mfd/wcd9xxx => asoc/codecs}/pdata.h (99%) rename {sound/soc => asoc}/codecs/sdm660_cdc/Makefile (100%) rename {sound/soc => asoc}/codecs/sdm660_cdc/msm-analog-cdc.c (99%) rename {sound/soc => asoc}/codecs/sdm660_cdc/msm-analog-cdc.h (99%) rename {sound/soc => asoc}/codecs/sdm660_cdc/msm-cdc-common.h (100%) rename {sound/soc => asoc}/codecs/sdm660_cdc/msm-digital-cdc.c (99%) rename {sound/soc => asoc}/codecs/sdm660_cdc/msm-digital-cdc.h (100%) rename {sound/soc => asoc}/codecs/sdm660_cdc/sdm660-cdc-irq.c (100%) rename {sound/soc => asoc}/codecs/sdm660_cdc/sdm660-cdc-irq.h (100%) rename {sound/soc => asoc}/codecs/sdm660_cdc/sdm660-cdc-registers.h (100%) rename {sound/soc => asoc}/codecs/sdm660_cdc/sdm660-regmap.c (100%) rename {sound/soc => asoc}/codecs/wcd-dsp-mgr.c (100%) rename {sound/soc => asoc}/codecs/wcd-dsp-utils.c (100%) rename {sound/soc => asoc}/codecs/wcd-dsp-utils.h (100%) rename {sound/soc => asoc}/codecs/wcd-mbhc-adc.c (100%) rename {sound/soc => asoc}/codecs/wcd-mbhc-adc.h (100%) rename {sound/soc => asoc}/codecs/wcd-mbhc-legacy.c (100%) rename {sound/soc => asoc}/codecs/wcd-mbhc-legacy.h (100%) rename {sound/soc => asoc}/codecs/wcd-mbhc-v2-api.h (100%) rename {sound/soc => asoc}/codecs/wcd-mbhc-v2.c (99%) rename {sound/soc => asoc}/codecs/wcd-mbhc-v2.h (100%) rename {sound/soc => asoc}/codecs/wcd-spi-registers.h (100%) rename {sound/soc => asoc}/codecs/wcd-spi.c (100%) rename {drivers/mfd => asoc/codecs}/wcd9335-regmap.c (99%) rename {drivers/mfd => asoc/codecs}/wcd9335-tables.c (99%) rename {sound/soc => asoc}/codecs/wcd9335.c (99%) rename {sound/soc => asoc}/codecs/wcd9335.h (98%) rename include/linux/mfd/wcd9335/irq.h => asoc/codecs/wcd9335_irq.h (100%) rename include/linux/mfd/wcd9335/registers.h => asoc/codecs/wcd9335_registers.h (100%) rename {sound/soc => asoc}/codecs/wcd934x/Makefile (67%) rename {sound/soc => asoc}/codecs/wcd934x/wcd934x-dsd.c (99%) rename {sound/soc => asoc}/codecs/wcd934x/wcd934x-dsd.h (100%) rename {sound/soc => asoc}/codecs/wcd934x/wcd934x-dsp-cntl.c (99%) rename {sound/soc => asoc}/codecs/wcd934x/wcd934x-dsp-cntl.h (100%) rename {sound/soc => asoc}/codecs/wcd934x/wcd934x-mbhc.c (99%) rename {sound/soc => asoc}/codecs/wcd934x/wcd934x-mbhc.h (100%) rename {drivers/mfd => asoc/codecs/wcd934x}/wcd934x-regmap.c (99%) rename {sound/soc => asoc}/codecs/wcd934x/wcd934x-routing.h (100%) rename {drivers/mfd => asoc/codecs/wcd934x}/wcd934x-tables.c (99%) rename {sound/soc => asoc}/codecs/wcd934x/wcd934x.c (99%) rename {sound/soc => asoc}/codecs/wcd934x/wcd934x.h (98%) rename include/linux/mfd/wcd934x/irq.h => asoc/codecs/wcd934x/wcd934x_irq.h (100%) rename {sound/soc => asoc}/codecs/wcd9xxx-common-v2.c (99%) rename {sound/soc => asoc}/codecs/wcd9xxx-common-v2.h (100%) rename {drivers/mfd => asoc/codecs}/wcd9xxx-core-init.c (92%) rename {drivers/mfd => asoc/codecs}/wcd9xxx-core.c (99%) rename {drivers/mfd => asoc/codecs}/wcd9xxx-irq.c (99%) rename {include/linux/mfd/wcd9xxx => asoc/codecs}/wcd9xxx-irq.h (97%) rename {drivers/mfd => asoc/codecs}/wcd9xxx-regmap.h (97%) rename {sound/soc => asoc}/codecs/wcd9xxx-resmgr-v2.c (99%) rename {sound/soc => asoc}/codecs/wcd9xxx-resmgr-v2.h (98%) rename {drivers/mfd => asoc/codecs}/wcd9xxx-rst.c (97%) rename {drivers/mfd => asoc/codecs}/wcd9xxx-slimslave.c (99%) rename {include/linux/mfd/wcd9xxx => asoc/codecs}/wcd9xxx-slimslave.h (96%) rename {sound/soc => asoc}/codecs/wcd9xxx-soc-init.c (100%) rename {drivers/mfd => asoc/codecs}/wcd9xxx-utils.c (99%) rename {include/linux/mfd/wcd9xxx => asoc/codecs}/wcd9xxx-utils.h (95%) rename {sound/soc => asoc}/codecs/wcd_cmi_api.h (100%) rename {sound/soc => asoc}/codecs/wcd_cpe_core.c (99%) rename {sound/soc => asoc}/codecs/wcd_cpe_core.h (100%) rename {sound/soc => asoc}/codecs/wcd_cpe_services.c (99%) rename {sound/soc => asoc}/codecs/wcd_cpe_services.h (100%) rename {sound/soc => asoc}/codecs/wcdcal-hwdep.c (100%) rename {sound/soc => asoc}/codecs/wcdcal-hwdep.h (100%) rename {sound/soc => asoc}/codecs/wsa881x-analog.c (100%) rename {sound/soc => asoc}/codecs/wsa881x-analog.h (100%) rename {sound/soc => asoc}/codecs/wsa881x-irq.c (100%) rename {sound/soc => asoc}/codecs/wsa881x-irq.h (100%) rename {sound/soc => asoc}/codecs/wsa881x-registers-analog.h (100%) rename {sound/soc => asoc}/codecs/wsa881x-registers.h (100%) rename {sound/soc => asoc}/codecs/wsa881x-regmap-analog.c (100%) rename {sound/soc => asoc}/codecs/wsa881x-regmap.c (100%) rename {sound/soc => asoc}/codecs/wsa881x-tables-analog.c (100%) rename {sound/soc => asoc}/codecs/wsa881x-tables.c (100%) rename {sound/soc => asoc}/codecs/wsa881x-temp-sensor.c (100%) rename {sound/soc => asoc}/codecs/wsa881x-temp-sensor.h (100%) rename {sound/soc => asoc}/codecs/wsa881x.c (99%) rename {sound/soc => asoc}/codecs/wsa881x.h (100%) rename {sound/soc/msm => asoc}/device_event.h (100%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-audio-effects-q6-v2.c (99%) rename {sound/soc/msm => asoc}/msm-audio-pinctrl.c (100%) rename {sound/soc/msm => asoc}/msm-audio-pinctrl.h (100%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-compress-q6-v2.c (99%) rename {sound/soc/msm => asoc}/msm-cpe-lsm.c (99%) rename {sound/soc/msm => asoc}/msm-dai-fe.c (100%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-dai-q6-hdmi-v2.c (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-dai-q6-v2.c (99%) rename {include/sound => asoc}/msm-dai-q6-v2.h (100%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-dai-slim.c (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-dai-stub-v2.c (100%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-dolby-common.h (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-dolby-dap-config.h (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-ds2-dap-config.c (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-ds2-dap-config.h (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-dts-srs-tm-config.c (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-lsm-client.c (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-pcm-afe-v2.c (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-pcm-afe-v2.h (95%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-pcm-dtmf-v2.c (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-pcm-host-voice-v2.c (99%) rename {sound/soc/msm => asoc}/msm-pcm-hostless.c (100%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-pcm-loopback-v2.c (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-pcm-q6-noirq.c (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-pcm-q6-v2.c (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-pcm-q6-v2.h (98%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-pcm-routing-devdep.c (100%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-pcm-routing-devdep.h (100%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-pcm-routing-v2.c (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-pcm-routing-v2.h (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-pcm-voice-v2.c (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-pcm-voice-v2.h (97%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-pcm-voip-v2.c (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-qti-pp-config.c (99%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-qti-pp-config.h (99%) rename {include/sound => asoc}/msm-slim-dma.h (100%) rename {sound/soc/msm/qdsp6v2 => asoc}/msm-transcode-loopback-q6-v2.c (99%) rename {sound/soc/msm => asoc}/msm8996.c (100%) rename {sound/soc/msm => asoc}/msm8998.c (99%) rename {sound/soc/msm => asoc}/sdm660-common.c (99%) rename {sound/soc/msm => asoc}/sdm660-common.h (98%) rename {sound/soc/msm => asoc}/sdm660-ext-dai-links.c (99%) rename {sound/soc/msm => asoc}/sdm660-external.c (99%) rename {sound/soc/msm => asoc}/sdm660-external.h (100%) rename {sound/soc/msm => asoc}/sdm660-internal.c (99%) rename {sound/soc/msm => asoc}/sdm660-internal.h (100%) rename {sound/soc/msm => asoc}/sdm845.c (99%) delete mode 100644 drivers/Makefile delete mode 100644 drivers/base/Makefile delete mode 100644 drivers/base/regmap/Makefile delete mode 120000 drivers/base/regmap/internal.h delete mode 100644 drivers/mfd/Makefile delete mode 100644 drivers/misc/Makefile delete mode 100644 drivers/misc/qcom/Kconfig delete mode 100644 drivers/misc/qcom/Makefile delete mode 100644 drivers/misc/qcom/qdsp6v2/ultrasound/Makefile delete mode 100644 drivers/pinctrl/Makefile delete mode 120000 drivers/pinctrl/core.h delete mode 120000 drivers/pinctrl/pinctrl-utils.h delete mode 100644 drivers/pinctrl/qcom/Makefile delete mode 100644 drivers/soc/Makefile delete mode 100644 drivers/soc/qcom/Makefile delete mode 100644 drivers/soc/qcom/qdsp6v2/Makefile delete mode 100644 drivers/soundwire/Kconfig delete mode 100644 drivers/soundwire/Makefile create mode 100644 dsp/Makefile rename {drivers/soc/qcom/qdsp6v2 => dsp}/adsp-loader.c (99%) rename {sound/soc/msm/qdsp6v2 => dsp}/adsp_err.c (99%) rename include/linux/qdsp6v2/dsp_debug.h => dsp/adsp_err.h (54%) rename {sound/soc/msm/qdsp6v2 => dsp}/audio_cal_utils.c (99%) rename {sound/soc/msm/qdsp6v2 => dsp}/audio_calibration.c (99%) rename {drivers/soc/qcom/qdsp6v2 => dsp}/audio_notifier.c (99%) rename {drivers/soc/qcom/qdsp6v2 => dsp}/audio_pdr.c (99%) rename {include/linux/qdsp6v2 => dsp}/audio_pdr.h (100%) rename {sound/soc/msm/qdsp6v2 => dsp}/audio_slimslave.c (100%) rename {drivers/soc/qcom/qdsp6v2 => dsp}/audio_ssr.c (98%) rename {include/linux/qdsp6v2 => dsp}/audio_ssr.h (100%) rename {drivers/soc/qcom/qdsp6v2 => dsp}/cdsp-loader.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/Makefile (92%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/aac_in.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/amrnb_in.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/amrwb_in.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_aac.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_alac.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_amrnb.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_amrwb.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_amrwbplus.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_ape.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_evrc.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_g711alaw.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_g711mlaw.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_hwacc_effects.c (99%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_mp3.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_multi_aac.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_qcelp.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_utils.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_utils.h (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_utils_aio.c (99%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_utils_aio.h (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_wma.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/audio_wmapro.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/evrc_in.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/g711alaw_in.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/g711mlaw_in.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/q6audio_common.h (94%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/q6audio_v2.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/q6audio_v2_aio.c (100%) rename {drivers/misc/qcom/qdsp6v2 => dsp/codecs}/qcelp_in.c (100%) rename {drivers/soc/qcom/qdsp6v2 => dsp}/msm_audio_ion.c (99%) rename {sound/soc/msm/qdsp6v2 => dsp}/q6adm.c (99%) rename {sound/soc/msm/qdsp6v2 => dsp}/q6afe.c (99%) rename {sound/soc/msm/qdsp6v2 => dsp}/q6asm.c (99%) rename {sound/soc/msm/qdsp6v2 => dsp}/q6audio-v2.c (99%) rename {sound/soc/msm/qdsp6v2 => dsp}/q6core.c (99%) rename {sound/soc/msm/qdsp6v2 => dsp}/q6lsm.c (99%) rename {drivers/misc/qcom/qdsp6v2/ultrasound => dsp}/q6usm.c (99%) rename {drivers/misc/qcom/qdsp6v2/ultrasound => dsp}/q6usm.h (99%) rename {sound/soc/msm/qdsp6v2 => dsp}/q6voice.c (99%) rename {sound/soc/msm/qdsp6v2 => dsp}/rtac.c (99%) rename {drivers/misc/qcom/qdsp6v2/ultrasound => dsp}/usf.c (99%) rename {include/linux/qdsp6v2 => dsp}/usf.h (100%) rename {drivers/misc/qcom/qdsp6v2/ultrasound => dsp}/usfcdev.c (100%) rename {drivers/misc/qcom/qdsp6v2/ultrasound => dsp}/usfcdev.h (100%) rename {sound/soc/msm/qdsp6v2 => include/asoc}/msm-dts-srs-tm-config.h (97%) rename include/{linux/mfd/wcd934x/registers.h => asoc/wcd934x_registers.h} (100%) rename include/{sound => dsp}/apr_audio-v2.h (99%) rename include/{sound => dsp}/audio_cal_utils.h (97%) rename include/{sound => dsp}/audio_calibration.h (100%) rename include/{linux/qdsp6v2 => dsp}/audio_notifier.h (100%) rename include/{sound => dsp}/msm-audio-effects-q6-v2.h (100%) create mode 100644 include/dsp/msm_audio_ion.h rename include/{sound => dsp}/q6adm-v2.h (98%) rename include/{sound => dsp}/q6afe-v2.h (99%) rename include/{sound => dsp}/q6asm-v2.h (99%) rename include/{sound => dsp}/q6audio-v2.h (96%) rename include/{sound => dsp}/q6core.h (99%) rename include/{sound => dsp}/q6lsm.h (99%) rename {sound/soc/msm/qdsp6v2 => include/dsp}/q6voice.h (99%) rename include/{linux/qdsp6v2 => dsp}/rtac.h (98%) rename include/{linux/qdsp6v2 => ipc}/apr.h (100%) rename include/{linux/qdsp6v2 => ipc}/apr_tal.h (100%) rename include/{linux/qdsp6v2 => ipc}/apr_us.h (99%) delete mode 100644 include/linux/avtimer_kernel.h create mode 120000 include/soc/internal.h rename include/{linux/soundwire => soc}/soundwire.h (100%) rename include/{linux/soundwire => soc}/swr-wcd.h (100%) delete mode 100644 include/sound/apr_audio.h create mode 100644 ipc/Makefile rename {drivers/soc/qcom/qdsp6v2 => ipc}/apr.c (99%) rename {drivers/soc/qcom/qdsp6v2 => ipc}/apr_tal_glink.c (99%) rename {drivers/soc/qcom/qdsp6v2 => ipc}/apr_v2.c (91%) rename {drivers/soc/qcom/qdsp6v2 => ipc}/apr_v3.c (90%) create mode 100644 soc/Makefile create mode 120000 soc/core.h rename {drivers/pinctrl/qcom => soc}/pinctrl-lpi.c (99%) create mode 120000 soc/pinctrl-utils.h rename {drivers/pinctrl/qcom => soc}/pinctrl-wcd.c (99%) rename {drivers/base/regmap => soc}/regmap-swr.c (98%) rename {drivers/soundwire => soc}/soundwire.c (99%) rename {drivers/soundwire => soc}/swr-wcd-ctrl.c (99%) rename {drivers/soundwire => soc}/swr-wcd-ctrl.h (98%) rename {drivers/soundwire => soc}/swrm_registers.h (100%) delete mode 100644 sound/Makefile delete mode 100644 sound/soc/codecs/msm_sdw/Kconfig delete mode 100644 sound/soc/codecs/sdm660_cdc/Kconfig delete mode 100644 sound/soc/msm/Kconfig delete mode 100644 sound/soc/msm/qdsp6v2/Makefile diff --git a/Makefile b/Makefile index b8428deb5c05..05b04c637301 100644 --- a/Makefile +++ b/Makefile @@ -19,5 +19,7 @@ LINUXINCLUDE += \ -include $(srctree)/techpack/audio/config/sdm845autoconf.h endif -obj-y += drivers/ -obj-y += sound/ +obj-y += asoc/ +obj-y += dsp/ +obj-y += ipc/ +obj-y += soc/ diff --git a/sound/soc/msm/Makefile b/asoc/Makefile similarity index 61% rename from sound/soc/msm/Makefile rename to asoc/Makefile index caf884322d9e..67cb9f3aac6b 100644 --- a/sound/soc/msm/Makefile +++ b/asoc/Makefile @@ -3,7 +3,6 @@ snd-soc-hostless-pcm-objs := msm-pcm-hostless.o obj-$(CONFIG_SND_SOC_MSM_HOSTLESS_PCM) += snd-soc-hostless-pcm.o -obj-$(CONFIG_SND_SOC_MSM_QDSP6V2_INTF) += qdsp6v2/ snd-soc-qdsp6v2-objs := msm-dai-fe.o obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o @@ -37,3 +36,20 @@ obj-$(CONFIG_SND_SOC_EXT_CODEC) += snd-soc-ext-codec.o # for SDM845 sound card driver snd-soc-sdm845-objs := sdm845.o obj-$(CONFIG_SND_SOC_MACHINE_SDM845) += snd-soc-sdm845.o + +snd-soc-qdsp6v2-objs += msm-dai-q6-v2.o msm-pcm-q6-v2.o \ + msm-pcm-routing-v2.o msm-compress-q6-v2.o \ + msm-pcm-afe-v2.o msm-pcm-voip-v2.o \ + msm-pcm-voice-v2.o msm-dai-q6-hdmi-v2.o \ + msm-lsm-client.o msm-pcm-host-voice-v2.o \ + msm-audio-effects-q6-v2.o msm-pcm-loopback-v2.o \ + msm-dai-slim.o msm-transcode-loopback-q6-v2.o msm-pcm-q6-noirq.o +obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o msm-pcm-dtmf-v2.o \ + msm-dai-stub-v2.o +obj-$(CONFIG_SND_HWDEP) += msm-pcm-routing-devdep.o +obj-$(CONFIG_DOLBY_DAP) += msm-dolby-dap-config.o +obj-$(CONFIG_DOLBY_DS2) += msm-ds2-dap-config.o +obj-$(CONFIG_DOLBY_LICENSE) += msm-ds2-dap-config.o +obj-$(CONFIG_DTS_SRS_TM) += msm-dts-srs-tm-config.o +obj-$(CONFIG_QTI_PP) += msm-qti-pp-config.o +obj-y += codecs/ diff --git a/sound/soc/codecs/Makefile b/asoc/codecs/Makefile similarity index 80% rename from sound/soc/codecs/Makefile rename to asoc/codecs/Makefile index 53256649cd4e..04218e8103e1 100644 --- a/sound/soc/codecs/Makefile +++ b/asoc/codecs/Makefile @@ -1,4 +1,3 @@ -snd-soc-wcd934x-objs := wcd934x.o snd-soc-wcd9xxx-v2-objs := wcd9xxx-common-v2.o wcd9xxx-resmgr-v2.o wcdcal-hwdep.o wcd9xxx-soc-init.o snd-soc-wcd-cpe-objs := wcd_cpe_services.o wcd_cpe_core.o snd-soc-wsa881x-objs := wsa881x.o wsa881x-tables.o wsa881x-regmap.o wsa881x-temp-sensor.o @@ -24,3 +23,10 @@ obj-$(CONFIG_SND_SOC_WCD_SPI) += snd-soc-wcd-spi.o snd-soc-msm-stub-objs := msm_stub.o obj-$(CONFIG_SND_SOC_MSM_STUB) += snd-soc-msm-stub.o + +wcd-core-objs := wcd9xxx-rst.o wcd9xxx-core-init.o \ + wcd9xxx-core.o wcd9xxx-irq.o \ + wcd9xxx-slimslave.o wcd9xxx-utils.o \ + wcd9335-regmap.o wcd9335-tables.o \ + msm-cdc-pinctrl.o msm-cdc-supply.o +obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd-core.o diff --git a/sound/soc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c similarity index 99% rename from sound/soc/codecs/audio-ext-clk-up.c rename to asoc/codecs/audio-ext-clk-up.c index 31c063d4b93e..50a8ed6fc014 100644 --- a/sound/soc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include "audio-ext-clk-up.h" enum audio_clk_mux { diff --git a/sound/soc/codecs/audio-ext-clk-up.h b/asoc/codecs/audio-ext-clk-up.h similarity index 100% rename from sound/soc/codecs/audio-ext-clk-up.h rename to asoc/codecs/audio-ext-clk-up.h diff --git a/sound/soc/codecs/audio-ext-clk.c b/asoc/codecs/audio-ext-clk.c similarity index 100% rename from sound/soc/codecs/audio-ext-clk.c rename to asoc/codecs/audio-ext-clk.c diff --git a/include/linux/mfd/wcd9xxx/core.h b/asoc/codecs/core.h similarity index 100% rename from include/linux/mfd/wcd9xxx/core.h rename to asoc/codecs/core.h diff --git a/include/sound/cpe_cmi.h b/asoc/codecs/cpe_cmi.h similarity index 100% rename from include/sound/cpe_cmi.h rename to asoc/codecs/cpe_cmi.h diff --git a/include/sound/cpe_core.h b/asoc/codecs/cpe_core.h similarity index 100% rename from include/sound/cpe_core.h rename to asoc/codecs/cpe_core.h diff --git a/include/sound/cpe_err.h b/asoc/codecs/cpe_err.h similarity index 100% rename from include/sound/cpe_err.h rename to asoc/codecs/cpe_err.h diff --git a/drivers/mfd/msm-cdc-pinctrl.c b/asoc/codecs/msm-cdc-pinctrl.c similarity index 99% rename from drivers/mfd/msm-cdc-pinctrl.c rename to asoc/codecs/msm-cdc-pinctrl.c index 859a75f93bb5..c4d0ec19931d 100644 --- a/drivers/mfd/msm-cdc-pinctrl.c +++ b/asoc/codecs/msm-cdc-pinctrl.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include "msm-cdc-pinctrl.h" struct msm_cdc_pinctrl_info { struct pinctrl *pinctrl; diff --git a/include/linux/mfd/msm-cdc-pinctrl.h b/asoc/codecs/msm-cdc-pinctrl.h similarity index 100% rename from include/linux/mfd/msm-cdc-pinctrl.h rename to asoc/codecs/msm-cdc-pinctrl.h diff --git a/drivers/mfd/msm-cdc-supply.c b/asoc/codecs/msm-cdc-supply.c similarity index 99% rename from drivers/mfd/msm-cdc-supply.c rename to asoc/codecs/msm-cdc-supply.c index 9c7ebf78a00e..e36baa82ac98 100644 --- a/drivers/mfd/msm-cdc-supply.c +++ b/asoc/codecs/msm-cdc-supply.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include "msm-cdc-supply.h" #include #define CODEC_DT_MAX_PROP_SIZE 40 diff --git a/include/linux/mfd/msm-cdc-supply.h b/asoc/codecs/msm-cdc-supply.h similarity index 100% rename from include/linux/mfd/msm-cdc-supply.h rename to asoc/codecs/msm-cdc-supply.h diff --git a/sound/soc/codecs/msm_hdmi_codec_rx.c b/asoc/codecs/msm_hdmi_codec_rx.c similarity index 100% rename from sound/soc/codecs/msm_hdmi_codec_rx.c rename to asoc/codecs/msm_hdmi_codec_rx.c diff --git a/sound/soc/codecs/msm_sdw/Makefile b/asoc/codecs/msm_sdw/Makefile similarity index 100% rename from sound/soc/codecs/msm_sdw/Makefile rename to asoc/codecs/msm_sdw/Makefile diff --git a/sound/soc/codecs/msm_sdw/msm-sdw-tables.c b/asoc/codecs/msm_sdw/msm-sdw-tables.c similarity index 100% rename from sound/soc/codecs/msm_sdw/msm-sdw-tables.c rename to asoc/codecs/msm_sdw/msm-sdw-tables.c diff --git a/sound/soc/codecs/msm_sdw/msm_sdw.h b/asoc/codecs/msm_sdw/msm_sdw.h similarity index 100% rename from sound/soc/codecs/msm_sdw/msm_sdw.h rename to asoc/codecs/msm_sdw/msm_sdw.h diff --git a/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c b/asoc/codecs/msm_sdw/msm_sdw_cdc.c similarity index 100% rename from sound/soc/codecs/msm_sdw/msm_sdw_cdc.c rename to asoc/codecs/msm_sdw/msm_sdw_cdc.c diff --git a/sound/soc/codecs/msm_sdw/msm_sdw_cdc_utils.c b/asoc/codecs/msm_sdw/msm_sdw_cdc_utils.c similarity index 100% rename from sound/soc/codecs/msm_sdw/msm_sdw_cdc_utils.c rename to asoc/codecs/msm_sdw/msm_sdw_cdc_utils.c diff --git a/sound/soc/codecs/msm_sdw/msm_sdw_registers.h b/asoc/codecs/msm_sdw/msm_sdw_registers.h similarity index 100% rename from sound/soc/codecs/msm_sdw/msm_sdw_registers.h rename to asoc/codecs/msm_sdw/msm_sdw_registers.h diff --git a/sound/soc/codecs/msm_sdw/msm_sdw_regmap.c b/asoc/codecs/msm_sdw/msm_sdw_regmap.c similarity index 100% rename from sound/soc/codecs/msm_sdw/msm_sdw_regmap.c rename to asoc/codecs/msm_sdw/msm_sdw_regmap.c diff --git a/sound/soc/codecs/msm_stub.c b/asoc/codecs/msm_stub.c similarity index 100% rename from sound/soc/codecs/msm_stub.c rename to asoc/codecs/msm_stub.c diff --git a/include/linux/mfd/wcd9xxx/pdata.h b/asoc/codecs/pdata.h similarity index 99% rename from include/linux/mfd/wcd9xxx/pdata.h rename to asoc/codecs/pdata.h index f188e850b800..fa16b3d1c8f5 100644 --- a/include/linux/mfd/wcd9xxx/pdata.h +++ b/asoc/codecs/pdata.h @@ -15,7 +15,7 @@ #define __MFD_WCD9XXX_PDATA_H__ #include -#include +#include "msm-cdc-supply.h" #define MICBIAS_EXT_BYP_CAP 0x00 #define MICBIAS_NO_EXT_BYP_CAP 0x01 diff --git a/sound/soc/codecs/sdm660_cdc/Makefile b/asoc/codecs/sdm660_cdc/Makefile similarity index 100% rename from sound/soc/codecs/sdm660_cdc/Makefile rename to asoc/codecs/sdm660_cdc/Makefile diff --git a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c similarity index 99% rename from sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c rename to asoc/codecs/sdm660_cdc/msm-analog-cdc.c index f126d35dee81..ddef508cb682 100644 --- a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c @@ -16,22 +16,22 @@ #include #include #include -#include #include #include -#include -#include #include #include #include #include #include -#include +#include +#include +#include +#include #include "msm-analog-cdc.h" +#include "msm-cdc-common.h" #include "sdm660-cdc-irq.h" #include "sdm660-cdc-registers.h" -#include "msm-cdc-common.h" -#include "../../msm/sdm660-common.h" +#include "../../sdm660-common.h" #include "../wcd-mbhc-v2-api.h" #define DRV_NAME "pmic_analog_codec" diff --git a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.h b/asoc/codecs/sdm660_cdc/msm-analog-cdc.h similarity index 99% rename from sound/soc/codecs/sdm660_cdc/msm-analog-cdc.h rename to asoc/codecs/sdm660_cdc/msm-analog-cdc.h index 9563565f36d2..fffdf3156255 100644 --- a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.h +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.h @@ -14,7 +14,7 @@ #include #include -#include +#include #include "../wcd-mbhc-v2.h" #include "../wcdcal-hwdep.h" #include "sdm660-cdc-registers.h" diff --git a/sound/soc/codecs/sdm660_cdc/msm-cdc-common.h b/asoc/codecs/sdm660_cdc/msm-cdc-common.h similarity index 100% rename from sound/soc/codecs/sdm660_cdc/msm-cdc-common.h rename to asoc/codecs/sdm660_cdc/msm-cdc-common.h diff --git a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c similarity index 99% rename from sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c rename to asoc/codecs/sdm660_cdc/msm-digital-cdc.c index 68a1d8d47b39..f59b653323c3 100644 --- a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -17,20 +17,20 @@ #include #include #include -#include #include #include -#include #include #include #include #include #include +#include +#include +#include #include "sdm660-cdc-registers.h" #include "msm-digital-cdc.h" #include "msm-cdc-common.h" -#include "../../msm/sdm660-common.h" -#include "../../../../drivers/base/regmap/internal.h" +#include "../../sdm660-common.h" #define DRV_NAME "msm_digital_codec" #define MCLK_RATE_9P6MHZ 9600000 diff --git a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.h b/asoc/codecs/sdm660_cdc/msm-digital-cdc.h similarity index 100% rename from sound/soc/codecs/sdm660_cdc/msm-digital-cdc.h rename to asoc/codecs/sdm660_cdc/msm-digital-cdc.h diff --git a/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.c b/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c similarity index 100% rename from sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.c rename to asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c diff --git a/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.h b/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h similarity index 100% rename from sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.h rename to asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h diff --git a/sound/soc/codecs/sdm660_cdc/sdm660-cdc-registers.h b/asoc/codecs/sdm660_cdc/sdm660-cdc-registers.h similarity index 100% rename from sound/soc/codecs/sdm660_cdc/sdm660-cdc-registers.h rename to asoc/codecs/sdm660_cdc/sdm660-cdc-registers.h diff --git a/sound/soc/codecs/sdm660_cdc/sdm660-regmap.c b/asoc/codecs/sdm660_cdc/sdm660-regmap.c similarity index 100% rename from sound/soc/codecs/sdm660_cdc/sdm660-regmap.c rename to asoc/codecs/sdm660_cdc/sdm660-regmap.c diff --git a/sound/soc/codecs/wcd-dsp-mgr.c b/asoc/codecs/wcd-dsp-mgr.c similarity index 100% rename from sound/soc/codecs/wcd-dsp-mgr.c rename to asoc/codecs/wcd-dsp-mgr.c diff --git a/sound/soc/codecs/wcd-dsp-utils.c b/asoc/codecs/wcd-dsp-utils.c similarity index 100% rename from sound/soc/codecs/wcd-dsp-utils.c rename to asoc/codecs/wcd-dsp-utils.c diff --git a/sound/soc/codecs/wcd-dsp-utils.h b/asoc/codecs/wcd-dsp-utils.h similarity index 100% rename from sound/soc/codecs/wcd-dsp-utils.h rename to asoc/codecs/wcd-dsp-utils.h diff --git a/sound/soc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c similarity index 100% rename from sound/soc/codecs/wcd-mbhc-adc.c rename to asoc/codecs/wcd-mbhc-adc.c diff --git a/sound/soc/codecs/wcd-mbhc-adc.h b/asoc/codecs/wcd-mbhc-adc.h similarity index 100% rename from sound/soc/codecs/wcd-mbhc-adc.h rename to asoc/codecs/wcd-mbhc-adc.h diff --git a/sound/soc/codecs/wcd-mbhc-legacy.c b/asoc/codecs/wcd-mbhc-legacy.c similarity index 100% rename from sound/soc/codecs/wcd-mbhc-legacy.c rename to asoc/codecs/wcd-mbhc-legacy.c diff --git a/sound/soc/codecs/wcd-mbhc-legacy.h b/asoc/codecs/wcd-mbhc-legacy.h similarity index 100% rename from sound/soc/codecs/wcd-mbhc-legacy.h rename to asoc/codecs/wcd-mbhc-legacy.h diff --git a/sound/soc/codecs/wcd-mbhc-v2-api.h b/asoc/codecs/wcd-mbhc-v2-api.h similarity index 100% rename from sound/soc/codecs/wcd-mbhc-v2-api.h rename to asoc/codecs/wcd-mbhc-v2-api.h diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c similarity index 99% rename from sound/soc/codecs/wcd-mbhc-v2.c rename to asoc/codecs/wcd-mbhc-v2.c index eb67de92871d..6b3dd8626da5 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -25,9 +25,9 @@ #include #include #include -#include #include #include +#include "msm-cdc-pinctrl.h" #include "wcdcal-hwdep.h" #include "wcd-mbhc-legacy.h" #include "wcd-mbhc-adc.h" diff --git a/sound/soc/codecs/wcd-mbhc-v2.h b/asoc/codecs/wcd-mbhc-v2.h similarity index 100% rename from sound/soc/codecs/wcd-mbhc-v2.h rename to asoc/codecs/wcd-mbhc-v2.h diff --git a/sound/soc/codecs/wcd-spi-registers.h b/asoc/codecs/wcd-spi-registers.h similarity index 100% rename from sound/soc/codecs/wcd-spi-registers.h rename to asoc/codecs/wcd-spi-registers.h diff --git a/sound/soc/codecs/wcd-spi.c b/asoc/codecs/wcd-spi.c similarity index 100% rename from sound/soc/codecs/wcd-spi.c rename to asoc/codecs/wcd-spi.c diff --git a/drivers/mfd/wcd9335-regmap.c b/asoc/codecs/wcd9335-regmap.c similarity index 99% rename from drivers/mfd/wcd9335-regmap.c rename to asoc/codecs/wcd9335-regmap.c index 1762374418c0..ffb79b79da1b 100644 --- a/drivers/mfd/wcd9335-regmap.c +++ b/asoc/codecs/wcd9335-regmap.c @@ -11,11 +11,11 @@ * GNU General Public License for more details. */ -#include -#include #include #include +#include "core.h" #include "wcd9xxx-regmap.h" +#include "wcd9335_registers.h" static const struct reg_sequence wcd9335_1_x_defaults[] = { { WCD9335_CODEC_RPM_CLK_GATE, 0x03, 0x00 }, diff --git a/drivers/mfd/wcd9335-tables.c b/asoc/codecs/wcd9335-tables.c similarity index 99% rename from drivers/mfd/wcd9335-tables.c rename to asoc/codecs/wcd9335-tables.c index f5c32efe76ef..7df2778f3498 100644 --- a/drivers/mfd/wcd9335-tables.c +++ b/asoc/codecs/wcd9335-tables.c @@ -12,7 +12,7 @@ */ #include -#include +#include "wcd9335_registers.h" #define WCD9335_REG(reg) ((reg) & 0xFF) diff --git a/sound/soc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c similarity index 99% rename from sound/soc/codecs/wcd9335.c rename to asoc/codecs/wcd9335.c index dedeaea55675..26a5a9de362b 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -22,29 +22,29 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include #include #include #include #include #include -#include +#include +#include #include #include #include #include #include #include +#include "core.h" +#include "pdata.h" #include "wcd9335.h" #include "wcd-mbhc-v2.h" #include "wcd9xxx-common-v2.h" #include "wcd9xxx-resmgr-v2.h" +#include "wcd9xxx-irq.h" +#include "wcd9335_registers.h" +#include "wcd9335_irq.h" #include "wcd_cpe_core.h" #include "wcdcal-hwdep.h" #include "wcd-mbhc-v2-api.h" diff --git a/sound/soc/codecs/wcd9335.h b/asoc/codecs/wcd9335.h similarity index 98% rename from sound/soc/codecs/wcd9335.h rename to asoc/codecs/wcd9335.h index c76461edecf1..48826e668d2e 100644 --- a/sound/soc/codecs/wcd9335.h +++ b/asoc/codecs/wcd9335.h @@ -15,8 +15,8 @@ #include #include -#include -#include +#include +#include "wcd9xxx-slimslave.h" #include "wcd-mbhc-v2.h" #define TASHA_REG_VAL(reg, val) {reg, 0, val} diff --git a/include/linux/mfd/wcd9335/irq.h b/asoc/codecs/wcd9335_irq.h similarity index 100% rename from include/linux/mfd/wcd9335/irq.h rename to asoc/codecs/wcd9335_irq.h diff --git a/include/linux/mfd/wcd9335/registers.h b/asoc/codecs/wcd9335_registers.h similarity index 100% rename from include/linux/mfd/wcd9335/registers.h rename to asoc/codecs/wcd9335_registers.h diff --git a/sound/soc/codecs/wcd934x/Makefile b/asoc/codecs/wcd934x/Makefile similarity index 67% rename from sound/soc/codecs/wcd934x/Makefile rename to asoc/codecs/wcd934x/Makefile index 12781f6d4556..c4db59b0e9d7 100644 --- a/sound/soc/codecs/wcd934x/Makefile +++ b/asoc/codecs/wcd934x/Makefile @@ -2,5 +2,6 @@ # Makefile for wcd934x codec driver. # snd-soc-wcd934x-objs := wcd934x.o wcd934x-dsp-cntl.o \ - wcd934x-mbhc.o wcd934x-dsd.o + wcd934x-mbhc.o wcd934x-dsd.o \ + wcd934x-regmap.o wcd934x-tables.o obj-$(CONFIG_SND_SOC_WCD934X) += snd-soc-wcd934x.o diff --git a/sound/soc/codecs/wcd934x/wcd934x-dsd.c b/asoc/codecs/wcd934x/wcd934x-dsd.c similarity index 99% rename from sound/soc/codecs/wcd934x/wcd934x-dsd.c rename to asoc/codecs/wcd934x/wcd934x-dsd.c index 3e23e3749bda..eea18c3d951b 100644 --- a/sound/soc/codecs/wcd934x/wcd934x-dsd.c +++ b/asoc/codecs/wcd934x/wcd934x-dsd.c @@ -12,9 +12,9 @@ #include #include -#include #include #include +#include #include "wcd934x-dsd.h" #define DSD_VOLUME_MAX_0dB 0 diff --git a/sound/soc/codecs/wcd934x/wcd934x-dsd.h b/asoc/codecs/wcd934x/wcd934x-dsd.h similarity index 100% rename from sound/soc/codecs/wcd934x/wcd934x-dsd.h rename to asoc/codecs/wcd934x/wcd934x-dsd.h diff --git a/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c similarity index 99% rename from sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c rename to asoc/codecs/wcd934x/wcd934x-dsp-cntl.c index 8da042531fd8..d82748b2689e 100644 --- a/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c @@ -15,13 +15,13 @@ #include #include #include -#include -#include -#include #include #include +#include #include "wcd934x.h" #include "wcd934x-dsp-cntl.h" +#include "../wcd9xxx-irq.h" +#include "../core.h" #define WCD_CNTL_DIR_NAME_LEN_MAX 32 #define WCD_CPE_FLL_MAX_RETRIES 5 diff --git a/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.h b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h similarity index 100% rename from sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.h rename to asoc/codecs/wcd934x/wcd934x-dsp-cntl.h diff --git a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c b/asoc/codecs/wcd934x/wcd934x-mbhc.c similarity index 99% rename from sound/soc/codecs/wcd934x/wcd934x-mbhc.c rename to asoc/codecs/wcd934x/wcd934x-mbhc.c index ea19caa14f8e..9595ba8e5c9c 100644 --- a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c +++ b/asoc/codecs/wcd934x/wcd934x-mbhc.c @@ -20,18 +20,18 @@ #include #include #include -#include -#include #include -#include -#include -#include #include #include #include #include #include "wcd934x.h" #include "wcd934x-mbhc.h" +#include +#include "wcd934x_irq.h" +#include "../core.h" +#include "../pdata.h" +#include "../wcd9xxx-irq.h" #include "../wcdcal-hwdep.h" #include "../wcd-mbhc-v2-api.h" diff --git a/sound/soc/codecs/wcd934x/wcd934x-mbhc.h b/asoc/codecs/wcd934x/wcd934x-mbhc.h similarity index 100% rename from sound/soc/codecs/wcd934x/wcd934x-mbhc.h rename to asoc/codecs/wcd934x/wcd934x-mbhc.h diff --git a/drivers/mfd/wcd934x-regmap.c b/asoc/codecs/wcd934x/wcd934x-regmap.c similarity index 99% rename from drivers/mfd/wcd934x-regmap.c rename to asoc/codecs/wcd934x/wcd934x-regmap.c index 27249eeec013..7f648fe1c938 100644 --- a/drivers/mfd/wcd934x-regmap.c +++ b/asoc/codecs/wcd934x/wcd934x-regmap.c @@ -11,11 +11,11 @@ * GNU General Public License for more details. */ -#include -#include #include #include -#include "wcd9xxx-regmap.h" +#include +#include "../core.h" +#include "../wcd9xxx-regmap.h" static const struct reg_sequence wcd934x_1_1_defaults[] = { diff --git a/sound/soc/codecs/wcd934x/wcd934x-routing.h b/asoc/codecs/wcd934x/wcd934x-routing.h similarity index 100% rename from sound/soc/codecs/wcd934x/wcd934x-routing.h rename to asoc/codecs/wcd934x/wcd934x-routing.h diff --git a/drivers/mfd/wcd934x-tables.c b/asoc/codecs/wcd934x/wcd934x-tables.c similarity index 99% rename from drivers/mfd/wcd934x-tables.c rename to asoc/codecs/wcd934x/wcd934x-tables.c index db963d08b66e..4e6c2fb2a1cc 100644 --- a/drivers/mfd/wcd934x-tables.c +++ b/asoc/codecs/wcd934x/wcd934x-tables.c @@ -12,7 +12,7 @@ */ #include -#include +#include #define WCD934X_REG(reg) ((reg) & 0xFF) diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c similarity index 99% rename from sound/soc/codecs/wcd934x/wcd934x.c rename to asoc/codecs/wcd934x/wcd934x.c index 3079cca65e38..1997e044fad7 100644 --- a/sound/soc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -27,24 +27,24 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include -#include +#include +#include #include #include #include #include #include #include +#include #include "wcd934x.h" #include "wcd934x-mbhc.h" #include "wcd934x-routing.h" #include "wcd934x-dsp-cntl.h" +#include "wcd934x_irq.h" +#include "../core.h" +#include "../pdata.h" +#include "../wcd9xxx-irq.h" #include "../wcd9xxx-common-v2.h" #include "../wcd9xxx-resmgr-v2.h" #include "../wcdcal-hwdep.h" diff --git a/sound/soc/codecs/wcd934x/wcd934x.h b/asoc/codecs/wcd934x/wcd934x.h similarity index 98% rename from sound/soc/codecs/wcd934x/wcd934x.h rename to asoc/codecs/wcd934x/wcd934x.h index 27c21f103533..ccd48ff2099f 100644 --- a/sound/soc/codecs/wcd934x/wcd934x.h +++ b/asoc/codecs/wcd934x/wcd934x.h @@ -13,9 +13,9 @@ #ifndef WCD934X_H #define WCD934X_H -#include -#include +#include #include "wcd934x-dsp-cntl.h" +#include "../wcd9xxx-slimslave.h" #include "../wcd9xxx-common-v2.h" #include "../wcd-mbhc-v2.h" diff --git a/include/linux/mfd/wcd934x/irq.h b/asoc/codecs/wcd934x/wcd934x_irq.h similarity index 100% rename from include/linux/mfd/wcd934x/irq.h rename to asoc/codecs/wcd934x/wcd934x_irq.h diff --git a/sound/soc/codecs/wcd9xxx-common-v2.c b/asoc/codecs/wcd9xxx-common-v2.c similarity index 99% rename from sound/soc/codecs/wcd9xxx-common-v2.c rename to asoc/codecs/wcd9xxx-common-v2.c index 62166579342a..478c0c6d72e6 100644 --- a/sound/soc/codecs/wcd9xxx-common-v2.c +++ b/asoc/codecs/wcd9xxx-common-v2.c @@ -16,8 +16,8 @@ #include #include #include -#include #include +#include "core.h" #include "wcd9xxx-common-v2.h" #define WCD_USLEEP_RANGE 50 diff --git a/sound/soc/codecs/wcd9xxx-common-v2.h b/asoc/codecs/wcd9xxx-common-v2.h similarity index 100% rename from sound/soc/codecs/wcd9xxx-common-v2.h rename to asoc/codecs/wcd9xxx-common-v2.h diff --git a/drivers/mfd/wcd9xxx-core-init.c b/asoc/codecs/wcd9xxx-core-init.c similarity index 92% rename from drivers/mfd/wcd9xxx-core-init.c rename to asoc/codecs/wcd9xxx-core-init.c index 7f933990682d..e575e0d3472e 100644 --- a/drivers/mfd/wcd9xxx-core-init.c +++ b/asoc/codecs/wcd9xxx-core-init.c @@ -11,9 +11,9 @@ */ #include -#include -#include -#include +#include "msm-cdc-pinctrl.h" +#include "wcd9xxx-irq.h" +#include "core.h" #define NUM_DRIVERS_REG_RET 3 diff --git a/drivers/mfd/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c similarity index 99% rename from drivers/mfd/wcd9xxx-core.c rename to asoc/codecs/wcd9xxx-core.c index 232c290bfb55..2ab5e894864e 100644 --- a/drivers/mfd/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -16,21 +16,21 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include #include #include +#include #include +#include "core.h" +#include "pdata.h" +#include "msm-cdc-pinctrl.h" +#include "msm-cdc-supply.h" +#include "wcd9xxx-irq.h" +#include "wcd9xxx-utils.h" #include "wcd9xxx-regmap.h" +#include "wcd9xxx-slimslave.h" #define WCD9XXX_REGISTER_START_OFFSET 0x800 #define WCD9XXX_SLIM_RW_MAX_TRIES 3 diff --git a/drivers/mfd/wcd9xxx-irq.c b/asoc/codecs/wcd9xxx-irq.c similarity index 99% rename from drivers/mfd/wcd9xxx-irq.c rename to asoc/codecs/wcd9xxx-irq.c index 092f44632e1b..65100c983f06 100644 --- a/drivers/mfd/wcd9xxx-irq.c +++ b/asoc/codecs/wcd9xxx-irq.c @@ -16,9 +16,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -29,6 +26,9 @@ #include #include #include +#include +#include "core.h" +#include "wcd9xxx-irq.h" #define BYTE_BIT_MASK(nr) (1UL << ((nr) % BITS_PER_BYTE)) #define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE) diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx-irq.h b/asoc/codecs/wcd9xxx-irq.h similarity index 97% rename from include/linux/mfd/wcd9xxx/wcd9xxx-irq.h rename to asoc/codecs/wcd9xxx-irq.h index 99ce60383cc2..dfe0b929a84b 100644 --- a/include/linux/mfd/wcd9xxx/wcd9xxx-irq.h +++ b/asoc/codecs/wcd9xxx-irq.h @@ -11,7 +11,7 @@ */ #include -#include +#include "core.h" #ifndef __MFD_WCD9XXX_IRQ_H #define __MFD_WCD9XXX_IRQ_H diff --git a/drivers/mfd/wcd9xxx-regmap.h b/asoc/codecs/wcd9xxx-regmap.h similarity index 97% rename from drivers/mfd/wcd9xxx-regmap.h rename to asoc/codecs/wcd9xxx-regmap.h index f44e8b1cf532..b7604ffb38d0 100644 --- a/drivers/mfd/wcd9xxx-regmap.h +++ b/asoc/codecs/wcd9xxx-regmap.h @@ -15,7 +15,7 @@ #define _WCD9XXX_REGMAP_ #include -#include +#include "core.h" typedef int (*regmap_patch_fptr)(struct regmap *, int); diff --git a/sound/soc/codecs/wcd9xxx-resmgr-v2.c b/asoc/codecs/wcd9xxx-resmgr-v2.c similarity index 99% rename from sound/soc/codecs/wcd9xxx-resmgr-v2.c rename to asoc/codecs/wcd9xxx-resmgr-v2.c index feef0a48af79..1b7610f08835 100644 --- a/sound/soc/codecs/wcd9xxx-resmgr-v2.c +++ b/asoc/codecs/wcd9xxx-resmgr-v2.c @@ -14,11 +14,11 @@ #include #include #include -#include -#include -#include #include #include "wcd9xxx-resmgr-v2.h" +#include "core.h" +#include "wcd9335_registers.h" +#include #define WCD9XXX_RCO_CALIBRATION_DELAY_INC_US 5000 #define WCD93XX_ANA_BIAS 0x0601 diff --git a/sound/soc/codecs/wcd9xxx-resmgr-v2.h b/asoc/codecs/wcd9xxx-resmgr-v2.h similarity index 98% rename from sound/soc/codecs/wcd9xxx-resmgr-v2.h rename to asoc/codecs/wcd9xxx-resmgr-v2.h index e831ba61e9c2..e9d3531e262e 100644 --- a/sound/soc/codecs/wcd9xxx-resmgr-v2.h +++ b/asoc/codecs/wcd9xxx-resmgr-v2.h @@ -13,8 +13,8 @@ #ifndef __WCD9XXX_COMMON_V2_H__ #define __WCD9XXX_COMMON_V2_H__ -#include #include +#include "core.h" enum wcd_clock_type { WCD_CLK_OFF, diff --git a/drivers/mfd/wcd9xxx-rst.c b/asoc/codecs/wcd9xxx-rst.c similarity index 97% rename from drivers/mfd/wcd9xxx-rst.c rename to asoc/codecs/wcd9xxx-rst.c index c8e0b348254a..3df95d537fe8 100644 --- a/drivers/mfd/wcd9xxx-rst.c +++ b/asoc/codecs/wcd9xxx-rst.c @@ -15,13 +15,13 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include "core.h" +#include "pdata.h" +#include "wcd9xxx-utils.h" +#include "wcd9335_registers.h" +#include "wcd9335_irq.h" +#include +#include "wcd934x/wcd934x_irq.h" /* wcd9335 interrupt table */ static const struct intr_data wcd9335_intr_table[] = { diff --git a/drivers/mfd/wcd9xxx-slimslave.c b/asoc/codecs/wcd9xxx-slimslave.c similarity index 99% rename from drivers/mfd/wcd9xxx-slimslave.c rename to asoc/codecs/wcd9xxx-slimslave.c index a99ad5a2f9c8..66a83320d03b 100644 --- a/drivers/mfd/wcd9xxx-slimslave.c +++ b/asoc/codecs/wcd9xxx-slimslave.c @@ -11,8 +11,8 @@ */ #include #include -#include #include +#include "wcd9xxx-slimslave.h" struct wcd9xxx_slim_sch { u16 rx_port_ch_reg_base; diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h b/asoc/codecs/wcd9xxx-slimslave.h similarity index 96% rename from include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h rename to asoc/codecs/wcd9xxx-slimslave.h index 96fdb00a2e03..5132e43efad0 100644 --- a/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h +++ b/asoc/codecs/wcd9xxx-slimslave.h @@ -10,11 +10,11 @@ * GNU General Public License for more details. */ -#ifndef __WCD9310_SLIMSLAVE_H_ -#define __WCD9310_SLIMSLAVE_H_ +#ifndef __WCD9XXX_SLIMSLAVE_H_ +#define __WCD9XXX_SLIMSLAVE_H_ #include -#include +#include "core.h" /* @@ -116,4 +116,4 @@ int wcd9xxx_rx_vport_validation(u32 port_id, int wcd9xxx_tx_vport_validation(u32 vtable, u32 port_id, struct wcd9xxx_codec_dai_data *codec_dai, u32 num_codec_dais); -#endif /* __WCD9310_SLIMSLAVE_H_ */ +#endif /* __WCD9XXX_SLIMSLAVE_H_ */ diff --git a/sound/soc/codecs/wcd9xxx-soc-init.c b/asoc/codecs/wcd9xxx-soc-init.c similarity index 100% rename from sound/soc/codecs/wcd9xxx-soc-init.c rename to asoc/codecs/wcd9xxx-soc-init.c diff --git a/drivers/mfd/wcd9xxx-utils.c b/asoc/codecs/wcd9xxx-utils.c similarity index 99% rename from drivers/mfd/wcd9xxx-utils.c rename to asoc/codecs/wcd9xxx-utils.c index 8d3d4ad4bbb5..a1ea93843f28 100644 --- a/drivers/mfd/wcd9xxx-utils.c +++ b/asoc/codecs/wcd9xxx-utils.c @@ -20,12 +20,12 @@ #include #include #include -#include -#include -#include -#include -#include -#include +#include "core.h" +#include "msm-cdc-supply.h" +#include "msm-cdc-pinctrl.h" +#include "pdata.h" +#include "wcd9xxx-irq.h" +#include "wcd9xxx-utils.h" #define REG_BYTES 2 #define VAL_BYTES 1 diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx-utils.h b/asoc/codecs/wcd9xxx-utils.h similarity index 95% rename from include/linux/mfd/wcd9xxx/wcd9xxx-utils.h rename to asoc/codecs/wcd9xxx-utils.h index 7a13dd19e8c0..a7ec56c2da0a 100644 --- a/include/linux/mfd/wcd9xxx/wcd9xxx-utils.h +++ b/asoc/codecs/wcd9xxx-utils.h @@ -16,8 +16,8 @@ #include #include #include -#include -#include +#include "pdata.h" +#include "core.h" struct wcd9xxx_pdata *wcd9xxx_populate_dt_data(struct device *dev); int wcd9xxx_bringup(struct device *dev); diff --git a/sound/soc/codecs/wcd_cmi_api.h b/asoc/codecs/wcd_cmi_api.h similarity index 100% rename from sound/soc/codecs/wcd_cmi_api.h rename to asoc/codecs/wcd_cmi_api.h diff --git a/sound/soc/codecs/wcd_cpe_core.c b/asoc/codecs/wcd_cpe_core.c similarity index 99% rename from sound/soc/codecs/wcd_cpe_core.c rename to asoc/codecs/wcd_cpe_core.c index f2a20d51d0e2..7748ace12686 100644 --- a/sound/soc/codecs/wcd_cpe_core.c +++ b/asoc/codecs/wcd_cpe_core.c @@ -23,16 +23,16 @@ #include #include #include -#include #include -#include #include -#include -#include -#include +#include +#include "core.h" +#include "cpe_core.h" +#include "cpe_err.h" #include "wcd_cpe_core.h" #include "wcd_cpe_services.h" #include "wcd_cmi_api.h" +#include "wcd9xxx-irq.h" #define CMI_CMD_TIMEOUT (10 * HZ) #define WCD_CPE_LSM_MAX_SESSIONS 2 diff --git a/sound/soc/codecs/wcd_cpe_core.h b/asoc/codecs/wcd_cpe_core.h similarity index 100% rename from sound/soc/codecs/wcd_cpe_core.h rename to asoc/codecs/wcd_cpe_core.h diff --git a/sound/soc/codecs/wcd_cpe_services.c b/asoc/codecs/wcd_cpe_services.c similarity index 99% rename from sound/soc/codecs/wcd_cpe_services.c rename to asoc/codecs/wcd_cpe_services.c index ad8962b6f1fe..7a0e70311407 100644 --- a/sound/soc/codecs/wcd_cpe_services.c +++ b/asoc/codecs/wcd_cpe_services.c @@ -17,10 +17,11 @@ #include #include #include -#include -#include #include +#include #include +#include "core.h" +#include "cpe_cmi.h" #include "wcd_cpe_services.h" #include "wcd_cmi_api.h" diff --git a/sound/soc/codecs/wcd_cpe_services.h b/asoc/codecs/wcd_cpe_services.h similarity index 100% rename from sound/soc/codecs/wcd_cpe_services.h rename to asoc/codecs/wcd_cpe_services.h diff --git a/sound/soc/codecs/wcdcal-hwdep.c b/asoc/codecs/wcdcal-hwdep.c similarity index 100% rename from sound/soc/codecs/wcdcal-hwdep.c rename to asoc/codecs/wcdcal-hwdep.c diff --git a/sound/soc/codecs/wcdcal-hwdep.h b/asoc/codecs/wcdcal-hwdep.h similarity index 100% rename from sound/soc/codecs/wcdcal-hwdep.h rename to asoc/codecs/wcdcal-hwdep.h diff --git a/sound/soc/codecs/wsa881x-analog.c b/asoc/codecs/wsa881x-analog.c similarity index 100% rename from sound/soc/codecs/wsa881x-analog.c rename to asoc/codecs/wsa881x-analog.c diff --git a/sound/soc/codecs/wsa881x-analog.h b/asoc/codecs/wsa881x-analog.h similarity index 100% rename from sound/soc/codecs/wsa881x-analog.h rename to asoc/codecs/wsa881x-analog.h diff --git a/sound/soc/codecs/wsa881x-irq.c b/asoc/codecs/wsa881x-irq.c similarity index 100% rename from sound/soc/codecs/wsa881x-irq.c rename to asoc/codecs/wsa881x-irq.c diff --git a/sound/soc/codecs/wsa881x-irq.h b/asoc/codecs/wsa881x-irq.h similarity index 100% rename from sound/soc/codecs/wsa881x-irq.h rename to asoc/codecs/wsa881x-irq.h diff --git a/sound/soc/codecs/wsa881x-registers-analog.h b/asoc/codecs/wsa881x-registers-analog.h similarity index 100% rename from sound/soc/codecs/wsa881x-registers-analog.h rename to asoc/codecs/wsa881x-registers-analog.h diff --git a/sound/soc/codecs/wsa881x-registers.h b/asoc/codecs/wsa881x-registers.h similarity index 100% rename from sound/soc/codecs/wsa881x-registers.h rename to asoc/codecs/wsa881x-registers.h diff --git a/sound/soc/codecs/wsa881x-regmap-analog.c b/asoc/codecs/wsa881x-regmap-analog.c similarity index 100% rename from sound/soc/codecs/wsa881x-regmap-analog.c rename to asoc/codecs/wsa881x-regmap-analog.c diff --git a/sound/soc/codecs/wsa881x-regmap.c b/asoc/codecs/wsa881x-regmap.c similarity index 100% rename from sound/soc/codecs/wsa881x-regmap.c rename to asoc/codecs/wsa881x-regmap.c diff --git a/sound/soc/codecs/wsa881x-tables-analog.c b/asoc/codecs/wsa881x-tables-analog.c similarity index 100% rename from sound/soc/codecs/wsa881x-tables-analog.c rename to asoc/codecs/wsa881x-tables-analog.c diff --git a/sound/soc/codecs/wsa881x-tables.c b/asoc/codecs/wsa881x-tables.c similarity index 100% rename from sound/soc/codecs/wsa881x-tables.c rename to asoc/codecs/wsa881x-tables.c diff --git a/sound/soc/codecs/wsa881x-temp-sensor.c b/asoc/codecs/wsa881x-temp-sensor.c similarity index 100% rename from sound/soc/codecs/wsa881x-temp-sensor.c rename to asoc/codecs/wsa881x-temp-sensor.c diff --git a/sound/soc/codecs/wsa881x-temp-sensor.h b/asoc/codecs/wsa881x-temp-sensor.h similarity index 100% rename from sound/soc/codecs/wsa881x-temp-sensor.h rename to asoc/codecs/wsa881x-temp-sensor.h diff --git a/sound/soc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c similarity index 99% rename from sound/soc/codecs/wsa881x.c rename to asoc/codecs/wsa881x.c index 77aea1049ca5..456f68c81954 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -26,13 +26,13 @@ #include #include #include -#include -#include +#include #include #include #include #include #include +#include "msm-cdc-pinctrl.h" #include "wsa881x.h" #include "wsa881x-temp-sensor.h" diff --git a/sound/soc/codecs/wsa881x.h b/asoc/codecs/wsa881x.h similarity index 100% rename from sound/soc/codecs/wsa881x.h rename to asoc/codecs/wsa881x.h diff --git a/sound/soc/msm/device_event.h b/asoc/device_event.h similarity index 100% rename from sound/soc/msm/device_event.h rename to asoc/device_event.h diff --git a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c b/asoc/msm-audio-effects-q6-v2.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c rename to asoc/msm-audio-effects-q6-v2.c index 9f082226ca35..962d64e94ba3 100644 --- a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c +++ b/asoc/msm-audio-effects-q6-v2.c @@ -11,11 +11,11 @@ */ #include -#include -#include #include -#include #include +#include +#include +#include #define MAX_ENABLE_CMD_SIZE 32 diff --git a/sound/soc/msm/msm-audio-pinctrl.c b/asoc/msm-audio-pinctrl.c similarity index 100% rename from sound/soc/msm/msm-audio-pinctrl.c rename to asoc/msm-audio-pinctrl.c diff --git a/sound/soc/msm/msm-audio-pinctrl.h b/asoc/msm-audio-pinctrl.h similarity index 100% rename from sound/soc/msm/msm-audio-pinctrl.h rename to asoc/msm-audio-pinctrl.h diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c rename to asoc/msm-compress-q6-v2.c index c88526564d79..89efb904ae3f 100644 --- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -26,23 +26,22 @@ #include #include #include -#include #include #include #include #include -#include #include #include #include - -#include -#include #include #include #include -#include + +#include +#include +#include +#include #include "msm-pcm-routing-v2.h" #include "msm-qti-pp-config.h" diff --git a/sound/soc/msm/msm-cpe-lsm.c b/asoc/msm-cpe-lsm.c similarity index 99% rename from sound/soc/msm/msm-cpe-lsm.c rename to asoc/msm-cpe-lsm.c index 7b65dda227b9..87297ec05104 100644 --- a/sound/soc/msm/msm-cpe-lsm.c +++ b/asoc/msm-cpe-lsm.c @@ -23,10 +23,10 @@ #include #include #include -#include #include #include -#include +#include "msm-slim-dma.h" +#include "codecs/cpe_core.h" #define SAMPLE_RATE_48KHZ 48000 #define SAMPLE_RATE_16KHZ 16000 diff --git a/sound/soc/msm/msm-dai-fe.c b/asoc/msm-dai-fe.c similarity index 100% rename from sound/soc/msm/msm-dai-fe.c rename to asoc/msm-dai-fe.c diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c b/asoc/msm-dai-q6-hdmi-v2.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c rename to asoc/msm-dai-q6-hdmi-v2.c index deb179898b6a..9c8d20a9f2a7 100644 --- a/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c +++ b/asoc/msm-dai-q6-hdmi-v2.c @@ -20,10 +20,10 @@ #include #include #include -#include -#include -#include #include +#include +#include +#include "msm-dai-q6-v2.h" #define HDMI_RX_CA_MAX 0x32 diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c rename to asoc/msm-dai-q6-v2.c index c8b01c679788..583934ddf6f1 100644 --- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -22,10 +21,11 @@ #include #include #include -#include -#include -#include #include +#include +#include +#include "msm-dai-q6-v2.h" +#include "codecs/core.h" #define MSM_DAI_PRI_AUXPCM_DT_DEV_ID 1 #define MSM_DAI_SEC_AUXPCM_DT_DEV_ID 2 diff --git a/include/sound/msm-dai-q6-v2.h b/asoc/msm-dai-q6-v2.h similarity index 100% rename from include/sound/msm-dai-q6-v2.h rename to asoc/msm-dai-q6-v2.h diff --git a/sound/soc/msm/qdsp6v2/msm-dai-slim.c b/asoc/msm-dai-slim.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-dai-slim.c rename to asoc/msm-dai-slim.c index 8115feef846e..0e7c7b1c4883 100644 --- a/sound/soc/msm/qdsp6v2/msm-dai-slim.c +++ b/asoc/msm-dai-slim.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include "msm-slim-dma.h" #define SLIM_DEV_NAME "msm-dai-slim" diff --git a/sound/soc/msm/qdsp6v2/msm-dai-stub-v2.c b/asoc/msm-dai-stub-v2.c similarity index 100% rename from sound/soc/msm/qdsp6v2/msm-dai-stub-v2.c rename to asoc/msm-dai-stub-v2.c diff --git a/sound/soc/msm/qdsp6v2/msm-dolby-common.h b/asoc/msm-dolby-common.h similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-dolby-common.h rename to asoc/msm-dolby-common.h index b43ff15e7649..885d283ef03d 100644 --- a/sound/soc/msm/qdsp6v2/msm-dolby-common.h +++ b/asoc/msm-dolby-common.h @@ -1,6 +1,5 @@ /* * Copyright (c) 2013-2014, 2016 The Linux Foundation. All rights reserved. - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. diff --git a/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h b/asoc/msm-dolby-dap-config.h similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h rename to asoc/msm-dolby-dap-config.h index 6204cb15857d..b2b713907130 100644 --- a/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h +++ b/asoc/msm-dolby-dap-config.h @@ -1,6 +1,5 @@ /* * Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/asoc/msm-ds2-dap-config.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c rename to asoc/msm-ds2-dap-config.c index 5c9393f7e407..7381e5d8c362 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/asoc/msm-ds2-dap-config.c @@ -15,11 +15,11 @@ #include #include #include -#include +#include +#include #include "msm-ds2-dap-config.h" #include "msm-pcm-routing-v2.h" -#include #if defined(CONFIG_DOLBY_DS2) || defined(CONFIG_DOLBY_LICENSE) diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h b/asoc/msm-ds2-dap-config.h similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h rename to asoc/msm-ds2-dap-config.h index 5804a64f5d48..c90bd8fb83a4 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h +++ b/asoc/msm-ds2-dap-config.h @@ -1,6 +1,5 @@ /* * Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. diff --git a/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c b/asoc/msm-dts-srs-tm-config.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c rename to asoc/msm-dts-srs-tm-config.c index 437cd979359d..78174afb9b47 100644 --- a/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.c +++ b/asoc/msm-dts-srs-tm-config.c @@ -16,11 +16,11 @@ #include #include #include -#include -#include -#include #include -#include "msm-dts-srs-tm-config.h" +#include +#include +#include +#include #include "msm-pcm-routing-v2.h" static int srs_port_id[AFE_MAX_PORTS] = {-1}; diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/asoc/msm-lsm-client.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-lsm-client.c rename to asoc/msm-lsm-client.c index 3a6cbe6937c4..e96d111a61e4 100644 --- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -28,9 +27,10 @@ #include #include #include -#include #include #include +#include +#include #include "msm-pcm-routing-v2.h" #define CAPTURE_MIN_NUM_PERIODS 2 diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/asoc/msm-pcm-afe-v2.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c rename to asoc/msm-pcm-afe-v2.c index ab9b3107665f..102fad8b3278 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c +++ b/asoc/msm-pcm-afe-v2.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -28,8 +27,9 @@ #include #include #include -#include #include +#include +#include #include "msm-pcm-afe-v2.h" #define MIN_PLAYBACK_PERIOD_SIZE (128 * 2) diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h b/asoc/msm-pcm-afe-v2.h similarity index 95% rename from sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h rename to asoc/msm-pcm-afe-v2.h index 84a4c3c6c275..926b626de37d 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.h +++ b/asoc/msm-pcm-afe-v2.h @@ -11,8 +11,8 @@ */ #ifndef _MSM_PCM_AFE_H #define _MSM_PCM_AFE_H -#include -#include +#include +#include struct pcm_afe_info { diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-dtmf-v2.c b/asoc/msm-pcm-dtmf-v2.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-pcm-dtmf-v2.c rename to asoc/msm-pcm-dtmf-v2.c index f4e03fe2e4cf..c387c7d0aab4 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-dtmf-v2.c +++ b/asoc/msm-pcm-dtmf-v2.c @@ -20,11 +20,11 @@ #include #include #include -#include +#include +#include #include "msm-pcm-q6-v2.h" #include "msm-pcm-routing-v2.h" -#include "q6voice.h" enum { DTMF_IN_RX, diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c b/asoc/msm-pcm-host-voice-v2.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c rename to asoc/msm-pcm-host-voice-v2.c index 2f60db993895..55b07bc75823 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-host-voice-v2.c +++ b/asoc/msm-pcm-host-voice-v2.c @@ -25,8 +25,8 @@ #include #include #include -#include -#include "q6voice.h" +#include +#include #define HPCM_MAX_Q_LEN 2 #define HPCM_MIN_VOC_PKT_SIZE 320 diff --git a/sound/soc/msm/msm-pcm-hostless.c b/asoc/msm-pcm-hostless.c similarity index 100% rename from sound/soc/msm/msm-pcm-hostless.c rename to asoc/msm-pcm-hostless.c diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c rename to asoc/msm-pcm-loopback-v2.c index 7ef1ca8f1ae1..a6ac8ca006fa 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -16,16 +16,16 @@ #include #include #include -#include #include #include -#include #include #include #include #include #include -#include +#include +#include +#include #include "msm-pcm-routing-v2.h" diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c rename to asoc/msm-pcm-q6-noirq.c index 75a2bffaa3ce..3e03437abcf6 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -28,7 +27,6 @@ #include #include #include -#include #include #include @@ -36,6 +34,8 @@ #include #include #include +#include +#include #include "msm-pcm-q6-v2.h" #include "msm-pcm-routing-v2.h" diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c rename to asoc/msm-pcm-q6-v2.c index 74e99d376049..4910decf6d8b 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -25,16 +25,16 @@ #include #include #include -#include #include #include #include -#include #include #include #include #include +#include +#include #include "msm-pcm-q6-v2.h" #include "msm-pcm-routing-v2.h" diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h b/asoc/msm-pcm-q6-v2.h similarity index 98% rename from sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h rename to asoc/msm-pcm-q6-v2.h index 3b3f0480d33c..0177b2d6ce79 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h +++ b/asoc/msm-pcm-q6-v2.h @@ -18,8 +18,8 @@ #ifndef _MSM_PCM_H #define _MSM_PCM_H -#include -#include +#include +#include diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.c b/asoc/msm-pcm-routing-devdep.c similarity index 100% rename from sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.c rename to asoc/msm-pcm-routing-devdep.c diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.h b/asoc/msm-pcm-routing-devdep.h similarity index 100% rename from sound/soc/msm/qdsp6v2/msm-pcm-routing-devdep.h rename to asoc/msm-pcm-routing-devdep.h diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c rename to asoc/msm-pcm-routing-v2.c index d67296f238f0..de2201ef2f80 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -25,25 +25,25 @@ #include #include #include -#include -#include -#include #include #include #include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "msm-pcm-routing-v2.h" #include "msm-pcm-routing-devdep.h" #include "msm-qti-pp-config.h" -#include "msm-dts-srs-tm-config.h" #include "msm-dolby-dap-config.h" #include "msm-ds2-dap-config.h" -#include "q6voice.h" -#include "sound/q6lsm.h" #ifndef CONFIG_DOLBY_DAP #undef DOLBY_ADM_COPP_TOPOLOGY_ID diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h rename to asoc/msm-pcm-routing-v2.h index 19e726001d25..4e823d3eba3c 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -11,7 +11,7 @@ */ #ifndef _MSM_PCM_ROUTING_H #define _MSM_PCM_ROUTING_H -#include +#include /* * These names are used by HAL to specify the BE. If any changes are diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c rename to asoc/msm-pcm-voice-v2.c index 654806e9795e..9972132000e9 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c +++ b/asoc/msm-pcm-voice-v2.c @@ -26,9 +26,9 @@ #include #include #include +#include #include "msm-pcm-voice-v2.h" -#include "q6voice.h" static struct msm_voice voice_info[VOICE_SESSION_INDEX_MAX]; diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.h b/asoc/msm-pcm-voice-v2.h similarity index 97% rename from sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.h rename to asoc/msm-pcm-voice-v2.h index e00cebc51e7e..60f5adcf5757 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.h +++ b/asoc/msm-pcm-voice-v2.h @@ -11,7 +11,7 @@ */ #ifndef _MSM_PCM_VOICE_H #define _MSM_PCM_VOICE_H -#include +#include enum { VOICE_SESSION_INDEX, diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c b/asoc/msm-pcm-voip-v2.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c rename to asoc/msm-pcm-voip-v2.c index 02225f0dcef4..86dcacacbaa3 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c +++ b/asoc/msm-pcm-voip-v2.c @@ -26,10 +26,10 @@ #include #include #include +#include #include "msm-pcm-q6-v2.h" #include "msm-pcm-routing-v2.h" -#include "q6voice.h" #define SHARED_MEM_BUF 2 #define VOIP_MAX_Q_LEN 10 diff --git a/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-qti-pp-config.c rename to asoc/msm-qti-pp-config.c index a885e1e3aa86..2064056ab350 100644 --- a/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -15,12 +15,12 @@ #include #include #include -#include -#include -#include #include -#include #include +#include +#include +#include +#include #include "msm-qti-pp-config.h" #include "msm-pcm-routing-v2.h" diff --git a/sound/soc/msm/qdsp6v2/msm-qti-pp-config.h b/asoc/msm-qti-pp-config.h similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-qti-pp-config.h rename to asoc/msm-qti-pp-config.h index 01a06a4965ef..14e9b10d0061 100644 --- a/sound/soc/msm/qdsp6v2/msm-qti-pp-config.h +++ b/asoc/msm-qti-pp-config.h @@ -1,6 +1,5 @@ /* * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. diff --git a/include/sound/msm-slim-dma.h b/asoc/msm-slim-dma.h similarity index 100% rename from include/sound/msm-slim-dma.h rename to asoc/msm-slim-dma.h diff --git a/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c similarity index 99% rename from sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c rename to asoc/msm-transcode-loopback-q6-v2.c index b1bb27248714..eaef498c49b7 100644 --- a/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -19,22 +19,21 @@ #include #include #include -#include #include #include #include #include #include #include -#include #include #include #include -#include #include #include #include -#include +#include +#include +#include #include "msm-pcm-routing-v2.h" #include "msm-qti-pp-config.h" diff --git a/sound/soc/msm/msm8996.c b/asoc/msm8996.c similarity index 100% rename from sound/soc/msm/msm8996.c rename to asoc/msm8996.c diff --git a/sound/soc/msm/msm8998.c b/asoc/msm8998.c similarity index 99% rename from sound/soc/msm/msm8998.c rename to asoc/msm8998.c index 222c65a3182d..6c5393d021d7 100644 --- a/sound/soc/msm/msm8998.c +++ b/asoc/msm8998.c @@ -23,23 +23,23 @@ #include #include #include -#include #include #include #include #include #include -#include -#include #include #include #include -#include -#include "qdsp6v2/msm-pcm-routing-v2.h" -#include "../codecs/wcd9335.h" -#include "../codecs/wcd934x/wcd934x.h" -#include "../codecs/wcd934x/wcd934x-mbhc.h" -#include "../codecs/wsa881x.h" +#include +#include +#include +#include "msm-pcm-routing-v2.h" +#include "codecs/msm-cdc-pinctrl.h" +#include "codecs/wcd9335.h" +#include "codecs/wcd934x/wcd934x.h" +#include "codecs/wcd934x/wcd934x-mbhc.h" +#include "codecs/wsa881x.h" #define DRV_NAME "msm8998-asoc-snd" diff --git a/sound/soc/msm/sdm660-common.c b/asoc/sdm660-common.c similarity index 99% rename from sound/soc/msm/sdm660-common.c rename to asoc/sdm660-common.c index b34b04b83044..16ecfaf9e8c7 100644 --- a/sound/soc/msm/sdm660-common.c +++ b/asoc/sdm660-common.c @@ -15,15 +15,15 @@ #include #include #include -#include #include -#include -#include "qdsp6v2/msm-pcm-routing-v2.h" +#include +#include "msm-pcm-routing-v2.h" #include "sdm660-common.h" #include "sdm660-internal.h" #include "sdm660-external.h" -#include "../codecs/sdm660_cdc/msm-analog-cdc.h" -#include "../codecs/wsa881x.h" +#include "codecs/msm-cdc-pinctrl.h" +#include "codecs/sdm660_cdc/msm-analog-cdc.h" +#include "codecs/wsa881x.h" #define DRV_NAME "sdm660-asoc-snd" diff --git a/sound/soc/msm/sdm660-common.h b/asoc/sdm660-common.h similarity index 98% rename from sound/soc/msm/sdm660-common.h rename to asoc/sdm660-common.h index bca8cd788a39..682dcd5d055e 100644 --- a/sound/soc/msm/sdm660-common.h +++ b/asoc/sdm660-common.h @@ -14,8 +14,8 @@ #define __MSM_COMMON #include -#include -#include "../codecs/wcd-mbhc-v2.h" +#include +#include "codecs/wcd-mbhc-v2.h" #define SAMPLING_RATE_8KHZ 8000 #define SAMPLING_RATE_11P025KHZ 11025 diff --git a/sound/soc/msm/sdm660-ext-dai-links.c b/asoc/sdm660-ext-dai-links.c similarity index 99% rename from sound/soc/msm/sdm660-ext-dai-links.c rename to asoc/sdm660-ext-dai-links.c index 77d3875d0a06..cde28706a75e 100644 --- a/sound/soc/msm/sdm660-ext-dai-links.c +++ b/asoc/sdm660-ext-dai-links.c @@ -10,7 +10,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -18,9 +17,10 @@ #include #include #include "qdsp6v2/msm-pcm-routing-v2.h" -#include "../codecs/wcd9335.h" #include "sdm660-common.h" #include "sdm660-external.h" +#include "codecs/core.h" +#include "codecs/wcd9335.h" #define DEV_NAME_STR_LEN 32 #define __CHIPSET__ "SDM660 " diff --git a/sound/soc/msm/sdm660-external.c b/asoc/sdm660-external.c similarity index 99% rename from sound/soc/msm/sdm660-external.c rename to asoc/sdm660-external.c index 84d1c2ea9b18..9085282964c0 100644 --- a/sound/soc/msm/sdm660-external.c +++ b/asoc/sdm660-external.c @@ -17,15 +17,15 @@ #include #include #include -#include -#include -#include "qdsp6v2/msm-pcm-routing-v2.h" +#include +#include +#include "msm-pcm-routing-v2.h" #include "msm-audio-pinctrl.h" #include "sdm660-common.h" #include "sdm660-external.h" -#include "../codecs/wcd9335.h" -#include "../codecs/wcd934x/wcd934x.h" -#include "../codecs/wcd934x/wcd934x-mbhc.h" +#include "codecs/wcd9335.h" +#include "codecs/wcd934x/wcd934x.h" +#include "codecs/wcd934x/wcd934x-mbhc.h" #define SDM660_SPK_ON 1 #define SDM660_SPK_OFF 0 diff --git a/sound/soc/msm/sdm660-external.h b/asoc/sdm660-external.h similarity index 100% rename from sound/soc/msm/sdm660-external.h rename to asoc/sdm660-external.h diff --git a/sound/soc/msm/sdm660-internal.c b/asoc/sdm660-internal.c similarity index 99% rename from sound/soc/msm/sdm660-internal.c rename to asoc/sdm660-internal.c index a57d6f611942..0afe82896cfb 100644 --- a/sound/soc/msm/sdm660-internal.c +++ b/asoc/sdm660-internal.c @@ -13,13 +13,13 @@ #include #include #include -#include #include -#include "qdsp6v2/msm-pcm-routing-v2.h" +#include "msm-pcm-routing-v2.h" #include "sdm660-common.h" -#include "../codecs/sdm660_cdc/msm-digital-cdc.h" -#include "../codecs/sdm660_cdc/msm-analog-cdc.h" -#include "../codecs/msm_sdw/msm_sdw.h" +#include "codecs/msm-cdc-pinctrl.h" +#include "codecs/sdm660_cdc/msm-digital-cdc.h" +#include "codecs/sdm660_cdc/msm-analog-cdc.h" +#include "codecs/msm_sdw/msm_sdw.h" #define __CHIPSET__ "SDM660 " #define MSM_DAILINK_NAME(name) (__CHIPSET__#name) diff --git a/sound/soc/msm/sdm660-internal.h b/asoc/sdm660-internal.h similarity index 100% rename from sound/soc/msm/sdm660-internal.h rename to asoc/sdm660-internal.h diff --git a/sound/soc/msm/sdm845.c b/asoc/sdm845.c similarity index 99% rename from sound/soc/msm/sdm845.c rename to asoc/sdm845.c index 3be194cdc48d..9d6ff120e671 100644 --- a/sound/soc/msm/sdm845.c +++ b/asoc/sdm845.c @@ -21,22 +21,22 @@ #include #include #include -#include #include #include #include #include #include -#include -#include #include #include #include -#include -#include "qdsp6v2/msm-pcm-routing-v2.h" -#include "../codecs/wcd934x/wcd934x.h" -#include "../codecs/wcd934x/wcd934x-mbhc.h" -#include "../codecs/wsa881x.h" +#include +#include +#include +#include "msm-pcm-routing-v2.h" +#include "codecs/msm-cdc-pinctrl.h" +#include "codecs/wcd934x/wcd934x.h" +#include "codecs/wcd934x/wcd934x-mbhc.h" +#include "codecs/wsa881x.h" #define DRV_NAME "sdm845-asoc-snd" diff --git a/drivers/Makefile b/drivers/Makefile deleted file mode 100644 index b48069c04d47..000000000000 --- a/drivers/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -obj-y += mfd/ -obj-y += misc/ -obj-y += soc/ -obj-y += soundwire/ -obj-y += base/ -obj-y += pinctrl/ diff --git a/drivers/base/Makefile b/drivers/base/Makefile deleted file mode 100644 index 76e50f9816bf..000000000000 --- a/drivers/base/Makefile +++ /dev/null @@ -1,2 +0,0 @@ - -obj-y += regmap/ diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile deleted file mode 100644 index a23e35ed8459..000000000000 --- a/drivers/base/regmap/Makefile +++ /dev/null @@ -1,2 +0,0 @@ - -obj-$(CONFIG_REGMAP_SWR) += regmap-swr.o diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h deleted file mode 120000 index e163b7862be6..000000000000 --- a/drivers/base/regmap/internal.h +++ /dev/null @@ -1 +0,0 @@ -../../../../../drivers/base/regmap/internal.h \ No newline at end of file diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile deleted file mode 100644 index 745691af1673..000000000000 --- a/drivers/mfd/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -wcd-core-objs := wcd9xxx-rst.o wcd9xxx-core-init.o \ - wcd9xxx-core.o wcd9xxx-irq.o \ - wcd9xxx-slimslave.o wcd9xxx-utils.o \ - wcd934x-regmap.o wcd934x-tables.o \ - wcd9335-regmap.o wcd9335-tables.o \ - msm-cdc-pinctrl.o msm-cdc-supply.o -obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd-core.o - diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile deleted file mode 100644 index f00d59de9db2..000000000000 --- a/drivers/misc/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for misc devices that really don't fit anywhere else. -# - -obj-y += qcom/ diff --git a/drivers/misc/qcom/Kconfig b/drivers/misc/qcom/Kconfig deleted file mode 100644 index e8a79605f361..000000000000 --- a/drivers/misc/qcom/Kconfig +++ /dev/null @@ -1,19 +0,0 @@ -config MSM_QDSP6V2_CODECS - bool "Audio QDSP6V2 APR support" - select SND_SOC_QDSP6V2 - help - Enable Audio codecs with APR IPC protocol support between - application processor and QDSP6 for B-family. APR is - used by audio driver to configure QDSP6's - ASM, ADM and AFE. - -config MSM_ULTRASOUND - bool "QDSP6V2 HW Ultrasound support" - select SND_SOC_QDSP6V2 - help - Enable HW Ultrasound support in QDSP6V2. - QDSP6V2 can support HW encoder & decoder and - ultrasound processing. It will enable - ultrasound data paths between - HW and services, calculating input events - upon the ultrasound data. diff --git a/drivers/misc/qcom/Makefile b/drivers/misc/qcom/Makefile deleted file mode 100644 index 120bdddcbc84..000000000000 --- a/drivers/misc/qcom/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-y += qdsp6v2/ diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/Makefile b/drivers/misc/qcom/qdsp6v2/ultrasound/Makefile deleted file mode 100644 index 41f614aa4eb3..000000000000 --- a/drivers/misc/qcom/qdsp6v2/ultrasound/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -ccflags-y := -I$(src)/.. -obj-$(CONFIG_MSM_ULTRASOUND) += usf.o usfcdev.o q6usm.o diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile deleted file mode 100644 index 0e0c511e18d9..000000000000 --- a/drivers/pinctrl/Makefile +++ /dev/null @@ -1,2 +0,0 @@ - -obj-y += qcom/ diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h deleted file mode 120000 index 2b68c81aa5d3..000000000000 --- a/drivers/pinctrl/core.h +++ /dev/null @@ -1 +0,0 @@ -../../../../drivers/pinctrl/core.h \ No newline at end of file diff --git a/drivers/pinctrl/pinctrl-utils.h b/drivers/pinctrl/pinctrl-utils.h deleted file mode 120000 index 3303afdf9f46..000000000000 --- a/drivers/pinctrl/pinctrl-utils.h +++ /dev/null @@ -1 +0,0 @@ -../../../../drivers/pinctrl/pinctrl-utils.h \ No newline at end of file diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile deleted file mode 100644 index cd1b749ae5ee..000000000000 --- a/drivers/pinctrl/qcom/Makefile +++ /dev/null @@ -1,3 +0,0 @@ - -obj-$(CONFIG_PINCTRL_WCD) += pinctrl-wcd.o -obj-$(CONFIG_PINCTRL_LPI) += pinctrl-lpi.o diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile deleted file mode 100644 index ae8ffae4cbc3..000000000000 --- a/drivers/soc/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the Linux Kernel SOC specific device drivers. -# - -obj-y += qcom/ diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile deleted file mode 100644 index 33e8a12f7890..000000000000 --- a/drivers/soc/qcom/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-y += qdsp6v2/ diff --git a/drivers/soc/qcom/qdsp6v2/Makefile b/drivers/soc/qcom/qdsp6v2/Makefile deleted file mode 100644 index 9fdd63a45857..000000000000 --- a/drivers/soc/qcom/qdsp6v2/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -obj-$(CONFIG_MSM_QDSP6_APRV2_GLINK) += apr.o apr_v2.o apr_tal_glink.o -obj-$(CONFIG_MSM_QDSP6_APRV3_GLINK) += apr.o apr_v3.o apr_tal_glink.o -obj-$(CONFIG_SND_SOC_MSM_QDSP6V2_INTF) += msm_audio_ion.o -obj-$(CONFIG_MSM_ADSP_LOADER) += adsp-loader.o -obj-$(CONFIG_MSM_QDSP6_SSR) += audio_ssr.o -obj-$(CONFIG_MSM_QDSP6_PDR) += audio_pdr.o -obj-$(CONFIG_MSM_QDSP6_NOTIFIER) += audio_notifier.o -obj-$(CONFIG_MSM_CDSP_LOADER) += cdsp-loader.o diff --git a/drivers/soundwire/Kconfig b/drivers/soundwire/Kconfig deleted file mode 100644 index e1ca532c22f5..000000000000 --- a/drivers/soundwire/Kconfig +++ /dev/null @@ -1,17 +0,0 @@ -# -# SOUNDWIRE driver configuration -# -menuconfig SOUNDWIRE - bool "Soundwire support" - help - Soundwire is a two wire interface for audio to connect - simple peripheral components in mobile devices. - -if SOUNDWIRE -config SOUNDWIRE_WCD_CTRL - depends on WCD9XXX_CODEC_CORE - tristate "QTI WCD CODEC Soundwire controller" - default n - help - Select driver for QTI's Soundwire Master Component. -endif diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile deleted file mode 100644 index 53acff15c4c4..000000000000 --- a/drivers/soundwire/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for kernel soundwire framework. -# -obj-$(CONFIG_SOUNDWIRE) += soundwire.o -obj-$(CONFIG_SOUNDWIRE_WCD_CTRL) += swr-wcd-ctrl.o diff --git a/dsp/Makefile b/dsp/Makefile new file mode 100644 index 000000000000..a31aeb22a20b --- /dev/null +++ b/dsp/Makefile @@ -0,0 +1,10 @@ +obj-$(CONFIG_SND_SOC_MSM_QDSP6V2_INTF) += audio_calibration.o audio_cal_utils.o \ + q6adm.o q6afe.o q6asm.o q6audio-v2.o q6voice.o q6core.o \ + rtac.o q6lsm.o audio_slimslave.o adsp_err.o msm_audio_ion.o +obj-$(CONFIG_MSM_ADSP_LOADER) += adsp-loader.o +obj-$(CONFIG_MSM_QDSP6_SSR) += audio_ssr.o +obj-$(CONFIG_MSM_QDSP6_PDR) += audio_pdr.o +obj-$(CONFIG_MSM_QDSP6_NOTIFIER) += audio_notifier.o +obj-$(CONFIG_MSM_CDSP_LOADER) += cdsp-loader.o +obj-$(CONFIG_MSM_ULTRASOUND) += usf.o usfcdev.o q6usm.o +obj-$(CONFIG_MSM_QDSP6V2_CODECS) += codecs/ diff --git a/drivers/soc/qcom/qdsp6v2/adsp-loader.c b/dsp/adsp-loader.c similarity index 99% rename from drivers/soc/qcom/qdsp6v2/adsp-loader.c rename to dsp/adsp-loader.c index d90267e01505..07eeea4e4c8b 100644 --- a/drivers/soc/qcom/qdsp6v2/adsp-loader.c +++ b/dsp/adsp-loader.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/sound/soc/msm/qdsp6v2/adsp_err.c b/dsp/adsp_err.c similarity index 99% rename from sound/soc/msm/qdsp6v2/adsp_err.c rename to dsp/adsp_err.c index d17bd6ab58be..319efc37cfe1 100644 --- a/sound/soc/msm/qdsp6v2/adsp_err.c +++ b/dsp/adsp_err.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include /* ERROR STRING */ diff --git a/include/linux/qdsp6v2/dsp_debug.h b/dsp/adsp_err.h similarity index 54% rename from include/linux/qdsp6v2/dsp_debug.h rename to dsp/adsp_err.h index bc1cd9ec8743..43be91d6ba8f 100644 --- a/include/linux/qdsp6v2/dsp_debug.h +++ b/dsp/adsp_err.h @@ -1,4 +1,5 @@ -/* Copyright (c) 2010, The Linux Foundation. All rights reserved. +/* + * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -6,17 +7,15 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * */ -#ifndef __DSP_DEBUG_H_ -#define __DSP_DEBUG_H_ -typedef int (*dsp_state_cb)(int state); -int dsp_debug_register(dsp_state_cb ptr); +#ifndef __ADSP_ERR__ +#define __ADSP_ERR__ + +int adsp_err_get_lnx_err_code(u32 adsp_error); -#define DSP_STATE_CRASHED 0x0 -#define DSP_STATE_CRASH_DUMP_DONE 0x1 +char *adsp_err_get_err_str(u32 adsp_error); #endif diff --git a/sound/soc/msm/qdsp6v2/audio_cal_utils.c b/dsp/audio_cal_utils.c similarity index 99% rename from sound/soc/msm/qdsp6v2/audio_cal_utils.c rename to dsp/audio_cal_utils.c index 7e69a7fe28f5..9a9a96aade7d 100644 --- a/sound/soc/msm/qdsp6v2/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include static int unmap_memory(struct cal_type_data *cal_type, struct cal_block_data *cal_block); diff --git a/sound/soc/msm/qdsp6v2/audio_calibration.c b/dsp/audio_calibration.c similarity index 99% rename from sound/soc/msm/qdsp6v2/audio_calibration.c rename to dsp/audio_calibration.c index d709b091a799..59fd464fe061 100644 --- a/sound/soc/msm/qdsp6v2/audio_calibration.c +++ b/dsp/audio_calibration.c @@ -17,9 +17,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include struct audio_cal_client_info { struct list_head list; diff --git a/drivers/soc/qcom/qdsp6v2/audio_notifier.c b/dsp/audio_notifier.c similarity index 99% rename from drivers/soc/qcom/qdsp6v2/audio_notifier.c rename to dsp/audio_notifier.c index 2320fea6e891..bcb5f9d98378 100644 --- a/drivers/soc/qcom/qdsp6v2/audio_notifier.c +++ b/dsp/audio_notifier.c @@ -12,12 +12,12 @@ #include #include -#include -#include -#include #include #include #include +#include +#include "audio_ssr.h" +#include "audio_pdr.h" /* Audio states internal to notifier. Client */ /* used states defined in audio_notifier.h */ diff --git a/drivers/soc/qcom/qdsp6v2/audio_pdr.c b/dsp/audio_pdr.c similarity index 99% rename from drivers/soc/qcom/qdsp6v2/audio_pdr.c rename to dsp/audio_pdr.c index 449d19a80b3e..0edcf0233efb 100644 --- a/drivers/soc/qcom/qdsp6v2/audio_pdr.c +++ b/dsp/audio_pdr.c @@ -12,9 +12,9 @@ #include #include -#include #include #include +#include "audio_pdr.h" static struct pd_qmi_client_data audio_pdr_services[AUDIO_PDR_DOMAIN_MAX] = { { /* AUDIO_PDR_DOMAIN_ADSP */ diff --git a/include/linux/qdsp6v2/audio_pdr.h b/dsp/audio_pdr.h similarity index 100% rename from include/linux/qdsp6v2/audio_pdr.h rename to dsp/audio_pdr.h diff --git a/sound/soc/msm/qdsp6v2/audio_slimslave.c b/dsp/audio_slimslave.c similarity index 100% rename from sound/soc/msm/qdsp6v2/audio_slimslave.c rename to dsp/audio_slimslave.c diff --git a/drivers/soc/qcom/qdsp6v2/audio_ssr.c b/dsp/audio_ssr.c similarity index 98% rename from drivers/soc/qcom/qdsp6v2/audio_ssr.c rename to dsp/audio_ssr.c index a66fb2a63fae..d3880c912cfd 100644 --- a/drivers/soc/qcom/qdsp6v2/audio_ssr.c +++ b/dsp/audio_ssr.c @@ -11,10 +11,10 @@ */ #include -#include #include #include #include +#include "audio_ssr.h" #define SCM_Q6_NMI_CMD 0x1 diff --git a/include/linux/qdsp6v2/audio_ssr.h b/dsp/audio_ssr.h similarity index 100% rename from include/linux/qdsp6v2/audio_ssr.h rename to dsp/audio_ssr.h diff --git a/drivers/soc/qcom/qdsp6v2/cdsp-loader.c b/dsp/cdsp-loader.c similarity index 100% rename from drivers/soc/qcom/qdsp6v2/cdsp-loader.c rename to dsp/cdsp-loader.c diff --git a/drivers/misc/qcom/qdsp6v2/Makefile b/dsp/codecs/Makefile similarity index 92% rename from drivers/misc/qcom/qdsp6v2/Makefile rename to dsp/codecs/Makefile index 90a123adbb7f..f9052190b273 100644 --- a/drivers/misc/qcom/qdsp6v2/Makefile +++ b/dsp/codecs/Makefile @@ -3,4 +3,3 @@ obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_wma.o audio_wmapro.o audio_aac.o audio obj-$(CONFIG_MSM_QDSP6V2_CODECS) += q6audio_v2.o q6audio_v2_aio.o obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_g711mlaw.o audio_g711alaw.o obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_mp3.o audio_amrnb.o audio_amrwb.o audio_amrwbplus.o audio_evrc.o audio_qcelp.o amrwb_in.o audio_hwacc_effects.o -obj-$(CONFIG_MSM_ULTRASOUND) += ultrasound/ diff --git a/drivers/misc/qcom/qdsp6v2/aac_in.c b/dsp/codecs/aac_in.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/aac_in.c rename to dsp/codecs/aac_in.c diff --git a/drivers/misc/qcom/qdsp6v2/amrnb_in.c b/dsp/codecs/amrnb_in.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/amrnb_in.c rename to dsp/codecs/amrnb_in.c diff --git a/drivers/misc/qcom/qdsp6v2/amrwb_in.c b/dsp/codecs/amrwb_in.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/amrwb_in.c rename to dsp/codecs/amrwb_in.c diff --git a/drivers/misc/qcom/qdsp6v2/audio_aac.c b/dsp/codecs/audio_aac.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_aac.c rename to dsp/codecs/audio_aac.c diff --git a/drivers/misc/qcom/qdsp6v2/audio_alac.c b/dsp/codecs/audio_alac.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_alac.c rename to dsp/codecs/audio_alac.c diff --git a/drivers/misc/qcom/qdsp6v2/audio_amrnb.c b/dsp/codecs/audio_amrnb.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_amrnb.c rename to dsp/codecs/audio_amrnb.c diff --git a/drivers/misc/qcom/qdsp6v2/audio_amrwb.c b/dsp/codecs/audio_amrwb.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_amrwb.c rename to dsp/codecs/audio_amrwb.c diff --git a/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c b/dsp/codecs/audio_amrwbplus.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c rename to dsp/codecs/audio_amrwbplus.c diff --git a/drivers/misc/qcom/qdsp6v2/audio_ape.c b/dsp/codecs/audio_ape.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_ape.c rename to dsp/codecs/audio_ape.c diff --git a/drivers/misc/qcom/qdsp6v2/audio_evrc.c b/dsp/codecs/audio_evrc.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_evrc.c rename to dsp/codecs/audio_evrc.c diff --git a/drivers/misc/qcom/qdsp6v2/audio_g711alaw.c b/dsp/codecs/audio_g711alaw.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_g711alaw.c rename to dsp/codecs/audio_g711alaw.c diff --git a/drivers/misc/qcom/qdsp6v2/audio_g711mlaw.c b/dsp/codecs/audio_g711mlaw.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_g711mlaw.c rename to dsp/codecs/audio_g711mlaw.c diff --git a/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c b/dsp/codecs/audio_hwacc_effects.c similarity index 99% rename from drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c rename to dsp/codecs/audio_hwacc_effects.c index b8972e3d8b6e..9444aa7c6259 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c +++ b/dsp/codecs/audio_hwacc_effects.c @@ -14,8 +14,8 @@ #include #include #include "q6audio_common.h" +#include #include "audio_utils_aio.h" -#include #define MAX_CHANNELS_SUPPORTED 8 #define WAIT_TIMEDOUT_DURATION_SECS 1 diff --git a/drivers/misc/qcom/qdsp6v2/audio_mp3.c b/dsp/codecs/audio_mp3.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_mp3.c rename to dsp/codecs/audio_mp3.c diff --git a/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c b/dsp/codecs/audio_multi_aac.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_multi_aac.c rename to dsp/codecs/audio_multi_aac.c diff --git a/drivers/misc/qcom/qdsp6v2/audio_qcelp.c b/dsp/codecs/audio_qcelp.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_qcelp.c rename to dsp/codecs/audio_qcelp.c diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils.c b/dsp/codecs/audio_utils.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_utils.c rename to dsp/codecs/audio_utils.c diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils.h b/dsp/codecs/audio_utils.h similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_utils.h rename to dsp/codecs/audio_utils.h diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c similarity index 99% rename from drivers/misc/qcom/qdsp6v2/audio_utils_aio.c rename to dsp/codecs/audio_utils_aio.c index 80f6e57e4699..52dced4f3558 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c +++ b/dsp/codecs/audio_utils_aio.c @@ -24,8 +24,8 @@ #include #include #include -#include #include +#include #include "audio_utils_aio.h" #ifdef CONFIG_USE_DEV_CTRL_VOLUME #include diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.h b/dsp/codecs/audio_utils_aio.h similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_utils_aio.h rename to dsp/codecs/audio_utils_aio.h diff --git a/drivers/misc/qcom/qdsp6v2/audio_wma.c b/dsp/codecs/audio_wma.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_wma.c rename to dsp/codecs/audio_wma.c diff --git a/drivers/misc/qcom/qdsp6v2/audio_wmapro.c b/dsp/codecs/audio_wmapro.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/audio_wmapro.c rename to dsp/codecs/audio_wmapro.c diff --git a/drivers/misc/qcom/qdsp6v2/evrc_in.c b/dsp/codecs/evrc_in.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/evrc_in.c rename to dsp/codecs/evrc_in.c diff --git a/drivers/misc/qcom/qdsp6v2/g711alaw_in.c b/dsp/codecs/g711alaw_in.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/g711alaw_in.c rename to dsp/codecs/g711alaw_in.c diff --git a/drivers/misc/qcom/qdsp6v2/g711mlaw_in.c b/dsp/codecs/g711mlaw_in.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/g711mlaw_in.c rename to dsp/codecs/g711mlaw_in.c diff --git a/drivers/misc/qcom/qdsp6v2/q6audio_common.h b/dsp/codecs/q6audio_common.h similarity index 94% rename from drivers/misc/qcom/qdsp6v2/q6audio_common.h rename to dsp/codecs/q6audio_common.h index 49b88b793cc3..75f20e5ac2bd 100644 --- a/drivers/misc/qcom/qdsp6v2/q6audio_common.h +++ b/dsp/codecs/q6audio_common.h @@ -16,8 +16,8 @@ #ifndef __Q6_AUDIO_COMMON_H__ #define __Q6_AUDIO_COMMON_H__ -#include -#include +#include +#include void q6_audio_cb(uint32_t opcode, uint32_t token, diff --git a/drivers/misc/qcom/qdsp6v2/q6audio_v2.c b/dsp/codecs/q6audio_v2.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/q6audio_v2.c rename to dsp/codecs/q6audio_v2.c diff --git a/drivers/misc/qcom/qdsp6v2/q6audio_v2_aio.c b/dsp/codecs/q6audio_v2_aio.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/q6audio_v2_aio.c rename to dsp/codecs/q6audio_v2_aio.c diff --git a/drivers/misc/qcom/qdsp6v2/qcelp_in.c b/dsp/codecs/qcelp_in.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/qcelp_in.c rename to dsp/codecs/qcelp_in.c diff --git a/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c b/dsp/msm_audio_ion.c similarity index 99% rename from drivers/soc/qcom/qdsp6v2/msm_audio_ion.c rename to dsp/msm_audio_ion.c index 2f14c744cd89..24df1aa06714 100644 --- a/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -23,11 +23,11 @@ #include #include #include -#include +#include #include -#include #include #include +#include #define MSM_AUDIO_ION_PROBED (1 << 0) diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/dsp/q6adm.c similarity index 99% rename from sound/soc/msm/qdsp6v2/q6adm.c rename to dsp/q6adm.c index 15906054f2b8..19151139eeff 100644 --- a/sound/soc/msm/qdsp6v2/q6adm.c +++ b/dsp/q6adm.c @@ -17,15 +17,15 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include -#include "msm-dts-srs-tm-config.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include "adsp_err.h" #define TIMEOUT_MS 1000 diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/dsp/q6afe.c similarity index 99% rename from sound/soc/msm/qdsp6v2/q6afe.c rename to dsp/q6afe.c index e1ce947cba48..78be555eb8eb 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/dsp/q6afe.c @@ -18,15 +18,14 @@ #include #include #include -#include #include -#include -#include -#include -#include "msm-pcm-routing-v2.h" -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include "adsp_err.h" #define WAKELOCK_TIMEOUT 5000 enum { diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/dsp/q6asm.c similarity index 99% rename from sound/soc/msm/qdsp6v2/q6asm.c rename to dsp/q6asm.c index e7e161849ff5..28b3f733bcd9 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/dsp/q6asm.c @@ -22,25 +22,25 @@ #include #include #include -#include #include #include #include -#include #include #include #include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include "adsp_err.h" + #define TRUE 0x01 #define FALSE 0x00 #define SESSION_MAX 8 diff --git a/sound/soc/msm/qdsp6v2/q6audio-v2.c b/dsp/q6audio-v2.c similarity index 99% rename from sound/soc/msm/qdsp6v2/q6audio-v2.c rename to dsp/q6audio-v2.c index ea78e6a6538e..6e31c366c798 100644 --- a/sound/soc/msm/qdsp6v2/q6audio-v2.c +++ b/dsp/q6audio-v2.c @@ -16,8 +16,8 @@ #include #include #include -#include -#include +#include +#include int q6audio_get_port_index(u16 port_id) { diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/dsp/q6core.c similarity index 99% rename from sound/soc/msm/qdsp6v2/q6core.c rename to dsp/q6core.c index 3aaaa35e535b..dd97a495221b 100644 --- a/sound/soc/msm/qdsp6v2/q6core.c +++ b/dsp/q6core.c @@ -18,9 +18,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #define TIMEOUT_MS 1000 /* diff --git a/sound/soc/msm/qdsp6v2/q6lsm.c b/dsp/q6lsm.c similarity index 99% rename from sound/soc/msm/qdsp6v2/q6lsm.c rename to dsp/q6lsm.c index 799d1be97ffb..adc541ae0f37 100644 --- a/sound/soc/msm/qdsp6v2/q6lsm.c +++ b/dsp/q6lsm.c @@ -23,16 +23,16 @@ #include #include #include -#include #include -#include -#include #include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include "adsp_err.h" #define APR_TIMEOUT (5 * HZ) #define LSM_ALIGN_BOUNDARY 512 diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c b/dsp/q6usm.c similarity index 99% rename from drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c rename to dsp/q6usm.c index f20f335be3cb..5b822ae99358 100644 --- a/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c +++ b/dsp/q6usm.c @@ -12,13 +12,12 @@ */ #include #include -#include #include #include #include -#include -#include -#include +#include +#include +#include #include "q6usm.h" #define ADSP_MEMORY_MAP_SHMEM8_4K_POOL 3 diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.h b/dsp/q6usm.h similarity index 99% rename from drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.h rename to dsp/q6usm.h index d45d1657c924..2e9d7c9bdb9f 100644 --- a/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.h +++ b/dsp/q6usm.h @@ -13,7 +13,7 @@ #ifndef __Q6_USM_H__ #define __Q6_USM_H__ -#include +#include #define Q6USM_EVENT_UNDEF 0 #define Q6USM_EVENT_READ_DONE 1 diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/dsp/q6voice.c similarity index 99% rename from sound/soc/msm/qdsp6v2/q6voice.c rename to dsp/q6voice.c index 15c9e130f4f4..cfcc822d5484 100644 --- a/sound/soc/msm/qdsp6v2/q6voice.c +++ b/dsp/q6voice.c @@ -16,17 +16,17 @@ #include #include #include -#include #include -#include - -#include "sound/q6audio-v2.h" -#include "sound/apr_audio-v2.h" -#include "sound/q6afe-v2.h" -#include -#include "q6voice.h" -#include + +#include +#include +#include +#include +#include +#include +#include +#include "adsp_err.h" #define TIMEOUT_MS 300 diff --git a/sound/soc/msm/qdsp6v2/rtac.c b/dsp/rtac.c similarity index 99% rename from sound/soc/msm/qdsp6v2/rtac.c rename to dsp/rtac.c index cd02501bac7b..456ac5773d64 100644 --- a/sound/soc/msm/qdsp6v2/rtac.c +++ b/dsp/rtac.c @@ -20,16 +20,15 @@ #include #include #include -#include -#include #include -#include -#include -#include -#include -#include "q6voice.h" -#include "msm-pcm-routing-v2.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include "adsp_err.h" /* Max size of payload (buf size - apr header) */ diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/usf.c b/dsp/usf.c similarity index 99% rename from drivers/misc/qcom/qdsp6v2/ultrasound/usf.c rename to dsp/usf.c index 3da46b647002..dfa2097ddf67 100644 --- a/drivers/misc/qcom/qdsp6v2/ultrasound/usf.c +++ b/dsp/usf.c @@ -24,9 +24,9 @@ #include #include #include -#include -#include +#include #include "q6usm.h" +#include "usf.h" #include "usfcdev.h" /* The driver version*/ diff --git a/include/linux/qdsp6v2/usf.h b/dsp/usf.h similarity index 100% rename from include/linux/qdsp6v2/usf.h rename to dsp/usf.h diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.c b/dsp/usfcdev.c similarity index 100% rename from drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.c rename to dsp/usfcdev.c diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.h b/dsp/usfcdev.h similarity index 100% rename from drivers/misc/qcom/qdsp6v2/ultrasound/usfcdev.h rename to dsp/usfcdev.h diff --git a/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.h b/include/asoc/msm-dts-srs-tm-config.h similarity index 97% rename from sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.h rename to include/asoc/msm-dts-srs-tm-config.h index e3c75b3bd755..c00461b84bf0 100644 --- a/sound/soc/msm/qdsp6v2/msm-dts-srs-tm-config.h +++ b/include/asoc/msm-dts-srs-tm-config.h @@ -1,6 +1,5 @@ /* * Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved. - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. @@ -15,6 +14,7 @@ #define _MSM_DTS_SRS_TM_CONFIG_H_ #include +#include struct param_outband; diff --git a/include/linux/mfd/wcd934x/registers.h b/include/asoc/wcd934x_registers.h similarity index 100% rename from include/linux/mfd/wcd934x/registers.h rename to include/asoc/wcd934x_registers.h diff --git a/include/sound/apr_audio-v2.h b/include/dsp/apr_audio-v2.h similarity index 99% rename from include/sound/apr_audio-v2.h rename to include/dsp/apr_audio-v2.h index 14f644579430..7fb2256bff8b 100644 --- a/include/sound/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -14,7 +14,7 @@ #ifndef _APR_AUDIO_V2_H_ #define _APR_AUDIO_V2_H_ -#include +#include #include /* size of header needed for passing data out of band */ diff --git a/include/sound/audio_cal_utils.h b/include/dsp/audio_cal_utils.h similarity index 97% rename from include/sound/audio_cal_utils.h rename to include/dsp/audio_cal_utils.h index b28b3bdf4e83..e12d8c1a9890 100644 --- a/include/sound/audio_cal_utils.h +++ b/include/dsp/audio_cal_utils.h @@ -14,9 +14,9 @@ #define _AUDIO_CAL_UTILS_H #include -#include #include -#include "audio_calibration.h" +#include +#include struct cal_data { size_t size; diff --git a/include/sound/audio_calibration.h b/include/dsp/audio_calibration.h similarity index 100% rename from include/sound/audio_calibration.h rename to include/dsp/audio_calibration.h diff --git a/include/linux/qdsp6v2/audio_notifier.h b/include/dsp/audio_notifier.h similarity index 100% rename from include/linux/qdsp6v2/audio_notifier.h rename to include/dsp/audio_notifier.h diff --git a/include/sound/msm-audio-effects-q6-v2.h b/include/dsp/msm-audio-effects-q6-v2.h similarity index 100% rename from include/sound/msm-audio-effects-q6-v2.h rename to include/dsp/msm-audio-effects-q6-v2.h diff --git a/include/dsp/msm_audio_ion.h b/include/dsp/msm_audio_ion.h new file mode 100644 index 000000000000..8a2fb6e34b99 --- /dev/null +++ b/include/dsp/msm_audio_ion.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _LINUX_MSM_AUDIO_ION_H +#define _LINUX_MSM_AUDIO_ION_H +#include +#include +#include + + +int msm_audio_ion_alloc(const char *name, struct ion_client **client, + struct ion_handle **handle, size_t bufsz, + ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr); + +int msm_audio_ion_import(const char *name, struct ion_client **client, + struct ion_handle **handle, int fd, + unsigned long *ionflag, size_t bufsz, + ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr); +int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle); +int msm_audio_ion_mmap(struct audio_buffer *substream, + struct vm_area_struct *vma); + +bool msm_audio_ion_is_smmu_available(void); +int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op); + +struct ion_client *msm_audio_ion_client_create(const char *name); +void msm_audio_ion_client_destroy(struct ion_client *client); +int msm_audio_ion_import_legacy(const char *name, struct ion_client *client, + struct ion_handle **handle, int fd, + unsigned long *ionflag, size_t bufsz, + ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr); +int msm_audio_ion_free_legacy(struct ion_client *client, + struct ion_handle *handle); +u32 msm_audio_populate_upper_32_bits(ion_phys_addr_t pa); +#endif /* _LINUX_MSM_AUDIO_ION_H */ diff --git a/include/sound/q6adm-v2.h b/include/dsp/q6adm-v2.h similarity index 98% rename from include/sound/q6adm-v2.h rename to include/dsp/q6adm-v2.h index e689e9357012..013d5229cf08 100644 --- a/include/sound/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -18,9 +18,9 @@ #define ADM_PATH_NONLIVE_REC 0x3 #define ADM_PATH_COMPRESSED_RX 0x5 #define ADM_PATH_COMPRESSED_TX 0x6 -#include -#include -#include +#include +#include +#include #define MAX_MODULES_IN_TOPO 16 #define ADM_GET_TOPO_MODULE_LIST_LENGTH\ diff --git a/include/sound/q6afe-v2.h b/include/dsp/q6afe-v2.h similarity index 99% rename from include/sound/q6afe-v2.h rename to include/dsp/q6afe-v2.h index 836117568d37..7df993e61c1c 100644 --- a/include/sound/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -11,8 +11,8 @@ */ #ifndef __Q6AFE_V2_H__ #define __Q6AFE_V2_H__ -#include -#include +#include +#include #define IN 0x000 #define OUT 0x001 diff --git a/include/sound/q6asm-v2.h b/include/dsp/q6asm-v2.h similarity index 99% rename from include/sound/q6asm-v2.h rename to include/dsp/q6asm-v2.h index 00b46a598280..157c243185b6 100644 --- a/include/sound/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -12,9 +12,9 @@ #ifndef __Q6_ASM_V2_H__ #define __Q6_ASM_V2_H__ -#include -#include -#include +#include +#include +#include #include #include diff --git a/include/sound/q6audio-v2.h b/include/dsp/q6audio-v2.h similarity index 96% rename from include/sound/q6audio-v2.h rename to include/dsp/q6audio-v2.h index fd14f330d1d5..5df88fcbb6f0 100644 --- a/include/sound/q6audio-v2.h +++ b/include/dsp/q6audio-v2.h @@ -13,7 +13,7 @@ #ifndef _Q6_AUDIO_H_ #define _Q6_AUDIO_H_ -#include +#include enum { LEGACY_PCM_MODE = 0, diff --git a/include/sound/q6core.h b/include/dsp/q6core.h similarity index 99% rename from include/sound/q6core.h rename to include/dsp/q6core.h index 0b8309a10a66..c0327ae1f77e 100644 --- a/include/sound/q6core.h +++ b/include/dsp/q6core.h @@ -12,7 +12,7 @@ #ifndef __Q6CORE_H__ #define __Q6CORE_H__ -#include +#include diff --git a/include/sound/q6lsm.h b/include/dsp/q6lsm.h similarity index 99% rename from include/sound/q6lsm.h rename to include/dsp/q6lsm.h index 26106a8db0ce..efce3a6d2076 100644 --- a/include/sound/q6lsm.h +++ b/include/dsp/q6lsm.h @@ -15,9 +15,9 @@ #include #include -#include +#include #include -#include +#include #define MAX_NUM_CONFIDENCE 20 diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/include/dsp/q6voice.h similarity index 99% rename from sound/soc/msm/qdsp6v2/q6voice.h rename to include/dsp/q6voice.h index 74d80be57931..56326b174b38 100644 --- a/sound/soc/msm/qdsp6v2/q6voice.h +++ b/include/dsp/q6voice.h @@ -12,10 +12,10 @@ #ifndef __QDSP6VOICE_H__ #define __QDSP6VOICE_H__ -#include -#include #include #include +#include +#include #define MAX_VOC_PKT_SIZE 642 #define SESSION_NAME_LEN 20 diff --git a/include/linux/qdsp6v2/rtac.h b/include/dsp/rtac.h similarity index 98% rename from include/linux/qdsp6v2/rtac.h rename to include/dsp/rtac.h index b6f4e56db7e7..f8c5556c5455 100644 --- a/include/linux/qdsp6v2/rtac.h +++ b/include/dsp/rtac.h @@ -9,12 +9,13 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. + * */ #ifndef __RTAC_H__ #define __RTAC_H__ -#include +#include /* Voice Modes */ #define RTAC_CVP 0 diff --git a/include/linux/qdsp6v2/apr.h b/include/ipc/apr.h similarity index 100% rename from include/linux/qdsp6v2/apr.h rename to include/ipc/apr.h diff --git a/include/linux/qdsp6v2/apr_tal.h b/include/ipc/apr_tal.h similarity index 100% rename from include/linux/qdsp6v2/apr_tal.h rename to include/ipc/apr_tal.h diff --git a/include/linux/qdsp6v2/apr_us.h b/include/ipc/apr_us.h similarity index 99% rename from include/linux/qdsp6v2/apr_us.h rename to include/ipc/apr_us.h index 9a6804a4d634..6e2f63de9756 100644 --- a/include/linux/qdsp6v2/apr_us.h +++ b/include/ipc/apr_us.h @@ -13,7 +13,7 @@ #ifndef __APR_US_H__ #define __APR_US_H__ -#include +#include /* ======================================================================= */ /* Session Level commands */ diff --git a/include/linux/avtimer_kernel.h b/include/linux/avtimer_kernel.h deleted file mode 100644 index e5a12559f1ba..000000000000 --- a/include/linux/avtimer_kernel.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _AVTIMER_H -#define _AVTIMER_H - -#include - -int avcs_core_open(void); -int avcs_core_disable_power_collapse(int disable);/* true or flase */ -int avcs_core_query_timer(uint64_t *avtimer_tick); - -#endif diff --git a/include/soc/internal.h b/include/soc/internal.h new file mode 120000 index 000000000000..2bc065526db0 --- /dev/null +++ b/include/soc/internal.h @@ -0,0 +1 @@ +../../../../drivers/base/regmap/internal.h \ No newline at end of file diff --git a/include/linux/soundwire/soundwire.h b/include/soc/soundwire.h similarity index 100% rename from include/linux/soundwire/soundwire.h rename to include/soc/soundwire.h diff --git a/include/linux/soundwire/swr-wcd.h b/include/soc/swr-wcd.h similarity index 100% rename from include/linux/soundwire/swr-wcd.h rename to include/soc/swr-wcd.h diff --git a/include/sound/apr_audio.h b/include/sound/apr_audio.h deleted file mode 100644 index eb35645c759f..000000000000 --- a/include/sound/apr_audio.h +++ /dev/null @@ -1,1931 +0,0 @@ -/* - * - * Copyright (c) 2010-2013, 2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _APR_AUDIO_H_ -#define _APR_AUDIO_H_ - -/* ASM opcodes without APR payloads*/ -#include - -/* - * Audio Front End (AFE) - */ - -/* Port ID. Update afe_get_port_index when a new port is added here. */ -#define PRIMARY_I2S_RX 0 /* index = 0 */ -#define PRIMARY_I2S_TX 1 /* index = 1 */ -#define PCM_RX 2 /* index = 2 */ -#define PCM_TX 3 /* index = 3 */ -#define SECONDARY_I2S_RX 4 /* index = 4 */ -#define SECONDARY_I2S_TX 5 /* index = 5 */ -#define MI2S_RX 6 /* index = 6 */ -#define MI2S_TX 7 /* index = 7 */ -#define HDMI_RX 8 /* index = 8 */ -#define RSVD_2 9 /* index = 9 */ -#define RSVD_3 10 /* index = 10 */ -#define DIGI_MIC_TX 11 /* index = 11 */ -#define VOICE_RECORD_RX 0x8003 /* index = 12 */ -#define VOICE_RECORD_TX 0x8004 /* index = 13 */ -#define VOICE_PLAYBACK_TX 0x8005 /* index = 14 */ - -/* Slimbus Multi channel port id pool */ -#define SLIMBUS_0_RX 0x4000 /* index = 15 */ -#define SLIMBUS_0_TX 0x4001 /* index = 16 */ -#define SLIMBUS_1_RX 0x4002 /* index = 17 */ -#define SLIMBUS_1_TX 0x4003 /* index = 18 */ -#define SLIMBUS_2_RX 0x4004 -#define SLIMBUS_2_TX 0x4005 -#define SLIMBUS_3_RX 0x4006 -#define SLIMBUS_3_TX 0x4007 -#define SLIMBUS_4_RX 0x4008 -#define SLIMBUS_4_TX 0x4009 /* index = 24 */ - -#define INT_BT_SCO_RX 0x3000 /* index = 25 */ -#define INT_BT_SCO_TX 0x3001 /* index = 26 */ -#define INT_BT_A2DP_RX 0x3002 /* index = 27 */ -#define INT_FM_RX 0x3004 /* index = 28 */ -#define INT_FM_TX 0x3005 /* index = 29 */ -#define RT_PROXY_PORT_001_RX 0x2000 /* index = 30 */ -#define RT_PROXY_PORT_001_TX 0x2001 /* index = 31 */ -#define SECONDARY_PCM_RX 12 /* index = 32 */ -#define SECONDARY_PCM_TX 13 /* index = 33 */ -#define PSEUDOPORT_01 0x8001 /* index =34 */ - -#define AFE_PORT_INVALID 0xFFFF -#define SLIMBUS_EXTPROC_RX AFE_PORT_INVALID - -#define AFE_PORT_CMD_START 0x000100ca - -#define AFE_EVENT_RTPORT_START 0 -#define AFE_EVENT_RTPORT_STOP 1 -#define AFE_EVENT_RTPORT_LOW_WM 2 -#define AFE_EVENT_RTPORT_HI_WM 3 - -struct afe_port_start_command { - struct apr_hdr hdr; - u16 port_id; - u16 gain; /* Q13 */ - u32 sample_rate; /* 8 , 16, 48khz */ -} __packed; - -#define AFE_PORT_CMD_STOP 0x000100cb -struct afe_port_stop_command { - struct apr_hdr hdr; - u16 port_id; - u16 reserved; -} __packed; - -#define AFE_PORT_CMD_APPLY_GAIN 0x000100cc -struct afe_port_gain_command { - struct apr_hdr hdr; - u16 port_id; - u16 gain;/* Q13 */ -} __packed; - -#define AFE_PORT_CMD_SIDETONE_CTL 0x000100cd -struct afe_port_sidetone_command { - struct apr_hdr hdr; - u16 rx_port_id; /* Primary i2s tx = 1 */ - /* PCM tx = 3 */ - /* Secondary i2s tx = 5 */ - /* Mi2s tx = 7 */ - /* Digital mic tx = 11 */ - u16 tx_port_id; /* Primary i2s rx = 0 */ - /* PCM rx = 2 */ - /* Secondary i2s rx = 4 */ - /* Mi2S rx = 6 */ - /* HDMI rx = 8 */ - u16 gain; /* Q13 */ - u16 enable; /* 1 = enable, 0 = disable */ -} __packed; - -#define AFE_PORT_CMD_LOOPBACK 0x000100ce -struct afe_loopback_command { - struct apr_hdr hdr; - u16 tx_port_id; /* Primary i2s rx = 0 */ - /* PCM rx = 2 */ - /* Secondary i2s rx = 4 */ - /* Mi2S rx = 6 */ - /* HDMI rx = 8 */ - u16 rx_port_id; /* Primary i2s tx = 1 */ - /* PCM tx = 3 */ - /* Secondary i2s tx = 5 */ - /* Mi2s tx = 7 */ - /* Digital mic tx = 11 */ - u16 mode; /* Default -1, DSP will conver - * the tx to rx format - */ - u16 enable; /* 1 = enable, 0 = disable */ -} __packed; - -#define AFE_PSEUDOPORT_CMD_START 0x000100cf -struct afe_pseudoport_start_command { - struct apr_hdr hdr; - u16 port_id; /* Pseudo Port 1 = 0x8000 */ - /* Pseudo Port 2 = 0x8001 */ - /* Pseudo Port 3 = 0x8002 */ - u16 timing; /* FTRT = 0 , AVTimer = 1, */ -} __packed; - -#define AFE_PSEUDOPORT_CMD_STOP 0x000100d0 -struct afe_pseudoport_stop_command { - struct apr_hdr hdr; - u16 port_id; /* Pseudo Port 1 = 0x8000 */ - /* Pseudo Port 2 = 0x8001 */ - /* Pseudo Port 3 = 0x8002 */ - u16 reserved; -} __packed; - -#define AFE_CMD_GET_ACTIVE_PORTS 0x000100d1 - - -#define AFE_CMD_GET_ACTIVE_HANDLES_FOR_PORT 0x000100d2 -struct afe_get_active_handles_command { - struct apr_hdr hdr; - u16 port_id; - u16 reserved; -} __packed; - -/* - * Opcode for AFE to start DTMF. - */ -#define AFE_PORTS_CMD_DTMF_CTL 0x00010102 - -/** DTMF payload.*/ -struct afe_dtmf_generation_command { - struct apr_hdr hdr; - - /* - * Duration of the DTMF tone in ms. - * -1 -> continuous, - * 0 -> disable - */ - int64_t duration_in_ms; - - /* - * The DTMF high tone frequency. - */ - uint16_t high_freq; - - /* - * The DTMF low tone frequency. - */ - uint16_t low_freq; - - /* - * The DTMF volume setting - */ - uint16_t gain; - - /* - * The number of ports to enable/disable on. - */ - uint16_t num_ports; - - /* - * The Destination ports - array . - * For DTMF on multiple ports, portIds needs to - * be populated numPorts times. - */ - uint16_t port_ids; - - /* - * variable for 32 bit alignment of APR packet. - */ - uint16_t reserved; -} __packed; - -#define AFE_PCM_CFG_MODE_PCM 0x0 -#define AFE_PCM_CFG_MODE_AUX 0x1 -#define AFE_PCM_CFG_SYNC_EXT 0x0 -#define AFE_PCM_CFG_SYNC_INT 0x1 -#define AFE_PCM_CFG_FRM_8BPF 0x0 -#define AFE_PCM_CFG_FRM_16BPF 0x1 -#define AFE_PCM_CFG_FRM_32BPF 0x2 -#define AFE_PCM_CFG_FRM_64BPF 0x3 -#define AFE_PCM_CFG_FRM_128BPF 0x4 -#define AFE_PCM_CFG_FRM_256BPF 0x5 -#define AFE_PCM_CFG_QUANT_ALAW_NOPAD 0x0 -#define AFE_PCM_CFG_QUANT_MULAW_NOPAD 0x1 -#define AFE_PCM_CFG_QUANT_LINEAR_NOPAD 0x2 -#define AFE_PCM_CFG_QUANT_ALAW_PAD 0x3 -#define AFE_PCM_CFG_QUANT_MULAW_PAD 0x4 -#define AFE_PCM_CFG_QUANT_LINEAR_PAD 0x5 -#define AFE_PCM_CFG_CDATAOE_MASTER 0x0 -#define AFE_PCM_CFG_CDATAOE_SHARE 0x1 - -struct afe_port_pcm_cfg { - u16 mode; /* PCM (short sync) = 0, AUXPCM (long sync) = 1 */ - u16 sync; /* external = 0 , internal = 1 */ - u16 frame; /* 8 bpf = 0 */ - /* 16 bpf = 1 */ - /* 32 bpf = 2 */ - /* 64 bpf = 3 */ - /* 128 bpf = 4 */ - /* 256 bpf = 5 */ - u16 quant; - u16 slot; /* Slot for PCM stream , 0 - 31 */ - u16 data; /* 0, PCM block is the only master */ - /* 1, PCM block is shares to driver data out signal */ - /* other master */ - u16 reserved; -} __packed; - -enum { - AFE_I2S_SD0 = 1, - AFE_I2S_SD1, - AFE_I2S_SD2, - AFE_I2S_SD3, - AFE_I2S_QUAD01, - AFE_I2S_QUAD23, - AFE_I2S_6CHS, - AFE_I2S_8CHS, -}; - -#define AFE_MI2S_MONO 0 -#define AFE_MI2S_STEREO 3 -#define AFE_MI2S_4CHANNELS 4 -#define AFE_MI2S_6CHANNELS 6 -#define AFE_MI2S_8CHANNELS 8 - -struct afe_port_mi2s_cfg { - u16 bitwidth; /* 16,24,32 */ - u16 line; /* Called ChannelMode in documentation */ - /* i2s_sd0 = 1 */ - /* i2s_sd1 = 2 */ - /* i2s_sd2 = 3 */ - /* i2s_sd3 = 4 */ - /* i2s_quad01 = 5 */ - /* i2s_quad23 = 6 */ - /* i2s_6chs = 7 */ - /* i2s_8chs = 8 */ - u16 channel; /* Called MonoStereo in documentation */ - /* i2s mono = 0 */ - /* i2s mono right = 1 */ - /* i2s mono left = 2 */ - /* i2s stereo = 3 */ - u16 ws; /* 0, word select signal from external source */ - /* 1, word select signal from internal source */ - u16 format; /* don't touch this field if it is not for */ - /* AFE_PORT_CMD_I2S_CONFIG opcode */ -} __packed; - -struct afe_port_hdmi_cfg { - u16 bitwidth; /* 16,24,32 */ - u16 channel_mode; /* HDMI Stereo = 0 */ - /* HDMI_3Point1 (4-ch) = 1 */ - /* HDMI_5Point1 (6-ch) = 2 */ - /* HDMI_6Point1 (8-ch) = 3 */ - u16 data_type; /* HDMI_Linear = 0 */ - /* HDMI_non_Linear = 1 */ -} __packed; - - -struct afe_port_hdmi_multi_ch_cfg { - u16 data_type; /* HDMI_Linear = 0 */ - /* HDMI_non_Linear = 1 */ - u16 channel_allocation; /* The default is 0 (Stereo) */ - u16 reserved; /* must be set to 0 */ -} __packed; - - -/* Slimbus Device Ids */ -#define AFE_SLIMBUS_DEVICE_1 0x0 -#define AFE_SLIMBUS_DEVICE_2 0x1 -#define AFE_PORT_MAX_AUDIO_CHAN_CNT 16 - -struct afe_port_slimbus_cfg { - u16 slimbus_dev_id; /* SLIMBUS Device id.*/ - - u16 slave_dev_pgd_la; /* Slave ported generic device - * logical address. - */ - u16 slave_dev_intfdev_la; /* Slave interface device logical - * address. - */ - u16 bit_width; /* bit width of the samples, 16, 24.*/ - - u16 data_format; /* data format.*/ - - u16 num_channels; /* Number of channels.*/ - - /* Slave port mapping for respective channels.*/ - u16 slave_port_mapping[AFE_PORT_MAX_AUDIO_CHAN_CNT]; - - u16 reserved; -} __packed; - -struct afe_port_slimbus_sch_cfg { - u16 slimbus_dev_id; /* SLIMBUS Device id.*/ - u16 bit_width; /* bit width of the samples, 16, 24.*/ - u16 data_format; /* data format.*/ - u16 num_channels; /* Number of channels.*/ - u16 reserved; - /* Slave channel mapping for respective channels.*/ - u8 slave_ch_mapping[8]; -} __packed; - -struct afe_port_rtproxy_cfg { - u16 bitwidth; /* 16,24,32 */ - u16 interleaved; /* interleaved = 1 */ - /* Noninterleaved = 0 */ - u16 frame_sz; /* 5ms buffers = 160bytes */ - u16 jitter; /* 10ms of jitter = 320 */ - u16 lw_mark; /* Low watermark in bytes for triggering event*/ - u16 hw_mark; /* High watermark bytes for triggering event*/ - u16 rsvd; - int num_ch; /* 1 to 8 */ -} __packed; - -struct afe_port_pseudo_cfg { - u16 bit_width; - u16 num_channels; - u16 data_format; - u16 timing_mode; - u16 reserved; -} __packed; - -#define AFE_PORT_AUDIO_IF_CONFIG 0x000100d3 -#define AFE_PORT_AUDIO_SLIM_SCH_CONFIG 0x000100e4 -#define AFE_PORT_MULTI_CHAN_HDMI_AUDIO_IF_CONFIG 0x000100D9 -#define AFE_PORT_CMD_I2S_CONFIG 0x000100E7 - -union afe_port_config { - struct afe_port_pcm_cfg pcm; - struct afe_port_mi2s_cfg mi2s; - struct afe_port_hdmi_cfg hdmi; - struct afe_port_hdmi_multi_ch_cfg hdmi_multi_ch; - struct afe_port_slimbus_cfg slimbus; - struct afe_port_slimbus_sch_cfg slim_sch; - struct afe_port_rtproxy_cfg rtproxy; - struct afe_port_pseudo_cfg pseudo; -} __packed; - -struct afe_audioif_config_command { - struct apr_hdr hdr; - u16 port_id; - union afe_port_config port; -} __packed; - -#define AFE_TEST_CODEC_LOOPBACK_CTL 0x000100d5 -struct afe_codec_loopback_command { - u16 port_inf; /* Primary i2s = 0 */ - /* PCM = 2 */ - /* Secondary i2s = 4 */ - /* Mi2s = 6 */ - u16 enable; /* 0, disable. 1, enable */ -} __packed; - - -#define AFE_PARAM_ID_SIDETONE_GAIN 0x00010300 -struct afe_param_sidetone_gain { - u16 gain; - u16 reserved; -} __packed; - -#define AFE_PARAM_ID_SAMPLING_RATE 0x00010301 -struct afe_param_sampling_rate { - u32 sampling_rate; -} __packed; - - -#define AFE_PARAM_ID_CHANNELS 0x00010302 -struct afe_param_channels { - u16 channels; - u16 reserved; -} __packed; - - -#define AFE_PARAM_ID_LOOPBACK_GAIN 0x00010303 -struct afe_param_loopback_gain { - u16 gain; - u16 reserved; -} __packed; - -/* Parameter ID used to configure and enable/disable the loopback path. The - * difference with respect to the existing API, AFE_PORT_CMD_LOOPBACK, is that - * it allows Rx port to be configured as source port in loopback path. Port-id - * in AFE_PORT_CMD_SET_PARAM cmd is the source port which can be Tx or Rx port. - * In addition, we can configure the type of routing mode to handle different - * use cases. - */ -enum { - /* Regular loopback from source to destination port */ - LB_MODE_DEFAULT = 1, - /* Sidetone feed from Tx source to Rx destination port */ - LB_MODE_SIDETONE, - /* Echo canceller reference, voice + audio + DTMF */ - LB_MODE_EC_REF_VOICE_AUDIO, - /* Echo canceller reference, voice alone */ - LB_MODE_EC_REF_VOICE -}; - -#define AFE_PARAM_ID_LOOPBACK_CONFIG 0x0001020B -#define AFE_API_VERSION_LOOPBACK_CONFIG 0x1 -struct afe_param_loopback_cfg { - /* Minor version used for tracking the version of the configuration - * interface. - */ - uint32_t loopback_cfg_minor_version; - - /* Destination Port Id. */ - uint16_t dst_port_id; - - /* Specifies data path type from src to dest port. Supported values: - * LB_MODE_DEFAULT - * LB_MODE_SIDETONE - * LB_MODE_EC_REF_VOICE_AUDIO - * LB_MODE_EC_REF_VOICE - */ - uint16_t routing_mode; - - /* Specifies whether to enable (1) or disable (0) an AFE loopback. */ - uint16_t enable; - - /* Reserved for 32-bit alignment. This field must be set to 0. */ - uint16_t reserved; -} __packed; - -#define AFE_MODULE_ID_PORT_INFO 0x00010200 -/* Module ID for the loopback-related parameters. */ -#define AFE_MODULE_LOOPBACK 0x00010205 -struct afe_param_payload_base { - u32 module_id; - u32 param_id; - u16 param_size; - u16 reserved; -} __packed; - -struct afe_param_payload { - struct afe_param_payload_base base; - union { - struct afe_param_sidetone_gain sidetone_gain; - struct afe_param_sampling_rate sampling_rate; - struct afe_param_channels channels; - struct afe_param_loopback_gain loopback_gain; - struct afe_param_loopback_cfg loopback_cfg; - } __packed param; -} __packed; - -#define AFE_PORT_CMD_SET_PARAM 0x000100dc - -struct afe_port_cmd_set_param { - struct apr_hdr hdr; - u16 port_id; - u16 payload_size; - u32 payload_address; - struct afe_param_payload payload; -} __packed; - -struct afe_port_cmd_set_param_no_payload { - struct apr_hdr hdr; - u16 port_id; - u16 payload_size; - u32 payload_address; -} __packed; - -#define AFE_EVENT_GET_ACTIVE_PORTS 0x00010100 -struct afe_get_active_ports_rsp { - u16 num_ports; - u16 port_id; -} __packed; - - -#define AFE_EVENT_GET_ACTIVE_HANDLES 0x00010102 -struct afe_get_active_handles_rsp { - u16 port_id; - u16 num_handles; - u16 mode; /* 0, voice rx */ - /* 1, voice tx */ - /* 2, audio rx */ - /* 3, audio tx */ - u16 handle; -} __packed; - -#define AFE_SERVICE_CMD_MEMORY_MAP 0x000100DE -struct afe_cmd_memory_map { - struct apr_hdr hdr; - u32 phy_addr; - u32 mem_sz; - u16 mem_id; - u16 rsvd; -} __packed; - -#define AFE_SERVICE_CMD_MEMORY_UNMAP 0x000100DF -struct afe_cmd_memory_unmap { - struct apr_hdr hdr; - u32 phy_addr; -} __packed; - -#define AFE_SERVICE_CMD_REG_RTPORT 0x000100E0 -struct afe_cmd_reg_rtport { - struct apr_hdr hdr; - u16 port_id; - u16 rsvd; -} __packed; - -#define AFE_SERVICE_CMD_UNREG_RTPORT 0x000100E1 -struct afe_cmd_unreg_rtport { - struct apr_hdr hdr; - u16 port_id; - u16 rsvd; -} __packed; - -#define AFE_SERVICE_CMD_RTPORT_WR 0x000100E2 -struct afe_cmd_rtport_wr { - struct apr_hdr hdr; - u16 port_id; - u16 rsvd; - u32 buf_addr; - u32 bytes_avail; -} __packed; - -#define AFE_SERVICE_CMD_RTPORT_RD 0x000100E3 -struct afe_cmd_rtport_rd { - struct apr_hdr hdr; - u16 port_id; - u16 rsvd; - u32 buf_addr; - u32 bytes_avail; -} __packed; - -#define AFE_EVENT_RT_PROXY_PORT_STATUS 0x00010105 - -#define ADM_MAX_COPPS 5 - -#define ADM_SERVICE_CMD_GET_COPP_HANDLES 0x00010300 -struct adm_get_copp_handles_command { - struct apr_hdr hdr; -} __packed; - -#define ADM_CMD_MATRIX_MAP_ROUTINGS 0x00010301 -struct adm_routings_session { - u16 id; - u16 num_copps; - u16 copp_id[ADM_MAX_COPPS+1]; /*Padding if numCopps is odd */ -} __packed; - -struct adm_routings_command { - struct apr_hdr hdr; - u32 path; /* 0 = Rx, 1 Tx */ - u32 num_sessions; - struct adm_routings_session session[8]; -} __packed; - - -#define ADM_CMD_MATRIX_RAMP_GAINS 0x00010302 -struct adm_ramp_gain { - struct apr_hdr hdr; - u16 session_id; - u16 copp_id; - u16 initial_gain; - u16 gain_increment; - u16 ramp_duration; - u16 reserved; -} __packed; - -struct adm_ramp_gains_command { - struct apr_hdr hdr; - u32 id; - u32 num_gains; - struct adm_ramp_gain gains[ADM_MAX_COPPS]; -} __packed; - - -#define ADM_CMD_COPP_OPEN 0x00010304 -struct adm_copp_open_command { - struct apr_hdr hdr; - u16 flags; - u16 mode; /* 1-RX, 2-Live TX, 3-Non Live TX */ - u16 endpoint_id1; - u16 endpoint_id2; - u32 topology_id; - u16 channel_config; - u16 reserved; - u32 rate; -} __packed; - -#define ADM_CMD_COPP_CLOSE 0x00010305 - -#define ADM_CMD_MULTI_CHANNEL_COPP_OPEN 0x00010310 -#define ADM_CMD_MULTI_CHANNEL_COPP_OPEN_V3 0x00010333 -struct adm_multi_ch_copp_open_command { - struct apr_hdr hdr; - u16 flags; - u16 mode; /* 1-RX, 2-Live TX, 3-Non Live TX */ - u16 endpoint_id1; - u16 endpoint_id2; - u32 topology_id; - u16 channel_config; - u16 reserved; - u32 rate; - u8 dev_channel_mapping[8]; -} __packed; - -struct adm_multi_channel_copp_open_v3 { - struct apr_hdr hdr; - u16 flags; - u16 mode; - u16 endpoint_id1; - u16 endpoint_id2; - u32 topology_id; - u16 channel_config; - u16 bit_width; - u32 rate; - u8 dev_channel_mapping[8]; -}; - -#define ADM_CMD_MEMORY_MAP 0x00010C30 -struct adm_cmd_memory_map { - struct apr_hdr hdr; - u32 buf_add; - u32 buf_size; - u16 mempool_id; - u16 reserved; -} __packed; - -#define ADM_CMD_MEMORY_UNMAP 0x00010C31 -struct adm_cmd_memory_unmap { - struct apr_hdr hdr; - u32 buf_add; -} __packed; - -#define ADM_CMD_MEMORY_MAP_REGIONS 0x00010C47 -struct adm_memory_map_regions { - u32 phys; - u32 buf_size; -} __packed; - -struct adm_cmd_memory_map_regions { - struct apr_hdr hdr; - u16 mempool_id; - u16 nregions; -} __packed; - -#define ADM_CMD_MEMORY_UNMAP_REGIONS 0x00010C48 -struct adm_memory_unmap_regions { - u32 phys; -} __packed; - -struct adm_cmd_memory_unmap_regions { - struct apr_hdr hdr; - u16 nregions; - u16 reserved; -} __packed; - -#define DEFAULT_COPP_TOPOLOGY 0x00010be3 -#define DEFAULT_POPP_TOPOLOGY 0x00010be4 -#define VPM_TX_SM_ECNS_COPP_TOPOLOGY 0x00010F71 -#define VPM_TX_DM_FLUENCE_COPP_TOPOLOGY 0x00010F72 -#define VPM_TX_QMIC_FLUENCE_COPP_TOPOLOGY 0x00010F75 - -#define LOWLATENCY_POPP_TOPOLOGY 0x00010C68 -#define LOWLATENCY_COPP_TOPOLOGY 0x00010312 -#define PCM_BITS_PER_SAMPLE 16 - -#define ASM_OPEN_WRITE_PERF_MODE_BIT (1<<28) -#define ASM_OPEN_READ_PERF_MODE_BIT (1<<29) -#define ADM_MULTI_CH_COPP_OPEN_PERF_MODE_BIT (1<<13) - - -#define ASM_MAX_EQ_BANDS 12 - -struct asm_eq_band { - u32 band_idx; /* The band index, 0 .. 11 */ - u32 filter_type; /* Filter band type */ - u32 center_freq_hz; /* Filter band center frequency */ - u32 filter_gain; /* Filter band initial gain (dB) */ - /* Range is +12 dB to -12 dB with 1dB increments. */ - u32 q_factor; -} __packed; - -struct asm_equalizer_params { - u32 enable; - u32 num_bands; - struct asm_eq_band eq_bands[ASM_MAX_EQ_BANDS]; -} __packed; - -struct asm_master_gain_params { - u16 master_gain; - u16 padding; -} __packed; - -struct asm_lrchannel_gain_params { - u16 left_gain; - u16 right_gain; -} __packed; - -struct asm_mute_params { - u32 muteflag; -} __packed; - -struct asm_softvolume_params { - u32 period; - u32 step; - u32 rampingcurve; -} __packed; - -struct asm_softpause_params { - u32 enable; - u32 period; - u32 step; - u32 rampingcurve; -} __packed; - -struct asm_pp_param_data_hdr { - u32 module_id; - u32 param_id; - u16 param_size; - u16 reserved; -} __packed; - -struct asm_pp_params_command { - struct apr_hdr hdr; - u32 *payload; - u32 payload_size; - struct asm_pp_param_data_hdr params; -} __packed; - -#define EQUALIZER_MODULE_ID 0x00010c27 -#define EQUALIZER_PARAM_ID 0x00010c28 - -#define VOLUME_CONTROL_MODULE_ID 0x00010bfe -#define MASTER_GAIN_PARAM_ID 0x00010bff -#define L_R_CHANNEL_GAIN_PARAM_ID 0x00010c00 -#define MUTE_CONFIG_PARAM_ID 0x00010c01 -#define SOFT_PAUSE_PARAM_ID 0x00010D6A -#define SOFT_VOLUME_PARAM_ID 0x00010C29 - -#define IIR_FILTER_ENABLE_PARAM_ID 0x00010c03 -#define IIR_FILTER_PREGAIN_PARAM_ID 0x00010c04 -#define IIR_FILTER_CONFIG_PARAM_ID 0x00010c05 - -#define MBADRC_MODULE_ID 0x00010c06 -#define MBADRC_ENABLE_PARAM_ID 0x00010c07 -#define MBADRC_CONFIG_PARAM_ID 0x00010c08 - - -#define ADM_CMD_SET_PARAMS 0x00010306 -#define ADM_CMD_GET_PARAMS 0x0001030B -#define ADM_CMDRSP_GET_PARAMS 0x0001030C -struct adm_set_params_command { - struct apr_hdr hdr; - u32 payload; - u32 payload_size; -} __packed; - - -#define ADM_CMD_TAP_COPP_PCM 0x00010307 -struct adm_tap_copp_pcm_command { - struct apr_hdr hdr; -} __packed; - - -/* QDSP6 to Client messages */ -#define ADM_SERVICE_CMDRSP_GET_COPP_HANDLES 0x00010308 -struct adm_get_copp_handles_respond { - struct apr_hdr hdr; - u32 handles; - u32 copp_id; -} __packed; - -#define ADM_CMDRSP_COPP_OPEN 0x0001030A -struct adm_copp_open_respond { - u32 status; - u16 copp_id; - u16 reserved; -} __packed; - -#define ADM_CMDRSP_MULTI_CHANNEL_COPP_OPEN 0x00010311 -#define ADM_CMDRSP_MULTI_CHANNEL_COPP_OPEN_V3 0x00010334 - - -#define ASM_STREAM_PRIORITY_NORMAL 0 -#define ASM_STREAM_PRIORITY_LOW 1 -#define ASM_STREAM_PRIORITY_HIGH 2 -#define ASM_STREAM_PRIORITY_RESERVED 3 - -#define ASM_END_POINT_DEVICE_MATRIX 0 -#define ASM_END_POINT_STREAM 1 - -#define AAC_ENC_MODE_AAC_LC 0x02 -#define AAC_ENC_MODE_AAC_P 0x05 -#define AAC_ENC_MODE_EAAC_P 0x1D - -#define ASM_STREAM_CMD_CLOSE 0x00010BCD -#define ASM_STREAM_CMD_FLUSH 0x00010BCE -#define ASM_STREAM_CMD_SET_PP_PARAMS 0x00010BCF -#define ASM_STREAM_CMD_GET_PP_PARAMS 0x00010BD0 -#define ASM_STREAM_CMDRSP_GET_PP_PARAMS 0x00010BD1 -#define ASM_SESSION_CMD_PAUSE 0x00010BD3 -#define ASM_SESSION_CMD_GET_SESSION_TIME 0x00010BD4 -#define ASM_DATA_CMD_EOS 0x00010BDB -#define ASM_DATA_EVENT_EOS 0x00010BDD - -#define ASM_SERVICE_CMD_GET_STREAM_HANDLES 0x00010C0B -#define ASM_STREAM_CMD_FLUSH_READBUFS 0x00010C09 - -#define ASM_SESSION_EVENT_RX_UNDERFLOW 0x00010C17 -#define ASM_SESSION_EVENT_TX_OVERFLOW 0x00010C18 -#define ASM_SERVICE_CMD_GET_WALLCLOCK_TIME 0x00010C19 -#define ASM_DATA_CMDRSP_EOS 0x00010C1C - -/* ASM Data structures */ - -/* common declarations */ -struct asm_pcm_cfg { - u16 ch_cfg; - u16 bits_per_sample; - u32 sample_rate; - u16 is_signed; - u16 interleaved; -}; - -#define PCM_CHANNEL_NULL 0 - -/* Front left channel. */ -#define PCM_CHANNEL_FL 1 - -/* Front right channel. */ -#define PCM_CHANNEL_FR 2 - -/* Front center channel. */ -#define PCM_CHANNEL_FC 3 - -/* Left surround channel.*/ -#define PCM_CHANNEL_LS 4 - -/* Right surround channel.*/ -#define PCM_CHANNEL_RS 5 - -/* Low frequency effect channel. */ -#define PCM_CHANNEL_LFE 6 - -/* Center surround channel; Rear center channel. */ -#define PCM_CHANNEL_CS 7 - -/* Left back channel; Rear left channel. */ -#define PCM_CHANNEL_LB 8 - -/* Right back channel; Rear right channel. */ -#define PCM_CHANNEL_RB 9 - -/* Top surround channel. */ -#define PCM_CHANNEL_TS 10 - -/* Center vertical height channel.*/ -#define PCM_CHANNEL_CVH 11 - -/* Mono surround channel.*/ -#define PCM_CHANNEL_MS 12 - -/* Front left of center. */ -#define PCM_CHANNEL_FLC 13 - -/* Front right of center. */ -#define PCM_CHANNEL_FRC 14 - -/* Rear left of center. */ -#define PCM_CHANNEL_RLC 15 - -/* Rear right of center. */ -#define PCM_CHANNEL_RRC 16 - -#define PCM_FORMAT_MAX_NUM_CHANNEL 8 - -/* Maximum number of channels supported - * in ASM_ENCDEC_DEC_CHAN_MAP command - */ -#define MAX_CHAN_MAP_CHANNELS 16 -/* - * Multiple-channel PCM decoder format block structure used in the - * #ASM_STREAM_CMD_OPEN_WRITE command. - * The data must be in little-endian format. - */ -struct asm_multi_channel_pcm_fmt_blk { - - u16 num_channels; /* - * Number of channels. - * Supported values:1 to 8 - */ - - u16 bits_per_sample; /* - * Number of bits per sample per channel. - * Supported values: 16, 24 When used for - * playback, the client must send 24-bit - * samples packed in 32-bit words. The - * 24-bit samples must be placed in the most - * significant 24 bits of the 32-bit word. When - * used for recording, the aDSP sends 24-bit - * samples packed in 32-bit words. The 24-bit - * samples are placed in the most significant - * 24 bits of the 32-bit word. - */ - - u32 sample_rate; /* - * Number of samples per second - * (in Hertz). Supported values: - * 2000 to 48000 - */ - - u16 is_signed; /* - * Flag that indicates the samples - * are signed (1). - */ - - u16 is_interleaved; /* - * Flag that indicates whether the channels are - * de-interleaved (0) or interleaved (1). - * Interleaved format means corresponding - * samples from the left and right channels are - * interleaved within the buffer. - * De-interleaved format means samples from - * each channel are contiguous in the buffer. - * The samples from one channel immediately - * follow those of the previous channel. - */ - - u8 channel_mapping[8]; /* - * Supported values: - * PCM_CHANNEL_NULL, PCM_CHANNEL_FL, - * PCM_CHANNEL_FR, PCM_CHANNEL_FC, - * PCM_CHANNEL_LS, PCM_CHANNEL_RS, - * PCM_CHANNEL_LFE, PCM_CHANNEL_CS, - * PCM_CHANNEL_LB, PCM_CHANNEL_RB, - * PCM_CHANNEL_TS, PCM_CHANNEL_CVH, - * PCM_CHANNEL_MS, PCM_CHANNEL_FLC, - * PCM_CHANNEL_FRC, PCM_CHANNEL_RLC, - * PCM_CHANNEL_RRC. - * Channel[i] mapping describes channel I. Each - * element i of the array describes channel I - * inside the buffer where I < num_channels. - * An unused channel is set to zero. - */ -}; -struct asm_dts_enc_cfg { - uint32_t sample_rate; - /* - * Samples at which input is to be encoded. - * Supported values: - * 44100 -- encode at 44.1 Khz - * 48000 -- encode at 48 Khz - */ - - uint32_t num_channels; - /* - * Number of channels for multi-channel encoding. - * Supported values: 1 to 6 - */ - - uint8_t channel_mapping[6]; - /* - * Channel array of size 16. Channel[i] mapping describes channel I. - * Each element i of the array describes channel I inside the buffer - * where num_channels. An unused channel is set to zero. Only first - * num_channels elements are valid - * - * Supported values: - * - # PCM_CHANNEL_L - * - # PCM_CHANNEL_R - * - # PCM_CHANNEL_C - * - # PCM_CHANNEL_LS - * - # PCM_CHANNEL_RS - * - # PCM_CHANNEL_LFE - */ - -}; -struct asm_adpcm_cfg { - u16 ch_cfg; - u16 bits_per_sample; - u32 sample_rate; - u32 block_size; -}; - -struct asm_yadpcm_cfg { - u16 ch_cfg; - u16 bits_per_sample; - u32 sample_rate; -}; - -struct asm_midi_cfg { - u32 nMode; -}; - -struct asm_wma_cfg { - u16 format_tag; - u16 ch_cfg; - u32 sample_rate; - u32 avg_bytes_per_sec; - u16 block_align; - u16 valid_bits_per_sample; - u32 ch_mask; - u16 encode_opt; - u16 adv_encode_opt; - u32 adv_encode_opt2; - u32 drc_peak_ref; - u32 drc_peak_target; - u32 drc_ave_ref; - u32 drc_ave_target; -}; - -struct asm_wmapro_cfg { - u16 format_tag; - u16 ch_cfg; - u32 sample_rate; - u32 avg_bytes_per_sec; - u16 block_align; - u16 valid_bits_per_sample; - u32 ch_mask; - u16 encode_opt; - u16 adv_encode_opt; - u32 adv_encode_opt2; - u32 drc_peak_ref; - u32 drc_peak_target; - u32 drc_ave_ref; - u32 drc_ave_target; -}; - -struct asm_aac_cfg { - u16 format; - u16 aot; - u16 ep_config; - u16 section_data_resilience; - u16 scalefactor_data_resilience; - u16 spectral_data_resilience; - u16 ch_cfg; - u16 reserved; - u32 sample_rate; -}; - -struct asm_amrwbplus_cfg { - u32 size_bytes; - u32 version; - u32 num_channels; - u32 amr_band_mode; - u32 amr_dtx_mode; - u32 amr_frame_fmt; - u32 amr_lsf_idx; -}; - -struct asm_flac_cfg { - u16 stream_info_present; - u16 min_blk_size; - u16 max_blk_size; - u16 ch_cfg; - u16 sample_size; - u16 sample_rate; - u16 md5_sum; - u32 ext_sample_rate; - u32 min_frame_size; - u32 max_frame_size; -}; - -struct asm_vorbis_cfg { - u32 ch_cfg; - u32 bit_rate; - u32 min_bit_rate; - u32 max_bit_rate; - u16 bit_depth_pcm_sample; - u16 bit_stream_format; -}; - -struct asm_aac_read_cfg { - u32 bitrate; - u32 enc_mode; - u16 format; - u16 ch_cfg; - u32 sample_rate; -}; - -struct asm_amrnb_read_cfg { - u16 mode; - u16 dtx_mode; -}; - -struct asm_amrwb_read_cfg { - u16 mode; - u16 dtx_mode; -}; - -struct asm_evrc_read_cfg { - u16 max_rate; - u16 min_rate; - u16 rate_modulation_cmd; - u16 reserved; -}; - -struct asm_qcelp13_read_cfg { - u16 max_rate; - u16 min_rate; - u16 reduced_rate_level; - u16 rate_modulation_cmd; -}; - -struct asm_sbc_read_cfg { - u32 subband; - u32 block_len; - u32 ch_mode; - u32 alloc_method; - u32 bit_rate; - u32 sample_rate; -}; - -struct asm_sbc_bitrate { - u32 bitrate; -}; - -struct asm_immed_decode { - u32 mode; -}; - -struct asm_sbr_ps { - u32 enable; -}; - -struct asm_dual_mono { - u16 sce_left; - u16 sce_right; -}; - -struct asm_dec_chan_map { - u32 num_channels; /* Number of decoder output - * channels. A value of 0 - * indicates native channel - * mapping, which is valid - * only for NT mode. This - * means the output of the - * decoder is to be preserved - * as is. - */ - - u8 channel_mapping[MAX_CHAN_MAP_CHANNELS];/* Channel array of size - * num_channels. It can grow - * till MAX_CHAN_MAP_CHANNELS. - * Channel[i] mapping - * describes channel I inside - * the decoder output buffer. - * Valid channel mapping - * values are to be present at - * the beginning of the array. - * All remaining elements of - * the array are to be filled - * with PCM_CHANNEL_NULL. - */ -}; - -struct asm_encode_cfg_blk { - u32 frames_per_buf; - u32 format_id; - u32 cfg_size; - union { - struct asm_pcm_cfg pcm; - struct asm_aac_read_cfg aac; - struct asm_amrnb_read_cfg amrnb; - struct asm_evrc_read_cfg evrc; - struct asm_qcelp13_read_cfg qcelp13; - struct asm_sbc_read_cfg sbc; - struct asm_amrwb_read_cfg amrwb; - struct asm_multi_channel_pcm_fmt_blk mpcm; - struct asm_dts_enc_cfg dts; - } __packed cfg; -}; - -struct asm_frame_meta_info { - u32 offset_to_frame; - u32 frame_size; - u32 encoded_pcm_samples; - u32 msw_ts; - u32 lsw_ts; - u32 nflags; -}; - -/* Stream level commands */ -#define ASM_STREAM_CMD_OPEN_READ 0x00010BCB -#define ASM_STREAM_CMD_OPEN_READ_V2_1 0x00010DB2 -struct asm_stream_cmd_open_read { - struct apr_hdr hdr; - u32 uMode; - u32 src_endpoint; - u32 pre_proc_top; - u32 format; -} __packed; - -struct asm_stream_cmd_open_read_v2_1 { - struct apr_hdr hdr; - u32 uMode; - u32 src_endpoint; - u32 pre_proc_top; - u32 format; - u16 bits_per_sample; - u16 reserved; -} __packed; - -/* Supported formats */ -#define LINEAR_PCM 0x00010BE5 -#define DTMF 0x00010BE6 -#define ADPCM 0x00010BE7 -#define YADPCM 0x00010BE8 -#define MP3 0x00010BE9 -#define MPEG4_AAC 0x00010BEA -#define AMRNB_FS 0x00010BEB -#define AMRWB_FS 0x00010BEC -#define V13K_FS 0x00010BED -#define EVRC_FS 0x00010BEE -#define EVRCB_FS 0x00010BEF -#define EVRCWB_FS 0x00010BF0 -#define MIDI 0x00010BF1 -#define SBC 0x00010BF2 -#define WMA_V10PRO 0x00010BF3 -#define WMA_V9 0x00010BF4 -#define AMR_WB_PLUS 0x00010BF5 -#define AC3_DECODER 0x00010BF6 -#define EAC3_DECODER 0x00010C3C -#define DTS 0x00010D88 -#define DTS_LBR 0x00010DBB -#define MP2 0x00010DBE -#define ATRAC 0x00010D89 -#define MAT 0x00010D8A -#define G711_ALAW_FS 0x00010BF7 -#define G711_MLAW_FS 0x00010BF8 -#define G711_PCM_FS 0x00010BF9 -#define MPEG4_MULTI_AAC 0x00010D86 -#define US_POINT_EPOS_FORMAT 0x00012310 -#define US_RAW_FORMAT 0x0001127C -#define US_PROX_FORMAT 0x0001272B -#define MULTI_CHANNEL_PCM 0x00010C66 - -#define ASM_ENCDEC_SBCRATE 0x00010C13 -#define ASM_ENCDEC_IMMDIATE_DECODE 0x00010C14 -#define ASM_ENCDEC_CFG_BLK 0x00010C2C - -#define ASM_ENCDEC_SBCRATE 0x00010C13 -#define ASM_ENCDEC_IMMDIATE_DECODE 0x00010C14 -#define ASM_ENCDEC_CFG_BLK 0x00010C2C - -#define ASM_STREAM_CMD_OPEN_READ_COMPRESSED 0x00010D95 -struct asm_stream_cmd_open_read_compressed { - struct apr_hdr hdr; - u32 uMode; - u32 frame_per_buf; -} __packed; - -#define ASM_STREAM_CMD_OPEN_WRITE 0x00010BCA -#define ASM_STREAM_CMD_OPEN_WRITE_V2_1 0x00010DB1 -struct asm_stream_cmd_open_write { - struct apr_hdr hdr; - u32 uMode; - u16 sink_endpoint; - u16 stream_handle; - u32 post_proc_top; - u32 format; -} __packed; - -#define IEC_61937_MASK 0x00000001 -#define IEC_60958_MASK 0x00000002 - -#define ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED 0x00010D84 -struct asm_stream_cmd_open_write_compressed { - struct apr_hdr hdr; - u32 flags; - u32 format; -} __packed; -#define ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK 0x00010DBA -struct asm_stream_cmd_open_transcode_loopback { - struct apr_hdr hdr; - uint32_t mode_flags; - /* - * All bits are reserved. Clients must set them to zero. - */ - - uint32_t src_format_id; - /* - * Specifies the media format of the input audio stream. - * - * Supported values: - * - #ASM_MEDIA_FMT_LINEAR_PCM - * - #ASM_MEDIA_FMT_MULTI_CHANNEL_PCM - */ - - uint32_t sink_format_id; - /* - * Specifies the media format of the output stream. - * - * Supported values: - * - #ASM_MEDIA_FMT_LINEAR_PCM - * - #ASM_MEDIA_FMT_MULTI_CHANNEL_PCM - * - #ASM_MEDIA_FMT_DTS - */ - - uint32_t audproc_topo_id; - /* - * Postprocessing topology ID, which specifies the topology (order of - * processing) of postprocessing algorithms. - * - * Supported values: - * - #ASM_STREAM_POSTPROC_TOPO_ID_DEFAULT - * - #ASM_STREAM_POSTPROC_TOPO_ID_PEAKMETER - * - #ASM_STREAM_POSTPROC_TOPO_ID_NONE - * - #ASM_STREAM_POSTPROC_TOPO_ID_MCH_PEAK_VOL - */ - - uint16_t src_endpoint_type; - /* - * Specifies the source endpoint that provides the input samples. - * - * Supported values: - * - 0 -- Tx device matrix or stream router - * (gateway to the hardware ports) - * - All other values are reserved - * - * Clients must set this field to zero. Otherwise, an error is returned. - */ - - uint16_t sink_endpoint_type; - /* - * Specifies the sink endpoint type. - * - * Supported values: - * - 0 -- Rx device matrix or stream router - * (gateway to the hardware ports) - * - All other values are reserved - * - * Clients must set this field to zero. Otherwise, an error is returned. - */ - - uint16_t bits_per_sample; - /* - * Number of bits per sample processed by the ASM modules. - * Supported values: 16, 24 - */ - - uint16_t reserved; - /* - * This field must be set to zero. - */ -} __packed; - -/* - * ID of the DTS mix LFE channel to front channels parameter in the - * #ASM_STREAM_CMD_SET_ENCDEC_PARAM command. - * asm_dts_generic_param_t - * ASM_PARAM_ID_DTS_MIX_LFE_TO_FRONT - */ -#define ASM_PARAM_ID_DTS_MIX_LFE_TO_FRONT 0x00010DB6 - -/* - * ID of the DTS DRC ratio parameter in the - * #ASM_STREAM_CMD_SET_ENCDEC_PARAM command. - * asm_dts_generic_param_t - * ASM_PARAM_ID_DTS_DRC_RATIO - */ -#define ASM_PARAM_ID_DTS_DRC_RATIO 0x00010DB7 - -/* - * ID of the DTS enable dialog normalization parameter in the - * #ASM_STREAM_CMD_SET_ENCDEC_PARAM command. - * - * asm_dts_generic_param_t - * ASM_PARAM_ID_DTS_ENABLE_DIALNORM - */ -#define ASM_PARAM_ID_DTS_ENABLE_DIALNORM 0x00010DB8 - -/* - * ID of the DTS enable parse REV2AUX parameter in the - * #ASM_STREAM_CMD_SET_ENCDEC_PARAM command. - * asm_dts_generic_param_t - * ASM_PARAM_ID_DTS_ENABLE_PARSE_REV2AUX - */ -#define ASM_PARAM_ID_DTS_ENABLE_PARSE_REV2AUX 0x00010DB9 - -struct asm_dts_generic_param { - int32_t generic_parameter; - /* - * #ASM_PARAM_ID_DTS_MIX_LFE_TO_FRONT: - * - if enabled, mixes LFE channel to front - * while downmixing (if necessary) - * - Supported values: 1-> enable, 0-> disable - * - Default: disabled - * - * #ASM_PARAM_ID_DTS_DRC_RATIO: - * - percentage of DRC ratio. - * - Supported values: 0-100 - * - Default: 0, DRC is disabled. - * - * #ASM_PARAM_ID_DTS_ENABLE_DIALNORM: - * - flag to enable dialog normalization post processing. - * - Supported values: 1-> enable, 0-> disable. - * - Default: enabled. - * - * #ASM_PARAM_ID_DTS_ENABLE_PARSE_REV2AUX: - * - flag to enable parsing of rev2aux chunk in the bitstream. - * This chunk contains broadcast metadata. - * - Supported values: 1-> enable, 0-> disable. - * - Default: disabled. - */ -}; - -struct asm_stream_cmd_dts_dec_param { - struct apr_hdr hdr; - u32 param_id; - u32 param_size; - struct asm_dts_generic_param generic_param; -} __packed; - - -#define ASM_STREAM_CMD_OPEN_READWRITE 0x00010BCC - -struct asm_stream_cmd_open_read_write { - struct apr_hdr hdr; - u32 uMode; - u32 post_proc_top; - u32 write_format; - u32 read_format; -} __packed; - -#define ASM_STREAM_CMD_OPEN_LOOPBACK 0x00010D6E -struct asm_stream_cmd_open_loopback { - struct apr_hdr hdr; - u32 mode_flags; -/* Mode flags. - * Bit 0-31: reserved; client should set these bits to 0 - */ - u16 src_endpointype; - /* Endpoint type. 0 = Tx Matrix */ - u16 sink_endpointype; - /* Endpoint type. 0 = Rx Matrix */ - u32 postprocopo_id; -/* Postprocessor topology ID. Specifies the topology of - * postprocessing algorithms. - */ -} __packed; - -#define ADM_CMD_CONNECT_AFE_PORT 0x00010320 -#define ADM_CMD_DISCONNECT_AFE_PORT 0x00010321 - -struct adm_cmd_connect_afe_port { - struct apr_hdr hdr; - u8 mode; /*mode represent the interface is for RX or TX*/ - u8 session_id; /*ASM session ID*/ - u16 afe_port_id; -} __packed; - -#define ADM_CMD_CONNECT_AFE_PORT_V2 0x00010332 - -struct adm_cmd_connect_afe_port_v2 { - struct apr_hdr hdr; - u8 mode; /*mode represent the interface is for RX or TX*/ - u8 session_id; /*ASM session ID*/ - u16 afe_port_id; - u32 num_channels; - u32 sampling_rate; -} __packed; - -#define ASM_STREAM_CMD_SET_ENCDEC_PARAM 0x00010C10 -#define ASM_STREAM_CMD_GET_ENCDEC_PARAM 0x00010C11 -#define ASM_ENCDEC_CFG_BLK_ID 0x00010C2C -#define ASM_ENABLE_SBR_PS 0x00010C63 -#define ASM_CONFIGURE_DUAL_MONO 0x00010C64 -struct asm_stream_cmd_encdec_cfg_blk { - struct apr_hdr hdr; - u32 param_id; - u32 param_size; - struct asm_encode_cfg_blk enc_blk; -} __packed; - -struct asm_stream_cmd_encdec_sbc_bitrate { - struct apr_hdr hdr; - u32 param_id; - struct asm_sbc_bitrate sbc_bitrate; -} __packed; - -struct asm_stream_cmd_encdec_immed_decode { - struct apr_hdr hdr; - u32 param_id; - u32 param_size; - struct asm_immed_decode dec; -} __packed; - -struct asm_stream_cmd_encdec_sbr { - struct apr_hdr hdr; - u32 param_id; - u32 param_size; - struct asm_sbr_ps sbr_ps; -} __packed; - -struct asm_stream_cmd_encdec_dualmono { - struct apr_hdr hdr; - u32 param_id; - u32 param_size; - struct asm_dual_mono channel_map; -} __packed; - -#define ASM_PARAM_ID_AAC_STEREO_MIX_COEFF_SELECTION_FLAG 0x00010DD8 - -/* Structure for AAC decoder stereo coefficient setting. */ - -struct asm_aac_stereo_mix_coeff_selection_param { - struct apr_hdr hdr; - u32 param_id; - u32 param_size; - u32 aac_stereo_mix_coeff_flag; -} __packed; - -#define ASM_ENCDEC_DEC_CHAN_MAP 0x00010D82 -struct asm_stream_cmd_encdec_channelmap { - struct apr_hdr hdr; - u32 param_id; - u32 param_size; - struct asm_dec_chan_map chan_map; -} __packed; - -#define ASM_STREAM_CMD_ADJUST_SAMPLES 0x00010C0A -struct asm_stream_cmd_adjust_samples { - struct apr_hdr hdr; - u16 nsamples; - u16 reserved; -} __packed; - -#define ASM_STREAM_CMD_TAP_POPP_PCM 0x00010BF9 -struct asm_stream_cmd_tap_popp_pcm { - struct apr_hdr hdr; - u16 enable; - u16 reserved; - u32 module_id; -} __packed; - -/* Session Level commands */ -#define ASM_SESSION_CMD_MEMORY_MAP 0x00010C32 -struct asm_stream_cmd_memory_map { - struct apr_hdr hdr; - u32 buf_add; - u32 buf_size; - u16 mempool_id; - u16 reserved; -} __packed; - -#define ASM_SESSION_CMD_MEMORY_UNMAP 0x00010C33 -struct asm_stream_cmd_memory_unmap { - struct apr_hdr hdr; - u32 buf_add; -} __packed; - -#define ASM_SESSION_CMD_MEMORY_MAP_REGIONS 0x00010C45 -struct asm_memory_map_regions { - u32 phys; - u32 buf_size; -} __packed; - -struct asm_stream_cmd_memory_map_regions { - struct apr_hdr hdr; - u16 mempool_id; - u16 nregions; -} __packed; - -#define ASM_SESSION_CMD_MEMORY_UNMAP_REGIONS 0x00010C46 -struct asm_memory_unmap_regions { - u32 phys; -} __packed; - -struct asm_stream_cmd_memory_unmap_regions { - struct apr_hdr hdr; - u16 nregions; - u16 reserved; -} __packed; - -#define ASM_SESSION_CMD_RUN 0x00010BD2 -struct asm_stream_cmd_run { - struct apr_hdr hdr; - u32 flags; - u32 msw_ts; - u32 lsw_ts; -} __packed; - -/* Session level events */ -#define ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS 0x00010BD5 -struct asm_stream_cmd_reg_rx_underflow_event { - struct apr_hdr hdr; - u16 enable; - u16 reserved; -} __packed; - -#define ASM_SESSION_CMD_REGISTER_FOR_TX_OVERFLOW_EVENTS 0x00010BD6 -struct asm_stream_cmd_reg_tx_overflow_event { - struct apr_hdr hdr; - u16 enable; - u16 reserved; -} __packed; - -/* Data Path commands */ -#define ASM_DATA_CMD_WRITE 0x00010BD9 -struct asm_stream_cmd_write { - struct apr_hdr hdr; - u32 buf_add; - u32 avail_bytes; - u32 uid; - u32 msw_ts; - u32 lsw_ts; - u32 uflags; -} __packed; - -#define ASM_DATA_CMD_READ 0x00010BDA -struct asm_stream_cmd_read { - struct apr_hdr hdr; - u32 buf_add; - u32 buf_size; - u32 uid; -} __packed; - -#define ASM_DATA_CMD_READ_COMPRESSED 0x00010DBF -struct asm_stream_cmd_read_compressed { - struct apr_hdr hdr; - u32 buf_add; - u32 buf_size; - u32 uid; -} __packed; - -#define ASM_DATA_CMD_MEDIA_FORMAT_UPDATE 0x00010BDC -#define ASM_DATA_EVENT_ENC_SR_CM_NOTIFY 0x00010BDE -struct asm_stream_media_format_update { - struct apr_hdr hdr; - u32 format; - u32 cfg_size; - union { - struct asm_pcm_cfg pcm_cfg; - struct asm_adpcm_cfg adpcm_cfg; - struct asm_yadpcm_cfg yadpcm_cfg; - struct asm_midi_cfg midi_cfg; - struct asm_wma_cfg wma_cfg; - struct asm_wmapro_cfg wmapro_cfg; - struct asm_aac_cfg aac_cfg; - struct asm_flac_cfg flac_cfg; - struct asm_vorbis_cfg vorbis_cfg; - struct asm_multi_channel_pcm_fmt_blk multi_ch_pcm_cfg; - struct asm_amrwbplus_cfg amrwbplus_cfg; - } __packed write_cfg; -} __packed; - - -/* Command Responses */ -#define ASM_STREAM_CMDRSP_GET_ENCDEC_PARAM 0x00010C12 -struct asm_stream_cmdrsp_get_readwrite_param { - struct apr_hdr hdr; - u32 status; - u32 param_id; - u16 param_size; - u16 padding; - union { - struct asm_sbc_bitrate sbc_bitrate; - struct asm_immed_decode aac_dec; - } __packed read_write_cfg; -} __packed; - - -#define ASM_SESSION_CMDRSP_GET_SESSION_TIME 0x00010BD8 -struct asm_stream_cmdrsp_get_session_time { - struct apr_hdr hdr; - u32 status; - u32 msw_ts; - u32 lsw_ts; -} __packed; - -#define ASM_DATA_EVENT_WRITE_DONE 0x00010BDF -struct asm_data_event_write_done { - u32 buf_add; - u32 status; -} __packed; - -#define ASM_DATA_EVENT_READ_DONE 0x00010BE0 -struct asm_data_event_read_done { - u32 status; - u32 buffer_add; - u32 enc_frame_size; - u32 offset; - u32 msw_ts; - u32 lsw_ts; - u32 flags; - u32 num_frames; - u32 id; -} __packed; - -#define ASM_DATA_EVENT_READ_COMPRESSED_DONE 0x00010DC0 -struct asm_data_event_read_compressed_done { - u32 status; - u32 buffer_add; - u32 enc_frame_size; - u32 offset; - u32 msw_ts; - u32 lsw_ts; - u32 flags; - u32 num_frames; - u32 id; -} __packed; - -#define ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY 0x00010C65 -struct asm_data_event_sr_cm_change_notify { - u32 sample_rate; - u16 no_of_channels; - u16 reserved; - u8 channel_map[8]; -} __packed; - -/* service level events */ - -#define ASM_SERVICE_CMDRSP_GET_STREAM_HANDLES 0x00010C1B -struct asm_svc_cmdrsp_get_strm_handles { - struct apr_hdr hdr; - u32 num_handles; - u32 stream_handles; -} __packed; - - -#define ASM_SERVICE_CMDRSP_GET_WALLCLOCK_TIME 0x00010C1A -struct asm_svc_cmdrsp_get_wallclock_time { - struct apr_hdr hdr; - u32 status; - u32 msw_ts; - u32 lsw_ts; -} __packed; - -/* Error code */ -#define ADSP_EOK 0x00000000 /* Success / completed / no errors. */ -#define ADSP_EFAILED 0x00000001 /* General failure. */ -#define ADSP_EBADPARAM 0x00000002 /* Bad operation parameter(s). */ -#define ADSP_EUNSUPPORTED 0x00000003 /* Unsupported routine/operation. */ -#define ADSP_EVERSION 0x00000004 /* Unsupported version. */ -#define ADSP_EUNEXPECTED 0x00000005 /* Unexpected problem encountered. */ -#define ADSP_EPANIC 0x00000006 /* Unhandled problem occurred. */ -#define ADSP_ENORESOURCE 0x00000007 /* Unable to allocate resource(s). */ -#define ADSP_EHANDLE 0x00000008 /* Invalid handle. */ -#define ADSP_EALREADY 0x00000009 /* Operation is already processed. */ -#define ADSP_ENOTREADY 0x0000000A /* Operation not ready to be processed*/ -#define ADSP_EPENDING 0x0000000B /* Operation is pending completion*/ -#define ADSP_EBUSY 0x0000000C /* Operation could not be accepted or - * processed. - */ -#define ADSP_EABORTED 0x0000000D /* Operation aborted due to an error. */ -#define ADSP_EPREEMPTED 0x0000000E /* Operation preempted by higher priority*/ -#define ADSP_ECONTINUE 0x0000000F /* Operation requests intervention - * to complete. - */ -#define ADSP_EIMMEDIATE 0x00000010 /* Operation requests immediate - * intervention to complete. - */ -#define ADSP_ENOTIMPL 0x00000011 /* Operation is not implemented. */ -#define ADSP_ENEEDMORE 0x00000012 /* Operation needs more data or resources*/ - -/* SRS TRUMEDIA GUIDS */ -#define SRS_TRUMEDIA_TOPOLOGY_ID 0x00010D90 -#define SRS_TRUMEDIA_MODULE_ID 0x10005010 -#define SRS_TRUMEDIA_PARAMS 0x10005011 -#define SRS_TRUMEDIA_PARAMS_WOWHD 0x10005012 -#define SRS_TRUMEDIA_PARAMS_CSHP 0x10005013 -#define SRS_TRUMEDIA_PARAMS_HPF 0x10005014 -#define SRS_TRUMEDIA_PARAMS_PEQ 0x10005015 -#define SRS_TRUMEDIA_PARAMS_HL 0x10005016 - -/* SRS STUDIO SOUND 3D GUIDS */ -#define SRS_SS3D_TOPOLOGY_ID 0x00010720 -#define SRS_SS3D_MODULE_ID 0x10005020 -#define SRS_SS3D_PARAMS 0x10005021 -#define SRS_SS3D_PARAMS_CTRL 0x10005022 -#define SRS_SS3D_PARAMS_FILTER 0x10005023 - -/* SRS ALSA CMD MASKS */ -#define SRS_CMD_UPLOAD 0x7FFF0000 -#define SRS_PARAM_INDEX_MASK 0x80000000 -#define SRS_PARAM_OFFSET_MASK 0x3FFF0000 -#define SRS_PARAM_VALUE_MASK 0x0000FFFF - -/* SRS TRUMEDIA start */ -#define SRS_ID_GLOBAL 0x00000001 -#define SRS_ID_WOWHD 0x00000002 -#define SRS_ID_CSHP 0x00000003 -#define SRS_ID_HPF 0x00000004 -#define SRS_ID_PEQ 0x00000005 -#define SRS_ID_HL 0x00000006 - -struct srs_trumedia_params_GLOBAL { - uint8_t v1; - uint8_t v2; - uint8_t v3; - uint8_t v4; - uint8_t v5; - uint8_t v6; - uint8_t v7; - uint8_t v8; -} __packed; - -struct srs_trumedia_params_WOWHD { - uint32_t v1; - uint16_t v2; - uint16_t v3; - uint16_t v4; - uint16_t v5; - uint16_t v6; - uint16_t v7; - uint16_t v8; - uint16_t v____A1; - uint32_t v9; - uint16_t v10; - uint16_t v11; - uint32_t v12[16]; -} __packed; - -struct srs_trumedia_params_CSHP { - uint32_t v1; - uint16_t v2; - uint16_t v3; - uint16_t v4; - uint16_t v5; - uint16_t v6; - uint16_t v____A1; - uint32_t v7; - uint16_t v8; - uint16_t v9; - uint32_t v10[16]; -} __packed; - -struct srs_trumedia_params_HPF { - uint32_t v1; - uint32_t v2[26]; -} __packed; - -struct srs_trumedia_params_PEQ { - uint32_t v1; - uint16_t v2; - uint16_t v3; - uint16_t v4; - uint16_t v____A1; - uint32_t v5[26]; - uint32_t v6[26]; -} __packed; - -struct srs_trumedia_params_HL { - uint16_t v1; - uint16_t v2; - uint16_t v3; - uint16_t v____A1; - int32_t v4; - uint32_t v5; - uint16_t v6; - uint16_t v____A2; - uint32_t v7; -} __packed; - -struct srs_trumedia_params { - struct srs_trumedia_params_GLOBAL global; - struct srs_trumedia_params_WOWHD wowhd; - struct srs_trumedia_params_CSHP cshp; - struct srs_trumedia_params_HPF hpf; - struct srs_trumedia_params_PEQ peq; - struct srs_trumedia_params_HL hl; -} __packed; - -int srs_trumedia_open(int port_id, int srs_tech_id, void *srs_params); -/* SRS TruMedia end */ - -/* SRS Studio Sound 3D start */ -#define SRS_ID_SS3D_GLOBAL 0x00000001 -#define SRS_ID_SS3D_CTRL 0x00000002 -#define SRS_ID_SS3D_FILTER 0x00000003 - -struct srs_SS3D_params_GLOBAL { - uint8_t v1; - uint8_t v2; - uint8_t v3; - uint8_t v4; - uint8_t v5; - uint8_t v6; - uint8_t v7; - uint8_t v8; -} __packed; - -struct srs_SS3D_ctrl_params { - uint8_t v[236]; -} __packed; - -struct srs_SS3D_filter_params { - uint8_t v[28 + 2752]; -} __packed; - -struct srs_SS3D_params { - struct srs_SS3D_params_GLOBAL global; - struct srs_SS3D_ctrl_params ss3d; - struct srs_SS3D_filter_params ss3d_f; -} __packed; - -int srs_ss3d_open(int port_id, int srs_tech_id, void *srs_params); -/* SRS Studio Sound 3D end */ -#endif /*_APR_AUDIO_H_*/ diff --git a/ipc/Makefile b/ipc/Makefile new file mode 100644 index 000000000000..fd840c94d178 --- /dev/null +++ b/ipc/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_MSM_QDSP6_APRV2_GLINK) += apr.o apr_v2.o apr_tal_glink.o +obj-$(CONFIG_MSM_QDSP6_APRV3_GLINK) += apr.o apr_v3.o apr_tal_glink.o diff --git a/drivers/soc/qcom/qdsp6v2/apr.c b/ipc/apr.c similarity index 99% rename from drivers/soc/qcom/qdsp6v2/apr.c rename to ipc/apr.c index e45f61eee58c..bec513ad270e 100644 --- a/drivers/soc/qcom/qdsp6v2/apr.c +++ b/ipc/apr.c @@ -26,14 +26,13 @@ #include #include #include +#include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include #define APR_PKT_IPC_LOG_PAGE_CNT 2 diff --git a/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c b/ipc/apr_tal_glink.c similarity index 99% rename from drivers/soc/qcom/qdsp6v2/apr_tal_glink.c rename to ipc/apr_tal_glink.c index fc7f63f1cae1..f99f9ed22e7a 100644 --- a/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c +++ b/ipc/apr_tal_glink.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #define APR_MAXIMUM_NUM_OF_RETRIES 2 diff --git a/drivers/soc/qcom/qdsp6v2/apr_v2.c b/ipc/apr_v2.c similarity index 91% rename from drivers/soc/qcom/qdsp6v2/apr_v2.c rename to ipc/apr_v2.c index 4ddf39b1a097..d330571f3908 100644 --- a/drivers/soc/qcom/qdsp6v2/apr_v2.c +++ b/ipc/apr_v2.c @@ -15,10 +15,9 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include enum apr_subsys_state apr_get_subsys_state(void) { diff --git a/drivers/soc/qcom/qdsp6v2/apr_v3.c b/ipc/apr_v3.c similarity index 90% rename from drivers/soc/qcom/qdsp6v2/apr_v3.c rename to ipc/apr_v3.c index 2bfc518841c9..5a4ef53bb76f 100644 --- a/drivers/soc/qcom/qdsp6v2/apr_v3.c +++ b/ipc/apr_v3.c @@ -15,10 +15,9 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include #define DEST_ID APR_DEST_MODEM diff --git a/soc/Makefile b/soc/Makefile new file mode 100644 index 000000000000..c563e76ecdce --- /dev/null +++ b/soc/Makefile @@ -0,0 +1,6 @@ + +obj-$(CONFIG_REGMAP_SWR) += regmap-swr.o +obj-$(CONFIG_PINCTRL_WCD) += pinctrl-wcd.o +obj-$(CONFIG_PINCTRL_LPI) += pinctrl-lpi.o +obj-$(CONFIG_SOUNDWIRE) += soundwire.o +obj-$(CONFIG_SOUNDWIRE_WCD_CTRL) += swr-wcd-ctrl.o diff --git a/soc/core.h b/soc/core.h new file mode 120000 index 000000000000..8a2fa90df8cb --- /dev/null +++ b/soc/core.h @@ -0,0 +1 @@ +../../../drivers/pinctrl/core.h \ No newline at end of file diff --git a/drivers/pinctrl/qcom/pinctrl-lpi.c b/soc/pinctrl-lpi.c similarity index 99% rename from drivers/pinctrl/qcom/pinctrl-lpi.c rename to soc/pinctrl-lpi.c index 11f954e1eb6c..db5a9e5a4d02 100644 --- a/drivers/pinctrl/qcom/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -19,12 +19,12 @@ #include #include #include -#include #include #include +#include -#include "../core.h" -#include "../pinctrl-utils.h" +#include "core.h" +#include "pinctrl-utils.h" #define LPI_ADDRESS_SIZE 0xC000 diff --git a/soc/pinctrl-utils.h b/soc/pinctrl-utils.h new file mode 120000 index 000000000000..9aab5f24bd14 --- /dev/null +++ b/soc/pinctrl-utils.h @@ -0,0 +1 @@ +../../../drivers/pinctrl/pinctrl-utils.h \ No newline at end of file diff --git a/drivers/pinctrl/qcom/pinctrl-wcd.c b/soc/pinctrl-wcd.c similarity index 99% rename from drivers/pinctrl/qcom/pinctrl-wcd.c rename to soc/pinctrl-wcd.c index 2cc68a0c6743..d7695dbe77b8 100644 --- a/drivers/pinctrl/qcom/pinctrl-wcd.c +++ b/soc/pinctrl-wcd.c @@ -21,10 +21,10 @@ #include #include #include -#include +#include -#include "../core.h" -#include "../pinctrl-utils.h" +#include "core.h" +#include "pinctrl-utils.h" #define WCD_REG_DIR_CTL WCD934X_CHIP_TIER_CTRL_GPIO_CTL_OE #define WCD_REG_VAL_CTL WCD934X_CHIP_TIER_CTRL_GPIO_CTL_DATA diff --git a/drivers/base/regmap/regmap-swr.c b/soc/regmap-swr.c similarity index 98% rename from drivers/base/regmap/regmap-swr.c rename to soc/regmap-swr.c index be1eb00ad876..ba092a2aaa70 100644 --- a/drivers/base/regmap/regmap-swr.c +++ b/soc/regmap-swr.c @@ -15,11 +15,11 @@ #include #include #include -#include #include #include +#include +#include -#include "internal.h" static int regmap_swr_gather_write(void *context, const void *reg, size_t reg_size, diff --git a/drivers/soundwire/soundwire.c b/soc/soundwire.c similarity index 99% rename from drivers/soundwire/soundwire.c rename to soc/soundwire.c index f0c7aa9ac01f..210de34e6666 100644 --- a/drivers/soundwire/soundwire.c +++ b/soc/soundwire.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include struct boardinfo { struct list_head list; diff --git a/drivers/soundwire/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c similarity index 99% rename from drivers/soundwire/swr-wcd-ctrl.c rename to soc/swr-wcd-ctrl.c index e338d582fa95..e7d7c797dd9e 100644 --- a/drivers/soundwire/swr-wcd-ctrl.c +++ b/soc/swr-wcd-ctrl.c @@ -17,8 +17,6 @@ #include #include #include -#include -#include #include #include #include @@ -26,6 +24,8 @@ #include #include #include +#include +#include #include "swrm_registers.h" #include "swr-wcd-ctrl.h" diff --git a/drivers/soundwire/swr-wcd-ctrl.h b/soc/swr-wcd-ctrl.h similarity index 98% rename from drivers/soundwire/swr-wcd-ctrl.h rename to soc/swr-wcd-ctrl.h index b7a3edac3e00..5a4f79b4ecf6 100644 --- a/drivers/soundwire/swr-wcd-ctrl.h +++ b/soc/swr-wcd-ctrl.h @@ -13,7 +13,7 @@ #ifndef _SWR_WCD_CTRL_H #define _SWR_WCD_CTRL_H #include -#include +#include #define SWR_MAX_ROW 0 /* Rows = 48 */ #define SWR_MAX_COL 7 /* Cols = 16 */ diff --git a/drivers/soundwire/swrm_registers.h b/soc/swrm_registers.h similarity index 100% rename from drivers/soundwire/swrm_registers.h rename to soc/swrm_registers.h diff --git a/sound/Makefile b/sound/Makefile deleted file mode 100644 index 71c713a41d38..000000000000 --- a/sound/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# MSM Machine Support - -obj-$(CONFIG_SND_SOC) += soc/msm/ -obj-$(CONFIG_SND_SOC) += soc/codecs/ diff --git a/sound/soc/codecs/msm_sdw/Kconfig b/sound/soc/codecs/msm_sdw/Kconfig deleted file mode 100644 index abd7c8c7dfb0..000000000000 --- a/sound/soc/codecs/msm_sdw/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -config SND_SOC_MSM_SDW - tristate "MSM Internal soundwire codec" - help - MSM-based soundwire codec core driver - supported along with internal digital - codec core. diff --git a/sound/soc/codecs/sdm660_cdc/Kconfig b/sound/soc/codecs/sdm660_cdc/Kconfig deleted file mode 100644 index 2f36c393a65b..000000000000 --- a/sound/soc/codecs/sdm660_cdc/Kconfig +++ /dev/null @@ -1,5 +0,0 @@ - -config SND_SOC_SDM660_CDC - tristate "MSM Internal PMIC based codec" - select SND_SOC_WCD_MBHC - select SND_SOC_WCD_MBHC_LEGACY diff --git a/sound/soc/msm/Kconfig b/sound/soc/msm/Kconfig deleted file mode 100644 index c557ae06e95f..000000000000 --- a/sound/soc/msm/Kconfig +++ /dev/null @@ -1,283 +0,0 @@ -menu "MSM SoC Audio support" - -config SND_SOC_MSM_HOSTLESS_PCM - tristate - -config SND_SOC_MSM_QDSP6V2_INTF - bool "SoC Q6 audio driver for MSM/APQ" - depends on MSM_QDSP6_APRV2_GLINK - help - To add support for SoC audio on MSM/APQ. - This will enable all the platform specific - interactions towards DSP. It includes asm, - adm and afe interfaces on the DSP. - -config SND_SOC_QDSP6V2 - tristate "SoC ALSA audio driver for QDSP6V2" - select SND_SOC_MSM_QDSP6V2_INTF - select SND_SOC_COMPRESS - help - To add support for MSM QDSP6V2 Soc Audio. - This will enable sound soc platform specific - audio drivers. This includes q6asm, q6adm, - q6afe interfaces to DSP using apr. - -config SND_SOC_QDSP_DEBUG - bool "QDSP Audio Driver Debug Feature" - help - Configuration to enable debugging utilities for - QDSP6 based audio drivers. One debugging utility - is inducing kernel panic upon encountering critical - errors from DSP audio modules - -config DOLBY_DS2 - bool "Enable Dolby DS2" - depends on SND_SOC_MSM_QDSP6V2_INTF - help - To add support for dolby DAP post processing. - This support is to configure the post processing parameters - to DSP. The configuration includes sending the end point - device, end point dependent post processing parameters and - the various posrt processing parameters - -config DOLBY_LICENSE - bool "Enable Dolby LICENSE" - depends on SND_SOC_MSM_QDSP6V2_INTF - help - To add support for dolby DAP post processing, - and retain DAP set license functionality only. - This is required by Dolby GEF implementation which needs - nothing but dolby license validation functionality in driver. - -config DTS_EAGLE - bool "Enable DTS Eagle Support" - depends on SND_SOC_MSM_QDSP6V2_INTF - select SND_HWDEP - help - To add DTS Eagle support on QDSP6 targets. - Eagle is a DTS pre/post processing - package that includes HeadphoneX. The configuration - includes sending tuning parameters of various modules. - -config DTS_SRS_TM - bool "Enable DTS SRS" - depends on SND_SOC_MSM_QDSP6V2_INTF - help - To add support for DTS SRS post processing. - This support is to configure the post processing - parameters to DSP. The configuration includes sending - tuning parameters of various modules. - -config QTI_PP - bool "Enable QTI PP" - depends on SND_SOC_MSM_QDSP6V2_INTF - help - To add support for default QTI post processing. - This support is to configure the post processing - parameters to DSP. The configuration includes sending - tuning parameters of various modules such as equalizer, - customized mixing. - -config QTI_PP_AUDIOSPHERE - bool "Enable QTI AUDIOSPHERE PP" - depends on SND_SOC_MSM_QDSP6V2_INTF - help - To add support for QTI audio sphere post processing. - This support is to configure the post processing - parameters to DSP. The configuration includes sending - tuning parameters of audio sphere module. - -config SND_SOC_CPE - tristate "CPE drivers" - depends on SND_SOC_WCD_CPE - help - To add support for Codec Processing Engine. This support - is to enable CPE block on the codec and this config needs - to be added to codecs that contain the CPE hardware block. - The configuration includes the cpe lsm driver to enable - listen on codec. - -config SND_SOC_INT_CODEC - tristate "SoC Machine driver for SDM660_INT" - depends on ARCH_QCOM - select SND_SOC_QDSP6V2 - select SND_SOC_MSM_STUB - select SND_SOC_MSM_HOSTLESS_PCM - select SND_DYNAMIC_MINORS - select MSM_QDSP6_APRV2_GLINK - select MSM_QDSP6_SSR - select MSM_QDSP6_PDR - select MSM_QDSP6_NOTIFIER - select MSM_QDSP6V2_CODECS - select MSM_CDC_PINCTRL - select SND_SOC_MSM_SDW - select SND_SOC_SDM660_CDC - select SND_SOC_MSM_HDMI_CODEC_RX - select QTI_PP - select DTS_SRS_TM - select DOLBY_LICENSE - select SND_HWDEP - select MSM_ULTRASOUND - select DTS_EAGLE - select SND_SOC_SDM660_COMMON - select SND_SOC_COMPRESS - select PINCTRL_LPI - help - To add support for SoC audio on MSM_INT. - This will enable sound soc drivers which - interfaces with DSP, also it will enable - the machine driver and the corresponding - DAI-links - -config SND_SOC_EXT_CODEC - tristate "SoC Machine driver for SDM660_EXT" - depends on ARCH_QCOM - select SND_SOC_QDSP6V2 - select SND_SOC_MSM_STUB - select SND_SOC_MSM_HOSTLESS_PCM - select SND_DYNAMIC_MINORS - select MSM_QDSP6_APRV2_GLINK - select MSM_QDSP6_SSR - select MSM_QDSP6_PDR - select MSM_QDSP6_NOTIFIER - select MSM_QDSP6V2_CODECS - select SND_SOC_WCD9335 - select SND_SOC_WCD934X - select SND_SOC_WSA881X - select SND_SOC_MSM_HDMI_CODEC_RX - select MFD_CORE - select QTI_PP - select DTS_SRS_TM - select DOLBY_LICENSE - select SND_SOC_CPE - select SND_SOC_WCD_CPE - select SND_HWDEP - select MSM_ULTRASOUND - select DTS_EAGLE - select SND_SOC_SDM660_COMMON - select SND_SOC_COMPRESS - select PINCTRL_LPI - help - To add support for SoC audio on MSM_EXT. - This will enable sound soc drivers which - interfaces with DSP, also it will enable - the machine driver and the corresponding - DAI-links - -config SND_SOC_MSM8996 - tristate "SoC Machine driver for MSM8996 boards" - depends on ARCH_MSM8996 - select SND_SOC_COMPRESS - select SND_SOC_QDSP6V2 - select SND_SOC_MSM_STUB - select SND_SOC_MSM_HOSTLESS_PCM - select SND_DYNAMIC_MINORS - select MSM_QDSP6_APRV2 - select MSM_QDSP6V2_CODECS - select SND_SOC_WCD9335 - select SND_SOC_WSA881X - select SND_SOC_MSM_HDMI_CODEC_RX - select DTS_SRS_TM - select QTI_PP - select QTI_PP_AUDIOSPHERE - select SND_SOC_CPE - select MSM_ULTRASOUND - select DOLBY_DS2 - select SND_HWDEP - select DTS_EAGLE - help - To add support for SoC audio on MSM8996. - This will enable sound soc drivers which - interfaces with DSP, also it will enable - the machine driver and the corresponding - DAI-links - -config SND_SOC_MACHINE_MSM8998 - tristate "SoC Machine driver for MSM8998 boards" - select SND_SOC_WSA881X - select SND_SOC_WCD9335 - select SND_SOC_WCD934X - select SND_SOC_CPE - - help - To enable the machine driver and the - corresponding DAI-links on MSM8998. - All platform specific audio modules are - enabled here. - -config SND_SOC_MSM8998 - tristate "Sound SoC drivers to interface with DSP" - depends on ARCH_QCOM - select SND_SOC_COMPRESS - select SND_SOC_QDSP6V2 - select SND_SOC_MSM_STUB - select SND_SOC_MSM_HOSTLESS_PCM - select SND_DYNAMIC_MINORS - select MSM_QDSP6_APRV2_GLINK - select MSM_QDSP6_SSR - select MSM_QDSP6_PDR - select MSM_QDSP6_NOTIFIER - select MSM_QDSP6V2_CODECS - select SND_SOC_MSM_HDMI_CODEC_RX - select DTS_SRS_TM - select QTI_PP - select MSM_ULTRASOUND - select DOLBY_LICENSE - select SND_HWDEP - select DTS_EAGLE - help - To add support for SoC audio on MSM8998. - This will enable sound soc drivers which - interfaces with DSP, also it will enable - the machine driver and the corresponding - DAI-links - -config SND_SOC_660 - tristate "SoC Machine driver for SDM660 boards" - depends on ARCH_SDM660 - select SND_SOC_INT_CODEC - select SND_SOC_EXT_CODEC - help - To add support for SoC audio on SDM660. - This will enable sound soc drivers which - interfaces with DSP, also it will enable - the machine driver and the corresponding - DAI-links - -config SND_SOC_MACHINE_SDM845 - tristate "SoC Machine driver for SDM845 boards" - select SND_SOC_WSA881X - select SND_SOC_WCD934X - - help - To enable the machine driver and the - corresponding DAI-links on SDM845. - All platform specific audio modules are - enabled here. - -config SND_SOC_SDM845 - tristate "SoC Machine driver for SDM845 boards" - depends on ARCH_QCOM - select SND_SOC_COMPRESS - select SND_SOC_QDSP6V2 - select SND_SOC_MSM_STUB - select SND_SOC_MSM_HOSTLESS_PCM - select SND_DYNAMIC_MINORS - select MSM_QDSP6_APRV2_GLINK - select MSM_QDSP6_SSR - select MSM_QDSP6_PDR - select MSM_QDSP6_NOTIFIER - select MSM_QDSP6V2_CODECS - select DTS_SRS_TM - select QTI_PP - select MSM_ULTRASOUND - select DOLBY_DS2 - select SND_HWDEP - select DTS_EAGLE - help - To add support for SoC audio on SDM845. - This enables sound soc drivers that interfaces - with DSP. This also enables the machine driver - and the corresponding DAI-links. - -endmenu diff --git a/sound/soc/msm/qdsp6v2/Makefile b/sound/soc/msm/qdsp6v2/Makefile deleted file mode 100644 index da2b2c783a83..000000000000 --- a/sound/soc/msm/qdsp6v2/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -snd-soc-qdsp6v2-objs += msm-dai-q6-v2.o msm-pcm-q6-v2.o \ - msm-pcm-routing-v2.o msm-compress-q6-v2.o \ - msm-pcm-afe-v2.o msm-pcm-voip-v2.o \ - msm-pcm-voice-v2.o msm-dai-q6-hdmi-v2.o \ - msm-lsm-client.o msm-pcm-host-voice-v2.o \ - msm-audio-effects-q6-v2.o msm-pcm-loopback-v2.o \ - msm-dai-slim.o msm-transcode-loopback-q6-v2.o \ - adsp_err.o -obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o msm-pcm-dtmf-v2.o \ - msm-dai-stub-v2.o -obj-$(CONFIG_SND_HWDEP) += msm-pcm-routing-devdep.o -obj-$(CONFIG_DOLBY_DAP) += msm-dolby-dap-config.o -obj-$(CONFIG_DOLBY_DS2) += msm-ds2-dap-config.o -obj-$(CONFIG_DOLBY_LICENSE) += msm-ds2-dap-config.o -obj-$(CONFIG_DTS_SRS_TM) += msm-dts-srs-tm-config.o -obj-$(CONFIG_QTI_PP) += msm-qti-pp-config.o -obj-y += audio_calibration.o audio_cal_utils.o q6adm.o q6afe.o q6asm.o \ - q6audio-v2.o q6voice.o q6core.o rtac.o q6lsm.o audio_slimslave.o \ - msm-pcm-q6-noirq.o -- GitLab From d1f3619befe5ca773d0f6056ddb6e5d2ab84f5c5 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 3 Aug 2017 18:54:01 +0530 Subject: [PATCH 0007/1645] audio-lnx: Propagate changes from kernel for wdsp-glink/avtimer Pick the WDSP-Glink and avtimer drivers from 4.9 kernel at below cutoff - (80be7d6a313 - "msm: ADSPRPC: Fix for NULL pointer dereference") This changes are done to migrate wdsp-glink/avtimer drivers to this new audio kernel techpack. Also remove the CDSP loader from techpack audio as it is non-audio related. Change-Id: I4f55429c5cbcd24920fdcb8eb2fe3aec02af320e Signed-off-by: Laxminath Kasam --- dsp/Makefile | 2 +- dsp/avtimer.c | 548 ++++++++++++++++++++ dsp/cdsp-loader.c | 280 ---------- ipc/Makefile | 1 + ipc/wcd-dsp-glink.c | 1201 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1751 insertions(+), 281 deletions(-) create mode 100644 dsp/avtimer.c delete mode 100644 dsp/cdsp-loader.c create mode 100644 ipc/wcd-dsp-glink.c diff --git a/dsp/Makefile b/dsp/Makefile index a31aeb22a20b..b609df228abe 100644 --- a/dsp/Makefile +++ b/dsp/Makefile @@ -5,6 +5,6 @@ obj-$(CONFIG_MSM_ADSP_LOADER) += adsp-loader.o obj-$(CONFIG_MSM_QDSP6_SSR) += audio_ssr.o obj-$(CONFIG_MSM_QDSP6_PDR) += audio_pdr.o obj-$(CONFIG_MSM_QDSP6_NOTIFIER) += audio_notifier.o -obj-$(CONFIG_MSM_CDSP_LOADER) += cdsp-loader.o obj-$(CONFIG_MSM_ULTRASOUND) += usf.o usfcdev.o q6usm.o +obj-$(CONFIG_MSM_AVTIMER) += avtimer.o obj-$(CONFIG_MSM_QDSP6V2_CODECS) += codecs/ diff --git a/dsp/avtimer.c b/dsp/avtimer.c new file mode 100644 index 000000000000..63044db6e4b9 --- /dev/null +++ b/dsp/avtimer.c @@ -0,0 +1,548 @@ +/* + * Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEVICE_NAME "avtimer" +#define TIMEOUT_MS 1000 +#define CORE_CLIENT 1 +#define TEMP_PORT ((CORE_CLIENT << 8) | 0x0001) +#define SSR_WAKETIME 1000 +#define Q6_READY_RETRY 250 +#define Q6_READY_MAX_RETRIES 40 + +#define AVCS_CMD_REMOTE_AVTIMER_VOTE_REQUEST 0x00012914 +#define AVCS_CMD_RSP_REMOTE_AVTIMER_VOTE_REQUEST 0x00012915 +#define AVCS_CMD_REMOTE_AVTIMER_RELEASE_REQUEST 0x00012916 +#define AVTIMER_REG_CNT 2 + +struct adsp_avt_timer { + struct apr_hdr hdr; + union { + char client_name[8]; + u32 avtimer_handle; + }; +} __packed; + +static int major; + +struct avtimer_t { + struct apr_svc *core_handle_q; + struct cdev myc; + struct class *avtimer_class; + struct mutex avtimer_lock; + int avtimer_open_cnt; + struct delayed_work ssr_dwork; + wait_queue_head_t adsp_resp_wait; + int enable_timer_resp_received; + int timer_handle; + void __iomem *p_avtimer_msw; + void __iomem *p_avtimer_lsw; + uint32_t clk_div; + uint32_t clk_mult; + atomic_t adsp_ready; + int num_retries; +}; + +static struct avtimer_t avtimer; + +static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) +{ + uint32_t *payload1; + + if (!data) { + pr_err("%s: Invalid params\n", __func__); + return -EINVAL; + } + pr_debug("%s: core msg: payload len = %u, apr resp opcode = 0x%X\n", + __func__, data->payload_size, data->opcode); + + switch (data->opcode) { + + case APR_BASIC_RSP_RESULT:{ + + if (!data->payload_size) { + pr_err("%s: APR_BASIC_RSP_RESULT No Payload ", + __func__); + return 0; + } + + payload1 = data->payload; + switch (payload1[0]) { + case AVCS_CMD_REMOTE_AVTIMER_RELEASE_REQUEST: + pr_debug("%s: Cmd = TIMER RELEASE status[0x%x]\n", + __func__, payload1[1]); + break; + default: + pr_err("Invalid cmd rsp[0x%x][0x%x]\n", + payload1[0], payload1[1]); + break; + } + break; + } + + case RESET_EVENTS:{ + pr_debug("%s: Reset event received in AV timer\n", __func__); + apr_reset(avtimer.core_handle_q); + avtimer.core_handle_q = NULL; + avtimer.avtimer_open_cnt = 0; + atomic_set(&avtimer.adsp_ready, 0); + schedule_delayed_work(&avtimer.ssr_dwork, + msecs_to_jiffies(SSR_WAKETIME)); + break; + } + + case AVCS_CMD_RSP_REMOTE_AVTIMER_VOTE_REQUEST: + payload1 = data->payload; + pr_debug("%s: RSP_REMOTE_AVTIMER_VOTE_REQUEST handle %x\n", + __func__, payload1[0]); + avtimer.timer_handle = payload1[0]; + avtimer.enable_timer_resp_received = 1; + wake_up(&avtimer.adsp_resp_wait); + break; + default: + pr_err("%s: Message adspcore svc: %d\n", + __func__, data->opcode); + break; + } + + return 0; +} + +int avcs_core_open(void) +{ + if (!avtimer.core_handle_q) + avtimer.core_handle_q = apr_register("ADSP", "CORE", + aprv2_core_fn_q, TEMP_PORT, NULL); + pr_debug("%s: Open_q %p\n", __func__, avtimer.core_handle_q); + if (!avtimer.core_handle_q) { + pr_err("%s: Unable to register CORE\n", __func__); + return -EINVAL; + } + return 0; +} +EXPORT_SYMBOL(avcs_core_open); + +static int avcs_core_disable_avtimer(int timerhandle) +{ + int rc = -EINVAL; + struct adsp_avt_timer payload; + + if (!timerhandle) { + pr_err("%s: Invalid timer handle\n", __func__); + return -EINVAL; + } + memset(&payload, 0, sizeof(payload)); + rc = avcs_core_open(); + if (!rc && avtimer.core_handle_q) { + payload.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + payload.hdr.pkt_size = + sizeof(struct adsp_avt_timer); + payload.hdr.src_svc = avtimer.core_handle_q->id; + payload.hdr.src_domain = APR_DOMAIN_APPS; + payload.hdr.dest_domain = APR_DOMAIN_ADSP; + payload.hdr.dest_svc = APR_SVC_ADSP_CORE; + payload.hdr.src_port = TEMP_PORT; + payload.hdr.dest_port = TEMP_PORT; + payload.hdr.token = CORE_CLIENT; + payload.hdr.opcode = AVCS_CMD_REMOTE_AVTIMER_RELEASE_REQUEST; + payload.avtimer_handle = timerhandle; + pr_debug("%s: disable avtimer opcode %x handle %x\n", + __func__, payload.hdr.opcode, payload.avtimer_handle); + rc = apr_send_pkt(avtimer.core_handle_q, + (uint32_t *)&payload); + if (rc < 0) + pr_err("%s: Enable AVtimer failed op[0x%x]rc[%d]\n", + __func__, payload.hdr.opcode, rc); + else + rc = 0; + } + return rc; +} + +static int avcs_core_enable_avtimer(char *client_name) +{ + int rc = -EINVAL, ret = -EINVAL; + struct adsp_avt_timer payload; + + if (!client_name) { + pr_err("%s: Invalid params\n", __func__); + return -EINVAL; + } + memset(&payload, 0, sizeof(payload)); + rc = avcs_core_open(); + if (!rc && avtimer.core_handle_q) { + avtimer.enable_timer_resp_received = 0; + payload.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_EVENT, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + payload.hdr.pkt_size = + sizeof(struct adsp_avt_timer); + payload.hdr.src_svc = avtimer.core_handle_q->id; + payload.hdr.src_domain = APR_DOMAIN_APPS; + payload.hdr.dest_domain = APR_DOMAIN_ADSP; + payload.hdr.dest_svc = APR_SVC_ADSP_CORE; + payload.hdr.src_port = TEMP_PORT; + payload.hdr.dest_port = TEMP_PORT; + payload.hdr.token = CORE_CLIENT; + payload.hdr.opcode = AVCS_CMD_REMOTE_AVTIMER_VOTE_REQUEST; + strlcpy(payload.client_name, client_name, + sizeof(payload.client_name)); + pr_debug("%s: enable avtimer opcode %x client name %s\n", + __func__, payload.hdr.opcode, payload.client_name); + rc = apr_send_pkt(avtimer.core_handle_q, + (uint32_t *)&payload); + if (rc < 0) { + pr_err("%s: Enable AVtimer failed op[0x%x]rc[%d]\n", + __func__, payload.hdr.opcode, rc); + goto bail; + } else + rc = 0; + ret = wait_event_timeout(avtimer.adsp_resp_wait, + (avtimer.enable_timer_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout for Enable timer\n", + __func__); + rc = -ETIMEDOUT; + } + if (rc) + avtimer.timer_handle = 0; + } +bail: + return rc; +} + +int avcs_core_disable_power_collapse(int enable) +{ + int rc = 0; + + mutex_lock(&avtimer.avtimer_lock); + if (enable) { + if (avtimer.avtimer_open_cnt) { + avtimer.avtimer_open_cnt++; + pr_debug("%s: opened avtimer open count=%d\n", + __func__, avtimer.avtimer_open_cnt); + rc = 0; + goto done; + } + rc = avcs_core_enable_avtimer("timer"); + if (!rc) { + avtimer.avtimer_open_cnt++; + atomic_set(&avtimer.adsp_ready, 1); + } + } else { + if (avtimer.avtimer_open_cnt > 0) { + avtimer.avtimer_open_cnt--; + if (!avtimer.avtimer_open_cnt) { + rc = avcs_core_disable_avtimer( + avtimer.timer_handle); + avtimer.timer_handle = 0; + } + } + } +done: + mutex_unlock(&avtimer.avtimer_lock); + return rc; +} +EXPORT_SYMBOL(avcs_core_disable_power_collapse); + +static void reset_work(struct work_struct *work) +{ + if (q6core_is_adsp_ready()) { + avcs_core_disable_power_collapse(1); + avtimer.num_retries = Q6_READY_MAX_RETRIES; + return; + } + pr_debug("%s:Q6 not ready-retry after sometime\n", __func__); + if (--avtimer.num_retries > 0) { + schedule_delayed_work(&avtimer.ssr_dwork, + msecs_to_jiffies(Q6_READY_RETRY)); + } else { + pr_err("%s: Q6 failed responding after multiple retries\n", + __func__); + avtimer.num_retries = Q6_READY_MAX_RETRIES; + } +} + +int avcs_core_query_timer(uint64_t *avtimer_tick) +{ + uint32_t avtimer_msw = 0, avtimer_lsw = 0; + uint64_t avtimer_tick_temp; + + if (!atomic_read(&avtimer.adsp_ready)) { + pr_debug("%s:In SSR, return\n", __func__); + return -ENETRESET; + } + avtimer_lsw = ioread32(avtimer.p_avtimer_lsw); + avtimer_msw = ioread32(avtimer.p_avtimer_msw); + + avtimer_tick_temp = (uint64_t)((uint64_t)avtimer_msw << 32) + | avtimer_lsw; + *avtimer_tick = mul_u64_u32_div(avtimer_tick_temp, avtimer.clk_mult, + avtimer.clk_div); + pr_debug_ratelimited("%s:Avtimer: msw: %u, lsw: %u, tick: %llu\n", + __func__, + avtimer_msw, avtimer_lsw, *avtimer_tick); + return 0; +} +EXPORT_SYMBOL(avcs_core_query_timer); + +static int avtimer_open(struct inode *inode, struct file *file) +{ + return avcs_core_disable_power_collapse(1); +} + +static int avtimer_release(struct inode *inode, struct file *file) +{ + return avcs_core_disable_power_collapse(0); +} + +/* + * ioctl call provides GET_AVTIMER + */ +static long avtimer_ioctl(struct file *file, unsigned int ioctl_num, + unsigned long ioctl_param) +{ + switch (ioctl_num) { + case IOCTL_GET_AVTIMER_TICK: + { + uint64_t avtimer_tick = 0; + int rc; + + rc = avcs_core_query_timer(&avtimer_tick); + + if (rc) { + pr_err("%s: Error: Invalid AV Timer tick, rc = %d\n", + __func__, rc); + return rc; + } + + pr_debug_ratelimited("%s: AV Timer tick: time %llx\n", + __func__, avtimer_tick); + if (copy_to_user((void *) ioctl_param, &avtimer_tick, + sizeof(avtimer_tick))) { + pr_err("%s: copy_to_user failed\n", __func__); + return -EFAULT; + } + } + break; + + default: + pr_err("%s: invalid cmd\n", __func__); + return -EINVAL; + } + return 0; +} + +static const struct file_operations avtimer_fops = { + .unlocked_ioctl = avtimer_ioctl, + .compat_ioctl = avtimer_ioctl, + .open = avtimer_open, + .release = avtimer_release +}; + +static int dev_avtimer_probe(struct platform_device *pdev) +{ + int result = 0; + dev_t dev = MKDEV(major, 0); + struct device *device_handle; + struct resource *reg_lsb = NULL, *reg_msb = NULL; + uint32_t clk_div_val; + uint32_t clk_mult_val; + + if (!pdev) { + pr_err("%s: Invalid params\n", __func__); + return -EINVAL; + } + reg_lsb = platform_get_resource_byname(pdev, + IORESOURCE_MEM, "avtimer_lsb_addr"); + if (!reg_lsb) { + dev_err(&pdev->dev, "%s: Looking up %s property", + "avtimer_lsb_addr", __func__); + return -EINVAL; + } + reg_msb = platform_get_resource_byname(pdev, + IORESOURCE_MEM, "avtimer_msb_addr"); + if (!reg_msb) { + dev_err(&pdev->dev, "%s: Looking up %s property", + "avtimer_msb_addr", __func__); + return -EINVAL; + } + INIT_DELAYED_WORK(&avtimer.ssr_dwork, reset_work); + + avtimer.p_avtimer_lsw = devm_ioremap_nocache(&pdev->dev, + reg_lsb->start, resource_size(reg_lsb)); + if (!avtimer.p_avtimer_lsw) { + dev_err(&pdev->dev, "%s: ioremap failed for lsb avtimer register", + __func__); + return -ENOMEM; + } + + avtimer.p_avtimer_msw = devm_ioremap_nocache(&pdev->dev, + reg_msb->start, resource_size(reg_msb)); + if (!avtimer.p_avtimer_msw) { + dev_err(&pdev->dev, "%s: ioremap failed for msb avtimer register", + __func__); + goto unmap; + } + avtimer.num_retries = Q6_READY_MAX_RETRIES; + /* get the device number */ + if (major) + result = register_chrdev_region(dev, 1, DEVICE_NAME); + else { + result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME); + major = MAJOR(dev); + } + + if (result < 0) { + dev_err(&pdev->dev, "%s: Registering avtimer device failed\n", + __func__); + goto unmap; + } + + avtimer.avtimer_class = class_create(THIS_MODULE, "avtimer"); + if (IS_ERR(avtimer.avtimer_class)) { + result = PTR_ERR(avtimer.avtimer_class); + dev_err(&pdev->dev, "%s: Error creating avtimer class: %d\n", + __func__, result); + goto unregister_chrdev_region; + } + + cdev_init(&avtimer.myc, &avtimer_fops); + result = cdev_add(&avtimer.myc, dev, 1); + + if (result < 0) { + dev_err(&pdev->dev, "%s: Registering file operations failed\n", + __func__); + goto class_destroy; + } + + device_handle = device_create(avtimer.avtimer_class, + NULL, avtimer.myc.dev, NULL, "avtimer"); + if (IS_ERR(device_handle)) { + result = PTR_ERR(device_handle); + pr_err("%s: device_create failed: %d\n", __func__, result); + goto class_destroy; + } + init_waitqueue_head(&avtimer.adsp_resp_wait); + mutex_init(&avtimer.avtimer_lock); + avtimer.avtimer_open_cnt = 0; + + pr_debug("%s: Device create done for avtimer major=%d\n", + __func__, major); + + if (of_property_read_u32(pdev->dev.of_node, + "qcom,clk-div", &clk_div_val)) + avtimer.clk_div = 1; + else + avtimer.clk_div = clk_div_val; + + if (of_property_read_u32(pdev->dev.of_node, + "qcom,clk-mult", &clk_mult_val)) + avtimer.clk_mult = 1; + else + avtimer.clk_mult = clk_mult_val; + + pr_debug("%s: avtimer.clk_div = %d, avtimer.clk_mult = %d\n", + __func__, avtimer.clk_div, avtimer.clk_mult); + return 0; + +class_destroy: + class_destroy(avtimer.avtimer_class); +unregister_chrdev_region: + unregister_chrdev_region(MKDEV(major, 0), 1); +unmap: + if (avtimer.p_avtimer_lsw) + devm_iounmap(&pdev->dev, avtimer.p_avtimer_lsw); + if (avtimer.p_avtimer_msw) + devm_iounmap(&pdev->dev, avtimer.p_avtimer_msw); + avtimer.p_avtimer_lsw = NULL; + avtimer.p_avtimer_msw = NULL; + return result; + +} + +static int dev_avtimer_remove(struct platform_device *pdev) +{ + pr_debug("%s: dev_avtimer_remove\n", __func__); + + if (avtimer.p_avtimer_lsw) + devm_iounmap(&pdev->dev, avtimer.p_avtimer_lsw); + if (avtimer.p_avtimer_msw) + devm_iounmap(&pdev->dev, avtimer.p_avtimer_msw); + device_destroy(avtimer.avtimer_class, avtimer.myc.dev); + cdev_del(&avtimer.myc); + class_destroy(avtimer.avtimer_class); + unregister_chrdev_region(MKDEV(major, 0), 1); + + return 0; +} + +static const struct of_device_id avtimer_machine_of_match[] = { + { .compatible = "qcom,avtimer", }, + {}, +}; +static struct platform_driver dev_avtimer_driver = { + .probe = dev_avtimer_probe, + .remove = dev_avtimer_remove, + .driver = { + .name = "dev_avtimer", + .of_match_table = avtimer_machine_of_match, + }, +}; + +static int __init avtimer_init(void) +{ + s32 rc; + + rc = platform_driver_register(&dev_avtimer_driver); + if (rc < 0) { + pr_err("%s: platform_driver_register failed\n", __func__); + goto error_platform_driver; + } + pr_debug("%s: dev_avtimer_init : done\n", __func__); + + return 0; +error_platform_driver: + + pr_err("%s: encounterd error\n", __func__); + return rc; +} + +static void __exit avtimer_exit(void) +{ + pr_debug("%s: avtimer_exit\n", __func__); + platform_driver_unregister(&dev_avtimer_driver); +} + +module_init(avtimer_init); +module_exit(avtimer_exit); + +MODULE_DESCRIPTION("avtimer driver"); +MODULE_LICENSE("GPL v2"); diff --git a/dsp/cdsp-loader.c b/dsp/cdsp-loader.c deleted file mode 100644 index 70977d36f0c9..000000000000 --- a/dsp/cdsp-loader.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (c) 2012-2014, 2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define BOOT_CMD 1 -#define IMAGE_UNLOAD_CMD 0 - -#define CDSP_SUBSYS_DOWN 0 -#define CDSP_SUBSYS_LOADED 1 - -static ssize_t cdsp_boot_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t count); - -struct cdsp_loader_private { - void *pil_h; - struct kobject *boot_cdsp_obj; - struct attribute_group *attr_group; -}; - -static struct kobj_attribute cdsp_boot_attribute = - __ATTR(boot, 0220, NULL, cdsp_boot_store); - -static struct attribute *attrs[] = { - &cdsp_boot_attribute.attr, - NULL, -}; - -static u32 cdsp_state = CDSP_SUBSYS_DOWN; -static struct platform_device *cdsp_private; -static struct work_struct cdsp_ldr_work; -static void cdsp_loader_unload(struct platform_device *pdev); - -static void cdsp_load_fw(struct work_struct *cdsp_ldr_work) -{ - struct platform_device *pdev = cdsp_private; - struct cdsp_loader_private *priv = NULL; - - int rc = 0; - const char *img_name; - - if (!pdev) { - dev_err(&pdev->dev, "%s: Platform device null\n", __func__); - goto fail; - } - - if (!pdev->dev.of_node) { - dev_err(&pdev->dev, - "%s: Device tree information missing\n", __func__); - - goto fail; - } - - rc = of_property_read_string(pdev->dev.of_node, - "qcom,proc-img-to-load", - &img_name); - if (rc) - goto fail; - - if (!strcmp(img_name, "cdsp")) { - /* cdsp_state always returns "0".*/ - if (cdsp_state == CDSP_SUBSYS_DOWN) { - priv = platform_get_drvdata(pdev); - if (!priv) { - dev_err(&pdev->dev, - " %s: Private data get failed\n", __func__); - goto fail; - } - - priv->pil_h = subsystem_get("cdsp"); - if (IS_ERR(priv->pil_h)) { - dev_err(&pdev->dev, "%s: pil get failed,\n", - __func__); - goto fail; - } - - /* Set the state of the CDSP.*/ - cdsp_state = CDSP_SUBSYS_LOADED; - } else if (cdsp_state == CDSP_SUBSYS_LOADED) { - dev_dbg(&pdev->dev, - "%s: CDSP state = %x\n", __func__, cdsp_state); - } - - dev_dbg(&pdev->dev, "%s: CDSP image is loaded\n", __func__); - return; - } - -fail: - dev_err(&pdev->dev, "%s: CDSP image loading failed\n", __func__); -} - -static void cdsp_loader_do(struct platform_device *pdev) -{ - schedule_work(&cdsp_ldr_work); -} - -static ssize_t cdsp_boot_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, - size_t count) -{ - int boot = 0, ret = 0; - - ret = sscanf(buf, "%du", &boot); - - if (ret != 1) - pr_debug("%s: invalid arguments for cdsp_loader.\n", __func__); - - if (boot == BOOT_CMD) { - pr_debug("%s: going to call cdsp_loader_do\n", __func__); - cdsp_loader_do(cdsp_private); - } else if (boot == IMAGE_UNLOAD_CMD) { - pr_debug("%s: going to call cdsp_unloader\n", __func__); - cdsp_loader_unload(cdsp_private); - } - return count; -} - -static void cdsp_loader_unload(struct platform_device *pdev) -{ - struct cdsp_loader_private *priv = NULL; - - priv = platform_get_drvdata(pdev); - - if (!priv) - return; - - if (priv->pil_h) { - dev_dbg(&pdev->dev, "%s: calling subsystem put\n", __func__); - subsystem_put(priv->pil_h); - priv->pil_h = NULL; - } -} - -static int cdsp_loader_init_sysfs(struct platform_device *pdev) -{ - int ret = -EINVAL; - struct cdsp_loader_private *priv = NULL; - - cdsp_private = NULL; - - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - ret = -ENOMEM; - return ret; - } - - platform_set_drvdata(pdev, priv); - - priv->pil_h = NULL; - priv->boot_cdsp_obj = NULL; - priv->attr_group = devm_kzalloc(&pdev->dev, - sizeof(*(priv->attr_group)), - GFP_KERNEL); - if (!priv->attr_group) { - dev_err(&pdev->dev, "%s: malloc attr_group failed\n", - __func__); - ret = -ENOMEM; - goto error_return; - } - - priv->attr_group->attrs = attrs; - - priv->boot_cdsp_obj = kobject_create_and_add("boot_cdsp", kernel_kobj); - if (!priv->boot_cdsp_obj) { - dev_err(&pdev->dev, "%s: sysfs create and add failed\n", - __func__); - ret = -ENOMEM; - goto error_return; - } - - ret = sysfs_create_group(priv->boot_cdsp_obj, priv->attr_group); - if (ret) { - dev_err(&pdev->dev, "%s: sysfs create group failed %d\n", - __func__, ret); - goto error_return; - } - - cdsp_private = pdev; - - return 0; - -error_return: - - if (priv->boot_cdsp_obj) { - kobject_del(priv->boot_cdsp_obj); - priv->boot_cdsp_obj = NULL; - } - - return ret; -} - -static int cdsp_loader_remove(struct platform_device *pdev) -{ - struct cdsp_loader_private *priv = NULL; - - priv = platform_get_drvdata(pdev); - - if (!priv) - return 0; - - if (priv->pil_h) { - subsystem_put(priv->pil_h); - priv->pil_h = NULL; - } - - if (priv->boot_cdsp_obj) { - sysfs_remove_group(priv->boot_cdsp_obj, priv->attr_group); - kobject_del(priv->boot_cdsp_obj); - priv->boot_cdsp_obj = NULL; - } - - return 0; -} - -static int cdsp_loader_probe(struct platform_device *pdev) -{ - int ret = cdsp_loader_init_sysfs(pdev); - - if (ret != 0) { - dev_err(&pdev->dev, "%s: Error in initing sysfs\n", __func__); - return ret; - } - - INIT_WORK(&cdsp_ldr_work, cdsp_load_fw); - - return 0; -} - -static const struct of_device_id cdsp_loader_dt_match[] = { - { .compatible = "qcom,cdsp-loader" }, - { } -}; -MODULE_DEVICE_TABLE(of, cdsp_loader_dt_match); - -static struct platform_driver cdsp_loader_driver = { - .driver = { - .name = "cdsp-loader", - .owner = THIS_MODULE, - .of_match_table = cdsp_loader_dt_match, - }, - .probe = cdsp_loader_probe, - .remove = cdsp_loader_remove, -}; - -static int __init cdsp_loader_init(void) -{ - return platform_driver_register(&cdsp_loader_driver); -} -module_init(cdsp_loader_init); - -static void __exit cdsp_loader_exit(void) -{ - platform_driver_unregister(&cdsp_loader_driver); -} -module_exit(cdsp_loader_exit); - -MODULE_DESCRIPTION("CDSP Loader module"); -MODULE_LICENSE("GPL v2"); diff --git a/ipc/Makefile b/ipc/Makefile index fd840c94d178..69389153b7c4 100644 --- a/ipc/Makefile +++ b/ipc/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_MSM_QDSP6_APRV2_GLINK) += apr.o apr_v2.o apr_tal_glink.o obj-$(CONFIG_MSM_QDSP6_APRV3_GLINK) += apr.o apr_v3.o apr_tal_glink.o +obj-$(CONFIG_WCD_DSP_GLINK) += wcd-dsp-glink.o diff --git a/ipc/wcd-dsp-glink.c b/ipc/wcd-dsp-glink.c new file mode 100644 index 000000000000..870b9f7455d3 --- /dev/null +++ b/ipc/wcd-dsp-glink.c @@ -0,0 +1,1201 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sound/wcd-dsp-glink.h" + +#define WDSP_GLINK_DRIVER_NAME "wcd-dsp-glink" +#define WDSP_MAX_WRITE_SIZE (256 * 1024) +#define WDSP_MAX_READ_SIZE (4 * 1024) +#define WDSP_MAX_NO_OF_INTENTS (20) +#define WDSP_MAX_NO_OF_CHANNELS (10) +#define WDSP_WRITE_PKT_SIZE (sizeof(struct wdsp_write_pkt)) +#define WDSP_REG_PKT_SIZE (sizeof(struct wdsp_reg_pkt)) +#define WDSP_CMD_PKT_SIZE (sizeof(struct wdsp_cmd_pkt)) +#define WDSP_CH_CFG_SIZE (sizeof(struct wdsp_glink_ch_cfg)) + +#define MINOR_NUMBER_COUNT 1 +#define WDSP_EDGE "wdsp" +#define RESP_QUEUE_SIZE 3 +#define QOS_PKT_SIZE 1024 +#define TIMEOUT_MS 1000 + +struct wdsp_glink_dev { + struct class *cls; + struct device *dev; + struct cdev cdev; + dev_t dev_num; +}; + +struct wdsp_glink_rsp_que { + /* Size of valid data in buffer */ + u32 buf_size; + + /* Response buffer */ + u8 buf[WDSP_MAX_READ_SIZE]; +}; + +struct wdsp_glink_tx_buf { + struct work_struct tx_work; + struct work_struct free_tx_work; + + /* Glink channel information */ + struct wdsp_glink_ch *ch; + + /* Tx buffer to send to glink */ + u8 buf[0]; +}; + +struct wdsp_glink_ch { + struct wdsp_glink_priv *wpriv; + + /* Glink channel handle */ + void *handle; + + /* Channel states like connect, disconnect */ + int channel_state; + struct mutex mutex; + + /* To free up the channel memory */ + bool free_mem; + + /* Glink local channel open work */ + struct work_struct lcl_ch_open_wrk; + + /* Glink local channel close work */ + struct work_struct lcl_ch_cls_wrk; + + /* Wait for ch connect state before sending any command */ + wait_queue_head_t ch_connect_wait; + + /* + * Glink channel configuration. This has to be the last + * member of the strucuture as it has variable size + */ + struct wdsp_glink_ch_cfg ch_cfg; +}; + +struct wdsp_glink_state { + /* Glink link state information */ + enum glink_link_state link_state; + void *handle; +}; + +struct wdsp_glink_priv { + /* Respone buffer related */ + u8 rsp_cnt; + struct wdsp_glink_rsp_que rsp[RESP_QUEUE_SIZE]; + struct completion rsp_complete; + struct mutex rsp_mutex; + + /* Glink channel related */ + struct mutex glink_mutex; + struct wdsp_glink_state glink_state; + struct wdsp_glink_ch **ch; + u8 no_of_channels; + struct work_struct ch_open_cls_wrk; + struct workqueue_struct *work_queue; + + wait_queue_head_t link_state_wait; + + struct device *dev; +}; + +static int wdsp_glink_close_ch(struct wdsp_glink_ch *ch); +static int wdsp_glink_open_ch(struct wdsp_glink_ch *ch); + +/* + * wdsp_glink_free_tx_buf_work - Work function to free tx pkt + * work: Work structure + */ +static void wdsp_glink_free_tx_buf_work(struct work_struct *work) +{ + struct wdsp_glink_tx_buf *tx_buf; + + tx_buf = container_of(work, struct wdsp_glink_tx_buf, + free_tx_work); + vfree(tx_buf); +} + +/* + * wdsp_glink_free_tx_buf - Function to free tx buffer + * priv: Pointer to the channel + * pkt_priv: Pointer to the tx buffer + */ +static void wdsp_glink_free_tx_buf(const void *priv, const void *pkt_priv) +{ + struct wdsp_glink_tx_buf *tx_buf = (struct wdsp_glink_tx_buf *)pkt_priv; + struct wdsp_glink_priv *wpriv; + struct wdsp_glink_ch *ch; + + if (!priv) { + pr_err("%s: Invalid priv\n", __func__); + return; + } + if (!tx_buf) { + pr_err("%s: Invalid tx_buf\n", __func__); + return; + } + + ch = (struct wdsp_glink_ch *)priv; + wpriv = ch->wpriv; + /* Work queue to free tx pkt */ + INIT_WORK(&tx_buf->free_tx_work, wdsp_glink_free_tx_buf_work); + queue_work(wpriv->work_queue, &tx_buf->free_tx_work); +} + +/* + * wdsp_glink_notify_rx - Glink notify rx callback for responses + * handle: Opaque Channel handle returned by GLink + * priv: Private pointer to the channel + * pkt_priv: Private pointer to the packet + * ptr: Pointer to the Rx data + * size: Size of the Rx data + */ +static void wdsp_glink_notify_rx(void *handle, const void *priv, + const void *pkt_priv, const void *ptr, + size_t size) +{ + u8 *rx_buf; + u8 rsp_cnt; + struct wdsp_glink_ch *ch; + struct wdsp_glink_priv *wpriv; + + if (!ptr || !priv) { + pr_err("%s: Invalid parameters\n", __func__); + return; + } + + ch = (struct wdsp_glink_ch *)priv; + wpriv = ch->wpriv; + rx_buf = (u8 *)ptr; + if (size > WDSP_MAX_READ_SIZE) { + dev_err(wpriv->dev, "%s: Size %zd is greater than allowed %d\n", + __func__, size, WDSP_MAX_READ_SIZE); + size = WDSP_MAX_READ_SIZE; + } + + mutex_lock(&wpriv->rsp_mutex); + rsp_cnt = wpriv->rsp_cnt; + if (rsp_cnt >= RESP_QUEUE_SIZE) { + dev_err(wpriv->dev, "%s: Resp Queue is Full\n", __func__); + rsp_cnt = 0; + } + dev_dbg(wpriv->dev, "%s: copy into buffer %d\n", __func__, rsp_cnt); + + memcpy(wpriv->rsp[rsp_cnt].buf, rx_buf, size); + wpriv->rsp[rsp_cnt].buf_size = size; + wpriv->rsp_cnt = ++rsp_cnt; + mutex_unlock(&wpriv->rsp_mutex); + + glink_rx_done(handle, ptr, true); + complete(&wpriv->rsp_complete); +} + +/* + * wdsp_glink_notify_tx_done - Glink notify tx done callback to + * free tx buffer + * handle: Opaque Channel handle returned by GLink + * priv: Private pointer to the channel + * pkt_priv: Private pointer to the packet + * ptr: Pointer to the Tx data + */ +static void wdsp_glink_notify_tx_done(void *handle, const void *priv, + const void *pkt_priv, const void *ptr) +{ + wdsp_glink_free_tx_buf(priv, pkt_priv); +} +/* + * wdsp_glink_notify_tx_abort - Glink notify tx abort callback to + * free tx buffer + * handle: Opaque Channel handle returned by GLink + * priv: Private pointer to the channel + * pkt_priv: Private pointer to the packet + */ +static void wdsp_glink_notify_tx_abort(void *handle, const void *priv, + const void *pkt_priv) +{ + wdsp_glink_free_tx_buf(priv, pkt_priv); +} + +/* + * wdsp_glink_notify_rx_intent_req - Glink notify rx intent request callback + * to queue buffer to receive from remote client + * handle: Opaque channel handle returned by GLink + * priv: Private pointer to the channel + * req_size: Size of intent to be queued + */ +static bool wdsp_glink_notify_rx_intent_req(void *handle, const void *priv, + size_t req_size) +{ + struct wdsp_glink_priv *wpriv; + struct wdsp_glink_ch *ch; + int rc = 0; + bool ret = false; + + if (!priv) { + pr_err("%s: Invalid priv\n", __func__); + goto done; + } + if (req_size > WDSP_MAX_READ_SIZE) { + pr_err("%s: Invalid req_size %zd\n", __func__, req_size); + goto done; + } + + ch = (struct wdsp_glink_ch *)priv; + wpriv = ch->wpriv; + + dev_dbg(wpriv->dev, "%s: intent size %zd requested for ch name %s", + __func__, req_size, ch->ch_cfg.name); + + mutex_lock(&ch->mutex); + rc = glink_queue_rx_intent(ch->handle, ch, req_size); + if (rc < 0) { + dev_err(wpriv->dev, "%s: Failed to queue rx intent, rc = %d\n", + __func__, rc); + mutex_unlock(&ch->mutex); + goto done; + } + mutex_unlock(&ch->mutex); + ret = true; + +done: + return ret; +} + +/* + * wdsp_glink_lcl_ch_open_wrk - Work function to open channel again + * when local disconnect event happens + * work: Work structure + */ +static void wdsp_glink_lcl_ch_open_wrk(struct work_struct *work) +{ + struct wdsp_glink_ch *ch; + + ch = container_of(work, struct wdsp_glink_ch, + lcl_ch_open_wrk); + + wdsp_glink_open_ch(ch); +} + +/* + * wdsp_glink_lcl_ch_cls_wrk - Work function to close channel locally + * when remote disconnect event happens + * work: Work structure + */ +static void wdsp_glink_lcl_ch_cls_wrk(struct work_struct *work) +{ + struct wdsp_glink_ch *ch; + + ch = container_of(work, struct wdsp_glink_ch, + lcl_ch_cls_wrk); + + wdsp_glink_close_ch(ch); +} + +/* + * wdsp_glink_notify_state - Glink channel state information event callback + * handle: Opaque Channel handle returned by GLink + * priv: Private pointer to the channel + * event: channel state event + */ +static void wdsp_glink_notify_state(void *handle, const void *priv, + unsigned int event) +{ + struct wdsp_glink_priv *wpriv; + struct wdsp_glink_ch *ch; + int i, ret = 0; + + if (!priv) { + pr_err("%s: Invalid priv\n", __func__); + return; + } + + ch = (struct wdsp_glink_ch *)priv; + wpriv = ch->wpriv; + + mutex_lock(&ch->mutex); + ch->channel_state = event; + if (event == GLINK_CONNECTED) { + dev_dbg(wpriv->dev, "%s: glink channel: %s connected\n", + __func__, ch->ch_cfg.name); + + for (i = 0; i < ch->ch_cfg.no_of_intents; i++) { + dev_dbg(wpriv->dev, "%s: intent_size = %d\n", __func__, + ch->ch_cfg.intents_size[i]); + ret = glink_queue_rx_intent(ch->handle, ch, + ch->ch_cfg.intents_size[i]); + if (ret < 0) + dev_warn(wpriv->dev, "%s: Failed to queue intent %d of size %d\n", + __func__, i, + ch->ch_cfg.intents_size[i]); + } + + ret = glink_qos_latency(ch->handle, ch->ch_cfg.latency_in_us, + QOS_PKT_SIZE); + if (ret < 0) + dev_warn(wpriv->dev, "%s: Failed to request qos %d for ch %s\n", + __func__, ch->ch_cfg.latency_in_us, + ch->ch_cfg.name); + + wake_up(&ch->ch_connect_wait); + mutex_unlock(&ch->mutex); + } else if (event == GLINK_LOCAL_DISCONNECTED) { + /* + * Don't use dev_dbg here as dev may not be valid if channel + * closed from driver close. + */ + pr_debug("%s: channel: %s disconnected locally\n", + __func__, ch->ch_cfg.name); + mutex_unlock(&ch->mutex); + + if (ch->free_mem) { + kfree(ch); + ch = NULL; + } + } else if (event == GLINK_REMOTE_DISCONNECTED) { + dev_dbg(wpriv->dev, "%s: remote channel: %s disconnected remotely\n", + __func__, ch->ch_cfg.name); + mutex_unlock(&ch->mutex); + /* + * If remote disconnect happens, local side also has + * to close the channel as per glink design in a + * separate work_queue. + */ + queue_work(wpriv->work_queue, &ch->lcl_ch_cls_wrk); + } +} + +/* + * wdsp_glink_close_ch - Internal function to close glink channel + * ch: Glink Channel structure. + */ +static int wdsp_glink_close_ch(struct wdsp_glink_ch *ch) +{ + struct wdsp_glink_priv *wpriv = ch->wpriv; + int ret = 0; + + mutex_lock(&wpriv->glink_mutex); + if (ch->handle) { + ret = glink_close(ch->handle); + if (ret < 0) { + dev_err(wpriv->dev, "%s: glink_close is failed, ret = %d\n", + __func__, ret); + } else { + ch->handle = NULL; + dev_dbg(wpriv->dev, "%s: ch %s is closed\n", __func__, + ch->ch_cfg.name); + } + } else { + dev_dbg(wpriv->dev, "%s: ch %s is already closed\n", __func__, + ch->ch_cfg.name); + } + mutex_unlock(&wpriv->glink_mutex); + + + return ret; +} + +/* + * wdsp_glink_open_ch - Internal function to open glink channel + * ch: Glink Channel structure. + */ +static int wdsp_glink_open_ch(struct wdsp_glink_ch *ch) +{ + struct wdsp_glink_priv *wpriv = ch->wpriv; + struct glink_open_config open_cfg; + int ret = 0; + + mutex_lock(&wpriv->glink_mutex); + if (!ch->handle) { + memset(&open_cfg, 0, sizeof(open_cfg)); + open_cfg.options = GLINK_OPT_INITIAL_XPORT; + open_cfg.edge = WDSP_EDGE; + open_cfg.notify_rx = wdsp_glink_notify_rx; + open_cfg.notify_tx_done = wdsp_glink_notify_tx_done; + open_cfg.notify_tx_abort = wdsp_glink_notify_tx_abort; + open_cfg.notify_state = wdsp_glink_notify_state; + open_cfg.notify_rx_intent_req = wdsp_glink_notify_rx_intent_req; + open_cfg.priv = ch; + open_cfg.name = ch->ch_cfg.name; + + dev_dbg(wpriv->dev, "%s: ch->ch_cfg.name = %s, latency_in_us = %d, intents = %d\n", + __func__, ch->ch_cfg.name, ch->ch_cfg.latency_in_us, + ch->ch_cfg.no_of_intents); + + ch->handle = glink_open(&open_cfg); + if (IS_ERR_OR_NULL(ch->handle)) { + dev_err(wpriv->dev, "%s: glink_open failed for ch %s\n", + __func__, ch->ch_cfg.name); + ch->handle = NULL; + ret = -EINVAL; + } + } else { + dev_err(wpriv->dev, "%s: ch %s is already opened\n", __func__, + ch->ch_cfg.name); + } + mutex_unlock(&wpriv->glink_mutex); + + return ret; +} + +/* + * wdsp_glink_close_all_ch - Internal function to close all glink channels + * wpriv: Wdsp_glink private structure + */ +static void wdsp_glink_close_all_ch(struct wdsp_glink_priv *wpriv) +{ + int i; + + for (i = 0; i < wpriv->no_of_channels; i++) + if (wpriv->ch && wpriv->ch[i]) + wdsp_glink_close_ch(wpriv->ch[i]); +} + +/* + * wdsp_glink_open_all_ch - Internal function to open all glink channels + * wpriv: Wdsp_glink private structure + */ +static int wdsp_glink_open_all_ch(struct wdsp_glink_priv *wpriv) +{ + int ret = 0, i, j; + + for (i = 0; i < wpriv->no_of_channels; i++) { + if (wpriv->ch && wpriv->ch[i]) { + ret = wdsp_glink_open_ch(wpriv->ch[i]); + if (ret < 0) + goto err_open; + } + } + goto done; + +err_open: + for (j = 0; j < i; j++) + if (wpriv->ch[i]) + wdsp_glink_close_ch(wpriv->ch[j]); + +done: + return ret; +} + +/* + * wdsp_glink_ch_open_wq - Work function to open glink channels + * work: Work structure + */ +static void wdsp_glink_ch_open_cls_wrk(struct work_struct *work) +{ + struct wdsp_glink_priv *wpriv; + + wpriv = container_of(work, struct wdsp_glink_priv, + ch_open_cls_wrk); + + if (wpriv->glink_state.link_state == GLINK_LINK_STATE_DOWN) { + dev_info(wpriv->dev, "%s: GLINK_LINK_STATE_DOWN\n", + __func__); + + wdsp_glink_close_all_ch(wpriv); + } else if (wpriv->glink_state.link_state == GLINK_LINK_STATE_UP) { + dev_info(wpriv->dev, "%s: GLINK_LINK_STATE_UP\n", + __func__); + + wdsp_glink_open_all_ch(wpriv); + } +} + +/* + * wdsp_glink_link_state_cb - Glink link state callback to inform + * about link states + * cb_info: Glink link state callback information structure + * priv: Private structure of link state passed while register + */ +static void wdsp_glink_link_state_cb(struct glink_link_state_cb_info *cb_info, + void *priv) +{ + struct wdsp_glink_priv *wpriv; + + if (!cb_info || !priv) { + pr_err("%s: Invalid parameters\n", __func__); + return; + } + + wpriv = (struct wdsp_glink_priv *)priv; + + mutex_lock(&wpriv->glink_mutex); + wpriv->glink_state.link_state = cb_info->link_state; + wake_up(&wpriv->link_state_wait); + mutex_unlock(&wpriv->glink_mutex); + + queue_work(wpriv->work_queue, &wpriv->ch_open_cls_wrk); +} + +/* + * wdsp_glink_ch_info_init- Internal function to allocate channel memory + * and register with glink + * wpriv: Wdsp_glink private structure. + * pkt: Glink registration packet contains glink channel information. + * pkt_size: Size of the pkt. + */ +static int wdsp_glink_ch_info_init(struct wdsp_glink_priv *wpriv, + struct wdsp_reg_pkt *pkt, size_t pkt_size) +{ + int ret = 0, i, j; + struct glink_link_info link_info; + struct wdsp_glink_ch_cfg *ch_cfg; + struct wdsp_glink_ch **ch; + u8 no_of_channels; + u8 *payload; + u32 ch_size, ch_cfg_size; + size_t size = WDSP_WRITE_PKT_SIZE + WDSP_REG_PKT_SIZE; + + mutex_lock(&wpriv->glink_mutex); + if (wpriv->ch) { + dev_err(wpriv->dev, "%s: glink ch memory is already allocated\n", + __func__); + ret = -EINVAL; + goto done; + } + payload = (u8 *)pkt->payload; + no_of_channels = pkt->no_of_channels; + + if (no_of_channels > WDSP_MAX_NO_OF_CHANNELS) { + dev_err(wpriv->dev, "%s: no_of_channels: %d but max allowed are %d\n", + __func__, no_of_channels, WDSP_MAX_NO_OF_CHANNELS); + ret = -EINVAL; + goto done; + } + ch = kcalloc(no_of_channels, sizeof(struct wdsp_glink_ch *), + GFP_ATOMIC); + if (!ch) { + ret = -ENOMEM; + goto done; + } + wpriv->ch = ch; + wpriv->no_of_channels = no_of_channels; + + for (i = 0; i < no_of_channels; i++) { + ch_cfg = (struct wdsp_glink_ch_cfg *)payload; + + size += WDSP_CH_CFG_SIZE; + if (size > pkt_size) { + dev_err(wpriv->dev, "%s: Invalid size = %zd, pkt_size = %zd\n", + __func__, size, pkt_size); + ret = -EINVAL; + goto err_ch_mem; + } + if (ch_cfg->no_of_intents > WDSP_MAX_NO_OF_INTENTS) { + dev_err(wpriv->dev, "%s: Invalid no_of_intents = %d\n", + __func__, ch_cfg->no_of_intents); + ret = -EINVAL; + goto err_ch_mem; + } + size += (sizeof(u32) * ch_cfg->no_of_intents); + if (size > pkt_size) { + dev_err(wpriv->dev, "%s: Invalid size = %zd, pkt_size = %zd\n", + __func__, size, pkt_size); + ret = -EINVAL; + goto err_ch_mem; + } + + ch_cfg_size = sizeof(struct wdsp_glink_ch_cfg) + + (sizeof(u32) * ch_cfg->no_of_intents); + ch_size = sizeof(struct wdsp_glink_ch) + + (sizeof(u32) * ch_cfg->no_of_intents); + + dev_dbg(wpriv->dev, "%s: channels: %d ch_cfg_size: %d, size: %zd, pkt_size: %zd", + __func__, no_of_channels, ch_cfg_size, size, pkt_size); + + ch[i] = kzalloc(ch_size, GFP_KERNEL); + if (!ch[i]) { + ret = -ENOMEM; + goto err_ch_mem; + } + ch[i]->channel_state = GLINK_LOCAL_DISCONNECTED; + memcpy(&ch[i]->ch_cfg, payload, ch_cfg_size); + payload += ch_cfg_size; + + mutex_init(&ch[i]->mutex); + ch[i]->wpriv = wpriv; + INIT_WORK(&ch[i]->lcl_ch_open_wrk, wdsp_glink_lcl_ch_open_wrk); + INIT_WORK(&ch[i]->lcl_ch_cls_wrk, wdsp_glink_lcl_ch_cls_wrk); + init_waitqueue_head(&ch[i]->ch_connect_wait); + } + + INIT_WORK(&wpriv->ch_open_cls_wrk, wdsp_glink_ch_open_cls_wrk); + + /* Register glink link_state notification */ + link_info.glink_link_state_notif_cb = wdsp_glink_link_state_cb; + link_info.transport = NULL; + link_info.edge = WDSP_EDGE; + + wpriv->glink_state.link_state = GLINK_LINK_STATE_DOWN; + wpriv->glink_state.handle = glink_register_link_state_cb(&link_info, + wpriv); + if (!wpriv->glink_state.handle) { + dev_err(wpriv->dev, "%s: Unable to register wdsp link state\n", + __func__); + ret = -EINVAL; + goto err_ch_mem; + } + goto done; + +err_ch_mem: + for (j = 0; j < i; j++) { + mutex_destroy(&ch[j]->mutex); + kfree(wpriv->ch[j]); + wpriv->ch[j] = NULL; + } + kfree(wpriv->ch); + wpriv->ch = NULL; + wpriv->no_of_channels = 0; + +done: + mutex_unlock(&wpriv->glink_mutex); + return ret; +} + +/* + * wdsp_glink_tx_buf_work - Work queue function to send tx buffer to glink + * work: Work structure + */ +static void wdsp_glink_tx_buf_work(struct work_struct *work) +{ + struct wdsp_glink_priv *wpriv; + struct wdsp_glink_ch *ch; + struct wdsp_glink_tx_buf *tx_buf; + struct wdsp_write_pkt *wpkt; + struct wdsp_cmd_pkt *cpkt; + int ret = 0; + + tx_buf = container_of(work, struct wdsp_glink_tx_buf, + tx_work); + ch = tx_buf->ch; + wpriv = ch->wpriv; + wpkt = (struct wdsp_write_pkt *)tx_buf->buf; + cpkt = (struct wdsp_cmd_pkt *)wpkt->payload; + dev_dbg(wpriv->dev, "%s: ch name = %s, payload size = %d\n", + __func__, cpkt->ch_name, cpkt->payload_size); + + mutex_lock(&tx_buf->ch->mutex); + if (ch->channel_state == GLINK_CONNECTED) { + mutex_unlock(&tx_buf->ch->mutex); + ret = glink_tx(ch->handle, tx_buf, + cpkt->payload, cpkt->payload_size, + GLINK_TX_REQ_INTENT); + if (ret < 0) { + dev_err(wpriv->dev, "%s: glink tx failed, ret = %d\n", + __func__, ret); + /* + * If glink_tx() is failed then free tx_buf here as + * there won't be any tx_done notification to + * free the buffer. + */ + vfree(tx_buf); + } + } else { + mutex_unlock(&tx_buf->ch->mutex); + dev_err(wpriv->dev, "%s: channel %s is not in connected state\n", + __func__, ch->ch_cfg.name); + /* + * Free tx_buf here as there won't be any tx_done + * notification in this case also. + */ + vfree(tx_buf); + } +} + +/* + * wdsp_glink_read - Read API to send the data to userspace + * file: Pointer to the file structure + * buf: Pointer to the userspace buffer + * count: Number bytes to read from the file + * ppos: Pointer to the position into the file + */ +static ssize_t wdsp_glink_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + int ret = 0, ret1 = 0; + struct wdsp_glink_rsp_que *rsp; + struct wdsp_glink_priv *wpriv; + + wpriv = (struct wdsp_glink_priv *)file->private_data; + if (!wpriv) { + pr_err("%s: Invalid private data\n", __func__); + ret = -EINVAL; + goto done; + } + + if (count > WDSP_MAX_READ_SIZE) { + dev_info(wpriv->dev, "%s: count = %zd is more than WDSP_MAX_READ_SIZE\n", + __func__, count); + count = WDSP_MAX_READ_SIZE; + } + /* + * Complete signal has given from glink rx notification callback + * or from flush API. Also use interruptible wait_for_completion API + * to allow the system to go in suspend. + */ + ret = wait_for_completion_interruptible(&wpriv->rsp_complete); + if (ret) + goto done; + + mutex_lock(&wpriv->rsp_mutex); + if (wpriv->rsp_cnt) { + wpriv->rsp_cnt--; + dev_dbg(wpriv->dev, "%s: read from buffer %d\n", + __func__, wpriv->rsp_cnt); + + rsp = &wpriv->rsp[wpriv->rsp_cnt]; + if (count < rsp->buf_size) { + ret1 = copy_to_user(buf, &rsp->buf, count); + /* Return the number of bytes copied */ + ret = count; + } else { + ret1 = copy_to_user(buf, &rsp->buf, rsp->buf_size); + /* Return the number of bytes copied */ + ret = rsp->buf_size; + } + + if (ret1) { + mutex_unlock(&wpriv->rsp_mutex); + dev_err(wpriv->dev, "%s: copy_to_user failed %d\n", + __func__, ret); + ret = -EFAULT; + goto done; + } + } else { + /* + * This will execute only if flush API is called or + * something wrong with ref_cnt + */ + dev_dbg(wpriv->dev, "%s: resp count = %d\n", __func__, + wpriv->rsp_cnt); + ret = -EINVAL; + } + mutex_unlock(&wpriv->rsp_mutex); + +done: + return ret; +} + +/* + * wdsp_glink_write - Write API to receive the data from userspace + * file: Pointer to the file structure + * buf: Pointer to the userspace buffer + * count: Number bytes to read from the file + * ppos: Pointer to the position into the file + */ +static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + int ret = 0, i, tx_buf_size; + struct wdsp_write_pkt *wpkt; + struct wdsp_cmd_pkt *cpkt; + struct wdsp_glink_tx_buf *tx_buf; + struct wdsp_glink_priv *wpriv; + size_t pkt_max_size; + + wpriv = (struct wdsp_glink_priv *)file->private_data; + if (!wpriv) { + pr_err("%s: Invalid private data\n", __func__); + ret = -EINVAL; + goto done; + } + + if ((count < WDSP_WRITE_PKT_SIZE) || + (count > WDSP_MAX_WRITE_SIZE)) { + dev_err(wpriv->dev, "%s: Invalid count = %zd\n", + __func__, count); + ret = -EINVAL; + goto done; + } + + dev_dbg(wpriv->dev, "%s: count = %zd\n", __func__, count); + + tx_buf_size = count + sizeof(struct wdsp_glink_tx_buf); + tx_buf = vzalloc(tx_buf_size); + if (!tx_buf) { + ret = -ENOMEM; + goto done; + } + + ret = copy_from_user(tx_buf->buf, buf, count); + if (ret) { + dev_err(wpriv->dev, "%s: copy_from_user failed %d\n", + __func__, ret); + ret = -EFAULT; + goto free_buf; + } + + wpkt = (struct wdsp_write_pkt *)tx_buf->buf; + switch (wpkt->pkt_type) { + case WDSP_REG_PKT: + if (count < (WDSP_WRITE_PKT_SIZE + WDSP_REG_PKT_SIZE + + WDSP_CH_CFG_SIZE)) { + dev_err(wpriv->dev, "%s: Invalid reg pkt size = %zd\n", + __func__, count); + ret = -EINVAL; + goto free_buf; + } + ret = wdsp_glink_ch_info_init(wpriv, + (struct wdsp_reg_pkt *)wpkt->payload, + count); + if (ret < 0) + dev_err(wpriv->dev, "%s: glink register failed, ret = %d\n", + __func__, ret); + vfree(tx_buf); + break; + case WDSP_READY_PKT: + ret = wait_event_timeout(wpriv->link_state_wait, + (wpriv->glink_state.link_state == + GLINK_LINK_STATE_UP), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + dev_err(wpriv->dev, "%s: Link state wait timeout\n", + __func__); + ret = -ETIMEDOUT; + goto free_buf; + } + ret = 0; + vfree(tx_buf); + break; + case WDSP_CMD_PKT: + if (count <= (WDSP_WRITE_PKT_SIZE + WDSP_CMD_PKT_SIZE)) { + dev_err(wpriv->dev, "%s: Invalid cmd pkt size = %zd\n", + __func__, count); + ret = -EINVAL; + goto free_buf; + } + mutex_lock(&wpriv->glink_mutex); + if (wpriv->glink_state.link_state == GLINK_LINK_STATE_DOWN) { + mutex_unlock(&wpriv->glink_mutex); + dev_err(wpriv->dev, "%s: Link state is Down\n", + __func__); + + ret = -ENETRESET; + goto free_buf; + } + mutex_unlock(&wpriv->glink_mutex); + cpkt = (struct wdsp_cmd_pkt *)wpkt->payload; + pkt_max_size = sizeof(struct wdsp_write_pkt) + + sizeof(struct wdsp_cmd_pkt) + + cpkt->payload_size; + if (count < pkt_max_size) { + dev_err(wpriv->dev, "%s: Invalid cmd pkt count = %zd, pkt_size = %zd\n", + __func__, count, pkt_max_size); + ret = -EINVAL; + goto free_buf; + } + dev_dbg(wpriv->dev, "%s: requested ch_name: %s, pkt_size: %zd\n", + __func__, cpkt->ch_name, pkt_max_size); + for (i = 0; i < wpriv->no_of_channels; i++) { + if (wpriv->ch && wpriv->ch[i] && + (!strcmp(cpkt->ch_name, + wpriv->ch[i]->ch_cfg.name))) { + tx_buf->ch = wpriv->ch[i]; + break; + } + } + if (!tx_buf->ch) { + dev_err(wpriv->dev, "%s: Failed to get glink channel\n", + __func__); + ret = -EINVAL; + goto free_buf; + } + + ret = wait_event_timeout(tx_buf->ch->ch_connect_wait, + (tx_buf->ch->channel_state == + GLINK_CONNECTED), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + dev_err(wpriv->dev, "%s: glink channel %s is not in connected state %d\n", + __func__, tx_buf->ch->ch_cfg.name, + tx_buf->ch->channel_state); + ret = -ETIMEDOUT; + goto free_buf; + } + ret = 0; + + INIT_WORK(&tx_buf->tx_work, wdsp_glink_tx_buf_work); + queue_work(wpriv->work_queue, &tx_buf->tx_work); + break; + default: + dev_err(wpriv->dev, "%s: Invalid packet type\n", __func__); + ret = -EINVAL; + vfree(tx_buf); + break; + } + goto done; + +free_buf: + vfree(tx_buf); + +done: + return ret; +} + +/* + * wdsp_glink_open - Open API to initialize private data + * inode: Pointer to the inode structure + * file: Pointer to the file structure + */ +static int wdsp_glink_open(struct inode *inode, struct file *file) +{ + int ret = 0; + struct wdsp_glink_priv *wpriv; + struct wdsp_glink_dev *wdev; + + if (!inode->i_cdev) { + pr_err("%s: cdev is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + wdev = container_of(inode->i_cdev, struct wdsp_glink_dev, cdev); + + wpriv = kzalloc(sizeof(struct wdsp_glink_priv), GFP_KERNEL); + if (!wpriv) { + ret = -ENOMEM; + goto done; + } + wpriv->dev = wdev->dev; + wpriv->work_queue = create_singlethread_workqueue("wdsp_glink_wq"); + if (!wpriv->work_queue) { + dev_err(wpriv->dev, "%s: Error creating wdsp_glink_wq\n", + __func__); + ret = -EINVAL; + goto err_wq; + } + + init_completion(&wpriv->rsp_complete); + init_waitqueue_head(&wpriv->link_state_wait); + mutex_init(&wpriv->rsp_mutex); + mutex_init(&wpriv->glink_mutex); + file->private_data = wpriv; + + goto done; + +err_wq: + kfree(wpriv); + +done: + return ret; +} + +/* + * wdsp_glink_flush - Flush API to unblock read. + * file: Pointer to the file structure + * id: Lock owner ID + */ +static int wdsp_glink_flush(struct file *file, fl_owner_t id) +{ + struct wdsp_glink_priv *wpriv; + + wpriv = (struct wdsp_glink_priv *)file->private_data; + if (!wpriv) { + pr_err("%s: Invalid private data\n", __func__); + return -EINVAL; + } + + complete(&wpriv->rsp_complete); + + return 0; +} + +/* + * wdsp_glink_release - Release API to clean up resources. + * Whenever a file structure is shared across multiple threads, + * release won't be invoked until all copies are closed + * (file->f_count.counter should be 0). If we need to flush pending + * data when any copy is closed, you should implement the flush method. + * + * inode: Pointer to the inode structure + * file: Pointer to the file structure + */ +static int wdsp_glink_release(struct inode *inode, struct file *file) +{ + int i, ret = 0; + struct wdsp_glink_priv *wpriv; + + wpriv = (struct wdsp_glink_priv *)file->private_data; + if (!wpriv) { + pr_err("%s: Invalid private data\n", __func__); + ret = -EINVAL; + goto done; + } + + if (wpriv->glink_state.handle) + glink_unregister_link_state_cb(wpriv->glink_state.handle); + + flush_workqueue(wpriv->work_queue); + destroy_workqueue(wpriv->work_queue); + + /* + * Clean up glink channel memory in channel state + * callback only if close channels are called from here. + */ + if (wpriv->ch) { + for (i = 0; i < wpriv->no_of_channels; i++) { + if (wpriv->ch[i]) { + wpriv->ch[i]->free_mem = true; + /* + * Channel handle NULL means channel is already + * closed. Free the channel memory here itself. + */ + if (!wpriv->ch[i]->handle) { + kfree(wpriv->ch[i]); + wpriv->ch[i] = NULL; + } else { + wdsp_glink_close_ch(wpriv->ch[i]); + } + } + } + + kfree(wpriv->ch); + wpriv->ch = NULL; + } + + mutex_destroy(&wpriv->glink_mutex); + mutex_destroy(&wpriv->rsp_mutex); + kfree(wpriv); + file->private_data = NULL; + +done: + return ret; +} + +static const struct file_operations wdsp_glink_fops = { + .owner = THIS_MODULE, + .open = wdsp_glink_open, + .read = wdsp_glink_read, + .write = wdsp_glink_write, + .flush = wdsp_glink_flush, + .release = wdsp_glink_release, +}; + +/* + * wdsp_glink_probe - Driver probe to expose char device + * pdev: Pointer to device tree data. + */ +static int wdsp_glink_probe(struct platform_device *pdev) +{ + int ret; + struct wdsp_glink_dev *wdev; + + wdev = devm_kzalloc(&pdev->dev, sizeof(*wdev), GFP_KERNEL); + if (!wdev) { + ret = -ENOMEM; + goto done; + } + + ret = alloc_chrdev_region(&wdev->dev_num, 0, MINOR_NUMBER_COUNT, + WDSP_GLINK_DRIVER_NAME); + if (ret < 0) { + dev_err(&pdev->dev, "%s: Failed to alloc char dev, err = %d\n", + __func__, ret); + goto err_chrdev; + } + + wdev->cls = class_create(THIS_MODULE, WDSP_GLINK_DRIVER_NAME); + if (IS_ERR(wdev->cls)) { + ret = PTR_ERR(wdev->cls); + dev_err(&pdev->dev, "%s: Failed to create class, err = %d\n", + __func__, ret); + goto err_class; + } + + wdev->dev = device_create(wdev->cls, NULL, wdev->dev_num, + NULL, WDSP_GLINK_DRIVER_NAME); + if (IS_ERR(wdev->dev)) { + ret = PTR_ERR(wdev->dev); + dev_err(&pdev->dev, "%s: Failed to create device, err = %d\n", + __func__, ret); + goto err_dev_create; + } + + cdev_init(&wdev->cdev, &wdsp_glink_fops); + ret = cdev_add(&wdev->cdev, wdev->dev_num, MINOR_NUMBER_COUNT); + if (ret < 0) { + dev_err(&pdev->dev, "%s: Failed to register char dev, err = %d\n", + __func__, ret); + goto err_cdev_add; + } + platform_set_drvdata(pdev, wdev); + goto done; + +err_cdev_add: + device_destroy(wdev->cls, wdev->dev_num); + +err_dev_create: + class_destroy(wdev->cls); + +err_class: + unregister_chrdev_region(0, MINOR_NUMBER_COUNT); + +err_chrdev: + devm_kfree(&pdev->dev, wdev); + +done: + return ret; +} + +/* + * wdsp_glink_remove - Driver remove to handle cleanup + * pdev: Pointer to device tree data. + */ +static int wdsp_glink_remove(struct platform_device *pdev) +{ + struct wdsp_glink_dev *wdev = platform_get_drvdata(pdev); + + if (wdev) { + cdev_del(&wdev->cdev); + device_destroy(wdev->cls, wdev->dev_num); + class_destroy(wdev->cls); + unregister_chrdev_region(0, MINOR_NUMBER_COUNT); + devm_kfree(&pdev->dev, wdev); + } else { + dev_err(&pdev->dev, "%s: Invalid device data\n", __func__); + } + + return 0; +} + +static const struct of_device_id wdsp_glink_of_match[] = { + {.compatible = "qcom,wcd-dsp-glink"}, + { } +}; +MODULE_DEVICE_TABLE(of, wdsp_glink_of_match); + +static struct platform_driver wdsp_glink_driver = { + .probe = wdsp_glink_probe, + .remove = wdsp_glink_remove, + .driver = { + .name = WDSP_GLINK_DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = wdsp_glink_of_match, + }, +}; + +module_platform_driver(wdsp_glink_driver); + +MODULE_DESCRIPTION("SoC WCD_DSP GLINK Driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 71ca58e195db0752381aa16ea07352de7a37fd08 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 3 Aug 2017 18:58:09 +0530 Subject: [PATCH 0008/1645] autoconf: Enable config for wdsp-glink/avtimer Enable the configs for WCD DSP Glink and avtimer drivers. Remove the CDSP Loader config as it is not audio related. Change-Id: Ic6101e106c1e1d91bece6f53d1572507570b6b6f Signed-off-by: Laxminath Kasam --- config/sdm845auto.conf | 3 ++- config/sdm845autoconf.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/config/sdm845auto.conf b/config/sdm845auto.conf index f9a7748a3fde..b6d4231ff275 100644 --- a/config/sdm845auto.conf +++ b/config/sdm845auto.conf @@ -20,7 +20,6 @@ CONFIG_REGMAP_SWR=y CONFIG_MSM_QDSP6_SSR=y CONFIG_MSM_QDSP6_PDR=y CONFIG_MSM_QDSP6_NOTIFIER=y -CONFIG_MSM_CDSP_LOADER=y CONFIG_SND_SOC_MSM_HOSTLESS_PCM=y CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y CONFIG_SND_SOC_SDM845=y @@ -39,3 +38,5 @@ CONFIG_DOLBY_LICENSE=y CONFIG_DTS_SRS_TM=y CONFIG_SND_SOC_MACHINE_SDM845=y CONFIG_SND_SOC_MSM_STUB=y +CONFIG_WCD_DSP_GLINK=y +CONFIG_MSM_AVTIMER=y diff --git a/config/sdm845autoconf.h b/config/sdm845autoconf.h index 6c3bb330656d..7e9de815db80 100644 --- a/config/sdm845autoconf.h +++ b/config/sdm845autoconf.h @@ -34,7 +34,6 @@ #define CONFIG_MSM_QDSP6_SSR 1 #define CONFIG_MSM_QDSP6_PDR 1 #define CONFIG_MSM_QDSP6_NOTIFIER 1 -#define CONFIG_MSM_CDSP_LOADER 1 #define CONFIG_SND_SOC_MSM_HOSTLESS_PCM 1 #define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 #define CONFIG_SND_SOC_SDM845 1 @@ -53,3 +52,5 @@ #define CONFIG_DTS_SRS_TM 1 #define CONFIG_WCD9XXX_CODEC_CORE 1 #define CONFIG_SND_SOC_MSM_STUB 1 +#define CONFIG_WCD_DSP_GLINK 1 +#define CONFIG_MSM_AVTIMER 1 -- GitLab From 34504581a0a6ed64b2f342867432f9628b48f0a9 Mon Sep 17 00:00:00 2001 From: Asish Bhattacharya Date: Tue, 8 Aug 2017 12:55:01 +0530 Subject: [PATCH 0009/1645] audio-lnx: Add snapshot of audio drivers from below commit. (1996ec83a45: "ARM: dts: msm: Reduce CNOC bus voting for USB slave on SDM845") This change is to migrate latest snapshot of kernel drivers. Change-Id: I84669db544773d3ce9d2d5dff0ab6943bd7d8ff9 Signed-off-by: Asish Bhattacharya --- asoc/codecs/sdm660_cdc/msm-digital-cdc.c | 5 +- asoc/codecs/wcd9335.c | 50 ++--- asoc/codecs/wcd934x/wcd934x.c | 40 ++-- asoc/msm-dai-fe.c | 15 +- asoc/msm-pcm-routing-v2.c | 228 ++++++++++++++++++----- asoc/msm8996.c | 7 +- asoc/msm8998.c | 7 +- asoc/sdm660-ext-dai-links.c | 6 +- asoc/sdm660-internal.c | 6 +- asoc/sdm845.c | 96 +++++++++- dsp/q6adm.c | 16 +- 11 files changed, 345 insertions(+), 131 deletions(-) diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c index f59b653323c3..3df917f717b5 100644 --- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -9,7 +9,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ - #include #include #include @@ -122,9 +121,7 @@ static void disable_digital_callback(void *flag) static int msm_dig_cdc_put_dec_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *w = wlist->widgets[0]; + struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int dec_mux, decimator; diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 26a5a9de362b..2f877160bf66 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -2261,9 +2261,8 @@ static const struct snd_kcontrol_new hph_type_detect_controls[] = { static int tasha_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); @@ -2275,9 +2274,8 @@ static int tasha_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, static int tasha_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); struct wcd9xxx *core = tasha_p->wcd9xxx; @@ -2328,9 +2326,8 @@ static int tasha_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); @@ -2341,9 +2338,8 @@ static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol, static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); @@ -2436,9 +2432,8 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, static int slim_rx_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); @@ -2454,9 +2449,8 @@ static const char *const slim_rx_mux_text[] = { static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); @@ -8505,9 +8499,8 @@ static const struct snd_kcontrol_new tasha_snd_controls[] = { static int tasha_put_dec_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val; @@ -8565,9 +8558,8 @@ static int tasha_put_dec_enum(struct snd_kcontrol *kcontrol, static int tasha_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val; @@ -8899,9 +8891,8 @@ static int tasha_codec_configure_cpe_input(struct snd_soc_dapm_widget *w, static int tasha_codec_aif4_mixer_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); @@ -8918,9 +8909,8 @@ static int tasha_codec_aif4_mixer_switch_get(struct snd_kcontrol *kcontrol, static int tasha_codec_aif4_mixer_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_dapm_update *update = NULL; struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 1997e044fad7..ce0141f9f43b 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -1110,9 +1110,8 @@ static int tavil_put_clkmode(struct snd_kcontrol *kcontrol, static int tavil_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); @@ -1124,9 +1123,8 @@ static int tavil_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, static int tavil_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); @@ -1176,9 +1174,8 @@ static int tavil_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); @@ -1189,9 +1186,8 @@ static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol, static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); @@ -1271,9 +1267,8 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, static int slim_rx_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); @@ -1285,9 +1280,8 @@ static int slim_rx_mux_get(struct snd_kcontrol *kcontrol, static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); @@ -5929,9 +5923,8 @@ static const struct snd_kcontrol_new tavil_snd_controls[] = { static int tavil_dec_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val; @@ -5989,9 +5982,8 @@ static int tavil_dec_enum_put(struct snd_kcontrol *kcontrol, static int tavil_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val; diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index c319ccf43feb..30a4d59f2ba4 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -2496,8 +2496,21 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .rate_min = 8000, .rate_max = 384000, }, + .capture = { + .stream_name = "MultiMedia16 Capture", + .aif_name = "MM_UL16", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, .ops = &msm_fe_Multimedia_dai_ops, - .compress_new = snd_soc_new_compress, .name = "MultiMedia16", .probe = fe_dai_probe, }, diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index de2201ef2f80..aa9b3abf6a48 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1768,9 +1768,8 @@ static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol, static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_dapm_update *update = NULL; @@ -1810,9 +1809,8 @@ static int msm_routing_get_listen_mixer(struct snd_kcontrol *kcontrol, static int msm_routing_put_listen_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_dapm_update *update = NULL; @@ -1928,9 +1926,8 @@ static int msm_routing_get_voice_mixer(struct snd_kcontrol *kcontrol, static int msm_routing_put_voice_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_dapm_update *update = NULL; @@ -1972,9 +1969,8 @@ static int msm_routing_get_voice_stub_mixer(struct snd_kcontrol *kcontrol, static int msm_routing_put_voice_stub_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_dapm_update *update = NULL; @@ -2075,9 +2071,8 @@ static int msm_routing_get_switch_mixer(struct snd_kcontrol *kcontrol, static int msm_routing_put_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_dapm_update *update = NULL; pr_debug("%s: FM Switch enable %ld\n", __func__, @@ -2104,9 +2099,8 @@ static int msm_routing_get_hfp_switch_mixer(struct snd_kcontrol *kcontrol, static int msm_routing_put_hfp_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_dapm_update *update = NULL; pr_debug("%s: HFP Switch enable %ld\n", __func__, @@ -2133,9 +2127,8 @@ static int msm_routing_get_int0_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, static int msm_routing_put_int0_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_dapm_update *update = NULL; pr_debug("%s: INT0 MI2S Switch enable %ld\n", __func__, @@ -2162,9 +2155,8 @@ static int msm_routing_get_int4_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, static int msm_routing_put_int4_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_dapm_update *update = NULL; pr_debug("%s: INT4 MI2S Switch enable %ld\n", __func__, @@ -2191,9 +2183,8 @@ static int msm_routing_get_usb_switch_mixer(struct snd_kcontrol *kcontrol, static int msm_routing_put_usb_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_dapm_update *update = NULL; pr_debug("%s: USB Switch enable %ld\n", __func__, @@ -2220,9 +2211,8 @@ static int msm_routing_get_pri_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, static int msm_routing_put_pri_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_dapm_update *update = NULL; pr_debug("%s: PRI MI2S Switch enable %ld\n", __func__, @@ -2249,9 +2239,8 @@ static int msm_routing_get_sec_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, static int msm_routing_put_sec_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_dapm_update *update = NULL; pr_debug("%s: SEC MI2S Switch enable %ld\n", __func__, @@ -2280,9 +2269,8 @@ static int msm_routing_put_tert_mi2s_switch_mixer( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_dapm_update *update = NULL; pr_debug("%s: TERT MI2S Switch enable %ld\n", __func__, @@ -2311,9 +2299,8 @@ static int msm_routing_put_quat_mi2s_switch_mixer( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_dapm_update *update = NULL; pr_debug("%s: QUAT MI2S Switch enable %ld\n", __func__, @@ -2340,9 +2327,8 @@ static int msm_routing_get_fm_pcmrx_switch_mixer(struct snd_kcontrol *kcontrol, static int msm_routing_put_fm_pcmrx_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_dapm_update *update = NULL; pr_debug("%s: FM Switch enable %ld\n", __func__, @@ -3490,9 +3476,8 @@ static int msm_routing_ec_ref_rx_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int ec_ref_port_id; - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct snd_soc_dapm_update *update = NULL; @@ -3655,6 +3640,11 @@ static const struct snd_kcontrol_new ext_ec_ref_mux_ul9 = msm_route_ec_ref_rx_enum[0], msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); +static const struct snd_kcontrol_new ext_ec_ref_mux_ul16 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL16 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + static const struct snd_kcontrol_new ext_ec_ref_mux_ul17 = SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL17 MUX Mux", msm_route_ec_ref_rx_enum[0], @@ -3684,9 +3674,8 @@ static int msm_routing_ext_ec_get(struct snd_kcontrol *kcontrol, static int msm_routing_ext_ec_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); int mux = ucontrol->value.enumerated.item[0]; struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; int ret = 1; @@ -7103,6 +7092,114 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new mmul16_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AUX_PCM_TX", MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_AUX_PCM_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new mmul9_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, @@ -11392,6 +11489,7 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL9", "MultiMedia9 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL16", "MultiMedia16 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL17", "MultiMedia17 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL18", "MultiMedia18 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL19", "MultiMedia19 Capture", 0, 0, 0, 0), @@ -12127,6 +12225,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia9 Mixer", SND_SOC_NOPM, 0, 0, mmul9_mixer_controls, ARRAY_SIZE(mmul9_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia16 Mixer", SND_SOC_NOPM, 0, 0, + mmul16_mixer_controls, ARRAY_SIZE(mmul16_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia17 Mixer", SND_SOC_NOPM, 0, 0, mmul17_mixer_controls, ARRAY_SIZE(mmul17_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia18 Mixer", SND_SOC_NOPM, 0, 0, @@ -12457,6 +12557,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &ext_ec_ref_mux_ul8), SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL9 MUX", SND_SOC_NOPM, 0, 0, &ext_ec_ref_mux_ul9), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL16 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul16), SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL17 MUX", SND_SOC_NOPM, 0, 0, &ext_ec_ref_mux_ul17), SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL18 MUX", SND_SOC_NOPM, 0, 0, @@ -12708,6 +12810,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia16 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia5 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"MultiMedia5 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -13276,6 +13379,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"}, {"MultiMedia3 Mixer", "MI2S_TX", "MI2S_TX"}, {"MultiMedia5 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia16 Mixer", "MI2S_TX", "MI2S_TX"}, {"MultiMedia1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, @@ -13294,12 +13398,15 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia3 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia5 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia16 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, + {"MultiMedia16 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia1 Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, {"MultiMedia3 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, {"MultiMedia5 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, {"MultiMedia1 Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, {"MultiMedia3 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, {"MultiMedia5 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia16 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, {"MultiMedia2 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia2 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, {"MultiMedia2 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, @@ -13314,9 +13421,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, {"MultiMedia3 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, {"MultiMedia5 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia16 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, {"MultiMedia6 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia16 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia6 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"MultiMedia6 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, @@ -13478,6 +13587,24 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia8 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia16 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia16 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia16 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia16 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia16 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia16 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia16 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia16 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia16 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia16 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia16 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia16 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia16 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia16 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia16 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia16 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia16 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, @@ -13560,8 +13687,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia19 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia5 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia8 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia16 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia4 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia16 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia17 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia18 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia19 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, @@ -13577,6 +13706,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia19 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia5 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia8 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia16 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MM_UL1", NULL, "MultiMedia1 Mixer"}, {"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MM_UL2", NULL, "MultiMedia2 Mixer"}, @@ -13586,6 +13716,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL6", NULL, "MultiMedia6 Mixer"}, {"MM_UL8", NULL, "MultiMedia8 Mixer"}, {"MM_UL9", NULL, "MultiMedia9 Mixer"}, + {"MM_UL16", NULL, "MultiMedia16 Mixer"}, {"MM_UL17", NULL, "MultiMedia17 Mixer"}, {"MM_UL18", NULL, "MultiMedia18 Mixer"}, {"MM_UL19", NULL, "MultiMedia19 Mixer"}, @@ -13996,6 +14127,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL6", NULL, "AUDIO_REF_EC_UL6 MUX"}, {"MM_UL8", NULL, "AUDIO_REF_EC_UL8 MUX"}, {"MM_UL9", NULL, "AUDIO_REF_EC_UL9 MUX"}, + {"MM_UL16", NULL, "AUDIO_REF_EC_UL16 MUX"}, {"MM_UL17", NULL, "AUDIO_REF_EC_UL17 MUX"}, {"MM_UL18", NULL, "AUDIO_REF_EC_UL18 MUX"}, {"MM_UL19", NULL, "AUDIO_REF_EC_UL19 MUX"}, diff --git a/asoc/msm8996.c b/asoc/msm8996.c index 45c5479884a2..08900372a2c2 100644 --- a/asoc/msm8996.c +++ b/asoc/msm8996.c @@ -2915,12 +2915,13 @@ static struct snd_soc_dai_link msm8996_common_dai_links[] = { .id = MSM_FRONTEND_DAI_MULTIMEDIA15, }, { - .name = "MSM8996 Compress9", - .stream_name = "Compress9", + .name = "MSM8996 ULL NOIRQ_2", + .stream_name = "MM_NOIRQ_2", .cpu_dai_name = "MultiMedia16", - .platform_name = "msm-compress-dsp", + .platform_name = "msm-pcm-dsp-noirq", .dynamic = 1, .dpcm_playback = 1, + .dpcm_capture = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .codec_dai_name = "snd-soc-dummy-dai", diff --git a/asoc/msm8998.c b/asoc/msm8998.c index 6c5393d021d7..b2fc005ebbb4 100644 --- a/asoc/msm8998.c +++ b/asoc/msm8998.c @@ -5312,12 +5312,13 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .id = MSM_FRONTEND_DAI_MULTIMEDIA15, }, { - .name = MSM_DAILINK_NAME(Compress9), - .stream_name = "Compress9", + .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), + .stream_name = "MM_NOIRQ_2", .cpu_dai_name = "MultiMedia16", - .platform_name = "msm-compress-dsp", + .platform_name = "msm-pcm-dsp-noirq", .dynamic = 1, .dpcm_playback = 1, + .dpcm_capture = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .codec_dai_name = "snd-soc-dummy-dai", diff --git a/asoc/sdm660-ext-dai-links.c b/asoc/sdm660-ext-dai-links.c index cde28706a75e..1e89976b4ab3 100644 --- a/asoc/sdm660-ext-dai-links.c +++ b/asoc/sdm660-ext-dai-links.c @@ -1270,10 +1270,10 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .id = MSM_FRONTEND_DAI_MULTIMEDIA15, }, {/* hw:x,33 */ - .name = MSM_DAILINK_NAME(Compress9), - .stream_name = "Compress9", + .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), + .stream_name = "MM_NOIRQ_2", .cpu_dai_name = "MultiMedia16", - .platform_name = "msm-compress-dsp", + .platform_name = "msm-pcm-dsp-noirq", .dynamic = 1, .dpcm_capture = 1, .dpcm_playback = 1, diff --git a/asoc/sdm660-internal.c b/asoc/sdm660-internal.c index 0afe82896cfb..fc2378d4e8d2 100644 --- a/asoc/sdm660-internal.c +++ b/asoc/sdm660-internal.c @@ -2194,10 +2194,10 @@ static struct snd_soc_dai_link msm_int_dai[] = { .id = MSM_FRONTEND_DAI_MULTIMEDIA15, }, {/* hw:x,33 */ - .name = MSM_DAILINK_NAME(Compress9), - .stream_name = "Compress9", + .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), + .stream_name = "MM_NOIRQ_2", .cpu_dai_name = "MultiMedia16", - .platform_name = "msm-compress-dsp", + .platform_name = "msm-pcm-dsp-noirq", .dynamic = 1, .dpcm_capture = 1, .dpcm_playback = 1, diff --git a/asoc/sdm845.c b/asoc/sdm845.c index 9d6ff120e671..e38def3c9e95 100644 --- a/asoc/sdm845.c +++ b/asoc/sdm845.c @@ -134,6 +134,13 @@ struct mi2s_conf { u32 msm_is_mi2s_master; }; +static u32 mi2s_ebit_clk[MI2S_MAX] = { + Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT +}; + struct auxpcm_conf { struct mutex lock; u32 ref_cnt; @@ -434,6 +441,7 @@ static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; static const char *const hifi_text[] = {"Off", "On"}; +static const char *const qos_text[] = {"Disable", "Enable"}; static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text); @@ -498,9 +506,11 @@ static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(hifi_function, hifi_text); +static SOC_ENUM_SINGLE_EXT_DECL(qos_vote, qos_text); static struct platform_device *spdev; static int msm_hifi_control; +static int qos_vote_status; static bool is_initial_boot; static bool codec_reg_done; @@ -2628,6 +2638,72 @@ static int msm_hifi_put(struct snd_kcontrol *kcontrol, return 0; } +static s32 msm_qos_value(struct snd_pcm_runtime *runtime) +{ + s32 usecs; + + if (!runtime->rate) + return -EINVAL; + + /* take 75% of period time as the deadline */ + usecs = (750000 / runtime->rate) * runtime->period_size; + usecs += ((750000 % runtime->rate) * runtime->period_size) / + runtime->rate; + + return usecs; +} + +static int msm_qos_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = qos_vote_status; + + return 0; +} + +static int msm_qos_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_card *card = codec->component.card; + const char *be_name = MSM_DAILINK_NAME(LowLatency); + struct snd_soc_pcm_runtime *rtd; + struct snd_pcm_substream *substream; + s32 usecs; + + rtd = snd_soc_get_pcm_runtime(card, be_name); + if (!rtd) { + pr_err("%s: fail to get pcm runtime for %s\n", + __func__, be_name); + return -EINVAL; + } + + substream = rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + if (!substream) { + pr_err("%s: substream is null\n", __func__); + return -EINVAL; + } + + qos_vote_status = ucontrol->value.enumerated.item[0]; + if (qos_vote_status) { + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + if (!substream->runtime) { + pr_err("%s: runtime is null\n", __func__); + return -EINVAL; + } + usecs = msm_qos_value(substream->runtime); + if (usecs >= 0) + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, usecs); + } else { + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + } + + return 0; +} + static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, msm_slim_rx_ch_get, msm_slim_rx_ch_put), @@ -2857,6 +2933,8 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get, msm_hifi_put), + SOC_ENUM_EXT("MultiMedia5_RX QOS Vote", qos_vote, msm_qos_ctl_get, + msm_qos_ctl_put), }; static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, @@ -4176,9 +4254,6 @@ static void update_mi2s_clk_val(int dai_id, int stream) mi2s_clk[dai_id].clk_freq_in_hz = mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample; } - - if (!mi2s_intf_conf[dai_id].msm_is_mi2s_master) - mi2s_clk[dai_id].clk_freq_in_hz = 0; } static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) @@ -4529,6 +4604,11 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) */ mutex_lock(&mi2s_intf_conf[index].lock); if (++mi2s_intf_conf[index].ref_cnt == 1) { + /* Check if msm needs to provide the clock to the interface */ + if (!mi2s_intf_conf[index].msm_is_mi2s_master) { + mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; + fmt = SND_SOC_DAIFMT_CBM_CFM; + } ret = msm_mi2s_set_sclk(substream, true); if (ret < 0) { dev_err(rtd->card->dev, @@ -4548,9 +4628,6 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) ret = -EINVAL; goto clk_off; } - /* Check if msm needs to provide the clock to the interface */ - if (!mi2s_intf_conf[index].msm_is_mi2s_master) - fmt = SND_SOC_DAIFMT_CBM_CFM; ret = snd_soc_dai_set_fmt(cpu_dai, fmt); if (ret < 0) { pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n", @@ -5325,12 +5402,13 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .id = MSM_FRONTEND_DAI_MULTIMEDIA15, }, { - .name = MSM_DAILINK_NAME(Compress9), - .stream_name = "Compress9", + .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), + .stream_name = "MM_NOIRQ_2", .cpu_dai_name = "MultiMedia16", - .platform_name = "msm-compress-dsp", + .platform_name = "msm-pcm-dsp-noirq", .dynamic = 1, .dpcm_playback = 1, + .dpcm_capture = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .codec_dai_name = "snd-soc-dummy-dai", diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 19151139eeff..bc217237be91 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2388,7 +2388,8 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, struct adm_cmd_device_open_v5 open; struct adm_cmd_device_open_v6 open_v6; int ret = 0; - int port_idx, copp_idx, flags; + int port_idx, flags; + int copp_idx = -1; int tmp_port = q6audio_get_port_id(port_id); pr_debug("%s:port %#x path:%d rate:%d mode:%d perf_mode:%d,topo_id %d\n", @@ -2442,8 +2443,17 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, (topology == VPM_TX_DM_RFECNS_COPP_TOPOLOGY)) rate = 16000; - copp_idx = adm_get_idx_if_copp_exists(port_idx, topology, perf_mode, - rate, bit_width, app_type); + /* + * Routing driver reuses the same adm for streams with the same + * app_type, sample_rate etc. + * This isn't allowed for ULL streams as per the DSP interface + */ + if (perf_mode != ULTRA_LOW_LATENCY_PCM_MODE) + copp_idx = adm_get_idx_if_copp_exists(port_idx, topology, + perf_mode, + rate, bit_width, + app_type); + if (copp_idx < 0) { copp_idx = adm_get_next_available_copp(port_idx); if (copp_idx >= MAX_COPPS_PER_PORT) { -- GitLab From 7e057cf8cd5e84aecf8ad82750ac8b6c6f0da68a Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 9 Aug 2017 23:55:15 +0530 Subject: [PATCH 0010/1645] audio-lnx: Enable compilation for sdm670 audio Enable compilation for sdm670 audio. Update for both internal and external codecs. Change-Id: I030837a2c0180a5a31d0ab786ad5de607027050f Signed-off-by: Laxminath Kasam --- Makefile | 9 +++++++++ asoc/Makefile | 2 +- asoc/codecs/Makefile | 14 +++++++++++++- asoc/codecs/msm_sdw/Makefile | 1 - asoc/codecs/msm_sdw/msm_sdw.h | 2 +- asoc/codecs/msm_sdw/msm_sdw_cdc.c | 22 ++++++++++------------ asoc/codecs/wcd_cpe_core.c | 2 +- asoc/codecs/wcd_cpe_services.c | 3 +-- asoc/sdm660-ext-dai-links.c | 2 +- 9 files changed, 37 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index 05b04c637301..ff83693730d3 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,10 @@ ifeq ($(CONFIG_ARCH_SDM845), y) include $(srctree)/techpack/audio/config/sdm845auto.conf export endif +ifeq ($(CONFIG_ARCH_SDM670), y) +include $(srctree)/techpack/audio/config/sdm670auto.conf +export +endif # Use USERINCLUDE when you must reference the UAPI directories only. USERINCLUDE += \ @@ -18,6 +22,11 @@ ifeq ($(CONFIG_ARCH_SDM845), y) LINUXINCLUDE += \ -include $(srctree)/techpack/audio/config/sdm845autoconf.h endif +ifeq ($(CONFIG_ARCH_SDM670), y) +LINUXINCLUDE += \ + -include $(srctree)/techpack/audio/config/sdm670autoconf.h +endif + obj-y += asoc/ obj-y += dsp/ diff --git a/asoc/Makefile b/asoc/Makefile index 67cb9f3aac6b..3fccff6726ba 100644 --- a/asoc/Makefile +++ b/asoc/Makefile @@ -21,7 +21,7 @@ obj-$(CONFIG_SND_SOC_MACHINE_MSM8998) += snd-soc-msm8998.o # for SDM660 sound card driver snd-soc-sdm660-common-objs := sdm660-common.o -obj-$(CONFIG_SND_SOC_SDM660_COMMON) += snd-soc-sdm660-common.o +obj-$(CONFIG_SND_SOC_SDM670) += snd-soc-sdm660-common.o # for SDM660 sound card driver snd-soc-int-codec-objs := sdm660-internal.o diff --git a/asoc/codecs/Makefile b/asoc/codecs/Makefile index 04218e8103e1..bb3a9356e867 100644 --- a/asoc/codecs/Makefile +++ b/asoc/codecs/Makefile @@ -1,12 +1,24 @@ snd-soc-wcd9xxx-v2-objs := wcd9xxx-common-v2.o wcd9xxx-resmgr-v2.o wcdcal-hwdep.o wcd9xxx-soc-init.o snd-soc-wcd-cpe-objs := wcd_cpe_services.o wcd_cpe_core.o snd-soc-wsa881x-objs := wsa881x.o wsa881x-tables.o wsa881x-regmap.o wsa881x-temp-sensor.o -snd-soc-wcd-mbhc-objs := wcd-mbhc-v2.o wcd-mbhc-adc.o +snd-soc-wcd-mbhc-objs := wcd-mbhc-v2.o +ifneq (,$(filter $(CONFIG_SND_SOC_WCD_MBHC_LEGACY),y m)) + snd-soc-wcd-mbhc-objs += wcd-mbhc-legacy.o +endif +ifneq (,$(filter $(CONFIG_SND_SOC_WCD_MBHC_ADC),y m)) + snd-soc-wcd-mbhc-objs += wcd-mbhc-adc.o +endif snd-soc-wcd-dsp-utils-objs := wcd-dsp-utils.o snd-soc-wcd-dsp-mgr-objs := wcd-dsp-mgr.o snd-soc-wcd-spi-objs := wcd-spi.o +snd-soc-wcd9335-objs := wcd9335.o +snd-soc-wcd-cpe-objs := wcd_cpe_services.o wcd_cpe_core.o +obj-$(CONFIG_SND_SOC_WCD9335) += snd-soc-wcd9335.o +obj-$(CONFIG_SND_SOC_WCD_CPE) += snd-soc-wcd-cpe.o obj-$(CONFIG_SND_SOC_WCD934X) += wcd934x/ +obj-$(CONFIG_SND_SOC_SDM660_CDC) += sdm660_cdc/ +obj-$(CONFIG_SND_SOC_MSM_SDW) += msm_sdw/ ifeq ($(CONFIG_COMMON_CLK_MSM), y) obj-$(CONFIG_AUDIO_EXT_CLK) += audio-ext-clk.o endif diff --git a/asoc/codecs/msm_sdw/Makefile b/asoc/codecs/msm_sdw/Makefile index 64e932b9d262..9518f4db5b18 100644 --- a/asoc/codecs/msm_sdw/Makefile +++ b/asoc/codecs/msm_sdw/Makefile @@ -1,3 +1,2 @@ snd-soc-msm-sdw-objs := msm_sdw_cdc.o msm_sdw_regmap.o msm-sdw-tables.o msm_sdw_cdc_utils.o obj-$(CONFIG_SND_SOC_MSM_SDW) += snd-soc-msm-sdw.o -ccflags-y += -I$(srctree)/sound/soc/msm diff --git a/asoc/codecs/msm_sdw/msm_sdw.h b/asoc/codecs/msm_sdw/msm_sdw.h index 376ebc6c38db..3285f5f5512d 100644 --- a/asoc/codecs/msm_sdw/msm_sdw.h +++ b/asoc/codecs/msm_sdw/msm_sdw.h @@ -13,7 +13,7 @@ #define MSM_SDW_H #include -#include +#include #include "msm_sdw_registers.h" #define MSM_SDW_MAX_REGISTER 0x400 diff --git a/asoc/codecs/msm_sdw/msm_sdw_cdc.c b/asoc/codecs/msm_sdw/msm_sdw_cdc.c index cfe42e00e358..3ff184c7fab3 100644 --- a/asoc/codecs/msm_sdw/msm_sdw_cdc.c +++ b/asoc/codecs/msm_sdw/msm_sdw_cdc.c @@ -14,25 +14,25 @@ #include #include #include -#include #include #include #include #include #include #include -#include -#include -#include -#include #include #include #include #include -#include #include +#include +#include +#include +#include +#include #include "msm_sdw.h" #include "msm_sdw_registers.h" +#include "../msm-cdc-pinctrl.h" #define MSM_SDW_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000) @@ -937,9 +937,8 @@ static int msm_sdw_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, static int msm_sdw_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct msm_sdw_priv *msm_sdw_p = snd_soc_codec_get_drvdata(codec); @@ -951,9 +950,8 @@ static int msm_sdw_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, static int msm_sdw_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget_list *wlist = - dapm_kcontrol_get_wlist(kcontrol); - struct snd_soc_dapm_widget *widget = wlist->widgets[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct msm_sdw_priv *msm_sdw_p = snd_soc_codec_get_drvdata(codec); struct soc_multi_mixer_control *mixer = diff --git a/asoc/codecs/wcd_cpe_core.c b/asoc/codecs/wcd_cpe_core.c index 7748ace12686..a7fcce316e6d 100644 --- a/asoc/codecs/wcd_cpe_core.c +++ b/asoc/codecs/wcd_cpe_core.c @@ -23,12 +23,12 @@ #include #include #include -#include #include #include #include "core.h" #include "cpe_core.h" #include "cpe_err.h" +#include "cpe_cmi.h" #include "wcd_cpe_core.h" #include "wcd_cpe_services.h" #include "wcd_cmi_api.h" diff --git a/asoc/codecs/wcd_cpe_services.c b/asoc/codecs/wcd_cpe_services.c index 7a0e70311407..522ce7abacd6 100644 --- a/asoc/codecs/wcd_cpe_services.c +++ b/asoc/codecs/wcd_cpe_services.c @@ -18,8 +18,7 @@ #include #include #include -#include -#include +#include "wcd9335_registers.h" #include "core.h" #include "cpe_cmi.h" #include "wcd_cpe_services.h" diff --git a/asoc/sdm660-ext-dai-links.c b/asoc/sdm660-ext-dai-links.c index 1e89976b4ab3..71ba1fa9060f 100644 --- a/asoc/sdm660-ext-dai-links.c +++ b/asoc/sdm660-ext-dai-links.c @@ -16,7 +16,7 @@ #include #include #include -#include "qdsp6v2/msm-pcm-routing-v2.h" +#include "msm-pcm-routing-v2.h" #include "sdm660-common.h" #include "sdm660-external.h" #include "codecs/core.h" -- GitLab From 8c87858751bf61c0e2dfc413ad8923aaad4a1665 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 10 Aug 2017 00:22:42 +0530 Subject: [PATCH 0011/1645] autoconf: Add conf file support for sdm670 audio Add new conf files to support sdm670 audio. Also update sdm845 to support required configs. Change-Id: I3b0ac16d80bba10a3226dbe5c1b39c64b5780ac9 Signed-off-by: Laxminath Kasam --- config/sdm670auto.conf | 46 ++++++++++++++++++++++++++++++++ config/sdm670autoconf.h | 59 +++++++++++++++++++++++++++++++++++++++++ config/sdm845auto.conf | 3 +-- config/sdm845autoconf.h | 2 -- 4 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 config/sdm670auto.conf create mode 100644 config/sdm670autoconf.h diff --git a/config/sdm670auto.conf b/config/sdm670auto.conf new file mode 100644 index 000000000000..59e27dc313f5 --- /dev/null +++ b/config/sdm670auto.conf @@ -0,0 +1,46 @@ +CONFIG_PINCTRL_LPI=y +CONFIG_PINCTRL_WCD=y +CONFIG_AUDIO_EXT_CLK=y +CONFIG_SND_SOC_WCD9XXX_V2=y +CONFIG_SND_SOC_WCD_MBHC=y +CONFIG_SND_SOC_WSA881X=y +CONFIG_SND_SOC_WCD_DSP_MGR=y +CONFIG_SND_SOC_WCD_SPI=y +CONFIG_SND_SOC_WCD_CPE=y +CONFIG_SND_SOC_WCD9335=y +CONFIG_SND_SOC_WCD934X=y +CONFIG_SND_SOC_WCD934X_MBHC=y +CONFIG_SND_SOC_WCD934X_DSD=y +CONFIG_MSM_QDSP6V2_CODECS=y +CONFIG_MSM_ULTRASOUND=y +CONFIG_MSM_QDSP6_APRV2_GLINK=y +CONFIG_MSM_ADSP_LOADER=y +CONFIG_REGMAP_SWR=y +CONFIG_MSM_QDSP6_SSR=y +CONFIG_MSM_QDSP6_PDR=y +CONFIG_MSM_QDSP6_NOTIFIER=y +CONFIG_SND_SOC_MSM_HOSTLESS_PCM=y +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y +CONFIG_SND_SOC_SDM670=y +CONFIG_MSM_GLINK_SPI_XPRT=y +CONFIG_SOUNDWIRE=y +CONFIG_SOUNDWIRE_WCD_CTRL=y +CONFIG_SND_SOC_QDSP6V2=y +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y +CONFIG_WCD9XXX_CODEC_CORE=y +CONFIG_MSM_CDC_PINCTRL=y +CONFIG_SND_SOC_WCD_MBHC_ADC=y +CONFIG_SND_SOC_WCD_MBHC_LEGACY=y +CONFIG_QTI_PP=y +CONFIG_SND_HWDEP=y +CONFIG_DTS_EAGLE=y +CONFIG_DOLBY_DS2=y +CONFIG_DOLBY_LICENSE=y +CONFIG_DTS_SRS_TM=y +CONFIG_SND_SOC_EXT_CODEC=y +CONFIG_SND_SOC_INT_CODEC=y +CONFIG_SND_SOC_MSM_STUB=y +CONFIG_WCD_DSP_GLINK=y +CONFIG_MSM_AVTIMER=y +CONFIG_SND_SOC_SDM660_CDC=y +CONFIG_SND_SOC_MSM_SDW=y diff --git a/config/sdm670autoconf.h b/config/sdm670autoconf.h new file mode 100644 index 000000000000..7b3a3515da36 --- /dev/null +++ b/config/sdm670autoconf.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define CONFIG_PINCTRL_LPI 1 +#define CONFIG_PINCTRL_WCD 1 +#define CONFIG_AUDIO_EXT_CLK 1 +#define CONFIG_SND_SOC_WCD9XXX_V2 1 +#define CONFIG_SND_SOC_WCD_CPE 1 +#define CONFIG_SND_SOC_WCD_MBHC 1 +#define CONFIG_SND_SOC_WSA881X 1 +#define CONFIG_SND_SOC_WCD_DSP_MGR 1 +#define CONFIG_SND_SOC_WCD_SPI 1 +#define CONFIG_SND_SOC_WCD9335 1 +#define CONFIG_SND_SOC_WCD934X 1 +#define CONFIG_SND_SOC_WCD934X_MBHC 1 +#define CONFIG_SND_SOC_WCD934X_DSD 1 +#define CONFIG_MSM_QDSP6V2_CODECS 1 +#define CONFIG_MSM_ULTRASOUND 1 +#define CONFIG_MSM_QDSP6_APRV2_GLINK 1 +#define CONFIG_MSM_ADSP_LOADER 1 +#define CONFIG_REGMAP_SWR 1 +#define CONFIG_MSM_QDSP6_SSR 1 +#define CONFIG_MSM_QDSP6_PDR 1 +#define CONFIG_MSM_QDSP6_NOTIFIER 1 +#define CONFIG_SND_SOC_MSM_HOSTLESS_PCM 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_SND_SOC_SDM670 1 +#define CONFIG_MSM_GLINK_SPI_XPRT 1 +#define CONFIG_SOUNDWIRE 1 +#define CONFIG_SOUNDWIRE_WCD_CTRL 1 +#define CONFIG_SND_SOC_WCD_MBHC_ADC 1 +#define CONFIG_SND_SOC_WCD_MBHC_LEGACY 1 +#define CONFIG_SND_SOC_QDSP6V2 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_QTI_PP 1 +#define CONFIG_SND_HWDEP 1 +#define CONFIG_DTS_EAGLE 1 +#define CONFIG_DOLBY_DS2 1 +#define CONFIG_DOLBY_LICENSE 1 +#define CONFIG_DTS_SRS_TM 1 +#define CONFIG_WCD9XXX_CODEC_CORE 1 +#define CONFIG_MSM_CDC_PINCTRL 1 +#define CONFIG_SND_SOC_MSM_STUB 1 +#define CONFIG_WCD_DSP_GLINK 1 +#define CONFIG_MSM_AVTIMER 1 +#define CONFIG_SND_SOC_EXT_CODEC 1 +#define CONFIG_SND_SOC_INT_CODEC 1 +#define CONFIG_SND_SOC_SDM660_CDC 1 +#define CONFIG_SND_SOC_MSM_SDW 1 diff --git a/config/sdm845auto.conf b/config/sdm845auto.conf index b6d4231ff275..97f2127ce606 100644 --- a/config/sdm845auto.conf +++ b/config/sdm845auto.conf @@ -1,5 +1,3 @@ -CONFIG_WCD934X_CODEC=y -CONFIG_WCD9335_CODEC=y CONFIG_PINCTRL_WCD=y CONFIG_SND_SOC_WCD934X=y CONFIG_AUDIO_EXT_CLK=y @@ -30,6 +28,7 @@ CONFIG_SND_SOC_QDSP6V2=y CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y CONFIG_MSM_CDC_PINCTRL=y CONFIG_WCD9XXX_CODEC_CORE=y +CONFIG_SND_SOC_WCD_MBHC_ADC=y CONFIG_QTI_PP=y CONFIG_SND_HWDEP=y CONFIG_DTS_EAGLE=y diff --git a/config/sdm845autoconf.h b/config/sdm845autoconf.h index 7e9de815db80..ea14533dece3 100644 --- a/config/sdm845autoconf.h +++ b/config/sdm845autoconf.h @@ -11,8 +11,6 @@ * GNU General Public License for more details. */ -#define CONFIG_WCD934X_CODEC 1 -#define CONFIG_WCD9335_CODEC 1 #define CONFIG_PINCTRL_WCD 1 #define CONFIG_SND_SOC_WCD934X 1 #define CONFIG_AUDIO_EXT_CLK 1 -- GitLab From 38070be30b1d7bbcc7e9e862f81fabface2a0707 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 17 Aug 2017 18:21:59 +0530 Subject: [PATCH 0012/1645] audio-lnx: Add latest snapshot for audio drivers. Propagate the changes based on latest snapshot for audio kernel source tree at below cutoff of kernel msm-4.9 - (aed56b2df75 - "drm/msm/sde: update te vsync enable sequence change") Change-Id: I7ed5102146986b81e5cb9ca55432360b3549b60c Signed-off-by: Laxminath Kasam --- asoc/codecs/msm_sdw/msm_sdw_cdc.c | 12 +- asoc/codecs/pdata.h | 2 + asoc/codecs/wcd-dsp-mgr.c | 22 +- asoc/codecs/wcd934x/wcd934x-dsp-cntl.c | 8 +- asoc/codecs/wcd9xxx-core.c | 4 + asoc/codecs/wcd9xxx-utils.c | 13 + asoc/codecs/wsa881x.h | 28 +- asoc/msm-audio-effects-q6-v2.c | 60 ++--- asoc/msm-dai-fe.c | 14 +- asoc/msm-lsm-client.c | 14 +- asoc/msm-pcm-routing-v2.c | 98 ++++++- asoc/msm8998.c | 7 +- asoc/sdm660-common.c | 15 ++ asoc/sdm660-common.h | 1 + asoc/sdm660-ext-dai-links.c | 18 +- asoc/sdm660-external.c | 126 ++++++--- asoc/sdm660-external.h | 2 + asoc/sdm660-internal.c | 8 +- asoc/sdm845.c | 15 +- dsp/codecs/audio_utils_aio.c | 57 ++-- dsp/q6core.c | 256 +++++++++++++++++- dsp/q6voice.c | 353 ++++++++++++++++++++++++- include/dsp/apr_audio-v2.h | 70 +++++ include/dsp/q6core.h | 6 + include/dsp/q6voice.h | 118 ++++++++- soc/pinctrl-lpi.c | 42 +-- 26 files changed, 1192 insertions(+), 177 deletions(-) diff --git a/asoc/codecs/msm_sdw/msm_sdw_cdc.c b/asoc/codecs/msm_sdw/msm_sdw_cdc.c index 3ff184c7fab3..05d1d801ce74 100644 --- a/asoc/codecs/msm_sdw/msm_sdw_cdc.c +++ b/asoc/codecs/msm_sdw/msm_sdw_cdc.c @@ -938,7 +938,7 @@ static int msm_sdw_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct msm_sdw_priv *msm_sdw_p = snd_soc_codec_get_drvdata(codec); @@ -951,7 +951,7 @@ static int msm_sdw_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct msm_sdw_priv *msm_sdw_p = snd_soc_codec_get_drvdata(codec); struct soc_multi_mixer_control *mixer = @@ -1376,15 +1376,19 @@ int msm_sdw_codec_info_create_codec_entry(struct snd_info_entry *codec_root, struct snd_info_entry *version_entry; struct msm_sdw_priv *msm_sdw; struct snd_soc_card *card; + char name[80]; if (!codec_root || !codec) return -EINVAL; msm_sdw = snd_soc_codec_get_drvdata(codec); card = codec->component.card; + + snprintf(name, sizeof(name), "%x.%s", (u32)msm_sdw->sdw_base_addr, + "msm-sdw-codec"); msm_sdw->entry = snd_info_create_subdir(codec_root->module, - "152c1000.msm-sdw-codec", - codec_root); + (const char *)name, + codec_root); if (!msm_sdw->entry) { dev_err(codec->dev, "%s: failed to create msm_sdw entry\n", __func__); diff --git a/asoc/codecs/pdata.h b/asoc/codecs/pdata.h index fa16b3d1c8f5..6df80eb064d6 100644 --- a/asoc/codecs/pdata.h +++ b/asoc/codecs/pdata.h @@ -179,6 +179,8 @@ struct wcd9xxx_pdata { int irq_base; int num_irqs; int reset_gpio; + bool has_buck_vsel_gpio; + struct device_node *buck_vsel_ctl_np; struct device_node *wcd_rst_np; struct wcd9xxx_amic amic_settings; struct slim_device slimbus_slave_device; diff --git a/asoc/codecs/wcd-dsp-mgr.c b/asoc/codecs/wcd-dsp-mgr.c index a6d46aef9724..6cc9f8c79d21 100644 --- a/asoc/codecs/wcd-dsp-mgr.c +++ b/asoc/codecs/wcd-dsp-mgr.c @@ -417,22 +417,23 @@ static int wdsp_download_segments(struct wdsp_mgr_priv *wdsp, /* Go through the list of segments and download one by one */ list_for_each_entry(seg, wdsp->seg_list, list) { ret = wdsp_load_each_segment(wdsp, seg); - if (ret < 0) { - wdsp_broadcast_event_downseq(wdsp, - WDSP_EVENT_DLOAD_FAILED, - NULL); + if (ret) goto dload_error; - } } + /* Flush the list before setting status and notifying components */ + wdsp_flush_segment_list(wdsp->seg_list); + WDSP_SET_STATUS(wdsp, status); /* Notify all components that image is downloaded */ wdsp_broadcast_event_downseq(wdsp, post, NULL); +done: + return ret; dload_error: wdsp_flush_segment_list(wdsp->seg_list); -done: + wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_DLOAD_FAILED, NULL); return ret; } @@ -486,10 +487,14 @@ static int wdsp_enable_dsp(struct wdsp_mgr_priv *wdsp) /* Make sure wdsp is in good state */ if (!WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_CODE_DLOADED)) { WDSP_ERR(wdsp, "WDSP in invalid state 0x%x", wdsp->status); - ret = -EINVAL; - goto done; + return -EINVAL; } + /* + * Acquire SSR mutex lock to make sure enablement of DSP + * does not race with SSR handling. + */ + WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex); /* Download the read-write sections of image */ ret = wdsp_download_segments(wdsp, WDSP_ELF_FLAG_WRITE); if (ret < 0) { @@ -510,6 +515,7 @@ static int wdsp_enable_dsp(struct wdsp_mgr_priv *wdsp) wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_POST_BOOTUP, NULL); WDSP_SET_STATUS(wdsp, WDSP_STATUS_BOOTED); done: + WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex); return ret; } diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c index d82748b2689e..031940ecbaf9 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c @@ -763,10 +763,6 @@ static int wcd_control_handler(struct device *dev, void *priv_data, case WDSP_EVENT_DLOAD_FAILED: case WDSP_EVENT_POST_SHUTDOWN: - if (event == WDSP_EVENT_POST_DLOAD_CODE) - /* Mark DSP online since code download is complete */ - wcd_cntl_change_online_state(cntl, 1); - /* Disable CPAR */ wcd_cntl_cpar_ctrl(cntl, false); /* Disable all the clocks */ @@ -775,6 +771,10 @@ static int wcd_control_handler(struct device *dev, void *priv_data, dev_err(codec->dev, "%s: Failed to disable clocks, err = %d\n", __func__, ret); + + if (event == WDSP_EVENT_POST_DLOAD_CODE) + /* Mark DSP online since code download is complete */ + wcd_cntl_change_online_state(cntl, 1); break; case WDSP_EVENT_PRE_DLOAD_DATA: diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index 2ab5e894864e..81408e8928ef 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -1280,6 +1280,10 @@ static int wcd9xxx_slim_probe(struct slim_device *slim) ret = -EINVAL; goto err_codec; } + + if (pdata->has_buck_vsel_gpio) + msm_cdc_pinctrl_select_active_state(pdata->buck_vsel_ctl_np); + device_id = slim_get_device_id(slim); if (!device_id) { dev_err(&slim->dev, "%s: Error, no device id\n", __func__); diff --git a/asoc/codecs/wcd9xxx-utils.c b/asoc/codecs/wcd9xxx-utils.c index a1ea93843f28..eee90a28952d 100644 --- a/asoc/codecs/wcd9xxx-utils.c +++ b/asoc/codecs/wcd9xxx-utils.c @@ -342,6 +342,19 @@ struct wcd9xxx_pdata *wcd9xxx_populate_dt_data(struct device *dev) goto err_parse_dt_prop; } + pdata->has_buck_vsel_gpio = of_property_read_bool(dev->of_node, + "qcom,has-buck-vsel-gpio"); + if (pdata->has_buck_vsel_gpio) { + pdata->buck_vsel_ctl_np = of_parse_phandle(dev->of_node, + "qcom,buck-vsel-gpio-node", 0); + if (!pdata->buck_vsel_ctl_np) { + dev_err(dev, "%s No entry for %s property in node %s\n", + __func__, "qcom,buck-vsel-gpio-node", + dev->of_node->full_name); + goto err_parse_dt_prop; + } + } + if (!(wcd9xxx_read_of_property_u32(dev, "qcom,cdc-mclk-clk-rate", &prop_val))) pdata->mclk_rate = prop_val; diff --git a/asoc/codecs/wsa881x.h b/asoc/codecs/wsa881x.h index be234ac0cd07..fbc60d86a12b 100644 --- a/asoc/codecs/wsa881x.h +++ b/asoc/codecs/wsa881x.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -20,9 +20,10 @@ #define WSA881X_MAX_SWR_PORTS 4 +#if IS_ENABLED(CONFIG_SND_SOC_WSA881X) extern int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, - u8 num_port, unsigned int *ch_mask, - unsigned int *ch_rate); + u8 num_port, unsigned int *ch_mask, + unsigned int *ch_rate); extern const u8 wsa881x_reg_readable[WSA881X_CACHE_SIZE]; extern struct regmap_config wsa881x_regmap_config; @@ -31,4 +32,25 @@ extern int wsa881x_codec_info_create_codec_entry( struct snd_soc_codec *codec); void wsa881x_regmap_defaults(struct regmap *regmap, u8 version); +#else +extern int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, + u8 num_port, unsigned int *ch_mask, + unsigned int *ch_rate) +{ + return 0; +} + +extern int wsa881x_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + return 0; +} + +void wsa881x_regmap_defaults(struct regmap *regmap, u8 version) +{ +} + +#endif + #endif /* _WSA881X_H */ diff --git a/asoc/msm-audio-effects-q6-v2.c b/asoc/msm-audio-effects-q6-v2.c index 962d64e94ba3..2385bac36f36 100644 --- a/asoc/msm-audio-effects-q6-v2.c +++ b/asoc/msm-audio-effects-q6-v2.c @@ -154,7 +154,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "VIRT ENABLE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_VIRTUALIZER; *updt_params++ = @@ -182,7 +182,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "VIRT STRENGTH", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_VIRTUALIZER; *updt_params++ = @@ -210,7 +210,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "VIRT OUT_TYPE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_VIRTUALIZER; *updt_params++ = @@ -238,7 +238,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "VIRT GAIN_ADJUST", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_VIRTUALIZER; *updt_params++ = @@ -316,7 +316,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_ENABLE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -344,7 +344,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_MODE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -372,7 +372,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_PRESET", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -400,7 +400,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_WET_MIX", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -428,7 +428,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_GAIN_ADJUST", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -456,7 +456,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_ROOM_LEVEL", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -484,7 +484,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_ROOM_HF_LEVEL", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -512,7 +512,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_DECAY_TIME", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -540,7 +540,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_DECAY_HF_RATIO", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -568,7 +568,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_REFLECTIONS_LEVEL", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -596,7 +596,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_REFLECTIONS_DELAY", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -624,7 +624,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_LEVEL", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -652,7 +652,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_DELAY", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -680,7 +680,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_DIFFUSION", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -708,7 +708,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_DENSITY", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -787,7 +787,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "BASS_BOOST_ENABLE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_BASS_BOOST; *updt_params++ = @@ -815,7 +815,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "BASS_BOOST_MODE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_BASS_BOOST; *updt_params++ = @@ -843,7 +843,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "BASS_BOOST_STRENGTH", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_BASS_BOOST; *updt_params++ = @@ -920,7 +920,7 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "PBE_ENABLE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_PBE; *updt_params++ = @@ -946,7 +946,7 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "PBE_PARAM", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_PBE; *updt_params++ = @@ -1031,7 +1031,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "EQ_ENABLE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; *updt_params++ = @@ -1099,7 +1099,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "EQ_CONFIG", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; *updt_params++ = @@ -1150,7 +1150,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "EQ_BAND_INDEX", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; *updt_params++ = @@ -1182,7 +1182,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "EQ_SINGLE_BAND_FREQ", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; *updt_params++ = @@ -1271,7 +1271,7 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, "VOLUME/VOLUME2_GAIN_2CH", rc); if (rc != 0) - break; + goto invalid_config; if (instance == SOFT_VOLUME_INSTANCE_2) *updt_params++ = ASM_MODULE_ID_VOL_CTRL2; @@ -1320,7 +1320,7 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, "VOLUME/VOLUME2_GAIN_MASTER", rc); if (rc != 0) - break; + goto invalid_config; if (instance == SOFT_VOLUME_INSTANCE_2) *updt_params++ = ASM_MODULE_ID_VOL_CTRL2; diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index 30a4d59f2ba4..89a9cc24a2e0 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -2376,8 +2376,20 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .rate_min = 8000, .rate_max = 384000, }, + .capture = { + .stream_name = "MultiMedia10 Capture", + .aif_name = "MM_UL10", + .rates = (SNDRV_PCM_RATE_8000_48000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, .ops = &msm_fe_Multimedia_dai_ops, - .compress_new = snd_soc_new_compress, .name = "MultiMedia10", .probe = fe_dai_probe, }, diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index e96d111a61e4..339125e2d775 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -1682,7 +1682,7 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s REG_SND_MODEL failed err %d\n", __func__, err); - return err; + goto done; } break; case SNDRV_LSM_SET_PARAMS: { @@ -1852,13 +1852,15 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: Invalid params event_status_v3\n", __func__); - return -EINVAL; + err = -EINVAL; + goto done; } if (copy_from_user(&userarg, arg, sizeof(userarg))) { dev_err(rtd->dev, "%s: err copyuser event_status_v3\n", __func__); - return -EFAULT; + err = -EFAULT; + goto done; } if (userarg.payload_size > @@ -1866,7 +1868,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, pr_err("%s: payload_size %d is invalid, max allowed = %d\n", __func__, userarg.payload_size, LISTEN_MAX_STATUS_PAYLOAD_SIZE); - return -EINVAL; + err = -EINVAL; + goto done; } size = sizeof(struct snd_lsm_event_status_v3) + @@ -1876,7 +1879,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: Allocation failed event status size %d\n", __func__, size); - return -EFAULT; + err = -EFAULT; + goto done; } user->payload_size = userarg.payload_size; err = msm_lsm_ioctl_shared(substream, cmd, user); diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index aa9b3abf6a48..8e3fe895d98d 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1093,7 +1093,7 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, port_type = MSM_AFE_PORT_TYPE_RX; } else if (stream_type == SNDRV_PCM_STREAM_CAPTURE) { session_type = SESSION_TYPE_TX; - if (passthr_mode != LEGACY_PCM) + if ((passthr_mode != LEGACY_PCM) && (passthr_mode != LISTEN)) path_type = ADM_PATH_COMPRESSED_TX; else path_type = ADM_PATH_LIVE_REC; @@ -3645,6 +3645,11 @@ static const struct snd_kcontrol_new ext_ec_ref_mux_ul16 = msm_route_ec_ref_rx_enum[0], msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); +static const struct snd_kcontrol_new ext_ec_ref_mux_ul10 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL10 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + static const struct snd_kcontrol_new ext_ec_ref_mux_ul17 = SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL17 MUX Mux", msm_route_ec_ref_rx_enum[0], @@ -7251,6 +7256,59 @@ static const struct snd_kcontrol_new mmul9_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new mmul10_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; static const struct snd_kcontrol_new mmul17_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, @@ -11489,6 +11547,7 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL9", "MultiMedia9 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL10", "MultiMedia10 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL16", "MultiMedia16 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL17", "MultiMedia17 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL18", "MultiMedia18 Capture", 0, 0, 0, 0), @@ -12225,6 +12284,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia9 Mixer", SND_SOC_NOPM, 0, 0, mmul9_mixer_controls, ARRAY_SIZE(mmul9_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia10 Mixer", SND_SOC_NOPM, 0, 0, + mmul10_mixer_controls, ARRAY_SIZE(mmul10_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia16 Mixer", SND_SOC_NOPM, 0, 0, mmul16_mixer_controls, ARRAY_SIZE(mmul16_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia17 Mixer", SND_SOC_NOPM, 0, 0, @@ -12557,6 +12618,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &ext_ec_ref_mux_ul8), SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL9 MUX", SND_SOC_NOPM, 0, 0, &ext_ec_ref_mux_ul9), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL10 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul10), SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL16 MUX", SND_SOC_NOPM, 0, 0, &ext_ec_ref_mux_ul16), SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL17 MUX", SND_SOC_NOPM, 0, 0, @@ -12810,9 +12873,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia10 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia16 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia5 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"MultiMedia5 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"MultiMedia10 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, {"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, @@ -13379,6 +13444,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"}, {"MultiMedia3 Mixer", "MI2S_TX", "MI2S_TX"}, {"MultiMedia5 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia10 Mixer", "MI2S_TX", "MI2S_TX"}, {"MultiMedia16 Mixer", "MI2S_TX", "MI2S_TX"}, {"MultiMedia1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, @@ -13395,17 +13461,21 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"MultiMedia3 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, {"MultiMedia5 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"MultiMedia10 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, {"MultiMedia1 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia3 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia5 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia10 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia16 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, {"MultiMedia16 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia1 Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, {"MultiMedia3 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, {"MultiMedia5 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, + {"MultiMedia10 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, {"MultiMedia1 Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, {"MultiMedia3 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, {"MultiMedia5 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia10 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, {"MultiMedia16 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, {"MultiMedia2 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia2 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, @@ -13418,13 +13488,16 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia10 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia6 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, {"MultiMedia3 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, {"MultiMedia5 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia10 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, {"MultiMedia16 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, {"MultiMedia6 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia10 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia16 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia6 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, @@ -13559,6 +13632,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia9 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia9 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia10 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia10 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia10 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia10 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia10 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia10 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia10 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia10 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, {"MultiMedia20 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia20 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"MultiMedia20 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, @@ -13586,6 +13667,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia6 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia8 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia10 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia16 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia16 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -13682,6 +13764,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia3 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia4 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia10 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia17 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia18 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia19 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, @@ -13701,6 +13784,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia3 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia4 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia10 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia17 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia18 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia19 Mixer", "AFE_PCM_TX", "PCM_TX"}, @@ -13716,6 +13800,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL6", NULL, "MultiMedia6 Mixer"}, {"MM_UL8", NULL, "MultiMedia8 Mixer"}, {"MM_UL9", NULL, "MultiMedia9 Mixer"}, + {"MM_UL10", NULL, "MultiMedia10 Mixer"}, {"MM_UL16", NULL, "MultiMedia16 Mixer"}, {"MM_UL17", NULL, "MultiMedia17 Mixer"}, {"MM_UL18", NULL, "MultiMedia18 Mixer"}, @@ -14104,6 +14189,16 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUDIO_REF_EC_UL9 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"AUDIO_REF_EC_UL9 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_0", "QUAT_TDM_RX_0"}, + {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_1", "QUAT_TDM_RX_1"}, + {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_2", "QUAT_TDM_RX_2"}, + {"AUDIO_REF_EC_UL10 MUX", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"AUDIO_REF_EC_UL17 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"AUDIO_REF_EC_UL17 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"AUDIO_REF_EC_UL17 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, @@ -14127,6 +14222,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL6", NULL, "AUDIO_REF_EC_UL6 MUX"}, {"MM_UL8", NULL, "AUDIO_REF_EC_UL8 MUX"}, {"MM_UL9", NULL, "AUDIO_REF_EC_UL9 MUX"}, + {"MM_UL10", NULL, "AUDIO_REF_EC_UL10 MUX"}, {"MM_UL16", NULL, "AUDIO_REF_EC_UL16 MUX"}, {"MM_UL17", NULL, "AUDIO_REF_EC_UL17 MUX"}, {"MM_UL18", NULL, "AUDIO_REF_EC_UL18 MUX"}, diff --git a/asoc/msm8998.c b/asoc/msm8998.c index b2fc005ebbb4..5f0128d05b0c 100644 --- a/asoc/msm8998.c +++ b/asoc/msm8998.c @@ -5036,12 +5036,13 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .id = MSM_FRONTEND_DAI_MULTIMEDIA7, }, { - .name = MSM_DAILINK_NAME(Compress3), - .stream_name = "Compress3", + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", .cpu_dai_name = "MultiMedia10", - .platform_name = "msm-compress-dsp", + .platform_name = "msm-pcm-dsp.1", .dynamic = 1, .dpcm_playback = 1, + .dpcm_capture = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .codec_dai_name = "snd-soc-dummy-dai", diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c index 16ecfaf9e8c7..f73e1cdd8f60 100644 --- a/asoc/sdm660-common.c +++ b/asoc/sdm660-common.c @@ -44,6 +44,8 @@ enum { EXT_DISP_RX_IDX_MAX, }; +bool codec_reg_done; + /* TDM default config */ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { { /* PRI TDM */ @@ -2016,6 +2018,12 @@ int msm_common_snd_controls_size(void) } EXPORT_SYMBOL(msm_common_snd_controls_size); +void msm_set_codec_reg_done(bool done) +{ + codec_reg_done = done; +} +EXPORT_SYMBOL(msm_set_codec_reg_done); + static inline int param_is_mask(int p) { return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && @@ -3027,6 +3035,12 @@ static const struct of_device_id sdm660_asoc_machine_of_match[] = { .data = "tasha_codec"}, { .compatible = "qcom,sdm660-asoc-snd-tavil", .data = "tavil_codec"}, + { .compatible = "qcom,sdm670-asoc-snd", + .data = "internal_codec"}, + { .compatible = "qcom,sdm670-asoc-snd-tasha", + .data = "tasha_codec"}, + { .compatible = "qcom,sdm670-asoc-snd-tavil", + .data = "tavil_codec"}, {}, }; @@ -3044,6 +3058,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) if (!pdata) return -ENOMEM; + msm_set_codec_reg_done(false); match = of_match_node(sdm660_asoc_machine_of_match, pdev->dev.of_node); if (!match) diff --git a/asoc/sdm660-common.h b/asoc/sdm660-common.h index 682dcd5d055e..0544b968d159 100644 --- a/asoc/sdm660-common.h +++ b/asoc/sdm660-common.h @@ -122,4 +122,5 @@ void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream); int msm_mi2s_snd_startup(struct snd_pcm_substream *substream); void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream); int msm_common_snd_controls_size(void); +void msm_set_codec_reg_done(bool done); #endif diff --git a/asoc/sdm660-ext-dai-links.c b/asoc/sdm660-ext-dai-links.c index 71ba1fa9060f..a76c16d76d00 100644 --- a/asoc/sdm660-ext-dai-links.c +++ b/asoc/sdm660-ext-dai-links.c @@ -29,8 +29,15 @@ #define WCN_CDC_SLIM_RX_CH_MAX 2 #define WCN_CDC_SLIM_TX_CH_MAX 3 -static struct snd_soc_card snd_soc_card_msm_card_tavil; -static struct snd_soc_card snd_soc_card_msm_card_tasha; +static struct snd_soc_card snd_soc_card_msm_card_tavil = { + .name = "sdm670-tavil-snd-card", + .late_probe = msm_snd_card_tavil_late_probe, +}; + +static struct snd_soc_card snd_soc_card_msm_card_tasha = { + .name = "sdm670-tasha-snd-card", + .late_probe = msm_snd_card_tasha_late_probe, +}; static struct snd_soc_ops msm_ext_slimbus_be_ops = { .hw_params = msm_snd_hw_params, @@ -990,13 +997,14 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .id = MSM_FRONTEND_DAI_MULTIMEDIA7, }, {/* hw:x,16 */ - .name = MSM_DAILINK_NAME(Compress3), - .stream_name = "Compress3", + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", .cpu_dai_name = "MultiMedia10", - .platform_name = "msm-compress-dsp", + .platform_name = "msm-pcm-dsp.1", .dynamic = 1, .dpcm_capture = 1, .dpcm_playback = 1, + .dpcm_capture = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .codec_dai_name = "snd-soc-dummy-dai", diff --git a/asoc/sdm660-external.c b/asoc/sdm660-external.c index 9085282964c0..dd8983c973e4 100644 --- a/asoc/sdm660-external.c +++ b/asoc/sdm660-external.c @@ -56,7 +56,6 @@ static int msm_ext_spk_control = 1; static struct wcd_mbhc_config *wcd_mbhc_cfg_ptr; -bool codec_reg_done; struct msm_asoc_wcd93xx_codec { void* (*get_afe_config_fn)(struct snd_soc_codec *codec, @@ -604,23 +603,23 @@ static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, static void *def_ext_mbhc_cal(void) { - void *tavil_wcd_cal; + void *wcd_mbhc_cal; struct wcd_mbhc_btn_detect_cfg *btn_cfg; u16 *btn_high; - tavil_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, + wcd_mbhc_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); - if (!tavil_wcd_cal) + if (!wcd_mbhc_cal) return NULL; -#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(tavil_wcd_cal)->X) = (Y)) +#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(wcd_mbhc_cal)->X) = (Y)) S(v_hs_max, 1600); #undef S -#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal)->X) = (Y)) +#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal)->X) = (Y)) S(num_btn, WCD_MBHC_DEF_BUTTONS); #undef S - btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal); + btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal); btn_high = ((void *)&btn_cfg->_v_btn_low) + (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); @@ -633,7 +632,7 @@ static void *def_ext_mbhc_cal(void) btn_high[6] = 500; btn_high[7] = 500; - return tavil_wcd_cal; + return wcd_mbhc_cal; } static inline int param_is_mask(int p) @@ -1479,6 +1478,79 @@ static struct snd_soc_dapm_route wcd_audio_paths[] = { {"MIC BIAS4", NULL, "MCLK"}, }; +int msm_snd_card_tasha_late_probe(struct snd_soc_card *card) +{ + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + void *mbhc_calibration; + + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err_pcm_runtime; + } + + mbhc_calibration = def_ext_mbhc_cal(); + if (!mbhc_calibration) { + ret = -ENOMEM; + goto err_mbhc_cal; + } + wcd_mbhc_cfg_ptr->calibration = mbhc_calibration; + ret = tasha_mbhc_hs_detect(rtd->codec, wcd_mbhc_cfg_ptr); + if (ret) { + dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", + __func__, ret); + goto err_hs_detect; + } + return 0; + +err_hs_detect: + kfree(mbhc_calibration); +err_mbhc_cal: +err_pcm_runtime: + return ret; +} + +int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) +{ + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + void *mbhc_calibration; + + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err; + } + + mbhc_calibration = def_ext_mbhc_cal(); + if (!mbhc_calibration) { + ret = -ENOMEM; + goto err; + } + wcd_mbhc_cfg_ptr->calibration = mbhc_calibration; + ret = tavil_mbhc_hs_detect(rtd->codec, wcd_mbhc_cfg_ptr); + if (ret) { + dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", + __func__, ret); + goto err_free_mbhc_cal; + } + return 0; + +err_free_mbhc_cal: + kfree(mbhc_calibration); +err: + return ret; +} + /** * msm_audrx_init - Audio init function of sound card instantiate. * @@ -1699,7 +1771,6 @@ int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) if (!entry) { pr_debug("%s: Cannot create codecs module entry\n", __func__); - pdata->codec_root = NULL; goto done; } pdata->codec_root = entry; @@ -1722,50 +1793,17 @@ int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) if (!entry) { pr_debug("%s: Cannot create codecs module entry\n", __func__); - ret = 0; - goto err_snd_module; + goto done; } pdata->codec_root = entry; tasha_codec_info_create_codec_entry(pdata->codec_root, codec); tasha_mbhc_zdet_gpio_ctrl(msm_config_hph_en0_gpio, rtd->codec); } - - wcd_mbhc_cfg_ptr->calibration = def_ext_mbhc_cal(); - if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { - if (wcd_mbhc_cfg_ptr->calibration) { - pdata->codec = codec; - ret = tavil_mbhc_hs_detect(codec, wcd_mbhc_cfg_ptr); - if (ret < 0) - pr_err("%s: Failed to intialise mbhc %d\n", - __func__, ret); - } else { - pr_err("%s: wcd_mbhc_cfg calibration is NULL\n", - __func__); - ret = -ENOMEM; - goto err_mbhc_cal; - } - } else { - if (wcd_mbhc_cfg_ptr->calibration) { - pdata->codec = codec; - ret = tasha_mbhc_hs_detect(codec, wcd_mbhc_cfg_ptr); - if (ret < 0) - pr_err("%s: Failed to intialise mbhc %d\n", - __func__, ret); - } else { - pr_err("%s: wcd_mbhc_cfg calibration is NULL\n", - __func__); - ret = -ENOMEM; - goto err_mbhc_cal; - } - - } - codec_reg_done = true; done: + msm_set_codec_reg_done(true); return 0; -err_snd_module: err_afe_cfg: -err_mbhc_cal: return ret; } EXPORT_SYMBOL(msm_audrx_init); diff --git a/asoc/sdm660-external.h b/asoc/sdm660-external.h index acf5735c2502..d53e7c7d9518 100644 --- a/asoc/sdm660-external.h +++ b/asoc/sdm660-external.h @@ -30,6 +30,8 @@ struct snd_soc_card *populate_snd_card_dailinks(struct device *dev, int snd_card_val); int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params); +int msm_snd_card_tavil_late_probe(struct snd_soc_card *card); +int msm_snd_card_tasha_late_probe(struct snd_soc_card *card); #ifdef CONFIG_SND_SOC_EXT_CODEC int msm_ext_cdc_init(struct platform_device *, struct msm_asoc_mach_data *, struct snd_soc_card **, struct wcd_mbhc_config *); diff --git a/asoc/sdm660-internal.c b/asoc/sdm660-internal.c index fc2378d4e8d2..b5b05b10c9a5 100644 --- a/asoc/sdm660-internal.c +++ b/asoc/sdm660-internal.c @@ -1314,6 +1314,7 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) msm_dig_codec_info_create_codec_entry(codec_root, dig_cdc); msm_anlg_codec_info_create_codec_entry(codec_root, ana_cdc); done: + msm_set_codec_reg_done(true); return 0; } @@ -1914,13 +1915,14 @@ static struct snd_soc_dai_link msm_int_dai[] = { .id = MSM_FRONTEND_DAI_MULTIMEDIA7, }, {/* hw:x,16 */ - .name = MSM_DAILINK_NAME(Compress3), - .stream_name = "Compress3", + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", .cpu_dai_name = "MultiMedia10", - .platform_name = "msm-compress-dsp", + .platform_name = "msm-pcm-dsp.1", .dynamic = 1, .dpcm_capture = 1, .dpcm_playback = 1, + .dpcm_capture = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .codec_dai_name = "snd-soc-dummy-dai", diff --git a/asoc/sdm845.c b/asoc/sdm845.c index e38def3c9e95..7f29450062a9 100644 --- a/asoc/sdm845.c +++ b/asoc/sdm845.c @@ -5126,12 +5126,13 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .id = MSM_FRONTEND_DAI_MULTIMEDIA7, }, { - .name = MSM_DAILINK_NAME(Compress3), - .stream_name = "Compress3", + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", .cpu_dai_name = "MultiMedia10", - .platform_name = "msm-compress-dsp", + .platform_name = "msm-pcm-dsp.1", .dynamic = 1, .dpcm_playback = 1, + .dpcm_capture = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .codec_dai_name = "snd-soc-dummy-dai", @@ -6696,16 +6697,18 @@ static int msm_init_wsa_dev(struct platform_device *pdev, ret = of_property_read_u32(pdev->dev.of_node, "qcom,wsa-max-devs", &wsa_max_devs); if (ret) { - dev_dbg(&pdev->dev, + dev_info(&pdev->dev, "%s: wsa-max-devs property missing in DT %s, ret = %d\n", __func__, pdev->dev.of_node->full_name, ret); - goto err; + card->num_aux_devs = 0; + return 0; } if (wsa_max_devs == 0) { dev_warn(&pdev->dev, "%s: Max WSA devices is 0 for this target?\n", __func__); - goto err; + card->num_aux_devs = 0; + return 0; } /* Get count of WSA device phandles for this platform */ diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c index 52dced4f3558..c67a24d7aa15 100644 --- a/dsp/codecs/audio_utils_aio.c +++ b/dsp/codecs/audio_utils_aio.c @@ -30,7 +30,9 @@ #ifdef CONFIG_USE_DEV_CTRL_VOLUME #include #endif /*CONFIG_USE_DEV_CTRL_VOLUME*/ +static DEFINE_MUTEX(lock); #ifdef CONFIG_DEBUG_FS + int audio_aio_debug_open(struct inode *inode, struct file *file) { file->private_data = inode->i_private; @@ -43,29 +45,37 @@ ssize_t audio_aio_debug_read(struct file *file, char __user *buf, const int debug_bufmax = 4096; static char buffer[4096]; int n = 0; - struct q6audio_aio *audio = file->private_data; + struct q6audio_aio *audio; - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "feedback %d\n", audio->feedback); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "inqueue empty %d\n", list_empty(&audio->in_queue)); - n += scnprintf(buffer + n, debug_bufmax - n, - "outqueue empty %d\n", list_empty(&audio->out_queue)); + mutex_lock(&lock); + if (file->private_data != NULL) { + audio = file->private_data; + mutex_lock(&audio->lock); + n = scnprintf(buffer, debug_bufmax, "opened %d\n", + audio->opened); + n += scnprintf(buffer + n, debug_bufmax - n, + "enabled %d\n", audio->enabled); + n += scnprintf(buffer + n, debug_bufmax - n, + "stopped %d\n", audio->stopped); + n += scnprintf(buffer + n, debug_bufmax - n, + "feedback %d\n", audio->feedback); + mutex_unlock(&audio->lock); + /* Following variables are only useful for debugging when + * when playback halts unexpectedly. Thus, no mutual exclusion + * enforced + */ + n += scnprintf(buffer + n, debug_bufmax - n, + "wflush %d\n", audio->wflush); + n += scnprintf(buffer + n, debug_bufmax - n, + "rflush %d\n", audio->rflush); + n += scnprintf(buffer + n, debug_bufmax - n, + "inqueue empty %d\n", + list_empty(&audio->in_queue)); + n += scnprintf(buffer + n, debug_bufmax - n, + "outqueue empty %d\n", + list_empty(&audio->out_queue)); + } + mutex_unlock(&lock); buffer[n] = 0; return simple_read_from_buffer(buf, count, ppos, buffer, n); } @@ -580,6 +590,7 @@ int audio_aio_release(struct inode *inode, struct file *file) struct q6audio_aio *audio = file->private_data; pr_debug("%s[%pK]\n", __func__, audio); + mutex_lock(&lock); mutex_lock(&audio->lock); mutex_lock(&audio->read_lock); mutex_lock(&audio->write_lock); @@ -622,6 +633,8 @@ int audio_aio_release(struct inode *inode, struct file *file) #endif kfree(audio->codec_cfg); kfree(audio); + file->private_data = NULL; + mutex_unlock(&lock); return 0; } diff --git a/dsp/q6core.c b/dsp/q6core.c index dd97a495221b..181a800cbf1f 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -20,7 +20,9 @@ #include #include #include +#include #include +#include "adsp_err.h" #define TIMEOUT_MS 1000 /* @@ -36,16 +38,30 @@ enum { CORE_MAX_CAL }; +enum ver_query_status { + VER_QUERY_UNATTEMPTED, + VER_QUERY_UNSUPPORTED, + VER_QUERY_SUPPORTED +}; + +struct q6core_avcs_ver_info { + enum ver_query_status status; + struct avcs_fwk_ver_info ver_info; +}; + struct q6core_str { struct apr_svc *core_handle_q; wait_queue_head_t bus_bw_req_wait; wait_queue_head_t cmd_req_wait; + wait_queue_head_t avcs_fwk_ver_req_wait; u32 bus_bw_resp_received; enum cmd_flags { FLAG_NONE, FLAG_CMDRSP_LICENSE_RESULT } cmd_resp_received_flag; + u32 avcs_fwk_ver_resp_received; struct mutex cmd_lock; + struct mutex ver_lock; union { struct avcs_cmdrsp_get_license_validation_result cmdrsp_license_result; @@ -54,6 +70,7 @@ struct q6core_str { struct cal_type_data *cal_data[CORE_MAX_CAL]; uint32_t mem_map_cal_handle; int32_t adsp_status; + struct q6core_avcs_ver_info q6core_avcs_ver_info; }; static struct q6core_str q6core_lcl; @@ -65,9 +82,61 @@ struct generic_get_data_ { }; static struct generic_get_data_ *generic_get_data; +static int parse_fwk_version_info(uint32_t *payload) +{ + size_t fwk_ver_size; + size_t svc_size; + int num_services; + int ret = 0; + + pr_debug("%s: Payload info num services %d\n", + __func__, payload[4]); + /* + * payload1[4] is the number of services running on DSP + * Based on this info, we copy the payload into core + * avcs version info structure. + */ + num_services = payload[4]; + q6core_lcl.q6core_avcs_ver_info.ver_info.avcs_fwk_version. + num_services = num_services; + if (num_services > VSS_MAX_AVCS_NUM_SERVICES) { + pr_err("%s: num_services: %d greater than max services: %d\n", + __func__, num_services, VSS_MAX_AVCS_NUM_SERVICES); + ret = -EINVAL; + goto done; + } + fwk_ver_size = sizeof(struct avcs_get_fwk_version); + svc_size = num_services * sizeof(struct avs_svc_api_info); + /* + * Dynamically allocate memory for all + * the services based on num_services + */ + q6core_lcl.q6core_avcs_ver_info.ver_info.services = NULL; + q6core_lcl.q6core_avcs_ver_info.ver_info.services = + kzalloc(svc_size, GFP_ATOMIC); + if (q6core_lcl.q6core_avcs_ver_info.ver_info.services == NULL) { + ret = -ENOMEM; + goto done; + } + /* + * memcpy is done twice because the memory allocated for + * q6core_lcl.q6core_avcs_ver_info.ver_info is not + * contiguous. + */ + memcpy(&q6core_lcl.q6core_avcs_ver_info.ver_info, + (uint8_t *)payload, fwk_ver_size); + memcpy(q6core_lcl.q6core_avcs_ver_info.ver_info.services, + (uint8_t *)&payload[sizeof(struct avcs_get_fwk_version)/ + sizeof(uint32_t)], svc_size); + ret = 0; +done: + return ret; +} + static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) { uint32_t *payload1; + int ret = 0; if (data == NULL) { pr_err("%s: data argument is null\n", __func__); @@ -118,6 +187,17 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) q6core_lcl.bus_bw_resp_received = 1; wake_up(&q6core_lcl.bus_bw_req_wait); break; + case AVCS_CMD_GET_FWK_VERSION: + pr_debug("%s: Cmd = AVCS_CMD_GET_FWK_VERSION status[%s]\n", + __func__, adsp_err_get_err_str(payload1[1])); + /* ADSP status to match Linux error standard */ + q6core_lcl.adsp_status = -payload1[1]; + if (payload1[1] == ADSP_EUNSUPPORTED) + q6core_lcl.q6core_avcs_ver_info.status = + VER_QUERY_UNSUPPORTED; + q6core_lcl.avcs_fwk_ver_resp_received = 1; + wake_up(&q6core_lcl.avcs_fwk_ver_req_wait); + break; default: pr_err("%s: Invalid cmd rsp[0x%x][0x%x] opcode %d\n", __func__, @@ -130,7 +210,7 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) case RESET_EVENTS:{ pr_debug("%s: Reset event received in Core service\n", __func__); - apr_reset(q6core_lcl.core_handle_q); + /* no reset done as the data will not change after SSR*/ q6core_lcl.core_handle_q = NULL; break; } @@ -161,6 +241,18 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) q6core_lcl.cmd_resp_received_flag = FLAG_CMDRSP_LICENSE_RESULT; wake_up(&q6core_lcl.cmd_req_wait); break; + case AVCS_CMDRSP_GET_FWK_VERSION: + pr_debug("%s: Received AVCS_CMDRSP_GET_FWK_VERSION\n", + __func__); + payload1 = data->payload; + q6core_lcl.q6core_avcs_ver_info.status = VER_QUERY_SUPPORTED; + q6core_lcl.avcs_fwk_ver_resp_received = 1; + ret = parse_fwk_version_info(payload1); + if (ret < 0) + pr_err("%s: Failed to parse payload:%d\n", + __func__, ret); + wake_up(&q6core_lcl.avcs_fwk_ver_req_wait); + break; default: pr_err("%s: Message id from adsp core svc: 0x%x\n", __func__, data->opcode); @@ -217,6 +309,157 @@ struct cal_block_data *cal_utils_get_cal_block_by_key( return NULL; } +static int q6core_send_get_avcs_fwk_ver_cmd(void) +{ + struct apr_hdr avcs_ver_cmd; + int ret; + + avcs_ver_cmd.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + avcs_ver_cmd.pkt_size = sizeof(struct apr_hdr); + avcs_ver_cmd.src_port = 0; + avcs_ver_cmd.dest_port = 0; + avcs_ver_cmd.token = 0; + avcs_ver_cmd.opcode = AVCS_CMD_GET_FWK_VERSION; + + q6core_lcl.adsp_status = 0; + q6core_lcl.avcs_fwk_ver_resp_received = 0; + + ret = apr_send_pkt(q6core_lcl.core_handle_q, + (uint32_t *) &avcs_ver_cmd); + if (ret < 0) { + pr_err("%s: failed to send apr packet, ret=%d\n", __func__, + ret); + goto done; + } + + ret = wait_event_timeout(q6core_lcl.avcs_fwk_ver_req_wait, + (q6core_lcl.avcs_fwk_ver_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout for AVCS fwk version info\n", + __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (q6core_lcl.adsp_status < 0) { + /* + * adsp_err_get_err_str expects a positive value but we store + * the DSP error as negative to match the Linux error standard. + * Pass in the negated value so adsp_err_get_err_str returns + * the correct string. + */ + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(-q6core_lcl.adsp_status)); + ret = adsp_err_get_lnx_err_code(q6core_lcl.adsp_status); + goto done; + } + + ret = 0; + +done: + return ret; +} + +int q6core_get_service_version(uint32_t service_id, + struct avcs_fwk_ver_info *ver_info, + size_t size) +{ + int i; + uint32_t num_services; + size_t svc_size; + + svc_size = q6core_get_avcs_service_size(service_id); + if (svc_size != size) { + pr_err("%s: Expected size: %ld, Provided size: %ld", + __func__, svc_size, size); + return -EINVAL; + } + + num_services = + q6core_lcl.q6core_avcs_ver_info.ver_info. + avcs_fwk_version.num_services; + + if (ver_info == NULL) { + pr_err("%s: NULL parameter ver_info\n", __func__); + return -EINVAL; + } + + memcpy(ver_info, &q6core_lcl.q6core_avcs_ver_info. + ver_info.avcs_fwk_version, sizeof(struct avcs_get_fwk_version)); + + if (service_id == AVCS_SERVICE_ID_ALL) { + memcpy(&ver_info->services[0], &q6core_lcl. + q6core_avcs_ver_info.ver_info.services[0], + (num_services * sizeof(struct avs_svc_api_info))); + } else { + for (i = 0; i < num_services; i++) { + if (q6core_lcl.q6core_avcs_ver_info. + ver_info.services[i].service_id == service_id) { + memcpy(&ver_info->services[0], + &q6core_lcl.q6core_avcs_ver_info. + ver_info.services[i], size); + break; + } + } + } + + return 0; +} +EXPORT_SYMBOL(q6core_get_service_version); + +size_t q6core_get_avcs_service_size(uint32_t service_id) +{ + int ret = 0; + uint32_t num_services; + + num_services = + q6core_lcl.q6core_avcs_ver_info.ver_info. + avcs_fwk_version.num_services; + + mutex_lock(&(q6core_lcl.ver_lock)); + pr_debug("%s: q6core_avcs_ver_info.status(%d)\n", __func__, + q6core_lcl.q6core_avcs_ver_info.status); + + switch (q6core_lcl.q6core_avcs_ver_info.status) { + case VER_QUERY_SUPPORTED: + pr_debug("%s: AVCS FWK version query already attempted\n", + __func__); + ret = num_services * sizeof(struct avs_svc_api_info); + break; + case VER_QUERY_UNSUPPORTED: + ret = -EOPNOTSUPP; + break; + case VER_QUERY_UNATTEMPTED: + pr_debug("%s: Attempting AVCS FWK version query\n", __func__); + if (q6core_is_adsp_ready()) { + ret = q6core_send_get_avcs_fwk_ver_cmd(); + if (ret == 0) + ret = num_services * + sizeof(struct avs_svc_api_info); + } else { + pr_err("%s: ADSP is not ready to query version\n", + __func__); + ret = -ENODEV; + } + break; + default: + pr_err("%s: Invalid version query status %d\n", __func__, + q6core_lcl.q6core_avcs_ver_info.status); + ret = -EINVAL; + break; + } + mutex_unlock(&(q6core_lcl.ver_lock)); + + if (service_id != AVCS_SERVICE_ID_ALL) + return sizeof(struct avs_svc_api_info); + + return ret; +} +EXPORT_SYMBOL(q6core_get_avcs_service_size); + int32_t core_set_license(uint32_t key, uint32_t module_id) { struct avcs_cmd_set_license *cmd_setl = NULL; @@ -827,18 +1070,16 @@ static int q6core_init_cal_data(void) static int __init core_init(void) { + memset(&q6core_lcl, 0, sizeof(struct q6core_str)); init_waitqueue_head(&q6core_lcl.bus_bw_req_wait); - q6core_lcl.bus_bw_resp_received = 0; - - q6core_lcl.core_handle_q = NULL; - init_waitqueue_head(&q6core_lcl.cmd_req_wait); + init_waitqueue_head(&q6core_lcl.avcs_fwk_ver_req_wait); q6core_lcl.cmd_resp_received_flag = FLAG_NONE; mutex_init(&q6core_lcl.cmd_lock); - q6core_lcl.mem_map_cal_handle = 0; - q6core_lcl.adsp_status = 0; + mutex_init(&q6core_lcl.ver_lock); q6core_init_cal_data(); + return 0; } module_init(core_init); @@ -846,6 +1087,7 @@ module_init(core_init); static void __exit core_exit(void) { mutex_destroy(&q6core_lcl.cmd_lock); + mutex_destroy(&q6core_lcl.ver_lock); q6core_delete_cal_data(); } module_exit(core_exit); diff --git a/dsp/q6voice.c b/dsp/q6voice.c index cfcc822d5484..28e50d9f55eb 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -24,8 +24,9 @@ #include #include #include -#include +#include #include +#include #include "adsp_err.h" #define TIMEOUT_MS 300 @@ -33,6 +34,9 @@ #define CMD_STATUS_SUCCESS 0 #define CMD_STATUS_FAIL 1 +#define NUM_CHANNELS_MONO 1 +#define NUM_CHANNELS_STEREO 2 +#define CVP_VERSION_2 2 enum { VOC_TOKEN_NONE, @@ -83,6 +87,11 @@ static int voice_send_cvp_device_channels_cmd(struct voice_data *v); static int voice_send_cvp_media_format_cmd(struct voice_data *v, uint32_t param_type); static int voice_send_cvp_topology_commit_cmd(struct voice_data *v); +static int voice_send_cvp_channel_info_cmd(struct voice_data *v); +static int voice_send_cvp_channel_info_v2(struct voice_data *v, + uint32_t param_type); +static int voice_get_avcs_version_per_service(uint32_t service_id); + static int voice_cvs_stop_playback(struct voice_data *v); static int voice_cvs_start_playback(struct voice_data *v); @@ -3793,6 +3802,295 @@ int voc_unmap_rtac_block(uint32_t *mem_map_handle) return result; } +static int voice_send_cvp_channel_info_v2(struct voice_data *v, + uint32_t param_type) +{ + int ret; + struct cvp_set_channel_info_cmd_v2 cvp_set_channel_info_cmd; + void *apr_cvp; + u16 cvp_handle; + struct vss_icommon_param_data_channel_info_v2_t + *channel_info_param_data = + &cvp_set_channel_info_cmd. + cvp_set_ch_info_param_v2.param_data; + struct vss_param_vocproc_dev_channel_info_t *channel_info = + &channel_info_param_data->channel_info; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + apr_cvp = common.apr_q6_cvp; + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + cvp_handle = voice_get_cvp_handle(v); + memset(&cvp_set_channel_info_cmd, 0, sizeof(cvp_set_channel_info_cmd)); + + cvp_set_channel_info_cmd.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_set_channel_info_cmd.hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_set_channel_info_cmd) - APR_HDR_SIZE); + cvp_set_channel_info_cmd.hdr.src_svc = 0; + cvp_set_channel_info_cmd.hdr.src_domain = APR_DOMAIN_APPS; + cvp_set_channel_info_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_set_channel_info_cmd.hdr.dest_svc = 0; + cvp_set_channel_info_cmd.hdr.dest_domain = APR_DOMAIN_ADSP; + cvp_set_channel_info_cmd.hdr.dest_port = cvp_handle; + cvp_set_channel_info_cmd.hdr.token = 0; + cvp_set_channel_info_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2; + + cvp_set_channel_info_cmd.cvp_set_ch_info_param_v2.mem_size = + sizeof(struct vss_icommon_param_data_channel_info_v2_t); + + channel_info_param_data->module_id = VSS_MODULE_CVD_GENERIC; + channel_info_param_data->param_size = + sizeof(struct vss_param_vocproc_dev_channel_info_t); + + /* Device specific data */ + switch (param_type) { + case RX_PATH: + channel_info_param_data->param_id = + VSS_PARAM_VOCPROC_RX_CHANNEL_INFO; + channel_info->num_channels = v->dev_rx.no_of_channels; + channel_info->bits_per_sample = v->dev_rx.bits_per_sample; + break; + + case TX_PATH: + channel_info_param_data->param_id = + VSS_PARAM_VOCPROC_TX_CHANNEL_INFO; + channel_info->num_channels = v->dev_tx.no_of_channels; + channel_info->bits_per_sample = v->dev_tx.bits_per_sample; + break; + + case EC_REF_PATH: + channel_info_param_data->param_id = + VSS_PARAM_VOCPROC_EC_REF_CHANNEL_INFO; + channel_info->num_channels = v->dev_rx.no_of_channels; + channel_info->bits_per_sample = v->dev_rx.bits_per_sample; + break; + default: + pr_err("%s: Invalid param type\n", + __func__); + ret = -EINVAL; + goto done; + } + + if (channel_info->num_channels == NUM_CHANNELS_MONO) { + channel_info->channel_mapping[0] = PCM_CHANNEL_FC; + } else if (channel_info->num_channels == NUM_CHANNELS_STEREO) { + channel_info->channel_mapping[0] = PCM_CHANNEL_FL; + channel_info->channel_mapping[1] = PCM_CHANNEL_FR; + } else { + pr_err("%s: Unsupported num channels: %d\n", + __func__, channel_info->num_channels); + ret = -EINVAL; + goto done; + } + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_set_channel_info_cmd); + if (ret < 0) { + pr_err("%s: Failed to send VSS_ICOMMON_CMD_SET_PARAM_V2\n", + __func__); + goto done; + } + + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s] handle = %d\n", __func__, + adsp_err_get_err_str(v->async_err), cvp_handle); + ret = adsp_err_get_lnx_err_code(v->async_err); + goto done; + } + ret = 0; +done: + return ret; +} + +static int voice_send_cvp_channel_info_cmd(struct voice_data *v) +{ + int ret = 0; + + ret = voice_send_cvp_channel_info_v2(v, RX_PATH); + if (ret < 0) { + pr_err("%s: Error in sending cvp_channel_info RX: %d\n", + __func__, ret); + goto done; + } + + ret = voice_send_cvp_channel_info_v2(v, TX_PATH); + if (ret < 0) { + pr_err("%s: Error in sending cvp_channel_info TX: %d\n", + __func__, ret); + goto done; + } + + ret = voice_send_cvp_channel_info_v2(v, EC_REF_PATH); + if (ret < 0) { + pr_err("%s: Error in sending cvp_channel_info EC Ref: %d\n", + __func__, ret); + goto done; + } +done: + return ret; +} + +static int voice_send_cvp_mfc_config_v2(struct voice_data *v) +{ + int ret; + struct cvp_set_mfc_config_cmd_v2 cvp_set_mfc_config_cmd; + void *apr_cvp; + u16 cvp_handle; + struct vss_icommon_param_data_mfc_config_v2_t *cvp_config_param_data = + &cvp_set_mfc_config_cmd.cvp_set_mfc_param_v2.param_data; + struct vss_param_mfc_config_info_t *mfc_config_info = + &cvp_config_param_data->mfc_config_info; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + apr_cvp = common.apr_q6_cvp; + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + cvp_handle = voice_get_cvp_handle(v); + memset(&cvp_set_mfc_config_cmd, 0, sizeof(cvp_set_mfc_config_cmd)); + + cvp_set_mfc_config_cmd.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_set_mfc_config_cmd.hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_set_mfc_config_cmd) - APR_HDR_SIZE); + cvp_set_mfc_config_cmd.hdr.src_svc = 0; + cvp_set_mfc_config_cmd.hdr.src_domain = APR_DOMAIN_APPS; + cvp_set_mfc_config_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_set_mfc_config_cmd.hdr.dest_svc = 0; + cvp_set_mfc_config_cmd.hdr.dest_domain = APR_DOMAIN_ADSP; + cvp_set_mfc_config_cmd.hdr.dest_port = cvp_handle; + cvp_set_mfc_config_cmd.hdr.token = 0; + cvp_set_mfc_config_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2; + cvp_set_mfc_config_cmd.cvp_set_mfc_param_v2.mem_size = + sizeof(struct vss_icommon_param_data_mfc_config_v2_t); + + cvp_config_param_data->module_id = AUDPROC_MODULE_ID_MFC; + cvp_config_param_data->param_id = + AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; + cvp_config_param_data->param_size = + sizeof(struct vss_param_mfc_config_info_t); + + mfc_config_info->num_channels = v->dev_rx.no_of_channels; + mfc_config_info->bits_per_sample = 16; + mfc_config_info->sample_rate = v->dev_rx.sample_rate; + + if (mfc_config_info->num_channels == NUM_CHANNELS_MONO) { + mfc_config_info->channel_type[0] = PCM_CHANNEL_FC; + } else if (mfc_config_info->num_channels == NUM_CHANNELS_STEREO) { + mfc_config_info->channel_type[0] = PCM_CHANNEL_FL; + mfc_config_info->channel_type[1] = PCM_CHANNEL_FR; + } else { + pr_err("%s: Unsupported num channels: %d\n", + __func__, mfc_config_info->num_channels); + ret = -EINVAL; + goto done; + } + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *)&cvp_set_mfc_config_cmd); + if (ret < 0) { + pr_err("%s: Failed to send VSS_ICOMMON_CMD_SET_PARAM_V2 %d\n", + __func__, ret); + goto done; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s] handle = %d\n", __func__, + adsp_err_get_err_str(v->async_err), cvp_handle); + ret = adsp_err_get_lnx_err_code(v->async_err); + goto done; + } + ret = 0; +done: + return ret; +} + +static int voice_send_cvp_mfc_config_cmd(struct voice_data *v) +{ + int ret = 0; + + if (common.cvp_version >= CVP_VERSION_2) { + ret = voice_send_cvp_mfc_config_v2(v); + } else { + pr_warn("%s: CVP Version not supported\n", __func__); + ret = -EINVAL; + } + + return ret; +} + +static int voice_get_avcs_version_per_service(uint32_t service_id) +{ + int ret = 0; + size_t svc_size; + struct avcs_fwk_ver_info ver_info = {{0}, NULL}; + + if (service_id == AVCS_SERVICE_ID_ALL) { + pr_err("%s: Invalid service id: %d", __func__, + AVCS_SERVICE_ID_ALL); + return -EINVAL; + } + + svc_size = sizeof(struct avs_svc_api_info); + ver_info.services = kzalloc(svc_size, GFP_KERNEL); + if (ver_info.services == NULL) + return -ENOMEM; + + ret = q6core_get_service_version(service_id, &ver_info, svc_size); + if (ret < 0) + goto done; + + ret = ver_info.services[0].api_version; + common.is_avcs_version_queried = true; +done: + kfree(ver_info.services); + return ret; +} + static int voice_setup_vocproc(struct voice_data *v) { int ret = 0; @@ -3803,6 +4101,18 @@ static int voice_setup_vocproc(struct voice_data *v) goto fail; } + if (common.is_avcs_version_queried == false) + common.cvp_version = voice_get_avcs_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_CVP_V); + + if (common.cvp_version < 0) { + pr_err("%s: Invalid CVP version %d\n", + __func__, common.cvp_version); + ret = -EINVAL; + goto fail; + } + pr_debug("%s: CVP Version %d\n", __func__, common.cvp_version); + ret = voice_send_cvp_media_fmt_info_cmd(v); if (ret < 0) { pr_err("%s: Set media format info failed err:%d\n", __func__, @@ -3817,6 +4127,15 @@ static int voice_setup_vocproc(struct voice_data *v) goto fail; } + /* Send MFC config only when the no of channels are more than 1 */ + if (v->dev_rx.no_of_channels > NUM_CHANNELS_MONO) { + ret = voice_send_cvp_mfc_config_cmd(v); + if (ret < 0) { + pr_warn("%s: Set mfc config failed err:%d\n", + __func__, ret); + } + } + voice_send_cvs_register_cal_cmd(v); voice_send_cvp_register_dev_cfg_cmd(v); voice_send_cvp_register_cal_cmd(v); @@ -3962,11 +4281,18 @@ static int voice_send_cvp_device_channels_cmd(struct voice_data *v) static int voice_send_cvp_media_fmt_info_cmd(struct voice_data *v) { - int ret; + int ret = 0; - ret = voice_send_cvp_device_channels_cmd(v); - if (ret < 0) + if (common.cvp_version < CVP_VERSION_2) + ret = voice_send_cvp_device_channels_cmd(v); + else + ret = voice_send_cvp_channel_info_cmd(v); + + if (ret < 0) { + pr_err("%s: Set channel info failed err: %d\n", __func__, + ret); goto done; + } if (voice_get_cvd_int_version(common.cvd_version) >= CVD_INT_VERSION_2_3) { @@ -3994,7 +4320,7 @@ static int voice_send_cvp_media_format_cmd(struct voice_data *v, void *apr_cvp; u16 cvp_handle; struct vss_icommon_param_data_t *media_fmt_param_data = - &cvp_set_media_format_cmd.cvp_set_param_v2.param_data; + &cvp_set_media_format_cmd.cvp_set_media_param_v2.param_data; struct vss_param_endpoint_media_format_info_t *media_fmt_info = &media_fmt_param_data->media_format_info; @@ -4032,7 +4358,7 @@ static int voice_send_cvp_media_format_cmd(struct voice_data *v, cvp_set_media_format_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2; /* Fill param data */ - cvp_set_media_format_cmd.cvp_set_param_v2.mem_size = + cvp_set_media_format_cmd.cvp_set_media_param_v2.mem_size = sizeof(struct vss_icommon_param_data_t); media_fmt_param_data->module_id = VSS_MODULE_CVD_GENERIC; media_fmt_param_data->param_size = @@ -6197,6 +6523,15 @@ int voc_enable_device(uint32_t session_id) goto done; } + /* Send MFC config only when the no of channels are > 1 */ + if (v->dev_rx.no_of_channels > NUM_CHANNELS_MONO) { + ret = voice_send_cvp_mfc_config_cmd(v); + if (ret < 0) { + pr_warn("%s: Set mfc config failed err: %d\n", + __func__, ret); + } + } + voice_send_cvp_register_dev_cfg_cmd(v); voice_send_cvp_register_cal_cmd(v); voice_send_cvp_register_vol_cal_cmd(v); @@ -7054,7 +7389,8 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv) case VSS_ICOMMON_CMD_SET_PARAM_V2: switch (data->token) { case VOC_SET_MEDIA_FORMAT_PARAM_TOKEN: - pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called by voice_send_cvp_media_format_cmd\n", + case VOC_GENERIC_SET_PARAM_TOKEN: + pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called\n", __func__); v->cvp_state = CMD_STATUS_SUCCESS; v->async_err = ptr[1]; @@ -8566,7 +8902,8 @@ static int __init voice_init(void) common.default_vol_step_val = 0; common.default_vol_ramp_duration_ms = DEFAULT_VOLUME_RAMP_DURATION; common.default_mute_ramp_duration_ms = DEFAULT_MUTE_RAMP_DURATION; - + common.cvp_version = 0; + common.is_avcs_version_queried = false; /* Initialize EC Ref media format info */ common.ec_ref_ext = false; common.ec_media_fmt_info.port_id = AFE_PORT_INVALID; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 7fb2256bff8b..66d6e475e896 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -8537,6 +8537,8 @@ struct asm_eq_params { #define VSS_ICOMMON_CMD_GET_PARAM_V2 0x0001133E #define VSS_ICOMMON_RSP_GET_PARAM 0x00011008 +#define VSS_MAX_AVCS_NUM_SERVICES 25 + /* ID of the Bass Boost module. * This module supports the following parameter IDs: * - #AUDPROC_PARAM_ID_BASS_BOOST_ENABLE @@ -9197,6 +9199,74 @@ struct asm_aptx_dec_fmt_blk_v2 { */ } __packed; +/* Q6Core Specific */ +#define AVCS_CMD_GET_FWK_VERSION (0x0001292C) +#define AVCS_CMDRSP_GET_FWK_VERSION (0x0001292D) + +#define AVCS_SERVICE_ID_ALL (0xFFFFFFFF) +#define APRV2_IDS_SERVICE_ID_ADSP_CVP_V (0xB) + +struct avcs_get_fwk_version { + /* + * Indicates the major version of the AVS build. + * This value is incremented on chipset family boundaries. + */ + uint32_t build_major_version; + + /* + * Minor version of the AVS build. + * This value represents the mainline to which the AVS build belongs. + */ + uint32_t build_minor_version; + + /* Indicates the AVS branch version to which the image belongs. */ + uint32_t build_branch_version; + + /* Indicates the AVS sub-branch or customer product line information. */ + uint32_t build_subbranch_version; + + /* Number of supported AVS services in the current build. */ + uint32_t num_services; +}; + +struct avs_svc_api_info { + /* + * APRV2 service IDs for the individual static services. + * + * @values + * - APRV2_IDS_SERVICE_ID_ADSP_CORE_V + * - APRV2_IDS_SERVICE_ID_ADSP_AFE_V + * - APRV2_IDS_SERVICE_ID_ADSP_ASM_V + * - APRV2_IDS_SERVICE_ID_ADSP_ADM_V + * - APRV2_IDS_SERVICE_ID_ADSP_MVM_V + * - APRV2_IDS_SERVICE_ID_ADSP_CVS_V + * - APRV2_IDS_SERVICE_ID_ADSP_CVP_V + * - APRV2_IDS_SERVICE_ID_ADSP_LSM_V + */ + uint32_t service_id; + + /* + * Indicates the API version of the service. + * + * Each new API update that warrants a change on the HLOS side triggers + * an increment in the version. + */ + uint32_t api_version; + + /* + * Indicates the API increments on a sub-branch (not on the mainline). + * + * API branch version numbers can increment independently on different + * sub-branches. + */ + uint32_t api_branch_version; +}; + +struct avcs_fwk_ver_info { + struct avcs_get_fwk_version avcs_fwk_version; + struct avs_svc_api_info *services; +} __packed; + /* LSM Specific */ #define VW_FEAT_DIM (39) diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index c0327ae1f77e..1f1adad031e3 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -13,6 +13,7 @@ #ifndef __Q6CORE_H__ #define __Q6CORE_H__ #include +#include @@ -21,6 +22,11 @@ bool q6core_is_adsp_ready(void); +int q6core_get_service_version(uint32_t service_id, + struct avcs_fwk_ver_info *ver_info, + size_t size); +size_t q6core_get_avcs_service_size(uint32_t service_id); + #define ADSP_CMD_SET_DTS_EAGLE_DATA_ID 0x00012919 #define DTS_EAGLE_LICENSE_ID 0x00028346 struct adsp_dts_eagle { diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index 56326b174b38..f6f0d8c80591 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -124,7 +124,7 @@ struct media_format_info { }; enum { - VOC_NO_SET_PARAM_TOKEN = 0, + VOC_GENERIC_SET_PARAM_TOKEN = 0, VOC_RTAC_SET_PARAM_TOKEN, VOC_SET_MEDIA_FORMAT_PARAM_TOKEN, VOC_SET_PARAM_TOKEN_MAX @@ -239,6 +239,19 @@ struct vss_param_endpoint_media_format_info_t { uint8_t channel_mapping[VSS_NUM_CHANNELS_MAX]; } __packed; +struct vss_param_vocproc_dev_channel_info_t { + uint32_t num_channels; + uint32_t bits_per_sample; + uint8_t channel_mapping[VSS_NUM_CHANNELS_MAX]; +} __packed; + +struct vss_param_mfc_config_info_t { + uint32_t sample_rate; + uint16_t bits_per_sample; + uint16_t num_channels; + uint16_t channel_type[VSS_NUM_CHANNELS_MAX]; +} __packed; + struct vss_icommon_param_data_t { /* Valid ID of the module. */ uint32_t module_id; @@ -260,6 +273,88 @@ struct vss_icommon_param_data_t { }; } __packed; +struct vss_icommon_param_data_channel_info_v2_t { + /* Valid ID of the module. */ + uint32_t module_id; + /* Valid ID of the parameter. */ + uint32_t param_id; + /* + * Data size of the structure relating to the param_id/module_id + * combination in uint8_t bytes. + */ + uint16_t param_size; + /* This field must be set to zero. */ + uint16_t reserved; + struct vss_param_vocproc_dev_channel_info_t channel_info; +} __packed; + +struct vss_icommon_cmd_set_param_channel_info_v2_t { + /* + * Pointer to the unique identifier for an address (physical/virtual). + * + * If the parameter data payload is within the message payload + * (in-band), set this field to 0. The parameter data begins at the + * specified data payload address. + * + * If the parameter data is out-of-band, this field is the handle to + * the physical address in the shared memory that holds the parameter + * data. + */ + uint32_t mem_handle; + /* + * Location of the parameter data payload. + * + * The payload is an array of vss_icommon_param_data_t. If the + * mem_handle is 0, this field is ignored. + */ + uint64_t mem_address; + /* Size of the parameter data payload in bytes. */ + uint32_t mem_size; + struct vss_icommon_param_data_channel_info_v2_t param_data; +} __packed; + +struct vss_icommon_param_data_mfc_config_v2_t { + /* Valid ID of the module. */ + uint32_t module_id; + /* Valid ID of the parameter. */ + uint32_t param_id; + /* + * Data size of the structure relating to the param_id/module_id + * combination in uint8_t bytes. + */ + uint16_t param_size; + /* This field must be set to zero. */ + uint16_t reserved; + struct vss_param_mfc_config_info_t mfc_config_info; +} __packed; + +struct vss_icommon_cmd_set_param_mfc_config_v2_t { + /* + * Pointer to the unique identifier for an address (physical/virtual). + * + * If the parameter data payload is within the message payload + * (in-band), set this field to 0. The parameter data begins at the + * specified data payload address. + * + * If the parameter data is out-of-band, this field is the handle to + * the physical address in the shared memory that holds the parameter + * data. + */ + + uint32_t mem_handle; + /* + * Location of the parameter data payload. + * + * The payload is an array of vss_icommon_param_data_t. If the + * mem_handle is 0, this field is ignored. + */ + uint64_t mem_address; + /* Size of the parameter data payload in bytes. */ + uint32_t mem_size; + + struct vss_icommon_param_data_mfc_config_v2_t param_data; +} __packed; + /* Payload structure for the VSS_ICOMMON_CMD_SET_PARAM_V2 command. */ struct vss_icommon_cmd_set_param_v2_t { /* @@ -674,6 +769,12 @@ struct vss_imemory_cmd_unmap_t { #define VSS_IRECORD_MODE_TX_RX_MIXING 0x00010F7B /* Select mixed Tx and Rx paths. */ +#define VSS_PARAM_VOCPROC_TX_CHANNEL_INFO 0x0001328E + +#define VSS_PARAM_VOCPROC_RX_CHANNEL_INFO 0x0001328F + +#define VSS_PARAM_VOCPROC_EC_REF_CHANNEL_INFO 0x00013290 + #define VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO 0x00013253 #define VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO 0x00013254 @@ -1485,7 +1586,18 @@ struct cvp_set_dev_channels_cmd { struct cvp_set_media_format_cmd { struct apr_hdr hdr; - struct vss_icommon_cmd_set_param_v2_t cvp_set_param_v2; + struct vss_icommon_cmd_set_param_v2_t cvp_set_media_param_v2; +} __packed; + +struct cvp_set_channel_info_cmd_v2 { + struct apr_hdr hdr; + struct vss_icommon_cmd_set_param_channel_info_v2_t + cvp_set_ch_info_param_v2; +} __packed; + +struct cvp_set_mfc_config_cmd_v2 { + struct apr_hdr hdr; + struct vss_icommon_cmd_set_param_mfc_config_v2_t cvp_set_mfc_param_v2; } __packed; struct cvp_set_vp3_data_cmd { @@ -1756,6 +1868,8 @@ struct common_data { bool srvcc_rec_flag; bool is_destroy_cvd; char cvd_version[CVD_VERSION_STRING_MAX_SIZE]; + int cvp_version; + bool is_avcs_version_queried; bool is_per_vocoder_cal_enabled; bool is_sound_focus_resp_success; bool is_source_tracking_resp_success; diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index db5a9e5a4d02..1e7ead817399 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -26,7 +26,7 @@ #include "core.h" #include "pinctrl-utils.h" -#define LPI_ADDRESS_SIZE 0xC000 +#define LPI_ADDRESS_SIZE 0x20000 #define LPI_GPIO_REG_VAL_CTL 0x00 #define LPI_GPIO_REG_DIR_CTL 0x04 @@ -109,35 +109,35 @@ static const u32 lpi_offset[] = { 0x00000000, 0x00001000, 0x00002000, - 0x00002010, 0x00003000, - 0x00003010, 0x00004000, - 0x00004010, 0x00005000, - 0x00005010, - 0x00005020, - 0x00005030, 0x00006000, - 0x00006010, 0x00007000, - 0x00007010, - 0x00005040, - 0x00005050, 0x00008000, - 0x00008010, - 0x00008020, - 0x00008030, - 0x00008040, - 0x00008050, - 0x00008060, - 0x00008070, 0x00009000, - 0x00009010, 0x0000A000, - 0x0000A010, 0x0000B000, - 0x0000B010, + 0x0000C000, + 0x0000D000, + 0x0000E000, + 0x0000F000, + 0x00010000, + 0x00011000, + 0x00012000, + 0x00013000, + 0x00014000, + 0x00015000, + 0x00016000, + 0x00017000, + 0x00018000, + 0x00019000, + 0x0001A000, + 0x0001B000, + 0x0001C000, + 0x0001D000, + 0x0001E000, + 0x0001F000, }; static const char *const lpi_gpio_functions[] = { -- GitLab From 13a66c87f44511e203182c81c993f036a4c799be Mon Sep 17 00:00:00 2001 From: Asish Bhattacharya Date: Fri, 1 Sep 2017 00:04:39 +0530 Subject: [PATCH 0013/1645] autoconf: sdm845: add conf to enable display port Add audio configurations to enable audio functionality over DisplayPort on sdm845. Change-Id: If8b5f6c25bca08a61b951cb97167e9ead7271dd3 Signed-off-by: Asish Bhattacharya --- config/sdm845auto.conf | 1 + config/sdm845autoconf.h | 1 + 2 files changed, 2 insertions(+) diff --git a/config/sdm845auto.conf b/config/sdm845auto.conf index 97f2127ce606..64ca29f9da4a 100644 --- a/config/sdm845auto.conf +++ b/config/sdm845auto.conf @@ -39,3 +39,4 @@ CONFIG_SND_SOC_MACHINE_SDM845=y CONFIG_SND_SOC_MSM_STUB=y CONFIG_WCD_DSP_GLINK=y CONFIG_MSM_AVTIMER=y +CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y diff --git a/config/sdm845autoconf.h b/config/sdm845autoconf.h index ea14533dece3..5bd70f614fa6 100644 --- a/config/sdm845autoconf.h +++ b/config/sdm845autoconf.h @@ -52,3 +52,4 @@ #define CONFIG_SND_SOC_MSM_STUB 1 #define CONFIG_WCD_DSP_GLINK 1 #define CONFIG_MSM_AVTIMER 1 +#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 -- GitLab From 24d1c0878add199218982e806ffdbfb24ad8485a Mon Sep 17 00:00:00 2001 From: Shiv Maliyappanahalli Date: Thu, 31 Aug 2017 15:26:09 -0700 Subject: [PATCH 0014/1645] asoc: codecs: add object to compile audio hdmi codec driver HDMI codec driver is not compiling as the corresponding object file is not set in the makefile. Add object file to SND_SOC_MSM_HDMI_CODEC_RX config. Change-Id: I6068f551db357e5bfa73ff5b51014347f38b925c Signed-off-by: Shiv Maliyappanahalli --- asoc/codecs/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/codecs/Makefile b/asoc/codecs/Makefile index bb3a9356e867..7c55c59b7875 100644 --- a/asoc/codecs/Makefile +++ b/asoc/codecs/Makefile @@ -42,3 +42,4 @@ wcd-core-objs := wcd9xxx-rst.o wcd9xxx-core-init.o \ wcd9335-regmap.o wcd9335-tables.o \ msm-cdc-pinctrl.o msm-cdc-supply.o obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd-core.o +obj-$(CONFIG_SND_SOC_MSM_HDMI_CODEC_RX) := msm_hdmi_codec_rx.o -- GitLab From 8b3bdea209db74decf81b861d005fa814514b45b Mon Sep 17 00:00:00 2001 From: Shiv Maliyappanahalli Date: Thu, 31 Aug 2017 18:02:20 -0700 Subject: [PATCH 0015/1645] asoc: codecs: fix compilation error for wcd codec The previous commit fb24ad8485a assigns obj-y with msm_hdmi_codec_rx.o instead of appending, thus giving compilation error as previously assigned object files are removed. Fix by appending obj-y with msm_hdmi_codec_rx.o instead of assigning. Change-Id: I7c5ea5627e2e1888e3fc0b53a6650ab64b9a29a8 Signed-off-by: Shiv Maliyappanahalli --- asoc/codecs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/Makefile b/asoc/codecs/Makefile index 7c55c59b7875..f0477f7eeb54 100644 --- a/asoc/codecs/Makefile +++ b/asoc/codecs/Makefile @@ -42,4 +42,4 @@ wcd-core-objs := wcd9xxx-rst.o wcd9xxx-core-init.o \ wcd9335-regmap.o wcd9335-tables.o \ msm-cdc-pinctrl.o msm-cdc-supply.o obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd-core.o -obj-$(CONFIG_SND_SOC_MSM_HDMI_CODEC_RX) := msm_hdmi_codec_rx.o +obj-$(CONFIG_SND_SOC_MSM_HDMI_CODEC_RX) += msm_hdmi_codec_rx.o -- GitLab From 8f7ccc2e6f1faf10b4d948c20f86c0e847050912 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 28 Aug 2017 17:35:04 +0530 Subject: [PATCH 0016/1645] audio-lnx: Add latest snapshot for audio drivers. Propagate the changes based on latest snapshot for audio kernel source tree at below cutoff of kernel msm-4.9 - (040750bfa78 - "Revert "ARM: dts: msm: Add DT node for aop-qmp clock controller on SDM845 v2"") CRs-Fixed: 2104096 Change-Id: I0927c40b3a188dbf892e7ec4c1c7810953724929 Signed-off-by: Laxminath Kasam --- asoc/codecs/msm-cdc-pinctrl.c | 10 ++++- asoc/codecs/wcd-spi.c | 4 ++ asoc/codecs/wcd9335.c | 2 +- asoc/codecs/wcd934x/wcd934x-mbhc.c | 2 +- asoc/codecs/wcd934x/wcd934x.c | 40 ++++++++++++++++-- asoc/codecs/wcd9xxx-core.c | 1 + asoc/codecs/wcd9xxx-irq.c | 27 +++++++++++- asoc/msm-compress-q6-v2.c | 20 +++++++++ asoc/msm-dai-q6-v2.c | 1 - asoc/msm-qti-pp-config.c | 41 ++++++++++++++++++ asoc/msm-qti-pp-config.h | 1 + asoc/sdm660-common.c | 6 +-- asoc/sdm660-common.h | 9 ---- asoc/sdm660-external.c | 68 ------------------------------ asoc/sdm660-external.h | 4 -- asoc/sdm845.c | 1 + dsp/audio_notifier.c | 2 +- dsp/codecs/audio_utils_aio.c | 2 + dsp/q6adm.c | 2 +- dsp/q6core.c | 2 +- dsp/q6voice.c | 2 +- include/dsp/apr_audio-v2.h | 2 +- include/dsp/q6voice.h | 2 +- ipc/apr.c | 1 + ipc/apr_tal_glink.c | 2 +- soc/soundwire.c | 11 +++-- soc/swr-wcd-ctrl.c | 24 ++++++++--- soc/swr-wcd-ctrl.h | 1 + 28 files changed, 177 insertions(+), 113 deletions(-) diff --git a/asoc/codecs/msm-cdc-pinctrl.c b/asoc/codecs/msm-cdc-pinctrl.c index c4d0ec19931d..79e322f1a277 100644 --- a/asoc/codecs/msm-cdc-pinctrl.c +++ b/asoc/codecs/msm-cdc-pinctrl.c @@ -217,8 +217,14 @@ static int msm_cdc_pinctrl_remove(struct platform_device *pdev) gpio_data = dev_get_drvdata(&pdev->dev); - if (gpio_data && gpio_data->pinctrl) - devm_pinctrl_put(gpio_data->pinctrl); + /* to free the requested gpio before exiting */ + if (gpio_data) { + if (gpio_is_valid(gpio_data->gpio)) + gpio_free(gpio_data->gpio); + + if (gpio_data->pinctrl) + devm_pinctrl_put(gpio_data->pinctrl); + } devm_kfree(&pdev->dev, gpio_data); diff --git a/asoc/codecs/wcd-spi.c b/asoc/codecs/wcd-spi.c index 957d6428427c..67cb46c74925 100644 --- a/asoc/codecs/wcd-spi.c +++ b/asoc/codecs/wcd-spi.c @@ -1374,6 +1374,10 @@ static void wcd_spi_component_unbind(struct device *dev, { struct spi_device *spi = to_spi_device(dev); struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + struct wcd_spi_debug_data *dbg_data = &wcd_spi->debug_data; + + debugfs_remove_recursive(dbg_data->dir); + dbg_data->dir = NULL; wcd_spi->m_dev = NULL; wcd_spi->m_ops = NULL; diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 2f877160bf66..21de9f5f6d6f 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -112,7 +112,7 @@ /* Convert from vout ctl to micbias voltage in mV */ #define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50) -#define TASHA_ZDET_NUM_MEASUREMENTS 150 +#define TASHA_ZDET_NUM_MEASUREMENTS 900 #define TASHA_MBHC_GET_C1(c) ((c & 0xC000) >> 14) #define TASHA_MBHC_GET_X1(x) (x & 0x3FFF) /* z value compared in milliOhm */ diff --git a/asoc/codecs/wcd934x/wcd934x-mbhc.c b/asoc/codecs/wcd934x/wcd934x-mbhc.c index 9595ba8e5c9c..4eb14de31075 100644 --- a/asoc/codecs/wcd934x/wcd934x-mbhc.c +++ b/asoc/codecs/wcd934x/wcd934x-mbhc.c @@ -44,7 +44,7 @@ /* Z floating defined in ohms */ #define TAVIL_ZDET_FLOATING_IMPEDANCE 0x0FFFFFFE -#define TAVIL_ZDET_NUM_MEASUREMENTS 150 +#define TAVIL_ZDET_NUM_MEASUREMENTS 900 #define TAVIL_MBHC_GET_C1(c) ((c & 0xC000) >> 14) #define TAVIL_MBHC_GET_X1(x) (x & 0x3FFF) /* Z value compared in milliOhm */ diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index ce0141f9f43b..66c7830e2a3f 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -128,6 +128,8 @@ static const struct snd_kcontrol_new name##_mux = \ #define WCD934X_DIG_CORE_REG_MIN WCD934X_CDC_ANC0_CLK_RESET_CTL #define WCD934X_DIG_CORE_REG_MAX 0xFFF +#define WCD934X_CHILD_DEVICES_MAX 6 + #define WCD934X_MAX_MICBIAS 4 #define DAPM_MICBIAS1_STANDALONE "MIC BIAS1 Standalone" #define DAPM_MICBIAS2_STANDALONE "MIC BIAS2 Standalone" @@ -626,6 +628,11 @@ struct tavil_priv { int power_active_ref; int sidetone_coeff_array[IIR_MAX][BAND_MAX] [WCD934X_CDC_SIDETONE_IIR_COEFF_MAX]; + + struct spi_device *spi; + struct platform_device *pdev_child_devices + [WCD934X_CHILD_DEVICES_MAX]; + int child_count; }; static const struct tavil_reg_mask_val tavil_spkr_default[] = { @@ -5105,6 +5112,13 @@ static void tavil_restore_iir_coeff(struct tavil_priv *tavil, int iir_idx) int band_idx = 0, coeff_idx = 0; struct snd_soc_codec *codec = tavil->codec; + /* + * snd_soc_write call crashes at rmmod if there is no machine + * driver and hence no codec pointer available + */ + if (!codec) + return; + for (band_idx = 0; band_idx < BAND_MAX; band_idx++) { snd_soc_write(codec, (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), @@ -9397,6 +9411,9 @@ static int tavil_soc_codec_remove(struct snd_soc_codec *codec) control = dev_get_drvdata(codec->dev->parent); devm_kfree(codec->dev, control->rx_chs); + /* slimslave deinit in wcd core looks for this value */ + control->num_rx_port = 0; + control->num_tx_port = 0; control->rx_chs = NULL; control->tx_chs = NULL; tavil_cleanup_irqs(tavil); @@ -9736,6 +9753,7 @@ static void tavil_codec_add_spi_device(struct tavil_priv *tavil, goto err_dt_parse; } + tavil->spi = spi; /* Put the reference to SPI master */ put_device(&master->dev); @@ -9782,6 +9800,7 @@ static void tavil_add_child_devices(struct work_struct *work) } platdata = &tavil->swr.plat_data; + tavil->child_count = 0; for_each_child_of_node(wcd9xxx->dev->of_node, node) { @@ -9849,6 +9868,10 @@ static void tavil_add_child_devices(struct work_struct *work) __func__); tavil->swr.ctrl_data = swr_ctrl_data; } + if (tavil->child_count < WCD934X_CHILD_DEVICES_MAX) + tavil->pdev_child_devices[tavil->child_count++] = pdev; + else + goto err_mem; } return; @@ -10076,11 +10099,24 @@ static int tavil_probe(struct platform_device *pdev) static int tavil_remove(struct platform_device *pdev) { struct tavil_priv *tavil; + int count = 0; tavil = platform_get_drvdata(pdev); if (!tavil) return -EINVAL; + /* do dsd deinit before codec->component->regmap becomes freed */ + if (tavil->dsd_config) { + tavil_dsd_deinit(tavil->dsd_config); + tavil->dsd_config = NULL; + } + + if (tavil->spi) + spi_unregister_device(tavil->spi); + for (count = 0; count < tavil->child_count && + count < WCD934X_CHILD_DEVICES_MAX; count++) + platform_device_unregister(tavil->pdev_child_devices[count]); + mutex_destroy(&tavil->micb_lock); mutex_destroy(&tavil->svs_mutex); mutex_destroy(&tavil->codec_mutex); @@ -10091,10 +10127,6 @@ static int tavil_remove(struct platform_device *pdev) snd_soc_unregister_codec(&pdev->dev); clk_put(tavil->wcd_ext_clk); wcd_resmgr_remove(tavil->resmgr); - if (tavil->dsd_config) { - tavil_dsd_deinit(tavil->dsd_config); - tavil->dsd_config = NULL; - } devm_kfree(&pdev->dev, tavil); return 0; } diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index 81408e8928ef..7f74aef8f0c0 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -592,6 +592,7 @@ static void wcd9xxx_device_exit(struct wcd9xxx *wcd9xxx) { device_init_wakeup(wcd9xxx->dev, false); wcd9xxx_irq_exit(&wcd9xxx->core_res); + mfd_remove_devices(wcd9xxx->dev); wcd9xxx_bringdown(wcd9xxx->dev); wcd9xxx_reset_low(wcd9xxx->dev); wcd9xxx_core_res_deinit(&wcd9xxx->core_res); diff --git a/asoc/codecs/wcd9xxx-irq.c b/asoc/codecs/wcd9xxx-irq.c index 65100c983f06..b192e992d1fa 100644 --- a/asoc/codecs/wcd9xxx-irq.c +++ b/asoc/codecs/wcd9xxx-irq.c @@ -52,6 +52,8 @@ static int phyirq_to_virq( struct wcd9xxx_core_resource *wcd9xxx_res, int irq); static unsigned int wcd9xxx_irq_get_upstream_irq( struct wcd9xxx_core_resource *wcd9xxx_res); +static void wcd9xxx_irq_put_downstream_irq( + struct wcd9xxx_core_resource *wcd9xxx_res); static void wcd9xxx_irq_put_upstream_irq( struct wcd9xxx_core_resource *wcd9xxx_res); static int wcd9xxx_map_irq( @@ -632,6 +634,7 @@ void wcd9xxx_irq_exit(struct wcd9xxx_core_resource *wcd9xxx_res) disable_irq_wake(wcd9xxx_res->irq); free_irq(wcd9xxx_res->irq, wcd9xxx_res); wcd9xxx_res->irq = 0; + wcd9xxx_irq_put_downstream_irq(wcd9xxx_res); wcd9xxx_irq_put_upstream_irq(wcd9xxx_res); } mutex_destroy(&wcd9xxx_res->irq_lock); @@ -754,6 +757,29 @@ static unsigned int wcd9xxx_irq_get_upstream_irq( return data->irq; } +static void wcd9xxx_irq_put_downstream_irq( + struct wcd9xxx_core_resource *wcd9xxx_res) +{ + int irq, virq, ret; + + /* + * IRQ migration hits error if the chip data and handles + * are not made NULL. make associated data and handles + * to NULL at irq_exit + */ + for (irq = 0; irq < wcd9xxx_res->num_irqs; irq++) { + virq = wcd9xxx_map_irq(wcd9xxx_res, irq); + pr_debug("%s: irq %d -> %d\n", __func__, irq, virq); + ret = irq_set_chip_data(virq, NULL); + if (ret) { + pr_err("%s: Failed to configure irq %d (%d)\n", + __func__, irq, ret); + return; + } + irq_set_chip_and_handler(virq, NULL, NULL); + } +} + static void wcd9xxx_irq_put_upstream_irq( struct wcd9xxx_core_resource *wcd9xxx_res) { @@ -821,7 +847,6 @@ static int wcd9xxx_irq_remove(struct platform_device *pdev) wmb(); irq_domain_remove(data->domain); kfree(data); - domain->host_data = NULL; return 0; } diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 89efb904ae3f..a9f28ca8ef89 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -1281,6 +1281,9 @@ static int msm_compr_configure_dsp_for_playback .step = SOFT_VOLUME_STEP, .rampingcurve = SOFT_VOLUME_CURVE_LINEAR, }; + struct snd_kcontrol *kctl; + struct snd_ctl_elem_value kctl_elem_value; + uint16_t target_asm_bit_width = 0; pr_debug("%s: stream_id %d\n", __func__, ac->stream_id); stream_index = STREAM_ARRAY_INDEX(ac->stream_id); @@ -1289,6 +1292,23 @@ static int msm_compr_configure_dsp_for_playback return -EINVAL; } + kctl = snd_soc_card_get_kcontrol(soc_prtd->card, + DSP_BIT_WIDTH_MIXER_CTL); + if (kctl) { + kctl->get(kctl, &kctl_elem_value); + target_asm_bit_width = kctl_elem_value.value.integer.value[0]; + if (target_asm_bit_width > 0) { + pr_debug("%s enforce ASM bitwidth to %d from %d\n", + __func__, + target_asm_bit_width, + bits_per_sample); + bits_per_sample = target_asm_bit_width; + } + } else { + pr_info("%s: failed to get mixer ctl for %s.\n", + __func__, DSP_BIT_WIDTH_MIXER_CTL); + } + if ((prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S24_LE) || (prtd->codec_param.codec.format == SNDRV_PCM_FORMAT_S24_3LE)) bits_per_sample = 24; diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 583934ddf6f1..6b620a5c8ed0 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -3632,7 +3632,6 @@ static int msm_dai_q6_dai_mi2s_remove(struct snd_soc_dai *dai) clear_bit(STATUS_PORT_STARTED, mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask); } - kfree(mi2s_dai_data); return 0; } diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index 2064056ab350..0d1018236aec 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -392,6 +392,7 @@ static int msm_afe_tert_mi2s_lb_vol_ctrl; static int msm_afe_quat_mi2s_lb_vol_ctrl; static int msm_afe_slimbus_7_lb_vol_ctrl; static int msm_afe_slimbus_8_lb_vol_ctrl; +static int msm_asm_bit_width; static const DECLARE_TLV_DB_LINEAR(fm_rx_vol_gain, 0, INT_RX_VOL_MAX_STEPS); static const DECLARE_TLV_DB_LINEAR(afe_lb_vol_gain, 0, INT_RX_VOL_MAX_STEPS); @@ -412,6 +413,38 @@ static int msm_qti_pp_set_fm_vol_mixer(struct snd_kcontrol *kcontrol, return 0; } +static int msm_asm_bit_width_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s get ASM bitwidth = %d\n", + __func__, msm_asm_bit_width); + + ucontrol->value.integer.value[0] = msm_asm_bit_width; + + return 0; +} + +static int msm_asm_bit_width_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 16: + msm_asm_bit_width = 16; + break; + case 24: + msm_asm_bit_width = 24; + break; + case 32: + msm_asm_bit_width = 32; + break; + default: + msm_asm_bit_width = 0; + break; + } + + return 0; +} + static int msm_qti_pp_get_pri_mi2s_lb_vol_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1132,6 +1165,11 @@ static const struct snd_kcontrol_new int_fm_vol_mixer_controls[] = { msm_qti_pp_set_quat_mi2s_fm_vol_mixer, fm_rx_vol_gain), }; +static const struct snd_kcontrol_new dsp_bit_width_controls[] = { + SOC_SINGLE_EXT(DSP_BIT_WIDTH_MIXER_CTL, SND_SOC_NOPM, 0, 0x20, + 0, msm_asm_bit_width_get, msm_asm_bit_width_put), +}; + static const struct snd_kcontrol_new pri_mi2s_lb_vol_mixer_controls[] = { SOC_SINGLE_EXT_TLV("PRI MI2S LOOPBACK Volume", SND_SOC_NOPM, 0, INT_RX_VOL_GAIN, 0, msm_qti_pp_get_pri_mi2s_lb_vol_mixer, @@ -1403,5 +1441,8 @@ void msm_qti_pp_add_controls(struct snd_soc_platform *platform) snd_soc_add_platform_controls(platform, msm_multichannel_ec_controls, ARRAY_SIZE(msm_multichannel_ec_controls)); + + snd_soc_add_platform_controls(platform, dsp_bit_width_controls, + ARRAY_SIZE(dsp_bit_width_controls)); } #endif /* CONFIG_QTI_PP */ diff --git a/asoc/msm-qti-pp-config.h b/asoc/msm-qti-pp-config.h index 14e9b10d0061..ade2f5e507ec 100644 --- a/asoc/msm-qti-pp-config.h +++ b/asoc/msm-qti-pp-config.h @@ -14,6 +14,7 @@ #define _MSM_QTI_PP_H_ #include +#define DSP_BIT_WIDTH_MIXER_CTL "ASM Bit Width" int msm_adsp_inform_mixer_ctl(struct snd_soc_pcm_runtime *rtd, uint32_t *payload); int msm_adsp_init_mixer_ctl_pp_event_queue(struct snd_soc_pcm_runtime *rtd); diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c index f73e1cdd8f60..8006472ff338 100644 --- a/asoc/sdm660-common.c +++ b/asoc/sdm660-common.c @@ -3186,8 +3186,6 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) gpio_free(pdata->hph_en0_gpio); pdata->hph_en0_gpio = 0; } - if (pdata->snd_card_val != INT_SND_CARD) - msm_ext_cdc_deinit(pdata); devm_kfree(&pdev->dev, pdata); return ret; } @@ -3199,10 +3197,8 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) if (pdata->snd_card_val == INT_SND_CARD) mutex_destroy(&pdata->cdc_int_mclk0_mutex); - else - msm_ext_cdc_deinit(pdata); - msm_free_auxdev_mem(pdev); + msm_free_auxdev_mem(pdev); gpio_free(pdata->us_euro_gpio); gpio_free(pdata->hph_en1_gpio); gpio_free(pdata->hph_en0_gpio); diff --git a/asoc/sdm660-common.h b/asoc/sdm660-common.h index 0544b968d159..c7de18f7f4db 100644 --- a/asoc/sdm660-common.h +++ b/asoc/sdm660-common.h @@ -78,14 +78,6 @@ enum { EXT_SND_CARD_TAVIL, }; -struct msm_snd_interrupt { - void __iomem *mpm_wakeup; - void __iomem *intr1_cfg_apps; - void __iomem *lpi_gpio_intr_cfg; - void __iomem *lpi_gpio_cfg; - void __iomem *lpi_gpio_inout; -}; - struct msm_asoc_mach_data { int us_euro_gpio; /* used by gpio driver API */ int hph_en1_gpio; @@ -112,7 +104,6 @@ struct msm_asoc_mach_data { struct mutex cdc_int_mclk0_mutex; struct delayed_work disable_int_mclk0_work; struct afe_clk_set digital_cdc_core_clk; - struct msm_snd_interrupt msm_snd_intr_lpi; }; int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, diff --git a/asoc/sdm660-external.c b/asoc/sdm660-external.c index dd8983c973e4..0358ad8ad9b4 100644 --- a/asoc/sdm660-external.c +++ b/asoc/sdm660-external.c @@ -35,22 +35,6 @@ #define CODEC_EXT_CLK_RATE 9600000 #define ADSP_STATE_READY_TIMEOUT_MS 3000 -#define TLMM_CENTER_MPM_WAKEUP_INT_EN_0 0x03596000 -#define LPI_GPIO_22_WAKEUP_VAL 0x00000002 - -#define TLMM_LPI_DIR_CONN_INTR1_CFG_APPS 0x0359D004 -#define LPI_GPIO_22_INTR1_CFG_VAL 0x01 -#define LPI_GPIO_22_INTR1_CFG_MASK 0x03 - -#define TLMM_LPI_GPIO_INTR_CFG1 0x0359B004 -#define LPI_GPIO_INTR_CFG1_VAL 0x00000113 - -#define TLMM_LPI_GPIO22_CFG 0x15078040 -#define LPI_GPIO22_CFG_VAL 0x0000009 - -#define TLMM_LPI_GPIO22_INOUT 0x179D1318 -#define LPI_GPIO22_INOUT_VAL 0x0020000 - #define WSA8810_NAME_1 "wsa881x.20170211" #define WSA8810_NAME_2 "wsa881x.20170212" @@ -1209,28 +1193,6 @@ static void msm_afe_clear_config(void) afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); } -static void msm_snd_interrupt_config(struct msm_asoc_mach_data *pdata) -{ - int val; - - val = ioread32(pdata->msm_snd_intr_lpi.mpm_wakeup); - val |= LPI_GPIO_22_WAKEUP_VAL; - iowrite32(val, pdata->msm_snd_intr_lpi.mpm_wakeup); - - val = ioread32(pdata->msm_snd_intr_lpi.intr1_cfg_apps); - val &= ~(LPI_GPIO_22_INTR1_CFG_MASK); - val |= LPI_GPIO_22_INTR1_CFG_VAL; - iowrite32(val, pdata->msm_snd_intr_lpi.intr1_cfg_apps); - - iowrite32(LPI_GPIO_INTR_CFG1_VAL, - pdata->msm_snd_intr_lpi.lpi_gpio_intr_cfg); - iowrite32(LPI_GPIO22_CFG_VAL, - pdata->msm_snd_intr_lpi.lpi_gpio_cfg); - val = ioread32(pdata->msm_snd_intr_lpi.lpi_gpio_inout); - val |= LPI_GPIO22_INOUT_VAL; - iowrite32(val, pdata->msm_snd_intr_lpi.lpi_gpio_inout); -} - static int msm_adsp_power_up_config(struct snd_soc_codec *codec) { int ret = 0; @@ -1262,7 +1224,6 @@ static int msm_adsp_power_up_config(struct snd_soc_codec *codec) ret = -ETIMEDOUT; goto err_fail; } - msm_snd_interrupt_config(pdata); ret = msm_afe_set_config(codec); if (ret) @@ -1883,36 +1844,7 @@ int msm_ext_cdc_init(struct platform_device *pdev, ret); ret = 0; } - pdata->msm_snd_intr_lpi.mpm_wakeup = - ioremap(TLMM_CENTER_MPM_WAKEUP_INT_EN_0, 4); - pdata->msm_snd_intr_lpi.intr1_cfg_apps = - ioremap(TLMM_LPI_DIR_CONN_INTR1_CFG_APPS, 4); - pdata->msm_snd_intr_lpi.lpi_gpio_intr_cfg = - ioremap(TLMM_LPI_GPIO_INTR_CFG1, 4); - pdata->msm_snd_intr_lpi.lpi_gpio_cfg = - ioremap(TLMM_LPI_GPIO22_CFG, 4); - pdata->msm_snd_intr_lpi.lpi_gpio_inout = - ioremap(TLMM_LPI_GPIO22_INOUT, 4); err: return ret; } EXPORT_SYMBOL(msm_ext_cdc_init); - -/** - * msm_ext_cdc_deinit - external codec machine specific deinit. - */ -void msm_ext_cdc_deinit(struct msm_asoc_mach_data *pdata) -{ - if (pdata->msm_snd_intr_lpi.mpm_wakeup) - iounmap(pdata->msm_snd_intr_lpi.mpm_wakeup); - if (pdata->msm_snd_intr_lpi.intr1_cfg_apps) - iounmap(pdata->msm_snd_intr_lpi.intr1_cfg_apps); - if (pdata->msm_snd_intr_lpi.lpi_gpio_intr_cfg) - iounmap(pdata->msm_snd_intr_lpi.lpi_gpio_intr_cfg); - if (pdata->msm_snd_intr_lpi.lpi_gpio_cfg) - iounmap(pdata->msm_snd_intr_lpi.lpi_gpio_cfg); - if (pdata->msm_snd_intr_lpi.lpi_gpio_inout) - iounmap(pdata->msm_snd_intr_lpi.lpi_gpio_inout); - -} -EXPORT_SYMBOL(msm_ext_cdc_deinit); diff --git a/asoc/sdm660-external.h b/asoc/sdm660-external.h index d53e7c7d9518..0648c014b6d2 100644 --- a/asoc/sdm660-external.h +++ b/asoc/sdm660-external.h @@ -36,7 +36,6 @@ int msm_snd_card_tasha_late_probe(struct snd_soc_card *card); int msm_ext_cdc_init(struct platform_device *, struct msm_asoc_mach_data *, struct snd_soc_card **, struct wcd_mbhc_config *); void msm_ext_register_audio_notifier(struct platform_device *pdev); -void msm_ext_cdc_deinit(struct msm_asoc_mach_data *pdata); #else inline int msm_ext_cdc_init(struct platform_device *pdev, struct msm_asoc_mach_data *pdata, @@ -49,8 +48,5 @@ inline int msm_ext_cdc_init(struct platform_device *pdev, inline void msm_ext_register_audio_notifier(struct platform_device *pdev) { } -inline void msm_ext_cdc_deinit(void) -{ -} #endif #endif diff --git a/asoc/sdm845.c b/asoc/sdm845.c index 7f29450062a9..a3654d8ecdb2 100644 --- a/asoc/sdm845.c +++ b/asoc/sdm845.c @@ -7149,6 +7149,7 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) msm_release_pinctrl(pdev); snd_soc_unregister_card(card); + audio_notifier_deregister("sdm845"); return 0; } diff --git a/dsp/audio_notifier.c b/dsp/audio_notifier.c index bcb5f9d98378..a1b5d1e6f8bd 100644 --- a/dsp/audio_notifier.c +++ b/dsp/audio_notifier.c @@ -510,7 +510,7 @@ int audio_notifier_deregister(char *client_name) int ret = 0; int ret2; struct list_head *ptr, *next; - struct client_data *client_data; + struct client_data *client_data = NULL; if (client_name == NULL) { pr_err("%s: client_name is NULL\n", __func__); diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c index c67a24d7aa15..e8f22e79f8cb 100644 --- a/dsp/codecs/audio_utils_aio.c +++ b/dsp/codecs/audio_utils_aio.c @@ -1067,6 +1067,8 @@ static int audio_aio_async_write(struct q6audio_aio *audio, struct audio_client *ac; struct audio_aio_write_param param; + memset(¶m, 0, sizeof(param)); + if (!audio || !buf_node) { pr_err("%s NULL pointer audio=[0x%pK], buf_node=[0x%pK]\n", __func__, audio, buf_node); diff --git a/dsp/q6adm.c b/dsp/q6adm.c index bc217237be91..461e155d4176 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2438,7 +2438,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, flags = ADM_LEGACY_DEVICE_SESSION; } - if ((topology == VPM_TX_SM_ECNS_COPP_TOPOLOGY) || + if ((topology == VPM_TX_SM_ECNS_V2_COPP_TOPOLOGY) || (topology == VPM_TX_DM_FLUENCE_COPP_TOPOLOGY) || (topology == VPM_TX_DM_RFECNS_COPP_TOPOLOGY)) rate = 16000; diff --git a/dsp/q6core.c b/dsp/q6core.c index 181a800cbf1f..8d82704055fc 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -373,7 +373,7 @@ int q6core_get_service_version(uint32_t service_id, svc_size = q6core_get_avcs_service_size(service_id); if (svc_size != size) { - pr_err("%s: Expected size: %ld, Provided size: %ld", + pr_err("%s: Expected size: %zu, Provided size: %zu\n", __func__, svc_size, size); return -EINVAL; } diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 28e50d9f55eb..7cd340f96177 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -8038,7 +8038,7 @@ uint32_t voice_get_topology(uint32_t topology_idx) if (topology_idx == CVP_VOC_RX_TOPOLOGY_CAL) { topology = VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT; } else if (topology_idx == CVP_VOC_TX_TOPOLOGY_CAL) { - topology = VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS; + topology = VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS_V2; } else { pr_err("%s: cal index %x is invalid!\n", __func__, topology_idx); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 66d6e475e896..2256b7b4d9b8 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -3666,7 +3666,7 @@ struct afe_lpass_core_shared_clk_config_command { #define DEFAULT_POPP_TOPOLOGY 0x00010BE4 #define COMPRESSED_PASSTHROUGH_DEFAULT_TOPOLOGY 0x0001076B #define COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY 0x00010774 -#define VPM_TX_SM_ECNS_COPP_TOPOLOGY 0x00010F71 +#define VPM_TX_SM_ECNS_V2_COPP_TOPOLOGY 0x00010F89 #define VPM_TX_DM_FLUENCE_COPP_TOPOLOGY 0x00010F72 #define VPM_TX_QMIC_FLUENCE_COPP_TOPOLOGY 0x00010F75 #define VPM_TX_DM_RFECNS_COPP_TOPOLOGY 0x00010F86 diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index f6f0d8c80591..7818707b5aa9 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -1218,7 +1218,7 @@ struct vss_istream_cmd_set_packet_exchange_mode_t { #define VSS_IVOCPROC_CMD_DEREGISTER_DYNAMIC_CALIBRATION_DATA 0x0001307C #define VSS_IVOCPROC_TOPOLOGY_ID_NONE 0x00010F70 -#define VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS 0x00010F71 +#define VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS_V2 0x00010F89 #define VSS_IVOCPROC_TOPOLOGY_ID_TX_DM_FLUENCE 0x00010F72 #define VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT 0x00010F77 diff --git a/ipc/apr.c b/ipc/apr.c index bec513ad270e..8fc62f406cb7 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -820,6 +820,7 @@ static void dispatch_event(unsigned long code, uint16_t proc) uint16_t clnt; int i, j; + memset(&data, 0, sizeof(data)); data.opcode = RESET_EVENTS; data.reset_event = code; diff --git a/ipc/apr_tal_glink.c b/ipc/apr_tal_glink.c index f99f9ed22e7a..7de7ddafdb54 100644 --- a/ipc/apr_tal_glink.c +++ b/ipc/apr_tal_glink.c @@ -239,7 +239,7 @@ int apr_tal_rx_intents_config(struct apr_svc_ch_dev *apr_ch, int num_of_intents, uint32_t size) { int i; - int rc; + int rc = 0; if (!apr_ch || !num_of_intents || !size) { pr_err("%s: Invalid parameter\n", __func__); diff --git a/soc/soundwire.c b/soc/soundwire.c index 210de34e6666..6095c0a82e94 100644 --- a/soc/soundwire.c +++ b/soc/soundwire.c @@ -79,11 +79,16 @@ void swr_remove_device(struct swr_device *swr_dev) { struct swr_device *swr_dev_loop, *safe; + /* + * master still has reference to all nodes and deletes + * at platform_unregister, so need to init the deleted + * entry + */ list_for_each_entry_safe(swr_dev_loop, safe, &swr_dev->master->devices, dev_list) { if (swr_dev == swr_dev_loop) - list_del(&swr_dev_loop->dev_list); + list_del_init(&swr_dev_loop->dev_list); } } EXPORT_SYMBOL(swr_remove_device); @@ -789,9 +794,7 @@ static void swr_unregister_device(struct swr_device *swr) static void swr_master_release(struct device *dev) { - struct swr_master *master = to_swr_master(dev); - - kfree(master); + /* kfree of master done at swrm_remove of device */ } #define swr_master_attr_gr NULL diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c index e7d7c797dd9e..bb78372aa9e5 100644 --- a/soc/swr-wcd-ctrl.c +++ b/soc/swr-wcd-ctrl.c @@ -396,11 +396,17 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) return -EINVAL; if (enable) { - swrm->clk(swrm->handle, true); - swrm->state = SWR_MSTR_UP; - } else { + swrm->clk_ref_count++; + if (swrm->clk_ref_count == 1) { + swrm->clk(swrm->handle, true); + swrm->state = SWR_MSTR_UP; + } + } else if (--swrm->clk_ref_count == 0) { swrm->clk(swrm->handle, false); swrm->state = SWR_MSTR_DOWN; + } else if (swrm->clk_ref_count < 0) { + pr_err("%s: swrm clk count mismatch\n", __func__); + swrm->clk_ref_count = 0; } return 0; } @@ -1170,7 +1176,10 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) u8 devnum = 0; int ret = IRQ_HANDLED; - pm_runtime_get_sync(&swrm->pdev->dev); + mutex_lock(&swrm->reslock); + swrm_clk_request(swrm, true); + mutex_unlock(&swrm->reslock); + intr_sts = swrm->read(swrm->handle, SWRM_INTERRUPT_STATUS); intr_sts &= SWRM_INTERRUPT_STATUS_RMSK; for (i = 0; i < SWRM_INTERRUPT_MAX; i++) { @@ -1258,8 +1267,10 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) break; } } - pm_runtime_mark_last_busy(&swrm->pdev->dev); - pm_runtime_put_autosuspend(&swrm->pdev->dev); + + mutex_lock(&swrm->reslock); + swrm_clk_request(swrm, false); + mutex_unlock(&swrm->reslock); return ret; } @@ -1447,6 +1458,7 @@ static int swrm_probe(struct platform_device *pdev) swrm->wcmd_id = 0; swrm->slave_status = 0; swrm->num_rx_chs = 0; + swrm->clk_ref_count = 0; swrm->state = SWR_MSTR_RESUME; init_completion(&swrm->reset); init_completion(&swrm->broadcast); diff --git a/soc/swr-wcd-ctrl.h b/soc/swr-wcd-ctrl.h index 5a4f79b4ecf6..52a60a3c6087 100644 --- a/soc/swr-wcd-ctrl.h +++ b/soc/swr-wcd-ctrl.h @@ -78,6 +78,7 @@ struct swr_mstr_ctrl { struct device *dev; struct resource *supplies; struct clk *mclk; + int clk_ref_count; struct completion reset; struct completion broadcast; struct mutex mlock; -- GitLab From 540284901837726119cd0a1f672787587fffae80 Mon Sep 17 00:00:00 2001 From: Preetam Singh Ranawat Date: Mon, 4 Sep 2017 11:42:26 +0530 Subject: [PATCH 0017/1645] dsp: add CELT encoder support Add CELT encoder support to enable audio broadcast over split a2dp. Change-Id: If0d927913c5e525ff1cebf857323ab70be2122a1 Signed-off-by: Preetam Singh Ranawat --- asoc/msm-dai-q6-v2.c | 15 +++++++++-- dsp/q6afe.c | 3 ++- include/dsp/apr_audio-v2.h | 51 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 6b620a5c8ed0..25eb2ecff35a 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -49,6 +49,7 @@ enum { ENC_FMT_AAC_V2 = ASM_MEDIA_FMT_AAC_V2, ENC_FMT_APTX = ASM_MEDIA_FMT_APTX, ENC_FMT_APTX_HD = ASM_MEDIA_FMT_APTX_HD, + ENC_FMT_CELT = ASM_MEDIA_FMT_CELT, }; enum { @@ -2146,7 +2147,12 @@ static int msm_dai_q6_afe_enc_cfg_get(struct snd_kcontrol *kcontrol, case ENC_FMT_APTX_HD: memcpy(ucontrol->value.bytes.data + format_size, &dai_data->enc_config.data, - sizeof(struct asm_aac_enc_cfg_v2_t)); + sizeof(struct asm_custom_enc_cfg_t)); + break; + case ENC_FMT_CELT: + memcpy(ucontrol->value.bytes.data + format_size, + &dai_data->enc_config.data, + sizeof(struct asm_celt_enc_cfg_t)); break; default: pr_debug("%s: unknown format = %d\n", @@ -2190,7 +2196,12 @@ static int msm_dai_q6_afe_enc_cfg_put(struct snd_kcontrol *kcontrol, case ENC_FMT_APTX_HD: memcpy(&dai_data->enc_config.data, ucontrol->value.bytes.data + format_size, - sizeof(struct asm_custom_enc_cfg_aptx_t)); + sizeof(struct asm_custom_enc_cfg_t)); + break; + case ENC_FMT_CELT: + memcpy(&dai_data->enc_config.data, + ucontrol->value.bytes.data + format_size, + sizeof(struct asm_celt_enc_cfg_t)); break; default: pr_debug("%s: Ignore enc config for unknown format = %d\n", diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 78be555eb8eb..a6041b377525 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2824,7 +2824,8 @@ static int q6afe_send_enc_config(u16 port_id, pr_debug("%s:update DSP for enc format = %d\n", __func__, format); if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 && - format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD) { + format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD && + format != ASM_MEDIA_FMT_CELT) { pr_err("%s:Unsuppported format Ignore AFE config\n", __func__); return 0; } diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 2256b7b4d9b8..3d9a56cdfefd 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -3252,7 +3252,7 @@ struct asm_aac_enc_cfg_v2_t { #define PCM_CHANNEL_R 2 #define PCM_CHANNEL_C 3 -struct asm_custom_enc_cfg_aptx_t { +struct asm_custom_enc_cfg_t { uint32_t sample_rate; /* Mono or stereo */ uint16_t num_channels; @@ -3263,6 +3263,52 @@ struct asm_custom_enc_cfg_aptx_t { uint8_t channel_mapping[8]; uint32_t custom_size; } __packed; +#define ASM_MEDIA_FMT_CELT 0x00013221 +struct asm_celt_specific_enc_cfg_t { + /* + * Bit rate used for encoding. + * This is used to calculate the upper threshold + * for bytes per frame if vbr_flag is 1. + * Or else, this will be used as a regular constant + * bit rate for encoder output. + * @Range : 32000 to 1536000 + * @Default: 128 + */ + uint32_t bit_rate; + /* + * Frame size used for encoding. + * @Range : 64, 128, 256, 512 + * @Default: 256 + */ + uint16_t frame_size; + /* + * complexity of algorithm. + * @Range : 0-10 + * @Default: 3 + */ + uint16_t complexity; + /* + * Switch variable for prediction feature. + * Used to choose between the level of interframe + * predictions allowed while encoding. + * @Range: + * 0: Independent Frames. + * 1: Short Term interframe prediction allowed. + * 2: Long term prediction allowed. + * @Default: 2 + */ + uint16_t prediction_mode; + /* + * Variable Bit Rate flag. + * @Default: 0 + */ + uint16_t vbr_flag; +} __packed; + +struct asm_celt_enc_cfg_t { + struct asm_custom_enc_cfg_t custom_config; + struct asm_celt_specific_enc_cfg_t celt_specific_config; +} __packed; struct afe_enc_fmt_id_param_t { /* @@ -3331,7 +3377,8 @@ struct afe_port_media_type_t { union afe_enc_config_data { struct asm_sbc_enc_cfg_t sbc_config; struct asm_aac_enc_cfg_v2_t aac_config; - struct asm_custom_enc_cfg_aptx_t aptx_config; + struct asm_custom_enc_cfg_t custom_config; + struct asm_celt_enc_cfg_t celt_config; }; struct afe_enc_config { -- GitLab From 5eaced6d700c7aa2f33f81583ac87b328bece566 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 7 Sep 2017 10:31:26 -0700 Subject: [PATCH 0018/1645] ASoC: codecs: wcd934x: Fix slimbus overflow Remove MCLK_CONTROL and FS_CNT_CONTROL from the list of volatile registers so that regmap sync happens for these registers when coming out of power collapse. These clock registers need to be synced otherwise codec state is not restored correctly after power collapse. CRs-fixed: 2053506 Change-Id: I9b5385a357f9ad05ad085603410704e916e3985e Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd934x/wcd934x-regmap.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/asoc/codecs/wcd934x/wcd934x-regmap.c b/asoc/codecs/wcd934x/wcd934x-regmap.c index 7f648fe1c938..ff18bd80a971 100644 --- a/asoc/codecs/wcd934x/wcd934x-regmap.c +++ b/asoc/codecs/wcd934x/wcd934x-regmap.c @@ -1932,12 +1932,10 @@ static bool wcd934x_is_volatile_register(struct device *dev, unsigned int reg) case WCD934X_ANA_BIAS: case WCD934X_ANA_BUCK_CTL: case WCD934X_ANA_RCO: - case WCD934X_CDC_CLK_RST_CTRL_MCLK_CONTROL: case WCD934X_CODEC_RPM_CLK_GATE: case WCD934X_BIAS_VBG_FINE_ADJ: case WCD934X_CODEC_CPR_SVS_CX_VDD: case WCD934X_CODEC_CPR_SVS2_CX_VDD: - case WCD934X_CDC_CLK_RST_CTRL_FS_CNT_CONTROL: return true; } -- GitLab From e908ba91db76c49884b2bf3dceca3849ab4043c0 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Thu, 31 Aug 2017 18:36:00 -0700 Subject: [PATCH 0019/1645] ASoC: wcd-spi: initialize local variable 'status' Variable 'status' is used without initialization. Initialize it to the right value. Change-Id: I7f43d8905d8192e5f308e9fd00a52eb531f2f698 Signed-off-by: Xiaoyu Ye --- asoc/codecs/wcd-spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/wcd-spi.c b/asoc/codecs/wcd-spi.c index 67cb46c74925..072a7538ef1d 100644 --- a/asoc/codecs/wcd-spi.c +++ b/asoc/codecs/wcd-spi.c @@ -522,7 +522,7 @@ static int wcd_spi_cmd_rdsr(struct spi_device *spi, struct spi_transfer *tx_xfer = &wcd_spi->xfer2[0]; struct spi_transfer *rx_xfer = &wcd_spi->xfer2[1]; u8 rdsr_cmd; - u32 status; + u32 status = 0; int ret; rdsr_cmd = WCD_SPI_CMD_RDSR; -- GitLab From 72863154a8fc83dc326d06f3d2862f1a45443050 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Wed, 6 Sep 2017 15:47:35 -0700 Subject: [PATCH 0020/1645] ASoC: add SLIM_7_TX routing for Multimedia10 Add missing FE to BE link for Multimedia10. Change-Id: Ibf9a80c942107b1f68b5954b21f87d4f7494b1fc Signed-off-by: Vikram Panduranga --- asoc/msm-pcm-routing-v2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 8e3fe895d98d..29dfade94f0f 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -7281,6 +7281,9 @@ static const struct snd_kcontrol_new mmul10_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), -- GitLab From 98526effb3dd34bf6112fdcd01c2bf7b3a2517fe Mon Sep 17 00:00:00 2001 From: yidongh Date: Tue, 5 Sep 2017 17:57:55 +0800 Subject: [PATCH 0021/1645] asoc: initialize L/R/C gain for both mono/stereo playback When there's a dynamic channel change from mono to stereo, volume burst is observed because center channel gain for stereo is not initialized. Initialize center channel gain for both mono and stereo playback. CRs-Fixed: 2095081 Change-Id: I02254b5696a17e2792ea26a2265ab01326f5cf9e Signed-off-by: Yidong Huang --- asoc/msm-compress-q6-v2.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index a9f28ca8ef89..cd9c28195b87 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -388,12 +388,9 @@ static int msm_compr_set_volume(struct snd_compr_stream *cstream, } else { gain_list[0] = volume_l; gain_list[1] = volume_r; - /* force sending FR/FL/FC volume for mono */ - if (prtd->num_channels == 1) { - gain_list[2] = volume_l; - num_channels = 3; - use_default = true; - } + gain_list[2] = volume_l; + num_channels = 3; + use_default = true; rc = q6asm_set_multich_gain(prtd->audio_client, num_channels, gain_list, chmap, use_default); } -- GitLab From da488bf1ff3eafdb5a6155480c4442df1fe47cd4 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 30 Aug 2017 22:16:25 +0530 Subject: [PATCH 0022/1645] asoc: remove unused audio files Update to remove unused driver files from techpack audio. CRs-Fixed: 2105780 Change-Id: I1dcf1c6e75838863eee0556f7919068dfc47772d Signed-off-by: Laxminath Kasam --- asoc/Makefile | 4 - asoc/codecs/Makefile | 19 +- asoc/codecs/wcd934x/Makefile | 3 +- asoc/codecs/wsa881x-analog.c | 1446 --------- asoc/codecs/wsa881x-analog.h | 50 - asoc/codecs/wsa881x-irq.c | 610 ---- asoc/codecs/wsa881x-irq.h | 82 - asoc/codecs/wsa881x-registers-analog.h | 206 -- asoc/codecs/wsa881x-regmap-analog.c | 499 --- asoc/codecs/wsa881x-tables-analog.c | 171 - asoc/msm-audio-pinctrl.c | 316 -- asoc/msm-audio-pinctrl.h | 43 - asoc/msm8996.c | 4007 ------------------------ asoc/sdm660-external.c | 1 - 14 files changed, 8 insertions(+), 7449 deletions(-) delete mode 100644 asoc/codecs/wsa881x-analog.c delete mode 100644 asoc/codecs/wsa881x-analog.h delete mode 100644 asoc/codecs/wsa881x-irq.c delete mode 100644 asoc/codecs/wsa881x-irq.h delete mode 100644 asoc/codecs/wsa881x-registers-analog.h delete mode 100644 asoc/codecs/wsa881x-regmap-analog.c delete mode 100644 asoc/codecs/wsa881x-tables-analog.c delete mode 100644 asoc/msm-audio-pinctrl.c delete mode 100644 asoc/msm-audio-pinctrl.h delete mode 100644 asoc/msm8996.c diff --git a/asoc/Makefile b/asoc/Makefile index 3fccff6726ba..cc28148dcf3e 100644 --- a/asoc/Makefile +++ b/asoc/Makefile @@ -11,10 +11,6 @@ obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o snd-soc-cpe-objs := msm-cpe-lsm.o obj-$(CONFIG_SND_SOC_CPE) += snd-soc-cpe.o -# for MSM8996 sound card driver -snd-soc-msm8996-objs := msm8996.o -obj-$(CONFIG_SND_SOC_MSM8996) += snd-soc-msm8996.o - # for MSM8998 sound card driver snd-soc-msm8998-objs := msm8998.o obj-$(CONFIG_SND_SOC_MACHINE_MSM8998) += snd-soc-msm8998.o diff --git a/asoc/codecs/Makefile b/asoc/codecs/Makefile index f0477f7eeb54..9b02c8a51cd7 100644 --- a/asoc/codecs/Makefile +++ b/asoc/codecs/Makefile @@ -1,4 +1,6 @@ -snd-soc-wcd9xxx-v2-objs := wcd9xxx-common-v2.o wcd9xxx-resmgr-v2.o wcdcal-hwdep.o wcd9xxx-soc-init.o +snd-soc-wcd9xxx-objs := wcd9xxx-common-v2.o wcd9xxx-resmgr-v2.o \ + wcdcal-hwdep.o wcd9xxx-soc-init.o wcd-dsp-utils.o \ + wcd-dsp-mgr.o audio-ext-clk-up.o snd-soc-wcd-cpe-objs := wcd_cpe_services.o wcd_cpe_core.o snd-soc-wsa881x-objs := wsa881x.o wsa881x-tables.o wsa881x-regmap.o wsa881x-temp-sensor.o snd-soc-wcd-mbhc-objs := wcd-mbhc-v2.o @@ -8,8 +10,6 @@ endif ifneq (,$(filter $(CONFIG_SND_SOC_WCD_MBHC_ADC),y m)) snd-soc-wcd-mbhc-objs += wcd-mbhc-adc.o endif -snd-soc-wcd-dsp-utils-objs := wcd-dsp-utils.o -snd-soc-wcd-dsp-mgr-objs := wcd-dsp-mgr.o snd-soc-wcd-spi-objs := wcd-spi.o snd-soc-wcd9335-objs := wcd9335.o snd-soc-wcd-cpe-objs := wcd_cpe_services.o wcd_cpe_core.o @@ -19,18 +19,10 @@ obj-$(CONFIG_SND_SOC_WCD_CPE) += snd-soc-wcd-cpe.o obj-$(CONFIG_SND_SOC_WCD934X) += wcd934x/ obj-$(CONFIG_SND_SOC_SDM660_CDC) += sdm660_cdc/ obj-$(CONFIG_SND_SOC_MSM_SDW) += msm_sdw/ -ifeq ($(CONFIG_COMMON_CLK_MSM), y) - obj-$(CONFIG_AUDIO_EXT_CLK) += audio-ext-clk.o -endif -ifeq ($(CONFIG_COMMON_CLK_QCOM), y) - obj-$(CONFIG_AUDIO_EXT_CLK) += audio-ext-clk-up.o -endif -obj-$(CONFIG_SND_SOC_WCD9XXX_V2) += snd-soc-wcd9xxx-v2.o -obj-$(CONFIG_SND_SOC_WCD_CPE) += snd-soc-wcd-cpe.o +obj-$(CONFIG_SND_SOC_WCD9XXX_V2) += snd-soc-wcd9xxx.o obj-$(CONFIG_SND_SOC_WCD_MBHC) += snd-soc-wcd-mbhc.o obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o -obj-$(CONFIG_SND_SOC_WCD_DSP_MGR) += snd-soc-wcd-dsp-mgr.o snd-soc-wcd-dsp-utils.o obj-$(CONFIG_SND_SOC_WCD_SPI) += snd-soc-wcd-spi.o snd-soc-msm-stub-objs := msm_stub.o @@ -41,5 +33,8 @@ wcd-core-objs := wcd9xxx-rst.o wcd9xxx-core-init.o \ wcd9xxx-slimslave.o wcd9xxx-utils.o \ wcd9335-regmap.o wcd9335-tables.o \ msm-cdc-pinctrl.o msm-cdc-supply.o +wcd-core-objs += wcd934x/wcd934x-regmap.o +wcd-core-objs += wcd934x/wcd934x-tables.o + obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd-core.o obj-$(CONFIG_SND_SOC_MSM_HDMI_CODEC_RX) += msm_hdmi_codec_rx.o diff --git a/asoc/codecs/wcd934x/Makefile b/asoc/codecs/wcd934x/Makefile index c4db59b0e9d7..12781f6d4556 100644 --- a/asoc/codecs/wcd934x/Makefile +++ b/asoc/codecs/wcd934x/Makefile @@ -2,6 +2,5 @@ # Makefile for wcd934x codec driver. # snd-soc-wcd934x-objs := wcd934x.o wcd934x-dsp-cntl.o \ - wcd934x-mbhc.o wcd934x-dsd.o \ - wcd934x-regmap.o wcd934x-tables.o + wcd934x-mbhc.o wcd934x-dsd.o obj-$(CONFIG_SND_SOC_WCD934X) += snd-soc-wcd934x.o diff --git a/asoc/codecs/wsa881x-analog.c b/asoc/codecs/wsa881x-analog.c deleted file mode 100644 index 4de962497765..000000000000 --- a/asoc/codecs/wsa881x-analog.c +++ /dev/null @@ -1,1446 +0,0 @@ -/* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "wsa881x-analog.h" -#include "wsa881x-temp-sensor.h" -#include "../msm/msm-audio-pinctrl.h" - -#define SPK_GAIN_12DB 4 -#define WIDGET_NAME_MAX_SIZE 80 - -/* - * Private data Structure for wsa881x. All parameters related to - * WSA881X codec needs to be defined here. - */ -struct wsa881x_pdata { - struct regmap *regmap[2]; - struct i2c_client *client[2]; - struct snd_soc_codec *codec; - - /* track wsa881x status during probe */ - int status; - bool boost_enable; - bool visense_enable; - int spk_pa_gain; - struct i2c_msg xfer_msg[2]; - struct mutex xfer_lock; - bool regmap_flag; - bool wsa_active; - int index; - int (*enable_mclk)(struct snd_soc_card *, bool); - struct wsa881x_tz_priv tz_pdata; - int bg_cnt; - int clk_cnt; - int enable_cnt; - int version; - struct mutex bg_lock; - struct mutex res_lock; - struct delayed_work ocp_ctl_work; -}; - -enum { - WSA881X_STATUS_PROBING, - WSA881X_STATUS_I2C, -}; - -#define WSA881X_OCP_CTL_TIMER_SEC 2 -#define WSA881X_OCP_CTL_TEMP_CELSIUS 25 -#define WSA881X_OCP_CTL_POLL_TIMER_SEC 60 - -static int wsa881x_ocp_poll_timer_sec = WSA881X_OCP_CTL_POLL_TIMER_SEC; -module_param(wsa881x_ocp_poll_timer_sec, int, 0664); -MODULE_PARM_DESC(wsa881x_ocp_poll_timer_sec, "timer for ocp ctl polling"); - -static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec, - bool enable); - -const char *wsa_tz_names[] = {"wsa881x.0e", "wsa881x.0f"}; - -struct wsa881x_pdata wsa_pdata[MAX_WSA881X_DEVICE]; - -static bool pinctrl_init; - -static int wsa881x_populate_dt_pdata(struct device *dev); -static int wsa881x_reset(struct wsa881x_pdata *pdata, bool enable); -static int wsa881x_startup(struct wsa881x_pdata *pdata); -static int wsa881x_shutdown(struct wsa881x_pdata *pdata); - -static int delay_array_msec[] = {10, 20, 30, 40, 50}; - -static int wsa881x_i2c_addr = -1; -static int wsa881x_probing_count; -static int wsa881x_presence_count; - -static const char * const wsa881x_spk_pa_gain_text[] = { -"POS_13P5_DB", "POS_12_DB", "POS_10P5_DB", "POS_9_DB", "POS_7P5_DB", -"POS_6_DB", "POS_4P5_DB", "POS_3_DB", "POS_1P5_DB", "POS_0_DB"}; - -static const struct soc_enum wsa881x_spk_pa_gain_enum[] = { - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa881x_spk_pa_gain_text), - wsa881x_spk_pa_gain_text), -}; - -static int wsa881x_spk_pa_gain_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = wsa881x->spk_pa_gain; - - dev_dbg(codec->dev, "%s: spk_pa_gain = %ld\n", __func__, - ucontrol->value.integer.value[0]); - - return 0; -} - -static int wsa881x_spk_pa_gain_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - if (ucontrol->value.integer.value[0] < 0 || - ucontrol->value.integer.value[0] > 0xC) { - dev_err(codec->dev, "%s: Unsupported gain val %ld\n", - __func__, ucontrol->value.integer.value[0]); - return -EINVAL; - } - wsa881x->spk_pa_gain = ucontrol->value.integer.value[0]; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - return 0; -} - -static int get_i2c_wsa881x_device_index(u16 reg) -{ - u16 mask = 0x0f00; - int value = 0; - - value = ((reg & mask) >> 8) & 0x000f; - - switch (value) { - case 0: - return 0; - case 1: - return 1; - default: - break; - } - return -EINVAL; -} - -static int wsa881x_i2c_write_device(struct wsa881x_pdata *wsa881x, - unsigned int reg, unsigned int val) -{ - int i = 0, rc = 0; - int wsa881x_index; - struct i2c_msg *msg; - int ret = 0; - int bytes = 1; - u8 reg_addr = 0; - u8 data[bytes + 1]; - - wsa881x_index = get_i2c_wsa881x_device_index(reg); - if (wsa881x_index < 0) { - pr_err("%s:invalid register to write\n", __func__); - return -EINVAL; - } - if (wsa881x->regmap_flag) { - rc = regmap_write(wsa881x->regmap[wsa881x_index], reg, val); - for (i = 0; rc && i < ARRAY_SIZE(delay_array_msec); i++) { - pr_err("Failed writing reg=%u - retry(%d)\n", reg, i); - /* retry after delay of increasing order */ - msleep(delay_array_msec[i]); - rc = regmap_write(wsa881x->regmap[wsa881x_index], - reg, val); - } - if (rc) - pr_err("Failed writing reg=%u rc=%d\n", reg, rc); - else - pr_err("write success register = %x val = %x\n", - reg, val); - } else { - reg_addr = (u8)reg; - msg = &wsa881x->xfer_msg[0]; - msg->addr = wsa881x->client[wsa881x_index]->addr; - msg->len = bytes + 1; - msg->flags = 0; - data[0] = reg; - data[1] = (u8)val; - msg->buf = data; - ret = i2c_transfer(wsa881x->client[wsa881x_index]->adapter, - wsa881x->xfer_msg, 1); - /* Try again if the write fails */ - if (ret != 1) { - ret = i2c_transfer( - wsa881x->client[wsa881x_index]->adapter, - wsa881x->xfer_msg, 1); - if (ret != 1) { - pr_err("failed to write the device\n"); - return ret; - } - } - pr_debug("write success reg = %x val = %x\n", reg, data[1]); - } - return rc; -} - -static int wsa881x_i2c_read_device(struct wsa881x_pdata *wsa881x, - unsigned int reg) -{ - int wsa881x_index; - int i = 0, rc = 0; - unsigned int val; - struct i2c_msg *msg; - int ret = 0; - u8 reg_addr = 0; - u8 dest[5]; - - wsa881x_index = get_i2c_wsa881x_device_index(reg); - if (wsa881x_index < 0) { - pr_err("%s:invalid register to read\n", __func__); - return -EINVAL; - } - if (wsa881x->regmap_flag) { - rc = regmap_read(wsa881x->regmap[wsa881x_index], reg, &val); - for (i = 0; rc && i < ARRAY_SIZE(delay_array_msec); i++) { - pr_err("Failed reading reg=%u - retry(%d)\n", reg, i); - /* retry after delay of increasing order */ - msleep(delay_array_msec[i]); - rc = regmap_read(wsa881x->regmap[wsa881x_index], - reg, &val); - } - if (rc) { - pr_err("Failed reading reg=%u rc=%d\n", reg, rc); - return rc; - } - pr_debug("read success reg = %x val = %x\n", - reg, val); - } else { - reg_addr = (u8)reg; - msg = &wsa881x->xfer_msg[0]; - msg->addr = wsa881x->client[wsa881x_index]->addr; - msg->len = 1; - msg->flags = 0; - msg->buf = ®_addr; - - msg = &wsa881x->xfer_msg[1]; - msg->addr = wsa881x->client[wsa881x_index]->addr; - msg->len = 1; - msg->flags = I2C_M_RD; - msg->buf = dest; - ret = i2c_transfer(wsa881x->client[wsa881x_index]->adapter, - wsa881x->xfer_msg, 2); - - /* Try again if read fails first time */ - if (ret != 2) { - ret = i2c_transfer( - wsa881x->client[wsa881x_index]->adapter, - wsa881x->xfer_msg, 2); - if (ret != 2) { - pr_err("failed to read wsa register:%d\n", - reg); - return ret; - } - } - val = dest[0]; - } - return val; -} - -static unsigned int wsa881x_i2c_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - struct wsa881x_pdata *wsa881x; - unsigned int val; - int ret; - - if (codec == NULL) { - pr_err("%s: invalid codec\n", __func__); - return -EINVAL; - } - wsa881x = snd_soc_codec_get_drvdata(codec); - if (!wsa881x->wsa_active) { - ret = snd_soc_cache_read(codec, reg, &val); - if (ret >= 0) - return val; - dev_err(codec->dev, - "cache read failed for reg: 0x%x ret: %d\n", - reg, ret); - return ret; - } - return wsa881x_i2c_read_device(wsa881x, reg); -} - -static int wsa881x_i2c_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int val) -{ - struct wsa881x_pdata *wsa881x; - int ret = 0; - - if (codec == NULL) { - pr_err("%s: invalid codec\n", __func__); - return -EINVAL; - } - wsa881x = snd_soc_codec_get_drvdata(codec); - if (!wsa881x->wsa_active) { - ret = snd_soc_cache_write(codec, reg, val); - if (ret != 0) - dev_err(codec->dev, "cache write to %x failed: %d\n", - reg, ret); - return ret; - } - return wsa881x_i2c_write_device(wsa881x, reg, val); -} - -static int wsa881x_i2c_get_client_index(struct i2c_client *client, - int *wsa881x_index) -{ - int ret = 0; - - switch (client->addr) { - case WSA881X_I2C_SPK0_SLAVE0_ADDR: - case WSA881X_I2C_SPK0_SLAVE1_ADDR: - *wsa881x_index = WSA881X_I2C_SPK0_SLAVE0; - break; - case WSA881X_I2C_SPK1_SLAVE0_ADDR: - case WSA881X_I2C_SPK1_SLAVE1_ADDR: - *wsa881x_index = WSA881X_I2C_SPK1_SLAVE0; - break; - default: - ret = -EINVAL; - break; - } - return ret; -} - -static int wsa881x_boost_ctrl(struct snd_soc_codec *codec, bool enable) -{ - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - pr_debug("%s: enable:%d\n", __func__, enable); - if (enable) { - if (!WSA881X_IS_2_0(wsa881x->version)) { - snd_soc_update_bits(codec, WSA881X_ANA_CTL, - 0x01, 0x01); - snd_soc_update_bits(codec, WSA881X_ANA_CTL, - 0x04, 0x04); - snd_soc_update_bits(codec, WSA881X_BOOST_PS_CTL, - 0x40, 0x00); - snd_soc_update_bits(codec, WSA881X_BOOST_PRESET_OUT1, - 0xF0, 0xB0); - snd_soc_update_bits(codec, WSA881X_BOOST_ZX_CTL, - 0x20, 0x00); - snd_soc_update_bits(codec, WSA881X_BOOST_EN_CTL, - 0x80, 0x80); - } else { - snd_soc_update_bits(codec, WSA881X_BOOST_LOOP_STABILITY, - 0x03, 0x03); - snd_soc_update_bits(codec, WSA881X_BOOST_MISC2_CTL, - 0xFF, 0x14); - snd_soc_update_bits(codec, WSA881X_BOOST_START_CTL, - 0x80, 0x80); - snd_soc_update_bits(codec, WSA881X_BOOST_START_CTL, - 0x03, 0x00); - snd_soc_update_bits(codec, - WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, - 0x0C, 0x04); - snd_soc_update_bits(codec, - WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, - 0x03, 0x00); - snd_soc_update_bits(codec, WSA881X_BOOST_PRESET_OUT1, - 0xF0, 0x70); - snd_soc_update_bits(codec, WSA881X_ANA_CTL, 0x03, 0x01); - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, - 0x08, 0x08); - snd_soc_update_bits(codec, WSA881X_ANA_CTL, 0x04, 0x04); - snd_soc_update_bits(codec, WSA881X_BOOST_CURRENT_LIMIT, - 0x0F, 0x08); - snd_soc_update_bits(codec, WSA881X_BOOST_EN_CTL, - 0x80, 0x80); - } - /* For WSA8810, start-up time is 1500us as per qcrg sequence */ - usleep_range(1500, 1510); - } else { - /* ENSURE: Class-D amp is shutdown. CLK is still on */ - snd_soc_update_bits(codec, WSA881X_BOOST_EN_CTL, 0x80, 0x00); - /* boost settle time is 1500us as per qcrg sequence */ - usleep_range(1500, 1510); - } - return 0; -} - -static int wsa881x_visense_txfe_ctrl(struct snd_soc_codec *codec, bool enable, - u8 isense1_gain, u8 isense2_gain, - u8 vsense_gain) -{ - u8 value = 0; - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - pr_debug("%s: enable:%d\n", __func__, enable); - - if (enable) { - if (WSA881X_IS_2_0(wsa881x->version)) { - snd_soc_update_bits(codec, WSA881X_OTP_REG_28, - 0x3F, 0x3A); - snd_soc_update_bits(codec, WSA881X_BONGO_RESRV_REG1, - 0xFF, 0xB2); - snd_soc_update_bits(codec, WSA881X_BONGO_RESRV_REG2, - 0xFF, 0x05); - } - snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_VSENSE_VCM, - 0x08, 0x00); - if (WSA881X_IS_2_0(wsa881x->version)) { - snd_soc_update_bits(codec, WSA881X_SPKR_PROT_ATEST2, - 0x1C, 0x04); - } else { - snd_soc_update_bits(codec, WSA881X_SPKR_PROT_ATEST2, - 0x08, 0x08); - snd_soc_update_bits(codec, WSA881X_SPKR_PROT_ATEST2, - 0x02, 0x02); - } - value = ((isense2_gain << 6) | (isense1_gain << 4) | - (vsense_gain << 3)); - snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_GAIN, - 0xF8, value); - snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_GAIN, - 0x01, 0x01); - } else { - if (WSA881X_IS_2_0(wsa881x->version)) - snd_soc_update_bits(codec, - WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x10, 0x10); - else - snd_soc_update_bits(codec, - WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x08, 0x08); - /* - * 200us sleep is needed after visense txfe disable as per - * HW requirement. - */ - usleep_range(200, 210); - - snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_GAIN, - 0x01, 0x00); - } - return 0; -} - -static int wsa881x_visense_adc_ctrl(struct snd_soc_codec *codec, bool enable) -{ - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - pr_debug("%s: enable:%d\n", __func__, enable); - if (enable) { - if (!WSA881X_IS_2_0(wsa881x->version)) - snd_soc_update_bits(codec, WSA881X_ADC_SEL_IBIAS, - 0x70, 0x40); - snd_soc_update_bits(codec, WSA881X_ADC_EN_SEL_IBIAS, - 0x07, 0x04); - snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_V, 0x80, 0x80); - snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_I, 0x80, 0x80); - } else { - /* Ensure: Speaker Protection has been stopped */ - snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_V, 0x80, 0x00); - snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_I, 0x80, 0x00); - } - - return 0; -} - -static void wsa881x_bandgap_ctrl(struct snd_soc_codec *codec, bool enable) -{ - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: enable:%d, bg_count:%d\n", __func__, - enable, wsa881x->bg_cnt); - mutex_lock(&wsa881x->bg_lock); - if (enable) { - ++wsa881x->bg_cnt; - if (wsa881x->bg_cnt == 1) { - snd_soc_update_bits(codec, WSA881X_TEMP_OP, - 0x08, 0x08); - /* 400usec sleep is needed as per HW requirement */ - usleep_range(400, 410); - snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x04); - } - } else { - --wsa881x->bg_cnt; - if (wsa881x->bg_cnt <= 0) { - WARN_ON(wsa881x->bg_cnt < 0); - wsa881x->bg_cnt = 0; - snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x00); - snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x08, 0x00); - } - } - mutex_unlock(&wsa881x->bg_lock); -} - -static void wsa881x_clk_ctrl(struct snd_soc_codec *codec, bool enable) -{ - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s:ss enable:%d, clk_count:%d\n", __func__, - enable, wsa881x->clk_cnt); - mutex_lock(&wsa881x->res_lock); - if (enable) { - ++wsa881x->clk_cnt; - if (wsa881x->clk_cnt == 1) { - snd_soc_write(codec, WSA881X_CDC_RST_CTL, 0x02); - snd_soc_write(codec, WSA881X_CDC_RST_CTL, 0x03); - snd_soc_write(codec, WSA881X_CLOCK_CONFIG, 0x01); - snd_soc_write(codec, WSA881X_CDC_DIG_CLK_CTL, 0x01); - snd_soc_write(codec, WSA881X_CDC_ANA_CLK_CTL, 0x01); - } - } else { - --wsa881x->clk_cnt; - if (wsa881x->clk_cnt <= 0) { - WARN_ON(wsa881x->clk_cnt < 0); - wsa881x->clk_cnt = 0; - snd_soc_write(codec, WSA881X_CDC_ANA_CLK_CTL, 0x00); - snd_soc_write(codec, WSA881X_CDC_DIG_CLK_CTL, 0x00); - if (WSA881X_IS_2_0(wsa881x->version)) - snd_soc_update_bits(codec, - WSA881X_CDC_TOP_CLK_CTL, 0x01, 0x00); - } - } - mutex_unlock(&wsa881x->res_lock); -} - -static int wsa881x_rdac_ctrl(struct snd_soc_codec *codec, bool enable) -{ - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - pr_debug("%s: enable:%d\n", __func__, enable); - if (enable) { - snd_soc_update_bits(codec, WSA881X_ANA_CTL, 0x08, 0x00); - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, 0x08, 0x08); - snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x20, 0x00); - snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x40, 0x40); - snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x80, 0x80); - if (WSA881X_IS_2_0(wsa881x->version)) { - snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_CAL, - 0x01, 0x01); - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, - 0x30, 0x30); - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, - 0x0C, 0x00); - } - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, 0xF0, 0x40); - snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL1, 0x01, 0x01); - } else { - /* Ensure class-D amp is off */ - snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x80, 0x00); - } - return 0; -} - -static int wsa881x_spkr_pa_ctrl(struct snd_soc_codec *codec, bool enable) -{ - int ret = 0; - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - pr_debug("%s: enable:%d\n", __func__, enable); - if (enable) { - /* - * Ensure: Boost is enabled and stable, Analog input is up - * and outputting silence - */ - if (!WSA881X_IS_2_0(wsa881x->version)) { - snd_soc_update_bits(codec, WSA881X_ADC_EN_DET_TEST_I, - 0xFF, 0x01); - snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_V, - 0x02, 0x02); - snd_soc_update_bits(codec, WSA881X_ADC_EN_DET_TEST_V, - 0xFF, 0x10); - snd_soc_update_bits(codec, WSA881X_SPKR_PWRSTG_DBG, - 0xA0, 0xA0); - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, - 0x80, 0x80); - usleep_range(700, 710); - snd_soc_update_bits(codec, WSA881X_SPKR_PWRSTG_DBG, - 0x00, 0x00); - snd_soc_update_bits(codec, WSA881X_ADC_EN_DET_TEST_V, - 0xFF, 0x00); - snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_V, - 0x02, 0x00); - snd_soc_update_bits(codec, WSA881X_ADC_EN_DET_TEST_I, - 0xFF, 0x00); - } else - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, - 0x80, 0x80); - /* add 1000us delay as per qcrg */ - usleep_range(1000, 1010); - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, 0x01, 0x01); - if (WSA881X_IS_2_0(wsa881x->version)) - snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_CAL, - 0x01, 0x00); - usleep_range(1000, 1010); - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, 0xF0, - (wsa881x->spk_pa_gain << 4)); - if (wsa881x->visense_enable) { - ret = msm_gpioset_activate(CLIENT_WSA_BONGO_1, - "wsa_vi"); - if (ret) { - pr_err("%s: gpio set cannot be activated %s\n", - __func__, "wsa_vi"); - return ret; - } - wsa881x_visense_txfe_ctrl(codec, true, - 0x00, 0x01, 0x00); - wsa881x_visense_adc_ctrl(codec, true); - } - } else { - /* - * Ensure: Boost is still on, Stream from Analog input and - * Speaker Protection has been stopped and input is at 0V - */ - if (WSA881X_IS_2_0(wsa881x->version)) { - snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_CAL, - 0x01, 0x01); - usleep_range(1000, 1010); - snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_CAL, - 0x01, 0x00); - msleep(20); - snd_soc_update_bits(codec, WSA881X_ANA_CTL, - 0x03, 0x00); - usleep_range(200, 210); - } - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, 0x80, 0x00); - } - return 0; -} - -static int wsa881x_get_boost(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = wsa881x->boost_enable; - return 0; -} - -static int wsa881x_set_boost(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - int value = ucontrol->value.integer.value[0]; - - dev_dbg(codec->dev, "%s: Boost enable current %d, new %d\n", - __func__, wsa881x->boost_enable, value); - wsa881x->boost_enable = value; - return 0; -} - -static int wsa881x_get_visense(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = wsa881x->visense_enable; - return 0; -} - -static int wsa881x_set_visense(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - int value = ucontrol->value.integer.value[0]; - - dev_dbg(codec->dev, "%s: VIsense enable current %d, new %d\n", - __func__, wsa881x->visense_enable, value); - wsa881x->visense_enable = value; - return 0; -} - -static const struct snd_kcontrol_new wsa881x_snd_controls[] = { - SOC_SINGLE_EXT("BOOST Switch", SND_SOC_NOPM, 0, 1, 0, - wsa881x_get_boost, wsa881x_set_boost), - - SOC_SINGLE_EXT("VISENSE Switch", SND_SOC_NOPM, 0, 1, 0, - wsa881x_get_visense, wsa881x_set_visense), - - SOC_ENUM_EXT("WSA_SPK PA Gain", wsa881x_spk_pa_gain_enum[0], - wsa881x_spk_pa_gain_get, wsa881x_spk_pa_gain_put), -}; - -static const char * const rdac_text[] = { - "ZERO", "Switch", -}; - -static const struct soc_enum rdac_enum = - SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(rdac_text), rdac_text); - -static const struct snd_kcontrol_new rdac_mux[] = { - SOC_DAPM_ENUM("RDAC", rdac_enum) -}; - -static int wsa881x_rdac_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - int ret = 0; - - dev_dbg(codec->dev, "%s: %s %d boost %d visense %d\n", - __func__, w->name, event, - wsa881x->boost_enable, wsa881x->visense_enable); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - ret = wsa881x_startup(wsa881x); - if (ret) { - pr_err("%s: wsa startup failed ret: %d", __func__, ret); - return ret; - } - wsa881x_clk_ctrl(codec, true); - snd_soc_update_bits(codec, WSA881X_SPKR_DAC_CTL, 0x02, 0x02); - if (!WSA881X_IS_2_0(wsa881x->version)) - snd_soc_update_bits(codec, WSA881X_BIAS_REF_CTRL, - 0x0F, 0x08); - wsa881x_bandgap_ctrl(codec, true); - if (!WSA881X_IS_2_0(wsa881x->version)) - snd_soc_update_bits(codec, WSA881X_SPKR_BBM_CTL, - 0x02, 0x02); - snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL1, 0xC0, 0x80); - snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL1, 0x06, 0x06); - if (!WSA881X_IS_2_0(wsa881x->version)) { - snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL2, - 0x04, 0x04); - snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_INT, - 0x09, 0x09); - } - snd_soc_update_bits(codec, WSA881X_SPKR_PA_INT, 0xF0, 0x20); - if (WSA881X_IS_2_0(wsa881x->version)) - snd_soc_update_bits(codec, WSA881X_SPKR_PA_INT, - 0x0E, 0x0E); - if (wsa881x->boost_enable) - wsa881x_boost_ctrl(codec, true); - break; - case SND_SOC_DAPM_POST_PMU: - wsa881x_rdac_ctrl(codec, true); - break; - case SND_SOC_DAPM_PRE_PMD: - wsa881x_rdac_ctrl(codec, false); - if (wsa881x->visense_enable) { - wsa881x_visense_adc_ctrl(codec, false); - wsa881x_visense_txfe_ctrl(codec, false, - 0x00, 0x01, 0x00); - ret = msm_gpioset_suspend(CLIENT_WSA_BONGO_1, - "wsa_vi"); - if (ret) { - pr_err("%s: gpio set cannot be suspended %s\n", - __func__, "wsa_vi"); - return ret; - } - } - break; - case SND_SOC_DAPM_POST_PMD: - if (wsa881x->boost_enable) - wsa881x_boost_ctrl(codec, false); - wsa881x_clk_ctrl(codec, false); - wsa881x_bandgap_ctrl(codec, false); - ret = wsa881x_shutdown(wsa881x); - if (ret < 0) { - pr_err("%s: wsa shutdown failed ret: %d", - __func__, ret); - return ret; - } - break; - default: - pr_err("%s: invalid event:%d\n", __func__, event); - return -EINVAL; - } - return 0; -} - -static void wsa881x_ocp_ctl_work(struct work_struct *work) -{ - struct wsa881x_pdata *wsa881x; - struct delayed_work *dwork; - struct snd_soc_codec *codec; - unsigned long temp_val; - - dwork = to_delayed_work(work); - wsa881x = container_of(dwork, struct wsa881x_pdata, ocp_ctl_work); - - if (!wsa881x) - return; - - codec = wsa881x->codec; - wsa881x_get_temp(wsa881x->tz_pdata.tz_dev, &temp_val); - dev_dbg(codec->dev, " temp = %ld\n", temp_val); - - if (temp_val <= WSA881X_OCP_CTL_TEMP_CELSIUS) - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0x00); - else - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0); - - schedule_delayed_work(&wsa881x->ocp_ctl_work, - msecs_to_jiffies(wsa881x_ocp_poll_timer_sec * 1000)); -} - -static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - pr_debug("%s: %s %d\n", __func__, w->name, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0x80); - break; - case SND_SOC_DAPM_POST_PMU: - wsa881x_spkr_pa_ctrl(codec, true); - schedule_delayed_work(&wsa881x->ocp_ctl_work, - msecs_to_jiffies(WSA881X_OCP_CTL_TIMER_SEC * 1000)); - break; - case SND_SOC_DAPM_PRE_PMD: - wsa881x_spkr_pa_ctrl(codec, false); - break; - case SND_SOC_DAPM_POST_PMD: - cancel_delayed_work_sync(&wsa881x->ocp_ctl_work); - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0); - break; - default: - pr_err("%s: invalid event:%d\n", __func__, event); - return -EINVAL; - } - return 0; -} - - -static const struct snd_soc_dapm_widget wsa881x_dapm_widgets[] = { - SND_SOC_DAPM_INPUT("WSA_IN"), - - SND_SOC_DAPM_DAC_E("RDAC Analog", NULL, SND_SOC_NOPM, 0, 0, - wsa881x_rdac_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX("WSA_RDAC", SND_SOC_NOPM, 0, 0, - rdac_mux), - - SND_SOC_DAPM_PGA_S("WSA_SPKR PGA", 1, SND_SOC_NOPM, 0, 0, - wsa881x_spkr_pa_event, - SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | - SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_OUTPUT("WSA_SPKR"), -}; - -static const struct snd_soc_dapm_route wsa881x_audio_map[] = { - {"WSA_RDAC", "Switch", "WSA_IN"}, - {"RDAC Analog", NULL, "WSA_RDAC"}, - {"WSA_SPKR PGA", NULL, "RDAC Analog"}, - {"WSA_SPKR", NULL, "WSA_SPKR PGA"}, -}; - - -static int wsa881x_startup(struct wsa881x_pdata *pdata) -{ - int ret = 0; - struct snd_soc_codec *codec = pdata->codec; - struct snd_soc_card *card = codec->component.card; - - pr_debug("%s(): wsa startup, enable_cnt:%d\n", __func__, - pdata->enable_cnt); - - if (pdata->enable_cnt++ > 0) - return 0; - ret = msm_gpioset_activate(CLIENT_WSA_BONGO_1, "wsa_clk"); - if (ret) { - pr_err("%s: gpio set cannot be activated %s\n", - __func__, "wsa_clk"); - return ret; - } - if (pdata->enable_mclk) { - ret = pdata->enable_mclk(card, true); - if (ret < 0) { - dev_err_ratelimited(codec->dev, - "%s: mclk enable failed %d\n", - __func__, ret); - return ret; - } - } - ret = wsa881x_reset(pdata, true); - return ret; -} - -static int wsa881x_shutdown(struct wsa881x_pdata *pdata) -{ - int ret = 0, reg; - struct snd_soc_codec *codec = pdata->codec; - struct snd_soc_card *card = codec->component.card; - - pr_debug("%s(): wsa shutdown, enable_cnt:%d\n", __func__, - pdata->enable_cnt); - if (--pdata->enable_cnt > 0) - return 0; - ret = wsa881x_reset(pdata, false); - if (ret) { - pr_err("%s: wsa reset failed suspend %d\n", - __func__, ret); - return ret; - } - - if (pdata->enable_mclk) { - ret = pdata->enable_mclk(card, false); - if (ret < 0) { - pr_err("%s: mclk disable failed %d\n", - __func__, ret); - return ret; - } - } - - ret = msm_gpioset_suspend(CLIENT_WSA_BONGO_1, "wsa_clk"); - if (ret) { - pr_err("%s: gpio set cannot be suspended %s\n", - __func__, "wsa_clk"); - return ret; - } - if (pdata->codec) { - /* restore defaults to cache */ - for (reg = 0; reg < ARRAY_SIZE(wsa881x_ana_reg_defaults); - reg++) { - if (wsa881x_ana_reg_readable[reg]) - snd_soc_cache_write(pdata->codec, - wsa881x_ana_reg_defaults[reg].reg, - wsa881x_ana_reg_defaults[reg].def); - } - } - return 0; -} - -static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec, - bool enable) -{ - int ret = 0; - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - if (enable) { - ret = wsa881x_startup(wsa881x); - if (ret < 0) { - dev_err_ratelimited(codec->dev, - "%s: failed to startup\n", __func__); - return ret; - } - } - wsa881x_clk_ctrl(codec, enable); - wsa881x_bandgap_ctrl(codec, enable); - if (!enable) { - ret = wsa881x_shutdown(wsa881x); - if (ret < 0) - dev_err_ratelimited(codec->dev, - "%s: failed to shutdown\n", __func__); - } - return ret; -} - -static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec, - struct wsa_temp_register *wsa_temp_reg) -{ - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - int ret = 0; - - if (!wsa881x) { - dev_err(codec->dev, "%s: wsa881x is NULL\n", __func__); - return -EINVAL; - } - ret = wsa881x_resource_acquire(codec, true); - if (ret) { - dev_err_ratelimited(codec->dev, - "%s: resource acquire fail\n", __func__); - return ret; - } - - if (WSA881X_IS_2_0(wsa881x->version)) { - snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x00); - wsa_temp_reg->dmeas_msb = snd_soc_read(codec, WSA881X_TEMP_MSB); - wsa_temp_reg->dmeas_lsb = snd_soc_read(codec, WSA881X_TEMP_LSB); - snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x01); - } else { - wsa_temp_reg->dmeas_msb = snd_soc_read(codec, - WSA881X_TEMP_DOUT_MSB); - wsa_temp_reg->dmeas_lsb = snd_soc_read(codec, - WSA881X_TEMP_DOUT_LSB); - } - wsa_temp_reg->d1_msb = snd_soc_read(codec, WSA881X_OTP_REG_1); - wsa_temp_reg->d1_lsb = snd_soc_read(codec, WSA881X_OTP_REG_2); - wsa_temp_reg->d2_msb = snd_soc_read(codec, WSA881X_OTP_REG_3); - wsa_temp_reg->d2_lsb = snd_soc_read(codec, WSA881X_OTP_REG_4); - - ret = wsa881x_resource_acquire(codec, false); - if (ret) - dev_err_ratelimited(codec->dev, - "%s: resource release fail\n", __func__); - - return ret; -} - -static int wsa881x_probe(struct snd_soc_codec *codec) -{ - struct i2c_client *client; - int ret = 0; - int wsa881x_index = 0; - struct snd_soc_dapm_context *dapm = &codec->dapm; - char *widget_name = NULL; - struct snd_soc_card *card = codec->component.card; - struct snd_soc_codec_conf *codec_conf = card->codec_conf; - - client = dev_get_drvdata(codec->dev); - ret = wsa881x_i2c_get_client_index(client, &wsa881x_index); - if (ret != 0) { - dev_err(&client->dev, "%s: I2C get codec I2C\n" - "client failed\n", __func__); - return ret; - } - mutex_init(&wsa_pdata[wsa881x_index].bg_lock); - mutex_init(&wsa_pdata[wsa881x_index].res_lock); - snprintf(wsa_pdata[wsa881x_index].tz_pdata.name, 100, "%s", - wsa_tz_names[wsa881x_index]); - wsa_pdata[wsa881x_index].codec = codec; - wsa_pdata[wsa881x_index].spk_pa_gain = SPK_GAIN_12DB; - wsa_pdata[wsa881x_index].codec = codec; - wsa_pdata[wsa881x_index].tz_pdata.codec = codec; - wsa_pdata[wsa881x_index].tz_pdata.wsa_temp_reg_read = - wsa881x_temp_reg_read; - snd_soc_codec_set_drvdata(codec, &wsa_pdata[wsa881x_index]); - wsa881x_init_thermal(&wsa_pdata[wsa881x_index].tz_pdata); - INIT_DELAYED_WORK(&wsa_pdata[wsa881x_index].ocp_ctl_work, - wsa881x_ocp_ctl_work); - - if (codec_conf->name_prefix) { - widget_name = kcalloc(WIDGET_NAME_MAX_SIZE, sizeof(char), - GFP_KERNEL); - if (!widget_name) - return -ENOMEM; - - snprintf(widget_name, WIDGET_NAME_MAX_SIZE, - "%s WSA_SPKR", codec_conf->name_prefix); - snd_soc_dapm_ignore_suspend(dapm, widget_name); - snprintf(widget_name, WIDGET_NAME_MAX_SIZE, - "%s WSA_IN", codec_conf->name_prefix); - snd_soc_dapm_ignore_suspend(dapm, widget_name); - kfree(widget_name); - } else { - snd_soc_dapm_ignore_suspend(dapm, "WSA_SPKR"); - snd_soc_dapm_ignore_suspend(dapm, "WSA_IN"); - } - - snd_soc_dapm_sync(dapm); - return 0; -} - -static int wsa881x_remove(struct snd_soc_codec *codec) -{ - struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); - - if (wsa881x->tz_pdata.tz_dev) - wsa881x_deinit_thermal(wsa881x->tz_pdata.tz_dev); - - mutex_destroy(&wsa881x->bg_lock); - mutex_destroy(&wsa881x->res_lock); - return 0; -} - -static struct snd_soc_codec_driver soc_codec_dev_wsa881x = { - .probe = wsa881x_probe, - .remove = wsa881x_remove, - - .read = wsa881x_i2c_read, - .write = wsa881x_i2c_write, - - .reg_cache_size = WSA881X_CACHE_SIZE, - .reg_cache_default = wsa881x_ana_reg_defaults, - .reg_word_size = 1, - - .component_driver = { - .controls = wsa881x_snd_controls, - .num_controls = ARRAY_SIZE(wsa881x_snd_controls), - .dapm_widgets = wsa881x_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(wsa881x_dapm_widgets), - .dapm_routes = wsa881x_audio_map, - .num_dapm_routes = ARRAY_SIZE(wsa881x_audio_map), - }, -}; - -static int wsa881x_reset(struct wsa881x_pdata *pdata, bool enable) -{ - int ret = 0; - - /* - * shutdown the GPIOs WSA_EN, WSA_MCLK, regulators - * and restore defaults in soc cache when shutdown. - * Enable regulators, GPIOs WSA_MCLK, WSA_EN when powerup. - */ - if (enable) { - if (pdata->wsa_active) - return 0; - ret = msm_gpioset_activate(CLIENT_WSA_BONGO_1, "wsa_reset"); - if (ret) { - pr_err("%s: gpio set cannot be activated %s\n", - __func__, "wsa_reset"); - return ret; - } - ret = msm_gpioset_suspend(CLIENT_WSA_BONGO_1, "wsa_reset"); - if (ret) { - pr_err("%s: gpio set cannot be suspended(powerup) %s\n", - __func__, "wsa_reset"); - return ret; - } - ret = msm_gpioset_activate(CLIENT_WSA_BONGO_1, "wsa_reset"); - if (ret) { - pr_err("%s: gpio set cannot be activated %s\n", - __func__, "wsa_reset"); - return ret; - } - pdata->wsa_active = true; - } else { - if (!pdata->wsa_active) - return 0; - ret = msm_gpioset_suspend(CLIENT_WSA_BONGO_1, "wsa_reset"); - if (ret) { - pr_err("%s: gpio set cannot be suspended %s\n", - __func__, "wsa_reset"); - return ret; - } - pdata->wsa_active = false; - } - return ret; -} - -int wsa881x_get_client_index(void) -{ - return wsa881x_i2c_addr; -} -EXPORT_SYMBOL(wsa881x_get_client_index); - -int wsa881x_get_probing_count(void) -{ - return wsa881x_probing_count; -} -EXPORT_SYMBOL(wsa881x_get_probing_count); - -int wsa881x_get_presence_count(void) -{ - return wsa881x_presence_count; -} -EXPORT_SYMBOL(wsa881x_get_presence_count); - -int wsa881x_set_mclk_callback( - int (*enable_mclk_callback)(struct snd_soc_card *, bool)) -{ - int i; - - for (i = 0; i < MAX_WSA881X_DEVICE; i++) { - if (wsa_pdata[i].status == WSA881X_STATUS_I2C) - wsa_pdata[i].enable_mclk = enable_mclk_callback; - } - return 0; -} -EXPORT_SYMBOL(wsa881x_set_mclk_callback); - -static int check_wsa881x_presence(struct i2c_client *client) -{ - int ret = 0; - int wsa881x_index = 0; - - ret = wsa881x_i2c_get_client_index(client, &wsa881x_index); - if (ret != 0) { - dev_err(&client->dev, "%s: I2C get codec I2C\n" - "client failed\n", __func__); - return ret; - } - ret = wsa881x_i2c_read_device(&wsa_pdata[wsa881x_index], - WSA881X_CDC_RST_CTL); - if (ret < 0) { - dev_err(&client->dev, "failed to read wsa881x with addr %x\n", - client->addr); - return ret; - } - ret = wsa881x_i2c_write_device(&wsa_pdata[wsa881x_index], - WSA881X_CDC_RST_CTL, 0x01); - if (ret < 0) { - dev_err(&client->dev, "failed write addr %x reg:0x5 val:0x1\n", - client->addr); - return ret; - } - /* allow 20ms before trigger next write to verify WSA881x presence */ - msleep(20); - ret = wsa881x_i2c_write_device(&wsa_pdata[wsa881x_index], - WSA881X_CDC_RST_CTL, 0x00); - if (ret < 0) { - dev_err(&client->dev, "failed write addr %x reg:0x5 val:0x0\n", - client->addr); - return ret; - } - return ret; -} - -static int wsa881x_populate_dt_pdata(struct device *dev) -{ - int ret = 0; - - /* reading the gpio configurations from dtsi file */ - if (!pinctrl_init) { - ret = msm_gpioset_initialize(CLIENT_WSA_BONGO_1, dev); - if (ret < 0) { - dev_err(dev, - "%s: error reading dtsi files%d\n", __func__, ret); - goto err; - } - pinctrl_init = true; - } -err: - return ret; -} - -static int wsa881x_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int ret = 0; - int wsa881x_index = 0; - struct wsa881x_pdata *pdata = NULL; - - ret = wsa881x_i2c_get_client_index(client, &wsa881x_index); - if (ret != 0) { - dev_err(&client->dev, "%s: I2C get codec I2C\n" - "client failed\n", __func__); - return ret; - } - - pdata = &wsa_pdata[wsa881x_index]; - - if ((client->addr == WSA881X_I2C_SPK0_SLAVE1_ADDR || - client->addr == WSA881X_I2C_SPK1_SLAVE1_ADDR) && - (pdata->status == WSA881X_STATUS_PROBING)) - return ret; - - if (pdata->status == WSA881X_STATUS_I2C) { - dev_dbg(&client->dev, "%s:probe for other slaves\n" - "devices of codec I2C slave Addr = %x\n", - __func__, client->addr); - - dev_dbg(&client->dev, "%s:wsa_idx = %d SLAVE = %d\n", - __func__, wsa881x_index, WSA881X_ANALOG_SLAVE); - pdata->regmap[WSA881X_ANALOG_SLAVE] = - devm_regmap_init_i2c( - client, - &wsa881x_ana_regmap_config[WSA881X_ANALOG_SLAVE]); - regcache_cache_bypass(pdata->regmap[WSA881X_ANALOG_SLAVE], - true); - if (IS_ERR(pdata->regmap[WSA881X_ANALOG_SLAVE])) { - ret = PTR_ERR(pdata->regmap[WSA881X_ANALOG_SLAVE]); - dev_err(&client->dev, - "%s: regmap_init failed %d\n", - __func__, ret); - } - client->dev.platform_data = pdata; - i2c_set_clientdata(client, pdata); - pdata->client[WSA881X_ANALOG_SLAVE] = client; - if (pdata->version == WSA881X_2_0) - wsa881x_update_regmap_2_0( - pdata->regmap[WSA881X_ANALOG_SLAVE], - WSA881X_ANALOG_SLAVE); - - return ret; - } else if (pdata->status == WSA881X_STATUS_PROBING) { - pdata->index = wsa881x_index; - if (client->dev.of_node) { - dev_dbg(&client->dev, "%s:Platform data\n" - "from device tree\n", __func__); - ret = wsa881x_populate_dt_pdata(&client->dev); - if (ret < 0) { - dev_err(&client->dev, - "%s: Fail to obtain pdata from device tree\n", - __func__); - ret = -EINVAL; - goto err; - } - client->dev.platform_data = pdata; - } else { - dev_dbg(&client->dev, "%s:Platform data from\n" - "board file\n", __func__); - pdata = client->dev.platform_data; - } - if (!pdata) { - dev_dbg(&client->dev, "no platform data?\n"); - ret = -EINVAL; - goto err; - } - i2c_set_clientdata(client, pdata); - dev_set_drvdata(&client->dev, client); - - pdata->regmap[WSA881X_DIGITAL_SLAVE] = - devm_regmap_init_i2c( - client, - &wsa881x_ana_regmap_config[WSA881X_DIGITAL_SLAVE]); - regcache_cache_bypass(pdata->regmap[WSA881X_DIGITAL_SLAVE], - true); - if (IS_ERR(pdata->regmap[WSA881X_DIGITAL_SLAVE])) { - ret = PTR_ERR(pdata->regmap[WSA881X_DIGITAL_SLAVE]); - dev_err(&client->dev, "%s: regmap_init failed %d\n", - __func__, ret); - goto err; - } - /* bus reset sequence */ - ret = wsa881x_reset(pdata, true); - if (ret < 0) { - dev_err(&client->dev, "%s: WSA enable Failed %d\n", - __func__, ret); - goto err; - } - pdata->client[WSA881X_DIGITAL_SLAVE] = client; - pdata->regmap_flag = true; - ret = check_wsa881x_presence(client); - if (ret < 0) { - dev_err(&client->dev, - "failed to ping wsa with addr:%x, ret = %d\n", - client->addr, ret); - wsa881x_probing_count++; - goto err1; - } - pdata->version = wsa881x_i2c_read_device(pdata, - WSA881X_CHIP_ID1); - pr_debug("%s: wsa881x version: %d\n", __func__, pdata->version); - if (pdata->version == WSA881X_2_0) { - wsa881x_update_reg_defaults_2_0(); - wsa881x_update_regmap_2_0( - pdata->regmap[WSA881X_DIGITAL_SLAVE], - WSA881X_DIGITAL_SLAVE); - } - wsa881x_presence_count++; - wsa881x_probing_count++; - ret = snd_soc_register_codec(&client->dev, - &soc_codec_dev_wsa881x, - NULL, 0); - if (ret < 0) - goto err1; - pdata->status = WSA881X_STATUS_I2C; - } -err1: - wsa881x_reset(pdata, false); -err: - return 0; -} - -static int wsa881x_i2c_remove(struct i2c_client *client) -{ - struct wsa881x_pdata *wsa881x = i2c_get_clientdata(client); - - snd_soc_unregister_codec(&client->dev); - i2c_set_clientdata(client, NULL); - kfree(wsa881x); - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int wsa881x_i2c_suspend(struct device *dev) -{ - pr_debug("%s: system suspend\n", __func__); - return 0; -} - -static int wsa881x_i2c_resume(struct device *dev) -{ - pr_debug("%s: system resume\n", __func__); - return 0; -} - -static const struct dev_pm_ops wsa881x_i2c_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(wsa881x_i2c_suspend, wsa881x_i2c_resume) -}; -#endif /* CONFIG_PM_SLEEP */ - -static const struct i2c_device_id wsa881x_i2c_id[] = { - {"wsa881x-i2c-dev", WSA881X_I2C_SPK0_SLAVE0_ADDR}, - {"wsa881x-i2c-dev", WSA881X_I2C_SPK0_SLAVE1_ADDR}, - {"wsa881x-i2c-dev", WSA881X_I2C_SPK1_SLAVE0_ADDR}, - {"wsa881x-i2c-dev", WSA881X_I2C_SPK1_SLAVE1_ADDR}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, wsa881x_i2c_id); - - -static const struct of_device_id msm_match_table[] = { - {.compatible = "qcom,wsa881x-i2c-codec"}, - {} -}; -MODULE_DEVICE_TABLE(of, msm_match_table); - -static struct i2c_driver wsa881x_codec_driver = { - .driver = { - .name = "wsa881x-i2c-codec", - .owner = THIS_MODULE, -#ifdef CONFIG_PM_SLEEP - .pm = &wsa881x_i2c_pm_ops, -#endif - .of_match_table = msm_match_table, - }, - .id_table = wsa881x_i2c_id, - .probe = wsa881x_i2c_probe, - .remove = wsa881x_i2c_remove, -}; - -static int __init wsa881x_codec_init(void) -{ - int i = 0; - - for (i = 0; i < MAX_WSA881X_DEVICE; i++) - wsa_pdata[i].status = WSA881X_STATUS_PROBING; - return i2c_add_driver(&wsa881x_codec_driver); -} -module_init(wsa881x_codec_init); - -static void __exit wsa881x_codec_exit(void) -{ - i2c_del_driver(&wsa881x_codec_driver); -} - -module_exit(wsa881x_codec_exit); - -MODULE_DESCRIPTION("WSA881x Codec driver"); -MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/wsa881x-analog.h b/asoc/codecs/wsa881x-analog.h deleted file mode 100644 index a2ef2a284c23..000000000000 --- a/asoc/codecs/wsa881x-analog.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _WSA881X_H -#define _WSA881X_H - -#include -#include "wsa881x-registers-analog.h" -#include - -#define WSA881X_I2C_SPK0_SLAVE0_ADDR 0x0E -#define WSA881X_I2C_SPK0_SLAVE1_ADDR 0x44 -#define WSA881X_I2C_SPK1_SLAVE0_ADDR 0x0F -#define WSA881X_I2C_SPK1_SLAVE1_ADDR 0x45 - -#define WSA881X_I2C_SPK0_SLAVE0 0 -#define WSA881X_I2C_SPK1_SLAVE0 1 -#define MAX_WSA881X_DEVICE 2 -#define WSA881X_DIGITAL_SLAVE 0 -#define WSA881X_ANALOG_SLAVE 1 - -enum { - WSA881X_1_X = 0, - WSA881X_2_0, -}; - -#define WSA881X_IS_2_0(ver) \ - ((ver == WSA881X_2_0) ? 1 : 0) - -extern const u8 wsa881x_ana_reg_readable[WSA881X_CACHE_SIZE]; -extern struct reg_default wsa881x_ana_reg_defaults[WSA881X_CACHE_SIZE]; -extern struct regmap_config wsa881x_ana_regmap_config[2]; -int wsa881x_get_client_index(void); -int wsa881x_get_probing_count(void); -int wsa881x_get_presence_count(void); -int wsa881x_set_mclk_callback( - int (*enable_mclk_callback)(struct snd_soc_card *, bool)); -void wsa881x_update_reg_defaults_2_0(void); -void wsa881x_update_regmap_2_0(struct regmap *regmap, int flag); - -#endif /* _WSA881X_H */ diff --git a/asoc/codecs/wsa881x-irq.c b/asoc/codecs/wsa881x-irq.c deleted file mode 100644 index 9afbd92b8f72..000000000000 --- a/asoc/codecs/wsa881x-irq.c +++ /dev/null @@ -1,610 +0,0 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "wsa881x-irq.h" -#include "wsa881x-registers-analog.h" - -#define BYTE_BIT_MASK(nr) (1UL << ((nr) % BITS_PER_BYTE)) -#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE) - - -#define WSA_MAX_NUM_IRQS 8 - -#ifndef NO_IRQ -#define NO_IRQ (-1) -#endif - -static int virq_to_phyirq( - struct wsa_resource *wsa_res, int virq); -static int phyirq_to_virq( - struct wsa_resource *wsa_res, int irq); -static unsigned int wsa_irq_get_upstream_irq( - struct wsa_resource *wsa_res); -static void wsa_irq_put_upstream_irq( - struct wsa_resource *wsa_res); -static int wsa_map_irq( - struct wsa_resource *wsa_res, int irq); - -static struct snd_soc_codec *ptr_codec; - -/** - * wsa_set_codec() - to update codec pointer - * @codec: codec pointer. - * - * To update the codec pointer, which is used to read/write - * wsa register. - * - * Return: void. - */ -void wsa_set_codec(struct snd_soc_codec *codec) -{ - if (codec == NULL) { - pr_err("%s: codec pointer is NULL\n", __func__); - ptr_codec = NULL; - return; - } - ptr_codec = codec; - /* Initialize interrupt mask and level registers */ - snd_soc_write(codec, WSA881X_INTR_LEVEL, 0x8F); - snd_soc_write(codec, WSA881X_INTR_MASK, 0x8F); -} - -static void wsa_irq_lock(struct irq_data *data) -{ - struct wsa_resource *wsa_res = - irq_data_get_irq_chip_data(data); - - if (wsa_res == NULL) { - pr_err("%s: wsa_res pointer is NULL\n", __func__); - return; - } - mutex_lock(&wsa_res->irq_lock); -} - -static void wsa_irq_sync_unlock(struct irq_data *data) -{ - struct wsa_resource *wsa_res = - irq_data_get_irq_chip_data(data); - - if (wsa_res == NULL) { - pr_err("%s: wsa_res pointer is NULL\n", __func__); - return; - } - if (wsa_res->codec == NULL) { - pr_err("%s: codec pointer not registered\n", __func__); - if (ptr_codec == NULL) { - pr_err("%s: did not receive valid codec pointer\n", - __func__); - goto unlock; - } else { - wsa_res->codec = ptr_codec; - } - } - - /* - * If there's been a change in the mask write it back - * to the hardware. - */ - if (wsa_res->irq_masks_cur != - wsa_res->irq_masks_cache) { - - wsa_res->irq_masks_cache = - wsa_res->irq_masks_cur; - snd_soc_write(wsa_res->codec, - WSA881X_INTR_MASK, - wsa_res->irq_masks_cur); - } -unlock: - mutex_unlock(&wsa_res->irq_lock); -} - -static void wsa_irq_enable(struct irq_data *data) -{ - struct wsa_resource *wsa_res = - irq_data_get_irq_chip_data(data); - int wsa_irq; - - if (wsa_res == NULL) { - pr_err("%s: wsa_res pointer is NULL\n", __func__); - return; - } - wsa_irq = virq_to_phyirq(wsa_res, data->irq); - pr_debug("%s: wsa_irq = %d\n", __func__, wsa_irq); - wsa_res->irq_masks_cur &= - ~(BYTE_BIT_MASK(wsa_irq)); -} - -static void wsa_irq_disable(struct irq_data *data) -{ - struct wsa_resource *wsa_res = - irq_data_get_irq_chip_data(data); - int wsa_irq; - - if (wsa_res == NULL) { - pr_err("%s: wsa_res pointer is NULL\n", __func__); - return; - } - wsa_irq = virq_to_phyirq(wsa_res, data->irq); - pr_debug("%s: wsa_irq = %d\n", __func__, wsa_irq); - wsa_res->irq_masks_cur - |= BYTE_BIT_MASK(wsa_irq); -} - -static void wsa_irq_ack(struct irq_data *data) -{ - int wsa_irq = 0; - struct wsa_resource *wsa_res = - irq_data_get_irq_chip_data(data); - - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return; - } - wsa_irq = virq_to_phyirq(wsa_res, data->irq); - pr_debug("%s: IRQ_ACK called for WCD9XXX IRQ: %d\n", - __func__, wsa_irq); -} - -static void wsa_irq_mask(struct irq_data *d) -{ - /* do nothing but required as linux calls irq_mask without NULL check */ -} - -static struct irq_chip wsa_irq_chip = { - .name = "wsa", - .irq_bus_lock = wsa_irq_lock, - .irq_bus_sync_unlock = wsa_irq_sync_unlock, - .irq_disable = wsa_irq_disable, - .irq_enable = wsa_irq_enable, - .irq_mask = wsa_irq_mask, - .irq_ack = wsa_irq_ack, -}; - -static irqreturn_t wsa_irq_thread(int irq, void *data) -{ - struct wsa_resource *wsa_res = data; - int i; - u8 status; - - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return IRQ_HANDLED; - } - if (wsa_res->codec == NULL) { - pr_err("%s: codec pointer not registered\n", __func__); - if (ptr_codec == NULL) { - pr_err("%s: did not receive valid codec pointer\n", - __func__); - return IRQ_HANDLED; - } - wsa_res->codec = ptr_codec; - } - status = snd_soc_read(wsa_res->codec, WSA881X_INTR_STATUS); - /* Apply masking */ - status &= ~wsa_res->irq_masks_cur; - - for (i = 0; i < wsa_res->num_irqs; i++) { - if (status & BYTE_BIT_MASK(i)) { - mutex_lock(&wsa_res->nested_irq_lock); - handle_nested_irq(phyirq_to_virq(wsa_res, i)); - mutex_unlock(&wsa_res->nested_irq_lock); - } - } - - return IRQ_HANDLED; -} - -/** - * wsa_free_irq() - to free an interrupt - * @irq: interrupt number. - * @data: pointer to wsa resource. - * - * To free already requested interrupt. - * - * Return: void. - */ -void wsa_free_irq(int irq, void *data) -{ - struct wsa_resource *wsa_res = data; - - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return; - } - free_irq(phyirq_to_virq(wsa_res, irq), data); -} - -/** - * wsa_enable_irq() - to enable an interrupt - * @wsa_res: pointer to wsa resource. - * @irq: interrupt number. - * - * This function is to enable an interrupt. - * - * Return: void. - */ -void wsa_enable_irq(struct wsa_resource *wsa_res, int irq) -{ - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return; - } - enable_irq(phyirq_to_virq(wsa_res, irq)); -} - -/** - * wsa_disable_irq() - to disable an interrupt - * @wsa_res: pointer to wsa resource. - * @irq: interrupt number. - * - * To disable an interrupt without waiting for executing - * handler to complete. - * - * Return: void. - */ -void wsa_disable_irq(struct wsa_resource *wsa_res, int irq) -{ - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return; - } - disable_irq_nosync(phyirq_to_virq(wsa_res, irq)); -} - -/** - * wsa_disable_irq_sync() - to disable an interrupt - * @wsa_res: pointer to wsa resource. - * @irq: interrupt number. - * - * To disable an interrupt, wait for executing IRQ - * handler to complete. - * - * Return: void. - */ -void wsa_disable_irq_sync( - struct wsa_resource *wsa_res, int irq) -{ - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return; - } - disable_irq(phyirq_to_virq(wsa_res, irq)); -} - -static int wsa_irq_setup_downstream_irq(struct wsa_resource *wsa_res) -{ - int irq, virq, ret; - - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return -EINVAL; - } - pr_debug("%s: enter\n", __func__); - - for (irq = 0; irq < wsa_res->num_irqs; irq++) { - /* Map OF irq */ - virq = wsa_map_irq(wsa_res, irq); - pr_debug("%s: irq %d -> %d\n", __func__, irq, virq); - if (virq == NO_IRQ) { - pr_err("%s, No interrupt specifier for irq %d\n", - __func__, irq); - return NO_IRQ; - } - - ret = irq_set_chip_data(virq, wsa_res); - if (ret) { - pr_err("%s: Failed to configure irq %d (%d)\n", - __func__, irq, ret); - return ret; - } - - if (wsa_res->irq_level_high[irq]) - irq_set_chip_and_handler(virq, &wsa_irq_chip, - handle_level_irq); - else - irq_set_chip_and_handler(virq, &wsa_irq_chip, - handle_edge_irq); - - irq_set_nested_thread(virq, 1); - } - - pr_debug("%s: leave\n", __func__); - - return 0; -} - -static int wsa_irq_init(struct wsa_resource *wsa_res) -{ - int i, ret; - - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return -EINVAL; - } - mutex_init(&wsa_res->irq_lock); - mutex_init(&wsa_res->nested_irq_lock); - - wsa_res->irq = wsa_irq_get_upstream_irq(wsa_res); - if (!wsa_res->irq) { - pr_warn("%s: irq driver is not yet initialized\n", __func__); - mutex_destroy(&wsa_res->irq_lock); - mutex_destroy(&wsa_res->nested_irq_lock); - return -EPROBE_DEFER; - } - pr_debug("%s: probed irq %d\n", __func__, wsa_res->irq); - - /* Setup downstream IRQs */ - ret = wsa_irq_setup_downstream_irq(wsa_res); - if (ret) { - pr_err("%s: Failed to setup downstream IRQ\n", __func__); - goto fail_irq_init; - } - - /* mask all the interrupts */ - for (i = 0; i < wsa_res->num_irqs; i++) { - wsa_res->irq_masks_cur |= BYTE_BIT_MASK(i); - wsa_res->irq_masks_cache |= BYTE_BIT_MASK(i); - } - - ret = request_threaded_irq(wsa_res->irq, NULL, wsa_irq_thread, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, - "wsa", wsa_res); - if (ret != 0) { - dev_err(wsa_res->dev, "Failed to request IRQ %d: %d\n", - wsa_res->irq, ret); - } else { - ret = enable_irq_wake(wsa_res->irq); - if (ret) { - dev_err(wsa_res->dev, - "Failed to set wake interrupt on IRQ %d: %d\n", - wsa_res->irq, ret); - free_irq(wsa_res->irq, wsa_res); - } - } - - if (ret) - goto fail_irq_init; - - return ret; - -fail_irq_init: - dev_err(wsa_res->dev, - "%s: Failed to init wsa irq\n", __func__); - wsa_irq_put_upstream_irq(wsa_res); - mutex_destroy(&wsa_res->irq_lock); - mutex_destroy(&wsa_res->nested_irq_lock); - return ret; -} - -/** - * wsa_request_irq() - to request/register an interrupt - * @wsa_res: pointer to wsa_resource. - * @irq: interrupt number. - * @handler: interrupt handler function pointer. - * @name: interrupt name. - * @data: device info. - * - * Convert physical irq to virtual irq and then - * reguest for threaded handler. - * - * Return: Retuns success/failure. - */ -int wsa_request_irq(struct wsa_resource *wsa_res, - int irq, irq_handler_t handler, - const char *name, void *data) -{ - int virq; - - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return -EINVAL; - } - virq = phyirq_to_virq(wsa_res, irq); - - /* - * ARM needs us to explicitly flag the IRQ as valid - * and will set them noprobe when we do so. - */ -#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) - set_irq_flags(virq, IRQF_VALID); -#else - set_irq_noprobe(virq); -#endif - - return request_threaded_irq(virq, NULL, handler, IRQF_TRIGGER_RISING, - name, data); -} - -/** - * wsa_irq_exit() - to disable/clear interrupt/resources - * @wsa_res: pointer to wsa_resource - * - * Disable and free the interrupts and then release resources. - * - * Return: void. - */ -void wsa_irq_exit(struct wsa_resource *wsa_res) -{ - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return; - } - dev_dbg(wsa_res->dev, "%s: Cleaning up irq %d\n", __func__, - wsa_res->irq); - - if (wsa_res->irq) { - disable_irq_wake(wsa_res->irq); - free_irq(wsa_res->irq, wsa_res); - /* Release parent's of node */ - wsa_irq_put_upstream_irq(wsa_res); - } - mutex_destroy(&wsa_res->irq_lock); - mutex_destroy(&wsa_res->nested_irq_lock); -} - -static int phyirq_to_virq(struct wsa_resource *wsa_res, int offset) -{ - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return -EINVAL; - } - return irq_linear_revmap(wsa_res->domain, offset); -} - -static int virq_to_phyirq(struct wsa_resource *wsa_res, int virq) -{ - struct irq_data *irq_data = irq_get_irq_data(virq); - - if (unlikely(!irq_data)) { - pr_err("%s: irq_data is NULL\n", __func__); - return -EINVAL; - } - return irq_data->hwirq; -} - -static unsigned int wsa_irq_get_upstream_irq(struct wsa_resource *wsa_res) -{ - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return -EINVAL; - } - return wsa_res->irq; -} - -static void wsa_irq_put_upstream_irq(struct wsa_resource *wsa_res) -{ - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return; - } - /* Hold parent's of node */ - of_node_put(wsa_res->dev->of_node); -} - -static int wsa_map_irq(struct wsa_resource *wsa_res, int irq) -{ - if (wsa_res == NULL) { - pr_err("%s: wsa_res is NULL\n", __func__); - return -EINVAL; - } - return of_irq_to_resource(wsa_res->dev->of_node, irq, NULL); -} - -static int wsa_irq_probe(struct platform_device *pdev) -{ - int irq; - struct wsa_resource *wsa_res = NULL; - int ret = -EINVAL; - - irq = platform_get_irq_byname(pdev, "wsa-int"); - if (irq < 0) { - dev_err(&pdev->dev, "%s: Couldn't find wsa-int node(%d)\n", - __func__, irq); - return -EINVAL; - } - pr_debug("%s: node %s\n", __func__, pdev->name); - wsa_res = kzalloc(sizeof(*wsa_res), GFP_KERNEL); - if (!wsa_res) { - pr_err("%s: could not allocate memory\n", __func__); - return -ENOMEM; - } - /* - * wsa interrupt controller supports N to N irq mapping with - * single cell binding with irq numbers(offsets) only. - * Use irq_domain_simple_ops that has irq_domain_simple_map and - * irq_domain_xlate_onetwocell. - */ - wsa_res->dev = &pdev->dev; - wsa_res->domain = irq_domain_add_linear(wsa_res->dev->of_node, - WSA_MAX_NUM_IRQS, &irq_domain_simple_ops, - wsa_res); - if (!wsa_res->domain) { - dev_err(&pdev->dev, "%s: domain is NULL\n", __func__); - ret = -ENOMEM; - goto err; - } - wsa_res->dev = &pdev->dev; - - dev_dbg(&pdev->dev, "%s: virq = %d\n", __func__, irq); - wsa_res->irq = irq; - wsa_res->num_irq_regs = 1; - wsa_res->num_irqs = WSA_NUM_IRQS; - ret = wsa_irq_init(wsa_res); - if (ret < 0) { - dev_err(&pdev->dev, "%s: failed to do irq init %d\n", - __func__, ret); - goto err; - } - - return ret; -err: - kfree(wsa_res); - return ret; -} - -static int wsa_irq_remove(struct platform_device *pdev) -{ - struct irq_domain *domain; - struct wsa_resource *data; - - domain = irq_find_host(pdev->dev.of_node); - if (unlikely(!domain)) { - pr_err("%s: domain is NULL\n", __func__); - return -EINVAL; - } - data = (struct wsa_resource *)domain->host_data; - data->irq = 0; - - return 0; -} - -static const struct of_device_id of_match[] = { - { .compatible = "qcom,wsa-irq" }, - { } -}; - -static struct platform_driver wsa_irq_driver = { - .probe = wsa_irq_probe, - .remove = wsa_irq_remove, - .driver = { - .name = "wsa_intc", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(of_match), - }, -}; - -static int wsa_irq_drv_init(void) -{ - return platform_driver_register(&wsa_irq_driver); -} -subsys_initcall(wsa_irq_drv_init); - -static void wsa_irq_drv_exit(void) -{ - platform_driver_unregister(&wsa_irq_driver); -} -module_exit(wsa_irq_drv_exit); - -MODULE_DESCRIPTION("WSA881x IRQ driver"); -MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/wsa881x-irq.h b/asoc/codecs/wsa881x-irq.h deleted file mode 100644 index 270eb917a666..000000000000 --- a/asoc/codecs/wsa881x-irq.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef __WSA881X_IRQ_H__ -#define __WSA881X_IRQ_H__ - -#include -#include -#include - -/** - * enum wsa_interrupts - wsa interrupt number - * @WSA_INT_SAF2WAR: Temp irq interrupt, from safe state to warning state. - * @WSA_INT_WAR2SAF: Temp irq interrupt, from warning state to safe state. - * @WSA_INT_DISABLE: Disable Temp sensor interrupts. - * @WSA_INT_OCP: OCP interrupt. - * @WSA_INT_CLIP: CLIP detect interrupt. - * @WSA_NUM_IRQS: MAX Interrupt number. - * - * WSA IRQ Interrupt numbers. - */ -enum wsa_interrupts { - WSA_INT_SAF2WAR = 0, - WSA_INT_WAR2SAF, - WSA_INT_DISABLE, - WSA_INT_OCP, - WSA_INT_CLIP, - WSA_NUM_IRQS, -}; - -/** - * struct wsa_resource - the basic wsa_resource structure - * @irq_lock: lock used by irq_chip functions. - * @nested_irq_lock: lock used while handling nested interrupts. - * @irq: interrupt number. - * @irq_masks_cur: current mask value to be written to mask registers. - * @irq_masks_cache: cached mask value. - * @num_irqs: number of supported interrupts. - * @num_irq_regs: number of irq registers. - * @parent: parent pointer. - * @dev: device pointer. - * @domain: irq domain pointer. - * codec: codec pointer. - * - * Contains required members used in wsa irq driver. - */ - -struct wsa_resource { - struct mutex irq_lock; - struct mutex nested_irq_lock; - unsigned int irq; - u8 irq_masks_cur; - u8 irq_masks_cache; - bool irq_level_high[8]; - int num_irqs; - int num_irq_regs; - void *parent; - struct device *dev; - struct irq_domain *domain; - struct snd_soc_codec *codec; -}; - -void wsa_set_codec(struct snd_soc_codec *codec); -void wsa_free_irq(int irq, void *data); -void wsa_enable_irq(struct wsa_resource *wsa_res, int irq); -void wsa_disable_irq(struct wsa_resource *wsa_res, int irq); -void wsa_disable_irq_sync(struct wsa_resource *wsa_res, int irq); -int wsa_request_irq(struct wsa_resource *wsa_res, - int irq, irq_handler_t handler, - const char *name, void *data); - -void wsa_irq_exit(struct wsa_resource *wsa_res); - -#endif /* __WSA881X_IRQ_H__ */ diff --git a/asoc/codecs/wsa881x-registers-analog.h b/asoc/codecs/wsa881x-registers-analog.h deleted file mode 100644 index a5ebf8e1aab4..000000000000 --- a/asoc/codecs/wsa881x-registers-analog.h +++ /dev/null @@ -1,206 +0,0 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef WSA881X_REGISTERS_H -#define WSA881X_REGISTERS_H - -#define WSA881X_DIGITAL_BASE 0x0000 -#define WSA881X_ANALOG_BASE 0x0100 - -#define WSA881X_CHIP_ID0 (WSA881X_DIGITAL_BASE+0x0000) -#define WSA881X_CHIP_ID1 (WSA881X_DIGITAL_BASE+0x0001) -#define WSA881X_CHIP_ID2 (WSA881X_DIGITAL_BASE+0x0002) -#define WSA881X_CHIP_ID3 (WSA881X_DIGITAL_BASE+0x0003) -#define WSA881X_BUS_ID (WSA881X_DIGITAL_BASE+0x0004) -#define WSA881X_CDC_RST_CTL (WSA881X_DIGITAL_BASE+0x0005) -#define WSA881X_CDC_TOP_CLK_CTL (WSA881X_DIGITAL_BASE+0x0006) -#define WSA881X_CDC_ANA_CLK_CTL (WSA881X_DIGITAL_BASE+0x0007) -#define WSA881X_CDC_DIG_CLK_CTL (WSA881X_DIGITAL_BASE+0x0008) -#define WSA881X_CLOCK_CONFIG (WSA881X_DIGITAL_BASE+0x0009) -#define WSA881X_ANA_CTL (WSA881X_DIGITAL_BASE+0x000A) -#define WSA881X_SWR_RESET_EN (WSA881X_DIGITAL_BASE+0x000B) -#define WSA881X_RESET_CTL (WSA881X_DIGITAL_BASE+0x000C) -#define WSA881X_TADC_VALUE_CTL (WSA881X_DIGITAL_BASE+0x000F) -#define WSA881X_TEMP_DETECT_CTL (WSA881X_DIGITAL_BASE+0x0010) -#define WSA881X_TEMP_MSB (WSA881X_DIGITAL_BASE+0x0011) -#define WSA881X_TEMP_LSB (WSA881X_DIGITAL_BASE+0x0012) -#define WSA881X_TEMP_CONFIG0 (WSA881X_DIGITAL_BASE+0x0013) -#define WSA881X_TEMP_CONFIG1 (WSA881X_DIGITAL_BASE+0x0014) -#define WSA881X_CDC_CLIP_CTL (WSA881X_DIGITAL_BASE+0x0015) -#define WSA881X_SDM_PDM9_LSB (WSA881X_DIGITAL_BASE+0x0016) -#define WSA881X_SDM_PDM9_MSB (WSA881X_DIGITAL_BASE+0x0017) -#define WSA881X_CDC_RX_CTL (WSA881X_DIGITAL_BASE+0x0018) -#define WSA881X_DEM_BYPASS_DATA0 (WSA881X_DIGITAL_BASE+0x0019) -#define WSA881X_DEM_BYPASS_DATA1 (WSA881X_DIGITAL_BASE+0x001A) -#define WSA881X_DEM_BYPASS_DATA2 (WSA881X_DIGITAL_BASE+0x001B) -#define WSA881X_DEM_BYPASS_DATA3 (WSA881X_DIGITAL_BASE+0x001C) -#define WSA881X_OTP_CTRL0 (WSA881X_DIGITAL_BASE+0x001D) -#define WSA881X_OTP_CTRL1 (WSA881X_DIGITAL_BASE+0x001E) -#define WSA881X_HDRIVE_CTL_GROUP1 (WSA881X_DIGITAL_BASE+0x001F) -#define WSA881X_INTR_MODE (WSA881X_DIGITAL_BASE+0x0020) -#define WSA881X_INTR_MASK (WSA881X_DIGITAL_BASE+0x0021) -#define WSA881X_INTR_STATUS (WSA881X_DIGITAL_BASE+0x0022) -#define WSA881X_INTR_CLEAR (WSA881X_DIGITAL_BASE+0x0023) -#define WSA881X_INTR_LEVEL (WSA881X_DIGITAL_BASE+0x0024) -#define WSA881X_INTR_SET (WSA881X_DIGITAL_BASE+0x0025) -#define WSA881X_INTR_TEST (WSA881X_DIGITAL_BASE+0x0026) -#define WSA881X_PDM_TEST_MODE (WSA881X_DIGITAL_BASE+0x0030) -#define WSA881X_ATE_TEST_MODE (WSA881X_DIGITAL_BASE+0x0031) -#define WSA881X_PIN_CTL_MODE (WSA881X_DIGITAL_BASE+0x0032) -#define WSA881X_PIN_CTL_OE (WSA881X_DIGITAL_BASE+0x0033) -#define WSA881X_PIN_WDATA_IOPAD (WSA881X_DIGITAL_BASE+0x0034) -#define WSA881X_PIN_STATUS (WSA881X_DIGITAL_BASE+0x0035) -#define WSA881X_DIG_DEBUG_MODE (WSA881X_DIGITAL_BASE+0x0037) -#define WSA881X_DIG_DEBUG_SEL (WSA881X_DIGITAL_BASE+0x0038) -#define WSA881X_DIG_DEBUG_EN (WSA881X_DIGITAL_BASE+0x0039) -#define WSA881X_SWR_HM_TEST1 (WSA881X_DIGITAL_BASE+0x003B) -#define WSA881X_SWR_HM_TEST2 (WSA881X_DIGITAL_BASE+0x003C) -#define WSA881X_TEMP_DETECT_DBG_CTL (WSA881X_DIGITAL_BASE+0x003D) -#define WSA881X_TEMP_DEBUG_MSB (WSA881X_DIGITAL_BASE+0x003E) -#define WSA881X_TEMP_DEBUG_LSB (WSA881X_DIGITAL_BASE+0x003F) -#define WSA881X_SAMPLE_EDGE_SEL (WSA881X_DIGITAL_BASE+0x0044) -#define WSA881X_IOPAD_CTL (WSA881X_DIGITAL_BASE+0x0045) -#define WSA881X_SPARE_0 (WSA881X_DIGITAL_BASE+0x0050) -#define WSA881X_SPARE_1 (WSA881X_DIGITAL_BASE+0x0051) -#define WSA881X_SPARE_2 (WSA881X_DIGITAL_BASE+0x0052) -#define WSA881X_OTP_REG_0 (WSA881X_DIGITAL_BASE+0x0080) -#define WSA881X_OTP_REG_1 (WSA881X_DIGITAL_BASE+0x0081) -#define WSA881X_OTP_REG_2 (WSA881X_DIGITAL_BASE+0x0082) -#define WSA881X_OTP_REG_3 (WSA881X_DIGITAL_BASE+0x0083) -#define WSA881X_OTP_REG_4 (WSA881X_DIGITAL_BASE+0x0084) -#define WSA881X_OTP_REG_5 (WSA881X_DIGITAL_BASE+0x0085) -#define WSA881X_OTP_REG_6 (WSA881X_DIGITAL_BASE+0x0086) -#define WSA881X_OTP_REG_7 (WSA881X_DIGITAL_BASE+0x0087) -#define WSA881X_OTP_REG_8 (WSA881X_DIGITAL_BASE+0x0088) -#define WSA881X_OTP_REG_9 (WSA881X_DIGITAL_BASE+0x0089) -#define WSA881X_OTP_REG_10 (WSA881X_DIGITAL_BASE+0x008A) -#define WSA881X_OTP_REG_11 (WSA881X_DIGITAL_BASE+0x008B) -#define WSA881X_OTP_REG_12 (WSA881X_DIGITAL_BASE+0x008C) -#define WSA881X_OTP_REG_13 (WSA881X_DIGITAL_BASE+0x008D) -#define WSA881X_OTP_REG_14 (WSA881X_DIGITAL_BASE+0x008E) -#define WSA881X_OTP_REG_15 (WSA881X_DIGITAL_BASE+0x008F) -#define WSA881X_OTP_REG_16 (WSA881X_DIGITAL_BASE+0x0090) -#define WSA881X_OTP_REG_17 (WSA881X_DIGITAL_BASE+0x0091) -#define WSA881X_OTP_REG_18 (WSA881X_DIGITAL_BASE+0x0092) -#define WSA881X_OTP_REG_19 (WSA881X_DIGITAL_BASE+0x0093) -#define WSA881X_OTP_REG_20 (WSA881X_DIGITAL_BASE+0x0094) -#define WSA881X_OTP_REG_21 (WSA881X_DIGITAL_BASE+0x0095) -#define WSA881X_OTP_REG_22 (WSA881X_DIGITAL_BASE+0x0096) -#define WSA881X_OTP_REG_23 (WSA881X_DIGITAL_BASE+0x0097) -#define WSA881X_OTP_REG_24 (WSA881X_DIGITAL_BASE+0x0098) -#define WSA881X_OTP_REG_25 (WSA881X_DIGITAL_BASE+0x0099) -#define WSA881X_OTP_REG_26 (WSA881X_DIGITAL_BASE+0x009A) -#define WSA881X_OTP_REG_27 (WSA881X_DIGITAL_BASE+0x009B) -#define WSA881X_OTP_REG_28 (WSA881X_DIGITAL_BASE+0x009C) -#define WSA881X_OTP_REG_29 (WSA881X_DIGITAL_BASE+0x009D) -#define WSA881X_OTP_REG_30 (WSA881X_DIGITAL_BASE+0x009E) -#define WSA881X_OTP_REG_31 (WSA881X_DIGITAL_BASE+0x009F) -#define WSA881X_OTP_REG_32 (WSA881X_DIGITAL_BASE+0x00A0) -#define WSA881X_OTP_REG_33 (WSA881X_DIGITAL_BASE+0x00A1) -#define WSA881X_OTP_REG_34 (WSA881X_DIGITAL_BASE+0x00A2) -#define WSA881X_OTP_REG_35 (WSA881X_DIGITAL_BASE+0x00A3) -#define WSA881X_OTP_REG_36 (WSA881X_DIGITAL_BASE+0x00A4) -#define WSA881X_OTP_REG_37 (WSA881X_DIGITAL_BASE+0x00A5) -#define WSA881X_OTP_REG_38 (WSA881X_DIGITAL_BASE+0x00A6) -#define WSA881X_OTP_REG_39 (WSA881X_DIGITAL_BASE+0x00A7) -#define WSA881X_OTP_REG_40 (WSA881X_DIGITAL_BASE+0x00A8) -#define WSA881X_OTP_REG_41 (WSA881X_DIGITAL_BASE+0x00A9) -#define WSA881X_OTP_REG_42 (WSA881X_DIGITAL_BASE+0x00AA) -#define WSA881X_OTP_REG_43 (WSA881X_DIGITAL_BASE+0x00AB) -#define WSA881X_OTP_REG_44 (WSA881X_DIGITAL_BASE+0x00AC) -#define WSA881X_OTP_REG_45 (WSA881X_DIGITAL_BASE+0x00AD) -#define WSA881X_OTP_REG_46 (WSA881X_DIGITAL_BASE+0x00AE) -#define WSA881X_OTP_REG_47 (WSA881X_DIGITAL_BASE+0x00AF) -#define WSA881X_OTP_REG_48 (WSA881X_DIGITAL_BASE+0x00B0) -#define WSA881X_OTP_REG_49 (WSA881X_DIGITAL_BASE+0x00B1) -#define WSA881X_OTP_REG_50 (WSA881X_DIGITAL_BASE+0x00B2) -#define WSA881X_OTP_REG_51 (WSA881X_DIGITAL_BASE+0x00B3) -#define WSA881X_OTP_REG_52 (WSA881X_DIGITAL_BASE+0x00B4) -#define WSA881X_OTP_REG_53 (WSA881X_DIGITAL_BASE+0x00B5) -#define WSA881X_OTP_REG_54 (WSA881X_DIGITAL_BASE+0x00B6) -#define WSA881X_OTP_REG_55 (WSA881X_DIGITAL_BASE+0x00B7) -#define WSA881X_OTP_REG_56 (WSA881X_DIGITAL_BASE+0x00B8) -#define WSA881X_OTP_REG_57 (WSA881X_DIGITAL_BASE+0x00B9) -#define WSA881X_OTP_REG_58 (WSA881X_DIGITAL_BASE+0x00BA) -#define WSA881X_OTP_REG_59 (WSA881X_DIGITAL_BASE+0x00BB) -#define WSA881X_OTP_REG_60 (WSA881X_DIGITAL_BASE+0x00BC) -#define WSA881X_OTP_REG_61 (WSA881X_DIGITAL_BASE+0x00BD) -#define WSA881X_OTP_REG_62 (WSA881X_DIGITAL_BASE+0x00BE) -#define WSA881X_OTP_REG_63 (WSA881X_DIGITAL_BASE+0x00BF) -/* Analog Register address space */ -#define WSA881X_BIAS_REF_CTRL (WSA881X_ANALOG_BASE+0x0000) -#define WSA881X_BIAS_TEST (WSA881X_ANALOG_BASE+0x0001) -#define WSA881X_BIAS_BIAS (WSA881X_ANALOG_BASE+0x0002) -#define WSA881X_TEMP_OP (WSA881X_ANALOG_BASE+0x0003) -#define WSA881X_TEMP_IREF_CTRL (WSA881X_ANALOG_BASE+0x0004) -#define WSA881X_TEMP_ISENS_CTRL (WSA881X_ANALOG_BASE+0x0005) -#define WSA881X_TEMP_CLK_CTRL (WSA881X_ANALOG_BASE+0x0006) -#define WSA881X_TEMP_TEST (WSA881X_ANALOG_BASE+0x0007) -#define WSA881X_TEMP_BIAS (WSA881X_ANALOG_BASE+0x0008) -#define WSA881X_TEMP_ADC_CTRL (WSA881X_ANALOG_BASE+0x0009) -#define WSA881X_TEMP_DOUT_MSB (WSA881X_ANALOG_BASE+0x000A) -#define WSA881X_TEMP_DOUT_LSB (WSA881X_ANALOG_BASE+0x000B) -#define WSA881X_ADC_EN_MODU_V (WSA881X_ANALOG_BASE+0x0010) -#define WSA881X_ADC_EN_MODU_I (WSA881X_ANALOG_BASE+0x0011) -#define WSA881X_ADC_EN_DET_TEST_V (WSA881X_ANALOG_BASE+0x0012) -#define WSA881X_ADC_EN_DET_TEST_I (WSA881X_ANALOG_BASE+0x0013) -#define WSA881X_ADC_SEL_IBIAS (WSA881X_ANALOG_BASE+0x0014) -#define WSA881X_ADC_EN_SEL_IBIAS (WSA881X_ANALOG_BASE+0x0015) -#define WSA881X_SPKR_DRV_EN (WSA881X_ANALOG_BASE+0x001A) -#define WSA881X_SPKR_DRV_GAIN (WSA881X_ANALOG_BASE+0x001B) -#define WSA881X_SPKR_DAC_CTL (WSA881X_ANALOG_BASE+0x001C) -#define WSA881X_SPKR_DRV_DBG (WSA881X_ANALOG_BASE+0x001D) -#define WSA881X_SPKR_PWRSTG_DBG (WSA881X_ANALOG_BASE+0x001E) -#define WSA881X_SPKR_OCP_CTL (WSA881X_ANALOG_BASE+0x001F) -#define WSA881X_SPKR_CLIP_CTL (WSA881X_ANALOG_BASE+0x0020) -#define WSA881X_SPKR_BBM_CTL (WSA881X_ANALOG_BASE+0x0021) -#define WSA881X_SPKR_MISC_CTL1 (WSA881X_ANALOG_BASE+0x0022) -#define WSA881X_SPKR_MISC_CTL2 (WSA881X_ANALOG_BASE+0x0023) -#define WSA881X_SPKR_BIAS_INT (WSA881X_ANALOG_BASE+0x0024) -#define WSA881X_SPKR_PA_INT (WSA881X_ANALOG_BASE+0x0025) -#define WSA881X_SPKR_BIAS_CAL (WSA881X_ANALOG_BASE+0x0026) -#define WSA881X_SPKR_BIAS_PSRR (WSA881X_ANALOG_BASE+0x0027) -#define WSA881X_SPKR_STATUS1 (WSA881X_ANALOG_BASE+0x0028) -#define WSA881X_SPKR_STATUS2 (WSA881X_ANALOG_BASE+0x0029) -#define WSA881X_BOOST_EN_CTL (WSA881X_ANALOG_BASE+0x002A) -#define WSA881X_BOOST_CURRENT_LIMIT (WSA881X_ANALOG_BASE+0x002B) -#define WSA881X_BOOST_PS_CTL (WSA881X_ANALOG_BASE+0x002C) -#define WSA881X_BOOST_PRESET_OUT1 (WSA881X_ANALOG_BASE+0x002D) -#define WSA881X_BOOST_PRESET_OUT2 (WSA881X_ANALOG_BASE+0x002E) -#define WSA881X_BOOST_FORCE_OUT (WSA881X_ANALOG_BASE+0x002F) -#define WSA881X_BOOST_LDO_PROG (WSA881X_ANALOG_BASE+0x0030) -#define WSA881X_BOOST_SLOPE_COMP_ISENSE_FB (WSA881X_ANALOG_BASE+0x0031) -#define WSA881X_BOOST_RON_CTL (WSA881X_ANALOG_BASE+0x0032) -#define WSA881X_BOOST_LOOP_STABILITY (WSA881X_ANALOG_BASE+0x0033) -#define WSA881X_BOOST_ZX_CTL (WSA881X_ANALOG_BASE+0x0034) -#define WSA881X_BOOST_START_CTL (WSA881X_ANALOG_BASE+0x0035) -#define WSA881X_BOOST_MISC1_CTL (WSA881X_ANALOG_BASE+0x0036) -#define WSA881X_BOOST_MISC2_CTL (WSA881X_ANALOG_BASE+0x0037) -#define WSA881X_BOOST_MISC3_CTL (WSA881X_ANALOG_BASE+0x0038) -#define WSA881X_BOOST_ATEST_CTL (WSA881X_ANALOG_BASE+0x0039) -#define WSA881X_SPKR_PROT_FE_GAIN (WSA881X_ANALOG_BASE+0x003A) -#define WSA881X_SPKR_PROT_FE_CM_LDO_SET (WSA881X_ANALOG_BASE+0x003B) -#define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1 (WSA881X_ANALOG_BASE+0x003C) -#define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2 (WSA881X_ANALOG_BASE+0x003D) -#define WSA881X_SPKR_PROT_ATEST1 (WSA881X_ANALOG_BASE+0x003E) -#define WSA881X_SPKR_PROT_ATEST2 (WSA881X_ANALOG_BASE+0x003F) -#define WSA881X_SPKR_PROT_FE_VSENSE_VCM (WSA881X_ANALOG_BASE+0x0040) -#define WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1 (WSA881X_ANALOG_BASE+0x0041) -#define WSA881X_BONGO_RESRV_REG1 (WSA881X_ANALOG_BASE+0x0042) -#define WSA881X_BONGO_RESRV_REG2 (WSA881X_ANALOG_BASE+0x0043) -#define WSA881X_SPKR_PROT_SAR (WSA881X_ANALOG_BASE+0x0044) -#define WSA881X_SPKR_STATUS3 (WSA881X_ANALOG_BASE+0x0045) - -#define WSA881X_NUM_REGISTERS (WSA881X_SPKR_STATUS3+1) -#define WSA881X_MAX_REGISTER (WSA881X_NUM_REGISTERS-1) -#define WSA881X_CACHE_SIZE WSA881X_NUM_REGISTERS -#endif /* WSA881X_REGISTERS_H */ diff --git a/asoc/codecs/wsa881x-regmap-analog.c b/asoc/codecs/wsa881x-regmap-analog.c deleted file mode 100644 index 2bc3c9eb7061..000000000000 --- a/asoc/codecs/wsa881x-regmap-analog.c +++ /dev/null @@ -1,499 +0,0 @@ -/* - * Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include "wsa881x-registers-analog.h" -#include "wsa881x-analog.h" - -struct reg_default wsa881x_ana_reg_defaults[] = { - {WSA881X_CHIP_ID0, 0x00}, - {WSA881X_CHIP_ID1, 0x00}, - {WSA881X_CHIP_ID2, 0x00}, - {WSA881X_CHIP_ID3, 0x02}, - {WSA881X_BUS_ID, 0x00}, - {WSA881X_CDC_RST_CTL, 0x00}, - {WSA881X_CDC_TOP_CLK_CTL, 0x03}, - {WSA881X_CDC_ANA_CLK_CTL, 0x00}, - {WSA881X_CDC_DIG_CLK_CTL, 0x00}, - {WSA881X_CLOCK_CONFIG, 0x00}, - {WSA881X_ANA_CTL, 0x08}, - {WSA881X_SWR_RESET_EN, 0x00}, - {WSA881X_TEMP_DETECT_CTL, 0x01}, - {WSA881X_TEMP_MSB, 0x00}, - {WSA881X_TEMP_LSB, 0x00}, - {WSA881X_TEMP_CONFIG0, 0x00}, - {WSA881X_TEMP_CONFIG1, 0x00}, - {WSA881X_CDC_CLIP_CTL, 0x03}, - {WSA881X_SDM_PDM9_LSB, 0x00}, - {WSA881X_SDM_PDM9_MSB, 0x00}, - {WSA881X_CDC_RX_CTL, 0x7E}, - {WSA881X_DEM_BYPASS_DATA0, 0x00}, - {WSA881X_DEM_BYPASS_DATA1, 0x00}, - {WSA881X_DEM_BYPASS_DATA2, 0x00}, - {WSA881X_DEM_BYPASS_DATA3, 0x00}, - {WSA881X_OTP_CTRL0, 0x00}, - {WSA881X_OTP_CTRL1, 0x00}, - {WSA881X_HDRIVE_CTL_GROUP1, 0x00}, - {WSA881X_INTR_MODE, 0x00}, - {WSA881X_INTR_MASK, 0x1F}, - {WSA881X_INTR_STATUS, 0x00}, - {WSA881X_INTR_CLEAR, 0x00}, - {WSA881X_INTR_LEVEL, 0x00}, - {WSA881X_INTR_SET, 0x00}, - {WSA881X_INTR_TEST, 0x00}, - {WSA881X_PDM_TEST_MODE, 0x00}, - {WSA881X_ATE_TEST_MODE, 0x00}, - {WSA881X_PIN_CTL_MODE, 0x00}, - {WSA881X_PIN_CTL_OE, 0x00}, - {WSA881X_PIN_WDATA_IOPAD, 0x00}, - {WSA881X_PIN_STATUS, 0x00}, - {WSA881X_DIG_DEBUG_MODE, 0x00}, - {WSA881X_DIG_DEBUG_SEL, 0x00}, - {WSA881X_DIG_DEBUG_EN, 0x00}, - {WSA881X_SWR_HM_TEST1, 0x08}, - {WSA881X_SWR_HM_TEST2, 0x00}, - {WSA881X_TEMP_DETECT_DBG_CTL, 0x00}, - {WSA881X_TEMP_DEBUG_MSB, 0x00}, - {WSA881X_TEMP_DEBUG_LSB, 0x00}, - {WSA881X_SAMPLE_EDGE_SEL, 0x0C}, - {WSA881X_SPARE_0, 0x00}, - {WSA881X_SPARE_1, 0x00}, - {WSA881X_SPARE_2, 0x00}, - {WSA881X_OTP_REG_0, 0x01}, - {WSA881X_OTP_REG_1, 0xFF}, - {WSA881X_OTP_REG_2, 0xC0}, - {WSA881X_OTP_REG_3, 0xFF}, - {WSA881X_OTP_REG_4, 0xC0}, - {WSA881X_OTP_REG_5, 0xFF}, - {WSA881X_OTP_REG_6, 0xFF}, - {WSA881X_OTP_REG_7, 0xFF}, - {WSA881X_OTP_REG_8, 0xFF}, - {WSA881X_OTP_REG_9, 0xFF}, - {WSA881X_OTP_REG_10, 0xFF}, - {WSA881X_OTP_REG_11, 0xFF}, - {WSA881X_OTP_REG_12, 0xFF}, - {WSA881X_OTP_REG_13, 0xFF}, - {WSA881X_OTP_REG_14, 0xFF}, - {WSA881X_OTP_REG_15, 0xFF}, - {WSA881X_OTP_REG_16, 0xFF}, - {WSA881X_OTP_REG_17, 0xFF}, - {WSA881X_OTP_REG_18, 0xFF}, - {WSA881X_OTP_REG_19, 0xFF}, - {WSA881X_OTP_REG_20, 0xFF}, - {WSA881X_OTP_REG_21, 0xFF}, - {WSA881X_OTP_REG_22, 0xFF}, - {WSA881X_OTP_REG_23, 0xFF}, - {WSA881X_OTP_REG_24, 0x03}, - {WSA881X_OTP_REG_25, 0x01}, - {WSA881X_OTP_REG_26, 0x03}, - {WSA881X_OTP_REG_27, 0x11}, - {WSA881X_OTP_REG_28, 0xFF}, - {WSA881X_OTP_REG_29, 0xFF}, - {WSA881X_OTP_REG_30, 0xFF}, - {WSA881X_OTP_REG_31, 0xFF}, - {WSA881X_OTP_REG_63, 0x40}, - /* WSA881x Analog registers */ - {WSA881X_BIAS_REF_CTRL, 0x6C}, - {WSA881X_BIAS_TEST, 0x16}, - {WSA881X_BIAS_BIAS, 0xF0}, - {WSA881X_TEMP_OP, 0x00}, - {WSA881X_TEMP_IREF_CTRL, 0x56}, - {WSA881X_TEMP_ISENS_CTRL, 0x47}, - {WSA881X_TEMP_CLK_CTRL, 0x87}, - {WSA881X_TEMP_TEST, 0x00}, - {WSA881X_TEMP_BIAS, 0x51}, - {WSA881X_TEMP_ADC_CTRL, 0x00}, - {WSA881X_TEMP_DOUT_MSB, 0x00}, - {WSA881X_TEMP_DOUT_LSB, 0x00}, - {WSA881X_ADC_EN_MODU_V, 0x00}, - {WSA881X_ADC_EN_MODU_I, 0x00}, - {WSA881X_ADC_EN_DET_TEST_V, 0x00}, - {WSA881X_ADC_EN_DET_TEST_I, 0x00}, - {WSA881X_ADC_SEL_IBIAS, 0x25}, - {WSA881X_ADC_EN_SEL_IBIAS, 0x10}, - {WSA881X_SPKR_DRV_EN, 0x74}, - {WSA881X_SPKR_DRV_GAIN, 0x01}, - {WSA881X_SPKR_DAC_CTL, 0x40}, - {WSA881X_SPKR_DRV_DBG, 0x15}, - {WSA881X_SPKR_PWRSTG_DBG, 0x00}, - {WSA881X_SPKR_OCP_CTL, 0xD4}, - {WSA881X_SPKR_CLIP_CTL, 0x90}, - {WSA881X_SPKR_BBM_CTL, 0x00}, - {WSA881X_SPKR_MISC_CTL1, 0x80}, - {WSA881X_SPKR_MISC_CTL2, 0x00}, - {WSA881X_SPKR_BIAS_INT, 0x56}, - {WSA881X_SPKR_PA_INT, 0x54}, - {WSA881X_SPKR_BIAS_CAL, 0xAC}, - {WSA881X_SPKR_BIAS_PSRR, 0x54}, - {WSA881X_SPKR_STATUS1, 0x00}, - {WSA881X_SPKR_STATUS2, 0x00}, - {WSA881X_BOOST_EN_CTL, 0x18}, - {WSA881X_BOOST_CURRENT_LIMIT, 0x7A}, - {WSA881X_BOOST_PS_CTL, 0xC0}, - {WSA881X_BOOST_PRESET_OUT1, 0x77}, - {WSA881X_BOOST_PRESET_OUT2, 0x70}, - {WSA881X_BOOST_FORCE_OUT, 0x0E}, - {WSA881X_BOOST_LDO_PROG, 0x16}, - {WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, 0x71}, - {WSA881X_BOOST_RON_CTL, 0x0F}, - {WSA881X_BOOST_LOOP_STABILITY, 0xAD}, - {WSA881X_BOOST_ZX_CTL, 0x34}, - {WSA881X_BOOST_START_CTL, 0x23}, - {WSA881X_BOOST_MISC1_CTL, 0x80}, - {WSA881X_BOOST_MISC2_CTL, 0x00}, - {WSA881X_BOOST_MISC3_CTL, 0x00}, - {WSA881X_BOOST_ATEST_CTL, 0x00}, - {WSA881X_SPKR_PROT_FE_GAIN, 0x46}, - {WSA881X_SPKR_PROT_FE_CM_LDO_SET, 0x3B}, - {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1, 0x8D}, - {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2, 0x8D}, - {WSA881X_SPKR_PROT_ATEST1, 0x01}, - {WSA881X_SPKR_PROT_ATEST2, 0x00}, - {WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x8D}, - {WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1, 0x4D}, - {WSA881X_BONGO_RESRV_REG1, 0x00}, - {WSA881X_BONGO_RESRV_REG2, 0x00}, - {WSA881X_SPKR_PROT_SAR, 0x00}, - {WSA881X_SPKR_STATUS3, 0x00}, -}; - -struct reg_default wsa881x_ana_reg_defaults_0[] = { - {WSA881X_CHIP_ID0, 0x00}, - {WSA881X_CHIP_ID1, 0x00}, - {WSA881X_CHIP_ID2, 0x00}, - {WSA881X_CHIP_ID3, 0x02}, - {WSA881X_BUS_ID, 0x00}, - {WSA881X_CDC_RST_CTL, 0x00}, - {WSA881X_CDC_TOP_CLK_CTL, 0x03}, - {WSA881X_CDC_ANA_CLK_CTL, 0x00}, - {WSA881X_CDC_DIG_CLK_CTL, 0x00}, - {WSA881X_CLOCK_CONFIG, 0x00}, - {WSA881X_ANA_CTL, 0x08}, - {WSA881X_SWR_RESET_EN, 0x00}, - {WSA881X_TEMP_DETECT_CTL, 0x01}, - {WSA881X_TEMP_MSB, 0x00}, - {WSA881X_TEMP_LSB, 0x00}, - {WSA881X_TEMP_CONFIG0, 0x00}, - {WSA881X_TEMP_CONFIG1, 0x00}, - {WSA881X_CDC_CLIP_CTL, 0x03}, - {WSA881X_SDM_PDM9_LSB, 0x00}, - {WSA881X_SDM_PDM9_MSB, 0x00}, - {WSA881X_CDC_RX_CTL, 0x7E}, - {WSA881X_DEM_BYPASS_DATA0, 0x00}, - {WSA881X_DEM_BYPASS_DATA1, 0x00}, - {WSA881X_DEM_BYPASS_DATA2, 0x00}, - {WSA881X_DEM_BYPASS_DATA3, 0x00}, - {WSA881X_OTP_CTRL0, 0x00}, - {WSA881X_OTP_CTRL1, 0x00}, - {WSA881X_HDRIVE_CTL_GROUP1, 0x00}, - {WSA881X_INTR_MODE, 0x00}, - {WSA881X_INTR_MASK, 0x1F}, - {WSA881X_INTR_STATUS, 0x00}, - {WSA881X_INTR_CLEAR, 0x00}, - {WSA881X_INTR_LEVEL, 0x00}, - {WSA881X_INTR_SET, 0x00}, - {WSA881X_INTR_TEST, 0x00}, - {WSA881X_PDM_TEST_MODE, 0x00}, - {WSA881X_ATE_TEST_MODE, 0x00}, - {WSA881X_PIN_CTL_MODE, 0x00}, - {WSA881X_PIN_CTL_OE, 0x00}, - {WSA881X_PIN_WDATA_IOPAD, 0x00}, - {WSA881X_PIN_STATUS, 0x00}, - {WSA881X_DIG_DEBUG_MODE, 0x00}, - {WSA881X_DIG_DEBUG_SEL, 0x00}, - {WSA881X_DIG_DEBUG_EN, 0x00}, - {WSA881X_SWR_HM_TEST1, 0x08}, - {WSA881X_SWR_HM_TEST2, 0x00}, - {WSA881X_TEMP_DETECT_DBG_CTL, 0x00}, - {WSA881X_TEMP_DEBUG_MSB, 0x00}, - {WSA881X_TEMP_DEBUG_LSB, 0x00}, - {WSA881X_SAMPLE_EDGE_SEL, 0x0C}, - {WSA881X_SPARE_0, 0x00}, - {WSA881X_SPARE_1, 0x00}, - {WSA881X_SPARE_2, 0x00}, - {WSA881X_OTP_REG_0, 0x01}, - {WSA881X_OTP_REG_1, 0xFF}, - {WSA881X_OTP_REG_2, 0xC0}, - {WSA881X_OTP_REG_3, 0xFF}, - {WSA881X_OTP_REG_4, 0xC0}, - {WSA881X_OTP_REG_5, 0xFF}, - {WSA881X_OTP_REG_6, 0xFF}, - {WSA881X_OTP_REG_7, 0xFF}, - {WSA881X_OTP_REG_8, 0xFF}, - {WSA881X_OTP_REG_9, 0xFF}, - {WSA881X_OTP_REG_10, 0xFF}, - {WSA881X_OTP_REG_11, 0xFF}, - {WSA881X_OTP_REG_12, 0xFF}, - {WSA881X_OTP_REG_13, 0xFF}, - {WSA881X_OTP_REG_14, 0xFF}, - {WSA881X_OTP_REG_15, 0xFF}, - {WSA881X_OTP_REG_16, 0xFF}, - {WSA881X_OTP_REG_17, 0xFF}, - {WSA881X_OTP_REG_18, 0xFF}, - {WSA881X_OTP_REG_19, 0xFF}, - {WSA881X_OTP_REG_20, 0xFF}, - {WSA881X_OTP_REG_21, 0xFF}, - {WSA881X_OTP_REG_22, 0xFF}, - {WSA881X_OTP_REG_23, 0xFF}, - {WSA881X_OTP_REG_24, 0x03}, - {WSA881X_OTP_REG_25, 0x01}, - {WSA881X_OTP_REG_26, 0x03}, - {WSA881X_OTP_REG_27, 0x11}, - {WSA881X_OTP_REG_28, 0xFF}, - {WSA881X_OTP_REG_29, 0xFF}, - {WSA881X_OTP_REG_30, 0xFF}, - {WSA881X_OTP_REG_31, 0xFF}, - {WSA881X_OTP_REG_63, 0x40}, -}; - -struct reg_default wsa881x_ana_reg_defaults_1[] = { - {WSA881X_BIAS_REF_CTRL - WSA881X_ANALOG_BASE, 0x6C}, - {WSA881X_BIAS_TEST - WSA881X_ANALOG_BASE, 0x16}, - {WSA881X_BIAS_BIAS - WSA881X_ANALOG_BASE, 0xF0}, - {WSA881X_TEMP_OP - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_TEMP_IREF_CTRL - WSA881X_ANALOG_BASE, 0x56}, - {WSA881X_TEMP_ISENS_CTRL - WSA881X_ANALOG_BASE, 0x47}, - {WSA881X_TEMP_CLK_CTRL - WSA881X_ANALOG_BASE, 0x87}, - {WSA881X_TEMP_TEST - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_TEMP_BIAS - WSA881X_ANALOG_BASE, 0x51}, - {WSA881X_TEMP_ADC_CTRL - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_TEMP_DOUT_MSB - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_TEMP_DOUT_LSB - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_ADC_EN_MODU_V - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_ADC_EN_MODU_I - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_ADC_EN_DET_TEST_V - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_ADC_EN_DET_TEST_I - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_ADC_SEL_IBIAS - WSA881X_ANALOG_BASE, 0x25}, - {WSA881X_ADC_EN_SEL_IBIAS - WSA881X_ANALOG_BASE, 0x10}, - {WSA881X_SPKR_DRV_EN - WSA881X_ANALOG_BASE, 0x74}, - {WSA881X_SPKR_DRV_GAIN - WSA881X_ANALOG_BASE, 0x01}, - {WSA881X_SPKR_DAC_CTL - WSA881X_ANALOG_BASE, 0x40}, - {WSA881X_SPKR_DRV_DBG - WSA881X_ANALOG_BASE, 0x15}, - {WSA881X_SPKR_PWRSTG_DBG - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_SPKR_OCP_CTL - WSA881X_ANALOG_BASE, 0xD4}, - {WSA881X_SPKR_CLIP_CTL - WSA881X_ANALOG_BASE, 0x90}, - {WSA881X_SPKR_BBM_CTL - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_SPKR_MISC_CTL1 - WSA881X_ANALOG_BASE, 0x80}, - {WSA881X_SPKR_MISC_CTL2 - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_SPKR_BIAS_INT - WSA881X_ANALOG_BASE, 0x56}, - {WSA881X_SPKR_PA_INT - WSA881X_ANALOG_BASE, 0x54}, - {WSA881X_SPKR_BIAS_CAL - WSA881X_ANALOG_BASE, 0xAC}, - {WSA881X_SPKR_BIAS_PSRR - WSA881X_ANALOG_BASE, 0x54}, - {WSA881X_SPKR_STATUS1 - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_SPKR_STATUS2 - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_BOOST_EN_CTL - WSA881X_ANALOG_BASE, 0x18}, - {WSA881X_BOOST_CURRENT_LIMIT - WSA881X_ANALOG_BASE, 0x7A}, - {WSA881X_BOOST_PS_CTL - WSA881X_ANALOG_BASE, 0xC0}, - {WSA881X_BOOST_PRESET_OUT1 - WSA881X_ANALOG_BASE, 0x77}, - {WSA881X_BOOST_PRESET_OUT2 - WSA881X_ANALOG_BASE, 0x70}, - {WSA881X_BOOST_FORCE_OUT - WSA881X_ANALOG_BASE, 0x0E}, - {WSA881X_BOOST_LDO_PROG - WSA881X_ANALOG_BASE, 0x16}, - {WSA881X_BOOST_SLOPE_COMP_ISENSE_FB - WSA881X_ANALOG_BASE, 0x71}, - {WSA881X_BOOST_RON_CTL - WSA881X_ANALOG_BASE, 0x0F}, - {WSA881X_BOOST_LOOP_STABILITY - WSA881X_ANALOG_BASE, 0xAD}, - {WSA881X_BOOST_ZX_CTL - WSA881X_ANALOG_BASE, 0x34}, - {WSA881X_BOOST_START_CTL - WSA881X_ANALOG_BASE, 0x23}, - {WSA881X_BOOST_MISC1_CTL - WSA881X_ANALOG_BASE, 0x80}, - {WSA881X_BOOST_MISC2_CTL - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_BOOST_MISC3_CTL - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_BOOST_ATEST_CTL - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_SPKR_PROT_FE_GAIN - WSA881X_ANALOG_BASE, 0x46}, - {WSA881X_SPKR_PROT_FE_CM_LDO_SET - WSA881X_ANALOG_BASE, 0x3B}, - {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1 - WSA881X_ANALOG_BASE, 0x8D}, - {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2 - WSA881X_ANALOG_BASE, 0x8D}, - {WSA881X_SPKR_PROT_ATEST1 - WSA881X_ANALOG_BASE, 0x01}, - {WSA881X_SPKR_PROT_ATEST2 - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_SPKR_PROT_FE_VSENSE_VCM - WSA881X_ANALOG_BASE, 0x8D}, - {WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1 - WSA881X_ANALOG_BASE, 0x4D}, - {WSA881X_BONGO_RESRV_REG1 - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_BONGO_RESRV_REG2 - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_SPKR_PROT_SAR - WSA881X_ANALOG_BASE, 0x00}, - {WSA881X_SPKR_STATUS3 - WSA881X_ANALOG_BASE, 0x00}, -}; - -struct reg_default wsa881x_rev_2_0_dig[] = { - {WSA881X_RESET_CTL, 0x00}, - {WSA881X_TADC_VALUE_CTL, 0x01}, - {WSA881X_INTR_MASK, 0x1B}, - {WSA881X_IOPAD_CTL, 0x00}, - {WSA881X_OTP_REG_28, 0x3F}, - {WSA881X_OTP_REG_29, 0x3F}, - {WSA881X_OTP_REG_30, 0x01}, - {WSA881X_OTP_REG_31, 0x01}, -}; - -struct reg_default wsa881x_rev_2_0_ana[] = { - {WSA881X_TEMP_ADC_CTRL, 0x03}, - {WSA881X_ADC_SEL_IBIAS, 0x45}, - {WSA881X_SPKR_DRV_GAIN, 0xC1}, - {WSA881X_SPKR_DAC_CTL, 0x42}, - {WSA881X_SPKR_BBM_CTL, 0x02}, - {WSA881X_SPKR_MISC_CTL1, 0x40}, - {WSA881X_SPKR_MISC_CTL2, 0x07}, - {WSA881X_SPKR_BIAS_INT, 0x5F}, - {WSA881X_SPKR_BIAS_PSRR, 0x44}, - {WSA881X_BOOST_PS_CTL, 0xA0}, - {WSA881X_BOOST_PRESET_OUT1, 0xB7}, - {WSA881X_BOOST_LOOP_STABILITY, 0x8D}, - {WSA881X_SPKR_PROT_ATEST2, 0x02}, - {WSA881X_BONGO_RESRV_REG1, 0x5E}, - {WSA881X_BONGO_RESRV_REG2, 0x07}, -}; - -struct reg_default wsa881x_rev_2_0_regmap_ana[] = { - {WSA881X_TEMP_ADC_CTRL - WSA881X_ANALOG_BASE, 0x03}, - {WSA881X_ADC_SEL_IBIAS - WSA881X_ANALOG_BASE, 0x45}, - {WSA881X_SPKR_DRV_GAIN - WSA881X_ANALOG_BASE, 0xC1}, - {WSA881X_SPKR_DAC_CTL - WSA881X_ANALOG_BASE, 0x42}, - {WSA881X_SPKR_BBM_CTL - WSA881X_ANALOG_BASE, 0x02}, - {WSA881X_SPKR_MISC_CTL1 - WSA881X_ANALOG_BASE, 0x40}, - {WSA881X_SPKR_MISC_CTL2 - WSA881X_ANALOG_BASE, 0x07}, - {WSA881X_SPKR_BIAS_INT - WSA881X_ANALOG_BASE, 0x5F}, - {WSA881X_SPKR_BIAS_PSRR - WSA881X_ANALOG_BASE, 0x44}, - {WSA881X_BOOST_PS_CTL - WSA881X_ANALOG_BASE, 0xA0}, - {WSA881X_BOOST_PRESET_OUT1 - WSA881X_ANALOG_BASE, 0xB7}, - {WSA881X_BOOST_LOOP_STABILITY - WSA881X_ANALOG_BASE, 0x8D}, - {WSA881X_SPKR_PROT_ATEST2 - WSA881X_ANALOG_BASE, 0x02}, - {WSA881X_BONGO_RESRV_REG1 - WSA881X_ANALOG_BASE, 0x5E}, - {WSA881X_BONGO_RESRV_REG2 - WSA881X_ANALOG_BASE, 0x07}, -}; - -/** - * wsa881x_update_reg_defaults_2_0 - update default values of regs for v2.0 - * - * WSA881x v2.0 has different default values for certain analog and digital - * registers compared to v1.x. Therefore, update the values of these registers - * with the values from tables defined above for v2.0. - */ -void wsa881x_update_reg_defaults_2_0(void) -{ - int i, j; - - for (i = 0; i < ARRAY_SIZE(wsa881x_rev_2_0_dig); i++) { - for (j = 0; j < ARRAY_SIZE(wsa881x_ana_reg_defaults); j++) - if (wsa881x_ana_reg_defaults[j].reg == - wsa881x_rev_2_0_dig[i].reg) - wsa881x_ana_reg_defaults[j].def = - wsa881x_rev_2_0_dig[i].def; - } - for (i = 0; i < ARRAY_SIZE(wsa881x_rev_2_0_ana); i++) { - for (j = 0; j < ARRAY_SIZE(wsa881x_ana_reg_defaults); j++) - if (wsa881x_ana_reg_defaults[j].reg == - wsa881x_rev_2_0_ana[i].reg) - wsa881x_ana_reg_defaults[j].def = - wsa881x_rev_2_0_ana[i].def; - } -} -EXPORT_SYMBOL(wsa881x_update_reg_defaults_2_0); - -/** - * wsa881x_update_regmap_2_0 - update regmap framework with new tables - * @regmap: pointer to WSA881x regmap structure - * @flag: indicates digital or analog WSA881x slave - * - * WSA881x v2.0 has some new registers for both analog and digital slaves. - * Update the regmap framework with all the new registers. - */ -void wsa881x_update_regmap_2_0(struct regmap *regmap, int flag) -{ - u16 ret = 0; - - switch (flag) { - case WSA881X_DIGITAL_SLAVE: - ret = regmap_register_patch(regmap, wsa881x_rev_2_0_dig, - ARRAY_SIZE(wsa881x_rev_2_0_dig)); - break; - case WSA881X_ANALOG_SLAVE: - ret = regmap_register_patch(regmap, wsa881x_rev_2_0_ana, - ARRAY_SIZE(wsa881x_rev_2_0_ana)); - break; - default: - pr_debug("%s: unknown version", __func__); - ret = -EINVAL; - break; - } - if (ret) - pr_err("%s: Failed to update regmap defaults ret= %d\n", - __func__, ret); -} -EXPORT_SYMBOL(wsa881x_update_regmap_2_0); - -static bool wsa881x_readable_register(struct device *dev, unsigned int reg) -{ - return wsa881x_ana_reg_readable[reg]; -} - -static bool wsa881x_volatile_register(struct device *dev, unsigned int reg) -{ - switch (reg) { - case WSA881X_CHIP_ID0: - case WSA881X_CHIP_ID1: - case WSA881X_CHIP_ID2: - case WSA881X_CHIP_ID3: - case WSA881X_BUS_ID: - case WSA881X_TEMP_MSB: - case WSA881X_TEMP_LSB: - case WSA881X_SDM_PDM9_LSB: - case WSA881X_SDM_PDM9_MSB: - case WSA881X_OTP_REG_0: - case WSA881X_OTP_REG_1: - case WSA881X_OTP_REG_2: - case WSA881X_OTP_REG_3: - case WSA881X_OTP_REG_4: - case WSA881X_OTP_REG_5: - case WSA881X_OTP_REG_31: - case WSA881X_TEMP_DOUT_MSB: - case WSA881X_TEMP_DOUT_LSB: - case WSA881X_TEMP_OP: - case WSA881X_OTP_CTRL1: - case WSA881X_INTR_STATUS: - case WSA881X_ATE_TEST_MODE: - case WSA881X_PIN_STATUS: - case WSA881X_SWR_HM_TEST2: - case WSA881X_SPKR_STATUS1: - case WSA881X_SPKR_STATUS2: - case WSA881X_SPKR_STATUS3: - case WSA881X_SPKR_PROT_SAR: - return true; - default: - return false; - } -} - -struct regmap_config wsa881x_ana_regmap_config[] = { -{ - .reg_bits = 8, - .val_bits = 8, - .cache_type = REGCACHE_NONE, - .reg_defaults = wsa881x_ana_reg_defaults_0, - .num_reg_defaults = ARRAY_SIZE(wsa881x_ana_reg_defaults_0), - .max_register = WSA881X_MAX_REGISTER, - .volatile_reg = wsa881x_volatile_register, - .readable_reg = wsa881x_readable_register, - .reg_format_endian = REGMAP_ENDIAN_NATIVE, - .val_format_endian = REGMAP_ENDIAN_NATIVE, -}, -{ - .reg_bits = 8, - .val_bits = 8, - .cache_type = REGCACHE_NONE, - .reg_defaults = wsa881x_ana_reg_defaults_1, - .num_reg_defaults = ARRAY_SIZE(wsa881x_ana_reg_defaults_1), - .max_register = WSA881X_MAX_REGISTER, - .volatile_reg = wsa881x_volatile_register, - .readable_reg = wsa881x_readable_register, - .reg_format_endian = REGMAP_ENDIAN_NATIVE, - .val_format_endian = REGMAP_ENDIAN_NATIVE, -} -}; diff --git a/asoc/codecs/wsa881x-tables-analog.c b/asoc/codecs/wsa881x-tables-analog.c deleted file mode 100644 index 061ed6fff798..000000000000 --- a/asoc/codecs/wsa881x-tables-analog.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include "wsa881x-registers-analog.h" - -const u8 wsa881x_ana_reg_readable[WSA881X_CACHE_SIZE] = { - [WSA881X_CHIP_ID0] = 1, - [WSA881X_CHIP_ID1] = 1, - [WSA881X_CHIP_ID2] = 1, - [WSA881X_CHIP_ID3] = 1, - [WSA881X_BUS_ID] = 1, - [WSA881X_CDC_RST_CTL] = 1, - [WSA881X_CDC_TOP_CLK_CTL] = 1, - [WSA881X_CDC_ANA_CLK_CTL] = 1, - [WSA881X_CDC_DIG_CLK_CTL] = 1, - [WSA881X_CLOCK_CONFIG] = 1, - [WSA881X_ANA_CTL] = 1, - [WSA881X_SWR_RESET_EN] = 1, - [WSA881X_RESET_CTL] = 1, - [WSA881X_TADC_VALUE_CTL] = 1, - [WSA881X_TEMP_DETECT_CTL] = 1, - [WSA881X_TEMP_MSB] = 1, - [WSA881X_TEMP_LSB] = 1, - [WSA881X_TEMP_CONFIG0] = 1, - [WSA881X_TEMP_CONFIG1] = 1, - [WSA881X_CDC_CLIP_CTL] = 1, - [WSA881X_SDM_PDM9_LSB] = 1, - [WSA881X_SDM_PDM9_MSB] = 1, - [WSA881X_CDC_RX_CTL] = 1, - [WSA881X_DEM_BYPASS_DATA0] = 1, - [WSA881X_DEM_BYPASS_DATA1] = 1, - [WSA881X_DEM_BYPASS_DATA2] = 1, - [WSA881X_DEM_BYPASS_DATA3] = 1, - [WSA881X_OTP_CTRL0] = 1, - [WSA881X_OTP_CTRL1] = 1, - [WSA881X_HDRIVE_CTL_GROUP1] = 1, - [WSA881X_INTR_MODE] = 1, - [WSA881X_INTR_MASK] = 1, - [WSA881X_INTR_STATUS] = 1, - [WSA881X_INTR_CLEAR] = 1, - [WSA881X_INTR_LEVEL] = 1, - [WSA881X_INTR_SET] = 1, - [WSA881X_INTR_TEST] = 1, - [WSA881X_PDM_TEST_MODE] = 1, - [WSA881X_ATE_TEST_MODE] = 1, - [WSA881X_PIN_CTL_MODE] = 1, - [WSA881X_PIN_CTL_OE] = 1, - [WSA881X_PIN_WDATA_IOPAD] = 1, - [WSA881X_PIN_STATUS] = 1, - [WSA881X_DIG_DEBUG_MODE] = 1, - [WSA881X_DIG_DEBUG_SEL] = 1, - [WSA881X_DIG_DEBUG_EN] = 1, - [WSA881X_SWR_HM_TEST1] = 1, - [WSA881X_SWR_HM_TEST2] = 1, - [WSA881X_TEMP_DETECT_DBG_CTL] = 1, - [WSA881X_TEMP_DEBUG_MSB] = 1, - [WSA881X_TEMP_DEBUG_LSB] = 1, - [WSA881X_SAMPLE_EDGE_SEL] = 1, - [WSA881X_IOPAD_CTL] = 1, - [WSA881X_SPARE_0] = 1, - [WSA881X_SPARE_1] = 1, - [WSA881X_SPARE_2] = 1, - [WSA881X_OTP_REG_0] = 1, - [WSA881X_OTP_REG_1] = 1, - [WSA881X_OTP_REG_2] = 1, - [WSA881X_OTP_REG_3] = 1, - [WSA881X_OTP_REG_4] = 1, - [WSA881X_OTP_REG_5] = 1, - [WSA881X_OTP_REG_6] = 1, - [WSA881X_OTP_REG_7] = 1, - [WSA881X_OTP_REG_8] = 1, - [WSA881X_OTP_REG_9] = 1, - [WSA881X_OTP_REG_10] = 1, - [WSA881X_OTP_REG_11] = 1, - [WSA881X_OTP_REG_12] = 1, - [WSA881X_OTP_REG_13] = 1, - [WSA881X_OTP_REG_14] = 1, - [WSA881X_OTP_REG_15] = 1, - [WSA881X_OTP_REG_16] = 1, - [WSA881X_OTP_REG_17] = 1, - [WSA881X_OTP_REG_18] = 1, - [WSA881X_OTP_REG_19] = 1, - [WSA881X_OTP_REG_20] = 1, - [WSA881X_OTP_REG_21] = 1, - [WSA881X_OTP_REG_22] = 1, - [WSA881X_OTP_REG_23] = 1, - [WSA881X_OTP_REG_24] = 1, - [WSA881X_OTP_REG_25] = 1, - [WSA881X_OTP_REG_26] = 1, - [WSA881X_OTP_REG_27] = 1, - [WSA881X_OTP_REG_28] = 1, - [WSA881X_OTP_REG_29] = 1, - [WSA881X_OTP_REG_30] = 1, - [WSA881X_OTP_REG_31] = 1, - [WSA881X_OTP_REG_63] = 1, - /* Analog Registers */ - [WSA881X_BIAS_REF_CTRL] = 1, - [WSA881X_BIAS_TEST] = 1, - [WSA881X_BIAS_BIAS] = 1, - [WSA881X_TEMP_OP] = 1, - [WSA881X_TEMP_IREF_CTRL] = 1, - [WSA881X_TEMP_ISENS_CTRL] = 1, - [WSA881X_TEMP_CLK_CTRL] = 1, - [WSA881X_TEMP_TEST] = 1, - [WSA881X_TEMP_BIAS] = 1, - [WSA881X_TEMP_ADC_CTRL] = 1, - [WSA881X_TEMP_DOUT_MSB] = 1, - [WSA881X_TEMP_DOUT_LSB] = 1, - [WSA881X_ADC_EN_MODU_V] = 1, - [WSA881X_ADC_EN_MODU_I] = 1, - [WSA881X_ADC_EN_DET_TEST_V] = 1, - [WSA881X_ADC_EN_DET_TEST_I] = 1, - [WSA881X_ADC_SEL_IBIAS] = 1, - [WSA881X_ADC_EN_SEL_IBIAS] = 1, - [WSA881X_SPKR_DRV_EN] = 1, - [WSA881X_SPKR_DRV_GAIN] = 1, - [WSA881X_SPKR_DAC_CTL] = 1, - [WSA881X_SPKR_DRV_DBG] = 1, - [WSA881X_SPKR_PWRSTG_DBG] = 1, - [WSA881X_SPKR_OCP_CTL] = 1, - [WSA881X_SPKR_CLIP_CTL] = 1, - [WSA881X_SPKR_BBM_CTL] = 1, - [WSA881X_SPKR_MISC_CTL1] = 1, - [WSA881X_SPKR_MISC_CTL2] = 1, - [WSA881X_SPKR_BIAS_INT] = 1, - [WSA881X_SPKR_PA_INT] = 1, - [WSA881X_SPKR_BIAS_CAL] = 1, - [WSA881X_SPKR_BIAS_PSRR] = 1, - [WSA881X_SPKR_STATUS1] = 1, - [WSA881X_SPKR_STATUS2] = 1, - [WSA881X_BOOST_EN_CTL] = 1, - [WSA881X_BOOST_CURRENT_LIMIT] = 1, - [WSA881X_BOOST_PS_CTL] = 1, - [WSA881X_BOOST_PRESET_OUT1] = 1, - [WSA881X_BOOST_PRESET_OUT2] = 1, - [WSA881X_BOOST_FORCE_OUT] = 1, - [WSA881X_BOOST_LDO_PROG] = 1, - [WSA881X_BOOST_SLOPE_COMP_ISENSE_FB] = 1, - [WSA881X_BOOST_RON_CTL] = 1, - [WSA881X_BOOST_LOOP_STABILITY] = 1, - [WSA881X_BOOST_ZX_CTL] = 1, - [WSA881X_BOOST_START_CTL] = 1, - [WSA881X_BOOST_MISC1_CTL] = 1, - [WSA881X_BOOST_MISC2_CTL] = 1, - [WSA881X_BOOST_MISC3_CTL] = 1, - [WSA881X_BOOST_ATEST_CTL] = 1, - [WSA881X_SPKR_PROT_FE_GAIN] = 1, - [WSA881X_SPKR_PROT_FE_CM_LDO_SET] = 1, - [WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1] = 1, - [WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2] = 1, - [WSA881X_SPKR_PROT_ATEST1] = 1, - [WSA881X_SPKR_PROT_ATEST2] = 1, - [WSA881X_SPKR_PROT_FE_VSENSE_VCM] = 1, - [WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1] = 1, - [WSA881X_BONGO_RESRV_REG1] = 1, - [WSA881X_BONGO_RESRV_REG2] = 1, - [WSA881X_SPKR_PROT_SAR] = 1, - [WSA881X_SPKR_STATUS3] = 1, -}; diff --git a/asoc/msm-audio-pinctrl.c b/asoc/msm-audio-pinctrl.c deleted file mode 100644 index f0fba840eb2d..000000000000 --- a/asoc/msm-audio-pinctrl.c +++ /dev/null @@ -1,316 +0,0 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include "msm-audio-pinctrl.h" - -/* - * pinctrl -- handle to query pinctrl apis - * cdc lines -- stores pinctrl handles for pinctrl states - * active_set -- maintain the overall pinctrl state - */ -struct cdc_pinctrl_info { - struct pinctrl *pinctrl; - struct pinctrl_state **cdc_lines; - int active_set; -}; - -/* - * gpiosets -- stores all gpiosets mentioned in dtsi file - * gpiosets_comb_names -- stores all possible gpioset combinations - * gpioset_state -- maintains counter for each gpioset - * gpiosets_max -- maintain the total supported gpiosets - * gpiosets_comb_max -- maintain the total gpiosets combinations - */ -struct cdc_gpioset_info { - char **gpiosets; - char **gpiosets_comb_names; - uint8_t *gpioset_state; - int gpiosets_max; - int gpiosets_comb_max; -}; - -static struct cdc_pinctrl_info pinctrl_info[MAX_PINCTRL_CLIENT]; -static struct cdc_gpioset_info gpioset_info[MAX_PINCTRL_CLIENT]; - -/* Finds the index for the gpio set in the dtsi file */ -int msm_get_gpioset_index(enum pinctrl_client client, char *keyword) -{ - int i; - - for (i = 0; i < gpioset_info[client].gpiosets_max; i++) { - if (!(strcmp(gpioset_info[client].gpiosets[i], keyword))) - break; - } - /* Checking if the keyword is present in dtsi or not */ - if (i != gpioset_info[client].gpiosets_max) - return i; - else - return -EINVAL; -} - -/* - * This function reads the following from dtsi file - * 1. All gpio sets - * 2. All combinations of gpio sets - * 3. Pinctrl handles to gpio sets - * - * Returns error if there is - * 1. Problem reading from dtsi file - * 2. Memory allocation failure - */ -int msm_gpioset_initialize(enum pinctrl_client client, - struct device *dev) -{ - struct pinctrl *pinctrl; - const char *gpioset_names = "qcom,msm-gpios"; - const char *gpioset_combinations = "qcom,pinctrl-names"; - const char *gpioset_names_str = NULL; - const char *gpioset_comb_str = NULL; - int num_strings = 0; - int ret = 0; - int i = 0; - - pr_debug("%s\n", __func__); - pinctrl = devm_pinctrl_get(dev); - if (IS_ERR(pinctrl)) { - pr_err("%s: Unable to get pinctrl handle\n", - __func__); - return -EINVAL; - } - pinctrl_info[client].pinctrl = pinctrl; - - /* Reading of gpio sets */ - num_strings = of_property_count_strings(dev->of_node, - gpioset_names); - if (num_strings < 0) { - dev_err(dev, - "%s: missing %s in dt node or length is incorrect\n", - __func__, gpioset_names); - goto err; - } - gpioset_info[client].gpiosets_max = num_strings; - gpioset_info[client].gpiosets = devm_kzalloc(dev, - gpioset_info[client].gpiosets_max * - sizeof(char *), GFP_KERNEL); - if (!gpioset_info[client].gpiosets) { - dev_err(dev, "Can't allocate memory for gpio set names\n"); - ret = -ENOMEM; - goto err; - } - - for (i = 0; i < num_strings; i++) { - ret = of_property_read_string_index(dev->of_node, - gpioset_names, i, &gpioset_names_str); - - gpioset_info[client].gpiosets[i] = devm_kzalloc(dev, - (strlen(gpioset_names_str) + 1), GFP_KERNEL); - - if (!gpioset_info[client].gpiosets[i]) { - dev_err(dev, "%s: Can't allocate gpiosets[%d] data\n", - __func__, i); - ret = -ENOMEM; - goto err; - } - strlcpy(gpioset_info[client].gpiosets[i], - gpioset_names_str, strlen(gpioset_names_str)+1); - gpioset_names_str = NULL; - } - num_strings = 0; - - /* Allocating memory for gpio set counter */ - gpioset_info[client].gpioset_state = devm_kzalloc(dev, - gpioset_info[client].gpiosets_max * - sizeof(uint8_t), GFP_KERNEL); - if (!gpioset_info[client].gpioset_state) { - dev_err(dev, "Can't allocate memory for gpio set counter\n"); - ret = -ENOMEM; - goto err; - } - - /* Reading of all combinations of gpio sets */ - num_strings = of_property_count_strings(dev->of_node, - gpioset_combinations); - if (num_strings < 0) { - dev_err(dev, - "%s: missing %s in dt node or length is incorrect\n", - __func__, gpioset_combinations); - goto err; - } - gpioset_info[client].gpiosets_comb_max = num_strings; - gpioset_info[client].gpiosets_comb_names = devm_kzalloc(dev, - num_strings * sizeof(char *), GFP_KERNEL); - if (!gpioset_info[client].gpiosets_comb_names) { - ret = -ENOMEM; - goto err; - } - - for (i = 0; i < gpioset_info[client].gpiosets_comb_max; i++) { - ret = of_property_read_string_index(dev->of_node, - gpioset_combinations, i, &gpioset_comb_str); - - gpioset_info[client].gpiosets_comb_names[i] = devm_kzalloc(dev, - (strlen(gpioset_comb_str) + 1), GFP_KERNEL); - if (!gpioset_info[client].gpiosets_comb_names[i]) { - ret = -ENOMEM; - goto err; - } - - strlcpy(gpioset_info[client].gpiosets_comb_names[i], - gpioset_comb_str, - strlen(gpioset_comb_str)+1); - pr_debug("%s: GPIO configuration %s\n", - __func__, - gpioset_info[client].gpiosets_comb_names[i]); - gpioset_comb_str = NULL; - } - - /* Allocating memory for handles to pinctrl states */ - pinctrl_info[client].cdc_lines = devm_kzalloc(dev, - num_strings * sizeof(char *), GFP_KERNEL); - if (!pinctrl_info[client].cdc_lines) { - ret = -ENOMEM; - goto err; - } - - /* Get pinctrl handles for gpio sets in dtsi file */ - for (i = 0; i < num_strings; i++) { - pinctrl_info[client].cdc_lines[i] = pinctrl_lookup_state( - pinctrl, - (const char *)gpioset_info[client]. - gpiosets_comb_names[i]); - if (IS_ERR(pinctrl_info[client].cdc_lines[i])) - pr_err("%s: Unable to get pinctrl handle for %s\n", - __func__, gpioset_info[client]. - gpiosets_comb_names[i]); - } - goto success; - -err: - /* Free up memory allocated for gpio set combinations */ - for (i = 0; i < gpioset_info[client].gpiosets_max; i++) { - if (gpioset_info[client].gpiosets[i] != NULL) { - devm_kfree(dev, gpioset_info[client].gpiosets[i]); - gpioset_info[client].gpiosets[i] = NULL; - } - } - if (gpioset_info[client].gpiosets != NULL) { - devm_kfree(dev, gpioset_info[client].gpiosets); - gpioset_info[client].gpiosets = NULL; - } - - /* Free up memory allocated for gpio set combinations */ - for (i = 0; i < gpioset_info[client].gpiosets_comb_max; i++) { - if (gpioset_info[client].gpiosets_comb_names[i] != NULL) { - devm_kfree(dev, - gpioset_info[client].gpiosets_comb_names[i]); - gpioset_info[client].gpiosets_comb_names[i] = NULL; - } - } - if (gpioset_info[client].gpiosets_comb_names != NULL) { - devm_kfree(dev, gpioset_info[client].gpiosets_comb_names); - gpioset_info[client].gpiosets_comb_names = NULL; - } - - /* Free up memory allocated for handles to pinctrl states */ - if (pinctrl_info[client].cdc_lines != NULL) { - devm_kfree(dev, pinctrl_info[client].cdc_lines); - pinctrl_info[client].cdc_lines = NULL; - } - - /* Free up memory allocated for counter of gpio sets */ - if (gpioset_info[client].gpioset_state != NULL) { - devm_kfree(dev, gpioset_info[client].gpioset_state); - gpioset_info[client].gpioset_state = NULL; - } - -success: - return ret; -} - -int msm_gpioset_activate(enum pinctrl_client client, char *keyword) -{ - int ret = 0; - int gp_set = 0; - int active_set = 0; - - gp_set = msm_get_gpioset_index(client, keyword); - if (gp_set < 0) { - pr_err("%s: gpio set name does not exist\n", - __func__); - return gp_set; - } - - if (!gpioset_info[client].gpioset_state[gp_set]) { - /* - * If pinctrl pointer is not valid, - * no need to proceed further - */ - active_set = pinctrl_info[client].active_set; - if (IS_ERR(pinctrl_info[client].cdc_lines[active_set])) - return 0; - - pinctrl_info[client].active_set |= (1 << gp_set); - active_set = pinctrl_info[client].active_set; - pr_debug("%s: pinctrl.active_set: %d\n", __func__, active_set); - - /* Select the appropriate pinctrl state */ - ret = pinctrl_select_state(pinctrl_info[client].pinctrl, - pinctrl_info[client].cdc_lines[active_set]); - } - gpioset_info[client].gpioset_state[gp_set]++; - - return ret; -} - -int msm_gpioset_suspend(enum pinctrl_client client, char *keyword) -{ - int ret = 0; - int gp_set = 0; - int active_set = 0; - - gp_set = msm_get_gpioset_index(client, keyword); - if (gp_set < 0) { - pr_err("%s: gpio set name does not exist\n", - __func__); - return gp_set; - } - - if (gpioset_info[client].gpioset_state[gp_set] == 1) { - pinctrl_info[client].active_set &= ~(1 << gp_set); - /* - * If pinctrl pointer is not valid, - * no need to proceed further - */ - active_set = pinctrl_info[client].active_set; - if (IS_ERR(pinctrl_info[client].cdc_lines[active_set])) - return -EINVAL; - - pr_debug("%s: pinctrl.active_set: %d\n", __func__, - pinctrl_info[client].active_set); - /* Select the appropriate pinctrl state */ - ret = pinctrl_select_state(pinctrl_info[client].pinctrl, - pinctrl_info[client].cdc_lines[pinctrl_info[client]. - active_set]); - } - if (!(gpioset_info[client].gpioset_state[gp_set])) { - pr_err("%s: Invalid call to de activate gpios: %d\n", __func__, - gpioset_info[client].gpioset_state[gp_set]); - return -EINVAL; - } - - gpioset_info[client].gpioset_state[gp_set]--; - - return ret; -} diff --git a/asoc/msm-audio-pinctrl.h b/asoc/msm-audio-pinctrl.h deleted file mode 100644 index ec7c6aafdaea..000000000000 --- a/asoc/msm-audio-pinctrl.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __MSM_AUDIO_PINCTRL_H -#define __MSM_AUDIO_PINCTRL_H - -enum pinctrl_client { - CLIENT_WCD, - CLIENT_WSA_BONGO_1, - CLIENT_WSA_BONGO_2, - MAX_PINCTRL_CLIENT, -}; - - -/* finds the index for the gpio set in the dtsi file */ -int msm_get_gpioset_index(enum pinctrl_client client, char *keyword); - -/* - * this function reads the following from dtsi file - * 1. all gpio sets - * 2. all combinations of gpio sets - * 3. pinctrl handles to gpio sets - * - * returns error if there is - * 1. problem reading from dtsi file - * 2. memory allocation failure - */ -int msm_gpioset_initialize(enum pinctrl_client client, struct device *dev); - -int msm_gpioset_activate(enum pinctrl_client client, char *keyword); - -int msm_gpioset_suspend(enum pinctrl_client client, char *keyword); - -#endif /* __MSM_AUDIO_PINCTRL_H */ diff --git a/asoc/msm8996.c b/asoc/msm8996.c deleted file mode 100644 index 08900372a2c2..000000000000 --- a/asoc/msm8996.c +++ /dev/null @@ -1,4007 +0,0 @@ -/* - * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "qdsp6v2/msm-pcm-routing-v2.h" -#include "../codecs/wcd9xxx-common.h" -#include "../codecs/wcd9330.h" -#include "../codecs/wcd9335.h" -#include "../codecs/wsa881x.h" - -#define DRV_NAME "msm8996-asoc-snd" - -#define SAMPLING_RATE_8KHZ 8000 -#define SAMPLING_RATE_16KHZ 16000 -#define SAMPLING_RATE_32KHZ 32000 -#define SAMPLING_RATE_48KHZ 48000 -#define SAMPLING_RATE_96KHZ 96000 -#define SAMPLING_RATE_192KHZ 192000 -#define SAMPLING_RATE_44P1KHZ 44100 - -#define MSM8996_SPK_ON 1 -#define MSM8996_HIFI_ON 1 - -#define WCD9XXX_MBHC_DEF_BUTTONS 8 -#define WCD9XXX_MBHC_DEF_RLOADS 5 -#define CODEC_EXT_CLK_RATE 9600000 -#define ADSP_STATE_READY_TIMEOUT_MS 3000 -#define DEV_NAME_STR_LEN 32 - -#define WSA8810_NAME_1 "wsa881x.20170211" -#define WSA8810_NAME_2 "wsa881x.20170212" - -static int slim0_rx_sample_rate = SAMPLING_RATE_48KHZ; -static int slim0_tx_sample_rate = SAMPLING_RATE_48KHZ; -static int slim1_tx_sample_rate = SAMPLING_RATE_48KHZ; -static int slim0_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; -static int slim0_tx_bit_format = SNDRV_PCM_FORMAT_S16_LE; -static int slim1_tx_bit_format = SNDRV_PCM_FORMAT_S16_LE; -static int hdmi_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; -static int msm8996_auxpcm_rate = SAMPLING_RATE_8KHZ; -static int slim5_rx_sample_rate = SAMPLING_RATE_48KHZ; -static int slim5_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; -static int slim6_rx_sample_rate = SAMPLING_RATE_48KHZ; -static int slim6_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; - -static struct platform_device *spdev; -static int ext_us_amp_gpio = -1; -static int msm8996_spk_control = 1; -static int msm_slim_0_rx_ch = 1; -static int msm_slim_0_tx_ch = 1; -static int msm_slim_1_tx_ch = 1; -static int msm_slim_5_rx_ch = 1; -static int msm_slim_6_rx_ch = 1; -static int msm_hifi_control; -static int msm_vi_feed_tx_ch = 2; - -static int msm_hdmi_rx_ch = 2; -static int msm_proxy_rx_ch = 2; -static int hdmi_rx_sample_rate = SAMPLING_RATE_48KHZ; -static int msm_tert_mi2s_tx_ch = 2; - -static bool codec_reg_done; - -static const char *const hifi_function[] = {"Off", "On"}; -static const char *const pin_states[] = {"Disable", "active"}; -static const char *const spk_function[] = {"Off", "On"}; -static const char *const slim0_rx_ch_text[] = {"One", "Two"}; -static const char *const slim5_rx_ch_text[] = {"One", "Two"}; -static const char *const slim6_rx_ch_text[] = {"One", "Two"}; -static const char *const slim0_tx_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", - "Eight"}; -static const char *const vi_feed_ch_text[] = {"One", "Two"}; -static char const *hdmi_rx_ch_text[] = {"Two", "Three", "Four", "Five", - "Six", "Seven", "Eight"}; -static char const *rx_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"}; -static char const *slim5_rx_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"}; -static char const *slim6_rx_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"}; -static char const *slim0_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96", - "KHZ_192", "KHZ_44P1", "KHZ_8", - "KHZ_16", "KHZ_32"}; -static char const *slim5_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96", - "KHZ_192", "KHZ_44P1"}; -static char const *slim6_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96", - "KHZ_192", "KHZ_44P1"}; -static const char *const proxy_rx_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", "Eight"}; - -static char const *hdmi_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96", - "KHZ_192"}; - -static const char *const auxpcm_rate_text[] = {"8000", "16000"}; -static const struct soc_enum msm8996_auxpcm_enum[] = { - SOC_ENUM_SINGLE_EXT(2, auxpcm_rate_text), -}; - -static struct afe_clk_set mi2s_tx_clk = { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, -}; - -struct msm8996_wsa881x_dev_info { - struct device_node *of_node; - u32 index; -}; - -static struct snd_soc_aux_dev *msm8996_aux_dev; -static struct snd_soc_codec_conf *msm8996_codec_conf; - -struct msm8996_asoc_mach_data { - u32 mclk_freq; - int us_euro_gpio; - int hph_en1_gpio; - int hph_en0_gpio; - struct snd_info_entry *codec_root; -}; - -struct msm8996_asoc_wcd93xx_codec { - void* (*get_afe_config_fn)(struct snd_soc_codec *codec, - enum afe_config_type config_type); - void (*mbhc_hs_detect_exit)(struct snd_soc_codec *codec); -}; - -static struct msm8996_asoc_wcd93xx_codec msm8996_codec_fn; - -struct msm8996_liquid_dock_dev { - int dock_plug_gpio; - int dock_plug_irq; - int dock_plug_det; - struct work_struct irq_work; - struct switch_dev audio_sdev; -}; -static struct msm8996_liquid_dock_dev *msm8996_liquid_dock_dev; - -static void *adsp_state_notifier; -static void *def_tasha_mbhc_cal(void); -static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, - int enable, bool dapm); -static int msm8996_wsa881x_init(struct snd_soc_component *component); - -/* - * Need to report LINEIN - * if R/L channel impedance is larger than 5K ohm - */ -static struct wcd_mbhc_config wcd_mbhc_cfg = { - .read_fw_bin = false, - .calibration = NULL, - .detect_extn_cable = true, - .mono_stero_detection = false, - .swap_gnd_mic = NULL, - .hs_ext_micbias = true, - .key_code[0] = KEY_MEDIA, - .key_code[1] = KEY_VOICECOMMAND, - .key_code[2] = KEY_VOLUMEUP, - .key_code[3] = KEY_VOLUMEDOWN, - .key_code[4] = 0, - .key_code[5] = 0, - .key_code[6] = 0, - .key_code[7] = 0, - .linein_th = 5000, - .moisture_en = true, - .mbhc_micbias = MIC_BIAS_2, - .anc_micbias = MIC_BIAS_2, - .enable_anc_mic_detect = false, -}; - -static inline int param_is_mask(int p) -{ - return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && - (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); -} - -static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, - int n) -{ - return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); -} - -static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit) -{ - if (bit >= SNDRV_MASK_MAX) - return; - if (param_is_mask(n)) { - struct snd_mask *m = param_to_mask(p, n); - - m->bits[0] = 0; - m->bits[1] = 0; - m->bits[bit >> 5] |= (1 << (bit & 31)); - } -} - -static void msm8996_liquid_docking_irq_work(struct work_struct *work) -{ - struct msm8996_liquid_dock_dev *dock_dev = - container_of(work, struct msm8996_liquid_dock_dev, - irq_work); - - dock_dev->dock_plug_det = - gpio_get_value(dock_dev->dock_plug_gpio); - - switch_set_state(&dock_dev->audio_sdev, dock_dev->dock_plug_det); - /* notify to audio daemon */ - sysfs_notify(&dock_dev->audio_sdev.dev->kobj, NULL, "state"); -} - -static irqreturn_t msm8996_liquid_docking_irq_handler(int irq, void *dev) -{ - struct msm8996_liquid_dock_dev *dock_dev = dev; - - /* switch speakers should not run in interrupt context */ - schedule_work(&dock_dev->irq_work); - return IRQ_HANDLED; -} - -static int msm8996_liquid_init_docking(void) -{ - int ret = 0; - int dock_plug_gpio = 0; - - /* plug in docking speaker+plug in device OR unplug one of them */ - u32 dock_plug_irq_flags = IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING | - IRQF_SHARED; - - dock_plug_gpio = of_get_named_gpio(spdev->dev.of_node, - "qcom,dock-plug-det-irq", 0); - - if (dock_plug_gpio >= 0) { - msm8996_liquid_dock_dev = - kzalloc(sizeof(*msm8996_liquid_dock_dev), GFP_KERNEL); - if (!msm8996_liquid_dock_dev) { - ret = -ENOMEM; - goto exit; - } - - msm8996_liquid_dock_dev->dock_plug_gpio = dock_plug_gpio; - - ret = gpio_request(msm8996_liquid_dock_dev->dock_plug_gpio, - "dock-plug-det-irq"); - if (ret) { - pr_err("%s:failed request msm8996_liquid_dock_plug_gpio err = %d\n", - __func__, ret); - ret = -EINVAL; - goto fail_dock_gpio; - } - - msm8996_liquid_dock_dev->dock_plug_det = - gpio_get_value( - msm8996_liquid_dock_dev->dock_plug_gpio); - msm8996_liquid_dock_dev->dock_plug_irq = - gpio_to_irq( - msm8996_liquid_dock_dev->dock_plug_gpio); - - ret = request_irq(msm8996_liquid_dock_dev->dock_plug_irq, - msm8996_liquid_docking_irq_handler, - dock_plug_irq_flags, - "liquid_dock_plug_irq", - msm8996_liquid_dock_dev); - if (ret < 0) { - pr_err("%s: Request Irq Failed err = %d\n", - __func__, ret); - goto fail_dock_gpio; - } - - msm8996_liquid_dock_dev->audio_sdev.name = - QC_AUDIO_EXTERNAL_SPK_1_EVENT; - - if (switch_dev_register( - &msm8996_liquid_dock_dev->audio_sdev) < 0) { - pr_err("%s: dock device register in switch diretory failed\n", - __func__); - goto fail_switch_dev; - } - - INIT_WORK( - &msm8996_liquid_dock_dev->irq_work, - msm8996_liquid_docking_irq_work); - } - return 0; - -fail_switch_dev: - free_irq(msm8996_liquid_dock_dev->dock_plug_irq, - msm8996_liquid_dock_dev); -fail_dock_gpio: - gpio_free(msm8996_liquid_dock_dev->dock_plug_gpio); -exit: - kfree(msm8996_liquid_dock_dev); - msm8996_liquid_dock_dev = NULL; - return ret; -} - -static void msm8996_ext_control(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - - pr_debug("%s: msm8996_spk_control = %d", __func__, - msm8996_spk_control); - if (msm8996_spk_control == MSM8996_SPK_ON) { - snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp"); - snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp"); - } else { - snd_soc_dapm_disable_pin(dapm, "Lineout_1 amp"); - snd_soc_dapm_disable_pin(dapm, "Lineout_2 amp"); - } - snd_soc_dapm_sync(dapm); -} - -static int msm8996_get_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm8996_spk_control = %d\n", - __func__, msm8996_spk_control); - ucontrol->value.integer.value[0] = msm8996_spk_control; - return 0; -} - -static int msm8996_set_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - - pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - if (msm8996_spk_control == ucontrol->value.integer.value[0]) - return 0; - - msm8996_spk_control = ucontrol->value.integer.value[0]; - msm8996_ext_control(codec); - return 1; -} - -static int msm8996_hifi_ctrl(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct snd_soc_card *card = codec->component.card; - struct msm8996_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - - pr_debug("%s: msm_hifi_control = %d", __func__, - msm_hifi_control); - if (pdata->hph_en1_gpio < 0) { - pr_err("%s: hph_en1_gpio is invalid\n", __func__); - return -EINVAL; - } - if (msm_hifi_control == MSM8996_HIFI_ON) { - gpio_direction_output(pdata->hph_en1_gpio, 1); - /* 5msec delay needed as per HW requirement */ - usleep_range(5000, 5010); - } else { - gpio_direction_output(pdata->hph_en1_gpio, 0); - } - snd_soc_dapm_sync(dapm); - return 0; -} - -static int msm8996_hifi_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_hifi_control = %d\n", - __func__, msm_hifi_control); - ucontrol->value.integer.value[0] = msm_hifi_control; - return 0; -} - -static int msm8996_hifi_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - - pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - msm_hifi_control = ucontrol->value.integer.value[0]; - msm8996_hifi_ctrl(codec); - return 1; -} - -static int msm8996_ext_us_amp_init(void) -{ - int ret = 0; - - ext_us_amp_gpio = of_get_named_gpio(spdev->dev.of_node, - "qcom,ext-ult-spk-amp-gpio", 0); - if (ext_us_amp_gpio >= 0) { - ret = gpio_request(ext_us_amp_gpio, "ext_us_amp_gpio"); - if (ret) { - pr_err("%s: ext_us_amp_gpio request failed, ret:%d\n", - __func__, ret); - return ret; - } - gpio_direction_output(ext_us_amp_gpio, 0); - } - return ret; -} - -static void msm8996_ext_us_amp_enable(u32 on) -{ - if (on) - gpio_direction_output(ext_us_amp_gpio, 1); - else - gpio_direction_output(ext_us_amp_gpio, 0); - - pr_debug("%s: US Emitter GPIO enable:%s\n", __func__, - on ? "Enable" : "Disable"); -} - -static int msm_ext_ultrasound_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - pr_debug("%s()\n", __func__); - if (strcmp(w->name, "ultrasound amp")) { - if (!gpio_is_valid(ext_us_amp_gpio)) { - pr_err("%s: ext_us_amp_gpio isn't configured\n", - __func__); - return -EINVAL; - } - if (SND_SOC_DAPM_EVENT_ON(event)) - msm8996_ext_us_amp_enable(1); - else - msm8996_ext_us_amp_enable(0); - } else { - pr_err("%s() Invalid Widget = %s\n", - __func__, w->name); - return -EINVAL; - } - return 0; -} - -static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, - int enable, bool dapm) -{ - int ret = 0; - - if (!strcmp(dev_name(codec->dev), "tasha_codec")) { - ret = tasha_cdc_mclk_enable(codec, enable, dapm); - } else { - dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", - __func__); - ret = -EINVAL; - } - - return ret; -} - -static int msm8996_mclk_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - pr_debug("%s: event = %d\n", __func__, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - return msm_snd_enable_codec_ext_clk(codec, 1, true); - case SND_SOC_DAPM_POST_PMD: - return msm_snd_enable_codec_ext_clk(codec, 0, true); - } - return 0; -} - -static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, - int enable, bool dapm) -{ - int ret = 0; - - if (!strcmp(dev_name(codec->dev), "tasha_codec")) - ret = tasha_cdc_mclk_tx_enable(codec, enable, dapm); - else { - dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", - __func__); - ret = -EINVAL; - } - return ret; -} - -static int msm8996_mclk_tx_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - pr_debug("%s: event = %d\n", __func__, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - return msm_snd_enable_codec_ext_tx_clk(codec, 1, true); - case SND_SOC_DAPM_POST_PMD: - return msm_snd_enable_codec_ext_tx_clk(codec, 0, true); - } - return 0; -} - -static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct snd_soc_card *card = codec->component.card; - struct msm8996_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - int ret = 0; - - pr_debug("%s: msm_hifi_control = %d", __func__, - msm_hifi_control); - switch (event) { - case SND_SOC_DAPM_POST_PMU: - if (msm_hifi_control == MSM8996_HIFI_ON) { - if (pdata->hph_en0_gpio < 0) { - pr_err("%s: hph_en0_gpio is invalid\n", - __func__); - ret = -EINVAL; - goto err; - } - gpio_direction_output(pdata->hph_en0_gpio, 1); - } - break; - case SND_SOC_DAPM_PRE_PMD: - if (msm_hifi_control == MSM8996_HIFI_ON) { - if (pdata->hph_en0_gpio < 0) { - pr_err("%s: hph_en0_gpio is invalid\n", - __func__); - ret = -EINVAL; - goto err; - } - gpio_direction_output(pdata->hph_en0_gpio, 0); - } - break; - } -err: - return ret; -} - -static const struct snd_soc_dapm_widget msm8996_dapm_widgets[] = { - - SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, - msm8996_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0, - msm8996_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SPK("Lineout_1 amp", NULL), - SND_SOC_DAPM_SPK("Lineout_3 amp", NULL), - SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), - SND_SOC_DAPM_SPK("Lineout_4 amp", NULL), - SND_SOC_DAPM_SPK("ultrasound amp", msm_ext_ultrasound_event), - SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event), - SND_SOC_DAPM_MIC("Handset Mic", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), - SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL), - SND_SOC_DAPM_MIC("Analog Mic4", NULL), - SND_SOC_DAPM_MIC("Analog Mic6", NULL), - SND_SOC_DAPM_MIC("Analog Mic7", NULL), - SND_SOC_DAPM_MIC("Analog Mic8", NULL), - - SND_SOC_DAPM_MIC("Digital Mic0", NULL), - SND_SOC_DAPM_MIC("Digital Mic1", NULL), - SND_SOC_DAPM_MIC("Digital Mic2", NULL), - SND_SOC_DAPM_MIC("Digital Mic3", NULL), - SND_SOC_DAPM_MIC("Digital Mic4", NULL), - SND_SOC_DAPM_MIC("Digital Mic5", NULL), - SND_SOC_DAPM_MIC("Digital Mic6", NULL), -}; - -static struct snd_soc_dapm_route wcd9335_audio_paths[] = { - {"MIC BIAS1", NULL, "MCLK TX"}, - {"MIC BIAS2", NULL, "MCLK TX"}, - {"MIC BIAS3", NULL, "MCLK TX"}, - {"MIC BIAS4", NULL, "MCLK TX"}, -}; - -static int slim5_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val = 0; - - switch (slim5_rx_sample_rate) { - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 3; - break; - - case SAMPLING_RATE_192KHZ: - sample_rate_val = 2; - break; - - case SAMPLING_RATE_96KHZ: - sample_rate_val = 1; - break; - - case SAMPLING_RATE_48KHZ: - default: - sample_rate_val = 0; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: slim5_rx_sample_rate = %d\n", __func__, - slim5_rx_sample_rate); - - return 0; -} - -static int slim5_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: ucontrol value = %ld\n", __func__, - ucontrol->value.integer.value[0]); - - switch (ucontrol->value.integer.value[0]) { - case 3: - slim5_rx_sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 2: - slim5_rx_sample_rate = SAMPLING_RATE_192KHZ; - break; - case 1: - slim5_rx_sample_rate = SAMPLING_RATE_96KHZ; - break; - case 0: - default: - slim5_rx_sample_rate = SAMPLING_RATE_48KHZ; - } - - pr_debug("%s: slim5_rx_sample_rate = %d\n", __func__, - slim5_rx_sample_rate); - - return 0; -} - -static int slim6_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val = 0; - - switch (slim6_rx_sample_rate) { - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 3; - break; - - case SAMPLING_RATE_192KHZ: - sample_rate_val = 2; - break; - - case SAMPLING_RATE_96KHZ: - sample_rate_val = 1; - break; - - case SAMPLING_RATE_48KHZ: - default: - sample_rate_val = 0; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: slim6_rx_sample_rate = %d\n", __func__, - slim6_rx_sample_rate); - - return 0; -} - -static int slim6_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 3: - slim6_rx_sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 2: - slim6_rx_sample_rate = SAMPLING_RATE_192KHZ; - break; - case 1: - slim6_rx_sample_rate = SAMPLING_RATE_96KHZ; - break; - case 0: - default: - slim6_rx_sample_rate = SAMPLING_RATE_48KHZ; - break; - } - - pr_debug("%s: ucontrol value = %ld, slim6_rx_sample_rate = %d\n", - __func__, ucontrol->value.integer.value[0], - slim6_rx_sample_rate); - - return 0; -} - -static int slim0_tx_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (slim0_tx_bit_format) { - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: slim0_tx_bit_format = %d, ucontrol value = %ld\n", - __func__, slim0_tx_bit_format, - ucontrol->value.integer.value[0]); - return 0; -} - -static int slim0_tx_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int rc = 0; - - switch (ucontrol->value.integer.value[0]) { - case 2: - slim0_tx_bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - slim0_tx_bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - slim0_tx_bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - default: - pr_err("%s: invalid value %ld\n", __func__, - ucontrol->value.integer.value[0]); - rc = -EINVAL; - break; - } - - pr_debug("%s: ucontrol value = %ld, slim0_tx_bit_format = %d\n", - __func__, ucontrol->value.integer.value[0], - slim0_tx_bit_format); - - return rc; -} - -static int slim0_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val = 0; - - switch (slim0_rx_sample_rate) { - case SAMPLING_RATE_32KHZ: - sample_rate_val = 6; - break; - - case SAMPLING_RATE_16KHZ: - sample_rate_val = 5; - break; - - case SAMPLING_RATE_8KHZ: - sample_rate_val = 4; - break; - - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 3; - break; - - case SAMPLING_RATE_192KHZ: - sample_rate_val = 2; - break; - - case SAMPLING_RATE_96KHZ: - sample_rate_val = 1; - break; - - case SAMPLING_RATE_48KHZ: - default: - sample_rate_val = 0; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: slim0_rx_sample_rate = %d\n", __func__, - slim0_rx_sample_rate); - - return 0; -} - -static int slim0_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: ucontrol value = %ld\n", __func__, - ucontrol->value.integer.value[0]); - - switch (ucontrol->value.integer.value[0]) { - case 6: - slim0_rx_sample_rate = SAMPLING_RATE_32KHZ; - break; - case 5: - slim0_rx_sample_rate = SAMPLING_RATE_16KHZ; - break; - case 4: - slim0_rx_sample_rate = SAMPLING_RATE_8KHZ; - break; - case 3: - slim0_rx_sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 2: - slim0_rx_sample_rate = SAMPLING_RATE_192KHZ; - break; - case 1: - slim0_rx_sample_rate = SAMPLING_RATE_96KHZ; - break; - case 0: - default: - slim0_rx_sample_rate = SAMPLING_RATE_48KHZ; - } - - pr_debug("%s: slim0_rx_sample_rate = %d\n", __func__, - slim0_rx_sample_rate); - - return 0; -} - -static int slim0_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val = 0; - - switch (slim0_tx_sample_rate) { - case SAMPLING_RATE_192KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_48KHZ: - default: - sample_rate_val = 0; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: slim0_tx_sample_rate = %d\n", __func__, - slim0_tx_sample_rate); - return 0; -} - -static int slim0_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int rc = 0; - - pr_debug("%s: ucontrol value = %ld\n", __func__, - ucontrol->value.integer.value[0]); - - switch (ucontrol->value.integer.value[0]) { - case 2: - slim0_tx_sample_rate = SAMPLING_RATE_192KHZ; - break; - case 1: - slim0_tx_sample_rate = SAMPLING_RATE_96KHZ; - break; - case 0: - slim0_tx_sample_rate = SAMPLING_RATE_48KHZ; - break; - default: - rc = -EINVAL; - pr_err("%s: invalid sample rate being passed\n", __func__); - break; - } - - pr_debug("%s: slim0_tx_sample_rate = %d\n", __func__, - slim0_tx_sample_rate); - return rc; -} - -static int slim5_rx_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - switch (slim5_rx_bit_format) { - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: slim5_rx_bit_format = %d, ucontrol value = %ld\n", - __func__, slim5_rx_bit_format, - ucontrol->value.integer.value[0]); - - return 0; -} - -static int slim5_rx_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 2: - slim5_rx_bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - slim5_rx_bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - slim5_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - return 0; -} - -static int slim6_rx_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - switch (slim6_rx_bit_format) { - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: slim6_rx_bit_format = %d, ucontrol value = %ld\n", - __func__, slim6_rx_bit_format, - ucontrol->value.integer.value[0]); - - return 0; -} - -static int slim6_rx_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 2: - slim6_rx_bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - slim6_rx_bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - slim6_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - return 0; -} - -static int slim0_rx_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - switch (slim0_rx_bit_format) { - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: slim0_rx_bit_format = %d, ucontrol value = %ld\n", - __func__, slim0_rx_bit_format, - ucontrol->value.integer.value[0]); - - return 0; -} - -static int slim0_rx_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 2: - slim0_rx_bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - slim0_rx_bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - slim0_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - return 0; -} - -static int msm_slim_5_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_slim_5_rx_ch = %d\n", __func__, - msm_slim_5_rx_ch); - ucontrol->value.integer.value[0] = msm_slim_5_rx_ch - 1; - return 0; -} - -static int msm_slim_5_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_slim_5_rx_ch = ucontrol->value.integer.value[0] + 1; - pr_debug("%s: msm_slim_5_rx_ch = %d\n", __func__, - msm_slim_5_rx_ch); - return 1; -} - -static int msm_slim_6_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_slim_6_rx_ch = %d\n", __func__, - msm_slim_6_rx_ch); - ucontrol->value.integer.value[0] = msm_slim_6_rx_ch - 1; - return 0; -} - -static int msm_slim_6_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_slim_6_rx_ch = ucontrol->value.integer.value[0] + 1; - pr_debug("%s: msm_slim_6_rx_ch = %d\n", __func__, - msm_slim_6_rx_ch); - return 1; -} - -static int msm_slim_0_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_slim_0_rx_ch = %d\n", __func__, - msm_slim_0_rx_ch); - ucontrol->value.integer.value[0] = msm_slim_0_rx_ch - 1; - return 0; -} - -static int msm_slim_0_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_slim_0_rx_ch = ucontrol->value.integer.value[0] + 1; - pr_debug("%s: msm_slim_0_rx_ch = %d\n", __func__, - msm_slim_0_rx_ch); - return 1; -} - -static int msm_slim_0_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_slim_0_tx_ch = %d\n", __func__, - msm_slim_0_tx_ch); - ucontrol->value.integer.value[0] = msm_slim_0_tx_ch - 1; - return 0; -} - -static int msm_slim_0_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_slim_0_tx_ch = ucontrol->value.integer.value[0] + 1; - pr_debug("%s: msm_slim_0_tx_ch = %d\n", __func__, msm_slim_0_tx_ch); - return 1; -} - -static int msm_slim_1_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_slim_1_tx_ch = %d\n", __func__, - msm_slim_1_tx_ch); - ucontrol->value.integer.value[0] = msm_slim_1_tx_ch - 1; - return 0; -} - -static int msm_slim_1_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_slim_1_tx_ch = ucontrol->value.integer.value[0] + 1; - - pr_debug("%s: msm_slim_1_tx_ch = %d\n", __func__, msm_slim_1_tx_ch); - return 1; -} - -static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1; - pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, - ucontrol->value.integer.value[0]); - return 0; -} - -static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1; - - pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch); - return 1; -} - -static int hdmi_rx_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - switch (hdmi_rx_bit_format) { - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: hdmi_rx_bit_format = %d, ucontrol value = %ld\n", - __func__, hdmi_rx_bit_format, - ucontrol->value.integer.value[0]); - - return 0; -} - -static int hdmi_rx_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 2: - hdmi_rx_bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - hdmi_rx_bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - hdmi_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - pr_debug("%s: hdmi_rx_bit_format = %d, ucontrol value = %ld\n", - __func__, hdmi_rx_bit_format, - ucontrol->value.integer.value[0]); - return 0; -} - -static int msm_hdmi_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_hdmi_rx_ch = %d\n", __func__, - msm_hdmi_rx_ch); - ucontrol->value.integer.value[0] = msm_hdmi_rx_ch - 2; - - return 0; -} - -static int msm_hdmi_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_hdmi_rx_ch = ucontrol->value.integer.value[0] + 2; - if (msm_hdmi_rx_ch > 8) { - pr_err("%s: channels %d exceeded 8.Limiting to max chs-8\n", - __func__, msm_hdmi_rx_ch); - msm_hdmi_rx_ch = 8; - } - pr_debug("%s: msm_hdmi_rx_ch = %d\n", __func__, msm_hdmi_rx_ch); - - return 1; -} - -static int hdmi_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val = 0; - - switch (hdmi_rx_sample_rate) { - case SAMPLING_RATE_192KHZ: - sample_rate_val = 2; - break; - - case SAMPLING_RATE_96KHZ: - sample_rate_val = 1; - break; - - case SAMPLING_RATE_48KHZ: - default: - sample_rate_val = 0; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: hdmi_rx_sample_rate = %d\n", __func__, - hdmi_rx_sample_rate); - - return 0; -} - -static int hdmi_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: ucontrol value = %ld\n", __func__, - ucontrol->value.integer.value[0]); - - switch (ucontrol->value.integer.value[0]) { - case 2: - hdmi_rx_sample_rate = SAMPLING_RATE_192KHZ; - break; - case 1: - hdmi_rx_sample_rate = SAMPLING_RATE_96KHZ; - break; - case 0: - default: - hdmi_rx_sample_rate = SAMPLING_RATE_48KHZ; - } - - pr_debug("%s: hdmi_rx_sample_rate = %d\n", __func__, - hdmi_rx_sample_rate); - - return 0; -} - -static int msm8996_auxpcm_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = msm8996_auxpcm_rate; - return 0; -} - -static int msm8996_auxpcm_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 0: - msm8996_auxpcm_rate = SAMPLING_RATE_8KHZ; - break; - case 1: - msm8996_auxpcm_rate = SAMPLING_RATE_16KHZ; - break; - default: - msm8996_auxpcm_rate = SAMPLING_RATE_8KHZ; - break; - } - return 0; -} - -static int msm_proxy_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_proxy_rx_ch = %d\n", __func__, msm_proxy_rx_ch); - ucontrol->value.integer.value[0] = msm_proxy_rx_ch - 1; - return 0; -} - -static int msm_proxy_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_proxy_rx_ch = ucontrol->value.integer.value[0] + 1; - pr_debug("%s: msm_proxy_rx_ch = %d\n", __func__, msm_proxy_rx_ch); - return 1; -} - -static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = - hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); - - struct snd_interval *channels = - hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - - rate->min = rate->max = msm8996_auxpcm_rate; - channels->min = channels->max = 1; - - return 0; -} - -static int msm_proxy_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - pr_debug("%s: msm_proxy_rx_ch =%d\n", __func__, msm_proxy_rx_ch); - - if (channels->max < 2) - channels->min = channels->max = 2; - channels->min = channels->max = msm_proxy_rx_ch; - rate->min = rate->max = SAMPLING_RATE_48KHZ; - return 0; -} - -static int msm_proxy_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - - rate->min = rate->max = SAMPLING_RATE_48KHZ; - return 0; -} - -static int msm8996_hdmi_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - pr_debug("%s channels->min %u channels->max %u ()\n", __func__, - channels->min, channels->max); - - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - hdmi_rx_bit_format); - if (channels->max < 2) - channels->min = channels->max = 2; - rate->min = rate->max = hdmi_rx_sample_rate; - channels->min = channels->max = msm_hdmi_rx_ch; - - return 0; -} - -static int msm_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - pr_debug("%s: channel:%d\n", __func__, msm_tert_mi2s_tx_ch); - rate->min = rate->max = SAMPLING_RATE_48KHZ; - channels->min = channels->max = msm_tert_mi2s_tx_ch; - return 0; -} - -static int msm8996_mi2s_snd_startup(struct snd_pcm_substream *substream) -{ - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - - pr_debug("%s: substream = %s stream = %d\n", __func__, - substream->name, substream->stream); - - mi2s_tx_clk.enable = 1; - ret = afe_set_lpass_clock_v2(AFE_PORT_ID_TERTIARY_MI2S_TX, - &mi2s_tx_clk); - if (ret < 0) { - pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret); - goto err; - } - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - pr_err("%s: set fmt cpu dai failed, err:%d\n", __func__, ret); -err: - return ret; -} - -static void msm8996_mi2s_snd_shutdown(struct snd_pcm_substream *substream) -{ - int ret = 0; - - pr_debug("%s: substream = %s stream = %d\n", __func__, - substream->name, substream->stream); - - mi2s_tx_clk.enable = 0; - ret = afe_set_lpass_clock_v2(AFE_PORT_ID_TERTIARY_MI2S_TX, - &mi2s_tx_clk); - if (ret < 0) - pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret); -} - -static struct snd_soc_ops msm8996_mi2s_be_ops = { - .startup = msm8996_mi2s_snd_startup, - .shutdown = msm8996_mi2s_snd_shutdown, -}; - -static int msm_slim_5_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim5_rx_bit_format); - rate->min = rate->max = slim5_rx_sample_rate; - channels->min = channels->max = msm_slim_5_rx_ch; - - pr_debug("%s: format = %d, rate = %d, channels = %d\n", - __func__, params_format(params), params_rate(params), - msm_slim_5_rx_ch); - - return 0; -} - -static int msm_slim_6_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim6_rx_bit_format); - rate->min = rate->max = slim6_rx_sample_rate; - channels->min = channels->max = msm_slim_6_rx_ch; - - pr_debug("%s: format = %d, rate = %d, channels = %d\n", - __func__, params_format(params), params_rate(params), - msm_slim_6_rx_ch); - - return 0; -} - -static int msm_slim_0_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim0_rx_bit_format); - rate->min = rate->max = slim0_rx_sample_rate; - channels->min = channels->max = msm_slim_0_rx_ch; - - pr_debug("%s: format = %d, rate = %d, channels = %d\n", - __func__, params_format(params), params_rate(params), - msm_slim_0_rx_ch); - - return 0; -} - -static int msm_slim_0_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - pr_debug("%s()\n", __func__); - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, slim0_tx_bit_format); - rate->min = rate->max = slim0_tx_sample_rate; - channels->min = channels->max = msm_slim_0_tx_ch; - - return 0; -} - -static int msm_slim_1_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - pr_debug("%s()\n", __func__); - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, slim1_tx_bit_format); - rate->min = rate->max = slim1_tx_sample_rate; - channels->min = channels->max = msm_slim_1_tx_ch; - - return 0; -} - -static int msm_slim_4_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - SNDRV_PCM_FORMAT_S32_LE); - - rate->min = rate->max = SAMPLING_RATE_8KHZ; - channels->min = channels->max = msm_vi_feed_tx_ch; - pr_debug("%s: msm_vi_feed_tx_ch: %d\n", __func__, msm_vi_feed_tx_ch); - - return 0; -} - -static int msm_slim_5_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - int rc = 0; - void *config = NULL; - struct snd_soc_codec *codec = rtd->codec; - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - pr_debug("%s: enter\n", __func__); - rate->min = rate->max = SAMPLING_RATE_16KHZ; - channels->min = channels->max = 1; - - config = msm8996_codec_fn.get_afe_config_fn(codec, - AFE_SLIMBUS_SLAVE_PORT_CONFIG); - if (config) { - rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, config, - SLIMBUS_5_TX); - if (rc) { - pr_err("%s: Failed to set slimbus slave port config %d\n", - __func__, rc); - } - } - - return rc; -} - -static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - - pr_debug("%s:\n", __func__); - rate->min = rate->max = SAMPLING_RATE_48KHZ; - return 0; -} - -static const struct soc_enum msm_snd_enum[] = { - SOC_ENUM_SINGLE_EXT(2, spk_function), - SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text), - SOC_ENUM_SINGLE_EXT(8, slim0_tx_ch_text), - SOC_ENUM_SINGLE_EXT(7, hdmi_rx_ch_text), - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_bit_format_text), - rx_bit_format_text), - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim0_rx_sample_rate_text), - slim0_rx_sample_rate_text), - SOC_ENUM_SINGLE_EXT(8, proxy_rx_ch_text), - SOC_ENUM_SINGLE_EXT(3, hdmi_rx_sample_rate_text), - SOC_ENUM_SINGLE_EXT(4, slim5_rx_sample_rate_text), - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim5_rx_bit_format_text), - slim5_rx_bit_format_text), - SOC_ENUM_SINGLE_EXT(2, slim5_rx_ch_text), - SOC_ENUM_SINGLE_EXT(2, hifi_function), - SOC_ENUM_SINGLE_EXT(2, vi_feed_ch_text), - SOC_ENUM_SINGLE_EXT(4, slim6_rx_sample_rate_text), - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim6_rx_bit_format_text), - slim6_rx_bit_format_text), - SOC_ENUM_SINGLE_EXT(2, slim6_rx_ch_text), -}; - -static const struct snd_kcontrol_new msm_snd_controls[] = { - SOC_ENUM_EXT("Speaker Function", msm_snd_enum[0], msm8996_get_spk, - msm8996_set_spk), - SOC_ENUM_EXT("SLIM_0_RX Channels", msm_snd_enum[1], - msm_slim_0_rx_ch_get, msm_slim_0_rx_ch_put), - SOC_ENUM_EXT("SLIM_5_RX Channels", msm_snd_enum[10], - msm_slim_5_rx_ch_get, msm_slim_5_rx_ch_put), - SOC_ENUM_EXT("SLIM_6_RX Channels", msm_snd_enum[15], - msm_slim_6_rx_ch_get, msm_slim_6_rx_ch_put), - SOC_ENUM_EXT("SLIM_0_TX Channels", msm_snd_enum[2], - msm_slim_0_tx_ch_get, msm_slim_0_tx_ch_put), - SOC_ENUM_EXT("SLIM_1_TX Channels", msm_snd_enum[2], - msm_slim_1_tx_ch_get, msm_slim_1_tx_ch_put), - SOC_ENUM_EXT("AUX PCM SampleRate", msm8996_auxpcm_enum[0], - msm8996_auxpcm_rate_get, - msm8996_auxpcm_rate_put), - SOC_ENUM_EXT("HDMI_RX Channels", msm_snd_enum[3], - msm_hdmi_rx_ch_get, msm_hdmi_rx_ch_put), - SOC_ENUM_EXT("SLIM_0_RX Format", msm_snd_enum[4], - slim0_rx_bit_format_get, slim0_rx_bit_format_put), - SOC_ENUM_EXT("SLIM_5_RX Format", msm_snd_enum[9], - slim5_rx_bit_format_get, slim5_rx_bit_format_put), - SOC_ENUM_EXT("SLIM_6_RX Format", msm_snd_enum[14], - slim6_rx_bit_format_get, slim6_rx_bit_format_put), - SOC_ENUM_EXT("SLIM_0_RX SampleRate", msm_snd_enum[5], - slim0_rx_sample_rate_get, slim0_rx_sample_rate_put), - SOC_ENUM_EXT("SLIM_5_RX SampleRate", msm_snd_enum[8], - slim5_rx_sample_rate_get, slim5_rx_sample_rate_put), - SOC_ENUM_EXT("SLIM_6_RX SampleRate", msm_snd_enum[13], - slim6_rx_sample_rate_get, slim6_rx_sample_rate_put), - SOC_ENUM_EXT("HDMI_RX Bit Format", msm_snd_enum[4], - hdmi_rx_bit_format_get, hdmi_rx_bit_format_put), - SOC_ENUM_EXT("PROXY_RX Channels", msm_snd_enum[6], - msm_proxy_rx_ch_get, msm_proxy_rx_ch_put), - SOC_ENUM_EXT("HDMI_RX SampleRate", msm_snd_enum[7], - hdmi_rx_sample_rate_get, hdmi_rx_sample_rate_put), - SOC_ENUM_EXT("SLIM_0_TX SampleRate", msm_snd_enum[5], - slim0_tx_sample_rate_get, slim0_tx_sample_rate_put), - SOC_ENUM_EXT("SLIM_0_TX Format", msm_snd_enum[4], - slim0_tx_bit_format_get, slim0_tx_bit_format_put), - SOC_ENUM_EXT("HiFi Function", msm_snd_enum[11], msm8996_hifi_get, - msm8996_hifi_put), - SOC_ENUM_EXT("VI_FEED_TX Channels", msm_snd_enum[12], - msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), -}; - -static bool msm8996_swap_gnd_mic(struct snd_soc_codec *codec) -{ - struct snd_soc_card *card = codec->component.card; - struct msm8996_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - int value = gpio_get_value_cansleep(pdata->us_euro_gpio); - - pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value); - gpio_set_value_cansleep(pdata->us_euro_gpio, !value); - return true; -} - -static int msm_afe_set_config(struct snd_soc_codec *codec) -{ - int rc; - void *config_data = NULL; - - pr_debug("%s: enter\n", __func__); - - if (!msm8996_codec_fn.get_afe_config_fn) { - dev_err(codec->dev, "%s: codec get afe config not init'ed\n", - __func__); - return -EINVAL; - } - - config_data = msm8996_codec_fn.get_afe_config_fn(codec, - AFE_CDC_REGISTERS_CONFIG); - if (config_data) { - rc = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0); - if (rc) { - pr_err("%s: Failed to set codec registers config %d\n", - __func__, rc); - return rc; - } - } - - config_data = msm8996_codec_fn.get_afe_config_fn(codec, - AFE_CDC_REGISTER_PAGE_CONFIG); - if (config_data) { - rc = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, - 0); - if (rc) - pr_err("%s: Failed to set cdc register page config\n", - __func__); - } - - config_data = msm8996_codec_fn.get_afe_config_fn(codec, - AFE_SLIMBUS_SLAVE_CONFIG); - if (config_data) { - rc = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0); - if (rc) { - pr_err("%s: Failed to set slimbus slave config %d\n", - __func__, rc); - return rc; - } - } - - return 0; -} - -static void msm_afe_clear_config(void) -{ - afe_clear_config(AFE_CDC_REGISTERS_CONFIG); - afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); -} - -static int msm8996_adsp_state_callback(struct notifier_block *nb, - unsigned long value, void *priv) -{ - if (value == SUBSYS_BEFORE_SHUTDOWN) { - pr_debug("%s: ADSP is about to shutdown. Clearing AFE config\n", - __func__); - msm_afe_clear_config(); - } else if (value == SUBSYS_AFTER_POWERUP) { - pr_debug("%s: ADSP is up\n", __func__); - } - - return NOTIFY_OK; -} - -static struct notifier_block adsp_state_notifier_block = { - .notifier_call = msm8996_adsp_state_callback, - .priority = -INT_MAX, -}; - -static int msm8996_wcd93xx_codec_up(struct snd_soc_codec *codec) -{ - int err; - unsigned long timeout; - int adsp_ready = 0; - - timeout = jiffies + - msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); - - do { - if (!q6core_is_adsp_ready()) { - pr_err_ratelimited("%s: ADSP Audio isn't ready\n", - __func__); - /* - * ADSP will be coming up after subsystem restart and - * it might not be fully up when the control reaches - * here. So, wait for 50msec before checking ADSP state - */ - msleep(50); - } else { - pr_debug("%s: ADSP Audio is ready\n", __func__); - adsp_ready = 1; - break; - } - } while (time_after(timeout, jiffies)); - - if (!adsp_ready) { - pr_err("%s: timed out waiting for ADSP Audio\n", __func__); - return -ETIMEDOUT; - } - - err = msm_afe_set_config(codec); - if (err) - pr_err("%s: Failed to set AFE config. err %d\n", - __func__, err); - return err; -} - -static int msm8996_tasha_codec_event_cb(struct snd_soc_codec *codec, - enum wcd9335_codec_event codec_event) -{ - switch (codec_event) { - case WCD9335_CODEC_EVENT_CODEC_UP: - return msm8996_wcd93xx_codec_up(codec); - default: - pr_err("%s: UnSupported codec event %d\n", - __func__, codec_event); - return -EINVAL; - } -} - -static int msm8996_config_hph_en0_gpio(struct snd_soc_codec *codec, bool high) -{ - struct snd_soc_card *card = codec->component.card; - struct msm8996_asoc_mach_data *pdata; - int val; - - if (!card) - return 0; - - pdata = snd_soc_card_get_drvdata(card); - if (!pdata || !gpio_is_valid(pdata->hph_en0_gpio)) - return 0; - - val = gpio_get_value_cansleep(pdata->hph_en0_gpio); - if ((!!val) == high) - return 0; - - gpio_direction_output(pdata->hph_en0_gpio, (int)high); - - return 1; -} - -static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) -{ - int err; - void *config_data; - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_component *aux_comp; - void *mbhc_calibration; - struct snd_card *card; - struct snd_info_entry *entry; - struct msm8996_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(rtd->card); - - /* Codec SLIMBUS configuration - * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13 - * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 - * TX14, TX15, TX16 - */ - unsigned int rx_ch[TASHA_RX_MAX] = {144, 145, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156}; - unsigned int tx_ch[TASHA_TX_MAX] = {128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143}; - - pr_info("%s: dev_name%s\n", __func__, dev_name(cpu_dai->dev)); - - rtd->pmdown_time = 0; - - err = snd_soc_add_codec_controls(codec, msm_snd_controls, - ARRAY_SIZE(msm_snd_controls)); - if (err < 0) { - pr_err("%s: add_codec_controls failed, err %d\n", - __func__, err); - return err; - } - - err = msm8996_liquid_init_docking(); - if (err) { - pr_err("%s: 8996 init Docking stat IRQ failed (%d)\n", - __func__, err); - return err; - } - - err = msm8996_ext_us_amp_init(); - if (err) { - pr_err("%s: 8996 US Emitter GPIO init failed (%d)\n", - __func__, err); - return err; - } - - snd_soc_dapm_new_controls(dapm, msm8996_dapm_widgets, - ARRAY_SIZE(msm8996_dapm_widgets)); - - snd_soc_dapm_add_routes(dapm, wcd9335_audio_paths, - ARRAY_SIZE(wcd9335_audio_paths)); - snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp"); - snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp"); - snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp"); - snd_soc_dapm_enable_pin(dapm, "Lineout_4 amp"); - - snd_soc_dapm_ignore_suspend(dapm, "Lineout_1 amp"); - snd_soc_dapm_ignore_suspend(dapm, "Lineout_3 amp"); - snd_soc_dapm_ignore_suspend(dapm, "Lineout_2 amp"); - snd_soc_dapm_ignore_suspend(dapm, "Lineout_4 amp"); - snd_soc_dapm_ignore_suspend(dapm, "ultrasound amp"); - snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic7"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic8"); - snd_soc_dapm_ignore_suspend(dapm, "MADINPUT"); - snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT"); - snd_soc_dapm_ignore_suspend(dapm, "EAR"); - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1"); - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2"); - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3"); - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4"); - snd_soc_dapm_ignore_suspend(dapm, "ANC EAR"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC4"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC5"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC6"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC1"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC2"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC3"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC4"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC5"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC0"); - snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); - snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); - snd_soc_dapm_ignore_suspend(dapm, "HPHL"); - snd_soc_dapm_ignore_suspend(dapm, "HPHR"); - snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL"); - snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR"); - snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT1"); - snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT2"); - snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); - snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); - - snd_soc_dapm_sync(dapm); - - snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), - tx_ch, ARRAY_SIZE(rx_ch), rx_ch); - - msm8996_codec_fn.get_afe_config_fn = tasha_get_afe_config; - msm8996_codec_fn.mbhc_hs_detect_exit = tasha_mbhc_hs_detect_exit; - - err = msm_afe_set_config(codec); - if (err) { - pr_err("%s: Failed to set AFE config %d\n", __func__, err); - goto out; - } - - config_data = msm8996_codec_fn.get_afe_config_fn(codec, - AFE_AANC_VERSION); - if (config_data) { - err = afe_set_config(AFE_AANC_VERSION, config_data, 0); - if (err) { - pr_err("%s: Failed to set aanc version %d\n", - __func__, err); - goto out; - } - } - config_data = msm8996_codec_fn.get_afe_config_fn(codec, - AFE_CDC_CLIP_REGISTERS_CONFIG); - if (config_data) { - err = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG, - config_data, 0); - if (err) { - pr_err("%s: Failed to set clip registers %d\n", - __func__, err); - goto out; - } - } - config_data = msm8996_codec_fn.get_afe_config_fn(codec, - AFE_CLIP_BANK_SEL); - if (config_data) { - err = afe_set_config(AFE_CLIP_BANK_SEL, config_data, 0); - if (err) { - pr_err("%s: Failed to set AFE bank selection %d\n", - __func__, err); - goto out; - } - } - /* Start mbhc */ - tasha_mbhc_zdet_gpio_ctrl(msm8996_config_hph_en0_gpio, rtd->codec); - mbhc_calibration = def_tasha_mbhc_cal(); - if (mbhc_calibration) { - wcd_mbhc_cfg.calibration = mbhc_calibration; - err = tasha_mbhc_hs_detect(codec, &wcd_mbhc_cfg); - if (err) { - pr_err("%s: mbhc hs detect failed, err:%d\n", - __func__, err); - goto out; - } - } else { - pr_err("%s: mbhc_cfg calibration is NULL\n", __func__); - err = -ENOMEM; - goto out; - } - adsp_state_notifier = subsys_notif_register_notifier("adsp", - &adsp_state_notifier_block); - if (!adsp_state_notifier) { - pr_err("%s: Failed to register adsp state notifier\n", - __func__); - err = -EFAULT; - msm8996_codec_fn.mbhc_hs_detect_exit(codec); - goto out; - } - - tasha_event_register(msm8996_tasha_codec_event_cb, rtd->codec); - - /* - * Send speaker configuration only for WSA8810. - * Defalut configuration is for WSA8815. - */ - if (!list_empty(&rtd->card->aux_comp_list)) { - aux_comp = list_first_entry(&rtd->card->aux_comp_list, - struct snd_soc_component, list_aux); - if (!strcmp(aux_comp->name, WSA8810_NAME_1) || - !strcmp(aux_comp->name, WSA8810_NAME_2)) { - tasha_set_spkr_mode(rtd->codec, SPKR_MODE_1); - tasha_set_spkr_gain_offset(rtd->codec, - RX_GAIN_OFFSET_M1P5_DB); - } - } - codec_reg_done = true; - - card = rtd->card->snd_card; - entry = snd_info_create_subdir(card->module, "codecs", - card->proc_root); - if (!entry) { - pr_debug("%s: Cannot create codecs module entry\n", - __func__); - err = 0; - goto out; - } - pdata->codec_root = entry; - tasha_codec_info_create_codec_entry(pdata->codec_root, codec); - - return 0; -out: - return err; -} - -static void *def_tasha_mbhc_cal(void) -{ - void *tasha_wcd_cal; - struct wcd_mbhc_btn_detect_cfg *btn_cfg; - u16 *btn_high; - - tasha_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, - WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); - if (!tasha_wcd_cal) - return NULL; - -#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(tasha_wcd_cal)->X) = (Y)) - S(v_hs_max, 1500); -#undef S -#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(tasha_wcd_cal)->X) = (Y)) - S(num_btn, WCD_MBHC_DEF_BUTTONS); -#undef S - - btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(tasha_wcd_cal); - btn_high = ((void *)&btn_cfg->_v_btn_low) + - (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); - - btn_high[0] = 75; - btn_high[1] = 150; - btn_high[2] = 237; - btn_high[3] = 500; - btn_high[4] = 500; - btn_high[5] = 500; - btn_high[6] = 500; - btn_high[7] = 500; - - return tasha_wcd_cal; -} - -static int msm_snd_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai_link *dai_link = rtd->dai_link; - - int ret = 0; - u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; - u32 rx_ch_cnt = 0, tx_ch_cnt = 0; - u32 user_set_tx_ch = 0; - u32 rx_ch_count; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map, err:%d\n", - __func__, ret); - goto end; - } - if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_5_RX) { - pr_debug("%s: rx_5_ch=%d\n", __func__, - msm_slim_5_rx_ch); - rx_ch_count = msm_slim_5_rx_ch; - } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_6_RX) { - pr_debug("%s: rx_6_ch=%d\n", __func__, - msm_slim_6_rx_ch); - rx_ch_count = msm_slim_6_rx_ch; - } else { - pr_debug("%s: rx_0_ch=%d\n", __func__, - msm_slim_0_rx_ch); - rx_ch_count = msm_slim_0_rx_ch; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, - rx_ch_count, rx_ch); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto end; - } - } else { - - pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__, - codec_dai->name, codec_dai->id, user_set_tx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map\n, err:%d\n", - __func__, ret); - goto end; - } - /* For _tx1 case */ - if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_0_TX) - user_set_tx_ch = msm_slim_0_tx_ch; - /* For _tx3 case */ - else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_1_TX) - user_set_tx_ch = msm_slim_1_tx_ch; - else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_3_TX) - /* DAI 5 is used for external EC reference from codec. - * Since Rx is fed as reference for EC, the config of - * this DAI is based on that of the Rx path. - */ - user_set_tx_ch = msm_slim_0_rx_ch; - else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_4_TX) - user_set_tx_ch = msm_vi_feed_tx_ch; - else - user_set_tx_ch = tx_ch_cnt; - - pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), BE id (%d)\n", - __func__, msm_slim_0_tx_ch, user_set_tx_ch, - tx_ch_cnt, dai_link->id); - - ret = snd_soc_dai_set_channel_map(cpu_dai, - user_set_tx_ch, tx_ch, 0, 0); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto end; - } - } -end: - return ret; -} - -static int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai_link *dai_link = rtd->dai_link; - - int ret = 0; - u32 tx_ch[SLIM_MAX_TX_PORTS]; - u32 tx_ch_cnt = 0; - u32 user_set_tx_ch = 0; - - if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) { - pr_err("%s: Invalid stream type %d\n", - __func__, substream->stream); - ret = -EINVAL; - goto end; - } - - pr_debug("%s: %s_tx_dai_id_%d\n", __func__, - codec_dai->name, codec_dai->id); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, NULL, NULL); - if (ret < 0) { - pr_err("%s: failed to get codec chan map\n, err:%d\n", - __func__, ret); - goto end; - } - - user_set_tx_ch = tx_ch_cnt; - - pr_debug("%s: tx_ch_cnt(%d) BE id %d\n", - __func__, tx_ch_cnt, dai_link->id); - - ret = snd_soc_dai_set_channel_map(cpu_dai, - user_set_tx_ch, tx_ch, 0, 0); - if (ret < 0) - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); -end: - return ret; -} - -static struct snd_soc_ops msm8996_be_ops = { - .hw_params = msm_snd_hw_params, -}; - -static struct snd_soc_ops msm8996_cpe_ops = { - .hw_params = msm_snd_cpe_hw_params, -}; - -static int msm8996_slimbus_2_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret = 0; - unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; - unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0; - unsigned int num_tx_ch = 0; - unsigned int num_rx_ch = 0; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - num_rx_ch = params_channels(params); - pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__, - codec_dai->name, codec_dai->id, num_rx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map, err:%d\n", - __func__, ret); - goto end; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, - num_rx_ch, rx_ch); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto end; - } - } else { - num_tx_ch = params_channels(params); - pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__, - codec_dai->name, codec_dai->id, num_tx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map, err:%d\n", - __func__, ret); - goto end; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, - num_tx_ch, tx_ch, 0, 0); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto end; - } - } -end: - return ret; -} - -static struct snd_soc_ops msm8996_slimbus_2_be_ops = { - .hw_params = msm8996_slimbus_2_hw_params, -}; - -static int msm8996_get_ll_qos_val(struct snd_pcm_runtime *runtime) -{ - int usecs; - - /* take 10% of period time as the deadline */ - usecs = (100000 / runtime->rate) * runtime->period_size; - usecs += ((100000 % runtime->rate) * runtime->period_size) / - runtime->rate; - - return usecs; -} - -static int msm8996_mm5_prepare(struct snd_pcm_substream *substream) -{ - if (pm_qos_request_active(&substream->latency_pm_qos_req)) - pm_qos_remove_request(&substream->latency_pm_qos_req); - pm_qos_add_request(&substream->latency_pm_qos_req, - PM_QOS_CPU_DMA_LATENCY, - msm8996_get_ll_qos_val(substream->runtime)); - return 0; -} - -static struct snd_soc_ops msm8996_mm5_ops = { - .prepare = msm8996_mm5_prepare, -}; - -/* Digital audio interface glue - connects codec <---> CPU */ -static struct snd_soc_dai_link msm8996_common_dai_links[] = { - /* FrontEnd DAI Links */ - { - .name = "MSM8996 Media1", - .stream_name = "MultiMedia1", - .cpu_dai_name = "MultiMedia1", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA1 - }, - { - .name = "MSM8996 Media2", - .stream_name = "MultiMedia2", - .cpu_dai_name = "MultiMedia2", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA2, - }, - { - .name = "VoiceMMode1", - .stream_name = "VoiceMMode1", - .cpu_dai_name = "VoiceMMode1", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_VOICEMMODE1, - }, - { - .name = "MSM VoIP", - .stream_name = "VoIP", - .cpu_dai_name = "VoIP", - .platform_name = "msm-voip-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_VOIP, - }, - { - .name = "MSM8996 ULL", - .stream_name = "MultiMedia3", - .cpu_dai_name = "MultiMedia3", - .platform_name = "msm-pcm-dsp.2", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA3, - }, - /* Hostless PCM purpose */ - { - .name = "SLIMBUS_0 Hostless", - .stream_name = "SLIMBUS_0 Hostless", - .cpu_dai_name = "SLIMBUS0_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "Tertiary MI2S TX_Hostless", - .stream_name = "Tertiary MI2S_TX Hostless Capture", - .cpu_dai_name = "TERT_MI2S_TX_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "MSM AFE-PCM RX", - .stream_name = "AFE-PROXY RX", - .cpu_dai_name = "msm-dai-q6-dev.241", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .platform_name = "msm-pcm-afe", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - }, - { - .name = "MSM AFE-PCM TX", - .stream_name = "AFE-PROXY TX", - .cpu_dai_name = "msm-dai-q6-dev.240", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .platform_name = "msm-pcm-afe", - .ignore_suspend = 1, - }, - { - .name = "MSM8996 Compress1", - .stream_name = "Compress1", - .cpu_dai_name = "MultiMedia4", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA4, - }, - { - .name = "AUXPCM Hostless", - .stream_name = "AUXPCM Hostless", - .cpu_dai_name = "AUXPCM_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "SLIMBUS_1 Hostless", - .stream_name = "SLIMBUS_1 Hostless", - .cpu_dai_name = "SLIMBUS1_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "SLIMBUS_3 Hostless", - .stream_name = "SLIMBUS_3 Hostless", - .cpu_dai_name = "SLIMBUS3_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "SLIMBUS_4 Hostless", - .stream_name = "SLIMBUS_4 Hostless", - .cpu_dai_name = "SLIMBUS4_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "VoLTE", - .stream_name = "VoLTE", - .cpu_dai_name = "VoLTE", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_VOLTE, - }, - { - .name = "MSM8996 LowLatency", - .stream_name = "MultiMedia5", - .cpu_dai_name = "MultiMedia5", - .platform_name = "msm-pcm-dsp.1", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA5, - .ops = &msm8996_mm5_ops, - }, - { - .name = "Listen 1 Audio Service", - .stream_name = "Listen 1 Audio Service", - .cpu_dai_name = "LSM1", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM1, - }, - /* Multiple Tunnel instances */ - { - .name = "MSM8996 Compress2", - .stream_name = "Compress2", - .cpu_dai_name = "MultiMedia7", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA7, - }, - { - .name = "MSM8996 Compress3", - .stream_name = "Compress3", - .cpu_dai_name = "MultiMedia10", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA10, - }, - { - .name = "MSM8996 ULL NOIRQ", - .stream_name = "MM_NOIRQ", - .cpu_dai_name = "MultiMedia8", - .platform_name = "msm-pcm-dsp-noirq", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA8, - }, - { - .name = "QCHAT", - .stream_name = "QCHAT", - .cpu_dai_name = "QCHAT", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_QCHAT, - }, - /* HDMI Hostless */ - { - .name = "HDMI_RX_HOSTLESS", - .stream_name = "HDMI_RX_HOSTLESS", - .cpu_dai_name = "HDMI_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "VoiceMMode2", - .stream_name = "VoiceMMode2", - .cpu_dai_name = "VoiceMMode2", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_VOICEMMODE2, - }, - { - .name = "INT_HFP_BT Hostless", - .stream_name = "INT_HFP_BT Hostless", - .cpu_dai_name = "INT_HFP_BT_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "MSM8996 HFP TX", - .stream_name = "MultiMedia6", - .cpu_dai_name = "MultiMedia6", - .platform_name = "msm-pcm-loopback", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA6, - }, - /* LSM FE */ - { - .name = "Listen 2 Audio Service", - .stream_name = "Listen 2 Audio Service", - .cpu_dai_name = "LSM2", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM2, - }, - { - .name = "Listen 3 Audio Service", - .stream_name = "Listen 3 Audio Service", - .cpu_dai_name = "LSM3", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM3, - }, - { - .name = "Listen 4 Audio Service", - .stream_name = "Listen 4 Audio Service", - .cpu_dai_name = "LSM4", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM4, - }, - { - .name = "Listen 5 Audio Service", - .stream_name = "Listen 5 Audio Service", - .cpu_dai_name = "LSM5", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM5, - }, - { - .name = "Listen 6 Audio Service", - .stream_name = "Listen 6 Audio Service", - .cpu_dai_name = "LSM6", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM6, - }, - { - .name = "Listen 7 Audio Service", - .stream_name = "Listen 7 Audio Service", - .cpu_dai_name = "LSM7", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM7, - }, - { - .name = "Listen 8 Audio Service", - .stream_name = "Listen 8 Audio Service", - .cpu_dai_name = "LSM8", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM8, - }, - { - .name = "MSM8996 Media9", - .stream_name = "MultiMedia9", - .cpu_dai_name = "MultiMedia9", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA9, - }, - { - .name = "VoWLAN", - .stream_name = "VoWLAN", - .cpu_dai_name = "VoWLAN", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_VOWLAN, - }, - { - .name = "MSM8996 Compress4", - .stream_name = "Compress4", - .cpu_dai_name = "MultiMedia11", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA11, - }, - { - .name = "MSM8996 Compress5", - .stream_name = "Compress5", - .cpu_dai_name = "MultiMedia12", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA12, - }, - { - .name = "MSM8996 Compress6", - .stream_name = "Compress6", - .cpu_dai_name = "MultiMedia13", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA13, - }, - { - .name = "MSM8996 Compress7", - .stream_name = "Compress7", - .cpu_dai_name = "MultiMedia14", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA14, - }, - { - .name = "MSM8996 Compress8", - .stream_name = "Compress8", - .cpu_dai_name = "MultiMedia15", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA15, - }, - { - .name = "MSM8996 ULL NOIRQ_2", - .stream_name = "MM_NOIRQ_2", - .cpu_dai_name = "MultiMedia16", - .platform_name = "msm-pcm-dsp-noirq", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA16, - }, - { - .name = "Circuit-Switch Voice", - .stream_name = "CS-Voice", - .cpu_dai_name = "CS-VOICE", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_CS_VOICE, - }, - { - .name = "Voice2", - .stream_name = "Voice2", - .cpu_dai_name = "Voice2", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_VOICE2, - }, -}; - -static struct snd_soc_dai_link msm8996_tasha_fe_dai_links[] = { - { - .name = LPASS_BE_SLIMBUS_4_TX, - .stream_name = "Slimbus4 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16393", - .platform_name = "msm-pcm-hostless", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_vifeedback", - .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, - .be_hw_params_fixup = msm_slim_4_tx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - }, - /* Ultrasound RX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Playback", - .stream_name = "SLIMBUS_2 Hostless Playback", - .cpu_dai_name = "msm-dai-q6-dev.16388", - .platform_name = "msm-pcm-hostless", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx2", - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm8996_slimbus_2_be_ops, - }, - /* Ultrasound TX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Capture", - .stream_name = "SLIMBUS_2 Hostless Capture", - .cpu_dai_name = "msm-dai-q6-dev.16389", - .platform_name = "msm-pcm-hostless", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx2", - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm8996_slimbus_2_be_ops, - }, - /* CPE LSM direct dai-link */ - { - .name = "CPE Listen service", - .stream_name = "CPE Listen Audio Service", - .cpu_dai_name = "msm-dai-slim", - .platform_name = "msm-cpe-lsm", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "tasha_mad1", - .codec_name = "tasha_codec", - .ops = &msm8996_cpe_ops, - }, - /* slimbus rx 6 hostless */ - { - .name = "SLIMBUS_6 Hostless Playback", - .stream_name = "SLIMBUS_6 Hostless", - .cpu_dai_name = "SLIMBUS6_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - /* CPE LSM EC PP direct dai-link */ - { - .name = "CPE Listen service ECPP", - .stream_name = "CPE Listen Audio Service ECPP", - .cpu_dai_name = "CPE_LSM_NOHOST", - .platform_name = "msm-cpe-lsm.3", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "tasha_cpe", - .codec_name = "tasha_codec", - }, -}; - -static struct snd_soc_dai_link msm8996_common_be_dai_links[] = { - /* Backend AFE DAI Links */ - { - .name = LPASS_BE_AFE_PCM_RX, - .stream_name = "AFE Playback", - .cpu_dai_name = "msm-dai-q6-dev.224", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_AFE_PCM_RX, - .be_hw_params_fixup = msm_proxy_rx_be_hw_params_fixup, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_AFE_PCM_TX, - .stream_name = "AFE Capture", - .cpu_dai_name = "msm-dai-q6-dev.225", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_AFE_PCM_TX, - .be_hw_params_fixup = msm_proxy_tx_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Primary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_AUXPCM_RX, - .stream_name = "AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_AUXPCM_RX, - .be_hw_params_fixup = msm_auxpcm_be_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - /* this dainlink has playback support */ - }, - { - .name = LPASS_BE_AUXPCM_TX, - .stream_name = "AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_AUXPCM_TX, - .be_hw_params_fixup = msm_auxpcm_be_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Record Uplink BACK END DAI Link */ - { - .name = LPASS_BE_INCALL_RECORD_TX, - .stream_name = "Voice Uplink Capture", - .cpu_dai_name = "msm-dai-q6-dev.32772", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Record Downlink BACK END DAI Link */ - { - .name = LPASS_BE_INCALL_RECORD_RX, - .stream_name = "Voice Downlink Capture", - .cpu_dai_name = "msm-dai-q6-dev.32771", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Music BACK END DAI Link */ - { - .name = LPASS_BE_VOICE_PLAYBACK_TX, - .stream_name = "Voice Farend Playback", - .cpu_dai_name = "msm-dai-q6-dev.32773", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Music 2 BACK END DAI Link */ - { - .name = LPASS_BE_VOICE2_PLAYBACK_TX, - .stream_name = "Voice2 Farend Playback", - .cpu_dai_name = "msm-dai-q6-dev.32770", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_TERT_MI2S_TX, - .stream_name = "Tertiary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - .be_hw_params_fixup = msm_tx_be_hw_params_fixup, - .ops = &msm8996_mi2s_be_ops, - .ignore_suspend = 1, - } -}; - -static struct snd_soc_dai_link msm8996_tasha_be_dai_links[] = { - /* Backend DAI Links */ - { - .name = LPASS_BE_SLIMBUS_0_RX, - .stream_name = "Slimbus Playback", - .cpu_dai_name = "msm-dai-q6-dev.16384", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mix_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, - .init = &msm_audrx_init, - .be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm8996_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_0_TX, - .stream_name = "Slimbus Capture", - .cpu_dai_name = "msm-dai-q6-dev.16385", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, - .be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm8996_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_1_RX, - .stream_name = "Slimbus1 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16386", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mix_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, - .be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_1_TX, - .stream_name = "Slimbus1 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16387", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx3", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, - .be_hw_params_fixup = msm_slim_1_tx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_3_RX, - .stream_name = "Slimbus3 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16390", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mix_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, - .be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_3_TX, - .stream_name = "Slimbus3 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16391", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, - .be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_4_RX, - .stream_name = "Slimbus4 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16392", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mix_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, - .be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_5_RX, - .stream_name = "Slimbus5 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16394", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx3", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, - .be_hw_params_fixup = msm_slim_5_rx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - /* MAD BE */ - { - .name = LPASS_BE_SLIMBUS_5_TX, - .stream_name = "Slimbus5 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16395", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mad1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, - .be_hw_params_fixup = msm_slim_5_tx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_6_RX, - .stream_name = "Slimbus6 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16396", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx4", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, - .be_hw_params_fixup = msm_slim_6_rx_be_hw_params_fixup, - .ops = &msm8996_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm8996_hdmi_dai_link[] = { - /* HDMI BACK END DAI Link */ - { - .name = LPASS_BE_HDMI, - .stream_name = "HDMI Playback", - .cpu_dai_name = "msm-dai-q6-hdmi.8", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-hdmi-audio-codec-rx", - .codec_dai_name = "msm_hdmi_audio_codec_rx_dai", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_HDMI_RX, - .be_hw_params_fixup = msm8996_hdmi_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm8996_tasha_dai_links[ - ARRAY_SIZE(msm8996_common_dai_links) + - ARRAY_SIZE(msm8996_tasha_fe_dai_links) + - ARRAY_SIZE(msm8996_common_be_dai_links) + - ARRAY_SIZE(msm8996_tasha_be_dai_links) + - ARRAY_SIZE(msm8996_hdmi_dai_link)]; - -static int msm8996_wsa881x_init(struct snd_soc_component *component) -{ - u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106}; - u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107}; - unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; - unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); - struct msm8996_asoc_mach_data *pdata; - struct snd_soc_dapm_context *dapm; - - if (!codec) { - pr_err("%s codec is NULL\n", __func__); - return -EINVAL; - } - - dapm = snd_soc_codec_get_dapm(codec); - - if (!strcmp(component->name_prefix, "SpkrLeft")) { - dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n", - __func__, codec->component.name); - wsa881x_set_channel_map(codec, &spkleft_ports[0], - WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0]); - if (dapm->component) { - snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); - snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); - } - } else if (!strcmp(component->name_prefix, "SpkrRight")) { - dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n", - __func__, codec->component.name); - wsa881x_set_channel_map(codec, &spkright_ports[0], - WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0]); - if (dapm->component) { - snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); - snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); - } - } else { - dev_err(codec->dev, "%s: wrong codec name %s\n", __func__, - codec->component.name); - return -EINVAL; - } - pdata = snd_soc_card_get_drvdata(component->card); - if (pdata && pdata->codec_root) - wsa881x_codec_info_create_codec_entry(pdata->codec_root, - codec); - - return 0; -} - -struct snd_soc_card snd_soc_card_tasha_msm8996 = { - .name = "msm8996-tasha-snd-card", -}; - -static int msm8996_populate_dai_link_component_of_node( - struct snd_soc_card *card) -{ - int i, index, ret = 0; - struct device *cdev = card->dev; - struct snd_soc_dai_link *dai_link = card->dai_link; - struct device_node *np; - - if (!cdev) { - pr_err("%s: Sound card device memory NULL\n", __func__); - return -ENODEV; - } - - for (i = 0; i < card->num_links; i++) { - if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) - continue; - - /* populate platform_of_node for snd card dai links */ - if (dai_link[i].platform_name && - !dai_link[i].platform_of_node) { - index = of_property_match_string(cdev->of_node, - "asoc-platform-names", - dai_link[i].platform_name); - if (index < 0) { - pr_err("%s: No match found for platform name: %s\n", - __func__, dai_link[i].platform_name); - ret = index; - goto err; - } - np = of_parse_phandle(cdev->of_node, "asoc-platform", - index); - if (!np) { - pr_err("%s: retrieving phandle for platform %s, index %d failed\n", - __func__, dai_link[i].platform_name, - index); - ret = -ENODEV; - goto err; - } - dai_link[i].platform_of_node = np; - dai_link[i].platform_name = NULL; - } - - /* populate cpu_of_node for snd card dai links */ - if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { - index = of_property_match_string(cdev->of_node, - "asoc-cpu-names", - dai_link[i].cpu_dai_name); - if (index >= 0) { - np = of_parse_phandle(cdev->of_node, "asoc-cpu", - index); - if (!np) { - pr_err("%s: retrieving phandle for cpu dai %s failed\n", - __func__, - dai_link[i].cpu_dai_name); - ret = -ENODEV; - goto err; - } - dai_link[i].cpu_of_node = np; - dai_link[i].cpu_dai_name = NULL; - } - } - - /* populate codec_of_node for snd card dai links */ - if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { - index = of_property_match_string(cdev->of_node, - "asoc-codec-names", - dai_link[i].codec_name); - if (index < 0) - continue; - np = of_parse_phandle(cdev->of_node, "asoc-codec", - index); - if (!np) { - pr_err("%s: retrieving phandle for codec %s failed\n", - __func__, dai_link[i].codec_name); - ret = -ENODEV; - goto err; - } - dai_link[i].codec_of_node = np; - dai_link[i].codec_name = NULL; - } - } - -err: - return ret; -} - -static int msm8996_prepare_us_euro(struct snd_soc_card *card) -{ - struct msm8996_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - int ret; - - if (pdata->us_euro_gpio >= 0) { - dev_dbg(card->dev, "%s: us_euro gpio request %d", __func__, - pdata->us_euro_gpio); - ret = gpio_request(pdata->us_euro_gpio, "TASHA_CODEC_US_EURO"); - if (ret) { - dev_err(card->dev, - "%s: Failed to request codec US/EURO gpio %d error %d\n", - __func__, pdata->us_euro_gpio, ret); - return ret; - } - } - - return 0; -} - -static int msm8996_prepare_hifi(struct snd_soc_card *card) -{ - struct msm8996_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - int ret; - - if (gpio_is_valid(pdata->hph_en1_gpio)) { - dev_dbg(card->dev, "%s: hph_en1_gpio request %d\n", __func__, - pdata->hph_en1_gpio); - ret = gpio_request(pdata->hph_en1_gpio, "hph_en1_gpio"); - if (ret) { - dev_err(card->dev, - "%s: hph_en1_gpio request failed, ret:%d\n", - __func__, ret); - return ret; - } - } - if (gpio_is_valid(pdata->hph_en0_gpio)) { - dev_dbg(card->dev, "%s: hph_en0_gpio request %d\n", __func__, - pdata->hph_en0_gpio); - ret = gpio_request(pdata->hph_en0_gpio, "hph_en0_gpio"); - if (ret) { - dev_err(card->dev, - "%s: hph_en0_gpio request failed, ret:%d\n", - __func__, ret); - return ret; - } - } - return 0; -} - -static const struct of_device_id msm8996_asoc_machine_of_match[] = { - { .compatible = "qcom,msm8996-asoc-snd-tasha", - .data = "tasha_codec"}, - {}, -}; - -static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) -{ - struct snd_soc_card *card = NULL; - struct snd_soc_dai_link *dailink; - int len_1, len_2, len_3, len_4; - const struct of_device_id *match; - - match = of_match_node(msm8996_asoc_machine_of_match, dev->of_node); - if (!match) { - dev_err(dev, "%s: No DT match found for sound card\n", - __func__); - return NULL; - } - - if (!strcmp(match->data, "tasha_codec")) { - card = &snd_soc_card_tasha_msm8996; - len_1 = ARRAY_SIZE(msm8996_common_dai_links); - len_2 = len_1 + ARRAY_SIZE(msm8996_tasha_fe_dai_links); - len_3 = len_2 + ARRAY_SIZE(msm8996_common_be_dai_links); - - memcpy(msm8996_tasha_dai_links, - msm8996_common_dai_links, - sizeof(msm8996_common_dai_links)); - memcpy(msm8996_tasha_dai_links + len_1, - msm8996_tasha_fe_dai_links, - sizeof(msm8996_tasha_fe_dai_links)); - memcpy(msm8996_tasha_dai_links + len_2, - msm8996_common_be_dai_links, - sizeof(msm8996_common_be_dai_links)); - memcpy(msm8996_tasha_dai_links + len_3, - msm8996_tasha_be_dai_links, - sizeof(msm8996_tasha_be_dai_links)); - - dailink = msm8996_tasha_dai_links; - len_4 = len_3 + ARRAY_SIZE(msm8996_tasha_be_dai_links); - } - - if (of_property_read_bool(dev->of_node, "qcom,hdmi-audio-rx")) { - dev_dbg(dev, "%s(): hdmi audio support present\n", - __func__); - memcpy(dailink + len_4, msm8996_hdmi_dai_link, - sizeof(msm8996_hdmi_dai_link)); - len_4 += ARRAY_SIZE(msm8996_hdmi_dai_link); - } else { - dev_dbg(dev, "%s(): No hdmi audio support\n", __func__); - } - - if (card) { - card->dai_link = dailink; - card->num_links = len_4; - } - - return card; -} - -static int msm8996_init_wsa_dev(struct platform_device *pdev, - struct snd_soc_card *card) -{ - struct device_node *wsa_of_node; - u32 wsa_max_devs; - u32 wsa_dev_cnt; - char *dev_name_str = NULL; - struct msm8996_wsa881x_dev_info *wsa881x_dev_info; - const char *wsa_auxdev_name_prefix[1]; - int found = 0; - int i; - int ret; - - /* Get maximum WSA device count for this platform */ - ret = of_property_read_u32(pdev->dev.of_node, - "qcom,wsa-max-devs", &wsa_max_devs); - if (ret) { - dev_dbg(&pdev->dev, - "%s: wsa-max-devs property missing in DT %s, ret = %d\n", - __func__, pdev->dev.of_node->full_name, ret); - return 0; - } - if (wsa_max_devs == 0) { - dev_warn(&pdev->dev, - "%s: Max WSA devices is 0 for this target?\n", - __func__); - return 0; - } - - /* Get count of WSA device phandles for this platform */ - wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node, - "qcom,wsa-devs", NULL); - if (wsa_dev_cnt == -ENOENT) { - dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n", - __func__); - return 0; - } else if (wsa_dev_cnt <= 0) { - dev_err(&pdev->dev, - "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n", - __func__, wsa_dev_cnt); - return -EINVAL; - } - - /* - * Expect total phandles count to be NOT less than maximum possible - * WSA count. However, if it is less, then assign same value to - * max count as well. - */ - if (wsa_dev_cnt < wsa_max_devs) { - dev_dbg(&pdev->dev, - "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n", - __func__, wsa_max_devs, wsa_dev_cnt); - wsa_max_devs = wsa_dev_cnt; - } - - /* Make sure prefix string passed for each WSA device */ - ret = of_property_count_strings(pdev->dev.of_node, - "qcom,wsa-aux-dev-prefix"); - if (ret != wsa_dev_cnt) { - dev_err(&pdev->dev, - "%s: expecting %d wsa prefix. Defined only %d in DT\n", - __func__, wsa_dev_cnt, ret); - return -EINVAL; - } - - /* - * Alloc mem to store phandle and index info of WSA device, if already - * registered with ALSA core - */ - wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs, - sizeof(struct msm8996_wsa881x_dev_info), - GFP_KERNEL); - if (!wsa881x_dev_info) - return -ENOMEM; - - /* - * search and check whether all WSA devices are already - * registered with ALSA core or not. If found a node, store - * the node and the index in a local array of struct for later - * use. - */ - for (i = 0; i < wsa_dev_cnt; i++) { - wsa_of_node = of_parse_phandle(pdev->dev.of_node, - "qcom,wsa-devs", i); - if (unlikely(!wsa_of_node)) { - /* we should not be here */ - dev_err(&pdev->dev, - "%s: wsa dev node is not present\n", - __func__); - return -EINVAL; - } - if (soc_find_component(wsa_of_node, NULL)) { - /* WSA device registered with ALSA core */ - wsa881x_dev_info[found].of_node = wsa_of_node; - wsa881x_dev_info[found].index = i; - found++; - if (found == wsa_max_devs) - break; - } - } - - if (found < wsa_max_devs) { - dev_dbg(&pdev->dev, - "%s: failed to find %d components. Found only %d\n", - __func__, wsa_max_devs, found); - return -EPROBE_DEFER; - } - dev_info(&pdev->dev, - "%s: found %d wsa881x devices registered with ALSA core\n", - __func__, found); - - card->num_aux_devs = wsa_max_devs; - card->num_configs = wsa_max_devs; - - /* Alloc array of AUX devs struct */ - msm8996_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, - sizeof(struct snd_soc_aux_dev), - GFP_KERNEL); - if (!msm8996_aux_dev) - return -ENOMEM; - - /* Alloc array of codec conf struct */ - msm8996_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs, - sizeof(struct snd_soc_codec_conf), - GFP_KERNEL); - if (!msm8996_codec_conf) - return -ENOMEM; - - for (i = 0; i < card->num_aux_devs; i++) { - dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN, - GFP_KERNEL); - if (!dev_name_str) - return -ENOMEM; - - ret = of_property_read_string_index(pdev->dev.of_node, - "qcom,wsa-aux-dev-prefix", - wsa881x_dev_info[i].index, - wsa_auxdev_name_prefix); - if (ret) { - dev_err(&pdev->dev, - "%s: failed to read wsa aux dev prefix, ret = %d\n", - __func__, ret); - return -EINVAL; - } - - snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i); - msm8996_aux_dev[i].name = dev_name_str; - msm8996_aux_dev[i].codec_name = NULL; - msm8996_aux_dev[i].codec_of_node = - wsa881x_dev_info[i].of_node; - msm8996_aux_dev[i].init = msm8996_wsa881x_init; - msm8996_codec_conf[i].dev_name = NULL; - msm8996_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0]; - msm8996_codec_conf[i].of_node = - wsa881x_dev_info[i].of_node; - } - card->codec_conf = msm8996_codec_conf; - card->aux_dev = msm8996_aux_dev; - - return 0; -} - -static int msm8996_asoc_machine_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card; - struct msm8996_asoc_mach_data *pdata; - const char *mbhc_audio_jack_type = NULL; - char *mclk_freq_prop_name; - const struct of_device_id *match; - int ret; - - if (!pdev->dev.of_node) { - dev_err(&pdev->dev, "No platform supplied from device tree\n"); - return -EINVAL; - } - - pdata = devm_kzalloc(&pdev->dev, - sizeof(struct msm8996_asoc_mach_data), GFP_KERNEL); - if (!pdata) - return -ENOMEM; - - card = populate_snd_card_dailinks(&pdev->dev); - if (!card) { - dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); - ret = -EINVAL; - goto err; - } - card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); - snd_soc_card_set_drvdata(card, pdata); - - ret = snd_soc_of_parse_card_name(card, "qcom,model"); - if (ret) { - dev_err(&pdev->dev, "parse card name failed, err:%d\n", - ret); - goto err; - } - - ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing"); - if (ret) { - dev_err(&pdev->dev, "parse audio routing failed, err:%d\n", - ret); - goto err; - } - - match = of_match_node(msm8996_asoc_machine_of_match, - pdev->dev.of_node); - if (!match) { - dev_err(&pdev->dev, "%s: no matched codec is found.\n", - __func__); - goto err; - } - - mclk_freq_prop_name = "qcom,tasha-mclk-clk-freq"; - - ret = of_property_read_u32(pdev->dev.of_node, - mclk_freq_prop_name, &pdata->mclk_freq); - if (ret) { - dev_err(&pdev->dev, - "Looking up %s property in node %s failed, err%d\n", - mclk_freq_prop_name, - pdev->dev.of_node->full_name, ret); - goto err; - } - - if (pdata->mclk_freq != CODEC_EXT_CLK_RATE) { - dev_err(&pdev->dev, "unsupported mclk freq %u\n", - pdata->mclk_freq); - ret = -EINVAL; - goto err; - } - - spdev = pdev; - - ret = msm8996_populate_dai_link_component_of_node(card); - if (ret) { - ret = -EPROBE_DEFER; - goto err; - } - - ret = msm8996_init_wsa_dev(pdev, card); - if (ret) - goto err; - - pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node, - "qcom,hph-en1-gpio", 0); - if (pdata->hph_en1_gpio < 0) { - dev_dbg(&pdev->dev, "%s: %s property not found %d\n", - __func__, "qcom,hph-en1-gpio", pdata->hph_en1_gpio); - } - - pdata->hph_en0_gpio = of_get_named_gpio(pdev->dev.of_node, - "qcom,hph-en0-gpio", 0); - if (pdata->hph_en0_gpio < 0) { - dev_dbg(&pdev->dev, "%s: %s property not found %d\n", - __func__, "qcom,hph-en0-gpio", pdata->hph_en0_gpio); - } - ret = msm8996_prepare_hifi(card); - if (ret) - dev_dbg(&pdev->dev, "msm8996_prepare_hifi failed (%d)\n", - ret); - - ret = snd_soc_register_card(card); - if (ret == -EPROBE_DEFER) { - if (codec_reg_done) - ret = -EINVAL; - goto err; - } else if (ret) { - dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", - ret); - goto err; - } - dev_info(&pdev->dev, "Sound card %s registered\n", card->name); - - ret = of_property_read_string(pdev->dev.of_node, - "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type); - if (ret) { - dev_dbg(&pdev->dev, "Looking up %s property in node %s failed", - "qcom,mbhc-audio-jack-type", - pdev->dev.of_node->full_name); - dev_dbg(&pdev->dev, "Jack type properties set to default"); - } else { - if (!strcmp(mbhc_audio_jack_type, "4-pole-jack")) - dev_dbg(&pdev->dev, "This hardware has 4 pole jack"); - else if (!strcmp(mbhc_audio_jack_type, "5-pole-jack")) - dev_dbg(&pdev->dev, "This hardware has 5 pole jack"); - else if (!strcmp(mbhc_audio_jack_type, "6-pole-jack")) - dev_dbg(&pdev->dev, "This hardware has 6 pole jack"); - else - dev_dbg(&pdev->dev, "Unknown value, set to default"); - } - /* - * Parse US-Euro gpio info from DT. Report no error if us-euro - * entry is not found in DT file as some targets do not support - * US-Euro detection - */ - pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node, - "qcom,us-euro-gpios", 0); - if (pdata->us_euro_gpio < 0) { - dev_info(&pdev->dev, "property %s not detected in node %s", - "qcom,us-euro-gpios", - pdev->dev.of_node->full_name); - } else { - dev_dbg(&pdev->dev, "%s detected %d", - "qcom,us-euro-gpios", pdata->us_euro_gpio); - wcd_mbhc_cfg.swap_gnd_mic = msm8996_swap_gnd_mic; - } - - ret = msm8996_prepare_us_euro(card); - if (ret) - dev_info(&pdev->dev, "msm8996_prepare_us_euro failed (%d)\n", - ret); - return 0; -err: - if (pdata->us_euro_gpio > 0) { - dev_dbg(&pdev->dev, "%s free us_euro gpio %d\n", - __func__, pdata->us_euro_gpio); - gpio_free(pdata->us_euro_gpio); - pdata->us_euro_gpio = 0; - } - if (pdata->hph_en1_gpio > 0) { - dev_dbg(&pdev->dev, "%s free hph_en1_gpio %d\n", - __func__, pdata->hph_en1_gpio); - gpio_free(pdata->hph_en1_gpio); - pdata->hph_en1_gpio = 0; - } - if (pdata->hph_en0_gpio > 0) { - dev_dbg(&pdev->dev, "%s free hph_en0_gpio %d\n", - __func__, pdata->hph_en0_gpio); - gpio_free(pdata->hph_en0_gpio); - pdata->hph_en0_gpio = 0; - } - devm_kfree(&pdev->dev, pdata); - return ret; -} - -static int msm8996_asoc_machine_remove(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct msm8996_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - - if (gpio_is_valid(ext_us_amp_gpio)) - gpio_free(ext_us_amp_gpio); - - gpio_free(pdata->us_euro_gpio); - gpio_free(pdata->hph_en1_gpio); - gpio_free(pdata->hph_en0_gpio); - - if (msm8996_liquid_dock_dev != NULL) { - switch_dev_unregister(&msm8996_liquid_dock_dev->audio_sdev); - - if (msm8996_liquid_dock_dev->dock_plug_irq) - free_irq(msm8996_liquid_dock_dev->dock_plug_irq, - msm8996_liquid_dock_dev); - - if (msm8996_liquid_dock_dev->dock_plug_gpio) - gpio_free(msm8996_liquid_dock_dev->dock_plug_gpio); - - kfree(msm8996_liquid_dock_dev); - msm8996_liquid_dock_dev = NULL; - } - snd_soc_unregister_card(card); - - return 0; -} - -static struct platform_driver msm8996_asoc_machine_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .pm = &snd_soc_pm_ops, - .of_match_table = msm8996_asoc_machine_of_match, - }, - .probe = msm8996_asoc_machine_probe, - .remove = msm8996_asoc_machine_remove, -}; -module_platform_driver(msm8996_asoc_machine_driver); - -MODULE_DESCRIPTION("ALSA SoC msm"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:" DRV_NAME); -MODULE_DEVICE_TABLE(of, msm8996_asoc_machine_of_match); diff --git a/asoc/sdm660-external.c b/asoc/sdm660-external.c index 0358ad8ad9b4..1c12bfd732cd 100644 --- a/asoc/sdm660-external.c +++ b/asoc/sdm660-external.c @@ -20,7 +20,6 @@ #include #include #include "msm-pcm-routing-v2.h" -#include "msm-audio-pinctrl.h" #include "sdm660-common.h" #include "sdm660-external.h" #include "codecs/wcd9335.h" -- GitLab From 0713e26a7d146cc3eda5f9dfee06a7cce802a876 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 30 Aug 2017 22:28:49 +0530 Subject: [PATCH 0023/1645] autoconf: update config to support DLKM audio for WCD/WSA To support DLKM audio for WCD/WSA drivers on SDM845, update conf file to install as module(.ko) for required configs. CRs-Fixed: 2082310 Change-Id: I359799ac8c8ac050fce1eac8741837004f9f6a0b Signed-off-by: Laxminath Kasam --- config/sdm845auto.conf | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/config/sdm845auto.conf b/config/sdm845auto.conf index 64ca29f9da4a..5234e2b3a618 100644 --- a/config/sdm845auto.conf +++ b/config/sdm845auto.conf @@ -1,14 +1,16 @@ -CONFIG_PINCTRL_WCD=y -CONFIG_SND_SOC_WCD934X=y -CONFIG_AUDIO_EXT_CLK=y -CONFIG_SND_SOC_WCD9XXX_V2=y -CONFIG_SND_SOC_WCD_MBHC=y -CONFIG_SND_SOC_WSA881X=y -CONFIG_SND_SOC_WCD_DSP_MGR=y -CONFIG_SND_SOC_WCD_SPI=y -CONFIG_SND_SOC_WCD934X=y -CONFIG_SND_SOC_WCD934X_MBHC=y -CONFIG_SND_SOC_WCD934X_DSD=y +CONFIG_PINCTRL_WCD=m +CONFIG_SND_SOC_WCD9XXX_V2=m +CONFIG_SND_SOC_WCD_MBHC=m +CONFIG_SND_SOC_WSA881X=m +CONFIG_SND_SOC_WCD_SPI=m +CONFIG_SND_SOC_WCD934X=m +CONFIG_SOUNDWIRE_WCD_CTRL=m +CONFIG_WCD9XXX_CODEC_CORE=m +CONFIG_MSM_CDC_PINCTRL=m +CONFIG_SND_SOC_WCD934X_MBHC=m +CONFIG_SND_SOC_WCD934X_DSD=m +CONFIG_SND_SOC_MACHINE_SDM845=m +CONFIG_WCD_DSP_GLINK=m CONFIG_MSM_QDSP6V2_CODECS=y CONFIG_MSM_ULTRASOUND=y CONFIG_MSM_QDSP6_APRV2_GLINK=y @@ -19,15 +21,10 @@ CONFIG_MSM_QDSP6_SSR=y CONFIG_MSM_QDSP6_PDR=y CONFIG_MSM_QDSP6_NOTIFIER=y CONFIG_SND_SOC_MSM_HOSTLESS_PCM=y -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y CONFIG_SND_SOC_SDM845=y CONFIG_MSM_GLINK_SPI_XPRT=y CONFIG_SOUNDWIRE=y -CONFIG_SOUNDWIRE_WCD_CTRL=y CONFIG_SND_SOC_QDSP6V2=y -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y -CONFIG_MSM_CDC_PINCTRL=y -CONFIG_WCD9XXX_CODEC_CORE=y CONFIG_SND_SOC_WCD_MBHC_ADC=y CONFIG_QTI_PP=y CONFIG_SND_HWDEP=y @@ -35,8 +32,6 @@ CONFIG_DTS_EAGLE=y CONFIG_DOLBY_DS2=y CONFIG_DOLBY_LICENSE=y CONFIG_DTS_SRS_TM=y -CONFIG_SND_SOC_MACHINE_SDM845=y CONFIG_SND_SOC_MSM_STUB=y -CONFIG_WCD_DSP_GLINK=y CONFIG_MSM_AVTIMER=y CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y -- GitLab From 73f4dfff2075eac9e064450156ddf44bae6a7d61 Mon Sep 17 00:00:00 2001 From: Asish Bhattacharya Date: Sun, 10 Sep 2017 09:58:32 +0530 Subject: [PATCH 0024/1645] autoconf: enabled HDMI for sdm670 Fix compilation of kernel for sdm670. Change-Id: Ice7768e280a924043b7aafb4d8f7e9fdc051134b Signed-off-by: Asish Bhattacharya --- config/sdm670auto.conf | 1 + config/sdm670autoconf.h | 1 + 2 files changed, 2 insertions(+) diff --git a/config/sdm670auto.conf b/config/sdm670auto.conf index 59e27dc313f5..cbeb2dee9ae8 100644 --- a/config/sdm670auto.conf +++ b/config/sdm670auto.conf @@ -44,3 +44,4 @@ CONFIG_WCD_DSP_GLINK=y CONFIG_MSM_AVTIMER=y CONFIG_SND_SOC_SDM660_CDC=y CONFIG_SND_SOC_MSM_SDW=y +CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y diff --git a/config/sdm670autoconf.h b/config/sdm670autoconf.h index 7b3a3515da36..1cec92c8c7a8 100644 --- a/config/sdm670autoconf.h +++ b/config/sdm670autoconf.h @@ -57,3 +57,4 @@ #define CONFIG_SND_SOC_INT_CODEC 1 #define CONFIG_SND_SOC_SDM660_CDC 1 #define CONFIG_SND_SOC_MSM_SDW 1 +#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 -- GitLab From f0cb90b1f715e02d8eb0cdb7ac01931643d0f290 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 7 Sep 2017 11:40:08 +0530 Subject: [PATCH 0025/1645] dsp: assign channel mapping for Quad Mic use case Assign channel mapping for Quad Mic voice use case in channel info command during voice setup as DSP requires channel mapping to be sent with default values. CRs-Fixed: 2097341 Change-Id: I661f845c26f8639e5e8dffa430ecc8cb3b3e8780 Signed-off-by: Aditya Bavanari --- dsp/q6voice.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 7cd340f96177..d7d19b7af0f3 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -36,6 +36,7 @@ #define CMD_STATUS_FAIL 1 #define NUM_CHANNELS_MONO 1 #define NUM_CHANNELS_STEREO 2 +#define NUM_CHANNELS_QUAD 4 #define CVP_VERSION_2 2 enum { @@ -3889,11 +3890,15 @@ static int voice_send_cvp_channel_info_v2(struct voice_data *v, } else if (channel_info->num_channels == NUM_CHANNELS_STEREO) { channel_info->channel_mapping[0] = PCM_CHANNEL_FL; channel_info->channel_mapping[1] = PCM_CHANNEL_FR; + } else if (channel_info->num_channels == NUM_CHANNELS_QUAD && + param_type == TX_PATH) { + channel_info->channel_mapping[0] = PCM_CHANNEL_FL; + channel_info->channel_mapping[1] = PCM_CHANNEL_FR; + channel_info->channel_mapping[2] = PCM_CHANNEL_LS; + channel_info->channel_mapping[3] = PCM_CHANNEL_RS; } else { - pr_err("%s: Unsupported num channels: %d\n", - __func__, channel_info->num_channels); - ret = -EINVAL; - goto done; + pr_warn("%s: Unsupported num channels: %d for path: %d\n", + __func__, channel_info->num_channels, param_type); } v->cvp_state = CMD_STATUS_FAIL; @@ -4014,10 +4019,8 @@ static int voice_send_cvp_mfc_config_v2(struct voice_data *v) mfc_config_info->channel_type[0] = PCM_CHANNEL_FL; mfc_config_info->channel_type[1] = PCM_CHANNEL_FR; } else { - pr_err("%s: Unsupported num channels: %d\n", - __func__, mfc_config_info->num_channels); - ret = -EINVAL; - goto done; + pr_warn("%s: Unsupported num channels: %d\n", + __func__, mfc_config_info->num_channels); } v->cvp_state = CMD_STATUS_FAIL; -- GitLab From 245361df3830a3bf7263e90a1e373d5bd6409577 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 7 Sep 2017 12:11:30 +0530 Subject: [PATCH 0026/1645] dsp: fix 2nd channel mute in VPRx out for Stereo EC ref In Stereo EC reference, mute is observed in VPRx output of 2nd channel when only speaker device uses custom MFC topology. When handset and speaker use the same custom topology, issue is not observed. Because when DSP VPRx module creates the custom topology with handset configuration (1 channel and center channel mapping) and device switch to speaker occurs MFC conversion from center to left and right channels is successful. But in case where handset uses default topology, when device switch to speaker occurs, VPRx creates the custom topology with speaker configuration(2 channels and left mapping). So, when MFC config is received, only left->left mapping is done which leads to mute in right channel. Fix is to send the channel mixer configuration to MFC module so that both left->left and left->right mapping is done. CRs-Fixed: 2102374 Change-Id: If9be09866615e6623e78f48b9841eb068c825992 Signed-off-by: Aditya Bavanari --- dsp/q6voice.c | 106 +++++++++++++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 3 ++ include/dsp/q6voice.h | 57 ++++++++++++++++++++ 3 files changed, 166 insertions(+) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index d7d19b7af0f3..6f70f57dc400 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -38,6 +38,7 @@ #define NUM_CHANNELS_STEREO 2 #define NUM_CHANNELS_QUAD 4 #define CVP_VERSION_2 2 +#define GAIN_Q14_FORMAT(a) (a << 14) enum { VOC_TOKEN_NONE, @@ -3958,6 +3959,103 @@ static int voice_send_cvp_channel_info_cmd(struct voice_data *v) return ret; } +static int voice_send_cvp_ch_mixer_info_v2(struct voice_data *v) +{ + int ret; + struct cvp_set_channel_mixer_info_cmd_v2 cvp_set_ch_mixer_info_cmd; + void *apr_cvp; + u16 cvp_handle; + struct vss_icommon_param_data_ch_mixer_v2_t *cvp_config_param_data = + &cvp_set_ch_mixer_info_cmd. + cvp_set_ch_mixer_param_v2.param_data; + struct vss_param_channel_mixer_info_t *ch_mixer_info = + &cvp_config_param_data->ch_mixer_info; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + apr_cvp = common.apr_q6_cvp; + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + cvp_handle = voice_get_cvp_handle(v); + memset(&cvp_set_ch_mixer_info_cmd, 0, + sizeof(cvp_set_ch_mixer_info_cmd)); + + cvp_set_ch_mixer_info_cmd.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_set_ch_mixer_info_cmd.hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_set_ch_mixer_info_cmd) - APR_HDR_SIZE); + cvp_set_ch_mixer_info_cmd.hdr.src_svc = 0; + cvp_set_ch_mixer_info_cmd.hdr.src_domain = APR_DOMAIN_APPS; + cvp_set_ch_mixer_info_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_set_ch_mixer_info_cmd.hdr.dest_svc = 0; + cvp_set_ch_mixer_info_cmd.hdr.dest_domain = APR_DOMAIN_ADSP; + cvp_set_ch_mixer_info_cmd.hdr.dest_port = cvp_handle; + cvp_set_ch_mixer_info_cmd.hdr.token = VOC_GENERIC_SET_PARAM_TOKEN; + cvp_set_ch_mixer_info_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2; + cvp_set_ch_mixer_info_cmd.cvp_set_ch_mixer_param_v2.mem_size = + sizeof(struct vss_icommon_param_data_ch_mixer_v2_t); + + cvp_config_param_data->module_id = AUDPROC_MODULE_ID_MFC; + cvp_config_param_data->param_id = + AUDPROC_CHMIXER_PARAM_ID_COEFF; + cvp_config_param_data->param_size = + sizeof(struct vss_param_channel_mixer_info_t); + + ch_mixer_info->index = 0; + ch_mixer_info->num_output_channels = v->dev_rx.no_of_channels; + /* + * Configure Rx input to be mono for channel mixer as the DSP + * configures vocproc input as mono. + */ + ch_mixer_info->num_input_channels = NUM_CHANNELS_MONO; + ch_mixer_info->out_channel_map[0] = PCM_CHANNEL_L; + ch_mixer_info->out_channel_map[1] = PCM_CHANNEL_R; + ch_mixer_info->in_channel_map[0] = PCM_CHANNEL_L; + ch_mixer_info->channel_weight_coeff[0][0] = GAIN_Q14_FORMAT(1); + ch_mixer_info->channel_weight_coeff[1][0] = GAIN_Q14_FORMAT(1); + ch_mixer_info->reserved = 0; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *)&cvp_set_ch_mixer_info_cmd); + if (ret < 0) { + pr_err("%s: Failed to send VSS_ICOMMON_CMD_SET_PARAM_V2 %d\n", + __func__, ret); + goto done; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s] handle = %d\n", __func__, + adsp_err_get_err_str(v->async_err), cvp_handle); + ret = adsp_err_get_lnx_err_code(v->async_err); + goto done; + } + ret = 0; +done: + return ret; +} + static int voice_send_cvp_mfc_config_v2(struct voice_data *v) { int ret; @@ -4057,7 +4155,15 @@ static int voice_send_cvp_mfc_config_cmd(struct voice_data *v) int ret = 0; if (common.cvp_version >= CVP_VERSION_2) { + ret = voice_send_cvp_ch_mixer_info_v2(v); + if (ret < 0) + pr_warn("%s: Set channel mixer config failed err:%d", + __func__, ret); + ret = voice_send_cvp_mfc_config_v2(v); + if (ret < 0) + pr_warn("%s: Set MFC config failed err:%d", + __func__, ret); } else { pr_warn("%s: CVP Version not supported\n", __func__); ret = -EINVAL; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 2256b7b4d9b8..8e9b6294156b 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -623,6 +623,9 @@ struct audproc_softvolume_params { */ #define AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT 0x00010913 +/* Param ID of Channel Mixer used by AUDPROC_MODULE_ID_MFC */ +#define AUDPROC_CHMIXER_PARAM_ID_COEFF 0x00010342 + struct audproc_mfc_output_media_fmt { struct adm_cmd_set_pp_params_v5 params; diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index 7818707b5aa9..af7995a01cd9 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -245,6 +245,16 @@ struct vss_param_vocproc_dev_channel_info_t { uint8_t channel_mapping[VSS_NUM_CHANNELS_MAX]; } __packed; +struct vss_param_channel_mixer_info_t { + uint32_t index; + uint16_t num_output_channels; + uint16_t num_input_channels; + uint16_t out_channel_map[2]; + uint16_t in_channel_map[1]; + uint16_t channel_weight_coeff[2][1]; + uint16_t reserved; +} __packed; + struct vss_param_mfc_config_info_t { uint32_t sample_rate; uint16_t bits_per_sample; @@ -313,6 +323,47 @@ struct vss_icommon_cmd_set_param_channel_info_v2_t { struct vss_icommon_param_data_channel_info_v2_t param_data; } __packed; +struct vss_icommon_param_data_ch_mixer_v2_t { + /* Valid ID of the module. */ + uint32_t module_id; + /* Valid ID of the parameter. */ + uint32_t param_id; + /* + * Data size of the structure relating to the param_id/module_id + * combination in uint8_t bytes. + */ + uint16_t param_size; + /* This field must be set to zero. */ + uint16_t reserved; + struct vss_param_channel_mixer_info_t ch_mixer_info; +} __packed; + +struct vss_icommon_cmd_set_param_ch_mixer_v2_t { + /* + * Pointer to the unique identifier for an address (physical/virtual). + * + * If the parameter data payload is within the message payload + * (in-band), set this field to 0. The parameter data begins at the + * specified data payload address. + * + * If the parameter data is out-of-band, this field is the handle to + * the physical address in the shared memory that holds the parameter + * data. + */ + uint32_t mem_handle; + /* + * Location of the parameter data payload. + * + * The payload is an array of vss_icommon_param_data_t. If the + * mem_handle is 0, this field is ignored. + */ + uint64_t mem_address; + /* Size of the parameter data payload in bytes. */ + uint32_t mem_size; + + struct vss_icommon_param_data_ch_mixer_v2_t param_data; +} __packed; + struct vss_icommon_param_data_mfc_config_v2_t { /* Valid ID of the module. */ uint32_t module_id; @@ -1595,6 +1646,12 @@ struct cvp_set_channel_info_cmd_v2 { cvp_set_ch_info_param_v2; } __packed; +struct cvp_set_channel_mixer_info_cmd_v2 { + struct apr_hdr hdr; + struct vss_icommon_cmd_set_param_ch_mixer_v2_t + cvp_set_ch_mixer_param_v2; +} __packed; + struct cvp_set_mfc_config_cmd_v2 { struct apr_hdr hdr; struct vss_icommon_cmd_set_param_mfc_config_v2_t cvp_set_mfc_param_v2; -- GitLab From 60871bde94822da700156d1e47139d7bb26a823b Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Fri, 8 Sep 2017 11:26:51 -0700 Subject: [PATCH 0027/1645] ipc: initialize glink link state There is a chance that glink channel memory pointer is used after free if WDSP_REG_PKT and WDSP_CMD_PKT are received at the same time from different threads. Fix this issue by initializing glink link state to GLINK_LINK_STATE_DOWN. Also limit error logs to avoid watchdog timeout issues. Change-Id: I07c4e6f12eb057405eb59f1c0d04b890fa964ce8 Signed-off-by: Vidyakumar Athota --- ipc/wcd-dsp-glink.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/ipc/wcd-dsp-glink.c b/ipc/wcd-dsp-glink.c index 870b9f7455d3..095205c52c18 100644 --- a/ipc/wcd-dsp-glink.c +++ b/ipc/wcd-dsp-glink.c @@ -570,7 +570,7 @@ static int wdsp_glink_ch_info_init(struct wdsp_glink_priv *wpriv, mutex_lock(&wpriv->glink_mutex); if (wpriv->ch) { - dev_err(wpriv->dev, "%s: glink ch memory is already allocated\n", + dev_err_ratelimited(wpriv->dev, "%s: glink ch memory is already allocated\n", __func__); ret = -EINVAL; goto done; @@ -579,7 +579,7 @@ static int wdsp_glink_ch_info_init(struct wdsp_glink_priv *wpriv, no_of_channels = pkt->no_of_channels; if (no_of_channels > WDSP_MAX_NO_OF_CHANNELS) { - dev_err(wpriv->dev, "%s: no_of_channels: %d but max allowed are %d\n", + dev_err_ratelimited(wpriv->dev, "%s: no_of_channels: %d but max allowed are %d\n", __func__, no_of_channels, WDSP_MAX_NO_OF_CHANNELS); ret = -EINVAL; goto done; @@ -598,20 +598,20 @@ static int wdsp_glink_ch_info_init(struct wdsp_glink_priv *wpriv, size += WDSP_CH_CFG_SIZE; if (size > pkt_size) { - dev_err(wpriv->dev, "%s: Invalid size = %zd, pkt_size = %zd\n", + dev_err_ratelimited(wpriv->dev, "%s: Invalid size = %zd, pkt_size = %zd\n", __func__, size, pkt_size); ret = -EINVAL; goto err_ch_mem; } if (ch_cfg->no_of_intents > WDSP_MAX_NO_OF_INTENTS) { - dev_err(wpriv->dev, "%s: Invalid no_of_intents = %d\n", + dev_err_ratelimited(wpriv->dev, "%s: Invalid no_of_intents = %d\n", __func__, ch_cfg->no_of_intents); ret = -EINVAL; goto err_ch_mem; } size += (sizeof(u32) * ch_cfg->no_of_intents); if (size > pkt_size) { - dev_err(wpriv->dev, "%s: Invalid size = %zd, pkt_size = %zd\n", + dev_err_ratelimited(wpriv->dev, "%s: Invalid size = %zd, pkt_size = %zd\n", __func__, size, pkt_size); ret = -EINVAL; goto err_ch_mem; @@ -746,7 +746,7 @@ static ssize_t wdsp_glink_read(struct file *file, char __user *buf, } if (count > WDSP_MAX_READ_SIZE) { - dev_info(wpriv->dev, "%s: count = %zd is more than WDSP_MAX_READ_SIZE\n", + dev_info_ratelimited(wpriv->dev, "%s: count = %zd is more than WDSP_MAX_READ_SIZE\n", __func__, count); count = WDSP_MAX_READ_SIZE; } @@ -778,7 +778,7 @@ static ssize_t wdsp_glink_read(struct file *file, char __user *buf, if (ret1) { mutex_unlock(&wpriv->rsp_mutex); - dev_err(wpriv->dev, "%s: copy_to_user failed %d\n", + dev_err_ratelimited(wpriv->dev, "%s: copy_to_user failed %d\n", __func__, ret); ret = -EFAULT; goto done; @@ -824,7 +824,7 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, if ((count < WDSP_WRITE_PKT_SIZE) || (count > WDSP_MAX_WRITE_SIZE)) { - dev_err(wpriv->dev, "%s: Invalid count = %zd\n", + dev_err_ratelimited(wpriv->dev, "%s: Invalid count = %zd\n", __func__, count); ret = -EINVAL; goto done; @@ -841,7 +841,7 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, ret = copy_from_user(tx_buf->buf, buf, count); if (ret) { - dev_err(wpriv->dev, "%s: copy_from_user failed %d\n", + dev_err_ratelimited(wpriv->dev, "%s: copy_from_user failed %d\n", __func__, ret); ret = -EFAULT; goto free_buf; @@ -852,7 +852,7 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, case WDSP_REG_PKT: if (count < (WDSP_WRITE_PKT_SIZE + WDSP_REG_PKT_SIZE + WDSP_CH_CFG_SIZE)) { - dev_err(wpriv->dev, "%s: Invalid reg pkt size = %zd\n", + dev_err_ratelimited(wpriv->dev, "%s: Invalid reg pkt size = %zd\n", __func__, count); ret = -EINVAL; goto free_buf; @@ -861,7 +861,7 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, (struct wdsp_reg_pkt *)wpkt->payload, count); if (ret < 0) - dev_err(wpriv->dev, "%s: glink register failed, ret = %d\n", + dev_err_ratelimited(wpriv->dev, "%s: glink register failed, ret = %d\n", __func__, ret); vfree(tx_buf); break; @@ -871,7 +871,7 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, GLINK_LINK_STATE_UP), msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { - dev_err(wpriv->dev, "%s: Link state wait timeout\n", + dev_err_ratelimited(wpriv->dev, "%s: Link state wait timeout\n", __func__); ret = -ETIMEDOUT; goto free_buf; @@ -881,7 +881,7 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, break; case WDSP_CMD_PKT: if (count <= (WDSP_WRITE_PKT_SIZE + WDSP_CMD_PKT_SIZE)) { - dev_err(wpriv->dev, "%s: Invalid cmd pkt size = %zd\n", + dev_err_ratelimited(wpriv->dev, "%s: Invalid cmd pkt size = %zd\n", __func__, count); ret = -EINVAL; goto free_buf; @@ -889,7 +889,7 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, mutex_lock(&wpriv->glink_mutex); if (wpriv->glink_state.link_state == GLINK_LINK_STATE_DOWN) { mutex_unlock(&wpriv->glink_mutex); - dev_err(wpriv->dev, "%s: Link state is Down\n", + dev_err_ratelimited(wpriv->dev, "%s: Link state is Down\n", __func__); ret = -ENETRESET; @@ -901,7 +901,7 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, sizeof(struct wdsp_cmd_pkt) + cpkt->payload_size; if (count < pkt_max_size) { - dev_err(wpriv->dev, "%s: Invalid cmd pkt count = %zd, pkt_size = %zd\n", + dev_err_ratelimited(wpriv->dev, "%s: Invalid cmd pkt count = %zd, pkt_size = %zd\n", __func__, count, pkt_max_size); ret = -EINVAL; goto free_buf; @@ -917,7 +917,7 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, } } if (!tx_buf->ch) { - dev_err(wpriv->dev, "%s: Failed to get glink channel\n", + dev_err_ratelimited(wpriv->dev, "%s: Failed to get glink channel\n", __func__); ret = -EINVAL; goto free_buf; @@ -928,7 +928,7 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, GLINK_CONNECTED), msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { - dev_err(wpriv->dev, "%s: glink channel %s is not in connected state %d\n", + dev_err_ratelimited(wpriv->dev, "%s: glink channel %s is not in connected state %d\n", __func__, tx_buf->ch->ch_cfg.name, tx_buf->ch->channel_state); ret = -ETIMEDOUT; @@ -940,7 +940,8 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, queue_work(wpriv->work_queue, &tx_buf->tx_work); break; default: - dev_err(wpriv->dev, "%s: Invalid packet type\n", __func__); + dev_err_ratelimited(wpriv->dev, "%s: Invalid packet type\n", + __func__); ret = -EINVAL; vfree(tx_buf); break; @@ -986,6 +987,7 @@ static int wdsp_glink_open(struct inode *inode, struct file *file) goto err_wq; } + wpriv->glink_state.link_state = GLINK_LINK_STATE_DOWN; init_completion(&wpriv->rsp_complete); init_waitqueue_head(&wpriv->link_state_wait); mutex_init(&wpriv->rsp_mutex); -- GitLab From 861a8fa60c95fb9f7fa1784c00173754ddb45a11 Mon Sep 17 00:00:00 2001 From: Tanya Dixit Date: Tue, 12 Sep 2017 15:38:21 +0530 Subject: [PATCH 0028/1645] dsp: fix no recovery after SSR/PDR Add apr_reset for q6core service to enable glink channel to close and open properly after SSR. CRs-Fixed: 2099312 Change-Id: Ia023cdb19a6a9dc7fae3e5c28ab51ddd92d37527 Signed-off-by: Tanya Dixit --- dsp/q6core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dsp/q6core.c b/dsp/q6core.c index 8d82704055fc..95b203a74b07 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -210,7 +210,11 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) case RESET_EVENTS:{ pr_debug("%s: Reset event received in Core service\n", __func__); - /* no reset done as the data will not change after SSR*/ + /* + * no reset for q6core_avcs_ver_info done as + * the data will not change after SSR + */ + apr_reset(q6core_lcl.core_handle_q); q6core_lcl.core_handle_q = NULL; break; } -- GitLab From a6b2a5317309c757a16fb4f40bce616bc9d1a4f9 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Thu, 24 Aug 2017 16:50:06 -0700 Subject: [PATCH 0029/1645] ASoC: sdm845: add support to enable QUAT TDM TX path Add support to update QUAT TDM TX HW parameters and back end DAI link ops to enable QUAT TDM recording feature on SDM845. Change-Id: If0fccafaf563f9453559a45a59300a5bec75f449 Signed-off-by: Xiaoyu Ye --- asoc/sdm845.c | 52 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/asoc/sdm845.c b/asoc/sdm845.c index a3654d8ecdb2..ce5373cda341 100644 --- a/asoc/sdm845.c +++ b/asoc/sdm845.c @@ -4495,21 +4495,22 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream, unsigned int slot_mask; unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; - pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); - - slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; - /*2 slot config - bits 0 and 1 set for the first two slots */ - slot_mask = 0x0000FFFF >> (16-slots); slot_width = 32; - channels = slots; + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); - pr_debug("%s: slot_width %d slots %d\n", __func__, slot_width, slots); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - pr_debug("%s: slot_width %d\n", __func__, slot_width); + slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + /*2 slot config - bits 0 and 1 set for the first two slots */ + slot_mask = 0x0000FFFF >> (16-slots); + channels = slots; + + pr_debug("%s: tdm rx slot_width %d slots %d\n", + __func__, slot_width, slots); + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, slots, slot_width); if (ret < 0) { - pr_err("%s: failed to set tdm slot, err:%d\n", + pr_err("%s: failed to set tdm rx slot, err:%d\n", __func__, ret); goto end; } @@ -4517,11 +4518,36 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream, ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, channels, slot_offset); if (ret < 0) { - pr_err("%s: failed to set channel map, err:%d\n", + pr_err("%s: failed to set tdm rx channel map, err:%d\n", + __func__, ret); + goto end; + } + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + /*2 slot config - bits 0 and 1 set for the first two slots */ + slot_mask = 0x0000FFFF >> (16-slots); + channels = slots; + + pr_debug("%s: tdm tx slot_width %d slots %d\n", + __func__, slot_width, slots); + + ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm tx slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + channels, slot_offset, 0, NULL); + if (ret < 0) { + pr_err("%s: failed to set tdm tx channel map, err:%d\n", __func__, ret); goto end; } } else { + ret = -EINVAL; pr_err("%s: invalid use case, err:%d\n", __func__, ret); } @@ -4540,7 +4566,7 @@ static int sdm845_tdm_snd_startup(struct snd_pcm_substream *substream) ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); if (ret) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", __func__, ret); return ret; @@ -4556,7 +4582,7 @@ static void sdm845_tdm_snd_shutdown(struct snd_pcm_substream *substream) ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); if (ret) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", __func__, ret); } @@ -5734,7 +5760,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, + .ops = &sdm845_tdm_be_ops, .ignore_suspend = 1, }, }; -- GitLab From 1cb5ce084c7853c77397d94622c5b3d30208dd46 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Tue, 12 Sep 2017 18:19:08 -0700 Subject: [PATCH 0030/1645] ASoC: msm: qdsp6v2: add support to enable 4-channel QUAT TDM recording Add the corresponding 'cap_mask' to support 4 slots configuration in CPU DAI driver to enable 4-channel QUAT TDM recording feature on SDM845. Change-Id: I137d874b00fadde7513ab6c843f61becc74feac1 Signed-off-by: Xiaoyu Ye --- asoc/msm-dai-q6-v2.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 6b620a5c8ed0..1d01026f1cf2 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -6104,11 +6104,14 @@ static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai, return -EINVAL; } - /* HW only supports 16 and 8 slots configuration */ + /* HW supports 1-32 slots configuration. Typical: 1, 2, 4, 8, 16, 32 */ switch (slots) { case 2: cap_mask = 0x03; break; + case 4: + cap_mask = 0x0F; + break; case 8: cap_mask = 0xFF; break; -- GitLab From 2d0102dd44b605c9ae24dd93e49b9de7811fffe4 Mon Sep 17 00:00:00 2001 From: Siena Richard Date: Tue, 5 Sep 2017 11:15:45 -0700 Subject: [PATCH 0031/1645] dsp: allocate contiguous memory for version information Allocate contiguous memory for version information instead of splitting it across the stack and heap to centralize memory and improve readability. CRs-Fixed: 2104576 Signed-off-by: Siena Richard Change-Id: Id7b5942522da6312da57bfef3d3c0b55934fe1d7 --- dsp/q6core.c | 126 +++++++++++++++++-------------------- dsp/q6voice.c | 17 ++--- include/dsp/apr_audio-v2.h | 2 +- include/dsp/q6core.h | 2 +- 4 files changed, 69 insertions(+), 78 deletions(-) diff --git a/dsp/q6core.c b/dsp/q6core.c index 8d82704055fc..72c146b0230d 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -46,7 +46,7 @@ enum ver_query_status { struct q6core_avcs_ver_info { enum ver_query_status status; - struct avcs_fwk_ver_info ver_info; + struct avcs_fwk_ver_info *ver_info; }; struct q6core_str { @@ -84,53 +84,40 @@ static struct generic_get_data_ *generic_get_data; static int parse_fwk_version_info(uint32_t *payload) { - size_t fwk_ver_size; - size_t svc_size; + size_t ver_size; int num_services; - int ret = 0; pr_debug("%s: Payload info num services %d\n", __func__, payload[4]); + /* * payload1[4] is the number of services running on DSP * Based on this info, we copy the payload into core * avcs version info structure. */ num_services = payload[4]; - q6core_lcl.q6core_avcs_ver_info.ver_info.avcs_fwk_version. - num_services = num_services; if (num_services > VSS_MAX_AVCS_NUM_SERVICES) { pr_err("%s: num_services: %d greater than max services: %d\n", __func__, num_services, VSS_MAX_AVCS_NUM_SERVICES); - ret = -EINVAL; - goto done; + return -EINVAL; } - fwk_ver_size = sizeof(struct avcs_get_fwk_version); - svc_size = num_services * sizeof(struct avs_svc_api_info); + /* * Dynamically allocate memory for all * the services based on num_services */ - q6core_lcl.q6core_avcs_ver_info.ver_info.services = NULL; - q6core_lcl.q6core_avcs_ver_info.ver_info.services = - kzalloc(svc_size, GFP_ATOMIC); - if (q6core_lcl.q6core_avcs_ver_info.ver_info.services == NULL) { - ret = -ENOMEM; - goto done; - } - /* - * memcpy is done twice because the memory allocated for - * q6core_lcl.q6core_avcs_ver_info.ver_info is not - * contiguous. - */ - memcpy(&q6core_lcl.q6core_avcs_ver_info.ver_info, - (uint8_t *)payload, fwk_ver_size); - memcpy(q6core_lcl.q6core_avcs_ver_info.ver_info.services, - (uint8_t *)&payload[sizeof(struct avcs_get_fwk_version)/ - sizeof(uint32_t)], svc_size); - ret = 0; -done: - return ret; + ver_size = sizeof(struct avcs_get_fwk_version) + + num_services * sizeof(struct avs_svc_api_info); + if (q6core_lcl.q6core_avcs_ver_info.ver_info != NULL) + pr_warn("%s: Version info is not NULL\n", __func__); + q6core_lcl.q6core_avcs_ver_info.ver_info = + kzalloc(ver_size, GFP_ATOMIC); + if (q6core_lcl.q6core_avcs_ver_info.ver_info == NULL) + return -ENOMEM; + + memcpy(q6core_lcl.q6core_avcs_ver_info.ver_info, (uint8_t *) payload, + ver_size); + return 0; } static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) @@ -367,58 +354,56 @@ int q6core_get_service_version(uint32_t service_id, struct avcs_fwk_ver_info *ver_info, size_t size) { + struct avcs_fwk_ver_info *cached_ver_info = NULL; int i; uint32_t num_services; - size_t svc_size; + size_t ver_size; + int ret; - svc_size = q6core_get_avcs_service_size(service_id); - if (svc_size != size) { - pr_err("%s: Expected size: %zu, Provided size: %zu\n", - __func__, svc_size, size); + if (ver_info == NULL) { + pr_err("%s: ver_info is NULL\n", __func__); return -EINVAL; } - num_services = - q6core_lcl.q6core_avcs_ver_info.ver_info. - avcs_fwk_version.num_services; + ret = q6core_get_fwk_version_size(service_id); + if (ret < 0) { + pr_err("%s: Failed to get service size for service id %d with error %d\n", + __func__, service_id, ret); + return ret; + } - if (ver_info == NULL) { - pr_err("%s: NULL parameter ver_info\n", __func__); + ver_size = ret; + if (ver_size != size) { + pr_err("%s: Expected size %zu and provided size %zu do not match\n", + __func__, ver_size, size); return -EINVAL; } - memcpy(ver_info, &q6core_lcl.q6core_avcs_ver_info. - ver_info.avcs_fwk_version, sizeof(struct avcs_get_fwk_version)); + cached_ver_info = q6core_lcl.q6core_avcs_ver_info.ver_info; + num_services = cached_ver_info->avcs_fwk_version.num_services; if (service_id == AVCS_SERVICE_ID_ALL) { - memcpy(&ver_info->services[0], &q6core_lcl. - q6core_avcs_ver_info.ver_info.services[0], - (num_services * sizeof(struct avs_svc_api_info))); - } else { - for (i = 0; i < num_services; i++) { - if (q6core_lcl.q6core_avcs_ver_info. - ver_info.services[i].service_id == service_id) { - memcpy(&ver_info->services[0], - &q6core_lcl.q6core_avcs_ver_info. - ver_info.services[i], size); - break; - } - } + memcpy(ver_info, cached_ver_info, ver_size); + return 0; } - return 0; + ver_info->avcs_fwk_version = cached_ver_info->avcs_fwk_version; + for (i = 0; i < num_services; i++) { + if (cached_ver_info->services[i].service_id == service_id) { + ver_info->services[0] = cached_ver_info->services[i]; + return 0; + } + } + pr_err("%s: No service matching service ID %d\n", __func__, service_id); + return -EINVAL; } EXPORT_SYMBOL(q6core_get_service_version); -size_t q6core_get_avcs_service_size(uint32_t service_id) +size_t q6core_get_fwk_version_size(uint32_t service_id) { int ret = 0; uint32_t num_services; - num_services = - q6core_lcl.q6core_avcs_ver_info.ver_info. - avcs_fwk_version.num_services; - mutex_lock(&(q6core_lcl.ver_lock)); pr_debug("%s: q6core_avcs_ver_info.status(%d)\n", __func__, q6core_lcl.q6core_avcs_ver_info.status); @@ -427,7 +412,6 @@ size_t q6core_get_avcs_service_size(uint32_t service_id) case VER_QUERY_SUPPORTED: pr_debug("%s: AVCS FWK version query already attempted\n", __func__); - ret = num_services * sizeof(struct avs_svc_api_info); break; case VER_QUERY_UNSUPPORTED: ret = -EOPNOTSUPP; @@ -436,9 +420,6 @@ size_t q6core_get_avcs_service_size(uint32_t service_id) pr_debug("%s: Attempting AVCS FWK version query\n", __func__); if (q6core_is_adsp_ready()) { ret = q6core_send_get_avcs_fwk_ver_cmd(); - if (ret == 0) - ret = num_services * - sizeof(struct avs_svc_api_info); } else { pr_err("%s: ADSP is not ready to query version\n", __func__); @@ -453,12 +434,21 @@ size_t q6core_get_avcs_service_size(uint32_t service_id) } mutex_unlock(&(q6core_lcl.ver_lock)); - if (service_id != AVCS_SERVICE_ID_ALL) - return sizeof(struct avs_svc_api_info); + if (ret) + goto done; + + num_services = q6core_lcl.q6core_avcs_ver_info.ver_info + ->avcs_fwk_version.num_services; + ret = sizeof(struct avcs_get_fwk_version); + if (service_id == AVCS_SERVICE_ID_ALL) + ret += num_services * sizeof(struct avs_svc_api_info); + else + ret += sizeof(struct avs_svc_api_info); +done: return ret; } -EXPORT_SYMBOL(q6core_get_avcs_service_size); +EXPORT_SYMBOL(q6core_get_fwk_version_size); int32_t core_set_license(uint32_t key, uint32_t module_id) { diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 7cd340f96177..fa338b2282d7 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -4066,8 +4066,8 @@ static int voice_send_cvp_mfc_config_cmd(struct voice_data *v) static int voice_get_avcs_version_per_service(uint32_t service_id) { int ret = 0; - size_t svc_size; - struct avcs_fwk_ver_info ver_info = {{0}, NULL}; + size_t ver_size; + struct avcs_fwk_ver_info *ver_info = NULL; if (service_id == AVCS_SERVICE_ID_ALL) { pr_err("%s: Invalid service id: %d", __func__, @@ -4075,19 +4075,20 @@ static int voice_get_avcs_version_per_service(uint32_t service_id) return -EINVAL; } - svc_size = sizeof(struct avs_svc_api_info); - ver_info.services = kzalloc(svc_size, GFP_KERNEL); - if (ver_info.services == NULL) + ver_size = sizeof(struct avcs_get_fwk_version) + + sizeof(struct avs_svc_api_info); + ver_info = kzalloc(ver_size, GFP_KERNEL); + if (ver_info == NULL) return -ENOMEM; - ret = q6core_get_service_version(service_id, &ver_info, svc_size); + ret = q6core_get_service_version(service_id, ver_info, ver_size); if (ret < 0) goto done; - ret = ver_info.services[0].api_version; + ret = ver_info->services[0].api_version; common.is_avcs_version_queried = true; done: - kfree(ver_info.services); + kfree(ver_info); return ret; } diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 2256b7b4d9b8..121efc432c59 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -9264,7 +9264,7 @@ struct avs_svc_api_info { struct avcs_fwk_ver_info { struct avcs_get_fwk_version avcs_fwk_version; - struct avs_svc_api_info *services; + struct avs_svc_api_info services[0]; } __packed; /* LSM Specific */ diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index 1f1adad031e3..f6240a33e6fd 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -25,7 +25,7 @@ bool q6core_is_adsp_ready(void); int q6core_get_service_version(uint32_t service_id, struct avcs_fwk_ver_info *ver_info, size_t size); -size_t q6core_get_avcs_service_size(uint32_t service_id); +size_t q6core_get_fwk_version_size(uint32_t service_id); #define ADSP_CMD_SET_DTS_EAGLE_DATA_ID 0x00012919 #define DTS_EAGLE_LICENSE_ID 0x00028346 -- GitLab From 2b6adc8ba19b57d3c58f02c2c154e022d9d9f4d9 Mon Sep 17 00:00:00 2001 From: Cong Tang Date: Fri, 26 May 2017 12:06:50 +0800 Subject: [PATCH 0032/1645] ASoC: add support to configure TDM dai clk attribute and clk freq TDM dai driver supports optional clk attribute configuration and clk freq update. To configure TDM interface as PCM mode, the clk attribute should be Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO. Implement set_sysclk callback function to update Quaternary TDM RX and TX clk freq. Change-Id: I41edaa8d99325e9582e04ddb81a6ad5b5e4435bc Signed-off-by: Cong Tang Signed-off-by: Xiaoyu Ye --- asoc/msm-dai-q6-v2.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 6b620a5c8ed0..189a417ebb0e 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -5127,6 +5127,25 @@ static int msm_dai_tdm_q6_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "%s: Clk Rate from DT file %d\n", __func__, tdm_clk_set.clk_freq_in_hz); + /* initialize static tdm clk attribute to default value */ + tdm_clk_set.clk_attri = Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO; + + /* extract tdm clk attribute into static */ + if (of_find_property(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-clk-attribute", NULL)) { + rc = of_property_read_u16(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-clk-attribute", + &tdm_clk_set.clk_attri); + if (rc) { + dev_err(&pdev->dev, "%s: value for clk attribute not found %s\n", + __func__, "qcom,msm-cpudai-tdm-clk-attribute"); + goto rtn; + } + dev_dbg(&pdev->dev, "%s: clk attribute from DT file %d\n", + __func__, tdm_clk_set.clk_attri); + } else + dev_dbg(&pdev->dev, "%s: clk attribute not found\n", __func__); + /* extract tdm clk src master/slave info into static */ rc = of_property_read_u32(pdev->dev.of_node, "qcom,msm-cpudai-tdm-clk-internal", @@ -6203,6 +6222,40 @@ static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai, return rc; } +static int msm_dai_q6_tdm_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct msm_dai_q6_tdm_dai_data *dai_data = + dev_get_drvdata(dai->dev); + + switch (dai->id) { + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + dai_data->clk_set.clk_freq_in_hz = freq; + break; + default: + return -EINVAL; + } + + dev_dbg(dai->dev, "%s: dai id = 0x%x, group clk_freq = %d\n", + __func__, dai->id, freq); + return 0; +} + static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_num, unsigned int *tx_slot, unsigned int rx_num, unsigned int *rx_slot) @@ -6632,6 +6685,7 @@ static struct snd_soc_dai_ops msm_dai_q6_tdm_ops = { .hw_params = msm_dai_q6_tdm_hw_params, .set_tdm_slot = msm_dai_q6_tdm_set_tdm_slot, .set_channel_map = msm_dai_q6_tdm_set_channel_map, + .set_sysclk = msm_dai_q6_tdm_set_sysclk, .shutdown = msm_dai_q6_tdm_shutdown, }; -- GitLab From f48af4ff1f4b67c172833c68ccf1bba12075d89c Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Fri, 1 Sep 2017 14:57:51 -0700 Subject: [PATCH 0033/1645] ASoC: sdm845: add support to update TDM CLK frequency at runtime TDM CLK frequency needs to be updated at runtime to use the correct CLK setup. Change-Id: Ib42fedca3cbf41b85ca121ca04cc994bf8ad4d39 Signed-off-by: Xiaoyu Ye --- asoc/sdm845.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/asoc/sdm845.c b/asoc/sdm845.c index a3654d8ecdb2..2d26aac09a4a 100644 --- a/asoc/sdm845.c +++ b/asoc/sdm845.c @@ -4492,7 +4492,7 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret = 0; int channels, slot_width, slots; - unsigned int slot_mask; + unsigned int slot_mask, rate, clk_freq; unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); @@ -4524,8 +4524,16 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream, } else { pr_err("%s: invalid use case, err:%d\n", __func__, ret); + goto end; } + rate = params_rate(params); + clk_freq = rate * slot_width * slots; + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, clk_freq, SND_SOC_CLOCK_OUT); + if (ret < 0) + pr_err("%s: failed to set tdm clk, err:%d\n", + __func__, ret); + end: return ret; } -- GitLab From a8aea17dddb8030a3bf89cb1e63779c269b4c02f Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 13 Sep 2017 11:37:53 +0530 Subject: [PATCH 0034/1645] dsp: fix dangling pointer access Assign the circular buffer address to port buffer only after ION allocation is succesful to fix dangling pointer access. Also, lock the circular buffer memory allocation in order to avoid multiple allocations for a port. CRs-Fixed: 2096407 Change-Id: I22c1d55ea611ac59cdca51924787f6831bad8c2b Signed-off-by: Aditya Bavanari --- dsp/q6asm.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 28b3f733bcd9..0a4216a0e28c 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -3350,6 +3350,15 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac, int bytes_to_alloc, rc; size_t len; + mutex_lock(&ac->cmd_lock); + + if (ac->port[dir].buf) { + pr_err("%s: Buffer already allocated\n", __func__); + rc = -EINVAL; + mutex_unlock(&ac->cmd_lock); + goto done; + } + buf_circ = kzalloc(sizeof(struct audio_buffer), GFP_KERNEL); if (!buf_circ) { @@ -3357,10 +3366,6 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac, goto done; } - mutex_lock(&ac->cmd_lock); - - ac->port[dir].buf = buf_circ; - bytes_to_alloc = bufsz * bufcnt; bytes_to_alloc = PAGE_ALIGN(bytes_to_alloc); @@ -3372,11 +3377,12 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac, if (rc) { pr_err("%s: Audio ION alloc is failed, rc = %d\n", __func__, rc); - mutex_unlock(&ac->cmd_lock); kfree(buf_circ); + mutex_unlock(&ac->cmd_lock); goto done; } + ac->port[dir].buf = buf_circ; buf_circ->used = dir ^ 1; buf_circ->size = bytes_to_alloc; buf_circ->actual_size = bytes_to_alloc; @@ -3541,12 +3547,6 @@ int q6asm_open_shared_io(struct audio_client *ac, goto done; } - if (ac->port[dir].buf) { - pr_err("%s: Buffer already allocated\n", __func__); - rc = -EINVAL; - goto done; - } - rc = q6asm_set_shared_circ_buff(ac, open, bufsz, bufcnt, dir); if (rc) -- GitLab From 016c49fa463b54e0e729a4c275750116a47b1502 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Mon, 11 Sep 2017 15:15:56 -0700 Subject: [PATCH 0035/1645] ASoC: add routing entries for Multimedia10 and Multimedia16 Add missing FE to BE links for Multimedia10 and Multimedia16 which can resolve FE to BE routing failures. Change-Id: I9f889d88fe520f7efa83c2e2058995fa955c82cb Signed-off-by: Vikram Panduranga --- asoc/msm-pcm-routing-v2.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 29dfade94f0f..788946ad8ea1 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -7311,6 +7311,30 @@ static const struct snd_kcontrol_new mmul10_mixer_controls[] = { SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AUX_PCM_TX", MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_AUX_PCM_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_AUX_PCM_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul17_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, @@ -14202,6 +14226,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_1", "QUAT_TDM_RX_1"}, {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_2", "QUAT_TDM_RX_2"}, {"AUDIO_REF_EC_UL10 MUX", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + + {"AUDIO_REF_EC_UL16 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL16 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL16 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL16 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"AUDIO_REF_EC_UL17 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"AUDIO_REF_EC_UL17 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"AUDIO_REF_EC_UL17 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, -- GitLab From a63f8be985e508d3bacba7bb1df80fee2dd4eb58 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Tue, 12 Sep 2017 16:51:26 -0700 Subject: [PATCH 0036/1645] ASoC: msm: fix compilation errors when CONFIG_QTI_PP is disabled Add dummy static inline functions for feature QTI_PP to fix compilation erros for undefined function when flag 'CONFIG_QTI_PP' is not defined. Change-Id: I24c29636755f44a80b2a0267e0dbb8f72d6a3c9d Signed-off-by: Xiaoyu Ye --- asoc/msm-qti-pp-config.h | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/asoc/msm-qti-pp-config.h b/asoc/msm-qti-pp-config.h index ade2f5e507ec..3bf97b479e84 100644 --- a/asoc/msm-qti-pp-config.h +++ b/asoc/msm-qti-pp-config.h @@ -15,6 +15,7 @@ #include #define DSP_BIT_WIDTH_MIXER_CTL "ASM Bit Width" +#ifdef CONFIG_QTI_PP int msm_adsp_inform_mixer_ctl(struct snd_soc_pcm_runtime *rtd, uint32_t *payload); int msm_adsp_init_mixer_ctl_pp_event_queue(struct snd_soc_pcm_runtime *rtd); @@ -25,7 +26,6 @@ int msm_adsp_stream_callback_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int msm_adsp_stream_callback_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); -#ifdef CONFIG_QTI_PP void msm_qti_pp_send_eq_values(int fedai_id); int msm_qti_pp_send_stereo_to_custom_stereo_cmd(int port_id, int copp_idx, unsigned int session_id, @@ -35,6 +35,42 @@ int msm_qti_pp_send_stereo_to_custom_stereo_cmd(int port_id, int copp_idx, uint16_t op_FR_ip_FR_weight); void msm_qti_pp_add_controls(struct snd_soc_platform *platform); #else /* CONFIG_QTI_PP */ +static inline int msm_adsp_inform_mixer_ctl(struct snd_soc_pcm_runtime *rtd, + uint32_t *payload) +{ + return 0; +} + +static inline int msm_adsp_init_mixer_ctl_pp_event_queue( + struct snd_soc_pcm_runtime *rtd) +{ + return 0; +} + +static inline int msm_adsp_clean_mixer_ctl_pp_event_queue( + struct snd_soc_pcm_runtime *rtd) +{ + return 0; +} + +static inline int msm_adsp_stream_cmd_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + return 0; +} + +static inline int msm_adsp_stream_callback_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static inline int msm_adsp_stream_callback_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + return 0; +} + #define msm_qti_pp_send_eq_values(fedai_id) do {} while (0) #define msm_qti_pp_send_stereo_to_custom_stereo_cmd(port_id, copp_idx, \ session_id, op_FL_ip_FL_weight, op_FL_ip_FR_weight, \ -- GitLab From ee9c03a81e6f5fc7d8b12fde367820a1e0d3e229 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Thu, 7 Sep 2017 15:06:17 -0700 Subject: [PATCH 0037/1645] asoc: send effect config based on apptype Add support to configure a specific module and its parameter on adm based on apptype. This can be used to dynamically configure a module provided by application. Change-Id: Iccfee192b0dec505bbb5f65a251e0dd12432fe59 Signed-off-by: Vikram Panduranga --- asoc/msm-pcm-routing-v2.c | 88 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 8e3fe895d98d..7a2dc54753d5 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -10816,6 +10816,91 @@ static const struct snd_kcontrol_new app_type_cfg_controls[] = { 0x2000, 0, 4, NULL, msm_routing_put_app_type_gain_control) }; +static int msm_routing_put_module_cfg_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int copp_idx, fe_id, be_id, port_type; + int ret = 0; + unsigned long copp; + struct msm_pcm_routing_bdai_data *bedai; + char *param_data = NULL; + uint32_t *update_param_data = NULL; + uint32_t param_size = sizeof(uint32_t) + + sizeof(struct adm_param_data_v5); + int dir = ucontrol->value.integer.value[0] ? SESSION_TYPE_TX : + SESSION_TYPE_RX; + int app_type = ucontrol->value.integer.value[1]; + int module_id = ucontrol->value.integer.value[2]; + int instance_id = ucontrol->value.integer.value[3]; + int param_id = ucontrol->value.integer.value[4]; + int param_value = ucontrol->value.integer.value[5]; + + port_type = (dir == SESSION_TYPE_RX) ? MSM_AFE_PORT_TYPE_RX : + MSM_AFE_PORT_TYPE_TX; + pr_debug("%s app_type:%d mod_id:%d instance_id:%d param_id:%d value:%d\n", + __func__, app_type, module_id, + instance_id, param_id, param_value); + + param_data = kzalloc(param_size, GFP_KERNEL); + if (!param_data) + return -ENOMEM; + + update_param_data = (uint32_t *)param_data; + *update_param_data++ = module_id; + *update_param_data++ = param_id; + *update_param_data++ = sizeof(uint32_t); + *update_param_data++ = param_value; + + mutex_lock(&routing_lock); + for (be_id = 0; be_id < MSM_BACKEND_DAI_MAX; be_id++) { + if (is_be_dai_extproc(be_id)) + continue; + + bedai = &msm_bedais[be_id]; + if (afe_get_port_type(bedai->port_id) != port_type) + continue; + + if (!bedai->active) + continue; + + for (fe_id = 0; fe_id < MSM_FRONTEND_DAI_MAX; fe_id++) { + if (!test_bit(fe_id, &bedai->fe_sessions[0])) + continue; + + if (app_type != + fe_dai_app_type_cfg[fe_id][dir][be_id].app_type) + continue; + + copp = session_copp_map[fe_id][dir][be_id]; + for (copp_idx = 0; copp_idx < MAX_COPPS_PER_PORT; + copp_idx++) { + if (!test_bit(copp_idx, &copp)) + continue; + + ret = adm_send_params_v5(bedai->port_id, + copp_idx, + param_data, + param_size); + if (ret) { + pr_err("%s: Setting param failed with err=%d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + } + } + } +done: + mutex_unlock(&routing_lock); + kfree(param_data); + return ret; +} + +static const struct snd_kcontrol_new module_cfg_controls[] = { + SOC_SINGLE_MULTI_EXT("Audio Effect", SND_SOC_NOPM, 0, + 0x2000, 0, 6, NULL, msm_routing_put_module_cfg_control) +}; + static int msm_routing_get_lsm_app_type_cfg_control( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -15810,6 +15895,9 @@ static int msm_routing_probe(struct snd_soc_platform *platform) snd_soc_add_platform_controls(platform, lsm_app_type_cfg_controls, ARRAY_SIZE(lsm_app_type_cfg_controls)); + snd_soc_add_platform_controls(platform, module_cfg_controls, + ARRAY_SIZE(module_cfg_controls)); + snd_soc_add_platform_controls(platform, stereo_to_custom_stereo_controls, ARRAY_SIZE(stereo_to_custom_stereo_controls)); -- GitLab From 4d6a6bef3249f0af49793413f0237e091c2c5aa6 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Fri, 15 Sep 2017 10:35:44 +0800 Subject: [PATCH 0038/1645] ASoC: wcd-mbhc: add support to read new headset detection parameters To config different headset detection parameters for different hardware, add two new headset detection parameters in device tree and read it in mbhc driver. Change-Id: I10457b7d5eae54eba8a4cd273885a63ebad3ccb3 Signed-off-by: Meng Wang --- asoc/codecs/wcd-mbhc-adc.c | 46 +++++++++++++++++++++++++++----------- asoc/codecs/wcd-mbhc-v2.c | 14 ++++++++++++ asoc/codecs/wcd-mbhc-v2.h | 2 ++ 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index e44eec9fa5c7..097dda9e4242 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -370,11 +370,18 @@ static bool wcd_mbhc_adc_check_for_spl_headset(struct wcd_mbhc *mbhc, * btn press/relesae for HEADSET type during correct work. */ output_mv = wcd_measure_adc_once(mbhc, MUX_CTL_IN2P); - adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV * + if (mbhc->hs_thr) + adc_threshold = mbhc->hs_thr; + else + adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV * wcd_mbhc_get_micbias(mbhc))/WCD_MBHC_ADC_MICBIAS_MV); - adc_hph_threshold = ((WCD_MBHC_ADC_HPH_THRESHOLD_MV * - wcd_mbhc_get_micbias(mbhc))/ - WCD_MBHC_ADC_MICBIAS_MV); + + if (mbhc->hph_thr) + adc_hph_threshold = mbhc->hph_thr; + else + adc_hph_threshold = ((WCD_MBHC_ADC_HPH_THRESHOLD_MV * + wcd_mbhc_get_micbias(mbhc))/ + WCD_MBHC_ADC_MICBIAS_MV); if (output_mv > adc_threshold || output_mv < adc_hph_threshold) { spl_hs = false; @@ -426,8 +433,10 @@ static bool wcd_is_special_headset(struct wcd_mbhc *mbhc) return false; } } - - adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV * + if (mbhc->hs_thr) + adc_threshold = mbhc->hs_thr; + else + adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV * wcd_mbhc_get_micbias(mbhc)) / WCD_MBHC_ADC_MICBIAS_MV); @@ -556,14 +565,25 @@ static void wcd_micbias_disable(struct wcd_mbhc *mbhc) } } -static int wcd_mbhc_get_plug_from_adc(int adc_result) +static int wcd_mbhc_get_plug_from_adc(struct wcd_mbhc *mbhc, int adc_result) { enum wcd_mbhc_plug_type plug_type = MBHC_PLUG_TYPE_INVALID; + u32 hph_thr = 0, hs_thr = 0; + + if (mbhc->hs_thr) + hs_thr = mbhc->hs_thr; + else + hs_thr = WCD_MBHC_ADC_HS_THRESHOLD_MV; + + if (mbhc->hph_thr) + hph_thr = mbhc->hph_thr; + else + hph_thr = WCD_MBHC_ADC_HPH_THRESHOLD_MV; - if (adc_result < WCD_MBHC_ADC_HPH_THRESHOLD_MV) + if (adc_result < hph_thr) plug_type = MBHC_PLUG_TYPE_HEADPHONE; - else if (adc_result > WCD_MBHC_ADC_HS_THRESHOLD_MV) + else if (adc_result > hs_thr) plug_type = MBHC_PLUG_TYPE_HIGH_HPH; else plug_type = MBHC_PLUG_TYPE_HEADSET; @@ -612,7 +632,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) } /* Find plug type */ output_mv = wcd_measure_adc_continuous(mbhc); - plug_type = wcd_mbhc_get_plug_from_adc(output_mv); + plug_type = wcd_mbhc_get_plug_from_adc(mbhc, output_mv); /* * Report plug type if it is either headset or headphone @@ -667,7 +687,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) * instead of hogging system by contineous polling, wait for * sometime and re-check stop request again. */ - plug_type = wcd_mbhc_get_plug_from_adc(output_mv); + plug_type = wcd_mbhc_get_plug_from_adc(mbhc, output_mv); if ((output_mv > WCD_MBHC_ADC_HS_THRESHOLD_MV) && (spl_hs_count < WCD_MBHC_SPL_HS_CNT)) { @@ -713,7 +733,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) no_gnd_mic_swap_cnt++; pt_gnd_mic_swap_cnt = 0; plug_type = wcd_mbhc_get_plug_from_adc( - output_mv); + mbhc, output_mv); if ((no_gnd_mic_swap_cnt < GND_MIC_SWAP_THRESHOLD) && (spl_hs_count != WCD_MBHC_SPL_HS_CNT)) { @@ -747,7 +767,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) plug_type); if (plug_type != MBHC_PLUG_TYPE_GND_MIC_SWAP) { plug_type = wcd_mbhc_get_plug_from_adc( - output_mv); + mbhc, output_mv); if (!spl_hs_reported && spl_hs_count == WCD_MBHC_SPL_HS_CNT) { spl_hs_reported = true; diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 6b3dd8626da5..7e91a6e3c121 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -1838,6 +1838,8 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, struct snd_soc_card *card = codec->component.card; const char *hph_switch = "qcom,msm-mbhc-hphl-swh"; const char *gnd_switch = "qcom,msm-mbhc-gnd-swh"; + const char *hs_thre = "qcom,msm-mbhc-hs-mic-max-threshold-mv"; + const char *hph_thre = "qcom,msm-mbhc-hs-mic-min-threshold-mv"; pr_debug("%s: enter\n", __func__); @@ -1855,6 +1857,18 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, goto err; } + ret = of_property_read_u32(card->dev->of_node, hs_thre, + &(mbhc->hs_thr)); + if (ret) + dev_dbg(card->dev, + "%s: missing %s in dt node\n", __func__, hs_thre); + + ret = of_property_read_u32(card->dev->of_node, hph_thre, + &(mbhc->hph_thr)); + if (ret) + dev_dbg(card->dev, + "%s: missing %s in dt node\n", __func__, hph_thre); + ret = of_property_read_u32_array(card->dev->of_node, "qcom,msm-mbhc-moist-cfg", hph_moist_config, 3); diff --git a/asoc/codecs/wcd-mbhc-v2.h b/asoc/codecs/wcd-mbhc-v2.h index c8714fc3abbc..d180cde53413 100644 --- a/asoc/codecs/wcd-mbhc-v2.h +++ b/asoc/codecs/wcd-mbhc-v2.h @@ -518,6 +518,8 @@ struct wcd_mbhc { bool in_swch_irq_handler; bool hphl_swh; /*track HPHL switch NC / NO */ bool gnd_swh; /*track GND switch NC / NO */ + u32 hs_thr; + u32 hph_thr; u32 moist_vref; u32 moist_iref; u32 moist_rref; -- GitLab From 87c83b72af7e8718918a6dd4fce63af4072e6774 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Tue, 19 Sep 2017 12:06:46 -0700 Subject: [PATCH 0039/1645] ipc: fix out of bounds read issue If userspace sends non-null terminated channel name then out of bounds read is possible while printing channel name. Fix this issue by validating channel name before use. Change-Id: Ide270a54be14b280e87360836a0fad1302075660 Signed-off-by: Vidyakumar Athota --- ipc/wcd-dsp-glink.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/ipc/wcd-dsp-glink.c b/ipc/wcd-dsp-glink.c index 095205c52c18..cab7c3b7c4a2 100644 --- a/ipc/wcd-dsp-glink.c +++ b/ipc/wcd-dsp-glink.c @@ -634,6 +634,21 @@ static int wdsp_glink_ch_info_init(struct wdsp_glink_priv *wpriv, memcpy(&ch[i]->ch_cfg, payload, ch_cfg_size); payload += ch_cfg_size; + /* check ch name is valid string or not */ + for (j = 0; j < WDSP_CH_NAME_MAX_LEN; j++) { + if (ch[i]->ch_cfg.name[j] == '\0') + break; + } + + if (j == WDSP_CH_NAME_MAX_LEN) { + dev_err_ratelimited(wpriv->dev, "%s: Wrong channel name\n", + __func__); + kfree(ch[i]); + ch[i] = NULL; + ret = -EINVAL; + goto err_ch_mem; + } + mutex_init(&ch[i]->mutex); ch[i]->wpriv = wpriv; INIT_WORK(&ch[i]->lcl_ch_open_wrk, wdsp_glink_lcl_ch_open_wrk); @@ -906,8 +921,6 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, ret = -EINVAL; goto free_buf; } - dev_dbg(wpriv->dev, "%s: requested ch_name: %s, pkt_size: %zd\n", - __func__, cpkt->ch_name, pkt_max_size); for (i = 0; i < wpriv->no_of_channels; i++) { if (wpriv->ch && wpriv->ch[i] && (!strcmp(cpkt->ch_name, @@ -922,6 +935,8 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, ret = -EINVAL; goto free_buf; } + dev_dbg(wpriv->dev, "%s: requested ch_name: %s, pkt_size: %zd\n", + __func__, cpkt->ch_name, pkt_max_size); ret = wait_event_timeout(tx_buf->ch->ch_connect_wait, (tx_buf->ch->channel_state == -- GitLab From 83716b9a69a414977da6075e1470b54e85d91752 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 14 Sep 2017 12:13:13 +0530 Subject: [PATCH 0040/1645] ASoC: wsa881x: fix wsa881x speaker damage wsa881x speaker damage has been reported due to DC at wsa output. Add a register setting which will reset the soundwire when there are any DC or synchronization issues. CRs-Fixed: 2086505 Change-Id: Id2bfb876a5bace891befa613153a88ee54033d76 Signed-off-by: Vatsal Bucha --- asoc/codecs/wsa881x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index 456f68c81954..bff0ad539792 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -968,6 +968,8 @@ static void wsa881x_init(struct snd_soc_codec *codec) wsa881x->version = snd_soc_read(codec, WSA881X_CHIP_ID1); wsa881x_regmap_defaults(wsa881x->regmap, wsa881x->version); + /* Enable software reset output from soundwire slave */ + snd_soc_update_bits(codec, WSA881X_SWR_RESET_EN, 0x07, 0x07); /* Bring out of analog reset */ snd_soc_update_bits(codec, WSA881X_CDC_RST_CTL, 0x02, 0x02); /* Bring out of digital reset */ -- GitLab From 39603aff7b1f33bac2fb7571b47b633118a35d27 Mon Sep 17 00:00:00 2001 From: Rohit Kumar Date: Mon, 11 Sep 2017 00:00:37 +0530 Subject: [PATCH 0041/1645] ipc: apr_v2: export symbols used by WCD driver Add EXPORT_SYMBOL to symbols used by codec driver. Codec driver is built as separate module and requires symbols called to be exported. Change-Id: I3d1bc6c8cbfc1b92f790b700ecfeaff211ddcff0 Signed-off-by: Rohit Kumar --- ipc/apr_v2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ipc/apr_v2.c b/ipc/apr_v2.c index d330571f3908..7e6331009458 100644 --- a/ipc/apr_v2.c +++ b/ipc/apr_v2.c @@ -19,10 +19,16 @@ #include #include +/** + * apr_get_subsys_state - get Q6 subsys status + * + * Returns apr_subsys_state + */ enum apr_subsys_state apr_get_subsys_state(void) { return apr_get_q6_state(); } +EXPORT_SYMBOL(apr_get_subsys_state); void apr_set_subsys_state(void) { -- GitLab From e169e990eabe69efc1d43b1cea17caec61d99268 Mon Sep 17 00:00:00 2001 From: Satya Krishna Pindiproli Date: Fri, 22 Sep 2017 11:34:35 +0530 Subject: [PATCH 0042/1645] audio-lnx: dsp: codecs: modify API to configure output PCM block Pass valid channel count and sample rate information to configure AAC decoder component and modify the API used to configure the output PCM block when multi AAC decoder component is used in non-tunnelled mode. Change-Id: I5938f316a39b722924416b6910e6c8b835e7855e Signed-off-by: Satya Krishna Pindiproli --- dsp/codecs/audio_aac.c | 4 +++- dsp/codecs/audio_multi_aac.c | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/dsp/codecs/audio_aac.c b/dsp/codecs/audio_aac.c index 0f371fd1aa48..006b21c6793a 100644 --- a/dsp/codecs/audio_aac.c +++ b/dsp/codecs/audio_aac.c @@ -48,7 +48,9 @@ static long audio_ioctl_shared(struct file *file, unsigned int cmd, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ - rc = q6asm_enc_cfg_blk_pcm(audio->ac, 0, 0); + rc = q6asm_enc_cfg_blk_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); if (rc < 0) { pr_err("pcm output block config failed\n"); break; diff --git a/dsp/codecs/audio_multi_aac.c b/dsp/codecs/audio_multi_aac.c index 01c3dc5ada58..5d407e0c5e61 100644 --- a/dsp/codecs/audio_multi_aac.c +++ b/dsp/codecs/audio_multi_aac.c @@ -59,9 +59,9 @@ static long audio_ioctl_shared(struct file *file, unsigned int cmd, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ - rc = q6asm_enc_cfg_blk_pcm_native(audio->ac, - aac_cfg.sample_rate, - aac_cfg.ch_cfg); + rc = q6asm_enc_cfg_blk_pcm(audio->ac, + audio->pcm_cfg.sample_rate, + audio->pcm_cfg.channel_count); if (rc < 0) { pr_err("pcm output block config failed\n"); break; -- GitLab From 13da482a7024da66730566a1f47d83781a535166 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Mon, 18 Sep 2017 17:46:30 -0700 Subject: [PATCH 0043/1645] dsp: fix logic to send AFE calibration for TDM AFE ports AFE calibration should be sent even when the number of group ports is 1. Remove this condition from API to send AFE calibration for any number of group ports. Change-Id: I7f0c8ab739da2831e17e5dbbaf013cf99f2e6d88 Signed-off-by: Xiaoyu Ye --- dsp/q6afe.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index a6041b377525..0289144006fe 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2644,10 +2644,9 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id); } - /* Also send the topology id here if multiple ports: */ + /* Also send the topology id here: */ port_index = afe_get_port_index(port_id); - if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE) && - num_groups > 1) { + if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) { /* One time call: only for first time */ afe_send_custom_topology(); afe_send_port_topology_id(port_id); @@ -2709,14 +2708,12 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, ret = -EINVAL; goto fail_cmd; } - /* slot mapping is not need if there is only one group */ - if (num_groups > 1) { - ret = afe_send_slot_mapping_cfg(&tdm_port->slot_mapping, - port_id); - if (ret < 0) { - pr_err("%s: afe send failed %d\n", __func__, ret); - goto fail_cmd; - } + + ret = afe_send_slot_mapping_cfg(&tdm_port->slot_mapping, + port_id); + if (ret < 0) { + pr_err("%s: afe send failed %d\n", __func__, ret); + goto fail_cmd; } if (tdm_port->custom_tdm_header.header_type) { -- GitLab From a507793028a15cf331f560c11d84f9e5f10b318b Mon Sep 17 00:00:00 2001 From: Rohit Kumar Date: Sun, 10 Sep 2017 22:05:05 +0530 Subject: [PATCH 0044/1645] asoc: msm: add support for quinary interfaces in dai and routing driver Add support for dais and routing for Quinary MI2S, AUXPCM and TDM interfaces. Change-Id: I50c3099a658998bab805c4c6a5aa447e85f3e7c6 Signed-off-by: Rohit Kumar --- asoc/msm-dai-q6-v2.c | 629 ++++++++++++ asoc/msm-pcm-routing-v2.c | 1960 +++++++++++++++++++++++++++++++++--- asoc/msm-pcm-routing-v2.h | 36 + include/dsp/apr_audio-v2.h | 60 +- 4 files changed, 2552 insertions(+), 133 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 898cb1b0f674..2802a4fa170a 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -31,6 +31,7 @@ #define MSM_DAI_SEC_AUXPCM_DT_DEV_ID 2 #define MSM_DAI_TERT_AUXPCM_DT_DEV_ID 3 #define MSM_DAI_QUAT_AUXPCM_DT_DEV_ID 4 +#define MSM_DAI_QUIN_AUXPCM_DT_DEV_ID 5 #define spdif_clock_value(rate) (2*rate*32*2) @@ -155,6 +156,22 @@ enum { IDX_QUATERNARY_TDM_TX_5, IDX_QUATERNARY_TDM_TX_6, IDX_QUATERNARY_TDM_TX_7, + IDX_QUINARY_TDM_RX_0, + IDX_QUINARY_TDM_RX_1, + IDX_QUINARY_TDM_RX_2, + IDX_QUINARY_TDM_RX_3, + IDX_QUINARY_TDM_RX_4, + IDX_QUINARY_TDM_RX_5, + IDX_QUINARY_TDM_RX_6, + IDX_QUINARY_TDM_RX_7, + IDX_QUINARY_TDM_TX_0, + IDX_QUINARY_TDM_TX_1, + IDX_QUINARY_TDM_TX_2, + IDX_QUINARY_TDM_TX_3, + IDX_QUINARY_TDM_TX_4, + IDX_QUINARY_TDM_TX_5, + IDX_QUINARY_TDM_TX_6, + IDX_QUINARY_TDM_TX_7, IDX_TDM_MAX, }; @@ -167,6 +184,8 @@ enum { IDX_GROUP_TERTIARY_TDM_TX, IDX_GROUP_QUATERNARY_TDM_RX, IDX_GROUP_QUATERNARY_TDM_TX, + IDX_GROUP_QUINARY_TDM_RX, + IDX_GROUP_QUINARY_TDM_TX, IDX_GROUP_TDM_MAX, }; @@ -394,6 +413,26 @@ int msm_dai_q6_get_group_idx(u16 id) case AFE_PORT_ID_QUATERNARY_TDM_TX_6: case AFE_PORT_ID_QUATERNARY_TDM_TX_7: return IDX_GROUP_QUATERNARY_TDM_TX; + case AFE_GROUP_DEVICE_ID_QUINARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_RX_1: + case AFE_PORT_ID_QUINARY_TDM_RX_2: + case AFE_PORT_ID_QUINARY_TDM_RX_3: + case AFE_PORT_ID_QUINARY_TDM_RX_4: + case AFE_PORT_ID_QUINARY_TDM_RX_5: + case AFE_PORT_ID_QUINARY_TDM_RX_6: + case AFE_PORT_ID_QUINARY_TDM_RX_7: + return IDX_GROUP_QUINARY_TDM_RX; + case AFE_GROUP_DEVICE_ID_QUINARY_TDM_TX: + case AFE_PORT_ID_QUINARY_TDM_TX: + case AFE_PORT_ID_QUINARY_TDM_TX_1: + case AFE_PORT_ID_QUINARY_TDM_TX_2: + case AFE_PORT_ID_QUINARY_TDM_TX_3: + case AFE_PORT_ID_QUINARY_TDM_TX_4: + case AFE_PORT_ID_QUINARY_TDM_TX_5: + case AFE_PORT_ID_QUINARY_TDM_TX_6: + case AFE_PORT_ID_QUINARY_TDM_TX_7: + return IDX_GROUP_QUINARY_TDM_TX; default: return -EINVAL; } } @@ -529,6 +568,38 @@ int msm_dai_q6_get_port_idx(u16 id) return IDX_QUATERNARY_TDM_RX_7; case AFE_PORT_ID_QUATERNARY_TDM_TX_7: return IDX_QUATERNARY_TDM_TX_7; + case AFE_PORT_ID_QUINARY_TDM_RX: + return IDX_QUINARY_TDM_RX_0; + case AFE_PORT_ID_QUINARY_TDM_TX: + return IDX_QUINARY_TDM_TX_0; + case AFE_PORT_ID_QUINARY_TDM_RX_1: + return IDX_QUINARY_TDM_RX_1; + case AFE_PORT_ID_QUINARY_TDM_TX_1: + return IDX_QUINARY_TDM_TX_1; + case AFE_PORT_ID_QUINARY_TDM_RX_2: + return IDX_QUINARY_TDM_RX_2; + case AFE_PORT_ID_QUINARY_TDM_TX_2: + return IDX_QUINARY_TDM_TX_2; + case AFE_PORT_ID_QUINARY_TDM_RX_3: + return IDX_QUINARY_TDM_RX_3; + case AFE_PORT_ID_QUINARY_TDM_TX_3: + return IDX_QUINARY_TDM_TX_3; + case AFE_PORT_ID_QUINARY_TDM_RX_4: + return IDX_QUINARY_TDM_RX_4; + case AFE_PORT_ID_QUINARY_TDM_TX_4: + return IDX_QUINARY_TDM_TX_4; + case AFE_PORT_ID_QUINARY_TDM_RX_5: + return IDX_QUINARY_TDM_RX_5; + case AFE_PORT_ID_QUINARY_TDM_TX_5: + return IDX_QUINARY_TDM_TX_5; + case AFE_PORT_ID_QUINARY_TDM_RX_6: + return IDX_QUINARY_TDM_RX_6; + case AFE_PORT_ID_QUINARY_TDM_TX_6: + return IDX_QUINARY_TDM_TX_6; + case AFE_PORT_ID_QUINARY_TDM_RX_7: + return IDX_QUINARY_TDM_RX_7; + case AFE_PORT_ID_QUINARY_TDM_TX_7: + return IDX_QUINARY_TDM_TX_7; default: return -EINVAL; } } @@ -908,6 +979,14 @@ static int msm_dai_q6_auxpcm_prepare(struct snd_pcm_substream *substream, aux_dai_data->clk_set.clk_id = Q6AFE_LPASS_CLK_ID_QUAD_PCM_EBIT; break; + case MSM_DAI_QUIN_AUXPCM_DT_DEV_ID: + if (pcm_clk_rate) + aux_dai_data->clk_set.clk_id = + Q6AFE_LPASS_CLK_ID_QUIN_PCM_IBIT; + else + aux_dai_data->clk_set.clk_id = + Q6AFE_LPASS_CLK_ID_QUIN_PCM_EBIT; + break; default: dev_err(dai->dev, "%s: AUXPCM id: %d not supported\n", __func__, dai->id); @@ -1146,6 +1225,32 @@ static struct snd_soc_dai_driver msm_dai_q6_aux_pcm_dai[] = { .probe = msm_dai_q6_aux_pcm_probe, .remove = msm_dai_q6_dai_auxpcm_remove, }, + { + .playback = { + .stream_name = "Quin AUX PCM Playback", + .aif_name = "QUIN_AUX_PCM_RX", + .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_max = 16000, + .rate_min = 8000, + }, + .capture = { + .stream_name = "Quin AUX PCM Capture", + .aif_name = "QUIN_AUX_PCM_TX", + .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_max = 16000, + .rate_min = 8000, + }, + .id = MSM_DAI_QUIN_AUXPCM_DT_DEV_ID, + .ops = &msm_dai_q6_auxpcm_ops, + .probe = msm_dai_q6_aux_pcm_probe, + .remove = msm_dai_q6_dai_auxpcm_remove, + }, }; static int msm_dai_q6_spdif_format_put(struct snd_kcontrol *kcontrol, @@ -3044,6 +3149,11 @@ static int msm_auxpcm_dev_probe(struct platform_device *pdev) dai_data->tx_pid = AFE_PORT_ID_QUATERNARY_PCM_TX; pdev->id = MSM_DAI_QUAT_AUXPCM_DT_DEV_ID; i = 3; + } else if (!strcmp(intf_name, "quinary")) { + dai_data->rx_pid = AFE_PORT_ID_QUINARY_PCM_RX; + dai_data->tx_pid = AFE_PORT_ID_QUINARY_PCM_TX; + pdev->id = MSM_DAI_QUIN_AUXPCM_DT_DEV_ID; + i = 4; } else { dev_err(&pdev->dev, "%s: invalid DT intf name %s\n", __func__, intf_name); @@ -5052,6 +5162,13 @@ static int msm_dai_q6_tdm_set_clk_param(u32 group_id, else clk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUAD_TDM_EBIT; break; + case AFE_GROUP_DEVICE_ID_QUINARY_TDM_RX: + case AFE_GROUP_DEVICE_ID_QUINARY_TDM_TX: + if (mode) + clk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUIN_TDM_IBIT; + else + clk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT; + break; default: return -EINVAL; } @@ -5510,6 +5627,54 @@ static const struct snd_kcontrol_new tdm_config_controls_data_format[] = { SOC_ENUM_EXT("QUAT_TDM_TX_7 Data Format", tdm_config_enum[0], msm_dai_q6_tdm_data_format_get, msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_1 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_2 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_3 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_4 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_5 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_6 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_7 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_1 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_2 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_3 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_4 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_5 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_6 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_7 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), }; static const struct snd_kcontrol_new tdm_config_controls_header_type[] = { @@ -5705,6 +5870,54 @@ static const struct snd_kcontrol_new tdm_config_controls_header_type[] = { SOC_ENUM_EXT("QUAT_TDM_TX_7 Header Type", tdm_config_enum[1], msm_dai_q6_tdm_header_type_get, msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUIN_TDM_RX_1 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUIN_TDM_RX_2 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUIN_TDM_RX_3 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUIN_TDM_RX_4 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUIN_TDM_RX_5 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUIN_TDM_RX_6 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUIN_TDM_RX_7 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUIN_TDM_TX_1 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUIN_TDM_TX_2 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUIN_TDM_TX_3 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUIN_TDM_TX_4 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUIN_TDM_TX_5 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUIN_TDM_TX_6 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("QUIN_TDM_TX_7 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), }; static const struct snd_kcontrol_new tdm_config_controls_header[] = { @@ -5964,6 +6177,70 @@ static const struct snd_kcontrol_new tdm_config_controls_header[] = { SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, msm_dai_q6_tdm_header_get, msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_0 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_1 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_2 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_3 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_4 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_5 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_6 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_7 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_0 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_1 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_2 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_3 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_4 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_5 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_6 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_7 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), }; static int msm_dai_q6_tdm_set_clk( @@ -6187,6 +6464,14 @@ static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai, case AFE_PORT_ID_QUATERNARY_TDM_RX_5: case AFE_PORT_ID_QUATERNARY_TDM_RX_6: case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + case AFE_PORT_ID_QUINARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_RX_1: + case AFE_PORT_ID_QUINARY_TDM_RX_2: + case AFE_PORT_ID_QUINARY_TDM_RX_3: + case AFE_PORT_ID_QUINARY_TDM_RX_4: + case AFE_PORT_ID_QUINARY_TDM_RX_5: + case AFE_PORT_ID_QUINARY_TDM_RX_6: + case AFE_PORT_ID_QUINARY_TDM_RX_7: tdm_group->nslots_per_frame = slots; tdm_group->slot_width = slot_width; tdm_group->slot_mask = rx_mask & cap_mask; @@ -6223,6 +6508,14 @@ static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai, case AFE_PORT_ID_QUATERNARY_TDM_TX_5: case AFE_PORT_ID_QUATERNARY_TDM_TX_6: case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + case AFE_PORT_ID_QUINARY_TDM_TX: + case AFE_PORT_ID_QUINARY_TDM_TX_1: + case AFE_PORT_ID_QUINARY_TDM_TX_2: + case AFE_PORT_ID_QUINARY_TDM_TX_3: + case AFE_PORT_ID_QUINARY_TDM_TX_4: + case AFE_PORT_ID_QUINARY_TDM_TX_5: + case AFE_PORT_ID_QUINARY_TDM_TX_6: + case AFE_PORT_ID_QUINARY_TDM_TX_7: tdm_group->nslots_per_frame = slots; tdm_group->slot_width = slot_width; tdm_group->slot_mask = tx_mask & cap_mask; @@ -6316,6 +6609,14 @@ static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai, case AFE_PORT_ID_QUATERNARY_TDM_RX_5: case AFE_PORT_ID_QUATERNARY_TDM_RX_6: case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + case AFE_PORT_ID_QUINARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_RX_1: + case AFE_PORT_ID_QUINARY_TDM_RX_2: + case AFE_PORT_ID_QUINARY_TDM_RX_3: + case AFE_PORT_ID_QUINARY_TDM_RX_4: + case AFE_PORT_ID_QUINARY_TDM_RX_5: + case AFE_PORT_ID_QUINARY_TDM_RX_6: + case AFE_PORT_ID_QUINARY_TDM_RX_7: if (!rx_slot) { dev_err(dai->dev, "%s: rx slot not found\n", __func__); return -EINVAL; @@ -6366,6 +6667,14 @@ static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai, case AFE_PORT_ID_QUATERNARY_TDM_TX_5: case AFE_PORT_ID_QUATERNARY_TDM_TX_6: case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + case AFE_PORT_ID_QUINARY_TDM_TX: + case AFE_PORT_ID_QUINARY_TDM_TX_1: + case AFE_PORT_ID_QUINARY_TDM_TX_2: + case AFE_PORT_ID_QUINARY_TDM_TX_3: + case AFE_PORT_ID_QUINARY_TDM_TX_4: + case AFE_PORT_ID_QUINARY_TDM_TX_5: + case AFE_PORT_ID_QUINARY_TDM_TX_6: + case AFE_PORT_ID_QUINARY_TDM_TX_7: if (!tx_slot) { dev_err(dai->dev, "%s: tx slot not found\n", __func__); return -EINVAL; @@ -7984,6 +8293,326 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .probe = msm_dai_q6_dai_tdm_probe, .remove = msm_dai_q6_dai_tdm_remove, }, + { + .playback = { + .stream_name = "Quinary TDM0 Playback", + .aif_name = "QUIN_TDM_RX_0", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUINARY_TDM_RX, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Quinary TDM1 Playback", + .aif_name = "QUIN_TDM_RX_1", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUINARY_TDM_RX_1, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Quinary TDM2 Playback", + .aif_name = "QUIN_TDM_RX_2", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUINARY_TDM_RX_2, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Quinary TDM3 Playback", + .aif_name = "QUIN_TDM_RX_3", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUINARY_TDM_RX_3, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Quinary TDM4 Playback", + .aif_name = "QUIN_TDM_RX_4", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUINARY_TDM_RX_4, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Quinary TDM5 Playback", + .aif_name = "QUIN_TDM_RX_5", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUINARY_TDM_RX_5, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Quinary TDM6 Playback", + .aif_name = "QUIN_TDM_RX_6", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUINARY_TDM_RX_6, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Quinary TDM7 Playback", + .aif_name = "QUIN_TDM_RX_7", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUINARY_TDM_RX_7, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Quinary TDM0 Capture", + .aif_name = "QUIN_TDM_TX_0", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUINARY_TDM_TX, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Quinary TDM1 Capture", + .aif_name = "QUIN_TDM_TX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUINARY_TDM_TX_1, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Quinary TDM2 Capture", + .aif_name = "QUIN_TDM_TX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUINARY_TDM_TX_2, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Quinary TDM3 Capture", + .aif_name = "QUIN_TDM_TX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUINARY_TDM_TX_3, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Quinary TDM4 Capture", + .aif_name = "QUIN_TDM_TX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUINARY_TDM_TX_4, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Quinary TDM5 Capture", + .aif_name = "QUIN_TDM_TX_5", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUINARY_TDM_TX_5, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Quinary TDM6 Capture", + .aif_name = "QUIN_TDM_TX_6", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUINARY_TDM_TX_6, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Quinary TDM7 Capture", + .aif_name = "QUIN_TDM_TX_7", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_QUINARY_TDM_TX_7, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, }; static const struct snd_soc_component_driver msm_q6_tdm_dai_component = { diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 788946ad8ea1..2af966454726 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -67,6 +67,7 @@ static int pri_mi2s_switch_enable; static int sec_mi2s_switch_enable; static int tert_mi2s_switch_enable; static int quat_mi2s_switch_enable; +static int quin_mi2s_switch_enable; static int fm_pcmrx_switch_enable; static int usb_switch_enable; static int lsm_port_index; @@ -497,6 +498,38 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_QUAT_TDM_RX_7}, { AFE_PORT_ID_QUATERNARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_QUAT_TDM_TX_7}, + { AFE_PORT_ID_QUINARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_TDM_RX_0}, + { AFE_PORT_ID_QUINARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_TDM_TX_0}, + { AFE_PORT_ID_QUINARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_TDM_RX_1}, + { AFE_PORT_ID_QUINARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_TDM_TX_1}, + { AFE_PORT_ID_QUINARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_TDM_RX_2}, + { AFE_PORT_ID_QUINARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_TDM_TX_2}, + { AFE_PORT_ID_QUINARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_TDM_RX_3}, + { AFE_PORT_ID_QUINARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_TDM_TX_3}, + { AFE_PORT_ID_QUINARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_TDM_RX_4}, + { AFE_PORT_ID_QUINARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_TDM_TX_4}, + { AFE_PORT_ID_QUINARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_TDM_RX_5}, + { AFE_PORT_ID_QUINARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_TDM_TX_5}, + { AFE_PORT_ID_QUINARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_TDM_RX_6}, + { AFE_PORT_ID_QUINARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_TDM_TX_6}, + { AFE_PORT_ID_QUINARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_TDM_RX_7}, + { AFE_PORT_ID_QUINARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_TDM_TX_7}, { INT_BT_A2DP_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_INT_BT_A2DP_RX}, { AFE_PORT_ID_USB_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, @@ -513,6 +546,10 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_QUAT_AUXPCM_RX}, { AFE_PORT_ID_QUATERNARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_QUAT_AUXPCM_TX}, + { AFE_PORT_ID_QUINARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_AUXPCM_RX}, + { AFE_PORT_ID_QUINARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUIN_AUXPCM_TX}, { AFE_PORT_ID_INT0_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_INT0_MI2S_RX}, { AFE_PORT_ID_INT0_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, @@ -2315,6 +2352,36 @@ static int msm_routing_put_quat_mi2s_switch_mixer( return 1; } +static int msm_routing_get_quin_mi2s_switch_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = quin_mi2s_switch_enable; + pr_debug("%s: QUIN MI2S Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_put_quin_mi2s_switch_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: QUIN MI2S Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + if (ucontrol->value.integer.value[0]) + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, + update); + else + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, + update); + quin_mi2s_switch_enable = ucontrol->value.integer.value[0]; + return 1; +} + static int msm_routing_get_fm_pcmrx_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2787,8 +2854,13 @@ static const char *const be_name[] = { "QUAT_TDM_RX_2", "QUAT_TDM_TX_2", "QUAT_TDM_RX_3", "QUAT_TDM_TX_3", "QUAT_TDM_RX_4", "QUAT_TDM_TX_4", "QUAT_TDM_RX_5", "QUAT_TDM_TX_5", "QUAT_TDM_RX_6", "QUAT_TDM_TX_6", "QUAT_TDM_RX_7", "QUAT_TDM_TX_7", +"QUIN_TDM_RX_0", "QUIN_TDM_TX_0", "QUIN_TDM_RX_1", "QUIN_TDM_TX_1", +"QUIN_TDM_RX_2", "QUIN_TDM_TX_2", "QUIN_TDM_RX_3", "QUIN_TDM_TX_3", +"QUIN_TDM_RX_4", "QUIN_TDM_TX_4", "QUIN_TDM_RX_5", "QUIN_TDM_TX_5", +"QUIN_TDM_RX_6", "QUIN_TDM_TX_6", "QUIN_TDM_RX_7", "QUIN_TDM_TX_7", "INT_BT_A2DP_RX", "USB_RX", "USB_TX", "DISPLAY_PORT_RX", "TERT_AUXPCM_RX", "TERT_AUXPCM_TX", "QUAT_AUXPCM_RX", "QUAT_AUXPCM_TX", +"QUIN_AUXPCM_RX", "QUIN_AUXPCM_TX", "INT0_MI2S_RX", "INT0_MI2S_TX", "INT1_MI2S_RX", "INT1_MI2S_TX", "INT2_MI2S_RX", "INT2_MI2S_TX", "INT3_MI2S_RX", "INT3_MI2S_TX", "INT4_MI2S_RX", "INT4_MI2S_TX", "INT5_MI2S_RX", "INT5_MI2S_TX", @@ -5327,6 +5399,56 @@ static const struct snd_kcontrol_new quat_auxpcm_rx_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new quin_auxpcm_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, @@ -6410,6 +6532,273 @@ static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new quin_tdm_rx_0_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_tx_0_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_rx_1_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new mmul1_mixer_controls[] = { SOC_SINGLE_EXT("PRI_TX", MSM_BACKEND_DAI_PRI_I2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, @@ -6450,6 +6839,9 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -6522,6 +6914,18 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -6618,6 +7022,18 @@ static const struct snd_kcontrol_new mmul2_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -6654,6 +7070,9 @@ static const struct snd_kcontrol_new mmul3_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_AUX_PCM_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_AUX_PCM_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -6714,7 +7133,19 @@ static const struct snd_kcontrol_new mmul3_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), -}; + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; static const struct snd_kcontrol_new mmul4_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, @@ -6786,6 +7217,18 @@ static const struct snd_kcontrol_new mmul4_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -6834,6 +7277,9 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_AUX_PCM_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_AUX_PCM_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -6894,6 +7340,18 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -6936,6 +7394,9 @@ static const struct snd_kcontrol_new mmul6_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -6996,6 +7457,18 @@ static const struct snd_kcontrol_new mmul6_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -7089,6 +7562,18 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -7254,6 +7739,18 @@ static const struct snd_kcontrol_new mmul9_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul10_mixer_controls[] = { @@ -7424,6 +7921,9 @@ static const struct snd_kcontrol_new mmul20_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -7472,6 +7972,18 @@ static const struct snd_kcontrol_new mmul20_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { @@ -8113,6 +8625,39 @@ static const struct snd_kcontrol_new quat_aux_pcm_rx_voice_mixer_controls[] = { msm_routing_put_voice_mixer), }; +static const struct snd_kcontrol_new quin_aux_pcm_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, @@ -8300,6 +8845,9 @@ static const struct snd_kcontrol_new tx_voice_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_Voice", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUIN_AUX_PCM_TX_Voice", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), SOC_SINGLE_EXT("PRI_MI2S_TX_Voice", MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8348,6 +8896,9 @@ static const struct snd_kcontrol_new tx_voice2_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUIN_AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), SOC_SINGLE_EXT("PRI_MI2S_TX_Voice2", MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8390,6 +8941,9 @@ static const struct snd_kcontrol_new tx_volte_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_VoLTE", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUIN_AUX_PCM_TX_VoLTE", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), SOC_SINGLE_EXT("MI2S_TX_VoLTE", MSM_BACKEND_DAI_MI2S_TX, MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8435,6 +8989,9 @@ static const struct snd_kcontrol_new tx_vowlan_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_VoWLAN", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUIN_AUX_PCM_TX_VoWLAN", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), SOC_SINGLE_EXT("MI2S_TX_VoWLAN", MSM_BACKEND_DAI_MI2S_TX, MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8483,6 +9040,9 @@ static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_MMode1", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUIN_AUX_PCM_TX_MMode1", + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_SINGLE_EXT("PRI_MI2S_TX_MMode1", MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8534,6 +9094,9 @@ static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_MMode2", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUIN_AUX_PCM_TX_MMode2", + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_SINGLE_EXT("PRI_MI2S_TX_MMode2", MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8582,6 +9145,9 @@ static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_Voip", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUIN_AUX_PCM_TX_Voip", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), SOC_SINGLE_EXT("PRI_MI2S_TX_Voip", MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8642,6 +9208,9 @@ static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("QUIN_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), @@ -8681,6 +9250,9 @@ static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("QUIN_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), @@ -8726,6 +9298,9 @@ static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("QUIN_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), @@ -8774,6 +9349,9 @@ static const struct snd_kcontrol_new tx_qchat_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_QCHAT", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QUIN_AUX_PCM_TX_QCHAT", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), SOC_SINGLE_EXT("MI2S_TX_QCHAT", MSM_BACKEND_DAI_MI2S_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8810,6 +9388,9 @@ static const struct snd_kcontrol_new int0_mi2s_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_BACKEND_DAI_INT3_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), @@ -8840,6 +9421,9 @@ static const struct snd_kcontrol_new int4_mi2s_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_BACKEND_DAI_INT3_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), @@ -8885,6 +9469,9 @@ static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_AUXPCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), @@ -8900,6 +9487,9 @@ static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), @@ -8915,6 +9505,9 @@ static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_MI2S_RX", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_MI2S_RX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new aux_pcm_rx_port_mixer_controls[] = { @@ -8971,6 +9564,18 @@ static const struct snd_kcontrol_new quat_auxpcm_rx_port_mixer_controls[] = { msm_routing_put_port_mixer), }; +static const struct snd_kcontrol_new quin_auxpcm_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("QUIN_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + static const struct snd_kcontrol_new sbus_1_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, @@ -9153,11 +9758,38 @@ static const struct snd_kcontrol_new quat_mi2s_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; +static const struct snd_kcontrol_new quin_mi2s_rx_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + static const struct snd_kcontrol_new pri_tdm_rx_0_port_mixer_controls[] = { SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, @@ -9223,6 +9855,22 @@ static const struct snd_kcontrol_new pri_tdm_rx_0_port_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_1_port_mixer_controls[] = { @@ -9290,6 +9938,22 @@ static const struct snd_kcontrol_new pri_tdm_rx_1_port_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_2_port_mixer_controls[] = { @@ -9357,6 +10021,22 @@ static const struct snd_kcontrol_new pri_tdm_rx_2_port_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_3_port_mixer_controls[] = { @@ -9424,6 +10104,22 @@ static const struct snd_kcontrol_new pri_tdm_rx_3_port_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_0_port_mixer_controls[] = { @@ -9491,6 +10187,22 @@ static const struct snd_kcontrol_new sec_tdm_rx_0_port_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_1_port_mixer_controls[] = { @@ -9558,6 +10270,22 @@ static const struct snd_kcontrol_new sec_tdm_rx_1_port_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_2_port_mixer_controls[] = { @@ -9625,6 +10353,22 @@ static const struct snd_kcontrol_new sec_tdm_rx_2_port_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_3_port_mixer_controls[] = { @@ -9692,6 +10436,22 @@ static const struct snd_kcontrol_new sec_tdm_rx_3_port_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_0_port_mixer_controls[] = { @@ -9759,6 +10519,22 @@ static const struct snd_kcontrol_new tert_tdm_rx_0_port_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_1_port_mixer_controls[] = { @@ -9826,6 +10602,22 @@ static const struct snd_kcontrol_new tert_tdm_rx_1_port_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_2_port_mixer_controls[] = { @@ -9857,377 +10649,805 @@ static const struct snd_kcontrol_new tert_tdm_rx_2_port_mixer_controls[] = { MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_3_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_0_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_1_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_2_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new tert_tdm_rx_3_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, +static const struct snd_kcontrol_new quat_tdm_rx_3_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new quat_tdm_rx_0_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, +static const struct snd_kcontrol_new quin_tdm_rx_0_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new quat_tdm_rx_1_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, +static const struct snd_kcontrol_new quin_tdm_rx_1_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new quat_tdm_rx_2_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, +static const struct snd_kcontrol_new quin_tdm_rx_2_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new quat_tdm_rx_3_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, +static const struct snd_kcontrol_new quin_tdm_rx_3_port_mixer_controls[] = { + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new tert_mi2s_rx_port_mixer_controls[] = { @@ -10243,6 +11463,9 @@ static const struct snd_kcontrol_new tert_mi2s_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), @@ -10264,6 +11487,9 @@ static const struct snd_kcontrol_new sec_mi2s_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), @@ -10551,6 +11777,11 @@ static const struct snd_kcontrol_new quat_mi2s_rx_switch_mixer_controls = 0, 1, 0, msm_routing_get_quat_mi2s_switch_mixer, msm_routing_put_quat_mi2s_switch_mixer); +static const struct snd_kcontrol_new quin_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_quin_mi2s_switch_mixer, + msm_routing_put_quin_mi2s_switch_mixer); + static const struct snd_kcontrol_new hfp_pri_aux_switch_mixer_controls = SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, 0, 1, 0, msm_routing_get_hfp_switch_mixer, @@ -11660,6 +12891,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_IN("QUAT_MI2S_DL_HL", "Quaternary MI2S_RX Hostless Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_MI2S_DL_HL", + "Quinary MI2S_RX Hostless Playback", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("AUXPCM_DL_HL", "AUXPCM_HOSTLESS Playback", 0, 0, 0, 0), @@ -11686,6 +12920,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_UL_HL", "Quaternary MI2S_TX Hostless Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_MI2S_UL_HL", + "Quinary MI2S_TX Hostless Capture", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_0_DL_HL", "Primary TDM0 Hostless Playback", @@ -11879,6 +13116,54 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_7_UL_HL", "Quaternary TDM7 Hostless Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_0_DL_HL", + "Quinary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_0_UL_HL", + "Quinary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_1_DL_HL", + "Quinary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_1_UL_HL", + "Quinary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_2_DL_HL", + "Quinary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_2_UL_HL", + "Quinary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_3_DL_HL", + "Quinary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_3_UL_HL", + "Quinary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_4_DL_HL", + "Quinary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_4_UL_HL", + "Quinary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_5_DL_HL", + "Quinary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_5_UL_HL", + "Quinary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_6_DL_HL", + "Quinary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_6_UL_HL", + "Quinary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_7_DL_HL", + "Quinary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_7_UL_HL", + "Quinary TDM7 Hostless Capture", + 0, 0, 0, 0), /* LSM */ SND_SOC_DAPM_AIF_OUT("LSM1_UL_HL", "Listen 1 Audio Service Capture", @@ -12091,6 +13376,38 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_7", "Quaternary TDM7 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_0", "Quinary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_0", "Quinary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_1", "Quinary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_1", "Quinary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_2", "Quinary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_2", "Quinary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_3", "Quinary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_3", "Quinary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_4", "Quinary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_4", "Quinary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_5", "Quinary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_5", "Quinary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_6", "Quinary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_6", "Quinary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_7", "Quinary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_7", "Quinary TDM7 Capture", + 0, 0, 0, 0), /* incall */ SND_SOC_DAPM_AIF_OUT("VOICE_PLAYBACK_TX", "Voice Farend Playback", 0, 0, 0, 0), @@ -12124,6 +13441,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("QUAT_AUX_PCM_TX", "Quat AUX PCM Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_AUX_PCM_RX", "Quin AUX PCM Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_AUX_PCM_TX", "Quin AUX PCM Capture", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("VOICE_STUB_DL", "VOICE_STUB Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("VOICE_STUB_UL", "VOICE_STUB Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("VOICE2_STUB_DL", "VOICE2_STUB Playback", @@ -12176,6 +13497,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &tert_mi2s_rx_switch_mixer_controls), SND_SOC_DAPM_SWITCH("QUAT_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, &quat_mi2s_rx_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("QUIN_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, + &quin_mi2s_rx_switch_mixer_controls), SND_SOC_DAPM_SWITCH("HFP_PRI_AUX_UL_HL", SND_SOC_NOPM, 0, 0, &hfp_pri_aux_switch_mixer_controls), SND_SOC_DAPM_SWITCH("HFP_AUX_UL_HL", SND_SOC_NOPM, 0, 0, @@ -12295,6 +13618,21 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUAT_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, quat_tdm_rx_3_mixer_controls, ARRAY_SIZE(quat_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_0_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_tx_0_mixer_controls, + ARRAY_SIZE(quin_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_1_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_2_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_3_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_3_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0, mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0, @@ -12333,6 +13671,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUAT_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, quat_auxpcm_rx_mixer_controls, ARRAY_SIZE(quat_auxpcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_auxpcm_rx_mixer_controls, + ARRAY_SIZE(quin_auxpcm_rx_mixer_controls)), /* incall */ SND_SOC_DAPM_MIXER("Incall_Music Audio Mixer", SND_SOC_NOPM, 0, 0, incall_music_delivery_mixer_controls, @@ -12389,6 +13730,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_NOPM, 0, 0, quat_aux_pcm_rx_voice_mixer_controls, ARRAY_SIZE(quat_aux_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + quin_aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(quin_aux_pcm_rx_voice_mixer_controls)), SND_SOC_DAPM_MIXER("HDMI_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, hdmi_rx_voice_mixer_controls, @@ -12494,6 +13839,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUAT_AUXPCM_RX Port Mixer", SND_SOC_NOPM, 0, 0, quat_auxpcm_rx_port_mixer_controls, ARRAY_SIZE(quat_auxpcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_AUXPCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, quin_auxpcm_rx_port_mixer_controls, + ARRAY_SIZE(quin_auxpcm_rx_port_mixer_controls)), SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Port Mixer", SND_SOC_NOPM, 0, 0, sbus_1_rx_port_mixer_controls, ARRAY_SIZE(sbus_1_rx_port_mixer_controls)), @@ -12532,6 +13880,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUAT_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, quat_mi2s_rx_port_mixer_controls, ARRAY_SIZE(quat_mi2s_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, + quin_mi2s_rx_port_mixer_controls, + ARRAY_SIZE(quin_mi2s_rx_port_mixer_controls)), SND_SOC_DAPM_MIXER("PRI_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, pri_tdm_rx_0_port_mixer_controls, ARRAY_SIZE(pri_tdm_rx_0_port_mixer_controls)), @@ -12580,6 +13931,18 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUAT_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0, quat_tdm_rx_3_port_mixer_controls, ARRAY_SIZE(quat_tdm_rx_3_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_0_port_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_0_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_1 Port Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_1_port_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_1_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_2 Port Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_2_port_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_2_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_3_port_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_3_port_mixer_controls)), SND_SOC_DAPM_MIXER("INT0_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, int0_mi2s_rx_port_mixer_controls, ARRAY_SIZE(int0_mi2s_rx_port_mixer_controls)), @@ -13355,42 +14718,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Audio Mixer"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Audio Mixer"}, - - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Audio Mixer"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, @@ -13466,6 +14793,100 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Audio Mixer"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0 Audio Mixer"}, + + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_TDM_TX_0", NULL, "QUIN_TDM_TX_0 Audio Mixer"}, + + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1 Audio Mixer"}, + + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2 Audio Mixer"}, + + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Audio Mixer"}, + {"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"}, {"MultiMedia1 Mixer", "MI2S_TX", "MI2S_TX"}, {"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"}, @@ -13504,6 +14925,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, {"MultiMedia10 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, {"MultiMedia16 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "QUIN_AUX_PCM_TX", "QUIN_AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "QUIN_AUX_PCM_TX", "QUIN_AUX_PCM_TX"}, {"MultiMedia2 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia2 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, {"MultiMedia2 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, @@ -13530,6 +14954,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"MultiMedia6 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia6 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia6 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"MultiMedia1 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia1 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -13547,6 +14972,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia1 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia1 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia1 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia1 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia1 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia1 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"MultiMedia2 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia2 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -13564,6 +14993,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia2 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia2 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia2 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia2 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia2 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia2 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia2 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"MultiMedia3 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia3 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -13581,6 +15014,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia3 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia3 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia3 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia3 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia3 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia3 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia3 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"MultiMedia4 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia4 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -13598,6 +15035,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia4 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia4 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia4 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia4 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia4 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia4 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia4 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"MultiMedia5 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia5 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -13615,6 +15056,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia5 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia5 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia5 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia5 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia5 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia5 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"MultiMedia6 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia6 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -13632,6 +15077,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia6 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia6 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia6 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia6 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia6 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia6 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"MultiMedia8 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia8 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -13649,6 +15098,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia8 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia8 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia8 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia8 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia8 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia8 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"MultiMedia9 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"MultiMedia9 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, @@ -13658,6 +15111,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia9 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia9 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia9 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia9 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia9 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia9 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia9 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"MultiMedia10 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"MultiMedia10 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, @@ -13671,6 +15128,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia20 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"MultiMedia20 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia20 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia20 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"MultiMedia20 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia20 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, {"MultiMedia20 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, @@ -13687,6 +15145,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia20 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia20 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia20 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia20 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia20 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia20 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia20 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, @@ -13906,6 +15368,24 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUX_PCM_RX Audio Mixer"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUX_PCM_RX Audio Mixer"}, + {"MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, {"MI2S_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, {"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, @@ -14063,6 +15543,18 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUX_PCM_RX_Voice Mixer"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUX_PCM_RX_Voice Mixer"}, + {"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, {"HDMI_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, {"HDMI_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, @@ -14161,6 +15653,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VOC_EXT_EC MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"VOC_EXT_EC MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"VOC_EXT_EC MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"VOC_EXT_EC MUX", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"VOC_EXT_EC MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"CS-VOICE_UL1", NULL, "VOC_EXT_EC MUX"}, {"VOIP_UL", NULL, "VOC_EXT_EC MUX"}, @@ -14275,6 +15768,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"Voice_Tx Mixer", "SEC_AUX_PCM_TX_Voice", "SEC_AUX_PCM_TX"}, {"Voice_Tx Mixer", "TERT_AUX_PCM_TX_Voice", "TERT_AUX_PCM_TX"}, {"Voice_Tx Mixer", "QUAT_AUX_PCM_TX_Voice", "QUAT_AUX_PCM_TX"}, + {"Voice_Tx Mixer", "QUIN_AUX_PCM_TX_Voice", "QUIN_AUX_PCM_TX"}, {"Voice_Tx Mixer", "SEC_MI2S_TX_Voice", "SEC_MI2S_TX"}, {"CS-VOICE_UL1", NULL, "Voice_Tx Mixer"}, @@ -14292,6 +15786,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"Voice2_Tx Mixer", "SEC_AUX_PCM_TX_Voice2", "SEC_AUX_PCM_TX"}, {"Voice2_Tx Mixer", "TERT_AUX_PCM_TX_Voice2", "TERT_AUX_PCM_TX"}, {"Voice2_Tx Mixer", "QUAT_AUX_PCM_TX_Voice2", "QUAT_AUX_PCM_TX"}, + {"Voice2_Tx Mixer", "QUIN_AUX_PCM_TX_Voice2", "QUIN_AUX_PCM_TX"}, {"VOICE2_UL", NULL, "Voice2_Tx Mixer"}, {"VoLTE_Tx Mixer", "PRI_TX_VoLTE", "PRI_I2S_TX"}, @@ -14305,6 +15800,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoLTE_Tx Mixer", "SEC_AUX_PCM_TX_VoLTE", "SEC_AUX_PCM_TX"}, {"VoLTE_Tx Mixer", "TERT_AUX_PCM_TX_VoLTE", "TERT_AUX_PCM_TX"}, {"VoLTE_Tx Mixer", "QUAT_AUX_PCM_TX_VoLTE", "QUAT_AUX_PCM_TX"}, + {"VoLTE_Tx Mixer", "QUIN_AUX_PCM_TX_VoLTE", "QUIN_AUX_PCM_TX"}, {"VoLTE_Tx Mixer", "MI2S_TX_VoLTE", "MI2S_TX"}, {"VoLTE_Tx Mixer", "PRI_MI2S_TX_VoLTE", "PRI_MI2S_TX"}, {"VoLTE_Tx Mixer", "TERT_MI2S_TX_VoLTE", "TERT_MI2S_TX"}, @@ -14321,6 +15817,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoWLAN_Tx Mixer", "SEC_AUX_PCM_TX_VoWLAN", "SEC_AUX_PCM_TX"}, {"VoWLAN_Tx Mixer", "TERT_AUX_PCM_TX_VoWLAN", "TERT_AUX_PCM_TX"}, {"VoWLAN_Tx Mixer", "QUAT_AUX_PCM_TX_VoWLAN", "QUAT_AUX_PCM_TX"}, + {"VoWLAN_Tx Mixer", "QUIN_AUX_PCM_TX_VoWLAN", "QUIN_AUX_PCM_TX"}, {"VoWLAN_Tx Mixer", "MI2S_TX_VoWLAN", "MI2S_TX"}, {"VoWLAN_Tx Mixer", "PRI_MI2S_TX_VoWLAN", "PRI_MI2S_TX"}, {"VoWLAN_Tx Mixer", "TERT_MI2S_TX_VoWLAN", "TERT_MI2S_TX"}, @@ -14341,6 +15838,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode1_Tx Mixer", "SEC_AUX_PCM_TX_MMode1", "SEC_AUX_PCM_TX"}, {"VoiceMMode1_Tx Mixer", "TERT_AUX_PCM_TX_MMode1", "TERT_AUX_PCM_TX"}, {"VoiceMMode1_Tx Mixer", "QUAT_AUX_PCM_TX_MMode1", "QUAT_AUX_PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "QUIN_AUX_PCM_TX_MMode1", "QUIN_AUX_PCM_TX"}, {"VoiceMMode1_Tx Mixer", "QUAT_TDM_TX_0_MMode1", "QUAT_TDM_TX_0"}, {"VOICEMMODE1_UL", NULL, "VoiceMMode1_Tx Mixer"}, @@ -14359,6 +15857,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode2_Tx Mixer", "SEC_AUX_PCM_TX_MMode2", "SEC_AUX_PCM_TX"}, {"VoiceMMode2_Tx Mixer", "TERT_AUX_PCM_TX_MMode2", "TERT_AUX_PCM_TX"}, {"VoiceMMode2_Tx Mixer", "QUAT_AUX_PCM_TX_MMode2", "QUAT_AUX_PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "QUIN_AUX_PCM_TX_MMode2", "QUIN_AUX_PCM_TX"}, {"VOICEMMODE2_UL", NULL, "VoiceMMode2_Tx Mixer"}, {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"}, @@ -14375,6 +15874,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"Voip_Tx Mixer", "SEC_AUX_PCM_TX_Voip", "SEC_AUX_PCM_TX"}, {"Voip_Tx Mixer", "TERT_AUX_PCM_TX_Voip", "TERT_AUX_PCM_TX"}, {"Voip_Tx Mixer", "QUAT_AUX_PCM_TX_Voip", "QUAT_AUX_PCM_TX"}, + {"Voip_Tx Mixer", "QUIN_AUX_PCM_TX_Voip", "QUIN_AUX_PCM_TX"}, {"Voip_Tx Mixer", "PRI_MI2S_TX_Voip", "PRI_MI2S_TX"}, {"VOIP_UL", NULL, "Voip_Tx Mixer"}, @@ -14482,6 +15982,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QCHAT_Tx Mixer", "SEC_AUX_PCM_TX_QCHAT", "SEC_AUX_PCM_TX"}, {"QCHAT_Tx Mixer", "TERT_AUX_PCM_TX_QCHAT", "TERT_AUX_PCM_TX"}, {"QCHAT_Tx Mixer", "QUAT_AUX_PCM_TX_QCHAT", "QUAT_AUX_PCM_TX"}, + {"QCHAT_Tx Mixer", "QUIN_AUX_PCM_TX_QCHAT", "QUIN_AUX_PCM_TX"}, {"QCHAT_Tx Mixer", "MI2S_TX_QCHAT", "MI2S_TX"}, {"QCHAT_Tx Mixer", "PRI_MI2S_TX_QCHAT", "PRI_MI2S_TX"}, {"QCHAT_Tx Mixer", "TERT_MI2S_TX_QCHAT", "TERT_MI2S_TX"}, @@ -14521,6 +16022,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_MI2S_RX_DL_HL", "Switch", "QUAT_MI2S_DL_HL"}, {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_DL_HL"}, + {"QUIN_MI2S_RX_DL_HL", "Switch", "QUIN_MI2S_DL_HL"}, + {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_DL_HL"}, {"MI2S_UL_HL", NULL, "TERT_MI2S_TX"}, {"INT3_MI2S_UL_HL", NULL, "INT3_MI2S_TX"}, {"TERT_MI2S_UL_HL", NULL, "TERT_MI2S_TX"}, @@ -14564,6 +16067,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1_DL_HL"}, {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_DL_HL"}, {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3_DL_HL"}, + {"QUIN_TDM_TX_0_UL_HL", NULL, "QUIN_TDM_TX_0"}, + {"QUIN_TDM_TX_1_UL_HL", NULL, "QUIN_TDM_TX_1"}, + {"QUIN_TDM_TX_2_UL_HL", NULL, "QUIN_TDM_TX_2"}, + {"QUIN_TDM_TX_3_UL_HL", NULL, "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0_DL_HL"}, + {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1_DL_HL"}, + {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2_DL_HL"}, + {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3_DL_HL"}, {"PRI_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"PRI_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, @@ -14581,6 +16092,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Port Mixer"}, {"PRI_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -14599,6 +16114,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Port Mixer"}, {"PRI_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -14617,6 +16136,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Port Mixer"}, {"PRI_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -14635,6 +16158,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Port Mixer"}, {"SEC_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -14653,6 +16180,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Port Mixer"}, {"SEC_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -14671,6 +16202,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Port Mixer"}, {"SEC_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -14689,6 +16224,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Port Mixer"}, {"SEC_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -14707,6 +16246,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Port Mixer"}, {"TERT_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -14725,6 +16268,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Port Mixer"}, {"TERT_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -14743,6 +16290,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Port Mixer"}, {"TERT_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -14761,6 +16312,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Port Mixer"}, {"TERT_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -14779,6 +16334,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Port Mixer"}, {"QUAT_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -14797,6 +16356,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Port Mixer"}, {"QUAT_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -14815,6 +16378,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Port Mixer"}, {"QUAT_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -14833,6 +16400,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Port Mixer"}, {"QUAT_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -14851,12 +16422,105 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Port Mixer"}, + {"QUIN_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Port Mixer"}, + + {"QUIN_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Port Mixer"}, + + {"QUIN_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Port Mixer"}, + + {"QUIN_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Port Mixer"}, + {"INT0_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"INT0_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"INT0_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"INT0_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"INT0_MI2S_RX Port Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"INT0_MI2S_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"INT0_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, @@ -14868,6 +16532,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"INT4_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"INT4_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"INT4_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"INT4_MI2S_RX Port Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"INT4_MI2S_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"INT4_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, @@ -14884,11 +16549,13 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_0_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, {"SLIMBUS_0_RX Port Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, {"SLIMBUS_0_RX Port Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, {"SLIMBUS_0_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"SLIMBUS_0_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"}, {"AFE_PCM_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, @@ -14923,6 +16590,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUXPCM_RX Port Mixer"}, + {"QUIN_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUIN_AUXPCM_RX Port Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, + {"QUIN_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUXPCM_RX Port Mixer"}, + {"Voice Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, {"Voice Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"Voice Stub Tx Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, @@ -14931,6 +16603,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"Voice Stub Tx Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, {"Voice Stub Tx Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, {"Voice Stub Tx Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, {"Voice Stub Tx Mixer", "MI2S_TX", "MI2S_TX"}, {"Voice Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"Voice Stub Tx Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, @@ -15058,6 +16731,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"PRI_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"PRI_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"PRI_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"PRI_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"PRI_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"PRI_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, @@ -15068,6 +16742,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"SEC_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"SEC_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"SEC_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"SEC_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"SEC_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"SEC_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, @@ -15077,6 +16752,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"TERT_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"TERT_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"TERT_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"TERT_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"TERT_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX Port Mixer"}, @@ -15085,12 +16761,22 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"QUAT_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"QUAT_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"QUAT_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"QUAT_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"QUAT_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"QUAT_MI2S_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"QUAT_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX Port Mixer"}, + {"QUIN_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUIN_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUIN_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"QUIN_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"QUIN_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"QUIN_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"QUIN_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX Port Mixer"}, + /* Backend Enablement */ {"BE_OUT", NULL, "PRI_I2S_RX"}, @@ -15126,6 +16812,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "SEC_AUX_PCM_RX"}, {"BE_OUT", NULL, "TERT_AUX_PCM_RX"}, {"BE_OUT", NULL, "QUAT_AUX_PCM_RX"}, + {"BE_OUT", NULL, "QUIN_AUX_PCM_RX"}, {"BE_OUT", NULL, "INT_BT_SCO_RX"}, {"BE_OUT", NULL, "INT_FM_RX"}, {"BE_OUT", NULL, "PCM_RX"}, @@ -15149,6 +16836,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "QUAT_TDM_RX_1"}, {"BE_OUT", NULL, "QUAT_TDM_RX_2"}, {"BE_OUT", NULL, "QUAT_TDM_RX_3"}, + {"BE_OUT", NULL, "QUIN_TDM_RX_0"}, + {"BE_OUT", NULL, "QUIN_TDM_RX_1"}, + {"BE_OUT", NULL, "QUIN_TDM_RX_2"}, + {"BE_OUT", NULL, "QUIN_TDM_RX_3"}, {"PRI_I2S_TX", NULL, "BE_IN"}, {"MI2S_TX", NULL, "BE_IN"}, @@ -15182,6 +16873,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_AUX_PCM_TX", NULL, "BE_IN"}, {"TERT_AUX_PCM_TX", NULL, "BE_IN"}, {"QUAT_AUX_PCM_TX", NULL, "BE_IN"}, + {"QUIN_AUX_PCM_TX", NULL, "BE_IN"}, {"INCALL_RECORD_TX", NULL, "BE_IN"}, {"INCALL_RECORD_RX", NULL, "BE_IN"}, {"SLIM0_RX_VI_FB_LCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"}, @@ -15210,6 +16902,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_TX_1", NULL, "BE_IN"}, {"QUAT_TDM_TX_2", NULL, "BE_IN"}, {"QUAT_TDM_TX_3", NULL, "BE_IN"}, + {"QUIN_TDM_TX_0", NULL, "BE_IN"}, + {"QUIN_TDM_TX_1", NULL, "BE_IN"}, + {"QUIN_TDM_TX_2", NULL, "BE_IN"}, + {"QUIN_TDM_TX_3", NULL, "BE_IN"}, }; static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 4e823d3eba3c..479ba35309b9 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -40,6 +40,8 @@ #define LPASS_BE_TERT_AUXPCM_TX "TERT_AUX_PCM_TX" #define LPASS_BE_QUAT_AUXPCM_RX "QUAT_AUX_PCM_RX" #define LPASS_BE_QUAT_AUXPCM_TX "QUAT_AUX_PCM_TX" +#define LPASS_BE_QUIN_AUXPCM_RX "QUIN_AUX_PCM_RX" +#define LPASS_BE_QUIN_AUXPCM_TX "QUIN_AUX_PCM_TX" #define LPASS_BE_VOICE_PLAYBACK_TX "VOICE_PLAYBACK_TX" #define LPASS_BE_VOICE2_PLAYBACK_TX "VOICE2_PLAYBACK_TX" #define LPASS_BE_INCALL_RECORD_RX "INCALL_RECORD_RX" @@ -143,6 +145,22 @@ #define LPASS_BE_QUAT_TDM_TX_6 "QUAT_TDM_TX_6" #define LPASS_BE_QUAT_TDM_RX_7 "QUAT_TDM_RX_7" #define LPASS_BE_QUAT_TDM_TX_7 "QUAT_TDM_TX_7" +#define LPASS_BE_QUIN_TDM_RX_0 "QUIN_TDM_RX_0" +#define LPASS_BE_QUIN_TDM_TX_0 "QUIN_TDM_TX_0" +#define LPASS_BE_QUIN_TDM_RX_1 "QUIN_TDM_RX_1" +#define LPASS_BE_QUIN_TDM_TX_1 "QUIN_TDM_TX_1" +#define LPASS_BE_QUIN_TDM_RX_2 "QUIN_TDM_RX_2" +#define LPASS_BE_QUIN_TDM_TX_2 "QUIN_TDM_TX_2" +#define LPASS_BE_QUIN_TDM_RX_3 "QUIN_TDM_RX_3" +#define LPASS_BE_QUIN_TDM_TX_3 "QUIN_TDM_TX_3" +#define LPASS_BE_QUIN_TDM_RX_4 "QUIN_TDM_RX_4" +#define LPASS_BE_QUIN_TDM_TX_4 "QUIN_TDM_TX_4" +#define LPASS_BE_QUIN_TDM_RX_5 "QUIN_TDM_RX_5" +#define LPASS_BE_QUIN_TDM_TX_5 "QUIN_TDM_TX_5" +#define LPASS_BE_QUIN_TDM_RX_6 "QUIN_TDM_RX_6" +#define LPASS_BE_QUIN_TDM_TX_6 "QUIN_TDM_TX_6" +#define LPASS_BE_QUIN_TDM_RX_7 "QUIN_TDM_RX_7" +#define LPASS_BE_QUIN_TDM_TX_7 "QUIN_TDM_TX_7" #define LPASS_BE_SLIMBUS_7_RX "SLIMBUS_7_RX" #define LPASS_BE_SLIMBUS_7_TX "SLIMBUS_7_TX" @@ -341,6 +359,22 @@ enum { MSM_BACKEND_DAI_QUAT_TDM_TX_6, MSM_BACKEND_DAI_QUAT_TDM_RX_7, MSM_BACKEND_DAI_QUAT_TDM_TX_7, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_4, + MSM_BACKEND_DAI_QUIN_TDM_TX_4, + MSM_BACKEND_DAI_QUIN_TDM_RX_5, + MSM_BACKEND_DAI_QUIN_TDM_TX_5, + MSM_BACKEND_DAI_QUIN_TDM_RX_6, + MSM_BACKEND_DAI_QUIN_TDM_TX_6, + MSM_BACKEND_DAI_QUIN_TDM_RX_7, + MSM_BACKEND_DAI_QUIN_TDM_TX_7, MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_BACKEND_DAI_USB_RX, MSM_BACKEND_DAI_USB_TX, @@ -349,6 +383,8 @@ enum { MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_BACKEND_DAI_INT0_MI2S_TX, MSM_BACKEND_DAI_INT1_MI2S_RX, diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index e755e4d86f77..df635ccad1cd 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1051,7 +1051,7 @@ struct adm_cmd_connect_afe_port_v5 { /* End of the range of port IDs for TDM devices. */ #define AFE_PORT_ID_TDM_PORT_RANGE_END \ - (AFE_PORT_ID_TDM_PORT_RANGE_START+0x40-1) + (AFE_PORT_ID_TDM_PORT_RANGE_START+0x50-1) /* Size of the range of port IDs for TDM ports. */ #define AFE_PORT_ID_TDM_PORT_RANGE_SIZE \ @@ -1084,6 +1084,7 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_PORT_ID_SENARY_MI2S_RX 0x1018 /* ID of the senary MI2S Tx port. */ #define AFE_PORT_ID_SENARY_MI2S_TX 0x1019 + /* ID of the Internal 0 MI2S Rx port */ #define AFE_PORT_ID_INT0_MI2S_RX 0x102E /* ID of the Internal 0 MI2S Tx port */ @@ -1112,6 +1113,10 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_PORT_ID_INT6_MI2S_RX 0x103A /* ID of the Internal 6 MI2S Tx port */ #define AFE_PORT_ID_INT6_MI2S_TX 0x103B + +#define AFE_PORT_ID_QUINARY_PCM_RX 0x103C +#define AFE_PORT_ID_QUINARY_PCM_TX 0x103D + #define AFE_PORT_ID_SPDIF_RX 0x5000 #define AFE_PORT_ID_RT_PROXY_PORT_001_RX 0x2000 #define AFE_PORT_ID_RT_PROXY_PORT_001_TX 0x2001 @@ -1328,6 +1333,40 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_PORT_ID_QUATERNARY_TDM_TX_7 \ (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0E) +#define AFE_PORT_ID_QUINARY_TDM_RX \ + (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x40) +#define AFE_PORT_ID_QUINARY_TDM_RX_1 \ + (AFE_PORT_ID_QUINARY_TDM_RX + 0x02) +#define AFE_PORT_ID_QUINARY_TDM_RX_2 \ + (AFE_PORT_ID_QUINARY_TDM_RX + 0x04) +#define AFE_PORT_ID_QUINARY_TDM_RX_3 \ + (AFE_PORT_ID_QUINARY_TDM_RX + 0x06) +#define AFE_PORT_ID_QUINARY_TDM_RX_4 \ + (AFE_PORT_ID_QUINARY_TDM_RX + 0x08) +#define AFE_PORT_ID_QUINARY_TDM_RX_5 \ + (AFE_PORT_ID_QUINARY_TDM_RX + 0x0A) +#define AFE_PORT_ID_QUINARY_TDM_RX_6 \ + (AFE_PORT_ID_QUINARY_TDM_RX + 0x0C) +#define AFE_PORT_ID_QUINARY_TDM_RX_7 \ + (AFE_PORT_ID_QUINARY_TDM_RX + 0x0E) + +#define AFE_PORT_ID_QUINARY_TDM_TX \ + (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x41) +#define AFE_PORT_ID_QUINARY_TDM_TX_1 \ + (AFE_PORT_ID_QUINARY_TDM_TX + 0x02) +#define AFE_PORT_ID_QUINARY_TDM_TX_2 \ + (AFE_PORT_ID_QUINARY_TDM_TX + 0x04) +#define AFE_PORT_ID_QUINARY_TDM_TX_3 \ + (AFE_PORT_ID_QUINARY_TDM_TX + 0x06) +#define AFE_PORT_ID_QUINARY_TDM_TX_4 \ + (AFE_PORT_ID_QUINARY_TDM_TX + 0x08) +#define AFE_PORT_ID_QUINARY_TDM_TX_5 \ + (AFE_PORT_ID_QUINARY_TDM_TX + 0x0A) +#define AFE_PORT_ID_QUINARY_TDM_TX_6 \ + (AFE_PORT_ID_QUINARY_TDM_TX + 0x0C) +#define AFE_PORT_ID_QUINARY_TDM_TX_7 \ + (AFE_PORT_ID_QUINARY_TDM_TX + 0x0E) + #define AFE_PORT_ID_INVALID 0xFFFF #define AAC_ENC_MODE_AAC_LC 0x02 @@ -9595,6 +9634,9 @@ enum afe_lpass_clk_mode { /* Clock ID for INT6 I2S IBIT */ #define Q6AFE_LPASS_CLK_ID_INT6_MI2S_IBIT 0x115 +/* Clock ID for QUINARY MI2S OSR CLK */ +#define Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR 0x116 + /* Clock ID for Primary PCM IBIT */ #define Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT 0x200 /* Clock ID for Primary PCM EBIT */ @@ -9611,6 +9653,12 @@ enum afe_lpass_clk_mode { #define Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT 0x206 /* Clock ID for Quartery PCM EBIT */ #define Q6AFE_LPASS_CLK_ID_QUAD_PCM_EBIT 0x207 +/* Clock ID for Quinary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUIN_PCM_IBIT 0x208 +/* Clock ID for Quinary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUIN_PCM_EBIT 0x209 +/* Clock ID for QUINARY PCM OSR */ +#define Q6AFE_LPASS_CLK_ID_QUI_PCM_OSR 0x20A /** Clock ID for Primary TDM IBIT */ #define Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT 0x200 @@ -9628,6 +9676,12 @@ enum afe_lpass_clk_mode { #define Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT 0x206 /** Clock ID for Quartery TDM EBIT */ #define Q6AFE_LPASS_CLK_ID_QUAD_TDM_EBIT 0x207 +/** Clock ID for Quinary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_QUIN_TDM_IBIT 0x208 +/** Clock ID for Quinary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT 0x209 +/** Clock ID for Quinary TDM OSR */ +#define Q6AFE_LPASS_CLK_ID_QUIN_TDM_OSR 0x20A /* Clock ID for MCLK1 */ #define Q6AFE_LPASS_CLK_ID_MCLK_1 0x300 @@ -10089,6 +10143,10 @@ struct afe_group_device_group_cfg { (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x100) #define AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_TX \ (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x100) +#define AFE_GROUP_DEVICE_ID_QUINARY_TDM_RX \ + (AFE_PORT_ID_QUINARY_TDM_RX + 0x100) +#define AFE_GROUP_DEVICE_ID_QUINARY_TDM_TX \ + (AFE_PORT_ID_QUINARY_TDM_TX + 0x100) /* ID of the parameter used by #AFE_MODULE_GROUP_DEVICE to configure the * group device. #AFE_SVC_CMD_SET_PARAM can use this parameter ID. -- GitLab From d17544899a099da44098f565f284dfe8fdcd2468 Mon Sep 17 00:00:00 2001 From: Rohit Kumar Date: Sun, 10 Sep 2017 22:57:39 +0530 Subject: [PATCH 0045/1645] asoc: sdm660: add support for quinary interfaces Add support for Quinary MI2S, AuxPCM and TDM interfaces in sdm660 machine driver. Change-Id: I2dad713a3286499e9b76206b28a82b56638949a4 Signed-off-by: Rohit Kumar --- asoc/sdm660-common.c | 143 +++++++++++++++++++++++++++++++++++- asoc/sdm660-common.h | 1 + asoc/sdm660-ext-dai-links.c | 90 +++++++++++++++++++++++ asoc/sdm660-internal.c | 90 +++++++++++++++++++++++ 4 files changed, 322 insertions(+), 2 deletions(-) diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c index 8006472ff338..78218ab056a3 100644 --- a/asoc/sdm660-common.c +++ b/asoc/sdm660-common.c @@ -87,6 +87,16 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUIN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ } }; @@ -131,6 +141,16 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUIN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ } }; @@ -155,6 +175,7 @@ enum { SEC_MI2S, TERT_MI2S, QUAT_MI2S, + QUIN_MI2S, MI2S_MAX, }; @@ -163,6 +184,7 @@ enum { SEC_AUX_PCM, TERT_AUX_PCM, QUAT_AUX_PCM, + QUIN_AUX_PCM, AUX_PCM_MAX, }; @@ -171,6 +193,7 @@ enum { PCM_I2S_SEL_SEC, PCM_I2S_SEL_TERT, PCM_I2S_SEL_QUAT, + PCM_I2S_SEL_QUIN, PCM_I2S_SEL_MAX, }; @@ -231,6 +254,7 @@ static struct dev_config mi2s_rx_cfg[] = { [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, }; static struct dev_config mi2s_tx_cfg[] = { @@ -238,6 +262,7 @@ static struct dev_config mi2s_tx_cfg[] = { [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; static struct dev_config aux_pcm_rx_cfg[] = { @@ -245,6 +270,7 @@ static struct dev_config aux_pcm_rx_cfg[] = { [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; static struct dev_config aux_pcm_tx_cfg[] = { @@ -252,6 +278,7 @@ static struct dev_config aux_pcm_tx_cfg[] = { [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; static char const *ch_text[] = {"Two", "Three", "Four", "Five", @@ -290,26 +317,32 @@ static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_format, mi2s_format_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_format, mi2s_format_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_format, mi2s_format_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_format, mi2s_format_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_format, mi2s_format_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_format, mi2s_format_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_format, mi2s_format_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_format, mi2s_format_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); @@ -318,6 +351,8 @@ static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); @@ -520,6 +555,9 @@ static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, } else if (strnstr(kcontrol->id.name, "QUAT", sizeof(kcontrol->id.name))) { port->mode = TDM_QUAT; + } else if (strnstr(kcontrol->id.name, "QUIN", + sizeof(kcontrol->id.name))) { + port->mode = TDM_QUIN; } else { pr_err("%s: unsupported mode in: %s", __func__, kcontrol->id.name); @@ -955,6 +993,9 @@ static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", sizeof("QUAT_AUX_PCM"))) idx = QUAT_AUX_PCM; + else if (strnstr(kcontrol->id.name, "QUIN_AUX_PCM", + sizeof("QUIN_AUX_PCM"))) + idx = QUIN_AUX_PCM; else { pr_err("%s: unsupported port: %s", __func__, kcontrol->id.name); @@ -1052,6 +1093,9 @@ static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", sizeof("QUAT_MI2S_RX"))) idx = QUAT_MI2S; + else if (strnstr(kcontrol->id.name, "QUIN_MI2S_RX", + sizeof("QUIN_MI2S_RX"))) + idx = QUIN_MI2S; else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", sizeof("PRIM_MI2S_TX"))) idx = PRIM_MI2S; @@ -1064,6 +1108,9 @@ static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", sizeof("QUAT_MI2S_TX"))) idx = QUAT_MI2S; + else if (strnstr(kcontrol->id.name, "QUIN_MI2S_TX", + sizeof("QUIN_MI2S_TX"))) + idx = QUIN_MI2S; else { pr_err("%s: unsupported channel: %s", __func__, kcontrol->id.name); @@ -1836,6 +1883,9 @@ const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate, aux_pcm_rx_sample_rate_get, aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_RX SampleRate", quin_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, aux_pcm_tx_sample_rate_get, aux_pcm_tx_sample_rate_put), @@ -1848,6 +1898,9 @@ const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, aux_pcm_tx_sample_rate_get, aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_TX SampleRate", quin_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, mi2s_rx_sample_rate_get, mi2s_rx_sample_rate_put), @@ -1860,6 +1913,9 @@ const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, mi2s_rx_sample_rate_get, mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_MI2S_RX SampleRate", quin_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, mi2s_tx_sample_rate_get, mi2s_tx_sample_rate_put), @@ -1872,6 +1928,9 @@ const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, mi2s_tx_sample_rate_get, mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_MI2S_TX SampleRate", quin_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), SOC_ENUM_EXT("PRIM_MI2S_RX Format", prim_mi2s_rx_format, mi2s_rx_format_get, mi2s_rx_format_put), @@ -1884,6 +1943,9 @@ const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("QUAT_MI2S_RX Format", quat_mi2s_rx_format, mi2s_rx_format_get, mi2s_rx_format_put), + SOC_ENUM_EXT("QUIN_MI2S_RX Format", quin_mi2s_rx_format, + mi2s_rx_format_get, + mi2s_rx_format_put), SOC_ENUM_EXT("PRIM_MI2S_TX Format", prim_mi2s_tx_format, mi2s_tx_format_get, mi2s_tx_format_put), @@ -1896,6 +1958,9 @@ const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("QUAT_MI2S_TX Format", quat_mi2s_tx_format, mi2s_tx_format_get, mi2s_tx_format_put), + SOC_ENUM_EXT("QUIN_MI2S_TX Format", quin_mi2s_tx_format, + mi2s_tx_format_get, + mi2s_tx_format_put), SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, @@ -1912,6 +1977,10 @@ const struct snd_kcontrol_new msm_common_snd_controls[] = { msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUIN_MI2S_RX Channels", quin_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUIN_MI2S_TX Channels", quin_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, usb_audio_rx_ch_get, usb_audio_rx_ch_put), SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, @@ -2005,6 +2074,24 @@ const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, tdm_tx_ch_get, tdm_tx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), }; /** @@ -2187,6 +2274,22 @@ int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; break; + case MSM_BACKEND_DAI_QUIN_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUIN_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + case MSM_BACKEND_DAI_AUXPCM_RX: rate->min = rate->max = aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; @@ -2243,6 +2346,20 @@ int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, aux_pcm_tx_cfg[QUAT_AUX_PCM].channels; break; + case MSM_BACKEND_DAI_QUIN_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[QUIN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUIN_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUIN_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[QUIN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUIN_AUX_PCM].channels; + break; + case MSM_BACKEND_DAI_PRI_MI2S_RX: rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate; channels->min = channels->max = @@ -2307,6 +2424,22 @@ int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, mi2s_tx_cfg[QUAT_MI2S].bit_format); break; + case MSM_BACKEND_DAI_QUINARY_MI2S_RX: + rate->min = rate->max = mi2s_rx_cfg[QUIN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUIN_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUIN_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + rate->min = rate->max = mi2s_tx_cfg[QUIN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUIN_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUIN_MI2S].bit_format); + break; + default: rate->min = rate->max = SAMPLING_RATE_48KHZ; break; @@ -2381,6 +2514,12 @@ static int msm_get_port_id(int id) case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; break; + case MSM_BACKEND_DAI_QUINARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUINARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUINARY_MI2S_TX; + break; default: pr_err("%s: Invalid id: %d\n", __func__, id); afe_port_id = -EINVAL; @@ -2481,7 +2620,7 @@ int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) __func__, substream->name, substream->stream, cpu_dai->name, cpu_dai->id); - if (index < PRIM_MI2S || index > QUAT_MI2S) { + if (index < PRIM_MI2S || index >= MI2S_MAX) { ret = -EINVAL; dev_err(rtd->card->dev, "%s: CPU DAI id (%d) out of range\n", @@ -2555,7 +2694,7 @@ void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); - if (index < PRIM_MI2S || index > QUAT_MI2S) { + if (index < PRIM_MI2S || index >= MI2S_MAX) { pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); return; } diff --git a/asoc/sdm660-common.h b/asoc/sdm660-common.h index c7de18f7f4db..3276d1fa2c58 100644 --- a/asoc/sdm660-common.h +++ b/asoc/sdm660-common.h @@ -51,6 +51,7 @@ enum { TDM_SEC, TDM_TERT, TDM_QUAT, + TDM_QUIN, TDM_INTERFACE_MAX, }; diff --git a/asoc/sdm660-ext-dai-links.c b/asoc/sdm660-ext-dai-links.c index a76c16d76d00..4777a5ff3ee1 100644 --- a/asoc/sdm660-ext-dai-links.c +++ b/asoc/sdm660-ext-dai-links.c @@ -205,10 +205,12 @@ static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream, case AFE_PORT_ID_SECONDARY_TDM_RX: case AFE_PORT_ID_TERTIARY_TDM_RX: case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_RX: case AFE_PORT_ID_PRIMARY_TDM_TX: case AFE_PORT_ID_SECONDARY_TDM_TX: case AFE_PORT_ID_TERTIARY_TDM_TX: case AFE_PORT_ID_QUATERNARY_TDM_TX: + case AFE_PORT_ID_QUINARY_TDM_TX: slot_offset = tdm_slot_offset[TDM_0]; break; default: @@ -1568,6 +1570,34 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .ops = &msm_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUIN_TDM_RX_0, + .stream_name = "Quinary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.37184", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_TDM_TX_0, + .stream_name = "Quinary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.37185", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { @@ -1687,6 +1717,35 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUIN_MI2S_RX, + .stream_name = "Quinary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_TX, + .stream_name = "Quinary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { @@ -1814,6 +1873,37 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .ignore_pmdown_time = 1, .ops = &msm_aux_pcm_be_ops, }, + /* Quinary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUIN_AUXPCM_RX, + .stream_name = "Quin AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_QUIN_AUXPCM_TX, + .stream_name = "Quin AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .ops = &msm_aux_pcm_be_ops, + }, }; static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { diff --git a/asoc/sdm660-internal.c b/asoc/sdm660-internal.c index b5b05b10c9a5..713da55cb0a9 100644 --- a/asoc/sdm660-internal.c +++ b/asoc/sdm660-internal.c @@ -1499,10 +1499,12 @@ static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream, case AFE_PORT_ID_SECONDARY_TDM_RX: case AFE_PORT_ID_TERTIARY_TDM_RX: case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_RX: case AFE_PORT_ID_PRIMARY_TDM_TX: case AFE_PORT_ID_SECONDARY_TDM_TX: case AFE_PORT_ID_TERTIARY_TDM_TX: case AFE_PORT_ID_QUATERNARY_TDM_TX: + case AFE_PORT_ID_QUINARY_TDM_TX: slot_offset = tdm_slot_offset[TDM_0]; break; default: @@ -2607,6 +2609,34 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .ops = &msm_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUIN_TDM_RX_0, + .stream_name = "Quinary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.37184", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_TDM_TX_0, + .stream_name = "Quinary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.37185", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { @@ -2726,6 +2756,35 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUIN_MI2S_RX, + .stream_name = "Quinary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_TX, + .stream_name = "Quinary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { @@ -2853,6 +2912,37 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .ignore_pmdown_time = 1, .ops = &msm_aux_pcm_be_ops, }, + /* Quinary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUIN_AUXPCM_RX, + .stream_name = "Quin AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_QUIN_AUXPCM_TX, + .stream_name = "Quin AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .ops = &msm_aux_pcm_be_ops, + }, }; -- GitLab From b3154657732a3b73b04c5b7d63ff7952c7425281 Mon Sep 17 00:00:00 2001 From: Rohit Kumar Date: Mon, 11 Sep 2017 00:33:13 +0530 Subject: [PATCH 0046/1645] autoconf: sdm670: add support to compile analog and digital codec Make autoconf changes to enable compilation of analog and digital codec separately. Change-Id: I0e7da48ead0bfe535f9103776845e068a3c149d3 Signed-off-by: Rohit Kumar --- config/sdm670auto.conf | 2 ++ config/sdm670autoconf.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/config/sdm670auto.conf b/config/sdm670auto.conf index cbeb2dee9ae8..ca30dd039e7d 100644 --- a/config/sdm670auto.conf +++ b/config/sdm670auto.conf @@ -43,5 +43,7 @@ CONFIG_SND_SOC_MSM_STUB=y CONFIG_WCD_DSP_GLINK=y CONFIG_MSM_AVTIMER=y CONFIG_SND_SOC_SDM660_CDC=y +CONFIG_SND_SOC_ANALOG_CDC=y +CONFIG_SND_SOC_DIGITAL_CDC=y CONFIG_SND_SOC_MSM_SDW=y CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y diff --git a/config/sdm670autoconf.h b/config/sdm670autoconf.h index 1cec92c8c7a8..6aba91d63f8d 100644 --- a/config/sdm670autoconf.h +++ b/config/sdm670autoconf.h @@ -56,5 +56,7 @@ #define CONFIG_SND_SOC_EXT_CODEC 1 #define CONFIG_SND_SOC_INT_CODEC 1 #define CONFIG_SND_SOC_SDM660_CDC 1 +#define CONFIG_SND_SOC_ANALOG_CDC 1 +#define CONFIG_SND_SOC_DIGITAL_CDC 1 #define CONFIG_SND_SOC_MSM_SDW 1 #define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 -- GitLab From 6f90162f22361d74d3d2deb08dae0afffce5bcb0 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 19 Sep 2017 10:21:57 +0800 Subject: [PATCH 0047/1645] ASoC: wcd-mbhc: update electrical removal detection logic when moisture is in jack, removing of the plug result in electrical removal interrupt. So, update electrical interrupt handler to handle mechanical removal based on moisture status. CRs-Fixed: 2058106 Change-Id: I9cfbfbaf04783f0edcadb14d7828759020745289 Signed-off-by: Meng Wang --- asoc/codecs/wcd-mbhc-adc.c | 66 ++++++++++++++++++---- asoc/codecs/wcd-mbhc-legacy.c | 90 ++++++++++++++++++++++++------ asoc/codecs/wcd-mbhc-v2.c | 3 +- asoc/codecs/wcd-mbhc-v2.h | 6 ++ asoc/codecs/wcd9335.c | 6 ++ asoc/codecs/wcd934x/wcd934x-mbhc.c | 6 ++ 6 files changed, 148 insertions(+), 29 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index e44eec9fa5c7..ad414770a2cc 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -895,6 +895,8 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) struct wcd_mbhc *mbhc = data; unsigned long timeout; int adc_threshold, output_mv, retry = 0; + bool hphpa_on = false; + u8 moisture_status = 0; pr_debug("%s: enter\n", __func__); WCD_MBHC_RSC_LOCK(mbhc); @@ -928,17 +930,59 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) goto exit; } - /* - * ADC COMPLETE and ELEC_REM interrupts are both enabled for HEADPHONE, - * need to reject the ADC COMPLETE interrupt which follows ELEC_REM one - * when HEADPHONE is removed. - */ - if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) - mbhc->extn_cable_hph_rem = true; - WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_DETECTION_DONE, 0); - WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, 0); - WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 0); - wcd_mbhc_elec_hs_report_unplug(mbhc); + if (mbhc->mbhc_cfg->moisture_en) { + if (mbhc->mbhc_cb->hph_pa_on_status) + if (mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec)) { + hphpa_on = true; + WCD_MBHC_REG_UPDATE_BITS( + WCD_MBHC_HPHL_PA_EN, 0); + WCD_MBHC_REG_UPDATE_BITS( + WCD_MBHC_HPH_PA_EN, 0); + } + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHR_GND, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_GND, 1); + /* wait for 50ms to get moisture status */ + usleep_range(50000, 50100); + + WCD_MBHC_REG_READ(WCD_MBHC_MOISTURE_STATUS, moisture_status); + } + + if (mbhc->mbhc_cfg->moisture_en && !moisture_status) { + pr_debug("%s: moisture present in jack\n", __func__); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MECH_DETECTION_TYPE, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0); + mbhc->btn_press_intr = false; + mbhc->is_btn_press = false; + if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET) + wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADSET); + else if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) + wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADPHONE); + else if (mbhc->current_plug == MBHC_PLUG_TYPE_GND_MIC_SWAP) + wcd_mbhc_report_plug(mbhc, 0, SND_JACK_UNSUPPORTED); + else if (mbhc->current_plug == MBHC_PLUG_TYPE_HIGH_HPH) + wcd_mbhc_report_plug(mbhc, 0, SND_JACK_LINEOUT); + } else { + /* + * ADC COMPLETE and ELEC_REM interrupts are both enabled for + * HEADPHONE, need to reject the ADC COMPLETE interrupt which + * follows ELEC_REM one when HEADPHONE is removed. + */ + if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) + mbhc->extn_cable_hph_rem = true; + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_DETECTION_DONE, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 0); + wcd_mbhc_elec_hs_report_unplug(mbhc); + + if (hphpa_on) { + hphpa_on = false; + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_PA_EN, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPH_PA_EN, 1); + } + } exit: WCD_MBHC_RSC_UNLOCK(mbhc); pr_debug("%s: leave\n", __func__); diff --git a/asoc/codecs/wcd-mbhc-legacy.c b/asoc/codecs/wcd-mbhc-legacy.c index 745e2e81a556..a72f64b40861 100644 --- a/asoc/codecs/wcd-mbhc-legacy.c +++ b/asoc/codecs/wcd-mbhc-legacy.c @@ -794,6 +794,8 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) unsigned long timeout; bool removed = true; int retry = 0; + bool hphpa_on = false; + u8 moisture_status = 0; pr_debug("%s: enter\n", __func__); @@ -830,29 +832,78 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) WCD_MBHC_REG_READ(WCD_MBHC_HS_COMP_RESULT, hs_comp_result); if (removed) { - if (!(hphl_sch && mic_sch && hs_comp_result)) { - /* - * extension cable is still plugged in - * report it as LINEOUT device - */ - goto report_unplug; + if (mbhc->mbhc_cfg->moisture_en) { + if (mbhc->mbhc_cb->hph_pa_on_status) + if ( + mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec)) { + hphpa_on = true; + WCD_MBHC_REG_UPDATE_BITS( + WCD_MBHC_HPHL_PA_EN, 0); + WCD_MBHC_REG_UPDATE_BITS( + WCD_MBHC_HPH_PA_EN, 0); + } + + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHR_GND, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_GND, 1); + /* wait for 50ms to get moisture status */ + usleep_range(50000, 50100); + + WCD_MBHC_REG_READ( + WCD_MBHC_MOISTURE_STATUS, moisture_status); + } + + if (mbhc->mbhc_cfg->moisture_en && !moisture_status) { + pr_debug("%s: moisture present in jack\n", __func__); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 0); + WCD_MBHC_REG_UPDATE_BITS( + WCD_MBHC_MECH_DETECTION_TYPE, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0); + mbhc->btn_press_intr = false; + mbhc->is_btn_press = false; + if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET) + wcd_mbhc_report_plug( + mbhc, 0, SND_JACK_HEADSET); + else if (mbhc->current_plug == + MBHC_PLUG_TYPE_HEADPHONE) + wcd_mbhc_report_plug( + mbhc, 0, SND_JACK_HEADPHONE); + else if (mbhc->current_plug == + MBHC_PLUG_TYPE_GND_MIC_SWAP) + wcd_mbhc_report_plug( + mbhc, 0, SND_JACK_UNSUPPORTED); + else if (mbhc->current_plug == + MBHC_PLUG_TYPE_HIGH_HPH) + wcd_mbhc_report_plug( + mbhc, 0, SND_JACK_LINEOUT); } else { - if (!mic_sch) { - mic_trigerred++; - pr_debug("%s: Removal MIC trigerred %d\n", - __func__, mic_trigerred); - } - if (!hphl_sch) { - hphl_trigerred++; - pr_debug("%s: Removal HPHL trigerred %d\n", - __func__, hphl_trigerred); - } - if (mic_trigerred && hphl_trigerred) { + if (!(hphl_sch && mic_sch && hs_comp_result)) { /* * extension cable is still plugged in * report it as LINEOUT device */ goto report_unplug; + } else { + if (!mic_sch) { + mic_trigerred++; + pr_debug( + "%s: Removal MIC trigerred %d\n", + __func__, mic_trigerred); + } + if (!hphl_sch) { + hphl_trigerred++; + pr_debug( + "%s: Removal HPHL trigerred %d\n", + __func__, hphl_trigerred); + } + if (mic_trigerred && hphl_trigerred) { + /* + * extension cable is still plugged in + * report it as LINEOUT device + */ + goto report_unplug; + } } } } @@ -863,6 +914,11 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) report_unplug: wcd_mbhc_elec_hs_report_unplug(mbhc); + if (hphpa_on) { + hphpa_on = false; + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_PA_EN, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPH_PA_EN, 1); + } hphl_trigerred = 0; mic_trigerred = 0; WCD_MBHC_RSC_UNLOCK(mbhc); diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 6b3dd8626da5..339d0f3d420b 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -550,7 +550,7 @@ void wcd_mbhc_hs_elec_irq(struct wcd_mbhc *mbhc, int irq_type, } EXPORT_SYMBOL(wcd_mbhc_hs_elec_irq); -static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, +void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, enum snd_jack_types jack_type) { struct snd_soc_codec *codec = mbhc->codec; @@ -725,6 +725,7 @@ static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, } pr_debug("%s: leave hph_status %x\n", __func__, mbhc->hph_status); } +EXPORT_SYMBOL(wcd_mbhc_report_plug); void wcd_mbhc_elec_hs_report_unplug(struct wcd_mbhc *mbhc) { diff --git a/asoc/codecs/wcd-mbhc-v2.h b/asoc/codecs/wcd-mbhc-v2.h index c8714fc3abbc..32dc78ca0a09 100644 --- a/asoc/codecs/wcd-mbhc-v2.h +++ b/asoc/codecs/wcd-mbhc-v2.h @@ -16,6 +16,7 @@ #include #include #include "wcdcal-hwdep.h" +#include #define TOMBAK_MBHC_NC 0 #define TOMBAK_MBHC_NO 1 @@ -204,6 +205,9 @@ enum wcd_mbhc_register_function { WCD_MBHC_ANC_DET_EN, WCD_MBHC_FSM_STATUS, WCD_MBHC_MUX_CTL, + WCD_MBHC_MOISTURE_STATUS, + WCD_MBHC_HPHR_GND, + WCD_MBHC_HPHL_GND, WCD_MBHC_HPHL_OCP_DET_EN, WCD_MBHC_HPHR_OCP_DET_EN, WCD_MBHC_HPHL_OCP_STATUS, @@ -594,5 +598,7 @@ void wcd_mbhc_jack_report(struct wcd_mbhc *mbhc, struct snd_soc_jack *jack, int status, int mask); int wcd_cancel_btn_work(struct wcd_mbhc *mbhc); int wcd_mbhc_get_button_mask(struct wcd_mbhc *mbhc); +void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, + enum snd_jack_types jack_type); #endif /* __WCD_MBHC_V2_H__ */ diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 21de9f5f6d6f..19877b96b0ed 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -650,6 +650,12 @@ static struct wcd_mbhc_register 0, 0, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL", WCD9335_MBHC_CTL_2, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MOISTURE_STATUS", + WCD9335_MBHC_FSM_STATUS, 0X20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_GND", + WCD9335_HPH_PA_CTL2, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_GND", + WCD9335_HPH_PA_CTL2, 0x10, 4, 0), }; static const struct wcd_mbhc_intr intr_ids = { diff --git a/asoc/codecs/wcd934x/wcd934x-mbhc.c b/asoc/codecs/wcd934x/wcd934x-mbhc.c index 4eb14de31075..807d4ea58e89 100644 --- a/asoc/codecs/wcd934x/wcd934x-mbhc.c +++ b/asoc/codecs/wcd934x/wcd934x-mbhc.c @@ -120,6 +120,12 @@ static struct wcd_mbhc_register WCD934X_MBHC_STATUS_SPARE_1, 0x01, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL", WCD934X_MBHC_NEW_CTL_2, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MOISTURE_STATUS", + WCD934X_MBHC_NEW_FSM_STATUS, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_GND", + WCD934X_HPH_PA_CTL2, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_GND", + WCD934X_HPH_PA_CTL2, 0x10, 4, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_DET_EN", WCD934X_HPH_L_TEST, 0x01, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_DET_EN", -- GitLab From 8968c5f2a2dc09b0c9a97fad45cbb7aa2273cba6 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 28 Sep 2017 15:49:45 +0530 Subject: [PATCH 0048/1645] ASoC: Modify name for Tertiary MI2S RX and TX Change name from "TERTIARY_MI2S" to "TERT_MI2S" for RX and TX in order to maintain consistency with other Mi2S back-ends. CRs-Fixed: 2075701 Change-Id: I52116df27a780e42de4a6b3d74249f77d311d8d4 Signed-off-by: Vatsal Bucha --- asoc/msm-pcm-routing-v2.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 4e823d3eba3c..e5cc7bb2066b 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -56,8 +56,8 @@ #define LPASS_BE_SEC_MI2S_TX "SEC_MI2S_TX" #define LPASS_BE_PRI_MI2S_RX "PRI_MI2S_RX" #define LPASS_BE_PRI_MI2S_TX "PRI_MI2S_TX" -#define LPASS_BE_TERT_MI2S_RX "TERTIARY_MI2S_RX" -#define LPASS_BE_TERT_MI2S_TX "TERTIARY_MI2S_TX" +#define LPASS_BE_TERT_MI2S_RX "TERT_MI2S_RX" +#define LPASS_BE_TERT_MI2S_TX "TERT_MI2S_TX" #define LPASS_BE_AUDIO_I2S_RX "AUDIO_I2S_RX" #define LPASS_BE_STUB_RX "STUB_RX" #define LPASS_BE_STUB_TX "STUB_TX" -- GitLab From 9c429506158aac4d5903f5e157c6c0b51e5b1d31 Mon Sep 17 00:00:00 2001 From: kunleiz Date: Mon, 18 Sep 2017 16:10:19 +0800 Subject: [PATCH 0049/1645] rtac: add size check when reading cal data kvaddr buffer Add size check to ensure cal data bytes size fits inside the cal data when copying to user space buffer. CRs-Fixed: 2110256 Change-Id: I511999984684a9db4aaf1cf2c65eb1495c36980f Signed-off-by: kunleiz --- dsp/rtac.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/dsp/rtac.c b/dsp/rtac.c index 456ac5773d64..84ef8355a1c3 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -909,6 +909,14 @@ int send_adm_apr(void *buf, u32 opcode) bytes_returned = ((u32 *)rtac_cal[ADM_RTAC_CAL].cal_data. kvaddr)[2] + 3 * sizeof(u32); + if (bytes_returned > rtac_cal[ADM_RTAC_CAL]. + map_data.map_size) { + pr_err("%s: Invalid data size = %d\n", + __func__, bytes_returned); + result = -EINVAL; + goto err; + } + if (bytes_returned > user_buf_size) { pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n", __func__, user_buf_size, bytes_returned); @@ -1132,6 +1140,14 @@ int send_rtac_asm_apr(void *buf, u32 opcode) bytes_returned = ((u32 *)rtac_cal[ASM_RTAC_CAL].cal_data. kvaddr)[2] + 3 * sizeof(u32); + if (bytes_returned > rtac_cal[ASM_RTAC_CAL]. + map_data.map_size) { + pr_err("%s: Invalid data size = %d\n", + __func__, bytes_returned); + result = -EINVAL; + goto err; + } + if (bytes_returned > user_buf_size) { pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n", __func__, user_buf_size, bytes_returned); @@ -1392,6 +1408,14 @@ static int send_rtac_afe_apr(void *buf, uint32_t opcode) bytes_returned = get_resp->param_size + sizeof(struct afe_port_param_data_v2); + if (bytes_returned > rtac_cal[AFE_RTAC_CAL]. + map_data.map_size) { + pr_err("%s: Invalid data size = %d\n", + __func__, bytes_returned); + result = -EINVAL; + goto err; + } + if (bytes_returned > user_afe_buf.buf_size) { pr_err("%s: user size = 0x%x, returned size = 0x%x\n", __func__, user_afe_buf.buf_size, @@ -1617,6 +1641,14 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode) bytes_returned = ((u32 *)rtac_cal[VOICE_RTAC_CAL].cal_data. kvaddr)[2] + 3 * sizeof(u32); + if (bytes_returned > rtac_cal[VOICE_RTAC_CAL]. + map_data.map_size) { + pr_err("%s: Invalid data size = %d\n", + __func__, bytes_returned); + result = -EINVAL; + goto err; + } + if (bytes_returned > user_buf_size) { pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n", __func__, user_buf_size, bytes_returned); -- GitLab From 4b5bd80a91f86cca6dc2b1197ff0716539c7779c Mon Sep 17 00:00:00 2001 From: Rohit Kumar Date: Mon, 11 Sep 2017 00:30:40 +0530 Subject: [PATCH 0050/1645] asoc: codecs: Add support to compile internal codec as module Separate compilation of analog and digital codec and add support to compile them as dynamic module. Change-Id: I81f01bf60aef71f67e025fa4ff1ba805a960e61d Signed-off-by: Rohit Kumar --- asoc/codecs/sdm660_cdc/Makefile | 6 +- .../codecs/sdm660_cdc/msm-analog-cdc-regmap.h | 186 ++++++++++++++++++ asoc/codecs/sdm660_cdc/msm-analog-cdc.c | 4 +- ...m660-regmap.c => msm-digital-cdc-regmap.c} | 159 --------------- 4 files changed, 193 insertions(+), 162 deletions(-) create mode 100644 asoc/codecs/sdm660_cdc/msm-analog-cdc-regmap.h rename asoc/codecs/sdm660_cdc/{sdm660-regmap.c => msm-digital-cdc-regmap.c} (72%) diff --git a/asoc/codecs/sdm660_cdc/Makefile b/asoc/codecs/sdm660_cdc/Makefile index d846fae26054..0ebf40717dd7 100644 --- a/asoc/codecs/sdm660_cdc/Makefile +++ b/asoc/codecs/sdm660_cdc/Makefile @@ -1,2 +1,4 @@ -snd-soc-sdm660-cdc-objs := msm-analog-cdc.o msm-digital-cdc.o sdm660-regmap.o -obj-$(CONFIG_SND_SOC_SDM660_CDC) += snd-soc-sdm660-cdc.o sdm660-cdc-irq.o +snd-soc-analog-cdc-objs := sdm660-cdc-irq.o msm-analog-cdc.o +snd-soc-digital-cdc-objs := msm-digital-cdc.o msm-digital-cdc-regmap.o +obj-$(CONFIG_SND_SOC_ANALOG_CDC) += snd-soc-analog-cdc.o +obj-$(CONFIG_SND_SOC_DIGITAL_CDC) += snd-soc-digital-cdc.o diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc-regmap.h b/asoc/codecs/sdm660_cdc/msm-analog-cdc-regmap.h new file mode 100644 index 000000000000..55846a1a20ca --- /dev/null +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc-regmap.h @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef ANALOG_CDC_REGMAP_H +#define ANALOG_CDC_REGMAP_H + +#include +#include "sdm660-cdc-registers.h" + +/* + * Default register reset values that are common across different versions + * are defined here. If a register reset value is changed based on version + * then remove it from this structure and add it in version specific + * structures. + */ + +struct reg_default + msm89xx_pmic_cdc_defaults[MSM89XX_PMIC_CDC_CACHE_SIZE] = { + {MSM89XX_PMIC_DIGITAL_REVISION1, 0x00}, + {MSM89XX_PMIC_DIGITAL_REVISION2, 0x00}, + {MSM89XX_PMIC_DIGITAL_PERPH_TYPE, 0x23}, + {MSM89XX_PMIC_DIGITAL_PERPH_SUBTYPE, 0x01}, + {MSM89XX_PMIC_DIGITAL_INT_RT_STS, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_SET_TYPE, 0xFF}, + {MSM89XX_PMIC_DIGITAL_INT_POLARITY_HIGH, 0xFF}, + {MSM89XX_PMIC_DIGITAL_INT_POLARITY_LOW, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_LATCHED_CLR, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_EN_SET, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_EN_CLR, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_LATCHED_STS, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_PENDING_STS, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_MID_SEL, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_PRIORITY, 0x00}, + {MSM89XX_PMIC_DIGITAL_GPIO_MODE, 0x00}, + {MSM89XX_PMIC_DIGITAL_PIN_CTL_OE, 0x01}, + {MSM89XX_PMIC_DIGITAL_PIN_CTL_DATA, 0x00}, + {MSM89XX_PMIC_DIGITAL_PIN_STATUS, 0x00}, + {MSM89XX_PMIC_DIGITAL_HDRIVE_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL, 0x02}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL, 0x02}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_HPHR_DAC_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX1_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX2_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX3_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX_LB_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_RX_CTL1, 0x7C}, + {MSM89XX_PMIC_DIGITAL_CDC_RX_CTL2, 0x7C}, + {MSM89XX_PMIC_DIGITAL_CDC_RX_CTL3, 0x7C}, + {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA0, 0x00}, + {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA1, 0x00}, + {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA2, 0x00}, + {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA3, 0x00}, + {MSM89XX_PMIC_DIGITAL_DIG_DEBUG_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_DIG_DEBUG_EN, 0x00}, + {MSM89XX_PMIC_DIGITAL_SPARE_0, 0x00}, + {MSM89XX_PMIC_DIGITAL_SPARE_1, 0x00}, + {MSM89XX_PMIC_DIGITAL_SPARE_2, 0x00}, + {MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0x00}, + {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL1, 0x00}, + {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL2, 0x02}, + {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x05}, + {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_TEST1, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_TEST_VAL, 0x00}, + {MSM89XX_PMIC_DIGITAL_TRIM_NUM, 0x00}, + {MSM89XX_PMIC_DIGITAL_TRIM_CTRL, 0x00}, + {MSM89XX_PMIC_ANALOG_REVISION1, 0x00}, + {MSM89XX_PMIC_ANALOG_REVISION2, 0x00}, + {MSM89XX_PMIC_ANALOG_REVISION3, 0x00}, + {MSM89XX_PMIC_ANALOG_REVISION4, 0x00}, + {MSM89XX_PMIC_ANALOG_PERPH_TYPE, 0x23}, + {MSM89XX_PMIC_ANALOG_PERPH_SUBTYPE, 0x09}, + {MSM89XX_PMIC_ANALOG_INT_RT_STS, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_SET_TYPE, 0x3F}, + {MSM89XX_PMIC_ANALOG_INT_POLARITY_HIGH, 0x3F}, + {MSM89XX_PMIC_ANALOG_INT_POLARITY_LOW, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_LATCHED_CLR, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_EN_SET, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_EN_CLR, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_LATCHED_STS, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_PENDING_STS, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_MID_SEL, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_PRIORITY, 0x00}, + {MSM89XX_PMIC_ANALOG_MICB_1_EN, 0x00}, + {MSM89XX_PMIC_ANALOG_MICB_1_VAL, 0x20}, + {MSM89XX_PMIC_ANALOG_MICB_1_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS, 0x49}, + {MSM89XX_PMIC_ANALOG_MICB_2_EN, 0x20}, + {MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2, 0x00}, + {MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x35}, + {MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x08}, + {MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, 0x98}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL, 0x20}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL, 0x40}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN3_CTL, 0x61}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN4_CTL, 0x80}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT, 0x00}, + {MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x00}, + {MSM89XX_PMIC_ANALOG_TX_1_EN, 0x03}, + {MSM89XX_PMIC_ANALOG_TX_2_EN, 0x03}, + {MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_1, 0xBF}, + {MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_2, 0x8C}, + {MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x6B}, + {MSM89XX_PMIC_ANALOG_TX_1_2_TXFE_CLKDIV, 0x51}, + {MSM89XX_PMIC_ANALOG_TX_3_EN, 0x02}, + {MSM89XX_PMIC_ANALOG_NCP_EN, 0x26}, + {MSM89XX_PMIC_ANALOG_NCP_CLK, 0x23}, + {MSM89XX_PMIC_ANALOG_NCP_DEGLITCH, 0x5B}, + {MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0x08}, + {MSM89XX_PMIC_ANALOG_NCP_BIAS, 0x29}, + {MSM89XX_PMIC_ANALOG_NCP_VCTRL, 0x24}, + {MSM89XX_PMIC_ANALOG_NCP_TEST, 0x00}, + {MSM89XX_PMIC_ANALOG_NCP_CLIM_ADDR, 0xD5}, + {MSM89XX_PMIC_ANALOG_RX_CLOCK_DIVIDER, 0xE8}, + {MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL, 0xCF}, + {MSM89XX_PMIC_ANALOG_RX_COM_OCP_COUNT, 0x6E}, + {MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, 0x18}, + {MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA, 0x5A}, + {MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_LDO_OCP, 0x69}, + {MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_CNP, 0x29}, + {MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, 0x80}, + {MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_CTL, 0xDA}, + {MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME, 0x16}, + {MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x00}, + {MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x20}, + {MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x00}, + {MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x20}, + {MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x12}, + {MSM89XX_PMIC_ANALOG_RX_ATEST, 0x00}, + {MSM89XX_PMIC_ANALOG_RX_HPH_STATUS, 0x0C}, + {MSM89XX_PMIC_ANALOG_RX_EAR_STATUS, 0x00}, + {MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x83}, + {MSM89XX_PMIC_ANALOG_SPKR_DRV_CLIP_DET, 0x91}, + {MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x29}, + {MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET, 0x4D}, + {MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1}, + {MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0x1E}, + {MSM89XX_PMIC_ANALOG_SPKR_DRV_MISC, 0xCB}, + {MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x00}, + {MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x02}, + {MSM89XX_PMIC_ANALOG_OUTPUT_VOLTAGE, 0x14}, + {MSM89XX_PMIC_ANALOG_BYPASS_MODE, 0x00}, + {MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, 0x1F}, + {MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO, 0x8C}, + {MSM89XX_PMIC_ANALOG_RDSON_MAX_DUTY_CYCLE, 0xC0}, + {MSM89XX_PMIC_ANALOG_BOOST_TEST1_1, 0x00}, + {MSM89XX_PMIC_ANALOG_BOOST_TEST_2, 0x00}, + {MSM89XX_PMIC_ANALOG_SPKR_SAR_STATUS, 0x00}, + {MSM89XX_PMIC_ANALOG_SPKR_DRV_STATUS, 0x00}, + {MSM89XX_PMIC_ANALOG_PBUS_ADD_CSR, 0x00}, + {MSM89XX_PMIC_ANALOG_PBUS_ADD_SEL, 0x00}, + {MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0x00}, + {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL1, 0x00}, + {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL2, 0x01}, + {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x05}, + {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_TEST1, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_TEST_VAL, 0x00}, + {MSM89XX_PMIC_ANALOG_TRIM_NUM, 0x04}, + {MSM89XX_PMIC_ANALOG_TRIM_CTRL1, 0x00}, + {MSM89XX_PMIC_ANALOG_TRIM_CTRL2, 0x00}, + {MSM89XX_PMIC_ANALOG_TRIM_CTRL3, 0x00}, + {MSM89XX_PMIC_ANALOG_TRIM_CTRL4, 0x00}, +}; + +#endif diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c index ddef508cb682..623303c3adca 100644 --- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c @@ -30,7 +30,7 @@ #include "msm-analog-cdc.h" #include "msm-cdc-common.h" #include "sdm660-cdc-irq.h" -#include "sdm660-cdc-registers.h" +#include "msm-analog-cdc-regmap.h" #include "../../sdm660-common.h" #include "../wcd-mbhc-v2-api.h" @@ -351,6 +351,7 @@ void msm_anlg_cdc_spk_ext_pa_cb( dev_dbg(codec->dev, "%s: Enter\n", __func__); sdm660_cdc->codec_spk_ext_pa_cb = codec_spk_ext_pa; } +EXPORT_SYMBOL(msm_anlg_cdc_spk_ext_pa_cb); static void msm_anlg_cdc_compute_impedance(struct snd_soc_codec *codec, s16 l, s16 r, uint32_t *zl, uint32_t *zr, @@ -3172,6 +3173,7 @@ int msm_anlg_cdc_mclk_enable(struct snd_soc_codec *codec, } return 0; } +EXPORT_SYMBOL(msm_anlg_cdc_mclk_enable); static int msm_anlg_cdc_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) diff --git a/asoc/codecs/sdm660_cdc/sdm660-regmap.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc-regmap.c similarity index 72% rename from asoc/codecs/sdm660_cdc/sdm660-regmap.c rename to asoc/codecs/sdm660_cdc/msm-digital-cdc-regmap.c index 7d8ac6df14bb..a62679174567 100644 --- a/asoc/codecs/sdm660_cdc/sdm660-regmap.c +++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc-regmap.c @@ -154,165 +154,6 @@ struct reg_default {MSM89XX_CDC_CORE_TX4_DMIC_CTL, 0x00}, }; -struct reg_default - msm89xx_pmic_cdc_defaults[MSM89XX_PMIC_CDC_CACHE_SIZE] = { - {MSM89XX_PMIC_DIGITAL_REVISION1, 0x00}, - {MSM89XX_PMIC_DIGITAL_REVISION2, 0x00}, - {MSM89XX_PMIC_DIGITAL_PERPH_TYPE, 0x23}, - {MSM89XX_PMIC_DIGITAL_PERPH_SUBTYPE, 0x01}, - {MSM89XX_PMIC_DIGITAL_INT_RT_STS, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_SET_TYPE, 0xFF}, - {MSM89XX_PMIC_DIGITAL_INT_POLARITY_HIGH, 0xFF}, - {MSM89XX_PMIC_DIGITAL_INT_POLARITY_LOW, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_LATCHED_CLR, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_EN_SET, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_EN_CLR, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_LATCHED_STS, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_PENDING_STS, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_MID_SEL, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_PRIORITY, 0x00}, - {MSM89XX_PMIC_DIGITAL_GPIO_MODE, 0x00}, - {MSM89XX_PMIC_DIGITAL_PIN_CTL_OE, 0x01}, - {MSM89XX_PMIC_DIGITAL_PIN_CTL_DATA, 0x00}, - {MSM89XX_PMIC_DIGITAL_PIN_STATUS, 0x00}, - {MSM89XX_PMIC_DIGITAL_HDRIVE_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL, 0x02}, - {MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL, 0x02}, - {MSM89XX_PMIC_DIGITAL_CDC_CONN_HPHR_DAC_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX1_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX2_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX3_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX_LB_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_RX_CTL1, 0x7C}, - {MSM89XX_PMIC_DIGITAL_CDC_RX_CTL2, 0x7C}, - {MSM89XX_PMIC_DIGITAL_CDC_RX_CTL3, 0x7C}, - {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA0, 0x00}, - {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA1, 0x00}, - {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA2, 0x00}, - {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA3, 0x00}, - {MSM89XX_PMIC_DIGITAL_DIG_DEBUG_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_DIG_DEBUG_EN, 0x00}, - {MSM89XX_PMIC_DIGITAL_SPARE_0, 0x00}, - {MSM89XX_PMIC_DIGITAL_SPARE_1, 0x00}, - {MSM89XX_PMIC_DIGITAL_SPARE_2, 0x00}, - {MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0x00}, - {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL1, 0x00}, - {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL2, 0x02}, - {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x05}, - {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_TEST1, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_TEST_VAL, 0x00}, - {MSM89XX_PMIC_DIGITAL_TRIM_NUM, 0x00}, - {MSM89XX_PMIC_DIGITAL_TRIM_CTRL, 0x00}, - {MSM89XX_PMIC_ANALOG_REVISION1, 0x00}, - {MSM89XX_PMIC_ANALOG_REVISION2, 0x00}, - {MSM89XX_PMIC_ANALOG_REVISION3, 0x00}, - {MSM89XX_PMIC_ANALOG_REVISION4, 0x00}, - {MSM89XX_PMIC_ANALOG_PERPH_TYPE, 0x23}, - {MSM89XX_PMIC_ANALOG_PERPH_SUBTYPE, 0x09}, - {MSM89XX_PMIC_ANALOG_INT_RT_STS, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_SET_TYPE, 0x3F}, - {MSM89XX_PMIC_ANALOG_INT_POLARITY_HIGH, 0x3F}, - {MSM89XX_PMIC_ANALOG_INT_POLARITY_LOW, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_LATCHED_CLR, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_EN_SET, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_EN_CLR, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_LATCHED_STS, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_PENDING_STS, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_MID_SEL, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_PRIORITY, 0x00}, - {MSM89XX_PMIC_ANALOG_MICB_1_EN, 0x00}, - {MSM89XX_PMIC_ANALOG_MICB_1_VAL, 0x20}, - {MSM89XX_PMIC_ANALOG_MICB_1_CTL, 0x00}, - {MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS, 0x49}, - {MSM89XX_PMIC_ANALOG_MICB_2_EN, 0x20}, - {MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2, 0x00}, - {MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, 0x00}, - {MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x35}, - {MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x08}, - {MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, 0x00}, - {MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, 0x98}, - {MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, 0x00}, - {MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL, 0x20}, - {MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL, 0x40}, - {MSM89XX_PMIC_ANALOG_MBHC_BTN3_CTL, 0x61}, - {MSM89XX_PMIC_ANALOG_MBHC_BTN4_CTL, 0x80}, - {MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT, 0x00}, - {MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x00}, - {MSM89XX_PMIC_ANALOG_TX_1_EN, 0x03}, - {MSM89XX_PMIC_ANALOG_TX_2_EN, 0x03}, - {MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_1, 0xBF}, - {MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_2, 0x8C}, - {MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL, 0x00}, - {MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x6B}, - {MSM89XX_PMIC_ANALOG_TX_1_2_TXFE_CLKDIV, 0x51}, - {MSM89XX_PMIC_ANALOG_TX_3_EN, 0x02}, - {MSM89XX_PMIC_ANALOG_NCP_EN, 0x26}, - {MSM89XX_PMIC_ANALOG_NCP_CLK, 0x23}, - {MSM89XX_PMIC_ANALOG_NCP_DEGLITCH, 0x5B}, - {MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0x08}, - {MSM89XX_PMIC_ANALOG_NCP_BIAS, 0x29}, - {MSM89XX_PMIC_ANALOG_NCP_VCTRL, 0x24}, - {MSM89XX_PMIC_ANALOG_NCP_TEST, 0x00}, - {MSM89XX_PMIC_ANALOG_NCP_CLIM_ADDR, 0xD5}, - {MSM89XX_PMIC_ANALOG_RX_CLOCK_DIVIDER, 0xE8}, - {MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL, 0xCF}, - {MSM89XX_PMIC_ANALOG_RX_COM_OCP_COUNT, 0x6E}, - {MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, 0x18}, - {MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA, 0x5A}, - {MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_LDO_OCP, 0x69}, - {MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_CNP, 0x29}, - {MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, 0x80}, - {MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_CTL, 0xDA}, - {MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME, 0x16}, - {MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x00}, - {MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x20}, - {MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x00}, - {MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x20}, - {MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x12}, - {MSM89XX_PMIC_ANALOG_RX_ATEST, 0x00}, - {MSM89XX_PMIC_ANALOG_RX_HPH_STATUS, 0x0C}, - {MSM89XX_PMIC_ANALOG_RX_EAR_STATUS, 0x00}, - {MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x00}, - {MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x00}, - {MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x83}, - {MSM89XX_PMIC_ANALOG_SPKR_DRV_CLIP_DET, 0x91}, - {MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x29}, - {MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET, 0x4D}, - {MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1}, - {MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0x1E}, - {MSM89XX_PMIC_ANALOG_SPKR_DRV_MISC, 0xCB}, - {MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x00}, - {MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x02}, - {MSM89XX_PMIC_ANALOG_OUTPUT_VOLTAGE, 0x14}, - {MSM89XX_PMIC_ANALOG_BYPASS_MODE, 0x00}, - {MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, 0x1F}, - {MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO, 0x8C}, - {MSM89XX_PMIC_ANALOG_RDSON_MAX_DUTY_CYCLE, 0xC0}, - {MSM89XX_PMIC_ANALOG_BOOST_TEST1_1, 0x00}, - {MSM89XX_PMIC_ANALOG_BOOST_TEST_2, 0x00}, - {MSM89XX_PMIC_ANALOG_SPKR_SAR_STATUS, 0x00}, - {MSM89XX_PMIC_ANALOG_SPKR_DRV_STATUS, 0x00}, - {MSM89XX_PMIC_ANALOG_PBUS_ADD_CSR, 0x00}, - {MSM89XX_PMIC_ANALOG_PBUS_ADD_SEL, 0x00}, - {MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0x00}, - {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL1, 0x00}, - {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL2, 0x01}, - {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x05}, - {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_TEST1, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_TEST_VAL, 0x00}, - {MSM89XX_PMIC_ANALOG_TRIM_NUM, 0x04}, - {MSM89XX_PMIC_ANALOG_TRIM_CTRL1, 0x00}, - {MSM89XX_PMIC_ANALOG_TRIM_CTRL2, 0x00}, - {MSM89XX_PMIC_ANALOG_TRIM_CTRL3, 0x00}, - {MSM89XX_PMIC_ANALOG_TRIM_CTRL4, 0x00}, -}; - static const u8 msm89xx_cdc_core_reg_readable[MSM89XX_CDC_CORE_CACHE_SIZE] = { [MSM89XX_CDC_CORE_CLK_RX_RESET_CTL] = 1, [MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL] = 1, -- GitLab From 804f26b95f9c79c1ae988d38b471ac60e9c0f9b8 Mon Sep 17 00:00:00 2001 From: Rohit Kumar Date: Mon, 2 Oct 2017 10:35:21 +0530 Subject: [PATCH 0051/1645] asoc: sdm660: add sclk and mclk support for quinary interfaces Add sclk and mclk support for quinary MI2S interfaces for sdm660. Also, update MCLK IDs for secondary and quaternary MI2S. Change-Id: If6271224caffbf1623939d409e3e031d5a0c8423 Signed-off-by: Rohit Kumar --- asoc/sdm660-common.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c index 78218ab056a3..e90037a1d211 100644 --- a/asoc/sdm660-common.c +++ b/asoc/sdm660-common.c @@ -208,7 +208,8 @@ static u32 mi2s_ebit_clk[MI2S_MAX] = { Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT, Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT, Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT, - Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT }; struct msm_wsa881x_dev_info { @@ -401,6 +402,14 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = { Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, } }; @@ -415,7 +424,7 @@ static struct afe_clk_set mi2s_mclk[MI2S_MAX] = { }, { AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_MCLK_4, + Q6AFE_LPASS_CLK_ID_MCLK_2, Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, @@ -431,7 +440,15 @@ static struct afe_clk_set mi2s_mclk[MI2S_MAX] = { }, { AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_MCLK_2, + Q6AFE_LPASS_CLK_ID_MCLK_1, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR, Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, -- GitLab From af88e4c53bf79693197d64a2adfbede01aa196c6 Mon Sep 17 00:00:00 2001 From: Rohit Kumar Date: Wed, 4 Oct 2017 13:47:10 +0530 Subject: [PATCH 0052/1645] asoc: sdm660: configure mi2s gpios from machine driver Add support to configure MI2S gpios from machine driver. Change-Id: I561fdc775c63fd7b31d41a3053956d1643bea566 Signed-off-by: Rohit Kumar --- asoc/sdm660-common.c | 30 +++++++++++++++++++++--------- asoc/sdm660-common.h | 10 ++++++++++ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c index e90037a1d211..e6b82dfda7a2 100644 --- a/asoc/sdm660-common.c +++ b/asoc/sdm660-common.c @@ -170,15 +170,6 @@ static struct dev_config usb_tx_cfg = { .channels = 1, }; -enum { - PRIM_MI2S = 0, - SEC_MI2S, - TERT_MI2S, - QUAT_MI2S, - QUIN_MI2S, - MI2S_MAX, -}; - enum { PRIM_AUX_PCM = 0, SEC_AUX_PCM, @@ -2631,6 +2622,8 @@ int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) int port_id = msm_get_port_id(rtd->dai_link->id); int index = cpu_dai->id; unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); dev_dbg(rtd->card->dev, "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", @@ -2682,6 +2675,9 @@ int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) goto clk_off; } } + if (pdata->mi2s_gpio_p[index]) + msm_cdc_pinctrl_select_active_state( + pdata->mi2s_gpio_p[index]); } mutex_unlock(&mi2s_intf_conf[index].lock); return 0; @@ -2708,6 +2704,8 @@ void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = substream->private_data; int port_id = msm_get_port_id(rtd->dai_link->id); int index = rtd->cpu_dai->id; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); @@ -2718,6 +2716,10 @@ void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) mutex_lock(&mi2s_intf_conf[index].lock); if (--mi2s_intf_conf[index].ref_cnt == 0) { + if (pdata->mi2s_gpio_p[index]) + msm_cdc_pinctrl_select_sleep_state( + pdata->mi2s_gpio_p[index]); + ret = msm_mi2s_set_sclk(substream, false); if (ret < 0) { pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", @@ -3262,6 +3264,16 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) "qcom,cdc-ext-spk-gpios", 0); } + pdata->mi2s_gpio_p[PRIM_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,pri-mi2s-gpios", 0); + pdata->mi2s_gpio_p[SEC_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,sec-mi2s-gpios", 0); + pdata->mi2s_gpio_p[TERT_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,tert-mi2s-gpios", 0); + pdata->mi2s_gpio_p[QUAT_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,quat-mi2s-gpios", 0); + pdata->mi2s_gpio_p[QUIN_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,quin-mi2s-gpios", 0); /* * Parse US-Euro gpio info from DT. Report no error if us-euro * entry is not found in DT file as some targets do not support diff --git a/asoc/sdm660-common.h b/asoc/sdm660-common.h index 3276d1fa2c58..2c8e29e8792f 100644 --- a/asoc/sdm660-common.h +++ b/asoc/sdm660-common.h @@ -60,6 +60,15 @@ struct tdm_port { u32 channel; }; +enum { + PRIM_MI2S = 0, + SEC_MI2S, + TERT_MI2S, + QUAT_MI2S, + QUIN_MI2S, + MI2S_MAX, +}; + enum { DIG_CDC, ANA_CDC, @@ -90,6 +99,7 @@ struct msm_asoc_mach_data { struct device_node *comp_gpio_p; /* used by pinctrl API */ struct device_node *dmic_gpio_p; /* used by pinctrl API */ struct device_node *ext_spk_gpio_p; /* used by pinctrl API */ + struct device_node *mi2s_gpio_p[MI2S_MAX]; /* used by pinctrl API */ struct snd_soc_codec *codec; struct sdm660_codec sdm660_codec_fn; struct snd_info_entry *codec_root; -- GitLab From e87298f55a186eb290cce6a924ec895c88095715 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 11 Sep 2017 13:34:34 -0700 Subject: [PATCH 0053/1645] asoc: wcd934x: update micbias noise filter resistance Update micbias noise filter resistance for better performance during audio capture. CRs-Fixed: 2055467 Change-Id: I56eb08ca9785d36cf577f32297f2c719224f0f65 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd934x/wcd934x.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 66c7830e2a3f..7fd1e63dd6fe 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -8633,6 +8633,10 @@ static const struct tavil_reg_mask_val tavil_codec_reg_init_common_val[] = { {WCD934X_TLMM_DMIC3_DATA_PINCFG, 0xFF, 0x0a}, {WCD934X_CPE_SS_SVA_CFG, 0x60, 0x00}, {WCD934X_CPE_SS_CPAR_CFG, 0x10, 0x10}, + {WCD934X_MICB1_TEST_CTL_1, 0xff, 0xfa}, + {WCD934X_MICB2_TEST_CTL_1, 0xff, 0xfa}, + {WCD934X_MICB3_TEST_CTL_1, 0xff, 0xfa}, + {WCD934X_MICB4_TEST_CTL_1, 0xff, 0xfa}, }; static void tavil_codec_init_reg(struct tavil_priv *priv) -- GitLab From 0cf63fe351d62f05e49120a6e4c0d7a6e5181867 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Mon, 25 Sep 2017 18:41:31 -0700 Subject: [PATCH 0054/1645] soc: define dummy function for swrm_wcd_notify Add dummy function for swrm_wcd_notify to avoid compilation errors when configuration options 'CONFIG_SOUNDWIRE' and 'CONFIG_SOUNDWIRE_WCD_CTRL' are not selected for a target. Change-Id: Ie12d2df8777934494f0f8607d846e2d1ec49f2a6 Signed-off-by: Xiaoyu Ye --- include/soc/swr-wcd.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/include/soc/swr-wcd.h b/include/soc/swr-wcd.h index 041b901fd954..f6ff61a22fe2 100644 --- a/include/soc/swr-wcd.h +++ b/include/soc/swr-wcd.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -30,6 +30,13 @@ struct swr_mstr_port { u8 *port; }; +#if IS_ENABLED(CONFIG_SOUNDWIRE_WCD_CTRL) extern int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data); - +#else /* CONFIG_SOUNDWIRE_WCD_CTRL */ +static inline int swrm_wcd_notify(struct platform_device *pdev, u32 id, + void *data) +{ + return 0; +} +#endif /* CONFIG_SOUNDWIRE_WCD_CTRL */ #endif /* _LINUX_SWR_WCD_H */ -- GitLab From dbe57dc5a7ee412c0146663ad52b571a1279dcdc Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 5 Oct 2017 15:22:00 -0700 Subject: [PATCH 0055/1645] dsp: remove wakelock.h includes These includes aren't used and the file will go away in the future, so just drop it. Change-Id: I9bfcd39fd775e16765c46ea99da087292fe2e461 Signed-off-by: Stephen Boyd --- dsp/codecs/audio_utils_aio.h | 1 - dsp/q6afe.c | 1 - dsp/usf.c | 1 - 3 files changed, 3 deletions(-) diff --git a/dsp/codecs/audio_utils_aio.h b/dsp/codecs/audio_utils_aio.h index 82374f9a17a9..e44f9d9c642a 100644 --- a/dsp/codecs/audio_utils_aio.h +++ b/dsp/codecs/audio_utils_aio.h @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 0289144006fe..3cdf2eccb547 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/dsp/usf.c b/dsp/usf.c index dfa2097ddf67..f75439de4e94 100644 --- a/dsp/usf.c +++ b/dsp/usf.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include "q6usm.h" -- GitLab From c08b14f78c7b0064c4012ad0d4cbdc133a5ffa22 Mon Sep 17 00:00:00 2001 From: Rohit Kumar Date: Fri, 6 Oct 2017 10:52:17 +0530 Subject: [PATCH 0056/1645] dsp: add quinary interface support in q6afe Add support for quinary interfaces in q6afe. Also, fix routing for quinary tdm rx port. Change-Id: I5db68da1cc8bc17bc5e7b743282abf83fb100bbc Signed-off-by: Rohit Kumar --- asoc/msm-pcm-routing-v2.c | 8 ++-- dsp/q6afe.c | 80 +++++++++++++++++++++++++++++++++++++++ include/dsp/q6afe-v2.h | 19 ++++++++++ 3 files changed, 103 insertions(+), 4 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 60119264f9b9..3338ac6834a5 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -16533,7 +16533,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUIN_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Port Mixer"}, + {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0 Port Mixer"}, {"QUIN_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"QUIN_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, @@ -16555,7 +16555,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUIN_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Port Mixer"}, + {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1 Port Mixer"}, {"QUIN_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"QUIN_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, @@ -16577,7 +16577,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUIN_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Port Mixer"}, + {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2 Port Mixer"}, {"QUIN_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"QUIN_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, @@ -16599,7 +16599,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUIN_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Port Mixer"}, + {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Port Mixer"}, {"INT0_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"INT0_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 0289144006fe..8e96f6fecbf7 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -495,6 +495,7 @@ int afe_get_port_type(u16 port_id) case AFE_PORT_ID_SECONDARY_PCM_RX: case AFE_PORT_ID_TERTIARY_PCM_RX: case AFE_PORT_ID_QUATERNARY_PCM_RX: + case AFE_PORT_ID_QUINARY_PCM_RX: case AFE_PORT_ID_PRIMARY_TDM_RX: case AFE_PORT_ID_PRIMARY_TDM_RX_1: case AFE_PORT_ID_PRIMARY_TDM_RX_2: @@ -527,6 +528,14 @@ int afe_get_port_type(u16 port_id) case AFE_PORT_ID_QUATERNARY_TDM_RX_5: case AFE_PORT_ID_QUATERNARY_TDM_RX_6: case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + case AFE_PORT_ID_QUINARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_RX_1: + case AFE_PORT_ID_QUINARY_TDM_RX_2: + case AFE_PORT_ID_QUINARY_TDM_RX_3: + case AFE_PORT_ID_QUINARY_TDM_RX_4: + case AFE_PORT_ID_QUINARY_TDM_RX_5: + case AFE_PORT_ID_QUINARY_TDM_RX_6: + case AFE_PORT_ID_QUINARY_TDM_RX_7: case AFE_PORT_ID_USB_RX: case AFE_PORT_ID_INT0_MI2S_RX: case AFE_PORT_ID_INT1_MI2S_RX: @@ -566,6 +575,7 @@ int afe_get_port_type(u16 port_id) case AFE_PORT_ID_SECONDARY_PCM_TX: case AFE_PORT_ID_TERTIARY_PCM_TX: case AFE_PORT_ID_QUATERNARY_PCM_TX: + case AFE_PORT_ID_QUINARY_PCM_TX: case AFE_PORT_ID_PRIMARY_TDM_TX: case AFE_PORT_ID_PRIMARY_TDM_TX_1: case AFE_PORT_ID_PRIMARY_TDM_TX_2: @@ -598,6 +608,14 @@ int afe_get_port_type(u16 port_id) case AFE_PORT_ID_QUATERNARY_TDM_TX_5: case AFE_PORT_ID_QUATERNARY_TDM_TX_6: case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + case AFE_PORT_ID_QUINARY_TDM_TX: + case AFE_PORT_ID_QUINARY_TDM_TX_1: + case AFE_PORT_ID_QUINARY_TDM_TX_2: + case AFE_PORT_ID_QUINARY_TDM_TX_3: + case AFE_PORT_ID_QUINARY_TDM_TX_4: + case AFE_PORT_ID_QUINARY_TDM_TX_5: + case AFE_PORT_ID_QUINARY_TDM_TX_6: + case AFE_PORT_ID_QUINARY_TDM_TX_7: case AFE_PORT_ID_USB_TX: case AFE_PORT_ID_INT0_MI2S_TX: case AFE_PORT_ID_INT1_MI2S_TX: @@ -685,6 +703,8 @@ int afe_sizeof_cfg_cmd(u16 port_id) case AFE_PORT_ID_TERTIARY_PCM_TX: case AFE_PORT_ID_QUATERNARY_PCM_RX: case AFE_PORT_ID_QUATERNARY_PCM_TX: + case AFE_PORT_ID_QUINARY_PCM_RX: + case AFE_PORT_ID_QUINARY_PCM_TX: default: pr_debug("%s: default case 0x%x\n", __func__, port_id); ret_size = SIZEOF_CFG_CMD(afe_param_id_pcm_cfg); @@ -3071,6 +3091,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, case AFE_PORT_ID_TERTIARY_PCM_TX: case AFE_PORT_ID_QUATERNARY_PCM_RX: case AFE_PORT_ID_QUATERNARY_PCM_TX: + case AFE_PORT_ID_QUINARY_PCM_RX: + case AFE_PORT_ID_QUINARY_PCM_TX: cfg_type = AFE_PARAM_ID_PCM_CONFIG; break; case PRIMARY_I2S_RX: @@ -3288,6 +3310,10 @@ int afe_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_QUATERNARY_PCM_RX; case AFE_PORT_ID_QUATERNARY_PCM_TX: return IDX_AFE_PORT_ID_QUATERNARY_PCM_TX; + case AFE_PORT_ID_QUINARY_PCM_RX: + return IDX_AFE_PORT_ID_QUINARY_PCM_RX; + case AFE_PORT_ID_QUINARY_PCM_TX: + return IDX_AFE_PORT_ID_QUINARY_PCM_TX; case SECONDARY_I2S_RX: return IDX_SECONDARY_I2S_RX; case SECONDARY_I2S_TX: return IDX_SECONDARY_I2S_TX; case MI2S_RX: return IDX_MI2S_RX; @@ -3481,6 +3507,38 @@ int afe_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_7; case AFE_PORT_ID_QUATERNARY_TDM_TX_7: return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_7; + case AFE_PORT_ID_QUINARY_TDM_RX: + return IDX_AFE_PORT_ID_QUINARY_TDM_RX_0; + case AFE_PORT_ID_QUINARY_TDM_TX: + return IDX_AFE_PORT_ID_QUINARY_TDM_TX_0; + case AFE_PORT_ID_QUINARY_TDM_RX_1: + return IDX_AFE_PORT_ID_QUINARY_TDM_RX_1; + case AFE_PORT_ID_QUINARY_TDM_TX_1: + return IDX_AFE_PORT_ID_QUINARY_TDM_TX_1; + case AFE_PORT_ID_QUINARY_TDM_RX_2: + return IDX_AFE_PORT_ID_QUINARY_TDM_RX_2; + case AFE_PORT_ID_QUINARY_TDM_TX_2: + return IDX_AFE_PORT_ID_QUINARY_TDM_TX_2; + case AFE_PORT_ID_QUINARY_TDM_RX_3: + return IDX_AFE_PORT_ID_QUINARY_TDM_RX_3; + case AFE_PORT_ID_QUINARY_TDM_TX_3: + return IDX_AFE_PORT_ID_QUINARY_TDM_TX_3; + case AFE_PORT_ID_QUINARY_TDM_RX_4: + return IDX_AFE_PORT_ID_QUINARY_TDM_RX_4; + case AFE_PORT_ID_QUINARY_TDM_TX_4: + return IDX_AFE_PORT_ID_QUINARY_TDM_TX_4; + case AFE_PORT_ID_QUINARY_TDM_RX_5: + return IDX_AFE_PORT_ID_QUINARY_TDM_RX_5; + case AFE_PORT_ID_QUINARY_TDM_TX_5: + return IDX_AFE_PORT_ID_QUINARY_TDM_TX_5; + case AFE_PORT_ID_QUINARY_TDM_RX_6: + return IDX_AFE_PORT_ID_QUINARY_TDM_RX_6; + case AFE_PORT_ID_QUINARY_TDM_TX_6: + return IDX_AFE_PORT_ID_QUINARY_TDM_TX_6; + case AFE_PORT_ID_QUINARY_TDM_RX_7: + return IDX_AFE_PORT_ID_QUINARY_TDM_RX_7; + case AFE_PORT_ID_QUINARY_TDM_TX_7: + return IDX_AFE_PORT_ID_QUINARY_TDM_TX_7; case AFE_PORT_ID_INT0_MI2S_RX: return IDX_AFE_PORT_ID_INT0_MI2S_RX; case AFE_PORT_ID_INT0_MI2S_TX: @@ -3597,6 +3655,8 @@ int afe_open(u16 port_id, case AFE_PORT_ID_TERTIARY_PCM_TX: case AFE_PORT_ID_QUATERNARY_PCM_RX: case AFE_PORT_ID_QUATERNARY_PCM_TX: + case AFE_PORT_ID_QUINARY_PCM_RX: + case AFE_PORT_ID_QUINARY_PCM_TX: cfg_type = AFE_PARAM_ID_PCM_CONFIG; break; case SECONDARY_I2S_RX: @@ -3980,6 +4040,8 @@ int afe_port_group_set_param(u16 group_id, case AFE_GROUP_DEVICE_ID_TERTIARY_TDM_TX: case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_RX: case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_TX: + case AFE_GROUP_DEVICE_ID_QUINARY_TDM_RX: + case AFE_GROUP_DEVICE_ID_QUINARY_TDM_TX: cfg_type = AFE_PARAM_ID_GROUP_DEVICE_TDM_CONFIG; break; default: @@ -5262,6 +5324,8 @@ int afe_validate_port(u16 port_id) case AFE_PORT_ID_TERTIARY_PCM_TX: case AFE_PORT_ID_QUATERNARY_PCM_RX: case AFE_PORT_ID_QUATERNARY_PCM_TX: + case AFE_PORT_ID_QUINARY_PCM_RX: + case AFE_PORT_ID_QUINARY_PCM_TX: case SECONDARY_I2S_RX: case SECONDARY_I2S_TX: case MI2S_RX: @@ -5376,6 +5440,22 @@ int afe_validate_port(u16 port_id) case AFE_PORT_ID_QUATERNARY_TDM_TX_6: case AFE_PORT_ID_QUATERNARY_TDM_RX_7: case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + case AFE_PORT_ID_QUINARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_TX: + case AFE_PORT_ID_QUINARY_TDM_RX_1: + case AFE_PORT_ID_QUINARY_TDM_TX_1: + case AFE_PORT_ID_QUINARY_TDM_RX_2: + case AFE_PORT_ID_QUINARY_TDM_TX_2: + case AFE_PORT_ID_QUINARY_TDM_RX_3: + case AFE_PORT_ID_QUINARY_TDM_TX_3: + case AFE_PORT_ID_QUINARY_TDM_RX_4: + case AFE_PORT_ID_QUINARY_TDM_TX_4: + case AFE_PORT_ID_QUINARY_TDM_RX_5: + case AFE_PORT_ID_QUINARY_TDM_TX_5: + case AFE_PORT_ID_QUINARY_TDM_RX_6: + case AFE_PORT_ID_QUINARY_TDM_TX_6: + case AFE_PORT_ID_QUINARY_TDM_RX_7: + case AFE_PORT_ID_QUINARY_TDM_TX_7: case AFE_PORT_ID_INT0_MI2S_RX: case AFE_PORT_ID_INT1_MI2S_RX: case AFE_PORT_ID_INT2_MI2S_RX: diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 7df993e61c1c..8fb480b3bb6d 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -205,6 +205,25 @@ enum { IDX_AFE_PORT_ID_INT5_MI2S_TX, IDX_AFE_PORT_ID_INT6_MI2S_RX, IDX_AFE_PORT_ID_INT6_MI2S_TX, + /* IDX 143-> 160 */ + IDX_AFE_PORT_ID_QUINARY_PCM_RX, + IDX_AFE_PORT_ID_QUINARY_PCM_TX, + IDX_AFE_PORT_ID_QUINARY_TDM_RX_0, + IDX_AFE_PORT_ID_QUINARY_TDM_TX_0, + IDX_AFE_PORT_ID_QUINARY_TDM_RX_1, + IDX_AFE_PORT_ID_QUINARY_TDM_TX_1, + IDX_AFE_PORT_ID_QUINARY_TDM_RX_2, + IDX_AFE_PORT_ID_QUINARY_TDM_TX_2, + IDX_AFE_PORT_ID_QUINARY_TDM_RX_3, + IDX_AFE_PORT_ID_QUINARY_TDM_TX_3, + IDX_AFE_PORT_ID_QUINARY_TDM_RX_4, + IDX_AFE_PORT_ID_QUINARY_TDM_TX_4, + IDX_AFE_PORT_ID_QUINARY_TDM_RX_5, + IDX_AFE_PORT_ID_QUINARY_TDM_TX_5, + IDX_AFE_PORT_ID_QUINARY_TDM_RX_6, + IDX_AFE_PORT_ID_QUINARY_TDM_TX_6, + IDX_AFE_PORT_ID_QUINARY_TDM_RX_7, + IDX_AFE_PORT_ID_QUINARY_TDM_TX_7, AFE_MAX_PORTS }; -- GitLab From 7fccd584b649ce06d528d7d374698f5813a26c41 Mon Sep 17 00:00:00 2001 From: Rohit Kumar Date: Tue, 10 Oct 2017 19:32:44 +0530 Subject: [PATCH 0057/1645] soc: pinctrl-lpi: update sizeof lpi offset to 32bit Update sizeof lpi register offset to 32 bit to accommodate all register offset for sdm670. Change-Id: I9a3fdb56f9faf6c0aff627cbedaa54db606d2434 Signed-off-by: Rohit Kumar --- soc/pinctrl-lpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index 1e7ead817399..0fa7b60d068f 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -81,7 +81,7 @@ enum lpi_gpio_func_index { * @function: See lpi_gpio_functions[] */ struct lpi_gpio_pad { - u16 offset; + u32 offset; bool output_enabled; bool value; char __iomem *base; -- GitLab From 2e3e0f21804b74d85b97e77175b4172af767e790 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 11 Oct 2017 19:57:35 +0530 Subject: [PATCH 0058/1645] ASoC: codecs: sdm660_cdc: Fix pop noise issue at DMIC Pop noise occurs during switch from handset to speaker mode during voice call. This is because sufficient delay is not provided for tx to unmute. A delayed workqueue that will do unmute at the end solves the issue. CRs-Fixed: 2101423 Change-Id: I1ae7068b23158bb8428d5b96e9f65fb05a67ff7e Signed-off-by: Vatsal Bucha --- asoc/codecs/sdm660_cdc/msm-digital-cdc.c | 106 +++++++++-------------- asoc/codecs/sdm660_cdc/msm-digital-cdc.h | 7 ++ 2 files changed, 50 insertions(+), 63 deletions(-) diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c index 3df917f717b5..e7c7147c0f7b 100644 --- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -55,6 +55,11 @@ static unsigned long tx_digital_gain_reg[] = { MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN, }; +#define SDM660_TX_UNMUTE_DELAY_MS 40 +static int tx_unmute_delay = SDM660_TX_UNMUTE_DELAY_MS; +module_param(tx_unmute_delay, int, 0664); +MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path"); + static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); struct snd_soc_codec *registered_digcodec; @@ -924,6 +929,9 @@ static int msm_dig_cdc_codec_enable_dec(struct snd_soc_dapm_widget *w, /* enable HPF */ snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x00); + schedule_delayed_work( + &msm_dig_cdc->tx_mute_dwork[decimator - 1].dwork, + msecs_to_jiffies(tx_unmute_delay)); if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq != CF_MIN_3DB_150HZ) { @@ -937,20 +945,14 @@ static int msm_dig_cdc_codec_enable_dec(struct snd_soc_dapm_widget *w, snd_soc_read(codec, tx_digital_gain_reg[w->shift + offset]) ); - if (pdata->lb_mode) { - pr_debug("%s: loopback mode unmute the DEC\n", - __func__); - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00); - } - snd_soc_update_bits(codec, tx_vol_ctl_reg, - 0x01, 0x00); - break; case SND_SOC_DAPM_PRE_PMD: snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01); msleep(20); snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08); cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork); + cancel_delayed_work_sync( + &msm_dig_cdc->tx_mute_dwork[decimator - 1].dwork); break; case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, @@ -1191,6 +1193,35 @@ int msm_dig_codec_info_create_codec_entry(struct snd_info_entry *codec_root, } EXPORT_SYMBOL(msm_dig_codec_info_create_codec_entry); +static void sdm660_tx_mute_update_callback(struct work_struct *work) +{ + struct tx_mute_work *tx_mute_dwork; + struct snd_soc_codec *codec = NULL; + struct msm_dig_priv *dig_cdc; + struct delayed_work *delayed_work; + u16 tx_vol_ctl_reg = 0; + u8 decimator = 0, i; + + delayed_work = to_delayed_work(work); + tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); + dig_cdc = tx_mute_dwork->dig_cdc; + codec = dig_cdc->codec; + + for (i = 0; i < (NUM_DECIMATORS - 1); i++) { + if (dig_cdc->dec_active[i]) + decimator = i + 1; + if (decimator && decimator < NUM_DECIMATORS) { + /* unmute decimators corresponding to Tx DAI's*/ + tx_vol_ctl_reg = + MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG + + 32 * (decimator - 1); + snd_soc_update_bits(codec, tx_vol_ctl_reg, + 0x01, 0x00); + } + decimator = 0; + } +} + static int msm_dig_cdc_soc_probe(struct snd_soc_codec *codec) { struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev); @@ -1207,6 +1238,10 @@ static int msm_dig_cdc_soc_probe(struct snd_soc_codec *codec) tx_hpf_work[i].decimator = i + 1; INIT_DELAYED_WORK(&tx_hpf_work[i].dwork, tx_hpf_corner_freq_callback); + msm_dig_cdc->tx_mute_dwork[i].dig_cdc = msm_dig_cdc; + msm_dig_cdc->tx_mute_dwork[i].decimator = i + 1; + INIT_DELAYED_WORK(&msm_dig_cdc->tx_mute_dwork[i].dwork, + sdm660_tx_mute_update_callback); } for (i = 0; i < MSM89XX_RX_MAX; i++) @@ -1891,63 +1926,8 @@ static const struct snd_kcontrol_new msm_dig_snd_controls[] = { MSM89XX_CDC_CORE_TX5_MUX_CTL, 3, 1, 0), }; -static int msm_dig_cdc_digital_mute(struct snd_soc_dai *dai, int mute) -{ - struct snd_soc_codec *codec = NULL; - u16 tx_vol_ctl_reg = 0; - u8 decimator = 0, i; - struct msm_dig_priv *dig_cdc; - - pr_debug("%s: Digital Mute val = %d\n", __func__, mute); - - if (!dai || !dai->codec) { - pr_err("%s: Invalid params\n", __func__); - return -EINVAL; - } - codec = dai->codec; - dig_cdc = snd_soc_codec_get_drvdata(codec); - - if (dai->id == AIF1_PB) { - dev_dbg(codec->dev, "%s: Not capture use case skip\n", - __func__); - return 0; - } - - mute = (mute) ? 1 : 0; - if (!mute) { - /* - * 15 ms is an emperical value for the mute time - * that was arrived by checking the pop level - * to be inaudible - */ - usleep_range(15000, 15010); - } - - if (dai->id == AIF3_SVA) { - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG, 0x01, mute); - goto ret; - } - for (i = 0; i < (NUM_DECIMATORS - 1); i++) { - if (dig_cdc->dec_active[i]) - decimator = i + 1; - if (decimator && decimator < NUM_DECIMATORS) { - /* mute/unmute decimators corresponding to Tx DAI's */ - tx_vol_ctl_reg = - MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG + - 32 * (decimator - 1); - snd_soc_update_bits(codec, tx_vol_ctl_reg, - 0x01, mute); - } - decimator = 0; - } -ret: - return 0; -} - static struct snd_soc_dai_ops msm_dig_dai_ops = { .hw_params = msm_dig_cdc_hw_params, - .digital_mute = msm_dig_cdc_digital_mute, }; diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.h b/asoc/codecs/sdm660_cdc/msm-digital-cdc.h index f0e7a9cf9228..42c31d5089b2 100644 --- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.h +++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.h @@ -32,6 +32,12 @@ enum { MSM89XX_RX_MAX, }; +struct tx_mute_work { + struct msm_dig_priv *dig_cdc; + u32 decimator; + struct delayed_work dwork; +}; + struct msm_dig_priv { struct snd_soc_codec *codec; u32 comp_enabled[MSM89XX_RX_MAX]; @@ -54,6 +60,7 @@ struct msm_dig_priv { int (*register_notifier)(void *handle, struct notifier_block *nblock, bool enable); + struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS]; }; struct dig_ctrl_platform_data { -- GitLab From 899b78bd181688a8f5557a456cd34f657b3f0f8c Mon Sep 17 00:00:00 2001 From: Preetam Singh Ranawat Date: Thu, 7 Sep 2017 12:36:06 -0700 Subject: [PATCH 0059/1645] dsp: add support for aptX dual mono Send sync mode parameter to DSP for supporting aptX dual mono. Change-Id: I1c43b0dec6661a77644e28df45ca6c1a182745de Signed-off-by: Aniket Kumar Lata --- asoc/msm-dai-q6-v2.c | 8 ++++++++ dsp/q6afe.c | 18 ++++++++++++++++++ include/dsp/apr_audio-v2.h | 27 +++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 2802a4fa170a..53622e085465 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -2249,6 +2249,10 @@ static int msm_dai_q6_afe_enc_cfg_get(struct snd_kcontrol *kcontrol, sizeof(struct asm_aac_enc_cfg_v2_t)); break; case ENC_FMT_APTX: + memcpy(ucontrol->value.bytes.data + format_size, + &dai_data->enc_config.data, + sizeof(struct asm_aptx_enc_cfg_t)); + break; case ENC_FMT_APTX_HD: memcpy(ucontrol->value.bytes.data + format_size, &dai_data->enc_config.data, @@ -2298,6 +2302,10 @@ static int msm_dai_q6_afe_enc_cfg_put(struct snd_kcontrol *kcontrol, sizeof(struct asm_aac_enc_cfg_v2_t)); break; case ENC_FMT_APTX: + memcpy(&dai_data->enc_config.data, + ucontrol->value.bytes.data + format_size, + sizeof(struct asm_aptx_enc_cfg_t)); + break; case ENC_FMT_APTX_HD: memcpy(&dai_data->enc_config.data, ucontrol->value.bytes.data + format_size, diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 8e96f6fecbf7..2bdfd10fdc32 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2895,6 +2895,24 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } + if (format == ASM_MEDIA_FMT_APTX) { + config.param.payload_size = + payload_size + sizeof(config.port.sync_mode_param); + pr_debug("%s: sending AFE_PARAM_ID_APTX_SYNC_MODE to DSP", + __func__); + config.pdata.param_id = AFE_PARAM_ID_APTX_SYNC_MODE; + config.pdata.param_size = sizeof(config.port.sync_mode_param); + config.port.sync_mode_param.sync_mode = + config.port.enc_blk_param.enc_blk_config.aptx_config. + aptx_v2_cfg.sync_mode; + ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE_PARAM_ID_APTX_SYNC_MODE for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + } + config.param.payload_size = payload_size + sizeof(config.port.enc_pkt_id_param); pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP payload = %d", diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index df635ccad1cd..be56d74eef43 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -3074,6 +3074,16 @@ struct afe_param_id_set_topology_cfg { u32 topology_id; } __packed; +#define AFE_PARAM_ID_APTX_SYNC_MODE 0x00013205 + +struct afe_param_id_aptx_sync_mode { + /* + * sync mode: 0x0 = stereo sync mode (default) + * 0x01 = dual mono sync mode + * 0x02 = dual mono with no sync on either L or R + */ + uint32_t sync_mode; +} __packed; /* * Generic encoder module ID. @@ -3305,6 +3315,21 @@ struct asm_custom_enc_cfg_t { uint8_t channel_mapping[8]; uint32_t custom_size; } __packed; + +struct asm_aptx_v2_enc_cfg_ext_t { + /* + * sync mode: 0x0 = stereo sync mode (default) + * 0x01 = dual mono sync mode + * 0x02 = dual mono with no sync on either L or R + */ + uint32_t sync_mode; +} __packed; + +struct asm_aptx_enc_cfg_t { + struct asm_custom_enc_cfg_t custom_cfg; + struct asm_aptx_v2_enc_cfg_ext_t aptx_v2_cfg; +} __packed; + #define ASM_MEDIA_FMT_CELT 0x00013221 struct asm_celt_specific_enc_cfg_t { /* @@ -3421,6 +3446,7 @@ union afe_enc_config_data { struct asm_aac_enc_cfg_v2_t aac_config; struct asm_custom_enc_cfg_t custom_config; struct asm_celt_enc_cfg_t celt_config; + struct asm_aptx_enc_cfg_t aptx_config; }; struct afe_enc_config { @@ -3461,6 +3487,7 @@ union afe_port_config { struct afe_param_id_set_topology_cfg topology; struct afe_param_id_tdm_cfg tdm; struct afe_param_id_usb_audio_cfg usb_audio; + struct afe_param_id_aptx_sync_mode sync_mode_param; struct afe_enc_fmt_id_param_t enc_fmt; struct afe_port_media_type_t media_type; struct afe_enc_cfg_blk_param_t enc_blk_param; -- GitLab From 8e4368d3dddd841149cf845dde957e4acce9a73d Mon Sep 17 00:00:00 2001 From: Ben Romberger Date: Fri, 18 Aug 2017 15:54:18 -0700 Subject: [PATCH 0060/1645] ASoC: msm: qdsp6v2: Add S24_3LE support to DP driver Add support for HDMI and DP for S24_3LE bit format. This allows playback of 24bit audio on the external device. Change-Id: Ia6e1148b2e5d13cc0ff6f2372d61c83c3e704255 Signed-off-by: Ben Romberger --- asoc/codecs/msm_hdmi_codec_rx.c | 3 ++- asoc/msm-dai-q6-hdmi-v2.c | 8 ++++++-- asoc/sdm845.c | 10 ++++++++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/msm_hdmi_codec_rx.c b/asoc/codecs/msm_hdmi_codec_rx.c index 46cfe7dede26..3a48f530d1ef 100644 --- a/asoc/codecs/msm_hdmi_codec_rx.c +++ b/asoc/codecs/msm_hdmi_codec_rx.c @@ -489,7 +489,8 @@ static struct snd_soc_dai_driver msm_ext_disp_audio_codec_rx_dais[] = { .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE, + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, }, .ops = &msm_ext_disp_audio_codec_rx_dai_ops, }, diff --git a/asoc/msm-dai-q6-hdmi-v2.c b/asoc/msm-dai-q6-hdmi-v2.c index 9c8d20a9f2a7..212c4e3274fb 100644 --- a/asoc/msm-dai-q6-hdmi-v2.c +++ b/asoc/msm-dai-q6-hdmi-v2.c @@ -217,6 +217,7 @@ static int msm_dai_q6_hdmi_hw_params(struct snd_pcm_substream *substream, dai_data->port_config.hdmi_multi_ch.bit_width = 16; break; case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: dai_data->port_config.hdmi_multi_ch.bit_width = 24; break; } @@ -435,7 +436,9 @@ static struct snd_soc_dai_driver msm_dai_q6_hdmi_hdmi_rx_dai = { SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, .channels_min = 2, .channels_max = 8, .rate_max = 192000, @@ -457,7 +460,8 @@ static struct snd_soc_dai_driver msm_dai_q6_display_port_rx_dai[] = { SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE, + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, .channels_min = 2, .channels_max = 8, .rate_max = 192000, diff --git a/asoc/sdm845.c b/asoc/sdm845.c index 5721c323e0b5..0506636e8367 100644 --- a/asoc/sdm845.c +++ b/asoc/sdm845.c @@ -408,7 +408,8 @@ static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four", static const char *const vi_feed_ch_text[] = {"One", "Two"}; static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", "S32_LE"}; -static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE"}; +static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE", + "S24_3LE"}; static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", "KHZ_44P1", "KHZ_48", "KHZ_88P2", "KHZ_96", "KHZ_176P4", @@ -1420,10 +1421,12 @@ static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol, return idx; switch (ext_disp_rx_cfg[idx].bit_format) { + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; case SNDRV_PCM_FORMAT_S24_LE: ucontrol->value.integer.value[0] = 1; break; - case SNDRV_PCM_FORMAT_S16_LE: default: ucontrol->value.integer.value[0] = 0; @@ -1445,6 +1448,9 @@ static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol, return idx; switch (ucontrol->value.integer.value[0]) { + case 2: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; case 1: ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; break; -- GitLab From 88513a31e56deee44b87338eeb0a2446869675d4 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 12 Oct 2017 12:29:25 +0530 Subject: [PATCH 0061/1645] dsp: add support to set topology specific info in voice usecases Add support to set number of channels and channel mapping to DSP as per the info received from ACDB files along with topology for a device in voice usecases instead of reading from backend configuration. When topology specific channel info is not supported, send the default no of channels and channel mapping as per backend to support backward compatibility. CRs-Fixed: 2110934 Change-Id: Iad512474fc25c906d97513f6648cd8ba6244eda1 Signed-off-by: Aditya Bavanari --- dsp/q6voice.c | 133 +++++++++++++++++---- include/dsp/q6voice.h | 2 + include/uapi/linux/msm_audio_calibration.h | 8 ++ 3 files changed, 118 insertions(+), 25 deletions(-) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index fa910caf9296..983e0a2388ca 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -2368,6 +2368,9 @@ static int voice_send_set_device_cmd(struct voice_data *v) &cvp_setdev_cmd.cvp_set_device_v2.tx_topology_id, &cvp_setdev_cmd.cvp_set_device_v2.rx_topology_id); + voice_set_topology_specific_info(v, CVP_VOC_RX_TOPOLOGY_CAL); + voice_set_topology_specific_info(v, CVP_VOC_TX_TOPOLOGY_CAL); + cvp_setdev_cmd.cvp_set_device_v2.tx_port_id = v->dev_tx.port_id; cvp_setdev_cmd.cvp_set_device_v2.rx_port_id = v->dev_rx.port_id; @@ -2722,6 +2725,9 @@ static int voice_send_cvp_create_cmd(struct voice_data *v) &cvp_session_cmd.cvp_session.tx_topology_id, &cvp_session_cmd.cvp_session.rx_topology_id); + voice_set_topology_specific_info(v, CVP_VOC_RX_TOPOLOGY_CAL); + voice_set_topology_specific_info(v, CVP_VOC_TX_TOPOLOGY_CAL); + cvp_session_cmd.cvp_session.direction = 2; /*tx and rx*/ cvp_session_cmd.cvp_session.tx_port_id = v->dev_tx.port_id; cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.port_id; @@ -3864,6 +3870,9 @@ static int voice_send_cvp_channel_info_v2(struct voice_data *v, VSS_PARAM_VOCPROC_RX_CHANNEL_INFO; channel_info->num_channels = v->dev_rx.no_of_channels; channel_info->bits_per_sample = v->dev_rx.bits_per_sample; + memcpy(&channel_info->channel_mapping, + v->dev_rx.channel_mapping, + VSS_NUM_CHANNELS_MAX * sizeof(uint8_t)); break; case TX_PATH: @@ -3871,6 +3880,9 @@ static int voice_send_cvp_channel_info_v2(struct voice_data *v, VSS_PARAM_VOCPROC_TX_CHANNEL_INFO; channel_info->num_channels = v->dev_tx.no_of_channels; channel_info->bits_per_sample = v->dev_tx.bits_per_sample; + memcpy(&channel_info->channel_mapping, + v->dev_tx.channel_mapping, + VSS_NUM_CHANNELS_MAX * sizeof(uint8_t)); break; case EC_REF_PATH: @@ -3878,6 +3890,9 @@ static int voice_send_cvp_channel_info_v2(struct voice_data *v, VSS_PARAM_VOCPROC_EC_REF_CHANNEL_INFO; channel_info->num_channels = v->dev_rx.no_of_channels; channel_info->bits_per_sample = v->dev_rx.bits_per_sample; + memcpy(&channel_info->channel_mapping, + v->dev_rx.channel_mapping, + VSS_NUM_CHANNELS_MAX * sizeof(uint8_t)); break; default: pr_err("%s: Invalid param type\n", @@ -3886,21 +3901,6 @@ static int voice_send_cvp_channel_info_v2(struct voice_data *v, goto done; } - if (channel_info->num_channels == NUM_CHANNELS_MONO) { - channel_info->channel_mapping[0] = PCM_CHANNEL_FC; - } else if (channel_info->num_channels == NUM_CHANNELS_STEREO) { - channel_info->channel_mapping[0] = PCM_CHANNEL_FL; - channel_info->channel_mapping[1] = PCM_CHANNEL_FR; - } else if (channel_info->num_channels == NUM_CHANNELS_QUAD && - param_type == TX_PATH) { - channel_info->channel_mapping[0] = PCM_CHANNEL_FL; - channel_info->channel_mapping[1] = PCM_CHANNEL_FR; - channel_info->channel_mapping[2] = PCM_CHANNEL_LS; - channel_info->channel_mapping[3] = PCM_CHANNEL_RS; - } else { - pr_warn("%s: Unsupported num channels: %d for path: %d\n", - __func__, channel_info->num_channels, param_type); - } v->cvp_state = CMD_STATUS_FAIL; v->async_err = 0; @@ -4110,16 +4110,9 @@ static int voice_send_cvp_mfc_config_v2(struct voice_data *v) mfc_config_info->num_channels = v->dev_rx.no_of_channels; mfc_config_info->bits_per_sample = 16; mfc_config_info->sample_rate = v->dev_rx.sample_rate; - - if (mfc_config_info->num_channels == NUM_CHANNELS_MONO) { - mfc_config_info->channel_type[0] = PCM_CHANNEL_FC; - } else if (mfc_config_info->num_channels == NUM_CHANNELS_STEREO) { - mfc_config_info->channel_type[0] = PCM_CHANNEL_FL; - mfc_config_info->channel_type[1] = PCM_CHANNEL_FR; - } else { - pr_warn("%s: Unsupported num channels: %d\n", - __func__, mfc_config_info->num_channels); - } + memcpy(&mfc_config_info->channel_type, + v->dev_rx.channel_mapping, + VSS_NUM_CHANNELS_MAX * sizeof(uint8_t)); v->cvp_state = CMD_STATUS_FAIL; v->async_err = 0; @@ -8183,6 +8176,96 @@ uint32_t voice_get_topology(uint32_t topology_idx) return topology; } +int voice_set_topology_specific_info(struct voice_data *v, + uint32_t topology_idx) +{ + struct cal_block_data *cal_block = NULL; + int ret = 0; + uint32_t topo_channels; + + if (common.cal_data[topology_idx] == NULL) { + pr_err("%s: cal type is NULL for cal index %x\n", + __func__, topology_idx); + ret = -EINVAL; + goto done; + } + + mutex_lock(&common.cal_data[topology_idx]->lock); + cal_block = cal_utils_get_only_cal_block( + common.cal_data[topology_idx]); + if (cal_block == NULL) { + pr_debug("%s: cal_block not found for cal index %x\n", + __func__, topology_idx); + ret = -EINVAL; + goto unlock; + } + + if (topology_idx == CVP_VOC_RX_TOPOLOGY_CAL) { + topo_channels = ((struct audio_cal_info_voc_top *) + cal_block->cal_info)->num_channels; + if (topo_channels > 0) { + v->dev_rx.no_of_channels = topo_channels; + pr_debug("%s: Topology Rx no of channels: %d", + __func__, v->dev_rx.no_of_channels); + memcpy(&v->dev_rx.channel_mapping, + &((struct audio_cal_info_voc_top *) + cal_block->cal_info)->channel_mapping, + VSS_CHANNEL_MAPPING_SIZE); + } else { + pr_debug("%s: cal data is zero, default to Rx backend config\n", + __func__); + if (v->dev_rx.no_of_channels == NUM_CHANNELS_MONO) { + v->dev_rx.channel_mapping[0] = PCM_CHANNEL_FC; + } else if (v->dev_rx.no_of_channels == + NUM_CHANNELS_STEREO) { + v->dev_rx.channel_mapping[0] = PCM_CHANNEL_FL; + v->dev_rx.channel_mapping[1] = PCM_CHANNEL_FR; + } else { + pr_warn("%s: Unsupported Rx num channels: %d\n", + __func__, v->dev_rx.no_of_channels); + } + } + } else if (topology_idx == CVP_VOC_TX_TOPOLOGY_CAL) { + topo_channels = ((struct audio_cal_info_voc_top *) + cal_block->cal_info)->num_channels; + if (topo_channels > 0) { + v->dev_tx.no_of_channels = topo_channels; + pr_debug("%s: Topology Tx no of channels: %d", + __func__, v->dev_tx.no_of_channels); + memcpy(&v->dev_tx.channel_mapping, + &((struct audio_cal_info_voc_top *) + cal_block->cal_info)->channel_mapping, + VSS_CHANNEL_MAPPING_SIZE); + } else { + pr_debug("%s: cal data is zero, default to Tx backend config\n", + __func__); + if (v->dev_tx.no_of_channels == NUM_CHANNELS_MONO) { + v->dev_tx.channel_mapping[0] = PCM_CHANNEL_FC; + } else if (v->dev_tx.no_of_channels == + NUM_CHANNELS_STEREO) { + v->dev_tx.channel_mapping[0] = PCM_CHANNEL_FL; + v->dev_tx.channel_mapping[1] = PCM_CHANNEL_FR; + } else if (v->dev_tx.no_of_channels == + NUM_CHANNELS_QUAD) { + v->dev_tx.channel_mapping[0] = PCM_CHANNEL_FL; + v->dev_tx.channel_mapping[1] = PCM_CHANNEL_FR; + v->dev_tx.channel_mapping[2] = PCM_CHANNEL_LS; + v->dev_tx.channel_mapping[3] = PCM_CHANNEL_RS; + } else { + pr_warn("%s: Unsupported Tx num channels: %d\n", + __func__, v->dev_tx.no_of_channels); + } + } + } else { + pr_err("%s: topology index %x is invalid\n", + __func__, topology_idx); + } +unlock: + mutex_unlock(&common.cal_data[topology_idx]->lock); +done: + return ret; +} + static int get_cal_type_index(int32_t cal_type) { int ret = -EINVAL; diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index af7995a01cd9..a41a2db8f868 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -2063,6 +2063,8 @@ int voc_disable_topology(uint32_t session_id, uint32_t disable); int voc_set_device_config(uint32_t session_id, uint8_t path_dir, struct media_format_info *finfo); uint32_t voice_get_topology(uint32_t topology_idx); +int voice_set_topology_specific_info(struct voice_data *v, + uint32_t topology_idx); int voc_set_sound_focus(struct sound_focus_param sound_focus_param); int voc_get_sound_focus(struct sound_focus_param *soundFocusData); int voc_get_source_tracking(struct source_tracking_param *sourceTrackingData); diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h index 5a0b8603070d..1696ae5e9118 100644 --- a/include/uapi/linux/msm_audio_calibration.h +++ b/include/uapi/linux/msm_audio_calibration.h @@ -107,6 +107,8 @@ enum { #define AFE_SIDETONE_IIR_CAL_TYPE AFE_SIDETONE_IIR_CAL_TYPE +#define TOPOLOGY_SPECIFIC_CHANNEL_INFO + enum { VERSION_0_0, }; @@ -376,9 +378,15 @@ struct audio_cal_info_lsm { int32_t app_type; }; +#define VSS_NUM_CHANNELS_MAX 8 + struct audio_cal_info_voc_top { int32_t topology; int32_t acdb_id; +#ifdef TOPOLOGY_SPECIFIC_CHANNEL_INFO + uint32_t num_channels; + uint8_t channel_mapping[VSS_NUM_CHANNELS_MAX]; +#endif }; struct audio_cal_info_vocproc { -- GitLab From fb90eb6176ec661b489b75859b439bafe8644b04 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Tue, 10 Oct 2017 12:26:08 -0700 Subject: [PATCH 0062/1645] dsp: fix reset logic during ADSP SSR for lsm During ADSP SSR, unless all APR clients are de-registered, Glink channel will not be closed, which will cause Glink channel to remain in stale/unusable state after ADSP SSR. Fix this by adding APR reset logic in LSM driver. Change-Id: Idec26836cfa4ecbacc557996339facd84ac19668 Signed-off-by: Xiaoyu Ye --- dsp/q6lsm.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index adc541ae0f37..848f2cd93868 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -148,6 +148,10 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) __func__, data->opcode, data->reset_event, data->reset_proc); + apr_reset(client->apr); + client->apr = NULL; + atomic_set(&client->cmd_state, CMD_STATE_CLEARED); + wake_up(&client->cmd_wait); cal_utils_clear_cal_block_q6maps(LSM_MAX_CAL_IDX, lsm_common.cal_data); mutex_lock(&lsm_common.cal_data[LSM_CUSTOM_TOP_IDX]->lock); @@ -368,6 +372,11 @@ static int q6lsm_apr_send_pkt(struct lsm_client *client, void *handle, unsigned long flags = 0; struct apr_hdr *msg_hdr = (struct apr_hdr *) data; + if (!handle) { + pr_err("%s: handle is NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: enter wait %d\n", __func__, wait); if (wait) mutex_lock(&lsm_common.apr_lock); @@ -1341,6 +1350,10 @@ static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv) pr_debug("%s: SSR event received 0x%x, event 0x%x,\n" "proc 0x%x SID 0x%x\n", __func__, data->opcode, data->reset_event, data->reset_proc, sid); + + apr_reset(lsm_common.apr); + lsm_common.apr = NULL; + atomic_set(&lsm_common.apr_users, 0); lsm_common.common_client[sid].lsm_cal_phy_addr = 0; cal_utils_clear_cal_block_q6maps(LSM_MAX_CAL_IDX, lsm_common.cal_data); -- GitLab From 091ff790319eff74b8cf64b8ec94d263a6f24fd1 Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Wed, 11 Oct 2017 18:35:07 +0530 Subject: [PATCH 0063/1645] asoc: sdm660: update cpu_dai_name for quin_tdm Update cpu_dai_name of quin_tdm from tdm group id to port id for sdm670 internal and external codec machine driver to fix soundcard registration issue. Change-Id: I2f7ed4ea983c1d457c4d2940c33f5bb7440ddee6 Signed-off-by: Rohit kumar --- asoc/sdm660-ext-dai-links.c | 4 ++-- asoc/sdm660-internal.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/asoc/sdm660-ext-dai-links.c b/asoc/sdm660-ext-dai-links.c index 4777a5ff3ee1..a33113550f4c 100644 --- a/asoc/sdm660-ext-dai-links.c +++ b/asoc/sdm660-ext-dai-links.c @@ -1573,7 +1573,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { { .name = LPASS_BE_QUIN_TDM_RX_0, .stream_name = "Quinary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.37184", + .cpu_dai_name = "msm-dai-q6-tdm.36928", .platform_name = "msm-pcm-routing", .codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-rx", @@ -1587,7 +1587,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { { .name = LPASS_BE_QUIN_TDM_TX_0, .stream_name = "Quinary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.37185", + .cpu_dai_name = "msm-dai-q6-tdm.36929", .platform_name = "msm-pcm-routing", .codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-tx", diff --git a/asoc/sdm660-internal.c b/asoc/sdm660-internal.c index 713da55cb0a9..a1536fefe635 100644 --- a/asoc/sdm660-internal.c +++ b/asoc/sdm660-internal.c @@ -2612,7 +2612,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { { .name = LPASS_BE_QUIN_TDM_RX_0, .stream_name = "Quinary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.37184", + .cpu_dai_name = "msm-dai-q6-tdm.36928", .platform_name = "msm-pcm-routing", .codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-rx", @@ -2626,7 +2626,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { { .name = LPASS_BE_QUIN_TDM_TX_0, .stream_name = "Quinary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.37185", + .cpu_dai_name = "msm-dai-q6-tdm.36929", .platform_name = "msm-pcm-routing", .codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-tx", -- GitLab From 5e7ef9c9228aa09223f0189b5a80f373149da0ef Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Mon, 16 Oct 2017 19:40:38 -0700 Subject: [PATCH 0064/1645] ASoC: add support to configure clock frequency for all TDM interfaces Enable all five TDM interfaces to configure clock frequency during the runtime. Change-Id: I066ea2034509dee2350205ee887dd3eeb6f5389b Signed-off-by: Xiaoyu Ye --- asoc/msm-dai-q6-v2.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 2802a4fa170a..dd7aebc4f844 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -6535,26 +6535,12 @@ static int msm_dai_q6_tdm_set_sysclk(struct snd_soc_dai *dai, struct msm_dai_q6_tdm_dai_data *dai_data = dev_get_drvdata(dai->dev); - switch (dai->id) { - case AFE_PORT_ID_QUATERNARY_TDM_RX: - case AFE_PORT_ID_QUATERNARY_TDM_RX_1: - case AFE_PORT_ID_QUATERNARY_TDM_RX_2: - case AFE_PORT_ID_QUATERNARY_TDM_RX_3: - case AFE_PORT_ID_QUATERNARY_TDM_RX_4: - case AFE_PORT_ID_QUATERNARY_TDM_RX_5: - case AFE_PORT_ID_QUATERNARY_TDM_RX_6: - case AFE_PORT_ID_QUATERNARY_TDM_RX_7: - case AFE_PORT_ID_QUATERNARY_TDM_TX: - case AFE_PORT_ID_QUATERNARY_TDM_TX_1: - case AFE_PORT_ID_QUATERNARY_TDM_TX_2: - case AFE_PORT_ID_QUATERNARY_TDM_TX_3: - case AFE_PORT_ID_QUATERNARY_TDM_TX_4: - case AFE_PORT_ID_QUATERNARY_TDM_TX_5: - case AFE_PORT_ID_QUATERNARY_TDM_TX_6: - case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + if ((dai->id >= AFE_PORT_ID_PRIMARY_TDM_RX) && + (dai->id <= AFE_PORT_ID_QUINARY_TDM_TX_7)) { dai_data->clk_set.clk_freq_in_hz = freq; - break; - default: + } else { + dev_err(dai->dev, "%s: invalid dai id 0x%x\n", + __func__, dai->id); return -EINVAL; } -- GitLab From f74efd8eb1c494d3fa00e6a529357c3fb8099206 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 27 Sep 2017 11:24:55 +0800 Subject: [PATCH 0065/1645] audio-lnx: Add support to build sdm670 machine driver as module When CONFIG_SND_SOC_EXT_CODEC/CONFIG_SND_SOC_INT_CODEC is set to m not y, "ifdef CONFIG_SND_SOC_EXT_CODEC/CONFIG_SND_SOC_INT_CODEC" would be false which would cause init functions as dummy functions. Change to "if IS_ENABLED" and When CONFIG_SND_SOC_EXT_CODEC/ CONFIG_SND_SOC_INT_CODEC is set to y/m, both would set the condition to true. Change Makefile to compile machine driver for internal/external codec as one module. Change-Id: Ib72f95a24e8a4e657a1e9efc655f92a397b44d32 Signed-off-by: Meng Wang --- asoc/Makefile | 16 +++------------- asoc/sdm660-external.h | 2 +- asoc/sdm660-internal.h | 4 ++-- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/asoc/Makefile b/asoc/Makefile index cc28148dcf3e..4d3839de9556 100644 --- a/asoc/Makefile +++ b/asoc/Makefile @@ -15,19 +15,9 @@ obj-$(CONFIG_SND_SOC_CPE) += snd-soc-cpe.o snd-soc-msm8998-objs := msm8998.o obj-$(CONFIG_SND_SOC_MACHINE_MSM8998) += snd-soc-msm8998.o -# for SDM660 sound card driver -snd-soc-sdm660-common-objs := sdm660-common.o -obj-$(CONFIG_SND_SOC_SDM670) += snd-soc-sdm660-common.o - -# for SDM660 sound card driver -snd-soc-int-codec-objs := sdm660-internal.o -obj-$(CONFIG_SND_SOC_INT_CODEC) += snd-soc-sdm660-common.o -obj-$(CONFIG_SND_SOC_INT_CODEC) += snd-soc-int-codec.o - -# for SDM660 sound card driver -snd-soc-ext-codec-objs := sdm660-external.o sdm660-ext-dai-links.o -obj-$(CONFIG_SND_SOC_EXT_CODEC) += snd-soc-sdm660-common.o -obj-$(CONFIG_SND_SOC_EXT_CODEC) += snd-soc-ext-codec.o +# for SDM670 sound card driver +snd-soc-sdm670-objs := sdm660-common.o sdm660-internal.o sdm660-external.o sdm660-ext-dai-links.o +obj-$(CONFIG_SND_SOC_SDM670) += snd-soc-sdm670.o # for SDM845 sound card driver snd-soc-sdm845-objs := sdm845.o diff --git a/asoc/sdm660-external.h b/asoc/sdm660-external.h index 0648c014b6d2..b81e158be5f7 100644 --- a/asoc/sdm660-external.h +++ b/asoc/sdm660-external.h @@ -32,7 +32,7 @@ int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params); int msm_snd_card_tavil_late_probe(struct snd_soc_card *card); int msm_snd_card_tasha_late_probe(struct snd_soc_card *card); -#ifdef CONFIG_SND_SOC_EXT_CODEC +#if IS_ENABLED(CONFIG_SND_SOC_EXT_CODEC) int msm_ext_cdc_init(struct platform_device *, struct msm_asoc_mach_data *, struct snd_soc_card **, struct wcd_mbhc_config *); void msm_ext_register_audio_notifier(struct platform_device *pdev); diff --git a/asoc/sdm660-internal.h b/asoc/sdm660-internal.h index ccc62b8f33dc..6918231b8b74 100644 --- a/asoc/sdm660-internal.h +++ b/asoc/sdm660-internal.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -15,7 +15,7 @@ #include -#ifdef CONFIG_SND_SOC_INT_CODEC +#if IS_ENABLED(CONFIG_SND_SOC_INT_CODEC) int msm_int_cdc_init(struct platform_device *pdev, struct msm_asoc_mach_data *pdata, struct snd_soc_card **card, -- GitLab From 3b19449547a5010304c8f01a0e7d949f2c981d47 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 27 Sep 2017 12:20:22 +0800 Subject: [PATCH 0066/1645] audio-lnx: asoc: codecs: Fix rmmod issues with wcd9335 Remove any child devices associated with this codec driver so that rmmod and insmod again will run without issues. Clear MBHC setting during tasha_remove. Change-Id: Icad9b2ad21601525c68c5d151cd664aa6060e911 Signed-off-by: Meng Wang --- asoc/codecs/wcd9335.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 19877b96b0ed..8ade82b7bb21 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -87,6 +87,8 @@ #define TASHA_NUM_INTERPOLATORS 9 #define TASHA_NUM_DECIMATORS 9 +#define WCD9335_CHILD_DEVICES_MAX 6 + #define BYTE_BIT_MASK(nr) (1 << ((nr) % BITS_PER_BYTE)) #define TASHA_MAD_AUDIO_FIRMWARE_PATH "wcd9335/wcd9335_mad_audio.bin" #define TASHA_CPE_SS_ERR_STATUS_MEM_ACCESS (1 << 0) @@ -829,6 +831,10 @@ struct tasha_priv { u32 ref_count; /* Lock to protect mclk enablement */ struct mutex mclk_lock; + + struct platform_device *pdev_child_devices + [WCD9335_CHILD_DEVICES_MAX]; + int child_count; }; static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec, @@ -13576,11 +13582,14 @@ static int tasha_codec_remove(struct snd_soc_codec *codec) struct wcd9xxx *control; control = dev_get_drvdata(codec->dev->parent); + control->num_rx_port = 0; + control->num_tx_port = 0; control->rx_chs = NULL; control->tx_chs = NULL; tasha_cleanup_irqs(tasha); /* Cleanup MBHC */ + wcd_mbhc_deinit(&tasha->mbhc); /* Cleanup resmgr */ return 0; @@ -13920,6 +13929,7 @@ static void tasha_add_child_devices(struct work_struct *work) } platdata = &tasha->swr_plat_data; + tasha->child_count = 0; for_each_child_of_node(wcd9xxx->dev->of_node, node) { if (!strcmp(node->name, "swr_master")) @@ -13980,6 +13990,11 @@ static void tasha_add_child_devices(struct work_struct *work) tasha->nr = ctrl_num; tasha->swr_ctrl_data = swr_ctrl_data; } + + if (tasha->child_count < WCD9335_CHILD_DEVICES_MAX) + tasha->pdev_child_devices[tasha->child_count++] = pdev; + else + goto err; } return; @@ -14179,17 +14194,25 @@ static int tasha_probe(struct platform_device *pdev) static int tasha_remove(struct platform_device *pdev) { struct tasha_priv *tasha; + int count = 0; tasha = platform_get_drvdata(pdev); + if (!tasha) + return -EINVAL; + + for (count = 0; count < tasha->child_count && + count < WCD9335_CHILD_DEVICES_MAX; count++) + platform_device_unregister(tasha->pdev_child_devices[count]); + mutex_destroy(&tasha->codec_mutex); clk_put(tasha->wcd_ext_clk); if (tasha->wcd_native_clk) clk_put(tasha->wcd_native_clk); mutex_destroy(&tasha->mclk_lock); - devm_kfree(&pdev->dev, tasha); - snd_soc_unregister_codec(&pdev->dev); mutex_destroy(&tasha->sb_clk_gear_lock); + snd_soc_unregister_codec(&pdev->dev); + devm_kfree(&pdev->dev, tasha); return 0; } -- GitLab From 921b95f9a22630ab45a328dc66f310b28e82fb61 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 27 Sep 2017 15:29:03 +0800 Subject: [PATCH 0067/1645] audio-lnx: soc: pinctrl-lpi: fix rmmod issues Deregister lpi with audio notifier when removing driver to avoid crash when rmmod and insmod again. Change-Id: Ibcaf272e6405ef8403b3ac66af5572050fa1092e Signed-off-by: Meng Wang --- soc/pinctrl-lpi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index 1e7ead817399..836ab49f6893 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -622,6 +622,7 @@ static int lpi_pinctrl_remove(struct platform_device *pdev) { struct lpi_gpio_state *state = platform_get_drvdata(pdev); + audio_notifier_deregister("lpi_tlmm"); gpiochip_remove(&state->chip); return 0; } -- GitLab From 04d19310186883d767451d765cc83d9f17d08f79 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Wed, 11 Oct 2017 20:08:44 -0700 Subject: [PATCH 0068/1645] ASoC: sdm845: update TDM configurations for TX and RX Update TDM configurations for primary, secondary, and tertiary TDM interfaces. Change-Id: I1729ad4d8563063802dfae9128e290d58ad43497 Signed-off-by: Xiaoyu Ye --- asoc/sdm845.c | 277 ++++++++++++-------------------------------------- 1 file changed, 66 insertions(+), 211 deletions(-) diff --git a/asoc/sdm845.c b/asoc/sdm845.c index 5721c323e0b5..72948823db92 100644 --- a/asoc/sdm845.c +++ b/asoc/sdm845.c @@ -70,7 +70,6 @@ #define WCN_CDC_SLIM_TX_CH_MAX 3 #define TDM_CHANNEL_MAX 8 -#define TDM_SLOT_OFFSET_MAX 8 #define MSM_HIFI_ON 1 @@ -311,17 +310,6 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { } }; -/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */ -static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { - {0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */ -}; /* Default configuration of slimbus channels */ static struct dev_config slim_rx_cfg[] = { @@ -431,8 +419,8 @@ static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", - "KHZ_44P1", "KHZ_48", "KHZ_96", - "KHZ_192", "KHZ_352P8", "KHZ_384"}; + "KHZ_48", "KHZ_176P4", + "KHZ_352P8"}; static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", "KHZ_44P1", "KHZ_48", @@ -1614,23 +1602,14 @@ static int tdm_get_sample_rate(int value) sample_rate = SAMPLING_RATE_32KHZ; break; case 3: - sample_rate = SAMPLING_RATE_44P1KHZ; + sample_rate = SAMPLING_RATE_48KHZ; break; case 4: - sample_rate = SAMPLING_RATE_48KHZ; + sample_rate = SAMPLING_RATE_176P4KHZ; break; case 5: - sample_rate = SAMPLING_RATE_96KHZ; - break; - case 6: - sample_rate = SAMPLING_RATE_192KHZ; - break; - case 7: sample_rate = SAMPLING_RATE_352P8KHZ; break; - case 8: - sample_rate = SAMPLING_RATE_384KHZ; - break; default: sample_rate = SAMPLING_RATE_48KHZ; break; @@ -1668,26 +1647,17 @@ static int tdm_get_sample_rate_val(int sample_rate) case SAMPLING_RATE_32KHZ: sample_rate_val = 2; break; - case SAMPLING_RATE_44P1KHZ: + case SAMPLING_RATE_48KHZ: sample_rate_val = 3; break; - case SAMPLING_RATE_48KHZ: + case SAMPLING_RATE_176P4KHZ: sample_rate_val = 4; break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 5; - break; - case SAMPLING_RATE_192KHZ: - sample_rate_val = 6; - break; case SAMPLING_RATE_352P8KHZ: - sample_rate_val = 7; - break; - case SAMPLING_RATE_384KHZ: - sample_rate_val = 8; + sample_rate_val = 5; break; default: - sample_rate_val = 4; + sample_rate_val = 3; break; } return sample_rate_val; @@ -4491,15 +4461,46 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret = 0; - int channels, slot_width, slots; + int slot_width = 32; + int channels, slots; unsigned int slot_mask, rate, clk_freq; unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; - slot_width = 32; pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + slots = tdm_rx_cfg[TDM_PRI][TDM_0].channels; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + slots = tdm_rx_cfg[TDM_SEC][TDM_0].channels; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + slots = tdm_rx_cfg[TDM_TERT][TDM_0].channels; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX: + slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX: + slots = tdm_tx_cfg[TDM_SEC][TDM_0].channels; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX: + slots = tdm_tx_cfg[TDM_TERT][TDM_0].channels; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + break; + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { /*2 slot config - bits 0 and 1 set for the first two slots */ slot_mask = 0x0000FFFF >> (16-slots); channels = slots; @@ -4523,7 +4524,6 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream, goto end; } } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels; /*2 slot config - bits 0 and 1 set for the first two slots */ slot_mask = 0x0000FFFF >> (16-slots); channels = slots; @@ -4568,14 +4568,19 @@ static int sdm845_tdm_snd_startup(struct snd_pcm_substream *substream) { int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); - if (ret) - pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret); + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || + (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { + ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); + if (ret) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret); + } return ret; } @@ -4584,15 +4589,19 @@ static void sdm845_tdm_snd_shutdown(struct snd_pcm_substream *substream) { int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); - if (ret) - pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret); - + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || + (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { + ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); + if (ret) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret); + } } static struct snd_soc_ops sdm845_tdm_be_ops = { @@ -4726,157 +4735,6 @@ static struct snd_soc_ops msm_aux_pcm_be_ops = { .shutdown = msm_aux_pcm_snd_shutdown, }; -static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width, - int slots) -{ - unsigned int slot_mask = 0; - int i, j; - unsigned int *slot_offset; - - for (i = TDM_0; i < TDM_PORT_MAX; i++) { - slot_offset = tdm_slot_offset[i]; - - for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) { - if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID) - slot_mask |= - (1 << ((slot_offset[j] * 8) / slot_width)); - else - break; - } - } - - return slot_mask; -} - -static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret = 0; - int channels, slot_width, slots; - unsigned int slot_mask; - unsigned int *slot_offset; - int offset_channels = 0; - int i; - - pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); - - channels = params_channels(params); - switch (channels) { - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S32_LE: - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S16_LE: - /* - * Up to 8 channels HW config should - * use 32 bit slot width for max support of - * stream bit width. (slot_width > bit_width) - */ - slot_width = 32; - break; - default: - pr_err("%s: invalid param format 0x%x\n", - __func__, params_format(params)); - return -EINVAL; - } - slots = 8; - slot_mask = tdm_param_set_slot_mask(cpu_dai->id, - slot_width, - slots); - if (!slot_mask) { - pr_err("%s: invalid slot_mask 0x%x\n", - __func__, slot_mask); - return -EINVAL; - } - break; - default: - pr_err("%s: invalid param channels %d\n", - __func__, channels); - return -EINVAL; - } - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - switch (cpu_dai->id) { - case AFE_PORT_ID_PRIMARY_TDM_RX: - case AFE_PORT_ID_SECONDARY_TDM_RX: - case AFE_PORT_ID_TERTIARY_TDM_RX: - case AFE_PORT_ID_QUATERNARY_TDM_RX: - case AFE_PORT_ID_PRIMARY_TDM_TX: - case AFE_PORT_ID_SECONDARY_TDM_TX: - case AFE_PORT_ID_TERTIARY_TDM_TX: - case AFE_PORT_ID_QUATERNARY_TDM_TX: - slot_offset = tdm_slot_offset[TDM_0]; - break; - default: - pr_err("%s: dai id 0x%x not supported\n", - __func__, cpu_dai->id); - return -EINVAL; - } - - for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { - if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) - offset_channels++; - else - break; - } - - if (offset_channels == 0) { - pr_err("%s: slot offset not supported, offset_channels %d\n", - __func__, offset_channels); - return -EINVAL; - } - - if (channels > offset_channels) { - pr_err("%s: channels %d exceed offset_channels %d\n", - __func__, channels, offset_channels); - return -EINVAL; - } - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, - slots, slot_width); - if (ret < 0) { - pr_err("%s: failed to set tdm slot, err:%d\n", - __func__, ret); - goto err; - } - - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, - channels, slot_offset); - if (ret < 0) { - pr_err("%s: failed to set channel map, err:%d\n", - __func__, ret); - goto err; - } - } else { - ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, - slots, slot_width); - if (ret < 0) { - pr_err("%s: failed to set tdm slot, err:%d\n", - __func__, ret); - goto err; - } - - ret = snd_soc_dai_set_channel_map(cpu_dai, channels, - slot_offset, 0, NULL); - if (ret < 0) { - pr_err("%s: failed to set channel map, err:%d\n", - __func__, ret); - goto err; - } - } -err: - return ret; -} - static struct snd_soc_ops msm_be_ops = { .hw_params = msm_snd_hw_params, }; @@ -4889,9 +4747,6 @@ static struct snd_soc_ops msm_wcn_ops = { .hw_params = msm_wcn_hw_params, }; -static struct snd_soc_ops msm_tdm_be_ops = { - .hw_params = msm_tdm_snd_hw_params -}; /* Digital audio interface glue - connects codec <---> CPU */ static struct snd_soc_dai_link msm_common_dai_links[] = { @@ -5670,7 +5525,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_playback = 1, .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, + .ops = &sdm845_tdm_be_ops, .ignore_suspend = 1, }, { @@ -5684,7 +5539,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, + .ops = &sdm845_tdm_be_ops, .ignore_suspend = 1, }, { @@ -5698,7 +5553,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_playback = 1, .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, + .ops = &sdm845_tdm_be_ops, .ignore_suspend = 1, }, { @@ -5712,7 +5567,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, + .ops = &sdm845_tdm_be_ops, .ignore_suspend = 1, }, { @@ -5726,7 +5581,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_playback = 1, .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, + .ops = &sdm845_tdm_be_ops, .ignore_suspend = 1, }, { @@ -5740,7 +5595,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, + .ops = &sdm845_tdm_be_ops, .ignore_suspend = 1, }, { -- GitLab From c444ff7b6a6cd3efaa983e51c1c8f9d3735fe384 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 18 Oct 2017 10:52:07 +0800 Subject: [PATCH 0069/1645] audio-lnx: asoc: sdm660: fix rmmod issue with audio notifier Deregister sound card with audio notifier when removing driver to avoid crash. Change-Id: I4f22fefce519e8dab25901337fdf2e62044090ed Signed-off-by: Meng Wang --- asoc/sdm660-common.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c index e6b82dfda7a2..7142de513e95 100644 --- a/asoc/sdm660-common.c +++ b/asoc/sdm660-common.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "msm-pcm-routing-v2.h" #include "sdm660-common.h" #include "sdm660-internal.h" @@ -3370,6 +3371,10 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) gpio_free(pdata->us_euro_gpio); gpio_free(pdata->hph_en1_gpio); gpio_free(pdata->hph_en0_gpio); + + if (pdata->snd_card_val != INT_SND_CARD) + audio_notifier_deregister("sdm660"); + snd_soc_unregister_card(card); return 0; } -- GitLab From 431f0b1a3a03be7d53851473b841bcf056694fbe Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 18 Oct 2017 10:53:57 +0800 Subject: [PATCH 0070/1645] audio-lnx: asoc: sdm660: fix rmmod issue Remove msm_free_auxdev_mem to avoid kernel panic. Change-Id: I0a60cc33acf942c33273d86d9ef24dff6bd3a1b6 Signed-off-by: Meng Wang --- asoc/sdm660-common.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c index 7142de513e95..34fcdf0150ac 100644 --- a/asoc/sdm660-common.c +++ b/asoc/sdm660-common.c @@ -3135,20 +3135,6 @@ static int msm_init_wsa_dev(struct platform_device *pdev, return ret; } -static void msm_free_auxdev_mem(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - int i; - - if (card->num_aux_devs > 0) { - for (i = 0; i < card->num_aux_devs; i++) { - kfree(msm_aux_dev[i].codec_name); - kfree(msm_codec_conf[i].dev_name); - kfree(msm_codec_conf[i].name_prefix); - } - } -} - static void i2s_auxpcm_init(struct platform_device *pdev) { int count; @@ -3367,7 +3353,6 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) if (pdata->snd_card_val == INT_SND_CARD) mutex_destroy(&pdata->cdc_int_mclk0_mutex); - msm_free_auxdev_mem(pdev); gpio_free(pdata->us_euro_gpio); gpio_free(pdata->hph_en1_gpio); gpio_free(pdata->hph_en0_gpio); -- GitLab From c4ef3b5ecaa4161cb7455dfabb77e28ee6d6f188 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 18 Oct 2017 10:57:15 +0800 Subject: [PATCH 0071/1645] audio-lnx: asoc: sdm660: fix rmmod issue with gpio_free Check if GPIO is valid before free to avoid crash. Change-Id: Ie052e5ff1776ad57ae9c1d0f00873ba29e11f78f Signed-off-by: Meng Wang --- asoc/sdm660-common.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c index 34fcdf0150ac..1874cfa02860 100644 --- a/asoc/sdm660-common.c +++ b/asoc/sdm660-common.c @@ -3353,9 +3353,18 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) if (pdata->snd_card_val == INT_SND_CARD) mutex_destroy(&pdata->cdc_int_mclk0_mutex); - gpio_free(pdata->us_euro_gpio); - gpio_free(pdata->hph_en1_gpio); - gpio_free(pdata->hph_en0_gpio); + if (gpio_is_valid(pdata->us_euro_gpio)) { + gpio_free(pdata->us_euro_gpio); + pdata->us_euro_gpio = 0; + } + if (gpio_is_valid(pdata->hph_en1_gpio)) { + gpio_free(pdata->hph_en1_gpio); + pdata->hph_en1_gpio = 0; + } + if (gpio_is_valid(pdata->hph_en0_gpio)) { + gpio_free(pdata->hph_en0_gpio); + pdata->hph_en0_gpio = 0; + } if (pdata->snd_card_val != INT_SND_CARD) audio_notifier_deregister("sdm660"); -- GitLab From 523325316e7b2a8858dba93fc104c890d84ccc11 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 12 Oct 2017 08:58:30 +0530 Subject: [PATCH 0072/1645] ASoC: codecs: sdm660_cdc: Fix mute if compander is disabled Compander disable sequence does not get called after headphone playback on FM. This results in mute at one channel. Compander clock should be disabled at the end to resolve the mute. CRs-Fixed: 2102126 Change-Id: Ia47fb1c393db255b52a965173a769896768f245e Signed-off-by: Vatsal Bucha --- asoc/codecs/sdm660_cdc/msm-digital-cdc.c | 82 ++++++++++++------------ 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c index 3df917f717b5..eeaddf6ed5c8 100644 --- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -211,60 +211,60 @@ static int msm_dig_cdc_codec_config_compander(struct snd_soc_codec *codec, int interp_n, int event) { struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec); + int comp_ch_bits_set = 0x03; dev_dbg(codec->dev, "%s: event %d shift %d, enabled %d\n", __func__, event, interp_n, dig_cdc->comp_enabled[interp_n]); - /* compander is not enabled */ - if (!dig_cdc->comp_enabled[interp_n]) + /* compander is invalid */ + if (dig_cdc->comp_enabled[interp_n] != COMPANDER_1 && + dig_cdc->comp_enabled[interp_n]) { + dev_dbg(codec->dev, "%s: Invalid compander %d\n", __func__, + dig_cdc->comp_enabled[interp_n]); return 0; + } - switch (dig_cdc->comp_enabled[interp_n]) { - case COMPANDER_1: - if (SND_SOC_DAPM_EVENT_ON(event)) { - /* Enable Compander Clock */ - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B2_CTL, 0x0F, 0x09); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x01, 0x01); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B1_CTL, - 1 << interp_n, 1 << interp_n); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x01); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xF0, 0x50); - /* add sleep for compander to settle */ - usleep_range(1000, 1100); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x28); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xF0, 0xB0); + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Compander Clock */ + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B2_CTL, 0x0F, 0x09); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x01, 0x01); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B1_CTL, + 1 << interp_n, 1 << interp_n); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x01); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xF0, 0x50); + /* add sleep for compander to settle */ + usleep_range(1000, 1100); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x28); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xF0, 0xB0); - /* Enable Compander GPIO */ - if (dig_cdc->codec_hph_comp_gpio) - dig_cdc->codec_hph_comp_gpio(1, codec); - } else if (SND_SOC_DAPM_EVENT_OFF(event)) { - /* Disable Compander GPIO */ - if (dig_cdc->codec_hph_comp_gpio) - dig_cdc->codec_hph_comp_gpio(0, codec); + /* Enable Compander GPIO */ + if (dig_cdc->codec_hph_comp_gpio) + dig_cdc->codec_hph_comp_gpio(1, codec); + } else if (SND_SOC_DAPM_EVENT_OFF(event)) { + /* Disable Compander GPIO */ + if (dig_cdc->codec_hph_comp_gpio) + dig_cdc->codec_hph_comp_gpio(0, codec); + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B1_CTL, + 1 << interp_n, 0); + comp_ch_bits_set = snd_soc_read(codec, + MSM89XX_CDC_CORE_COMP0_B1_CTL); + if ((comp_ch_bits_set & 0x03) == 0x00) { snd_soc_update_bits(codec, MSM89XX_CDC_CORE_COMP0_B2_CTL, 0x0F, 0x05); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B1_CTL, - 1 << interp_n, 0); - snd_soc_update_bits(codec, + snd_soc_update_bits(codec, MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x01, 0x00); } - break; - default: - dev_dbg(codec->dev, "%s: Invalid compander %d\n", __func__, - dig_cdc->comp_enabled[interp_n]); - break; - }; - + } return 0; } -- GitLab From 8b1366a648d53416d16f94dee0c33d4249018f92 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 5 Oct 2017 01:44:16 +0530 Subject: [PATCH 0073/1645] Audio: DLKM support for all audio modules Switch to DLKM for all audio kernel modules. Change-Id: I6a96023a21f655f873531af9ace81f2b01eb0f58 Signed-off-by: Laxminath Kasam --- Android.mk | 22 + asoc/Android.mk | 73 ++ asoc/Kbuild | 161 ++++ asoc/codecs/Android.mk | 121 +++ asoc/codecs/Kbuild | 181 ++++ asoc/codecs/cpe_core.h | 15 + asoc/codecs/msm_sdw/Android.mk | 46 + asoc/codecs/msm_sdw/Kbuild | 104 ++ asoc/codecs/msm_sdw/msm_sdw.h | 29 + asoc/codecs/sdm660_cdc/Android.mk | 53 + asoc/codecs/sdm660_cdc/Kbuild | 110 +++ asoc/codecs/sdm660_cdc/msm-analog-cdc.h | 38 +- asoc/codecs/sdm660_cdc/msm-digital-cdc.h | 16 + asoc/codecs/wcd-mbhc-legacy.h | 2 +- asoc/codecs/wcd-mbhc-v2.c | 12 + asoc/codecs/wcd9335.h | 72 ++ asoc/codecs/wcd934x/Android.mk | 54 ++ asoc/codecs/wcd934x/Kbuild | 105 ++ asoc/msm-audio-effects-q6-v2.c | 73 ++ asoc/msm-compress-q6-v2.c | 6 +- asoc/msm-cpe-lsm.c | 13 +- asoc/msm-dai-fe.c | 6 +- asoc/msm-dai-q6-hdmi-v2.c | 6 +- asoc/msm-dai-q6-v2.c | 11 +- asoc/msm-dai-slim.c | 7 +- asoc/msm-dai-stub-v2.c | 6 +- asoc/msm-ds2-dap-config.c | 2 +- asoc/msm-lsm-client.c | 6 +- asoc/msm-pcm-afe-v2.c | 6 +- asoc/msm-pcm-dtmf-v2.c | 6 +- asoc/msm-pcm-host-voice-v2.c | 6 +- asoc/msm-pcm-hostless.c | 6 +- asoc/msm-pcm-loopback-v2.c | 6 +- asoc/msm-pcm-q6-noirq.c | 12 +- asoc/msm-pcm-q6-v2.c | 6 +- asoc/msm-pcm-routing-v2.c | 8 +- asoc/msm-pcm-voice-v2.c | 6 +- asoc/msm-pcm-voip-v2.c | 6 +- asoc/msm-transcode-loopback-q6-v2.c | 6 +- asoc/platform_init.c | 69 ++ asoc/platform_init.h | 58 ++ config/sdm670auto.conf | 99 +- config/sdm670autoconf.h | 1 + dsp/Android.mk | 86 ++ dsp/Kbuild | 149 +++ dsp/adsp_err.c | 16 +- dsp/audio_cal_utils.c | 9 + dsp/audio_calibration.c | 7 +- dsp/audio_notifier.c | 43 +- dsp/audio_pdr.c | 39 +- dsp/audio_pdr.h | 1 + dsp/audio_slimslave.c | 6 +- dsp/audio_ssr.c | 43 +- dsp/avtimer.c | 8 +- dsp/codecs/Android.mk | 54 ++ dsp/codecs/Kbuild | 133 +++ dsp/codecs/aac_in.c | 8 +- dsp/codecs/amrnb_in.c | 7 +- dsp/codecs/amrwb_in.c | 7 +- dsp/codecs/audio_aac.c | 8 +- dsp/codecs/audio_alac.c | 8 +- dsp/codecs/audio_amrnb.c | 8 +- dsp/codecs/audio_amrwb.c | 8 +- dsp/codecs/audio_amrwbplus.c | 8 +- dsp/codecs/audio_ape.c | 8 +- dsp/codecs/audio_evrc.c | 8 +- dsp/codecs/audio_g711alaw.c | 10 +- dsp/codecs/audio_g711mlaw.c | 8 +- dsp/codecs/audio_hwacc_effects.c | 8 +- dsp/codecs/audio_mp3.c | 8 +- dsp/codecs/audio_multi_aac.c | 8 +- dsp/codecs/audio_native.c | 75 ++ dsp/codecs/audio_qcelp.c | 8 +- dsp/codecs/audio_utils.h | 44 + dsp/codecs/audio_wma.c | 8 +- dsp/codecs/audio_wmapro.c | 8 +- dsp/codecs/evrc_in.c | 7 +- dsp/codecs/g711alaw_in.c | 7 +- dsp/codecs/g711mlaw_in.c | 7 +- dsp/codecs/qcelp_in.c | 7 +- {asoc => dsp}/msm-dts-srs-tm-config.c | 44 +- dsp/msm_audio_ion.c | 83 +- dsp/q6_init.c | 55 ++ dsp/q6_init.h | 43 + dsp/q6adm.c | 395 +++++++- dsp/q6afe.c | 326 ++++++- dsp/q6asm.c | 912 +++++++++++++++++- dsp/q6audio-v2.c | 9 + dsp/q6core.c | 34 +- dsp/q6lsm.c | 208 +++- dsp/q6usm.c | 4 +- dsp/q6usm.h | 1 + dsp/q6voice.c | 432 ++++++++- dsp/rtac.c | 10 +- dsp/usf.c | 12 +- dsp/usfcdev.c | 13 +- include/dsp/audio_notifier.h | 4 +- include/{asoc => dsp}/msm-dts-srs-tm-config.h | 0 include/dsp/q6adm-v2.h | 2 + include/ipc/apr.h | 1 + include/ipc/apr_tal.h | 1 + include/soc/internal.h | 2 +- ipc/Android.mk | 61 ++ ipc/Kbuild | 153 +++ ipc/apr.c | 103 +- ipc/apr_tal_glink.c | 3 +- ipc/apr_v2.c | 10 + ipc/apr_v3.c | 10 + ipc/wcd-dsp-glink.c | 12 +- soc/Android.mk | 79 ++ soc/Kbuild | 121 +++ soc/core.h | 2 +- soc/pinctrl-utils.h | 2 +- soc/soundwire.c | 2 +- soc/swr-wcd-ctrl.c | 3 +- 115 files changed, 5341 insertions(+), 347 deletions(-) create mode 100644 Android.mk create mode 100644 asoc/Android.mk create mode 100644 asoc/Kbuild create mode 100644 asoc/codecs/Android.mk create mode 100644 asoc/codecs/Kbuild create mode 100644 asoc/codecs/msm_sdw/Android.mk create mode 100644 asoc/codecs/msm_sdw/Kbuild create mode 100644 asoc/codecs/sdm660_cdc/Android.mk create mode 100644 asoc/codecs/sdm660_cdc/Kbuild create mode 100644 asoc/codecs/wcd934x/Android.mk create mode 100644 asoc/codecs/wcd934x/Kbuild create mode 100644 asoc/platform_init.c create mode 100644 asoc/platform_init.h create mode 100644 dsp/Android.mk create mode 100644 dsp/Kbuild create mode 100644 dsp/codecs/Android.mk create mode 100644 dsp/codecs/Kbuild create mode 100644 dsp/codecs/audio_native.c rename {asoc => dsp}/msm-dts-srs-tm-config.c (92%) create mode 100644 dsp/q6_init.c create mode 100644 dsp/q6_init.h rename include/{asoc => dsp}/msm-dts-srs-tm-config.h (100%) create mode 100644 ipc/Android.mk create mode 100644 ipc/Kbuild create mode 100644 soc/Android.mk create mode 100644 soc/Kbuild diff --git a/Android.mk b/Android.mk new file mode 100644 index 000000000000..a7341e330017 --- /dev/null +++ b/Android.mk @@ -0,0 +1,22 @@ +# Android makefile for audio kernel modules +MY_LOCAL_PATH := $(call my-dir) + +UAPI_OUT := $(OUT)/obj/vendor/qcom/opensource/audio-kernel/include + +ifeq ($(call is-board-platform-in-list,sdm845 sdm670),true) +$(shell mkdir -p $(UAPI_OUT)/linux;) +$(shell mkdir -p $(UAPI_OUT)/sound;) + +include $(MY_LOCAL_PATH)/ipc/Android.mk +include $(MY_LOCAL_PATH)/dsp/Android.mk +include $(MY_LOCAL_PATH)/dsp/codecs/Android.mk +include $(MY_LOCAL_PATH)/soc/Android.mk +include $(MY_LOCAL_PATH)/asoc/Android.mk +include $(MY_LOCAL_PATH)/asoc/codecs/Android.mk +include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk +endif + +ifeq ($(call is-board-platform,sdm670),true) +include $(MY_LOCAL_PATH)/asoc/codecs/sdm660_cdc/Android.mk +include $(MY_LOCAL_PATH)/asoc/codecs/msm_sdw/Android.mk +endif diff --git a/asoc/Android.mk b/asoc/Android.mk new file mode 100644 index 000000000000..9497ae9f08ee --- /dev/null +++ b/asoc/Android.mk @@ -0,0 +1,73 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,sdm845),true) +TARGET := sdm845 +AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m +endif + +ifeq ($(call is-board-platform,sdm670),true) +TARGET := sdm670 +AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,sdm845 sdm670),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=platform_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_platform.ko +LOCAL_MODULE_KBUILD_NAME := platform_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +ifeq ($(call is-board-platform,sdm670),true) +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_cpe_lsm.ko +LOCAL_MODULE_KBUILD_NAME := cpe_lsm_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +endif +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_machine_$(TARGET).ko +LOCAL_MODULE_KBUILD_NAME := machine_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/asoc/Kbuild b/asoc/Kbuild new file mode 100644 index 000000000000..eb32e8841c22 --- /dev/null +++ b/asoc/Kbuild @@ -0,0 +1,161 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +KERNEL_BUILD := 0 + + +ifeq ($(KERNEL_BUILD), 0) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + ifeq ($(CONFIG_ARCH_SDM845), y) + include $(AUDIO_ROOT)/config/sdm845auto.conf + export + endif + ifeq ($(CONFIG_ARCH_SDM670), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + endif +endif + + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ ASoC Drivers ############ + + +# for SDM6xx sound card driver +ifeq ($(CONFIG_SND_SOC_SDM670), m) + MACHINE_OBJS += sdm660-common.o +endif + +# for SDM6xx sound card driver +ifeq ($(CONFIG_SND_SOC_INT_CODEC), m) + MACHINE_OBJS += sdm660-internal.o +endif + +# for SDM6xx sound card driver +ifeq ($(CONFIG_SND_SOC_EXT_CODEC), m) + MACHINE_OBJS += sdm660-external.o + MACHINE_OBJS += sdm660-ext-dai-links.o +endif + +# for SDM845 sound card driver +ifeq ($(CONFIG_SND_SOC_MACHINE_SDM845), m) + MACHINE_OBJS += sdm845.o +endif + +ifeq ($(CONFIG_SND_SOC_CPE), m) + CPE_LSM_OBJS += msm-cpe-lsm.o +endif + +ifeq ($(CONFIG_SND_SOC_QDSP6V2), m) + PLATFORM_OBJS += msm-audio-effects-q6-v2.o + PLATFORM_OBJS += msm-compress-q6-v2.o + PLATFORM_OBJS += msm-dai-fe.o + PLATFORM_OBJS += msm-dai-q6-hdmi-v2.o + PLATFORM_OBJS += msm-dai-q6-v2.o + PLATFORM_OBJS += msm-dai-slim.o + PLATFORM_OBJS += msm-dai-stub-v2.o + PLATFORM_OBJS += msm-ds2-dap-config.o + PLATFORM_OBJS += msm-lsm-client.o + PLATFORM_OBJS += msm-pcm-afe-v2.o + PLATFORM_OBJS += msm-pcm-dtmf-v2.o + PLATFORM_OBJS += msm-pcm-hostless.o + PLATFORM_OBJS += msm-pcm-host-voice-v2.o + PLATFORM_OBJS += msm-pcm-loopback-v2.o + PLATFORM_OBJS += msm-pcm-q6-noirq.o + PLATFORM_OBJS += msm-pcm-q6-v2.o + PLATFORM_OBJS += msm-pcm-routing-devdep.o + PLATFORM_OBJS += msm-pcm-routing-v2.o + PLATFORM_OBJS += msm-pcm-voice-v2.o + PLATFORM_OBJS += msm-pcm-voip-v2.o + PLATFORM_OBJS += msm-qti-pp-config.o + PLATFORM_OBJS += msm-transcode-loopback-q6-v2.o + PLATFORM_OBJS += platform_init.o +endif + +LINUX_INC += -Iinclude/linux + +INCS := $(COMMON_INC) \ + $(UAPI_INC) + +ifeq ($(CONFIG_ARCH_SDM845), y) +INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h +endif +ifeq ($(CONFIG_ARCH_SDM670), y) +INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h +endif + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + + +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_QDSP6V2) += platform_dlkm.o +platform_dlkm-y := $(PLATFORM_OBJS) + +obj-$(CONFIG_SND_SOC_MACHINE_SDM845) += machine_dlkm.o +machine_dlkm-y := $(MACHINE_OBJS) + +obj-$(CONFIG_SND_SOC_EXT_CODEC) += machine_dlkm.o +machine_dlkm-y := $(MACHINE_OBJS) + +obj-$(CONFIG_SND_SOC_INT_CODEC) += machine_dlkm.o +machine_dlkm-y := $(MACHINE_OBJS) + +obj-$(CONFIG_SND_SOC_CPE) += cpe_lsm_dlkm.o +cpe_lsm_dlkm-y := $(CPE_LSM_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk new file mode 100644 index 000000000000..863da5a59735 --- /dev/null +++ b/asoc/codecs/Android.mk @@ -0,0 +1,121 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,sdm845),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m +endif + +ifeq ($(call is-board-platform,sdm670),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,sdm845 sdm670),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=wcd_core_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd_core.ko +LOCAL_MODULE_KBUILD_NAME := wcd_core_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd9xxx.ko +LOCAL_MODULE_KBUILD_NAME := wcd9xxx_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +ifeq ($(call is-board-platform,sdm670),true) +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd_cpe.ko +LOCAL_MODULE_KBUILD_NAME := wcd_cpe_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +endif +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd_spi.ko +LOCAL_MODULE_KBUILD_NAME := wcd_spi_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +ifeq ($(call is-board-platform,sdm670),true) +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd9335.ko +LOCAL_MODULE_KBUILD_NAME := wcd9335_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +endif +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_wsa881x.ko +LOCAL_MODULE_KBUILD_NAME := wsa881x_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_stub.ko +LOCAL_MODULE_KBUILD_NAME := stub_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_mbhc.ko +LOCAL_MODULE_KBUILD_NAME := mbhc_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_hdmi.ko +LOCAL_MODULE_KBUILD_NAME := hdmi_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild new file mode 100644 index 000000000000..83d4da441d41 --- /dev/null +++ b/asoc/codecs/Kbuild @@ -0,0 +1,181 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +KERNEL_BUILD := 0 + + +ifeq ($(KERNEL_BUILD), 0) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + ifeq ($(CONFIG_ARCH_SDM845), y) + include $(AUDIO_ROOT)/config/sdm845auto.conf + export + endif + ifeq ($(CONFIG_ARCH_SDM670), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + endif +endif + + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ ASoC Codecs ############ +ifeq ($(CONFIG_WCD9XXX_CODEC_CORE), m) + CORE_OBJS += wcd9xxx-rst.o + CORE_OBJS += wcd9xxx-core-init.o + CORE_OBJS += wcd9xxx-core.o + CORE_OBJS += wcd9xxx-irq.o + CORE_OBJS += wcd9xxx-slimslave.o + CORE_OBJS += wcd9xxx-utils.o + CORE_OBJS += wcd9335-regmap.o + CORE_OBJS += wcd9335-tables.o + CORE_OBJS += msm-cdc-pinctrl.o + CORE_OBJS += msm-cdc-supply.o + CORE_OBJS += wcd934x/wcd934x-regmap.o + CORE_OBJS += wcd934x/wcd934x-tables.o +endif + +ifeq ($(CONFIG_SND_SOC_WCD9XXX_V2), m) + WCD9XXX_OBJS += wcd9xxx-common-v2.o + WCD9XXX_OBJS += wcd9xxx-resmgr-v2.o + WCD9XXX_OBJS += wcdcal-hwdep.o + WCD9XXX_OBJS += wcd9xxx-soc-init.o + WCD9XXX_OBJS += wcd-dsp-utils.o + WCD9XXX_OBJS += wcd-dsp-mgr.o + WCD9XXX_OBJS += audio-ext-clk-up.o +endif + +ifeq ($(CONFIG_SND_SOC_WCD9335), m) + WCD9335_OBJS += wcd9335.o +endif + +ifeq ($(CONFIG_SND_SOC_WSA881X), m) + WSA881X_OBJS += wsa881x.o + WSA881X_OBJS += wsa881x-tables.o + WSA881X_OBJS += wsa881x-regmap.o + WSA881X_OBJS += wsa881x-temp-sensor.o +endif + +ifeq ($(CONFIG_SND_SOC_MSM_STUB), m) + STUB_OBJS += msm_stub.o +endif +ifeq ($(CONFIG_SND_SOC_WCD_SPI), m) + SPI_OBJS += wcd-spi.o +endif + +ifeq ($(CONFIG_SND_SOC_WCD_CPE), m) + WCD_CPE_OBJS += wcd_cpe_core.o + WCD_CPE_OBJS += wcd_cpe_services.o +endif + +ifeq ($(CONFIG_SND_SOC_WCD_MBHC), m) + MBHC_OBJS += wcd-mbhc-v2.o +endif + +ifeq ($(CONFIG_SND_SOC_WCD_MBHC_ADC), m) + MBHC_OBJS += wcd-mbhc-adc.o +endif + +ifeq ($(CONFIG_SND_SOC_WCD_MBHC_LEGACY), m) + MBHC_OBJS += wcd-mbhc-legacy.o +endif + +ifeq ($(CONFIG_SND_SOC_MSM_HDMI_CODEC_RX), m) + HDMICODEC_OBJS += msm_hdmi_codec_rx.o +endif + +LINUX_INC += -Iinclude/linux + +INCS := $(COMMON_INC) \ + $(UAPI_INC) + +ifeq ($(CONFIG_ARCH_SDM845), y) +INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h +endif +ifeq ($(CONFIG_ARCH_SDM670), y) +INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h +endif + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + + +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +# Module information used by KBuild framework +obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd_core_dlkm.o +wcd_core_dlkm-y := $(CORE_OBJS) + +obj-$(CONFIG_SND_SOC_WCD9XXX_V2) += wcd9xxx_dlkm.o +wcd9xxx_dlkm-y := $(WCD9XXX_OBJS) + +obj-$(CONFIG_SND_SOC_WCD9335) += wcd9335_dlkm.o +wcd9335_dlkm-y := $(WCD9335_OBJS) + +obj-$(CONFIG_SND_SOC_WSA881X) += wsa881x_dlkm.o +wsa881x_dlkm-y := $(WSA881X_OBJS) + +obj-$(CONFIG_SND_SOC_MSM_STUB) += stub_dlkm.o +stub_dlkm-y := $(STUB_OBJS) + +obj-$(CONFIG_SND_SOC_WCD_CPE) += wcd_cpe_dlkm.o +wcd_cpe_dlkm-y := $(WCD_CPE_OBJS) + +obj-$(CONFIG_SND_SOC_WCD_SPI) += wcd_spi_dlkm.o +wcd_spi_dlkm-y := $(SPI_OBJS) + +obj-$(CONFIG_SND_SOC_WCD_MBHC) += mbhc_dlkm.o +mbhc_dlkm-y := $(MBHC_OBJS) + +obj-$(CONFIG_SND_SOC_MSM_HDMI_CODEC_RX) += hdmi_dlkm.o +hdmi_dlkm-y := $(HDMICODEC_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/cpe_core.h b/asoc/codecs/cpe_core.h index 9f7c2f31ff0d..99504c5c9625 100644 --- a/asoc/codecs/cpe_core.h +++ b/asoc/codecs/cpe_core.h @@ -173,7 +173,22 @@ struct wcd_cpe_lsm_ops { struct cpe_lsm_session *session, void *data); }; +#if IS_ENABLED(CONFIG_SND_SOC_WCD_CPE) int wcd_cpe_get_lsm_ops(struct wcd_cpe_lsm_ops *lsm_ops); int wcd_cpe_get_afe_ops(struct wcd_cpe_afe_ops *afe_ops); void *wcd_cpe_get_core_handle(struct snd_soc_codec *codec); +#else /* CONFIG_SND_SOC_WCD_CPE */ +static inline int wcd_cpe_get_lsm_ops(struct wcd_cpe_lsm_ops *lsm_ops) +{ + return 0; +} +static inline int wcd_cpe_get_afe_ops(struct wcd_cpe_afe_ops *afe_ops) +{ + return 0; +} +static inline void *wcd_cpe_get_core_handle(struct snd_soc_codec *codec) +{ + return NULL; +} +#endif /* CONFIG_SND_SOC_WCD_CPE */ #endif diff --git a/asoc/codecs/msm_sdw/Android.mk b/asoc/codecs/msm_sdw/Android.mk new file mode 100644 index 000000000000..421420b84899 --- /dev/null +++ b/asoc/codecs/msm_sdw/Android.mk @@ -0,0 +1,46 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform,sdm670),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=msm_sdw_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_msm_sdw.ko +LOCAL_MODULE_KBUILD_NAME := msm_sdw_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/asoc/codecs/msm_sdw/Kbuild b/asoc/codecs/msm_sdw/Kbuild new file mode 100644 index 000000000000..a55948e21495 --- /dev/null +++ b/asoc/codecs/msm_sdw/Kbuild @@ -0,0 +1,104 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +KERNEL_BUILD := 0 + + +ifeq ($(KERNEL_BUILD), 0) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + ifeq ($(CONFIG_ARCH_SDM845), y) + include $(AUDIO_ROOT)/config/sdm845auto.conf + export + endif + ifeq ($(CONFIG_ARCH_SDM670), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + endif +endif + + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ MSM Soundwire ############ + +# for MSM Soundwire Codec +ifeq ($(CONFIG_SND_SOC_MSM_SDW), m) + MSM_SDW_OBJS += msm_sdw_cdc.o + MSM_SDW_OBJS += msm_sdw_regmap.o + MSM_SDW_OBJS += msm-sdw-tables.o + MSM_SDW_OBJS += msm_sdw_cdc_utils.o +endif + +LINUX_INC += -Iinclude/linux + +INCS := $(COMMON_INC) \ + $(UAPI_INC) + +ifeq ($(CONFIG_ARCH_SDM845), y) +INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h +endif +ifeq ($(CONFIG_ARCH_SDM670), y) +INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h +endif + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_MSM_SDW) += msm_sdw_dlkm.o +msm_sdw_dlkm-y := $(MSM_SDW_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/msm_sdw/msm_sdw.h b/asoc/codecs/msm_sdw/msm_sdw.h index 3285f5f5512d..d4ac43333392 100644 --- a/asoc/codecs/msm_sdw/msm_sdw.h +++ b/asoc/codecs/msm_sdw/msm_sdw.h @@ -156,6 +156,7 @@ struct msm_sdw_priv { struct snd_info_entry *version_entry; }; +#if IS_ENABLED(CONFIG_SND_SOC_MSM_SDW) extern int msm_sdw_set_spkr_mode(struct snd_soc_codec *codec, int mode); extern int msm_sdw_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset); @@ -167,4 +168,32 @@ extern struct regmap *msm_sdw_regmap_init(struct device *dev, extern int msm_sdw_codec_info_create_codec_entry( struct snd_info_entry *codec_root, struct snd_soc_codec *codec); +#else /* CONFIG_SND_SOC_MSM_SDW */ +static inline int msm_sdw_set_spkr_mode(struct snd_soc_codec *codec, int mode) +{ + return 0; +} +static inline int msm_sdw_set_spkr_gain_offset(struct snd_soc_codec *codec, + int offset); +{ + return 0; +} +static inline void msm_sdw_gpio_cb( + int (*sdw_cdc_gpio_fn)(bool enable, struct snd_soc_codec *codec), + struct snd_soc_codec *codec); +{ + +} +static inline struct regmap *msm_sdw_regmap_init(struct device *dev, + const struct regmap_config *config); +{ + return NULL; +} +static inline int msm_sdw_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + return 0; +} +#endif /* CONFIG_SND_SOC_MSM_SDW */ #endif diff --git a/asoc/codecs/sdm660_cdc/Android.mk b/asoc/codecs/sdm660_cdc/Android.mk new file mode 100644 index 000000000000..f322a65562f4 --- /dev/null +++ b/asoc/codecs/sdm660_cdc/Android.mk @@ -0,0 +1,53 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform,sdm670),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=analog_cdc_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_analog_cdc.ko +LOCAL_MODULE_KBUILD_NAME := analog_cdc_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_digital_cdc.ko +LOCAL_MODULE_KBUILD_NAME := digital_cdc_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/asoc/codecs/sdm660_cdc/Kbuild b/asoc/codecs/sdm660_cdc/Kbuild new file mode 100644 index 000000000000..c1777ee53372 --- /dev/null +++ b/asoc/codecs/sdm660_cdc/Kbuild @@ -0,0 +1,110 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +KERNEL_BUILD := 0 + + +ifeq ($(KERNEL_BUILD), 0) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + ifeq ($(CONFIG_ARCH_SDM845), y) + include $(AUDIO_ROOT)/config/sdm845auto.conf + export + endif + ifeq ($(CONFIG_ARCH_SDM670), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + endif +endif + + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ SDM660_CDC ############ + +# for SDM660_CDC Codec +ifeq ($(CONFIG_SND_SOC_ANALOG_CDC), m) + ANALOG_CDC_OBJS += msm-analog-cdc.o + ANALOG_CDC_OBJS += sdm660-cdc-irq.o +endif + +ifeq ($(CONFIG_SND_SOC_DIGITAL_CDC), m) + DIGITAL_CDC_OBJS += msm-digital-cdc.o + DIGITAL_CDC_OBJS += msm-digital-cdc-regmap.o +endif +LINUX_INC += -Iinclude/linux + +INCS := $(COMMON_INC) \ + $(UAPI_INC) + +ifeq ($(CONFIG_ARCH_SDM845), y) +INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h +endif +ifeq ($(CONFIG_ARCH_SDM670), y) +INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h +endif + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + + +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_ANALOG_CDC) += analog_cdc_dlkm.o +analog_cdc_dlkm-y := $(ANALOG_CDC_OBJS) + +obj-$(CONFIG_SND_SOC_DIGITAL_CDC) += digital_cdc_dlkm.o +digital_cdc_dlkm-y := $(DIGITAL_CDC_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.h b/asoc/codecs/sdm660_cdc/msm-analog-cdc.h index fffdf3156255..9591487b57b8 100644 --- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.h +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.h @@ -221,20 +221,48 @@ struct sdm660_cdc_pdata { struct sdm660_cdc_regulator regulator[MAX_REGULATOR]; }; - +#if IS_ENABLED(CONFIG_SND_SOC_ANALOG_CDC) extern int msm_anlg_cdc_mclk_enable(struct snd_soc_codec *codec, int mclk_enable, bool dapm); - extern int msm_anlg_cdc_hs_detect(struct snd_soc_codec *codec, struct wcd_mbhc_config *mbhc_cfg); - extern void msm_anlg_cdc_hs_detect_exit(struct snd_soc_codec *codec); - extern void sdm660_cdc_update_int_spk_boost(bool enable); - extern void msm_anlg_cdc_spk_ext_pa_cb( int (*codec_spk_ext_pa)(struct snd_soc_codec *codec, int enable), struct snd_soc_codec *codec); int msm_anlg_codec_info_create_codec_entry(struct snd_info_entry *codec_root, struct snd_soc_codec *codec); +#else /* CONFIG_SND_SOC_ANALOG_CDC */ +static inline int msm_anlg_cdc_mclk_enable(struct snd_soc_codec *codec, + int mclk_enable, bool dapm) +{ + return 0; +} +static inline int msm_anlg_cdc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg) +{ + return 0; +} +static inline void msm_anlg_cdc_hs_detect_exit(struct snd_soc_codec *codec) +{ + +} +static inline void sdm660_cdc_update_int_spk_boost(bool enable) +{ + +} +static inline void msm_anlg_cdc_spk_ext_pa_cb( + int (*codec_spk_ext_pa)(struct snd_soc_codec *codec, + int enable), struct snd_soc_codec *codec) +{ + +} +static inline int msm_anlg_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + return 0; +} +#endif /* CONFIG_SND_SOC_ANALOG_CDC */ #endif diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.h b/asoc/codecs/sdm660_cdc/msm-digital-cdc.h index 42c31d5089b2..cb6cfe2f538e 100644 --- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.h +++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.h @@ -89,10 +89,26 @@ enum { BAND_MAX, }; +#if IS_ENABLED(CONFIG_SND_SOC_DIGITAL_CDC) extern void msm_dig_cdc_hph_comp_cb( int (*codec_hph_comp_gpio)( bool enable, struct snd_soc_codec *codec), struct snd_soc_codec *codec); int msm_dig_codec_info_create_codec_entry(struct snd_info_entry *codec_root, struct snd_soc_codec *codec); +#else /* CONFIG_SND_SOC_DIGITAL_CDC */ +static inline void msm_dig_cdc_hph_comp_cb( + int (*codec_hph_comp_gpio)( + bool enable, struct snd_soc_codec *codec), + struct snd_soc_codec *codec) +{ + +} +static inline int msm_dig_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + return 0; +} +#endif /* CONFIG_SND_SOC_DIGITAL_CDC */ #endif diff --git a/asoc/codecs/wcd-mbhc-legacy.h b/asoc/codecs/wcd-mbhc-legacy.h index 594393d47896..af3a7dc6d06b 100644 --- a/asoc/codecs/wcd-mbhc-legacy.h +++ b/asoc/codecs/wcd-mbhc-legacy.h @@ -15,7 +15,7 @@ #include "wcdcal-hwdep.h" #include "wcd-mbhc-v2.h" -#ifdef CONFIG_SND_SOC_WCD_MBHC_LEGACY +#if IS_ENABLED(CONFIG_SND_SOC_WCD_MBHC_LEGACY) void wcd_mbhc_legacy_init(struct wcd_mbhc *mbhc); #else static inline void wcd_mbhc_legacy_init(struct wcd_mbhc *mbhc) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index d7c59211658a..3c501b490084 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -2121,5 +2121,17 @@ void wcd_mbhc_deinit(struct wcd_mbhc *mbhc) } EXPORT_SYMBOL(wcd_mbhc_deinit); +static int __init mbhc_init(void) +{ + return 0; +} + +static void __exit mbhc_exit(void) +{ +} + +module_init(mbhc_init); +module_exit(mbhc_exit); + MODULE_DESCRIPTION("wcd MBHC v2 module"); MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/wcd9335.h b/asoc/codecs/wcd9335.h index 48826e668d2e..f5f103853b30 100644 --- a/asoc/codecs/wcd9335.h +++ b/asoc/codecs/wcd9335.h @@ -137,6 +137,7 @@ enum { RX_GAIN_OFFSET_0_DB, }; +#if IS_ENABLED(CONFIG_SND_SOC_WCD9335) extern void *tasha_get_afe_config(struct snd_soc_codec *codec, enum afe_config_type config_type); extern int tasha_cdc_mclk_enable(struct snd_soc_codec *codec, int enable, @@ -163,4 +164,75 @@ extern int tasha_codec_enable_standalone_micbias(struct snd_soc_codec *codec, extern int tasha_set_spkr_mode(struct snd_soc_codec *codec, int mode); extern int tasha_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset); extern enum codec_variant tasha_codec_ver(void); +#else /* CONFIG_SND_SOC_WCD9335 */ +static inline void *tasha_get_afe_config(struct snd_soc_codec *codec, + enum afe_config_type config_type) +{ + return NULL; +} +static inline int tasha_cdc_mclk_enable(struct snd_soc_codec *codec, + int enable, + bool dapm) +{ + return 0; +} +static inline int tasha_cdc_mclk_tx_enable(struct snd_soc_codec *codec, + int enable, + bool dapm) +{ + return 0; +} +static inline int tasha_enable_efuse_sensing(struct snd_soc_codec *codec) +{ + return 0; +} +static inline int tasha_mbhc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg) +{ + return 0; +} +static inline void tasha_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +{ + +} +static inline void tasha_mbhc_zdet_gpio_ctrl( + int (*zdet_gpio_cb)(struct snd_soc_codec *codec, bool high), + struct snd_soc_codec *codec) +{ + +} +static inline int tasha_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + return 0; +} +static inline void tasha_event_register( + int (*machine_event_cb)(struct snd_soc_codec *codec, + enum wcd9335_codec_event), + struct snd_soc_codec *codec) +{ + +} +static inline int tasha_codec_enable_standalone_micbias( + struct snd_soc_codec *codec, + int micb_num, + bool enable) +{ + return 0; +} +static inline int tasha_set_spkr_mode(struct snd_soc_codec *codec, int mode) +{ + return 0; +} +static inline int tasha_set_spkr_gain_offset(struct snd_soc_codec *codec, + int offset) +{ + return 0; +} +static inline enum codec_variant tasha_codec_ver(void) +{ + return 0; +} +#endif /* CONFIG_SND_SOC_WCD9335 */ #endif diff --git a/asoc/codecs/wcd934x/Android.mk b/asoc/codecs/wcd934x/Android.mk new file mode 100644 index 000000000000..627d04f2cc0f --- /dev/null +++ b/asoc/codecs/wcd934x/Android.mk @@ -0,0 +1,54 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,sdm845),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m +endif + +ifeq ($(call is-board-platform,sdm670),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,sdm845 sdm670),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=wcd934x_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd934x.ko +LOCAL_MODULE_KBUILD_NAME := wcd934x_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild new file mode 100644 index 000000000000..6bc854c84787 --- /dev/null +++ b/asoc/codecs/wcd934x/Kbuild @@ -0,0 +1,105 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +KERNEL_BUILD := 0 + + +ifeq ($(KERNEL_BUILD), 0) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + ifeq ($(CONFIG_ARCH_SDM845), y) + include $(AUDIO_ROOT)/config/sdm845auto.conf + export + endif + ifeq ($(CONFIG_ARCH_SDM670), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + endif +endif + + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ WCD934X ############ + +# for WCD934X Codec +ifeq ($(CONFIG_SND_SOC_WCD934X), m) + WCD934X_OBJS += wcd934x.o + WCD934X_OBJS += wcd934x-dsp-cntl.o + WCD934X_OBJS += wcd934x-mbhc.o + WCD934X_OBJS += wcd934x-dsd.o +endif + +LINUX_INC += -Iinclude/linux + +INCS := $(COMMON_INC) \ + $(UAPI_INC) + +ifeq ($(CONFIG_ARCH_SDM845), y) +INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h +endif +ifeq ($(CONFIG_ARCH_SDM670), y) +INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h +endif + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + + +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_WCD934X) += wcd934x_dlkm.o +wcd934x_dlkm-y := $(WCD934X_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/msm-audio-effects-q6-v2.c b/asoc/msm-audio-effects-q6-v2.c index 2385bac36f36..5bab856d2290 100644 --- a/asoc/msm-audio-effects-q6-v2.c +++ b/asoc/msm-audio-effects-q6-v2.c @@ -37,6 +37,11 @@ do { \ } while (0) +/** + * msm_audio_effects_is_effmodule_supp_in_top - + * Checks if given topology and module in effects + * + */ bool msm_audio_effects_is_effmodule_supp_in_top(int effect_module, int topology) { @@ -56,6 +61,7 @@ bool msm_audio_effects_is_effmodule_supp_in_top(int effect_module, return false; } } +EXPORT_SYMBOL(msm_audio_effects_is_effmodule_supp_in_top); int msm_audio_effects_enable_extn(struct audio_client *ac, struct msm_nt_eff_all_config *effects, @@ -102,6 +108,16 @@ int msm_audio_effects_enable_extn(struct audio_client *ac, return rc; } +/** + * msm_audio_effects_virtualizer_handler - + * Audio effects handler for virtualizer + * + * @ac: audio client handle + * @pbe: virtualizer params + * @values: values to be updated + * + * Return 0 on success or error on failure + */ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, struct virtualizer_params *virtualizer, long *values) @@ -263,7 +279,18 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, kfree(params); return rc; } +EXPORT_SYMBOL(msm_audio_effects_virtualizer_handler); +/** + * msm_audio_effects_reverb_handler - + * Audio effects handler for reverb + * + * @ac: audio client handle + * @pbe: reverb params + * @values: values to be updated + * + * Return 0 on success or error on failure + */ int msm_audio_effects_reverb_handler(struct audio_client *ac, struct reverb_params *reverb, long *values) @@ -733,7 +760,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, kfree(params); return rc; } +EXPORT_SYMBOL(msm_audio_effects_reverb_handler); +/** + * msm_audio_effects_bass_boost_handler - + * Audio effects handler for bass_boost + * + * @ac: audio client handle + * @bass_boost: bass_boost params + * @values: values to be updated + * + * Return 0 on success or error on failure + */ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, struct bass_boost_params *bass_boost, long *values) @@ -868,7 +906,18 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, kfree(params); return rc; } +EXPORT_SYMBOL(msm_audio_effects_bass_boost_handler); +/** + * msm_audio_effects_pbe_handler - + * Audio effects handler for pbe + * + * @ac: audio client handle + * @pbe: pbe params + * @values: values to be updated + * + * Return 0 on success or error on failure + */ int msm_audio_effects_pbe_handler(struct audio_client *ac, struct pbe_params *pbe, long *values) @@ -975,7 +1024,18 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, kfree(params); return rc; } +EXPORT_SYMBOL(msm_audio_effects_pbe_handler); +/** + * msm_audio_effects_popless_eq_handler - + * Audio effects handler for popless equalizer + * + * @ac: audio client handle + * @eq: equalizer params + * @values: values to be updated + * + * Return 0 on success or error on failure + */ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, struct eq_params *eq, long *values) @@ -1207,6 +1267,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, kfree(params); return rc; } +EXPORT_SYMBOL(msm_audio_effects_popless_eq_handler); static int __msm_audio_effects_volume_handler(struct audio_client *ac, struct soft_volume_params *vol, @@ -1370,9 +1431,21 @@ int msm_audio_effects_volume_handler(struct audio_client *ac, SOFT_VOLUME_INSTANCE_1); } +/** + * msm_audio_effects_volume_handler_v2 - + * Audio effects handler for volume + * + * @ac: audio client handle + * @vol: volume params + * @values: values to be updated + * @instance: instance to update + * + * Return 0 on success or error on failure + */ int msm_audio_effects_volume_handler_v2(struct audio_client *ac, struct soft_volume_params *vol, long *values, int instance) { return __msm_audio_effects_volume_handler(ac, vol, values, instance); } +EXPORT_SYMBOL(msm_audio_effects_volume_handler_v2); diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index cd9c28195b87..b30c42438ae9 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -4541,17 +4541,15 @@ static struct platform_driver msm_compr_driver = { .remove = msm_compr_remove, }; -static int __init msm_soc_platform_init(void) +int __init msm_compress_dsp_init(void) { return platform_driver_register(&msm_compr_driver); } -module_init(msm_soc_platform_init); -static void __exit msm_soc_platform_exit(void) +void __exit msm_compress_dsp_exit(void) { platform_driver_unregister(&msm_compr_driver); } -module_exit(msm_soc_platform_exit); MODULE_DESCRIPTION("Compress Offload platform driver"); MODULE_LICENSE("GPL v2"); diff --git a/asoc/msm-cpe-lsm.c b/asoc/msm-cpe-lsm.c index 87297ec05104..637778491e22 100644 --- a/asoc/msm-cpe-lsm.c +++ b/asoc/msm-cpe-lsm.c @@ -3335,8 +3335,19 @@ static struct platform_driver msm_cpe_lsm_driver = { .probe = msm_cpe_lsm_probe, .remove = msm_cpe_lsm_remove, }; -module_platform_driver(msm_cpe_lsm_driver); +int __init msm_cpe_lsm_init(void) +{ + return platform_driver_register(&msm_cpe_lsm_driver); +} + +void __exit msm_cpe_lsm_exit(void) +{ + platform_driver_unregister(&msm_cpe_lsm_driver); +} + +module_init(msm_cpe_lsm_init); +module_exit(msm_cpe_lsm_exit); MODULE_DESCRIPTION("CPE LSM platform driver"); MODULE_DEVICE_TABLE(of, msm_cpe_lsm_dt_match); MODULE_LICENSE("GPL v2"); diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index 89a9cc24a2e0..c988eeec2c40 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -2698,17 +2698,15 @@ static struct platform_driver msm_fe_dai_driver = { }, }; -static int __init msm_fe_dai_init(void) +int __init msm_fe_dai_init(void) { return platform_driver_register(&msm_fe_dai_driver); } -module_init(msm_fe_dai_init); -static void __exit msm_fe_dai_exit(void) +void __exit msm_fe_dai_exit(void) { platform_driver_unregister(&msm_fe_dai_driver); } -module_exit(msm_fe_dai_exit); /* Module information */ MODULE_DESCRIPTION("MSM Frontend DAI driver"); diff --git a/asoc/msm-dai-q6-hdmi-v2.c b/asoc/msm-dai-q6-hdmi-v2.c index 212c4e3274fb..eb9f5f5de8ad 100644 --- a/asoc/msm-dai-q6-hdmi-v2.c +++ b/asoc/msm-dai-q6-hdmi-v2.c @@ -538,17 +538,15 @@ static struct platform_driver msm_dai_q6_hdmi_driver = { }, }; -static int __init msm_dai_q6_hdmi_init(void) +int __init msm_dai_q6_hdmi_init(void) { return platform_driver_register(&msm_dai_q6_hdmi_driver); } -module_init(msm_dai_q6_hdmi_init); -static void __exit msm_dai_q6_hdmi_exit(void) +void __exit msm_dai_q6_hdmi_exit(void) { platform_driver_unregister(&msm_dai_q6_hdmi_driver); } -module_exit(msm_dai_q6_hdmi_exit); /* Module information */ MODULE_DESCRIPTION("MSM DSP HDMI DAI driver"); diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index cfe47ed6fae0..70fcadcdb3c0 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -8857,7 +8857,7 @@ static struct platform_driver msm_dai_q6_tdm_driver = { }, }; -static int __init msm_dai_q6_init(void) +int __init msm_dai_q6_init(void) { int rc; @@ -8927,16 +8927,17 @@ static int __init msm_dai_q6_init(void) fail: return rc; } -module_init(msm_dai_q6_init); -static void __exit msm_dai_q6_exit(void) +void __exit msm_dai_q6_exit(void) { + platform_driver_unregister(&msm_dai_q6_tdm_driver); + platform_driver_unregister(&msm_dai_q6_spdif_driver); + platform_driver_unregister(&msm_dai_mi2s_q6); + platform_driver_unregister(&msm_dai_q6_mi2s_driver); platform_driver_unregister(&msm_dai_q6_dev); platform_driver_unregister(&msm_dai_q6); platform_driver_unregister(&msm_auxpcm_dev_driver); - platform_driver_unregister(&msm_dai_q6_spdif_driver); } -module_exit(msm_dai_q6_exit); /* Module information */ MODULE_DESCRIPTION("MSM DSP DAI driver"); diff --git a/asoc/msm-dai-slim.c b/asoc/msm-dai-slim.c index 0e7c7b1c4883..427fd6ce8c43 100644 --- a/asoc/msm-dai-slim.c +++ b/asoc/msm-dai-slim.c @@ -642,7 +642,7 @@ static struct slim_driver msm_dai_slim_driver = { .id_table = msm_dai_slim_dt_match, }; -static int __init msm_dai_slim_init(void) +int __init msm_dai_slim_init(void) { int rc; @@ -652,12 +652,11 @@ static int __init msm_dai_slim_init(void) __func__, rc); return rc; } -module_init(msm_dai_slim_init); -static void __exit msm_dai_slim_exit(void) +void __exit msm_dai_slim_exit(void) { + slim_driver_unregister(&msm_dai_slim_driver); } -module_exit(msm_dai_slim_exit); /* Module information */ MODULE_DESCRIPTION("Slimbus apps-owned channel handling driver"); diff --git a/asoc/msm-dai-stub-v2.c b/asoc/msm-dai-stub-v2.c index 3a2c3d3dbbcf..d4178c895cc4 100644 --- a/asoc/msm-dai-stub-v2.c +++ b/asoc/msm-dai-stub-v2.c @@ -354,7 +354,7 @@ static struct platform_driver msm_dai_stub_driver = { }, }; -static int __init msm_dai_stub_init(void) +int __init msm_dai_stub_init(void) { int rc = 0; @@ -378,16 +378,14 @@ static int __init msm_dai_stub_init(void) fail: return rc; } -module_init(msm_dai_stub_init); -static void __exit msm_dai_stub_exit(void) +void __exit msm_dai_stub_exit(void) { pr_debug("%s:\n", __func__); platform_driver_unregister(&msm_dai_stub_dev); platform_driver_unregister(&msm_dai_stub_driver); } -module_exit(msm_dai_stub_exit); /* Module information */ MODULE_DESCRIPTION("MSM Stub DSP DAI driver"); diff --git a/asoc/msm-ds2-dap-config.c b/asoc/msm-ds2-dap-config.c index 7381e5d8c362..419da8fa20c0 100644 --- a/asoc/msm-ds2-dap-config.c +++ b/asoc/msm-ds2-dap-config.c @@ -2269,7 +2269,7 @@ static int msm_ds2_dap_param_visualizer_control_get( static int msm_ds2_dap_set_security_control(u32 cmd, void *arg) { - return 0 + return 0; } static int msm_ds2_dap_update_dev_map_port_id(int32_t device_id, int port_id) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 339125e2d775..15cdfb155f36 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -2401,17 +2401,15 @@ static struct platform_driver msm_lsm_driver = { .remove = msm_lsm_remove, }; -static int __init msm_soc_platform_init(void) +int __init msm_lsm_client_init(void) { return platform_driver_register(&msm_lsm_driver); } -module_init(msm_soc_platform_init); -static void __exit msm_soc_platform_exit(void) +void __exit msm_lsm_client_exit(void) { platform_driver_unregister(&msm_lsm_driver); } -module_exit(msm_soc_platform_exit); MODULE_DESCRIPTION("LSM client platform driver"); MODULE_DEVICE_TABLE(of, msm_lsm_client_dt_match); diff --git a/asoc/msm-pcm-afe-v2.c b/asoc/msm-pcm-afe-v2.c index 102fad8b3278..f700f0bf8a10 100644 --- a/asoc/msm-pcm-afe-v2.c +++ b/asoc/msm-pcm-afe-v2.c @@ -904,19 +904,17 @@ static struct platform_driver msm_afe_driver = { .remove = msm_afe_remove, }; -static int __init msm_soc_platform_init(void) +int __init msm_pcm_afe_init(void) { pr_debug("%s\n", __func__); return platform_driver_register(&msm_afe_driver); } -module_init(msm_soc_platform_init); -static void __exit msm_soc_platform_exit(void) +void __exit msm_pcm_afe_exit(void) { pr_debug("%s\n", __func__); platform_driver_unregister(&msm_afe_driver); } -module_exit(msm_soc_platform_exit); MODULE_DESCRIPTION("AFE PCM module platform driver"); MODULE_LICENSE("GPL v2"); diff --git a/asoc/msm-pcm-dtmf-v2.c b/asoc/msm-pcm-dtmf-v2.c index c387c7d0aab4..7bc823bebf7b 100644 --- a/asoc/msm-pcm-dtmf-v2.c +++ b/asoc/msm-pcm-dtmf-v2.c @@ -580,17 +580,15 @@ static struct platform_driver msm_pcm_driver = { .remove = msm_pcm_remove, }; -static int __init msm_soc_platform_init(void) +int __init msm_pcm_dtmf_init(void) { return platform_driver_register(&msm_pcm_driver); } -module_init(msm_soc_platform_init); -static void __exit msm_soc_platform_exit(void) +void __exit msm_pcm_dtmf_exit(void) { platform_driver_unregister(&msm_pcm_driver); } -module_exit(msm_soc_platform_exit); MODULE_DESCRIPTION("DTMF platform driver"); MODULE_LICENSE("GPL v2"); diff --git a/asoc/msm-pcm-host-voice-v2.c b/asoc/msm-pcm-host-voice-v2.c index 55b07bc75823..0c47ec11338a 100644 --- a/asoc/msm-pcm-host-voice-v2.c +++ b/asoc/msm-pcm-host-voice-v2.c @@ -1504,7 +1504,7 @@ static struct platform_driver msm_pcm_driver = { .remove = msm_pcm_remove, }; -static int __init msm_soc_platform_init(void) +int __init msm_voice_host_init(void) { int i = 0; struct session *s = NULL; @@ -1541,13 +1541,11 @@ static int __init msm_soc_platform_init(void) return platform_driver_register(&msm_pcm_driver); } -module_init(msm_soc_platform_init); -static void __exit msm_soc_platform_exit(void) +void __exit msm_voice_host_exit(void) { platform_driver_unregister(&msm_pcm_driver); } -module_exit(msm_soc_platform_exit); MODULE_DESCRIPTION("PCM module platform driver"); MODULE_LICENSE("GPL v2"); diff --git a/asoc/msm-pcm-hostless.c b/asoc/msm-pcm-hostless.c index 35766b44981c..90d76b49f654 100644 --- a/asoc/msm-pcm-hostless.c +++ b/asoc/msm-pcm-hostless.c @@ -66,17 +66,15 @@ static struct platform_driver msm_pcm_hostless_driver = { .remove = msm_pcm_hostless_remove, }; -static int __init msm_soc_platform_init(void) +int __init msm_pcm_hostless_init(void) { return platform_driver_register(&msm_pcm_hostless_driver); } -module_init(msm_soc_platform_init); -static void __exit msm_soc_platform_exit(void) +void __exit msm_pcm_hostless_exit(void) { platform_driver_unregister(&msm_pcm_hostless_driver); } -module_exit(msm_soc_platform_exit); MODULE_DESCRIPTION("Hostless platform driver"); MODULE_LICENSE("GPL v2"); diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index a6ac8ca006fa..e50a00575d95 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -785,17 +785,15 @@ static struct platform_driver msm_pcm_driver = { .remove = msm_pcm_remove, }; -static int __init msm_soc_platform_init(void) +int __init msm_pcm_loopback_init(void) { return platform_driver_register(&msm_pcm_driver); } -module_init(msm_soc_platform_init); -static void __exit msm_soc_platform_exit(void) +void __exit msm_pcm_loopback_exit(void) { platform_driver_unregister(&msm_pcm_driver); } -module_exit(msm_soc_platform_exit); MODULE_DESCRIPTION("PCM loopback platform driver"); MODULE_LICENSE("GPL v2"); diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index 3e03437abcf6..307e7a6fae65 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -1252,33 +1252,31 @@ static int msm_pcm_remove(struct platform_device *pdev) snd_soc_unregister_platform(&pdev->dev); return 0; } -static const struct of_device_id msm_pcm_dt_match[] = { +static const struct of_device_id msm_pcm_noirq_dt_match[] = { {.compatible = "qcom,msm-pcm-dsp-noirq"}, {} }; -MODULE_DEVICE_TABLE(of, msm_pcm_dt_match); +MODULE_DEVICE_TABLE(of, msm_pcm_noirq_dt_match); static struct platform_driver msm_pcm_driver_noirq = { .driver = { .name = "msm-pcm-dsp-noirq", .owner = THIS_MODULE, - .of_match_table = msm_pcm_dt_match, + .of_match_table = msm_pcm_noirq_dt_match, }, .probe = msm_pcm_probe, .remove = msm_pcm_remove, }; -static int __init msm_soc_platform_init(void) +int __init msm_pcm_noirq_init(void) { return platform_driver_register(&msm_pcm_driver_noirq); } -module_init(msm_soc_platform_init); -static void __exit msm_soc_platform_exit(void) +void __exit msm_pcm_noirq_exit(void) { platform_driver_unregister(&msm_pcm_driver_noirq); } -module_exit(msm_soc_platform_exit); MODULE_DESCRIPTION("PCM NOIRQ module platform driver"); MODULE_LICENSE("GPL v2"); diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 4910decf6d8b..0a0e26d8b0a2 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1863,7 +1863,7 @@ static struct platform_driver msm_pcm_driver = { .remove = msm_pcm_remove, }; -static int __init msm_soc_platform_init(void) +int __init msm_pcm_dsp_init(void) { init_waitqueue_head(&the_locks.enable_wait); init_waitqueue_head(&the_locks.eos_wait); @@ -1872,13 +1872,11 @@ static int __init msm_soc_platform_init(void) return platform_driver_register(&msm_pcm_driver); } -module_init(msm_soc_platform_init); -static void __exit msm_soc_platform_exit(void) +void __exit msm_pcm_dsp_exit(void) { platform_driver_unregister(&msm_pcm_driver); } -module_exit(msm_soc_platform_exit); MODULE_DESCRIPTION("PCM module platform driver"); MODULE_LICENSE("GPL v2"); diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 3338ac6834a5..965518bdae33 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include @@ -17781,7 +17781,7 @@ static int msm_routing_init_cal_data(void) return ret; } -static int __init msm_soc_routing_platform_init(void) +int __init msm_soc_routing_platform_init(void) { mutex_init(&routing_lock); if (msm_routing_init_cal_data()) @@ -17795,16 +17795,14 @@ static int __init msm_soc_routing_platform_init(void) return platform_driver_register(&msm_routing_pcm_driver); } -module_init(msm_soc_routing_platform_init); -static void __exit msm_soc_routing_platform_exit(void) +void __exit msm_soc_routing_platform_exit(void) { msm_routing_delete_cal_data(); memset(&be_dai_name_table, 0, sizeof(be_dai_name_table)); mutex_destroy(&routing_lock); platform_driver_unregister(&msm_routing_pcm_driver); } -module_exit(msm_soc_routing_platform_exit); MODULE_DESCRIPTION("MSM routing platform driver"); MODULE_LICENSE("GPL v2"); diff --git a/asoc/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c index 9972132000e9..7b236b4f0489 100644 --- a/asoc/msm-pcm-voice-v2.c +++ b/asoc/msm-pcm-voice-v2.c @@ -758,7 +758,7 @@ static struct platform_driver msm_pcm_driver = { .remove = msm_pcm_remove, }; -static int __init msm_soc_platform_init(void) +int __init msm_pcm_voice_init(void) { int i = 0; @@ -769,13 +769,11 @@ static int __init msm_soc_platform_init(void) return platform_driver_register(&msm_pcm_driver); } -module_init(msm_soc_platform_init); -static void __exit msm_soc_platform_exit(void) +void __exit msm_pcm_voice_exit(void) { platform_driver_unregister(&msm_pcm_driver); } -module_exit(msm_soc_platform_exit); MODULE_DESCRIPTION("Voice PCM module platform driver"); MODULE_LICENSE("GPL v2"); diff --git a/asoc/msm-pcm-voip-v2.c b/asoc/msm-pcm-voip-v2.c index 86dcacacbaa3..58fc534f1cb0 100644 --- a/asoc/msm-pcm-voip-v2.c +++ b/asoc/msm-pcm-voip-v2.c @@ -1684,7 +1684,7 @@ static struct platform_driver msm_pcm_driver = { .remove = msm_pcm_remove, }; -static int __init msm_soc_platform_init(void) +int __init msm_pcm_voip_init(void) { memset(&voip_info, 0, sizeof(voip_info)); voip_info.mode = MODE_PCM; @@ -1703,13 +1703,11 @@ static int __init msm_soc_platform_init(void) return platform_driver_register(&msm_pcm_driver); } -module_init(msm_soc_platform_init); -static void __exit msm_soc_platform_exit(void) +void __exit msm_pcm_voip_exit(void) { platform_driver_unregister(&msm_pcm_driver); } -module_exit(msm_soc_platform_exit); MODULE_DESCRIPTION("PCM module platform driver"); MODULE_LICENSE("GPL v2"); diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index eaef498c49b7..94ebbf748a92 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -951,20 +951,18 @@ static struct platform_driver msm_transcode_loopback_driver = { .remove = msm_transcode_remove, }; -static int __init msm_soc_platform_init(void) +int __init msm_transcode_loopback_init(void) { memset(&transcode_info, 0, sizeof(struct msm_transcode_loopback)); mutex_init(&transcode_info.lock); return platform_driver_register(&msm_transcode_loopback_driver); } -module_init(msm_soc_platform_init); -static void __exit msm_soc_platform_exit(void) +void __exit msm_transcode_loopback_exit(void) { mutex_destroy(&transcode_info.lock); platform_driver_unregister(&msm_transcode_loopback_driver); } -module_exit(msm_soc_platform_exit); MODULE_DESCRIPTION("Transcode loopback platform driver"); MODULE_LICENSE("GPL v2"); diff --git a/asoc/platform_init.c b/asoc/platform_init.c new file mode 100644 index 000000000000..79d0e41998f5 --- /dev/null +++ b/asoc/platform_init.c @@ -0,0 +1,69 @@ +/* +Copyright (c) 2017, The Linux Foundation. All rights reserved. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2 and +only version 2 as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +* +*/ + +#include +#include +#include "platform_init.h" + +static int __init audio_platform_init(void) +{ + msm_compress_dsp_init(); + msm_fe_dai_init(); + msm_dai_q6_hdmi_init(); + msm_dai_q6_init(); + msm_dai_slim_init(); + msm_dai_stub_init(); + msm_lsm_client_init(); + msm_pcm_afe_init(); + msm_pcm_dtmf_init(); + msm_pcm_hostless_init(); + msm_voice_host_init(); + msm_pcm_loopback_init(); + msm_pcm_noirq_init(); + msm_pcm_dsp_init(); + msm_soc_routing_platform_init(); + msm_pcm_voice_init(); + msm_pcm_voip_init(); + msm_transcode_loopback_init(); + + return 0; +} + +static void audio_platform_exit(void) +{ + msm_transcode_loopback_exit(); + msm_pcm_voip_exit(); + msm_pcm_voice_exit(); + msm_soc_routing_platform_exit(); + msm_pcm_dsp_exit(); + msm_pcm_noirq_exit(); + msm_pcm_loopback_exit(); + msm_voice_host_exit(); + msm_pcm_hostless_exit(); + msm_pcm_dtmf_exit(); + msm_pcm_afe_exit(); + msm_lsm_client_exit(); + msm_dai_stub_exit(); + msm_dai_slim_exit(); + msm_dai_q6_exit(); + msm_dai_q6_hdmi_exit(); + msm_fe_dai_exit(); + msm_compress_dsp_exit(); +} + +module_init(audio_platform_init); +module_exit(audio_platform_exit); + +MODULE_DESCRIPTION("Audio Platform driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/platform_init.h b/asoc/platform_init.h new file mode 100644 index 000000000000..db9b32d2ee5c --- /dev/null +++ b/asoc/platform_init.h @@ -0,0 +1,58 @@ +/* +Copyright (c) 2017, The Linux Foundation. All rights reserved. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2 and +only version 2 as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +* +*/ + +#ifndef __PLATFORM_INIT_H__ +#define __PLATFORM_INIT_H__ +int msm_compress_dsp_init(void); +int msm_fe_dai_init(void); +int msm_dai_q6_hdmi_init(void); +int msm_dai_q6_init(void); +int msm_dai_slim_init(void); +int msm_dai_stub_init(void); +int msm_lsm_client_init(void); +int msm_pcm_afe_init(void); +int msm_pcm_dtmf_init(void); +int msm_pcm_hostless_init(void); +int msm_voice_host_init(void); +int msm_pcm_loopback_init(void); +int msm_pcm_noirq_init(void); +int msm_pcm_dsp_init(void); +int msm_soc_routing_platform_init(void); +int msm_pcm_voice_init(void); +int msm_pcm_voip_init(void); +int msm_transcode_loopback_init(void); +int msm_cpe_lsm_init(void); + +void msm_cpe_lsm_exit(void); +void msm_transcode_loopback_exit(void); +void msm_pcm_voip_exit(void); +void msm_pcm_voice_exit(void); +void msm_soc_routing_platform_exit(void); +void msm_pcm_dsp_exit(void); +void msm_pcm_noirq_exit(void); +void msm_pcm_loopback_exit(void); +void msm_voice_host_exit(void); +void msm_pcm_hostless_exit(void); +void msm_pcm_dtmf_exit(void); +void msm_pcm_afe_exit(void); +void msm_lsm_client_exit(void); +void msm_dai_stub_exit(void); +void msm_dai_slim_exit(void); +void msm_dai_q6_exit(void); +void msm_dai_q6_hdmi_exit(void); +void msm_fe_dai_exit(void); +void msm_compress_dsp_exit(void); + +#endif + diff --git a/config/sdm670auto.conf b/config/sdm670auto.conf index ca30dd039e7d..07f195b28f7b 100644 --- a/config/sdm670auto.conf +++ b/config/sdm670auto.conf @@ -1,49 +1,50 @@ -CONFIG_PINCTRL_LPI=y -CONFIG_PINCTRL_WCD=y -CONFIG_AUDIO_EXT_CLK=y -CONFIG_SND_SOC_WCD9XXX_V2=y -CONFIG_SND_SOC_WCD_MBHC=y -CONFIG_SND_SOC_WSA881X=y -CONFIG_SND_SOC_WCD_DSP_MGR=y -CONFIG_SND_SOC_WCD_SPI=y -CONFIG_SND_SOC_WCD_CPE=y -CONFIG_SND_SOC_WCD9335=y -CONFIG_SND_SOC_WCD934X=y -CONFIG_SND_SOC_WCD934X_MBHC=y -CONFIG_SND_SOC_WCD934X_DSD=y -CONFIG_MSM_QDSP6V2_CODECS=y -CONFIG_MSM_ULTRASOUND=y -CONFIG_MSM_QDSP6_APRV2_GLINK=y -CONFIG_MSM_ADSP_LOADER=y -CONFIG_REGMAP_SWR=y -CONFIG_MSM_QDSP6_SSR=y -CONFIG_MSM_QDSP6_PDR=y -CONFIG_MSM_QDSP6_NOTIFIER=y -CONFIG_SND_SOC_MSM_HOSTLESS_PCM=y -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y -CONFIG_SND_SOC_SDM670=y -CONFIG_MSM_GLINK_SPI_XPRT=y -CONFIG_SOUNDWIRE=y -CONFIG_SOUNDWIRE_WCD_CTRL=y -CONFIG_SND_SOC_QDSP6V2=y -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y -CONFIG_WCD9XXX_CODEC_CORE=y -CONFIG_MSM_CDC_PINCTRL=y -CONFIG_SND_SOC_WCD_MBHC_ADC=y -CONFIG_SND_SOC_WCD_MBHC_LEGACY=y -CONFIG_QTI_PP=y -CONFIG_SND_HWDEP=y -CONFIG_DTS_EAGLE=y -CONFIG_DOLBY_DS2=y -CONFIG_DOLBY_LICENSE=y -CONFIG_DTS_SRS_TM=y -CONFIG_SND_SOC_EXT_CODEC=y -CONFIG_SND_SOC_INT_CODEC=y -CONFIG_SND_SOC_MSM_STUB=y -CONFIG_WCD_DSP_GLINK=y -CONFIG_MSM_AVTIMER=y -CONFIG_SND_SOC_SDM660_CDC=y -CONFIG_SND_SOC_ANALOG_CDC=y -CONFIG_SND_SOC_DIGITAL_CDC=y -CONFIG_SND_SOC_MSM_SDW=y -CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y +CONFIG_PINCTRL_LPI=m +CONFIG_PINCTRL_WCD=m +CONFIG_AUDIO_EXT_CLK=m +CONFIG_SND_SOC_WCD9XXX_V2=m +CONFIG_SND_SOC_WCD_MBHC=m +CONFIG_SND_SOC_WSA881X=m +CONFIG_SND_SOC_WCD_DSP_MGR=m +CONFIG_SND_SOC_WCD_SPI=m +CONFIG_SND_SOC_WCD_CPE=m +CONFIG_SND_SOC_CPE=m +CONFIG_SND_SOC_WCD9335=m +CONFIG_SND_SOC_WCD934X=m +CONFIG_SND_SOC_WCD934X_MBHC=m +CONFIG_SND_SOC_WCD934X_DSD=m +CONFIG_MSM_QDSP6V2_CODECS=m +CONFIG_MSM_ULTRASOUND=m +CONFIG_MSM_QDSP6_APRV2_GLINK=m +CONFIG_MSM_ADSP_LOADER=m +CONFIG_REGMAP_SWR=m +CONFIG_MSM_QDSP6_SSR=m +CONFIG_MSM_QDSP6_PDR=m +CONFIG_MSM_QDSP6_NOTIFIER=m +CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +CONFIG_SND_SOC_SDM670=m +CONFIG_MSM_GLINK_SPI_XPRT=m +CONFIG_SOUNDWIRE=m +CONFIG_SOUNDWIRE_WCD_CTRL=m +CONFIG_SND_SOC_QDSP6V2=m +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +CONFIG_WCD9XXX_CODEC_CORE=m +CONFIG_MSM_CDC_PINCTRL=m +CONFIG_SND_SOC_WCD_MBHC_ADC=m +CONFIG_SND_SOC_WCD_MBHC_LEGACY=m +CONFIG_QTI_PP=m +CONFIG_SND_HWDEP=m +CONFIG_DTS_EAGLE=m +CONFIG_DOLBY_DS2=m +CONFIG_DOLBY_LICENSE=m +CONFIG_DTS_SRS_TM=m +CONFIG_SND_SOC_EXT_CODEC=m +CONFIG_SND_SOC_INT_CODEC=m +CONFIG_SND_SOC_MSM_STUB=m +CONFIG_WCD_DSP_GLINK=m +CONFIG_MSM_AVTIMER=m +CONFIG_SND_SOC_SDM660_CDC=m +CONFIG_SND_SOC_ANALOG_CDC=m +CONFIG_SND_SOC_DIGITAL_CDC=m +CONFIG_SND_SOC_MSM_SDW=m +CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m diff --git a/config/sdm670autoconf.h b/config/sdm670autoconf.h index 6aba91d63f8d..462862f31c50 100644 --- a/config/sdm670autoconf.h +++ b/config/sdm670autoconf.h @@ -55,6 +55,7 @@ #define CONFIG_MSM_AVTIMER 1 #define CONFIG_SND_SOC_EXT_CODEC 1 #define CONFIG_SND_SOC_INT_CODEC 1 +#define CONFIG_SND_SOC_CPE 1 #define CONFIG_SND_SOC_SDM660_CDC 1 #define CONFIG_SND_SOC_ANALOG_CDC 1 #define CONFIG_SND_SOC_DIGITAL_CDC 1 diff --git a/dsp/Android.mk b/dsp/Android.mk new file mode 100644 index 000000000000..428901cac75a --- /dev/null +++ b/dsp/Android.mk @@ -0,0 +1,86 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,sdm845),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m +endif + +ifeq ($(call is-board-platform,sdm670),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,sdm845 sdm670),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=q6_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_q6.ko +LOCAL_MODULE_KBUILD_NAME := q6_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_usf.ko +LOCAL_MODULE_KBUILD_NAME := usf_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_adsp_loader.ko +LOCAL_MODULE_KBUILD_NAME := adsp_loader_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_q6_notifier.ko +LOCAL_MODULE_KBUILD_NAME := q6_notifier_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_q6_pdr.ko +LOCAL_MODULE_KBUILD_NAME := q6_pdr_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/dsp/Kbuild b/dsp/Kbuild new file mode 100644 index 000000000000..87720854379c --- /dev/null +++ b/dsp/Kbuild @@ -0,0 +1,149 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +KERNEL_BUILD := 0 + + +ifeq ($(KERNEL_BUILD), 0) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + ifeq ($(CONFIG_ARCH_SDM845), y) + include $(AUDIO_ROOT)/config/sdm845auto.conf + export + endif + ifeq ($(CONFIG_ARCH_SDM670), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + endif +endif + + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ QDSP6V2 ############ + +ifeq ($(CONFIG_SND_SOC_MSM_QDSP6V2_INTF), m) + Q6_OBJS += audio_calibration.o + Q6_OBJS += audio_cal_utils.o + Q6_OBJS += msm-dts-srs-tm-config.o + Q6_OBJS += q6adm.o + Q6_OBJS += q6afe.o + Q6_OBJS += q6asm.o + Q6_OBJS += q6audio-v2.o + Q6_OBJS += q6voice.o + Q6_OBJS += q6core.o + Q6_OBJS += rtac.o + Q6_OBJS += q6lsm.o + Q6_OBJS += audio_slimslave.o + Q6_OBJS += adsp_err.o + Q6_OBJS += msm_audio_ion.o + Q6_OBJS += avtimer.o + Q6_OBJS += q6_init.o +endif +ifeq ($(CONFIG_MSM_ADSP_LOADER), m) +ADSP_LOADER_OBJS += adsp-loader.o +endif + +ifeq ($(CONFIG_MSM_QDSP6_NOTIFIER), m) +QDSP6_NOTIFIER_OBJS += audio_notifier.o audio_ssr.o +endif + +ifeq ($(CONFIG_MSM_QDSP6_PDR), m) +QDSP6_PDR_OBJS += audio_pdr.o +endif + +ifeq ($(CONFIG_MSM_ULTRASOUND), m) +USF_OBJS += usf.o usfcdev.o q6usm.o +endif + +LINUX_INC += -Iinclude/linux + +INCS := $(COMMON_INC) \ + $(UAPI_INC) + +ifeq ($(CONFIG_ARCH_SDM845), y) +INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h +endif +ifeq ($(CONFIG_ARCH_SDM670), y) +INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h +endif + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +# If the module name is not "wlan", then the define MULTI_IF_NAME to be the +# same a the QCA CHIP name. The host driver will then append MULTI_IF_NAME to +# any string that must be unique for all instances of the driver on the system. +# This allows multiple instances of the driver with different module names. +# If the module name is wlan, leave MULTI_IF_NAME undefined and the code will +# treat the driver as the primary driver. +ifneq ($(MODNAME), qdsp6v2) +CHIP_NAME ?= $(MODNAME) +CDEFINES += -DMULTI_IF_NAME=\"$(CHIP_NAME)\" +endif + +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers + +obj-$(CONFIG_SND_SOC_MSM_QDSP6V2_INTF) += q6_dlkm.o +q6_dlkm-y := $(Q6_OBJS) + +obj-$(CONFIG_MSM_ULTRASOUND) += usf_dlkm.o +usf_dlkm-y := $(USF_OBJS) + +obj-$(CONFIG_MSM_ADSP_LOADER) += adsp_loader_dlkm.o +adsp_loader_dlkm-y := $(ADSP_LOADER_OBJS) + +obj-$(CONFIG_MSM_QDSP6_NOTIFIER) += q6_notifier_dlkm.o +q6_notifier_dlkm-y := $(QDSP6_NOTIFIER_OBJS) + +obj-$(CONFIG_MSM_QDSP6_PDR) += q6_pdr_dlkm.o +q6_pdr_dlkm-y := $(QDSP6_PDR_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/dsp/adsp_err.c b/dsp/adsp_err.c index 319efc37cfe1..7ad80dc6ecc3 100644 --- a/dsp/adsp_err.c +++ b/dsp/adsp_err.c @@ -63,7 +63,7 @@ /* Unexpected error code. */ #define ADSP_ERR_MAX_STR "ADSP_ERR_MAX" -#ifdef CONFIG_SND_SOC_QDSP_DEBUG +#if IS_ENABLED(CONFIG_SND_SOC_QDSP_DEBUG) static bool adsp_err_panic; #ifdef CONFIG_DEBUG_FS @@ -123,7 +123,7 @@ static struct adsp_err_code adsp_err_code_info[ADSP_ERR_MAX+1] = { { -EADV, ADSP_ERR_MAX_STR}, }; -#ifdef CONFIG_SND_SOC_QDSP_DEBUG +#if IS_ENABLED(CONFIG_SND_SOC_QDSP_DEBUG) static inline void adsp_err_check_panic(u32 adsp_error) { if (adsp_err_panic && adsp_error != ADSP_EALREADY) @@ -151,8 +151,8 @@ char *adsp_err_get_err_str(u32 adsp_error) return adsp_err_code_info[adsp_error].adsp_err_str; } -#if defined(CONFIG_SND_SOC_QDSP_DEBUG) && defined(CONFIG_DEBUG_FS) -static int __init adsp_err_init(void) +#if IS_ENABLED(CONFIG_SND_SOC_QDSP_DEBUG) && defined(CONFIG_DEBUG_FS) +int __init adsp_err_init(void) { @@ -162,6 +162,12 @@ static int __init adsp_err_init(void) return 0; } +#else +int __init adsp_err_init(void) { return 0; } -device_initcall(adsp_err_init); #endif + +void __exit adsp_err_exit(void) +{ + return; +} diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index 9a9a96aade7d..ffd3929dd3d5 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -481,6 +481,14 @@ static void destroy_cal_type_data(struct cal_type_data *cal_type) return; } +/** + * cal_utils_destroy_cal_types - + * Destroys cal types and deregister from cal info + * + * @num_cal_types: number of cal types + * @cal_type: cal type pointer with cal info + * + */ void cal_utils_destroy_cal_types(int num_cal_types, struct cal_type_data **cal_type) { @@ -506,6 +514,7 @@ void cal_utils_destroy_cal_types(int num_cal_types, done: return; } +EXPORT_SYMBOL(cal_utils_destroy_cal_types); /** * cal_utils_get_only_cal_block diff --git a/dsp/audio_calibration.c b/dsp/audio_calibration.c index 59fd464fe061..f812c98ab1f6 100644 --- a/dsp/audio_calibration.c +++ b/dsp/audio_calibration.c @@ -593,7 +593,7 @@ struct miscdevice audio_cal_misc = { .fops = &audio_cal_fops, }; -static int __init audio_cal_init(void) +int __init audio_cal_init(void) { int i = 0; @@ -609,7 +609,7 @@ static int __init audio_cal_init(void) return misc_register(&audio_cal_misc); } -static void __exit audio_cal_exit(void) +void __exit audio_cal_exit(void) { int i = 0; struct list_head *ptr, *next; @@ -627,10 +627,9 @@ static void __exit audio_cal_exit(void) client_info_node = NULL; } } + misc_deregister(&audio_cal_misc); } -subsys_initcall(audio_cal_init); -module_exit(audio_cal_exit); MODULE_DESCRIPTION("SoC QDSP6v2 Audio Calibration driver"); MODULE_LICENSE("GPL v2"); diff --git a/dsp/audio_notifier.c b/dsp/audio_notifier.c index a1b5d1e6f8bd..485c703d25b1 100644 --- a/dsp/audio_notifier.c +++ b/dsp/audio_notifier.c @@ -12,7 +12,6 @@ #include #include -#include #include #include #include @@ -489,9 +488,6 @@ static int audio_notifer_pdr_adsp_cb(struct notifier_block *this, static int audio_notifer_ssr_adsp_cb(struct notifier_block *this, unsigned long opcode, void *data) { - if (opcode == SUBSYS_BEFORE_SHUTDOWN) - audio_ssr_send_nmi(data); - return audio_notifer_service_cb(opcode, AUDIO_NOTIFIER_SSR_SERVICE, AUDIO_NOTIFIER_ADSP_DOMAIN); @@ -602,35 +598,46 @@ static int __init audio_notifier_subsys_init(void) return 0; } -subsys_initcall(audio_notifier_subsys_init); + +static int __init audio_notifier_late_init(void) +{ + /* + * If pdr registration failed, register clients on next service + * Do in late init to ensure that SSR subsystem is initialized + */ + mutex_lock(¬ifier_mutex); + if (!audio_notifer_is_service_enabled(AUDIO_NOTIFIER_PDR_SERVICE)) + audio_notifer_reg_all_clients(); + + mutex_unlock(¬ifier_mutex); + return 0; +} static int __init audio_notifier_init(void) { int ret; + audio_notifier_subsys_init(); + ret = audio_pdr_register(&pdr_nb); if (ret < 0) { - pr_debug("%s: PDR register failed, ret = %d, disable service\n", + pr_err("%s: PDR register failed, ret = %d, disable service\n", __func__, ret); audio_notifer_disable_service(AUDIO_NOTIFIER_PDR_SERVICE); } /* Do not return error since PDR enablement is not critical */ + audio_notifier_late_init(); + return 0; } module_init(audio_notifier_init); -static int __init audio_notifier_late_init(void) +static void __exit audio_notifier_exit(void) { - /* - * If pdr registration failed, register clients on next service - * Do in late init to ensure that SSR subsystem is initialized - */ - mutex_lock(¬ifier_mutex); - if (!audio_notifer_is_service_enabled(AUDIO_NOTIFIER_PDR_SERVICE)) - audio_notifer_reg_all_clients(); - - mutex_unlock(¬ifier_mutex); - return 0; + audio_pdr_deregister(&pdr_nb); } -late_initcall(audio_notifier_late_init); +module_exit(audio_notifier_exit); + +MODULE_DESCRIPTION("Audio notifier driver"); +MODULE_LICENSE("GPL v2"); diff --git a/dsp/audio_pdr.c b/dsp/audio_pdr.c index 0edcf0233efb..75f3bbb5062b 100644 --- a/dsp/audio_pdr.c +++ b/dsp/audio_pdr.c @@ -63,6 +63,14 @@ static struct notifier_block audio_pdr_locator_nb = { .priority = 0, }; +/** + * audio_pdr_register - + * register to PDR framework + * + * @nb: notifier block + * + * Returns 0 on success or error on failure + */ int audio_pdr_register(struct notifier_block *nb) { if (nb == NULL) { @@ -73,6 +81,24 @@ int audio_pdr_register(struct notifier_block *nb) } EXPORT_SYMBOL(audio_pdr_register); +/** + * audio_pdr_deregister - + * Deregister from PDR framework + * + * @nb: notifier block + * + * Returns 0 on success or error on failure + */ +int audio_pdr_deregister(struct notifier_block *nb) +{ + if (nb == NULL) { + pr_err("%s: Notifier block is NULL\n", __func__); + return -EINVAL; + } + return srcu_notifier_chain_unregister(&audio_pdr_cb_list, nb); +} +EXPORT_SYMBOL(audio_pdr_deregister); + void *audio_pdr_service_register(int domain_id, struct notifier_block *nb, int *curr_state) { @@ -125,12 +151,13 @@ static int __init audio_pdr_subsys_init(void) srcu_init_notifier_head(&audio_pdr_cb_list); return 0; } -subsys_initcall(audio_pdr_subsys_init); static int __init audio_pdr_late_init(void) { int ret; + audio_pdr_subsys_init(); + ret = get_service_location( audio_pdr_services[AUDIO_PDR_DOMAIN_ADSP].client_name, audio_pdr_services[AUDIO_PDR_DOMAIN_ADSP].service_name, @@ -144,4 +171,12 @@ static int __init audio_pdr_late_init(void) return ret; } -late_initcall(audio_pdr_late_init); +module_init(audio_pdr_late_init); + +static void __exit audio_pdr_late_exit(void) +{ +} +module_exit(audio_pdr_late_exit); + +MODULE_DESCRIPTION("PDR framework driver"); +MODULE_LICENSE("GPL v2"); diff --git a/dsp/audio_pdr.h b/dsp/audio_pdr.h index ebfd366b1e44..2a45c6a61fac 100644 --- a/dsp/audio_pdr.h +++ b/dsp/audio_pdr.h @@ -41,6 +41,7 @@ enum { * Failure: Error code */ int audio_pdr_register(struct notifier_block *nb); +int audio_pdr_deregister(struct notifier_block *nb); /* * Use audio_pdr_service_register to register with a PDR service diff --git a/dsp/audio_slimslave.c b/dsp/audio_slimslave.c index e9ecfd5b2e44..f9e9cdc3709e 100644 --- a/dsp/audio_slimslave.c +++ b/dsp/audio_slimslave.c @@ -160,17 +160,15 @@ static struct slim_driver audio_slimslave_driver = { .suspend = audio_slimslave_suspend, }; -static int __init audio_slimslave_init(void) +int __init audio_slimslave_init(void) { return slim_driver_register(&audio_slimslave_driver); } -module_init(audio_slimslave_init); -static void __exit audio_slimslave_exit(void) +void __exit audio_slimslave_exit(void) { } -module_exit(audio_slimslave_exit); /* Module information */ MODULE_DESCRIPTION("Audio side Slimbus slave driver"); diff --git a/dsp/audio_ssr.c b/dsp/audio_ssr.c index d3880c912cfd..b1acb918e0fc 100644 --- a/dsp/audio_ssr.c +++ b/dsp/audio_ssr.c @@ -11,18 +11,24 @@ */ #include -#include #include #include #include "audio_ssr.h" -#define SCM_Q6_NMI_CMD 0x1 - static char *audio_ssr_domains[] = { "adsp", "modem" }; +/** + * audio_ssr_register - + * register to SSR framework + * + * @domain_id: Domain ID to register with + * @nb: notifier block + * + * Returns handle pointer on success or error PTR on failure + */ void *audio_ssr_register(int domain_id, struct notifier_block *nb) { if ((domain_id < 0) || @@ -36,31 +42,18 @@ void *audio_ssr_register(int domain_id, struct notifier_block *nb) } EXPORT_SYMBOL(audio_ssr_register); +/** + * audio_ssr_deregister - + * Deregister handle from SSR framework + * + * @handle: SSR handle + * @nb: notifier block + * + * Returns 0 on success or error on failure + */ int audio_ssr_deregister(void *handle, struct notifier_block *nb) { return subsys_notif_unregister_notifier(handle, nb); } EXPORT_SYMBOL(audio_ssr_deregister); -void audio_ssr_send_nmi(void *ssr_cb_data) -{ - struct notif_data *data = (struct notif_data *)ssr_cb_data; - struct scm_desc desc; - - if (data && data->crashed) { - /* Send NMI to QDSP6 via an SCM call. */ - if (!is_scm_armv8()) { - scm_call_atomic1(SCM_SVC_UTIL, - SCM_Q6_NMI_CMD, 0x1); - } else { - desc.args[0] = 0x1; - desc.arginfo = SCM_ARGS(1); - scm_call2_atomic(SCM_SIP_FNID(SCM_SVC_UTIL, - SCM_Q6_NMI_CMD), &desc); - } - /* The write should go through before q6 is shutdown */ - mb(); - pr_debug("%s: Q6 NMI was sent.\n", __func__); - } -} -EXPORT_SYMBOL(audio_ssr_send_nmi); diff --git a/dsp/avtimer.c b/dsp/avtimer.c index 63044db6e4b9..184e0e9370df 100644 --- a/dsp/avtimer.c +++ b/dsp/avtimer.c @@ -517,7 +517,7 @@ static struct platform_driver dev_avtimer_driver = { }, }; -static int __init avtimer_init(void) +int __init avtimer_init(void) { s32 rc; @@ -535,14 +535,10 @@ static int __init avtimer_init(void) return rc; } -static void __exit avtimer_exit(void) +void __exit avtimer_exit(void) { - pr_debug("%s: avtimer_exit\n", __func__); platform_driver_unregister(&dev_avtimer_driver); } -module_init(avtimer_init); -module_exit(avtimer_exit); - MODULE_DESCRIPTION("avtimer driver"); MODULE_LICENSE("GPL v2"); diff --git a/dsp/codecs/Android.mk b/dsp/codecs/Android.mk new file mode 100644 index 000000000000..865ace12cb00 --- /dev/null +++ b/dsp/codecs/Android.mk @@ -0,0 +1,54 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,sdm845),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m +endif + +ifeq ($(call is-board-platform,sdm670),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,sdm845 sdm670),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=native_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_native.ko +LOCAL_MODULE_KBUILD_NAME := native_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild new file mode 100644 index 000000000000..683f5997bd9c --- /dev/null +++ b/dsp/codecs/Kbuild @@ -0,0 +1,133 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +KERNEL_BUILD := 0 + + +ifeq ($(KERNEL_BUILD), 0) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + ifeq ($(CONFIG_ARCH_SDM845), y) + include $(AUDIO_ROOT)/config/sdm845auto.conf + export + endif + ifeq ($(CONFIG_ARCH_SDM670), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + endif +endif + + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ Native Enc/Dec ############ + +ifeq ($(CONFIG_MSM_QDSP6V2_CODECS), m) + NATIVE_OBJS += q6audio_v2.o q6audio_v2_aio.o + NATIVE_OBJS += audio_utils_aio.o + NATIVE_OBJS += audio_utils.o + NATIVE_OBJS += audio_native.o + NATIVE_OBJS += aac_in.o + NATIVE_OBJS += amrnb_in.o + NATIVE_OBJS += amrwb_in.o + NATIVE_OBJS += audio_aac.o + NATIVE_OBJS += audio_alac.o + NATIVE_OBJS += audio_amrnb.o + NATIVE_OBJS += audio_amrwb.o + NATIVE_OBJS += audio_amrwbplus.o + NATIVE_OBJS += audio_ape.o + NATIVE_OBJS += audio_evrc.o + NATIVE_OBJS += audio_g711alaw.o + NATIVE_OBJS += audio_g711mlaw.o + NATIVE_OBJS += audio_hwacc_effects.o + NATIVE_OBJS += audio_mp3.o + NATIVE_OBJS += audio_multi_aac.o + NATIVE_OBJS += audio_qcelp.o + NATIVE_OBJS += audio_wma.o + NATIVE_OBJS += audio_wmapro.o + NATIVE_OBJS += evrc_in.o + NATIVE_OBJS += g711alaw_in.o + NATIVE_OBJS += g711mlaw_in.o + NATIVE_OBJS += qcelp_in.o +endif + +LINUX_INC += -Iinclude/linux + +INCS := $(COMMON_INC) \ + $(UAPI_INC) + +ifeq ($(CONFIG_ARCH_SDM845), y) +INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h +endif +ifeq ($(CONFIG_ARCH_SDM670), y) +INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h +endif + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +# If the module name is not "wlan", then the define MULTI_IF_NAME to be the +# same a the QCA CHIP name. The host driver will then append MULTI_IF_NAME to +# any string that must be unique for all instances of the driver on the system. +# This allows multiple instances of the driver with different module names. +# If the module name is wlan, leave MULTI_IF_NAME undefined and the code will +# treat the driver as the primary driver. +ifneq ($(MODNAME), qdsp6v2) +CHIP_NAME ?= $(MODNAME) +CDEFINES += -DMULTI_IF_NAME=\"$(CHIP_NAME)\" +endif + +# Module information used by KBuild framework +obj-$(CONFIG_MSM_QDSP6V2_CODECS) += native_dlkm.o +native_dlkm-y := $(NATIVE_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/dsp/codecs/aac_in.c b/dsp/codecs/aac_in.c index c0828dc6d1bc..5c071416551a 100644 --- a/dsp/codecs/aac_in.c +++ b/dsp/codecs/aac_in.c @@ -702,8 +702,12 @@ struct miscdevice audio_aac_in_misc = { .fops = &audio_in_fops, }; -static int __init aac_in_init(void) +int __init aac_in_init(void) { return misc_register(&audio_aac_in_misc); } -device_initcall(aac_in_init); + +void __exit aac_in_exit(void) +{ + misc_deregister(&audio_aac_in_misc); +} diff --git a/dsp/codecs/amrnb_in.c b/dsp/codecs/amrnb_in.c index b24764cf9516..d9a019de9115 100644 --- a/dsp/codecs/amrnb_in.c +++ b/dsp/codecs/amrnb_in.c @@ -394,9 +394,12 @@ struct miscdevice audio_amrnb_in_misc = { .fops = &audio_in_fops, }; -static int __init amrnb_in_init(void) +int __init amrnb_in_init(void) { return misc_register(&audio_amrnb_in_misc); } -device_initcall(amrnb_in_init); +void __exit amrnb_in_exit(void) +{ + misc_deregister(&audio_amrnb_in_misc); +} diff --git a/dsp/codecs/amrwb_in.c b/dsp/codecs/amrwb_in.c index 77b4be54f10b..d1d4ab71b86d 100644 --- a/dsp/codecs/amrwb_in.c +++ b/dsp/codecs/amrwb_in.c @@ -392,9 +392,12 @@ struct miscdevice audio_amrwb_in_misc = { .fops = &audio_in_fops, }; -static int __init amrwb_in_init(void) +int __init amrwb_in_init(void) { return misc_register(&audio_amrwb_in_misc); } -device_initcall(amrwb_in_init); +void __exit amrwb_in_exit(void) +{ + misc_deregister(&audio_amrwb_in_misc); +} diff --git a/dsp/codecs/audio_aac.c b/dsp/codecs/audio_aac.c index 006b21c6793a..ea7506fbe6a7 100644 --- a/dsp/codecs/audio_aac.c +++ b/dsp/codecs/audio_aac.c @@ -461,7 +461,7 @@ static struct miscdevice audio_aac_misc = { .fops = &audio_aac_fops, }; -static int __init audio_aac_init(void) +int __init audio_aac_init(void) { int ret = misc_register(&audio_aac_misc); @@ -473,4 +473,8 @@ static int __init audio_aac_init(void) return ret; } -device_initcall(audio_aac_init); +void __exit audio_aac_exit(void) +{ + mutex_destroy(&audio_aac_ws_mgr.ws_lock); + misc_deregister(&audio_aac_misc); +} diff --git a/dsp/codecs/audio_alac.c b/dsp/codecs/audio_alac.c index d0b86c684808..50a0bf7e342a 100644 --- a/dsp/codecs/audio_alac.c +++ b/dsp/codecs/audio_alac.c @@ -420,7 +420,7 @@ static struct miscdevice audio_alac_misc = { .fops = &audio_alac_fops, }; -static int __init audio_alac_init(void) +int __init audio_alac_init(void) { int ret = misc_register(&audio_alac_misc); @@ -432,4 +432,8 @@ static int __init audio_alac_init(void) return ret; } -device_initcall(audio_alac_init); +void __exit audio_alac_exit(void) +{ + mutex_destroy(&audio_alac_ws_mgr.ws_lock); + misc_deregister(&audio_alac_misc); +} diff --git a/dsp/codecs/audio_amrnb.c b/dsp/codecs/audio_amrnb.c index 950098be9b95..041774259ab8 100644 --- a/dsp/codecs/audio_amrnb.c +++ b/dsp/codecs/audio_amrnb.c @@ -211,7 +211,7 @@ static struct miscdevice audio_amrnb_misc = { .fops = &audio_amrnb_fops, }; -static int __init audio_amrnb_init(void) +int __init audio_amrnb_init(void) { int ret = misc_register(&audio_amrnb_misc); @@ -223,4 +223,8 @@ static int __init audio_amrnb_init(void) return ret; } -device_initcall(audio_amrnb_init); +void __exit audio_amrnb_exit(void) +{ + mutex_destroy(&audio_amrnb_ws_mgr.ws_lock); + misc_deregister(&audio_amrnb_misc); +} diff --git a/dsp/codecs/audio_amrwb.c b/dsp/codecs/audio_amrwb.c index cb5db0d61ecd..091bee4d3ff0 100644 --- a/dsp/codecs/audio_amrwb.c +++ b/dsp/codecs/audio_amrwb.c @@ -216,7 +216,7 @@ static struct miscdevice audio_amrwb_misc = { .fops = &audio_amrwb_fops, }; -static int __init audio_amrwb_init(void) +int __init audio_amrwb_init(void) { int ret = misc_register(&audio_amrwb_misc); @@ -228,4 +228,8 @@ static int __init audio_amrwb_init(void) return ret; } -device_initcall(audio_amrwb_init); +void __exit audio_amrwb_exit(void) +{ + mutex_destroy(&audio_amrwb_ws_mgr.ws_lock); + misc_deregister(&audio_amrwb_misc); +} diff --git a/dsp/codecs/audio_amrwbplus.c b/dsp/codecs/audio_amrwbplus.c index 458a80c4c5bf..566aee735e6c 100644 --- a/dsp/codecs/audio_amrwbplus.c +++ b/dsp/codecs/audio_amrwbplus.c @@ -382,7 +382,7 @@ static struct miscdevice audio_amrwbplus_misc = { .fops = &audio_amrwbplus_fops, }; -static int __init audio_amrwbplus_init(void) +int __init audio_amrwbplus_init(void) { int ret = misc_register(&audio_amrwbplus_misc); @@ -394,4 +394,8 @@ static int __init audio_amrwbplus_init(void) return ret; } -device_initcall(audio_amrwbplus_init); +void __exit audio_amrwbplus_exit(void) +{ + mutex_destroy(&audio_amrwbplus_ws_mgr.ws_lock); + misc_deregister(&audio_amrwbplus_misc); +} diff --git a/dsp/codecs/audio_ape.c b/dsp/codecs/audio_ape.c index d7dc0648aeda..b11f83ef561a 100644 --- a/dsp/codecs/audio_ape.c +++ b/dsp/codecs/audio_ape.c @@ -344,7 +344,7 @@ static struct miscdevice audio_ape_misc = { .fops = &audio_ape_fops, }; -static int __init audio_ape_init(void) +int __init audio_ape_init(void) { int ret = misc_register(&audio_ape_misc); @@ -356,4 +356,8 @@ static int __init audio_ape_init(void) return ret; } -device_initcall(audio_ape_init); +void __exit audio_ape_exit(void) +{ + mutex_destroy(&audio_ape_ws_mgr.ws_lock); + misc_deregister(&audio_ape_misc); +} diff --git a/dsp/codecs/audio_evrc.c b/dsp/codecs/audio_evrc.c index 87762319b013..78bbde648604 100644 --- a/dsp/codecs/audio_evrc.c +++ b/dsp/codecs/audio_evrc.c @@ -169,7 +169,7 @@ static struct miscdevice audio_evrc_misc = { .fops = &audio_evrc_fops, }; -static int __init audio_evrc_init(void) +int __init audio_evrc_init(void) { int ret = misc_register(&audio_evrc_misc); @@ -181,4 +181,8 @@ static int __init audio_evrc_init(void) return ret; } -device_initcall(audio_evrc_init); +void __exit audio_evrc_exit(void) +{ + mutex_destroy(&audio_evrc_ws_mgr.ws_lock); + misc_deregister(&audio_evrc_misc); +} diff --git a/dsp/codecs/audio_g711alaw.c b/dsp/codecs/audio_g711alaw.c index 24f87e4bd1a6..a6e0a6e62414 100644 --- a/dsp/codecs/audio_g711alaw.c +++ b/dsp/codecs/audio_g711alaw.c @@ -375,7 +375,7 @@ static struct miscdevice audio_g711alaw_misc = { .fops = &audio_g711_fops, }; -static int __init audio_g711alaw_init(void) +int __init audio_g711alaw_init(void) { int ret = misc_register(&audio_g711alaw_misc); @@ -386,11 +386,9 @@ static int __init audio_g711alaw_init(void) return ret; } -static void __exit audio_g711alaw_exit(void) + +void __exit audio_g711alaw_exit(void) { - misc_deregister(&audio_g711alaw_misc); mutex_destroy(&audio_g711_ws_mgr.ws_lock); + misc_deregister(&audio_g711alaw_misc); } - -device_initcall(audio_g711alaw_init); -__exitcall(audio_g711alaw_exit); diff --git a/dsp/codecs/audio_g711mlaw.c b/dsp/codecs/audio_g711mlaw.c index 10d368011931..2a2598c70842 100644 --- a/dsp/codecs/audio_g711mlaw.c +++ b/dsp/codecs/audio_g711mlaw.c @@ -374,7 +374,7 @@ static struct miscdevice audio_g711mlaw_misc = { .fops = &audio_g711_fops, }; -static int __init audio_g711mlaw_init(void) +int __init audio_g711mlaw_init(void) { int ret = misc_register(&audio_g711mlaw_misc); @@ -386,11 +386,9 @@ static int __init audio_g711mlaw_init(void) return ret; } -static void __exit audio_g711mlaw_exit(void) +void __exit audio_g711mlaw_exit(void) { - misc_deregister(&audio_g711mlaw_misc); mutex_destroy(&audio_g711_ws_mgr.ws_lock); + misc_deregister(&audio_g711mlaw_misc); } -device_initcall(audio_g711mlaw_init); -__exitcall(audio_g711mlaw_exit); diff --git a/dsp/codecs/audio_hwacc_effects.c b/dsp/codecs/audio_hwacc_effects.c index 9444aa7c6259..c285511d3bfc 100644 --- a/dsp/codecs/audio_hwacc_effects.c +++ b/dsp/codecs/audio_hwacc_effects.c @@ -768,11 +768,15 @@ struct miscdevice audio_effects_misc = { .fops = &audio_effects_fops, }; -static int __init audio_effects_init(void) +int __init audio_effects_init(void) { return misc_register(&audio_effects_misc); } -device_initcall(audio_effects_init); +void __exit audio_effects_exit(void) +{ + misc_deregister(&audio_effects_misc); +} + MODULE_DESCRIPTION("Audio hardware accelerated effects driver"); MODULE_LICENSE("GPL v2"); diff --git a/dsp/codecs/audio_mp3.c b/dsp/codecs/audio_mp3.c index 0b10c7a83677..81e8486ada71 100644 --- a/dsp/codecs/audio_mp3.c +++ b/dsp/codecs/audio_mp3.c @@ -173,7 +173,7 @@ static struct miscdevice audio_mp3_misc = { .fops = &audio_mp3_fops, }; -static int __init audio_mp3_init(void) +int __init audio_mp3_init(void) { int ret = misc_register(&audio_mp3_misc); @@ -185,4 +185,8 @@ static int __init audio_mp3_init(void) return ret; } -device_initcall(audio_mp3_init); +void __exit audio_mp3_exit(void) +{ + mutex_destroy(&audio_mp3_ws_mgr.ws_lock); + misc_deregister(&audio_mp3_misc); +} diff --git a/dsp/codecs/audio_multi_aac.c b/dsp/codecs/audio_multi_aac.c index 5d407e0c5e61..c3e616aef423 100644 --- a/dsp/codecs/audio_multi_aac.c +++ b/dsp/codecs/audio_multi_aac.c @@ -508,7 +508,7 @@ static struct miscdevice audio_multiaac_misc = { .fops = &audio_aac_fops, }; -static int __init audio_aac_init(void) +int __init audio_multiaac_init(void) { int ret = misc_register(&audio_multiaac_misc); @@ -520,4 +520,8 @@ static int __init audio_aac_init(void) return ret; } -device_initcall(audio_aac_init); +void __exit audio_multiaac_exit(void) +{ + mutex_destroy(&audio_multiaac_ws_mgr.ws_lock); + misc_deregister(&audio_multiaac_misc); +} diff --git a/dsp/codecs/audio_native.c b/dsp/codecs/audio_native.c new file mode 100644 index 000000000000..8f21cc74f0d7 --- /dev/null +++ b/dsp/codecs/audio_native.c @@ -0,0 +1,75 @@ +/* +Copyright (c) 2017, The Linux Foundation. All rights reserved. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2 and +only version 2 as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +* +*/ + +#include +#include +#include "audio_utils.h" + +static int __init audio_native_init(void) +{ + aac_in_init(); + amrnb_in_init(); + amrwb_in_init(); + audio_aac_init(); + audio_alac_init(); + audio_amrnb_init(); + audio_amrwb_init(); + audio_amrwbplus_init(); + audio_ape_init(); + audio_evrc_init(); + audio_g711alaw_init(); + audio_g711mlaw_init(); + audio_effects_init(); + audio_mp3_init(); + audio_multiaac_init(); + audio_qcelp_init(); + audio_wma_init(); + audio_wmapro_init(); + evrc_in_init(); + g711alaw_in_init(); + g711mlaw_in_init(); + qcelp_in_init(); + return 0; +} + +static void __exit audio_native_exit(void) +{ + aac_in_exit(); + amrnb_in_exit(); + amrwb_in_exit(); + audio_aac_exit(); + audio_alac_exit(); + audio_amrnb_exit(); + audio_amrwb_exit(); + audio_amrwbplus_exit(); + audio_ape_exit(); + audio_evrc_exit(); + audio_g711alaw_exit(); + audio_g711mlaw_exit(); + audio_effects_exit(); + audio_mp3_exit(); + audio_multiaac_exit(); + audio_qcelp_exit(); + audio_wma_exit(); + audio_wmapro_exit(); + evrc_in_exit(); + g711alaw_in_exit(); + g711mlaw_in_exit(); + qcelp_in_exit(); +} + +module_init(audio_native_init); +module_exit(audio_native_exit); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Native Encoder/Decoder module"); diff --git a/dsp/codecs/audio_qcelp.c b/dsp/codecs/audio_qcelp.c index 8f2511c40b03..86902948dd96 100644 --- a/dsp/codecs/audio_qcelp.c +++ b/dsp/codecs/audio_qcelp.c @@ -176,7 +176,7 @@ static struct miscdevice audio_qcelp_misc = { .fops = &audio_qcelp_fops, }; -static int __init audio_qcelp_init(void) +int audio_qcelp_init(void) { int ret = misc_register(&audio_qcelp_misc); @@ -188,4 +188,8 @@ static int __init audio_qcelp_init(void) return ret; } -device_initcall(audio_qcelp_init); +void __exit audio_qcelp_exit(void) +{ + mutex_destroy(&audio_qcelp_ws_mgr.ws_lock); + misc_deregister(&audio_qcelp_misc); +} diff --git a/dsp/codecs/audio_utils.h b/dsp/codecs/audio_utils.h index f5517d833621..3ad6903b3365 100644 --- a/dsp/codecs/audio_utils.h +++ b/dsp/codecs/audio_utils.h @@ -112,3 +112,47 @@ ssize_t audio_in_write(struct file *file, const char __user *buf, size_t count, loff_t *pos); int audio_in_release(struct inode *inode, struct file *file); int audio_in_set_config(struct file *file, struct msm_audio_config *cfg); +int aac_in_init(void); +int amrnb_in_init(void); +int amrwb_in_init(void); +int audio_aac_init(void); +int audio_alac_init(void); +int audio_amrnb_init(void); +int audio_amrwb_init(void); +int audio_amrwbplus_init(void); +int audio_ape_init(void); +int audio_evrc_init(void); +int audio_g711alaw_init(void); +int audio_g711mlaw_init(void); +int audio_effects_init(void); +int audio_mp3_init(void); +int audio_multiaac_init(void); +int audio_qcelp_init(void); +int audio_wma_init(void); +int audio_wmapro_init(void); +int evrc_in_init(void); +int g711alaw_in_init(void); +int g711mlaw_in_init(void); +int qcelp_in_init(void); +void aac_in_exit(void); +void amrnb_in_exit(void); +void amrwb_in_exit(void); +void audio_aac_exit(void); +void audio_alac_exit(void); +void audio_amrnb_exit(void); +void audio_amrwb_exit(void); +void audio_amrwbplus_exit(void); +void audio_ape_exit(void); +void audio_evrc_exit(void); +void audio_g711alaw_exit(void); +void audio_g711mlaw_exit(void); +void audio_effects_exit(void); +void audio_mp3_exit(void); +void audio_multiaac_exit(void); +void audio_qcelp_exit(void); +void audio_wma_exit(void); +void audio_wmapro_exit(void); +void evrc_in_exit(void); +void g711alaw_in_exit(void); +void g711mlaw_in_exit(void); +void qcelp_in_exit(void); diff --git a/dsp/codecs/audio_wma.c b/dsp/codecs/audio_wma.c index e35334a3313a..975dc0b01c48 100644 --- a/dsp/codecs/audio_wma.c +++ b/dsp/codecs/audio_wma.c @@ -330,7 +330,7 @@ static struct miscdevice audio_wma_misc = { .fops = &audio_wma_fops, }; -static int __init audio_wma_init(void) +int __init audio_wma_init(void) { int ret = misc_register(&audio_wma_misc); @@ -342,4 +342,8 @@ static int __init audio_wma_init(void) return ret; } -device_initcall(audio_wma_init); +void __exit audio_wma_exit(void) +{ + mutex_destroy(&audio_wma_ws_mgr.ws_lock); + misc_deregister(&audio_wma_misc); +} diff --git a/dsp/codecs/audio_wmapro.c b/dsp/codecs/audio_wmapro.c index 3cb9db15f872..3ce4cdc86e90 100644 --- a/dsp/codecs/audio_wmapro.c +++ b/dsp/codecs/audio_wmapro.c @@ -403,7 +403,7 @@ static struct miscdevice audio_wmapro_misc = { .fops = &audio_wmapro_fops, }; -static int __init audio_wmapro_init(void) +int __init audio_wmapro_init(void) { int ret = misc_register(&audio_wmapro_misc); @@ -415,4 +415,8 @@ static int __init audio_wmapro_init(void) return ret; } -device_initcall(audio_wmapro_init); +void __exit audio_wmapro_exit(void) +{ + mutex_destroy(&audio_wmapro_ws_mgr.ws_lock); + misc_deregister(&audio_wmapro_misc); +} diff --git a/dsp/codecs/evrc_in.c b/dsp/codecs/evrc_in.c index e30271dd8102..158ff6f08c57 100644 --- a/dsp/codecs/evrc_in.c +++ b/dsp/codecs/evrc_in.c @@ -402,9 +402,12 @@ struct miscdevice audio_evrc_in_misc = { .fops = &audio_in_fops, }; -static int __init evrc_in_init(void) +int __init evrc_in_init(void) { return misc_register(&audio_evrc_in_misc); } -device_initcall(evrc_in_init); +void __exit evrc_in_exit(void) +{ + misc_deregister(&audio_evrc_in_misc); +} diff --git a/dsp/codecs/g711alaw_in.c b/dsp/codecs/g711alaw_in.c index bc8c0a36a825..bd49bc9ab714 100644 --- a/dsp/codecs/g711alaw_in.c +++ b/dsp/codecs/g711alaw_in.c @@ -374,9 +374,12 @@ struct miscdevice audio_g711alaw_in_misc = { .fops = &audio_in_fops, }; -static int __init g711alaw_in_init(void) +int __init g711alaw_in_init(void) { return misc_register(&audio_g711alaw_in_misc); } -device_initcall(g711alaw_in_init); +void __exit g711alaw_in_exit(void) +{ + misc_deregister(&audio_g711alaw_in_misc); +} diff --git a/dsp/codecs/g711mlaw_in.c b/dsp/codecs/g711mlaw_in.c index b92c44957377..d646bd1330cd 100644 --- a/dsp/codecs/g711mlaw_in.c +++ b/dsp/codecs/g711mlaw_in.c @@ -377,9 +377,12 @@ struct miscdevice audio_g711mlaw_in_misc = { .fops = &audio_in_fops, }; -static int __init g711mlaw_in_init(void) +int __init g711mlaw_in_init(void) { return misc_register(&audio_g711mlaw_in_misc); } -device_initcall(g711mlaw_in_init); +void __exit g711mlaw_in_exit(void) +{ + misc_deregister(&audio_g711mlaw_in_misc); +} diff --git a/dsp/codecs/qcelp_in.c b/dsp/codecs/qcelp_in.c index da5520f75a62..050c95f38955 100644 --- a/dsp/codecs/qcelp_in.c +++ b/dsp/codecs/qcelp_in.c @@ -402,9 +402,12 @@ struct miscdevice audio_qcelp_in_misc = { .fops = &audio_in_fops, }; -static int __init qcelp_in_init(void) +int __init qcelp_in_init(void) { return misc_register(&audio_qcelp_in_misc); } -device_initcall(qcelp_in_init); +void __exit qcelp_in_exit(void) +{ + misc_deregister(&audio_qcelp_in_misc); +} diff --git a/asoc/msm-dts-srs-tm-config.c b/dsp/msm-dts-srs-tm-config.c similarity index 92% rename from asoc/msm-dts-srs-tm-config.c rename to dsp/msm-dts-srs-tm-config.c index 78174afb9b47..cd3da4d642d9 100644 --- a/asoc/msm-dts-srs-tm-config.c +++ b/dsp/msm-dts-srs-tm-config.c @@ -18,10 +18,9 @@ #include #include #include -#include #include #include -#include "msm-pcm-routing-v2.h" +#include static int srs_port_id[AFE_MAX_PORTS] = {-1}; static int srs_copp_idx[AFE_MAX_PORTS] = {-1}; @@ -142,10 +141,10 @@ static int msm_dts_srs_trumedia_control_set(struct snd_kcontrol *kcontrol, int ret, port_id; pr_debug("SRS control normal called\n"); - msm_pcm_routing_acquire_lock(); + msm_dts_srs_acquire_lock(); port_id = SLIMBUS_0_RX; ret = msm_dts_srs_trumedia_control_set_(port_id, kcontrol, ucontrol); - msm_pcm_routing_release_lock(); + msm_dts_srs_release_lock(); return ret; } @@ -155,10 +154,10 @@ static int msm_dts_srs_trumedia_control_i2s_set(struct snd_kcontrol *kcontrol, int ret, port_id; pr_debug("SRS control I2S called\n"); - msm_pcm_routing_acquire_lock(); + msm_dts_srs_acquire_lock(); port_id = PRIMARY_I2S_RX; ret = msm_dts_srs_trumedia_control_set_(port_id, kcontrol, ucontrol); - msm_pcm_routing_release_lock(); + msm_dts_srs_release_lock(); return ret; } @@ -168,10 +167,10 @@ static int msm_dts_srs_trumedia_control_mi2s_set(struct snd_kcontrol *kcontrol, int ret, port_id; pr_debug("SRS control MI2S called\n"); - msm_pcm_routing_acquire_lock(); + msm_dts_srs_acquire_lock(); port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; ret = msm_dts_srs_trumedia_control_set_(port_id, kcontrol, ucontrol); - msm_pcm_routing_release_lock(); + msm_dts_srs_release_lock(); return ret; } @@ -181,10 +180,10 @@ static int msm_dts_srs_trumedia_control_hdmi_set(struct snd_kcontrol *kcontrol, int ret, port_id; pr_debug("SRS control HDMI called\n"); - msm_pcm_routing_acquire_lock(); + msm_dts_srs_acquire_lock(); port_id = HDMI_RX; ret = msm_dts_srs_trumedia_control_set_(port_id, kcontrol, ucontrol); - msm_pcm_routing_release_lock(); + msm_dts_srs_release_lock(); return ret; } @@ -270,6 +269,13 @@ static const struct snd_kcontrol_new lpa_srs_trumedia_controls_mi2s[] = { } }; +/** + * msm_dts_srs_tm_add_controls - + * Add DTS SRS module controls + * + * @platform: component to which controls can be registered + * + */ void msm_dts_srs_tm_add_controls(struct snd_soc_platform *platform) { snd_soc_add_platform_controls(platform, @@ -287,6 +293,7 @@ void msm_dts_srs_tm_add_controls(struct snd_soc_platform *platform) lpa_srs_trumedia_controls_mi2s, ARRAY_SIZE(lpa_srs_trumedia_controls_mi2s)); } +EXPORT_SYMBOL(msm_dts_srs_tm_add_controls); static int reg_ion_mem(void) { @@ -322,6 +329,13 @@ static void unreg_ion_mem(void) po.size = 0; } +/** + * msm_dts_srs_tm_deinit - + * De-Initializes DTS SRS module + * + * @port_id: Port ID number + * + */ void msm_dts_srs_tm_deinit(int port_id) { set_port_id(port_id, -1); @@ -333,7 +347,16 @@ void msm_dts_srs_tm_deinit(int port_id) } } } +EXPORT_SYMBOL(msm_dts_srs_tm_deinit); +/** + * msm_dts_srs_tm_init - + * Initializes DTS SRS module + * + * @port_id: Port ID number + * @copp_idx: COPP index + * + */ void msm_dts_srs_tm_init(int port_id, int copp_idx) { int cur_ref_cnt = 0; @@ -355,3 +378,4 @@ void msm_dts_srs_tm_init(int port_id, int copp_idx) } msm_dts_srs_tm_send_params(port_id, 1); } +EXPORT_SYMBOL(msm_dts_srs_tm_init); diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index 24df1aa06714..0baca8dd5470 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -89,6 +89,20 @@ static void msm_audio_ion_add_allocation( mutex_unlock(&(msm_audio_ion_data->list_mutex)); } +/** + * msm_audio_ion_alloc - + * Allocs ION memory for given client name + * + * @name: Name of audio ION client + * @client: ION client to be assigned + * @handle: ION handle to be assigned + * @bufsz: buffer size + * @paddr: Physical address to be assigned with allocated region + * @pa_len: length of allocated region to be assigned + * vaddr: virtual address to be assigned + * + * Returns 0 on success or error on failure + */ int msm_audio_ion_alloc(const char *name, struct ion_client **client, struct ion_handle **handle, size_t bufsz, ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr) @@ -243,6 +257,15 @@ int msm_audio_ion_import(const char *name, struct ion_client **client, return rc; } +/** + * msm_audio_ion_free - + * fress ION memory for given client and handle + * + * @client: ION client + * @handle: ION handle + * + * Returns 0 on success or error on failure + */ int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle) { if (!client || !handle) { @@ -260,6 +283,15 @@ int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle) } EXPORT_SYMBOL(msm_audio_ion_free); +/** + * msm_audio_ion_mmap - + * Audio ION memory map + * + * @ab: audio buf pointer + * @vma: virtual mem area + * + * Returns 0 on success or error on failure + */ int msm_audio_ion_mmap(struct audio_buffer *ab, struct vm_area_struct *vma) { @@ -351,6 +383,7 @@ int msm_audio_ion_mmap(struct audio_buffer *ab, } return 0; } +EXPORT_SYMBOL(msm_audio_ion_mmap); bool msm_audio_ion_is_smmu_available(void) @@ -366,8 +399,15 @@ struct ion_client *msm_audio_ion_client_create(const char *name) pclient = msm_ion_client_create(name); return pclient; } +EXPORT_SYMBOL(msm_audio_ion_client_create); - +/** + * msm_audio_ion_client_destroy - + * Removes ION client handle + * + * @client: ION client + * + */ void msm_audio_ion_client_destroy(struct ion_client *client) { pr_debug("%s: client = %pK smmu_enabled = %d\n", __func__, @@ -375,7 +415,24 @@ void msm_audio_ion_client_destroy(struct ion_client *client) ion_client_destroy(client); } +EXPORT_SYMBOL(msm_audio_ion_client_destroy); +/** + * msm_audio_ion_import_legacy - + * Alloc ION memory for given size + * + * @name: ION client name + * @client: ION client + * @handle: ION handle to be updated + * @fd: ION fd + * @ionflag: Flags for ION handle + * @bufsz: buffer size + * @paddr: pointer to be updated with physical address of allocated ION memory + * @pa_len: pointer to be updated with size of physical memory + * @vaddr: pointer to be updated with virtual address + * + * Returns 0 on success or error on failure + */ int msm_audio_ion_import_legacy(const char *name, struct ion_client *client, struct ion_handle **handle, int fd, unsigned long *ionflag, size_t bufsz, @@ -438,7 +495,16 @@ int msm_audio_ion_import_legacy(const char *name, struct ion_client *client, err: return rc; } +EXPORT_SYMBOL(msm_audio_ion_import_legacy); +/** + * msm_audio_ion_free_legacy - + * Frees ION memory for given handle + * + * @client: ION client + * @handle: ION handle + * + */ int msm_audio_ion_free_legacy(struct ion_client *client, struct ion_handle *handle) { @@ -451,6 +517,7 @@ int msm_audio_ion_free_legacy(struct ion_client *client, /* no client_destrody in legacy*/ return 0; } +EXPORT_SYMBOL(msm_audio_ion_free_legacy); int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op) { @@ -710,6 +777,13 @@ u32 msm_audio_ion_get_smmu_sid_mode32(void) return 0; } +/** + * msm_audio_populate_upper_32_bits - + * retrieve upper 32bits of 64bit address + * + * @pa: 64bit physical address + * + */ u32 msm_audio_populate_upper_32_bits(ion_phys_addr_t pa) { if (sizeof(ion_phys_addr_t) == sizeof(u32)) @@ -717,6 +791,7 @@ u32 msm_audio_populate_upper_32_bits(ion_phys_addr_t pa) else return upper_32_bits(pa); } +EXPORT_SYMBOL(msm_audio_populate_upper_32_bits); static int msm_audio_ion_probe(struct platform_device *pdev) { @@ -837,17 +912,15 @@ static struct platform_driver msm_audio_ion_driver = { .remove = msm_audio_ion_remove, }; -static int __init msm_audio_ion_init(void) +int __init msm_audio_ion_init(void) { return platform_driver_register(&msm_audio_ion_driver); } -module_init(msm_audio_ion_init); -static void __exit msm_audio_ion_exit(void) +void __exit msm_audio_ion_exit(void) { platform_driver_unregister(&msm_audio_ion_driver); } -module_exit(msm_audio_ion_exit); MODULE_DESCRIPTION("MSM Audio ION module"); MODULE_LICENSE("GPL v2"); diff --git a/dsp/q6_init.c b/dsp/q6_init.c new file mode 100644 index 000000000000..3b885dcb9095 --- /dev/null +++ b/dsp/q6_init.c @@ -0,0 +1,55 @@ +/* +Copyright (c) 2017, The Linux Foundation. All rights reserved. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2 and +only version 2 as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +* +*/ + +#include +#include +#include "q6_init.h" + +static int __init audio_q6_init(void) +{ + adsp_err_init(); + audio_cal_init(); + rtac_init(); + adm_init(); + afe_init(); + q6asm_init(); + q6lsm_init(); + voice_init(); + core_init(); + msm_audio_ion_init(); + audio_slimslave_init(); + avtimer_init(); + return 0; +} + +static void __exit audio_q6_exit(void) +{ + avtimer_exit(); + audio_slimslave_exit(); + msm_audio_ion_exit(); + core_exit(); + voice_exit(); + q6lsm_exit(); + q6asm_exit(); + afe_exit(); + adm_exit(); + rtac_exit(); + audio_cal_exit(); + adsp_err_exit(); +} + +module_init(audio_q6_init); +module_exit(audio_q6_exit); +MODULE_DESCRIPTION("Q6 module"); +MODULE_LICENSE("GPL v2"); diff --git a/dsp/q6_init.h b/dsp/q6_init.h new file mode 100644 index 000000000000..971e9b29e177 --- /dev/null +++ b/dsp/q6_init.h @@ -0,0 +1,43 @@ +/* +Copyright (c) 2017, The Linux Foundation. All rights reserved. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2 and +only version 2 as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +* +*/ + +#ifndef __Q6_INIT_H__ +#define __Q6_INIT_H__ +int adsp_err_init(void); +int adm_init(void); +int afe_init(void); +int q6asm_init(void); +int q6lsm_init(void); +int voice_init(void); +int audio_cal_init(void); +int core_init(void); +int rtac_init(void); +int msm_audio_ion_init(void); +int audio_slimslave_init(void); +int avtimer_init(void); + +void avtimer_exit(void); +void audio_slimslave_exit(void); +void msm_audio_ion_exit(void); +void rtac_exit(void); +void core_exit(void); +void audio_cal_exit(void); +void voice_exit(void); +void q6lsm_exit(void); +void q6asm_exit(void); +void afe_exit(void); +void adm_exit(void); +void adsp_err_exit(void); +#endif + diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 461e155d4176..77c28976e379 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -127,7 +127,26 @@ static struct adm_multi_ch_map multi_ch_maps[2] = { static int adm_get_parameters[MAX_COPPS_PER_PORT * ADM_GET_PARAMETER_LENGTH]; static int adm_module_topo_list[ MAX_COPPS_PER_PORT * ADM_GET_TOPO_MODULE_LIST_LENGTH]; +static struct mutex dts_srs_lock; +void msm_dts_srs_acquire_lock(void) +{ + mutex_lock(&dts_srs_lock); +} + +void msm_dts_srs_release_lock(void) +{ + mutex_unlock(&dts_srs_lock); +} + +/** + * adm_validate_and_get_port_index - + * validate given port id + * + * @port_id: Port ID number + * + * Returns valid index on success or error on failure + */ int adm_validate_and_get_port_index(int port_id) { int index; @@ -150,7 +169,16 @@ int adm_validate_and_get_port_index(int port_id) pr_debug("%s: port_idx- %d\n", __func__, index); return index; } +EXPORT_SYMBOL(adm_validate_and_get_port_index); +/** + * adm_get_default_copp_idx - + * retrieve default copp_idx for given port + * + * @port_id: Port ID number + * + * Returns valid value on success or error on failure + */ int adm_get_default_copp_idx(int port_id) { int port_idx = adm_validate_and_get_port_index(port_id), idx; @@ -167,6 +195,7 @@ int adm_get_default_copp_idx(int port_id) } return -EINVAL; } +EXPORT_SYMBOL(adm_get_default_copp_idx); int adm_get_topology_for_port_from_copp_id(int port_id, int copp_id) { @@ -185,6 +214,15 @@ int adm_get_topology_for_port_from_copp_id(int port_id, int copp_id) return 0; } +/** + * adm_get_topology_for_port_copp_idx - + * retrieve topology of given port/copp_idx + * + * @port_id: Port ID number + * @copp_idx: copp index of ADM copp + * + * Returns valid value on success or 0 on failure + */ int adm_get_topology_for_port_copp_idx(int port_id, int copp_idx) { int port_idx = adm_validate_and_get_port_index(port_id); @@ -196,6 +234,7 @@ int adm_get_topology_for_port_copp_idx(int port_id, int copp_idx) } return atomic_read(&this_adm.copp.topology[port_idx][copp_idx]); } +EXPORT_SYMBOL(adm_get_topology_for_port_copp_idx); int adm_get_indexes_from_copp_id(int copp_id, int *copp_idx, int *port_idx) { @@ -264,6 +303,17 @@ static int adm_get_next_available_copp(int port_idx) return idx; } +/** + * srs_trumedia_open - + * command to set SRS trumedia open + * + * @port_id: Port ID number + * @copp_idx: copp index of ADM copp + * @srs_tech_id: SRS tech index + * @srs_params: params pointer + * + * Returns 0 on success or error on failure + */ int srs_trumedia_open(int port_id, int copp_idx, __s32 srs_tech_id, void *srs_params) { @@ -529,6 +579,7 @@ int srs_trumedia_open(int port_id, int copp_idx, __s32 srs_tech_id, kfree(adm_params); return ret; } +EXPORT_SYMBOL(srs_trumedia_open); static int adm_populate_channel_weight(u16 *ptr, struct msm_pcm_channel_mixer *ch_mixer, @@ -790,7 +841,20 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, return ret; } +EXPORT_SYMBOL(adm_programable_channel_mixer); +/** + * adm_set_stereo_to_custom_stereo - + * command to update custom stereo + * + * @port_id: Port ID number + * @copp_idx: copp index of ADM copp + * @session_id: session id to be updated + * @params: params pointer + * @param_length: length of params + * + * Returns 0 on success or error on failure + */ int adm_set_stereo_to_custom_stereo(int port_id, int copp_idx, unsigned int session_id, char *params, uint32_t params_length) @@ -876,7 +940,19 @@ int adm_set_stereo_to_custom_stereo(int port_id, int copp_idx, kfree(adm_params); return rc; } +EXPORT_SYMBOL(adm_set_stereo_to_custom_stereo); +/** + * adm_dolby_dap_send_params - + * command to send dolby dap params + * + * @port_id: Port ID number + * @copp_idx: copp index of ADM copp + * @params: params pointer + * @param_length: length of params + * + * Returns 0 on success or error on failure + */ int adm_dolby_dap_send_params(int port_id, int copp_idx, char *params, uint32_t params_length) { @@ -951,7 +1027,19 @@ int adm_dolby_dap_send_params(int port_id, int copp_idx, char *params, kfree(adm_params); return rc; } +EXPORT_SYMBOL(adm_dolby_dap_send_params); +/** + * adm_get_params_v5 - + * command to retrieve ADM params for given module + * + * @port_id: Port ID number + * @copp_idx: copp index of ADM copp + * @params: params pointer + * @param_length: length of params + * + * Returns 0 on success or error on failure + */ int adm_send_params_v5(int port_id, int copp_idx, char *params, uint32_t params_length) { @@ -1026,6 +1114,7 @@ int adm_send_params_v5(int port_id, int copp_idx, char *params, kfree(adm_params); return rc; } +EXPORT_SYMBOL(adm_send_params_v5); int adm_get_params_v2(int port_id, int copp_idx, uint32_t module_id, uint32_t param_id, uint32_t params_length, @@ -1142,13 +1231,38 @@ int adm_get_params_v2(int port_id, int copp_idx, uint32_t module_id, return rc; } +/** + * adm_get_params - + * command to retrieve ADM params for given module + * + * @port_id: Port ID number + * @copp_idx: copp index of ADM copp + * @module_id: module ID + * @param_id: Param index + * @param_length: length of params + * @params: params pointer + * + * Returns 0 on success or error on failure + */ int adm_get_params(int port_id, int copp_idx, uint32_t module_id, uint32_t param_id, uint32_t params_length, char *params) { return adm_get_params_v2(port_id, copp_idx, module_id, param_id, params_length, params, 0); } +EXPORT_SYMBOL(adm_get_params); +/** + * adm_get_pp_topo_module_list - + * command to update PP top module list + * + * @port_id: Port ID number + * @copp_idx: copp index of ADM copp + * @param_length: length of params + * @params: pointer with PP top module params + * + * Returns 0 on success or error on failure + */ int adm_get_pp_topo_module_list(int port_id, int copp_idx, int32_t param_length, char *params) { @@ -1245,6 +1359,8 @@ int adm_get_pp_topo_module_list(int port_id, int copp_idx, int32_t param_length, pr_debug("%s : rc = %d ", __func__, rc); return rc; } +EXPORT_SYMBOL(adm_get_pp_topo_module_list); + static void adm_callback_debug_print(struct apr_client_data *data) { uint32_t *payload; @@ -1264,6 +1380,15 @@ static void adm_callback_debug_print(struct apr_client_data *data) __func__, data->opcode, data->payload_size); } +/** + * adm_set_multi_ch_map - + * Update multi channel map info + * + * @channel_map: pointer with channel map info + * @path: direction or ADM path type + * + * Returns 0 on success or error on failure + */ int adm_set_multi_ch_map(char *channel_map, int path) { int idx; @@ -1283,7 +1408,17 @@ int adm_set_multi_ch_map(char *channel_map, int path) return 0; } +EXPORT_SYMBOL(adm_set_multi_ch_map); +/** + * adm_get_multi_ch_map - + * Retrieves multi channel map info + * + * @channel_map: pointer to be updated with channel map + * @path: direction or ADM path type + * + * Returns 0 on success or error on failure + */ int adm_get_multi_ch_map(char *channel_map, int path) { int idx; @@ -1304,6 +1439,7 @@ int adm_get_multi_ch_map(char *channel_map, int path) return 0; } +EXPORT_SYMBOL(adm_get_multi_ch_map); static int32_t adm_callback(struct apr_client_data *data, void *priv) { @@ -2170,6 +2306,16 @@ static void send_adm_cal(int port_id, int copp_idx, int path, int perf_mode, app_type, acdb_id, sample_rate); } +/** + * adm_connect_afe_port - + * command to send ADM connect AFE port + * + * @mode: value of mode for ADM connect AFE + * @session_id: session active to connect + * @port_id: Port ID number + * + * Returns 0 on success or error on failure + */ int adm_connect_afe_port(int mode, int session_id, int port_id) { struct adm_cmd_connect_afe_port_v5 cmd; @@ -2249,6 +2395,7 @@ int adm_connect_afe_port(int mode, int session_id, int port_id) return ret; } +EXPORT_SYMBOL(adm_connect_afe_port); int adm_arrange_mch_map(struct adm_cmd_device_open_v5 *open, int path, int channel_mode) @@ -2382,6 +2529,22 @@ int adm_arrange_mch_ep2_map(struct adm_cmd_device_open_v6 *open_v6, return rc; } +/** + * adm_open - + * command to send ADM open + * + * @port_id: port id number + * @path: direction or ADM path type + * @rate: sample rate of session + * @channel_mode: number of channels set + * @topology: topology active for this session + * @perf_mode: performance mode like LL/ULL/.. + * @bit_width: bit width to set for copp + * @app_type: App type used for this session + * @acdb_id: ACDB ID of this device + * + * Returns 0 on success or error on failure + */ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, int perf_mode, uint16_t bit_width, int app_type, int acdb_id) { @@ -2621,7 +2784,17 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, atomic_inc(&this_adm.copp.cnt[port_idx][copp_idx]); return copp_idx; } +EXPORT_SYMBOL(adm_open); +/** + * adm_copp_mfc_cfg - + * command to send ADM MFC config + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * @dst_sample_rate: sink sample rate + * + */ void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate) { struct audproc_mfc_output_media_fmt mfc_cfg; @@ -2723,6 +2896,7 @@ void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate) fail_cmd: return; } +EXPORT_SYMBOL(adm_copp_mfc_cfg); static void route_set_opcode_matrix_id( struct adm_cmd_matrix_map_routings_v5 **route_addr, @@ -2763,6 +2937,17 @@ static void route_set_opcode_matrix_id( __func__, route->hdr.opcode, route->matrix_id); } +/** + * adm_matrix_map - + * command to send ADM matrix map for ADM copp list + * + * @path: direction or ADM path type + * @payload_map: have info of session id and associated copp_idx/num_copps + * @perf_mode: performance mode like LL/ULL/.. + * @passthr_mode: flag to indicate passthrough mode + * + * Returns 0 on success or error on failure + */ int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode, uint32_t passthr_mode) { @@ -2892,34 +3077,69 @@ int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode, kfree(matrix_map); return ret; } +EXPORT_SYMBOL(adm_matrix_map); +/** + * adm_ec_ref_rx_id - + * Update EC ref port ID + * + */ void adm_ec_ref_rx_id(int port_id) { this_adm.ec_ref_rx = port_id; pr_debug("%s: ec_ref_rx:%d\n", __func__, this_adm.ec_ref_rx); } +EXPORT_SYMBOL(adm_ec_ref_rx_id); +/** + * adm_num_ec_ref_rx_chans - + * Update EC ref number of channels + * + */ void adm_num_ec_ref_rx_chans(int num_chans) { this_adm.num_ec_ref_rx_chans = num_chans; pr_debug("%s: num_ec_ref_rx_chans:%d\n", __func__, this_adm.num_ec_ref_rx_chans); } +EXPORT_SYMBOL(adm_num_ec_ref_rx_chans); +/** + * adm_ec_ref_rx_bit_width - + * Update EC ref bit_width + * + */ void adm_ec_ref_rx_bit_width(int bit_width) { this_adm.ec_ref_rx_bit_width = bit_width; pr_debug("%s: ec_ref_rx_bit_width:%d\n", __func__, this_adm.ec_ref_rx_bit_width); } +EXPORT_SYMBOL(adm_ec_ref_rx_bit_width); +/** + * adm_ec_ref_rx_sampling_rate - + * Update EC ref sample rate + * + */ void adm_ec_ref_rx_sampling_rate(int sampling_rate) { this_adm.ec_ref_rx_sampling_rate = sampling_rate; pr_debug("%s: ec_ref_rx_sampling_rate:%d\n", __func__, this_adm.ec_ref_rx_sampling_rate); } +EXPORT_SYMBOL(adm_ec_ref_rx_sampling_rate); +/** + * adm_close - + * command to close ADM copp + * + * @port_id: Port ID number + * @perf_mode: performance mode like LL/ULL/.. + * @copp_idx: copp index assigned + * + * Returns 0 on success or error on failure + */ int adm_close(int port_id, int perf_mode, int copp_idx) { struct apr_hdr close; @@ -3053,6 +3273,7 @@ int adm_close(int port_id, int perf_mode, int copp_idx) } return 0; } +EXPORT_SYMBOL(adm_close); int send_rtac_audvol_cal(void) { @@ -3474,6 +3695,16 @@ static int adm_init_cal_data(void) return ret; } +/** + * adm_set_volume - + * command to set volume on ADM copp + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * @volume: gain value to set + * + * Returns 0 on success or error on failure + */ int adm_set_volume(int port_id, int copp_idx, int volume) { struct audproc_volume_ctrl_master_gain audproc_vol; @@ -3552,7 +3783,18 @@ int adm_set_volume(int port_id, int copp_idx, int volume) fail_cmd: return rc; } +EXPORT_SYMBOL(adm_set_volume); +/** + * adm_set_softvolume - + * command to set softvolume + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * @softvol_param: Params to set for softvolume + * + * Returns 0 on success or error on failure + */ int adm_set_softvolume(int port_id, int copp_idx, struct audproc_softvolume_params *softvol_param) { @@ -3644,7 +3886,18 @@ int adm_set_softvolume(int port_id, int copp_idx, fail_cmd: return rc; } +EXPORT_SYMBOL(adm_set_softvolume); +/** + * adm_set_mic_gain - + * command to set MIC gain + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * @volume: gain value to set + * + * Returns 0 on success or error on failure + */ int adm_set_mic_gain(int port_id, int copp_idx, int volume) { struct adm_set_mic_gain_params mic_gain_params; @@ -3722,7 +3975,18 @@ int adm_set_mic_gain(int port_id, int copp_idx, int volume) fail_cmd: return rc; } +EXPORT_SYMBOL(adm_set_mic_gain); +/** + * adm_send_set_multichannel_ec_primary_mic_ch - + * command to set multi-ch EC primary mic + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * @primary_mic_ch: channel number of primary mic + * + * Returns 0 on success or error on failure + */ int adm_send_set_multichannel_ec_primary_mic_ch(int port_id, int copp_idx, int primary_mic_ch) { @@ -3810,7 +4074,19 @@ int adm_send_set_multichannel_ec_primary_mic_ch(int port_id, int copp_idx, fail_cmd: return rc; } +EXPORT_SYMBOL(adm_send_set_multichannel_ec_primary_mic_ch); +/** + * adm_param_enable - + * command to send params to ADM for given module + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * @module_id: ADM module + * @enable: flag to enable or disable module + * + * Returns 0 on success or error on failure + */ int adm_param_enable(int port_id, int copp_idx, int module_id, int enable) { struct audproc_enable_param_t adm_mod_enable; @@ -3896,7 +4172,22 @@ int adm_param_enable(int port_id, int copp_idx, int module_id, int enable) return rc; } +EXPORT_SYMBOL(adm_param_enable); +/** + * adm_send_calibration - + * send ADM calibration to DSP + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * @path: direction or ADM path type + * @perf_mode: performance mode like LL/ULL/.. + * @cal_type: calibration type to use + * @params: pointer with cal data + * @size: cal size + * + * Returns 0 on success or error on failure + */ int adm_send_calibration(int port_id, int copp_idx, int path, int perf_mode, int cal_type, char *params, int size) { @@ -3988,6 +4279,7 @@ int adm_send_calibration(int port_id, int copp_idx, int path, int perf_mode, kfree(adm_params); return rc; } +EXPORT_SYMBOL(adm_send_calibration); /* * adm_update_wait_parameters must be called with routing driver locks. @@ -4024,7 +4316,17 @@ int adm_set_wait_parameters(int port_id, int copp_idx) return ret; } +EXPORT_SYMBOL(adm_set_wait_parameters); +/** + * adm_reset_wait_parameters - + * reset wait parameters or ADM delay value + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * + * Returns 0 on success or error on failure + */ int adm_reset_wait_parameters(int port_id, int copp_idx) { int ret = 0, port_idx; @@ -4050,7 +4352,18 @@ int adm_reset_wait_parameters(int port_id, int copp_idx) end: return ret; } +EXPORT_SYMBOL(adm_reset_wait_parameters); +/** + * adm_wait_timeout - + * ADM wait command after command send to DSP + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * @wait_time: value in ms for command timeout + * + * Returns 0 on success or error on failure + */ int adm_wait_timeout(int port_id, int copp_idx, int wait_time) { int ret = 0, port_idx; @@ -4081,7 +4394,22 @@ int adm_wait_timeout(int port_id, int copp_idx, int wait_time) pr_debug("%s: return %d--\n", __func__, ret); return ret; } +EXPORT_SYMBOL(adm_wait_timeout); +/** + * adm_store_cal_data - + * Retrieve calibration data for ADM copp device + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * @path: direction or copp type + * @perf_mode: performance mode like LL/ULL/.. + * @cal_index: calibration index to use + * @params: pointer to store cal data + * @size: pointer to fill with cal size + * + * Returns 0 on success or error on failure + */ int adm_store_cal_data(int port_id, int copp_idx, int path, int perf_mode, int cal_index, char *params, int *size) { @@ -4165,7 +4493,18 @@ int adm_store_cal_data(int port_id, int copp_idx, int path, int perf_mode, end: return rc; } +EXPORT_SYMBOL(adm_store_cal_data); +/** + * adm_send_compressed_device_mute - + * command to send mute for compressed device + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * @mute_on: flag to indicate mute or unmute + * + * Returns 0 on success or error on failure + */ int adm_send_compressed_device_mute(int port_id, int copp_idx, bool mute_on) { struct adm_set_compressed_device_mute mute_params; @@ -4242,7 +4581,18 @@ int adm_send_compressed_device_mute(int port_id, int copp_idx, bool mute_on) end: return ret; } +EXPORT_SYMBOL(adm_send_compressed_device_mute); +/** + * adm_send_compressed_device_latency - + * command to send latency for compressed device + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * @latency: latency value to pass + * + * Returns 0 on success or error on failure + */ int adm_send_compressed_device_latency(int port_id, int copp_idx, int latency) { struct adm_set_compressed_device_latency latency_params; @@ -4319,6 +4669,7 @@ int adm_send_compressed_device_latency(int port_id, int copp_idx, int latency) end: return ret; } +EXPORT_SYMBOL(adm_send_compressed_device_latency); /** * adm_swap_speaker_channels @@ -4450,6 +4801,16 @@ int adm_swap_speaker_channels(int port_id, int copp_idx, } EXPORT_SYMBOL(adm_swap_speaker_channels); +/** + * adm_set_sound_focus - + * Update sound focus info + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * @soundFocusData: sound focus data to pass + * + * Returns 0 on success or error on failure + */ int adm_set_sound_focus(int port_id, int copp_idx, struct sound_focus_param soundFocusData) { @@ -4559,7 +4920,18 @@ int adm_set_sound_focus(int port_id, int copp_idx, return ret; } +EXPORT_SYMBOL(adm_set_sound_focus); +/** + * adm_get_sound_focus - + * Retrieve sound focus info + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * @soundFocusData: pointer for sound focus data to be updated with + * + * Returns 0 on success or error on failure + */ int adm_get_sound_focus(int port_id, int copp_idx, struct sound_focus_param *soundFocusData) { @@ -4623,6 +4995,7 @@ int adm_get_sound_focus(int port_id, int copp_idx, return ret; } +EXPORT_SYMBOL(adm_get_sound_focus); static int adm_source_tracking_alloc_map_memory(void) { @@ -4682,6 +5055,16 @@ static int adm_source_tracking_alloc_map_memory(void) return ret; } +/** + * adm_get_source_tracking - + * Retrieve source tracking info + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * @sourceTrackingData: pointer for source track data to be updated with + * + * Returns 0 on success or error on failure + */ int adm_get_source_tracking(int port_id, int copp_idx, struct source_tracking_param *sourceTrackingData) { @@ -4808,8 +5191,9 @@ int adm_get_source_tracking(int port_id, int copp_idx, return ret; } +EXPORT_SYMBOL(adm_get_source_tracking); -static int __init adm_init(void) +int __init adm_init(void) { int i = 0, j; @@ -4857,14 +5241,13 @@ static int __init adm_init(void) this_adm.sourceTrackingData.apr_cmd_status = -1; atomic_set(&this_adm.mem_map_handles[ADM_MEM_MAP_INDEX_SOURCE_TRACKING], 0); + mutex_init(&dts_srs_lock); return 0; } -static void __exit adm_exit(void) +void __exit adm_exit(void) { + mutex_destroy(&dts_srs_lock); adm_delete_cal_data(); } - -device_initcall(adm_init); -module_exit(adm_exit); diff --git a/dsp/q6afe.c b/dsp/q6afe.c index b6a7aa329447..631a12324675 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -157,6 +157,13 @@ int afe_get_topology(int port_id) return topology; } +/** + * afe_set_aanc_info - + * Update AFE AANC info + * + * @q6_aanc_info: AFE AANC info params + * + */ void afe_set_aanc_info(struct aanc_data *q6_aanc_info) { this_afe.aanc_info.aanc_active = q6_aanc_info->aanc_active; @@ -169,6 +176,7 @@ void afe_set_aanc_info(struct aanc_data *q6_aanc_info) this_afe.aanc_info.aanc_rx_port, this_afe.aanc_info.aanc_tx_port); } +EXPORT_SYMBOL(afe_set_aanc_info); static void afe_callback_debug_print(struct apr_client_data *data) { @@ -457,6 +465,14 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) return 0; } +/** + * afe_get_port_type - + * Retrieve AFE port type whether RX or TX + * + * @port_id: AFE Port ID number + * + * Returns RX/TX type on success or -EINVAL on failure. + */ int afe_get_port_type(u16 port_id) { int ret; @@ -635,6 +651,7 @@ int afe_get_port_type(u16 port_id) return ret; } +EXPORT_SYMBOL(afe_get_port_type); int afe_sizeof_cfg_cmd(u16 port_id) { @@ -712,6 +729,12 @@ int afe_sizeof_cfg_cmd(u16 port_id) return ret_size; } +/** + * afe_q6_interface_prepare - + * wrapper API to check Q6 AFE registered to APR otherwise registers + * + * Returns 0 on success or error on failure. + */ int afe_q6_interface_prepare(void) { int ret = 0; @@ -729,6 +752,7 @@ int afe_q6_interface_prepare(void) } return ret; } +EXPORT_SYMBOL(afe_q6_interface_prepare); /* * afe_apr_send_pkt : returns 0 on success, negative otherwise. @@ -2059,6 +2083,15 @@ int afe_send_aanc_version( return ret; } +/** + * afe_port_set_mad_type - + * to update mad type + * + * @port_id: AFE port id number + * @mad_type: MAD type enum value + * + * Returns 0 on success or error on failure. + */ int afe_port_set_mad_type(u16 port_id, enum afe_mad_type mad_type) { int i; @@ -2077,7 +2110,16 @@ int afe_port_set_mad_type(u16 port_id, enum afe_mad_type mad_type) atomic_set(&afe_ports_mad_type[i], mad_type); return 0; } +EXPORT_SYMBOL(afe_port_set_mad_type); +/** + * afe_port_get_mad_type - + * to retrieve mad type + * + * @port_id: AFE port id number + * + * Returns valid enum value on success or MAD_HW_NONE on failure. + */ enum afe_mad_type afe_port_get_mad_type(u16 port_id) { int i; @@ -2093,7 +2135,19 @@ enum afe_mad_type afe_port_get_mad_type(u16 port_id) } return (enum afe_mad_type) atomic_read(&afe_ports_mad_type[i]); } +EXPORT_SYMBOL(afe_port_get_mad_type); +/** + * afe_set_config - + * to configure AFE session with + * specified configuration for given config type + * + * @config_type: config type + * @config_data: configuration to pass to AFE session + * @arg: argument used in specific config types + * + * Returns 0 on success or error value on port start failure. + */ int afe_set_config(enum afe_config_type config_type, void *config_data, int arg) { int ret; @@ -2247,6 +2301,16 @@ int afe_send_spdif_clk_cfg(struct afe_param_id_spdif_clk_cfg *cfg, return ret; } +/** + * afe_send_spdif_ch_status_cfg - + * to configure AFE session with + * specified channel status configuration + * + * @ch_status_cfg: channel status configutation + * @port_id: AFE port id number + * + * Returns 0 on success or error value on port start failure. + */ int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg *ch_status_cfg, u16 port_id) { @@ -2326,6 +2390,7 @@ int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg fail_cmd: return ret; } +EXPORT_SYMBOL(afe_send_spdif_ch_status_cfg); static int afe_send_cmd_port_start(u16 port_id) { @@ -2388,6 +2453,16 @@ static int afe_aanc_start(uint16_t tx_port_id, uint16_t rx_port_id) return ret; } +/** + * afe_spdif_port_start - to configure AFE session with + * specified port configuration + * + * @port_id: AFE port id number + * @spdif_port: spdif port configutation + * @rate: sampling rate of port + * + * Returns 0 on success or error value on port start failure. + */ int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port, u32 rate) { @@ -2463,6 +2538,7 @@ int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port, fail_cmd: return ret; } +EXPORT_SYMBOL(afe_spdif_port_start); int afe_send_slot_mapping_cfg( struct afe_param_id_slot_mapping_cfg *slot_mapping_cfg, @@ -2622,6 +2698,17 @@ int afe_send_custom_tdm_header_cfg( return ret; } +/** + * afe_tdm_port_start - to configure AFE session with + * specified port configuration + * + * @port_id: AFE port id number + * @tdm_port: TDM port configutation + * @rate: sampling rate of port + * @num_groups: number of TDM groups + * + * Returns 0 on success or error value on port start failure. + */ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, u32 rate, u16 num_groups) { @@ -2749,7 +2836,16 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, fail_cmd: return ret; } +EXPORT_SYMBOL(afe_tdm_port_start); +/** + * afe_set_cal_mode - + * set cal mode for AFE calibration + * + * @port_id: AFE port id number + * @afe_cal_mode: AFE calib mode + * + */ void afe_set_cal_mode(u16 port_id, enum afe_cal_mode afe_cal_mode) { uint16_t port_index; @@ -2757,11 +2853,20 @@ void afe_set_cal_mode(u16 port_id, enum afe_cal_mode afe_cal_mode) port_index = afe_get_port_index(port_id); this_afe.afe_cal_mode[port_index] = afe_cal_mode; } +EXPORT_SYMBOL(afe_set_cal_mode); +/** + * afe_set_routing_callback - + * Update callback function for routing + * + * @cb: callback function to update with + * + */ void afe_set_routing_callback(routing_cb cb) { this_afe.rt_cb = cb; } +EXPORT_SYMBOL(afe_set_routing_callback); int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) { @@ -3590,6 +3695,16 @@ int afe_get_port_index(u16 port_id) } } +/** + * afe_open - + * command to open AFE port + * + * @port_id: AFE port id + * @afe_config: AFE port config to pass + * @rate: sample rate + * + * Returns 0 on success or error on failure + */ int afe_open(u16 port_id, union afe_port_config *afe_config, int rate) { @@ -3767,7 +3882,18 @@ int afe_open(u16 port_id, mutex_unlock(&this_afe.afe_cmd_lock); return ret; } +EXPORT_SYMBOL(afe_open); +/** + * afe_loopback - + * command to set loopback between AFE ports + * + * @enable: enable or disable loopback + * @rx_port: AFE RX port ID + * @tx_port: AFE TX port ID + * + * Returns 0 on success or error on failure + */ int afe_loopback(u16 enable, u16 rx_port, u16 tx_port) { struct afe_loopback_cfg_v1 lb_cmd; @@ -3825,7 +3951,17 @@ int afe_loopback(u16 enable, u16 rx_port, u16 tx_port) pr_err("%s: AFE loopback failed %d\n", __func__, ret); return ret; } +EXPORT_SYMBOL(afe_loopback); +/** + * afe_loopback_gain - + * command to set gain for AFE loopback + * + * @port_id: AFE port id + * @volume: gain value to set + * + * Returns 0 on success or error on failure + */ int afe_loopback_gain(u16 port_id, u16 volume) { struct afe_loopback_gain_per_path_param set_param; @@ -3908,6 +4044,7 @@ int afe_loopback_gain(u16 port_id, u16 volume) fail_cmd: return ret; } +EXPORT_SYMBOL(afe_loopback_gain); int afe_pseudo_port_start_nowait(u16 port_id) { @@ -4094,6 +4231,16 @@ int afe_port_group_set_param(u16 group_id, return ret; } +/** + * afe_port_group_enable - + * command to enable AFE port group + * + * @group_id: group ID for AFE port group + * @afe_group_config: config for AFE group + * @enable: flag to indicate enable or disable + * + * Returns 0 on success or error on failure + */ int afe_port_group_enable(u16 group_id, union afe_port_group_config *afe_group_config, u16 enable) @@ -4146,6 +4293,7 @@ int afe_port_group_enable(u16 group_id, return ret; } +EXPORT_SYMBOL(afe_port_group_enable); int afe_stop_pseudo_port(u16 port_id) { @@ -4191,11 +4339,28 @@ int afe_stop_pseudo_port(u16 port_id) return ret; } +/** + * afe_req_mmap_handle - + * Retrieve AFE memory map handle + * + * @ac: AFE audio client + * + * Returns memory map handle + */ uint32_t afe_req_mmap_handle(struct afe_audio_client *ac) { return ac->mem_map_handle; } +EXPORT_SYMBOL(afe_req_mmap_handle); +/** + * q6afe_audio_client_alloc - + * Assign new AFE audio client + * + * @priv: privata data to hold for audio client + * + * Returns ac pointer on success or NULL on failure + */ struct afe_audio_client *q6afe_audio_client_alloc(void *priv) { struct afe_audio_client *ac; @@ -4220,7 +4385,19 @@ struct afe_audio_client *q6afe_audio_client_alloc(void *priv) return ac; } +EXPORT_SYMBOL(q6afe_audio_client_alloc); +/** + * q6afe_audio_client_buf_alloc_contiguous - + * Allocate contiguous shared buffers + * + * @dir: RX or TX direction of AFE port + * @ac: AFE audio client handle + * @bufsz: size of each shared buffer + * @bufcnt: number of buffers + * + * Returns 0 on success or error on failure + */ int q6afe_audio_client_buf_alloc_contiguous(unsigned int dir, struct afe_audio_client *ac, unsigned int bufsz, @@ -4299,7 +4476,18 @@ int q6afe_audio_client_buf_alloc_contiguous(unsigned int dir, q6afe_audio_client_buf_free_contiguous(dir, ac); return -EINVAL; } +EXPORT_SYMBOL(q6afe_audio_client_buf_alloc_contiguous); +/** + * afe_memory_map - + * command to map shared buffers to AFE + * + * @dma_addr_p: DMA physical address + * @dma_buf_sz: shared DMA buffer size + * @ac: AFE audio client handle + * + * Returns 0 on success or error on failure + */ int afe_memory_map(phys_addr_t dma_addr_p, u32 dma_buf_sz, struct afe_audio_client *ac) { @@ -4320,6 +4508,7 @@ int afe_memory_map(phys_addr_t dma_addr_p, u32 dma_buf_sz, return ret; } +EXPORT_SYMBOL(afe_memory_map); int afe_cmd_memory_map(phys_addr_t dma_addr_p, u32 dma_buf_sz) { @@ -4494,6 +4683,15 @@ int afe_cmd_memory_map_nowait(int port_id, phys_addr_t dma_addr_p, kfree(mmap_region_cmd); return ret; } + +/** + * q6afe_audio_client_buf_free_contiguous - + * frees the shared contiguous memory + * + * @dir: RX or TX direction of port + * @ac: AFE audio client handle + * + */ int q6afe_audio_client_buf_free_contiguous(unsigned int dir, struct afe_audio_client *ac) { @@ -4533,7 +4731,15 @@ int q6afe_audio_client_buf_free_contiguous(unsigned int dir, mutex_unlock(&ac->cmd_lock); return 0; } +EXPORT_SYMBOL(q6afe_audio_client_buf_free_contiguous); +/** + * q6afe_audio_client_free - + * frees the audio client from AFE + * + * @ac: AFE audio client handle + * + */ void q6afe_audio_client_free(struct afe_audio_client *ac) { int loopcnt; @@ -4552,7 +4758,16 @@ void q6afe_audio_client_free(struct afe_audio_client *ac) } kfree(ac); } +EXPORT_SYMBOL(q6afe_audio_client_free); +/** + * afe_cmd_memory_unmap - + * command to unmap memory for AFE shared buffer + * + * @mem_map_handle: memory map handle to be unmapped + * + * Returns 0 on success or error on failure + */ int afe_cmd_memory_unmap(u32 mem_map_handle) { int ret = 0; @@ -4593,6 +4808,7 @@ int afe_cmd_memory_unmap(u32 mem_map_handle) return ret; } +EXPORT_SYMBOL(afe_cmd_memory_unmap); int afe_cmd_memory_unmap_nowait(u32 mem_map_handle) { @@ -4629,6 +4845,16 @@ int afe_cmd_memory_unmap_nowait(u32 mem_map_handle) return ret; } +/** + * afe_register_get_events - + * register for events from proxy port + * + * @port_id: Port ID to register events + * @cb: callback function to invoke for events from proxy port + * @private_data: private data to sent back in callback fn + * + * Returns 0 on success or error on failure + */ int afe_register_get_events(u16 port_id, void (*cb)(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv), @@ -4681,7 +4907,16 @@ int afe_register_get_events(u16 port_id, __func__, ret); return ret; } +EXPORT_SYMBOL(afe_register_get_events); +/** + * afe_unregister_get_events - + * unregister for events from proxy port + * + * @port_id: Port ID to unregister events + * + * Returns 0 on success or error on failure + */ int afe_unregister_get_events(u16 port_id) { int ret = 0; @@ -4748,7 +4983,19 @@ int afe_unregister_get_events(u16 port_id) __func__, ret); return ret; } +EXPORT_SYMBOL(afe_unregister_get_events); +/** + * afe_rt_proxy_port_write - + * command for AFE RT proxy port write + * + * @buf_addr_p: Physical buffer address with + * playback data to proxy port + * @mem_map_handle: memory map handle of write buffer + * @bytes: number of bytes to write + * + * Returns 0 on success or error on failure + */ int afe_rt_proxy_port_write(phys_addr_t buf_addr_p, u32 mem_map_handle, int bytes) { @@ -4785,7 +5032,18 @@ int afe_rt_proxy_port_write(phys_addr_t buf_addr_p, return ret; } +EXPORT_SYMBOL(afe_rt_proxy_port_write); +/** + * afe_rt_proxy_port_read - + * command for AFE RT proxy port read + * + * @buf_addr_p: Physical buffer address to fill read data + * @mem_map_handle: memory map handle for buffer read + * @bytes: number of bytes to read + * + * Returns 0 on success or error on failure + */ int afe_rt_proxy_port_read(phys_addr_t buf_addr_p, u32 mem_map_handle, int bytes) { @@ -4820,6 +5078,7 @@ int afe_rt_proxy_port_read(phys_addr_t buf_addr_p, __func__, afecmd_rd.port_id, ret); return ret; } +EXPORT_SYMBOL(afe_rt_proxy_port_read); #ifdef CONFIG_DEBUG_FS static struct dentry *debugfs_afelb; @@ -4985,6 +5244,14 @@ static void config_debug_fs_exit(void) } #endif +/** + * afe_set_dtmf_gen_rx_portid - + * Set port_id for DTMF tone generation + * + * @port_id: AFE port id + * @set: set or reset port id value for dtmf gen + * + */ void afe_set_dtmf_gen_rx_portid(u16 port_id, int set) { if (set) @@ -4992,7 +5259,18 @@ void afe_set_dtmf_gen_rx_portid(u16 port_id, int set) else if (this_afe.dtmf_gen_rx_portid == port_id) this_afe.dtmf_gen_rx_portid = -1; } +EXPORT_SYMBOL(afe_set_dtmf_gen_rx_portid); +/** + * afe_dtmf_generate_rx - command to generate AFE DTMF RX + * + * @duration_in_ms: Duration in ms for dtmf tone + * @high_freq: Higher frequency for dtmf + * @low_freq: lower frequency for dtmf + * @gain: Gain value for DTMF tone + * + * Returns 0 on success, appropriate error code otherwise + */ int afe_dtmf_generate_rx(int64_t duration_in_ms, uint16_t high_freq, uint16_t low_freq, uint16_t gain) @@ -5079,6 +5357,7 @@ int afe_dtmf_generate_rx(int64_t duration_in_ms, pr_err("%s: failed %d\n", __func__, ret); return ret; } +EXPORT_SYMBOL(afe_dtmf_generate_rx); static int afe_sidetone_iir(u16 tx_port_id) { @@ -5556,6 +5835,13 @@ int afe_port_stop_nowait(int port_id) } +/** + * afe_close - command to close AFE port + * + * @port_id: AFE port id + * + * Returns 0 on success, appropriate error code otherwise + */ int afe_close(int port_id) { struct afe_port_cmd_device_stop stop; @@ -5678,6 +5964,7 @@ int afe_close(int port_id) fail_cmd: return ret; } +EXPORT_SYMBOL(afe_close); int afe_set_digital_codec_core_clock(u16 port_id, struct afe_digital_clk_cfg *cfg) @@ -5754,6 +6041,14 @@ int afe_set_digital_codec_core_clock(u16 port_id, return ret; } +/** + * afe_set_lpass_clock - Enable AFE lpass clock + * + * @port_id: AFE port id + * @cfg: pointer to clk set struct + * + * Returns 0 on success, appropriate error code otherwise + */ int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg) { struct afe_lpass_clk_config_command clk_cfg; @@ -5844,6 +6139,7 @@ int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg) mutex_unlock(&this_afe.afe_cmd_lock); return ret; } +EXPORT_SYMBOL(afe_set_lpass_clock); /** * afe_set_lpass_clk_cfg - Set AFE clk config @@ -6325,6 +6621,15 @@ int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) return ret; } +/** + * afe_get_av_dev_drift - + * command to retrieve AV drift + * + * @timing_stats: timing stats to be updated with AV drift values + * @port: AFE port ID + * + * Returns 0 on success or error on failure + */ int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats, u16 port) { @@ -6406,6 +6711,7 @@ int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats, exit: return ret; } +EXPORT_SYMBOL(afe_get_av_dev_drift); int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) { @@ -6486,6 +6792,18 @@ int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) return ret; } +/** + * afe_spk_prot_feed_back_cfg - + * command to setup spk protection feedback config + * + * @src_port: source port id + * @dst_port: destination port id + * @l_ch: left speaker active or not + * @r_ch: right speaker active or not + * @enable: flag to enable or disable + * + * Returns 0 on success or error on failure + */ int afe_spk_prot_feed_back_cfg(int src_port, int dst_port, int l_ch, int r_ch, u32 enable) { @@ -6531,6 +6849,7 @@ int afe_spk_prot_feed_back_cfg(int src_port, int dst_port, fail_cmd: return ret; } +EXPORT_SYMBOL(afe_spk_prot_feed_back_cfg); static int get_cal_type_index(int32_t cal_type) { @@ -7200,7 +7519,7 @@ int afe_unmap_rtac_block(uint32_t *mem_map_handle) return result; } -static int __init afe_init(void) +int __init afe_init(void) { int i = 0, ret; @@ -7231,7 +7550,7 @@ static int __init afe_init(void) return 0; } -static void __exit afe_exit(void) +void __exit afe_exit(void) { afe_delete_cal_data(); @@ -7239,6 +7558,3 @@ static void __exit afe_exit(void) mutex_destroy(&this_afe.afe_cmd_lock); wakeup_source_trash(&wl.ws); } - -device_initcall(afe_init); -__exitcall(afe_exit); diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 0a4216a0e28c..4e988ee489e6 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -981,6 +981,15 @@ int q6asm_audio_client_buf_free(unsigned int dir, return 0; } +/** + * q6asm_audio_client_buf_free_contiguous - + * frees the memory buffers for ASM + * + * @dir: RX or TX direction + * @ac: audio client handle + * + * Returns 0 on success or error on failure + */ int q6asm_audio_client_buf_free_contiguous(unsigned int dir, struct audio_client *ac) { @@ -1030,7 +1039,15 @@ int q6asm_audio_client_buf_free_contiguous(unsigned int dir, mutex_unlock(&ac->cmd_lock); return 0; } +EXPORT_SYMBOL(q6asm_audio_client_buf_free_contiguous); +/** + * q6asm_audio_client_free - + * frees the audio client for ASM + * + * @ac: audio client handle + * + */ void q6asm_audio_client_free(struct audio_client *ac) { int loopcnt; @@ -1075,7 +1092,17 @@ void q6asm_audio_client_free(struct audio_client *ac) ac = NULL; mutex_unlock(&session_lock); } +EXPORT_SYMBOL(q6asm_audio_client_free); +/** + * q6asm_set_io_mode - + * Update IO mode for ASM + * + * @ac: audio client handle + * @mode1: IO mode to update + * + * Returns 0 on success or error on failure + */ int q6asm_set_io_mode(struct audio_client *ac, uint32_t mode1) { uint32_t mode; @@ -1102,6 +1129,7 @@ int q6asm_set_io_mode(struct audio_client *ac, uint32_t mode1) return ret; } +EXPORT_SYMBOL(q6asm_set_io_mode); void *q6asm_mmap_apr_reg(void) { @@ -1123,6 +1151,15 @@ void *q6asm_mmap_apr_reg(void) return NULL; } +/** + * q6asm_send_stream_cmd - + * command to send for ASM stream + * + * @ac: audio client handle + * @data: event data + * + * Returns 0 on success or error on failure + */ int q6asm_send_stream_cmd(struct audio_client *ac, struct msm_adsp_event_data *data) { @@ -1188,7 +1225,17 @@ int q6asm_send_stream_cmd(struct audio_client *ac, done: return rc; } +EXPORT_SYMBOL(q6asm_send_stream_cmd); +/** + * q6asm_audio_client_alloc - + * Alloc audio client for ASM + * + * @cb: callback fn + * @priv: private data + * + * Returns ac pointer on success or NULL on failure + */ struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv) { struct audio_client *ac; @@ -1284,7 +1331,16 @@ struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv) kfree(ac); return NULL; } +EXPORT_SYMBOL(q6asm_audio_client_alloc); +/** + * q6asm_get_audio_client - + * Retrieve audio client for ASM + * + * @session_id: ASM session id + * + * Returns valid pointer on success or NULL on failure + */ struct audio_client *q6asm_get_audio_client(int session_id) { if (session_id == ASM_CONTROL_SESSION) @@ -1303,7 +1359,19 @@ struct audio_client *q6asm_get_audio_client(int session_id) err: return NULL; } +EXPORT_SYMBOL(q6asm_get_audio_client); +/** + * q6asm_audio_client_buf_alloc - + * Allocs memory from ION for ASM + * + * @dir: RX or TX direction + * @ac: Audio client handle + * @bufsz: size of each buffer + * @bufcnt: number of buffers to alloc + * + * Returns 0 on success or error on failure + */ int q6asm_audio_client_buf_alloc(unsigned int dir, struct audio_client *ac, unsigned int bufsz, @@ -1393,7 +1461,19 @@ int q6asm_audio_client_buf_alloc(unsigned int dir, q6asm_audio_client_buf_free(dir, ac); return -EINVAL; } +EXPORT_SYMBOL(q6asm_audio_client_buf_alloc); +/** + * q6asm_audio_client_buf_alloc_contiguous - + * Alloc contiguous memory from ION for ASM + * + * @dir: RX or TX direction + * @ac: Audio client handle + * @bufsz: size of each buffer + * @bufcnt: number of buffers to alloc + * + * Returns 0 on success or error on failure + */ int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir, struct audio_client *ac, unsigned int bufsz, @@ -1496,6 +1576,7 @@ int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir, q6asm_audio_client_buf_free_contiguous(dir, ac); return -EINVAL; } +EXPORT_SYMBOL(q6asm_audio_client_buf_alloc_contiguous); static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) { @@ -2134,6 +2215,18 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) return 0; } +/** + * q6asm_is_cpu_buf_avail - + * retrieve next CPU buf avail + * + * @dir: RX or TX direction + * @ac: Audio client handle + * @size: size pointer to be updated with size of buffer + * @index: index pointer to be updated with + * CPU buffer index available + * + * Returns buffer pointer on success or NULL on failure + */ void *q6asm_is_cpu_buf_avail(int dir, struct audio_client *ac, uint32_t *size, uint32_t *index) { @@ -2188,7 +2281,17 @@ void *q6asm_is_cpu_buf_avail(int dir, struct audio_client *ac, uint32_t *size, } return NULL; } +EXPORT_SYMBOL(q6asm_is_cpu_buf_avail); +/** + * q6asm_cpu_buf_release - + * releases cpu buffer for ASM + * + * @dir: RX or TX direction + * @ac: Audio client handle + * + * Returns 0 on success or error on failure + */ int q6asm_cpu_buf_release(int dir, struct audio_client *ac) { struct audio_port_data *port; @@ -2222,7 +2325,20 @@ int q6asm_cpu_buf_release(int dir, struct audio_client *ac) exit: return ret; } +EXPORT_SYMBOL(q6asm_cpu_buf_release); +/** + * q6asm_is_cpu_buf_avail_nolock - + * retrieve next CPU buf avail without lock acquire + * + * @dir: RX or TX direction + * @ac: Audio client handle + * @size: size pointer to be updated with size of buffer + * @index: index pointer to be updated with + * CPU buffer index available + * + * Returns buffer pointer on success or NULL on failure + */ void *q6asm_is_cpu_buf_avail_nolock(int dir, struct audio_client *ac, uint32_t *size, uint32_t *index) { @@ -2271,6 +2387,7 @@ void *q6asm_is_cpu_buf_avail_nolock(int dir, struct audio_client *ac, port->max_buf_cnt); return data; } +EXPORT_SYMBOL(q6asm_is_cpu_buf_avail_nolock); int q6asm_is_dsp_buf_avail(int dir, struct audio_client *ac) { @@ -2559,6 +2676,15 @@ static int __q6asm_open_read(struct audio_client *ac, return rc; } +/** + * q6asm_open_read - + * command to open ASM in read mode + * + * @ac: Audio client handle + * @format: capture format for ASM + * + * Returns 0 on success or error on failure + */ int q6asm_open_read(struct audio_client *ac, uint32_t format) { @@ -2566,6 +2692,7 @@ int q6asm_open_read(struct audio_client *ac, PCM_MEDIA_FORMAT_V2 /*media fmt block ver*/, false/*ts_mode*/); } +EXPORT_SYMBOL(q6asm_open_read); int q6asm_open_read_v2(struct audio_client *ac, uint32_t format, uint16_t bits_per_sample) @@ -2608,6 +2735,16 @@ int q6asm_open_read_v4(struct audio_client *ac, uint32_t format, } EXPORT_SYMBOL(q6asm_open_read_v4); +/** + * q6asm_open_write_compressed - + * command to open ASM in compressed write mode + * + * @ac: Audio client handle + * @format: playback format for ASM + * @passthrough_flag: flag to indicate passthrough option + * + * Returns 0 on success or error on failure + */ int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format, uint32_t passthrough_flag) { @@ -2711,6 +2848,7 @@ int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_open_write_compressed); static int __q6asm_open_write(struct audio_client *ac, uint32_t format, uint16_t bits_per_sample, uint32_t stream_id, @@ -2871,6 +3009,7 @@ int q6asm_open_write(struct audio_client *ac, uint32_t format) false /*gapless*/, PCM_MEDIA_FORMAT_V2 /*pcm_format_block_ver*/); } +EXPORT_SYMBOL(q6asm_open_write); int q6asm_open_write_v2(struct audio_client *ac, uint32_t format, uint16_t bits_per_sample) @@ -3128,6 +3267,16 @@ static int __q6asm_open_read_write(struct audio_client *ac, uint32_t rd_format, return rc; } +/** + * q6asm_open_read_write - + * command to open ASM in read/write mode + * + * @ac: Audio client handle + * @rd_format: capture format for ASM + * @wr_format: playback format for ASM + * + * Returns 0 on success or error on failure + */ int q6asm_open_read_write(struct audio_client *ac, uint32_t rd_format, uint32_t wr_format) { @@ -3136,7 +3285,22 @@ int q6asm_open_read_write(struct audio_client *ac, uint32_t rd_format, 16 /*bits_per_sample*/, false /*overwrite_topology*/, 0); } +EXPORT_SYMBOL(q6asm_open_read_write); +/** + * q6asm_open_read_write_v2 - + * command to open ASM in bi-directional read/write mode + * + * @ac: Audio client handle + * @rd_format: capture format for ASM + * @wr_format: playback format for ASM + * @is_meta_data_mode: mode to indicate if meta data present + * @bits_per_sample: number of bits per sample + * @overwrite_topology: topology to be overwritten flag + * @topology: Topology for ASM + * + * Returns 0 on success or error on failure + */ int q6asm_open_read_write_v2(struct audio_client *ac, uint32_t rd_format, uint32_t wr_format, bool is_meta_data_mode, uint32_t bits_per_sample, bool overwrite_topology, @@ -3146,7 +3310,17 @@ int q6asm_open_read_write_v2(struct audio_client *ac, uint32_t rd_format, is_meta_data_mode, bits_per_sample, overwrite_topology, topology); } +EXPORT_SYMBOL(q6asm_open_read_write_v2); +/** + * q6asm_open_loopback_v2 - + * command to open ASM in loopback mode + * + * @ac: Audio client handle + * @bits_per_sample: number of bits per sample + * + * Returns 0 on success or error on failure + */ int q6asm_open_loopback_v2(struct audio_client *ac, uint16_t bits_per_sample) { int rc = 0x00; @@ -3243,8 +3417,19 @@ int q6asm_open_loopback_v2(struct audio_client *ac, uint16_t bits_per_sample) fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_open_loopback_v2); - +/** + * q6asm_open_transcode_loopback - + * command to open ASM in transcode loopback mode + * + * @ac: Audio client handle + * @bits_per_sample: number of bits per sample + * @source_format: Format of clip + * @sink_format: end device supported format + * + * Returns 0 on success or error on failure + */ int q6asm_open_transcode_loopback(struct audio_client *ac, uint16_t bits_per_sample, uint32_t source_format, uint32_t sink_format) @@ -3339,6 +3524,7 @@ int q6asm_open_transcode_loopback(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_open_transcode_loopback); static int q6asm_set_shared_circ_buff(struct audio_client *ac, @@ -3719,7 +3905,19 @@ int q6asm_get_shared_pos(struct audio_client *ac, uint32_t *read_index, __func__); return -EAGAIN; } +EXPORT_SYMBOL(q6asm_get_shared_pos); +/** + * q6asm_run - + * command to set ASM to run state + * + * @ac: Audio client handle + * @flags: Flags for session + * @msw_ts: upper 32bits timestamp + * @lsw_ts: lower 32bits timestamp + * + * Returns 0 on success or error on failure + */ int q6asm_run(struct audio_client *ac, uint32_t flags, uint32_t msw_ts, uint32_t lsw_ts) { @@ -3775,6 +3973,7 @@ int q6asm_run(struct audio_client *ac, uint32_t flags, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_run); static int __q6asm_run_nowait(struct audio_client *ac, uint32_t flags, uint32_t msw_ts, uint32_t lsw_ts, uint32_t stream_id) @@ -3807,11 +4006,23 @@ static int __q6asm_run_nowait(struct audio_client *ac, uint32_t flags, return 0; } +/** + * q6asm_run_nowait - + * command to set ASM to run state with no wait for ack + * + * @ac: Audio client handle + * @flags: Flags for session + * @msw_ts: upper 32bits timestamp + * @lsw_ts: lower 32bits timestamp + * + * Returns 0 on success or error on failure + */ int q6asm_run_nowait(struct audio_client *ac, uint32_t flags, uint32_t msw_ts, uint32_t lsw_ts) { return __q6asm_run_nowait(ac, flags, msw_ts, lsw_ts, ac->stream_id); } +EXPORT_SYMBOL(q6asm_run_nowait); int q6asm_stream_run_nowait(struct audio_client *ac, uint32_t flags, uint32_t msw_ts, uint32_t lsw_ts, uint32_t stream_id) @@ -3819,6 +4030,20 @@ int q6asm_stream_run_nowait(struct audio_client *ac, uint32_t flags, return __q6asm_run_nowait(ac, flags, msw_ts, lsw_ts, stream_id); } +/** + * q6asm_enc_cfg_blk_aac - + * command to set encode cfg block for aac + * + * @ac: Audio client handle + * @frames_per_buf: number of frames per buffer + * @sample_rate: Sample rate + * @channels: number of ASM channels + * @bit_rate: Bit rate info + * @mode: mode of AAC stream encode + * @format: aac format flag + * + * Returns 0 on success or error on failure + */ int q6asm_enc_cfg_blk_aac(struct audio_client *ac, uint32_t frames_per_buf, uint32_t sample_rate, uint32_t channels, @@ -3874,7 +4099,18 @@ int q6asm_enc_cfg_blk_aac(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_enc_cfg_blk_aac); +/** + * q6asm_enc_cfg_blk_g711 - + * command to set encode cfg block for g711 + * + * @ac: Audio client handle + * @frames_per_buf: number of frames per buffer + * @sample_rate: Sample rate + * + * Returns 0 on success or error on failure + */ int q6asm_enc_cfg_blk_g711(struct audio_client *ac, uint32_t frames_per_buf, uint32_t sample_rate) @@ -3925,7 +4161,17 @@ int q6asm_enc_cfg_blk_g711(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_enc_cfg_blk_g711); +/** + * q6asm_set_encdec_chan_map - + * command to set encdec channel map + * + * @ac: Audio client handle + * @channels: number of channels + * + * Returns 0 on success or error on failure + */ int q6asm_set_encdec_chan_map(struct audio_client *ac, uint32_t num_channels) { @@ -3978,6 +4224,7 @@ int q6asm_set_encdec_chan_map(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_set_encdec_chan_map); /* * q6asm_enc_cfg_blk_pcm_v4 - sends encoder configuration parameters @@ -4178,6 +4425,20 @@ int q6asm_enc_cfg_blk_pcm_v3(struct audio_client *ac, } EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_v3); +/** + * q6asm_enc_cfg_blk_pcm_v2 - + * command to set encode config block for pcm_v2 + * + * @ac: Audio client handle + * @rate: sample rate + * @channels: number of channels + * @bits_per_sample: number of bits per sample + * @use_default_chmap: Flag indicating to use default ch_map or not + * @use_back_flavor: back flavor flag + * @channel_map: Custom channel map settings + * + * Returns 0 on success or error on failure + */ int q6asm_enc_cfg_blk_pcm_v2(struct audio_client *ac, uint32_t rate, uint32_t channels, uint16_t bits_per_sample, bool use_default_chmap, bool use_back_flavor, u8 *channel_map) @@ -4256,6 +4517,7 @@ int q6asm_enc_cfg_blk_pcm_v2(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_v2); static int __q6asm_enc_cfg_blk_pcm_v4(struct audio_client *ac, uint32_t rate, uint32_t channels, @@ -4286,11 +4548,22 @@ static int __q6asm_enc_cfg_blk_pcm(struct audio_client *ac, bits_per_sample, true, false, NULL); } +/** + * q6asm_enc_cfg_blk_pcm - + * command to set encode config block for pcm + * + * @ac: Audio client handle + * @rate: sample rate + * @channels: number of channels + * + * Returns 0 on success or error on failure + */ int q6asm_enc_cfg_blk_pcm(struct audio_client *ac, uint32_t rate, uint32_t channels) { return __q6asm_enc_cfg_blk_pcm(ac, rate, channels, 16); } +EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm); int q6asm_enc_cfg_blk_pcm_format_support(struct audio_client *ac, uint32_t rate, uint32_t channels, uint16_t bits_per_sample) @@ -4343,6 +4616,16 @@ int q6asm_enc_cfg_blk_pcm_format_support_v4(struct audio_client *ac, } EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_format_support_v4); +/** + * q6asm_enc_cfg_blk_pcm_native - + * command to set encode config block for pcm_native + * + * @ac: Audio client handle + * @rate: sample rate + * @channels: number of channels + * + * Returns 0 on success or error on failure + */ int q6asm_enc_cfg_blk_pcm_native(struct audio_client *ac, uint32_t rate, uint32_t channels) { @@ -4405,6 +4688,7 @@ int q6asm_enc_cfg_blk_pcm_native(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_native); static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, bool use_back_flavor) @@ -4477,6 +4761,15 @@ static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, return 0; } +/** + * q6asm_enable_sbrps - + * command to enable sbrps for ASM + * + * @ac: Audio client handle + * @sbr_ps_enable: flag for sbr_ps enable or disable + * + * Returns 0 on success or error on failure + */ int q6asm_enable_sbrps(struct audio_client *ac, uint32_t sbr_ps_enable) { @@ -4528,7 +4821,18 @@ int q6asm_enable_sbrps(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_enable_sbrps); +/** + * q6asm_cfg_dual_mono_aac - + * command to set config for dual mono aac + * + * @ac: Audio client handle + * @sce_left: left sce val + * @sce_right: right sce val + * + * Returns 0 on success or error on failure + */ int q6asm_cfg_dual_mono_aac(struct audio_client *ac, uint16_t sce_left, uint16_t sce_right) { @@ -4577,6 +4881,7 @@ int q6asm_cfg_dual_mono_aac(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_cfg_dual_mono_aac); /* Support for selecting stereo mixing coefficients for B family not done */ int q6asm_cfg_aac_sel_mix_coef(struct audio_client *ac, uint32_t mix_coeff) @@ -4622,7 +4927,21 @@ int q6asm_cfg_aac_sel_mix_coef(struct audio_client *ac, uint32_t mix_coeff) fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_cfg_aac_sel_mix_coef); +/** + * q6asm_enc_cfg_blk_qcelp - + * command to set encode config block for QCELP + * + * @ac: Audio client handle + * @frames_per_buf: Number of frames per buffer + * @min_rate: Minimum Enc rate + * @max_rate: Maximum Enc rate + * reduced_rate_level: Reduced rate level + * @rate_modulation_cmd: rate modulation command + * + * Returns 0 on success or error on failure + */ int q6asm_enc_cfg_blk_qcelp(struct audio_client *ac, uint32_t frames_per_buf, uint16_t min_rate, uint16_t max_rate, uint16_t reduced_rate_level, uint16_t rate_modulation_cmd) @@ -4677,7 +4996,20 @@ int q6asm_enc_cfg_blk_qcelp(struct audio_client *ac, uint32_t frames_per_buf, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_enc_cfg_blk_qcelp); +/** + * q6asm_enc_cfg_blk_evrc - + * command to set encode config block for EVRC + * + * @ac: Audio client handle + * @frames_per_buf: Number of frames per buffer + * @min_rate: Minimum Enc rate + * @max_rate: Maximum Enc rate + * @rate_modulation_cmd: rate modulation command + * + * Returns 0 on success or error on failure + */ int q6asm_enc_cfg_blk_evrc(struct audio_client *ac, uint32_t frames_per_buf, uint16_t min_rate, uint16_t max_rate, uint16_t rate_modulation_cmd) @@ -4730,7 +5062,19 @@ int q6asm_enc_cfg_blk_evrc(struct audio_client *ac, uint32_t frames_per_buf, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_enc_cfg_blk_evrc); +/** + * q6asm_enc_cfg_blk_amrnb - + * command to set encode config block for AMRNB + * + * @ac: Audio client handle + * @frames_per_buf: Number of frames per buffer + * @band_mode: Band mode used + * @dtx_enable: DTX en flag + * + * Returns 0 on success or error on failure + */ int q6asm_enc_cfg_blk_amrnb(struct audio_client *ac, uint32_t frames_per_buf, uint16_t band_mode, uint16_t dtx_enable) { @@ -4779,7 +5123,19 @@ int q6asm_enc_cfg_blk_amrnb(struct audio_client *ac, uint32_t frames_per_buf, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_enc_cfg_blk_amrnb); +/** + * q6asm_enc_cfg_blk_amrwb - + * command to set encode config block for AMRWB + * + * @ac: Audio client handle + * @frames_per_buf: Number of frames per buffer + * @band_mode: Band mode used + * @dtx_enable: DTX en flag + * + * Returns 0 on success or error on failure + */ int q6asm_enc_cfg_blk_amrwb(struct audio_client *ac, uint32_t frames_per_buf, uint16_t band_mode, uint16_t dtx_enable) { @@ -4828,6 +5184,7 @@ int q6asm_enc_cfg_blk_amrwb(struct audio_client *ac, uint32_t frames_per_buf, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_enc_cfg_blk_amrwb); static int __q6asm_media_format_block_pcm(struct audio_client *ac, @@ -5075,6 +5432,16 @@ static int __q6asm_media_format_block_pcm_v4(struct audio_client *ac, return rc; } +/** + * q6asm_media_format_block_pcm - + * command to set mediafmt block for PCM on ASM stream + * + * @ac: Audio client handle + * @rate: sample rate + * @channels: number of ASM channels + * + * Returns 0 on success or error on failure + */ int q6asm_media_format_block_pcm(struct audio_client *ac, uint32_t rate, uint32_t channels) { @@ -5082,7 +5449,19 @@ int q6asm_media_format_block_pcm(struct audio_client *ac, channels, 16, ac->stream_id, true, NULL); } +EXPORT_SYMBOL(q6asm_media_format_block_pcm); +/** + * q6asm_media_format_block_pcm_format_support - + * command to set mediafmt block for PCM format support + * + * @ac: Audio client handle + * @rate: sample rate + * @channels: number of ASM channels + * @bits_per_sample: number of bits per sample + * + * Returns 0 on success or error on failure + */ int q6asm_media_format_block_pcm_format_support(struct audio_client *ac, uint32_t rate, uint32_t channels, uint16_t bits_per_sample) @@ -5091,6 +5470,7 @@ int q6asm_media_format_block_pcm_format_support(struct audio_client *ac, channels, bits_per_sample, ac->stream_id, true, NULL); } +EXPORT_SYMBOL(q6asm_media_format_block_pcm_format_support); int q6asm_media_format_block_pcm_format_support_v2(struct audio_client *ac, uint32_t rate, uint32_t channels, @@ -5668,24 +6048,65 @@ static int __q6asm_media_format_block_multi_aac(struct audio_client *ac, return rc; } +/** + * q6asm_media_format_block_multi_aac - + * command to set mediafmt block for multi_aac on ASM stream + * + * @ac: Audio client handle + * @cfg: multi_aac config + * + * Returns 0 on success or error on failure + */ int q6asm_media_format_block_multi_aac(struct audio_client *ac, struct asm_aac_cfg *cfg) { return __q6asm_media_format_block_multi_aac(ac, cfg, ac->stream_id); } +EXPORT_SYMBOL(q6asm_media_format_block_multi_aac); +/** + * q6asm_media_format_block_aac - + * command to set mediafmt block for aac on ASM + * + * @ac: Audio client handle + * @cfg: aac config + * + * Returns 0 on success or error on failure + */ int q6asm_media_format_block_aac(struct audio_client *ac, struct asm_aac_cfg *cfg) { return __q6asm_media_format_block_multi_aac(ac, cfg, ac->stream_id); } +EXPORT_SYMBOL(q6asm_media_format_block_aac); +/** + * q6asm_stream_media_format_block_aac - + * command to set mediafmt block for aac on ASM stream + * + * @ac: Audio client handle + * @cfg: aac config + * @stream_id: stream ID info + * + * Returns 0 on success or error on failure + */ int q6asm_stream_media_format_block_aac(struct audio_client *ac, struct asm_aac_cfg *cfg, int stream_id) { return __q6asm_media_format_block_multi_aac(ac, cfg, stream_id); } +EXPORT_SYMBOL(q6asm_stream_media_format_block_aac); +/** + * q6asm_media_format_block_wma - + * command to set mediafmt block for wma on ASM stream + * + * @ac: Audio client handle + * @cfg: wma config + * @stream_id: stream ID info + * + * Returns 0 on success or error on failure + */ int q6asm_media_format_block_wma(struct audio_client *ac, void *cfg, int stream_id) { @@ -5740,7 +6161,18 @@ int q6asm_media_format_block_wma(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_media_format_block_wma); +/** + * q6asm_media_format_block_wmapro - + * command to set mediafmt block for wmapro on ASM stream + * + * @ac: Audio client handle + * @cfg: wmapro config + * @stream_id: stream ID info + * + * Returns 0 on success or error on failure + */ int q6asm_media_format_block_wmapro(struct audio_client *ac, void *cfg, int stream_id) { @@ -5800,7 +6232,18 @@ int q6asm_media_format_block_wmapro(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_media_format_block_wmapro); +/** + * q6asm_media_format_block_amrwbplus - + * command to set mediafmt block for amrwbplus on ASM stream + * + * @ac: Audio client handle + * @cfg: amrwbplus config + * @stream_id: stream ID info + * + * Returns 0 on success or error on failure + */ int q6asm_media_format_block_amrwbplus(struct audio_client *ac, struct asm_amrwbplus_cfg *cfg) { @@ -5848,7 +6291,18 @@ int q6asm_media_format_block_amrwbplus(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_media_format_block_amrwbplus); +/** + * q6asm_stream_media_format_block_flac - + * command to set mediafmt block for flac on ASM stream + * + * @ac: Audio client handle + * @cfg: FLAC config + * @stream_id: stream ID info + * + * Returns 0 on success or error on failure + */ int q6asm_stream_media_format_block_flac(struct audio_client *ac, struct asm_flac_cfg *cfg, int stream_id) { @@ -5901,7 +6355,18 @@ int q6asm_stream_media_format_block_flac(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_stream_media_format_block_flac); +/** + * q6asm_media_format_block_alac - + * command to set mediafmt block for alac on ASM stream + * + * @ac: Audio client handle + * @cfg: ALAC config + * @stream_id: stream ID info + * + * Returns 0 on success or error on failure + */ int q6asm_media_format_block_alac(struct audio_client *ac, struct asm_alac_cfg *cfg, int stream_id) { @@ -5957,6 +6422,7 @@ int q6asm_media_format_block_alac(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_media_format_block_alac); /* * q6asm_media_format_block_g711 - sends g711 decoder configuration @@ -6027,6 +6493,16 @@ int q6asm_media_format_block_g711(struct audio_client *ac, } EXPORT_SYMBOL(q6asm_media_format_block_g711); +/** + * q6asm_stream_media_format_block_vorbis - + * command to set mediafmt block for vorbis on ASM stream + * + * @ac: Audio client handle + * @cfg: vorbis config + * @stream_id: stream ID info + * + * Returns 0 on success or error on failure + */ int q6asm_stream_media_format_block_vorbis(struct audio_client *ac, struct asm_vorbis_cfg *cfg, int stream_id) { @@ -6071,7 +6547,18 @@ int q6asm_stream_media_format_block_vorbis(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_stream_media_format_block_vorbis); +/** + * q6asm_media_format_block_ape - + * command to set mediafmt block for APE on ASM stream + * + * @ac: Audio client handle + * @cfg: APE config + * @stream_id: stream ID info + * + * Returns 0 on success or error on failure + */ int q6asm_media_format_block_ape(struct audio_client *ac, struct asm_ape_cfg *cfg, int stream_id) { @@ -6125,6 +6612,7 @@ int q6asm_media_format_block_ape(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_media_format_block_ape); /* * q6asm_media_format_block_dsd- Sends DSD Decoder @@ -6186,6 +6674,16 @@ int q6asm_media_format_block_dsd(struct audio_client *ac, } EXPORT_SYMBOL(q6asm_media_format_block_dsd); +/** + * q6asm_stream_media_format_block_aptx_dec - + * command to set mediafmt block for APTX dec on ASM stream + * + * @ac: Audio client handle + * @srate: sample rate + * @stream_id: stream ID info + * + * Returns 0 on success or error on failure + */ int q6asm_stream_media_format_block_aptx_dec(struct audio_client *ac, uint32_t srate, int stream_id) { @@ -6236,6 +6734,7 @@ int q6asm_stream_media_format_block_aptx_dec(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_stream_media_format_block_aptx_dec); static int __q6asm_ds1_set_endp_params(struct audio_client *ac, int param_id, int param_value, int stream_id) @@ -6294,6 +6793,16 @@ static int __q6asm_ds1_set_endp_params(struct audio_client *ac, int param_id, return rc; } +/** + * q6asm_ds1_set_endp_params - + * command to set DS1 params for ASM + * + * @ac: Audio client handle + * @param_id: param id + * @param_value: value of param + * + * Returns 0 on success or error on failure + */ int q6asm_ds1_set_endp_params(struct audio_client *ac, int param_id, int param_value) { @@ -6301,6 +6810,17 @@ int q6asm_ds1_set_endp_params(struct audio_client *ac, ac->stream_id); } +/** + * q6asm_ds1_set_stream_endp_params - + * command to set DS1 params for ASM stream + * + * @ac: Audio client handle + * @param_id: param id + * @param_value: value of param + * @stream_id: stream ID info + * + * Returns 0 on success or error on failure + */ int q6asm_ds1_set_stream_endp_params(struct audio_client *ac, int param_id, int param_value, int stream_id) @@ -6308,7 +6828,20 @@ int q6asm_ds1_set_stream_endp_params(struct audio_client *ac, return __q6asm_ds1_set_endp_params(ac, param_id, param_value, stream_id); } +EXPORT_SYMBOL(q6asm_ds1_set_stream_endp_params); +/** + * q6asm_memory_map - + * command to send memory map for ASM + * + * @ac: Audio client handle + * @buf_add: buffer address to map + * @dir: RX or TX session + * @bufsz: size of each buffer + * @bufcnt: buffer count + * + * Returns 0 on success or error on failure + */ int q6asm_memory_map(struct audio_client *ac, phys_addr_t buf_add, int dir, uint32_t bufsz, uint32_t bufcnt) { @@ -6402,7 +6935,18 @@ int q6asm_memory_map(struct audio_client *ac, phys_addr_t buf_add, int dir, kfree(mmap_region_cmd); return rc; } +EXPORT_SYMBOL(q6asm_memory_map); +/** + * q6asm_memory_unmap - + * command to send memory unmap for ASM + * + * @ac: Audio client handle + * @buf_add: buffer address to unmap + * @dir: RX or TX session + * + * Returns 0 on success or error on failure + */ int q6asm_memory_unmap(struct audio_client *ac, phys_addr_t buf_add, int dir) { struct avs_cmd_shared_mem_unmap_regions mem_unmap; @@ -6487,8 +7031,20 @@ int q6asm_memory_unmap(struct audio_client *ac, phys_addr_t buf_add, int dir) } return rc; } +EXPORT_SYMBOL(q6asm_memory_unmap); - +/** + * q6asm_memory_map_regions - + * command to send memory map regions for ASM + * + * @ac: Audio client handle + * @dir: RX or TX session + * @bufsz: size of each buffer + * @bufcnt: buffer count + * @is_contiguous: alloc contiguous mem or not + * + * Returns 0 on success or error on failure + */ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, uint32_t bufsz, uint32_t bufcnt, bool is_contiguous) @@ -6628,7 +7184,17 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, kfree(mmap_region_cmd); return rc; } +EXPORT_SYMBOL(q6asm_memory_map_regions); +/** + * q6asm_memory_unmap_regions - + * command to send memory unmap regions for ASM + * + * @ac: Audio client handle + * @dir: RX or TX session + * + * Returns 0 on success or error on failure + */ static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir) { struct avs_cmd_shared_mem_unmap_regions mem_unmap; @@ -6715,6 +7281,7 @@ static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir) } return rc; } +EXPORT_SYMBOL(q6asm_memory_unmap_regions); int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain) { @@ -6886,7 +7453,17 @@ int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, done: return rc; } +EXPORT_SYMBOL(q6asm_set_multich_gain); +/** + * q6asm_set_mute - + * command to set mute for ASM + * + * @ac: Audio client handle + * @muteflag: mute value + * + * Returns 0 on success or error on failure + */ int q6asm_set_mute(struct audio_client *ac, int muteflag) { struct asm_volume_ctrl_mute_config mute; @@ -6948,6 +7525,7 @@ int q6asm_set_mute(struct audio_client *ac, int muteflag) fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_set_mute); static int __q6asm_set_volume(struct audio_client *ac, int volume, int instance) { @@ -7023,16 +7601,35 @@ static int __q6asm_set_volume(struct audio_client *ac, int volume, int instance) return rc; } +/** + * q6asm_set_volume - + * command to set volume for ASM + * + * @ac: Audio client handle + * @volume: volume level + * + * Returns 0 on success or error on failure + */ int q6asm_set_volume(struct audio_client *ac, int volume) { return __q6asm_set_volume(ac, volume, SOFT_VOLUME_INSTANCE_1); } +EXPORT_SYMBOL(q6asm_set_volume); int q6asm_set_volume_v2(struct audio_client *ac, int volume, int instance) { return __q6asm_set_volume(ac, volume, instance); } +/** + * q6asm_set_aptx_dec_bt_addr - + * command to aptx decoder BT addr for ASM + * + * @ac: Audio client handle + * @cfg: APTX decoder bt addr config + * + * Returns 0 on success or error on failure + */ int q6asm_set_aptx_dec_bt_addr(struct audio_client *ac, struct aptx_dec_bt_addr_cfg *cfg) { @@ -7095,7 +7692,17 @@ int q6asm_set_aptx_dec_bt_addr(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_set_aptx_dec_bt_addr); +/** + * q6asm_send_ion_fd - + * command to send ION memory map for ASM + * + * @ac: Audio client handle + * @fd: ION file desc + * + * Returns 0 on success or error on failure + */ int q6asm_send_ion_fd(struct audio_client *ac, int fd) { struct ion_client *client; @@ -7181,7 +7788,18 @@ int q6asm_send_ion_fd(struct audio_client *ac, int fd) fail_cmd: return ret; } +EXPORT_SYMBOL(q6asm_send_ion_fd); +/** + * q6asm_send_rtic_event_ack - + * command to send RTIC event ack + * + * @ac: Audio client handle + * @param: params for event ack + * @params_length: length of params + * + * Returns 0 on success or error on failure + */ int q6asm_send_rtic_event_ack(struct audio_client *ac, void *param, uint32_t params_length) { @@ -7245,7 +7863,17 @@ int q6asm_send_rtic_event_ack(struct audio_client *ac, done: return rc; } +EXPORT_SYMBOL(q6asm_send_rtic_event_ack); +/** + * q6asm_set_softpause - + * command to set pause for ASM + * + * @ac: Audio client handle + * @pause_param: params for pause + * + * Returns 0 on success or error on failure + */ int q6asm_set_softpause(struct audio_client *ac, struct asm_softpause_params *pause_param) { @@ -7313,6 +7941,7 @@ int q6asm_set_softpause(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_set_softpause); static int __q6asm_set_softvolume(struct audio_client *ac, struct asm_softvolume_params *softvol_param, @@ -7392,20 +8021,50 @@ static int __q6asm_set_softvolume(struct audio_client *ac, return rc; } +/** + * q6asm_set_softvolume - + * command to set softvolume for ASM + * + * @ac: Audio client handle + * @softvol_param: params for softvol + * + * Returns 0 on success or error on failure + */ int q6asm_set_softvolume(struct audio_client *ac, struct asm_softvolume_params *softvol_param) { return __q6asm_set_softvolume(ac, softvol_param, SOFT_VOLUME_INSTANCE_1); } +EXPORT_SYMBOL(q6asm_set_softvolume); +/** + * q6asm_set_softvolume_v2 - + * command to set softvolume V2 for ASM + * + * @ac: Audio client handle + * @softvol_param: params for softvol + * @instance: instance to apply softvol + * + * Returns 0 on success or error on failure + */ int q6asm_set_softvolume_v2(struct audio_client *ac, struct asm_softvolume_params *softvol_param, int instance) { return __q6asm_set_softvolume(ac, softvol_param, instance); } +EXPORT_SYMBOL(q6asm_set_softvolume_v2); +/** + * q6asm_equalizer - + * command to set equalizer for ASM + * + * @ac: Audio client handle + * @eq_p: Equalizer params + * + * Returns 0 on success or error on failure + */ int q6asm_equalizer(struct audio_client *ac, void *eq_p) { struct asm_eq_params eq; @@ -7498,6 +8157,7 @@ int q6asm_equalizer(struct audio_client *ac, void *eq_p) fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_equalizer); static int __q6asm_read(struct audio_client *ac, bool is_custom_len_reqd, int len) @@ -7580,15 +8240,45 @@ static int __q6asm_read(struct audio_client *ac, bool is_custom_len_reqd, return -EINVAL; } +/** + * q6asm_read - + * command to read buffer data from DSP + * + * @ac: Audio client handle + * + * Returns 0 on success or error on failure + */ int q6asm_read(struct audio_client *ac) { return __q6asm_read(ac, false/*is_custom_len_reqd*/, 0); } +EXPORT_SYMBOL(q6asm_read); + + +/** + * q6asm_read_v2 - + * command to read buffer data from DSP + * + * @ac: Audio client handle + * @len: buffer size to read + * + * Returns 0 on success or error on failure + */ int q6asm_read_v2(struct audio_client *ac, uint32_t len) { return __q6asm_read(ac, true /*is_custom_len_reqd*/, len); } +EXPORT_SYMBOL(q6asm_read_v2); +/** + * q6asm_read_nolock - + * command to read buffer data from DSP + * with no wait for ack. + * + * @ac: Audio client handle + * + * Returns 0 on success or error on failure + */ int q6asm_read_nolock(struct audio_client *ac) { struct asm_data_cmd_read_v2 read; @@ -7662,7 +8352,17 @@ int q6asm_read_nolock(struct audio_client *ac) fail_cmd: return -EINVAL; } +EXPORT_SYMBOL(q6asm_read_nolock); +/** + * q6asm_async_write - + * command to write DSP buffer + * + * @ac: Audio client handle + * @param: params for async write + * + * Returns 0 on success or error on failure + */ int q6asm_async_write(struct audio_client *ac, struct audio_aio_write_param *param) { @@ -7747,7 +8447,17 @@ int q6asm_async_write(struct audio_client *ac, fail_cmd: return -EINVAL; } +EXPORT_SYMBOL(q6asm_async_write); +/** + * q6asm_async_read - + * command to read DSP buffer + * + * @ac: Audio client handle + * @param: params for async read + * + * Returns 0 on success or error on failure + */ int q6asm_async_read(struct audio_client *ac, struct audio_aio_read_param *param) { @@ -7815,7 +8525,20 @@ int q6asm_async_read(struct audio_client *ac, fail_cmd: return -EINVAL; } +EXPORT_SYMBOL(q6asm_async_read); +/** + * q6asm_write - + * command to write buffer data to DSP + * + * @ac: Audio client handle + * @len: buffer size + * @msw_ts: upper 32bits of timestamp + * @lsw_ts: lower 32bits of timestamp + * @flags: Flags for timestamp mode + * + * Returns 0 on success or error on failure + */ int q6asm_write(struct audio_client *ac, uint32_t len, uint32_t msw_ts, uint32_t lsw_ts, uint32_t flags) { @@ -7895,7 +8618,21 @@ int q6asm_write(struct audio_client *ac, uint32_t len, uint32_t msw_ts, fail_cmd: return -EINVAL; } +EXPORT_SYMBOL(q6asm_write); +/** + * q6asm_write_nolock - + * command to write buffer data to DSP + * with no wait for ack. + * + * @ac: Audio client handle + * @len: buffer size + * @msw_ts: upper 32bits of timestamp + * @lsw_ts: lower 32bits of timestamp + * @flags: Flags for timestamp mode + * + * Returns 0 on success or error on failure + */ int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts, uint32_t lsw_ts, uint32_t flags) { @@ -7972,7 +8709,17 @@ int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts, fail_cmd: return -EINVAL; } +EXPORT_SYMBOL(q6asm_write_nolock); +/** + * q6asm_get_session_time - + * command to retrieve timestamp info + * + * @ac: Audio client handle + * @tstamp: pointer to fill with timestamp info + * + * Returns 0 on success or error on failure + */ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) { struct asm_mtmx_strtr_get_params mtmx_params; @@ -8029,7 +8776,17 @@ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) fail_cmd: return -EINVAL; } +EXPORT_SYMBOL(q6asm_get_session_time); +/** + * q6asm_get_session_time_legacy - + * command to retrieve timestamp info + * + * @ac: Audio client handle + * @tstamp: pointer to fill with timestamp info + * + * Returns 0 on success or error on failure + */ int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp) { struct apr_hdr hdr; @@ -8075,8 +8832,18 @@ int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp) fail_cmd: return -EINVAL; } +EXPORT_SYMBOL(q6asm_get_session_time_legacy); - +/** + * q6asm_send_audio_effects_params - + * command to send audio effects params + * + * @ac: Audio client handle + * @params: audio effects params + * @params_length: size of params + * + * Returns 0 on success or error on failure + */ int q6asm_send_audio_effects_params(struct audio_client *ac, char *params, uint32_t params_length) { @@ -8148,7 +8915,18 @@ int q6asm_send_audio_effects_params(struct audio_client *ac, char *params, kfree(asm_params); return rc; } +EXPORT_SYMBOL(q6asm_send_audio_effects_params); +/** + * q6asm_send_mtmx_strtr_window - + * command to send matrix for window params + * + * @ac: Audio client handle + * @window_param: window params + * @param_id: param id for window + * + * Returns 0 on success or error on failure + */ int q6asm_send_mtmx_strtr_window(struct audio_client *ac, struct asm_session_mtmx_strtr_param_window_v2_t *window_param, uint32_t param_id) @@ -8222,7 +9000,17 @@ int q6asm_send_mtmx_strtr_window(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_send_mtmx_strtr_window); +/** + * q6asm_send_mtmx_strtr_render_mode - + * command to send matrix for render mode + * + * @ac: Audio client handle + * @render_mode: rendering mode + * + * Returns 0 on success or error on failure + */ int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac, uint32_t render_mode) { @@ -8307,7 +9095,17 @@ int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac, exit: return rc; } +EXPORT_SYMBOL(q6asm_send_mtmx_strtr_render_mode); +/** + * q6asm_send_mtmx_strtr_clk_rec_mode - + * command to send matrix for clock rec + * + * @ac: Audio client handle + * @clk_rec_mode: mode for clock rec + * + * Returns 0 on success or error on failure + */ int q6asm_send_mtmx_strtr_clk_rec_mode(struct audio_client *ac, uint32_t clk_rec_mode) { @@ -8392,7 +9190,17 @@ int q6asm_send_mtmx_strtr_clk_rec_mode(struct audio_client *ac, exit: return rc; } +EXPORT_SYMBOL(q6asm_send_mtmx_strtr_clk_rec_mode); +/** + * q6asm_send_mtmx_strtr_enable_adjust_session_clock - + * command to send matrix for adjust time + * + * @ac: Audio client handle + * @enable: flag to adjust time or not + * + * Returns 0 on success or error on failure + */ int q6asm_send_mtmx_strtr_enable_adjust_session_clock(struct audio_client *ac, bool enable) { @@ -8465,6 +9273,7 @@ int q6asm_send_mtmx_strtr_enable_adjust_session_clock(struct audio_client *ac, exit: return rc; } +EXPORT_SYMBOL(q6asm_send_mtmx_strtr_enable_adjust_session_clock); static int __q6asm_cmd(struct audio_client *ac, int cmd, uint32_t stream_id) @@ -8588,16 +9397,50 @@ static int __q6asm_cmd(struct audio_client *ac, int cmd, uint32_t stream_id) return rc; } +/** + * q6asm_cmd - + * Function used to send commands for + * ASM with wait for ack. + * + * @ac: Audio client handle + * @cmd: command to send + * + * Returns 0 on success or error on failure + */ int q6asm_cmd(struct audio_client *ac, int cmd) { return __q6asm_cmd(ac, cmd, ac->stream_id); } +EXPORT_SYMBOL(q6asm_cmd); +/** + * q6asm_stream_cmd - + * Function used to send commands for + * ASM stream with wait for ack. + * + * @ac: Audio client handle + * @cmd: command to send + * @stream_id: Stream ID + * + * Returns 0 on success or error on failure + */ int q6asm_stream_cmd(struct audio_client *ac, int cmd, uint32_t stream_id) { return __q6asm_cmd(ac, cmd, stream_id); } +EXPORT_SYMBOL(q6asm_stream_cmd); +/** + * q6asm_cmd_nowait - + * Function used to send commands for + * ASM stream without wait for ack. + * + * @ac: Audio client handle + * @cmd: command to send + * @stream_id: Stream ID + * + * Returns 0 on success or error on failure + */ static int __q6asm_cmd_nowait(struct audio_client *ac, int cmd, uint32_t stream_id) { @@ -8666,13 +9509,26 @@ int q6asm_cmd_nowait(struct audio_client *ac, int cmd) pr_debug("%s: stream_id: %d\n", __func__, ac->stream_id); return __q6asm_cmd_nowait(ac, cmd, ac->stream_id); } +EXPORT_SYMBOL(q6asm_cmd_nowait); +/** + * q6asm_stream_cmd_nowait - + * Function used to send commands for + * ASM stream without wait for ack. + * + * @ac: Audio client handle + * @cmd: command to send + * @stream_id: Stream ID + * + * Returns 0 on success or error on failure + */ int q6asm_stream_cmd_nowait(struct audio_client *ac, int cmd, uint32_t stream_id) { pr_debug("%s: stream_id: %d\n", __func__, stream_id); return __q6asm_cmd_nowait(ac, cmd, stream_id); } +EXPORT_SYMBOL(q6asm_stream_cmd_nowait); int __q6asm_send_meta_data(struct audio_client *ac, uint32_t stream_id, uint32_t initial_samples, uint32_t trailing_samples) @@ -8732,12 +9588,24 @@ int __q6asm_send_meta_data(struct audio_client *ac, uint32_t stream_id, return -EINVAL; } +/** + * q6asm_stream_send_meta_data - + * command to send meta data for stream + * + * @ac: Audio client handle + * @stream_id: Stream ID + * @initial_samples: Initial samples of stream + * @trailing_samples: Trailing samples of stream + * + * Returns 0 on success or error on failure + */ int q6asm_stream_send_meta_data(struct audio_client *ac, uint32_t stream_id, uint32_t initial_samples, uint32_t trailing_samples) { return __q6asm_send_meta_data(ac, stream_id, initial_samples, trailing_samples); } +EXPORT_SYMBOL(q6asm_stream_send_meta_data); int q6asm_send_meta_data(struct audio_client *ac, uint32_t initial_samples, uint32_t trailing_samples) @@ -8772,6 +9640,15 @@ static void q6asm_reset_buf_state(struct audio_client *ac) } } +/** + * q6asm_reg_tx_overflow - + * command to register for TX overflow events + * + * @ac: Audio client handle + * @enable: flag to enable or disable events + * + * Returns 0 on success or error on failure + */ int q6asm_reg_tx_overflow(struct audio_client *ac, uint16_t enable) { struct asm_session_cmd_regx_overflow tx_overflow; @@ -8822,6 +9699,7 @@ int q6asm_reg_tx_overflow(struct audio_client *ac, uint16_t enable) fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_reg_tx_overflow); int q6asm_reg_rx_underflow(struct audio_client *ac, uint16_t enable) { @@ -8856,6 +9734,16 @@ int q6asm_reg_rx_underflow(struct audio_client *ac, uint16_t enable) return -EINVAL; } +/** + * q6asm_adjust_session_clock - + * command to adjust session clock + * + * @ac: Audio client handle + * @adjust_time_lsw: lower 32bits + * @adjust_time_msw: upper 32bits + * + * Returns 0 on success or error on failure + */ int q6asm_adjust_session_clock(struct audio_client *ac, uint32_t adjust_time_lsw, uint32_t adjust_time_msw) @@ -8917,6 +9805,7 @@ int q6asm_adjust_session_clock(struct audio_client *ac, fail_cmd: return rc; } +EXPORT_SYMBOL(q6asm_adjust_session_clock); /* * q6asm_get_path_delay() - get the path delay for an audio session @@ -8966,6 +9855,7 @@ int q6asm_get_path_delay(struct audio_client *ac) return 0; } +EXPORT_SYMBOL(q6asm_get_path_delay); int q6asm_get_apr_service_id(int session_id) { @@ -9062,6 +9952,14 @@ static int q6asm_get_asm_app_type_cal(void) return app_type; } +/** + * q6asm_send_cal - + * command to send ASM calibration + * + * @ac: Audio client handle + * + * Returns 0 on success or error on failure + */ int q6asm_send_cal(struct audio_client *ac) { struct cal_block_data *cal_block = NULL; @@ -9176,6 +10074,7 @@ int q6asm_send_cal(struct audio_client *ac) done: return rc; } +EXPORT_SYMBOL(q6asm_send_cal); static int get_cal_type_index(int32_t cal_type) { @@ -9350,7 +10249,7 @@ static int q6asm_is_valid_session(struct apr_client_data *data, void *priv) return 0; } -static int __init q6asm_init(void) +int __init q6asm_init(void) { int lcnt, ret; @@ -9387,10 +10286,7 @@ static int __init q6asm_init(void) return 0; } -static void __exit q6asm_exit(void) +void __exit q6asm_exit(void) { q6asm_delete_cal_data(); } - -device_initcall(q6asm_init); -__exitcall(q6asm_exit); diff --git a/dsp/q6audio-v2.c b/dsp/q6audio-v2.c index 6e31c366c798..55e7244741fb 100644 --- a/dsp/q6audio-v2.c +++ b/dsp/q6audio-v2.c @@ -650,6 +650,14 @@ int q6audio_is_digital_pcm_interface(u16 port_id) return ret; } +/** + * q6audio_validate_port - + * validates port id + * + * @port_id: port id to validate + * + * Returns 0 on success or error on invalid port + */ int q6audio_validate_port(u16 port_id) { int ret; @@ -805,3 +813,4 @@ int q6audio_validate_port(u16 port_id) return ret; } +EXPORT_SYMBOL(q6audio_validate_port); diff --git a/dsp/q6core.c b/dsp/q6core.c index 9f1d9e411ea1..b80786209b7c 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -454,6 +454,15 @@ size_t q6core_get_fwk_version_size(uint32_t service_id) } EXPORT_SYMBOL(q6core_get_fwk_version_size); +/** + * core_set_license - + * command to set license for module + * + * @key: license key hash + * @module_id: DSP Module ID + * + * Returns 0 on success or error on failure + */ int32_t core_set_license(uint32_t key, uint32_t module_id) { struct avcs_cmd_set_license *cmd_setl = NULL; @@ -528,7 +537,16 @@ int32_t core_set_license(uint32_t key, uint32_t module_id) return rc; } +EXPORT_SYMBOL(core_set_license); +/** + * core_get_license_status - + * command to retrieve license status for module + * + * @module_id: DSP Module ID + * + * Returns 0 on success or error on failure + */ int32_t core_get_license_status(uint32_t module_id) { struct avcs_cmd_get_license_validation_result get_lvr_cmd; @@ -586,7 +604,16 @@ int32_t core_get_license_status(uint32_t module_id) __func__, ret, module_id); return ret; } +EXPORT_SYMBOL(core_get_license_status); +/** + * core_set_dolby_manufacturer_id - + * command to set dolby manufacturer id + * + * @manufacturer_id: Dolby manufacturer id + * + * Returns 0 on success or error on failure + */ uint32_t core_set_dolby_manufacturer_id(int manufacturer_id) { struct adsp_dolby_manufacturer_id payload; @@ -617,6 +644,7 @@ uint32_t core_set_dolby_manufacturer_id(int manufacturer_id) mutex_unlock(&(q6core_lcl.cmd_lock)); return rc; } +EXPORT_SYMBOL(core_set_dolby_manufacturer_id); /** * q6core_is_adsp_ready - check adsp ready status @@ -1062,7 +1090,7 @@ static int q6core_init_cal_data(void) return ret; } -static int __init core_init(void) +int __init core_init(void) { memset(&q6core_lcl, 0, sizeof(struct q6core_str)); init_waitqueue_head(&q6core_lcl.bus_bw_req_wait); @@ -1076,14 +1104,12 @@ static int __init core_init(void) return 0; } -module_init(core_init); -static void __exit core_exit(void) +void __exit core_exit(void) { mutex_destroy(&q6core_lcl.cmd_lock); mutex_destroy(&q6core_lcl.ver_lock); q6core_delete_cal_data(); } -module_exit(core_exit); MODULE_DESCRIPTION("ADSP core driver"); MODULE_LICENSE("GPL v2"); diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 848f2cd93868..e34bff9732ca 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -293,6 +293,15 @@ static int q6lsm_mmap_apr_dereg(void) return 0; } +/** + * q6lsm_client_alloc - + * Allocate session for LSM client + * + * @cb: callback fn + * @priv: private data + * + * Returns LSM client handle on success or NULL on failure + */ struct lsm_client *q6lsm_client_alloc(lsm_app_cb cb, void *priv) { struct lsm_client *client; @@ -341,7 +350,15 @@ struct lsm_client *q6lsm_client_alloc(lsm_app_cb cb, void *priv) q6lsm_client_free(client); return NULL; } +EXPORT_SYMBOL(q6lsm_client_alloc); +/** + * q6lsm_client_free - + * Performs LSM client free + * + * @client: LSM client handle + * + */ void q6lsm_client_free(struct lsm_client *client) { if (!client) @@ -358,6 +375,7 @@ void q6lsm_client_free(struct lsm_client *client) kfree(client); client = NULL; } +EXPORT_SYMBOL(q6lsm_client_free); /* * q6lsm_apr_send_pkt : If wait == true, hold mutex to prevent from preempting @@ -593,6 +611,15 @@ static int q6lsm_do_open_v2(struct lsm_client *client, } +/** + * q6lsm_sm_set_param_data - + * Update sound model param data + * + * @client: LSM client handle + * @p_info: param info + * @offset: pointer to retrieve size + * + */ void q6lsm_sm_set_param_data(struct lsm_client *client, struct lsm_params_info *p_info, size_t *offset) @@ -606,7 +633,17 @@ void q6lsm_sm_set_param_data(struct lsm_client *client, param->p_size.param_size = client->sound_model.size; *offset = sizeof(*param); } +EXPORT_SYMBOL(q6lsm_sm_set_param_data); +/** + * q6lsm_open - + * command to open LSM session + * + * @client: LSM client handle + * @app_id: App ID for LSM + * + * Returns 0 on success or error on failure + */ int q6lsm_open(struct lsm_client *client, uint16_t app_id) { int rc = 0; @@ -654,6 +691,7 @@ int q6lsm_open(struct lsm_client *client, uint16_t app_id) pr_debug("%s: leave %d\n", __func__, rc); return rc; } +EXPORT_SYMBOL(q6lsm_open); static int q6lsm_send_confidence_levels( struct lsm_client *client, @@ -760,16 +798,30 @@ static int q6lsm_send_param_opmode(struct lsm_client *client, return rc; } +/** + * set_lsm_port - + * Update LSM AFE port + * + */ void set_lsm_port(int lsm_port) { lsm_afe_port = lsm_port; } +EXPORT_SYMBOL(set_lsm_port); int get_lsm_port(void) { return lsm_afe_port; } +/** + * q6lsm_set_port_connected - + * command to set LSM port connected + * + * @client: LSM client handle + * + * Returns 0 on success or error on failure + */ int q6lsm_set_port_connected(struct lsm_client *client) { int rc; @@ -819,6 +871,8 @@ int q6lsm_set_port_connected(struct lsm_client *client) return rc; } +EXPORT_SYMBOL(q6lsm_set_port_connected); + static int q6lsm_send_param_polling_enable(struct lsm_client *client, bool poll_en, struct lsm_module_param_ids *poll_enable_ids, @@ -859,6 +913,15 @@ static int q6lsm_send_param_polling_enable(struct lsm_client *client, return rc; } +/** + * q6lsm_set_fwk_mode_cfg - + * command to set LSM fwk mode cfg + * + * @client: LSM client handle + * @event_mode: mode for fwk cfg + * + * Returns 0 on success or error on failure + */ int q6lsm_set_fwk_mode_cfg(struct lsm_client *client, uint32_t event_mode) { @@ -906,6 +969,7 @@ int q6lsm_set_fwk_mode_cfg(struct lsm_client *client, __func__, msg_hdr->opcode, rc); return rc; } +EXPORT_SYMBOL(q6lsm_set_fwk_mode_cfg); static int q6lsm_arrange_mch_map(struct lsm_param_media_fmt *media_fmt, int channel_count) @@ -941,6 +1005,14 @@ static int q6lsm_arrange_mch_map(struct lsm_param_media_fmt *media_fmt, return rc; } +/** + * q6lsm_set_media_fmt_params - + * command to set LSM media fmt params + * + * @client: LSM client handle + * + * Returns 0 on success or error on failure + */ int q6lsm_set_media_fmt_params(struct lsm_client *client) { int rc = 0; @@ -998,7 +1070,18 @@ int q6lsm_set_media_fmt_params(struct lsm_client *client) err_ret: return rc; } +EXPORT_SYMBOL(q6lsm_set_media_fmt_params); +/** + * q6lsm_set_data - + * Command to set LSM data + * + * @client: LSM client handle + * @mode: LSM detection mode value + * @detectfailure: flag for detect failure + * + * Returns 0 on success or error on failure + */ int q6lsm_set_data(struct lsm_client *client, enum lsm_detection_mode mode, bool detectfailure) @@ -1061,7 +1144,16 @@ int q6lsm_set_data(struct lsm_client *client, err_ret: return rc; } +EXPORT_SYMBOL(q6lsm_set_data); +/** + * q6lsm_register_sound_model - + * Register LSM snd model + * + * @client: LSM client handle + * + * Returns 0 on success or error on failure + */ int q6lsm_register_sound_model(struct lsm_client *client, enum lsm_detection_mode mode, bool detectfailure) @@ -1098,7 +1190,16 @@ int q6lsm_register_sound_model(struct lsm_client *client, return rc; } +EXPORT_SYMBOL(q6lsm_register_sound_model); +/** + * q6lsm_deregister_sound_model - + * De-register LSM snd model + * + * @client: LSM client handle + * + * Returns 0 on success or error on failure + */ int q6lsm_deregister_sound_model(struct lsm_client *client) { int rc; @@ -1134,6 +1235,7 @@ int q6lsm_deregister_sound_model(struct lsm_client *client) return rc; } +EXPORT_SYMBOL(q6lsm_deregister_sound_model); static void q6lsm_add_mmaphdr(struct lsm_client *client, struct apr_hdr *hdr, u32 pkt_size, u32 cmd_flg, u32 token) @@ -1285,7 +1387,14 @@ static int q6lsm_send_cal(struct lsm_client *client, return rc; } - +/** + * q6lsm_snd_model_buf_free - + * Free memory for LSM snd model + * + * @client: LSM client handle + * + * Returns 0 on success or error on failure + */ int q6lsm_snd_model_buf_free(struct lsm_client *client) { int rc; @@ -1316,6 +1425,7 @@ int q6lsm_snd_model_buf_free(struct lsm_client *client) mutex_unlock(&client->cmd_lock); return rc; } +EXPORT_SYMBOL(q6lsm_snd_model_buf_free); static struct lsm_client *q6lsm_get_lsm_client(int session_id) { @@ -1420,6 +1530,16 @@ static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv) return 0; } +/** + * q6lsm_snd_model_buf_alloc - + * Allocate memory for LSM snd model + * + * @client: LSM client handle + * @len: size of sound model + * @allocate_module_data: flag to allocate for set_param payload + * + * Returns 0 on success or error on failure + */ int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len, bool allocate_module_data) { @@ -1523,6 +1643,7 @@ int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len, q6lsm_snd_model_buf_free(client); return rc; } +EXPORT_SYMBOL(q6lsm_snd_model_buf_alloc); static int q6lsm_cmd(struct lsm_client *client, int opcode, bool wait) { @@ -1613,6 +1734,17 @@ static int q6lsm_send_param_gain( return rc; } +/** + * q6lsm_set_one_param - + * command for LSM set params + * + * @client: LSM client handle + * p_info: Params info + * data: payload based on param type + * param_type: LSM param type + * + * Returns 0 on success or error on failure + */ int q6lsm_set_one_param(struct lsm_client *client, struct lsm_params_info *p_info, void *data, uint32_t param_type) @@ -1798,23 +1930,60 @@ int q6lsm_set_one_param(struct lsm_client *client, return rc; } +EXPORT_SYMBOL(q6lsm_set_one_param); +/** + * q6lsm_start - + * command for LSM start + * + * @client: LSM client handle + * + * Returns 0 on success or error on failure + */ int q6lsm_start(struct lsm_client *client, bool wait) { return q6lsm_cmd(client, LSM_SESSION_CMD_START, wait); } +EXPORT_SYMBOL(q6lsm_start); +/** + * q6lsm_stop - + * command for LSM stop + * + * @client: LSM client handle + * + * Returns 0 on success or error on failure + */ int q6lsm_stop(struct lsm_client *client, bool wait) { return q6lsm_cmd(client, LSM_SESSION_CMD_STOP, wait); } +EXPORT_SYMBOL(q6lsm_stop); +/** + * q6lsm_close - + * command for LSM close + * + * @client: LSM client handle + * + * Returns 0 on success or error on failure + */ int q6lsm_close(struct lsm_client *client) { return q6lsm_cmd(client, LSM_SESSION_CMD_CLOSE_TX, true); } +EXPORT_SYMBOL(q6lsm_close); +/** + * q6lsm_lab_control - + * command to set LSM LAB control params + * + * @client: LSM client handle + * @enable: bool flag to enable or disable LAB on DSP + * + * Returns 0 on success or error on failure + */ int q6lsm_lab_control(struct lsm_client *client, u32 enable) { int rc = 0; @@ -1876,7 +2045,16 @@ int q6lsm_lab_control(struct lsm_client *client, u32 enable) exit: return rc; } +EXPORT_SYMBOL(q6lsm_lab_control); +/** + * q6lsm_stop_lab - + * command to stop LSM LAB + * + * @client: LSM client handle + * + * Returns 0 on success or error on failure + */ int q6lsm_stop_lab(struct lsm_client *client) { int rc = 0; @@ -1890,7 +2068,17 @@ int q6lsm_stop_lab(struct lsm_client *client) pr_err("%s: Lab stop failed %d\n", __func__, rc); return rc; } +EXPORT_SYMBOL(q6lsm_stop_lab); +/** + * q6lsm_read - + * command for LSM read + * + * @client: LSM client handle + * @lsm_cmd_read: LSM read command + * + * Returns 0 on success or error on failure + */ int q6lsm_read(struct lsm_client *client, struct lsm_cmd_read *read) { int rc = 0; @@ -1910,7 +2098,17 @@ int q6lsm_read(struct lsm_client *client, struct lsm_cmd_read *read) pr_err("%s: read buffer call failed rc %d\n", __func__, rc); return rc; } +EXPORT_SYMBOL(q6lsm_read); +/** + * q6lsm_lab_buffer_alloc - + * Lab buffer allocation or de-alloc + * + * @client: LSM client handle + * @alloc: Allocate or free ion memory + * + * Returns 0 on success or error on failure + */ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc) { int ret = 0, i = 0; @@ -2000,6 +2198,7 @@ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc) } return ret; } +EXPORT_SYMBOL(q6lsm_lab_buffer_alloc); static int get_cal_type_index(int32_t cal_type) { @@ -2155,7 +2354,7 @@ static int q6lsm_init_cal_data(void) return ret; } -static int __init q6lsm_init(void) +int __init q6lsm_init(void) { int i = 0; @@ -2177,10 +2376,7 @@ static int __init q6lsm_init(void) return 0; } -static void __exit q6lsm_exit(void) +void __exit q6lsm_exit(void) { lsm_delete_cal_data(); } - -device_initcall(q6lsm_init); -__exitcall(q6lsm_exit); diff --git a/dsp/q6usm.c b/dsp/q6usm.c index 5b822ae99358..1ed74a9c2b1d 100644 --- a/dsp/q6usm.c +++ b/dsp/q6usm.c @@ -1455,12 +1455,10 @@ int q6usm_get_us_stream_param(int dir, struct us_client *usc, return rc; } -static int __init q6usm_init(void) +int __init q6usm_init(void) { pr_debug("%s\n", __func__); init_waitqueue_head(&this_mmap.cmd_wait); memset(session, 0, sizeof(session)); return 0; } - -device_initcall(q6usm_init); diff --git a/dsp/q6usm.h b/dsp/q6usm.h index 2e9d7c9bdb9f..fa2cd627c91d 100644 --- a/dsp/q6usm.h +++ b/dsp/q6usm.h @@ -126,5 +126,6 @@ int q6usm_set_us_stream_param(int dir, struct us_client *usc, uint32_t module_id, uint32_t param_id, uint32_t buf_size); int q6usm_get_us_stream_param(int dir, struct us_client *usc, uint32_t module_id, uint32_t param_id, uint32_t buf_size); +int q6usm_init(void); #endif /* __Q6_USM_H__ */ diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 983e0a2388ca..985e959ab879 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -292,6 +292,14 @@ char *voc_get_session_name(u32 session_id) return session_name; } +/** + * voc_get_session_id - + * Get session ID of given voice session name + * + * @name: voice session name + * + * Returns session id for valid session or 0 if invalid. + */ uint32_t voc_get_session_id(char *name) { u32 session_id = 0; @@ -326,6 +334,7 @@ uint32_t voc_get_session_id(char *name) return session_id; } +EXPORT_SYMBOL(voc_get_session_id); static struct voice_data *voice_get_session(u32 session_id) { @@ -1802,6 +1811,11 @@ static int voice_send_dtmf_rx_detection_cmd(struct voice_data *v, return ret; } +/** + * voc_disable_dtmf_det_on_active_sessions - + * command to disable DTMF detection for voice sessions + * + */ void voc_disable_dtmf_det_on_active_sessions(void) { struct voice_data *v = NULL; @@ -1818,7 +1832,17 @@ void voc_disable_dtmf_det_on_active_sessions(void) } } } +EXPORT_SYMBOL(voc_disable_dtmf_det_on_active_sessions); +/** + * voc_enable_dtmf_rx_detection - + * command to set DTMF RX detection + * + * @session_id: voice session ID to send this command + * @enable: Enable or Disable detection + * + * Returns 0 on success or error on failure + */ int voc_enable_dtmf_rx_detection(uint32_t session_id, uint32_t enable) { struct voice_data *v = voice_get_session(session_id); @@ -1840,13 +1864,29 @@ int voc_enable_dtmf_rx_detection(uint32_t session_id, uint32_t enable) return ret; } +EXPORT_SYMBOL(voc_enable_dtmf_rx_detection); +/** + * voc_set_destroy_cvd_flag - + * set flag for destroy CVD session + * + * @is_destroy_cvd: bool value used to indicate + * destroy CVD session or not. + * + */ void voc_set_destroy_cvd_flag(bool is_destroy_cvd) { pr_debug("%s: %d\n", __func__, is_destroy_cvd); common.is_destroy_cvd = is_destroy_cvd; } +EXPORT_SYMBOL(voc_set_destroy_cvd_flag); +/** + * voc_alloc_cal_shared_memory - + * Alloc mem map table for calibration + * + * Returns 0 on success or error on failure + */ int voc_alloc_cal_shared_memory(void) { int rc = 0; @@ -1867,7 +1907,14 @@ int voc_alloc_cal_shared_memory(void) return rc; } +EXPORT_SYMBOL(voc_alloc_cal_shared_memory); +/** + * voc_alloc_voip_shared_memory - + * Alloc mem map table for OOB + * + * Returns 0 on success or error on failure + */ int voc_alloc_voip_shared_memory(void) { int rc = 0; @@ -1890,6 +1937,7 @@ int voc_alloc_voip_shared_memory(void) return rc; } +EXPORT_SYMBOL(voc_alloc_voip_shared_memory); static int is_cal_memory_allocated(void) { @@ -2218,6 +2266,14 @@ static int voice_config_cvs_vocoder(struct voice_data *v) return ret; } +/** + * voc_update_amr_vocoder_rate - + * command to update AMR rate for voice session + * + * @session_id: voice session ID to send this command + * + * Returns 0 on success or error on failure + */ int voc_update_amr_vocoder_rate(uint32_t session_id) { int ret = 0; @@ -2242,6 +2298,7 @@ int voc_update_amr_vocoder_rate(uint32_t session_id) done: return ret; } +EXPORT_SYMBOL(voc_update_amr_vocoder_rate); static int voice_send_start_voice_cmd(struct voice_data *v) { @@ -5640,6 +5697,16 @@ static int voice_cvs_stop_record(struct voice_data *v) return ret; } +/** + * voc_start_record - + * command to set record for voice session + * + * @port_id: Pseudo Port ID for record data + * @set: Enable or Disable for record start/stop + * @session_id: voice session ID to send this command + * + * Returns 0 on success or error on failure + */ int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id) { int ret = 0; @@ -5774,6 +5841,7 @@ int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id) return ret; } +EXPORT_SYMBOL(voc_start_record); static int voice_cvs_start_playback(struct voice_data *v) { @@ -5962,6 +6030,15 @@ static int voc_lch_ops(struct voice_data *v, enum voice_lch_mode lch_mode) return ret; } +/** + * voc_start_playback - + * command to set playback for voice session + * + * @set: Enable or Disable for playback start/stop + * @port_id: Pseudo Port ID for playback data + * + * Returns 0 on success or error on failure + */ int voc_start_playback(uint32_t set, uint16_t port_id) { struct voice_data *v = NULL; @@ -6004,7 +6081,17 @@ int voc_start_playback(uint32_t set, uint16_t port_id) return ret; } +EXPORT_SYMBOL(voc_start_playback); +/** + * voc_disable_topology - + * disable topology for voice session + * + * @session_id: voice session ID to send this command + * @disable: disable value + * + * Returns 0 on success or error on failure + */ int voc_disable_topology(uint32_t session_id, uint32_t disable) { struct voice_data *v = voice_get_session(session_id); @@ -6024,6 +6111,7 @@ int voc_disable_topology(uint32_t session_id, uint32_t disable) return ret; } +EXPORT_SYMBOL(voc_disable_topology); static int voice_set_packet_exchange_mode_and_config(uint32_t session_id, uint32_t mode) @@ -6057,6 +6145,17 @@ static int voice_set_packet_exchange_mode_and_config(uint32_t session_id, return -EINVAL; } +/** + * voc_set_tx_mute - + * command to send TX mute for voice session + * + * @session_id: voice session ID to send this command + * @dir: RX or TX + * @mute: TX mute value + * @ramp_duration: Ramp duration in ms + * + * Returns 0 on success or error on failure + */ int voc_set_tx_mute(uint32_t session_id, uint32_t dir, uint32_t mute, uint32_t ramp_duration) { @@ -6089,7 +6188,19 @@ int voc_set_tx_mute(uint32_t session_id, uint32_t dir, uint32_t mute, return ret; } +EXPORT_SYMBOL(voc_set_tx_mute); +/** + * voc_set_device_mute - + * command to set device mute for voice session + * + * @session_id: voice session ID to send this command + * @dir: RX or TX + * @mute: mute value + * @ramp_duration: Ramp duration in ms + * + * Returns 0 on success or error on failure + */ int voc_set_device_mute(uint32_t session_id, uint32_t dir, uint32_t mute, uint32_t ramp_duration) { @@ -6130,6 +6241,7 @@ int voc_set_device_mute(uint32_t session_id, uint32_t dir, uint32_t mute, return ret; } +EXPORT_SYMBOL(voc_set_device_mute); int voc_get_rx_device_mute(uint32_t session_id) { @@ -6151,6 +6263,15 @@ int voc_get_rx_device_mute(uint32_t session_id) return ret; } +/** + * voc_set_tty_mode - + * Update tty mode for voice session + * + * @session_id: voice session ID + * @tty_mode: TTY mode value + * + * Returns 0 on success or error on failure + */ int voc_set_tty_mode(uint32_t session_id, uint8_t tty_mode) { struct voice_data *v = voice_get_session(session_id); @@ -6170,7 +6291,16 @@ int voc_set_tty_mode(uint32_t session_id, uint8_t tty_mode) return ret; } +EXPORT_SYMBOL(voc_set_tty_mode); +/** + * voc_get_tty_mode - + * Retrieve tty mode for voice session + * + * @session_id: voice session ID + * + * Returns 0 on success or error on failure + */ uint8_t voc_get_tty_mode(uint32_t session_id) { struct voice_data *v = voice_get_session(session_id); @@ -6190,7 +6320,18 @@ uint8_t voc_get_tty_mode(uint32_t session_id) return ret; } +EXPORT_SYMBOL(voc_get_tty_mode); +/** + * voc_set_pp_enable - + * Command to set PP for voice module + * + * @session_id: voice session ID to send this command + * @module_id: voice module id + * @enable: enable/disable flag + * + * Returns 0 on success or error on failure + */ int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, uint32_t enable) { struct voice_data *v = NULL; @@ -6225,7 +6366,17 @@ int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, uint32_t enable) return ret; } +EXPORT_SYMBOL(voc_set_pp_enable); +/** + * voc_set_hd_enable - + * Command to set HD for voice session + * + * @session_id: voice session ID to send this command + * @enable: enable/disable flag + * + * Returns 0 on success or error on failure + */ int voc_set_hd_enable(uint32_t session_id, uint32_t enable) { struct voice_data *v = NULL; @@ -6252,7 +6403,17 @@ int voc_set_hd_enable(uint32_t session_id, uint32_t enable) return ret; } +EXPORT_SYMBOL(voc_set_hd_enable); +/** + * voc_set_afe_sidetone - + * Command to set sidetone at AFE + * + * @session_id: voice session ID to send this command + * @sidetone_enable: enable/disable flag for sidetone + * + * Returns 0 on success or error on failure + */ int voc_set_afe_sidetone(uint32_t session_id, bool sidetone_enable) { struct voice_data *v = NULL; @@ -6286,7 +6447,14 @@ int voc_set_afe_sidetone(uint32_t session_id, bool sidetone_enable) } return ret; } +EXPORT_SYMBOL(voc_set_afe_sidetone); +/** + * voc_get_afe_sidetone - + * Retrieve sidetone status at AFE + * + * Returns sidetone enable status + */ bool voc_get_afe_sidetone(void) { bool ret; @@ -6294,6 +6462,7 @@ bool voc_get_afe_sidetone(void) ret = common.sidetone_enable; return ret; } +EXPORT_SYMBOL(voc_get_afe_sidetone); int voc_get_pp_enable(uint32_t session_id, uint32_t module_id) { @@ -6314,6 +6483,17 @@ int voc_get_pp_enable(uint32_t session_id, uint32_t module_id) return ret; } +/** + * voc_set_rx_vol_step - + * command to send voice RX volume in step value + * + * @session_id: voice session ID + * @dir: direction RX or TX + * @vol_step: Volume step value + * @ramp_duration: Ramp duration in ms + * + * Returns 0 on success or -EINVAL on failure + */ int voc_set_rx_vol_step(uint32_t session_id, uint32_t dir, uint32_t vol_step, uint32_t ramp_duration) { @@ -6344,7 +6524,18 @@ int voc_set_rx_vol_step(uint32_t session_id, uint32_t dir, uint32_t vol_step, return ret; } +EXPORT_SYMBOL(voc_set_rx_vol_step); +/** + * voc_set_device_config - + * Set voice path config for RX or TX + * + * @session_id: voice session ID + * @path_dir: direction RX or TX + * @finfo: format config info + * + * Returns 0 on success or -EINVAL on failure + */ int voc_set_device_config(uint32_t session_id, uint8_t path_dir, struct media_format_info *finfo) { @@ -6387,7 +6578,15 @@ int voc_set_device_config(uint32_t session_id, uint8_t path_dir, return 0; } +EXPORT_SYMBOL(voc_set_device_config); +/** + * voc_set_ext_ec_ref_media_fmt_info - + * Update voice EC media format info + * + * @finfo: media format info + * + */ int voc_set_ext_ec_ref_media_fmt_info(struct media_format_info *finfo) { mutex_lock(&common.common_lock); @@ -6404,7 +6603,18 @@ int voc_set_ext_ec_ref_media_fmt_info(struct media_format_info *finfo) mutex_unlock(&common.common_lock); return 0; } +EXPORT_SYMBOL(voc_set_ext_ec_ref_media_fmt_info); +/** + * voc_set_route_flag - + * Set voice route state for RX or TX + * + * @session_id: voice session ID + * @path_dir: direction RX or TX + * @set: Value of route state to set + * + * Returns 0 on success or -EINVAL on failure + */ int voc_set_route_flag(uint32_t session_id, uint8_t path_dir, uint8_t set) { struct voice_data *v = voice_get_session(session_id); @@ -6428,7 +6638,17 @@ int voc_set_route_flag(uint32_t session_id, uint8_t path_dir, uint8_t set) return 0; } +EXPORT_SYMBOL(voc_set_route_flag); +/** + * voc_get_route_flag - + * Retrieve voice route state for RX or TX + * + * @session_id: voice session ID + * @path_dir: direction RX or TX + * + * Returns route state on success or 0 on failure + */ uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir) { struct voice_data *v = voice_get_session(session_id); @@ -6451,7 +6671,16 @@ uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir) return ret; } +EXPORT_SYMBOL(voc_get_route_flag); +/** + * voc_end_voice_call - + * command to end voice call + * + * @session_id: voice session ID to send this command + * + * Returns 0 on success or error on failure + */ int voc_end_voice_call(uint32_t session_id) { struct voice_data *v = voice_get_session(session_id); @@ -6488,7 +6717,16 @@ int voc_end_voice_call(uint32_t session_id) mutex_unlock(&v->lock); return ret; } +EXPORT_SYMBOL(voc_end_voice_call); +/** + * voc_standby_voice_call - + * command to standy voice call + * + * @session_id: voice session ID to send this command + * + * Returns 0 on success or error on failure + */ int voc_standby_voice_call(uint32_t session_id) { struct voice_data *v = voice_get_session(session_id); @@ -6537,7 +6775,16 @@ int voc_standby_voice_call(uint32_t session_id) fail: return ret; } +EXPORT_SYMBOL(voc_standby_voice_call); +/** + * voc_disable_device - + * command to pause call and disable voice path + * + * @session_id: voice session ID to send this command + * + * Returns 0 on success or error on failure + */ int voc_disable_device(uint32_t session_id) { struct voice_data *v = voice_get_session(session_id); @@ -6574,7 +6821,16 @@ int voc_disable_device(uint32_t session_id) return ret; } +EXPORT_SYMBOL(voc_disable_device); +/** + * voc_enable_device - + * command to enable voice path and start call + * + * @session_id: voice session ID to send this command + * + * Returns 0 on success or error on failure + */ int voc_enable_device(uint32_t session_id) { struct voice_data *v = voice_get_session(session_id); @@ -6662,7 +6918,17 @@ int voc_enable_device(uint32_t session_id) return ret; } +EXPORT_SYMBOL(voc_enable_device); +/** + * voc_set_lch - + * command to set hold/unhold call state + * + * @session_id: voice session ID to send this command + * @lch_mode: LCH mode to set + * + * Returns 0 on success or error on failure + */ int voc_set_lch(uint32_t session_id, enum voice_lch_mode lch_mode) { struct voice_data *v = voice_get_session(session_id); @@ -6696,7 +6962,16 @@ int voc_set_lch(uint32_t session_id, enum voice_lch_mode lch_mode) done: return ret; } +EXPORT_SYMBOL(voc_set_lch); +/** + * voc_resume_voice_call - + * command to resume voice call + * + * @session_id: voice session ID to send this command + * + * Returns 0 on success or error on failure + */ int voc_resume_voice_call(uint32_t session_id) { struct voice_data *v = voice_get_session(session_id); @@ -6712,7 +6987,16 @@ int voc_resume_voice_call(uint32_t session_id) fail: return -EINVAL; } +EXPORT_SYMBOL(voc_resume_voice_call); +/** + * voc_start_voice_call - + * command to start voice call + * + * @session_id: voice session ID to send this command + * + * Returns 0 on success or error on failure + */ int voc_start_voice_call(uint32_t session_id) { struct voice_data *v = voice_get_session(session_id); @@ -6819,7 +7103,14 @@ int voc_start_voice_call(uint32_t session_id) mutex_unlock(&v->lock); return ret; } +EXPORT_SYMBOL(voc_start_voice_call); +/** + * voc_set_ext_ec_ref_port_id - + * Set EC ref port id + * + * Returns 0 on success or -EINVAL on failure + */ int voc_set_ext_ec_ref_port_id(uint16_t port_id, bool state) { int ret = 0; @@ -6841,7 +7132,15 @@ int voc_set_ext_ec_ref_port_id(uint16_t port_id, bool state) mutex_unlock(&common.common_lock); return ret; } +EXPORT_SYMBOL(voc_set_ext_ec_ref_port_id); +/** + * voc_get_ext_ec_ref_port_id - + * Retrieve EC ref port id + * + * Returns EC Ref port id if present + * otherwise AFE_PORT_INVALID + */ int voc_get_ext_ec_ref_port_id(void) { if (common.ec_ref_ext) @@ -6849,7 +7148,18 @@ int voc_get_ext_ec_ref_port_id(void) else return AFE_PORT_INVALID; } +EXPORT_SYMBOL(voc_get_ext_ec_ref_port_id); +/** + * voc_register_mvs_cb - + * Update callback info for mvs + * + * @ul_cb: Uplink callback fn + * @dl_cb: downlink callback fn + * ssr_cb: SSR callback fn + * @private_data: private data of mvs + * + */ void voc_register_mvs_cb(ul_cb_fn ul_cb, dl_cb_fn dl_cb, voip_ssr_cb ssr_cb, @@ -6860,14 +7170,28 @@ void voc_register_mvs_cb(ul_cb_fn ul_cb, common.mvs_info.ssr_cb = ssr_cb; common.mvs_info.private_data = private_data; } +EXPORT_SYMBOL(voc_register_mvs_cb); +/** + * voc_register_dtmf_rx_detection_cb - + * Update callback info for dtmf + * + * @dtmf_rx_ul_cb: DTMF uplink RX callback fn + * @private_data: private data of dtmf info + * + */ void voc_register_dtmf_rx_detection_cb(dtmf_rx_det_cb_fn dtmf_rx_ul_cb, void *private_data) { common.dtmf_info.dtmf_rx_ul_cb = dtmf_rx_ul_cb; common.dtmf_info.private_data = private_data; } +EXPORT_SYMBOL(voc_register_dtmf_rx_detection_cb); +/** + * voc_config_vocoder - + * Update config for mvs params. + */ void voc_config_vocoder(uint32_t media_type, uint32_t rate, uint32_t network_type, @@ -6882,6 +7206,7 @@ void voc_config_vocoder(uint32_t media_type, common.mvs_info.evrc_min_rate = evrc_min_rate; common.mvs_info.evrc_max_rate = evrc_max_rate; } +EXPORT_SYMBOL(voc_config_vocoder); static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) { @@ -7753,6 +8078,14 @@ static int voice_alloc_oob_mem_table(void) return rc; } +/** + * voc_send_cvp_start_vocpcm - + * command to start voice hpcm + * + * @session_id: voice session ID to send this command + * + * Returns 0 on success or error on failure + */ int voc_send_cvp_start_vocpcm(uint32_t session_id, struct vss_ivpcm_tap_point *vpcm_tp, uint32_t no_of_tp) @@ -7831,7 +8164,16 @@ int voc_send_cvp_start_vocpcm(uint32_t session_id, done: return ret; } +EXPORT_SYMBOL(voc_send_cvp_start_vocpcm); +/** + * voc_send_cvp_stop_vocpcm - + * command to stop voice hpcm + * + * @session_id: voice session ID to send this command + * + * Returns 0 on success or error on failure + */ int voc_send_cvp_stop_vocpcm(uint32_t session_id) { struct cvp_command vpcm_stop_cmd; @@ -7892,7 +8234,19 @@ int voc_send_cvp_stop_vocpcm(uint32_t session_id) done: return ret; } +EXPORT_SYMBOL(voc_send_cvp_stop_vocpcm); +/** + * voc_send_cvp_map_vocpcm_memory - + * command to map memory for voice hpcm + * + * @session_id: voice session ID to send this command + * @tp_mem_table: tap point memory table of hpcm + * paddr: Physical address of hpcm memory mapped area. + * bufsize: Buffer size of memory mapped area + * + * Returns 0 on success or error on failure + */ int voc_send_cvp_map_vocpcm_memory(uint32_t session_id, struct mem_map_table *tp_mem_table, phys_addr_t paddr, uint32_t bufsize) @@ -7902,7 +8256,16 @@ int voc_send_cvp_map_vocpcm_memory(uint32_t session_id, (dma_addr_t) paddr, bufsize, VOC_VOICE_HOST_PCM_MAP_TOKEN); } +EXPORT_SYMBOL(voc_send_cvp_map_vocpcm_memory); +/** + * voc_send_cvp_unmap_vocpcm_memory - + * command to unmap memory for voice hpcm + * + * @session_id: voice session ID to send this command + * + * Returns 0 on success or error on failure + */ int voc_send_cvp_unmap_vocpcm_memory(uint32_t session_id) { int ret = 0; @@ -7916,7 +8279,16 @@ int voc_send_cvp_unmap_vocpcm_memory(uint32_t session_id) return ret; } +EXPORT_SYMBOL(voc_send_cvp_unmap_vocpcm_memory); +/** + * voc_send_cvp_vocpcm_push_buf_evt - Send buf event command + * + * @session_id: voice session ID to send this command + * @push_buff_evt: pointer with buffer event details + * + * Returns 0 on success or error on failure + */ int voc_send_cvp_vocpcm_push_buf_evt(uint32_t session_id, struct vss_ivpcm_evt_push_buffer_v2_t *push_buff_evt) { @@ -7979,20 +8351,41 @@ int voc_send_cvp_vocpcm_push_buf_evt(uint32_t session_id, done: return ret; } +EXPORT_SYMBOL(voc_send_cvp_vocpcm_push_buf_evt); +/** + * voc_register_hpcm_evt_cb - Updates hostpcm info. + * + * @hostpcm_cb: callback function for hostpcm event + * @private_data: private data for hostpcm + * + */ void voc_register_hpcm_evt_cb(hostpcm_cb_fn hostpcm_cb, void *private_data) { common.hostpcm_info.hostpcm_evt_cb = hostpcm_cb; common.hostpcm_info.private_data = private_data; } +EXPORT_SYMBOL(voc_register_hpcm_evt_cb); +/** + * voc_deregister_hpcm_evt_cb - resets hostpcm info. + * + */ void voc_deregister_hpcm_evt_cb(void) { common.hostpcm_info.hostpcm_evt_cb = NULL; common.hostpcm_info.private_data = NULL; } +EXPORT_SYMBOL(voc_deregister_hpcm_evt_cb); +/** + * voc_get_cvd_version - retrieve CVD version. + * + * @cvd_version: pointer to be updated with CVD version info. + * + * Returns 0 on success or error on failure + */ int voc_get_cvd_version(char *cvd_version) { int ret = 0; @@ -8041,6 +8434,7 @@ int voc_get_cvd_version(char *cvd_version) return ret; } +EXPORT_SYMBOL(voc_get_cvd_version); static int voice_alloc_cal_mem_map_table(void) { @@ -8598,6 +8992,13 @@ static int voice_send_set_sound_focus_cmd(struct voice_data *v, return ret; } +/** + * voc_set_sound_focus - sends sound focus data. + * + * @soundFocusData: sound focus data. + * + * Returns 0 on success or error on failure + */ int voc_set_sound_focus(struct sound_focus_param soundFocusData) { struct voice_data *v = NULL; @@ -8629,6 +9030,7 @@ int voc_set_sound_focus(struct sound_focus_param soundFocusData) return ret; } +EXPORT_SYMBOL(voc_set_sound_focus); static int voice_send_get_sound_focus_cmd(struct voice_data *v, struct sound_focus_param *soundFocusData) @@ -8727,6 +9129,13 @@ static int voice_send_get_sound_focus_cmd(struct voice_data *v, return ret; } +/** + * voc_get_sound_focus - retrieves sound focus data. + * + * @soundFocusData: pointer to be updated with sound focus data. + * + * Returns 0 on success or error on failure + */ int voc_get_sound_focus(struct sound_focus_param *soundFocusData) { struct voice_data *v = NULL; @@ -8758,6 +9167,7 @@ int voc_get_sound_focus(struct sound_focus_param *soundFocusData) return ret; } +EXPORT_SYMBOL(voc_get_sound_focus); static int is_source_tracking_shared_memomry_allocated(void) { @@ -9045,6 +9455,13 @@ static int voice_send_get_source_tracking_cmd(struct voice_data *v, return ret; } +/** + * voc_get_source_tracking - retrieves source track data. + * + * @sourceTrackingData: pointer to be updated with source track data. + * + * Returns 0 on success or error on failure + */ int voc_get_source_tracking(struct source_tracking_param *sourceTrackingData) { struct voice_data *v = NULL; @@ -9077,13 +9494,21 @@ int voc_get_source_tracking(struct source_tracking_param *sourceTrackingData) return ret; } +EXPORT_SYMBOL(voc_get_source_tracking); +/** + * is_voc_initialized: + * + * Returns voice module init status + * + */ int is_voc_initialized(void) { return module_initialized; } +EXPORT_SYMBOL(is_voc_initialized); -static int __init voice_init(void) +int __init voice_init(void) { int rc = 0, i = 0; @@ -9180,12 +9605,9 @@ static int __init voice_init(void) return rc; } -device_initcall(voice_init); -static void __exit voice_exit(void) +void __exit voice_exit(void) { voice_delete_cal_data(); free_cal_map_table(); } - -__exitcall(voice_exit); diff --git a/dsp/rtac.c b/dsp/rtac.c index 84ef8355a1c3..806bbc5fb16b 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -1875,7 +1875,7 @@ struct miscdevice rtac_misc = { .fops = &rtac_fops, }; -static int __init rtac_init(void) +int __init rtac_init(void) { int i = 0; @@ -1949,7 +1949,13 @@ static int __init rtac_init(void) return -ENOMEM; } -module_init(rtac_init); +void __exit rtac_exit(void) +{ + kzfree(rtac_adm_buffer); + kzfree(rtac_asm_buffer); + kzfree(rtac_afe_buffer); + misc_deregister(&rtac_misc); +} MODULE_DESCRIPTION("SoC QDSP6v2 Real-Time Audio Calibration driver"); MODULE_LICENSE("GPL v2"); diff --git a/dsp/usf.c b/dsp/usf.c index f75439de4e94..263ba1f8b04e 100644 --- a/dsp/usf.c +++ b/dsp/usf.c @@ -27,6 +27,7 @@ #include "q6usm.h" #include "usf.h" #include "usfcdev.h" +#include "q6_init.h" /* The driver version*/ #define DRV_VERSION "1.7.1" @@ -2455,10 +2456,19 @@ static int __init usf_init(void) break; } } + if (!rc) q6usm_init(); return rc; } +module_init(usf_init); -device_initcall(usf_init); +static void __exit usf_exit(void) +{ + uint16_t ind = 0; + for (ind = 0; ind < MAX_DEVS_NUMBER; ++ind) + misc_deregister(&usf_misc[ind]); +} +module_exit(usf_exit); MODULE_DESCRIPTION("Ultrasound framework driver"); +MODULE_LICENSE("GPL v2"); diff --git a/dsp/usfcdev.c b/dsp/usfcdev.c index 6b8aae01ec53..289616669f48 100644 --- a/dsp/usfcdev.c +++ b/dsp/usfcdev.c @@ -217,7 +217,7 @@ static bool usfcdev_filter(struct input_handle *handle, uint16_t ind = (uint16_t)handle->handler->minor; bool rc = (s_usfcdev_events[ind].event_status != USFCDEV_EVENT_ENABLED); - if (s_usf_pid == sys_getpid()) { + if (s_usf_pid == current->pid) { /* Pass events from usfcdev driver */ rc = false; pr_debug("%s: event_type=%d; type=%d; code=%d; val=%d", @@ -395,7 +395,7 @@ bool usfcdev_set_filter(uint16_t event_type_ind, bool filter) if (filter) { s_usfcdev_events[event_type_ind].event_status = USFCDEV_EVENT_DISABLING; - s_usf_pid = sys_getpid(); + s_usf_pid = current->pid; usfcdev_clean_dev(event_type_ind); s_usfcdev_events[event_type_ind].event_status = USFCDEV_EVENT_DISABLED; @@ -411,12 +411,3 @@ bool usfcdev_set_filter(uint16_t event_type_ind, bool filter) return rc; } - -static int __init usfcdev_init(void) -{ - return 0; -} - -device_initcall(usfcdev_init); - -MODULE_DESCRIPTION("Handle of events from devices, conflicting with USF"); diff --git a/include/dsp/audio_notifier.h b/include/dsp/audio_notifier.h index 3587b49a05c6..c7794ac602de 100644 --- a/include/dsp/audio_notifier.h +++ b/include/dsp/audio_notifier.h @@ -43,7 +43,7 @@ struct audio_notifier_cb_data { int domain; }; -#ifdef CONFIG_MSM_QDSP6_NOTIFIER +#if IS_ENABLED(CONFIG_MSM_QDSP6_NOTIFIER) /* * Use audio_notifier_register to register any audio @@ -100,6 +100,6 @@ static inline int audio_notifier_deregister(char *client_name) return 0; } -#endif /* CONFIG_MSM_QDSP6_PDR */ +#endif /* CONFIG_MSM_QDSP6_NOTIFIER */ #endif diff --git a/include/asoc/msm-dts-srs-tm-config.h b/include/dsp/msm-dts-srs-tm-config.h similarity index 100% rename from include/asoc/msm-dts-srs-tm-config.h rename to include/dsp/msm-dts-srs-tm-config.h diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 013d5229cf08..6a6d3b23f1f5 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -184,4 +184,6 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, int session_type, struct msm_pcm_channel_mixer *ch_mixer, int channel_index); +void msm_dts_srs_acquire_lock(void); +void msm_dts_srs_release_lock(void); #endif /* __Q6_ADM_V2_H__ */ diff --git a/include/ipc/apr.h b/include/ipc/apr.h index 29deb3ca5ac7..4e5e3d8630a5 100644 --- a/include/ipc/apr.h +++ b/include/ipc/apr.h @@ -174,6 +174,7 @@ int apr_send_pkt(void *handle, uint32_t *buf); int apr_deregister(void *handle); void subsys_notif_register(char *client_name, int domain, struct notifier_block *nb); +void subsys_notif_deregister(char *client_name); int apr_get_dest_id(char *dest); uint16_t apr_get_data_src(struct apr_hdr *hdr); void change_q6_state(int state); diff --git a/include/ipc/apr_tal.h b/include/ipc/apr_tal.h index 26d1a4c56ebc..fc1471d4f08d 100644 --- a/include/ipc/apr_tal.h +++ b/include/ipc/apr_tal.h @@ -73,6 +73,7 @@ int apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data, int apr_tal_close(struct apr_svc_ch_dev *apr_ch); int apr_tal_rx_intents_config(struct apr_svc_ch_dev *apr_ch, int num_of_intents, uint32_t size); +int apr_tal_init(void); struct apr_svc_ch_dev { diff --git a/include/soc/internal.h b/include/soc/internal.h index 2bc065526db0..452d9d2686bd 120000 --- a/include/soc/internal.h +++ b/include/soc/internal.h @@ -1 +1 @@ -../../../../drivers/base/regmap/internal.h \ No newline at end of file +../../../../../../kernel/msm-4.9/drivers/base/regmap/internal.h \ No newline at end of file diff --git a/ipc/Android.mk b/ipc/Android.mk new file mode 100644 index 000000000000..8032374311ae --- /dev/null +++ b/ipc/Android.mk @@ -0,0 +1,61 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,sdm845),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m +endif + +ifeq ($(call is-board-platform,sdm670),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,sdm845 sdm670),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=apr_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_apr.ko +LOCAL_MODULE_KBUILD_NAME := apr_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_wglink.ko +LOCAL_MODULE_KBUILD_NAME := wglink_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/ipc/Kbuild b/ipc/Kbuild new file mode 100644 index 000000000000..b729f90318b7 --- /dev/null +++ b/ipc/Kbuild @@ -0,0 +1,153 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +KERNEL_BUILD := 0 + +TARGET_KERNEL_VERSION := 4.4 + +ifeq ($(KERNEL_BUILD), 0) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + ifeq ($(CONFIG_ARCH_SDM845), y) + include $(AUDIO_ROOT)/config/sdm845auto.conf + export + TARGET_KERNEL_VERSION := 4.9 + endif + ifeq ($(CONFIG_ARCH_SDM670), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + TARGET_KERNEL_VERSION := 4.9 + endif +endif + + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ IPC ############ + +ifeq ($(CONFIG_MSM_QDSP6_APRV2_GLINK), m) +APRV_GLINK += apr.o +APRV_GLINK += apr_v2.o +APRV_GLINK += apr_tal_glink.o +endif + +ifeq ($(CONFIG_MSM_QDSP6_APRV3_GLINK), m) +APRV_GLINK += apr.o +APRV_GLINK += apr_v3.o +APRV_GLINK += apr_tal_glink.o +endif + +ifeq ($(CONFIG_WCD_DSP_GLINK), m) +WDSP_GLINK += wcd-dsp-glink.o +endif + +LINUX_INC += -Iinclude/linux + +INCS := $(COMMON_INC) \ + $(UAPI_INC) + +ifeq ($(CONFIG_ARCH_SDM845), y) +INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h +endif +ifeq ($(CONFIG_ARCH_SDM670), y) +INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h +endif + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +HEADER_INSTALL_DIR := $(TOP)/kernel/msm-$(TARGET_KERNEL_VERSION)/scripts +UAPI_OUT := $(OUT)/obj/vendor/qcom/opensource/audio-kernel/include +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ avtimer.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_aac.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_ac3.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_alac.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_amrnb.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_amrwb.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_amrwbplus.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_ape.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_calibration.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_g711_dec.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_g711.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_mvs.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_qcp.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_sbc.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_voicememo.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_wma.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_wmapro.h;) + +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ audio_effects.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ audio_slimslave.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ devdep_params.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ lsm_params.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ msmcal-hwdep.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ voice_params.h;) +$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ wcd-dsp-glink.h;) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif +# If the module name is not "wlan", then the define MULTI_IF_NAME to be the +# same a the QCA CHIP name. The host driver will then append MULTI_IF_NAME to +# any string that must be unique for all instances of the driver on the system. +# This allows multiple instances of the driver with different module names. +# If the module name is wlan, leave MULTI_IF_NAME undefined and the code will +# treat the driver as the primary driver. +ifneq ($(MODNAME), qdsp6v2) +CHIP_NAME ?= $(MODNAME) +CDEFINES += -DMULTI_IF_NAME=\"$(CHIP_NAME)\" +endif + +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +# Module information used by KBuild framework +obj-$(CONFIG_MSM_QDSP6_APRV2_GLINK) += apr_dlkm.o +apr_dlkm-y := $(APRV_GLINK) + +obj-$(CONFIG_WCD_DSP_GLINK) += wglink_dlkm.o +wglink_dlkm-y := $(WDSP_GLINK) + +# inject some build related information +CDEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/ipc/apr.c b/ipc/apr.c index 8fc62f406cb7..dd2a63bd70f3 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -207,15 +207,29 @@ static struct apr_svc_table svc_tbl_voice[] = { }, }; +/** + * apr_get_modem_state: + * + * Returns current modem load status + * + */ enum apr_subsys_state apr_get_modem_state(void) { return atomic_read(&q6.modem_state); } +EXPORT_SYMBOL(apr_get_modem_state); +/** + * apr_set_modem_state - Update modem load status. + * + * @state: State to update modem load status + * + */ void apr_set_modem_state(enum apr_subsys_state state) { atomic_set(&q6.modem_state, state); } +EXPORT_SYMBOL(apr_set_modem_state); enum apr_subsys_state apr_cmpxchg_modem_state(enum apr_subsys_state prev, enum apr_subsys_state new) @@ -318,6 +332,15 @@ struct apr_client *apr_get_client(int dest_id, int client_id) return &client[dest_id][client_id]; } +/** + * apr_send_pkt - Clients call to send packet + * to destination processor. + * + * @handle: APR service handle + * @buf: payload to send to destination processor. + * + * Returns Bytes(>0)pkt_size on success or error on failure. + */ int apr_send_pkt(void *handle, uint32_t *buf) { struct apr_svc *svc = handle; @@ -391,6 +414,7 @@ int apr_send_pkt(void *handle, uint32_t *buf) return rc; } +EXPORT_SYMBOL(apr_send_pkt); int apr_pkt_config(void *handle, struct apr_pkt_cfg *cfg) { @@ -418,6 +442,19 @@ int apr_pkt_config(void *handle, struct apr_pkt_cfg *cfg) cfg->intents.num_of_intents, cfg->intents.size); } +/** + * apr_register - Clients call to register + * to APR. + * + * @dest: destination processor + * @svc_name: name of service to register as + * @svc_fn: callback function to trigger when response + * ack or packets received from destination processor. + * @src_port: Port number within a service + * @priv: private data of client, passed back in cb fn. + * + * Returns apr_svc handle on success or NULL on failure. + */ struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn, uint32_t src_port, void *priv) { @@ -534,6 +571,7 @@ struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn, done: return svc; } +EXPORT_SYMBOL(apr_register); void apr_cb_func(void *buf, int len, void *priv) @@ -735,6 +773,14 @@ static void apr_reset_deregister(struct work_struct *work) kfree(apr_reset); } +/** + * apr_deregister - Clients call to de-register + * from APR. + * + * @handle: APR service handle to de-register + * + * Returns 0 on success or -EINVAL on error. + */ int apr_deregister(void *handle) { struct apr_svc *svc = handle; @@ -784,7 +830,15 @@ int apr_deregister(void *handle) return 0; } +EXPORT_SYMBOL(apr_deregister); +/** + * apr_reset - sets up workqueue to de-register + * the given APR service handle. + * + * @handle: APR service handle + * + */ void apr_reset(void *handle) { struct apr_reset_work *apr_reset_worker = NULL; @@ -810,6 +864,7 @@ void apr_reset(void *handle) INIT_WORK(&apr_reset_worker->work, apr_reset_deregister); queue_work(apr_reset_workqueue, &apr_reset_worker->work); } +EXPORT_SYMBOL(apr_reset); /* Dispatch the Reset events to Modem and audio clients */ static void dispatch_event(unsigned long code, uint16_t proc) @@ -920,10 +975,28 @@ static struct notifier_block modem_service_nb = { .priority = 0, }; +#ifdef CONFIG_DEBUG_FS +static int __init apr_debug_init(void) +{ + debugfs_apr_debug = debugfs_create_file("msm_apr_debug", + S_IFREG | 0444, NULL, NULL, + &apr_debug_ops); + return 0; +} +#else +static int __init apr_debug_init(void) +( + return 0; +) +#endif + static int __init apr_init(void) { int i, j, k; + init_waitqueue_head(&dsp_wait); + init_waitqueue_head(&modem_wait); + for (i = 0; i < APR_DEST_MAX; i++) for (j = 0; j < APR_CLIENT_MAX; j++) { mutex_init(&client[i][j].m_lock); @@ -949,28 +1022,16 @@ static int __init apr_init(void) subsys_notif_register("apr_modem", AUDIO_NOTIFIER_MODEM_DOMAIN, &modem_service_nb); - return 0; + apr_tal_init(); + return apr_debug_init(); } -device_initcall(apr_init); +module_init(apr_init); -static int __init apr_late_init(void) +void __exit apr_exit(void) { - int ret = 0; - - init_waitqueue_head(&dsp_wait); - init_waitqueue_head(&modem_wait); - - return ret; -} -late_initcall(apr_late_init); - -#ifdef CONFIG_DEBUG_FS -static int __init apr_debug_init(void) -{ - debugfs_apr_debug = debugfs_create_file("msm_apr_debug", - S_IFREG | 0444, NULL, NULL, - &apr_debug_ops); - return 0; + subsys_notif_deregister("apr_modem"); + subsys_notif_deregister("apr_adsp"); } -device_initcall(apr_debug_init); -#endif +module_exit(apr_exit); +MODULE_DESCRIPTION("APR module"); +MODULE_LICENSE("GPL v2"); diff --git a/ipc/apr_tal_glink.c b/ipc/apr_tal_glink.c index 7de7ddafdb54..3803dcb1ea9a 100644 --- a/ipc/apr_tal_glink.c +++ b/ipc/apr_tal_glink.c @@ -416,7 +416,7 @@ static struct glink_link_info lpass_link_info = { .glink_link_state_notif_cb = apr_tal_link_state_cb, }; -static int __init apr_tal_init(void) +int apr_tal_init(void) { int i, j, k; @@ -448,4 +448,3 @@ static int __init apr_tal_init(void) return 0; } -device_initcall(apr_tal_init); diff --git a/ipc/apr_v2.c b/ipc/apr_v2.c index 7e6331009458..e85173cd2158 100644 --- a/ipc/apr_v2.c +++ b/ipc/apr_v2.c @@ -66,6 +66,16 @@ void subsys_notif_register(char *client_name, int domain, __func__, domain, ret); } +void subsys_notif_deregister(char *client_name) +{ + int ret; + + ret = audio_notifier_deregister(client_name); + if (ret < 0) + pr_err("%s: Audio notifier de-register failed for client %s\n", + __func__, client_name); +} + uint16_t apr_get_reset_domain(uint16_t proc) { return proc; diff --git a/ipc/apr_v3.c b/ipc/apr_v3.c index 5a4ef53bb76f..fa68daf55e84 100644 --- a/ipc/apr_v3.c +++ b/ipc/apr_v3.c @@ -58,6 +58,16 @@ void subsys_notif_register(char *client_name, int domain, __func__, domain, ret); } +void subsys_notif_deregister(char *client_name) +{ + int ret; + + ret = audio_notifier_deregister(client_name); + if (ret < 0) + pr_err("%s: Audio notifier de-register failed for client %s\n", + __func__, client_name); +} + uint16_t apr_get_reset_domain(uint16_t proc) { return APR_DEST_QDSP6; diff --git a/ipc/wcd-dsp-glink.c b/ipc/wcd-dsp-glink.c index cab7c3b7c4a2..400fd0617360 100644 --- a/ipc/wcd-dsp-glink.c +++ b/ipc/wcd-dsp-glink.c @@ -1212,7 +1212,17 @@ static struct platform_driver wdsp_glink_driver = { }, }; -module_platform_driver(wdsp_glink_driver); +static int __init wdsp_glink_init(void) +{ + return platform_driver_register(&wdsp_glink_driver); +} + +static void __exit wdsp_glink_exit(void) +{ + platform_driver_unregister(&wdsp_glink_driver); +} +module_init(wdsp_glink_init); +module_exit(wdsp_glink_exit); MODULE_DESCRIPTION("SoC WCD_DSP GLINK Driver"); MODULE_LICENSE("GPL v2"); diff --git a/soc/Android.mk b/soc/Android.mk new file mode 100644 index 000000000000..e5ec9aa22208 --- /dev/null +++ b/soc/Android.mk @@ -0,0 +1,79 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,sdm845),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m +endif + +ifeq ($(call is-board-platform,sdm670),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,sdm845 sdm670),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=soc_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +ifeq ($(call is-board-platform,sdm670),true) +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_lpi.ko +LOCAL_MODULE_KBUILD_NAME := pinctrl_lpi_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +endif +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_wcd.ko +LOCAL_MODULE_KBUILD_NAME := pinctrl_wcd_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_swr.ko +LOCAL_MODULE_KBUILD_NAME := swr_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_swr_ctrl.ko +LOCAL_MODULE_KBUILD_NAME := swr_ctrl_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/soc/Kbuild b/soc/Kbuild new file mode 100644 index 000000000000..45b77e9ce1f8 --- /dev/null +++ b/soc/Kbuild @@ -0,0 +1,121 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +KERNEL_BUILD := 0 + + +ifeq ($(KERNEL_BUILD), 0) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + ifeq ($(CONFIG_ARCH_SDM845), y) + include $(AUDIO_ROOT)/config/sdm845auto.conf + export + endif + ifeq ($(CONFIG_ARCH_SDM670), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + endif +endif + + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ SoC Modules ############ + +# for pinctrl WCD driver +ifeq ($(CONFIG_PINCTRL_WCD), m) + PINCTRL_WCD_OBJS += pinctrl-wcd.o +endif + +# for pinctrl LPI driver +ifeq ($(CONFIG_PINCTRL_LPI), m) + PINCTRL_LPI_OBJS += pinctrl-lpi.o +endif + +# for soundwire driver +ifeq ($(CONFIG_SOUNDWIRE_WCD_CTRL), m) + SWR_CTRL_OBJS += swr-wcd-ctrl.o +endif + +ifeq ($(CONFIG_SOUNDWIRE), m) + SWR_OBJS += regmap-swr.o + SWR_OBJS += soundwire.o +endif + +LINUX_INC += -Iinclude/linux + +INCS := $(COMMON_INC) \ + $(UAPI_INC) + +ifeq ($(CONFIG_ARCH_SDM845), y) +INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h +endif +ifeq ($(CONFIG_ARCH_SDM670), y) +INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h +endif + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +# Module information used by KBuild framework +obj-$(CONFIG_PINCTRL_WCD) += pinctrl_wcd_dlkm.o +pinctrl_wcd_dlkm-y := $(PINCTRL_WCD_OBJS) + +obj-$(CONFIG_PINCTRL_LPI) += pinctrl_lpi_dlkm.o +pinctrl_lpi_dlkm-y := $(PINCTRL_LPI_OBJS) + +obj-$(CONFIG_SOUNDWIRE) += swr_dlkm.o +swr_dlkm-y := $(SWR_OBJS) + +obj-$(CONFIG_SOUNDWIRE_WCD_CTRL) += swr_ctrl_dlkm.o +swr_ctrl_dlkm-y := $(SWR_CTRL_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/soc/core.h b/soc/core.h index 8a2fa90df8cb..451c69610e0d 120000 --- a/soc/core.h +++ b/soc/core.h @@ -1 +1 @@ -../../../drivers/pinctrl/core.h \ No newline at end of file +../../../../../kernel/msm-4.9/drivers/pinctrl/core.h \ No newline at end of file diff --git a/soc/pinctrl-utils.h b/soc/pinctrl-utils.h index 9aab5f24bd14..2ea9d23df537 120000 --- a/soc/pinctrl-utils.h +++ b/soc/pinctrl-utils.h @@ -1 +1 @@ -../../../drivers/pinctrl/pinctrl-utils.h \ No newline at end of file +../../../../../kernel/msm-4.9/drivers/pinctrl/pinctrl-utils.h \ No newline at end of file diff --git a/soc/soundwire.c b/soc/soundwire.c index 6095c0a82e94..cda4789d8d62 100644 --- a/soc/soundwire.c +++ b/soc/soundwire.c @@ -1026,7 +1026,7 @@ static int __init soundwire_init(void) return retval; } -postcore_initcall(soundwire_init); +module_init(soundwire_init); module_exit(soundwire_exit); diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c index bb78372aa9e5..dc1f7866d40c 100644 --- a/soc/swr-wcd-ctrl.c +++ b/soc/swr-wcd-ctrl.c @@ -1878,7 +1878,7 @@ static int __init swrm_init(void) { return platform_driver_register(&swr_mstr_driver); } -subsys_initcall(swrm_init); +module_init(swrm_init); static void __exit swrm_exit(void) { @@ -1886,7 +1886,6 @@ static void __exit swrm_exit(void) } module_exit(swrm_exit); - MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("WCD SoundWire Controller"); MODULE_ALIAS("platform:swr-wcd"); -- GitLab From 20df5454665b92491ac17fd1f0296e384ff90bde Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Mon, 16 Oct 2017 15:35:56 +0530 Subject: [PATCH 0074/1645] asoc: sdm660: update cpu dai id for quinary mi2s interface Update quinary mi2s cpu dai id to 4 for sdm670. This is required for sending correct afe port id for quin mi2s and keep all MI2S interfaces in sequence. CRs-Fixed: 2133890 Change-Id: I0ab35f2d97858f355da577076a5a1e3f438a1bab Signed-off-by: Rohit kumar --- asoc/sdm660-ext-dai-links.c | 4 ++-- asoc/sdm660-internal.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/asoc/sdm660-ext-dai-links.c b/asoc/sdm660-ext-dai-links.c index a33113550f4c..33e8e0aa2a89 100644 --- a/asoc/sdm660-ext-dai-links.c +++ b/asoc/sdm660-ext-dai-links.c @@ -1720,7 +1720,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { { .name = LPASS_BE_QUIN_MI2S_RX, .stream_name = "Quinary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.5", + .cpu_dai_name = "msm-dai-q6-mi2s.4", .platform_name = "msm-pcm-routing", .codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-rx", @@ -1735,7 +1735,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { { .name = LPASS_BE_QUIN_MI2S_TX, .stream_name = "Quinary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.5", + .cpu_dai_name = "msm-dai-q6-mi2s.4", .platform_name = "msm-pcm-routing", .codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-tx", diff --git a/asoc/sdm660-internal.c b/asoc/sdm660-internal.c index a1536fefe635..20e49bcb1b44 100644 --- a/asoc/sdm660-internal.c +++ b/asoc/sdm660-internal.c @@ -2759,7 +2759,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { { .name = LPASS_BE_QUIN_MI2S_RX, .stream_name = "Quinary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.5", + .cpu_dai_name = "msm-dai-q6-mi2s.4", .platform_name = "msm-pcm-routing", .codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-rx", @@ -2774,7 +2774,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { { .name = LPASS_BE_QUIN_MI2S_TX, .stream_name = "Quinary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.5", + .cpu_dai_name = "msm-dai-q6-mi2s.4", .platform_name = "msm-pcm-routing", .codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-tx", -- GitLab From b242df4632e4f7c7cb7a5f759aabdffa3909058b Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Mon, 16 Oct 2017 15:37:05 +0530 Subject: [PATCH 0075/1645] asoc: dai-q6: update quinary mi2s dai id to 4 Update quinary mi2s dai id to 4 and secondary mi2s playback sd1 dai id to 5. Also update index of mi2s_config_controls for primary, secondary, tertiary and quaternary mi2s. CRs-Fixed: 2133890 Change-Id: I00997b79a148cf50b2a3f9acf6e44fe603e5c944 Signed-off-by: Rohit kumar --- asoc/msm-dai-q6-v2.c | 32 ++++++++++++++++---------------- asoc/msm-dai-q6-v2.h | 6 +++--- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 70fcadcdb3c0..af288f1cd8ad 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -3690,13 +3690,13 @@ static int msm_dai_q6_dai_mi2s_probe(struct snd_soc_dai *dai) ctrl = NULL; if (mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.channel_mode) { if (dai->id == MSM_PRIM_MI2S) - ctrl = &mi2s_config_controls[4]; - if (dai->id == MSM_SEC_MI2S) ctrl = &mi2s_config_controls[5]; - if (dai->id == MSM_TERT_MI2S) + if (dai->id == MSM_SEC_MI2S) ctrl = &mi2s_config_controls[6]; - if (dai->id == MSM_QUAT_MI2S) + if (dai->id == MSM_TERT_MI2S) ctrl = &mi2s_config_controls[7]; + if (dai->id == MSM_QUAT_MI2S) + ctrl = &mi2s_config_controls[8]; if (dai->id == MSM_QUIN_MI2S) ctrl = &mi2s_config_controls[9]; if (dai->id == MSM_SENARY_MI2S) @@ -4276,18 +4276,6 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .probe = msm_dai_q6_dai_mi2s_probe, .remove = msm_dai_q6_dai_mi2s_remove, }, - { - .playback = { - .stream_name = "Secondary MI2S Playback SD1", - .aif_name = "SEC_MI2S_RX_SD1", - .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | - SNDRV_PCM_RATE_16000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rate_min = 8000, - .rate_max = 48000, - }, - .id = MSM_SEC_MI2S_SD1, - }, { .playback = { .stream_name = "Quinary MI2S Playback", @@ -4313,6 +4301,18 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .probe = msm_dai_q6_dai_mi2s_probe, .remove = msm_dai_q6_dai_mi2s_remove, }, + { + .playback = { + .stream_name = "Secondary MI2S Playback SD1", + .aif_name = "SEC_MI2S_RX_SD1", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .id = MSM_SEC_MI2S_SD1, + }, { .capture = { .stream_name = "Senary_mi2s Capture", diff --git a/asoc/msm-dai-q6-v2.h b/asoc/msm-dai-q6-v2.h index b1d76bf73f51..b3f457e9e544 100644 --- a/asoc/msm-dai-q6-v2.h +++ b/asoc/msm-dai-q6-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -25,8 +25,8 @@ #define MSM_SEC_MI2S 1 #define MSM_TERT_MI2S 2 #define MSM_QUAT_MI2S 3 -#define MSM_SEC_MI2S_SD1 4 -#define MSM_QUIN_MI2S 5 +#define MSM_QUIN_MI2S 4 +#define MSM_SEC_MI2S_SD1 5 #define MSM_SENARY_MI2S 6 #define MSM_INT0_MI2S 7 #define MSM_INT1_MI2S 8 -- GitLab From ebce3d99a49d97481a2e29c658758cfd173485b7 Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Mon, 16 Oct 2017 15:38:41 +0530 Subject: [PATCH 0076/1645] dsp: q6audio: add support for quinary interfaces Add support for quinary pcm and tdm interfaces in q6audio. CRs-Fixed: 2133890 Change-Id: I59ca2965f5d38d30bea5a00f34898af5c948ac16 Signed-off-by: Rohit kumar --- dsp/q6audio-v2.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/dsp/q6audio-v2.c b/dsp/q6audio-v2.c index 55e7244741fb..f3a756b5bca3 100644 --- a/dsp/q6audio-v2.c +++ b/dsp/q6audio-v2.c @@ -40,6 +40,10 @@ int q6audio_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_QUATERNARY_PCM_RX; case AFE_PORT_ID_QUATERNARY_PCM_TX: return IDX_AFE_PORT_ID_QUATERNARY_PCM_TX; + case AFE_PORT_ID_QUINARY_PCM_RX: + return IDX_AFE_PORT_ID_QUINARY_PCM_RX; + case AFE_PORT_ID_QUINARY_PCM_TX: + return IDX_AFE_PORT_ID_QUINARY_PCM_TX; case SECONDARY_I2S_RX: return IDX_SECONDARY_I2S_RX; case SECONDARY_I2S_TX: return IDX_SECONDARY_I2S_TX; case MI2S_RX: return IDX_MI2S_RX; @@ -95,6 +99,10 @@ int q6audio_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX; case AFE_PORT_ID_TERTIARY_MI2S_TX: return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX; + case AFE_PORT_ID_QUINARY_MI2S_RX: + return IDX_AFE_PORT_ID_QUINARY_MI2S_RX; + case AFE_PORT_ID_QUINARY_MI2S_TX: + return IDX_AFE_PORT_ID_QUINARY_MI2S_TX; case AUDIO_PORT_ID_I2S_RX: return IDX_AUDIO_PORT_ID_I2S_RX; case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1: @@ -227,6 +235,38 @@ int q6audio_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_7; case AFE_PORT_ID_QUATERNARY_TDM_TX_7: return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_7; + case AFE_PORT_ID_QUINARY_TDM_RX: + return IDX_AFE_PORT_ID_QUINARY_TDM_RX_0; + case AFE_PORT_ID_QUINARY_TDM_TX: + return IDX_AFE_PORT_ID_QUINARY_TDM_TX_0; + case AFE_PORT_ID_QUINARY_TDM_RX_1: + return IDX_AFE_PORT_ID_QUINARY_TDM_RX_1; + case AFE_PORT_ID_QUINARY_TDM_TX_1: + return IDX_AFE_PORT_ID_QUINARY_TDM_TX_1; + case AFE_PORT_ID_QUINARY_TDM_RX_2: + return IDX_AFE_PORT_ID_QUINARY_TDM_RX_2; + case AFE_PORT_ID_QUINARY_TDM_TX_2: + return IDX_AFE_PORT_ID_QUINARY_TDM_TX_2; + case AFE_PORT_ID_QUINARY_TDM_RX_3: + return IDX_AFE_PORT_ID_QUINARY_TDM_RX_3; + case AFE_PORT_ID_QUINARY_TDM_TX_3: + return IDX_AFE_PORT_ID_QUINARY_TDM_TX_3; + case AFE_PORT_ID_QUINARY_TDM_RX_4: + return IDX_AFE_PORT_ID_QUINARY_TDM_RX_4; + case AFE_PORT_ID_QUINARY_TDM_TX_4: + return IDX_AFE_PORT_ID_QUINARY_TDM_TX_4; + case AFE_PORT_ID_QUINARY_TDM_RX_5: + return IDX_AFE_PORT_ID_QUINARY_TDM_RX_5; + case AFE_PORT_ID_QUINARY_TDM_TX_5: + return IDX_AFE_PORT_ID_QUINARY_TDM_TX_5; + case AFE_PORT_ID_QUINARY_TDM_RX_6: + return IDX_AFE_PORT_ID_QUINARY_TDM_RX_6; + case AFE_PORT_ID_QUINARY_TDM_TX_6: + return IDX_AFE_PORT_ID_QUINARY_TDM_TX_6; + case AFE_PORT_ID_QUINARY_TDM_RX_7: + return IDX_AFE_PORT_ID_QUINARY_TDM_RX_7; + case AFE_PORT_ID_QUINARY_TDM_TX_7: + return IDX_AFE_PORT_ID_QUINARY_TDM_TX_7; case AFE_PORT_ID_SENARY_MI2S_TX: return IDX_AFE_PORT_ID_SENARY_MI2S_TX; case AFE_PORT_ID_USB_RX: @@ -286,6 +326,10 @@ int q6audio_get_port_id(u16 port_id) return AFE_PORT_ID_QUATERNARY_PCM_RX; case AFE_PORT_ID_QUATERNARY_PCM_TX: return AFE_PORT_ID_QUATERNARY_PCM_TX; + case AFE_PORT_ID_QUINARY_PCM_RX: + return AFE_PORT_ID_QUINARY_PCM_RX; + case AFE_PORT_ID_QUINARY_PCM_TX: + return AFE_PORT_ID_QUINARY_PCM_TX; case SECONDARY_I2S_RX: return AFE_PORT_ID_SECONDARY_MI2S_RX; case SECONDARY_I2S_TX: return AFE_PORT_ID_SECONDARY_MI2S_TX; case MI2S_RX: return AFE_PORT_ID_PRIMARY_MI2S_RX; @@ -342,6 +386,10 @@ int q6audio_get_port_id(u16 port_id) return AFE_PORT_ID_TERTIARY_MI2S_RX; case AFE_PORT_ID_TERTIARY_MI2S_TX: return AFE_PORT_ID_TERTIARY_MI2S_TX; + case AFE_PORT_ID_QUINARY_MI2S_RX: + return AFE_PORT_ID_QUINARY_MI2S_RX; + case AFE_PORT_ID_QUINARY_MI2S_TX: + return AFE_PORT_ID_QUINARY_MI2S_TX; case AUDIO_PORT_ID_I2S_RX: return AUDIO_PORT_ID_I2S_RX; case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1: @@ -474,6 +522,38 @@ int q6audio_get_port_id(u16 port_id) return AFE_PORT_ID_QUATERNARY_TDM_RX_7; case AFE_PORT_ID_QUATERNARY_TDM_TX_7: return AFE_PORT_ID_QUATERNARY_TDM_TX_7; + case AFE_PORT_ID_QUINARY_TDM_RX: + return AFE_PORT_ID_QUINARY_TDM_RX; + case AFE_PORT_ID_QUINARY_TDM_TX: + return AFE_PORT_ID_QUINARY_TDM_TX; + case AFE_PORT_ID_QUINARY_TDM_RX_1: + return AFE_PORT_ID_QUINARY_TDM_RX_1; + case AFE_PORT_ID_QUINARY_TDM_TX_1: + return AFE_PORT_ID_QUINARY_TDM_TX_1; + case AFE_PORT_ID_QUINARY_TDM_RX_2: + return AFE_PORT_ID_QUINARY_TDM_RX_2; + case AFE_PORT_ID_QUINARY_TDM_TX_2: + return AFE_PORT_ID_QUINARY_TDM_TX_2; + case AFE_PORT_ID_QUINARY_TDM_RX_3: + return AFE_PORT_ID_QUINARY_TDM_RX_3; + case AFE_PORT_ID_QUINARY_TDM_TX_3: + return AFE_PORT_ID_QUINARY_TDM_TX_3; + case AFE_PORT_ID_QUINARY_TDM_RX_4: + return AFE_PORT_ID_QUINARY_TDM_RX_4; + case AFE_PORT_ID_QUINARY_TDM_TX_4: + return AFE_PORT_ID_QUINARY_TDM_TX_4; + case AFE_PORT_ID_QUINARY_TDM_RX_5: + return AFE_PORT_ID_QUINARY_TDM_RX_5; + case AFE_PORT_ID_QUINARY_TDM_TX_5: + return AFE_PORT_ID_QUINARY_TDM_TX_5; + case AFE_PORT_ID_QUINARY_TDM_RX_6: + return AFE_PORT_ID_QUINARY_TDM_RX_6; + case AFE_PORT_ID_QUINARY_TDM_TX_6: + return AFE_PORT_ID_QUINARY_TDM_TX_6; + case AFE_PORT_ID_QUINARY_TDM_RX_7: + return AFE_PORT_ID_QUINARY_TDM_RX_7; + case AFE_PORT_ID_QUINARY_TDM_TX_7: + return AFE_PORT_ID_QUINARY_TDM_TX_7; case AFE_PORT_ID_SENARY_MI2S_TX: return AFE_PORT_ID_SENARY_MI2S_TX; case AFE_PORT_ID_USB_RX: @@ -549,12 +629,16 @@ int q6audio_is_digital_pcm_interface(u16 port_id) case AFE_PORT_ID_TERTIARY_PCM_TX: case AFE_PORT_ID_QUATERNARY_PCM_RX: case AFE_PORT_ID_QUATERNARY_PCM_TX: + case AFE_PORT_ID_QUINARY_PCM_RX: + case AFE_PORT_ID_QUINARY_PCM_TX: case SECONDARY_I2S_RX: case SECONDARY_I2S_TX: case MI2S_RX: case MI2S_TX: case AFE_PORT_ID_TERTIARY_MI2S_TX: case AFE_PORT_ID_TERTIARY_MI2S_RX: + case AFE_PORT_ID_QUINARY_MI2S_TX: + case AFE_PORT_ID_QUINARY_MI2S_RX: case AFE_PORT_ID_QUATERNARY_MI2S_RX: case AFE_PORT_ID_QUATERNARY_MI2S_TX: case AFE_PORT_ID_PRIMARY_MI2S_RX: @@ -627,6 +711,22 @@ int q6audio_is_digital_pcm_interface(u16 port_id) case AFE_PORT_ID_QUATERNARY_TDM_TX_6: case AFE_PORT_ID_QUATERNARY_TDM_RX_7: case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + case AFE_PORT_ID_QUINARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_TX: + case AFE_PORT_ID_QUINARY_TDM_RX_1: + case AFE_PORT_ID_QUINARY_TDM_TX_1: + case AFE_PORT_ID_QUINARY_TDM_RX_2: + case AFE_PORT_ID_QUINARY_TDM_TX_2: + case AFE_PORT_ID_QUINARY_TDM_RX_3: + case AFE_PORT_ID_QUINARY_TDM_TX_3: + case AFE_PORT_ID_QUINARY_TDM_RX_4: + case AFE_PORT_ID_QUINARY_TDM_TX_4: + case AFE_PORT_ID_QUINARY_TDM_RX_5: + case AFE_PORT_ID_QUINARY_TDM_TX_5: + case AFE_PORT_ID_QUINARY_TDM_RX_6: + case AFE_PORT_ID_QUINARY_TDM_TX_6: + case AFE_PORT_ID_QUINARY_TDM_RX_7: + case AFE_PORT_ID_QUINARY_TDM_TX_7: case AFE_PORT_ID_SENARY_MI2S_TX: case AFE_PORT_ID_INT0_MI2S_RX: case AFE_PORT_ID_INT0_MI2S_TX: @@ -673,6 +773,8 @@ int q6audio_validate_port(u16 port_id) case AFE_PORT_ID_TERTIARY_PCM_TX: case AFE_PORT_ID_QUATERNARY_PCM_RX: case AFE_PORT_ID_QUATERNARY_PCM_TX: + case AFE_PORT_ID_QUINARY_PCM_RX: + case AFE_PORT_ID_QUINARY_PCM_TX: case SECONDARY_I2S_RX: case SECONDARY_I2S_TX: case MI2S_RX: @@ -720,6 +822,8 @@ int q6audio_validate_port(u16 port_id) case AFE_PORT_ID_SPDIF_RX: case AFE_PORT_ID_TERTIARY_MI2S_RX: case AFE_PORT_ID_TERTIARY_MI2S_TX: + case AFE_PORT_ID_QUINARY_MI2S_RX: + case AFE_PORT_ID_QUINARY_MI2S_TX: case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1: case AFE_PORT_ID_PRIMARY_TDM_RX: case AFE_PORT_ID_PRIMARY_TDM_TX: @@ -785,6 +889,22 @@ int q6audio_validate_port(u16 port_id) case AFE_PORT_ID_QUATERNARY_TDM_TX_6: case AFE_PORT_ID_QUATERNARY_TDM_RX_7: case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + case AFE_PORT_ID_QUINARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_TX: + case AFE_PORT_ID_QUINARY_TDM_RX_1: + case AFE_PORT_ID_QUINARY_TDM_TX_1: + case AFE_PORT_ID_QUINARY_TDM_RX_2: + case AFE_PORT_ID_QUINARY_TDM_TX_2: + case AFE_PORT_ID_QUINARY_TDM_RX_3: + case AFE_PORT_ID_QUINARY_TDM_TX_3: + case AFE_PORT_ID_QUINARY_TDM_RX_4: + case AFE_PORT_ID_QUINARY_TDM_TX_4: + case AFE_PORT_ID_QUINARY_TDM_RX_5: + case AFE_PORT_ID_QUINARY_TDM_TX_5: + case AFE_PORT_ID_QUINARY_TDM_RX_6: + case AFE_PORT_ID_QUINARY_TDM_TX_6: + case AFE_PORT_ID_QUINARY_TDM_RX_7: + case AFE_PORT_ID_QUINARY_TDM_TX_7: case AFE_PORT_ID_SENARY_MI2S_TX: case AFE_PORT_ID_USB_RX: case AFE_PORT_ID_USB_TX: -- GitLab From b5321975e74d5a0ce6ffaa1c420ec97f0d0a807d Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Fri, 22 Sep 2017 17:54:48 +0800 Subject: [PATCH 0077/1645] uapi: extend struct of spk prot for ADSP SPv3 To support speaker protection v3, add sp version and limiter threshold in spk_prot_cfg struct. Change-Id: Ia4c89934e00bfa8c0e0c6823f48d56baf6759f14 Signed-off-by: Xiaojun Sang --- include/uapi/linux/msm_audio_calibration.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h index 1696ae5e9118..29fdf8f966e6 100644 --- a/include/uapi/linux/msm_audio_calibration.h +++ b/include/uapi/linux/msm_audio_calibration.h @@ -108,6 +108,7 @@ enum { #define AFE_SIDETONE_IIR_CAL_TYPE AFE_SIDETONE_IIR_CAL_TYPE #define TOPOLOGY_SPECIFIC_CHANNEL_INFO +#define MSM_SPKR_PROT_SPV3 enum { VERSION_0_0, @@ -301,6 +302,10 @@ struct audio_cal_info_spk_prot_cfg { * 1 - Start calib * 2 - Disable spk prot */ +#ifdef MSM_SPKR_PROT_SPV3 + uint32_t sp_version; + int32_t limiter_th[SP_V2_NUM_MAX_SPKRS]; +#endif }; struct audio_cal_info_sp_th_vi_ftm_cfg { -- GitLab From 12120ab1adcc4dfdf01ec5a68e8029a3dacd1857 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Thu, 28 Sep 2017 18:21:21 +0800 Subject: [PATCH 0078/1645] ASoC: add support for speaker protection 3.0 Add a new AFE API to send limiter threshold to ADSP. Change-Id: Ibcd795d7c0edb4f081636c621e51e5a1eaa036b1 Signed-off-by: Xiaojun Sang --- dsp/q6afe.c | 26 ++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 8 +++++++- include/dsp/q6afe-v2.h | 2 +- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 631a12324675..864ae4ad4507 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1045,6 +1045,7 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, } switch (param_id) { case AFE_PARAM_ID_FBSP_MODE_RX_CFG: + case AFE_PARAM_ID_SP_RX_LIMITER_TH: config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; break; case AFE_PARAM_ID_FEEDBACK_PATH_CFG: @@ -1229,6 +1230,7 @@ static void afe_send_cal_spkr_prot_tx(int port_id) static void afe_send_cal_spkr_prot_rx(int port_id) { union afe_spkr_prot_config afe_spk_config; + union afe_spkr_prot_config afe_spk_limiter_config; if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL) goto done; @@ -1250,6 +1252,30 @@ static void afe_send_cal_spkr_prot_rx(int port_id) &afe_spk_config)) pr_err("%s: RX MODE_VI_PROC_CFG failed\n", __func__); + + if (afe_spk_config.mode_rx_cfg.mode == + Q6AFE_MSM_SPKR_PROCESSING) { + if (this_afe.prot_cfg.sp_version >= + AFE_API_VERSION_SUPPORT_SPV3) { + afe_spk_limiter_config.limiter_th_cfg. + minor_version = 1; + afe_spk_limiter_config.limiter_th_cfg. + lim_thr_per_calib_q27[SP_V2_SPKR_1] = + this_afe.prot_cfg.limiter_th[SP_V2_SPKR_1]; + afe_spk_limiter_config.limiter_th_cfg. + lim_thr_per_calib_q27[SP_V2_SPKR_2] = + this_afe.prot_cfg.limiter_th[SP_V2_SPKR_2]; + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_RX_LIMITER_TH, + &afe_spk_limiter_config)) + pr_err("%s: SP_RX_LIMITER_TH failed.\n", + __func__); + } else { + pr_debug("%s: SPv3 failed to apply on AFE API version=%d.\n", + __func__, + this_afe.prot_cfg.sp_version); + } + } } mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); done: diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index be56d74eef43..ad0aa44a64bd 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -8895,7 +8895,7 @@ struct cmd_set_topologies { #define AFE_MODULE_FB_SPKR_PROT_RX 0x0001021C #define AFE_MODULE_FB_SPKR_PROT_V2_RX 0x0001025F - +#define AFE_PARAM_ID_SP_RX_LIMITER_TH 0x000102B1 #define AFE_PARAM_ID_FBSP_MODE_RX_CFG 0x0001021D #define AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG 0x00010260 @@ -9123,6 +9123,11 @@ struct afe_sp_ex_vi_get_param_resp { struct afe_sp_ex_vi_ftm_params param; } __packed; +struct afe_sp_rx_limiter_th_param { + uint32_t minor_version; + uint32_t lim_thr_per_calib_q27[SP_V2_NUM_MAX_SPKR]; +} __packed; + union afe_spkr_prot_config { struct asm_fbsp_mode_rx_cfg mode_rx_cfg; struct asm_spkr_calib_vi_proc_cfg vi_proc_cfg; @@ -9132,6 +9137,7 @@ union afe_spkr_prot_config { struct afe_sp_th_vi_ftm_cfg th_vi_ftm_cfg; struct afe_sp_ex_vi_mode_cfg ex_vi_mode_cfg; struct afe_sp_ex_vi_ftm_cfg ex_vi_ftm_cfg; + struct afe_sp_rx_limiter_th_param limiter_th_cfg; } __packed; struct afe_spkr_prot_config_command { diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 8fb480b3bb6d..6fb9c442ec30 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -41,7 +41,7 @@ #define AFE_CLK_VERSION_V1 1 #define AFE_CLK_VERSION_V2 2 - +#define AFE_API_VERSION_SUPPORT_SPV3 2 typedef int (*routing_cb)(int port); enum { -- GitLab From 24daae88958aee7848c144f92470c7033075d958 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Fri, 22 Sep 2017 16:50:24 +0800 Subject: [PATCH 0079/1645] ASoC: codecs: add mixer ctls to control boost level Add new mixer ctls to control max boost state level for speaker protection V3. Change-Id: If967de46955f6dc8692986503daea68ce105f642 Signed-off-by: Xiaojun Sang --- asoc/codecs/msm_sdw/msm_sdw_cdc.c | 75 ++++++++++++++++++++++++++++++ asoc/codecs/wcd9335.c | 76 +++++++++++++++++++++++++++++++ asoc/codecs/wcd934x/wcd934x.c | 72 +++++++++++++++++++++++++++++ 3 files changed, 223 insertions(+) diff --git a/asoc/codecs/msm_sdw/msm_sdw_cdc.c b/asoc/codecs/msm_sdw/msm_sdw_cdc.c index 05d1d801ce74..5649167ee6bb 100644 --- a/asoc/codecs/msm_sdw/msm_sdw_cdc.c +++ b/asoc/codecs/msm_sdw/msm_sdw_cdc.c @@ -934,6 +934,66 @@ static int msm_sdw_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, return 0; } +static int msm_sdw_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max = 0; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + bst_state_max = snd_soc_read(codec, MSM_SDW_BOOST0_BOOST_CTL); + bst_state_max = (bst_state_max & 0x0c) >> 2; + ucontrol->value.integer.value[0] = bst_state_max; + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_sdw_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + bst_state_max = ucontrol->value.integer.value[0] << 2; + snd_soc_update_bits(codec, MSM_SDW_BOOST0_BOOST_CTL, + 0x0c, bst_state_max); + + return 0; +} + +static int msm_sdw_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max = 0; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + bst_state_max = snd_soc_read(codec, MSM_SDW_BOOST1_BOOST_CTL); + bst_state_max = (bst_state_max & 0x0c) >> 2; + ucontrol->value.integer.value[0] = bst_state_max; + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_sdw_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + bst_state_max = ucontrol->value.integer.value[0] << 2; + snd_soc_update_bits(codec, MSM_SDW_BOOST1_BOOST_CTL, + 0x0c, bst_state_max); + + return 0; +} + static int msm_sdw_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1465,8 +1525,15 @@ static const char * const msm_sdw_ear_spkr_pa_gain_text[] = { "G_4_DB", "G_5_DB", "G_6_DB" }; +static const char * const msm_sdw_speaker_boost_stage_text[] = { + "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2" +}; + static SOC_ENUM_SINGLE_EXT_DECL(msm_sdw_ear_spkr_pa_gain_enum, msm_sdw_ear_spkr_pa_gain_text); +static SOC_ENUM_SINGLE_EXT_DECL(msm_sdw_spkr_boost_stage_enum, + msm_sdw_speaker_boost_stage_text); + /* RX4 MIX1 */ static const struct soc_enum rx4_mix1_inp1_chain_enum = SOC_ENUM_SINGLE(MSM_SDW_TOP_RX7_PATH_INPUT0_MUX, @@ -1568,6 +1635,14 @@ static const struct snd_kcontrol_new msm_sdw_snd_controls[] = { SOC_ENUM_EXT("EAR SPKR PA Gain", msm_sdw_ear_spkr_pa_gain_enum, msm_sdw_ear_spkr_pa_gain_get, msm_sdw_ear_spkr_pa_gain_put), + SOC_ENUM_EXT("SPKR Left Boost Max State", + msm_sdw_spkr_boost_stage_enum, + msm_sdw_spkr_left_boost_stage_get, + msm_sdw_spkr_left_boost_stage_put), + SOC_ENUM_EXT("SPKR Right Boost Max State", + msm_sdw_spkr_boost_stage_enum, + msm_sdw_spkr_right_boost_stage_get, + msm_sdw_spkr_right_boost_stage_put), SOC_SINGLE_SX_TLV("RX4 Digital Volume", MSM_SDW_RX7_RX_VOL_CTL, 0, -84, 40, digital_gain), SOC_SINGLE_SX_TLV("RX5 Digital Volume", MSM_SDW_RX8_RX_VOL_CTL, diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 8ade82b7bb21..a4a838f9a6b9 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -8659,6 +8659,66 @@ static int tasha_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, return 0; } +static int tasha_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max = 0; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + bst_state_max = snd_soc_read(codec, WCD9335_CDC_BOOST0_BOOST_CTL); + bst_state_max = (bst_state_max & 0x0c) >> 2; + ucontrol->value.integer.value[0] = bst_state_max; + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int tasha_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + bst_state_max = ucontrol->value.integer.value[0] << 2; + snd_soc_update_bits(codec, WCD9335_CDC_BOOST0_BOOST_CTL, + 0x0c, bst_state_max); + + return 0; +} + +static int tasha_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max = 0; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + bst_state_max = snd_soc_read(codec, WCD9335_CDC_BOOST1_BOOST_CTL); + bst_state_max = (bst_state_max & 0x0c) >> 2; + ucontrol->value.integer.value[0] = bst_state_max; + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int tasha_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + bst_state_max = ucontrol->value.integer.value[0] << 2; + snd_soc_update_bits(codec, WCD9335_CDC_BOOST1_BOOST_CTL, + 0x0c, bst_state_max); + + return 0; +} + static int tasha_config_compander(struct snd_soc_codec *codec, int interp_n, int event) { @@ -8953,6 +9013,10 @@ static const char * const tasha_ear_spkr_pa_gain_text[] = { "G_5_DB", "G_6_DB" }; +static const char * const tasha_speaker_boost_stage_text[] = { + "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2" +}; + static const struct soc_enum tasha_ear_pa_gain_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_ear_pa_gain_text), tasha_ear_pa_gain_text); @@ -8961,6 +9025,10 @@ static const struct soc_enum tasha_ear_spkr_pa_gain_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_ear_spkr_pa_gain_text), tasha_ear_spkr_pa_gain_text); +static const struct soc_enum tasha_spkr_boost_stage_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tasha_speaker_boost_stage_text), + tasha_speaker_boost_stage_text); + static const struct snd_kcontrol_new tasha_analog_gain_controls[] = { SOC_ENUM_EXT("EAR PA Gain", tasha_ear_pa_gain_enum, tasha_ear_pa_gain_get, tasha_ear_pa_gain_put), @@ -8968,6 +9036,14 @@ static const struct snd_kcontrol_new tasha_analog_gain_controls[] = { SOC_ENUM_EXT("EAR SPKR PA Gain", tasha_ear_spkr_pa_gain_enum, tasha_ear_spkr_pa_gain_get, tasha_ear_spkr_pa_gain_put), + SOC_ENUM_EXT("SPKR Left Boost Max State", tasha_spkr_boost_stage_enum, + tasha_spkr_left_boost_stage_get, + tasha_spkr_left_boost_stage_put), + + SOC_ENUM_EXT("SPKR Right Boost Max State", tasha_spkr_boost_stage_enum, + tasha_spkr_right_boost_stage_get, + tasha_spkr_right_boost_stage_put), + SOC_SINGLE_TLV("HPHL Volume", WCD9335_HPH_L_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("HPHR Volume", WCD9335_HPH_R_EN, 0, 20, 1, diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 7fd1e63dd6fe..d6eb22d57951 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -5577,6 +5577,66 @@ static int tavil_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, return 0; } +static int tavil_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max = 0; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + bst_state_max = snd_soc_read(codec, WCD934X_CDC_BOOST0_BOOST_CTL); + bst_state_max = (bst_state_max & 0x0c) >> 2; + ucontrol->value.integer.value[0] = bst_state_max; + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int tavil_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + bst_state_max = ucontrol->value.integer.value[0] << 2; + snd_soc_update_bits(codec, WCD934X_CDC_BOOST0_BOOST_CTL, + 0x0c, bst_state_max); + + return 0; +} + +static int tavil_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max = 0; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + bst_state_max = snd_soc_read(codec, WCD934X_CDC_BOOST1_BOOST_CTL); + bst_state_max = (bst_state_max & 0x0c) >> 2; + ucontrol->value.integer.value[0] = bst_state_max; + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int tavil_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + bst_state_max = ucontrol->value.integer.value[0] << 2; + snd_soc_update_bits(codec, WCD934X_CDC_BOOST1_BOOST_CTL, + 0x0c, bst_state_max); + + return 0; +} + static int tavil_rx_hph_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -5655,9 +5715,15 @@ static const char * const tavil_ear_spkr_pa_gain_text[] = { "G_4_DB", "G_5_DB", "G_6_DB" }; +static const char * const tavil_speaker_boost_stage_text[] = { + "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2" +}; + static SOC_ENUM_SINGLE_EXT_DECL(tavil_ear_pa_gain_enum, tavil_ear_pa_gain_text); static SOC_ENUM_SINGLE_EXT_DECL(tavil_ear_spkr_pa_gain_enum, tavil_ear_spkr_pa_gain_text); +static SOC_ENUM_SINGLE_EXT_DECL(tavil_spkr_boost_stage_enum, + tavil_speaker_boost_stage_text); static SOC_ENUM_SINGLE_EXT_DECL(amic_pwr_lvl_enum, amic_pwr_lvl_text); static SOC_ENUM_SINGLE_EXT_DECL(hph_idle_detect_enum, hph_idle_detect_text); static SOC_ENUM_SINGLE_EXT_DECL(asrc_mode_enum, asrc_mode_text); @@ -5713,6 +5779,12 @@ static const struct snd_kcontrol_new tavil_snd_controls[] = { tavil_ear_pa_gain_get, tavil_ear_pa_gain_put), SOC_ENUM_EXT("EAR SPKR PA Gain", tavil_ear_spkr_pa_gain_enum, tavil_ear_spkr_pa_gain_get, tavil_ear_spkr_pa_gain_put), + SOC_ENUM_EXT("SPKR Left Boost Max State", tavil_spkr_boost_stage_enum, + tavil_spkr_left_boost_stage_get, + tavil_spkr_left_boost_stage_put), + SOC_ENUM_EXT("SPKR Right Boost Max State", tavil_spkr_boost_stage_enum, + tavil_spkr_right_boost_stage_get, + tavil_spkr_right_boost_stage_put), SOC_SINGLE_TLV("HPHL Volume", WCD934X_HPH_L_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("HPHR Volume", WCD934X_HPH_R_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("LINEOUT1 Volume", WCD934X_DIFF_LO_LO1_COMPANDER, -- GitLab From fa21d8cd20fb442954277cba8f7e5102353847a4 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Fri, 22 Sep 2017 17:05:02 +0800 Subject: [PATCH 0080/1645] ASoC: wsa: add mixer ctl to set boost value Add a new mixer ctl to set WSA boost value for speaker protection v3. Boost value for different stages are packed together. Change-Id: Ie80d7bea4d3af00b74935f8b680e72ee967717f6 Signed-off-by: Xiaojun Sang --- asoc/codecs/wsa881x.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index bff0ad539792..0755cdcab8b6 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -676,6 +676,36 @@ static int wsa881x_set_visense(struct snd_kcontrol *kcontrol, return 0; } +static int wsa881x_set_boost_level(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u8 wsa_boost_level = 0; + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + wsa_boost_level = ucontrol->value.integer.value[0]; + snd_soc_update_bits(codec, WSA881X_BOOST_PRESET_OUT1, + 0xff, wsa_boost_level); + + return 0; +} + +static int wsa881x_get_boost_level(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u8 wsa_boost_level = 0; + + wsa_boost_level = snd_soc_read(codec, WSA881X_BOOST_PRESET_OUT1); + ucontrol->value.integer.value[0] = wsa_boost_level; + dev_dbg(codec->dev, "%s: boost level = 0x%x\n", __func__, + wsa_boost_level); + + return 0; +} + static const struct snd_kcontrol_new wsa881x_snd_controls[] = { SOC_SINGLE_EXT("COMP Switch", SND_SOC_NOPM, 0, 1, 0, wsa881x_get_compander, wsa881x_set_compander), @@ -685,6 +715,9 @@ static const struct snd_kcontrol_new wsa881x_snd_controls[] = { SOC_SINGLE_EXT("VISENSE Switch", SND_SOC_NOPM, 0, 1, 0, wsa881x_get_visense, wsa881x_set_visense), + + SOC_SINGLE_EXT("Boost Level", SND_SOC_NOPM, 0, 0xff, 0, + wsa881x_get_boost_level, wsa881x_set_boost_level), }; static const struct snd_kcontrol_new swr_dac_port[] = { -- GitLab From 3249ff278d908af34824803a2d38d2890783cc31 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 12 Oct 2017 07:51:35 +0530 Subject: [PATCH 0081/1645] ASoC: codecs: sdm660_cdc: Fix kernel panic on sdm660-internal Kernel panic is observed during SSR. This is because ADSP does not get sufficient time to bring up LPASS after SSR. An increase in ADSP Ready timeout resolves the issue. CRs-Fixed: 2101404 Change-Id: Ia7d1ecde7a713b4d71b2a4ebb1f85a38b8fa28b5 Signed-off-by: Vatsal Bucha --- asoc/codecs/sdm660_cdc/msm-analog-cdc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c index 623303c3adca..6c66cd0f513d 100644 --- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c @@ -49,10 +49,10 @@ #define BUS_DOWN 1 /* - * 50 Milliseconds sufficient for DSP bring up in the lpass + * 200 Milliseconds sufficient for DSP bring up in the lpass * after Sub System Restart */ -#define ADSP_STATE_READY_TIMEOUT_MS 50 +#define ADSP_STATE_READY_TIMEOUT_MS 200 #define EAR_PMD 0 #define EAR_PMU 1 -- GitLab From 7be67e5fba5223e2ec40a34dad81ccefab2d67a3 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 12 Oct 2017 09:14:03 +0530 Subject: [PATCH 0082/1645] ASoC: wcd: set analog gain mode to manual when compander is off If compander DRE isn't turned on, ensure analog gain mode is set to manual mode. This also resolves low volume at one channel. CRs-Fixed: 2102126 Change-Id: Id29b7055fe4f7fa7b3853c26770df38d10539d8c Signed-off-by: Vatsal Bucha --- asoc/codecs/sdm660_cdc/msm-analog-cdc.c | 13 +++++++++++++ asoc/codecs/sdm660_cdc/msm-analog-cdc.h | 1 + asoc/codecs/sdm660_cdc/msm-digital-cdc.c | 7 +++++++ asoc/codecs/sdm660_cdc/msm-digital-cdc.h | 2 ++ 4 files changed, 23 insertions(+) diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c index 623303c3adca..c292b9116f50 100644 --- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c @@ -2620,6 +2620,18 @@ static int msm_anlg_cdc_codec_enable_micbias(struct snd_soc_dapm_widget *w, return 0; } +static void set_compander_mode(void *handle, int val) +{ + struct sdm660_cdc_priv *handle_cdc = handle; + struct snd_soc_codec *codec = handle_cdc->codec; + + if (get_codec_version(handle_cdc) >= DIANGU) { + snd_soc_update_bits(codec, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, + 0x08, val); + }; +} + static void update_clkdiv(void *handle, int val) { struct sdm660_cdc_priv *handle_cdc = handle; @@ -4653,6 +4665,7 @@ static int msm_anlg_cdc_probe(struct platform_device *pdev) BLOCKING_INIT_NOTIFIER_HEAD(&sdm660_cdc->notifier_mbhc); sdm660_cdc->dig_plat_data.handle = (void *) sdm660_cdc; + sdm660_cdc->dig_plat_data.set_compander_mode = set_compander_mode; sdm660_cdc->dig_plat_data.update_clkdiv = update_clkdiv; sdm660_cdc->dig_plat_data.get_cdc_version = get_cdc_version; sdm660_cdc->dig_plat_data.register_notifier = diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.h b/asoc/codecs/sdm660_cdc/msm-analog-cdc.h index 9591487b57b8..3ee3dee743d5 100644 --- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.h +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.h @@ -168,6 +168,7 @@ struct msm_dig_ctrl_data { struct msm_dig_ctrl_platform_data { void *handle; + void (*set_compander_mode)(void *handle, int val); void (*update_clkdiv)(void *handle, int val); int (*get_cdc_version)(void *handle); int (*register_notifier)(void *handle, diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c index 4ab203750303..00a969935d1a 100644 --- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -231,6 +231,12 @@ static int msm_dig_cdc_codec_config_compander(struct snd_soc_codec *codec, } if (SND_SOC_DAPM_EVENT_ON(event)) { + /* compander is not enabled */ + if (!dig_cdc->comp_enabled[interp_n]) { + dig_cdc->set_compander_mode(dig_cdc->handle, 0x00); + return 0; + }; + dig_cdc->set_compander_mode(dig_cdc->handle, 0x08); /* Enable Compander Clock */ snd_soc_update_bits(codec, MSM89XX_CDC_CORE_COMP0_B2_CTL, 0x0F, 0x09); @@ -2080,6 +2086,7 @@ static int msm_dig_cdc_probe(struct platform_device *pdev) msm_dig_cdc->dig_base, &msm_digital_regmap_config); msm_dig_cdc->update_clkdiv = pdata->update_clkdiv; + msm_dig_cdc->set_compander_mode = pdata->set_compander_mode; msm_dig_cdc->get_cdc_version = pdata->get_cdc_version; msm_dig_cdc->handle = pdata->handle; msm_dig_cdc->register_notifier = pdata->register_notifier; diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.h b/asoc/codecs/sdm660_cdc/msm-digital-cdc.h index cb6cfe2f538e..7abb2045b79c 100644 --- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.h +++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.h @@ -55,6 +55,7 @@ struct msm_dig_priv { u32 mute_mask; int dapm_bias_off; void *handle; + void (*set_compander_mode)(void *handle, int val); void (*update_clkdiv)(void *handle, int val); int (*get_cdc_version)(void *handle); int (*register_notifier)(void *handle, @@ -65,6 +66,7 @@ struct msm_dig_priv { struct dig_ctrl_platform_data { void *handle; + void (*set_compander_mode)(void *handle, int val); void (*update_clkdiv)(void *handle, int val); int (*get_cdc_version)(void *handle); int (*register_notifier)(void *handle, -- GitLab From a868bb9d140088d3b77a2395b97793ac4ce5ffd6 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 12 Oct 2017 08:24:04 +0530 Subject: [PATCH 0083/1645] ASoC: codecs: sdm660_cdc: Fix HPH CnP issue on sdm660-internal Pop is observed after start playback on hph. This is because both compander channels are not enabled at the same time which differs from ideal sequence. Amplitude of pop gets reduced after corresponding change is made. CRs-Fixed: 2101404 Change-Id: Iba2b8a809fd3b53f0c180ce28ac5668d7635fb24 Signed-off-by: Vatsal Bucha --- asoc/codecs/sdm660_cdc/msm-digital-cdc.c | 32 +++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c index 00a969935d1a..4b875ccec969 100644 --- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -217,6 +217,7 @@ static int msm_dig_cdc_codec_config_compander(struct snd_soc_codec *codec, { struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec); int comp_ch_bits_set = 0x03; + int comp_ch_value; dev_dbg(codec->dev, "%s: event %d shift %d, enabled %d\n", __func__, event, interp_n, @@ -236,15 +237,40 @@ static int msm_dig_cdc_codec_config_compander(struct snd_soc_codec *codec, dig_cdc->set_compander_mode(dig_cdc->handle, 0x00); return 0; }; + comp_ch_value = snd_soc_read(codec, + MSM89XX_CDC_CORE_COMP0_B1_CTL); + if (interp_n == 0) { + if (comp_ch_value & 0x02) { + dev_dbg(codec->dev, + "%s comp ch 1 already enabled\n", + __func__); + return 0; + } + } + if (interp_n == 1) { + if (comp_ch_value & 0x01) { + dev_dbg(codec->dev, + "%s comp ch 0 already enabled\n", + __func__); + return 0; + } + } dig_cdc->set_compander_mode(dig_cdc->handle, 0x08); /* Enable Compander Clock */ snd_soc_update_bits(codec, MSM89XX_CDC_CORE_COMP0_B2_CTL, 0x0F, 0x09); snd_soc_update_bits(codec, MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x01, 0x01); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B1_CTL, - 1 << interp_n, 1 << interp_n); + if (dig_cdc->comp_enabled[MSM89XX_RX1]) { + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B1_CTL, + 0x02, 0x02); + } + if (dig_cdc->comp_enabled[MSM89XX_RX2]) { + snd_soc_update_bits(codec, + MSM89XX_CDC_CORE_COMP0_B1_CTL, + 0x01, 0x01); + } snd_soc_update_bits(codec, MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x01); snd_soc_update_bits(codec, -- GitLab From d4d03c03ef6f9369100ad8442e2b354bd9223028 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 11 Oct 2017 20:03:20 +0530 Subject: [PATCH 0084/1645] ASoC: codecs: sdm660_cdc: Remove lb_mode mixer var from sdm660 lb_mode var is redundant for sdm660_cdc. Loopback works fine without this var also. CRs-Fixed: 2101423 Change-Id: I727da02660a0f1d6ee5582fc2f2c0a8f6cd59bc1 Signed-off-by: Vatsal Bucha --- asoc/codecs/sdm660_cdc/msm-analog-cdc.c | 46 ------------------------- 1 file changed, 46 deletions(-) diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c index 623303c3adca..db09290577b0 100644 --- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c @@ -1579,43 +1579,6 @@ static int msm_anlg_cdc_ear_pa_boost_set(struct snd_kcontrol *kcontrol, return 0; } -static int msm_anlg_cdc_loopback_mode_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct msm_asoc_mach_data *pdata = NULL; - - pdata = snd_soc_card_get_drvdata(codec->component.card); - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - return pdata->lb_mode; -} - -static int msm_anlg_cdc_loopback_mode_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct msm_asoc_mach_data *pdata = NULL; - - pdata = snd_soc_card_get_drvdata(codec->component.card); - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - switch (ucontrol->value.integer.value[0]) { - case 0: - pdata->lb_mode = false; - break; - case 1: - pdata->lb_mode = true; - break; - default: - return -EINVAL; - } - - return 0; -} - static int msm_anlg_cdc_pa_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1910,13 +1873,6 @@ static int msm_anlg_cdc_ext_spk_boost_set(struct snd_kcontrol *kcontrol, return 0; } - -static const char * const msm_anlg_cdc_loopback_mode_ctrl_text[] = { - "DISABLE", "ENABLE"}; -static const struct soc_enum msm_anlg_cdc_loopback_mode_ctl_enum[] = { - SOC_ENUM_SINGLE_EXT(2, msm_anlg_cdc_loopback_mode_ctrl_text), -}; - static const char * const msm_anlg_cdc_ear_pa_boost_ctrl_text[] = { "DISABLE", "ENABLE"}; static const struct soc_enum msm_anlg_cdc_ear_pa_boost_ctl_enum[] = { @@ -1980,8 +1936,6 @@ static const struct snd_kcontrol_new msm_anlg_cdc_snd_controls[] = { SOC_ENUM_EXT("Ext Spk Boost", msm_anlg_cdc_ext_spk_boost_ctl_enum[0], msm_anlg_cdc_ext_spk_boost_get, msm_anlg_cdc_ext_spk_boost_set), - SOC_ENUM_EXT("LOOPBACK Mode", msm_anlg_cdc_loopback_mode_ctl_enum[0], - msm_anlg_cdc_loopback_mode_get, msm_anlg_cdc_loopback_mode_put), SOC_SINGLE_TLV("ADC1 Volume", MSM89XX_PMIC_ANALOG_TX_1_EN, 3, 8, 0, analog_gain), SOC_SINGLE_TLV("ADC2 Volume", MSM89XX_PMIC_ANALOG_TX_2_EN, 3, -- GitLab From 6bb3a96984c19c3007ef54d75c5e5e1e228a1c99 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 9 Nov 2017 12:51:13 +0530 Subject: [PATCH 0085/1645] ASoC: Add support for qcs605 for dlkm Update make files to extend dlkm support for qcs605 Change-Id: Icf736fb66ca12966f4c6cd72bb906eb32899868a Signed-off-by: Laxminath Kasam --- Android.mk | 4 ++-- asoc/Android.mk | 6 +++--- asoc/codecs/Android.mk | 8 ++++---- asoc/codecs/msm_sdw/Android.mk | 2 +- asoc/codecs/sdm660_cdc/Android.mk | 2 +- asoc/codecs/wcd934x/Android.mk | 4 ++-- dsp/Android.mk | 4 ++-- dsp/codecs/Android.mk | 4 ++-- ipc/Android.mk | 4 ++-- soc/Android.mk | 6 +++--- 10 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Android.mk b/Android.mk index a7341e330017..18e9263f1cc4 100644 --- a/Android.mk +++ b/Android.mk @@ -3,7 +3,7 @@ MY_LOCAL_PATH := $(call my-dir) UAPI_OUT := $(OUT)/obj/vendor/qcom/opensource/audio-kernel/include -ifeq ($(call is-board-platform-in-list,sdm845 sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) $(shell mkdir -p $(UAPI_OUT)/linux;) $(shell mkdir -p $(UAPI_OUT)/sound;) @@ -16,7 +16,7 @@ include $(MY_LOCAL_PATH)/asoc/codecs/Android.mk include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk endif -ifeq ($(call is-board-platform,sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) include $(MY_LOCAL_PATH)/asoc/codecs/sdm660_cdc/Android.mk include $(MY_LOCAL_PATH)/asoc/codecs/msm_sdw/Android.mk endif diff --git a/asoc/Android.mk b/asoc/Android.mk index 9497ae9f08ee..73b17d3dea54 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -8,14 +8,14 @@ TARGET := sdm845 AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m endif -ifeq ($(call is-board-platform,sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) TARGET := sdm670 AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm845 sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) LOCAL_PATH := $(call my-dir) @@ -50,7 +50,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### -ifeq ($(call is-board-platform,sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_cpe_lsm.ko LOCAL_MODULE_KBUILD_NAME := cpe_lsm_dlkm.ko diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index 863da5a59735..24bf2f837dd5 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -7,13 +7,13 @@ ifeq ($(call is-board-platform,sdm845),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m endif -ifeq ($(call is-board-platform,sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm845 sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) LOCAL_PATH := $(call my-dir) @@ -56,7 +56,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### -ifeq ($(call is-board-platform,sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd_cpe.ko LOCAL_MODULE_KBUILD_NAME := wcd_cpe_dlkm.ko @@ -74,7 +74,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### -ifeq ($(call is-board-platform,sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd9335.ko LOCAL_MODULE_KBUILD_NAME := wcd9335_dlkm.ko diff --git a/asoc/codecs/msm_sdw/Android.mk b/asoc/codecs/msm_sdw/Android.mk index 421420b84899..dc6cd27b29d9 100644 --- a/asoc/codecs/msm_sdw/Android.mk +++ b/asoc/codecs/msm_sdw/Android.mk @@ -4,7 +4,7 @@ AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform,sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/sdm660_cdc/Android.mk b/asoc/codecs/sdm660_cdc/Android.mk index f322a65562f4..5a7878c4b03c 100644 --- a/asoc/codecs/sdm660_cdc/Android.mk +++ b/asoc/codecs/sdm660_cdc/Android.mk @@ -4,7 +4,7 @@ AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform,sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wcd934x/Android.mk b/asoc/codecs/wcd934x/Android.mk index 627d04f2cc0f..9cb8ec28e6a9 100644 --- a/asoc/codecs/wcd934x/Android.mk +++ b/asoc/codecs/wcd934x/Android.mk @@ -7,13 +7,13 @@ ifeq ($(call is-board-platform,sdm845),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m endif -ifeq ($(call is-board-platform,sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm845 sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/Android.mk b/dsp/Android.mk index 428901cac75a..4883ab4b2885 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -7,13 +7,13 @@ ifeq ($(call is-board-platform,sdm845),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m endif -ifeq ($(call is-board-platform,sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm845 sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/codecs/Android.mk b/dsp/codecs/Android.mk index 865ace12cb00..020d7998a889 100644 --- a/dsp/codecs/Android.mk +++ b/dsp/codecs/Android.mk @@ -7,13 +7,13 @@ ifeq ($(call is-board-platform,sdm845),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m endif -ifeq ($(call is-board-platform,sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm845 sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) LOCAL_PATH := $(call my-dir) diff --git a/ipc/Android.mk b/ipc/Android.mk index 8032374311ae..d72f68a9e926 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -7,13 +7,13 @@ ifeq ($(call is-board-platform,sdm845),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m endif -ifeq ($(call is-board-platform,sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm845 sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) LOCAL_PATH := $(call my-dir) diff --git a/soc/Android.mk b/soc/Android.mk index e5ec9aa22208..4a18e108e42c 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -7,13 +7,13 @@ ifeq ($(call is-board-platform,sdm845),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m endif -ifeq ($(call is-board-platform,sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm845 sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) LOCAL_PATH := $(call my-dir) @@ -40,7 +40,7 @@ KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) KBUILD_OPTIONS += $(AUDIO_SELECT) ########################################################### -ifeq ($(call is-board-platform,sdm670),true) +ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_lpi.ko LOCAL_MODULE_KBUILD_NAME := pinctrl_lpi_dlkm.ko -- GitLab From f6853a20103634a18044d8c38e9769e66d9f01d4 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Tue, 31 Oct 2017 18:44:16 -0700 Subject: [PATCH 0086/1645] ASoC: sdm845: fix clock refcount for MI2S/AUXPCM shutdown For MI2S and AUXPCM shutdown, if clock disable is failed, do not bother to re-increment clock reference. Otherwise, next time when startup is called, clock enable will not be called again, so use case will not work. Change-Id: I5ce4590d2a2030f9d00f1dba9577396f7685a87b Signed-off-by: Banajit Goswami Signed-off-by: Xiaoyu Ye --- asoc/sdm845.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/asoc/sdm845.c b/asoc/sdm845.c index f8c044401617..ed854e217ea2 100644 --- a/asoc/sdm845.c +++ b/asoc/sdm845.c @@ -4153,7 +4153,6 @@ static void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream) dev_err(rtd->card->dev, "%s lpaif_tert_muxsel_virt_addr is NULL\n", __func__); - auxpcm_intf_conf[index].ref_cnt++; } } mutex_unlock(&auxpcm_intf_conf[index].lock); @@ -4715,11 +4714,9 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) mutex_lock(&mi2s_intf_conf[index].lock); if (--mi2s_intf_conf[index].ref_cnt == 0) { ret = msm_mi2s_set_sclk(substream, false); - if (ret < 0) { + if (ret < 0) pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", __func__, index, ret); - mi2s_intf_conf[index].ref_cnt++; - } } mutex_unlock(&mi2s_intf_conf[index].lock); -- GitLab From f415b42910dd24502142f5d976994a75c127798c Mon Sep 17 00:00:00 2001 From: Tanya Dixit Date: Wed, 1 Nov 2017 12:41:24 +0530 Subject: [PATCH 0087/1645] dsp: add mutex unlock to properly release lock Add mutex unlock in function audio_effects_shared_ioctl at appropriate place to prevent use after free. CRs-Fixed: 2123291 Change-Id: Ie0d321dc8cc20a295d102a44faea7e5710834932 Signed-off-by: Tanya Dixit --- dsp/codecs/audio_hwacc_effects.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dsp/codecs/audio_hwacc_effects.c b/dsp/codecs/audio_hwacc_effects.c index c285511d3bfc..cd54b90cf338 100644 --- a/dsp/codecs/audio_hwacc_effects.c +++ b/dsp/codecs/audio_hwacc_effects.c @@ -161,7 +161,6 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned int cmd, pr_err("%s: Read buffer Allocation failed rc = %d\n", __func__, rc); rc = -ENOMEM; - mutex_unlock(&effects->lock); goto readbuf_fail; } atomic_set(&effects->out_count, effects->config.output.num_buf); @@ -176,7 +175,6 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned int cmd, if (rc < 0) { pr_err("%s: pcm read block config failed\n", __func__); rc = -EINVAL; - mutex_unlock(&effects->lock); goto cfg_fail; } pr_debug("%s: dec: sample_rate: %d, num_channels: %d, bit_width: %d\n", @@ -191,7 +189,6 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned int cmd, pr_err("%s: pcm write format block config failed\n", __func__); rc = -EINVAL; - mutex_unlock(&effects->lock); goto cfg_fail; } @@ -325,6 +322,7 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned int cmd, readbuf_fail: q6asm_audio_client_buf_free_contiguous(IN, effects->ac); + mutex_unlock(&effects->lock); return rc; cfg_fail: q6asm_audio_client_buf_free_contiguous(IN, @@ -332,6 +330,7 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned int cmd, q6asm_audio_client_buf_free_contiguous(OUT, effects->ac); effects->buf_alloc = 0; + mutex_unlock(&effects->lock); return rc; } -- GitLab From 1b70f5b02ddc6014e1dbd3dc9fac55595a8934c1 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 23 Oct 2017 16:17:49 +0530 Subject: [PATCH 0088/1645] ASoC: wcd: Fix pop noise when device switch Pop is observed during switch from playback in native mode to voice call and vice-versa. This is resolved by mclk reset to non-native mode before hph path powers up. CRs-Fixed: 2117960 Change-Id: Ic554c3b2af24dac3ae94b5a239559e5d11e98271 Signed-off-by: Vatsal Bucha --- asoc/codecs/sdm660_cdc/msm-digital-cdc.c | 6 +++ asoc/sdm660-common.h | 3 ++ asoc/sdm660-internal.c | 52 +++++++++--------------- 3 files changed, 29 insertions(+), 32 deletions(-) diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c index 4ab203750303..49a5e1a041d8 100644 --- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -84,6 +84,12 @@ static int msm_digcdc_clock_control(bool flag) if (flag) { mutex_lock(&pdata->cdc_int_mclk0_mutex); if (atomic_read(&pdata->int_mclk0_enabled) == false) { + if (pdata->native_clk_set) + pdata->digital_cdc_core_clk.clk_freq_in_hz = + NATIVE_MCLK_RATE; + else + pdata->digital_cdc_core_clk.clk_freq_in_hz = + DEFAULT_MCLK_RATE; pdata->digital_cdc_core_clk.enable = 1; ret = afe_set_lpass_clock_v2( AFE_PORT_ID_INT0_MI2S_RX, diff --git a/asoc/sdm660-common.h b/asoc/sdm660-common.h index 2c8e29e8792f..030f5219a963 100644 --- a/asoc/sdm660-common.h +++ b/asoc/sdm660-common.h @@ -17,6 +17,9 @@ #include #include "codecs/wcd-mbhc-v2.h" +#define DEFAULT_MCLK_RATE 9600000 +#define NATIVE_MCLK_RATE 11289600 + #define SAMPLING_RATE_8KHZ 8000 #define SAMPLING_RATE_11P025KHZ 11025 #define SAMPLING_RATE_16KHZ 16000 diff --git a/asoc/sdm660-internal.c b/asoc/sdm660-internal.c index 20e49bcb1b44..68e6685de47b 100644 --- a/asoc/sdm660-internal.c +++ b/asoc/sdm660-internal.c @@ -24,9 +24,6 @@ #define __CHIPSET__ "SDM660 " #define MSM_DAILINK_NAME(name) (__CHIPSET__#name) -#define DEFAULT_MCLK_RATE 9600000 -#define NATIVE_MCLK_RATE 11289600 - #define WCD_MBHC_DEF_RLOADS 5 #define WCN_CDC_SLIM_RX_CH_MAX 2 @@ -439,7 +436,7 @@ static int int_mi2s_ch_put(struct snd_kcontrol *kcontrol, static const struct snd_soc_dapm_widget msm_int_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY_S("INT_MCLK0", -1, SND_SOC_NOPM, 0, 0, - msm_int_mclk0_event, SND_SOC_DAPM_POST_PMD), + msm_int_mclk0_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MIC("Handset Mic", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_MIC("Secondary Mic", NULL), @@ -730,6 +727,8 @@ static int msm_int_enable_dig_cdc_clk(struct snd_soc_codec *codec, cancel_delayed_work_sync(&pdata->disable_int_mclk0_work); mutex_lock(&pdata->cdc_int_mclk0_mutex); if (atomic_read(&pdata->int_mclk0_enabled) == true) { + pdata->digital_cdc_core_clk.clk_freq_in_hz = + DEFAULT_MCLK_RATE; pdata->digital_cdc_core_clk.enable = 0; ret = afe_set_lpass_clock_v2( AFE_PORT_ID_INT0_MI2S_RX, @@ -738,6 +737,7 @@ static int msm_int_enable_dig_cdc_clk(struct snd_soc_codec *codec, pr_err("%s: failed to disable CCLK\n", __func__); atomic_set(&pdata->int_mclk0_enabled, false); + atomic_set(&pdata->int_mclk0_rsc_ref, 0); } mutex_unlock(&pdata->cdc_int_mclk0_mutex); } @@ -959,6 +959,16 @@ static int msm_int_mclk0_event(struct snd_soc_dapm_widget *w, pdata = snd_soc_card_get_drvdata(codec->component.card); pr_debug("%s: event = %d\n", __func__, event); switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = msm_cdc_pinctrl_select_active_state(pdata->pdm_gpio_p); + if (ret < 0) { + pr_err("%s: gpio set cannot be activated %s\n", + __func__, "int_pdm"); + return ret; + } + msm_int_enable_dig_cdc_clk(codec, 1, true); + msm_anlg_cdc_mclk_enable(codec, 1, true); + break; case SND_SOC_DAPM_POST_PMD: pr_debug("%s: mclk_res_ref = %d\n", __func__, atomic_read(&pdata->int_mclk0_rsc_ref)); @@ -968,12 +978,10 @@ static int msm_int_mclk0_event(struct snd_soc_dapm_widget *w, __func__, "int_pdm"); return ret; } - if (atomic_read(&pdata->int_mclk0_rsc_ref) == 0) { - pr_debug("%s: disabling MCLK\n", __func__); - /* disable the codec mclk config*/ - msm_anlg_cdc_mclk_enable(codec, 0, true); - msm_int_enable_dig_cdc_clk(codec, 0, true); - } + pr_debug("%s: disabling MCLK\n", __func__); + /* disable the codec mclk config*/ + msm_anlg_cdc_mclk_enable(codec, 0, true); + msm_int_enable_dig_cdc_clk(codec, 0, true); break; default: pr_err("%s: invalid DAPM event %d\n", __func__, event); @@ -1158,19 +1166,6 @@ static int msm_int_mi2s_snd_startup(struct snd_pcm_substream *substream) __func__, ret); return ret; } - ret = msm_int_enable_dig_cdc_clk(codec, 1, true); - if (ret < 0) { - pr_err("failed to enable mclk\n"); - return ret; - } - /* Enable the codec mclk config */ - ret = msm_cdc_pinctrl_select_active_state(pdata->pdm_gpio_p); - if (ret < 0) { - pr_err("%s: gpio set cannot be activated %s\n", - __func__, "int_pdm"); - return ret; - } - msm_anlg_cdc_mclk_enable(codec, 1, true); ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) pr_err("%s: set fmt cpu dai failed; ret=%d\n", __func__, ret); @@ -1181,9 +1176,6 @@ static int msm_int_mi2s_snd_startup(struct snd_pcm_substream *substream) static void msm_int_mi2s_snd_shutdown(struct snd_pcm_substream *substream) { int ret; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_card *card = rtd->card; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); @@ -1192,12 +1184,6 @@ static void msm_int_mi2s_snd_shutdown(struct snd_pcm_substream *substream) if (ret < 0) pr_err("%s:clock disable failed; ret=%d\n", __func__, ret); - if (atomic_read(&pdata->int_mclk0_rsc_ref) > 0) { - atomic_dec(&pdata->int_mclk0_rsc_ref); - pr_debug("%s: decrementing mclk_res_ref %d\n", - __func__, - atomic_read(&pdata->int_mclk0_rsc_ref)); - } } static void *def_msm_int_wcd_mbhc_cal(void) @@ -3070,6 +3056,8 @@ static void msm_disable_int_mclk0(struct work_struct *work) && atomic_read(&pdata->int_mclk0_rsc_ref) == 0) { pr_debug("Disable the mclk\n"); pdata->digital_cdc_core_clk.enable = 0; + pdata->digital_cdc_core_clk.clk_freq_in_hz = + DEFAULT_MCLK_RATE; ret = afe_set_lpass_clock_v2( AFE_PORT_ID_INT0_MI2S_RX, &pdata->digital_cdc_core_clk); -- GitLab From afb4161307243214f91a0da2a6d1fb68f4c33a3a Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Tue, 3 Oct 2017 18:26:08 -0700 Subject: [PATCH 0089/1645] ASoC: sdxpoorwills: enable audio compilation Enable compilation of audio drivers for SDXPOORWILLS. Change-Id: I2a8d949f98ab6fb56111dffdab51d9123a41c3c1 Signed-off-by: Xiaoyu Ye --- Makefile | 9 +++++++- config/sdxpoorwillsauto.conf | 29 ++++++++++++++++++++++++ config/sdxpoorwillsautoconf.h | 42 +++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 config/sdxpoorwillsauto.conf create mode 100644 config/sdxpoorwillsautoconf.h diff --git a/Makefile b/Makefile index ff83693730d3..de65a18f0478 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,10 @@ ifeq ($(CONFIG_ARCH_SDM670), y) include $(srctree)/techpack/audio/config/sdm670auto.conf export endif +ifeq ($(CONFIG_ARCH_SDXPOORWILLS), y) +include $(srctree)/techpack/audio/config/sdxpoorwillsauto.conf +export +endif # Use USERINCLUDE when you must reference the UAPI directories only. USERINCLUDE += \ @@ -26,7 +30,10 @@ ifeq ($(CONFIG_ARCH_SDM670), y) LINUXINCLUDE += \ -include $(srctree)/techpack/audio/config/sdm670autoconf.h endif - +ifeq ($(CONFIG_ARCH_SDXPOORWILLS), y) +LINUXINCLUDE += \ + -include $(srctree)/techpack/audio/config/sdxpoorwillsautoconf.h +endif obj-y += asoc/ obj-y += dsp/ diff --git a/config/sdxpoorwillsauto.conf b/config/sdxpoorwillsauto.conf new file mode 100644 index 000000000000..d9dd081e876a --- /dev/null +++ b/config/sdxpoorwillsauto.conf @@ -0,0 +1,29 @@ +CONFIG_PINCTRL_WCD=y +CONFIG_SND_SOC_WCD934X=y +CONFIG_AUDIO_EXT_CLK=y +CONFIG_SND_SOC_WCD9XXX_V2=y +CONFIG_SND_SOC_WCD_MBHC=y +CONFIG_SND_SOC_WSA881X=y +CONFIG_SND_SOC_WCD_DSP_MGR=y +CONFIG_SND_SOC_WCD934X=y +CONFIG_SND_SOC_WCD934X_MBHC=y +CONFIG_SND_SOC_WCD934X_DSD=y +CONFIG_MSM_QDSP6V2_CODECS=y +CONFIG_MSM_QDSP6_APRV3_GLINK=y +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y +CONFIG_MSM_ADSP_LOADER=y +CONFIG_REGMAP_SWR=y +CONFIG_SND_SOC_MSM_HOSTLESS_PCM=y +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y +CONFIG_SND_SOC_POORWILLS=y +CONFIG_SOUNDWIRE=y +CONFIG_SOUNDWIRE_WCD_CTRL=y +CONFIG_SND_SOC_QDSP6V2=y +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y +CONFIG_MSM_CDC_PINCTRL=y +CONFIG_WCD9XXX_CODEC_CORE=y +CONFIG_SND_SOC_WCD_MBHC_ADC=y +CONFIG_QTI_PP=y +CONFIG_SND_HWDEP=y +CONFIG_SND_SOC_MACHINE_SDXPOORWILLS=y +CONFIG_SND_SOC_MSM_STUB=y diff --git a/config/sdxpoorwillsautoconf.h b/config/sdxpoorwillsautoconf.h new file mode 100644 index 000000000000..9fc6258fe1b3 --- /dev/null +++ b/config/sdxpoorwillsautoconf.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define CONFIG_PINCTRL_WCD 1 +#define CONFIG_SND_SOC_WCD934X 1 +#define CONFIG_AUDIO_EXT_CLK 1 +#define CONFIG_SND_SOC_WCD9XXX_V2 1 +#define CONFIG_SND_SOC_WCD_MBHC 1 +#define CONFIG_SND_SOC_WSA881X 1 +#define CONFIG_SND_SOC_WCD_DSP_MGR 1 +#define CONFIG_SND_SOC_WCD934X 1 +#define CONFIG_SND_SOC_WCD934X_MBHC 1 +#define CONFIG_SND_SOC_WCD934X_DSD 1 +#define CONFIG_MSM_QDSP6V2_CODECS 1 +#define CONFIG_MSM_QDSP6_APRV3_GLINK 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_MSM_ADSP_LOADER 1 +#define CONFIG_REGMAP_SWR 1 +#define CONFIG_SND_SOC_MSM_HOSTLESS_PCM 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_SND_SOC_POORWILLS 1 +#define CONFIG_SOUNDWIRE 1 +#define CONFIG_SOUNDWIRE_WCD_CTRL 1 +#define CONFIG_SND_SOC_QDSP6V2 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_MSM_CDC_PINCTRL 1 +#define CONFIG_WCD9XXX_CODEC_CORE 1 +#define CONFIG_SND_SOC_WCD_MBHC_ADC 1 +#define CONFIG_QTI_PP 1 +#define CONFIG_SND_HWDEP 1 +#define CONFIG_SND_SOC_MACHINE_SDXPOORWILLS 1 +#define CONFIG_SND_SOC_MSM_STUB 1 -- GitLab From a87e56ddf26974829423496a3865101c4e0e720a Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Wed, 25 Oct 2017 22:59:48 -0700 Subject: [PATCH 0090/1645] dsp: sdxpoorwills: fix compilation issue Variable 'vm_page_prot' has different types in different ARM platforms. Using macro "pgprot_val" to handle it to fix compilation issue for sdxpoorwills targets. Change-Id: Ic7b8de9860759cc56812e7a3ffb1aaea2b6779f9 Signed-off-by: Xiaoyu Ye --- dsp/msm_audio_ion.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index 0baca8dd5470..ca9505f02f6a 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -346,7 +346,7 @@ int msm_audio_ion_mmap(struct audio_buffer *ab, vma, (unsigned int)addr, len, (unsigned int)vma->vm_start, (unsigned int)vma->vm_end, - (unsigned long)vma->vm_page_prot.pgprot); + (unsigned long)pgprot_val(vma->vm_page_prot)); remap_pfn_range(vma, addr, page_to_pfn(page), len, vma->vm_page_prot); addr += len; @@ -369,7 +369,7 @@ int msm_audio_ion_mmap(struct audio_buffer *ab, pr_debug("vma=%pK, vm_start=%x vm_end=%x vm_pgoff=%ld vm_page_prot=%lu\n", vma, (unsigned int)vma->vm_start, (unsigned int)vma->vm_end, vma->vm_pgoff, - (unsigned long)vma->vm_page_prot.pgprot); + (unsigned long)pgprot_val(vma->vm_page_prot)); va_len = vma->vm_end - vma->vm_start; if ((offset > phys_len) || (va_len > phys_len-offset)) { pr_err("wrong offset size %ld, lens= %zd, va_len=%zd\n", -- GitLab From 0527c56a87864046b522db23aede796cfee1abd4 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 4 Oct 2017 20:38:49 +0530 Subject: [PATCH 0091/1645] ASoC: Remove excess logs in compress driver Excess logs are printed in msm_compr_pointer during ADSP SSR. This causes failure of some interrupts to occur which results in SSR failure. Logs can be reduced by applying ratelimit. CRs-Fixed: 2128011 Change-Id: I0d3d82bf52ea307cdf719f97c4907a2d376580c1 Signed-off-by: Vatsal Bucha --- asoc/msm-compress-q6-v2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index b30c42438ae9..1df13afd82f6 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -2610,8 +2610,8 @@ static int msm_compr_pointer(struct snd_compr_stream *cstream, tstamp.copied_total = prtd->received_total; first_buffer = prtd->first_buffer; if (atomic_read(&prtd->error)) { - pr_err("%s Got RESET EVENTS notification, return error\n", - __func__); + pr_err_ratelimited("%s Got RESET EVENTS notification, return error\n", + __func__); if (cstream->direction == SND_COMPRESS_PLAYBACK) runtime->total_bytes_transferred = tstamp.copied_total; else -- GitLab From 8a60b82da9123b939698598e941657b806cec3d1 Mon Sep 17 00:00:00 2001 From: kunleiz Date: Wed, 11 Oct 2017 15:04:02 +0800 Subject: [PATCH 0092/1645] ASoC: msm: qdsp6v2: Remove unused FE DAIs Clean up unused FE DAIs and remove duplicate routings from dapm routing map for MI2S_RX_VOICE Mixer. CRs-Fixed: 2001153 Change-Id: I2c9bd1255331d83b1901915259fe61d287f682fc Signed-off-by: kunleiz --- asoc/msm-dai-fe.c | 127 --------- asoc/msm-pcm-routing-v2.c | 586 +------------------------------------- asoc/msm-pcm-routing-v2.h | 4 - asoc/msm-qti-pp-config.c | 2 +- 4 files changed, 2 insertions(+), 717 deletions(-) diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index c988eeec2c40..9160a2d728b4 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -154,31 +154,6 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "MultiMedia2", .probe = fe_dai_probe, }, - { - .playback = { - .stream_name = "CS-VOICE Playback", - .aif_name = "CS-VOICE_DL1", - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .channels_min = 1, - .channels_max = 2, - .rate_min = 8000, - .rate_max = 48000, - }, - .capture = { - .stream_name = "CS-VOICE Capture", - .aif_name = "CS-VOICE_UL1", - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .channels_min = 1, - .channels_max = 2, - .rate_min = 8000, - .rate_max = 48000, - }, - .ops = &msm_fe_dai_ops, - .name = "CS-VOICE", - .probe = fe_dai_probe, - }, { .playback = { .stream_name = "VoIP Playback", @@ -746,31 +721,6 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "VOICE_STUB", .probe = fe_dai_probe, }, - { - .playback = { - .stream_name = "VoLTE Playback", - .aif_name = "VoLTE_DL", - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .channels_min = 1, - .channels_max = 2, - .rate_min = 8000, - .rate_max = 48000, - }, - .capture = { - .stream_name = "VoLTE Capture", - .aif_name = "VoLTE_UL", - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .channels_min = 1, - .channels_max = 2, - .rate_min = 8000, - .rate_max = 48000, - }, - .ops = &msm_fe_dai_ops, - .name = "VoLTE", - .probe = fe_dai_probe, - }, { .playback = { .stream_name = "MI2S_RX_HOSTLESS Playback", @@ -2013,58 +1963,6 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "QUAT_TDM_RX_7_HOSTLESS", .probe = fe_dai_probe, }, - { - .playback = { - .stream_name = "Voice2 Playback", - .aif_name = "VOICE2_DL", - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .channels_min = 1, - .channels_max = 2, - .rate_min = 8000, - .rate_max = 48000, - }, - .capture = { - .stream_name = "Voice2 Capture", - .aif_name = "VOICE2_UL", - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .channels_min = 1, - .channels_max = 2, - .rate_min = 8000, - .rate_max = 48000, - }, - .ops = &msm_fe_dai_ops, - .name = "Voice2", - .probe = fe_dai_probe, - }, - { - .playback = { - .stream_name = "Pseudo Playback", - .aif_name = "MM_DL9", - .rates = (SNDRV_PCM_RATE_8000_48000 | - SNDRV_PCM_RATE_KNOT), - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .channels_min = 1, - .channels_max = 8, - .rate_min = 8000, - .rate_max = 48000, - }, - .capture = { - .stream_name = "Pseudo Capture", - .aif_name = "MM_UL9", - .rates = (SNDRV_PCM_RATE_8000_48000| - SNDRV_PCM_RATE_KNOT), - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .channels_min = 1, - .channels_max = 8, - .rate_min = 8000, - .rate_max = 48000, - }, - .ops = &msm_fe_Multimedia_dai_ops, - .name = "Pseudo", - .probe = fe_dai_probe, - }, { .playback = { .stream_name = "DTMF_RX_HOSTLESS Playback", @@ -2335,31 +2233,6 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "LSM8", .probe = fe_dai_probe, }, - { - .playback = { - .stream_name = "VoWLAN Playback", - .aif_name = "VoWLAN_DL", - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .channels_min = 1, - .channels_max = 2, - .rate_min = 8000, - .rate_max = 48000, - }, - .capture = { - .stream_name = "VoWLAN Capture", - .aif_name = "VoWLAN_UL", - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .channels_min = 1, - .channels_max = 2, - .rate_min = 8000, - .rate_max = 48000, - }, - .ops = &msm_fe_dai_ops, - .name = "VoWLAN", - .probe = fe_dai_probe, - }, /* FE DAIs created for multiple instances of offload playback */ { .playback = { diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 965518bdae33..0aed70c4b522 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -643,9 +643,6 @@ static struct msm_pcm_routing_fdai_data {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, /* MULTIMEDIA20 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, - /* CS_VOICE */ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, /* VOIP */ @@ -658,15 +655,9 @@ static struct msm_pcm_routing_fdai_data {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, /* VOICE_STUB */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, - /* VOLTE */ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, /* DTMF_RX */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, - /* VOICE2 */ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, /* QCHAT */ @@ -700,9 +691,6 @@ static struct msm_pcm_routing_fdai_data {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, /* VOICE2_STUB */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, - /* VOWLAN */ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, /* VOICEMMODE1 */ @@ -1273,18 +1261,6 @@ static u32 msm_pcm_routing_get_voc_sessionid(u16 val) u32 session_id; switch (val) { - case MSM_FRONTEND_DAI_CS_VOICE: - session_id = voc_get_session_id(VOICE_SESSION_NAME); - break; - case MSM_FRONTEND_DAI_VOLTE: - session_id = voc_get_session_id(VOLTE_SESSION_NAME); - break; - case MSM_FRONTEND_DAI_VOWLAN: - session_id = voc_get_session_id(VOWLAN_SESSION_NAME); - break; - case MSM_FRONTEND_DAI_VOICE2: - session_id = voc_get_session_id(VOICE2_SESSION_NAME); - break; case MSM_FRONTEND_DAI_QCHAT: session_id = voc_get_session_id(QCHAT_SESSION_NAME); break; @@ -7987,21 +7963,9 @@ static const struct snd_kcontrol_new mmul20_mixer_controls[] = { }; static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8017,21 +7981,9 @@ static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8041,21 +7993,9 @@ static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new sec_mi2s_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8071,12 +8011,6 @@ static const struct snd_kcontrol_new sec_mi2s_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8086,15 +8020,9 @@ static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8110,12 +8038,6 @@ static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new slimbus_6_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8125,15 +8047,9 @@ static const struct snd_kcontrol_new slimbus_6_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8149,12 +8065,6 @@ static const struct snd_kcontrol_new slimbus_6_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new usb_audio_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8164,15 +8074,9 @@ static const struct snd_kcontrol_new usb_audio_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8188,12 +8092,6 @@ static const struct snd_kcontrol_new usb_audio_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8203,12 +8101,6 @@ static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8224,24 +8116,12 @@ static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new mi2s_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8257,12 +8137,6 @@ static const struct snd_kcontrol_new mi2s_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new pri_mi2s_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8272,15 +8146,9 @@ static const struct snd_kcontrol_new pri_mi2s_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8332,12 +8200,6 @@ static const struct snd_kcontrol_new int4_mi2s_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new tert_mi2s_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8347,15 +8209,9 @@ static const struct snd_kcontrol_new tert_mi2s_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8371,12 +8227,6 @@ static const struct snd_kcontrol_new tert_mi2s_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new quat_mi2s_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8386,15 +8236,9 @@ static const struct snd_kcontrol_new quat_mi2s_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8410,12 +8254,6 @@ static const struct snd_kcontrol_new quat_mi2s_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new quin_mi2s_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8425,15 +8263,9 @@ static const struct snd_kcontrol_new quin_mi2s_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8449,12 +8281,6 @@ static const struct snd_kcontrol_new quin_mi2s_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8464,15 +8290,9 @@ static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8488,12 +8308,6 @@ static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8503,15 +8317,9 @@ static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8527,24 +8335,12 @@ static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new sec_aux_pcm_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8560,24 +8356,12 @@ static const struct snd_kcontrol_new sec_aux_pcm_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new tert_aux_pcm_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8593,24 +8377,12 @@ static const struct snd_kcontrol_new tert_aux_pcm_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new quat_aux_pcm_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8626,24 +8398,12 @@ static const struct snd_kcontrol_new quat_aux_pcm_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new quin_aux_pcm_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8659,21 +8419,9 @@ static const struct snd_kcontrol_new quin_aux_pcm_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), @@ -8698,12 +8446,6 @@ static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new slimbus_7_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8713,15 +8455,9 @@ static const struct snd_kcontrol_new slimbus_7_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8737,12 +8473,6 @@ static const struct snd_kcontrol_new slimbus_7_rx_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new slimbus_8_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_8_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8752,15 +8482,9 @@ static const struct snd_kcontrol_new slimbus_8_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_8_RX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_8_RX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_8_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8817,201 +8541,6 @@ static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = { msm_routing_put_voice_stub_mixer), }; -static const struct snd_kcontrol_new tx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_TX_Voice", MSM_BACKEND_DAI_PRI_I2S_TX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("MI2S_TX_Voice", MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_0_TX_Voice", MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice", - MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_CS_VOICE, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX_Voice", MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("AUX_PCM_TX_Voice", MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_TX_Voice", MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_TX_Voice", MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_Voice", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUIN_AUX_PCM_TX_Voice", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX_Voice", MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX_Voice", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX_Voice", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_7_TX_Voice", MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_8_TX_Voice", MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("USB_AUDIO_TX_Voice", MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new tx_voice2_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_TX_Voice2", MSM_BACKEND_DAI_PRI_I2S_TX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("MI2S_TX_Voice2", MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_0_TX_Voice2", MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voice2", - MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICE2, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX_Voice2", MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUIN_AUX_PCM_TX_Voice2", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX_Voice2", MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX_Voice2", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_7_TX_Voice2", MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_8_TX_Voice2", MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("USB_AUDIO_TX_Voice2", MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new tx_volte_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_TX_VoLTE", MSM_BACKEND_DAI_PRI_I2S_TX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_0_TX_VoLTE", MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_VoLTE", - MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOLTE, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX_VoLTE", MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("AUX_PCM_TX_VoLTE", MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_TX_VoLTE", MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_TX_VoLTE", MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_VoLTE", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUIN_AUX_PCM_TX_VoLTE", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("MI2S_TX_VoLTE", MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX_VoLTE", MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX_VoLTE", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_7_TX_VoLTE", MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_8_TX_VoLTE", MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("USB_AUDIO_TX_VoLTE", MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new tx_vowlan_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_TX_VoWLAN", MSM_BACKEND_DAI_PRI_I2S_TX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_0_TX_VoWLAN", MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_VoWLAN", - MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOWLAN, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX_VoWLAN", MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("AUX_PCM_TX_VoWLAN", MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_TX_VoWLAN", MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_TX_VoWLAN", MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_VoWLAN", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUIN_AUX_PCM_TX_VoWLAN", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("MI2S_TX_VoWLAN", MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX_VoWLAN", MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX_VoWLAN", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_7_TX_VoWLAN", MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_8_TX_VoWLAN", MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("USB_AUDIO_TX_VoWLAN", MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { SOC_SINGLE_EXT("PRI_TX_MMode1", MSM_BACKEND_DAI_PRI_I2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, @@ -12896,14 +12425,6 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("MM_UL18", "MultiMedia18 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL19", "MultiMedia19 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL20", "MultiMedia20 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("CS-VOICE_DL1", "CS-VOICE Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("VOICE2_DL", "Voice2 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VOICE2_UL", "Voice2 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("VoLTE_DL", "VoLTE Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VoLTE_UL", "VoLTE Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("VoWLAN_DL", "VoWLAN Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VoWLAN_UL", "VoWLAN Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("VOICEMMODE1_DL", "VoiceMMode1 Playback", 0, 0, 0, 0), @@ -13855,21 +13376,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_NOPM, 0, 0, quat_tdm_rx_2_voice_mixer_controls, ARRAY_SIZE(quat_tdm_rx_2_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("Voice_Tx Mixer", - SND_SOC_NOPM, 0, 0, tx_voice_mixer_controls, - ARRAY_SIZE(tx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("Voice2_Tx Mixer", - SND_SOC_NOPM, 0, 0, tx_voice2_mixer_controls, - ARRAY_SIZE(tx_voice2_mixer_controls)), SND_SOC_DAPM_MIXER("Voip_Tx Mixer", SND_SOC_NOPM, 0, 0, tx_voip_mixer_controls, ARRAY_SIZE(tx_voip_mixer_controls)), - SND_SOC_DAPM_MIXER("VoLTE_Tx Mixer", - SND_SOC_NOPM, 0, 0, tx_volte_mixer_controls, - ARRAY_SIZE(tx_volte_mixer_controls)), - SND_SOC_DAPM_MIXER("VoWLAN_Tx Mixer", - SND_SOC_NOPM, 0, 0, tx_vowlan_mixer_controls, - ARRAY_SIZE(tx_vowlan_mixer_controls)), SND_SOC_DAPM_MIXER("VoiceMMode1_Tx Mixer", SND_SOC_NOPM, 0, 0, tx_voicemmode1_mixer_controls, ARRAY_SIZE(tx_voicemmode1_mixer_controls)), @@ -15471,20 +14980,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUX_PCM_RX Audio Mixer"}, - {"MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"MI2S_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"}, - - {"PRI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"PRI_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"PRI_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"PRI_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"PRI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"PRI_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, @@ -15492,19 +14987,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"}, - {"SEC_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"SEC_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"SEC_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"SEC_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"SEC_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"SEC_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"}, - {"SEC_MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"SEC_MI2S_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"SEC_MI2S_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"SEC_MI2S_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"SEC_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"SEC_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"SEC_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, @@ -15512,10 +14999,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX_Voice Mixer"}, - {"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"SLIM_0_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"SLIM_0_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"SLIM_0_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"SLIM_0_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"SLIM_0_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, @@ -15526,10 +15009,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIM_0_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"}, - {"SLIM_6_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"SLIM_6_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"SLIM_6_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"SLIM_6_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"SLIM_6_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"SLIM_6_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"SLIM_6_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, @@ -15540,10 +15019,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIM_6_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"SLIMBUS_6_RX", NULL, "SLIM_6_RX_Voice Mixer"}, - {"USB_AUDIO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"USB_AUDIO_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"USB_AUDIO_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"USB_AUDIO_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"USB_AUDIO_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"USB_AUDIO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"USB_AUDIO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, @@ -15554,10 +15029,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"USB_AUDIO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX_Voice Mixer"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"INTERNAL_BT_SCO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"INTERNAL_BT_SCO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, @@ -15567,10 +15038,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"}, - {"AFE_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"AFE_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"AFE_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"AFE_PCM_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"AFE_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"AFE_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, @@ -15578,10 +15045,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"AFE_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"}, - {"AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"AUX_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"AUX_PCM_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"AUX_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, @@ -15592,10 +15055,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"}, - {"SEC_AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"SEC_AUX_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"SEC_AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"SEC_AUX_PCM_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"SEC_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"SEC_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"SEC_AUX_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, @@ -15604,10 +15063,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX_Voice Mixer"}, - {"TERT_AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"TERT_AUX_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"TERT_AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"TERT_AUX_PCM_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"TERT_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"TERT_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"TERT_AUX_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, @@ -15616,10 +15071,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"TERT_AUX_PCM_RX", NULL, "TERT_AUX_PCM_RX_Voice Mixer"}, - {"QUAT_AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"QUAT_AUX_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"QUAT_AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"QUAT_AUX_PCM_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"QUAT_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"QUAT_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"QUAT_AUX_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, @@ -15628,10 +15079,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUX_PCM_RX_Voice Mixer"}, - {"QUIN_AUX_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"QUIN_AUX_PCM_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"QUIN_AUX_PCM_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"QUIN_AUX_PCM_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"QUIN_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"QUIN_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"QUIN_AUX_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, @@ -15640,10 +15087,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUX_PCM_RX_Voice Mixer"}, - {"HDMI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"HDMI_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"HDMI_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"HDMI_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"HDMI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"HDMI_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, @@ -15652,22 +15095,15 @@ static const struct snd_soc_dapm_route intercon[] = { {"HDMI", NULL, "HDMI_RX_Voice Mixer"}, {"HDMI", NULL, "HDMI_DL_HL"}, - {"MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"MI2S_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, {"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"MI2S_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"MI2S_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, {"MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"}, - {"PRI_MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"PRI_MI2S_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, {"PRI_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_MI2S_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"PRI_MI2S_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"PRI_MI2S_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"PRI_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, {"PRI_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, @@ -15691,11 +15127,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"INT4_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_Voice Mixer"}, - {"TERT_MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"TERT_MI2S_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, {"TERT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"TERT_MI2S_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"TERT_MI2S_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"TERT_MI2S_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"TERT_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, {"TERT_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, @@ -15705,11 +15137,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX_Voice Mixer"}, - {"QUAT_MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"QUAT_MI2S_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, {"QUAT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"QUAT_MI2S_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"QUAT_MI2S_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"QUAT_MI2S_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"QUAT_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, {"QUAT_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, @@ -15718,11 +15146,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_Voice Mixer"}, - {"QUIN_MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"QUIN_MI2S_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, {"QUIN_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"QUIN_MI2S_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"QUIN_MI2S_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"QUIN_MI2S_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"QUIN_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, {"QUIN_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, @@ -16743,10 +16167,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_3_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX_Voice Mixer"}, - {"SLIM_7_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"SLIM_7_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"SLIM_7_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"SLIM_7_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"SLIM_7_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"SLIM_7_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"SLIM_7_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, @@ -16757,10 +16177,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIM_7_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"SLIMBUS_7_RX", NULL, "SLIM_7_RX_Voice Mixer"}, - {"SLIM_8_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"SLIM_8_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, - {"SLIM_8_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"SLIM_8_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"SLIM_8_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"SLIM_8_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"SLIM_8_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 8f91e4ff13d9..5360b5b5f770 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -211,14 +211,11 @@ enum { MSM_FRONTEND_DAI_MULTIMEDIA18, MSM_FRONTEND_DAI_MULTIMEDIA19, MSM_FRONTEND_DAI_MULTIMEDIA20, - MSM_FRONTEND_DAI_CS_VOICE, MSM_FRONTEND_DAI_VOIP, MSM_FRONTEND_DAI_AFE_RX, MSM_FRONTEND_DAI_AFE_TX, MSM_FRONTEND_DAI_VOICE_STUB, - MSM_FRONTEND_DAI_VOLTE, MSM_FRONTEND_DAI_DTMF_RX, - MSM_FRONTEND_DAI_VOICE2, MSM_FRONTEND_DAI_QCHAT, MSM_FRONTEND_DAI_VOLTE_STUB, MSM_FRONTEND_DAI_LSM1, @@ -230,7 +227,6 @@ enum { MSM_FRONTEND_DAI_LSM7, MSM_FRONTEND_DAI_LSM8, MSM_FRONTEND_DAI_VOICE2_STUB, - MSM_FRONTEND_DAI_VOWLAN, MSM_FRONTEND_DAI_VOICEMMODE1, MSM_FRONTEND_DAI_VOICEMMODE2, MSM_FRONTEND_DAI_MAX, diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index 0d1018236aec..00a29d71a55b 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -27,7 +27,7 @@ /* EQUALIZER */ /* Equal to Frontend after last of the MULTIMEDIA SESSIONS */ -#define MAX_EQ_SESSIONS MSM_FRONTEND_DAI_CS_VOICE +#define MAX_EQ_SESSIONS (MSM_FRONTEND_DAI_MULTIMEDIA20 + 1) enum { EQ_BAND1 = 0, -- GitLab From c3f9814e4f6cb21dbf10b885ab22c62cd7ca2a35 Mon Sep 17 00:00:00 2001 From: Haynes Mathew George Date: Wed, 18 Oct 2017 14:40:24 -0700 Subject: [PATCH 0093/1645] asoc: sdm845: update and affine qos value Fix qos value to 300 micro seconds to prevent core from going into low power mode when low latency session is active. Also pin this qos to core 1 & core 2 where audio and glink threads are running to let other cores to go to low power modes if possible. Change-Id: I46d356c384fd8d02a9a3b336a113200171bf25a0 Signed-off-by: Haynes Mathew George Signed-off-by: Dhananjay Kumar Signed-off-by: Aniket Kumar Lata --- asoc/sdm845.c | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/asoc/sdm845.c b/asoc/sdm845.c index f8c044401617..3397648b9c9f 100644 --- a/asoc/sdm845.c +++ b/asoc/sdm845.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -72,6 +73,7 @@ #define TDM_CHANNEL_MAX 8 #define MSM_HIFI_ON 1 +#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ enum { SLIM_RX_0 = 0, @@ -2614,21 +2616,6 @@ static int msm_hifi_put(struct snd_kcontrol *kcontrol, return 0; } -static s32 msm_qos_value(struct snd_pcm_runtime *runtime) -{ - s32 usecs; - - if (!runtime->rate) - return -EINVAL; - - /* take 75% of period time as the deadline */ - usecs = (750000 / runtime->rate) * runtime->period_size; - usecs += ((750000 % runtime->rate) * runtime->period_size) / - runtime->rate; - - return usecs; -} - static int msm_qos_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2668,7 +2655,7 @@ static int msm_qos_ctl_put(struct snd_kcontrol *kcontrol, pr_err("%s: runtime is null\n", __func__); return -EINVAL; } - usecs = msm_qos_value(substream->runtime); + usecs = MSM_LL_QOS_VALUE; if (usecs >= 0) pm_qos_add_request(&substream->latency_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, usecs); @@ -4616,6 +4603,30 @@ static struct snd_soc_ops sdm845_tdm_be_ops = { .shutdown = sdm845_tdm_snd_shutdown }; +static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) +{ + cpumask_t mask; + + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + + cpumask_clear(&mask); + cpumask_set_cpu(1, &mask); /* affine to core 1 */ + cpumask_set_cpu(2, &mask); /* affine to core 2 */ + cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); + + substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; + + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + MSM_LL_QOS_VALUE); + return 0; +} + +static struct snd_soc_ops msm_fe_qos_ops = { + .prepare = msm_fe_qos_prepare, +}; + static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) { int ret = 0; @@ -4986,6 +4997,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { /* this dainlink has playback support */ .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .ops = &msm_fe_qos_ops, }, { .name = "Listen 1 Audio Service", @@ -5053,6 +5065,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .ignore_pmdown_time = 1, /* this dainlink has playback support */ .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + .ops = &msm_fe_qos_ops, }, /* HDMI Hostless */ { -- GitLab From f6bc7130d2ab45c5f7220da2eb56686fb0571bb8 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Fri, 20 Oct 2017 22:29:42 -0700 Subject: [PATCH 0094/1645] asoc: wcd9xxx-core: avoid slimbus read/write during ADSP SSR This reverts commit 40bc50d768038c04f8c1 ("mfd: wcd9xxx-core: Synchronize codec down and reset calls from slimbus."). This is to make sure that the dev_up flag is set right after device_down is called from Slimbus after ADSP SSR. This flag helps make sure that all read/write calls over slimbus are blocked until ADSP and Slimbus are fully up post-SSR. Change-Id: I5595a23a0b51f2ca392ddfb5773b057204185b54 Signed-off-by: Banajit Goswami --- asoc/codecs/core.h | 2 +- asoc/codecs/wcd9xxx-core.c | 49 +++++++++++++------------------------- 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/asoc/codecs/core.h b/asoc/codecs/core.h index b994010f5222..b4c1be40ff31 100644 --- a/asoc/codecs/core.h +++ b/asoc/codecs/core.h @@ -350,7 +350,7 @@ struct wcd9xxx { int (*post_reset)(struct wcd9xxx *wcd9xxx); void *ssr_priv; - unsigned long dev_up; + bool dev_up; u32 num_of_supplies; struct regulator_bulk_data *supplies; diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index 7f74aef8f0c0..49be43a3e12f 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -228,7 +228,7 @@ static int wcd9xxx_slim_read_device(struct wcd9xxx *wcd9xxx, unsigned short reg, if (!wcd9xxx->dev_up) { dev_dbg_ratelimited( - wcd9xxx->dev, "%s: No read allowed. dev_up = %lu\n", + wcd9xxx->dev, "%s: No read allowed. dev_up = %d\n", __func__, wcd9xxx->dev_up); return 0; } @@ -268,7 +268,7 @@ static int wcd9xxx_slim_write_device(struct wcd9xxx *wcd9xxx, if (!wcd9xxx->dev_up) { dev_dbg_ratelimited( - wcd9xxx->dev, "%s: No write allowed. dev_up = %lu\n", + wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n", __func__, wcd9xxx->dev_up); return 0; } @@ -345,7 +345,7 @@ int wcd9xxx_slim_write_repeat(struct wcd9xxx *wcd9xxx, unsigned short reg, if (!wcd9xxx->dev_up) { dev_dbg_ratelimited( - wcd9xxx->dev, "%s: No write allowed. dev_up = %lu\n", + wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n", __func__, wcd9xxx->dev_up); ret = 0; goto done; @@ -426,7 +426,7 @@ int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx, if (!wcd9xxx->dev_up) { dev_dbg_ratelimited( - wcd9xxx->dev, "%s: No write allowed. dev_up = %lu\n", + wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n", __func__, wcd9xxx->dev_up); return 0; } @@ -1484,27 +1484,12 @@ static int wcd9xxx_slim_device_reset(struct slim_device *sldev) return -EINVAL; } - /* - * Wait for 500 ms for device down to complete. Observed delay - * of ~200ms for device down to complete after being called, - * due to context switch issue. - */ - ret = wait_on_bit_timeout(&wcd9xxx->dev_up, 0, - TASK_INTERRUPTIBLE, - msecs_to_jiffies(500)); - if (ret) - pr_err("%s: slim device down not complete in 500 msec\n", - __func__); - - mutex_lock(&wcd9xxx->reset_lock); - - dev_info(wcd9xxx->dev, "%s: device reset, dev_up = %lu\n", - __func__, wcd9xxx->dev_up); - if (wcd9xxx->dev_up) { - mutex_unlock(&wcd9xxx->reset_lock); + dev_info(wcd9xxx->dev, "%s: device reset, dev_up = %d\n", + __func__, wcd9xxx->dev_up); + if (wcd9xxx->dev_up) return 0; - } + mutex_lock(&wcd9xxx->reset_lock); ret = wcd9xxx_reset(wcd9xxx->dev); if (ret) dev_err(wcd9xxx->dev, "%s: Resetting Codec failed\n", __func__); @@ -1522,8 +1507,8 @@ static int wcd9xxx_slim_device_up(struct slim_device *sldev) pr_err("%s: wcd9xxx is NULL\n", __func__); return -EINVAL; } - dev_info(wcd9xxx->dev, "%s: slim device up, dev_up = %lu\n", - __func__, wcd9xxx->dev_up); + dev_info(wcd9xxx->dev, "%s: slim device up, dev_up = %d\n", + __func__, wcd9xxx->dev_up); if (wcd9xxx->dev_up) return 0; @@ -1545,20 +1530,18 @@ static int wcd9xxx_slim_device_down(struct slim_device *sldev) return -EINVAL; } - mutex_lock(&wcd9xxx->reset_lock); - - dev_info(wcd9xxx->dev, "%s: device down, dev_up = %lu\n", - __func__, wcd9xxx->dev_up); - if (!wcd9xxx->dev_up) { - mutex_unlock(&wcd9xxx->reset_lock); + dev_info(wcd9xxx->dev, "%s: device down, dev_up = %d\n", + __func__, wcd9xxx->dev_up); + if (!wcd9xxx->dev_up) return 0; - } + wcd9xxx->dev_up = false; + + mutex_lock(&wcd9xxx->reset_lock); if (wcd9xxx->dev_down) wcd9xxx->dev_down(wcd9xxx); wcd9xxx_irq_exit(&wcd9xxx->core_res); wcd9xxx_reset_low(wcd9xxx->dev); - wcd9xxx->dev_up = false; mutex_unlock(&wcd9xxx->reset_lock); return 0; -- GitLab From 09d4168c79d6ec82c2f565c1021b1b213127ec32 Mon Sep 17 00:00:00 2001 From: Walter Yang Date: Wed, 25 Oct 2017 11:50:43 +0800 Subject: [PATCH 0095/1645] ASoC: wcd934x: reset ASRC after playback Reset ASRC after audio playback is completed to clear the FIFO and avoid any noise being generated. CRs-Fixed: 2129994 Change-Id: Ie45796e1bd68d5a8bd790490a65520358f26b811 Signed-off-by: Walter Yang --- asoc/codecs/wcd934x/wcd934x.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index d6eb22d57951..d70963541193 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -2879,7 +2879,7 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec, int asrc_in, int event) { struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); - u16 cfg_reg, ctl_reg, clk_reg, asrc_ctl, mix_ctl_reg; + u16 cfg_reg, ctl_reg, clk_reg, asrc_ctl, mix_ctl_reg, paired_reg; int asrc, ret = 0; u8 main_sr, mix_sr, asrc_mode = 0; @@ -2888,6 +2888,7 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec, cfg_reg = WCD934X_CDC_RX1_RX_PATH_CFG0; ctl_reg = WCD934X_CDC_RX1_RX_PATH_CTL; clk_reg = WCD934X_MIXING_ASRC0_CLK_RST_CTL; + paired_reg = WCD934X_MIXING_ASRC1_CLK_RST_CTL; asrc_ctl = WCD934X_MIXING_ASRC0_CTL1; asrc = ASRC0; break; @@ -2895,6 +2896,7 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec, cfg_reg = WCD934X_CDC_RX3_RX_PATH_CFG0; ctl_reg = WCD934X_CDC_RX3_RX_PATH_CTL; clk_reg = WCD934X_MIXING_ASRC0_CLK_RST_CTL; + paired_reg = WCD934X_MIXING_ASRC1_CLK_RST_CTL; asrc_ctl = WCD934X_MIXING_ASRC0_CTL1; asrc = ASRC0; break; @@ -2902,6 +2904,7 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec, cfg_reg = WCD934X_CDC_RX2_RX_PATH_CFG0; ctl_reg = WCD934X_CDC_RX2_RX_PATH_CTL; clk_reg = WCD934X_MIXING_ASRC1_CLK_RST_CTL; + paired_reg = WCD934X_MIXING_ASRC0_CLK_RST_CTL; asrc_ctl = WCD934X_MIXING_ASRC1_CTL1; asrc = ASRC1; break; @@ -2909,6 +2912,7 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec, cfg_reg = WCD934X_CDC_RX4_RX_PATH_CFG0; ctl_reg = WCD934X_CDC_RX4_RX_PATH_CTL; clk_reg = WCD934X_MIXING_ASRC1_CLK_RST_CTL; + paired_reg = WCD934X_MIXING_ASRC0_CLK_RST_CTL; asrc_ctl = WCD934X_MIXING_ASRC1_CTL1; asrc = ASRC1; break; @@ -2916,6 +2920,7 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec, cfg_reg = WCD934X_CDC_RX7_RX_PATH_CFG0; ctl_reg = WCD934X_CDC_RX7_RX_PATH_CTL; clk_reg = WCD934X_MIXING_ASRC2_CLK_RST_CTL; + paired_reg = WCD934X_MIXING_ASRC3_CLK_RST_CTL; asrc_ctl = WCD934X_MIXING_ASRC2_CTL1; asrc = ASRC2; break; @@ -2923,6 +2928,7 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec, cfg_reg = WCD934X_CDC_RX8_RX_PATH_CFG0; ctl_reg = WCD934X_CDC_RX8_RX_PATH_CTL; clk_reg = WCD934X_MIXING_ASRC3_CLK_RST_CTL; + paired_reg = WCD934X_MIXING_ASRC2_CLK_RST_CTL; asrc_ctl = WCD934X_MIXING_ASRC3_CTL1; asrc = ASRC3; break; @@ -2936,6 +2942,13 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec, switch (event) { case SND_SOC_DAPM_PRE_PMU: if (tavil->asrc_users[asrc] == 0) { + if ((snd_soc_read(codec, clk_reg) & 0x02) || + (snd_soc_read(codec, paired_reg) & 0x02)) { + snd_soc_update_bits(codec, clk_reg, + 0x02, 0x00); + snd_soc_update_bits(codec, paired_reg, + 0x02, 0x00); + } snd_soc_update_bits(codec, cfg_reg, 0x80, 0x80); snd_soc_update_bits(codec, clk_reg, 0x01, 0x01); main_sr = snd_soc_read(codec, ctl_reg) & 0x0F; @@ -2955,7 +2968,7 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec, tavil->asrc_users[asrc] = 0; snd_soc_update_bits(codec, asrc_ctl, 0x07, 0x00); snd_soc_update_bits(codec, cfg_reg, 0x80, 0x00); - snd_soc_update_bits(codec, clk_reg, 0x01, 0x00); + snd_soc_update_bits(codec, clk_reg, 0x03, 0x02); } break; }; -- GitLab From 15fffc6b9b8ab71e2bbed8caced567c61523afc1 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Sat, 21 Oct 2017 01:12:47 -0700 Subject: [PATCH 0096/1645] asoc: wcd934x: set bus down flag right when notification reaches Set bus_down_in_recovery flag as soon as possible when BUS down notification reaches codec driver. This is to avoid any unwanted slimbus transaction while BUS is still not recovered. Change-Id: I77917975372bf51e6aa881cbfc63c479478db375 Signed-off-by: Banajit Goswami --- asoc/codecs/wcd934x/wcd934x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index d6eb22d57951..1f751ec4b558 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -9203,13 +9203,13 @@ static int tavil_device_down(struct wcd9xxx *wcd9xxx) codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); priv = snd_soc_codec_get_drvdata(codec); + for (count = 0; count < NUM_CODEC_DAIS; count++) + priv->dai[count].bus_down_in_recovery = true; if (priv->swr.ctrl_data) swrm_wcd_notify(priv->swr.ctrl_data[0].swr_pdev, SWR_DEVICE_DOWN, NULL); tavil_dsd_reset(priv->dsd_config); snd_soc_card_change_online_state(codec->component.card, 0); - for (count = 0; count < NUM_CODEC_DAIS; count++) - priv->dai[count].bus_down_in_recovery = true; wcd_dsp_ssr_event(priv->wdsp_cntl, WCD_CDC_DOWN_EVENT); wcd_resmgr_set_sido_input_src_locked(priv->resmgr, SIDO_SOURCE_INTERNAL); -- GitLab From e9a5007c9fe12c10a5d663e0136b3947864bad99 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 6 Sep 2017 17:40:11 +0530 Subject: [PATCH 0097/1645] ASoC: wcd: Fix pop noise in HPH plus LO4 concurrent usecase Pop sound happens after start playback on HPH when ultrasound playback on LO4 is enabled. This is because CnP is sequence dependent and enabling design blocks in specified order is causing minimum CnP. CRs-Fixed: 2100346 Change-Id: If10f9013cc1a2aa61fe9c719d3190f2df0b00950 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd9335.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index a4a838f9a6b9..7bc2272164a7 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -3874,6 +3874,8 @@ static int tasha_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0xC0, 0xC0); } set_bit(HPH_PA_DELAY, &tasha->status_mask); + if (!(strcmp(w->name, "HPHR PA"))) + snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x40, 0x40); break; case SND_SOC_DAPM_POST_PMU: if (!(strcmp(w->name, "ANC HPHR PA"))) { @@ -3926,7 +3928,8 @@ static int tasha_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, WCD_EVENT_PRE_HPHR_PA_OFF, &tasha->mbhc); tasha_codec_hph_post_pa_config(tasha, hph_mode, event); - if (!(strcmp(w->name, "ANC HPHR PA"))) + if (!(strcmp(w->name, "ANC HPHR PA")) || + !(strcmp(w->name, "HPHR PA"))) snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x40, 0x00); break; case SND_SOC_DAPM_POST_PMD: @@ -3967,6 +3970,8 @@ static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, (test_bit(HPH_PA_DELAY, &tasha->status_mask))) { snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0xC0, 0xC0); } + if (!(strcmp(w->name, "HPHL PA"))) + snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x80, 0x80); set_bit(HPH_PA_DELAY, &tasha->status_mask); break; case SND_SOC_DAPM_POST_PMU: @@ -4021,7 +4026,8 @@ static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, WCD_EVENT_PRE_HPHL_PA_OFF, &tasha->mbhc); tasha_codec_hph_post_pa_config(tasha, hph_mode, event); - if (!(strcmp(w->name, "ANC HPHL PA"))) + if (!(strcmp(w->name, "ANC HPHL PA")) || + !(strcmp(w->name, "HPHL PA"))) snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x80, 0x00); break; case SND_SOC_DAPM_POST_PMD: @@ -4366,6 +4372,9 @@ static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, ((hph_mode == CLS_H_LOHIFI) ? CLS_H_HIFI : hph_mode)); + if (!(strcmp(w->name, "RX INT2 DAC"))) + snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x10, 0x10); + tasha_codec_hph_mode_config(codec, event, hph_mode); if (tasha->anc_func) @@ -4388,6 +4397,8 @@ static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL, 0x03, 0x00); } + if (!(strcmp(w->name, "RX INT2 DAC"))) + snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x10, 0x00); break; case SND_SOC_DAPM_POST_PMD: /* 1000us required as per HW requirement */ @@ -4446,6 +4457,9 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, ((hph_mode == CLS_H_LOHIFI) ? CLS_H_HIFI : hph_mode)); + if (!(strcmp(w->name, "RX INT1 DAC"))) + snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x20, 0x20); + tasha_codec_hph_mode_config(codec, event, hph_mode); if (tasha->anc_func) @@ -4475,6 +4489,8 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, } break; case SND_SOC_DAPM_PRE_PMD: + if (!(strcmp(w->name, "RX INT1 DAC"))) + snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x20, 0x00); if ((hph_mode == CLS_H_LP) && (TASHA_IS_1_1(wcd9xxx))) { snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL, @@ -10967,12 +10983,12 @@ static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = { 0, 0, tasha_codec_ear_dac_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_DAC_E("RX INT1 DAC", NULL, WCD9335_ANA_HPH, - 5, 0, tasha_codec_hphl_dac_event, + SND_SOC_DAPM_DAC_E("RX INT1 DAC", NULL, SND_SOC_NOPM, + 0, 0, tasha_codec_hphl_dac_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_DAC_E("RX INT2 DAC", NULL, WCD9335_ANA_HPH, - 4, 0, tasha_codec_hphr_dac_event, + SND_SOC_DAPM_DAC_E("RX INT2 DAC", NULL, SND_SOC_NOPM, + 0, 0, tasha_codec_hphr_dac_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_DAC_E("RX INT3 DAC", NULL, SND_SOC_NOPM, @@ -10987,11 +11003,11 @@ static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = { SND_SOC_DAPM_DAC_E("RX INT6 DAC", NULL, SND_SOC_NOPM, 0, 0, tasha_codec_lineout_dac_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("HPHL PA", WCD9335_ANA_HPH, 7, 0, NULL, 0, + SND_SOC_DAPM_PGA_E("HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0, tasha_codec_enable_hphl_pa, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("HPHR PA", WCD9335_ANA_HPH, 6, 0, NULL, 0, + SND_SOC_DAPM_PGA_E("HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0, tasha_codec_enable_hphr_pa, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), -- GitLab From 00d55efdfbbf148296415a7d295229731b8e3eb7 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 27 Oct 2017 18:41:55 -0700 Subject: [PATCH 0098/1645] asoc: codecs: add support for TX hybrid mode Add support for analog mic TX hybrid mode to allow audio catpure in high performance at the same time achieving lower power. CRs-Fixed: 2136385 Change-Id: I08b90a26d6b6e4761ff17dec84bf58f8d437d908 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd934x/wcd934x.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 2b930581a542..8e3981c9fdf5 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -115,6 +115,7 @@ static const struct snd_kcontrol_new name##_mux = \ #define WCD934X_AMIC_PWR_LEVEL_LP 0 #define WCD934X_AMIC_PWR_LEVEL_DEFAULT 1 #define WCD934X_AMIC_PWR_LEVEL_HP 2 +#define WCD934X_AMIC_PWR_LEVEL_HYBRID 3 #define WCD934X_AMIC_PWR_LVL_MASK 0x60 #define WCD934X_AMIC_PWR_LVL_SHIFT 0x5 @@ -122,6 +123,7 @@ static const struct snd_kcontrol_new name##_mux = \ #define WCD934X_DEC_PWR_LVL_LP 0x02 #define WCD934X_DEC_PWR_LVL_HP 0x04 #define WCD934X_DEC_PWR_LVL_DF 0x00 +#define WCD934X_DEC_PWR_LVL_HYBRID WCD934X_DEC_PWR_LVL_DF #define WCD934X_STRING_LEN 100 #define WCD934X_CDC_SIDETONE_IIR_COEFF_MAX 5 @@ -4014,6 +4016,7 @@ static int tavil_codec_enable_dec(struct snd_soc_dapm_widget *w, WCD934X_DEC_PWR_LVL_HP); break; case WCD934X_AMIC_PWR_LEVEL_DEFAULT: + case WCD934X_AMIC_PWR_LEVEL_HYBRID: default: snd_soc_update_bits(codec, dec_cfg_reg, WCD934X_DEC_PWR_LVL_MASK, @@ -5707,7 +5710,7 @@ static const char * const rx_cf_text[] = { }; static const char * const amic_pwr_lvl_text[] = { - "LOW_PWR", "DEFAULT", "HIGH_PERF" + "LOW_PWR", "DEFAULT", "HIGH_PERF", "HYBRID" }; static const char * const hph_idle_detect_text[] = { -- GitLab From 52697fe50c7264486681d6de0e071e1c311ec685 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 29 Nov 2017 15:44:14 +0530 Subject: [PATCH 0099/1645] ASoC: remove error prints and warning at bootup log Cleanup for errors and warning print in audio drivers. CRs-Fixed: 2080345 Change-Id: Ib473dad9226127930be7079063e7795a802ca279 Signed-off-by: Laxminath Kasam --- asoc/codecs/sdm660_cdc/msm-analog-cdc.c | 15 +-------------- asoc/codecs/sdm660_cdc/msm-digital-cdc.c | 6 ++++++ asoc/msm-pcm-routing-v2.c | 15 +++++++++++++++ asoc/sdm660-internal.c | 3 +++ 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c index d83d15a3b1cc..ffd4260b3185 100644 --- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c @@ -3630,18 +3630,6 @@ static const struct sdm660_cdc_reg_mask_val {MSM89XX_PMIC_ANALOG_RX_COM_OCP_COUNT, 0xFF, 0xFF}, }; -static void msm_anlg_cdc_codec_init_cache(struct snd_soc_codec *codec) -{ - u32 i; - - regcache_cache_only(codec->component.regmap, true); - /* update cache with POR values */ - for (i = 0; i < ARRAY_SIZE(msm89xx_pmic_cdc_defaults); i++) - snd_soc_write(codec, msm89xx_pmic_cdc_defaults[i].reg, - msm89xx_pmic_cdc_defaults[i].def); - regcache_cache_only(codec->component.regmap, false); -} - static void msm_anlg_cdc_codec_init_reg(struct snd_soc_codec *codec) { u32 i; @@ -3687,7 +3675,7 @@ static struct regulator *msm_anlg_cdc_find_regulator( return sdm660_cdc->supplies[i].consumer; } - dev_err(sdm660_cdc->dev, "Error: regulator not found:%s\n" + dev_dbg(sdm660_cdc->dev, "Error: regulator not found:%s\n" , name); return NULL; } @@ -4139,7 +4127,6 @@ static int msm_anlg_cdc_soc_probe(struct snd_soc_codec *codec) ARRAY_SIZE(hph_type_detect_controls)); msm_anlg_cdc_bringup(codec); - msm_anlg_cdc_codec_init_cache(codec); msm_anlg_cdc_codec_init_reg(codec); msm_anlg_cdc_update_reg_defaults(codec); diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c index 928c908e3da6..2c3d0d66afca 100644 --- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -1397,6 +1397,9 @@ static const struct snd_soc_dapm_route audio_dig_map[] = { {"RX2 MIX1 INP2", "RX3", "I2S RX3"}, {"RX2 MIX1 INP2", "IIR1", "IIR1"}, {"RX2 MIX1 INP2", "IIR2", "IIR2"}, + {"RX2 MIX1 INP3", "RX1", "I2S RX1"}, + {"RX2 MIX1 INP3", "RX2", "I2S RX2"}, + {"RX2 MIX1 INP3", "RX3", "I2S RX3"}, {"RX3 MIX1 INP1", "RX1", "I2S RX1"}, {"RX3 MIX1 INP1", "RX2", "I2S RX2"}, @@ -1408,6 +1411,9 @@ static const struct snd_soc_dapm_route audio_dig_map[] = { {"RX3 MIX1 INP2", "RX3", "I2S RX3"}, {"RX3 MIX1 INP2", "IIR1", "IIR1"}, {"RX3 MIX1 INP2", "IIR2", "IIR2"}, + {"RX3 MIX1 INP3", "RX1", "I2S RX1"}, + {"RX3 MIX1 INP3", "RX2", "I2S RX2"}, + {"RX3 MIX1 INP3", "RX3", "I2S RX3"}, {"RX1 MIX2 INP1", "IIR1", "IIR1"}, {"RX2 MIX2 INP1", "IIR1", "IIR1"}, diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 0aed70c4b522..c2ad1b0e4c04 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -12816,8 +12816,16 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("INT0_MI2S_RX", "INT0 MI2S Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT2_MI2S_RX", "INT2 MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT3_MI2S_RX", "INT3 MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT5_MI2S_RX", "INT5 MI2S Playback", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("INT4_MI2S_RX", "INT4 MI2S Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT4_MI2S_TX", "INT4 MI2S Capture", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("QUIN_MI2S_RX", "Quinary MI2S Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0), @@ -12828,6 +12836,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX", "Tertiary MI2S Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT0_MI2S_TX", "INT0 MI2S Capture", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("INT2_MI2S_TX", "INT2 MI2S Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("INT3_MI2S_TX", "INT3 MI2S Capture", @@ -16304,6 +16314,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "PRI_MI2S_RX"}, {"BE_OUT", NULL, "INT0_MI2S_RX"}, {"BE_OUT", NULL, "INT4_MI2S_RX"}, + {"BE_OUT", NULL, "INT2_MI2S_RX"}, + {"BE_OUT", NULL, "INT3_MI2S_RX"}, + {"BE_OUT", NULL, "INT5_MI2S_RX"}, {"BE_OUT", NULL, "INT_BT_SCO_RX"}, {"BE_OUT", NULL, "INT_BT_A2DP_RX"}, {"BE_OUT", NULL, "INT_FM_RX"}, @@ -16348,8 +16361,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_MI2S_TX", NULL, "BE_IN"}, {"PRI_MI2S_TX", NULL, "BE_IN"}, {"TERT_MI2S_TX", NULL, "BE_IN"}, + {"INT0_MI2S_TX", NULL, "BE_IN"}, {"INT2_MI2S_TX", NULL, "BE_IN"}, {"INT3_MI2S_TX", NULL, "BE_IN"}, + {"INT4_MI2S_TX", NULL, "BE_IN"}, {"INT5_MI2S_TX", NULL, "BE_IN"}, {"SEC_MI2S_TX", NULL, "BE_IN"}, {"SENARY_MI2S_TX", NULL, "BE_IN" }, diff --git a/asoc/sdm660-internal.c b/asoc/sdm660-internal.c index 68e6685de47b..e568f5f572e2 100644 --- a/asoc/sdm660-internal.c +++ b/asoc/sdm660-internal.c @@ -1277,6 +1277,9 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); + snd_soc_dapm_sync(dapm); + + dapm = snd_soc_codec_get_dapm(dig_cdc); snd_soc_dapm_ignore_suspend(dapm, "DMIC1"); snd_soc_dapm_ignore_suspend(dapm, "DMIC2"); snd_soc_dapm_ignore_suspend(dapm, "DMIC3"); -- GitLab From 5071ff10c0c4e2a1ff6af0083d210945c0ee7fe3 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Mon, 20 Nov 2017 14:11:24 -0800 Subject: [PATCH 0100/1645] asoc: remove deprecated dummy functions in DAP modules File "msm-ds2-dap-config.c" has corresponding dummy functions defined for all of its functions to avoid compilation error when config flags "CONFIG_DOLBY_LICENSE" and "CONFIG_DOLBY_DS2" are not selected for a target. However, this file will not get compiled when these two flags are not selected. Therefore, those dummy functions are useless and should be removed. Change-Id: Ic53a6a9d87d6fd56560af1aec3dc012d6486b42a Signed-off-by: Xiaoyu Ye --- asoc/msm-ds2-dap-config.c | 143 -------------------------------------- 1 file changed, 143 deletions(-) diff --git a/asoc/msm-ds2-dap-config.c b/asoc/msm-ds2-dap-config.c index 419da8fa20c0..645ecf5cfd2d 100644 --- a/asoc/msm-ds2-dap-config.c +++ b/asoc/msm-ds2-dap-config.c @@ -22,8 +22,6 @@ #include "msm-pcm-routing-v2.h" -#if defined(CONFIG_DOLBY_DS2) || defined(CONFIG_DOLBY_LICENSE) - /* ramp up/down for 30ms */ #define DOLBY_SOFT_VOLUME_PERIOD 40 /* Step value 0ms or 0us */ @@ -2174,144 +2172,3 @@ int msm_ds2_dap_set_custom_stereo_onoff(int port_id, int copp_idx, } return rc; } - -#else - -static int msm_ds2_dap_alloc_and_store_cal_data(int dev_map_idx, int path, - int perf_mode) -{ - return 0; -} - -static int msm_ds2_dap_free_cal_data(int dev_map_idx) -{ - return 0; -} - -static int msm_ds2_dap_send_cal_data(int dev_map_idx) -{ - return 0; -} - -static int msm_ds2_dap_can_enable_module(int32_t module_id) -{ - return 0; -} - -static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) -{ - return 0; -} - -static bool msm_ds2_dap_check_is_param_modified(int32_t *dap_params_modified, - int32_t idx, int32_t commit) -{ - return false; -} - - -static int msm_ds2_dap_map_device_to_dolby_cache_devices(int32_t device_id) -{ - return 0; -} - -static int msm_ds2_dap_update_num_devices(struct dolby_param_data *dolby_data, - int32_t *num_device, int32_t *dev_arr, - int32_t array_size) -{ - return 0; -} - -static int msm_ds2_dap_commit_params(struct dolby_param_data *dolby_data, - int commit) -{ - return 0; -} - -static int msm_ds2_dap_handle_commands(u32 cmd, void *arg) -{ - return 0; -} - -static int msm_ds2_dap_set_param(u32 cmd, void *arg) -{ - return 0; -} - -static int msm_ds2_dap_get_param(u32 cmd, void *arg) -{ - return 0; -} - -static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) -{ - return 0; -} - -static int msm_ds2_dap_send_cached_params(int dev_map_idx, - int commit) -{ - return 0; -} - -static int msm_ds2_dap_set_vspe_vdhe(int dev_map_idx, - bool is_custom_stereo_enabled) -{ - return 0; -} - -static int msm_ds2_dap_param_visualizer_control_get( - u32 cmd, void *arg, - struct msm_pcm_routing_bdai_data *bedais) -{ - return 0; -} - -static int msm_ds2_dap_set_security_control(u32 cmd, void *arg) -{ - return 0; -} - -static int msm_ds2_dap_update_dev_map_port_id(int32_t device_id, int port_id) -{ - return 0; -} - -static int32_t msm_ds2_dap_get_port_id( - int32_t device_id, int32_t be_id) -{ - return 0; -} - -static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) -{ - return 0; -} - -static int msm_ds2_dap_handle_bypass_wait(int port_id, int copp_idx, - int wait_time) -{ - return 0; -} - -static int dap_set_custom_stereo_onoff(int dev_map_idx, - bool is_custom_stereo_enabled) -{ - return 0; -} -int qti_set_custom_stereo_on(int port_id, int copp_idx, - bool is_custom_stereo_on) -{ - return 0; -} -int set_custom_stereo_onoff(int dev_map_idx, - bool is_custom_stereo_enabled) -{ - return 0; -} -int msm_ds2_dap_ioctl_shared(struct snd_hwdep *hw, struct file *file, - u32 cmd, void *arg) -{ - return 0; -} -#endif /* CONFIG_DOLBY_DS2 || CONFIG_DOLBY_LICENSE */ -- GitLab From 38fdba57ef84a4607a02b0de3c873d66ef87c7c8 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Tue, 17 Oct 2017 22:28:08 -0700 Subject: [PATCH 0101/1645] ASoC: sdm845: update MI2S supported sampling rates Update MI2S supported sampling rates in machine driver to match the CPU DAI driver. Change-Id: If6145e9f18182ab4621ffcd14716039fcc1bef6f Signed-off-by: Xiaoyu Ye --- asoc/sdm845.c | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/asoc/sdm845.c b/asoc/sdm845.c index d75174c3d9ca..ff19b116ac63 100644 --- a/asoc/sdm845.c +++ b/asoc/sdm845.c @@ -425,9 +425,9 @@ static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", "KHZ_48", "KHZ_176P4", "KHZ_352P8"}; static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; -static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16", - "KHZ_32", "KHZ_44P1", "KHZ_48", - "KHZ_96", "KHZ_192"}; +static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_16", + "KHZ_22P05", "KHZ_32", "KHZ_44P1", + "KHZ_48", "KHZ_96", "KHZ_192"}; static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; @@ -2184,26 +2184,32 @@ static int mi2s_get_sample_rate_val(int sample_rate) case SAMPLING_RATE_8KHZ: sample_rate_val = 0; break; - case SAMPLING_RATE_16KHZ: + case SAMPLING_RATE_11P025KHZ: sample_rate_val = 1; break; - case SAMPLING_RATE_32KHZ: + case SAMPLING_RATE_16KHZ: sample_rate_val = 2; break; - case SAMPLING_RATE_44P1KHZ: + case SAMPLING_RATE_22P05KHZ: sample_rate_val = 3; break; - case SAMPLING_RATE_48KHZ: + case SAMPLING_RATE_32KHZ: sample_rate_val = 4; break; - case SAMPLING_RATE_96KHZ: + case SAMPLING_RATE_44P1KHZ: sample_rate_val = 5; break; - case SAMPLING_RATE_192KHZ: + case SAMPLING_RATE_48KHZ: sample_rate_val = 6; break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; default: - sample_rate_val = 4; + sample_rate_val = 6; break; } return sample_rate_val; @@ -2218,21 +2224,27 @@ static int mi2s_get_sample_rate(int value) sample_rate = SAMPLING_RATE_8KHZ; break; case 1: - sample_rate = SAMPLING_RATE_16KHZ; + sample_rate = SAMPLING_RATE_11P025KHZ; break; case 2: - sample_rate = SAMPLING_RATE_32KHZ; + sample_rate = SAMPLING_RATE_16KHZ; break; case 3: - sample_rate = SAMPLING_RATE_44P1KHZ; + sample_rate = SAMPLING_RATE_22P05KHZ; break; case 4: - sample_rate = SAMPLING_RATE_48KHZ; + sample_rate = SAMPLING_RATE_32KHZ; break; case 5: - sample_rate = SAMPLING_RATE_96KHZ; + sample_rate = SAMPLING_RATE_44P1KHZ; break; case 6: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 8: sample_rate = SAMPLING_RATE_192KHZ; break; default: -- GitLab From 9326b2df53c2f21d560941c5e2a1a648477d4136 Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Fri, 27 Oct 2017 09:27:29 +0530 Subject: [PATCH 0102/1645] asoc: codecs: disable analog codec static supplies during suspend Disable regulator supplies of analog codec during suspend to reduce power consumption. CRs-Fixed: 2132296 Change-Id: Ia4b690f01e83e929f8bf4d279454e2ff2e8655a2 Signed-off-by: Rohit kumar --- asoc/codecs/sdm660_cdc/msm-analog-cdc.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c index d83d15a3b1cc..35e00a3930bf 100644 --- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c @@ -4208,7 +4208,7 @@ static int msm_anlg_cdc_enable_static_supplies_to_optimum( struct sdm660_cdc_pdata *pdata) { int i; - int ret = 0; + int ret = 0, rc = 0; for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { if (pdata->regulator[i].ondemand) @@ -4217,6 +4217,12 @@ static int msm_anlg_cdc_enable_static_supplies_to_optimum( sdm660_cdc->supplies[i].consumer) <= 0) continue; + rc = regulator_enable(sdm660_cdc->supplies[i].consumer); + if (rc) { + dev_err(sdm660_cdc->dev, "Failed to enable %s: %d\n", + sdm660_cdc->supplies[i].supply, rc); + break; + } ret = regulator_set_voltage( sdm660_cdc->supplies[i].consumer, pdata->regulator[i].min_uv, @@ -4233,7 +4239,10 @@ static int msm_anlg_cdc_enable_static_supplies_to_optimum( sdm660_cdc->supplies[i].supply); } - return ret; + while (rc && i--) + if (!pdata->regulator[i].ondemand) + regulator_disable(sdm660_cdc->supplies[i].consumer); + return rc; } static int msm_anlg_cdc_disable_static_supplies_to_optimum( @@ -4252,7 +4261,12 @@ static int msm_anlg_cdc_disable_static_supplies_to_optimum( regulator_set_voltage(sdm660_cdc->supplies[i].consumer, 0, pdata->regulator[i].max_uv); regulator_set_load(sdm660_cdc->supplies[i].consumer, 0); - dev_dbg(sdm660_cdc->dev, "Regulator %s set optimum mode\n", + ret = regulator_disable(sdm660_cdc->supplies[i].consumer); + if (ret) + dev_err(sdm660_cdc->dev, "Failed to disable %s: %d\n", + sdm660_cdc->supplies[i].supply, ret); + + dev_dbg(sdm660_cdc->dev, "Regulator %s disable\n", sdm660_cdc->supplies[i].supply); } @@ -4421,7 +4435,7 @@ static int msm_anlg_cdc_enable_static_supplies( sdm660_cdc->supplies[i].supply); } - while (ret && --i) + while (ret && i--) if (!pdata->regulator[i].ondemand) regulator_disable(sdm660_cdc->supplies[i].consumer); return ret; -- GitLab From 66f1f21285f20711a4f6917dd562906f8d79ea1a Mon Sep 17 00:00:00 2001 From: Preetam Singh Ranawat Date: Tue, 5 Dec 2017 15:30:24 +0530 Subject: [PATCH 0103/1645] asoc: add multiple sampling rates support for a2dp Add support of 44.1Khz, 88.2Khz and 96Khz over split-a2dp path. CRs-Fixed: 2153696 Change-Id: I69f20c7a9c465c974e847f42d754c69511138fbb Signed-off-by: Preetam Singh Ranawat --- asoc/sdm660-external.c | 25 ++++++++++++++++++++++++- asoc/sdm660-internal.c | 22 +++++++++++++++++++++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/asoc/sdm660-external.c b/asoc/sdm660-external.c index 1c12bfd732cd..b22a365cd4be 100644 --- a/asoc/sdm660-external.c +++ b/asoc/sdm660-external.c @@ -121,7 +121,9 @@ static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_88P2", "KHZ_96", "KHZ_176P4", "KHZ_192", "KHZ_352P8", "KHZ_384"}; static const char *const spk_function_text[] = {"Off", "On"}; -static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_48"}; +static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; static SOC_ENUM_SINGLE_EXT_DECL(spk_func_en, spk_function_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); @@ -312,7 +314,16 @@ static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, * value. */ switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: ucontrol->value.integer.value[0] = 2; break; case SAMPLING_RATE_16KHZ: @@ -338,9 +349,21 @@ static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; break; case 2: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; break; + case 4: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ; + break; case 0: default: slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; diff --git a/asoc/sdm660-internal.c b/asoc/sdm660-internal.c index 68e6685de47b..44a628be3e1f 100644 --- a/asoc/sdm660-internal.c +++ b/asoc/sdm660-internal.c @@ -150,7 +150,9 @@ static const char *const int_mi2s_tx_ch_text[] = {"One", "Two", "Three", "Four"}; static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"}; static const char *const loopback_mclk_text[] = {"DISABLE", "ENABLE"}; -static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_48"}; +static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_sample_rate, int_mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_chs, int_mi2s_ch_text); @@ -835,7 +837,16 @@ static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, * value. */ switch (bt_fm_cfg[BT_SLIM7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: ucontrol->value.integer.value[0] = 2; break; case SAMPLING_RATE_16KHZ: @@ -860,8 +871,17 @@ static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_16KHZ; break; case 2: + bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_48KHZ; break; + case 4: + bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_96KHZ; + break; case 0: default: bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_8KHZ; -- GitLab From 5faacb3a7ee820c82ad76fad94e4f1c2c13169a2 Mon Sep 17 00:00:00 2001 From: Asish Bhattacharya Date: Mon, 4 Dec 2017 17:23:15 +0530 Subject: [PATCH 0104/1645] ASoC: allow drivers to compile both static and dynamic Based on where the code is synced the driver should allow both static and dynamic linked compilation. Also remove __exit for modules loaded from another common init/exit functions. Change-Id: Ib58f152002aba3af4446f9bbd9b82c279212bd0a Signed-off-by: Asish Bhattacharya --- Makefile | 2 +- asoc/Kbuild | 59 ++++++++++++++++++----------- asoc/Makefile | 41 -------------------- asoc/codecs/Kbuild | 55 ++++++++++++++++----------- asoc/codecs/Makefile | 40 ------------------- asoc/codecs/msm_sdw/Kbuild | 30 +++++++++------ asoc/codecs/msm_sdw/Makefile | 2 - asoc/codecs/sdm660_cdc/Kbuild | 32 +++++++++------- asoc/codecs/sdm660_cdc/Makefile | 4 -- asoc/codecs/wcd934x/Kbuild | 32 +++++++++------- asoc/codecs/wcd934x/Makefile | 6 --- asoc/msm-compress-q6-v2.c | 2 +- asoc/msm-dai-fe.c | 2 +- asoc/msm-dai-q6-hdmi-v2.c | 2 +- asoc/msm-dai-q6-v2.c | 2 +- asoc/msm-dai-slim.c | 2 +- asoc/msm-dai-stub-v2.c | 2 +- asoc/msm-lsm-client.c | 2 +- asoc/msm-pcm-afe-v2.c | 2 +- asoc/msm-pcm-dtmf-v2.c | 2 +- asoc/msm-pcm-host-voice-v2.c | 2 +- asoc/msm-pcm-hostless.c | 2 +- asoc/msm-pcm-loopback-v2.c | 2 +- asoc/msm-pcm-q6-noirq.c | 2 +- asoc/msm-pcm-q6-v2.c | 2 +- asoc/msm-pcm-routing-v2.c | 2 +- asoc/msm-pcm-voice-v2.c | 2 +- asoc/msm-pcm-voip-v2.c | 2 +- asoc/msm-transcode-loopback-q6-v2.c | 2 +- config/sdm670auto_static.conf | 50 ++++++++++++++++++++++++ dsp/Kbuild | 47 ++++++++++++++--------- dsp/Makefile | 10 ----- dsp/adsp_err.c | 2 +- dsp/audio_calibration.c | 2 +- dsp/audio_slimslave.c | 4 +- dsp/avtimer.c | 2 +- dsp/codecs/Kbuild | 39 +++++++++---------- dsp/codecs/Makefile | 5 --- dsp/codecs/aac_in.c | 2 +- dsp/codecs/amrnb_in.c | 2 +- dsp/codecs/amrwb_in.c | 2 +- dsp/codecs/audio_aac.c | 2 +- dsp/codecs/audio_alac.c | 2 +- dsp/codecs/audio_amrnb.c | 2 +- dsp/codecs/audio_amrwb.c | 2 +- dsp/codecs/audio_amrwbplus.c | 2 +- dsp/codecs/audio_ape.c | 2 +- dsp/codecs/audio_evrc.c | 2 +- dsp/codecs/audio_g711alaw.c | 2 +- dsp/codecs/audio_g711mlaw.c | 2 +- dsp/codecs/audio_hwacc_effects.c | 2 +- dsp/codecs/audio_mp3.c | 2 +- dsp/codecs/audio_multi_aac.c | 2 +- dsp/codecs/audio_qcelp.c | 2 +- dsp/codecs/audio_wma.c | 2 +- dsp/codecs/audio_wmapro.c | 2 +- dsp/codecs/evrc_in.c | 2 +- dsp/codecs/g711alaw_in.c | 2 +- dsp/codecs/g711mlaw_in.c | 2 +- dsp/codecs/qcelp_in.c | 2 +- dsp/msm_audio_ion.c | 2 +- dsp/q6adm.c | 2 +- dsp/q6afe.c | 2 +- dsp/q6asm.c | 2 +- dsp/q6core.c | 2 +- dsp/q6lsm.c | 2 +- dsp/q6voice.c | 2 +- dsp/rtac.c | 2 +- ipc/Kbuild | 53 ++++++++++++++++---------- ipc/Makefile | 3 -- soc/Kbuild | 37 ++++++++++-------- soc/Makefile | 6 --- 72 files changed, 332 insertions(+), 327 deletions(-) delete mode 100644 asoc/Makefile delete mode 100644 asoc/codecs/Makefile delete mode 100644 asoc/codecs/msm_sdw/Makefile delete mode 100644 asoc/codecs/sdm660_cdc/Makefile delete mode 100644 asoc/codecs/wcd934x/Makefile create mode 100644 config/sdm670auto_static.conf delete mode 100644 dsp/Makefile delete mode 100644 dsp/codecs/Makefile delete mode 100644 ipc/Makefile delete mode 100644 soc/Makefile diff --git a/Makefile b/Makefile index de65a18f0478..2848799ae3a6 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ include $(srctree)/techpack/audio/config/sdm845auto.conf export endif ifeq ($(CONFIG_ARCH_SDM670), y) -include $(srctree)/techpack/audio/config/sdm670auto.conf +include $(srctree)/techpack/audio/config/sdm670auto_static.conf export endif ifeq ($(CONFIG_ARCH_SDXPOORWILLS), y) diff --git a/asoc/Kbuild b/asoc/Kbuild index eb32e8841c22..e5b8514c9db7 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -1,22 +1,32 @@ # We can build either as part of a standalone Kernel build or as # an external module. Determine which mechanism is being used -KERNEL_BUILD := 0 +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif -ifeq ($(KERNEL_BUILD), 0) +ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SDM845), y) include $(AUDIO_ROOT)/config/sdm845auto.conf export + INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h endif ifeq ($(CONFIG_ARCH_SDM670), y) include $(AUDIO_ROOT)/config/sdm670auto.conf export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif endif - # As per target team, build is done as follows: # Defconfig : build with default flags # Slub : defconfig + CONFIG_SLUB_DEBUG := y + @@ -45,31 +55,31 @@ COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) # for SDM6xx sound card driver -ifeq ($(CONFIG_SND_SOC_SDM670), m) +ifdef CONFIG_SND_SOC_SDM670 MACHINE_OBJS += sdm660-common.o endif # for SDM6xx sound card driver -ifeq ($(CONFIG_SND_SOC_INT_CODEC), m) +ifdef CONFIG_SND_SOC_INT_CODEC MACHINE_OBJS += sdm660-internal.o endif # for SDM6xx sound card driver -ifeq ($(CONFIG_SND_SOC_EXT_CODEC), m) +ifdef CONFIG_SND_SOC_EXT_CODEC MACHINE_OBJS += sdm660-external.o MACHINE_OBJS += sdm660-ext-dai-links.o endif # for SDM845 sound card driver -ifeq ($(CONFIG_SND_SOC_MACHINE_SDM845), m) +ifdef CONFIG_SND_SOC_MACHINE_SDM845 MACHINE_OBJS += sdm845.o endif -ifeq ($(CONFIG_SND_SOC_CPE), m) +ifdef CONFIG_SND_SOC_CPE CPE_LSM_OBJS += msm-cpe-lsm.o endif -ifeq ($(CONFIG_SND_SOC_QDSP6V2), m) +ifdef CONFIG_SND_SOC_QDSP6V2 PLATFORM_OBJS += msm-audio-effects-q6-v2.o PLATFORM_OBJS += msm-compress-q6-v2.o PLATFORM_OBJS += msm-dai-fe.o @@ -77,7 +87,6 @@ ifeq ($(CONFIG_SND_SOC_QDSP6V2), m) PLATFORM_OBJS += msm-dai-q6-v2.o PLATFORM_OBJS += msm-dai-slim.o PLATFORM_OBJS += msm-dai-stub-v2.o - PLATFORM_OBJS += msm-ds2-dap-config.o PLATFORM_OBJS += msm-lsm-client.o PLATFORM_OBJS += msm-pcm-afe-v2.o PLATFORM_OBJS += msm-pcm-dtmf-v2.o @@ -86,30 +95,32 @@ ifeq ($(CONFIG_SND_SOC_QDSP6V2), m) PLATFORM_OBJS += msm-pcm-loopback-v2.o PLATFORM_OBJS += msm-pcm-q6-noirq.o PLATFORM_OBJS += msm-pcm-q6-v2.o - PLATFORM_OBJS += msm-pcm-routing-devdep.o PLATFORM_OBJS += msm-pcm-routing-v2.o PLATFORM_OBJS += msm-pcm-voice-v2.o PLATFORM_OBJS += msm-pcm-voip-v2.o - PLATFORM_OBJS += msm-qti-pp-config.o PLATFORM_OBJS += msm-transcode-loopback-q6-v2.o PLATFORM_OBJS += platform_init.o endif +ifdef CONFIG_DOLBY_DS2 + PLATFORM_OBJS += msm-ds2-dap-config.o +endif +ifdef CONFIG_DOLBY_LICENSE + PLATFORM_OBJS += msm-ds2-dap-config.o +endif +ifdef CONFIG_SND_HWDEP + PLATFORM_OBJS += msm-pcm-routing-devdep.o +endif +ifdef CONFIG_QTI_PP + PLATFORM_OBJS += msm-qti-pp-config.o +endif LINUX_INC += -Iinclude/linux -INCS := $(COMMON_INC) \ +INCS += $(COMMON_INC) \ $(UAPI_INC) -ifeq ($(CONFIG_ARCH_SDM845), y) -INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h -endif -ifeq ($(CONFIG_ARCH_SDM670), y) -INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h -endif - EXTRA_CFLAGS += $(INCS) - CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_LITTLE_BIT_ENDIAN \ -DDOT11F_LITTLE_ENDIAN_HOST \ @@ -135,12 +146,16 @@ ifeq ($(call cc-option-yn, -Wheader-guard),y) EXTRA_CFLAGS += -Wheader-guard endif - +ifeq ($(KERNEL_BUILD), 0) KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers +endif +ifeq ($(KERNEL_BUILD), 1) + obj-y += codecs/ +endif # Module information used by KBuild framework obj-$(CONFIG_SND_SOC_QDSP6V2) += platform_dlkm.o platform_dlkm-y := $(PLATFORM_OBJS) diff --git a/asoc/Makefile b/asoc/Makefile deleted file mode 100644 index 4d3839de9556..000000000000 --- a/asoc/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -# MSM Machine Support - -snd-soc-hostless-pcm-objs := msm-pcm-hostless.o -obj-$(CONFIG_SND_SOC_MSM_HOSTLESS_PCM) += snd-soc-hostless-pcm.o - - -snd-soc-qdsp6v2-objs := msm-dai-fe.o -obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o - -#for CPE drivers -snd-soc-cpe-objs := msm-cpe-lsm.o -obj-$(CONFIG_SND_SOC_CPE) += snd-soc-cpe.o - -# for MSM8998 sound card driver -snd-soc-msm8998-objs := msm8998.o -obj-$(CONFIG_SND_SOC_MACHINE_MSM8998) += snd-soc-msm8998.o - -# for SDM670 sound card driver -snd-soc-sdm670-objs := sdm660-common.o sdm660-internal.o sdm660-external.o sdm660-ext-dai-links.o -obj-$(CONFIG_SND_SOC_SDM670) += snd-soc-sdm670.o - -# for SDM845 sound card driver -snd-soc-sdm845-objs := sdm845.o -obj-$(CONFIG_SND_SOC_MACHINE_SDM845) += snd-soc-sdm845.o - -snd-soc-qdsp6v2-objs += msm-dai-q6-v2.o msm-pcm-q6-v2.o \ - msm-pcm-routing-v2.o msm-compress-q6-v2.o \ - msm-pcm-afe-v2.o msm-pcm-voip-v2.o \ - msm-pcm-voice-v2.o msm-dai-q6-hdmi-v2.o \ - msm-lsm-client.o msm-pcm-host-voice-v2.o \ - msm-audio-effects-q6-v2.o msm-pcm-loopback-v2.o \ - msm-dai-slim.o msm-transcode-loopback-q6-v2.o msm-pcm-q6-noirq.o -obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o msm-pcm-dtmf-v2.o \ - msm-dai-stub-v2.o -obj-$(CONFIG_SND_HWDEP) += msm-pcm-routing-devdep.o -obj-$(CONFIG_DOLBY_DAP) += msm-dolby-dap-config.o -obj-$(CONFIG_DOLBY_DS2) += msm-ds2-dap-config.o -obj-$(CONFIG_DOLBY_LICENSE) += msm-ds2-dap-config.o -obj-$(CONFIG_DTS_SRS_TM) += msm-dts-srs-tm-config.o -obj-$(CONFIG_QTI_PP) += msm-qti-pp-config.o -obj-y += codecs/ diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 83d4da441d41..1cbd20e459f7 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -1,22 +1,31 @@ # We can build either as part of a standalone Kernel build or as # an external module. Determine which mechanism is being used -KERNEL_BUILD := 0 - +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif -ifeq ($(KERNEL_BUILD), 0) +ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SDM845), y) include $(AUDIO_ROOT)/config/sdm845auto.conf export + INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h endif ifeq ($(CONFIG_ARCH_SDM670), y) include $(AUDIO_ROOT)/config/sdm670auto.conf export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif endif - # As per target team, build is done as follows: # Defconfig : build with default flags # Slub : defconfig + CONFIG_SLUB_DEBUG := y + @@ -42,7 +51,7 @@ COMMON_DIR := include COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) ############ ASoC Codecs ############ -ifeq ($(CONFIG_WCD9XXX_CODEC_CORE), m) +ifdef CONFIG_WCD9XXX_CODEC_CORE CORE_OBJS += wcd9xxx-rst.o CORE_OBJS += wcd9xxx-core-init.o CORE_OBJS += wcd9xxx-core.o @@ -57,7 +66,7 @@ ifeq ($(CONFIG_WCD9XXX_CODEC_CORE), m) CORE_OBJS += wcd934x/wcd934x-tables.o endif -ifeq ($(CONFIG_SND_SOC_WCD9XXX_V2), m) +ifdef CONFIG_SND_SOC_WCD9XXX_V2 WCD9XXX_OBJS += wcd9xxx-common-v2.o WCD9XXX_OBJS += wcd9xxx-resmgr-v2.o WCD9XXX_OBJS += wcdcal-hwdep.o @@ -67,56 +76,50 @@ ifeq ($(CONFIG_SND_SOC_WCD9XXX_V2), m) WCD9XXX_OBJS += audio-ext-clk-up.o endif -ifeq ($(CONFIG_SND_SOC_WCD9335), m) +ifdef CONFIG_SND_SOC_WCD9335 WCD9335_OBJS += wcd9335.o endif -ifeq ($(CONFIG_SND_SOC_WSA881X), m) +ifdef CONFIG_SND_SOC_WSA881X WSA881X_OBJS += wsa881x.o WSA881X_OBJS += wsa881x-tables.o WSA881X_OBJS += wsa881x-regmap.o WSA881X_OBJS += wsa881x-temp-sensor.o endif -ifeq ($(CONFIG_SND_SOC_MSM_STUB), m) +ifdef CONFIG_SND_SOC_MSM_STUB STUB_OBJS += msm_stub.o endif -ifeq ($(CONFIG_SND_SOC_WCD_SPI), m) +ifdef CONFIG_SND_SOC_WCD_SPI SPI_OBJS += wcd-spi.o endif -ifeq ($(CONFIG_SND_SOC_WCD_CPE), m) +ifdef CONFIG_SND_SOC_WCD_CPE WCD_CPE_OBJS += wcd_cpe_core.o WCD_CPE_OBJS += wcd_cpe_services.o endif -ifeq ($(CONFIG_SND_SOC_WCD_MBHC), m) +ifdef CONFIG_SND_SOC_WCD_MBHC MBHC_OBJS += wcd-mbhc-v2.o endif -ifeq ($(CONFIG_SND_SOC_WCD_MBHC_ADC), m) +ifdef CONFIG_SND_SOC_WCD_MBHC_ADC MBHC_OBJS += wcd-mbhc-adc.o endif -ifeq ($(CONFIG_SND_SOC_WCD_MBHC_LEGACY), m) +ifdef CONFIG_SND_SOC_WCD_MBHC_LEGACY MBHC_OBJS += wcd-mbhc-legacy.o endif -ifeq ($(CONFIG_SND_SOC_MSM_HDMI_CODEC_RX), m) +ifdef CONFIG_SND_SOC_MSM_HDMI_CODEC_RX HDMICODEC_OBJS += msm_hdmi_codec_rx.o endif LINUX_INC += -Iinclude/linux -INCS := $(COMMON_INC) \ +INCS += $(COMMON_INC) \ $(UAPI_INC) -ifeq ($(CONFIG_ARCH_SDM845), y) -INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h -endif -ifeq ($(CONFIG_ARCH_SDM670), y) -INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h -endif EXTRA_CFLAGS += $(INCS) @@ -147,8 +150,16 @@ EXTRA_CFLAGS += -Wheader-guard endif +ifeq ($(KERNEL_BUILD), 0) KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + +ifeq ($(KERNEL_BUILD), 1) + obj-y += wcd934x/ + obj-y += sdm660_cdc/ + obj-y += msm_sdw/ +endif # Module information used by KBuild framework obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd_core_dlkm.o wcd_core_dlkm-y := $(CORE_OBJS) diff --git a/asoc/codecs/Makefile b/asoc/codecs/Makefile deleted file mode 100644 index 9b02c8a51cd7..000000000000 --- a/asoc/codecs/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -snd-soc-wcd9xxx-objs := wcd9xxx-common-v2.o wcd9xxx-resmgr-v2.o \ - wcdcal-hwdep.o wcd9xxx-soc-init.o wcd-dsp-utils.o \ - wcd-dsp-mgr.o audio-ext-clk-up.o -snd-soc-wcd-cpe-objs := wcd_cpe_services.o wcd_cpe_core.o -snd-soc-wsa881x-objs := wsa881x.o wsa881x-tables.o wsa881x-regmap.o wsa881x-temp-sensor.o -snd-soc-wcd-mbhc-objs := wcd-mbhc-v2.o -ifneq (,$(filter $(CONFIG_SND_SOC_WCD_MBHC_LEGACY),y m)) - snd-soc-wcd-mbhc-objs += wcd-mbhc-legacy.o -endif -ifneq (,$(filter $(CONFIG_SND_SOC_WCD_MBHC_ADC),y m)) - snd-soc-wcd-mbhc-objs += wcd-mbhc-adc.o -endif -snd-soc-wcd-spi-objs := wcd-spi.o -snd-soc-wcd9335-objs := wcd9335.o -snd-soc-wcd-cpe-objs := wcd_cpe_services.o wcd_cpe_core.o - -obj-$(CONFIG_SND_SOC_WCD9335) += snd-soc-wcd9335.o -obj-$(CONFIG_SND_SOC_WCD_CPE) += snd-soc-wcd-cpe.o -obj-$(CONFIG_SND_SOC_WCD934X) += wcd934x/ -obj-$(CONFIG_SND_SOC_SDM660_CDC) += sdm660_cdc/ -obj-$(CONFIG_SND_SOC_MSM_SDW) += msm_sdw/ - -obj-$(CONFIG_SND_SOC_WCD9XXX_V2) += snd-soc-wcd9xxx.o -obj-$(CONFIG_SND_SOC_WCD_MBHC) += snd-soc-wcd-mbhc.o -obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o -obj-$(CONFIG_SND_SOC_WCD_SPI) += snd-soc-wcd-spi.o - -snd-soc-msm-stub-objs := msm_stub.o -obj-$(CONFIG_SND_SOC_MSM_STUB) += snd-soc-msm-stub.o - -wcd-core-objs := wcd9xxx-rst.o wcd9xxx-core-init.o \ - wcd9xxx-core.o wcd9xxx-irq.o \ - wcd9xxx-slimslave.o wcd9xxx-utils.o \ - wcd9335-regmap.o wcd9335-tables.o \ - msm-cdc-pinctrl.o msm-cdc-supply.o -wcd-core-objs += wcd934x/wcd934x-regmap.o -wcd-core-objs += wcd934x/wcd934x-tables.o - -obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd-core.o -obj-$(CONFIG_SND_SOC_MSM_HDMI_CODEC_RX) += msm_hdmi_codec_rx.o diff --git a/asoc/codecs/msm_sdw/Kbuild b/asoc/codecs/msm_sdw/Kbuild index a55948e21495..e2b5bc319516 100644 --- a/asoc/codecs/msm_sdw/Kbuild +++ b/asoc/codecs/msm_sdw/Kbuild @@ -1,22 +1,32 @@ # We can build either as part of a standalone Kernel build or as # an external module. Determine which mechanism is being used -KERNEL_BUILD := 0 +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif -ifeq ($(KERNEL_BUILD), 0) +ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SDM845), y) include $(AUDIO_ROOT)/config/sdm845auto.conf export + INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h endif ifeq ($(CONFIG_ARCH_SDM670), y) include $(AUDIO_ROOT)/config/sdm670auto.conf export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif endif - # As per target team, build is done as follows: # Defconfig : build with default flags # Slub : defconfig + CONFIG_SLUB_DEBUG := y + @@ -44,7 +54,7 @@ COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) ############ MSM Soundwire ############ # for MSM Soundwire Codec -ifeq ($(CONFIG_SND_SOC_MSM_SDW), m) +ifdef CONFIG_SND_SOC_MSM_SDW MSM_SDW_OBJS += msm_sdw_cdc.o MSM_SDW_OBJS += msm_sdw_regmap.o MSM_SDW_OBJS += msm-sdw-tables.o @@ -53,16 +63,9 @@ endif LINUX_INC += -Iinclude/linux -INCS := $(COMMON_INC) \ +INCS += $(COMMON_INC) \ $(UAPI_INC) -ifeq ($(CONFIG_ARCH_SDM845), y) -INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h -endif -ifeq ($(CONFIG_ARCH_SDM670), y) -INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h -endif - EXTRA_CFLAGS += $(INCS) @@ -91,11 +94,14 @@ ifeq ($(call cc-option-yn, -Wheader-guard),y) EXTRA_CFLAGS += -Wheader-guard endif +ifeq ($(KERNEL_BUILD), 0) KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + # Module information used by KBuild framework obj-$(CONFIG_SND_SOC_MSM_SDW) += msm_sdw_dlkm.o msm_sdw_dlkm-y := $(MSM_SDW_OBJS) diff --git a/asoc/codecs/msm_sdw/Makefile b/asoc/codecs/msm_sdw/Makefile deleted file mode 100644 index 9518f4db5b18..000000000000 --- a/asoc/codecs/msm_sdw/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -snd-soc-msm-sdw-objs := msm_sdw_cdc.o msm_sdw_regmap.o msm-sdw-tables.o msm_sdw_cdc_utils.o -obj-$(CONFIG_SND_SOC_MSM_SDW) += snd-soc-msm-sdw.o diff --git a/asoc/codecs/sdm660_cdc/Kbuild b/asoc/codecs/sdm660_cdc/Kbuild index c1777ee53372..56122c1e9898 100644 --- a/asoc/codecs/sdm660_cdc/Kbuild +++ b/asoc/codecs/sdm660_cdc/Kbuild @@ -1,22 +1,32 @@ # We can build either as part of a standalone Kernel build or as # an external module. Determine which mechanism is being used -KERNEL_BUILD := 0 +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif -ifeq ($(KERNEL_BUILD), 0) +ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SDM845), y) include $(AUDIO_ROOT)/config/sdm845auto.conf export + INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h endif ifeq ($(CONFIG_ARCH_SDM670), y) include $(AUDIO_ROOT)/config/sdm670auto.conf export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif endif - # As per target team, build is done as follows: # Defconfig : build with default flags # Slub : defconfig + CONFIG_SLUB_DEBUG := y + @@ -44,27 +54,20 @@ COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) ############ SDM660_CDC ############ # for SDM660_CDC Codec -ifeq ($(CONFIG_SND_SOC_ANALOG_CDC), m) +ifdef CONFIG_SND_SOC_ANALOG_CDC ANALOG_CDC_OBJS += msm-analog-cdc.o ANALOG_CDC_OBJS += sdm660-cdc-irq.o endif -ifeq ($(CONFIG_SND_SOC_DIGITAL_CDC), m) +ifdef CONFIG_SND_SOC_DIGITAL_CDC DIGITAL_CDC_OBJS += msm-digital-cdc.o DIGITAL_CDC_OBJS += msm-digital-cdc-regmap.o endif LINUX_INC += -Iinclude/linux -INCS := $(COMMON_INC) \ +INCS += $(COMMON_INC) \ $(UAPI_INC) -ifeq ($(CONFIG_ARCH_SDM845), y) -INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h -endif -ifeq ($(CONFIG_ARCH_SDM670), y) -INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h -endif - EXTRA_CFLAGS += $(INCS) @@ -94,11 +97,14 @@ EXTRA_CFLAGS += -Wheader-guard endif +ifeq ($(KERNEL_BUILD), 0) KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + # Module information used by KBuild framework obj-$(CONFIG_SND_SOC_ANALOG_CDC) += analog_cdc_dlkm.o analog_cdc_dlkm-y := $(ANALOG_CDC_OBJS) diff --git a/asoc/codecs/sdm660_cdc/Makefile b/asoc/codecs/sdm660_cdc/Makefile deleted file mode 100644 index 0ebf40717dd7..000000000000 --- a/asoc/codecs/sdm660_cdc/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -snd-soc-analog-cdc-objs := sdm660-cdc-irq.o msm-analog-cdc.o -snd-soc-digital-cdc-objs := msm-digital-cdc.o msm-digital-cdc-regmap.o -obj-$(CONFIG_SND_SOC_ANALOG_CDC) += snd-soc-analog-cdc.o -obj-$(CONFIG_SND_SOC_DIGITAL_CDC) += snd-soc-digital-cdc.o diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index 6bc854c84787..e46e39d20cf6 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -1,22 +1,33 @@ # We can build either as part of a standalone Kernel build or as # an external module. Determine which mechanism is being used -KERNEL_BUILD := 0 +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif -ifeq ($(KERNEL_BUILD), 0) + +ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SDM845), y) include $(AUDIO_ROOT)/config/sdm845auto.conf export + INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h endif ifeq ($(CONFIG_ARCH_SDM670), y) include $(AUDIO_ROOT)/config/sdm670auto.conf export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif endif - # As per target team, build is done as follows: # Defconfig : build with default flags # Slub : defconfig + CONFIG_SLUB_DEBUG := y + @@ -44,7 +55,7 @@ COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) ############ WCD934X ############ # for WCD934X Codec -ifeq ($(CONFIG_SND_SOC_WCD934X), m) +ifdef CONFIG_SND_SOC_WCD934X WCD934X_OBJS += wcd934x.o WCD934X_OBJS += wcd934x-dsp-cntl.o WCD934X_OBJS += wcd934x-mbhc.o @@ -53,16 +64,9 @@ endif LINUX_INC += -Iinclude/linux -INCS := $(COMMON_INC) \ +INCS += $(COMMON_INC) \ $(UAPI_INC) -ifeq ($(CONFIG_ARCH_SDM845), y) -INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h -endif -ifeq ($(CONFIG_ARCH_SDM670), y) -INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h -endif - EXTRA_CFLAGS += $(INCS) @@ -91,12 +95,14 @@ ifeq ($(call cc-option-yn, -Wheader-guard),y) EXTRA_CFLAGS += -Wheader-guard endif - +ifeq ($(KERNEL_BUILD), 0) KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + # Module information used by KBuild framework obj-$(CONFIG_SND_SOC_WCD934X) += wcd934x_dlkm.o wcd934x_dlkm-y := $(WCD934X_OBJS) diff --git a/asoc/codecs/wcd934x/Makefile b/asoc/codecs/wcd934x/Makefile deleted file mode 100644 index 12781f6d4556..000000000000 --- a/asoc/codecs/wcd934x/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# Makefile for wcd934x codec driver. -# -snd-soc-wcd934x-objs := wcd934x.o wcd934x-dsp-cntl.o \ - wcd934x-mbhc.o wcd934x-dsd.o -obj-$(CONFIG_SND_SOC_WCD934X) += snd-soc-wcd934x.o diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 1df13afd82f6..b5e28275387f 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -4546,7 +4546,7 @@ int __init msm_compress_dsp_init(void) return platform_driver_register(&msm_compr_driver); } -void __exit msm_compress_dsp_exit(void) +void msm_compress_dsp_exit(void) { platform_driver_unregister(&msm_compr_driver); } diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index 9160a2d728b4..72883eb80641 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -2576,7 +2576,7 @@ int __init msm_fe_dai_init(void) return platform_driver_register(&msm_fe_dai_driver); } -void __exit msm_fe_dai_exit(void) +void msm_fe_dai_exit(void) { platform_driver_unregister(&msm_fe_dai_driver); } diff --git a/asoc/msm-dai-q6-hdmi-v2.c b/asoc/msm-dai-q6-hdmi-v2.c index eb9f5f5de8ad..c061c08b2d02 100644 --- a/asoc/msm-dai-q6-hdmi-v2.c +++ b/asoc/msm-dai-q6-hdmi-v2.c @@ -543,7 +543,7 @@ int __init msm_dai_q6_hdmi_init(void) return platform_driver_register(&msm_dai_q6_hdmi_driver); } -void __exit msm_dai_q6_hdmi_exit(void) +void msm_dai_q6_hdmi_exit(void) { platform_driver_unregister(&msm_dai_q6_hdmi_driver); } diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index af288f1cd8ad..5156e0d2d4de 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -8928,7 +8928,7 @@ int __init msm_dai_q6_init(void) return rc; } -void __exit msm_dai_q6_exit(void) +void msm_dai_q6_exit(void) { platform_driver_unregister(&msm_dai_q6_tdm_driver); platform_driver_unregister(&msm_dai_q6_spdif_driver); diff --git a/asoc/msm-dai-slim.c b/asoc/msm-dai-slim.c index 427fd6ce8c43..e8bdf13fdc6c 100644 --- a/asoc/msm-dai-slim.c +++ b/asoc/msm-dai-slim.c @@ -653,7 +653,7 @@ int __init msm_dai_slim_init(void) return rc; } -void __exit msm_dai_slim_exit(void) +void msm_dai_slim_exit(void) { slim_driver_unregister(&msm_dai_slim_driver); } diff --git a/asoc/msm-dai-stub-v2.c b/asoc/msm-dai-stub-v2.c index d4178c895cc4..c8b6b7736631 100644 --- a/asoc/msm-dai-stub-v2.c +++ b/asoc/msm-dai-stub-v2.c @@ -379,7 +379,7 @@ int __init msm_dai_stub_init(void) return rc; } -void __exit msm_dai_stub_exit(void) +void msm_dai_stub_exit(void) { pr_debug("%s:\n", __func__); diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 15cdfb155f36..f6a56985080a 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -2406,7 +2406,7 @@ int __init msm_lsm_client_init(void) return platform_driver_register(&msm_lsm_driver); } -void __exit msm_lsm_client_exit(void) +void msm_lsm_client_exit(void) { platform_driver_unregister(&msm_lsm_driver); } diff --git a/asoc/msm-pcm-afe-v2.c b/asoc/msm-pcm-afe-v2.c index f700f0bf8a10..77eecb23d26f 100644 --- a/asoc/msm-pcm-afe-v2.c +++ b/asoc/msm-pcm-afe-v2.c @@ -910,7 +910,7 @@ int __init msm_pcm_afe_init(void) return platform_driver_register(&msm_afe_driver); } -void __exit msm_pcm_afe_exit(void) +void msm_pcm_afe_exit(void) { pr_debug("%s\n", __func__); platform_driver_unregister(&msm_afe_driver); diff --git a/asoc/msm-pcm-dtmf-v2.c b/asoc/msm-pcm-dtmf-v2.c index 7bc823bebf7b..9953eebcef6b 100644 --- a/asoc/msm-pcm-dtmf-v2.c +++ b/asoc/msm-pcm-dtmf-v2.c @@ -585,7 +585,7 @@ int __init msm_pcm_dtmf_init(void) return platform_driver_register(&msm_pcm_driver); } -void __exit msm_pcm_dtmf_exit(void) +void msm_pcm_dtmf_exit(void) { platform_driver_unregister(&msm_pcm_driver); } diff --git a/asoc/msm-pcm-host-voice-v2.c b/asoc/msm-pcm-host-voice-v2.c index 0c47ec11338a..fd771df5d3d4 100644 --- a/asoc/msm-pcm-host-voice-v2.c +++ b/asoc/msm-pcm-host-voice-v2.c @@ -1542,7 +1542,7 @@ int __init msm_voice_host_init(void) return platform_driver_register(&msm_pcm_driver); } -void __exit msm_voice_host_exit(void) +void msm_voice_host_exit(void) { platform_driver_unregister(&msm_pcm_driver); } diff --git a/asoc/msm-pcm-hostless.c b/asoc/msm-pcm-hostless.c index 90d76b49f654..e2850a421d67 100644 --- a/asoc/msm-pcm-hostless.c +++ b/asoc/msm-pcm-hostless.c @@ -71,7 +71,7 @@ int __init msm_pcm_hostless_init(void) return platform_driver_register(&msm_pcm_hostless_driver); } -void __exit msm_pcm_hostless_exit(void) +void msm_pcm_hostless_exit(void) { platform_driver_unregister(&msm_pcm_hostless_driver); } diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index e50a00575d95..1c26d1966b24 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -790,7 +790,7 @@ int __init msm_pcm_loopback_init(void) return platform_driver_register(&msm_pcm_driver); } -void __exit msm_pcm_loopback_exit(void) +void msm_pcm_loopback_exit(void) { platform_driver_unregister(&msm_pcm_driver); } diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index 307e7a6fae65..dbc6d33a65be 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -1273,7 +1273,7 @@ int __init msm_pcm_noirq_init(void) return platform_driver_register(&msm_pcm_driver_noirq); } -void __exit msm_pcm_noirq_exit(void) +void msm_pcm_noirq_exit(void) { platform_driver_unregister(&msm_pcm_driver_noirq); } diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 0a0e26d8b0a2..314584e5fc2d 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1873,7 +1873,7 @@ int __init msm_pcm_dsp_init(void) return platform_driver_register(&msm_pcm_driver); } -void __exit msm_pcm_dsp_exit(void) +void msm_pcm_dsp_exit(void) { platform_driver_unregister(&msm_pcm_driver); } diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 0aed70c4b522..c0dc3556fe68 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -17212,7 +17212,7 @@ int __init msm_soc_routing_platform_init(void) return platform_driver_register(&msm_routing_pcm_driver); } -void __exit msm_soc_routing_platform_exit(void) +void msm_soc_routing_platform_exit(void) { msm_routing_delete_cal_data(); memset(&be_dai_name_table, 0, sizeof(be_dai_name_table)); diff --git a/asoc/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c index 7b236b4f0489..b82c5871795d 100644 --- a/asoc/msm-pcm-voice-v2.c +++ b/asoc/msm-pcm-voice-v2.c @@ -770,7 +770,7 @@ int __init msm_pcm_voice_init(void) return platform_driver_register(&msm_pcm_driver); } -void __exit msm_pcm_voice_exit(void) +void msm_pcm_voice_exit(void) { platform_driver_unregister(&msm_pcm_driver); } diff --git a/asoc/msm-pcm-voip-v2.c b/asoc/msm-pcm-voip-v2.c index 58fc534f1cb0..02cee29e3c02 100644 --- a/asoc/msm-pcm-voip-v2.c +++ b/asoc/msm-pcm-voip-v2.c @@ -1704,7 +1704,7 @@ int __init msm_pcm_voip_init(void) return platform_driver_register(&msm_pcm_driver); } -void __exit msm_pcm_voip_exit(void) +void msm_pcm_voip_exit(void) { platform_driver_unregister(&msm_pcm_driver); } diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index 94ebbf748a92..3c8e917f4278 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -958,7 +958,7 @@ int __init msm_transcode_loopback_init(void) return platform_driver_register(&msm_transcode_loopback_driver); } -void __exit msm_transcode_loopback_exit(void) +void msm_transcode_loopback_exit(void) { mutex_destroy(&transcode_info.lock); platform_driver_unregister(&msm_transcode_loopback_driver); diff --git a/config/sdm670auto_static.conf b/config/sdm670auto_static.conf new file mode 100644 index 000000000000..dc555646594d --- /dev/null +++ b/config/sdm670auto_static.conf @@ -0,0 +1,50 @@ +CONFIG_PINCTRL_LPI=y +CONFIG_PINCTRL_WCD=y +CONFIG_AUDIO_EXT_CLK=y +CONFIG_SND_SOC_WCD9XXX_V2=y +CONFIG_SND_SOC_WCD_MBHC=y +CONFIG_SND_SOC_WSA881X=y +CONFIG_SND_SOC_WCD_DSP_MGR=y +CONFIG_SND_SOC_WCD_SPI=y +CONFIG_SND_SOC_WCD_CPE=y +CONFIG_SND_SOC_CPE=y +CONFIG_SND_SOC_WCD9335=y +CONFIG_SND_SOC_WCD934X=y +CONFIG_SND_SOC_WCD934X_MBHC=y +CONFIG_SND_SOC_WCD934X_DSD=y +CONFIG_MSM_QDSP6V2_CODECS=y +CONFIG_MSM_ULTRASOUND=y +CONFIG_MSM_QDSP6_APRV2_GLINK=y +CONFIG_MSM_ADSP_LOADER=y +CONFIG_REGMAP_SWR=y +CONFIG_MSM_QDSP6_SSR=y +CONFIG_MSM_QDSP6_PDR=y +CONFIG_MSM_QDSP6_NOTIFIER=y +CONFIG_SND_SOC_MSM_HOSTLESS_PCM=y +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y +CONFIG_SND_SOC_SDM670=y +CONFIG_MSM_GLINK_SPI_XPRT=y +CONFIG_SOUNDWIRE=y +CONFIG_SOUNDWIRE_WCD_CTRL=y +CONFIG_SND_SOC_QDSP6V2=y +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y +CONFIG_WCD9XXX_CODEC_CORE=y +CONFIG_MSM_CDC_PINCTRL=y +CONFIG_SND_SOC_WCD_MBHC_ADC=y +CONFIG_SND_SOC_WCD_MBHC_LEGACY=y +CONFIG_QTI_PP=y +CONFIG_SND_HWDEP=y +CONFIG_DTS_EAGLE=y +CONFIG_DOLBY_DS2=y +CONFIG_DOLBY_LICENSE=y +CONFIG_DTS_SRS_TM=y +CONFIG_SND_SOC_EXT_CODEC=y +CONFIG_SND_SOC_INT_CODEC=y +CONFIG_SND_SOC_MSM_STUB=y +CONFIG_WCD_DSP_GLINK=y +CONFIG_MSM_AVTIMER=y +CONFIG_SND_SOC_SDM660_CDC=y +CONFIG_SND_SOC_ANALOG_CDC=y +CONFIG_SND_SOC_DIGITAL_CDC=y +CONFIG_SND_SOC_MSM_SDW=y +CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y diff --git a/dsp/Kbuild b/dsp/Kbuild index 87720854379c..306a25a12604 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -1,22 +1,33 @@ # We can build either as part of a standalone Kernel build or as # an external module. Determine which mechanism is being used -KERNEL_BUILD := 0 - +ifeq ($(MODNAME), ) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif -ifeq ($(KERNEL_BUILD), 0) +ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SDM845), y) include $(AUDIO_ROOT)/config/sdm845auto.conf export + INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h endif ifeq ($(CONFIG_ARCH_SDM670), y) include $(AUDIO_ROOT)/config/sdm670auto.conf export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif endif + # As per target team, build is done as follows: # Defconfig : build with default flags # Slub : defconfig + CONFIG_SLUB_DEBUG := y + @@ -43,10 +54,9 @@ COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) ############ QDSP6V2 ############ -ifeq ($(CONFIG_SND_SOC_MSM_QDSP6V2_INTF), m) +ifdef CONFIG_SND_SOC_MSM_QDSP6V2_INTF Q6_OBJS += audio_calibration.o Q6_OBJS += audio_cal_utils.o - Q6_OBJS += msm-dts-srs-tm-config.o Q6_OBJS += q6adm.o Q6_OBJS += q6afe.o Q6_OBJS += q6asm.o @@ -61,34 +71,31 @@ ifeq ($(CONFIG_SND_SOC_MSM_QDSP6V2_INTF), m) Q6_OBJS += avtimer.o Q6_OBJS += q6_init.o endif -ifeq ($(CONFIG_MSM_ADSP_LOADER), m) +ifdef CONFIG_DTS_SRS_TM + Q6_OBJS += msm-dts-srs-tm-config.o +endif + +ifdef CONFIG_MSM_ADSP_LOADER ADSP_LOADER_OBJS += adsp-loader.o endif -ifeq ($(CONFIG_MSM_QDSP6_NOTIFIER), m) +ifdef CONFIG_MSM_QDSP6_NOTIFIER QDSP6_NOTIFIER_OBJS += audio_notifier.o audio_ssr.o endif -ifeq ($(CONFIG_MSM_QDSP6_PDR), m) +ifdef CONFIG_MSM_QDSP6_PDR QDSP6_PDR_OBJS += audio_pdr.o endif -ifeq ($(CONFIG_MSM_ULTRASOUND), m) +ifdef CONFIG_MSM_ULTRASOUND USF_OBJS += usf.o usfcdev.o q6usm.o endif LINUX_INC += -Iinclude/linux -INCS := $(COMMON_INC) \ +INCS += $(COMMON_INC) \ $(UAPI_INC) -ifeq ($(CONFIG_ARCH_SDM845), y) -INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h -endif -ifeq ($(CONFIG_ARCH_SDM670), y) -INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h -endif - EXTRA_CFLAGS += $(INCS) @@ -128,7 +135,13 @@ CHIP_NAME ?= $(MODNAME) CDEFINES += -DMULTI_IF_NAME=\"$(CHIP_NAME)\" endif +ifeq ($(KERNEL_BUILD), 0) KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +endif + +ifeq ($(KERNEL_BUILD), 1) + obj-y += codecs/ +endif obj-$(CONFIG_SND_SOC_MSM_QDSP6V2_INTF) += q6_dlkm.o q6_dlkm-y := $(Q6_OBJS) diff --git a/dsp/Makefile b/dsp/Makefile deleted file mode 100644 index b609df228abe..000000000000 --- a/dsp/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -obj-$(CONFIG_SND_SOC_MSM_QDSP6V2_INTF) += audio_calibration.o audio_cal_utils.o \ - q6adm.o q6afe.o q6asm.o q6audio-v2.o q6voice.o q6core.o \ - rtac.o q6lsm.o audio_slimslave.o adsp_err.o msm_audio_ion.o -obj-$(CONFIG_MSM_ADSP_LOADER) += adsp-loader.o -obj-$(CONFIG_MSM_QDSP6_SSR) += audio_ssr.o -obj-$(CONFIG_MSM_QDSP6_PDR) += audio_pdr.o -obj-$(CONFIG_MSM_QDSP6_NOTIFIER) += audio_notifier.o -obj-$(CONFIG_MSM_ULTRASOUND) += usf.o usfcdev.o q6usm.o -obj-$(CONFIG_MSM_AVTIMER) += avtimer.o -obj-$(CONFIG_MSM_QDSP6V2_CODECS) += codecs/ diff --git a/dsp/adsp_err.c b/dsp/adsp_err.c index 7ad80dc6ecc3..e34d76b6aae6 100644 --- a/dsp/adsp_err.c +++ b/dsp/adsp_err.c @@ -167,7 +167,7 @@ int __init adsp_err_init(void) { return 0; } #endif -void __exit adsp_err_exit(void) +void adsp_err_exit(void) { return; } diff --git a/dsp/audio_calibration.c b/dsp/audio_calibration.c index f812c98ab1f6..c895fa788315 100644 --- a/dsp/audio_calibration.c +++ b/dsp/audio_calibration.c @@ -609,7 +609,7 @@ int __init audio_cal_init(void) return misc_register(&audio_cal_misc); } -void __exit audio_cal_exit(void) +void audio_cal_exit(void) { int i = 0; struct list_head *ptr, *next; diff --git a/dsp/audio_slimslave.c b/dsp/audio_slimslave.c index f9e9cdc3709e..25866d12ed73 100644 --- a/dsp/audio_slimslave.c +++ b/dsp/audio_slimslave.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -165,7 +165,7 @@ int __init audio_slimslave_init(void) return slim_driver_register(&audio_slimslave_driver); } -void __exit audio_slimslave_exit(void) +void audio_slimslave_exit(void) { } diff --git a/dsp/avtimer.c b/dsp/avtimer.c index 184e0e9370df..b6833ed788b2 100644 --- a/dsp/avtimer.c +++ b/dsp/avtimer.c @@ -535,7 +535,7 @@ int __init avtimer_init(void) return rc; } -void __exit avtimer_exit(void) +void avtimer_exit(void) { platform_driver_unregister(&dev_avtimer_driver); } diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 683f5997bd9c..13b2399217d8 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -1,22 +1,32 @@ # We can build either as part of a standalone Kernel build or as # an external module. Determine which mechanism is being used -KERNEL_BUILD := 0 - +ifeq ($(MODNAME), ) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif -ifeq ($(KERNEL_BUILD), 0) +ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SDM845), y) include $(AUDIO_ROOT)/config/sdm845auto.conf export + INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h + endif ifeq ($(CONFIG_ARCH_SDM670), y) include $(AUDIO_ROOT)/config/sdm670auto.conf export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif endif - # As per target team, build is done as follows: # Defconfig : build with default flags # Slub : defconfig + CONFIG_SLUB_DEBUG := y + @@ -43,7 +53,7 @@ COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) ############ Native Enc/Dec ############ -ifeq ($(CONFIG_MSM_QDSP6V2_CODECS), m) +ifdef CONFIG_MSM_QDSP6V2_CODECS NATIVE_OBJS += q6audio_v2.o q6audio_v2_aio.o NATIVE_OBJS += audio_utils_aio.o NATIVE_OBJS += audio_utils.o @@ -74,16 +84,9 @@ endif LINUX_INC += -Iinclude/linux -INCS := $(COMMON_INC) \ +INCS += $(COMMON_INC) \ $(UAPI_INC) -ifeq ($(CONFIG_ARCH_SDM845), y) -INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h -endif -ifeq ($(CONFIG_ARCH_SDM670), y) -INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h -endif - EXTRA_CFLAGS += $(INCS) @@ -112,17 +115,9 @@ ifeq ($(call cc-option-yn, -Wheader-guard),y) EXTRA_CFLAGS += -Wheader-guard endif +ifeq ($(KERNEL_BUILD), 0) KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers -# If the module name is not "wlan", then the define MULTI_IF_NAME to be the -# same a the QCA CHIP name. The host driver will then append MULTI_IF_NAME to -# any string that must be unique for all instances of the driver on the system. -# This allows multiple instances of the driver with different module names. -# If the module name is wlan, leave MULTI_IF_NAME undefined and the code will -# treat the driver as the primary driver. -ifneq ($(MODNAME), qdsp6v2) -CHIP_NAME ?= $(MODNAME) -CDEFINES += -DMULTI_IF_NAME=\"$(CHIP_NAME)\" endif # Module information used by KBuild framework diff --git a/dsp/codecs/Makefile b/dsp/codecs/Makefile deleted file mode 100644 index f9052190b273..000000000000 --- a/dsp/codecs/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-$(CONFIG_MSM_QDSP6V2_CODECS) += aac_in.o qcelp_in.o evrc_in.o amrnb_in.o g711mlaw_in.o g711alaw_in.o audio_utils.o -obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_wma.o audio_wmapro.o audio_aac.o audio_multi_aac.o audio_alac.o audio_ape.o audio_utils_aio.o -obj-$(CONFIG_MSM_QDSP6V2_CODECS) += q6audio_v2.o q6audio_v2_aio.o -obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_g711mlaw.o audio_g711alaw.o -obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_mp3.o audio_amrnb.o audio_amrwb.o audio_amrwbplus.o audio_evrc.o audio_qcelp.o amrwb_in.o audio_hwacc_effects.o diff --git a/dsp/codecs/aac_in.c b/dsp/codecs/aac_in.c index 5c071416551a..e10fbee605f7 100644 --- a/dsp/codecs/aac_in.c +++ b/dsp/codecs/aac_in.c @@ -707,7 +707,7 @@ int __init aac_in_init(void) return misc_register(&audio_aac_in_misc); } -void __exit aac_in_exit(void) +void aac_in_exit(void) { misc_deregister(&audio_aac_in_misc); } diff --git a/dsp/codecs/amrnb_in.c b/dsp/codecs/amrnb_in.c index d9a019de9115..4e3586036702 100644 --- a/dsp/codecs/amrnb_in.c +++ b/dsp/codecs/amrnb_in.c @@ -399,7 +399,7 @@ int __init amrnb_in_init(void) return misc_register(&audio_amrnb_in_misc); } -void __exit amrnb_in_exit(void) +void amrnb_in_exit(void) { misc_deregister(&audio_amrnb_in_misc); } diff --git a/dsp/codecs/amrwb_in.c b/dsp/codecs/amrwb_in.c index d1d4ab71b86d..ce9dc45c1d96 100644 --- a/dsp/codecs/amrwb_in.c +++ b/dsp/codecs/amrwb_in.c @@ -397,7 +397,7 @@ int __init amrwb_in_init(void) return misc_register(&audio_amrwb_in_misc); } -void __exit amrwb_in_exit(void) +void amrwb_in_exit(void) { misc_deregister(&audio_amrwb_in_misc); } diff --git a/dsp/codecs/audio_aac.c b/dsp/codecs/audio_aac.c index ea7506fbe6a7..c742f722ee84 100644 --- a/dsp/codecs/audio_aac.c +++ b/dsp/codecs/audio_aac.c @@ -473,7 +473,7 @@ int __init audio_aac_init(void) return ret; } -void __exit audio_aac_exit(void) +void audio_aac_exit(void) { mutex_destroy(&audio_aac_ws_mgr.ws_lock); misc_deregister(&audio_aac_misc); diff --git a/dsp/codecs/audio_alac.c b/dsp/codecs/audio_alac.c index 50a0bf7e342a..cfb3087fec46 100644 --- a/dsp/codecs/audio_alac.c +++ b/dsp/codecs/audio_alac.c @@ -432,7 +432,7 @@ int __init audio_alac_init(void) return ret; } -void __exit audio_alac_exit(void) +void audio_alac_exit(void) { mutex_destroy(&audio_alac_ws_mgr.ws_lock); misc_deregister(&audio_alac_misc); diff --git a/dsp/codecs/audio_amrnb.c b/dsp/codecs/audio_amrnb.c index 041774259ab8..1b5dd949f7f2 100644 --- a/dsp/codecs/audio_amrnb.c +++ b/dsp/codecs/audio_amrnb.c @@ -223,7 +223,7 @@ int __init audio_amrnb_init(void) return ret; } -void __exit audio_amrnb_exit(void) +void audio_amrnb_exit(void) { mutex_destroy(&audio_amrnb_ws_mgr.ws_lock); misc_deregister(&audio_amrnb_misc); diff --git a/dsp/codecs/audio_amrwb.c b/dsp/codecs/audio_amrwb.c index 091bee4d3ff0..14087821481f 100644 --- a/dsp/codecs/audio_amrwb.c +++ b/dsp/codecs/audio_amrwb.c @@ -228,7 +228,7 @@ int __init audio_amrwb_init(void) return ret; } -void __exit audio_amrwb_exit(void) +void audio_amrwb_exit(void) { mutex_destroy(&audio_amrwb_ws_mgr.ws_lock); misc_deregister(&audio_amrwb_misc); diff --git a/dsp/codecs/audio_amrwbplus.c b/dsp/codecs/audio_amrwbplus.c index 566aee735e6c..9d6c118712ec 100644 --- a/dsp/codecs/audio_amrwbplus.c +++ b/dsp/codecs/audio_amrwbplus.c @@ -394,7 +394,7 @@ int __init audio_amrwbplus_init(void) return ret; } -void __exit audio_amrwbplus_exit(void) +void audio_amrwbplus_exit(void) { mutex_destroy(&audio_amrwbplus_ws_mgr.ws_lock); misc_deregister(&audio_amrwbplus_misc); diff --git a/dsp/codecs/audio_ape.c b/dsp/codecs/audio_ape.c index b11f83ef561a..3df634713a69 100644 --- a/dsp/codecs/audio_ape.c +++ b/dsp/codecs/audio_ape.c @@ -356,7 +356,7 @@ int __init audio_ape_init(void) return ret; } -void __exit audio_ape_exit(void) +void audio_ape_exit(void) { mutex_destroy(&audio_ape_ws_mgr.ws_lock); misc_deregister(&audio_ape_misc); diff --git a/dsp/codecs/audio_evrc.c b/dsp/codecs/audio_evrc.c index 78bbde648604..6cddc9cacf70 100644 --- a/dsp/codecs/audio_evrc.c +++ b/dsp/codecs/audio_evrc.c @@ -181,7 +181,7 @@ int __init audio_evrc_init(void) return ret; } -void __exit audio_evrc_exit(void) +void audio_evrc_exit(void) { mutex_destroy(&audio_evrc_ws_mgr.ws_lock); misc_deregister(&audio_evrc_misc); diff --git a/dsp/codecs/audio_g711alaw.c b/dsp/codecs/audio_g711alaw.c index a6e0a6e62414..6382616fab55 100644 --- a/dsp/codecs/audio_g711alaw.c +++ b/dsp/codecs/audio_g711alaw.c @@ -387,7 +387,7 @@ int __init audio_g711alaw_init(void) return ret; } -void __exit audio_g711alaw_exit(void) +void audio_g711alaw_exit(void) { mutex_destroy(&audio_g711_ws_mgr.ws_lock); misc_deregister(&audio_g711alaw_misc); diff --git a/dsp/codecs/audio_g711mlaw.c b/dsp/codecs/audio_g711mlaw.c index 2a2598c70842..9994aabc9591 100644 --- a/dsp/codecs/audio_g711mlaw.c +++ b/dsp/codecs/audio_g711mlaw.c @@ -386,7 +386,7 @@ int __init audio_g711mlaw_init(void) return ret; } -void __exit audio_g711mlaw_exit(void) +void audio_g711mlaw_exit(void) { mutex_destroy(&audio_g711_ws_mgr.ws_lock); misc_deregister(&audio_g711mlaw_misc); diff --git a/dsp/codecs/audio_hwacc_effects.c b/dsp/codecs/audio_hwacc_effects.c index cd54b90cf338..f66164bfc62f 100644 --- a/dsp/codecs/audio_hwacc_effects.c +++ b/dsp/codecs/audio_hwacc_effects.c @@ -772,7 +772,7 @@ int __init audio_effects_init(void) return misc_register(&audio_effects_misc); } -void __exit audio_effects_exit(void) +void audio_effects_exit(void) { misc_deregister(&audio_effects_misc); } diff --git a/dsp/codecs/audio_mp3.c b/dsp/codecs/audio_mp3.c index 81e8486ada71..4435f3e71c88 100644 --- a/dsp/codecs/audio_mp3.c +++ b/dsp/codecs/audio_mp3.c @@ -185,7 +185,7 @@ int __init audio_mp3_init(void) return ret; } -void __exit audio_mp3_exit(void) +void audio_mp3_exit(void) { mutex_destroy(&audio_mp3_ws_mgr.ws_lock); misc_deregister(&audio_mp3_misc); diff --git a/dsp/codecs/audio_multi_aac.c b/dsp/codecs/audio_multi_aac.c index c3e616aef423..45405dd58251 100644 --- a/dsp/codecs/audio_multi_aac.c +++ b/dsp/codecs/audio_multi_aac.c @@ -520,7 +520,7 @@ int __init audio_multiaac_init(void) return ret; } -void __exit audio_multiaac_exit(void) +void audio_multiaac_exit(void) { mutex_destroy(&audio_multiaac_ws_mgr.ws_lock); misc_deregister(&audio_multiaac_misc); diff --git a/dsp/codecs/audio_qcelp.c b/dsp/codecs/audio_qcelp.c index 86902948dd96..4b23bace509d 100644 --- a/dsp/codecs/audio_qcelp.c +++ b/dsp/codecs/audio_qcelp.c @@ -188,7 +188,7 @@ int audio_qcelp_init(void) return ret; } -void __exit audio_qcelp_exit(void) +void audio_qcelp_exit(void) { mutex_destroy(&audio_qcelp_ws_mgr.ws_lock); misc_deregister(&audio_qcelp_misc); diff --git a/dsp/codecs/audio_wma.c b/dsp/codecs/audio_wma.c index 975dc0b01c48..ef9c8c65c085 100644 --- a/dsp/codecs/audio_wma.c +++ b/dsp/codecs/audio_wma.c @@ -342,7 +342,7 @@ int __init audio_wma_init(void) return ret; } -void __exit audio_wma_exit(void) +void audio_wma_exit(void) { mutex_destroy(&audio_wma_ws_mgr.ws_lock); misc_deregister(&audio_wma_misc); diff --git a/dsp/codecs/audio_wmapro.c b/dsp/codecs/audio_wmapro.c index 3ce4cdc86e90..21826189b6a0 100644 --- a/dsp/codecs/audio_wmapro.c +++ b/dsp/codecs/audio_wmapro.c @@ -415,7 +415,7 @@ int __init audio_wmapro_init(void) return ret; } -void __exit audio_wmapro_exit(void) +void audio_wmapro_exit(void) { mutex_destroy(&audio_wmapro_ws_mgr.ws_lock); misc_deregister(&audio_wmapro_misc); diff --git a/dsp/codecs/evrc_in.c b/dsp/codecs/evrc_in.c index 158ff6f08c57..15f08e7450b8 100644 --- a/dsp/codecs/evrc_in.c +++ b/dsp/codecs/evrc_in.c @@ -407,7 +407,7 @@ int __init evrc_in_init(void) return misc_register(&audio_evrc_in_misc); } -void __exit evrc_in_exit(void) +void evrc_in_exit(void) { misc_deregister(&audio_evrc_in_misc); } diff --git a/dsp/codecs/g711alaw_in.c b/dsp/codecs/g711alaw_in.c index bd49bc9ab714..c668b48b812d 100644 --- a/dsp/codecs/g711alaw_in.c +++ b/dsp/codecs/g711alaw_in.c @@ -379,7 +379,7 @@ int __init g711alaw_in_init(void) return misc_register(&audio_g711alaw_in_misc); } -void __exit g711alaw_in_exit(void) +void g711alaw_in_exit(void) { misc_deregister(&audio_g711alaw_in_misc); } diff --git a/dsp/codecs/g711mlaw_in.c b/dsp/codecs/g711mlaw_in.c index d646bd1330cd..2f20c1335f6e 100644 --- a/dsp/codecs/g711mlaw_in.c +++ b/dsp/codecs/g711mlaw_in.c @@ -382,7 +382,7 @@ int __init g711mlaw_in_init(void) return misc_register(&audio_g711mlaw_in_misc); } -void __exit g711mlaw_in_exit(void) +void g711mlaw_in_exit(void) { misc_deregister(&audio_g711mlaw_in_misc); } diff --git a/dsp/codecs/qcelp_in.c b/dsp/codecs/qcelp_in.c index 050c95f38955..be09ea4a0508 100644 --- a/dsp/codecs/qcelp_in.c +++ b/dsp/codecs/qcelp_in.c @@ -407,7 +407,7 @@ int __init qcelp_in_init(void) return misc_register(&audio_qcelp_in_misc); } -void __exit qcelp_in_exit(void) +void qcelp_in_exit(void) { misc_deregister(&audio_qcelp_in_misc); } diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index ca9505f02f6a..113829057aff 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -917,7 +917,7 @@ int __init msm_audio_ion_init(void) return platform_driver_register(&msm_audio_ion_driver); } -void __exit msm_audio_ion_exit(void) +void msm_audio_ion_exit(void) { platform_driver_unregister(&msm_audio_ion_driver); } diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 77c28976e379..78ce2b88ac21 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -5246,7 +5246,7 @@ int __init adm_init(void) return 0; } -void __exit adm_exit(void) +void adm_exit(void) { mutex_destroy(&dts_srs_lock); adm_delete_cal_data(); diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 864ae4ad4507..bdc6cda075d8 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -7576,7 +7576,7 @@ int __init afe_init(void) return 0; } -void __exit afe_exit(void) +void afe_exit(void) { afe_delete_cal_data(); diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 4e988ee489e6..c990f82361a7 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -10286,7 +10286,7 @@ int __init q6asm_init(void) return 0; } -void __exit q6asm_exit(void) +void q6asm_exit(void) { q6asm_delete_cal_data(); } diff --git a/dsp/q6core.c b/dsp/q6core.c index b80786209b7c..5e09faa7d7e8 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -1105,7 +1105,7 @@ int __init core_init(void) return 0; } -void __exit core_exit(void) +void core_exit(void) { mutex_destroy(&q6core_lcl.cmd_lock); mutex_destroy(&q6core_lcl.ver_lock); diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index e34bff9732ca..2a98dc719965 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -2376,7 +2376,7 @@ int __init q6lsm_init(void) return 0; } -void __exit q6lsm_exit(void) +void q6lsm_exit(void) { lsm_delete_cal_data(); } diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 985e959ab879..1a20f9d1ebe3 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -9606,7 +9606,7 @@ int __init voice_init(void) } -void __exit voice_exit(void) +void voice_exit(void) { voice_delete_cal_data(); free_cal_map_table(); diff --git a/dsp/rtac.c b/dsp/rtac.c index 806bbc5fb16b..43c69ccab394 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -1949,7 +1949,7 @@ int __init rtac_init(void) return -ENOMEM; } -void __exit rtac_exit(void) +void rtac_exit(void) { kzfree(rtac_adm_buffer); kzfree(rtac_asm_buffer); diff --git a/ipc/Kbuild b/ipc/Kbuild index b729f90318b7..92760fb0cd2f 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -1,25 +1,41 @@ # We can build either as part of a standalone Kernel build or as # an external module. Determine which mechanism is being used -KERNEL_BUILD := 0 +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + +TARGET_KERNEL_VERSION := 4.9 -TARGET_KERNEL_VERSION := 4.4 +# These are configurable via Kconfig for kernel-based builds +# Need to explicitly configure for Android-based builds +ifeq ($(CONFIG_ARCH_SDM845), y) + TARGET_KERNEL_VERSION := 4.9 +endif +ifeq ($(CONFIG_ARCH_SDM670), y) + TARGET_KERNEL_VERSION := 4.9 +endif + +KDIR := $(TOP)/kernel/msm-$(TARGET_KERNEL_VERSION) + +ifeq ($(KERNEL_BUILD), 1) + AUDIO_ROOT := $(KDIR)/techpack/audio +endif ifeq ($(KERNEL_BUILD), 0) - # These are configurable via Kconfig for kernel-based builds - # Need to explicitly configure for Android-based builds ifeq ($(CONFIG_ARCH_SDM845), y) include $(AUDIO_ROOT)/config/sdm845auto.conf export - TARGET_KERNEL_VERSION := 4.9 + INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h endif ifeq ($(CONFIG_ARCH_SDM670), y) include $(AUDIO_ROOT)/config/sdm670auto.conf export - TARGET_KERNEL_VERSION := 4.9 + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif endif - # As per target team, build is done as follows: # Defconfig : build with default flags # Slub : defconfig + CONFIG_SLUB_DEBUG := y + @@ -46,34 +62,27 @@ COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) ############ IPC ############ -ifeq ($(CONFIG_MSM_QDSP6_APRV2_GLINK), m) +ifdef CONFIG_MSM_QDSP6_APRV2_GLINK APRV_GLINK += apr.o APRV_GLINK += apr_v2.o APRV_GLINK += apr_tal_glink.o endif -ifeq ($(CONFIG_MSM_QDSP6_APRV3_GLINK), m) +ifdef CONFIG_MSM_QDSP6_APRV3_GLINK APRV_GLINK += apr.o APRV_GLINK += apr_v3.o APRV_GLINK += apr_tal_glink.o endif -ifeq ($(CONFIG_WCD_DSP_GLINK), m) +ifdef CONFIG_WCD_DSP_GLINK WDSP_GLINK += wcd-dsp-glink.o endif LINUX_INC += -Iinclude/linux -INCS := $(COMMON_INC) \ +INCS += $(COMMON_INC) \ $(UAPI_INC) -ifeq ($(CONFIG_ARCH_SDM845), y) -INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h -endif -ifeq ($(CONFIG_ARCH_SDM670), y) -INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h -endif - EXTRA_CFLAGS += $(INCS) @@ -89,6 +98,8 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ KBUILD_CPPFLAGS += $(CDEFINES) +ifeq ($(KERNEL_BUILD), 0) + HEADER_INSTALL_DIR := $(TOP)/kernel/msm-$(TARGET_KERNEL_VERSION)/scripts UAPI_OUT := $(OUT)/obj/vendor/qcom/opensource/audio-kernel/include $(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ avtimer.h;) @@ -118,6 +129,10 @@ $(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT $(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ voice_params.h;) $(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ wcd-dsp-glink.h;) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers + +endif + # Currently, for versions of gcc which support it, the kernel Makefile # is disabling the maybe-uninitialized warning. Re-enable it for the # AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it @@ -141,9 +156,9 @@ CHIP_NAME ?= $(MODNAME) CDEFINES += -DMULTI_IF_NAME=\"$(CHIP_NAME)\" endif -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers # Module information used by KBuild framework obj-$(CONFIG_MSM_QDSP6_APRV2_GLINK) += apr_dlkm.o +obj-$(CONFIG_MSM_QDSP6_APRV3_GLINK) += apr_dlkm.o apr_dlkm-y := $(APRV_GLINK) obj-$(CONFIG_WCD_DSP_GLINK) += wglink_dlkm.o diff --git a/ipc/Makefile b/ipc/Makefile deleted file mode 100644 index 69389153b7c4..000000000000 --- a/ipc/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_MSM_QDSP6_APRV2_GLINK) += apr.o apr_v2.o apr_tal_glink.o -obj-$(CONFIG_MSM_QDSP6_APRV3_GLINK) += apr.o apr_v3.o apr_tal_glink.o -obj-$(CONFIG_WCD_DSP_GLINK) += wcd-dsp-glink.o diff --git a/soc/Kbuild b/soc/Kbuild index 45b77e9ce1f8..c9cf31bc2039 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -1,22 +1,31 @@ # We can build either as part of a standalone Kernel build or as # an external module. Determine which mechanism is being used -KERNEL_BUILD := 0 - +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif -ifeq ($(KERNEL_BUILD), 0) +ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SDM845), y) include $(AUDIO_ROOT)/config/sdm845auto.conf export + INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h endif ifeq ($(CONFIG_ARCH_SDM670), y) include $(AUDIO_ROOT)/config/sdm670auto.conf export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif endif - # As per target team, build is done as follows: # Defconfig : build with default flags # Slub : defconfig + CONFIG_SLUB_DEBUG := y + @@ -44,37 +53,30 @@ COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) ############ SoC Modules ############ # for pinctrl WCD driver -ifeq ($(CONFIG_PINCTRL_WCD), m) +ifdef CONFIG_PINCTRL_WCD PINCTRL_WCD_OBJS += pinctrl-wcd.o endif # for pinctrl LPI driver -ifeq ($(CONFIG_PINCTRL_LPI), m) +ifdef CONFIG_PINCTRL_LPI PINCTRL_LPI_OBJS += pinctrl-lpi.o endif # for soundwire driver -ifeq ($(CONFIG_SOUNDWIRE_WCD_CTRL), m) +ifdef CONFIG_SOUNDWIRE_WCD_CTRL SWR_CTRL_OBJS += swr-wcd-ctrl.o endif -ifeq ($(CONFIG_SOUNDWIRE), m) +ifdef CONFIG_SOUNDWIRE SWR_OBJS += regmap-swr.o SWR_OBJS += soundwire.o endif LINUX_INC += -Iinclude/linux -INCS := $(COMMON_INC) \ +INCS += $(COMMON_INC) \ $(UAPI_INC) -ifeq ($(CONFIG_ARCH_SDM845), y) -INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h -endif -ifeq ($(CONFIG_ARCH_SDM670), y) -INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h -endif - EXTRA_CFLAGS += $(INCS) @@ -90,7 +92,10 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ KBUILD_CPPFLAGS += $(CDEFINES) +ifeq ($(KERNEL_BUILD), 0) KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +endif + # Currently, for versions of gcc which support it, the kernel Makefile # is disabling the maybe-uninitialized warning. Re-enable it for the # AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it diff --git a/soc/Makefile b/soc/Makefile deleted file mode 100644 index c563e76ecdce..000000000000 --- a/soc/Makefile +++ /dev/null @@ -1,6 +0,0 @@ - -obj-$(CONFIG_REGMAP_SWR) += regmap-swr.o -obj-$(CONFIG_PINCTRL_WCD) += pinctrl-wcd.o -obj-$(CONFIG_PINCTRL_LPI) += pinctrl-lpi.o -obj-$(CONFIG_SOUNDWIRE) += soundwire.o -obj-$(CONFIG_SOUNDWIRE_WCD_CTRL) += swr-wcd-ctrl.o -- GitLab From 776b1b32c21543d73e68b7e94c696190b792ae4f Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 25 Oct 2017 15:50:46 -0700 Subject: [PATCH 0105/1645] asoc: codecs: stop mbhc before mbhc init and after ssr In SSR init call stop mbhc before initializing mbhc again, so that usbc analog deregisters the callback with PMI notifier. CRs-fixed: 2128532 Change-Id: I329f25172b5cc2d80b93918787f703d89c95062f Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd934x/wcd934x-mbhc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/codecs/wcd934x/wcd934x-mbhc.c b/asoc/codecs/wcd934x/wcd934x-mbhc.c index 807d4ea58e89..ae147ca0f411 100644 --- a/asoc/codecs/wcd934x/wcd934x-mbhc.c +++ b/asoc/codecs/wcd934x/wcd934x-mbhc.c @@ -1043,6 +1043,7 @@ int tavil_mbhc_post_ssr_init(struct wcd934x_mbhc *mbhc, return -EINVAL; } + tavil_mbhc_hs_detect_exit(codec); wcd_mbhc_deinit(wcd_mbhc); ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids, wcd_mbhc_registers, TAVIL_ZDET_SUPPORTED); -- GitLab From d3047b2ae01de0dd2c48244c19cab35d8c004da2 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 22 Nov 2017 15:29:52 +0530 Subject: [PATCH 0106/1645] ipc: add validity check to APR port Add boundary checks for APR port received from ADSP. CRs-Fixed: 2143207 Change-Id: I9a7fa39ee223e1859323caa6eb74c1c8a26a041d Signed-off-by: Aditya Bavanari --- ipc/apr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ipc/apr.c b/ipc/apr.c index dd2a63bd70f3..d2029943dcd9 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -717,9 +717,10 @@ void apr_cb_func(void *buf, int len, void *priv) } temp_port = ((data.dest_port >> 8) * 8) + (data.dest_port & 0xFF); - pr_debug("port = %d t_port = %d\n", data.src_port, temp_port); - if (c_svc->port_cnt && c_svc->port_fn[temp_port]) - c_svc->port_fn[temp_port](&data, c_svc->port_priv[temp_port]); + if (((temp_port >= 0) && (temp_port < APR_MAX_PORTS)) + && (c_svc->port_cnt && c_svc->port_fn[temp_port])) + c_svc->port_fn[temp_port](&data, + c_svc->port_priv[temp_port]); else if (c_svc->fn) c_svc->fn(&data, c_svc->priv); else -- GitLab From e4fd7d54842e1b1842e1027fd9eaa3fe8d10626e Mon Sep 17 00:00:00 2001 From: Aalique Grahame Date: Tue, 28 Nov 2017 13:24:13 -0800 Subject: [PATCH 0107/1645] ASoC: Enable display-port for voice calls Add mixer controls to enable voice calls over display-port. CRs-Fixed: 2151849 Change-Id: Id245b9c5b97d55c1db60e897954cc94eecd7f42d Signed-off-by: Aalique Grahame --- asoc/msm-pcm-routing-v2.c | 46 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 0aed70c4b522..5e84b2171cf3 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -3620,6 +3620,10 @@ static int msm_routing_ec_ref_rx_put(struct snd_kcontrol *kcontrol, msm_route_ec_ref_rx = 22; ec_ref_port_id = AFE_PORT_ID_INT3_MI2S_TX; break; + case 23: + msm_route_ec_ref_rx = 23; + ec_ref_port_id = AFE_PORT_ID_HDMI_OVER_DP_RX; + break; default: msm_route_ec_ref_rx = 0; /* NONE */ pr_err("%s EC ref rx %ld not valid\n", @@ -3642,7 +3646,7 @@ static const char *const ec_ref_rx[] = { "None", "SLIM_RX", "I2S_RX", "SLIM_5_RX", "SLIM_1_TX", "QUAT_TDM_TX_1", "QUAT_TDM_RX_0", "QUAT_TDM_RX_1", "QUAT_TDM_RX_2", "SLIM_6_RX", "TERT_MI2S_RX", "QUAT_MI2S_RX", "TERT_TDM_TX_0", "USB_AUDIO_RX", - "INT0_MI2S_RX", "INT4_MI2S_RX", "INT3_MI2S_TX"}; + "INT0_MI2S_RX", "INT4_MI2S_RX", "INT3_MI2S_TX", "DISPLAY_PORT"}; static const struct soc_enum msm_route_ec_ref_rx_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ec_ref_rx), ec_ref_rx), @@ -8091,6 +8095,33 @@ static const struct snd_kcontrol_new usb_audio_rx_voice_mixer_controls[] = { msm_routing_put_voice_mixer), }; +static const struct snd_kcontrol_new display_port_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, @@ -13552,6 +13583,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("USB_AUDIO_RX Port Mixer", SND_SOC_NOPM, 0, 0, usb_rx_port_mixer_controls, ARRAY_SIZE(usb_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, display_port_rx_voice_mixer_controls, + ARRAY_SIZE(display_port_rx_voice_mixer_controls)), /* lsm mixer definitions */ SND_SOC_DAPM_MIXER("LSM1 Mixer", SND_SOC_NOPM, 0, 0, lsm1_mixer_controls, ARRAY_SIZE(lsm1_mixer_controls)), @@ -15029,6 +15063,16 @@ static const struct snd_soc_dapm_route intercon[] = { {"USB_AUDIO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX_Voice Mixer"}, + {"DISPLAY_PORT_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"DISPLAY_PORT_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"DISPLAY_PORT_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"DISPLAY_PORT_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"DISPLAY_PORT_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"DISPLAY_PORT_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"DISPLAY_PORT_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"DISPLAY_PORT_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"DISPLAY_PORT", NULL, "DISPLAY_PORT_RX_Voice Mixer"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"INTERNAL_BT_SCO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"INTERNAL_BT_SCO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, -- GitLab From df5a00af69f36e3f91f83ea858ab752cd8da15cc Mon Sep 17 00:00:00 2001 From: kunleiz Date: Mon, 27 Nov 2017 15:27:36 +0800 Subject: [PATCH 0108/1645] ASoC: msm: qdsp6v2: Remove unused dapm routings Clean up unused routings from dapm routing map. CRs-Fixed: 2149819 Change-Id: I056e8ca14d75262844616c7c831bec450d809d48 Signed-off-by: kunleiz --- asoc/msm-pcm-routing-v2.c | 316 ++++---------------------------------- 1 file changed, 26 insertions(+), 290 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 5e84b2171cf3..bee175f96354 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -8018,15 +8018,6 @@ static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8045,15 +8036,6 @@ static const struct snd_kcontrol_new slimbus_6_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8072,15 +8054,6 @@ static const struct snd_kcontrol_new usb_audio_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8099,15 +8072,6 @@ static const struct snd_kcontrol_new display_port_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8126,12 +8090,6 @@ static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8150,9 +8108,6 @@ static const struct snd_kcontrol_new mi2s_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8171,15 +8126,6 @@ static const struct snd_kcontrol_new pri_mi2s_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8234,15 +8180,6 @@ static const struct snd_kcontrol_new tert_mi2s_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8261,15 +8198,6 @@ static const struct snd_kcontrol_new quat_mi2s_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8288,15 +8216,6 @@ static const struct snd_kcontrol_new quin_mi2s_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8315,15 +8234,6 @@ static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8342,15 +8252,6 @@ static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8369,9 +8270,6 @@ static const struct snd_kcontrol_new sec_aux_pcm_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8390,9 +8288,6 @@ static const struct snd_kcontrol_new tert_aux_pcm_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8411,9 +8306,6 @@ static const struct snd_kcontrol_new quat_aux_pcm_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8432,9 +8324,6 @@ static const struct snd_kcontrol_new quin_aux_pcm_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8453,15 +8342,6 @@ static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8480,15 +8360,6 @@ static const struct snd_kcontrol_new slimbus_7_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8507,15 +8378,6 @@ static const struct snd_kcontrol_new slimbus_8_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_8_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_8_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -8537,39 +8399,30 @@ static const struct snd_kcontrol_new quat_tdm_rx_2_voice_mixer_controls[] = { }; static const struct snd_kcontrol_new stub_rx_mixer_controls[] = { - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_EXTPROC_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_EXTPROC_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_EXTPROC_RX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_EXTPROC_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_EXTPROC_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new slimbus_1_rx_mixer_controls[] = { - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = { - SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { @@ -15035,9 +14888,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"SLIM_0_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SLIM_0_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"SLIM_0_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"SLIM_0_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"SLIM_0_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"SLIM_0_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"SLIM_0_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, @@ -15045,9 +14895,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIM_6_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"SLIM_6_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SLIM_6_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"SLIM_6_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"SLIM_6_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"SLIM_6_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"SLIM_6_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"SLIM_6_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, @@ -15055,9 +14902,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"USB_AUDIO_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"USB_AUDIO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"USB_AUDIO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"USB_AUDIO_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"USB_AUDIO_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"USB_AUDIO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"USB_AUDIO_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"USB_AUDIO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, @@ -15065,9 +14909,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"DISPLAY_PORT_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"DISPLAY_PORT_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"DISPLAY_PORT_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"DISPLAY_PORT_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"DISPLAY_PORT_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"DISPLAY_PORT_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"DISPLAY_PORT_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"DISPLAY_PORT_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, @@ -15078,8 +14919,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"INTERNAL_BT_SCO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"}, {"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, @@ -15091,9 +14930,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"AUX_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"AUX_PCM_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"AUX_PCM_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, @@ -15101,7 +14937,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"SEC_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SEC_AUX_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, {"SEC_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"SEC_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"SEC_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, @@ -15109,7 +14944,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"TERT_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"TERT_AUX_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, {"TERT_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"TERT_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"TERT_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, @@ -15117,7 +14951,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"QUAT_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"QUAT_AUX_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, {"QUAT_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"QUAT_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"QUAT_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, @@ -15125,7 +14958,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"QUIN_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"QUIN_AUX_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, {"QUIN_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"QUIN_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"QUIN_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, @@ -15140,7 +14972,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"HDMI", NULL, "HDMI_DL_HL"}, {"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, {"MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, @@ -15148,9 +14979,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"}, {"PRI_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_MI2S_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, - {"PRI_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"PRI_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, {"PRI_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"PRI_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"PRI_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, @@ -15172,9 +15000,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_Voice Mixer"}, {"TERT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"TERT_MI2S_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, - {"TERT_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"TERT_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, {"TERT_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"TERT_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"TERT_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, @@ -15182,18 +15007,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX_Voice Mixer"}, {"QUAT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"QUAT_MI2S_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, - {"QUAT_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"QUAT_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, {"QUAT_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"QUAT_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"QUAT_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_Voice Mixer"}, {"QUIN_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"QUIN_MI2S_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, - {"QUIN_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"QUIN_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, {"QUIN_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"QUIN_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"QUIN_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, @@ -15208,11 +15027,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VOC_EXT_EC MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"VOC_EXT_EC MUX", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"VOC_EXT_EC MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"CS-VOICE_UL1", NULL, "VOC_EXT_EC MUX"}, {"VOIP_UL", NULL, "VOC_EXT_EC MUX"}, - {"VoLTE_UL", NULL, "VOC_EXT_EC MUX"}, - {"VOICE2_UL", NULL, "VOC_EXT_EC MUX"}, - {"VoWLAN_UL", NULL, "VOC_EXT_EC MUX"}, {"VOICEMMODE1_UL", NULL, "VOC_EXT_EC MUX"}, {"VOICEMMODE2_UL", NULL, "VOC_EXT_EC MUX"}, @@ -15307,75 +15122,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL18", NULL, "AUDIO_REF_EC_UL18 MUX"}, {"MM_UL19", NULL, "AUDIO_REF_EC_UL19 MUX"}, - {"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"}, - {"Voice_Tx Mixer", "PRI_MI2S_TX_Voice", "PRI_MI2S_TX"}, - {"Voice_Tx Mixer", "MI2S_TX_Voice", "MI2S_TX"}, - {"Voice_Tx Mixer", "TERT_MI2S_TX_Voice", "TERT_MI2S_TX"}, - {"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"}, - {"Voice_Tx Mixer", "SLIM_7_TX_Voice", "SLIMBUS_7_TX"}, - {"Voice_Tx Mixer", "SLIM_8_TX_Voice", "SLIMBUS_8_TX"}, - {"Voice_Tx Mixer", "USB_AUDIO_TX_Voice", "USB_AUDIO_TX"}, - {"Voice_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice", "INT_BT_SCO_TX"}, - {"Voice_Tx Mixer", "AFE_PCM_TX_Voice", "PCM_TX"}, - {"Voice_Tx Mixer", "AUX_PCM_TX_Voice", "AUX_PCM_TX"}, - {"Voice_Tx Mixer", "SEC_AUX_PCM_TX_Voice", "SEC_AUX_PCM_TX"}, - {"Voice_Tx Mixer", "TERT_AUX_PCM_TX_Voice", "TERT_AUX_PCM_TX"}, - {"Voice_Tx Mixer", "QUAT_AUX_PCM_TX_Voice", "QUAT_AUX_PCM_TX"}, - {"Voice_Tx Mixer", "QUIN_AUX_PCM_TX_Voice", "QUIN_AUX_PCM_TX"}, - {"Voice_Tx Mixer", "SEC_MI2S_TX_Voice", "SEC_MI2S_TX"}, - {"CS-VOICE_UL1", NULL, "Voice_Tx Mixer"}, - - {"Voice2_Tx Mixer", "PRI_TX_Voice2", "PRI_I2S_TX"}, - {"Voice2_Tx Mixer", "PRI_MI2S_TX_Voice2", "PRI_MI2S_TX"}, - {"Voice2_Tx Mixer", "MI2S_TX_Voice2", "MI2S_TX"}, - {"Voice2_Tx Mixer", "TERT_MI2S_TX_Voice2", "TERT_MI2S_TX"}, - {"Voice2_Tx Mixer", "SLIM_0_TX_Voice2", "SLIMBUS_0_TX"}, - {"Voice2_Tx Mixer", "SLIM_7_TX_Voice2", "SLIMBUS_7_TX"}, - {"Voice2_Tx Mixer", "SLIM_8_TX_Voice2", "SLIMBUS_8_TX"}, - {"Voice2_Tx Mixer", "USB_AUDIO_TX_Voice2", "USB_AUDIO_TX"}, - {"Voice2_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice2", "INT_BT_SCO_TX"}, - {"Voice2_Tx Mixer", "AFE_PCM_TX_Voice2", "PCM_TX"}, - {"Voice2_Tx Mixer", "AUX_PCM_TX_Voice2", "AUX_PCM_TX"}, - {"Voice2_Tx Mixer", "SEC_AUX_PCM_TX_Voice2", "SEC_AUX_PCM_TX"}, - {"Voice2_Tx Mixer", "TERT_AUX_PCM_TX_Voice2", "TERT_AUX_PCM_TX"}, - {"Voice2_Tx Mixer", "QUAT_AUX_PCM_TX_Voice2", "QUAT_AUX_PCM_TX"}, - {"Voice2_Tx Mixer", "QUIN_AUX_PCM_TX_Voice2", "QUIN_AUX_PCM_TX"}, - {"VOICE2_UL", NULL, "Voice2_Tx Mixer"}, - - {"VoLTE_Tx Mixer", "PRI_TX_VoLTE", "PRI_I2S_TX"}, - {"VoLTE_Tx Mixer", "SLIM_0_TX_VoLTE", "SLIMBUS_0_TX"}, - {"VoLTE_Tx Mixer", "SLIM_7_TX_VoLTE", "SLIMBUS_7_TX"}, - {"VoLTE_Tx Mixer", "SLIM_8_TX_VoLTE", "SLIMBUS_8_TX"}, - {"VoLTE_Tx Mixer", "USB_AUDIO_TX_VoLTE", "USB_AUDIO_TX"}, - {"VoLTE_Tx Mixer", "INTERNAL_BT_SCO_TX_VoLTE", "INT_BT_SCO_TX"}, - {"VoLTE_Tx Mixer", "AFE_PCM_TX_VoLTE", "PCM_TX"}, - {"VoLTE_Tx Mixer", "AUX_PCM_TX_VoLTE", "AUX_PCM_TX"}, - {"VoLTE_Tx Mixer", "SEC_AUX_PCM_TX_VoLTE", "SEC_AUX_PCM_TX"}, - {"VoLTE_Tx Mixer", "TERT_AUX_PCM_TX_VoLTE", "TERT_AUX_PCM_TX"}, - {"VoLTE_Tx Mixer", "QUAT_AUX_PCM_TX_VoLTE", "QUAT_AUX_PCM_TX"}, - {"VoLTE_Tx Mixer", "QUIN_AUX_PCM_TX_VoLTE", "QUIN_AUX_PCM_TX"}, - {"VoLTE_Tx Mixer", "MI2S_TX_VoLTE", "MI2S_TX"}, - {"VoLTE_Tx Mixer", "PRI_MI2S_TX_VoLTE", "PRI_MI2S_TX"}, - {"VoLTE_Tx Mixer", "TERT_MI2S_TX_VoLTE", "TERT_MI2S_TX"}, - {"VoLTE_UL", NULL, "VoLTE_Tx Mixer"}, - - {"VoWLAN_Tx Mixer", "PRI_TX_VoWLAN", "PRI_I2S_TX"}, - {"VoWLAN_Tx Mixer", "SLIM_0_TX_VoWLAN", "SLIMBUS_0_TX"}, - {"VoWLAN_Tx Mixer", "SLIM_7_TX_VoWLAN", "SLIMBUS_7_TX"}, - {"VoWLAN_Tx Mixer", "SLIM_8_TX_VoWLAN", "SLIMBUS_8_TX"}, - {"VoWLAN_Tx Mixer", "USB_AUDIO_TX_VoWLAN", "USB_AUDIO_TX"}, - {"VoWLAN_Tx Mixer", "INTERNAL_BT_SCO_TX_VoWLAN", "INT_BT_SCO_TX"}, - {"VoWLAN_Tx Mixer", "AFE_PCM_TX_VoWLAN", "PCM_TX"}, - {"VoWLAN_Tx Mixer", "AUX_PCM_TX_VoWLAN", "AUX_PCM_TX"}, - {"VoWLAN_Tx Mixer", "SEC_AUX_PCM_TX_VoWLAN", "SEC_AUX_PCM_TX"}, - {"VoWLAN_Tx Mixer", "TERT_AUX_PCM_TX_VoWLAN", "TERT_AUX_PCM_TX"}, - {"VoWLAN_Tx Mixer", "QUAT_AUX_PCM_TX_VoWLAN", "QUAT_AUX_PCM_TX"}, - {"VoWLAN_Tx Mixer", "QUIN_AUX_PCM_TX_VoWLAN", "QUIN_AUX_PCM_TX"}, - {"VoWLAN_Tx Mixer", "MI2S_TX_VoWLAN", "MI2S_TX"}, - {"VoWLAN_Tx Mixer", "PRI_MI2S_TX_VoWLAN", "PRI_MI2S_TX"}, - {"VoWLAN_Tx Mixer", "TERT_MI2S_TX_VoWLAN", "TERT_MI2S_TX"}, - {"VoWLAN_UL", NULL, "VoWLAN_Tx Mixer"}, - {"VoiceMMode1_Tx Mixer", "PRI_TX_MMode1", "PRI_I2S_TX"}, {"VoiceMMode1_Tx Mixer", "PRI_MI2S_TX_MMode1", "PRI_MI2S_TX"}, {"VoiceMMode1_Tx Mixer", "MI2S_TX_MMode1", "MI2S_TX"}, @@ -16195,27 +15941,20 @@ static const struct snd_soc_dapm_route intercon[] = { {"Voice2 Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"VOICE2_STUB_UL", NULL, "Voice2 Stub Tx Mixer"}, - {"STUB_RX Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"STUB_RX Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"STUB_RX Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"STUB_RX Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"STUB_RX Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"STUB_RX", NULL, "STUB_RX Mixer"}, - {"SLIMBUS_1_RX Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"SLIMBUS_1_RX Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"SLIMBUS_1_RX Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + + {"SLIMBUS_1_RX Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIMBUS_1_RX Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Mixer"}, - {"AFE_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"AFE_PCM_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"AFE_PCM_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, - {"SLIMBUS_3_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"SLIMBUS_3_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"SLIMBUS_3_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + + {"SLIMBUS_3_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIMBUS_3_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX_Voice Mixer"}, {"SLIM_7_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"SLIM_7_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SLIM_7_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"SLIM_7_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"SLIM_7_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"SLIM_7_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"SLIM_7_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"SLIM_7_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, @@ -16223,9 +15962,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIM_8_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"SLIM_8_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SLIM_8_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"SLIM_8_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"SLIM_8_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"SLIM_8_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"SLIM_8_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"SLIM_8_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, -- GitLab From 3efc4a220ff7e0e0016d0ad98eb49f6fa8b9776d Mon Sep 17 00:00:00 2001 From: Yunfei Zhang Date: Tue, 7 Nov 2017 16:30:13 +0800 Subject: [PATCH 0109/1645] ASoC: qdsp6v2: Add Audio EC Ref routing to LSM FEs Add routings between LSM FEs and Audio EC Ref, or AFE port for external Audio EC Ref will not be enabled during DSP SVA. Change-Id: Ic70ee9479cd384d0226ac0e92a1824f92ec2d946 Signed-off-by: Yunfei Zhang --- asoc/msm-pcm-routing-v2.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 0aed70c4b522..fa3544d1876a 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -15249,6 +15249,16 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUDIO_REF_EC_UL19 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"AUDIO_REF_EC_UL19 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"LSM1_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM2_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM3_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM4_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM5_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM6_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM7_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM8_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"MM_UL1", NULL, "AUDIO_REF_EC_UL1 MUX"}, {"MM_UL2", NULL, "AUDIO_REF_EC_UL2 MUX"}, {"MM_UL3", NULL, "AUDIO_REF_EC_UL3 MUX"}, -- GitLab From f423ab17d3e196d9694cb6744000610a0af02ad2 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Wed, 22 Nov 2017 11:38:29 -0800 Subject: [PATCH 0110/1645] dsp: unlock the mutex before return to avoid potential deadlock Function "q6asm_set_shared_circ_buff" has a potential scenario that can cause deadlock due to a missing call to unlock mutex before return. Avoid this potential deadlock by calling the mutex unlock just before the return of function "q6asm_set_shared_circ_buff". Change-Id: Ic454eb5eb57c7616d891277c09e0e3bd37e63cd2 Signed-off-by: Xiaoyu Ye --- dsp/q6asm.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 4e988ee489e6..ba6bbb6766eb 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -3541,7 +3541,6 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac, if (ac->port[dir].buf) { pr_err("%s: Buffer already allocated\n", __func__); rc = -EINVAL; - mutex_unlock(&ac->cmd_lock); goto done; } @@ -3564,7 +3563,6 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac, pr_err("%s: Audio ION alloc is failed, rc = %d\n", __func__, rc); kfree(buf_circ); - mutex_unlock(&ac->cmd_lock); goto done; } @@ -3590,8 +3588,8 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac, msm_audio_populate_upper_32_bits(buf_circ->phys); open->map_region_circ_buf.mem_size_bytes = bytes_to_alloc; - mutex_unlock(&ac->cmd_lock); done: + mutex_unlock(&ac->cmd_lock); return rc; } -- GitLab From 092e0edef44b9e2c54d077d05d058dcfa991f28e Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Mon, 11 Dec 2017 16:13:32 +0800 Subject: [PATCH 0111/1645] dsp: send spkr prot calibration after default acdb send dynamic limiter threshold value for spv3 after default ACDB. Otherwise, dynamic value gets overwritten by default ACDB value. Change-Id: Icf509ba3398920439f8bad2a861f946c7472fe78 Signed-off-by: Xiaojun Sang --- dsp/q6afe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 864ae4ad4507..c7495d215a69 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1633,8 +1633,8 @@ void afe_send_cal(u16 port_id) afe_send_cal_spkr_prot_tx(port_id); send_afe_cal_type(AFE_COMMON_TX_CAL, port_id); } else if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) { - afe_send_cal_spkr_prot_rx(port_id); send_afe_cal_type(AFE_COMMON_RX_CAL, port_id); + afe_send_cal_spkr_prot_rx(port_id); } } -- GitLab From ae532a03f1f6afa94cacd64ef77c8871dc38321c Mon Sep 17 00:00:00 2001 From: Preetam Singh Ranawat Date: Fri, 20 Oct 2017 18:06:10 +0530 Subject: [PATCH 0112/1645] asoc: add multiple sampling rates support for a2dp Add support of 44.1Khz, 88.2Khz and 96Khz over split-a2dp path. CRs-Fixed: 2143086 Change-Id: I05e7e947bec250c509f647718323bd208c46b2b2 Signed-off-by: Preetam Singh Ranawat --- asoc/sdm845.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/asoc/sdm845.c b/asoc/sdm845.c index d75174c3d9ca..1bc31fb3ef8e 100644 --- a/asoc/sdm845.c +++ b/asoc/sdm845.c @@ -404,7 +404,9 @@ static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", "KHZ_44P1", "KHZ_48", "KHZ_88P2", "KHZ_96", "KHZ_176P4", "KHZ_192", "KHZ_352P8", "KHZ_384"}; -static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_48"}; +static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; @@ -984,7 +986,16 @@ static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, * value. */ switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: ucontrol->value.integer.value[0] = 2; break; case SAMPLING_RATE_16KHZ: @@ -1010,9 +1021,21 @@ static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; break; case 2: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; break; + case 4: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ; + break; case 0: default: slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; -- GitLab From d99897f5bb23b5c6f05604dd54ab050902187046 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Mon, 13 Nov 2017 23:44:32 -0800 Subject: [PATCH 0113/1645] dsp: codecs: add support to enable multiaac 5.1 channel playback Channel number of multiaac audio decoder is hard-coded to two during the configuration. Modify it to accept different channel numbers to enable 5.1 channel playback. Change-Id: Ibc33ddc7f2ac810a6a34cdbd7a832e58531dfa4f Signed-off-by: Xiaoyu Ye --- dsp/codecs/audio_multi_aac.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dsp/codecs/audio_multi_aac.c b/dsp/codecs/audio_multi_aac.c index c3e616aef423..a026c36af009 100644 --- a/dsp/codecs/audio_multi_aac.c +++ b/dsp/codecs/audio_multi_aac.c @@ -111,7 +111,14 @@ static long audio_ioctl_shared(struct file *file, unsigned int cmd, pr_err("cmd media format block failed\n"); break; } - rc = q6asm_set_encdec_chan_map(audio->ac, 2); + + /* Fall back to the default number of channels + * if aac_cfg.ch_cfg is not between 1-6 + */ + if ((aac_cfg.ch_cfg == 0) || (aac_cfg.ch_cfg > 6)) + aac_cfg.ch_cfg = 2; + + rc = q6asm_set_encdec_chan_map(audio->ac, aac_cfg.ch_cfg); if (rc < 0) { pr_err("%s: cmd set encdec_chan_map failed\n", __func__); -- GitLab From f746a87965615ebcc7ec4de4e66ee0441e7e6fcc Mon Sep 17 00:00:00 2001 From: Preetam Singh Ranawat Date: Fri, 20 Oct 2017 18:13:14 +0530 Subject: [PATCH 0114/1645] dsp: add scrambler support in DSP over split a2dp Add support to enable scrambler in COP Packetizer module over split A2DP path to fix 44.1Khz playback. CRs-Fixed: 2143142 Change-Id: I52fec39e10a1c0939fd49d1e1303b03312544abf Signed-off-by: Preetam Singh Ranawat --- asoc/msm-dai-q6-v2.c | 37 +++++++++++++++++++++++++++++++++++++ dsp/q6afe.c | 28 +++++++++++++++++++++++----- include/dsp/apr_audio-v2.h | 20 ++++++++++++++++++++ 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index af288f1cd8ad..8dec8e29f324 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -2419,6 +2419,36 @@ static int msm_dai_q6_afe_input_bit_format_put( return 0; } +static int msm_dai_q6_afe_scrambler_mode_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (!dai_data) { + pr_err("%s: Invalid dai data\n", __func__); + return -EINVAL; + } + ucontrol->value.integer.value[0] = dai_data->enc_config.scrambler_mode; + + return 0; +} + +static int msm_dai_q6_afe_scrambler_mode_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (!dai_data) { + pr_err("%s: Invalid dai data\n", __func__); + return -EINVAL; + } + dai_data->enc_config.scrambler_mode = ucontrol->value.integer.value[0]; + pr_debug("%s: afe scrambler mode : %d\n", + __func__, dai_data->enc_config.scrambler_mode); + return 0; +} static const struct snd_kcontrol_new afe_enc_config_controls[] = { { @@ -2436,6 +2466,10 @@ static const struct snd_kcontrol_new afe_enc_config_controls[] = { SOC_ENUM_EXT("AFE Input Bit Format", afe_input_bit_format_enum[0], msm_dai_q6_afe_input_bit_format_get, msm_dai_q6_afe_input_bit_format_put), + SOC_SINGLE_EXT("AFE Scrambler Mode", + 0, 0, 1, 0, + msm_dai_q6_afe_scrambler_mode_get, + msm_dai_q6_afe_scrambler_mode_put), }; static int msm_dai_q6_slim_rx_drift_info(struct snd_kcontrol *kcontrol, @@ -2598,6 +2632,9 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&afe_enc_config_controls[2], dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&afe_enc_config_controls[3], + dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&avd_drift_config_controls[2], dai)); diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 864ae4ad4507..5d8486fdfdc3 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2961,7 +2961,8 @@ int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) static int q6afe_send_enc_config(u16 port_id, union afe_enc_config_data *cfg, u32 format, union afe_port_config afe_config, - u16 afe_in_channels, u16 afe_in_bit_width) + u16 afe_in_channels, u16 afe_in_bit_width, + u32 scrambler_mode) { struct afe_audioif_config_command config; int index; @@ -3058,6 +3059,20 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } + config.param.payload_size = + payload_size + sizeof(config.port.enc_set_scrambler_param); + pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING mode= %d to DSP payload = %d\n", + __func__, scrambler_mode, config.param.payload_size); + config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING; + config.pdata.param_size = sizeof(config.port.enc_set_scrambler_param); + config.port.enc_set_scrambler_param.enable_scrambler = scrambler_mode; + ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + config.param.payload_size = payload_size + sizeof(config.port.media_type); config.pdata.param_size = sizeof(config.port.media_type); @@ -3094,7 +3109,8 @@ static int q6afe_send_enc_config(u16 port_id, static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, - union afe_enc_config_data *cfg, u32 enc_format) + union afe_enc_config_data *cfg, u32 enc_format, + u32 scrambler_mode) { struct afe_audioif_config_command config; int ret = 0; @@ -3357,7 +3373,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, __func__, enc_format); ret = q6afe_send_enc_config(port_id, cfg, enc_format, *afe_config, afe_in_channels, - afe_in_bit_width); + afe_in_bit_width, + scrambler_mode); if (ret) { pr_err("%s: AFE encoder config for port 0x%x failed %d\n", __func__, port_id, ret); @@ -3410,7 +3427,7 @@ int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate) { return __afe_port_start(port_id, afe_config, rate, - 0, 0, NULL, ASM_MEDIA_FMT_NONE); + 0, 0, NULL, ASM_MEDIA_FMT_NONE, 0); } EXPORT_SYMBOL(afe_port_start); @@ -3433,7 +3450,8 @@ int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, { return __afe_port_start(port_id, afe_config, rate, afe_in_channels, afe_in_bit_width, - &enc_cfg->data, enc_cfg->format); + &enc_cfg->data, enc_cfg->format, + enc_cfg->scrambler_mode); } EXPORT_SYMBOL(afe_port_start_v2); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index ad0aa44a64bd..d01a5073ec5f 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -3118,6 +3118,12 @@ struct afe_param_id_aptx_sync_mode { */ #define AFE_ENCODER_PARAM_ID_ENC_FMT_ID 0x0001322B +/* + * Encoder scrambler parameter for the #AVS_MODULE_ID_ENCODER module. + * This parameter cannot be set runtime. + */ +#define AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING 0x0001323C + /* * Data format to send compressed data * is transmitted/received over Slimbus lines. @@ -3451,6 +3457,7 @@ union afe_enc_config_data { struct afe_enc_config { u32 format; + u32 scrambler_mode; union afe_enc_config_data data; }; @@ -3474,6 +3481,18 @@ struct avs_enc_packetizer_id_param_t { uint32_t enc_packetizer_id; }; +/* + * Payload of the AVS_ENCODER_PARAM_ID_ENABLE_SCRAMBLING parameter. + */ +struct avs_enc_set_scrambler_param_t { + /* + * Supported values: + * 1 : enable scrambler + * 0 : disable scrambler + */ + uint32_t enable_scrambler; +}; + union afe_port_config { struct afe_param_id_pcm_cfg pcm; struct afe_param_id_i2s_cfg i2s; @@ -3492,6 +3511,7 @@ union afe_port_config { struct afe_port_media_type_t media_type; struct afe_enc_cfg_blk_param_t enc_blk_param; struct avs_enc_packetizer_id_param_t enc_pkt_id_param; + struct avs_enc_set_scrambler_param_t enc_set_scrambler_param; } __packed; struct afe_audioif_config_command_no_payload { -- GitLab From 0a087aff7bb2ad78c09a4a96e7bd39332d359c41 Mon Sep 17 00:00:00 2001 From: Preetam Singh Ranawat Date: Wed, 25 Oct 2017 15:02:28 +0530 Subject: [PATCH 0115/1645] dsp: add LDAC encoder support Add support for LDAC encoding in dsp to enable LDAC encoder over split a2dp path. CRs-Fixed: 2143086 Change-Id: Ia5ed981f5cd9cc61621d667362585ec7a7e64fa1 Signed-off-by: Preetam Singh Ranawat --- asoc/msm-dai-q6-v2.c | 11 ++++++++++ dsp/q6afe.c | 12 ++++++++-- include/dsp/apr_audio-v2.h | 45 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index af288f1cd8ad..756882c447af 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -51,6 +51,7 @@ enum { ENC_FMT_APTX = ASM_MEDIA_FMT_APTX, ENC_FMT_APTX_HD = ASM_MEDIA_FMT_APTX_HD, ENC_FMT_CELT = ASM_MEDIA_FMT_CELT, + ENC_FMT_LDAC = ASM_MEDIA_FMT_LDAC, }; enum { @@ -2263,6 +2264,11 @@ static int msm_dai_q6_afe_enc_cfg_get(struct snd_kcontrol *kcontrol, &dai_data->enc_config.data, sizeof(struct asm_celt_enc_cfg_t)); break; + case ENC_FMT_LDAC: + memcpy(ucontrol->value.bytes.data + format_size, + &dai_data->enc_config.data, + sizeof(struct asm_ldac_enc_cfg_t)); + break; default: pr_debug("%s: unknown format = %d\n", __func__, dai_data->enc_config.format); @@ -2316,6 +2322,11 @@ static int msm_dai_q6_afe_enc_cfg_put(struct snd_kcontrol *kcontrol, ucontrol->value.bytes.data + format_size, sizeof(struct asm_celt_enc_cfg_t)); break; + case ENC_FMT_LDAC: + memcpy(&dai_data->enc_config.data, + ucontrol->value.bytes.data + format_size, + sizeof(struct asm_ldac_enc_cfg_t)); + break; default: pr_debug("%s: Ignore enc config for unknown format = %d\n", __func__, dai_data->enc_config.format); diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 864ae4ad4507..f80d271eb929 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2972,7 +2972,7 @@ static int q6afe_send_enc_config(u16 port_id, pr_debug("%s:update DSP for enc format = %d\n", __func__, format); if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 && format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD && - format != ASM_MEDIA_FMT_CELT) { + format != ASM_MEDIA_FMT_CELT && format != ASM_MEDIA_FMT_LDAC) { pr_err("%s:Unsuppported format Ignore AFE config\n", __func__); return 0; } @@ -3066,7 +3066,15 @@ static int q6afe_send_enc_config(u16 port_id, config.pdata.module_id = AFE_MODULE_PORT; config.pdata.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE; config.port.media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE; - config.port.media_type.sample_rate = afe_config.slim_sch.sample_rate; + if (format == ASM_MEDIA_FMT_LDAC) { + config.port.media_type.sample_rate = + config.port.enc_blk_param.enc_blk_config.ldac_config. + custom_config.sample_rate; + } else { + config.port.media_type.sample_rate = + afe_config.slim_sch.sample_rate; + } + if (afe_in_bit_width) config.port.media_type.bit_width = afe_in_bit_width; else diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index ad0aa44a64bd..bc1763216cb2 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -3377,6 +3377,50 @@ struct asm_celt_enc_cfg_t { struct asm_celt_specific_enc_cfg_t celt_specific_config; } __packed; +#define ASM_MEDIA_FMT_LDAC 0x00013224 +struct asm_ldac_specific_enc_cfg_t { + /* + * This is used to calculate the encoder output + * bytes per frame (i.e. bytes per packet). + * Bit rate also configures the EQMID. + * The min bit rate 303000 bps is calculated for + * 44.1 kHz and 88.2 KHz sampling frequencies with + * Mobile use Quality. + * The max bit rate of 990000 bps is calculated for + * 96kHz and 48 KHz with High Quality + * @Range(in bits per second) + * 303000 for Mobile use Quality + * 606000 for standard Quality + * 909000 for High Quality + */ + uint32_t bit_rate; + /* + * The channel setting information for LDAC specification + * of Bluetooth A2DP which is determined by SRC and SNK + * devices in Bluetooth transmission. + * @Range: + * 0 for native mode + * 4 for mono + * 2 for dual channel + * 1 for stereo + */ + uint16_t channel_mode; + /* + * Maximum Transmission Unit (MTU). + * The minimum MTU that a L2CAP implementation for LDAC shall + * support is 679 bytes, because LDAC is optimized with 2-DH5 + * packet as its target. + * @Range : 679 + * @Default: 679 for LDACBT_MTU_2DH5 + */ + uint16_t mtu; +} __packed; + +struct asm_ldac_enc_cfg_t { + struct asm_custom_enc_cfg_t custom_config; + struct asm_ldac_specific_enc_cfg_t ldac_specific_config; +} __packed; + struct afe_enc_fmt_id_param_t { /* * Supported values: @@ -3447,6 +3491,7 @@ union afe_enc_config_data { struct asm_custom_enc_cfg_t custom_config; struct asm_celt_enc_cfg_t celt_config; struct asm_aptx_enc_cfg_t aptx_config; + struct asm_ldac_enc_cfg_t ldac_config; }; struct afe_enc_config { -- GitLab From 5392d8052e1a81bad1c1da097cd2900f0ff6c4aa Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 8 Nov 2017 20:32:38 -0800 Subject: [PATCH 0116/1645] asoc: codecs: modify gnd mic swap threshold for usb-c analog To reduce time of usb-c analog headset detection, reduce gnd mic swap threshold if usb-c is enabled. Use existing threshold value otherwise. CRs-Fixed: 2137077 Change-Id: Ic1d1f3a00c9034caaac45f2c80f018546a69ce59 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd-mbhc-adc.c | 10 +++++----- asoc/codecs/wcd-mbhc-legacy.c | 8 ++++---- asoc/codecs/wcd-mbhc-v2.c | 2 ++ asoc/codecs/wcd-mbhc-v2.h | 2 ++ 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index bcb616e7d700..920796f2e39d 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -622,7 +622,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) do { cross_conn = wcd_check_cross_conn(mbhc); try++; - } while (try < GND_MIC_SWAP_THRESHOLD); + } while (try < mbhc->swap_thr); if (cross_conn > 0) { plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; @@ -714,10 +714,10 @@ static void wcd_correct_swch_plug(struct work_struct *work) pt_gnd_mic_swap_cnt++; no_gnd_mic_swap_cnt = 0; if (pt_gnd_mic_swap_cnt < - GND_MIC_SWAP_THRESHOLD) { + mbhc->swap_thr) { continue; } else if (pt_gnd_mic_swap_cnt > - GND_MIC_SWAP_THRESHOLD) { + mbhc->swap_thr) { /* * This is due to GND/MIC switch didn't * work, Report unsupported plug. @@ -735,14 +735,14 @@ static void wcd_correct_swch_plug(struct work_struct *work) plug_type = wcd_mbhc_get_plug_from_adc( mbhc, output_mv); if ((no_gnd_mic_swap_cnt < - GND_MIC_SWAP_THRESHOLD) && + mbhc->swap_thr) && (spl_hs_count != WCD_MBHC_SPL_HS_CNT)) { continue; } else { no_gnd_mic_swap_cnt = 0; } } - if ((pt_gnd_mic_swap_cnt == GND_MIC_SWAP_THRESHOLD) && + if ((pt_gnd_mic_swap_cnt == mbhc->swap_thr) && (plug_type == MBHC_PLUG_TYPE_GND_MIC_SWAP)) { /* * if switch is toggled, check again, diff --git a/asoc/codecs/wcd-mbhc-legacy.c b/asoc/codecs/wcd-mbhc-legacy.c index a72f64b40861..9f6a6254986f 100644 --- a/asoc/codecs/wcd-mbhc-legacy.c +++ b/asoc/codecs/wcd-mbhc-legacy.c @@ -498,7 +498,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) do { cross_conn = wcd_check_cross_conn(mbhc); try++; - } while (try < GND_MIC_SWAP_THRESHOLD); + } while (try < mbhc->swap_thr); /* * Check for cross connection 4 times. @@ -599,10 +599,10 @@ static void wcd_correct_swch_plug(struct work_struct *work) pt_gnd_mic_swap_cnt++; no_gnd_mic_swap_cnt = 0; if (pt_gnd_mic_swap_cnt < - GND_MIC_SWAP_THRESHOLD) { + mbhc->swap_thr) { continue; } else if (pt_gnd_mic_swap_cnt > - GND_MIC_SWAP_THRESHOLD) { + mbhc->swap_thr) { /* * This is due to GND/MIC switch didn't * work, Report unsupported plug. @@ -626,7 +626,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) no_gnd_mic_swap_cnt = 0; } } - if ((pt_gnd_mic_swap_cnt == GND_MIC_SWAP_THRESHOLD) && + if ((pt_gnd_mic_swap_cnt == mbhc->swap_thr) && (plug_type == MBHC_PLUG_TYPE_GND_MIC_SWAP)) { /* * if switch is toggled, check again, diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 3c501b490084..6088a1ee09a7 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -1707,6 +1707,7 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) if (mbhc_cfg->enable_usbc_analog) { dev_dbg(mbhc->codec->dev, "%s: usbc analog enabled\n", __func__); + mbhc->swap_thr = GND_MIC_USBC_SWAP_THRESHOLD; rc = wcd_mbhc_init_gpio(mbhc, mbhc_cfg, "qcom,usbc-analog-en1-gpio", &config->usbc_en1_gpio, @@ -1901,6 +1902,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, mbhc->extn_cable_hph_rem = false; mbhc->hph_type = WCD_MBHC_HPH_NONE; mbhc->wcd_mbhc_regs = wcd_mbhc_regs; + mbhc->swap_thr = GND_MIC_SWAP_THRESHOLD; if (mbhc->intr_ids == NULL) { pr_err("%s: Interrupt mapping not provided\n", __func__); diff --git a/asoc/codecs/wcd-mbhc-v2.h b/asoc/codecs/wcd-mbhc-v2.h index 0c57eee8a454..bdae77630f02 100644 --- a/asoc/codecs/wcd-mbhc-v2.h +++ b/asoc/codecs/wcd-mbhc-v2.h @@ -142,6 +142,7 @@ do { \ #define SPECIAL_HS_DETECT_TIME_MS (2 * 1000) #define MBHC_BUTTON_PRESS_THRESHOLD_MIN 250 #define GND_MIC_SWAP_THRESHOLD 4 +#define GND_MIC_USBC_SWAP_THRESHOLD 2 #define WCD_FAKE_REMOVAL_MIN_PERIOD_MS 100 #define HS_VREF_MIN_VAL 1400 #define FW_READ_ATTEMPTS 15 @@ -524,6 +525,7 @@ struct wcd_mbhc { bool gnd_swh; /*track GND switch NC / NO */ u32 hs_thr; u32 hph_thr; + u32 swap_thr; u32 moist_vref; u32 moist_iref; u32 moist_rref; -- GitLab From 9e31a8a6e38c7b95b79e35132d0629c9d5abd4f1 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Thu, 16 Nov 2017 18:40:14 -0800 Subject: [PATCH 0117/1645] asoc: sdm845: check sound card status before sending AFE config WCD codec must be enumerated before AFE configuration for some of the features can be sent to DSP. This is because as part of setting up this configuration, DSP tries to access some codec register. These register accesses will fail if codec is not enumerated already. Add a check for Sound Card online state to confirm that WCD codec has already enumerated before sending AFE configs. Change-Id: I0b7e5eb49e4f6c6aee9cb142054e57eae592602b Signed-off-by: Banajit Goswami --- asoc/sdm845.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/asoc/sdm845.c b/asoc/sdm845.c index d75174c3d9ca..3eb20a2d4969 100644 --- a/asoc/sdm845.c +++ b/asoc/sdm845.c @@ -3618,31 +3618,44 @@ static void msm_afe_clear_config(void) afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); } -static int msm_adsp_power_up_config(struct snd_soc_codec *codec) +static int msm_adsp_power_up_config(struct snd_soc_codec *codec, + struct snd_card *card) { int ret = 0; unsigned long timeout; int adsp_ready = 0; + bool snd_card_online = 0; timeout = jiffies + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); do { - if (q6core_is_adsp_ready()) { - pr_debug("%s: ADSP Audio is ready\n", __func__); - adsp_ready = 1; - break; + if (!snd_card_online) { + snd_card_online = snd_card_is_online_state(card); + pr_debug("%s: Sound card is %s\n", __func__, + snd_card_online ? "Online" : "Offline"); + } + if (!adsp_ready) { + adsp_ready = q6core_is_adsp_ready(); + pr_debug("%s: ADSP Audio is %s\n", __func__, + adsp_ready ? "ready" : "not ready"); } + if (snd_card_online && adsp_ready) + break; + /* - * ADSP will be coming up after subsystem restart and + * Sound card/ADSP will be coming up after subsystem restart and * it might not be fully up when the control reaches * here. So, wait for 50msec before checking ADSP state */ msleep(50); } while (time_after(timeout, jiffies)); - if (!adsp_ready) { - pr_err("%s: timed out waiting for ADSP Audio\n", __func__); + if (!snd_card_online || !adsp_ready) { + pr_err("%s: Timeout. Sound card is %s, ADSP Audio is %s\n", + __func__, + snd_card_online ? "Online" : "Offline", + adsp_ready ? "ready" : "not ready"); ret = -ETIMEDOUT; goto err; } @@ -3700,7 +3713,7 @@ static int sdm845_notifier_service_cb(struct notifier_block *this, } codec = rtd->codec; - ret = msm_adsp_power_up_config(codec); + ret = msm_adsp_power_up_config(codec, card->snd_card); if (ret < 0) { dev_err(card->dev, "%s: msm_adsp_power_up_config failed ret = %d!\n", @@ -3798,7 +3811,7 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) msm_codec_fn.get_afe_config_fn = tavil_get_afe_config; - ret = msm_adsp_power_up_config(codec); + ret = msm_adsp_power_up_config(codec, rtd->card->snd_card); if (ret) { pr_err("%s: Failed to set AFE config %d\n", __func__, ret); goto err; @@ -7046,6 +7059,7 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + audio_notifier_deregister("sdm845"); if (pdata->us_euro_gpio > 0) { gpio_free(pdata->us_euro_gpio); pdata->us_euro_gpio = 0; @@ -7054,7 +7068,6 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) msm_release_pinctrl(pdev); snd_soc_unregister_card(card); - audio_notifier_deregister("sdm845"); return 0; } -- GitLab From 3889b4aebb018fd745f583acd8e1d40c937f97e6 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 21 Nov 2017 19:52:26 +0530 Subject: [PATCH 0118/1645] dsp: add support for new AFE LSM cal types Add support for new AFE LSM cal types in order to avoid topology and cal block overriding during concurrent use cases like SVA with speaker protection. CRs-Fixed: 2085865 Change-Id: I9af5c34ea7ad9403b9e6d63ac5d3e73e708a320e Signed-off-by: Aditya Bavanari --- dsp/audio_cal_utils.c | 4 ++ dsp/q6afe.c | 55 ++++++++++++++++++---- include/uapi/linux/msm_audio_calibration.h | 5 ++ 3 files changed, 54 insertions(+), 10 deletions(-) diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index ffd3929dd3d5..743bd93ce846 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -77,6 +77,7 @@ size_t get_cal_info_size(int32_t cal_type) size = sizeof(struct audio_cal_info_audstrm); break; case AFE_TOPOLOGY_CAL_TYPE: + case AFE_LSM_TOPOLOGY_CAL_TYPE: size = sizeof(struct audio_cal_info_afe_top); break; case AFE_CUST_TOPOLOGY_CAL_TYPE: @@ -86,6 +87,7 @@ size_t get_cal_info_size(int32_t cal_type) size = sizeof(struct audio_cal_info_afe); break; case AFE_COMMON_TX_CAL_TYPE: + case AFE_LSM_TX_CAL_TYPE: size = sizeof(struct audio_cal_info_afe); break; case AFE_FB_SPKR_PROT_CAL_TYPE: @@ -223,6 +225,7 @@ size_t get_user_cal_type_size(int32_t cal_type) size = sizeof(struct audio_cal_type_audstrm); break; case AFE_TOPOLOGY_CAL_TYPE: + case AFE_LSM_TOPOLOGY_CAL_TYPE: size = sizeof(struct audio_cal_type_afe_top); break; case AFE_CUST_TOPOLOGY_CAL_TYPE: @@ -232,6 +235,7 @@ size_t get_user_cal_type_size(int32_t cal_type) size = sizeof(struct audio_cal_type_afe); break; case AFE_COMMON_TX_CAL_TYPE: + case AFE_LSM_TX_CAL_TYPE: size = sizeof(struct audio_cal_type_afe); break; case AFE_FB_SPKR_PROT_CAL_TYPE: diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 864ae4ad4507..481f4b1051d7 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -30,12 +30,14 @@ enum { AFE_COMMON_RX_CAL = 0, AFE_COMMON_TX_CAL, + AFE_LSM_TX_CAL, AFE_AANC_CAL, AFE_FB_SPKR_PROT_CAL, AFE_HW_DELAY_CAL, AFE_SIDETONE_CAL, AFE_SIDETONE_IIR_CAL, AFE_TOPOLOGY_CAL, + AFE_LSM_TOPOLOGY_CAL, AFE_CUST_TOPOLOGY_CAL, AFE_FB_SPKR_PROT_TH_VI_CAL, AFE_FB_SPKR_PROT_EX_VI_CAL, @@ -1396,14 +1398,15 @@ static struct cal_block_data *afe_find_cal_topo_id_by_port( return NULL; } -static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id) +static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id, + int cal_type_index) { int ret = 0; struct cal_block_data *cal_block = NULL; struct audio_cal_info_afe_top *afe_top_info = NULL; - if (this_afe.cal_data[AFE_TOPOLOGY_CAL] == NULL) { + if (this_afe.cal_data[cal_type_index] == NULL) { pr_err("%s: [AFE_TOPOLOGY_CAL] not initialized\n", __func__); return -EINVAL; } @@ -1413,9 +1416,9 @@ static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id) } *topology_id = 0; - mutex_lock(&this_afe.cal_data[AFE_TOPOLOGY_CAL]->lock); + mutex_lock(&this_afe.cal_data[cal_type_index]->lock); cal_block = afe_find_cal_topo_id_by_port( - this_afe.cal_data[AFE_TOPOLOGY_CAL], port_id); + this_afe.cal_data[cal_type_index], port_id); if (cal_block == NULL) { pr_err("%s: [AFE_TOPOLOGY_CAL] not initialized for this port %d\n", __func__, port_id); @@ -1437,7 +1440,7 @@ static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id) __func__, port_id, afe_top_info->acdb_id, afe_top_info->topology, ret); unlock: - mutex_unlock(&this_afe.cal_data[AFE_TOPOLOGY_CAL]->lock); + mutex_unlock(&this_afe.cal_data[cal_type_index]->lock); return ret; } @@ -1455,7 +1458,12 @@ static int afe_send_port_topology_id(u16 port_id) return -EINVAL; } - ret = afe_get_cal_topology_id(port_id, &topology_id); + ret = afe_get_cal_topology_id(port_id, &topology_id, AFE_TOPOLOGY_CAL); + if (ret < 0) { + pr_debug("%s: Check for LSM topology\n", __func__); + ret = afe_get_cal_topology_id(port_id, &topology_id, + AFE_LSM_TOPOLOGY_CAL); + } if (ret || !topology_id) { pr_debug("%s: AFE port[%d] get_cal_topology[%d] invalid!\n", __func__, port_id, topology_id); @@ -1572,7 +1580,7 @@ static struct cal_block_data *afe_find_cal(int cal_index, int port_id) return cal_block; } -static void send_afe_cal_type(int cal_index, int port_id) +static int send_afe_cal_type(int cal_index, int port_id) { struct cal_block_data *cal_block = NULL; int ret; @@ -1583,19 +1591,22 @@ static void send_afe_cal_type(int cal_index, int port_id) if (this_afe.cal_data[cal_index] == NULL) { pr_warn("%s: cal_index %d not allocated!\n", __func__, cal_index); + ret = -EINVAL; goto done; } if (afe_port_index < 0) { pr_err("%s: Error getting AFE port index %d\n", __func__, afe_port_index); + ret = -EINVAL; goto done; } mutex_lock(&this_afe.cal_data[cal_index]->lock); if (((cal_index == AFE_COMMON_RX_CAL) || - (cal_index == AFE_COMMON_TX_CAL)) && + (cal_index == AFE_COMMON_TX_CAL) || + (cal_index == AFE_LSM_TX_CAL)) && (this_afe.dev_acdb_id[afe_port_index] > 0)) cal_block = afe_find_cal(cal_index, port_id); else @@ -1604,6 +1615,7 @@ static void send_afe_cal_type(int cal_index, int port_id) if (cal_block == NULL) { pr_err("%s cal_block not found!!\n", __func__); + ret = -EINVAL; goto unlock; } @@ -1613,6 +1625,7 @@ static void send_afe_cal_type(int cal_index, int port_id) if (ret) { pr_err("%s: Remap_cal_data failed for cal %d!\n", __func__, cal_index); + ret = -EINVAL; goto unlock; } ret = afe_send_cal_block(port_id, cal_block); @@ -1622,16 +1635,20 @@ static void send_afe_cal_type(int cal_index, int port_id) unlock: mutex_unlock(&this_afe.cal_data[cal_index]->lock); done: - return; + return ret; } void afe_send_cal(u16 port_id) { + int ret; + pr_debug("%s: port_id=0x%x\n", __func__, port_id); if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX) { afe_send_cal_spkr_prot_tx(port_id); - send_afe_cal_type(AFE_COMMON_TX_CAL, port_id); + ret = send_afe_cal_type(AFE_COMMON_TX_CAL, port_id); + if (ret < 0) + send_afe_cal_type(AFE_LSM_TX_CAL, port_id); } else if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) { afe_send_cal_spkr_prot_rx(port_id); send_afe_cal_type(AFE_COMMON_RX_CAL, port_id); @@ -6888,6 +6905,9 @@ static int get_cal_type_index(int32_t cal_type) case AFE_COMMON_TX_CAL_TYPE: ret = AFE_COMMON_TX_CAL; break; + case AFE_LSM_TX_CAL_TYPE: + ret = AFE_LSM_TX_CAL; + break; case AFE_AANC_CAL_TYPE: ret = AFE_AANC_CAL; break; @@ -6906,6 +6926,9 @@ static int get_cal_type_index(int32_t cal_type) case AFE_TOPOLOGY_CAL_TYPE: ret = AFE_TOPOLOGY_CAL; break; + case AFE_LSM_TOPOLOGY_CAL_TYPE: + ret = AFE_LSM_TOPOLOGY_CAL; + break; case AFE_CUST_TOPOLOGY_CAL_TYPE: ret = AFE_CUST_TOPOLOGY_CAL; break; @@ -7408,6 +7431,12 @@ static int afe_init_cal_data(void) {afe_map_cal_data, afe_unmap_cal_data, cal_utils_match_buf_num} }, + {{AFE_LSM_TX_CAL_TYPE, + {afe_alloc_cal, afe_dealloc_cal, NULL, + afe_set_cal, NULL, NULL} }, + {afe_map_cal_data, afe_unmap_cal_data, + cal_utils_match_buf_num} }, + {{AFE_AANC_CAL_TYPE, {afe_alloc_cal, afe_dealloc_cal, NULL, afe_set_cal, NULL, NULL} }, @@ -7440,6 +7469,12 @@ static int afe_init_cal_data(void) {NULL, NULL, cal_utils_match_buf_num} }, + {{AFE_LSM_TOPOLOGY_CAL_TYPE, + {NULL, NULL, NULL, + afe_set_cal, NULL, NULL} }, + {NULL, NULL, + cal_utils_match_buf_num} }, + {{AFE_CUST_TOPOLOGY_CAL_TYPE, {afe_alloc_cal, afe_dealloc_cal, NULL, afe_set_cal, NULL, NULL} }, diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h index 29fdf8f966e6..27dacde651f1 100644 --- a/include/uapi/linux/msm_audio_calibration.h +++ b/include/uapi/linux/msm_audio_calibration.h @@ -99,6 +99,8 @@ enum { AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE, AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE, AFE_SIDETONE_IIR_CAL_TYPE, + AFE_LSM_TOPOLOGY_CAL_TYPE, + AFE_LSM_TX_CAL_TYPE, MAX_CAL_TYPES, }; @@ -107,6 +109,9 @@ enum { #define AFE_SIDETONE_IIR_CAL_TYPE AFE_SIDETONE_IIR_CAL_TYPE +#define AFE_LSM_TOPOLOGY_CAL_TYPE AFE_LSM_TOPOLOGY_CAL_TYPE +#define AFE_LSM_TX_CAL_TYPE AFE_LSM_TX_CAL_TYPE + #define TOPOLOGY_SPECIFIC_CHANNEL_INFO #define MSM_SPKR_PROT_SPV3 -- GitLab From 5e53248e0622f4bc07628c143d69445b5cbe045f Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 22 Nov 2017 14:15:57 -0800 Subject: [PATCH 0119/1645] autoconf: sdm845: remove unused configs Remove duplicates and unused configs from the config header file. CRs-fixed: 2147443 Change-Id: I10735b0a344e575591c128bd9ca74850c068023d Signed-off-by: Karthikeyan Mani --- config/sdm845autoconf.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/config/sdm845autoconf.h b/config/sdm845autoconf.h index 5bd70f614fa6..fcef4c13e776 100644 --- a/config/sdm845autoconf.h +++ b/config/sdm845autoconf.h @@ -13,14 +13,11 @@ #define CONFIG_PINCTRL_WCD 1 #define CONFIG_SND_SOC_WCD934X 1 -#define CONFIG_AUDIO_EXT_CLK 1 #define CONFIG_SND_SOC_WCD9XXX_V2 1 #define CONFIG_SND_SOC_WCD_CPE 1 #define CONFIG_SND_SOC_WCD_MBHC 1 #define CONFIG_SND_SOC_WSA881X 1 -#define CONFIG_SND_SOC_WCD_DSP_MGR 1 #define CONFIG_SND_SOC_WCD_SPI 1 -#define CONFIG_SND_SOC_WCD934X 1 #define CONFIG_SND_SOC_WCD934X_MBHC 1 #define CONFIG_SND_SOC_WCD934X_DSD 1 #define CONFIG_MSM_QDSP6V2_CODECS 1 @@ -33,14 +30,12 @@ #define CONFIG_MSM_QDSP6_PDR 1 #define CONFIG_MSM_QDSP6_NOTIFIER 1 #define CONFIG_SND_SOC_MSM_HOSTLESS_PCM 1 -#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 #define CONFIG_SND_SOC_SDM845 1 #define CONFIG_MSM_GLINK_SPI_XPRT 1 #define CONFIG_SOUNDWIRE 1 #define CONFIG_SOUNDWIRE_WCD_CTRL 1 #define CONFIG_SND_SOC_WCD_MBHC_ADC 1 #define CONFIG_SND_SOC_QDSP6V2 1 -#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 #define CONFIG_MSM_CDC_PINCTRL 1 #define CONFIG_QTI_PP 1 #define CONFIG_SND_HWDEP 1 -- GitLab From 2a627ae4bbaff3338a22bb6b7f2809ac9c4a208d Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 21 Nov 2017 20:24:53 +0530 Subject: [PATCH 0120/1645] dsp: add support for new ADM LSM cal types Add support for new ADM LSM cal types in order to avoid topology and cal block overriding during concurrent use cases like SVA with speaker protection. CRs-Fixed: 2085865 Change-Id: I155d29ff0b77b069aa5970408332064c5c2aebd7 Signed-off-by: Aditya Bavanari --- asoc/msm-pcm-routing-v2.c | 101 +++++++++++++++------ asoc/msm-pcm-routing-v2.h | 6 ++ dsp/audio_cal_utils.c | 4 + dsp/q6adm.c | 34 +++++-- include/dsp/q6adm-v2.h | 2 + include/uapi/linux/msm_audio_calibration.h | 5 + 6 files changed, 116 insertions(+), 36 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 0aed70c4b522..af0b40ed1844 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -57,7 +57,7 @@ static struct mutex routing_lock; -static struct cal_type_data *cal_data; +static struct cal_type_data *cal_data[MAX_ROUTING_CAL_TYPES]; static int fm_switch_enable; static int hfp_switch_enable; @@ -883,21 +883,21 @@ int msm_pcm_routing_get_stream_app_type_cfg( } EXPORT_SYMBOL(msm_pcm_routing_get_stream_app_type_cfg); -static struct cal_block_data *msm_routing_find_topology_by_path(int path) +static struct cal_block_data *msm_routing_find_topology_by_path(int path, + int cal_index) { - struct list_head *ptr, *next; - struct cal_block_data *cal_block = NULL; - + struct list_head *ptr, *next; + struct cal_block_data *cal_block = NULL; pr_debug("%s\n", __func__); list_for_each_safe(ptr, next, - &cal_data->cal_blocks) { + &cal_data[cal_index]->cal_blocks) { cal_block = list_entry(ptr, struct cal_block_data, list); - if (((struct audio_cal_info_adm_top *)cal_block->cal_info) - ->path == path) { + if (((struct audio_cal_info_adm_top *)cal_block + ->cal_info)->path == path) { return cal_block; } } @@ -907,7 +907,8 @@ static struct cal_block_data *msm_routing_find_topology_by_path(int path) static struct cal_block_data *msm_routing_find_topology(int path, int app_type, - int acdb_id) + int acdb_id, + int cal_index) { struct list_head *ptr, *next; struct cal_block_data *cal_block = NULL; @@ -916,7 +917,7 @@ static struct cal_block_data *msm_routing_find_topology(int path, pr_debug("%s\n", __func__); list_for_each_safe(ptr, next, - &cal_data->cal_blocks) { + &cal_data[cal_index]->cal_blocks) { cal_block = list_entry(ptr, struct cal_block_data, list); @@ -931,7 +932,7 @@ static struct cal_block_data *msm_routing_find_topology(int path, } pr_debug("%s: Can't find topology for path %d, app %d, acdb_id %d defaulting to search by path\n", __func__, path, app_type, acdb_id); - return msm_routing_find_topology_by_path(path); + return msm_routing_find_topology_by_path(cal_index, path); } static int msm_routing_get_adm_topology(int fedai_id, int session_type, @@ -941,28 +942,37 @@ static int msm_routing_get_adm_topology(int fedai_id, int session_type, struct cal_block_data *cal_block = NULL; int app_type = 0, acdb_dev_id = 0; - pr_debug("%s: fedai_id %d, session_type %d, be_id %d\n", __func__, fedai_id, session_type, be_id); if (cal_data == NULL) goto done; - mutex_lock(&cal_data->lock); - app_type = fe_dai_app_type_cfg[fedai_id][session_type][be_id].app_type; acdb_dev_id = fe_dai_app_type_cfg[fedai_id][session_type][be_id].acdb_dev_id; + mutex_lock(&cal_data[ADM_TOPOLOGY_CAL_TYPE_IDX]->lock); cal_block = msm_routing_find_topology(session_type, app_type, - acdb_dev_id); - if (cal_block == NULL) - goto unlock; - - topology = ((struct audio_cal_info_adm_top *) - cal_block->cal_info)->topology; -unlock: - mutex_unlock(&cal_data->lock); + acdb_dev_id, + ADM_TOPOLOGY_CAL_TYPE_IDX); + if (cal_block != NULL) + topology = ((struct audio_cal_info_adm_top *) + cal_block->cal_info)->topology; + mutex_unlock(&cal_data[ADM_TOPOLOGY_CAL_TYPE_IDX]->lock); + + if (cal_block == NULL) { + pr_debug("%s: Check for LSM topology\n", __func__); + mutex_lock(&cal_data[ADM_LSM_TOPOLOGY_CAL_TYPE_IDX]->lock); + cal_block = msm_routing_find_topology(session_type, app_type, + acdb_dev_id, + ADM_LSM_TOPOLOGY_CAL_TYPE_IDX); + if (cal_block != NULL) + topology = ((struct audio_cal_info_adm_top *) + cal_block->cal_info)->topology; + mutex_unlock(&cal_data[ADM_LSM_TOPOLOGY_CAL_TYPE_IDX]->lock); + } + done: pr_debug("%s: Using topology %d\n", __func__, topology); return topology; @@ -2562,6 +2572,7 @@ static int msm_routing_lsm_func_put(struct snd_kcontrol *kcontrol, pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, mad_type); + adm_set_lsm_port_id(port_id); return afe_port_set_mad_type(port_id, mad_type); } @@ -17146,14 +17157,39 @@ int msm_routing_check_backend_enabled(int fedai_id) return 0; } +static int get_cal_type_index(int32_t cal_type) +{ + int ret = -EINVAL; + + switch (cal_type) { + case ADM_TOPOLOGY_CAL_TYPE: + ret = ADM_TOPOLOGY_CAL_TYPE_IDX; + break; + case ADM_LSM_TOPOLOGY_CAL_TYPE: + ret = ADM_LSM_TOPOLOGY_CAL_TYPE_IDX; + break; + default: + pr_err("%s: Invalid cal type %d\n", __func__, cal_type); + } + return ret; +} + static int msm_routing_set_cal(int32_t cal_type, size_t data_size, void *data) { int ret = 0; - + int cal_index; pr_debug("%s\n", __func__); - ret = cal_utils_set_cal(data_size, data, cal_data, 0, NULL); + cal_index = get_cal_type_index(cal_type); + if (cal_index < 0) { + pr_err("%s: Could not get cal index %d\n", + __func__, cal_index); + ret = -EINVAL; + goto done; + } + + ret = cal_utils_set_cal(data_size, data, cal_data[cal_index], 0, NULL); if (ret < 0) { pr_err("%s: cal_utils_set_cal failed, ret = %d, cal type = %d!\n", __func__, ret, cal_type); @@ -17168,22 +17204,27 @@ static void msm_routing_delete_cal_data(void) { pr_debug("%s\n", __func__); - cal_utils_destroy_cal_types(1, &cal_data); + cal_utils_destroy_cal_types(MAX_ROUTING_CAL_TYPES, &cal_data[0]); } static int msm_routing_init_cal_data(void) { int ret = 0; - struct cal_type_info cal_type_info = { - {ADM_TOPOLOGY_CAL_TYPE, + struct cal_type_info cal_type_info[] = { + {{ADM_TOPOLOGY_CAL_TYPE, + {NULL, NULL, NULL, + msm_routing_set_cal, NULL, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, + + {{ADM_LSM_TOPOLOGY_CAL_TYPE, {NULL, NULL, NULL, msm_routing_set_cal, NULL, NULL} }, - {NULL, NULL, cal_utils_match_buf_num} + {NULL, NULL, cal_utils_match_buf_num} }, }; pr_debug("%s\n", __func__); - ret = cal_utils_create_cal_types(1, &cal_data, - &cal_type_info); + ret = cal_utils_create_cal_types(MAX_ROUTING_CAL_TYPES, &cal_data[0], + &cal_type_info[0]); if (ret < 0) { pr_err("%s: could not create cal type!\n", __func__); diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 5360b5b5f770..a1977b4b3737 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -433,6 +433,12 @@ enum { #define BE_DAI_PORT_SESSIONS_IDX_MAX 4 #define BE_DAI_FE_SESSIONS_IDX_MAX 2 +enum { + ADM_TOPOLOGY_CAL_TYPE_IDX = 0, + ADM_LSM_TOPOLOGY_CAL_TYPE_IDX, + MAX_ROUTING_CAL_TYPES +}; + struct msm_pcm_routing_evt { void (*event_func)(enum msm_pcm_routing_event, void *); void *priv_data; diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index 743bd93ce846..ad1dc3d35ce3 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -54,6 +54,7 @@ size_t get_cal_info_size(int32_t cal_type) size = sizeof(struct audio_cal_info_voc_col); break; case ADM_TOPOLOGY_CAL_TYPE: + case ADM_LSM_TOPOLOGY_CAL_TYPE: size = sizeof(struct audio_cal_info_adm_top); break; case ADM_CUST_TOPOLOGY_CAL_TYPE: @@ -61,6 +62,7 @@ size_t get_cal_info_size(int32_t cal_type) size = 0; break; case ADM_AUDPROC_CAL_TYPE: + case ADM_LSM_AUDPROC_CAL_TYPE: size = sizeof(struct audio_cal_info_audproc); break; case ADM_AUDVOL_CAL_TYPE: @@ -202,6 +204,7 @@ size_t get_user_cal_type_size(int32_t cal_type) size = sizeof(struct audio_cal_type_voc_col); break; case ADM_TOPOLOGY_CAL_TYPE: + case ADM_LSM_TOPOLOGY_CAL_TYPE: size = sizeof(struct audio_cal_type_adm_top); break; case ADM_CUST_TOPOLOGY_CAL_TYPE: @@ -209,6 +212,7 @@ size_t get_user_cal_type_size(int32_t cal_type) size = sizeof(struct audio_cal_type_basic); break; case ADM_AUDPROC_CAL_TYPE: + case ADM_LSM_AUDPROC_CAL_TYPE: size = sizeof(struct audio_cal_type_audproc); break; case ADM_AUDVOL_CAL_TYPE: diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 77c28976e379..2539be54a94c 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -104,6 +104,7 @@ struct adm_ctl { int num_ec_ref_rx_chans; int ec_ref_rx_bit_width; int ec_ref_rx_sampling_rate; + int lsm_port_id; }; static struct adm_ctl this_adm; @@ -2144,7 +2145,8 @@ static struct cal_block_data *adm_find_cal_by_path(int cal_index, int path) cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_index == ADM_AUDPROC_CAL) { + if (cal_index == ADM_AUDPROC_CAL || + cal_index == ADM_LSM_AUDPROC_CAL) { audproc_cal_info = cal_block->cal_info; if ((audproc_cal_info->path == path) && (cal_block->cal_data.size > 0)) @@ -2177,7 +2179,8 @@ static struct cal_block_data *adm_find_cal_by_app_type(int cal_index, int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_index == ADM_AUDPROC_CAL) { + if (cal_index == ADM_AUDPROC_CAL || + cal_index == ADM_LSM_AUDPROC_CAL) { audproc_cal_info = cal_block->cal_info; if ((audproc_cal_info->path == path) && (audproc_cal_info->app_type == app_type) && @@ -2214,7 +2217,8 @@ static struct cal_block_data *adm_find_cal(int cal_index, int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_index == ADM_AUDPROC_CAL) { + if (cal_index == ADM_AUDPROC_CAL || + cal_index == ADM_LSM_AUDPROC_CAL) { audproc_cal_info = cal_block->cal_info; if ((audproc_cal_info->path == path) && (audproc_cal_info->app_type == app_type) && @@ -2295,13 +2299,22 @@ static int get_cal_path(int path) return TX_DEVICE; } +void adm_set_lsm_port_id(int port_id) +{ + this_adm.lsm_port_id = port_id; +} + static void send_adm_cal(int port_id, int copp_idx, int path, int perf_mode, int app_type, int acdb_id, int sample_rate) { pr_debug("%s: port id 0x%x copp_idx %d\n", __func__, port_id, copp_idx); - send_adm_cal_type(ADM_AUDPROC_CAL, path, port_id, copp_idx, perf_mode, - app_type, acdb_id, sample_rate); + if (port_id != this_adm.lsm_port_id) + send_adm_cal_type(ADM_AUDPROC_CAL, path, port_id, copp_idx, + perf_mode, app_type, acdb_id, sample_rate); + else + send_adm_cal_type(ADM_LSM_AUDPROC_CAL, path, port_id, copp_idx, + perf_mode, app_type, acdb_id, sample_rate); send_adm_cal_type(ADM_AUDVOL_CAL, path, port_id, copp_idx, perf_mode, app_type, acdb_id, sample_rate); } @@ -3447,6 +3460,9 @@ static int get_cal_type_index(int32_t cal_type) case ADM_AUDPROC_CAL_TYPE: ret = ADM_AUDPROC_CAL; break; + case ADM_LSM_AUDPROC_CAL_TYPE: + ret = ADM_LSM_AUDPROC_CAL; + break; case ADM_AUDVOL_CAL_TYPE: ret = ADM_AUDVOL_CAL; break; @@ -3654,6 +3670,12 @@ static int adm_init_cal_data(void) {adm_map_cal_data, adm_unmap_cal_data, cal_utils_match_buf_num} }, + {{ADM_LSM_AUDPROC_CAL_TYPE, + {adm_alloc_cal, adm_dealloc_cal, NULL, + adm_set_cal, NULL, NULL} }, + {adm_map_cal_data, adm_unmap_cal_data, + cal_utils_match_buf_num} }, + {{ADM_AUDVOL_CAL_TYPE, {adm_alloc_cal, adm_dealloc_cal, NULL, adm_set_cal, NULL, NULL} }, @@ -4460,7 +4482,7 @@ int adm_store_cal_data(int port_id, int copp_idx, int path, int perf_mode, goto unlock; } - if (cal_index == ADM_AUDPROC_CAL) { + if (cal_index == ADM_AUDPROC_CAL || cal_index == ADM_LSM_AUDPROC_CAL) { if (cal_block->cal_data.size > AUD_PROC_BLOCK_SIZE) { pr_err("%s:audproc:invalid size exp/actual[%zd, %d]\n", __func__, cal_block->cal_data.size, *size); diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 6a6d3b23f1f5..19a844c316e3 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -32,6 +32,7 @@ enum { ADM_CUSTOM_TOP_CAL = 0, ADM_AUDPROC_CAL, + ADM_LSM_AUDPROC_CAL, ADM_AUDVOL_CAL, ADM_RTAC_INFO_CAL, ADM_RTAC_APR_CAL, @@ -186,4 +187,5 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, int channel_index); void msm_dts_srs_acquire_lock(void); void msm_dts_srs_release_lock(void); +void adm_set_lsm_port_id(int port_id); #endif /* __Q6_ADM_V2_H__ */ diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h index 27dacde651f1..3b97ab2bf1e0 100644 --- a/include/uapi/linux/msm_audio_calibration.h +++ b/include/uapi/linux/msm_audio_calibration.h @@ -101,6 +101,8 @@ enum { AFE_SIDETONE_IIR_CAL_TYPE, AFE_LSM_TOPOLOGY_CAL_TYPE, AFE_LSM_TX_CAL_TYPE, + ADM_LSM_TOPOLOGY_CAL_TYPE, + ADM_LSM_AUDPROC_CAL_TYPE, MAX_CAL_TYPES, }; @@ -111,6 +113,9 @@ enum { #define AFE_LSM_TOPOLOGY_CAL_TYPE AFE_LSM_TOPOLOGY_CAL_TYPE #define AFE_LSM_TX_CAL_TYPE AFE_LSM_TX_CAL_TYPE +#define ADM_LSM_TOPOLOGY_CAL_TYPE ADM_LSM_TOPOLOGY_CAL_TYPE +#define ADM_LSM_AUDPROC_CAL_TYPE ADM_LSM_AUDPROC_CAL_TYPE +#define LSM_CAL_TYPES #define TOPOLOGY_SPECIFIC_CHANNEL_INFO #define MSM_SPKR_PROT_SPV3 -- GitLab From a8349a42c75266c40b1060fec0b04025593bafc5 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 13 Dec 2017 09:30:15 +0530 Subject: [PATCH 0121/1645] dsp: assign channel mapping to three channel voice Tx devices Assign default channel mapping to three channel voice Tx devices when the topology specific info cal data is NULL. Change-Id: Ic9d572edc1d7de07a2bd5e11d82f875368c35854 Signed-off-by: Aditya Bavanari --- dsp/q6voice.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 985e959ab879..428e34cc6abb 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -36,6 +36,7 @@ #define CMD_STATUS_FAIL 1 #define NUM_CHANNELS_MONO 1 #define NUM_CHANNELS_STEREO 2 +#define NUM_CHANNELS_THREE 3 #define NUM_CHANNELS_QUAD 4 #define CVP_VERSION_2 2 #define GAIN_Q14_FORMAT(a) (a << 14) @@ -8639,6 +8640,11 @@ int voice_set_topology_specific_info(struct voice_data *v, NUM_CHANNELS_STEREO) { v->dev_tx.channel_mapping[0] = PCM_CHANNEL_FL; v->dev_tx.channel_mapping[1] = PCM_CHANNEL_FR; + } else if (v->dev_tx.no_of_channels == + NUM_CHANNELS_THREE) { + v->dev_tx.channel_mapping[0] = PCM_CHANNEL_FL; + v->dev_tx.channel_mapping[1] = PCM_CHANNEL_FR; + v->dev_tx.channel_mapping[2] = PCM_CHANNEL_FC; } else if (v->dev_tx.no_of_channels == NUM_CHANNELS_QUAD) { v->dev_tx.channel_mapping[0] = PCM_CHANNEL_FL; -- GitLab From 9730cdd47eec4241ec6c5c58abc32aec585d0251 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 26 Sep 2017 12:48:31 +0800 Subject: [PATCH 0122/1645] ASoC: dsp: add spin lock to protect ac There is a possible use after free for the ac variable that causes kernel panic. Add spinlock to fix race condition to avoid this issue. Change-Id: I71638c269f572ff1eaad87682fa000cd1dad407d Signed-off-by: Meng Wang --- dsp/q6asm.c | 122 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 93 insertions(+), 29 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index d6774f4ede03..caf7df1dce6f 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -91,8 +91,13 @@ struct asm_mmap { }; static struct asm_mmap this_mmap; + +struct audio_session { + struct audio_client *ac; + spinlock_t session_lock; +}; /* session id: 0 reserved */ -static struct audio_client *session[ASM_ACTIVE_STREAMS_ALLOWED + 1]; +static struct audio_session session[ASM_ACTIVE_STREAMS_ALLOWED + 1]; struct asm_buffer_node { struct list_head list; @@ -530,8 +535,8 @@ static int q6asm_session_alloc(struct audio_client *ac) int n; for (n = 1; n <= ASM_ACTIVE_STREAMS_ALLOWED; n++) { - if (!session[n]) { - session[n] = ac; + if (!(session[n].ac)) { + session[n].ac = ac; return n; } } @@ -539,25 +544,39 @@ static int q6asm_session_alloc(struct audio_client *ac) return -ENOMEM; } -static bool q6asm_is_valid_audio_client(struct audio_client *ac) +static int q6asm_get_session_id_from_audio_client(struct audio_client *ac) { int n; for (n = 1; n <= ASM_ACTIVE_STREAMS_ALLOWED; n++) { - if (session[n] == ac) - return 1; + if (session[n].ac == ac) + return n; } return 0; } +static bool q6asm_is_valid_audio_client(struct audio_client *ac) +{ + return q6asm_get_session_id_from_audio_client(ac) ? 1 : 0; +} + static void q6asm_session_free(struct audio_client *ac) { + int session_id; + pr_debug("%s: sessionid[%d]\n", __func__, ac->session); + session_id = ac->session; rtac_remove_popp_from_adm_devices(ac->session); - session[ac->session] = 0; + spin_lock_bh(&(session[session_id].session_lock)); + session[ac->session].ac = NULL; ac->session = 0; ac->perf_mode = LEGACY_PCM_MODE; ac->fptr_cache_ops = NULL; + ac->cb = NULL; + ac->priv = NULL; + kfree(ac); + ac = NULL; + spin_unlock_bh(&(session[session_id].session_lock)); } static uint32_t q6asm_get_next_buf(struct audio_client *ac, @@ -1088,8 +1107,6 @@ void q6asm_audio_client_free(struct audio_client *ac) pr_debug("%s: APR De-Register\n", __func__); /*done:*/ - kfree(ac); - ac = NULL; mutex_unlock(&session_lock); } EXPORT_SYMBOL(q6asm_audio_client_free); @@ -1252,6 +1269,7 @@ struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv) if (n <= 0) { pr_err("%s: ASM Session alloc fail n=%d\n", __func__, n); mutex_unlock(&session_lock); + kfree(ac); goto fail_session; } ac->session = n; @@ -1328,7 +1346,6 @@ struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv) fail_apr1: q6asm_session_free(ac); fail_session: - kfree(ac); return NULL; } EXPORT_SYMBOL(q6asm_audio_client_alloc); @@ -1351,11 +1368,11 @@ struct audio_client *q6asm_get_audio_client(int session_id) goto err; } - if (!session[session_id]) { + if (!(session[session_id].ac)) { pr_err("%s: session not active: %d\n", __func__, session_id); goto err; } - return session[session_id]; + return session[session_id].ac; err: return NULL; } @@ -1591,6 +1608,8 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) struct audio_client *ac = NULL; struct audio_port_data *port; + int session_id; + if (!data) { pr_err("%s: Invalid CB\n", __func__); return 0; @@ -1632,12 +1651,20 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) return 0; } asm_token.token = data->token; - ac = q6asm_get_audio_client(asm_token._token.session_id); + session_id = asm_token._token.session_id; + + if ((session_id > 0 && session_id <= ASM_ACTIVE_STREAMS_ALLOWED)) + spin_lock(&(session[session_id].session_lock)); + + ac = q6asm_get_audio_client(session_id); dir = q6asm_get_flag_from_token(&asm_token, ASM_DIRECTION_OFFSET); if (!ac) { pr_debug("%s: session[%d] already freed\n", - __func__, asm_token._token.session_id); + __func__, session_id); + if ((session_id > 0 && + session_id <= ASM_ACTIVE_STREAMS_ALLOWED)) + spin_unlock(&(session[session_id].session_lock)); return 0; } @@ -1688,6 +1715,9 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) __func__, payload[0]); break; } + if ((session_id > 0 && + session_id <= ASM_ACTIVE_STREAMS_ALLOWED)) + spin_unlock(&(session[session_id].session_lock)); return 0; } @@ -1722,6 +1752,9 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) if (ac->cb) ac->cb(data->opcode, data->token, data->payload, ac->priv); + if ((session_id > 0 && session_id <= ASM_ACTIVE_STREAMS_ALLOWED)) + spin_unlock(&(session[session_id].session_lock)); + return 0; } @@ -1789,6 +1822,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) struct msm_adsp_event_data *pp_event_package = NULL; uint32_t payload_size = 0; + int session_id; + if (ac == NULL) { pr_err("%s: ac NULL\n", __func__); return -EINVAL; @@ -1797,15 +1832,19 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) pr_err("%s: data NULL\n", __func__); return -EINVAL; } - if (!q6asm_is_valid_audio_client(ac)) { - pr_err("%s: audio client pointer is invalid, ac = %pK\n", - __func__, ac); + + session_id = q6asm_get_session_id_from_audio_client(ac); + if (session_id <= 0 || session_id > ASM_ACTIVE_STREAMS_ALLOWED) { + pr_err("%s: Session ID is invalid, session = %d\n", __func__, + session_id); return -EINVAL; } + spin_lock(&(session[session_id].session_lock)); - if (ac->session <= 0 || ac->session > 8) { - pr_err("%s: Session ID is invalid, session = %d\n", __func__, - ac->session); + if (!q6asm_is_valid_audio_client(ac)) { + pr_err("%s: audio client pointer is invalid, ac = %pK\n", + __func__, ac); + spin_unlock(&(session[session_id].session_lock)); return -EINVAL; } @@ -1818,7 +1857,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) } if (data->opcode == RESET_EVENTS) { + spin_unlock(&(session[session_id].session_lock)); mutex_lock(&ac->cmd_lock); + spin_lock(&(session[session_id].session_lock)); atomic_set(&ac->reset, 1); if (ac->apr == NULL) { ac->apr = ac->apr2; @@ -1839,6 +1880,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) wake_up(&ac->time_wait); wake_up(&ac->cmd_wait); wake_up(&ac->mem_wait); + spin_unlock(&(session[session_id].session_lock)); mutex_unlock(&ac->cmd_lock); return 0; } @@ -1853,6 +1895,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) (data->opcode != ASM_SESSION_EVENT_RX_UNDERFLOW)) { if (payload == NULL) { pr_err("%s: payload is null\n", __func__); + spin_unlock(&(session[session_id].session_lock)); return -EINVAL; } dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x] opcode 0x%x\n", @@ -1878,6 +1921,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) ret = q6asm_is_valid_session(data, priv); if (ret != 0) { pr_err("%s: session invalid %d\n", __func__, ret); + spin_unlock(&(session[session_id].session_lock)); return ret; } case ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2: @@ -1917,6 +1961,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) payload[1]); wake_up(&ac->cmd_wait); } + spin_unlock( + &(session[session_id].session_lock)); return 0; } if ((is_adsp_reg_event(payload[0]) >= 0) || @@ -1947,6 +1993,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) atomic_set(&ac->mem_state, payload[1]); wake_up(&ac->mem_wait); } + spin_unlock( + &(session[session_id].session_lock)); return 0; } if (atomic_read(&ac->mem_state) && wakeup_flag) { @@ -1994,6 +2042,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) __func__, payload[0]); break; } + + spin_unlock(&(session[session_id].session_lock)); return 0; } @@ -2008,6 +2058,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) if (port->buf == NULL) { pr_err("%s: Unexpected Write Done\n", __func__); + spin_unlock( + &(session[session_id].session_lock)); return -EINVAL; } spin_lock_irqsave(&port->dsp_lock, dsp_flags); @@ -2022,6 +2074,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) __func__, payload[0], payload[1]); spin_unlock_irqrestore(&port->dsp_lock, dsp_flags); + spin_unlock( + &(session[session_id].session_lock)); return -EINVAL; } port->buf[buf_index].used = 1; @@ -2092,6 +2146,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) if (ac->io_mode & SYNC_IO_MODE) { if (port->buf == NULL) { pr_err("%s: Unexpected Write Done\n", __func__); + spin_unlock( + &(session[session_id].session_lock)); return -EINVAL; } spin_lock_irqsave(&port->dsp_lock, dsp_flags); @@ -2166,8 +2222,10 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) pr_debug("%s: ASM_STREAM_EVENT payload[0][0x%x] payload[1][0x%x]", __func__, payload[0], payload[1]); i = is_adsp_raise_event(data->opcode); - if (i < 0) + if (i < 0) { + spin_unlock(&(session[session_id].session_lock)); return 0; + } /* repack payload for asm_stream_pp_event * package is composed of event type + size + actual payload @@ -2176,8 +2234,10 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) pp_event_package = kzalloc(payload_size + sizeof(struct msm_adsp_event_data), GFP_ATOMIC); - if (!pp_event_package) + if (!pp_event_package) { + spin_unlock(&(session[session_id].session_lock)); return -ENOMEM; + } pp_event_package->event_type = i; pp_event_package->payload_len = payload_size; @@ -2186,6 +2246,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) ac->cb(data->opcode, data->token, (void *)pp_event_package, ac->priv); kfree(pp_event_package); + spin_unlock(&(session[session_id].session_lock)); return 0; case ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2: pr_debug("%s: ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2 sesion %d status 0x%x msw %u lsw %u\n", @@ -2211,7 +2272,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) if (ac->cb) ac->cb(data->opcode, data->token, data->payload, ac->priv); - + spin_unlock(&(session[session_id].session_lock)); return 0; } @@ -9864,7 +9925,7 @@ int q6asm_get_apr_service_id(int session_id) return -EINVAL; } - return ((struct apr_svc *)session[session_id]->apr)->id; + return ((struct apr_svc *)(session[session_id].ac)->apr)->id; } int q6asm_get_asm_topology(int session_id) @@ -9875,12 +9936,12 @@ int q6asm_get_asm_topology(int session_id) pr_err("%s: invalid session_id = %d\n", __func__, session_id); goto done; } - if (session[session_id] == NULL) { + if (session[session_id].ac == NULL) { pr_err("%s: session not created for session id = %d\n", __func__, session_id); goto done; } - topology = session[session_id]->topology; + topology = (session[session_id].ac)->topology; done: return topology; } @@ -9893,12 +9954,12 @@ int q6asm_get_asm_app_type(int session_id) pr_err("%s: invalid session_id = %d\n", __func__, session_id); goto done; } - if (session[session_id] == NULL) { + if (session[session_id].ac == NULL) { pr_err("%s: session not created for session id = %d\n", __func__, session_id); goto done; } - app_type = session[session_id]->app_type; + app_type = (session[session_id].ac)->app_type; done: return app_type; } @@ -10253,7 +10314,10 @@ int __init q6asm_init(void) pr_debug("%s:\n", __func__); - memset(session, 0, sizeof(session)); + memset(session, 0, sizeof(struct audio_session) * + (ASM_ACTIVE_STREAMS_ALLOWED + 1)); + for (lcnt = 0; lcnt <= ASM_ACTIVE_STREAMS_ALLOWED; lcnt++) + spin_lock_init(&(session[lcnt].session_lock)); set_custom_topology = 1; /*setup common client used for cal mem map */ -- GitLab From 94815dae7eede20fda3ebee4aba3ef7ba2c57f67 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 29 Nov 2017 15:09:55 +0530 Subject: [PATCH 0123/1645] audio-lnx: Fix re-compile issue for dlkm On incremental build, Module.symver used will be older. Add commands to delete symver files before recompile starts for audio kernel. Change-Id: I1e90ad4543a7a06b5940f0a2612d18ed722ecd55 Signed-off-by: Laxminath Kasam --- Android.mk | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Android.mk b/Android.mk index 18e9263f1cc4..a95c0da7e7fd 100644 --- a/Android.mk +++ b/Android.mk @@ -6,6 +6,13 @@ UAPI_OUT := $(OUT)/obj/vendor/qcom/opensource/audio-kernel/include ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) $(shell mkdir -p $(UAPI_OUT)/linux;) $(shell mkdir -p $(UAPI_OUT)/sound;) +$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers) +$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers) +$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/codecs/Module.symvers) +$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers) +$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers) +$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers) +$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers) include $(MY_LOCAL_PATH)/ipc/Android.mk include $(MY_LOCAL_PATH)/dsp/Android.mk @@ -17,6 +24,8 @@ include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk endif ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) +$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers) +$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/sdm660_cdc/Android.mk include $(MY_LOCAL_PATH)/asoc/codecs/msm_sdw/Android.mk endif -- GitLab From 9deef915545db236e3657d141dfb9efdf40d2c2b Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 20 Nov 2017 13:31:31 +0530 Subject: [PATCH 0124/1645] asoc: set freed pointers to NULL Set freed pointers to NULL to avoid double free in msm_compr_playback_open and msm_compr_playback_free functions of the compress driver. CRs-Fixed: 2142216 Change-Id: Ifd011dd85dd9f610c7b69dd460f73d26e006cd66 Signed-off-by: Aditya Bavanari --- asoc/msm-compress-q6-v2.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index b5e28275387f..3a3774a4e930 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -102,6 +102,7 @@ struct msm_compr_pdata { bool use_legacy_api; /* indicates use older asm apis*/ struct msm_compr_dec_params *dec_params[MSM_FRONTEND_DAI_MAX]; struct msm_compr_ch_map *ch_map[MSM_FRONTEND_DAI_MAX]; + bool is_in_use[MSM_FRONTEND_DAI_MAX]; }; struct msm_compr_audio { @@ -1531,11 +1532,16 @@ static int msm_compr_playback_open(struct snd_compr_stream *cstream) { struct snd_compr_runtime *runtime = cstream->runtime; struct snd_soc_pcm_runtime *rtd = cstream->private_data; - struct msm_compr_audio *prtd; + struct msm_compr_audio *prtd = NULL; struct msm_compr_pdata *pdata = snd_soc_platform_get_drvdata(rtd->platform); pr_debug("%s\n", __func__); + if (pdata->is_in_use[rtd->dai_link->id] == true) { + pr_err("%s: %s is already in use, err: %d\n", + __func__, rtd->dai_link->cpu_dai_name, -EBUSY); + return -EBUSY; + } prtd = kzalloc(sizeof(struct msm_compr_audio), GFP_KERNEL); if (prtd == NULL) { pr_err("Failed to allocate memory for msm_compr_audio\n"); @@ -1547,7 +1553,7 @@ static int msm_compr_playback_open(struct snd_compr_stream *cstream) pdata->cstream[rtd->dai_link->id] = cstream; pdata->audio_effects[rtd->dai_link->id] = kzalloc(sizeof(struct msm_compr_audio_effects), GFP_KERNEL); - if (!pdata->audio_effects[rtd->dai_link->id]) { + if (pdata->audio_effects[rtd->dai_link->id] == NULL) { pr_err("%s: Could not allocate memory for effects\n", __func__); pdata->cstream[rtd->dai_link->id] = NULL; kfree(prtd); @@ -1555,10 +1561,11 @@ static int msm_compr_playback_open(struct snd_compr_stream *cstream) } pdata->dec_params[rtd->dai_link->id] = kzalloc(sizeof(struct msm_compr_dec_params), GFP_KERNEL); - if (!pdata->dec_params[rtd->dai_link->id]) { + if (pdata->dec_params[rtd->dai_link->id] == NULL) { pr_err("%s: Could not allocate memory for dec params\n", __func__); kfree(pdata->audio_effects[rtd->dai_link->id]); + pdata->audio_effects[rtd->dai_link->id] = NULL; pdata->cstream[rtd->dai_link->id] = NULL; kfree(prtd); return -ENOMEM; @@ -1603,20 +1610,22 @@ static int msm_compr_playback_open(struct snd_compr_stream *cstream) populate_codec_list(prtd); prtd->audio_client = q6asm_audio_client_alloc( (app_cb)compr_event_handler, prtd); - if (!prtd->audio_client) { + if (prtd->audio_client == NULL) { pr_err("%s: Could not allocate memory for client\n", __func__); kfree(pdata->audio_effects[rtd->dai_link->id]); + pdata->audio_effects[rtd->dai_link->id] = NULL; kfree(pdata->dec_params[rtd->dai_link->id]); + pdata->dec_params[rtd->dai_link->id] = NULL; pdata->cstream[rtd->dai_link->id] = NULL; - runtime->private_data = NULL; kfree(prtd); + runtime->private_data = NULL; return -ENOMEM; } pr_debug("%s: session ID %d\n", __func__, prtd->audio_client->session); prtd->audio_client->perf_mode = false; prtd->session_id = prtd->audio_client->session; msm_adsp_init_mixer_ctl_pp_event_queue(rtd); - + pdata->is_in_use[rtd->dai_link->id] = true; return 0; } @@ -1772,10 +1781,15 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream) q6asm_audio_client_free(ac); msm_adsp_clean_mixer_ctl_pp_event_queue(soc_prtd); - kfree(pdata->audio_effects[soc_prtd->dai_link->id]); - pdata->audio_effects[soc_prtd->dai_link->id] = NULL; - kfree(pdata->dec_params[soc_prtd->dai_link->id]); - pdata->dec_params[soc_prtd->dai_link->id] = NULL; + if (pdata->audio_effects[soc_prtd->dai_link->id] != NULL) { + kfree(pdata->audio_effects[soc_prtd->dai_link->id]); + pdata->audio_effects[soc_prtd->dai_link->id] = NULL; + } + if (pdata->dec_params[soc_prtd->dai_link->id] != NULL) { + kfree(pdata->dec_params[soc_prtd->dai_link->id]); + pdata->dec_params[soc_prtd->dai_link->id] = NULL; + } + pdata->is_in_use[soc_prtd->dai_link->id] = false; kfree(prtd); runtime->private_data = NULL; @@ -3842,6 +3856,7 @@ static int msm_compr_probe(struct snd_soc_platform *platform) pdata->dec_params[i] = NULL; pdata->cstream[i] = NULL; pdata->ch_map[i] = NULL; + pdata->is_in_use[i] = false; } snd_soc_add_platform_controls(platform, msm_compr_gapless_controls, -- GitLab From 8832732009e27c8996dcf968e092f1568506bdb6 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Fri, 8 Dec 2017 10:51:58 -0800 Subject: [PATCH 0125/1645] ipc: add api to vote for upgrading thread priority For some time critical tasks, the thread priority might need to be upgraded to Real-Time Thread priority level. Expose an interface from APR layer so that clients can vote for a priority upgrade whenever needed. Change-Id: Ieb4afa914905750eccdf7672020a8751fdcf6462 Signed-off-by: Banajit Goswami --- include/ipc/apr.h | 4 +- include/ipc/apr_tal.h | 3 +- ipc/apr.c | 101 ++++++++++++++++++++++++++++++++++++++++++ ipc/apr_tal_glink.c | 32 +++++++++++++ 4 files changed, 138 insertions(+), 2 deletions(-) diff --git a/include/ipc/apr.h b/include/ipc/apr.h index 4e5e3d8630a5..6b4817edeeb5 100644 --- a/include/ipc/apr.h +++ b/include/ipc/apr.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -188,4 +188,6 @@ int apr_set_q6_state(enum apr_subsys_state state); void apr_set_subsys_state(void); const char *apr_get_lpass_subsys_name(void); uint16_t apr_get_reset_domain(uint16_t proc); +int apr_start_rx_rt(void *handle); +int apr_end_rx_rt(void *handle); #endif diff --git a/include/ipc/apr_tal.h b/include/ipc/apr_tal.h index fc1471d4f08d..aa53e217c714 100644 --- a/include/ipc/apr_tal.h +++ b/include/ipc/apr_tal.h @@ -74,7 +74,8 @@ int apr_tal_close(struct apr_svc_ch_dev *apr_ch); int apr_tal_rx_intents_config(struct apr_svc_ch_dev *apr_ch, int num_of_intents, uint32_t size); int apr_tal_init(void); - +int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch); +int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch); struct apr_svc_ch_dev { void *handle; diff --git a/ipc/apr.c b/ipc/apr.c index d2029943dcd9..9f9cf915ab3d 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -774,6 +774,107 @@ static void apr_reset_deregister(struct work_struct *work) kfree(apr_reset); } +/** + * apr_start_rx_rt - Clients call to vote for thread + * priority upgrade whenever needed. + * + * @handle: APR service handle + * + * Returns 0 on success or error otherwise. + */ +int apr_start_rx_rt(void *handle) +{ + int rc = 0; + struct apr_svc *svc = handle; + uint16_t dest_id = 0; + uint16_t client_id = 0; + + if (!svc) { + pr_err("%s: Invalid APR handle\n", __func__); + return -EINVAL; + } + + mutex_lock(&svc->m_lock); + dest_id = svc->dest_id; + client_id = svc->client_id; + + if ((client_id >= APR_CLIENT_MAX) || (dest_id >= APR_DEST_MAX)) { + pr_err("%s: %s invalid. client_id = %u, dest_id = %u\n", + __func__, + client_id >= APR_CLIENT_MAX ? "Client ID" : "Dest ID", + client_id, dest_id); + rc = -EINVAL; + goto exit; + } + + if (!client[dest_id][client_id].handle) { + pr_err("%s: Client handle is NULL\n", __func__); + rc = -EINVAL; + goto exit; + } + + rc = apr_tal_start_rx_rt(client[dest_id][client_id].handle); + if (rc) + pr_err("%s: failed to set RT thread priority for APR RX. rc = %d\n", + __func__, rc); + +exit: + mutex_unlock(&svc->m_lock); + return rc; +} +EXPORT_SYMBOL(apr_start_rx_rt); + +/** + * apr_end_rx_rt - Clients call to unvote for thread + * priority upgrade (perviously voted with + * apr_start_rx_rt()). + * + * @handle: APR service handle + * + * Returns 0 on success or error otherwise. + */ +int apr_end_rx_rt(void *handle) +{ + int rc = 0; + struct apr_svc *svc = handle; + uint16_t dest_id = 0; + uint16_t client_id = 0; + + if (!svc) { + pr_err("%s: Invalid APR handle\n", __func__); + return -EINVAL; + } + + mutex_lock(&svc->m_lock); + dest_id = svc->dest_id; + client_id = svc->client_id; + + if ((client_id >= APR_CLIENT_MAX) || (dest_id >= APR_DEST_MAX)) { + pr_err("%s: %s invalid. client_id = %u, dest_id = %u\n", + __func__, + client_id >= APR_CLIENT_MAX ? "Client ID" : "Dest ID", + client_id, dest_id); + rc = -EINVAL; + goto exit; + } + + if (!client[dest_id][client_id].handle) { + pr_err("%s: Client handle is NULL\n", __func__); + rc = -EINVAL; + goto exit; + } + + rc = apr_tal_end_rx_rt(client[dest_id][client_id].handle); + if (rc) + pr_err("%s: failed to reset RT thread priority for APR RX. rc = %d\n", + __func__, rc); + +exit: + mutex_unlock(&svc->m_lock); + return rc; +} +EXPORT_SYMBOL(apr_end_rx_rt); + /** * apr_deregister - Clients call to de-register * from APR. diff --git a/ipc/apr_tal_glink.c b/ipc/apr_tal_glink.c index 3803dcb1ea9a..6683348686aa 100644 --- a/ipc/apr_tal_glink.c +++ b/ipc/apr_tal_glink.c @@ -357,6 +357,38 @@ struct apr_svc_ch_dev *apr_tal_open(uint32_t clnt, uint32_t dest, uint32_t dl, return rc ? NULL : apr_ch; } +int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch) +{ + int rc = 0; + + if (!apr_ch || !apr_ch->handle) { + rc = -EINVAL; + goto exit; + } + + mutex_lock(&apr_ch->m_lock); + rc = glink_start_rx_rt(apr_ch->handle); + mutex_unlock(&apr_ch->m_lock); +exit: + return rc; +} + +int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch) +{ + int rc = 0; + + if (!apr_ch || !apr_ch->handle) { + rc = -EINVAL; + goto exit; + } + + mutex_lock(&apr_ch->m_lock); + rc = glink_end_rx_rt(apr_ch->handle); + mutex_unlock(&apr_ch->m_lock); +exit: + return rc; +} + int apr_tal_close(struct apr_svc_ch_dev *apr_ch) { int rc; -- GitLab From 616e68cd4a3185fc6f8c4f9de804ef490c779bf6 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Fri, 27 Oct 2017 01:31:19 -0700 Subject: [PATCH 0126/1645] asoc: vote for Glink Rx thread priority upgrade For Low-latency audio playback usecase, vote for a priority upgrade for Glink Rx thread, to avoid any performance issue. Change-Id: I8332c80eedd7325700e695f341fc4b92f65fd77c Signed-off-by: Banajit Goswami --- asoc/msm-pcm-q6-v2.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 314584e5fc2d..4311499aead7 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -614,8 +614,15 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; struct msm_audio *prtd; + struct msm_plat_data *pdata; int ret = 0; + pdata = (struct msm_plat_data *) + dev_get_drvdata(soc_prtd->platform->dev); + if (!pdata) { + pr_err("%s: platform data not populated\n", __func__); + return -EINVAL; + } prtd = kzalloc(sizeof(struct msm_audio), GFP_KERNEL); if (prtd == NULL) return -ENOMEM; @@ -693,6 +700,10 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) prtd->reset_event = false; runtime->private_data = prtd; msm_adsp_init_mixer_ctl_pp_event_queue(soc_prtd); + /* Vote to update the Rx thread priority to RT Thread for playback */ + if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) && + (pdata->perf_mode == LOW_LATENCY_PCM_MODE)) + apr_start_rx_rt(prtd->audio_client->apr); return 0; } @@ -800,6 +811,7 @@ static int msm_pcm_playback_close(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; struct msm_audio *prtd = runtime->private_data; + struct msm_plat_data *pdata; uint32_t timeout; int dir = 0; int ret = 0; @@ -809,6 +821,16 @@ static int msm_pcm_playback_close(struct snd_pcm_substream *substream) if (prtd->audio_client) { dir = IN; + /* + * Unvote to downgrade the Rx thread priority from + * RT Thread for Low-Latency use case. + */ + pdata = (struct msm_plat_data *) + dev_get_drvdata(soc_prtd->platform->dev); + if (pdata) { + if (pdata->perf_mode == LOW_LATENCY_PCM_MODE) + apr_end_rx_rt(prtd->audio_client->apr); + } /* determine timeout length */ if (runtime->frame_bits == 0 || runtime->rate == 0) { timeout = CMD_EOS_MIN_TIMEOUT_LENGTH; -- GitLab From 3817b1847e4b444bd55ed03eba227f3953c59166 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Mon, 4 Dec 2017 15:56:05 -0800 Subject: [PATCH 0127/1645] msm: Array bounds check for buffer index Check the ASM buffer index boundary before using it to access the buffer to avoid out of array bounds error. CRs-Fixed: 2145996 Change-Id: I5492941dfd9e7c3fa90af6caec14f9ff7e75d248 Signed-off-by: Vignesh Kulothungan --- asoc/msm-pcm-q6-v2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 314584e5fc2d..35e75664e141 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -184,6 +184,11 @@ static void event_handler(uint32_t opcode, case ASM_DATA_EVENT_READ_DONE_V2: { pr_debug("ASM_DATA_EVENT_READ_DONE_V2\n"); buf_index = q6asm_get_buf_index_from_token(token); + if (buf_index >= CAPTURE_MAX_NUM_PERIODS) { + pr_err("%s: buffer index %u is out of range.\n", + __func__, buf_index); + return; + } pr_debug("%s: token=0x%08x buf_index=0x%08x\n", __func__, token, buf_index); prtd->in_frame_info[buf_index].size = payload[4]; -- GitLab From 6348e874156acbd638f8ca2a420f35c884bf8d2b Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 18 Dec 2017 11:53:22 +0530 Subject: [PATCH 0128/1645] dsp: export adm_set_lsm_port_id for platform For audio modules DLKM support, export the ADM API to external modules. CRs-Fixed: 2160337 Change-Id: Ieaf88b2c1d99f5fc42a7a3f1900887702323f18b Signed-off-by: Aditya Bavanari --- dsp/q6adm.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 403d70dbc98b..514af254db99 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2299,10 +2299,18 @@ static int get_cal_path(int path) return TX_DEVICE; } +/* + * Command to set LSM port ID + * which is used to send LSM cal + * + * @port_id: Port ID number to be set + * + */ void adm_set_lsm_port_id(int port_id) { this_adm.lsm_port_id = port_id; } +EXPORT_SYMBOL(adm_set_lsm_port_id); static void send_adm_cal(int port_id, int copp_idx, int path, int perf_mode, int app_type, int acdb_id, int sample_rate) -- GitLab From d6d62b8d3c2962466542d7139efbde3b92e2234c Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 12 Dec 2017 14:22:31 +0530 Subject: [PATCH 0129/1645] ASoC: wcd: Avoid multiple insertion/removals for aux cable High impedance aux cable when inserted causes jack to change to lineout. This causes removal event to be called which results in pause during music playback because jack value is not updated. Do not change current plug while plug is marked as lineout. CRs-Fixed: 2151012 Change-Id: I99797b58c48be00185a352094e32e8623faee491 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd-mbhc-legacy.c | 6 +++++- asoc/codecs/wcd-mbhc-v2.c | 3 +++ asoc/codecs/wcd-mbhc-v2.h | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd-mbhc-legacy.c b/asoc/codecs/wcd-mbhc-legacy.c index 9f6a6254986f..d03d8342a8df 100644 --- a/asoc/codecs/wcd-mbhc-legacy.c +++ b/asoc/codecs/wcd-mbhc-legacy.c @@ -688,7 +688,11 @@ static void wcd_correct_swch_plug(struct work_struct *work) if (!wrk_complete && mbhc->btn_press_intr) { pr_debug("%s: Can be slow insertion of headphone\n", __func__); wcd_cancel_btn_work(mbhc); - plug_type = MBHC_PLUG_TYPE_HEADPHONE; + /* Report as headphone only if previously + * not reported as lineout + */ + if (!mbhc->force_linein) + plug_type = MBHC_PLUG_TYPE_HEADPHONE; } /* * If plug_tye is headset, we might have already reported either in diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 6088a1ee09a7..0b6e35562355 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -605,6 +605,7 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, hphrocp_off_report(mbhc, SND_JACK_OC_HPHR); hphlocp_off_report(mbhc, SND_JACK_OC_HPHL); mbhc->current_plug = MBHC_PLUG_TYPE_NONE; + mbhc->force_linein = false; } else { /* * Report removal of current jack type. @@ -657,6 +658,7 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, SND_JACK_LINEOUT | SND_JACK_ANC_HEADPHONE | SND_JACK_UNSUPPORTED); + mbhc->force_linein = false; } if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET && @@ -699,6 +701,7 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, mbhc->zr < MAX_IMPED) && (jack_type == SND_JACK_HEADPHONE)) { jack_type = SND_JACK_LINEOUT; + mbhc->force_linein = true; mbhc->current_plug = MBHC_PLUG_TYPE_HIGH_HPH; if (mbhc->hph_status) { mbhc->hph_status &= ~(SND_JACK_HEADSET | diff --git a/asoc/codecs/wcd-mbhc-v2.h b/asoc/codecs/wcd-mbhc-v2.h index bdae77630f02..94f096adcfbb 100644 --- a/asoc/codecs/wcd-mbhc-v2.h +++ b/asoc/codecs/wcd-mbhc-v2.h @@ -589,6 +589,7 @@ struct wcd_mbhc { struct work_struct usbc_analog_work; struct wcd_mbhc_fn *mbhc_fn; + bool force_linein; }; void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc, -- GitLab From f6d89a5094e7415a71d5c3cf564a0489dbb0739e Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Fri, 8 Dec 2017 16:39:17 +0530 Subject: [PATCH 0130/1645] audio-lnx: Correct mutex usage during error handling Release the acquired mutex when there is failure in enabling the soundwire clock. Change-Id: I2e10ed7f0bd86524998a67d62e85754f7989eca2 Signed-off-by: Ramprasad Katkam --- asoc/codecs/msm_sdw/msm_sdw_cdc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/msm_sdw/msm_sdw_cdc.c b/asoc/codecs/msm_sdw/msm_sdw_cdc.c index 5649167ee6bb..7a5ba8f0c7c4 100644 --- a/asoc/codecs/msm_sdw/msm_sdw_cdc.c +++ b/asoc/codecs/msm_sdw/msm_sdw_cdc.c @@ -256,8 +256,8 @@ static int msm_int_enable_sdw_cdc_clk(struct msm_sdw_priv *msm_sdw, msm_sdw->int_mclk1_enabled = false; } } - mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); rtn: + mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); return ret; } EXPORT_SYMBOL(msm_int_enable_sdw_cdc_clk); -- GitLab From 83b0584703f719039a7a5176e8dafd31452c5251 Mon Sep 17 00:00:00 2001 From: Walter Yang Date: Fri, 17 Nov 2017 15:47:57 +0800 Subject: [PATCH 0131/1645] ASoC: wcd934x: WDSP debug enhancement Add interface to trigger WDSP dumps for debug use. Important register dump and WDSP ramdump are both collected when DEBUG_DUMP string is sent from userspace via WDSP misc node or when WDSP boot timeout happens. CRs-Fixed: 2117755 Change-Id: I8b91a8939201a54512a5e3557ce771b4ff2ff075 Signed-off-by: Walter Yang --- asoc/codecs/wcd-dsp-mgr.c | 42 ++++++++++ asoc/codecs/wcd934x/wcd934x-dsp-cntl.c | 109 ++++++++++++++++++++++++- asoc/codecs/wcd934x/wcd934x-dsp-cntl.h | 6 +- 3 files changed, 154 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/wcd-dsp-mgr.c b/asoc/codecs/wcd-dsp-mgr.c index 6cc9f8c79d21..9bcb6353e8dd 100644 --- a/asoc/codecs/wcd-dsp-mgr.c +++ b/asoc/codecs/wcd-dsp-mgr.c @@ -838,6 +838,45 @@ static int wdsp_ssr_handler(struct wdsp_mgr_priv *wdsp, void *arg, return 0; } +#ifdef CONFIG_DEBUG_FS +static int wdsp_debug_dump_handler(struct wdsp_mgr_priv *wdsp, void *arg) +{ + struct wdsp_err_signal_arg *err_data; + int ret = 0; + + WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex); + /* If there is no SSR, set the SSR type to collect ramdumps */ + if (wdsp->ssr_type == WDSP_SSR_TYPE_NO_SSR) { + wdsp->ssr_type = WDSP_SSR_TYPE_WDSP_DOWN; + } else { + WDSP_DBG(wdsp, "SSR handling is running, skip debug ramdump"); + ret = 0; + WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex); + goto done; + } + if (arg) { + err_data = (struct wdsp_err_signal_arg *) arg; + memcpy(&wdsp->dump_data.err_data, err_data, + sizeof(*err_data)); + } else { + WDSP_DBG(wdsp, "Invalid input, arg is NULL"); + ret = -EINVAL; + WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex); + goto done; + } + wdsp_collect_ramdumps(wdsp); + wdsp->ssr_type = WDSP_SSR_TYPE_NO_SSR; + WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex); +done: + return ret; +} +#else +static int wdsp_debug_dump_handler(struct wdsp_mgr_priv *wdsp, void *arg) +{ + return 0; +} +#endif + static int wdsp_signal_handler(struct device *wdsp_dev, enum wdsp_signal signal, void *arg) { @@ -866,6 +905,9 @@ static int wdsp_signal_handler(struct device *wdsp_dev, case WDSP_CDC_UP_SIGNAL: ret = wdsp_ssr_handler(wdsp, arg, WDSP_SSR_TYPE_CDC_UP); break; + case WDSP_DEBUG_DUMP: + ret = wdsp_debug_dump_handler(wdsp, arg); + break; default: ret = -EINVAL; break; diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c index 031940ecbaf9..35e12244cbfa 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c @@ -31,6 +31,7 @@ #define WCD_PROCFS_ENTRY_MAX_LEN 16 #define WCD_934X_RAMDUMP_START_ADDR 0x20100000 #define WCD_934X_RAMDUMP_SIZE ((1024 * 1024) - 128) +#define WCD_MISCDEV_CMD_MAX_LEN 11 #define WCD_CNTL_MUTEX_LOCK(codec, lock) \ { \ @@ -76,6 +77,95 @@ static u8 mem_enable_values[] = { 0xE0, 0xC0, 0x80, 0x00, }; +#ifdef CONFIG_DEBUG_FS +#define WCD_CNTL_SET_ERR_IRQ_FLAG(cntl)\ + atomic_cmpxchg(&cntl->err_irq_flag, 0, 1) +#define WCD_CNTL_CLR_ERR_IRQ_FLAG(cntl)\ + atomic_set(&cntl->err_irq_flag, 0) + +static u16 wdsp_reg_for_debug_dump[] = { + WCD934X_CPE_SS_CPE_CTL, + WCD934X_CPE_SS_PWR_SYS_PSTATE_CTL_0, + WCD934X_CPE_SS_PWR_SYS_PSTATE_CTL_1, + WCD934X_CPE_SS_PWR_CPEFLL_CTL, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_OVERRIDE, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_4, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_5, + WCD934X_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN, + WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL, + WCD934X_CPE_SS_MAD_CTL, + WCD934X_CPE_SS_CPAR_CTL, + WCD934X_CPE_SS_WDOG_CFG, + WCD934X_CPE_SS_STATUS, + WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, + WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, + WCD934X_CPE_SS_SS_ERROR_INT_MASK_1A, + WCD934X_CPE_SS_SS_ERROR_INT_MASK_1B, + WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0A, + WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0B, + WCD934X_CPE_SS_SS_ERROR_INT_STATUS_1A, + WCD934X_CPE_SS_SS_ERROR_INT_STATUS_1B, +}; + +static void wcd_cntl_collect_debug_dumps(struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + struct wdsp_err_signal_arg arg; + int i; + u8 val; + + /* If WDSP SSR happens, skip collecting debug dumps */ + if (WCD_CNTL_SET_ERR_IRQ_FLAG(cntl) != 0) + return; + + /* Mask all error interrupts */ + snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, + 0xFF); + snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, + 0xFF); + + /* Collect important WDSP registers dump for debug use */ + pr_err("%s: Dump the WDSP registers for debug use\n", __func__); + for (i = 0; i < sizeof(wdsp_reg_for_debug_dump)/sizeof(u16); i++) { + val = snd_soc_read(codec, wdsp_reg_for_debug_dump[i]); + pr_err("%s: reg = 0x%x, val = 0x%x\n", __func__, + wdsp_reg_for_debug_dump[i], val); + } + + /* Trigger NMI in WDSP to sync and update the memory */ + snd_soc_write(codec, WCD934X_CPE_SS_BACKUP_INT, 0x02); + + /* Collect WDSP ramdump for debug use */ + if (cntl->m_dev && cntl->m_ops && cntl->m_ops->signal_handler) { + arg.mem_dumps_enabled = cntl->ramdump_enable; + arg.remote_start_addr = WCD_934X_RAMDUMP_START_ADDR; + arg.dump_size = WCD_934X_RAMDUMP_SIZE; + cntl->m_ops->signal_handler(cntl->m_dev, WDSP_DEBUG_DUMP, + &arg); + } + + /* Unmask the fatal irqs */ + snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, + ~(cntl->irqs.fatal_irqs & 0xFF)); + snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, + ~((cntl->irqs.fatal_irqs >> 8) & 0xFF)); + + WCD_CNTL_CLR_ERR_IRQ_FLAG(cntl); +} +#else +#define WCD_CNTL_SET_ERR_IRQ_FLAG(cntl) 0 +#define WCD_CNTL_CLR_ERR_IRQ_FLAG(cntl) do {} while (0) +static void wcd_cntl_collect_debug_dumps(struct wcd_dsp_cntl *cntl) +{ +} +#endif + static ssize_t wdsp_boot_show(struct wcd_dsp_cntl *cntl, char *buf) { return snprintf(buf, WCD_SYSFS_ENTRY_MAX_LEN, @@ -663,6 +753,7 @@ static int wcd_cntl_do_boot(struct wcd_dsp_cntl *cntl) if (!ret) { dev_err(codec->dev, "%s: WDSP boot timed out\n", __func__); + wcd_cntl_collect_debug_dumps(cntl); ret = -ETIMEDOUT; goto err_boot; } else { @@ -719,7 +810,7 @@ static irqreturn_t wcd_cntl_err_irq(int irq, void *data) struct wdsp_err_signal_arg arg; u16 status = 0; u8 reg_val; - int ret = 0; + int rc, ret = 0; reg_val = snd_soc_read(codec, WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0A); status = status | reg_val; @@ -732,6 +823,12 @@ static irqreturn_t wcd_cntl_err_irq(int irq, void *data) if ((status & cntl->irqs.fatal_irqs) && (cntl->m_dev && cntl->m_ops && cntl->m_ops->signal_handler)) { + /* + * If WDSP SSR happens, skip collecting debug dumps. + * If debug dumps collecting happens first, WDSP_ERR_INTR + * will be blocked in signal_handler and get processed later. + */ + rc = WCD_CNTL_SET_ERR_IRQ_FLAG(cntl); arg.mem_dumps_enabled = cntl->ramdump_enable; arg.remote_start_addr = WCD_934X_RAMDUMP_START_ADDR; arg.dump_size = WCD_934X_RAMDUMP_SIZE; @@ -742,6 +839,8 @@ static irqreturn_t wcd_cntl_err_irq(int irq, void *data) "%s: Failed to handle fatal irq 0x%x\n", __func__, status & cntl->irqs.fatal_irqs); wcd_cntl_change_online_state(cntl, 0); + if (rc == 0) + WCD_CNTL_CLR_ERR_IRQ_FLAG(cntl); } else { dev_err(cntl->codec->dev, "%s: Invalid signal_handler\n", __func__); @@ -912,7 +1011,7 @@ static ssize_t wcd_miscdev_write(struct file *filep, const char __user *ubuf, bool vote; int ret = 0; - if (count == 0 || count > 2) { + if (count == 0 || count > WCD_MISCDEV_CMD_MAX_LEN) { pr_err("%s: Invalid count = %zd\n", __func__, count); ret = -EINVAL; goto done; @@ -939,6 +1038,11 @@ static ssize_t wcd_miscdev_write(struct file *filep, const char __user *ubuf, } cntl->boot_reqs--; vote = false; + } else if (!strcmp(val, "DEBUG_DUMP")) { + dev_dbg(cntl->codec->dev, + "%s: Collect dumps for debug use\n", __func__); + wcd_cntl_collect_debug_dumps(cntl); + goto done; } else { dev_err(cntl->codec->dev, "%s: Invalid value %s\n", __func__, val); @@ -1309,6 +1413,7 @@ void wcd_dsp_cntl_init(struct snd_soc_codec *codec, mutex_init(&control->clk_mutex); mutex_init(&control->ssr_mutex); init_waitqueue_head(&control->ssr_entry.offline_poll_wait); + WCD_CNTL_CLR_ERR_IRQ_FLAG(control); /* * The default state of WDSP is in SVS mode. diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h index e934638cc487..2f71d0e18edb 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -109,6 +109,10 @@ struct wcd_dsp_cntl { /* Misc device related */ char miscdev_name[256]; struct miscdevice miscdev; +#ifdef CONFIG_DEBUG_FS + /* Debug dump related */ + atomic_t err_irq_flag; +#endif }; void wcd_dsp_cntl_init(struct snd_soc_codec *codec, -- GitLab From 82597ffeeccbb1facc9bb948be91d309fa01e318 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 15 Dec 2017 16:17:42 -0800 Subject: [PATCH 0132/1645] asoc: codecs: Fix device switch pop issue With AANC enabled, and when the device switches from speaker path to handset path there is a audible pop. Add more delay to the aanc enable work function to resolve the pop issue. CRs-Fixed: 2137607 Change-Id: Icaf381179b0a81440b21ab4280cb6fc95e6fe6ba Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd934x/wcd934x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 8e3981c9fdf5..e7cec2b4d348 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -526,7 +526,7 @@ struct tx_mute_work { struct delayed_work dwork; }; -#define WCD934X_SPK_ANC_EN_DELAY_MS 350 +#define WCD934X_SPK_ANC_EN_DELAY_MS 550 static int spk_anc_en_delay = WCD934X_SPK_ANC_EN_DELAY_MS; module_param(spk_anc_en_delay, int, 0664); MODULE_PARM_DESC(spk_anc_en_delay, "delay to enable anc in speaker path"); -- GitLab From 817af9a7f17b454d6e16ee8c5068017013382250 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 28 Dec 2017 11:42:43 +0530 Subject: [PATCH 0133/1645] ASoC: sdm660_cdc: Fix ear_pa_gain control In analog codec, EAR PA gain control get function is updated with input value again resulting in override. Remove the override of control value again. CRs-Fixed: 2161617 Change-Id: I7ddd252adf53666a6c9adc1bc92e840067fa932c Signed-off-by: Laxminath Kasam --- asoc/codecs/sdm660_cdc/msm-analog-cdc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c index a1732b722b9e..9121baf0f418 100644 --- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c @@ -1595,11 +1595,11 @@ static int msm_anlg_cdc_pa_gain_get(struct snd_kcontrol *kcontrol, if (ear_pa_gain == 0x00) { ucontrol->value.integer.value[0] = 3; } else if (ear_pa_gain == 0x01) { - ucontrol->value.integer.value[1] = 2; + ucontrol->value.integer.value[0] = 2; } else if (ear_pa_gain == 0x02) { - ucontrol->value.integer.value[2] = 1; + ucontrol->value.integer.value[0] = 1; } else if (ear_pa_gain == 0x03) { - ucontrol->value.integer.value[3] = 0; + ucontrol->value.integer.value[0] = 0; } else { dev_err(codec->dev, "%s: ERROR: Unsupported Ear Gain = 0x%x\n", @@ -1621,7 +1621,6 @@ static int msm_anlg_cdc_pa_gain_get(struct snd_kcontrol *kcontrol, return -EINVAL; } } - ucontrol->value.integer.value[0] = ear_pa_gain; dev_dbg(codec->dev, "%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain); return 0; } -- GitLab From 942d1c6ed175c95f5b2041c2317f35a8af0c5ca3 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 29 Dec 2017 11:02:22 +0530 Subject: [PATCH 0134/1645] audio: Enable audio compile for 8953 Add support for audio compile for 8953. Change-Id: I37ef20b44aecba8ffc9a7d1d346bf83a9115ad1b Signed-off-by: Laxminath Kasam --- Android.mk | 4 ++-- asoc/Android.mk | 6 +++--- asoc/Kbuild | 5 +++++ asoc/codecs/Android.mk | 6 +++--- asoc/codecs/Kbuild | 5 +++++ asoc/codecs/msm_sdw/Android.mk | 2 +- asoc/codecs/msm_sdw/Kbuild | 5 +++++ asoc/codecs/sdm660_cdc/Android.mk | 2 +- asoc/codecs/sdm660_cdc/Kbuild | 5 +++++ asoc/codecs/wcd934x/Android.mk | 4 ++-- asoc/codecs/wcd934x/Kbuild | 5 +++++ dsp/Android.mk | 4 ++-- dsp/Kbuild | 5 +++++ dsp/codecs/Android.mk | 4 ++-- dsp/codecs/Kbuild | 5 +++++ ipc/Android.mk | 4 ++-- ipc/Kbuild | 5 +++++ soc/Android.mk | 6 +++--- soc/Kbuild | 5 +++++ 19 files changed, 66 insertions(+), 21 deletions(-) diff --git a/Android.mk b/Android.mk index a95c0da7e7fd..cda991e9889f 100644 --- a/Android.mk +++ b/Android.mk @@ -3,7 +3,7 @@ MY_LOCAL_PATH := $(call my-dir) UAPI_OUT := $(OUT)/obj/vendor/qcom/opensource/audio-kernel/include -ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) $(shell mkdir -p $(UAPI_OUT)/linux;) $(shell mkdir -p $(UAPI_OUT)/sound;) $(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers) @@ -23,7 +23,7 @@ include $(MY_LOCAL_PATH)/asoc/codecs/Android.mk include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk endif -ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) $(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers) $(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/sdm660_cdc/Android.mk diff --git a/asoc/Android.mk b/asoc/Android.mk index 73b17d3dea54..5023a09828a3 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -8,14 +8,14 @@ TARGET := sdm845 AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m endif -ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) TARGET := sdm670 AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) LOCAL_PATH := $(call my-dir) @@ -50,7 +50,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### -ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_cpe_lsm.ko LOCAL_MODULE_KBUILD_NAME := cpe_lsm_dlkm.ko diff --git a/asoc/Kbuild b/asoc/Kbuild index e5b8514c9db7..91ebf8a0e0ad 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -25,6 +25,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM450), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index 24bf2f837dd5..037774c2252e 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -7,13 +7,13 @@ ifeq ($(call is-board-platform,sdm845),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m endif -ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) LOCAL_PATH := $(call my-dir) @@ -74,7 +74,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### -ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd9335.ko LOCAL_MODULE_KBUILD_NAME := wcd9335_dlkm.ko diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 1cbd20e459f7..005a68cd4a9e 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -24,6 +24,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM450), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/asoc/codecs/msm_sdw/Android.mk b/asoc/codecs/msm_sdw/Android.mk index dc6cd27b29d9..338e7f450221 100644 --- a/asoc/codecs/msm_sdw/Android.mk +++ b/asoc/codecs/msm_sdw/Android.mk @@ -4,7 +4,7 @@ AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/msm_sdw/Kbuild b/asoc/codecs/msm_sdw/Kbuild index e2b5bc319516..f687cddf5155 100644 --- a/asoc/codecs/msm_sdw/Kbuild +++ b/asoc/codecs/msm_sdw/Kbuild @@ -25,6 +25,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM450), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/asoc/codecs/sdm660_cdc/Android.mk b/asoc/codecs/sdm660_cdc/Android.mk index 5a7878c4b03c..43a5645fdf64 100644 --- a/asoc/codecs/sdm660_cdc/Android.mk +++ b/asoc/codecs/sdm660_cdc/Android.mk @@ -4,7 +4,7 @@ AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/sdm660_cdc/Kbuild b/asoc/codecs/sdm660_cdc/Kbuild index 56122c1e9898..6c379e1bfc70 100644 --- a/asoc/codecs/sdm660_cdc/Kbuild +++ b/asoc/codecs/sdm660_cdc/Kbuild @@ -25,6 +25,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM450), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/asoc/codecs/wcd934x/Android.mk b/asoc/codecs/wcd934x/Android.mk index 9cb8ec28e6a9..0fe519ffded7 100644 --- a/asoc/codecs/wcd934x/Android.mk +++ b/asoc/codecs/wcd934x/Android.mk @@ -7,13 +7,13 @@ ifeq ($(call is-board-platform,sdm845),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m endif -ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index e46e39d20cf6..7ea91ce677e1 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -26,6 +26,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM450), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/dsp/Android.mk b/dsp/Android.mk index 4883ab4b2885..98f865b8a96f 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -7,13 +7,13 @@ ifeq ($(call is-board-platform,sdm845),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m endif -ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/Kbuild b/dsp/Kbuild index 306a25a12604..73dcb2ae330b 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -24,6 +24,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM450), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h + endif endif diff --git a/dsp/codecs/Android.mk b/dsp/codecs/Android.mk index 020d7998a889..984a5139c94c 100644 --- a/dsp/codecs/Android.mk +++ b/dsp/codecs/Android.mk @@ -7,13 +7,13 @@ ifeq ($(call is-board-platform,sdm845),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m endif -ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 13b2399217d8..34d39ad06d23 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -25,6 +25,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM450), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/ipc/Android.mk b/ipc/Android.mk index d72f68a9e926..b7908dce51c3 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -7,13 +7,13 @@ ifeq ($(call is-board-platform,sdm845),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m endif -ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) LOCAL_PATH := $(call my-dir) diff --git a/ipc/Kbuild b/ipc/Kbuild index 92760fb0cd2f..72c9ef1c25b0 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -34,6 +34,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM450), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/soc/Android.mk b/soc/Android.mk index 4a18e108e42c..1c256fefc796 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -7,13 +7,13 @@ ifeq ($(call is-board-platform,sdm845),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m endif -ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm845 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) LOCAL_PATH := $(call my-dir) @@ -40,7 +40,7 @@ KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) KBUILD_OPTIONS += $(AUDIO_SELECT) ########################################################### -ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_lpi.ko LOCAL_MODULE_KBUILD_NAME := pinctrl_lpi_dlkm.ko diff --git a/soc/Kbuild b/soc/Kbuild index c9cf31bc2039..29f69d578e92 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -24,6 +24,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM450), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h + endif endif # As per target team, build is done as follows: -- GitLab From 30feb0d4a0f74c60fae0d82452fe543490e345d8 Mon Sep 17 00:00:00 2001 From: Revathi Uddaraju Date: Tue, 21 Nov 2017 15:30:19 +0530 Subject: [PATCH 0135/1645] sdm670: Add mixer control and update affine qos value Add mixer control for MultiMedia5_RX QOS Vote and update affine qos value. Change-Id: Id027ea4c708d0827a24ca655d0f1810331100cee Signed-off-by: Revathi Uddaraju --- asoc/sdm660-common.c | 61 +++++++++++++++++++++++++++++++++++++ asoc/sdm660-ext-dai-links.c | 28 +++++++++++++++++ asoc/sdm660-internal.c | 29 +++++++++++++++++- 3 files changed, 117 insertions(+), 1 deletion(-) diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c index 1874cfa02860..449664287303 100644 --- a/asoc/sdm660-common.c +++ b/asoc/sdm660-common.c @@ -26,6 +26,9 @@ #include "codecs/sdm660_cdc/msm-analog-cdc.h" #include "codecs/wsa881x.h" +#define __CHIPSET__ "SDM660 " +#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) + #define DRV_NAME "sdm660-asoc-snd" #define MSM_INT_DIGITAL_CODEC "msm-dig-codec" @@ -33,6 +36,7 @@ #define DEV_NAME_STR_LEN 32 #define DEFAULT_MCLK_RATE 9600000 +#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ struct dev_config { u32 sample_rate; @@ -303,6 +307,7 @@ static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE"}; static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96", "KHZ_192"}; +static const char *const qos_text[] = {"Disable", "Enable"}; static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); @@ -361,6 +366,9 @@ static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(qos_vote, qos_text); + +static int qos_vote_status; static struct afe_clk_set mi2s_clk[MI2S_MAX] = { { @@ -1877,6 +1885,57 @@ static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol, return 0; } +static int msm_qos_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = qos_vote_status; + + return 0; +} + +static int msm_qos_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_card *card = codec->component.card; + const char *fe_name = MSM_DAILINK_NAME(LowLatency); + struct snd_soc_pcm_runtime *rtd; + struct snd_pcm_substream *substream; + s32 usecs; + + rtd = snd_soc_get_pcm_runtime(card, fe_name); + if (!rtd) { + pr_err("%s: fail to get pcm runtime for %s\n", + __func__, fe_name); + return -EINVAL; + } + + substream = rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + if (!substream) { + pr_err("%s: substream is null\n", __func__); + return -EINVAL; + } + + qos_vote_status = ucontrol->value.enumerated.item[0]; + if (qos_vote_status) { + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + if (!substream->runtime) { + pr_err("%s: runtime is null\n", __func__); + return -EINVAL; + } + usecs = MSM_LL_QOS_VALUE; + if (usecs >= 0) + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, usecs); + } else { + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + } + + return 0; +} + const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, proxy_rx_ch_get, proxy_rx_ch_put), @@ -2101,6 +2160,8 @@ const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("QUIN_TDM_TX_0 Channels", tdm_tx_chs, tdm_tx_ch_get, tdm_tx_ch_put), + SOC_ENUM_EXT("MultiMedia5_RX QOS Vote", qos_vote, msm_qos_ctl_get, + msm_qos_ctl_put), }; /** diff --git a/asoc/sdm660-ext-dai-links.c b/asoc/sdm660-ext-dai-links.c index 33e8e0aa2a89..5e37da364fe4 100644 --- a/asoc/sdm660-ext-dai-links.c +++ b/asoc/sdm660-ext-dai-links.c @@ -21,6 +21,7 @@ #include "sdm660-external.h" #include "codecs/core.h" #include "codecs/wcd9335.h" +#include #define DEV_NAME_STR_LEN 32 #define __CHIPSET__ "SDM660 " @@ -28,6 +29,7 @@ #define WCN_CDC_SLIM_RX_CH_MAX 2 #define WCN_CDC_SLIM_TX_CH_MAX 3 +#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ static struct snd_soc_card snd_soc_card_msm_card_tavil = { .name = "sdm670-tavil-snd-card", @@ -279,6 +281,30 @@ static struct snd_soc_ops msm_tdm_be_ops = { .hw_params = msm_tdm_snd_hw_params }; +static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) +{ + cpumask_t mask; + + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + + cpumask_clear(&mask); + cpumask_set_cpu(1, &mask); /* affine to core 1 */ + cpumask_set_cpu(2, &mask); /* affine to core 2 */ + cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); + + substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; + + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + MSM_LL_QOS_VALUE); + return 0; +} + +static struct snd_soc_ops msm_fe_qos_ops = { + .prepare = msm_fe_qos_prepare, +}; + static struct snd_soc_dai_link msm_ext_tasha_fe_dai[] = { /* tasha_vifeedback for speaker protection */ { @@ -963,6 +989,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { /* this dai link has playback support */ .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .ops = &msm_fe_qos_ops, }, /* LSM FE */ {/* hw:x,14 */ @@ -1032,6 +1059,7 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .ignore_pmdown_time = 1, /* this dai link has playback support */ .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + .ops = &msm_fe_qos_ops, }, {/* hw:x,18 */ .name = "HDMI_RX_HOSTLESS", diff --git a/asoc/sdm660-internal.c b/asoc/sdm660-internal.c index adcd294799bd..2446d7bafa08 100644 --- a/asoc/sdm660-internal.c +++ b/asoc/sdm660-internal.c @@ -20,6 +20,7 @@ #include "codecs/sdm660_cdc/msm-digital-cdc.h" #include "codecs/sdm660_cdc/msm-analog-cdc.h" #include "codecs/msm_sdw/msm_sdw.h" +#include #define __CHIPSET__ "SDM660 " #define MSM_DAILINK_NAME(name) (__CHIPSET__#name) @@ -31,7 +32,7 @@ #define WSA8810_NAME_1 "wsa881x.20170211" #define WSA8810_NAME_2 "wsa881x.20170212" - +#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ enum { INT0_MI2S = 0, INT1_MI2S, @@ -1636,6 +1637,30 @@ static struct snd_soc_ops msm_sdw_mi2s_be_ops = { .shutdown = msm_sdw_mi2s_snd_shutdown, }; +static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) +{ + cpumask_t mask; + + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + + cpumask_clear(&mask); + cpumask_set_cpu(1, &mask); /* affine to core 1 */ + cpumask_set_cpu(2, &mask); /* affine to core 2 */ + cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); + + substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; + + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + MSM_LL_QOS_VALUE); + return 0; +} + +static struct snd_soc_ops msm_fe_qos_ops = { + .prepare = msm_fe_qos_prepare, +}; + struct snd_soc_dai_link_component dlc_rx1[] = { { .of_node = NULL, @@ -1892,6 +1917,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { /* this dai link has playback support */ .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .ops = &msm_fe_qos_ops, }, /* LSM FE */ {/* hw:x,14 */ @@ -1959,6 +1985,7 @@ static struct snd_soc_dai_link msm_int_dai[] = { .ignore_pmdown_time = 1, /* this dai link has playback support */ .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + .ops = &msm_fe_qos_ops, }, {/* hw:x,18 */ .name = "HDMI_RX_HOSTLESS", -- GitLab From 65b7a17e0f1b6408ae406779af539f07bb804de0 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Tue, 12 Dec 2017 17:33:24 -0800 Subject: [PATCH 0136/1645] dsp: Update ADSP status to reflect failure Update the adsp status to log failures during AVCS_CMDRSP_GET_FWK_VERSION callback. Set q6core_avcs_ver_info status to VER_QUERY_SUPPORTED only when there is a valid ADSP response for framework version. Change-Id: Ie2c6db2842c0b89c9d1a3807bcb49d413a639988 Signed-off-by: Vignesh Kulothungan --- dsp/q6core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/dsp/q6core.c b/dsp/q6core.c index 5e09faa7d7e8..e7c41bb9c2c9 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -236,12 +236,16 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) pr_debug("%s: Received AVCS_CMDRSP_GET_FWK_VERSION\n", __func__); payload1 = data->payload; - q6core_lcl.q6core_avcs_ver_info.status = VER_QUERY_SUPPORTED; q6core_lcl.avcs_fwk_ver_resp_received = 1; ret = parse_fwk_version_info(payload1); - if (ret < 0) + if (ret < 0) { + q6core_lcl.adsp_status = ret; pr_err("%s: Failed to parse payload:%d\n", __func__, ret); + } else { + q6core_lcl.q6core_avcs_ver_info.status = + VER_QUERY_SUPPORTED; + } wake_up(&q6core_lcl.avcs_fwk_ver_req_wait); break; default: -- GitLab From 9ae2ddedeee49c7b81475aa1339c35a86e5983d1 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 9 Jan 2018 11:35:29 +0530 Subject: [PATCH 0137/1645] dsp: fix NULL pointer exception in core driver NULL pointer dereference occurs while getting version size when version info memory allocation fails. Add NULL check to avoid this NULL pointer exception. CRs-Fixed: 2142971 Change-Id: I47a905a9b4e767d54b406a279626369f18a861d9 Signed-off-by: Aditya Bavanari --- dsp/q6core.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/dsp/q6core.c b/dsp/q6core.c index e7c41bb9c2c9..c5b64096a234 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -108,8 +108,7 @@ static int parse_fwk_version_info(uint32_t *payload) */ ver_size = sizeof(struct avcs_get_fwk_version) + num_services * sizeof(struct avs_svc_api_info); - if (q6core_lcl.q6core_avcs_ver_info.ver_info != NULL) - pr_warn("%s: Version info is not NULL\n", __func__); + q6core_lcl.q6core_avcs_ver_info.ver_info = kzalloc(ver_size, GFP_ATOMIC); if (q6core_lcl.q6core_avcs_ver_info.ver_info == NULL) @@ -236,7 +235,6 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) pr_debug("%s: Received AVCS_CMDRSP_GET_FWK_VERSION\n", __func__); payload1 = data->payload; - q6core_lcl.avcs_fwk_ver_resp_received = 1; ret = parse_fwk_version_info(payload1); if (ret < 0) { q6core_lcl.adsp_status = ret; @@ -246,6 +244,7 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) q6core_lcl.q6core_avcs_ver_info.status = VER_QUERY_SUPPORTED; } + q6core_lcl.avcs_fwk_ver_resp_received = 1; wake_up(&q6core_lcl.avcs_fwk_ver_req_wait); break; default: @@ -445,8 +444,14 @@ size_t q6core_get_fwk_version_size(uint32_t service_id) if (ret) goto done; - num_services = q6core_lcl.q6core_avcs_ver_info.ver_info - ->avcs_fwk_version.num_services; + if (q6core_lcl.q6core_avcs_ver_info.ver_info != NULL) { + num_services = q6core_lcl.q6core_avcs_ver_info.ver_info + ->avcs_fwk_version.num_services; + } else { + pr_err("%s: ver_info is NULL\n", __func__); + ret = -EINVAL; + goto done; + } ret = sizeof(struct avcs_get_fwk_version); if (service_id == AVCS_SERVICE_ID_ALL) -- GitLab From d61b84dec187cc8339d04249b7a5ad1383494bb3 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 3 Jan 2018 13:24:06 +0530 Subject: [PATCH 0138/1645] asoc: sdm670: check sound card status before sending AFE config WCD codec must be enumerated before AFE configuration for some of the features can be sent to DSP. This is because as part of setting up this configuration, DSP tries to access some codec register. These register accesses will fail if codec is not enumerated already. Add a check for sound card online state to confirm that WCD codec has already enumerated before sending AFE configs. CRs-Fixed: 2166356 Change-Id: Ie5883f3543872d7a049a00a4c70445232360f2f9 Signed-off-by: Aditya Bavanari --- asoc/sdm660-external.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/asoc/sdm660-external.c b/asoc/sdm660-external.c index b22a365cd4be..8ff98eddef0e 100644 --- a/asoc/sdm660-external.c +++ b/asoc/sdm660-external.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1215,34 +1215,44 @@ static void msm_afe_clear_config(void) afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); } -static int msm_adsp_power_up_config(struct snd_soc_codec *codec) +static int msm_adsp_power_up_config(struct snd_soc_codec *codec, + struct snd_card *card) { int ret = 0; unsigned long timeout; int adsp_ready = 0; - struct snd_soc_card *card = codec->component.card; - struct msm_asoc_mach_data *pdata; + bool snd_card_online = 0; - pdata = snd_soc_card_get_drvdata(card); timeout = jiffies + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); do { - if (q6core_is_adsp_ready()) { - pr_debug("%s: ADSP Audio is ready\n", __func__); - adsp_ready = 1; - break; + if (!snd_card_online) { + snd_card_online = snd_card_is_online_state(card); + pr_debug("%s: Sound card is %s\n", __func__, + snd_card_online ? "Online" : "Offline"); } + if (!adsp_ready) { + adsp_ready = q6core_is_adsp_ready(); + pr_debug("%s: ADSP Audio is %s\n", __func__, + adsp_ready ? "ready" : "not ready"); + } + if (snd_card_online && adsp_ready) + break; + /* - * ADSP will be coming up after subsystem restart and + * Sound card/ADSP will be coming up after subsystem restart and * it might not be fully up when the control reaches * here. So, wait for 50msec before checking ADSP state */ msleep(50); } while (time_after(timeout, jiffies)); - if (!adsp_ready) { - pr_err("%s: timed out waiting for ADSP Audio\n", __func__); + if (!snd_card_online || !adsp_ready) { + pr_err("%s: Timeout. Sound card is %s, ADSP Audio is %s\n", + __func__, + snd_card_online ? "Online" : "Offline", + adsp_ready ? "ready" : "not ready"); ret = -ETIMEDOUT; goto err_fail; } @@ -1300,7 +1310,7 @@ static int sdm660_notifier_service_cb(struct notifier_block *this, } codec = rtd->codec; - ret = msm_adsp_power_up_config(codec); + ret = msm_adsp_power_up_config(codec, card->snd_card); if (ret < 0) { dev_err(card->dev, "%s: msm_adsp_power_up_config failed ret = %d!\n", @@ -1688,7 +1698,7 @@ int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) msm_codec_fn.mbhc_hs_detect_exit = tasha_mbhc_hs_detect_exit; } - ret = msm_adsp_power_up_config(codec); + ret = msm_adsp_power_up_config(codec, rtd->card->snd_card); if (ret) { pr_err("%s: Failed to set AFE config %d\n", __func__, ret); goto err_afe_cfg; -- GitLab From 140a80a114fa6e3928b36b50635b0e463ab7980b Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 3 Jan 2018 16:51:17 +0530 Subject: [PATCH 0139/1645] asoc: sdm670: add/remove flag ignore_pmdown_time for RX/TX DAIs - During PCM close, the AIF power down will be delayed if ignore_pmdown_time flag is not set. Set this flag for ultrasound RX DAI to avoid delay in PCM close which causes slimbus overflow. - Flag ignore_pmdown_time is only required to be set for RX DAIs. Add this flag for RX DAIs that don't have it and remove this flag for TX DAIs that have it in sdm670 machine driver. CRs-Fixed: 2166356 Change-Id: I794ee96fb96fe04091ce73f0b48f84ebf119256c Signed-off-by: Aditya Bavanari --- asoc/sdm660-ext-dai-links.c | 27 ++++++++++----------------- asoc/sdm660-internal.c | 25 ++++++++----------------- 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/asoc/sdm660-ext-dai-links.c b/asoc/sdm660-ext-dai-links.c index 5e37da364fe4..02d35a9ebf7d 100644 --- a/asoc/sdm660-ext-dai-links.c +++ b/asoc/sdm660-ext-dai-links.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -331,6 +331,7 @@ static struct snd_soc_dai_link msm_ext_tasha_fe_dai[] = { .ignore_suspend = 1, .dpcm_playback = 1, .dpcm_capture = 1, + .ignore_pmdown_time = 1, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ops = &msm_ext_slimbus_2_be_ops, }, @@ -358,7 +359,6 @@ static struct snd_soc_dai_link msm_ext_tasha_fe_dai[] = { .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, .dpcm_capture = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "tasha_mad1", .codec_name = "tasha_codec", .ops = &msm_ext_cpe_ops, @@ -418,6 +418,7 @@ static struct snd_soc_dai_link msm_ext_tavil_fe_dai[] = { .codec_name = "tavil_codec", .codec_dai_name = "tavil_rx2", .ignore_suspend = 1, + .ignore_pmdown_time = 1, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ops = &msm_ext_slimbus_2_be_ops, }, @@ -1003,7 +1004,6 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { SND_SOC_DPCM_TRIGGER_POST }, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM1, @@ -1033,7 +1033,6 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .dynamic = 1, .dpcm_capture = 1, .dpcm_playback = 1, - .dpcm_capture = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .codec_dai_name = "snd-soc-dummy-dai", @@ -1104,7 +1103,6 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { SND_SOC_DPCM_TRIGGER_POST }, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM2, @@ -1120,7 +1118,6 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { SND_SOC_DPCM_TRIGGER_POST }, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM3, @@ -1136,7 +1133,6 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { SND_SOC_DPCM_TRIGGER_POST }, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM4, @@ -1152,7 +1148,6 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { SND_SOC_DPCM_TRIGGER_POST }, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM5, @@ -1168,7 +1163,6 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { SND_SOC_DPCM_TRIGGER_POST }, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM6 @@ -1184,7 +1178,6 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { SND_SOC_DPCM_TRIGGER_POST }, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM7, @@ -1200,7 +1193,6 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { SND_SOC_DPCM_TRIGGER_POST }, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM8, @@ -1335,7 +1327,6 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { SND_SOC_DPCM_TRIGGER_POST}, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, @@ -1444,6 +1435,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ignore_suspend = 1, + .ignore_pmdown_time = 1, }, /* Incall Music 2 BACK END DAI Link */ { @@ -1458,6 +1450,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ignore_suspend = 1, + .ignore_pmdown_time = 1, }, { .name = LPASS_BE_USB_AUDIO_RX, @@ -1499,6 +1492,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, + .ignore_pmdown_time = 1, }, { .name = LPASS_BE_PRI_TDM_TX_0, @@ -1527,6 +1521,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, + .ignore_pmdown_time = 1, }, { .name = LPASS_BE_SEC_TDM_TX_0, @@ -1555,6 +1550,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, + .ignore_pmdown_time = 1, }, { .name = LPASS_BE_TERT_TDM_TX_0, @@ -1583,6 +1579,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, + .ignore_pmdown_time = 1, }, { .name = LPASS_BE_QUAT_TDM_TX_0, @@ -1611,6 +1608,7 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, + .ignore_pmdown_time = 1, }, { .name = LPASS_BE_QUIN_TDM_TX_0, @@ -1804,7 +1802,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_pmdown_time = 1, .ignore_suspend = 1, .ops = &msm_aux_pcm_be_ops, }, @@ -1836,7 +1833,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .ops = &msm_aux_pcm_be_ops, }, /* Tertiary AUX PCM Backend DAI Links */ @@ -1867,7 +1863,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .ops = &msm_aux_pcm_be_ops, }, /* Quaternary AUX PCM Backend DAI Links */ @@ -1898,7 +1893,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .ops = &msm_aux_pcm_be_ops, }, /* Quinary AUX PCM Backend DAI Links */ @@ -1929,7 +1923,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .ops = &msm_aux_pcm_be_ops, }, }; diff --git a/asoc/sdm660-internal.c b/asoc/sdm660-internal.c index 2446d7bafa08..7e02e21f3629 100644 --- a/asoc/sdm660-internal.c +++ b/asoc/sdm660-internal.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1881,7 +1881,6 @@ static struct snd_soc_dai_link msm_int_dai[] = { SND_SOC_DPCM_TRIGGER_POST}, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, @@ -1931,7 +1930,6 @@ static struct snd_soc_dai_link msm_int_dai[] = { SND_SOC_DPCM_TRIGGER_POST }, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM1, @@ -2030,7 +2028,6 @@ static struct snd_soc_dai_link msm_int_dai[] = { SND_SOC_DPCM_TRIGGER_POST }, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM2, @@ -2046,7 +2043,6 @@ static struct snd_soc_dai_link msm_int_dai[] = { SND_SOC_DPCM_TRIGGER_POST }, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM3, @@ -2062,7 +2058,6 @@ static struct snd_soc_dai_link msm_int_dai[] = { SND_SOC_DPCM_TRIGGER_POST }, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM4, @@ -2078,7 +2073,6 @@ static struct snd_soc_dai_link msm_int_dai[] = { SND_SOC_DPCM_TRIGGER_POST }, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM5, @@ -2094,7 +2088,6 @@ static struct snd_soc_dai_link msm_int_dai[] = { SND_SOC_DPCM_TRIGGER_POST }, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM6 @@ -2110,7 +2103,6 @@ static struct snd_soc_dai_link msm_int_dai[] = { SND_SOC_DPCM_TRIGGER_POST }, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM7, @@ -2126,7 +2118,6 @@ static struct snd_soc_dai_link msm_int_dai[] = { SND_SOC_DPCM_TRIGGER_POST }, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM8, @@ -2261,7 +2252,6 @@ static struct snd_soc_dai_link msm_int_dai[] = { SND_SOC_DPCM_TRIGGER_POST}, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, @@ -2367,7 +2357,6 @@ static struct snd_soc_dai_link msm_int_wsa_dai[] = { .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ignore_suspend = 1, .dpcm_capture = 1, - .ignore_pmdown_time = 1, }, }; @@ -2491,6 +2480,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_suspend = 1, + .ignore_pmdown_time = 1, }, /* Incall Music 2 BACK END DAI Link */ { @@ -2505,6 +2495,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_suspend = 1, + .ignore_pmdown_time = 1, }, { .name = LPASS_BE_USB_AUDIO_RX, @@ -2546,6 +2537,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, + .ignore_pmdown_time = 1, }, { .name = LPASS_BE_PRI_TDM_TX_0, @@ -2574,6 +2566,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, + .ignore_pmdown_time = 1, }, { .name = LPASS_BE_SEC_TDM_TX_0, @@ -2602,6 +2595,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, + .ignore_pmdown_time = 1, }, { .name = LPASS_BE_TERT_TDM_TX_0, @@ -2630,6 +2624,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, + .ignore_pmdown_time = 1, }, { .name = LPASS_BE_QUAT_TDM_TX_0, @@ -2658,6 +2653,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = { .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ops = &msm_tdm_be_ops, .ignore_suspend = 1, + .ignore_pmdown_time = 1, }, { .name = LPASS_BE_QUIN_TDM_TX_0, @@ -2851,7 +2847,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_pmdown_time = 1, .ignore_suspend = 1, .ops = &msm_aux_pcm_be_ops, }, @@ -2883,7 +2878,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .ops = &msm_aux_pcm_be_ops, }, /* Tertiary AUX PCM Backend DAI Links */ @@ -2914,7 +2908,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .ops = &msm_aux_pcm_be_ops, }, /* Quaternary AUX PCM Backend DAI Links */ @@ -2945,7 +2938,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .ops = &msm_aux_pcm_be_ops, }, /* Quinary AUX PCM Backend DAI Links */ @@ -2976,7 +2968,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX, .be_hw_params_fixup = msm_common_be_hw_params_fixup, .ignore_suspend = 1, - .ignore_pmdown_time = 1, .ops = &msm_aux_pcm_be_ops, }, }; -- GitLab From b68d1027647b95d50375f482ff27638405effc54 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 8 Jan 2018 19:14:41 +0530 Subject: [PATCH 0140/1645] ASoC: sdm670: fix clock refcount for MI2S shutdown For MI2S shutdown, if clock disable is failed, do not bother to re-increment clock reference. Otherwise, next time when startup is called, clock enable will not be called again, so use case will not work. CRs-Fixed: 2166356 Change-Id: Ic7a93a5f20eaabed93d0cd94d76d09f0f1c869fd Signed-off-by: Aditya Bavanari --- asoc/sdm660-common.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c index 449664287303..ccfe528487dd 100644 --- a/asoc/sdm660-common.c +++ b/asoc/sdm660-common.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2783,11 +2783,10 @@ void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) pdata->mi2s_gpio_p[index]); ret = msm_mi2s_set_sclk(substream, false); - if (ret < 0) { + if (ret < 0) pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", __func__, index, ret); - mi2s_intf_conf[index].ref_cnt++; - } + if (mi2s_intf_conf[index].msm_is_ext_mclk) { mi2s_mclk[index].enable = 0; pr_debug("%s: Disabling mclk, clk_freq_in_hz = %u\n", -- GitLab From 3c88f6143955db985e0b743a94056ac07d582a3f Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Fri, 17 Nov 2017 16:00:05 +0800 Subject: [PATCH 0141/1645] ASoC: update softlink for internal.h, core.h and pinctrl-utils.h update softlink for internal.h, core.h and pinctrl-utils.h for sdm855 Change-Id: I3e92e8da1ab1bbfce7fbb92c6997af22777925dc Signed-off-by: Meng Wang --- include/soc/internal.h | 2 +- soc/core.h | 2 +- soc/pinctrl-utils.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/soc/internal.h b/include/soc/internal.h index 452d9d2686bd..ad0a98dfc101 120000 --- a/include/soc/internal.h +++ b/include/soc/internal.h @@ -1 +1 @@ -../../../../../../kernel/msm-4.9/drivers/base/regmap/internal.h \ No newline at end of file +../../../../../../kernel/msm-4.14/drivers/base/regmap/internal.h \ No newline at end of file diff --git a/soc/core.h b/soc/core.h index 451c69610e0d..b9f94ca74f63 120000 --- a/soc/core.h +++ b/soc/core.h @@ -1 +1 @@ -../../../../../kernel/msm-4.9/drivers/pinctrl/core.h \ No newline at end of file +../../../../../kernel/msm-4.14/drivers/pinctrl/core.h \ No newline at end of file diff --git a/soc/pinctrl-utils.h b/soc/pinctrl-utils.h index 2ea9d23df537..0f74549b32c1 120000 --- a/soc/pinctrl-utils.h +++ b/soc/pinctrl-utils.h @@ -1 +1 @@ -../../../../../kernel/msm-4.9/drivers/pinctrl/pinctrl-utils.h \ No newline at end of file +../../../../../kernel/msm-4.14/drivers/pinctrl/pinctrl-utils.h \ No newline at end of file -- GitLab From 723548296feb9e416dc7ca561650e5dcbf9c9d45 Mon Sep 17 00:00:00 2001 From: Shiv Maliyappanahalli Date: Fri, 17 Nov 2017 16:07:27 -0800 Subject: [PATCH 0142/1645] ipc: Add support for apr over rpmsg Add support for apr communication over rpmsg to enable inter processor comuunication b/w APPS and ADSP for audio usecases. Change-Id: I834ded7f1dd709e1d9e835b852c2edc25e8607e0 Signed-off-by: Shiv Maliyappanahalli --- include/ipc/apr_tal.h | 3 +- ipc/Kbuild | 12 +- ipc/apr.c | 3 +- ipc/apr_tal_rpmsg.c | 303 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 313 insertions(+), 8 deletions(-) create mode 100644 ipc/apr_tal_rpmsg.c diff --git a/include/ipc/apr_tal.h b/include/ipc/apr_tal.h index aa53e217c714..534fd84d2ba8 100644 --- a/include/ipc/apr_tal.h +++ b/include/ipc/apr_tal.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2011, 2016-2017 The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2011, 2016-2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -74,6 +74,7 @@ int apr_tal_close(struct apr_svc_ch_dev *apr_ch); int apr_tal_rx_intents_config(struct apr_svc_ch_dev *apr_ch, int num_of_intents, uint32_t size); int apr_tal_init(void); +void apr_tal_exit(void); int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch); int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch); diff --git a/ipc/Kbuild b/ipc/Kbuild index 72c9ef1c25b0..8730156756a5 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -67,16 +67,16 @@ COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) ############ IPC ############ -ifdef CONFIG_MSM_QDSP6_APRV2_GLINK +ifdef CONFIG_MSM_QDSP6_APRV2_RPMSG APRV_GLINK += apr.o APRV_GLINK += apr_v2.o -APRV_GLINK += apr_tal_glink.o +APRV_GLINK += apr_tal_rpmsg.o endif -ifdef CONFIG_MSM_QDSP6_APRV3_GLINK +ifdef CONFIG_MSM_QDSP6_APRV3_RPMSG APRV_GLINK += apr.o APRV_GLINK += apr_v3.o -APRV_GLINK += apr_tal_glink.o +APRV_GLINK += apr_tal_rpmsg.o endif ifdef CONFIG_WCD_DSP_GLINK @@ -162,8 +162,8 @@ CDEFINES += -DMULTI_IF_NAME=\"$(CHIP_NAME)\" endif # Module information used by KBuild framework -obj-$(CONFIG_MSM_QDSP6_APRV2_GLINK) += apr_dlkm.o -obj-$(CONFIG_MSM_QDSP6_APRV3_GLINK) += apr_dlkm.o +obj-$(CONFIG_MSM_QDSP6_APRV2_RPMSG) += apr_dlkm.o +obj-$(CONFIG_MSM_QDSP6_APRV3_RPMSG) += apr_dlkm.o apr_dlkm-y := $(APRV_GLINK) obj-$(CONFIG_WCD_DSP_GLINK) += wglink_dlkm.o diff --git a/ipc/apr.c b/ipc/apr.c index 9f9cf915ab3d..331f057c4135 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2014, 2016-2017 The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2014, 2016-2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1133,6 +1133,7 @@ void __exit apr_exit(void) { subsys_notif_deregister("apr_modem"); subsys_notif_deregister("apr_adsp"); + apr_tal_exit(); } module_exit(apr_exit); MODULE_DESCRIPTION("APR module"); diff --git a/ipc/apr_tal_rpmsg.c b/ipc/apr_tal_rpmsg.c new file mode 100644 index 000000000000..aaadca486844 --- /dev/null +++ b/ipc/apr_tal_rpmsg.c @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +enum apr_channel_state { + APR_CH_DISCONNECTED, + APR_CH_CONNECTED, +}; + +#define APR_MAXIMUM_NUM_OF_RETRIES 2 + +static struct apr_svc_ch_dev + apr_svc_ch[APR_DL_MAX][APR_DEST_MAX][APR_CLIENT_MAX]; + +/** + * apr_tal_write() - Write a message across to the remote processor + * @apr_ch: apr channel handle + * @data: buffer that needs to be transferred over the channel + * @pkt_priv: private data of the packet + * @len: length of the buffer + * + * Returns len of buffer successfully transferred on success + * and an appropriate error value on failure. + */ +int apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data, + struct apr_pkt_priv *pkt_priv, int len) +{ + int rc = 0, retries = 0; + unsigned long flags; + struct rpmsg_device *rpdev = NULL; + + if (!apr_ch || len > APR_MAX_BUF || + apr_ch->channel_state != APR_CH_CONNECTED) + return -EINVAL; + + spin_lock_irqsave(&apr_ch->w_lock, flags); + rpdev = apr_ch->handle; + if (!rpdev) { + spin_unlock_irqrestore(&apr_ch->w_lock, flags); + return -EINVAL; + } + + do { + if (rc == -EAGAIN) + udelay(50); + rc = rpmsg_trysend(rpdev->ept, data, len); + } while (rc == -EAGAIN && retries++ < APR_MAXIMUM_NUM_OF_RETRIES); + spin_unlock_irqrestore(&apr_ch->w_lock, flags); + + if (rc) + pr_err("%s: Unable to send the packet, rc:%d\n", __func__, rc); + else + rc = len; + + return rc; +} +EXPORT_SYMBOL(apr_tal_write); + +/** + * apr_tal_rx_intents_config() - Configure glink intents for remote processor + * @apr_ch: apr channel handle + * @num_of_intents: number of intents + * @size: size of the intents + * + * This api is not supported with RPMSG. Returns 0 to indicate success + */ +int apr_tal_rx_intents_config(struct apr_svc_ch_dev *apr_ch, + int num_of_intents, uint32_t size) +{ + pr_debug("%s: NO-OP\n", __func__); + return 0; +} +EXPORT_SYMBOL(apr_tal_rx_intents_config); + +/** + * apr_tal_start_rx_rt() - Set RT thread priority for APR RX transfer + * @apr_ch: apr channel handle + * + * This api is not supported with RPMSG as message transfer occurs + * in client's context. Returns 0 to indicate success. + */ +int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch) +{ + pr_debug("%s: NO-OP\n", __func__); + return 0; +} +EXPORT_SYMBOL(apr_tal_start_rx_rt); + +/** + * apr_tal_end_rx_rt() - Remove RT thread priority for APR RX transfer + * @apr_ch: apr channel handle + * + * This api is not supported with RPMSG. Returns 0 to indicate success + */ +int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch) +{ + pr_debug("%s: NO-OP\n", __func__); + return 0; +} +EXPORT_SYMBOL(apr_tal_end_rx_rt); + +/** + * apr_tal_open() - Open a transport channel for data transfer + * on remote processor. + * @clnt: apr client, audio or voice + * @dest: destination remote processor for which apr channel is requested for. + * @dl: type of data link + * @func: callback function to handle data transfer from remote processor + * @priv: private data of the client + * + * Returns apr_svc_ch_dev handle on success and NULL on failure. + */ +struct apr_svc_ch_dev *apr_tal_open(uint32_t clnt, uint32_t dest, uint32_t dl, + apr_svc_cb_fn func, void *priv) +{ + int rc = 0; + struct apr_svc_ch_dev *apr_ch = NULL; + + if ((clnt != APR_CLIENT_AUDIO) || (dest != APR_DEST_QDSP6) || + (dl != APR_DL_SMD)) { + pr_err("%s: Invalid params, clnt:%d, dest:%d, dl:%d\n", + __func__, clnt, dest, dl); + return NULL; + } + + apr_ch = &apr_svc_ch[APR_DL_SMD][APR_DEST_QDSP6][APR_CLIENT_AUDIO]; + mutex_lock(&apr_ch->m_lock); + if (!apr_ch->handle) { + rc = wait_event_timeout(apr_ch->wait, + (apr_ch->channel_state == APR_CH_CONNECTED), 5 * HZ); + + if (rc == 0) { + pr_err("%s: TIMEOUT for APR_CH_CONNECTED event\n", + __func__); + rc = -ETIMEDOUT; + goto unlock; + } + } + + pr_debug("%s: Channel connected, returning handle :%pK\n", + __func__, apr_ch->handle); + apr_ch->func = func; + apr_ch->priv = priv; + +unlock: + mutex_unlock(&apr_ch->m_lock); + return rc ? NULL : apr_ch; +} +EXPORT_SYMBOL(apr_tal_open); + +/** + * apr_tal_close() - Close transport channel on remote processor. + * @apr_ch: apr channel handle + * + * Returns 0 on success and an appropriate error value on failure. + */ +int apr_tal_close(struct apr_svc_ch_dev *apr_ch) +{ + int rc = 0; + + if (!apr_ch || !apr_ch->handle) { + rc = -EINVAL; + goto exit; + } + + mutex_lock(&apr_ch->m_lock); + apr_ch->func = NULL; + apr_ch->priv = NULL; + mutex_unlock(&apr_ch->m_lock); + +exit: + return rc; +} +EXPORT_SYMBOL(apr_tal_close); + +static int apr_tal_rpmsg_callback(struct rpmsg_device *rpdev, + void *data, int len, void *priv, u32 addr) +{ + struct apr_svc_ch_dev *apr_ch = dev_get_drvdata(&rpdev->dev); + unsigned long flags; + + if (!apr_ch || !data) { + pr_err("%s: Invalid apr_ch or ptr\n", __func__); + return -EINVAL; + } + + dev_dbg(&rpdev->dev, "%s: Rx packet received, len:%d\n", + __func__, len); + + spin_lock_irqsave(&apr_ch->r_lock, flags); + if (apr_ch->func) + apr_ch->func((void *)data, len, apr_ch->priv); + spin_unlock_irqrestore(&apr_ch->r_lock, flags); + + return 0; +} + +static int apr_tal_rpmsg_probe(struct rpmsg_device *rpdev) +{ + struct apr_svc_ch_dev *apr_ch = NULL; + + if (!strcmp(rpdev->id.name, "apr_audio_svc")) { + dev_info(&rpdev->dev, "%s: Channel[%s] state[Up]\n", + __func__, rpdev->id.name); + + apr_ch = + &apr_svc_ch[APR_DL_SMD][APR_DEST_QDSP6][APR_CLIENT_AUDIO]; + apr_ch->handle = rpdev; + apr_ch->channel_state = APR_CH_CONNECTED; + dev_set_drvdata(&rpdev->dev, apr_ch); + wake_up(&apr_ch->wait); + } else { + dev_err(&rpdev->dev, "%s, Invalid Channel [%s]\n", + __func__, rpdev->id.name); + return -EINVAL; + } + + return 0; +} + +static void apr_tal_rpmsg_remove(struct rpmsg_device *rpdev) +{ + struct apr_svc_ch_dev *apr_ch = dev_get_drvdata(&rpdev->dev); + + if (!apr_ch) { + dev_err(&rpdev->dev, "%s: Invalid apr_ch\n", __func__); + return; + } + + dev_info(&rpdev->dev, "%s: Channel[%s] state[Down]\n", + __func__, rpdev->id.name); + apr_ch->handle = NULL; + apr_ch->channel_state = APR_CH_DISCONNECTED; + dev_set_drvdata(&rpdev->dev, NULL); +} + +static const struct rpmsg_device_id apr_tal_rpmsg_match[] = { + { "apr_audio_svc" }, + {} +}; + +static struct rpmsg_driver apr_tal_rpmsg_driver = { + .probe = apr_tal_rpmsg_probe, + .remove = apr_tal_rpmsg_remove, + .callback = apr_tal_rpmsg_callback, + .id_table = apr_tal_rpmsg_match, + .drv = { + .name = "apr_tal_rpmsg", + }, +}; + +/** + * apr_tal_int() - Registers rpmsg driver with rpmsg framework. + * + * Returns 0 on success and an appropriate error value on failure. + */ +int apr_tal_init(void) +{ + int i, j, k; + int ret; + + memset(apr_svc_ch, 0, sizeof(struct apr_svc_ch_dev)); + for (i = 0; i < APR_DL_MAX; i++) { + for (j = 0; j < APR_DEST_MAX; j++) { + for (k = 0; k < APR_CLIENT_MAX; k++) { + init_waitqueue_head(&apr_svc_ch[i][j][k].wait); + spin_lock_init(&apr_svc_ch[i][j][k].w_lock); + spin_lock_init(&apr_svc_ch[i][j][k].r_lock); + mutex_init(&apr_svc_ch[i][j][k].m_lock); + } + } + } + ret = register_rpmsg_driver(&apr_tal_rpmsg_driver); + return ret; +} +EXPORT_SYMBOL(apr_tal_init); + +/** + * apr_tal_exit() - De-register rpmsg driver with rpmsg framework. + */ +void apr_tal_exit(void) +{ + unregister_rpmsg_driver(&apr_tal_rpmsg_driver); +} +EXPORT_SYMBOL(apr_tal_exit); + -- GitLab From 9bc15323067ba23cb6d45f1c626609be8f9e2fdc Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 29 Jan 2018 17:45:51 +0800 Subject: [PATCH 0143/1645] ASoC: uapi: Export the audio header file to userspace Audio driver requires that exported header files should be placed in uapi folder. Change adds the audio header files to uapi folder. Change-Id: Ifb47492507a482b1b2f5caa00af4268e08e64803 Signed-off-by: Meng Wang --- include/uapi/linux/Kbuild | 1 + include/uapi/linux/mfd/Kbuild | 1 + include/uapi/linux/mfd/wcd9xxx/Kbuild | 2 + .../linux/mfd/wcd9xxx/wcd9320_registers.h | 1399 +++++++++++++++++ .../linux/mfd/wcd9xxx/wcd9xxx_registers.h | 361 +++++ 5 files changed, 1764 insertions(+) create mode 100644 include/uapi/linux/mfd/Kbuild create mode 100644 include/uapi/linux/mfd/wcd9xxx/Kbuild create mode 100644 include/uapi/linux/mfd/wcd9xxx/wcd9320_registers.h create mode 100644 include/uapi/linux/mfd/wcd9xxx/wcd9xxx_registers.h diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 7647f052b7f4..f6af2bf8cca3 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -17,3 +17,4 @@ header-y += msm_audio_alac.h header-y += msm_audio_ape.h header-y += msm_audio_g711.h header-y += msm_audio_g711_dec.h +header-y += mfd/ diff --git a/include/uapi/linux/mfd/Kbuild b/include/uapi/linux/mfd/Kbuild new file mode 100644 index 000000000000..9377c98b0aa3 --- /dev/null +++ b/include/uapi/linux/mfd/Kbuild @@ -0,0 +1 @@ +header-y += wcd9xxx/ diff --git a/include/uapi/linux/mfd/wcd9xxx/Kbuild b/include/uapi/linux/mfd/wcd9xxx/Kbuild new file mode 100644 index 000000000000..8e55965bbe7e --- /dev/null +++ b/include/uapi/linux/mfd/wcd9xxx/Kbuild @@ -0,0 +1,2 @@ +header-y += wcd9xxx_registers.h +header-y += wcd9320_registers.h diff --git a/include/uapi/linux/mfd/wcd9xxx/wcd9320_registers.h b/include/uapi/linux/mfd/wcd9xxx/wcd9320_registers.h new file mode 100644 index 000000000000..63ab62419559 --- /dev/null +++ b/include/uapi/linux/mfd/wcd9xxx/wcd9320_registers.h @@ -0,0 +1,1399 @@ +#ifndef WCD9320_REGISTERS_H +#define WCD9320_REGISTERS_H + +#include + +#define TAIKO_A_CHIP_CTL WCD9XXX_A_CHIP_CTL +#define TAIKO_A_CHIP_CTL__POR WCD9XXX_A_CHIP_CTL__POR +#define TAIKO_A_CHIP_STATUS WCD9XXX_A_CHIP_STATUS +#define TAIKO_A_CHIP_STATUS__POR WCD9XXX_A_CHIP_STATUS__POR +#define TAIKO_A_CHIP_ID_BYTE_0 WCD9XXX_A_CHIP_ID_BYTE_0 +#define TAIKO_A_CHIP_ID_BYTE_0__POR WCD9XXX_A_CHIP_ID_BYTE_0__POR +#define TAIKO_A_CHIP_ID_BYTE_1 WCD9XXX_A_CHIP_ID_BYTE_1 +#define TAIKO_A_CHIP_ID_BYTE_1__POR WCD9XXX_A_CHIP_ID_BYTE_1__POR +#define TAIKO_A_CHIP_ID_BYTE_2 WCD9XXX_A_CHIP_ID_BYTE_2 +#define TAIKO_A_CHIP_ID_BYTE_2__POR WCD9XXX_A_CHIP_ID_BYTE_2__POR +#define TAIKO_A_CHIP_ID_BYTE_3 WCD9XXX_A_CHIP_ID_BYTE_3 +#define TAIKO_A_CHIP_ID_BYTE_3__POR WCD9XXX_A_CHIP_ID_BYTE_3__POR +#define TAIKO_A_CHIP_VERSION WCD9XXX_A_CHIP_VERSION +#define TAIKO_A_CHIP_VERSION__POR WCD9XXX_A_CHIP_VERSION__POR +#define TAIKO_A_SB_VERSION WCD9XXX_A_SB_VERSION +#define TAIKO_A_SB_VERSION__POR WCD9XXX_A_SB_VERSION__POR +#define TAIKO_A_SLAVE_ID_1 WCD9XXX_A_SLAVE_ID_1 +#define TAIKO_A_SLAVE_ID_1__POR WCD9XXX_A_SLAVE_ID_1__POR +#define TAIKO_A_SLAVE_ID_2 WCD9XXX_A_SLAVE_ID_2 +#define TAIKO_A_SLAVE_ID_2__POR WCD9XXX_A_SLAVE_ID_2__POR +#define TAIKO_A_SLAVE_ID_3 WCD9XXX_A_SLAVE_ID_3 +#define TAIKO_A_SLAVE_ID_3__POR WCD9XXX_A_SLAVE_ID_3__POR +#define TAIKO_A_PIN_CTL_OE0 (0x010) +#define TAIKO_A_PIN_CTL_OE0__POR (0x00) +#define TAIKO_A_PIN_CTL_OE1 (0x011) +#define TAIKO_A_PIN_CTL_OE1__POR (0x00) +#define TAIKO_A_PIN_CTL_DATA0 (0x012) +#define TAIKO_A_PIN_CTL_DATA0__POR (0x00) +#define TAIKO_A_PIN_CTL_DATA1 (0x013) +#define TAIKO_A_PIN_CTL_DATA1__POR (0x00) +#define TAIKO_A_HDRIVE_GENERIC (0x018) +#define TAIKO_A_HDRIVE_GENERIC__POR (0x00) +#define TAIKO_A_HDRIVE_OVERRIDE (0x019) +#define TAIKO_A_HDRIVE_OVERRIDE__POR (0x08) +#define TAIKO_A_ANA_CSR_WAIT_STATE (0x020) +#define TAIKO_A_ANA_CSR_WAIT_STATE__POR (0x44) +#define TAIKO_A_PROCESS_MONITOR_CTL0 (0x040) +#define TAIKO_A_PROCESS_MONITOR_CTL0__POR (0x80) +#define TAIKO_A_PROCESS_MONITOR_CTL1 (0x041) +#define TAIKO_A_PROCESS_MONITOR_CTL1__POR (0x00) +#define TAIKO_A_PROCESS_MONITOR_CTL2 (0x042) +#define TAIKO_A_PROCESS_MONITOR_CTL2__POR (0x00) +#define TAIKO_A_PROCESS_MONITOR_CTL3 (0x043) +#define TAIKO_A_PROCESS_MONITOR_CTL3__POR (0x01) +#define TAIKO_A_QFUSE_CTL (0x048) +#define TAIKO_A_QFUSE_CTL__POR (0x00) +#define TAIKO_A_QFUSE_STATUS (0x049) +#define TAIKO_A_QFUSE_STATUS__POR (0x00) +#define TAIKO_A_QFUSE_DATA_OUT0 (0x04A) +#define TAIKO_A_QFUSE_DATA_OUT0__POR (0x00) +#define TAIKO_A_QFUSE_DATA_OUT1 (0x04B) +#define TAIKO_A_QFUSE_DATA_OUT1__POR (0x00) +#define TAIKO_A_QFUSE_DATA_OUT2 (0x04C) +#define TAIKO_A_QFUSE_DATA_OUT2__POR (0x00) +#define TAIKO_A_QFUSE_DATA_OUT3 (0x04D) +#define TAIKO_A_QFUSE_DATA_OUT3__POR (0x00) +#define TAIKO_A_QFUSE_DATA_OUT4 (0x04E) +#define TAIKO_A_QFUSE_DATA_OUT4__POR (0x00) +#define TAIKO_A_QFUSE_DATA_OUT5 (0x04F) +#define TAIKO_A_QFUSE_DATA_OUT5__POR (0x00) +#define TAIKO_A_QFUSE_DATA_OUT6 (0x050) +#define TAIKO_A_QFUSE_DATA_OUT6__POR (0x00) +#define TAIKO_A_QFUSE_DATA_OUT7 (0x051) +#define TAIKO_A_QFUSE_DATA_OUT7__POR (0x00) +#define TAIKO_A_CDC_CTL WCD9XXX_A_CDC_CTL +#define TAIKO_A_CDC_CTL__POR WCD9XXX_A_CDC_CTL__POR +#define TAIKO_A_LEAKAGE_CTL WCD9XXX_A_LEAKAGE_CTL +#define TAIKO_A_LEAKAGE_CTL__POR WCD9XXX_A_LEAKAGE_CTL__POR +#define TAIKO_A_INTR_MODE (0x090) +#define TAIKO_A_INTR_MODE__POR (0x00) +#define TAIKO_A_INTR_MASK0 (0x094) +#define TAIKO_A_INTR_MASK0__POR (0xFF) +#define TAIKO_A_INTR_MASK1 (0x095) +#define TAIKO_A_INTR_MASK1__POR (0xFF) +#define TAIKO_A_INTR_MASK2 (0x096) +#define TAIKO_A_INTR_MASK2__POR (0x3F) +#define TAIKO_A_INTR_MASK3 (0x097) +#define TAIKO_A_INTR_MASK3__POR (0x3F) +#define TAIKO_A_INTR_STATUS0 (0x098) +#define TAIKO_A_INTR_STATUS0__POR (0x00) +#define TAIKO_A_INTR_STATUS1 (0x099) +#define TAIKO_A_INTR_STATUS1__POR (0x00) +#define TAIKO_A_INTR_STATUS2 (0x09A) +#define TAIKO_A_INTR_STATUS2__POR (0x00) +#define TAIKO_A_INTR_STATUS3 (0x09B) +#define TAIKO_A_INTR_STATUS3__POR (0x00) +#define TAIKO_A_INTR_CLEAR0 (0x09C) +#define TAIKO_A_INTR_CLEAR0__POR (0x00) +#define TAIKO_A_INTR_CLEAR1 (0x09D) +#define TAIKO_A_INTR_CLEAR1__POR (0x00) +#define TAIKO_A_INTR_CLEAR2 (0x09E) +#define TAIKO_A_INTR_CLEAR2__POR (0x00) +#define TAIKO_A_INTR_CLEAR3 (0x09F) +#define TAIKO_A_INTR_CLEAR3__POR (0x00) +#define TAIKO_A_INTR_LEVEL0 (0x0A0) +#define TAIKO_A_INTR_LEVEL0__POR (0x01) +#define TAIKO_A_INTR_LEVEL1 (0x0A1) +#define TAIKO_A_INTR_LEVEL1__POR (0x00) +#define TAIKO_A_INTR_LEVEL2 (0x0A2) +#define TAIKO_A_INTR_LEVEL2__POR (0x00) +#define TAIKO_A_INTR_LEVEL3 (0x0A3) +#define TAIKO_A_INTR_LEVEL3__POR (0x00) +#define TAIKO_A_INTR_TEST0 (0x0A4) +#define TAIKO_A_INTR_TEST0__POR (0x00) +#define TAIKO_A_INTR_TEST1 (0x0A5) +#define TAIKO_A_INTR_TEST1__POR (0x00) +#define TAIKO_A_INTR_TEST2 (0x0A6) +#define TAIKO_A_INTR_TEST2__POR (0x00) +#define TAIKO_A_INTR_TEST3 (0x0A7) +#define TAIKO_A_INTR_TEST3__POR (0x00) +#define TAIKO_A_INTR_SET0 (0x0A8) +#define TAIKO_A_INTR_SET0__POR (0x00) +#define TAIKO_A_INTR_SET1 (0x0A9) +#define TAIKO_A_INTR_SET1__POR (0x00) +#define TAIKO_A_INTR_SET2 (0x0AA) +#define TAIKO_A_INTR_SET2__POR (0x00) +#define TAIKO_A_INTR_SET3 (0x0AB) +#define TAIKO_A_INTR_SET3__POR (0x00) +#define TAIKO_A_INTR_DESTN0 (0x0AC) +#define TAIKO_A_INTR_DESTN0__POR (0x00) +#define TAIKO_A_INTR_DESTN1 (0x0AD) +#define TAIKO_A_INTR_DESTN1__POR (0x00) +#define TAIKO_A_INTR_DESTN2 (0x0AE) +#define TAIKO_A_INTR_DESTN2__POR (0x00) +#define TAIKO_A_INTR_DESTN3 (0x0AF) +#define TAIKO_A_INTR_DESTN3__POR (0x00) +#define TAIKO_A_CDC_TX_I2S_SCK_MODE (0x0C0) +#define TAIKO_A_CDC_TX_I2S_SCK_MODE__POR (0x00) +#define TAIKO_A_CDC_TX_I2S_WS_MODE (0x0C1) +#define TAIKO_A_CDC_TX_I2S_WS_MODE__POR (0x00) +#define TAIKO_A_CDC_DMIC_DATA0_MODE (0x0C4) +#define TAIKO_A_CDC_DMIC_DATA0_MODE__POR (0x00) +#define TAIKO_A_CDC_DMIC_CLK0_MODE (0x0C5) +#define TAIKO_A_CDC_DMIC_CLK0_MODE__POR (0x00) +#define TAIKO_A_CDC_DMIC_DATA1_MODE (0x0C6) +#define TAIKO_A_CDC_DMIC_DATA1_MODE__POR (0x00) +#define TAIKO_A_CDC_DMIC_CLK1_MODE (0x0C7) +#define TAIKO_A_CDC_DMIC_CLK1_MODE__POR (0x00) +#define TAIKO_A_CDC_RX_I2S_SCK_MODE (0x0C8) +#define TAIKO_A_CDC_RX_I2S_SCK_MODE__POR (0x00) +#define TAIKO_A_CDC_RX_I2S_WS_MODE (0x0C9) +#define TAIKO_A_CDC_RX_I2S_WS_MODE__POR (0x00) +#define TAIKO_A_CDC_DMIC_DATA2_MODE (0x0CA) +#define TAIKO_A_CDC_DMIC_DATA2_MODE__POR (0x00) +#define TAIKO_A_CDC_DMIC_CLK2_MODE (0x0CB) +#define TAIKO_A_CDC_DMIC_CLK2_MODE__POR (0x00) +#define TAIKO_A_CDC_INTR1_MODE (0x0CC) +#define TAIKO_A_CDC_INTR1_MODE__POR (0x00) +#define TAIKO_A_CDC_SB_NRZ_SEL_MODE (0x0CD) +#define TAIKO_A_CDC_SB_NRZ_SEL_MODE__POR (0x00) +#define TAIKO_A_CDC_INTR2_MODE (0x0CE) +#define TAIKO_A_CDC_INTR2_MODE__POR (0x00) +#define TAIKO_A_CDC_RF_PA_ON_MODE (0x0CF) +#define TAIKO_A_CDC_RF_PA_ON_MODE__POR (0x00) +#define TAIKO_A_BIAS_REF_CTL (0x100) +#define TAIKO_A_BIAS_REF_CTL__POR (0x1C) +#define TAIKO_A_BIAS_CENTRAL_BG_CTL (0x101) +#define TAIKO_A_BIAS_CENTRAL_BG_CTL__POR (0x50) +#define TAIKO_A_BIAS_PRECHRG_CTL (0x102) +#define TAIKO_A_BIAS_PRECHRG_CTL__POR (0x07) +#define TAIKO_A_BIAS_CURR_CTL_1 (0x103) +#define TAIKO_A_BIAS_CURR_CTL_1__POR (0x52) +#define TAIKO_A_BIAS_CURR_CTL_2 (0x104) +#define TAIKO_A_BIAS_CURR_CTL_2__POR (0x00) +#define TAIKO_A_BIAS_OSC_BG_CTL (0x105) +#define TAIKO_A_BIAS_OSC_BG_CTL__POR (0x16) +#define TAIKO_A_CLK_BUFF_EN1 (0x108) +#define TAIKO_A_CLK_BUFF_EN1__POR (0x04) +#define TAIKO_A_CLK_BUFF_EN2 (0x109) +#define TAIKO_A_CLK_BUFF_EN2__POR (0x02) +#define TAIKO_A_LDO_H_MODE_1 (0x110) +#define TAIKO_A_LDO_H_MODE_1__POR (0x65) +#define TAIKO_A_LDO_H_MODE_2 (0x111) +#define TAIKO_A_LDO_H_MODE_2__POR (0xA8) +#define TAIKO_A_LDO_H_LOOP_CTL (0x112) +#define TAIKO_A_LDO_H_LOOP_CTL__POR (0x6B) +#define TAIKO_A_LDO_H_COMP_1 (0x113) +#define TAIKO_A_LDO_H_COMP_1__POR (0x84) +#define TAIKO_A_LDO_H_COMP_2 (0x114) +#define TAIKO_A_LDO_H_COMP_2__POR (0xE0) +#define TAIKO_A_LDO_H_BIAS_1 (0x115) +#define TAIKO_A_LDO_H_BIAS_1__POR (0x6D) +#define TAIKO_A_LDO_H_BIAS_2 (0x116) +#define TAIKO_A_LDO_H_BIAS_2__POR (0xA5) +#define TAIKO_A_LDO_H_BIAS_3 (0x117) +#define TAIKO_A_LDO_H_BIAS_3__POR (0x60) +#define TAIKO_A_VBAT_CLK (0x118) +#define TAIKO_A_VBAT_CLK__POR (0x03) +#define TAIKO_A_VBAT_LOOP (0x119) +#define TAIKO_A_VBAT_LOOP__POR (0x02) +#define TAIKO_A_VBAT_REF (0x11A) +#define TAIKO_A_VBAT_REF__POR (0x20) +#define TAIKO_A_VBAT_ADC_TEST (0x11B) +#define TAIKO_A_VBAT_ADC_TEST__POR (0x00) +#define TAIKO_A_VBAT_FE (0x11C) +#define TAIKO_A_VBAT_FE__POR (0x48) +#define TAIKO_A_VBAT_BIAS_1 (0x11D) +#define TAIKO_A_VBAT_BIAS_1__POR (0x03) +#define TAIKO_A_VBAT_BIAS_2 (0x11E) +#define TAIKO_A_VBAT_BIAS_2__POR (0x00) +#define TAIKO_A_VBAT_ADC_DATA_MSB (0x11F) +#define TAIKO_A_VBAT_ADC_DATA_MSB__POR (0x00) +#define TAIKO_A_VBAT_ADC_DATA_LSB (0x120) +#define TAIKO_A_VBAT_ADC_DATA_LSB__POR (0x00) +#define TAIKO_A_MICB_CFILT_1_CTL (0x128) +#define TAIKO_A_MICB_CFILT_1_CTL__POR (0x40) +#define TAIKO_A_MICB_CFILT_1_VAL (0x129) +#define TAIKO_A_MICB_CFILT_1_VAL__POR (0x80) +#define TAIKO_A_MICB_CFILT_1_PRECHRG (0x12A) +#define TAIKO_A_MICB_CFILT_1_PRECHRG__POR (0x38) +#define TAIKO_A_MICB_1_CTL (0x12B) +#define TAIKO_A_MICB_1_CTL__POR (0x16) +#define TAIKO_A_MICB_1_INT_RBIAS (0x12C) +#define TAIKO_A_MICB_1_INT_RBIAS__POR (0x24) +#define TAIKO_A_MICB_1_MBHC (0x12D) +#define TAIKO_A_MICB_1_MBHC__POR (0x01) +#define TAIKO_A_MICB_CFILT_2_CTL (0x12E) +#define TAIKO_A_MICB_CFILT_2_CTL__POR (0x40) +#define TAIKO_A_MICB_CFILT_2_VAL (0x12F) +#define TAIKO_A_MICB_CFILT_2_VAL__POR (0x80) +#define TAIKO_A_MICB_CFILT_2_PRECHRG (0x130) +#define TAIKO_A_MICB_CFILT_2_PRECHRG__POR (0x38) +#define TAIKO_A_MICB_2_CTL (0x131) +#define TAIKO_A_MICB_2_CTL__POR (0x16) +#define TAIKO_A_MICB_2_INT_RBIAS (0x132) +#define TAIKO_A_MICB_2_INT_RBIAS__POR (0x24) +#define TAIKO_A_MICB_2_MBHC (0x133) +#define TAIKO_A_MICB_2_MBHC__POR (0x02) +#define TAIKO_A_MICB_CFILT_3_CTL (0x134) +#define TAIKO_A_MICB_CFILT_3_CTL__POR (0x40) +#define TAIKO_A_MICB_CFILT_3_VAL (0x135) +#define TAIKO_A_MICB_CFILT_3_VAL__POR (0x80) +#define TAIKO_A_MICB_CFILT_3_PRECHRG (0x136) +#define TAIKO_A_MICB_CFILT_3_PRECHRG__POR (0x38) +#define TAIKO_A_MICB_3_CTL (0x137) +#define TAIKO_A_MICB_3_CTL__POR (0x16) +#define TAIKO_A_MICB_3_INT_RBIAS (0x138) +#define TAIKO_A_MICB_3_INT_RBIAS__POR (0x24) +#define TAIKO_A_MICB_3_MBHC (0x139) +#define TAIKO_A_MICB_3_MBHC__POR (0x00) +#define TAIKO_A_MICB_4_CTL (0x13D) +#define TAIKO_A_MICB_4_CTL__POR (0x16) +#define TAIKO_A_MICB_4_INT_RBIAS (0x13E) +#define TAIKO_A_MICB_4_INT_RBIAS__POR (0x24) +#define TAIKO_A_MICB_4_MBHC (0x13F) +#define TAIKO_A_MICB_4_MBHC__POR (0x01) +#define TAIKO_A_MBHC_INSERT_DETECT (0x14A) +#define TAIKO_A_MBHC_INSERT_DETECT__POR (0x00) +#define TAIKO_A_MBHC_INSERT_DET_STATUS (0x14B) +#define TAIKO_A_MBHC_INSERT_DET_STATUS__POR (0x00) +#define TAIKO_A_TX_COM_BIAS (0x14C) +#define TAIKO_A_TX_COM_BIAS__POR (0xF0) +#define TAIKO_A_MBHC_SCALING_MUX_1 (0x14E) +#define TAIKO_A_MBHC_SCALING_MUX_1__POR (0x00) +#define TAIKO_A_MBHC_SCALING_MUX_2 (0x14F) +#define TAIKO_A_MBHC_SCALING_MUX_2__POR (0x80) +#define TAIKO_A_MAD_ANA_CTRL (0x150) +#define TAIKO_A_MAD_ANA_CTRL__POR (0xF1) +#define TAIKO_A_TX_SUP_SWITCH_CTRL_1 (0x151) +#define TAIKO_A_TX_SUP_SWITCH_CTRL_1__POR (0x00) +#define TAIKO_A_TX_SUP_SWITCH_CTRL_2 (0x152) +#define TAIKO_A_TX_SUP_SWITCH_CTRL_2__POR (0x80) +#define TAIKO_A_TX_1_2_EN (0x153) +#define TAIKO_A_TX_1_2_EN__POR (0x00) +#define TAIKO_A_TX_1_2_TEST_EN (0x154) +#define TAIKO_A_TX_1_2_TEST_EN__POR (0xCC) +#define TAIKO_A_TX_1_2_ADC_CH1 (0x155) +#define TAIKO_A_TX_1_2_ADC_CH1__POR (0x44) +#define TAIKO_A_TX_1_2_ADC_CH2 (0x156) +#define TAIKO_A_TX_1_2_ADC_CH2__POR (0x44) +#define TAIKO_A_TX_1_2_ATEST_REFCTRL (0x157) +#define TAIKO_A_TX_1_2_ATEST_REFCTRL__POR (0x00) +#define TAIKO_A_TX_1_2_TEST_CTL (0x158) +#define TAIKO_A_TX_1_2_TEST_CTL__POR (0x38) +#define TAIKO_A_TX_1_2_TEST_BLOCK_EN (0x159) +#define TAIKO_A_TX_1_2_TEST_BLOCK_EN__POR (0xFC) +#define TAIKO_A_TX_1_2_TXFE_CLKDIV (0x15A) +#define TAIKO_A_TX_1_2_TXFE_CLKDIV__POR (0x55) +#define TAIKO_A_TX_1_2_SAR_ERR_CH1 (0x15B) +#define TAIKO_A_TX_1_2_SAR_ERR_CH1__POR (0x00) +#define TAIKO_A_TX_1_2_SAR_ERR_CH2 (0x15C) +#define TAIKO_A_TX_1_2_SAR_ERR_CH2__POR (0x00) +#define TAIKO_A_TX_3_4_EN (0x15D) +#define TAIKO_A_TX_3_4_EN__POR (0x00) +#define TAIKO_A_TX_3_4_TEST_EN (0x15E) +#define TAIKO_A_TX_3_4_TEST_EN__POR (0xCC) +#define TAIKO_A_TX_3_4_ADC_CH3 (0x15F) +#define TAIKO_A_TX_3_4_ADC_CH3__POR (0x44) +#define TAIKO_A_TX_3_4_ADC_CH4 (0x160) +#define TAIKO_A_TX_3_4_ADC_CH4__POR (0x44) +#define TAIKO_A_TX_3_4_ATEST_REFCTRL (0x161) +#define TAIKO_A_TX_3_4_ATEST_REFCTRL__POR (0x00) +#define TAIKO_A_TX_3_4_TEST_CTL (0x162) +#define TAIKO_A_TX_3_4_TEST_CTL__POR (0x38) +#define TAIKO_A_TX_3_4_TEST_BLOCK_EN (0x163) +#define TAIKO_A_TX_3_4_TEST_BLOCK_EN__POR (0xFC) +#define TAIKO_A_TX_3_4_TXFE_CKDIV (0x164) +#define TAIKO_A_TX_3_4_TXFE_CKDIV__POR (0x55) +#define TAIKO_A_TX_3_4_SAR_ERR_CH3 (0x165) +#define TAIKO_A_TX_3_4_SAR_ERR_CH3__POR (0x00) +#define TAIKO_A_TX_3_4_SAR_ERR_CH4 (0x166) +#define TAIKO_A_TX_3_4_SAR_ERR_CH4__POR (0x00) +#define TAIKO_A_TX_5_6_EN (0x167) +#define TAIKO_A_TX_5_6_EN__POR (0x11) +#define TAIKO_A_TX_5_6_TEST_EN (0x168) +#define TAIKO_A_TX_5_6_TEST_EN__POR (0xCC) +#define TAIKO_A_TX_5_6_ADC_CH5 (0x169) +#define TAIKO_A_TX_5_6_ADC_CH5__POR (0x44) +#define TAIKO_A_TX_5_6_ADC_CH6 (0x16A) +#define TAIKO_A_TX_5_6_ADC_CH6__POR (0x44) +#define TAIKO_A_TX_5_6_ATEST_REFCTRL (0x16B) +#define TAIKO_A_TX_5_6_ATEST_REFCTRL__POR (0x00) +#define TAIKO_A_TX_5_6_TEST_CTL (0x16C) +#define TAIKO_A_TX_5_6_TEST_CTL__POR (0x38) +#define TAIKO_A_TX_5_6_TEST_BLOCK_EN (0x16D) +#define TAIKO_A_TX_5_6_TEST_BLOCK_EN__POR (0xFC) +#define TAIKO_A_TX_5_6_TXFE_CKDIV (0x16E) +#define TAIKO_A_TX_5_6_TXFE_CKDIV__POR (0x55) +#define TAIKO_A_TX_5_6_SAR_ERR_CH5 (0x16F) +#define TAIKO_A_TX_5_6_SAR_ERR_CH5__POR (0x00) +#define TAIKO_A_TX_5_6_SAR_ERR_CH6 (0x170) +#define TAIKO_A_TX_5_6_SAR_ERR_CH6__POR (0x00) +#define TAIKO_A_TX_7_MBHC_EN (0x171) +#define TAIKO_A_TX_7_MBHC_EN__POR (0x0C) +#define TAIKO_A_TX_7_MBHC_ATEST_REFCTRL (0x172) +#define TAIKO_A_TX_7_MBHC_ATEST_REFCTRL__POR (0x00) +#define TAIKO_A_TX_7_MBHC_ADC (0x173) +#define TAIKO_A_TX_7_MBHC_ADC__POR (0x44) +#define TAIKO_A_TX_7_MBHC_TEST_CTL (0x174) +#define TAIKO_A_TX_7_MBHC_TEST_CTL__POR (0x38) +#define TAIKO_A_TX_7_MBHC_SAR_ERR (0x175) +#define TAIKO_A_TX_7_MBHC_SAR_ERR__POR (0x00) +#define TAIKO_A_TX_7_TXFE_CLKDIV (0x176) +#define TAIKO_A_TX_7_TXFE_CLKDIV__POR (0x0B) +#define TAIKO_A_BUCK_MODE_1 (0x181) +#define TAIKO_A_BUCK_MODE_1__POR (0x21) +#define TAIKO_A_BUCK_MODE_2 (0x182) +#define TAIKO_A_BUCK_MODE_2__POR (0xFF) +#define TAIKO_A_BUCK_MODE_3 (0x183) +#define TAIKO_A_BUCK_MODE_3__POR (0xCC) +#define TAIKO_A_BUCK_MODE_4 (0x184) +#define TAIKO_A_BUCK_MODE_4__POR (0x3A) +#define TAIKO_A_BUCK_MODE_5 (0x185) +#define TAIKO_A_BUCK_MODE_5__POR (0x00) +#define TAIKO_A_BUCK_CTRL_VCL_1 (0x186) +#define TAIKO_A_BUCK_CTRL_VCL_1__POR (0x48) +#define TAIKO_A_BUCK_CTRL_VCL_2 (0x187) +#define TAIKO_A_BUCK_CTRL_VCL_2__POR (0xA3) +#define TAIKO_A_BUCK_CTRL_VCL_3 (0x188) +#define TAIKO_A_BUCK_CTRL_VCL_3__POR (0x82) +#define TAIKO_A_BUCK_CTRL_CCL_1 (0x189) +#define TAIKO_A_BUCK_CTRL_CCL_1__POR (0xAB) +#define TAIKO_A_BUCK_CTRL_CCL_2 (0x18A) +#define TAIKO_A_BUCK_CTRL_CCL_2__POR (0xDC) +#define TAIKO_A_BUCK_CTRL_CCL_3 (0x18B) +#define TAIKO_A_BUCK_CTRL_CCL_3__POR (0x6A) +#define TAIKO_A_BUCK_CTRL_CCL_4 (0x18C) +#define TAIKO_A_BUCK_CTRL_CCL_4__POR (0x58) +#define TAIKO_A_BUCK_CTRL_PWM_DRVR_1 (0x18D) +#define TAIKO_A_BUCK_CTRL_PWM_DRVR_1__POR (0x50) +#define TAIKO_A_BUCK_CTRL_PWM_DRVR_2 (0x18E) +#define TAIKO_A_BUCK_CTRL_PWM_DRVR_2__POR (0x64) +#define TAIKO_A_BUCK_CTRL_PWM_DRVR_3 (0x18F) +#define TAIKO_A_BUCK_CTRL_PWM_DRVR_3__POR (0x77) +#define TAIKO_A_BUCK_TMUX_A_D (0x190) +#define TAIKO_A_BUCK_TMUX_A_D__POR (0x00) +#define TAIKO_A_NCP_BUCKREF (0x191) +#define TAIKO_A_NCP_BUCKREF__POR (0x00) +#define TAIKO_A_NCP_EN (0x192) +#define TAIKO_A_NCP_EN__POR (0xFE) +#define TAIKO_A_NCP_CLK (0x193) +#define TAIKO_A_NCP_CLK__POR (0x94) +#define TAIKO_A_NCP_STATIC (0x194) +#define TAIKO_A_NCP_STATIC__POR (0x28) +#define TAIKO_A_NCP_VTH_LOW (0x195) +#define TAIKO_A_NCP_VTH_LOW__POR (0x88) +#define TAIKO_A_NCP_VTH_HIGH (0x196) +#define TAIKO_A_NCP_VTH_HIGH__POR (0xA0) +#define TAIKO_A_NCP_ATEST (0x197) +#define TAIKO_A_NCP_ATEST__POR (0x00) +#define TAIKO_A_NCP_DTEST (0x198) +#define TAIKO_A_NCP_DTEST__POR (0x00) +#define TAIKO_A_NCP_DLY1 (0x199) +#define TAIKO_A_NCP_DLY1__POR (0x06) +#define TAIKO_A_NCP_DLY2 (0x19A) +#define TAIKO_A_NCP_DLY2__POR (0x06) +#define TAIKO_A_RX_AUX_SW_CTL (0x19B) +#define TAIKO_A_RX_AUX_SW_CTL__POR (0x00) +#define TAIKO_A_RX_PA_AUX_IN_CONN (0x19C) +#define TAIKO_A_RX_PA_AUX_IN_CONN__POR (0x00) +#define TAIKO_A_RX_COM_TIMER_DIV (0x19E) +#define TAIKO_A_RX_COM_TIMER_DIV__POR (0xE8) +#define TAIKO_A_RX_COM_OCP_CTL (0x19F) +#define TAIKO_A_RX_COM_OCP_CTL__POR (0x1F) +#define TAIKO_A_RX_COM_OCP_COUNT (0x1A0) +#define TAIKO_A_RX_COM_OCP_COUNT__POR (0x77) +#define TAIKO_A_RX_COM_DAC_CTL (0x1A1) +#define TAIKO_A_RX_COM_DAC_CTL__POR (0x00) +#define TAIKO_A_RX_COM_BIAS (0x1A2) +#define TAIKO_A_RX_COM_BIAS__POR (0x00) +#define TAIKO_A_RX_HPH_AUTO_CHOP (0x1A4) +#define TAIKO_A_RX_HPH_AUTO_CHOP__POR (0x38) +#define TAIKO_A_RX_HPH_CHOP_CTL (0x1A5) +#define TAIKO_A_RX_HPH_CHOP_CTL__POR (0xB4) +#define TAIKO_A_RX_HPH_BIAS_PA (0x1A6) +#define TAIKO_A_RX_HPH_BIAS_PA__POR (0xAA) +#define TAIKO_A_RX_HPH_BIAS_LDO (0x1A7) +#define TAIKO_A_RX_HPH_BIAS_LDO__POR (0x87) +#define TAIKO_A_RX_HPH_BIAS_CNP (0x1A8) +#define TAIKO_A_RX_HPH_BIAS_CNP__POR (0x8A) +#define TAIKO_A_RX_HPH_BIAS_WG_OCP (0x1A9) +#define TAIKO_A_RX_HPH_BIAS_WG_OCP__POR (0x2A) +#define TAIKO_A_RX_HPH_OCP_CTL (0x1AA) +#define TAIKO_A_RX_HPH_OCP_CTL__POR (0x68) +#define TAIKO_A_RX_HPH_CNP_EN (0x1AB) +#define TAIKO_A_RX_HPH_CNP_EN__POR (0x80) +#define TAIKO_A_RX_HPH_CNP_WG_CTL (0x1AC) +#define TAIKO_A_RX_HPH_CNP_WG_CTL__POR (0xDE) +#define TAIKO_A_RX_HPH_CNP_WG_TIME (0x1AD) +#define TAIKO_A_RX_HPH_CNP_WG_TIME__POR (0x2A) +#define TAIKO_A_RX_HPH_L_GAIN (0x1AE) +#define TAIKO_A_RX_HPH_L_GAIN__POR (0x00) +#define TAIKO_A_RX_HPH_L_TEST (0x1AF) +#define TAIKO_A_RX_HPH_L_TEST__POR (0x00) +#define TAIKO_A_RX_HPH_L_PA_CTL (0x1B0) +#define TAIKO_A_RX_HPH_L_PA_CTL__POR (0x40) +#define TAIKO_A_RX_HPH_L_DAC_CTL (0x1B1) +#define TAIKO_A_RX_HPH_L_DAC_CTL__POR (0x00) +#define TAIKO_A_RX_HPH_L_ATEST (0x1B2) +#define TAIKO_A_RX_HPH_L_ATEST__POR (0x00) +#define TAIKO_A_RX_HPH_L_STATUS (0x1B3) +#define TAIKO_A_RX_HPH_L_STATUS__POR (0x00) +#define TAIKO_A_RX_HPH_R_GAIN (0x1B4) +#define TAIKO_A_RX_HPH_R_GAIN__POR (0x00) +#define TAIKO_A_RX_HPH_R_TEST (0x1B5) +#define TAIKO_A_RX_HPH_R_TEST__POR (0x00) +#define TAIKO_A_RX_HPH_R_PA_CTL (0x1B6) +#define TAIKO_A_RX_HPH_R_PA_CTL__POR (0x40) +#define TAIKO_A_RX_HPH_R_DAC_CTL (0x1B7) +#define TAIKO_A_RX_HPH_R_DAC_CTL__POR (0x00) +#define TAIKO_A_RX_HPH_R_ATEST (0x1B8) +#define TAIKO_A_RX_HPH_R_ATEST__POR (0x00) +#define TAIKO_A_RX_HPH_R_STATUS (0x1B9) +#define TAIKO_A_RX_HPH_R_STATUS__POR (0x00) +#define TAIKO_A_RX_EAR_BIAS_PA (0x1BA) +#define TAIKO_A_RX_EAR_BIAS_PA__POR (0xA6) +#define TAIKO_A_RX_EAR_BIAS_CMBUFF (0x1BB) +#define TAIKO_A_RX_EAR_BIAS_CMBUFF__POR (0xA0) +#define TAIKO_A_RX_EAR_EN (0x1BC) +#define TAIKO_A_RX_EAR_EN__POR (0x00) +#define TAIKO_A_RX_EAR_GAIN (0x1BD) +#define TAIKO_A_RX_EAR_GAIN__POR (0x02) +#define TAIKO_A_RX_EAR_CMBUFF (0x1BE) +#define TAIKO_A_RX_EAR_CMBUFF__POR (0x04) +#define TAIKO_A_RX_EAR_ICTL (0x1BF) +#define TAIKO_A_RX_EAR_ICTL__POR (0x40) +#define TAIKO_A_RX_EAR_CCOMP (0x1C0) +#define TAIKO_A_RX_EAR_CCOMP__POR (0x08) +#define TAIKO_A_RX_EAR_VCM (0x1C1) +#define TAIKO_A_RX_EAR_VCM__POR (0x03) +#define TAIKO_A_RX_EAR_CNP (0x1C2) +#define TAIKO_A_RX_EAR_CNP__POR (0xF2) +#define TAIKO_A_RX_EAR_DAC_CTL_ATEST (0x1C3) +#define TAIKO_A_RX_EAR_DAC_CTL_ATEST__POR (0x00) +#define TAIKO_A_RX_EAR_STATUS (0x1C5) +#define TAIKO_A_RX_EAR_STATUS__POR (0x04) +#define TAIKO_A_RX_LINE_BIAS_PA (0x1C6) +#define TAIKO_A_RX_LINE_BIAS_PA__POR (0xA8) +#define TAIKO_A_RX_BUCK_BIAS1 (0x1C7) +#define TAIKO_A_RX_BUCK_BIAS1__POR (0x42) +#define TAIKO_A_RX_BUCK_BIAS2 (0x1C8) +#define TAIKO_A_RX_BUCK_BIAS2__POR (0x84) +#define TAIKO_A_RX_LINE_COM (0x1C9) +#define TAIKO_A_RX_LINE_COM__POR (0x80) +#define TAIKO_A_RX_LINE_CNP_EN (0x1CA) +#define TAIKO_A_RX_LINE_CNP_EN__POR (0x00) +#define TAIKO_A_RX_LINE_CNP_WG_CTL (0x1CB) +#define TAIKO_A_RX_LINE_CNP_WG_CTL__POR (0x00) +#define TAIKO_A_RX_LINE_CNP_WG_TIME (0x1CC) +#define TAIKO_A_RX_LINE_CNP_WG_TIME__POR (0x04) +#define TAIKO_A_RX_LINE_1_GAIN (0x1CD) +#define TAIKO_A_RX_LINE_1_GAIN__POR (0x00) +#define TAIKO_A_RX_LINE_1_TEST (0x1CE) +#define TAIKO_A_RX_LINE_1_TEST__POR (0x00) +#define TAIKO_A_RX_LINE_1_DAC_CTL (0x1CF) +#define TAIKO_A_RX_LINE_1_DAC_CTL__POR (0x00) +#define TAIKO_A_RX_LINE_1_STATUS (0x1D0) +#define TAIKO_A_RX_LINE_1_STATUS__POR (0x00) +#define TAIKO_A_RX_LINE_2_GAIN (0x1D1) +#define TAIKO_A_RX_LINE_2_GAIN__POR (0x00) +#define TAIKO_A_RX_LINE_2_TEST (0x1D2) +#define TAIKO_A_RX_LINE_2_TEST__POR (0x00) +#define TAIKO_A_RX_LINE_2_DAC_CTL (0x1D3) +#define TAIKO_A_RX_LINE_2_DAC_CTL__POR (0x00) +#define TAIKO_A_RX_LINE_2_STATUS (0x1D4) +#define TAIKO_A_RX_LINE_2_STATUS__POR (0x00) +#define TAIKO_A_RX_LINE_3_GAIN (0x1D5) +#define TAIKO_A_RX_LINE_3_GAIN__POR (0x00) +#define TAIKO_A_RX_LINE_3_TEST (0x1D6) +#define TAIKO_A_RX_LINE_3_TEST__POR (0x00) +#define TAIKO_A_RX_LINE_3_DAC_CTL (0x1D7) +#define TAIKO_A_RX_LINE_3_DAC_CTL__POR (0x00) +#define TAIKO_A_RX_LINE_3_STATUS (0x1D8) +#define TAIKO_A_RX_LINE_3_STATUS__POR (0x00) +#define TAIKO_A_RX_LINE_4_GAIN (0x1D9) +#define TAIKO_A_RX_LINE_4_GAIN__POR (0x00) +#define TAIKO_A_RX_LINE_4_TEST (0x1DA) +#define TAIKO_A_RX_LINE_4_TEST__POR (0x00) +#define TAIKO_A_RX_LINE_4_DAC_CTL (0x1DB) +#define TAIKO_A_RX_LINE_4_DAC_CTL__POR (0x00) +#define TAIKO_A_RX_LINE_4_STATUS (0x1DC) +#define TAIKO_A_RX_LINE_4_STATUS__POR (0x00) +#define TAIKO_A_RX_LINE_CNP_DBG (0x1DD) +#define TAIKO_A_RX_LINE_CNP_DBG__POR (0x00) +#define TAIKO_A_SPKR_DRV_EN (0x1DF) +#define TAIKO_A_SPKR_DRV_EN__POR (0x6F) +#define TAIKO_A_SPKR_DRV_GAIN (0x1E0) +#define TAIKO_A_SPKR_DRV_GAIN__POR (0x00) +#define TAIKO_A_SPKR_DRV_DAC_CTL (0x1E1) +#define TAIKO_A_SPKR_DRV_DAC_CTL__POR (0x04) +#define TAIKO_A_SPKR_DRV_OCP_CTL (0x1E2) +#define TAIKO_A_SPKR_DRV_OCP_CTL__POR (0x98) +#define TAIKO_A_SPKR_DRV_CLIP_DET (0x1E3) +#define TAIKO_A_SPKR_DRV_CLIP_DET__POR (0x48) +#define TAIKO_A_SPKR_DRV_IEC (0x1E4) +#define TAIKO_A_SPKR_DRV_IEC__POR (0x20) +#define TAIKO_A_SPKR_DRV_DBG_DAC (0x1E5) +#define TAIKO_A_SPKR_DRV_DBG_DAC__POR (0x05) +#define TAIKO_A_SPKR_DRV_DBG_PA (0x1E6) +#define TAIKO_A_SPKR_DRV_DBG_PA__POR (0x18) +#define TAIKO_A_SPKR_DRV_DBG_PWRSTG (0x1E7) +#define TAIKO_A_SPKR_DRV_DBG_PWRSTG__POR (0x00) +#define TAIKO_A_SPKR_DRV_BIAS_LDO (0x1E8) +#define TAIKO_A_SPKR_DRV_BIAS_LDO__POR (0x45) +#define TAIKO_A_SPKR_DRV_BIAS_INT (0x1E9) +#define TAIKO_A_SPKR_DRV_BIAS_INT__POR (0xA5) +#define TAIKO_A_SPKR_DRV_BIAS_PA (0x1EA) +#define TAIKO_A_SPKR_DRV_BIAS_PA__POR (0x55) +#define TAIKO_A_SPKR_DRV_STATUS_OCP (0x1EB) +#define TAIKO_A_SPKR_DRV_STATUS_OCP__POR (0x00) +#define TAIKO_A_SPKR_DRV_STATUS_PA (0x1EC) +#define TAIKO_A_SPKR_DRV_STATUS_PA__POR (0x00) +#define TAIKO_A_SPKR_PROT_EN (0x1ED) +#define TAIKO_A_SPKR_PROT_EN__POR (0x00) +#define TAIKO_A_SPKR_PROT_ADC_EN (0x1EE) +#define TAIKO_A_SPKR_PROT_ADC_EN__POR (0x44) +#define TAIKO_A_SPKR_PROT_ISENSE_BIAS (0x1EF) +#define TAIKO_A_SPKR_PROT_ISENSE_BIAS__POR (0x44) +#define TAIKO_A_SPKR_PROT_VSENSE_BIAS (0x1F0) +#define TAIKO_A_SPKR_PROT_VSENSE_BIAS__POR (0x44) +#define TAIKO_A_SPKR_PROT_ADC_ATEST_REFCTRL (0x1F1) +#define TAIKO_A_SPKR_PROT_ADC_ATEST_REFCTRL__POR (0x00) +#define TAIKO_A_SPKR_PROT_ADC_TEST_CTL (0x1F2) +#define TAIKO_A_SPKR_PROT_ADC_TEST_CTL__POR (0x38) +#define TAIKO_A_SPKR_PROT_TEST_BLOCK_EN (0x1F3) +#define TAIKO_A_SPKR_PROT_TEST_BLOCK_EN__POR (0xFC) +#define TAIKO_A_SPKR_PROT_ATEST (0x1F4) +#define TAIKO_A_SPKR_PROT_ATEST__POR (0x00) +#define TAIKO_A_SPKR_PROT_V_SAR_ERR (0x1F5) +#define TAIKO_A_SPKR_PROT_V_SAR_ERR__POR (0x00) +#define TAIKO_A_SPKR_PROT_I_SAR_ERR (0x1F6) +#define TAIKO_A_SPKR_PROT_I_SAR_ERR__POR (0x00) +#define TAIKO_A_SPKR_PROT_LDO_CTRL (0x1F7) +#define TAIKO_A_SPKR_PROT_LDO_CTRL__POR (0x00) +#define TAIKO_A_SPKR_PROT_ISENSE_CTRL (0x1F8) +#define TAIKO_A_SPKR_PROT_ISENSE_CTRL__POR (0x00) +#define TAIKO_A_SPKR_PROT_VSENSE_CTRL (0x1F9) +#define TAIKO_A_SPKR_PROT_VSENSE_CTRL__POR (0x00) +#define TAIKO_A_RC_OSC_FREQ (0x1FA) +#define TAIKO_A_RC_OSC_FREQ__POR (0x46) +#define TAIKO_A_RC_OSC_TEST (0x1FB) +#define TAIKO_A_RC_OSC_TEST__POR (0x0A) +#define TAIKO_A_RC_OSC_STATUS (0x1FC) +#define TAIKO_A_RC_OSC_STATUS__POR (0x18) +#define TAIKO_A_RC_OSC_TUNER (0x1FD) +#define TAIKO_A_RC_OSC_TUNER__POR (0x00) +#define TAIKO_A_MBHC_HPH (0x1FE) +#define TAIKO_A_MBHC_HPH__POR (0x44) +#define TAIKO_A_CDC_ANC1_B1_CTL (0x200) +#define TAIKO_A_CDC_ANC1_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC2_B1_CTL (0x280) +#define TAIKO_A_CDC_ANC2_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC1_SHIFT (0x201) +#define TAIKO_A_CDC_ANC1_SHIFT__POR (0x00) +#define TAIKO_A_CDC_ANC2_SHIFT (0x281) +#define TAIKO_A_CDC_ANC2_SHIFT__POR (0x00) +#define TAIKO_A_CDC_ANC1_IIR_B1_CTL (0x202) +#define TAIKO_A_CDC_ANC1_IIR_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC2_IIR_B1_CTL (0x282) +#define TAIKO_A_CDC_ANC2_IIR_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC1_IIR_B2_CTL (0x203) +#define TAIKO_A_CDC_ANC1_IIR_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC2_IIR_B2_CTL (0x283) +#define TAIKO_A_CDC_ANC2_IIR_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC1_IIR_B3_CTL (0x204) +#define TAIKO_A_CDC_ANC1_IIR_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC2_IIR_B3_CTL (0x284) +#define TAIKO_A_CDC_ANC2_IIR_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC1_LPF_B1_CTL (0x206) +#define TAIKO_A_CDC_ANC1_LPF_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC2_LPF_B1_CTL (0x286) +#define TAIKO_A_CDC_ANC2_LPF_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC1_LPF_B2_CTL (0x207) +#define TAIKO_A_CDC_ANC1_LPF_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC2_LPF_B2_CTL (0x287) +#define TAIKO_A_CDC_ANC2_LPF_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC1_SPARE (0x209) +#define TAIKO_A_CDC_ANC1_SPARE__POR (0x00) +#define TAIKO_A_CDC_ANC2_SPARE (0x289) +#define TAIKO_A_CDC_ANC2_SPARE__POR (0x00) +#define TAIKO_A_CDC_ANC1_SMLPF_CTL (0x20A) +#define TAIKO_A_CDC_ANC1_SMLPF_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC2_SMLPF_CTL (0x28A) +#define TAIKO_A_CDC_ANC2_SMLPF_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC1_DCFLT_CTL (0x20B) +#define TAIKO_A_CDC_ANC1_DCFLT_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC2_DCFLT_CTL (0x28B) +#define TAIKO_A_CDC_ANC2_DCFLT_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC1_GAIN_CTL (0x20C) +#define TAIKO_A_CDC_ANC1_GAIN_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC2_GAIN_CTL (0x28C) +#define TAIKO_A_CDC_ANC2_GAIN_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC1_B2_CTL (0x20D) +#define TAIKO_A_CDC_ANC1_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_ANC2_B2_CTL (0x28D) +#define TAIKO_A_CDC_ANC2_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_TX1_VOL_CTL_TIMER (0x220) +#define TAIKO_A_CDC_TX1_VOL_CTL_TIMER__POR (0x00) +#define TAIKO_A_CDC_TX2_VOL_CTL_TIMER (0x228) +#define TAIKO_A_CDC_TX2_VOL_CTL_TIMER__POR (0x00) +#define TAIKO_A_CDC_TX3_VOL_CTL_TIMER (0x230) +#define TAIKO_A_CDC_TX3_VOL_CTL_TIMER__POR (0x00) +#define TAIKO_A_CDC_TX4_VOL_CTL_TIMER (0x238) +#define TAIKO_A_CDC_TX4_VOL_CTL_TIMER__POR (0x00) +#define TAIKO_A_CDC_TX5_VOL_CTL_TIMER (0x240) +#define TAIKO_A_CDC_TX5_VOL_CTL_TIMER__POR (0x00) +#define TAIKO_A_CDC_TX6_VOL_CTL_TIMER (0x248) +#define TAIKO_A_CDC_TX6_VOL_CTL_TIMER__POR (0x00) +#define TAIKO_A_CDC_TX7_VOL_CTL_TIMER (0x250) +#define TAIKO_A_CDC_TX7_VOL_CTL_TIMER__POR (0x00) +#define TAIKO_A_CDC_TX8_VOL_CTL_TIMER (0x258) +#define TAIKO_A_CDC_TX8_VOL_CTL_TIMER__POR (0x00) +#define TAIKO_A_CDC_TX9_VOL_CTL_TIMER (0x260) +#define TAIKO_A_CDC_TX9_VOL_CTL_TIMER__POR (0x00) +#define TAIKO_A_CDC_TX10_VOL_CTL_TIMER (0x268) +#define TAIKO_A_CDC_TX10_VOL_CTL_TIMER__POR (0x00) +#define TAIKO_A_CDC_TX1_VOL_CTL_GAIN (0x221) +#define TAIKO_A_CDC_TX1_VOL_CTL_GAIN__POR (0x00) +#define TAIKO_A_CDC_TX2_VOL_CTL_GAIN (0x229) +#define TAIKO_A_CDC_TX2_VOL_CTL_GAIN__POR (0x00) +#define TAIKO_A_CDC_TX3_VOL_CTL_GAIN (0x231) +#define TAIKO_A_CDC_TX3_VOL_CTL_GAIN__POR (0x00) +#define TAIKO_A_CDC_TX4_VOL_CTL_GAIN (0x239) +#define TAIKO_A_CDC_TX4_VOL_CTL_GAIN__POR (0x00) +#define TAIKO_A_CDC_TX5_VOL_CTL_GAIN (0x241) +#define TAIKO_A_CDC_TX5_VOL_CTL_GAIN__POR (0x00) +#define TAIKO_A_CDC_TX6_VOL_CTL_GAIN (0x249) +#define TAIKO_A_CDC_TX6_VOL_CTL_GAIN__POR (0x00) +#define TAIKO_A_CDC_TX7_VOL_CTL_GAIN (0x251) +#define TAIKO_A_CDC_TX7_VOL_CTL_GAIN__POR (0x00) +#define TAIKO_A_CDC_TX8_VOL_CTL_GAIN (0x259) +#define TAIKO_A_CDC_TX8_VOL_CTL_GAIN__POR (0x00) +#define TAIKO_A_CDC_TX9_VOL_CTL_GAIN (0x261) +#define TAIKO_A_CDC_TX9_VOL_CTL_GAIN__POR (0x00) +#define TAIKO_A_CDC_TX10_VOL_CTL_GAIN (0x269) +#define TAIKO_A_CDC_TX10_VOL_CTL_GAIN__POR (0x00) +#define TAIKO_A_CDC_TX1_VOL_CTL_CFG (0x222) +#define TAIKO_A_CDC_TX1_VOL_CTL_CFG__POR (0x00) +#define TAIKO_A_CDC_TX2_VOL_CTL_CFG (0x22A) +#define TAIKO_A_CDC_TX2_VOL_CTL_CFG__POR (0x00) +#define TAIKO_A_CDC_TX3_VOL_CTL_CFG (0x232) +#define TAIKO_A_CDC_TX3_VOL_CTL_CFG__POR (0x00) +#define TAIKO_A_CDC_TX4_VOL_CTL_CFG (0x23A) +#define TAIKO_A_CDC_TX4_VOL_CTL_CFG__POR (0x00) +#define TAIKO_A_CDC_TX5_VOL_CTL_CFG (0x242) +#define TAIKO_A_CDC_TX5_VOL_CTL_CFG__POR (0x00) +#define TAIKO_A_CDC_TX6_VOL_CTL_CFG (0x24A) +#define TAIKO_A_CDC_TX6_VOL_CTL_CFG__POR (0x00) +#define TAIKO_A_CDC_TX7_VOL_CTL_CFG (0x252) +#define TAIKO_A_CDC_TX7_VOL_CTL_CFG__POR (0x00) +#define TAIKO_A_CDC_TX8_VOL_CTL_CFG (0x25A) +#define TAIKO_A_CDC_TX8_VOL_CTL_CFG__POR (0x00) +#define TAIKO_A_CDC_TX9_VOL_CTL_CFG (0x262) +#define TAIKO_A_CDC_TX9_VOL_CTL_CFG__POR (0x00) +#define TAIKO_A_CDC_TX10_VOL_CTL_CFG (0x26A) +#define TAIKO_A_CDC_TX10_VOL_CTL_CFG__POR (0x00) +#define TAIKO_A_CDC_TX1_MUX_CTL (0x223) +#define TAIKO_A_CDC_TX1_MUX_CTL__POR (0x08) +#define TAIKO_A_CDC_TX2_MUX_CTL (0x22B) +#define TAIKO_A_CDC_TX2_MUX_CTL__POR (0x08) +#define TAIKO_A_CDC_TX3_MUX_CTL (0x233) +#define TAIKO_A_CDC_TX3_MUX_CTL__POR (0x08) +#define TAIKO_A_CDC_TX4_MUX_CTL (0x23B) +#define TAIKO_A_CDC_TX4_MUX_CTL__POR (0x08) +#define TAIKO_A_CDC_TX5_MUX_CTL (0x243) +#define TAIKO_A_CDC_TX5_MUX_CTL__POR (0x08) +#define TAIKO_A_CDC_TX6_MUX_CTL (0x24B) +#define TAIKO_A_CDC_TX6_MUX_CTL__POR (0x08) +#define TAIKO_A_CDC_TX7_MUX_CTL (0x253) +#define TAIKO_A_CDC_TX7_MUX_CTL__POR (0x08) +#define TAIKO_A_CDC_TX8_MUX_CTL (0x25B) +#define TAIKO_A_CDC_TX8_MUX_CTL__POR (0x08) +#define TAIKO_A_CDC_TX9_MUX_CTL (0x263) +#define TAIKO_A_CDC_TX9_MUX_CTL__POR (0x08) +#define TAIKO_A_CDC_TX10_MUX_CTL (0x26B) +#define TAIKO_A_CDC_TX10_MUX_CTL__POR (0x08) +#define TAIKO_A_CDC_TX1_CLK_FS_CTL (0x224) +#define TAIKO_A_CDC_TX1_CLK_FS_CTL__POR (0x03) +#define TAIKO_A_CDC_TX2_CLK_FS_CTL (0x22C) +#define TAIKO_A_CDC_TX2_CLK_FS_CTL__POR (0x03) +#define TAIKO_A_CDC_TX3_CLK_FS_CTL (0x234) +#define TAIKO_A_CDC_TX3_CLK_FS_CTL__POR (0x03) +#define TAIKO_A_CDC_TX4_CLK_FS_CTL (0x23C) +#define TAIKO_A_CDC_TX4_CLK_FS_CTL__POR (0x03) +#define TAIKO_A_CDC_TX5_CLK_FS_CTL (0x244) +#define TAIKO_A_CDC_TX5_CLK_FS_CTL__POR (0x03) +#define TAIKO_A_CDC_TX6_CLK_FS_CTL (0x24C) +#define TAIKO_A_CDC_TX6_CLK_FS_CTL__POR (0x03) +#define TAIKO_A_CDC_TX7_CLK_FS_CTL (0x254) +#define TAIKO_A_CDC_TX7_CLK_FS_CTL__POR (0x03) +#define TAIKO_A_CDC_TX8_CLK_FS_CTL (0x25C) +#define TAIKO_A_CDC_TX8_CLK_FS_CTL__POR (0x03) +#define TAIKO_A_CDC_TX9_CLK_FS_CTL (0x264) +#define TAIKO_A_CDC_TX9_CLK_FS_CTL__POR (0x03) +#define TAIKO_A_CDC_TX10_CLK_FS_CTL (0x26C) +#define TAIKO_A_CDC_TX10_CLK_FS_CTL__POR (0x03) +#define TAIKO_A_CDC_TX1_DMIC_CTL (0x225) +#define TAIKO_A_CDC_TX1_DMIC_CTL__POR (0x00) +#define TAIKO_A_CDC_TX2_DMIC_CTL (0x22D) +#define TAIKO_A_CDC_TX2_DMIC_CTL__POR (0x00) +#define TAIKO_A_CDC_TX3_DMIC_CTL (0x235) +#define TAIKO_A_CDC_TX3_DMIC_CTL__POR (0x00) +#define TAIKO_A_CDC_TX4_DMIC_CTL (0x23D) +#define TAIKO_A_CDC_TX4_DMIC_CTL__POR (0x00) +#define TAIKO_A_CDC_TX5_DMIC_CTL (0x245) +#define TAIKO_A_CDC_TX5_DMIC_CTL__POR (0x00) +#define TAIKO_A_CDC_TX6_DMIC_CTL (0x24D) +#define TAIKO_A_CDC_TX6_DMIC_CTL__POR (0x00) +#define TAIKO_A_CDC_TX7_DMIC_CTL (0x255) +#define TAIKO_A_CDC_TX7_DMIC_CTL__POR (0x00) +#define TAIKO_A_CDC_TX8_DMIC_CTL (0x25D) +#define TAIKO_A_CDC_TX8_DMIC_CTL__POR (0x00) +#define TAIKO_A_CDC_TX9_DMIC_CTL (0x265) +#define TAIKO_A_CDC_TX9_DMIC_CTL__POR (0x00) +#define TAIKO_A_CDC_TX10_DMIC_CTL (0x26D) +#define TAIKO_A_CDC_TX10_DMIC_CTL__POR (0x00) +#define TAIKO_A_CDC_DEBUG_B1_CTL (0x278) +#define TAIKO_A_CDC_DEBUG_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_DEBUG_B2_CTL (0x279) +#define TAIKO_A_CDC_DEBUG_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_DEBUG_B3_CTL (0x27A) +#define TAIKO_A_CDC_DEBUG_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_DEBUG_B4_CTL (0x27B) +#define TAIKO_A_CDC_DEBUG_B4_CTL__POR (0x00) +#define TAIKO_A_CDC_DEBUG_B5_CTL (0x27C) +#define TAIKO_A_CDC_DEBUG_B5_CTL__POR (0x00) +#define TAIKO_A_CDC_DEBUG_B6_CTL (0x27D) +#define TAIKO_A_CDC_DEBUG_B6_CTL__POR (0x00) +#define TAIKO_A_CDC_DEBUG_B7_CTL (0x27E) +#define TAIKO_A_CDC_DEBUG_B7_CTL__POR (0x00) +#define TAIKO_A_CDC_SRC1_PDA_CFG (0x2A0) +#define TAIKO_A_CDC_SRC1_PDA_CFG__POR (0x00) +#define TAIKO_A_CDC_SRC2_PDA_CFG (0x2A8) +#define TAIKO_A_CDC_SRC2_PDA_CFG__POR (0x00) +#define TAIKO_A_CDC_SRC1_FS_CTL (0x2A1) +#define TAIKO_A_CDC_SRC1_FS_CTL__POR (0x1B) +#define TAIKO_A_CDC_SRC2_FS_CTL (0x2A9) +#define TAIKO_A_CDC_SRC2_FS_CTL__POR (0x1B) +#define TAIKO_A_CDC_RX1_B1_CTL (0x2B0) +#define TAIKO_A_CDC_RX1_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_RX2_B1_CTL (0x2B8) +#define TAIKO_A_CDC_RX2_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_RX3_B1_CTL (0x2C0) +#define TAIKO_A_CDC_RX3_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_RX4_B1_CTL (0x2C8) +#define TAIKO_A_CDC_RX4_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_RX5_B1_CTL (0x2D0) +#define TAIKO_A_CDC_RX5_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_RX6_B1_CTL (0x2D8) +#define TAIKO_A_CDC_RX6_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_RX7_B1_CTL (0x2E0) +#define TAIKO_A_CDC_RX7_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_RX1_B2_CTL (0x2B1) +#define TAIKO_A_CDC_RX1_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_RX2_B2_CTL (0x2B9) +#define TAIKO_A_CDC_RX2_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_RX3_B2_CTL (0x2C1) +#define TAIKO_A_CDC_RX3_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_RX4_B2_CTL (0x2C9) +#define TAIKO_A_CDC_RX4_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_RX5_B2_CTL (0x2D1) +#define TAIKO_A_CDC_RX5_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_RX6_B2_CTL (0x2D9) +#define TAIKO_A_CDC_RX6_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_RX7_B2_CTL (0x2E1) +#define TAIKO_A_CDC_RX7_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_RX1_B3_CTL (0x2B2) +#define TAIKO_A_CDC_RX1_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_RX2_B3_CTL (0x2BA) +#define TAIKO_A_CDC_RX2_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_RX3_B3_CTL (0x2C2) +#define TAIKO_A_CDC_RX3_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_RX4_B3_CTL (0x2CA) +#define TAIKO_A_CDC_RX4_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_RX5_B3_CTL (0x2D2) +#define TAIKO_A_CDC_RX5_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_RX6_B3_CTL (0x2DA) +#define TAIKO_A_CDC_RX6_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_RX7_B3_CTL (0x2E2) +#define TAIKO_A_CDC_RX7_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_RX1_B4_CTL (0x2B3) +#define TAIKO_A_CDC_RX1_B4_CTL__POR (0x00) +#define TAIKO_A_CDC_RX2_B4_CTL (0x2BB) +#define TAIKO_A_CDC_RX2_B4_CTL__POR (0x00) +#define TAIKO_A_CDC_RX3_B4_CTL (0x2C3) +#define TAIKO_A_CDC_RX3_B4_CTL__POR (0x00) +#define TAIKO_A_CDC_RX4_B4_CTL (0x2CB) +#define TAIKO_A_CDC_RX4_B4_CTL__POR (0x00) +#define TAIKO_A_CDC_RX5_B4_CTL (0x2D3) +#define TAIKO_A_CDC_RX5_B4_CTL__POR (0x00) +#define TAIKO_A_CDC_RX6_B4_CTL (0x2DB) +#define TAIKO_A_CDC_RX6_B4_CTL__POR (0x00) +#define TAIKO_A_CDC_RX7_B4_CTL (0x2E3) +#define TAIKO_A_CDC_RX7_B4_CTL__POR (0x00) +#define TAIKO_A_CDC_RX1_B5_CTL (0x2B4) +#define TAIKO_A_CDC_RX1_B5_CTL__POR (0x78) +#define TAIKO_A_CDC_RX2_B5_CTL (0x2BC) +#define TAIKO_A_CDC_RX2_B5_CTL__POR (0x78) +#define TAIKO_A_CDC_RX3_B5_CTL (0x2C4) +#define TAIKO_A_CDC_RX3_B5_CTL__POR (0x78) +#define TAIKO_A_CDC_RX4_B5_CTL (0x2CC) +#define TAIKO_A_CDC_RX4_B5_CTL__POR (0x78) +#define TAIKO_A_CDC_RX5_B5_CTL (0x2D4) +#define TAIKO_A_CDC_RX5_B5_CTL__POR (0x78) +#define TAIKO_A_CDC_RX6_B5_CTL (0x2DC) +#define TAIKO_A_CDC_RX6_B5_CTL__POR (0x78) +#define TAIKO_A_CDC_RX7_B5_CTL (0x2E4) +#define TAIKO_A_CDC_RX7_B5_CTL__POR (0x78) +#define TAIKO_A_CDC_RX1_B6_CTL (0x2B5) +#define TAIKO_A_CDC_RX1_B6_CTL__POR (0x80) +#define TAIKO_A_CDC_RX2_B6_CTL (0x2BD) +#define TAIKO_A_CDC_RX2_B6_CTL__POR (0x80) +#define TAIKO_A_CDC_RX3_B6_CTL (0x2C5) +#define TAIKO_A_CDC_RX3_B6_CTL__POR (0x80) +#define TAIKO_A_CDC_RX4_B6_CTL (0x2CD) +#define TAIKO_A_CDC_RX4_B6_CTL__POR (0x80) +#define TAIKO_A_CDC_RX5_B6_CTL (0x2D5) +#define TAIKO_A_CDC_RX5_B6_CTL__POR (0x80) +#define TAIKO_A_CDC_RX6_B6_CTL (0x2DD) +#define TAIKO_A_CDC_RX6_B6_CTL__POR (0x80) +#define TAIKO_A_CDC_RX7_B6_CTL (0x2E5) +#define TAIKO_A_CDC_RX7_B6_CTL__POR (0x80) +#define TAIKO_A_CDC_RX1_VOL_CTL_B1_CTL (0x2B6) +#define TAIKO_A_CDC_RX1_VOL_CTL_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_RX2_VOL_CTL_B1_CTL (0x2BE) +#define TAIKO_A_CDC_RX2_VOL_CTL_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_RX3_VOL_CTL_B1_CTL (0x2C6) +#define TAIKO_A_CDC_RX3_VOL_CTL_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_RX4_VOL_CTL_B1_CTL (0x2CE) +#define TAIKO_A_CDC_RX4_VOL_CTL_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_RX5_VOL_CTL_B1_CTL (0x2D6) +#define TAIKO_A_CDC_RX5_VOL_CTL_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_RX6_VOL_CTL_B1_CTL (0x2DE) +#define TAIKO_A_CDC_RX6_VOL_CTL_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_RX7_VOL_CTL_B1_CTL (0x2E6) +#define TAIKO_A_CDC_RX7_VOL_CTL_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL (0x2B7) +#define TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL (0x2BF) +#define TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL (0x2C7) +#define TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL (0x2CF) +#define TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL (0x2D7) +#define TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL (0x2DF) +#define TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL (0x2E7) +#define TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_VBAT_CFG (0x2E8) +#define TAIKO_A_CDC_VBAT_CFG__POR (0x1A) +#define TAIKO_A_CDC_VBAT_ADC_CAL1 (0x2E9) +#define TAIKO_A_CDC_VBAT_ADC_CAL1__POR (0x00) +#define TAIKO_A_CDC_VBAT_ADC_CAL2 (0x2EA) +#define TAIKO_A_CDC_VBAT_ADC_CAL2__POR (0x00) +#define TAIKO_A_CDC_VBAT_ADC_CAL3 (0x2EB) +#define TAIKO_A_CDC_VBAT_ADC_CAL3__POR (0x04) +#define TAIKO_A_CDC_VBAT_PK_EST1 (0x2EC) +#define TAIKO_A_CDC_VBAT_PK_EST1__POR (0xE0) +#define TAIKO_A_CDC_VBAT_PK_EST2 (0x2ED) +#define TAIKO_A_CDC_VBAT_PK_EST2__POR (0x01) +#define TAIKO_A_CDC_VBAT_PK_EST3 (0x2EE) +#define TAIKO_A_CDC_VBAT_PK_EST3__POR (0x40) +#define TAIKO_A_CDC_VBAT_RF_PROC1 (0x2EF) +#define TAIKO_A_CDC_VBAT_RF_PROC1__POR (0x2A) +#define TAIKO_A_CDC_VBAT_RF_PROC2 (0x2F0) +#define TAIKO_A_CDC_VBAT_RF_PROC2__POR (0x86) +#define TAIKO_A_CDC_VBAT_TAC1 (0x2F1) +#define TAIKO_A_CDC_VBAT_TAC1__POR (0x70) +#define TAIKO_A_CDC_VBAT_TAC2 (0x2F2) +#define TAIKO_A_CDC_VBAT_TAC2__POR (0x18) +#define TAIKO_A_CDC_VBAT_TAC3 (0x2F3) +#define TAIKO_A_CDC_VBAT_TAC3__POR (0x18) +#define TAIKO_A_CDC_VBAT_TAC4 (0x2F4) +#define TAIKO_A_CDC_VBAT_TAC4__POR (0x03) +#define TAIKO_A_CDC_VBAT_GAIN_UPD1 (0x2F5) +#define TAIKO_A_CDC_VBAT_GAIN_UPD1__POR (0x01) +#define TAIKO_A_CDC_VBAT_GAIN_UPD2 (0x2F6) +#define TAIKO_A_CDC_VBAT_GAIN_UPD2__POR (0x00) +#define TAIKO_A_CDC_VBAT_GAIN_UPD3 (0x2F7) +#define TAIKO_A_CDC_VBAT_GAIN_UPD3__POR (0x64) +#define TAIKO_A_CDC_VBAT_GAIN_UPD4 (0x2F8) +#define TAIKO_A_CDC_VBAT_GAIN_UPD4__POR (0x01) +#define TAIKO_A_CDC_VBAT_DEBUG1 (0x2F9) +#define TAIKO_A_CDC_VBAT_DEBUG1__POR (0x00) +#define TAIKO_A_CDC_CLK_ANC_RESET_CTL (0x300) +#define TAIKO_A_CDC_CLK_ANC_RESET_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_RX_RESET_CTL (0x301) +#define TAIKO_A_CDC_CLK_RX_RESET_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_TX_RESET_B1_CTL (0x302) +#define TAIKO_A_CDC_CLK_TX_RESET_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_TX_RESET_B2_CTL (0x303) +#define TAIKO_A_CDC_CLK_TX_RESET_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_DMIC_B1_CTL (0x304) +#define TAIKO_A_CDC_CLK_DMIC_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_DMIC_B2_CTL (0x305) +#define TAIKO_A_CDC_CLK_DMIC_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_RX_I2S_CTL (0x306) +#define TAIKO_A_CDC_CLK_RX_I2S_CTL__POR (0x03) +#define TAIKO_A_CDC_CLK_TX_I2S_CTL (0x307) +#define TAIKO_A_CDC_CLK_TX_I2S_CTL__POR (0x03) +#define TAIKO_A_CDC_CLK_OTHR_RESET_B1_CTL (0x308) +#define TAIKO_A_CDC_CLK_OTHR_RESET_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_OTHR_RESET_B2_CTL (0x309) +#define TAIKO_A_CDC_CLK_OTHR_RESET_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL (0x30A) +#define TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL (0x30B) +#define TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_OTHR_CTL (0x30C) +#define TAIKO_A_CDC_CLK_OTHR_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL (0x30D) +#define TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_ANC_CLK_EN_CTL (0x30E) +#define TAIKO_A_CDC_CLK_ANC_CLK_EN_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_RX_B1_CTL (0x30F) +#define TAIKO_A_CDC_CLK_RX_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_RX_B2_CTL (0x310) +#define TAIKO_A_CDC_CLK_RX_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_MCLK_CTL (0x311) +#define TAIKO_A_CDC_CLK_MCLK_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_PDM_CTL (0x312) +#define TAIKO_A_CDC_CLK_PDM_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_SD_CTL (0x313) +#define TAIKO_A_CDC_CLK_SD_CTL__POR (0x00) +#define TAIKO_A_CDC_CLK_POWER_CTL (0x314) +#define TAIKO_A_CDC_CLK_POWER_CTL__POR (0x00) +#define TAIKO_A_CDC_CLSH_B1_CTL (0x320) +#define TAIKO_A_CDC_CLSH_B1_CTL__POR (0xE4) +#define TAIKO_A_CDC_CLSH_B2_CTL (0x321) +#define TAIKO_A_CDC_CLSH_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CLSH_B3_CTL (0x322) +#define TAIKO_A_CDC_CLSH_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_CLSH_BUCK_NCP_VARS (0x323) +#define TAIKO_A_CDC_CLSH_BUCK_NCP_VARS__POR (0x00) +#define TAIKO_A_CDC_CLSH_IDLE_HPH_THSD (0x324) +#define TAIKO_A_CDC_CLSH_IDLE_HPH_THSD__POR (0x12) +#define TAIKO_A_CDC_CLSH_IDLE_EAR_THSD (0x325) +#define TAIKO_A_CDC_CLSH_IDLE_EAR_THSD__POR (0x0C) +#define TAIKO_A_CDC_CLSH_FCLKONLY_HPH_THSD (0x326) +#define TAIKO_A_CDC_CLSH_FCLKONLY_HPH_THSD__POR (0x18) +#define TAIKO_A_CDC_CLSH_FCLKONLY_EAR_THSD (0x327) +#define TAIKO_A_CDC_CLSH_FCLKONLY_EAR_THSD__POR (0x23) +#define TAIKO_A_CDC_CLSH_K_ADDR (0x328) +#define TAIKO_A_CDC_CLSH_K_ADDR__POR (0x00) +#define TAIKO_A_CDC_CLSH_K_DATA (0x329) +#define TAIKO_A_CDC_CLSH_K_DATA__POR (0xA4) +#define TAIKO_A_CDC_CLSH_I_PA_FACT_HPH_L (0x32A) +#define TAIKO_A_CDC_CLSH_I_PA_FACT_HPH_L__POR (0xD7) +#define TAIKO_A_CDC_CLSH_I_PA_FACT_HPH_U (0x32B) +#define TAIKO_A_CDC_CLSH_I_PA_FACT_HPH_U__POR (0x05) +#define TAIKO_A_CDC_CLSH_I_PA_FACT_EAR_L (0x32C) +#define TAIKO_A_CDC_CLSH_I_PA_FACT_EAR_L__POR (0x60) +#define TAIKO_A_CDC_CLSH_I_PA_FACT_EAR_U (0x32D) +#define TAIKO_A_CDC_CLSH_I_PA_FACT_EAR_U__POR (0x09) +#define TAIKO_A_CDC_CLSH_V_PA_HD_EAR (0x32E) +#define TAIKO_A_CDC_CLSH_V_PA_HD_EAR__POR (0x00) +#define TAIKO_A_CDC_CLSH_V_PA_HD_HPH (0x32F) +#define TAIKO_A_CDC_CLSH_V_PA_HD_HPH__POR (0x00) +#define TAIKO_A_CDC_CLSH_V_PA_MIN_EAR (0x330) +#define TAIKO_A_CDC_CLSH_V_PA_MIN_EAR__POR (0x00) +#define TAIKO_A_CDC_CLSH_V_PA_MIN_HPH (0x331) +#define TAIKO_A_CDC_CLSH_V_PA_MIN_HPH__POR (0x00) +#define TAIKO_A_CDC_IIR1_GAIN_B1_CTL (0x340) +#define TAIKO_A_CDC_IIR1_GAIN_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR2_GAIN_B1_CTL (0x350) +#define TAIKO_A_CDC_IIR2_GAIN_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR1_GAIN_B2_CTL (0x341) +#define TAIKO_A_CDC_IIR1_GAIN_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR2_GAIN_B2_CTL (0x351) +#define TAIKO_A_CDC_IIR2_GAIN_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR1_GAIN_B3_CTL (0x342) +#define TAIKO_A_CDC_IIR1_GAIN_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR2_GAIN_B3_CTL (0x352) +#define TAIKO_A_CDC_IIR2_GAIN_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR1_GAIN_B4_CTL (0x343) +#define TAIKO_A_CDC_IIR1_GAIN_B4_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR2_GAIN_B4_CTL (0x353) +#define TAIKO_A_CDC_IIR2_GAIN_B4_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR1_GAIN_B5_CTL (0x344) +#define TAIKO_A_CDC_IIR1_GAIN_B5_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR2_GAIN_B5_CTL (0x354) +#define TAIKO_A_CDC_IIR2_GAIN_B5_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR1_GAIN_B6_CTL (0x345) +#define TAIKO_A_CDC_IIR1_GAIN_B6_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR2_GAIN_B6_CTL (0x355) +#define TAIKO_A_CDC_IIR2_GAIN_B6_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR1_GAIN_B7_CTL (0x346) +#define TAIKO_A_CDC_IIR1_GAIN_B7_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR2_GAIN_B7_CTL (0x356) +#define TAIKO_A_CDC_IIR2_GAIN_B7_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR1_GAIN_B8_CTL (0x347) +#define TAIKO_A_CDC_IIR1_GAIN_B8_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR2_GAIN_B8_CTL (0x357) +#define TAIKO_A_CDC_IIR2_GAIN_B8_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR1_CTL (0x348) +#define TAIKO_A_CDC_IIR1_CTL__POR (0x40) +#define TAIKO_A_CDC_IIR2_CTL (0x358) +#define TAIKO_A_CDC_IIR2_CTL__POR (0x40) +#define TAIKO_A_CDC_IIR1_GAIN_TIMER_CTL (0x349) +#define TAIKO_A_CDC_IIR1_GAIN_TIMER_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR2_GAIN_TIMER_CTL (0x359) +#define TAIKO_A_CDC_IIR2_GAIN_TIMER_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR1_COEF_B1_CTL (0x34A) +#define TAIKO_A_CDC_IIR1_COEF_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR2_COEF_B1_CTL (0x35A) +#define TAIKO_A_CDC_IIR2_COEF_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR1_COEF_B2_CTL (0x34B) +#define TAIKO_A_CDC_IIR1_COEF_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_IIR2_COEF_B2_CTL (0x35B) +#define TAIKO_A_CDC_IIR2_COEF_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_TOP_GAIN_UPDATE (0x360) +#define TAIKO_A_CDC_TOP_GAIN_UPDATE__POR (0x00) +#define TAIKO_A_CDC_COMP0_B1_CTL (0x368) +#define TAIKO_A_CDC_COMP0_B1_CTL__POR (0x30) +#define TAIKO_A_CDC_COMP1_B1_CTL (0x370) +#define TAIKO_A_CDC_COMP1_B1_CTL__POR (0x30) +#define TAIKO_A_CDC_COMP2_B1_CTL (0x378) +#define TAIKO_A_CDC_COMP2_B1_CTL__POR (0x30) +#define TAIKO_A_CDC_COMP0_B2_CTL (0x369) +#define TAIKO_A_CDC_COMP0_B2_CTL__POR (0xB5) +#define TAIKO_A_CDC_COMP1_B2_CTL (0x371) +#define TAIKO_A_CDC_COMP1_B2_CTL__POR (0xB5) +#define TAIKO_A_CDC_COMP2_B2_CTL (0x379) +#define TAIKO_A_CDC_COMP2_B2_CTL__POR (0xB5) +#define TAIKO_A_CDC_COMP0_B3_CTL (0x36A) +#define TAIKO_A_CDC_COMP0_B3_CTL__POR (0x28) +#define TAIKO_A_CDC_COMP1_B3_CTL (0x372) +#define TAIKO_A_CDC_COMP1_B3_CTL__POR (0x28) +#define TAIKO_A_CDC_COMP2_B3_CTL (0x37A) +#define TAIKO_A_CDC_COMP2_B3_CTL__POR (0x28) +#define TAIKO_A_CDC_COMP0_B4_CTL (0x36B) +#define TAIKO_A_CDC_COMP0_B4_CTL__POR (0x3C) +#define TAIKO_A_CDC_COMP1_B4_CTL (0x373) +#define TAIKO_A_CDC_COMP1_B4_CTL__POR (0x3C) +#define TAIKO_A_CDC_COMP2_B4_CTL (0x37B) +#define TAIKO_A_CDC_COMP2_B4_CTL__POR (0x3C) +#define TAIKO_A_CDC_COMP0_B5_CTL (0x36C) +#define TAIKO_A_CDC_COMP0_B5_CTL__POR (0x1F) +#define TAIKO_A_CDC_COMP1_B5_CTL (0x374) +#define TAIKO_A_CDC_COMP1_B5_CTL__POR (0x1F) +#define TAIKO_A_CDC_COMP2_B5_CTL (0x37C) +#define TAIKO_A_CDC_COMP2_B5_CTL__POR (0x1F) +#define TAIKO_A_CDC_COMP0_B6_CTL (0x36D) +#define TAIKO_A_CDC_COMP0_B6_CTL__POR (0x00) +#define TAIKO_A_CDC_COMP1_B6_CTL (0x375) +#define TAIKO_A_CDC_COMP1_B6_CTL__POR (0x00) +#define TAIKO_A_CDC_COMP2_B6_CTL (0x37D) +#define TAIKO_A_CDC_COMP2_B6_CTL__POR (0x00) +#define TAIKO_A_CDC_COMP0_SHUT_DOWN_STATUS (0x36E) +#define TAIKO_A_CDC_COMP0_SHUT_DOWN_STATUS__POR (0x03) +#define TAIKO_A_CDC_COMP1_SHUT_DOWN_STATUS (0x376) +#define TAIKO_A_CDC_COMP1_SHUT_DOWN_STATUS__POR (0x03) +#define TAIKO_A_CDC_COMP2_SHUT_DOWN_STATUS (0x37E) +#define TAIKO_A_CDC_COMP2_SHUT_DOWN_STATUS__POR (0x03) +#define TAIKO_A_CDC_COMP0_FS_CFG (0x36F) +#define TAIKO_A_CDC_COMP0_FS_CFG__POR (0x03) +#define TAIKO_A_CDC_COMP1_FS_CFG (0x377) +#define TAIKO_A_CDC_COMP1_FS_CFG__POR (0x03) +#define TAIKO_A_CDC_COMP2_FS_CFG (0x37F) +#define TAIKO_A_CDC_COMP2_FS_CFG__POR (0x03) +#define TAIKO_A_CDC_CONN_RX1_B1_CTL (0x380) +#define TAIKO_A_CDC_CONN_RX1_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX1_B2_CTL (0x381) +#define TAIKO_A_CDC_CONN_RX1_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX1_B3_CTL (0x382) +#define TAIKO_A_CDC_CONN_RX1_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX2_B1_CTL (0x383) +#define TAIKO_A_CDC_CONN_RX2_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX2_B2_CTL (0x384) +#define TAIKO_A_CDC_CONN_RX2_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX2_B3_CTL (0x385) +#define TAIKO_A_CDC_CONN_RX2_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX3_B1_CTL (0x386) +#define TAIKO_A_CDC_CONN_RX3_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX3_B2_CTL (0x387) +#define TAIKO_A_CDC_CONN_RX3_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX4_B1_CTL (0x388) +#define TAIKO_A_CDC_CONN_RX4_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX4_B2_CTL (0x389) +#define TAIKO_A_CDC_CONN_RX4_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX5_B1_CTL (0x38A) +#define TAIKO_A_CDC_CONN_RX5_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX5_B2_CTL (0x38B) +#define TAIKO_A_CDC_CONN_RX5_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX6_B1_CTL (0x38C) +#define TAIKO_A_CDC_CONN_RX6_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX6_B2_CTL (0x38D) +#define TAIKO_A_CDC_CONN_RX6_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX7_B1_CTL (0x38E) +#define TAIKO_A_CDC_CONN_RX7_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX7_B2_CTL (0x38F) +#define TAIKO_A_CDC_CONN_RX7_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX7_B3_CTL (0x390) +#define TAIKO_A_CDC_CONN_RX7_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_ANC_B1_CTL (0x391) +#define TAIKO_A_CDC_CONN_ANC_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_ANC_B2_CTL (0x392) +#define TAIKO_A_CDC_CONN_ANC_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_TX_B1_CTL (0x393) +#define TAIKO_A_CDC_CONN_TX_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_TX_B2_CTL (0x394) +#define TAIKO_A_CDC_CONN_TX_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_TX_B3_CTL (0x395) +#define TAIKO_A_CDC_CONN_TX_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_TX_B4_CTL (0x396) +#define TAIKO_A_CDC_CONN_TX_B4_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_EQ1_B1_CTL (0x397) +#define TAIKO_A_CDC_CONN_EQ1_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_EQ1_B2_CTL (0x398) +#define TAIKO_A_CDC_CONN_EQ1_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_EQ1_B3_CTL (0x399) +#define TAIKO_A_CDC_CONN_EQ1_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_EQ1_B4_CTL (0x39A) +#define TAIKO_A_CDC_CONN_EQ1_B4_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_EQ2_B1_CTL (0x39B) +#define TAIKO_A_CDC_CONN_EQ2_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_EQ2_B2_CTL (0x39C) +#define TAIKO_A_CDC_CONN_EQ2_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_EQ2_B3_CTL (0x39D) +#define TAIKO_A_CDC_CONN_EQ2_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_EQ2_B4_CTL (0x39E) +#define TAIKO_A_CDC_CONN_EQ2_B4_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_SRC1_B1_CTL (0x39F) +#define TAIKO_A_CDC_CONN_SRC1_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_SRC1_B2_CTL (0x3A0) +#define TAIKO_A_CDC_CONN_SRC1_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_SRC2_B1_CTL (0x3A1) +#define TAIKO_A_CDC_CONN_SRC2_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_SRC2_B2_CTL (0x3A2) +#define TAIKO_A_CDC_CONN_SRC2_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_TX_SB_B1_CTL (0x3A3) +#define TAIKO_A_CDC_CONN_TX_SB_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_TX_SB_B2_CTL (0x3A4) +#define TAIKO_A_CDC_CONN_TX_SB_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_TX_SB_B3_CTL (0x3A5) +#define TAIKO_A_CDC_CONN_TX_SB_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_TX_SB_B4_CTL (0x3A6) +#define TAIKO_A_CDC_CONN_TX_SB_B4_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_TX_SB_B5_CTL (0x3A7) +#define TAIKO_A_CDC_CONN_TX_SB_B5_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_TX_SB_B6_CTL (0x3A8) +#define TAIKO_A_CDC_CONN_TX_SB_B6_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_TX_SB_B7_CTL (0x3A9) +#define TAIKO_A_CDC_CONN_TX_SB_B7_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_TX_SB_B8_CTL (0x3AA) +#define TAIKO_A_CDC_CONN_TX_SB_B8_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_TX_SB_B9_CTL (0x3AB) +#define TAIKO_A_CDC_CONN_TX_SB_B9_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_TX_SB_B10_CTL (0x3AC) +#define TAIKO_A_CDC_CONN_TX_SB_B10_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_TX_SB_B11_CTL (0x3AD) +#define TAIKO_A_CDC_CONN_TX_SB_B11_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX_SB_B1_CTL (0x3AE) +#define TAIKO_A_CDC_CONN_RX_SB_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_RX_SB_B2_CTL (0x3AF) +#define TAIKO_A_CDC_CONN_RX_SB_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_CLSH_CTL (0x3B0) +#define TAIKO_A_CDC_CONN_CLSH_CTL__POR (0x00) +#define TAIKO_A_CDC_CONN_MISC (0x3B1) +#define TAIKO_A_CDC_CONN_MISC__POR (0x01) +#define TAIKO_A_CDC_CONN_MAD (0x3B2) +#define TAIKO_A_CDC_CONN_MAD__POR (0x01) +#define TAIKO_A_CDC_MBHC_EN_CTL (0x3C0) +#define TAIKO_A_CDC_MBHC_EN_CTL__POR (0x00) +#define TAIKO_A_CDC_MBHC_FIR_B1_CFG (0x3C1) +#define TAIKO_A_CDC_MBHC_FIR_B1_CFG__POR (0x00) +#define TAIKO_A_CDC_MBHC_FIR_B2_CFG (0x3C2) +#define TAIKO_A_CDC_MBHC_FIR_B2_CFG__POR (0x06) +#define TAIKO_A_CDC_MBHC_TIMER_B1_CTL (0x3C3) +#define TAIKO_A_CDC_MBHC_TIMER_B1_CTL__POR (0x03) +#define TAIKO_A_CDC_MBHC_TIMER_B2_CTL (0x3C4) +#define TAIKO_A_CDC_MBHC_TIMER_B2_CTL__POR (0x09) +#define TAIKO_A_CDC_MBHC_TIMER_B3_CTL (0x3C5) +#define TAIKO_A_CDC_MBHC_TIMER_B3_CTL__POR (0x1E) +#define TAIKO_A_CDC_MBHC_TIMER_B4_CTL (0x3C6) +#define TAIKO_A_CDC_MBHC_TIMER_B4_CTL__POR (0x45) +#define TAIKO_A_CDC_MBHC_TIMER_B5_CTL (0x3C7) +#define TAIKO_A_CDC_MBHC_TIMER_B5_CTL__POR (0x04) +#define TAIKO_A_CDC_MBHC_TIMER_B6_CTL (0x3C8) +#define TAIKO_A_CDC_MBHC_TIMER_B6_CTL__POR (0x78) +#define TAIKO_A_CDC_MBHC_B1_STATUS (0x3C9) +#define TAIKO_A_CDC_MBHC_B1_STATUS__POR (0x00) +#define TAIKO_A_CDC_MBHC_B2_STATUS (0x3CA) +#define TAIKO_A_CDC_MBHC_B2_STATUS__POR (0x00) +#define TAIKO_A_CDC_MBHC_B3_STATUS (0x3CB) +#define TAIKO_A_CDC_MBHC_B3_STATUS__POR (0x00) +#define TAIKO_A_CDC_MBHC_B4_STATUS (0x3CC) +#define TAIKO_A_CDC_MBHC_B4_STATUS__POR (0x00) +#define TAIKO_A_CDC_MBHC_B5_STATUS (0x3CD) +#define TAIKO_A_CDC_MBHC_B5_STATUS__POR (0x00) +#define TAIKO_A_CDC_MBHC_B1_CTL (0x3CE) +#define TAIKO_A_CDC_MBHC_B1_CTL__POR (0xC0) +#define TAIKO_A_CDC_MBHC_B2_CTL (0x3CF) +#define TAIKO_A_CDC_MBHC_B2_CTL__POR (0x5D) +#define TAIKO_A_CDC_MBHC_VOLT_B1_CTL (0x3D0) +#define TAIKO_A_CDC_MBHC_VOLT_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_MBHC_VOLT_B2_CTL (0x3D1) +#define TAIKO_A_CDC_MBHC_VOLT_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_MBHC_VOLT_B3_CTL (0x3D2) +#define TAIKO_A_CDC_MBHC_VOLT_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_MBHC_VOLT_B4_CTL (0x3D3) +#define TAIKO_A_CDC_MBHC_VOLT_B4_CTL__POR (0x00) +#define TAIKO_A_CDC_MBHC_VOLT_B5_CTL (0x3D4) +#define TAIKO_A_CDC_MBHC_VOLT_B5_CTL__POR (0x00) +#define TAIKO_A_CDC_MBHC_VOLT_B6_CTL (0x3D5) +#define TAIKO_A_CDC_MBHC_VOLT_B6_CTL__POR (0x00) +#define TAIKO_A_CDC_MBHC_VOLT_B7_CTL (0x3D6) +#define TAIKO_A_CDC_MBHC_VOLT_B7_CTL__POR (0xFF) +#define TAIKO_A_CDC_MBHC_VOLT_B8_CTL (0x3D7) +#define TAIKO_A_CDC_MBHC_VOLT_B8_CTL__POR (0x07) +#define TAIKO_A_CDC_MBHC_VOLT_B9_CTL (0x3D8) +#define TAIKO_A_CDC_MBHC_VOLT_B9_CTL__POR (0xFF) +#define TAIKO_A_CDC_MBHC_VOLT_B10_CTL (0x3D9) +#define TAIKO_A_CDC_MBHC_VOLT_B10_CTL__POR (0x7F) +#define TAIKO_A_CDC_MBHC_VOLT_B11_CTL (0x3DA) +#define TAIKO_A_CDC_MBHC_VOLT_B11_CTL__POR (0x00) +#define TAIKO_A_CDC_MBHC_VOLT_B12_CTL (0x3DB) +#define TAIKO_A_CDC_MBHC_VOLT_B12_CTL__POR (0x80) +#define TAIKO_A_CDC_MBHC_CLK_CTL (0x3DC) +#define TAIKO_A_CDC_MBHC_CLK_CTL__POR (0x00) +#define TAIKO_A_CDC_MBHC_INT_CTL (0x3DD) +#define TAIKO_A_CDC_MBHC_INT_CTL__POR (0x00) +#define TAIKO_A_CDC_MBHC_DEBUG_CTL (0x3DE) +#define TAIKO_A_CDC_MBHC_DEBUG_CTL__POR (0x00) +#define TAIKO_A_CDC_MBHC_SPARE (0x3DF) +#define TAIKO_A_CDC_MBHC_SPARE__POR (0x00) +#define TAIKO_A_CDC_MAD_MAIN_CTL_1 (0x3E0) +#define TAIKO_A_CDC_MAD_MAIN_CTL_1__POR (0x00) +#define TAIKO_A_CDC_MAD_MAIN_CTL_2 (0x3E1) +#define TAIKO_A_CDC_MAD_MAIN_CTL_2__POR (0x00) +#define TAIKO_A_CDC_MAD_AUDIO_CTL_1 (0x3E2) +#define TAIKO_A_CDC_MAD_AUDIO_CTL_1__POR (0x00) +#define TAIKO_A_CDC_MAD_AUDIO_CTL_2 (0x3E3) +#define TAIKO_A_CDC_MAD_AUDIO_CTL_2__POR (0x00) +#define TAIKO_A_CDC_MAD_AUDIO_CTL_3 (0x3E4) +#define TAIKO_A_CDC_MAD_AUDIO_CTL_3__POR (0x00) +#define TAIKO_A_CDC_MAD_AUDIO_CTL_4 (0x3E5) +#define TAIKO_A_CDC_MAD_AUDIO_CTL_4__POR (0x00) +#define TAIKO_A_CDC_MAD_AUDIO_CTL_5 (0x3E6) +#define TAIKO_A_CDC_MAD_AUDIO_CTL_5__POR (0x00) +#define TAIKO_A_CDC_MAD_AUDIO_CTL_6 (0x3E7) +#define TAIKO_A_CDC_MAD_AUDIO_CTL_6__POR (0x00) +#define TAIKO_A_CDC_MAD_AUDIO_CTL_7 (0x3E8) +#define TAIKO_A_CDC_MAD_AUDIO_CTL_7__POR (0x00) +#define TAIKO_A_CDC_MAD_AUDIO_CTL_8 (0x3E9) +#define TAIKO_A_CDC_MAD_AUDIO_CTL_8__POR (0x00) +#define TAIKO_A_CDC_MAD_AUDIO_IIR_CTL_PTR (0x3EA) +#define TAIKO_A_CDC_MAD_AUDIO_IIR_CTL_PTR__POR (0x00) +#define TAIKO_A_CDC_MAD_AUDIO_IIR_CTL_VAL (0x3EB) +#define TAIKO_A_CDC_MAD_AUDIO_IIR_CTL_VAL__POR (0x40) +#define TAIKO_A_CDC_MAD_ULTR_CTL_1 (0x3EC) +#define TAIKO_A_CDC_MAD_ULTR_CTL_1__POR (0x00) +#define TAIKO_A_CDC_MAD_ULTR_CTL_2 (0x3ED) +#define TAIKO_A_CDC_MAD_ULTR_CTL_2__POR (0x00) +#define TAIKO_A_CDC_MAD_ULTR_CTL_3 (0x3EE) +#define TAIKO_A_CDC_MAD_ULTR_CTL_3__POR (0x00) +#define TAIKO_A_CDC_MAD_ULTR_CTL_4 (0x3EF) +#define TAIKO_A_CDC_MAD_ULTR_CTL_4__POR (0x00) +#define TAIKO_A_CDC_MAD_ULTR_CTL_5 (0x3F0) +#define TAIKO_A_CDC_MAD_ULTR_CTL_5__POR (0x00) +#define TAIKO_A_CDC_MAD_ULTR_CTL_6 (0x3F1) +#define TAIKO_A_CDC_MAD_ULTR_CTL_6__POR (0x00) +#define TAIKO_A_CDC_MAD_ULTR_CTL_7 (0x3F2) +#define TAIKO_A_CDC_MAD_ULTR_CTL_7__POR (0x00) +#define TAIKO_A_CDC_MAD_BEACON_CTL_1 (0x3F3) +#define TAIKO_A_CDC_MAD_BEACON_CTL_1__POR (0x00) +#define TAIKO_A_CDC_MAD_BEACON_CTL_2 (0x3F4) +#define TAIKO_A_CDC_MAD_BEACON_CTL_2__POR (0x00) +#define TAIKO_A_CDC_MAD_BEACON_CTL_3 (0x3F5) +#define TAIKO_A_CDC_MAD_BEACON_CTL_3__POR (0x00) +#define TAIKO_A_CDC_MAD_BEACON_CTL_4 (0x3F6) +#define TAIKO_A_CDC_MAD_BEACON_CTL_4__POR (0x00) +#define TAIKO_A_CDC_MAD_BEACON_CTL_5 (0x3F7) +#define TAIKO_A_CDC_MAD_BEACON_CTL_5__POR (0x00) +#define TAIKO_A_CDC_MAD_BEACON_CTL_6 (0x3F8) +#define TAIKO_A_CDC_MAD_BEACON_CTL_6__POR (0x00) +#define TAIKO_A_CDC_MAD_BEACON_CTL_7 (0x3F9) +#define TAIKO_A_CDC_MAD_BEACON_CTL_7__POR (0x00) +#define TAIKO_A_CDC_MAD_BEACON_CTL_8 (0x3FA) +#define TAIKO_A_CDC_MAD_BEACON_CTL_8__POR (0x00) +#define TAIKO_A_CDC_MAD_BEACON_IIR_CTL_PTR (0x3FB) +#define TAIKO_A_CDC_MAD_BEACON_IIR_CTL_PTR__POR (0x00) +#define TAIKO_A_CDC_MAD_BEACON_IIR_CTL_VAL (0x3FC) +#define TAIKO_A_CDC_MAD_BEACON_IIR_CTL_VAL__POR (0x00) + +/* Taiko v2+ registers */ +#define TAIKO_A_CDC_TX_1_GAIN (0x153) +#define TAIKO_A_CDC_TX_1_GAIN__POR (0x02) +#define TAIKO_A_CDC_TX_2_GAIN (0x155) +#define TAIKO_A_CDC_TX_2_GAIN__POR (0x02) +#define TAIKO_A_CDC_TX_1_2_ADC_IB (0x156) +#define TAIKO_A_CDC_TX_1_2_ADC_IB__POR (0x44) +#define TAIKO_A_CDC_TX_3_GAIN (0x15D) +#define TAIKO_A_CDC_TX_3_GAIN__POR (0x02) +#define TAIKO_A_CDC_TX_4_GAIN (0x15F) +#define TAIKO_A_CDC_TX_4_GAIN__POR (0x02) +#define TAIKO_A_CDC_TX_3_4_ADC_IB (0x160) +#define TAIKO_A_CDC_TX_3_4_ADC_IB__POR (0x44) +#define TAIKO_A_CDC_TX_5_GAIN (0x167) +#define TAIKO_A_CDC_TX_5_GAIN__POR (0x02) +#define TAIKO_A_CDC_TX_6_GAIN (0x169) +#define TAIKO_A_CDC_TX_6_GAIN__POR (0x02) +#define TAIKO_A_CDC_TX_5_6_ADC_IB (0x16A) +#define TAIKO_A_CDC_TX_5_6_ADC_IB__POR (0x44) +#define TAIKO_A_CDC_SPKR_CLIPDET_VAL0 (0x270) +#define TAIKO_A_CDC_SPKR_CLIPDET_VAL0__POR (0x00) +#define TAIKO_A_CDC_SPKR_CLIPDET_VAL1 (0x271) +#define TAIKO_A_CDC_SPKR_CLIPDET_VAL1__POR (0x00) +#define TAIKO_A_CDC_SPKR_CLIPDET_VAL2 (0x272) +#define TAIKO_A_CDC_SPKR_CLIPDET_VAL2__POR (0x00) +#define TAIKO_A_CDC_SPKR_CLIPDET_VAL3 (0x273) +#define TAIKO_A_CDC_SPKR_CLIPDET_VAL3__POR (0x00) +#define TAIKO_A_CDC_SPKR_CLIPDET_VAL4 (0x274) +#define TAIKO_A_CDC_SPKR_CLIPDET_VAL4__POR (0x00) +#define TAIKO_A_CDC_SPKR_CLIPDET_VAL5 (0x275) +#define TAIKO_A_CDC_SPKR_CLIPDET_VAL5__POR (0x00) +#define TAIKO_A_CDC_SPKR_CLIPDET_VAL6 (0x276) +#define TAIKO_A_CDC_SPKR_CLIPDET_VAL6__POR (0x00) +#define TAIKO_A_CDC_SPKR_CLIPDET_VAL7 (0x277) +#define TAIKO_A_CDC_SPKR_CLIPDET_VAL7__POR (0x00) +#define TAIKO_A_CDC_VBAT_GAIN_UPD_MON (0x2FA) +#define TAIKO_A_CDC_VBAT_GAIN_UPD_MON__POR (0x00) +#define TAIKO_A_CDC_VBAT_GAIN_MON_VAL (0x2FB) +#define TAIKO_A_CDC_VBAT_GAIN_MON_VAL__POR (0x00) +#define TAIKO_A_CDC_PA_RAMP_B1_CTL (0x361) +#define TAIKO_A_CDC_PA_RAMP_B1_CTL__POR (0x00) +#define TAIKO_A_CDC_PA_RAMP_B2_CTL (0x362) +#define TAIKO_A_CDC_PA_RAMP_B2_CTL__POR (0x00) +#define TAIKO_A_CDC_PA_RAMP_B3_CTL (0x363) +#define TAIKO_A_CDC_PA_RAMP_B3_CTL__POR (0x00) +#define TAIKO_A_CDC_PA_RAMP_B4_CTL (0x364) +#define TAIKO_A_CDC_PA_RAMP_B4_CTL__POR (0x00) +#define TAIKO_A_CDC_SPKR_CLIPDET_B1_CTL (0x365) +#define TAIKO_A_CDC_SPKR_CLIPDET_B1_CTL__POR (0x00) + +/* SLIMBUS Slave Registers */ +#define TAIKO_SLIM_PGD_PORT_INT_EN0 (0x30) +#define TAIKO_SLIM_PGD_PORT_INT_STATUS_RX_0 (0x34) +#define TAIKO_SLIM_PGD_PORT_INT_STATUS_RX_1 (0x35) +#define TAIKO_SLIM_PGD_PORT_INT_STATUS_TX_0 (0x36) +#define TAIKO_SLIM_PGD_PORT_INT_STATUS_TX_1 (0x37) +#define TAIKO_SLIM_PGD_PORT_INT_CLR_RX_0 (0x38) +#define TAIKO_SLIM_PGD_PORT_INT_CLR_RX_1 (0x39) +#define TAIKO_SLIM_PGD_PORT_INT_CLR_TX_0 (0x3A) +#define TAIKO_SLIM_PGD_PORT_INT_CLR_TX_1 (0x3B) +#define TAIKO_SLIM_PGD_PORT_INT_RX_SOURCE0 (0x60) +#define TAIKO_SLIM_PGD_PORT_INT_TX_SOURCE0 (0x70) + +/* Macros for Packing Register Writes into a U32 */ +#define TAIKO_PACKED_REG_SIZE sizeof(u32) + +#define TAIKO_CODEC_PACK_ENTRY(reg, mask, val) ((val & 0xff)|\ + ((mask & 0xff) << 8)|((reg & 0xffff) << 16)) + +#define TAIKO_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \ + do { \ + ((reg) = ((packed >> 16) & (0xffff))); \ + ((mask) = ((packed >> 8) & (0xff))); \ + ((val) = ((packed) & (0xff))); \ + } while (0); + +#endif diff --git a/include/uapi/linux/mfd/wcd9xxx/wcd9xxx_registers.h b/include/uapi/linux/mfd/wcd9xxx/wcd9xxx_registers.h new file mode 100644 index 000000000000..7902cfbafad8 --- /dev/null +++ b/include/uapi/linux/mfd/wcd9xxx/wcd9xxx_registers.h @@ -0,0 +1,361 @@ +#ifndef WCD9XXX_CODEC_DIGITAL_H + +#define WCD9XXX_CODEC_DIGITAL_H + +#define WCD9XXX_A_CHIP_CTL (0x00) +#define WCD9XXX_A_CHIP_CTL__POR (0x00000000) +#define WCD9XXX_A_CHIP_STATUS (0x01) +#define WCD9XXX_A_CHIP_STATUS__POR (0x00000000) +#define WCD9XXX_A_CHIP_ID_BYTE_0 (0x04) +#define WCD9XXX_A_CHIP_ID_BYTE_0__POR (0x00000000) +#define WCD9XXX_A_CHIP_ID_BYTE_1 (0x05) +#define WCD9XXX_A_CHIP_ID_BYTE_1__POR (0x00000000) +#define WCD9XXX_A_CHIP_ID_BYTE_2 (0x06) +#define WCD9XXX_A_CHIP_ID_BYTE_2__POR (0x00000000) +#define WCD9XXX_A_CHIP_ID_BYTE_3 (0x07) +#define WCD9XXX_A_CHIP_ID_BYTE_3__POR (0x00000001) +#define WCD9XXX_A_CHIP_VERSION (0x08) +#define WCD9XXX_A_CHIP_VERSION__POR (0x00000020) +#define WCD9XXX_A_SB_VERSION (0x09) +#define WCD9XXX_A_SB_VERSION__POR (0x00000010) +#define WCD9XXX_A_SLAVE_ID_1 (0x0C) +#define WCD9XXX_A_SLAVE_ID_1__POR (0x00000077) +#define WCD9XXX_A_SLAVE_ID_2 (0x0D) +#define WCD9XXX_A_SLAVE_ID_2__POR (0x00000066) +#define WCD9XXX_A_SLAVE_ID_3 (0x0E) +#define WCD9XXX_A_SLAVE_ID_3__POR (0x00000055) +#define WCD9XXX_A_CDC_CTL (0x80) +#define WCD9XXX_A_CDC_CTL__POR (0x00000000) +#define WCD9XXX_A_LEAKAGE_CTL (0x88) +#define WCD9XXX_A_LEAKAGE_CTL__POR (0x00000004) +#define WCD9XXX_A_INTR_MODE (0x90) +#define WCD9XXX_A_INTR_MASK0 (0x94) +#define WCD9XXX_A_INTR_STATUS0 (0x98) +#define WCD9XXX_A_INTR_CLEAR0 (0x9C) +#define WCD9XXX_A_INTR_LEVEL0 (0xA0) +#define WCD9XXX_A_INTR_LEVEL1 (0xA1) +#define WCD9XXX_A_INTR_LEVEL2 (0xA2) +#define WCD9XXX_A_RX_HPH_CNP_EN (0x1AB) +#define WCD9XXX_A_RX_HPH_CNP_EN__POR (0x80) +#define WCD9XXX_A_RX_HPH_CNP_EN (0x1AB) +#define WCD9XXX_A_RX_HPH_CNP_EN__POR (0x80) +#define WCD9XXX_A_BIAS_CENTRAL_BG_CTL (0x101) +#define WCD9XXX_A_BIAS_CENTRAL_BG_CTL__POR (0x50) +#define WCD9XXX_A_CLK_BUFF_EN1 (0x108) +#define WCD9XXX_A_CLK_BUFF_EN1__POR (0x04) +#define WCD9XXX_A_CLK_BUFF_EN2 (0x109) +#define WCD9XXX_A_CLK_BUFF_EN2__POR (0x02) +#define WCD9XXX_A_RX_COM_BIAS (0x1A2) +#define WCD9XXX_A_RX_COM_BIAS__POR (0x00) +#define WCD9XXX_A_RC_OSC_FREQ (0x1FA) +#define WCD9XXX_A_RC_OSC_FREQ__POR (0x46) +#define WCD9XXX_A_BIAS_OSC_BG_CTL (0x105) +#define WCD9XXX_A_BIAS_OSC_BG_CTL__POR (0x16) +#define WCD9XXX_A_RC_OSC_TEST (0x1FB) +#define WCD9XXX_A_RC_OSC_TEST__POR (0x0A) +#define WCD9XXX_A_CDC_CLK_MCLK_CTL (0x311) +#define WCD9XXX_A_CDC_CLK_MCLK_CTL__POR (0x00) + +#define WCD9XXX_A_CDC_MBHC_EN_CTL (0x3C0) +#define WCD9XXX_A_CDC_MBHC_EN_CTL__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_FIR_B1_CFG (0x3C1) +#define WCD9XXX_A_CDC_MBHC_FIR_B1_CFG__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_FIR_B2_CFG (0x3C2) +#define WCD9XXX_A_CDC_MBHC_FIR_B2_CFG__POR (0x06) +#define WCD9XXX_A_CDC_MBHC_TIMER_B1_CTL (0x3C3) +#define WCD9XXX_A_CDC_MBHC_TIMER_B1_CTL__POR (0x03) +#define WCD9XXX_A_CDC_MBHC_TIMER_B2_CTL (0x3C4) +#define WCD9XXX_A_CDC_MBHC_TIMER_B2_CTL__POR (0x09) +#define WCD9XXX_A_CDC_MBHC_TIMER_B3_CTL (0x3C5) +#define WCD9XXX_A_CDC_MBHC_TIMER_B3_CTL__POR (0x1E) +#define WCD9XXX_A_CDC_MBHC_TIMER_B4_CTL (0x3C6) +#define WCD9XXX_A_CDC_MBHC_TIMER_B4_CTL__POR (0x45) +#define WCD9XXX_A_CDC_MBHC_TIMER_B5_CTL (0x3C7) +#define WCD9XXX_A_CDC_MBHC_TIMER_B5_CTL__POR (0x04) +#define WCD9XXX_A_CDC_MBHC_TIMER_B6_CTL (0x3C8) +#define WCD9XXX_A_CDC_MBHC_TIMER_B6_CTL__POR (0x78) +#define WCD9XXX_A_CDC_MBHC_B1_STATUS (0x3C9) +#define WCD9XXX_A_CDC_MBHC_B1_STATUS__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_B2_STATUS (0x3CA) +#define WCD9XXX_A_CDC_MBHC_B2_STATUS__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_B3_STATUS (0x3CB) +#define WCD9XXX_A_CDC_MBHC_B3_STATUS__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_B4_STATUS (0x3CC) +#define WCD9XXX_A_CDC_MBHC_B4_STATUS__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_B5_STATUS (0x3CD) +#define WCD9XXX_A_CDC_MBHC_B5_STATUS__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_B1_CTL (0x3CE) +#define WCD9XXX_A_CDC_MBHC_B1_CTL__POR (0xC0) +#define WCD9XXX_A_CDC_MBHC_B2_CTL (0x3CF) +#define WCD9XXX_A_CDC_MBHC_B2_CTL__POR (0x5D) +#define WCD9XXX_A_CDC_MBHC_VOLT_B1_CTL (0x3D0) +#define WCD9XXX_A_CDC_MBHC_VOLT_B1_CTL__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_VOLT_B2_CTL (0x3D1) +#define WCD9XXX_A_CDC_MBHC_VOLT_B2_CTL__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL (0x3D2) +#define WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL (0x3D3) +#define WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL (0x3D4) +#define WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL (0x3D5) +#define WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_VOLT_B7_CTL (0x3D6) +#define WCD9XXX_A_CDC_MBHC_VOLT_B7_CTL__POR (0xFF) +#define WCD9XXX_A_CDC_MBHC_VOLT_B8_CTL (0x3D7) +#define WCD9XXX_A_CDC_MBHC_VOLT_B8_CTL__POR (0x07) +#define WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL (0x3D8) +#define WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL__POR (0xFF) +#define WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL (0x3D9) +#define WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL__POR (0x7F) +#define WCD9XXX_A_CDC_MBHC_VOLT_B11_CTL (0x3DA) +#define WCD9XXX_A_CDC_MBHC_VOLT_B11_CTL__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_VOLT_B12_CTL (0x3DB) +#define WCD9XXX_A_CDC_MBHC_VOLT_B12_CTL__POR (0x80) +#define WCD9XXX_A_CDC_MBHC_CLK_CTL (0x3DC) +#define WCD9XXX_A_CDC_MBHC_CLK_CTL__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_INT_CTL (0x3DD) +#define WCD9XXX_A_CDC_MBHC_INT_CTL__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_DEBUG_CTL (0x3DE) +#define WCD9XXX_A_CDC_MBHC_DEBUG_CTL__POR (0x00) +#define WCD9XXX_A_CDC_MBHC_SPARE (0x3DF) +#define WCD9XXX_A_CDC_MBHC_SPARE__POR (0x00) +#define WCD9XXX_A_MBHC_SCALING_MUX_1 (0x14E) +#define WCD9XXX_A_MBHC_SCALING_MUX_1__POR (0x00) +#define WCD9XXX_A_RX_HPH_OCP_CTL (0x1AA) +#define WCD9XXX_A_RX_HPH_OCP_CTL__POR (0x68) +#define WCD9XXX_A_MICB_1_CTL (0x12B) +#define WCD9XXX_A_MICB_1_CTL__POR (0x16) +#define WCD9XXX_A_MICB_1_INT_RBIAS (0x12C) +#define WCD9XXX_A_MICB_1_INT_RBIAS__POR (0x24) +#define WCD9XXX_A_MICB_1_MBHC (0x12D) +#define WCD9XXX_A_MICB_1_MBHC__POR (0x01) +#define WCD9XXX_A_MICB_CFILT_2_CTL (0x12E) +#define WCD9XXX_A_MICB_CFILT_2_CTL__POR (0x40) +#define WCD9XXX_A_MICB_CFILT_2_VAL (0x12F) +#define WCD9XXX_A_MICB_CFILT_2_VAL__POR (0x80) +#define WCD9XXX_A_MICB_CFILT_2_PRECHRG (0x130) +#define WCD9XXX_A_MICB_CFILT_2_PRECHRG__POR (0x38) +#define WCD9XXX_A_MICB_2_CTL (0x131) +#define WCD9XXX_A_MICB_2_CTL__POR (0x16) +#define WCD9XXX_A_MICB_2_INT_RBIAS (0x132) +#define WCD9XXX_A_MICB_2_INT_RBIAS__POR (0x24) +#define WCD9XXX_A_MICB_2_MBHC (0x133) +#define WCD9XXX_A_MICB_2_MBHC__POR (0x02) +#define WCD9XXX_A_MICB_CFILT_3_CTL (0x134) +#define WCD9XXX_A_MICB_CFILT_3_CTL__POR (0x40) +#define WCD9XXX_A_MICB_CFILT_3_VAL (0x135) +#define WCD9XXX_A_MICB_CFILT_3_VAL__POR (0x80) +#define WCD9XXX_A_MICB_CFILT_3_PRECHRG (0x136) +#define WCD9XXX_A_MICB_CFILT_3_PRECHRG__POR (0x38) +#define WCD9XXX_A_MICB_3_CTL (0x137) +#define WCD9XXX_A_MICB_3_CTL__POR (0x16) +#define WCD9XXX_A_MICB_3_INT_RBIAS (0x138) +#define WCD9XXX_A_MICB_3_INT_RBIAS__POR (0x24) +#define WCD9XXX_A_MICB_3_MBHC (0x139) +#define WCD9XXX_A_MICB_3_MBHC__POR (0x00) +#define WCD9XXX_A_MICB_4_CTL (0x13D) +#define WCD9XXX_A_MICB_4_CTL__POR (0x16) +#define WCD9XXX_A_MICB_4_INT_RBIAS (0x13E) +#define WCD9XXX_A_MICB_4_INT_RBIAS__POR (0x24) +#define WCD9XXX_A_MICB_4_MBHC (0x13F) +#define WCD9XXX_A_MICB_4_MBHC__POR (0x01) +#define WCD9XXX_A_MICB_CFILT_1_VAL (0x129) +#define WCD9XXX_A_MICB_CFILT_1_VAL__POR (0x80) +#define WCD9XXX_A_RX_HPH_L_STATUS (0x1B3) +#define WCD9XXX_A_RX_HPH_L_STATUS__POR (0x00) +#define WCD9XXX_A_MBHC_HPH (0x1FE) +#define WCD9XXX_A_MBHC_HPH__POR (0x44) +#define WCD9XXX_A_RX_HPH_CNP_WG_TIME (0x1AD) +#define WCD9XXX_A_RX_HPH_CNP_WG_TIME__POR (0x2A) +#define WCD9XXX_A_RX_HPH_R_DAC_CTL (0x1B7) +#define WCD9XXX_A_RX_HPH_R_DAC_CTL__POR (0x00) +#define WCD9XXX_A_RX_HPH_L_DAC_CTL (0x1B1) +#define WCD9XXX_A_RX_HPH_L_DAC_CTL__POR (0x00) +#define WCD9XXX_A_TX_7_MBHC_EN (0x171) +#define WCD9XXX_A_TX_7_MBHC_EN__POR (0x0C) +#define WCD9XXX_A_PIN_CTL_OE0 (0x010) +#define WCD9XXX_A_PIN_CTL_OE0__POR (0x00) +#define WCD9XXX_A_PIN_CTL_OE1 (0x011) +#define WCD9XXX_A_PIN_CTL_OE1__POR (0x00) +#define WCD9XXX_A_MICB_CFILT_1_CTL (0x128) +#define WCD9XXX_A_LDO_H_MODE_1 (0x110) +#define WCD9XXX_A_LDO_H_MODE_1__POR (0x65) +#define WCD9XXX_A_MICB_CFILT_1_CTL__POR (0x40) +#define WCD9XXX_A_TX_7_MBHC_TEST_CTL (0x174) +#define WCD9XXX_A_TX_7_MBHC_TEST_CTL__POR (0x38) +#define WCD9XXX_A_MBHC_SCALING_MUX_2 (0x14F) +#define WCD9XXX_A_MBHC_SCALING_MUX_2__POR (0x80) +#define WCD9XXX_A_TX_COM_BIAS (0x14C) +#define WCD9XXX_A_TX_COM_BIAS__POR (0xF0) + +#define WCD9XXX_A_MBHC_INSERT_DETECT (0x14A) /* TAIKO and later */ +#define WCD9XXX_A_MBHC_INSERT_DETECT__POR (0x00) +#define WCD9XXX_A_MBHC_INSERT_DET_STATUS (0x14B) /* TAIKO and later */ +#define WCD9XXX_A_MBHC_INSERT_DET_STATUS__POR (0x00) +#define WCD9XXX_A_MAD_ANA_CTRL (0x150) +#define WCD9XXX_A_MAD_ANA_CTRL__POR (0xF1) + + +#define WCD9XXX_A_CDC_CLK_OTHR_CTL (0x30C) +#define WCD9XXX_A_CDC_CLK_OTHR_CTL__POR (0x00) + +/* Class H related common registers */ +#define WCD9XXX_A_BUCK_MODE_1 (0x181) +#define WCD9XXX_A_BUCK_MODE_1__POR (0x21) +#define WCD9XXX_A_BUCK_MODE_2 (0x182) +#define WCD9XXX_A_BUCK_MODE_2__POR (0xFF) +#define WCD9XXX_A_BUCK_MODE_3 (0x183) +#define WCD9XXX_A_BUCK_MODE_3__POR (0xCC) +#define WCD9XXX_A_BUCK_MODE_4 (0x184) +#define WCD9XXX_A_BUCK_MODE_4__POR (0x3A) +#define WCD9XXX_A_BUCK_MODE_5 (0x185) +#define WCD9XXX_A_BUCK_MODE_5__POR (0x00) +#define WCD9XXX_A_BUCK_CTRL_VCL_1 (0x186) +#define WCD9XXX_A_BUCK_CTRL_VCL_1__POR (0x48) +#define WCD9XXX_A_BUCK_CTRL_VCL_2 (0x187) +#define WCD9XXX_A_BUCK_CTRL_VCL_2__POR (0xA3) +#define WCD9XXX_A_BUCK_CTRL_VCL_3 (0x188) +#define WCD9XXX_A_BUCK_CTRL_VCL_3__POR (0x82) +#define WCD9XXX_A_BUCK_CTRL_CCL_1 (0x189) +#define WCD9XXX_A_BUCK_CTRL_CCL_1__POR (0xAB) +#define WCD9XXX_A_BUCK_CTRL_CCL_2 (0x18A) +#define WCD9XXX_A_BUCK_CTRL_CCL_2__POR (0xDC) +#define WCD9XXX_A_BUCK_CTRL_CCL_3 (0x18B) +#define WCD9XXX_A_BUCK_CTRL_CCL_3__POR (0x6A) +#define WCD9XXX_A_BUCK_CTRL_CCL_4 (0x18C) +#define WCD9XXX_A_BUCK_CTRL_CCL_4__POR (0x58) +#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_1 (0x18D) +#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_1__POR (0x50) +#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_2 (0x18E) +#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_2__POR (0x64) +#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_3 (0x18F) +#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_3__POR (0x77) +#define WCD9XXX_A_BUCK_TMUX_A_D (0x190) +#define WCD9XXX_A_BUCK_TMUX_A_D__POR (0x00) +#define WCD9XXX_A_NCP_EN (0x192) +#define WCD9XXX_A_NCP_EN__POR (0xFE) +#define WCD9XXX_A_NCP_STATIC (0x194) +#define WCD9XXX_A_NCP_STATIC__POR (0x28) +#define WCD9XXX_A_NCP_BUCKREF (0x191) +#define WCD9XXX_A_NCP_BUCKREF__POR (0x00) +#define WCD9XXX_A_CDC_CLSH_B1_CTL (0x320) +#define WCD9XXX_A_CDC_CLSH_B1_CTL__POR (0xE4) +#define WCD9XXX_A_CDC_CLSH_B2_CTL (0x321) +#define WCD9XXX_A_CDC_CLSH_B2_CTL__POR (0x00) +#define WCD9XXX_A_CDC_CLSH_B3_CTL (0x322) +#define WCD9XXX_A_CDC_CLSH_B3_CTL__POR (0x00) +#define WCD9XXX_A_CDC_CLSH_BUCK_NCP_VARS (0x323) +#define WCD9XXX_A_CDC_CLSH_BUCK_NCP_VARS__POR (0x00) +#define WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD (0x324) +#define WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD__POR (0x12) +#define WCD9XXX_A_CDC_CLSH_IDLE_EAR_THSD (0x325) +#define WCD9XXX_A_CDC_CLSH_IDLE_EAR_THSD__POR (0x0C) +#define WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD (0x326) +#define WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD__POR (0x18) +#define WCD9XXX_A_CDC_CLSH_FCLKONLY_EAR_THSD (0x327) +#define WCD9XXX_A_CDC_CLSH_FCLKONLY_EAR_THSD__POR (0x23) +#define WCD9XXX_A_CDC_CLSH_K_ADDR (0x328) +#define WCD9XXX_A_CDC_CLSH_K_ADDR__POR (0x00) +#define WCD9XXX_A_CDC_CLSH_K_DATA (0x329) +#define WCD9XXX_A_CDC_CLSH_K_DATA__POR (0xA4) +#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L (0x32A) +#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L__POR (0xD7) +#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U (0x32B) +#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U__POR (0x05) +#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_EAR_L (0x32C) +#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_EAR_L__POR (0x60) +#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_EAR_U (0x32D) +#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_EAR_U__POR (0x09) +#define WCD9XXX_A_CDC_CLSH_V_PA_HD_EAR (0x32E) +#define WCD9XXX_A_CDC_CLSH_V_PA_HD_EAR__POR (0x00) +#define WCD9XXX_A_CDC_CLSH_V_PA_HD_HPH (0x32F) +#define WCD9XXX_A_CDC_CLSH_V_PA_HD_HPH__POR (0x00) +#define WCD9XXX_A_CDC_CLSH_V_PA_MIN_EAR (0x330) +#define WCD9XXX_A_CDC_CLSH_V_PA_MIN_EAR__POR (0x00) +#define WCD9XXX_A_CDC_CLSH_V_PA_MIN_HPH (0x331) +#define WCD9XXX_A_CDC_CLSH_V_PA_MIN_HPH__POR (0x00) + +#define WCD9XXX_A_CDC_RX1_B6_CTL (0x2B5) +#define WCD9XXX_A_CDC_RX1_B6_CTL__POR (0x80) +#define WCD9XXX_A_CDC_RX2_B6_CTL (0x2BD) +#define WCD9XXX_A_CDC_RX2_B6_CTL__POR (0x80) +#define WCD9XXX_A_RX_HPH_L_GAIN (0x1AE) +#define WCD9XXX_A_RX_HPH_L_GAIN__POR (0x00) +#define WCD9XXX_A_RX_HPH_R_GAIN (0x1B4) +#define WCD9XXX_A_RX_HPH_R_GAIN__POR (0x00) +#define WCD9XXX_A_RX_HPH_CHOP_CTL (0x1A5) +#define WCD9XXX_A_RX_HPH_CHOP_CTL__POR (0xB4) +#define WCD9XXX_A_RX_HPH_BIAS_PA (0x1A6) +#define WCD9XXX_A_RX_HPH_BIAS_PA__POR (0x7A) +#define WCD9XXX_A_RX_HPH_L_TEST (0x1AF) +#define WCD9XXX_A_RX_HPH_L_TEST__POR (0x00) +#define WCD9XXX_A_RX_HPH_R_TEST (0x1B5) +#define WCD9XXX_A_RX_HPH_R_TEST__POR (0x00) +#define WCD9XXX_A_CDC_CLK_RX_B1_CTL (0x30F) +#define WCD9XXX_A_CDC_CLK_RX_B1_CTL__POR (0x00) +#define WCD9XXX_A_NCP_CLK (0x193) +#define WCD9XXX_A_NCP_CLK__POR (0x94) +#define WCD9XXX_A_RX_HPH_BIAS_WG_OCP (0x1A9) +#define WCD9XXX_A_RX_HPH_BIAS_WG_OCP__POR (0x2A) +#define WCD9XXX_A_RX_HPH_CNP_WG_CTL (0x1AC) +#define WCD9XXX_A_RX_HPH_CNP_WG_CTL__POR (0xDE) +#define WCD9XXX_A_RX_HPH_L_PA_CTL (0x1B0) +#define WCD9XXX_A_RX_HPH_L_PA_CTL__POR (0x42) +#define WCD9XXX_A_RX_HPH_R_PA_CTL (0x1B6) +#define WCD9XXX_A_RX_HPH_R_PA_CTL__POR (0x42) +#define WCD9XXX_A_CDC_CONN_RX2_B1_CTL (0x383) +#define WCD9XXX_A_CDC_CONN_RX2_B1_CTL__POR (0x00) +#define WCD9XXX_A_CDC_PA_RAMP_B1_CTL (0x361) +#define WCD9XXX_A_CDC_PA_RAMP_B1_CTL__POR (0x00) +#define WCD9XXX_A_CDC_PA_RAMP_B2_CTL (0x362) +#define WCD9XXX_A_CDC_PA_RAMP_B2_CTL__POR (0x00) +#define WCD9XXX_A_CDC_PA_RAMP_B3_CTL (0x363) +#define WCD9XXX_A_CDC_PA_RAMP_B3_CTL__POR (0x00) +#define WCD9XXX_A_CDC_PA_RAMP_B4_CTL (0x364) +#define WCD9XXX_A_CDC_PA_RAMP_B4_CTL__POR (0x00) + +#define WCD9330_A_LEAKAGE_CTL (0x03C) +#define WCD9330_A_LEAKAGE_CTL__POR (0x04) +#define WCD9330_A_CDC_CTL (0x034) +#define WCD9330_A_CDC_CTL__POR (0x00) + +/* Class-H registers for codecs from and above WCD9335 */ +#define WCD9XXX_A_CDC_RX0_RX_PATH_CFG0 (0xB42) +#define WCD9XXX_A_CDC_RX1_RX_PATH_CFG0 (0xB56) +#define WCD9XXX_A_CDC_RX2_RX_PATH_CFG0 (0xB6A) +#define WCD9XXX_A_CDC_CLSH_K1_MSB (0xC08) +#define WCD9XXX_A_CDC_CLSH_K1_LSB (0xC09) +#define WCD9XXX_A_ANA_RX_SUPPLIES (0x608) +#define WCD9XXX_A_ANA_HPH (0x609) +#define WCD9XXX_A_CDC_CLSH_CRC (0xC01) +#define WCD9XXX_FLYBACK_EN (0x6A4) +#define WCD9XXX_FLYBACK_VNEG_CTRL_1 (0x6A5) +#define WCD9XXX_FLYBACK_VNEGDAC_CTRL_2 (0x6AF) +#define WCD9XXX_RX_BIAS_FLYB_BUFF (0x6C7) +#define WCD9XXX_HPH_L_EN (0x6D3) +#define WCD9XXX_HPH_R_EN (0x6D6) +#define WCD9XXX_HPH_REFBUFF_UHQA_CTL (0x6DD) +#define WCD9XXX_CLASSH_CTRL_VCL_2 (0x69B) +#define WCD9XXX_CDC_CLSH_HPH_V_PA (0xC04) +#define WCD9XXX_CDC_RX0_RX_PATH_SEC0 (0xB49) +#define WCD9XXX_CDC_RX1_RX_PATH_CTL (0xB55) +#define WCD9XXX_CDC_RX2_RX_PATH_CTL (0xB69) +#define WCD9XXX_CDC_CLK_RST_CTRL_MCLK_CONTROL (0xD41) +#define WCD9XXX_CLASSH_CTRL_CCL_1 (0x69C) + +/* RX Gain control registers of codecs from and above WCD9335 */ +#define WCD9XXX_CDC_RX1_RX_VOL_CTL (0xB59) +#define WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL (0xB5C) +#define WCD9XXX_CDC_RX1_RX_PATH_SEC1 (0xB5E) +#define WCD9XXX_CDC_RX2_RX_VOL_CTL (0xB6D) +#define WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL (0xB70) +#define WCD9XXX_CDC_RX2_RX_PATH_SEC1 (0xB72) + +/* Class-H registers for codecs from and above WCD934X */ +#define WCD9XXX_HPH_CNP_WG_CTL (0x06cc) +#define WCD9XXX_FLYBACK_VNEG_CTRL_4 (0x06a8) +#define WCD9XXX_HPH_NEW_INT_PA_MISC2 (0x0738) +#define WCD9XXX_RX_BIAS_HPH_LOWPOWER (0x06bf) +#define WCD9XXX_HPH_PA_CTL1 (0x06d1) +#endif -- GitLab From 5106b5627c098e0631645a9ef44e8498a63bd0b2 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 8 Jan 2018 13:16:32 +0530 Subject: [PATCH 0144/1645] dsp: fix low volume in audio recording ADM calibration is not sent in audio recording use case which leads to low volume issue. Since the LSM port ID is same as audio recording port ID in case of internal codec, driver tries to send LSM calibration for non LSM use case in which case no calibration will be sent. Instead of using port ID, use the pass_thr mode to differentiate between LSM and non LSM use cases. CRs-Fixed: 2167317 Change-Id: I1b6ea51d83330f6439791cf1bb6170306f6895b0 Signed-off-by: Aditya Bavanari --- asoc/msm-pcm-routing-v2.c | 1 - dsp/q6adm.c | 24 ++++++------------------ include/dsp/q6adm-v2.h | 3 +-- 3 files changed, 7 insertions(+), 21 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 1ff7c41222df..c0bc05736298 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -2572,7 +2572,6 @@ static int msm_routing_lsm_func_put(struct snd_kcontrol *kcontrol, pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, mad_type); - adm_set_lsm_port_id(port_id); return afe_port_set_mad_type(port_id, mad_type); } diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 514af254db99..d5dc960de4a0 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -104,7 +104,6 @@ struct adm_ctl { int num_ec_ref_rx_chans; int ec_ref_rx_bit_width; int ec_ref_rx_sampling_rate; - int lsm_port_id; }; static struct adm_ctl this_adm; @@ -2299,25 +2298,13 @@ static int get_cal_path(int path) return TX_DEVICE; } -/* - * Command to set LSM port ID - * which is used to send LSM cal - * - * @port_id: Port ID number to be set - * - */ -void adm_set_lsm_port_id(int port_id) -{ - this_adm.lsm_port_id = port_id; -} -EXPORT_SYMBOL(adm_set_lsm_port_id); - static void send_adm_cal(int port_id, int copp_idx, int path, int perf_mode, - int app_type, int acdb_id, int sample_rate) + int app_type, int acdb_id, int sample_rate, + int passthr_mode) { pr_debug("%s: port id 0x%x copp_idx %d\n", __func__, port_id, copp_idx); - if (port_id != this_adm.lsm_port_id) + if (passthr_mode != LISTEN) send_adm_cal_type(ADM_AUDPROC_CAL, path, port_id, copp_idx, perf_mode, app_type, acdb_id, sample_rate); else @@ -3083,7 +3070,8 @@ int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode, get_cal_path(path), perf_mode, payload_map.app_type[i], payload_map.acdb_dev_id[i], - payload_map.sample_rate[i]); + payload_map.sample_rate[i], + passthr_mode); /* ADM COPP calibration is already sent */ clear_bit(ADM_STATUS_CALIBRATION_REQUIRED, (void *)&this_adm.copp. diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 19a844c316e3..881943b464c3 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -187,5 +187,4 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, int channel_index); void msm_dts_srs_acquire_lock(void); void msm_dts_srs_release_lock(void); -void adm_set_lsm_port_id(int port_id); #endif /* __Q6_ADM_V2_H__ */ -- GitLab From ecc4edaf8338d0806cc157727a43079b71176646 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Wed, 13 Dec 2017 16:24:10 -0800 Subject: [PATCH 0145/1645] asoc: codecs: re-factor audio-ext-clk driver Re-factor audio clock driver to register one clock at a time and remove duplicate lpass clocks. Change-Id: I63ddf4b65ec7e9cda0dcad4e0167cd8636e89e1a Signed-off-by: Vidyakumar Athota --- asoc/codecs/audio-ext-clk-up.c | 603 ++++++++++----------------------- 1 file changed, 184 insertions(+), 419 deletions(-) diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index 50a8ed6fc014..d20aab2c83b2 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -19,16 +19,15 @@ #include #include "../../../drivers/clk/qcom/common.h" #include -#include -#include #include #include #include "audio-ext-clk-up.h" -enum audio_clk_mux { - AP_CLK2, - LPASS_MCLK, - LPASS_MCLK2, +enum { + AUDIO_EXT_CLK_PMI, + AUDIO_EXT_CLK_LNBB2, + AUDIO_EXT_CLK_LPASS, + AUDIO_EXT_CLK_MAX, }; struct pinctrl_info { @@ -38,152 +37,37 @@ struct pinctrl_info { char __iomem *base; }; -struct audio_ext_ap_clk { - bool enabled; - int gpio; - struct clk_fixed_factor fact; -}; - -struct audio_ext_pmi_clk { - int gpio; - struct clk_fixed_factor fact; -}; - -struct audio_ext_ap_clk2 { - bool enabled; +struct audio_ext_clk { struct pinctrl_info pnctrl_info; struct clk_fixed_factor fact; }; -struct audio_ext_lpass_mclk { - struct pinctrl_info pnctrl_info; - struct clk_fixed_factor fact; -}; - -static struct afe_clk_set clk2_config = { - Q6AFE_LPASS_CLK_CONFIG_API_VERSION, - Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR, - Q6AFE_LPASS_IBIT_CLK_11_P2896_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, -}; - -static struct afe_clk_set lpass_default = { - Q6AFE_LPASS_CLK_CONFIG_API_VERSION, - Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR, - Q6AFE_LPASS_IBIT_CLK_11_P2896_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, +struct audio_ext_clk_priv { + struct device *dev; + int clk_src; + struct afe_clk_set clk_cfg; + struct audio_ext_clk audio_clk; }; -static struct afe_clk_set lpass_mclk = { - Q6AFE_LPASS_CLK_CONFIG_API_VERSION, - Q6AFE_LPASS_CLK_ID_MCLK_1, - Q6AFE_LPASS_OSR_CLK_11_P2896_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, -}; - -static inline struct audio_ext_ap_clk *to_audio_ap_clk(struct clk_hw *hw) +static inline struct audio_ext_clk_priv *to_audio_clk(struct clk_hw *hw) { - return container_of(hw, struct audio_ext_ap_clk, fact.hw); + return container_of(hw, struct audio_ext_clk_priv, audio_clk.fact.hw); } static int audio_ext_clk_prepare(struct clk_hw *hw) { - struct audio_ext_ap_clk *audio_clk = to_audio_ap_clk(hw); - - pr_debug("%s: gpio: %d\n", __func__, audio_clk->gpio); - if (gpio_is_valid(audio_clk->gpio)) - return gpio_direction_output(audio_clk->gpio, 1); - return 0; -} - -static void audio_ext_clk_unprepare(struct clk_hw *hw) -{ - struct audio_ext_ap_clk *audio_clk = to_audio_ap_clk(hw); - - pr_debug("%s: gpio: %d\n", __func__, audio_clk->gpio); - if (gpio_is_valid(audio_clk->gpio)) - gpio_direction_output(audio_clk->gpio, 0); -} - -static inline struct audio_ext_ap_clk2 *to_audio_ap_clk2(struct clk_hw *hw) -{ - return container_of(hw, struct audio_ext_ap_clk2, fact.hw); -} - -static int audio_ext_clk2_prepare(struct clk_hw *hw) -{ - struct audio_ext_ap_clk2 *audio_clk2 = to_audio_ap_clk2(hw); - struct pinctrl_info *pnctrl_info = &audio_clk2->pnctrl_info; - int ret; - - - if (!pnctrl_info->pinctrl || !pnctrl_info->active) - return 0; - - ret = pinctrl_select_state(pnctrl_info->pinctrl, - pnctrl_info->active); - if (ret) { - pr_err("%s: active state select failed with %d\n", - __func__, ret); - return -EIO; - } - - clk2_config.enable = 1; - ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk2_config); - if (ret < 0) { - pr_err("%s: failed to set clock, ret = %d\n", __func__, ret); - return -EINVAL; - } - - return 0; -} - -static void audio_ext_clk2_unprepare(struct clk_hw *hw) -{ - struct audio_ext_ap_clk2 *audio_clk2 = to_audio_ap_clk2(hw); - struct pinctrl_info *pnctrl_info = &audio_clk2->pnctrl_info; - int ret; - - if (!pnctrl_info->pinctrl || !pnctrl_info->sleep) - return; - - ret = pinctrl_select_state(pnctrl_info->pinctrl, - pnctrl_info->sleep); - if (ret) - pr_err("%s: sleep state select failed with %d\n", - __func__, ret); - - clk2_config.enable = 0; - ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk2_config); - if (ret < 0) - pr_err("%s: failed to reset clock, ret = %d\n", __func__, ret); -} - -static inline struct audio_ext_lpass_mclk *to_audio_lpass_mclk( - struct clk_hw *hw) -{ - return container_of(hw, struct audio_ext_lpass_mclk, fact.hw); -} - -static int audio_ext_lpass_mclk_prepare(struct clk_hw *hw) -{ - struct audio_ext_lpass_mclk *audio_lpass_mclk = to_audio_lpass_mclk(hw); - struct pinctrl_info *pnctrl_info = &audio_lpass_mclk->pnctrl_info; + struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw); + struct pinctrl_info *pnctrl_info = &clk_priv->audio_clk.pnctrl_info; int ret; - lpass_mclk.enable = 1; - ret = afe_set_lpass_clock_v2(AFE_PORT_ID_PRIMARY_MI2S_RX, - &lpass_mclk); - if (ret < 0) { - pr_err("%s afe_set_digital_codec_core_clock failed\n", - __func__); - return ret; + if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS) { + clk_priv->clk_cfg.enable = 1; + ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg); + if (ret < 0) { + pr_err("%s afe_set_digital_codec_core_clock failed\n", + __func__); + return ret; + } } if (pnctrl_info->pinctrl) { @@ -201,10 +85,10 @@ static int audio_ext_lpass_mclk_prepare(struct clk_hw *hw) return 0; } -static void audio_ext_lpass_mclk_unprepare(struct clk_hw *hw) +static void audio_ext_clk_unprepare(struct clk_hw *hw) { - struct audio_ext_lpass_mclk *audio_lpass_mclk = to_audio_lpass_mclk(hw); - struct pinctrl_info *pnctrl_info = &audio_lpass_mclk->pnctrl_info; + struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw); + struct pinctrl_info *pnctrl_info = &clk_priv->audio_clk.pnctrl_info; int ret; if (pnctrl_info->pinctrl) { @@ -217,207 +101,90 @@ static void audio_ext_lpass_mclk_unprepare(struct clk_hw *hw) } } - lpass_mclk.enable = 0; - ret = afe_set_lpass_clock_v2(AFE_PORT_ID_PRIMARY_MI2S_RX, - &lpass_mclk); - if (ret < 0) - pr_err("%s: afe_set_digital_codec_core_clock failed, ret = %d\n", - __func__, ret); - if (pnctrl_info->base) - iowrite32(0, pnctrl_info->base); -} - -static int audio_ext_lpass_mclk2_prepare(struct clk_hw *hw) -{ - struct audio_ext_lpass_mclk *audio_lpass_mclk2 = - to_audio_lpass_mclk(hw); - struct pinctrl_info *pnctrl_info = &audio_lpass_mclk2->pnctrl_info; - int ret; - - if (pnctrl_info->pinctrl) { - ret = pinctrl_select_state(pnctrl_info->pinctrl, - pnctrl_info->active); - if (ret) { - pr_err("%s: active state select failed with %d\n", - __func__, ret); - return -EIO; - } - } - - lpass_default.enable = 1; - ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &lpass_default); - if (ret < 0) { - pr_err("%s: failed to set clock, ret = %d\n", __func__, ret); - return -EINVAL; - } - - return 0; -} - -static void audio_ext_lpass_mclk2_unprepare(struct clk_hw *hw) -{ - struct audio_ext_lpass_mclk *audio_lpass_mclk2 = - to_audio_lpass_mclk(hw); - struct pinctrl_info *pnctrl_info = &audio_lpass_mclk2->pnctrl_info; - int ret; - - if (pnctrl_info->pinctrl) { - ret = pinctrl_select_state(pnctrl_info->pinctrl, - pnctrl_info->sleep); - if (ret) - pr_err("%s: sleep state select failed with %d\n", + if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS) { + clk_priv->clk_cfg.enable = 0; + ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg); + if (ret < 0) + pr_err("%s: afe_set_lpass_clk_cfg failed, ret = %d\n", __func__, ret); } - lpass_default.enable = 0; - ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &lpass_default); - if (ret < 0) - pr_err("%s: failed to reset clock, ret = %d\n", __func__, ret); + if (pnctrl_info->base) + iowrite32(0, pnctrl_info->base); } -static const struct clk_ops audio_ext_ap_clk_ops = { +static const struct clk_ops audio_ext_clk_ops = { .prepare = audio_ext_clk_prepare, .unprepare = audio_ext_clk_unprepare, }; -static const struct clk_ops audio_ext_ap_clk2_ops = { - .prepare = audio_ext_clk2_prepare, - .unprepare = audio_ext_clk2_unprepare, -}; - -static const struct clk_ops audio_ext_lpass_mclk_ops = { - .prepare = audio_ext_lpass_mclk_prepare, - .unprepare = audio_ext_lpass_mclk_unprepare, -}; - -static const struct clk_ops audio_ext_lpass_mclk2_ops = { - .prepare = audio_ext_lpass_mclk2_prepare, - .unprepare = audio_ext_lpass_mclk2_unprepare, -}; - -static struct audio_ext_pmi_clk audio_pmi_clk = { - .gpio = -EINVAL, - .fact = { - .mult = 1, - .div = 1, - .hw.init = &(struct clk_init_data){ - .name = "audio_ext_pmi_clk", - .parent_names = (const char *[]){ "div_clk1" }, - .num_parents = 1, - .ops = &clk_dummy_ops, - }, - }, -}; - -static struct audio_ext_pmi_clk audio_pmi_lnbb_clk = { - .gpio = -EINVAL, - .fact = { - .mult = 1, - .div = 1, - .hw.init = &(struct clk_init_data){ - .name = "audio_ext_pmi_lnbb_clk", - .parent_names = (const char *[]){ "ln_bb_clk2" }, - .num_parents = 1, - .ops = &clk_dummy_ops, +static struct audio_ext_clk audio_clk_array[] = { + { + .pnctrl_info = {NULL}, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_ext_pmi_clk", + .parent_names = (const char *[]) + { "qpnp_clkdiv_1" }, + .num_parents = 1, + .ops = &audio_ext_clk_ops, + }, }, }, -}; - -static struct audio_ext_ap_clk audio_ap_clk = { - .gpio = -EINVAL, - .fact = { - .mult = 1, - .div = 1, - .hw.init = &(struct clk_init_data){ - .name = "audio_ap_clk", - .ops = &audio_ext_ap_clk_ops, - }, - }, -}; - -static struct audio_ext_ap_clk2 audio_ap_clk2 = { - .enabled = false, - .pnctrl_info = {NULL}, - .fact = { - .mult = 1, - .div = 1, - .hw.init = &(struct clk_init_data){ - .name = "audio_ap_clk2", - .ops = &audio_ext_ap_clk2_ops, + { + .pnctrl_info = {NULL}, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_ext_pmi_lnbb_clk", + .parent_names = (const char *[]) + { "ln_bb_clk2" }, + .num_parents = 1, + .ops = &clk_dummy_ops, + }, }, }, -}; - -static struct audio_ext_lpass_mclk audio_lpass_mclk = { - .pnctrl_info = {NULL}, - .fact = { - .mult = 1, - .div = 1, - .hw.init = &(struct clk_init_data){ - .name = "audio_lpass_mclk", - .ops = &audio_ext_lpass_mclk_ops, - }, - }, -}; - -static struct audio_ext_lpass_mclk audio_lpass_mclk2 = { - .pnctrl_info = {NULL}, - .fact = { - .mult = 1, - .div = 1, - .hw.init = &(struct clk_init_data){ - .name = "audio_lpass_mclk2", - .ops = &audio_ext_lpass_mclk2_ops, + { + .pnctrl_info = {NULL}, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_lpass_mclk", + .ops = &audio_ext_clk_ops, + }, }, }, }; -static struct clk_hw *audio_msm_hws[] = { - &audio_pmi_clk.fact.hw, - &audio_ap_clk.fact.hw, - &audio_ap_clk2.fact.hw, - &audio_lpass_mclk.fact.hw, - &audio_lpass_mclk2.fact.hw, -}; - -static struct clk_hw *audio_msm_hws1[] = { - &audio_pmi_lnbb_clk.fact.hw, -}; - -static int audio_get_pinctrl(struct platform_device *pdev, - enum audio_clk_mux mux) +static int audio_get_pinctrl(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct audio_ext_clk_priv *clk_priv = platform_get_drvdata(pdev); struct pinctrl_info *pnctrl_info; struct pinctrl *pinctrl; int ret; u32 reg; - switch (mux) { - case AP_CLK2: - pnctrl_info = &audio_ap_clk2.pnctrl_info; - break; - case LPASS_MCLK: - pnctrl_info = &audio_lpass_mclk.pnctrl_info; - break; - case LPASS_MCLK2: - pnctrl_info = &audio_lpass_mclk2.pnctrl_info; - break; - default: - dev_err(dev, "%s Not a valid MUX ID: %d\n", - __func__, mux); - return -EINVAL; + if (clk_priv->clk_src == AUDIO_EXT_CLK_LNBB2) { + dev_dbg(dev, "%s no pinctrl for clk_src = %d\n", + __func__, clk_priv->clk_src); + return 0; } + pnctrl_info = &clk_priv->audio_clk.pnctrl_info; if (pnctrl_info->pinctrl) { - dev_dbg(dev, "%s: already requested before\n", + dev_err(dev, "%s: already requested before\n", __func__); return -EINVAL; } pinctrl = devm_pinctrl_get(dev); if (IS_ERR_OR_NULL(pinctrl)) { - dev_dbg(dev, "%s: Unable to get pinctrl handle\n", + dev_err(dev, "%s: Unable to get pinctrl handle\n", __func__); return -EINVAL; } @@ -462,136 +229,134 @@ static int audio_get_pinctrl(struct platform_device *pdev, return -EINVAL; } -static int audio_ref_clk_probe(struct platform_device *pdev) +static int audio_put_pinctrl(struct platform_device *pdev) +{ + struct audio_ext_clk_priv *clk_priv = platform_get_drvdata(pdev); + struct pinctrl_info *pnctrl_info = NULL; + + pnctrl_info = &clk_priv->audio_clk.pnctrl_info; + if (pnctrl_info && pnctrl_info->pinctrl) { + devm_pinctrl_put(pnctrl_info->pinctrl); + pnctrl_info->pinctrl = NULL; + } + + return 0; +} + +static int audio_get_clk_data(struct platform_device *pdev) { - int clk_gpio; int ret; - u32 mclk_freq; struct clk *audio_clk; - struct device *dev = &pdev->dev; - int i; + struct clk_hw *clkhw; struct clk_onecell_data *clk_data; + struct audio_ext_clk_priv *clk_priv = platform_get_drvdata(pdev); - ret = of_property_read_u32(pdev->dev.of_node, - "qcom,codec-mclk-clk-freq", - &mclk_freq); - if (!ret) { - lpass_mclk.clk_freq_in_hz = mclk_freq; - - ret = audio_get_pinctrl(pdev, LPASS_MCLK); - if (ret) - dev_err(&pdev->dev, "%s: Parsing pinctrl %s failed\n", - __func__, "LPASS_MCLK"); - ret = audio_get_pinctrl(pdev, LPASS_MCLK2); - if (ret) - dev_dbg(&pdev->dev, "%s: Parsing pinctrl %s failed\n", - __func__, "LPASS_MCLK2"); + clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->clk_num = 1; + clk_data->clks = devm_kzalloc(&pdev->dev, + sizeof(struct clk *), + GFP_KERNEL); + if (!clk_data->clks) + return -ENOMEM; + + clkhw = &clk_priv->audio_clk.fact.hw; + audio_clk = devm_clk_register(&pdev->dev, clkhw); + if (IS_ERR(audio_clk)) { + dev_err(&pdev->dev, + "%s: clock register failed for clk_src = %d\\n", + __func__, clk_priv->clk_src); + ret = PTR_ERR(audio_clk); + return ret; } + clk_data->clks[0] = audio_clk; - clk_gpio = of_get_named_gpio(pdev->dev.of_node, - "qcom,audio-ref-clk-gpio", 0); - if (clk_gpio > 0) { - ret = gpio_request(clk_gpio, "EXT_CLK"); - if (ret) { - dev_err(&pdev->dev, - "Request ext clk gpio failed %d, err:%d\n", - clk_gpio, ret); - goto err; - } - if (of_property_read_bool(pdev->dev.of_node, - "qcom,node_has_rpm_clock")) { - audio_pmi_clk.gpio = clk_gpio; - } else - audio_ap_clk.gpio = clk_gpio; + ret = of_clk_add_provider(pdev->dev.of_node, + of_clk_src_onecell_get, clk_data); + if (ret) + dev_err(&pdev->dev, "%s: clock add failed for clk_src = %d\n", + __func__, clk_priv->clk_src); + + return ret; +} + +static int audio_ref_clk_probe(struct platform_device *pdev) +{ + int ret; + struct audio_ext_clk_priv *clk_priv; + u32 clk_freq = 0, clk_id = 0, clk_src = 0; + + clk_priv = devm_kzalloc(&pdev->dev, sizeof(*clk_priv), GFP_KERNEL); + if (!clk_priv) + return -ENOMEM; + + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,codec-ext-clk-src", + &clk_src); + if (ret) { + dev_err(&pdev->dev, "%s: could not get clk source, ret = %d\n", + __func__, ret); + return ret; } - ret = audio_get_pinctrl(pdev, AP_CLK2); - if (ret) - dev_dbg(&pdev->dev, "%s: Parsing pinctrl failed\n", - __func__); + if (clk_src >= AUDIO_EXT_CLK_MAX) { + dev_err(&pdev->dev, "%s: Invalid clk source = %d\n", + __func__, clk_src); + return -EINVAL; + } - clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL); - if (!clk_data) - goto err_gpio; - - - clk_gpio = of_get_named_gpio(pdev->dev.of_node, - "qcom,audio-ref-clk-gpio", 0); - if (clk_gpio > 0) { - clk_data->clk_num = ARRAY_SIZE(audio_msm_hws); - clk_data->clks = devm_kzalloc(&pdev->dev, - clk_data->clk_num * - sizeof(struct clk *), - GFP_KERNEL); - if (!clk_data->clks) - goto err_clk; - - for (i = 0; i < ARRAY_SIZE(audio_msm_hws); i++) { - audio_clk = devm_clk_register(dev, audio_msm_hws[i]); - if (IS_ERR(audio_clk)) { - dev_err(&pdev->dev, - "%s: ref clock: %d register failed\n", - __func__, i); - return PTR_ERR(audio_clk); - } - clk_data->clks[i] = audio_clk; - } - } else { - clk_data->clk_num = ARRAY_SIZE(audio_msm_hws1); - clk_data->clks = devm_kzalloc(&pdev->dev, - clk_data->clk_num * - sizeof(struct clk *), - GFP_KERNEL); - if (!clk_data->clks) - goto err_clk; - - for (i = 0; i < ARRAY_SIZE(audio_msm_hws1); i++) { - audio_clk = devm_clk_register(dev, audio_msm_hws1[i]); - if (IS_ERR(audio_clk)) { - dev_err(&pdev->dev, - "%s: ref clock: %d register failed\n", - __func__, i); - return PTR_ERR(audio_clk); - } - clk_data->clks[i] = audio_clk; - } + clk_priv->clk_src = clk_src; + memcpy(&clk_priv->audio_clk, &audio_clk_array[clk_src], + sizeof(struct audio_ext_clk)); + + /* Init lpass clk default values */ + clk_priv->clk_cfg.clk_set_minor_version = + Q6AFE_LPASS_CLK_CONFIG_API_VERSION; + clk_priv->clk_cfg.clk_id = Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR; + clk_priv->clk_cfg.clk_freq_in_hz = Q6AFE_LPASS_OSR_CLK_9_P600_MHZ; + clk_priv->clk_cfg.clk_attri = Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO; + + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,codec-lpass-ext-clk-freq", + &clk_freq); + if (!ret) + clk_priv->clk_cfg.clk_freq_in_hz = clk_freq; + + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,codec-lpass-clk-id", + &clk_id); + if (!ret) + clk_priv->clk_cfg.clk_id = clk_id; + + dev_dbg(&pdev->dev, "%s: ext-clk freq: %d, lpass clk_id: %d, clk_src: %d\n", + __func__, clk_priv->clk_cfg.clk_freq_in_hz, + clk_priv->clk_cfg.clk_id, clk_priv->clk_src); + platform_set_drvdata(pdev, clk_priv); + + ret = audio_get_pinctrl(pdev); + if (ret) { + dev_err(&pdev->dev, "%s: Parsing PMI pinctrl failed\n", + __func__); + return ret; } - ret = of_clk_add_provider(pdev->dev.of_node, - of_clk_src_onecell_get, clk_data); + ret = audio_get_clk_data(pdev); if (ret) { - dev_err(&pdev->dev, "%s: audio ref clock register failed\n", + dev_err(&pdev->dev, "%s: clk_init is failed\n", __func__); - goto err_gpio; + audio_put_pinctrl(pdev); + return ret; } return 0; - -err_clk: - if (clk_data) - devm_kfree(&pdev->dev, clk_data->clks); - devm_kfree(&pdev->dev, clk_data); -err_gpio: - gpio_free(clk_gpio); - -err: - return ret; } static int audio_ref_clk_remove(struct platform_device *pdev) { - struct pinctrl_info *pnctrl_info = &audio_ap_clk2.pnctrl_info; - - if (audio_pmi_clk.gpio > 0) - gpio_free(audio_pmi_clk.gpio); - else if (audio_ap_clk.gpio > 0) - gpio_free(audio_ap_clk.gpio); - - if (pnctrl_info->pinctrl) { - devm_pinctrl_put(pnctrl_info->pinctrl); - pnctrl_info->pinctrl = NULL; - } + audio_put_pinctrl(pdev); return 0; } -- GitLab From cd2fa5348edf8e88844de84088e85077286688a1 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Wed, 17 Jan 2018 17:42:46 -0800 Subject: [PATCH 0146/1645] codecs: add on-demand supply support Add new APIs to enable/disable on-demand codec supplies to msm-cdc-supply driver. Change-Id: Iaf33ac40165832595c875e26179dc036b62b36f8 Signed-off-by: Vidyakumar Athota --- asoc/codecs/msm-cdc-supply.c | 102 ++++++++++++++++++++++++++++++++++- asoc/codecs/msm-cdc-supply.h | 10 +++- 2 files changed, 110 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/msm-cdc-supply.c b/asoc/codecs/msm-cdc-supply.c index e36baa82ac98..6687ec58a746 100644 --- a/asoc/codecs/msm-cdc-supply.c +++ b/asoc/codecs/msm-cdc-supply.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -126,6 +126,106 @@ static int msm_cdc_check_supply_param(struct device *dev, return 0; } +/* + * msm_cdc_disable_ondemand_supply: + * Disable codec ondemand supply + * + * @dev: pointer to codec device + * @supplies: pointer to regulator bulk data + * @cdc_vreg: pointer to platform regulator data + * @num_supplies: number of supplies + * @supply_name: Ondemand supply name to be enabled + * + * Return error code if supply disable is failed + */ +int msm_cdc_disable_ondemand_supply(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies, + char *supply_name) +{ + int rc, i; + + if ((!supply_name) || (!supplies)) { + pr_err("%s: either dev or supplies or cdc_vreg is NULL\n", + __func__); + return -EINVAL; + } + /* input parameter validation */ + rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies); + if (rc) + return rc; + + for (i = 0; i < num_supplies; i++) { + if (cdc_vreg[i].ondemand && + !strcmp(cdc_vreg[i].name, supply_name)) { + rc = regulator_disable(supplies[i].consumer); + if (rc) + dev_err(dev, "%s: failed to disable supply %s, err:%d\n", + __func__, supplies[i].supply, rc); + break; + } + } + if (i == num_supplies) { + dev_err(dev, "%s: not able to find supply %s\n", + __func__, supply_name); + rc = -EINVAL; + } + + return rc; +} +EXPORT_SYMBOL(msm_cdc_disable_ondemand_supply); + +/* + * msm_cdc_enable_ondemand_supply: + * Enable codec ondemand supply + * + * @dev: pointer to codec device + * @supplies: pointer to regulator bulk data + * @cdc_vreg: pointer to platform regulator data + * @num_supplies: number of supplies + * @supply_name: Ondemand supply name to be enabled + * + * Return error code if supply enable is failed + */ +int msm_cdc_enable_ondemand_supply(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies, + char *supply_name) +{ + int rc, i; + + if ((!supply_name) || (!supplies)) { + pr_err("%s: either dev or supplies or cdc_vreg is NULL\n", + __func__); + return -EINVAL; + } + /* input parameter validation */ + rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies); + if (rc) + return rc; + + for (i = 0; i < num_supplies; i++) { + if (cdc_vreg[i].ondemand && + !strcmp(cdc_vreg[i].name, supply_name)) { + rc = regulator_enable(supplies[i].consumer); + if (rc) + dev_err(dev, "%s: failed to enable supply %s, rc: %d\n", + __func__, supplies[i].supply, rc); + break; + } + } + if (i == num_supplies) { + dev_err(dev, "%s: not able to find supply %s\n", + __func__, supply_name); + rc = -EINVAL; + } + + return rc; +} +EXPORT_SYMBOL(msm_cdc_enable_ondemand_supply); + /* * msm_cdc_disable_static_supplies: * Disable codec static supplies diff --git a/asoc/codecs/msm-cdc-supply.h b/asoc/codecs/msm-cdc-supply.h index b40f44b1f12f..b6516fa944be 100644 --- a/asoc/codecs/msm-cdc-supply.h +++ b/asoc/codecs/msm-cdc-supply.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016, 2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -29,6 +29,14 @@ struct cdc_regulator { extern int msm_cdc_get_power_supplies(struct device *dev, struct cdc_regulator **cdc_vreg, int *total_num_supplies); +extern int msm_cdc_disable_ondemand_supply(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies, char *supply_name); +extern int msm_cdc_enable_ondemand_supply(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies, char *supply_name); extern int msm_cdc_disable_static_supplies(struct device *dev, struct regulator_bulk_data *supplies, struct cdc_regulator *cdc_vreg, -- GitLab From 7206c72494e36a3e70acdb499bc9aebdfcdfd6c7 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Tue, 5 Dec 2017 11:43:47 -0800 Subject: [PATCH 0147/1645] ipc: wcd-dsp-glink: move wdsp ipc to rpmsg Add support for wdsp communication over rpmsg to enable inter process communication between application processor and codec DSP. Change-Id: I6679e9d8b104bbd41e19bbf788a41129dc97da88 Signed-off-by: Vidyakumar Athota --- ipc/wcd-dsp-glink.c | 1062 +++++++++++++------------------------------ 1 file changed, 304 insertions(+), 758 deletions(-) diff --git a/ipc/wcd-dsp-glink.c b/ipc/wcd-dsp-glink.c index 400fd0617360..04df026579ad 100644 --- a/ipc/wcd-dsp-glink.c +++ b/ipc/wcd-dsp-glink.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -13,34 +13,33 @@ #include #include #include -#include +#include #include #include #include #include -#include #include #include +#include #include -#include +#include #include "sound/wcd-dsp-glink.h" #define WDSP_GLINK_DRIVER_NAME "wcd-dsp-glink" #define WDSP_MAX_WRITE_SIZE (256 * 1024) #define WDSP_MAX_READ_SIZE (4 * 1024) -#define WDSP_MAX_NO_OF_INTENTS (20) -#define WDSP_MAX_NO_OF_CHANNELS (10) #define WDSP_WRITE_PKT_SIZE (sizeof(struct wdsp_write_pkt)) -#define WDSP_REG_PKT_SIZE (sizeof(struct wdsp_reg_pkt)) #define WDSP_CMD_PKT_SIZE (sizeof(struct wdsp_cmd_pkt)) -#define WDSP_CH_CFG_SIZE (sizeof(struct wdsp_glink_ch_cfg)) #define MINOR_NUMBER_COUNT 1 -#define WDSP_EDGE "wdsp" #define RESP_QUEUE_SIZE 3 -#define QOS_PKT_SIZE 1024 #define TIMEOUT_MS 1000 +enum wdsp_ch_state { + WDSP_CH_DISCONNECTED, + WDSP_CH_CONNECTED, +}; + struct wdsp_glink_dev { struct class *cls; struct device *dev; @@ -48,7 +47,7 @@ struct wdsp_glink_dev { dev_t dev_num; }; -struct wdsp_glink_rsp_que { +struct wdsp_rsp_que { /* Size of valid data in buffer */ u32 buf_size; @@ -56,687 +55,230 @@ struct wdsp_glink_rsp_que { u8 buf[WDSP_MAX_READ_SIZE]; }; -struct wdsp_glink_tx_buf { - struct work_struct tx_work; - struct work_struct free_tx_work; - - /* Glink channel information */ - struct wdsp_glink_ch *ch; - - /* Tx buffer to send to glink */ - u8 buf[0]; -}; - -struct wdsp_glink_ch { +struct wdsp_ch { struct wdsp_glink_priv *wpriv; - - /* Glink channel handle */ + /* rpmsg handle */ void *handle; - /* Channel states like connect, disconnect */ - int channel_state; - struct mutex mutex; - - /* To free up the channel memory */ - bool free_mem; - - /* Glink local channel open work */ - struct work_struct lcl_ch_open_wrk; - - /* Glink local channel close work */ - struct work_struct lcl_ch_cls_wrk; + int ch_state; + char ch_name[RPMSG_NAME_SIZE]; + spinlock_t ch_lock; +}; - /* Wait for ch connect state before sending any command */ - wait_queue_head_t ch_connect_wait; +struct wdsp_tx_buf { + struct work_struct tx_work; - /* - * Glink channel configuration. This has to be the last - * member of the strucuture as it has variable size - */ - struct wdsp_glink_ch_cfg ch_cfg; -}; + /* Glink channel information */ + struct wdsp_ch *ch; -struct wdsp_glink_state { - /* Glink link state information */ - enum glink_link_state link_state; - void *handle; + /* Tx buffer to send to glink */ + u8 buf[0]; }; struct wdsp_glink_priv { /* Respone buffer related */ u8 rsp_cnt; - struct wdsp_glink_rsp_que rsp[RESP_QUEUE_SIZE]; + struct wdsp_rsp_que rsp[RESP_QUEUE_SIZE]; struct completion rsp_complete; - struct mutex rsp_mutex; + spinlock_t rsp_lock; /* Glink channel related */ - struct mutex glink_mutex; - struct wdsp_glink_state glink_state; - struct wdsp_glink_ch **ch; - u8 no_of_channels; - struct work_struct ch_open_cls_wrk; + int no_of_channels; + struct wdsp_ch **ch; struct workqueue_struct *work_queue; + /* Wait for all channels state before sending any command */ + wait_queue_head_t ch_state_wait; - wait_queue_head_t link_state_wait; - + struct wdsp_glink_dev *wdev; struct device *dev; }; +static struct wdsp_glink_priv *wpriv; -static int wdsp_glink_close_ch(struct wdsp_glink_ch *ch); -static int wdsp_glink_open_ch(struct wdsp_glink_ch *ch); - -/* - * wdsp_glink_free_tx_buf_work - Work function to free tx pkt - * work: Work structure - */ -static void wdsp_glink_free_tx_buf_work(struct work_struct *work) +static struct wdsp_ch *wdsp_get_ch(char *ch_name) { - struct wdsp_glink_tx_buf *tx_buf; - - tx_buf = container_of(work, struct wdsp_glink_tx_buf, - free_tx_work); - vfree(tx_buf); -} - -/* - * wdsp_glink_free_tx_buf - Function to free tx buffer - * priv: Pointer to the channel - * pkt_priv: Pointer to the tx buffer - */ -static void wdsp_glink_free_tx_buf(const void *priv, const void *pkt_priv) -{ - struct wdsp_glink_tx_buf *tx_buf = (struct wdsp_glink_tx_buf *)pkt_priv; - struct wdsp_glink_priv *wpriv; - struct wdsp_glink_ch *ch; + int i; - if (!priv) { - pr_err("%s: Invalid priv\n", __func__); - return; - } - if (!tx_buf) { - pr_err("%s: Invalid tx_buf\n", __func__); - return; + for (i = 0; i < wpriv->no_of_channels; i++) { + if (!strcmp(ch_name, wpriv->ch[i]->ch_name)) + return wpriv->ch[i]; } - - ch = (struct wdsp_glink_ch *)priv; - wpriv = ch->wpriv; - /* Work queue to free tx pkt */ - INIT_WORK(&tx_buf->free_tx_work, wdsp_glink_free_tx_buf_work); - queue_work(wpriv->work_queue, &tx_buf->free_tx_work); + return NULL; } /* - * wdsp_glink_notify_rx - Glink notify rx callback for responses - * handle: Opaque Channel handle returned by GLink - * priv: Private pointer to the channel - * pkt_priv: Private pointer to the packet - * ptr: Pointer to the Rx data - * size: Size of the Rx data + * wdsp_rpmsg_callback - Rpmsg callback for responses + * rpdev: Rpmsg device structure + * data: Pointer to the Rx data + * len: Size of the Rx data + * priv: Private pointer to the channel + * addr: Address variable + * Returns 0 on success and an appropriate error value on failure */ -static void wdsp_glink_notify_rx(void *handle, const void *priv, - const void *pkt_priv, const void *ptr, - size_t size) +static int wdsp_rpmsg_callback(struct rpmsg_device *rpdev, void *data, + int len, void *priv, u32 addr__unused) { - u8 *rx_buf; - u8 rsp_cnt; - struct wdsp_glink_ch *ch; + struct wdsp_ch *ch = dev_get_drvdata(&rpdev->dev); struct wdsp_glink_priv *wpriv; + unsigned long flags; + u8 *rx_buf; + u8 rsp_cnt = 0; - if (!ptr || !priv) { - pr_err("%s: Invalid parameters\n", __func__); - return; + if (!ch || !data) { + pr_err("%s: Invalid ch or data\n", __func__); + return -EINVAL; } - ch = (struct wdsp_glink_ch *)priv; wpriv = ch->wpriv; - rx_buf = (u8 *)ptr; - if (size > WDSP_MAX_READ_SIZE) { - dev_err(wpriv->dev, "%s: Size %zd is greater than allowed %d\n", - __func__, size, WDSP_MAX_READ_SIZE); - size = WDSP_MAX_READ_SIZE; - } - - mutex_lock(&wpriv->rsp_mutex); - rsp_cnt = wpriv->rsp_cnt; - if (rsp_cnt >= RESP_QUEUE_SIZE) { - dev_err(wpriv->dev, "%s: Resp Queue is Full\n", __func__); + rx_buf = (u8 *)data; + if (len > WDSP_MAX_READ_SIZE) { + dev_info_ratelimited(wpriv->dev, "%s: Size %d is greater than allowed %d\n", + __func__, len, WDSP_MAX_READ_SIZE); + len = WDSP_MAX_READ_SIZE; + } + dev_dbg_ratelimited(wpriv->dev, "%s: copy into buffer %d\n", __func__, + wpriv->rsp_cnt); + + if (wpriv->rsp_cnt >= RESP_QUEUE_SIZE) { + dev_info_ratelimited(wpriv->dev, "%s: Resp Queue is Full\n", + __func__); rsp_cnt = 0; } - dev_dbg(wpriv->dev, "%s: copy into buffer %d\n", __func__, rsp_cnt); - - memcpy(wpriv->rsp[rsp_cnt].buf, rx_buf, size); - wpriv->rsp[rsp_cnt].buf_size = size; + spin_lock_irqsave(&wpriv->rsp_lock, flags); + rsp_cnt = wpriv->rsp_cnt; + memcpy(wpriv->rsp[rsp_cnt].buf, rx_buf, len); + wpriv->rsp[rsp_cnt].buf_size = len; wpriv->rsp_cnt = ++rsp_cnt; - mutex_unlock(&wpriv->rsp_mutex); + spin_unlock_irqrestore(&wpriv->rsp_lock, flags); - glink_rx_done(handle, ptr, true); complete(&wpriv->rsp_complete); -} -/* - * wdsp_glink_notify_tx_done - Glink notify tx done callback to - * free tx buffer - * handle: Opaque Channel handle returned by GLink - * priv: Private pointer to the channel - * pkt_priv: Private pointer to the packet - * ptr: Pointer to the Tx data - */ -static void wdsp_glink_notify_tx_done(void *handle, const void *priv, - const void *pkt_priv, const void *ptr) -{ - wdsp_glink_free_tx_buf(priv, pkt_priv); -} -/* - * wdsp_glink_notify_tx_abort - Glink notify tx abort callback to - * free tx buffer - * handle: Opaque Channel handle returned by GLink - * priv: Private pointer to the channel - * pkt_priv: Private pointer to the packet - */ -static void wdsp_glink_notify_tx_abort(void *handle, const void *priv, - const void *pkt_priv) -{ - wdsp_glink_free_tx_buf(priv, pkt_priv); + return 0; } /* - * wdsp_glink_notify_rx_intent_req - Glink notify rx intent request callback - * to queue buffer to receive from remote client - * handle: Opaque channel handle returned by GLink - * priv: Private pointer to the channel - * req_size: Size of intent to be queued + * wdsp_rpmsg_probe - Rpmsg channel probe function + * rpdev: Rpmsg device structure + * Returns 0 on success and an appropriate error value on failure */ -static bool wdsp_glink_notify_rx_intent_req(void *handle, const void *priv, - size_t req_size) +static int wdsp_rpmsg_probe(struct rpmsg_device *rpdev) { - struct wdsp_glink_priv *wpriv; - struct wdsp_glink_ch *ch; - int rc = 0; - bool ret = false; - - if (!priv) { - pr_err("%s: Invalid priv\n", __func__); - goto done; - } - if (req_size > WDSP_MAX_READ_SIZE) { - pr_err("%s: Invalid req_size %zd\n", __func__, req_size); - goto done; - } - - ch = (struct wdsp_glink_ch *)priv; - wpriv = ch->wpriv; - - dev_dbg(wpriv->dev, "%s: intent size %zd requested for ch name %s", - __func__, req_size, ch->ch_cfg.name); + struct wdsp_ch *ch; - mutex_lock(&ch->mutex); - rc = glink_queue_rx_intent(ch->handle, ch, req_size); - if (rc < 0) { - dev_err(wpriv->dev, "%s: Failed to queue rx intent, rc = %d\n", - __func__, rc); - mutex_unlock(&ch->mutex); - goto done; + ch = wdsp_get_ch(rpdev->id.name); + if (!ch) { + dev_err(&rpdev->dev, "%s, Invalid Channel [%s]\n", + __func__, rpdev->id.name); + return -EINVAL; } - mutex_unlock(&ch->mutex); - ret = true; - -done: - return ret; -} -/* - * wdsp_glink_lcl_ch_open_wrk - Work function to open channel again - * when local disconnect event happens - * work: Work structure - */ -static void wdsp_glink_lcl_ch_open_wrk(struct work_struct *work) -{ - struct wdsp_glink_ch *ch; + dev_dbg(&rpdev->dev, "%s: Channel[%s] state[Up]\n", + __func__, rpdev->id.name); - ch = container_of(work, struct wdsp_glink_ch, - lcl_ch_open_wrk); + spin_lock(&ch->ch_lock); + ch->handle = rpdev; + ch->ch_state = WDSP_CH_CONNECTED; + spin_unlock(&ch->ch_lock); + dev_set_drvdata(&rpdev->dev, ch); + wake_up(&wpriv->ch_state_wait); - wdsp_glink_open_ch(ch); -} - -/* - * wdsp_glink_lcl_ch_cls_wrk - Work function to close channel locally - * when remote disconnect event happens - * work: Work structure - */ -static void wdsp_glink_lcl_ch_cls_wrk(struct work_struct *work) -{ - struct wdsp_glink_ch *ch; - - ch = container_of(work, struct wdsp_glink_ch, - lcl_ch_cls_wrk); - - wdsp_glink_close_ch(ch); + return 0; } /* - * wdsp_glink_notify_state - Glink channel state information event callback - * handle: Opaque Channel handle returned by GLink - * priv: Private pointer to the channel - * event: channel state event + * wdsp_rpmsg_remove - Rpmsg channel remove function + * rpdev: Rpmsg device structure */ -static void wdsp_glink_notify_state(void *handle, const void *priv, - unsigned int event) +static void wdsp_rpmsg_remove(struct rpmsg_device *rpdev) { - struct wdsp_glink_priv *wpriv; - struct wdsp_glink_ch *ch; - int i, ret = 0; + struct wdsp_ch *ch = dev_get_drvdata(&rpdev->dev); - if (!priv) { - pr_err("%s: Invalid priv\n", __func__); + if (!ch) { + dev_err(&rpdev->dev, "%s: Invalid ch\n", __func__); return; } - ch = (struct wdsp_glink_ch *)priv; - wpriv = ch->wpriv; - - mutex_lock(&ch->mutex); - ch->channel_state = event; - if (event == GLINK_CONNECTED) { - dev_dbg(wpriv->dev, "%s: glink channel: %s connected\n", - __func__, ch->ch_cfg.name); - - for (i = 0; i < ch->ch_cfg.no_of_intents; i++) { - dev_dbg(wpriv->dev, "%s: intent_size = %d\n", __func__, - ch->ch_cfg.intents_size[i]); - ret = glink_queue_rx_intent(ch->handle, ch, - ch->ch_cfg.intents_size[i]); - if (ret < 0) - dev_warn(wpriv->dev, "%s: Failed to queue intent %d of size %d\n", - __func__, i, - ch->ch_cfg.intents_size[i]); - } - - ret = glink_qos_latency(ch->handle, ch->ch_cfg.latency_in_us, - QOS_PKT_SIZE); - if (ret < 0) - dev_warn(wpriv->dev, "%s: Failed to request qos %d for ch %s\n", - __func__, ch->ch_cfg.latency_in_us, - ch->ch_cfg.name); - - wake_up(&ch->ch_connect_wait); - mutex_unlock(&ch->mutex); - } else if (event == GLINK_LOCAL_DISCONNECTED) { - /* - * Don't use dev_dbg here as dev may not be valid if channel - * closed from driver close. - */ - pr_debug("%s: channel: %s disconnected locally\n", - __func__, ch->ch_cfg.name); - mutex_unlock(&ch->mutex); - - if (ch->free_mem) { - kfree(ch); - ch = NULL; - } - } else if (event == GLINK_REMOTE_DISCONNECTED) { - dev_dbg(wpriv->dev, "%s: remote channel: %s disconnected remotely\n", - __func__, ch->ch_cfg.name); - mutex_unlock(&ch->mutex); - /* - * If remote disconnect happens, local side also has - * to close the channel as per glink design in a - * separate work_queue. - */ - queue_work(wpriv->work_queue, &ch->lcl_ch_cls_wrk); - } -} - -/* - * wdsp_glink_close_ch - Internal function to close glink channel - * ch: Glink Channel structure. - */ -static int wdsp_glink_close_ch(struct wdsp_glink_ch *ch) -{ - struct wdsp_glink_priv *wpriv = ch->wpriv; - int ret = 0; - - mutex_lock(&wpriv->glink_mutex); - if (ch->handle) { - ret = glink_close(ch->handle); - if (ret < 0) { - dev_err(wpriv->dev, "%s: glink_close is failed, ret = %d\n", - __func__, ret); - } else { - ch->handle = NULL; - dev_dbg(wpriv->dev, "%s: ch %s is closed\n", __func__, - ch->ch_cfg.name); - } - } else { - dev_dbg(wpriv->dev, "%s: ch %s is already closed\n", __func__, - ch->ch_cfg.name); - } - mutex_unlock(&wpriv->glink_mutex); - - - return ret; -} - -/* - * wdsp_glink_open_ch - Internal function to open glink channel - * ch: Glink Channel structure. - */ -static int wdsp_glink_open_ch(struct wdsp_glink_ch *ch) -{ - struct wdsp_glink_priv *wpriv = ch->wpriv; - struct glink_open_config open_cfg; - int ret = 0; - - mutex_lock(&wpriv->glink_mutex); - if (!ch->handle) { - memset(&open_cfg, 0, sizeof(open_cfg)); - open_cfg.options = GLINK_OPT_INITIAL_XPORT; - open_cfg.edge = WDSP_EDGE; - open_cfg.notify_rx = wdsp_glink_notify_rx; - open_cfg.notify_tx_done = wdsp_glink_notify_tx_done; - open_cfg.notify_tx_abort = wdsp_glink_notify_tx_abort; - open_cfg.notify_state = wdsp_glink_notify_state; - open_cfg.notify_rx_intent_req = wdsp_glink_notify_rx_intent_req; - open_cfg.priv = ch; - open_cfg.name = ch->ch_cfg.name; - - dev_dbg(wpriv->dev, "%s: ch->ch_cfg.name = %s, latency_in_us = %d, intents = %d\n", - __func__, ch->ch_cfg.name, ch->ch_cfg.latency_in_us, - ch->ch_cfg.no_of_intents); - - ch->handle = glink_open(&open_cfg); - if (IS_ERR_OR_NULL(ch->handle)) { - dev_err(wpriv->dev, "%s: glink_open failed for ch %s\n", - __func__, ch->ch_cfg.name); - ch->handle = NULL; - ret = -EINVAL; - } - } else { - dev_err(wpriv->dev, "%s: ch %s is already opened\n", __func__, - ch->ch_cfg.name); - } - mutex_unlock(&wpriv->glink_mutex); - - return ret; + dev_dbg(&rpdev->dev, "%s: Channel[%s] state[Down]\n", + __func__, rpdev->id.name); + spin_lock(&ch->ch_lock); + ch->handle = NULL; + ch->ch_state = WDSP_CH_DISCONNECTED; + spin_unlock(&ch->ch_lock); + dev_set_drvdata(&rpdev->dev, NULL); } -/* - * wdsp_glink_close_all_ch - Internal function to close all glink channels - * wpriv: Wdsp_glink private structure - */ -static void wdsp_glink_close_all_ch(struct wdsp_glink_priv *wpriv) +static bool wdsp_is_ch_connected(struct wdsp_glink_priv *wpriv) { int i; - for (i = 0; i < wpriv->no_of_channels; i++) - if (wpriv->ch && wpriv->ch[i]) - wdsp_glink_close_ch(wpriv->ch[i]); -} - -/* - * wdsp_glink_open_all_ch - Internal function to open all glink channels - * wpriv: Wdsp_glink private structure - */ -static int wdsp_glink_open_all_ch(struct wdsp_glink_priv *wpriv) -{ - int ret = 0, i, j; - for (i = 0; i < wpriv->no_of_channels; i++) { - if (wpriv->ch && wpriv->ch[i]) { - ret = wdsp_glink_open_ch(wpriv->ch[i]); - if (ret < 0) - goto err_open; + spin_lock(&wpriv->ch[i]->ch_lock); + if (wpriv->ch[i]->ch_state != WDSP_CH_CONNECTED) { + spin_unlock(&wpriv->ch[i]->ch_lock); + return false; } + spin_unlock(&wpriv->ch[i]->ch_lock); } - goto done; - -err_open: - for (j = 0; j < i; j++) - if (wpriv->ch[i]) - wdsp_glink_close_ch(wpriv->ch[j]); - -done: - return ret; -} - -/* - * wdsp_glink_ch_open_wq - Work function to open glink channels - * work: Work structure - */ -static void wdsp_glink_ch_open_cls_wrk(struct work_struct *work) -{ - struct wdsp_glink_priv *wpriv; - - wpriv = container_of(work, struct wdsp_glink_priv, - ch_open_cls_wrk); - - if (wpriv->glink_state.link_state == GLINK_LINK_STATE_DOWN) { - dev_info(wpriv->dev, "%s: GLINK_LINK_STATE_DOWN\n", - __func__); - - wdsp_glink_close_all_ch(wpriv); - } else if (wpriv->glink_state.link_state == GLINK_LINK_STATE_UP) { - dev_info(wpriv->dev, "%s: GLINK_LINK_STATE_UP\n", - __func__); - - wdsp_glink_open_all_ch(wpriv); - } + return true; } -/* - * wdsp_glink_link_state_cb - Glink link state callback to inform - * about link states - * cb_info: Glink link state callback information structure - * priv: Private structure of link state passed while register - */ -static void wdsp_glink_link_state_cb(struct glink_link_state_cb_info *cb_info, - void *priv) +static int wdsp_wait_for_all_ch_connect(struct wdsp_glink_priv *wpriv) { - struct wdsp_glink_priv *wpriv; - - if (!cb_info || !priv) { - pr_err("%s: Invalid parameters\n", __func__); - return; - } - - wpriv = (struct wdsp_glink_priv *)priv; - - mutex_lock(&wpriv->glink_mutex); - wpriv->glink_state.link_state = cb_info->link_state; - wake_up(&wpriv->link_state_wait); - mutex_unlock(&wpriv->glink_mutex); - - queue_work(wpriv->work_queue, &wpriv->ch_open_cls_wrk); -} - -/* - * wdsp_glink_ch_info_init- Internal function to allocate channel memory - * and register with glink - * wpriv: Wdsp_glink private structure. - * pkt: Glink registration packet contains glink channel information. - * pkt_size: Size of the pkt. - */ -static int wdsp_glink_ch_info_init(struct wdsp_glink_priv *wpriv, - struct wdsp_reg_pkt *pkt, size_t pkt_size) -{ - int ret = 0, i, j; - struct glink_link_info link_info; - struct wdsp_glink_ch_cfg *ch_cfg; - struct wdsp_glink_ch **ch; - u8 no_of_channels; - u8 *payload; - u32 ch_size, ch_cfg_size; - size_t size = WDSP_WRITE_PKT_SIZE + WDSP_REG_PKT_SIZE; - - mutex_lock(&wpriv->glink_mutex); - if (wpriv->ch) { - dev_err_ratelimited(wpriv->dev, "%s: glink ch memory is already allocated\n", - __func__); - ret = -EINVAL; - goto done; - } - payload = (u8 *)pkt->payload; - no_of_channels = pkt->no_of_channels; - - if (no_of_channels > WDSP_MAX_NO_OF_CHANNELS) { - dev_err_ratelimited(wpriv->dev, "%s: no_of_channels: %d but max allowed are %d\n", - __func__, no_of_channels, WDSP_MAX_NO_OF_CHANNELS); - ret = -EINVAL; - goto done; - } - ch = kcalloc(no_of_channels, sizeof(struct wdsp_glink_ch *), - GFP_ATOMIC); - if (!ch) { - ret = -ENOMEM; - goto done; - } - wpriv->ch = ch; - wpriv->no_of_channels = no_of_channels; - - for (i = 0; i < no_of_channels; i++) { - ch_cfg = (struct wdsp_glink_ch_cfg *)payload; - - size += WDSP_CH_CFG_SIZE; - if (size > pkt_size) { - dev_err_ratelimited(wpriv->dev, "%s: Invalid size = %zd, pkt_size = %zd\n", - __func__, size, pkt_size); - ret = -EINVAL; - goto err_ch_mem; - } - if (ch_cfg->no_of_intents > WDSP_MAX_NO_OF_INTENTS) { - dev_err_ratelimited(wpriv->dev, "%s: Invalid no_of_intents = %d\n", - __func__, ch_cfg->no_of_intents); - ret = -EINVAL; - goto err_ch_mem; - } - size += (sizeof(u32) * ch_cfg->no_of_intents); - if (size > pkt_size) { - dev_err_ratelimited(wpriv->dev, "%s: Invalid size = %zd, pkt_size = %zd\n", - __func__, size, pkt_size); - ret = -EINVAL; - goto err_ch_mem; - } - - ch_cfg_size = sizeof(struct wdsp_glink_ch_cfg) + - (sizeof(u32) * ch_cfg->no_of_intents); - ch_size = sizeof(struct wdsp_glink_ch) + - (sizeof(u32) * ch_cfg->no_of_intents); - - dev_dbg(wpriv->dev, "%s: channels: %d ch_cfg_size: %d, size: %zd, pkt_size: %zd", - __func__, no_of_channels, ch_cfg_size, size, pkt_size); - - ch[i] = kzalloc(ch_size, GFP_KERNEL); - if (!ch[i]) { - ret = -ENOMEM; - goto err_ch_mem; - } - ch[i]->channel_state = GLINK_LOCAL_DISCONNECTED; - memcpy(&ch[i]->ch_cfg, payload, ch_cfg_size); - payload += ch_cfg_size; - - /* check ch name is valid string or not */ - for (j = 0; j < WDSP_CH_NAME_MAX_LEN; j++) { - if (ch[i]->ch_cfg.name[j] == '\0') - break; - } - - if (j == WDSP_CH_NAME_MAX_LEN) { - dev_err_ratelimited(wpriv->dev, "%s: Wrong channel name\n", - __func__); - kfree(ch[i]); - ch[i] = NULL; - ret = -EINVAL; - goto err_ch_mem; - } - - mutex_init(&ch[i]->mutex); - ch[i]->wpriv = wpriv; - INIT_WORK(&ch[i]->lcl_ch_open_wrk, wdsp_glink_lcl_ch_open_wrk); - INIT_WORK(&ch[i]->lcl_ch_cls_wrk, wdsp_glink_lcl_ch_cls_wrk); - init_waitqueue_head(&ch[i]->ch_connect_wait); - } - - INIT_WORK(&wpriv->ch_open_cls_wrk, wdsp_glink_ch_open_cls_wrk); - - /* Register glink link_state notification */ - link_info.glink_link_state_notif_cb = wdsp_glink_link_state_cb; - link_info.transport = NULL; - link_info.edge = WDSP_EDGE; - - wpriv->glink_state.link_state = GLINK_LINK_STATE_DOWN; - wpriv->glink_state.handle = glink_register_link_state_cb(&link_info, - wpriv); - if (!wpriv->glink_state.handle) { - dev_err(wpriv->dev, "%s: Unable to register wdsp link state\n", - __func__); - ret = -EINVAL; - goto err_ch_mem; - } - goto done; + int ret; -err_ch_mem: - for (j = 0; j < i; j++) { - mutex_destroy(&ch[j]->mutex); - kfree(wpriv->ch[j]); - wpriv->ch[j] = NULL; + ret = wait_event_timeout(wpriv->ch_state_wait, + wdsp_is_ch_connected(wpriv), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + dev_err_ratelimited(wpriv->dev, "%s: All channels are not connected\n", + __func__); + ret = -ETIMEDOUT; + goto err; } - kfree(wpriv->ch); - wpriv->ch = NULL; - wpriv->no_of_channels = 0; + ret = 0; -done: - mutex_unlock(&wpriv->glink_mutex); +err: return ret; } /* - * wdsp_glink_tx_buf_work - Work queue function to send tx buffer to glink + * wdsp_tx_buf_work - Work queue function to send tx buffer to glink * work: Work structure */ -static void wdsp_glink_tx_buf_work(struct work_struct *work) +static void wdsp_tx_buf_work(struct work_struct *work) { struct wdsp_glink_priv *wpriv; - struct wdsp_glink_ch *ch; - struct wdsp_glink_tx_buf *tx_buf; + struct wdsp_ch *ch; + struct wdsp_tx_buf *tx_buf; struct wdsp_write_pkt *wpkt; struct wdsp_cmd_pkt *cpkt; int ret = 0; + struct rpmsg_device *rpdev = NULL; - tx_buf = container_of(work, struct wdsp_glink_tx_buf, + tx_buf = container_of(work, struct wdsp_tx_buf, tx_work); ch = tx_buf->ch; wpriv = ch->wpriv; wpkt = (struct wdsp_write_pkt *)tx_buf->buf; cpkt = (struct wdsp_cmd_pkt *)wpkt->payload; + dev_dbg(wpriv->dev, "%s: ch name = %s, payload size = %d\n", __func__, cpkt->ch_name, cpkt->payload_size); - mutex_lock(&tx_buf->ch->mutex); - if (ch->channel_state == GLINK_CONNECTED) { - mutex_unlock(&tx_buf->ch->mutex); - ret = glink_tx(ch->handle, tx_buf, - cpkt->payload, cpkt->payload_size, - GLINK_TX_REQ_INTENT); - if (ret < 0) { - dev_err(wpriv->dev, "%s: glink tx failed, ret = %d\n", + spin_lock(&ch->ch_lock); + rpdev = ch->handle; + if (rpdev || ch->ch_state == WDSP_CH_CONNECTED) { + spin_unlock(&ch->ch_lock); + ret = rpmsg_send(rpdev->ept, cpkt->payload, + cpkt->payload_size); + if (ret < 0) + dev_err(wpriv->dev, "%s: rpmsg send failed, ret = %d\n", __func__, ret); - /* - * If glink_tx() is failed then free tx_buf here as - * there won't be any tx_done notification to - * free the buffer. - */ - vfree(tx_buf); - } } else { - mutex_unlock(&tx_buf->ch->mutex); + spin_unlock(&ch->ch_lock); dev_err(wpriv->dev, "%s: channel %s is not in connected state\n", - __func__, ch->ch_cfg.name); - /* - * Free tx_buf here as there won't be any tx_done - * notification in this case also. - */ - vfree(tx_buf); + __func__, ch->ch_name); } + vfree(tx_buf); } /* @@ -745,19 +287,20 @@ static void wdsp_glink_tx_buf_work(struct work_struct *work) * buf: Pointer to the userspace buffer * count: Number bytes to read from the file * ppos: Pointer to the position into the file + * Returns 0 on success and an appropriate error value on failure */ static ssize_t wdsp_glink_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { int ret = 0, ret1 = 0; - struct wdsp_glink_rsp_que *rsp; + struct wdsp_rsp_que *read_rsp = NULL; struct wdsp_glink_priv *wpriv; + unsigned long flags; wpriv = (struct wdsp_glink_priv *)file->private_data; if (!wpriv) { pr_err("%s: Invalid private data\n", __func__); - ret = -EINVAL; - goto done; + return -EINVAL; } if (count > WDSP_MAX_READ_SIZE) { @@ -766,35 +309,42 @@ static ssize_t wdsp_glink_read(struct file *file, char __user *buf, count = WDSP_MAX_READ_SIZE; } /* - * Complete signal has given from glink rx notification callback + * Complete signal has given from gwdsp_rpmsg_callback() * or from flush API. Also use interruptible wait_for_completion API * to allow the system to go in suspend. */ ret = wait_for_completion_interruptible(&wpriv->rsp_complete); - if (ret) - goto done; + if (ret < 0) + return ret; + + read_rsp = kzalloc(sizeof(struct wdsp_rsp_que), GFP_KERNEL); + if (!read_rsp) + return -ENOMEM; - mutex_lock(&wpriv->rsp_mutex); + spin_lock_irqsave(&wpriv->rsp_lock, flags); if (wpriv->rsp_cnt) { wpriv->rsp_cnt--; dev_dbg(wpriv->dev, "%s: read from buffer %d\n", __func__, wpriv->rsp_cnt); - rsp = &wpriv->rsp[wpriv->rsp_cnt]; - if (count < rsp->buf_size) { - ret1 = copy_to_user(buf, &rsp->buf, count); + memcpy(read_rsp, &wpriv->rsp[wpriv->rsp_cnt], + sizeof(struct wdsp_rsp_que)); + spin_unlock_irqrestore(&wpriv->rsp_lock, flags); + + if (count < read_rsp->buf_size) { + ret1 = copy_to_user(buf, read_rsp->buf, count); /* Return the number of bytes copied */ ret = count; } else { - ret1 = copy_to_user(buf, &rsp->buf, rsp->buf_size); + ret1 = copy_to_user(buf, read_rsp->buf, + read_rsp->buf_size); /* Return the number of bytes copied */ - ret = rsp->buf_size; + ret = read_rsp->buf_size; } if (ret1) { - mutex_unlock(&wpriv->rsp_mutex); dev_err_ratelimited(wpriv->dev, "%s: copy_to_user failed %d\n", - __func__, ret); + __func__, ret); ret = -EFAULT; goto done; } @@ -805,11 +355,12 @@ static ssize_t wdsp_glink_read(struct file *file, char __user *buf, */ dev_dbg(wpriv->dev, "%s: resp count = %d\n", __func__, wpriv->rsp_cnt); + spin_unlock_irqrestore(&wpriv->rsp_lock, flags); ret = -EINVAL; } - mutex_unlock(&wpriv->rsp_mutex); done: + kfree(read_rsp); return ret; } @@ -819,6 +370,7 @@ static ssize_t wdsp_glink_read(struct file *file, char __user *buf, * buf: Pointer to the userspace buffer * count: Number bytes to read from the file * ppos: Pointer to the position into the file + * Returns 0 on success and an appropriate error value on failure */ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) @@ -826,7 +378,7 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, int ret = 0, i, tx_buf_size; struct wdsp_write_pkt *wpkt; struct wdsp_cmd_pkt *cpkt; - struct wdsp_glink_tx_buf *tx_buf; + struct wdsp_tx_buf *tx_buf; struct wdsp_glink_priv *wpriv; size_t pkt_max_size; @@ -847,7 +399,7 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, dev_dbg(wpriv->dev, "%s: count = %zd\n", __func__, count); - tx_buf_size = count + sizeof(struct wdsp_glink_tx_buf); + tx_buf_size = count + sizeof(struct wdsp_tx_buf); tx_buf = vzalloc(tx_buf_size); if (!tx_buf) { ret = -ENOMEM; @@ -865,33 +417,14 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, wpkt = (struct wdsp_write_pkt *)tx_buf->buf; switch (wpkt->pkt_type) { case WDSP_REG_PKT: - if (count < (WDSP_WRITE_PKT_SIZE + WDSP_REG_PKT_SIZE + - WDSP_CH_CFG_SIZE)) { - dev_err_ratelimited(wpriv->dev, "%s: Invalid reg pkt size = %zd\n", - __func__, count); - ret = -EINVAL; - goto free_buf; - } - ret = wdsp_glink_ch_info_init(wpriv, - (struct wdsp_reg_pkt *)wpkt->payload, - count); - if (ret < 0) - dev_err_ratelimited(wpriv->dev, "%s: glink register failed, ret = %d\n", - __func__, ret); + /* Keep this case to support backward compatibility */ vfree(tx_buf); break; case WDSP_READY_PKT: - ret = wait_event_timeout(wpriv->link_state_wait, - (wpriv->glink_state.link_state == - GLINK_LINK_STATE_UP), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - dev_err_ratelimited(wpriv->dev, "%s: Link state wait timeout\n", - __func__); - ret = -ETIMEDOUT; - goto free_buf; - } - ret = 0; + ret = wdsp_wait_for_all_ch_connect(wpriv); + if (ret < 0) + dev_err_ratelimited(wpriv->dev, "%s: Channels not in connected state\n", + __func__); vfree(tx_buf); break; case WDSP_CMD_PKT: @@ -901,16 +434,6 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, ret = -EINVAL; goto free_buf; } - mutex_lock(&wpriv->glink_mutex); - if (wpriv->glink_state.link_state == GLINK_LINK_STATE_DOWN) { - mutex_unlock(&wpriv->glink_mutex); - dev_err_ratelimited(wpriv->dev, "%s: Link state is Down\n", - __func__); - - ret = -ENETRESET; - goto free_buf; - } - mutex_unlock(&wpriv->glink_mutex); cpkt = (struct wdsp_cmd_pkt *)wpkt->payload; pkt_max_size = sizeof(struct wdsp_write_pkt) + sizeof(struct wdsp_cmd_pkt) + @@ -922,15 +445,13 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, goto free_buf; } for (i = 0; i < wpriv->no_of_channels; i++) { - if (wpriv->ch && wpriv->ch[i] && - (!strcmp(cpkt->ch_name, - wpriv->ch[i]->ch_cfg.name))) { + if (!strcmp(cpkt->ch_name, wpriv->ch[i]->ch_name)) { tx_buf->ch = wpriv->ch[i]; break; } } if (!tx_buf->ch) { - dev_err_ratelimited(wpriv->dev, "%s: Failed to get glink channel\n", + dev_err_ratelimited(wpriv->dev, "%s: Failed to get channel\n", __func__); ret = -EINVAL; goto free_buf; @@ -938,20 +459,17 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, dev_dbg(wpriv->dev, "%s: requested ch_name: %s, pkt_size: %zd\n", __func__, cpkt->ch_name, pkt_max_size); - ret = wait_event_timeout(tx_buf->ch->ch_connect_wait, - (tx_buf->ch->channel_state == - GLINK_CONNECTED), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - dev_err_ratelimited(wpriv->dev, "%s: glink channel %s is not in connected state %d\n", - __func__, tx_buf->ch->ch_cfg.name, - tx_buf->ch->channel_state); - ret = -ETIMEDOUT; + spin_lock(&tx_buf->ch->ch_lock); + if (tx_buf->ch->ch_state != WDSP_CH_CONNECTED) { + spin_unlock(&tx_buf->ch->ch_lock); + ret = -ENETRESET; + dev_err_ratelimited(wpriv->dev, "%s: Channels are not in connected state\n", + __func__); goto free_buf; } - ret = 0; + spin_unlock(&tx_buf->ch->ch_lock); - INIT_WORK(&tx_buf->tx_work, wdsp_glink_tx_buf_work); + INIT_WORK(&tx_buf->tx_work, wdsp_tx_buf_work); queue_work(wpriv->work_queue, &tx_buf->tx_work); break; default: @@ -974,54 +492,22 @@ static ssize_t wdsp_glink_write(struct file *file, const char __user *buf, * wdsp_glink_open - Open API to initialize private data * inode: Pointer to the inode structure * file: Pointer to the file structure + * Returns 0 on success and an appropriate error value on failure */ static int wdsp_glink_open(struct inode *inode, struct file *file) { - int ret = 0; - struct wdsp_glink_priv *wpriv; - struct wdsp_glink_dev *wdev; - - if (!inode->i_cdev) { - pr_err("%s: cdev is NULL\n", __func__); - ret = -EINVAL; - goto done; - } - wdev = container_of(inode->i_cdev, struct wdsp_glink_dev, cdev); - wpriv = kzalloc(sizeof(struct wdsp_glink_priv), GFP_KERNEL); - if (!wpriv) { - ret = -ENOMEM; - goto done; - } - wpriv->dev = wdev->dev; - wpriv->work_queue = create_singlethread_workqueue("wdsp_glink_wq"); - if (!wpriv->work_queue) { - dev_err(wpriv->dev, "%s: Error creating wdsp_glink_wq\n", - __func__); - ret = -EINVAL; - goto err_wq; - } - - wpriv->glink_state.link_state = GLINK_LINK_STATE_DOWN; - init_completion(&wpriv->rsp_complete); - init_waitqueue_head(&wpriv->link_state_wait); - mutex_init(&wpriv->rsp_mutex); - mutex_init(&wpriv->glink_mutex); + pr_debug("%s: wpriv = %pK\n", __func__, wpriv); file->private_data = wpriv; - goto done; - -err_wq: - kfree(wpriv); - -done: - return ret; + return 0; } /* * wdsp_glink_flush - Flush API to unblock read. * file: Pointer to the file structure * id: Lock owner ID + * Returns 0 on success and an appropriate error value on failure */ static int wdsp_glink_flush(struct file *file, fl_owner_t id) { @@ -1047,56 +533,115 @@ static int wdsp_glink_flush(struct file *file, fl_owner_t id) * * inode: Pointer to the inode structure * file: Pointer to the file structure + * Returns 0 on success and an appropriate error value on failure */ static int wdsp_glink_release(struct inode *inode, struct file *file) { - int i, ret = 0; - struct wdsp_glink_priv *wpriv; + pr_debug("%s: file->private_data = %pK\n", __func__, + file->private_data); + file->private_data = NULL; - wpriv = (struct wdsp_glink_priv *)file->private_data; - if (!wpriv) { - pr_err("%s: Invalid private data\n", __func__); - ret = -EINVAL; - goto done; - } + return 0; +} - if (wpriv->glink_state.handle) - glink_unregister_link_state_cb(wpriv->glink_state.handle); +static struct rpmsg_driver wdsp_rpmsg_driver = { + .probe = wdsp_rpmsg_probe, + .remove = wdsp_rpmsg_remove, + .callback = wdsp_rpmsg_callback, + /* Update this dynamically before register_rpmsg() */ + .id_table = NULL, + .drv = { + .name = "wdsp_rpmsg", + }, +}; - flush_workqueue(wpriv->work_queue); - destroy_workqueue(wpriv->work_queue); +static int wdsp_register_rpmsg(struct platform_device *pdev, + struct wdsp_glink_dev *wdev) +{ + int ret = 0; + int i, no_of_channels; + struct rpmsg_device_id *wdsp_rpmsg_id_table, *id_table; + const char *ch_name = NULL; + + wpriv = devm_kzalloc(&pdev->dev, + sizeof(struct wdsp_glink_priv), GFP_KERNEL); + if (!wpriv) + return -ENOMEM; + + no_of_channels = of_property_count_strings(pdev->dev.of_node, + "qcom,wdsp_channles"); + if (no_of_channels < 0) { + dev_err(&pdev->dev, "%s: channel name parse error %d\n", + __func__, no_of_channels); + return -EINVAL; + } - /* - * Clean up glink channel memory in channel state - * callback only if close channels are called from here. - */ - if (wpriv->ch) { - for (i = 0; i < wpriv->no_of_channels; i++) { - if (wpriv->ch[i]) { - wpriv->ch[i]->free_mem = true; - /* - * Channel handle NULL means channel is already - * closed. Free the channel memory here itself. - */ - if (!wpriv->ch[i]->handle) { - kfree(wpriv->ch[i]); - wpriv->ch[i] = NULL; - } else { - wdsp_glink_close_ch(wpriv->ch[i]); - } - } + wpriv->ch = devm_kzalloc(&pdev->dev, + (sizeof(struct wdsp_glink_priv *) * no_of_channels), + GFP_KERNEL); + if (!wpriv->ch) + return -ENOMEM; + + for (i = 0; i < no_of_channels; i++) { + ret = of_property_read_string_index(pdev->dev.of_node, + "qcom,wdsp-channels", i, + &ch_name); + if (ret) { + dev_err(&pdev->dev, "%s: channel name parse error %d\n", + __func__, ret); + return -EINVAL; } + wpriv->ch[i] = devm_kzalloc(&pdev->dev, + sizeof(struct wdsp_glink_priv), + GFP_KERNEL); + if (!wpriv->ch[i]) + return -ENOMEM; - kfree(wpriv->ch); - wpriv->ch = NULL; + strlcpy(wpriv->ch[i]->ch_name, ch_name, RPMSG_NAME_SIZE); + wpriv->ch[i]->wpriv = wpriv; + spin_lock_init(&wpriv->ch[i]->ch_lock); } + init_waitqueue_head(&wpriv->ch_state_wait); + init_completion(&wpriv->rsp_complete); + spin_lock_init(&wpriv->rsp_lock); - mutex_destroy(&wpriv->glink_mutex); - mutex_destroy(&wpriv->rsp_mutex); - kfree(wpriv); - file->private_data = NULL; + wpriv->wdev = wdev; + wpriv->dev = wdev->dev; + wpriv->work_queue = create_singlethread_workqueue("wdsp_glink_wq"); + if (!wpriv->work_queue) { + dev_err(&pdev->dev, "%s: Error creating wdsp_glink_wq\n", + __func__); + return -EINVAL; + } -done: + wdsp_rpmsg_id_table = devm_kzalloc(&pdev->dev, + (sizeof(struct rpmsg_device_id) * + (no_of_channels + 1)), + GFP_KERNEL); + if (!wdsp_rpmsg_id_table) { + ret = -ENOMEM; + goto err; + } + + wpriv->no_of_channels = no_of_channels; + id_table = wdsp_rpmsg_id_table; + for (i = 0; i < no_of_channels; i++) { + strlcpy(id_table->name, wpriv->ch[i]->ch_name, + RPMSG_NAME_SIZE); + id_table++; + } + wdsp_rpmsg_driver.id_table = wdsp_rpmsg_id_table; + ret = register_rpmsg_driver(&wdsp_rpmsg_driver); + if (ret < 0) { + dev_err(&pdev->dev, "%s: Rpmsg driver register failed, err = %d\n", + __func__, ret); + goto err; + } + + return 0; + +err: + destroy_workqueue(wpriv->work_queue); return ret; } @@ -1109,10 +654,6 @@ static const struct file_operations wdsp_glink_fops = { .release = wdsp_glink_release, }; -/* - * wdsp_glink_probe - Driver probe to expose char device - * pdev: Pointer to device tree data. - */ static int wdsp_glink_probe(struct platform_device *pdev) { int ret; @@ -1156,7 +697,15 @@ static int wdsp_glink_probe(struct platform_device *pdev) __func__, ret); goto err_cdev_add; } - platform_set_drvdata(pdev, wdev); + + ret = wdsp_register_rpmsg(pdev, wdev); + if (ret < 0) { + dev_err(&pdev->dev, "%s: Failed to register with rpmsg, err = %d\n", + __func__, ret); + goto err_cdev_add; + } + platform_set_drvdata(pdev, wpriv); + goto done; err_cdev_add: @@ -1169,28 +718,25 @@ static int wdsp_glink_probe(struct platform_device *pdev) unregister_chrdev_region(0, MINOR_NUMBER_COUNT); err_chrdev: - devm_kfree(&pdev->dev, wdev); - done: return ret; } -/* - * wdsp_glink_remove - Driver remove to handle cleanup - * pdev: Pointer to device tree data. - */ static int wdsp_glink_remove(struct platform_device *pdev) { - struct wdsp_glink_dev *wdev = platform_get_drvdata(pdev); - - if (wdev) { - cdev_del(&wdev->cdev); - device_destroy(wdev->cls, wdev->dev_num); - class_destroy(wdev->cls); - unregister_chrdev_region(0, MINOR_NUMBER_COUNT); - devm_kfree(&pdev->dev, wdev); - } else { - dev_err(&pdev->dev, "%s: Invalid device data\n", __func__); + struct wdsp_glink_priv *wpriv = platform_get_drvdata(pdev); + + unregister_rpmsg_driver(&wdsp_rpmsg_driver); + + if (wpriv) { + flush_workqueue(wpriv->work_queue); + destroy_workqueue(wpriv->work_queue); + if (wpriv->wdev) { + cdev_del(&wpriv->wdev->cdev); + device_destroy(wpriv->wdev->cls, wpriv->wdev->dev_num); + class_destroy(wpriv->wdev->cls); + unregister_chrdev_region(0, MINOR_NUMBER_COUNT); + } } return 0; -- GitLab From ac147b705e9b6a7da9b1d3b7ddde3b4c5eb93e7c Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 30 Oct 2017 16:46:16 +0800 Subject: [PATCH 0148/1645] ASoC: update snd_pcm_ops copy interface in platform drivers snd_pcm_ops copy interface used by msm platform drivers is replaced with copy_user in msm-4.14. Unit of two input variables is changed from frame count to byte. Update all the related msm platform drivers to adapt to this change. Change-Id: Icecd0454c7a80e5ee90407c64aaf1ca76d2d9815 Signed-off-by: Meng Wang --- asoc/msm-cpe-lsm.c | 8 +++--- asoc/msm-lsm-client.c | 13 +++++----- asoc/msm-pcm-afe-v2.c | 28 ++++++++++----------- asoc/msm-pcm-dtmf-v2.c | 23 ++++++++---------- asoc/msm-pcm-host-voice-v2.c | 41 ++++++++++++++----------------- asoc/msm-pcm-q6-noirq.c | 6 ++--- asoc/msm-pcm-q6-v2.c | 32 +++++++++++------------- asoc/msm-pcm-voip-v2.c | 47 ++++++++++++++++-------------------- 8 files changed, 89 insertions(+), 109 deletions(-) diff --git a/asoc/msm-cpe-lsm.c b/asoc/msm-cpe-lsm.c index 637778491e22..2dc32f67fab1 100644 --- a/asoc/msm-cpe-lsm.c +++ b/asoc/msm-cpe-lsm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -3132,7 +3132,7 @@ static snd_pcm_uframes_t msm_cpe_lsm_pointer( } static int msm_cpe_lsm_copy(struct snd_pcm_substream *substream, int a, - snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames) + unsigned long hwoff, void __user *buf, unsigned long fbytes) { struct cpe_lsm_data *lsm_d = cpe_get_lsm_data(substream); struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -3140,10 +3140,8 @@ static int msm_cpe_lsm_copy(struct snd_pcm_substream *substream, int a, struct cpe_lsm_session *session; struct cpe_lsm_lab *lab_d = &lsm_d->lab; char *pcm_buf; - int fbytes = 0; int rc = 0; - fbytes = frames_to_bytes(runtime, frames); if (runtime->status->state == SNDRV_PCM_STATE_XRUN || runtime->status->state == SNDRV_PCM_STATE_PREPARED) { pr_err("%s: XRUN ignore for now\n", __func__); @@ -3286,7 +3284,7 @@ static const struct snd_pcm_ops msm_cpe_lsm_ops = { .prepare = msm_cpe_lsm_prepare, .trigger = msm_cpe_lsm_trigger, .pointer = msm_cpe_lsm_pointer, - .copy = msm_cpe_lsm_copy, + .copy_user = msm_cpe_lsm_copy, .hw_params = msm_cpe_lsm_hwparams, .compat_ioctl = msm_cpe_lsm_ioctl_compat, }; diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index f6a56985080a..666ad08be74d 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2176,12 +2176,12 @@ static snd_pcm_uframes_t msm_lsm_pcm_pointer( } static int msm_lsm_pcm_copy(struct snd_pcm_substream *substream, int ch, - snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames) + unsigned long hwoff, void __user *buf, unsigned long fbytes) { struct snd_pcm_runtime *runtime = substream->runtime; struct lsm_priv *prtd = runtime->private_data; char *pcm_buf = NULL; - int fbytes = 0, rc = 0; + int rc = 0; struct snd_soc_pcm_runtime *rtd; if (!substream->private_data) { @@ -2196,7 +2196,6 @@ static int msm_lsm_pcm_copy(struct snd_pcm_substream *substream, int ch, return -EINVAL; } - fbytes = frames_to_bytes(runtime, frames); if (runtime->status->state == SNDRV_PCM_STATE_XRUN || runtime->status->state == SNDRV_PCM_STATE_PREPARED) { dev_err(rtd->dev, @@ -2221,12 +2220,12 @@ static int msm_lsm_pcm_copy(struct snd_pcm_substream *substream, int ch, prtd->lsm_client->hw_params.period_count; pcm_buf = prtd->lsm_client->lab_buffer[prtd->appl_cnt].data; dev_dbg(rtd->dev, - "%s: copy the pcm data size %d\n", + "%s: copy the pcm data size %lu\n", __func__, fbytes); if (pcm_buf) { if (copy_to_user(buf, pcm_buf, fbytes)) { dev_err(rtd->dev, - "%s: failed to copy bytes %d\n", + "%s: failed to copy bytes %lu\n", __func__, fbytes); return -EINVAL; } @@ -2341,7 +2340,7 @@ static const struct snd_pcm_ops msm_lsm_ops = { .prepare = msm_lsm_prepare, .compat_ioctl = msm_lsm_ioctl_compat, .hw_params = msm_lsm_hw_params, - .copy = msm_lsm_pcm_copy, + .copy_user = msm_lsm_pcm_copy, .pointer = msm_lsm_pcm_pointer, }; diff --git a/asoc/msm-pcm-afe-v2.c b/asoc/msm-pcm-afe-v2.c index 77eecb23d26f..3a65fe5d4df6 100644 --- a/asoc/msm-pcm-afe-v2.c +++ b/asoc/msm-pcm-afe-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -489,20 +489,20 @@ static int msm_afe_open(struct snd_pcm_substream *substream) } static int msm_afe_playback_copy(struct snd_pcm_substream *substream, - int channel, snd_pcm_uframes_t hwoff, - void __user *buf, snd_pcm_uframes_t frames) + int channel, unsigned long hwoff, + void __user *buf, unsigned long fbytes) { int ret = 0; struct snd_pcm_runtime *runtime = substream->runtime; struct pcm_afe_info *prtd = runtime->private_data; - char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); + char *hwbuf = runtime->dma_area + hwoff; u32 mem_map_handle = 0; pr_debug("%s : appl_ptr 0x%lx hw_ptr 0x%lx dest_to_copy 0x%pK\n", __func__, runtime->control->appl_ptr, runtime->status->hw_ptr, hwbuf); - if (copy_from_user(hwbuf, buf, frames_to_bytes(runtime, frames))) { + if (copy_from_user(hwbuf, buf, fbytes)) { pr_err("%s :Failed to copy audio from user buffer\n", __func__); @@ -542,13 +542,13 @@ static int msm_afe_playback_copy(struct snd_pcm_substream *substream, } static int msm_afe_capture_copy(struct snd_pcm_substream *substream, - int channel, snd_pcm_uframes_t hwoff, - void __user *buf, snd_pcm_uframes_t frames) + int channel, unsigned long hwoff, + void __user *buf, unsigned long fbytes) { int ret = 0; struct snd_pcm_runtime *runtime = substream->runtime; struct pcm_afe_info *prtd = runtime->private_data; - char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); + char *hwbuf = runtime->dma_area + hwoff; u32 mem_map_handle = 0; if (!prtd->mmap_flag) { @@ -590,7 +590,7 @@ static int msm_afe_capture_copy(struct snd_pcm_substream *substream, __func__, runtime->control->appl_ptr, runtime->status->hw_ptr, hwbuf); - if (copy_to_user(buf, hwbuf, frames_to_bytes(runtime, frames))) { + if (copy_to_user(buf, hwbuf, fbytes)) { pr_err("%s: copy to user failed\n", __func__); goto fail; @@ -602,8 +602,8 @@ static int msm_afe_capture_copy(struct snd_pcm_substream *substream, } static int msm_afe_copy(struct snd_pcm_substream *substream, int channel, - snd_pcm_uframes_t hwoff, void __user *buf, - snd_pcm_uframes_t frames) + unsigned long hwoff, void __user *buf, + unsigned long fbytes) { struct snd_pcm_runtime *runtime = substream->runtime; struct pcm_afe_info *prtd = runtime->private_data; @@ -618,10 +618,10 @@ static int msm_afe_copy(struct snd_pcm_substream *substream, int channel, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ret = msm_afe_playback_copy(substream, channel, hwoff, - buf, frames); + buf, fbytes); else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ret = msm_afe_capture_copy(substream, channel, hwoff, - buf, frames); + buf, fbytes); return ret; } @@ -841,7 +841,7 @@ static snd_pcm_uframes_t msm_afe_pointer(struct snd_pcm_substream *substream) static const struct snd_pcm_ops msm_afe_ops = { .open = msm_afe_open, - .copy = msm_afe_copy, + .copy_user = msm_afe_copy, .hw_params = msm_afe_hw_params, .trigger = msm_afe_trigger, .close = msm_afe_close, diff --git a/asoc/msm-pcm-dtmf-v2.c b/asoc/msm-pcm-dtmf-v2.c index 9953eebcef6b..77dc81ce9c21 100644 --- a/asoc/msm-pcm-dtmf-v2.c +++ b/asoc/msm-pcm-dtmf-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2017-2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -217,24 +217,21 @@ static void dtmf_rx_detected_cb(uint8_t *pkt, } static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, - int channel, snd_pcm_uframes_t hwoff, - void __user *buf, snd_pcm_uframes_t frames) + int channel, unsigned long hwoff, + void __user *buf, unsigned long fbytes) { int ret = 0; - int count = 0; struct dtmf_buf_node *buf_node = NULL; struct snd_pcm_runtime *runtime = substream->runtime; struct dtmf_drv_info *prtd = runtime->private_data; unsigned long dsp_flags; - count = frames_to_bytes(runtime, frames); - ret = wait_event_interruptible_timeout(prtd->out_wait, (!list_empty(&prtd->out_queue)), 1 * HZ); if (ret > 0) { - if (count <= DTMF_PKT_SIZE) { + if (fbytes <= DTMF_PKT_SIZE) { spin_lock_irqsave(&prtd->dsp_lock, dsp_flags); buf_node = list_first_entry(&prtd->out_queue, struct dtmf_buf_node, list); @@ -242,7 +239,7 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags); ret = copy_to_user(buf, &buf_node->dtmf_det_pkt, - count); + fbytes); if (ret) { pr_err("%s: Copy to user returned %d\n", __func__, ret); @@ -254,8 +251,8 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags); } else { - pr_err("%s: Read count %d > DTMF_PKT_SIZE\n", - __func__, count); + pr_err("%s: Read count %lu > DTMF_PKT_SIZE\n", + __func__, fbytes); ret = -ENOMEM; } } else if (ret == 0) { @@ -269,14 +266,14 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, } static int msm_pcm_copy(struct snd_pcm_substream *substream, int a, - snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames) + unsigned long hwoff, void __user *buf, unsigned long fbytes) { int ret = 0; pr_debug("%s() DTMF\n", __func__); if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ret = msm_pcm_capture_copy(substream, a, hwoff, buf, frames); + ret = msm_pcm_capture_copy(substream, a, hwoff, buf, fbytes); return ret; } @@ -524,7 +521,7 @@ static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream) static const struct snd_pcm_ops msm_pcm_ops = { .open = msm_pcm_open, - .copy = msm_pcm_copy, + .copy_user = msm_pcm_copy, .hw_params = msm_pcm_hw_params, .close = msm_pcm_close, .prepare = msm_pcm_prepare, diff --git a/asoc/msm-pcm-host-voice-v2.c b/asoc/msm-pcm-host-voice-v2.c index fd771df5d3d4..2692a7fc5d8d 100644 --- a/asoc/msm-pcm-host-voice-v2.c +++ b/asoc/msm-pcm-host-voice-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1088,8 +1088,8 @@ static int msm_pcm_close(struct snd_pcm_substream *substream) } static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, - snd_pcm_uframes_t hwoff, void __user *buf, - snd_pcm_uframes_t frames) + unsigned long hwoff, void __user *buf, + unsigned long fbytes) { int ret = 0; struct hpcm_buf_node *buf_node = NULL; @@ -1098,8 +1098,6 @@ static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, struct dai_data *dai_data = hpcm_get_dai_data(substream->pcm->id, prtd); unsigned long dsp_flags; - int count = frames_to_bytes(runtime, frames); - if (dai_data == NULL) { pr_err("%s, dai_data is null\n", __func__); @@ -1112,7 +1110,7 @@ static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, dai_data->state == HPCM_STOPPED), 1 * HZ); if (ret > 0) { - if (count <= HPCM_MAX_VOC_PKT_SIZE) { + if (fbytes <= HPCM_MAX_VOC_PKT_SIZE) { spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags); buf_node = list_first_entry(&dai_data->free_queue, @@ -1120,14 +1118,14 @@ static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, list_del(&buf_node->list); spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags); ret = copy_from_user(&buf_node->frame.voc_pkt, buf, - count); - buf_node->frame.len = count; + fbytes); + buf_node->frame.len = fbytes; spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags); list_add_tail(&buf_node->list, &dai_data->filled_queue); spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags); } else { - pr_err("%s: Write cnt %d is > HPCM_MAX_VOC_PKT_SIZE\n", - __func__, count); + pr_err("%s: Write cnt %lu is > HPCM_MAX_VOC_PKT_SIZE\n", + __func__, fbytes); ret = -ENOMEM; } } else if (ret == 0) { @@ -1142,11 +1140,10 @@ static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, } static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, - int channel, snd_pcm_uframes_t hwoff, - void __user *buf, snd_pcm_uframes_t frames) + int channel, unsigned long hwoff, + void __user *buf, unsigned long fbytes) { int ret = 0; - int count = 0; struct hpcm_buf_node *buf_node = NULL; struct snd_pcm_runtime *runtime = substream->runtime; struct hpcm_drv *prtd = runtime->private_data; @@ -1160,15 +1157,13 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, goto done; } - count = frames_to_bytes(runtime, frames); - ret = wait_event_interruptible_timeout(dai_data->queue_wait, (!list_empty(&dai_data->filled_queue) || dai_data->state == HPCM_STOPPED), 1 * HZ); if (ret > 0) { - if (count <= HPCM_MAX_VOC_PKT_SIZE) { + if (fbytes <= HPCM_MAX_VOC_PKT_SIZE) { spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags); buf_node = list_first_entry(&dai_data->filled_queue, struct hpcm_buf_node, list); @@ -1186,8 +1181,8 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags); } else { - pr_err("%s: Read count %d > HPCM_MAX_VOC_PKT_SIZE\n", - __func__, count); + pr_err("%s: Read count %lu > HPCM_MAX_VOC_PKT_SIZE\n", + __func__, fbytes); ret = -ENOMEM; } @@ -1204,17 +1199,17 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, } static int msm_pcm_copy(struct snd_pcm_substream *substream, int channel, - snd_pcm_uframes_t hwoff, void __user *buf, - snd_pcm_uframes_t frames) + unsigned long hwoff, void __user *buf, + unsigned long fbytes) { int ret = 0; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ret = msm_pcm_playback_copy(substream, channel, - hwoff, buf, frames); + hwoff, buf, fbytes); else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ret = msm_pcm_capture_copy(substream, channel, - hwoff, buf, frames); + hwoff, buf, fbytes); return ret; } @@ -1446,7 +1441,7 @@ static const struct snd_pcm_ops msm_pcm_ops = { .prepare = msm_pcm_prepare, .trigger = msm_pcm_trigger, .pointer = msm_pcm_pointer, - .copy = msm_pcm_copy, + .copy_user = msm_pcm_copy, .close = msm_pcm_close, }; diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index dbc6d33a65be..62753155e873 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -530,7 +530,7 @@ static snd_pcm_uframes_t msm_pcm_pointer(struct snd_pcm_substream *substream) } static int msm_pcm_copy(struct snd_pcm_substream *substream, int a, - snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames) + unsigned long hwoff, void __user *buf, unsigned long fbytes) { return -EINVAL; } @@ -1182,7 +1182,7 @@ static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) static const struct snd_pcm_ops msm_pcm_ops = { .open = msm_pcm_open, .prepare = msm_pcm_prepare, - .copy = msm_pcm_copy, + .copy_user = msm_pcm_copy, .hw_params = msm_pcm_hw_params, .ioctl = msm_pcm_ioctl, #ifdef CONFIG_COMPAT diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index bb6ce734b3c5..bbcbab35957c 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -714,10 +714,9 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) } static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, - snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames) + unsigned long hwoff, void __user *buf, unsigned long fbytes) { int ret = 0; - int fbytes = 0; int xfer = 0; char *bufptr = NULL; void *data = NULL; @@ -728,7 +727,6 @@ static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, struct snd_pcm_runtime *runtime = substream->runtime; struct msm_audio *prtd = runtime->private_data; - fbytes = frames_to_bytes(runtime, frames); pr_debug("%s: prtd->out_count = %d\n", __func__, atomic_read(&prtd->out_count)); @@ -775,8 +773,8 @@ static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, bufptr = data; if (bufptr) { - pr_debug("%s:fbytes =%d: xfer=%d size=%d\n", - __func__, fbytes, xfer, size); + pr_debug("%s:fbytes =%lu: xfer=%d size=%d\n", + __func__, fbytes, xfer, size); if (copy_from_user(bufptr, buf, xfer)) { ret = -EFAULT; pr_err("%s: copy_from_user failed\n", @@ -786,8 +784,8 @@ static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, } buf += xfer; fbytes -= xfer; - pr_debug("%s:fbytes = %d: xfer=%d\n", __func__, fbytes, - xfer); + pr_debug("%s:fbytes = %lu: xfer=%d\n", __func__, + fbytes, xfer); if (atomic_read(&prtd->start)) { pr_debug("%s:writing %d bytes of buffer to dsp\n", __func__, xfer); @@ -870,11 +868,10 @@ static int msm_pcm_playback_close(struct snd_pcm_substream *substream) } static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, - int channel, snd_pcm_uframes_t hwoff, void __user *buf, - snd_pcm_uframes_t frames) + int channel, unsigned long hwoff, void __user *buf, + unsigned long fbytes) { int ret = 0; - int fbytes = 0; int xfer; char *bufptr; void *data = NULL; @@ -886,7 +883,6 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, pr_debug("%s\n", __func__); - fbytes = frames_to_bytes(runtime, frames); pr_debug("appl_ptr %d\n", (int)runtime->control->appl_ptr); pr_debug("hw_ptr %d\n", (int)runtime->status->hw_ptr); @@ -915,7 +911,7 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, data = q6asm_is_cpu_buf_avail(OUT, prtd->audio_client, &size, &idx); bufptr = data; pr_debug("Size = %d\n", size); - pr_debug("fbytes = %d\n", fbytes); + pr_debug("fbytes = %lu\n", fbytes); pr_debug("idx = %d\n", idx); if (bufptr) { xfer = fbytes; @@ -932,7 +928,7 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, fbytes -= xfer; size -= xfer; prtd->in_frame_info[idx].offset += xfer; - pr_debug("%s:fbytes = %d: size=%d: xfer=%d\n", + pr_debug("%s:fbytes = %lu: size=%d: xfer=%d\n", __func__, fbytes, size, xfer); pr_debug(" Sending next buffer to dsp\n"); memset(&prtd->in_frame_info[idx], 0, @@ -977,14 +973,14 @@ static int msm_pcm_capture_close(struct snd_pcm_substream *substream) } static int msm_pcm_copy(struct snd_pcm_substream *substream, int a, - snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames) + unsigned long hwoff, void __user *buf, unsigned long fbytes) { int ret = 0; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - ret = msm_pcm_playback_copy(substream, a, hwoff, buf, frames); + ret = msm_pcm_playback_copy(substream, a, hwoff, buf, fbytes); else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ret = msm_pcm_capture_copy(substream, a, hwoff, buf, frames); + ret = msm_pcm_capture_copy(substream, a, hwoff, buf, fbytes); return ret; } @@ -1086,7 +1082,7 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream, static const struct snd_pcm_ops msm_pcm_ops = { .open = msm_pcm_open, - .copy = msm_pcm_copy, + .copy_user = msm_pcm_copy, .hw_params = msm_pcm_hw_params, .close = msm_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/asoc/msm-pcm-voip-v2.c b/asoc/msm-pcm-voip-v2.c index 02cee29e3c02..b8d7390bbb8a 100644 --- a/asoc/msm-pcm-voip-v2.c +++ b/asoc/msm-pcm-voip-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -778,7 +778,7 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) } static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, - snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames) + unsigned long hwoff, void __user *buf, unsigned long fbytes) { int ret = 0; struct voip_buf_node *buf_node = NULL; @@ -786,9 +786,7 @@ static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, struct voip_drv_info *prtd = runtime->private_data; unsigned long dsp_flags; - int count = frames_to_bytes(runtime, frames); - - pr_debug("%s: count = %d, frames=%d\n", __func__, count, (int)frames); + pr_debug("%s: fbytes=%lu\n", __func__, fbytes); if (prtd->voip_reset) { pr_debug("%s: RESET event happened during VoIP\n", __func__); @@ -805,7 +803,7 @@ static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, } if (ret > 0) { - if (count <= VOIP_MAX_VOC_PKT_SIZE) { + if (fbytes <= VOIP_MAX_VOC_PKT_SIZE) { spin_lock_irqsave(&prtd->dsp_lock, dsp_flags); buf_node = list_first_entry(&prtd->free_in_queue, @@ -814,23 +812,23 @@ static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags); if (prtd->mode == MODE_PCM) { ret = copy_from_user(&buf_node->frame.voc_pkt, - buf, count); + buf, fbytes); if (ret) { pr_err("%s: copy from user failed %d\n", __func__, ret); return -EFAULT; } - buf_node->frame.pktlen = count; + buf_node->frame.pktlen = fbytes; } else { ret = copy_from_user(&buf_node->frame, - buf, count); + buf, fbytes); if (ret) { pr_err("%s: copy from user failed %d\n", __func__, ret); return -EFAULT; } - if (buf_node->frame.pktlen >= count) - buf_node->frame.pktlen = count - + if (buf_node->frame.pktlen >= fbytes) + buf_node->frame.pktlen = fbytes - (sizeof(buf_node->frame.frm_hdr) + sizeof(buf_node->frame.pktlen)); } @@ -838,8 +836,8 @@ static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, list_add_tail(&buf_node->list, &prtd->in_queue); spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags); } else { - pr_err("%s: Write cnt %d is > VOIP_MAX_VOC_PKT_SIZE\n", - __func__, count); + pr_err("%s: Write cnt %lu is > VOIP_MAX_VOC_PKT_SIZE\n", + __func__, fbytes); ret = -ENOMEM; } @@ -853,20 +851,17 @@ static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, return ret; } static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, - int channel, snd_pcm_uframes_t hwoff, void __user *buf, - snd_pcm_uframes_t frames) + int channel, unsigned long hwoff, void __user *buf, + unsigned long fbytes) { int ret = 0; - int count = 0; struct voip_buf_node *buf_node = NULL; struct snd_pcm_runtime *runtime = substream->runtime; struct voip_drv_info *prtd = runtime->private_data; unsigned long dsp_flags; int size; - count = frames_to_bytes(runtime, frames); - - pr_debug("%s: count = %d\n", __func__, count); + pr_debug("%s: fbytes = %lu\n", __func__, fbytes); if (prtd->voip_reset) { pr_debug("%s: RESET event happened during VoIP\n", __func__); @@ -885,7 +880,7 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, if (ret > 0) { - if (count <= VOIP_MAX_VOC_PKT_SIZE) { + if (fbytes <= VOIP_MAX_VOC_PKT_SIZE) { spin_lock_irqsave(&prtd->dsp_ul_lock, dsp_flags); buf_node = list_first_entry(&prtd->out_queue, struct voip_buf_node, list); @@ -914,8 +909,8 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, &prtd->free_out_queue); spin_unlock_irqrestore(&prtd->dsp_ul_lock, dsp_flags); } else { - pr_err("%s: Read count %d > VOIP_MAX_VOC_PKT_SIZE\n", - __func__, count); + pr_err("%s: Read fbytes %lu > VOIP_MAX_VOC_PKT_SIZE\n", + __func__, fbytes); ret = -ENOMEM; } @@ -930,14 +925,14 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, return ret; } static int msm_pcm_copy(struct snd_pcm_substream *substream, int a, - snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames) + unsigned long hwoff, void __user *buf, unsigned long fbytes) { int ret = 0; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - ret = msm_pcm_playback_copy(substream, a, hwoff, buf, frames); + ret = msm_pcm_playback_copy(substream, a, hwoff, buf, fbytes); else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ret = msm_pcm_capture_copy(substream, a, hwoff, buf, frames); + ret = msm_pcm_capture_copy(substream, a, hwoff, buf, fbytes); return ret; } @@ -1598,7 +1593,7 @@ static int voip_get_media_type(uint32_t mode, uint32_t rate_type, static const struct snd_pcm_ops msm_pcm_ops = { .open = msm_pcm_open, - .copy = msm_pcm_copy, + .copy_user = msm_pcm_copy, .hw_params = msm_pcm_hw_params, .close = msm_pcm_close, .prepare = msm_pcm_prepare, -- GitLab From 9cbeb978326db985248de1d33539739ecf315271 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Mon, 22 Jan 2018 17:10:15 -0800 Subject: [PATCH 0149/1645] codecs: add wcd9360 audio codec driver Initial commit to add wcd9360 audio codec driver. Change-Id: Ib4e5e41ce7e540e4426c9ca26db8e834edc3d4da Signed-off-by: Vidyakumar Athota --- Android.mk | 5 + asoc/codecs/core.h | 4 +- asoc/codecs/wcd9360/Android.mk | 50 + asoc/codecs/wcd9360/Kbuild | 104 + asoc/codecs/wcd9360/wcd9360-defaults.h | 2231 +++++++ asoc/codecs/wcd9360/wcd9360-dsp-cntl.c | 1354 ++++ asoc/codecs/wcd9360/wcd9360-dsp-cntl.h | 120 + asoc/codecs/wcd9360/wcd9360-irq.h | 56 + asoc/codecs/wcd9360/wcd9360-regmap.c | 110 + asoc/codecs/wcd9360/wcd9360-routing.h | 864 +++ asoc/codecs/wcd9360/wcd9360.c | 7915 ++++++++++++++++++++++++ asoc/codecs/wcd9360/wcd9360.h | 157 + include/asoc/wcd9360-registers.h | 1158 ++++ 13 files changed, 14127 insertions(+), 1 deletion(-) create mode 100644 asoc/codecs/wcd9360/Android.mk create mode 100644 asoc/codecs/wcd9360/Kbuild create mode 100644 asoc/codecs/wcd9360/wcd9360-defaults.h create mode 100644 asoc/codecs/wcd9360/wcd9360-dsp-cntl.c create mode 100644 asoc/codecs/wcd9360/wcd9360-dsp-cntl.h create mode 100644 asoc/codecs/wcd9360/wcd9360-irq.h create mode 100644 asoc/codecs/wcd9360/wcd9360-regmap.c create mode 100644 asoc/codecs/wcd9360/wcd9360-routing.h create mode 100644 asoc/codecs/wcd9360/wcd9360.c create mode 100644 asoc/codecs/wcd9360/wcd9360.h create mode 100644 include/asoc/wcd9360-registers.h diff --git a/Android.mk b/Android.mk index cda991e9889f..6a75d00ce25d 100644 --- a/Android.mk +++ b/Android.mk @@ -29,3 +29,8 @@ $(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sd include $(MY_LOCAL_PATH)/asoc/codecs/sdm660_cdc/Android.mk include $(MY_LOCAL_PATH)/asoc/codecs/msm_sdw/Android.mk endif + +ifeq ($(call is-board-platform-in-list,msmnile),true) +$(shell rm -rf $(OUT_DIR)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd9360/Module.symvers) +include $(MY_LOCAL_PATH)/asoc/codecs/wcd9360/Android.mk +endif diff --git a/asoc/codecs/core.h b/asoc/codecs/core.h index b4c1be40ff31..c6f62cf46b33 100644 --- a/asoc/codecs/core.h +++ b/asoc/codecs/core.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -105,6 +105,8 @@ #define IS_CODEC_VERSION(wcd, wcdversion) \ ((wcd->version == wcdversion) ? true : false) +#define PAHU_VERSION_1_0 0 + enum { CDC_V_1_0, CDC_V_1_1, diff --git a/asoc/codecs/wcd9360/Android.mk b/asoc/codecs/wcd9360/Android.mk new file mode 100644 index 000000000000..bf65cffe8a4b --- /dev/null +++ b/asoc/codecs/wcd9360/Android.mk @@ -0,0 +1,50 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,msmnile),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,msmnile),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=wcd9360_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd9360.ko +LOCAL_MODULE_KBUILD_NAME := wcd9360_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/asoc/codecs/wcd9360/Kbuild b/asoc/codecs/wcd9360/Kbuild new file mode 100644 index 000000000000..a1b5fe44bac6 --- /dev/null +++ b/asoc/codecs/wcd9360/Kbuild @@ -0,0 +1,104 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + + + +ifeq ($(KERNEL_BUILD), 1) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) + ifeq ($(CONFIG_ARCH_SDM855), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif +endif + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ WCD934X ############ + +# for WCD9360 Codec +ifdef CONFIG_SND_SOC_WCD9360 + WCD9360_OBJS += wcd9360.o + WCD9360_OBJS += wcd9360-dsp-cntl.o +endif + +LINUX_INC += -Iinclude/linux + +INCS += $(COMMON_INC) \ + $(UAPI_INC) + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +ifeq ($(KERNEL_BUILD), 0) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_WCD9360) += wcd9360_dlkm.o +wcd9360_dlkm-y := $(WCD9360_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/wcd9360/wcd9360-defaults.h b/asoc/codecs/wcd9360/wcd9360-defaults.h new file mode 100644 index 000000000000..5557ddafa865 --- /dev/null +++ b/asoc/codecs/wcd9360/wcd9360-defaults.h @@ -0,0 +1,2231 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __WCD9360_DEFAULTS_H__ +#define __WCD9360_DEFAULTS_H__ + +#include +#include + +#define WCD9360_REG(reg) ((reg) & 0xFF) + +static const struct reg_default wcd9360_defaults[] = { +{WCD9360_PAGE0_PAGE_REGISTER, 0x00}, +{WCD9360_CODEC_RPM_CLK_BYPASS, 0x00}, +{WCD9360_CODEC_RPM_CLK_GATE, 0x1F}, +{WCD9360_CODEC_RPM_CLK_MCLK_CFG, 0x00}, +{WCD9360_CODEC_RPM_CLK_MCLK2_CFG, 0x02}, +{WCD9360_CODEC_RPM_I2S_DSD_CLK_SEL, 0x00}, +{WCD9360_CODEC_RPM_RST_CTL, 0x00}, +{WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x04}, +{WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE0, 0x10}, +{WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE1, 0x60}, +{WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE2, 0x93}, +{WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE3, 0x01}, +{WCD9360_CHIP_TIER_CTRL_EFUSE_CTL, 0x10}, +{WCD9360_CHIP_TIER_CTRL_EFUSE_TEST0, 0x00}, +{WCD9360_CHIP_TIER_CTRL_EFUSE_TEST1, 0x00}, +{WCD9360_CHIP_TIER_CTRL_EFUSE_STATUS, 0x00}, +{WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO, 0x0D}, +{WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_1, 0x00}, +{WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_2, 0x00}, +{WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_3, 0x00}, +{WCD9360_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL, 0x44}, +{WCD9360_CHIP_TIER_CTRL_I2C_ACTIVE, 0x00}, +{WCD9360_CHIP_TIER_CTRL_ALT_FUNC_EN, 0x00}, +{WCD9360_CHIP_TIER_CTRL_GPIO_CTL_OE, 0x00}, +{WCD9360_CHIP_TIER_CTRL_GPIO_CTL_DATA, 0x00}, +{WCD9360_DATA_HUB_RX0_CFG, 0x00}, +{WCD9360_DATA_HUB_RX1_CFG, 0x00}, +{WCD9360_DATA_HUB_RX2_CFG, 0x00}, +{WCD9360_DATA_HUB_RX3_CFG, 0x00}, +{WCD9360_DATA_HUB_RX4_CFG, 0x00}, +{WCD9360_DATA_HUB_RX5_CFG, 0x00}, +{WCD9360_DATA_HUB_RX6_CFG, 0x00}, +{WCD9360_DATA_HUB_RX7_CFG, 0x00}, +{WCD9360_DATA_HUB_SB_TX0_INP_CFG, 0x00}, +{WCD9360_DATA_HUB_SB_TX1_INP_CFG, 0x00}, +{WCD9360_DATA_HUB_SB_TX2_INP_CFG, 0x00}, +{WCD9360_DATA_HUB_SB_TX3_INP_CFG, 0x00}, +{WCD9360_DATA_HUB_SB_TX4_INP_CFG, 0x00}, +{WCD9360_DATA_HUB_SB_TX5_INP_CFG, 0x00}, +{WCD9360_DATA_HUB_SB_TX6_INP_CFG, 0x00}, +{WCD9360_DATA_HUB_SB_TX7_INP_CFG, 0x00}, +{WCD9360_DATA_HUB_SB_TX8_INP_CFG, 0x00}, +{WCD9360_DATA_HUB_SB_TX9_INP_CFG, 0x00}, +{WCD9360_DATA_HUB_SB_TX10_INP_CFG, 0x00}, +{WCD9360_DATA_HUB_SB_TX11_INP_CFG, 0x00}, +{WCD9360_DATA_HUB_SB_TX12_INP_CFG, 0x00}, +{WCD9360_DATA_HUB_SB_TX13_INP_CFG, 0x00}, +{WCD9360_DATA_HUB_SB_TX14_INP_CFG, 0x00}, +{WCD9360_DATA_HUB_SB_TX15_INP_CFG, 0x00}, +{WCD9360_DATA_HUB_I2S_TX0_CFG, 0x00}, +{WCD9360_DATA_HUB_I2S_TX0_CFG2, 0x00}, +{WCD9360_DATA_HUB_I2S_TX1_0_CFG, 0x00}, +{WCD9360_DATA_HUB_I2S_TX1_1_CFG, 0x00}, +{WCD9360_DATA_HUB_DATA_HUB_CFG, 0x03}, +{WCD9360_DATA_HUB_I2S_0_CTL, 0x0C}, +{WCD9360_DATA_HUB_I2S_1_CTL, 0x0C}, +{WCD9360_DATA_HUB_I2S_0_CTL2, 0x01}, +{WCD9360_DATA_HUB_I2S_1_CTL2, 0x01}, +{WCD9360_DATA_HUB_I2S_CLKSRC_CTL, 0x00}, +{WCD9360_DATA_HUB_I2S_COMMON_CTL, 0x00}, +{WCD9360_DATA_HUB_I2S_0_TDM_CTL, 0x00}, +{WCD9360_DATA_HUB_I2S_0_TDM_CTL2, 0x05}, +{WCD9360_DATA_HUB_I2S_0_TDM_CH_RX, 0x00}, +{WCD9360_DATA_HUB_I2S_0_TDM_CH_TX, 0x00}, +{WCD9360_DATA_HUB_I2S_0_TDM_CFG, 0x00}, +{WCD9360_DATA_HUB_I2S_0_TDM_STRETCH, 0x00}, +{WCD9360_DATA_HUB_I2S_RESET_CTL, 0x00}, +{WCD9360_DMA_RDMA_CTL_0, 0x00}, +{WCD9360_DMA_RDMA_CTL_1, 0x00}, +{WCD9360_DMA_RDMA_CTL_2, 0x00}, +{WCD9360_DMA_RDMA_CTL_3, 0x00}, +{WCD9360_DMA_RDMA_CTL_4, 0x00}, +{WCD9360_DMA_CH_2_3_CFG_RDMA_0, 0xFF}, +{WCD9360_DMA_CH_2_3_CFG_RDMA_1, 0xFF}, +{WCD9360_DMA_CH_2_3_CFG_RDMA_2, 0xFF}, +{WCD9360_DMA_CH_2_3_CFG_RDMA_3, 0xFF}, +{WCD9360_DMA_CH_2_3_CFG_RDMA_4, 0xFF}, +{WCD9360_DMA_CH_0_1_CFG_RDMA_0, 0xFF}, +{WCD9360_DMA_CH_0_1_CFG_RDMA_1, 0xFF}, +{WCD9360_DMA_CH_0_1_CFG_RDMA_2, 0xFF}, +{WCD9360_DMA_CH_0_1_CFG_RDMA_3, 0xFF}, +{WCD9360_DMA_CH_0_1_CFG_RDMA_4, 0xFF}, +{WCD9360_DMA_RDMA4_PRT_CFG, 0x00}, +{WCD9360_DMA_RDMA_SBTX0_7_CFG, 0x00}, +{WCD9360_DMA_RDMA_SBTX8_10_CFG, 0x00}, +{WCD9360_DMA_WDMA_CTL_0, 0x00}, +{WCD9360_DMA_WDMA_CTL_1, 0x00}, +{WCD9360_DMA_WDMA_CTL_2, 0x00}, +{WCD9360_DMA_WDMA_CTL_3, 0x00}, +{WCD9360_DMA_WDMA_CTL_4, 0x00}, +{WCD9360_DMA_CH_4_5_CFG_WDMA_0, 0x00}, +{WCD9360_DMA_CH_4_5_CFG_WDMA_1, 0x00}, +{WCD9360_DMA_CH_4_5_CFG_WDMA_2, 0x00}, +{WCD9360_DMA_CH_4_5_CFG_WDMA_3, 0x00}, +{WCD9360_DMA_CH_4_5_CFG_WDMA_4, 0x00}, +{WCD9360_DMA_CH_2_3_CFG_WDMA_0, 0x00}, +{WCD9360_DMA_CH_2_3_CFG_WDMA_1, 0x00}, +{WCD9360_DMA_CH_2_3_CFG_WDMA_2, 0x00}, +{WCD9360_DMA_CH_2_3_CFG_WDMA_3, 0x00}, +{WCD9360_DMA_CH_2_3_CFG_WDMA_4, 0x00}, +{WCD9360_DMA_CH_0_1_CFG_WDMA_0, 0x00}, +{WCD9360_DMA_CH_0_1_CFG_WDMA_1, 0x00}, +{WCD9360_DMA_CH_0_1_CFG_WDMA_2, 0x00}, +{WCD9360_DMA_CH_0_1_CFG_WDMA_3, 0x00}, +{WCD9360_DMA_CH_0_1_CFG_WDMA_4, 0x00}, +{WCD9360_DMA_WDMA0_PRT_CFG, 0x00}, +{WCD9360_DMA_WDMA3_PRT_CFG, 0x00}, +{WCD9360_DMA_WDMA4_PRT0_3_CFG, 0x00}, +{WCD9360_DMA_WDMA4_PRT4_7_CFG, 0x00}, +{WCD9360_PAGE1_PAGE_REGISTER, 0x00}, +{WCD9360_CPE_FLL_USER_CTL_0, 0x71}, +{WCD9360_CPE_FLL_USER_CTL_1, 0x34}, +{WCD9360_CPE_FLL_USER_CTL_2, 0x0B}, +{WCD9360_CPE_FLL_USER_CTL_3, 0x02}, +{WCD9360_CPE_FLL_USER_CTL_4, 0x04}, +{WCD9360_CPE_FLL_USER_CTL_5, 0x02}, +{WCD9360_CPE_FLL_USER_CTL_6, 0x6E}, +{WCD9360_CPE_FLL_USER_CTL_7, 0x00}, +{WCD9360_CPE_FLL_USER_CTL_8, 0x94}, +{WCD9360_CPE_FLL_USER_CTL_9, 0x50}, +{WCD9360_CPE_FLL_L_VAL_CTL_0, 0x53}, +{WCD9360_CPE_FLL_L_VAL_CTL_1, 0x00}, +{WCD9360_CPE_FLL_DSM_FRAC_CTL_0, 0x00}, +{WCD9360_CPE_FLL_DSM_FRAC_CTL_1, 0xFF}, +{WCD9360_CPE_FLL_CONFIG_CTL_0, 0x6B}, +{WCD9360_CPE_FLL_CONFIG_CTL_1, 0x05}, +{WCD9360_CPE_FLL_CONFIG_CTL_2, 0x20}, +{WCD9360_CPE_FLL_CONFIG_CTL_3, 0x00}, +{WCD9360_CPE_FLL_CONFIG_CTL_4, 0x10}, +{WCD9360_CPE_FLL_TEST_CTL_0, 0x80}, +{WCD9360_CPE_FLL_TEST_CTL_1, 0x00}, +{WCD9360_CPE_FLL_TEST_CTL_2, 0x00}, +{WCD9360_CPE_FLL_TEST_CTL_3, 0x00}, +{WCD9360_CPE_FLL_TEST_CTL_4, 0x00}, +{WCD9360_CPE_FLL_TEST_CTL_5, 0x00}, +{WCD9360_CPE_FLL_TEST_CTL_6, 0x04}, +{WCD9360_CPE_FLL_TEST_CTL_7, 0x33}, +{WCD9360_CPE_FLL_FREQ_CTL_0, 0x00}, +{WCD9360_CPE_FLL_FREQ_CTL_1, 0x00}, +{WCD9360_CPE_FLL_FREQ_CTL_2, 0x00}, +{WCD9360_CPE_FLL_FREQ_CTL_3, 0x00}, +{WCD9360_CPE_FLL_SSC_CTL_0, 0x00}, +{WCD9360_CPE_FLL_SSC_CTL_1, 0x00}, +{WCD9360_CPE_FLL_SSC_CTL_2, 0x00}, +{WCD9360_CPE_FLL_SSC_CTL_3, 0x00}, +{WCD9360_CPE_FLL_FLL_MODE, 0x20}, +{WCD9360_CPE_FLL_STATUS_0, 0x00}, +{WCD9360_CPE_FLL_STATUS_1, 0x00}, +{WCD9360_CPE_FLL_STATUS_2, 0x00}, +{WCD9360_CPE_FLL_STATUS_3, 0x00}, +{WCD9360_I2S_FLL_USER_CTL_0, 0x41}, +{WCD9360_I2S_FLL_USER_CTL_1, 0x94}, +{WCD9360_I2S_FLL_USER_CTL_2, 0x08}, +{WCD9360_I2S_FLL_USER_CTL_3, 0x02}, +{WCD9360_I2S_FLL_USER_CTL_4, 0x04}, +{WCD9360_I2S_FLL_USER_CTL_5, 0x02}, +{WCD9360_I2S_FLL_USER_CTL_6, 0x40}, +{WCD9360_I2S_FLL_USER_CTL_7, 0x00}, +{WCD9360_I2S_FLL_USER_CTL_8, 0x5F}, +{WCD9360_I2S_FLL_USER_CTL_9, 0x02}, +{WCD9360_I2S_FLL_L_VAL_CTL_0, 0x40}, +{WCD9360_I2S_FLL_L_VAL_CTL_1, 0x00}, +{WCD9360_I2S_FLL_DSM_FRAC_CTL_0, 0x00}, +{WCD9360_I2S_FLL_DSM_FRAC_CTL_1, 0xFF}, +{WCD9360_I2S_FLL_CONFIG_CTL_0, 0x6B}, +{WCD9360_I2S_FLL_CONFIG_CTL_1, 0x05}, +{WCD9360_I2S_FLL_CONFIG_CTL_2, 0x20}, +{WCD9360_I2S_FLL_CONFIG_CTL_3, 0x00}, +{WCD9360_I2S_FLL_CONFIG_CTL_4, 0x30}, +{WCD9360_I2S_FLL_TEST_CTL_0, 0x80}, +{WCD9360_I2S_FLL_TEST_CTL_1, 0x00}, +{WCD9360_I2S_FLL_TEST_CTL_2, 0x00}, +{WCD9360_I2S_FLL_TEST_CTL_3, 0x00}, +{WCD9360_I2S_FLL_TEST_CTL_4, 0x00}, +{WCD9360_I2S_FLL_TEST_CTL_5, 0x00}, +{WCD9360_I2S_FLL_TEST_CTL_6, 0x04}, +{WCD9360_I2S_FLL_TEST_CTL_7, 0xFF}, +{WCD9360_I2S_FLL_FREQ_CTL_0, 0x00}, +{WCD9360_I2S_FLL_FREQ_CTL_1, 0x00}, +{WCD9360_I2S_FLL_FREQ_CTL_2, 0x00}, +{WCD9360_I2S_FLL_FREQ_CTL_3, 0x00}, +{WCD9360_I2S_FLL_SSC_CTL_0, 0x00}, +{WCD9360_I2S_FLL_SSC_CTL_1, 0x00}, +{WCD9360_I2S_FLL_SSC_CTL_2, 0x00}, +{WCD9360_I2S_FLL_SSC_CTL_3, 0x00}, +{WCD9360_I2S_FLL_FLL_MODE, 0x00}, +{WCD9360_I2S_FLL_STATUS_0, 0x00}, +{WCD9360_I2S_FLL_STATUS_1, 0x00}, +{WCD9360_I2S_FLL_STATUS_2, 0x00}, +{WCD9360_I2S_FLL_STATUS_3, 0x00}, +{WCD9360_PAGE2_PAGE_REGISTER, 0x00}, +{WCD9360_CPE_SS_CPE_CTL, 0x05}, +{WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_0, 0x01}, +{WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_1, 0x00}, +{WCD9360_CPE_SS_PWR_CPEFLL_CTL, 0x02}, +{WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, 0xFF}, +{WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, 0x03}, +{WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0, 0xFF}, +{WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1, 0xFF}, +{WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2, 0xFF}, +{WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3, 0xFF}, +{WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_4, 0xFF}, +{WCD9360_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN, 0x07}, +{WCD9360_CPE_SS_US_BUF_INT_PERIOD, 0x5F}, +{WCD9360_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD, 0x13}, +{WCD9360_CPE_SS_SVA_CFG, 0x41}, +{WCD9360_CPE_SS_US_CFG, 0x00}, +{WCD9360_CPE_SS_MAD_CTL, 0x00}, +{WCD9360_CPE_SS_CPAR_CTL, 0x00}, +{WCD9360_CPE_SS_DMIC0_CTL, 0x00}, +{WCD9360_CPE_SS_DMIC1_CTL, 0x00}, +{WCD9360_CPE_SS_DMIC2_CTL, 0x00}, +{WCD9360_CPE_SS_DMIC_CFG, 0x80}, +{WCD9360_CPE_SS_CPAR_CFG, 0x00}, +{WCD9360_CPE_SS_WDOG_CFG, 0x01}, +{WCD9360_CPE_SS_BACKUP_INT, 0x00}, +{WCD9360_CPE_SS_STATUS, 0x00}, +{WCD9360_CPE_SS_CPE_OCD_CFG, 0x00}, +{WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A, 0xFF}, +{WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B, 0x3F}, +{WCD9360_CPE_SS_SS_ERROR_INT_MASK_1A, 0xFF}, +{WCD9360_CPE_SS_SS_ERROR_INT_MASK_1B, 0x3F}, +{WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0A, 0x00}, +{WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0B, 0x00}, +{WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1A, 0x00}, +{WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1B, 0x00}, +{WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0A, 0x00}, +{WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0B, 0x00}, +{WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1A, 0x00}, +{WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1B, 0x00}, +{WCD9360_CPE_SS_DMIC3_CTL, 0x00}, +{WCD9360_CPE_SS_WDOG_RESET, 0x00}, +{WCD9360_CPE_SS_LPASS_MCLK_PRG, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_IN_0, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_IN_1, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_IN_2, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_IN_3, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_IN_4, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_IN_5, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_IN_6, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_IN_7, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_IN_8, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_IN_9, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_IN_10, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_IN_11, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_IN_12, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_IN_13, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_IN_14, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_IN_15, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_OUT_0, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_OUT_1, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_OUT_2, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_OUT_3, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_OUT_4, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_OUT_5, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_OUT_6, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_OUT_7, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_OUT_8, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_OUT_9, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_OUT_10, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_OUT_11, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_OUT_12, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_OUT_13, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_OUT_14, 0x00}, +{WCD9360_CPE_SS_LPASS_IPC_OUT_15, 0x00}, +{WCD9360_CPE_SS_LPASS_ARB_CTL, 0x00}, +{WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_0, 0x00}, +{WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_1, 0x00}, +{WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_0, 0x00}, +{WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_1, 0x00}, +{WCD9360_SOC_MAD_MAIN_CTL_1, 0x00}, +{WCD9360_SOC_MAD_MAIN_CTL_2, 0x00}, +{WCD9360_SOC_MAD_AUDIO_CTL_1, 0x00}, +{WCD9360_SOC_MAD_AUDIO_CTL_2, 0x00}, +{WCD9360_SOC_MAD_AUDIO_CTL_3, 0x00}, +{WCD9360_SOC_MAD_AUDIO_CTL_4, 0x00}, +{WCD9360_SOC_MAD_AUDIO_CTL_5, 0x00}, +{WCD9360_SOC_MAD_AUDIO_CTL_6, 0x00}, +{WCD9360_SOC_MAD_AUDIO_CTL_7, 0x00}, +{WCD9360_SOC_MAD_AUDIO_CTL_8, 0x00}, +{WCD9360_SOC_MAD_AUDIO_IIR_CTL_PTR, 0x00}, +{WCD9360_SOC_MAD_AUDIO_IIR_CTL_VAL, 0x40}, +{WCD9360_SOC_MAD_ULTR_CTL_1, 0x00}, +{WCD9360_SOC_MAD_ULTR_CTL_2, 0x00}, +{WCD9360_SOC_MAD_ULTR_CTL_3, 0x00}, +{WCD9360_SOC_MAD_ULTR_CTL_4, 0x00}, +{WCD9360_SOC_MAD_ULTR_CTL_5, 0x00}, +{WCD9360_SOC_MAD_ULTR_CTL_6, 0x00}, +{WCD9360_SOC_MAD_ULTR_CTL_7, 0x00}, +{WCD9360_SOC_MAD_BEACON_CTL_1, 0x00}, +{WCD9360_SOC_MAD_BEACON_CTL_2, 0x00}, +{WCD9360_SOC_MAD_BEACON_CTL_3, 0x00}, +{WCD9360_SOC_MAD_BEACON_CTL_4, 0x00}, +{WCD9360_SOC_MAD_BEACON_CTL_5, 0x00}, +{WCD9360_SOC_MAD_BEACON_CTL_6, 0x00}, +{WCD9360_SOC_MAD_BEACON_CTL_7, 0x00}, +{WCD9360_SOC_MAD_BEACON_CTL_8, 0x00}, +{WCD9360_SOC_MAD_BEACON_IIR_CTL_PTR, 0x00}, +{WCD9360_SOC_MAD_BEACON_IIR_CTL_VAL, 0x00}, +{WCD9360_SOC_MAD_INP_SEL, 0x00}, +{WCD9360_SOC_MAD_MAD2_INP_SEL, 0x00}, +{WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_CTRL, 0x00}, +{WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_STATUS, 0x00}, +{WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_FS, 0x00}, +{WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_IN_SEL, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT0, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT1, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT2, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT3, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT4, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT5, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT6, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT7, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT8, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT9, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT10, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT11, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT12, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT13, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT14, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT15, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT0, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT1, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT2, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT3, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT4, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT5, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT6, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT7, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT8, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT9, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT10, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT11, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT12, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT13, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT14, 0x00}, +{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT15, 0x00}, +{WCD9360_PAGE4_PAGE_REGISTER, 0x00}, +{WCD9360_INTR_CFG, 0x00}, +{WCD9360_INTR_CLR_COMMIT, 0x00}, +{WCD9360_INTR_PIN1_MASK0, 0xFF}, +{WCD9360_INTR_PIN1_MASK1, 0xFF}, +{WCD9360_INTR_PIN1_MASK2, 0xFF}, +{WCD9360_INTR_PIN1_MASK3, 0xFF}, +{WCD9360_INTR_PIN1_STATUS0, 0x00}, +{WCD9360_INTR_PIN1_STATUS1, 0x00}, +{WCD9360_INTR_PIN1_STATUS2, 0x00}, +{WCD9360_INTR_PIN1_STATUS3, 0x00}, +{WCD9360_INTR_PIN1_CLEAR0, 0x00}, +{WCD9360_INTR_PIN1_CLEAR1, 0x00}, +{WCD9360_INTR_PIN1_CLEAR2, 0x00}, +{WCD9360_INTR_PIN1_CLEAR3, 0x00}, +{WCD9360_INTR_PIN2_MASK3, 0xFF}, +{WCD9360_INTR_PIN2_STATUS3, 0x00}, +{WCD9360_INTR_PIN2_CLEAR3, 0x00}, +{WCD9360_INTR_CPESS_SUMRY_MASK2, 0xFF}, +{WCD9360_INTR_CPESS_SUMRY_MASK3, 0xFF}, +{WCD9360_INTR_CPESS_SUMRY_STATUS2, 0x00}, +{WCD9360_INTR_CPESS_SUMRY_STATUS3, 0x00}, +{WCD9360_INTR_CPESS_SUMRY_CLEAR2, 0x00}, +{WCD9360_INTR_CPESS_SUMRY_CLEAR3, 0x00}, +{WCD9360_INTR_LEVEL0, 0x3B}, +{WCD9360_INTR_LEVEL1, 0x00}, +{WCD9360_INTR_LEVEL2, 0xD0}, +{WCD9360_INTR_LEVEL3, 0x00}, +{WCD9360_INTR_BYPASS0, 0x00}, +{WCD9360_INTR_BYPASS1, 0x00}, +{WCD9360_INTR_BYPASS2, 0x00}, +{WCD9360_INTR_BYPASS3, 0x00}, +{WCD9360_INTR_SET0, 0x00}, +{WCD9360_INTR_SET1, 0x00}, +{WCD9360_INTR_SET2, 0x00}, +{WCD9360_INTR_SET3, 0x00}, +{WCD9360_INTR_CODEC_MISC_MASK, 0x73}, +{WCD9360_INTR_CODEC_MISC_STATUS, 0x00}, +{WCD9360_INTR_CODEC_MISC_CLEAR, 0x00}, +{WCD9360_ANA_PAGE_REGISTER, 0x00}, +{WCD9360_ANA_BIAS, 0x00}, +{WCD9360_ANA_RCO, 0x00}, +{WCD9360_ANA_BUCK_CTL, 0x00}, +{WCD9360_ANA_BUCK_STATUS, 0x00}, +{WCD9360_ANA_EAR, 0x00}, +{WCD9360_ANA_MAD_SETUP, 0x01}, +{WCD9360_ANA_AMIC1, 0x20}, +{WCD9360_ANA_AMIC2, 0x00}, +{WCD9360_ANA_AMIC3, 0x20}, +{WCD9360_ANA_AMIC4, 0x00}, +{WCD9360_ANA_MICB1, 0x10}, +{WCD9360_ANA_MICB2, 0x10}, +{WCD9360_ANA_MICB3, 0x10}, +{WCD9360_ANA_MICB4, 0x10}, +{WCD9360_BIAS_CTL, 0x2A}, +{WCD9360_BIAS_VBG_FINE_ADJ, 0x55}, +{WCD9360_RCO_CTRL_1, 0x44}, +{WCD9360_RCO_CTRL_2, 0x48}, +{WCD9360_RCO_CAL, 0x00}, +{WCD9360_RCO_CAL_1, 0x00}, +{WCD9360_RCO_CAL_2, 0x00}, +{WCD9360_RCO_TEST_CTRL, 0x00}, +{WCD9360_RCO_CAL_OUT_1, 0x00}, +{WCD9360_RCO_CAL_OUT_2, 0x00}, +{WCD9360_RCO_CAL_OUT_3, 0x00}, +{WCD9360_RCO_CAL_OUT_4, 0x00}, +{WCD9360_RCO_CAL_OUT_5, 0x00}, +{WCD9360_SIDO_MODE_1, 0x84}, +{WCD9360_SIDO_MODE_2, 0xFE}, +{WCD9360_SIDO_MODE_3, 0xF6}, +{WCD9360_SIDO_MODE_4, 0x56}, +{WCD9360_SIDO_VCL_1, 0x00}, +{WCD9360_SIDO_VCL_2, 0x6C}, +{WCD9360_SIDO_VCL_3, 0x44}, +{WCD9360_SIDO_CCL_1, 0x57}, +{WCD9360_SIDO_CCL_2, 0x92}, +{WCD9360_SIDO_CCL_3, 0x35}, +{WCD9360_SIDO_CCL_4, 0x61}, +{WCD9360_SIDO_CCL_5, 0x6D}, +{WCD9360_SIDO_CCL_6, 0x60}, +{WCD9360_SIDO_CCL_7, 0x6F}, +{WCD9360_SIDO_CCL_8, 0x6F}, +{WCD9360_SIDO_CCL_9, 0x6E}, +{WCD9360_SIDO_CCL_10, 0x26}, +{WCD9360_SIDO_FILTER_1, 0x92}, +{WCD9360_SIDO_FILTER_2, 0x54}, +{WCD9360_SIDO_DRIVER_1, 0x77}, +{WCD9360_SIDO_DRIVER_2, 0x55}, +{WCD9360_SIDO_DRIVER_3, 0x55}, +{WCD9360_SIDO_CAL_CODE_EXT_1, 0x9C}, +{WCD9360_SIDO_CAL_CODE_EXT_2, 0x82}, +{WCD9360_SIDO_CAL_CODE_OUT_1, 0x00}, +{WCD9360_SIDO_CAL_CODE_OUT_2, 0x00}, +{WCD9360_SIDO_TEST_1, 0x00}, +{WCD9360_SIDO_TEST_2, 0x00}, +{WCD9360_LDOH_MODE, 0x2B}, +{WCD9360_LDOH_BIAS, 0x68}, +{WCD9360_LDOH_STB_LOADS, 0x00}, +{WCD9360_LDOH_SLOWRAMP, 0x50}, +{WCD9360_MICB1_TEST_CTL_1, 0x1A}, +{WCD9360_MICB1_TEST_CTL_2, 0x18}, +{WCD9360_MICB1_TEST_CTL_3, 0xA4}, +{WCD9360_MICB2_TEST_CTL_1, 0x1A}, +{WCD9360_MICB2_TEST_CTL_2, 0x18}, +{WCD9360_MICB2_TEST_CTL_3, 0xA4}, +{WCD9360_MICB3_TEST_CTL_1, 0x1A}, +{WCD9360_MICB3_TEST_CTL_2, 0x18}, +{WCD9360_MICB3_TEST_CTL_3, 0xA4}, +{WCD9360_MICB4_TEST_CTL_1, 0x1A}, +{WCD9360_MICB4_TEST_CTL_2, 0x18}, +{WCD9360_MICB4_TEST_CTL_3, 0xA4}, +{WCD9360_TX_COM_ADC_VCM, 0x39}, +{WCD9360_TX_COM_BIAS_ATEST, 0xC0}, +{WCD9360_TX_COM_ADC_INT1_IB, 0x6F}, +{WCD9360_TX_COM_ADC_INT2_IB, 0x4F}, +{WCD9360_TX_COM_TXFE_DIV_CTL, 0x2E}, +{WCD9360_TX_COM_TXFE_DIV_START, 0x00}, +{WCD9360_TX_COM_TXFE_DIV_STOP_9P6M, 0xC7}, +{WCD9360_TX_COM_TXFE_DIV_STOP_12P288M, 0xFF}, +{WCD9360_TX_1_2_TEST_EN, 0xCC}, +{WCD9360_TX_1_2_ADC_IB, 0x09}, +{WCD9360_TX_1_2_ATEST_REFCTL, 0x0A}, +{WCD9360_TX_1_2_TEST_CTL, 0x38}, +{WCD9360_TX_1_2_TEST_BLK_EN, 0xFF}, +{WCD9360_TX_1_2_TXFE_CLKDIV, 0x00}, +{WCD9360_TX_1_2_SAR1_ERR, 0x00}, +{WCD9360_TX_1_2_SAR2_ERR, 0x00}, +{WCD9360_TX_3_4_TEST_EN, 0xCC}, +{WCD9360_TX_3_4_ADC_IB, 0x09}, +{WCD9360_TX_3_4_ATEST_REFCTL, 0x0A}, +{WCD9360_TX_3_4_TEST_CTL, 0x38}, +{WCD9360_TX_3_4_TEST_BLK_EN, 0xFF}, +{WCD9360_TX_3_4_TXFE_CLKDIV, 0x00}, +{WCD9360_TX_3_4_SAR1_ERR, 0x00}, +{WCD9360_TX_3_4_SAR2_ERR, 0x00}, +{WCD9360_RX_RX_EAR_BIAS_CON_1, 0x2A}, +{WCD9360_RX_RX_EAR_BIAS_CON_2, 0x8A}, +{WCD9360_RX_RX_AUX_BIAS_CON_1, 0x2A}, +{WCD9360_RX_RX_AUX_BIAS_CON_2, 0x8A}, +{WCD9360_RX_RX_BIAS_ATEST, 0x0C}, +{WCD9360_RX_RXTOP_RESERVED, 0x00}, +{WCD9360_EAR_EAR_EN_REG, 0x22}, +{WCD9360_EAR_EAR_PA_CON, 0x44}, +{WCD9360_EAR_EAR_SP_CON, 0xDB}, +{WCD9360_EAR_EAR_DAC_CON, 0x00}, +{WCD9360_EAR_EAR_CNP_FSM_CON, 0xB6}, +{WCD9360_EAR_DAC_CTL_TEST, 0x00}, +{WCD9360_EAR_STATUS_REG, 0x00}, +{WCD9360_EAR_EAR_COMPANDER_CON, 0x02}, +{WCD9360_ANA_NEW_PAGE_REGISTER, 0x00}, +{WCD9360_CLK_SYS_PLL_ENABLES, 0x00}, +{WCD9360_CLK_SYS_PLL_PRESET, 0x00}, +{WCD9360_CLK_SYS_PLL_STATUS, 0x00}, +{WCD9360_CLK_SYS_MCLK_PRG, 0x10}, +{WCD9360_CLK_SYS_MCLK2_PRG1, 0x00}, +{WCD9360_CLK_SYS_MCLK_MISC, 0x00}, +{WCD9360_SIDO_NEW_VOUT_A_STARTUP, 0x17}, +{WCD9360_SIDO_NEW_VOUT_D_STARTUP, 0x0D}, +{WCD9360_SIDO_NEW_VOUT_D_FREQ1, 0x07}, +{WCD9360_SIDO_NEW_VOUT_D_FREQ2, 0x00}, +{WCD9360_AUX_ANA_EAR, 0x00}, +{WCD9360_LDORXTX_LDORXTX, 0x10}, +{WCD9360_DIE_CRACK_CTL, 0x00}, +{WCD9360_DIE_CRACK_OUT, 0x00}, +{WCD9360_LOOP_BACK_EN, 0x00}, +{WCD9360_CLK_SYS_INT_POST_DIV_REG0, 0x00}, +{WCD9360_CLK_SYS_INT_POST_DIV_REG1, 0x00}, +{WCD9360_CLK_SYS_INT_REF_DIV_REG0, 0x00}, +{WCD9360_CLK_SYS_INT_REF_DIV_REG1, 0x00}, +{WCD9360_CLK_SYS_INT_FILTER_REG0, 0x00}, +{WCD9360_CLK_SYS_INT_FILTER_REG1, 0x00}, +{WCD9360_CLK_SYS_INT_PLL_L_VAL, 0x00}, +{WCD9360_CLK_SYS_INT_PLL_M_VAL, 0x00}, +{WCD9360_CLK_SYS_INT_PLL_N_VAL, 0x00}, +{WCD9360_CLK_SYS_INT_TEST_REG0, 0x00}, +{WCD9360_CLK_SYS_INT_PFD_CP_DSM_PROG, 0x00}, +{WCD9360_CLK_SYS_INT_VCO_PROG, 0x00}, +{WCD9360_CLK_SYS_INT_TEST_REG1, 0x00}, +{WCD9360_CLK_SYS_INT_LDO_LOCK_CFG, 0x00}, +{WCD9360_CLK_SYS_INT_DIG_LOCK_DET_CFG, 0x00}, +{WCD9360_CLK_SYS_INT_CLK_TEST1, 0x00}, +{WCD9360_CLK_SYS_INT_CLK_TEST2, 0x00}, +{WCD9360_CLK_SYS_INT_CLK_TEST3, 0x00}, +{WCD9360_SIDO_NEW_INT_RAMP_STATUS, 0x00}, +{WCD9360_SIDO_NEW_INT_SPARE_1, 0x00}, +{WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_A, 0x64}, +{WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_D, 0x40}, +{WCD9360_SIDO_NEW_INT_RAMP_INC_WAIT, 0x24}, +{WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_CTL, 0x09}, +{WCD9360_SIDO_NEW_INT_RAMP_IBLEED_CTL, 0x7D}, +{WCD9360_SIDO_NEW_INT_DEBUG_CPROVR_TEST, 0x00}, +{WCD9360_SIDO_NEW_INT_RAMP_CTL_A, 0x14}, +{WCD9360_SIDO_NEW_INT_RAMP_CTL_D, 0x14}, +{WCD9360_SIDO_NEW_INT_RAMP_TIMEOUT_PERIOD, 0x33}, +{WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING1, 0x3F}, +{WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING2, 0x74}, +{WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING3, 0x33}, +{WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL1, 0x1D}, +{WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL2, 0x0A}, +{WCD9360_EAR_INT_NEW_EAR_CHOPPER_CON, 0xA8}, +{WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON1, 0x42}, +{WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON2, 0x22}, +{WCD9360_EAR_INT_NEW_EAR_DYNAMIC_BIAS, 0x00}, +{WCD9360_AUX_INT_AUX_EN_REG, 0x22}, +{WCD9360_AUX_INT_AUX_PA_CON, 0x46}, +{WCD9360_AUX_INT_AUX_SP_CON, 0xD2}, +{WCD9360_AUX_INT_AUX_DAC_CON, 0x00}, +{WCD9360_AUX_INT_AUX_CNP_FSM_CON, 0xB6}, +{WCD9360_AUX_INT_AUX_TEST, 0x00}, +{WCD9360_AUX_INT_STATUS_REG, 0x00}, +{WCD9360_AUX_INT_AUX_MISC, 0x00}, +{WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL1, 0xFF}, +{WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL2, 0xD8}, +{WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL3, 0x80}, +{WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL4, 0xFF}, +{WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL5, 0x09}, +{WCD9360_LDORXTX_INT_ANA_LDORXTX_STATUS, 0x00}, +{WCD9360_DIE_CRACK_INT_INT1, 0x02}, +{WCD9360_DIE_CRACK_INT_INT2, 0x60}, +{WCD9360_LOOP_BACK_INT_SPARE, 0x00}, +{WCD9360_PAGE10_PAGE_REGISTER, 0x00}, +{WCD9360_CDC_ANC0_CLK_RESET_CTL, 0x00}, +{WCD9360_CDC_ANC0_MODE_1_CTL, 0x00}, +{WCD9360_CDC_ANC0_MODE_2_CTL, 0x00}, +{WCD9360_CDC_ANC0_FF_SHIFT, 0x00}, +{WCD9360_CDC_ANC0_FB_SHIFT, 0x00}, +{WCD9360_CDC_ANC0_LPF_FF_A_CTL, 0x00}, +{WCD9360_CDC_ANC0_LPF_FF_B_CTL, 0x00}, +{WCD9360_CDC_ANC0_LPF_FB_CTL, 0x00}, +{WCD9360_CDC_ANC0_SMLPF_CTL, 0x00}, +{WCD9360_CDC_ANC0_DCFLT_SHIFT_CTL, 0x00}, +{WCD9360_CDC_ANC0_IIR_ADAPT_CTL, 0x00}, +{WCD9360_CDC_ANC0_IIR_COEFF_1_CTL, 0x00}, +{WCD9360_CDC_ANC0_IIR_COEFF_2_CTL, 0x00}, +{WCD9360_CDC_ANC0_FF_A_GAIN_CTL, 0x00}, +{WCD9360_CDC_ANC0_FF_B_GAIN_CTL, 0x00}, +{WCD9360_CDC_ANC0_FB_GAIN_CTL, 0x00}, +{WCD9360_CDC_TX0_TX_PATH_CTL, 0x04}, +{WCD9360_CDC_TX0_TX_PATH_CFG0, 0x10}, +{WCD9360_CDC_TX0_TX_PATH_CFG1, 0x03}, +{WCD9360_CDC_TX0_TX_VOL_CTL, 0x00}, +{WCD9360_CDC_TX0_TX_PATH_192_CTL, 0x00}, +{WCD9360_CDC_TX0_TX_PATH_192_CFG, 0x00}, +{WCD9360_CDC_TX0_TX_PATH_SEC0, 0x00}, +{WCD9360_CDC_TX0_TX_PATH_SEC1, 0x00}, +{WCD9360_CDC_TX0_TX_PATH_SEC2, 0x01}, +{WCD9360_CDC_TX0_TX_PATH_SEC3, 0x3C}, +{WCD9360_CDC_TX0_TX_PATH_SEC4, 0x20}, +{WCD9360_CDC_TX0_TX_PATH_SEC5, 0x00}, +{WCD9360_CDC_TX0_TX_PATH_SEC6, 0x00}, +{WCD9360_CDC_TX1_TX_PATH_CTL, 0x04}, +{WCD9360_CDC_TX1_TX_PATH_CFG0, 0x10}, +{WCD9360_CDC_TX1_TX_PATH_CFG1, 0x03}, +{WCD9360_CDC_TX1_TX_VOL_CTL, 0x00}, +{WCD9360_CDC_TX1_TX_PATH_192_CTL, 0x00}, +{WCD9360_CDC_TX1_TX_PATH_192_CFG, 0x00}, +{WCD9360_CDC_TX1_TX_PATH_SEC0, 0x00}, +{WCD9360_CDC_TX1_TX_PATH_SEC1, 0x00}, +{WCD9360_CDC_TX1_TX_PATH_SEC2, 0x01}, +{WCD9360_CDC_TX1_TX_PATH_SEC3, 0x3C}, +{WCD9360_CDC_TX1_TX_PATH_SEC4, 0x20}, +{WCD9360_CDC_TX1_TX_PATH_SEC5, 0x00}, +{WCD9360_CDC_TX1_TX_PATH_SEC6, 0x00}, +{WCD9360_CDC_TX2_TX_PATH_CTL, 0x04}, +{WCD9360_CDC_TX2_TX_PATH_CFG0, 0x10}, +{WCD9360_CDC_TX2_TX_PATH_CFG1, 0x03}, +{WCD9360_CDC_TX2_TX_VOL_CTL, 0x00}, +{WCD9360_CDC_TX2_TX_PATH_192_CTL, 0x00}, +{WCD9360_CDC_TX2_TX_PATH_192_CFG, 0x00}, +{WCD9360_CDC_TX2_TX_PATH_SEC0, 0x00}, +{WCD9360_CDC_TX2_TX_PATH_SEC1, 0x00}, +{WCD9360_CDC_TX2_TX_PATH_SEC2, 0x01}, +{WCD9360_CDC_TX2_TX_PATH_SEC3, 0x3C}, +{WCD9360_CDC_TX2_TX_PATH_SEC4, 0x20}, +{WCD9360_CDC_TX2_TX_PATH_SEC5, 0x00}, +{WCD9360_CDC_TX2_TX_PATH_SEC6, 0x00}, +{WCD9360_CDC_TX3_TX_PATH_CTL, 0x04}, +{WCD9360_CDC_TX3_TX_PATH_CFG0, 0x10}, +{WCD9360_CDC_TX3_TX_PATH_CFG1, 0x03}, +{WCD9360_CDC_TX3_TX_VOL_CTL, 0x00}, +{WCD9360_CDC_TX3_TX_PATH_192_CTL, 0x00}, +{WCD9360_CDC_TX3_TX_PATH_192_CFG, 0x00}, +{WCD9360_CDC_TX3_TX_PATH_SEC0, 0x00}, +{WCD9360_CDC_TX3_TX_PATH_SEC1, 0x00}, +{WCD9360_CDC_TX3_TX_PATH_SEC2, 0x01}, +{WCD9360_CDC_TX3_TX_PATH_SEC3, 0x3C}, +{WCD9360_CDC_TX3_TX_PATH_SEC4, 0x20}, +{WCD9360_CDC_TX3_TX_PATH_SEC5, 0x00}, +{WCD9360_CDC_TX3_TX_PATH_SEC6, 0x00}, +{WCD9360_CDC_TX4_TX_PATH_CTL, 0x04}, +{WCD9360_CDC_TX4_TX_PATH_CFG0, 0x10}, +{WCD9360_CDC_TX4_TX_PATH_CFG1, 0x03}, +{WCD9360_CDC_TX4_TX_VOL_CTL, 0x00}, +{WCD9360_CDC_TX4_TX_PATH_192_CTL, 0x00}, +{WCD9360_CDC_TX4_TX_PATH_192_CFG, 0x00}, +{WCD9360_CDC_TX4_TX_PATH_SEC0, 0x00}, +{WCD9360_CDC_TX4_TX_PATH_SEC1, 0x00}, +{WCD9360_CDC_TX4_TX_PATH_SEC2, 0x01}, +{WCD9360_CDC_TX4_TX_PATH_SEC3, 0x3C}, +{WCD9360_CDC_TX4_TX_PATH_SEC4, 0x20}, +{WCD9360_CDC_TX4_TX_PATH_SEC5, 0x00}, +{WCD9360_CDC_TX4_TX_PATH_SEC6, 0x00}, +{WCD9360_CDC_TX5_TX_PATH_CTL, 0x04}, +{WCD9360_CDC_TX5_TX_PATH_CFG0, 0x10}, +{WCD9360_CDC_TX5_TX_PATH_CFG1, 0x03}, +{WCD9360_CDC_TX5_TX_VOL_CTL, 0x00}, +{WCD9360_CDC_TX5_TX_PATH_192_CTL, 0x00}, +{WCD9360_CDC_TX5_TX_PATH_192_CFG, 0x00}, +{WCD9360_CDC_TX5_TX_PATH_SEC0, 0x00}, +{WCD9360_CDC_TX5_TX_PATH_SEC1, 0x00}, +{WCD9360_CDC_TX5_TX_PATH_SEC2, 0x01}, +{WCD9360_CDC_TX5_TX_PATH_SEC3, 0x3C}, +{WCD9360_CDC_TX5_TX_PATH_SEC4, 0x20}, +{WCD9360_CDC_TX5_TX_PATH_SEC5, 0x00}, +{WCD9360_CDC_TX5_TX_PATH_SEC6, 0x00}, +{WCD9360_CDC_TX6_TX_PATH_CTL, 0x04}, +{WCD9360_CDC_TX6_TX_PATH_CFG0, 0x10}, +{WCD9360_CDC_TX6_TX_PATH_CFG1, 0x03}, +{WCD9360_CDC_TX6_TX_VOL_CTL, 0x00}, +{WCD9360_CDC_TX6_TX_PATH_192_CTL, 0x00}, +{WCD9360_CDC_TX6_TX_PATH_192_CFG, 0x00}, +{WCD9360_CDC_TX6_TX_PATH_SEC0, 0x00}, +{WCD9360_CDC_TX6_TX_PATH_SEC1, 0x00}, +{WCD9360_CDC_TX6_TX_PATH_SEC2, 0x01}, +{WCD9360_CDC_TX6_TX_PATH_SEC3, 0x3C}, +{WCD9360_CDC_TX6_TX_PATH_SEC4, 0x20}, +{WCD9360_CDC_TX6_TX_PATH_SEC5, 0x00}, +{WCD9360_CDC_TX6_TX_PATH_SEC6, 0x00}, +{WCD9360_CDC_TX7_TX_PATH_CTL, 0x04}, +{WCD9360_CDC_TX7_TX_PATH_CFG0, 0x10}, +{WCD9360_CDC_TX7_TX_PATH_CFG1, 0x03}, +{WCD9360_CDC_TX7_TX_VOL_CTL, 0x00}, +{WCD9360_CDC_TX7_TX_PATH_192_CTL, 0x00}, +{WCD9360_CDC_TX7_TX_PATH_192_CFG, 0x00}, +{WCD9360_CDC_TX7_TX_PATH_SEC0, 0x00}, +{WCD9360_CDC_TX7_TX_PATH_SEC1, 0x00}, +{WCD9360_CDC_TX7_TX_PATH_SEC2, 0x01}, +{WCD9360_CDC_TX7_TX_PATH_SEC3, 0x3C}, +{WCD9360_CDC_TX7_TX_PATH_SEC4, 0x20}, +{WCD9360_CDC_TX7_TX_PATH_SEC5, 0x00}, +{WCD9360_CDC_TX7_TX_PATH_SEC6, 0x00}, +{WCD9360_CDC_TX8_TX_PATH_CTL, 0x04}, +{WCD9360_CDC_TX8_TX_PATH_CFG0, 0x10}, +{WCD9360_CDC_TX8_TX_PATH_CFG1, 0x03}, +{WCD9360_CDC_TX8_TX_VOL_CTL, 0x00}, +{WCD9360_CDC_TX8_TX_PATH_192_CTL, 0x00}, +{WCD9360_CDC_TX8_TX_PATH_192_CFG, 0x00}, +{WCD9360_CDC_TX8_TX_PATH_SEC0, 0x00}, +{WCD9360_CDC_TX8_TX_PATH_SEC1, 0x00}, +{WCD9360_CDC_TX8_TX_PATH_SEC2, 0x01}, +{WCD9360_CDC_TX8_TX_PATH_SEC3, 0x3C}, +{WCD9360_CDC_TX8_TX_PATH_SEC4, 0x20}, +{WCD9360_CDC_TX8_TX_PATH_SEC5, 0x00}, +{WCD9360_CDC_TX8_TX_PATH_SEC6, 0x00}, +{WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x02}, +{WCD9360_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x00}, +{WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x02}, +{WCD9360_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x00}, +{WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x02}, +{WCD9360_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x00}, +{WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x02}, +{WCD9360_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x00}, +{WCD9360_PAGE11_PAGE_REGISTER, 0x00}, +{WCD9360_CDC_COMPANDER0_CTL0, 0x60}, +{WCD9360_CDC_COMPANDER0_CTL1, 0xDB}, +{WCD9360_CDC_COMPANDER0_CTL2, 0xFF}, +{WCD9360_CDC_COMPANDER0_CTL3, 0x35}, +{WCD9360_CDC_COMPANDER0_CTL4, 0xFF}, +{WCD9360_CDC_COMPANDER0_CTL5, 0x00}, +{WCD9360_CDC_COMPANDER0_CTL6, 0x01}, +{WCD9360_CDC_COMPANDER0_CTL7, 0x06}, +{WCD9360_CDC_COMPANDER7_CTL0, 0x60}, +{WCD9360_CDC_COMPANDER7_CTL1, 0xDB}, +{WCD9360_CDC_COMPANDER7_CTL2, 0xFF}, +{WCD9360_CDC_COMPANDER7_CTL3, 0x35}, +{WCD9360_CDC_COMPANDER7_CTL4, 0xFF}, +{WCD9360_CDC_COMPANDER7_CTL5, 0x00}, +{WCD9360_CDC_COMPANDER7_CTL6, 0x01}, +{WCD9360_CDC_COMPANDER7_CTL7, 0x06}, +{WCD9360_CDC_COMPANDER8_CTL0, 0x60}, +{WCD9360_CDC_COMPANDER8_CTL1, 0xDB}, +{WCD9360_CDC_COMPANDER8_CTL2, 0xFF}, +{WCD9360_CDC_COMPANDER8_CTL3, 0x35}, +{WCD9360_CDC_COMPANDER8_CTL4, 0xFF}, +{WCD9360_CDC_COMPANDER8_CTL5, 0x00}, +{WCD9360_CDC_COMPANDER8_CTL6, 0x01}, +{WCD9360_CDC_COMPANDER8_CTL7, 0x06}, +{WCD9360_CDC_RX0_RX_PATH_CTL, 0x04}, +{WCD9360_CDC_RX0_RX_PATH_CFG0, 0x00}, +{WCD9360_CDC_RX0_RX_PATH_CFG1, 0x64}, +{WCD9360_CDC_RX0_RX_PATH_CFG2, 0x80}, +{WCD9360_CDC_RX0_RX_VOL_CTL, 0x00}, +{WCD9360_CDC_RX0_RX_PATH_MIX_CTL, 0x04}, +{WCD9360_CDC_RX0_RX_PATH_MIX_CFG, 0x12}, +{WCD9360_CDC_RX0_RX_VOL_MIX_CTL, 0x00}, +{WCD9360_CDC_RX0_RX_PATH_SEC0, 0xFC}, +{WCD9360_CDC_RX0_RX_PATH_SEC1, 0x08}, +{WCD9360_CDC_RX0_RX_PATH_SEC2, 0x00}, +{WCD9360_CDC_RX0_RX_PATH_SEC3, 0x00}, +{WCD9360_CDC_RX0_RX_PATH_SEC5, 0x00}, +{WCD9360_CDC_RX0_RX_PATH_SEC6, 0x00}, +{WCD9360_CDC_RX0_RX_PATH_SEC7, 0x00}, +{WCD9360_CDC_RX0_RX_PATH_MIX_SEC0, 0x08}, +{WCD9360_CDC_RX0_RX_PATH_MIX_SEC1, 0x00}, +{WCD9360_CDC_RX0_RX_PATH_DSMDEM_CTL, 0x00}, +{WCD9360_CDC_RX9_RX_PATH_CTL, 0x04}, +{WCD9360_CDC_RX9_RX_PATH_CFG0, 0x00}, +{WCD9360_CDC_RX9_RX_PATH_CFG1, 0x64}, +{WCD9360_CDC_RX9_RX_PATH_CFG2, 0x80}, +{WCD9360_CDC_RX9_RX_VOL_CTL, 0x00}, +{WCD9360_CDC_RX9_RX_PATH_MIX_CTL, 0x04}, +{WCD9360_CDC_RX9_RX_PATH_MIX_CFG, 0x12}, +{WCD9360_CDC_RX9_RX_VOL_MIX_CTL, 0x00}, +{WCD9360_CDC_RX9_RX_PATH_SEC0, 0xFC}, +{WCD9360_CDC_RX9_RX_PATH_SEC1, 0x08}, +{WCD9360_CDC_RX9_RX_PATH_SEC2, 0x00}, +{WCD9360_CDC_RX9_RX_PATH_SEC3, 0x00}, +{WCD9360_CDC_RX9_RX_PATH_SEC5, 0x00}, +{WCD9360_CDC_RX9_RX_PATH_SEC6, 0x00}, +{WCD9360_CDC_RX9_RX_PATH_SEC7, 0x00}, +{WCD9360_CDC_RX9_RX_PATH_MIX_SEC0, 0x08}, +{WCD9360_CDC_RX9_RX_PATH_MIX_SEC1, 0x00}, +{WCD9360_CDC_RX9_RX_PATH_DSMDEM_CTL, 0x00}, +{WCD9360_CDC_RX7_RX_PATH_CTL, 0x04}, +{WCD9360_CDC_RX7_RX_PATH_CFG0, 0x00}, +{WCD9360_CDC_RX7_RX_PATH_CFG1, 0x64}, +{WCD9360_CDC_RX7_RX_PATH_CFG2, 0x80}, +{WCD9360_CDC_RX7_RX_VOL_CTL, 0x00}, +{WCD9360_CDC_RX7_RX_PATH_MIX_CTL, 0x04}, +{WCD9360_CDC_RX7_RX_PATH_MIX_CFG, 0x12}, +{WCD9360_CDC_RX7_RX_VOL_MIX_CTL, 0x00}, +{WCD9360_CDC_RX7_RX_PATH_SEC0, 0x04}, +{WCD9360_CDC_RX7_RX_PATH_SEC1, 0x08}, +{WCD9360_CDC_RX7_RX_PATH_SEC2, 0x00}, +{WCD9360_CDC_RX7_RX_PATH_SEC3, 0x00}, +{WCD9360_CDC_RX7_RX_PATH_SEC5, 0x00}, +{WCD9360_CDC_RX7_RX_PATH_SEC6, 0x00}, +{WCD9360_CDC_RX7_RX_PATH_SEC7, 0x00}, +{WCD9360_CDC_RX7_RX_PATH_MIX_SEC0, 0x08}, +{WCD9360_CDC_RX7_RX_PATH_MIX_SEC1, 0x00}, +{WCD9360_CDC_RX7_RX_PATH_DSMDEM_CTL, 0x00}, +{WCD9360_CDC_RX8_RX_PATH_CTL, 0x04}, +{WCD9360_CDC_RX8_RX_PATH_CFG0, 0x00}, +{WCD9360_CDC_RX8_RX_PATH_CFG1, 0x64}, +{WCD9360_CDC_RX8_RX_PATH_CFG2, 0x80}, +{WCD9360_CDC_RX8_RX_VOL_CTL, 0x00}, +{WCD9360_CDC_RX8_RX_PATH_MIX_CTL, 0x04}, +{WCD9360_CDC_RX8_RX_PATH_MIX_CFG, 0x12}, +{WCD9360_CDC_RX8_RX_VOL_MIX_CTL, 0x00}, +{WCD9360_CDC_RX8_RX_PATH_SEC0, 0x04}, +{WCD9360_CDC_RX8_RX_PATH_SEC1, 0x08}, +{WCD9360_CDC_RX8_RX_PATH_SEC2, 0x00}, +{WCD9360_CDC_RX8_RX_PATH_SEC3, 0x00}, +{WCD9360_CDC_RX8_RX_PATH_SEC5, 0x00}, +{WCD9360_CDC_RX8_RX_PATH_SEC6, 0x00}, +{WCD9360_CDC_RX8_RX_PATH_SEC7, 0x00}, +{WCD9360_CDC_RX8_RX_PATH_MIX_SEC0, 0x08}, +{WCD9360_CDC_RX8_RX_PATH_MIX_SEC1, 0x00}, +{WCD9360_CDC_RX8_RX_PATH_DSMDEM_CTL, 0x00}, +{WCD9360_PAGE12_PAGE_REGISTER, 0x00}, +{WCD9360_CDC_BOOST0_BOOST_PATH_CTL, 0x00}, +{WCD9360_CDC_BOOST0_BOOST_CTL, 0xD0}, +{WCD9360_CDC_BOOST0_BOOST_CFG1, 0x89}, +{WCD9360_CDC_BOOST0_BOOST_CFG2, 0x04}, +{WCD9360_CDC_BOOST1_BOOST_PATH_CTL, 0x00}, +{WCD9360_CDC_BOOST1_BOOST_CTL, 0xD0}, +{WCD9360_CDC_BOOST1_BOOST_CFG1, 0x89}, +{WCD9360_CDC_BOOST1_BOOST_CFG2, 0x04}, +{WCD9360_MIXING_ASRC2_CLK_RST_CTL, 0x00}, +{WCD9360_MIXING_ASRC2_CTL0, 0x00}, +{WCD9360_MIXING_ASRC2_CTL1, 0x00}, +{WCD9360_MIXING_ASRC2_FIFO_CTL, 0xA8}, +{WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_LSB, 0x00}, +{WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_MSB, 0x00}, +{WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_LSB, 0x00}, +{WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_MSB, 0x00}, +{WCD9360_MIXING_ASRC2_STATUS_FIFO, 0x00}, +{WCD9360_MIXING_ASRC3_CLK_RST_CTL, 0x00}, +{WCD9360_MIXING_ASRC3_CTL0, 0x00}, +{WCD9360_MIXING_ASRC3_CTL1, 0x00}, +{WCD9360_MIXING_ASRC3_FIFO_CTL, 0xA8}, +{WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_LSB, 0x00}, +{WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_MSB, 0x00}, +{WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_LSB, 0x00}, +{WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_MSB, 0x00}, +{WCD9360_MIXING_ASRC3_STATUS_FIFO, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_WR_DATA_0, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_WR_DATA_1, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_WR_DATA_2, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_WR_DATA_3, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_WR_ADDR_0, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_WR_ADDR_1, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_WR_ADDR_2, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_WR_ADDR_3, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_RD_ADDR_0, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_RD_ADDR_1, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_RD_ADDR_2, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_RD_ADDR_3, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_RD_DATA_0, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_RD_DATA_1, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_RD_DATA_2, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_RD_DATA_3, 0x00}, +{WCD9360_SWR_AHB_BRIDGE_ACCESS_CFG, 0x0F}, +{WCD9360_SWR_AHB_BRIDGE_ACCESS_STATUS, 0x03}, +{WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL, 0x04}, +{WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1, 0x00}, +{WCD9360_SIDETONE_ASRC0_CLK_RST_CTL, 0x00}, +{WCD9360_SIDETONE_ASRC0_CTL0, 0x00}, +{WCD9360_SIDETONE_ASRC0_CTL1, 0x00}, +{WCD9360_SIDETONE_ASRC0_FIFO_CTL, 0xA8}, +{WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00}, +{WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00}, +{WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00}, +{WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00}, +{WCD9360_SIDETONE_ASRC0_STATUS_FIFO, 0x00}, +{WCD9360_EC_REF_HQ0_EC_REF_HQ_PATH_CTL, 0x00}, +{WCD9360_EC_REF_HQ0_EC_REF_HQ_CFG0, 0x01}, +{WCD9360_EC_REF_HQ1_EC_REF_HQ_PATH_CTL, 0x00}, +{WCD9360_EC_REF_HQ1_EC_REF_HQ_CFG0, 0x01}, +{WCD9360_EC_ASRC0_CLK_RST_CTL, 0x00}, +{WCD9360_EC_ASRC0_CTL0, 0x00}, +{WCD9360_EC_ASRC0_CTL1, 0x00}, +{WCD9360_EC_ASRC0_FIFO_CTL, 0xA8}, +{WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00}, +{WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00}, +{WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00}, +{WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00}, +{WCD9360_EC_ASRC0_STATUS_FIFO, 0x00}, +{WCD9360_EC_ASRC1_CLK_RST_CTL, 0x00}, +{WCD9360_EC_ASRC1_CTL0, 0x00}, +{WCD9360_EC_ASRC1_CTL1, 0x00}, +{WCD9360_EC_ASRC1_FIFO_CTL, 0xA8}, +{WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00}, +{WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00}, +{WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00}, +{WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00}, +{WCD9360_EC_ASRC1_STATUS_FIFO, 0x00}, +{WCD9360_PAGE13_PAGE_REGISTER, 0x00}, +{WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0, 0x00}, +{WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1, 0x00}, +{WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0, 0x00}, +{WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1, 0x00}, +{WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0, 0x00}, +{WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1, 0x00}, +{WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0, 0x00}, +{WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1, 0x00}, +{WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG0, 0x00}, +{WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG1, 0x00}, +{WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG2, 0x00}, +{WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG3, 0x00}, +{WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG4, 0x00}, +{WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0x00}, +{WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 0x00}, +{WCD9360_CDC_RX_INP_MUX_ANC_CFG0, 0x00}, +{WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 0x00}, +{WCD9360_CDC_RX_INP_MUX_EC_REF_HQ_CFG0, 0x00}, +{WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0x00}, +{WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0x00}, +{WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0x00}, +{WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0x00}, +{WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0x00}, +{WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0x00}, +{WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0x00}, +{WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0x00}, +{WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0x00}, +{WCD9360_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0x00}, +{WCD9360_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0x00}, +{WCD9360_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0x00}, +{WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0x00}, +{WCD9360_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0x00}, +{WCD9360_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0x00}, +{WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0x00}, +{WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1, 0x00}, +{WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2, 0x00}, +{WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3, 0x00}, +{WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0, 0x00}, +{WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1, 0x00}, +{WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2, 0x00}, +{WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3, 0x00}, +{WCD9360_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x00}, +{WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00}, +{WCD9360_CDC_CLK_RST_CTRL_SWR_CONTROL, 0x00}, +{WCD9360_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL, 0x0A}, +{WCD9360_CDC_PROX_DETECT_PROX_CTL, 0x08}, +{WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD0, 0x00}, +{WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD1, 0x4B}, +{WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB, 0x00}, +{WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB, 0x00}, +{WCD9360_CDC_PROX_DETECT_PROX_STATUS, 0x00}, +{WCD9360_CDC_PROX_DETECT_PROX_TEST_CTRL, 0x00}, +{WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB, 0x00}, +{WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB, 0x00}, +{WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD, 0x00}, +{WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD, 0x00}, +{WCD9360_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT, 0x00}, +{WCD9360_CDC_SIDETONE_IIR0_IIR_PATH_CTL, 0x00}, +{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0x00}, +{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0x00}, +{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0x00}, +{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0x00}, +{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL, 0x00}, +{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL, 0x00}, +{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL, 0x00}, +{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL, 0x00}, +{WCD9360_CDC_SIDETONE_IIR0_IIR_CTL, 0x40}, +{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL, 0x00}, +{WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, 0x00}, +{WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL, 0x00}, +{WCD9360_CDC_TOP_TOP_CFG0, 0x00}, +{WCD9360_CDC_TOP_TOP_CFG1, 0x00}, +{WCD9360_CDC_TOP_TOP_CFG7, 0x00}, +{WCD9360_CDC_TOP_EAR_COMP_WR_LSB, 0x00}, +{WCD9360_CDC_TOP_EAR_COMP_WR_MSB, 0x00}, +{WCD9360_CDC_TOP_EAR_COMP_LUT, 0x00}, +{WCD9360_CDC_TOP_EAR_COMP_RD_LSB, 0x00}, +{WCD9360_CDC_TOP_EAR_COMP_RD_MSB, 0x00}, +{WCD9360_CDC_TOP_TOP_DEBUG, 0x00}, +{WCD9360_PAGE80_PAGE_REGISTER, 0x00}, +{WCD9360_CODEC_CPR_WR_DATA_0, 0x00}, +{WCD9360_CODEC_CPR_WR_DATA_1, 0x00}, +{WCD9360_CODEC_CPR_WR_DATA_2, 0x00}, +{WCD9360_CODEC_CPR_WR_DATA_3, 0x00}, +{WCD9360_CODEC_CPR_WR_ADDR_0, 0x00}, +{WCD9360_CODEC_CPR_WR_ADDR_1, 0x00}, +{WCD9360_CODEC_CPR_WR_ADDR_2, 0x00}, +{WCD9360_CODEC_CPR_WR_ADDR_3, 0x00}, +{WCD9360_CODEC_CPR_RD_ADDR_0, 0x00}, +{WCD9360_CODEC_CPR_RD_ADDR_1, 0x00}, +{WCD9360_CODEC_CPR_RD_ADDR_2, 0x00}, +{WCD9360_CODEC_CPR_RD_ADDR_3, 0x00}, +{WCD9360_CODEC_CPR_RD_DATA_0, 0x00}, +{WCD9360_CODEC_CPR_RD_DATA_1, 0x00}, +{WCD9360_CODEC_CPR_RD_DATA_2, 0x00}, +{WCD9360_CODEC_CPR_RD_DATA_3, 0x00}, +{WCD9360_CODEC_CPR_ACCESS_CFG, 0x0F}, +{WCD9360_CODEC_CPR_ACCESS_STATUS, 0x03}, +{WCD9360_CODEC_CPR_NOM_CX_VDD, 0xB4}, +{WCD9360_CODEC_CPR_SVS_CX_VDD, 0x7C}, +{WCD9360_CODEC_CPR_SVS2_CX_VDD, 0x58}, +{WCD9360_CODEC_CPR_NOM_MX_VDD, 0xB4}, +{WCD9360_CODEC_CPR_SVS_MX_VDD, 0xB4}, +{WCD9360_CODEC_CPR_SVS2_MX_VDD, 0xA0}, +{WCD9360_CODEC_CPR_SVS2_MIN_CX_VDD, 0x2C}, +{WCD9360_CODEC_CPR_MAX_SVS2_STEP, 0x08}, +{WCD9360_CODEC_CPR_CTL, 0x00}, +{WCD9360_CODEC_CPR_SW_MODECHNG_STATUS, 0x00}, +{WCD9360_CODEC_CPR_SW_MODECHNG_START, 0x00}, +{WCD9360_CODEC_CPR_CPR_STATUS, 0x00}, +{WCD9360_PAGE128_PAGE_REGISTER, 0x00}, +{WCD9360_TLMM_JTCK_PINCFG, 0x00}, +{WCD9360_TLMM_INTR1_PINCFG, 0x00}, +{WCD9360_TLMM_INTR2_PINCFG, 0x00}, +{WCD9360_TLMM_SWR_DATA_PINCFG, 0x00}, +{WCD9360_TLMM_SWR_CLK_PINCFG, 0x00}, +{WCD9360_TLMM_SLIMBUS_DATA1_PINCFG, 0x00}, +{WCD9360_TLMM_SLIMBUS_DATA2_PINCFG, 0x00}, +{WCD9360_TLMM_SLIMBUS_CLK_PINCFG, 0x00}, +{WCD9360_TLMM_I2C_CLK_PINCFG, 0x00}, +{WCD9360_TLMM_I2C_DATA_PINCFG, 0x00}, +{WCD9360_TLMM_I2S_0_RX_PINCFG, 0x00}, +{WCD9360_TLMM_I2S_0_TX_PINCFG, 0x00}, +{WCD9360_TLMM_I2S_0_SCK_PINCFG, 0x00}, +{WCD9360_TLMM_I2S_0_WS_PINCFG, 0x00}, +{WCD9360_TLMM_I2S_1_RX_PINCFG, 0x00}, +{WCD9360_TLMM_I2S_1_TX_PINCFG, 0x00}, +{WCD9360_TLMM_I2S_1_SCK_PINCFG, 0x00}, +{WCD9360_TLMM_I2S_1_WS_PINCFG, 0x00}, +{WCD9360_TLMM_DMIC1_CLK_PINCFG, 0x00}, +{WCD9360_TLMM_DMIC1_DATA_PINCFG, 0x00}, +{WCD9360_TLMM_DMIC2_CLK_PINCFG, 0x00}, +{WCD9360_TLMM_DMIC2_DATA_PINCFG, 0x00}, +{WCD9360_TLMM_GPIO1_PINCFG, 0x00}, +{WCD9360_TLMM_GPIO2_PINCFG, 0x00}, +{WCD9360_TLMM_GPIO3_PINCFG, 0x00}, +{WCD9360_TLMM_GPIO4_PINCFG, 0x00}, +{WCD9360_TLMM_SPI_S_CSN_PINCFG, 0x00}, +{WCD9360_TLMM_SPI_S_CLK_PINCFG, 0x00}, +{WCD9360_TLMM_SPI_S_DOUT_PINCFG, 0x00}, +{WCD9360_TLMM_SPI_S_DIN_PINCFG, 0x00}, +{WCD9360_TLMM_GPIO0_PINCFG, 0x00}, +{WCD9360_TLMM_DMIC3_CLK_PINCFG, 0x00}, +{WCD9360_TLMM_DMIC3_DATA_PINCFG, 0x00}, +{WCD9360_TLMM_DMIC4_CLK_PINCFG, 0x00}, +{WCD9360_TLMM_DMIC4_DATA_PINCFG, 0x00}, +{WCD9360_TEST_DEBUG_PIN_CTL_OE_0, 0x00}, +{WCD9360_TEST_DEBUG_PIN_CTL_OE_1, 0x00}, +{WCD9360_TEST_DEBUG_PIN_CTL_OE_2, 0x00}, +{WCD9360_TEST_DEBUG_PIN_CTL_OE_3, 0x00}, +{WCD9360_TEST_DEBUG_PIN_CTL_OE_4, 0x00}, +{WCD9360_TEST_DEBUG_PIN_CTL_DATA_0, 0x00}, +{WCD9360_TEST_DEBUG_PIN_CTL_DATA_1, 0x00}, +{WCD9360_TEST_DEBUG_PIN_CTL_DATA_2, 0x00}, +{WCD9360_TEST_DEBUG_PIN_CTL_DATA_3, 0x00}, +{WCD9360_TEST_DEBUG_PIN_CTL_DATA_4, 0x00}, +{WCD9360_TEST_DEBUG_PAD_DRVCTL_0, 0x00}, +{WCD9360_TEST_DEBUG_PAD_DRVCTL_1, 0x00}, +{WCD9360_TEST_DEBUG_PIN_STATUS, 0x00}, +{WCD9360_TEST_DEBUG_NPL_DLY_TEST_1, 0x10}, +{WCD9360_TEST_DEBUG_NPL_DLY_TEST_2, 0x60}, +{WCD9360_TEST_DEBUG_MEM_CTRL, 0x00}, +{WCD9360_TEST_DEBUG_DEBUG_BUS_SEL, 0x00}, +{WCD9360_TEST_DEBUG_DEBUG_JTAG, 0x00}, +{WCD9360_TEST_DEBUG_DEBUG_EN_1, 0x00}, +{WCD9360_TEST_DEBUG_DEBUG_EN_2, 0x00}, +{WCD9360_TEST_DEBUG_DEBUG_EN_3, 0x00}, +{WCD9360_TEST_DEBUG_DEBUG_EN_4, 0x00}, +{WCD9360_TEST_DEBUG_DEBUG_EN_5, 0x00}, +{WCD9360_TEST_DEBUG_ANA_DTEST_DIR, 0x00}, +{WCD9360_TEST_DEBUG_PAD_INP_DISABLE_0, 0x00}, +{WCD9360_TEST_DEBUG_PAD_INP_DISABLE_1, 0x00}, +{WCD9360_TEST_DEBUG_PAD_INP_DISABLE_2, 0x00}, +{WCD9360_TEST_DEBUG_PAD_INP_DISABLE_3, 0x00}, +{WCD9360_TEST_DEBUG_PAD_INP_DISABLE_4, 0x00}, +{WCD9360_TEST_DEBUG_SYSMEM_CTRL, 0x00}, +{WCD9360_TEST_DEBUG_LVAL_NOM_LOW, 0x96}, +{WCD9360_TEST_DEBUG_LVAL_NOM_HIGH, 0x00}, +{WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_LOW, 0x53}, +{WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_HIGH, 0x00}, +{WCD9360_TEST_DEBUG_SPI_SLAVE_CHAR, 0x00}, +{WCD9360_TEST_DEBUG_CODEC_DIAGS, 0x00}, +}; + + +const u8 wcd9360_page0_reg_access[WCD9360_PAGE_SIZE] = { +[WCD9360_REG(WCD9360_PAGE0_PAGE_REGISTER)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_RPM_CLK_BYPASS)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_RPM_CLK_GATE)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_RPM_CLK_MCLK_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_RPM_CLK_MCLK2_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_RPM_I2S_DSD_CLK_SEL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_RPM_RST_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE0)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE1)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE2)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE3)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_EFUSE_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_EFUSE_TEST0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_EFUSE_TEST1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_EFUSE_STATUS)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_I2C_ACTIVE)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_ALT_FUNC_EN)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_GPIO_CTL_OE)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_GPIO_CTL_DATA)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_RX0_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_RX1_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_RX2_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_RX3_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_RX4_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_RX5_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_RX6_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_RX7_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_SB_TX0_INP_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_SB_TX1_INP_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_SB_TX2_INP_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_SB_TX3_INP_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_SB_TX4_INP_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_SB_TX5_INP_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_SB_TX6_INP_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_SB_TX7_INP_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_SB_TX8_INP_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_SB_TX9_INP_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_SB_TX10_INP_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_SB_TX11_INP_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_SB_TX12_INP_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_SB_TX13_INP_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_SB_TX14_INP_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_SB_TX15_INP_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_TX0_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_TX0_CFG2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_TX1_0_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_TX1_1_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_DATA_HUB_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_1_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_CTL2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_1_CTL2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_CLKSRC_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_COMMON_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_CTL2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_CH_RX)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_CH_TX)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_STRETCH)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DATA_HUB_I2S_RESET_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_RDMA_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_RDMA_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_RDMA_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_RDMA_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_RDMA_CTL_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_RDMA_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_RDMA_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_RDMA_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_RDMA_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_RDMA_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_RDMA_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_RDMA_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_RDMA_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_RDMA_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_RDMA_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_RDMA4_PRT_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_RDMA_SBTX0_7_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_RDMA_SBTX8_10_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_WDMA_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_WDMA_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_WDMA_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_WDMA_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_WDMA_CTL_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_4_5_CFG_WDMA_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_4_5_CFG_WDMA_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_4_5_CFG_WDMA_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_4_5_CFG_WDMA_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_4_5_CFG_WDMA_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_WDMA_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_WDMA_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_WDMA_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_WDMA_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_WDMA_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_WDMA_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_WDMA_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_WDMA_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_WDMA_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_WDMA_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_WDMA0_PRT_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_WDMA3_PRT_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_WDMA4_PRT0_3_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DMA_WDMA4_PRT4_7_CFG)] = WCD9360_RW, +}; + +const u8 wcd9360_page1_reg_access[WCD9360_PAGE_SIZE] = { +[WCD9360_REG(WCD9360_PAGE1_PAGE_REGISTER)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_8)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_9)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_L_VAL_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_L_VAL_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_DSM_FRAC_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_DSM_FRAC_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_CONFIG_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_CONFIG_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_CONFIG_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_CONFIG_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_CONFIG_CTL_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_FREQ_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_FREQ_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_FREQ_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_FREQ_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_SSC_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_SSC_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_SSC_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_SSC_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_FLL_MODE)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_FLL_STATUS_0)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_FLL_STATUS_1)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_FLL_STATUS_2)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_FLL_STATUS_3)] = WCD9360_RO, +[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_8)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_9)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_L_VAL_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_L_VAL_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_DSM_FRAC_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_DSM_FRAC_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_CONFIG_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_CONFIG_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_CONFIG_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_CONFIG_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_CONFIG_CTL_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_FREQ_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_FREQ_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_FREQ_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_FREQ_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_SSC_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_SSC_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_SSC_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_SSC_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_FLL_MODE)] = WCD9360_RW, +[WCD9360_REG(WCD9360_I2S_FLL_STATUS_0)] = WCD9360_RO, +[WCD9360_REG(WCD9360_I2S_FLL_STATUS_1)] = WCD9360_RO, +[WCD9360_REG(WCD9360_I2S_FLL_STATUS_2)] = WCD9360_RO, +[WCD9360_REG(WCD9360_I2S_FLL_STATUS_3)] = WCD9360_RO, +}; + +const u8 wcd9360_page2_reg_access[WCD9360_PAGE_SIZE] = { +[WCD9360_REG(WCD9360_PAGE2_PAGE_REGISTER)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_CPE_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_PWR_CPEFLL_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_US_BUF_INT_PERIOD)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_SVA_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_US_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_MAD_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_CPAR_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_DMIC0_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_DMIC1_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_DMIC2_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_DMIC_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_CPAR_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_WDOG_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_BACKUP_INT)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_STATUS)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_CPE_OCD_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_MASK_1A)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_MASK_1B)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0A)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0B)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1A)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1B)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0A)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0B)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1A)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1B)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_DMIC3_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_WDOG_RESET)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_MCLK_PRG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_0)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_1)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_2)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_3)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_4)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_5)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_6)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_7)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_8)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_9)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_10)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_11)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_12)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_13)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_14)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_15)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_0)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_1)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_2)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_3)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_4)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_5)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_6)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_7)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_8)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_9)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_10)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_11)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_12)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_13)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_14)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_15)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_LPASS_ARB_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_0)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_1)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_MAIN_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_MAIN_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_8)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_IIR_CTL_PTR)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_IIR_CTL_VAL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_8)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_BEACON_IIR_CTL_PTR)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_BEACON_IIR_CTL_VAL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_INP_SEL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SOC_MAD_MAD2_INP_SEL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_CTRL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_STATUS)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_FS)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_IN_SEL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT0)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT1)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT2)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT3)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT4)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT5)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT6)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT7)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT8)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT9)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT10)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT11)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT12)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT13)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT14)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT15)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT0)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT1)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT2)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT3)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT4)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT5)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT6)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT7)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT8)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT9)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT10)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT11)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT12)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT13)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT14)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT15)] = WCD9360_RO, +}; + +const u8 wcd9360_page4_reg_access[WCD9360_PAGE_SIZE] = { +[WCD9360_REG(WCD9360_PAGE4_PAGE_REGISTER)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_CLR_COMMIT)] = WCD9360_WO, +[WCD9360_REG(WCD9360_INTR_PIN1_MASK0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_PIN1_MASK1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_PIN1_MASK2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_PIN1_MASK3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_PIN1_STATUS0)] = WCD9360_RO, +[WCD9360_REG(WCD9360_INTR_PIN1_STATUS1)] = WCD9360_RO, +[WCD9360_REG(WCD9360_INTR_PIN1_STATUS2)] = WCD9360_RO, +[WCD9360_REG(WCD9360_INTR_PIN1_STATUS3)] = WCD9360_RO, +[WCD9360_REG(WCD9360_INTR_PIN1_CLEAR0)] = WCD9360_WO, +[WCD9360_REG(WCD9360_INTR_PIN1_CLEAR1)] = WCD9360_WO, +[WCD9360_REG(WCD9360_INTR_PIN1_CLEAR2)] = WCD9360_WO, +[WCD9360_REG(WCD9360_INTR_PIN1_CLEAR3)] = WCD9360_WO, +[WCD9360_REG(WCD9360_INTR_PIN2_MASK3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_PIN2_STATUS3)] = WCD9360_RO, +[WCD9360_REG(WCD9360_INTR_PIN2_CLEAR3)] = WCD9360_WO, +[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_MASK2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_MASK3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_STATUS2)] = WCD9360_RO, +[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_STATUS3)] = WCD9360_RO, +[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_CLEAR2)] = WCD9360_WO, +[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_CLEAR3)] = WCD9360_WO, +[WCD9360_REG(WCD9360_INTR_LEVEL0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_LEVEL1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_LEVEL2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_LEVEL3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_BYPASS0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_BYPASS1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_BYPASS2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_BYPASS3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_SET0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_SET1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_SET2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_SET3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_CODEC_MISC_MASK)] = WCD9360_RW, +[WCD9360_REG(WCD9360_INTR_CODEC_MISC_STATUS)] = WCD9360_RO, +[WCD9360_REG(WCD9360_INTR_CODEC_MISC_CLEAR)] = WCD9360_WO, +}; + +const u8 wcd9360_page6_reg_access[WCD9360_PAGE_SIZE] = { +[WCD9360_REG(WCD9360_ANA_PAGE_REGISTER)] = WCD9360_RW, +[WCD9360_REG(WCD9360_ANA_BIAS)] = WCD9360_RW, +[WCD9360_REG(WCD9360_ANA_AMIC_INPUT_SWITCH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_ANA_RCO)] = WCD9360_RW, +[WCD9360_REG(WCD9360_ANA_BUCK_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_ANA_BUCK_STATUS)] = WCD9360_RO, +[WCD9360_REG(WCD9360_ANA_EAR)] = WCD9360_RW, +[WCD9360_REG(WCD9360_ANA_MAD_SETUP)] = WCD9360_RW, +[WCD9360_REG(WCD9360_ANA_AMIC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_ANA_AMIC2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_ANA_AMIC3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_ANA_AMIC4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_ANA_MICB1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_ANA_MICB2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_ANA_MICB3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_ANA_MICB4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_BIAS_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_BIAS_VBG_FINE_ADJ)] = WCD9360_RW, +[WCD9360_REG(WCD9360_RCO_CTRL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_RCO_CTRL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_RCO_CAL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_RCO_CAL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_RCO_CAL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_RCO_TEST_CTRL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_RCO_CAL_OUT_1)] = WCD9360_RO, +[WCD9360_REG(WCD9360_RCO_CAL_OUT_2)] = WCD9360_RO, +[WCD9360_REG(WCD9360_RCO_CAL_OUT_3)] = WCD9360_RO, +[WCD9360_REG(WCD9360_RCO_CAL_OUT_4)] = WCD9360_RO, +[WCD9360_REG(WCD9360_RCO_CAL_OUT_5)] = WCD9360_RO, +[WCD9360_REG(WCD9360_SIDO_MODE_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_MODE_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_MODE_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_MODE_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_VCL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_VCL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_VCL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_CCL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_CCL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_CCL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_CCL_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_CCL_5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_CCL_6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_CCL_7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_CCL_8)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_CCL_9)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_CCL_10)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_FILTER_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_FILTER_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_DRIVER_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_DRIVER_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_DRIVER_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_CAL_CODE_EXT_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_CAL_CODE_EXT_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_CAL_CODE_OUT_1)] = WCD9360_RO, +[WCD9360_REG(WCD9360_SIDO_CAL_CODE_OUT_2)] = WCD9360_RO, +[WCD9360_REG(WCD9360_SIDO_TEST_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_TEST_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_LDOH_MODE)] = WCD9360_RW, +[WCD9360_REG(WCD9360_LDOH_BIAS)] = WCD9360_RW, +[WCD9360_REG(WCD9360_LDOH_STB_LOADS)] = WCD9360_RW, +[WCD9360_REG(WCD9360_LDOH_SLOWRAMP)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MICB1_TEST_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MICB1_TEST_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MICB1_TEST_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MICB2_TEST_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MICB2_TEST_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MICB2_TEST_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MICB3_TEST_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MICB3_TEST_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MICB3_TEST_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MICB4_TEST_CTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MICB4_TEST_CTL_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MICB4_TEST_CTL_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_COM_ADC_VCM)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_COM_BIAS_ATEST)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_COM_ADC_INT1_IB)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_COM_ADC_INT2_IB)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_COM_TXFE_DIV_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_COM_TXFE_DIV_START)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_COM_TXFE_DIV_STOP_9P6M)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_COM_TXFE_DIV_STOP_12P288M)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_1_2_TEST_EN)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_1_2_ADC_IB)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_1_2_ATEST_REFCTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_1_2_TEST_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_1_2_TEST_BLK_EN)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_1_2_TXFE_CLKDIV)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_1_2_SAR1_ERR)] = WCD9360_RO, +[WCD9360_REG(WCD9360_TX_1_2_SAR2_ERR)] = WCD9360_RO, +[WCD9360_REG(WCD9360_TX_3_4_TEST_EN)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_3_4_ADC_IB)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_3_4_ATEST_REFCTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_3_4_TEST_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_3_4_TEST_BLK_EN)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_3_4_TXFE_CLKDIV)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TX_3_4_SAR1_ERR)] = WCD9360_RO, +[WCD9360_REG(WCD9360_TX_3_4_SAR2_ERR)] = WCD9360_RO, +[WCD9360_REG(WCD9360_RX_RX_EAR_BIAS_CON_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_RX_RX_EAR_BIAS_CON_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_RX_RX_AUX_BIAS_CON_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_RX_RX_AUX_BIAS_CON_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_RX_RX_BIAS_ATEST)] = WCD9360_RW, +[WCD9360_REG(WCD9360_RX_RXTOP_RESERVED)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EAR_EAR_EN_REG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EAR_EAR_PA_CON)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EAR_EAR_SP_CON)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EAR_EAR_DAC_CON)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EAR_EAR_CNP_FSM_CON)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EAR_DAC_CTL_TEST)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EAR_STATUS_REG)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EAR_EAR_COMPANDER_CON)] = WCD9360_RW, +}; + +const u8 wcd9360_page7_reg_access[WCD9360_PAGE_SIZE] = { +[WCD9360_REG(WCD9360_ANA_NEW_PAGE_REGISTER)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_PLL_ENABLES)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_PLL_PRESET)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_PLL_STATUS)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CLK_SYS_MCLK_PRG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_MCLK2_PRG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_MCLK_MISC)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_VOUT_A_STARTUP)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_VOUT_D_STARTUP)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_VOUT_D_FREQ1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_VOUT_D_FREQ2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_AUX_ANA_EAR)] = WCD9360_RW, +[WCD9360_REG(WCD9360_LDORXTX_LDORXTX)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DIE_CRACK_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DIE_CRACK_OUT)] = WCD9360_RO, +[WCD9360_REG(WCD9360_LOOP_BACK_EN)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_POST_DIV_REG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_POST_DIV_REG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_REF_DIV_REG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_REF_DIV_REG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_FILTER_REG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_FILTER_REG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_PLL_L_VAL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_PLL_M_VAL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_PLL_N_VAL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_TEST_REG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_PFD_CP_DSM_PROG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_VCO_PROG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_TEST_REG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_LDO_LOCK_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_DIG_LOCK_DET_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_CLK_TEST1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_CLK_TEST2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CLK_SYS_INT_CLK_TEST3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_STATUS)] = WCD9360_RO, +[WCD9360_REG(WCD9360_SIDO_NEW_INT_SPARE_1)] = WCD9360_RO, +[WCD9360_REG(WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_A)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_D)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_INC_WAIT)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_IBLEED_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_INT_DEBUG_CPROVR_TEST)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_CTL_A)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_CTL_D)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_TIMEOUT_PERIOD)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EAR_INT_NEW_EAR_CHOPPER_CON)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EAR_INT_NEW_EAR_DYNAMIC_BIAS)] = WCD9360_RW, +[WCD9360_REG(WCD9360_AUX_INT_AUX_EN_REG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_AUX_INT_AUX_PA_CON)] = WCD9360_RW, +[WCD9360_REG(WCD9360_AUX_INT_AUX_SP_CON)] = WCD9360_RW, +[WCD9360_REG(WCD9360_AUX_INT_AUX_DAC_CON)] = WCD9360_RW, +[WCD9360_REG(WCD9360_AUX_INT_AUX_CNP_FSM_CON)] = WCD9360_RW, +[WCD9360_REG(WCD9360_AUX_INT_AUX_TEST)] = WCD9360_RW, +[WCD9360_REG(WCD9360_AUX_INT_STATUS_REG)] = WCD9360_RO, +[WCD9360_REG(WCD9360_AUX_INT_AUX_MISC)] = WCD9360_RW, +[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_STATUS)] = WCD9360_RO, +[WCD9360_REG(WCD9360_DIE_CRACK_INT_INT1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_DIE_CRACK_INT_INT2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_LOOP_BACK_INT_SPARE)] = WCD9360_RW, +}; + +const u8 wcd9360_page10_reg_access[WCD9360_PAGE_SIZE] = { +[WCD9360_REG(WCD9360_PAGE10_PAGE_REGISTER)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_ANC0_CLK_RESET_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_ANC0_MODE_1_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_ANC0_MODE_2_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_ANC0_FF_SHIFT)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_ANC0_FB_SHIFT)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_ANC0_LPF_FF_A_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_ANC0_LPF_FF_B_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_ANC0_LPF_FB_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_ANC0_SMLPF_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_ANC0_DCFLT_SHIFT_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_ANC0_IIR_ADAPT_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_ANC0_IIR_COEFF_1_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_ANC0_IIR_COEFF_2_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_ANC0_FF_A_GAIN_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_ANC0_FF_B_GAIN_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_ANC0_FB_GAIN_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX0_TX_VOL_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_192_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_192_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX1_TX_VOL_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_192_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_192_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX2_TX_VOL_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_192_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_192_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX3_TX_VOL_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_192_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_192_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX4_TX_VOL_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_192_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_192_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX5_TX_VOL_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_192_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_192_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX6_TX_VOL_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_192_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_192_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX7_TX_VOL_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_192_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_192_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX8_TX_VOL_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_192_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_192_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX9_SPKR_PROT_PATH_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX10_SPKR_PROT_PATH_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX11_SPKR_PROT_PATH_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX12_SPKR_PROT_PATH_CFG0)] = WCD9360_RW, +}; + +const u8 wcd9360_page11_reg_access[WCD9360_PAGE_SIZE] = { +[WCD9360_REG(WCD9360_PAGE11_PAGE_REGISTER)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL6)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL6)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL6)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_CFG2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_VOL_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_MIX_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_MIX_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_VOL_MIX_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_MIX_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_MIX_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_DSMDEM_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_CFG2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_VOL_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_MIX_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_MIX_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_VOL_MIX_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_MIX_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_MIX_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_DSMDEM_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_CFG2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_VOL_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_MIX_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_MIX_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_VOL_MIX_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_MIX_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_MIX_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_DSMDEM_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_CFG2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_VOL_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_MIX_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_MIX_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_VOL_MIX_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_MIX_SEC0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_MIX_SEC1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_DSMDEM_CTL)] = WCD9360_RW, +}; + +const u8 wcd9360_page12_reg_access[WCD9360_PAGE_SIZE] = { +[WCD9360_REG(WCD9360_PAGE12_PAGE_REGISTER)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_BOOST0_BOOST_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_BOOST0_BOOST_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_BOOST0_BOOST_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_BOOST0_BOOST_CFG2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_BOOST1_BOOST_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_BOOST1_BOOST_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_BOOST1_BOOST_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_BOOST1_BOOST_CFG2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MIXING_ASRC2_CLK_RST_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MIXING_ASRC2_CTL0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MIXING_ASRC2_CTL1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MIXING_ASRC2_FIFO_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_LSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_MSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_LSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_MSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_MIXING_ASRC2_STATUS_FIFO)] = WCD9360_RO, +[WCD9360_REG(WCD9360_MIXING_ASRC3_CLK_RST_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MIXING_ASRC3_CTL0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MIXING_ASRC3_CTL1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MIXING_ASRC3_FIFO_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_LSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_MSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_LSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_MSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_MIXING_ASRC3_STATUS_FIFO)] = WCD9360_RO, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_DATA_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_DATA_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_DATA_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_DATA_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_ADDR_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_ADDR_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_ADDR_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_ADDR_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_ADDR_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_ADDR_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_ADDR_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_ADDR_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_DATA_0)] = WCD9360_RO, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_DATA_1)] = WCD9360_RO, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_DATA_2)] = WCD9360_RO, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_DATA_3)] = WCD9360_RO, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_ACCESS_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_ACCESS_STATUS)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDETONE_ASRC0_CLK_RST_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDETONE_ASRC0_CTL0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDETONE_ASRC0_CTL1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDETONE_ASRC0_FIFO_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_SIDETONE_ASRC0_STATUS_FIFO)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EC_REF_HQ0_EC_REF_HQ_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EC_REF_HQ0_EC_REF_HQ_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EC_REF_HQ1_EC_REF_HQ_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EC_REF_HQ1_EC_REF_HQ_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EC_ASRC0_CLK_RST_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EC_ASRC0_CTL0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EC_ASRC0_CTL1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EC_ASRC0_FIFO_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_LSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_MSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_LSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_MSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EC_ASRC0_STATUS_FIFO)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EC_ASRC1_CLK_RST_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EC_ASRC1_CTL0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EC_ASRC1_CTL1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EC_ASRC1_FIFO_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_LSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_MSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_LSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_MSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_EC_ASRC1_STATUS_FIFO)] = WCD9360_RO, +}; + +const u8 wcd9360_page13_reg_access[WCD9360_PAGE_SIZE] = { +[WCD9360_REG(WCD9360_PAGE13_PAGE_REGISTER)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_ANC_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_EC_REF_HQ_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX5_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX6_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX7_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX10_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX11_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_CLK_RST_CTRL_MCLK_CONTROL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_CLK_RST_CTRL_SWR_CONTROL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_STATUS)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_TEST_CTRL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_PATH_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TOP_TOP_CFG0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TOP_TOP_CFG1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TOP_TOP_CFG7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TOP_EAR_COMP_WR_LSB)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TOP_EAR_COMP_WR_MSB)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TOP_EAR_COMP_LUT)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CDC_TOP_EAR_COMP_RD_LSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CDC_TOP_EAR_COMP_RD_MSB)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CDC_TOP_TOP_DEBUG)] = WCD9360_RW, +}; + +const u8 wcd9360_page80_reg_access[WCD9360_PAGE_SIZE] = { +[WCD9360_REG(WCD9360_PAGE80_PAGE_REGISTER)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_WR_DATA_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_WR_DATA_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_WR_DATA_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_WR_DATA_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_WR_ADDR_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_WR_ADDR_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_WR_ADDR_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_WR_ADDR_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_RD_ADDR_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_RD_ADDR_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_RD_ADDR_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_RD_ADDR_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_RD_DATA_0)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CODEC_CPR_RD_DATA_1)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CODEC_CPR_RD_DATA_2)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CODEC_CPR_RD_DATA_3)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CODEC_CPR_ACCESS_CFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_ACCESS_STATUS)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CODEC_CPR_NOM_CX_VDD)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_SVS_CX_VDD)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_SVS2_CX_VDD)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_NOM_MX_VDD)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_SVS_MX_VDD)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_SVS2_MX_VDD)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_SVS2_MIN_CX_VDD)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_MAX_SVS2_STEP)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_CTL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_CODEC_CPR_SW_MODECHNG_STATUS)] = WCD9360_RO, +[WCD9360_REG(WCD9360_CODEC_CPR_SW_MODECHNG_START)] = WCD9360_WO, +[WCD9360_REG(WCD9360_CODEC_CPR_CPR_STATUS)] = WCD9360_RW, +}; + +const u8 wcd9360_page128_reg_access[WCD9360_PAGE_SIZE] = { +[WCD9360_REG(WCD9360_PAGE128_PAGE_REGISTER)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_JTCK_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_INTR1_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_INTR2_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_SWR_DATA_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_SWR_CLK_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_SLIMBUS_DATA1_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_SLIMBUS_DATA2_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_SLIMBUS_CLK_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_I2C_CLK_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_I2C_DATA_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_I2S_0_RX_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_I2S_0_TX_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_I2S_0_SCK_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_I2S_0_WS_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_I2S_1_RX_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_I2S_1_TX_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_I2S_1_SCK_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_I2S_1_WS_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_DMIC1_CLK_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_DMIC1_DATA_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_DMIC2_CLK_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_DMIC2_DATA_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_GPIO1_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_GPIO2_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_GPIO3_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_GPIO4_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_SPI_S_CSN_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_SPI_S_CLK_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_SPI_S_DOUT_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_SPI_S_DIN_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_GPIO0_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_DMIC3_CLK_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_DMIC3_DATA_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_DMIC4_CLK_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TLMM_DMIC4_DATA_PINCFG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_OE_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_OE_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_OE_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_OE_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_OE_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_DATA_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_DATA_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_DATA_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_DATA_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_DATA_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_DRVCTL_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_DRVCTL_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_STATUS)] = WCD9360_RO, +[WCD9360_REG(WCD9360_TEST_DEBUG_NPL_DLY_TEST_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_NPL_DLY_TEST_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_MEM_CTRL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_BUS_SEL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_JTAG)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_EN_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_EN_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_EN_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_EN_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_EN_5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_ANA_DTEST_DIR)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_INP_DISABLE_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_INP_DISABLE_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_INP_DISABLE_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_INP_DISABLE_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_INP_DISABLE_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_SYSMEM_CTRL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_LVAL_NOM_LOW)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_LVAL_NOM_HIGH)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_LOW)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_HIGH)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_SPI_SLAVE_CHAR)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_CODEC_DIAGS)] = WCD9360_RO, +[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_TEST)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_0)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_1)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_2)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_3)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_4)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_5)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_6)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_7)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_8)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_9)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_10)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_11)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_12)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_13)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_14)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_15)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_16)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_17)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_18)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_19)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_20)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_21)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_22)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_23)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_24)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_25)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_26)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_27)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_28)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_29)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_30)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_31)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_RD_CTRL)] = WCD9360_RW, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_RD_7_0)] = WCD9360_RO, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_RD_15_8)] = WCD9360_RO, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_RD_23_16)] = WCD9360_RO, +[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_RD_31_24)] = WCD9360_RO, + +}; + +const u8 * const wcd9360_reg[WCD9360_PAGE_MAX] = { +[WCD9360_PAGE_0] = wcd9360_page0_reg_access, +[WCD9360_PAGE_1] = wcd9360_page1_reg_access, +[WCD9360_PAGE_2] = wcd9360_page2_reg_access, +[WCD9360_PAGE_4] = wcd9360_page4_reg_access, +[WCD9360_PAGE_6] = wcd9360_page6_reg_access, +[WCD9360_PAGE_7] = wcd9360_page7_reg_access, +[WCD9360_PAGE_10] = wcd9360_page10_reg_access, +[WCD9360_PAGE_11] = wcd9360_page11_reg_access, +[WCD9360_PAGE_12] = wcd9360_page12_reg_access, +[WCD9360_PAGE_13] = wcd9360_page13_reg_access, +[WCD9360_PAGE_80] = wcd9360_page80_reg_access, +[WCD9360_PAGE_128] = wcd9360_page128_reg_access, +}; + +#endif diff --git a/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c b/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c new file mode 100644 index 000000000000..5a67aa62cd20 --- /dev/null +++ b/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c @@ -0,0 +1,1354 @@ +/* + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "wcd9360.h" +#include "wcd9360-dsp-cntl.h" +#include "../wcd9xxx-irq.h" +#include "../core.h" + +#define WCD_CNTL_DIR_NAME_LEN_MAX 32 +#define WCD_CPE_FLL_MAX_RETRIES 5 +#define WCD_MEM_ENABLE_MAX_RETRIES 20 +#define WCD_DSP_BOOT_TIMEOUT_MS 3000 +#define WCD_SYSFS_ENTRY_MAX_LEN 8 +#define WCD_PROCFS_ENTRY_MAX_LEN 16 +#define WCD_9360_RAMDUMP_START_ADDR 0x20100000 +#define WCD_9360_RAMDUMP_SIZE ((1024 * 1024) - 128) + +#define WCD_CNTL_MUTEX_LOCK(codec, lock) \ +{ \ + dev_dbg(codec->dev, "%s: mutex_lock(%s)\n", \ + __func__, __stringify_1(lock)); \ + mutex_lock(&lock); \ +} + +#define WCD_CNTL_MUTEX_UNLOCK(codec, lock) \ +{ \ + dev_dbg(codec->dev, "%s: mutex_unlock(%s)\n", \ + __func__, __stringify_1(lock)); \ + mutex_unlock(&lock); \ +} + +enum wcd_mem_type { + WCD_MEM_TYPE_ALWAYS_ON, + WCD_MEM_TYPE_SWITCHABLE, +}; + +struct wcd_cntl_attribute { + struct attribute attr; + ssize_t (*show)(struct wcd_dsp_cntl *cntl, char *buf); + ssize_t (*store)(struct wcd_dsp_cntl *cntl, const char *buf, + ssize_t count); +}; + +#define WCD_CNTL_ATTR(_name, _mode, _show, _store) \ +static struct wcd_cntl_attribute cntl_attr_##_name = { \ + .attr = {.name = __stringify(_name), .mode = _mode}, \ + .show = _show, \ + .store = _store, \ +} + +#define to_wcd_cntl_attr(a) \ + container_of((a), struct wcd_cntl_attribute, attr) + +#define to_wcd_cntl(kobj) \ + container_of((kobj), struct wcd_dsp_cntl, wcd_kobj) + +static u8 mem_enable_values[] = { + 0xFE, 0xFC, 0xF8, 0xF0, + 0xE0, 0xC0, 0x80, 0x00, +}; + +static ssize_t wdsp_boot_show(struct wcd_dsp_cntl *cntl, char *buf) +{ + return snprintf(buf, WCD_SYSFS_ENTRY_MAX_LEN, + "%u", cntl->boot_reqs); +} + +static ssize_t wdsp_boot_store(struct wcd_dsp_cntl *cntl, + const char *buf, ssize_t count) +{ + u32 val; + bool vote; + int ret; + + ret = kstrtou32(buf, 10, &val); + if (ret) { + dev_err(cntl->codec->dev, + "%s: Invalid entry, ret = %d\n", __func__, ret); + return -EINVAL; + } + + if (val > 0) { + cntl->boot_reqs++; + vote = true; + } else { + cntl->boot_reqs--; + vote = false; + } + + if (cntl->m_dev && cntl->m_ops && + cntl->m_ops->vote_for_dsp) + ret = cntl->m_ops->vote_for_dsp(cntl->m_dev, vote); + else + ret = -EINVAL; + + if (ret < 0) + dev_err(cntl->codec->dev, + "%s: failed to %s dsp\n", __func__, + vote ? "enable" : "disable"); + return count; +} + +WCD_CNTL_ATTR(boot, 0660, wdsp_boot_show, wdsp_boot_store); + +static ssize_t wcd_cntl_sysfs_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct wcd_cntl_attribute *wcd_attr = to_wcd_cntl_attr(attr); + struct wcd_dsp_cntl *cntl = to_wcd_cntl(kobj); + ssize_t ret = -EINVAL; + + if (cntl && wcd_attr->show) + ret = wcd_attr->show(cntl, buf); + + return ret; +} + +static ssize_t wcd_cntl_sysfs_store(struct kobject *kobj, + struct attribute *attr, const char *buf, + size_t count) +{ + struct wcd_cntl_attribute *wcd_attr = to_wcd_cntl_attr(attr); + struct wcd_dsp_cntl *cntl = to_wcd_cntl(kobj); + ssize_t ret = -EINVAL; + + if (cntl && wcd_attr->store) + ret = wcd_attr->store(cntl, buf, count); + + return ret; +} + +static const struct sysfs_ops wcd_cntl_sysfs_ops = { + .show = wcd_cntl_sysfs_show, + .store = wcd_cntl_sysfs_store, +}; + +static struct kobj_type wcd_cntl_ktype = { + .sysfs_ops = &wcd_cntl_sysfs_ops, +}; + +static void wcd_cntl_change_online_state(struct wcd_dsp_cntl *cntl, + u8 online) +{ + struct wdsp_ssr_entry *ssr_entry = &cntl->ssr_entry; + unsigned long ret; + + WCD_CNTL_MUTEX_LOCK(cntl->codec, cntl->ssr_mutex); + ssr_entry->offline = !online; + /* Make sure the write is complete */ + wmb(); + ret = xchg(&ssr_entry->offline_change, 1); + wake_up_interruptible(&ssr_entry->offline_poll_wait); + dev_dbg(cntl->codec->dev, + "%s: requested %u, offline %u offline_change %u, ret = %ldn", + __func__, online, ssr_entry->offline, + ssr_entry->offline_change, ret); + WCD_CNTL_MUTEX_UNLOCK(cntl->codec, cntl->ssr_mutex); +} + +static ssize_t wdsp_ssr_entry_read(struct snd_info_entry *entry, + void *file_priv_data, struct file *file, + char __user *buf, size_t count, loff_t pos) +{ + int len = 0; + char buffer[WCD_PROCFS_ENTRY_MAX_LEN]; + struct wcd_dsp_cntl *cntl; + struct wdsp_ssr_entry *ssr_entry; + ssize_t ret; + u8 offline; + + cntl = (struct wcd_dsp_cntl *) entry->private_data; + if (!cntl) { + pr_err("%s: Invalid private data for SSR procfs entry\n", + __func__); + return -EINVAL; + } + + ssr_entry = &cntl->ssr_entry; + + WCD_CNTL_MUTEX_LOCK(cntl->codec, cntl->ssr_mutex); + offline = ssr_entry->offline; + /* Make sure the read is complete */ + rmb(); + dev_dbg(cntl->codec->dev, "%s: offline = %s\n", __func__, + offline ? "true" : "false"); + len = snprintf(buffer, sizeof(buffer), "%s\n", + offline ? "OFFLINE" : "ONLINE"); + ret = simple_read_from_buffer(buf, count, &pos, buffer, len); + WCD_CNTL_MUTEX_UNLOCK(cntl->codec, cntl->ssr_mutex); + + return ret; +} + +static unsigned int wdsp_ssr_entry_poll(struct snd_info_entry *entry, + void *private_data, struct file *file, + poll_table *wait) +{ + struct wcd_dsp_cntl *cntl; + struct wdsp_ssr_entry *ssr_entry; + unsigned int ret = 0; + + if (!entry || !entry->private_data) { + pr_err("%s: %s is NULL\n", __func__, + (!entry) ? "entry" : "private_data"); + return -EINVAL; + } + + cntl = (struct wcd_dsp_cntl *) entry->private_data; + ssr_entry = &cntl->ssr_entry; + + dev_dbg(cntl->codec->dev, "%s: Poll wait, offline = %u\n", + __func__, ssr_entry->offline); + poll_wait(file, &ssr_entry->offline_poll_wait, wait); + dev_dbg(cntl->codec->dev, "%s: Woken up Poll wait, offline = %u\n", + __func__, ssr_entry->offline); + + WCD_CNTL_MUTEX_LOCK(cntl->codec, cntl->ssr_mutex); + if (xchg(&ssr_entry->offline_change, 0)) + ret = POLLIN | POLLPRI | POLLRDNORM; + dev_dbg(cntl->codec->dev, "%s: ret (%d) from poll_wait\n", + __func__, ret); + WCD_CNTL_MUTEX_UNLOCK(cntl->codec, cntl->ssr_mutex); + + return ret; +} + +static struct snd_info_entry_ops wdsp_ssr_entry_ops = { + .read = wdsp_ssr_entry_read, + .poll = wdsp_ssr_entry_poll, +}; + +static int wcd_cntl_cpe_fll_calibrate(struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + int ret = 0, retry = 0; + u8 cal_lsb, cal_msb; + u8 lock_det; + + /* Make sure clocks are gated */ + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPE_CTL, + 0x05, 0x00); + + /* Enable CPE FLL reference clock */ + snd_soc_update_bits(codec, WCD9360_CLK_SYS_MCLK2_PRG1, + 0x80, 0x80); + + snd_soc_update_bits(codec, WCD9360_CPE_FLL_USER_CTL_5, + 0xF3, 0x13); + snd_soc_write(codec, WCD9360_CPE_FLL_L_VAL_CTL_0, 0x50); + + /* Disable CPAR reset and Enable CPAR clk */ + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, + 0x02, 0x02); + + /* Write calibration l-value based on cdc clk rate */ + if (cntl->clk_rate == 9600000) { + cal_lsb = 0x6d; + cal_msb = 0x00; + } else { + cal_lsb = 0x56; + cal_msb = 0x00; + } + snd_soc_write(codec, WCD9360_CPE_FLL_USER_CTL_6, cal_lsb); + snd_soc_write(codec, WCD9360_CPE_FLL_USER_CTL_7, cal_msb); + + /* FLL mode to follow power up sequence */ + snd_soc_update_bits(codec, WCD9360_CPE_FLL_FLL_MODE, + 0x60, 0x00); + + /* HW controlled CPE FLL */ + snd_soc_update_bits(codec, WCD9360_CPE_FLL_FLL_MODE, + 0x80, 0x80); + + /* Force on CPE FLL */ + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CFG, + 0x04, 0x04); + + do { + /* Time for FLL calibration to complete */ + usleep_range(1000, 1100); + lock_det = snd_soc_read(codec, WCD9360_CPE_FLL_STATUS_3); + retry++; + } while (!(lock_det & 0x01) && + retry <= WCD_CPE_FLL_MAX_RETRIES); + + if (!(lock_det & 0x01)) { + dev_err(codec->dev, "%s: lock detect not set, 0x%02x\n", + __func__, lock_det); + ret = -EIO; + goto err_lock_det; + } + + snd_soc_update_bits(codec, WCD9360_CPE_FLL_FLL_MODE, + 0x60, 0x20); + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CFG, + 0x04, 0x00); + return ret; + +err_lock_det: + /* Undo the register settings */ + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CFG, + 0x04, 0x00); + snd_soc_update_bits(codec, WCD9360_CPE_FLL_FLL_MODE, + 0x80, 0x00); + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, + 0x02, 0x00); + return ret; +} + +static void wcd_cntl_config_cpar(struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + u8 nom_lo, nom_hi, svs2_lo, svs2_hi; + + /* Configure CPAR */ + nom_hi = svs2_hi = 0; + if (cntl->clk_rate == 9600000) { + nom_lo = 0x90; + svs2_lo = 0x50; + } else { + nom_lo = 0x70; + svs2_lo = 0x3e; + } + + snd_soc_write(codec, WCD9360_TEST_DEBUG_LVAL_NOM_LOW, nom_lo); + snd_soc_write(codec, WCD9360_TEST_DEBUG_LVAL_NOM_HIGH, nom_hi); + snd_soc_write(codec, WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_LOW, svs2_lo); + snd_soc_write(codec, WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_HIGH, svs2_hi); + + snd_soc_update_bits(codec, WCD9360_CPE_SS_PWR_CPEFLL_CTL, + 0x03, 0x03); +} + +static int wcd_cntl_cpe_fll_ctrl(struct wcd_dsp_cntl *cntl, + bool enable) +{ + struct snd_soc_codec *codec = cntl->codec; + int ret = 0; + + if (enable) { + ret = wcd_cntl_cpe_fll_calibrate(cntl); + if (ret < 0) { + dev_err(codec->dev, + "%s: cpe_fll_cal failed, err = %d\n", + __func__, ret); + goto done; + } + + wcd_cntl_config_cpar(cntl); + + /* Enable AHB CLK and CPE CLK*/ + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPE_CTL, + 0x05, 0x05); + } else { + /* Disable AHB CLK and CPE CLK */ + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPE_CTL, + 0x05, 0x00); + /* Reset the CPAR mode for CPE FLL */ + snd_soc_write(codec, WCD9360_CPE_FLL_FLL_MODE, 0x20); + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CFG, + 0x04, 0x00); + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, + 0x02, 0x00); + } +done: + return ret; +} + +static int wcd_cntl_clocks_enable(struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + int ret; + + WCD_CNTL_MUTEX_LOCK(codec, cntl->clk_mutex); + /* Enable codec clock */ + if (cntl->cdc_cb && cntl->cdc_cb->cdc_clk_en) + ret = cntl->cdc_cb->cdc_clk_en(codec, true); + else + ret = -EINVAL; + + if (ret < 0) { + dev_err(codec->dev, + "%s: Failed to enable cdc clk, err = %d\n", + __func__, ret); + goto done; + } + /* Pull CPAR out of reset */ + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, 0x04, 0x00); + + /* Configure and Enable CPE FLL clock */ + ret = wcd_cntl_cpe_fll_ctrl(cntl, true); + if (ret < 0) { + dev_err(codec->dev, + "%s: Failed to enable cpe clk, err = %d\n", + __func__, ret); + goto err_cpe_clk; + } + cntl->is_clk_enabled = true; + + /* Ungate the CPR clock */ + snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_GATE, 0x10, 0x00); +done: + WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex); + return ret; + +err_cpe_clk: + if (cntl->cdc_cb && cntl->cdc_cb->cdc_clk_en) + cntl->cdc_cb->cdc_clk_en(codec, false); + + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, 0x04, 0x04); + WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex); + return ret; +} + +static int wcd_cntl_clocks_disable(struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + int ret = 0; + + WCD_CNTL_MUTEX_LOCK(codec, cntl->clk_mutex); + if (!cntl->is_clk_enabled) { + dev_info(codec->dev, "%s: clocks already disabled\n", + __func__); + goto done; + } + + /* Gate the CPR clock */ + snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_GATE, 0x10, 0x10); + + /* Disable CPE FLL clock */ + ret = wcd_cntl_cpe_fll_ctrl(cntl, false); + if (ret < 0) + dev_err(codec->dev, + "%s: Failed to disable cpe clk, err = %d\n", + __func__, ret); + + /* + * Even if CPE FLL disable failed, go ahead and disable + * the codec clock + */ + if (cntl->cdc_cb && cntl->cdc_cb->cdc_clk_en) + ret = cntl->cdc_cb->cdc_clk_en(codec, false); + else + ret = -EINVAL; + + cntl->is_clk_enabled = false; + + /* Put CPAR in reset */ + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, 0x04, 0x04); +done: + WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex); + return ret; +} + +static void wcd_cntl_cpar_ctrl(struct wcd_dsp_cntl *cntl, + bool enable) +{ + struct snd_soc_codec *codec = cntl->codec; + + if (enable) + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, 0x03, 0x03); + else + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, 0x03, 0x00); +} + +static int wcd_cntl_enable_memory(struct wcd_dsp_cntl *cntl, + enum wcd_mem_type mem_type) +{ + struct snd_soc_codec *codec = cntl->codec; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + int loop_cnt = 0; + u8 status = 0; + int ret = 0; + + + switch (mem_type) { + + case WCD_MEM_TYPE_ALWAYS_ON: + + /* 512KB of always on region */ + wcd9xxx_slim_write_repeat(wcd9xxx, + WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0, + ARRAY_SIZE(mem_enable_values), + mem_enable_values); + wcd9xxx_slim_write_repeat(wcd9xxx, + WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1, + ARRAY_SIZE(mem_enable_values), + mem_enable_values); + break; + + case WCD_MEM_TYPE_SWITCHABLE: + + snd_soc_update_bits(codec, WCD9360_TEST_DEBUG_MEM_CTRL, + 0x80, 0x80); + do { + loop_cnt++; + /* Time to enable the power domain for memory */ + usleep_range(100, 150); + } while ((status & 0x02) != 0x02 && + loop_cnt != WCD_MEM_ENABLE_MAX_RETRIES); + + if ((status & 0x02) != 0x02) { + dev_err(cntl->codec->dev, + "%s: power domain not enabled, status = 0x%02x\n", + __func__, status); + ret = -EIO; + goto done; + } + + /* Rest of the memory */ + wcd9xxx_slim_write_repeat(wcd9xxx, + WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2, + ARRAY_SIZE(mem_enable_values), + mem_enable_values); + wcd9xxx_slim_write_repeat(wcd9xxx, + WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3, + ARRAY_SIZE(mem_enable_values), + mem_enable_values); + + snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN, + 0x05); + break; + + default: + dev_err(cntl->codec->dev, "%s: Invalid mem_type %d\n", + __func__, mem_type); + ret = -EINVAL; + break; + } +done: + /* Make sure Deep sleep of memories is enabled for all banks */ + snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, 0xFF); + snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, 0x0F); + + return ret; +} + +static void wcd_cntl_disable_memory(struct wcd_dsp_cntl *cntl, + enum wcd_mem_type mem_type) +{ + struct snd_soc_codec *codec = cntl->codec; + + switch (mem_type) { + case WCD_MEM_TYPE_ALWAYS_ON: + snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1, + 0xFF); + snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0, + 0xFF); + break; + case WCD_MEM_TYPE_SWITCHABLE: + snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3, + 0xFF); + snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2, + 0xFF); + snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN, + 0x07); + + snd_soc_update_bits(codec, WCD9360_TEST_DEBUG_MEM_CTRL, + 0x80, 0x00); + break; + default: + dev_err(cntl->codec->dev, "%s: Invalid mem_type %d\n", + __func__, mem_type); + break; + } + + snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, 0xFF); + snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, 0x0F); +} + +static void wcd_cntl_do_shutdown(struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + + /* Disable WDOG */ + snd_soc_update_bits(codec, WCD9360_CPE_SS_WDOG_CFG, + 0x3F, 0x01); + + /* Put WDSP in reset state */ + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPE_CTL, + 0x02, 0x00); + + /* If DSP transitions from boot to shutdown, then vote for SVS */ + if (cntl->is_wdsp_booted) + cntl->cdc_cb->cdc_vote_svs(codec, true); + cntl->is_wdsp_booted = false; +} + +static int wcd_cntl_do_boot(struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + int ret = 0; + + /* + * Debug mode is set from debugfs file node. If debug_mode + * is set, then do not configure the watchdog timer. This + * will be required for debugging the DSP firmware. + */ + if (cntl->debug_mode) { + snd_soc_update_bits(codec, WCD9360_CPE_SS_WDOG_CFG, + 0x3F, 0x01); + } else { + snd_soc_update_bits(codec, WCD9360_CPE_SS_WDOG_CFG, + 0x3F, 0x21); + } + + /* Make sure all the error interrupts are cleared */ + snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0A, 0xFF); + snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0B, 0xFF); + + reinit_completion(&cntl->boot_complete); + + /* Remove WDSP out of reset */ + snd_soc_update_bits(codec, WCD9360_CPE_SS_CPE_CTL, + 0x02, 0x02); + + /* + * In debug mode, DSP may not boot up normally, + * wait indefinitely for DSP to boot. + */ + if (cntl->debug_mode) { + wait_for_completion(&cntl->boot_complete); + dev_dbg(codec->dev, "%s: WDSP booted in dbg mode\n", __func__); + cntl->is_wdsp_booted = true; + goto done; + } + + /* Boot in normal mode */ + ret = wait_for_completion_timeout(&cntl->boot_complete, + msecs_to_jiffies(WCD_DSP_BOOT_TIMEOUT_MS)); + if (!ret) { + dev_err(codec->dev, "%s: WDSP boot timed out\n", + __func__); + ret = -ETIMEDOUT; + goto err_boot; + } else { + /* + * Re-initialize the return code to 0, as in success case, + * it will hold the remaining time for completion timeout + */ + ret = 0; + } + + dev_dbg(codec->dev, "%s: WDSP booted in normal mode\n", __func__); + cntl->is_wdsp_booted = true; + + /* Enable WDOG */ + snd_soc_update_bits(codec, WCD9360_CPE_SS_WDOG_CFG, + 0x10, 0x10); +done: + /* If dsp booted up, then remove vote on SVS */ + if (cntl->is_wdsp_booted) + cntl->cdc_cb->cdc_vote_svs(codec, false); + + return ret; +err_boot: + /* call shutdown to perform cleanup */ + wcd_cntl_do_shutdown(cntl); + return ret; +} + +static irqreturn_t wcd_cntl_ipc_irq(int irq, void *data) +{ + struct wcd_dsp_cntl *cntl = data; + int ret; + + complete(&cntl->boot_complete); + + if (cntl->m_dev && cntl->m_ops && + cntl->m_ops->signal_handler) + ret = cntl->m_ops->signal_handler(cntl->m_dev, WDSP_IPC1_INTR, + NULL); + else + ret = -EINVAL; + + if (ret < 0) + dev_err(cntl->codec->dev, + "%s: Failed to handle irq %d\n", __func__, irq); + + return IRQ_HANDLED; +} + +static irqreturn_t wcd_cntl_err_irq(int irq, void *data) +{ + struct wcd_dsp_cntl *cntl = data; + struct snd_soc_codec *codec = cntl->codec; + struct wdsp_err_signal_arg arg; + u16 status = 0; + u8 reg_val; + int ret = 0; + + reg_val = snd_soc_read(codec, WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0A); + status = status | reg_val; + + reg_val = snd_soc_read(codec, WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0B); + status = status | (reg_val << 8); + + dev_info(codec->dev, "%s: error interrupt status = 0x%x\n", + __func__, status); + + if ((status & cntl->irqs.fatal_irqs) && + (cntl->m_dev && cntl->m_ops && cntl->m_ops->signal_handler)) { + arg.mem_dumps_enabled = cntl->ramdump_enable; + arg.remote_start_addr = WCD_9360_RAMDUMP_START_ADDR; + arg.dump_size = WCD_9360_RAMDUMP_SIZE; + ret = cntl->m_ops->signal_handler(cntl->m_dev, WDSP_ERR_INTR, + &arg); + if (ret < 0) + dev_err(cntl->codec->dev, + "%s: Failed to handle fatal irq 0x%x\n", + __func__, status & cntl->irqs.fatal_irqs); + wcd_cntl_change_online_state(cntl, 0); + } else { + dev_err(cntl->codec->dev, "%s: Invalid signal_handler\n", + __func__); + } + + return IRQ_HANDLED; +} + +static int wcd_control_handler(struct device *dev, void *priv_data, + enum wdsp_event_type event, void *data) +{ + struct wcd_dsp_cntl *cntl = priv_data; + struct snd_soc_codec *codec = cntl->codec; + int ret = 0; + + switch (event) { + case WDSP_EVENT_POST_INIT: + case WDSP_EVENT_POST_DLOAD_CODE: + case WDSP_EVENT_DLOAD_FAILED: + case WDSP_EVENT_POST_SHUTDOWN: + + /* Disable CPAR */ + wcd_cntl_cpar_ctrl(cntl, false); + /* Disable all the clocks */ + ret = wcd_cntl_clocks_disable(cntl); + if (ret < 0) + dev_err(codec->dev, + "%s: Failed to disable clocks, err = %d\n", + __func__, ret); + + if (event == WDSP_EVENT_POST_DLOAD_CODE) + /* Mark DSP online since code download is complete */ + wcd_cntl_change_online_state(cntl, 1); + break; + + case WDSP_EVENT_PRE_DLOAD_DATA: + case WDSP_EVENT_PRE_DLOAD_CODE: + + /* Enable all the clocks */ + ret = wcd_cntl_clocks_enable(cntl); + if (ret < 0) { + dev_err(codec->dev, + "%s: Failed to enable clocks, err = %d\n", + __func__, ret); + goto done; + } + + /* Enable CPAR */ + wcd_cntl_cpar_ctrl(cntl, true); + + if (event == WDSP_EVENT_PRE_DLOAD_CODE) + wcd_cntl_enable_memory(cntl, WCD_MEM_TYPE_ALWAYS_ON); + else if (event == WDSP_EVENT_PRE_DLOAD_DATA) + wcd_cntl_enable_memory(cntl, WCD_MEM_TYPE_SWITCHABLE); + break; + + case WDSP_EVENT_DO_BOOT: + + ret = wcd_cntl_do_boot(cntl); + if (ret < 0) + dev_err(codec->dev, + "%s: WDSP boot failed, err = %d\n", + __func__, ret); + break; + + case WDSP_EVENT_DO_SHUTDOWN: + + wcd_cntl_do_shutdown(cntl); + wcd_cntl_disable_memory(cntl, WCD_MEM_TYPE_SWITCHABLE); + break; + + default: + dev_dbg(codec->dev, "%s: unhandled event %d\n", + __func__, event); + } + +done: + return ret; +} + +static int wcd_cntl_sysfs_init(char *dir, struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + int ret = 0; + + ret = kobject_init_and_add(&cntl->wcd_kobj, &wcd_cntl_ktype, + kernel_kobj, dir); + if (ret < 0) { + dev_err(codec->dev, + "%s: Failed to add kobject %s, err = %d\n", + __func__, dir, ret); + goto done; + } + + ret = sysfs_create_file(&cntl->wcd_kobj, &cntl_attr_boot.attr); + if (ret < 0) { + dev_err(codec->dev, + "%s: Failed to add wdsp_boot sysfs entry to %s\n", + __func__, dir); + goto fail_create_file; + } + + return ret; + +fail_create_file: + kobject_put(&cntl->wcd_kobj); +done: + return ret; +} + +static void wcd_cntl_sysfs_remove(struct wcd_dsp_cntl *cntl) +{ + sysfs_remove_file(&cntl->wcd_kobj, &cntl_attr_boot.attr); + kobject_put(&cntl->wcd_kobj); +} + +static void wcd_cntl_debugfs_init(char *dir, struct wcd_dsp_cntl *cntl) +{ + struct snd_soc_codec *codec = cntl->codec; + + cntl->entry = debugfs_create_dir(dir, NULL); + if (IS_ERR_OR_NULL(dir)) { + dev_err(codec->dev, "%s debugfs_create_dir failed for %s\n", + __func__, dir); + goto done; + } + + debugfs_create_u32("debug_mode", 0644, + cntl->entry, &cntl->debug_mode); + debugfs_create_bool("ramdump_enable", 0644, + cntl->entry, &cntl->ramdump_enable); +done: + return; +} + +static void wcd_cntl_debugfs_remove(struct wcd_dsp_cntl *cntl) +{ + if (cntl) + debugfs_remove(cntl->entry); +} + +static int wcd_miscdev_release(struct inode *inode, struct file *filep) +{ + struct wcd_dsp_cntl *cntl = container_of(filep->private_data, + struct wcd_dsp_cntl, miscdev); + if (!cntl->m_dev || !cntl->m_ops || + !cntl->m_ops->vote_for_dsp) { + dev_err(cntl->codec->dev, + "%s: DSP not ready to boot\n", __func__); + return -EINVAL; + } + + /* Make sure the DSP users goes to zero upon closing dev node */ + while (cntl->boot_reqs > 0) { + cntl->m_ops->vote_for_dsp(cntl->m_dev, false); + cntl->boot_reqs--; + } + + return 0; +} + +static ssize_t wcd_miscdev_write(struct file *filep, const char __user *ubuf, + size_t count, loff_t *pos) +{ + struct wcd_dsp_cntl *cntl = container_of(filep->private_data, + struct wcd_dsp_cntl, miscdev); + char val[count]; + bool vote; + int ret = 0; + + if (count == 0 || count > 2) { + pr_err("%s: Invalid count = %zd\n", __func__, count); + ret = -EINVAL; + goto done; + } + + ret = copy_from_user(val, ubuf, count); + if (ret < 0) { + dev_err(cntl->codec->dev, + "%s: copy_from_user failed, err = %d\n", + __func__, ret); + ret = -EFAULT; + goto done; + } + + if (val[0] == '1') { + cntl->boot_reqs++; + vote = true; + } else if (val[0] == '0') { + if (cntl->boot_reqs == 0) { + dev_err(cntl->codec->dev, + "%s: WDSP already disabled\n", __func__); + ret = -EINVAL; + goto done; + } + cntl->boot_reqs--; + vote = false; + } else { + dev_err(cntl->codec->dev, "%s: Invalid value %s\n", + __func__, val); + ret = -EINVAL; + goto done; + } + + dev_dbg(cntl->codec->dev, + "%s: booted = %s, ref_cnt = %d, vote = %s\n", + __func__, cntl->is_wdsp_booted ? "true" : "false", + cntl->boot_reqs, vote ? "true" : "false"); + + if (cntl->m_dev && cntl->m_ops && + cntl->m_ops->vote_for_dsp) + ret = cntl->m_ops->vote_for_dsp(cntl->m_dev, vote); + else + ret = -EINVAL; +done: + if (ret) + return ret; + else + return count; +} + +static const struct file_operations wcd_miscdev_fops = { + .write = wcd_miscdev_write, + .release = wcd_miscdev_release, +}; + +static int wcd_cntl_miscdev_create(struct wcd_dsp_cntl *cntl) +{ + snprintf(cntl->miscdev_name, ARRAY_SIZE(cntl->miscdev_name), + "wcd_dsp%u_control", cntl->dsp_instance); + cntl->miscdev.minor = MISC_DYNAMIC_MINOR; + cntl->miscdev.name = cntl->miscdev_name; + cntl->miscdev.fops = &wcd_miscdev_fops; + cntl->miscdev.parent = cntl->codec->dev; + + return misc_register(&cntl->miscdev); +} + +static void wcd_cntl_miscdev_destroy(struct wcd_dsp_cntl *cntl) +{ + misc_deregister(&cntl->miscdev); +} + +static int wcd_control_init(struct device *dev, void *priv_data) +{ + struct wcd_dsp_cntl *cntl = priv_data; + struct snd_soc_codec *codec = cntl->codec; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; + int ret; + bool err_irq_requested = false; + + ret = wcd9xxx_request_irq(core_res, + cntl->irqs.cpe_ipc1_irq, + wcd_cntl_ipc_irq, "CPE IPC1", + cntl); + if (ret < 0) { + dev_err(codec->dev, + "%s: Failed to request cpe ipc irq, err = %d\n", + __func__, ret); + goto done; + } + + /* Unmask the fatal irqs */ + snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A, + ~(cntl->irqs.fatal_irqs & 0xFF)); + snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B, + ~((cntl->irqs.fatal_irqs >> 8) & 0xFF)); + + /* + * CPE ERR irq is used only for error reporting from WCD DSP, + * even if this request fails, DSP can be function normally. + * Continuing with init even if the CPE ERR irq request fails. + */ + if (wcd9xxx_request_irq(core_res, cntl->irqs.cpe_err_irq, + wcd_cntl_err_irq, "CPE ERR", cntl)) + dev_info(codec->dev, "%s: Failed request_irq(cpe_err_irq)", + __func__); + else + err_irq_requested = true; + + + /* Enable all the clocks */ + ret = wcd_cntl_clocks_enable(cntl); + if (ret < 0) { + dev_err(codec->dev, "%s: Failed to enable clocks, err = %d\n", + __func__, ret); + goto err_clk_enable; + } + wcd_cntl_cpar_ctrl(cntl, true); + + return 0; + +err_clk_enable: + /* Mask all error interrupts */ + snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A, 0xFF); + snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B, 0xFF); + + /* Free the irq's requested */ + wcd9xxx_free_irq(core_res, cntl->irqs.cpe_ipc1_irq, cntl); + + if (err_irq_requested) + wcd9xxx_free_irq(core_res, cntl->irqs.cpe_err_irq, cntl); +done: + return ret; +} + +static int wcd_control_deinit(struct device *dev, void *priv_data) +{ + struct wcd_dsp_cntl *cntl = priv_data; + struct snd_soc_codec *codec = cntl->codec; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; + + wcd_cntl_clocks_disable(cntl); + wcd_cntl_cpar_ctrl(cntl, false); + + /* Mask all error interrupts */ + snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A, 0xFF); + snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B, 0xFF); + + /* Free the irq's requested */ + wcd9xxx_free_irq(core_res, cntl->irqs.cpe_err_irq, cntl); + wcd9xxx_free_irq(core_res, cntl->irqs.cpe_ipc1_irq, cntl); + + return 0; +} + +static struct wdsp_cmpnt_ops control_ops = { + .init = wcd_control_init, + .deinit = wcd_control_deinit, + .event_handler = wcd_control_handler, +}; + +static int wcd_ctrl_component_bind(struct device *dev, + struct device *master, + void *data) +{ + struct wcd_dsp_cntl *cntl; + struct snd_soc_codec *codec; + struct snd_card *card; + struct snd_info_entry *entry; + char proc_name[WCD_PROCFS_ENTRY_MAX_LEN]; + char wcd_cntl_dir_name[WCD_CNTL_DIR_NAME_LEN_MAX]; + int ret = 0; + + if (!dev || !master || !data) { + pr_err("%s: Invalid parameters\n", __func__); + return -EINVAL; + } + + cntl = pahu_get_wcd_dsp_cntl(dev); + if (!cntl) { + dev_err(dev, "%s: Failed to get cntl reference\n", + __func__); + return -EINVAL; + } + + cntl->m_dev = master; + cntl->m_ops = data; + + if (!cntl->m_ops->register_cmpnt_ops) { + dev_err(dev, "%s: invalid master callback register_cmpnt_ops\n", + __func__); + ret = -EINVAL; + goto done; + } + + ret = cntl->m_ops->register_cmpnt_ops(master, dev, cntl, &control_ops); + if (ret) { + dev_err(dev, "%s: register_cmpnt_ops failed, err = %d\n", + __func__, ret); + goto done; + } + + ret = wcd_cntl_miscdev_create(cntl); + if (ret < 0) { + dev_err(dev, "%s: misc dev register failed, err = %d\n", + __func__, ret); + goto done; + } + + snprintf(wcd_cntl_dir_name, WCD_CNTL_DIR_NAME_LEN_MAX, + "%s%d", "wdsp", cntl->dsp_instance); + ret = wcd_cntl_sysfs_init(wcd_cntl_dir_name, cntl); + if (ret < 0) { + dev_err(dev, "%s: sysfs_init failed, err = %d\n", + __func__, ret); + goto err_sysfs_init; + } + + wcd_cntl_debugfs_init(wcd_cntl_dir_name, cntl); + + codec = cntl->codec; + card = codec->component.card->snd_card; + snprintf(proc_name, WCD_PROCFS_ENTRY_MAX_LEN, "%s%d%s", "cpe", + cntl->dsp_instance, "_state"); + entry = snd_info_create_card_entry(card, proc_name, card->proc_root); + if (!entry) { + /* Do not treat this as Fatal error */ + dev_err(dev, "%s: Failed to create procfs entry %s\n", + __func__, proc_name); + goto err_sysfs_init; + } + + cntl->ssr_entry.entry = entry; + cntl->ssr_entry.offline = 1; + entry->size = WCD_PROCFS_ENTRY_MAX_LEN; + entry->content = SNDRV_INFO_CONTENT_DATA; + entry->c.ops = &wdsp_ssr_entry_ops; + entry->private_data = cntl; + ret = snd_info_register(entry); + if (ret < 0) { + dev_err(dev, "%s: Failed to register entry %s, err = %d\n", + __func__, proc_name, ret); + snd_info_free_entry(entry); + /* Let bind still happen even if creating the entry failed */ + ret = 0; + } +done: + return ret; + +err_sysfs_init: + wcd_cntl_miscdev_destroy(cntl); + return ret; +} + +static void wcd_ctrl_component_unbind(struct device *dev, + struct device *master, + void *data) +{ + struct wcd_dsp_cntl *cntl; + + if (!dev) { + pr_err("%s: Invalid device\n", __func__); + return; + } + + cntl = pahu_get_wcd_dsp_cntl(dev); + if (!cntl) { + dev_err(dev, "%s: Failed to get cntl reference\n", + __func__); + return; + } + + cntl->m_dev = NULL; + cntl->m_ops = NULL; + + /* Remove the sysfs entries */ + wcd_cntl_sysfs_remove(cntl); + + /* Remove the debugfs entries */ + wcd_cntl_debugfs_remove(cntl); + + /* Remove the misc device */ + wcd_cntl_miscdev_destroy(cntl); +} + +static const struct component_ops wcd_ctrl_component_ops = { + .bind = wcd_ctrl_component_bind, + .unbind = wcd_ctrl_component_unbind, +}; + +/* + * wcd9360_dsp_ssr_event: handle the SSR event raised by caller. + * @cntl: Handle to the wcd_dsp_cntl structure + * @event: The SSR event to be handled + * + * Notifies the manager driver about the SSR event. + * Returns 0 on success and negative error code on error. + */ +int wcd9360_dsp_ssr_event(struct wcd_dsp_cntl *cntl, enum cdc_ssr_event event) +{ + int ret = 0; + + if (!cntl) { + pr_err("%s: Invalid handle to control\n", __func__); + return -EINVAL; + } + + if (!cntl->m_dev || !cntl->m_ops || !cntl->m_ops->signal_handler) { + dev_err(cntl->codec->dev, + "%s: Invalid signal_handler callback\n", __func__); + return -EINVAL; + } + + switch (event) { + case WCD_CDC_DOWN_EVENT: + ret = cntl->m_ops->signal_handler(cntl->m_dev, + WDSP_CDC_DOWN_SIGNAL, + NULL); + if (ret < 0) + dev_err(cntl->codec->dev, + "%s: WDSP_CDC_DOWN_SIGNAL failed, err = %d\n", + __func__, ret); + wcd_cntl_change_online_state(cntl, 0); + break; + case WCD_CDC_UP_EVENT: + ret = cntl->m_ops->signal_handler(cntl->m_dev, + WDSP_CDC_UP_SIGNAL, + NULL); + if (ret < 0) + dev_err(cntl->codec->dev, + "%s: WDSP_CDC_UP_SIGNAL failed, err = %d\n", + __func__, ret); + break; + default: + dev_err(cntl->codec->dev, "%s: Invalid event %d\n", + __func__, event); + ret = -EINVAL; + break; + } + + return ret; +} +EXPORT_SYMBOL(wcd9360_dsp_ssr_event); + +/* + * wcd9360_dsp_cntl_init: Initialize the wcd-dsp control + * @codec: pointer to the codec handle + * @params: Parameters required to initialize wcd-dsp control + * + * This API is expected to be invoked by the codec driver and + * provide information essential for the wcd dsp control to + * configure and initialize the dsp + */ +void wcd9360_dsp_cntl_init(struct snd_soc_codec *codec, + struct wcd_dsp_params *params, + struct wcd_dsp_cntl **cntl) +{ + struct wcd_dsp_cntl *control; + int ret; + + if (!codec || !params) { + pr_err("%s: Invalid handle to %s\n", __func__, + (!codec) ? "codec" : "params"); + *cntl = NULL; + return; + } + + if (*cntl) { + pr_err("%s: cntl is non NULL, maybe already initialized ?\n", + __func__); + return; + } + + if (!params->cb || !params->cb->cdc_clk_en || + !params->cb->cdc_vote_svs) { + dev_err(codec->dev, + "%s: clk_en and vote_svs callbacks must be provided\n", + __func__); + return; + } + + control = kzalloc(sizeof(*control), GFP_KERNEL); + if (!(control)) + return; + + control->codec = codec; + control->clk_rate = params->clk_rate; + control->cdc_cb = params->cb; + control->dsp_instance = params->dsp_instance; + memcpy(&control->irqs, ¶ms->irqs, sizeof(control->irqs)); + init_completion(&control->boot_complete); + mutex_init(&control->clk_mutex); + mutex_init(&control->ssr_mutex); + init_waitqueue_head(&control->ssr_entry.offline_poll_wait); + + /* + * The default state of WDSP is in SVS mode. + * Vote for SVS now, the vote will be removed only + * after DSP is booted up. + */ + control->cdc_cb->cdc_vote_svs(codec, true); + + /* + * If this is the last component needed by master to be ready, + * then component_bind will be called within the component_add. + * Hence, the data pointer should be assigned before component_add, + * so that we can access it during this component's bind call. + */ + *cntl = control; + ret = component_add(codec->dev, &wcd_ctrl_component_ops); + if (ret) { + dev_err(codec->dev, "%s: component_add failed, err = %d\n", + __func__, ret); + kfree(*cntl); + *cntl = NULL; + } +} +EXPORT_SYMBOL(wcd9360_dsp_cntl_init); + +/* + * wcd9360_dsp_cntl_deinit: De-initialize the wcd-dsp control + * @cntl: The struct wcd_dsp_cntl to de-initialize + * + * This API is intended to be invoked by the codec driver + * to de-initialize the wcd dsp control + */ +void wcd9360_dsp_cntl_deinit(struct wcd_dsp_cntl **cntl) +{ + struct wcd_dsp_cntl *control = *cntl; + struct snd_soc_codec *codec; + + /* If control is NULL, there is nothing to de-initialize */ + if (!control) + return; + codec = control->codec; + + /* + * Calling shutdown will cleanup all register states, + * irrespective of DSP was booted up or not. + */ + wcd_cntl_do_shutdown(control); + wcd_cntl_disable_memory(control, WCD_MEM_TYPE_SWITCHABLE); + wcd_cntl_disable_memory(control, WCD_MEM_TYPE_ALWAYS_ON); + + component_del(codec->dev, &wcd_ctrl_component_ops); + + mutex_destroy(&control->clk_mutex); + mutex_destroy(&control->ssr_mutex); + kfree(*cntl); + *cntl = NULL; +} +EXPORT_SYMBOL(wcd9360_dsp_cntl_deinit); diff --git a/asoc/codecs/wcd9360/wcd9360-dsp-cntl.h b/asoc/codecs/wcd9360/wcd9360-dsp-cntl.h new file mode 100644 index 000000000000..db8b4310552b --- /dev/null +++ b/asoc/codecs/wcd9360/wcd9360-dsp-cntl.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __WCD9360_DSP_CNTL_H__ +#define __WCD9360_DSP_CNTL_H__ + +#include +#include +#include + +enum cdc_ssr_event { + WCD_CDC_DOWN_EVENT, + WCD_CDC_UP_EVENT, +}; + +struct wcd_dsp_cdc_cb { + /* Callback to enable codec clock */ + int (*cdc_clk_en)(struct snd_soc_codec *, bool); + /* Callback to vote and unvote for SVS2 mode */ + void (*cdc_vote_svs)(struct snd_soc_codec *, bool); +}; + +struct wcd_dsp_irq_info { + /* IPC interrupt */ + int cpe_ipc1_irq; + + /* CPE error summary interrupt */ + int cpe_err_irq; + + /* + * Bit mask to indicate which of the + * error interrupts are to be considered + * as fatal. + */ + u16 fatal_irqs; +}; + +struct wcd_dsp_params { + struct wcd_dsp_cdc_cb *cb; + struct wcd_dsp_irq_info irqs; + + /* Rate at which the codec clock operates */ + u32 clk_rate; + + /* + * Represents the dsp instance, will be used + * to create sysfs and debugfs entries with + * directory wdsp + */ + u32 dsp_instance; +}; + +struct wdsp_ssr_entry { + u8 offline; + u8 offline_change; + wait_queue_head_t offline_poll_wait; + struct snd_info_entry *entry; +}; + +struct wcd_dsp_cntl { + /* Handle to codec */ + struct snd_soc_codec *codec; + + /* Clk rate of the codec clock */ + u32 clk_rate; + + /* Callbacks to codec driver */ + const struct wcd_dsp_cdc_cb *cdc_cb; + + /* Completion to indicate WDSP boot done */ + struct completion boot_complete; + + struct wcd_dsp_irq_info irqs; + u32 dsp_instance; + + /* Sysfs entries related */ + int boot_reqs; + struct kobject wcd_kobj; + + /* Debugfs related */ + struct dentry *entry; + u32 debug_mode; + bool ramdump_enable; + + /* WDSP manager drivers data */ + struct device *m_dev; + struct wdsp_mgr_ops *m_ops; + + /* clk related */ + struct mutex clk_mutex; + bool is_clk_enabled; + + /* Keep track of WDSP boot status */ + bool is_wdsp_booted; + + /* SSR related */ + struct wdsp_ssr_entry ssr_entry; + struct mutex ssr_mutex; + + /* Misc device related */ + char miscdev_name[256]; + struct miscdevice miscdev; +}; + +void wcd9360_dsp_cntl_init(struct snd_soc_codec *codec, + struct wcd_dsp_params *params, + struct wcd_dsp_cntl **cntl); +void wcd9360_dsp_cntl_deinit(struct wcd_dsp_cntl **cntl); +int wcd9360_dsp_ssr_event(struct wcd_dsp_cntl *cntl, enum cdc_ssr_event event); +#endif /* end __WCD_DSP_CONTROL_H__ */ diff --git a/asoc/codecs/wcd9360/wcd9360-irq.h b/asoc/codecs/wcd9360/wcd9360-irq.h new file mode 100644 index 000000000000..fa79447709b3 --- /dev/null +++ b/asoc/codecs/wcd9360/wcd9360-irq.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __WCD9360_IRQ_H_ +#define __WCD9360_IRQ_H_ + +enum { + /* INTR_REG 0 */ + WCD9360_IRQ_MISC = 1, + WCD9360_IRQ_RESERVED_0, + WCD9360_IRQ_LDO_RXTX_SCD, + WCD9360_IRQ_EAR_PA_SCD, + WCD9360_IRQ_AUX_PA_SCD, + WCD9360_IRQ_AUX_PA_CNP_COMPLETE, + WCD9360_IRQ_EAR_PA_CNP_COMPLETE, + /* INTR_REG 1 */ + WCD9360_IRQ_RESERVED_1, + WCD9360_IRQ_RESERVED_2, + WCD9360_IRQ_RESERVED_3, + WCD9360_IRQ_RESERVED_4, + WCD9360_IRQ_RESERVED_5, + WCD9360_IRQ_RESERVED_6, + WCD9360_IRQ_RESERVED_7, + WCD9360_IRQ_RESERVED_8, + /* INTR_REG 2 */ + WCD9360_IRQ_RESERVED_9, + WCD9360_IRQ_RESERVED_10, + WCD9360_IRQ_RESERVED_11, + WCD9360_IRQ_RESERVED_12, + WCD9360_IRQ_SOUNDWIRE, + WCD9360_IRQ_RESERVED_13, + WCD9360_IRQ_RCO_ERROR, + WCD9360_IRQ_CPE_ERROR, + /* INTR_REG 3 */ + WCD9360_IRQ_MAD_AUDIO, + WCD9360_IRQ_MAD_BEACON, + WCD9360_IRQ_MAD_ULTRASOUND, + WCD9360_IRQ_RESERVED_14, + WCD9360_IRQ_RESERVED_15, + WCD9360_IRQ_CPE1_INTR, + WCD9360_IRQ_CPE2_INTR, + WCD9360_IRQ_CPE_LPASS_ACK, + WCD9360_NUM_IRQS, +}; + +#endif diff --git a/asoc/codecs/wcd9360/wcd9360-regmap.c b/asoc/codecs/wcd9360/wcd9360-regmap.c new file mode 100644 index 000000000000..b74c1fb5c608 --- /dev/null +++ b/asoc/codecs/wcd9360/wcd9360-regmap.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include "../core.h" +#include "../wcd9xxx-regmap.h" +#include "wcd9360-defaults.h" + +static bool wcd9360_is_readable_register(struct device *dev, unsigned int reg) +{ + u8 pg_num, reg_offset; + const u8 *reg_tbl = NULL; + + /* + * Get the page number from MSB of codec register. If its 0x80, assign + * the corresponding page index PAGE_0x80. + */ + pg_num = reg >> 8; + if (pg_num == 128) + pg_num = WCD9360_PAGE_128; + else if (pg_num == 80) + pg_num = WCD9360_PAGE_80; + else if (pg_num > 15) + return false; + + reg_tbl = wcd9360_reg[pg_num]; + reg_offset = reg & 0xFF; + + if (reg_tbl && reg_tbl[reg_offset]) + return true; + else + return false; +} + +static bool wcd9360_is_volatile_register(struct device *dev, unsigned int reg) +{ + u8 pg_num, reg_offset; + const u8 *reg_tbl = NULL; + + pg_num = reg >> 8; + + if (pg_num == 1 || pg_num == 2 || + pg_num == 6 || pg_num == 7) + return true; + else if (pg_num == 128) + pg_num = WCD9360_PAGE_128; + else if (pg_num == 80) + pg_num = WCD9360_PAGE_80; + else if (pg_num > 15) + return false; + + reg_tbl = wcd9360_reg[pg_num]; + reg_offset = reg & 0xFF; + + if (reg_tbl && reg_tbl[reg_offset] == WCD9360_RO) + return true; + + if ((reg >= WCD9360_CODEC_RPM_RST_CTL) && + (reg <= WCD9360_CHIP_TIER_CTRL_ALT_FUNC_EN)) + return true; + + if ((reg >= WCD9360_CDC_ANC0_IIR_COEFF_1_CTL) && + (reg <= WCD9360_CDC_ANC0_FB_GAIN_CTL)) + return true; + + if ((reg >= WCD9360_CODEC_CPR_WR_DATA_0) && + (reg <= WCD9360_CODEC_CPR_RD_DATA_3)) + return true; + + /* + * Need to mark volatile for registers that are writable but + * only few bits are read-only + */ + switch (reg) { + case WCD9360_CODEC_RPM_CLK_BYPASS: + case WCD9360_CODEC_RPM_CLK_GATE: + case WCD9360_CODEC_RPM_CLK_MCLK_CFG: + case WCD9360_CODEC_CPR_SVS_CX_VDD: + case WCD9360_CODEC_CPR_SVS2_CX_VDD: + case WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL: + case WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL: + return true; + } + + return false; +} + +struct regmap_config wcd9360_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wcd9360_defaults, + .num_reg_defaults = ARRAY_SIZE(wcd9360_defaults), + .max_register = WCD9360_MAX_REGISTER, + .volatile_reg = wcd9360_is_volatile_register, + .readable_reg = wcd9360_is_readable_register, + .can_multi_write = true, +}; diff --git a/asoc/codecs/wcd9360/wcd9360-routing.h b/asoc/codecs/wcd9360/wcd9360-routing.h new file mode 100644 index 000000000000..06eab605000b --- /dev/null +++ b/asoc/codecs/wcd9360/wcd9360-routing.h @@ -0,0 +1,864 @@ +/* + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __WCD9360_ROUTING_H__ +#define __WCD9360_ROUTING_H__ + +#include + +const struct snd_soc_dapm_route pahu_slim_audio_map[] = { + + {"AIF4 MAD", NULL, "AIF4_MAD Mixer"}, + + /* Virtual input widget Mixer SLIMBUS */ + {"AIF1_CAP Mixer", "SLIM TX0", "SLIM TX0"}, + {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1"}, + {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2"}, + {"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3"}, + {"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4"}, + {"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5"}, + {"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6"}, + {"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7"}, + {"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8"}, + {"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9"}, + {"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10"}, + {"AIF1_CAP Mixer", "SLIM TX11", "SLIM TX11"}, + {"AIF1_CAP Mixer", "SLIM TX13", "SLIM TX13"}, + + {"AIF2_CAP Mixer", "SLIM TX0", "SLIM TX0"}, + {"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1"}, + {"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2"}, + {"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3"}, + {"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4"}, + {"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5"}, + {"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6"}, + {"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7"}, + {"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8"}, + {"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9"}, + {"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10"}, + {"AIF2_CAP Mixer", "SLIM TX11", "SLIM TX11"}, + {"AIF2_CAP Mixer", "SLIM TX13", "SLIM TX13"}, + + {"AIF3_CAP Mixer", "SLIM TX0", "SLIM TX0"}, + {"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1"}, + {"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2"}, + {"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3"}, + {"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4"}, + {"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5"}, + {"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6"}, + {"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7"}, + {"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8"}, + {"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9"}, + {"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10"}, + {"AIF3_CAP Mixer", "SLIM TX11", "SLIM TX11"}, + {"AIF3_CAP Mixer", "SLIM TX13", "SLIM TX13"}, + + {"AIF4_MAD Mixer", "SLIM TX13", "SLIM TX13"}, + + /* CDC Tx interface with SLIMBUS */ + {"SLIM TX0", NULL, "CDC_IF TX0 MUX"}, + {"SLIM TX1", NULL, "CDC_IF TX1 MUX"}, + {"SLIM TX2", NULL, "CDC_IF TX2 MUX"}, + {"SLIM TX3", NULL, "CDC_IF TX3 MUX"}, + {"SLIM TX4", NULL, "CDC_IF TX4 MUX"}, + {"SLIM TX5", NULL, "CDC_IF TX5 MUX"}, + {"SLIM TX6", NULL, "CDC_IF TX6 MUX"}, + {"SLIM TX7", NULL, "CDC_IF TX7 MUX"}, + {"SLIM TX8", NULL, "CDC_IF TX8 MUX"}, + {"SLIM TX9", NULL, "CDC_IF TX9 MUX"}, + {"SLIM TX10", NULL, "CDC_IF TX10 MUX"}, + {"SLIM TX11", NULL, "CDC_IF TX11 MUX"}, + {"SLIM TX13", NULL, "CDC_IF TX13 MUX"}, + + {"SLIM RX0 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"}, + {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"}, + + {"SLIM RX0 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"}, + {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"}, + + {"SLIM RX0 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"}, + {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"}, + + {"SLIM RX0 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX1 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX2 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX3 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX4 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX5 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX6 MUX", "AIF4_PB", "AIF4 PB"}, + {"SLIM RX7 MUX", "AIF4_PB", "AIF4 PB"}, + + {"SLIM RX0", NULL, "SLIM RX0 MUX"}, + {"SLIM RX1", NULL, "SLIM RX1 MUX"}, + {"SLIM RX2", NULL, "SLIM RX2 MUX"}, + {"SLIM RX3", NULL, "SLIM RX3 MUX"}, + {"SLIM RX4", NULL, "SLIM RX4 MUX"}, + {"SLIM RX5", NULL, "SLIM RX5 MUX"}, + {"SLIM RX6", NULL, "SLIM RX6 MUX"}, + {"SLIM RX7", NULL, "SLIM RX7 MUX"}, + + /* CDC Rx interface with SLIMBUS */ + {"CDC_IF RX0 MUX", "SLIM RX0", "SLIM RX0"}, + {"CDC_IF RX1 MUX", "SLIM RX1", "SLIM RX1"}, + {"CDC_IF RX2 MUX", "SLIM RX2", "SLIM RX2"}, + {"CDC_IF RX3 MUX", "SLIM RX3", "SLIM RX3"}, + {"CDC_IF RX4 MUX", "SLIM RX4", "SLIM RX4"}, + {"CDC_IF RX5 MUX", "SLIM RX5", "SLIM RX5"}, + {"CDC_IF RX6 MUX", "SLIM RX6", "SLIM RX6"}, + {"CDC_IF RX7 MUX", "SLIM RX7", "SLIM RX7"}, + + /* VI Feedback */ + {"AIF4_VI Mixer", "SPKR_VI_1", "VIINPUT"}, + {"AIF4_VI Mixer", "SPKR_VI_2", "VIINPUT"}, + {"AIF4 VI", NULL, "AIF4_VI Mixer"}, + +}; + +const struct snd_soc_dapm_route pahu_audio_map[] = { + + /* Virtual input widgets */ + {"AIF1 CAP", NULL, "AIF1_CAP Mixer"}, + {"AIF2 CAP", NULL, "AIF2_CAP Mixer"}, + {"AIF3 CAP", NULL, "AIF3_CAP Mixer"}, + + /* WDMA3 */ + {"WDMA3 PORT0 MUX", "DEC0", "ADC MUX0"}, + {"WDMA3 PORT0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"}, + {"WDMA3 PORT1 MUX", "DEC1", "ADC MUX1"}, + {"WDMA3 PORT1 MUX", "RX_MIX_TX1", "RX MIX TX1 MUX"}, + {"WDMA3 PORT2 MUX", "DEC2", "ADC MUX2"}, + {"WDMA3 PORT2 MUX", "RX_MIX_TX2", "RX MIX TX2 MUX"}, + {"WDMA3 PORT3 MUX", "DEC3", "ADC MUX3"}, + {"WDMA3 PORT3 MUX", "RX_MIX_TX3", "RX MIX TX3 MUX"}, + {"WDMA3 PORT4 MUX", "DEC4", "ADC MUX4"}, + {"WDMA3 PORT4 MUX", "RX_MIX_TX4", "RX MIX TX4 MUX"}, + {"WDMA3 PORT5 MUX", "DEC5", "ADC MUX5"}, + {"WDMA3 PORT5 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"}, + {"WDMA3 PORT6 MUX", "DEC6", "ADC MUX6"}, + {"WDMA3 PORT6 MUX", "RX_MIX_TX6", "RX MIX TX6 MUX"}, + + {"WDMA3 CH0 MUX", "PORT_0", "WDMA3 PORT0 MUX"}, + {"WDMA3 CH0 MUX", "PORT_1", "WDMA3 PORT1 MUX"}, + {"WDMA3 CH0 MUX", "PORT_2", "WDMA3 PORT2 MUX"}, + {"WDMA3 CH0 MUX", "PORT_3", "WDMA3 PORT3 MUX"}, + {"WDMA3 CH0 MUX", "PORT_4", "WDMA3 PORT4 MUX"}, + {"WDMA3 CH0 MUX", "PORT_5", "WDMA3 PORT5 MUX"}, + {"WDMA3 CH0 MUX", "PORT_6", "WDMA3 PORT6 MUX"}, + {"WDMA3 CH0 MUX", "PORT_7", "ADC MUX7"}, + {"WDMA3 CH0 MUX", "PORT_8", "ADC MUX8"}, + + {"WDMA3 CH1 MUX", "PORT_0", "WDMA3 PORT0 MUX"}, + {"WDMA3 CH1 MUX", "PORT_1", "WDMA3 PORT1 MUX"}, + {"WDMA3 CH1 MUX", "PORT_2", "WDMA3 PORT2 MUX"}, + {"WDMA3 CH1 MUX", "PORT_3", "WDMA3 PORT3 MUX"}, + {"WDMA3 CH1 MUX", "PORT_4", "WDMA3 PORT4 MUX"}, + {"WDMA3 CH1 MUX", "PORT_5", "WDMA3 PORT5 MUX"}, + {"WDMA3 CH1 MUX", "PORT_6", "WDMA3 PORT6 MUX"}, + {"WDMA3 CH1 MUX", "PORT_7", "ADC MUX7"}, + {"WDMA3 CH1 MUX", "PORT_8", "ADC MUX8"}, + + {"WDMA3 CH2 MUX", "PORT_0", "WDMA3 PORT0 MUX"}, + {"WDMA3 CH2 MUX", "PORT_1", "WDMA3 PORT1 MUX"}, + {"WDMA3 CH2 MUX", "PORT_2", "WDMA3 PORT2 MUX"}, + {"WDMA3 CH2 MUX", "PORT_3", "WDMA3 PORT3 MUX"}, + {"WDMA3 CH2 MUX", "PORT_4", "WDMA3 PORT4 MUX"}, + {"WDMA3 CH2 MUX", "PORT_5", "WDMA3 PORT5 MUX"}, + {"WDMA3 CH2 MUX", "PORT_6", "WDMA3 PORT6 MUX"}, + {"WDMA3 CH2 MUX", "PORT_7", "ADC MUX7"}, + {"WDMA3 CH2 MUX", "PORT_8", "ADC MUX8"}, + + {"WDMA3 CH3 MUX", "PORT_0", "WDMA3 PORT0 MUX"}, + {"WDMA3 CH3 MUX", "PORT_1", "WDMA3 PORT1 MUX"}, + {"WDMA3 CH3 MUX", "PORT_2", "WDMA3 PORT2 MUX"}, + {"WDMA3 CH3 MUX", "PORT_3", "WDMA3 PORT3 MUX"}, + {"WDMA3 CH3 MUX", "PORT_4", "WDMA3 PORT4 MUX"}, + {"WDMA3 CH3 MUX", "PORT_5", "WDMA3 PORT5 MUX"}, + {"WDMA3 CH3 MUX", "PORT_6", "WDMA3 PORT6 MUX"}, + {"WDMA3 CH3 MUX", "PORT_7", "ADC MUX7"}, + {"WDMA3 CH3 MUX", "PORT_8", "ADC MUX8"}, + + {"WDMA3_CH_MIXER", NULL, "WDMA3 CH0 MUX"}, + {"WDMA3_CH_MIXER", NULL, "WDMA3 CH1 MUX"}, + {"WDMA3_CH_MIXER", NULL, "WDMA3 CH2 MUX"}, + {"WDMA3_CH_MIXER", NULL, "WDMA3 CH3 MUX"}, + + {"WDMA3_ON_OFF", "Switch", "WDMA3_CH_MIXER"}, + {"WDMA3_OUT", NULL, "WDMA3_ON_OFF"}, + + /* MAD */ + {"MAD_SEL MUX", "SPE", "MAD_CPE_INPUT"}, + {"MAD_SEL MUX", "MSM", "MADINPUT"}, + + {"MAD_INP MUX", "MAD", "MAD_SEL MUX"}, + {"MAD_INP MUX", "DEC1", "ADC MUX1"}, + + {"MAD_BROADCAST", "Switch", "MAD_INP MUX"}, + {"MAD_CPE1", "Switch", "MAD_INP MUX"}, + {"MAD_CPE2", "Switch", "MAD_INP MUX"}, + + {"MAD_CPE_OUT1", NULL, "MAD_CPE1"}, + {"MAD_CPE_OUT2", NULL, "MAD_CPE2"}, + + {"CDC_IF TX0 MUX", "DEC0", "ADC MUX0"}, + {"CDC_IF TX0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"}, + {"CDC_IF TX0 MUX", "DEC0_192", "ADC US MUX0"}, + + {"CDC_IF TX1 MUX", "DEC1", "ADC MUX1"}, + {"CDC_IF TX1 MUX", "RX_MIX_TX1", "RX MIX TX1 MUX"}, + {"CDC_IF TX1 MUX", "DEC1_192", "ADC US MUX1"}, + + {"CDC_IF TX2 MUX", "DEC2", "ADC MUX2"}, + {"CDC_IF TX2 MUX", "RX_MIX_TX2", "RX MIX TX2 MUX"}, + {"CDC_IF TX2 MUX", "DEC2_192", "ADC US MUX2"}, + + {"CDC_IF TX3 MUX", "DEC3", "ADC MUX3"}, + {"CDC_IF TX3 MUX", "RX_MIX_TX3", "RX MIX TX3 MUX"}, + {"CDC_IF TX3 MUX", "DEC3_192", "ADC US MUX3"}, + + {"CDC_IF TX4 MUX", "DEC4", "ADC MUX4"}, + {"CDC_IF TX4 MUX", "RX_MIX_TX4", "RX MIX TX4 MUX"}, + {"CDC_IF TX4 MUX", "DEC4_192", "ADC US MUX4"}, + + {"CDC_IF TX5 MUX", "DEC5", "ADC MUX5"}, + {"CDC_IF TX5 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"}, + {"CDC_IF TX5 MUX", "DEC5_192", "ADC US MUX5"}, + + {"CDC_IF TX6 MUX", "DEC6", "ADC MUX6"}, + {"CDC_IF TX6 MUX", "RX_MIX_TX6", "RX MIX TX6 MUX"}, + {"CDC_IF TX6 MUX", "DEC6_192", "ADC US MUX6"}, + + {"CDC_IF TX7 MUX", "DEC7", "ADC MUX7"}, + {"CDC_IF TX7 MUX", "RX_MIX_TX7", "RX MIX TX7 MUX"}, + {"CDC_IF TX7 MUX", "DEC7_192", "ADC US MUX7"}, + + {"CDC_IF TX8 MUX", "DEC8", "ADC MUX8"}, + {"CDC_IF TX8 MUX", "RX_MIX_TX8", "RX MIX TX8 MUX"}, + {"CDC_IF TX8 MUX", "DEC8_192", "ADC US MUX8"}, + + {"CDC_IF TX9 MUX", "DEC7", "ADC MUX7"}, + {"CDC_IF TX9 MUX", "DEC7_192", "ADC US MUX7"}, + {"CDC_IF TX10 MUX", "DEC6", "ADC MUX6"}, + {"CDC_IF TX10 MUX", "DEC6_192", "ADC US MUX6"}, + + {"CDC_IF TX11 MUX", "DEC_0_5", "CDC_IF TX11 INP1 MUX"}, + {"CDC_IF TX11 MUX", "DEC_9_12", "CDC_IF TX11 INP1 MUX"}, + {"CDC_IF TX11 INP1 MUX", "DEC0", "ADC MUX0"}, + {"CDC_IF TX11 INP1 MUX", "DEC1", "ADC MUX1"}, + {"CDC_IF TX11 INP1 MUX", "DEC2", "ADC MUX2"}, + {"CDC_IF TX11 INP1 MUX", "DEC3", "ADC MUX3"}, + {"CDC_IF TX11 INP1 MUX", "DEC4", "ADC MUX4"}, + {"CDC_IF TX11 INP1 MUX", "DEC5", "ADC MUX5"}, + {"CDC_IF TX11 INP1 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"}, + + {"CDC_IF TX13 MUX", "MAD_BRDCST", "MAD_BROADCAST"}, + {"CDC_IF TX13 MUX", "CDC_DEC_5", "CDC_IF TX13 INP1 MUX"}, + {"CDC_IF TX13 INP1 MUX", "DEC5", "ADC MUX5"}, + {"CDC_IF TX13 INP1 MUX", "DEC5_192", "ADC US MUX5"}, + + {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, + + {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, + + {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, + + {"RX MIX TX3 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX3 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, + + {"RX MIX TX4 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX4 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, + + {"RX MIX TX5 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX5 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, + + {"RX MIX TX6 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX6 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, + + {"RX MIX TX7 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX7 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, + + {"RX MIX TX8 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, + {"RX MIX TX8 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, + + {"ADC US MUX0", "US_Switch", "ADC MUX0"}, + {"ADC US MUX1", "US_Switch", "ADC MUX1"}, + {"ADC US MUX2", "US_Switch", "ADC MUX2"}, + {"ADC US MUX3", "US_Switch", "ADC MUX3"}, + {"ADC US MUX4", "US_Switch", "ADC MUX4"}, + {"ADC US MUX5", "US_Switch", "ADC MUX5"}, + {"ADC US MUX6", "US_Switch", "ADC MUX6"}, + {"ADC US MUX7", "US_Switch", "ADC MUX7"}, + {"ADC US MUX8", "US_Switch", "ADC MUX8"}, + + {"ADC MUX0", "DMIC", "DMIC MUX0"}, + {"ADC MUX0", "AMIC", "AMIC MUX0"}, + {"ADC MUX1", "DMIC", "DMIC MUX1"}, + {"ADC MUX1", "AMIC", "AMIC MUX1"}, + {"ADC MUX2", "DMIC", "DMIC MUX2"}, + {"ADC MUX2", "AMIC", "AMIC MUX2"}, + {"ADC MUX3", "DMIC", "DMIC MUX3"}, + {"ADC MUX3", "AMIC", "AMIC MUX3"}, + {"ADC MUX4", "DMIC", "DMIC MUX4"}, + {"ADC MUX4", "AMIC", "AMIC MUX4"}, + {"ADC MUX5", "DMIC", "DMIC MUX5"}, + {"ADC MUX5", "AMIC", "AMIC MUX5"}, + {"ADC MUX6", "DMIC", "DMIC MUX6"}, + {"ADC MUX6", "AMIC", "AMIC MUX6"}, + {"ADC MUX7", "DMIC", "DMIC MUX7"}, + {"ADC MUX7", "AMIC", "AMIC MUX7"}, + {"ADC MUX8", "DMIC", "DMIC MUX8"}, + {"ADC MUX8", "AMIC", "AMIC MUX8"}, + {"ADC MUX10", "DMIC", "DMIC MUX10"}, + {"ADC MUX10", "AMIC", "AMIC MUX10"}, + {"ADC MUX11", "DMIC", "DMIC MUX11"}, + {"ADC MUX11", "AMIC", "AMIC MUX11"}, + + {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX11"}, + {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX10"}, + {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX11"}, + + {"DMIC MUX0", "DMIC0", "DMIC0"}, + {"DMIC MUX0", "DMIC1", "DMIC1"}, + {"DMIC MUX0", "DMIC2", "DMIC2"}, + {"DMIC MUX0", "DMIC3", "DMIC3"}, + {"DMIC MUX0", "DMIC4", "DMIC4"}, + {"DMIC MUX0", "DMIC5", "DMIC5"}, + {"DMIC MUX0", "DMIC6", "DMIC6"}, + {"DMIC MUX0", "DMIC7", "DMIC7"}, + {"AMIC MUX0", "ADC1", "ADC1"}, + {"AMIC MUX0", "ADC2", "ADC2"}, + {"AMIC MUX0", "ADC3", "ADC3"}, + {"AMIC MUX0", "ADC4", "ADC4"}, + + {"DMIC MUX1", "DMIC0", "DMIC0"}, + {"DMIC MUX1", "DMIC1", "DMIC1"}, + {"DMIC MUX1", "DMIC2", "DMIC2"}, + {"DMIC MUX1", "DMIC3", "DMIC3"}, + {"DMIC MUX1", "DMIC4", "DMIC4"}, + {"DMIC MUX1", "DMIC5", "DMIC5"}, + {"DMIC MUX1", "DMIC6", "DMIC6"}, + {"DMIC MUX1", "DMIC7", "DMIC7"}, + {"AMIC MUX1", "ADC1", "ADC1"}, + {"AMIC MUX1", "ADC2", "ADC2"}, + {"AMIC MUX1", "ADC3", "ADC3"}, + {"AMIC MUX1", "ADC4", "ADC4"}, + + {"DMIC MUX2", "DMIC0", "DMIC0"}, + {"DMIC MUX2", "DMIC1", "DMIC1"}, + {"DMIC MUX2", "DMIC2", "DMIC2"}, + {"DMIC MUX2", "DMIC3", "DMIC3"}, + {"DMIC MUX2", "DMIC4", "DMIC4"}, + {"DMIC MUX2", "DMIC5", "DMIC5"}, + {"DMIC MUX2", "DMIC6", "DMIC6"}, + {"DMIC MUX2", "DMIC7", "DMIC7"}, + {"AMIC MUX2", "ADC1", "ADC1"}, + {"AMIC MUX2", "ADC2", "ADC2"}, + {"AMIC MUX2", "ADC3", "ADC3"}, + {"AMIC MUX2", "ADC4", "ADC4"}, + + {"DMIC MUX3", "DMIC0", "DMIC0"}, + {"DMIC MUX3", "DMIC1", "DMIC1"}, + {"DMIC MUX3", "DMIC2", "DMIC2"}, + {"DMIC MUX3", "DMIC3", "DMIC3"}, + {"DMIC MUX3", "DMIC4", "DMIC4"}, + {"DMIC MUX3", "DMIC5", "DMIC5"}, + {"DMIC MUX3", "DMIC6", "DMIC6"}, + {"DMIC MUX3", "DMIC7", "DMIC7"}, + {"AMIC MUX3", "ADC1", "ADC1"}, + {"AMIC MUX3", "ADC2", "ADC2"}, + {"AMIC MUX3", "ADC3", "ADC3"}, + {"AMIC MUX3", "ADC4", "ADC4"}, + + {"DMIC MUX4", "DMIC0", "DMIC0"}, + {"DMIC MUX4", "DMIC1", "DMIC1"}, + {"DMIC MUX4", "DMIC2", "DMIC2"}, + {"DMIC MUX4", "DMIC3", "DMIC3"}, + {"DMIC MUX4", "DMIC4", "DMIC4"}, + {"DMIC MUX4", "DMIC5", "DMIC5"}, + {"DMIC MUX4", "DMIC6", "DMIC6"}, + {"DMIC MUX4", "DMIC7", "DMIC7"}, + {"AMIC MUX4", "ADC1", "ADC1"}, + {"AMIC MUX4", "ADC2", "ADC2"}, + {"AMIC MUX4", "ADC3", "ADC3"}, + {"AMIC MUX4", "ADC4", "ADC4"}, + + {"DMIC MUX5", "DMIC0", "DMIC0"}, + {"DMIC MUX5", "DMIC1", "DMIC1"}, + {"DMIC MUX5", "DMIC2", "DMIC2"}, + {"DMIC MUX5", "DMIC3", "DMIC3"}, + {"DMIC MUX5", "DMIC4", "DMIC4"}, + {"DMIC MUX5", "DMIC5", "DMIC5"}, + {"DMIC MUX5", "DMIC6", "DMIC6"}, + {"DMIC MUX5", "DMIC7", "DMIC7"}, + {"AMIC MUX5", "ADC1", "ADC1"}, + {"AMIC MUX5", "ADC2", "ADC2"}, + {"AMIC MUX5", "ADC3", "ADC3"}, + {"AMIC MUX5", "ADC4", "ADC4"}, + + {"DMIC MUX6", "DMIC0", "DMIC0"}, + {"DMIC MUX6", "DMIC1", "DMIC1"}, + {"DMIC MUX6", "DMIC2", "DMIC2"}, + {"DMIC MUX6", "DMIC3", "DMIC3"}, + {"DMIC MUX6", "DMIC4", "DMIC4"}, + {"DMIC MUX6", "DMIC5", "DMIC5"}, + {"DMIC MUX6", "DMIC6", "DMIC6"}, + {"DMIC MUX6", "DMIC7", "DMIC7"}, + {"AMIC MUX6", "ADC1", "ADC1"}, + {"AMIC MUX6", "ADC2", "ADC2"}, + {"AMIC MUX6", "ADC3", "ADC3"}, + {"AMIC MUX6", "ADC4", "ADC4"}, + + {"DMIC MUX7", "DMIC0", "DMIC0"}, + {"DMIC MUX7", "DMIC1", "DMIC1"}, + {"DMIC MUX7", "DMIC2", "DMIC2"}, + {"DMIC MUX7", "DMIC3", "DMIC3"}, + {"DMIC MUX7", "DMIC4", "DMIC4"}, + {"DMIC MUX7", "DMIC5", "DMIC5"}, + {"DMIC MUX7", "DMIC6", "DMIC6"}, + {"DMIC MUX7", "DMIC7", "DMIC7"}, + {"AMIC MUX7", "ADC1", "ADC1"}, + {"AMIC MUX7", "ADC2", "ADC2"}, + {"AMIC MUX7", "ADC3", "ADC3"}, + {"AMIC MUX7", "ADC4", "ADC4"}, + + {"DMIC MUX8", "DMIC0", "DMIC0"}, + {"DMIC MUX8", "DMIC1", "DMIC1"}, + {"DMIC MUX8", "DMIC2", "DMIC2"}, + {"DMIC MUX8", "DMIC3", "DMIC3"}, + {"DMIC MUX8", "DMIC4", "DMIC4"}, + {"DMIC MUX8", "DMIC5", "DMIC5"}, + {"DMIC MUX8", "DMIC6", "DMIC6"}, + {"DMIC MUX8", "DMIC7", "DMIC7"}, + {"AMIC MUX8", "ADC1", "ADC1"}, + {"AMIC MUX8", "ADC2", "ADC2"}, + {"AMIC MUX8", "ADC3", "ADC3"}, + {"AMIC MUX8", "ADC4", "ADC4"}, + + {"DMIC MUX10", "DMIC0", "DMIC0"}, + {"DMIC MUX10", "DMIC1", "DMIC1"}, + {"DMIC MUX10", "DMIC2", "DMIC2"}, + {"DMIC MUX10", "DMIC3", "DMIC3"}, + {"DMIC MUX10", "DMIC4", "DMIC4"}, + {"DMIC MUX10", "DMIC5", "DMIC5"}, + {"DMIC MUX10", "DMIC6", "DMIC6"}, + {"DMIC MUX10", "DMIC7", "DMIC7"}, + {"AMIC MUX10", "ADC1", "ADC1"}, + {"AMIC MUX10", "ADC2", "ADC2"}, + {"AMIC MUX10", "ADC3", "ADC3"}, + {"AMIC MUX10", "ADC4", "ADC4"}, + + {"DMIC MUX11", "DMIC0", "DMIC0"}, + {"DMIC MUX11", "DMIC1", "DMIC1"}, + {"DMIC MUX11", "DMIC2", "DMIC2"}, + {"DMIC MUX11", "DMIC3", "DMIC3"}, + {"DMIC MUX11", "DMIC4", "DMIC4"}, + {"DMIC MUX11", "DMIC5", "DMIC5"}, + {"DMIC MUX11", "DMIC6", "DMIC6"}, + {"DMIC MUX11", "DMIC7", "DMIC7"}, + {"AMIC MUX11", "ADC1", "ADC1"}, + {"AMIC MUX11", "ADC2", "ADC2"}, + {"AMIC MUX11", "ADC3", "ADC3"}, + {"AMIC MUX11", "ADC4", "ADC4"}, + + {"ADC2_IN", "AMIC1", "AMIC1"}, + {"ADC2_IN", "AMIC2", "AMIC2"}, + {"ADC4_IN", "AMIC3", "AMIC3"}, + {"ADC4_IN", "AMIC4", "AMIC4"}, + + {"ADC1", NULL, "AMIC1"}, + {"ADC2", NULL, "ADC2_IN"}, + {"ADC3", NULL, "AMIC3"}, + {"ADC4", NULL, "ADC4_IN"}, + + {"ADC1", NULL, "LDO_RXTX"}, + {"ADC2", NULL, "LDO_RXTX"}, + {"ADC3", NULL, "LDO_RXTX"}, + {"ADC4", NULL, "LDO_RXTX"}, + + {"RX INT0_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT0_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT0_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT0_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT0_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT0_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT0_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT0_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT0_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT0_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT0_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT0_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT0_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT0_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT0_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT0_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT0_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT0_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT0_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT0_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT0_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT0_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"}, + + {"RX INT7_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT7_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT7_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT7_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT7_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT7_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT7_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT7_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT7_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT7_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT7_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT7_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT7_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT7_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT7_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT7_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT7_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT7_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT7_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT7_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT7_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT7_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT7_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT7_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT7_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT7_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT7_1 MIX1 INP2", "IIR0", "IIR0"}, + + {"RX INT8_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT8_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT8_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT8_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT8_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT8_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT8_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT8_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT8_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT8_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT8_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT8_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT8_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT8_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT8_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT8_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT8_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT8_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT8_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT8_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT8_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT8_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT8_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT8_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT8_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT8_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT8_1 MIX1 INP2", "IIR0", "IIR0"}, + + {"RX INT9_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT9_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT9_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT9_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT9_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT9_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT9_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT9_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT9_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT9_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT9_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT9_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT9_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT9_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT9_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT9_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT9_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT9_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT9_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT9_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT9_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT9_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT9_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT9_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT9_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT9_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT9_1 MIX1 INP2", "IIR0", "IIR0"}, + + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"}, + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"}, + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"}, + {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP0"}, + {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP1"}, + {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP2"}, + {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP0"}, + {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP1"}, + {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP2"}, + {"RX INT9_1 MIX1", NULL, "RX INT9_1 MIX1 INP0"}, + {"RX INT9_1 MIX1", NULL, "RX INT9_1 MIX1 INP1"}, + {"RX INT9_1 MIX1", NULL, "RX INT9_1 MIX1 INP2"}, + + /* Mixing path INT0 */ + {"RX INT0_2 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT0_2 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT0_2 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT0_2 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT0_2 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT0_2 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT0_2 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT0_2 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT0_2 INTERP", NULL, "RX INT0_2 MUX"}, + {"RX INT0 SEC MIX", NULL, "RX INT0_2 INTERP"}, + + /* Mixing path INT7 */ + {"RX INT7_2 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT7_2 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT7_2 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT7_2 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT7_2 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT7_2 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT7_2 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT7_2 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT7_2 INTERP", NULL, "RX INT7_2 MUX"}, + {"RX INT7 SEC MIX", NULL, "RX INT7_2 INTERP"}, + + /* Mixing path INT8 */ + {"RX INT8_2 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT8_2 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT8_2 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT8_2 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT8_2 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT8_2 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT8_2 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT8_2 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT8_2 INTERP", NULL, "RX INT8_2 MUX"}, + {"RX INT8 SEC MIX", NULL, "RX INT8_2 INTERP"}, + + /* Mixing path INT9 */ + {"RX INT9_2 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"RX INT9_2 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"RX INT9_2 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"RX INT9_2 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"RX INT9_2 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"RX INT9_2 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"RX INT9_2 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"RX INT9_2 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"RX INT9_2 INTERP", NULL, "RX INT9_2 MUX"}, + {"RX INT9 SEC MIX", NULL, "RX INT9_2 INTERP"}, + + {"RX INT0_1 INTERP", NULL, "RX INT0_1 MIX1"}, + {"RX INT0 SEC MIX", NULL, "RX INT0_1 INTERP"}, + {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"}, + {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"}, + {"RX INT0 DEM MUX", NULL, "RX INT0 MIX2"}, + {"RX INT0 DAC", NULL, "RX INT0 DEM MUX"}, + {"RX INT0 DAC", NULL, "LDO_RXTX"}, + {"EAR PA", NULL, "RX INT0 DAC"}, + {"EAR", NULL, "EAR PA"}, + + {"RX INT7_1 INTERP", NULL, "RX INT7_1 MIX1"}, + {"RX INT7 SEC MIX", NULL, "RX INT7_1 INTERP"}, + {"RX INT7 MIX2", NULL, "RX INT7 SEC MIX"}, + {"RX INT7 MIX2", NULL, "RX INT7 MIX2 INP"}, + {"RX INT7 CHAIN", NULL, "RX INT7 MIX2"}, + {"SPK1 OUT", NULL, "RX INT7 CHAIN"}, + + {"RX INT8_1 INTERP", NULL, "RX INT8_1 MIX1"}, + {"RX INT8 SEC MIX", NULL, "RX INT8_1 INTERP"}, + {"RX INT8 SEC MIX", NULL, "RX INT8_1 MIX1"}, + {"RX INT8 CHAIN", NULL, "RX INT8 SEC MIX"}, + {"SPK2 OUT", NULL, "RX INT8 CHAIN"}, + + {"RX INT9_1 INTERP", NULL, "RX INT9_1 MIX1"}, + {"RX INT9 SEC MIX", NULL, "RX INT9_1 INTERP"}, + {"RX INT9 MIX2", NULL, "RX INT9 SEC MIX"}, + {"RX INT9 MIX2", NULL, "RX INT9 MIX2 INP"}, + {"RX INT9 DEM MUX", NULL, "RX INT9 MIX2"}, + {"RX INT9 DAC", NULL, "RX INT9 DEM MUX"}, + {"RX INT9 DAC", NULL, "LDO_RXTX"}, + {"AUX PA", NULL, "RX INT9 DAC"}, + {"AUX", NULL, "AUX PA"}, + + /* ANC Routing */ + {"ANC0 FB MUX", "ANC_IN_EAR", "RX INT0 MIX2"}, + {"ANC0 FB MUX", "ANC_IN_EAR_SPKR", "RX INT7 MIX2"}, + + {"ANC OUT EAR Enable", "Switch", "ADC MUX10"}, + {"ANC OUT EAR Enable", "Switch", "ADC MUX11"}, + {"RX INT0 MIX2", NULL, "ANC OUT EAR Enable"}, + + {"ANC EAR PA", NULL, "RX INT0 DAC"}, + {"ANC EAR", NULL, "ANC EAR PA"}, + + {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX10"}, + {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX11"}, + {"RX INT7 MIX2", NULL, "ANC OUT EAR SPKR Enable"}, + + {"ANC SPKR PA Enable", "Switch", "RX INT7 CHAIN"}, + {"ANC SPK1 PA", NULL, "ANC SPKR PA Enable"}, + {"SPK1 OUT", NULL, "ANC SPK1 PA"}, + + /* + * SRC0 input to Sidetone RX Mixer + * on RX0, RX1, RX2, RX3, RX4 and RX7 chains + */ + {"IIR0", NULL, "IIR0 INP0 MUX"}, + {"IIR0 INP0 MUX", "DEC0", "ADC MUX0"}, + {"IIR0 INP0 MUX", "DEC1", "ADC MUX1"}, + {"IIR0 INP0 MUX", "DEC2", "ADC MUX2"}, + {"IIR0 INP0 MUX", "DEC3", "ADC MUX3"}, + {"IIR0 INP0 MUX", "DEC4", "ADC MUX4"}, + {"IIR0 INP0 MUX", "DEC5", "ADC MUX5"}, + {"IIR0 INP0 MUX", "DEC6", "ADC MUX6"}, + {"IIR0 INP0 MUX", "DEC7", "ADC MUX7"}, + {"IIR0 INP0 MUX", "DEC8", "ADC MUX8"}, + {"IIR0 INP0 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"IIR0 INP0 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"IIR0 INP0 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"IIR0 INP0 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"IIR0 INP0 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"IIR0 INP0 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"IIR0 INP0 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"IIR0 INP0 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"IIR0", NULL, "IIR0 INP1 MUX"}, + {"IIR0 INP1 MUX", "DEC0", "ADC MUX0"}, + {"IIR0 INP1 MUX", "DEC1", "ADC MUX1"}, + {"IIR0 INP1 MUX", "DEC2", "ADC MUX2"}, + {"IIR0 INP1 MUX", "DEC3", "ADC MUX3"}, + {"IIR0 INP1 MUX", "DEC4", "ADC MUX4"}, + {"IIR0 INP1 MUX", "DEC5", "ADC MUX5"}, + {"IIR0 INP1 MUX", "DEC6", "ADC MUX6"}, + {"IIR0 INP1 MUX", "DEC7", "ADC MUX7"}, + {"IIR0 INP1 MUX", "DEC8", "ADC MUX8"}, + {"IIR0 INP1 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"IIR0 INP1 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"IIR0 INP1 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"IIR0 INP1 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"IIR0 INP1 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"IIR0 INP1 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"IIR0 INP1 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"IIR0 INP1 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"IIR0", NULL, "IIR0 INP2 MUX"}, + {"IIR0 INP2 MUX", "DEC0", "ADC MUX0"}, + {"IIR0 INP2 MUX", "DEC1", "ADC MUX1"}, + {"IIR0 INP2 MUX", "DEC2", "ADC MUX2"}, + {"IIR0 INP2 MUX", "DEC3", "ADC MUX3"}, + {"IIR0 INP2 MUX", "DEC4", "ADC MUX4"}, + {"IIR0 INP2 MUX", "DEC5", "ADC MUX5"}, + {"IIR0 INP2 MUX", "DEC6", "ADC MUX6"}, + {"IIR0 INP2 MUX", "DEC7", "ADC MUX7"}, + {"IIR0 INP2 MUX", "DEC8", "ADC MUX8"}, + {"IIR0 INP2 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"IIR0 INP2 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"IIR0 INP2 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"IIR0 INP2 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"IIR0 INP2 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"IIR0 INP2 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"IIR0 INP2 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"IIR0 INP2 MUX", "RX7", "CDC_IF RX7 MUX"}, + {"IIR0", NULL, "IIR0 INP3 MUX"}, + {"IIR0 INP3 MUX", "DEC0", "ADC MUX0"}, + {"IIR0 INP3 MUX", "DEC1", "ADC MUX1"}, + {"IIR0 INP3 MUX", "DEC2", "ADC MUX2"}, + {"IIR0 INP3 MUX", "DEC3", "ADC MUX3"}, + {"IIR0 INP3 MUX", "DEC4", "ADC MUX4"}, + {"IIR0 INP3 MUX", "DEC5", "ADC MUX5"}, + {"IIR0 INP3 MUX", "DEC6", "ADC MUX6"}, + {"IIR0 INP3 MUX", "DEC7", "ADC MUX7"}, + {"IIR0 INP3 MUX", "DEC8", "ADC MUX8"}, + {"IIR0 INP3 MUX", "RX0", "CDC_IF RX0 MUX"}, + {"IIR0 INP3 MUX", "RX1", "CDC_IF RX1 MUX"}, + {"IIR0 INP3 MUX", "RX2", "CDC_IF RX2 MUX"}, + {"IIR0 INP3 MUX", "RX3", "CDC_IF RX3 MUX"}, + {"IIR0 INP3 MUX", "RX4", "CDC_IF RX4 MUX"}, + {"IIR0 INP3 MUX", "RX5", "CDC_IF RX5 MUX"}, + {"IIR0 INP3 MUX", "RX6", "CDC_IF RX6 MUX"}, + {"IIR0 INP3 MUX", "RX7", "CDC_IF RX7 MUX"}, + + {"SRC0", NULL, "IIR0"}, + {"RX INT0 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT7 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT9 MIX2 INP", "SRC0", "SRC0"}, + + /* Native clk mix path routing */ + {"RX INT7_2 NATIVE MUX", "ON", "RX INT7_2 MUX"}, + {"RX INT7_2 INTERP", NULL, "RX INT7_2 NATIVE MUX"}, + {"RX INT7_2 NATIVE MUX", NULL, "RX INT7 NATIVE SUPPLY"}, + + {"RX INT8_2 NATIVE MUX", "ON", "RX INT8_2 MUX"}, + {"RX INT8_2 INTERP", NULL, "RX INT8_2 NATIVE MUX"}, + {"RX INT8_2 NATIVE MUX", NULL, "RX INT8 NATIVE SUPPLY"}, + + /* ASRC Routing */ + {"ASRC2 MUX", "ASRC_IN_SPKR1", "RX INT7_2 INTERP"}, + {"RX INT7 SEC MIX", NULL, "ASRC2 MUX"}, + + {"ASRC3 MUX", "ASRC_IN_SPKR2", "RX INT8_2 INTERP"}, + {"RX INT8 SEC MIX", NULL, "ASRC3 MUX"}, +}; + +#endif diff --git a/asoc/codecs/wcd9360/wcd9360.c b/asoc/codecs/wcd9360/wcd9360.c new file mode 100644 index 000000000000..f0f6b47a08a9 --- /dev/null +++ b/asoc/codecs/wcd9360/wcd9360.c @@ -0,0 +1,7915 @@ +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcd9360.h" +#include "wcd9360-routing.h" +#include "wcd9360-dsp-cntl.h" +#include "wcd9360-irq.h" +#include "../core.h" +#include "../pdata.h" +#include "../wcd9xxx-irq.h" +#include "../wcd9xxx-common-v2.h" +#include "../wcd9xxx-resmgr-v2.h" +#include "../wcdcal-hwdep.h" +#include "../msm-cdc-supply.h" + + +#define WCD9360_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\ + SNDRV_PCM_RATE_384000) +/* Fractional Rates */ +#define WCD9360_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_176400) + +#define WCD9360_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE) + +#define WCD9360_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +#define WCD9360_FORMATS_S16_LE (SNDRV_PCM_FMTBIT_S16_LE) + +/* Macros for packing register writes into a U32 */ +#define WCD9360_PACKED_REG_SIZE sizeof(u32) +#define WCD9360_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \ + do { \ + ((reg) = ((packed >> 16) & (0xffff))); \ + ((mask) = ((packed >> 8) & (0xff))); \ + ((val) = ((packed) & (0xff))); \ + } while (0) + +#define STRING(name) #name +#define WCD_DAPM_ENUM(name, reg, offset, text) \ +static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ +static const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_ENUM(STRING(name), name##_enum) + +#define WCD_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \ +static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ +static const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname) + +#define WCD_DAPM_MUX(name, shift, kctl) \ + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux) + +/* + * Timeout in milli seconds and it is the wait time for + * slim channel removal interrupt to receive. + */ +#define WCD9360_SLIM_CLOSE_TIMEOUT 1000 +#define WCD9360_SLIM_IRQ_OVERFLOW (1 << 0) +#define WCD9360_SLIM_IRQ_UNDERFLOW (1 << 1) +#define WCD9360_SLIM_IRQ_PORT_CLOSED (1 << 2) + +#define WCD9360_MCLK_CLK_9P6MHZ 9600000 + +#define WCD9360_INTERP_MUX_NUM_INPUTS 3 +#define WCD9360_NUM_INTERPOLATORS 10 +#define WCD9360_NUM_DECIMATORS 9 +#define WCD9360_RX_PATH_CTL_OFFSET 20 +#define WCD9360_TLMM_DMIC_PINCFG_OFFSET 15 + +#define BYTE_BIT_MASK(nr) (1 << ((nr) % BITS_PER_BYTE)) + +#define WCD9360_REG_BITS 8 +#define WCD9360_MAX_VALID_ADC_MUX 11 +#define WCD9360_INVALID_ADC_MUX 9 + +#define WCD9360_AMIC_PWR_LEVEL_LP 0 +#define WCD9360_AMIC_PWR_LEVEL_DEFAULT 1 +#define WCD9360_AMIC_PWR_LEVEL_HP 2 +#define WCD9360_AMIC_PWR_LVL_MASK 0x60 +#define WCD9360_AMIC_PWR_LVL_SHIFT 0x5 + +#define WCD9360_DEC_PWR_LVL_MASK 0x06 +#define WCD9360_DEC_PWR_LVL_LP 0x02 +#define WCD9360_DEC_PWR_LVL_HP 0x04 +#define WCD9360_DEC_PWR_LVL_DF 0x00 +#define WCD9360_STRING_LEN 100 + +#define WCD9360_CDC_SIDETONE_IIR_COEFF_MAX 5 +#define WCD9360_CDC_REPEAT_WRITES_MAX 16 +#define WCD9360_DIG_CORE_REG_MIN WCD9360_CDC_ANC0_CLK_RESET_CTL +#define WCD9360_DIG_CORE_REG_MAX 0xFFF + +#define WCD9360_CHILD_DEVICES_MAX 6 + +#define WCD9360_MAX_MICBIAS 4 +#define DAPM_MICBIAS1_STANDALONE "MIC BIAS1 Standalone" +#define DAPM_MICBIAS2_STANDALONE "MIC BIAS2 Standalone" +#define DAPM_MICBIAS3_STANDALONE "MIC BIAS3 Standalone" +#define DAPM_MICBIAS4_STANDALONE "MIC BIAS4 Standalone" + +#define WCD9360_LDO_RXTX_SUPPLY_NAME "vdd_ldo_rxtx_supply" + +#define TX_HPF_CUT_OFF_FREQ_MASK 0x60 +#define CF_MIN_3DB_4HZ 0x0 +#define CF_MIN_3DB_75HZ 0x1 +#define CF_MIN_3DB_150HZ 0x2 + +#define CPE_ERR_WDOG_BITE BIT(0) +#define CPE_FATAL_IRQS CPE_ERR_WDOG_BITE + +#define WCD9360_MAD_AUDIO_FIRMWARE_PATH "wcd9360/wcd9360_mad_audio.bin" + +#define PAHU_VERSION_ENTRY_SIZE 17 + +#define WCD9360_DIG_CORE_COLLAPSE_TIMER_MS (5 * 1000) + +enum { + POWER_COLLAPSE, + POWER_RESUME, +}; + +static int dig_core_collapse_enable = 1; +module_param(dig_core_collapse_enable, int, 0664); +MODULE_PARM_DESC(dig_core_collapse_enable, "enable/disable power gating"); + +/* dig_core_collapse timer in seconds */ +static int dig_core_collapse_timer = (WCD9360_DIG_CORE_COLLAPSE_TIMER_MS/1000); +module_param(dig_core_collapse_timer, int, 0664); +MODULE_PARM_DESC(dig_core_collapse_timer, "timer for power gating"); + +enum { + VI_SENSE_1, + VI_SENSE_2, + CLK_INTERNAL, + CLK_MODE, +}; + +enum { + AIF1_PB = 0, + AIF1_CAP, + AIF2_PB, + AIF2_CAP, + AIF3_PB, + AIF3_CAP, + AIF4_PB, + AIF4_VIFEED, + AIF4_MAD_TX, + NUM_CODEC_DAIS, +}; + +enum { + INTn_1_INP_SEL_ZERO = 0, + INTn_1_INP_SEL_DEC0, + INTn_1_INP_SEL_DEC1, + INTn_1_INP_SEL_IIR0, + INTn_1_INP_SEL_NA, + INTn_1_INP_SEL_RX0, + INTn_1_INP_SEL_RX1, + INTn_1_INP_SEL_RX2, + INTn_1_INP_SEL_RX3, + INTn_1_INP_SEL_RX4, + INTn_1_INP_SEL_RX5, + INTn_1_INP_SEL_RX6, + INTn_1_INP_SEL_RX7, +}; + +enum { + INTn_2_INP_SEL_ZERO = 0, + INTn_2_INP_SEL_RX0, + INTn_2_INP_SEL_RX1, + INTn_2_INP_SEL_RX2, + INTn_2_INP_SEL_RX3, + INTn_2_INP_SEL_RX4, + INTn_2_INP_SEL_RX5, + INTn_2_INP_SEL_RX6, + INTn_2_INP_SEL_RX7, + INTn_2_INP_SEL_PROXIMITY, +}; + +enum { + INTERP_MAIN_PATH, + INTERP_MIX_PATH, +}; + +struct pahu_cpr_reg_defaults { + int wr_data; + int wr_addr; +}; + +struct interp_sample_rate { + int sample_rate; + int rate_val; +}; + +static struct interp_sample_rate sr_val_tbl[] = { + {8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5}, + {192000, 0x6}, {384000, 0x7}, {44100, 0x9}, {88200, 0xA}, + {176400, 0xB}, {352800, 0xC}, +}; + +static const struct wcd9xxx_ch pahu_rx_chs[WCD9360_RX_MAX] = { + WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER, 0), + WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 1, 1), + WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 2, 2), + WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 3, 3), + WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 4, 4), + WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 5, 5), + WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 6, 6), + WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 7, 7), +}; + +static const struct wcd9xxx_ch pahu_tx_chs[WCD9360_TX_MAX] = { + WCD9XXX_CH(0, 0), + WCD9XXX_CH(1, 1), + WCD9XXX_CH(2, 2), + WCD9XXX_CH(3, 3), + WCD9XXX_CH(4, 4), + WCD9XXX_CH(5, 5), + WCD9XXX_CH(6, 6), + WCD9XXX_CH(7, 7), + WCD9XXX_CH(8, 8), + WCD9XXX_CH(9, 9), + WCD9XXX_CH(10, 10), + WCD9XXX_CH(11, 11), + WCD9XXX_CH(12, 12), + WCD9XXX_CH(13, 13), + WCD9XXX_CH(14, 14), + WCD9XXX_CH(15, 15), +}; + +static const u32 vport_slim_check_table[NUM_CODEC_DAIS] = { + 0, /* AIF1_PB */ + BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX), /* AIF1_CAP */ + 0, /* AIF2_PB */ + BIT(AIF1_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX), /* AIF2_CAP */ + 0, /* AIF3_PB */ + BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF4_MAD_TX), /* AIF3_CAP */ + 0, /* AIF4_PB */ +}; + +/* Codec supports 2 IIR filters */ +enum { + IIR0 = 0, + IIR_MAX, +}; + +/* Each IIR has 5 Filter Stages */ +enum { + BAND1 = 0, + BAND2, + BAND3, + BAND4, + BAND5, + BAND_MAX, +}; + +enum { + COMPANDER_0, /* EAR */ + COMPANDER_1, /* HPH_L */ + COMPANDER_2, /* HPH_R */ + COMPANDER_3, /* LO1_DIFF */ + COMPANDER_4, /* LO2_DIFF */ + COMPANDER_5, /* LO3_SE */ + COMPANDER_6, /* LO4_SE */ + COMPANDER_7, /* SWR SPK CH1 */ + COMPANDER_8, /* SWR SPK CH2 */ + COMPANDER_9, /* AUX */ + COMPANDER_MAX, +}; + +enum { + ASRC_IN_SPKR1, + ASRC_IN_SPKR2, + ASRC_INVALID, +}; + +enum { + ASRC2, + ASRC3, + ASRC_MAX, +}; + +enum { + CONV_88P2K_TO_384K, + CONV_96K_TO_352P8K, + CONV_352P8K_TO_384K, + CONV_384K_TO_352P8K, + CONV_384K_TO_384K, + CONV_96K_TO_384K, +}; + +static struct afe_param_slimbus_slave_port_cfg pahu_slimbus_slave_port_cfg = { + .minor_version = 1, + .slimbus_dev_id = AFE_SLIMBUS_DEVICE_1, + .slave_dev_pgd_la = 0, + .slave_dev_intfdev_la = 0, + .bit_width = 16, + .data_format = 0, + .num_channels = 1 +}; + +static struct afe_param_cdc_reg_page_cfg pahu_cdc_reg_page_cfg = { + .minor_version = AFE_API_VERSION_CDC_REG_PAGE_CFG, + .enable = 1, + .proc_id = AFE_CDC_REG_PAGE_ASSIGN_PROC_ID_1, +}; + +static struct afe_param_cdc_reg_cfg audio_reg_cfg[] = { + { + 1, + (WCD9360_REGISTER_START_OFFSET + WCD9360_SOC_MAD_MAIN_CTL_1), + HW_MAD_AUDIO_ENABLE, 0x1, WCD9360_REG_BITS, 0 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + WCD9360_SOC_MAD_AUDIO_CTL_3), + HW_MAD_AUDIO_SLEEP_TIME, 0xF, WCD9360_REG_BITS, 0 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + WCD9360_SOC_MAD_AUDIO_CTL_4), + HW_MAD_TX_AUDIO_SWITCH_OFF, 0x1, WCD9360_REG_BITS, 0 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + WCD9360_INTR_CFG), + MAD_AUDIO_INT_DEST_SELECT_REG, 0x2, WCD9360_REG_BITS, 0 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + WCD9360_INTR_PIN2_MASK3), + MAD_AUDIO_INT_MASK_REG, 0x1, WCD9360_REG_BITS, 0 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + WCD9360_INTR_PIN2_STATUS3), + MAD_AUDIO_INT_STATUS_REG, 0x1, WCD9360_REG_BITS, 0 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + WCD9360_INTR_PIN2_CLEAR3), + MAD_AUDIO_INT_CLEAR_REG, 0x1, WCD9360_REG_BITS, 0 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + WCD9360_SB_PGD_PORT_TX_BASE), + SB_PGD_PORT_TX_WATERMARK_N, 0x1E, WCD9360_REG_BITS, 0x1 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + WCD9360_SB_PGD_PORT_TX_BASE), + SB_PGD_PORT_TX_ENABLE_N, 0x1, WCD9360_REG_BITS, 0x1 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + WCD9360_SB_PGD_PORT_RX_BASE), + SB_PGD_PORT_RX_WATERMARK_N, 0x1E, WCD9360_REG_BITS, 0x1 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + WCD9360_SB_PGD_PORT_RX_BASE), + SB_PGD_PORT_RX_ENABLE_N, 0x1, WCD9360_REG_BITS, 0x1 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + + WCD9360_CDC_ANC0_IIR_ADAPT_CTL), + AANC_FF_GAIN_ADAPTIVE, 0x4, WCD9360_REG_BITS, 0 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + + WCD9360_CDC_ANC0_IIR_ADAPT_CTL), + AANC_FFGAIN_ADAPTIVE_EN, 0x8, WCD9360_REG_BITS, 0 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + + WCD9360_CDC_ANC0_FF_A_GAIN_CTL), + AANC_GAIN_CONTROL, 0xFF, WCD9360_REG_BITS, 0 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + + SB_PGD_TX_PORT_MULTI_CHANNEL_0(0)), + SB_PGD_TX_PORTn_MULTI_CHNL_0, 0xFF, WCD9360_REG_BITS, 0x4 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + + SB_PGD_TX_PORT_MULTI_CHANNEL_1(0)), + SB_PGD_TX_PORTn_MULTI_CHNL_1, 0xFF, WCD9360_REG_BITS, 0x4 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + + SB_PGD_RX_PORT_MULTI_CHANNEL_0(0x180, 0)), + SB_PGD_RX_PORTn_MULTI_CHNL_0, 0xFF, WCD9360_REG_BITS, 0x4 + }, + { + 1, + (WCD9360_REGISTER_START_OFFSET + + SB_PGD_RX_PORT_MULTI_CHANNEL_0(0x181, 0)), + SB_PGD_RX_PORTn_MULTI_CHNL_1, 0xFF, WCD9360_REG_BITS, 0x4 + }, +}; + +static struct afe_param_cdc_reg_cfg_data pahu_audio_reg_cfg = { + .num_registers = ARRAY_SIZE(audio_reg_cfg), + .reg_data = audio_reg_cfg, +}; + +static struct afe_param_id_cdc_aanc_version pahu_cdc_aanc_version = { + .cdc_aanc_minor_version = AFE_API_VERSION_CDC_AANC_VERSION, + .aanc_hw_version = AANC_HW_BLOCK_VERSION_2, +}; + +static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); +static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); + +#define WCD9360_TX_UNMUTE_DELAY_MS 40 + +static int tx_unmute_delay = WCD9360_TX_UNMUTE_DELAY_MS; +module_param(tx_unmute_delay, int, 0664); +MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path"); + +static void pahu_codec_set_tx_hold(struct snd_soc_codec *, u16, bool); + +/* Hold instance to soundwire platform device */ +struct pahu_swr_ctrl_data { + struct platform_device *swr_pdev; +}; + +struct wcd_swr_ctrl_platform_data { + void *handle; /* holds codec private data */ + int (*read)(void *handle, int reg); + int (*write)(void *handle, int reg, int val); + int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); + int (*clk)(void *handle, bool enable); + int (*handle_irq)(void *handle, + irqreturn_t (*swrm_irq_handler)(int irq, void *data), + void *swrm_handle, int action); +}; + +/* Holds all Soundwire and speaker related information */ +struct wcd9360_swr { + struct pahu_swr_ctrl_data *ctrl_data; + struct wcd_swr_ctrl_platform_data plat_data; + struct mutex read_mutex; + struct mutex write_mutex; + struct mutex clk_mutex; + int spkr_gain_offset; + int spkr_mode; + int clk_users; + int rx_7_count; + int rx_8_count; +}; + +struct tx_mute_work { + struct pahu_priv *pahu; + u8 decimator; + struct delayed_work dwork; +}; + +#define WCD9360_SPK_ANC_EN_DELAY_MS 550 +static int spk_anc_en_delay = WCD9360_SPK_ANC_EN_DELAY_MS; +module_param(spk_anc_en_delay, int, 0664); +MODULE_PARM_DESC(spk_anc_en_delay, "delay to enable anc in speaker path"); + +struct spk_anc_work { + struct pahu_priv *pahu; + struct delayed_work dwork; +}; + +struct hpf_work { + struct pahu_priv *pahu; + u8 decimator; + u8 hpf_cut_off_freq; + struct delayed_work dwork; +}; + +struct pahu_priv { + struct device *dev; + struct wcd9xxx *wcd9xxx; + struct snd_soc_codec *codec; + s32 ldo_rxtx_cnt; + s32 dmic_0_1_clk_cnt; + s32 dmic_2_3_clk_cnt; + s32 dmic_4_5_clk_cnt; + s32 dmic_6_7_clk_cnt; + s32 micb_ref[PAHU_MAX_MICBIAS]; + s32 pullup_ref[PAHU_MAX_MICBIAS]; + + /* ANC related */ + u32 anc_slot; + bool anc_func; + + /* compander */ + int comp_enabled[COMPANDER_MAX]; + int ear_spkr_gain; + + /* Mad switch reference count */ + int mad_switch_cnt; + + /* track pahu interface type */ + u8 intf_type; + + /* to track the status */ + unsigned long status_mask; + + struct afe_param_cdc_slimbus_slave_cfg slimbus_slave_cfg; + + /* num of slim ports required */ + struct wcd9xxx_codec_dai_data dai[NUM_CODEC_DAIS]; + /* Port values for Rx and Tx codec_dai */ + unsigned int rx_port_value[WCD9360_RX_MAX]; + unsigned int tx_port_value; + + struct wcd9xxx_resmgr_v2 *resmgr; + struct wcd9360_swr swr; + struct mutex micb_lock; + + struct delayed_work power_gate_work; + struct mutex power_lock; + + struct clk *wcd_ext_clk; + + struct mutex codec_mutex; + struct work_struct pahu_add_child_devices_work; + struct hpf_work tx_hpf_work[WCD9360_NUM_DECIMATORS]; + struct tx_mute_work tx_mute_dwork[WCD9360_NUM_DECIMATORS]; + struct spk_anc_work spk_anc_dwork; + + unsigned int vi_feed_value; + + /* DSP control */ + struct wcd_dsp_cntl *wdsp_cntl; + + /* cal info for codec */ + struct fw_info *fw_data; + + /* Entry for version info */ + struct snd_info_entry *entry; + struct snd_info_entry *version_entry; + + /* SVS voting related */ + struct mutex svs_mutex; + int svs_ref_cnt; + + int native_clk_users; + /* ASRC users count */ + int asrc_users[ASRC_MAX]; + int asrc_output_mode[ASRC_MAX]; + /* Main path clock users count */ + int main_clk_users[WCD9360_NUM_INTERPOLATORS]; + + int power_active_ref; + u8 sidetone_coeff_array[IIR_MAX][BAND_MAX] + [WCD9360_CDC_SIDETONE_IIR_COEFF_MAX * 4]; + + struct spi_device *spi; + struct platform_device *pdev_child_devices + [WCD9360_CHILD_DEVICES_MAX]; + int child_count; +}; + +static const struct pahu_reg_mask_val pahu_spkr_default[] = { + {WCD9360_CDC_COMPANDER7_CTL3, 0x80, 0x80}, + {WCD9360_CDC_COMPANDER8_CTL3, 0x80, 0x80}, + {WCD9360_CDC_COMPANDER7_CTL7, 0x01, 0x01}, + {WCD9360_CDC_COMPANDER8_CTL7, 0x01, 0x01}, + {WCD9360_CDC_BOOST0_BOOST_CTL, 0x7C, 0x50}, + {WCD9360_CDC_BOOST1_BOOST_CTL, 0x7C, 0x50}, +}; + +static const struct pahu_reg_mask_val pahu_spkr_mode1[] = { + {WCD9360_CDC_COMPANDER7_CTL3, 0x80, 0x00}, + {WCD9360_CDC_COMPANDER8_CTL3, 0x80, 0x00}, + {WCD9360_CDC_COMPANDER7_CTL7, 0x01, 0x00}, + {WCD9360_CDC_COMPANDER8_CTL7, 0x01, 0x00}, + {WCD9360_CDC_BOOST0_BOOST_CTL, 0x7C, 0x44}, + {WCD9360_CDC_BOOST1_BOOST_CTL, 0x7C, 0x44}, +}; + +static int __pahu_enable_efuse_sensing(struct pahu_priv *pahu); + +/** + * pahu_set_spkr_gain_offset - offset the speaker path + * gain with the given offset value. + * + * @codec: codec instance + * @offset: Indicates speaker path gain offset value. + * + * Returns 0 on success or -EINVAL on error. + */ +int pahu_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset) +{ + struct pahu_priv *priv = snd_soc_codec_get_drvdata(codec); + + if (!priv) + return -EINVAL; + + priv->swr.spkr_gain_offset = offset; + return 0; +} +EXPORT_SYMBOL(pahu_set_spkr_gain_offset); + +/** + * pahu_set_spkr_mode - Configures speaker compander and smartboost + * settings based on speaker mode. + * + * @codec: codec instance + * @mode: Indicates speaker configuration mode. + * + * Returns 0 on success or -EINVAL on error. + */ +int pahu_set_spkr_mode(struct snd_soc_codec *codec, int mode) +{ + struct pahu_priv *priv = snd_soc_codec_get_drvdata(codec); + int i; + const struct pahu_reg_mask_val *regs; + int size; + + if (!priv) + return -EINVAL; + + switch (mode) { + case WCD9360_SPKR_MODE_1: + regs = pahu_spkr_mode1; + size = ARRAY_SIZE(pahu_spkr_mode1); + break; + default: + regs = pahu_spkr_default; + size = ARRAY_SIZE(pahu_spkr_default); + break; + } + + priv->swr.spkr_mode = mode; + for (i = 0; i < size; i++) + snd_soc_update_bits(codec, regs[i].reg, + regs[i].mask, regs[i].val); + return 0; +} +EXPORT_SYMBOL(pahu_set_spkr_mode); + +/** + * pahu_get_afe_config - returns specific codec configuration to afe to write + * + * @codec: codec instance + * @config_type: Indicates type of configuration to write. + */ +void *pahu_get_afe_config(struct snd_soc_codec *codec, + enum afe_config_type config_type) +{ + struct pahu_priv *priv = snd_soc_codec_get_drvdata(codec); + + switch (config_type) { + case AFE_SLIMBUS_SLAVE_CONFIG: + return &priv->slimbus_slave_cfg; + case AFE_CDC_REGISTERS_CONFIG: + return &pahu_audio_reg_cfg; + case AFE_SLIMBUS_SLAVE_PORT_CONFIG: + return &pahu_slimbus_slave_port_cfg; + case AFE_AANC_VERSION: + return &pahu_cdc_aanc_version; + case AFE_CDC_REGISTER_PAGE_CONFIG: + return &pahu_cdc_reg_page_cfg; + default: + dev_info(codec->dev, "%s: Unknown config_type 0x%x\n", + __func__, config_type); + return NULL; + } +} +EXPORT_SYMBOL(pahu_get_afe_config); + +static void pahu_vote_svs(struct pahu_priv *pahu, bool vote) +{ + struct wcd9xxx *wcd9xxx; + + wcd9xxx = pahu->wcd9xxx; + + mutex_lock(&pahu->svs_mutex); + if (vote) { + pahu->svs_ref_cnt++; + if (pahu->svs_ref_cnt == 1) + regmap_update_bits(wcd9xxx->regmap, + WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_0, + 0x01, 0x01); + } else { + /* Do not decrement ref count if it is already 0 */ + if (pahu->svs_ref_cnt == 0) + goto done; + + pahu->svs_ref_cnt--; + if (pahu->svs_ref_cnt == 0) + regmap_update_bits(wcd9xxx->regmap, + WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_0, + 0x01, 0x00); + } +done: + dev_dbg(pahu->dev, "%s: vote = %s, updated ref cnt = %u\n", __func__, + vote ? "vote" : "Unvote", pahu->svs_ref_cnt); + mutex_unlock(&pahu->svs_mutex); +} + +static int pahu_get_anc_slot(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = pahu->anc_slot; + return 0; +} + +static int pahu_put_anc_slot(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + pahu->anc_slot = ucontrol->value.integer.value[0]; + return 0; +} + +static int pahu_get_anc_func(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = (pahu->anc_func == true ? 1 : 0); + return 0; +} + +static int pahu_put_anc_func(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + + mutex_lock(&pahu->codec_mutex); + pahu->anc_func = (!ucontrol->value.integer.value[0] ? false : true); + dev_dbg(codec->dev, "%s: anc_func %x", __func__, pahu->anc_func); + + if (pahu->anc_func == true) { + snd_soc_dapm_enable_pin(dapm, "ANC EAR PA"); + snd_soc_dapm_enable_pin(dapm, "ANC EAR"); + snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA"); + snd_soc_dapm_disable_pin(dapm, "EAR PA"); + snd_soc_dapm_disable_pin(dapm, "EAR"); + } else { + snd_soc_dapm_disable_pin(dapm, "ANC EAR PA"); + snd_soc_dapm_disable_pin(dapm, "ANC EAR"); + snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA"); + snd_soc_dapm_enable_pin(dapm, "EAR PA"); + snd_soc_dapm_enable_pin(dapm, "EAR"); + } + mutex_unlock(&pahu->codec_mutex); + + snd_soc_dapm_sync(dapm); + return 0; +} + +static int pahu_codec_enable_anc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + const char *filename; + const struct firmware *fw; + int i; + int ret = 0; + int num_anc_slots; + struct wcd9xxx_anc_header *anc_head; + struct firmware_cal *hwdep_cal = NULL; + u32 anc_writes_size = 0; + int anc_size_remaining; + u32 *anc_ptr; + u16 reg; + u8 mask, val; + size_t cal_size; + const void *data; + + if (!pahu->anc_func) + return 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + hwdep_cal = wcdcal_get_fw_cal(pahu->fw_data, WCD9XXX_ANC_CAL); + if (hwdep_cal) { + data = hwdep_cal->data; + cal_size = hwdep_cal->size; + dev_dbg(codec->dev, "%s: using hwdep calibration, cal_size %zd", + __func__, cal_size); + } else { + filename = "wcd9360/WCD9360_anc.bin"; + ret = request_firmware(&fw, filename, codec->dev); + if (ret < 0) { + dev_err(codec->dev, "%s: Failed to acquire ANC data: %d\n", + __func__, ret); + return ret; + } + if (!fw) { + dev_err(codec->dev, "%s: Failed to get anc fw\n", + __func__); + return -ENODEV; + } + data = fw->data; + cal_size = fw->size; + dev_dbg(codec->dev, "%s: using request_firmware calibration\n", + __func__); + } + if (cal_size < sizeof(struct wcd9xxx_anc_header)) { + dev_err(codec->dev, "%s: Invalid cal_size %zd\n", + __func__, cal_size); + ret = -EINVAL; + goto err; + } + /* First number is the number of register writes */ + anc_head = (struct wcd9xxx_anc_header *)(data); + anc_ptr = (u32 *)(data + sizeof(struct wcd9xxx_anc_header)); + anc_size_remaining = cal_size - + sizeof(struct wcd9xxx_anc_header); + num_anc_slots = anc_head->num_anc_slots; + + if (pahu->anc_slot >= num_anc_slots) { + dev_err(codec->dev, "%s: Invalid ANC slot selected\n", + __func__); + ret = -EINVAL; + goto err; + } + for (i = 0; i < num_anc_slots; i++) { + if (anc_size_remaining < WCD9360_PACKED_REG_SIZE) { + dev_err(codec->dev, "%s: Invalid register format\n", + __func__); + ret = -EINVAL; + goto err; + } + anc_writes_size = (u32)(*anc_ptr); + anc_size_remaining -= sizeof(u32); + anc_ptr += 1; + + if ((anc_writes_size * WCD9360_PACKED_REG_SIZE) > + anc_size_remaining) { + dev_err(codec->dev, "%s: Invalid register format\n", + __func__); + ret = -EINVAL; + goto err; + } + + if (pahu->anc_slot == i) + break; + + anc_size_remaining -= (anc_writes_size * + WCD9360_PACKED_REG_SIZE); + anc_ptr += anc_writes_size; + } + if (i == num_anc_slots) { + dev_err(codec->dev, "%s: Selected ANC slot not present\n", + __func__); + ret = -EINVAL; + goto err; + } + + for (i = 0; i < anc_writes_size; i++) { + WCD9360_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val); + snd_soc_write(codec, reg, (val & mask)); + } + + if (!hwdep_cal) + release_firmware(fw); + break; + + case SND_SOC_DAPM_POST_PMU: + break; + + case SND_SOC_DAPM_POST_PMD: + if (!strcmp(w->name, "ANC EAR PA") || + !strcmp(w->name, "ANC SPK1 PA")) { + snd_soc_update_bits(codec, WCD9360_CDC_ANC0_MODE_1_CTL, + 0x30, 0x00); + msleep(50); + snd_soc_update_bits(codec, WCD9360_CDC_ANC0_MODE_1_CTL, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD9360_CDC_ANC0_CLK_RESET_CTL, + 0x38, 0x38); + snd_soc_update_bits(codec, + WCD9360_CDC_ANC0_CLK_RESET_CTL, + 0x07, 0x00); + snd_soc_update_bits(codec, + WCD9360_CDC_ANC0_CLK_RESET_CTL, + 0x38, 0x00); + } + break; + } + + return 0; +err: + if (!hwdep_cal) + release_firmware(fw); + return ret; +} + +static int pahu_get_clkmode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); + + if (test_bit(CLK_MODE, &pahu_p->status_mask)) + ucontrol->value.enumerated.item[0] = 1; + else + ucontrol->value.enumerated.item[0] = 0; + + dev_dbg(codec->dev, "%s: is_low_power_clock: %s\n", __func__, + test_bit(CLK_MODE, &pahu_p->status_mask) ? "true" : "false"); + + return 0; +} + +static int pahu_put_clkmode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); + + if (ucontrol->value.enumerated.item[0]) + set_bit(CLK_MODE, &pahu_p->status_mask); + else + clear_bit(CLK_MODE, &pahu_p->status_mask); + + dev_dbg(codec->dev, "%s: is_low_power_clock: %s\n", __func__, + test_bit(CLK_MODE, &pahu_p->status_mask) ? "true" : "false"); + + return 0; +} + +static int pahu_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = pahu_p->vi_feed_value; + + return 0; +} + +static int pahu_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); + struct soc_multi_mixer_control *mixer = + ((struct soc_multi_mixer_control *)kcontrol->private_value); + u32 dai_id = widget->shift; + u32 port_id = mixer->shift; + u32 enable = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: enable: %d, port_id:%d, dai_id: %d\n", + __func__, enable, port_id, dai_id); + + pahu_p->vi_feed_value = ucontrol->value.integer.value[0]; + + mutex_lock(&pahu_p->codec_mutex); + if (enable) { + if (port_id == WCD9360_TX14 && !test_bit(VI_SENSE_1, + &pahu_p->status_mask)) { + list_add_tail(&core->tx_chs[WCD9360_TX14].list, + &pahu_p->dai[dai_id].wcd9xxx_ch_list); + set_bit(VI_SENSE_1, &pahu_p->status_mask); + } + if (port_id == WCD9360_TX15 && !test_bit(VI_SENSE_2, + &pahu_p->status_mask)) { + list_add_tail(&core->tx_chs[WCD9360_TX15].list, + &pahu_p->dai[dai_id].wcd9xxx_ch_list); + set_bit(VI_SENSE_2, &pahu_p->status_mask); + } + } else { + if (port_id == WCD9360_TX14 && test_bit(VI_SENSE_1, + &pahu_p->status_mask)) { + list_del_init(&core->tx_chs[WCD9360_TX14].list); + clear_bit(VI_SENSE_1, &pahu_p->status_mask); + } + if (port_id == WCD9360_TX15 && test_bit(VI_SENSE_2, + &pahu_p->status_mask)) { + list_del_init(&core->tx_chs[WCD9360_TX15].list); + clear_bit(VI_SENSE_2, &pahu_p->status_mask); + } + } + mutex_unlock(&pahu_p->codec_mutex); + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL); + + return 0; +} + +static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = pahu_p->tx_port_value; + return 0; +} + +static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); + struct snd_soc_dapm_update *update = NULL; + struct soc_multi_mixer_control *mixer = + ((struct soc_multi_mixer_control *)kcontrol->private_value); + u32 dai_id = widget->shift; + u32 port_id = mixer->shift; + u32 enable = ucontrol->value.integer.value[0]; + u32 vtable; + + dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", + __func__, + widget->name, ucontrol->id.name, pahu_p->tx_port_value, + widget->shift, ucontrol->value.integer.value[0]); + + mutex_lock(&pahu_p->codec_mutex); + if (dai_id >= ARRAY_SIZE(vport_slim_check_table)) { + dev_err(codec->dev, "%s: dai_id: %d, out of bounds\n", + __func__, dai_id); + mutex_unlock(&pahu_p->codec_mutex); + return -EINVAL; + } + vtable = vport_slim_check_table[dai_id]; + + switch (dai_id) { + case AIF1_CAP: + case AIF2_CAP: + case AIF3_CAP: + /* only add to the list if value not set */ + if (enable && !(pahu_p->tx_port_value & 1 << port_id)) { + if (wcd9xxx_tx_vport_validation(vtable, port_id, + pahu_p->dai, NUM_CODEC_DAIS)) { + dev_dbg(codec->dev, "%s: TX%u is used by other virtual port\n", + __func__, port_id); + mutex_unlock(&pahu_p->codec_mutex); + return 0; + } + pahu_p->tx_port_value |= 1 << port_id; + list_add_tail(&core->tx_chs[port_id].list, + &pahu_p->dai[dai_id].wcd9xxx_ch_list); + } else if (!enable && (pahu_p->tx_port_value & + 1 << port_id)) { + pahu_p->tx_port_value &= ~(1 << port_id); + list_del_init(&core->tx_chs[port_id].list); + } else { + if (enable) + dev_dbg(codec->dev, "%s: TX%u port is used by\n" + "this virtual port\n", + __func__, port_id); + else + dev_dbg(codec->dev, "%s: TX%u port is not used by\n" + "this virtual port\n", + __func__, port_id); + /* avoid update power function */ + mutex_unlock(&pahu_p->codec_mutex); + return 0; + } + break; + case AIF4_MAD_TX: + break; + default: + dev_err(codec->dev, "Unknown AIF %d\n", dai_id); + mutex_unlock(&pahu_p->codec_mutex); + return -EINVAL; + } + dev_dbg(codec->dev, "%s: name %s sname %s updated value %u shift %d\n", + __func__, widget->name, widget->sname, pahu_p->tx_port_value, + widget->shift); + + mutex_unlock(&pahu_p->codec_mutex); + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update); + + return 0; +} + +static int slim_rx_mux_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = + pahu_p->rx_port_value[widget->shift]; + return 0; +} + +static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + unsigned int rx_port_value; + u32 port_id = widget->shift; + + pahu_p->rx_port_value[port_id] = ucontrol->value.enumerated.item[0]; + rx_port_value = pahu_p->rx_port_value[port_id]; + + mutex_lock(&pahu_p->codec_mutex); + dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", + __func__, widget->name, ucontrol->id.name, + rx_port_value, widget->shift, + ucontrol->value.integer.value[0]); + + /* value need to match the Virtual port and AIF number */ + switch (rx_port_value) { + case 0: + list_del_init(&core->rx_chs[port_id].list); + break; + case 1: + if (wcd9xxx_rx_vport_validation(port_id + + WCD9360_RX_PORT_START_NUMBER, + &pahu_p->dai[AIF1_PB].wcd9xxx_ch_list)) { + dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + __func__, port_id); + goto rtn; + } + list_add_tail(&core->rx_chs[port_id].list, + &pahu_p->dai[AIF1_PB].wcd9xxx_ch_list); + break; + case 2: + if (wcd9xxx_rx_vport_validation(port_id + + WCD9360_RX_PORT_START_NUMBER, + &pahu_p->dai[AIF2_PB].wcd9xxx_ch_list)) { + dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + __func__, port_id); + goto rtn; + } + list_add_tail(&core->rx_chs[port_id].list, + &pahu_p->dai[AIF2_PB].wcd9xxx_ch_list); + break; + case 3: + if (wcd9xxx_rx_vport_validation(port_id + + WCD9360_RX_PORT_START_NUMBER, + &pahu_p->dai[AIF3_PB].wcd9xxx_ch_list)) { + dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + __func__, port_id); + goto rtn; + } + list_add_tail(&core->rx_chs[port_id].list, + &pahu_p->dai[AIF3_PB].wcd9xxx_ch_list); + break; + case 4: + if (wcd9xxx_rx_vport_validation(port_id + + WCD9360_RX_PORT_START_NUMBER, + &pahu_p->dai[AIF4_PB].wcd9xxx_ch_list)) { + dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + __func__, port_id); + goto rtn; + } + list_add_tail(&core->rx_chs[port_id].list, + &pahu_p->dai[AIF4_PB].wcd9xxx_ch_list); + break; + default: + dev_err(codec->dev, "Unknown AIF %d\n", rx_port_value); + goto err; + } +rtn: + mutex_unlock(&pahu_p->codec_mutex); + snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, + rx_port_value, e, update); + + return 0; +err: + mutex_unlock(&pahu_p->codec_mutex); + return -EINVAL; +} + +static void pahu_codec_enable_slim_port_intr( + struct wcd9xxx_codec_dai_data *dai, + struct snd_soc_codec *codec) +{ + struct wcd9xxx_ch *ch; + int port_num = 0; + unsigned short reg = 0; + u8 val = 0; + struct pahu_priv *pahu_p; + + if (!dai || !codec) { + pr_err("%s: Invalid params\n", __func__); + return; + } + + pahu_p = snd_soc_codec_get_drvdata(codec); + list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) { + if (ch->port >= WCD9360_RX_PORT_START_NUMBER) { + port_num = ch->port - WCD9360_RX_PORT_START_NUMBER; + reg = WCD9360_SLIM_PGD_PORT_INT_RX_EN0 + (port_num / 8); + val = wcd9xxx_interface_reg_read(pahu_p->wcd9xxx, + reg); + if (!(val & BYTE_BIT_MASK(port_num))) { + val |= BYTE_BIT_MASK(port_num); + wcd9xxx_interface_reg_write( + pahu_p->wcd9xxx, reg, val); + val = wcd9xxx_interface_reg_read( + pahu_p->wcd9xxx, reg); + } + } else { + port_num = ch->port; + reg = WCD9360_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8); + val = wcd9xxx_interface_reg_read(pahu_p->wcd9xxx, + reg); + if (!(val & BYTE_BIT_MASK(port_num))) { + val |= BYTE_BIT_MASK(port_num); + wcd9xxx_interface_reg_write(pahu_p->wcd9xxx, + reg, val); + val = wcd9xxx_interface_reg_read( + pahu_p->wcd9xxx, reg); + } + } + } +} + +static int pahu_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai, + bool up) +{ + int ret = 0; + struct wcd9xxx_ch *ch; + + if (up) { + list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) { + ret = wcd9xxx_get_slave_port(ch->ch_num); + if (ret < 0) { + pr_err("%s: Invalid slave port ID: %d\n", + __func__, ret); + ret = -EINVAL; + } else { + set_bit(ret, &dai->ch_mask); + } + } + } else { + ret = wait_event_timeout(dai->dai_wait, (dai->ch_mask == 0), + msecs_to_jiffies( + WCD9360_SLIM_CLOSE_TIMEOUT)); + if (!ret) { + pr_err("%s: Slim close tx/rx wait timeout, ch_mask:0x%lx\n", + __func__, dai->ch_mask); + ret = -ETIMEDOUT; + } else { + ret = 0; + } + } + return ret; +} + +static int pahu_codec_enable_slimrx(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct wcd9xxx *core; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); + int ret = 0; + struct wcd9xxx_codec_dai_data *dai; + + core = dev_get_drvdata(codec->dev->parent); + + dev_dbg(codec->dev, "%s: event called! codec name %s num_dai %d\n" + "stream name %s event %d\n", + __func__, codec->component.name, + codec->component.num_dai, w->sname, event); + + dai = &pahu_p->dai[w->shift]; + dev_dbg(codec->dev, "%s: w->name %s w->shift %d event %d\n", + __func__, w->name, w->shift, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + dai->bus_down_in_recovery = false; + pahu_codec_enable_slim_port_intr(dai, codec); + (void) pahu_codec_enable_slim_chmask(dai, true); + ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list, + dai->rate, dai->bit_width, + &dai->grph); + break; + case SND_SOC_DAPM_POST_PMD: + ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list, + dai->grph); + dev_dbg(codec->dev, "%s: Disconnect RX port, ret = %d\n", + __func__, ret); + + if (!dai->bus_down_in_recovery) + ret = pahu_codec_enable_slim_chmask(dai, false); + else + dev_dbg(codec->dev, + "%s: bus in recovery skip enable slim_chmask", + __func__); + ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list, + dai->grph); + break; + } + return ret; +} + +static int pahu_codec_enable_slimtx(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx_codec_dai_data *dai; + struct wcd9xxx *core; + int ret = 0; + + dev_dbg(codec->dev, + "%s: w->name %s, w->shift = %d, num_dai %d stream name %s\n", + __func__, w->name, w->shift, + codec->component.num_dai, w->sname); + + dai = &pahu_p->dai[w->shift]; + core = dev_get_drvdata(codec->dev->parent); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + dai->bus_down_in_recovery = false; + pahu_codec_enable_slim_port_intr(dai, codec); + (void) pahu_codec_enable_slim_chmask(dai, true); + ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list, + dai->rate, dai->bit_width, + &dai->grph); + break; + case SND_SOC_DAPM_POST_PMD: + ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list, + dai->grph); + if (!dai->bus_down_in_recovery) + ret = pahu_codec_enable_slim_chmask(dai, false); + if (ret < 0) { + ret = wcd9xxx_disconnect_port(core, + &dai->wcd9xxx_ch_list, + dai->grph); + dev_dbg(codec->dev, "%s: Disconnect RX port, ret = %d\n", + __func__, ret); + } + break; + } + return ret; +} + +static int pahu_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct wcd9xxx *core = NULL; + struct snd_soc_codec *codec = NULL; + struct pahu_priv *pahu_p = NULL; + int ret = 0; + struct wcd9xxx_codec_dai_data *dai = NULL; + + codec = snd_soc_dapm_to_codec(w->dapm); + pahu_p = snd_soc_codec_get_drvdata(codec); + core = dev_get_drvdata(codec->dev->parent); + + dev_dbg(codec->dev, + "%s: num_dai %d stream name %s w->name %s event %d shift %d\n", + __func__, codec->component.num_dai, w->sname, + w->name, event, w->shift); + + if (w->shift != AIF4_VIFEED) { + pr_err("%s Error in enabling the tx path\n", __func__); + ret = -EINVAL; + goto done; + } + dai = &pahu_p->dai[w->shift]; + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (test_bit(VI_SENSE_1, &pahu_p->status_mask)) { + dev_dbg(codec->dev, "%s: spkr1 enabled\n", __func__); + /* Enable V&I sensing */ + snd_soc_update_bits(codec, + WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); + snd_soc_update_bits(codec, + WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x0F, 0x00); + snd_soc_update_bits(codec, + WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x0F, + 0x00); + snd_soc_update_bits(codec, + WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x10); + snd_soc_update_bits(codec, + WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10, + 0x10); + snd_soc_update_bits(codec, + WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x00); + snd_soc_update_bits(codec, + WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, + 0x00); + } + if (test_bit(VI_SENSE_2, &pahu_p->status_mask)) { + pr_debug("%s: spkr2 enabled\n", __func__); + /* Enable V&I sensing */ + snd_soc_update_bits(codec, + WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x0F, + 0x00); + snd_soc_update_bits(codec, + WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x0F, + 0x00); + snd_soc_update_bits(codec, + WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10, + 0x10); + snd_soc_update_bits(codec, + WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10, + 0x10); + snd_soc_update_bits(codec, + WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, + 0x00); + snd_soc_update_bits(codec, + WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, + 0x00); + } + dai->bus_down_in_recovery = false; + pahu_codec_enable_slim_port_intr(dai, codec); + (void) pahu_codec_enable_slim_chmask(dai, true); + ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list, + dai->rate, dai->bit_width, + &dai->grph); + break; + case SND_SOC_DAPM_POST_PMD: + ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list, + dai->grph); + if (ret) + dev_err(codec->dev, "%s error in close_slim_sch_tx %d\n", + __func__, ret); + if (!dai->bus_down_in_recovery) + ret = pahu_codec_enable_slim_chmask(dai, false); + if (ret < 0) { + ret = wcd9xxx_disconnect_port(core, + &dai->wcd9xxx_ch_list, + dai->grph); + dev_dbg(codec->dev, "%s: Disconnect TX port, ret = %d\n", + __func__, ret); + } + if (test_bit(VI_SENSE_1, &pahu_p->status_mask)) { + /* Disable V&I sensing */ + dev_dbg(codec->dev, "%s: spkr1 disabled\n", __func__); + snd_soc_update_bits(codec, + WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); + snd_soc_update_bits(codec, + WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x00); + snd_soc_update_bits(codec, + WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10, + 0x00); + } + if (test_bit(VI_SENSE_2, &pahu_p->status_mask)) { + /* Disable V&I sensing */ + dev_dbg(codec->dev, "%s: spkr2 disabled\n", __func__); + snd_soc_update_bits(codec, + WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_update_bits(codec, + WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10, + 0x00); + snd_soc_update_bits(codec, + WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10, + 0x00); + } + break; + } +done: + return ret; +} + +static int pahu_codec_enable_ldo_rxtx(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + pahu->ldo_rxtx_cnt++; + if (pahu->ldo_rxtx_cnt == 1) { + /* Enable VDD_LDO_RxTx regulator */ + msm_cdc_enable_ondemand_supply(pahu->wcd9xxx->dev, + pahu->wcd9xxx->supplies, + pdata->regulator, + pdata->num_supplies, + WCD9360_LDO_RXTX_SUPPLY_NAME); + + snd_soc_update_bits(codec, WCD9360_LDORXTX_LDORXTX, + 0x80, 0x80); + } + break; + case SND_SOC_DAPM_POST_PMD: + pahu->ldo_rxtx_cnt--; + if (pahu->ldo_rxtx_cnt < 0) + pahu->ldo_rxtx_cnt = 0; + + if (!pahu->ldo_rxtx_cnt) { + snd_soc_update_bits(codec, WCD9360_LDORXTX_LDORXTX, + 0x80, 0x00); + /* Disable VDD_LDO_RxTx regulator */ + msm_cdc_disable_ondemand_supply(pahu->wcd9xxx->dev, + pahu->wcd9xxx->supplies, + pdata->regulator, + pdata->num_supplies, + WCD9360_LDO_RXTX_SUPPLY_NAME); + } + break; + }; + dev_dbg(codec->dev, "%s: Current LDO RXTX user count: %d\n", __func__, + pahu->ldo_rxtx_cnt); + + return 0; +} + +static void pahu_spk_anc_update_callback(struct work_struct *work) +{ + struct spk_anc_work *spk_anc_dwork; + struct pahu_priv *pahu; + struct delayed_work *delayed_work; + struct snd_soc_codec *codec; + + delayed_work = to_delayed_work(work); + spk_anc_dwork = container_of(delayed_work, struct spk_anc_work, dwork); + pahu = spk_anc_dwork->pahu; + codec = pahu->codec; + + snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_CFG0, 0x10, 0x10); +} + +static int pahu_codec_enable_spkr_anc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + int ret = 0; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + if (!pahu->anc_func) + return 0; + + dev_dbg(codec->dev, "%s: w: %s event: %d anc: %d\n", __func__, + w->name, event, pahu->anc_func); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = pahu_codec_enable_anc(w, kcontrol, event); + schedule_delayed_work(&pahu->spk_anc_dwork.dwork, + msecs_to_jiffies(spk_anc_en_delay)); + break; + case SND_SOC_DAPM_POST_PMD: + cancel_delayed_work_sync(&pahu->spk_anc_dwork.dwork); + snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_CFG0, + 0x10, 0x00); + ret = pahu_codec_enable_anc(w, kcontrol, event); + break; + } + return ret; +} + +static int pahu_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + int ret = 0; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* + * 5ms sleep is required after PA is enabled as per + * HW requirement + */ + usleep_range(5000, 5500); + snd_soc_update_bits(codec, WCD9360_CDC_RX9_RX_PATH_CTL, + 0x10, 0x00); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, WCD9360_CDC_RX9_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + WCD9360_CDC_RX9_RX_PATH_MIX_CTL, + 0x10, 0x00); + break; + default: + break; + }; + + return ret; +} + +static int pahu_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + int ret = 0; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* + * 5ms sleep is required after PA is enabled as per + * HW requirement + */ + usleep_range(5000, 5500); + snd_soc_update_bits(codec, WCD9360_CDC_RX0_RX_PATH_CTL, + 0x10, 0x00); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, WCD9360_CDC_RX0_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + WCD9360_CDC_RX0_RX_PATH_MIX_CTL, + 0x10, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + /* + * 5ms sleep is required after PA is disabled as per + * HW requirement + */ + usleep_range(5000, 5500); + + if (!(strcmp(w->name, "ANC EAR PA"))) { + ret = pahu_codec_enable_anc(w, kcontrol, event); + snd_soc_update_bits(codec, WCD9360_CDC_RX0_RX_PATH_CFG0, + 0x10, 0x00); + } + break; + }; + + return ret; +} + +static int pahu_codec_ear_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + int ret = 0; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (pahu->anc_func) { + ret = pahu_codec_enable_anc(w, kcontrol, event); + snd_soc_update_bits(codec, WCD9360_CDC_RX0_RX_PATH_CFG0, + 0x10, 0x10); + } + break; + default: + break; + }; + + return ret; +} + +static int pahu_codec_spk_boost_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 boost_path_ctl, boost_path_cfg1; + u16 reg, reg_mix; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + if (!strcmp(w->name, "RX INT7 CHAIN")) { + boost_path_ctl = WCD9360_CDC_BOOST0_BOOST_PATH_CTL; + boost_path_cfg1 = WCD9360_CDC_RX7_RX_PATH_CFG1; + reg = WCD9360_CDC_RX7_RX_PATH_CTL; + reg_mix = WCD9360_CDC_RX7_RX_PATH_MIX_CTL; + } else if (!strcmp(w->name, "RX INT8 CHAIN")) { + boost_path_ctl = WCD9360_CDC_BOOST1_BOOST_PATH_CTL; + boost_path_cfg1 = WCD9360_CDC_RX8_RX_PATH_CFG1; + reg = WCD9360_CDC_RX8_RX_PATH_CTL; + reg_mix = WCD9360_CDC_RX8_RX_PATH_MIX_CTL; + } else { + dev_err(codec->dev, "%s: unknown widget: %s\n", + __func__, w->name); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x01); + snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x10); + snd_soc_update_bits(codec, reg, 0x10, 0x00); + if ((snd_soc_read(codec, reg_mix)) & 0x10) + snd_soc_update_bits(codec, reg_mix, 0x10, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x00); + snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x00); + break; + }; + + return 0; +} + +static int __pahu_codec_enable_swr(struct snd_soc_dapm_widget *w, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct pahu_priv *pahu; + int ch_cnt = 0; + + pahu = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) || + (strnstr(w->name, "INT7 MIX2", + sizeof("RX INT7 MIX2"))))) + pahu->swr.rx_7_count++; + if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) && + !pahu->swr.rx_8_count) + pahu->swr.rx_8_count++; + ch_cnt = !!(pahu->swr.rx_7_count) + pahu->swr.rx_8_count; + + swrm_wcd_notify(pahu->swr.ctrl_data[0].swr_pdev, + SWR_DEVICE_UP, NULL); + swrm_wcd_notify(pahu->swr.ctrl_data[0].swr_pdev, + SWR_SET_NUM_RX_CH, &ch_cnt); + break; + case SND_SOC_DAPM_POST_PMD: + if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) || + (strnstr(w->name, "INT7 MIX2", + sizeof("RX INT7 MIX2")))) + pahu->swr.rx_7_count--; + if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) && + pahu->swr.rx_8_count) + pahu->swr.rx_8_count--; + ch_cnt = !!(pahu->swr.rx_7_count) + pahu->swr.rx_8_count; + + swrm_wcd_notify(pahu->swr.ctrl_data[0].swr_pdev, + SWR_SET_NUM_RX_CH, &ch_cnt); + + break; + } + dev_dbg(pahu->dev, "%s: %s: current swr ch cnt: %d\n", + __func__, w->name, ch_cnt); + + return 0; +} + +static int pahu_codec_enable_swr(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + return __pahu_codec_enable_swr(w, event); +} + +static int pahu_codec_config_mad(struct snd_soc_codec *codec) +{ + int ret = 0; + int idx; + const struct firmware *fw; + struct firmware_cal *hwdep_cal = NULL; + struct wcd_mad_audio_cal *mad_cal = NULL; + const void *data; + const char *filename = WCD9360_MAD_AUDIO_FIRMWARE_PATH; + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + size_t cal_size; + + hwdep_cal = wcdcal_get_fw_cal(pahu->fw_data, WCD9XXX_MAD_CAL); + if (hwdep_cal) { + data = hwdep_cal->data; + cal_size = hwdep_cal->size; + dev_dbg(codec->dev, "%s: using hwdep calibration\n", + __func__); + } else { + ret = request_firmware(&fw, filename, codec->dev); + if (ret || !fw) { + dev_err(codec->dev, + "%s: MAD firmware acquire failed, err = %d\n", + __func__, ret); + return -ENODEV; + } + data = fw->data; + cal_size = fw->size; + dev_dbg(codec->dev, "%s: using request_firmware calibration\n", + __func__); + } + + if (cal_size < sizeof(*mad_cal)) { + dev_err(codec->dev, + "%s: Incorrect size %zd for MAD Cal, expected %zd\n", + __func__, cal_size, sizeof(*mad_cal)); + ret = -ENOMEM; + goto done; + } + + mad_cal = (struct wcd_mad_audio_cal *) (data); + if (!mad_cal) { + dev_err(codec->dev, + "%s: Invalid calibration data\n", + __func__); + ret = -EINVAL; + goto done; + } + + snd_soc_write(codec, WCD9360_SOC_MAD_MAIN_CTL_2, + mad_cal->microphone_info.cycle_time); + snd_soc_update_bits(codec, WCD9360_SOC_MAD_MAIN_CTL_1, 0xFF << 3, + ((uint16_t)mad_cal->microphone_info.settle_time) + << 3); + + /* Audio */ + snd_soc_write(codec, WCD9360_SOC_MAD_AUDIO_CTL_8, + mad_cal->audio_info.rms_omit_samples); + snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_CTL_1, + 0x07 << 4, mad_cal->audio_info.rms_comp_time << 4); + snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_CTL_2, 0x03 << 2, + mad_cal->audio_info.detection_mechanism << 2); + snd_soc_write(codec, WCD9360_SOC_MAD_AUDIO_CTL_7, + mad_cal->audio_info.rms_diff_threshold & 0x3F); + snd_soc_write(codec, WCD9360_SOC_MAD_AUDIO_CTL_5, + mad_cal->audio_info.rms_threshold_lsb); + snd_soc_write(codec, WCD9360_SOC_MAD_AUDIO_CTL_6, + mad_cal->audio_info.rms_threshold_msb); + + for (idx = 0; idx < ARRAY_SIZE(mad_cal->audio_info.iir_coefficients); + idx++) { + snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_IIR_CTL_PTR, + 0x3F, idx); + snd_soc_write(codec, WCD9360_SOC_MAD_AUDIO_IIR_CTL_VAL, + mad_cal->audio_info.iir_coefficients[idx]); + dev_dbg(codec->dev, "%s:MAD Audio IIR Coef[%d] = 0X%x", + __func__, idx, + mad_cal->audio_info.iir_coefficients[idx]); + } + + /* Beacon */ + snd_soc_write(codec, WCD9360_SOC_MAD_BEACON_CTL_8, + mad_cal->beacon_info.rms_omit_samples); + snd_soc_update_bits(codec, WCD9360_SOC_MAD_BEACON_CTL_1, + 0x07 << 4, mad_cal->beacon_info.rms_comp_time << 4); + snd_soc_update_bits(codec, WCD9360_SOC_MAD_BEACON_CTL_2, 0x03 << 2, + mad_cal->beacon_info.detection_mechanism << 2); + snd_soc_write(codec, WCD9360_SOC_MAD_BEACON_CTL_7, + mad_cal->beacon_info.rms_diff_threshold & 0x1F); + snd_soc_write(codec, WCD9360_SOC_MAD_BEACON_CTL_5, + mad_cal->beacon_info.rms_threshold_lsb); + snd_soc_write(codec, WCD9360_SOC_MAD_BEACON_CTL_6, + mad_cal->beacon_info.rms_threshold_msb); + + for (idx = 0; idx < ARRAY_SIZE(mad_cal->beacon_info.iir_coefficients); + idx++) { + snd_soc_update_bits(codec, WCD9360_SOC_MAD_BEACON_IIR_CTL_PTR, + 0x3F, idx); + snd_soc_write(codec, WCD9360_SOC_MAD_BEACON_IIR_CTL_VAL, + mad_cal->beacon_info.iir_coefficients[idx]); + dev_dbg(codec->dev, "%s:MAD Beacon IIR Coef[%d] = 0X%x", + __func__, idx, + mad_cal->beacon_info.iir_coefficients[idx]); + } + + /* Ultrasound */ + snd_soc_update_bits(codec, WCD9360_SOC_MAD_ULTR_CTL_1, + 0x07 << 4, + mad_cal->ultrasound_info.rms_comp_time << 4); + snd_soc_update_bits(codec, WCD9360_SOC_MAD_ULTR_CTL_2, 0x03 << 2, + mad_cal->ultrasound_info.detection_mechanism << 2); + snd_soc_write(codec, WCD9360_SOC_MAD_ULTR_CTL_7, + mad_cal->ultrasound_info.rms_diff_threshold & 0x1F); + snd_soc_write(codec, WCD9360_SOC_MAD_ULTR_CTL_5, + mad_cal->ultrasound_info.rms_threshold_lsb); + snd_soc_write(codec, WCD9360_SOC_MAD_ULTR_CTL_6, + mad_cal->ultrasound_info.rms_threshold_msb); + +done: + if (!hwdep_cal) + release_firmware(fw); + + return ret; +} + +static int __pahu_codec_enable_mad(struct snd_soc_codec *codec, bool enable) +{ + int rc = 0; + + /* Return if CPE INPUT is DEC1 */ + if (snd_soc_read(codec, WCD9360_CPE_SS_SVA_CFG) & 0x04) { + dev_dbg(codec->dev, "%s: MAD is bypassed, skip mad %s\n", + __func__, enable ? "enable" : "disable"); + return rc; + } + + dev_dbg(codec->dev, "%s: enable = %s\n", __func__, + enable ? "enable" : "disable"); + + if (enable) { + snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_CTL_2, + 0x03, 0x03); + rc = pahu_codec_config_mad(codec); + if (rc < 0) { + snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_CTL_2, + 0x03, 0x00); + goto done; + } + + /* Turn on MAD clk */ + snd_soc_update_bits(codec, WCD9360_CPE_SS_MAD_CTL, + 0x01, 0x01); + + /* Undo reset for MAD */ + snd_soc_update_bits(codec, WCD9360_CPE_SS_MAD_CTL, + 0x02, 0x00); + snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_MCLK_CFG, + 0x04, 0x04); + } else { + snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_CTL_2, + 0x03, 0x00); + /* Reset the MAD block */ + snd_soc_update_bits(codec, WCD9360_CPE_SS_MAD_CTL, + 0x02, 0x02); + /* Turn off MAD clk */ + snd_soc_update_bits(codec, WCD9360_CPE_SS_MAD_CTL, + 0x01, 0x00); + snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_MCLK_CFG, + 0x04, 0x00); + } +done: + return rc; +} + +static int pahu_codec_ape_enable_mad(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + int rc = 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WCD9360_CPE_SS_SVA_CFG, 0x40, 0x40); + rc = __pahu_codec_enable_mad(codec, true); + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_update_bits(codec, WCD9360_CPE_SS_SVA_CFG, 0x40, 0x00); + __pahu_codec_enable_mad(codec, false); + break; + } + + dev_dbg(pahu->dev, "%s: event = %d\n", __func__, event); + return rc; +} + +static int pahu_codec_cpe_mad_ctl(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + int rc = 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + pahu->mad_switch_cnt++; + if (pahu->mad_switch_cnt != 1) + goto done; + + snd_soc_update_bits(codec, WCD9360_CPE_SS_SVA_CFG, 0x20, 0x20); + rc = __pahu_codec_enable_mad(codec, true); + if (rc < 0) { + pahu->mad_switch_cnt--; + goto done; + } + + break; + case SND_SOC_DAPM_PRE_PMD: + pahu->mad_switch_cnt--; + if (pahu->mad_switch_cnt != 0) + goto done; + + snd_soc_update_bits(codec, WCD9360_CPE_SS_SVA_CFG, 0x20, 0x00); + __pahu_codec_enable_mad(codec, false); + break; + } +done: + dev_dbg(pahu->dev, "%s: event = %d, mad_switch_cnt = %d\n", + __func__, event, pahu->mad_switch_cnt); + return rc; +} + +static int pahu_get_asrc_mode(struct pahu_priv *pahu, int asrc, + u8 main_sr, u8 mix_sr) +{ + u8 asrc_output_mode; + int asrc_mode = CONV_88P2K_TO_384K; + + if ((asrc < 0) || (asrc >= ASRC_MAX)) + return 0; + + asrc_output_mode = pahu->asrc_output_mode[asrc]; + + if (asrc_output_mode) { + /* + * If Mix sample rate is < 96KHz, use 96K to 352.8K + * conversion, or else use 384K to 352.8K conversion + */ + if (mix_sr < 5) + asrc_mode = CONV_96K_TO_352P8K; + else + asrc_mode = CONV_384K_TO_352P8K; + } else { + /* Integer main and Fractional mix path */ + if (main_sr < 8 && mix_sr > 9) { + asrc_mode = CONV_352P8K_TO_384K; + } else if (main_sr > 8 && mix_sr < 8) { + /* Fractional main and Integer mix path */ + if (mix_sr < 5) + asrc_mode = CONV_96K_TO_352P8K; + else + asrc_mode = CONV_384K_TO_352P8K; + } else if (main_sr < 8 && mix_sr < 8) { + /* Integer main and Integer mix path */ + asrc_mode = CONV_96K_TO_384K; + } + } + + return asrc_mode; +} + +static int pahu_codec_wdma3_ctl(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Fix to 16KHz */ + snd_soc_update_bits(codec, WCD9360_DMA_WDMA_CTL_3, + 0xF0, 0x10); + /* Select mclk_1 */ + snd_soc_update_bits(codec, WCD9360_DMA_WDMA_CTL_3, + 0x02, 0x00); + /* Enable DMA */ + snd_soc_update_bits(codec, WCD9360_DMA_WDMA_CTL_3, + 0x01, 0x01); + break; + + case SND_SOC_DAPM_POST_PMD: + /* Disable DMA */ + snd_soc_update_bits(codec, WCD9360_DMA_WDMA_CTL_3, + 0x01, 0x00); + break; + + }; + + return 0; +} +static int pahu_codec_enable_asrc(struct snd_soc_codec *codec, + int asrc_in, int event) +{ + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + u16 cfg_reg, ctl_reg, clk_reg, asrc_ctl, mix_ctl_reg, paired_reg; + int asrc, ret = 0; + u8 main_sr, mix_sr, asrc_mode = 0; + + switch (asrc_in) { + case ASRC_IN_SPKR1: + cfg_reg = WCD9360_CDC_RX7_RX_PATH_CFG0; + ctl_reg = WCD9360_CDC_RX7_RX_PATH_CTL; + clk_reg = WCD9360_MIXING_ASRC2_CLK_RST_CTL; + paired_reg = WCD9360_MIXING_ASRC2_CLK_RST_CTL; + asrc_ctl = WCD9360_MIXING_ASRC2_CTL1; + asrc = ASRC2; + break; + case ASRC_IN_SPKR2: + cfg_reg = WCD9360_CDC_RX8_RX_PATH_CFG0; + ctl_reg = WCD9360_CDC_RX8_RX_PATH_CTL; + clk_reg = WCD9360_MIXING_ASRC3_CLK_RST_CTL; + paired_reg = WCD9360_MIXING_ASRC3_CLK_RST_CTL; + asrc_ctl = WCD9360_MIXING_ASRC3_CTL1; + asrc = ASRC3; + break; + default: + dev_err(codec->dev, "%s: Invalid asrc input :%d\n", __func__, + asrc_in); + ret = -EINVAL; + goto done; + }; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (pahu->asrc_users[asrc] == 0) { + if ((snd_soc_read(codec, clk_reg) & 0x02) || + (snd_soc_read(codec, paired_reg) & 0x02)) { + snd_soc_update_bits(codec, clk_reg, + 0x02, 0x00); + snd_soc_update_bits(codec, paired_reg, + 0x02, 0x00); + } + snd_soc_update_bits(codec, cfg_reg, 0x80, 0x80); + snd_soc_update_bits(codec, clk_reg, 0x01, 0x01); + main_sr = snd_soc_read(codec, ctl_reg) & 0x0F; + mix_ctl_reg = ctl_reg + 5; + mix_sr = snd_soc_read(codec, mix_ctl_reg) & 0x0F; + asrc_mode = pahu_get_asrc_mode(pahu, asrc, + main_sr, mix_sr); + dev_dbg(codec->dev, "%s: main_sr:%d mix_sr:%d asrc_mode %d\n", + __func__, main_sr, mix_sr, asrc_mode); + snd_soc_update_bits(codec, asrc_ctl, 0x07, asrc_mode); + } + pahu->asrc_users[asrc]++; + break; + case SND_SOC_DAPM_POST_PMD: + pahu->asrc_users[asrc]--; + if (pahu->asrc_users[asrc] <= 0) { + pahu->asrc_users[asrc] = 0; + snd_soc_update_bits(codec, asrc_ctl, 0x07, 0x00); + snd_soc_update_bits(codec, cfg_reg, 0x80, 0x00); + snd_soc_update_bits(codec, clk_reg, 0x03, 0x02); + } + break; + }; + + dev_dbg(codec->dev, "%s: ASRC%d, users: %d\n", + __func__, asrc, pahu->asrc_users[asrc]); + +done: + return ret; +} + +static int pahu_codec_enable_asrc_resampler(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int ret = 0; + u8 cfg, asrc_in; + + cfg = snd_soc_read(codec, WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0); + if (!(cfg & 0xFF)) { + dev_err(codec->dev, "%s: ASRC%u input not selected\n", + __func__, w->shift); + return -EINVAL; + } + + switch (w->shift) { + case ASRC2: + asrc_in = ((cfg & 0x30) == 0x20) ? ASRC_IN_SPKR1 : ASRC_INVALID; + ret = pahu_codec_enable_asrc(codec, asrc_in, event); + break; + case ASRC3: + asrc_in = ((cfg & 0xC0) == 0x80) ? ASRC_IN_SPKR2 : ASRC_INVALID; + ret = pahu_codec_enable_asrc(codec, asrc_in, event); + break; + default: + dev_err(codec->dev, "%s: Invalid asrc:%u\n", __func__, + w->shift); + ret = -EINVAL; + break; + }; + + return ret; +} + +static int pahu_enable_native_supply(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (++pahu->native_clk_users == 1) { + snd_soc_update_bits(codec, WCD9360_CLK_SYS_PLL_ENABLES, + 0x01, 0x01); + usleep_range(100, 120); + snd_soc_update_bits(codec, WCD9360_CLK_SYS_MCLK2_PRG1, + 0x06, 0x02); + snd_soc_update_bits(codec, WCD9360_CLK_SYS_MCLK2_PRG1, + 0x01, 0x01); + snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_GATE, + 0x04, 0x00); + /* Add sleep as per HW register sequence */ + usleep_range(30, 50); + snd_soc_update_bits(codec, + WCD9360_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x02, 0x02); + snd_soc_update_bits(codec, + WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x10, 0x10); + } + break; + case SND_SOC_DAPM_PRE_PMD: + if (pahu->native_clk_users && + (--pahu->native_clk_users == 0)) { + snd_soc_update_bits(codec, + WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x10, 0x00); + snd_soc_update_bits(codec, + WCD9360_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x02, 0x00); + snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_GATE, + 0x04, 0x04); + snd_soc_update_bits(codec, WCD9360_CLK_SYS_MCLK2_PRG1, + 0x01, 0x00); + snd_soc_update_bits(codec, WCD9360_CLK_SYS_MCLK2_PRG1, + 0x06, 0x00); + snd_soc_update_bits(codec, WCD9360_CLK_SYS_PLL_ENABLES, + 0x01, 0x00); + } + break; + } + + dev_dbg(codec->dev, "%s: native_clk_users: %d, event: %d\n", + __func__, pahu->native_clk_users, event); + + return 0; +} + +static int pahu_codec_config_ear_spkr_gain(struct snd_soc_codec *codec, + int event, int gain_reg) +{ + int comp_gain_offset, val; + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + switch (pahu->swr.spkr_mode) { + /* Compander gain in SPKR_MODE1 case is 12 dB */ + case WCD9360_SPKR_MODE_1: + comp_gain_offset = -12; + break; + /* Default case compander gain is 15 dB */ + default: + comp_gain_offset = -15; + break; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* Apply ear spkr gain only if compander is enabled */ + if (pahu->comp_enabled[COMPANDER_7] && + (gain_reg == WCD9360_CDC_RX7_RX_VOL_CTL || + gain_reg == WCD9360_CDC_RX7_RX_VOL_MIX_CTL) && + (pahu->ear_spkr_gain != 0)) { + /* For example, val is -8(-12+5-1) for 4dB of gain */ + val = comp_gain_offset + pahu->ear_spkr_gain - 1; + snd_soc_write(codec, gain_reg, val); + + dev_dbg(codec->dev, "%s: RX7 Volume %d dB\n", + __func__, val); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* + * Reset RX7 volume to 0 dB if compander is enabled and + * ear_spkr_gain is non-zero. + */ + if (pahu->comp_enabled[COMPANDER_7] && + (gain_reg == WCD9360_CDC_RX7_RX_VOL_CTL || + gain_reg == WCD9360_CDC_RX7_RX_VOL_MIX_CTL) && + (pahu->ear_spkr_gain != 0)) { + snd_soc_write(codec, gain_reg, 0x0); + + dev_dbg(codec->dev, "%s: Reset RX7 Volume to 0 dB\n", + __func__); + } + break; + } + + return 0; +} + +static int pahu_config_compander(struct snd_soc_codec *codec, int interp_n, + int event) +{ + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + int comp; + u16 comp_ctl0_reg, rx_path_cfg0_reg; + + /* HPH, LO are not valid and AUX does not have compander */ + if (((interp_n >= INTERP_HPHL_NA) && (interp_n <= INTERP_LO4_NA)) || + (interp_n == INTERP_AUX)) + return 0; + + comp = interp_n; + dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n", + __func__, event, comp, pahu->comp_enabled[comp]); + + if (!pahu->comp_enabled[comp]) + return 0; + + comp_ctl0_reg = WCD9360_CDC_COMPANDER0_CTL0 + (comp * 8); + rx_path_cfg0_reg = WCD9360_CDC_RX0_RX_PATH_CFG0 + (comp * 20); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Compander Clock */ + snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01); + /* Soft reset */ + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); + /* Compander enable */ + snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); + } + + return 0; +} + +/** + * pahu_codec_enable_interp_clk - Enable main path Interpolator + * clock. + * + * @codec: Codec instance + * @event: Indicates speaker path gain offset value + * @intp_idx: Interpolator index + * Returns number of main clock users + */ +int pahu_codec_enable_interp_clk(struct snd_soc_codec *codec, + int event, int interp_idx) +{ + struct pahu_priv *pahu; + u16 main_reg; + + if (!codec) { + pr_err("%s: codec is NULL\n", __func__); + return -EINVAL; + } + + pahu = snd_soc_codec_get_drvdata(codec); + + main_reg = WCD9360_CDC_RX0_RX_PATH_CTL + + (interp_idx * WCD9360_RX_PATH_CTL_OFFSET); + + if (interp_idx == INTERP_AUX) + main_reg = WCD9360_CDC_RX9_RX_PATH_CTL; + + if (SND_SOC_DAPM_EVENT_ON(event)) { + if (pahu->main_clk_users[interp_idx] == 0) { + /* Main path PGA mute enable */ + snd_soc_update_bits(codec, main_reg, 0x10, 0x10); + /* Clk enable */ + snd_soc_update_bits(codec, main_reg, 0x20, 0x20); + pahu_config_compander(codec, interp_idx, event); + } + pahu->main_clk_users[interp_idx]++; + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + pahu->main_clk_users[interp_idx]--; + if (pahu->main_clk_users[interp_idx] <= 0) { + pahu->main_clk_users[interp_idx] = 0; + pahu_config_compander(codec, interp_idx, event); + /* Clk Disable */ + snd_soc_update_bits(codec, main_reg, 0x20, 0x00); + /* Reset enable and disable */ + snd_soc_update_bits(codec, main_reg, 0x40, 0x40); + snd_soc_update_bits(codec, main_reg, 0x40, 0x00); + /* Reset rate to 48K*/ + snd_soc_update_bits(codec, main_reg, 0x0F, 0x04); + } + } + + dev_dbg(codec->dev, "%s event %d main_clk_users %d\n", + __func__, event, pahu->main_clk_users[interp_idx]); + + return pahu->main_clk_users[interp_idx]; +} +EXPORT_SYMBOL(pahu_codec_enable_interp_clk); + +static int pahu_codec_enable_mix_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + u16 gain_reg, mix_reg; + int offset_val = 0; + int val = 0; + + if (w->shift >= WCD9360_NUM_INTERPOLATORS || + ((w->shift >= INTERP_HPHL_NA) && (w->shift <= INTERP_LO4_NA))) { + dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", + __func__, w->shift, w->name); + return -EINVAL; + }; + + gain_reg = WCD9360_CDC_RX0_RX_VOL_MIX_CTL + + (w->shift * WCD9360_RX_PATH_CTL_OFFSET); + mix_reg = WCD9360_CDC_RX0_RX_PATH_MIX_CTL + + (w->shift * WCD9360_RX_PATH_CTL_OFFSET); + + if (w->shift == INTERP_AUX) { + gain_reg = WCD9360_CDC_RX9_RX_VOL_MIX_CTL; + mix_reg = WCD9360_CDC_RX9_RX_PATH_MIX_CTL; + } + + if (w->shift == INTERP_SPKR1 || w->shift == INTERP_SPKR2) + __pahu_codec_enable_swr(w, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + pahu_codec_enable_interp_clk(codec, event, w->shift); + /* Clk enable */ + snd_soc_update_bits(codec, mix_reg, 0x20, 0x20); + break; + case SND_SOC_DAPM_POST_PMU: + if ((pahu->swr.spkr_gain_offset == + WCD9360_RX_GAIN_OFFSET_M1P5_DB) && + (pahu->comp_enabled[COMPANDER_7] || + pahu->comp_enabled[COMPANDER_8]) && + (gain_reg == WCD9360_CDC_RX7_RX_VOL_MIX_CTL || + gain_reg == WCD9360_CDC_RX8_RX_VOL_MIX_CTL)) { + snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_update_bits(codec, + WCD9360_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x01); + snd_soc_update_bits(codec, WCD9360_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_update_bits(codec, + WCD9360_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x01); + offset_val = -2; + } + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + pahu_codec_config_ear_spkr_gain(codec, event, gain_reg); + break; + case SND_SOC_DAPM_POST_PMD: + /* Clk Disable */ + snd_soc_update_bits(codec, mix_reg, 0x20, 0x00); + pahu_codec_enable_interp_clk(codec, event, w->shift); + /* Reset enable and disable */ + snd_soc_update_bits(codec, mix_reg, 0x40, 0x40); + snd_soc_update_bits(codec, mix_reg, 0x40, 0x00); + + if ((pahu->swr.spkr_gain_offset == + WCD9360_RX_GAIN_OFFSET_M1P5_DB) && + (pahu->comp_enabled[COMPANDER_7] || + pahu->comp_enabled[COMPANDER_8]) && + (gain_reg == WCD9360_CDC_RX7_RX_VOL_MIX_CTL || + gain_reg == WCD9360_CDC_RX8_RX_VOL_MIX_CTL)) { + snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD9360_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x00); + snd_soc_update_bits(codec, WCD9360_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD9360_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x00); + offset_val = 2; + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + } + pahu_codec_config_ear_spkr_gain(codec, event, gain_reg); + break; + }; + dev_dbg(codec->dev, "%s event %d name %s\n", __func__, event, w->name); + + return 0; +} + +static int pahu_codec_enable_main_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + u16 gain_reg; + u16 reg; + int val; + int offset_val = 0; + + dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + + if (w->shift >= WCD9360_NUM_INTERPOLATORS || + ((w->shift >= INTERP_HPHL_NA) && (w->shift <= INTERP_LO4_NA))) { + dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", + __func__, w->shift, w->name); + return -EINVAL; + }; + + reg = WCD9360_CDC_RX0_RX_PATH_CTL + (w->shift * + WCD9360_RX_PATH_CTL_OFFSET); + gain_reg = WCD9360_CDC_RX0_RX_VOL_CTL + (w->shift * + WCD9360_RX_PATH_CTL_OFFSET); + + if (w->shift == INTERP_AUX) { + reg = WCD9360_CDC_RX9_RX_PATH_CTL; + gain_reg = WCD9360_CDC_RX9_RX_VOL_CTL; + } + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + pahu_codec_enable_interp_clk(codec, event, w->shift); + break; + case SND_SOC_DAPM_POST_PMU: + /* apply gain after int clk is enabled */ + if ((pahu->swr.spkr_gain_offset == + WCD9360_RX_GAIN_OFFSET_M1P5_DB) && + (pahu->comp_enabled[COMPANDER_7] || + pahu->comp_enabled[COMPANDER_8]) && + (gain_reg == WCD9360_CDC_RX7_RX_VOL_CTL || + gain_reg == WCD9360_CDC_RX8_RX_VOL_CTL)) { + snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_update_bits(codec, + WCD9360_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x01); + snd_soc_update_bits(codec, WCD9360_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_update_bits(codec, + WCD9360_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x01); + offset_val = -2; + } + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + pahu_codec_config_ear_spkr_gain(codec, event, gain_reg); + break; + case SND_SOC_DAPM_POST_PMD: + pahu_codec_enable_interp_clk(codec, event, w->shift); + + if ((pahu->swr.spkr_gain_offset == + WCD9360_RX_GAIN_OFFSET_M1P5_DB) && + (pahu->comp_enabled[COMPANDER_7] || + pahu->comp_enabled[COMPANDER_8]) && + (gain_reg == WCD9360_CDC_RX7_RX_VOL_CTL || + gain_reg == WCD9360_CDC_RX8_RX_VOL_CTL)) { + snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD9360_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x00); + snd_soc_update_bits(codec, WCD9360_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD9360_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x00); + offset_val = 2; + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + } + pahu_codec_config_ear_spkr_gain(codec, event, gain_reg); + break; + }; + + return 0; +} + +static int pahu_codec_set_iir_gain(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: /* fall through */ + case SND_SOC_DAPM_PRE_PMD: + if (strnstr(w->name, "IIR0", sizeof("IIR0"))) { + snd_soc_write(codec, + WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, + snd_soc_read(codec, + WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)); + snd_soc_write(codec, + WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, + snd_soc_read(codec, + WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)); + snd_soc_write(codec, + WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, + snd_soc_read(codec, + WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)); + snd_soc_write(codec, + WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, + snd_soc_read(codec, + WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)); + } + break; + } + return 0; +} + +static int pahu_codec_find_amic_input(struct snd_soc_codec *codec, + int adc_mux_n) +{ + u16 mask, shift, adc_mux_in_reg; + u16 amic_mux_sel_reg; + bool is_amic; + + if (adc_mux_n < 0 || adc_mux_n > WCD9360_MAX_VALID_ADC_MUX || + adc_mux_n == WCD9360_INVALID_ADC_MUX) + return 0; + + if (adc_mux_n < 3) { + adc_mux_in_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + + 2 * adc_mux_n; + mask = 0x03; + shift = 0; + amic_mux_sel_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + + 2 * adc_mux_n; + } else if (adc_mux_n < 4) { + adc_mux_in_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1; + mask = 0x03; + shift = 0; + amic_mux_sel_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + + 2 * adc_mux_n; + } else if (adc_mux_n < 7) { + adc_mux_in_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + + 2 * (adc_mux_n - 4); + mask = 0x0C; + shift = 2; + amic_mux_sel_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + + adc_mux_n - 4; + } else if (adc_mux_n < 8) { + adc_mux_in_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1; + mask = 0x0C; + shift = 2; + amic_mux_sel_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + + adc_mux_n - 4; + } else if (adc_mux_n < 12) { + adc_mux_in_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + + 2 * (((adc_mux_n == 8) ? (adc_mux_n - 8) : + (adc_mux_n - 9))); + mask = 0x30; + shift = 4; + amic_mux_sel_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0 + + ((adc_mux_n == 8) ? (adc_mux_n - 8) : + (adc_mux_n - 9)); + } + + is_amic = (((snd_soc_read(codec, adc_mux_in_reg) & mask) >> shift) + == 1); + if (!is_amic) + return 0; + + return snd_soc_read(codec, amic_mux_sel_reg) & 0x07; +} + +static void pahu_codec_set_tx_hold(struct snd_soc_codec *codec, + u16 amic_reg, bool set) +{ + u8 mask = 0x20; + u8 val; + + if (amic_reg == WCD9360_ANA_AMIC1 || + amic_reg == WCD9360_ANA_AMIC3) + mask = 0x40; + + val = set ? mask : 0x00; + + switch (amic_reg) { + case WCD9360_ANA_AMIC1: + case WCD9360_ANA_AMIC2: + snd_soc_update_bits(codec, WCD9360_ANA_AMIC2, mask, val); + break; + case WCD9360_ANA_AMIC3: + case WCD9360_ANA_AMIC4: + snd_soc_update_bits(codec, WCD9360_ANA_AMIC4, mask, val); + break; + default: + dev_dbg(codec->dev, "%s: invalid amic: %d\n", + __func__, amic_reg); + break; + } +} + +static int pahu_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + int adc_mux_n = w->shift; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int amic_n; + + dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + amic_n = pahu_codec_find_amic_input(codec, adc_mux_n); + break; + default: + break; + } + + return 0; +} + +static u16 pahu_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic) +{ + u16 pwr_level_reg = 0; + + switch (amic) { + case 1: + case 2: + pwr_level_reg = WCD9360_ANA_AMIC1; + break; + + case 3: + case 4: + pwr_level_reg = WCD9360_ANA_AMIC3; + break; + default: + dev_dbg(codec->dev, "%s: invalid amic: %d\n", + __func__, amic); + break; + } + + return pwr_level_reg; +} + +#define TX_HPF_CUT_OFF_FREQ_MASK 0x60 +#define CF_MIN_3DB_4HZ 0x0 +#define CF_MIN_3DB_75HZ 0x1 +#define CF_MIN_3DB_150HZ 0x2 + +static void pahu_tx_hpf_corner_freq_callback(struct work_struct *work) +{ + struct delayed_work *hpf_delayed_work; + struct hpf_work *hpf_work; + struct pahu_priv *pahu; + struct snd_soc_codec *codec; + u16 dec_cfg_reg, amic_reg, go_bit_reg; + u8 hpf_cut_off_freq; + int amic_n; + + hpf_delayed_work = to_delayed_work(work); + hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); + pahu = hpf_work->pahu; + codec = pahu->codec; + hpf_cut_off_freq = hpf_work->hpf_cut_off_freq; + + dec_cfg_reg = WCD9360_CDC_TX0_TX_PATH_CFG0 + 16 * hpf_work->decimator; + go_bit_reg = dec_cfg_reg + 7; + + dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", + __func__, hpf_work->decimator, hpf_cut_off_freq); + + amic_n = pahu_codec_find_amic_input(codec, hpf_work->decimator); + if (amic_n) { + amic_reg = WCD9360_ANA_AMIC1 + amic_n - 1; + pahu_codec_set_tx_hold(codec, amic_reg, false); + } + snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x02); + /* Minimum 1 clk cycle delay is required as per HW spec */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x00); +} + +static void pahu_tx_mute_update_callback(struct work_struct *work) +{ + struct tx_mute_work *tx_mute_dwork; + struct pahu_priv *pahu; + struct delayed_work *delayed_work; + struct snd_soc_codec *codec; + u16 tx_vol_ctl_reg; + + delayed_work = to_delayed_work(work); + tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); + pahu = tx_mute_dwork->pahu; + codec = pahu->codec; + + tx_vol_ctl_reg = WCD9360_CDC_TX0_TX_PATH_CTL + + 16 * tx_mute_dwork->decimator; + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); +} + +static int pahu_codec_enable_rx_path_clk(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 sidetone_reg; + + dev_dbg(codec->dev, "%s %d %d\n", __func__, event, w->shift); + sidetone_reg = WCD9360_CDC_RX0_RX_PATH_CFG1 + 0x14*(w->shift); + + if (w->shift == INTERP_AUX) + sidetone_reg = WCD9360_CDC_RX9_RX_PATH_CFG1; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (!strcmp(w->name, "RX INT7 MIX2 INP")) + __pahu_codec_enable_swr(w, event); + pahu_codec_enable_interp_clk(codec, event, w->shift); + snd_soc_update_bits(codec, sidetone_reg, 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, sidetone_reg, 0x10, 0x00); + pahu_codec_enable_interp_clk(codec, event, w->shift); + if (!strcmp(w->name, "RX INT7 MIX2 INP")) + __pahu_codec_enable_swr(w, event); + break; + default: + break; + }; + return 0; +} + +static int pahu_codec_enable_dec(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + unsigned int decimator; + char *dec_adc_mux_name = NULL; + char *widget_name = NULL; + char *wname; + int ret = 0, amic_n; + u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg; + u16 tx_gain_ctl_reg; + char *dec; + u8 hpf_cut_off_freq; + + dev_dbg(codec->dev, "%s %d\n", __func__, event); + + widget_name = kstrndup(w->name, 15, GFP_KERNEL); + if (!widget_name) + return -ENOMEM; + + wname = widget_name; + dec_adc_mux_name = strsep(&widget_name, " "); + if (!dec_adc_mux_name) { + dev_err(codec->dev, "%s: Invalid decimator = %s\n", + __func__, w->name); + ret = -EINVAL; + goto out; + } + dec_adc_mux_name = widget_name; + + dec = strpbrk(dec_adc_mux_name, "012345678"); + if (!dec) { + dev_err(codec->dev, "%s: decimator index not found\n", + __func__); + ret = -EINVAL; + goto out; + } + + ret = kstrtouint(dec, 10, &decimator); + if (ret < 0) { + dev_err(codec->dev, "%s: Invalid decimator = %s\n", + __func__, wname); + ret = -EINVAL; + goto out; + } + + dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__, + w->name, decimator); + + tx_vol_ctl_reg = WCD9360_CDC_TX0_TX_PATH_CTL + 16 * decimator; + hpf_gate_reg = WCD9360_CDC_TX0_TX_PATH_SEC2 + 16 * decimator; + dec_cfg_reg = WCD9360_CDC_TX0_TX_PATH_CFG0 + 16 * decimator; + tx_gain_ctl_reg = WCD9360_CDC_TX0_TX_VOL_CTL + 16 * decimator; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + amic_n = pahu_codec_find_amic_input(codec, decimator); + if (amic_n) + pwr_level_reg = pahu_codec_get_amic_pwlvl_reg(codec, + amic_n); + + if (pwr_level_reg) { + switch ((snd_soc_read(codec, pwr_level_reg) & + WCD9360_AMIC_PWR_LVL_MASK) >> + WCD9360_AMIC_PWR_LVL_SHIFT) { + case WCD9360_AMIC_PWR_LEVEL_LP: + snd_soc_update_bits(codec, dec_cfg_reg, + WCD9360_DEC_PWR_LVL_MASK, + WCD9360_DEC_PWR_LVL_LP); + break; + + case WCD9360_AMIC_PWR_LEVEL_HP: + snd_soc_update_bits(codec, dec_cfg_reg, + WCD9360_DEC_PWR_LVL_MASK, + WCD9360_DEC_PWR_LVL_HP); + break; + case WCD9360_AMIC_PWR_LEVEL_DEFAULT: + default: + snd_soc_update_bits(codec, dec_cfg_reg, + WCD9360_DEC_PWR_LVL_MASK, + WCD9360_DEC_PWR_LVL_DF); + break; + } + } + /* Enable TX PGA Mute */ + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMU: + hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) & + TX_HPF_CUT_OFF_FREQ_MASK) >> 5; + + pahu->tx_hpf_work[decimator].hpf_cut_off_freq = + hpf_cut_off_freq; + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { + snd_soc_update_bits(codec, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + CF_MIN_3DB_150HZ << 5); + snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); + /* + * Minimum 1 clk cycle delay is required as per + * HW spec. + */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00); + } + /* schedule work queue to Remove Mute */ + schedule_delayed_work(&pahu->tx_mute_dwork[decimator].dwork, + msecs_to_jiffies(tx_unmute_delay)); + if (pahu->tx_hpf_work[decimator].hpf_cut_off_freq != + CF_MIN_3DB_150HZ) + schedule_delayed_work( + &pahu->tx_hpf_work[decimator].dwork, + msecs_to_jiffies(300)); + /* apply gain after decimator is enabled */ + snd_soc_write(codec, tx_gain_ctl_reg, + snd_soc_read(codec, tx_gain_ctl_reg)); + break; + case SND_SOC_DAPM_PRE_PMD: + hpf_cut_off_freq = + pahu->tx_hpf_work[decimator].hpf_cut_off_freq; + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + if (cancel_delayed_work_sync( + &pahu->tx_hpf_work[decimator].dwork)) { + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { + snd_soc_update_bits(codec, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_update_bits(codec, hpf_gate_reg, + 0x02, 0x02); + /* + * Minimum 1 clk cycle delay is required as per + * HW spec. + */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, hpf_gate_reg, + 0x02, 0x00); + } + } + cancel_delayed_work_sync( + &pahu->tx_mute_dwork[decimator].dwork); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); + snd_soc_update_bits(codec, dec_cfg_reg, + WCD9360_DEC_PWR_LVL_MASK, + WCD9360_DEC_PWR_LVL_DF); + break; + }; +out: + kfree(wname); + return ret; +} + +static u32 pahu_get_dmic_sample_rate(struct snd_soc_codec *codec, + unsigned int dmic, + struct wcd9xxx_pdata *pdata) +{ + u8 tx_stream_fs; + u8 adc_mux_index = 0, adc_mux_sel = 0; + bool dec_found = false; + u16 adc_mux_ctl_reg, tx_fs_reg; + u32 dmic_fs; + + while (dec_found == 0 && adc_mux_index < WCD9360_MAX_VALID_ADC_MUX) { + if (adc_mux_index < 4) { + adc_mux_ctl_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + + (adc_mux_index * 2); + } else if (adc_mux_index < WCD9360_INVALID_ADC_MUX) { + adc_mux_ctl_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + + adc_mux_index - 4; + } else if (adc_mux_index == WCD9360_INVALID_ADC_MUX) { + ++adc_mux_index; + continue; + } + adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) & + 0xF8) >> 3) - 1; + + if (adc_mux_sel == dmic) { + dec_found = true; + break; + } + + ++adc_mux_index; + } + + if (dec_found && adc_mux_index <= 8) { + tx_fs_reg = WCD9360_CDC_TX0_TX_PATH_CTL + (16 * adc_mux_index); + tx_stream_fs = snd_soc_read(codec, tx_fs_reg) & 0x0F; + if (tx_stream_fs <= 4) { + if (pdata->dmic_sample_rate <= + WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ) + dmic_fs = pdata->dmic_sample_rate; + else + dmic_fs = WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ; + } else + dmic_fs = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ; + } else { + dmic_fs = pdata->dmic_sample_rate; + } + + return dmic_fs; +} + +static u8 pahu_get_dmic_clk_val(struct snd_soc_codec *codec, + u32 dmic_clk_rate) +{ + u32 div_factor; + u8 dmic_ctl_val = WCD9360_DMIC_CLK_DIV_2; + + dev_dbg(codec->dev, "%s: dmic_sample_rate = %d\n", + __func__, dmic_clk_rate); + + if (dmic_clk_rate == 0) { + dev_err(codec->dev, "%s: dmic_sample_rate cannot be 0\n", + __func__); + goto done; + } + + div_factor = WCD9360_MCLK_CLK_9P6MHZ / dmic_clk_rate; + switch (div_factor) { + case 2: + dmic_ctl_val = WCD9360_DMIC_CLK_DIV_2; + break; + case 3: + dmic_ctl_val = WCD9360_DMIC_CLK_DIV_3; + break; + case 4: + dmic_ctl_val = WCD9360_DMIC_CLK_DIV_4; + break; + case 6: + dmic_ctl_val = WCD9360_DMIC_CLK_DIV_6; + break; + case 8: + dmic_ctl_val = WCD9360_DMIC_CLK_DIV_8; + break; + case 16: + dmic_ctl_val = WCD9360_DMIC_CLK_DIV_16; + break; + default: + dev_err(codec->dev, + "%s: Invalid div_factor %u, dmic_rate(%u)\n", + __func__, div_factor, dmic_clk_rate); + break; + } + +done: + return dmic_ctl_val; +} + +static int pahu_codec_enable_adc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s: event:%d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + pahu_codec_set_tx_hold(codec, w->reg, true); + break; + default: + break; + } + + return 0; +} + +static int pahu_codec_enable_dmic(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + u8 dmic_clk_en = 0x01; + u16 dmic_clk_reg; + s32 *dmic_clk_cnt; + u8 dmic_rate_val, dmic_rate_shift = 1; + unsigned int dmic; + u32 dmic_sample_rate; + + dmic = w->shift; + switch (dmic) { + case 0: + case 1: + dmic_clk_cnt = &(pahu->dmic_0_1_clk_cnt); + dmic_clk_reg = WCD9360_CPE_SS_DMIC0_CTL; + break; + case 2: + case 3: + dmic_clk_cnt = &(pahu->dmic_2_3_clk_cnt); + dmic_clk_reg = WCD9360_CPE_SS_DMIC1_CTL; + break; + case 4: + case 5: + dmic_clk_cnt = &(pahu->dmic_4_5_clk_cnt); + dmic_clk_reg = WCD9360_CPE_SS_DMIC2_CTL; + break; + case 6: + case 7: + dmic_clk_cnt = &(pahu->dmic_6_7_clk_cnt); + dmic_clk_reg = WCD9360_CPE_SS_DMIC3_CTL; + break; + default: + dev_err(codec->dev, "%s: Invalid DMIC Selection\n", + __func__); + return -EINVAL; + }; + dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", + __func__, event, dmic, *dmic_clk_cnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + dmic_sample_rate = pahu_get_dmic_sample_rate(codec, dmic, + pdata); + dmic_rate_val = + pahu_get_dmic_clk_val(codec, + dmic_sample_rate); + + (*dmic_clk_cnt)++; + if (*dmic_clk_cnt == 1) { + snd_soc_update_bits(codec, dmic_clk_reg, + 0x07 << dmic_rate_shift, + dmic_rate_val << dmic_rate_shift); + snd_soc_update_bits(codec, dmic_clk_reg, + dmic_clk_en, dmic_clk_en); + } + + break; + case SND_SOC_DAPM_POST_PMD: + dmic_rate_val = + pahu_get_dmic_clk_val(codec, + pdata->mad_dmic_sample_rate); + (*dmic_clk_cnt)--; + if (*dmic_clk_cnt == 0) { + snd_soc_update_bits(codec, dmic_clk_reg, + dmic_clk_en, 0); + snd_soc_update_bits(codec, dmic_clk_reg, + 0x07 << dmic_rate_shift, + dmic_rate_val << dmic_rate_shift); + } + break; + }; + + return 0; +} + +/* + * pahu_micbias_control: enable/disable micbias + * @codec: handle to snd_soc_codec * + * @micb_num: micbias to be enabled/disabled, e.g. micbias1 or micbias2 + * @req: control requested, enable/disable or pullup enable/disable + * @is_dapm: triggered by dapm or not + * + * return 0 if control is success or error code in case of failure + */ +int pahu_micbias_control(struct snd_soc_codec *codec, + int micb_num, int req, bool is_dapm) +{ + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + int micb_index = micb_num - 1; + u16 micb_reg; + + if ((micb_index < 0) || (micb_index > PAHU_MAX_MICBIAS - 1)) { + dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n", + __func__, micb_index); + return -EINVAL; + } + + switch (micb_num) { + case MIC_BIAS_1: + micb_reg = WCD9360_ANA_MICB1; + break; + case MIC_BIAS_2: + micb_reg = WCD9360_ANA_MICB2; + break; + case MIC_BIAS_3: + micb_reg = WCD9360_ANA_MICB3; + break; + case MIC_BIAS_4: + micb_reg = WCD9360_ANA_MICB4; + break; + default: + dev_err(codec->dev, "%s: Invalid micbias number: %d\n", + __func__, micb_num); + return -EINVAL; + } + mutex_lock(&pahu->micb_lock); + + switch (req) { + case MICB_PULLUP_ENABLE: + pahu->pullup_ref[micb_index]++; + if ((pahu->pullup_ref[micb_index] == 1) && + (pahu->micb_ref[micb_index] == 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + break; + case MICB_PULLUP_DISABLE: + if (pahu->pullup_ref[micb_index] > 0) + pahu->pullup_ref[micb_index]--; + if ((pahu->pullup_ref[micb_index] == 0) && + (pahu->micb_ref[micb_index] == 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + break; + case MICB_ENABLE: + pahu->micb_ref[micb_index]++; + if (pahu->micb_ref[micb_index] == 1) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + break; + case MICB_DISABLE: + if (pahu->micb_ref[micb_index] > 0) + pahu->micb_ref[micb_index]--; + if ((pahu->micb_ref[micb_index] == 0) && + (pahu->pullup_ref[micb_index] > 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + else if ((pahu->micb_ref[micb_index] == 0) && + (pahu->pullup_ref[micb_index] == 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + break; + } + + dev_dbg(codec->dev, "%s: micb_num:%d, micb_ref: %d\n", + __func__, micb_num, pahu->micb_ref[micb_index]); + + mutex_unlock(&pahu->micb_lock); + + return 0; +} +EXPORT_SYMBOL(pahu_micbias_control); + +static int __pahu_codec_enable_micbias(struct snd_soc_dapm_widget *w, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int micb_num; + + dev_dbg(codec->dev, "%s: wname: %s, event: %d\n", + __func__, w->name, event); + + if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) + micb_num = MIC_BIAS_1; + else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2"))) + micb_num = MIC_BIAS_2; + else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3"))) + micb_num = MIC_BIAS_3; + else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4"))) + micb_num = MIC_BIAS_4; + else + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* + * Use ref count to handle micbias pullup + * and enable requests + */ + pahu_micbias_control(codec, micb_num, MICB_ENABLE, true); + break; + case SND_SOC_DAPM_POST_PMU: + /* wait for cnp time */ + usleep_range(1000, 1100); + break; + case SND_SOC_DAPM_POST_PMD: + pahu_micbias_control(codec, micb_num, MICB_DISABLE, true); + break; + }; + + return 0; +} + +/* + * pahu_codec_enable_standalone_micbias - enable micbias standalone + * @codec: pointer to codec instance + * @micb_num: number of micbias to be enabled + * @enable: true to enable micbias or false to disable + * + * This function is used to enable micbias (1, 2, 3 or 4) during + * standalone independent of whether TX use-case is running or not + * + * Return: error code in case of failure or 0 for success + */ +int pahu_codec_enable_standalone_micbias(struct snd_soc_codec *codec, + int micb_num, + bool enable) +{ + const char * const micb_names[] = { + DAPM_MICBIAS1_STANDALONE, DAPM_MICBIAS2_STANDALONE, + DAPM_MICBIAS3_STANDALONE, DAPM_MICBIAS4_STANDALONE + }; + int micb_index = micb_num - 1; + int rc; + + if (!codec) { + pr_err("%s: Codec memory is NULL\n", __func__); + return -EINVAL; + } + + if ((micb_index < 0) || (micb_index > PAHU_MAX_MICBIAS - 1)) { + dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n", + __func__, micb_index); + return -EINVAL; + } + + if (enable) + rc = snd_soc_dapm_force_enable_pin( + snd_soc_codec_get_dapm(codec), + micb_names[micb_index]); + else + rc = snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(codec), + micb_names[micb_index]); + + if (!rc) + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + else + dev_err(codec->dev, "%s: micbias%d force %s pin failed\n", + __func__, micb_num, (enable ? "enable" : "disable")); + + return rc; +} +EXPORT_SYMBOL(pahu_codec_enable_standalone_micbias); + +static int pahu_codec_force_enable_micbias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + int ret = 0; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd_resmgr_enable_master_bias(pahu->resmgr); + pahu_cdc_mclk_enable(codec, true); + ret = __pahu_codec_enable_micbias(w, SND_SOC_DAPM_PRE_PMU); + /* Wait for 1ms for better cnp */ + usleep_range(1000, 1100); + pahu_cdc_mclk_enable(codec, false); + break; + case SND_SOC_DAPM_POST_PMD: + ret = __pahu_codec_enable_micbias(w, SND_SOC_DAPM_POST_PMD); + wcd_resmgr_disable_master_bias(pahu->resmgr); + break; + } + + return ret; +} + +static int pahu_codec_enable_micbias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + return __pahu_codec_enable_micbias(w, event); +} + +static void pahu_restore_iir_coeff(struct pahu_priv *pahu, int iir_idx, + int band_idx) +{ + u16 reg_add; + int no_of_reg = 0; + + regmap_write(pahu->wcd9xxx->regmap, + (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); + reg_add = WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx; + + if (pahu->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) + return; + /* + * Since wcd9xxx_slim_write_repeat() supports only maximum of 16 + * registers at a time, split total 20 writes(5 coefficients per + * band and 4 writes per coefficient) into 16 and 4. + */ + no_of_reg = WCD9360_CDC_REPEAT_WRITES_MAX; + wcd9xxx_slim_write_repeat(pahu->wcd9xxx, reg_add, no_of_reg, + &pahu->sidetone_coeff_array[iir_idx][band_idx][0]); + + no_of_reg = (WCD9360_CDC_SIDETONE_IIR_COEFF_MAX * 4) - + WCD9360_CDC_REPEAT_WRITES_MAX; + wcd9xxx_slim_write_repeat(pahu->wcd9xxx, reg_add, no_of_reg, + &pahu->sidetone_coeff_array[iir_idx][band_idx] + [WCD9360_CDC_REPEAT_WRITES_MAX]); +} + +static int pahu_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + /* IIR filter band registers are at integer multiples of 16 */ + u16 iir_reg = WCD9360_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx; + + ucontrol->value.integer.value[0] = (snd_soc_read(codec, iir_reg) & + (1 << band_idx)) != 0; + + dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, + iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[0]); + return 0; +} + +static int pahu_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + bool iir_band_en_status; + int value = ucontrol->value.integer.value[0]; + u16 iir_reg = WCD9360_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx; + + pahu_restore_iir_coeff(pahu, iir_idx, band_idx); + + /* Mask first 5 bits, 6-8 are reserved */ + snd_soc_update_bits(codec, iir_reg, (1 << band_idx), + (value << band_idx)); + + iir_band_en_status = ((snd_soc_read(codec, iir_reg) & + (1 << band_idx)) != 0); + dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, + iir_idx, band_idx, iir_band_en_status); + return 0; +} + +static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec, + int iir_idx, int band_idx, + int coeff_idx) +{ + uint32_t value = 0; + + /* Address does not automatically update if reading */ + snd_soc_write(codec, + (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t)) & 0x7F); + + value |= snd_soc_read(codec, + (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx)); + + snd_soc_write(codec, + (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 1) & 0x7F); + + value |= (snd_soc_read(codec, + (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + + 16 * iir_idx)) << 8); + + snd_soc_write(codec, + (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 2) & 0x7F); + + value |= (snd_soc_read(codec, + (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + + 16 * iir_idx)) << 16); + + snd_soc_write(codec, + (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 3) & 0x7F); + + /* Mask bits top 2 bits since they are reserved */ + value |= ((snd_soc_read(codec, + (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + + 16 * iir_idx)) & 0x3F) << 24); + + return value; +} + +static int pahu_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + ucontrol->value.integer.value[0] = + get_iir_band_coeff(codec, iir_idx, band_idx, 0); + ucontrol->value.integer.value[1] = + get_iir_band_coeff(codec, iir_idx, band_idx, 1); + ucontrol->value.integer.value[2] = + get_iir_band_coeff(codec, iir_idx, band_idx, 2); + ucontrol->value.integer.value[3] = + get_iir_band_coeff(codec, iir_idx, band_idx, 3); + ucontrol->value.integer.value[4] = + get_iir_band_coeff(codec, iir_idx, band_idx, 4); + + dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n" + "%s: IIR #%d band #%d b1 = 0x%x\n" + "%s: IIR #%d band #%d b2 = 0x%x\n" + "%s: IIR #%d band #%d a1 = 0x%x\n" + "%s: IIR #%d band #%d a2 = 0x%x\n", + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[0], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[1], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[2], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[3], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[4]); + return 0; +} + +static void set_iir_band_coeff(struct snd_soc_codec *codec, + int iir_idx, int band_idx, + uint32_t value) +{ + snd_soc_write(codec, + (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), + (value & 0xFF)); + + snd_soc_write(codec, + (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), + (value >> 8) & 0xFF); + + snd_soc_write(codec, + (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), + (value >> 16) & 0xFF); + + /* Mask top 2 bits, 7-8 are reserved */ + snd_soc_write(codec, + (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), + (value >> 24) & 0x3F); +} + +static int pahu_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int coeff_idx, idx = 0; + + /* + * Mask top bit it is reserved + * Updates addr automatically for each B2 write + */ + snd_soc_write(codec, + (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); + + /* Store the coefficients in sidetone coeff array */ + for (coeff_idx = 0; coeff_idx < WCD9360_CDC_SIDETONE_IIR_COEFF_MAX; + coeff_idx++) { + uint32_t value = ucontrol->value.integer.value[coeff_idx]; + + set_iir_band_coeff(codec, iir_idx, band_idx, value); + + /* Four 8 bit values(one 32 bit) per coefficient */ + pahu->sidetone_coeff_array[iir_idx][band_idx][idx++] = + (value & 0xFF); + pahu->sidetone_coeff_array[iir_idx][band_idx][idx++] = + ((value >> 8) & 0xFF); + pahu->sidetone_coeff_array[iir_idx][band_idx][idx++] = + ((value >> 16) & 0xFF); + pahu->sidetone_coeff_array[iir_idx][band_idx][idx++] = + ((value >> 24) & 0xFF); + } + + pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n" + "%s: IIR #%d band #%d b1 = 0x%x\n" + "%s: IIR #%d band #%d b2 = 0x%x\n" + "%s: IIR #%d band #%d a1 = 0x%x\n" + "%s: IIR #%d band #%d a2 = 0x%x\n", + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 0), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 1), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 2), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 3), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 4)); + return 0; +} + +static int pahu_compander_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = pahu->comp_enabled[comp]; + return 0; +} + +static int pahu_compander_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int value = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n", + __func__, comp + 1, pahu->comp_enabled[comp], value); + pahu->comp_enabled[comp] = value; + + return 0; +} + +static int pahu_dmic_pin_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u16 offset; + u8 reg_val, pinctl_position; + + pinctl_position = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + offset = pinctl_position - WCD9360_TLMM_DMIC_PINCFG_OFFSET; + reg_val = snd_soc_read(codec, + WCD9360_TLMM_DMIC1_CLK_PINCFG + offset); + + ucontrol->value.integer.value[0] = !!reg_val; + + return 0; +} + +static int pahu_dmic_pin_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + u16 ctl_reg, cfg_reg, offset; + u8 ctl_val, cfg_val, pinctl_position, pinctl_mode, mask; + + /* 0- high or low; 1- high Z */ + pinctl_mode = ucontrol->value.integer.value[0]; + pinctl_position = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + switch (pinctl_position >> 3) { + case 0: + ctl_reg = WCD9360_TEST_DEBUG_PIN_CTL_OE_0; + break; + case 1: + ctl_reg = WCD9360_TEST_DEBUG_PIN_CTL_OE_1; + break; + case 2: + ctl_reg = WCD9360_TEST_DEBUG_PIN_CTL_OE_2; + break; + case 3: + ctl_reg = WCD9360_TEST_DEBUG_PIN_CTL_OE_3; + break; + default: + dev_err(codec->dev, "%s: Invalid pinctl position = %d\n", + __func__, pinctl_position); + return -EINVAL; + } + + ctl_val = ~(pinctl_mode << (pinctl_position & 0x07)); + mask = 1 << (pinctl_position & 0x07); + snd_soc_update_bits(codec, ctl_reg, mask, ctl_val); + + offset = pinctl_position - WCD9360_TLMM_DMIC_PINCFG_OFFSET; + cfg_reg = WCD9360_TLMM_DMIC1_CLK_PINCFG + offset; + if (pinctl_mode) { + if (pahu->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) + cfg_val = 0x5; + else + cfg_val = 0xD; + } else + cfg_val = 0; + snd_soc_update_bits(codec, cfg_reg, 0x1F, cfg_val); + + dev_dbg(codec->dev, "%s: reg=0x%x mask=0x%x val=%d reg=0x%x val=%d\n", + __func__, ctl_reg, mask, ctl_val, cfg_reg, cfg_val); + + return 0; +} + +static int pahu_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u16 amic_reg = 0; + + if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE")) + amic_reg = WCD9360_ANA_AMIC1; + if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE")) + amic_reg = WCD9360_ANA_AMIC3; + + if (amic_reg) + ucontrol->value.integer.value[0] = + (snd_soc_read(codec, amic_reg) & + WCD9360_AMIC_PWR_LVL_MASK) >> + WCD9360_AMIC_PWR_LVL_SHIFT; + return 0; +} + +static int pahu_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u32 mode_val; + u16 amic_reg = 0; + + mode_val = ucontrol->value.enumerated.item[0]; + + dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val); + + if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE")) + amic_reg = WCD9360_ANA_AMIC1; + if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE")) + amic_reg = WCD9360_ANA_AMIC3; + + if (amic_reg) + snd_soc_update_bits(codec, amic_reg, WCD9360_AMIC_PWR_LVL_MASK, + mode_val << WCD9360_AMIC_PWR_LVL_SHIFT); + return 0; +} + +static const char *const pahu_conn_mad_text[] = { + "NOTUSED1", "ADC1", "ADC2", "ADC3", "ADC4", "NOTUSED5", + "NOTUSED6", "NOTUSED2", "DMIC0", "DMIC1", "DMIC2", "DMIC3", + "DMIC4", "DMIC5", "DMIC6", "DMIC7" +}; + +static const struct soc_enum pahu_conn_mad_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(pahu_conn_mad_text), + pahu_conn_mad_text); + +static int pahu_mad_input_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u8 pahu_mad_input; + + pahu_mad_input = snd_soc_read(codec, WCD9360_SOC_MAD_INP_SEL) & 0x0F; + ucontrol->value.integer.value[0] = pahu_mad_input; + + dev_dbg(codec->dev, "%s: pahu_mad_input = %s\n", __func__, + pahu_conn_mad_text[pahu_mad_input]); + + return 0; +} + +static int pahu_mad_input_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_card *card = codec->component.card; + u8 pahu_mad_input; + char mad_amic_input_widget[6]; + const char *mad_input_widget; + const char *source_widget = NULL; + u32 adc, i, mic_bias_found = 0; + int ret = 0; + char *mad_input; + bool is_adc_input = false; + + pahu_mad_input = ucontrol->value.integer.value[0]; + + if (pahu_mad_input >= sizeof(pahu_conn_mad_text)/ + sizeof(pahu_conn_mad_text[0])) { + dev_err(codec->dev, + "%s: pahu_mad_input = %d out of bounds\n", + __func__, pahu_mad_input); + return -EINVAL; + } + + if (strnstr(pahu_conn_mad_text[pahu_mad_input], "NOTUSED", + sizeof("NOTUSED"))) { + dev_dbg(codec->dev, + "%s: Unsupported pahu_mad_input = %s\n", + __func__, pahu_conn_mad_text[pahu_mad_input]); + /* Make sure the MAD register is updated */ + snd_soc_update_bits(codec, WCD9360_ANA_MAD_SETUP, + 0x88, 0x00); + return -EINVAL; + } + + if (strnstr(pahu_conn_mad_text[pahu_mad_input], + "ADC", sizeof("ADC"))) { + mad_input = strpbrk(pahu_conn_mad_text[pahu_mad_input], + "1234"); + if (!mad_input) { + dev_err(codec->dev, "%s: Invalid MAD input %s\n", + __func__, pahu_conn_mad_text[pahu_mad_input]); + return -EINVAL; + } + + ret = kstrtouint(mad_input, 10, &adc); + if ((ret < 0) || (adc > 4)) { + dev_err(codec->dev, "%s: Invalid ADC = %s\n", __func__, + pahu_conn_mad_text[pahu_mad_input]); + return -EINVAL; + } + + snprintf(mad_amic_input_widget, 6, "%s%u", "AMIC", adc); + + mad_input_widget = mad_amic_input_widget; + is_adc_input = true; + } else { + /* DMIC type input widget*/ + mad_input_widget = pahu_conn_mad_text[pahu_mad_input]; + } + + dev_dbg(codec->dev, + "%s: pahu input widget = %s, adc_input = %s\n", __func__, + mad_input_widget, is_adc_input ? "true" : "false"); + + for (i = 0; i < card->num_of_dapm_routes; i++) { + if (!strcmp(card->of_dapm_routes[i].sink, mad_input_widget)) { + source_widget = card->of_dapm_routes[i].source; + if (!source_widget) { + dev_err(codec->dev, + "%s: invalid source widget\n", + __func__); + return -EINVAL; + } + + if (strnstr(source_widget, + "MIC BIAS1", sizeof("MIC BIAS1"))) { + mic_bias_found = 1; + break; + } else if (strnstr(source_widget, + "MIC BIAS2", sizeof("MIC BIAS2"))) { + mic_bias_found = 2; + break; + } else if (strnstr(source_widget, + "MIC BIAS3", sizeof("MIC BIAS3"))) { + mic_bias_found = 3; + break; + } else if (strnstr(source_widget, + "MIC BIAS4", sizeof("MIC BIAS4"))) { + mic_bias_found = 4; + break; + } + } + } + + if (!mic_bias_found) { + dev_err(codec->dev, "%s: mic bias not found for input %s\n", + __func__, mad_input_widget); + return -EINVAL; + } + + dev_dbg(codec->dev, "%s: mic_bias found = %d\n", __func__, + mic_bias_found); + + snd_soc_update_bits(codec, WCD9360_SOC_MAD_INP_SEL, + 0x0F, pahu_mad_input); + snd_soc_update_bits(codec, WCD9360_ANA_MAD_SETUP, + 0x07, mic_bias_found); + /* for all adc inputs, mad should be in micbias mode with BG enabled */ + if (is_adc_input) + snd_soc_update_bits(codec, WCD9360_ANA_MAD_SETUP, + 0x88, 0x88); + else + snd_soc_update_bits(codec, WCD9360_ANA_MAD_SETUP, + 0x88, 0x00); + return 0; +} + +static int pahu_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = pahu->ear_spkr_gain; + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int pahu_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + pahu->ear_spkr_gain = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: gain = %d\n", __func__, pahu->ear_spkr_gain); + + return 0; +} + +static int pahu_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max = 0; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + bst_state_max = snd_soc_read(codec, WCD9360_CDC_BOOST0_BOOST_CTL); + bst_state_max = (bst_state_max & 0x0c) >> 2; + ucontrol->value.integer.value[0] = bst_state_max; + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int pahu_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + bst_state_max = ucontrol->value.integer.value[0] << 2; + snd_soc_update_bits(codec, WCD9360_CDC_BOOST0_BOOST_CTL, + 0x0c, bst_state_max); + + return 0; +} + +static int pahu_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max = 0; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + bst_state_max = snd_soc_read(codec, WCD9360_CDC_BOOST1_BOOST_CTL); + bst_state_max = (bst_state_max & 0x0c) >> 2; + ucontrol->value.integer.value[0] = bst_state_max; + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int pahu_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + bst_state_max = ucontrol->value.integer.value[0] << 2; + snd_soc_update_bits(codec, WCD9360_CDC_BOOST1_BOOST_CTL, + 0x0c, bst_state_max); + + return 0; +} + +static const char *const pahu_anc_func_text[] = {"OFF", "ON"}; +static const struct soc_enum pahu_anc_func_enum = + SOC_ENUM_SINGLE_EXT(2, pahu_anc_func_text); + +static const char *const pahu_clkmode_text[] = {"EXTERNAL", "INTERNAL"}; +static SOC_ENUM_SINGLE_EXT_DECL(pahu_clkmode_enum, pahu_clkmode_text); + +/* Cutoff frequency for high pass filter */ +static const char * const cf_text[] = { + "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ" +}; + +static const char * const rx_cf_text[] = { + "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ", + "CF_NEG_3DB_0P48HZ" +}; + +static const char * const amic_pwr_lvl_text[] = { + "LOW_PWR", "DEFAULT", "HIGH_PERF", "HYBRID" +}; + +static const char * const pahu_ear_pa_gain_text[] = { + "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB", + "G_0_DB", "G_M2P5_DB", "UNDEFINED", "G_M12_DB" +}; + +static const char * const pahu_ear_spkr_pa_gain_text[] = { + "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB", + "G_4_DB", "G_5_DB", "G_6_DB" +}; + +static const char * const pahu_speaker_boost_stage_text[] = { + "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2" +}; + +static SOC_ENUM_SINGLE_EXT_DECL(pahu_ear_pa_gain_enum, pahu_ear_pa_gain_text); +static SOC_ENUM_SINGLE_EXT_DECL(pahu_ear_spkr_pa_gain_enum, + pahu_ear_spkr_pa_gain_text); +static SOC_ENUM_SINGLE_EXT_DECL(pahu_spkr_boost_stage_enum, + pahu_speaker_boost_stage_text); +static SOC_ENUM_SINGLE_EXT_DECL(amic_pwr_lvl_enum, amic_pwr_lvl_text); +static SOC_ENUM_SINGLE_DECL(cf_dec0_enum, WCD9360_CDC_TX0_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec1_enum, WCD9360_CDC_TX1_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec2_enum, WCD9360_CDC_TX2_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec3_enum, WCD9360_CDC_TX3_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec4_enum, WCD9360_CDC_TX4_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec5_enum, WCD9360_CDC_TX5_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec6_enum, WCD9360_CDC_TX6_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec7_enum, WCD9360_CDC_TX7_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec8_enum, WCD9360_CDC_TX8_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int0_1_enum, WCD9360_CDC_RX0_RX_PATH_CFG2, 0, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD9360_CDC_RX0_RX_PATH_MIX_CFG, 2, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int7_1_enum, WCD9360_CDC_RX7_RX_PATH_CFG2, 0, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD9360_CDC_RX7_RX_PATH_MIX_CFG, 2, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int8_1_enum, WCD9360_CDC_RX8_RX_PATH_CFG2, 0, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD9360_CDC_RX8_RX_PATH_MIX_CFG, 2, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int9_1_enum, WCD9360_CDC_RX9_RX_PATH_CFG2, 0, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int9_2_enum, WCD9360_CDC_RX9_RX_PATH_MIX_CFG, 2, + rx_cf_text); + +static const struct snd_kcontrol_new pahu_snd_controls[] = { + SOC_ENUM_EXT("EAR SPKR PA Gain", pahu_ear_spkr_pa_gain_enum, + pahu_ear_spkr_pa_gain_get, pahu_ear_spkr_pa_gain_put), + SOC_ENUM_EXT("SPKR Left Boost Max State", pahu_spkr_boost_stage_enum, + pahu_spkr_left_boost_stage_get, + pahu_spkr_left_boost_stage_put), + SOC_ENUM_EXT("SPKR Right Boost Max State", pahu_spkr_boost_stage_enum, + pahu_spkr_right_boost_stage_get, + pahu_spkr_right_boost_stage_put), + SOC_SINGLE_TLV("ADC1 Volume", WCD9360_ANA_AMIC1, 0, 20, 0, analog_gain), + SOC_SINGLE_TLV("ADC2 Volume", WCD9360_ANA_AMIC2, 0, 20, 0, analog_gain), + SOC_SINGLE_TLV("ADC3 Volume", WCD9360_ANA_AMIC3, 0, 20, 0, analog_gain), + SOC_SINGLE_TLV("ADC4 Volume", WCD9360_ANA_AMIC4, 0, 20, 0, analog_gain), + + SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9360_CDC_RX0_RX_VOL_CTL, + 0, -84, 40, digital_gain), /* -84dB min - 40dB max */ + SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9360_CDC_RX7_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9360_CDC_RX8_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX9 Digital Volume", WCD9360_CDC_RX9_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume", + WCD9360_CDC_RX0_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume", + WCD9360_CDC_RX7_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume", + WCD9360_CDC_RX8_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX9 Mix Digital Volume", + WCD9360_CDC_RX9_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), + + SOC_SINGLE_SX_TLV("DEC0 Volume", WCD9360_CDC_TX0_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC1 Volume", WCD9360_CDC_TX1_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC2 Volume", WCD9360_CDC_TX2_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC3 Volume", WCD9360_CDC_TX3_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC4 Volume", WCD9360_CDC_TX4_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC5 Volume", WCD9360_CDC_TX5_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC6 Volume", WCD9360_CDC_TX6_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC7 Volume", WCD9360_CDC_TX7_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC8 Volume", WCD9360_CDC_TX8_TX_VOL_CTL, 0, + -84, 40, digital_gain), + + SOC_SINGLE_SX_TLV("IIR0 INP0 Volume", + WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR0 INP1 Volume", + WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR0 INP2 Volume", + WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR0 INP3 Volume", + WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84, 40, + digital_gain), + + SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, pahu_get_anc_slot, + pahu_put_anc_slot), + SOC_ENUM_EXT("ANC Function", pahu_anc_func_enum, pahu_get_anc_func, + pahu_put_anc_func), + + SOC_ENUM_EXT("CLK MODE", pahu_clkmode_enum, pahu_get_clkmode, + pahu_put_clkmode), + + SOC_ENUM("TX0 HPF cut off", cf_dec0_enum), + SOC_ENUM("TX1 HPF cut off", cf_dec1_enum), + SOC_ENUM("TX2 HPF cut off", cf_dec2_enum), + SOC_ENUM("TX3 HPF cut off", cf_dec3_enum), + SOC_ENUM("TX4 HPF cut off", cf_dec4_enum), + SOC_ENUM("TX5 HPF cut off", cf_dec5_enum), + SOC_ENUM("TX6 HPF cut off", cf_dec6_enum), + SOC_ENUM("TX7 HPF cut off", cf_dec7_enum), + SOC_ENUM("TX8 HPF cut off", cf_dec8_enum), + + SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum), + SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum), + SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum), + SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum), + SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum), + SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum), + SOC_ENUM("RX INT9_1 HPF cut off", cf_int9_1_enum), + SOC_ENUM("RX INT9_2 HPF cut off", cf_int9_2_enum), + + SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0, + pahu_iir_enable_audio_mixer_get, + pahu_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR0 Enable Band2", IIR0, BAND2, 1, 0, + pahu_iir_enable_audio_mixer_get, + pahu_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR0 Enable Band3", IIR0, BAND3, 1, 0, + pahu_iir_enable_audio_mixer_get, + pahu_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR0 Enable Band4", IIR0, BAND4, 1, 0, + pahu_iir_enable_audio_mixer_get, + pahu_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR0 Enable Band5", IIR0, BAND5, 1, 0, + pahu_iir_enable_audio_mixer_get, + pahu_iir_enable_audio_mixer_put), + + SOC_SINGLE_MULTI_EXT("IIR0 Band1", IIR0, BAND1, 255, 0, 5, + pahu_iir_band_audio_mixer_get, pahu_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR0 Band2", IIR0, BAND2, 255, 0, 5, + pahu_iir_band_audio_mixer_get, pahu_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR0 Band3", IIR0, BAND3, 255, 0, 5, + pahu_iir_band_audio_mixer_get, pahu_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR0 Band4", IIR0, BAND4, 255, 0, 5, + pahu_iir_band_audio_mixer_get, pahu_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR0 Band5", IIR0, BAND5, 255, 0, 5, + pahu_iir_band_audio_mixer_get, pahu_iir_band_audio_mixer_put), + + SOC_SINGLE_EXT("COMP0 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0, + pahu_compander_get, pahu_compander_put), + SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0, + pahu_compander_get, pahu_compander_put), + SOC_SINGLE_EXT("COMP8 Switch", SND_SOC_NOPM, COMPANDER_8, 1, 0, + pahu_compander_get, pahu_compander_put), + + SOC_ENUM_EXT("MAD Input", pahu_conn_mad_enum, + pahu_mad_input_get, pahu_mad_input_put), + + SOC_SINGLE_EXT("DMIC1_CLK_PIN_MODE", SND_SOC_NOPM, 15, 1, 0, + pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put), + + SOC_SINGLE_EXT("DMIC1_DATA_PIN_MODE", SND_SOC_NOPM, 16, 1, 0, + pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put), + + SOC_SINGLE_EXT("DMIC2_CLK_PIN_MODE", SND_SOC_NOPM, 17, 1, 0, + pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put), + + SOC_SINGLE_EXT("DMIC2_DATA_PIN_MODE", SND_SOC_NOPM, 18, 1, 0, + pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put), + + SOC_SINGLE_EXT("DMIC3_CLK_PIN_MODE", SND_SOC_NOPM, 28, 1, 0, + pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put), + + SOC_SINGLE_EXT("DMIC3_DATA_PIN_MODE", SND_SOC_NOPM, 29, 1, 0, + pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put), + + SOC_SINGLE_EXT("DMIC4_CLK_PIN_MODE", SND_SOC_NOPM, 30, 1, 0, + pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put), + + SOC_SINGLE_EXT("DMIC4_DATA_PIN_MODE", SND_SOC_NOPM, 31, 1, 0, + pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put), + + SOC_ENUM_EXT("AMIC_1_2 PWR MODE", amic_pwr_lvl_enum, + pahu_amic_pwr_lvl_get, pahu_amic_pwr_lvl_put), + SOC_ENUM_EXT("AMIC_3_4 PWR MODE", amic_pwr_lvl_enum, + pahu_amic_pwr_lvl_get, pahu_amic_pwr_lvl_put), +}; + +static int pahu_dec_enum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val; + u16 mic_sel_reg = 0; + u8 mic_sel; + + val = ucontrol->value.enumerated.item[0]; + if (val > e->items - 1) + return -EINVAL; + + dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + widget->name, val); + + switch (e->reg) { + case WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1: + if (e->shift_l == 0) + mic_sel_reg = WCD9360_CDC_TX0_TX_PATH_CFG0; + else if (e->shift_l == 2) + mic_sel_reg = WCD9360_CDC_TX4_TX_PATH_CFG0; + else if (e->shift_l == 4) + mic_sel_reg = WCD9360_CDC_TX8_TX_PATH_CFG0; + break; + case WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1: + if (e->shift_l == 0) + mic_sel_reg = WCD9360_CDC_TX1_TX_PATH_CFG0; + else if (e->shift_l == 2) + mic_sel_reg = WCD9360_CDC_TX5_TX_PATH_CFG0; + break; + case WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1: + if (e->shift_l == 0) + mic_sel_reg = WCD9360_CDC_TX2_TX_PATH_CFG0; + else if (e->shift_l == 2) + mic_sel_reg = WCD9360_CDC_TX6_TX_PATH_CFG0; + break; + case WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1: + if (e->shift_l == 0) + mic_sel_reg = WCD9360_CDC_TX3_TX_PATH_CFG0; + else if (e->shift_l == 2) + mic_sel_reg = WCD9360_CDC_TX7_TX_PATH_CFG0; + break; + default: + dev_err(codec->dev, "%s: e->reg: 0x%x not expected\n", + __func__, e->reg); + return -EINVAL; + } + + /* ADC: 0, DMIC: 1 */ + mic_sel = val ? 0x0 : 0x1; + if (mic_sel_reg) + snd_soc_update_bits(codec, mic_sel_reg, 1 << 7, mic_sel << 7); + + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +static int pahu_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val; + unsigned short look_ahead_dly_reg = WCD9360_CDC_RX0_RX_PATH_CFG0; + + val = ucontrol->value.enumerated.item[0]; + if (val >= e->items) + return -EINVAL; + + dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + widget->name, val); + + if (e->reg == WCD9360_CDC_RX0_RX_PATH_SEC0) + look_ahead_dly_reg = WCD9360_CDC_RX0_RX_PATH_CFG0; + else if (e->reg == WCD9360_CDC_RX9_RX_PATH_SEC0) + look_ahead_dly_reg = WCD9360_CDC_RX9_RX_PATH_CFG0; + + /* Set Look Ahead Delay */ + snd_soc_update_bits(codec, look_ahead_dly_reg, + 0x08, (val ? 0x08 : 0x00)); + /* Set DEM INP Select */ + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +static const char * const rx_int0_7_mix_mux_text[] = { + "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", + "RX6", "RX7", "PROXIMITY", "IIR0" +}; + +static const char * const rx_int_mix_mux_text[] = { + "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", + "RX6", "RX7", "NA", "IIR0" +}; + +static const char * const rx_prim_mix_text[] = { + "ZERO", "DEC0", "DEC1", "IIR0", "INVALID", "RX0", "RX1", "RX2", + "RX3", "RX4", "RX5", "RX6", "RX7" +}; + +static const char * const rx_sidetone_mix_text[] = { + "ZERO", "SRC0" +}; + +static const char * const cdc_if_tx0_mux_text[] = { + "ZERO", "RX_MIX_TX0", "DEC0", "DEC0_192" +}; +static const char * const cdc_if_tx1_mux_text[] = { + "ZERO", "RX_MIX_TX1", "DEC1", "DEC1_192" +}; +static const char * const cdc_if_tx2_mux_text[] = { + "ZERO", "RX_MIX_TX2", "DEC2", "DEC2_192" +}; +static const char * const cdc_if_tx3_mux_text[] = { + "ZERO", "RX_MIX_TX3", "DEC3", "DEC3_192" +}; +static const char * const cdc_if_tx4_mux_text[] = { + "ZERO", "RX_MIX_TX4", "DEC4", "DEC4_192" +}; +static const char * const cdc_if_tx5_mux_text[] = { + "ZERO", "RX_MIX_TX5", "DEC5", "DEC5_192" +}; +static const char * const cdc_if_tx6_mux_text[] = { + "ZERO", "RX_MIX_TX6", "DEC6", "DEC6_192" +}; +static const char * const cdc_if_tx7_mux_text[] = { + "ZERO", "RX_MIX_TX7", "DEC7", "DEC7_192" +}; +static const char * const cdc_if_tx8_mux_text[] = { + "ZERO", "RX_MIX_TX8", "DEC8", "DEC8_192" +}; +static const char * const cdc_if_tx9_mux_text[] = { + "ZERO", "DEC7", "DEC7_192" +}; +static const char * const cdc_if_tx10_mux_text[] = { + "ZERO", "DEC6", "DEC6_192" +}; +static const char * const cdc_if_tx11_mux_text[] = { + "DEC_0_5", "DEC_9_12", "MAD_AUDIO", "MAD_BRDCST" +}; +static const char * const cdc_if_tx11_inp1_mux_text[] = { + "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", + "DEC5", "RX_MIX_TX5", "DEC9_10", "DEC11_12" +}; +static const char * const cdc_if_tx13_mux_text[] = { + "CDC_DEC_5", "MAD_BRDCST" +}; +static const char * const cdc_if_tx13_inp1_mux_text[] = { + "ZERO", "DEC5", "DEC5_192" +}; + +static const char * const iir_inp_mux_text[] = { + "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", + "DEC7", "DEC8", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7" +}; + +static const char * const rx_int_dem_inp_mux_text[] = { + "NORMAL_DSM_OUT", "NOT_VALID", "ADC_LOOPBACK" +}; + +static const char * const rx_int0_1_interp_mux_text[] = { + "ZERO", "RX INT0_1 MIX1", +}; + +static const char * const rx_int7_1_interp_mux_text[] = { + "ZERO", "RX INT7_1 MIX1", +}; + +static const char * const rx_int8_1_interp_mux_text[] = { + "ZERO", "RX INT8_1 MIX1", +}; + +static const char * const rx_int9_1_interp_mux_text[] = { + "ZERO", "RX INT9_1 MIX1", +}; + +static const char * const rx_int0_2_interp_mux_text[] = { + "ZERO", "RX INT0_2 MUX", +}; + +static const char * const rx_int7_2_interp_mux_text[] = { + "ZERO", "RX INT7_2 MUX", +}; + +static const char * const rx_int8_2_interp_mux_text[] = { + "ZERO", "RX INT8_2 MUX", +}; + +static const char * const rx_int9_2_interp_mux_text[] = { + "ZERO", "RX INT9_2 MUX", +}; + +static const char * const mad_sel_txt[] = { + "SPE", "MSM" +}; + +static const char * const mad_inp_mux_txt[] = { + "MAD", "DEC1" +}; + +static const char * const adc_mux_text[] = { + "DMIC", "AMIC", "ANC_FB_TUNE1" +}; + +static const char * const dmic_mux_text[] = { + "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", + "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "DMIC6", + "DMIC7" +}; + +static const char * const amic_mux_text[] = { + "ZERO", "ADC1", "ADC2", "ADC3", "ADC4" +}; + +static const char * const adc2_in_text[] = { + "AMIC2", "AMIC1" +}; + +static const char * const adc4_in_text[] = { + "AMIC4", "AMIC3" +}; + +static const char * const anc0_fb_mux_text[] = { + "ZERO", "INVALID", "ANC_IN_EAR", "ANC_IN_EAR_SPKR", +}; + +static const char * const rx_echo_mux_text[] = { + "ZERO", "RX_MIX0", "NA", "NA", "NA", "NA", "NA", "NA", + "RX_MIX7", "RX_MIX8", "NA", "NA", "NA", "NA", "RX_MIX9" +}; + +static const char *const slim_rx_mux_text[] = { + "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB" +}; + +static const char *const cdc_if_rx0_mux_text[] = { + "SLIM RX0", "I2S RX0" +}; +static const char *const cdc_if_rx1_mux_text[] = { + "SLIM RX1", "I2S RX1" +}; +static const char *const cdc_if_rx2_mux_text[] = { + "SLIM RX2", "I2S RX2" +}; +static const char *const cdc_if_rx3_mux_text[] = { + "SLIM RX3", "I2S RX3" +}; +static const char *const cdc_if_rx4_mux_text[] = { + "SLIM RX4", "I2S RX4" +}; +static const char *const cdc_if_rx5_mux_text[] = { + "SLIM RX5", "I2S RX5" +}; +static const char *const cdc_if_rx6_mux_text[] = { + "SLIM RX6", "I2S RX6" +}; +static const char *const cdc_if_rx7_mux_text[] = { + "SLIM RX7", "I2S RX7" +}; + +static const char * const asrc2_mux_text[] = { + "ZERO", "ASRC_IN_SPKR1", +}; + +static const char * const asrc3_mux_text[] = { + "ZERO", "ASRC_IN_SPKR2", +}; + +static const char * const native_mux_text[] = { + "OFF", "ON", +}; + +static const char *const wdma3_port0_text[] = { + "RX_MIX_TX0", "DEC0" +}; + +static const char *const wdma3_port1_text[] = { + "RX_MIX_TX1", "DEC1" +}; + +static const char *const wdma3_port2_text[] = { + "RX_MIX_TX2", "DEC2" +}; + +static const char *const wdma3_port3_text[] = { + "RX_MIX_TX3", "DEC3" +}; + +static const char *const wdma3_port4_text[] = { + "RX_MIX_TX4", "DEC4" +}; + +static const char *const wdma3_port5_text[] = { + "RX_MIX_TX5", "DEC5" +}; + +static const char *const wdma3_port6_text[] = { + "RX_MIX_TX6", "DEC6" +}; + +static const char *const wdma3_ch_text[] = { + "PORT_0", "PORT_1", "PORT_2", "PORT_3", "PORT_4", + "PORT_5", "PORT_6", "PORT_7", "PORT_8", +}; + +static const struct snd_kcontrol_new aif4_vi_mixer[] = { + SOC_SINGLE_EXT("SPKR_VI_1", SND_SOC_NOPM, WCD9360_TX14, 1, 0, + pahu_vi_feed_mixer_get, pahu_vi_feed_mixer_put), + SOC_SINGLE_EXT("SPKR_VI_2", SND_SOC_NOPM, WCD9360_TX15, 1, 0, + pahu_vi_feed_mixer_get, pahu_vi_feed_mixer_put), +}; + +static const struct snd_kcontrol_new aif1_cap_mixer[] = { + SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9360_TX0, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9360_TX1, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9360_TX2, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9360_TX3, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9360_TX4, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9360_TX5, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9360_TX6, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9360_TX7, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9360_TX8, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD9360_TX9, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD9360_TX10, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD9360_TX11, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9360_TX13, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), +}; + +static const struct snd_kcontrol_new aif2_cap_mixer[] = { + SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9360_TX0, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9360_TX1, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9360_TX2, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9360_TX3, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9360_TX4, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9360_TX5, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9360_TX6, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9360_TX7, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9360_TX8, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD9360_TX9, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD9360_TX10, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD9360_TX11, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9360_TX13, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), +}; + +static const struct snd_kcontrol_new aif3_cap_mixer[] = { + SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9360_TX0, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9360_TX1, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9360_TX2, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9360_TX3, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9360_TX4, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9360_TX5, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9360_TX6, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9360_TX7, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9360_TX8, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD9360_TX9, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD9360_TX10, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD9360_TX11, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), + SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9360_TX13, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), +}; + +static const struct snd_kcontrol_new aif4_mad_mixer[] = { + SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9360_TX13, 1, 0, + slim_tx_mixer_get, slim_tx_mixer_put), +}; + +WCD_DAPM_ENUM_EXT(slim_rx0, SND_SOC_NOPM, 0, slim_rx_mux_text, + slim_rx_mux_get, slim_rx_mux_put); +WCD_DAPM_ENUM_EXT(slim_rx1, SND_SOC_NOPM, 0, slim_rx_mux_text, + slim_rx_mux_get, slim_rx_mux_put); +WCD_DAPM_ENUM_EXT(slim_rx2, SND_SOC_NOPM, 0, slim_rx_mux_text, + slim_rx_mux_get, slim_rx_mux_put); +WCD_DAPM_ENUM_EXT(slim_rx3, SND_SOC_NOPM, 0, slim_rx_mux_text, + slim_rx_mux_get, slim_rx_mux_put); +WCD_DAPM_ENUM_EXT(slim_rx4, SND_SOC_NOPM, 0, slim_rx_mux_text, + slim_rx_mux_get, slim_rx_mux_put); +WCD_DAPM_ENUM_EXT(slim_rx5, SND_SOC_NOPM, 0, slim_rx_mux_text, + slim_rx_mux_get, slim_rx_mux_put); +WCD_DAPM_ENUM_EXT(slim_rx6, SND_SOC_NOPM, 0, slim_rx_mux_text, + slim_rx_mux_get, slim_rx_mux_put); +WCD_DAPM_ENUM_EXT(slim_rx7, SND_SOC_NOPM, 0, slim_rx_mux_text, + slim_rx_mux_get, slim_rx_mux_put); + +WCD_DAPM_ENUM(cdc_if_rx0, SND_SOC_NOPM, 0, cdc_if_rx0_mux_text); +WCD_DAPM_ENUM(cdc_if_rx1, SND_SOC_NOPM, 0, cdc_if_rx1_mux_text); +WCD_DAPM_ENUM(cdc_if_rx2, SND_SOC_NOPM, 0, cdc_if_rx2_mux_text); +WCD_DAPM_ENUM(cdc_if_rx3, SND_SOC_NOPM, 0, cdc_if_rx3_mux_text); +WCD_DAPM_ENUM(cdc_if_rx4, SND_SOC_NOPM, 0, cdc_if_rx4_mux_text); +WCD_DAPM_ENUM(cdc_if_rx5, SND_SOC_NOPM, 0, cdc_if_rx5_mux_text); +WCD_DAPM_ENUM(cdc_if_rx6, SND_SOC_NOPM, 0, cdc_if_rx6_mux_text); +WCD_DAPM_ENUM(cdc_if_rx7, SND_SOC_NOPM, 0, cdc_if_rx7_mux_text); + +WCD_DAPM_ENUM(rx_int0_2, WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, + rx_int0_7_mix_mux_text); +WCD_DAPM_ENUM(rx_int7_2, WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1, 0, + rx_int0_7_mix_mux_text); +WCD_DAPM_ENUM(rx_int8_2, WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1, 0, + rx_int_mix_mux_text); +WCD_DAPM_ENUM(rx_int9_2, WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1, 0, + rx_int0_7_mix_mux_text); + +WCD_DAPM_ENUM(rx_int0_1_mix_inp0, WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0, 0, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int0_1_mix_inp1, WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int0_1_mix_inp2, WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int7_1_mix_inp0, WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0, 0, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int7_1_mix_inp1, WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int7_1_mix_inp2, WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int8_1_mix_inp0, WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0, 0, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int8_1_mix_inp1, WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int8_1_mix_inp2, WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int9_1_mix_inp0, WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0, 0, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int9_1_mix_inp1, WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0, 4, + rx_prim_mix_text); +WCD_DAPM_ENUM(rx_int9_1_mix_inp2, WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1, 4, + rx_prim_mix_text); + +WCD_DAPM_ENUM(rx_int0_mix2_inp, WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0, + rx_sidetone_mix_text); +WCD_DAPM_ENUM(rx_int7_mix2_inp, WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 2, + rx_sidetone_mix_text); +WCD_DAPM_ENUM(rx_int9_mix2_inp, WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 4, + rx_sidetone_mix_text); + +WCD_DAPM_ENUM(tx_adc_mux10, WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 4, + adc_mux_text); +WCD_DAPM_ENUM(tx_adc_mux11, WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 4, + adc_mux_text); + +WCD_DAPM_ENUM(tx_dmic_mux0, WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux1, WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux2, WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux3, WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux4, WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux5, WCD9360_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux6, WCD9360_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux7, WCD9360_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux8, WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux10, WCD9360_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 3, + dmic_mux_text); +WCD_DAPM_ENUM(tx_dmic_mux11, WCD9360_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 3, + dmic_mux_text); + +WCD_DAPM_ENUM(tx_amic_mux0, WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux1, WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux2, WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux3, WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux4, WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux5, WCD9360_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux6, WCD9360_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux7, WCD9360_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux8, WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux10, WCD9360_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0, + amic_mux_text); +WCD_DAPM_ENUM(tx_amic_mux11, WCD9360_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0, + amic_mux_text); + +WCD_DAPM_ENUM(tx_adc2_in, WCD9360_ANA_AMIC_INPUT_SWITCH_CTL, 7, adc2_in_text); +WCD_DAPM_ENUM(tx_adc4_in, WCD9360_ANA_AMIC_INPUT_SWITCH_CTL, 6, adc4_in_text); + +WCD_DAPM_ENUM(cdc_if_tx0, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0, 0, + cdc_if_tx0_mux_text); +WCD_DAPM_ENUM(cdc_if_tx1, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0, 2, + cdc_if_tx1_mux_text); +WCD_DAPM_ENUM(cdc_if_tx2, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0, 4, + cdc_if_tx2_mux_text); +WCD_DAPM_ENUM(cdc_if_tx3, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0, 6, + cdc_if_tx3_mux_text); +WCD_DAPM_ENUM(cdc_if_tx4, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1, 0, + cdc_if_tx4_mux_text); +WCD_DAPM_ENUM(cdc_if_tx5, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1, 2, + cdc_if_tx5_mux_text); +WCD_DAPM_ENUM(cdc_if_tx6, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1, 4, + cdc_if_tx6_mux_text); +WCD_DAPM_ENUM(cdc_if_tx7, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1, 6, + cdc_if_tx7_mux_text); +WCD_DAPM_ENUM(cdc_if_tx8, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2, 0, + cdc_if_tx8_mux_text); +WCD_DAPM_ENUM(cdc_if_tx9, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2, 2, + cdc_if_tx9_mux_text); +WCD_DAPM_ENUM(cdc_if_tx10, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2, 4, + cdc_if_tx10_mux_text); +WCD_DAPM_ENUM(cdc_if_tx11_inp1, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3, 0, + cdc_if_tx11_inp1_mux_text); +WCD_DAPM_ENUM(cdc_if_tx11, WCD9360_DATA_HUB_SB_TX11_INP_CFG, 0, + cdc_if_tx11_mux_text); +WCD_DAPM_ENUM(cdc_if_tx13_inp1, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3, 4, + cdc_if_tx13_inp1_mux_text); +WCD_DAPM_ENUM(cdc_if_tx13, WCD9360_DATA_HUB_SB_TX13_INP_CFG, 0, + cdc_if_tx13_mux_text); + +WCD_DAPM_ENUM(rx_mix_tx0, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG0, 0, + rx_echo_mux_text); +WCD_DAPM_ENUM(rx_mix_tx1, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG0, 4, + rx_echo_mux_text); +WCD_DAPM_ENUM(rx_mix_tx2, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG1, 0, + rx_echo_mux_text); +WCD_DAPM_ENUM(rx_mix_tx3, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG1, 4, + rx_echo_mux_text); +WCD_DAPM_ENUM(rx_mix_tx4, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG2, 0, + rx_echo_mux_text); +WCD_DAPM_ENUM(rx_mix_tx5, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG2, 4, + rx_echo_mux_text); +WCD_DAPM_ENUM(rx_mix_tx6, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG3, 0, + rx_echo_mux_text); +WCD_DAPM_ENUM(rx_mix_tx7, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG3, 4, + rx_echo_mux_text); +WCD_DAPM_ENUM(rx_mix_tx8, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, + rx_echo_mux_text); + +WCD_DAPM_ENUM(iir0_inp0, WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0, + iir_inp_mux_text); +WCD_DAPM_ENUM(iir0_inp1, WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1, 0, + iir_inp_mux_text); +WCD_DAPM_ENUM(iir0_inp2, WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2, 0, + iir_inp_mux_text); +WCD_DAPM_ENUM(iir0_inp3, WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3, 0, + iir_inp_mux_text); + +WCD_DAPM_ENUM(rx_int0_1_interp, SND_SOC_NOPM, 0, rx_int0_1_interp_mux_text); +WCD_DAPM_ENUM(rx_int7_1_interp, SND_SOC_NOPM, 0, rx_int7_1_interp_mux_text); +WCD_DAPM_ENUM(rx_int8_1_interp, SND_SOC_NOPM, 0, rx_int8_1_interp_mux_text); +WCD_DAPM_ENUM(rx_int9_1_interp, SND_SOC_NOPM, 0, rx_int9_1_interp_mux_text); + +WCD_DAPM_ENUM(rx_int0_2_interp, SND_SOC_NOPM, 0, rx_int0_2_interp_mux_text); +WCD_DAPM_ENUM(rx_int7_2_interp, SND_SOC_NOPM, 0, rx_int7_2_interp_mux_text); +WCD_DAPM_ENUM(rx_int8_2_interp, SND_SOC_NOPM, 0, rx_int8_2_interp_mux_text); +WCD_DAPM_ENUM(rx_int9_2_interp, SND_SOC_NOPM, 0, rx_int9_2_interp_mux_text); + +WCD_DAPM_ENUM(mad_sel, WCD9360_CPE_SS_SVA_CFG, 0, + mad_sel_txt); + +WCD_DAPM_ENUM(mad_inp_mux, WCD9360_CPE_SS_SVA_CFG, 2, + mad_inp_mux_txt); + +WCD_DAPM_ENUM_EXT(rx_int0_dem_inp, WCD9360_CDC_RX0_RX_PATH_SEC0, 0, + rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double, + pahu_int_dem_inp_mux_put); + +WCD_DAPM_ENUM_EXT(rx_int9_dem_inp, WCD9360_CDC_RX9_RX_PATH_SEC0, 0, + rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double, + pahu_int_dem_inp_mux_put); + +WCD_DAPM_ENUM_EXT(tx_adc_mux0, WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0, + adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); +WCD_DAPM_ENUM_EXT(tx_adc_mux1, WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0, + adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); +WCD_DAPM_ENUM_EXT(tx_adc_mux2, WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0, + adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); +WCD_DAPM_ENUM_EXT(tx_adc_mux3, WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0, + adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); +WCD_DAPM_ENUM_EXT(tx_adc_mux4, WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 2, + adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); +WCD_DAPM_ENUM_EXT(tx_adc_mux5, WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 2, + adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); +WCD_DAPM_ENUM_EXT(tx_adc_mux6, WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 2, + adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); +WCD_DAPM_ENUM_EXT(tx_adc_mux7, WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 2, + adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); +WCD_DAPM_ENUM_EXT(tx_adc_mux8, WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 4, + adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); + +WCD_DAPM_ENUM(asrc2, WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 4, + asrc2_mux_text); +WCD_DAPM_ENUM(asrc3, WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 6, + asrc3_mux_text); + +WCD_DAPM_ENUM(int7_2_native, SND_SOC_NOPM, 0, native_mux_text); +WCD_DAPM_ENUM(int8_2_native, SND_SOC_NOPM, 0, native_mux_text); + +WCD_DAPM_ENUM(anc0_fb, WCD9360_CDC_RX_INP_MUX_ANC_CFG0, 0, anc0_fb_mux_text); + +WCD_DAPM_ENUM(wdma3_port0, WCD9360_DMA_WDMA3_PRT_CFG, 0, wdma3_port0_text); +WCD_DAPM_ENUM(wdma3_port1, WCD9360_DMA_WDMA3_PRT_CFG, 1, wdma3_port1_text); +WCD_DAPM_ENUM(wdma3_port2, WCD9360_DMA_WDMA3_PRT_CFG, 2, wdma3_port2_text); +WCD_DAPM_ENUM(wdma3_port3, WCD9360_DMA_WDMA3_PRT_CFG, 3, wdma3_port3_text); +WCD_DAPM_ENUM(wdma3_port4, WCD9360_DMA_WDMA3_PRT_CFG, 4, wdma3_port4_text); +WCD_DAPM_ENUM(wdma3_port5, WCD9360_DMA_WDMA3_PRT_CFG, 5, wdma3_port5_text); +WCD_DAPM_ENUM(wdma3_port6, WCD9360_DMA_WDMA3_PRT_CFG, 6, wdma3_port6_text); + +WCD_DAPM_ENUM(wdma3_ch0, WCD9360_DMA_CH_0_1_CFG_WDMA_3, 0, wdma3_ch_text); +WCD_DAPM_ENUM(wdma3_ch1, WCD9360_DMA_CH_0_1_CFG_WDMA_3, 4, wdma3_ch_text); +WCD_DAPM_ENUM(wdma3_ch2, WCD9360_DMA_CH_2_3_CFG_WDMA_3, 0, wdma3_ch_text); +WCD_DAPM_ENUM(wdma3_ch3, WCD9360_DMA_CH_2_3_CFG_WDMA_3, 4, wdma3_ch_text); + +static const struct snd_kcontrol_new anc_ear_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new anc_ear_spkr_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new anc_spkr_pa_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new mad_cpe1_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new mad_cpe2_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new mad_brdcst_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux0_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux1_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux2_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux3_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux4_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux5_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux6_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux7_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new adc_us_mux8_switch = + SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new wdma3_onoff_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_soc_dapm_widget pahu_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM, + AIF1_PB, 0, pahu_codec_enable_slimrx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM, + AIF2_PB, 0, pahu_codec_enable_slimrx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM, + AIF3_PB, 0, pahu_codec_enable_slimrx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM, + AIF4_PB, 0, pahu_codec_enable_slimrx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + WCD_DAPM_MUX("SLIM RX0 MUX", WCD9360_RX0, slim_rx0), + WCD_DAPM_MUX("SLIM RX1 MUX", WCD9360_RX1, slim_rx1), + WCD_DAPM_MUX("SLIM RX2 MUX", WCD9360_RX2, slim_rx2), + WCD_DAPM_MUX("SLIM RX3 MUX", WCD9360_RX3, slim_rx3), + WCD_DAPM_MUX("SLIM RX4 MUX", WCD9360_RX4, slim_rx4), + WCD_DAPM_MUX("SLIM RX5 MUX", WCD9360_RX5, slim_rx5), + WCD_DAPM_MUX("SLIM RX6 MUX", WCD9360_RX6, slim_rx6), + WCD_DAPM_MUX("SLIM RX7 MUX", WCD9360_RX7, slim_rx7), + + SND_SOC_DAPM_MIXER("SLIM RX0", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0), + + WCD_DAPM_MUX("CDC_IF RX0 MUX", WCD9360_RX0, cdc_if_rx0), + WCD_DAPM_MUX("CDC_IF RX1 MUX", WCD9360_RX1, cdc_if_rx1), + WCD_DAPM_MUX("CDC_IF RX2 MUX", WCD9360_RX2, cdc_if_rx2), + WCD_DAPM_MUX("CDC_IF RX3 MUX", WCD9360_RX3, cdc_if_rx3), + WCD_DAPM_MUX("CDC_IF RX4 MUX", WCD9360_RX4, cdc_if_rx4), + WCD_DAPM_MUX("CDC_IF RX5 MUX", WCD9360_RX5, cdc_if_rx5), + WCD_DAPM_MUX("CDC_IF RX6 MUX", WCD9360_RX6, cdc_if_rx6), + WCD_DAPM_MUX("CDC_IF RX7 MUX", WCD9360_RX7, cdc_if_rx7), + + SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", SND_SOC_NOPM, INTERP_EAR, 0, + &rx_int0_2_mux, pahu_codec_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT7_2 MUX", SND_SOC_NOPM, INTERP_SPKR1, 0, + &rx_int7_2_mux, pahu_codec_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT8_2 MUX", SND_SOC_NOPM, INTERP_SPKR2, 0, + &rx_int8_2_mux, pahu_codec_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT9_2 MUX", SND_SOC_NOPM, INTERP_AUX, 0, + &rx_int9_2_mux, pahu_codec_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + WCD_DAPM_MUX("RX INT0_1 MIX1 INP0", 0, rx_int0_1_mix_inp0), + WCD_DAPM_MUX("RX INT0_1 MIX1 INP1", 0, rx_int0_1_mix_inp1), + WCD_DAPM_MUX("RX INT0_1 MIX1 INP2", 0, rx_int0_1_mix_inp2), + + SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, + &rx_int7_1_mix_inp0_mux, pahu_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx_int7_1_mix_inp1_mux, pahu_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx_int7_1_mix_inp2_mux, pahu_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, + &rx_int8_1_mix_inp0_mux, pahu_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx_int8_1_mix_inp1_mux, pahu_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx_int8_1_mix_inp2_mux, pahu_codec_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + WCD_DAPM_MUX("RX INT9_1 MIX1 INP0", 0, rx_int9_1_mix_inp0), + WCD_DAPM_MUX("RX INT9_1 MIX1 INP1", 0, rx_int9_1_mix_inp1), + WCD_DAPM_MUX("RX INT9_1 MIX1 INP2", 0, rx_int9_1_mix_inp2), + + SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT7_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT7 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT8_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT8 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT9_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT9 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT7 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT9 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MIXER_E("RX INT7 CHAIN", SND_SOC_NOPM, 0, 0, + NULL, 0, pahu_codec_spk_boost_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX INT8 CHAIN", SND_SOC_NOPM, 0, 0, + NULL, 0, pahu_codec_spk_boost_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("RX INT0 MIX2 INP", SND_SOC_NOPM, INTERP_EAR, + 0, &rx_int0_mix2_inp_mux, pahu_codec_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT7 MIX2 INP", SND_SOC_NOPM, INTERP_SPKR1, + 0, &rx_int7_mix2_inp_mux, pahu_codec_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT9 MIX2 INP", SND_SOC_NOPM, INTERP_AUX, + 0, &rx_int9_mix2_inp_mux, pahu_codec_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + WCD_DAPM_MUX("CDC_IF TX0 MUX", WCD9360_TX0, cdc_if_tx0), + WCD_DAPM_MUX("CDC_IF TX1 MUX", WCD9360_TX1, cdc_if_tx1), + WCD_DAPM_MUX("CDC_IF TX2 MUX", WCD9360_TX2, cdc_if_tx2), + WCD_DAPM_MUX("CDC_IF TX3 MUX", WCD9360_TX3, cdc_if_tx3), + WCD_DAPM_MUX("CDC_IF TX4 MUX", WCD9360_TX4, cdc_if_tx4), + WCD_DAPM_MUX("CDC_IF TX5 MUX", WCD9360_TX5, cdc_if_tx5), + WCD_DAPM_MUX("CDC_IF TX6 MUX", WCD9360_TX6, cdc_if_tx6), + WCD_DAPM_MUX("CDC_IF TX7 MUX", WCD9360_TX7, cdc_if_tx7), + WCD_DAPM_MUX("CDC_IF TX8 MUX", WCD9360_TX8, cdc_if_tx8), + WCD_DAPM_MUX("CDC_IF TX9 MUX", WCD9360_TX9, cdc_if_tx9), + WCD_DAPM_MUX("CDC_IF TX10 MUX", WCD9360_TX10, cdc_if_tx10), + WCD_DAPM_MUX("CDC_IF TX11 MUX", WCD9360_TX11, cdc_if_tx11), + WCD_DAPM_MUX("CDC_IF TX11 INP1 MUX", WCD9360_TX11, cdc_if_tx11_inp1), + WCD_DAPM_MUX("CDC_IF TX13 MUX", WCD9360_TX13, cdc_if_tx13), + WCD_DAPM_MUX("CDC_IF TX13 INP1 MUX", WCD9360_TX13, cdc_if_tx13_inp1), + + SND_SOC_DAPM_MUX_E("ADC MUX0", WCD9360_CDC_TX0_TX_PATH_CTL, 5, 0, + &tx_adc_mux0_mux, pahu_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX1", WCD9360_CDC_TX1_TX_PATH_CTL, 5, 0, + &tx_adc_mux1_mux, pahu_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX2", WCD9360_CDC_TX2_TX_PATH_CTL, 5, 0, + &tx_adc_mux2_mux, pahu_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX3", WCD9360_CDC_TX3_TX_PATH_CTL, 5, 0, + &tx_adc_mux3_mux, pahu_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX4", WCD9360_CDC_TX4_TX_PATH_CTL, 5, 0, + &tx_adc_mux4_mux, pahu_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX5", WCD9360_CDC_TX5_TX_PATH_CTL, 5, 0, + &tx_adc_mux5_mux, pahu_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX6", WCD9360_CDC_TX6_TX_PATH_CTL, 5, 0, + &tx_adc_mux6_mux, pahu_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX7", WCD9360_CDC_TX7_TX_PATH_CTL, 5, 0, + &tx_adc_mux7_mux, pahu_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX8", WCD9360_CDC_TX8_TX_PATH_CTL, 5, 0, + &tx_adc_mux8_mux, pahu_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("ADC MUX10", SND_SOC_NOPM, 10, 0, &tx_adc_mux10_mux, + pahu_codec_tx_adc_cfg, SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_MUX_E("ADC MUX11", SND_SOC_NOPM, 11, 0, &tx_adc_mux11_mux, + pahu_codec_tx_adc_cfg, SND_SOC_DAPM_POST_PMU), + + WCD_DAPM_MUX("DMIC MUX0", 0, tx_dmic_mux0), + WCD_DAPM_MUX("DMIC MUX1", 0, tx_dmic_mux1), + WCD_DAPM_MUX("DMIC MUX2", 0, tx_dmic_mux2), + WCD_DAPM_MUX("DMIC MUX3", 0, tx_dmic_mux3), + WCD_DAPM_MUX("DMIC MUX4", 0, tx_dmic_mux4), + WCD_DAPM_MUX("DMIC MUX5", 0, tx_dmic_mux5), + WCD_DAPM_MUX("DMIC MUX6", 0, tx_dmic_mux6), + WCD_DAPM_MUX("DMIC MUX7", 0, tx_dmic_mux7), + WCD_DAPM_MUX("DMIC MUX8", 0, tx_dmic_mux8), + WCD_DAPM_MUX("DMIC MUX10", 0, tx_dmic_mux10), + WCD_DAPM_MUX("DMIC MUX11", 0, tx_dmic_mux11), + + WCD_DAPM_MUX("AMIC MUX0", 0, tx_amic_mux0), + WCD_DAPM_MUX("AMIC MUX1", 0, tx_amic_mux1), + WCD_DAPM_MUX("AMIC MUX2", 0, tx_amic_mux2), + WCD_DAPM_MUX("AMIC MUX3", 0, tx_amic_mux3), + WCD_DAPM_MUX("AMIC MUX4", 0, tx_amic_mux4), + WCD_DAPM_MUX("AMIC MUX5", 0, tx_amic_mux5), + WCD_DAPM_MUX("AMIC MUX6", 0, tx_amic_mux6), + WCD_DAPM_MUX("AMIC MUX7", 0, tx_amic_mux7), + WCD_DAPM_MUX("AMIC MUX8", 0, tx_amic_mux8), + WCD_DAPM_MUX("AMIC MUX10", 0, tx_amic_mux10), + WCD_DAPM_MUX("AMIC MUX11", 0, tx_amic_mux11), + + SND_SOC_DAPM_ADC_E("ADC1", NULL, WCD9360_ANA_AMIC1, 7, 0, + pahu_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_ADC_E("ADC2", NULL, WCD9360_ANA_AMIC2, 7, 0, + pahu_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_ADC_E("ADC3", NULL, WCD9360_ANA_AMIC3, 7, 0, + pahu_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_ADC_E("ADC4", NULL, WCD9360_ANA_AMIC4, 7, 0, + pahu_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + + WCD_DAPM_MUX("ANC0 FB MUX", 0, anc0_fb), + + WCD_DAPM_MUX("ADC2_IN", 0, tx_adc2_in), + WCD_DAPM_MUX("ADC4_IN", 0, tx_adc4_in), + + SND_SOC_DAPM_INPUT("AMIC1"), + SND_SOC_DAPM_INPUT("AMIC2"), + SND_SOC_DAPM_INPUT("AMIC3"), + SND_SOC_DAPM_INPUT("AMIC4"), + + SND_SOC_DAPM_MICBIAS_E("MIC BIAS1", SND_SOC_NOPM, 0, 0, + pahu_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS2", SND_SOC_NOPM, 0, 0, + pahu_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS3", SND_SOC_NOPM, 0, 0, + pahu_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS4", SND_SOC_NOPM, 0, 0, + pahu_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS1_STANDALONE, SND_SOC_NOPM, 0, 0, + pahu_codec_force_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS2_STANDALONE, SND_SOC_NOPM, 0, 0, + pahu_codec_force_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS3_STANDALONE, SND_SOC_NOPM, 0, 0, + pahu_codec_force_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS4_STANDALONE, SND_SOC_NOPM, 0, 0, + pahu_codec_force_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM, + AIF1_CAP, 0, pahu_codec_enable_slimtx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM, + AIF2_CAP, 0, pahu_codec_enable_slimtx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM, + AIF3_CAP, 0, pahu_codec_enable_slimtx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0, + aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)), + SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0, + aif2_cap_mixer, ARRAY_SIZE(aif2_cap_mixer)), + SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0, + aif3_cap_mixer, ARRAY_SIZE(aif3_cap_mixer)), + SND_SOC_DAPM_MIXER("AIF4_MAD Mixer", SND_SOC_NOPM, AIF4_MAD_TX, 0, + aif4_mad_mixer, ARRAY_SIZE(aif4_mad_mixer)), + + SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM, + AIF4_VIFEED, 0, pahu_codec_enable_slimvi_feedback, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_AIF_OUT("AIF4 MAD", "AIF4 MAD TX", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_MIXER("AIF4_VI Mixer", SND_SOC_NOPM, AIF4_VIFEED, 0, + aif4_vi_mixer, ARRAY_SIZE(aif4_vi_mixer)), + SND_SOC_DAPM_INPUT("VIINPUT"), + + SND_SOC_DAPM_MIXER("SLIM TX0", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX3", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX4", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX5", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX6", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX7", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX8", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX9", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX10", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX11", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SLIM TX13", SND_SOC_NOPM, 0, 0, NULL, 0), + + /* Digital Mic Inputs */ + SND_SOC_DAPM_ADC_E("DMIC0", NULL, SND_SOC_NOPM, 0, 0, + pahu_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 1, 0, + pahu_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 2, 0, + pahu_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 3, 0, + pahu_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 4, 0, + pahu_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 5, 0, + pahu_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 6, 0, + pahu_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC7", NULL, SND_SOC_NOPM, 7, 0, + pahu_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + WCD_DAPM_MUX("IIR0 INP0 MUX", 0, iir0_inp0), + WCD_DAPM_MUX("IIR0 INP1 MUX", 0, iir0_inp1), + WCD_DAPM_MUX("IIR0 INP2 MUX", 0, iir0_inp2), + WCD_DAPM_MUX("IIR0 INP3 MUX", 0, iir0_inp3), + + SND_SOC_DAPM_MIXER_E("IIR0", WCD9360_CDC_SIDETONE_IIR0_IIR_PATH_CTL, + 4, 0, NULL, 0, pahu_codec_set_iir_gain, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_MIXER("SRC0", WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL, + 4, 0, NULL, 0), + + WCD_DAPM_MUX("RX MIX TX0 MUX", 0, rx_mix_tx0), + WCD_DAPM_MUX("RX MIX TX1 MUX", 0, rx_mix_tx1), + WCD_DAPM_MUX("RX MIX TX2 MUX", 0, rx_mix_tx2), + WCD_DAPM_MUX("RX MIX TX3 MUX", 0, rx_mix_tx3), + WCD_DAPM_MUX("RX MIX TX4 MUX", 0, rx_mix_tx4), + WCD_DAPM_MUX("RX MIX TX5 MUX", 0, rx_mix_tx5), + WCD_DAPM_MUX("RX MIX TX6 MUX", 0, rx_mix_tx6), + WCD_DAPM_MUX("RX MIX TX7 MUX", 0, rx_mix_tx7), + WCD_DAPM_MUX("RX MIX TX8 MUX", 0, rx_mix_tx8), + WCD_DAPM_MUX("RX INT0 DEM MUX", 0, rx_int0_dem_inp), + WCD_DAPM_MUX("RX INT9 DEM MUX", 0, rx_int9_dem_inp), + + SND_SOC_DAPM_MUX_E("RX INT0_1 INTERP", SND_SOC_NOPM, INTERP_EAR, 0, + &rx_int0_1_interp_mux, pahu_codec_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT7_1 INTERP", SND_SOC_NOPM, INTERP_SPKR1, 0, + &rx_int7_1_interp_mux, pahu_codec_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT8_1 INTERP", SND_SOC_NOPM, INTERP_SPKR2, 0, + &rx_int8_1_interp_mux, pahu_codec_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT9_1 INTERP", SND_SOC_NOPM, INTERP_AUX, 0, + &rx_int9_1_interp_mux, pahu_codec_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + WCD_DAPM_MUX("RX INT0_2 INTERP", 0, rx_int0_2_interp), + WCD_DAPM_MUX("RX INT7_2 INTERP", 0, rx_int7_2_interp), + WCD_DAPM_MUX("RX INT8_2 INTERP", 0, rx_int8_2_interp), + WCD_DAPM_MUX("RX INT9_2 INTERP", 0, rx_int9_2_interp), + + SND_SOC_DAPM_SWITCH("ADC US MUX0", WCD9360_CDC_TX0_TX_PATH_192_CTL, 0, + 0, &adc_us_mux0_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX1", WCD9360_CDC_TX1_TX_PATH_192_CTL, 0, + 0, &adc_us_mux1_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX2", WCD9360_CDC_TX2_TX_PATH_192_CTL, 0, + 0, &adc_us_mux2_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX3", WCD9360_CDC_TX3_TX_PATH_192_CTL, 0, + 0, &adc_us_mux3_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX4", WCD9360_CDC_TX4_TX_PATH_192_CTL, 0, + 0, &adc_us_mux4_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX5", WCD9360_CDC_TX5_TX_PATH_192_CTL, 0, + 0, &adc_us_mux5_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX6", WCD9360_CDC_TX6_TX_PATH_192_CTL, 0, + 0, &adc_us_mux6_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX7", WCD9360_CDC_TX7_TX_PATH_192_CTL, 0, + 0, &adc_us_mux7_switch), + SND_SOC_DAPM_SWITCH("ADC US MUX8", WCD9360_CDC_TX8_TX_PATH_192_CTL, 0, + 0, &adc_us_mux8_switch), + + /* MAD related widgets */ + SND_SOC_DAPM_INPUT("MAD_CPE_INPUT"), + SND_SOC_DAPM_INPUT("MADINPUT"), + + WCD_DAPM_MUX("MAD_SEL MUX", 0, mad_sel), + WCD_DAPM_MUX("MAD_INP MUX", 0, mad_inp_mux), + + SND_SOC_DAPM_SWITCH_E("MAD_BROADCAST", SND_SOC_NOPM, 0, 0, + &mad_brdcst_switch, pahu_codec_ape_enable_mad, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_SWITCH_E("MAD_CPE1", SND_SOC_NOPM, 0, 0, + &mad_cpe1_switch, pahu_codec_cpe_mad_ctl, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SWITCH_E("MAD_CPE2", SND_SOC_NOPM, 0, 0, + &mad_cpe2_switch, pahu_codec_cpe_mad_ctl, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_OUTPUT("MAD_CPE_OUT1"), + SND_SOC_DAPM_OUTPUT("MAD_CPE_OUT2"), + + SND_SOC_DAPM_DAC_E("RX INT0 DAC", NULL, SND_SOC_NOPM, + 0, 0, pahu_codec_ear_dac_event, SND_SOC_DAPM_PRE_PMU), + + SND_SOC_DAPM_PGA_E("EAR PA", WCD9360_ANA_EAR, 7, 0, NULL, 0, + pahu_codec_enable_ear_pa, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("ANC EAR PA", WCD9360_ANA_EAR, 7, 0, NULL, 0, + pahu_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("ANC SPK1 PA", SND_SOC_NOPM, 0, 0, NULL, 0, + pahu_codec_enable_spkr_anc, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_OUTPUT("EAR"), + SND_SOC_DAPM_OUTPUT("SPK1 OUT"), + SND_SOC_DAPM_OUTPUT("SPK2 OUT"), + SND_SOC_DAPM_OUTPUT("ANC EAR"), + + SND_SOC_DAPM_SWITCH("ANC OUT EAR Enable", SND_SOC_NOPM, 0, 0, + &anc_ear_switch), + SND_SOC_DAPM_SWITCH("ANC OUT EAR SPKR Enable", SND_SOC_NOPM, 0, 0, + &anc_ear_spkr_switch), + SND_SOC_DAPM_SWITCH("ANC SPKR PA Enable", SND_SOC_NOPM, 0, 0, + &anc_spkr_pa_switch), + + SND_SOC_DAPM_DAC("RX INT9 DAC", NULL, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_PGA_E("AUX PA", WCD9360_AUX_ANA_EAR, 7, 0, NULL, 0, + pahu_codec_enable_aux_pa, SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_OUTPUT("AUX"), + + + SND_SOC_DAPM_SUPPLY("LDO_RXTX", SND_SOC_NOPM, 0, 0, + pahu_codec_enable_ldo_rxtx, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("RX INT7 NATIVE SUPPLY", SND_SOC_NOPM, + INTERP_SPKR1, 0, pahu_enable_native_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SUPPLY("RX INT8 NATIVE SUPPLY", SND_SOC_NOPM, + INTERP_SPKR2, 0, pahu_enable_native_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + WCD_DAPM_MUX("RX INT7_2 NATIVE MUX", 0, int7_2_native), + WCD_DAPM_MUX("RX INT8_2 NATIVE MUX", 0, int8_2_native), + + SND_SOC_DAPM_MUX_E("ASRC2 MUX", SND_SOC_NOPM, ASRC2, 0, + &asrc2_mux, pahu_codec_enable_asrc_resampler, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("ASRC3 MUX", SND_SOC_NOPM, ASRC3, 0, + &asrc3_mux, pahu_codec_enable_asrc_resampler, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /* WDMA3 widgets */ + WCD_DAPM_MUX("WDMA3 PORT0 MUX", 0, wdma3_port0), + WCD_DAPM_MUX("WDMA3 PORT1 MUX", 1, wdma3_port1), + WCD_DAPM_MUX("WDMA3 PORT2 MUX", 2, wdma3_port2), + WCD_DAPM_MUX("WDMA3 PORT3 MUX", 3, wdma3_port3), + WCD_DAPM_MUX("WDMA3 PORT4 MUX", 4, wdma3_port4), + WCD_DAPM_MUX("WDMA3 PORT5 MUX", 5, wdma3_port5), + WCD_DAPM_MUX("WDMA3 PORT6 MUX", 6, wdma3_port6), + + WCD_DAPM_MUX("WDMA3 CH0 MUX", 0, wdma3_ch0), + WCD_DAPM_MUX("WDMA3 CH1 MUX", 4, wdma3_ch1), + WCD_DAPM_MUX("WDMA3 CH2 MUX", 0, wdma3_ch2), + WCD_DAPM_MUX("WDMA3 CH3 MUX", 4, wdma3_ch3), + + SND_SOC_DAPM_MIXER("WDMA3_CH_MIXER", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_SWITCH_E("WDMA3_ON_OFF", SND_SOC_NOPM, 0, 0, + &wdma3_onoff_switch, pahu_codec_wdma3_ctl, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_OUTPUT("WDMA3_OUT"), +}; + +static int pahu_get_channel_map(struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot) +{ + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(dai->codec); + u32 i = 0; + struct wcd9xxx_ch *ch; + int ret = 0; + + switch (dai->id) { + case AIF1_PB: + case AIF2_PB: + case AIF3_PB: + case AIF4_PB: + if (!rx_slot || !rx_num) { + dev_err(pahu->dev, "%s: Invalid rx_slot 0x%pK or rx_num 0x%pK\n", + __func__, rx_slot, rx_num); + ret = -EINVAL; + break; + } + list_for_each_entry(ch, &pahu->dai[dai->id].wcd9xxx_ch_list, + list) { + dev_dbg(pahu->dev, "%s: slot_num %u ch->ch_num %d\n", + __func__, i, ch->ch_num); + rx_slot[i++] = ch->ch_num; + } + *rx_num = i; + dev_dbg(pahu->dev, "%s: dai_name = %s dai_id = %x rx_num = %d\n", + __func__, dai->name, dai->id, i); + if (*rx_num == 0) { + dev_err(pahu->dev, "%s: Channel list empty for dai_name = %s dai_id = %x\n", + __func__, dai->name, dai->id); + ret = -EINVAL; + } + break; + case AIF1_CAP: + case AIF2_CAP: + case AIF3_CAP: + case AIF4_MAD_TX: + case AIF4_VIFEED: + if (!tx_slot || !tx_num) { + dev_err(pahu->dev, "%s: Invalid tx_slot 0x%pK or tx_num 0x%pK\n", + __func__, tx_slot, tx_num); + ret = -EINVAL; + break; + } + list_for_each_entry(ch, &pahu->dai[dai->id].wcd9xxx_ch_list, + list) { + dev_dbg(pahu->dev, "%s: slot_num %u ch->ch_num %d\n", + __func__, i, ch->ch_num); + tx_slot[i++] = ch->ch_num; + } + *tx_num = i; + dev_dbg(pahu->dev, "%s: dai_name = %s dai_id = %x tx_num = %d\n", + __func__, dai->name, dai->id, i); + if (*tx_num == 0) { + dev_err(pahu->dev, "%s: Channel list empty for dai_name = %s dai_id = %x\n", + __func__, dai->name, dai->id); + ret = -EINVAL; + } + break; + default: + dev_err(pahu->dev, "%s: Invalid DAI ID %x\n", + __func__, dai->id); + ret = -EINVAL; + break; + } + + return ret; +} + +static int pahu_set_channel_map(struct snd_soc_dai *dai, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot) +{ + struct pahu_priv *pahu; + struct wcd9xxx *core; + struct wcd9xxx_codec_dai_data *dai_data = NULL; + + pahu = snd_soc_codec_get_drvdata(dai->codec); + core = dev_get_drvdata(dai->codec->dev->parent); + + if (!tx_slot || !rx_slot) { + dev_err(pahu->dev, "%s: Invalid tx_slot 0x%pK, rx_slot 0x%pK\n", + __func__, tx_slot, rx_slot); + return -EINVAL; + } + dev_dbg(pahu->dev, "%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n", + __func__, dai->name, dai->id, tx_num, rx_num); + + wcd9xxx_init_slimslave(core, core->slim->laddr, + tx_num, tx_slot, rx_num, rx_slot); + /* Reserve TX13 for MAD data channel */ + dai_data = &pahu->dai[AIF4_MAD_TX]; + if (dai_data) + list_add_tail(&core->tx_chs[WCD9360_TX13].list, + &dai_data->wcd9xxx_ch_list); + + return 0; +} + +static int pahu_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + return 0; +} + +static void pahu_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); +} + +static int pahu_set_decimator_rate(struct snd_soc_dai *dai, + u32 sample_rate) +{ + struct snd_soc_codec *codec = dai->codec; + struct wcd9xxx_ch *ch; + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + u32 tx_port = 0, tx_fs_rate = 0; + u8 shift = 0, shift_val = 0, tx_mux_sel = 0; + int decimator = -1; + u16 tx_port_reg = 0, tx_fs_reg = 0; + + switch (sample_rate) { + case 8000: + tx_fs_rate = 0; + break; + case 16000: + tx_fs_rate = 1; + break; + case 32000: + tx_fs_rate = 3; + break; + case 48000: + tx_fs_rate = 4; + break; + case 96000: + tx_fs_rate = 5; + break; + case 192000: + tx_fs_rate = 6; + break; + default: + dev_err(pahu->dev, "%s: Invalid TX sample rate: %d\n", + __func__, sample_rate); + return -EINVAL; + + }; + + list_for_each_entry(ch, &pahu->dai[dai->id].wcd9xxx_ch_list, list) { + tx_port = ch->port; + dev_dbg(codec->dev, "%s: dai->id = %d, tx_port = %d", + __func__, dai->id, tx_port); + + if ((tx_port < 0) || (tx_port == 12) || (tx_port >= 14)) { + dev_err(codec->dev, "%s: Invalid SLIM TX%u port. DAI ID: %d\n", + __func__, tx_port, dai->id); + return -EINVAL; + } + /* Find the SB TX MUX input - which decimator is connected */ + if (tx_port < 4) { + tx_port_reg = WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0; + shift = (tx_port << 1); + shift_val = 0x03; + } else if ((tx_port >= 4) && (tx_port < 8)) { + tx_port_reg = WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1; + shift = ((tx_port - 4) << 1); + shift_val = 0x03; + } else if ((tx_port >= 8) && (tx_port < 11)) { + tx_port_reg = WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2; + shift = ((tx_port - 8) << 1); + shift_val = 0x03; + } else if (tx_port == 11) { + tx_port_reg = WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3; + shift = 0; + shift_val = 0x0F; + } else if (tx_port == 13) { + tx_port_reg = WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3; + shift = 4; + shift_val = 0x03; + } + tx_mux_sel = snd_soc_read(codec, tx_port_reg) & + (shift_val << shift); + tx_mux_sel = tx_mux_sel >> shift; + + if (tx_port <= 8) { + if ((tx_mux_sel == 0x2) || (tx_mux_sel == 0x3)) + decimator = tx_port; + } else if (tx_port <= 10) { + if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2)) + decimator = ((tx_port == 9) ? 7 : 6); + } else if (tx_port == 11) { + if ((tx_mux_sel >= 1) && (tx_mux_sel < 7)) + decimator = tx_mux_sel - 1; + } else if (tx_port == 13) { + if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2)) + decimator = 5; + } + + if (decimator >= 0) { + tx_fs_reg = WCD9360_CDC_TX0_TX_PATH_CTL + + 16 * decimator; + dev_dbg(codec->dev, "%s: set DEC%u (-> SLIM_TX%u) rate to %u\n", + __func__, decimator, tx_port, sample_rate); + snd_soc_update_bits(codec, tx_fs_reg, 0x0F, tx_fs_rate); + } else if ((tx_port <= 8) && (tx_mux_sel == 0x01)) { + /* Check if the TX Mux input is RX MIX TXn */ + dev_dbg(codec->dev, "%s: RX_MIX_TX%u going to CDC_IF TX%u\n", + __func__, tx_port, tx_port); + } else { + dev_err(codec->dev, "%s: ERROR: Invalid decimator: %d\n", + __func__, decimator); + return -EINVAL; + } + } + return 0; +} + +static int pahu_set_mix_interpolator_rate(struct snd_soc_dai *dai, + u8 rate_reg_val, + u32 sample_rate) +{ + u8 int_2_inp; + u32 j; + u16 int_mux_cfg1, int_fs_reg; + u8 int_mux_cfg1_val; + struct snd_soc_codec *codec = dai->codec; + struct wcd9xxx_ch *ch; + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + list_for_each_entry(ch, &pahu->dai[dai->id].wcd9xxx_ch_list, list) { + int_2_inp = INTn_2_INP_SEL_RX0 + ch->port - + WCD9360_RX_PORT_START_NUMBER; + if ((int_2_inp < INTn_2_INP_SEL_RX0) || + (int_2_inp > INTn_2_INP_SEL_RX7)) { + dev_err(codec->dev, "%s: Invalid RX%u port, Dai ID is %d\n", + __func__, + (ch->port - WCD9360_RX_PORT_START_NUMBER), + dai->id); + return -EINVAL; + } + + for (j = 0; j < WCD9360_NUM_INTERPOLATORS; j++) { + if (j == INTERP_EAR) { + int_mux_cfg1 = + WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1; + int_fs_reg = WCD9360_CDC_RX0_RX_PATH_MIX_CTL; + } else if (j == INTERP_SPKR1) { + int_mux_cfg1 = + WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1; + int_fs_reg = WCD9360_CDC_RX7_RX_PATH_MIX_CTL; + } else if (j == INTERP_SPKR2) { + int_mux_cfg1 = + WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1; + int_fs_reg = WCD9360_CDC_RX8_RX_PATH_MIX_CTL; + } else if (j == INTERP_AUX) { + int_mux_cfg1 = + WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1; + int_fs_reg = WCD9360_CDC_RX9_RX_PATH_MIX_CTL; + } else { + continue; + } + + int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1) & + 0x0F; + if (int_mux_cfg1_val == int_2_inp) { + /* + * Ear mix path supports only 48, 96, 192, + * 384KHz only + */ + if ((j == INTERP_EAR || j == INTERP_AUX) && + (rate_reg_val < 0x4 || rate_reg_val > 0x7)) { + dev_err_ratelimited(codec->dev, + "%s: Invalid rate for AIF_PB DAI(%d)\n", + __func__, dai->id); + return -EINVAL; + } + + dev_dbg(codec->dev, "%s: AIF_PB DAI(%d) connected to INT%u_2\n", + __func__, dai->id, j); + dev_dbg(codec->dev, "%s: set INT%u_2 sample rate to %u\n", + __func__, j, sample_rate); + snd_soc_update_bits(codec, int_fs_reg, 0x0F, + rate_reg_val); + } + } + } + return 0; +} + +static int pahu_set_prim_interpolator_rate(struct snd_soc_dai *dai, + u8 rate_reg_val, + u32 sample_rate) +{ + u8 int_1_mix1_inp; + u32 j; + u16 int_mux_cfg0, int_mux_cfg1; + u16 int_fs_reg; + u8 int_mux_cfg0_val, int_mux_cfg1_val; + u8 inp0_sel, inp1_sel, inp2_sel; + struct snd_soc_codec *codec = dai->codec; + struct wcd9xxx_ch *ch; + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + list_for_each_entry(ch, &pahu->dai[dai->id].wcd9xxx_ch_list, list) { + int_1_mix1_inp = INTn_1_INP_SEL_RX0 + ch->port - + WCD9360_RX_PORT_START_NUMBER; + if ((int_1_mix1_inp < INTn_1_INP_SEL_RX0) || + (int_1_mix1_inp > INTn_1_INP_SEL_RX7)) { + dev_err(codec->dev, "%s: Invalid RX%u port, Dai ID is %d\n", + __func__, + (ch->port - WCD9360_RX_PORT_START_NUMBER), + dai->id); + return -EINVAL; + } + + /* + * Loop through all interpolator MUX inputs and find out + * to which interpolator input, the slim rx port + * is connected + */ + for (j = 0; j < WCD9360_NUM_INTERPOLATORS; j++) { + if (j == INTERP_EAR) { + int_mux_cfg0 = + WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0; + int_fs_reg = WCD9360_CDC_RX0_RX_PATH_CTL; + } else if (j == INTERP_SPKR1) { + int_mux_cfg0 = + WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0; + int_fs_reg = WCD9360_CDC_RX7_RX_PATH_CTL; + } else if (j == INTERP_SPKR2) { + int_mux_cfg0 = + WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0; + int_fs_reg = WCD9360_CDC_RX8_RX_PATH_CTL; + } else if (j == INTERP_AUX) { + int_mux_cfg0 = + WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0; + int_fs_reg = WCD9360_CDC_RX9_RX_PATH_CTL; + } else { + continue; + } + int_mux_cfg1 = int_mux_cfg0 + 1; + + int_mux_cfg0_val = snd_soc_read(codec, int_mux_cfg0); + int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1); + inp0_sel = int_mux_cfg0_val & 0x0F; + inp1_sel = (int_mux_cfg0_val >> 4) & 0x0F; + inp2_sel = (int_mux_cfg1_val >> 4) & 0x0F; + if ((inp0_sel == int_1_mix1_inp) || + (inp1_sel == int_1_mix1_inp) || + (inp2_sel == int_1_mix1_inp)) { + /* + * Primary path does not support + * native sample rates + */ + if (rate_reg_val > 0x7) { + dev_err_ratelimited(codec->dev, + "%s: Invalid rate for AIF_PB DAI(%d)\n", + __func__, dai->id); + return -EINVAL; + } + dev_dbg(codec->dev, + "%s: AIF_PB DAI(%d) connected to INT%u_1\n", + __func__, dai->id, j); + dev_dbg(codec->dev, + "%s: set INT%u_1 sample rate to %u\n", + __func__, j, sample_rate); + snd_soc_update_bits(codec, int_fs_reg, 0x0F, + rate_reg_val); + } + int_mux_cfg0 += 2; + } + } + + return 0; +} + + +static int pahu_set_interpolator_rate(struct snd_soc_dai *dai, + u32 sample_rate) +{ + struct snd_soc_codec *codec = dai->codec; + int rate_val = 0; + int i, ret; + + for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) { + if (sample_rate == sr_val_tbl[i].sample_rate) { + rate_val = sr_val_tbl[i].rate_val; + break; + } + } + if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) { + dev_err(codec->dev, "%s: Unsupported sample rate: %d\n", + __func__, sample_rate); + return -EINVAL; + } + + ret = pahu_set_prim_interpolator_rate(dai, (u8)rate_val, sample_rate); + if (ret) + return ret; + ret = pahu_set_mix_interpolator_rate(dai, (u8)rate_val, sample_rate); + if (ret) + return ret; + + return ret; +} + +static int pahu_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + return 0; +} + +static int pahu_vi_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(dai->codec); + + dev_dbg(pahu->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", + __func__, dai->name, dai->id, params_rate(params), + params_channels(params)); + + pahu->dai[dai->id].rate = params_rate(params); + pahu->dai[dai->id].bit_width = 32; + + return 0; +} + +static int pahu_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(dai->codec); + int ret = 0; + + dev_dbg(pahu->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", + __func__, dai->name, dai->id, params_rate(params), + params_channels(params)); + + switch (substream->stream) { + case SNDRV_PCM_STREAM_PLAYBACK: + ret = pahu_set_interpolator_rate(dai, params_rate(params)); + if (ret) { + dev_err(pahu->dev, "%s: cannot set sample rate: %u\n", + __func__, params_rate(params)); + return ret; + } + switch (params_width(params)) { + case 16: + pahu->dai[dai->id].bit_width = 16; + break; + case 24: + pahu->dai[dai->id].bit_width = 24; + break; + case 32: + pahu->dai[dai->id].bit_width = 32; + break; + default: + return -EINVAL; + } + pahu->dai[dai->id].rate = params_rate(params); + break; + case SNDRV_PCM_STREAM_CAPTURE: + if (dai->id != AIF4_MAD_TX) + ret = pahu_set_decimator_rate(dai, + params_rate(params)); + if (ret) { + dev_err(pahu->dev, "%s: cannot set TX Decimator rate: %d\n", + __func__, ret); + return ret; + } + switch (params_width(params)) { + case 16: + pahu->dai[dai->id].bit_width = 16; + break; + case 24: + pahu->dai[dai->id].bit_width = 24; + break; + default: + dev_err(pahu->dev, "%s: Invalid format 0x%x\n", + __func__, params_width(params)); + return -EINVAL; + }; + pahu->dai[dai->id].rate = params_rate(params); + break; + default: + dev_err(pahu->dev, "%s: Invalid stream type %d\n", __func__, + substream->stream); + return -EINVAL; + }; + + return 0; +} + +static struct snd_soc_dai_ops pahu_dai_ops = { + .startup = pahu_startup, + .shutdown = pahu_shutdown, + .hw_params = pahu_hw_params, + .prepare = pahu_prepare, + .set_channel_map = pahu_set_channel_map, + .get_channel_map = pahu_get_channel_map, +}; + +static struct snd_soc_dai_ops pahu_vi_dai_ops = { + .hw_params = pahu_vi_hw_params, + .set_channel_map = pahu_set_channel_map, + .get_channel_map = pahu_get_channel_map, +}; + +static struct snd_soc_dai_driver pahu_dai[] = { + { + .name = "pahu_rx1", + .id = AIF1_PB, + .playback = { + .stream_name = "AIF1 Playback", + .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK, + .formats = WCD9360_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 384000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &pahu_dai_ops, + }, + { + .name = "pahu_tx1", + .id = AIF1_CAP, + .capture = { + .stream_name = "AIF1 Capture", + .rates = WCD9360_RATES_MASK, + .formats = WCD9360_FORMATS_S16_S24_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &pahu_dai_ops, + }, + { + .name = "pahu_rx2", + .id = AIF2_PB, + .playback = { + .stream_name = "AIF2 Playback", + .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK, + .formats = WCD9360_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 384000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &pahu_dai_ops, + }, + { + .name = "pahu_tx2", + .id = AIF2_CAP, + .capture = { + .stream_name = "AIF2 Capture", + .rates = WCD9360_RATES_MASK, + .formats = WCD9360_FORMATS_S16_S24_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &pahu_dai_ops, + }, + { + .name = "pahu_rx3", + .id = AIF3_PB, + .playback = { + .stream_name = "AIF3 Playback", + .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK, + .formats = WCD9360_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 384000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &pahu_dai_ops, + }, + { + .name = "pahu_tx3", + .id = AIF3_CAP, + .capture = { + .stream_name = "AIF3 Capture", + .rates = WCD9360_RATES_MASK, + .formats = WCD9360_FORMATS_S16_S24_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &pahu_dai_ops, + }, + { + .name = "pahu_rx4", + .id = AIF4_PB, + .playback = { + .stream_name = "AIF4 Playback", + .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK, + .formats = WCD9360_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 384000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &pahu_dai_ops, + }, + { + .name = "pahu_vifeedback", + .id = AIF4_VIFEED, + .capture = { + .stream_name = "VIfeed", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, + .formats = WCD9360_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 4, + }, + .ops = &pahu_vi_dai_ops, + }, + { + .name = "pahu_mad1", + .id = AIF4_MAD_TX, + .capture = { + .stream_name = "AIF4 MAD TX", + .rates = SNDRV_PCM_RATE_16000, + .formats = WCD9360_FORMATS_S16_LE, + .rate_min = 16000, + .rate_max = 16000, + .channels_min = 1, + .channels_max = 1, + }, + .ops = &pahu_dai_ops, + }, +}; + +static void pahu_codec_power_gate_digital_core(struct pahu_priv *pahu) +{ + mutex_lock(&pahu->power_lock); + dev_dbg(pahu->dev, "%s: Entering power gating function, %d\n", + __func__, pahu->power_active_ref); + + if (pahu->power_active_ref > 0) + goto exit; + + wcd9xxx_set_power_state(pahu->wcd9xxx, + WCD_REGION_POWER_COLLAPSE_BEGIN, + WCD9XXX_DIG_CORE_REGION_1); + regmap_update_bits(pahu->wcd9xxx->regmap, + WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x04, 0x04); + regmap_update_bits(pahu->wcd9xxx->regmap, + WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x01, 0x00); + regmap_update_bits(pahu->wcd9xxx->regmap, + WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x02, 0x00); + wcd9xxx_set_power_state(pahu->wcd9xxx, WCD_REGION_POWER_DOWN, + WCD9XXX_DIG_CORE_REGION_1); +exit: + dev_dbg(pahu->dev, "%s: Exiting power gating function, %d\n", + __func__, pahu->power_active_ref); + mutex_unlock(&pahu->power_lock); +} + +static void pahu_codec_power_gate_work(struct work_struct *work) +{ + struct pahu_priv *pahu; + struct delayed_work *dwork; + + dwork = to_delayed_work(work); + pahu = container_of(dwork, struct pahu_priv, power_gate_work); + + pahu_codec_power_gate_digital_core(pahu); +} + +/* called under power_lock acquisition */ +static int pahu_dig_core_remove_power_collapse(struct pahu_priv *pahu) +{ + regmap_write(pahu->wcd9xxx->regmap, + WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x05); + regmap_write(pahu->wcd9xxx->regmap, + WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x07); + regmap_update_bits(pahu->wcd9xxx->regmap, + WCD9360_CODEC_RPM_RST_CTL, 0x02, 0x00); + regmap_update_bits(pahu->wcd9xxx->regmap, + WCD9360_CODEC_RPM_RST_CTL, 0x02, 0x02); + regmap_write(pahu->wcd9xxx->regmap, + WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x03); + + wcd9xxx_set_power_state(pahu->wcd9xxx, + WCD_REGION_POWER_COLLAPSE_REMOVE, + WCD9XXX_DIG_CORE_REGION_1); + regcache_mark_dirty(pahu->wcd9xxx->regmap); + regcache_sync_region(pahu->wcd9xxx->regmap, + WCD9360_DIG_CORE_REG_MIN, + WCD9360_DIG_CORE_REG_MAX); + return 0; +} + +static int pahu_dig_core_power_collapse(struct pahu_priv *pahu, + int req_state) +{ + int cur_state; + + /* Exit if feature is disabled */ + if (!dig_core_collapse_enable) + return 0; + + mutex_lock(&pahu->power_lock); + if (req_state == POWER_COLLAPSE) + pahu->power_active_ref--; + else if (req_state == POWER_RESUME) + pahu->power_active_ref++; + else + goto unlock_mutex; + + if (pahu->power_active_ref < 0) { + dev_dbg(pahu->dev, "%s: power_active_ref is negative\n", + __func__); + goto unlock_mutex; + } + + if (req_state == POWER_COLLAPSE) { + if (pahu->power_active_ref == 0) { + schedule_delayed_work(&pahu->power_gate_work, + msecs_to_jiffies(dig_core_collapse_timer * 1000)); + } + } else if (req_state == POWER_RESUME) { + if (pahu->power_active_ref == 1) { + /* + * At this point, there can be two cases: + * 1. Core already in power collapse state + * 2. Timer kicked in and still did not expire or + * waiting for the power_lock + */ + cur_state = wcd9xxx_get_current_power_state( + pahu->wcd9xxx, + WCD9XXX_DIG_CORE_REGION_1); + if (cur_state == WCD_REGION_POWER_DOWN) { + pahu_dig_core_remove_power_collapse(pahu); + } else { + mutex_unlock(&pahu->power_lock); + cancel_delayed_work_sync( + &pahu->power_gate_work); + mutex_lock(&pahu->power_lock); + } + } + } + +unlock_mutex: + mutex_unlock(&pahu->power_lock); + + return 0; +} + +static int pahu_cdc_req_mclk_enable(struct pahu_priv *pahu, + bool enable) +{ + int ret = 0; + + if (enable) { + ret = clk_prepare_enable(pahu->wcd_ext_clk); + if (ret) { + dev_err(pahu->dev, "%s: ext clk enable failed\n", + __func__); + goto done; + } + /* get BG */ + wcd_resmgr_enable_master_bias(pahu->resmgr); + /* get MCLK */ + wcd_resmgr_enable_clk_block(pahu->resmgr, WCD_CLK_MCLK); + } else { + /* put MCLK */ + wcd_resmgr_disable_clk_block(pahu->resmgr, WCD_CLK_MCLK); + /* put BG */ + wcd_resmgr_disable_master_bias(pahu->resmgr); + clk_disable_unprepare(pahu->wcd_ext_clk); + } + +done: + return ret; +} + +static int __pahu_cdc_mclk_enable_locked(struct pahu_priv *pahu, + bool enable) +{ + int ret = 0; + + if (!pahu->wcd_ext_clk) { + dev_err(pahu->dev, "%s: wcd ext clock is NULL\n", __func__); + return -EINVAL; + } + + dev_dbg(pahu->dev, "%s: mclk_enable = %u\n", __func__, enable); + + if (enable) { + pahu_dig_core_power_collapse(pahu, POWER_RESUME); + pahu_vote_svs(pahu, true); + ret = pahu_cdc_req_mclk_enable(pahu, true); + if (ret) + goto done; + } else { + pahu_cdc_req_mclk_enable(pahu, false); + pahu_vote_svs(pahu, false); + pahu_dig_core_power_collapse(pahu, POWER_COLLAPSE); + } + +done: + return ret; +} + +static int __pahu_cdc_mclk_enable(struct pahu_priv *pahu, + bool enable) +{ + int ret; + + WCD9XXX_V2_BG_CLK_LOCK(pahu->resmgr); + ret = __pahu_cdc_mclk_enable_locked(pahu, enable); + if (enable) + wcd_resmgr_set_sido_input_src(pahu->resmgr, + SIDO_SOURCE_RCO_BG); + WCD9XXX_V2_BG_CLK_UNLOCK(pahu->resmgr); + + return ret; +} + +static ssize_t pahu_codec_version_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, size_t count, + loff_t pos) +{ + struct pahu_priv *pahu; + struct wcd9xxx *wcd9xxx; + char buffer[PAHU_VERSION_ENTRY_SIZE]; + int len = 0; + + pahu = (struct pahu_priv *) entry->private_data; + if (!pahu) { + pr_err("%s: pahu priv is null\n", __func__); + return -EINVAL; + } + + wcd9xxx = pahu->wcd9xxx; + + switch (wcd9xxx->version) { + case PAHU_VERSION_1_0: + len = snprintf(buffer, sizeof(buffer), "WCD9360_1_0\n"); + break; + default: + len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + } + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops pahu_codec_info_ops = { + .read = pahu_codec_version_read, +}; + +/* + * pahu_codec_info_create_codec_entry - creates wcd9360 module + * @codec_root: The parent directory + * @codec: Codec instance + * + * Creates wcd9360 module and version entry under the given + * parent directory. + * + * Return: 0 on success or negative error code on failure. + */ +int pahu_codec_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + struct snd_info_entry *version_entry; + struct pahu_priv *pahu; + struct snd_soc_card *card; + + if (!codec_root || !codec) + return -EINVAL; + + pahu = snd_soc_codec_get_drvdata(codec); + card = codec->component.card; + pahu->entry = snd_info_create_subdir(codec_root->module, + "pahu", codec_root); + if (!pahu->entry) { + dev_dbg(codec->dev, "%s: failed to create wcd9360 entry\n", + __func__); + return -ENOMEM; + } + + version_entry = snd_info_create_card_entry(card->snd_card, + "version", + pahu->entry); + if (!version_entry) { + dev_dbg(codec->dev, "%s: failed to create wcd9360 version entry\n", + __func__); + return -ENOMEM; + } + + version_entry->private_data = pahu; + version_entry->size = PAHU_VERSION_ENTRY_SIZE; + version_entry->content = SNDRV_INFO_CONTENT_DATA; + version_entry->c.ops = &pahu_codec_info_ops; + + if (snd_info_register(version_entry) < 0) { + snd_info_free_entry(version_entry); + return -ENOMEM; + } + pahu->version_entry = version_entry; + + return 0; +} +EXPORT_SYMBOL(pahu_codec_info_create_codec_entry); + +/** + * pahu_cdc_mclk_enable - Enable/disable codec mclk + * + * @codec: codec instance + * @enable: Indicates clk enable or disable + * + * Returns 0 on Success and error on failure + */ +int pahu_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable) +{ + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + return __pahu_cdc_mclk_enable(pahu, enable); +} +EXPORT_SYMBOL(pahu_cdc_mclk_enable); + +static int __pahu_codec_internal_rco_ctrl(struct snd_soc_codec *codec, + bool enable) +{ + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + if (enable) { + if (wcd_resmgr_get_clk_type(pahu->resmgr) == + WCD_CLK_RCO) { + ret = wcd_resmgr_enable_clk_block(pahu->resmgr, + WCD_CLK_RCO); + } else { + ret = pahu_cdc_req_mclk_enable(pahu, true); + if (ret) { + dev_err(codec->dev, + "%s: mclk_enable failed, err = %d\n", + __func__, ret); + goto done; + } + wcd_resmgr_set_sido_input_src(pahu->resmgr, + SIDO_SOURCE_RCO_BG); + ret = wcd_resmgr_enable_clk_block(pahu->resmgr, + WCD_CLK_RCO); + ret |= pahu_cdc_req_mclk_enable(pahu, false); + } + + } else { + ret = wcd_resmgr_disable_clk_block(pahu->resmgr, + WCD_CLK_RCO); + } + + if (ret) { + dev_err(codec->dev, "%s: Error in %s RCO\n", + __func__, (enable ? "enabling" : "disabling")); + ret = -EINVAL; + } + +done: + return ret; +} + +/* + * pahu_codec_internal_rco_ctrl: Enable/Disable codec's RCO clock + * @codec: Handle to the codec + * @enable: Indicates whether clock should be enabled or disabled + */ +static int pahu_codec_internal_rco_ctrl(struct snd_soc_codec *codec, + bool enable) +{ + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + WCD9XXX_V2_BG_CLK_LOCK(pahu->resmgr); + ret = __pahu_codec_internal_rco_ctrl(codec, enable); + WCD9XXX_V2_BG_CLK_UNLOCK(pahu->resmgr); + return ret; +} + +/* + * pahu_cdc_mclk_tx_enable: Enable/Disable codec's clock for TX path + * @codec: Handle to codec + * @enable: Indicates whether clock should be enabled or disabled + */ +int pahu_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable) +{ + struct pahu_priv *pahu_p; + int ret = 0; + bool clk_mode; + bool clk_internal; + + if (!codec) + return -EINVAL; + + pahu_p = snd_soc_codec_get_drvdata(codec); + clk_mode = test_bit(CLK_MODE, &pahu_p->status_mask); + clk_internal = test_bit(CLK_INTERNAL, &pahu_p->status_mask); + + dev_dbg(codec->dev, "%s: clkmode: %d, enable: %d, clk_internal: %d\n", + __func__, clk_mode, enable, clk_internal); + + if (clk_mode || clk_internal) { + if (enable) { + wcd_resmgr_enable_master_bias(pahu_p->resmgr); + pahu_dig_core_power_collapse(pahu_p, POWER_RESUME); + pahu_vote_svs(pahu_p, true); + ret = pahu_codec_internal_rco_ctrl(codec, enable); + set_bit(CLK_INTERNAL, &pahu_p->status_mask); + } else { + clear_bit(CLK_INTERNAL, &pahu_p->status_mask); + pahu_codec_internal_rco_ctrl(codec, enable); + pahu_vote_svs(pahu_p, false); + pahu_dig_core_power_collapse(pahu_p, POWER_COLLAPSE); + wcd_resmgr_disable_master_bias(pahu_p->resmgr); + } + } else { + ret = __pahu_cdc_mclk_enable(pahu_p, enable); + } + + return ret; +} +EXPORT_SYMBOL(pahu_cdc_mclk_tx_enable); + +static const struct wcd_resmgr_cb pahu_resmgr_cb = { + .cdc_rco_ctrl = __pahu_codec_internal_rco_ctrl, +}; + +static const struct pahu_reg_mask_val pahu_codec_mclk2_1_0_defaults[] = { + /* + * PLL Settings: + * Clock Root: MCLK2, + * Clock Source: EXT_CLK, + * Clock Destination: MCLK2 + * Clock Freq In: 19.2MHz, + * Clock Freq Out: 11.2896MHz + */ + {WCD9360_CLK_SYS_MCLK2_PRG1, 0x60, 0x20}, + {WCD9360_CLK_SYS_INT_POST_DIV_REG0, 0xFF, 0x5E}, + {WCD9360_CLK_SYS_INT_POST_DIV_REG1, 0x1F, 0x1F}, + {WCD9360_CLK_SYS_INT_REF_DIV_REG0, 0xFF, 0x54}, + {WCD9360_CLK_SYS_INT_REF_DIV_REG1, 0xFF, 0x01}, + {WCD9360_CLK_SYS_INT_FILTER_REG1, 0x07, 0x04}, + {WCD9360_CLK_SYS_INT_PLL_L_VAL, 0xFF, 0x93}, + {WCD9360_CLK_SYS_INT_PLL_N_VAL, 0xFF, 0xFA}, + {WCD9360_CLK_SYS_INT_TEST_REG0, 0xFF, 0x90}, + {WCD9360_CLK_SYS_INT_PFD_CP_DSM_PROG, 0xFF, 0x7E}, + {WCD9360_CLK_SYS_INT_VCO_PROG, 0xFF, 0xF8}, + {WCD9360_CLK_SYS_INT_TEST_REG1, 0xFF, 0x68}, + {WCD9360_CLK_SYS_INT_LDO_LOCK_CFG, 0xFF, 0x40}, + {WCD9360_CLK_SYS_INT_DIG_LOCK_DET_CFG, 0xFF, 0x32}, +}; + +static const struct pahu_reg_mask_val pahu_codec_reg_defaults[] = { + {WCD9360_BIAS_VBG_FINE_ADJ, 0xFF, 0x75}, + {WCD9360_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x01}, + {WCD9360_CODEC_CPR_SVS_CX_VDD, 0xFF, 0x7C}, /* value in svs mode */ + {WCD9360_CODEC_CPR_SVS2_CX_VDD, 0xFF, 0x58}, /* value in svs2 mode */ + {WCD9360_CDC_RX0_RX_PATH_DSMDEM_CTL, 0x01, 0x01}, + {WCD9360_CDC_RX7_RX_PATH_DSMDEM_CTL, 0x01, 0x01}, + {WCD9360_CDC_RX8_RX_PATH_DSMDEM_CTL, 0x01, 0x01}, + {WCD9360_CDC_RX9_RX_PATH_DSMDEM_CTL, 0x01, 0x01}, + {WCD9360_CDC_COMPANDER8_CTL7, 0x1E, 0x18}, + {WCD9360_CDC_COMPANDER7_CTL7, 0x1E, 0x18}, + {WCD9360_CDC_RX0_RX_PATH_SEC0, 0x08, 0x00}, + {WCD9360_CDC_RX9_RX_PATH_SEC0, 0x08, 0x00}, + {WCD9360_MICB1_TEST_CTL_2, 0x07, 0x01}, + {WCD9360_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12}, + {WCD9360_CDC_BOOST0_BOOST_CFG2, 0x1C, 0x08}, + {WCD9360_CDC_BOOST1_BOOST_CFG1, 0x3F, 0x12}, + {WCD9360_CDC_BOOST1_BOOST_CFG2, 0x1C, 0x08}, + {WCD9360_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD, 0x1F, 0x09}, + {WCD9360_CDC_TX0_TX_PATH_CFG1, 0x01, 0x00}, + {WCD9360_CDC_TX1_TX_PATH_CFG1, 0x01, 0x00}, + {WCD9360_CDC_TX2_TX_PATH_CFG1, 0x01, 0x00}, + {WCD9360_CDC_TX3_TX_PATH_CFG1, 0x01, 0x00}, + {WCD9360_CDC_TX4_TX_PATH_CFG1, 0x01, 0x00}, + {WCD9360_CDC_TX5_TX_PATH_CFG1, 0x01, 0x00}, + {WCD9360_CDC_TX6_TX_PATH_CFG1, 0x01, 0x00}, + {WCD9360_CDC_TX7_TX_PATH_CFG1, 0x01, 0x00}, + {WCD9360_CDC_TX8_TX_PATH_CFG1, 0x01, 0x00}, + {WCD9360_CPE_FLL_CONFIG_CTL_2, 0xFF, 0x20}, + {WCD9360_CPE_SS_DMIC_CFG, 0x80, 0x00}, + {WCD9360_CDC_BOOST0_BOOST_CTL, 0x70, 0x50}, + {WCD9360_CDC_BOOST1_BOOST_CTL, 0x70, 0x50}, + {WCD9360_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08}, + {WCD9360_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08}, + {WCD9360_CDC_TOP_TOP_CFG1, 0x02, 0x02}, + {WCD9360_CDC_TOP_TOP_CFG1, 0x01, 0x01}, + {WCD9360_CDC_TOP_EAR_COMP_LUT, 0x80, 0x80}, + {WCD9360_EAR_EAR_DAC_CON, 0x06, 0x02}, + {WCD9360_AUX_INT_AUX_DAC_CON, 0x06, 0x02}, + {WCD9360_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {WCD9360_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {WCD9360_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {WCD9360_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {WCD9360_DATA_HUB_SB_TX11_INP_CFG, 0x01, 0x01}, + {WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x01}, + {WCD9360_CDC_COMPANDER7_CTL3, 0x80, 0x80}, + {WCD9360_CDC_COMPANDER8_CTL3, 0x80, 0x80}, + {WCD9360_CDC_COMPANDER7_CTL7, 0x01, 0x01}, + {WCD9360_CDC_COMPANDER8_CTL7, 0x01, 0x01}, + {WCD9360_CODEC_RPM_CLK_GATE, 0x08, 0x00}, + {WCD9360_TLMM_DMIC3_CLK_PINCFG, 0xFF, 0x0a}, + {WCD9360_TLMM_DMIC3_DATA_PINCFG, 0xFF, 0x0a}, + {WCD9360_CPE_SS_SVA_CFG, 0x60, 0x00}, + {WCD9360_CPE_SS_CPAR_CFG, 0x10, 0x10}, +}; + +static const struct pahu_cpr_reg_defaults cpr_defaults[] = { + { 0x00000820, 0x00000094 }, + { 0x00000fC0, 0x00000048 }, + { 0x0000f000, 0x00000044 }, + { 0x0000bb80, 0xC0000178 }, + { 0x00000000, 0x00000160 }, + { 0x10854522, 0x00000060 }, + { 0x10854509, 0x00000064 }, + { 0x108544dd, 0x00000068 }, + { 0x108544ad, 0x0000006C }, + { 0x0000077E, 0x00000070 }, + { 0x000007da, 0x00000074 }, + { 0x00000000, 0x00000078 }, + { 0x00000000, 0x0000007C }, + { 0x00042029, 0x00000080 }, + { 0x4002002A, 0x00000090 }, + { 0x4002002B, 0x00000090 }, +}; + +static void pahu_update_reg_defaults(struct pahu_priv *pahu) +{ + u32 i; + struct wcd9xxx *wcd9xxx; + + wcd9xxx = pahu->wcd9xxx; + for (i = 0; i < ARRAY_SIZE(pahu_codec_reg_defaults); i++) + regmap_update_bits(wcd9xxx->regmap, + pahu_codec_reg_defaults[i].reg, + pahu_codec_reg_defaults[i].mask, + pahu_codec_reg_defaults[i].val); +} + +static void pahu_update_cpr_defaults(struct pahu_priv *pahu) +{ + int i; + struct wcd9xxx *wcd9xxx; + + wcd9xxx = pahu->wcd9xxx; + + __pahu_cdc_mclk_enable(pahu, true); + + regmap_update_bits(wcd9xxx->regmap, WCD9360_CODEC_RPM_CLK_GATE, + 0x10, 0x00); + + for (i = 0; i < ARRAY_SIZE(cpr_defaults); i++) { + regmap_bulk_write(wcd9xxx->regmap, + WCD9360_CODEC_CPR_WR_DATA_0, + (u8 *)&cpr_defaults[i].wr_data, 4); + regmap_bulk_write(wcd9xxx->regmap, + WCD9360_CODEC_CPR_WR_ADDR_0, + (u8 *)&cpr_defaults[i].wr_addr, 4); + } + + __pahu_cdc_mclk_enable(pahu, false); +} + +static void pahu_slim_interface_init_reg(struct snd_soc_codec *codec) +{ + int i; + struct pahu_priv *priv = snd_soc_codec_get_drvdata(codec); + + for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++) + wcd9xxx_interface_reg_write(priv->wcd9xxx, + WCD9360_SLIM_PGD_PORT_INT_RX_EN0 + i, + 0xFF); +} + +static irqreturn_t pahu_misc_irq(int irq, void *data) +{ + struct pahu_priv *pahu = data; + int misc_val; + + /* Find source of interrupt */ + regmap_read(pahu->wcd9xxx->regmap, WCD9360_INTR_CODEC_MISC_STATUS, + &misc_val); + + dev_dbg(pahu->dev, "%s: Codec misc irq: %d, val: 0x%x\n", + __func__, irq, misc_val); + + /* Clear interrupt status */ + regmap_update_bits(pahu->wcd9xxx->regmap, + WCD9360_INTR_CODEC_MISC_CLEAR, misc_val, 0x00); + + return IRQ_HANDLED; +} + +static irqreturn_t pahu_slimbus_irq(int irq, void *data) +{ + struct pahu_priv *pahu = data; + unsigned long status = 0; + int i, j, port_id, k; + u32 bit; + u8 val, int_val = 0; + bool tx, cleared; + unsigned short reg = 0; + + for (i = WCD9360_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0; + i <= WCD9360_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) { + val = wcd9xxx_interface_reg_read(pahu->wcd9xxx, i); + status |= ((u32)val << (8 * j)); + } + + for_each_set_bit(j, &status, 32) { + tx = (j >= 16 ? true : false); + port_id = (tx ? j - 16 : j); + val = wcd9xxx_interface_reg_read(pahu->wcd9xxx, + WCD9360_SLIM_PGD_PORT_INT_RX_SOURCE0 + j); + if (val) { + if (!tx) + reg = WCD9360_SLIM_PGD_PORT_INT_RX_EN0 + + (port_id / 8); + else + reg = WCD9360_SLIM_PGD_PORT_INT_TX_EN0 + + (port_id / 8); + int_val = wcd9xxx_interface_reg_read( + pahu->wcd9xxx, reg); + /* + * Ignore interrupts for ports for which the + * interrupts are not specifically enabled. + */ + if (!(int_val & (1 << (port_id % 8)))) + continue; + } + if (val & WCD9360_SLIM_IRQ_OVERFLOW) + dev_err_ratelimited(pahu->dev, "%s: overflow error on %s port %d, value %x\n", + __func__, (tx ? "TX" : "RX"), port_id, val); + if (val & WCD9360_SLIM_IRQ_UNDERFLOW) + dev_err_ratelimited(pahu->dev, "%s: underflow error on %s port %d, value %x\n", + __func__, (tx ? "TX" : "RX"), port_id, val); + if ((val & WCD9360_SLIM_IRQ_OVERFLOW) || + (val & WCD9360_SLIM_IRQ_UNDERFLOW)) { + if (!tx) + reg = WCD9360_SLIM_PGD_PORT_INT_RX_EN0 + + (port_id / 8); + else + reg = WCD9360_SLIM_PGD_PORT_INT_TX_EN0 + + (port_id / 8); + int_val = wcd9xxx_interface_reg_read( + pahu->wcd9xxx, reg); + if (int_val & (1 << (port_id % 8))) { + int_val = int_val ^ (1 << (port_id % 8)); + wcd9xxx_interface_reg_write(pahu->wcd9xxx, + reg, int_val); + } + } + if (val & WCD9360_SLIM_IRQ_PORT_CLOSED) { + /* + * INT SOURCE register starts from RX to TX + * but port number in the ch_mask is in opposite way + */ + bit = (tx ? j - 16 : j + 16); + dev_dbg(pahu->dev, "%s: %s port %d closed value %x, bit %u\n", + __func__, (tx ? "TX" : "RX"), port_id, val, + bit); + for (k = 0, cleared = false; k < NUM_CODEC_DAIS; k++) { + dev_dbg(pahu->dev, "%s: pahu->dai[%d].ch_mask = 0x%lx\n", + __func__, k, pahu->dai[k].ch_mask); + if (test_and_clear_bit(bit, + &pahu->dai[k].ch_mask)) { + cleared = true; + if (!pahu->dai[k].ch_mask) + wake_up( + &pahu->dai[k].dai_wait); + /* + * There are cases when multiple DAIs + * might be using the same slimbus + * channel. Hence don't break here. + */ + } + } + } + wcd9xxx_interface_reg_write(pahu->wcd9xxx, + WCD9360_SLIM_PGD_PORT_INT_CLR_RX_0 + + (j / 8), + 1 << (j % 8)); + } + + return IRQ_HANDLED; +} + +static int pahu_setup_irqs(struct pahu_priv *pahu) +{ + int ret = 0; + struct snd_soc_codec *codec = pahu->codec; + struct wcd9xxx *wcd9xxx = pahu->wcd9xxx; + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + + ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_SLIMBUS, + pahu_slimbus_irq, "SLIMBUS Slave", pahu); + if (ret) + dev_err(codec->dev, "%s: Failed to request irq %d\n", __func__, + WCD9XXX_IRQ_SLIMBUS); + else + pahu_slim_interface_init_reg(codec); + + /* Register for misc interrupts as well */ + ret = wcd9xxx_request_irq(core_res, WCD9360_IRQ_MISC, + pahu_misc_irq, "CDC MISC Irq", pahu); + if (ret) + dev_err(codec->dev, "%s: Failed to request cdc misc irq\n", + __func__); + + return ret; +} + +static void pahu_init_slim_slave_cfg(struct snd_soc_codec *codec) +{ + struct pahu_priv *priv = snd_soc_codec_get_drvdata(codec); + struct afe_param_cdc_slimbus_slave_cfg *cfg; + struct wcd9xxx *wcd9xxx = priv->wcd9xxx; + uint64_t eaddr = 0; + + cfg = &priv->slimbus_slave_cfg; + cfg->minor_version = 1; + cfg->tx_slave_port_offset = 0; + cfg->rx_slave_port_offset = 16; + + memcpy(&eaddr, &wcd9xxx->slim->e_addr, sizeof(wcd9xxx->slim->e_addr)); + WARN_ON(sizeof(wcd9xxx->slim->e_addr) != 6); + cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF; + cfg->device_enum_addr_msw = eaddr >> 32; + + dev_dbg(codec->dev, "%s: slimbus logical address 0x%llx\n", + __func__, eaddr); +} + +static void pahu_cleanup_irqs(struct pahu_priv *pahu) +{ + struct wcd9xxx *wcd9xxx = pahu->wcd9xxx; + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + + wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_SLIMBUS, pahu); + wcd9xxx_free_irq(core_res, WCD9360_IRQ_MISC, pahu); +} + +/* + * wcd9360_get_micb_vout_ctl_val: converts micbias from volts to register value + * @micb_mv: micbias in mv + * + * return register value converted + */ +int wcd9360_get_micb_vout_ctl_val(u32 micb_mv) +{ + /* min micbias voltage is 1V and maximum is 2.85V */ + if (micb_mv < 1000 || micb_mv > 2850) { + pr_err("%s: unsupported micbias voltage\n", __func__); + return -EINVAL; + } + + return (micb_mv - 1000) / 50; +} +EXPORT_SYMBOL(wcd9360_get_micb_vout_ctl_val); + +static int pahu_handle_pdata(struct pahu_priv *pahu, + struct wcd9xxx_pdata *pdata) +{ + struct snd_soc_codec *codec = pahu->codec; + u8 mad_dmic_ctl_val; + u8 anc_ctl_value; + u32 dmic_clk_drv; + int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4; + int rc = 0; + + if (!pdata) { + dev_err(codec->dev, "%s: NULL pdata\n", __func__); + return -ENODEV; + } + + /* set micbias voltage */ + vout_ctl_1 = wcd9360_get_micb_vout_ctl_val(pdata->micbias.micb1_mv); + vout_ctl_2 = wcd9360_get_micb_vout_ctl_val(pdata->micbias.micb2_mv); + vout_ctl_3 = wcd9360_get_micb_vout_ctl_val(pdata->micbias.micb3_mv); + vout_ctl_4 = wcd9360_get_micb_vout_ctl_val(pdata->micbias.micb4_mv); + if (vout_ctl_1 < 0 || vout_ctl_2 < 0 || + vout_ctl_3 < 0 || vout_ctl_4 < 0) { + rc = -EINVAL; + goto done; + } + snd_soc_update_bits(codec, WCD9360_ANA_MICB1, 0x3F, vout_ctl_1); + snd_soc_update_bits(codec, WCD9360_ANA_MICB2, 0x3F, vout_ctl_2); + snd_soc_update_bits(codec, WCD9360_ANA_MICB3, 0x3F, vout_ctl_3); + snd_soc_update_bits(codec, WCD9360_ANA_MICB4, 0x3F, vout_ctl_4); + + if (pdata->dmic_sample_rate == + WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) { + dev_info(codec->dev, "%s: dmic_rate invalid default = %d\n", + __func__, WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ); + pdata->dmic_sample_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ; + } + if (pdata->mad_dmic_sample_rate == + WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) { + dev_info(codec->dev, "%s: mad_dmic_rate invalid default = %d\n", + __func__, WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ); + /* + * use dmic_sample_rate as the default for MAD + * if mad dmic sample rate is undefined + */ + pdata->mad_dmic_sample_rate = pdata->dmic_sample_rate; + } + + if (pdata->dmic_clk_drv == + WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED) { + pdata->dmic_clk_drv = WCD9360_DMIC_CLK_DRIVE_DEFAULT; + dev_dbg(codec->dev, + "%s: dmic_clk_strength invalid, default = %d\n", + __func__, pdata->dmic_clk_drv); + } + + switch (pdata->dmic_clk_drv) { + case 2: + dmic_clk_drv = 0; + break; + case 4: + dmic_clk_drv = 1; + break; + case 8: + dmic_clk_drv = 2; + break; + case 16: + dmic_clk_drv = 3; + break; + default: + dev_err(codec->dev, + "%s: invalid dmic_clk_drv %d, using default\n", + __func__, pdata->dmic_clk_drv); + dmic_clk_drv = 0; + break; + } + + snd_soc_update_bits(codec, WCD9360_TEST_DEBUG_PAD_DRVCTL_0, + 0x0C, dmic_clk_drv << 2); + + /* + * Default the DMIC clk rates to mad_dmic_sample_rate, + * whereas, the anc/txfe dmic rates to dmic_sample_rate + * since the anc/txfe are independent of mad block. + */ + mad_dmic_ctl_val = pahu_get_dmic_clk_val(pahu->codec, + pdata->mad_dmic_sample_rate); + snd_soc_update_bits(codec, WCD9360_CPE_SS_DMIC0_CTL, + 0x0E, mad_dmic_ctl_val << 1); + snd_soc_update_bits(codec, WCD9360_CPE_SS_DMIC1_CTL, + 0x0E, mad_dmic_ctl_val << 1); + snd_soc_update_bits(codec, WCD9360_CPE_SS_DMIC2_CTL, + 0x0E, mad_dmic_ctl_val << 1); + + if (dmic_clk_drv == WCD9360_DMIC_CLK_DIV_2) + anc_ctl_value = WCD9360_ANC_DMIC_X2_FULL_RATE; + else + anc_ctl_value = WCD9360_ANC_DMIC_X2_HALF_RATE; + + snd_soc_update_bits(codec, WCD9360_CDC_ANC0_MODE_2_CTL, + 0x40, anc_ctl_value << 6); + snd_soc_update_bits(codec, WCD9360_CDC_ANC0_MODE_2_CTL, + 0x20, anc_ctl_value << 5); + +done: + return rc; +} + +static void pahu_cdc_vote_svs(struct snd_soc_codec *codec, bool vote) +{ + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + return pahu_vote_svs(pahu, vote); +} + +struct wcd_dsp_cdc_cb cdc_cb = { + .cdc_clk_en = pahu_codec_internal_rco_ctrl, + .cdc_vote_svs = pahu_cdc_vote_svs, +}; + +static int pahu_wdsp_initialize(struct snd_soc_codec *codec) +{ + struct wcd9xxx *control; + struct pahu_priv *pahu; + struct wcd_dsp_params params; + int ret = 0; + + control = dev_get_drvdata(codec->dev->parent); + pahu = snd_soc_codec_get_drvdata(codec); + + params.cb = &cdc_cb; + params.irqs.cpe_ipc1_irq = WCD9360_IRQ_CPE1_INTR; + params.irqs.cpe_err_irq = WCD9360_IRQ_CPE_ERROR; + params.irqs.fatal_irqs = CPE_FATAL_IRQS; + params.clk_rate = control->mclk_rate; + params.dsp_instance = 0; + + wcd9360_dsp_cntl_init(codec, ¶ms, &pahu->wdsp_cntl); + if (!pahu->wdsp_cntl) { + dev_err(pahu->dev, "%s: wcd-dsp-control init failed\n", + __func__); + ret = -EINVAL; + } + + return ret; +} + +static void pahu_mclk2_reg_defaults(struct pahu_priv *pahu) +{ + int i; + struct snd_soc_codec *codec = pahu->codec; + + /* MCLK2 configuration */ + for (i = 0; i < ARRAY_SIZE(pahu_codec_mclk2_1_0_defaults); i++) + snd_soc_update_bits(codec, + pahu_codec_mclk2_1_0_defaults[i].reg, + pahu_codec_mclk2_1_0_defaults[i].mask, + pahu_codec_mclk2_1_0_defaults[i].val); +} + +static int pahu_device_down(struct wcd9xxx *wcd9xxx) +{ + struct snd_soc_codec *codec; + struct pahu_priv *priv; + int count; + + codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); + priv = snd_soc_codec_get_drvdata(codec); + if (priv->swr.ctrl_data) + swrm_wcd_notify(priv->swr.ctrl_data[0].swr_pdev, + SWR_DEVICE_DOWN, NULL); + snd_soc_card_change_online_state(codec->component.card, 0); + for (count = 0; count < NUM_CODEC_DAIS; count++) + priv->dai[count].bus_down_in_recovery = true; + wcd9360_dsp_ssr_event(priv->wdsp_cntl, WCD_CDC_DOWN_EVENT); + wcd_resmgr_set_sido_input_src_locked(priv->resmgr, + SIDO_SOURCE_INTERNAL); + + return 0; +} + +static int pahu_post_reset_cb(struct wcd9xxx *wcd9xxx) +{ + int i, ret = 0; + struct wcd9xxx *control; + struct snd_soc_codec *codec; + struct pahu_priv *pahu; + struct wcd9xxx_pdata *pdata; + + codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); + pahu = snd_soc_codec_get_drvdata(codec); + control = dev_get_drvdata(codec->dev->parent); + + wcd9xxx_set_power_state(pahu->wcd9xxx, + WCD_REGION_POWER_COLLAPSE_REMOVE, + WCD9XXX_DIG_CORE_REGION_1); + + mutex_lock(&pahu->codec_mutex); + + pahu_vote_svs(pahu, true); + pahu_slimbus_slave_port_cfg.slave_dev_intfdev_la = + control->slim_slave->laddr; + pahu_slimbus_slave_port_cfg.slave_dev_pgd_la = + control->slim->laddr; + pahu_init_slim_slave_cfg(codec); + snd_soc_card_change_online_state(codec->component.card, 1); + + for (i = 0; i < PAHU_MAX_MICBIAS; i++) + pahu->micb_ref[i] = 0; + + dev_dbg(codec->dev, "%s: MCLK Rate = %x\n", + __func__, control->mclk_rate); + + pahu_update_reg_defaults(pahu); + wcd_resmgr_post_ssr_v2(pahu->resmgr); + __pahu_enable_efuse_sensing(pahu); + pahu_mclk2_reg_defaults(pahu); + + __pahu_cdc_mclk_enable(pahu, true); + regcache_mark_dirty(codec->component.regmap); + regcache_sync(codec->component.regmap); + __pahu_cdc_mclk_enable(pahu, false); + + pahu_update_cpr_defaults(pahu); + + pdata = dev_get_platdata(codec->dev->parent); + ret = pahu_handle_pdata(pahu, pdata); + if (ret < 0) + dev_err(codec->dev, "%s: invalid pdata\n", __func__); + + pahu_cleanup_irqs(pahu); + ret = pahu_setup_irqs(pahu); + if (ret) { + dev_err(codec->dev, "%s: pahu irq setup failed %d\n", + __func__, ret); + goto done; + } + + pahu_set_spkr_mode(codec, pahu->swr.spkr_mode); + /* + * Once the codec initialization is completed, the svs vote + * can be released allowing the codec to go to SVS2. + */ + pahu_vote_svs(pahu, false); + wcd9360_dsp_ssr_event(pahu->wdsp_cntl, WCD_CDC_UP_EVENT); + +done: + mutex_unlock(&pahu->codec_mutex); + return ret; +} + +static int pahu_soc_codec_probe(struct snd_soc_codec *codec) +{ + struct wcd9xxx *control; + struct pahu_priv *pahu; + struct wcd9xxx_pdata *pdata; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + int i, ret; + void *ptr = NULL; + + control = dev_get_drvdata(codec->dev->parent); + + dev_info(codec->dev, "%s()\n", __func__); + pahu = snd_soc_codec_get_drvdata(codec); + pahu->intf_type = wcd9xxx_get_intf_type(); + + control->dev_down = pahu_device_down; + control->post_reset = pahu_post_reset_cb; + control->ssr_priv = (void *)codec; + + /* Resource Manager post Init */ + ret = wcd_resmgr_post_init(pahu->resmgr, &pahu_resmgr_cb, codec); + if (ret) { + dev_err(codec->dev, "%s: wcd resmgr post init failed\n", + __func__); + goto err; + } + + pahu->fw_data = devm_kzalloc(codec->dev, sizeof(*(pahu->fw_data)), + GFP_KERNEL); + if (!pahu->fw_data) + goto err; + + set_bit(WCD9XXX_ANC_CAL, pahu->fw_data->cal_bit); + set_bit(WCD9XXX_MAD_CAL, pahu->fw_data->cal_bit); + + ret = wcd_cal_create_hwdep(pahu->fw_data, + WCD9XXX_CODEC_HWDEP_NODE, codec); + if (ret < 0) { + dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret); + goto err_hwdep; + } + + pahu->codec = codec; + for (i = 0; i < COMPANDER_MAX; i++) + pahu->comp_enabled[i] = 0; + + pdata = dev_get_platdata(codec->dev->parent); + ret = pahu_handle_pdata(pahu, pdata); + if (ret < 0) { + dev_err(codec->dev, "%s: bad pdata\n", __func__); + goto err_hwdep; + } + + ptr = devm_kzalloc(codec->dev, (sizeof(pahu_rx_chs) + + sizeof(pahu_tx_chs)), GFP_KERNEL); + if (!ptr) { + ret = -ENOMEM; + goto err_hwdep; + } + + snd_soc_dapm_add_routes(dapm, pahu_slim_audio_map, + ARRAY_SIZE(pahu_slim_audio_map)); + for (i = 0; i < NUM_CODEC_DAIS; i++) { + INIT_LIST_HEAD(&pahu->dai[i].wcd9xxx_ch_list); + init_waitqueue_head(&pahu->dai[i].dai_wait); + } + pahu_slimbus_slave_port_cfg.slave_dev_intfdev_la = + control->slim_slave->laddr; + pahu_slimbus_slave_port_cfg.slave_dev_pgd_la = + control->slim->laddr; + pahu_slimbus_slave_port_cfg.slave_port_mapping[0] = + WCD9360_TX13; + pahu_init_slim_slave_cfg(codec); + + control->num_rx_port = WCD9360_RX_MAX; + control->rx_chs = ptr; + memcpy(control->rx_chs, pahu_rx_chs, sizeof(pahu_rx_chs)); + control->num_tx_port = WCD9360_TX_MAX; + control->tx_chs = ptr + sizeof(pahu_rx_chs); + memcpy(control->tx_chs, pahu_tx_chs, sizeof(pahu_tx_chs)); + + ret = pahu_setup_irqs(pahu); + if (ret) { + dev_err(pahu->dev, "%s: pahu irq setup failed %d\n", + __func__, ret); + goto err_pdata; + } + + for (i = 0; i < WCD9360_NUM_DECIMATORS; i++) { + pahu->tx_hpf_work[i].pahu = pahu; + pahu->tx_hpf_work[i].decimator = i; + INIT_DELAYED_WORK(&pahu->tx_hpf_work[i].dwork, + pahu_tx_hpf_corner_freq_callback); + + pahu->tx_mute_dwork[i].pahu = pahu; + pahu->tx_mute_dwork[i].decimator = i; + INIT_DELAYED_WORK(&pahu->tx_mute_dwork[i].dwork, + pahu_tx_mute_update_callback); + } + + pahu->spk_anc_dwork.pahu = pahu; + INIT_DELAYED_WORK(&pahu->spk_anc_dwork.dwork, + pahu_spk_anc_update_callback); + + pahu_mclk2_reg_defaults(pahu); + + mutex_lock(&pahu->codec_mutex); + snd_soc_dapm_disable_pin(dapm, "ANC EAR PA"); + snd_soc_dapm_disable_pin(dapm, "ANC EAR"); + snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA"); + mutex_unlock(&pahu->codec_mutex); + + snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AIF1 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "AIF2 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AIF2 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "AIF3 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AIF3 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "AIF4 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX"); + snd_soc_dapm_ignore_suspend(dapm, "VIfeed"); + + snd_soc_dapm_sync(dapm); + + pahu_wdsp_initialize(codec); + + /* + * Once the codec initialization is completed, the svs vote + * can be released allowing the codec to go to SVS2. + */ + pahu_vote_svs(pahu, false); + + return ret; + +err_pdata: + devm_kfree(codec->dev, ptr); + control->rx_chs = NULL; + control->tx_chs = NULL; +err_hwdep: + devm_kfree(codec->dev, pahu->fw_data); + pahu->fw_data = NULL; +err: + return ret; +} + +static int pahu_soc_codec_remove(struct snd_soc_codec *codec) +{ + struct wcd9xxx *control; + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + control = dev_get_drvdata(codec->dev->parent); + devm_kfree(codec->dev, control->rx_chs); + /* slimslave deinit in wcd core looks for this value */ + control->num_rx_port = 0; + control->num_tx_port = 0; + control->rx_chs = NULL; + control->tx_chs = NULL; + pahu_cleanup_irqs(pahu); + + if (pahu->wdsp_cntl) + wcd9360_dsp_cntl_deinit(&pahu->wdsp_cntl); + + return 0; +} + +static struct regmap *pahu_get_regmap(struct device *dev) +{ + struct wcd9xxx *control = dev_get_drvdata(dev->parent); + + return control->regmap; +} + +static struct snd_soc_codec_driver soc_codec_dev_pahu = { + .probe = pahu_soc_codec_probe, + .remove = pahu_soc_codec_remove, + .get_regmap = pahu_get_regmap, + .component_driver = { + .controls = pahu_snd_controls, + .num_controls = ARRAY_SIZE(pahu_snd_controls), + .dapm_widgets = pahu_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(pahu_dapm_widgets), + .dapm_routes = pahu_audio_map, + .num_dapm_routes = ARRAY_SIZE(pahu_audio_map), + }, +}; + +#ifdef CONFIG_PM +static int pahu_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct pahu_priv *pahu = platform_get_drvdata(pdev); + + if (!pahu) { + dev_err(dev, "%s: pahu private data is NULL\n", __func__); + return -EINVAL; + } + dev_dbg(dev, "%s: system suspend\n", __func__); + if (delayed_work_pending(&pahu->power_gate_work) && + cancel_delayed_work_sync(&pahu->power_gate_work)) + pahu_codec_power_gate_digital_core(pahu); + return 0; +} + +static int pahu_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct pahu_priv *pahu = platform_get_drvdata(pdev); + + if (!pahu) { + dev_err(dev, "%s: pahu private data is NULL\n", __func__); + return -EINVAL; + } + dev_dbg(dev, "%s: system resume\n", __func__); + return 0; +} + +static const struct dev_pm_ops pahu_pm_ops = { + .suspend = pahu_suspend, + .resume = pahu_resume, +}; +#endif + +static int pahu_swrm_read(void *handle, int reg) +{ + struct pahu_priv *pahu; + struct wcd9xxx *wcd9xxx; + unsigned short swr_rd_addr_base; + unsigned short swr_rd_data_base; + int val, ret; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + pahu = (struct pahu_priv *)handle; + wcd9xxx = pahu->wcd9xxx; + + dev_dbg(pahu->dev, "%s: Reading soundwire register, 0x%x\n", + __func__, reg); + swr_rd_addr_base = WCD9360_SWR_AHB_BRIDGE_RD_ADDR_0; + swr_rd_data_base = WCD9360_SWR_AHB_BRIDGE_RD_DATA_0; + + mutex_lock(&pahu->swr.read_mutex); + ret = regmap_bulk_write(wcd9xxx->regmap, swr_rd_addr_base, + (u8 *)®, 4); + if (ret < 0) { + dev_err(pahu->dev, "%s: RD Addr Failure\n", __func__); + goto done; + } + ret = regmap_bulk_read(wcd9xxx->regmap, swr_rd_data_base, + (u8 *)&val, 4); + if (ret < 0) { + dev_err(pahu->dev, "%s: RD Data Failure\n", __func__); + goto done; + } + ret = val; +done: + mutex_unlock(&pahu->swr.read_mutex); + + return ret; +} + +static int pahu_swrm_bulk_write(void *handle, u32 *reg, u32 *val, size_t len) +{ + struct pahu_priv *pahu; + struct wcd9xxx *wcd9xxx; + struct wcd9xxx_reg_val *bulk_reg; + unsigned short swr_wr_addr_base; + unsigned short swr_wr_data_base; + int i, j, ret; + + if (!handle || !reg || !val) { + pr_err("%s: NULL parameter\n", __func__); + return -EINVAL; + } + if (len <= 0) { + pr_err("%s: Invalid size: %zu\n", __func__, len); + return -EINVAL; + } + pahu = (struct pahu_priv *)handle; + wcd9xxx = pahu->wcd9xxx; + + swr_wr_addr_base = WCD9360_SWR_AHB_BRIDGE_WR_ADDR_0; + swr_wr_data_base = WCD9360_SWR_AHB_BRIDGE_WR_DATA_0; + + bulk_reg = kzalloc((2 * len * sizeof(struct wcd9xxx_reg_val)), + GFP_KERNEL); + if (!bulk_reg) + return -ENOMEM; + + for (i = 0, j = 0; i < (len * 2); i += 2, j++) { + bulk_reg[i].reg = swr_wr_data_base; + bulk_reg[i].buf = (u8 *)(&val[j]); + bulk_reg[i].bytes = 4; + bulk_reg[i+1].reg = swr_wr_addr_base; + bulk_reg[i+1].buf = (u8 *)(®[j]); + bulk_reg[i+1].bytes = 4; + } + + mutex_lock(&pahu->swr.write_mutex); + ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, + (len * 2), false); + if (ret) { + dev_err(pahu->dev, "%s: swrm bulk write failed, ret: %d\n", + __func__, ret); + } + mutex_unlock(&pahu->swr.write_mutex); + + kfree(bulk_reg); + return ret; +} + +static int pahu_swrm_write(void *handle, int reg, int val) +{ + struct pahu_priv *pahu; + struct wcd9xxx *wcd9xxx; + unsigned short swr_wr_addr_base; + unsigned short swr_wr_data_base; + struct wcd9xxx_reg_val bulk_reg[2]; + int ret; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + pahu = (struct pahu_priv *)handle; + wcd9xxx = pahu->wcd9xxx; + + swr_wr_addr_base = WCD9360_SWR_AHB_BRIDGE_WR_ADDR_0; + swr_wr_data_base = WCD9360_SWR_AHB_BRIDGE_WR_DATA_0; + + /* First Write the Data to register */ + bulk_reg[0].reg = swr_wr_data_base; + bulk_reg[0].buf = (u8 *)(&val); + bulk_reg[0].bytes = 4; + bulk_reg[1].reg = swr_wr_addr_base; + bulk_reg[1].buf = (u8 *)(®); + bulk_reg[1].bytes = 4; + + mutex_lock(&pahu->swr.write_mutex); + ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, 2, false); + if (ret < 0) + dev_err(pahu->dev, "%s: WR Data Failure\n", __func__); + mutex_unlock(&pahu->swr.write_mutex); + + return ret; +} + +static int pahu_swrm_clock(void *handle, bool enable) +{ + struct pahu_priv *pahu; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + pahu = (struct pahu_priv *)handle; + + mutex_lock(&pahu->swr.clk_mutex); + dev_dbg(pahu->dev, "%s: swrm clock %s\n", + __func__, (enable?"enable" : "disable")); + if (enable) { + pahu->swr.clk_users++; + if (pahu->swr.clk_users == 1) { + regmap_update_bits(pahu->wcd9xxx->regmap, + WCD9360_TEST_DEBUG_NPL_DLY_TEST_1, + 0x10, 0x00); + __pahu_cdc_mclk_enable(pahu, true); + regmap_update_bits(pahu->wcd9xxx->regmap, + WCD9360_CDC_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x01); + } + } else { + pahu->swr.clk_users--; + if (pahu->swr.clk_users == 0) { + regmap_update_bits(pahu->wcd9xxx->regmap, + WCD9360_CDC_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x00); + __pahu_cdc_mclk_enable(pahu, false); + regmap_update_bits(pahu->wcd9xxx->regmap, + WCD9360_TEST_DEBUG_NPL_DLY_TEST_1, + 0x10, 0x10); + } + } + dev_dbg(pahu->dev, "%s: swrm clock users %d\n", + __func__, pahu->swr.clk_users); + mutex_unlock(&pahu->swr.clk_mutex); + + return 0; +} + +static int pahu_swrm_handle_irq(void *handle, + irqreturn_t (*swrm_irq_handler)(int irq, + void *data), + void *swrm_handle, + int action) +{ + struct pahu_priv *pahu; + int ret = 0; + struct wcd9xxx *wcd9xxx; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + pahu = (struct pahu_priv *) handle; + wcd9xxx = pahu->wcd9xxx; + + if (action) { + ret = wcd9xxx_request_irq(&wcd9xxx->core_res, + WCD9360_IRQ_SOUNDWIRE, + swrm_irq_handler, + "Pahu SWR Master", swrm_handle); + if (ret) + dev_err(pahu->dev, "%s: Failed to request irq %d\n", + __func__, WCD9360_IRQ_SOUNDWIRE); + } else + wcd9xxx_free_irq(&wcd9xxx->core_res, WCD9360_IRQ_SOUNDWIRE, + swrm_handle); + + return ret; +} + +static void pahu_codec_add_spi_device(struct pahu_priv *pahu, + struct device_node *node) +{ + struct spi_master *master; + struct spi_device *spi; + u32 prop_value; + int rc; + + /* Read the master bus num from DT node */ + rc = of_property_read_u32(node, "qcom,master-bus-num", + &prop_value); + if (rc < 0) { + dev_err(pahu->dev, "%s: prop %s not found in node %s", + __func__, "qcom,master-bus-num", node->full_name); + goto done; + } + + /* Get the reference to SPI master */ + master = spi_busnum_to_master(prop_value); + if (!master) { + dev_err(pahu->dev, "%s: Invalid spi_master for bus_num %u\n", + __func__, prop_value); + goto done; + } + + /* Allocate the spi device */ + spi = spi_alloc_device(master); + if (!spi) { + dev_err(pahu->dev, "%s: spi_alloc_device failed\n", + __func__); + goto err_spi_alloc_dev; + } + + /* Initialize device properties */ + if (of_modalias_node(node, spi->modalias, + sizeof(spi->modalias)) < 0) { + dev_err(pahu->dev, "%s: cannot find modalias for %s\n", + __func__, node->full_name); + goto err_dt_parse; + } + + rc = of_property_read_u32(node, "qcom,chip-select", + &prop_value); + if (rc < 0) { + dev_err(pahu->dev, "%s: prop %s not found in node %s", + __func__, "qcom,chip-select", node->full_name); + goto err_dt_parse; + } + spi->chip_select = prop_value; + + rc = of_property_read_u32(node, "qcom,max-frequency", + &prop_value); + if (rc < 0) { + dev_err(pahu->dev, "%s: prop %s not found in node %s", + __func__, "qcom,max-frequency", node->full_name); + goto err_dt_parse; + } + spi->max_speed_hz = prop_value; + + spi->dev.of_node = node; + + rc = spi_add_device(spi); + if (rc < 0) { + dev_err(pahu->dev, "%s: spi_add_device failed\n", __func__); + goto err_dt_parse; + } + + pahu->spi = spi; + /* Put the reference to SPI master */ + put_device(&master->dev); + + return; + +err_dt_parse: + spi_dev_put(spi); + +err_spi_alloc_dev: + /* Put the reference to SPI master */ + put_device(&master->dev); +done: + return; +} + +static void pahu_add_child_devices(struct work_struct *work) +{ + struct pahu_priv *pahu; + struct platform_device *pdev; + struct device_node *node; + struct wcd9xxx *wcd9xxx; + struct pahu_swr_ctrl_data *swr_ctrl_data = NULL, *temp; + int ret, ctrl_num = 0; + struct wcd_swr_ctrl_platform_data *platdata; + char plat_dev_name[WCD9360_STRING_LEN]; + + pahu = container_of(work, struct pahu_priv, + pahu_add_child_devices_work); + if (!pahu) { + pr_err("%s: Memory for wcd9360 does not exist\n", + __func__); + return; + } + wcd9xxx = pahu->wcd9xxx; + if (!wcd9xxx) { + pr_err("%s: Memory for WCD9XXX does not exist\n", + __func__); + return; + } + if (!wcd9xxx->dev->of_node) { + dev_err(wcd9xxx->dev, "%s: DT node for wcd9xxx does not exist\n", + __func__); + return; + } + + platdata = &pahu->swr.plat_data; + pahu->child_count = 0; + + for_each_child_of_node(wcd9xxx->dev->of_node, node) { + + /* Parse and add the SPI device node */ + if (!strcmp(node->name, "wcd_spi")) { + pahu_codec_add_spi_device(pahu, node); + continue; + } + + /* Parse other child device nodes and add platform device */ + if (!strcmp(node->name, "swr_master")) + strlcpy(plat_dev_name, "pahu_swr_ctrl", + (WCD9360_STRING_LEN - 1)); + else if (strnstr(node->name, "msm_cdc_pinctrl", + strlen("msm_cdc_pinctrl")) != NULL) + strlcpy(plat_dev_name, node->name, + (WCD9360_STRING_LEN - 1)); + else + continue; + + pdev = platform_device_alloc(plat_dev_name, -1); + if (!pdev) { + dev_err(wcd9xxx->dev, "%s: pdev memory alloc failed\n", + __func__); + ret = -ENOMEM; + goto err_mem; + } + pdev->dev.parent = pahu->dev; + pdev->dev.of_node = node; + + if (strcmp(node->name, "swr_master") == 0) { + ret = platform_device_add_data(pdev, platdata, + sizeof(*platdata)); + if (ret) { + dev_err(&pdev->dev, + "%s: cannot add plat data ctrl:%d\n", + __func__, ctrl_num); + goto err_pdev_add; + } + } + + ret = platform_device_add(pdev); + if (ret) { + dev_err(&pdev->dev, + "%s: Cannot add platform device\n", + __func__); + goto err_pdev_add; + } + + if (strcmp(node->name, "swr_master") == 0) { + temp = krealloc(swr_ctrl_data, + (ctrl_num + 1) * sizeof( + struct pahu_swr_ctrl_data), + GFP_KERNEL); + if (!temp) { + dev_err(wcd9xxx->dev, "out of memory\n"); + ret = -ENOMEM; + goto err_pdev_add; + } + swr_ctrl_data = temp; + swr_ctrl_data[ctrl_num].swr_pdev = pdev; + ctrl_num++; + dev_dbg(&pdev->dev, + "%s: Added soundwire ctrl device(s)\n", + __func__); + pahu->swr.ctrl_data = swr_ctrl_data; + } + if (pahu->child_count < WCD9360_CHILD_DEVICES_MAX) + pahu->pdev_child_devices[pahu->child_count++] = pdev; + else + goto err_mem; + } + + return; + +err_pdev_add: + platform_device_put(pdev); +err_mem: + return; +} + +static int __pahu_enable_efuse_sensing(struct pahu_priv *pahu) +{ + int val, rc; + + WCD9XXX_V2_BG_CLK_LOCK(pahu->resmgr); + __pahu_cdc_mclk_enable_locked(pahu, true); + + regmap_update_bits(pahu->wcd9xxx->regmap, + WCD9360_CHIP_TIER_CTRL_EFUSE_CTL, 0x1E, 0x10); + regmap_update_bits(pahu->wcd9xxx->regmap, + WCD9360_CHIP_TIER_CTRL_EFUSE_CTL, 0x01, 0x01); + /* + * 5ms sleep required after enabling efuse control + * before checking the status. + */ + usleep_range(5000, 5500); + wcd_resmgr_set_sido_input_src(pahu->resmgr, + SIDO_SOURCE_RCO_BG); + + WCD9XXX_V2_BG_CLK_UNLOCK(pahu->resmgr); + + rc = regmap_read(pahu->wcd9xxx->regmap, + WCD9360_CHIP_TIER_CTRL_EFUSE_STATUS, &val); + if (rc || (!(val & 0x01))) + WARN(1, "%s: Efuse sense is not complete val=%x, ret=%d\n", + __func__, val, rc); + + __pahu_cdc_mclk_enable(pahu, false); + + return rc; +} + +/* + * pahu_get_wcd_dsp_cntl: Get the reference to wcd_dsp_cntl + * @dev: Device pointer for codec device + * + * This API gets the reference to codec's struct wcd_dsp_cntl + */ +struct wcd_dsp_cntl *pahu_get_wcd_dsp_cntl(struct device *dev) +{ + struct platform_device *pdev; + struct pahu_priv *pahu; + + if (!dev) { + pr_err("%s: Invalid device\n", __func__); + return NULL; + } + + pdev = to_platform_device(dev); + pahu = platform_get_drvdata(pdev); + + return pahu->wdsp_cntl; +} +EXPORT_SYMBOL(pahu_get_wcd_dsp_cntl); + +static int pahu_probe(struct platform_device *pdev) +{ + int ret = 0; + struct pahu_priv *pahu; + struct clk *wcd_ext_clk; + struct wcd9xxx_resmgr_v2 *resmgr; + struct wcd9xxx_power_region *cdc_pwr; + + pahu = devm_kzalloc(&pdev->dev, sizeof(struct pahu_priv), + GFP_KERNEL); + if (!pahu) + return -ENOMEM; + + platform_set_drvdata(pdev, pahu); + + pahu->wcd9xxx = dev_get_drvdata(pdev->dev.parent); + pahu->dev = &pdev->dev; + INIT_DELAYED_WORK(&pahu->power_gate_work, pahu_codec_power_gate_work); + mutex_init(&pahu->power_lock); + INIT_WORK(&pahu->pahu_add_child_devices_work, + pahu_add_child_devices); + mutex_init(&pahu->micb_lock); + mutex_init(&pahu->swr.read_mutex); + mutex_init(&pahu->swr.write_mutex); + mutex_init(&pahu->swr.clk_mutex); + mutex_init(&pahu->codec_mutex); + mutex_init(&pahu->svs_mutex); + + /* + * Codec hardware by default comes up in SVS mode. + * Initialize the svs_ref_cnt to 1 to reflect the hardware + * state in the driver. + */ + pahu->svs_ref_cnt = 1; + + cdc_pwr = devm_kzalloc(&pdev->dev, sizeof(struct wcd9xxx_power_region), + GFP_KERNEL); + if (!cdc_pwr) { + ret = -ENOMEM; + goto err_resmgr; + } + pahu->wcd9xxx->wcd9xxx_pwr[WCD9XXX_DIG_CORE_REGION_1] = cdc_pwr; + cdc_pwr->pwr_collapse_reg_min = WCD9360_DIG_CORE_REG_MIN; + cdc_pwr->pwr_collapse_reg_max = WCD9360_DIG_CORE_REG_MAX; + wcd9xxx_set_power_state(pahu->wcd9xxx, + WCD_REGION_POWER_COLLAPSE_REMOVE, + WCD9XXX_DIG_CORE_REGION_1); + /* + * Init resource manager so that if child nodes such as SoundWire + * requests for clock, resource manager can honor the request + */ + resmgr = wcd_resmgr_init(&pahu->wcd9xxx->core_res, NULL); + if (IS_ERR(resmgr)) { + ret = PTR_ERR(resmgr); + dev_err(&pdev->dev, "%s: Failed to initialize wcd resmgr\n", + __func__); + goto err_resmgr; + } + pahu->resmgr = resmgr; + pahu->swr.plat_data.handle = (void *) pahu; + pahu->swr.plat_data.read = pahu_swrm_read; + pahu->swr.plat_data.write = pahu_swrm_write; + pahu->swr.plat_data.bulk_write = pahu_swrm_bulk_write; + pahu->swr.plat_data.clk = pahu_swrm_clock; + pahu->swr.plat_data.handle_irq = pahu_swrm_handle_irq; + pahu->swr.spkr_gain_offset = WCD9360_RX_GAIN_OFFSET_0_DB; + + /* Register for Clock */ + wcd_ext_clk = clk_get(pahu->wcd9xxx->dev, "wcd_clk"); + if (IS_ERR(wcd_ext_clk)) { + dev_err(pahu->wcd9xxx->dev, "%s: clk get %s failed\n", + __func__, "wcd_ext_clk"); + goto err_clk; + } + pahu->wcd_ext_clk = wcd_ext_clk; + dev_dbg(&pdev->dev, "%s: MCLK Rate = %x\n", __func__, + pahu->wcd9xxx->mclk_rate); + /* Update codec register default values */ + pahu_update_reg_defaults(pahu); + __pahu_enable_efuse_sensing(pahu); + pahu_update_cpr_defaults(pahu); + + /* Register with soc framework */ + ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pahu, + pahu_dai, ARRAY_SIZE(pahu_dai)); + if (ret) { + dev_err(&pdev->dev, "%s: Codec registration failed\n", + __func__); + goto err_cdc_reg; + } + schedule_work(&pahu->pahu_add_child_devices_work); + + return ret; + +err_cdc_reg: + clk_put(pahu->wcd_ext_clk); +err_clk: + wcd_resmgr_remove(pahu->resmgr); +err_resmgr: + mutex_destroy(&pahu->micb_lock); + mutex_destroy(&pahu->svs_mutex); + mutex_destroy(&pahu->codec_mutex); + mutex_destroy(&pahu->swr.read_mutex); + mutex_destroy(&pahu->swr.write_mutex); + mutex_destroy(&pahu->swr.clk_mutex); + devm_kfree(&pdev->dev, pahu); + + return ret; +} + +static int pahu_remove(struct platform_device *pdev) +{ + struct pahu_priv *pahu; + int count = 0; + + pahu = platform_get_drvdata(pdev); + if (!pahu) + return -EINVAL; + + if (pahu->spi) + spi_unregister_device(pahu->spi); + for (count = 0; count < pahu->child_count && + count < WCD9360_CHILD_DEVICES_MAX; count++) + platform_device_unregister(pahu->pdev_child_devices[count]); + + mutex_destroy(&pahu->micb_lock); + mutex_destroy(&pahu->svs_mutex); + mutex_destroy(&pahu->codec_mutex); + mutex_destroy(&pahu->swr.read_mutex); + mutex_destroy(&pahu->swr.write_mutex); + mutex_destroy(&pahu->swr.clk_mutex); + + snd_soc_unregister_codec(&pdev->dev); + clk_put(pahu->wcd_ext_clk); + wcd_resmgr_remove(pahu->resmgr); + devm_kfree(&pdev->dev, pahu); + return 0; +} + +static struct platform_driver pahu_codec_driver = { + .probe = pahu_probe, + .remove = pahu_remove, + .driver = { + .name = "pahu_codec", + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &pahu_pm_ops, +#endif + }, +}; + +module_platform_driver(pahu_codec_driver); + +MODULE_DESCRIPTION("Pahu Codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/wcd9360/wcd9360.h b/asoc/codecs/wcd9360/wcd9360.h new file mode 100644 index 000000000000..32e542472319 --- /dev/null +++ b/asoc/codecs/wcd9360/wcd9360.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __WCD9360_H__ +#define __WCD9360_H__ + +#include +#include "wcd9360-dsp-cntl.h" +#include "../wcd9xxx-slimslave.h" +#include "../wcd9xxx-common-v2.h" + +#define WCD9360_REGISTER_START_OFFSET 0x800 +#define WCD9360_SB_PGD_PORT_RX_BASE 0x40 +#define WCD9360_SB_PGD_PORT_TX_BASE 0x50 +#define WCD9360_RX_PORT_START_NUMBER 16 + +#define WCD9360_DMIC_CLK_DIV_2 0x0 +#define WCD9360_DMIC_CLK_DIV_3 0x1 +#define WCD9360_DMIC_CLK_DIV_4 0x2 +#define WCD9360_DMIC_CLK_DIV_6 0x3 +#define WCD9360_DMIC_CLK_DIV_8 0x4 +#define WCD9360_DMIC_CLK_DIV_16 0x5 +#define WCD9360_DMIC_CLK_DRIVE_DEFAULT 0x02 + +#define WCD9360_ANC_DMIC_X2_FULL_RATE 1 +#define WCD9360_ANC_DMIC_X2_HALF_RATE 0 + +#define PAHU_MAX_MICBIAS 4 +#define PAHU_NUM_INTERPOLATORS 10 +#define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64 + +/* Convert from vout ctl to micbias voltage in mV */ +#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50) + + +/* Number of input and output Slimbus port */ +enum { + WCD9360_RX0 = 0, + WCD9360_RX1, + WCD9360_RX2, + WCD9360_RX3, + WCD9360_RX4, + WCD9360_RX5, + WCD9360_RX6, + WCD9360_RX7, + WCD9360_RX_MAX, +}; + +enum { + WCD9360_TX0 = 0, + WCD9360_TX1, + WCD9360_TX2, + WCD9360_TX3, + WCD9360_TX4, + WCD9360_TX5, + WCD9360_TX6, + WCD9360_TX7, + WCD9360_TX8, + WCD9360_TX9, + WCD9360_TX10, + WCD9360_TX11, + WCD9360_TX12, + WCD9360_TX13, + WCD9360_TX14, + WCD9360_TX15, + WCD9360_TX_MAX, +}; + +enum { + INTERP_EAR = 0, + /* Headset and Lineout are not avalible in pahu */ + INTERP_HPHL_NA, + INTERP_HPHR_NA, + INTERP_LO1_NA, + INTERP_LO2_NA, + INTERP_LO3_NA, + INTERP_LO4_NA, + INTERP_SPKR1, + INTERP_SPKR2, + INTERP_AUX, + INTERP_MAX, +}; + +/* + * Selects compander and smart boost settings + * for a given speaker mode + */ +enum { + WCD9360_SPKR_MODE_DEFAULT, + WCD9360_SPKR_MODE_1, /* COMP Gain = 12dB, Smartboost Max = 5.5V */ +}; + +/* + * Rx path gain offsets + */ +enum { + WCD9360_RX_GAIN_OFFSET_M1P5_DB, + WCD9360_RX_GAIN_OFFSET_0_DB, +}; + +enum { + MIC_BIAS_1 = 1, + MIC_BIAS_2, + MIC_BIAS_3, + MIC_BIAS_4 +}; + +enum { + MICB_PULLUP_ENABLE, + MICB_PULLUP_DISABLE, + MICB_ENABLE, + MICB_DISABLE, +}; + +/* + * Dai data structure holds the + * dai specific info like rate, + * channel number etc. + */ +struct pahu_codec_dai_data { + u32 rate; + u32 *ch_num; + u32 ch_act; + u32 ch_tot; +}; + +/* + * Structure used to update codec + * register defaults after reset + */ +struct pahu_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + +extern void *pahu_get_afe_config(struct snd_soc_codec *codec, + enum afe_config_type config_type); +extern int pahu_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable); +extern int pahu_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable); +extern int pahu_set_spkr_mode(struct snd_soc_codec *codec, int mode); +extern int pahu_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset); +extern struct wcd_dsp_cntl *pahu_get_wcd_dsp_cntl(struct device *dev); +extern int wcd9360_get_micb_vout_ctl_val(u32 micb_mv); +extern int pahu_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_codec *codec); +#endif diff --git a/include/asoc/wcd9360-registers.h b/include/asoc/wcd9360-registers.h new file mode 100644 index 000000000000..bca9de3019e3 --- /dev/null +++ b/include/asoc/wcd9360-registers.h @@ -0,0 +1,1158 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _WCD9360_REGISTERS_H +#define _WCD9360_REGISTERS_H + +#define WCD9360_PAGE_SIZE 256 +#define WCD9360_NUM_PAGES 256 + +enum { + WCD9360_PAGE_0 = 0, + WCD9360_PAGE_1, + WCD9360_PAGE_2, + WCD9360_PAGE_4 = 4, + WCD9360_PAGE_6 = 6, + WCD9360_PAGE_7, + WCD9360_PAGE_10 = 10, + WCD9360_PAGE_11, + WCD9360_PAGE_12, + WCD9360_PAGE_13, + WCD9360_PAGE_14, + WCD9360_PAGE_80, + WCD9360_PAGE_128, + WCD9360_PAGE_MAX, +}; + +enum { + WCD9360_WO = 0, + WCD9360_RO, + WCD9360_RW, +}; + +extern const u8 * const wcd9360_reg[WCD9360_PAGE_MAX]; + +/* Page-0 Registers */ +#define WCD9360_PAGE0_PAGE_REGISTER (0x00000000) +#define WCD9360_CODEC_RPM_CLK_BYPASS (0x00000001) +#define WCD9360_CODEC_RPM_CLK_GATE (0x00000002) +#define WCD9360_CODEC_RPM_CLK_MCLK_CFG (0x00000003) +#define WCD9360_CODEC_RPM_CLK_MCLK2_CFG (0x00000004) +#define WCD9360_CODEC_RPM_I2S_DSD_CLK_SEL (0x00000005) +#define WCD9360_CODEC_RPM_RST_CTL (0x00000009) +#define WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL (0x00000011) +#define WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE0 (0x00000021) +#define WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE1 (0x00000022) +#define WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE2 (0x00000023) +#define WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE3 (0x00000024) +#define WCD9360_CHIP_TIER_CTRL_EFUSE_CTL (0x00000025) +#define WCD9360_CHIP_TIER_CTRL_EFUSE_TEST0 (0x00000026) +#define WCD9360_CHIP_TIER_CTRL_EFUSE_TEST1 (0x00000027) +#define WCD9360_CHIP_TIER_CTRL_EFUSE_STATUS (0x00000039) +#define WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO (0x0000003A) +#define WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_1 (0x0000003B) +#define WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_2 (0x0000003C) +#define WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_3 (0x0000003D) +#define WCD9360_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL (0x0000003E) +#define WCD9360_CHIP_TIER_CTRL_I2C_ACTIVE (0x00000040) +#define WCD9360_CHIP_TIER_CTRL_ALT_FUNC_EN (0x00000041) +#define WCD9360_CHIP_TIER_CTRL_GPIO_CTL_OE (0x00000042) +#define WCD9360_CHIP_TIER_CTRL_GPIO_CTL_DATA (0x00000043) +#define WCD9360_DATA_HUB_RX0_CFG (0x00000051) +#define WCD9360_DATA_HUB_RX1_CFG (0x00000052) +#define WCD9360_DATA_HUB_RX2_CFG (0x00000053) +#define WCD9360_DATA_HUB_RX3_CFG (0x00000054) +#define WCD9360_DATA_HUB_RX4_CFG (0x00000055) +#define WCD9360_DATA_HUB_RX5_CFG (0x00000056) +#define WCD9360_DATA_HUB_RX6_CFG (0x00000057) +#define WCD9360_DATA_HUB_RX7_CFG (0x00000058) +#define WCD9360_DATA_HUB_SB_TX0_INP_CFG (0x00000061) +#define WCD9360_DATA_HUB_SB_TX1_INP_CFG (0x00000062) +#define WCD9360_DATA_HUB_SB_TX2_INP_CFG (0x00000063) +#define WCD9360_DATA_HUB_SB_TX3_INP_CFG (0x00000064) +#define WCD9360_DATA_HUB_SB_TX4_INP_CFG (0x00000065) +#define WCD9360_DATA_HUB_SB_TX5_INP_CFG (0x00000066) +#define WCD9360_DATA_HUB_SB_TX6_INP_CFG (0x00000067) +#define WCD9360_DATA_HUB_SB_TX7_INP_CFG (0x00000068) +#define WCD9360_DATA_HUB_SB_TX8_INP_CFG (0x00000069) +#define WCD9360_DATA_HUB_SB_TX9_INP_CFG (0x0000006A) +#define WCD9360_DATA_HUB_SB_TX10_INP_CFG (0x0000006B) +#define WCD9360_DATA_HUB_SB_TX11_INP_CFG (0x0000006C) +#define WCD9360_DATA_HUB_SB_TX12_INP_CFG (0x0000006D) +#define WCD9360_DATA_HUB_SB_TX13_INP_CFG (0x0000006E) +#define WCD9360_DATA_HUB_SB_TX14_INP_CFG (0x0000006F) +#define WCD9360_DATA_HUB_SB_TX15_INP_CFG (0x00000070) +#define WCD9360_DATA_HUB_I2S_TX0_CFG (0x00000071) +#define WCD9360_DATA_HUB_I2S_TX0_CFG2 (0x00000072) +#define WCD9360_DATA_HUB_I2S_TX1_0_CFG (0x00000073) +#define WCD9360_DATA_HUB_I2S_TX1_1_CFG (0x00000074) +#define WCD9360_DATA_HUB_DATA_HUB_CFG (0x00000079) +#define WCD9360_DATA_HUB_I2S_0_CTL (0x00000081) +#define WCD9360_DATA_HUB_I2S_1_CTL (0x00000082) +#define WCD9360_DATA_HUB_I2S_0_CTL2 (0x00000083) +#define WCD9360_DATA_HUB_I2S_1_CTL2 (0x00000084) +#define WCD9360_DATA_HUB_I2S_CLKSRC_CTL (0x00000085) +#define WCD9360_DATA_HUB_I2S_COMMON_CTL (0x00000086) +#define WCD9360_DATA_HUB_I2S_0_TDM_CTL (0x00000087) +#define WCD9360_DATA_HUB_I2S_0_TDM_CTL2 (0x00000089) +#define WCD9360_DATA_HUB_I2S_0_TDM_CH_RX (0x0000008A) +#define WCD9360_DATA_HUB_I2S_0_TDM_CH_TX (0x0000008B) +#define WCD9360_DATA_HUB_I2S_0_TDM_CFG (0x0000008C) +#define WCD9360_DATA_HUB_I2S_0_TDM_STRETCH (0x0000008D) +#define WCD9360_DATA_HUB_I2S_RESET_CTL (0x00000090) +#define WCD9360_DMA_RDMA_CTL_0 (0x00000091) +#define WCD9360_DMA_CH_2_3_CFG_RDMA_0 (0x00000092) +#define WCD9360_DMA_CH_0_1_CFG_RDMA_0 (0x00000093) +#define WCD9360_DMA_RDMA_CTL_1 (0x00000094) +#define WCD9360_DMA_CH_2_3_CFG_RDMA_1 (0x00000095) +#define WCD9360_DMA_CH_0_1_CFG_RDMA_1 (0x00000096) +#define WCD9360_DMA_RDMA_CTL_2 (0x00000097) +#define WCD9360_DMA_CH_2_3_CFG_RDMA_2 (0x00000098) +#define WCD9360_DMA_CH_0_1_CFG_RDMA_2 (0x00000099) +#define WCD9360_DMA_RDMA_CTL_3 (0x0000009A) +#define WCD9360_DMA_CH_2_3_CFG_RDMA_3 (0x0000009B) +#define WCD9360_DMA_CH_0_1_CFG_RDMA_3 (0x0000009C) +#define WCD9360_DMA_RDMA_CTL_4 (0x0000009D) +#define WCD9360_DMA_CH_2_3_CFG_RDMA_4 (0x0000009E) +#define WCD9360_DMA_CH_0_1_CFG_RDMA_4 (0x0000009F) +#define WCD9360_DMA_RDMA4_PRT_CFG (0x000000B1) +#define WCD9360_DMA_RDMA_SBTX0_7_CFG (0x000000B9) +#define WCD9360_DMA_RDMA_SBTX8_10_CFG (0x000000BA) +#define WCD9360_DMA_WDMA_CTL_0 (0x000000C1) +#define WCD9360_DMA_WDMA_CTL_1 (0x000000C6) +#define WCD9360_DMA_WDMA_CTL_2 (0x000000CB) +#define WCD9360_DMA_WDMA_CTL_3 (0x000000D0) +#define WCD9360_DMA_WDMA_CTL_4 (0x000000D5) +#define WCD9360_DMA_CH_4_5_CFG_WDMA_0 (0x000000C2) +#define WCD9360_DMA_CH_4_5_CFG_WDMA_1 (0x000000C7) +#define WCD9360_DMA_CH_4_5_CFG_WDMA_2 (0x000000CC) +#define WCD9360_DMA_CH_4_5_CFG_WDMA_3 (0x000000D1) +#define WCD9360_DMA_CH_4_5_CFG_WDMA_4 (0x000000D6) +#define WCD9360_DMA_CH_2_3_CFG_WDMA_0 (0x000000C3) +#define WCD9360_DMA_CH_2_3_CFG_WDMA_1 (0x000000C8) +#define WCD9360_DMA_CH_2_3_CFG_WDMA_2 (0x000000CD) +#define WCD9360_DMA_CH_2_3_CFG_WDMA_3 (0x000000D2) +#define WCD9360_DMA_CH_2_3_CFG_WDMA_4 (0x000000D7) +#define WCD9360_DMA_CH_0_1_CFG_WDMA_0 (0x000000C4) +#define WCD9360_DMA_CH_0_1_CFG_WDMA_1 (0x000000C9) +#define WCD9360_DMA_CH_0_1_CFG_WDMA_2 (0x000000CE) +#define WCD9360_DMA_CH_0_1_CFG_WDMA_3 (0x000000D3) +#define WCD9360_DMA_CH_0_1_CFG_WDMA_4 (0x000000D8) +#define WCD9360_DMA_WDMA0_PRT_CFG (0x000000E1) +#define WCD9360_DMA_WDMA3_PRT_CFG (0x000000E2) +#define WCD9360_DMA_WDMA4_PRT0_3_CFG (0x000000E3) +#define WCD9360_DMA_WDMA4_PRT4_7_CFG (0x000000E4) +#define WCD9360_PAGE1_PAGE_REGISTER (0x00000100) +#define WCD9360_CPE_FLL_USER_CTL_0 (0x00000101) +#define WCD9360_CPE_FLL_USER_CTL_1 (0x00000102) +#define WCD9360_CPE_FLL_USER_CTL_2 (0x00000103) +#define WCD9360_CPE_FLL_USER_CTL_3 (0x00000104) +#define WCD9360_CPE_FLL_USER_CTL_4 (0x00000105) +#define WCD9360_CPE_FLL_USER_CTL_5 (0x00000106) +#define WCD9360_CPE_FLL_USER_CTL_6 (0x00000107) +#define WCD9360_CPE_FLL_USER_CTL_7 (0x00000108) +#define WCD9360_CPE_FLL_USER_CTL_8 (0x00000109) +#define WCD9360_CPE_FLL_USER_CTL_9 (0x0000010A) +#define WCD9360_CPE_FLL_L_VAL_CTL_0 (0x0000010B) +#define WCD9360_CPE_FLL_L_VAL_CTL_1 (0x0000010C) +#define WCD9360_CPE_FLL_DSM_FRAC_CTL_0 (0x0000010D) +#define WCD9360_CPE_FLL_DSM_FRAC_CTL_1 (0x0000010E) +#define WCD9360_CPE_FLL_CONFIG_CTL_0 (0x0000010F) +#define WCD9360_CPE_FLL_CONFIG_CTL_1 (0x00000110) +#define WCD9360_CPE_FLL_CONFIG_CTL_2 (0x00000111) +#define WCD9360_CPE_FLL_CONFIG_CTL_3 (0x00000112) +#define WCD9360_CPE_FLL_CONFIG_CTL_4 (0x00000113) +#define WCD9360_CPE_FLL_TEST_CTL_0 (0x00000114) +#define WCD9360_CPE_FLL_TEST_CTL_1 (0x00000115) +#define WCD9360_CPE_FLL_TEST_CTL_2 (0x00000116) +#define WCD9360_CPE_FLL_TEST_CTL_3 (0x00000117) +#define WCD9360_CPE_FLL_TEST_CTL_4 (0x00000118) +#define WCD9360_CPE_FLL_TEST_CTL_5 (0x00000119) +#define WCD9360_CPE_FLL_TEST_CTL_6 (0x0000011A) +#define WCD9360_CPE_FLL_TEST_CTL_7 (0x0000011B) +#define WCD9360_CPE_FLL_FREQ_CTL_0 (0x0000011C) +#define WCD9360_CPE_FLL_FREQ_CTL_1 (0x0000011D) +#define WCD9360_CPE_FLL_FREQ_CTL_2 (0x0000011E) +#define WCD9360_CPE_FLL_FREQ_CTL_3 (0x0000011F) +#define WCD9360_CPE_FLL_SSC_CTL_0 (0x00000120) +#define WCD9360_CPE_FLL_SSC_CTL_1 (0x00000121) +#define WCD9360_CPE_FLL_SSC_CTL_2 (0x00000122) +#define WCD9360_CPE_FLL_SSC_CTL_3 (0x00000123) +#define WCD9360_CPE_FLL_FLL_MODE (0x00000124) +#define WCD9360_CPE_FLL_STATUS_0 (0x00000125) +#define WCD9360_CPE_FLL_STATUS_1 (0x00000126) +#define WCD9360_CPE_FLL_STATUS_2 (0x00000127) +#define WCD9360_CPE_FLL_STATUS_3 (0x00000128) +#define WCD9360_I2S_FLL_USER_CTL_0 (0x00000141) +#define WCD9360_I2S_FLL_USER_CTL_1 (0x00000142) +#define WCD9360_I2S_FLL_USER_CTL_2 (0x00000143) +#define WCD9360_I2S_FLL_USER_CTL_3 (0x00000144) +#define WCD9360_I2S_FLL_USER_CTL_4 (0x00000145) +#define WCD9360_I2S_FLL_USER_CTL_5 (0x00000146) +#define WCD9360_I2S_FLL_USER_CTL_6 (0x00000147) +#define WCD9360_I2S_FLL_USER_CTL_7 (0x00000148) +#define WCD9360_I2S_FLL_USER_CTL_8 (0x00000149) +#define WCD9360_I2S_FLL_USER_CTL_9 (0x0000014A) +#define WCD9360_I2S_FLL_L_VAL_CTL_0 (0x0000014B) +#define WCD9360_I2S_FLL_L_VAL_CTL_1 (0x0000014C) +#define WCD9360_I2S_FLL_DSM_FRAC_CTL_0 (0x0000014D) +#define WCD9360_I2S_FLL_DSM_FRAC_CTL_1 (0x0000014E) +#define WCD9360_I2S_FLL_CONFIG_CTL_0 (0x0000014F) +#define WCD9360_I2S_FLL_CONFIG_CTL_1 (0x00000150) +#define WCD9360_I2S_FLL_CONFIG_CTL_2 (0x00000151) +#define WCD9360_I2S_FLL_CONFIG_CTL_3 (0x00000152) +#define WCD9360_I2S_FLL_CONFIG_CTL_4 (0x00000153) +#define WCD9360_I2S_FLL_TEST_CTL_0 (0x00000154) +#define WCD9360_I2S_FLL_TEST_CTL_1 (0x00000155) +#define WCD9360_I2S_FLL_TEST_CTL_2 (0x00000156) +#define WCD9360_I2S_FLL_TEST_CTL_3 (0x00000157) +#define WCD9360_I2S_FLL_TEST_CTL_4 (0x00000158) +#define WCD9360_I2S_FLL_TEST_CTL_5 (0x00000159) +#define WCD9360_I2S_FLL_TEST_CTL_6 (0x0000015A) +#define WCD9360_I2S_FLL_TEST_CTL_7 (0x0000015B) +#define WCD9360_I2S_FLL_FREQ_CTL_0 (0x0000015C) +#define WCD9360_I2S_FLL_FREQ_CTL_1 (0x0000015D) +#define WCD9360_I2S_FLL_FREQ_CTL_2 (0x0000015E) +#define WCD9360_I2S_FLL_FREQ_CTL_3 (0x0000015F) +#define WCD9360_I2S_FLL_SSC_CTL_0 (0x00000160) +#define WCD9360_I2S_FLL_SSC_CTL_1 (0x00000161) +#define WCD9360_I2S_FLL_SSC_CTL_2 (0x00000162) +#define WCD9360_I2S_FLL_SSC_CTL_3 (0x00000163) +#define WCD9360_I2S_FLL_FLL_MODE (0x00000164) +#define WCD9360_I2S_FLL_STATUS_0 (0x00000165) +#define WCD9360_I2S_FLL_STATUS_1 (0x00000166) +#define WCD9360_I2S_FLL_STATUS_2 (0x00000167) +#define WCD9360_I2S_FLL_STATUS_3 (0x00000168) +#define WCD9360_PAGE2_PAGE_REGISTER (0x00000200) +#define WCD9360_CPE_SS_CPE_CTL (0x00000201) +#define WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_0 (0x00000202) +#define WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_1 (0x00000203) +#define WCD9360_CPE_SS_PWR_CPEFLL_CTL (0x00000204) +#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0 (0x00000205) +#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1 (0x00000206) +#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0 (0x00000208) +#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1 (0x00000209) +#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2 (0x0000020A) +#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3 (0x0000020B) +#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_4 (0x0000020C) +#define WCD9360_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN (0x0000020E) +#define WCD9360_CPE_SS_US_BUF_INT_PERIOD (0x00000212) +#define WCD9360_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD (0x00000213) +#define WCD9360_CPE_SS_SVA_CFG (0x00000214) +#define WCD9360_CPE_SS_US_CFG (0x00000215) +#define WCD9360_CPE_SS_MAD_CTL (0x00000216) +#define WCD9360_CPE_SS_CPAR_CTL (0x00000217) +#define WCD9360_CPE_SS_DMIC0_CTL (0x00000218) +#define WCD9360_CPE_SS_DMIC1_CTL (0x00000219) +#define WCD9360_CPE_SS_DMIC2_CTL (0x0000021A) +#define WCD9360_CPE_SS_DMIC_CFG (0x0000021B) +#define WCD9360_CPE_SS_CPAR_CFG (0x0000021C) +#define WCD9360_CPE_SS_WDOG_CFG (0x0000021D) +#define WCD9360_CPE_SS_BACKUP_INT (0x0000021E) +#define WCD9360_CPE_SS_STATUS (0x0000021F) +#define WCD9360_CPE_SS_CPE_OCD_CFG (0x00000220) +#define WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A (0x00000221) +#define WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B (0x00000222) +#define WCD9360_CPE_SS_SS_ERROR_INT_MASK_1A (0x00000223) +#define WCD9360_CPE_SS_SS_ERROR_INT_MASK_1B (0x00000224) +#define WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0A (0x00000225) +#define WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0B (0x00000226) +#define WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1A (0x00000227) +#define WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1B (0x00000228) +#define WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0A (0x00000229) +#define WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0B (0x0000022A) +#define WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1A (0x0000022B) +#define WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1B (0x0000022C) +#define WCD9360_CPE_SS_DMIC3_CTL (0x00000231) +#define WCD9360_CPE_SS_WDOG_RESET (0x00000239) +#define WCD9360_CPE_SS_LPASS_MCLK_PRG (0x00000240) +#define WCD9360_CPE_SS_LPASS_IPC_IN_0 (0x00000241) +#define WCD9360_CPE_SS_LPASS_IPC_IN_1 (0x00000242) +#define WCD9360_CPE_SS_LPASS_IPC_IN_2 (0x00000243) +#define WCD9360_CPE_SS_LPASS_IPC_IN_3 (0x00000244) +#define WCD9360_CPE_SS_LPASS_IPC_IN_4 (0x00000245) +#define WCD9360_CPE_SS_LPASS_IPC_IN_5 (0x00000246) +#define WCD9360_CPE_SS_LPASS_IPC_IN_6 (0x00000247) +#define WCD9360_CPE_SS_LPASS_IPC_IN_7 (0x00000248) +#define WCD9360_CPE_SS_LPASS_IPC_IN_8 (0x00000249) +#define WCD9360_CPE_SS_LPASS_IPC_IN_9 (0x0000024A) +#define WCD9360_CPE_SS_LPASS_IPC_IN_10 (0x0000024B) +#define WCD9360_CPE_SS_LPASS_IPC_IN_11 (0x0000024C) +#define WCD9360_CPE_SS_LPASS_IPC_IN_12 (0x0000024D) +#define WCD9360_CPE_SS_LPASS_IPC_IN_13 (0x0000024E) +#define WCD9360_CPE_SS_LPASS_IPC_IN_14 (0x0000024F) +#define WCD9360_CPE_SS_LPASS_IPC_IN_15 (0x00000250) +#define WCD9360_CPE_SS_LPASS_IPC_OUT_0 (0x00000251) +#define WCD9360_CPE_SS_LPASS_IPC_OUT_1 (0x00000252) +#define WCD9360_CPE_SS_LPASS_IPC_OUT_2 (0x00000253) +#define WCD9360_CPE_SS_LPASS_IPC_OUT_3 (0x00000254) +#define WCD9360_CPE_SS_LPASS_IPC_OUT_4 (0x00000255) +#define WCD9360_CPE_SS_LPASS_IPC_OUT_5 (0x00000256) +#define WCD9360_CPE_SS_LPASS_IPC_OUT_6 (0x00000257) +#define WCD9360_CPE_SS_LPASS_IPC_OUT_7 (0x00000258) +#define WCD9360_CPE_SS_LPASS_IPC_OUT_8 (0x00000259) +#define WCD9360_CPE_SS_LPASS_IPC_OUT_9 (0x0000025A) +#define WCD9360_CPE_SS_LPASS_IPC_OUT_10 (0x0000025B) +#define WCD9360_CPE_SS_LPASS_IPC_OUT_11 (0x0000025C) +#define WCD9360_CPE_SS_LPASS_IPC_OUT_12 (0x0000025D) +#define WCD9360_CPE_SS_LPASS_IPC_OUT_13 (0x0000025E) +#define WCD9360_CPE_SS_LPASS_IPC_OUT_14 (0x0000025F) +#define WCD9360_CPE_SS_LPASS_IPC_OUT_15 (0x00000260) +#define WCD9360_CPE_SS_LPASS_ARB_CTL (0x00000261) +#define WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_0 (0x00000271) +#define WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_1 (0x00000272) +#define WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_0 (0x00000273) +#define WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_1 (0x00000274) +#define WCD9360_SOC_MAD_MAIN_CTL_1 (0x00000281) +#define WCD9360_SOC_MAD_MAIN_CTL_2 (0x00000282) +#define WCD9360_SOC_MAD_AUDIO_CTL_1 (0x00000283) +#define WCD9360_SOC_MAD_AUDIO_CTL_2 (0x00000284) +#define WCD9360_SOC_MAD_AUDIO_CTL_3 (0x00000285) +#define WCD9360_SOC_MAD_AUDIO_CTL_4 (0x00000286) +#define WCD9360_SOC_MAD_AUDIO_CTL_5 (0x00000287) +#define WCD9360_SOC_MAD_AUDIO_CTL_6 (0x00000288) +#define WCD9360_SOC_MAD_AUDIO_CTL_7 (0x00000289) +#define WCD9360_SOC_MAD_AUDIO_CTL_8 (0x0000028A) +#define WCD9360_SOC_MAD_AUDIO_IIR_CTL_PTR (0x0000028B) +#define WCD9360_SOC_MAD_AUDIO_IIR_CTL_VAL (0x0000028C) +#define WCD9360_SOC_MAD_ULTR_CTL_1 (0x0000028D) +#define WCD9360_SOC_MAD_ULTR_CTL_2 (0x0000028E) +#define WCD9360_SOC_MAD_ULTR_CTL_3 (0x0000028F) +#define WCD9360_SOC_MAD_ULTR_CTL_4 (0x00000290) +#define WCD9360_SOC_MAD_ULTR_CTL_5 (0x00000291) +#define WCD9360_SOC_MAD_ULTR_CTL_6 (0x00000292) +#define WCD9360_SOC_MAD_ULTR_CTL_7 (0x00000293) +#define WCD9360_SOC_MAD_BEACON_CTL_1 (0x00000294) +#define WCD9360_SOC_MAD_BEACON_CTL_2 (0x00000295) +#define WCD9360_SOC_MAD_BEACON_CTL_3 (0x00000296) +#define WCD9360_SOC_MAD_BEACON_CTL_4 (0x00000297) +#define WCD9360_SOC_MAD_BEACON_CTL_5 (0x00000298) +#define WCD9360_SOC_MAD_BEACON_CTL_6 (0x00000299) +#define WCD9360_SOC_MAD_BEACON_CTL_7 (0x0000029A) +#define WCD9360_SOC_MAD_BEACON_CTL_8 (0x0000029B) +#define WCD9360_SOC_MAD_BEACON_IIR_CTL_PTR (0x0000029C) +#define WCD9360_SOC_MAD_BEACON_IIR_CTL_VAL (0x0000029D) +#define WCD9360_SOC_MAD_INP_SEL (0x0000029E) +#define WCD9360_SOC_MAD_MAD2_INP_SEL (0x0000029F) +#define WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_CTRL (0x000002B1) +#define WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_STATUS (0x000002B2) +#define WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_FS (0x000002B3) +#define WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_IN_SEL (0x000002B4) +#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT0 (0x000002C1) +#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT1 (0x000002C2) +#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT2 (0x000002C3) +#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT3 (0x000002C4) +#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT4 (0x000002C5) +#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT5 (0x000002C6) +#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT6 (0x000002C7) +#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT7 (0x000002C8) +#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT8 (0x000002C9) +#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT9 (0x000002CA) +#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT10 (0x000002CB) +#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT11 (0x000002CC) +#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT12 (0x000002CD) +#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT13 (0x000002CE) +#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT14 (0x000002CF) +#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT15 (0x000002D0) +#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT0 (0x000002D1) +#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT1 (0x000002D2) +#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT2 (0x000002D3) +#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT3 (0x000002D4) +#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT4 (0x000002D5) +#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT5 (0x000002D6) +#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT6 (0x000002D7) +#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT7 (0x000002D8) +#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT8 (0x000002D9) +#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT9 (0x000002DA) +#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT10 (0x000002DB) +#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT11 (0x000002DC) +#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT12 (0x000002DD) +#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT13 (0x000002DE) +#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT14 (0x000002DF) +#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT15 (0x000002E0) +#define WCD9360_PAGE4_PAGE_REGISTER (0x00000400) +#define WCD9360_INTR_CFG (0x00000401) +#define WCD9360_INTR_CLR_COMMIT (0x00000402) +#define WCD9360_INTR_PIN1_MASK0 (0x00000409) +#define WCD9360_INTR_PIN1_MASK1 (0x0000040A) +#define WCD9360_INTR_PIN1_MASK2 (0x0000040B) +#define WCD9360_INTR_PIN1_MASK3 (0x0000040C) +#define WCD9360_INTR_PIN1_STATUS0 (0x00000411) +#define WCD9360_INTR_PIN1_STATUS1 (0x00000412) +#define WCD9360_INTR_PIN1_STATUS2 (0x00000413) +#define WCD9360_INTR_PIN1_STATUS3 (0x00000414) +#define WCD9360_INTR_PIN1_CLEAR0 (0x00000419) +#define WCD9360_INTR_PIN1_CLEAR1 (0x0000041A) +#define WCD9360_INTR_PIN1_CLEAR2 (0x0000041B) +#define WCD9360_INTR_PIN1_CLEAR3 (0x0000041C) +#define WCD9360_INTR_PIN2_MASK3 (0x00000424) +#define WCD9360_INTR_PIN2_STATUS3 (0x0000042C) +#define WCD9360_INTR_PIN2_CLEAR3 (0x00000434) +#define WCD9360_INTR_CPESS_SUMRY_MASK2 (0x0000043B) +#define WCD9360_INTR_CPESS_SUMRY_MASK3 (0x0000043C) +#define WCD9360_INTR_CPESS_SUMRY_STATUS2 (0x00000443) +#define WCD9360_INTR_CPESS_SUMRY_STATUS3 (0x00000444) +#define WCD9360_INTR_CPESS_SUMRY_CLEAR2 (0x0000044B) +#define WCD9360_INTR_CPESS_SUMRY_CLEAR3 (0x0000044C) +#define WCD9360_INTR_LEVEL0 (0x00000461) +#define WCD9360_INTR_LEVEL1 (0x00000462) +#define WCD9360_INTR_LEVEL2 (0x00000463) +#define WCD9360_INTR_LEVEL3 (0x00000464) +#define WCD9360_INTR_BYPASS0 (0x00000469) +#define WCD9360_INTR_BYPASS1 (0x0000046A) +#define WCD9360_INTR_BYPASS2 (0x0000046B) +#define WCD9360_INTR_BYPASS3 (0x0000046C) +#define WCD9360_INTR_SET0 (0x00000471) +#define WCD9360_INTR_SET1 (0x00000472) +#define WCD9360_INTR_SET2 (0x00000473) +#define WCD9360_INTR_SET3 (0x00000474) +#define WCD9360_INTR_CODEC_MISC_MASK (0x000004B1) +#define WCD9360_INTR_CODEC_MISC_STATUS (0x000004B2) +#define WCD9360_INTR_CODEC_MISC_CLEAR (0x000004B3) +#define WCD9360_ANA_PAGE_REGISTER (0x00000600) +#define WCD9360_ANA_BIAS (0x00000601) +#define WCD9360_ANA_AMIC_INPUT_SWITCH_CTL (0x00000602) +#define WCD9360_ANA_RCO (0x00000603) +#define WCD9360_ANA_BUCK_CTL (0x00000606) +#define WCD9360_ANA_BUCK_STATUS (0x00000607) +#define WCD9360_ANA_EAR (0x0000060A) +#define WCD9360_ANA_MAD_SETUP (0x0000060D) +#define WCD9360_ANA_AMIC1 (0x0000060E) +#define WCD9360_ANA_AMIC2 (0x0000060F) +#define WCD9360_ANA_AMIC3 (0x00000610) +#define WCD9360_ANA_AMIC4 (0x00000611) +#define WCD9360_ANA_MICB1 (0x00000622) +#define WCD9360_ANA_MICB2 (0x00000623) +#define WCD9360_ANA_MICB3 (0x00000625) +#define WCD9360_ANA_MICB4 (0x00000626) +#define WCD9360_BIAS_CTL (0x00000628) +#define WCD9360_BIAS_VBG_FINE_ADJ (0x00000629) +#define WCD9360_RCO_CTRL_1 (0x0000062E) +#define WCD9360_RCO_CTRL_2 (0x0000062F) +#define WCD9360_RCO_CAL (0x00000630) +#define WCD9360_RCO_CAL_1 (0x00000631) +#define WCD9360_RCO_CAL_2 (0x00000632) +#define WCD9360_RCO_TEST_CTRL (0x00000633) +#define WCD9360_RCO_CAL_OUT_1 (0x00000634) +#define WCD9360_RCO_CAL_OUT_2 (0x00000635) +#define WCD9360_RCO_CAL_OUT_3 (0x00000636) +#define WCD9360_RCO_CAL_OUT_4 (0x00000637) +#define WCD9360_RCO_CAL_OUT_5 (0x00000638) +#define WCD9360_SIDO_MODE_1 (0x0000063A) +#define WCD9360_SIDO_MODE_2 (0x0000063B) +#define WCD9360_SIDO_MODE_3 (0x0000063C) +#define WCD9360_SIDO_MODE_4 (0x0000063D) +#define WCD9360_SIDO_VCL_1 (0x0000063E) +#define WCD9360_SIDO_VCL_2 (0x0000063F) +#define WCD9360_SIDO_VCL_3 (0x00000640) +#define WCD9360_SIDO_CCL_1 (0x00000641) +#define WCD9360_SIDO_CCL_2 (0x00000642) +#define WCD9360_SIDO_CCL_3 (0x00000643) +#define WCD9360_SIDO_CCL_4 (0x00000644) +#define WCD9360_SIDO_CCL_5 (0x00000645) +#define WCD9360_SIDO_CCL_6 (0x00000646) +#define WCD9360_SIDO_CCL_7 (0x00000647) +#define WCD9360_SIDO_CCL_8 (0x00000648) +#define WCD9360_SIDO_CCL_9 (0x00000649) +#define WCD9360_SIDO_CCL_10 (0x0000064A) +#define WCD9360_SIDO_FILTER_1 (0x0000064B) +#define WCD9360_SIDO_FILTER_2 (0x0000064C) +#define WCD9360_SIDO_DRIVER_1 (0x0000064D) +#define WCD9360_SIDO_DRIVER_2 (0x0000064E) +#define WCD9360_SIDO_DRIVER_3 (0x0000064F) +#define WCD9360_SIDO_CAL_CODE_EXT_1 (0x00000650) +#define WCD9360_SIDO_CAL_CODE_EXT_2 (0x00000651) +#define WCD9360_SIDO_CAL_CODE_OUT_1 (0x00000652) +#define WCD9360_SIDO_CAL_CODE_OUT_2 (0x00000653) +#define WCD9360_SIDO_TEST_1 (0x00000654) +#define WCD9360_SIDO_TEST_2 (0x00000655) +#define WCD9360_LDOH_MODE (0x00000667) +#define WCD9360_LDOH_BIAS (0x00000668) +#define WCD9360_LDOH_STB_LOADS (0x00000669) +#define WCD9360_LDOH_SLOWRAMP (0x0000066A) +#define WCD9360_MICB1_TEST_CTL_1 (0x0000066B) +#define WCD9360_MICB1_TEST_CTL_2 (0x0000066C) +#define WCD9360_MICB1_TEST_CTL_3 (0x0000066D) +#define WCD9360_MICB2_TEST_CTL_1 (0x0000066E) +#define WCD9360_MICB2_TEST_CTL_2 (0x0000066F) +#define WCD9360_MICB2_TEST_CTL_3 (0x00000670) +#define WCD9360_MICB3_TEST_CTL_1 (0x00000671) +#define WCD9360_MICB3_TEST_CTL_2 (0x00000672) +#define WCD9360_MICB3_TEST_CTL_3 (0x00000673) +#define WCD9360_MICB4_TEST_CTL_1 (0x00000674) +#define WCD9360_MICB4_TEST_CTL_2 (0x00000675) +#define WCD9360_MICB4_TEST_CTL_3 (0x00000676) +#define WCD9360_TX_COM_ADC_VCM (0x00000677) +#define WCD9360_TX_COM_BIAS_ATEST (0x00000678) +#define WCD9360_TX_COM_ADC_INT1_IB (0x00000679) +#define WCD9360_TX_COM_ADC_INT2_IB (0x0000067A) +#define WCD9360_TX_COM_TXFE_DIV_CTL (0x0000067B) +#define WCD9360_TX_COM_TXFE_DIV_START (0x0000067C) +#define WCD9360_TX_COM_TXFE_DIV_STOP_9P6M (0x0000067D) +#define WCD9360_TX_COM_TXFE_DIV_STOP_12P288M (0x0000067E) +#define WCD9360_TX_1_2_TEST_EN (0x0000067F) +#define WCD9360_TX_1_2_ADC_IB (0x00000680) +#define WCD9360_TX_1_2_ATEST_REFCTL (0x00000681) +#define WCD9360_TX_1_2_TEST_CTL (0x00000682) +#define WCD9360_TX_1_2_TEST_BLK_EN (0x00000683) +#define WCD9360_TX_1_2_TXFE_CLKDIV (0x00000684) +#define WCD9360_TX_1_2_SAR1_ERR (0x00000685) +#define WCD9360_TX_1_2_SAR2_ERR (0x00000686) +#define WCD9360_TX_3_4_TEST_EN (0x00000687) +#define WCD9360_TX_3_4_ADC_IB (0x00000688) +#define WCD9360_TX_3_4_ATEST_REFCTL (0x00000689) +#define WCD9360_TX_3_4_TEST_CTL (0x0000068A) +#define WCD9360_TX_3_4_TEST_BLK_EN (0x0000068B) +#define WCD9360_TX_3_4_TXFE_CLKDIV (0x0000068C) +#define WCD9360_TX_3_4_SAR1_ERR (0x0000068D) +#define WCD9360_TX_3_4_SAR2_ERR (0x0000068E) +#define WCD9360_RX_RX_EAR_BIAS_CON_1 (0x000006B3) +#define WCD9360_RX_RX_EAR_BIAS_CON_2 (0x000006B4) +#define WCD9360_RX_RX_AUX_BIAS_CON_1 (0x000006B5) +#define WCD9360_RX_RX_AUX_BIAS_CON_2 (0x000006B6) +#define WCD9360_RX_RX_BIAS_ATEST (0x000006B7) +#define WCD9360_RX_RXTOP_RESERVED (0x000006B8) +#define WCD9360_EAR_EAR_EN_REG (0x000006E1) +#define WCD9360_EAR_EAR_PA_CON (0x000006E2) +#define WCD9360_EAR_EAR_SP_CON (0x000006E3) +#define WCD9360_EAR_EAR_DAC_CON (0x000006E4) +#define WCD9360_EAR_EAR_CNP_FSM_CON (0x000006E5) +#define WCD9360_EAR_DAC_CTL_TEST (0x000006E6) +#define WCD9360_EAR_STATUS_REG (0x000006E7) +#define WCD9360_EAR_EAR_COMPANDER_CON (0x000006E8) +#define WCD9360_ANA_NEW_PAGE_REGISTER (0x00000700) +#define WCD9360_CLK_SYS_PLL_ENABLES (0x0000070E) +#define WCD9360_CLK_SYS_PLL_PRESET (0x0000070F) +#define WCD9360_CLK_SYS_PLL_STATUS (0x00000710) +#define WCD9360_CLK_SYS_MCLK_PRG (0x00000711) +#define WCD9360_CLK_SYS_MCLK2_PRG1 (0x00000712) +#define WCD9360_CLK_SYS_MCLK_MISC (0x00000713) +#define WCD9360_SIDO_NEW_VOUT_A_STARTUP (0x0000071B) +#define WCD9360_SIDO_NEW_VOUT_D_STARTUP (0x0000071C) +#define WCD9360_SIDO_NEW_VOUT_D_FREQ1 (0x0000071D) +#define WCD9360_SIDO_NEW_VOUT_D_FREQ2 (0x0000071E) +#define WCD9360_AUX_ANA_EAR (0x00000728) +#define WCD9360_LDORXTX_LDORXTX (0x00000729) +#define WCD9360_DIE_CRACK_CTL (0x0000072A) +#define WCD9360_DIE_CRACK_OUT (0x0000072B) +#define WCD9360_LOOP_BACK_EN (0x0000072C) +#define WCD9360_CLK_SYS_INT_POST_DIV_REG0 (0x0000076C) +#define WCD9360_CLK_SYS_INT_POST_DIV_REG1 (0x0000076D) +#define WCD9360_CLK_SYS_INT_REF_DIV_REG0 (0x0000076E) +#define WCD9360_CLK_SYS_INT_REF_DIV_REG1 (0x0000076F) +#define WCD9360_CLK_SYS_INT_FILTER_REG0 (0x00000770) +#define WCD9360_CLK_SYS_INT_FILTER_REG1 (0x00000771) +#define WCD9360_CLK_SYS_INT_PLL_L_VAL (0x00000772) +#define WCD9360_CLK_SYS_INT_PLL_M_VAL (0x00000773) +#define WCD9360_CLK_SYS_INT_PLL_N_VAL (0x00000774) +#define WCD9360_CLK_SYS_INT_TEST_REG0 (0x00000775) +#define WCD9360_CLK_SYS_INT_PFD_CP_DSM_PROG (0x00000776) +#define WCD9360_CLK_SYS_INT_VCO_PROG (0x00000777) +#define WCD9360_CLK_SYS_INT_TEST_REG1 (0x00000778) +#define WCD9360_CLK_SYS_INT_LDO_LOCK_CFG (0x00000779) +#define WCD9360_CLK_SYS_INT_DIG_LOCK_DET_CFG (0x0000077A) +#define WCD9360_CLK_SYS_INT_CLK_TEST1 (0x0000077B) +#define WCD9360_CLK_SYS_INT_CLK_TEST2 (0x0000077C) +#define WCD9360_CLK_SYS_INT_CLK_TEST3 (0x0000077D) +#define WCD9360_SIDO_NEW_INT_RAMP_STATUS (0x00000796) +#define WCD9360_SIDO_NEW_INT_SPARE_1 (0x00000797) +#define WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_A (0x00000798) +#define WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_D (0x00000799) +#define WCD9360_SIDO_NEW_INT_RAMP_INC_WAIT (0x0000079A) +#define WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_CTL (0x0000079B) +#define WCD9360_SIDO_NEW_INT_RAMP_IBLEED_CTL (0x0000079C) +#define WCD9360_SIDO_NEW_INT_DEBUG_CPROVR_TEST (0x0000079D) +#define WCD9360_SIDO_NEW_INT_RAMP_CTL_A (0x0000079E) +#define WCD9360_SIDO_NEW_INT_RAMP_CTL_D (0x0000079F) +#define WCD9360_SIDO_NEW_INT_RAMP_TIMEOUT_PERIOD (0x000007A0) +#define WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING1 (0x000007A1) +#define WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING2 (0x000007A2) +#define WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING3 (0x000007A3) +#define WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL1 (0x000007A4) +#define WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL2 (0x000007A5) +#define WCD9360_EAR_INT_NEW_EAR_CHOPPER_CON (0x000007B7) +#define WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON1 (0x000007B8) +#define WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON2 (0x000007B9) +#define WCD9360_EAR_INT_NEW_EAR_DYNAMIC_BIAS (0x000007BA) +#define WCD9360_AUX_INT_AUX_EN_REG (0x000007BD) +#define WCD9360_AUX_INT_AUX_PA_CON (0x000007BE) +#define WCD9360_AUX_INT_AUX_SP_CON (0x000007BF) +#define WCD9360_AUX_INT_AUX_DAC_CON (0x000007C0) +#define WCD9360_AUX_INT_AUX_CNP_FSM_CON (0x000007C1) +#define WCD9360_AUX_INT_AUX_TEST (0x000007C2) +#define WCD9360_AUX_INT_STATUS_REG (0x000007C3) +#define WCD9360_AUX_INT_AUX_MISC (0x000007C4) +#define WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL1 (0x000007C5) +#define WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL2 (0x000007C6) +#define WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL3 (0x000007C7) +#define WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL4 (0x000007C8) +#define WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL5 (0x000007C9) +#define WCD9360_LDORXTX_INT_ANA_LDORXTX_STATUS (0x000007CA) +#define WCD9360_DIE_CRACK_INT_INT1 (0x000007CC) +#define WCD9360_DIE_CRACK_INT_INT2 (0x000007CD) +#define WCD9360_LOOP_BACK_INT_SPARE (0x000007CE) +#define WCD9360_PAGE10_PAGE_REGISTER (0x00000A00) +#define WCD9360_CDC_ANC0_CLK_RESET_CTL (0x00000A01) +#define WCD9360_CDC_ANC0_MODE_1_CTL (0x00000A02) +#define WCD9360_CDC_ANC0_MODE_2_CTL (0x00000A03) +#define WCD9360_CDC_ANC0_FF_SHIFT (0x00000A04) +#define WCD9360_CDC_ANC0_FB_SHIFT (0x00000A05) +#define WCD9360_CDC_ANC0_LPF_FF_A_CTL (0x00000A06) +#define WCD9360_CDC_ANC0_LPF_FF_B_CTL (0x00000A07) +#define WCD9360_CDC_ANC0_LPF_FB_CTL (0x00000A08) +#define WCD9360_CDC_ANC0_SMLPF_CTL (0x00000A09) +#define WCD9360_CDC_ANC0_DCFLT_SHIFT_CTL (0x00000A0A) +#define WCD9360_CDC_ANC0_IIR_ADAPT_CTL (0x00000A0B) +#define WCD9360_CDC_ANC0_IIR_COEFF_1_CTL (0x00000A0C) +#define WCD9360_CDC_ANC0_IIR_COEFF_2_CTL (0x00000A0D) +#define WCD9360_CDC_ANC0_FF_A_GAIN_CTL (0x00000A0E) +#define WCD9360_CDC_ANC0_FF_B_GAIN_CTL (0x00000A0F) +#define WCD9360_CDC_ANC0_FB_GAIN_CTL (0x00000A10) +#define WCD9360_CDC_TX0_TX_PATH_CTL (0x00000A31) +#define WCD9360_CDC_TX0_TX_PATH_CFG0 (0x00000A32) +#define WCD9360_CDC_TX0_TX_PATH_CFG1 (0x00000A33) +#define WCD9360_CDC_TX0_TX_VOL_CTL (0x00000A34) +#define WCD9360_CDC_TX0_TX_PATH_192_CTL (0x00000A35) +#define WCD9360_CDC_TX0_TX_PATH_192_CFG (0x00000A36) +#define WCD9360_CDC_TX0_TX_PATH_SEC0 (0x00000A37) +#define WCD9360_CDC_TX0_TX_PATH_SEC1 (0x00000A38) +#define WCD9360_CDC_TX0_TX_PATH_SEC2 (0x00000A39) +#define WCD9360_CDC_TX0_TX_PATH_SEC3 (0x00000A3A) +#define WCD9360_CDC_TX0_TX_PATH_SEC4 (0x00000A3B) +#define WCD9360_CDC_TX0_TX_PATH_SEC5 (0x00000A3C) +#define WCD9360_CDC_TX0_TX_PATH_SEC6 (0x00000A3D) +#define WCD9360_CDC_TX1_TX_PATH_CTL (0x00000A41) +#define WCD9360_CDC_TX1_TX_PATH_CFG0 (0x00000A42) +#define WCD9360_CDC_TX1_TX_PATH_CFG1 (0x00000A43) +#define WCD9360_CDC_TX1_TX_VOL_CTL (0x00000A44) +#define WCD9360_CDC_TX1_TX_PATH_192_CTL (0x00000A45) +#define WCD9360_CDC_TX1_TX_PATH_192_CFG (0x00000A46) +#define WCD9360_CDC_TX1_TX_PATH_SEC0 (0x00000A47) +#define WCD9360_CDC_TX1_TX_PATH_SEC1 (0x00000A48) +#define WCD9360_CDC_TX1_TX_PATH_SEC2 (0x00000A49) +#define WCD9360_CDC_TX1_TX_PATH_SEC3 (0x00000A4A) +#define WCD9360_CDC_TX1_TX_PATH_SEC4 (0x00000A4B) +#define WCD9360_CDC_TX1_TX_PATH_SEC5 (0x00000A4C) +#define WCD9360_CDC_TX1_TX_PATH_SEC6 (0x00000A4D) +#define WCD9360_CDC_TX2_TX_PATH_CTL (0x00000A51) +#define WCD9360_CDC_TX2_TX_PATH_CFG0 (0x00000A52) +#define WCD9360_CDC_TX2_TX_PATH_CFG1 (0x00000A53) +#define WCD9360_CDC_TX2_TX_VOL_CTL (0x00000A54) +#define WCD9360_CDC_TX2_TX_PATH_192_CTL (0x00000A55) +#define WCD9360_CDC_TX2_TX_PATH_192_CFG (0x00000A56) +#define WCD9360_CDC_TX2_TX_PATH_SEC0 (0x00000A57) +#define WCD9360_CDC_TX2_TX_PATH_SEC1 (0x00000A58) +#define WCD9360_CDC_TX2_TX_PATH_SEC2 (0x00000A59) +#define WCD9360_CDC_TX2_TX_PATH_SEC3 (0x00000A5A) +#define WCD9360_CDC_TX2_TX_PATH_SEC4 (0x00000A5B) +#define WCD9360_CDC_TX2_TX_PATH_SEC5 (0x00000A5C) +#define WCD9360_CDC_TX2_TX_PATH_SEC6 (0x00000A5D) +#define WCD9360_CDC_TX3_TX_PATH_CTL (0x00000A61) +#define WCD9360_CDC_TX3_TX_PATH_CFG0 (0x00000A62) +#define WCD9360_CDC_TX3_TX_PATH_CFG1 (0x00000A63) +#define WCD9360_CDC_TX3_TX_VOL_CTL (0x00000A64) +#define WCD9360_CDC_TX3_TX_PATH_192_CTL (0x00000A65) +#define WCD9360_CDC_TX3_TX_PATH_192_CFG (0x00000A66) +#define WCD9360_CDC_TX3_TX_PATH_SEC0 (0x00000A67) +#define WCD9360_CDC_TX3_TX_PATH_SEC1 (0x00000A68) +#define WCD9360_CDC_TX3_TX_PATH_SEC2 (0x00000A69) +#define WCD9360_CDC_TX3_TX_PATH_SEC3 (0x00000A6A) +#define WCD9360_CDC_TX3_TX_PATH_SEC4 (0x00000A6B) +#define WCD9360_CDC_TX3_TX_PATH_SEC5 (0x00000A6C) +#define WCD9360_CDC_TX3_TX_PATH_SEC6 (0x00000A6D) +#define WCD9360_CDC_TX4_TX_PATH_CTL (0x00000A71) +#define WCD9360_CDC_TX4_TX_PATH_CFG0 (0x00000A72) +#define WCD9360_CDC_TX4_TX_PATH_CFG1 (0x00000A73) +#define WCD9360_CDC_TX4_TX_VOL_CTL (0x00000A74) +#define WCD9360_CDC_TX4_TX_PATH_192_CTL (0x00000A75) +#define WCD9360_CDC_TX4_TX_PATH_192_CFG (0x00000A76) +#define WCD9360_CDC_TX4_TX_PATH_SEC0 (0x00000A77) +#define WCD9360_CDC_TX4_TX_PATH_SEC1 (0x00000A78) +#define WCD9360_CDC_TX4_TX_PATH_SEC2 (0x00000A79) +#define WCD9360_CDC_TX4_TX_PATH_SEC3 (0x00000A7A) +#define WCD9360_CDC_TX4_TX_PATH_SEC4 (0x00000A7B) +#define WCD9360_CDC_TX4_TX_PATH_SEC5 (0x00000A7C) +#define WCD9360_CDC_TX4_TX_PATH_SEC6 (0x00000A7D) +#define WCD9360_CDC_TX5_TX_PATH_CTL (0x00000A81) +#define WCD9360_CDC_TX5_TX_PATH_CFG0 (0x00000A82) +#define WCD9360_CDC_TX5_TX_PATH_CFG1 (0x00000A83) +#define WCD9360_CDC_TX5_TX_VOL_CTL (0x00000A84) +#define WCD9360_CDC_TX5_TX_PATH_192_CTL (0x00000A85) +#define WCD9360_CDC_TX5_TX_PATH_192_CFG (0x00000A86) +#define WCD9360_CDC_TX5_TX_PATH_SEC0 (0x00000A87) +#define WCD9360_CDC_TX5_TX_PATH_SEC1 (0x00000A88) +#define WCD9360_CDC_TX5_TX_PATH_SEC2 (0x00000A89) +#define WCD9360_CDC_TX5_TX_PATH_SEC3 (0x00000A8A) +#define WCD9360_CDC_TX5_TX_PATH_SEC4 (0x00000A8B) +#define WCD9360_CDC_TX5_TX_PATH_SEC5 (0x00000A8C) +#define WCD9360_CDC_TX5_TX_PATH_SEC6 (0x00000A8D) +#define WCD9360_CDC_TX6_TX_PATH_CTL (0x00000A91) +#define WCD9360_CDC_TX6_TX_PATH_CFG0 (0x00000A92) +#define WCD9360_CDC_TX6_TX_PATH_CFG1 (0x00000A93) +#define WCD9360_CDC_TX6_TX_VOL_CTL (0x00000A94) +#define WCD9360_CDC_TX6_TX_PATH_192_CTL (0x00000A95) +#define WCD9360_CDC_TX6_TX_PATH_192_CFG (0x00000A96) +#define WCD9360_CDC_TX6_TX_PATH_SEC0 (0x00000A97) +#define WCD9360_CDC_TX6_TX_PATH_SEC1 (0x00000A98) +#define WCD9360_CDC_TX6_TX_PATH_SEC2 (0x00000A99) +#define WCD9360_CDC_TX6_TX_PATH_SEC3 (0x00000A9A) +#define WCD9360_CDC_TX6_TX_PATH_SEC4 (0x00000A9B) +#define WCD9360_CDC_TX6_TX_PATH_SEC5 (0x00000A9C) +#define WCD9360_CDC_TX6_TX_PATH_SEC6 (0x00000A9D) +#define WCD9360_CDC_TX7_TX_PATH_CTL (0x00000AA1) +#define WCD9360_CDC_TX7_TX_PATH_CFG0 (0x00000AA2) +#define WCD9360_CDC_TX7_TX_PATH_CFG1 (0x00000AA3) +#define WCD9360_CDC_TX7_TX_VOL_CTL (0x00000AA4) +#define WCD9360_CDC_TX7_TX_PATH_192_CTL (0x00000AA5) +#define WCD9360_CDC_TX7_TX_PATH_192_CFG (0x00000AA6) +#define WCD9360_CDC_TX7_TX_PATH_SEC0 (0x00000AA7) +#define WCD9360_CDC_TX7_TX_PATH_SEC1 (0x00000AA8) +#define WCD9360_CDC_TX7_TX_PATH_SEC2 (0x00000AA9) +#define WCD9360_CDC_TX7_TX_PATH_SEC3 (0x00000AAA) +#define WCD9360_CDC_TX7_TX_PATH_SEC4 (0x00000AAB) +#define WCD9360_CDC_TX7_TX_PATH_SEC5 (0x00000AAC) +#define WCD9360_CDC_TX7_TX_PATH_SEC6 (0x00000AAD) +#define WCD9360_CDC_TX8_TX_PATH_CTL (0x00000AB1) +#define WCD9360_CDC_TX8_TX_PATH_CFG0 (0x00000AB2) +#define WCD9360_CDC_TX8_TX_PATH_CFG1 (0x00000AB3) +#define WCD9360_CDC_TX8_TX_VOL_CTL (0x00000AB4) +#define WCD9360_CDC_TX8_TX_PATH_192_CTL (0x00000AB5) +#define WCD9360_CDC_TX8_TX_PATH_192_CFG (0x00000AB6) +#define WCD9360_CDC_TX8_TX_PATH_SEC0 (0x00000AB7) +#define WCD9360_CDC_TX8_TX_PATH_SEC1 (0x00000AB8) +#define WCD9360_CDC_TX8_TX_PATH_SEC2 (0x00000AB9) +#define WCD9360_CDC_TX8_TX_PATH_SEC3 (0x00000ABA) +#define WCD9360_CDC_TX8_TX_PATH_SEC4 (0x00000ABB) +#define WCD9360_CDC_TX8_TX_PATH_SEC5 (0x00000ABC) +#define WCD9360_CDC_TX8_TX_PATH_SEC6 (0x00000ABD) +#define WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL (0x00000AC2) +#define WCD9360_CDC_TX9_SPKR_PROT_PATH_CFG0 (0x00000AC3) +#define WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL (0x00000AC6) +#define WCD9360_CDC_TX10_SPKR_PROT_PATH_CFG0 (0x00000AC7) +#define WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL (0x00000ACA) +#define WCD9360_CDC_TX11_SPKR_PROT_PATH_CFG0 (0x00000ACB) +#define WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL (0x00000ACE) +#define WCD9360_CDC_TX12_SPKR_PROT_PATH_CFG0 (0x00000ACF) +#define WCD9360_PAGE11_PAGE_REGISTER (0x00000B00) +#define WCD9360_CDC_COMPANDER0_CTL0 (0x00000B21) +#define WCD9360_CDC_COMPANDER0_CTL1 (0x00000B22) +#define WCD9360_CDC_COMPANDER0_CTL2 (0x00000B23) +#define WCD9360_CDC_COMPANDER0_CTL3 (0x00000B24) +#define WCD9360_CDC_COMPANDER0_CTL4 (0x00000B25) +#define WCD9360_CDC_COMPANDER0_CTL5 (0x00000B26) +#define WCD9360_CDC_COMPANDER0_CTL6 (0x00000B27) +#define WCD9360_CDC_COMPANDER0_CTL7 (0x00000B28) +#define WCD9360_CDC_COMPANDER7_CTL0 (0x00000B31) +#define WCD9360_CDC_COMPANDER7_CTL1 (0x00000B32) +#define WCD9360_CDC_COMPANDER7_CTL2 (0x00000B33) +#define WCD9360_CDC_COMPANDER7_CTL3 (0x00000B34) +#define WCD9360_CDC_COMPANDER7_CTL4 (0x00000B35) +#define WCD9360_CDC_COMPANDER7_CTL5 (0x00000B36) +#define WCD9360_CDC_COMPANDER7_CTL6 (0x00000B37) +#define WCD9360_CDC_COMPANDER7_CTL7 (0x00000B38) +#define WCD9360_CDC_COMPANDER8_CTL0 (0x00000B39) +#define WCD9360_CDC_COMPANDER8_CTL1 (0x00000B3A) +#define WCD9360_CDC_COMPANDER8_CTL2 (0x00000B3B) +#define WCD9360_CDC_COMPANDER8_CTL3 (0x00000B3C) +#define WCD9360_CDC_COMPANDER8_CTL4 (0x00000B3D) +#define WCD9360_CDC_COMPANDER8_CTL5 (0x00000B3E) +#define WCD9360_CDC_COMPANDER8_CTL6 (0x00000B3F) +#define WCD9360_CDC_COMPANDER8_CTL7 (0x00000B40) +#define WCD9360_CDC_RX0_RX_PATH_CTL (0x00000B41) +#define WCD9360_CDC_RX0_RX_PATH_CFG0 (0x00000B42) +#define WCD9360_CDC_RX0_RX_PATH_CFG1 (0x00000B43) +#define WCD9360_CDC_RX0_RX_PATH_CFG2 (0x00000B44) +#define WCD9360_CDC_RX0_RX_VOL_CTL (0x00000B45) +#define WCD9360_CDC_RX0_RX_PATH_MIX_CTL (0x00000B46) +#define WCD9360_CDC_RX0_RX_PATH_MIX_CFG (0x00000B47) +#define WCD9360_CDC_RX0_RX_VOL_MIX_CTL (0x00000B48) +#define WCD9360_CDC_RX0_RX_PATH_SEC0 (0x00000B49) +#define WCD9360_CDC_RX0_RX_PATH_SEC1 (0x00000B4A) +#define WCD9360_CDC_RX0_RX_PATH_SEC2 (0x00000B4B) +#define WCD9360_CDC_RX0_RX_PATH_SEC3 (0x00000B4C) +#define WCD9360_CDC_RX0_RX_PATH_SEC5 (0x00000B4E) +#define WCD9360_CDC_RX0_RX_PATH_SEC6 (0x00000B4F) +#define WCD9360_CDC_RX0_RX_PATH_SEC7 (0x00000B50) +#define WCD9360_CDC_RX0_RX_PATH_MIX_SEC0 (0x00000B51) +#define WCD9360_CDC_RX0_RX_PATH_MIX_SEC1 (0x00000B52) +#define WCD9360_CDC_RX0_RX_PATH_DSMDEM_CTL (0x00000B53) +#define WCD9360_CDC_RX9_RX_PATH_CTL (0x00000BA5) +#define WCD9360_CDC_RX9_RX_PATH_CFG0 (0x00000BA6) +#define WCD9360_CDC_RX9_RX_PATH_CFG1 (0x00000BA7) +#define WCD9360_CDC_RX9_RX_PATH_CFG2 (0x00000BA8) +#define WCD9360_CDC_RX9_RX_VOL_CTL (0x00000BA9) +#define WCD9360_CDC_RX9_RX_PATH_MIX_CTL (0x00000BAA) +#define WCD9360_CDC_RX9_RX_PATH_MIX_CFG (0x00000BAB) +#define WCD9360_CDC_RX9_RX_VOL_MIX_CTL (0x00000BAC) +#define WCD9360_CDC_RX9_RX_PATH_SEC0 (0x00000BAD) +#define WCD9360_CDC_RX9_RX_PATH_SEC1 (0x00000BAE) +#define WCD9360_CDC_RX9_RX_PATH_SEC2 (0x00000BAF) +#define WCD9360_CDC_RX9_RX_PATH_SEC3 (0x00000BB0) +#define WCD9360_CDC_RX9_RX_PATH_SEC5 (0x00000BB2) +#define WCD9360_CDC_RX9_RX_PATH_SEC6 (0x00000BB3) +#define WCD9360_CDC_RX9_RX_PATH_SEC7 (0x00000BB4) +#define WCD9360_CDC_RX9_RX_PATH_MIX_SEC0 (0x00000BB5) +#define WCD9360_CDC_RX9_RX_PATH_MIX_SEC1 (0x00000BB6) +#define WCD9360_CDC_RX9_RX_PATH_DSMDEM_CTL (0x00000BB7) +#define WCD9360_CDC_RX7_RX_PATH_CTL (0x00000BCD) +#define WCD9360_CDC_RX7_RX_PATH_CFG0 (0x00000BCE) +#define WCD9360_CDC_RX7_RX_PATH_CFG1 (0x00000BCF) +#define WCD9360_CDC_RX7_RX_PATH_CFG2 (0x00000BD0) +#define WCD9360_CDC_RX7_RX_VOL_CTL (0x00000BD1) +#define WCD9360_CDC_RX7_RX_PATH_MIX_CTL (0x00000BD2) +#define WCD9360_CDC_RX7_RX_PATH_MIX_CFG (0x00000BD3) +#define WCD9360_CDC_RX7_RX_VOL_MIX_CTL (0x00000BD4) +#define WCD9360_CDC_RX7_RX_PATH_SEC0 (0x00000BD5) +#define WCD9360_CDC_RX7_RX_PATH_SEC1 (0x00000BD6) +#define WCD9360_CDC_RX7_RX_PATH_SEC2 (0x00000BD7) +#define WCD9360_CDC_RX7_RX_PATH_SEC3 (0x00000BD8) +#define WCD9360_CDC_RX7_RX_PATH_SEC5 (0x00000BDA) +#define WCD9360_CDC_RX7_RX_PATH_SEC6 (0x00000BDB) +#define WCD9360_CDC_RX7_RX_PATH_SEC7 (0x00000BDC) +#define WCD9360_CDC_RX7_RX_PATH_MIX_SEC0 (0x00000BDD) +#define WCD9360_CDC_RX7_RX_PATH_MIX_SEC1 (0x00000BDE) +#define WCD9360_CDC_RX7_RX_PATH_DSMDEM_CTL (0x00000BDF) +#define WCD9360_CDC_RX8_RX_PATH_CTL (0x00000BE1) +#define WCD9360_CDC_RX8_RX_PATH_CFG0 (0x00000BE2) +#define WCD9360_CDC_RX8_RX_PATH_CFG1 (0x00000BE3) +#define WCD9360_CDC_RX8_RX_PATH_CFG2 (0x00000BE4) +#define WCD9360_CDC_RX8_RX_VOL_CTL (0x00000BE5) +#define WCD9360_CDC_RX8_RX_PATH_MIX_CTL (0x00000BE6) +#define WCD9360_CDC_RX8_RX_PATH_MIX_CFG (0x00000BE7) +#define WCD9360_CDC_RX8_RX_VOL_MIX_CTL (0x00000BE8) +#define WCD9360_CDC_RX8_RX_PATH_SEC0 (0x00000BE9) +#define WCD9360_CDC_RX8_RX_PATH_SEC1 (0x00000BEA) +#define WCD9360_CDC_RX8_RX_PATH_SEC2 (0x00000BEB) +#define WCD9360_CDC_RX8_RX_PATH_SEC3 (0x00000BEC) +#define WCD9360_CDC_RX8_RX_PATH_SEC5 (0x00000BEE) +#define WCD9360_CDC_RX8_RX_PATH_SEC6 (0x00000BEF) +#define WCD9360_CDC_RX8_RX_PATH_SEC7 (0x00000BF0) +#define WCD9360_CDC_RX8_RX_PATH_MIX_SEC0 (0x00000BF1) +#define WCD9360_CDC_RX8_RX_PATH_MIX_SEC1 (0x00000BF2) +#define WCD9360_CDC_RX8_RX_PATH_DSMDEM_CTL (0x00000BF3) +#define WCD9360_PAGE12_PAGE_REGISTER (0x00000C00) +#define WCD9360_CDC_BOOST0_BOOST_PATH_CTL (0x00000C19) +#define WCD9360_CDC_BOOST0_BOOST_CTL (0x00000C1A) +#define WCD9360_CDC_BOOST0_BOOST_CFG1 (0x00000C1B) +#define WCD9360_CDC_BOOST0_BOOST_CFG2 (0x00000C1C) +#define WCD9360_CDC_BOOST1_BOOST_PATH_CTL (0x00000C21) +#define WCD9360_CDC_BOOST1_BOOST_CTL (0x00000C22) +#define WCD9360_CDC_BOOST1_BOOST_CFG1 (0x00000C23) +#define WCD9360_CDC_BOOST1_BOOST_CFG2 (0x00000C24) +#define WCD9360_MIXING_ASRC2_CLK_RST_CTL (0x00000C6D) +#define WCD9360_MIXING_ASRC2_CTL0 (0x00000C6E) +#define WCD9360_MIXING_ASRC2_CTL1 (0x00000C6F) +#define WCD9360_MIXING_ASRC2_FIFO_CTL (0x00000C70) +#define WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_LSB (0x00000C71) +#define WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_MSB (0x00000C72) +#define WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_LSB (0x00000C73) +#define WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_MSB (0x00000C74) +#define WCD9360_MIXING_ASRC2_STATUS_FIFO (0x00000C75) +#define WCD9360_MIXING_ASRC3_CLK_RST_CTL (0x00000C79) +#define WCD9360_MIXING_ASRC3_CTL0 (0x00000C7A) +#define WCD9360_MIXING_ASRC3_CTL1 (0x00000C7B) +#define WCD9360_MIXING_ASRC3_FIFO_CTL (0x00000C7C) +#define WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_LSB (0x00000C7D) +#define WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_MSB (0x00000C7E) +#define WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_LSB (0x00000C7F) +#define WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_MSB (0x00000C80) +#define WCD9360_MIXING_ASRC3_STATUS_FIFO (0x00000C81) +#define WCD9360_SWR_AHB_BRIDGE_WR_DATA_0 (0x00000C85) +#define WCD9360_SWR_AHB_BRIDGE_WR_DATA_1 (0x00000C86) +#define WCD9360_SWR_AHB_BRIDGE_WR_DATA_2 (0x00000C87) +#define WCD9360_SWR_AHB_BRIDGE_WR_DATA_3 (0x00000C88) +#define WCD9360_SWR_AHB_BRIDGE_WR_ADDR_0 (0x00000C89) +#define WCD9360_SWR_AHB_BRIDGE_WR_ADDR_1 (0x00000C8A) +#define WCD9360_SWR_AHB_BRIDGE_WR_ADDR_2 (0x00000C8B) +#define WCD9360_SWR_AHB_BRIDGE_WR_ADDR_3 (0x00000C8C) +#define WCD9360_SWR_AHB_BRIDGE_RD_ADDR_0 (0x00000C8D) +#define WCD9360_SWR_AHB_BRIDGE_RD_ADDR_1 (0x00000C8E) +#define WCD9360_SWR_AHB_BRIDGE_RD_ADDR_2 (0x00000C8F) +#define WCD9360_SWR_AHB_BRIDGE_RD_ADDR_3 (0x00000C90) +#define WCD9360_SWR_AHB_BRIDGE_RD_DATA_0 (0x00000C91) +#define WCD9360_SWR_AHB_BRIDGE_RD_DATA_1 (0x00000C92) +#define WCD9360_SWR_AHB_BRIDGE_RD_DATA_2 (0x00000C93) +#define WCD9360_SWR_AHB_BRIDGE_RD_DATA_3 (0x00000C94) +#define WCD9360_SWR_AHB_BRIDGE_ACCESS_CFG (0x00000C95) +#define WCD9360_SWR_AHB_BRIDGE_ACCESS_STATUS (0x00000C96) +#define WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL (0x00000CB5) +#define WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1 (0x00000CB6) +#define WCD9360_SIDETONE_ASRC0_CLK_RST_CTL (0x00000CBD) +#define WCD9360_SIDETONE_ASRC0_CTL0 (0x00000CBE) +#define WCD9360_SIDETONE_ASRC0_CTL1 (0x00000CBF) +#define WCD9360_SIDETONE_ASRC0_FIFO_CTL (0x00000CC0) +#define WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB (0x00000CC1) +#define WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB (0x00000CC2) +#define WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB (0x00000CC3) +#define WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB (0x00000CC4) +#define WCD9360_SIDETONE_ASRC0_STATUS_FIFO (0x00000CC5) +#define WCD9360_EC_REF_HQ0_EC_REF_HQ_PATH_CTL (0x00000CD5) +#define WCD9360_EC_REF_HQ0_EC_REF_HQ_CFG0 (0x00000CD6) +#define WCD9360_EC_REF_HQ1_EC_REF_HQ_PATH_CTL (0x00000CDD) +#define WCD9360_EC_REF_HQ1_EC_REF_HQ_CFG0 (0x00000CDE) +#define WCD9360_EC_ASRC0_CLK_RST_CTL (0x00000CE5) +#define WCD9360_EC_ASRC0_CTL0 (0x00000CE6) +#define WCD9360_EC_ASRC0_CTL1 (0x00000CE7) +#define WCD9360_EC_ASRC0_FIFO_CTL (0x00000CE8) +#define WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_LSB (0x00000CE9) +#define WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_MSB (0x00000CEA) +#define WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_LSB (0x00000CEB) +#define WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_MSB (0x00000CEC) +#define WCD9360_EC_ASRC0_STATUS_FIFO (0x00000CED) +#define WCD9360_EC_ASRC1_CLK_RST_CTL (0x00000CF1) +#define WCD9360_EC_ASRC1_CTL0 (0x00000CF2) +#define WCD9360_EC_ASRC1_CTL1 (0x00000CF3) +#define WCD9360_EC_ASRC1_FIFO_CTL (0x00000CF4) +#define WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_LSB (0x00000CF5) +#define WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_MSB (0x00000CF6) +#define WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_LSB (0x00000CF7) +#define WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_MSB (0x00000CF8) +#define WCD9360_EC_ASRC1_STATUS_FIFO (0x00000CF9) +#define WCD9360_PAGE13_PAGE_REGISTER (0x00000D00) +#define WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0 (0x00000D01) +#define WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1 (0x00000D02) +#define WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0 (0x00000D0B) +#define WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1 (0x00000D0C) +#define WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0 (0x00000D0F) +#define WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1 (0x00000D10) +#define WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0 (0x00000D11) +#define WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1 (0x00000D12) +#define WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG0 (0x00000D13) +#define WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG1 (0x00000D14) +#define WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG2 (0x00000D15) +#define WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG3 (0x00000D16) +#define WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG4 (0x00000D17) +#define WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0 (0x00000D18) +#define WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1 (0x00000D19) +#define WCD9360_CDC_RX_INP_MUX_ANC_CFG0 (0x00000D1A) +#define WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0 (0x00000D1B) +#define WCD9360_CDC_RX_INP_MUX_EC_REF_HQ_CFG0 (0x00000D1C) +#define WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0 (0x00000D1D) +#define WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1 (0x00000D1E) +#define WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG0 (0x00000D1F) +#define WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1 (0x00000D20) +#define WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG0 (0x00000D21) +#define WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1 (0x00000D22) +#define WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG0 (0x00000D23) +#define WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1 (0x00000D25) +#define WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0 (0x00000D26) +#define WCD9360_CDC_TX_INP_MUX_ADC_MUX5_CFG0 (0x00000D27) +#define WCD9360_CDC_TX_INP_MUX_ADC_MUX6_CFG0 (0x00000D28) +#define WCD9360_CDC_TX_INP_MUX_ADC_MUX7_CFG0 (0x00000D29) +#define WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0 (0x00000D2A) +#define WCD9360_CDC_TX_INP_MUX_ADC_MUX10_CFG0 (0x00000D2B) +#define WCD9360_CDC_TX_INP_MUX_ADC_MUX11_CFG0 (0x00000D2C) +#define WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0 (0x00000D31) +#define WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1 (0x00000D32) +#define WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2 (0x00000D33) +#define WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3 (0x00000D34) +#define WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0 (0x00000D3A) +#define WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1 (0x00000D3B) +#define WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2 (0x00000D3C) +#define WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3 (0x00000D3D) +#define WCD9360_CDC_CLK_RST_CTRL_MCLK_CONTROL (0x00000D41) +#define WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL (0x00000D42) +#define WCD9360_CDC_CLK_RST_CTRL_SWR_CONTROL (0x00000D43) +#define WCD9360_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL (0x00000D45) +#define WCD9360_CDC_PROX_DETECT_PROX_CTL (0x00000D49) +#define WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD0 (0x00000D4A) +#define WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD1 (0x00000D4B) +#define WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB (0x00000D4C) +#define WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB (0x00000D4D) +#define WCD9360_CDC_PROX_DETECT_PROX_STATUS (0x00000D4E) +#define WCD9360_CDC_PROX_DETECT_PROX_TEST_CTRL (0x00000D4F) +#define WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB (0x00000D50) +#define WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB (0x00000D51) +#define WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD (0x00000D52) +#define WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD (0x00000D53) +#define WCD9360_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT (0x00000D54) +#define WCD9360_CDC_SIDETONE_IIR0_IIR_PATH_CTL (0x00000D55) +#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL (0x00000D56) +#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL (0x00000D57) +#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL (0x00000D58) +#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL (0x00000D59) +#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL (0x00000D5A) +#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL (0x00000D5B) +#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL (0x00000D5C) +#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL (0x00000D5D) +#define WCD9360_CDC_SIDETONE_IIR0_IIR_CTL (0x00000D5E) +#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL (0x00000D5F) +#define WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL (0x00000D60) +#define WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL (0x00000D61) +#define WCD9360_CDC_TOP_TOP_CFG0 (0x00000D81) +#define WCD9360_CDC_TOP_TOP_CFG1 (0x00000D82) +#define WCD9360_CDC_TOP_TOP_CFG7 (0x00000D88) +#define WCD9360_CDC_TOP_EAR_COMP_WR_LSB (0x00000DA9) +#define WCD9360_CDC_TOP_EAR_COMP_WR_MSB (0x00000DAA) +#define WCD9360_CDC_TOP_EAR_COMP_LUT (0x00000DAB) +#define WCD9360_CDC_TOP_EAR_COMP_RD_LSB (0x00000DAC) +#define WCD9360_CDC_TOP_EAR_COMP_RD_MSB (0x00000DAD) +#define WCD9360_CDC_TOP_TOP_DEBUG (0x00000DAE) +#define WCD9360_PAGE80_PAGE_REGISTER (0x00005000) +#define WCD9360_CODEC_CPR_WR_DATA_0 (0x00005001) +#define WCD9360_CODEC_CPR_WR_DATA_1 (0x00005002) +#define WCD9360_CODEC_CPR_WR_DATA_2 (0x00005003) +#define WCD9360_CODEC_CPR_WR_DATA_3 (0x00005004) +#define WCD9360_CODEC_CPR_WR_ADDR_0 (0x00005005) +#define WCD9360_CODEC_CPR_WR_ADDR_1 (0x00005006) +#define WCD9360_CODEC_CPR_WR_ADDR_2 (0x00005007) +#define WCD9360_CODEC_CPR_WR_ADDR_3 (0x00005008) +#define WCD9360_CODEC_CPR_RD_ADDR_0 (0x00005009) +#define WCD9360_CODEC_CPR_RD_ADDR_1 (0x0000500A) +#define WCD9360_CODEC_CPR_RD_ADDR_2 (0x0000500B) +#define WCD9360_CODEC_CPR_RD_ADDR_3 (0x0000500C) +#define WCD9360_CODEC_CPR_RD_DATA_0 (0x0000500D) +#define WCD9360_CODEC_CPR_RD_DATA_1 (0x0000500E) +#define WCD9360_CODEC_CPR_RD_DATA_2 (0x0000500F) +#define WCD9360_CODEC_CPR_RD_DATA_3 (0x00005010) +#define WCD9360_CODEC_CPR_ACCESS_CFG (0x00005011) +#define WCD9360_CODEC_CPR_ACCESS_STATUS (0x00005012) +#define WCD9360_CODEC_CPR_NOM_CX_VDD (0x00005021) +#define WCD9360_CODEC_CPR_SVS_CX_VDD (0x00005022) +#define WCD9360_CODEC_CPR_SVS2_CX_VDD (0x00005023) +#define WCD9360_CODEC_CPR_NOM_MX_VDD (0x00005024) +#define WCD9360_CODEC_CPR_SVS_MX_VDD (0x00005025) +#define WCD9360_CODEC_CPR_SVS2_MX_VDD (0x00005026) +#define WCD9360_CODEC_CPR_SVS2_MIN_CX_VDD (0x00005027) +#define WCD9360_CODEC_CPR_MAX_SVS2_STEP (0x00005028) +#define WCD9360_CODEC_CPR_CTL (0x00005029) +#define WCD9360_CODEC_CPR_SW_MODECHNG_STATUS (0x0000502A) +#define WCD9360_CODEC_CPR_SW_MODECHNG_START (0x0000502B) +#define WCD9360_CODEC_CPR_CPR_STATUS (0x0000502C) +#define WCD9360_PAGE128_PAGE_REGISTER (0x00008000) +#define WCD9360_TLMM_JTCK_PINCFG (0x00008001) +#define WCD9360_TLMM_INTR1_PINCFG (0x00008002) +#define WCD9360_TLMM_INTR2_PINCFG (0x00008003) +#define WCD9360_TLMM_SWR_DATA_PINCFG (0x00008004) +#define WCD9360_TLMM_SWR_CLK_PINCFG (0x00008005) +#define WCD9360_TLMM_SLIMBUS_DATA1_PINCFG (0x00008006) +#define WCD9360_TLMM_SLIMBUS_DATA2_PINCFG (0x00008007) +#define WCD9360_TLMM_SLIMBUS_CLK_PINCFG (0x00008008) +#define WCD9360_TLMM_I2C_CLK_PINCFG (0x00008009) +#define WCD9360_TLMM_I2C_DATA_PINCFG (0x0000800A) +#define WCD9360_TLMM_I2S_0_RX_PINCFG (0x0000800B) +#define WCD9360_TLMM_I2S_0_TX_PINCFG (0x0000800C) +#define WCD9360_TLMM_I2S_0_SCK_PINCFG (0x0000800D) +#define WCD9360_TLMM_I2S_0_WS_PINCFG (0x0000800E) +#define WCD9360_TLMM_I2S_1_RX_PINCFG (0x0000800F) +#define WCD9360_TLMM_I2S_1_TX_PINCFG (0x00008010) +#define WCD9360_TLMM_I2S_1_SCK_PINCFG (0x00008011) +#define WCD9360_TLMM_I2S_1_WS_PINCFG (0x00008012) +#define WCD9360_TLMM_DMIC1_CLK_PINCFG (0x00008013) +#define WCD9360_TLMM_DMIC1_DATA_PINCFG (0x00008014) +#define WCD9360_TLMM_DMIC2_CLK_PINCFG (0x00008015) +#define WCD9360_TLMM_DMIC2_DATA_PINCFG (0x00008016) +#define WCD9360_TLMM_GPIO1_PINCFG (0x00008017) +#define WCD9360_TLMM_GPIO2_PINCFG (0x00008018) +#define WCD9360_TLMM_GPIO3_PINCFG (0x00008019) +#define WCD9360_TLMM_GPIO4_PINCFG (0x0000801A) +#define WCD9360_TLMM_SPI_S_CSN_PINCFG (0x0000801B) +#define WCD9360_TLMM_SPI_S_CLK_PINCFG (0x0000801C) +#define WCD9360_TLMM_SPI_S_DOUT_PINCFG (0x0000801D) +#define WCD9360_TLMM_SPI_S_DIN_PINCFG (0x0000801E) +#define WCD9360_TLMM_GPIO0_PINCFG (0x0000801F) +#define WCD9360_TLMM_DMIC3_CLK_PINCFG (0x00008020) +#define WCD9360_TLMM_DMIC3_DATA_PINCFG (0x00008021) +#define WCD9360_TLMM_DMIC4_CLK_PINCFG (0x00008022) +#define WCD9360_TLMM_DMIC4_DATA_PINCFG (0x00008023) +#define WCD9360_TEST_DEBUG_PIN_CTL_OE_0 (0x00008031) +#define WCD9360_TEST_DEBUG_PIN_CTL_OE_1 (0x00008032) +#define WCD9360_TEST_DEBUG_PIN_CTL_OE_2 (0x00008033) +#define WCD9360_TEST_DEBUG_PIN_CTL_OE_3 (0x00008034) +#define WCD9360_TEST_DEBUG_PIN_CTL_OE_4 (0x00008035) +#define WCD9360_TEST_DEBUG_PIN_CTL_DATA_0 (0x00008036) +#define WCD9360_TEST_DEBUG_PIN_CTL_DATA_1 (0x00008037) +#define WCD9360_TEST_DEBUG_PIN_CTL_DATA_2 (0x00008038) +#define WCD9360_TEST_DEBUG_PIN_CTL_DATA_3 (0x00008039) +#define WCD9360_TEST_DEBUG_PIN_CTL_DATA_4 (0x0000803A) +#define WCD9360_TEST_DEBUG_PAD_DRVCTL_0 (0x0000803B) +#define WCD9360_TEST_DEBUG_PAD_DRVCTL_1 (0x0000803C) +#define WCD9360_TEST_DEBUG_PIN_STATUS (0x0000803D) +#define WCD9360_TEST_DEBUG_NPL_DLY_TEST_1 (0x0000803E) +#define WCD9360_TEST_DEBUG_NPL_DLY_TEST_2 (0x0000803F) +#define WCD9360_TEST_DEBUG_MEM_CTRL (0x00008040) +#define WCD9360_TEST_DEBUG_DEBUG_BUS_SEL (0x00008041) +#define WCD9360_TEST_DEBUG_DEBUG_JTAG (0x00008042) +#define WCD9360_TEST_DEBUG_DEBUG_EN_1 (0x00008043) +#define WCD9360_TEST_DEBUG_DEBUG_EN_2 (0x00008044) +#define WCD9360_TEST_DEBUG_DEBUG_EN_3 (0x00008045) +#define WCD9360_TEST_DEBUG_DEBUG_EN_4 (0x00008046) +#define WCD9360_TEST_DEBUG_DEBUG_EN_5 (0x00008047) +#define WCD9360_TEST_DEBUG_ANA_DTEST_DIR (0x0000804A) +#define WCD9360_TEST_DEBUG_PAD_INP_DISABLE_0 (0x0000804B) +#define WCD9360_TEST_DEBUG_PAD_INP_DISABLE_1 (0x0000804C) +#define WCD9360_TEST_DEBUG_PAD_INP_DISABLE_2 (0x0000804D) +#define WCD9360_TEST_DEBUG_PAD_INP_DISABLE_3 (0x0000804E) +#define WCD9360_TEST_DEBUG_PAD_INP_DISABLE_4 (0x0000804F) +#define WCD9360_TEST_DEBUG_SYSMEM_CTRL (0x00008050) +#define WCD9360_TEST_DEBUG_LVAL_NOM_LOW (0x00008052) +#define WCD9360_TEST_DEBUG_LVAL_NOM_HIGH (0x00008053) +#define WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_LOW (0x00008054) +#define WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_HIGH (0x00008055) +#define WCD9360_TEST_DEBUG_SPI_SLAVE_CHAR (0x00008056) +#define WCD9360_TEST_DEBUG_CODEC_DIAGS (0x00008057) +#define WCD9360_TEST_DEBUG_PAD_TEST (0x00008058) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_0 (0x00008061) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_1 (0x00008062) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_2 (0x00008063) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_3 (0x00008064) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_4 (0x00008065) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_5 (0x00008066) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_6 (0x00008067) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_7 (0x00008068) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_8 (0x00008069) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_9 (0x0000806A) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_10 (0x0000806B) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_11 (0x0000806C) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_12 (0x0000806D) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_13 (0x0000806E) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_14 (0x0000806F) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_15 (0x00008070) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_16 (0x00008071) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_17 (0x00008072) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_18 (0x00008073) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_19 (0x00008074) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_20 (0x00008075) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_21 (0x00008076) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_22 (0x00008077) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_23 (0x00008078) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_24 (0x00008079) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_25 (0x0000807A) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_26 (0x0000807B) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_27 (0x0000807C) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_28 (0x0000807D) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_29 (0x0000807E) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_30 (0x0000807F) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_31 (0x00008080) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_RD_CTRL (0x00008081) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_RD_7_0 (0x00008082) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_RD_15_8 (0x00008083) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_RD_23_16 (0x00008084) +#define WCD9360_TEST_DEBUG_DEBUG_MUX_RD_31_24 (0x00008085) +#define WCD9360_MAX_REGISTER 0x80FF + +/* SLIMBUS Slave Registers */ +#define WCD9360_SLIM_PGD_PORT_INT_RX_EN0 (0x30) +#define WCD9360_SLIM_PGD_PORT_INT_TX_EN0 (0x32) +#define WCD9360_SLIM_PGD_PORT_INT_STATUS_RX_0 (0x34) +#define WCD9360_SLIM_PGD_PORT_INT_STATUS_RX_1 (0x35) +#define WCD9360_SLIM_PGD_PORT_INT_STATUS_TX_0 (0x36) +#define WCD9360_SLIM_PGD_PORT_INT_STATUS_TX_1 (0x37) +#define WCD9360_SLIM_PGD_PORT_INT_CLR_RX_0 (0x38) +#define WCD9360_SLIM_PGD_PORT_INT_CLR_RX_1 (0x39) +#define WCD9360_SLIM_PGD_PORT_INT_CLR_TX_0 (0x3A) +#define WCD9360_SLIM_PGD_PORT_INT_CLR_TX_1 (0x3B) +#define WCD9360_SLIM_PGD_PORT_INT_RX_SOURCE0 (0x60) +#define WCD9360_SLIM_PGD_PORT_INT_TX_SOURCE0 (0x70) + +#endif -- GitLab From 130934724fad11a170980782c0b2d687e17c37e8 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Mon, 22 Jan 2018 18:32:55 -0800 Subject: [PATCH 0150/1645] codecs: add wcd9360 driver support in wcd9xxx core Add changes to support wcd9360 audio codec driver in wcd9xxx common files. Change-Id: I5b9f9d592b6843d7887eb3954d079776ddf15764 Signed-off-by: Vidyakumar Athota --- asoc/codecs/core.h | 2 + asoc/codecs/wcd9xxx-core.c | 6 +- asoc/codecs/wcd9xxx-regmap.h | 7 +- asoc/codecs/wcd9xxx-resmgr-v2.c | 127 ++++++++++++------------- asoc/codecs/wcd9xxx-rst.c | 161 +++++++++++++++++++++++++++++++- asoc/codecs/wcd9xxx-utils.c | 19 +++- 6 files changed, 253 insertions(+), 69 deletions(-) diff --git a/asoc/codecs/core.h b/asoc/codecs/core.h index c6f62cf46b33..7d9fcd2db268 100644 --- a/asoc/codecs/core.h +++ b/asoc/codecs/core.h @@ -119,6 +119,7 @@ enum codec_variant { WCD9335, WCD9326, WCD934X, + WCD9360, }; enum wcd9xxx_slim_slave_addr_type { @@ -297,6 +298,7 @@ enum wcd9xxx_chipid_major { TASHA_MAJOR = cpu_to_le16(0x0), TASHA2P0_MAJOR = cpu_to_le16(0x107), TAVIL_MAJOR = cpu_to_le16(0x108), + PAHU_MAJOR = cpu_to_le16(0x109), }; enum codec_power_states { diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index 49be43a3e12f..54f3eae0e62e 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -88,6 +88,7 @@ static const int wcd9xxx_cdc_types[] = { [WCD9330] = WCD9330, [WCD9335] = WCD9335, [WCD934X] = WCD934X, + [WCD9360] = WCD9360, }; static const struct of_device_id wcd9xxx_of_match[] = { @@ -327,7 +328,8 @@ int wcd9xxx_slim_write_repeat(struct wcd9xxx *wcd9xxx, unsigned short reg, struct slim_ele_access slim_msg; mutex_lock(&wcd9xxx->io_lock); - if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X) { + if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X || + wcd9xxx->type == WCD9360) { ret = wcd9xxx_page_write(wcd9xxx, ®); if (ret) goto done; diff --git a/asoc/codecs/wcd9xxx-regmap.h b/asoc/codecs/wcd9xxx-regmap.h index b7604ffb38d0..18e0e58b5117 100644 --- a/asoc/codecs/wcd9xxx-regmap.h +++ b/asoc/codecs/wcd9xxx-regmap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -19,6 +19,8 @@ typedef int (*regmap_patch_fptr)(struct regmap *, int); +extern struct regmap_config wcd9360_regmap_config; + extern struct regmap_config wcd934x_regmap_config; extern int wcd934x_regmap_register_patch(struct regmap *regmap, int version); @@ -32,6 +34,9 @@ static inline struct regmap_config *wcd9xxx_get_regmap_config(int type) struct regmap_config *regmap_config; switch (type) { + case WCD9360: + regmap_config = &wcd9360_regmap_config; + break; case WCD934X: regmap_config = &wcd934x_regmap_config; break; diff --git a/asoc/codecs/wcd9xxx-resmgr-v2.c b/asoc/codecs/wcd9xxx-resmgr-v2.c index 1b7610f08835..d390558ce660 100644 --- a/asoc/codecs/wcd9xxx-resmgr-v2.c +++ b/asoc/codecs/wcd9xxx-resmgr-v2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -17,14 +17,18 @@ #include #include "wcd9xxx-resmgr-v2.h" #include "core.h" -#include "wcd9335_registers.h" -#include #define WCD9XXX_RCO_CALIBRATION_DELAY_INC_US 5000 +/* This register is valid only for WCD9335 */ +#define WCD93XX_ANA_CLK_TOP 0x0602 + #define WCD93XX_ANA_BIAS 0x0601 #define WCD93XX_CDC_CLK_RST_CTRL_MCLK_CONTROL 0x0d41 #define WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL 0x0d42 - +#define WCD93XX_CLK_SYS_MCLK_PRG 0x711 +#define WCD93XX_CODEC_RPM_CLK_GATE 0x002 +#define WCD93XX_ANA_RCO 0x603 +#define WCD93XX_ANA_BUCK_CTL 0x606 static const char *wcd_resmgr_clk_type_to_str(enum wcd_clock_type clk_type) { @@ -44,13 +48,13 @@ static int wcd_resmgr_codec_reg_update_bits(struct wcd9xxx_resmgr_v2 *resmgr, bool change; int ret; - if (resmgr->codec_type == WCD934X) { - /* Tavil does not support ANA_CLK_TOP register */ - if (reg == WCD9335_ANA_CLK_TOP) + if (resmgr->codec_type != WCD9335) { + /* Tavil and Pahu does not support ANA_CLK_TOP register */ + if (reg == WCD93XX_ANA_CLK_TOP) return 0; } else { /* Tasha does not support CLK_SYS_MCLK_PRG register */ - if (reg == WCD934X_CLK_SYS_MCLK_PRG) + if (reg == WCD93XX_CLK_SYS_MCLK_PRG) return 0; } if (resmgr->codec) { @@ -74,11 +78,11 @@ static int wcd_resmgr_codec_reg_read(struct wcd9xxx_resmgr_v2 *resmgr, { int val, ret; - if (resmgr->codec_type == WCD934X) { - if (reg == WCD9335_ANA_CLK_TOP) + if (resmgr->codec_type != WCD9335) { + if (reg == WCD93XX_ANA_CLK_TOP) return 0; } else { - if (reg == WCD934X_CLK_SYS_MCLK_PRG) + if (reg == WCD93XX_CLK_SYS_MCLK_PRG) return 0; } if (resmgr->codec) { @@ -242,26 +246,26 @@ static int wcd_resmgr_enable_clk_mclk(struct wcd9xxx_resmgr_v2 *resmgr) if (++resmgr->clk_mclk_users == 1) { wcd_resmgr_codec_reg_update_bits(resmgr, - WCD9335_ANA_CLK_TOP, 0x80, 0x80); + WCD93XX_ANA_CLK_TOP, 0x80, 0x80); wcd_resmgr_codec_reg_update_bits(resmgr, - WCD9335_ANA_CLK_TOP, 0x08, 0x00); + WCD93XX_ANA_CLK_TOP, 0x08, 0x00); wcd_resmgr_codec_reg_update_bits(resmgr, - WCD9335_ANA_CLK_TOP, 0x04, 0x04); - if (resmgr->codec_type == WCD934X) { + WCD93XX_ANA_CLK_TOP, 0x04, 0x04); + if (resmgr->codec_type != WCD9335) { /* * In tavil clock contrl register is changed * to CLK_SYS_MCLK_PRG */ wcd_resmgr_codec_reg_update_bits(resmgr, - WCD934X_CLK_SYS_MCLK_PRG, 0x80, 0x80); + WCD93XX_CLK_SYS_MCLK_PRG, 0x80, 0x80); wcd_resmgr_codec_reg_update_bits(resmgr, - WCD934X_CLK_SYS_MCLK_PRG, 0x30, 0x10); + WCD93XX_CLK_SYS_MCLK_PRG, 0x30, 0x10); wcd_resmgr_codec_reg_update_bits(resmgr, - WCD934X_CLK_SYS_MCLK_PRG, 0x02, 0x00); + WCD93XX_CLK_SYS_MCLK_PRG, 0x02, 0x00); wcd_resmgr_codec_reg_update_bits(resmgr, - WCD934X_CLK_SYS_MCLK_PRG, 0x01, 0x01); + WCD93XX_CLK_SYS_MCLK_PRG, 0x01, 0x01); wcd_resmgr_codec_reg_update_bits(resmgr, - WCD934X_CLK_SYS_MCLK_PRG, 0x02, 0x00); + WCD93XX_CLK_SYS_MCLK_PRG, 0x02, 0x00); wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x01); @@ -269,10 +273,7 @@ static int wcd_resmgr_enable_clk_mclk(struct wcd9xxx_resmgr_v2 *resmgr) WCD93XX_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x01); wcd_resmgr_codec_reg_update_bits(resmgr, - WCD93XX_CDC_CLK_RST_CTRL_MCLK_CONTROL, - 0x01, 0x01); - wcd_resmgr_codec_reg_update_bits(resmgr, - WCD934X_CODEC_RPM_CLK_GATE, 0x03, 0x00); + WCD93XX_CODEC_RPM_CLK_GATE, 0x03, 0x00); } else { wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, @@ -308,28 +309,28 @@ static int wcd_resmgr_disable_clk_mclk(struct wcd9xxx_resmgr_v2 *resmgr) if (resmgr->clk_rco_users > 0) { /* MCLK to RCO switch */ wcd_resmgr_codec_reg_update_bits(resmgr, - WCD9335_ANA_CLK_TOP, + WCD93XX_ANA_CLK_TOP, 0x08, 0x08); wcd_resmgr_codec_reg_update_bits(resmgr, - WCD934X_CLK_SYS_MCLK_PRG, 0x02, 0x02); + WCD93XX_CLK_SYS_MCLK_PRG, 0x02, 0x02); /* Disable clock buffer */ wcd_resmgr_codec_reg_update_bits(resmgr, - WCD934X_CLK_SYS_MCLK_PRG, 0x80, 0x00); + WCD93XX_CLK_SYS_MCLK_PRG, 0x80, 0x00); resmgr->clk_type = WCD_CLK_RCO; } else { wcd_resmgr_codec_reg_update_bits(resmgr, - WCD9335_ANA_CLK_TOP, + WCD93XX_ANA_CLK_TOP, 0x04, 0x00); wcd_resmgr_codec_reg_update_bits(resmgr, - WCD934X_CLK_SYS_MCLK_PRG, 0x81, 0x00); + WCD93XX_CLK_SYS_MCLK_PRG, 0x81, 0x00); resmgr->clk_type = WCD_CLK_OFF; } - wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_CLK_TOP, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_CLK_TOP, 0x80, 0x00); } - if ((resmgr->codec_type == WCD934X) && + if ((resmgr->codec_type != WCD9335) && (resmgr->clk_type == WCD_CLK_OFF)) wcd_resmgr_set_sido_input_src(resmgr, SIDO_SOURCE_INTERNAL); @@ -342,15 +343,15 @@ static int wcd_resmgr_disable_clk_mclk(struct wcd9xxx_resmgr_v2 *resmgr) static void wcd_resmgr_set_buck_accuracy(struct wcd9xxx_resmgr_v2 *resmgr) { - wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL, 0x02, 0x02); /* 100us sleep needed after HIGH_ACCURACY_PRE_EN1 */ usleep_range(100, 110); - wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL, 0x01, 0x01); /* 100us sleep needed after HIGH_ACCURACY_PRE_EN2 */ usleep_range(100, 110); - wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL, 0x04, 0x04); /* 100us sleep needed after HIGH_ACCURACY_EN */ usleep_range(100, 110); @@ -373,9 +374,9 @@ static int wcd_resmgr_enable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr) /* RCO Enable */ if (resmgr->sido_input_src == SIDO_SOURCE_INTERNAL) { wcd_resmgr_codec_reg_update_bits(resmgr, - WCD9335_ANA_RCO, - 0x80, 0x80); - if (resmgr->codec_type == WCD934X) + WCD93XX_ANA_RCO, + 0x80, 0x80); + if (resmgr->codec_type != WCD9335) wcd_resmgr_set_buck_accuracy(resmgr); } @@ -384,7 +385,7 @@ static int wcd_resmgr_enable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr) * requirements */ usleep_range(20, 25); - wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO, 0x40, 0x40); /* * 20us required after RCO is enabled as per HW @@ -392,20 +393,20 @@ static int wcd_resmgr_enable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr) */ usleep_range(20, 25); /* RCO Calibration */ - wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO, 0x04, 0x04); - if (resmgr->codec_type == WCD934X) + if (resmgr->codec_type != WCD9335) /* - * For wcd934x codec, 20us sleep is needed + * For wcd934x and wcd936x codecs, 20us sleep is needed * after enabling RCO calibration */ usleep_range(20, 25); - wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO, 0x04, 0x00); - if (resmgr->codec_type == WCD934X) + if (resmgr->codec_type != WCD9335) /* - * For wcd934x codec, 20us sleep is needed + * For wcd934x and wcd936x codecs, 20us sleep is needed * after disabling RCO calibration */ usleep_range(20, 25); @@ -413,7 +414,7 @@ static int wcd_resmgr_enable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr) /* RCO calibration takes app. 5ms to complete */ usleep_range(WCD9XXX_RCO_CALIBRATION_DELAY_INC_US, WCD9XXX_RCO_CALIBRATION_DELAY_INC_US + 100); - if (wcd_resmgr_codec_reg_read(resmgr, WCD9335_ANA_RCO) & 0x02) + if (wcd_resmgr_codec_reg_read(resmgr, WCD93XX_ANA_RCO) & 0x02) rco_cal_done = false; WARN((!rco_cal_done), "RCO Calibration failed\n"); @@ -421,10 +422,10 @@ static int wcd_resmgr_enable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr) /* Switch MUX to RCO */ if (resmgr->clk_mclk_users == 1) { wcd_resmgr_codec_reg_update_bits(resmgr, - WCD9335_ANA_CLK_TOP, + WCD93XX_ANA_CLK_TOP, 0x08, 0x08); wcd_resmgr_codec_reg_update_bits(resmgr, - WCD934X_CLK_SYS_MCLK_PRG, + WCD93XX_CLK_SYS_MCLK_PRG, 0x02, 0x02); resmgr->clk_type = WCD_CLK_RCO; } @@ -449,35 +450,35 @@ static int wcd_resmgr_disable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr) if ((resmgr->clk_rco_users == 0) && (resmgr->clk_type == WCD_CLK_RCO)) { - wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_CLK_TOP, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_CLK_TOP, 0x08, 0x00); wcd_resmgr_codec_reg_update_bits(resmgr, - WCD934X_CLK_SYS_MCLK_PRG, + WCD93XX_CLK_SYS_MCLK_PRG, 0x02, 0x00); - wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_CLK_TOP, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_CLK_TOP, 0x04, 0x00); - wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO, 0x40, 0x00); if (resmgr->sido_input_src == SIDO_SOURCE_INTERNAL) wcd_resmgr_codec_reg_update_bits(resmgr, - WCD9335_ANA_RCO, + WCD93XX_ANA_RCO, 0x80, 0x00); wcd_resmgr_codec_reg_update_bits(resmgr, - WCD934X_CLK_SYS_MCLK_PRG, + WCD93XX_CLK_SYS_MCLK_PRG, 0x01, 0x00); resmgr->clk_type = WCD_CLK_OFF; } else if ((resmgr->clk_rco_users == 0) && (resmgr->clk_mclk_users)) { /* Disable RCO while MCLK is ON */ - wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO, 0x40, 0x00); if (resmgr->sido_input_src == SIDO_SOURCE_INTERNAL) wcd_resmgr_codec_reg_update_bits(resmgr, - WCD9335_ANA_RCO, + WCD93XX_ANA_RCO, 0x80, 0x00); } - if ((resmgr->codec_type == WCD934X) && + if ((resmgr->codec_type != WCD9335) && (resmgr->clk_type == WCD_CLK_OFF)) wcd_resmgr_set_sido_input_src(resmgr, SIDO_SOURCE_INTERNAL); @@ -530,28 +531,28 @@ void wcd_resmgr_set_sido_input_src(struct wcd9xxx_resmgr_v2 *resmgr, return; if (sido_src == SIDO_SOURCE_INTERNAL) { - wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL, 0x04, 0x00); usleep_range(100, 110); - wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL, 0x03, 0x00); usleep_range(100, 110); - wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_RCO, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO, 0x80, 0x00); usleep_range(100, 110); resmgr->sido_input_src = SIDO_SOURCE_INTERNAL; pr_debug("%s: sido input src to internal\n", __func__); } else if (sido_src == SIDO_SOURCE_RCO_BG) { - wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_RCO, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO, 0x80, 0x80); usleep_range(100, 110); - wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL, 0x02, 0x02); usleep_range(100, 110); - wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL, 0x01, 0x01); usleep_range(100, 110); - wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL, + wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL, 0x04, 0x04); usleep_range(100, 110); resmgr->sido_input_src = SIDO_SOURCE_RCO_BG; diff --git a/asoc/codecs/wcd9xxx-rst.c b/asoc/codecs/wcd9xxx-rst.c index 3df95d537fe8..b369556a1a6d 100644 --- a/asoc/codecs/wcd9xxx-rst.c +++ b/asoc/codecs/wcd9xxx-rst.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -22,6 +22,8 @@ #include "wcd9335_irq.h" #include #include "wcd934x/wcd934x_irq.h" +#include +#include "wcd9360/wcd9360-irq.h" /* wcd9335 interrupt table */ static const struct intr_data wcd9335_intr_table[] = { @@ -86,6 +88,25 @@ static const struct intr_data wcd934x_intr_table[] = { {WCD934X_IRQ_VBAT_RESTORE, false}, }; +static const struct intr_data wcd9360_intr_table[] = { + {WCD9XXX_IRQ_SLIMBUS, false}, + {WCD9360_IRQ_MISC, false}, + {WCD9360_IRQ_LDO_RXTX_SCD, false}, + {WCD9360_IRQ_EAR_PA_SCD, false}, + {WCD9360_IRQ_AUX_PA_SCD, false}, + {WCD9360_IRQ_EAR_PA_CNP_COMPLETE, false}, + {WCD9360_IRQ_AUX_PA_CNP_COMPLETE, false}, + {WCD9360_IRQ_RESERVED_3, false}, + {WCD9360_IRQ_SOUNDWIRE, false}, + {WCD9360_IRQ_RCO_ERROR, false}, + {WCD9360_IRQ_CPE_ERROR, false}, + {WCD9360_IRQ_MAD_AUDIO, false}, + {WCD9360_IRQ_MAD_BEACON, false}, + {WCD9360_IRQ_CPE1_INTR, true}, + {WCD9360_IRQ_RESERVED_4, false}, + {WCD9360_IRQ_MAD_ULTRASOUND, false}, +}; + /* * wcd9335_bring_down: Bringdown WCD Codec * @@ -384,11 +405,143 @@ static int wcd934x_get_cdc_info(struct wcd9xxx *wcd9xxx, return rc; } +/* + * wcd9360_bring_down: Bringdown WCD Codec + * + * @wcd9xxx: Pointer to wcd9xxx structure + * + * Returns 0 for success or negative error code for failure + */ +static int wcd9360_bring_down(struct wcd9xxx *wcd9xxx) +{ + if (!wcd9xxx || !wcd9xxx->regmap) + return -EINVAL; + + regmap_write(wcd9xxx->regmap, WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x04); + + return 0; +} + +/* + * wcd9360_bring_up: Bringup WCD Codec + * + * @wcd9xxx: Pointer to the wcd9xxx structure + * + * Returns 0 for success or negative error code for failure + */ +static int wcd9360_bring_up(struct wcd9xxx *wcd9xxx) +{ + struct regmap *wcd_regmap; + + if (!wcd9xxx) + return -EINVAL; + + if (!wcd9xxx->regmap) { + dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null!\n", + __func__); + return -EINVAL; + } + wcd_regmap = wcd9xxx->regmap; + + regmap_write(wcd_regmap, WCD9360_CODEC_RPM_RST_CTL, 0x01); + regmap_write(wcd_regmap, WCD9360_SIDO_NEW_VOUT_A_STARTUP, 0x19); + regmap_write(wcd_regmap, WCD9360_SIDO_NEW_VOUT_D_STARTUP, 0x15); + /* Add 1msec delay for VOUT to settle */ + usleep_range(1000, 1100); + regmap_write(wcd_regmap, WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5); + regmap_write(wcd_regmap, WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7); + regmap_write(wcd_regmap, WCD9360_CODEC_RPM_RST_CTL, 0x3); + regmap_write(wcd_regmap, WCD9360_CODEC_RPM_RST_CTL, 0x7); + regmap_write(wcd_regmap, WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3); + + return 0; +} + +/* + * wcd9360_get_cdc_info: Get codec specific information + * + * @wcd9xxx: pointer to wcd9xxx structure + * @wcd_type: pointer to wcd9xxx_codec_type structure + * + * Returns 0 for success or negative error code for failure + */ +static int wcd9360_get_cdc_info(struct wcd9xxx *wcd9xxx, + struct wcd9xxx_codec_type *wcd_type) +{ + u16 id_minor, id_major; + struct regmap *wcd_regmap; + int rc, version = -1; + + if (!wcd9xxx || !wcd_type) + return -EINVAL; + + if (!wcd9xxx->regmap) { + dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null\n", __func__); + return -EINVAL; + } + wcd_regmap = wcd9xxx->regmap; + + rc = regmap_bulk_read(wcd_regmap, WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE0, + (u8 *)&id_minor, sizeof(u16)); + if (rc) + return -EINVAL; + + rc = regmap_bulk_read(wcd_regmap, WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE2, + (u8 *)&id_major, sizeof(u16)); + if (rc) + return -EINVAL; + + dev_info(wcd9xxx->dev, "%s: wcd9xxx chip id major 0x%x, minor 0x%x\n", + __func__, id_major, id_minor); + + if (id_major != PAHU_MAJOR) + goto version_unknown; + + /* + * As fine version info cannot be retrieved before pahu probe. + * Assign coarse versions for possible future use before Pahu probe. + */ + if (id_minor == cpu_to_le16(0)) + version = PAHU_VERSION_1_0; + +version_unknown: + if (version < 0) + dev_err(wcd9xxx->dev, "%s: wcd934x version unknown\n", + __func__); + + /* Fill codec type info */ + wcd_type->id_major = id_major; + wcd_type->id_minor = id_minor; + wcd_type->num_irqs = WCD9360_NUM_IRQS; + wcd_type->version = version; + wcd_type->slim_slave_type = WCD9XXX_SLIM_SLAVE_ADDR_TYPE_1; + wcd_type->i2c_chip_status = 0x01; + wcd_type->intr_tbl = wcd9360_intr_table; + wcd_type->intr_tbl_size = ARRAY_SIZE(wcd934x_intr_table); + + wcd_type->intr_reg[WCD9XXX_INTR_STATUS_BASE] = + WCD9360_INTR_PIN1_STATUS0; + wcd_type->intr_reg[WCD9XXX_INTR_CLEAR_BASE] = + WCD9360_INTR_PIN1_CLEAR0; + wcd_type->intr_reg[WCD9XXX_INTR_MASK_BASE] = + WCD9360_INTR_PIN1_MASK0; + wcd_type->intr_reg[WCD9XXX_INTR_LEVEL_BASE] = + WCD9360_INTR_LEVEL0; + wcd_type->intr_reg[WCD9XXX_INTR_CLR_COMMIT] = + WCD9360_INTR_CLR_COMMIT; + + return rc; +} + codec_bringdown_fn wcd9xxx_bringdown_fn(int type) { codec_bringdown_fn cdc_bdown_fn; switch (type) { + case WCD9360: + cdc_bdown_fn = wcd9360_bring_down; + break; case WCD934X: cdc_bdown_fn = wcd934x_bring_down; break; @@ -408,6 +561,9 @@ codec_bringup_fn wcd9xxx_bringup_fn(int type) codec_bringup_fn cdc_bup_fn; switch (type) { + case WCD9360: + cdc_bup_fn = wcd9360_bring_up; + break; case WCD934X: cdc_bup_fn = wcd934x_bring_up; break; @@ -427,6 +583,9 @@ codec_type_fn wcd9xxx_get_codec_info_fn(int type) codec_type_fn cdc_type_fn; switch (type) { + case WCD9360: + cdc_type_fn = wcd9360_get_cdc_info; + break; case WCD934X: cdc_type_fn = wcd934x_get_cdc_info; break; diff --git a/asoc/codecs/wcd9xxx-utils.c b/asoc/codecs/wcd9xxx-utils.c index eee90a28952d..1f521bca4b23 100644 --- a/asoc/codecs/wcd9xxx-utils.c +++ b/asoc/codecs/wcd9xxx-utils.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -38,6 +38,16 @@ static enum wcd9xxx_intf_status wcd9xxx_intf = -1; +static struct mfd_cell pahu_devs[] = { + { + .name = "qcom-wcd-pinctrl", + .of_compatible = "qcom,wcd-pinctrl", + }, + { + .name = "pahu_codec", + }, +}; + static struct mfd_cell tavil_devs[] = { { .name = "qcom-wcd-pinctrl", @@ -467,7 +477,8 @@ int wcd9xxx_page_write(struct wcd9xxx *wcd9xxx, unsigned short *reg) unsigned short c_reg, reg_addr; u8 pg_num, prev_pg_num; - if (wcd9xxx->type != WCD9335 && wcd9xxx->type != WCD934X) + if (wcd9xxx->type != WCD9335 && wcd9xxx->type != WCD934X && + wcd9xxx->type != WCD9360) return ret; c_reg = *reg; @@ -864,6 +875,10 @@ int wcd9xxx_get_codec_info(struct device *dev) } switch (wcd9xxx->type) { + case WCD9360: + cinfo->dev = pahu_devs; + cinfo->size = ARRAY_SIZE(pahu_devs); + break; case WCD934X: cinfo->dev = tavil_devs; cinfo->size = ARRAY_SIZE(tavil_devs); -- GitLab From 08bb73698a5af9f4e6fc33cefb97ae7b58401054 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Fri, 3 Nov 2017 22:48:23 -0700 Subject: [PATCH 0151/1645] dsp: update MSM Audio ION wrappers to align with upstream Between Linux-4.9 and Linux-4.14, upstream has updated the ION APIs significantly to make ION ready to bring out of staging folder. This has changed the way ION and dma_buf APIs used to work together for allocating, mapping and deallocating ION buffers. Update MSM Audio ION wrapper functions used by audio drivers to reflect these ION API changes as per upstream ION. Change-Id: I63097e147a397aa3a538f69ac88b6fb10871c3dc Signed-off-by: Banajit Goswami --- asoc/msm-pcm-host-voice-v2.c | 33 +- asoc/msm-pcm-q6-noirq.c | 11 +- dsp/audio_cal_utils.c | 20 +- dsp/codecs/audio_utils_aio.c | 31 +- dsp/codecs/audio_utils_aio.h | 5 +- dsp/msm-dts-srs-tm-config.c | 16 +- dsp/msm_audio_ion.c | 1010 ++++++++++++++------------------- dsp/q6adm.c | 32 +- dsp/q6afe.c | 19 +- dsp/q6asm.c | 64 +-- dsp/q6lsm.c | 23 +- dsp/q6usm.c | 21 +- dsp/q6usm.h | 14 +- dsp/q6voice.c | 106 ++-- dsp/rtac.c | 30 +- include/dsp/audio_cal_utils.h | 5 +- include/dsp/msm_audio_ion.h | 30 +- include/dsp/q6afe-v2.h | 5 +- include/dsp/q6asm-v2.h | 5 +- include/dsp/q6lsm.h | 8 +- include/dsp/q6voice.h | 17 +- include/dsp/rtac.h | 5 +- 22 files changed, 592 insertions(+), 918 deletions(-) diff --git a/asoc/msm-pcm-host-voice-v2.c b/asoc/msm-pcm-host-voice-v2.c index fd771df5d3d4..440228e0689d 100644 --- a/asoc/msm-pcm-host-voice-v2.c +++ b/asoc/msm-pcm-host-voice-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -119,7 +119,7 @@ struct session { struct tap_point rx_tap_point; phys_addr_t sess_paddr; void *sess_kvaddr; - struct ion_handle *ion_handle; + struct dma_buf *dma_buf; struct mem_map_table tp_mem_table; }; @@ -145,7 +145,6 @@ struct hpcm_drv { struct mutex lock; struct session session[MAX_SESSION]; struct mixer_conf mixer_conf; - struct ion_client *ion_client; struct start_cmd start_cmd; }; @@ -452,19 +451,12 @@ static void hpcm_free_allocated_mem(struct hpcm_drv *prtd) paddr = sess->sess_paddr; if (paddr) { - msm_audio_ion_free(prtd->ion_client, sess->ion_handle); - prtd->ion_client = NULL; - sess->ion_handle = NULL; - msm_audio_ion_free(sess->tp_mem_table.client, - sess->tp_mem_table.handle); - sess->tp_mem_table.client = NULL; - sess->tp_mem_table.handle = NULL; + msm_audio_ion_free(sess->dma_buf); + sess->dma_buf = NULL; + msm_audio_ion_free(sess->tp_mem_table.dma_buf); + sess->tp_mem_table.dma_buf = NULL; sess->sess_paddr = 0; sess->sess_kvaddr = 0; - sess->ion_handle = 0; - prtd->ion_client = 0; - sess->tp_mem_table.client = 0; - sess->tp_mem_table.handle = 0; txtp->capture_dai_data.vocpcm_ion_buffer.paddr = 0; txtp->capture_dai_data.vocpcm_ion_buffer.kvaddr = 0; @@ -531,9 +523,7 @@ static int hpcm_allocate_shared_memory(struct hpcm_drv *prtd) txtp = &sess->tx_tap_point; rxtp = &sess->rx_tap_point; - result = msm_audio_ion_alloc("host_pcm_buffer", - &prtd->ion_client, - &sess->ion_handle, + result = msm_audio_ion_alloc(&sess->dma_buf, VHPCM_BLOCK_SIZE, &sess->sess_paddr, &mem_len, @@ -549,9 +539,7 @@ static int hpcm_allocate_shared_memory(struct hpcm_drv *prtd) pr_debug("%s: Host PCM memory block allocated\n", __func__); /* Allocate mem_map_table for tap point */ - result = msm_audio_ion_alloc("host_pcm_table", - &sess->tp_mem_table.client, - &sess->tp_mem_table.handle, + result = msm_audio_ion_alloc(&sess->tp_mem_table.dma_buf, sizeof(struct vss_imemory_table_t), &sess->tp_mem_table.phys, &len, @@ -560,9 +548,8 @@ static int hpcm_allocate_shared_memory(struct hpcm_drv *prtd) if (result) { pr_err("%s: msm_audio_ion_alloc error, rc = %d\n", __func__, result); - msm_audio_ion_free(prtd->ion_client, sess->ion_handle); - prtd->ion_client = NULL; - sess->ion_handle = NULL; + msm_audio_ion_free(sess->dma_buf); + sess->dma_buf = NULL; sess->sess_paddr = 0; sess->sess_kvaddr = 0; ret = -ENOMEM; diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index dbc6d33a65be..34dc4bbdd118 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -451,7 +452,13 @@ static int msm_pcm_mmap_fd(struct snd_pcm_substream *substream, apd = prtd->audio_client->port; ab = &(apd[dir].buf[0]); - mmap_fd->fd = ion_share_dma_buf_fd(ab->client, ab->handle); + /* + * Passing O_CLOEXEC as flag passed to fd, to be in sync with + * previous implimentation. + * This was the flag used by previous internal wrapper API, which + * used to call dma_buf_fd internally. + */ + mmap_fd->fd = dma_buf_fd(ab->dma_buf, O_CLOEXEC); if (mmap_fd->fd >= 0) { mmap_fd->dir = dir; mmap_fd->actual_size = ab->actual_size; diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index ad1dc3d35ce3..95794796c4f1 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -442,11 +442,9 @@ static void delete_cal_block(struct cal_block_data *cal_block) cal_block->client_info = NULL; kfree(cal_block->cal_info); cal_block->cal_info = NULL; - if (cal_block->map_data.ion_client != NULL) { - msm_audio_ion_free(cal_block->map_data.ion_client, - cal_block->map_data.ion_handle); - cal_block->map_data.ion_client = NULL; - cal_block->map_data.ion_handle = NULL; + if (cal_block->map_data.dma_buf != NULL) { + msm_audio_ion_free(cal_block->map_data.dma_buf); + cal_block->map_data.dma_buf = NULL; } kfree(cal_block); done: @@ -604,9 +602,7 @@ static int cal_block_ion_alloc(struct cal_block_data *cal_block) goto done; } - ret = msm_audio_ion_import("audio_cal_client", - &cal_block->map_data.ion_client, - &cal_block->map_data.ion_handle, + ret = msm_audio_ion_import(&cal_block->map_data.dma_buf, cal_block->map_data.ion_map_handle, NULL, 0, &cal_block->cal_data.paddr, @@ -736,10 +732,8 @@ static int realloc_memory(struct cal_block_data *cal_block) { int ret = 0; - msm_audio_ion_free(cal_block->map_data.ion_client, - cal_block->map_data.ion_handle); - cal_block->map_data.ion_client = NULL; - cal_block->map_data.ion_handle = NULL; + msm_audio_ion_free(cal_block->map_data.dma_buf); + cal_block->map_data.dma_buf = NULL; cal_block->cal_data.size = 0; ret = cal_block_ion_alloc(cal_block); diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c index e8f22e79f8cb..7f332f4f7aa6 100644 --- a/dsp/codecs/audio_utils_aio.c +++ b/dsp/codecs/audio_utils_aio.c @@ -1,6 +1,6 @@ /* Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -420,7 +420,7 @@ void audio_aio_reset_ion_region(struct q6audio_aio *audio) list_for_each_safe(ptr, next, &audio->ion_region_queue) { region = list_entry(ptr, struct audio_aio_ion_region, list); list_del(®ion->list); - msm_audio_ion_free_legacy(audio->client, region->handle); + msm_audio_ion_free(region->dma_buf); kfree(region); } } @@ -614,7 +614,6 @@ int audio_aio_release(struct inode *inode, struct file *file) audio_aio_disable(audio); audio_aio_unmap_ion_region(audio); audio_aio_reset_ion_region(audio); - msm_audio_ion_client_destroy(audio->client); audio->event_abort = 1; wake_up(&audio->event_wait); audio_aio_reset_event_queue(audio); @@ -960,11 +959,11 @@ static int audio_aio_ion_check(struct q6audio_aio *audio, static int audio_aio_ion_add(struct q6audio_aio *audio, struct msm_audio_ion_info *info) { - ion_phys_addr_t paddr = 0; + dma_addr_t paddr = 0; size_t len = 0; struct audio_aio_ion_region *region; int rc = -EINVAL; - struct ion_handle *handle = NULL; + struct dma_buf *dma_buf = NULL; unsigned long ionflag; void *kvaddr = NULL; @@ -976,8 +975,7 @@ static int audio_aio_ion_add(struct q6audio_aio *audio, goto end; } - rc = msm_audio_ion_import_legacy("Audio_Dec_Client", audio->client, - &handle, info->fd, &ionflag, + rc = msm_audio_ion_import(&dma_buf, info->fd, &ionflag, 0, &paddr, &len, &kvaddr); if (rc) { pr_err("%s: msm audio ion alloc failed\n", __func__); @@ -990,7 +988,7 @@ static int audio_aio_ion_add(struct q6audio_aio *audio, goto ion_error; } - region->handle = handle; + region->dma_buf = dma_buf; region->vaddr = info->vaddr; region->fd = info->fd; region->paddr = paddr; @@ -1012,7 +1010,7 @@ static int audio_aio_ion_add(struct q6audio_aio *audio, mmap_error: list_del(®ion->list); ion_error: - msm_audio_ion_free_legacy(audio->client, handle); + msm_audio_ion_free(dma_buf); import_error: kfree(region); end: @@ -1049,8 +1047,7 @@ static int audio_aio_ion_remove(struct q6audio_aio *audio, __func__, audio); list_del(®ion->list); - msm_audio_ion_free_legacy(audio->client, - region->handle); + msm_audio_ion_free(region->dma_buf); kfree(region); rc = 0; break; @@ -1378,22 +1375,12 @@ int audio_aio_open(struct q6audio_aio *audio, struct file *file) goto cleanup; } } - audio->client = msm_audio_ion_client_create("Audio_Dec_Client"); - if (IS_ERR_OR_NULL(audio->client)) { - pr_err("Unable to create ION client\n"); - rc = -ENOMEM; - goto cleanup; - } - pr_debug("Ion client create in audio_aio_open %pK", audio->client); rc = register_volume_listener(audio); if (rc < 0) - goto ion_cleanup; + goto cleanup; return 0; -ion_cleanup: - msm_audio_ion_client_destroy(audio->client); - audio->client = NULL; cleanup: list_for_each_safe(ptr, next, &audio->free_event_queue) { e_node = list_first_entry(&audio->free_event_queue, diff --git a/dsp/codecs/audio_utils_aio.h b/dsp/codecs/audio_utils_aio.h index e44f9d9c642a..1993f6047ef1 100644 --- a/dsp/codecs/audio_utils_aio.h +++ b/dsp/codecs/audio_utils_aio.h @@ -1,6 +1,6 @@ /* Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -119,7 +119,7 @@ struct ws_mgr { struct audio_aio_ion_region { struct list_head list; - struct ion_handle *handle; + struct dma_buf *dma_buf; int fd; void *vaddr; phys_addr_t paddr; @@ -182,7 +182,6 @@ struct q6audio_aio { struct list_head free_event_queue; struct list_head event_queue; struct list_head ion_region_queue; /* protected by lock */ - struct ion_client *client; struct audio_aio_drv_operations drv_ops; union msm_audio_event_payload eos_write_payload; uint32_t device_events; diff --git a/dsp/msm-dts-srs-tm-config.c b/dsp/msm-dts-srs-tm-config.c index cd3da4d642d9..fff98b57287c 100644 --- a/dsp/msm-dts-srs-tm-config.c +++ b/dsp/msm-dts-srs-tm-config.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014, 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014, 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -25,8 +25,7 @@ static int srs_port_id[AFE_MAX_PORTS] = {-1}; static int srs_copp_idx[AFE_MAX_PORTS] = {-1}; static union srs_trumedia_params_u msm_srs_trumedia_params; -static struct ion_client *ion_client; -static struct ion_handle *ion_handle; +struct dma_buf *dma_buf; static struct param_outband po; static atomic_t ref_cnt; #define ION_MEM_SIZE (8 * 1024) @@ -299,13 +298,13 @@ static int reg_ion_mem(void) { int rc; - rc = msm_audio_ion_alloc("SRS_TRUMEDIA", &ion_client, &ion_handle, - ION_MEM_SIZE, &po.paddr, (size_t *)&po.size, + rc = msm_audio_ion_alloc(&dma_buf, ION_MEM_SIZE, + &po.paddr, (size_t *)&po.size, &po.kvaddr); if (rc != 0) pr_err("%s: failed to allocate memory.\n", __func__); - pr_debug("%s: exited ion_client = %pK, ion_handle = %pK, phys_addr = %lu, length = %d, vaddr = %pK, rc = 0x%x\n", - __func__, ion_client, ion_handle, (long)po.paddr, + pr_debug("%s: exited dma_buf = %pK, phys_addr = %lu, length = %d, vaddr = %pK, rc = 0x%x\n", + __func__, dma_buf, (long)po.paddr, (unsigned int)po.size, po.kvaddr, rc); return rc; } @@ -323,7 +322,8 @@ void msm_dts_srs_tm_ion_memmap(struct param_outband *po_) static void unreg_ion_mem(void) { - msm_audio_ion_free(ion_client, ion_handle); + msm_audio_ion_free(dma_buf); + dma_buf = NULL; po.kvaddr = NULL; po.paddr = 0; po.size = 0; diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index 113829057aff..c0879218515b 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -23,9 +23,10 @@ #include #include #include -#include #include #include +#include +#include #include #include @@ -40,7 +41,6 @@ #define MSM_AUDIO_SMMU_SID_OFFSET 32 struct msm_audio_ion_private { - bool smmu_enabled; bool audioheap_enabled; struct device *cb_dev; struct dma_iommu_mapping *mapping; @@ -52,9 +52,8 @@ struct msm_audio_ion_private { }; struct msm_audio_alloc_data { - struct ion_client *client; - struct ion_handle *handle; size_t len; + void *vaddr; struct dma_buf *dma_buf; struct dma_buf_attachment *attach; struct sg_table *table; @@ -63,17 +62,6 @@ struct msm_audio_alloc_data { static struct msm_audio_ion_private msm_audio_ion_data = {0,}; -static int msm_audio_ion_get_phys(struct ion_client *client, - struct ion_handle *handle, - ion_phys_addr_t *addr, size_t *len); - -static int msm_audio_dma_buf_map(struct ion_client *client, - struct ion_handle *handle, - ion_phys_addr_t *addr, size_t *len); - -static int msm_audio_dma_buf_unmap(struct ion_client *client, - struct ion_handle *handle); - static void msm_audio_ion_add_allocation( struct msm_audio_ion_private *msm_audio_ion_data, struct msm_audio_alloc_data *alloc_data) @@ -89,196 +77,408 @@ static void msm_audio_ion_add_allocation( mutex_unlock(&(msm_audio_ion_data->list_mutex)); } +static int msm_audio_dma_buf_map(struct dma_buf *dma_buf, + dma_addr_t *addr, size_t *len) +{ + + struct msm_audio_alloc_data *alloc_data; + struct device *cb_dev; + int rc = 0; + + cb_dev = msm_audio_ion_data.cb_dev; + + /* Data required per buffer mapping */ + alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL); + if (!alloc_data) + return -ENOMEM; + + alloc_data->dma_buf = dma_buf; + alloc_data->len = dma_buf->size; + *len = dma_buf->size; + + /* Attach the dma_buf to context bank device */ + alloc_data->attach = dma_buf_attach(alloc_data->dma_buf, + cb_dev); + if (IS_ERR(alloc_data->attach)) { + rc = PTR_ERR(alloc_data->attach); + dev_err(cb_dev, + "%s: Fail to attach dma_buf to CB, rc = %d\n", + __func__, rc); + goto err_attach; + } + + /* + * Get the scatter-gather list. + * There is no info as this is a write buffer or + * read buffer, hence the request is bi-directional + * to accommodate both read and write mappings. + */ + alloc_data->table = dma_buf_map_attachment(alloc_data->attach, + DMA_BIDIRECTIONAL); + if (IS_ERR(alloc_data->table)) { + rc = PTR_ERR(alloc_data->table); + dev_err(cb_dev, + "%s: Fail to map attachment, rc = %d\n", + __func__, rc); + goto err_map_attach; + } + + /* physical address from mapping */ + *addr = MSM_AUDIO_ION_PHYS_ADDR(alloc_data); + + msm_audio_ion_add_allocation(&msm_audio_ion_data, + alloc_data); + return rc; + +err_map_attach: + dma_buf_detach(alloc_data->dma_buf, + alloc_data->attach); +err_attach: + kfree(alloc_data); + + return rc; +} + +static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf) +{ + int rc = 0; + struct msm_audio_alloc_data *alloc_data = NULL; + struct list_head *ptr, *next; + struct device *cb_dev = msm_audio_ion_data.cb_dev; + bool found = false; + + /* + * Though list_for_each_safe is delete safe, lock + * should be explicitly acquired to avoid race condition + * on adding elements to the list. + */ + mutex_lock(&(msm_audio_ion_data.list_mutex)); + list_for_each_safe(ptr, next, + &(msm_audio_ion_data.alloc_list)) { + + alloc_data = list_entry(ptr, struct msm_audio_alloc_data, + list); + + if (alloc_data->dma_buf == dma_buf) { + found = true; + dma_buf_unmap_attachment(alloc_data->attach, + alloc_data->table, + DMA_BIDIRECTIONAL); + + dma_buf_detach(alloc_data->dma_buf, + alloc_data->attach); + + dma_buf_put(alloc_data->dma_buf); + + list_del(&(alloc_data->list)); + kfree(alloc_data); + break; + } + } + mutex_unlock(&(msm_audio_ion_data.list_mutex)); + + if (!found) { + dev_err(cb_dev, + "%s: cannot find allocation, dma_buf %pK", + __func__, dma_buf); + rc = -EINVAL; + } + + return rc; +} + +static int msm_audio_ion_get_phys(struct dma_buf *dma_buf, + dma_addr_t *addr, size_t *len) +{ + int rc = 0; + + rc = msm_audio_dma_buf_map(dma_buf, addr, len); + if (rc) { + pr_err("%s: failed to map DMA buf, err = %d\n", + __func__, rc); + goto err; + } + /* Append the SMMU SID information to the IOVA address */ + *addr |= msm_audio_ion_data.smmu_sid_bits; + + pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc); +err: + return rc; +} + +static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf) +{ + int i = 0; + int rc = 0; + void *addr = NULL; + unsigned int pg_cnt = 0; + struct msm_audio_alloc_data *alloc_data = NULL; + + rc = dma_buf_begin_cpu_access(dma_buf, DMA_BIDIRECTIONAL); + if (rc) { + pr_err("%s: kmap dma_buf_begin_cpu_access fail\n", __func__); + goto exit; + } + + pg_cnt = dma_buf->size / PAGE_SIZE; + if (dma_buf->size % PAGE_SIZE) + pg_cnt++; + + if (pg_cnt == 0) { + pr_err("%s: Page count is NULL\n", __func__); + goto exit; + } + + /* Map the first page, and store the address to addr */ + addr = dma_buf_kmap(dma_buf, 0); + if (!addr) { + pr_err("%s: mapping kernel buffer failed for page 0\n", + __func__); + goto exit; + } + /* Map remaining pages */ + for (i = 1; i < pg_cnt; i++) { + if (!dma_buf_kmap(dma_buf, i)) { + pr_err("%s: mapping kernel buffer failed for page %d\n", + __func__, i); + goto err; + } + } + + /* + * TBD: remove the below section once new API + * for mapping kernel virtual address is available. + */ + mutex_lock(&(msm_audio_ion_data.list_mutex)); + list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list), + list) { + if (alloc_data->dma_buf == dma_buf) { + alloc_data->vaddr = addr; + break; + } + } + mutex_unlock(&(msm_audio_ion_data.list_mutex)); + + return addr; + +err: + for (; i > 0; i--) + dma_buf_kunmap(dma_buf, i - 1, addr); + addr = NULL; +exit: + return addr; +} + +static void msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf) +{ + int i, rc = 0; + unsigned int pg_cnt = 0; + void *vaddr = NULL; + struct msm_audio_alloc_data *alloc_data = NULL; + struct device *cb_dev = msm_audio_ion_data.cb_dev; + + /* + * TBD: remove the below section once new API + * for unmapping kernel virtual address is available. + */ + mutex_lock(&(msm_audio_ion_data.list_mutex)); + list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list), + list) { + if (alloc_data->dma_buf == dma_buf) { + vaddr = alloc_data->vaddr; + break; + } + } + mutex_unlock(&(msm_audio_ion_data.list_mutex)); + + if (!vaddr) { + dev_err(cb_dev, + "%s: cannot find allocation for dma_buf %pK", + __func__, dma_buf); + goto err; + } + + pg_cnt = dma_buf->size / PAGE_SIZE; + if (dma_buf->size % PAGE_SIZE) + pg_cnt++; + + for (i = 0; i < pg_cnt; i++) + dma_buf_kunmap(dma_buf, i, vaddr); + + rc = dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL); + if (rc) { + dev_err(cb_dev, "%s: kmap dma_buf_end_cpu_access fail\n", + __func__); + goto err; + } + +err: + return; +} + +static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr, + size_t *plen, void *vaddr) +{ + int rc = 0; + + rc = msm_audio_ion_get_phys(dma_buf, paddr, plen); + if (rc) { + pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", + __func__, rc); + goto err; + } + + vaddr = msm_audio_ion_map_kernel(dma_buf); + if (IS_ERR_OR_NULL((void *)vaddr)) { + pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); + rc = -ENOMEM; + goto err; + } + +err: + return rc; +} + /** * msm_audio_ion_alloc - * Allocs ION memory for given client name * - * @name: Name of audio ION client - * @client: ION client to be assigned - * @handle: ION handle to be assigned + * @dma_buf: dma_buf for the ION memory * @bufsz: buffer size * @paddr: Physical address to be assigned with allocated region - * @pa_len: length of allocated region to be assigned + * @plen: length of allocated region to be assigned * vaddr: virtual address to be assigned * * Returns 0 on success or error on failure */ -int msm_audio_ion_alloc(const char *name, struct ion_client **client, - struct ion_handle **handle, size_t bufsz, - ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr) +int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, + dma_addr_t *paddr, size_t *plen, void **vaddr) { int rc = -EINVAL; unsigned long err_ion_ptr = 0; - if ((msm_audio_ion_data.smmu_enabled == true) && - !(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { + if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { pr_debug("%s:probe is not done, deferred\n", __func__); return -EPROBE_DEFER; } - if (!name || !client || !handle || !paddr || !vaddr - || !bufsz || !pa_len) { + if (!dma_buf || !paddr || !vaddr || !bufsz || !plen) { pr_err("%s: Invalid params\n", __func__); return -EINVAL; } - *client = msm_audio_ion_client_create(name); - if (IS_ERR_OR_NULL((void *)(*client))) { - pr_err("%s: ION create client for AUDIO failed\n", __func__); - goto err; - } - *handle = ion_alloc(*client, bufsz, SZ_4K, - ION_HEAP(ION_AUDIO_HEAP_ID), 0); - if (IS_ERR_OR_NULL((void *) (*handle))) { - if (msm_audio_ion_data.smmu_enabled == true) { - pr_debug("system heap is used"); - msm_audio_ion_data.audioheap_enabled = 0; - *handle = ion_alloc(*client, bufsz, SZ_4K, - ION_HEAP(ION_SYSTEM_HEAP_ID), 0); - } - if (IS_ERR_OR_NULL((void *) (*handle))) { - if (IS_ERR((void *)(*handle))) - err_ion_ptr = PTR_ERR((int *)(*handle)); - pr_err("%s:ION alloc fail err ptr=%ld, smmu_enabled=%d\n", - __func__, err_ion_ptr, msm_audio_ion_data.smmu_enabled); - rc = -ENOMEM; - goto err_ion_client; - } - } else { - pr_debug("audio heap is used"); - msm_audio_ion_data.audioheap_enabled = 1; + *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_HEAP_ID), 0); + if (IS_ERR_OR_NULL((void *)(*dma_buf))) { + if (IS_ERR((void *)(*dma_buf))) + err_ion_ptr = PTR_ERR((int *)(*dma_buf)); + pr_err("%s:ION alloc fail err ptr=%ld\n", + __func__, err_ion_ptr); + rc = -ENOMEM; + goto err; } - rc = msm_audio_ion_get_phys(*client, *handle, paddr, pa_len); + rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, *vaddr); if (rc) { - pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", - __func__, rc); - goto err_ion_handle; - } - - *vaddr = ion_map_kernel(*client, *handle); - if (IS_ERR_OR_NULL((void *)*vaddr)) { - pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); - goto err_ion_handle; + pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc); + goto err_dma_buf; } pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, *vaddr, bufsz); - if (bufsz != 0) { - pr_debug("%s: memset to 0 %pK %zd\n", __func__, *vaddr, bufsz); - memset((void *)*vaddr, 0, bufsz); - } + memset((void *)*vaddr, 0, bufsz); return rc; -err_ion_handle: - ion_free(*client, *handle); -err_ion_client: - msm_audio_ion_client_destroy(*client); - *handle = NULL; - *client = NULL; +err_dma_buf: + dma_buf_put(*dma_buf); err: return rc; } EXPORT_SYMBOL(msm_audio_ion_alloc); -int msm_audio_ion_import(const char *name, struct ion_client **client, - struct ion_handle **handle, int fd, +/** + * msm_audio_ion_import- + * Import ION buffer with given file descriptor + * + * @dma_buf: dma_buf for the ION memory + * @fd: file descriptor for the ION memory + * @ionflag: flags associated with ION buffer + * @bufsz: buffer size + * @paddr: Physical address to be assigned with allocated region + * @plen: length of allocated region to be assigned + * vaddr: virtual address to be assigned + * + * Returns 0 on success or error on failure + */ +int msm_audio_ion_import(struct dma_buf **dma_buf, int fd, unsigned long *ionflag, size_t bufsz, - ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr) + dma_addr_t *paddr, size_t *plen, void **vaddr) { int rc = 0; - if ((msm_audio_ion_data.smmu_enabled == true) && - !(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { + if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { pr_debug("%s:probe is not done, deferred\n", __func__); return -EPROBE_DEFER; } - if (!name || !client || !handle || !paddr || !vaddr || !pa_len) { + if (!dma_buf || !paddr || !vaddr || !plen) { pr_err("%s: Invalid params\n", __func__); rc = -EINVAL; goto err; } - *client = msm_audio_ion_client_create(name); - if (IS_ERR_OR_NULL((void *)(*client))) { - pr_err("%s: ION create client for AUDIO failed\n", __func__); + /* bufsz should be 0 and fd shouldn't be 0 as of now */ + *dma_buf = dma_buf_get(fd); + pr_debug("%s: dma_buf =%pK, fd=%d\n", __func__, *dma_buf, fd); + if (IS_ERR_OR_NULL((void *)(*dma_buf))) { + pr_err("%s: dma_buf_get failed\n", __func__); rc = -EINVAL; goto err; } - /* name should be audio_acdb_client or Audio_Dec_Client, - * bufsz should be 0 and fd shouldn't be 0 as of now - */ - *handle = ion_import_dma_buf_fd(*client, fd); - pr_debug("%s: DMA Buf name=%s, fd=%d handle=%pK\n", __func__, - name, fd, *handle); - if (IS_ERR_OR_NULL((void *) (*handle))) { - pr_err("%s: ion import dma buffer failed\n", - __func__); - rc = -EINVAL; - goto err_destroy_client; - } - if (ionflag != NULL) { - rc = ion_handle_get_flags(*client, *handle, ionflag); - if (rc) { - pr_err("%s: could not get flags for the handle\n", - __func__); - goto err_ion_handle; - } + pr_err("%s: could not get flags for the dma_buf\n", + __func__); + rc = -EOPNOTSUPP; + goto err_ion_flag; } - rc = msm_audio_ion_get_phys(*client, *handle, paddr, pa_len); + rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, *vaddr); if (rc) { - pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", - __func__, rc); - goto err_ion_handle; - } - - *vaddr = ion_map_kernel(*client, *handle); - if (IS_ERR_OR_NULL((void *)*vaddr)) { - pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); - rc = -ENOMEM; - goto err_ion_handle; + pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc); + goto err_ion_flag; } pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, *vaddr, bufsz); return 0; -err_ion_handle: - ion_free(*client, *handle); -err_destroy_client: - msm_audio_ion_client_destroy(*client); - *client = NULL; - *handle = NULL; +err_ion_flag: + dma_buf_put(*dma_buf); err: + *dma_buf = NULL; return rc; } +EXPORT_SYMBOL(msm_audio_ion_import); /** * msm_audio_ion_free - * fress ION memory for given client and handle * - * @client: ION client - * @handle: ION handle + * @dma_buf: dma_buf for the ION memory * * Returns 0 on success or error on failure */ -int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle) +int msm_audio_ion_free(struct dma_buf *dma_buf) { - if (!client || !handle) { - pr_err("%s Invalid params\n", __func__); + if (!dma_buf) { + pr_err("%s: dma_buf invalid\n", __func__); return -EINVAL; } - if (msm_audio_ion_data.smmu_enabled) - msm_audio_dma_buf_unmap(client, handle); - ion_unmap_kernel(client, handle); + msm_audio_ion_unmap_kernel(dma_buf); + + msm_audio_dma_buf_unmap(dma_buf); - ion_free(client, handle); - msm_audio_ion_client_destroy(client); return 0; } EXPORT_SYMBOL(msm_audio_ion_free); @@ -287,35 +487,42 @@ EXPORT_SYMBOL(msm_audio_ion_free); * msm_audio_ion_mmap - * Audio ION memory map * - * @ab: audio buf pointer + * @abuff: audio buf pointer * @vma: virtual mem area * * Returns 0 on success or error on failure */ -int msm_audio_ion_mmap(struct audio_buffer *ab, +int msm_audio_ion_mmap(struct audio_buffer *abuff, struct vm_area_struct *vma) { + struct msm_audio_alloc_data *alloc_data = NULL; struct sg_table *table; unsigned long addr = vma->vm_start; unsigned long offset = vma->vm_pgoff * PAGE_SIZE; struct scatterlist *sg; unsigned int i; struct page *page; - int ret; - - pr_debug("%s\n", __func__); + int ret = 0; + bool found = false; + struct device *cb_dev = msm_audio_ion_data.cb_dev; - table = ion_sg_table(ab->client, ab->handle); + mutex_lock(&(msm_audio_ion_data.list_mutex)); + list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list), + list) { + if (alloc_data->dma_buf == abuff->dma_buf) { + found = true; + table = alloc_data->table; + break; + } + } + mutex_unlock(&(msm_audio_ion_data.list_mutex)); - if (IS_ERR(table)) { - pr_err("%s: Unable to get sg_table from ion: %ld\n", - __func__, PTR_ERR(table)); - return PTR_ERR(table); - } else if (!table) { - pr_err("%s: sg_list is NULL\n", __func__); + if (!found) { + dev_err(cb_dev, + "%s: cannot find allocation, dma_buf %pK", + __func__, abuff->dma_buf); return -EINVAL; } - /* uncached */ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); @@ -354,383 +561,29 @@ int msm_audio_ion_mmap(struct audio_buffer *ab, return 0; } } else { - ion_phys_addr_t phys_addr; - size_t phys_len; - size_t va_len = 0; - pr_debug("%s: page is NULL\n", __func__); - ret = ion_phys(ab->client, ab->handle, &phys_addr, &phys_len); - if (ret) { - pr_err("%s: Unable to get phys address from ION buffer: %d\n" - , __func__, ret); - return ret; - } - pr_debug("phys=%pKK len=%zd\n", &phys_addr, phys_len); - pr_debug("vma=%pK, vm_start=%x vm_end=%x vm_pgoff=%ld vm_page_prot=%lu\n", - vma, (unsigned int)vma->vm_start, - (unsigned int)vma->vm_end, vma->vm_pgoff, - (unsigned long)pgprot_val(vma->vm_page_prot)); - va_len = vma->vm_end - vma->vm_start; - if ((offset > phys_len) || (va_len > phys_len-offset)) { - pr_err("wrong offset size %ld, lens= %zd, va_len=%zd\n", - offset, phys_len, va_len); - return -EINVAL; - } - ret = remap_pfn_range(vma, vma->vm_start, - __phys_to_pfn(phys_addr) + vma->vm_pgoff, - vma->vm_end - vma->vm_start, - vma->vm_page_prot); + ret = -EINVAL; } - return 0; -} -EXPORT_SYMBOL(msm_audio_ion_mmap); - -bool msm_audio_ion_is_smmu_available(void) -{ - return msm_audio_ion_data.smmu_enabled; -} - -/* move to static section again */ -struct ion_client *msm_audio_ion_client_create(const char *name) -{ - struct ion_client *pclient = NULL; - - pclient = msm_ion_client_create(name); - return pclient; -} -EXPORT_SYMBOL(msm_audio_ion_client_create); - -/** - * msm_audio_ion_client_destroy - - * Removes ION client handle - * - * @client: ION client - * - */ -void msm_audio_ion_client_destroy(struct ion_client *client) -{ - pr_debug("%s: client = %pK smmu_enabled = %d\n", __func__, - client, msm_audio_ion_data.smmu_enabled); - - ion_client_destroy(client); -} -EXPORT_SYMBOL(msm_audio_ion_client_destroy); - -/** - * msm_audio_ion_import_legacy - - * Alloc ION memory for given size - * - * @name: ION client name - * @client: ION client - * @handle: ION handle to be updated - * @fd: ION fd - * @ionflag: Flags for ION handle - * @bufsz: buffer size - * @paddr: pointer to be updated with physical address of allocated ION memory - * @pa_len: pointer to be updated with size of physical memory - * @vaddr: pointer to be updated with virtual address - * - * Returns 0 on success or error on failure - */ -int msm_audio_ion_import_legacy(const char *name, struct ion_client *client, - struct ion_handle **handle, int fd, - unsigned long *ionflag, size_t bufsz, - ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr) -{ - int rc = 0; - - if (!name || !client || !handle || !paddr || !vaddr || !pa_len) { - pr_err("%s: Invalid params\n", __func__); - rc = -EINVAL; - goto err; - } - /* client is already created for legacy and given - * name should be audio_acdb_client or Audio_Dec_Client, - * bufsz should be 0 and fd shouldn't be 0 as of now - */ - *handle = ion_import_dma_buf_fd(client, fd); - pr_debug("%s: DMA Buf name=%s, fd=%d handle=%pK\n", __func__, - name, fd, *handle); - if (IS_ERR_OR_NULL((void *)(*handle))) { - pr_err("%s: ion import dma buffer failed\n", - __func__); - rc = -EINVAL; - goto err; - } - - if (ionflag != NULL) { - rc = ion_handle_get_flags(client, *handle, ionflag); - if (rc) { - pr_err("%s: could not get flags for the handle\n", - __func__); - rc = -EINVAL; - goto err_ion_handle; - } - } - - rc = msm_audio_ion_get_phys(client, *handle, paddr, pa_len); - if (rc) { - pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", - __func__, rc); - rc = -EINVAL; - goto err_ion_handle; - } - - /*Need to add condition SMMU enable or not */ - *vaddr = ion_map_kernel(client, *handle); - if (IS_ERR_OR_NULL((void *)*vaddr)) { - pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); - rc = -EINVAL; - goto err_ion_handle; - } - - if (bufsz != 0) - memset((void *)*vaddr, 0, bufsz); - - return 0; - -err_ion_handle: - ion_free(client, *handle); -err: - return rc; + return ret; } -EXPORT_SYMBOL(msm_audio_ion_import_legacy); +EXPORT_SYMBOL(msm_audio_ion_mmap); /** - * msm_audio_ion_free_legacy - - * Frees ION memory for given handle + * msm_audio_populate_upper_32_bits - + * retrieve upper 32bits of 64bit address * - * @client: ION client - * @handle: ION handle + * @pa: 64bit physical address * */ -int msm_audio_ion_free_legacy(struct ion_client *client, - struct ion_handle *handle) -{ - if (msm_audio_ion_data.smmu_enabled) - msm_audio_dma_buf_unmap(client, handle); - - ion_unmap_kernel(client, handle); - - ion_free(client, handle); - /* no client_destrody in legacy*/ - return 0; -} -EXPORT_SYMBOL(msm_audio_ion_free_legacy); - -int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op) -{ - unsigned long ionflag = 0; - int rc = 0; - int msm_cache_ops = 0; - - if (!abuff) { - pr_err("%s: Invalid params: %pK\n", __func__, abuff); - return -EINVAL; - } - rc = ion_handle_get_flags(abuff->client, abuff->handle, - &ionflag); - if (rc) { - pr_err("ion_handle_get_flags failed: %d\n", rc); - goto cache_op_failed; - } - - /* has to be CACHED */ - if (ION_IS_CACHED(ionflag)) { - /* ION_IOC_INV_CACHES or ION_IOC_CLEAN_CACHES */ - msm_cache_ops = cache_op; - rc = msm_ion_do_cache_op(abuff->client, - abuff->handle, - (unsigned long *) abuff->data, - (unsigned long)abuff->size, - msm_cache_ops); - if (rc) { - pr_err("cache operation failed %d\n", rc); - goto cache_op_failed; - } - } -cache_op_failed: - return rc; -} - - -static int msm_audio_dma_buf_map(struct ion_client *client, - struct ion_handle *handle, - ion_phys_addr_t *addr, size_t *len) +u32 msm_audio_populate_upper_32_bits(dma_addr_t pa) { - - struct msm_audio_alloc_data *alloc_data; - struct device *cb_dev; - int rc = 0; - - cb_dev = msm_audio_ion_data.cb_dev; - - /* Data required per buffer mapping */ - alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL); - if (!alloc_data) - return -ENOMEM; - - /* Get the ION handle size */ - ion_handle_get_size(client, handle, len); - - alloc_data->client = client; - alloc_data->handle = handle; - alloc_data->len = *len; - - /* Get the dma_buf handle from ion_handle */ - alloc_data->dma_buf = ion_share_dma_buf(client, handle); - if (IS_ERR(alloc_data->dma_buf)) { - rc = PTR_ERR(alloc_data->dma_buf); - dev_err(cb_dev, - "%s: Fail to get dma_buf handle, rc = %d\n", - __func__, rc); - goto err_dma_buf; - } - - /* Attach the dma_buf to context bank device */ - alloc_data->attach = dma_buf_attach(alloc_data->dma_buf, - cb_dev); - if (IS_ERR(alloc_data->attach)) { - rc = PTR_ERR(alloc_data->attach); - dev_err(cb_dev, - "%s: Fail to attach dma_buf to CB, rc = %d\n", - __func__, rc); - goto err_attach; - } - - /* - * Get the scatter-gather list. - * There is no info as this is a write buffer or - * read buffer, hence the request is bi-directional - * to accommodate both read and write mappings. - */ - alloc_data->table = dma_buf_map_attachment(alloc_data->attach, - DMA_BIDIRECTIONAL); - if (IS_ERR(alloc_data->table)) { - rc = PTR_ERR(alloc_data->table); - dev_err(cb_dev, - "%s: Fail to map attachment, rc = %d\n", - __func__, rc); - goto err_map_attach; - } - - rc = dma_map_sg(cb_dev, alloc_data->table->sgl, - alloc_data->table->nents, - DMA_BIDIRECTIONAL); - if (rc != alloc_data->table->nents) { - dev_err(cb_dev, - "%s: Fail to map SG, rc = %d, nents = %d\n", - __func__, rc, alloc_data->table->nents); - goto err_map_sg; - } - /* Make sure not to return rc from dma_map_sg, as it can be nonzero */ - rc = 0; - - /* physical address from mapping */ - *addr = MSM_AUDIO_ION_PHYS_ADDR(alloc_data); - - msm_audio_ion_add_allocation(&msm_audio_ion_data, - alloc_data); - return rc; - -err_map_sg: - dma_buf_unmap_attachment(alloc_data->attach, - alloc_data->table, - DMA_BIDIRECTIONAL); -err_map_attach: - dma_buf_detach(alloc_data->dma_buf, - alloc_data->attach); -err_attach: - dma_buf_put(alloc_data->dma_buf); - -err_dma_buf: - kfree(alloc_data); - - return rc; -} - -static int msm_audio_dma_buf_unmap(struct ion_client *client, - struct ion_handle *handle) -{ - int rc = 0; - struct msm_audio_alloc_data *alloc_data = NULL; - struct list_head *ptr, *next; - struct device *cb_dev = msm_audio_ion_data.cb_dev; - bool found = false; - - /* - * Though list_for_each_safe is delete safe, lock - * should be explicitly acquired to avoid race condition - * on adding elements to the list. - */ - mutex_lock(&(msm_audio_ion_data.list_mutex)); - list_for_each_safe(ptr, next, - &(msm_audio_ion_data.alloc_list)) { - - alloc_data = list_entry(ptr, struct msm_audio_alloc_data, - list); - - if (alloc_data->handle == handle && - alloc_data->client == client) { - found = true; - dma_unmap_sg(cb_dev, - alloc_data->table->sgl, - alloc_data->table->nents, - DMA_BIDIRECTIONAL); - - dma_buf_unmap_attachment(alloc_data->attach, - alloc_data->table, - DMA_BIDIRECTIONAL); - - dma_buf_detach(alloc_data->dma_buf, - alloc_data->attach); - - dma_buf_put(alloc_data->dma_buf); - - list_del(&(alloc_data->list)); - kfree(alloc_data); - break; - } - } - mutex_unlock(&(msm_audio_ion_data.list_mutex)); - - if (!found) { - dev_err(cb_dev, - "%s: cannot find allocation, ion_handle %pK, ion_client %pK", - __func__, handle, client); - rc = -EINVAL; - } - - return rc; -} - -static int msm_audio_ion_get_phys(struct ion_client *client, - struct ion_handle *handle, - ion_phys_addr_t *addr, size_t *len) -{ - int rc = 0; - - pr_debug("%s: smmu_enabled = %d\n", __func__, - msm_audio_ion_data.smmu_enabled); - - if (msm_audio_ion_data.smmu_enabled) { - rc = msm_audio_dma_buf_map(client, handle, addr, len); - if (rc) { - pr_err("%s: failed to map DMA buf, err = %d\n", - __func__, rc); - goto err; - } - /* Append the SMMU SID information to the IOVA address */ - *addr |= msm_audio_ion_data.smmu_sid_bits; - } else { - rc = ion_phys(client, handle, addr, len); - } - - pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc); -err: - return rc; + if (sizeof(dma_addr_t) == sizeof(u32)) + return upper_32_bits(msm_audio_ion_data.smmu_sid_bits); + else + return upper_32_bits(pa); } +EXPORT_SYMBOL(msm_audio_populate_upper_32_bits); static int msm_audio_smmu_init(struct device *dev) { @@ -768,115 +621,75 @@ static const struct of_device_id msm_audio_ion_dt_match[] = { }; MODULE_DEVICE_TABLE(of, msm_audio_ion_dt_match); - -u32 msm_audio_ion_get_smmu_sid_mode32(void) -{ - if (msm_audio_ion_data.smmu_enabled) - return upper_32_bits(msm_audio_ion_data.smmu_sid_bits); - else - return 0; -} - -/** - * msm_audio_populate_upper_32_bits - - * retrieve upper 32bits of 64bit address - * - * @pa: 64bit physical address - * - */ -u32 msm_audio_populate_upper_32_bits(ion_phys_addr_t pa) -{ - if (sizeof(ion_phys_addr_t) == sizeof(u32)) - return msm_audio_ion_get_smmu_sid_mode32(); - else - return upper_32_bits(pa); -} -EXPORT_SYMBOL(msm_audio_populate_upper_32_bits); - static int msm_audio_ion_probe(struct platform_device *pdev) { int rc = 0; - const char *msm_audio_ion_dt = "qcom,smmu-enabled"; const char *msm_audio_ion_smmu = "qcom,smmu-version"; const char *msm_audio_ion_smmu_sid_mask = "qcom,smmu-sid-mask"; - bool smmu_enabled; enum apr_subsys_state q6_state; struct device *dev = &pdev->dev; + u64 smmu_sid = 0; + u64 smmu_sid_mask = 0; + struct of_phandle_args iommuspec; if (dev->of_node == NULL) { dev_err(dev, "%s: device tree is not found\n", __func__); - msm_audio_ion_data.smmu_enabled = 0; return 0; } - smmu_enabled = of_property_read_bool(dev->of_node, - msm_audio_ion_dt); - msm_audio_ion_data.smmu_enabled = smmu_enabled; + rc = of_property_read_u32(dev->of_node, + msm_audio_ion_smmu, + &msm_audio_ion_data.smmu_version); + if (rc) { + dev_err(dev, + "%s: qcom,smmu_version missing in DT node\n", + __func__); + return rc; + } + dev_dbg(dev, "%s: SMMU version is (%d)", __func__, + msm_audio_ion_data.smmu_version); + q6_state = apr_get_q6_state(); + if (q6_state == APR_SUBSYS_DOWN) { + dev_dbg(dev, + "defering %s, adsp_state %d\n", + __func__, q6_state); + return -EPROBE_DEFER; + } + dev_dbg(dev, "%s: adsp is ready\n", __func__); - if (smmu_enabled) { - rc = of_property_read_u32(dev->of_node, - msm_audio_ion_smmu, - &msm_audio_ion_data.smmu_version); - if (rc) { - dev_err(dev, - "%s: qcom,smmu_version missing in DT node\n", - __func__); - return rc; - } - dev_dbg(dev, "%s: SMMU version is (%d)", __func__, - msm_audio_ion_data.smmu_version); - q6_state = apr_get_q6_state(); - if (q6_state == APR_SUBSYS_DOWN) { - dev_dbg(dev, - "defering %s, adsp_state %d\n", - __func__, q6_state); - return -EPROBE_DEFER; - } - dev_dbg(dev, "%s: adsp is ready\n", __func__); - } - - dev_dbg(dev, "%s: SMMU is %s\n", __func__, - (smmu_enabled) ? "Enabled" : "Disabled"); - - if (smmu_enabled) { - u64 smmu_sid = 0; - u64 smmu_sid_mask = 0; - struct of_phandle_args iommuspec; - - /* Get SMMU SID information from Devicetree */ - rc = of_property_read_u64(dev->of_node, - msm_audio_ion_smmu_sid_mask, - &smmu_sid_mask); - if (rc) { - dev_err(dev, - "%s: qcom,smmu-sid-mask missing in DT node, using default\n", - __func__); - smmu_sid_mask = 0xFFFFFFFFFFFFFFFF; - } - rc = of_parse_phandle_with_args(dev->of_node, "iommus", - "#iommu-cells", 0, &iommuspec); - if (rc) - dev_err(dev, "%s: could not get smmu SID, ret = %d\n", - __func__, rc); - else - smmu_sid = (iommuspec.args[0] & smmu_sid_mask); - - msm_audio_ion_data.smmu_sid_bits = - smmu_sid << MSM_AUDIO_SMMU_SID_OFFSET; - - if (msm_audio_ion_data.smmu_version == 0x2) { - rc = msm_audio_smmu_init(dev); - } else { - dev_err(dev, "%s: smmu version invalid %d\n", - __func__, msm_audio_ion_data.smmu_version); - rc = -EINVAL; - } - if (rc) - dev_err(dev, "%s: smmu init failed, err = %d\n", - __func__, rc); + /* Get SMMU SID information from Devicetree */ + rc = of_property_read_u64(dev->of_node, + msm_audio_ion_smmu_sid_mask, + &smmu_sid_mask); + if (rc) { + dev_err(dev, + "%s: qcom,smmu-sid-mask missing in DT node, using default\n", + __func__); + smmu_sid_mask = 0xFFFFFFFFFFFFFFFF; } + rc = of_parse_phandle_with_args(dev->of_node, "iommus", + "#iommu-cells", 0, &iommuspec); + if (rc) + dev_err(dev, "%s: could not get smmu SID, ret = %d\n", + __func__, rc); + else + smmu_sid = (iommuspec.args[0] & smmu_sid_mask); + + msm_audio_ion_data.smmu_sid_bits = + smmu_sid << MSM_AUDIO_SMMU_SID_OFFSET; + + if (msm_audio_ion_data.smmu_version == 0x2) { + rc = msm_audio_smmu_init(dev); + } else { + dev_err(dev, "%s: smmu version invalid %d\n", + __func__, msm_audio_ion_data.smmu_version); + rc = -EINVAL; + } + if (rc) + dev_err(dev, "%s: smmu init failed, err = %d\n", + __func__, rc); if (!rc) msm_audio_ion_data.device_status |= MSM_AUDIO_ION_PROBED; @@ -897,7 +710,6 @@ static int msm_audio_ion_remove(struct platform_device *pdev) arm_iommu_release_mapping(mapping); } - msm_audio_ion_data.smmu_enabled = 0; msm_audio_ion_data.device_status = 0; return 0; } diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 514af254db99..c5dd85c7cda0 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -74,8 +74,7 @@ struct adm_copp { }; struct source_tracking_data { - struct ion_client *ion_client; - struct ion_handle *ion_handle; + struct dma_buf *dma_buf; struct param_outband memmap; int apr_cmd_status; }; @@ -1501,10 +1500,8 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) */ if (this_adm.sourceTrackingData.memmap.paddr != 0) { msm_audio_ion_free( - this_adm.sourceTrackingData.ion_client, - this_adm.sourceTrackingData.ion_handle); - this_adm.sourceTrackingData.ion_client = NULL; - this_adm.sourceTrackingData.ion_handle = NULL; + this_adm.sourceTrackingData.dma_buf); + this_adm.sourceTrackingData.dma_buf = NULL; this_adm.sourceTrackingData.memmap.size = 0; this_adm.sourceTrackingData.memmap.kvaddr = NULL; @@ -1919,7 +1916,7 @@ static int remap_cal_data(struct cal_block_data *cal_block, int cal_index) { int ret = 0; - if (cal_block->map_data.ion_client == NULL) { + if (cal_block->map_data.dma_buf == NULL) { pr_err("%s: No ION allocation for cal index %d!\n", __func__, cal_index); ret = -EINVAL; @@ -3223,10 +3220,8 @@ int adm_close(int port_id, int perf_mode, int copp_idx) __func__, ret); } msm_audio_ion_free( - this_adm.sourceTrackingData.ion_client, - this_adm.sourceTrackingData.ion_handle); - this_adm.sourceTrackingData.ion_client = NULL; - this_adm.sourceTrackingData.ion_handle = NULL; + this_adm.sourceTrackingData.dma_buf); + this_adm.sourceTrackingData.dma_buf = NULL; this_adm.sourceTrackingData.memmap.size = 0; this_adm.sourceTrackingData.memmap.kvaddr = NULL; this_adm.sourceTrackingData.memmap.paddr = 0; @@ -5033,9 +5028,7 @@ static int adm_source_tracking_alloc_map_memory(void) pr_debug("%s: Enter\n", __func__); - ret = msm_audio_ion_alloc("SOURCE_TRACKING", - &this_adm.sourceTrackingData.ion_client, - &this_adm.sourceTrackingData.ion_handle, + ret = msm_audio_ion_alloc(&this_adm.sourceTrackingData.dma_buf, AUD_PROC_BLOCK_SIZE, &this_adm.sourceTrackingData.memmap.paddr, &this_adm.sourceTrackingData.memmap.size, @@ -5058,10 +5051,8 @@ static int adm_source_tracking_alloc_map_memory(void) (void *)this_adm.sourceTrackingData.memmap.paddr, (uint32_t)this_adm.sourceTrackingData.memmap.size); - msm_audio_ion_free(this_adm.sourceTrackingData.ion_client, - this_adm.sourceTrackingData.ion_handle); - this_adm.sourceTrackingData.ion_client = NULL; - this_adm.sourceTrackingData.ion_handle = NULL; + msm_audio_ion_free(this_adm.sourceTrackingData.dma_buf); + this_adm.sourceTrackingData.dma_buf = NULL; this_adm.sourceTrackingData.memmap.size = 0; this_adm.sourceTrackingData.memmap.kvaddr = NULL; this_adm.sourceTrackingData.memmap.paddr = 0; @@ -5263,8 +5254,7 @@ int __init adm_init(void) if (adm_init_cal_data()) pr_err("%s: could not init cal data!\n", __func__); - this_adm.sourceTrackingData.ion_client = NULL; - this_adm.sourceTrackingData.ion_handle = NULL; + this_adm.sourceTrackingData.dma_buf = NULL; this_adm.sourceTrackingData.memmap.size = 0; this_adm.sourceTrackingData.memmap.kvaddr = NULL; this_adm.sourceTrackingData.memmap.paddr = 0; diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 391a7f776551..f926efbdc16b 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1515,7 +1515,7 @@ static int remap_cal_data(struct cal_block_data *cal_block, int cal_index) { int ret = 0; - if (cal_block->map_data.ion_client == NULL) { + if (cal_block->map_data.dma_buf == NULL) { pr_err("%s: No ION allocation for cal index %d!\n", __func__, cal_index); ret = -EINVAL; @@ -4502,8 +4502,8 @@ int q6afe_audio_client_buf_alloc_contiguous(unsigned int dir, ac->port[dir].buf = buf; - rc = msm_audio_ion_alloc("afe_client", &buf[0].client, - &buf[0].handle, bufsz*bufcnt, + rc = msm_audio_ion_alloc(&buf[0].dma_buf, + bufsz * bufcnt, &buf[0].phys, &len, &buf[0].data); if (rc) { @@ -4777,16 +4777,13 @@ int q6afe_audio_client_buf_free_contiguous(unsigned int dir, cnt = port->max_buf_cnt - 1; if (port->buf[0].data) { - pr_debug("%s: data[%pK]phys[%pK][%pK] , client[%pK] handle[%pK]\n", + pr_debug("%s: data[%pK], phys[%pK], dma_buf[%pK]\n", __func__, port->buf[0].data, &port->buf[0].phys, - &port->buf[0].phys, - port->buf[0].client, - port->buf[0].handle); - msm_audio_ion_free(port->buf[0].client, port->buf[0].handle); - port->buf[0].client = NULL; - port->buf[0].handle = NULL; + port->buf[0].dma_buf); + msm_audio_ion_free(port->buf[0].dma_buf); + port->buf[0].dma_buf = NULL; } while (cnt >= 0) { diff --git a/dsp/q6asm.c b/dsp/q6asm.c index caf7df1dce6f..4f61fbec5df2 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * Author: Brian Swetland * * This software is licensed under the terms of the GNU General Public @@ -661,7 +661,7 @@ static int remap_cal_data(int32_t cal_type, struct cal_block_data *cal_block) { int ret = 0; - if (cal_block->map_data.ion_client == NULL) { + if (cal_block->map_data.dma_buf == NULL) { pr_err("%s: No ION allocation for cal type %d!\n", __func__, cal_type); ret = -EINVAL; @@ -982,11 +982,9 @@ int q6asm_audio_client_buf_free(unsigned int dir, if (port->buf[cnt].data) { if (!rc || atomic_read(&ac->reset)) msm_audio_ion_free( - port->buf[cnt].client, - port->buf[cnt].handle); + port->buf[cnt].dma_buf); - port->buf[cnt].client = NULL; - port->buf[cnt].handle = NULL; + port->buf[cnt].dma_buf = NULL; port->buf[cnt].data = NULL; port->buf[cnt].phys = 0; --(port->max_buf_cnt); @@ -1033,18 +1031,14 @@ int q6asm_audio_client_buf_free_contiguous(unsigned int dir, } if (port->buf[0].data) { - pr_debug("%s: data[%pK]phys[%pK][%pK] , client[%pK] handle[%pK]\n", + pr_debug("%s: data[%pK], phys[%pK], dma_buf[%pK]\n", __func__, port->buf[0].data, &port->buf[0].phys, - &port->buf[0].phys, - port->buf[0].client, - port->buf[0].handle); + port->buf[0].dma_buf); if (!rc || atomic_read(&ac->reset)) - msm_audio_ion_free(port->buf[0].client, - port->buf[0].handle); - port->buf[0].client = NULL; - port->buf[0].handle = NULL; + msm_audio_ion_free(port->buf[0].dma_buf); + port->buf[0].dma_buf = NULL; } while (cnt >= 0) { @@ -1438,10 +1432,10 @@ int q6asm_audio_client_buf_alloc(unsigned int dir, while (cnt < bufcnt) { if (bufsz > 0) { if (!buf[cnt].data) { - rc = msm_audio_ion_alloc("asm_client", - &buf[cnt].client, &buf[cnt].handle, + rc = msm_audio_ion_alloc( + &buf[cnt].dma_buf, bufsz, - (ion_phys_addr_t *)&buf[cnt].phys, + &buf[cnt].phys, &len, &buf[cnt].data); if (rc) { @@ -1544,9 +1538,9 @@ int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir, /* The size to allocate should be multiple of 4K bytes */ bytes_to_alloc = PAGE_ALIGN(bytes_to_alloc); - rc = msm_audio_ion_alloc("asm_client", &buf[0].client, &buf[0].handle, + rc = msm_audio_ion_alloc(&buf[0].dma_buf, bytes_to_alloc, - (ion_phys_addr_t *)&buf[0].phys, &len, + &buf[0].phys, &len, &buf[0].data); if (rc) { pr_err("%s: Audio ION alloc is failed, rc = %d\n", @@ -3615,9 +3609,9 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac, bytes_to_alloc = bufsz * bufcnt; bytes_to_alloc = PAGE_ALIGN(bytes_to_alloc); - rc = msm_audio_ion_alloc("audio_client", &buf_circ->client, - &buf_circ->handle, bytes_to_alloc, - (ion_phys_addr_t *)&buf_circ->phys, + rc = msm_audio_ion_alloc(&buf_circ->dma_buf, + bytes_to_alloc, + &buf_circ->phys, &len, &buf_circ->data); if (rc) { @@ -3669,9 +3663,9 @@ int q6asm_set_shared_pos_buff(struct audio_client *ac, bytes_to_alloc = PAGE_ALIGN(bytes_to_alloc); - rc = msm_audio_ion_alloc("audio_client", &buf_pos->client, - &buf_pos->handle, bytes_to_alloc, - (ion_phys_addr_t *)&buf_pos->phys, &len, + rc = msm_audio_ion_alloc(&buf_pos->dma_buf, + bytes_to_alloc, + &buf_pos->phys, &len, &buf_pos->data); if (rc) { @@ -3900,18 +3894,15 @@ int q6asm_shared_io_free(struct audio_client *ac, int dir) port = &ac->port[dir]; mutex_lock(&ac->cmd_lock); if (port->buf && port->buf->data) { - msm_audio_ion_free(port->buf->client, port->buf->handle); - port->buf->client = NULL; - port->buf->handle = NULL; + msm_audio_ion_free(port->buf->dma_buf); + port->buf->dma_buf = NULL; port->max_buf_cnt = 0; kfree(port->buf); port->buf = NULL; } if (ac->shared_pos_buf.data) { - msm_audio_ion_free(ac->shared_pos_buf.client, - ac->shared_pos_buf.handle); - ac->shared_pos_buf.client = NULL; - ac->shared_pos_buf.handle = NULL; + msm_audio_ion_free(ac->shared_pos_buf.dma_buf); + ac->shared_pos_buf.dma_buf = NULL; } mutex_unlock(&ac->cmd_lock); return 0; @@ -7764,9 +7755,8 @@ EXPORT_SYMBOL(q6asm_set_aptx_dec_bt_addr); */ int q6asm_send_ion_fd(struct audio_client *ac, int fd) { - struct ion_client *client; - struct ion_handle *handle; - ion_phys_addr_t paddr; + struct dma_buf *dma_buf; + dma_addr_t paddr; size_t pa_len = 0; void *vaddr; int ret; @@ -7784,9 +7774,7 @@ int q6asm_send_ion_fd(struct audio_client *ac, int fd) goto fail_cmd; } - ret = msm_audio_ion_import("audio_mem_client", - &client, - &handle, + ret = msm_audio_ion_import(&dma_buf, fd, NULL, 0, diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 2a98dc719965..0dd6dbddce23 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018, Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1413,10 +1413,8 @@ int q6lsm_snd_model_buf_free(struct lsm_client *client) __func__, rc); if (client->sound_model.data) { - msm_audio_ion_free(client->sound_model.client, - client->sound_model.handle); - client->sound_model.client = NULL; - client->sound_model.handle = NULL; + msm_audio_ion_free(client->sound_model.dma_buf); + client->sound_model.dma_buf = NULL; client->sound_model.data = NULL; client->sound_model.phys = 0; client->lsm_cal_phy_addr = 0; @@ -1594,9 +1592,7 @@ int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len, cal_block->cal_data.size); pr_debug("%s: Pad zeros sound model %zd Total mem %zd\n", __func__, pad_zero, total_mem); - rc = msm_audio_ion_alloc("lsm_client", - &client->sound_model.client, - &client->sound_model.handle, + rc = msm_audio_ion_alloc(&client->sound_model.dma_buf, total_mem, &client->sound_model.phys, &len, @@ -2138,9 +2134,7 @@ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc) client->hw_params.period_count); return -ENOMEM; } - ret = msm_audio_ion_alloc("lsm_lab", - &client->lab_buffer[0].client, - &client->lab_buffer[0].handle, + ret = msm_audio_ion_alloc(&client->lab_buffer[0].dma_buf, allocate_size, &client->lab_buffer[0].phys, &len, &client->lab_buffer[0].data); @@ -2155,8 +2149,7 @@ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc) pr_err("%s: memory map filed ret %d size %zd\n", __func__, ret, len); msm_audio_ion_free( - client->lab_buffer[0].client, - client->lab_buffer[0].handle); + client->lab_buffer[0].dma_buf); } } if (ret) { @@ -2187,9 +2180,7 @@ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc) ret = q6lsm_memory_unmap_regions(client, client->lab_buffer[0].mem_map_handle); if (!ret) - msm_audio_ion_free( - client->lab_buffer[0].client, - client->lab_buffer[0].handle); + msm_audio_ion_free(client->lab_buffer[0].dma_buf); else pr_err("%s: unmap failed not freeing memory\n", __func__); diff --git a/dsp/q6usm.c b/dsp/q6usm.c index 1ed74a9c2b1d..3c335a841995 100644 --- a/dsp/q6usm.c +++ b/dsp/q6usm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -209,14 +209,13 @@ static int q6usm_us_client_buf_free(unsigned int dir, pr_debug("%s: data[%pK]phys[%llx][%pK]\n", __func__, (void *)port->data, (u64)port->phys, (void *)&port->phys); - msm_audio_ion_free(port->client, port->handle); + msm_audio_ion_free(port->dma_buf); port->data = NULL; port->phys = 0; port->buf_size = 0; port->buf_cnt = 0; - port->client = NULL; - port->handle = NULL; + port->dma_buf = NULL; mutex_unlock(&usc->cmd_lock); return rc; @@ -250,13 +249,12 @@ int q6usm_us_param_buf_free(unsigned int dir, (void *)port->param_buf, (u64)port->param_phys, (void *)&port->param_phys); - msm_audio_ion_free(port->param_client, port->param_handle); + msm_audio_ion_free(port->param_dma_buf); port->param_buf = NULL; port->param_phys = 0; port->param_buf_size = 0; - port->param_client = NULL; - port->param_handle = NULL; + port->param_dma_buf = NULL; mutex_unlock(&usc->cmd_lock); return rc; @@ -398,8 +396,7 @@ int q6usm_us_client_buf_alloc(unsigned int dir, /* The size to allocate should be multiple of 4K bytes */ size = PAGE_ALIGN(size); - rc = msm_audio_ion_alloc("ultrasound_client", - &port->client, &port->handle, + rc = msm_audio_ion_alloc(&port->dma_buf, size, &port->phys, &len, &port->data); @@ -464,8 +461,7 @@ int q6usm_us_param_buf_alloc(unsigned int dir, /* The size to allocate should be multiple of 4K bytes */ size = PAGE_ALIGN(size); - rc = msm_audio_ion_alloc("ultrasound_client", - &port->param_client, &port->param_handle, + rc = msm_audio_ion_alloc(&port->param_dma_buf, size, &port->param_phys, &len, &port->param_buf); @@ -725,8 +721,7 @@ uint32_t q6usm_get_virtual_address(int dir, ab.used = 1; ab.size = size; ab.actual_size = size; - ab.handle = port->handle; - ab.client = port->client; + ab.dma_buf = port->dma_buf; ret = msm_audio_ion_mmap(&ab, vms); diff --git a/dsp/q6usm.h b/dsp/q6usm.h index fa2cd627c91d..ba4f9a9a84a7 100644 --- a/dsp/q6usm.h +++ b/dsp/q6usm.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -63,10 +63,8 @@ struct us_port_data { /* read or write locks */ struct mutex lock; spinlock_t dsp_lock; - /* ION memory handle */ - struct ion_handle *handle; - /* ION memory client */ - struct ion_client *client; + /* ION dma_buf memory */ + struct dma_buf *dma_buf; /* extended parameters, related to q6 variants */ void *ext; /* physical address of parameter buffer */ @@ -77,10 +75,8 @@ struct us_port_data { uint32_t param_buf_size; /* parameter buffer memory handle */ void *param_buf_mem_handle; - /* ION memory handle for parameter buffer */ - struct ion_handle *param_handle; - /* ION memory client for parameter buffer */ - struct ion_client *param_client; + /* ION dma_buf memory for parameter buffer */ + struct dma_buf *param_dma_buf; }; struct us_client { diff --git a/dsp/q6voice.c b/dsp/q6voice.c index d5f280e3b0af..e26d156b57d3 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1944,8 +1944,7 @@ static int is_cal_memory_allocated(void) { bool ret; - if (common.cal_mem_map_table.client != NULL && - common.cal_mem_map_table.handle != NULL) + if (common.cal_mem_map_table.dma_buf != NULL) ret = true; else ret = false; @@ -1958,18 +1957,15 @@ static int free_cal_map_table(void) { int ret = 0; - if ((common.cal_mem_map_table.client == NULL) || - (common.cal_mem_map_table.handle == NULL)) + if (common.cal_mem_map_table.dma_buf == NULL) goto done; - ret = msm_audio_ion_free(common.cal_mem_map_table.client, - common.cal_mem_map_table.handle); + ret = msm_audio_ion_free(common.cal_mem_map_table.dma_buf); if (ret < 0) pr_err("%s: msm_audio_ion_free failed:\n", __func__); done: - common.cal_mem_map_table.client = NULL; - common.cal_mem_map_table.handle = NULL; + common.cal_mem_map_table.dma_buf = NULL; return ret; } @@ -1977,8 +1973,7 @@ static int is_rtac_memory_allocated(void) { bool ret; - if (common.rtac_mem_map_table.client != NULL && - common.rtac_mem_map_table.handle != NULL) + if (common.rtac_mem_map_table.dma_buf != NULL) ret = true; else ret = false; @@ -1990,18 +1985,15 @@ static int free_rtac_map_table(void) { int ret = 0; - if ((common.rtac_mem_map_table.client == NULL) || - (common.rtac_mem_map_table.handle == NULL)) + if (common.rtac_mem_map_table.dma_buf == NULL) goto done; - ret = msm_audio_ion_free(common.rtac_mem_map_table.client, - common.rtac_mem_map_table.handle); + ret = msm_audio_ion_free(common.rtac_mem_map_table.dma_buf); if (ret < 0) pr_err("%s: msm_audio_ion_free failed:\n", __func__); done: - common.rtac_mem_map_table.client = NULL; - common.rtac_mem_map_table.handle = NULL; + common.rtac_mem_map_table.dma_buf = NULL; return ret; } @@ -2021,8 +2013,7 @@ static int is_voip_memory_allocated(void) } mutex_lock(&common.common_lock); - if (v->shmem_info.sh_buf.client != NULL && - v->shmem_info.sh_buf.handle != NULL) + if (v->shmem_info.sh_buf.dma_buf != NULL) ret = true; else ret = false; @@ -3575,7 +3566,7 @@ static int remap_cal_data(struct cal_block_data *cal_block, pr_debug("%s\n", __func__); - if (cal_block->map_data.ion_client == NULL) { + if (cal_block->map_data.dma_buf == NULL) { pr_err("%s: No ION allocation for session_id %d!\n", __func__, session_id); ret = -EINVAL; @@ -7257,12 +7248,9 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) /* Free the ION memory and clear handles for Source Tracking */ if (is_source_tracking_shared_memomry_allocated()) { msm_audio_ion_free( - common.source_tracking_sh_mem.sh_mem_block.client, - common.source_tracking_sh_mem.sh_mem_block.handle); + common.source_tracking_sh_mem.sh_mem_block.dma_buf); common.source_tracking_sh_mem.mem_handle = 0; - common.source_tracking_sh_mem.sh_mem_block.client = - NULL; - common.source_tracking_sh_mem.sh_mem_block.handle = + common.source_tracking_sh_mem.sh_mem_block.dma_buf = NULL; } /* clean up srvcc rec flag */ @@ -7465,12 +7453,9 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv) /* Free the ION memory and clear handles for Source Tracking */ if (is_source_tracking_shared_memomry_allocated()) { msm_audio_ion_free( - common.source_tracking_sh_mem.sh_mem_block.client, - common.source_tracking_sh_mem.sh_mem_block.handle); + common.source_tracking_sh_mem.sh_mem_block.dma_buf); common.source_tracking_sh_mem.mem_handle = 0; - common.source_tracking_sh_mem.sh_mem_block.client = - NULL; - common.source_tracking_sh_mem.sh_mem_block.handle = + common.source_tracking_sh_mem.sh_mem_block.dma_buf = NULL; } voc_set_error_state(data->reset_proc); @@ -7743,12 +7728,9 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv) */ if (is_source_tracking_shared_memomry_allocated()) { msm_audio_ion_free( - common.source_tracking_sh_mem.sh_mem_block.client, - common.source_tracking_sh_mem.sh_mem_block.handle); + common.source_tracking_sh_mem.sh_mem_block.dma_buf); common.source_tracking_sh_mem.mem_handle = 0; - common.source_tracking_sh_mem.sh_mem_block.client = - NULL; - common.source_tracking_sh_mem.sh_mem_block.handle = + common.source_tracking_sh_mem.sh_mem_block.dma_buf = NULL; } voc_set_error_state(data->reset_proc); @@ -7958,10 +7940,8 @@ static int voice_free_oob_shared_mem(void) goto done; } - rc = msm_audio_ion_free(v->shmem_info.sh_buf.client, - v->shmem_info.sh_buf.handle); - v->shmem_info.sh_buf.client = NULL; - v->shmem_info.sh_buf.handle = NULL; + rc = msm_audio_ion_free(v->shmem_info.sh_buf.dma_buf); + v->shmem_info.sh_buf.dma_buf = NULL; if (rc < 0) { pr_err("%s: Error:%d freeing memory\n", __func__, rc); @@ -7975,8 +7955,7 @@ static int voice_free_oob_shared_mem(void) cnt++; } - v->shmem_info.sh_buf.client = NULL; - v->shmem_info.sh_buf.handle = NULL; + v->shmem_info.sh_buf.dma_buf = NULL; done: mutex_unlock(&common.common_lock); @@ -8003,9 +7982,8 @@ static int voice_alloc_oob_shared_mem(void) goto done; } - rc = msm_audio_ion_alloc("voip_client", &(v->shmem_info.sh_buf.client), - &(v->shmem_info.sh_buf.handle), - bufsz*bufcnt, + rc = msm_audio_ion_alloc(&(v->shmem_info.sh_buf.dma_buf), + bufsz * bufcnt, &phys, &len, &mem_addr); if (rc < 0) { @@ -8055,8 +8033,7 @@ static int voice_alloc_oob_mem_table(void) goto done; } - rc = msm_audio_ion_alloc("voip_client", &(v->shmem_info.memtbl.client), - &(v->shmem_info.memtbl.handle), + rc = msm_audio_ion_alloc(&(v->shmem_info.memtbl.dma_buf), sizeof(struct vss_imemory_table_t), &v->shmem_info.memtbl.phys, &len, @@ -8442,9 +8419,7 @@ static int voice_alloc_cal_mem_map_table(void) int ret = 0; size_t len; - ret = msm_audio_ion_alloc("voc_cal", - &(common.cal_mem_map_table.client), - &(common.cal_mem_map_table.handle), + ret = msm_audio_ion_alloc(&(common.cal_mem_map_table.dma_buf), sizeof(struct vss_imemory_table_t), &common.cal_mem_map_table.phys, &len, @@ -8469,9 +8444,8 @@ static int voice_alloc_rtac_mem_map_table(void) int ret = 0; size_t len; - ret = msm_audio_ion_alloc("voc_rtac_cal", - &(common.rtac_mem_map_table.client), - &(common.rtac_mem_map_table.handle), + ret = msm_audio_ion_alloc( + &(common.rtac_mem_map_table.dma_buf), sizeof(struct vss_imemory_table_t), &common.rtac_mem_map_table.phys, &len, @@ -9181,8 +9155,7 @@ static int is_source_tracking_shared_memomry_allocated(void) pr_debug("%s: Enter\n", __func__); - if (common.source_tracking_sh_mem.sh_mem_block.client != NULL && - common.source_tracking_sh_mem.sh_mem_block.handle != NULL) + if (common.source_tracking_sh_mem.sh_mem_block.dma_buf != NULL) ret = true; else ret = false; @@ -9198,9 +9171,8 @@ static int voice_alloc_source_tracking_shared_memory(void) pr_debug("%s: Enter\n", __func__); - ret = msm_audio_ion_alloc("source_tracking_sh_mem_block", - &(common.source_tracking_sh_mem.sh_mem_block.client), - &(common.source_tracking_sh_mem.sh_mem_block.handle), + ret = msm_audio_ion_alloc( + &(common.source_tracking_sh_mem.sh_mem_block.dma_buf), BUFFER_BLOCK_SIZE, &(common.source_tracking_sh_mem.sh_mem_block.phys), (size_t *)&(common.source_tracking_sh_mem.sh_mem_block.size), @@ -9221,9 +9193,8 @@ static int voice_alloc_source_tracking_shared_memory(void) (void *)(common.source_tracking_sh_mem.sh_mem_block.data), (size_t)(common.source_tracking_sh_mem.sh_mem_block.size)); - ret = msm_audio_ion_alloc("source_tracking_sh_mem_table", - &(common.source_tracking_sh_mem.sh_mem_table.client), - &(common.source_tracking_sh_mem.sh_mem_table.handle), + ret = msm_audio_ion_alloc( + &(common.source_tracking_sh_mem.sh_mem_table.dma_buf), sizeof(struct vss_imemory_table_t), &(common.source_tracking_sh_mem.sh_mem_table.phys), (size_t *)&(common.source_tracking_sh_mem.sh_mem_table.size), @@ -9233,10 +9204,8 @@ static int voice_alloc_source_tracking_shared_memory(void) __func__, ret); ret = msm_audio_ion_free( - common.source_tracking_sh_mem.sh_mem_block.client, - common.source_tracking_sh_mem.sh_mem_block.handle); - common.source_tracking_sh_mem.sh_mem_block.client = NULL; - common.source_tracking_sh_mem.sh_mem_block.handle = NULL; + common.source_tracking_sh_mem.sh_mem_block.dma_buf); + common.source_tracking_sh_mem.sh_mem_block.dma_buf = NULL; if (ret < 0) pr_err("%s: Error:%d freeing memory\n", __func__, ret); @@ -9312,13 +9281,11 @@ static int voice_unmap_and_free_source_tracking_shared_memory( } } - if ((common.source_tracking_sh_mem.sh_mem_block.client == NULL) || - (common.source_tracking_sh_mem.sh_mem_block.handle == NULL)) + if (common.source_tracking_sh_mem.sh_mem_block.dma_buf == NULL) goto done; ret = msm_audio_ion_free( - common.source_tracking_sh_mem.sh_mem_block.client, - common.source_tracking_sh_mem.sh_mem_block.handle); + common.source_tracking_sh_mem.sh_mem_block.dma_buf); if (ret < 0) { pr_err("%s: Error:%d freeing memory\n", __func__, ret); @@ -9328,8 +9295,7 @@ static int voice_unmap_and_free_source_tracking_shared_memory( done: common.source_tracking_sh_mem.mem_handle = 0; - common.source_tracking_sh_mem.sh_mem_block.client = NULL; - common.source_tracking_sh_mem.sh_mem_block.handle = NULL; + common.source_tracking_sh_mem.sh_mem_block.dma_buf = NULL; pr_debug("%s: Exit, ret=%d\n", __func__, ret); return ret; diff --git a/dsp/rtac.c b/dsp/rtac.c index 43c69ccab394..0785f5621f69 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -41,13 +41,13 @@ struct rtac_cal_block_data rtac_cal[MAX_RTAC_BLOCKS] = { /* ADM_RTAC_CAL */ - {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} }, + {{RTAC_BUF_SIZE, 0, 0}, {0, 0, 0} }, /* ASM_RTAC_CAL */ - {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} }, + {{RTAC_BUF_SIZE, 0, 0}, {0, 0, 0} }, /* VOICE_RTAC_CAL */ - {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} }, + {{RTAC_BUF_SIZE, 0, 0}, {0, 0, 0} }, /* AFE_RTAC_CAL */ - {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} } + {{RTAC_BUF_SIZE, 0, 0}, {0, 0, 0} } }; struct rtac_common_data { @@ -164,9 +164,7 @@ int rtac_allocate_cal_buffer(uint32_t cal_type) goto done; } - result = msm_audio_ion_alloc("rtac_client", - &rtac_cal[cal_type].map_data.ion_client, - &rtac_cal[cal_type].map_data.ion_handle, + result = msm_audio_ion_alloc(&rtac_cal[cal_type].map_data.dma_buf, rtac_cal[cal_type].map_data.map_size, &rtac_cal[cal_type].cal_data.paddr, &len, @@ -199,14 +197,13 @@ int rtac_free_cal_buffer(uint32_t cal_type) goto done; } - if (rtac_cal[cal_type].map_data.ion_client == NULL) { + if (rtac_cal[cal_type].map_data.dma_buf == NULL) { pr_debug("%s: cal_type %d not allocated!\n", __func__, cal_type); goto done; } - result = msm_audio_ion_free(rtac_cal[cal_type].map_data.ion_client, - rtac_cal[cal_type].map_data.ion_handle); + result = msm_audio_ion_free(rtac_cal[cal_type].map_data.dma_buf); if (result < 0) { pr_err("%s: ION free for RTAC failed! cal_type %d, paddr 0x%pK\n", __func__, cal_type, &rtac_cal[cal_type].cal_data.paddr); @@ -214,8 +211,7 @@ int rtac_free_cal_buffer(uint32_t cal_type) } rtac_cal[cal_type].map_data.map_handle = 0; - rtac_cal[cal_type].map_data.ion_client = NULL; - rtac_cal[cal_type].map_data.ion_handle = NULL; + rtac_cal[cal_type].map_data.dma_buf = NULL; rtac_cal[cal_type].cal_data.size = 0; rtac_cal[cal_type].cal_data.kvaddr = 0; rtac_cal[cal_type].cal_data.paddr = 0; @@ -754,7 +750,7 @@ int send_adm_apr(void *buf, u32 opcode) pr_debug("%s\n", __func__); - if (rtac_cal[ADM_RTAC_CAL].map_data.ion_handle == NULL) { + if (rtac_cal[ADM_RTAC_CAL].map_data.dma_buf == NULL) { result = rtac_allocate_cal_buffer(ADM_RTAC_CAL); if (result < 0) { pr_err("%s: allocate buffer failed!", @@ -983,7 +979,7 @@ int send_rtac_asm_apr(void *buf, u32 opcode) pr_debug("%s\n", __func__); - if (rtac_cal[ASM_RTAC_CAL].map_data.ion_handle == NULL) { + if (rtac_cal[ASM_RTAC_CAL].map_data.dma_buf == NULL) { result = rtac_allocate_cal_buffer(ASM_RTAC_CAL); if (result < 0) { pr_err("%s: allocate buffer failed!", @@ -1232,7 +1228,7 @@ static int send_rtac_afe_apr(void *buf, uint32_t opcode) pr_debug("%s\n", __func__); - if (rtac_cal[AFE_RTAC_CAL].map_data.ion_handle == NULL) { + if (rtac_cal[AFE_RTAC_CAL].map_data.dma_buf == NULL) { result = rtac_allocate_cal_buffer(AFE_RTAC_CAL); if (result < 0) { pr_err("%s: allocate buffer failed! ret = %d\n", @@ -1482,7 +1478,7 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode) pr_debug("%s\n", __func__); - if (rtac_cal[VOICE_RTAC_CAL].map_data.ion_handle == NULL) { + if (rtac_cal[VOICE_RTAC_CAL].map_data.dma_buf == NULL) { result = rtac_allocate_cal_buffer(VOICE_RTAC_CAL); if (result < 0) { pr_err("%s: allocate buffer failed!", diff --git a/include/dsp/audio_cal_utils.h b/include/dsp/audio_cal_utils.h index e12d8c1a9890..a4aa4e45d200 100644 --- a/include/dsp/audio_cal_utils.h +++ b/include/dsp/audio_cal_utils.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014, 2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -28,8 +28,7 @@ struct mem_map_data { size_t map_size; int32_t q6map_handle; int32_t ion_map_handle; - struct ion_client *ion_client; - struct ion_handle *ion_handle; + struct dma_buf *dma_buf; }; struct cal_block_data { diff --git a/include/dsp/msm_audio_ion.h b/include/dsp/msm_audio_ion.h index 8a2fb6e34b99..a4cd3867774b 100644 --- a/include/dsp/msm_audio_ion.h +++ b/include/dsp/msm_audio_ion.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2015, 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -18,28 +18,14 @@ #include -int msm_audio_ion_alloc(const char *name, struct ion_client **client, - struct ion_handle **handle, size_t bufsz, - ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr); +int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, + dma_addr_t *paddr, size_t *pa_len, void **vaddr); -int msm_audio_ion_import(const char *name, struct ion_client **client, - struct ion_handle **handle, int fd, +int msm_audio_ion_import(struct dma_buf **dma_buf, int fd, unsigned long *ionflag, size_t bufsz, - ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr); -int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle); -int msm_audio_ion_mmap(struct audio_buffer *substream, - struct vm_area_struct *vma); + dma_addr_t *paddr, size_t *pa_len, void **vaddr); +int msm_audio_ion_free(struct dma_buf *dma_buf); +int msm_audio_ion_mmap(struct audio_buffer *abuff, struct vm_area_struct *vma); -bool msm_audio_ion_is_smmu_available(void); -int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op); - -struct ion_client *msm_audio_ion_client_create(const char *name); -void msm_audio_ion_client_destroy(struct ion_client *client); -int msm_audio_ion_import_legacy(const char *name, struct ion_client *client, - struct ion_handle **handle, int fd, - unsigned long *ionflag, size_t bufsz, - ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr); -int msm_audio_ion_free_legacy(struct ion_client *client, - struct ion_handle *handle); -u32 msm_audio_populate_upper_32_bits(ion_phys_addr_t pa); +u32 msm_audio_populate_upper_32_bits(dma_addr_t pa); #endif /* _LINUX_MSM_AUDIO_ION_H */ diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 6fb9c442ec30..ade124952236 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -246,8 +246,7 @@ struct afe_audio_buffer { uint32_t used; uint32_t size;/* size of buffer */ uint32_t actual_size; /* actual number of bytes read by DSP */ - struct ion_handle *handle; - struct ion_client *client; + struct dma_buf *dma_buf; }; struct afe_audio_port_data { diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index 157c243185b6..27b360f376c5 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -165,8 +165,7 @@ struct audio_buffer { uint32_t used; uint32_t size;/* size of buffer */ uint32_t actual_size; /* actual number of bytes read by DSP */ - struct ion_handle *handle; - struct ion_client *client; + struct dma_buf *dma_buf; }; struct audio_aio_write_param { diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h index efce3a6d2076..9050a7ca86c6 100644 --- a/include/dsp/q6lsm.h +++ b/include/dsp/q6lsm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -33,8 +33,7 @@ struct lsm_sound_model { void *data; size_t size; /* size of buffer */ uint32_t actual_size; /* actual number of bytes read by DSP */ - struct ion_handle *handle; - struct ion_client *client; + struct dma_buf *dma_buf; uint32_t mem_map_handle; }; @@ -48,8 +47,7 @@ struct lsm_lab_buffer { dma_addr_t phys; void *data; size_t size; - struct ion_handle *handle; - struct ion_client *client; + struct dma_buf *dma_buf; uint32_t mem_map_handle; }; diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index a41a2db8f868..5dfdccf84420 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -156,8 +156,7 @@ struct mem_buffer { }; struct share_mem_buf { - struct ion_handle *handle; - struct ion_client *client; + struct dma_buf *dma_buf; struct mem_buffer buf[NUM_OF_BUFFERS]; }; @@ -165,8 +164,7 @@ struct mem_map_table { dma_addr_t phys; void *data; size_t size; /* size of buffer */ - struct ion_handle *handle; - struct ion_client *client; + struct dma_buf *dma_buf; }; /* Common */ @@ -1874,12 +1872,6 @@ struct voice_data { struct voice_rec_route_state rec_route_state; }; -struct cal_mem { - struct ion_handle *handle; - uint32_t phy; - void *buf; -}; - #define MAX_VOC_SESSIONS 8 struct common_data { @@ -1909,9 +1901,6 @@ struct common_data { uint32_t voice_host_pcm_mem_handle; - struct cal_mem cvp_cal; - struct cal_mem cvs_cal; - struct mutex common_lock; struct mvs_driver_info mvs_info; diff --git a/include/dsp/rtac.h b/include/dsp/rtac.h index f8c5556c5455..05dd82a7fcab 100644 --- a/include/dsp/rtac.h +++ b/include/dsp/rtac.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013-2015, 2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2013-2015, 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -38,8 +38,7 @@ enum { struct rtac_cal_mem_map_data { uint32_t map_size; uint32_t map_handle; - struct ion_client *ion_client; - struct ion_handle *ion_handle; + struct dma_buf *dma_buf; }; struct rtac_cal_data { -- GitLab From 0f1f3f6d041d49472d32701406221f7d2844d7d9 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Fri, 2 Feb 2018 03:36:46 -0800 Subject: [PATCH 0152/1645] dsp: add cache operations for dma_buf Add support for querying ION flags for dma_buf and for cache ops on dma_buf with CACHED Flag on. Change-Id: I219e564c477af8ba3b8676db1c9555a2b5b9ebab Signed-off-by: Banajit Goswami --- dsp/msm_audio_ion.c | 70 +++++++++++++++++++++++++++++++++---- include/dsp/msm_audio_ion.h | 5 +++ 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index c0879218515b..6ba29dce1075 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -422,8 +422,7 @@ int msm_audio_ion_import(struct dma_buf **dma_buf, int fd, if (!dma_buf || !paddr || !vaddr || !plen) { pr_err("%s: Invalid params\n", __func__); - rc = -EINVAL; - goto err; + return -EINVAL; } /* bufsz should be 0 and fd shouldn't be 0 as of now */ @@ -436,10 +435,12 @@ int msm_audio_ion_import(struct dma_buf **dma_buf, int fd, } if (ionflag != NULL) { - pr_err("%s: could not get flags for the dma_buf\n", - __func__); - rc = -EOPNOTSUPP; - goto err_ion_flag; + rc = dma_buf_get_flags(*dma_buf, ionflag); + if (rc) { + pr_err("%s: could not get flags for the dma_buf\n", + __func__); + goto err_ion_flag; + } } rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, *vaddr); @@ -569,6 +570,63 @@ int msm_audio_ion_mmap(struct audio_buffer *abuff, } EXPORT_SYMBOL(msm_audio_ion_mmap); +/** + * msm_audio_ion_cache_operations- + * Cache operations on cached Audio ION buffers + * + * @abuff: audio buf pointer + * @cache_op: cache operation to be performed + * + * Returns 0 on success or error on failure + */ +int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op) +{ + unsigned long ionflag = 0; + int rc = 0; + + if (!abuff) { + pr_err("%s: Invalid params: %pK\n", __func__, abuff); + return -EINVAL; + } + rc = dma_buf_get_flags(abuff->dma_buf, &ionflag); + if (rc) { + pr_err("%s: dma_buf_get_flags failed: %d\n", __func__, rc); + goto cache_op_failed; + } + + /* Has to be CACHED */ + if (ionflag & ION_FLAG_CACHED) { + /* MSM_AUDIO_ION_INV_CACHES or MSM_AUDIO_ION_CLEAN_CACHES */ + switch (cache_op) { + case MSM_AUDIO_ION_INV_CACHES: + rc = dma_buf_begin_cpu_access(abuff->dma_buf, + DMA_BIDIRECTIONAL); + if (rc) + pr_err("%s: failed to invalidate caches. rc = %d\n", + __func__, rc); + break; + case MSM_AUDIO_ION_CLEAN_CACHES: + rc = dma_buf_end_cpu_access(abuff->dma_buf, + DMA_BIDIRECTIONAL); + if (rc) + pr_err("%s: failed to clean caches. rc = %d\n", + __func__, rc); + break; + default: + pr_err("%s: Invalid cache operation %d\n", + __func__, cache_op); + } + } else { + pr_err("%s: Cache ops called on uncached buffer: %pK\n", + __func__, abuff->dma_buf); + rc = -EINVAL; + } + +cache_op_failed: + return rc; +} +EXPORT_SYMBOL(msm_audio_ion_cache_operations); + /** * msm_audio_populate_upper_32_bits - * retrieve upper 32bits of 64bit address diff --git a/include/dsp/msm_audio_ion.h b/include/dsp/msm_audio_ion.h index a4cd3867774b..dae1d1d7f485 100644 --- a/include/dsp/msm_audio_ion.h +++ b/include/dsp/msm_audio_ion.h @@ -17,6 +17,10 @@ #include #include +enum { + MSM_AUDIO_ION_INV_CACHES = 0, + MSM_AUDIO_ION_CLEAN_CACHES, +}; int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, dma_addr_t *paddr, size_t *pa_len, void **vaddr); @@ -26,6 +30,7 @@ int msm_audio_ion_import(struct dma_buf **dma_buf, int fd, dma_addr_t *paddr, size_t *pa_len, void **vaddr); int msm_audio_ion_free(struct dma_buf *dma_buf); int msm_audio_ion_mmap(struct audio_buffer *abuff, struct vm_area_struct *vma); +int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op); u32 msm_audio_populate_upper_32_bits(dma_addr_t pa); #endif /* _LINUX_MSM_AUDIO_ION_H */ -- GitLab From 9cb7bc20c7eb56c330dec9013b99ec957d347934 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Fri, 2 Feb 2018 15:10:57 +0800 Subject: [PATCH 0153/1645] ASoC: change OUT to PRODUCT_OUT Change OUT to PRODUCT_OUT in Android.mk to fit new Android. Change-Id: Idf64784eb2ab2b350872efbe04305bee2a47dd86 Signed-off-by: Meng Wang --- Android.mk | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Android.mk b/Android.mk index cda991e9889f..2fa054ba9569 100644 --- a/Android.mk +++ b/Android.mk @@ -1,18 +1,18 @@ # Android makefile for audio kernel modules MY_LOCAL_PATH := $(call my-dir) -UAPI_OUT := $(OUT)/obj/vendor/qcom/opensource/audio-kernel/include +UAPI_OUT := $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/include ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) $(shell mkdir -p $(UAPI_OUT)/linux;) $(shell mkdir -p $(UAPI_OUT)/sound;) -$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers) -$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers) -$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/codecs/Module.symvers) -$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers) -$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers) -$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers) -$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/codecs/Module.symvers) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers) include $(MY_LOCAL_PATH)/ipc/Android.mk include $(MY_LOCAL_PATH)/dsp/Android.mk @@ -24,8 +24,8 @@ include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk endif ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) -$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers) -$(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/sdm660_cdc/Android.mk include $(MY_LOCAL_PATH)/asoc/codecs/msm_sdw/Android.mk endif -- GitLab From 3e42fefa2fb78db26fbea6dbf2df377ee59d8af9 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 12 Dec 2017 21:27:32 +0530 Subject: [PATCH 0154/1645] ASoC: AQT1000: Add driver for AQT1000 codec AQT1000 codec is a hifi headset that supports audio playback and recording on headset. It also supports playback of fractional sampling rates. Audio playback and recording is transferred through I2S interface. Add driver for AQT1000 codec Change-Id: Iba163e9203d67216cdbf87727b06801356a001e3 Signed-off-by: Sudheer Papothi --- asoc/codecs/aqt1000/aqt1000-clsh.c | 805 +++++ asoc/codecs/aqt1000/aqt1000-clsh.h | 115 + asoc/codecs/aqt1000/aqt1000-core.c | 589 ++++ asoc/codecs/aqt1000/aqt1000-internal.h | 181 ++ asoc/codecs/aqt1000/aqt1000-irq.c | 185 ++ asoc/codecs/aqt1000/aqt1000-irq.h | 73 + asoc/codecs/aqt1000/aqt1000-mbhc.c | 1133 +++++++ asoc/codecs/aqt1000/aqt1000-mbhc.h | 84 + asoc/codecs/aqt1000/aqt1000-reg-defaults.h | 1616 ++++++++++ asoc/codecs/aqt1000/aqt1000-registers.h | 881 ++++++ asoc/codecs/aqt1000/aqt1000-regmap.c | 110 + asoc/codecs/aqt1000/aqt1000-routing.h | 170 ++ asoc/codecs/aqt1000/aqt1000-utils.c | 199 ++ asoc/codecs/aqt1000/aqt1000-utils.h | 22 + asoc/codecs/aqt1000/aqt1000.c | 3216 ++++++++++++++++++++ asoc/codecs/aqt1000/aqt1000.h | 225 ++ asoc/codecs/aqt1000/pdata.h | 40 + 17 files changed, 9644 insertions(+) create mode 100644 asoc/codecs/aqt1000/aqt1000-clsh.c create mode 100644 asoc/codecs/aqt1000/aqt1000-clsh.h create mode 100644 asoc/codecs/aqt1000/aqt1000-core.c create mode 100644 asoc/codecs/aqt1000/aqt1000-internal.h create mode 100644 asoc/codecs/aqt1000/aqt1000-irq.c create mode 100644 asoc/codecs/aqt1000/aqt1000-irq.h create mode 100644 asoc/codecs/aqt1000/aqt1000-mbhc.c create mode 100644 asoc/codecs/aqt1000/aqt1000-mbhc.h create mode 100644 asoc/codecs/aqt1000/aqt1000-reg-defaults.h create mode 100644 asoc/codecs/aqt1000/aqt1000-registers.h create mode 100644 asoc/codecs/aqt1000/aqt1000-regmap.c create mode 100644 asoc/codecs/aqt1000/aqt1000-routing.h create mode 100644 asoc/codecs/aqt1000/aqt1000-utils.c create mode 100644 asoc/codecs/aqt1000/aqt1000-utils.h create mode 100644 asoc/codecs/aqt1000/aqt1000.c create mode 100644 asoc/codecs/aqt1000/aqt1000.h create mode 100644 asoc/codecs/aqt1000/pdata.h diff --git a/asoc/codecs/aqt1000/aqt1000-clsh.c b/asoc/codecs/aqt1000/aqt1000-clsh.c new file mode 100644 index 000000000000..640795dc7900 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-clsh.c @@ -0,0 +1,805 @@ +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include "aqt1000-registers.h" +#include "aqt1000-clsh.h" + +#define AQT_USLEEP_RANGE 50 +#define MAX_IMPED_PARAMS 6 + +enum aqt_vref_dac_sel { + VREF_N1P9V = 0, + VREF_N1P86V, + VREF_N181V, + VREF_N1P74V, + VREF_N1P7V, + VREF_N0P9V, + VREF_N1P576V, + VREF_N1P827V, +}; + +enum aqt_vref_ctl { + CONTROLLER = 0, + I2C, +}; + +enum aqt_hd2_res_div_ctl { + DISCONNECT = 0, + P5_0P35, + P75_0P68, + P82_0P77, + P9_0P87, +}; + +enum aqt_curr_bias_err_amp { + I_0P25UA = 0, + I_0P5UA, + I_0P75UA, + I_1UA, + I_1P25UA, + I_1P5UA, + I_1P75UA, + I_2UA, +}; + +static const struct aqt_reg_mask_val imped_table_aqt[][MAX_IMPED_PARAMS] = { + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xf2}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf2}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xf2}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf2}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xf4}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf4}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xf4}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf4}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xf7}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf7}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xf7}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf7}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01}, + }, + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xf9}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf9}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xf9}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf9}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xfa}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfa}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xfa}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfa}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xfb}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfb}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xfb}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfb}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xfc}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfc}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xfc}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfc}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xfd}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xfd}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xfd}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xfd}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01}, + }, +}; + +static const struct aqt_imped_val imped_index[] = { + {4, 0}, + {5, 1}, + {6, 2}, + {7, 3}, + {8, 4}, + {9, 5}, + {10, 6}, + {11, 7}, + {12, 8}, + {13, 9}, +}; + +static void (*clsh_state_fp[NUM_CLSH_STATES])(struct snd_soc_codec *, + struct aqt_clsh_cdc_data *, + u8 req_state, bool en, int mode); + +static int get_impedance_index(int imped) +{ + int i = 0; + + if (imped < imped_index[i].imped_val) { + pr_debug("%s, detected impedance is less than 4 Ohm\n", + __func__); + i = 0; + goto ret; + } + if (imped >= imped_index[ARRAY_SIZE(imped_index) - 1].imped_val) { + pr_debug("%s, detected impedance is greater than 12 Ohm\n", + __func__); + i = ARRAY_SIZE(imped_index) - 1; + goto ret; + } + for (i = 0; i < ARRAY_SIZE(imped_index) - 1; i++) { + if (imped >= imped_index[i].imped_val && + imped < imped_index[i + 1].imped_val) + break; + } +ret: + pr_debug("%s: selected impedance index = %d\n", + __func__, imped_index[i].index); + return imped_index[i].index; +} + +/* + * Function: aqt_clsh_imped_config + * Params: codec, imped, reset + * Description: + * This function updates HPHL and HPHR gain settings + * according to the impedance value. + */ +void aqt_clsh_imped_config(struct snd_soc_codec *codec, int imped, bool reset) +{ + int i; + int index = 0; + int table_size; + + static const struct aqt_reg_mask_val + (*imped_table_ptr)[MAX_IMPED_PARAMS]; + + table_size = ARRAY_SIZE(imped_table_aqt); + imped_table_ptr = imped_table_aqt; + + /* reset = 1, which means request is to reset the register values */ + if (reset) { + for (i = 0; i < MAX_IMPED_PARAMS; i++) + snd_soc_update_bits(codec, + imped_table_ptr[index][i].reg, + imped_table_ptr[index][i].mask, 0); + return; + } + index = get_impedance_index(imped); + if (index >= (ARRAY_SIZE(imped_index) - 1)) { + pr_debug("%s, impedance not in range = %d\n", __func__, imped); + return; + } + if (index >= table_size) { + pr_debug("%s, impedance index not in range = %d\n", __func__, + index); + return; + } + for (i = 0; i < MAX_IMPED_PARAMS; i++) + snd_soc_update_bits(codec, + imped_table_ptr[index][i].reg, + imped_table_ptr[index][i].mask, + imped_table_ptr[index][i].val); +} +EXPORT_SYMBOL(aqt_clsh_imped_config); + +static const char *mode_to_str(int mode) +{ + switch (mode) { + case CLS_H_NORMAL: + return "CLS_H_NORMAL"; + case CLS_H_HIFI: + return "CLS_H_HIFI"; + case CLS_H_LOHIFI: + return "CLS_H_LOHIFI"; + case CLS_H_LP: + return "CLS_H_LP"; + case CLS_H_ULP: + return "CLS_H_ULP"; + case CLS_AB: + return "CLS_AB"; + case CLS_AB_HIFI: + return "CLS_AB_HIFI"; + default: + return "CLS_H_INVALID"; + }; +} + +static const char *const state_to_str[] = { + [AQT_CLSH_STATE_IDLE] = "STATE_IDLE", + [AQT_CLSH_STATE_HPHL] = "STATE_HPH_L", + [AQT_CLSH_STATE_HPHR] = "STATE_HPH_R", + [AQT_CLSH_STATE_HPH_ST] = "STATE_HPH_ST", +}; + +static inline void +aqt_enable_clsh_block(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *clsh_d, bool enable) +{ + if ((enable && ++clsh_d->clsh_users == 1) || + (!enable && --clsh_d->clsh_users == 0)) + snd_soc_update_bits(codec, AQT1000_CDC_CLSH_CRC, 0x01, + (u8) enable); + if (clsh_d->clsh_users < 0) + clsh_d->clsh_users = 0; + dev_dbg(codec->dev, "%s: clsh_users %d, enable %d", __func__, + clsh_d->clsh_users, enable); +} + +static inline bool aqt_clsh_enable_status(struct snd_soc_codec *codec) +{ + return snd_soc_read(codec, AQT1000_CDC_CLSH_CRC) & 0x01; +} + +static inline int aqt_clsh_get_int_mode(struct aqt_clsh_cdc_data *clsh_d, + int clsh_state) +{ + int mode; + + if ((clsh_state != AQT_CLSH_STATE_HPHL) && + (clsh_state != AQT_CLSH_STATE_HPHR)) + mode = CLS_NONE; + else + mode = clsh_d->interpolator_modes[ffs(clsh_state)]; + + return mode; +} + +static inline void aqt_clsh_set_int_mode(struct aqt_clsh_cdc_data *clsh_d, + int clsh_state, int mode) +{ + if ((clsh_state != AQT_CLSH_STATE_HPHL) && + (clsh_state != AQT_CLSH_STATE_HPHR)) + return; + + clsh_d->interpolator_modes[ffs(clsh_state)] = mode; +} + +static inline void aqt_clsh_set_buck_mode(struct snd_soc_codec *codec, + int mode) +{ + if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || + mode == CLS_AB_HIFI || mode == CLS_AB) + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + 0x08, 0x08); /* set to HIFI */ + else + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + 0x08, 0x00); /* set to default */ +} + +static inline void aqt_clsh_set_flyback_mode(struct snd_soc_codec *codec, + int mode) +{ + if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || + mode == CLS_AB_HIFI || mode == CLS_AB) + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + 0x04, 0x04); /* set to HIFI */ + else + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + 0x04, 0x00); /* set to Default */ +} + +static inline void aqt_clsh_gm3_boost_disable(struct snd_soc_codec *codec, + int mode) +{ + if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || + mode == CLS_AB_HIFI || mode == CLS_AB) { + snd_soc_update_bits(codec, AQT1000_HPH_CNP_WG_CTL, + 0x80, 0x0); /* disable GM3 Boost */ + snd_soc_update_bits(codec, AQT1000_FLYBACK_VNEG_CTRL_4, + 0xF0, 0x80); + } else { + snd_soc_update_bits(codec, AQT1000_HPH_CNP_WG_CTL, + 0x80, 0x80); /* set to Default */ + snd_soc_update_bits(codec, AQT1000_FLYBACK_VNEG_CTRL_4, + 0xF0, 0x70); + } +} + +static inline void aqt_clsh_flyback_dac_ctl(struct snd_soc_codec *codec, + int vref) +{ + snd_soc_update_bits(codec, AQT1000_FLYBACK_VNEGDAC_CTRL_2, + 0xE0, (vref << 5)); +} + +static inline void aqt_clsh_mode_vref_ctl(struct snd_soc_codec *codec, + int vref_ctl) +{ + if (vref_ctl == I2C) { + snd_soc_update_bits(codec, AQT1000_CLASSH_MODE_3, 0x02, 0x02); + snd_soc_update_bits(codec, AQT1000_CLASSH_MODE_2, 0xFF, 0x1C); + } else { + snd_soc_update_bits(codec, AQT1000_CLASSH_MODE_2, 0xFF, 0x3A); + snd_soc_update_bits(codec, AQT1000_CLASSH_MODE_3, 0x02, 0x00); + } +} + +static inline void aqt_clsh_buck_current_bias_ctl(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, AQT1000_BUCK_5V_IBIAS_CTL_4, + 0x70, (I_2UA << 4)); + snd_soc_update_bits(codec, AQT1000_BUCK_5V_IBIAS_CTL_4, + 0x07, I_0P25UA); + snd_soc_update_bits(codec, AQT1000_BUCK_5V_CTRL_CCL_2, + 0x3F, 0x3F); + } else { + snd_soc_update_bits(codec, AQT1000_BUCK_5V_IBIAS_CTL_4, + 0x70, (I_1UA << 4)); + snd_soc_update_bits(codec, AQT1000_BUCK_5V_IBIAS_CTL_4, + 0x07, I_1UA); + snd_soc_update_bits(codec, AQT1000_BUCK_5V_CTRL_CCL_2, + 0x3F, 0x20); + } +} + +static inline void aqt_clsh_rdac_hd2_ctl(struct snd_soc_codec *codec, + u8 hd2_div_ctl, u8 state) +{ + u16 reg = 0; + + if (state == AQT_CLSH_STATE_HPHL) + reg = AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_L; + else if (state == AQT_CLSH_STATE_HPHR) + reg = AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_R; + else + dev_err(codec->dev, "%s: Invalid state: %d\n", + __func__, state); + if (!reg) + snd_soc_update_bits(codec, reg, 0x0F, hd2_div_ctl); +} + +static inline void aqt_clsh_force_iq_ctl(struct snd_soc_codec *codec, + int mode) +{ + if (mode == CLS_H_LOHIFI || mode == CLS_AB) { + snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_PA_MISC2, + 0x20, 0x20); + snd_soc_update_bits(codec, AQT1000_RX_BIAS_HPH_LOWPOWER, + 0xF0, 0xC0); + snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL1, + 0x0E, 0x02); + } else { + + snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_PA_MISC2, + 0x20, 0x0); + snd_soc_update_bits(codec, AQT1000_RX_BIAS_HPH_LOWPOWER, + 0xF0, 0x80); + snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL1, + 0x0E, 0x06); + } +} + +static void aqt_clsh_buck_ctrl(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *clsh_d, + int mode, + bool enable) +{ + /* enable/disable buck */ + if ((enable && (++clsh_d->buck_users == 1)) || + (!enable && (--clsh_d->buck_users == 0))) + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + (1 << 7), (enable << 7)); + dev_dbg(codec->dev, "%s: buck_users %d, enable %d, mode: %s", + __func__, clsh_d->buck_users, enable, mode_to_str(mode)); + /* + * 500us sleep is required after buck enable/disable + * as per HW requirement + */ + usleep_range(500, 500 + AQT_USLEEP_RANGE); +} + +static void aqt_clsh_flyback_ctrl(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *clsh_d, + int mode, + bool enable) +{ + /* enable/disable flyback */ + if ((enable && (++clsh_d->flyback_users == 1)) || + (!enable && (--clsh_d->flyback_users == 0))) { + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + (1 << 6), (enable << 6)); + /* 100usec delay is needed as per HW requirement */ + usleep_range(100, 110); + } + dev_dbg(codec->dev, "%s: flyback_users %d, enable %d, mode: %s", + __func__, clsh_d->flyback_users, enable, mode_to_str(mode)); + /* + * 500us sleep is required after flyback enable/disable + * as per HW requirement + */ + usleep_range(500, 500 + AQT_USLEEP_RANGE); +} + +static void aqt_clsh_set_hph_mode(struct snd_soc_codec *codec, + int mode) +{ + u8 val = 0; + u8 gain = 0; + u8 res_val = VREF_FILT_R_0OHM; + u8 ipeak = DELTA_I_50MA; + + switch (mode) { + case CLS_H_NORMAL: + res_val = VREF_FILT_R_50KOHM; + val = 0x00; + gain = DAC_GAIN_0DB; + ipeak = DELTA_I_50MA; + break; + case CLS_AB: + val = 0x00; + gain = DAC_GAIN_0DB; + ipeak = DELTA_I_50MA; + break; + case CLS_AB_HIFI: + val = 0x08; + break; + case CLS_H_HIFI: + val = 0x08; + gain = DAC_GAIN_M0P2DB; + ipeak = DELTA_I_50MA; + break; + case CLS_H_LOHIFI: + val = 0x00; + break; + case CLS_H_ULP: + val = 0x0C; + break; + case CLS_H_LP: + val = 0x04; + ipeak = DELTA_I_30MA; + break; + default: + return; + }; + + if (mode == CLS_H_LOHIFI || mode == CLS_AB) + val = 0x04; + + snd_soc_update_bits(codec, AQT1000_ANA_HPH, 0x0C, val); +} + +static void aqt_clsh_set_buck_regulator_mode(struct snd_soc_codec *codec, + int mode) +{ + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + 0x02, 0x00); +} + +static void aqt_clsh_state_hph_st(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (mode == CLS_AB || mode == CLS_AB_HIFI) + return; + + if (is_enable) { + if (req_state == AQT_CLSH_STATE_HPHL) + snd_soc_update_bits(codec, + AQT1000_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x40); + if (req_state == AQT_CLSH_STATE_HPHR) + snd_soc_update_bits(codec, + AQT1000_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x40); + } else { + if (req_state == AQT_CLSH_STATE_HPHL) + snd_soc_update_bits(codec, + AQT1000_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x00); + if (req_state == AQT_CLSH_STATE_HPHR) + snd_soc_update_bits(codec, + AQT1000_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x00); + } +} + +static void aqt_clsh_state_hph_r(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (mode == CLS_H_NORMAL) { + dev_err(codec->dev, "%s: Normal mode not applicable for hph_r\n", + __func__); + return; + } + + if (is_enable) { + if (mode != CLS_AB && mode != CLS_AB_HIFI) { + aqt_enable_clsh_block(codec, clsh_d, true); + /* + * These K1 values depend on the Headphone Impedance + * For now it is assumed to be 16 ohm + */ + snd_soc_update_bits(codec, AQT1000_CDC_CLSH_K1_MSB, + 0x0F, 0x00); + snd_soc_update_bits(codec, AQT1000_CDC_CLSH_K1_LSB, + 0xFF, 0xC0); + snd_soc_update_bits(codec, + AQT1000_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x40); + } + aqt_clsh_set_buck_regulator_mode(codec, mode); + aqt_clsh_set_flyback_mode(codec, mode); + aqt_clsh_gm3_boost_disable(codec, mode); + aqt_clsh_flyback_dac_ctl(codec, VREF_N0P9V); + aqt_clsh_mode_vref_ctl(codec, I2C); + aqt_clsh_force_iq_ctl(codec, mode); + aqt_clsh_rdac_hd2_ctl(codec, P82_0P77, req_state); + aqt_clsh_flyback_ctrl(codec, clsh_d, mode, true); + aqt_clsh_flyback_dac_ctl(codec, VREF_N1P827V); + aqt_clsh_set_buck_mode(codec, mode); + aqt_clsh_buck_ctrl(codec, clsh_d, mode, true); + aqt_clsh_mode_vref_ctl(codec, CONTROLLER); + aqt_clsh_buck_current_bias_ctl(codec, true); + aqt_clsh_set_hph_mode(codec, mode); + } else { + aqt_clsh_set_hph_mode(codec, CLS_H_NORMAL); + aqt_clsh_buck_current_bias_ctl(codec, false); + + if (mode != CLS_AB && mode != CLS_AB_HIFI) { + snd_soc_update_bits(codec, + AQT1000_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x00); + aqt_enable_clsh_block(codec, clsh_d, false); + } + /* buck and flyback set to default mode and disable */ + aqt_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + aqt_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + aqt_clsh_rdac_hd2_ctl(codec, P5_0P35, req_state); + aqt_clsh_force_iq_ctl(codec, CLS_H_NORMAL); + aqt_clsh_gm3_boost_disable(codec, CLS_H_NORMAL); + aqt_clsh_set_flyback_mode(codec, CLS_H_NORMAL); + aqt_clsh_set_buck_mode(codec, CLS_H_NORMAL); + aqt_clsh_set_buck_regulator_mode(codec, CLS_H_NORMAL); + } +} + +static void aqt_clsh_state_hph_l(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (mode == CLS_H_NORMAL) { + dev_err(codec->dev, "%s: Normal mode not applicable for hph_l\n", + __func__); + return; + } + + if (is_enable) { + if (mode != CLS_AB && mode != CLS_AB_HIFI) { + aqt_enable_clsh_block(codec, clsh_d, true); + /* + * These K1 values depend on the Headphone Impedance + * For now it is assumed to be 16 ohm + */ + snd_soc_update_bits(codec, AQT1000_CDC_CLSH_K1_MSB, + 0x0F, 0x00); + snd_soc_update_bits(codec, AQT1000_CDC_CLSH_K1_LSB, + 0xFF, 0xC0); + snd_soc_update_bits(codec, + AQT1000_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x40); + } + aqt_clsh_set_buck_regulator_mode(codec, mode); + aqt_clsh_set_flyback_mode(codec, mode); + aqt_clsh_gm3_boost_disable(codec, mode); + aqt_clsh_flyback_dac_ctl(codec, VREF_N0P9V); + aqt_clsh_mode_vref_ctl(codec, I2C); + aqt_clsh_force_iq_ctl(codec, mode); + aqt_clsh_rdac_hd2_ctl(codec, P82_0P77, req_state); + aqt_clsh_flyback_ctrl(codec, clsh_d, mode, true); + aqt_clsh_flyback_dac_ctl(codec, VREF_N1P827V); + aqt_clsh_set_buck_mode(codec, mode); + aqt_clsh_buck_ctrl(codec, clsh_d, mode, true); + aqt_clsh_mode_vref_ctl(codec, CONTROLLER); + aqt_clsh_buck_current_bias_ctl(codec, true); + aqt_clsh_set_hph_mode(codec, mode); + } else { + aqt_clsh_set_hph_mode(codec, CLS_H_NORMAL); + aqt_clsh_buck_current_bias_ctl(codec, false); + + if (mode != CLS_AB && mode != CLS_AB_HIFI) { + snd_soc_update_bits(codec, + AQT1000_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x00); + aqt_enable_clsh_block(codec, clsh_d, false); + } + /* set buck and flyback to Default Mode */ + aqt_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + aqt_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + aqt_clsh_rdac_hd2_ctl(codec, P5_0P35, req_state); + aqt_clsh_force_iq_ctl(codec, CLS_H_NORMAL); + aqt_clsh_gm3_boost_disable(codec, CLS_H_NORMAL); + aqt_clsh_set_flyback_mode(codec, CLS_H_NORMAL); + aqt_clsh_set_buck_mode(codec, CLS_H_NORMAL); + aqt_clsh_set_buck_regulator_mode(codec, CLS_H_NORMAL); + } +} + +static void aqt_clsh_state_err(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_err(codec->dev, + "%s Wrong request for class H state machine requested to %s %s", + __func__, is_enable ? "enable" : "disable", + state_to_str[req_state]); +} + +/* + * Function: aqt_clsh_is_state_valid + * Params: state + * Description: + * Provides information on valid states of Class H configuration + */ +static bool aqt_clsh_is_state_valid(u8 state) +{ + switch (state) { + case AQT_CLSH_STATE_IDLE: + case AQT_CLSH_STATE_HPHL: + case AQT_CLSH_STATE_HPHR: + case AQT_CLSH_STATE_HPH_ST: + return true; + default: + return false; + }; +} + +/* + * Function: aqt_clsh_fsm + * Params: codec, cdc_clsh_d, req_state, req_type, clsh_event + * Description: + * This function handles PRE DAC and POST DAC conditions of different devices + * and updates class H configuration of different combination of devices + * based on validity of their states. cdc_clsh_d will contain current + * class h state information + */ +void aqt_clsh_fsm(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *cdc_clsh_d, + u8 clsh_event, u8 req_state, + int int_mode) +{ + u8 old_state, new_state; + + switch (clsh_event) { + case AQT_CLSH_EVENT_PRE_DAC: + old_state = cdc_clsh_d->state; + new_state = old_state | req_state; + + if (!aqt_clsh_is_state_valid(new_state)) { + dev_err(codec->dev, + "%s: Class-H not a valid new state: %s\n", + __func__, state_to_str[new_state]); + return; + } + if (new_state == old_state) { + dev_err(codec->dev, + "%s: Class-H already in requested state: %s\n", + __func__, state_to_str[new_state]); + return; + } + cdc_clsh_d->state = new_state; + aqt_clsh_set_int_mode(cdc_clsh_d, req_state, int_mode); + (*clsh_state_fp[new_state]) (codec, cdc_clsh_d, req_state, + CLSH_REQ_ENABLE, int_mode); + dev_dbg(codec->dev, + "%s: ClassH state transition from %s to %s\n", + __func__, state_to_str[old_state], + state_to_str[cdc_clsh_d->state]); + break; + case AQT_CLSH_EVENT_POST_PA: + old_state = cdc_clsh_d->state; + new_state = old_state & (~req_state); + if (new_state < NUM_CLSH_STATES) { + if (!aqt_clsh_is_state_valid(old_state)) { + dev_err(codec->dev, + "%s:Invalid old state:%s\n", + __func__, state_to_str[old_state]); + return; + } + if (new_state == old_state) { + dev_err(codec->dev, + "%s: Class-H already in requested state: %s\n", + __func__,state_to_str[new_state]); + return; + } + (*clsh_state_fp[old_state]) (codec, cdc_clsh_d, + req_state, CLSH_REQ_DISABLE, + int_mode); + cdc_clsh_d->state = new_state; + aqt_clsh_set_int_mode(cdc_clsh_d, req_state, CLS_NONE); + dev_dbg(codec->dev, "%s: ClassH state transition from %s to %s\n", + __func__, state_to_str[old_state], + state_to_str[cdc_clsh_d->state]); + } + break; + }; +} +EXPORT_SYMBOL(aqt_clsh_fsm); + +/* + * Function: aqt_clsh_get_clsh_state + * Params: clsh + * Description: + * This function returns the state of the class H controller + */ +int aqt_clsh_get_clsh_state(struct aqt_clsh_cdc_data *clsh) +{ + return clsh->state; +} +EXPORT_SYMBOL(aqt_clsh_get_clsh_state); + +/* + * Function: aqt_clsh_init + * Params: clsh + * Description: + * This function initializes the class H controller + */ +void aqt_clsh_init(struct aqt_clsh_cdc_data *clsh) +{ + int i; + + clsh->state = AQT_CLSH_STATE_IDLE; + + for (i = 0; i < NUM_CLSH_STATES; i++) + clsh_state_fp[i] = aqt_clsh_state_err; + + clsh_state_fp[AQT_CLSH_STATE_HPHL] = aqt_clsh_state_hph_l; + clsh_state_fp[AQT_CLSH_STATE_HPHR] = aqt_clsh_state_hph_r; + clsh_state_fp[AQT_CLSH_STATE_HPH_ST] = aqt_clsh_state_hph_st; + /* Set interpolator modes to NONE */ + aqt_clsh_set_int_mode(clsh, AQT_CLSH_STATE_HPHL, CLS_NONE); + aqt_clsh_set_int_mode(clsh, AQT_CLSH_STATE_HPHR, CLS_NONE); + clsh->flyback_users = 0; + clsh->buck_users = 0; + clsh->clsh_users = 0; +} +EXPORT_SYMBOL(aqt_clsh_init); diff --git a/asoc/codecs/aqt1000/aqt1000-clsh.h b/asoc/codecs/aqt1000/aqt1000-clsh.h new file mode 100644 index 000000000000..4a829b0c6925 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-clsh.h @@ -0,0 +1,115 @@ +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _AQT1000_CLSH_H +#define _AQT1000_CLSH_H + +#include +#include +#include +#include + +#define CLSH_REQ_ENABLE true +#define CLSH_REQ_DISABLE false + +#define AQT_CLSH_EVENT_PRE_DAC 0x01 +#define AQT_CLSH_EVENT_POST_PA 0x02 +/* + * Basic states for Class H state machine. + * represented as a bit mask within a u8 data type + * bit 0: HPH Left mode + * bit 1: HPH Right mode + */ +#define AQT_CLSH_STATE_IDLE 0x00 +#define AQT_CLSH_STATE_HPHL (0x01 << 0) +#define AQT_CLSH_STATE_HPHR (0x01 << 1) + +/* + * Though number of CLSH states are 2, max state shoulbe be 3 + * because state array index starts from 1. + */ +#define AQT_CLSH_STATE_MAX 3 +#define NUM_CLSH_STATES (0x01 << AQT_CLSH_STATE_MAX) + + +/* Derived State: Bits 1 and 2 should be set for Headphone stereo */ +#define AQT_CLSH_STATE_HPH_ST (AQT_CLSH_STATE_HPHL | \ + AQT_CLSH_STATE_HPHR) + +enum { + CLS_H_NORMAL = 0, /* Class-H Default */ + CLS_H_HIFI, /* Class-H HiFi */ + CLS_H_LP, /* Class-H Low Power */ + CLS_AB, /* Class-AB Low HIFI*/ + CLS_H_LOHIFI, /* LoHIFI */ + CLS_H_ULP, /* Ultra Low power */ + CLS_AB_HIFI, /* Class-AB */ + CLS_NONE, /* None of the above modes */ +}; + +enum { + DAC_GAIN_0DB = 0, + DAC_GAIN_0P2DB, + DAC_GAIN_0P4DB, + DAC_GAIN_0P6DB, + DAC_GAIN_0P8DB, + DAC_GAIN_M0P2DB, + DAC_GAIN_M0P4DB, + DAC_GAIN_M0P6DB, +}; + +enum { + VREF_FILT_R_0OHM = 0, + VREF_FILT_R_25KOHM, + VREF_FILT_R_50KOHM, + VREF_FILT_R_100KOHM, +}; + +enum { + DELTA_I_0MA, + DELTA_I_10MA, + DELTA_I_20MA, + DELTA_I_30MA, + DELTA_I_40MA, + DELTA_I_50MA, +}; + +struct aqt_imped_val { + u32 imped_val; + u8 index; +}; + +struct aqt_clsh_cdc_data { + u8 state; + int flyback_users; + int buck_users; + int clsh_users; + int interpolator_modes[AQT_CLSH_STATE_MAX]; +}; + +struct aqt_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + +extern void aqt_clsh_fsm(struct snd_soc_codec *codec, + struct aqt_clsh_cdc_data *cdc_clsh_d, + u8 clsh_event, u8 req_state, + int int_mode); + +extern void aqt_clsh_init(struct aqt_clsh_cdc_data *clsh); +extern int aqt_clsh_get_clsh_state(struct aqt_clsh_cdc_data *clsh); +extern void aqt_clsh_imped_config(struct snd_soc_codec *codec, int imped, + bool reset); + +#endif /* _AQT1000_CLSH_H */ diff --git a/asoc/codecs/aqt1000/aqt1000-core.c b/asoc/codecs/aqt1000/aqt1000-core.c new file mode 100644 index 000000000000..2306a2acfd7e --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-core.c @@ -0,0 +1,589 @@ +/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../msm-cdc-pinctrl.h" +#include "../msm-cdc-supply.h" +#include "aqt1000-registers.h" +#include "aqt1000-internal.h" +#include "aqt1000.h" +#include "aqt1000-utils.h" + +static int aqt1000_bringup(struct aqt1000 *aqt) +{ + struct aqt1000_pdata *pdata; + u8 clk_div = 0, mclk = 1; + + if (!aqt->regmap) { + dev_err(aqt->dev, "%s: aqt regmap is NULL\n", __func__); + return -EINVAL; + } + + /* Bringup register write sequence */ + regmap_update_bits(aqt->regmap, AQT1000_BUCK_5V_CTRL_CCL_1, 0xF0, 0xF0); + regmap_update_bits(aqt->regmap, AQT1000_BIAS_CCOMP_FINE_ADJ, + 0xF0, 0x90); + regmap_update_bits(aqt->regmap, AQT1000_ANA_BIAS, 0x80, 0x80); + regmap_update_bits(aqt->regmap, AQT1000_ANA_BIAS, 0x40, 0x40); + + /* Added 1msec sleep as per HW requirement */ + usleep_range(1000, 1010); + + regmap_update_bits(aqt->regmap, AQT1000_ANA_BIAS, 0x40, 0x00); + + clk_div = 0x04; /* Assumption is CLK DIV 2 */ + pdata = dev_get_platdata(aqt->dev); + if (pdata) { + if (pdata->mclk_rate == AQT1000_CLK_12P288MHZ) + mclk = 0; + clk_div = (((pdata->ext_clk_rate / pdata->mclk_rate) >> 1) + << 2); + } + regmap_update_bits(aqt->regmap, AQT1000_CHIP_CFG0_CLK_CFG_MCLK, + 0x03, mclk); + + regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK1_PRG, + 0x0C, clk_div); + + /* Source clock enable */ + regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK1_PRG, 0x02, 0x02); + + /* Ungate the source clock */ + regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK1_PRG, 0x10, 0x10); + + /* Set the I2S_HS_CLK reference to CLK DIV 2 */ + regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG, + 0x60, 0x20); + + /* Set the PLL preset to CLK9P6M_IN_12P288M_OUT */ + regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_PLL_PRESET, 0x0F, 0x02); + + /* Enable clock PLL */ + regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_PLL_ENABLES, + 0x01, 0x01); + + /* Add 100usec delay as per HW requirement */ + usleep_range(100, 110); + + /* Set AQT to I2S Master */ + regmap_update_bits(aqt->regmap, AQT1000_I2S_I2S_0_CTL, 0x02, 0x02); + + /* Enable I2S HS clock */ + regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG, + 0x01, 0x01); + + /* Codec digital reset */ + regmap_update_bits(aqt->regmap, AQT1000_CHIP_CFG0_RST_CTL, 0x01, 0x01); + + return 0; +} + +static int aqt1000_device_init(struct aqt1000 *aqt) +{ + int ret = 0; + + mutex_init(&aqt->io_lock); + mutex_init(&aqt->xfer_lock); + mutex_init(&aqt->cdc_bg_clk_lock); + mutex_init(&aqt->master_bias_lock); + + ret = aqt1000_bringup(aqt); + if (ret) { + ret = -EPROBE_DEFER; + goto done; + } + +done: + mutex_destroy(&aqt->io_lock); + mutex_destroy(&aqt->xfer_lock); + mutex_destroy(&aqt->cdc_bg_clk_lock); + mutex_destroy(&aqt->master_bias_lock); + return ret; +} + +static int aqt1000_i2c_write(struct aqt1000 *aqt1000, unsigned short reg, + void *val, int bytes) +{ + struct i2c_msg *msg; + int ret = 0; + u8 reg_addr = 0; + u8 data[bytes + 1]; + struct aqt1000_i2c *aqt1000_i2c; + u8 *value = (u8 *)val; + + aqt1000_i2c = &aqt1000->i2c_dev; + if (aqt1000_i2c == NULL || aqt1000_i2c->client == NULL) { + pr_err("%s: Failed to get device info\n", __func__); + return -ENODEV; + } + reg_addr = (u8)reg; + msg = &aqt1000_i2c->xfer_msg[0]; + msg->addr = aqt1000_i2c->client->addr; + msg->len = bytes + 1; + msg->flags = 0; + data[0] = reg; + data[1] = *value; + msg->buf = data; + ret = i2c_transfer(aqt1000_i2c->client->adapter, + aqt1000_i2c->xfer_msg, 1); + /* Try again if the write fails */ + if (ret != 1) { + ret = i2c_transfer(aqt1000_i2c->client->adapter, + aqt1000_i2c->xfer_msg, 1); + if (ret != 1) { + dev_err(aqt1000->dev, + "%s: I2C write failed, reg: 0x%x ret: %d\n", + __func__, reg, ret); + return ret; + } + } + dev_dbg(aqt1000->dev, "%s: write success register = %x val = %x\n", + __func__, reg, data[1]); + return 0; +} + +static int aqt1000_i2c_read(struct aqt1000 *aqt1000, unsigned short reg, + void *dst, int bytes) +{ + struct i2c_msg *msg; + int ret = 0; + u8 reg_addr = 0; + struct aqt1000_i2c *aqt1000_i2c; + u8 i = 0; + unsigned char *dest = (unsigned char *)dst; + + aqt1000_i2c = &aqt1000->i2c_dev; + if (aqt1000_i2c == NULL || aqt1000_i2c->client == NULL) { + pr_err("%s: Failed to get device info\n", __func__); + return -ENODEV; + } + for (i = 0; i < bytes; i++) { + reg_addr = (u8)reg++; + msg = &aqt1000_i2c->xfer_msg[0]; + msg->addr = aqt1000_i2c->client->addr; + msg->len = 1; + msg->flags = 0; + msg->buf = ®_addr; + + msg = &aqt1000_i2c->xfer_msg[1]; + msg->addr = aqt1000_i2c->client->addr; + msg->len = 1; + msg->flags = I2C_M_RD; + msg->buf = dest++; + ret = i2c_transfer(aqt1000_i2c->client->adapter, + aqt1000_i2c->xfer_msg, 2); + + /* Try again if read fails first time */ + if (ret != 2) { + ret = i2c_transfer(aqt1000_i2c->client->adapter, + aqt1000_i2c->xfer_msg, 2); + if (ret != 2) { + dev_err(aqt1000->dev, + "%s: I2C read failed, reg: 0x%x\n", + __func__, reg); + return ret; + } + } + } + return 0; +} + +static int aqt1000_reset(struct device *dev) +{ + struct aqt1000 *aqt1000; + int rc = 0; + + if (!dev) + return -ENODEV; + + aqt1000 = dev_get_drvdata(dev); + if (!aqt1000) + return -EINVAL; + + if (!aqt1000->aqt_rst_np) { + dev_err(dev, "%s: reset gpio device node not specified\n", + __func__); + return -EINVAL; + } + + if (!msm_cdc_pinctrl_get_state(aqt1000->aqt_rst_np)) { + rc = msm_cdc_pinctrl_select_sleep_state(aqt1000->aqt_rst_np); + if (rc) { + dev_err(dev, "%s: aqt sleep state request fail!\n", + __func__); + return rc; + } + + /* 20ms sleep required after pulling the reset gpio to LOW */ + msleep(20); + + rc = msm_cdc_pinctrl_select_active_state(aqt1000->aqt_rst_np); + if (rc) { + dev_err(dev, + "%s: aqt active state request fail, ret: %d\n", + __func__, rc); + return rc; + } + /* 20ms sleep required after pulling the reset gpio to HIGH */ + msleep(20); + } + + return rc; +} + +static int aqt1000_read_of_property_u32(struct device *dev, const char *name, + u32 *val) +{ + int rc = 0; + + rc = of_property_read_u32(dev->of_node, name, val); + if (rc) + dev_err(dev, "%s: Looking up %s property in node %s failed", + __func__, name, dev->of_node->full_name); + + return rc; +} + +static void aqt1000_dt_parse_micbias_info(struct device *dev, + struct aqt1000_micbias_setting *mb) +{ + u32 prop_val; + int rc; + + if (of_find_property(dev->of_node, "qcom,cdc-micbias-ldoh-v", NULL)) { + rc = aqt1000_read_of_property_u32(dev, + "qcom,cdc-micbias-ldoh-v", + &prop_val); + if (!rc) + mb->ldoh_v = (u8)prop_val; + } + + /* MB1 */ + if (of_find_property(dev->of_node, "qcom,cdc-micbias-cfilt1-mv", + NULL)) { + rc = aqt1000_read_of_property_u32(dev, + "qcom,cdc-micbias-cfilt1-mv", + &prop_val); + if (!rc) + mb->cfilt1_mv = prop_val; + + rc = aqt1000_read_of_property_u32(dev, + "qcom,cdc-micbias1-cfilt-sel", + &prop_val); + if (!rc) + mb->bias1_cfilt_sel = (u8)prop_val; + + } else if (of_find_property(dev->of_node, "qcom,cdc-micbias1-mv", + NULL)) { + rc = aqt1000_read_of_property_u32(dev, + "qcom,cdc-micbias1-mv", + &prop_val); + if (!rc) + mb->micb1_mv = prop_val; + } else { + dev_info(dev, "%s: Micbias1 DT property not found\n", + __func__); + } + + /* Print micbias info */ + dev_dbg(dev, "%s: ldoh_v %u cfilt1_mv %u micb1_mv %u \n", __func__, + (u32)mb->ldoh_v, (u32)mb->cfilt1_mv, (u32)mb->micb1_mv); +} + +static struct aqt1000_pdata *aqt1000_populate_dt_data(struct device *dev) +{ + struct aqt1000_pdata *pdata; + u32 prop_val; + + if (!dev || !dev->of_node) + return NULL; + + pdata = devm_kzalloc(dev, sizeof(struct aqt1000_pdata), + GFP_KERNEL); + if (!pdata) + return NULL; + + /* Parse power supplies */ + msm_cdc_get_power_supplies(dev, &pdata->regulator, + &pdata->num_supplies); + if (!pdata->regulator || (pdata->num_supplies <= 0)) { + dev_err(dev, "%s: no power supplies defined for codec\n", + __func__); + goto err_power_sup; + } + + /* Parse micbias info */ + aqt1000_dt_parse_micbias_info(dev, &pdata->micbias); + + pdata->aqt_rst_np = of_parse_phandle(dev->of_node, + "qcom,aqt-rst-gpio-node", 0); + if (!pdata->aqt_rst_np) { + dev_err(dev, "%s: Looking up %s property in node %s failed\n", + __func__, "qcom,aqt-rst-gpio-node", + dev->of_node->full_name); + goto err_parse_dt_prop; + } + + if (!(aqt1000_read_of_property_u32(dev, "qcom,cdc-ext-clk-rate", + &prop_val))) + pdata->ext_clk_rate = prop_val; + if (pdata->ext_clk_rate != AQT1000_CLK_24P576MHZ && + pdata->ext_clk_rate != AQT1000_CLK_19P2MHZ && + pdata->ext_clk_rate != AQT1000_CLK_12P288MHZ) { + /* Use the default ext_clk_rate if the DT value is wrong */ + pdata->ext_clk_rate = AQT1000_CLK_9P6MHZ; + } + + prop_val = 0; + if (!(aqt1000_read_of_property_u32(dev, "qcom,cdc-mclk-clk-rate", + &prop_val))) + pdata->mclk_rate = prop_val; + + if (pdata->mclk_rate != AQT1000_CLK_9P6MHZ && + pdata->mclk_rate != AQT1000_CLK_12P288MHZ) { + dev_err(dev, "%s: Invalid mclk_rate = %u\n", __func__, + pdata->mclk_rate); + goto err_parse_dt_prop; + } + if (pdata->ext_clk_rate % pdata->mclk_rate) { + dev_err(dev, + "%s: Invalid clock group, ext_clk = %d mclk = %d\n", + __func__, pdata->ext_clk_rate, pdata->mclk_rate); + goto err_parse_dt_prop; + } + + return pdata; + +err_parse_dt_prop: + devm_kfree(dev, pdata->regulator); + pdata->regulator = NULL; + pdata->num_supplies = 0; +err_power_sup: + devm_kfree(dev, pdata); + return NULL; +} + +static int aqt1000_bringdown(struct device *dev) +{ + /* No sequence for teardown */ + + return 0; +} + +static void aqt1000_device_exit(struct aqt1000 *aqt) +{ + aqt1000_bringdown(aqt->dev); + mutex_destroy(&aqt->io_lock); + mutex_destroy(&aqt->xfer_lock); + mutex_destroy(&aqt->cdc_bg_clk_lock); + mutex_destroy(&aqt->master_bias_lock); +} + +static int aqt1000_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct aqt1000 *aqt1000 = NULL; + struct aqt1000_pdata *pdata = NULL; + int ret = 0; + + pdata = aqt1000_populate_dt_data(&client->dev); + if (!pdata) { + dev_err(&client->dev, + "%s: Fail to obtain pdata from device tree\n", + __func__); + ret = -EINVAL; + goto fail; + } + client->dev.platform_data = pdata; + + aqt1000 = devm_kzalloc(&client->dev, sizeof(struct aqt1000), + GFP_KERNEL); + if (!aqt1000) { + ret = -ENOMEM; + goto fail; + } + + aqt1000->regmap = aqt1000_regmap_init(&client->dev, + &aqt1000_regmap_config); + if (IS_ERR(aqt1000->regmap)) { + ret = PTR_ERR(aqt1000->regmap); + dev_err(&client->dev, + "%s: Failed to init register map: %d\n", + __func__, ret); + goto fail; + } + aqt1000->aqt_rst_np = pdata->aqt_rst_np; + if (!aqt1000->aqt_rst_np) { + dev_err(&client->dev, "%s: pinctrl not used for rst_n\n", + __func__); + ret = -EINVAL; + goto fail; + } + + if (i2c_check_functionality(client->adapter, + I2C_FUNC_I2C) == 0) { + dev_dbg(&client->dev, "%s: can't talk I2C?\n", __func__); + ret = -EIO; + goto fail; + } + dev_set_drvdata(&client->dev, aqt1000); + aqt1000->dev = &client->dev; + aqt1000->dev_up = true; + aqt1000->mclk_rate = pdata->mclk_rate; + + aqt1000->num_of_supplies = pdata->num_supplies; + ret = msm_cdc_init_supplies(aqt1000->dev, &aqt1000->supplies, + pdata->regulator, + pdata->num_supplies); + if (!aqt1000->supplies) { + dev_err(aqt1000->dev, "%s: Cannot init aqt supplies\n", + __func__); + goto err_codec; + } + ret = msm_cdc_enable_static_supplies(aqt1000->dev, + aqt1000->supplies, + pdata->regulator, + pdata->num_supplies); + if (ret) { + dev_err(aqt1000->dev, "%s: aqt static supply enable failed!\n", + __func__); + goto err_codec; + } + /* 5 usec sleep is needed as per HW requirement */ + usleep_range(5, 10); + + ret = aqt1000_reset(aqt1000->dev); + if (ret) { + dev_err(aqt1000->dev, "%s: Codec reset failed\n", __func__); + goto err_supplies; + } + + aqt1000->i2c_dev.client = client; + aqt1000->read_dev = aqt1000_i2c_read; + aqt1000->write_dev = aqt1000_i2c_write; + + ret = aqt1000_device_init(aqt1000); + if (ret) { + pr_err("%s: error, initializing device failed (%d)\n", + __func__, ret); + goto err_supplies; + } + + ret = aqt_register_codec(&client->dev); + if (ret) { + dev_err(aqt1000->dev, "%s: Codec registration failed\n", + __func__); + goto err_cdc_register; + } + + return ret; + +err_cdc_register: + aqt1000_device_exit(aqt1000); +err_supplies: + msm_cdc_release_supplies(aqt1000->dev, aqt1000->supplies, + pdata->regulator, + pdata->num_supplies); + pdata->regulator = NULL; + pdata->num_supplies = 0; +err_codec: + devm_kfree(&client->dev, aqt1000); + dev_set_drvdata(&client->dev, NULL); +fail: + return ret; +} + +static int aqt1000_i2c_remove(struct i2c_client *client) +{ + struct aqt1000 *aqt; + struct aqt1000_pdata *pdata = client->dev.platform_data; + + aqt = dev_get_drvdata(&client->dev); + + msm_cdc_release_supplies(aqt->dev, aqt->supplies, + pdata->regulator, + pdata->num_supplies); + aqt1000_device_exit(aqt); + dev_set_drvdata(&client->dev, NULL); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int aqt1000_i2c_resume(struct device *dev) +{ + pr_debug("%s system resume\n", __func__); + return 0; +} + +static int aqt1000_i2c_suspend(struct device *dev) +{ + pr_debug("%s system suspend\n", __func__); + return 0; +} +#endif + +static struct i2c_device_id aqt1000_id_table[] = { + {"aqt1000-i2c", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, aqt1000_id_table); + +static const struct dev_pm_ops aqt1000_i2c_pm_ops = { + .suspend = aqt1000_i2c_suspend, + .resume = aqt1000_i2c_resume, +}; + +static const struct of_device_id aqt_match_table[] = { + {.compatible = "qcom,aqt1000-i2c-codec"}, + {} +}; +MODULE_DEVICE_TABLE(of, aqt_match_table); + +static struct i2c_driver aqt1000_i2c_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "aqt1000-i2c-codec", +#ifdef CONFIG_PM_SLEEP + .pm = &aqt1000_i2c_pm_ops, +#endif + .of_match_table = aqt_match_table, + }, + .id_table = aqt1000_id_table, + .probe = aqt1000_i2c_probe, + .remove = aqt1000_i2c_remove, +}; + +static int __init aqt1000_init(void) +{ + return i2c_add_driver(&aqt1000_i2c_driver); +} +module_init(aqt1000_init); + +static void __exit aqt1000_exit(void) +{ + i2c_del_driver(&aqt1000_i2c_driver); +} +module_exit(aqt1000_exit); + +MODULE_DESCRIPTION("AQT1000 Codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/aqt1000/aqt1000-internal.h b/asoc/codecs/aqt1000/aqt1000-internal.h new file mode 100644 index 000000000000..1ce0005fc64d --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-internal.h @@ -0,0 +1,181 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _AQT1000_INTERNAL_H +#define _AQT1000_INTERNAL_H + +#include +#include +#include + +#define AQT1000_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\ + SNDRV_PCM_RATE_384000) +/* Fractional Rates */ +#define AQT1000_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_176400) + +#define AQT1000_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE) + +#define AQT1000_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +#define AQT1000_FORMATS_S16_LE (SNDRV_PCM_FMTBIT_S16_LE) + +/* Macros for packing register writes into a U32 */ +#define AQT1000_PACKED_REG_SIZE sizeof(u32) +#define AQT1000_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \ + do { \ + ((reg) = ((packed >> 16) & (0xffff))); \ + ((mask) = ((packed >> 8) & (0xff))); \ + ((val) = ((packed) & (0xff))); \ + } while (0) + +#define STRING(name) #name +#define AQT_DAPM_ENUM(name, reg, offset, text) \ +static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ +static const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_ENUM(STRING(name), name##_enum) + +#define AQT_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \ +static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ +static const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname) + +#define AQT_DAPM_MUX(name, shift, kctl) \ + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux) + + +#define AQT1000_INTERP_MUX_NUM_INPUTS 3 +#define AQT1000_RX_PATH_CTL_OFFSET 20 + +#define BYTE_BIT_MASK(nr) (1 << ((nr) % BITS_PER_BYTE)) + +#define AQT1000_REG_BITS 8 +#define AQT1000_MAX_VALID_ADC_MUX 3 + +#define AQT1000_AMIC_PWR_LEVEL_LP 0 +#define AQT1000_AMIC_PWR_LEVEL_DEFAULT 1 +#define AQT1000_AMIC_PWR_LEVEL_HP 2 +#define AQT1000_AMIC_PWR_LVL_MASK 0x60 +#define AQT1000_AMIC_PWR_LVL_SHIFT 0x5 + +#define AQT1000_DEC_PWR_LVL_MASK 0x06 +#define AQT1000_DEC_PWR_LVL_DF 0x00 +#define AQT1000_DEC_PWR_LVL_LP 0x02 +#define AQT1000_DEC_PWR_LVL_HP 0x04 +#define AQT1000_STRING_LEN 100 + +#define AQT1000_CDC_SIDETONE_IIR_COEFF_MAX 5 + +#define AQT1000_MAX_MICBIAS 1 +#define DAPM_MICBIAS1_STANDALONE "MIC BIAS1 Standalone" + +#define TX_HPF_CUT_OFF_FREQ_MASK 0x60 +#define CF_MIN_3DB_4HZ 0x0 +#define CF_MIN_3DB_75HZ 0x1 +#define CF_MIN_3DB_150HZ 0x2 + +enum { + AUDIO_NOMINAL, + HPH_PA_DELAY, + CLSH_Z_CONFIG, + ANC_MIC_AMIC1, + ANC_MIC_AMIC2, + ANC_MIC_AMIC3, +}; + +enum { + MIC_BIAS_1 = 1, +}; + +enum { + MICB_PULLUP_ENABLE, + MICB_PULLUP_DISABLE, + MICB_ENABLE, + MICB_DISABLE, +}; + +enum { + INTn_1_INP_SEL_ZERO = 0, + INTn_1_INP_SEL_DEC0, + INTn_1_INP_SEL_DEC1, + INTn_1_INP_SEL_IIR0, + INTn_1_INP_SEL_IIR1, + INTn_1_INP_SEL_RX0, + INTn_1_INP_SEL_RX1, +}; + +enum { + INTn_2_INP_SEL_ZERO = 0, + INTn_2_INP_SEL_RX0, + INTn_2_INP_SEL_RX1, + INTn_2_INP_SEL_PROXIMITY, +}; + +/* Codec supports 2 IIR filters */ +enum { + IIR0 = 0, + IIR1, + IIR_MAX, +}; + +enum { + ASRC_IN_HPHL, + ASRC_IN_HPHR, + ASRC_INVALID, +}; + +enum { + CONV_88P2K_TO_384K, + CONV_96K_TO_352P8K, + CONV_352P8K_TO_384K, + CONV_384K_TO_352P8K, + CONV_384K_TO_384K, + CONV_96K_TO_384K, +}; + +enum aqt_notify_event { + AQT_EVENT_INVALID, + /* events for micbias ON and OFF */ + AQT_EVENT_PRE_MICBIAS_1_OFF, + AQT_EVENT_POST_MICBIAS_1_OFF, + AQT_EVENT_PRE_MICBIAS_1_ON, + AQT_EVENT_POST_MICBIAS_1_ON, + AQT_EVENT_PRE_DAPM_MICBIAS_1_OFF, + AQT_EVENT_POST_DAPM_MICBIAS_1_OFF, + AQT_EVENT_PRE_DAPM_MICBIAS_1_ON, + AQT_EVENT_POST_DAPM_MICBIAS_1_ON, + /* events for PA ON and OFF */ + AQT_EVENT_PRE_HPHL_PA_ON, + AQT_EVENT_POST_HPHL_PA_OFF, + AQT_EVENT_PRE_HPHR_PA_ON, + AQT_EVENT_POST_HPHR_PA_OFF, + AQT_EVENT_PRE_HPHL_PA_OFF, + AQT_EVENT_PRE_HPHR_PA_OFF, + AQT_EVENT_OCP_OFF, + AQT_EVENT_OCP_ON, + AQT_EVENT_LAST, +}; + +struct interp_sample_rate { + int sample_rate; + int rate_val; +}; + +extern struct regmap_config aqt1000_regmap_config; +extern int aqt_register_codec(struct device *dev); + +#endif /* _AQT1000_INTERNAL_H */ diff --git a/asoc/codecs/aqt1000/aqt1000-irq.c b/asoc/codecs/aqt1000/aqt1000-irq.c new file mode 100644 index 000000000000..e01dc4602379 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-irq.c @@ -0,0 +1,185 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "aqt1000-registers.h" +#include "aqt1000-irq.h" + + +static int aqt_irq_init(struct aqt1000_irq *aqt_irq) +{ + int i, ret; + + if (aqt_irq == NULL) { + pr_err("%s: aqt_irq is NULL\n", __func__); + return -EINVAL; + } + mutex_init(&aqt_irq->irq_lock); + mutex_init(&aqt_irq->nested_irq_lock); + + aqt_irq->irq = aqt_irq_get_upstream_irq(aqt_irq); + if (!aqt_irq->irq) { + pr_warn("%s: irq driver is not yet initialized\n", __func__); + mutex_destroy(&aqt_irq->irq_lock); + mutex_destroy(&aqt_irq->nested_irq_lock); + return -EPROBE_DEFER; + } + pr_debug("%s: probed irq %d\n", __func__, aqt_irq->irq); + + /* Setup downstream IRQs */ + ret = aqt_irq_setup_downstream_irq(aqt_irq); + if (ret) { + pr_err("%s: Failed to setup downstream IRQ\n", __func__); + goto fail_irq_init; + } + + /* mask all the interrupts */ + for (i = 0; i < aqt_irq->num_irqs; i++) { + aqt_irq->irq_masks_cur |= BYTE_BIT_MASK(i); + aqt_irq->irq_masks_cache |= BYTE_BIT_MASK(i); + } + + ret = request_threaded_irq(aqt_irq->irq, NULL, aqt_irq_thread, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "aqt", aqt_irq); + if (ret != 0) { + dev_err(aqt_irq->dev, "Failed to request IRQ %d: %d\n", + aqt_irq->irq, ret); + } else { + ret = enable_irq_wake(aqt_irq->irq); + if (ret) { + dev_err(aqt_irq->dev, + "Failed to set wake interrupt on IRQ %d: %d\n", + aqt_irq->irq, ret); + free_irq(aqt_irq->irq, aqt_irq); + } + } + + if (ret) + goto fail_irq_init; + + return ret; + +fail_irq_init: + dev_err(aqt_irq->dev, + "%s: Failed to init aqt irq\n", __func__); + aqt_irq_put_upstream_irq(aqt_irq); + mutex_destroy(&aqt_irq->irq_lock); + mutex_destroy(&aqt_irq->nested_irq_lock); + return ret; +} + +static int aqt_irq_probe(struct platform_device *pdev) +{ + int irq; + struct aqt1000_irq *aqt_irq = NULL; + int ret = -EINVAL; + + irq = platform_get_irq_byname(pdev, "aqt-int"); + if (irq < 0) { + dev_err(&pdev->dev, "%s: Couldn't find aqt-int node(%d)\n", + __func__, irq); + return -EINVAL; + } + aqt_irq = kzalloc(sizeof(*aqt_irq), GFP_KERNEL); + if (!aqt_irq) + return -ENOMEM; + /* + * AQT interrupt controller supports N to N irq mapping with + * single cell binding with irq numbers(offsets) only. + * Use irq_domain_simple_ops that has irq_domain_simple_map and + * irq_domain_xlate_onetwocell. + */ + aqt_irq->dev = &pdev->dev; + aqt_irq->domain = irq_domain_add_linear(aqt_irq->dev->of_node, + WSA_NUM_IRQS, &irq_domain_simple_ops, + aqt_irq); + if (!aqt_irq->domain) { + dev_err(&pdev->dev, "%s: domain is NULL\n", __func__); + ret = -ENOMEM; + goto err; + } + aqt_irq->dev = &pdev->dev; + + dev_dbg(&pdev->dev, "%s: virq = %d\n", __func__, irq); + aqt_irq->irq = irq; + aqt_irq->num_irq_regs = 2; + aqt_irq->num_irqs = WSA_NUM_IRQS; + ret = aqt_irq_init(aqt_irq); + if (ret < 0) { + dev_err(&pdev->dev, "%s: failed to do irq init %d\n", + __func__, ret); + goto err; + } + + return ret; +err: + kfree(aqt_irq); + return ret; +} + +static int aqt_irq_remove(struct platform_device *pdev) +{ + struct irq_domain *domain; + struct aqt1000_irq *data; + + domain = irq_find_host(pdev->dev.of_node); + if (unlikely(!domain)) { + pr_err("%s: domain is NULL\n", __func__); + return -EINVAL; + } + data = (struct aqt_irq *)domain->host_data; + data->irq = 0; + + return 0; +} + +static const struct of_device_id of_match[] = { + { .compatible = "qcom,aqt-irq" }, + { } +}; + +static struct platform_driver aqt_irq_driver = { + .probe = aqt_irq_probe, + .remove = aqt_irq_remove, + .driver = { + .name = "aqt_intc", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(of_match), + }, +}; + +static int aqt_irq_drv_init(void) +{ + return platform_driver_register(&aqt_irq_driver); +} +subsys_initcall(aqt_irq_drv_init); + +static void aqt_irq_drv_exit(void) +{ + platform_driver_unregister(&aqt_irq_driver); +} +module_exit(aqt_irq_drv_exit); + +MODULE_DESCRIPTION("AQT1000 IRQ driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/aqt1000/aqt1000-irq.h b/asoc/codecs/aqt1000/aqt1000-irq.h new file mode 100644 index 000000000000..dd5b1166a19d --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-irq.h @@ -0,0 +1,73 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __AQT1000_IRQ_H_ +#define __AQT1000_IRQ_H_ + +#include +#include + +enum { + /* INTR_CTRL_INT_MASK_2 */ + AQT1000_IRQ_MBHC_BUTTON_RELEASE_DET = 0, + AQT1000_IRQ_MBHC_BUTTON_PRESS_DET, + AQT1000_IRQ_MBHC_ELECT_INS_REM_DET, + AQT1000_IRQ_MBHC_ELECT_INS_REM_LEG_DET, + AQT1000_IRQ_MBHC_SW_DET, + AQT1000_IRQ_HPH_PA_OCPL_FAULT, + AQT1000_IRQ_HPH_PA_OCPR_FAULT, + AQT1000_IRQ_HPH_PA_CNPL_COMPLETE, + + /* INTR_CTRL_INT_MASK_3 */ + AQT1000_IRQ_HPH_PA_CNPR_COMPLETE, + AQT1000_CDC_HPHL_SURGE, + AQT1000_CDC_HPHR_SURGE, + AQT1000_PLL_LOCK_LOSS, + AQT1000_FLL_LOCK_LOSS, + AQT1000_DSD_INT, + AQT1000_NUM_IRQS, +}; + +/** + * struct aqt_irq - AQT IRQ resource structure + * @irq_lock: lock used by irq_chip functions. + * @nested_irq_lock: lock used while handling nested interrupts. + * @irq: interrupt number. + * @irq_masks_cur: current mask value to be written to mask registers. + * @irq_masks_cache: cached mask value. + * @num_irqs: number of supported interrupts. + * @num_irq_regs: number of irq registers. + * @parent: parent pointer. + * @dev: device pointer. + * @domain: irq domain pointer. + * + * Contains required members used in wsa irq driver. + */ + +struct aqt1000_irq { + struct mutex irq_lock; + struct mutex nested_irq_lock; + unsigned int irq; + u8 irq_masks_cur; + u8 irq_masks_cache; + bool irq_level_high[8]; + int num_irqs; + int num_irq_regs; + void *parent; + struct device *dev; + struct irq_domain *domain; +}; + +int aqt_irq_init(void); +void aqt_irq_exit(void); + +#endif /* __AQT1000_IRQ_H_ */ diff --git a/asoc/codecs/aqt1000/aqt1000-mbhc.c b/asoc/codecs/aqt1000/aqt1000-mbhc.c new file mode 100644 index 000000000000..2f7e470649de --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-mbhc.c @@ -0,0 +1,1133 @@ +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "aqt.h" +#include "aqt-mbhc.h" +#include +#include "aqt_irq.h" +#include "pdata.h" +#include "../wcd9xxx-irq.h" +#include "../wcdcal-hwdep.h" +#include "../wcd-mbhc-v2-api.h" + +#define AQT_ZDET_SUPPORTED true +/* Z value defined in milliohm */ +#define AQT_ZDET_VAL_32 32000 +#define AQT_ZDET_VAL_400 400000 +#define AQT_ZDET_VAL_1200 1200000 +#define AQT_ZDET_VAL_100K 100000000 +/* Z floating defined in ohms */ +#define AQT_ZDET_FLOATING_IMPEDANCE 0x0FFFFFFE + +#define AQT_ZDET_NUM_MEASUREMENTS 900 +#define AQT_MBHC_GET_C1(c) ((c & 0xC000) >> 14) +#define AQT_MBHC_GET_X1(x) (x & 0x3FFF) +/* Z value compared in milliOhm */ +#define AQT_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000)) +#define AQT_MBHC_ZDET_CONST (86 * 16384) +#define AQT_MBHC_MOISTURE_RREF R_24_KOHM + +static struct wcd_mbhc_register + wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = { + WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN", + AQT_ANA_MBHC_MECH, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_DET_EN", + AQT_ANA_MBHC_MECH, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MECH_DETECTION_TYPE", + AQT_ANA_MBHC_MECH, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_CLAMP_CTL", + AQT_MBHC_NEW_PLUG_DETECT_CTL, 0x30, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_DETECTION_TYPE", + AQT_ANA_MBHC_ELECT, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_CTRL", + AQT_MBHC_NEW_PLUG_DETECT_CTL, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL", + AQT_ANA_MBHC_MECH, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PLUG_TYPE", + AQT_ANA_MBHC_MECH, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_PLUG_TYPE", + AQT_ANA_MBHC_MECH, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SW_HPH_LP_100K_TO_GND", + AQT_ANA_MBHC_MECH, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_SCHMT_ISRC", + AQT_ANA_MBHC_ELECT, 0x06, 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_EN", + AQT_ANA_MBHC_ELECT, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_INSREM_DBNC", + AQT_MBHC_NEW_PLUG_DETECT_CTL, 0x0F, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_DBNC", + AQT_MBHC_NEW_CTL_1, 0x03, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_VREF", + AQT_MBHC_NEW_CTL_2, 0x03, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT", + AQT_ANA_MBHC_RESULT_3, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT", + AQT_ANA_MBHC_RESULT_3, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT", + AQT_ANA_MBHC_RESULT_3, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_SCHMT_RESULT", + AQT_ANA_MBHC_RESULT_3, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_OCP_FSM_EN", + AQT_HPH_OCP_CTL, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_RESULT", + AQT_ANA_MBHC_RESULT_3, 0x07, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_ISRC_CTL", + AQT_ANA_MBHC_ELECT, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT", + AQT_ANA_MBHC_RESULT_3, 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL", + AQT_ANA_MICB2, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME", + AQT_HPH_CNP_WG_TIME, 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN", + AQT_ANA_HPH, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PA_EN", + AQT_ANA_HPH, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_PA_EN", + AQT_ANA_HPH, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE", + AQT_ANA_MBHC_RESULT_3, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL", + 0, 0, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN", + AQT_MBHC_CTL_BCS, 0x02, 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_STATUS", + AQT_MBHC_STATUS_SPARE_1, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL", + AQT_MBHC_NEW_CTL_2, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_DET_EN", + AQT_HPH_L_TEST, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_DET_EN", + AQT_HPH_R_TEST, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_STATUS", + AQT_INTR_PIN1_STATUS0, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_STATUS", + AQT_INTR_PIN1_STATUS0, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_EN", + AQT_MBHC_NEW_CTL_1, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_COMPLETE", AQT_MBHC_NEW_FSM_STATUS, + 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_TIMEOUT", AQT_MBHC_NEW_FSM_STATUS, + 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_RESULT", AQT_MBHC_NEW_ADC_RESULT, + 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB2_VOUT", AQT_ANA_MICB2, 0x3F, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_MODE", + AQT_MBHC_NEW_CTL_1, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_DETECTION_DONE", + AQT_MBHC_NEW_CTL_1, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_ISRC_EN", + AQT_ANA_MBHC_ZDET, 0x02, 1, 0), +}; + +static const struct wcd_mbhc_intr intr_ids = { + .mbhc_sw_intr = AQT_IRQ_MBHC_SW_DET, + .mbhc_btn_press_intr = AQT_IRQ_MBHC_BUTTON_PRESS_DET, + .mbhc_btn_release_intr = AQT_IRQ_MBHC_BUTTON_RELEASE_DET, + .mbhc_hs_ins_intr = AQT_IRQ_MBHC_ELECT_INS_REM_LEG_DET, + .mbhc_hs_rem_intr = AQT_IRQ_MBHC_ELECT_INS_REM_DET, + .hph_left_ocp = AQT_IRQ_HPH_PA_OCPL_FAULT, + .hph_right_ocp = AQT_IRQ_HPH_PA_OCPR_FAULT, +}; + + +static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = { + "cdc-vdd-mic-bias", +}; + +struct aqt_mbhc_zdet_param { + u16 ldo_ctl; + u16 noff; + u16 nshift; + u16 btn5; + u16 btn6; + u16 btn7; +}; + +static int aqt_mbhc_request_irq(struct snd_soc_codec *codec, + int irq, irq_handler_t handler, + const char *name, void *data) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + + return wcd9xxx_request_irq(core_res, irq, handler, name, data); +} + +static void aqt_mbhc_irq_control(struct snd_soc_codec *codec, + int irq, bool enable) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + if (enable) + wcd9xxx_enable_irq(core_res, irq); + else + wcd9xxx_disable_irq(core_res, irq); +} + +static int aqt_mbhc_free_irq(struct snd_soc_codec *codec, + int irq, void *data) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + + wcd9xxx_free_irq(core_res, irq, data); + return 0; +} + +static void aqt_mbhc_clk_setup(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) + snd_soc_update_bits(codec, AQT_MBHC_NEW_CTL_1, + 0x80, 0x80); + else + snd_soc_update_bits(codec, AQT_MBHC_NEW_CTL_1, + 0x80, 0x00); +} + +static int aqt_mbhc_btn_to_num(struct snd_soc_codec *codec) +{ + return snd_soc_read(codec, AQT_ANA_MBHC_RESULT_3) & 0x7; +} + +static int aqt_enable_ext_mb_source(struct wcd_mbhc *mbhc, + bool turn_on) +{ + struct aqt_mbhc *aqt_mbhc; + struct snd_soc_codec *codec = mbhc->codec; + struct aqt_on_demand_supply *supply; + int ret = 0; + + aqt_mbhc = container_of(mbhc, struct aqt_mbhc, wcd_mbhc); + + supply = &aqt_mbhc->on_demand_list[AQT_ON_DEMAND_MICBIAS]; + if (!supply->supply) { + dev_dbg(codec->dev, "%s: warning supply not present ond for %s\n", + __func__, "onDemand Micbias"); + return ret; + } + + dev_dbg(codec->dev, "%s turn_on: %d count: %d\n", __func__, turn_on, + supply->ondemand_supply_count); + + if (turn_on) { + if (!(supply->ondemand_supply_count)) { + ret = snd_soc_dapm_force_enable_pin( + snd_soc_codec_get_dapm(codec), + "MICBIAS_REGULATOR"); + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + } + supply->ondemand_supply_count++; + } else { + if (supply->ondemand_supply_count > 0) + supply->ondemand_supply_count--; + if (!(supply->ondemand_supply_count)) { + ret = snd_soc_dapm_disable_pin( + snd_soc_codec_get_dapm(codec), + "MICBIAS_REGULATOR"); + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + } + } + + if (ret) + dev_err(codec->dev, "%s: Failed to %s external micbias source\n", + __func__, turn_on ? "enable" : "disabled"); + else + dev_dbg(codec->dev, "%s: %s external micbias source\n", + __func__, turn_on ? "Enabled" : "Disabled"); + + return ret; +} + +static void aqt_mbhc_mbhc_bias_control(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) + snd_soc_update_bits(codec, AQT_ANA_MBHC_ELECT, + 0x01, 0x01); + else + snd_soc_update_bits(codec, AQT_ANA_MBHC_ELECT, + 0x01, 0x00); +} + +static void aqt_mbhc_program_btn_thr(struct snd_soc_codec *codec, + s16 *btn_low, s16 *btn_high, + int num_btn, bool is_micbias) +{ + int i; + int vth; + + if (num_btn > WCD_MBHC_DEF_BUTTONS) { + dev_err(codec->dev, "%s: invalid number of buttons: %d\n", + __func__, num_btn); + return; + } + /* + * Tavil just needs one set of thresholds for button detection + * due to micbias voltage ramp to pullup upon button press. So + * btn_low and is_micbias are ignored and always program button + * thresholds using btn_high. + */ + for (i = 0; i < num_btn; i++) { + vth = ((btn_high[i] * 2) / 25) & 0x3F; + snd_soc_update_bits(codec, AQT_ANA_MBHC_BTN0 + i, + 0xFC, vth << 2); + dev_dbg(codec->dev, "%s: btn_high[%d]: %d, vth: %d\n", + __func__, i, btn_high[i], vth); + } +} + +static bool aqt_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock) +{ + struct snd_soc_codec *codec = mbhc->codec; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_core_resource *core_res = + &wcd9xxx->core_res; + bool ret = 0; + + if (lock) + ret = wcd9xxx_lock_sleep(core_res); + else + wcd9xxx_unlock_sleep(core_res); + + return ret; +} + +static int aqt_mbhc_register_notifier(struct wcd_mbhc *mbhc, + struct notifier_block *nblock, + bool enable) +{ + struct aqt_mbhc *aqt_mbhc; + + aqt_mbhc = container_of(mbhc, struct aqt_mbhc, wcd_mbhc); + + if (enable) + return blocking_notifier_chain_register(&aqt_mbhc->notifier, + nblock); + else + return blocking_notifier_chain_unregister( + &aqt_mbhc->notifier, nblock); +} + +static bool aqt_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) +{ + u8 val; + + if (micb_num == MIC_BIAS_2) { + val = (snd_soc_read(mbhc->codec, AQT_ANA_MICB2) >> 6); + if (val == 0x01) + return true; + } + return false; +} + +static bool aqt_mbhc_hph_pa_on_status(struct snd_soc_codec *codec) +{ + return (snd_soc_read(codec, AQT_ANA_HPH) & 0xC0) ? true : false; +} + +static void aqt_mbhc_hph_l_pull_up_control( + struct snd_soc_codec *codec, + enum mbhc_hs_pullup_iref pull_up_cur) +{ + /* Default pull up current to 2uA */ + if (pull_up_cur < I_OFF || pull_up_cur > I_3P0_UA || + pull_up_cur == I_DEFAULT) + pull_up_cur = I_2P0_UA; + + dev_dbg(codec->dev, "%s: HS pull up current:%d\n", + __func__, pull_up_cur); + + snd_soc_update_bits(codec, AQT_MBHC_NEW_PLUG_DETECT_CTL, + 0xC0, pull_up_cur << 6); +} + +static int aqt_mbhc_request_micbias(struct snd_soc_codec *codec, + int micb_num, int req) +{ + int ret; + + /* + * If micbias is requested, make sure that there + * is vote to enable mclk + */ + if (req == MICB_ENABLE) + aqt_cdc_mclk_enable(codec, true); + + ret = aqt_micbias_control(codec, micb_num, req, false); + + /* + * Release vote for mclk while requesting for + * micbias disable + */ + if (req == MICB_DISABLE) + aqt_cdc_mclk_enable(codec, false); + + return ret; +} + +static void aqt_mbhc_micb_ramp_control(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, AQT_ANA_MICB2_RAMP, + 0x1C, 0x0C); + snd_soc_update_bits(codec, AQT_ANA_MICB2_RAMP, + 0x80, 0x80); + } else { + snd_soc_update_bits(codec, AQT_ANA_MICB2_RAMP, + 0x80, 0x00); + snd_soc_update_bits(codec, AQT_ANA_MICB2_RAMP, + 0x1C, 0x00); + } +} + +static struct firmware_cal *aqt_get_hwdep_fw_cal(struct wcd_mbhc *mbhc, + enum wcd_cal_type type) +{ + struct aqt_mbhc *aqt_mbhc; + struct firmware_cal *hwdep_cal; + struct snd_soc_codec *codec = mbhc->codec; + + aqt_mbhc = container_of(mbhc, struct aqt_mbhc, wcd_mbhc); + + if (!codec) { + pr_err("%s: NULL codec pointer\n", __func__); + return NULL; + } + hwdep_cal = wcdcal_get_fw_cal(aqt_mbhc->fw_data, type); + if (!hwdep_cal) + dev_err(codec->dev, "%s: cal not sent by %d\n", + __func__, type); + + return hwdep_cal; +} + +static int aqt_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec, + int micb_num, bool req_en) +{ + struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + int rc, micb_mv; + + if (micb_num != MIC_BIAS_2) + return -EINVAL; + + /* + * If device tree micbias level is already above the minimum + * voltage needed to detect threshold microphone, then do + * not change the micbias, just return. + */ + if (pdata->micbias.micb2_mv >= WCD_MBHC_THR_HS_MICB_MV) + return 0; + + micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb2_mv; + + rc = aqt_mbhc_micb_adjust_voltage(codec, micb_mv, MIC_BIAS_2); + + return rc; +} + +static inline void aqt_mbhc_get_result_params(struct wcd9xxx *wcd9xxx, + s16 *d1_a, u16 noff, + int32_t *zdet) +{ + int i; + int val, val1; + s16 c1; + s32 x1, d1; + int32_t denom; + int minCode_param[] = { + 3277, 1639, 820, 410, 205, 103, 52, 26 + }; + + regmap_update_bits(wcd9xxx->regmap, AQT_ANA_MBHC_ZDET, 0x20, 0x20); + for (i = 0; i < AQT_ZDET_NUM_MEASUREMENTS; i++) { + regmap_read(wcd9xxx->regmap, AQT_ANA_MBHC_RESULT_2, &val); + if (val & 0x80) + break; + } + val = val << 0x8; + regmap_read(wcd9xxx->regmap, AQT_ANA_MBHC_RESULT_1, &val1); + val |= val1; + regmap_update_bits(wcd9xxx->regmap, AQT_ANA_MBHC_ZDET, 0x20, 0x00); + x1 = AQT_MBHC_GET_X1(val); + c1 = AQT_MBHC_GET_C1(val); + /* If ramp is not complete, give additional 5ms */ + if ((c1 < 2) && x1) + usleep_range(5000, 5050); + + if (!c1 || !x1) { + dev_dbg(wcd9xxx->dev, + "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n", + __func__, c1, x1); + goto ramp_down; + } + d1 = d1_a[c1]; + denom = (x1 * d1) - (1 << (14 - noff)); + if (denom > 0) + *zdet = (AQT_MBHC_ZDET_CONST * 1000) / denom; + else if (x1 < minCode_param[noff]) + *zdet = AQT_ZDET_FLOATING_IMPEDANCE; + + dev_dbg(wcd9xxx->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n", + __func__, d1, c1, x1, *zdet); +ramp_down: + i = 0; + while (x1) { + regmap_bulk_read(wcd9xxx->regmap, + AQT_ANA_MBHC_RESULT_1, (u8 *)&val, 2); + x1 = AQT_MBHC_GET_X1(val); + i++; + if (i == AQT_ZDET_NUM_MEASUREMENTS) + break; + } +} + +static void aqt_mbhc_zdet_ramp(struct snd_soc_codec *codec, + struct aqt_mbhc_zdet_param *zdet_param, + int32_t *zl, int32_t *zr, s16 *d1_a) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + int32_t zdet = 0; + + snd_soc_update_bits(codec, AQT_MBHC_NEW_ZDET_ANA_CTL, 0x70, + zdet_param->ldo_ctl << 4); + snd_soc_update_bits(codec, AQT_ANA_MBHC_BTN5, 0xFC, + zdet_param->btn5); + snd_soc_update_bits(codec, AQT_ANA_MBHC_BTN6, 0xFC, + zdet_param->btn6); + snd_soc_update_bits(codec, AQT_ANA_MBHC_BTN7, 0xFC, + zdet_param->btn7); + snd_soc_update_bits(codec, AQT_MBHC_NEW_ZDET_ANA_CTL, 0x0F, + zdet_param->noff); + snd_soc_update_bits(codec, AQT_MBHC_NEW_ZDET_RAMP_CTL, 0x0F, + zdet_param->nshift); + + if (!zl) + goto z_right; + /* Start impedance measurement for HPH_L */ + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_ZDET, 0x80, 0x80); + dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_L, noff = %d\n", + __func__, zdet_param->noff); + aqt_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet); + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_ZDET, 0x80, 0x00); + + *zl = zdet; + +z_right: + if (!zr) + return; + /* Start impedance measurement for HPH_R */ + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_ZDET, 0x40, 0x40); + dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_R, noff = %d\n", + __func__, zdet_param->noff); + aqt_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet); + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_ZDET, 0x40, 0x00); + + *zr = zdet; +} + +static inline void aqt_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec, + int32_t *z_val, int flag_l_r) +{ + s16 q1; + int q1_cal; + + if (*z_val < (AQT_ZDET_VAL_400/1000)) + q1 = snd_soc_read(codec, + AQT_CHIP_TIER_CTRL_EFUSE_VAL_OUT1 + (2 * flag_l_r)); + else + q1 = snd_soc_read(codec, + AQT_CHIP_TIER_CTRL_EFUSE_VAL_OUT2 + (2 * flag_l_r)); + if (q1 & 0x80) + q1_cal = (10000 - ((q1 & 0x7F) * 25)); + else + q1_cal = (10000 + (q1 * 25)); + if (q1_cal > 0) + *z_val = ((*z_val) * 10000) / q1_cal; +} + +static void aqt_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, + uint32_t *zr) +{ + struct snd_soc_codec *codec = mbhc->codec; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + s16 reg0, reg1, reg2, reg3, reg4; + int32_t z1L, z1R, z1Ls; + int zMono, z_diff1, z_diff2; + bool is_fsm_disable = false; + struct aqt_mbhc_zdet_param zdet_param[] = { + {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */ + {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */ + {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */ + {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */ + }; + struct aqt_mbhc_zdet_param *zdet_param_ptr = NULL; + s16 d1_a[][4] = { + {0, 30, 90, 30}, + {0, 30, 30, 5}, + {0, 30, 30, 5}, + {0, 30, 30, 5}, + }; + s16 *d1 = NULL; + + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + + reg0 = snd_soc_read(codec, AQT_ANA_MBHC_BTN5); + reg1 = snd_soc_read(codec, AQT_ANA_MBHC_BTN6); + reg2 = snd_soc_read(codec, AQT_ANA_MBHC_BTN7); + reg3 = snd_soc_read(codec, AQT_MBHC_CTL_CLK); + reg4 = snd_soc_read(codec, AQT_MBHC_NEW_ZDET_ANA_CTL); + + if (snd_soc_read(codec, AQT_ANA_MBHC_ELECT) & 0x80) { + is_fsm_disable = true; + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_ELECT, 0x80, 0x00); + } + + /* For NO-jack, disable L_DET_EN before Z-det measurements */ + if (mbhc->hphl_swh) + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_MECH, 0x80, 0x00); + + /* Turn off 100k pull down on HPHL */ + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_MECH, 0x01, 0x00); + + /* First get impedance on Left */ + d1 = d1_a[1]; + zdet_param_ptr = &zdet_param[1]; + aqt_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + + if (!AQT_MBHC_IS_SECOND_RAMP_REQUIRED(z1L)) + goto left_ch_impedance; + + /* Second ramp for left ch */ + if (z1L < AQT_ZDET_VAL_32) { + zdet_param_ptr = &zdet_param[0]; + d1 = d1_a[0]; + } else if ((z1L > AQT_ZDET_VAL_400) && (z1L <= AQT_ZDET_VAL_1200)) { + zdet_param_ptr = &zdet_param[2]; + d1 = d1_a[2]; + } else if (z1L > AQT_ZDET_VAL_1200) { + zdet_param_ptr = &zdet_param[3]; + d1 = d1_a[3]; + } + aqt_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + +left_ch_impedance: + if ((z1L == AQT_ZDET_FLOATING_IMPEDANCE) || + (z1L > AQT_ZDET_VAL_100K)) { + *zl = AQT_ZDET_FLOATING_IMPEDANCE; + zdet_param_ptr = &zdet_param[1]; + d1 = d1_a[1]; + } else { + *zl = z1L/1000; + aqt_wcd_mbhc_qfuse_cal(codec, zl, 0); + } + dev_dbg(codec->dev, "%s: impedance on HPH_L = %d(ohms)\n", + __func__, *zl); + + /* Start of right impedance ramp and calculation */ + aqt_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + if (AQT_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) { + if (((z1R > AQT_ZDET_VAL_1200) && + (zdet_param_ptr->noff == 0x6)) || + ((*zl) != AQT_ZDET_FLOATING_IMPEDANCE)) + goto right_ch_impedance; + /* Second ramp for right ch */ + if (z1R < AQT_ZDET_VAL_32) { + zdet_param_ptr = &zdet_param[0]; + d1 = d1_a[0]; + } else if ((z1R > AQT_ZDET_VAL_400) && + (z1R <= AQT_ZDET_VAL_1200)) { + zdet_param_ptr = &zdet_param[2]; + d1 = d1_a[2]; + } else if (z1R > AQT_ZDET_VAL_1200) { + zdet_param_ptr = &zdet_param[3]; + d1 = d1_a[3]; + } + aqt_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + } +right_ch_impedance: + if ((z1R == AQT_ZDET_FLOATING_IMPEDANCE) || + (z1R > AQT_ZDET_VAL_100K)) { + *zr = AQT_ZDET_FLOATING_IMPEDANCE; + } else { + *zr = z1R/1000; + aqt_wcd_mbhc_qfuse_cal(codec, zr, 1); + } + dev_dbg(codec->dev, "%s: impedance on HPH_R = %d(ohms)\n", + __func__, *zr); + + /* Mono/stereo detection */ + if ((*zl == AQT_ZDET_FLOATING_IMPEDANCE) && + (*zr == AQT_ZDET_FLOATING_IMPEDANCE)) { + dev_dbg(codec->dev, + "%s: plug type is invalid or extension cable\n", + __func__); + goto zdet_complete; + } + if ((*zl == AQT_ZDET_FLOATING_IMPEDANCE) || + (*zr == AQT_ZDET_FLOATING_IMPEDANCE) || + ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) || + ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) { + dev_dbg(codec->dev, + "%s: Mono plug type with one ch floating or shorted to GND\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_MONO; + goto zdet_complete; + } + snd_soc_update_bits(codec, AQT_HPH_R_ATEST, 0x02, 0x02); + snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, 0x40, 0x01); + if (*zl < (AQT_ZDET_VAL_32/1000)) + aqt_mbhc_zdet_ramp(codec, &zdet_param[0], &z1Ls, NULL, d1); + else + aqt_mbhc_zdet_ramp(codec, &zdet_param[1], &z1Ls, NULL, d1); + snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, 0x40, 0x00); + snd_soc_update_bits(codec, AQT_HPH_R_ATEST, 0x02, 0x00); + z1Ls /= 1000; + aqt_wcd_mbhc_qfuse_cal(codec, &z1Ls, 0); + /* Parallel of left Z and 9 ohm pull down resistor */ + zMono = ((*zl) * 9) / ((*zl) + 9); + z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls); + z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl)); + if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) { + dev_dbg(codec->dev, "%s: stereo plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_STEREO; + } else { + dev_dbg(codec->dev, "%s: MONO plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_MONO; + } + +zdet_complete: + snd_soc_write(codec, AQT_ANA_MBHC_BTN5, reg0); + snd_soc_write(codec, AQT_ANA_MBHC_BTN6, reg1); + snd_soc_write(codec, AQT_ANA_MBHC_BTN7, reg2); + /* Turn on 100k pull down on HPHL */ + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_MECH, 0x01, 0x01); + + /* For NO-jack, re-enable L_DET_EN after Z-det measurements */ + if (mbhc->hphl_swh) + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_MECH, 0x80, 0x80); + + snd_soc_write(codec, AQT_MBHC_NEW_ZDET_ANA_CTL, reg4); + snd_soc_write(codec, AQT_MBHC_CTL_CLK, reg3); + if (is_fsm_disable) + regmap_update_bits(wcd9xxx->regmap, + AQT_ANA_MBHC_ELECT, 0x80, 0x80); +} + +static void aqt_mbhc_gnd_det_ctrl(struct snd_soc_codec *codec, bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, AQT_ANA_MBHC_MECH, + 0x02, 0x02); + snd_soc_update_bits(codec, AQT_ANA_MBHC_MECH, + 0x40, 0x40); + } else { + snd_soc_update_bits(codec, AQT_ANA_MBHC_MECH, + 0x40, 0x00); + snd_soc_update_bits(codec, AQT_ANA_MBHC_MECH, + 0x02, 0x00); + } +} + +static void aqt_mbhc_hph_pull_down_ctrl(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, + 0x40, 0x40); + snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, + 0x10, 0x10); + } else { + snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, + 0x40, 0x00); + snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, + 0x10, 0x00); + } +} +static void aqt_mbhc_moisture_config(struct wcd_mbhc *mbhc) +{ + struct snd_soc_codec *codec = mbhc->codec; + + if ((mbhc->moist_rref == R_OFF) || + (mbhc->mbhc_cfg->enable_usbc_analog)) { + snd_soc_update_bits(codec, AQT_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); + return; + } + + /* Donot enable moisture detection if jack type is NC */ + if (!mbhc->hphl_swh) { + dev_dbg(codec->dev, "%s: disable moisture detection for NC\n", + __func__); + snd_soc_update_bits(codec, AQT_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); + return; + } + + snd_soc_update_bits(codec, AQT_MBHC_NEW_CTL_2, + 0x0C, mbhc->moist_rref << 2); +} + +static bool aqt_hph_register_recovery(struct wcd_mbhc *mbhc) +{ + struct snd_soc_codec *codec = mbhc->codec; + struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + + if (!aqt_mbhc) + return false; + + aqt_mbhc->is_hph_recover = false; + snd_soc_dapm_force_enable_pin(snd_soc_codec_get_dapm(codec), + "RESET_HPH_REGISTERS"); + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + + snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(codec), + "RESET_HPH_REGISTERS"); + snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + + return aqt_mbhc->is_hph_recover; +} + +static void aqt_update_anc_state(struct snd_soc_codec *codec, bool enable, + int anc_num) +{ + if (enable) + snd_soc_update_bits(codec, AQT_CDC_RX1_RX_PATH_CFG0 + + (20 * anc_num), 0x10, 0x10); + else + snd_soc_update_bits(codec, AQT_CDC_RX1_RX_PATH_CFG0 + + (20 * anc_num), 0x10, 0x00); +} + +static bool aqt_is_anc_on(struct wcd_mbhc *mbhc) +{ + bool anc_on = false; + u16 ancl, ancr; + + ancl = + (snd_soc_read(mbhc->codec, AQT_CDC_RX1_RX_PATH_CFG0)) & 0x10; + ancr = + (snd_soc_read(mbhc->codec, AQT_CDC_RX2_RX_PATH_CFG0)) & 0x10; + + anc_on = !!(ancl | ancr); + + return anc_on; +} + +static const struct wcd_mbhc_cb mbhc_cb = { + .request_irq = aqt_mbhc_request_irq, + .irq_control = aqt_mbhc_irq_control, + .free_irq = aqt_mbhc_free_irq, + .clk_setup = aqt_mbhc_clk_setup, + .map_btn_code_to_num = aqt_mbhc_btn_to_num, + .enable_mb_source = aqt_enable_ext_mb_source, + .mbhc_bias = aqt_mbhc_mbhc_bias_control, + .set_btn_thr = aqt_mbhc_program_btn_thr, + .lock_sleep = aqt_mbhc_lock_sleep, + .register_notifier = aqt_mbhc_register_notifier, + .micbias_enable_status = aqt_mbhc_micb_en_status, + .hph_pa_on_status = aqt_mbhc_hph_pa_on_status, + .hph_pull_up_control = aqt_mbhc_hph_l_pull_up_control, + .mbhc_micbias_control = aqt_mbhc_request_micbias, + .mbhc_micb_ramp_control = aqt_mbhc_micb_ramp_control, + .get_hwdep_fw_cal = aqt_get_hwdep_fw_cal, + .mbhc_micb_ctrl_thr_mic = aqt_mbhc_micb_ctrl_threshold_mic, + .compute_impedance = aqt_wcd_mbhc_calc_impedance, + .mbhc_gnd_det_ctrl = aqt_mbhc_gnd_det_ctrl, + .hph_pull_down_ctrl = aqt_mbhc_hph_pull_down_ctrl, + .mbhc_moisture_config = aqt_mbhc_moisture_config, + .hph_register_recovery = aqt_hph_register_recovery, + .update_anc_state = aqt_update_anc_state, + .is_anc_on = aqt_is_anc_on, +}; + +static struct regulator *aqt_codec_find_ondemand_regulator( + struct snd_soc_codec *codec, const char *name) +{ + int i; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + + for (i = 0; i < wcd9xxx->num_of_supplies; ++i) { + if (pdata->regulator[i].ondemand && + wcd9xxx->supplies[i].supply && + !strcmp(wcd9xxx->supplies[i].supply, name)) + return wcd9xxx->supplies[i].consumer; + } + + dev_dbg(codec->dev, "Warning: regulator not found:%s\n", + name); + return NULL; +} + +static int aqt_get_hph_type(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + struct wcd_mbhc *mbhc; + + if (!aqt_mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + + mbhc = &aqt_mbhc->wcd_mbhc; + + ucontrol->value.integer.value[0] = (u32) mbhc->hph_type; + dev_dbg(codec->dev, "%s: hph_type = %u\n", __func__, mbhc->hph_type); + + return 0; +} + +static int aqt_hph_impedance_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + uint32_t zl, zr; + bool hphr; + struct soc_multi_mixer_control *mc; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + + if (!aqt_mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + + mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); + hphr = mc->shift; + wcd_mbhc_get_impedance(&aqt_mbhc->wcd_mbhc, &zl, &zr); + dev_dbg(codec->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr); + ucontrol->value.integer.value[0] = hphr ? zr : zl; + + return 0; +} + +static const struct snd_kcontrol_new hph_type_detect_controls[] = { + SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0, + aqt_get_hph_type, NULL), +}; + +static const struct snd_kcontrol_new impedance_detect_controls[] = { + SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0, + aqt_hph_impedance_get, NULL), + SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0, + aqt_hph_impedance_get, NULL), +}; + +/* + * aqt_mbhc_get_impedance: get impedance of headphone left and right channels + * @aqt_mbhc: handle to struct aqt_mbhc * + * @zl: handle to left-ch impedance + * @zr: handle to right-ch impedance + * return 0 for success or error code in case of failure + */ +int aqt_mbhc_get_impedance(struct aqt_mbhc *aqt_mbhc, + uint32_t *zl, uint32_t *zr) +{ + if (!aqt_mbhc) { + pr_err("%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + if (!zl || !zr) { + pr_err("%s: zl or zr null!\n", __func__); + return -EINVAL; + } + + return wcd_mbhc_get_impedance(&aqt_mbhc->wcd_mbhc, zl, zr); +} +EXPORT_SYMBOL(aqt_mbhc_get_impedance); + +/* + * aqt_mbhc_hs_detect: starts mbhc insertion/removal functionality + * @codec: handle to snd_soc_codec * + * @mbhc_cfg: handle to mbhc configuration structure + * return 0 if mbhc_start is success or error code in case of failure + */ +int aqt_mbhc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg) +{ + struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + + if (!aqt_mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + + return wcd_mbhc_start(&aqt_mbhc->wcd_mbhc, mbhc_cfg); +} +EXPORT_SYMBOL(aqt_mbhc_hs_detect); + +/* + * aqt_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality + * @codec: handle to snd_soc_codec * + */ +void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +{ + struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + + if (!aqt_mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + return; + } + wcd_mbhc_stop(&aqt_mbhc->wcd_mbhc); +} +EXPORT_SYMBOL(aqt_mbhc_hs_detect_exit); + +/* + * aqt_mbhc_post_ssr_init: initialize mbhc for aqt post subsystem restart + * @mbhc: poniter to aqt_mbhc structure + * @codec: handle to snd_soc_codec * + * + * return 0 if mbhc_init is success or error code in case of failure + */ +int aqt_mbhc_post_ssr_init(struct aqt_mbhc *mbhc, + struct snd_soc_codec *codec) +{ + int ret; + struct wcd_mbhc *wcd_mbhc; + + if (!mbhc || !codec) + return -EINVAL; + + wcd_mbhc = &mbhc->wcd_mbhc; + if (wcd_mbhc == NULL) { + pr_err("%s: wcd_mbhc is NULL\n", __func__); + return -EINVAL; + } + + wcd_mbhc_deinit(wcd_mbhc); + ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids, + wcd_mbhc_registers, AQT_ZDET_SUPPORTED); + if (ret) { + dev_err(codec->dev, "%s: mbhc initialization failed\n", + __func__); + goto done; + } + +done: + return ret; +} +EXPORT_SYMBOL(aqt_mbhc_post_ssr_init); + +/* + * aqt_mbhc_init: initialize mbhc for aqt + * @mbhc: poniter to aqt_mbhc struct pointer to store the configs + * @codec: handle to snd_soc_codec * + * @fw_data: handle to firmware data + * + * return 0 if mbhc_init is success or error code in case of failure + */ +int aqt_mbhc_init(struct aqt_mbhc **mbhc, struct snd_soc_codec *codec, + struct fw_info *fw_data) +{ + struct regulator *supply; + struct aqt_mbhc *aqt_mbhc; + struct wcd_mbhc *wcd_mbhc; + int ret; + + aqt_mbhc = devm_kzalloc(codec->dev, sizeof(struct aqt_mbhc), + GFP_KERNEL); + if (!aqt_mbhc) + return -ENOMEM; + + aqt_mbhc->wcd9xxx = dev_get_drvdata(codec->dev->parent); + aqt_mbhc->fw_data = fw_data; + BLOCKING_INIT_NOTIFIER_HEAD(&aqt_mbhc->notifier); + wcd_mbhc = &aqt_mbhc->wcd_mbhc; + if (wcd_mbhc == NULL) { + pr_err("%s: wcd_mbhc is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + + /* Setting default mbhc detection logic to ADC */ + wcd_mbhc->mbhc_detection_logic = WCD_DETECTION_ADC; + + ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, + &intr_ids, wcd_mbhc_registers, + AQT_ZDET_SUPPORTED); + if (ret) { + dev_err(codec->dev, "%s: mbhc initialization failed\n", + __func__); + goto err; + } + + supply = aqt_codec_find_ondemand_regulator(codec, + on_demand_supply_name[AQT_ON_DEMAND_MICBIAS]); + if (supply) { + aqt_mbhc->on_demand_list[ + AQT_ON_DEMAND_MICBIAS].supply = + supply; + aqt_mbhc->on_demand_list[ + AQT_ON_DEMAND_MICBIAS].ondemand_supply_count = + 0; + } + + (*mbhc) = aqt_mbhc; + snd_soc_add_codec_controls(codec, impedance_detect_controls, + ARRAY_SIZE(impedance_detect_controls)); + snd_soc_add_codec_controls(codec, hph_type_detect_controls, + ARRAY_SIZE(hph_type_detect_controls)); + + return 0; +err: + devm_kfree(codec->dev, aqt_mbhc); + return ret; +} +EXPORT_SYMBOL(aqt_mbhc_init); + +/* + * aqt_mbhc_deinit: deinitialize mbhc for aqt + * @codec: handle to snd_soc_codec * + */ +void aqt_mbhc_deinit(struct snd_soc_codec *codec) +{ + struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + + if (aqt_mbhc) { + wcd_mbhc_deinit(&aqt_mbhc->wcd_mbhc); + devm_kfree(codec->dev, aqt_mbhc); + } +} +EXPORT_SYMBOL(aqt_mbhc_deinit); diff --git a/asoc/codecs/aqt1000/aqt1000-mbhc.h b/asoc/codecs/aqt1000/aqt1000-mbhc.h new file mode 100644 index 000000000000..848cb07d7e9b --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-mbhc.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __AQT_MBHC_H__ +#define __AQT_MBHC_H__ +#include "../wcd-mbhc-v2.h" + +enum aqt_on_demand_supply_name { + AQT_ON_DEMAND_MICBIAS = 0, + AQT_ON_DEMAND_SUPPLIES_MAX, +}; + +struct aqt_on_demand_supply { + struct regulator *supply; + int ondemand_supply_count; +}; + +struct aqt_mbhc { + struct wcd_mbhc wcd_mbhc; + struct blocking_notifier_head notifier; + struct aqt_on_demand_supply on_demand_list[ + AQT_ON_DEMAND_SUPPLIES_MAX]; + struct aqt1000 *aqt; + struct fw_info *fw_data; + bool mbhc_started; + bool is_hph_recover; +}; + +#if IS_ENABLED(CONFIG_SND_SOC_AQT_MBHC) +extern int aqt_mbhc_init(struct aqt_mbhc **mbhc, + struct snd_soc_codec *codec, + struct fw_info *fw_data); +extern void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec); +extern int aqt_mbhc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg); +extern void aqt_mbhc_deinit(struct snd_soc_codec *codec); +extern int aqt_mbhc_post_ssr_init(struct aqt_mbhc *mbhc, + struct snd_soc_codec *codec); +extern int aqt_mbhc_get_impedance(struct aqt_mbhc *aqt_mbhc, + uint32_t *zl, uint32_t *zr); +#else +static inline int aqt_mbhc_init(struct aqt_mbhc **mbhc, + struct snd_soc_codec *codec, + struct fw_info *fw_data) +{ + return 0; +} +static inline void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +{ +} +static inline int aqt_mbhc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg) +{ + return 0; +} +static inline void aqt_mbhc_deinit(struct snd_soc_codec *codec) +{ +} +static inline int aqt_mbhc_post_ssr_init(struct aqt_mbhc *mbhc, + struct snd_soc_codec *codec) +{ + return 0; +} +static inline int aqt_mbhc_get_impedance(struct aqt_mbhc *aqt_mbhc, + uint32_t *zl, uint32_t *zr) +{ + if (zl) + *zl = 0; + if (zr) + *zr = 0; + return -EINVAL; +} +#endif + +#endif /* __AQT_MBHC_H__ */ diff --git a/asoc/codecs/aqt1000/aqt1000-reg-defaults.h b/asoc/codecs/aqt1000/aqt1000-reg-defaults.h new file mode 100644 index 000000000000..5a5da25fa725 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-reg-defaults.h @@ -0,0 +1,1616 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _AQT1000_REG_DEFAULTS_H +#define _AQT1000_REG_DEFAULTS_H + +#include +#include "aqt1000-registers.h" + +#define AQT1000_REG(reg) ((reg) & 0xFF) +#define AQT1000_PAGE_SIZE 256 + +enum { + AQT1000_PAGE_0 = 0, + AQT1000_PAGE_1, + AQT1000_PAGE_2, + AQT1000_PAGE_5 = 5, + AQT1000_PAGE_6, + AQT1000_PAGE_7, + AQT1000_PAGE_10 = 0xA, + AQT1000_PAGE_11, + AQT1000_PAGE_12, + AQT1000_PAGE_13, + AQT1000_PAGE_15 = 0xF, + AQT1000_PAGE_128, + AQT1000_PAGE_MAX, +}; + +enum { + AQT1000_WO = 0, + AQT1000_RO, + AQT1000_RW, +}; + +static const struct reg_default aqt1000_defaults[] = { + {AQT1000_CHIP_CFG1_PWR_MEM_SD, 0x07}, + {AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_RAM, 0x00}, + {AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_ROM, 0x00}, + {AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_RAM, 0x00}, + {AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_ROM, 0x00}, + {AQT1000_CHIP_CFG1_CLK_CFG_FLL, 0x20}, + {AQT1000_CHIP_CFG1_CLK_CFG_SPI_M, 0x01}, + {AQT1000_CHIP_CFG1_CLK_CFG_I2C_M, 0x01}, + {AQT1000_CHIP_CFG1_CLK_CFG_UART, 0x01}, + {AQT1000_CHIP_CFG1_RST_USB_SS, 0x0E}, + {AQT1000_CHIP_CFG1_RST_BLSP, 0x0F}, + {AQT1000_CHIP_CFG1_RST_BUS_MTRX, 0x00}, + {AQT1000_CHIP_CFG1_RST_MISC, 0x00}, + {AQT1000_CHIP_CFG1_ANA_WAIT_STATE_CTL, 0xCC}, + {AQT1000_PAGE1_PAGE_REGISTER, 0x00}, + {AQT1000_FLL_USER_CTL_0, 0x71}, + {AQT1000_FLL_USER_CTL_1, 0x34}, + {AQT1000_FLL_USER_CTL_2, 0x0B}, + {AQT1000_FLL_USER_CTL_3, 0x02}, + {AQT1000_FLL_USER_CTL_4, 0x04}, + {AQT1000_FLL_USER_CTL_5, 0x02}, + {AQT1000_FLL_USER_CTL_6, 0x6E}, + {AQT1000_FLL_USER_CTL_7, 0x00}, + {AQT1000_FLL_USER_CTL_8, 0x94}, + {AQT1000_FLL_USER_CTL_9, 0x70}, + {AQT1000_FLL_L_VAL_CTL_0, 0x34}, + {AQT1000_FLL_L_VAL_CTL_1, 0x00}, + {AQT1000_FLL_DSM_FRAC_CTL_0, 0x00}, + {AQT1000_FLL_DSM_FRAC_CTL_1, 0xFF}, + {AQT1000_FLL_CONFIG_CTL_0, 0x6B}, + {AQT1000_FLL_CONFIG_CTL_1, 0x05}, + {AQT1000_FLL_CONFIG_CTL_2, 0x08}, + {AQT1000_FLL_CONFIG_CTL_3, 0x00}, + {AQT1000_FLL_CONFIG_CTL_4, 0x10}, + {AQT1000_FLL_TEST_CTL_0, 0x80}, + {AQT1000_FLL_TEST_CTL_1, 0x00}, + {AQT1000_FLL_TEST_CTL_2, 0x00}, + {AQT1000_FLL_TEST_CTL_3, 0x00}, + {AQT1000_FLL_TEST_CTL_4, 0x00}, + {AQT1000_FLL_TEST_CTL_5, 0x00}, + {AQT1000_FLL_TEST_CTL_6, 0x04}, + {AQT1000_FLL_TEST_CTL_7, 0x33}, + {AQT1000_FLL_FREQ_CTL_0, 0x00}, + {AQT1000_FLL_FREQ_CTL_1, 0x00}, + {AQT1000_FLL_FREQ_CTL_2, 0x00}, + {AQT1000_FLL_FREQ_CTL_3, 0x00}, + {AQT1000_FLL_SSC_CTL_0, 0x00}, + {AQT1000_FLL_SSC_CTL_1, 0x00}, + {AQT1000_FLL_SSC_CTL_2, 0x00}, + {AQT1000_FLL_SSC_CTL_3, 0x00}, + {AQT1000_FLL_FLL_MODE, 0xA0}, + {AQT1000_FLL_STATUS_0, 0x00}, + {AQT1000_FLL_STATUS_1, 0x00}, + {AQT1000_FLL_STATUS_2, 0x00}, + {AQT1000_FLL_STATUS_3, 0x00}, + {AQT1000_PAGE2_PAGE_REGISTER, 0x00}, + {AQT1000_I2S_I2S_0_TX_CFG, 0x00}, + {AQT1000_I2S_I2S_0_RX_CFG, 0x00}, + {AQT1000_I2S_I2S_0_CTL, 0x0C}, + {AQT1000_I2S_I2S_CLKSRC_CTL, 0x01}, + {AQT1000_I2S_I2S_HS_CLK_CTL, 0x00}, + {AQT1000_I2S_I2S_0_RST, 0x00}, + {AQT1000_I2S_SHADOW_I2S_0_CTL, 0x00}, + {AQT1000_I2S_SHADOW_I2S_0_RX_CFG, 0x09}, + {AQT1000_PAGE5_PAGE_REGISTER, 0x00}, + {AQT1000_INTR_CTRL_MCU_INT_POLARITY, 0x00}, + {AQT1000_INTR_CTRL_INT_MASK_0, 0xFE}, + {AQT1000_INTR_CTRL_INT_MASK_1, 0xFF}, + {AQT1000_INTR_CTRL_INT_MASK_2, 0xFF}, + {AQT1000_INTR_CTRL_INT_MASK_3, 0xEF}, + {AQT1000_INTR_CTRL_INT_MASK_4, 0x3B}, + {AQT1000_INTR_CTRL_INT_MASK_5, 0xFF}, + {AQT1000_INTR_CTRL_INT_MASK_6, 0x3F}, + {AQT1000_INTR_CTRL_INT_STATUS_0, 0x00}, + {AQT1000_INTR_CTRL_INT_STATUS_1, 0x00}, + {AQT1000_INTR_CTRL_INT_STATUS_2, 0x00}, + {AQT1000_INTR_CTRL_INT_STATUS_3, 0x00}, + {AQT1000_INTR_CTRL_INT_STATUS_4, 0x00}, + {AQT1000_INTR_CTRL_INT_STATUS_5, 0x00}, + {AQT1000_INTR_CTRL_INT_STATUS_6, 0x00}, + {AQT1000_INTR_CTRL_INT_CLEAR_0, 0x00}, + {AQT1000_INTR_CTRL_INT_CLEAR_1, 0x00}, + {AQT1000_INTR_CTRL_INT_CLEAR_2, 0x00}, + {AQT1000_INTR_CTRL_INT_CLEAR_3, 0x00}, + {AQT1000_INTR_CTRL_INT_CLEAR_4, 0x00}, + {AQT1000_INTR_CTRL_INT_CLEAR_5, 0x00}, + {AQT1000_INTR_CTRL_INT_CLEAR_6, 0x00}, + {AQT1000_INTR_CTRL_INT_TYPE_0, 0xEF}, + {AQT1000_INTR_CTRL_INT_TYPE_1, 0x03}, + {AQT1000_INTR_CTRL_INT_TYPE_2, 0x00}, + {AQT1000_INTR_CTRL_INT_TYPE_3, 0x20}, + {AQT1000_INTR_CTRL_INT_TYPE_4, 0x44}, + {AQT1000_INTR_CTRL_INT_TYPE_5, 0x00}, + {AQT1000_INTR_CTRL_INT_TYPE_6, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_EN_0, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_EN_1, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_EN_2, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_EN_3, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_EN_4, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_EN_5, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_EN_6, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_VAL_0, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_VAL_1, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_VAL_2, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_VAL_3, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_VAL_4, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_VAL_5, 0x00}, + {AQT1000_INTR_CTRL_INT_TEST_VAL_6, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_0, 0x02}, + {AQT1000_INTR_CTRL_INT_DEST_1, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_2, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_3, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_4, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_5, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_6, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_7, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_8, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_9, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_10, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_11, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_12, 0x00}, + {AQT1000_INTR_CTRL_INT_DEST_13, 0x00}, + {AQT1000_INTR_CTRL_CLR_COMMIT, 0x00}, + {AQT1000_ANA_PAGE_REGISTER, 0x00}, + {AQT1000_ANA_BIAS, 0x00}, + {AQT1000_ANA_RX_SUPPLIES, 0x00}, + {AQT1000_ANA_HPH, 0x0C}, + {AQT1000_ANA_AMIC1, 0x20}, + {AQT1000_ANA_AMIC2, 0x00}, + {AQT1000_ANA_AMIC3, 0x20}, + {AQT1000_ANA_AMIC3_HPF, 0x00}, + {AQT1000_ANA_MBHC_MECH, 0x39}, + {AQT1000_ANA_MBHC_ELECT, 0x08}, + {AQT1000_ANA_MBHC_ZDET, 0x00}, + {AQT1000_ANA_MBHC_RESULT_1, 0x00}, + {AQT1000_ANA_MBHC_RESULT_2, 0x00}, + {AQT1000_ANA_MBHC_RESULT_3, 0x00}, + {AQT1000_ANA_MBHC_BTN0, 0x00}, + {AQT1000_ANA_MBHC_BTN1, 0x10}, + {AQT1000_ANA_MBHC_BTN2, 0x20}, + {AQT1000_ANA_MBHC_BTN3, 0x30}, + {AQT1000_ANA_MBHC_BTN4, 0x40}, + {AQT1000_ANA_MBHC_BTN5, 0x50}, + {AQT1000_ANA_MBHC_BTN6, 0x60}, + {AQT1000_ANA_MBHC_BTN7, 0x70}, + {AQT1000_ANA_MICB1, 0x10}, + {AQT1000_ANA_MICB1_RAMP, 0x00}, + {AQT1000_BIAS_CTL, 0x28}, + {AQT1000_BIAS_CCOMP_FINE_ADJ, 0x75}, + {AQT1000_LED_LED_MODE_SEL_R, 0x00}, + {AQT1000_LED_LED_MISC_R, 0x00}, + {AQT1000_LED_LED_MODE_SEL_G, 0x00}, + {AQT1000_LED_LED_MISC_G, 0x00}, + {AQT1000_LED_LED_MODE_SEL_B, 0x00}, + {AQT1000_LED_LED_MISC_B, 0x00}, + {AQT1000_LDOH_MODE, 0x1D}, + {AQT1000_LDOH_BIAS, 0x00}, + {AQT1000_LDOH_STB_LOADS, 0x00}, + {AQT1000_LDOH_MISC1, 0x00}, + {AQT1000_LDOL_VDDCX_ADJUST, 0x01}, + {AQT1000_LDOL_DISABLE_LDOL, 0x00}, + {AQT1000_BUCK_5V_EN_CTL, 0x03}, + {AQT1000_BUCK_5V_VOUT_SEL, 0x03}, + {AQT1000_BUCK_5V_CTRL_VCL_1, 0x03}, + {AQT1000_BUCK_5V_CTRL_VCL_2, 0x21}, + {AQT1000_BUCK_5V_CTRL_CCL_2, 0x20}, + {AQT1000_BUCK_5V_CTRL_CCL_1, 0xA1}, + {AQT1000_BUCK_5V_CTRL_CCL_3, 0x02}, + {AQT1000_BUCK_5V_CTRL_CCL_4, 0x05}, + {AQT1000_BUCK_5V_CTRL_CCL_5, 0x00}, + {AQT1000_BUCK_5V_IBIAS_CTL_1, 0x37}, + {AQT1000_BUCK_5V_IBIAS_CTL_2, 0x00}, + {AQT1000_BUCK_5V_IBIAS_CTL_3, 0x33}, + {AQT1000_BUCK_5V_IBIAS_CTL_4, 0x33}, + {AQT1000_BUCK_5V_IBIAS_CTL_5, 0x00}, + {AQT1000_BUCK_5V_ATEST_DTEST_CTL, 0x00}, + {AQT1000_PON_BG_CTRL, 0x80}, + {AQT1000_PON_TEST_CTRL, 0x00}, + {AQT1000_MBHC_CTL_CLK, 0x30}, + {AQT1000_MBHC_CTL_ANA, 0x00}, + {AQT1000_MBHC_CTL_SPARE_1, 0x00}, + {AQT1000_MBHC_CTL_SPARE_2, 0x00}, + {AQT1000_MBHC_CTL_BCS, 0x00}, + {AQT1000_MBHC_MOISTURE_DET_FSM_STATUS, 0x00}, + {AQT1000_MBHC_TEST_CTL, 0x00}, + {AQT1000_MICB1_TEST_CTL_1, 0x1A}, + {AQT1000_MICB1_TEST_CTL_2, 0x18}, + {AQT1000_MICB1_TEST_CTL_3, 0xA4}, + {AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS, 0x00}, + {AQT1000_MICB1_MISC_MICB_MISC1, 0x00}, + {AQT1000_MICB1_MISC_MICB_MISC2, 0x00}, + {AQT1000_TX_COM_ADC_VCM, 0x39}, + {AQT1000_TX_COM_BIAS_ATEST, 0xC0}, + {AQT1000_TX_COM_ADC_INT1_IB, 0x6F}, + {AQT1000_TX_COM_ADC_INT2_IB, 0x4F}, + {AQT1000_TX_COM_TXFE_DIV_CTL, 0x2E}, + {AQT1000_TX_COM_TXFE_DIV_START, 0x00}, + {AQT1000_TX_COM_TXFE_DIV_STOP_9P6M, 0xC7}, + {AQT1000_TX_COM_TXFE_DIV_STOP_12P288M, 0xFF}, + {AQT1000_TX_1_2_TEST_EN, 0xCC}, + {AQT1000_TX_1_2_ADC_IB, 0x09}, + {AQT1000_TX_1_2_ATEST_REFCTL, 0x0A}, + {AQT1000_TX_1_2_TEST_CTL, 0x38}, + {AQT1000_TX_1_2_TEST_BLK_EN, 0xFF}, + {AQT1000_TX_1_2_TXFE_CLKDIV, 0x00}, + {AQT1000_TX_1_2_SAR1_ERR, 0x00}, + {AQT1000_TX_1_2_SAR2_ERR, 0x00}, + {AQT1000_TX_3_TEST_EN, 0xC0}, + {AQT1000_TX_3_ADC_IB, 0x09}, + {AQT1000_TX_3_ATEST_REFCTL, 0x0A}, + {AQT1000_TX_3_TEST_CTL, 0x38}, + {AQT1000_TX_3_TEST_BLK_EN, 0xFE}, + {AQT1000_TX_3_TXFE_CLKDIV, 0x00}, + {AQT1000_TX_3_SAR1_ERR, 0x00}, + {AQT1000_TX_3_SAR2_ERR, 0x00}, + {AQT1000_TX_ATEST1_2_SEL, 0x60}, + {AQT1000_CLASSH_MODE_1, 0x40}, + {AQT1000_CLASSH_MODE_2, 0x3A}, + {AQT1000_CLASSH_MODE_3, 0x00}, + {AQT1000_CLASSH_CTRL_VCL_1, 0x70}, + {AQT1000_CLASSH_CTRL_VCL_2, 0x82}, + {AQT1000_CLASSH_CTRL_CCL_1, 0x31}, + {AQT1000_CLASSH_CTRL_CCL_2, 0x80}, + {AQT1000_CLASSH_CTRL_CCL_3, 0x80}, + {AQT1000_CLASSH_CTRL_CCL_4, 0x51}, + {AQT1000_CLASSH_CTRL_CCL_5, 0x00}, + {AQT1000_CLASSH_BUCK_TMUX_A_D, 0x00}, + {AQT1000_CLASSH_BUCK_SW_DRV_CNTL, 0x77}, + {AQT1000_CLASSH_SPARE, 0x00}, + {AQT1000_FLYBACK_EN, 0x4E}, + {AQT1000_FLYBACK_VNEG_CTRL_1, 0x0B}, + {AQT1000_FLYBACK_VNEG_CTRL_2, 0x45}, + {AQT1000_FLYBACK_VNEG_CTRL_3, 0x74}, + {AQT1000_FLYBACK_VNEG_CTRL_4, 0x7F}, + {AQT1000_FLYBACK_VNEG_CTRL_5, 0x83}, + {AQT1000_FLYBACK_VNEG_CTRL_6, 0x98}, + {AQT1000_FLYBACK_VNEG_CTRL_7, 0xA9}, + {AQT1000_FLYBACK_VNEG_CTRL_8, 0x68}, + {AQT1000_FLYBACK_VNEG_CTRL_9, 0x64}, + {AQT1000_FLYBACK_VNEGDAC_CTRL_1, 0xED}, + {AQT1000_FLYBACK_VNEGDAC_CTRL_2, 0xF0}, + {AQT1000_FLYBACK_VNEGDAC_CTRL_3, 0xA6}, + {AQT1000_FLYBACK_CTRL_1, 0x65}, + {AQT1000_FLYBACK_TEST_CTL, 0x00}, + {AQT1000_RX_AUX_SW_CTL, 0x00}, + {AQT1000_RX_PA_AUX_IN_CONN, 0x00}, + {AQT1000_RX_TIMER_DIV, 0x32}, + {AQT1000_RX_OCP_CTL, 0x1F}, + {AQT1000_RX_OCP_COUNT, 0x77}, + {AQT1000_RX_BIAS_ATEST, 0x00}, + {AQT1000_RX_BIAS_MISC1, 0xAA}, + {AQT1000_RX_BIAS_HPH_LDO, 0xA9}, + {AQT1000_RX_BIAS_HPH_PA, 0xAA}, + {AQT1000_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8A}, + {AQT1000_RX_BIAS_HPH_RDAC_LDO, 0x88}, + {AQT1000_RX_BIAS_HPH_CNP1, 0x82}, + {AQT1000_RX_BIAS_HPH_LOWPOWER, 0x82}, + {AQT1000_RX_BIAS_MISC2, 0x80}, + {AQT1000_RX_BIAS_MISC3, 0x88}, + {AQT1000_RX_BIAS_MISC4, 0x88}, + {AQT1000_RX_BIAS_MISC5, 0xA8}, + {AQT1000_RX_BIAS_BUCK_RST, 0x08}, + {AQT1000_RX_BIAS_BUCK_VREF_ERRAMP, 0x44}, + {AQT1000_RX_BIAS_FLYB_ERRAMP, 0x40}, + {AQT1000_RX_BIAS_FLYB_BUFF, 0xAA}, + {AQT1000_RX_BIAS_FLYB_MID_RST, 0x14}, + {AQT1000_HPH_L_STATUS, 0x04}, + {AQT1000_HPH_R_STATUS, 0x04}, + {AQT1000_HPH_CNP_EN, 0x80}, + {AQT1000_HPH_CNP_WG_CTL, 0x9A}, + {AQT1000_HPH_CNP_WG_TIME, 0x14}, + {AQT1000_HPH_OCP_CTL, 0x28}, + {AQT1000_HPH_AUTO_CHOP, 0x16}, + {AQT1000_HPH_CHOP_CTL, 0x83}, + {AQT1000_HPH_PA_CTL1, 0x46}, + {AQT1000_HPH_PA_CTL2, 0x50}, + {AQT1000_HPH_L_EN, 0x80}, + {AQT1000_HPH_L_TEST, 0xE0}, + {AQT1000_HPH_L_ATEST, 0x50}, + {AQT1000_HPH_R_EN, 0x80}, + {AQT1000_HPH_R_TEST, 0xE0}, + {AQT1000_HPH_R_ATEST, 0x54}, + {AQT1000_HPH_RDAC_CLK_CTL1, 0x99}, + {AQT1000_HPH_RDAC_CLK_CTL2, 0x9B}, + {AQT1000_HPH_RDAC_LDO_CTL, 0x33}, + {AQT1000_HPH_RDAC_CHOP_CLK_LP_CTL, 0x00}, + {AQT1000_HPH_REFBUFF_UHQA_CTL, 0xA8}, + {AQT1000_HPH_REFBUFF_LP_CTL, 0x0E}, + {AQT1000_HPH_L_DAC_CTL, 0x00}, + {AQT1000_HPH_R_DAC_CTL, 0x00}, + {AQT1000_HPHLR_SURGE_COMP_SEL, 0x55}, + {AQT1000_HPHLR_SURGE_EN, 0x1D}, + {AQT1000_HPHLR_SURGE_MISC1, 0xA0}, + {AQT1000_HPHLR_SURGE_STATUS, 0x00}, + {AQT1000_ANA_NEW_PAGE_REGISTER, 0x00}, + {AQT1000_HPH_NEW_ANA_HPH2, 0x00}, + {AQT1000_HPH_NEW_ANA_HPH3, 0x00}, + {AQT1000_CLK_SYS_MCLK1_PRG, 0x09}, + {AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG, 0x20}, + {AQT1000_CLK_SYS_XO_CAP_XTP, 0x3F}, + {AQT1000_CLK_SYS_XO_CAP_XTM, 0x3F}, + {AQT1000_CLK_SYS_PLL_ENABLES, 0x00}, + {AQT1000_CLK_SYS_PLL_PRESET, 0x00}, + {AQT1000_CLK_SYS_PLL_STATUS, 0x00}, + {AQT1000_MBHC_NEW_ELECT_REM_CLAMP_CTL, 0x00}, + {AQT1000_MBHC_NEW_CTL_1, 0x02}, + {AQT1000_MBHC_NEW_CTL_2, 0x05}, + {AQT1000_MBHC_NEW_PLUG_DETECT_CTL, 0x29}, + {AQT1000_MBHC_NEW_ZDET_ANA_CTL, 0x0F}, + {AQT1000_MBHC_NEW_ZDET_RAMP_CTL, 0x00}, + {AQT1000_MBHC_NEW_FSM_STATUS, 0x00}, + {AQT1000_MBHC_NEW_ADC_RESULT, 0x00}, + {AQT1000_HPH_NEW_INT_RDAC_GAIN_CTL, 0x40}, + {AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x81}, + {AQT1000_HPH_NEW_INT_RDAC_VREF_CTL, 0x10}, + {AQT1000_HPH_NEW_INT_RDAC_OVERRIDE_CTL, 0x00}, + {AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x81}, + {AQT1000_HPH_NEW_INT_PA_MISC1, 0x22}, + {AQT1000_HPH_NEW_INT_PA_MISC2, 0x00}, + {AQT1000_HPH_NEW_INT_PA_RDAC_MISC, 0x00}, + {AQT1000_HPH_NEW_INT_HPH_TIMER1, 0xFE}, + {AQT1000_HPH_NEW_INT_HPH_TIMER2, 0x02}, + {AQT1000_HPH_NEW_INT_HPH_TIMER3, 0x4E}, + {AQT1000_HPH_NEW_INT_HPH_TIMER4, 0x54}, + {AQT1000_HPH_NEW_INT_PA_RDAC_MISC2, 0x80}, + {AQT1000_HPH_NEW_INT_PA_RDAC_MISC3, 0x00}, + {AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI, 0x62}, + {AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_ULP, 0x01}, + {AQT1000_RX_NEW_INT_HPH_RDAC_LDO_LP, 0x11}, + {AQT1000_CLK_SYS_INT_CLK_TEST1, 0x00}, + {AQT1000_CLK_SYS_INT_XO_TEST1, 0x98}, + {AQT1000_CLK_SYS_INT_XO_TEST2, 0x00}, + {AQT1000_CLK_SYS_INT_POST_DIV_REG0, 0x00}, + {AQT1000_CLK_SYS_INT_POST_DIV_REG1, 0x00}, + {AQT1000_CLK_SYS_INT_REF_DIV_REG0, 0x00}, + {AQT1000_CLK_SYS_INT_REF_DIV_REG1, 0x00}, + {AQT1000_CLK_SYS_INT_FILTER_REG0, 0x00}, + {AQT1000_CLK_SYS_INT_FILTER_REG1, 0x00}, + {AQT1000_CLK_SYS_INT_PLL_L_VAL, 0x00}, + {AQT1000_CLK_SYS_INT_PLL_M_VAL, 0x00}, + {AQT1000_CLK_SYS_INT_PLL_N_VAL, 0x00}, + {AQT1000_CLK_SYS_INT_TEST_REG0, 0x00}, + {AQT1000_CLK_SYS_INT_PFD_CP_DSM_PROG, 0x00}, + {AQT1000_CLK_SYS_INT_VCO_PROG, 0x00}, + {AQT1000_CLK_SYS_INT_TEST_REG1, 0x00}, + {AQT1000_CLK_SYS_INT_LDO_LOCK_CFG, 0x00}, + {AQT1000_CLK_SYS_INT_DIG_LOCK_DET_CFG, 0x00}, + {AQT1000_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL, 0x57}, + {AQT1000_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL, 0x01}, + {AQT1000_MBHC_NEW_INT_MECH_DET_CURRENT, 0x00}, + {AQT1000_MBHC_NEW_INT_SPARE_2, 0x00}, + {AQT1000_PAGE10_PAGE_REGISTER, 0x00}, + {AQT1000_CDC_ANC0_CLK_RESET_CTL, 0x00}, + {AQT1000_CDC_ANC0_MODE_1_CTL, 0x00}, + {AQT1000_CDC_ANC0_MODE_2_CTL, 0x00}, + {AQT1000_CDC_ANC0_FF_SHIFT, 0x00}, + {AQT1000_CDC_ANC0_FB_SHIFT, 0x00}, + {AQT1000_CDC_ANC0_LPF_FF_A_CTL, 0x00}, + {AQT1000_CDC_ANC0_LPF_FF_B_CTL, 0x00}, + {AQT1000_CDC_ANC0_LPF_FB_CTL, 0x00}, + {AQT1000_CDC_ANC0_SMLPF_CTL, 0x00}, + {AQT1000_CDC_ANC0_DCFLT_SHIFT_CTL, 0x00}, + {AQT1000_CDC_ANC0_IIR_ADAPT_CTL, 0x00}, + {AQT1000_CDC_ANC0_IIR_COEFF_1_CTL, 0x00}, + {AQT1000_CDC_ANC0_IIR_COEFF_2_CTL, 0x00}, + {AQT1000_CDC_ANC0_FF_A_GAIN_CTL, 0x00}, + {AQT1000_CDC_ANC0_FF_B_GAIN_CTL, 0x00}, + {AQT1000_CDC_ANC0_FB_GAIN_CTL, 0x00}, + {AQT1000_CDC_ANC0_RC_COMMON_CTL, 0x00}, + {AQT1000_CDC_ANC0_FIFO_COMMON_CTL, 0x88}, + {AQT1000_CDC_ANC0_RC0_STATUS_FMIN_CNTR, 0x00}, + {AQT1000_CDC_ANC0_RC1_STATUS_FMIN_CNTR, 0x00}, + {AQT1000_CDC_ANC0_RC0_STATUS_FMAX_CNTR, 0x00}, + {AQT1000_CDC_ANC0_RC1_STATUS_FMAX_CNTR, 0x00}, + {AQT1000_CDC_ANC0_STATUS_FIFO, 0x00}, + {AQT1000_CDC_ANC1_CLK_RESET_CTL, 0x00}, + {AQT1000_CDC_ANC1_MODE_1_CTL, 0x00}, + {AQT1000_CDC_ANC1_MODE_2_CTL, 0x00}, + {AQT1000_CDC_ANC1_FF_SHIFT, 0x00}, + {AQT1000_CDC_ANC1_FB_SHIFT, 0x00}, + {AQT1000_CDC_ANC1_LPF_FF_A_CTL, 0x00}, + {AQT1000_CDC_ANC1_LPF_FF_B_CTL, 0x00}, + {AQT1000_CDC_ANC1_LPF_FB_CTL, 0x00}, + {AQT1000_CDC_ANC1_SMLPF_CTL, 0x00}, + {AQT1000_CDC_ANC1_DCFLT_SHIFT_CTL, 0x00}, + {AQT1000_CDC_ANC1_IIR_ADAPT_CTL, 0x00}, + {AQT1000_CDC_ANC1_IIR_COEFF_1_CTL, 0x00}, + {AQT1000_CDC_ANC1_IIR_COEFF_2_CTL, 0x00}, + {AQT1000_CDC_ANC1_FF_A_GAIN_CTL, 0x00}, + {AQT1000_CDC_ANC1_FF_B_GAIN_CTL, 0x00}, + {AQT1000_CDC_ANC1_FB_GAIN_CTL, 0x00}, + {AQT1000_CDC_ANC1_RC_COMMON_CTL, 0x00}, + {AQT1000_CDC_ANC1_FIFO_COMMON_CTL, 0x88}, + {AQT1000_CDC_ANC1_RC0_STATUS_FMIN_CNTR, 0x00}, + {AQT1000_CDC_ANC1_RC1_STATUS_FMIN_CNTR, 0x00}, + {AQT1000_CDC_ANC1_RC0_STATUS_FMAX_CNTR, 0x00}, + {AQT1000_CDC_ANC1_RC1_STATUS_FMAX_CNTR, 0x00}, + {AQT1000_CDC_ANC1_STATUS_FIFO, 0x00}, + {AQT1000_CDC_TX0_TX_PATH_CTL, 0x04}, + {AQT1000_CDC_TX0_TX_PATH_CFG0, 0x10}, + {AQT1000_CDC_TX0_TX_PATH_CFG1, 0x03}, + {AQT1000_CDC_TX0_TX_VOL_CTL, 0x00}, + {AQT1000_CDC_TX0_TX_PATH_SEC0, 0x00}, + {AQT1000_CDC_TX0_TX_PATH_SEC1, 0x00}, + {AQT1000_CDC_TX0_TX_PATH_SEC2, 0x01}, + {AQT1000_CDC_TX0_TX_PATH_SEC3, 0x3C}, + {AQT1000_CDC_TX0_TX_PATH_SEC4, 0x20}, + {AQT1000_CDC_TX0_TX_PATH_SEC5, 0x00}, + {AQT1000_CDC_TX0_TX_PATH_SEC6, 0x00}, + {AQT1000_CDC_TX1_TX_PATH_CTL, 0x04}, + {AQT1000_CDC_TX1_TX_PATH_CFG0, 0x10}, + {AQT1000_CDC_TX1_TX_PATH_CFG1, 0x03}, + {AQT1000_CDC_TX1_TX_VOL_CTL, 0x00}, + {AQT1000_CDC_TX1_TX_PATH_SEC0, 0x00}, + {AQT1000_CDC_TX1_TX_PATH_SEC1, 0x00}, + {AQT1000_CDC_TX1_TX_PATH_SEC2, 0x01}, + {AQT1000_CDC_TX1_TX_PATH_SEC3, 0x3C}, + {AQT1000_CDC_TX1_TX_PATH_SEC4, 0x20}, + {AQT1000_CDC_TX1_TX_PATH_SEC5, 0x00}, + {AQT1000_CDC_TX1_TX_PATH_SEC6, 0x00}, + {AQT1000_CDC_TX2_TX_PATH_CTL, 0x04}, + {AQT1000_CDC_TX2_TX_PATH_CFG0, 0x10}, + {AQT1000_CDC_TX2_TX_PATH_CFG1, 0x03}, + {AQT1000_CDC_TX2_TX_VOL_CTL, 0x00}, + {AQT1000_CDC_TX2_TX_PATH_SEC0, 0x00}, + {AQT1000_CDC_TX2_TX_PATH_SEC1, 0x00}, + {AQT1000_CDC_TX2_TX_PATH_SEC2, 0x01}, + {AQT1000_CDC_TX2_TX_PATH_SEC3, 0x3C}, + {AQT1000_CDC_TX2_TX_PATH_SEC4, 0x20}, + {AQT1000_CDC_TX2_TX_PATH_SEC5, 0x00}, + {AQT1000_CDC_TX2_TX_PATH_SEC6, 0x00}, + {AQT1000_CDC_TX2_TX_PATH_SEC7, 0x25}, + {AQT1000_PAGE11_PAGE_REGISTER, 0x00}, + {AQT1000_CDC_COMPANDER1_CTL0, 0x60}, + {AQT1000_CDC_COMPANDER1_CTL1, 0xDB}, + {AQT1000_CDC_COMPANDER1_CTL2, 0xFF}, + {AQT1000_CDC_COMPANDER1_CTL3, 0x35}, + {AQT1000_CDC_COMPANDER1_CTL4, 0xFF}, + {AQT1000_CDC_COMPANDER1_CTL5, 0x00}, + {AQT1000_CDC_COMPANDER1_CTL6, 0x01}, + {AQT1000_CDC_COMPANDER1_CTL7, 0x26}, + {AQT1000_CDC_COMPANDER2_CTL0, 0x60}, + {AQT1000_CDC_COMPANDER2_CTL1, 0xDB}, + {AQT1000_CDC_COMPANDER2_CTL2, 0xFF}, + {AQT1000_CDC_COMPANDER2_CTL3, 0x35}, + {AQT1000_CDC_COMPANDER2_CTL4, 0xFF}, + {AQT1000_CDC_COMPANDER2_CTL5, 0x00}, + {AQT1000_CDC_COMPANDER2_CTL6, 0x01}, + {AQT1000_CDC_COMPANDER2_CTL7, 0x26}, + {AQT1000_CDC_RX1_RX_PATH_CTL, 0x04}, + {AQT1000_CDC_RX1_RX_PATH_CFG0, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_CFG1, 0x64}, + {AQT1000_CDC_RX1_RX_PATH_CFG2, 0x8F}, + {AQT1000_CDC_RX1_RX_VOL_CTL, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_MIX_CTL, 0x04}, + {AQT1000_CDC_RX1_RX_PATH_MIX_CFG, 0x7E}, + {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_SEC0, 0xFC}, + {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x08}, + {AQT1000_CDC_RX1_RX_PATH_SEC2, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_SEC3, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_SEC4, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_SEC5, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_SEC6, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_SEC7, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_MIX_SEC0, 0x08}, + {AQT1000_CDC_RX1_RX_PATH_MIX_SEC1, 0x00}, + {AQT1000_CDC_RX1_RX_PATH_DSMDEM_CTL, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_CTL, 0x04}, + {AQT1000_CDC_RX2_RX_PATH_CFG0, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_CFG1, 0x64}, + {AQT1000_CDC_RX2_RX_PATH_CFG2, 0x8F}, + {AQT1000_CDC_RX2_RX_VOL_CTL, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_MIX_CTL, 0x04}, + {AQT1000_CDC_RX2_RX_PATH_MIX_CFG, 0x7E}, + {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_SEC0, 0xFC}, + {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x08}, + {AQT1000_CDC_RX2_RX_PATH_SEC2, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_SEC3, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_SEC4, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_SEC5, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_SEC6, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_SEC7, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_MIX_SEC0, 0x08}, + {AQT1000_CDC_RX2_RX_PATH_MIX_SEC1, 0x00}, + {AQT1000_CDC_RX2_RX_PATH_DSMDEM_CTL, 0x00}, + {AQT1000_CDC_EQ_IIR0_PATH_CTL, 0x00}, + {AQT1000_CDC_EQ_IIR0_PATH_CFG0, 0x1F}, + {AQT1000_CDC_EQ_IIR0_PATH_CFG1, 0x00}, + {AQT1000_CDC_EQ_IIR0_PATH_CFG2, 0x00}, + {AQT1000_CDC_EQ_IIR0_PATH_CFG3, 0x00}, + {AQT1000_CDC_EQ_IIR0_COEF_CFG0, 0x00}, + {AQT1000_CDC_EQ_IIR0_COEF_CFG1, 0x00}, + {AQT1000_CDC_EQ_IIR1_PATH_CTL, 0x00}, + {AQT1000_CDC_EQ_IIR1_PATH_CFG0, 0x1F}, + {AQT1000_CDC_EQ_IIR1_PATH_CFG1, 0x00}, + {AQT1000_CDC_EQ_IIR1_PATH_CFG2, 0x00}, + {AQT1000_CDC_EQ_IIR1_PATH_CFG3, 0x00}, + {AQT1000_CDC_EQ_IIR1_COEF_CFG0, 0x00}, + {AQT1000_CDC_EQ_IIR1_COEF_CFG1, 0x00}, + {AQT1000_PAGE12_PAGE_REGISTER, 0x00}, + {AQT1000_CDC_CLSH_CRC, 0x00}, + {AQT1000_CDC_CLSH_DLY_CTRL, 0x03}, + {AQT1000_CDC_CLSH_DECAY_CTRL, 0x02}, + {AQT1000_CDC_CLSH_HPH_V_PA, 0x1C}, + {AQT1000_CDC_CLSH_EAR_V_PA, 0x39}, + {AQT1000_CDC_CLSH_HPH_V_HD, 0x0C}, + {AQT1000_CDC_CLSH_EAR_V_HD, 0x0C}, + {AQT1000_CDC_CLSH_K1_MSB, 0x01}, + {AQT1000_CDC_CLSH_K1_LSB, 0x00}, + {AQT1000_CDC_CLSH_K2_MSB, 0x00}, + {AQT1000_CDC_CLSH_K2_LSB, 0x80}, + {AQT1000_CDC_CLSH_IDLE_CTRL, 0x00}, + {AQT1000_CDC_CLSH_IDLE_HPH, 0x00}, + {AQT1000_CDC_CLSH_IDLE_EAR, 0x00}, + {AQT1000_CDC_CLSH_TEST0, 0x07}, + {AQT1000_CDC_CLSH_TEST1, 0x00}, + {AQT1000_CDC_CLSH_OVR_VREF, 0x00}, + {AQT1000_MIXING_ASRC0_CLK_RST_CTL, 0x00}, + {AQT1000_MIXING_ASRC0_CTL0, 0x00}, + {AQT1000_MIXING_ASRC0_CTL1, 0x00}, + {AQT1000_MIXING_ASRC0_FIFO_CTL, 0xA8}, + {AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00}, + {AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00}, + {AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00}, + {AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00}, + {AQT1000_MIXING_ASRC0_STATUS_FIFO, 0x00}, + {AQT1000_MIXING_ASRC1_CLK_RST_CTL, 0x00}, + {AQT1000_MIXING_ASRC1_CTL0, 0x00}, + {AQT1000_MIXING_ASRC1_CTL1, 0x00}, + {AQT1000_MIXING_ASRC1_FIFO_CTL, 0xA8}, + {AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00}, + {AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00}, + {AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00}, + {AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00}, + {AQT1000_MIXING_ASRC1_STATUS_FIFO, 0x00}, + {AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL, 0x04}, + {AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1, 0x00}, + {AQT1000_SIDETONE_ASRC0_CLK_RST_CTL, 0x00}, + {AQT1000_SIDETONE_ASRC0_CTL0, 0x00}, + {AQT1000_SIDETONE_ASRC0_CTL1, 0x00}, + {AQT1000_SIDETONE_ASRC0_FIFO_CTL, 0xA8}, + {AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00}, + {AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00}, + {AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00}, + {AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00}, + {AQT1000_SIDETONE_ASRC0_STATUS_FIFO, 0x00}, + {AQT1000_EC_REF_HQ0_EC_REF_HQ_PATH_CTL, 0x00}, + {AQT1000_EC_REF_HQ0_EC_REF_HQ_CFG0, 0x01}, + {AQT1000_EC_REF_HQ1_EC_REF_HQ_PATH_CTL, 0x00}, + {AQT1000_EC_REF_HQ1_EC_REF_HQ_CFG0, 0x01}, + {AQT1000_EC_ASRC0_CLK_RST_CTL, 0x00}, + {AQT1000_EC_ASRC0_CTL0, 0x00}, + {AQT1000_EC_ASRC0_CTL1, 0x00}, + {AQT1000_EC_ASRC0_FIFO_CTL, 0xA8}, + {AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00}, + {AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00}, + {AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00}, + {AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00}, + {AQT1000_EC_ASRC0_STATUS_FIFO, 0x00}, + {AQT1000_EC_ASRC1_CLK_RST_CTL, 0x00}, + {AQT1000_EC_ASRC1_CTL0, 0x00}, + {AQT1000_EC_ASRC1_CTL1, 0x00}, + {AQT1000_EC_ASRC1_FIFO_CTL, 0xA8}, + {AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00}, + {AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00}, + {AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00}, + {AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00}, + {AQT1000_EC_ASRC1_STATUS_FIFO, 0x00}, + {AQT1000_PAGE13_PAGE_REGISTER, 0x00}, + {AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG0, 0x00}, + {AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG1, 0x00}, + {AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0, 0x00}, + {AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG1, 0x00}, + {AQT1000_CDC_RX_INP_MUX_EQ_IIR_CFG0, 0x00}, + {AQT1000_CDC_RX_INP_MUX_DSD_CFG0, 0x00}, + {AQT1000_CDC_RX_INP_MUX_RX_MIX_CFG0, 0x00}, + {AQT1000_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0x00}, + {AQT1000_CDC_RX_INP_MUX_ANC_CFG0, 0x00}, + {AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 0x00}, + {AQT1000_CDC_RX_INP_MUX_EC_REF_HQ_CFG0, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG1, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG1, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG1, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 0x00}, + {AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG1, 0x00}, + {AQT1000_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0x00}, + {AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0, 0x00}, + {AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x00}, + {AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00}, + {AQT1000_CDC_CLK_RST_CTRL_DSD_CONTROL, 0x00}, + {AQT1000_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL, 0x0F}, + {AQT1000_CDC_CLK_RST_CTRL_GFM_CONTROL, 0x00}, + {AQT1000_CDC_CLK_RST_CTRL_I2S_CONTROL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_PATH_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_CTL, 0x40}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, 0x00}, + {AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL, 0x00}, + {AQT1000_CDC_TOP_TOP_CFG0, 0x00}, + {AQT1000_CDC_TOP_HPHL_COMP_WR_LSB, 0x00}, + {AQT1000_CDC_TOP_HPHL_COMP_WR_MSB, 0x00}, + {AQT1000_CDC_TOP_HPHL_COMP_LUT, 0x00}, + {AQT1000_CDC_TOP_HPHL_COMP_RD_LSB, 0x00}, + {AQT1000_CDC_TOP_HPHL_COMP_RD_MSB, 0x00}, + {AQT1000_CDC_TOP_HPHR_COMP_WR_LSB, 0x00}, + {AQT1000_CDC_TOP_HPHR_COMP_WR_MSB, 0x00}, + {AQT1000_CDC_TOP_HPHR_COMP_LUT, 0x00}, + {AQT1000_CDC_TOP_HPHR_COMP_RD_LSB, 0x00}, + {AQT1000_CDC_TOP_HPHR_COMP_RD_MSB, 0x00}, + {AQT1000_CDC_DSD0_PATH_CTL, 0x00}, + {AQT1000_CDC_DSD0_CFG0, 0x00}, + {AQT1000_CDC_DSD0_CFG1, 0x00}, + {AQT1000_CDC_DSD0_CFG2, 0x42}, + {AQT1000_CDC_DSD0_CFG3, 0x00}, + {AQT1000_CDC_DSD0_CFG4, 0x02}, + {AQT1000_CDC_DSD0_CFG5, 0x00}, + {AQT1000_CDC_DSD1_PATH_CTL, 0x00}, + {AQT1000_CDC_DSD1_CFG0, 0x00}, + {AQT1000_CDC_DSD1_CFG1, 0x00}, + {AQT1000_CDC_DSD1_CFG2, 0x42}, + {AQT1000_CDC_DSD1_CFG3, 0x00}, + {AQT1000_CDC_DSD1_CFG4, 0x02}, + {AQT1000_CDC_DSD1_CFG5, 0x00}, + {AQT1000_CDC_RX_IDLE_DET_PATH_CTL, 0x00}, + {AQT1000_CDC_RX_IDLE_DET_CFG0, 0x07}, + {AQT1000_CDC_RX_IDLE_DET_CFG1, 0x3C}, + {AQT1000_CDC_RX_IDLE_DET_CFG2, 0x00}, + {AQT1000_CDC_RX_IDLE_DET_CFG3, 0x00}, + {AQT1000_CDC_DOP_DET_CTL, 0x00}, + {AQT1000_CDC_DOP_DET_CFG0, 0xFA}, + {AQT1000_CDC_DOP_DET_CFG1, 0x05}, + {AQT1000_CDC_DOP_DET_CFG2, 0x00}, + {AQT1000_CDC_DOP_DET_CFG3, 0x33}, + {AQT1000_CDC_DOP_DET_CFG4, 0x20}, + {AQT1000_CDC_DOP_DET_STATUS0, 0x00}, + {AQT1000_PAGE15_PAGE_REGISTER, 0x00}, + {AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG0, 0x1B}, + {AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG1, 0x24}, + {AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG2, 0x00}, + {AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG3, 0x08}, + {AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG0, 0x1B}, + {AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG1, 0x24}, + {AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG2, 0x00}, + {AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG3, 0x08}, + {AQT1000_CDC_DEBUG_RC_RE_ASRC_DEBUG_CFG0, 0x00}, + {AQT1000_CDC_DEBUG_ANC0_RC0_FIFO_CTL, 0x4C}, + {AQT1000_CDC_DEBUG_ANC0_RC1_FIFO_CTL, 0x4C}, + {AQT1000_CDC_DEBUG_ANC1_RC0_FIFO_CTL, 0x4C}, + {AQT1000_CDC_DEBUG_ANC1_RC1_FIFO_CTL, 0x4C}, + {AQT1000_CDC_DEBUG_ANC_RC_RST_DBG_CNTR, 0x00}, + {AQT1000_PAGE128_PAGE_REGISTER, 0x00}, + {AQT1000_TLMM_SPI_CLK_PINCFG, 0x00}, + {AQT1000_TLMM_SPI_MOSI_PINCFG, 0x00}, + {AQT1000_TLMM_SPI_MISO_PINCFG, 0x00}, + {AQT1000_TLMM_SPI_CS_N_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO1_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO2_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO3_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO4_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO5_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO6_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO7_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO8_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO9_PINCFG, 0x00}, + {AQT1000_TLMM_GPIO10_PINCFG, 0x00}, + {AQT1000_PAD_CTRL_PAD_PDN_CTRL_0, 0x00}, + {AQT1000_PAD_CTRL_PAD_PDN_CTRL_1, 0x00}, + {AQT1000_PAD_CTRL_PAD_PU_CTRL_0, 0x00}, + {AQT1000_PAD_CTRL_PAD_PU_CTRL_1, 0x00}, + {AQT1000_PAD_CTRL_GPIO_CTL_0_OE, 0x00}, + {AQT1000_PAD_CTRL_GPIO_CTL_1_OE, 0x00}, + {AQT1000_PAD_CTRL_GPIO_CTL_0_DATA, 0x00}, + {AQT1000_PAD_CTRL_GPIO_CTL_1_DATA, 0x00}, + {AQT1000_PAD_CTRL_PAD_DRVCTL, 0x00}, + {AQT1000_PAD_CTRL_PIN_STATUS, 0x00}, + {AQT1000_PAD_CTRL_MEM_CTRL, 0x00}, + {AQT1000_PAD_CTRL_PAD_INP_DISABLE_0, 0x00}, + {AQT1000_PAD_CTRL_PAD_INP_DISABLE_1, 0x00}, + {AQT1000_PAD_CTRL_PIN_CTL_OE_0, 0x00}, + {AQT1000_PAD_CTRL_PIN_CTL_OE_1, 0x00}, + {AQT1000_PAD_CTRL_PIN_CTL_DATA_0, 0x00}, + {AQT1000_PAD_CTRL_PIN_CTL_DATA_1, 0x00}, + {AQT1000_PAD_CTRL_USB_PHY_CLK_DIV, 0x0F}, + {AQT1000_PAD_CTRL_DEBUG_BUS_CDC, 0x00}, + {AQT1000_PAD_CTRL_DEBUG_BUS_SEL, 0x00}, + {AQT1000_PAD_CTRL_DEBUG_EN_1, 0x00}, + {AQT1000_PAD_CTRL_DEBUG_EN_2, 0x00}, + {AQT1000_PAD_CTRL_DEBUG_EN_3, 0x00}, + {AQT1000_PAD_CTRL_DEBUG_EN_4, 0x00}, + {AQT1000_PAD_CTRL_DEBUG_EN_5, 0x00}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_0, 0x00}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_1, 0x01}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_2, 0x02}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_3, 0x03}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_4, 0x04}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_5, 0x05}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_6, 0x06}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_7, 0x07}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_8, 0x08}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_9, 0x09}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_10, 0x0A}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_11, 0x0B}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_12, 0x0C}, + {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_13, 0x0D}, + {AQT1000_PAD_CTRL_DEBUG_READ_0, 0x0D}, + {AQT1000_PAD_CTRL_DEBUG_READ_1, 0x0D}, + {AQT1000_PAD_CTRL_DEBUG_READ_2, 0x0D}, + {AQT1000_PAD_CTRL_DEBUG_READ_3, 0x0D}, + {AQT1000_PAD_CTRL_FPGA_CTL, 0x00}, +}; + +const u8 aqt1000_page0_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE0_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_CHIP_ID_BYTE0)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_CHIP_ID_BYTE1)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_CHIP_ID_BYTE2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_CHIP_ID_BYTE3)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_TEST0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_TEST1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT0)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT1)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT3)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT4)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT5)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT6)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT7)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT8)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT9)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT10)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT11)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT12)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT13)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT14)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT15)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_STATUS)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_I2C_SLAVE_ID_NONNEGO)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_I2C_SLAVE_ID_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_I2C_SLAVE_ID_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_I2C_SLAVE_ID_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_I2C_ACTIVE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_CLK_CFG_MCLK)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_CLK_CFG_MCLK2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_CLK_CTL_CDC_DIG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_RST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_TEST0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_TEST1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT0)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT1)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT3)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT4)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT5)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT6)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT7)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT8)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT9)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT10)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT11)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT12)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT13)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT14)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT15)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_STATUS)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_BUS_MTRX_CFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_DMA_BUS_VOTE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_USB_BUS_VOTE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_BLSP_BUS_VOTE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_MEM_SD)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_RAM)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_ROM)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_RAM)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_ROM)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_CLK_CFG_FLL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_CLK_CFG_SPI_M)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_CLK_CFG_I2C_M)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_CLK_CFG_UART)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_RST_USB_SS)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_RST_BLSP)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_RST_BUS_MTRX)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_RST_MISC)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CHIP_CFG1_ANA_WAIT_STATE_CTL)] = AQT1000_RW, +}; + +const u8 aqt1000_page1_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE1_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_8)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_USER_CTL_9)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_L_VAL_CTL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_L_VAL_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_DSM_FRAC_CTL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_DSM_FRAC_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_CONFIG_CTL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_CONFIG_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_CONFIG_CTL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_CONFIG_CTL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_CONFIG_CTL_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_TEST_CTL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_TEST_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_TEST_CTL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_TEST_CTL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_TEST_CTL_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_TEST_CTL_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_TEST_CTL_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_TEST_CTL_7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_FREQ_CTL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_FREQ_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_FREQ_CTL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_FREQ_CTL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_SSC_CTL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_SSC_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_SSC_CTL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_SSC_CTL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_FLL_MODE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLL_STATUS_0)] = AQT1000_RO, + [AQT1000_REG(AQT1000_FLL_STATUS_1)] = AQT1000_RO, + [AQT1000_REG(AQT1000_FLL_STATUS_2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_FLL_STATUS_3)] = AQT1000_RO, +}; + +const u8 aqt1000_page2_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE2_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_I2S_I2S_0_TX_CFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_I2S_I2S_0_RX_CFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_I2S_I2S_0_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_I2S_I2S_CLKSRC_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_I2S_I2S_HS_CLK_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_I2S_I2S_0_RST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_I2S_SHADOW_I2S_0_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_I2S_SHADOW_I2S_0_RX_CFG)] = AQT1000_RW, +}; + +const u8 aqt1000_page5_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE5_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_MCU_INT_POLARITY)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_0)] = AQT1000_RO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_1)] = AQT1000_RO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_3)] = AQT1000_RO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_4)] = AQT1000_RO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_5)] = AQT1000_RO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_6)] = AQT1000_RO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_0)] = AQT1000_WO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_1)] = AQT1000_WO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_2)] = AQT1000_WO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_3)] = AQT1000_WO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_4)] = AQT1000_WO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_5)] = AQT1000_WO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_6)] = AQT1000_WO, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_8)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_9)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_10)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_11)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_12)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_13)] = AQT1000_RW, + [AQT1000_REG(AQT1000_INTR_CTRL_CLR_COMMIT)] = AQT1000_WO, +}; + +const u8 aqt1000_page6_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_ANA_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_BIAS)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_RX_SUPPLIES)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_HPH)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_AMIC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_AMIC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_AMIC3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_AMIC3_HPF)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_MECH)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_ELECT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_ZDET)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_RESULT_1)] = AQT1000_RO, + [AQT1000_REG(AQT1000_ANA_MBHC_RESULT_2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_ANA_MBHC_RESULT_3)] = AQT1000_RO, + [AQT1000_REG(AQT1000_ANA_MBHC_BTN0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_BTN1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_BTN2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_BTN3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_BTN4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_BTN5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_BTN6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MBHC_BTN7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MICB1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_ANA_MICB1_RAMP)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BIAS_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BIAS_CCOMP_FINE_ADJ)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LED_LED_MODE_SEL_R)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LED_LED_MISC_R)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LED_LED_MODE_SEL_G)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LED_LED_MISC_G)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LED_LED_MODE_SEL_B)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LED_LED_MISC_B)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LDOH_MODE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LDOH_BIAS)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LDOH_STB_LOADS)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LDOH_MISC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LDOL_VDDCX_ADJUST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_LDOL_DISABLE_LDOL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_EN_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_VOUT_SEL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_CTRL_VCL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_CTRL_VCL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_CTRL_CCL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_CTRL_CCL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_CTRL_CCL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_CTRL_CCL_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_CTRL_CCL_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_IBIAS_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_IBIAS_CTL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_IBIAS_CTL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_IBIAS_CTL_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_IBIAS_CTL_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_BUCK_5V_ATEST_DTEST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PON_BG_CTRL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PON_TEST_CTRL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_CTL_CLK)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_CTL_ANA)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_CTL_SPARE_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_CTL_SPARE_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_CTL_BCS)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_MOISTURE_DET_FSM_STATUS)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MBHC_TEST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MICB1_TEST_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MICB1_TEST_CTL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MICB1_TEST_CTL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MICB1_MISC_MICB_MISC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MICB1_MISC_MICB_MISC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_COM_ADC_VCM)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_COM_BIAS_ATEST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_COM_ADC_INT1_IB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_COM_ADC_INT2_IB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_COM_TXFE_DIV_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_COM_TXFE_DIV_START)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_COM_TXFE_DIV_STOP_9P6M)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_COM_TXFE_DIV_STOP_12P288M)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_1_2_TEST_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_1_2_ADC_IB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_1_2_ATEST_REFCTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_1_2_TEST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_1_2_TEST_BLK_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_1_2_TXFE_CLKDIV)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_1_2_SAR1_ERR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_TX_1_2_SAR2_ERR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_TX_3_TEST_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_3_ADC_IB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_3_ATEST_REFCTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_3_TEST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_3_TEST_BLK_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_3_TXFE_CLKDIV)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TX_3_SAR1_ERR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_TX_3_SAR2_ERR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_TX_ATEST1_2_SEL)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CLASSH_MODE_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_MODE_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_MODE_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_CTRL_VCL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_CTRL_VCL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_CTRL_CCL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_CTRL_CCL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_CTRL_CCL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_CTRL_CCL_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_CTRL_CCL_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_BUCK_TMUX_A_D)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_BUCK_SW_DRV_CNTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLASSH_SPARE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_8)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_9)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEGDAC_CTRL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEGDAC_CTRL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_VNEGDAC_CTRL_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_CTRL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_FLYBACK_TEST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_AUX_SW_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_PA_AUX_IN_CONN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_TIMER_DIV)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_OCP_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_OCP_COUNT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_ATEST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_MISC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_HPH_LDO)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_HPH_PA)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_HPH_RDACBUFF_CNP2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_HPH_RDAC_LDO)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_HPH_CNP1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_HPH_LOWPOWER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_MISC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_MISC3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_MISC4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_MISC5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_BUCK_RST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_BUCK_VREF_ERRAMP)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_FLYB_ERRAMP)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_FLYB_BUFF)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_BIAS_FLYB_MID_RST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_L_STATUS)] = AQT1000_RO, + [AQT1000_REG(AQT1000_HPH_R_STATUS)] = AQT1000_RO, + [AQT1000_REG(AQT1000_HPH_CNP_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_CNP_WG_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_CNP_WG_TIME)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_OCP_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_AUTO_CHOP)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_CHOP_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_PA_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_PA_CTL2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_L_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_L_TEST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_L_ATEST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_R_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_R_TEST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_R_ATEST)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_RDAC_CLK_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_RDAC_CLK_CTL2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_RDAC_LDO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_RDAC_CHOP_CLK_LP_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_REFBUFF_UHQA_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_REFBUFF_LP_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_L_DAC_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_R_DAC_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPHLR_SURGE_COMP_SEL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPHLR_SURGE_EN)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPHLR_SURGE_MISC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPHLR_SURGE_STATUS)] = AQT1000_RO, +}; + +const u8 aqt1000_page7_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_ANA_NEW_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_ANA_HPH2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_ANA_HPH3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_MCLK1_PRG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_XO_CAP_XTP)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_XO_CAP_XTM)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_PLL_ENABLES)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_PLL_PRESET)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_PLL_STATUS)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MBHC_NEW_ELECT_REM_CLAMP_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_CTL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_CTL_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_PLUG_DETECT_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_ZDET_ANA_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_ZDET_RAMP_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_FSM_STATUS)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MBHC_NEW_ADC_RESULT)] = AQT1000_RO, + [AQT1000_REG(AQT1000_HPH_NEW_INT_RDAC_GAIN_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_L)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_RDAC_VREF_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_RDAC_OVERRIDE_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_R)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_PA_MISC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_PA_MISC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_PA_RDAC_MISC)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_HPH_TIMER1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_HPH_TIMER2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_HPH_TIMER3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_HPH_TIMER4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_PA_RDAC_MISC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_HPH_NEW_INT_PA_RDAC_MISC3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_ULP)] = AQT1000_RW, + [AQT1000_REG(AQT1000_RX_NEW_INT_HPH_RDAC_LDO_LP)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_CLK_TEST1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_XO_TEST1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_XO_TEST2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_POST_DIV_REG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_POST_DIV_REG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_REF_DIV_REG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_REF_DIV_REG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_FILTER_REG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_FILTER_REG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_PLL_L_VAL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_PLL_M_VAL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_PLL_N_VAL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_TEST_REG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_PFD_CP_DSM_PROG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_VCO_PROG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_TEST_REG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_LDO_LOCK_CFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CLK_SYS_INT_DIG_LOCK_DET_CFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL)] = + AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_INT_MECH_DET_CURRENT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MBHC_NEW_INT_SPARE_2)] = AQT1000_RW, +}; + +const u8 aqt1000_page10_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE10_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_CLK_RESET_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_MODE_1_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_MODE_2_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_FF_SHIFT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_FB_SHIFT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_LPF_FF_A_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_LPF_FF_B_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_LPF_FB_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_SMLPF_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_DCFLT_SHIFT_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_IIR_ADAPT_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_IIR_COEFF_1_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_IIR_COEFF_2_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_FF_A_GAIN_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_FF_B_GAIN_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_FB_GAIN_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_RC_COMMON_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_FIFO_COMMON_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC0_RC0_STATUS_FMIN_CNTR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC0_RC1_STATUS_FMIN_CNTR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC0_RC0_STATUS_FMAX_CNTR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC0_RC1_STATUS_FMAX_CNTR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC0_STATUS_FIFO)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC1_CLK_RESET_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_MODE_1_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_MODE_2_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_FF_SHIFT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_FB_SHIFT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_LPF_FF_A_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_LPF_FF_B_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_LPF_FB_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_SMLPF_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_DCFLT_SHIFT_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_IIR_ADAPT_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_IIR_COEFF_1_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_IIR_COEFF_2_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_FF_A_GAIN_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_FF_B_GAIN_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_FB_GAIN_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_RC_COMMON_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_FIFO_COMMON_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_ANC1_RC0_STATUS_FMIN_CNTR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC1_RC1_STATUS_FMIN_CNTR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC1_RC0_STATUS_FMAX_CNTR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC1_RC1_STATUS_FMAX_CNTR)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_ANC1_STATUS_FIFO)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_VOL_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_VOL_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_VOL_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC7)] = AQT1000_RW, +}; + +const u8 aqt1000_page11_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE11_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL6)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL6)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_CFG2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_VOL_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_MIX_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_MIX_CFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_VOL_MIX_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_MIX_SEC0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_MIX_SEC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_DSMDEM_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_CFG2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_VOL_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_MIX_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_MIX_CFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_VOL_MIX_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_MIX_SEC0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_MIX_SEC1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_DSMDEM_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR0_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR0_PATH_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR0_PATH_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR0_PATH_CFG2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR0_PATH_CFG3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR0_COEF_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR0_COEF_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR1_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR1_PATH_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR1_PATH_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR1_PATH_CFG2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR1_PATH_CFG3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR1_COEF_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_EQ_IIR1_COEF_CFG1)] = AQT1000_RW, +}; + +const u8 aqt1000_page12_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE12_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_CRC)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_DLY_CTRL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_DECAY_CTRL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_HPH_V_PA)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_EAR_V_PA)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_HPH_V_HD)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_EAR_V_HD)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_K1_MSB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_K1_LSB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_K2_MSB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_K2_LSB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_IDLE_CTRL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_IDLE_HPH)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_IDLE_EAR)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_TEST0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_TEST1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLSH_OVR_VREF)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC0_CLK_RST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC0_CTL0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC0_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC0_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC0_STATUS_FIFO)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC1_CLK_RST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC1_CTL0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC1_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC1_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_MIXING_ASRC1_STATUS_FIFO)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_CLK_RST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_CTL0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_SIDETONE_ASRC0_STATUS_FIFO)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_REF_HQ0_EC_REF_HQ_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_REF_HQ0_EC_REF_HQ_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_REF_HQ1_EC_REF_HQ_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_REF_HQ1_EC_REF_HQ_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC0_CLK_RST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC0_CTL0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC0_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC0_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC0_STATUS_FIFO)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC1_CLK_RST_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC1_CTL0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC1_CTL1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC1_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_EC_ASRC1_STATUS_FIFO)] = AQT1000_RO, +}; + +const u8 aqt1000_page13_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE13_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_EQ_IIR_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_DSD_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_RX_MIX_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_ANC_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_EC_REF_HQ_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0)] = + AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_DSD_CONTROL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_GFM_CONTROL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_I2S_CONTROL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL)] = + AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TOP_TOP_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TOP_HPHL_COMP_WR_LSB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TOP_HPHL_COMP_WR_MSB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TOP_HPHL_COMP_LUT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TOP_HPHL_COMP_RD_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_TOP_HPHL_COMP_RD_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_TOP_HPHR_COMP_WR_LSB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TOP_HPHR_COMP_WR_MSB)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TOP_HPHR_COMP_LUT)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_TOP_HPHR_COMP_RD_LSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_TOP_HPHR_COMP_RD_MSB)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_DSD0_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD0_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD0_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD0_CFG2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD0_CFG3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD0_CFG4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD0_CFG5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD1_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD1_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD1_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD1_CFG2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD1_CFG3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD1_CFG4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DSD1_CFG5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_IDLE_DET_PATH_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_IDLE_DET_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_IDLE_DET_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_IDLE_DET_CFG2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_RX_IDLE_DET_CFG3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DOP_DET_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DOP_DET_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DOP_DET_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DOP_DET_CFG2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DOP_DET_CFG3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DOP_DET_CFG4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DOP_DET_STATUS0)] = AQT1000_RO, +}; + +const u8 aqt1000_page15_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE15_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_RC_RE_ASRC_DEBUG_CFG0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_ANC0_RC0_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_ANC0_RC1_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_ANC1_RC0_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_ANC1_RC1_FIFO_CTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_CDC_DEBUG_ANC_RC_RST_DBG_CNTR)] = AQT1000_RW, +}; + +const u8 aqt1000_page128_reg_access[AQT1000_PAGE_SIZE] = { + [AQT1000_REG(AQT1000_PAGE128_PAGE_REGISTER)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_SPI_CLK_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_SPI_MOSI_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_SPI_MISO_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_SPI_CS_N_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO1_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO2_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO3_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO4_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO5_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO6_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO7_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO8_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO9_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_TLMM_GPIO10_PINCFG)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PAD_PDN_CTRL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PAD_PDN_CTRL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PAD_PU_CTRL_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PAD_PU_CTRL_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_GPIO_CTL_0_OE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_GPIO_CTL_1_OE)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_GPIO_CTL_0_DATA)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_GPIO_CTL_1_DATA)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PAD_DRVCTL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PIN_STATUS)] = AQT1000_RO, + [AQT1000_REG(AQT1000_PAD_CTRL_MEM_CTRL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PAD_INP_DISABLE_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PAD_INP_DISABLE_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PIN_CTL_OE_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PIN_CTL_OE_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PIN_CTL_DATA_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_PIN_CTL_DATA_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_USB_PHY_CLK_DIV)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_BUS_CDC)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_BUS_SEL)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_EN_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_EN_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_EN_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_EN_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_EN_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_0)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_1)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_2)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_3)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_4)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_5)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_6)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_7)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_8)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_9)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_10)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_11)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_12)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_13)] = AQT1000_RW, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_READ_0)] = AQT1000_RO, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_READ_1)] = AQT1000_RO, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_READ_2)] = AQT1000_RO, + [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_READ_3)] = AQT1000_RO, + [AQT1000_REG(AQT1000_PAD_CTRL_FPGA_CTL)] = AQT1000_RW, +}; + +const u8 * const aqt1000_reg[AQT1000_PAGE_MAX] = { + [AQT1000_PAGE_0] = aqt1000_page0_reg_access, + [AQT1000_PAGE_1] = aqt1000_page1_reg_access, + [AQT1000_PAGE_2] = aqt1000_page2_reg_access, + [AQT1000_PAGE_5] = aqt1000_page5_reg_access, + [AQT1000_PAGE_6] = aqt1000_page6_reg_access, + [AQT1000_PAGE_7] = aqt1000_page7_reg_access, + [AQT1000_PAGE_10] = aqt1000_page10_reg_access, + [AQT1000_PAGE_11] = aqt1000_page11_reg_access, + [AQT1000_PAGE_12] = aqt1000_page12_reg_access, + [AQT1000_PAGE_13] = aqt1000_page13_reg_access, + [AQT1000_PAGE_15] = aqt1000_page15_reg_access, + [AQT1000_PAGE_128] = aqt1000_page128_reg_access, +}; + +#endif /* _AQT1000_REG_DEFAULTS_H */ diff --git a/asoc/codecs/aqt1000/aqt1000-registers.h b/asoc/codecs/aqt1000/aqt1000-registers.h new file mode 100644 index 000000000000..9033466656f7 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-registers.h @@ -0,0 +1,881 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _AQT1000_REGISTERS_H +#define _AQT1000_REGISTERS_H + +#define AQT1000_PAGE0_BASE (0x00000000) +#define AQT1000_PAGE0_PAGE_REGISTER (0x00000000) +#define AQT1000_CHIP_CFG0_BASE (0x00000001) +#define AQT1000_CHIP_CFG0_CHIP_ID_BYTE0 (0x00000001) +#define AQT1000_CHIP_CFG0_CHIP_ID_BYTE1 (0x00000002) +#define AQT1000_CHIP_CFG0_CHIP_ID_BYTE2 (0x00000003) +#define AQT1000_CHIP_CFG0_CHIP_ID_BYTE3 (0x00000004) +#define AQT1000_CHIP_CFG0_EFUSE_CTL (0x00000005) +#define AQT1000_CHIP_CFG0_EFUSE_TEST0 (0x00000006) +#define AQT1000_CHIP_CFG0_EFUSE_TEST1 (0x00000007) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT0 (0x00000009) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT1 (0x0000000A) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT2 (0x0000000B) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT3 (0x0000000C) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT4 (0x0000000D) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT5 (0x0000000E) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT6 (0x0000000F) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT7 (0x00000010) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT8 (0x00000011) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT9 (0x00000012) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT10 (0x00000013) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT11 (0x00000014) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT12 (0x00000015) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT13 (0x00000016) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT14 (0x00000017) +#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT15 (0x00000018) +#define AQT1000_CHIP_CFG0_EFUSE_STATUS (0x00000019) +#define AQT1000_CHIP_CFG0_I2C_SLAVE_ID_NONNEGO (0x0000001A) +#define AQT1000_CHIP_CFG0_I2C_SLAVE_ID_1 (0x0000001B) +#define AQT1000_CHIP_CFG0_I2C_SLAVE_ID_2 (0x0000001C) +#define AQT1000_CHIP_CFG0_I2C_SLAVE_ID_3 (0x0000001D) +#define AQT1000_CHIP_CFG0_I2C_ACTIVE (0x00000020) +#define AQT1000_CHIP_CFG0_CLK_CFG_MCLK (0x00000021) +#define AQT1000_CHIP_CFG0_CLK_CFG_MCLK2 (0x00000022) +#define AQT1000_CHIP_CFG0_CLK_CTL_CDC_DIG (0x00000023) +#define AQT1000_CHIP_CFG0_RST_CTL (0x00000032) +#define AQT1000_CHIP_CFG0_EFUSE2_CTL (0x0000003D) +#define AQT1000_CHIP_CFG0_EFUSE2_TEST0 (0x0000003E) +#define AQT1000_CHIP_CFG0_EFUSE2_TEST1 (0x0000003F) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT0 (0x00000040) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT1 (0x00000041) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT2 (0x00000042) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT3 (0x00000043) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT4 (0x00000044) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT5 (0x00000045) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT6 (0x00000046) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT7 (0x00000047) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT8 (0x00000048) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT9 (0x00000049) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT10 (0x0000004A) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT11 (0x0000004B) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT12 (0x0000004C) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT13 (0x0000004D) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT14 (0x0000004E) +#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT15 (0x0000004F) +#define AQT1000_CHIP_CFG0_EFUSE2_STATUS (0x00000050) +#define AQT1000_CHIP_CFG1_BASE (0x00000051) +#define AQT1000_CHIP_CFG1_PWR_CTL (0x00000051) +#define AQT1000_CHIP_CFG1_BUS_MTRX_CFG (0x00000052) +#define AQT1000_CHIP_CFG1_DMA_BUS_VOTE (0x00000053) +#define AQT1000_CHIP_CFG1_USB_BUS_VOTE (0x00000054) +#define AQT1000_CHIP_CFG1_BLSP_BUS_VOTE (0x00000055) +#define AQT1000_CHIP_CFG1_PWR_MEM_SD (0x00000059) +#define AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_RAM (0x0000005C) +#define AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_ROM (0x0000005D) +#define AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_RAM (0x0000005E) +#define AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_ROM (0x0000005F) +#define AQT1000_CHIP_CFG1_CLK_CFG_FLL (0x00000061) +#define AQT1000_CHIP_CFG1_CLK_CFG_SPI_M (0x00000062) +#define AQT1000_CHIP_CFG1_CLK_CFG_I2C_M (0x00000063) +#define AQT1000_CHIP_CFG1_CLK_CFG_UART (0x00000064) +#define AQT1000_CHIP_CFG1_RST_USB_SS (0x00000071) +#define AQT1000_CHIP_CFG1_RST_BLSP (0x00000072) +#define AQT1000_CHIP_CFG1_RST_BUS_MTRX (0x00000073) +#define AQT1000_CHIP_CFG1_RST_MISC (0x00000074) +#define AQT1000_CHIP_CFG1_ANA_WAIT_STATE_CTL (0x00000081) +#define AQT1000_PAGE1_BASE (0x00000100) +#define AQT1000_PAGE1_PAGE_REGISTER (0x00000100) +#define AQT1000_FLL_BASE (0x00000101) +#define AQT1000_FLL_USER_CTL_0 (0x00000101) +#define AQT1000_FLL_USER_CTL_1 (0x00000102) +#define AQT1000_FLL_USER_CTL_2 (0x00000103) +#define AQT1000_FLL_USER_CTL_3 (0x00000104) +#define AQT1000_FLL_USER_CTL_4 (0x00000105) +#define AQT1000_FLL_USER_CTL_5 (0x00000106) +#define AQT1000_FLL_USER_CTL_6 (0x00000107) +#define AQT1000_FLL_USER_CTL_7 (0x00000108) +#define AQT1000_FLL_USER_CTL_8 (0x00000109) +#define AQT1000_FLL_USER_CTL_9 (0x0000010A) +#define AQT1000_FLL_L_VAL_CTL_0 (0x0000010B) +#define AQT1000_FLL_L_VAL_CTL_1 (0x0000010C) +#define AQT1000_FLL_DSM_FRAC_CTL_0 (0x0000010D) +#define AQT1000_FLL_DSM_FRAC_CTL_1 (0x0000010E) +#define AQT1000_FLL_CONFIG_CTL_0 (0x0000010F) +#define AQT1000_FLL_CONFIG_CTL_1 (0x00000110) +#define AQT1000_FLL_CONFIG_CTL_2 (0x00000111) +#define AQT1000_FLL_CONFIG_CTL_3 (0x00000112) +#define AQT1000_FLL_CONFIG_CTL_4 (0x00000113) +#define AQT1000_FLL_TEST_CTL_0 (0x00000114) +#define AQT1000_FLL_TEST_CTL_1 (0x00000115) +#define AQT1000_FLL_TEST_CTL_2 (0x00000116) +#define AQT1000_FLL_TEST_CTL_3 (0x00000117) +#define AQT1000_FLL_TEST_CTL_4 (0x00000118) +#define AQT1000_FLL_TEST_CTL_5 (0x00000119) +#define AQT1000_FLL_TEST_CTL_6 (0x0000011A) +#define AQT1000_FLL_TEST_CTL_7 (0x0000011B) +#define AQT1000_FLL_FREQ_CTL_0 (0x0000011C) +#define AQT1000_FLL_FREQ_CTL_1 (0x0000011D) +#define AQT1000_FLL_FREQ_CTL_2 (0x0000011E) +#define AQT1000_FLL_FREQ_CTL_3 (0x0000011F) +#define AQT1000_FLL_SSC_CTL_0 (0x00000120) +#define AQT1000_FLL_SSC_CTL_1 (0x00000121) +#define AQT1000_FLL_SSC_CTL_2 (0x00000122) +#define AQT1000_FLL_SSC_CTL_3 (0x00000123) +#define AQT1000_FLL_FLL_MODE (0x00000124) +#define AQT1000_FLL_STATUS_0 (0x00000125) +#define AQT1000_FLL_STATUS_1 (0x00000126) +#define AQT1000_FLL_STATUS_2 (0x00000127) +#define AQT1000_FLL_STATUS_3 (0x00000128) +#define AQT1000_PAGE2_BASE (0x00000200) +#define AQT1000_PAGE2_PAGE_REGISTER (0x00000200) +#define AQT1000_I2S_BASE (0x00000201) +#define AQT1000_I2S_I2S_0_TX_CFG (0x00000201) +#define AQT1000_I2S_I2S_0_RX_CFG (0x00000202) +#define AQT1000_I2S_I2S_0_CTL (0x00000203) +#define AQT1000_I2S_I2S_CLKSRC_CTL (0x00000204) +#define AQT1000_I2S_I2S_HS_CLK_CTL (0x00000205) +#define AQT1000_I2S_I2S_0_RST (0x00000206) +#define AQT1000_I2S_SHADOW_I2S_0_CTL (0x00000207) +#define AQT1000_I2S_SHADOW_I2S_0_RX_CFG (0x00000208) +#define AQT1000_PAGE5_BASE (0x00000500) +#define AQT1000_PAGE5_PAGE_REGISTER (0x00000500) +#define AQT1000_INTR_CTRL_INTR_CTRL_BASE (0x00000501) +#define AQT1000_INTR_CTRL_MCU_INT_POLARITY (0x00000501) +#define AQT1000_INTR_CTRL_INT_MASK_0 (0x00000502) +#define AQT1000_INTR_CTRL_INT_MASK_1 (0x00000503) +#define AQT1000_INTR_CTRL_INT_MASK_2 (0x00000504) +#define AQT1000_INTR_CTRL_INT_MASK_3 (0x00000505) +#define AQT1000_INTR_CTRL_INT_MASK_4 (0x00000506) +#define AQT1000_INTR_CTRL_INT_MASK_5 (0x00000507) +#define AQT1000_INTR_CTRL_INT_MASK_6 (0x00000508) +#define AQT1000_INTR_CTRL_INT_STATUS_0 (0x00000509) +#define AQT1000_INTR_CTRL_INT_STATUS_1 (0x0000050A) +#define AQT1000_INTR_CTRL_INT_STATUS_2 (0x0000050B) +#define AQT1000_INTR_CTRL_INT_STATUS_3 (0x0000050C) +#define AQT1000_INTR_CTRL_INT_STATUS_4 (0x0000050D) +#define AQT1000_INTR_CTRL_INT_STATUS_5 (0x0000050E) +#define AQT1000_INTR_CTRL_INT_STATUS_6 (0x0000050F) +#define AQT1000_INTR_CTRL_INT_CLEAR_0 (0x00000510) +#define AQT1000_INTR_CTRL_INT_CLEAR_1 (0x00000511) +#define AQT1000_INTR_CTRL_INT_CLEAR_2 (0x00000512) +#define AQT1000_INTR_CTRL_INT_CLEAR_3 (0x00000513) +#define AQT1000_INTR_CTRL_INT_CLEAR_4 (0x00000514) +#define AQT1000_INTR_CTRL_INT_CLEAR_5 (0x00000515) +#define AQT1000_INTR_CTRL_INT_CLEAR_6 (0x00000516) +#define AQT1000_INTR_CTRL_INT_TYPE_0 (0x00000517) +#define AQT1000_INTR_CTRL_INT_TYPE_1 (0x00000518) +#define AQT1000_INTR_CTRL_INT_TYPE_2 (0x00000519) +#define AQT1000_INTR_CTRL_INT_TYPE_3 (0x0000051A) +#define AQT1000_INTR_CTRL_INT_TYPE_4 (0x0000051B) +#define AQT1000_INTR_CTRL_INT_TYPE_5 (0x0000051C) +#define AQT1000_INTR_CTRL_INT_TYPE_6 (0x0000051D) +#define AQT1000_INTR_CTRL_INT_TEST_EN_0 (0x0000051E) +#define AQT1000_INTR_CTRL_INT_TEST_EN_1 (0x0000051F) +#define AQT1000_INTR_CTRL_INT_TEST_EN_2 (0x00000520) +#define AQT1000_INTR_CTRL_INT_TEST_EN_3 (0x00000521) +#define AQT1000_INTR_CTRL_INT_TEST_EN_4 (0x00000522) +#define AQT1000_INTR_CTRL_INT_TEST_EN_5 (0x00000523) +#define AQT1000_INTR_CTRL_INT_TEST_EN_6 (0x00000524) +#define AQT1000_INTR_CTRL_INT_TEST_VAL_0 (0x00000525) +#define AQT1000_INTR_CTRL_INT_TEST_VAL_1 (0x00000526) +#define AQT1000_INTR_CTRL_INT_TEST_VAL_2 (0x00000527) +#define AQT1000_INTR_CTRL_INT_TEST_VAL_3 (0x00000528) +#define AQT1000_INTR_CTRL_INT_TEST_VAL_4 (0x00000529) +#define AQT1000_INTR_CTRL_INT_TEST_VAL_5 (0x0000052A) +#define AQT1000_INTR_CTRL_INT_TEST_VAL_6 (0x0000052B) +#define AQT1000_INTR_CTRL_INT_DEST_0 (0x0000052C) +#define AQT1000_INTR_CTRL_INT_DEST_1 (0x0000052D) +#define AQT1000_INTR_CTRL_INT_DEST_2 (0x0000052E) +#define AQT1000_INTR_CTRL_INT_DEST_3 (0x0000052F) +#define AQT1000_INTR_CTRL_INT_DEST_4 (0x00000530) +#define AQT1000_INTR_CTRL_INT_DEST_5 (0x00000531) +#define AQT1000_INTR_CTRL_INT_DEST_6 (0x00000532) +#define AQT1000_INTR_CTRL_INT_DEST_7 (0x00000533) +#define AQT1000_INTR_CTRL_INT_DEST_8 (0x00000534) +#define AQT1000_INTR_CTRL_INT_DEST_9 (0x00000535) +#define AQT1000_INTR_CTRL_INT_DEST_10 (0x00000536) +#define AQT1000_INTR_CTRL_INT_DEST_11 (0x00000537) +#define AQT1000_INTR_CTRL_INT_DEST_12 (0x00000538) +#define AQT1000_INTR_CTRL_INT_DEST_13 (0x00000539) +#define AQT1000_INTR_CTRL_CLR_COMMIT (0x000005E1) +#define AQT1000_ANA_BASE (0x00000600) +#define AQT1000_ANA_PAGE_REGISTER (0x00000600) +#define AQT1000_ANA_BIAS (0x00000601) +#define AQT1000_ANA_RX_SUPPLIES (0x00000608) +#define AQT1000_ANA_HPH (0x00000609) +#define AQT1000_ANA_AMIC1 (0x0000060E) +#define AQT1000_ANA_AMIC2 (0x0000060F) +#define AQT1000_ANA_AMIC3 (0x00000610) +#define AQT1000_ANA_AMIC3_HPF (0x00000611) +#define AQT1000_ANA_MBHC_MECH (0x00000614) +#define AQT1000_ANA_MBHC_ELECT (0x00000615) +#define AQT1000_ANA_MBHC_ZDET (0x00000616) +#define AQT1000_ANA_MBHC_RESULT_1 (0x00000617) +#define AQT1000_ANA_MBHC_RESULT_2 (0x00000618) +#define AQT1000_ANA_MBHC_RESULT_3 (0x00000619) +#define AQT1000_ANA_MBHC_BTN0 (0x0000061A) +#define AQT1000_ANA_MBHC_BTN1 (0x0000061B) +#define AQT1000_ANA_MBHC_BTN2 (0x0000061C) +#define AQT1000_ANA_MBHC_BTN3 (0x0000061D) +#define AQT1000_ANA_MBHC_BTN4 (0x0000061E) +#define AQT1000_ANA_MBHC_BTN5 (0x0000061F) +#define AQT1000_ANA_MBHC_BTN6 (0x00000620) +#define AQT1000_ANA_MBHC_BTN7 (0x00000621) +#define AQT1000_ANA_MICB1 (0x00000622) +#define AQT1000_ANA_MICB1_RAMP (0x00000624) +#define AQT1000_BIAS_BASE (0x00000628) +#define AQT1000_BIAS_CTL (0x00000628) +#define AQT1000_BIAS_CCOMP_FINE_ADJ (0x00000629) +#define AQT1000_LED_BASE (0x0000062E) +#define AQT1000_LED_LED_MODE_SEL_R (0x0000062E) +#define AQT1000_LED_LED_MISC_R (0x0000062F) +#define AQT1000_LED_LED_MODE_SEL_G (0x00000630) +#define AQT1000_LED_LED_MISC_G (0x00000631) +#define AQT1000_LED_LED_MODE_SEL_B (0x00000632) +#define AQT1000_LED_LED_MISC_B (0x00000633) +#define AQT1000_LDOH_BASE (0x0000063A) +#define AQT1000_LDOH_MODE (0x0000063A) +#define AQT1000_LDOH_BIAS (0x0000063B) +#define AQT1000_LDOH_STB_LOADS (0x0000063C) +#define AQT1000_LDOH_MISC1 (0x0000063D) +#define AQT1000_LDOL_BASE (0x00000640) +#define AQT1000_LDOL_VDDCX_ADJUST (0x00000640) +#define AQT1000_LDOL_DISABLE_LDOL (0x00000641) +#define AQT1000_BUCK_5V_BASE (0x00000644) +#define AQT1000_BUCK_5V_EN_CTL (0x00000644) +#define AQT1000_BUCK_5V_VOUT_SEL (0x00000645) +#define AQT1000_BUCK_5V_CTRL_VCL_1 (0x00000646) +#define AQT1000_BUCK_5V_CTRL_VCL_2 (0x00000647) +#define AQT1000_BUCK_5V_CTRL_CCL_2 (0x00000648) +#define AQT1000_BUCK_5V_CTRL_CCL_1 (0x00000649) +#define AQT1000_BUCK_5V_CTRL_CCL_3 (0x0000064A) +#define AQT1000_BUCK_5V_CTRL_CCL_4 (0x0000064B) +#define AQT1000_BUCK_5V_CTRL_CCL_5 (0x0000064C) +#define AQT1000_BUCK_5V_IBIAS_CTL_1 (0x0000064D) +#define AQT1000_BUCK_5V_IBIAS_CTL_2 (0x0000064E) +#define AQT1000_BUCK_5V_IBIAS_CTL_3 (0x0000064F) +#define AQT1000_BUCK_5V_IBIAS_CTL_4 (0x00000650) +#define AQT1000_BUCK_5V_IBIAS_CTL_5 (0x00000651) +#define AQT1000_BUCK_5V_ATEST_DTEST_CTL (0x00000652) +#define AQT1000_PON_BASE (0x00000653) +#define AQT1000_PON_BG_CTRL (0x00000653) +#define AQT1000_PON_TEST_CTRL (0x00000654) +#define AQT1000_MBHC_BASE (0x00000656) +#define AQT1000_MBHC_CTL_CLK (0x00000656) +#define AQT1000_MBHC_CTL_ANA (0x00000657) +#define AQT1000_MBHC_CTL_SPARE_1 (0x00000658) +#define AQT1000_MBHC_CTL_SPARE_2 (0x00000659) +#define AQT1000_MBHC_CTL_BCS (0x0000065A) +#define AQT1000_MBHC_MOISTURE_DET_FSM_STATUS (0x0000065B) +#define AQT1000_MBHC_TEST_CTL (0x0000065C) +#define AQT1000_MICB1_BASE (0x0000066B) +#define AQT1000_MICB1_TEST_CTL_1 (0x0000066B) +#define AQT1000_MICB1_TEST_CTL_2 (0x0000066C) +#define AQT1000_MICB1_TEST_CTL_3 (0x0000066D) +#define AQT1000_MICB1_MISC_BASE (0x0000066E) +#define AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS (0x0000066E) +#define AQT1000_MICB1_MISC_MICB_MISC1 (0x0000066F) +#define AQT1000_MICB1_MISC_MICB_MISC2 (0x00000670) +#define AQT1000_TX_COM_BASE (0x00000677) +#define AQT1000_TX_COM_ADC_VCM (0x00000677) +#define AQT1000_TX_COM_BIAS_ATEST (0x00000678) +#define AQT1000_TX_COM_ADC_INT1_IB (0x00000679) +#define AQT1000_TX_COM_ADC_INT2_IB (0x0000067A) +#define AQT1000_TX_COM_TXFE_DIV_CTL (0x0000067B) +#define AQT1000_TX_COM_TXFE_DIV_START (0x0000067C) +#define AQT1000_TX_COM_TXFE_DIV_STOP_9P6M (0x0000067D) +#define AQT1000_TX_COM_TXFE_DIV_STOP_12P288M (0x0000067E) +#define AQT1000_TX_1_2_BASE (0x0000067F) +#define AQT1000_TX_1_2_TEST_EN (0x0000067F) +#define AQT1000_TX_1_2_ADC_IB (0x00000680) +#define AQT1000_TX_1_2_ATEST_REFCTL (0x00000681) +#define AQT1000_TX_1_2_TEST_CTL (0x00000682) +#define AQT1000_TX_1_2_TEST_BLK_EN (0x00000683) +#define AQT1000_TX_1_2_TXFE_CLKDIV (0x00000684) +#define AQT1000_TX_1_2_SAR1_ERR (0x00000685) +#define AQT1000_TX_1_2_SAR2_ERR (0x00000686) +#define AQT1000_TX_3_BASE (0x00000687) +#define AQT1000_TX_3_TEST_EN (0x00000687) +#define AQT1000_TX_3_ADC_IB (0x00000688) +#define AQT1000_TX_3_ATEST_REFCTL (0x00000689) +#define AQT1000_TX_3_TEST_CTL (0x0000068A) +#define AQT1000_TX_3_TEST_BLK_EN (0x0000068B) +#define AQT1000_TX_3_TXFE_CLKDIV (0x0000068C) +#define AQT1000_TX_3_SAR1_ERR (0x0000068D) +#define AQT1000_TX_3_SAR2_ERR (0x0000068E) +#define AQT1000_TX_BASE (0x0000068F) +#define AQT1000_TX_ATEST1_2_SEL (0x0000068F) +#define AQT1000_CLASSH_BASE (0x00000697) +#define AQT1000_CLASSH_MODE_1 (0x00000697) +#define AQT1000_CLASSH_MODE_2 (0x00000698) +#define AQT1000_CLASSH_MODE_3 (0x00000699) +#define AQT1000_CLASSH_CTRL_VCL_1 (0x0000069A) +#define AQT1000_CLASSH_CTRL_VCL_2 (0x0000069B) +#define AQT1000_CLASSH_CTRL_CCL_1 (0x0000069C) +#define AQT1000_CLASSH_CTRL_CCL_2 (0x0000069D) +#define AQT1000_CLASSH_CTRL_CCL_3 (0x0000069E) +#define AQT1000_CLASSH_CTRL_CCL_4 (0x0000069F) +#define AQT1000_CLASSH_CTRL_CCL_5 (0x000006A0) +#define AQT1000_CLASSH_BUCK_TMUX_A_D (0x000006A1) +#define AQT1000_CLASSH_BUCK_SW_DRV_CNTL (0x000006A2) +#define AQT1000_CLASSH_SPARE (0x000006A3) +#define AQT1000_FLYBACK_BASE (0x000006A4) +#define AQT1000_FLYBACK_EN (0x000006A4) +#define AQT1000_FLYBACK_VNEG_CTRL_1 (0x000006A5) +#define AQT1000_FLYBACK_VNEG_CTRL_2 (0x000006A6) +#define AQT1000_FLYBACK_VNEG_CTRL_3 (0x000006A7) +#define AQT1000_FLYBACK_VNEG_CTRL_4 (0x000006A8) +#define AQT1000_FLYBACK_VNEG_CTRL_5 (0x000006A9) +#define AQT1000_FLYBACK_VNEG_CTRL_6 (0x000006AA) +#define AQT1000_FLYBACK_VNEG_CTRL_7 (0x000006AB) +#define AQT1000_FLYBACK_VNEG_CTRL_8 (0x000006AC) +#define AQT1000_FLYBACK_VNEG_CTRL_9 (0x000006AD) +#define AQT1000_FLYBACK_VNEGDAC_CTRL_1 (0x000006AE) +#define AQT1000_FLYBACK_VNEGDAC_CTRL_2 (0x000006AF) +#define AQT1000_FLYBACK_VNEGDAC_CTRL_3 (0x000006B0) +#define AQT1000_FLYBACK_CTRL_1 (0x000006B1) +#define AQT1000_FLYBACK_TEST_CTL (0x000006B2) +#define AQT1000_RX_BASE (0x000006B3) +#define AQT1000_RX_AUX_SW_CTL (0x000006B3) +#define AQT1000_RX_PA_AUX_IN_CONN (0x000006B4) +#define AQT1000_RX_TIMER_DIV (0x000006B5) +#define AQT1000_RX_OCP_CTL (0x000006B6) +#define AQT1000_RX_OCP_COUNT (0x000006B7) +#define AQT1000_RX_BIAS_ATEST (0x000006B8) +#define AQT1000_RX_BIAS_MISC1 (0x000006B9) +#define AQT1000_RX_BIAS_HPH_LDO (0x000006BA) +#define AQT1000_RX_BIAS_HPH_PA (0x000006BB) +#define AQT1000_RX_BIAS_HPH_RDACBUFF_CNP2 (0x000006BC) +#define AQT1000_RX_BIAS_HPH_RDAC_LDO (0x000006BD) +#define AQT1000_RX_BIAS_HPH_CNP1 (0x000006BE) +#define AQT1000_RX_BIAS_HPH_LOWPOWER (0x000006BF) +#define AQT1000_RX_BIAS_MISC2 (0x000006C0) +#define AQT1000_RX_BIAS_MISC3 (0x000006C1) +#define AQT1000_RX_BIAS_MISC4 (0x000006C2) +#define AQT1000_RX_BIAS_MISC5 (0x000006C3) +#define AQT1000_RX_BIAS_BUCK_RST (0x000006C4) +#define AQT1000_RX_BIAS_BUCK_VREF_ERRAMP (0x000006C5) +#define AQT1000_RX_BIAS_FLYB_ERRAMP (0x000006C6) +#define AQT1000_RX_BIAS_FLYB_BUFF (0x000006C7) +#define AQT1000_RX_BIAS_FLYB_MID_RST (0x000006C8) +#define AQT1000_HPH_BASE (0x000006C9) +#define AQT1000_HPH_L_STATUS (0x000006C9) +#define AQT1000_HPH_R_STATUS (0x000006CA) +#define AQT1000_HPH_CNP_EN (0x000006CB) +#define AQT1000_HPH_CNP_WG_CTL (0x000006CC) +#define AQT1000_HPH_CNP_WG_TIME (0x000006CD) +#define AQT1000_HPH_OCP_CTL (0x000006CE) +#define AQT1000_HPH_AUTO_CHOP (0x000006CF) +#define AQT1000_HPH_CHOP_CTL (0x000006D0) +#define AQT1000_HPH_PA_CTL1 (0x000006D1) +#define AQT1000_HPH_PA_CTL2 (0x000006D2) +#define AQT1000_HPH_L_EN (0x000006D3) +#define AQT1000_HPH_L_TEST (0x000006D4) +#define AQT1000_HPH_L_ATEST (0x000006D5) +#define AQT1000_HPH_R_EN (0x000006D6) +#define AQT1000_HPH_R_TEST (0x000006D7) +#define AQT1000_HPH_R_ATEST (0x000006D8) +#define AQT1000_HPH_RDAC_CLK_CTL1 (0x000006D9) +#define AQT1000_HPH_RDAC_CLK_CTL2 (0x000006DA) +#define AQT1000_HPH_RDAC_LDO_CTL (0x000006DB) +#define AQT1000_HPH_RDAC_CHOP_CLK_LP_CTL (0x000006DC) +#define AQT1000_HPH_REFBUFF_UHQA_CTL (0x000006DD) +#define AQT1000_HPH_REFBUFF_LP_CTL (0x000006DE) +#define AQT1000_HPH_L_DAC_CTL (0x000006DF) +#define AQT1000_HPH_R_DAC_CTL (0x000006E0) +#define AQT1000_HPHLR_BASE (0x000006E1) +#define AQT1000_HPHLR_SURGE_COMP_SEL (0x000006E1) +#define AQT1000_HPHLR_SURGE_EN (0x000006E2) +#define AQT1000_HPHLR_SURGE_MISC1 (0x000006E3) +#define AQT1000_HPHLR_SURGE_STATUS (0x000006E4) +#define AQT1000_ANA_NEW_BASE (0x00000700) +#define AQT1000_ANA_NEW_PAGE_REGISTER (0x00000700) +#define AQT1000_HPH_NEW_BASE (0x00000701) +#define AQT1000_HPH_NEW_ANA_HPH2 (0x00000701) +#define AQT1000_HPH_NEW_ANA_HPH3 (0x00000702) +#define AQT1000_CLK_SYS_BASE (0x0000070E) +#define AQT1000_CLK_SYS_MCLK1_PRG (0x0000070E) +#define AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG (0x0000070F) +#define AQT1000_CLK_SYS_XO_CAP_XTP (0x00000710) +#define AQT1000_CLK_SYS_XO_CAP_XTM (0x00000711) +#define AQT1000_CLK_SYS_PLL_ENABLES (0x00000712) +#define AQT1000_CLK_SYS_PLL_PRESET (0x00000713) +#define AQT1000_CLK_SYS_PLL_STATUS (0x00000714) +#define AQT1000_MBHC_NEW_BASE (0x0000071F) +#define AQT1000_MBHC_NEW_ELECT_REM_CLAMP_CTL (0x0000071F) +#define AQT1000_MBHC_NEW_CTL_1 (0x00000720) +#define AQT1000_MBHC_NEW_CTL_2 (0x00000721) +#define AQT1000_MBHC_NEW_PLUG_DETECT_CTL (0x00000722) +#define AQT1000_MBHC_NEW_ZDET_ANA_CTL (0x00000723) +#define AQT1000_MBHC_NEW_ZDET_RAMP_CTL (0x00000724) +#define AQT1000_MBHC_NEW_FSM_STATUS (0x00000725) +#define AQT1000_MBHC_NEW_ADC_RESULT (0x00000726) +#define AQT1000_HPH_NEW_INT_BASE (0x00000732) +#define AQT1000_HPH_NEW_INT_RDAC_GAIN_CTL (0x00000732) +#define AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_L (0x00000733) +#define AQT1000_HPH_NEW_INT_RDAC_VREF_CTL (0x00000734) +#define AQT1000_HPH_NEW_INT_RDAC_OVERRIDE_CTL (0x00000735) +#define AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_R (0x00000736) +#define AQT1000_HPH_NEW_INT_PA_MISC1 (0x00000737) +#define AQT1000_HPH_NEW_INT_PA_MISC2 (0x00000738) +#define AQT1000_HPH_NEW_INT_PA_RDAC_MISC (0x00000739) +#define AQT1000_HPH_NEW_INT_HPH_TIMER1 (0x0000073A) +#define AQT1000_HPH_NEW_INT_HPH_TIMER2 (0x0000073B) +#define AQT1000_HPH_NEW_INT_HPH_TIMER3 (0x0000073C) +#define AQT1000_HPH_NEW_INT_HPH_TIMER4 (0x0000073D) +#define AQT1000_HPH_NEW_INT_PA_RDAC_MISC2 (0x0000073E) +#define AQT1000_HPH_NEW_INT_PA_RDAC_MISC3 (0x0000073F) +#define AQT1000_RX_NEW_INT_BASE (0x00000745) +#define AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI (0x00000745) +#define AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_ULP (0x00000746) +#define AQT1000_RX_NEW_INT_HPH_RDAC_LDO_LP (0x00000747) +#define AQT1000_CLK_SYS_INT_BASE (0x0000076C) +#define AQT1000_CLK_SYS_INT_CLK_TEST1 (0x0000076C) +#define AQT1000_CLK_SYS_INT_XO_TEST1 (0x0000076D) +#define AQT1000_CLK_SYS_INT_XO_TEST2 (0x0000076E) +#define AQT1000_CLK_SYS_INT_POST_DIV_REG0 (0x0000076F) +#define AQT1000_CLK_SYS_INT_POST_DIV_REG1 (0x00000770) +#define AQT1000_CLK_SYS_INT_REF_DIV_REG0 (0x00000771) +#define AQT1000_CLK_SYS_INT_REF_DIV_REG1 (0x00000772) +#define AQT1000_CLK_SYS_INT_FILTER_REG0 (0x00000773) +#define AQT1000_CLK_SYS_INT_FILTER_REG1 (0x00000774) +#define AQT1000_CLK_SYS_INT_PLL_L_VAL (0x00000775) +#define AQT1000_CLK_SYS_INT_PLL_M_VAL (0x00000776) +#define AQT1000_CLK_SYS_INT_PLL_N_VAL (0x00000777) +#define AQT1000_CLK_SYS_INT_TEST_REG0 (0x00000778) +#define AQT1000_CLK_SYS_INT_PFD_CP_DSM_PROG (0x00000779) +#define AQT1000_CLK_SYS_INT_VCO_PROG (0x0000077A) +#define AQT1000_CLK_SYS_INT_TEST_REG1 (0x0000077B) +#define AQT1000_CLK_SYS_INT_LDO_LOCK_CFG (0x0000077C) +#define AQT1000_CLK_SYS_INT_DIG_LOCK_DET_CFG (0x0000077D) +#define AQT1000_MBHC_NEW_INT_BASE (0x000007AF) +#define AQT1000_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL (0x000007AF) +#define AQT1000_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL (0x000007B0) +#define AQT1000_MBHC_NEW_INT_MECH_DET_CURRENT (0x000007B1) +#define AQT1000_MBHC_NEW_INT_SPARE_2 (0x000007B2) +#define AQT1000_PAGE10_BASE (0x00000A00) +#define AQT1000_PAGE10_PAGE_REGISTER (0x00000A00) +#define AQT1000_CDC_ANC0_BASE (0x00000A01) +#define AQT1000_CDC_ANC0_CLK_RESET_CTL (0x00000A01) +#define AQT1000_CDC_ANC0_MODE_1_CTL (0x00000A02) +#define AQT1000_CDC_ANC0_MODE_2_CTL (0x00000A03) +#define AQT1000_CDC_ANC0_FF_SHIFT (0x00000A04) +#define AQT1000_CDC_ANC0_FB_SHIFT (0x00000A05) +#define AQT1000_CDC_ANC0_LPF_FF_A_CTL (0x00000A06) +#define AQT1000_CDC_ANC0_LPF_FF_B_CTL (0x00000A07) +#define AQT1000_CDC_ANC0_LPF_FB_CTL (0x00000A08) +#define AQT1000_CDC_ANC0_SMLPF_CTL (0x00000A09) +#define AQT1000_CDC_ANC0_DCFLT_SHIFT_CTL (0x00000A0A) +#define AQT1000_CDC_ANC0_IIR_ADAPT_CTL (0x00000A0B) +#define AQT1000_CDC_ANC0_IIR_COEFF_1_CTL (0x00000A0C) +#define AQT1000_CDC_ANC0_IIR_COEFF_2_CTL (0x00000A0D) +#define AQT1000_CDC_ANC0_FF_A_GAIN_CTL (0x00000A0E) +#define AQT1000_CDC_ANC0_FF_B_GAIN_CTL (0x00000A0F) +#define AQT1000_CDC_ANC0_FB_GAIN_CTL (0x00000A10) +#define AQT1000_CDC_ANC0_RC_COMMON_CTL (0x00000A11) +#define AQT1000_CDC_ANC0_FIFO_COMMON_CTL (0x00000A13) +#define AQT1000_CDC_ANC0_RC0_STATUS_FMIN_CNTR (0x00000A14) +#define AQT1000_CDC_ANC0_RC1_STATUS_FMIN_CNTR (0x00000A15) +#define AQT1000_CDC_ANC0_RC0_STATUS_FMAX_CNTR (0x00000A16) +#define AQT1000_CDC_ANC0_RC1_STATUS_FMAX_CNTR (0x00000A17) +#define AQT1000_CDC_ANC0_STATUS_FIFO (0x00000A18) +#define AQT1000_CDC_ANC1_BASE (0x00000A19) +#define AQT1000_CDC_ANC1_CLK_RESET_CTL (0x00000A19) +#define AQT1000_CDC_ANC1_MODE_1_CTL (0x00000A1A) +#define AQT1000_CDC_ANC1_MODE_2_CTL (0x00000A1B) +#define AQT1000_CDC_ANC1_FF_SHIFT (0x00000A1C) +#define AQT1000_CDC_ANC1_FB_SHIFT (0x00000A1D) +#define AQT1000_CDC_ANC1_LPF_FF_A_CTL (0x00000A1E) +#define AQT1000_CDC_ANC1_LPF_FF_B_CTL (0x00000A1F) +#define AQT1000_CDC_ANC1_LPF_FB_CTL (0x00000A20) +#define AQT1000_CDC_ANC1_SMLPF_CTL (0x00000A21) +#define AQT1000_CDC_ANC1_DCFLT_SHIFT_CTL (0x00000A22) +#define AQT1000_CDC_ANC1_IIR_ADAPT_CTL (0x00000A23) +#define AQT1000_CDC_ANC1_IIR_COEFF_1_CTL (0x00000A24) +#define AQT1000_CDC_ANC1_IIR_COEFF_2_CTL (0x00000A25) +#define AQT1000_CDC_ANC1_FF_A_GAIN_CTL (0x00000A26) +#define AQT1000_CDC_ANC1_FF_B_GAIN_CTL (0x00000A27) +#define AQT1000_CDC_ANC1_FB_GAIN_CTL (0x00000A28) +#define AQT1000_CDC_ANC1_RC_COMMON_CTL (0x00000A29) +#define AQT1000_CDC_ANC1_FIFO_COMMON_CTL (0x00000A2B) +#define AQT1000_CDC_ANC1_RC0_STATUS_FMIN_CNTR (0x00000A2C) +#define AQT1000_CDC_ANC1_RC1_STATUS_FMIN_CNTR (0x00000A2D) +#define AQT1000_CDC_ANC1_RC0_STATUS_FMAX_CNTR (0x00000A2E) +#define AQT1000_CDC_ANC1_RC1_STATUS_FMAX_CNTR (0x00000A2F) +#define AQT1000_CDC_ANC1_STATUS_FIFO (0x00000A30) +#define AQT1000_CDC_TX0_BASE (0x00000A31) +#define AQT1000_CDC_TX0_TX_PATH_CTL (0x00000A31) +#define AQT1000_CDC_TX0_TX_PATH_CFG0 (0x00000A32) +#define AQT1000_CDC_TX0_TX_PATH_CFG1 (0x00000A33) +#define AQT1000_CDC_TX0_TX_VOL_CTL (0x00000A34) +#define AQT1000_CDC_TX0_TX_PATH_SEC0 (0x00000A37) +#define AQT1000_CDC_TX0_TX_PATH_SEC1 (0x00000A38) +#define AQT1000_CDC_TX0_TX_PATH_SEC2 (0x00000A39) +#define AQT1000_CDC_TX0_TX_PATH_SEC3 (0x00000A3A) +#define AQT1000_CDC_TX0_TX_PATH_SEC4 (0x00000A3B) +#define AQT1000_CDC_TX0_TX_PATH_SEC5 (0x00000A3C) +#define AQT1000_CDC_TX0_TX_PATH_SEC6 (0x00000A3D) +#define AQT1000_CDC_TX1_BASE (0x00000A41) +#define AQT1000_CDC_TX1_TX_PATH_CTL (0x00000A41) +#define AQT1000_CDC_TX1_TX_PATH_CFG0 (0x00000A42) +#define AQT1000_CDC_TX1_TX_PATH_CFG1 (0x00000A43) +#define AQT1000_CDC_TX1_TX_VOL_CTL (0x00000A44) +#define AQT1000_CDC_TX1_TX_PATH_SEC0 (0x00000A47) +#define AQT1000_CDC_TX1_TX_PATH_SEC1 (0x00000A48) +#define AQT1000_CDC_TX1_TX_PATH_SEC2 (0x00000A49) +#define AQT1000_CDC_TX1_TX_PATH_SEC3 (0x00000A4A) +#define AQT1000_CDC_TX1_TX_PATH_SEC4 (0x00000A4B) +#define AQT1000_CDC_TX1_TX_PATH_SEC5 (0x00000A4C) +#define AQT1000_CDC_TX1_TX_PATH_SEC6 (0x00000A4D) +#define AQT1000_CDC_TX2_BASE (0x00000A51) +#define AQT1000_CDC_TX2_TX_PATH_CTL (0x00000A51) +#define AQT1000_CDC_TX2_TX_PATH_CFG0 (0x00000A52) +#define AQT1000_CDC_TX2_TX_PATH_CFG1 (0x00000A53) +#define AQT1000_CDC_TX2_TX_VOL_CTL (0x00000A54) +#define AQT1000_CDC_TX2_TX_PATH_SEC0 (0x00000A57) +#define AQT1000_CDC_TX2_TX_PATH_SEC1 (0x00000A58) +#define AQT1000_CDC_TX2_TX_PATH_SEC2 (0x00000A59) +#define AQT1000_CDC_TX2_TX_PATH_SEC3 (0x00000A5A) +#define AQT1000_CDC_TX2_TX_PATH_SEC4 (0x00000A5B) +#define AQT1000_CDC_TX2_TX_PATH_SEC5 (0x00000A5C) +#define AQT1000_CDC_TX2_TX_PATH_SEC6 (0x00000A5D) +#define AQT1000_CDC_TX2_TX_PATH_SEC7 (0x00000A5E) +#define AQT1000_PAGE11_BASE (0x00000B00) +#define AQT1000_PAGE11_PAGE_REGISTER (0x00000B00) +#define AQT1000_CDC_COMPANDER1_BASE (0x00000B01) +#define AQT1000_CDC_COMPANDER1_CTL0 (0x00000B01) +#define AQT1000_CDC_COMPANDER1_CTL1 (0x00000B02) +#define AQT1000_CDC_COMPANDER1_CTL2 (0x00000B03) +#define AQT1000_CDC_COMPANDER1_CTL3 (0x00000B04) +#define AQT1000_CDC_COMPANDER1_CTL4 (0x00000B05) +#define AQT1000_CDC_COMPANDER1_CTL5 (0x00000B06) +#define AQT1000_CDC_COMPANDER1_CTL6 (0x00000B07) +#define AQT1000_CDC_COMPANDER1_CTL7 (0x00000B08) +#define AQT1000_CDC_COMPANDER2_BASE (0x00000B09) +#define AQT1000_CDC_COMPANDER2_CTL0 (0x00000B09) +#define AQT1000_CDC_COMPANDER2_CTL1 (0x00000B0A) +#define AQT1000_CDC_COMPANDER2_CTL2 (0x00000B0B) +#define AQT1000_CDC_COMPANDER2_CTL3 (0x00000B0C) +#define AQT1000_CDC_COMPANDER2_CTL4 (0x00000B0D) +#define AQT1000_CDC_COMPANDER2_CTL5 (0x00000B0E) +#define AQT1000_CDC_COMPANDER2_CTL6 (0x00000B0F) +#define AQT1000_CDC_COMPANDER2_CTL7 (0x00000B10) +#define AQT1000_CDC_RX1_BASE (0x00000B55) +#define AQT1000_CDC_RX1_RX_PATH_CTL (0x00000B55) +#define AQT1000_CDC_RX1_RX_PATH_CFG0 (0x00000B56) +#define AQT1000_CDC_RX1_RX_PATH_CFG1 (0x00000B57) +#define AQT1000_CDC_RX1_RX_PATH_CFG2 (0x00000B58) +#define AQT1000_CDC_RX1_RX_VOL_CTL (0x00000B59) +#define AQT1000_CDC_RX1_RX_PATH_MIX_CTL (0x00000B5A) +#define AQT1000_CDC_RX1_RX_PATH_MIX_CFG (0x00000B5B) +#define AQT1000_CDC_RX1_RX_VOL_MIX_CTL (0x00000B5C) +#define AQT1000_CDC_RX1_RX_PATH_SEC0 (0x00000B5D) +#define AQT1000_CDC_RX1_RX_PATH_SEC1 (0x00000B5E) +#define AQT1000_CDC_RX1_RX_PATH_SEC2 (0x00000B5F) +#define AQT1000_CDC_RX1_RX_PATH_SEC3 (0x00000B60) +#define AQT1000_CDC_RX1_RX_PATH_SEC4 (0x00000B61) +#define AQT1000_CDC_RX1_RX_PATH_SEC5 (0x00000B62) +#define AQT1000_CDC_RX1_RX_PATH_SEC6 (0x00000B63) +#define AQT1000_CDC_RX1_RX_PATH_SEC7 (0x00000B64) +#define AQT1000_CDC_RX1_RX_PATH_MIX_SEC0 (0x00000B65) +#define AQT1000_CDC_RX1_RX_PATH_MIX_SEC1 (0x00000B66) +#define AQT1000_CDC_RX1_RX_PATH_DSMDEM_CTL (0x00000B67) +#define AQT1000_CDC_RX2_BASE (0x00000B69) +#define AQT1000_CDC_RX2_RX_PATH_CTL (0x00000B69) +#define AQT1000_CDC_RX2_RX_PATH_CFG0 (0x00000B6A) +#define AQT1000_CDC_RX2_RX_PATH_CFG1 (0x00000B6B) +#define AQT1000_CDC_RX2_RX_PATH_CFG2 (0x00000B6C) +#define AQT1000_CDC_RX2_RX_VOL_CTL (0x00000B6D) +#define AQT1000_CDC_RX2_RX_PATH_MIX_CTL (0x00000B6E) +#define AQT1000_CDC_RX2_RX_PATH_MIX_CFG (0x00000B6F) +#define AQT1000_CDC_RX2_RX_VOL_MIX_CTL (0x00000B70) +#define AQT1000_CDC_RX2_RX_PATH_SEC0 (0x00000B71) +#define AQT1000_CDC_RX2_RX_PATH_SEC1 (0x00000B72) +#define AQT1000_CDC_RX2_RX_PATH_SEC2 (0x00000B73) +#define AQT1000_CDC_RX2_RX_PATH_SEC3 (0x00000B74) +#define AQT1000_CDC_RX2_RX_PATH_SEC4 (0x00000B75) +#define AQT1000_CDC_RX2_RX_PATH_SEC5 (0x00000B76) +#define AQT1000_CDC_RX2_RX_PATH_SEC6 (0x00000B77) +#define AQT1000_CDC_RX2_RX_PATH_SEC7 (0x00000B78) +#define AQT1000_CDC_RX2_RX_PATH_MIX_SEC0 (0x00000B79) +#define AQT1000_CDC_RX2_RX_PATH_MIX_SEC1 (0x00000B7A) +#define AQT1000_CDC_RX2_RX_PATH_DSMDEM_CTL (0x00000B7B) +#define AQT1000_CDC_EQ_IIR0_BASE (0x00000BD1) +#define AQT1000_CDC_EQ_IIR0_PATH_CTL (0x00000BD1) +#define AQT1000_CDC_EQ_IIR0_PATH_CFG0 (0x00000BD2) +#define AQT1000_CDC_EQ_IIR0_PATH_CFG1 (0x00000BD3) +#define AQT1000_CDC_EQ_IIR0_PATH_CFG2 (0x00000BD4) +#define AQT1000_CDC_EQ_IIR0_PATH_CFG3 (0x00000BD5) +#define AQT1000_CDC_EQ_IIR0_COEF_CFG0 (0x00000BD6) +#define AQT1000_CDC_EQ_IIR0_COEF_CFG1 (0x00000BD7) +#define AQT1000_CDC_EQ_IIR1_BASE (0x00000BE1) +#define AQT1000_CDC_EQ_IIR1_PATH_CTL (0x00000BE1) +#define AQT1000_CDC_EQ_IIR1_PATH_CFG0 (0x00000BE2) +#define AQT1000_CDC_EQ_IIR1_PATH_CFG1 (0x00000BE3) +#define AQT1000_CDC_EQ_IIR1_PATH_CFG2 (0x00000BE4) +#define AQT1000_CDC_EQ_IIR1_PATH_CFG3 (0x00000BE5) +#define AQT1000_CDC_EQ_IIR1_COEF_CFG0 (0x00000BE6) +#define AQT1000_CDC_EQ_IIR1_COEF_CFG1 (0x00000BE7) +#define AQT1000_PAGE12_BASE (0x00000C00) +#define AQT1000_PAGE12_PAGE_REGISTER (0x00000C00) +#define AQT1000_CDC_CLSH_CDC_CLSH_BASE (0x00000C01) +#define AQT1000_CDC_CLSH_CRC (0x00000C01) +#define AQT1000_CDC_CLSH_DLY_CTRL (0x00000C02) +#define AQT1000_CDC_CLSH_DECAY_CTRL (0x00000C03) +#define AQT1000_CDC_CLSH_HPH_V_PA (0x00000C04) +#define AQT1000_CDC_CLSH_EAR_V_PA (0x00000C05) +#define AQT1000_CDC_CLSH_HPH_V_HD (0x00000C06) +#define AQT1000_CDC_CLSH_EAR_V_HD (0x00000C07) +#define AQT1000_CDC_CLSH_K1_MSB (0x00000C08) +#define AQT1000_CDC_CLSH_K1_LSB (0x00000C09) +#define AQT1000_CDC_CLSH_K2_MSB (0x00000C0A) +#define AQT1000_CDC_CLSH_K2_LSB (0x00000C0B) +#define AQT1000_CDC_CLSH_IDLE_CTRL (0x00000C0C) +#define AQT1000_CDC_CLSH_IDLE_HPH (0x00000C0D) +#define AQT1000_CDC_CLSH_IDLE_EAR (0x00000C0E) +#define AQT1000_CDC_CLSH_TEST0 (0x00000C0F) +#define AQT1000_CDC_CLSH_TEST1 (0x00000C10) +#define AQT1000_CDC_CLSH_OVR_VREF (0x00000C11) +#define AQT1000_MIXING_ASRC0_BASE (0x00000C55) +#define AQT1000_MIXING_ASRC0_CLK_RST_CTL (0x00000C55) +#define AQT1000_MIXING_ASRC0_CTL0 (0x00000C56) +#define AQT1000_MIXING_ASRC0_CTL1 (0x00000C57) +#define AQT1000_MIXING_ASRC0_FIFO_CTL (0x00000C58) +#define AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_LSB (0x00000C59) +#define AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_MSB (0x00000C5A) +#define AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_LSB (0x00000C5B) +#define AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_MSB (0x00000C5C) +#define AQT1000_MIXING_ASRC0_STATUS_FIFO (0x00000C5D) +#define AQT1000_MIXING_ASRC1_BASE (0x00000C61) +#define AQT1000_MIXING_ASRC1_CLK_RST_CTL (0x00000C61) +#define AQT1000_MIXING_ASRC1_CTL0 (0x00000C62) +#define AQT1000_MIXING_ASRC1_CTL1 (0x00000C63) +#define AQT1000_MIXING_ASRC1_FIFO_CTL (0x00000C64) +#define AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_LSB (0x00000C65) +#define AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_MSB (0x00000C66) +#define AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_LSB (0x00000C67) +#define AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_MSB (0x00000C68) +#define AQT1000_MIXING_ASRC1_STATUS_FIFO (0x00000C69) +#define AQT1000_CDC_SIDETONE_SRC0_BASE (0x00000CB5) +#define AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL (0x00000CB5) +#define AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1 (0x00000CB6) +#define AQT1000_SIDETONE_ASRC0_BASE (0x00000CBD) +#define AQT1000_SIDETONE_ASRC0_CLK_RST_CTL (0x00000CBD) +#define AQT1000_SIDETONE_ASRC0_CTL0 (0x00000CBE) +#define AQT1000_SIDETONE_ASRC0_CTL1 (0x00000CBF) +#define AQT1000_SIDETONE_ASRC0_FIFO_CTL (0x00000CC0) +#define AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB (0x00000CC1) +#define AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB (0x00000CC2) +#define AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB (0x00000CC3) +#define AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB (0x00000CC4) +#define AQT1000_SIDETONE_ASRC0_STATUS_FIFO (0x00000CC5) +#define AQT1000_EC_REF_HQ0_BASE (0x00000CD5) +#define AQT1000_EC_REF_HQ0_EC_REF_HQ_PATH_CTL (0x00000CD5) +#define AQT1000_EC_REF_HQ0_EC_REF_HQ_CFG0 (0x00000CD6) +#define AQT1000_EC_REF_HQ1_BASE (0x00000CDD) +#define AQT1000_EC_REF_HQ1_EC_REF_HQ_PATH_CTL (0x00000CDD) +#define AQT1000_EC_REF_HQ1_EC_REF_HQ_CFG0 (0x00000CDE) +#define AQT1000_EC_ASRC0_BASE (0x00000CE5) +#define AQT1000_EC_ASRC0_CLK_RST_CTL (0x00000CE5) +#define AQT1000_EC_ASRC0_CTL0 (0x00000CE6) +#define AQT1000_EC_ASRC0_CTL1 (0x00000CE7) +#define AQT1000_EC_ASRC0_FIFO_CTL (0x00000CE8) +#define AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_LSB (0x00000CE9) +#define AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_MSB (0x00000CEA) +#define AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_LSB (0x00000CEB) +#define AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_MSB (0x00000CEC) +#define AQT1000_EC_ASRC0_STATUS_FIFO (0x00000CED) +#define AQT1000_EC_ASRC1_BASE (0x00000CF1) +#define AQT1000_EC_ASRC1_CLK_RST_CTL (0x00000CF1) +#define AQT1000_EC_ASRC1_CTL0 (0x00000CF2) +#define AQT1000_EC_ASRC1_CTL1 (0x00000CF3) +#define AQT1000_EC_ASRC1_FIFO_CTL (0x00000CF4) +#define AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_LSB (0x00000CF5) +#define AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_MSB (0x00000CF6) +#define AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_LSB (0x00000CF7) +#define AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_MSB (0x00000CF8) +#define AQT1000_EC_ASRC1_STATUS_FIFO (0x00000CF9) +#define AQT1000_PAGE13_BASE (0x00000D00) +#define AQT1000_PAGE13_PAGE_REGISTER (0x00000D00) +#define AQT1000_CDC_RX_INP_MUX_CDC_RX_INP_MUX_BASE (0x00000D01) +#define AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG0 (0x00000D03) +#define AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG1 (0x00000D04) +#define AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0 (0x00000D05) +#define AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG1 (0x00000D06) +#define AQT1000_CDC_RX_INP_MUX_EQ_IIR_CFG0 (0x00000D11) +#define AQT1000_CDC_RX_INP_MUX_DSD_CFG0 (0x00000D12) +#define AQT1000_CDC_RX_INP_MUX_RX_MIX_CFG0 (0x00000D13) +#define AQT1000_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0 (0x00000D18) +#define AQT1000_CDC_RX_INP_MUX_ANC_CFG0 (0x00000D1A) +#define AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0 (0x00000D1B) +#define AQT1000_CDC_RX_INP_MUX_EC_REF_HQ_CFG0 (0x00000D1C) +#define AQT1000_CDC_TX_INP_MUX_CDC_TX_INP_MUX_BASE (0x00000D1D) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG0 (0x00000D1D) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG1 (0x00000D1E) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG0 (0x00000D1F) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG1 (0x00000D20) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG0 (0x00000D21) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG1 (0x00000D22) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG0 (0x00000D29) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG1 (0x00000D2A) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG0 (0x00000D2B) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG1 (0x00000D2C) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG0 (0x00000D2D) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG1 (0x00000D2E) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG0 (0x00000D2F) +#define AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG1 (0x00000D30) +#define AQT1000_CDC_SIDETONE_IIR_INP_MUX_CDC_SIDETONE_IIR_INP_MUX_BASE (0xD31) +#define AQT1000_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0 (0x00000D31) +#define AQT1000_CDC_IF_ROUTER_CDC_IF_ROUTER_BASE (0x00000D3D) +#define AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0 (0x00000D3D) +#define AQT1000_CDC_CLK_RST_CTRL_CDC_CLK_RST_CTRL_BASE (0x00000D41) +#define AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL (0x00000D41) +#define AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL (0x00000D42) +#define AQT1000_CDC_CLK_RST_CTRL_DSD_CONTROL (0x00000D44) +#define AQT1000_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL (0x00000D45) +#define AQT1000_CDC_CLK_RST_CTRL_GFM_CONTROL (0x00000D46) +#define AQT1000_CDC_CLK_RST_CTRL_I2S_CONTROL (0x00000D47) +#define AQT1000_CDC_SIDETONE_IIR0_BASE (0x00000D55) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_PATH_CTL (0x00000D55) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL (0x00000D56) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL (0x00000D57) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL (0x00000D58) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL (0x00000D59) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL (0x00000D5A) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL (0x00000D5B) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL (0x00000D5C) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL (0x00000D5D) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_CTL (0x00000D5E) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL (0x00000D5F) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL (0x00000D60) +#define AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL (0x00000D61) +#define AQT1000_CDC_TOP_CDC_TOP_BASE (0x00000D81) +#define AQT1000_CDC_TOP_TOP_CFG0 (0x00000D81) +#define AQT1000_CDC_TOP_HPHL_COMP_WR_LSB (0x00000D89) +#define AQT1000_CDC_TOP_HPHL_COMP_WR_MSB (0x00000D8A) +#define AQT1000_CDC_TOP_HPHL_COMP_LUT (0x00000D8B) +#define AQT1000_CDC_TOP_HPHL_COMP_RD_LSB (0x00000D8C) +#define AQT1000_CDC_TOP_HPHL_COMP_RD_MSB (0x00000D8D) +#define AQT1000_CDC_TOP_HPHR_COMP_WR_LSB (0x00000D8E) +#define AQT1000_CDC_TOP_HPHR_COMP_WR_MSB (0x00000D8F) +#define AQT1000_CDC_TOP_HPHR_COMP_LUT (0x00000D90) +#define AQT1000_CDC_TOP_HPHR_COMP_RD_LSB (0x00000D91) +#define AQT1000_CDC_TOP_HPHR_COMP_RD_MSB (0x00000D92) +#define AQT1000_CDC_DSD0_BASE (0x00000DB1) +#define AQT1000_CDC_DSD0_PATH_CTL (0x00000DB1) +#define AQT1000_CDC_DSD0_CFG0 (0x00000DB2) +#define AQT1000_CDC_DSD0_CFG1 (0x00000DB3) +#define AQT1000_CDC_DSD0_CFG2 (0x00000DB4) +#define AQT1000_CDC_DSD0_CFG3 (0x00000DB5) +#define AQT1000_CDC_DSD0_CFG4 (0x00000DB6) +#define AQT1000_CDC_DSD0_CFG5 (0x00000DB7) +#define AQT1000_CDC_DSD1_BASE (0x00000DC1) +#define AQT1000_CDC_DSD1_PATH_CTL (0x00000DC1) +#define AQT1000_CDC_DSD1_CFG0 (0x00000DC2) +#define AQT1000_CDC_DSD1_CFG1 (0x00000DC3) +#define AQT1000_CDC_DSD1_CFG2 (0x00000DC4) +#define AQT1000_CDC_DSD1_CFG3 (0x00000DC5) +#define AQT1000_CDC_DSD1_CFG4 (0x00000DC6) +#define AQT1000_CDC_DSD1_CFG5 (0x00000DC7) +#define AQT1000_CDC_RX_IDLE_DET_CDC_RX_IDLE_DET_BASE (0x00000DD1) +#define AQT1000_CDC_RX_IDLE_DET_PATH_CTL (0x00000DD1) +#define AQT1000_CDC_RX_IDLE_DET_CFG0 (0x00000DD2) +#define AQT1000_CDC_RX_IDLE_DET_CFG1 (0x00000DD3) +#define AQT1000_CDC_RX_IDLE_DET_CFG2 (0x00000DD4) +#define AQT1000_CDC_RX_IDLE_DET_CFG3 (0x00000DD5) +#define AQT1000_CDC_DOP_DET_CDC_DOP_DET_BASE (0x00000DD9) +#define AQT1000_CDC_DOP_DET_CTL (0x00000DD9) +#define AQT1000_CDC_DOP_DET_CFG0 (0x00000DDA) +#define AQT1000_CDC_DOP_DET_CFG1 (0x00000DDB) +#define AQT1000_CDC_DOP_DET_CFG2 (0x00000DDC) +#define AQT1000_CDC_DOP_DET_CFG3 (0x00000DDD) +#define AQT1000_CDC_DOP_DET_CFG4 (0x00000DDE) +#define AQT1000_CDC_DOP_DET_STATUS0 (0x00000DE1) +#define AQT1000_PAGE15_BASE (0x00000F00) +#define AQT1000_PAGE15_PAGE_REGISTER (0x00000F00) +#define AQT1000_CDC_DEBUG_CDC_DEBUG_BASE (0x00000FA1) +#define AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG0 (0x00000FA1) +#define AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG1 (0x00000FA2) +#define AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG2 (0x00000FA3) +#define AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG3 (0x00000FA4) +#define AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG0 (0x00000FA5) +#define AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG1 (0x00000FA6) +#define AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG2 (0x00000FA7) +#define AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG3 (0x00000FA8) +#define AQT1000_CDC_DEBUG_RC_RE_ASRC_DEBUG_CFG0 (0x00000FAB) +#define AQT1000_CDC_DEBUG_ANC0_RC0_FIFO_CTL (0x00000FAC) +#define AQT1000_CDC_DEBUG_ANC0_RC1_FIFO_CTL (0x00000FAD) +#define AQT1000_CDC_DEBUG_ANC1_RC0_FIFO_CTL (0x00000FAE) +#define AQT1000_CDC_DEBUG_ANC1_RC1_FIFO_CTL (0x00000FAF) +#define AQT1000_CDC_DEBUG_ANC_RC_RST_DBG_CNTR (0x00000FB0) +#define AQT1000_PAGE128_BASE (0x00008000) +#define AQT1000_PAGE128_PAGE_REGISTER (0x00008000) +#define AQT1000_TLMM_TLMM_BASE (0x00008001) +#define AQT1000_TLMM_SPI_CLK_PINCFG (0x00008001) +#define AQT1000_TLMM_SPI_MOSI_PINCFG (0x00008002) +#define AQT1000_TLMM_SPI_MISO_PINCFG (0x00008003) +#define AQT1000_TLMM_SPI_CS_N_PINCFG (0x00008004) +#define AQT1000_TLMM_GPIO1_PINCFG (0x00008005) +#define AQT1000_TLMM_GPIO2_PINCFG (0x00008006) +#define AQT1000_TLMM_GPIO3_PINCFG (0x00008007) +#define AQT1000_TLMM_GPIO4_PINCFG (0x00008008) +#define AQT1000_TLMM_GPIO5_PINCFG (0x00008009) +#define AQT1000_TLMM_GPIO6_PINCFG (0x0000800A) +#define AQT1000_TLMM_GPIO7_PINCFG (0x0000800B) +#define AQT1000_TLMM_GPIO8_PINCFG (0x0000800C) +#define AQT1000_TLMM_GPIO9_PINCFG (0x0000800D) +#define AQT1000_TLMM_GPIO10_PINCFG (0x0000800E) +#define AQT1000_PAD_CTRL_PAD_CTRL_BASE (0x00008031) +#define AQT1000_PAD_CTRL_PAD_PDN_CTRL_0 (0x00008031) +#define AQT1000_PAD_CTRL_PAD_PDN_CTRL_1 (0x00008032) +#define AQT1000_PAD_CTRL_PAD_PU_CTRL_0 (0x00008033) +#define AQT1000_PAD_CTRL_PAD_PU_CTRL_1 (0x00008034) +#define AQT1000_PAD_CTRL_GPIO_CTL_0_OE (0x00008036) +#define AQT1000_PAD_CTRL_GPIO_CTL_1_OE (0x00008037) +#define AQT1000_PAD_CTRL_GPIO_CTL_0_DATA (0x00008038) +#define AQT1000_PAD_CTRL_GPIO_CTL_1_DATA (0x00008039) +#define AQT1000_PAD_CTRL_PAD_DRVCTL (0x0000803A) +#define AQT1000_PAD_CTRL_PIN_STATUS (0x0000803B) +#define AQT1000_PAD_CTRL_MEM_CTRL (0x0000803C) +#define AQT1000_PAD_CTRL_PAD_INP_DISABLE_0 (0x0000803E) +#define AQT1000_PAD_CTRL_PAD_INP_DISABLE_1 (0x0000803F) +#define AQT1000_PAD_CTRL_PIN_CTL_OE_0 (0x00008040) +#define AQT1000_PAD_CTRL_PIN_CTL_OE_1 (0x00008041) +#define AQT1000_PAD_CTRL_PIN_CTL_DATA_0 (0x00008042) +#define AQT1000_PAD_CTRL_PIN_CTL_DATA_1 (0x00008043) +#define AQT1000_PAD_CTRL_USB_PHY_CLK_DIV (0x00008044) +#define AQT1000_PAD_CTRL_DEBUG_BUS_CDC (0x00008045) +#define AQT1000_PAD_CTRL_DEBUG_BUS_SEL (0x00008046) +#define AQT1000_PAD_CTRL_DEBUG_EN_1 (0x00008047) +#define AQT1000_PAD_CTRL_DEBUG_EN_2 (0x00008048) +#define AQT1000_PAD_CTRL_DEBUG_EN_3 (0x00008049) +#define AQT1000_PAD_CTRL_DEBUG_EN_4 (0x0000804A) +#define AQT1000_PAD_CTRL_DEBUG_EN_5 (0x0000804B) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_0 (0x0000804C) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_1 (0x0000804D) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_2 (0x0000804E) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_3 (0x0000804F) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_4 (0x00008050) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_5 (0x00008051) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_6 (0x00008052) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_7 (0x00008053) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_8 (0x00008054) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_9 (0x00008055) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_10 (0x00008056) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_11 (0x00008057) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_12 (0x00008058) +#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_13 (0x00008059) +#define AQT1000_PAD_CTRL_DEBUG_READ_0 (0x0000805A) +#define AQT1000_PAD_CTRL_DEBUG_READ_1 (0x0000805B) +#define AQT1000_PAD_CTRL_DEBUG_READ_2 (0x0000805C) +#define AQT1000_PAD_CTRL_DEBUG_READ_3 (0x0000805D) +#define AQT1000_PAD_CTRL_FPGA_CTL (0x00008061) +#define AQT1000_MAX_REGISTER (0x000080FF) + +#endif /*_AQT_REGISTERS_H*/ diff --git a/asoc/codecs/aqt1000/aqt1000-regmap.c b/asoc/codecs/aqt1000/aqt1000-regmap.c new file mode 100644 index 000000000000..e38c32748f31 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-regmap.c @@ -0,0 +1,110 @@ +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "aqt1000-registers.h" +#include "aqt1000-reg-defaults.h" +#include "aqt1000-internal.h" + +static bool aqt1000_is_readable_register(struct device *dev, unsigned int reg) +{ + u8 pg_num, reg_offset; + const u8 *reg_tbl = NULL; + + /* + * Get the page number from MSB of codec register. If its 0x80, assign + * the corresponding page index PAGE_0x80. + */ + pg_num = reg >> 0x8; + if (pg_num == 0x80) + pg_num = AQT1000_PAGE_128; + else if (pg_num > 15) + return false; + + reg_tbl = aqt1000_reg[pg_num]; + reg_offset = reg & 0xFF; + + if (reg_tbl && reg_tbl[reg_offset]) + return true; + else + return false; +} + +static bool aqt1000_is_volatile_register(struct device *dev, unsigned int reg) +{ + u8 pg_num, reg_offset; + const u8 *reg_tbl = NULL; + + pg_num = reg >> 0x8; + if (pg_num == 0x80) + pg_num = AQT1000_PAGE_128; + else if (pg_num > 15) + return false; + + reg_tbl = aqt1000_reg[pg_num]; + reg_offset = reg & 0xFF; + + if (reg_tbl && reg_tbl[reg_offset] == AQT1000_RO) + return true; + + /* IIR Coeff registers are not cacheable */ + if ((reg >= AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL) && + (reg <= AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL)) + return true; + + if ((reg >= AQT1000_CDC_ANC0_IIR_COEFF_1_CTL) && + (reg <= AQT1000_CDC_ANC0_FB_GAIN_CTL)) + return true; + + if ((reg >= AQT1000_CDC_ANC1_IIR_COEFF_1_CTL) && + (reg <= AQT1000_CDC_ANC1_FB_GAIN_CTL)) + return true; + + /* + * Need to mark volatile for registers that are writable but + * only few bits are read-only + */ + switch (reg) { + case AQT1000_BUCK_5V_CTRL_CCL_1: + case AQT1000_BIAS_CCOMP_FINE_ADJ: + case AQT1000_ANA_BIAS: + case AQT1000_BUCK_5V_IBIAS_CTL_4: + case AQT1000_BUCK_5V_CTRL_CCL_2: + case AQT1000_CHIP_CFG0_RST_CTL: + case AQT1000_CHIP_CFG0_CLK_CTL_CDC_DIG: + case AQT1000_CHIP_CFG0_CLK_CFG_MCLK: + case AQT1000_CHIP_CFG0_EFUSE_CTL: + case AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL: + case AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL: + case AQT1000_ANA_RX_SUPPLIES: + case AQT1000_ANA_MBHC_MECH: + case AQT1000_ANA_MBHC_ELECT: + case AQT1000_ANA_MBHC_ZDET: + case AQT1000_ANA_MICB1: + case AQT1000_BUCK_5V_EN_CTL: + return true; + } + + return false; +} + +struct regmap_config aqt1000_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = aqt1000_defaults, + .num_reg_defaults = ARRAY_SIZE(aqt1000_defaults), + .max_register = AQT1000_MAX_REGISTER, + .volatile_reg = aqt1000_is_volatile_register, + .readable_reg = aqt1000_is_readable_register, +}; diff --git a/asoc/codecs/aqt1000/aqt1000-routing.h b/asoc/codecs/aqt1000/aqt1000-routing.h new file mode 100644 index 000000000000..9dc74a425ae3 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-routing.h @@ -0,0 +1,170 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef AQT1000_ROUTING_H +#define AQT1000_ROUTING_H + +#include + +const struct snd_soc_dapm_route aqt_audio_map[] = { + + /* CDC Tx interface */ + + {"AQT AIF1 CAP", NULL, "AQT AIF1 CAP Mixer"}, + {"AQT AIF1 CAP Mixer", "TX0", "AQT TX0_MUX"}, + {"AQT AIF1 CAP Mixer", "TX1", "AQT TX1_MUX"}, + + {"AQT TX0_MUX", "DEC_L", "AQT ADC0 MUX"}, + {"AQT TX0_MUX", "DEC_R", "AQT ADC1 MUX"}, + {"AQT TX0_MUX", "DEC_V", "AQT ADC2 MUX"}, + + {"AQT TX1_MUX", "DEC_L", "AQT ADC0 MUX"}, + {"AQT TX1_MUX", "DEC_R", "AQT ADC1 MUX"}, + {"AQT TX1_MUX", "DEC_V", "AQT ADC2 MUX"}, + + {"AQT ADC0 MUX", "AMIC", "AQT AMIC0_MUX"}, + {"AQT ADC0 MUX", "ANC_FB0", "AQT ANC_FB_TUNE0"}, + {"AQT ADC0 MUX", "ANC_FB1", "AQT ANC_FB_TUNE1"}, + + {"AQT ADC1 MUX", "AMIC", "AQT AMIC1_MUX"}, + {"AQT ADC1 MUX", "ANC_FB0", "AQT ANC_FB_TUNE0"}, + {"AQT ADC1 MUX", "ANC_FB1", "AQT ANC_FB_TUNE1"}, + + {"AQT ADC2 MUX", "AMIC", "AQT AMIC2_MUX"}, + {"AQT ADC2 MUX", "ANC_FB0", "AQT ANC_FB_TUNE0"}, + {"AQT ADC2 MUX", "ANC_FB1", "AQT ANC_FB_TUNE1"}, + + {"AQT AMIC0_MUX", "ADC_L", "AQT ADC_L"}, + {"AQT AMIC0_MUX", "ADC_R", "AQT ADC_R"}, + {"AQT AMIC0_MUX", "ADC_V", "AQT ADC_V"}, + + {"AQT AMIC1_MUX", "ADC_L", "AQT ADC_L"}, + {"AQT AMIC1_MUX", "ADC_R", "AQT ADC_R"}, + {"AQT AMIC1_MUX", "ADC_V", "AQT ADC_V"}, + + {"AQT AMIC2_MUX", "ADC_L", "AQT ADC_L"}, + {"AQT AMIC2_MUX", "ADC_R", "AQT ADC_R"}, + {"AQT AMIC2_MUX", "ADC_V", "AQT ADC_V"}, + + {"AQT ADC_L", NULL, "AQT AMIC1"}, + {"AQT ADC_R", NULL, "AQT AMIC2"}, + {"AQT ADC_V", NULL, "AQT AMIC3"}, + + {"AQT AMIC10_MUX", "ADC_L", "AQT ADC_L"}, + {"AQT AMIC10_MUX", "ADC_R", "AQT ADC_R"}, + {"AQT AMIC10_MUX", "ADC_V", "AQT ADC_V"}, + + {"AQT AMIC11_MUX", "ADC_L", "AQT ADC_L"}, + {"AQT AMIC11_MUX", "ADC_R", "AQT ADC_R"}, + {"AQT AMIC11_MUX", "ADC_V", "AQT ADC_V"}, + + {"AQT AMIC12_MUX", "ADC_L", "AQT ADC_L"}, + {"AQT AMIC12_MUX", "ADC_R", "AQT ADC_R"}, + {"AQT AMIC12_MUX", "ADC_V", "AQT ADC_V"}, + + {"AQT AMIC13_MUX", "ADC_L", "AQT ADC_L"}, + {"AQT AMIC13_MUX", "ADC_R", "AQT ADC_R"}, + {"AQT AMIC13_MUX", "ADC_V", "AQT ADC_V"}, + + {"AQT ANC OUT HPHL Enable", "Switch", "AQT AMIC10_MUX"}, + {"AQT ANC OUT HPHL Enable", "Switch", "AQT AMIC11_MUX"}, + {"AQT ANC OUT HPHR Enable", "Switch", "AQT AMIC12_MUX"}, + {"AQT ANC OUT HPHR Enable", "Switch", "AQT AMIC13_MUX"}, + + {"AQT RX INT1 MIX2", NULL, "AQT ANC OUT HPHL Enable"}, + {"AQT RX INT2 MIX2", NULL, "AQT ANC OUT HPHR Enable"}, + + {"AQT ANC0 FB MUX", "ANC_IN_HPHL", "AQT RX INT1 MIX2"}, + {"AQT ANC1 FB MUX", "ANC_IN_HPHR", "AQT RX INT2 MIX2"}, + + {"AQT I2S_L RX", "AIF1_PB", "AQT AIF1 PB"}, + {"AQT I2S_R RX", "AIF1_PB", "AQT AIF1 PB"}, + + {"AQT RX INT1_1 MUX", "I2S_L", "AQT I2S_L RX"}, + {"AQT RX INT1_1 MUX", "I2S_R", "AQT I2S_R RX"}, + {"AQT RX INT1_1 MUX", "DEC_L", "AQT ADC0 MUX"}, + {"AQT RX INT1_1 MUX", "DEC_R", "AQT ADC1 MUX"}, + {"AQT RX INT1_1 MUX", "DEC_V", "AQT ADC2 MUX"}, + + {"AQT RX INT2_1 MUX", "I2S_L", "AQT I2S_L RX"}, + {"AQT RX INT2_1 MUX", "I2S_R", "AQT I2S_R RX"}, + {"AQT RX INT2_1 MUX", "DEC_L", "AQT ADC0 MUX"}, + {"AQT RX INT2_1 MUX", "DEC_R", "AQT ADC1 MUX"}, + {"AQT RX INT2_1 MUX", "DEC_V", "AQT ADC2 MUX"}, + + {"AQT RX INT1_2 MUX", "I2S_L", "AQT I2S_L RX"}, + {"AQT RX INT1_2 MUX", "I2S_R", "AQT I2S_R RX"}, + {"AQT RX INT1_2 MUX", "DEC_L", "AQT ADC0 MUX"}, + {"AQT RX INT1_2 MUX", "DEC_R", "AQT ADC1 MUX"}, + {"AQT RX INT1_2 MUX", "DEC_V", "AQT ADC2 MUX"}, + {"AQT RX INT1_2 MUX", "IIR0", "AQT IIR0"}, + + {"AQT RX INT2_2 MUX", "I2S_L", "AQT I2S_L RX"}, + {"AQT RX INT2_2 MUX", "I2S_R", "AQT I2S_R RX"}, + {"AQT RX INT2_2 MUX", "DEC_L", "AQT ADC0 MUX"}, + {"AQT RX INT2_2 MUX", "DEC_R", "AQT ADC1 MUX"}, + {"AQT RX INT2_2 MUX", "DEC_V", "AQT ADC2 MUX"}, + {"AQT RX INT2_2 MUX", "IIR0", "AQT IIR0"}, + + {"AQT RX INT1_1 INTERP", NULL, "AQT RX INT1_1 MUX"}, + {"AQT RX INT1 MIX1", NULL, "AQT RX INT1_1 INTERP"}, + {"AQT RX INT1 MIX2", NULL, "AQT RX INT1 MIX1"}, + + {"AQT RX INT1_2 INTERP", NULL, "AQT RX INT1_2 MUX"}, + {"AQT RX INT1 MIX1", NULL, "AQT RX INT1_2 INTERP"}, + + {"AQT ASRC0 MUX", "ASRC_IN_HPHL", "AQT RX INT1_2 INTERP"}, + {"AQT RX INT1 MIX1", "HPHL Switch", "AQT ASRC0 MUX"}, + + {"AQT RX INT2_1 INTERP", NULL, "AQT RX INT2_1 MUX"}, + {"AQT RX INT2 MIX1", NULL, "AQT RX INT2_1 INTERP"}, + {"AQT RX INT2 MIX2", NULL, "AQT RX INT2 MIX1"}, + + {"AQT RX INT2_2 INTERP", NULL, "AQT RX INT2_2 MUX"}, + {"AQT RX INT2 MIX1", NULL, "AQT RX INT2_2 INTERP"}, + + {"AQT ASRC1 MUX", "ASRC_IN_HPHR", "AQT RX INT2_2 INTERP"}, + {"AQT RX INT2 MIX1", "HPHR Switch", "AQT ASRC1 MUX"}, + + {"AQT RX INT1 DEM MUX", "CLSH_DSM_OUT", "AQT RX INT1 MIX2"}, + {"AQT RX INT1 DAC", NULL, "AQT RX INT1 DEM MUX"}, + {"AQT RX INT1 DAC", NULL, "AQT RX_BIAS"}, + {"AQT HPHL PA", NULL, "AQT RX INT1 DAC"}, + {"AQT HPHL", NULL, "AQT HPHL PA"}, + + {"AQT RX INT2 DEM MUX", "CLSH_DSM_OUT", "AQT RX INT2 MIX2"}, + {"AQT RX INT2 DAC", NULL, "AQT RX INT2 DEM MUX"}, + {"AQT RX INT2 DAC", NULL, "AQT RX_BIAS"}, + {"AQT HPHR PA", NULL, "AQT RX INT2 DAC"}, + {"AQT HPHR", NULL, "AQT HPHR PA"}, + + {"AQT ANC HPHL PA", NULL, "AQT RX INT1 DAC"}, + {"AQT ANC HPHL", NULL, "AQT ANC HPHL PA"}, + + {"AQT ANC HPHR PA", NULL, "AQT RX INT2 DAC"}, + {"AQT ANC HPHR", NULL, "AQT ANC HPHR PA"}, + + {"AQT IIR0", NULL, "AQT TX_PATH2"}, + {"AQT SRC0", NULL, "AQT IIR0"}, + {"AQT RX INT1 MIX2", "SRC0", "AQT SRC0"}, + {"AQT RX INT2 MIX2", "SRC0", "AQT SRC0"}, + + /* Native clk main path routing */ + {"AQT RX INT1_1 NATIVE MUX", "ON", "AQT RX INT1_1 MUX"}, + {"AQT RX INT1_1 INTERP", NULL, "AQT RX INT1_1 NATIVE MUX"}, + {"AQT RX INT1_1 NATIVE MUX", NULL, "AQT RX INT1 NATIVE SUPPLY"}, + + {"AQT RX INT2_1 NATIVE MUX", "ON", "AQT RX INT2_1 MUX"}, + {"AQT RX INT2_1 INTERP", NULL, "AQT RX INT2_1 NATIVE MUX"}, + {"AQT RX INT2_1 NATIVE MUX", NULL, "AQT RX INT2 NATIVE SUPPLY"}, +}; + +#endif diff --git a/asoc/codecs/aqt1000/aqt1000-utils.c b/asoc/codecs/aqt1000/aqt1000-utils.c new file mode 100644 index 000000000000..f1c16de8a686 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-utils.c @@ -0,0 +1,199 @@ +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include "aqt1000.h" +#include "aqt1000-utils.h" + +#define REG_BYTES 2 +#define VAL_BYTES 1 +/* + * Page Register Address that APP Proc uses to + * access codec registers is identified as 0x00 + */ +#define PAGE_REG_ADDR 0x00 + +static int aqt_page_write(struct aqt1000 *aqt, unsigned short *reg) +{ + int ret = 0; + unsigned short c_reg, reg_addr; + u8 pg_num, prev_pg_num; + + c_reg = *reg; + pg_num = c_reg >> 8; + reg_addr = c_reg & 0xff; + if (aqt->prev_pg_valid) { + prev_pg_num = aqt->prev_pg; + if (prev_pg_num != pg_num) { + ret = aqt->write_dev( + aqt, PAGE_REG_ADDR, + (void *) &pg_num, 1); + if (ret < 0) + dev_err(aqt->dev, + "%s: page write error, pg_num: 0x%x\n", + __func__, pg_num); + else { + aqt->prev_pg = pg_num; + dev_dbg(aqt->dev, "%s: Page 0x%x Write to 0x00\n", + __func__, pg_num); + } + } + } else { + ret = aqt->write_dev( + aqt, PAGE_REG_ADDR, (void *) &pg_num, 1); + if (ret < 0) + dev_err(aqt->dev, + "%s: page write error, pg_num: 0x%x\n", + __func__, pg_num); + else { + aqt->prev_pg = pg_num; + aqt->prev_pg_valid = true; + dev_dbg(aqt->dev, "%s: Page 0x%x Write to 0x00\n", + __func__, pg_num); + } + } + *reg = reg_addr; + return ret; +} + +static int regmap_bus_read(void *context, const void *reg, size_t reg_size, + void *val, size_t val_size) +{ + struct device *dev = context; + struct aqt1000 *aqt = dev_get_drvdata(dev); + unsigned short c_reg, rreg; + int ret, i; + + if (!aqt) { + dev_err(dev, "%s: aqt is NULL\n", __func__); + return -EINVAL; + } + if (!reg || !val) { + dev_err(dev, "%s: reg or val is NULL\n", __func__); + return -EINVAL; + } + + if (reg_size != REG_BYTES) { + dev_err(dev, "%s: register size %zd bytes, not supported\n", + __func__, reg_size); + return -EINVAL; + } + + mutex_lock(&aqt->io_lock); + c_reg = *(u16 *)reg; + rreg = c_reg; + + ret = aqt_page_write(aqt, &c_reg); + if (ret) + goto err; + ret = aqt->read_dev(aqt, c_reg, val, val_size); + if (ret < 0) + dev_err(dev, "%s: Codec read failed (%d), reg: 0x%x, size:%zd\n", + __func__, ret, rreg, val_size); + else { + for (i = 0; i < val_size; i++) + dev_dbg(dev, "%s: Read 0x%02x from 0x%x\n", + __func__, ((u8 *)val)[i], rreg + i); + } +err: + mutex_unlock(&aqt->io_lock); + return ret; +} + +static int regmap_bus_gather_write(void *context, + const void *reg, size_t reg_size, + const void *val, size_t val_size) +{ + struct device *dev = context; + struct aqt1000 *aqt = dev_get_drvdata(dev); + unsigned short c_reg, rreg; + int ret, i; + + if (!aqt) { + dev_err(dev, "%s: aqt is NULL\n", __func__); + return -EINVAL; + } + if (!reg || !val) { + dev_err(dev, "%s: reg or val is NULL\n", __func__); + return -EINVAL; + } + if (reg_size != REG_BYTES) { + dev_err(dev, "%s: register size %zd bytes, not supported\n", + __func__, reg_size); + return -EINVAL; + } + mutex_lock(&aqt->io_lock); + c_reg = *(u16 *)reg; + rreg = c_reg; + + ret = aqt_page_write(aqt, &c_reg); + if (ret) + goto err; + + for (i = 0; i < val_size; i++) + dev_dbg(dev, "Write %02x to 0x%x\n", ((u8 *)val)[i], + rreg + i); + + ret = aqt->write_dev(aqt, c_reg, (void *) val, val_size); + if (ret < 0) + dev_err(dev, "%s: Codec write failed (%d), reg:0x%x, size:%zd\n", + __func__, ret, rreg, val_size); + +err: + mutex_unlock(&aqt->io_lock); + return ret; +} + +static int regmap_bus_write(void *context, const void *data, size_t count) +{ + struct device *dev = context; + struct aqt1000 *aqt = dev_get_drvdata(dev); + + if (!aqt) + return -EINVAL; + + WARN_ON(count < REG_BYTES); + + return regmap_bus_gather_write(context, data, REG_BYTES, + data + REG_BYTES, + count - REG_BYTES); +} + +static struct regmap_bus regmap_bus_config = { + .write = regmap_bus_write, + .gather_write = regmap_bus_gather_write, + .read = regmap_bus_read, + .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, + .val_format_endian_default = REGMAP_ENDIAN_NATIVE, +}; + +/* + * aqt1000_regmap_init: + * Initialize aqt1000 register map + * + * @dev: pointer to wcd device + * @config: pointer to register map config + * + * Returns pointer to regmap structure for success + * or NULL in case of failure. + */ +struct regmap *aqt1000_regmap_init(struct device *dev, + const struct regmap_config *config) +{ + return devm_regmap_init(dev, ®map_bus_config, dev, config); +} +EXPORT_SYMBOL(aqt1000_regmap_init); diff --git a/asoc/codecs/aqt1000/aqt1000-utils.h b/asoc/codecs/aqt1000/aqt1000-utils.h new file mode 100644 index 000000000000..9f68cf12b064 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-utils.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __WCD9XXX_UTILS_H__ +#define __WCD9XXX_UTILS_H__ + +#include +#include +#include + +struct regmap *aqt1000_regmap_init(struct device *dev, + const struct regmap_config *config); +#endif diff --git a/asoc/codecs/aqt1000/aqt1000.c b/asoc/codecs/aqt1000/aqt1000.c new file mode 100644 index 000000000000..aff8976e84f3 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000.c @@ -0,0 +1,3216 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "aqt1000-registers.h" +#include "aqt1000.h" +#include "aqt1000-routing.h" +#include "../wcdcal-hwdep.h" +#include "aqt1000-internal.h" + +#define AQT1000_CODEC_HWDEP_NODE 1001 +#define AQT1000_TX_UNMUTE_DELAY_MS 40 +#define TX_HPF_CUT_OFF_FREQ_MASK 0x60 +#define CF_MIN_3DB_4HZ 0x0 +#define CF_MIN_3DB_75HZ 0x1 +#define CF_MIN_3DB_150HZ 0x2 + +static struct interp_sample_rate sr_val_tbl[] = { + {8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5}, + {192000, 0x6}, {384000, 0x7}, {44100, 0x9}, {88200, 0xA}, + {176400, 0xB}, {352800, 0xC}, +}; + +static int tx_unmute_delay = AQT1000_TX_UNMUTE_DELAY_MS; +module_param(tx_unmute_delay, int, 0664); +MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path"); + +static void aqt_codec_set_tx_hold(struct snd_soc_codec *, u16, bool); + +/* Cutoff frequency for high pass filter */ +static const char * const cf_text[] = { + "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ" +}; + +static const char * const rx_cf_text[] = { + "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ", + "CF_NEG_3DB_0P48HZ" +}; + +struct aqt1000_anc_header { + u32 reserved[3]; + u32 num_anc_slots; +}; + +static SOC_ENUM_SINGLE_DECL(cf_dec0_enum, AQT1000_CDC_TX0_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec1_enum, AQT1000_CDC_TX1_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_dec2_enum, AQT1000_CDC_TX2_TX_PATH_CFG0, 5, + cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int1_1_enum, AQT1000_CDC_RX1_RX_PATH_CFG2, 0, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, AQT1000_CDC_RX1_RX_PATH_MIX_CFG, 2, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int2_1_enum, AQT1000_CDC_RX2_RX_PATH_CFG2, 0, + rx_cf_text); +static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, AQT1000_CDC_RX2_RX_PATH_MIX_CFG, 2, + rx_cf_text); + +static const DECLARE_TLV_DB_SCALE(hph_gain, -3000, 150, 0); +static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 150, 0); +static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); + +static int aqt_get_anc_slot(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = aqt->anc_slot; + return 0; +} + +static int aqt_put_anc_slot(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + aqt->anc_slot = ucontrol->value.integer.value[0]; + return 0; +} + +static int aqt_get_anc_func(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = (aqt->anc_func == true ? 1 : 0); + return 0; +} + +static int aqt_put_anc_func(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + + mutex_lock(&aqt->codec_mutex); + aqt->anc_func = (!ucontrol->value.integer.value[0] ? false : true); + dev_dbg(codec->dev, "%s: anc_func %x", __func__, aqt->anc_func); + + if (aqt->anc_func == true) { + snd_soc_dapm_enable_pin(dapm, "ANC HPHL PA"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHR PA"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHL"); + snd_soc_dapm_enable_pin(dapm, "ANC HPHR"); + snd_soc_dapm_disable_pin(dapm, "HPHL PA"); + snd_soc_dapm_disable_pin(dapm, "HPHR PA"); + snd_soc_dapm_disable_pin(dapm, "HPHL"); + snd_soc_dapm_disable_pin(dapm, "HPHR"); + } else { + snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHL"); + snd_soc_dapm_disable_pin(dapm, "ANC HPHR"); + snd_soc_dapm_enable_pin(dapm, "HPHL"); + snd_soc_dapm_enable_pin(dapm, "HPHR"); + snd_soc_dapm_enable_pin(dapm, "HPHL PA"); + snd_soc_dapm_enable_pin(dapm, "HPHR PA"); + } + mutex_unlock(&aqt->codec_mutex); + + snd_soc_dapm_sync(dapm); + return 0; +} + +static const char *const aqt_anc_func_text[] = {"OFF", "ON"}; +static const struct soc_enum aqt_anc_func_enum = + SOC_ENUM_SINGLE_EXT(2, aqt_anc_func_text); + +static int aqt_rx_hph_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = aqt->hph_mode; + return 0; +} + +static int aqt_rx_hph_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + u32 mode_val; + + mode_val = ucontrol->value.enumerated.item[0]; + + dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val); + + if (mode_val == 0) { + dev_warn(codec->dev, "%s:Invalid HPH Mode, default to Cls-H LOHiFi\n", + __func__); + mode_val = CLS_H_LOHIFI; + } + aqt->hph_mode = mode_val; + return 0; +} + +static const char * const rx_hph_mode_mux_text[] = { + "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI", + "CLS_H_ULP", "CLS_AB_HIFI", +}; + +static const struct soc_enum rx_hph_mode_mux_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text), + rx_hph_mode_mux_text); + +static int aqt_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + ucontrol->value.integer.value[0] = (snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_CTL) & + (1 << band_idx)) != 0; + + dev_dbg(codec->dev, "%s: IIR0 band #%d enable %d\n", __func__, + band_idx, (uint32_t)ucontrol->value.integer.value[0]); + + return 0; +} + +static int aqt_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + bool iir_band_en_status; + int value = ucontrol->value.integer.value[0]; + + /* Mask first 5 bits, 6-8 are reserved */ + snd_soc_update_bits(codec, AQT1000_CDC_SIDETONE_IIR0_IIR_CTL, + (1 << band_idx), (value << band_idx)); + + iir_band_en_status = ((snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_CTL) & + (1 << band_idx)) != 0); + dev_dbg(codec->dev, "%s: IIR0 band #%d enable %d\n", __func__, + band_idx, iir_band_en_status); + + return 0; +} + +static uint32_t aqt_get_iir_band_coeff(struct snd_soc_codec *codec, + int band_idx, int coeff_idx) +{ + uint32_t value = 0; + + /* Address does not automatically update if reading */ + snd_soc_write(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t)) & 0x7F); + + value |= snd_soc_read(codec, AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL); + + snd_soc_write(codec, AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 1) & 0x7F); + + value |= (snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL) << 8); + + snd_soc_write(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 2) & 0x7F); + + value |= (snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL) << 16); + + snd_soc_write(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 3) & 0x7F); + + /* Mask bits top 2 bits since they are reserved */ + value |= ((snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL) + & 0x3F) << 24); + + return value; +} + +static int aqt_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + ucontrol->value.integer.value[0] = + aqt_get_iir_band_coeff(codec, band_idx, 0); + ucontrol->value.integer.value[1] = + aqt_get_iir_band_coeff(codec, band_idx, 1); + ucontrol->value.integer.value[2] = + aqt_get_iir_band_coeff(codec, band_idx, 2); + ucontrol->value.integer.value[3] = + aqt_get_iir_band_coeff(codec, band_idx, 3); + ucontrol->value.integer.value[4] = + aqt_get_iir_band_coeff(codec, band_idx, 4); + + dev_dbg(codec->dev, "%s: IIR band #%d b0 = 0x%x\n" + "%s: IIR band #%d b1 = 0x%x\n" + "%s: IIR band #%d b2 = 0x%x\n" + "%s: IIR band #%d a1 = 0x%x\n" + "%s: IIR band #%d a2 = 0x%x\n", + __func__, band_idx, + (uint32_t)ucontrol->value.integer.value[0], + __func__, band_idx, + (uint32_t)ucontrol->value.integer.value[1], + __func__, band_idx, + (uint32_t)ucontrol->value.integer.value[2], + __func__, band_idx, + (uint32_t)ucontrol->value.integer.value[3], + __func__, band_idx, + (uint32_t)ucontrol->value.integer.value[4]); + + return 0; +} + +static void aqt_set_iir_band_coeff(struct snd_soc_codec *codec, + int band_idx, uint32_t value) +{ + snd_soc_write(codec, + (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL), + (value & 0xFF)); + + snd_soc_write(codec, + (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL), + (value >> 8) & 0xFF); + + snd_soc_write(codec, + (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL), + (value >> 16) & 0xFF); + + /* Mask top 2 bits, 7-8 are reserved */ + snd_soc_write(codec, + (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL), + (value >> 24) & 0x3F); +} + +static int aqt_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int coeff_idx; + + /* + * Mask top bit it is reserved + * Updates addr automatically for each B2 write + */ + snd_soc_write(codec, + (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL), + (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); + + for (coeff_idx = 0; coeff_idx < AQT1000_CDC_SIDETONE_IIR_COEFF_MAX; + coeff_idx++) { + aqt_set_iir_band_coeff(codec, band_idx, + ucontrol->value.integer.value[coeff_idx]); + } + + dev_dbg(codec->dev, "%s: IIR band #%d b0 = 0x%x\n" + "%s: IIR band #%d b1 = 0x%x\n" + "%s: IIR band #%d b2 = 0x%x\n" + "%s: IIR band #%d a1 = 0x%x\n" + "%s: IIR band #%d a2 = 0x%x\n", + __func__, band_idx, + aqt_get_iir_band_coeff(codec, band_idx, 0), + __func__, band_idx, + aqt_get_iir_band_coeff(codec, band_idx, 1), + __func__, band_idx, + aqt_get_iir_band_coeff(codec, band_idx, 2), + __func__, band_idx, + aqt_get_iir_band_coeff(codec, band_idx, 3), + __func__, band_idx, + aqt_get_iir_band_coeff(codec, band_idx, 4)); + + return 0; +} + +static int aqt_compander_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = aqt->comp_enabled[comp]; + return 0; +} + +static int aqt_compander_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int value = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n", + __func__, comp + 1, aqt->comp_enabled[comp], value); + aqt->comp_enabled[comp] = value; + + /* Any specific register configuration for compander */ + switch (comp) { + case COMPANDER_1: + /* Set Gain Source Select based on compander enable/disable */ + snd_soc_update_bits(codec, AQT1000_HPH_L_EN, 0x20, + (value ? 0x00:0x20)); + break; + case COMPANDER_2: + snd_soc_update_bits(codec, AQT1000_HPH_R_EN, 0x20, + (value ? 0x00:0x20)); + break; + default: + /* + * if compander is not enabled for any interpolator, + * it does not cause any audio failure, so do not + * return error in this case, but just print a log + */ + dev_warn(codec->dev, "%s: unknown compander: %d\n", + __func__, comp); + }; + return 0; +} + +static int aqt_hph_asrc_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int index = -EINVAL; + + if (!strcmp(kcontrol->id.name, "AQT ASRC0 Output Mode")) + index = ASRC0; + if (!strcmp(kcontrol->id.name, "AQT ASRC1 Output Mode")) + index = ASRC1; + + if (aqt && (index >= 0) && (index < ASRC_MAX)) + aqt->asrc_output_mode[index] = + ucontrol->value.integer.value[0]; + + return 0; +} + +static int aqt_hph_asrc_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int val = 0; + int index = -EINVAL; + + if (!strcmp(kcontrol->id.name, "AQT ASRC0 Output Mode")) + index = ASRC0; + if (!strcmp(kcontrol->id.name, "AQT ASRC1 Output Mode")) + index = ASRC1; + + if (aqt && (index >= 0) && (index < ASRC_MAX)) + val = aqt->asrc_output_mode[index]; + + ucontrol->value.integer.value[0] = val; + + return 0; +} + +static const char * const asrc_mode_text[] = { + "INT", "FRAC" +}; +static SOC_ENUM_SINGLE_EXT_DECL(asrc_mode_enum, asrc_mode_text); + +static int aqt_hph_idle_detect_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int val = 0; + + if (aqt) + val = aqt->idle_det_cfg.hph_idle_detect_en; + + ucontrol->value.integer.value[0] = val; + + return 0; +} + +static int aqt_hph_idle_detect_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + if (aqt) + aqt->idle_det_cfg.hph_idle_detect_en = + ucontrol->value.integer.value[0]; + + return 0; +} + +static const char * const hph_idle_detect_text[] = { + "OFF", "ON" +}; + +static SOC_ENUM_SINGLE_EXT_DECL(hph_idle_detect_enum, hph_idle_detect_text); + +static int aqt_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u16 amic_reg = 0; + + if (!strcmp(kcontrol->id.name, "AQT AMIC_1_2 PWR MODE")) + amic_reg = AQT1000_ANA_AMIC1; + if (!strcmp(kcontrol->id.name, "AQT AMIC_3 PWR MODE")) + amic_reg = AQT1000_ANA_AMIC3; + + if (amic_reg) + ucontrol->value.integer.value[0] = + (snd_soc_read(codec, amic_reg) & + AQT1000_AMIC_PWR_LVL_MASK) >> + AQT1000_AMIC_PWR_LVL_SHIFT; + return 0; +} + +static int aqt_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + u32 mode_val; + u16 amic_reg = 0; + + mode_val = ucontrol->value.enumerated.item[0]; + + dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val); + + if (!strcmp(kcontrol->id.name, "AQT AMIC_1_2 PWR MODE")) + amic_reg = AQT1000_ANA_AMIC1; + if (!strcmp(kcontrol->id.name, "AQT AMIC_3 PWR MODE")) + amic_reg = AQT1000_ANA_AMIC3; + + if (amic_reg) + snd_soc_update_bits(codec, amic_reg, AQT1000_AMIC_PWR_LVL_MASK, + mode_val << AQT1000_AMIC_PWR_LVL_SHIFT); + return 0; +} + +static const char * const amic_pwr_lvl_text[] = { + "LOW_PWR", "DEFAULT", "HIGH_PERF", "HYBRID" +}; + +static SOC_ENUM_SINGLE_EXT_DECL(amic_pwr_lvl_enum, amic_pwr_lvl_text); + +static const struct snd_kcontrol_new aqt_snd_controls[] = { + SOC_SINGLE_TLV("AQT HPHL Volume", AQT1000_HPH_L_EN, 0, 24, 1, hph_gain), + SOC_SINGLE_TLV("AQT HPHR Volume", AQT1000_HPH_R_EN, 0, 24, 1, hph_gain), + SOC_SINGLE_TLV("AQT ADC1 Volume", AQT1000_ANA_AMIC1, 0, 20, 0, + analog_gain), + SOC_SINGLE_TLV("AQT ADC2 Volume", AQT1000_ANA_AMIC2, 0, 20, 0, + analog_gain), + SOC_SINGLE_TLV("AQT ADC3 Volume", AQT1000_ANA_AMIC3, 0, 20, 0, + analog_gain), + + SOC_SINGLE_SX_TLV("AQT RX1 Digital Volume", AQT1000_CDC_RX1_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("AQT RX2 Digital Volume", AQT1000_CDC_RX2_RX_VOL_CTL, + 0, -84, 40, digital_gain), + + SOC_SINGLE_SX_TLV("AQT DEC0 Volume", AQT1000_CDC_TX0_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("AQT DEC1 Volume", AQT1000_CDC_TX1_TX_VOL_CTL, 0, + -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("AQT DEC2 Volume", AQT1000_CDC_TX2_TX_VOL_CTL, 0, + -84, 40, digital_gain), + + SOC_SINGLE_SX_TLV("AQT IIR0 INP0 Volume", + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("AQT IIR0 INP1 Volume", + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("AQT IIR0 INP2 Volume", + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("AQT IIR0 INP3 Volume", + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_EXT("AQT ANC Slot", SND_SOC_NOPM, 0, 100, 0, + aqt_get_anc_slot, aqt_put_anc_slot), + SOC_ENUM_EXT("AQT ANC Function", aqt_anc_func_enum, aqt_get_anc_func, + aqt_put_anc_func), + + SOC_ENUM("AQT TX0 HPF cut off", cf_dec0_enum), + SOC_ENUM("AQT TX1 HPF cut off", cf_dec1_enum), + SOC_ENUM("AQT TX2 HPF cut off", cf_dec2_enum), + + SOC_ENUM("AQT RX INT1_1 HPF cut off", cf_int1_1_enum), + SOC_ENUM("AQT RX INT1_2 HPF cut off", cf_int1_2_enum), + SOC_ENUM("AQT RX INT2_1 HPF cut off", cf_int2_1_enum), + SOC_ENUM("AQT RX INT2_2 HPF cut off", cf_int2_2_enum), + + SOC_ENUM_EXT("AQT RX HPH Mode", rx_hph_mode_mux_enum, + aqt_rx_hph_mode_get, aqt_rx_hph_mode_put), + + SOC_SINGLE_EXT("AQT IIR0 Enable Band1", IIR0, BAND1, 1, 0, + aqt_iir_enable_audio_mixer_get, + aqt_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("AQT IIR0 Enable Band2", IIR0, BAND2, 1, 0, + aqt_iir_enable_audio_mixer_get, + aqt_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("AQT IIR0 Enable Band3", IIR0, BAND3, 1, 0, + aqt_iir_enable_audio_mixer_get, + aqt_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("AQT IIR0 Enable Band4", IIR0, BAND4, 1, 0, + aqt_iir_enable_audio_mixer_get, + aqt_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("AQT IIR0 Enable Band5", IIR0, BAND5, 1, 0, + aqt_iir_enable_audio_mixer_get, + aqt_iir_enable_audio_mixer_put), + + SOC_SINGLE_MULTI_EXT("AQT IIR0 Band1", IIR0, BAND1, 255, 0, 5, + aqt_iir_band_audio_mixer_get, aqt_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("AQT IIR0 Band2", IIR0, BAND2, 255, 0, 5, + aqt_iir_band_audio_mixer_get, aqt_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("AQT IIR0 Band3", IIR0, BAND3, 255, 0, 5, + aqt_iir_band_audio_mixer_get, aqt_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("AQT IIR0 Band4", IIR0, BAND4, 255, 0, 5, + aqt_iir_band_audio_mixer_get, aqt_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("AQT IIR0 Band5", IIR0, BAND5, 255, 0, 5, + aqt_iir_band_audio_mixer_get, aqt_iir_band_audio_mixer_put), + + SOC_SINGLE_EXT("AQT COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0, + aqt_compander_get, aqt_compander_put), + SOC_SINGLE_EXT("AQT COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0, + aqt_compander_get, aqt_compander_put), + + SOC_ENUM_EXT("AQT ASRC0 Output Mode", asrc_mode_enum, + aqt_hph_asrc_mode_get, aqt_hph_asrc_mode_put), + SOC_ENUM_EXT("AQT ASRC1 Output Mode", asrc_mode_enum, + aqt_hph_asrc_mode_get, aqt_hph_asrc_mode_put), + + SOC_ENUM_EXT("AQT HPH Idle Detect", hph_idle_detect_enum, + aqt_hph_idle_detect_get, aqt_hph_idle_detect_put), + + SOC_ENUM_EXT("AQT AMIC_1_2 PWR MODE", amic_pwr_lvl_enum, + aqt_amic_pwr_lvl_get, aqt_amic_pwr_lvl_put), + SOC_ENUM_EXT("AQT AMIC_3 PWR MODE", amic_pwr_lvl_enum, + aqt_amic_pwr_lvl_get, aqt_amic_pwr_lvl_put), +}; + +static int aqt_codec_enable_rx_bias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + aqt->rx_bias_count++; + if (aqt->rx_bias_count == 1) { + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + 0x01, 0x01); + } + break; + case SND_SOC_DAPM_POST_PMD: + aqt->rx_bias_count--; + if (!aqt->rx_bias_count) + snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + 0x01, 0x00); + break; + }; + dev_dbg(codec->dev, "%s: Current RX BIAS user count: %d\n", __func__, + aqt->rx_bias_count); + + return 0; +} + +/* + * aqt_micbias_control: enable/disable micbias + * @codec: handle to snd_soc_codec * + * @micb_num: micbias to be enabled/disabled, e.g. micbias1 or micbias2 + * @req: control requested, enable/disable or pullup enable/disable + * @is_dapm: triggered by dapm or not + * + * return 0 if control is success or error code in case of failure + */ +int aqt_micbias_control(struct snd_soc_codec *codec, + int micb_num, int req, bool is_dapm) +{ + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + u16 micb_reg; + int pre_off_event = 0, post_off_event = 0; + int post_on_event = 0, post_dapm_off = 0; + int post_dapm_on = 0; + int ret = 0; + + switch (micb_num) { + case MIC_BIAS_1: + micb_reg = AQT1000_ANA_MICB1; + pre_off_event = AQT_EVENT_PRE_MICBIAS_1_OFF; + post_off_event = AQT_EVENT_POST_MICBIAS_1_OFF; + post_on_event = AQT_EVENT_POST_MICBIAS_1_ON; + post_dapm_on = AQT_EVENT_POST_DAPM_MICBIAS_1_ON; + post_dapm_off = AQT_EVENT_POST_DAPM_MICBIAS_1_OFF; + break; + default: + dev_err(codec->dev, "%s: Invalid micbias number: %d\n", + __func__, micb_num); + return -EINVAL; + } + mutex_lock(&aqt->micb_lock); + + switch (req) { + case MICB_PULLUP_ENABLE: + aqt->pullup_ref++; + if ((aqt->pullup_ref == 1) && + (aqt->micb_ref == 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + break; + case MICB_PULLUP_DISABLE: + if (aqt->pullup_ref > 0) + aqt->pullup_ref--; + if ((aqt->pullup_ref == 0) && + (aqt->micb_ref == 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + break; + case MICB_ENABLE: + aqt->micb_ref++; + if (aqt->micb_ref == 1) { + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + } + break; + case MICB_DISABLE: + if (aqt->micb_ref > 0) + aqt->micb_ref--; + if ((aqt->micb_ref == 0) && + (aqt->pullup_ref > 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + else if ((aqt->micb_ref == 0) && + (aqt->pullup_ref == 0)) { + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + } + break; + default: + dev_err(codec->dev, "%s: Invalid micbias request: %d\n", + __func__, req); + ret = -EINVAL; + break; + }; + + if (!ret) + dev_dbg(codec->dev, + "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", + __func__, micb_num, aqt->micb_ref, aqt->pullup_ref); + + mutex_unlock(&aqt->micb_lock); + + return ret; +} +EXPORT_SYMBOL(aqt_micbias_control); + +static int __aqt_codec_enable_micbias(struct snd_soc_dapm_widget *w, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int micb_num; + + dev_dbg(codec->dev, "%s: wname: %s, event: %d\n", + __func__, w->name, event); + + if (strnstr(w->name, "AQT MIC BIAS1", sizeof("AQT MIC BIAS1"))) + micb_num = MIC_BIAS_1; + else + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* + * MIC BIAS can also be requested by MBHC, + * so use ref count to handle micbias pullup + * and enable requests + */ + aqt_micbias_control(codec, micb_num, MICB_ENABLE, true); + break; + case SND_SOC_DAPM_POST_PMU: + /* wait for cnp time */ + usleep_range(1000, 1100); + break; + case SND_SOC_DAPM_POST_PMD: + aqt_micbias_control(codec, micb_num, MICB_DISABLE, true); + break; + }; + + return 0; +} + +static int aqt_codec_enable_micbias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + return __aqt_codec_enable_micbias(w, event); +} + +static int aqt_codec_enable_i2s_block(struct snd_soc_codec *codec) +{ + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&aqt->i2s_lock); + if (++aqt->i2s_users == 1) + snd_soc_update_bits(codec, AQT1000_I2S_I2S_0_CTL, 0x01, 0x01); + mutex_unlock(&aqt->i2s_lock); + + return 0; +} + +static int aqt_codec_disable_i2s_block(struct snd_soc_codec *codec) +{ + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&aqt->i2s_lock); + if (--aqt->i2s_users == 0) + snd_soc_update_bits(codec, AQT1000_I2S_I2S_0_CTL, 0x01, 0x00); + + if (aqt->i2s_users < 0) + dev_warn(codec->dev, "%s: i2s_users count (%d) < 0\n", + __func__, aqt->i2s_users); + mutex_unlock(&aqt->i2s_lock); + + return 0; +} + +static int aqt_codec_enable_i2s_tx(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + aqt_codec_enable_i2s_block(codec); + break; + case SND_SOC_DAPM_POST_PMD: + aqt_codec_disable_i2s_block(codec); + break; + } + dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); + + return 0; +} + +static int aqt_codec_enable_i2s_rx(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + aqt_codec_enable_i2s_block(codec); + break; + case SND_SOC_DAPM_POST_PMD: + aqt_codec_disable_i2s_block(codec); + break; + } + dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); + + return 0; +} + +static const char * const tx_mux_text[] = { + "ZERO", "DEC_L", "DEC_R", "DEC_V", +}; +AQT_DAPM_ENUM(tx0, AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0, 0, tx_mux_text); +AQT_DAPM_ENUM(tx1, AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0, 2, tx_mux_text); + +static const char * const tx_adc_mux_text[] = { + "AMIC", "ANC_FB0", "ANC_FB1", +}; +AQT_DAPM_ENUM(tx_adc0, AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0, + tx_adc_mux_text); +AQT_DAPM_ENUM(tx_adc1, AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0, + tx_adc_mux_text); +AQT_DAPM_ENUM(tx_adc2, AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0, + tx_adc_mux_text); + +static int aqt_find_amic_input(struct snd_soc_codec *codec, int adc_mux_n) +{ + u8 mask; + u16 adc_mux_in_reg = 0, amic_mux_sel_reg = 0; + bool is_amic; + + if (adc_mux_n > 2) + return 0; + + if (adc_mux_n < 3) { + adc_mux_in_reg = AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + + adc_mux_n; + mask = 0x03; + amic_mux_sel_reg = AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + + 2 * adc_mux_n; + } + is_amic = (((snd_soc_read(codec, adc_mux_in_reg) & mask)) == 0); + if (!is_amic) + return 0; + + return snd_soc_read(codec, amic_mux_sel_reg) & 0x07; +} + +static u16 aqt_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic) +{ + u16 pwr_level_reg = 0; + + switch (amic) { + case 1: + case 2: + pwr_level_reg = AQT1000_ANA_AMIC1; + break; + case 3: + pwr_level_reg = AQT1000_ANA_AMIC3; + break; + default: + dev_dbg(codec->dev, "%s: invalid amic: %d\n", + __func__, amic); + break; + } + + return pwr_level_reg; +} + +static void aqt_tx_hpf_corner_freq_callback(struct work_struct *work) +{ + struct delayed_work *hpf_delayed_work; + struct hpf_work *hpf_work; + struct aqt1000 *aqt; + struct snd_soc_codec *codec; + u16 dec_cfg_reg, amic_reg, go_bit_reg; + u8 hpf_cut_off_freq; + int amic_n; + + hpf_delayed_work = to_delayed_work(work); + hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); + aqt = hpf_work->aqt; + codec = aqt->codec; + hpf_cut_off_freq = hpf_work->hpf_cut_off_freq; + + dec_cfg_reg = AQT1000_CDC_TX0_TX_PATH_CFG0 + 16 * hpf_work->decimator; + go_bit_reg = dec_cfg_reg + 7; + + dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", + __func__, hpf_work->decimator, hpf_cut_off_freq); + + amic_n = aqt_find_amic_input(codec, hpf_work->decimator); + if (amic_n) { + amic_reg = AQT1000_ANA_AMIC1 + amic_n - 1; + aqt_codec_set_tx_hold(codec, amic_reg, false); + } + snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x02); + /* Minimum 1 clk cycle delay is required as per HW spec */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x00); +} + +static void aqt_tx_mute_update_callback(struct work_struct *work) +{ + struct tx_mute_work *tx_mute_dwork; + struct aqt1000 *aqt; + struct delayed_work *delayed_work; + struct snd_soc_codec *codec; + u16 tx_vol_ctl_reg, hpf_gate_reg; + + delayed_work = to_delayed_work(work); + tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); + aqt = tx_mute_dwork->aqt; + codec = aqt->codec; + + tx_vol_ctl_reg = AQT1000_CDC_TX0_TX_PATH_CTL + + 16 * tx_mute_dwork->decimator; + hpf_gate_reg = AQT1000_CDC_TX0_TX_PATH_SEC2 + + 16 * tx_mute_dwork->decimator; + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); +} + +static int aqt_codec_enable_dec(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + char *widget_name = NULL; + char *dec = NULL; + unsigned int decimator = 0; + u8 amic_n = 0; + u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg; + u16 tx_gain_ctl_reg; + int ret = 0; + u8 hpf_cut_off_freq; + + dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); + widget_name = kstrndup(w->name, 15, GFP_KERNEL); + if (!widget_name) + return -ENOMEM; + + dec = strpbrk(widget_name, "012"); + if (!dec) { + dev_err(codec->dev, "%s: decimator index not found\n", + __func__); + ret = -EINVAL; + goto out; + } + + ret = kstrtouint(dec, 10, &decimator); + if (ret < 0) { + dev_err(codec->dev, "%s: Invalid decimator = %s\n", + __func__, widget_name); + ret = -EINVAL; + goto out; + } + dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__, + w->name, decimator); + + tx_vol_ctl_reg = AQT1000_CDC_TX0_TX_PATH_CTL + 16 * decimator; + hpf_gate_reg = AQT1000_CDC_TX0_TX_PATH_SEC2 + 16 * decimator; + dec_cfg_reg = AQT1000_CDC_TX0_TX_PATH_CFG0 + 16 * decimator; + tx_gain_ctl_reg = AQT1000_CDC_TX0_TX_VOL_CTL + 16 * decimator; + + amic_n = aqt_find_amic_input(codec, decimator); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (amic_n) + pwr_level_reg = aqt_codec_get_amic_pwlvl_reg(codec, + amic_n); + if (pwr_level_reg) { + switch ((snd_soc_read(codec, pwr_level_reg) & + AQT1000_AMIC_PWR_LVL_MASK) >> + AQT1000_AMIC_PWR_LVL_SHIFT) { + case AQT1000_AMIC_PWR_LEVEL_LP: + snd_soc_update_bits(codec, dec_cfg_reg, + AQT1000_DEC_PWR_LVL_MASK, + AQT1000_DEC_PWR_LVL_LP); + break; + + case AQT1000_AMIC_PWR_LEVEL_HP: + snd_soc_update_bits(codec, dec_cfg_reg, + AQT1000_DEC_PWR_LVL_MASK, + AQT1000_DEC_PWR_LVL_HP); + break; + case AQT1000_AMIC_PWR_LEVEL_DEFAULT: + default: + snd_soc_update_bits(codec, dec_cfg_reg, + AQT1000_DEC_PWR_LVL_MASK, + AQT1000_DEC_PWR_LVL_DF); + break; + } + } + /* Enable TX PGA Mute */ + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMU: + hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) & + TX_HPF_CUT_OFF_FREQ_MASK) >> 5; + + aqt->tx_hpf_work[decimator].hpf_cut_off_freq = + hpf_cut_off_freq; + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { + snd_soc_update_bits(codec, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + CF_MIN_3DB_150HZ << 5); + snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); + /* + * Minimum 1 clk cycle delay is required as per + * HW spec. + */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00); + } + /* schedule work queue to Remove Mute */ + schedule_delayed_work(&aqt->tx_mute_dwork[decimator].dwork, + msecs_to_jiffies(tx_unmute_delay)); + if (aqt->tx_hpf_work[decimator].hpf_cut_off_freq != + CF_MIN_3DB_150HZ) + schedule_delayed_work( + &aqt->tx_hpf_work[decimator].dwork, + msecs_to_jiffies(300)); + /* apply gain after decimator is enabled */ + snd_soc_write(codec, tx_gain_ctl_reg, + snd_soc_read(codec, tx_gain_ctl_reg)); + break; + case SND_SOC_DAPM_PRE_PMD: + hpf_cut_off_freq = + aqt->tx_hpf_work[decimator].hpf_cut_off_freq; + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + if (cancel_delayed_work_sync( + &aqt->tx_hpf_work[decimator].dwork)) { + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { + snd_soc_update_bits(codec, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_update_bits(codec, hpf_gate_reg, + 0x02, 0x02); + /* + * Minimum 1 clk cycle delay is required as per + * HW spec. + */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, hpf_gate_reg, + 0x02, 0x00); + } + } + cancel_delayed_work_sync( + &aqt->tx_mute_dwork[decimator].dwork); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); + snd_soc_update_bits(codec, dec_cfg_reg, + AQT1000_DEC_PWR_LVL_MASK, + AQT1000_DEC_PWR_LVL_DF); + break; + } + +out: + kfree(widget_name); + return ret; +} + +static const char * const tx_amic_text[] = { + "ZERO", "ADC_L", "ADC_R", "ADC_V", +}; +AQT_DAPM_ENUM(tx_amic0, AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0, tx_amic_text); +AQT_DAPM_ENUM(tx_amic1, AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0, tx_amic_text); +AQT_DAPM_ENUM(tx_amic2, AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0, tx_amic_text); + +AQT_DAPM_ENUM(tx_amic10, AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0, + tx_amic_text); +AQT_DAPM_ENUM(tx_amic11, AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0, + tx_amic_text); +AQT_DAPM_ENUM(tx_amic12, AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 0, + tx_amic_text); +AQT_DAPM_ENUM(tx_amic13, AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 0, + tx_amic_text); + +static int aqt_codec_enable_adc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + aqt_codec_set_tx_hold(codec, w->reg, true); + break; + default: + break; + } + + return 0; +} + +static const struct snd_kcontrol_new anc_hphl_pa_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct snd_kcontrol_new anc_hphr_pa_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static int aqt_config_compander(struct snd_soc_codec *codec, int interp_n, + int event) +{ + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int comp; + u16 comp_ctl0_reg, rx_path_cfg0_reg; + + comp = interp_n; + dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n", + __func__, event, comp, aqt->comp_enabled[comp]); + + if (!aqt->comp_enabled[comp]) + return 0; + + comp_ctl0_reg = AQT1000_CDC_COMPANDER1_CTL0 + (comp * 8); + rx_path_cfg0_reg = AQT1000_CDC_RX1_RX_PATH_CFG0 + (comp * 20); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Compander Clock */ + snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); + } + + return 0; +} + +static void aqt_codec_idle_detect_control(struct snd_soc_codec *codec, + int interp, int event) +{ + int reg = 0, mask, val; + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + if (!aqt->idle_det_cfg.hph_idle_detect_en) + return; + + if (interp == INTERP_HPHL) { + reg = AQT1000_CDC_RX_IDLE_DET_PATH_CTL; + mask = 0x01; + val = 0x01; + } + if (interp == INTERP_HPHR) { + reg = AQT1000_CDC_RX_IDLE_DET_PATH_CTL; + mask = 0x02; + val = 0x02; + } + + if (reg && SND_SOC_DAPM_EVENT_ON(event)) + snd_soc_update_bits(codec, reg, mask, val); + + if (reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, reg, mask, 0x00); + aqt->idle_det_cfg.hph_idle_thr = 0; + snd_soc_write(codec, AQT1000_CDC_RX_IDLE_DET_CFG3, 0x0); + } +} + +static void aqt_codec_hphdelay_lutbypass(struct snd_soc_codec *codec, + u16 interp_idx, int event) +{ + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + u8 hph_dly_mask; + u16 hph_lut_bypass_reg = 0; + u16 hph_comp_ctrl7 = 0; + + + switch (interp_idx) { + case INTERP_HPHL: + hph_dly_mask = 1; + hph_lut_bypass_reg = AQT1000_CDC_TOP_HPHL_COMP_LUT; + hph_comp_ctrl7 = AQT1000_CDC_COMPANDER1_CTL7; + break; + case INTERP_HPHR: + hph_dly_mask = 2; + hph_lut_bypass_reg = AQT1000_CDC_TOP_HPHR_COMP_LUT; + hph_comp_ctrl7 = AQT1000_CDC_COMPANDER2_CTL7; + break; + default: + break; + } + + if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) { + snd_soc_update_bits(codec, AQT1000_CDC_CLSH_TEST0, + hph_dly_mask, 0x0); + snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x80); + if (aqt->hph_mode == CLS_H_ULP) + snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x20); + } + + if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, AQT1000_CDC_CLSH_TEST0, + hph_dly_mask, hph_dly_mask); + snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x00); + snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x0); + } +} + +static int aqt_codec_enable_interp_clk(struct snd_soc_codec *codec, + int event, int interp_idx) +{ + struct aqt1000 *aqt; + u16 main_reg, dsm_reg; + + if (!codec) { + pr_err("%s: codec is NULL\n", __func__); + return -EINVAL; + } + + aqt = snd_soc_codec_get_drvdata(codec); + main_reg = AQT1000_CDC_RX1_RX_PATH_CTL + (interp_idx * 20); + dsm_reg = AQT1000_CDC_RX1_RX_PATH_DSMDEM_CTL + (interp_idx * 20); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + if (aqt->main_clk_users[interp_idx] == 0) { + /* Main path PGA mute enable */ + snd_soc_update_bits(codec, main_reg, 0x10, 0x10); + /* Clk enable */ + snd_soc_update_bits(codec, dsm_reg, 0x01, 0x01); + snd_soc_update_bits(codec, main_reg, 0x20, 0x20); + aqt_codec_idle_detect_control(codec, interp_idx, + event); + aqt_codec_hphdelay_lutbypass(codec, interp_idx, + event); + aqt_config_compander(codec, interp_idx, event); + } + aqt->main_clk_users[interp_idx]++; + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + aqt->main_clk_users[interp_idx]--; + if (aqt->main_clk_users[interp_idx] <= 0) { + aqt->main_clk_users[interp_idx] = 0; + aqt_config_compander(codec, interp_idx, event); + aqt_codec_hphdelay_lutbypass(codec, interp_idx, + event); + aqt_codec_idle_detect_control(codec, interp_idx, + event); + /* Clk Disable */ + snd_soc_update_bits(codec, main_reg, 0x20, 0x00); + snd_soc_update_bits(codec, dsm_reg, 0x01, 0x00); + /* Reset enable and disable */ + snd_soc_update_bits(codec, main_reg, 0x40, 0x40); + snd_soc_update_bits(codec, main_reg, 0x40, 0x00); + /* Reset rate to 48K*/ + snd_soc_update_bits(codec, main_reg, 0x0F, 0x04); + } + } + + dev_dbg(codec->dev, "%s event %d main_clk_users %d\n", + __func__, event, aqt->main_clk_users[interp_idx]); + + return aqt->main_clk_users[interp_idx]; +} + +static int aqt_anc_out_switch_cb(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + aqt_codec_enable_interp_clk(codec, event, w->shift); + + return 0; +} + +static const char * const anc0_fb_mux_text[] = { + "ZERO", "ANC_IN_HPHL", +}; + +static const char * const anc1_fb_mux_text[] = { + "ZERO", "ANC_IN_HPHR", +}; + +AQT_DAPM_ENUM(anc0_fb, AQT1000_CDC_RX_INP_MUX_ANC_CFG0, 0, anc0_fb_mux_text); +AQT_DAPM_ENUM(anc1_fb, AQT1000_CDC_RX_INP_MUX_ANC_CFG0, 3, anc1_fb_mux_text); + +static const char *const rx_int1_1_mux_text[] = { + "ZERO", "MAIN_DMA_L", "I2S0_L", "I2S0_R", "DEC_L", "DEC_R", "DEC_V", + "SHADOW_I2S0_L", "MAIN_DMA_R" +}; + +static const char *const rx_int1_2_mux_text[] = { + "ZERO", "MIX_DMA_L", "I2S0_L", "I2S0_R", "DEC_L", "DEC_R", "DEC_V", + "IIR0", "MIX_DMA_R" +}; + +static const char *const rx_int2_1_mux_text[] = { + "ZERO", "MAIN_DMA_R", "I2S0_L", "I2S0_R", "DEC_L", "DEC_R", "DEC_V", + "SHADOW_I2S0_R", "MAIN_DMA_L" +}; + +static const char *const rx_int2_2_mux_text[] = { + "ZERO", "MIX_DMA_R", "I2S0_L", "I2S0_R", "DEC_L", "DEC_R", "DEC_V", + "IIR0", "MIX_DMA_L" +}; + +AQT_DAPM_ENUM(rx_int1_1, AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG0, 0, + rx_int1_1_mux_text); +AQT_DAPM_ENUM(rx_int1_2, AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, + rx_int1_2_mux_text); +AQT_DAPM_ENUM(rx_int2_1, AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, + rx_int2_1_mux_text); +AQT_DAPM_ENUM(rx_int2_2, AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, + rx_int2_2_mux_text); + +static int aqt_codec_set_idle_detect_thr(struct snd_soc_codec *codec, + int interp, int path_type) +{ + int port_id[4] = { 0, 0, 0, 0 }; + int *port_ptr, num_ports; + int bit_width = 0; + int mux_reg = 0, mux_reg_val = 0; + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int idle_thr; + + if ((interp != INTERP_HPHL) && (interp != INTERP_HPHR)) + return 0; + + if (!aqt->idle_det_cfg.hph_idle_detect_en) + return 0; + + port_ptr = &port_id[0]; + num_ports = 0; + + if (path_type == INTERP_MIX_PATH) { + if (interp == INTERP_HPHL) + mux_reg = AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG1; + else + mux_reg = AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG1; + } + + if (path_type == INTERP_MAIN_PATH) { + if (interp == INTERP_HPHL) + mux_reg = AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG0; + else + mux_reg = AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0; + } + mux_reg_val = snd_soc_read(codec, mux_reg); + + /* Read bit width from I2S reg if mux is set to I2S0_L or I2S0_R */ + if (mux_reg_val == 0x02 || mux_reg_val == 0x03) + bit_width = ((snd_soc_read(codec, AQT1000_I2S_I2S_0_CTL) & + 0x40) >> 6); + + switch (bit_width) { + case 1: /* 16 bit */ + idle_thr = 0xff; /* F16 */ + break; + case 0: /* 32 bit */ + default: + idle_thr = 0x03; /* F22 */ + break; + } + + dev_dbg(codec->dev, "%s: (new) idle_thr: %d, (cur) idle_thr: %d\n", + __func__, idle_thr, aqt->idle_det_cfg.hph_idle_thr); + + if ((aqt->idle_det_cfg.hph_idle_thr == 0) || + (idle_thr < aqt->idle_det_cfg.hph_idle_thr)) { + snd_soc_write(codec, AQT1000_CDC_RX_IDLE_DET_CFG3, idle_thr); + aqt->idle_det_cfg.hph_idle_thr = idle_thr; + } + + return 0; +} + +static int aqt_codec_enable_main_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 gain_reg = 0; + int val = 0; + + dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + + if (w->shift >= AQT1000_NUM_INTERPOLATORS) { + dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", + __func__, w->shift, w->name); + return -EINVAL; + }; + + gain_reg = AQT1000_CDC_RX1_RX_VOL_CTL + (w->shift * + AQT1000_RX_PATH_CTL_OFFSET); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + aqt_codec_enable_interp_clk(codec, event, w->shift); + break; + case SND_SOC_DAPM_POST_PMU: + aqt_codec_set_idle_detect_thr(codec, w->shift, + INTERP_MAIN_PATH); + /* apply gain after int clk is enabled */ + val = snd_soc_read(codec, gain_reg); + snd_soc_write(codec, gain_reg, val); + break; + case SND_SOC_DAPM_POST_PMD: + aqt_codec_enable_interp_clk(codec, event, w->shift); + break; + }; + + return 0; +} + +static int aqt_codec_enable_mix_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 gain_reg = 0; + u16 mix_reg = 0; + + if (w->shift >= AQT1000_NUM_INTERPOLATORS) { + dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", + __func__, w->shift, w->name); + return -EINVAL; + }; + gain_reg = AQT1000_CDC_RX1_RX_VOL_MIX_CTL + + (w->shift * AQT1000_RX_PATH_CTL_OFFSET); + mix_reg = AQT1000_CDC_RX1_RX_PATH_MIX_CTL + + (w->shift * AQT1000_RX_PATH_CTL_OFFSET); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + aqt_codec_enable_interp_clk(codec, event, w->shift); + /* Clk enable */ + snd_soc_update_bits(codec, mix_reg, 0x20, 0x20); + break; + case SND_SOC_DAPM_POST_PMU: + aqt_codec_set_idle_detect_thr(codec, w->shift, + INTERP_MIX_PATH); + break; + case SND_SOC_DAPM_POST_PMD: + /* Clk Disable */ + snd_soc_update_bits(codec, mix_reg, 0x20, 0x00); + aqt_codec_enable_interp_clk(codec, event, w->shift); + /* Reset enable and disable */ + snd_soc_update_bits(codec, mix_reg, 0x40, 0x40); + snd_soc_update_bits(codec, mix_reg, 0x40, 0x00); + + break; + }; + dev_dbg(codec->dev, "%s event %d name %s\n", __func__, event, w->name); + + return 0; +} + +static const char * const rx_int1_1_interp_mux_text[] = { + "ZERO", "RX INT1_1 MUX", +}; + +static const char * const rx_int2_1_interp_mux_text[] = { + "ZERO", "RX INT2_1 MUX", +}; + +static const char * const rx_int1_2_interp_mux_text[] = { + "ZERO", "RX INT1_2 MUX", +}; + +static const char * const rx_int2_2_interp_mux_text[] = { + "ZERO", "RX INT2_2 MUX", +}; + +AQT_DAPM_ENUM(rx_int1_1_interp, SND_SOC_NOPM, 0, rx_int1_1_interp_mux_text); +AQT_DAPM_ENUM(rx_int2_1_interp, SND_SOC_NOPM, 0, rx_int2_1_interp_mux_text); + +AQT_DAPM_ENUM(rx_int1_2_interp, SND_SOC_NOPM, 0, rx_int1_2_interp_mux_text); +AQT_DAPM_ENUM(rx_int2_2_interp, SND_SOC_NOPM, 0, rx_int2_2_interp_mux_text); + +static const char * const asrc0_mux_text[] = { + "ZERO", "ASRC_IN_HPHL", +}; + +static const char * const asrc1_mux_text[] = { + "ZERO", "ASRC_IN_HPHR", +}; + +AQT_DAPM_ENUM(asrc0, AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 0, + asrc0_mux_text); +AQT_DAPM_ENUM(asrc1, AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 2, + asrc1_mux_text); + +static int aqt_get_asrc_mode(struct aqt1000 *aqt, int asrc, + u8 main_sr, u8 mix_sr) +{ + u8 asrc_output_mode; + int asrc_mode = CONV_88P2K_TO_384K; + + if ((asrc < 0) || (asrc >= ASRC_MAX)) + return 0; + + asrc_output_mode = aqt->asrc_output_mode[asrc]; + + if (asrc_output_mode) { + /* + * If Mix sample rate is < 96KHz, use 96K to 352.8K + * conversion, or else use 384K to 352.8K conversion + */ + if (mix_sr < 5) + asrc_mode = CONV_96K_TO_352P8K; + else + asrc_mode = CONV_384K_TO_352P8K; + } else { + /* Integer main and Fractional mix path */ + if (main_sr < 8 && mix_sr > 9) { + asrc_mode = CONV_352P8K_TO_384K; + } else if (main_sr > 8 && mix_sr < 8) { + /* Fractional main and Integer mix path */ + if (mix_sr < 5) + asrc_mode = CONV_96K_TO_352P8K; + else + asrc_mode = CONV_384K_TO_352P8K; + } else if (main_sr < 8 && mix_sr < 8) { + /* Integer main and Integer mix path */ + asrc_mode = CONV_96K_TO_384K; + } + } + + return asrc_mode; +} + +static int aqt_codec_enable_asrc_resampler(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int asrc = 0, ret = 0; + u8 cfg; + u16 cfg_reg = 0; + u16 ctl_reg = 0; + u16 clk_reg = 0; + u16 asrc_ctl = 0; + u16 mix_ctl_reg = 0; + u16 paired_reg = 0; + u8 main_sr, mix_sr, asrc_mode = 0; + + cfg = snd_soc_read(codec, AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0); + if (!(cfg & 0xFF)) { + dev_err(codec->dev, "%s: ASRC%u input not selected\n", + __func__, w->shift); + return -EINVAL; + } + + switch (w->shift) { + case ASRC0: + if ((cfg & 0x03) == 0x01) { + cfg_reg = AQT1000_CDC_RX1_RX_PATH_CFG0; + ctl_reg = AQT1000_CDC_RX1_RX_PATH_CTL; + clk_reg = AQT1000_MIXING_ASRC0_CLK_RST_CTL; + paired_reg = AQT1000_MIXING_ASRC1_CLK_RST_CTL; + asrc_ctl = AQT1000_MIXING_ASRC0_CTL1; + } + break; + case ASRC1: + if ((cfg & 0x0C) == 0x4) { + cfg_reg = AQT1000_CDC_RX2_RX_PATH_CFG0; + ctl_reg = AQT1000_CDC_RX2_RX_PATH_CTL; + clk_reg = AQT1000_MIXING_ASRC1_CLK_RST_CTL; + paired_reg = AQT1000_MIXING_ASRC0_CLK_RST_CTL; + asrc_ctl = AQT1000_MIXING_ASRC1_CTL1; + } + break; + default: + dev_err(codec->dev, "%s: Invalid asrc:%u\n", __func__, + w->shift); + ret = -EINVAL; + break; + }; + + if ((cfg_reg == 0) || (ctl_reg == 0) || (clk_reg == 0) || + (asrc_ctl == 0) || ret) + goto done; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if ((snd_soc_read(codec, clk_reg) & 0x02) || + (snd_soc_read(codec, paired_reg) & 0x02)) { + snd_soc_update_bits(codec, clk_reg, 0x02, 0x00); + snd_soc_update_bits(codec, paired_reg, 0x02, 0x00); + } + snd_soc_update_bits(codec, cfg_reg, 0x80, 0x80); + snd_soc_update_bits(codec, clk_reg, 0x01, 0x01); + main_sr = snd_soc_read(codec, ctl_reg) & 0x0F; + mix_ctl_reg = ctl_reg + 5; + mix_sr = snd_soc_read(codec, mix_ctl_reg) & 0x0F; + asrc_mode = aqt_get_asrc_mode(aqt, asrc, + main_sr, mix_sr); + dev_dbg(codec->dev, "%s: main_sr:%d mix_sr:%d asrc_mode %d\n", + __func__, main_sr, mix_sr, asrc_mode); + snd_soc_update_bits(codec, asrc_ctl, 0x07, asrc_mode); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, asrc_ctl, 0x07, 0x00); + snd_soc_update_bits(codec, cfg_reg, 0x80, 0x00); + snd_soc_update_bits(codec, clk_reg, 0x03, 0x02); + break; + }; + +done: + return ret; +} + +static int aqt_codec_enable_anc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + const char *filename; + const struct firmware *fw; + int i; + int ret = 0; + int num_anc_slots; + struct aqt1000_anc_header *anc_head; + struct firmware_cal *hwdep_cal = NULL; + u32 anc_writes_size = 0; + u32 anc_cal_size = 0; + int anc_size_remaining; + u32 *anc_ptr; + u16 reg; + u8 mask, val; + size_t cal_size; + const void *data; + + if (!aqt->anc_func) + return 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + hwdep_cal = wcdcal_get_fw_cal(aqt->fw_data, WCD9XXX_ANC_CAL); + if (hwdep_cal) { + data = hwdep_cal->data; + cal_size = hwdep_cal->size; + dev_dbg(codec->dev, "%s: using hwdep calibration, cal_size %zd", + __func__, cal_size); + } else { + filename = "AQT1000/AQT1000_anc.bin"; + ret = request_firmware(&fw, filename, codec->dev); + if (ret < 0) { + dev_err(codec->dev, "%s: Failed to acquire ANC data: %d\n", + __func__, ret); + return ret; + } + if (!fw) { + dev_err(codec->dev, "%s: Failed to get anc fw\n", + __func__); + return -ENODEV; + } + data = fw->data; + cal_size = fw->size; + dev_dbg(codec->dev, "%s: using request_firmware calibration\n", + __func__); + } + if (cal_size < sizeof(struct aqt1000_anc_header)) { + dev_err(codec->dev, "%s: Invalid cal_size %zd\n", + __func__, cal_size); + ret = -EINVAL; + goto err; + } + /* First number is the number of register writes */ + anc_head = (struct aqt1000_anc_header *)(data); + anc_ptr = (u32 *)(data + sizeof(struct aqt1000_anc_header)); + anc_size_remaining = cal_size - + sizeof(struct aqt1000_anc_header); + num_anc_slots = anc_head->num_anc_slots; + + if (aqt->anc_slot >= num_anc_slots) { + dev_err(codec->dev, "%s: Invalid ANC slot selected\n", + __func__); + ret = -EINVAL; + goto err; + } + for (i = 0; i < num_anc_slots; i++) { + if (anc_size_remaining < AQT1000_PACKED_REG_SIZE) { + dev_err(codec->dev, "%s: Invalid register format\n", + __func__); + ret = -EINVAL; + goto err; + } + anc_writes_size = (u32)(*anc_ptr); + anc_size_remaining -= sizeof(u32); + anc_ptr += 1; + + if ((anc_writes_size * AQT1000_PACKED_REG_SIZE) > + anc_size_remaining) { + dev_err(codec->dev, "%s: Invalid register format\n", + __func__); + ret = -EINVAL; + goto err; + } + + if (aqt->anc_slot == i) + break; + + anc_size_remaining -= (anc_writes_size * + AQT1000_PACKED_REG_SIZE); + anc_ptr += anc_writes_size; + } + if (i == num_anc_slots) { + dev_err(codec->dev, "%s: Selected ANC slot not present\n", + __func__); + ret = -EINVAL; + goto err; + } + + i = 0; + anc_cal_size = anc_writes_size; + /* Rate converter clk enable and set bypass mode */ + if (!strcmp(w->name, "AQT RX INT1 DAC")) { + snd_soc_update_bits(codec, + AQT1000_CDC_ANC0_RC_COMMON_CTL, + 0x05, 0x05); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC0_FIFO_COMMON_CTL, + 0x66, 0x66); + anc_writes_size = anc_cal_size / 2; + snd_soc_update_bits(codec, + AQT1000_CDC_ANC0_CLK_RESET_CTL, 0x39, 0x39); + } else if (!strcmp(w->name, "AQT RX INT2 DAC")) { + snd_soc_update_bits(codec, + AQT1000_CDC_ANC1_RC_COMMON_CTL, + 0x05, 0x05); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC1_FIFO_COMMON_CTL, + 0x66, 0x66); + i = anc_cal_size / 2; + snd_soc_update_bits(codec, + AQT1000_CDC_ANC1_CLK_RESET_CTL, 0x39, 0x39); + } + + for (; i < anc_writes_size; i++) { + AQT1000_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val); + snd_soc_write(codec, reg, (val & mask)); + } + if (!strcmp(w->name, "AQT RX INT1 DAC")) + snd_soc_update_bits(codec, + AQT1000_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x08); + else if (!strcmp(w->name, "AQT RX INT2 DAC")) + snd_soc_update_bits(codec, + AQT1000_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x08); + + if (!hwdep_cal) + release_firmware(fw); + break; + + case SND_SOC_DAPM_POST_PMU: + /* Remove ANC Rx from reset */ + snd_soc_update_bits(codec, + AQT1000_CDC_ANC0_CLK_RESET_CTL, + 0x08, 0x00); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC1_CLK_RESET_CTL, + 0x08, 0x00); + break; + + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, AQT1000_CDC_ANC0_RC_COMMON_CTL, + 0x05, 0x00); + if (!strcmp(w->name, "AQT ANC HPHL PA")) { + snd_soc_update_bits(codec, AQT1000_CDC_ANC0_MODE_1_CTL, + 0x30, 0x00); + /* 50 msec sleep is needed to avoid click and pop as + * per HW requirement + */ + msleep(50); + snd_soc_update_bits(codec, AQT1000_CDC_ANC0_MODE_1_CTL, + 0x01, 0x00); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC0_CLK_RESET_CTL, + 0x38, 0x38); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC0_CLK_RESET_CTL, + 0x07, 0x00); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC0_CLK_RESET_CTL, + 0x38, 0x00); + } else if (!strcmp(w->name, "AQT ANC HPHR PA")) { + snd_soc_update_bits(codec, AQT1000_CDC_ANC1_MODE_1_CTL, + 0x30, 0x00); + /* 50 msec sleep is needed to avoid click and pop as + * per HW requirement + */ + msleep(50); + snd_soc_update_bits(codec, AQT1000_CDC_ANC1_MODE_1_CTL, + 0x01, 0x00); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC1_CLK_RESET_CTL, + 0x38, 0x38); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC1_CLK_RESET_CTL, + 0x07, 0x00); + snd_soc_update_bits(codec, + AQT1000_CDC_ANC1_CLK_RESET_CTL, + 0x38, 0x00); + } + break; + } + + return 0; +err: + if (!hwdep_cal) + release_firmware(fw); + return ret; +} + +static void aqt_codec_override(struct snd_soc_codec *codec, int mode, + int event) +{ + if (mode == CLS_AB || mode == CLS_AB_HIFI) { + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, + AQT1000_ANA_RX_SUPPLIES, 0x02, 0x02); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, + AQT1000_ANA_RX_SUPPLIES, 0x02, 0x00); + break; + } + } +} + +static void aqt_codec_set_tx_hold(struct snd_soc_codec *codec, + u16 amic_reg, bool set) +{ + u8 mask = 0x20; + u8 val; + + if (amic_reg == AQT1000_ANA_AMIC1 || + amic_reg == AQT1000_ANA_AMIC3) + mask = 0x40; + + val = set ? mask : 0x00; + + switch (amic_reg) { + case AQT1000_ANA_AMIC1: + case AQT1000_ANA_AMIC2: + snd_soc_update_bits(codec, AQT1000_ANA_AMIC2, mask, val); + break; + case AQT1000_ANA_AMIC3: + snd_soc_update_bits(codec, AQT1000_ANA_AMIC3_HPF, mask, val); + break; + default: + dev_dbg(codec->dev, "%s: invalid amic: %d\n", + __func__, amic_reg); + break; + } +} + +static void aqt_codec_clear_anc_tx_hold(struct aqt1000 *aqt) +{ + if (test_and_clear_bit(ANC_MIC_AMIC1, &aqt->status_mask)) + aqt_codec_set_tx_hold(aqt->codec, AQT1000_ANA_AMIC1, false); + if (test_and_clear_bit(ANC_MIC_AMIC2, &aqt->status_mask)) + aqt_codec_set_tx_hold(aqt->codec, AQT1000_ANA_AMIC2, false); + if (test_and_clear_bit(ANC_MIC_AMIC3, &aqt->status_mask)) + aqt_codec_set_tx_hold(aqt->codec, AQT1000_ANA_AMIC3, false); +} + +static const char * const rx_int_dem_inp_mux_text[] = { + "NORMAL_DSM_OUT", "CLSH_DSM_OUT", +}; + +static int aqt_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val; + unsigned short look_ahead_dly_reg = AQT1000_CDC_RX1_RX_PATH_CFG0; + + val = ucontrol->value.enumerated.item[0]; + if (val >= e->items) + return -EINVAL; + + dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + widget->name, val); + + if (e->reg == AQT1000_CDC_RX1_RX_PATH_SEC0) + look_ahead_dly_reg = AQT1000_CDC_RX1_RX_PATH_CFG0; + else if (e->reg == AQT1000_CDC_RX2_RX_PATH_SEC0) + look_ahead_dly_reg = AQT1000_CDC_RX2_RX_PATH_CFG0; + + /* Set Look Ahead Delay */ + snd_soc_update_bits(codec, look_ahead_dly_reg, + 0x08, (val ? 0x08 : 0x00)); + /* Set DEM INP Select */ + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +AQT_DAPM_ENUM_EXT(rx_int1_dem, AQT1000_CDC_RX1_RX_PATH_SEC0, 0, + rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double, + aqt_int_dem_inp_mux_put); +AQT_DAPM_ENUM_EXT(rx_int2_dem, AQT1000_CDC_RX2_RX_PATH_SEC0, 0, + rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double, + aqt_int_dem_inp_mux_put); + +static int aqt_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int hph_mode = aqt->hph_mode; + u8 dem_inp; + int ret = 0; + + dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, + w->name, event, hph_mode); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (aqt->anc_func) { + ret = aqt_codec_enable_anc(w, kcontrol, event); + /* 40 msec delay is needed to avoid click and pop */ + msleep(40); + } + /* Read DEM INP Select */ + dem_inp = snd_soc_read(codec, AQT1000_CDC_RX1_RX_PATH_SEC0) & + 0x03; + if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || + (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { + dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", + __func__, hph_mode); + return -EINVAL; + } + /* Disable AutoChop timer during power up */ + snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x00); + + aqt_clsh_fsm(codec, &aqt->clsh_d, + AQT_CLSH_EVENT_PRE_DAC, + AQT_CLSH_STATE_HPHL, + hph_mode); + + if (aqt->anc_func) + snd_soc_update_bits(codec, + AQT1000_CDC_RX1_RX_PATH_CFG0, + 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMD: + /* 1000us required as per HW requirement */ + usleep_range(1000, 1100); + aqt_clsh_fsm(codec, &aqt->clsh_d, + AQT_CLSH_EVENT_POST_PA, + AQT_CLSH_STATE_HPHL, + hph_mode); + break; + default: + break; + }; + + return ret; +} + +static int aqt_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int hph_mode = aqt->hph_mode; + u8 dem_inp; + int ret = 0; + + dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, + w->name, event, hph_mode); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (aqt->anc_func) { + ret = aqt_codec_enable_anc(w, kcontrol, event); + /* 40 msec delay is needed to avoid click and pop */ + msleep(40); + } + /* Read DEM INP Select */ + dem_inp = snd_soc_read(codec, AQT1000_CDC_RX2_RX_PATH_SEC0) & + 0x03; + if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || + (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { + dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", + __func__, hph_mode); + return -EINVAL; + } + /* Disable AutoChop timer during power up */ + snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x00); + aqt_clsh_fsm(codec, &aqt->clsh_d, + AQT_CLSH_EVENT_PRE_DAC, + AQT_CLSH_STATE_HPHR, + hph_mode); + if (aqt->anc_func) + snd_soc_update_bits(codec, + AQT1000_CDC_RX2_RX_PATH_CFG0, + 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMD: + /* 1000us required as per HW requirement */ + usleep_range(1000, 1100); + aqt_clsh_fsm(codec, &aqt->clsh_d, + AQT_CLSH_EVENT_POST_PA, + AQT_CLSH_STATE_HPHR, + hph_mode); + break; + default: + break; + }; + + return 0; +} + +static int aqt_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if ((!(strcmp(w->name, "AQT ANC HPHR PA"))) && + (test_bit(HPH_PA_DELAY, &aqt->status_mask))) + snd_soc_update_bits(codec, AQT1000_ANA_HPH, 0xC0, 0xC0); + + set_bit(HPH_PA_DELAY, &aqt->status_mask); + break; + case SND_SOC_DAPM_POST_PMU: + if ((!(strcmp(w->name, "AQT ANC HPHR PA")))) { + if ((snd_soc_read(codec, AQT1000_ANA_HPH) & 0xC0) + != 0xC0) + /* + * If PA_EN is not set (potentially in ANC case) + * then do nothing for POST_PMU and let left + * channel handle everything. + */ + break; + } + /* + * 7ms sleep is required after PA is enabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is needed. + */ + if (test_bit(HPH_PA_DELAY, &aqt->status_mask)) { + if (!aqt->comp_enabled[COMPANDER_2]) + usleep_range(20000, 20100); + else + usleep_range(7000, 7100); + clear_bit(HPH_PA_DELAY, &aqt->status_mask); + } + if (aqt->anc_func) { + /* Clear Tx FE HOLD if both PAs are enabled */ + if ((snd_soc_read(aqt->codec, AQT1000_ANA_HPH) & + 0xC0) == 0xC0) + aqt_codec_clear_anc_tx_hold(aqt); + } + + snd_soc_update_bits(codec, AQT1000_HPH_R_TEST, 0x01, 0x01); + + /* Remove mute */ + snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL, + 0x10, 0x00); + /* Enable GM3 boost */ + snd_soc_update_bits(codec, AQT1000_HPH_CNP_WG_CTL, + 0x80, 0x80); + /* Enable AutoChop timer at the end of power up */ + snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x02); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, AQT1000_CDC_RX2_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + AQT1000_CDC_RX2_RX_PATH_MIX_CTL, + 0x10, 0x00); + if (!(strcmp(w->name, "AQT ANC HPHR PA"))) { + dev_dbg(codec->dev, + "%s:Do everything needed for left channel\n", + __func__); + /* Do everything needed for left channel */ + snd_soc_update_bits(codec, AQT1000_HPH_L_TEST, + 0x01, 0x01); + + /* Remove mute */ + snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL, + 0x10, 0x00); + + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, + AQT1000_CDC_RX1_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + AQT1000_CDC_RX1_RX_PATH_MIX_CTL, + 0x10, 0x00); + + /* Remove ANC Rx from reset */ + ret = aqt_codec_enable_anc(w, kcontrol, event); + } + aqt_codec_override(codec, aqt->hph_mode, event); + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_update_bits(codec, AQT1000_HPH_R_TEST, 0x01, 0x00); + snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL, + 0x10, 0x10); + snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_MIX_CTL, + 0x10, 0x10); + if (!(strcmp(w->name, "AQT ANC HPHR PA"))) + snd_soc_update_bits(codec, AQT1000_ANA_HPH, 0x40, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + /* + * 5ms sleep is required after PA disable. If compander is + * disabled, then 20ms delay is needed after PA disable. + */ + if (!aqt->comp_enabled[COMPANDER_2]) + usleep_range(20000, 20100); + else + usleep_range(5000, 5100); + aqt_codec_override(codec, aqt->hph_mode, event); + if (!(strcmp(w->name, "AQT ANC HPHR PA"))) { + ret = aqt_codec_enable_anc(w, kcontrol, event); + snd_soc_update_bits(codec, + AQT1000_CDC_RX2_RX_PATH_CFG0, + 0x10, 0x00); + } + break; + }; + + return ret; +} + +static int aqt_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if ((!(strcmp(w->name, "AQT ANC HPHL PA"))) && + (test_bit(HPH_PA_DELAY, &aqt->status_mask))) + snd_soc_update_bits(codec, AQT1000_ANA_HPH, + 0xC0, 0xC0); + set_bit(HPH_PA_DELAY, &aqt->status_mask); + break; + case SND_SOC_DAPM_POST_PMU: + if (!(strcmp(w->name, "AQT ANC HPHL PA"))) { + if ((snd_soc_read(codec, AQT1000_ANA_HPH) & 0xC0) + != 0xC0) + /* + * If PA_EN is not set (potentially in ANC + * case) then do nothing for POST_PMU and + * let right channel handle everything. + */ + break; + } + /* + * 7ms sleep is required after PA is enabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is needed. + */ + if (test_bit(HPH_PA_DELAY, &aqt->status_mask)) { + if (!aqt->comp_enabled[COMPANDER_1]) + usleep_range(20000, 20100); + else + usleep_range(7000, 7100); + clear_bit(HPH_PA_DELAY, &aqt->status_mask); + } + if (aqt->anc_func) { + /* Clear Tx FE HOLD if both PAs are enabled */ + if ((snd_soc_read(aqt->codec, AQT1000_ANA_HPH) & + 0xC0) == 0xC0) + aqt_codec_clear_anc_tx_hold(aqt); + } + + snd_soc_update_bits(codec, AQT1000_HPH_L_TEST, 0x01, 0x01); + /* Remove Mute on primary path */ + snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL, + 0x10, 0x00); + /* Enable GM3 boost */ + snd_soc_update_bits(codec, AQT1000_HPH_CNP_WG_CTL, + 0x80, 0x80); + /* Enable AutoChop timer at the end of power up */ + snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x02); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, AQT1000_CDC_RX1_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + AQT1000_CDC_RX1_RX_PATH_MIX_CTL, + 0x10, 0x00); + if (!(strcmp(w->name, "AQT ANC HPHL PA"))) { + dev_dbg(codec->dev, + "%s:Do everything needed for right channel\n", + __func__); + + /* Do everything needed for right channel */ + snd_soc_update_bits(codec, AQT1000_HPH_R_TEST, + 0x01, 0x01); + + /* Remove mute */ + snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL, + 0x10, 0x00); + + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, + AQT1000_CDC_RX2_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + AQT1000_CDC_RX2_RX_PATH_MIX_CTL, + 0x10, 0x00); + /* Remove ANC Rx from reset */ + ret = aqt_codec_enable_anc(w, kcontrol, event); + } + aqt_codec_override(codec, aqt->hph_mode, event); + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_update_bits(codec, AQT1000_HPH_L_TEST, 0x01, 0x00); + snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL, + 0x10, 0x10); + snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_MIX_CTL, + 0x10, 0x10); + if (!(strcmp(w->name, "AQT ANC HPHL PA"))) + snd_soc_update_bits(codec, AQT1000_ANA_HPH, + 0x80, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + /* + * 5ms sleep is required after PA disable. If compander is + * disabled, then 20ms delay is needed after PA disable. + */ + if (!aqt->comp_enabled[COMPANDER_1]) + usleep_range(20000, 20100); + else + usleep_range(5000, 5100); + aqt_codec_override(codec, aqt->hph_mode, event); + if (!(strcmp(w->name, "AQT ANC HPHL PA"))) { + ret = aqt_codec_enable_anc(w, kcontrol, event); + snd_soc_update_bits(codec, + AQT1000_CDC_RX1_RX_PATH_CFG0, 0x10, 0x00); + } + break; + }; + + return ret; +} + +static int aqt_codec_set_iir_gain(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: /* fall through */ + case SND_SOC_DAPM_PRE_PMD: + if (strnstr(w->name, "AQT IIR0", sizeof("AQT IIR0"))) { + snd_soc_write(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, + snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)); + snd_soc_write(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, + snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)); + snd_soc_write(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, + snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)); + snd_soc_write(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, + snd_soc_read(codec, + AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)); + } + break; + } + return 0; +} + +static int aqt_enable_native_supply(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (++aqt->native_clk_users == 1) { + snd_soc_update_bits(codec, AQT1000_CLK_SYS_PLL_ENABLES, + 0x01, 0x01); + /* 100usec is needed as per HW requirement */ + usleep_range(100, 120); + snd_soc_update_bits(codec, + AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x02, 0x02); + snd_soc_update_bits(codec, + AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x10, 0x10); + } + break; + case SND_SOC_DAPM_PRE_PMD: + if (aqt->native_clk_users && + (--aqt->native_clk_users == 0)) { + snd_soc_update_bits(codec, + AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x10, 0x00); + snd_soc_update_bits(codec, + AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x02, 0x00); + snd_soc_update_bits(codec, AQT1000_CLK_SYS_PLL_ENABLES, + 0x01, 0x00); + } + break; + } + + dev_dbg(codec->dev, "%s: native_clk_users: %d, event: %d\n", + __func__, aqt->native_clk_users, event); + + return 0; +} + +static const char * const native_mux_text[] = { + "OFF", "ON", +}; + +AQT_DAPM_ENUM(int1_1_native, SND_SOC_NOPM, 0, native_mux_text); +AQT_DAPM_ENUM(int2_1_native, SND_SOC_NOPM, 0, native_mux_text); + +static int aif_cap_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static int aif_cap_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static const struct snd_kcontrol_new aif1_cap_mixer[] = { + SOC_SINGLE_EXT("TX0", SND_SOC_NOPM, AQT_TX0, 1, 0, + aif_cap_mixer_get, aif_cap_mixer_put), + SOC_SINGLE_EXT("TX1", SND_SOC_NOPM, AQT_TX1, 1, 0, + aif_cap_mixer_get, aif_cap_mixer_put), +}; + +static const struct snd_soc_dapm_widget aqt_dapm_widgets[] = { + + SND_SOC_DAPM_AIF_OUT_E("AQT AIF1 CAP", "AQT AIF1 Capture", 0, + SND_SOC_NOPM, AIF1_CAP, 0, aqt_codec_enable_i2s_tx, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER("AQT AIF1 CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0, + aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)), + + AQT_DAPM_MUX("AQT TX0_MUX", 0, tx0), + AQT_DAPM_MUX("AQT TX1_MUX", 0, tx1), + + SND_SOC_DAPM_MUX_E("AQT ADC0 MUX", AQT1000_CDC_TX0_TX_PATH_CTL, 5, 0, + &tx_adc0_mux, aqt_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("AQT ADC1 MUX", AQT1000_CDC_TX1_TX_PATH_CTL, 5, 0, + &tx_adc1_mux, aqt_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("AQT ADC2 MUX", AQT1000_CDC_TX2_TX_PATH_CTL, 5, 0, + &tx_adc2_mux, aqt_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + AQT_DAPM_MUX("AQT AMIC0_MUX", 0, tx_amic0), + AQT_DAPM_MUX("AQT AMIC1_MUX", 0, tx_amic1), + AQT_DAPM_MUX("AQT AMIC2_MUX", 0, tx_amic2), + + SND_SOC_DAPM_ADC_E("AQT ADC_L", NULL, AQT1000_ANA_AMIC1, 7, 0, + aqt_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_ADC_E("AQT ADC_R", NULL, AQT1000_ANA_AMIC2, 7, 0, + aqt_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_ADC_E("AQT ADC_V", NULL, AQT1000_ANA_AMIC3, 7, 0, + aqt_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), + + AQT_DAPM_MUX("AQT AMIC10_MUX", 0, tx_amic10), + AQT_DAPM_MUX("AQT AMIC11_MUX", 0, tx_amic11), + AQT_DAPM_MUX("AQT AMIC12_MUX", 0, tx_amic12), + AQT_DAPM_MUX("AQT AMIC13_MUX", 0, tx_amic13), + + SND_SOC_DAPM_SWITCH_E("AQT ANC OUT HPHL Enable", SND_SOC_NOPM, + INTERP_HPHL, 0, &anc_hphl_pa_switch, aqt_anc_out_switch_cb, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SWITCH_E("AQT ANC OUT HPHR Enable", SND_SOC_NOPM, + INTERP_HPHR, 0, &anc_hphr_pa_switch, aqt_anc_out_switch_cb, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_MIXER("AQT RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("AQT RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + + AQT_DAPM_MUX("AQT ANC0 FB MUX", 0, anc0_fb), + AQT_DAPM_MUX("AQT ANC1 FB MUX", 0, anc1_fb), + + SND_SOC_DAPM_INPUT("AQT AMIC1"), + SND_SOC_DAPM_INPUT("AQT AMIC2"), + SND_SOC_DAPM_INPUT("AQT AMIC3"), + + SND_SOC_DAPM_MIXER("AQT I2S_L RX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("AQT I2S_R RX", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_AIF_IN_E("AQT AIF1 PB", "AQT AIF1 Playback", 0, + SND_SOC_NOPM, AIF1_PB, 0, aqt_codec_enable_i2s_rx, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("AQT RX INT1_1 MUX", SND_SOC_NOPM, INTERP_HPHL, 0, + &rx_int1_1_mux, aqt_codec_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("AQT RX INT2_1 MUX", SND_SOC_NOPM, INTERP_HPHR, 0, + &rx_int2_1_mux, aqt_codec_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("AQT RX INT1_2 MUX", SND_SOC_NOPM, INTERP_HPHL, 0, + &rx_int1_2_mux, aqt_codec_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("AQT RX INT2_2 MUX", SND_SOC_NOPM, INTERP_HPHR, 0, + &rx_int2_2_mux, aqt_codec_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + AQT_DAPM_MUX("AQT RX INT1_1 INTERP", 0, rx_int1_1_interp), + AQT_DAPM_MUX("AQT RX INT1_2 INTERP", 0, rx_int1_2_interp), + AQT_DAPM_MUX("AQT RX INT2_1 INTERP", 0, rx_int2_1_interp), + AQT_DAPM_MUX("AQT RX INT2_2 INTERP", 0, rx_int2_2_interp), + + SND_SOC_DAPM_MIXER("AQT RX INT1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("AQT RX INT2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MUX_E("AQT ASRC0 MUX", SND_SOC_NOPM, ASRC0, 0, + &asrc0_mux, aqt_codec_enable_asrc_resampler, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("AQT ASRC1 MUX", SND_SOC_NOPM, ASRC1, 0, + &asrc1_mux, aqt_codec_enable_asrc_resampler, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + AQT_DAPM_MUX("AQT RX INT1 DEM MUX", 0, rx_int1_dem), + AQT_DAPM_MUX("AQT RX INT2 DEM MUX", 0, rx_int2_dem), + + SND_SOC_DAPM_DAC_E("AQT RX INT1 DAC", NULL, AQT1000_ANA_HPH, + 5, 0, aqt_codec_hphl_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("AQT RX INT2 DAC", NULL, AQT1000_ANA_HPH, + 4, 0, aqt_codec_hphr_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_PGA_E("AQT HPHL PA", AQT1000_ANA_HPH, 7, 0, NULL, 0, + aqt_codec_enable_hphl_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("AQT HPHR PA", AQT1000_ANA_HPH, 6, 0, NULL, 0, + aqt_codec_enable_hphr_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("AQT ANC HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0, + aqt_codec_enable_hphl_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("AQT ANC HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0, + aqt_codec_enable_hphr_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_OUTPUT("AQT HPHL"), + SND_SOC_DAPM_OUTPUT("AQT HPHR"), + SND_SOC_DAPM_OUTPUT("AQT ANC HPHL"), + SND_SOC_DAPM_OUTPUT("AQT ANC HPHR"), + + SND_SOC_DAPM_MIXER_E("AQT IIR0", AQT1000_CDC_SIDETONE_IIR0_IIR_PATH_CTL, + 4, 0, NULL, 0, aqt_codec_set_iir_gain, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_MIXER("AQT SRC0", + AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL, + 4, 0, NULL, 0), + + SND_SOC_DAPM_MICBIAS_E("AQT MIC BIAS1", SND_SOC_NOPM, 0, 0, + aqt_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("AQT RX_BIAS", SND_SOC_NOPM, 0, 0, + aqt_codec_enable_rx_bias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("AQT RX INT1 NATIVE SUPPLY", SND_SOC_NOPM, + INTERP_HPHL, 0, aqt_enable_native_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_SUPPLY("AQT RX INT2 NATIVE SUPPLY", SND_SOC_NOPM, + INTERP_HPHR, 0, aqt_enable_native_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + AQT_DAPM_MUX("AQT RX INT1_1 NATIVE MUX", 0, int1_1_native), + AQT_DAPM_MUX("AQT RX INT2_1 NATIVE MUX", 0, int2_1_native), +}; + +static int aqt_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + return 0; +} + +static void aqt_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); +} + +static int aqt_set_decimator_rate(struct snd_soc_dai *dai, + u32 sample_rate) +{ + struct snd_soc_codec *codec = dai->codec; + u8 tx_fs_rate = 0; + u8 tx_mux_sel = 0, tx0_mux_sel = 0, tx1_mux_sel = 0; + u16 tx_path_ctl_reg = 0; + + switch (sample_rate) { + case 8000: + tx_fs_rate = 0; + break; + case 16000: + tx_fs_rate = 1; + break; + case 32000: + tx_fs_rate = 3; + break; + case 48000: + tx_fs_rate = 4; + break; + case 96000: + tx_fs_rate = 5; + break; + case 192000: + tx_fs_rate = 6; + break; + default: + dev_err(codec->dev, "%s: Invalid TX sample rate: %d\n", + __func__, sample_rate); + return -EINVAL; + + }; + + /* Find which decimator path is enabled */ + tx_mux_sel = snd_soc_read(codec, AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0); + tx0_mux_sel = (tx_mux_sel & 0x03); + tx1_mux_sel = (tx_mux_sel & 0xC0); + + if (tx0_mux_sel) { + tx_path_ctl_reg = AQT1000_CDC_TX0_TX_PATH_CTL + + ((tx0_mux_sel - 1) * 16); + snd_soc_update_bits(codec, tx_path_ctl_reg, 0x0F, tx_fs_rate); + } + + if (tx1_mux_sel) { + tx_path_ctl_reg = AQT1000_CDC_TX0_TX_PATH_CTL + + ((tx1_mux_sel - 1) * 16); + snd_soc_update_bits(codec, tx_path_ctl_reg, 0x0F, tx_fs_rate); + } + + return 0; +} + +static int aqt_set_interpolator_rate(struct snd_soc_dai *dai, + u32 sample_rate) +{ + struct snd_soc_codec *codec = dai->codec; + int rate_val = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) { + if (sample_rate == sr_val_tbl[i].sample_rate) { + rate_val = sr_val_tbl[i].rate_val; + break; + } + } + if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) { + dev_err(codec->dev, "%s: Unsupported sample rate: %d\n", + __func__, sample_rate); + return -EINVAL; + } + + /* TODO - Set the rate only to enabled path */ + /* Set Primary interpolator rate */ + snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL, + 0x0F, (u8)rate_val); + snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL, + 0x0F, (u8)rate_val); + + /* Set mixing path interpolator rate */ + snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_MIX_CTL, + 0x0F, (u8)rate_val); + snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_MIX_CTL, + 0x0F, (u8)rate_val); + + return 0; +} + +static int aqt_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + return 0; +} + +static int aqt_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(dai->codec); + int ret = 0; + + dev_dbg(aqt->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", + __func__, dai->name, dai->id, params_rate(params), + params_channels(params)); + + switch (substream->stream) { + case SNDRV_PCM_STREAM_PLAYBACK: + ret = aqt_set_interpolator_rate(dai, params_rate(params)); + if (ret) { + dev_err(aqt->dev, "%s: cannot set sample rate: %u\n", + __func__, params_rate(params)); + return ret; + } + switch (params_width(params)) { + case 16: + aqt->dai[dai->id].bit_width = 16; + break; + case 24: + aqt->dai[dai->id].bit_width = 24; + break; + case 32: + aqt->dai[dai->id].bit_width = 32; + break; + default: + return -EINVAL; + } + aqt->dai[dai->id].rate = params_rate(params); + break; + case SNDRV_PCM_STREAM_CAPTURE: + ret = aqt_set_decimator_rate(dai, params_rate(params)); + if (ret) { + dev_err(aqt->dev, + "%s: cannot set TX Decimator rate: %d\n", + __func__, ret); + return ret; + } + switch (params_width(params)) { + case 16: + aqt->dai[dai->id].bit_width = 16; + break; + case 24: + aqt->dai[dai->id].bit_width = 24; + break; + default: + dev_err(aqt->dev, "%s: Invalid format 0x%x\n", + __func__, params_width(params)); + return -EINVAL; + }; + aqt->dai[dai->id].rate = params_rate(params); + break; + default: + dev_err(aqt->dev, "%s: Invalid stream type %d\n", __func__, + substream->stream); + return -EINVAL; + }; + + return 0; +} + +static struct snd_soc_dai_ops aqt_dai_ops = { + .startup = aqt_startup, + .shutdown = aqt_shutdown, + .hw_params = aqt_hw_params, + .prepare = aqt_prepare, +}; + +struct snd_soc_dai_driver aqt_dai[] = { + { + .name = "aqt_rx1", + .id = AIF1_PB, + .playback = { + .stream_name = "AQT AIF1 Playback", + .rates = AQT1000_RATES_MASK | AQT1000_FRAC_RATES_MASK, + .formats = AQT1000_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 384000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &aqt_dai_ops, + }, + { + .name = "aqt_tx1", + .id = AIF1_CAP, + .capture = { + .stream_name = "AQT AIF1 Capture", + .rates = AQT1000_RATES_MASK, + .formats = AQT1000_FORMATS_S16_S24_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &aqt_dai_ops, + }, +}; + +static int aqt_enable_mclk(struct aqt1000 *aqt) +{ + struct snd_soc_codec *codec = aqt->codec; + + /* Enable mclk requires master bias to be enabled first */ + if (aqt->master_bias_users <= 0) { + dev_err(aqt->dev, + "%s: Cannot turn on MCLK, BG is not enabled\n", + __func__); + return -EINVAL; + } + + if (++aqt->mclk_users == 1) { + /* Set clock div 2 */ + snd_soc_update_bits(codec, + AQT1000_CLK_SYS_MCLK1_PRG, 0x0C, 0x04); + snd_soc_update_bits(codec, + AQT1000_CLK_SYS_MCLK1_PRG, 0x10, 0x10); + snd_soc_update_bits(codec, + AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); + snd_soc_update_bits(codec, + AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + /* + * 10us sleep is required after clock is enabled + * as per HW requirement + */ + usleep_range(10, 15); + } + + dev_dbg(aqt->dev, "%s: mclk_users: %d\n", __func__, aqt->mclk_users); + + return 0; +} + +static int aqt_disable_mclk(struct aqt1000 *aqt) +{ + struct snd_soc_codec *codec = aqt->codec; + + if (aqt->mclk_users <= 0) { + dev_err(aqt->dev, "%s: No mclk users, cannot disable mclk\n", + __func__); + return -EINVAL; + } + + if (--aqt->mclk_users == 0) { + snd_soc_update_bits(codec, + AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x00); + snd_soc_update_bits(codec, + AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x00); + snd_soc_update_bits(codec, + AQT1000_CLK_SYS_MCLK1_PRG, 0x10, 0x00); + } + + dev_dbg(codec->dev, "%s: mclk_users: %d\n", __func__, aqt->mclk_users); + + return 0; +} + +static int aqt_enable_master_bias(struct aqt1000 *aqt) +{ + struct snd_soc_codec *codec = aqt->codec; + + mutex_lock(&aqt->master_bias_lock); + + aqt->master_bias_users++; + if (aqt->master_bias_users == 1) { + snd_soc_update_bits(codec, AQT1000_ANA_BIAS, 0x80, 0x80); + snd_soc_update_bits(codec, AQT1000_ANA_BIAS, 0x40, 0x40); + /* + * 1ms delay is required after pre-charge is enabled + * as per HW requirement + */ + usleep_range(1000, 1100); + snd_soc_update_bits(codec, AQT1000_ANA_BIAS, 0x40, 0x00); + } + + mutex_unlock(&aqt->master_bias_lock); + + return 0; +} + +static int aqt_disable_master_bias(struct aqt1000 *aqt) +{ + struct snd_soc_codec *codec = aqt->codec; + + mutex_lock(&aqt->master_bias_lock); + if (aqt->master_bias_users <= 0) { + mutex_unlock(&aqt->master_bias_lock); + return -EINVAL; + } + + aqt->master_bias_users--; + if (aqt->master_bias_users == 0) + snd_soc_update_bits(codec, AQT1000_ANA_BIAS, 0x80, 0x00); + mutex_unlock(&aqt->master_bias_lock); + + return 0; +} + +static int aqt_cdc_req_mclk_enable(struct aqt1000 *aqt, + bool enable) +{ + int ret = 0; + + if (enable) { + ret = clk_prepare_enable(aqt->ext_clk); + if (ret) { + dev_err(aqt->dev, "%s: ext clk enable failed\n", + __func__); + goto done; + } + /* Get BG */ + aqt_enable_master_bias(aqt); + /* Get MCLK */ + aqt_enable_mclk(aqt); + } else { + /* put MCLK */ + aqt_disable_mclk(aqt); + /* put BG */ + if (aqt_disable_master_bias(aqt)) + dev_err(aqt->dev, "%s: master bias disable failed\n", + __func__); + clk_disable_unprepare(aqt->ext_clk); + } + +done: + return ret; +} + +static int __aqt_cdc_mclk_enable_locked(struct aqt1000 *aqt, + bool enable) +{ + int ret = 0; + + dev_dbg(aqt->dev, "%s: mclk_enable = %u\n", __func__, enable); + + if (enable) + ret = aqt_cdc_req_mclk_enable(aqt, true); + else + aqt_cdc_req_mclk_enable(aqt, false); + + return ret; +} + +static int __aqt_cdc_mclk_enable(struct aqt1000 *aqt, + bool enable) +{ + int ret; + + mutex_lock(&aqt->cdc_bg_clk_lock); + ret = __aqt_cdc_mclk_enable_locked(aqt, enable); + mutex_unlock(&aqt->cdc_bg_clk_lock); + + return ret; +} + +/** + * aqt_cdc_mclk_enable - Enable/disable codec mclk + * + * @codec: codec instance + * @enable: Indicates clk enable or disable + * + * Returns 0 on Success and error on failure + */ +int aqt_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable) +{ + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + return __aqt_cdc_mclk_enable(aqt, enable); +} +EXPORT_SYMBOL(aqt_cdc_mclk_enable); + +/* + * aqt_get_micb_vout_ctl_val: converts micbias from volts to register value + * @micb_mv: micbias in mv + * + * return register value converted + */ +int aqt_get_micb_vout_ctl_val(u32 micb_mv) +{ + /* min micbias voltage is 1V and maximum is 2.85V */ + if (micb_mv < 1000 || micb_mv > 2850) { + pr_err("%s: unsupported micbias voltage\n", __func__); + return -EINVAL; + } + + return (micb_mv - 1000) / 50; +} +EXPORT_SYMBOL(aqt_get_micb_vout_ctl_val); + +static int aqt_set_micbias(struct aqt1000 *aqt, + struct aqt1000_pdata *pdata) +{ + struct snd_soc_codec *codec = aqt->codec; + int vout_ctl_1; + + if (!pdata) { + dev_err(codec->dev, "%s: NULL pdata\n", __func__); + return -ENODEV; + } + + /* set micbias voltage */ + vout_ctl_1 = aqt_get_micb_vout_ctl_val(pdata->micbias.micb1_mv); + if (vout_ctl_1 < 0) + return -EINVAL; + + snd_soc_update_bits(codec, AQT1000_ANA_MICB1, 0x3F, vout_ctl_1); + + return 0; +} + +static const struct aqt_reg_mask_val aqt_codec_reg_init[] = { + {AQT1000_CHIP_CFG0_CLK_CFG_MCLK, 0x04, 0x00}, + {AQT1000_CHIP_CFG0_EFUSE_CTL, 0x01, 0x01}, +}; + +static const struct aqt_reg_mask_val aqt_codec_reg_update[] = { + {AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x01}, + {AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x01}, + {AQT1000_CHIP_CFG0_CLK_CTL_CDC_DIG, 0x01, 0x01}, + {AQT1000_LDOH_MODE, 0x1F, 0x0B}, + {AQT1000_MICB1_TEST_CTL_2, 0x07, 0x01}, + {AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS, 0x03, 0x02}, + {AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS, 0x0C, 0x08}, + {AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS, 0x30, 0x20}, + {AQT1000_CDC_TX0_TX_PATH_CFG1, 0x01, 0x00}, + {AQT1000_CDC_TX1_TX_PATH_CFG1, 0x01, 0x00}, + {AQT1000_CDC_TX2_TX_PATH_CFG1, 0x01, 0x00}, +}; + +static void aqt_codec_init_reg(struct aqt1000 *priv) +{ + struct snd_soc_codec *codec = priv->codec; + u32 i; + + for (i = 0; i < ARRAY_SIZE(aqt_codec_reg_init); i++) + snd_soc_update_bits(codec, + aqt_codec_reg_init[i].reg, + aqt_codec_reg_init[i].mask, + aqt_codec_reg_init[i].val); +} + +static void aqt_codec_update_reg(struct aqt1000 *priv) +{ + struct snd_soc_codec *codec = priv->codec; + u32 i; + + for (i = 0; i < ARRAY_SIZE(aqt_codec_reg_update); i++) + snd_soc_update_bits(codec, + aqt_codec_reg_update[i].reg, + aqt_codec_reg_update[i].mask, + aqt_codec_reg_update[i].val); + +} + +static int aqt_soc_codec_probe(struct snd_soc_codec *codec) +{ + struct aqt1000 *aqt; + struct aqt1000_pdata *pdata; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + int i, ret = 0; + + dev_dbg(codec->dev, "%s()\n", __func__); + aqt = snd_soc_codec_get_drvdata(codec); + + mutex_init(&aqt->codec_mutex); + mutex_init(&aqt->i2s_lock); + /* Class-H Init */ + aqt_clsh_init(&aqt->clsh_d); + /* Default HPH Mode to Class-H Low HiFi */ + aqt->hph_mode = CLS_H_LOHIFI; + + aqt->fw_data = devm_kzalloc(codec->dev, sizeof(*(aqt->fw_data)), + GFP_KERNEL); + if (!aqt->fw_data) + goto err; + + set_bit(WCD9XXX_ANC_CAL, aqt->fw_data->cal_bit); + set_bit(WCD9XXX_MBHC_CAL, aqt->fw_data->cal_bit); + + ret = wcd_cal_create_hwdep(aqt->fw_data, + AQT1000_CODEC_HWDEP_NODE, codec); + if (ret < 0) { + dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret); + goto err_hwdep; + } + + aqt->codec = codec; + for (i = 0; i < COMPANDER_MAX; i++) + aqt->comp_enabled[i] = 0; + + aqt_cdc_mclk_enable(codec, true); + aqt_codec_init_reg(aqt); + aqt_cdc_mclk_enable(codec, false); + + /* Add 100usec delay as per HW requirement */ + usleep_range(100, 110); + + aqt_codec_update_reg(aqt); + + pdata = dev_get_platdata(codec->dev); + + /* If 1.8v is supplied externally, then disable internal 1.8v supply */ + for (i = 0; i < pdata->num_supplies; i++) { + if (!strcmp(pdata->regulator->name, "aqt_vdd1p8")) { + snd_soc_update_bits(codec, AQT1000_BUCK_5V_EN_CTL, + 0x03, 0x00); + dev_dbg(codec->dev, "%s: Disabled internal supply\n", + __func__); + break; + } + } + + aqt_set_micbias(aqt, pdata); + + snd_soc_dapm_add_routes(dapm, aqt_audio_map, + ARRAY_SIZE(aqt_audio_map)); + + for (i = 0; i < NUM_CODEC_DAIS; i++) { + INIT_LIST_HEAD(&aqt->dai[i].ch_list); + init_waitqueue_head(&aqt->dai[i].dai_wait); + } + + for (i = 0; i < AQT1000_NUM_DECIMATORS; i++) { + aqt->tx_hpf_work[i].aqt = aqt; + aqt->tx_hpf_work[i].decimator = i; + INIT_DELAYED_WORK(&aqt->tx_hpf_work[i].dwork, + aqt_tx_hpf_corner_freq_callback); + + aqt->tx_mute_dwork[i].aqt = aqt; + aqt->tx_mute_dwork[i].decimator = i; + INIT_DELAYED_WORK(&aqt->tx_mute_dwork[i].dwork, + aqt_tx_mute_update_callback); + } + + mutex_lock(&aqt->codec_mutex); + snd_soc_dapm_disable_pin(dapm, "AQT ANC HPHL PA"); + snd_soc_dapm_disable_pin(dapm, "AQT ANC HPHR PA"); + snd_soc_dapm_disable_pin(dapm, "AQT ANC HPHL"); + snd_soc_dapm_disable_pin(dapm, "AQT ANC HPHR"); + mutex_unlock(&aqt->codec_mutex); + + snd_soc_dapm_ignore_suspend(dapm, "AQT AIF1 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AQT AIF1 Capture"); + + snd_soc_dapm_sync(dapm); + + return ret; + +err_hwdep: + devm_kfree(codec->dev, aqt->fw_data); + aqt->fw_data = NULL; +err: + mutex_destroy(&aqt->i2s_lock); + mutex_destroy(&aqt->codec_mutex); + return ret; +} + +static int aqt_soc_codec_remove(struct snd_soc_codec *codec) +{ + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + + mutex_destroy(&aqt->i2s_lock); + mutex_destroy(&aqt->codec_mutex); + + return 0; +} + +static struct regmap *aqt_get_regmap(struct device *dev) +{ + struct aqt1000 *control = dev_get_drvdata(dev); + + return control->regmap; +} + +struct snd_soc_codec_driver snd_cdc_dev_aqt = { + .probe = aqt_soc_codec_probe, + .remove = aqt_soc_codec_remove, + .get_regmap = aqt_get_regmap, + .component_driver = { + .controls = aqt_snd_controls, + .num_controls = ARRAY_SIZE(aqt_snd_controls), + .dapm_widgets = aqt_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(aqt_dapm_widgets), + .dapm_routes = aqt_audio_map, + .num_dapm_routes = ARRAY_SIZE(aqt_audio_map), + }, +}; + +/* + * aqt_register_codec: Register the device to ASoC + * @dev: device + * + * return 0 success or error code in case of failure + */ +int aqt_register_codec(struct device *dev) +{ + return snd_soc_register_codec(dev, &snd_cdc_dev_aqt, aqt_dai, + ARRAY_SIZE(aqt_dai)); +} +EXPORT_SYMBOL(aqt_register_codec); diff --git a/asoc/codecs/aqt1000/aqt1000.h b/asoc/codecs/aqt1000/aqt1000.h new file mode 100644 index 000000000000..4267e6f552aa --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000.h @@ -0,0 +1,225 @@ +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef AQT1000_H +#define AQT1000_H + +#include +#include +#include +#include +#include "pdata.h" +#include "aqt1000-clsh.h" + +#define AQT1000_MAX_MICBIAS 1 +#define AQT1000_NUM_INTERPOLATORS 2 +#define AQT1000_NUM_DECIMATORS 3 +#define AQT1000_VOUT_CTL_TO_MICB(v) (1000 + v * 50) +#define AQT1000_RX_PATH_CTL_OFFSET 20 + +#define AQT1000_CLK_24P576MHZ 24576000 +#define AQT1000_CLK_19P2MHZ 19200000 +#define AQT1000_CLK_12P288MHZ 12288000 +#define AQT1000_CLK_9P6MHZ 9600000 + +#define AQT1000_ST_IIR_COEFF_MAX 5 + +enum { + AQT1000_RX0 = 0, + AQT1000_RX1, + AQT1000_RX_MAX, +}; + +enum { + AQT_NONE, + AQT_MCLK, + AQT_RCO, +}; + +enum { + AQT_TX0 = 0, + AQT_TX1, +}; + +enum { + ASRC0, + ASRC1, + ASRC_MAX, +}; + +/* Each IIR has 5 Filter Stages */ +enum { + BAND1 = 0, + BAND2, + BAND3, + BAND4, + BAND5, + BAND_MAX, +}; + +enum { + AQT1000_TX0 = 0, + AQT1000_TX1, + AQT1000_TX2, + AQT1000_TX_MAX, +}; + +enum { + INTERP_HPHL, + INTERP_HPHR, + INTERP_MAX, +}; + +enum { + INTERP_MAIN_PATH, + INTERP_MIX_PATH, +}; + +enum { + COMPANDER_1, /* HPH_L */ + COMPANDER_2, /* HPH_R */ + COMPANDER_MAX, +}; + +enum { + AIF1_PB = 0, + AIF1_CAP, + NUM_CODEC_DAIS, +}; + +struct aqt_codec_dai_data { + u32 rate; + u32 *ch_num; + u32 ch_act; + u32 ch_tot; +}; + +struct aqt_idle_detect_config { + u8 hph_idle_thr; + u8 hph_idle_detect_en; +}; + +struct aqt1000_i2c { + struct i2c_client *client; + struct i2c_msg xfer_msg[2]; + struct mutex xfer_lock; + int mod_id; +}; + +struct aqt1000_cdc_dai_data { + u32 rate; /* sample rate */ + u32 bit_width; /* sit width 16,24,32 */ + struct list_head ch_list; + wait_queue_head_t dai_wait; +}; + +struct tx_mute_work { + struct aqt1000 *aqt; + u8 decimator; + struct delayed_work dwork; +}; + +struct hpf_work { + struct aqt1000 *aqt; + u8 decimator; + u8 hpf_cut_off_freq; + struct delayed_work dwork; +}; + +struct aqt1000 { + struct device *dev; + struct mutex io_lock; + struct mutex xfer_lock; + struct mutex reset_lock; + + struct device_node *aqt_rst_np; + + int (*read_dev)(struct aqt1000 *aqt, unsigned short reg, + void *dest, int bytes); + int (*write_dev)(struct aqt1000 *aqt, unsigned short reg, + void *src, int bytes); + + u32 num_of_supplies; + struct regulator_bulk_data *supplies; + + u32 mclk_rate; + struct regmap *regmap; + struct snd_soc_codec *codec; + bool dev_up; + bool prev_pg_valid; + u8 prev_pg; + + struct aqt1000_i2c i2c_dev; + + /* Codec params */ + + /* ANC related */ + u32 anc_slot; + bool anc_func; + + /* compander */ + int comp_enabled[COMPANDER_MAX]; + + /* class h specific data */ + struct aqt_clsh_cdc_data clsh_d; + + /* Interpolator Mode Select for HPH_L and HPH_R */ + u32 hph_mode; + + unsigned long status_mask; + + struct aqt1000_cdc_dai_data dai[NUM_CODEC_DAIS]; + + struct mutex micb_lock; + + struct clk *ext_clk; + + /* mbhc module */ + struct aqt1000_mbhc *mbhc; + + struct mutex codec_mutex; + + /* cal info for codec */ + struct fw_info *fw_data; + + int native_clk_users; + /* ASRC users count */ + int asrc_users[ASRC_MAX]; + int asrc_output_mode[ASRC_MAX]; + /* Main path clock users count */ + int main_clk_users[AQT1000_NUM_INTERPOLATORS]; + + struct aqt_idle_detect_config idle_det_cfg; + u32 rx_bias_count; + + s32 micb_ref; + s32 pullup_ref; + int master_bias_users; + int mclk_users; + int i2s_users; + + struct hpf_work tx_hpf_work[AQT1000_NUM_DECIMATORS]; + struct tx_mute_work tx_mute_dwork[AQT1000_NUM_DECIMATORS]; + + struct mutex master_bias_lock; + struct mutex cdc_bg_clk_lock; + struct mutex i2s_lock; + + /* Interrupt */ + struct regmap_irq_chip_data *irq_chip; + int num_irq_regs; + struct irq_domain *virq; + int irq; + int irq_base; +}; + +#endif /* AQT1000_H */ diff --git a/asoc/codecs/aqt1000/pdata.h b/asoc/codecs/aqt1000/pdata.h new file mode 100644 index 000000000000..2c29848d7989 --- /dev/null +++ b/asoc/codecs/aqt1000/pdata.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _AQT1000_PDATA_H_ +#define _AQT1000_PDATA_H_ + +#include +#include +#include "../msm-cdc-supply.h" + +struct aqt1000_micbias_setting { + u8 ldoh_v; + u32 cfilt1_mv; + u32 micb1_mv; + u8 bias1_cfilt_sel; +}; + +struct aqt1000_pdata { + unsigned int irq_gpio; + unsigned int irq_flags; + struct cdc_regulator *regulator; + int num_supplies; + struct aqt1000_micbias_setting micbias; + struct device_node *aqt_rst_np; + u32 mclk_rate; + u32 ext_clk_rate; + u32 ext_1p8v_supply; +}; + +#endif /* _AQT1000_PDATA_H_ */ -- GitLab From 7ba0a822629f4482fcb44fa16e82d490e89291ae Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 7 Feb 2018 12:29:41 +0800 Subject: [PATCH 0155/1645] ASoC: change OUT_DIR to PRODUCT_OUT for wcd9360 OUT_DIR folder doesn't point to the right out folder. It would not delete the right Module.symvers for wcd9360. Change OUT_DIR to PRODUCT_OUT to delete the right wcd9360 module symbol. Change-Id: I6ad376e1cad8416d8eefeefe41e0933813d64997 Signed-off-by: Meng Wang --- Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Android.mk b/Android.mk index 6a75d00ce25d..5352d1885720 100644 --- a/Android.mk +++ b/Android.mk @@ -31,6 +31,6 @@ include $(MY_LOCAL_PATH)/asoc/codecs/msm_sdw/Android.mk endif ifeq ($(call is-board-platform-in-list,msmnile),true) -$(shell rm -rf $(OUT_DIR)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd9360/Module.symvers) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd9360/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wcd9360/Android.mk endif -- GitLab From 22e868b3b000bb5a2365fcdec86ca27a3fd7a589 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 21 Dec 2017 06:20:58 +0530 Subject: [PATCH 0156/1645] ASoC: AQT1000: Add Interrupt controller support for AQT codec AQT codec has MBHC(Multi Button Headset Controller) and other headset interrupts. Add interrupt controller driver to handle AQT codec interrupts. Change-Id: Ic8eb6b0ca24aa82c9adeb9f0fa0bf8768b424787 Signed-off-by: Sudheer Papothi --- asoc/codecs/aqt1000/aqt1000-core.c | 7 + asoc/codecs/aqt1000/aqt1000-irq.c | 367 +++++++++++++++++++---------- asoc/codecs/aqt1000/aqt1000-irq.h | 43 +--- 3 files changed, 256 insertions(+), 161 deletions(-) diff --git a/asoc/codecs/aqt1000/aqt1000-core.c b/asoc/codecs/aqt1000/aqt1000-core.c index 2306a2acfd7e..f6fee2063a09 100644 --- a/asoc/codecs/aqt1000/aqt1000-core.c +++ b/asoc/codecs/aqt1000/aqt1000-core.c @@ -28,6 +28,7 @@ #include "aqt1000-internal.h" #include "aqt1000.h" #include "aqt1000-utils.h" +#include "aqt1000-irq.h" static int aqt1000_bringup(struct aqt1000 *aqt) { @@ -113,6 +114,11 @@ static int aqt1000_device_init(struct aqt1000 *aqt) goto done; } + ret = aqt_irq_init(aqt); + if (ret) + goto done; + + return ret; done: mutex_destroy(&aqt->io_lock); mutex_destroy(&aqt->xfer_lock); @@ -392,6 +398,7 @@ static int aqt1000_bringdown(struct device *dev) static void aqt1000_device_exit(struct aqt1000 *aqt) { + aqt_irq_exit(aqt); aqt1000_bringdown(aqt->dev); mutex_destroy(&aqt->io_lock); mutex_destroy(&aqt->xfer_lock); diff --git a/asoc/codecs/aqt1000/aqt1000-irq.c b/asoc/codecs/aqt1000/aqt1000-irq.c index e01dc4602379..0c1335306465 100644 --- a/asoc/codecs/aqt1000/aqt1000-irq.c +++ b/asoc/codecs/aqt1000/aqt1000-irq.c @@ -12,174 +12,289 @@ #include #include -#include #include #include +#include #include #include #include #include #include #include +#include + +#include "pdata.h" +#include "aqt1000.h" #include "aqt1000-registers.h" #include "aqt1000-irq.h" +static const struct regmap_irq aqt1000_irqs[AQT1000_NUM_IRQS] = { + REGMAP_IRQ_REG(AQT1000_IRQ_MBHC_BUTTON_RELEASE_DET, 0, 0x01), + REGMAP_IRQ_REG(AQT1000_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x02), + REGMAP_IRQ_REG(AQT1000_IRQ_MBHC_ELECT_INS_REM_DET, 0, 0x04), + REGMAP_IRQ_REG(AQT1000_IRQ_MBHC_ELECT_INS_REM_LEG_DET, 0, 0x08), + REGMAP_IRQ_REG(AQT1000_IRQ_MBHC_SW_DET, 0, 0x10), + REGMAP_IRQ_REG(AQT1000_IRQ_HPH_PA_OCPL_FAULT, 0, 0x20), + REGMAP_IRQ_REG(AQT1000_IRQ_HPH_PA_OCPR_FAULT, 0, 0x40), + REGMAP_IRQ_REG(AQT1000_IRQ_HPH_PA_CNPL_COMPLETE, 0, 0x80), + REGMAP_IRQ_REG(AQT1000_IRQ_HPH_PA_CNPR_COMPLETE, 1, 0x01), + REGMAP_IRQ_REG(AQT1000_CDC_HPHL_SURGE, 1, 0x02), + REGMAP_IRQ_REG(AQT1000_CDC_HPHR_SURGE, 1, 0x04), +}; + +static const struct regmap_irq_chip aqt_regmap_irq_chip = { + .name = "AQT1000", + .irqs = aqt1000_irqs, + .num_irqs = ARRAY_SIZE(aqt1000_irqs), + .num_regs = 2, + .status_base = AQT1000_INTR_CTRL_INT_STATUS_2, + .mask_base = AQT1000_INTR_CTRL_INT_MASK_2, + .unmask_base = AQT1000_INTR_CTRL_INT_CLEAR_2, + .ack_base = AQT1000_INTR_CTRL_INT_STATUS_2, + .runtime_pm = true, +}; + +static int aqt_map_irq(struct aqt1000 *aqt, int irq) +{ + return regmap_irq_get_virq(aqt->irq_chip, irq); +} + +/** + * aqt_request_irq: Request a thread handler for the given IRQ + * @aqt: pointer to aqt1000 structure + * @irq: irq number + * @name: name for the IRQ thread + * @handler: irq handler + * @data: data pointer + * + * Returns 0 on success or error on failure + */ +int aqt_request_irq(struct aqt1000 *aqt, int irq, const char *name, + irq_handler_t handler, void *data) +{ + irq = aqt_map_irq(aqt, irq); + if (irq < 0) + return irq; + + return request_threaded_irq(irq, NULL, handler, IRQF_ONESHOT, + name, data); +} +EXPORT_SYMBOL(aqt_request_irq); + +/** + * aqt_free_irq: Free the IRQ resources allocated during request_irq + * @aqt: pointer to aqt1000 structure + * @irq: irq number + * @data: data pointer + */ +void aqt_free_irq(struct aqt1000 *aqt, int irq, void *data) +{ + irq = aqt_map_irq(aqt, irq); + if (irq < 0) + return; + + free_irq(irq, data); +} +EXPORT_SYMBOL(aqt_free_irq); -static int aqt_irq_init(struct aqt1000_irq *aqt_irq) +/** + * aqt_enable_irq: Enable the given IRQ + * @aqt: pointer to aqt1000 structure + * @irq: irq number + */ +void aqt_enable_irq(struct aqt1000 *aqt, int irq) +{ + if (aqt) + enable_irq(aqt_map_irq(aqt, irq)); +} +EXPORT_SYMBOL(aqt_enable_irq); + +/** + * aqt_disable_irq: Disable the given IRQ + * @aqt: pointer to aqt1000 structure + * @irq: irq number + */ +void aqt_disable_irq(struct aqt1000 *aqt, int irq) +{ + if (aqt) + disable_irq(aqt_map_irq(aqt, irq)); +} +EXPORT_SYMBOL(aqt_disable_irq); + +static irqreturn_t aqt_irq_thread(int irq, void *data) +{ + int ret = 0; + u8 sts[2]; + struct aqt1000 *aqt = data; + int num_irq_regs = aqt->num_irq_regs; + struct aqt1000_pdata *pdata; + + pdata = dev_get_platdata(aqt->dev); + + memset(sts, 0, sizeof(sts)); + ret = regmap_bulk_read(aqt->regmap, AQT1000_INTR_CTRL_INT_STATUS_2, + sts, num_irq_regs); + if (ret < 0) { + dev_err(aqt->dev, "%s: Failed to read intr status: %d\n", + __func__, ret); + } else if (ret == 0) { + while (gpio_get_value_cansleep(pdata->irq_gpio)) + handle_nested_irq(irq_find_mapping(aqt->virq, 0)); + } + + return IRQ_HANDLED; +} + +static void aqt_irq_disable(struct irq_data *data) +{ +} + +static void aqt_irq_enable(struct irq_data *data) +{ +} + +static struct irq_chip aqt_irq_chip = { + .name = "AQT", + .irq_disable = aqt_irq_disable, + .irq_enable = aqt_irq_enable, +}; + +static int aqt_irq_map(struct irq_domain *irqd, unsigned int virq, + irq_hw_number_t hw) +{ + struct aqt1000 *data = irqd->host_data; + + irq_set_chip_data(virq, data); + irq_set_chip_and_handler(virq, &aqt_irq_chip, handle_simple_irq); + irq_set_nested_thread(virq, 1); + irq_set_noprobe(virq); + + return 0; +} + +static const struct irq_domain_ops aqt_domain_ops = { + .map = aqt_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + +/** + * aqt_irq_init: Initializes IRQ module + * @aqt: pointer to aqt1000 structure + * + * Returns 0 on success or error on failure + */ +int aqt_irq_init(struct aqt1000 *aqt) { int i, ret; + unsigned int flags = IRQF_ONESHOT; + struct irq_data *irq_data; + struct aqt1000_pdata *pdata; - if (aqt_irq == NULL) { - pr_err("%s: aqt_irq is NULL\n", __func__); + if (!aqt) { + pr_err("%s: Null pointer handle\n", __func__); return -EINVAL; } - mutex_init(&aqt_irq->irq_lock); - mutex_init(&aqt_irq->nested_irq_lock); - - aqt_irq->irq = aqt_irq_get_upstream_irq(aqt_irq); - if (!aqt_irq->irq) { - pr_warn("%s: irq driver is not yet initialized\n", __func__); - mutex_destroy(&aqt_irq->irq_lock); - mutex_destroy(&aqt_irq->nested_irq_lock); - return -EPROBE_DEFER; - } - pr_debug("%s: probed irq %d\n", __func__, aqt_irq->irq); - /* Setup downstream IRQs */ - ret = aqt_irq_setup_downstream_irq(aqt_irq); - if (ret) { - pr_err("%s: Failed to setup downstream IRQ\n", __func__); - goto fail_irq_init; + if (!aqt->irq) { + dev_dbg(aqt->dev, "%s: No interrupt specified\n", __func__); + aqt->irq_base = 0; + return 0; } - /* mask all the interrupts */ - for (i = 0; i < aqt_irq->num_irqs; i++) { - aqt_irq->irq_masks_cur |= BYTE_BIT_MASK(i); - aqt_irq->irq_masks_cache |= BYTE_BIT_MASK(i); + pdata = dev_get_platdata(aqt->dev); + if (!pdata) { + dev_err(aqt->dev, "%s: Invalid platform data\n", __func__); + return -EINVAL; } - ret = request_threaded_irq(aqt_irq->irq, NULL, aqt_irq_thread, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, - "aqt", aqt_irq); - if (ret != 0) { - dev_err(aqt_irq->dev, "Failed to request IRQ %d: %d\n", - aqt_irq->irq, ret); - } else { - ret = enable_irq_wake(aqt_irq->irq); + /* Select default if not defined in DT */ + flags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT; + if (pdata->irq_flags) + flags = pdata->irq_flags; + + if (pdata->irq_gpio) { + if (gpio_to_irq(pdata->irq_gpio) != aqt->irq) { + dev_warn(aqt->dev, "%s: IRQ %d is not GPIO %d (%d)\n", + __func__, aqt->irq, pdata->irq_gpio, + gpio_to_irq(pdata->irq_gpio)); + aqt->irq = gpio_to_irq(pdata->irq_gpio); + } + + ret = devm_gpio_request_one(aqt->dev, pdata->irq_gpio, + GPIOF_IN, "AQT IRQ"); if (ret) { - dev_err(aqt_irq->dev, - "Failed to set wake interrupt on IRQ %d: %d\n", - aqt_irq->irq, ret); - free_irq(aqt_irq->irq, aqt_irq); + dev_err(aqt->dev, "%s: Failed to request gpio %d\n", + __func__, ret); + pdata->irq_gpio = 0; + return ret; } + } else { + dev_dbg(aqt->dev, "%s: irq_gpio is %d\n", + __func__, pdata->irq_gpio); + return 0; } - if (ret) - goto fail_irq_init; - - return ret; + irq_data = irq_get_irq_data(aqt->irq); + if (!irq_data) { + dev_err(aqt->dev, "%s: Invalid IRQ: %d\n", + __func__, aqt->irq); + return -EINVAL; + } -fail_irq_init: - dev_err(aqt_irq->dev, - "%s: Failed to init aqt irq\n", __func__); - aqt_irq_put_upstream_irq(aqt_irq); - mutex_destroy(&aqt_irq->irq_lock); - mutex_destroy(&aqt_irq->nested_irq_lock); - return ret; -} + for (i = 0; i < aqt->num_irq_regs; i++) { + regmap_write(aqt->regmap, + (AQT1000_INTR_CTRL_INT_TYPE_2 + i), 0); + } -static int aqt_irq_probe(struct platform_device *pdev) -{ - int irq; - struct aqt1000_irq *aqt_irq = NULL; - int ret = -EINVAL; - - irq = platform_get_irq_byname(pdev, "aqt-int"); - if (irq < 0) { - dev_err(&pdev->dev, "%s: Couldn't find aqt-int node(%d)\n", - __func__, irq); - return -EINVAL; + aqt->virq = irq_domain_add_linear(NULL, 1, &aqt_domain_ops, aqt); + if (!aqt->virq) { + dev_err(aqt->dev, "%s: Failed to add IRQ domain\n", __func__); + ret = -EINVAL; + goto err; } - aqt_irq = kzalloc(sizeof(*aqt_irq), GFP_KERNEL); - if (!aqt_irq) - return -ENOMEM; - /* - * AQT interrupt controller supports N to N irq mapping with - * single cell binding with irq numbers(offsets) only. - * Use irq_domain_simple_ops that has irq_domain_simple_map and - * irq_domain_xlate_onetwocell. - */ - aqt_irq->dev = &pdev->dev; - aqt_irq->domain = irq_domain_add_linear(aqt_irq->dev->of_node, - WSA_NUM_IRQS, &irq_domain_simple_ops, - aqt_irq); - if (!aqt_irq->domain) { - dev_err(&pdev->dev, "%s: domain is NULL\n", __func__); - ret = -ENOMEM; + ret = regmap_add_irq_chip(aqt->regmap, + irq_create_mapping(aqt->virq, 0), + IRQF_ONESHOT, 0, &aqt_regmap_irq_chip, + &aqt->irq_chip); + if (ret) { + dev_err(aqt->dev, "%s: Failed to add IRQs: %d\n", + __func__, ret); goto err; } - aqt_irq->dev = &pdev->dev; - dev_dbg(&pdev->dev, "%s: virq = %d\n", __func__, irq); - aqt_irq->irq = irq; - aqt_irq->num_irq_regs = 2; - aqt_irq->num_irqs = WSA_NUM_IRQS; - ret = aqt_irq_init(aqt_irq); - if (ret < 0) { - dev_err(&pdev->dev, "%s: failed to do irq init %d\n", - __func__, ret); - goto err; + ret = request_threaded_irq(aqt->irq, NULL, aqt_irq_thread, flags, + "aqt", aqt); + if (ret) { + dev_err(aqt->dev, "%s: failed to register irq: %d\n", + __func__, ret); + goto err_irq; } - return ret; + return 0; + +err_irq: + regmap_del_irq_chip(irq_create_mapping(aqt->virq, 1), aqt->irq_chip); err: - kfree(aqt_irq); return ret; } +EXPORT_SYMBOL(aqt_irq_init); -static int aqt_irq_remove(struct platform_device *pdev) +/** + * aqt_irq_exit: Uninitialize regmap IRQ and free IRQ resources + * @aqt: pointer to aqt1000 structure + * + * Returns 0 on success or error on failure + */ +int aqt_irq_exit(struct aqt1000 *aqt) { - struct irq_domain *domain; - struct aqt1000_irq *data; - - domain = irq_find_host(pdev->dev.of_node); - if (unlikely(!domain)) { - pr_err("%s: domain is NULL\n", __func__); + if (!aqt) { + pr_err("%s: Null pointer handle\n", __func__); return -EINVAL; } - data = (struct aqt_irq *)domain->host_data; - data->irq = 0; + regmap_del_irq_chip(irq_create_mapping(aqt->virq, 1), aqt->irq_chip); + free_irq(aqt->irq, aqt); return 0; } - -static const struct of_device_id of_match[] = { - { .compatible = "qcom,aqt-irq" }, - { } -}; - -static struct platform_driver aqt_irq_driver = { - .probe = aqt_irq_probe, - .remove = aqt_irq_remove, - .driver = { - .name = "aqt_intc", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(of_match), - }, -}; - -static int aqt_irq_drv_init(void) -{ - return platform_driver_register(&aqt_irq_driver); -} -subsys_initcall(aqt_irq_drv_init); - -static void aqt_irq_drv_exit(void) -{ - platform_driver_unregister(&aqt_irq_driver); -} -module_exit(aqt_irq_drv_exit); - -MODULE_DESCRIPTION("AQT1000 IRQ driver"); -MODULE_LICENSE("GPL v2"); +EXPORT_SYMBOL(aqt_irq_exit); diff --git a/asoc/codecs/aqt1000/aqt1000-irq.h b/asoc/codecs/aqt1000/aqt1000-irq.h index dd5b1166a19d..60be49c21163 100644 --- a/asoc/codecs/aqt1000/aqt1000-irq.h +++ b/asoc/codecs/aqt1000/aqt1000-irq.h @@ -13,6 +13,7 @@ #ifndef __AQT1000_IRQ_H_ #define __AQT1000_IRQ_H_ +#include #include #include @@ -31,43 +32,15 @@ enum { AQT1000_IRQ_HPH_PA_CNPR_COMPLETE, AQT1000_CDC_HPHL_SURGE, AQT1000_CDC_HPHR_SURGE, - AQT1000_PLL_LOCK_LOSS, - AQT1000_FLL_LOCK_LOSS, - AQT1000_DSD_INT, AQT1000_NUM_IRQS, }; -/** - * struct aqt_irq - AQT IRQ resource structure - * @irq_lock: lock used by irq_chip functions. - * @nested_irq_lock: lock used while handling nested interrupts. - * @irq: interrupt number. - * @irq_masks_cur: current mask value to be written to mask registers. - * @irq_masks_cache: cached mask value. - * @num_irqs: number of supported interrupts. - * @num_irq_regs: number of irq registers. - * @parent: parent pointer. - * @dev: device pointer. - * @domain: irq domain pointer. - * - * Contains required members used in wsa irq driver. - */ - -struct aqt1000_irq { - struct mutex irq_lock; - struct mutex nested_irq_lock; - unsigned int irq; - u8 irq_masks_cur; - u8 irq_masks_cache; - bool irq_level_high[8]; - int num_irqs; - int num_irq_regs; - void *parent; - struct device *dev; - struct irq_domain *domain; -}; - -int aqt_irq_init(void); -void aqt_irq_exit(void); +int aqt_request_irq(struct aqt1000 *aqt, int irq, const char *name, + irq_handler_t handler, void *data); +void aqt_free_irq(struct aqt1000 *aqt, int irq, void *data); +int aqt_irq_init(struct aqt1000 *aqt); +int aqt_irq_exit(struct aqt1000 *aqt); +void aqt_enable_irq(struct aqt1000 *aqt, int irq); +void aqt_disable_irq(struct aqt1000 *aqt, int irq); #endif /* __AQT1000_IRQ_H_ */ -- GitLab From 08d48d49ebe75db6ba16553aef7a5bbecc26edc1 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Fri, 22 Dec 2017 15:44:52 +0800 Subject: [PATCH 0157/1645] ASoC: AQT1000: add codec entry for AQT1000 codec Add codec entry for AQT1000 codec to support ADIE calibration. Add new hwdep node AQT1000_CODEC_HWDEP_NODE to store ANC/MBHC calibration data. Change-Id: I8b5ff9a2cfe2a0a8ac593b63b20b28697dc975bf Signed-off-by: Meng Wang --- asoc/codecs/aqt1000/aqt1000.c | 79 ++++++++++++++++++++++++++++++- asoc/codecs/aqt1000/aqt1000.h | 4 ++ include/uapi/sound/msmcal-hwdep.h | 1 + 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/aqt1000/aqt1000.c b/asoc/codecs/aqt1000/aqt1000.c index aff8976e84f3..b1af218d8379 100644 --- a/asoc/codecs/aqt1000/aqt1000.c +++ b/asoc/codecs/aqt1000/aqt1000.c @@ -39,13 +39,14 @@ #include "../wcdcal-hwdep.h" #include "aqt1000-internal.h" -#define AQT1000_CODEC_HWDEP_NODE 1001 #define AQT1000_TX_UNMUTE_DELAY_MS 40 #define TX_HPF_CUT_OFF_FREQ_MASK 0x60 #define CF_MIN_3DB_4HZ 0x0 #define CF_MIN_3DB_75HZ 0x1 #define CF_MIN_3DB_150HZ 0x2 +#define AQT_VERSION_ENTRY_SIZE 17 + static struct interp_sample_rate sr_val_tbl[] = { {8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5}, {192000, 0x6}, {384000, 0x7}, {44100, 0x9}, {88200, 0xA}, @@ -3024,6 +3025,82 @@ static int aqt_set_micbias(struct aqt1000 *aqt, return 0; } +static ssize_t aqt_codec_version_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, size_t count, + loff_t pos) +{ + char buffer[AQT_VERSION_ENTRY_SIZE]; + int len = 0; + + len = snprintf(buffer, sizeof(buffer), "AQT1000_1_0\n"); + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops aqt_codec_info_ops = { + .read = aqt_codec_version_read, +}; + +/* + * aqt_codec_info_create_codec_entry - creates aqt1000 module + * @codec_root: The parent directory + * @codec: Codec instance + * + * Creates aqt1000 module and version entry under the given + * parent directory. + * + * Return: 0 on success or negative error code on failure. + */ +int aqt_codec_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + struct snd_info_entry *version_entry; + struct aqt1000 *aqt; + struct snd_soc_card *card; + + if (!codec_root || !codec) + return -EINVAL; + + aqt = snd_soc_codec_get_drvdata(codec); + if (!aqt) { + dev_dbg(codec->dev, "%s: aqt is NULL\n", __func__); + return _EINVAL; + } + card = codec->component.card; + aqt->entry = snd_info_create_subdir(codec_root->module, + "aqt1000", codec_root); + if (!aqt->entry) { + dev_dbg(codec->dev, "%s: failed to create aqt1000 entry\n", + __func__); + return -ENOMEM; + } + + version_entry = snd_info_create_card_entry(card->snd_card, + "version", + aqt->entry); + if (!version_entry) { + dev_dbg(codec->dev, "%s: failed to create aqt1000 version entry\n", + __func__); + return -ENOMEM; + } + + version_entry->private_data = aqt; + version_entry->size = AQT_VERSION_ENTRY_SIZE; + version_entry->content = SNDRV_INFO_CONTENT_DATA; + version_entry->c.ops = &aqt_codec_info_ops; + + if (snd_info_register(version_entry) < 0) { + snd_info_free_entry(version_entry); + return -ENOMEM; + } + aqt->version_entry = version_entry; + + return 0; +} +EXPORT_SYMBOL(aqt_codec_info_create_codec_entry); + static const struct aqt_reg_mask_val aqt_codec_reg_init[] = { {AQT1000_CHIP_CFG0_CLK_CFG_MCLK, 0x04, 0x00}, {AQT1000_CHIP_CFG0_EFUSE_CTL, 0x01, 0x01}, diff --git a/asoc/codecs/aqt1000/aqt1000.h b/asoc/codecs/aqt1000/aqt1000.h index 4267e6f552aa..7b870db7a492 100644 --- a/asoc/codecs/aqt1000/aqt1000.h +++ b/asoc/codecs/aqt1000/aqt1000.h @@ -220,6 +220,10 @@ struct aqt1000 { struct irq_domain *virq; int irq; int irq_base; + + /* Entry for version info */ + struct snd_info_entry *entry; + struct snd_info_entry *version_entry; }; #endif /* AQT1000_H */ diff --git a/include/uapi/sound/msmcal-hwdep.h b/include/uapi/sound/msmcal-hwdep.h index 49f15de682fc..2f6d37ad0a10 100644 --- a/include/uapi/sound/msmcal-hwdep.h +++ b/include/uapi/sound/msmcal-hwdep.h @@ -2,6 +2,7 @@ #define _CALIB_HWDEP_H #define WCD9XXX_CODEC_HWDEP_NODE 1000 +#define AQT1000_CODEC_HWDEP_NODE 1001 enum wcd_cal_type { WCD9XXX_MIN_CAL, WCD9XXX_ANC_CAL = WCD9XXX_MIN_CAL, -- GitLab From ac5bb48a839a12073ac0e74d75576ee98e995a89 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 8 Feb 2018 09:04:42 +0800 Subject: [PATCH 0158/1645] SoC: msm: add machine driver for SDM855 Add machine driver for SDM855 with stub codec. Change-Id: I3203250f838147b626ad3edfb3edbdd9894022f7 Signed-off-by: Meng Wang --- asoc/sdm855.c | 1174 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1174 insertions(+) create mode 100644 asoc/sdm855.c diff --git a/asoc/sdm855.c b/asoc/sdm855.c new file mode 100644 index 000000000000..0acd7b7bf7f4 --- /dev/null +++ b/asoc/sdm855.c @@ -0,0 +1,1174 @@ +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "device_event.h" +#include "msm-pcm-routing-v2.h" +#include "codecs/wsa881x.h" + +#define DRV_NAME "sdm855-asoc-snd" + +#define __CHIPSET__ "SDM855 " +#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) + +#define DEV_NAME_STR_LEN 32 + +#define SAMPLING_RATE_8KHZ 8000 +#define SAMPLING_RATE_11P025KHZ 11025 +#define SAMPLING_RATE_16KHZ 16000 +#define SAMPLING_RATE_22P05KHZ 22050 +#define SAMPLING_RATE_32KHZ 32000 +#define SAMPLING_RATE_44P1KHZ 44100 +#define SAMPLING_RATE_48KHZ 48000 +#define SAMPLING_RATE_88P2KHZ 88200 +#define SAMPLING_RATE_96KHZ 96000 +#define SAMPLING_RATE_176P4KHZ 176400 +#define SAMPLING_RATE_192KHZ 192000 +#define SAMPLING_RATE_352P8KHZ 352800 +#define SAMPLING_RATE_384KHZ 384000 + +struct msm_wsa881x_dev_info { + struct device_node *of_node; + u32 index; +}; + +struct msm_asoc_mach_data { + u32 mclk_freq; + struct snd_info_entry *codec_root; +}; + +struct dev_config { + u32 sample_rate; + u32 bit_format; + u32 channels; +}; + +static struct platform_device *spdev; + +static struct snd_soc_aux_dev *msm_aux_dev; +static struct snd_soc_codec_conf *msm_codec_conf; + +enum { + SLIM_RX_0 = 0, + SLIM_RX_MAX, +}; + +enum { + SLIM_TX_0 = 0, + SLIM_TX_MAX, +}; + +/* Default configuration of slimbus channels */ +static struct dev_config slim_rx_cfg[] = { + [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config slim_tx_cfg[] = { + [SLIM_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static const char *const slim_rx_ch_text[] = {"One", "Two"}; +static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; + +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text); + +static int slim_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 10; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int slim_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + sample_rate = SAMPLING_RATE_384KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int slim_get_bit_format_val(int bit_format) +{ + int val = 0; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + val = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + val = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + val = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + val = 0; + break; + } + return val; +} + +static int slim_get_bit_format(int val) +{ + int bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + + switch (val) { + case 0: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + bit_fmt = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + bit_fmt = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + bit_fmt = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return bit_fmt; +} + +static int slim_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int port_id = 0; + + if (strnstr(kcontrol->id.name, "SLIM_0_RX", sizeof("SLIM_0_RX"))) { + port_id = SLIM_RX_0; + } else if (strnstr(kcontrol->id.name, + "SLIM_0_TX", sizeof("SLIM_0_TX"))) { + port_id = SLIM_TX_0; + } else { + pr_err("%s: unsupported channel: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + + return port_id; +} + +static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_sample_rate_val(slim_rx_cfg[ch_num].sample_rate); + + pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].sample_rate = + slim_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_sample_rate_val(slim_tx_cfg[ch_num].sample_rate); + + pr_debug("%s: slim[%d]_tx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate = 0; + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + sample_rate = slim_get_sample_rate(ucontrol->value.enumerated.item[0]); + if (sample_rate == SAMPLING_RATE_44P1KHZ) { + pr_err("%s: Unsupported sample rate %d: for Tx path\n", + __func__, sample_rate); + return -EINVAL; + } + slim_tx_cfg[ch_num].sample_rate = sample_rate; + + pr_debug("%s: slim[%d]_tx_sample_rate = %d, value = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_bit_format_val(slim_rx_cfg[ch_num].bit_format); + + pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_rx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].bit_format = + slim_get_bit_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_rx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_bit_format_val(slim_tx_cfg[ch_num].bit_format); + + pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_tx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_tx_cfg[ch_num].bit_format = + slim_get_bit_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_tx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].channels); + ucontrol->value.enumerated.item[0] = slim_rx_cfg[ch_num].channels - 1; + + return 0; +} + +static int slim_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].channels); + + return 1; +} + +static int slim_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].channels); + ucontrol->value.enumerated.item[0] = slim_tx_cfg[ch_num].channels - 1; + + return 0; +} + +static int slim_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_tx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].channels); + + return 1; +} + +static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, + slim_rx_ch_get, slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs, + slim_tx_ch_get, slim_tx_ch_put), + SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format, + slim_tx_bit_format_get, slim_tx_bit_format_put), + SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate, + slim_tx_sample_rate_get, slim_tx_sample_rate_put), +}; + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, + int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, + unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +static int msm_slim_get_ch_from_beid(int32_t be_id) +{ + int ch_id = 0; + + switch (be_id) { + case MSM_BACKEND_DAI_SLIMBUS_0_RX: + ch_id = SLIM_RX_0; + break; + case MSM_BACKEND_DAI_SLIMBUS_0_TX: + ch_id = SLIM_TX_0; + break; + default: + ch_id = SLIM_RX_0; + break; + } + + return ch_id; +} + +static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int rc = 0; + int idx; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->id) { + case MSM_BACKEND_DAI_SLIMBUS_0_RX: + idx = msm_slim_get_ch_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[idx].bit_format); + rate->min = rate->max = slim_rx_cfg[idx].sample_rate; + channels->min = channels->max = slim_rx_cfg[idx].channels; + break; + case MSM_BACKEND_DAI_SLIMBUS_0_TX: + idx = msm_slim_get_ch_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[idx].bit_format); + rate->min = rate->max = slim_tx_cfg[idx].sample_rate; + channels->min = channels->max = slim_tx_cfg[idx].channels; + break; + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + + return rc; +} + +static int msm_populate_dai_link_component_of_node( + struct snd_soc_card *card) +{ + int i, index, ret = 0; + struct device *cdev = card->dev; + struct snd_soc_dai_link *dai_link = card->dai_link; + struct device_node *np; + + if (!cdev) { + pr_err("%s: Sound card device memory NULL\n", __func__); + return -ENODEV; + } + + for (i = 0; i < card->num_links; i++) { + if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) + continue; + + /* populate platform_of_node for snd card dai links */ + if (dai_link[i].platform_name && + !dai_link[i].platform_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-platform-names", + dai_link[i].platform_name); + if (index < 0) { + pr_err("%s: No match found for platform name: %s\n", + __func__, dai_link[i].platform_name); + ret = index; + goto err; + } + np = of_parse_phandle(cdev->of_node, "asoc-platform", + index); + if (!np) { + pr_err("%s: retrieving phandle for platform %s, index %d failed\n", + __func__, dai_link[i].platform_name, + index); + ret = -ENODEV; + goto err; + } + dai_link[i].platform_of_node = np; + dai_link[i].platform_name = NULL; + } + + /* populate cpu_of_node for snd card dai links */ + if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-cpu-names", + dai_link[i].cpu_dai_name); + if (index >= 0) { + np = of_parse_phandle(cdev->of_node, "asoc-cpu", + index); + if (!np) { + pr_err("%s: retrieving phandle for cpu dai %s failed\n", + __func__, + dai_link[i].cpu_dai_name); + ret = -ENODEV; + goto err; + } + dai_link[i].cpu_of_node = np; + dai_link[i].cpu_dai_name = NULL; + } + } + + /* populate codec_of_node for snd card dai links */ + if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-codec-names", + dai_link[i].codec_name); + if (index < 0) + continue; + np = of_parse_phandle(cdev->of_node, "asoc-codec", + index); + if (!np) { + pr_err("%s: retrieving phandle for codec %s failed\n", + __func__, dai_link[i].codec_name); + ret = -ENODEV; + goto err; + } + dai_link[i].codec_of_node = np; + dai_link[i].codec_name = NULL; + } + } + +err: + return ret; +} + +static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + struct snd_soc_codec *codec = rtd->codec; + + ret = snd_soc_add_codec_controls(codec, msm_snd_controls, + ARRAY_SIZE(msm_snd_controls)); + if (ret < 0) { + dev_err(codec->dev, + "%s: add_codec_controls failed, err = %d\n", + __func__, ret); + return ret; + } + + return 0; +} + +static int msm_snd_stub_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + + int ret = 0; + unsigned int rx_ch[] = {144, 145, 146, 147, 148, 149, 150, + 151}; + unsigned int tx_ch[] = {128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143}; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + slim_rx_cfg[SLIM_RX_0].channels, + rx_ch); + if (ret < 0) + pr_err("%s: RX failed to set cpu chan map error %d\n", + __func__, ret); + } else { + ret = snd_soc_dai_set_channel_map(cpu_dai, + slim_tx_cfg[SLIM_TX_0].channels, + tx_ch, 0, 0); + if (ret < 0) + pr_err("%s: TX failed to set cpu chan map error %d\n", + __func__, ret); + } + + return ret; +} + +static struct snd_soc_ops msm_stub_be_ops = { + .hw_params = msm_snd_stub_hw_params, +}; + +static struct snd_soc_dai_link msm_stub_fe_dai_links[] = { + + /* FrontEnd DAI Links */ + { + .name = "MSMSTUB Media1", + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, +}; + +static struct snd_soc_dai_link msm_stub_be_dai_links[] = { + + /* Backend DAI Links */ + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_stub_init, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, /* dai link has playback support */ + .ignore_suspend = 1, + .ops = &msm_stub_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_stub_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_stub_dai_links[ + ARRAY_SIZE(msm_stub_fe_dai_links) + + ARRAY_SIZE(msm_stub_be_dai_links)]; + +struct snd_soc_card snd_soc_card_stub_msm = { + .name = "sdm855-stub-snd-card", +}; + +static const struct of_device_id sdm855_asoc_machine_of_match[] = { + { .compatible = "qcom,sdm855-asoc-snd-stub", + .data = "stub_codec"}, + {}, +}; + +static int sdm855_notifier_service_cb(struct notifier_block *this, + unsigned long opcode, void *ptr) +{ + return NOTIFY_OK; +} + +static struct notifier_block service_nb = { + .notifier_call = sdm855_notifier_service_cb, + .priority = -INT_MAX, +}; + +static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) +{ + struct snd_soc_card *card = NULL; + struct snd_soc_dai_link *dailink; + int len_1, len_2; + int total_links; + const struct of_device_id *match; + + match = of_match_node(sdm855_asoc_machine_of_match, dev->of_node); + if (!match) { + dev_err(dev, "%s: No DT match found for sound card\n", + __func__); + return NULL; + } + + if (!strcmp(match->data, "stub_codec")) { + card = &snd_soc_card_stub_msm; + len_1 = ARRAY_SIZE(msm_stub_fe_dai_links); + len_2 = len_1 + ARRAY_SIZE(msm_stub_be_dai_links); + + memcpy(msm_stub_dai_links, + msm_stub_fe_dai_links, + sizeof(msm_stub_fe_dai_links)); + memcpy(msm_stub_dai_links + len_1, + msm_stub_be_dai_links, + sizeof(msm_stub_be_dai_links)); + + dailink = msm_stub_dai_links; + total_links = len_2; + } + + if (card) { + card->dai_link = dailink; + card->num_links = total_links; + } + + return card; +} + +static int msm_wsa881x_init(struct snd_soc_component *component) +{ + u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106}; + u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107}; + unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; + unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + struct msm_asoc_mach_data *pdata; + struct snd_soc_dapm_context *dapm; + int ret = 0; + + if (!codec) { + pr_err("%s codec is NULL\n", __func__); + return -EINVAL; + } + + dapm = snd_soc_codec_get_dapm(codec); + + if (!strcmp(component->name_prefix, "SpkrLeft")) { + dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n", + __func__, codec->component.name); + wsa881x_set_channel_map(codec, &spkleft_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0]); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); + } + } else if (!strcmp(component->name_prefix, "SpkrRight")) { + dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n", + __func__, codec->component.name); + wsa881x_set_channel_map(codec, &spkright_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0]); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); + } + } else { + dev_err(codec->dev, "%s: wrong codec name %s\n", __func__, + codec->component.name); + ret = -EINVAL; + goto err; + } + pdata = snd_soc_card_get_drvdata(component->card); + if (pdata && pdata->codec_root) + wsa881x_codec_info_create_codec_entry(pdata->codec_root, + codec); + +err: + return ret; +} + +static int msm_init_wsa_dev(struct platform_device *pdev, + struct snd_soc_card *card) +{ + struct device_node *wsa_of_node; + u32 wsa_max_devs; + u32 wsa_dev_cnt; + int i; + struct msm_wsa881x_dev_info *wsa881x_dev_info; + const char *wsa_auxdev_name_prefix[1]; + char *dev_name_str = NULL; + int found = 0; + int ret = 0; + + /* Get maximum WSA device count for this platform */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,wsa-max-devs", &wsa_max_devs); + if (ret) { + dev_info(&pdev->dev, + "%s: wsa-max-devs property missing in DT %s, ret = %d\n", + __func__, pdev->dev.of_node->full_name, ret); + card->num_aux_devs = 0; + return 0; + } + if (wsa_max_devs == 0) { + dev_warn(&pdev->dev, + "%s: Max WSA devices is 0 for this target?\n", + __func__); + card->num_aux_devs = 0; + return 0; + } + + /* Get count of WSA device phandles for this platform */ + wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node, + "qcom,wsa-devs", NULL); + if (wsa_dev_cnt == -ENOENT) { + dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n", + __func__); + goto err; + } else if (wsa_dev_cnt <= 0) { + dev_err(&pdev->dev, + "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n", + __func__, wsa_dev_cnt); + ret = -EINVAL; + goto err; + } + + /* + * Expect total phandles count to be NOT less than maximum possible + * WSA count. However, if it is less, then assign same value to + * max count as well. + */ + if (wsa_dev_cnt < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n", + __func__, wsa_max_devs, wsa_dev_cnt); + wsa_max_devs = wsa_dev_cnt; + } + + /* Make sure prefix string passed for each WSA device */ + ret = of_property_count_strings(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix"); + if (ret != wsa_dev_cnt) { + dev_err(&pdev->dev, + "%s: expecting %d wsa prefix. Defined only %d in DT\n", + __func__, wsa_dev_cnt, ret); + ret = -EINVAL; + goto err; + } + + /* + * Alloc mem to store phandle and index info of WSA device, if already + * registered with ALSA core + */ + wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs, + sizeof(struct msm_wsa881x_dev_info), + GFP_KERNEL); + if (!wsa881x_dev_info) { + ret = -ENOMEM; + goto err; + } + + /* + * search and check whether all WSA devices are already + * registered with ALSA core or not. If found a node, store + * the node and the index in a local array of struct for later + * use. + */ + for (i = 0; i < wsa_dev_cnt; i++) { + wsa_of_node = of_parse_phandle(pdev->dev.of_node, + "qcom,wsa-devs", i); + if (unlikely(!wsa_of_node)) { + /* we should not be here */ + dev_err(&pdev->dev, + "%s: wsa dev node is not present\n", + __func__); + ret = -EINVAL; + goto err_free_dev_info; + } + if (soc_find_component(wsa_of_node, NULL)) { + /* WSA device registered with ALSA core */ + wsa881x_dev_info[found].of_node = wsa_of_node; + wsa881x_dev_info[found].index = i; + found++; + if (found == wsa_max_devs) + break; + } + } + + if (found < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: failed to find %d components. Found only %d\n", + __func__, wsa_max_devs, found); + return -EPROBE_DEFER; + } + dev_info(&pdev->dev, + "%s: found %d wsa881x devices registered with ALSA core\n", + __func__, found); + + card->num_aux_devs = wsa_max_devs; + card->num_configs = wsa_max_devs; + + /* Alloc array of AUX devs struct */ + msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_aux_dev), + GFP_KERNEL); + if (!msm_aux_dev) { + ret = -ENOMEM; + goto err_free_dev_info; + } + + /* Alloc array of codec conf struct */ + msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_codec_conf), + GFP_KERNEL); + if (!msm_codec_conf) { + ret = -ENOMEM; + goto err_free_aux_dev; + } + + for (i = 0; i < card->num_aux_devs; i++) { + dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN, + GFP_KERNEL); + if (!dev_name_str) { + ret = -ENOMEM; + goto err_free_cdc_conf; + } + + ret = of_property_read_string_index(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix", + wsa881x_dev_info[i].index, + wsa_auxdev_name_prefix); + if (ret) { + dev_err(&pdev->dev, + "%s: failed to read wsa aux dev prefix, ret = %d\n", + __func__, ret); + ret = -EINVAL; + goto err_free_dev_name_str; + } + + snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i); + msm_aux_dev[i].name = dev_name_str; + msm_aux_dev[i].codec_name = NULL; + msm_aux_dev[i].codec_of_node = + wsa881x_dev_info[i].of_node; + msm_aux_dev[i].init = msm_wsa881x_init; + msm_codec_conf[i].dev_name = NULL; + msm_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0]; + msm_codec_conf[i].of_node = + wsa881x_dev_info[i].of_node; + } + card->codec_conf = msm_codec_conf; + card->aux_dev = msm_aux_dev; + + return 0; + +err_free_dev_name_str: + devm_kfree(&pdev->dev, dev_name_str); +err_free_cdc_conf: + devm_kfree(&pdev->dev, msm_codec_conf); +err_free_aux_dev: + devm_kfree(&pdev->dev, msm_aux_dev); +err_free_dev_info: + devm_kfree(&pdev->dev, wsa881x_dev_info); +err: + return ret; +} + +static int msm_asoc_machine_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card; + struct msm_asoc_mach_data *pdata; + const struct of_device_id *match; + int ret; + + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, "No platform supplied from device tree\n"); + return -EINVAL; + } + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct msm_asoc_mach_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + card = populate_snd_card_dailinks(&pdev->dev); + if (!card) { + dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); + ret = -EINVAL; + goto err; + } + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, pdata); + + ret = snd_soc_of_parse_card_name(card, "qcom,model"); + if (ret) { + dev_err(&pdev->dev, "parse card name failed, err:%d\n", + ret); + goto err; + } + + match = of_match_node(sdm855_asoc_machine_of_match, + pdev->dev.of_node); + if (!match) { + dev_err(&pdev->dev, "%s: no matched codec is found.\n", + __func__); + goto err; + } + + ret = msm_populate_dai_link_component_of_node(card); + if (ret) { + ret = -EPROBE_DEFER; + goto err; + } + ret = msm_init_wsa_dev(pdev, card); + if (ret) + goto err; + + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret) { + dev_err(&pdev->dev, "%s: snd_soc_register_card failed (%d)\n", + __func__, ret); + goto err; + } + dev_info(&pdev->dev, "%s: Sound card %s registered\n", + __func__, card->name); + spdev = pdev; + + ret = audio_notifier_register("sdm855", AUDIO_NOTIFIER_ADSP_DOMAIN, + &service_nb); + if (ret < 0) + pr_err("%s: Audio notifier register failed ret = %d\n", + __func__, ret); + + return 0; +err: + devm_kfree(&pdev->dev, pdata); + return ret; +} + +static int msm_asoc_machine_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + audio_notifier_deregister("sdm855"); + return 0; +} + +static struct platform_driver sdm855_asoc_machine_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = sdm855_asoc_machine_of_match, + }, + .probe = msm_asoc_machine_probe, + .remove = msm_asoc_machine_remove, +}; +module_platform_driver(sdm855_asoc_machine_driver); + +MODULE_DESCRIPTION("ALSA SoC msm"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, sdm855_asoc_machine_of_match); -- GitLab From 85b6208522c6a9ecbba4f571b33056a31f62eca4 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Sun, 4 Feb 2018 09:59:16 +0800 Subject: [PATCH 0159/1645] ASoC: disable source tracking get functionality for sdm855 Disable source tracking get functionality for sdm855 till feature is completely enabled Change-Id: Id644fa46d95bd1091502b1c5ae4cce3bb64d633e Signed-off-by: Meng Wang --- asoc/msm-pcm-routing-v2.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 1ff7c41222df..c7259e292bb6 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -11768,24 +11768,7 @@ static int msm_source_tracking_info(struct snd_kcontrol *kcontrol, static int msm_voice_source_tracking_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - int ret = 0; - struct source_tracking_param sourceTrackingData; - - memset(&sourceTrackingData, 0, sizeof(struct source_tracking_param)); - - ret = voc_get_source_tracking(&sourceTrackingData); - if (ret) { - pr_err("%s: Error getting Source Tracking Params, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - memcpy(ucontrol->value.bytes.data, (void *)&sourceTrackingData, - sizeof(struct source_tracking_param)); - -done: - return ret; + return -EINVAL; } static int msm_audio_get_copp_idx_from_port_id(int port_id, int session_type, -- GitLab From 5fddb8d5321f02eafd7566724feb12ddcfb3d5f5 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 23 Jan 2018 16:56:56 +0800 Subject: [PATCH 0160/1645] ASoC: enable audio modules for msmnile Add audio config files and Change Android.mk, Makefile and Kbuild to enable audio modules for msmnile target. Change-Id: If6acabe2cd2074d688b810de3f48e6c60dfe9d22 Signed-off-by: Meng Wang Signed-off-by: Vidyakumar Athota --- Android.mk | 2 +- Makefile | 8 +++++++ asoc/Android.mk | 7 +++++- asoc/Kbuild | 23 ++++++++++++++----- asoc/codecs/Android.mk | 6 ++++- asoc/codecs/Kbuild | 9 ++++++-- config/sdm855auto.conf | 37 +++++++++++++++++++++++++++++++ config/sdm855autoconf.h | 49 +++++++++++++++++++++++++++++++++++++++++ dsp/Android.mk | 6 ++++- dsp/Kbuild | 7 +++++- dsp/codecs/Android.mk | 6 ++++- dsp/codecs/Kbuild | 9 ++++++-- ipc/Android.mk | 6 ++++- ipc/Kbuild | 12 ++++++++-- soc/Android.mk | 6 ++++- soc/Kbuild | 7 +++++- 16 files changed, 180 insertions(+), 20 deletions(-) create mode 100644 config/sdm855auto.conf create mode 100644 config/sdm855autoconf.h diff --git a/Android.mk b/Android.mk index cda991e9889f..34c922b28ed7 100644 --- a/Android.mk +++ b/Android.mk @@ -3,7 +3,7 @@ MY_LOCAL_PATH := $(call my-dir) UAPI_OUT := $(OUT)/obj/vendor/qcom/opensource/audio-kernel/include -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true) $(shell mkdir -p $(UAPI_OUT)/linux;) $(shell mkdir -p $(UAPI_OUT)/sound;) $(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers) diff --git a/Makefile b/Makefile index 2848799ae3a6..4e123b6de43b 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,10 @@ ifeq ($(CONFIG_ARCH_SDXPOORWILLS), y) include $(srctree)/techpack/audio/config/sdxpoorwillsauto.conf export endif +ifeq ($(CONFIG_ARCH_SDM855), y) +include $(srctree)/techpack/audio/config/sdm855auto.conf +export +endif # Use USERINCLUDE when you must reference the UAPI directories only. USERINCLUDE += \ @@ -34,6 +38,10 @@ ifeq ($(CONFIG_ARCH_SDXPOORWILLS), y) LINUXINCLUDE += \ -include $(srctree)/techpack/audio/config/sdxpoorwillsautoconf.h endif +ifeq ($(CONFIG_ARCH_SDM855), y) +LINUXINCLUDE += \ + -include $(srctree)/techpack/audio/config/sdm855autoconf.h +endif obj-y += asoc/ obj-y += dsp/ diff --git a/asoc/Android.mk b/asoc/Android.mk index 5023a09828a3..6154917aafb9 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -13,9 +13,14 @@ TARGET := sdm670 AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif +ifeq ($(call is-board-platform,msmnile),true) +TARGET := msmnile +AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/Kbuild b/asoc/Kbuild index 91ebf8a0e0ad..4ebce00485b1 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -30,6 +30,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM855), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif endif # As per target team, build is done as follows: @@ -80,6 +85,11 @@ ifdef CONFIG_SND_SOC_MACHINE_SDM845 MACHINE_OBJS += sdm845.o endif +# for SDM855 sound card driver +ifdef CONFIG_SND_SOC_SDM855 + MACHINE_OBJS += sdm855.o +endif + ifdef CONFIG_SND_SOC_CPE CPE_LSM_OBJS += msm-cpe-lsm.o endif @@ -152,11 +162,11 @@ EXTRA_CFLAGS += -Wheader-guard endif ifeq ($(KERNEL_BUILD), 0) -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers endif ifeq ($(KERNEL_BUILD), 1) obj-y += codecs/ @@ -168,6 +178,9 @@ platform_dlkm-y := $(PLATFORM_OBJS) obj-$(CONFIG_SND_SOC_MACHINE_SDM845) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) +obj-$(CONFIG_SND_SOC_SDM855) += machine_dlkm.o +machine_dlkm-y := $(MACHINE_OBJS) + obj-$(CONFIG_SND_SOC_EXT_CODEC) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index 037774c2252e..152f61705ae5 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -11,9 +11,13 @@ ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif +ifeq ($(call is-board-platform,msmnile),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 005a68cd4a9e..015164eb21e6 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -29,6 +29,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM855), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif endif # As per target team, build is done as follows: @@ -156,8 +161,8 @@ endif ifeq ($(KERNEL_BUILD), 0) -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers endif ifeq ($(KERNEL_BUILD), 1) diff --git a/config/sdm855auto.conf b/config/sdm855auto.conf new file mode 100644 index 000000000000..5257790c6173 --- /dev/null +++ b/config/sdm855auto.conf @@ -0,0 +1,37 @@ +CONFIG_PINCTRL_WCD=m +CONFIG_AUDIO_EXT_CLK=m +CONFIG_SND_SOC_WCD9XXX_V2=m +CONFIG_SND_SOC_WCD_MBHC=m +CONFIG_SND_SOC_WSA881X=m +CONFIG_SND_SOC_WCD9360=m +CONFIG_SND_SOC_WCD_DSP_MGR=m +CONFIG_SND_SOC_WCD_SPI=m +CONFIG_SND_SOC_WCD_CPE=m +CONFIG_SOUNDWIRE_WCD_CTRL=m +CONFIG_WCD9XXX_CODEC_CORE=m +CONFIG_MSM_CDC_PINCTRL=m +CONFIG_MSM_QDSP6V2_CODECS=m +CONFIG_MSM_ULTRASOUND=m +CONFIG_MSM_QDSP6_APRV2_RPMSG=m +CONFIG_MSM_ADSP_LOADER=m +CONFIG_REGMAP_SWR=m +CONFIG_MSM_QDSP6_SSR=m +CONFIG_MSM_QDSP6_PDR=m +CONFIG_MSM_QDSP6_NOTIFIER=m +CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +CONFIG_SND_SOC_SDM855=m +CONFIG_MSM_GLINK_SPI_XPRT=m +CONFIG_WCD_DSP_GLINK=m +CONFIG_SOUNDWIRE=m +CONFIG_SND_SOC_QDSP6V2=m +CONFIG_SND_SOC_WCD_MBHC_ADC=m +CONFIG_QTI_PP=m +CONFIG_SND_HWDEP=m +CONFIG_DTS_EAGLE=m +CONFIG_DOLBY_DS2=m +CONFIG_DOLBY_LICENSE=m +CONFIG_DTS_SRS_TM=m +CONFIG_SND_SOC_MSM_STUB=m +CONFIG_MSM_AVTIMER=m +CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m diff --git a/config/sdm855autoconf.h b/config/sdm855autoconf.h new file mode 100644 index 000000000000..593934adfee0 --- /dev/null +++ b/config/sdm855autoconf.h @@ -0,0 +1,49 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define CONFIG_PINCTRL_WCD 1 +#define CONFIG_AUDIO_EXT_CLK 1 +#define CONFIG_SND_SOC_WCD9XXX_V2 1 +#define CONFIG_SND_SOC_WCD_MBHC 1 +#define CONFIG_SND_SOC_WSA881X 1 +#define CONFIG_SND_SOC_WCD9360 1 +#define CONFIG_SND_SOC_WCD_DSP_MGR 1 +#define CONFIG_SND_SOC_WCD_SPI 1 +#define CONFIG_SND_SOC_WCD_CPE 1 +#define CONFIG_WCD9XXX_CODEC_CORE 1 +#define CONFIG_MSM_CDC_PINCTRL 1 +#define CONFIG_MSM_QDSP6V2_CODECS 1 +#define CONFIG_MSM_ULTRASOUND 1 +#define CONFIG_MSM_QDSP6_APRV2_RPMSG 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_MSM_ADSP_LOADER 1 +#define CONFIG_REGMAP_SWR 1 +#define CONFIG_MSM_QDSP6_SSR 1 +#define CONFIG_MSM_QDSP6_PDR 1 +#define CONFIG_MSM_QDSP6_NOTIFIER 1 +#define CONFIG_SND_SOC_MSM_HOSTLESS_PCM 1 +#define CONFIG_SND_SOC_SDM855 1 +#define CONFIG_MSM_GLINK_SPI_XPRT 1 +#define CONFIG_WCD_DSP_GLINK 1 +#define CONFIG_SOUNDWIRE 1 +#define CONFIG_SOUNDWIRE_WCD_CTRL 1 +#define CONFIG_SND_SOC_WCD_MBHC_ADC 1 +#define CONFIG_SND_SOC_QDSP6V2 1 +#define CONFIG_QTI_PP 1 +#define CONFIG_SND_HWDEP 1 +#define CONFIG_DTS_EAGLE 1 +#define CONFIG_DOLBY_DS2 1 +#define CONFIG_DOLBY_LICENSE 1 +#define CONFIG_DTS_SRS_TM 1 +#define CONFIG_SND_SOC_MSM_STUB 1 +#define CONFIG_MSM_AVTIMER 1 +#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 diff --git a/dsp/Android.mk b/dsp/Android.mk index 98f865b8a96f..cad30c8c9306 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -11,9 +11,13 @@ ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif +ifeq ($(call is-board-platform,msmnile),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/Kbuild b/dsp/Kbuild index 73dcb2ae330b..2bf3b26a99cd 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -29,6 +29,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM855), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif endif @@ -141,7 +146,7 @@ CDEFINES += -DMULTI_IF_NAME=\"$(CHIP_NAME)\" endif ifeq ($(KERNEL_BUILD), 0) -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers endif ifeq ($(KERNEL_BUILD), 1) diff --git a/dsp/codecs/Android.mk b/dsp/codecs/Android.mk index 984a5139c94c..50ec167bbdd7 100644 --- a/dsp/codecs/Android.mk +++ b/dsp/codecs/Android.mk @@ -11,9 +11,13 @@ ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif +ifeq ($(call is-board-platform,msmnile),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 34d39ad06d23..0890920842d8 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -30,6 +30,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM855), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif endif # As per target team, build is done as follows: @@ -121,8 +126,8 @@ EXTRA_CFLAGS += -Wheader-guard endif ifeq ($(KERNEL_BUILD), 0) -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers endif # Module information used by KBuild framework diff --git a/ipc/Android.mk b/ipc/Android.mk index b7908dce51c3..e6ad34678180 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -11,9 +11,13 @@ ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif +ifeq ($(call is-board-platform,msmnile),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true) LOCAL_PATH := $(call my-dir) diff --git a/ipc/Kbuild b/ipc/Kbuild index 72c9ef1c25b0..1fd41f78918a 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -16,6 +16,9 @@ endif ifeq ($(CONFIG_ARCH_SDM670), y) TARGET_KERNEL_VERSION := 4.9 endif +ifeq ($(CONFIG_ARCH_SDM855), y) + TARGET_KERNEL_VERSION := 4.14 +endif KDIR := $(TOP)/kernel/msm-$(TARGET_KERNEL_VERSION) @@ -39,6 +42,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM855), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif endif # As per target team, build is done as follows: @@ -106,7 +114,7 @@ KBUILD_CPPFLAGS += $(CDEFINES) ifeq ($(KERNEL_BUILD), 0) HEADER_INSTALL_DIR := $(TOP)/kernel/msm-$(TARGET_KERNEL_VERSION)/scripts -UAPI_OUT := $(OUT)/obj/vendor/qcom/opensource/audio-kernel/include +UAPI_OUT := $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/include $(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ avtimer.h;) $(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio.h;) $(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_aac.h;) @@ -134,7 +142,7 @@ $(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT $(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ voice_params.h;) $(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ wcd-dsp-glink.h;) -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers endif diff --git a/soc/Android.mk b/soc/Android.mk index 1c256fefc796..fa2569a318a7 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -11,9 +11,13 @@ ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif +ifeq ($(call is-board-platform,msmnile),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true) LOCAL_PATH := $(call my-dir) diff --git a/soc/Kbuild b/soc/Kbuild index 29f69d578e92..263166745c2a 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -29,6 +29,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM855), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif endif # As per target team, build is done as follows: @@ -98,7 +103,7 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ KBUILD_CPPFLAGS += $(CDEFINES) ifeq ($(KERNEL_BUILD), 0) -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers endif # Currently, for versions of gcc which support it, the kernel Makefile -- GitLab From 7c53cb50105b157b9e01cabaa089b7bfe9a5fdc0 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 29 Dec 2017 02:12:47 +0530 Subject: [PATCH 0161/1645] ASoC: AQT1000: Add API for adjusting the micbias voltage on AQT1000 AQT1000 codec supports multiple micbias voltage settings. Add an API to client modules to adjust the micbias voltage based on their desire voltage requirements. Change-Id: If89b836ab60b66e9ec1000fe6d07f4b1a8484b01 Signed-off-by: Sudheer Papothi --- asoc/codecs/aqt1000/aqt1000-api.h | 28 +++++++++++ asoc/codecs/aqt1000/aqt1000.c | 77 +++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 asoc/codecs/aqt1000/aqt1000-api.h diff --git a/asoc/codecs/aqt1000/aqt1000-api.h b/asoc/codecs/aqt1000/aqt1000-api.h new file mode 100644 index 000000000000..ef2e5267fe77 --- /dev/null +++ b/asoc/codecs/aqt1000/aqt1000-api.h @@ -0,0 +1,28 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef AQT1000_API_H +#define AQT1000_API_H + +#include +#include +#include +#include + +extern int aqt_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, + int volt, int micb_num); +extern int aqt_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable); +extern int aqt_get_micb_vout_ctl_val(u32 micb_mv); +extern int aqt_micbias_control(struct snd_soc_codec *codec, int micb_num, + int req, bool is_dapm); + +#endif /* AQT1000_API_H */ diff --git a/asoc/codecs/aqt1000/aqt1000.c b/asoc/codecs/aqt1000/aqt1000.c index b1af218d8379..8ed297fe2dc8 100644 --- a/asoc/codecs/aqt1000/aqt1000.c +++ b/asoc/codecs/aqt1000/aqt1000.c @@ -35,6 +35,7 @@ #include #include "aqt1000-registers.h" #include "aqt1000.h" +#include "aqt1000-api.h" #include "aqt1000-routing.h" #include "../wcdcal-hwdep.h" #include "aqt1000-internal.h" @@ -46,6 +47,7 @@ #define CF_MIN_3DB_150HZ 0x2 #define AQT_VERSION_ENTRY_SIZE 17 +#define AQT_VOUT_CTL_TO_MICB(x) (1000 + x *50) static struct interp_sample_rate sr_val_tbl[] = { {8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5}, @@ -682,6 +684,81 @@ static int aqt_codec_enable_rx_bias(struct snd_soc_dapm_widget *w, return 0; } +/* + * aqt_mbhc_micb_adjust_voltage: adjust specific micbias voltage + * @codec: handle to snd_soc_codec * + * @req_volt: micbias voltage to be set + * @micb_num: micbias to be set, e.g. micbias1 or micbias2 + * + * return 0 if adjustment is success or error code in case of failure + */ +int aqt_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, + int req_volt, int micb_num) +{ + struct aqt1000 *aqt; + int cur_vout_ctl, req_vout_ctl; + int micb_reg, micb_val, micb_en; + int ret = 0; + + if (!codec) { + pr_err("%s: Invalid codec pointer\n", __func__); + return -EINVAL; + } + + if (micb_num != MIC_BIAS_1) + return -EINVAL; + else + micb_reg = AQT1000_ANA_MICB1; + + aqt = snd_soc_codec_get_drvdata(codec); + mutex_lock(&aqt->micb_lock); + + /* + * If requested micbias voltage is same as current micbias + * voltage, then just return. Otherwise, adjust voltage as + * per requested value. If micbias is already enabled, then + * to avoid slow micbias ramp-up or down enable pull-up + * momentarily, change the micbias value and then re-enable + * micbias. + */ + micb_val = snd_soc_read(codec, micb_reg); + micb_en = (micb_val & 0xC0) >> 6; + cur_vout_ctl = micb_val & 0x3F; + + req_vout_ctl = aqt_get_micb_vout_ctl_val(req_volt); + if (req_vout_ctl < 0) { + ret = -EINVAL; + goto exit; + } + if (cur_vout_ctl == req_vout_ctl) { + ret = 0; + goto exit; + } + + dev_dbg(codec->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n", + __func__, micb_num, AQT_VOUT_CTL_TO_MICB(cur_vout_ctl), + req_volt, micb_en); + + if (micb_en == 0x1) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + + snd_soc_update_bits(codec, micb_reg, 0x3F, req_vout_ctl); + + if (micb_en == 0x1) { + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + /* + * Add 2ms delay as per HW requirement after enabling + * micbias + */ + usleep_range(2000, 2100); + } +exit: + mutex_unlock(&aqt->micb_lock); + + return ret; +} +EXPORT_SYMBOL(aqt_mbhc_micb_adjust_voltage); + /* * aqt_micbias_control: enable/disable micbias * @codec: handle to snd_soc_codec * -- GitLab From 8c9bd0f7d01289d0ae8585ce03c228388581bccf Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 29 Dec 2017 02:18:43 +0530 Subject: [PATCH 0162/1645] ASoC: wcd9xxx: Add new callback for headset pull up current AQT1000 supports different headset detect pull up current source values in MBHC. Add a callback function to handle new current source values in MBHC driver. Change-Id: I060af1aff3fe7c4dfd4aa4c480542efa54c2777c Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd-mbhc-v2.c | 12 +++++++++--- asoc/codecs/wcd-mbhc-v2.h | 19 ++++++++++++++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 0b6e35562355..93ff975e8371 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1274,7 +1274,10 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) WCD_MBHC_RSC_LOCK(mbhc); /* enable HS detection */ - if (mbhc->mbhc_cb->hph_pull_up_control) + if (mbhc->mbhc_cb->hph_pull_up_control_v2) + mbhc->mbhc_cb->hph_pull_up_control_v2(codec, + HS_PULLUP_I_DEFAULT); + else if (mbhc->mbhc_cb->hph_pull_up_control) mbhc->mbhc_cb->hph_pull_up_control(codec, I_DEFAULT); else WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, 3); @@ -1291,7 +1294,10 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) mbhc->hphl_swh = 1; mbhc->gnd_swh = 1; - if (mbhc->mbhc_cb->hph_pull_up_control) + if (mbhc->mbhc_cb->hph_pull_up_control_v2) + mbhc->mbhc_cb->hph_pull_up_control_v2(codec, + HS_PULLUP_I_OFF); + else if (mbhc->mbhc_cb->hph_pull_up_control) mbhc->mbhc_cb->hph_pull_up_control(codec, I_OFF); else WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, diff --git a/asoc/codecs/wcd-mbhc-v2.h b/asoc/codecs/wcd-mbhc-v2.h index 94f096adcfbb..fc8b3f8f484b 100644 --- a/asoc/codecs/wcd-mbhc-v2.h +++ b/asoc/codecs/wcd-mbhc-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -399,6 +399,22 @@ enum mbhc_hs_pullup_iref { I_3P0_UA, }; +enum mbhc_hs_pullup_iref_v2 { + HS_PULLUP_I_DEFAULT = -1, + HS_PULLUP_I_3P0_UA = 0, + HS_PULLUP_I_2P25_UA, + HS_PULLUP_I_1P5_UA, + HS_PULLUP_I_0P75_UA, + HS_PULLUP_I_1P125_UA = 0x05, + HS_PULLUP_I_0P375_UA = 0x07, + HS_PULLUP_I_2P0_UA, + HS_PULLUP_I_1P0_UA = 0x0A, + HS_PULLUP_I_0P5_UA, + HS_PULLUP_I_0P25_UA = 0x0F, + HS_PULLUP_I_0P125_UA = 0x17, + HS_PULLUP_I_OFF, +}; + enum mbhc_moisture_rref { R_OFF, R_24_KOHM, @@ -495,6 +511,7 @@ struct wcd_mbhc_cb { void (*update_anc_state)(struct snd_soc_codec *codec, bool enable, int anc_num); bool (*is_anc_on)(struct wcd_mbhc *mbhc); + void (*hph_pull_up_control_v2)(struct snd_soc_codec *, int); }; struct wcd_mbhc_fn { -- GitLab From 40270c4787e9e54ef793eac5b5693b0c8f1621b5 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 29 Dec 2017 02:23:54 +0530 Subject: [PATCH 0163/1645] ASoC: AQT1000: Add support for MBHC hardware in AQT1000 codec AQT1000 codec supports MBHC(Multi Button Headset controller) functionality. Add driver support for MBHC hardware in AQT1000 codec. Change-Id: Ia21a5bda304d42b2aedcf54f6df92ed29dd23a41 Signed-off-by: Sudheer Papothi --- asoc/codecs/aqt1000/aqt1000-internal.h | 11 - asoc/codecs/aqt1000/aqt1000-mbhc.c | 539 +++++++++++-------------- asoc/codecs/aqt1000/aqt1000-mbhc.h | 39 +- asoc/codecs/aqt1000/aqt1000.c | 71 ++++ 4 files changed, 316 insertions(+), 344 deletions(-) diff --git a/asoc/codecs/aqt1000/aqt1000-internal.h b/asoc/codecs/aqt1000/aqt1000-internal.h index 1ce0005fc64d..19b4b57b176d 100644 --- a/asoc/codecs/aqt1000/aqt1000-internal.h +++ b/asoc/codecs/aqt1000/aqt1000-internal.h @@ -97,17 +97,6 @@ enum { ANC_MIC_AMIC3, }; -enum { - MIC_BIAS_1 = 1, -}; - -enum { - MICB_PULLUP_ENABLE, - MICB_PULLUP_DISABLE, - MICB_ENABLE, - MICB_DISABLE, -}; - enum { INTn_1_INP_SEL_ZERO = 0, INTn_1_INP_SEL_DEC0, diff --git a/asoc/codecs/aqt1000/aqt1000-mbhc.c b/asoc/codecs/aqt1000/aqt1000-mbhc.c index 2f7e470649de..24f14a46e55e 100644 --- a/asoc/codecs/aqt1000/aqt1000-mbhc.c +++ b/asoc/codecs/aqt1000/aqt1000-mbhc.c @@ -19,17 +19,16 @@ #include #include #include -#include #include #include #include #include -#include "aqt.h" -#include "aqt-mbhc.h" -#include -#include "aqt_irq.h" +#include "aqt1000.h" +#include "aqt1000-api.h" +#include "aqt1000-mbhc.h" +#include "aqt1000-registers.h" +#include "aqt1000-irq.h" #include "pdata.h" -#include "../wcd9xxx-irq.h" #include "../wcdcal-hwdep.h" #include "../wcd-mbhc-v2-api.h" @@ -53,109 +52,104 @@ static struct wcd_mbhc_register wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = { WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN", - AQT_ANA_MBHC_MECH, 0x80, 7, 0), + AQT1000_ANA_MBHC_MECH, 0x80, 7, 0), WCD_MBHC_REGISTER("WCD_MBHC_GND_DET_EN", - AQT_ANA_MBHC_MECH, 0x40, 6, 0), + AQT1000_ANA_MBHC_MECH, 0x40, 6, 0), WCD_MBHC_REGISTER("WCD_MBHC_MECH_DETECTION_TYPE", - AQT_ANA_MBHC_MECH, 0x20, 5, 0), + AQT1000_ANA_MBHC_MECH, 0x20, 5, 0), WCD_MBHC_REGISTER("WCD_MBHC_MIC_CLAMP_CTL", - AQT_MBHC_NEW_PLUG_DETECT_CTL, 0x30, 4, 0), + AQT1000_MBHC_NEW_PLUG_DETECT_CTL, 0x30, 4, 0), WCD_MBHC_REGISTER("WCD_MBHC_ELECT_DETECTION_TYPE", - AQT_ANA_MBHC_ELECT, 0x08, 3, 0), + AQT1000_ANA_MBHC_ELECT, 0x08, 3, 0), WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_CTRL", - AQT_MBHC_NEW_PLUG_DETECT_CTL, 0xC0, 6, 0), + AQT1000_MBHC_NEW_INT_MECH_DET_CURRENT, 0x1F, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL", - AQT_ANA_MBHC_MECH, 0x04, 2, 0), + AQT1000_ANA_MBHC_MECH, 0x04, 2, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PLUG_TYPE", - AQT_ANA_MBHC_MECH, 0x10, 4, 0), + AQT1000_ANA_MBHC_MECH, 0x10, 4, 0), WCD_MBHC_REGISTER("WCD_MBHC_GND_PLUG_TYPE", - AQT_ANA_MBHC_MECH, 0x08, 3, 0), + AQT1000_ANA_MBHC_MECH, 0x08, 3, 0), WCD_MBHC_REGISTER("WCD_MBHC_SW_HPH_LP_100K_TO_GND", - AQT_ANA_MBHC_MECH, 0x01, 0, 0), + AQT1000_ANA_MBHC_MECH, 0x01, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_ELECT_SCHMT_ISRC", - AQT_ANA_MBHC_ELECT, 0x06, 1, 0), + AQT1000_ANA_MBHC_ELECT, 0x06, 1, 0), WCD_MBHC_REGISTER("WCD_MBHC_FSM_EN", - AQT_ANA_MBHC_ELECT, 0x80, 7, 0), + AQT1000_ANA_MBHC_ELECT, 0x80, 7, 0), WCD_MBHC_REGISTER("WCD_MBHC_INSREM_DBNC", - AQT_MBHC_NEW_PLUG_DETECT_CTL, 0x0F, 0, 0), + AQT1000_MBHC_NEW_PLUG_DETECT_CTL, 0x0F, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_BTN_DBNC", - AQT_MBHC_NEW_CTL_1, 0x03, 0, 0), + AQT1000_MBHC_NEW_CTL_1, 0x03, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_HS_VREF", - AQT_MBHC_NEW_CTL_2, 0x03, 0, 0), + AQT1000_MBHC_NEW_CTL_2, 0x03, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT", - AQT_ANA_MBHC_RESULT_3, 0x08, 3, 0), + AQT1000_ANA_MBHC_RESULT_3, 0x08, 3, 0), WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT", - AQT_ANA_MBHC_RESULT_3, 0x20, 5, 0), + AQT1000_ANA_MBHC_RESULT_3, 0x20, 5, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT", - AQT_ANA_MBHC_RESULT_3, 0x80, 7, 0), + AQT1000_ANA_MBHC_RESULT_3, 0x80, 7, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPHR_SCHMT_RESULT", - AQT_ANA_MBHC_RESULT_3, 0x40, 6, 0), + AQT1000_ANA_MBHC_RESULT_3, 0x40, 6, 0), WCD_MBHC_REGISTER("WCD_MBHC_OCP_FSM_EN", - AQT_HPH_OCP_CTL, 0x10, 4, 0), + AQT1000_HPH_OCP_CTL, 0x10, 4, 0), WCD_MBHC_REGISTER("WCD_MBHC_BTN_RESULT", - AQT_ANA_MBHC_RESULT_3, 0x07, 0, 0), + AQT1000_ANA_MBHC_RESULT_3, 0x07, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_BTN_ISRC_CTL", - AQT_ANA_MBHC_ELECT, 0x70, 4, 0), + AQT1000_ANA_MBHC_ELECT, 0x70, 4, 0), WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT", - AQT_ANA_MBHC_RESULT_3, 0xFF, 0, 0), + AQT1000_ANA_MBHC_RESULT_3, 0xFF, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL", - AQT_ANA_MICB2, 0xC0, 6, 0), + AQT1000_ANA_MICB1, 0xC0, 6, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME", - AQT_HPH_CNP_WG_TIME, 0xFF, 0, 0), + AQT1000_HPH_CNP_WG_TIME, 0xFF, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN", - AQT_ANA_HPH, 0x40, 6, 0), + AQT1000_ANA_HPH, 0x40, 6, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PA_EN", - AQT_ANA_HPH, 0x80, 7, 0), + AQT1000_ANA_HPH, 0x80, 7, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPH_PA_EN", - AQT_ANA_HPH, 0xC0, 6, 0), + AQT1000_ANA_HPH, 0xC0, 6, 0), WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE", - AQT_ANA_MBHC_RESULT_3, 0x10, 4, 0), + AQT1000_ANA_MBHC_RESULT_3, 0x10, 4, 0), WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL", 0, 0, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN", - AQT_MBHC_CTL_BCS, 0x02, 1, 0), + AQT1000_MBHC_CTL_BCS, 0x02, 1, 0), WCD_MBHC_REGISTER("WCD_MBHC_FSM_STATUS", - AQT_MBHC_STATUS_SPARE_1, 0x01, 0, 0), + AQT1000_MBHC_NEW_FSM_STATUS, 0x01, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL", - AQT_MBHC_NEW_CTL_2, 0x70, 4, 0), + AQT1000_MBHC_NEW_CTL_2, 0x70, 4, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_DET_EN", - AQT_HPH_L_TEST, 0x01, 0, 0), + AQT1000_HPH_L_TEST, 0x01, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_DET_EN", - AQT_HPH_R_TEST, 0x01, 0, 0), + AQT1000_HPH_R_TEST, 0x01, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_STATUS", - AQT_INTR_PIN1_STATUS0, 0x04, 2, 0), + AQT1000_INTR_CTRL_INT_STATUS_2, 0x20, 5, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_STATUS", - AQT_INTR_PIN1_STATUS0, 0x08, 3, 0), + AQT1000_INTR_CTRL_INT_STATUS_2, 0x40, 6, 0), WCD_MBHC_REGISTER("WCD_MBHC_ADC_EN", - AQT_MBHC_NEW_CTL_1, 0x08, 3, 0), - WCD_MBHC_REGISTER("WCD_MBHC_ADC_COMPLETE", AQT_MBHC_NEW_FSM_STATUS, + AQT1000_MBHC_NEW_CTL_1, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_COMPLETE", AQT1000_MBHC_NEW_FSM_STATUS, 0x40, 6, 0), - WCD_MBHC_REGISTER("WCD_MBHC_ADC_TIMEOUT", AQT_MBHC_NEW_FSM_STATUS, + WCD_MBHC_REGISTER("WCD_MBHC_ADC_TIMEOUT", AQT1000_MBHC_NEW_FSM_STATUS, 0x80, 7, 0), - WCD_MBHC_REGISTER("WCD_MBHC_ADC_RESULT", AQT_MBHC_NEW_ADC_RESULT, + WCD_MBHC_REGISTER("WCD_MBHC_ADC_RESULT", AQT1000_MBHC_NEW_ADC_RESULT, 0xFF, 0, 0), - WCD_MBHC_REGISTER("WCD_MBHC_MICB2_VOUT", AQT_ANA_MICB2, 0x3F, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB2_VOUT", AQT1000_ANA_MICB1, 0x3F, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_ADC_MODE", - AQT_MBHC_NEW_CTL_1, 0x10, 4, 0), + AQT1000_MBHC_NEW_CTL_1, 0x10, 4, 0), WCD_MBHC_REGISTER("WCD_MBHC_DETECTION_DONE", - AQT_MBHC_NEW_CTL_1, 0x04, 2, 0), + AQT1000_MBHC_NEW_CTL_1, 0x04, 2, 0), WCD_MBHC_REGISTER("WCD_MBHC_ELECT_ISRC_EN", - AQT_ANA_MBHC_ZDET, 0x02, 1, 0), + AQT1000_ANA_MBHC_ZDET, 0x02, 1, 0), }; static const struct wcd_mbhc_intr intr_ids = { - .mbhc_sw_intr = AQT_IRQ_MBHC_SW_DET, - .mbhc_btn_press_intr = AQT_IRQ_MBHC_BUTTON_PRESS_DET, - .mbhc_btn_release_intr = AQT_IRQ_MBHC_BUTTON_RELEASE_DET, - .mbhc_hs_ins_intr = AQT_IRQ_MBHC_ELECT_INS_REM_LEG_DET, - .mbhc_hs_rem_intr = AQT_IRQ_MBHC_ELECT_INS_REM_DET, - .hph_left_ocp = AQT_IRQ_HPH_PA_OCPL_FAULT, - .hph_right_ocp = AQT_IRQ_HPH_PA_OCPR_FAULT, -}; - - -static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = { - "cdc-vdd-mic-bias", + .mbhc_sw_intr = AQT1000_IRQ_MBHC_SW_DET, + .mbhc_btn_press_intr = AQT1000_IRQ_MBHC_BUTTON_PRESS_DET, + .mbhc_btn_release_intr = AQT1000_IRQ_MBHC_BUTTON_RELEASE_DET, + .mbhc_hs_ins_intr = AQT1000_IRQ_MBHC_ELECT_INS_REM_LEG_DET, + .mbhc_hs_rem_intr = AQT1000_IRQ_MBHC_ELECT_INS_REM_DET, + .hph_left_ocp = AQT1000_IRQ_HPH_PA_OCPL_FAULT, + .hph_right_ocp = AQT1000_IRQ_HPH_PA_OCPR_FAULT, }; struct aqt_mbhc_zdet_param { @@ -171,33 +165,29 @@ static int aqt_mbhc_request_irq(struct snd_soc_codec *codec, int irq, irq_handler_t handler, const char *name, void *data) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); - struct wcd9xxx_core_resource *core_res = - &wcd9xxx->core_res; + struct aqt1000 *aqt = dev_get_drvdata(codec->dev); - return wcd9xxx_request_irq(core_res, irq, handler, name, data); + return aqt_request_irq(aqt, irq, name, handler, data); } static void aqt_mbhc_irq_control(struct snd_soc_codec *codec, int irq, bool enable) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); - struct wcd9xxx_core_resource *core_res = - &wcd9xxx->core_res; + struct aqt1000 *aqt = dev_get_drvdata(codec->dev); + if (enable) - wcd9xxx_enable_irq(core_res, irq); + aqt_enable_irq(aqt, irq); else - wcd9xxx_disable_irq(core_res, irq); + aqt_disable_irq(aqt, irq); } static int aqt_mbhc_free_irq(struct snd_soc_codec *codec, int irq, void *data) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); - struct wcd9xxx_core_resource *core_res = - &wcd9xxx->core_res; + struct aqt1000 *aqt = dev_get_drvdata(codec->dev); + + aqt_free_irq(aqt, irq, data); - wcd9xxx_free_irq(core_res, irq, data); return 0; } @@ -205,75 +195,26 @@ static void aqt_mbhc_clk_setup(struct snd_soc_codec *codec, bool enable) { if (enable) - snd_soc_update_bits(codec, AQT_MBHC_NEW_CTL_1, + snd_soc_update_bits(codec, AQT1000_MBHC_NEW_CTL_1, 0x80, 0x80); else - snd_soc_update_bits(codec, AQT_MBHC_NEW_CTL_1, + snd_soc_update_bits(codec, AQT1000_MBHC_NEW_CTL_1, 0x80, 0x00); } static int aqt_mbhc_btn_to_num(struct snd_soc_codec *codec) { - return snd_soc_read(codec, AQT_ANA_MBHC_RESULT_3) & 0x7; -} - -static int aqt_enable_ext_mb_source(struct wcd_mbhc *mbhc, - bool turn_on) -{ - struct aqt_mbhc *aqt_mbhc; - struct snd_soc_codec *codec = mbhc->codec; - struct aqt_on_demand_supply *supply; - int ret = 0; - - aqt_mbhc = container_of(mbhc, struct aqt_mbhc, wcd_mbhc); - - supply = &aqt_mbhc->on_demand_list[AQT_ON_DEMAND_MICBIAS]; - if (!supply->supply) { - dev_dbg(codec->dev, "%s: warning supply not present ond for %s\n", - __func__, "onDemand Micbias"); - return ret; - } - - dev_dbg(codec->dev, "%s turn_on: %d count: %d\n", __func__, turn_on, - supply->ondemand_supply_count); - - if (turn_on) { - if (!(supply->ondemand_supply_count)) { - ret = snd_soc_dapm_force_enable_pin( - snd_soc_codec_get_dapm(codec), - "MICBIAS_REGULATOR"); - snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); - } - supply->ondemand_supply_count++; - } else { - if (supply->ondemand_supply_count > 0) - supply->ondemand_supply_count--; - if (!(supply->ondemand_supply_count)) { - ret = snd_soc_dapm_disable_pin( - snd_soc_codec_get_dapm(codec), - "MICBIAS_REGULATOR"); - snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); - } - } - - if (ret) - dev_err(codec->dev, "%s: Failed to %s external micbias source\n", - __func__, turn_on ? "enable" : "disabled"); - else - dev_dbg(codec->dev, "%s: %s external micbias source\n", - __func__, turn_on ? "Enabled" : "Disabled"); - - return ret; + return snd_soc_read(codec, AQT1000_ANA_MBHC_RESULT_3) & 0x7; } static void aqt_mbhc_mbhc_bias_control(struct snd_soc_codec *codec, bool enable) { if (enable) - snd_soc_update_bits(codec, AQT_ANA_MBHC_ELECT, + snd_soc_update_bits(codec, AQT1000_ANA_MBHC_ELECT, 0x01, 0x01); else - snd_soc_update_bits(codec, AQT_ANA_MBHC_ELECT, + snd_soc_update_bits(codec, AQT1000_ANA_MBHC_ELECT, 0x01, 0x00); } @@ -289,15 +230,10 @@ static void aqt_mbhc_program_btn_thr(struct snd_soc_codec *codec, __func__, num_btn); return; } - /* - * Tavil just needs one set of thresholds for button detection - * due to micbias voltage ramp to pullup upon button press. So - * btn_low and is_micbias are ignored and always program button - * thresholds using btn_high. - */ + for (i = 0; i < num_btn; i++) { vth = ((btn_high[i] * 2) / 25) & 0x3F; - snd_soc_update_bits(codec, AQT_ANA_MBHC_BTN0 + i, + snd_soc_update_bits(codec, AQT1000_ANA_MBHC_BTN0 + i, 0xFC, vth << 2); dev_dbg(codec->dev, "%s: btn_high[%d]: %d, vth: %d\n", __func__, i, btn_high[i], vth); @@ -307,15 +243,10 @@ static void aqt_mbhc_program_btn_thr(struct snd_soc_codec *codec, static bool aqt_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock) { struct snd_soc_codec *codec = mbhc->codec; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); - struct wcd9xxx_core_resource *core_res = - &wcd9xxx->core_res; + struct aqt1000 *aqt = dev_get_drvdata(codec->dev); bool ret = 0; - if (lock) - ret = wcd9xxx_lock_sleep(core_res); - else - wcd9xxx_unlock_sleep(core_res); + dev_dbg(aqt->dev, "%s: lock: %d\n", __func__, lock); return ret; } @@ -324,9 +255,9 @@ static int aqt_mbhc_register_notifier(struct wcd_mbhc *mbhc, struct notifier_block *nblock, bool enable) { - struct aqt_mbhc *aqt_mbhc; + struct aqt1000_mbhc *aqt_mbhc; - aqt_mbhc = container_of(mbhc, struct aqt_mbhc, wcd_mbhc); + aqt_mbhc = container_of(mbhc, struct aqt1000_mbhc, wcd_mbhc); if (enable) return blocking_notifier_chain_register(&aqt_mbhc->notifier, @@ -340,8 +271,9 @@ static bool aqt_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) { u8 val; - if (micb_num == MIC_BIAS_2) { - val = (snd_soc_read(mbhc->codec, AQT_ANA_MICB2) >> 6); + if (micb_num == MIC_BIAS_1) { + val = ((snd_soc_read(mbhc->codec, AQT1000_ANA_MICB1) & 0xC0) + >> 6); if (val == 0x01) return true; } @@ -350,29 +282,28 @@ static bool aqt_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) static bool aqt_mbhc_hph_pa_on_status(struct snd_soc_codec *codec) { - return (snd_soc_read(codec, AQT_ANA_HPH) & 0xC0) ? true : false; + return (snd_soc_read(codec, AQT1000_ANA_HPH) & 0xC0) ? true : false; } -static void aqt_mbhc_hph_l_pull_up_control( - struct snd_soc_codec *codec, - enum mbhc_hs_pullup_iref pull_up_cur) +static void aqt_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec, + int pull_up_cur) { /* Default pull up current to 2uA */ - if (pull_up_cur < I_OFF || pull_up_cur > I_3P0_UA || - pull_up_cur == I_DEFAULT) - pull_up_cur = I_2P0_UA; + if (pull_up_cur > HS_PULLUP_I_OFF || pull_up_cur < HS_PULLUP_I_3P0_UA || + pull_up_cur == HS_PULLUP_I_DEFAULT) + pull_up_cur = HS_PULLUP_I_2P0_UA; dev_dbg(codec->dev, "%s: HS pull up current:%d\n", __func__, pull_up_cur); - snd_soc_update_bits(codec, AQT_MBHC_NEW_PLUG_DETECT_CTL, - 0xC0, pull_up_cur << 6); + snd_soc_update_bits(codec, AQT1000_MBHC_NEW_INT_MECH_DET_CURRENT, + 0x1F, pull_up_cur); } static int aqt_mbhc_request_micbias(struct snd_soc_codec *codec, int micb_num, int req) { - int ret; + int ret = 0; /* * If micbias is requested, make sure that there @@ -397,14 +328,14 @@ static void aqt_mbhc_micb_ramp_control(struct snd_soc_codec *codec, bool enable) { if (enable) { - snd_soc_update_bits(codec, AQT_ANA_MICB2_RAMP, + snd_soc_update_bits(codec, AQT1000_ANA_MICB1_RAMP, 0x1C, 0x0C); - snd_soc_update_bits(codec, AQT_ANA_MICB2_RAMP, + snd_soc_update_bits(codec, AQT1000_ANA_MICB1_RAMP, 0x80, 0x80); } else { - snd_soc_update_bits(codec, AQT_ANA_MICB2_RAMP, + snd_soc_update_bits(codec, AQT1000_ANA_MICB1_RAMP, 0x80, 0x00); - snd_soc_update_bits(codec, AQT_ANA_MICB2_RAMP, + snd_soc_update_bits(codec, AQT1000_ANA_MICB1_RAMP, 0x1C, 0x00); } } @@ -412,11 +343,11 @@ static void aqt_mbhc_micb_ramp_control(struct snd_soc_codec *codec, static struct firmware_cal *aqt_get_hwdep_fw_cal(struct wcd_mbhc *mbhc, enum wcd_cal_type type) { - struct aqt_mbhc *aqt_mbhc; + struct aqt1000_mbhc *aqt_mbhc; struct firmware_cal *hwdep_cal; struct snd_soc_codec *codec = mbhc->codec; - aqt_mbhc = container_of(mbhc, struct aqt_mbhc, wcd_mbhc); + aqt_mbhc = container_of(mbhc, struct aqt1000_mbhc, wcd_mbhc); if (!codec) { pr_err("%s: NULL codec pointer\n", __func__); @@ -433,10 +364,10 @@ static struct firmware_cal *aqt_get_hwdep_fw_cal(struct wcd_mbhc *mbhc, static int aqt_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec, int micb_num, bool req_en) { - struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + struct aqt1000_pdata *pdata = dev_get_platdata(codec->dev); int rc, micb_mv; - if (micb_num != MIC_BIAS_2) + if (micb_num != MIC_BIAS_1) return -EINVAL; /* @@ -444,17 +375,17 @@ static int aqt_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec, * voltage needed to detect threshold microphone, then do * not change the micbias, just return. */ - if (pdata->micbias.micb2_mv >= WCD_MBHC_THR_HS_MICB_MV) + if (pdata->micbias.micb1_mv >= WCD_MBHC_THR_HS_MICB_MV) return 0; - micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb2_mv; + micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb1_mv; - rc = aqt_mbhc_micb_adjust_voltage(codec, micb_mv, MIC_BIAS_2); + rc = aqt_mbhc_micb_adjust_voltage(codec, micb_mv, MIC_BIAS_1); return rc; } -static inline void aqt_mbhc_get_result_params(struct wcd9xxx *wcd9xxx, +static inline void aqt_mbhc_get_result_params(struct aqt1000 *aqt, s16 *d1_a, u16 noff, int32_t *zdet) { @@ -467,16 +398,16 @@ static inline void aqt_mbhc_get_result_params(struct wcd9xxx *wcd9xxx, 3277, 1639, 820, 410, 205, 103, 52, 26 }; - regmap_update_bits(wcd9xxx->regmap, AQT_ANA_MBHC_ZDET, 0x20, 0x20); + regmap_update_bits(aqt->regmap, AQT1000_ANA_MBHC_ZDET, 0x20, 0x20); for (i = 0; i < AQT_ZDET_NUM_MEASUREMENTS; i++) { - regmap_read(wcd9xxx->regmap, AQT_ANA_MBHC_RESULT_2, &val); + regmap_read(aqt->regmap, AQT1000_ANA_MBHC_RESULT_2, &val); if (val & 0x80) break; } val = val << 0x8; - regmap_read(wcd9xxx->regmap, AQT_ANA_MBHC_RESULT_1, &val1); + regmap_read(aqt->regmap, AQT1000_ANA_MBHC_RESULT_1, &val1); val |= val1; - regmap_update_bits(wcd9xxx->regmap, AQT_ANA_MBHC_ZDET, 0x20, 0x00); + regmap_update_bits(aqt->regmap, AQT1000_ANA_MBHC_ZDET, 0x20, 0x00); x1 = AQT_MBHC_GET_X1(val); c1 = AQT_MBHC_GET_C1(val); /* If ramp is not complete, give additional 5ms */ @@ -484,7 +415,7 @@ static inline void aqt_mbhc_get_result_params(struct wcd9xxx *wcd9xxx, usleep_range(5000, 5050); if (!c1 || !x1) { - dev_dbg(wcd9xxx->dev, + dev_dbg(aqt->dev, "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n", __func__, c1, x1); goto ramp_down; @@ -496,13 +427,13 @@ static inline void aqt_mbhc_get_result_params(struct wcd9xxx *wcd9xxx, else if (x1 < minCode_param[noff]) *zdet = AQT_ZDET_FLOATING_IMPEDANCE; - dev_dbg(wcd9xxx->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n", + dev_dbg(aqt->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n", __func__, d1, c1, x1, *zdet); ramp_down: i = 0; while (x1) { - regmap_bulk_read(wcd9xxx->regmap, - AQT_ANA_MBHC_RESULT_1, (u8 *)&val, 2); + regmap_bulk_read(aqt->regmap, + AQT1000_ANA_MBHC_RESULT_1, (u8 *)&val, 2); x1 = AQT_MBHC_GET_X1(val); i++; if (i == AQT_ZDET_NUM_MEASUREMENTS) @@ -514,32 +445,32 @@ static void aqt_mbhc_zdet_ramp(struct snd_soc_codec *codec, struct aqt_mbhc_zdet_param *zdet_param, int32_t *zl, int32_t *zr, s16 *d1_a) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct aqt1000 *aqt = dev_get_drvdata(codec->dev); int32_t zdet = 0; - snd_soc_update_bits(codec, AQT_MBHC_NEW_ZDET_ANA_CTL, 0x70, + snd_soc_update_bits(codec, AQT1000_MBHC_NEW_ZDET_ANA_CTL, 0x70, zdet_param->ldo_ctl << 4); - snd_soc_update_bits(codec, AQT_ANA_MBHC_BTN5, 0xFC, + snd_soc_update_bits(codec, AQT1000_ANA_MBHC_BTN5, 0xFC, zdet_param->btn5); - snd_soc_update_bits(codec, AQT_ANA_MBHC_BTN6, 0xFC, + snd_soc_update_bits(codec, AQT1000_ANA_MBHC_BTN6, 0xFC, zdet_param->btn6); - snd_soc_update_bits(codec, AQT_ANA_MBHC_BTN7, 0xFC, + snd_soc_update_bits(codec, AQT1000_ANA_MBHC_BTN7, 0xFC, zdet_param->btn7); - snd_soc_update_bits(codec, AQT_MBHC_NEW_ZDET_ANA_CTL, 0x0F, + snd_soc_update_bits(codec, AQT1000_MBHC_NEW_ZDET_ANA_CTL, 0x0F, zdet_param->noff); - snd_soc_update_bits(codec, AQT_MBHC_NEW_ZDET_RAMP_CTL, 0x0F, + snd_soc_update_bits(codec, AQT1000_MBHC_NEW_ZDET_RAMP_CTL, 0x0F, zdet_param->nshift); if (!zl) goto z_right; /* Start impedance measurement for HPH_L */ - regmap_update_bits(wcd9xxx->regmap, - AQT_ANA_MBHC_ZDET, 0x80, 0x80); - dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_L, noff = %d\n", + regmap_update_bits(aqt->regmap, + AQT1000_ANA_MBHC_ZDET, 0x80, 0x80); + dev_dbg(aqt->dev, "%s: ramp for HPH_L, noff = %d\n", __func__, zdet_param->noff); - aqt_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet); - regmap_update_bits(wcd9xxx->regmap, - AQT_ANA_MBHC_ZDET, 0x80, 0x00); + aqt_mbhc_get_result_params(aqt, d1_a, zdet_param->noff, &zdet); + regmap_update_bits(aqt->regmap, + AQT1000_ANA_MBHC_ZDET, 0x80, 0x00); *zl = zdet; @@ -547,13 +478,13 @@ static void aqt_mbhc_zdet_ramp(struct snd_soc_codec *codec, if (!zr) return; /* Start impedance measurement for HPH_R */ - regmap_update_bits(wcd9xxx->regmap, - AQT_ANA_MBHC_ZDET, 0x40, 0x40); - dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_R, noff = %d\n", + regmap_update_bits(aqt->regmap, + AQT1000_ANA_MBHC_ZDET, 0x40, 0x40); + dev_dbg(aqt->dev, "%s: ramp for HPH_R, noff = %d\n", __func__, zdet_param->noff); - aqt_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet); - regmap_update_bits(wcd9xxx->regmap, - AQT_ANA_MBHC_ZDET, 0x40, 0x00); + aqt_mbhc_get_result_params(aqt, d1_a, zdet_param->noff, &zdet); + regmap_update_bits(aqt->regmap, + AQT1000_ANA_MBHC_ZDET, 0x40, 0x00); *zr = zdet; } @@ -566,10 +497,10 @@ static inline void aqt_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec, if (*z_val < (AQT_ZDET_VAL_400/1000)) q1 = snd_soc_read(codec, - AQT_CHIP_TIER_CTRL_EFUSE_VAL_OUT1 + (2 * flag_l_r)); + AQT1000_CHIP_CFG0_EFUSE_VAL_OUT1 + (2 * flag_l_r)); else q1 = snd_soc_read(codec, - AQT_CHIP_TIER_CTRL_EFUSE_VAL_OUT2 + (2 * flag_l_r)); + AQT1000_CHIP_CFG0_EFUSE_VAL_OUT2 + (2 * flag_l_r)); if (q1 & 0x80) q1_cal = (10000 - ((q1 & 0x7F) * 25)); else @@ -582,7 +513,7 @@ static void aqt_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, uint32_t *zr) { struct snd_soc_codec *codec = mbhc->codec; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct aqt1000 *aqt = dev_get_drvdata(codec->dev); s16 reg0, reg1, reg2, reg3, reg4; int32_t z1L, z1R, z1Ls; int zMono, z_diff1, z_diff2; @@ -604,26 +535,26 @@ static void aqt_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); - reg0 = snd_soc_read(codec, AQT_ANA_MBHC_BTN5); - reg1 = snd_soc_read(codec, AQT_ANA_MBHC_BTN6); - reg2 = snd_soc_read(codec, AQT_ANA_MBHC_BTN7); - reg3 = snd_soc_read(codec, AQT_MBHC_CTL_CLK); - reg4 = snd_soc_read(codec, AQT_MBHC_NEW_ZDET_ANA_CTL); + reg0 = snd_soc_read(codec, AQT1000_ANA_MBHC_BTN5); + reg1 = snd_soc_read(codec, AQT1000_ANA_MBHC_BTN6); + reg2 = snd_soc_read(codec, AQT1000_ANA_MBHC_BTN7); + reg3 = snd_soc_read(codec, AQT1000_MBHC_CTL_CLK); + reg4 = snd_soc_read(codec, AQT1000_MBHC_NEW_ZDET_ANA_CTL); - if (snd_soc_read(codec, AQT_ANA_MBHC_ELECT) & 0x80) { + if (snd_soc_read(codec, AQT1000_ANA_MBHC_ELECT) & 0x80) { is_fsm_disable = true; - regmap_update_bits(wcd9xxx->regmap, - AQT_ANA_MBHC_ELECT, 0x80, 0x00); + regmap_update_bits(aqt->regmap, + AQT1000_ANA_MBHC_ELECT, 0x80, 0x00); } /* For NO-jack, disable L_DET_EN before Z-det measurements */ if (mbhc->hphl_swh) - regmap_update_bits(wcd9xxx->regmap, - AQT_ANA_MBHC_MECH, 0x80, 0x00); + regmap_update_bits(aqt->regmap, + AQT1000_ANA_MBHC_MECH, 0x80, 0x00); /* Turn off 100k pull down on HPHL */ - regmap_update_bits(wcd9xxx->regmap, - AQT_ANA_MBHC_MECH, 0x01, 0x00); + regmap_update_bits(aqt->regmap, + AQT1000_ANA_MBHC_MECH, 0x01, 0x00); /* First get impedance on Left */ d1 = d1_a[1]; @@ -709,14 +640,14 @@ static void aqt_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, mbhc->hph_type = WCD_MBHC_HPH_MONO; goto zdet_complete; } - snd_soc_update_bits(codec, AQT_HPH_R_ATEST, 0x02, 0x02); - snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, 0x40, 0x01); + snd_soc_update_bits(codec, AQT1000_HPH_R_ATEST, 0x02, 0x02); + snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2, 0x40, 0x01); if (*zl < (AQT_ZDET_VAL_32/1000)) aqt_mbhc_zdet_ramp(codec, &zdet_param[0], &z1Ls, NULL, d1); else aqt_mbhc_zdet_ramp(codec, &zdet_param[1], &z1Ls, NULL, d1); - snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, 0x40, 0x00); - snd_soc_update_bits(codec, AQT_HPH_R_ATEST, 0x02, 0x00); + snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2, 0x40, 0x00); + snd_soc_update_bits(codec, AQT1000_HPH_R_ATEST, 0x02, 0x00); z1Ls /= 1000; aqt_wcd_mbhc_qfuse_cal(codec, &z1Ls, 0); /* Parallel of left Z and 9 ohm pull down resistor */ @@ -734,36 +665,36 @@ static void aqt_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, } zdet_complete: - snd_soc_write(codec, AQT_ANA_MBHC_BTN5, reg0); - snd_soc_write(codec, AQT_ANA_MBHC_BTN6, reg1); - snd_soc_write(codec, AQT_ANA_MBHC_BTN7, reg2); + snd_soc_write(codec, AQT1000_ANA_MBHC_BTN5, reg0); + snd_soc_write(codec, AQT1000_ANA_MBHC_BTN6, reg1); + snd_soc_write(codec, AQT1000_ANA_MBHC_BTN7, reg2); /* Turn on 100k pull down on HPHL */ - regmap_update_bits(wcd9xxx->regmap, - AQT_ANA_MBHC_MECH, 0x01, 0x01); + regmap_update_bits(aqt->regmap, + AQT1000_ANA_MBHC_MECH, 0x01, 0x01); /* For NO-jack, re-enable L_DET_EN after Z-det measurements */ if (mbhc->hphl_swh) - regmap_update_bits(wcd9xxx->regmap, - AQT_ANA_MBHC_MECH, 0x80, 0x80); + regmap_update_bits(aqt->regmap, + AQT1000_ANA_MBHC_MECH, 0x80, 0x80); - snd_soc_write(codec, AQT_MBHC_NEW_ZDET_ANA_CTL, reg4); - snd_soc_write(codec, AQT_MBHC_CTL_CLK, reg3); + snd_soc_write(codec, AQT1000_MBHC_NEW_ZDET_ANA_CTL, reg4); + snd_soc_write(codec, AQT1000_MBHC_CTL_CLK, reg3); if (is_fsm_disable) - regmap_update_bits(wcd9xxx->regmap, - AQT_ANA_MBHC_ELECT, 0x80, 0x80); + regmap_update_bits(aqt->regmap, + AQT1000_ANA_MBHC_ELECT, 0x80, 0x80); } static void aqt_mbhc_gnd_det_ctrl(struct snd_soc_codec *codec, bool enable) { if (enable) { - snd_soc_update_bits(codec, AQT_ANA_MBHC_MECH, + snd_soc_update_bits(codec, AQT1000_ANA_MBHC_MECH, 0x02, 0x02); - snd_soc_update_bits(codec, AQT_ANA_MBHC_MECH, + snd_soc_update_bits(codec, AQT1000_ANA_MBHC_MECH, 0x40, 0x40); } else { - snd_soc_update_bits(codec, AQT_ANA_MBHC_MECH, + snd_soc_update_bits(codec, AQT1000_ANA_MBHC_MECH, 0x40, 0x00); - snd_soc_update_bits(codec, AQT_ANA_MBHC_MECH, + snd_soc_update_bits(codec, AQT1000_ANA_MBHC_MECH, 0x02, 0x00); } } @@ -772,69 +703,50 @@ static void aqt_mbhc_hph_pull_down_ctrl(struct snd_soc_codec *codec, bool enable) { if (enable) { - snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, + snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2, 0x40, 0x40); - snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, + snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2, 0x10, 0x10); } else { - snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, + snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2, 0x40, 0x00); - snd_soc_update_bits(codec, AQT_HPH_PA_CTL2, + snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2, 0x10, 0x00); } } + static void aqt_mbhc_moisture_config(struct wcd_mbhc *mbhc) { struct snd_soc_codec *codec = mbhc->codec; if ((mbhc->moist_rref == R_OFF) || (mbhc->mbhc_cfg->enable_usbc_analog)) { - snd_soc_update_bits(codec, AQT_MBHC_NEW_CTL_2, + snd_soc_update_bits(codec, AQT1000_MBHC_NEW_CTL_2, 0x0C, R_OFF << 2); return; } - /* Donot enable moisture detection if jack type is NC */ + /* Do not enable moisture detection if jack type is NC */ if (!mbhc->hphl_swh) { dev_dbg(codec->dev, "%s: disable moisture detection for NC\n", __func__); - snd_soc_update_bits(codec, AQT_MBHC_NEW_CTL_2, + snd_soc_update_bits(codec, AQT1000_MBHC_NEW_CTL_2, 0x0C, R_OFF << 2); return; } - snd_soc_update_bits(codec, AQT_MBHC_NEW_CTL_2, + snd_soc_update_bits(codec, AQT1000_MBHC_NEW_CTL_2, 0x0C, mbhc->moist_rref << 2); } -static bool aqt_hph_register_recovery(struct wcd_mbhc *mbhc) -{ - struct snd_soc_codec *codec = mbhc->codec; - struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); - - if (!aqt_mbhc) - return false; - - aqt_mbhc->is_hph_recover = false; - snd_soc_dapm_force_enable_pin(snd_soc_codec_get_dapm(codec), - "RESET_HPH_REGISTERS"); - snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); - - snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(codec), - "RESET_HPH_REGISTERS"); - snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); - - return aqt_mbhc->is_hph_recover; -} - static void aqt_update_anc_state(struct snd_soc_codec *codec, bool enable, int anc_num) { if (enable) - snd_soc_update_bits(codec, AQT_CDC_RX1_RX_PATH_CFG0 + + snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num), 0x10, 0x10); else - snd_soc_update_bits(codec, AQT_CDC_RX1_RX_PATH_CFG0 + + snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num), 0x10, 0x00); } @@ -844,9 +756,9 @@ static bool aqt_is_anc_on(struct wcd_mbhc *mbhc) u16 ancl, ancr; ancl = - (snd_soc_read(mbhc->codec, AQT_CDC_RX1_RX_PATH_CFG0)) & 0x10; + (snd_soc_read(mbhc->codec, AQT1000_CDC_RX1_RX_PATH_CFG0)) & 0x10; ancr = - (snd_soc_read(mbhc->codec, AQT_CDC_RX2_RX_PATH_CFG0)) & 0x10; + (snd_soc_read(mbhc->codec, AQT1000_CDC_RX2_RX_PATH_CFG0)) & 0x10; anc_on = !!(ancl | ancr); @@ -859,14 +771,13 @@ static const struct wcd_mbhc_cb mbhc_cb = { .free_irq = aqt_mbhc_free_irq, .clk_setup = aqt_mbhc_clk_setup, .map_btn_code_to_num = aqt_mbhc_btn_to_num, - .enable_mb_source = aqt_enable_ext_mb_source, .mbhc_bias = aqt_mbhc_mbhc_bias_control, .set_btn_thr = aqt_mbhc_program_btn_thr, .lock_sleep = aqt_mbhc_lock_sleep, .register_notifier = aqt_mbhc_register_notifier, .micbias_enable_status = aqt_mbhc_micb_en_status, .hph_pa_on_status = aqt_mbhc_hph_pa_on_status, - .hph_pull_up_control = aqt_mbhc_hph_l_pull_up_control, + .hph_pull_up_control_v2 = aqt_mbhc_hph_l_pull_up_control, .mbhc_micbias_control = aqt_mbhc_request_micbias, .mbhc_micb_ramp_control = aqt_mbhc_micb_ramp_control, .get_hwdep_fw_cal = aqt_get_hwdep_fw_cal, @@ -875,35 +786,16 @@ static const struct wcd_mbhc_cb mbhc_cb = { .mbhc_gnd_det_ctrl = aqt_mbhc_gnd_det_ctrl, .hph_pull_down_ctrl = aqt_mbhc_hph_pull_down_ctrl, .mbhc_moisture_config = aqt_mbhc_moisture_config, - .hph_register_recovery = aqt_hph_register_recovery, .update_anc_state = aqt_update_anc_state, .is_anc_on = aqt_is_anc_on, }; -static struct regulator *aqt_codec_find_ondemand_regulator( - struct snd_soc_codec *codec, const char *name) -{ - int i; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); - struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); - - for (i = 0; i < wcd9xxx->num_of_supplies; ++i) { - if (pdata->regulator[i].ondemand && - wcd9xxx->supplies[i].supply && - !strcmp(wcd9xxx->supplies[i].supply, name)) - return wcd9xxx->supplies[i].consumer; - } - - dev_dbg(codec->dev, "Warning: regulator not found:%s\n", - name); - return NULL; -} - static int aqt_get_hph_type(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct aqt1000_mbhc *aqt_mbhc = aqt->mbhc; struct wcd_mbhc *mbhc; if (!aqt_mbhc) { @@ -926,7 +818,8 @@ static int aqt_hph_impedance_get(struct snd_kcontrol *kcontrol, bool hphr; struct soc_multi_mixer_control *mc; struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct aqt1000_mbhc *aqt_mbhc = aqt->mbhc; if (!aqt_mbhc) { dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); @@ -961,7 +854,7 @@ static const struct snd_kcontrol_new impedance_detect_controls[] = { * @zr: handle to right-ch impedance * return 0 for success or error code in case of failure */ -int aqt_mbhc_get_impedance(struct aqt_mbhc *aqt_mbhc, +int aqt_mbhc_get_impedance(struct aqt1000_mbhc *aqt_mbhc, uint32_t *zl, uint32_t *zr) { if (!aqt_mbhc) { @@ -986,8 +879,21 @@ EXPORT_SYMBOL(aqt_mbhc_get_impedance); int aqt_mbhc_hs_detect(struct snd_soc_codec *codec, struct wcd_mbhc_config *mbhc_cfg) { - struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + struct aqt1000 *aqt; + struct aqt1000_mbhc *aqt_mbhc; + if (!codec) { + pr_err("%s: codec is NULL\n", __func__); + return -EINVAL; + } + + aqt = snd_soc_codec_get_drvdata(codec); + if (!aqt) { + pr_err("%s: aqt is NULL\n", __func__); + return -EINVAL; + } + + aqt_mbhc = aqt->mbhc; if (!aqt_mbhc) { dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); return -EINVAL; @@ -1003,8 +909,21 @@ EXPORT_SYMBOL(aqt_mbhc_hs_detect); */ void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec) { - struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + struct aqt1000 *aqt; + struct aqt1000_mbhc *aqt_mbhc; + + if (!codec) { + pr_err("%s: codec is NULL\n", __func__); + return; + } + + aqt = snd_soc_codec_get_drvdata(codec); + if (!aqt) { + pr_err("%s: aqt is NULL\n", __func__); + return; + } + aqt_mbhc = aqt->mbhc; if (!aqt_mbhc) { dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); return; @@ -1020,7 +939,7 @@ EXPORT_SYMBOL(aqt_mbhc_hs_detect_exit); * * return 0 if mbhc_init is success or error code in case of failure */ -int aqt_mbhc_post_ssr_init(struct aqt_mbhc *mbhc, +int aqt_mbhc_post_ssr_init(struct aqt1000_mbhc *mbhc, struct snd_soc_codec *codec) { int ret; @@ -1057,20 +976,24 @@ EXPORT_SYMBOL(aqt_mbhc_post_ssr_init); * * return 0 if mbhc_init is success or error code in case of failure */ -int aqt_mbhc_init(struct aqt_mbhc **mbhc, struct snd_soc_codec *codec, +int aqt_mbhc_init(struct aqt1000_mbhc **mbhc, struct snd_soc_codec *codec, struct fw_info *fw_data) { - struct regulator *supply; - struct aqt_mbhc *aqt_mbhc; + struct aqt1000_mbhc *aqt_mbhc; struct wcd_mbhc *wcd_mbhc; int ret; - aqt_mbhc = devm_kzalloc(codec->dev, sizeof(struct aqt_mbhc), + if (!codec) { + pr_err("%s: codec is NULL\n", __func__); + return -EINVAL; + } + + aqt_mbhc = devm_kzalloc(codec->dev, sizeof(struct aqt1000_mbhc), GFP_KERNEL); if (!aqt_mbhc) return -ENOMEM; - aqt_mbhc->wcd9xxx = dev_get_drvdata(codec->dev->parent); + aqt_mbhc->aqt = dev_get_drvdata(codec->dev); aqt_mbhc->fw_data = fw_data; BLOCKING_INIT_NOTIFIER_HEAD(&aqt_mbhc->notifier); wcd_mbhc = &aqt_mbhc->wcd_mbhc; @@ -1093,17 +1016,6 @@ int aqt_mbhc_init(struct aqt_mbhc **mbhc, struct snd_soc_codec *codec, goto err; } - supply = aqt_codec_find_ondemand_regulator(codec, - on_demand_supply_name[AQT_ON_DEMAND_MICBIAS]); - if (supply) { - aqt_mbhc->on_demand_list[ - AQT_ON_DEMAND_MICBIAS].supply = - supply; - aqt_mbhc->on_demand_list[ - AQT_ON_DEMAND_MICBIAS].ondemand_supply_count = - 0; - } - (*mbhc) = aqt_mbhc; snd_soc_add_codec_controls(codec, impedance_detect_controls, ARRAY_SIZE(impedance_detect_controls)); @@ -1123,8 +1035,21 @@ EXPORT_SYMBOL(aqt_mbhc_init); */ void aqt_mbhc_deinit(struct snd_soc_codec *codec) { - struct aqt_mbhc *aqt_mbhc = aqt_soc_get_mbhc(codec); + struct aqt1000 *aqt; + struct aqt1000_mbhc *aqt_mbhc; + + if (!codec) { + pr_err("%s: codec is NULL\n", __func__); + return; + } + + aqt = snd_soc_codec_get_drvdata(codec); + if (!aqt) { + pr_err("%s: aqt is NULL\n", __func__); + return; + } + aqt_mbhc = aqt->mbhc; if (aqt_mbhc) { wcd_mbhc_deinit(&aqt_mbhc->wcd_mbhc); devm_kfree(codec->dev, aqt_mbhc); diff --git a/asoc/codecs/aqt1000/aqt1000-mbhc.h b/asoc/codecs/aqt1000/aqt1000-mbhc.h index 848cb07d7e9b..bdf0f5a69cf8 100644 --- a/asoc/codecs/aqt1000/aqt1000-mbhc.h +++ b/asoc/codecs/aqt1000/aqt1000-mbhc.h @@ -1,5 +1,4 @@ -/* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -10,45 +9,32 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ -#ifndef __AQT_MBHC_H__ -#define __AQT_MBHC_H__ +#ifndef __AQT1000_MBHC_H__ +#define __AQT1000_MBHC_H__ #include "../wcd-mbhc-v2.h" -enum aqt_on_demand_supply_name { - AQT_ON_DEMAND_MICBIAS = 0, - AQT_ON_DEMAND_SUPPLIES_MAX, -}; - -struct aqt_on_demand_supply { - struct regulator *supply; - int ondemand_supply_count; -}; - -struct aqt_mbhc { +struct aqt1000_mbhc { struct wcd_mbhc wcd_mbhc; struct blocking_notifier_head notifier; - struct aqt_on_demand_supply on_demand_list[ - AQT_ON_DEMAND_SUPPLIES_MAX]; struct aqt1000 *aqt; struct fw_info *fw_data; bool mbhc_started; - bool is_hph_recover; }; -#if IS_ENABLED(CONFIG_SND_SOC_AQT_MBHC) -extern int aqt_mbhc_init(struct aqt_mbhc **mbhc, +#if IS_ENABLED(CONFIG_SND_SOC_AQT1000) +extern int aqt_mbhc_init(struct aqt1000_mbhc **mbhc, struct snd_soc_codec *codec, struct fw_info *fw_data); extern void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec); extern int aqt_mbhc_hs_detect(struct snd_soc_codec *codec, struct wcd_mbhc_config *mbhc_cfg); extern void aqt_mbhc_deinit(struct snd_soc_codec *codec); -extern int aqt_mbhc_post_ssr_init(struct aqt_mbhc *mbhc, +extern int aqt_mbhc_post_ssr_init(struct aqt1000_mbhc *mbhc, struct snd_soc_codec *codec); -extern int aqt_mbhc_get_impedance(struct aqt_mbhc *aqt_mbhc, +extern int aqt_mbhc_get_impedance(struct aqt1000_mbhc *aqt_mbhc, uint32_t *zl, uint32_t *zr); #else -static inline int aqt_mbhc_init(struct aqt_mbhc **mbhc, +static inline int aqt_mbhc_init(struct aqt1000_mbhc **mbhc, struct snd_soc_codec *codec, struct fw_info *fw_data) { @@ -65,12 +51,13 @@ static inline int aqt_mbhc_hs_detect(struct snd_soc_codec *codec, static inline void aqt_mbhc_deinit(struct snd_soc_codec *codec) { } -static inline int aqt_mbhc_post_ssr_init(struct aqt_mbhc *mbhc, +static inline int aqt_mbhc_post_ssr_init(struct aqt1000_mbhc *mbhc, struct snd_soc_codec *codec) { return 0; } -static inline int aqt_mbhc_get_impedance(struct aqt_mbhc *aqt_mbhc, + +static inline int aqt_mbhc_get_impedance(struct aqt1000_mbhc *aqt_mbhc, uint32_t *zl, uint32_t *zr) { if (zl) @@ -81,4 +68,4 @@ static inline int aqt_mbhc_get_impedance(struct aqt_mbhc *aqt_mbhc, } #endif -#endif /* __AQT_MBHC_H__ */ +#endif /* __AQT1000_MBHC_H__ */ diff --git a/asoc/codecs/aqt1000/aqt1000.c b/asoc/codecs/aqt1000/aqt1000.c index 8ed297fe2dc8..97043fbb6f2b 100644 --- a/asoc/codecs/aqt1000/aqt1000.c +++ b/asoc/codecs/aqt1000/aqt1000.c @@ -36,6 +36,7 @@ #include "aqt1000-registers.h" #include "aqt1000.h" #include "aqt1000-api.h" +#include "aqt1000-mbhc.h" #include "aqt1000-routing.h" #include "../wcdcal-hwdep.h" #include "aqt1000-internal.h" @@ -812,7 +813,15 @@ int aqt_micbias_control(struct snd_soc_codec *codec, aqt->micb_ref++; if (aqt->micb_ref == 1) { snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + if (post_on_event && aqt->mbhc) + blocking_notifier_call_chain( + &aqt->mbhc->notifier, + post_on_event, + &aqt->mbhc->wcd_mbhc); } + if (is_dapm && post_dapm_on && aqt->mbhc) + blocking_notifier_call_chain(&aqt->mbhc->notifier, + post_dapm_on, &aqt->mbhc->wcd_mbhc); break; case MICB_DISABLE: if (aqt->micb_ref > 0) @@ -822,8 +831,21 @@ int aqt_micbias_control(struct snd_soc_codec *codec, snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); else if ((aqt->micb_ref == 0) && (aqt->pullup_ref == 0)) { + if (pre_off_event && aqt->mbhc) + blocking_notifier_call_chain( + &aqt->mbhc->notifier, + pre_off_event, + &aqt->mbhc->wcd_mbhc); snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + if (post_off_event && aqt->mbhc) + blocking_notifier_call_chain( + &aqt->mbhc->notifier, + post_off_event, + &aqt->mbhc->wcd_mbhc); } + if (is_dapm && post_dapm_off && aqt->mbhc) + blocking_notifier_call_chain(&aqt->mbhc->notifier, + post_dapm_off, &aqt->mbhc->wcd_mbhc); break; default: dev_err(codec->dev, "%s: Invalid micbias request: %d\n", @@ -2063,6 +2085,8 @@ static int aqt_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, int hph_mode = aqt->hph_mode; u8 dem_inp; int ret = 0; + uint32_t impedl = 0; + uint32_t impedr = 0; dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, w->name, event, hph_mode); @@ -2096,6 +2120,17 @@ static int aqt_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CFG0, 0x10, 0x10); + + ret = aqt_mbhc_get_impedance(aqt->mbhc, + &impedl, &impedr); + if (!ret) { + aqt_clsh_imped_config(codec, impedl, false); + set_bit(CLSH_Z_CONFIG, &aqt->status_mask); + } else { + dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n", + __func__, ret); + ret = 0; + } break; case SND_SOC_DAPM_POST_PMD: /* 1000us required as per HW requirement */ @@ -2104,6 +2139,10 @@ static int aqt_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, AQT_CLSH_EVENT_POST_PA, AQT_CLSH_STATE_HPHL, hph_mode); + if (test_bit(CLSH_Z_CONFIG, &aqt->status_mask)) { + aqt_clsh_imped_config(codec, impedl, true); + clear_bit(CLSH_Z_CONFIG, &aqt->status_mask); + } break; default: break; @@ -2259,6 +2298,9 @@ static int aqt_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, aqt_codec_override(codec, aqt->hph_mode, event); break; case SND_SOC_DAPM_PRE_PMD: + blocking_notifier_call_chain(&aqt->mbhc->notifier, + AQT_EVENT_PRE_HPHR_PA_OFF, + &aqt->mbhc->wcd_mbhc); snd_soc_update_bits(codec, AQT1000_HPH_R_TEST, 0x01, 0x00); snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL, 0x10, 0x10); @@ -2277,6 +2319,9 @@ static int aqt_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, else usleep_range(5000, 5100); aqt_codec_override(codec, aqt->hph_mode, event); + blocking_notifier_call_chain(&aqt->mbhc->notifier, + AQT_EVENT_POST_HPHR_PA_OFF, + &aqt->mbhc->wcd_mbhc); if (!(strcmp(w->name, "AQT ANC HPHR PA"))) { ret = aqt_codec_enable_anc(w, kcontrol, event); snd_soc_update_bits(codec, @@ -2379,6 +2424,9 @@ static int aqt_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, aqt_codec_override(codec, aqt->hph_mode, event); break; case SND_SOC_DAPM_PRE_PMD: + blocking_notifier_call_chain(&aqt->mbhc->notifier, + AQT_EVENT_PRE_HPHL_PA_OFF, + &aqt->mbhc->wcd_mbhc); snd_soc_update_bits(codec, AQT1000_HPH_L_TEST, 0x01, 0x00); snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL, 0x10, 0x10); @@ -2398,6 +2446,9 @@ static int aqt_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, else usleep_range(5000, 5100); aqt_codec_override(codec, aqt->hph_mode, event); + blocking_notifier_call_chain(&aqt->mbhc->notifier, + AQT_EVENT_POST_HPHL_PA_OFF, + &aqt->mbhc->wcd_mbhc); if (!(strcmp(w->name, "AQT ANC HPHL PA"))) { ret = aqt_codec_enable_anc(w, kcontrol, event); snd_soc_update_bits(codec, @@ -3247,6 +3298,14 @@ static int aqt_soc_codec_probe(struct snd_soc_codec *codec) set_bit(WCD9XXX_ANC_CAL, aqt->fw_data->cal_bit); set_bit(WCD9XXX_MBHC_CAL, aqt->fw_data->cal_bit); + /* Register for Clock */ + aqt->ext_clk = clk_get(aqt->dev, "aqt_clk"); + if (IS_ERR(aqt->ext_clk)) { + dev_err(aqt->dev, "%s: clk get %s failed\n", + __func__, "aqt_ext_clk"); + goto err_clk; + } + ret = wcd_cal_create_hwdep(aqt->fw_data, AQT1000_CODEC_HWDEP_NODE, codec); if (ret < 0) { @@ -3254,6 +3313,12 @@ static int aqt_soc_codec_probe(struct snd_soc_codec *codec) goto err_hwdep; } + /* Initialize MBHC module */ + ret = aqt_mbhc_init(&aqt->mbhc, codec, aqt->fw_data); + if (ret) { + pr_err("%s: mbhc initialization failed\n", __func__); + goto err_hwdep; + } aqt->codec = codec; for (i = 0; i < COMPANDER_MAX; i++) aqt->comp_enabled[i] = 0; @@ -3317,6 +3382,8 @@ static int aqt_soc_codec_probe(struct snd_soc_codec *codec) return ret; err_hwdep: + clk_put(aqt->ext_clk); +err_clk: devm_kfree(codec->dev, aqt->fw_data); aqt->fw_data = NULL; err: @@ -3329,8 +3396,12 @@ static int aqt_soc_codec_remove(struct snd_soc_codec *codec) { struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + /* Deinitialize MBHC module */ + aqt_mbhc_deinit(codec); + aqt->mbhc = NULL; mutex_destroy(&aqt->i2s_lock); mutex_destroy(&aqt->codec_mutex); + clk_put(aqt->ext_clk); return 0; } -- GitLab From e788b89d8b1e8db8acc7e9fdef8221f5bc151810 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 26 Jan 2018 05:18:25 +0530 Subject: [PATCH 0164/1645] codecs: wcd9360: Add AQT based dais in WCD9360 codec driver WCD9360 codec acts as an interface between AQT codec and msmnile CPU DAI. Add AQT based playback and capture dais in WCD9360 codec driver. Change-Id: Ic780dd336a775dbb48a1d3ada90029763ac7a657 Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd9360/wcd9360-routing.h | 19 ++- asoc/codecs/wcd9360/wcd9360.c | 162 +++++++++++++++++++++++++- 2 files changed, 175 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/wcd9360/wcd9360-routing.h b/asoc/codecs/wcd9360/wcd9360-routing.h index 06eab605000b..1d41c0a4871c 100644 --- a/asoc/codecs/wcd9360/wcd9360-routing.h +++ b/asoc/codecs/wcd9360/wcd9360-routing.h @@ -75,8 +75,8 @@ const struct snd_soc_dapm_route pahu_slim_audio_map[] = { {"SLIM TX7", NULL, "CDC_IF TX7 MUX"}, {"SLIM TX8", NULL, "CDC_IF TX8 MUX"}, {"SLIM TX9", NULL, "CDC_IF TX9 MUX"}, - {"SLIM TX10", NULL, "CDC_IF TX10 MUX"}, - {"SLIM TX11", NULL, "CDC_IF TX11 MUX"}, + {"SLIM TX10", NULL, "CDC_IF TX10 MUX2"}, + {"SLIM TX11", NULL, "CDC_IF TX11 MUX2"}, {"SLIM TX13", NULL, "CDC_IF TX13 MUX"}, {"SLIM RX0 MUX", "AIF1_PB", "AIF1 PB"}, @@ -138,7 +138,6 @@ const struct snd_soc_dapm_route pahu_slim_audio_map[] = { {"AIF4_VI Mixer", "SPKR_VI_1", "VIINPUT"}, {"AIF4_VI Mixer", "SPKR_VI_2", "VIINPUT"}, {"AIF4 VI", NULL, "AIF4_VI Mixer"}, - }; const struct snd_soc_dapm_route pahu_audio_map[] = { @@ -266,7 +265,9 @@ const struct snd_soc_dapm_route pahu_audio_map[] = { {"CDC_IF TX9 MUX", "DEC7_192", "ADC US MUX7"}, {"CDC_IF TX10 MUX", "DEC6", "ADC MUX6"}, {"CDC_IF TX10 MUX", "DEC6_192", "ADC US MUX6"}, + {"CDC_IF TX10 MUX2", "TX10_MUX1", "CDC_IF TX10 MUX"}, + {"CDC_IF TX11 MUX2", "TX11_MUX1", "CDC_IF TX11 MUX"}, {"CDC_IF TX11 MUX", "DEC_0_5", "CDC_IF TX11 INP1 MUX"}, {"CDC_IF TX11 MUX", "DEC_9_12", "CDC_IF TX11 INP1 MUX"}, {"CDC_IF TX11 INP1 MUX", "DEC0", "ADC MUX0"}, @@ -859,6 +860,18 @@ const struct snd_soc_dapm_route pahu_audio_map[] = { {"ASRC3 MUX", "ASRC_IN_SPKR2", "RX INT8_2 INTERP"}, {"RX INT8 SEC MIX", NULL, "ASRC3 MUX"}, + + /* SLIMBUS-I2S Bridge interface */ + {"I2S TX1_0 MUX", "AIF4_PB", "AIF4 PB"}, + {"I2S TX1_1 MUX", "AIF4_PB", "AIF4 PB"}, + {"I2S TX1 MIXER", NULL, "I2S TX1_0 MUX"}, + {"I2S TX1 MIXER", NULL, "I2S TX1_1 MUX"}, + {"I2S1 CAP", NULL, "I2S TX1 MIXER"}, + + {"CDC_IF TX10 MUX2", "I2SRX1_0_BRDG", "CDC_IF RX2 MUX"}, + {"CDC_IF TX11 MUX2", "I2SRX1_1_BRDG", "CDC_IF RX3 MUX"}, + {"CDC_IF RX2 MUX", "I2SRX1_0", "I2S1 PB"}, + {"CDC_IF RX3 MUX", "I2SRX1_1", "I2S1 PB"}, }; #endif diff --git a/asoc/codecs/wcd9360/wcd9360.c b/asoc/codecs/wcd9360/wcd9360.c index f0f6b47a08a9..1e743c0a13c4 100644 --- a/asoc/codecs/wcd9360/wcd9360.c +++ b/asoc/codecs/wcd9360/wcd9360.c @@ -184,6 +184,8 @@ enum { AIF4_PB, AIF4_VIFEED, AIF4_MAD_TX, + I2S1_PB, + I2S1_CAP, NUM_CODEC_DAIS, }; @@ -601,6 +603,7 @@ struct pahu_priv { struct platform_device *pdev_child_devices [WCD9360_CHILD_DEVICES_MAX]; int child_count; + int i2s_ref_cnt; }; static const struct pahu_reg_mask_val pahu_spkr_default[] = { @@ -1540,6 +1543,71 @@ static int pahu_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w, return ret; } +static void pahu_codec_enable_i2s(struct snd_soc_codec *codec, bool enable) +{ + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); + + if (enable) { + if (++pahu->i2s_ref_cnt == 1) + snd_soc_update_bits(codec, WCD9360_DATA_HUB_I2S_1_CTL, + 0x01, 0x01); + } else { + if (--pahu->i2s_ref_cnt == 0) + snd_soc_update_bits(codec, WCD9360_DATA_HUB_I2S_1_CTL, + 0x01, 0x00); + } +} + +static int pahu_i2s_aif_rx_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + switch(event) { + case SND_SOC_DAPM_PRE_PMU: + pahu_cdc_mclk_enable(codec, true); + break; + case SND_SOC_DAPM_POST_PMU: + pahu_codec_enable_i2s(codec, true); + break; + case SND_SOC_DAPM_PRE_PMD: + pahu_codec_enable_i2s(codec, false); + break; + case SND_SOC_DAPM_POST_PMD: + pahu_cdc_mclk_enable(codec, false); + break; + } + + return 0; +} + +static int pahu_i2s_aif_tx_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + switch(event) { + case SND_SOC_DAPM_PRE_PMU: + pahu_cdc_mclk_enable(codec, true); + break; + case SND_SOC_DAPM_POST_PMU: + pahu_codec_enable_i2s(codec, true); + break; + case SND_SOC_DAPM_PRE_PMD: + pahu_codec_enable_i2s(codec, false); + break; + case SND_SOC_DAPM_POST_PMD: + pahu_cdc_mclk_enable(codec, false); + break; + } + + return 0; +} + static int pahu_codec_enable_ldo_rxtx(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -4413,8 +4481,14 @@ static const char * const cdc_if_tx9_mux_text[] = { static const char * const cdc_if_tx10_mux_text[] = { "ZERO", "DEC6", "DEC6_192" }; +static const char * const cdc_if_tx10_mux2_text[] = { + "TX10_MUX1", "I2SRX1_0_BRDG" +}; +static const char * const cdc_if_tx11_mux2_text[] = { + "TX11_MUX1", "I2SRX1_1_BRDG", "SWR_PACKED_PDM" +}; static const char * const cdc_if_tx11_mux_text[] = { - "DEC_0_5", "DEC_9_12", "MAD_AUDIO", "MAD_BRDCST" + "RDMA_TX11", "DEC_0_5", "DEC_9_12", "MAD_AUDIO", "MAD_BRDCST" }; static const char * const cdc_if_tx11_inp1_mux_text[] = { "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", @@ -4518,10 +4592,10 @@ static const char *const cdc_if_rx1_mux_text[] = { "SLIM RX1", "I2S RX1" }; static const char *const cdc_if_rx2_mux_text[] = { - "SLIM RX2", "I2S RX2" + "SLIM RX2", "I2SRX1_0", "I2SRX0_2" }; static const char *const cdc_if_rx3_mux_text[] = { - "SLIM RX3", "I2S RX3" + "SLIM RX3", "I2SRX1_1", "I2SRX0_3" }; static const char *const cdc_if_rx4_mux_text[] = { "SLIM RX4", "I2S RX4" @@ -4823,10 +4897,14 @@ WCD_DAPM_ENUM(cdc_if_tx9, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2, 2, cdc_if_tx9_mux_text); WCD_DAPM_ENUM(cdc_if_tx10, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2, 4, cdc_if_tx10_mux_text); +WCD_DAPM_ENUM(cdc_if_tx10_inp2, WCD9360_DATA_HUB_SB_TX10_INP_CFG, 3, + cdc_if_tx10_mux2_text); WCD_DAPM_ENUM(cdc_if_tx11_inp1, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3, 0, cdc_if_tx11_inp1_mux_text); WCD_DAPM_ENUM(cdc_if_tx11, WCD9360_DATA_HUB_SB_TX11_INP_CFG, 0, cdc_if_tx11_mux_text); +WCD_DAPM_ENUM(cdc_if_tx11_inp2, WCD9360_DATA_HUB_SB_TX11_INP_CFG, 3, + cdc_if_tx11_mux2_text); WCD_DAPM_ENUM(cdc_if_tx13_inp1, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3, 4, cdc_if_tx13_inp1_mux_text); WCD_DAPM_ENUM(cdc_if_tx13, WCD9360_DATA_HUB_SB_TX13_INP_CFG, 0, @@ -4974,6 +5052,17 @@ static const struct snd_kcontrol_new adc_us_mux8_switch = static const struct snd_kcontrol_new wdma3_onoff_switch = SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); +static const char *const i2s_tx1_0_txt[] = { + "ZERO", "SB_TX8", "SB_RX2", "SB_TX12" +}; + +static const char *const i2s_tx1_1_txt[] = { + "ZERO", "SB_RX0", "SB_RX1", "SB_RX2", "SB_RX3", "SB_TX11" +}; + +WCD_DAPM_ENUM(i2s_tx1_0_inp, WCD9360_DATA_HUB_I2S_TX1_0_CFG, 0, i2s_tx1_0_txt); +WCD_DAPM_ENUM(i2s_tx1_1_inp, WCD9360_DATA_HUB_I2S_TX1_1_CFG, 0, i2s_tx1_1_txt); + static const struct snd_soc_dapm_widget pahu_dapm_widgets[] = { SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM, AIF1_PB, 0, pahu_codec_enable_slimrx, @@ -4988,6 +5077,11 @@ static const struct snd_soc_dapm_widget pahu_dapm_widgets[] = { AIF4_PB, 0, pahu_codec_enable_slimrx, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_IN_E("I2S1 PB", "I2S1 Playback", 0, SND_SOC_NOPM, + I2S1_PB, 0, pahu_i2s_aif_rx_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + WCD_DAPM_MUX("SLIM RX0 MUX", WCD9360_RX0, slim_rx0), WCD_DAPM_MUX("SLIM RX1 MUX", WCD9360_RX1, slim_rx1), WCD_DAPM_MUX("SLIM RX2 MUX", WCD9360_RX2, slim_rx2), @@ -5104,6 +5198,8 @@ static const struct snd_soc_dapm_widget pahu_dapm_widgets[] = { WCD_DAPM_MUX("CDC_IF TX11 INP1 MUX", WCD9360_TX11, cdc_if_tx11_inp1), WCD_DAPM_MUX("CDC_IF TX13 MUX", WCD9360_TX13, cdc_if_tx13), WCD_DAPM_MUX("CDC_IF TX13 INP1 MUX", WCD9360_TX13, cdc_if_tx13_inp1), + WCD_DAPM_MUX("CDC_IF TX10 MUX2", WCD9360_TX10, cdc_if_tx10_inp2), + WCD_DAPM_MUX("CDC_IF TX11 MUX2", WCD9360_TX11, cdc_if_tx11_inp2), SND_SOC_DAPM_MUX_E("ADC MUX0", WCD9360_CDC_TX0_TX_PATH_CTL, 5, 0, &tx_adc_mux0_mux, pahu_codec_enable_dec, @@ -5234,6 +5330,16 @@ static const struct snd_soc_dapm_widget pahu_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM, AIF3_CAP, 0, pahu_codec_enable_slimtx, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + WCD_DAPM_MUX("I2S TX1_0 MUX", 0, i2s_tx1_0_inp), + WCD_DAPM_MUX("I2S TX1_1 MUX", 0, i2s_tx1_1_inp), + SND_SOC_DAPM_MIXER("I2S TX1 MIXER", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_AIF_OUT_E("I2S1 CAP", "I2S1 Capture", 0, + SND_SOC_NOPM, I2S1_CAP, 0, pahu_i2s_aif_tx_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0, aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)), SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0, @@ -5956,6 +6062,22 @@ static int pahu_hw_params(struct snd_pcm_substream *substream, return 0; } +static int pahu_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct pahu_priv *pahu = snd_soc_codec_get_drvdata(dai->codec); + + dev_dbg(dai->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", + __func__, dai->name, dai->id, params_rate(params), + params_channels(params)); + + pahu->dai[dai->id].rate = params_rate(params); + pahu->dai[dai->id].bit_width = params_width(params); + + return 0; +} + static struct snd_soc_dai_ops pahu_dai_ops = { .startup = pahu_startup, .shutdown = pahu_shutdown, @@ -5971,6 +6093,10 @@ static struct snd_soc_dai_ops pahu_vi_dai_ops = { .get_channel_map = pahu_get_channel_map, }; +static struct snd_soc_dai_ops pahu_i2s_dai_ops = { + .hw_params = pahu_i2s_hw_params, +}; + static struct snd_soc_dai_driver pahu_dai[] = { { .name = "pahu_rx1", @@ -6098,6 +6224,34 @@ static struct snd_soc_dai_driver pahu_dai[] = { }, .ops = &pahu_dai_ops, }, + { + .name = "pahu_i2s1_rx", + .id = I2S1_PB, + .playback = { + .stream_name = "I2S1 Playback", + .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK, + .formats = WCD9360_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 384000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &pahu_i2s_dai_ops, + }, + { + .name = "pahu_i2s1_tx", + .id = I2S1_CAP, + .capture = { + .stream_name = "I2S1 Capture", + .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK, + .formats = WCD9360_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &pahu_i2s_dai_ops, + }, }; static void pahu_codec_power_gate_digital_core(struct pahu_priv *pahu) @@ -7205,6 +7359,8 @@ static int pahu_soc_codec_probe(struct snd_soc_codec *codec) snd_soc_dapm_ignore_suspend(dapm, "AIF4 Playback"); snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX"); snd_soc_dapm_ignore_suspend(dapm, "VIfeed"); + snd_soc_dapm_ignore_suspend(dapm, "I2S1 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "I2S1 Capture"); snd_soc_dapm_sync(dapm); -- GitLab From d511059f31261dc9ac2423c357aecf75a2a9eee5 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Tue, 20 Feb 2018 13:06:19 -0800 Subject: [PATCH 0165/1645] ipc: update UAPI header install location Update UAPI header install location from PRODUCT_OUT to OUT. Change-Id: I6a1d3b14ae77317f1fc2069a33865ceed190c200 Signed-off-by: Banajit Goswami --- ipc/Kbuild | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipc/Kbuild b/ipc/Kbuild index b3a70601a13e..5c9c49254d95 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -114,7 +114,7 @@ KBUILD_CPPFLAGS += $(CDEFINES) ifeq ($(KERNEL_BUILD), 0) HEADER_INSTALL_DIR := $(TOP)/kernel/msm-$(TARGET_KERNEL_VERSION)/scripts -UAPI_OUT := $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/include +UAPI_OUT := $(OUT)/obj/vendor/qcom/opensource/audio-kernel/include $(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ avtimer.h;) $(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio.h;) $(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_aac.h;) -- GitLab From 085a654371f19614ce09406d325f7e551fbc7a5b Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 25 Jan 2018 23:38:29 +0530 Subject: [PATCH 0166/1645] ASoC: AQT1000: DLKM support for AQT1000 driver Add build configuration to compile AQT1000 driver for msmnile target. Change-Id: Ia5b43544a2247c53458fd5585d62152d0e9fd3a7 Signed-off-by: Sudheer Papothi --- Android.mk | 5 ++ asoc/codecs/aqt1000/Android.mk | 41 ++++++++++++ asoc/codecs/aqt1000/Kbuild | 114 +++++++++++++++++++++++++++++++++ config/sdm855auto.conf | 1 + config/sdm855autoconf.h | 1 + 5 files changed, 162 insertions(+) create mode 100644 asoc/codecs/aqt1000/Android.mk create mode 100644 asoc/codecs/aqt1000/Kbuild diff --git a/Android.mk b/Android.mk index 89636e6f341c..74058a1cb1fb 100644 --- a/Android.mk +++ b/Android.mk @@ -23,6 +23,11 @@ include $(MY_LOCAL_PATH)/asoc/codecs/Android.mk include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk endif +ifeq ($(call is-board-platform-in-list,sdm670 msmnile),true) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/aqt1000/Module.symvers) +include $(MY_LOCAL_PATH)/asoc/codecs/aqt1000/Android.mk +endif + ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers) diff --git a/asoc/codecs/aqt1000/Android.mk b/asoc/codecs/aqt1000/Android.mk new file mode 100644 index 000000000000..63635da80746 --- /dev/null +++ b/asoc/codecs/aqt1000/Android.mk @@ -0,0 +1,41 @@ +# Android makefile for audio kernel modules + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,sdm670 msmnile),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=aqt1000_cdc_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_aqt1000_cdc.ko +LOCAL_MODULE_KBUILD_NAME := aqt1000_cdc_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +endif # DLKM check +endif # supported target check diff --git a/asoc/codecs/aqt1000/Kbuild b/asoc/codecs/aqt1000/Kbuild new file mode 100644 index 000000000000..40cc7d4ab47b --- /dev/null +++ b/asoc/codecs/aqt1000/Kbuild @@ -0,0 +1,114 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + +ifeq ($(KERNEL_BUILD), 1) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + + ifeq ($(CONFIG_ARCH_SDM670), y) + include $(AUDIO_ROOT)/config/sdm670auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h + endif + + ifeq ($(CONFIG_ARCH_SDM855), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif +endif + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +# for AQT1000 Codec +ifeq ($(CONFIG_SND_SOC_AQT1000), m) + AQT1000_CDC_OBJS += aqt1000-regmap.o + AQT1000_CDC_OBJS += aqt1000-utils.o + AQT1000_CDC_OBJS += aqt1000-core.o + AQT1000_CDC_OBJS += aqt1000-irq.o + AQT1000_CDC_OBJS += aqt1000-clsh.o + AQT1000_CDC_OBJS += aqt1000.o + AQT1000_CDC_OBJS += aqt1000-mbhc.o +endif + +LINUX_INC += -Iinclude/linux + +INCS := $(COMMON_INC) \ + $(UAPI_INC) + +EXTRA_CFLAGS += $(INCS) + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +ifeq ($(KERNEL_BUILD), 0) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/aqt1000/Module.symvers +endif + +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_AQT1000) += aqt1000_cdc_dlkm.o +aqt1000_cdc_dlkm-y := $(AQT1000_CDC_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/config/sdm855auto.conf b/config/sdm855auto.conf index 5257790c6173..2ebdce0379a4 100644 --- a/config/sdm855auto.conf +++ b/config/sdm855auto.conf @@ -35,3 +35,4 @@ CONFIG_DTS_SRS_TM=m CONFIG_SND_SOC_MSM_STUB=m CONFIG_MSM_AVTIMER=m CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m +CONFIG_SND_SOC_AQT1000=m diff --git a/config/sdm855autoconf.h b/config/sdm855autoconf.h index 593934adfee0..651b04a49a04 100644 --- a/config/sdm855autoconf.h +++ b/config/sdm855autoconf.h @@ -47,3 +47,4 @@ #define CONFIG_SND_SOC_MSM_STUB 1 #define CONFIG_MSM_AVTIMER 1 #define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 +#define CONFIG_SND_SOC_AQT1000 1 -- GitLab From 14a1fecf2f19ca190bcd05f6f447a8d54669e8d1 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 22 Feb 2018 11:24:11 +0530 Subject: [PATCH 0167/1645] ASoC: msm-cdc-pinctrl: Add stub function for pinctrl get function Add stub function for msm pinctrl get function when msm pinctrl configuration is not defined. Change-Id: I5229dd804025e328471f0fd35cff33a69d47b2dd Signed-off-by: Sudheer Papothi --- asoc/codecs/msm-cdc-pinctrl.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/msm-cdc-pinctrl.h b/asoc/codecs/msm-cdc-pinctrl.h index 7eabefb80e19..4286fffa3bf4 100644 --- a/asoc/codecs/msm-cdc-pinctrl.h +++ b/asoc/codecs/msm-cdc-pinctrl.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -44,6 +44,10 @@ int msm_cdc_pinctrl_drv_init(void) void msm_cdc_pinctrl_drv_exit(void) { } +bool msm_cdc_pinctrl_get_state(struct device_node *np) +{ + return true; +} #endif #endif -- GitLab From e161119e92b4ab1e1df2496b84f85e2a02c7bdf4 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 1 Feb 2018 17:24:08 +0800 Subject: [PATCH 0168/1645] ASoC: msm: add dailinks for msmnile machine driver Add ALSA dailinks for supporting various audio/voice use cases for msmnile target. Change-Id: If300b2c94e72414a657f30691cdfcb0d0a3b9a13 Signed-off-by: Vidyakumar Athota --- asoc/sdm855.c | 5532 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 5405 insertions(+), 127 deletions(-) diff --git a/asoc/sdm855.c b/asoc/sdm855.c index 0acd7b7bf7f4..d6507369f5b1 100644 --- a/asoc/sdm855.c +++ b/asoc/sdm855.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,8 @@ #include #include "device_event.h" #include "msm-pcm-routing-v2.h" +#include "codecs/msm-cdc-pinctrl.h" +#include "codecs/wcd9360/wcd9360.h" #include "codecs/wsa881x.h" #define DRV_NAME "sdm855-asoc-snd" @@ -54,14 +57,66 @@ #define SAMPLING_RATE_352P8KHZ 352800 #define SAMPLING_RATE_384KHZ 384000 -struct msm_wsa881x_dev_info { - struct device_node *of_node; - u32 index; +#define WSA8810_NAME_1 "wsa881x.20170211" +#define WSA8810_NAME_2 "wsa881x.20170212" +#define WCN_CDC_SLIM_RX_CH_MAX 2 +#define WCN_CDC_SLIM_TX_CH_MAX 3 +#define TDM_CHANNEL_MAX 8 + +#define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ + +enum { + SLIM_RX_0 = 0, + SLIM_RX_1, + SLIM_RX_2, + SLIM_RX_3, + SLIM_RX_4, + SLIM_RX_5, + SLIM_RX_6, + SLIM_RX_7, + SLIM_RX_MAX, +}; +enum { + SLIM_TX_0 = 0, + SLIM_TX_1, + SLIM_TX_2, + SLIM_TX_3, + SLIM_TX_4, + SLIM_TX_5, + SLIM_TX_6, + SLIM_TX_7, + SLIM_TX_8, + SLIM_TX_MAX, }; -struct msm_asoc_mach_data { - u32 mclk_freq; - struct snd_info_entry *codec_root; +enum { + PRIM_MI2S = 0, + SEC_MI2S, + TERT_MI2S, + QUAT_MI2S, + MI2S_MAX, +}; + +enum { + PRIM_AUX_PCM = 0, + SEC_AUX_PCM, + TERT_AUX_PCM, + QUAT_AUX_PCM, + AUX_PCM_MAX, +}; + +struct mi2s_conf { + struct mutex lock; + u32 ref_cnt; + u32 msm_is_mi2s_master; +}; + +static u32 mi2s_ebit_clk[MI2S_MAX] = { + Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT }; struct dev_config { @@ -70,47 +125,395 @@ struct dev_config { u32 channels; }; -static struct platform_device *spdev; +enum { + DP_RX_IDX = 0, + EXT_DISP_RX_IDX_MAX, +}; -static struct snd_soc_aux_dev *msm_aux_dev; -static struct snd_soc_codec_conf *msm_codec_conf; +struct msm_wsa881x_dev_info { + struct device_node *of_node; + u32 index; +}; + +enum pinctrl_pin_state { + STATE_DISABLE = 0, /* All pins are in sleep state */ + STATE_MI2S_ACTIVE, /* IS2 = active, TDM = sleep */ + STATE_TDM_ACTIVE, /* IS2 = sleep, TDM = active */ +}; + +struct msm_pinctrl_info { + struct pinctrl *pinctrl; + struct pinctrl_state *mi2s_disable; + struct pinctrl_state *tdm_disable; + struct pinctrl_state *mi2s_active; + struct pinctrl_state *tdm_active; + enum pinctrl_pin_state curr_state; +}; + +struct msm_asoc_mach_data { + struct snd_info_entry *codec_root; + struct msm_pinctrl_info pinctrl_info; +}; + +struct msm_asoc_wcd93xx_codec { + void* (*get_afe_config_fn)(struct snd_soc_codec *codec, + enum afe_config_type config_type); +}; + +static const char *const pin_states[] = {"sleep", "i2s-active", + "tdm-active"}; enum { - SLIM_RX_0 = 0, - SLIM_RX_MAX, + TDM_0 = 0, + TDM_1, + TDM_2, + TDM_3, + TDM_4, + TDM_5, + TDM_6, + TDM_7, + TDM_PORT_MAX, }; enum { - SLIM_TX_0 = 0, - SLIM_TX_MAX, + TDM_PRI = 0, + TDM_SEC, + TDM_TERT, + TDM_QUAT, + TDM_INTERFACE_MAX, +}; + +struct tdm_port { + u32 mode; + u32 channel; +}; + +/* TDM default config */ +static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + } +}; + +/* TDM default config */ +static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + } }; /* Default configuration of slimbus channels */ static struct dev_config slim_rx_cfg[] = { [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; static struct dev_config slim_tx_cfg[] = { [SLIM_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +/* Default configuration of external display BE */ +static struct dev_config ext_disp_rx_cfg[] = { + [DP_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config usb_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, }; +static struct dev_config usb_tx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 1, +}; + +static struct dev_config proxy_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +/* Default configuration of MI2S channels */ +static struct dev_config mi2s_rx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config mi2s_tx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_rx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_tx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; +static int msm_vi_feed_tx_ch = 2; static const char *const slim_rx_ch_text[] = {"One", "Two"}; static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; +static const char *const vi_feed_ch_text[] = {"One", "Two"}; +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; +static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE", + "S24_3LE"}; static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", "KHZ_44P1", "KHZ_48", "KHZ_88P2", "KHZ_96", "KHZ_176P4", "KHZ_192", "KHZ_352P8", "KHZ_384"}; -static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", - "S32_LE"}; +static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; +static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *ch_text[] = {"Two", "Three", "Four", "Five", + "Six", "Seven", "Eight"}; +static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_32", "KHZ_44P1", + "KHZ_88P2", "KHZ_176P4" }; +static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", "Eight"}; +static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; +static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", + "KHZ_48", "KHZ_176P4", + "KHZ_352P8"}; +static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; +static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_16", + "KHZ_22P05", "KHZ_32", "KHZ_44P1", + "KHZ_48", "KHZ_96", "KHZ_192"}; +static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static const char *const hifi_text[] = {"Off", "On"}; +static const char *const qos_text[] = {"Disable", "Enable"}; static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_1_tx_chs, slim_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, + ext_disp_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); + +static struct platform_device *spdev; + +static bool is_initial_boot; +static bool codec_reg_done; +static struct snd_soc_aux_dev *msm_aux_dev; +static struct snd_soc_codec_conf *msm_codec_conf; +static struct msm_asoc_wcd93xx_codec msm_codec_fn; + +static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, + int enable, bool dapm); +static int msm_wsa881x_init(struct snd_soc_component *component); + +static struct snd_soc_dapm_route wcd_audio_paths[] = { + {"MIC BIAS1", NULL, "MCLK TX"}, + {"MIC BIAS3", NULL, "MCLK TX"}, + {"MIC BIAS4", NULL, "MCLK TX"}, +}; + +static struct afe_clk_set mi2s_clk[MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + } +}; + +static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; static int slim_get_sample_rate_val(int sample_rate) { @@ -255,8 +658,20 @@ static int slim_get_port_idx(struct snd_kcontrol *kcontrol) if (strnstr(kcontrol->id.name, "SLIM_0_RX", sizeof("SLIM_0_RX"))) { port_id = SLIM_RX_0; } else if (strnstr(kcontrol->id.name, - "SLIM_0_TX", sizeof("SLIM_0_TX"))) { + "SLIM_2_RX", sizeof("SLIM_2_RX"))) { + port_id = SLIM_RX_2; + } else if (strnstr(kcontrol->id.name, + "SLIM_5_RX", sizeof("SLIM_5_RX"))) { + port_id = SLIM_RX_5; + } else if (strnstr(kcontrol->id.name, + "SLIM_6_RX", sizeof("SLIM_6_RX"))) { + port_id = SLIM_RX_6; + } else if (strnstr(kcontrol->id.name, + "SLIM_0_TX", sizeof("SLIM_0_TX"))) { port_id = SLIM_TX_0; + } else if (strnstr(kcontrol->id.name, + "SLIM_1_TX", sizeof("SLIM_1_TX"))) { + port_id = SLIM_TX_1; } else { pr_err("%s: unsupported channel: %s", __func__, kcontrol->id.name); @@ -476,102 +891,4864 @@ static int slim_tx_ch_put(struct snd_kcontrol *kcontrol, return 1; } -static const struct snd_kcontrol_new msm_snd_controls[] = { - SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, - slim_rx_ch_get, slim_rx_ch_put), - SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs, - slim_tx_ch_get, slim_tx_ch_put), - SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format, - slim_rx_bit_format_get, slim_rx_bit_format_put), - SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format, - slim_tx_bit_format_get, slim_tx_bit_format_put), - SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate, - slim_rx_sample_rate_get, slim_rx_sample_rate_put), - SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate, - slim_tx_sample_rate_get, slim_tx_sample_rate_put), +static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1; + pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch); + return 1; +} + +static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* + * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) + * when used for BT_SCO use case. Return either Rx or Tx sample rate + * value. + */ + switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate = %d", __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n", + __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate, + slim_tx_cfg[SLIM_TX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, + usb_rx_cfg.channels); + ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1; + return 0; +} + +static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels); + return 1; +} + +static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_rx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__, + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_rx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_rx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_rx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_rx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, + usb_tx_cfg.channels); + ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1; + return 0; +} + +static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels); + return 1; +} + +static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_tx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + default: + sample_rate_val = 6; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__, + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_tx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_tx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_tx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_tx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "Display Port RX", + sizeof("Display Port RX"))) { + idx = DP_RX_IDX; + } else { + pr_err("%s: unsupported BE: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].bit_format) { + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 2: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int ext_disp_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.integer.value[0] = + ext_disp_rx_cfg[idx].channels - 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + + return 0; +} + +static int ext_disp_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ext_disp_rx_cfg[idx].channels = + ucontrol->value.integer.value[0] + 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + return 1; +} + +static int ext_disp_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].sample_rate) { + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 6; + break; + + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 4; + break; + + case SAMPLING_RATE_32KHZ: + sample_rate_val = 3; + break; + + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: ext_disp_rx[%d].sample_rate = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].sample_rate); + + return 0; +} + +static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 6: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 5: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 4: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_32KHZ; + break; + case 2: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, ext_disp_rx[%d].sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], idx, + ext_disp_rx_cfg[idx].sample_rate); + return 0; +} + +static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2; + + return 0; +} + +static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2; + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + + return 1; +} + +static int tdm_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int aux_pcm_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 0: + default: + sample_rate = SAMPLING_RATE_8KHZ; + break; + } + return sample_rate; +} + +static int tdm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 5; + break; + default: + sample_rate_val = 3; + break; + } + return sample_rate_val; +} + +static int aux_pcm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + return sample_rate_val; +} + +static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, + struct tdm_port *port) +{ + if (port) { + if (strnstr(kcontrol->id.name, "PRI", + sizeof(kcontrol->id.name))) { + port->mode = TDM_PRI; + } else if (strnstr(kcontrol->id.name, "SEC", + sizeof(kcontrol->id.name))) { + port->mode = TDM_SEC; + } else if (strnstr(kcontrol->id.name, "TERT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_TERT; + } else if (strnstr(kcontrol->id.name, "QUAT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_QUAT; + } else { + pr_err("%s: unsupported mode in: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + + if (strnstr(kcontrol->id.name, "RX_0", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_0", + sizeof(kcontrol->id.name))) { + port->channel = TDM_0; + } else if (strnstr(kcontrol->id.name, "RX_1", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_1", + sizeof(kcontrol->id.name))) { + port->channel = TDM_1; + } else if (strnstr(kcontrol->id.name, "RX_2", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_2", + sizeof(kcontrol->id.name))) { + port->channel = TDM_2; + } else if (strnstr(kcontrol->id.name, "RX_3", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_3", + sizeof(kcontrol->id.name))) { + port->channel = TDM_3; + } else if (strnstr(kcontrol->id.name, "RX_4", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_4", + sizeof(kcontrol->id.name))) { + port->channel = TDM_4; + } else if (strnstr(kcontrol->id.name, "RX_5", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_5", + sizeof(kcontrol->id.name))) { + port->channel = TDM_5; + } else if (strnstr(kcontrol->id.name, "RX_6", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_6", + sizeof(kcontrol->id.name))) { + port->channel = TDM_6; + } else if (strnstr(kcontrol->id.name, "RX_7", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_7", + sizeof(kcontrol->id.name))) { + port->channel = TDM_7; + } else { + pr_err("%s: unsupported channel in: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + } else + return -EINVAL; + return 0; +} + +static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_rx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_tx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_get_format(int value) +{ + int format = 0; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int tdm_get_format_val(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 2; + break; + default: + value = 0; + break; + } + return value; +} + +static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_rx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_tx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + + ucontrol->value.enumerated.item[0] = + tdm_rx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = + tdm_tx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", + sizeof("PRIM_AUX_PCM"))) + idx = PRIM_AUX_PCM; + else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM", + sizeof("SEC_AUX_PCM"))) + idx = SEC_AUX_PCM; + else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", + sizeof("TERT_AUX_PCM"))) + idx = TERT_AUX_PCM; + else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", + sizeof("QUAT_AUX_PCM"))) + idx = QUAT_AUX_PCM; + else { + pr_err("%s: unsupported port: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX", + sizeof("PRIM_MI2S_RX"))) + idx = PRIM_MI2S; + else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX", + sizeof("SEC_MI2S_RX"))) + idx = SEC_MI2S; + else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", + sizeof("TERT_MI2S_RX"))) + idx = TERT_MI2S; + else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", + sizeof("QUAT_MI2S_RX"))) + idx = QUAT_MI2S; + else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", + sizeof("PRIM_MI2S_TX"))) + idx = PRIM_MI2S; + else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX", + sizeof("SEC_MI2S_TX"))) + idx = SEC_MI2S; + else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", + sizeof("TERT_MI2S_TX"))) + idx = TERT_MI2S; + else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", + sizeof("QUAT_MI2S_TX"))) + idx = QUAT_MI2S; + else { + pr_err("%s: unsupported channel: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int mi2s_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + default: + sample_rate_val = 6; + break; + } + return sample_rate_val; +} + +static int mi2s_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_192KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int mi2s_auxpcm_get_format(int value) +{ + int format; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int mi2s_auxpcm_get_format_value(int format) +{ + int value; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + value = 2; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 3; + break; + default: + value = 0; + break; + } + return value; +} + +static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(mi2s_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(mi2s_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(aux_pcm_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(aux_pcm_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} +static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, + slim_rx_ch_get, slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs, + slim_rx_ch_get, slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs, + slim_tx_ch_get, slim_tx_ch_put), + SOC_ENUM_EXT("SLIM_1_TX Channels", slim_1_tx_chs, + slim_tx_ch_get, slim_tx_ch_put), + SOC_ENUM_EXT("SLIM_5_RX Channels", slim_5_rx_chs, + slim_rx_ch_get, slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_6_RX Channels", slim_6_rx_chs, + slim_rx_ch_get, slim_rx_ch_put), + SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, + msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, + usb_audio_rx_ch_get, usb_audio_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, + usb_audio_tx_ch_get, usb_audio_tx_ch_put), + SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, + ext_disp_rx_ch_get, ext_disp_rx_ch_put), + SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, + proxy_rx_ch_get, proxy_rx_ch_put), + SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_5_RX Format", slim_5_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_6_RX Format", slim_6_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format, + slim_tx_bit_format_get, slim_tx_bit_format_put), + SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, + usb_audio_rx_format_get, usb_audio_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, + usb_audio_tx_format_get, usb_audio_tx_format_put), + SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, + ext_disp_rx_format_get, ext_disp_rx_format_put), + SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate, + slim_tx_sample_rate_get, slim_tx_sample_rate_put), + SOC_ENUM_EXT("SLIM_5_RX SampleRate", slim_5_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_6_RX SampleRate", slim_6_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, + usb_audio_rx_sample_rate_get, + usb_audio_rx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, + usb_audio_tx_sample_rate_get, + usb_audio_tx_sample_rate_put), + SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, + ext_disp_rx_sample_rate_get, + ext_disp_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("SEC_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("TERT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("TERT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), +}; + +static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, + int enable, bool dapm) +{ + int ret = 0; + + if (!strcmp(dev_name(codec->dev), "pahu_codec")) { + ret = pahu_cdc_mclk_enable(codec, enable); + } else { + dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", + __func__); + ret = -EINVAL; + } + return ret; +} + +static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, + int enable, bool dapm) +{ + int ret = 0; + + if (!strcmp(dev_name(codec->dev), "pahu_codec")) { + ret = pahu_cdc_mclk_tx_enable(codec, enable); + } else { + dev_err(codec->dev, "%s: unknown codec to enable TX ext clk\n", + __func__); + ret = -EINVAL; + } + + return ret; +} + +static int msm_mclk_tx_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + pr_debug("%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return msm_snd_enable_codec_ext_tx_clk(codec, 1, true); + case SND_SOC_DAPM_POST_PMD: + return msm_snd_enable_codec_ext_tx_clk(codec, 0, true); + } + return 0; +} + +static int msm_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + pr_debug("%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return msm_snd_enable_codec_ext_clk(codec, 1, true); + case SND_SOC_DAPM_POST_PMD: + return msm_snd_enable_codec_ext_clk(codec, 0, true); + } + return 0; +} + +static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { + + SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, + msm_mclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0, + msm_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIC("Handset Mic", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + + SND_SOC_DAPM_MIC("Digital Mic0", NULL), + SND_SOC_DAPM_MIC("Digital Mic1", NULL), + SND_SOC_DAPM_MIC("Digital Mic2", NULL), + SND_SOC_DAPM_MIC("Digital Mic3", NULL), + SND_SOC_DAPM_MIC("Digital Mic4", NULL), + SND_SOC_DAPM_MIC("Digital Mic5", NULL), + SND_SOC_DAPM_MIC("Digital Mic6", NULL), + SND_SOC_DAPM_MIC("Digital Mic7", NULL), +}; + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, + int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, + unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +static int msm_slim_get_ch_from_beid(int32_t be_id) +{ + int ch_id = 0; + + switch (be_id) { + case MSM_BACKEND_DAI_SLIMBUS_0_RX: + ch_id = SLIM_RX_0; + break; + case MSM_BACKEND_DAI_SLIMBUS_1_RX: + ch_id = SLIM_RX_1; + break; + case MSM_BACKEND_DAI_SLIMBUS_2_RX: + ch_id = SLIM_RX_2; + break; + case MSM_BACKEND_DAI_SLIMBUS_3_RX: + ch_id = SLIM_RX_3; + break; + case MSM_BACKEND_DAI_SLIMBUS_4_RX: + ch_id = SLIM_RX_4; + break; + case MSM_BACKEND_DAI_SLIMBUS_6_RX: + ch_id = SLIM_RX_6; + break; + case MSM_BACKEND_DAI_SLIMBUS_0_TX: + ch_id = SLIM_TX_0; + break; + case MSM_BACKEND_DAI_SLIMBUS_3_TX: + ch_id = SLIM_TX_3; + break; + default: + ch_id = SLIM_RX_0; + break; + } + + return ch_id; +} + +static int msm_ext_disp_get_idx_from_beid(int32_t be_id) +{ + int idx; + + switch (be_id) { + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = DP_RX_IDX; + break; + default: + pr_err("%s: Incorrect ext_disp BE id %d\n", __func__, be_id); + idx = -EINVAL; + break; + } + + return idx; +} + +static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int rc = 0; + int idx; + void *config = NULL; + struct snd_soc_codec *codec = NULL; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->id) { + case MSM_BACKEND_DAI_SLIMBUS_0_RX: + case MSM_BACKEND_DAI_SLIMBUS_1_RX: + case MSM_BACKEND_DAI_SLIMBUS_2_RX: + case MSM_BACKEND_DAI_SLIMBUS_3_RX: + case MSM_BACKEND_DAI_SLIMBUS_4_RX: + case MSM_BACKEND_DAI_SLIMBUS_6_RX: + idx = msm_slim_get_ch_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[idx].bit_format); + rate->min = rate->max = slim_rx_cfg[idx].sample_rate; + channels->min = channels->max = slim_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_0_TX: + case MSM_BACKEND_DAI_SLIMBUS_3_TX: + idx = msm_slim_get_ch_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[idx].bit_format); + rate->min = rate->max = slim_tx_cfg[idx].sample_rate; + channels->min = channels->max = slim_tx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_1_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[1].bit_format); + rate->min = rate->max = slim_tx_cfg[1].sample_rate; + channels->min = channels->max = slim_tx_cfg[1].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_4_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + SNDRV_PCM_FORMAT_S32_LE); + rate->min = rate->max = SAMPLING_RATE_8KHZ; + channels->min = channels->max = msm_vi_feed_tx_ch; + break; + + case MSM_BACKEND_DAI_SLIMBUS_5_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[5].bit_format); + rate->min = rate->max = slim_rx_cfg[5].sample_rate; + channels->min = channels->max = slim_rx_cfg[5].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_5_TX: + codec = rtd->codec; + rate->min = rate->max = SAMPLING_RATE_16KHZ; + channels->min = channels->max = 1; + + config = msm_codec_fn.get_afe_config_fn(codec, + AFE_SLIMBUS_SLAVE_PORT_CONFIG); + if (config) { + rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, + config, SLIMBUS_5_TX); + if (rc) + pr_err("%s: Failed to set slimbus slave port config %d\n", + __func__, rc); + } + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[SLIM_RX_7].bit_format); + rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate; + channels->min = channels->max = + slim_rx_cfg[SLIM_RX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_8_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_8].channels; + break; + + case MSM_BACKEND_DAI_USB_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_rx_cfg.bit_format); + rate->min = rate->max = usb_rx_cfg.sample_rate; + channels->min = channels->max = usb_rx_cfg.channels; + break; + + case MSM_BACKEND_DAI_USB_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_tx_cfg.bit_format); + rate->min = rate->max = usb_tx_cfg.sample_rate; + channels->min = channels->max = usb_tx_cfg.channels; + break; + + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = msm_ext_disp_get_idx_from_beid(dai_link->id); + if (idx < 0) { + pr_err("%s: Incorrect ext disp idx %d\n", + __func__, idx); + rc = idx; + goto done; + } + + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + ext_disp_rx_cfg[idx].bit_format); + rate->min = rate->max = ext_disp_rx_cfg[idx].sample_rate; + channels->min = channels->max = ext_disp_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_AFE_PCM_RX: + channels->min = channels->max = proxy_rx_cfg.channels; + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + + case MSM_BACKEND_DAI_PRI_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_PRI_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[PRIM_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[SEC_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[SEC_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[TERT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[TERT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[QUAT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[QUAT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUAT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUAT_MI2S].channels; + break; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + +done: + return rc; +} + +static int msm_afe_set_config(struct snd_soc_codec *codec) +{ + int ret = 0; + void *config_data = NULL; + + if (!msm_codec_fn.get_afe_config_fn) { + dev_err(codec->dev, "%s: codec get afe config not init'ed\n", + __func__); + return -EINVAL; + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CDC_REGISTERS_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0); + if (ret) { + dev_err(codec->dev, + "%s: Failed to set codec registers config %d\n", + __func__, ret); + return ret; + } + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CDC_REGISTER_PAGE_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, + 0); + if (ret) + dev_err(codec->dev, + "%s: Failed to set cdc register page config\n", + __func__); + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_SLIMBUS_SLAVE_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0); + if (ret) { + dev_err(codec->dev, + "%s: Failed to set slimbus slave config %d\n", + __func__, ret); + return ret; + } + } + + return 0; +} + +static void msm_afe_clear_config(void) +{ + afe_clear_config(AFE_CDC_REGISTERS_CONFIG); + afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); +} + +static int msm_adsp_power_up_config(struct snd_soc_codec *codec, + struct snd_card *card) +{ + int ret = 0; + unsigned long timeout; + int adsp_ready = 0; + bool snd_card_online = 0; + + timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + + do { + if (!snd_card_online) { + snd_card_online = snd_card_is_online_state(card); + pr_debug("%s: Sound card is %s\n", __func__, + snd_card_online ? "Online" : "Offline"); + } + if (!adsp_ready) { + adsp_ready = q6core_is_adsp_ready(); + pr_debug("%s: ADSP Audio is %s\n", __func__, + adsp_ready ? "ready" : "not ready"); + } + if (snd_card_online && adsp_ready) + break; + + /* + * Sound card/ADSP will be coming up after subsystem restart and + * it might not be fully up when the control reaches + * here. So, wait for 50msec before checking ADSP state + */ + msleep(50); + } while (time_after(timeout, jiffies)); + + if (!snd_card_online || !adsp_ready) { + pr_err("%s: Timeout. Sound card is %s, ADSP Audio is %s\n", + __func__, + snd_card_online ? "Online" : "Offline", + adsp_ready ? "ready" : "not ready"); + ret = -ETIMEDOUT; + goto err; + } + + ret = msm_afe_set_config(codec); + if (ret) + pr_err("%s: Failed to set AFE config. err %d\n", + __func__, ret); + + return 0; + +err: + return ret; +} + +static int sdm855_notifier_service_cb(struct notifier_block *this, + unsigned long opcode, void *ptr) +{ + int ret; + struct snd_soc_card *card = NULL; + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + struct snd_soc_codec *codec; + + pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); + + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + /* + * Use flag to ignore initial boot notifications + * On initial boot msm_adsp_power_up_config is + * called on init. There is no need to clear + * and set the config again on initial boot. + */ + if (is_initial_boot) + break; + msm_afe_clear_config(); + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (is_initial_boot) { + is_initial_boot = false; + break; + } + if (!spdev) + return -EINVAL; + + card = platform_get_drvdata(spdev); + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err; + } + codec = rtd->codec; + + ret = msm_adsp_power_up_config(codec, card->snd_card); + if (ret < 0) { + dev_err(card->dev, + "%s: msm_adsp_power_up_config failed ret = %d!\n", + __func__, ret); + goto err; + } + break; + default: + break; + } +err: + return NOTIFY_OK; +} + +static struct notifier_block service_nb = { + .notifier_call = sdm855_notifier_service_cb, + .priority = -INT_MAX, +}; + +static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + void *config_data; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_component *aux_comp; + struct snd_card *card; + struct snd_info_entry *entry; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); + + /* + * Codec SLIMBUS configuration + * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8 + * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 + * TX14, TX15, TX16 + */ + unsigned int rx_ch[WCD9360_RX_MAX] = {144, 145, 146, 147, 148, 149, + 150, 151}; + unsigned int tx_ch[WCD9360_TX_MAX] = {128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143}; + + pr_info("%s: dev_name:%s\n", __func__, dev_name(cpu_dai->dev)); + + rtd->pmdown_time = 0; + + ret = snd_soc_add_codec_controls(codec, msm_snd_controls, + ARRAY_SIZE(msm_snd_controls)); + if (ret < 0) { + pr_err("%s: add_codec_controls failed, err %d\n", + __func__, ret); + return ret; + } + + snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, + ARRAY_SIZE(msm_dapm_widgets)); + + snd_soc_dapm_add_routes(dapm, wcd_audio_paths, + ARRAY_SIZE(wcd_audio_paths)); + + snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic6"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic7"); + snd_soc_dapm_ignore_suspend(dapm, "MADINPUT"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT1"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT2"); + snd_soc_dapm_ignore_suspend(dapm, "EAR"); + snd_soc_dapm_ignore_suspend(dapm, "ANC EAR"); + snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); + snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); + + snd_soc_dapm_sync(dapm); + + snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); + + msm_codec_fn.get_afe_config_fn = pahu_get_afe_config; + + ret = msm_adsp_power_up_config(codec, rtd->card->snd_card); + if (ret) { + pr_err("%s: Failed to set AFE config %d\n", __func__, ret); + goto err; + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_AANC_VERSION); + if (config_data) { + ret = afe_set_config(AFE_AANC_VERSION, config_data, 0); + if (ret) { + pr_err("%s: Failed to set aanc version %d\n", + __func__, ret); + goto err; + } + } + + /* + * Send speaker configuration only for WSA8810. + * Default configuration is for WSA8815. + */ + pr_debug("%s: Number of aux devices: %d\n", + __func__, rtd->card->num_aux_devs); + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->component_dev_list)) { + aux_comp = list_first_entry(&rtd->card->component_dev_list, + struct snd_soc_component, card_aux_list); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { + pahu_set_spkr_mode(rtd->codec, WCD9360_SPKR_MODE_1); + pahu_set_spkr_gain_offset(rtd->codec, + WCD9360_RX_GAIN_OFFSET_M1P5_DB); + } + } + card = rtd->card->snd_card; + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + pdata->codec_root = NULL; + goto done; + } + pdata->codec_root = entry; + pahu_codec_info_create_codec_entry(pdata->codec_root, codec); + +done: + codec_reg_done = true; + return 0; + +err: + return ret; +} + +static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) +{ + unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; + unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); +} + +static int msm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + int ret = 0; + u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + u32 user_set_tx_ch = 0; + u32 rx_ch_count; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err; + } + if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_5_RX) { + pr_debug("%s: rx_5_ch=%d\n", __func__, + slim_rx_cfg[5].channels); + rx_ch_count = slim_rx_cfg[5].channels; + } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_2_RX) { + pr_debug("%s: rx_2_ch=%d\n", __func__, + slim_rx_cfg[2].channels); + rx_ch_count = slim_rx_cfg[2].channels; + } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_6_RX) { + pr_debug("%s: rx_6_ch=%d\n", __func__, + slim_rx_cfg[6].channels); + rx_ch_count = slim_rx_cfg[6].channels; + } else { + pr_debug("%s: rx_0_ch=%d\n", __func__, + slim_rx_cfg[0].channels); + rx_ch_count = slim_rx_cfg[0].channels; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + rx_ch_count, rx_ch); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + } else { + + pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__, + codec_dai->name, codec_dai->id, user_set_tx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get tx codec chan map, err:%d\n", + __func__, ret); + goto err; + } + /* For _tx1 case */ + if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_0_TX) + user_set_tx_ch = slim_tx_cfg[0].channels; + /* For _tx3 case */ + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_1_TX) + user_set_tx_ch = slim_tx_cfg[1].channels; + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_4_TX) + user_set_tx_ch = msm_vi_feed_tx_ch; + else + user_set_tx_ch = tx_ch_cnt; + + pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), BE id (%d)\n", + __func__, slim_tx_cfg[0].channels, user_set_tx_ch, + tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + user_set_tx_ch, tx_ch, 0, 0); + if (ret < 0) + pr_err("%s: failed to set tx cpu chan map, err:%d\n", + __func__, ret); + } + +err: + return ret; +} + +static int msm_slimbus_2_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; + unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0; + unsigned int num_tx_ch = 0; + unsigned int num_rx_ch = 0; + int ret = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + num_rx_ch = params_channels(params); + pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__, + codec_dai->name, codec_dai->id, num_rx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + num_rx_ch, rx_ch); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + } else { + num_tx_ch = params_channels(params); + pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__, + codec_dai->name, codec_dai->id, num_tx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get tx codec chan map, err:%d\n", + __func__, ret); + goto err; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, + num_tx_ch, tx_ch, 0, 0); + if (ret < 0) { + pr_err("%s: failed to set tx cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + } + +err: + return ret; +} + +static int msm_wcn_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + int ret; + + dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret) { + dev_err(rtd->dev, + "%s: failed to get BTFM codec chan map\n, err:%d\n", + __func__, ret); + goto err; + } + + dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) BE id %d\n", + __func__, tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); + if (ret) + dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + +err: + return ret; +} + +static int msm_get_port_id(int be_id) +{ + int afe_port_id; + + switch (be_id) { + case MSM_BACKEND_DAI_PRI_MI2S_RX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_PRI_MI2S_TX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + default: + pr_err("%s: Invalid BE id: %d\n", __func__, be_id); + afe_port_id = -EINVAL; + } + + return afe_port_id; +} + +static u32 get_mi2s_bits_per_sample(u32 bit_format) +{ + u32 bit_per_sample; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + case SNDRV_PCM_FORMAT_S24_LE: + bit_per_sample = 32; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bit_per_sample = 16; + break; + } + + return bit_per_sample; +} + +static void update_mi2s_clk_val(int dai_id, int stream) +{ + u32 bit_per_sample; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } else { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } +} + +static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int port_id = 0; + int index = cpu_dai->id; + + port_id = msm_get_port_id(rtd->dai_link->id); + if (port_id < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto err; + } + + if (enable) { + update_mi2s_clk_val(index, substream->stream); + dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, + mi2s_clk[index].clk_freq_in_hz); + } + + mi2s_clk[index].enable = enable; + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_clk[index]); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed for port 0x%x , err:%d\n", + __func__, port_id, ret); + goto err; + } + +err: + return ret; +} + +static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, + enum pinctrl_pin_state new_state) +{ + int ret = 0; + int curr_state = 0; + + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + if (pinctrl_info->pinctrl == NULL) { + pr_err("%s: pinctrl_info->pinctrl is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + curr_state = pinctrl_info->curr_state; + pinctrl_info->curr_state = new_state; + pr_debug("%s: curr_state = %s new_state = %s\n", __func__, + pin_states[curr_state], pin_states[pinctrl_info->curr_state]); + + if (curr_state == pinctrl_info->curr_state) { + pr_debug("%s: Already in same state\n", __func__); + goto err; + } + + if (curr_state != STATE_DISABLE && + pinctrl_info->curr_state != STATE_DISABLE) { + pr_debug("%s: state already active cannot switch\n", __func__); + ret = -EIO; + goto err; + } + + switch (pinctrl_info->curr_state) { + case STATE_MI2S_ACTIVE: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_active); + if (ret) { + pr_err("%s: MI2S state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + case STATE_TDM_ACTIVE: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->tdm_active); + if (ret) { + pr_err("%s: TDM state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + case STATE_DISABLE: + if (curr_state == STATE_MI2S_ACTIVE) { + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_disable); + } else { + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->tdm_disable); + } + if (ret) { + pr_err("%s: state disable failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + default: + pr_err("%s: TLMM pin state is invalid\n", __func__); + return -EINVAL; + } + +err: + return ret; +} + +static void msm_release_pinctrl(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + if (pinctrl_info->pinctrl) { + devm_pinctrl_put(pinctrl_info->pinctrl); + pinctrl_info->pinctrl = NULL; + } +} + +static int msm_get_pinctrl(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = NULL; + struct pinctrl *pinctrl; + int ret; + + pinctrl_info = &pdata->pinctrl_info; + + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + return -EINVAL; + } + + pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR_OR_NULL(pinctrl)) { + pr_err("%s: Unable to get pinctrl handle\n", __func__); + return -EINVAL; + } + pinctrl_info->pinctrl = pinctrl; + + /* get all the states handles from Device Tree */ + pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl, + "quat-mi2s-sleep"); + if (IS_ERR(pinctrl_info->mi2s_disable)) { + pr_err("%s: could not get mi2s_disable pinstate\n", __func__); + goto err; + } + pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl, + "quat-mi2s-active"); + if (IS_ERR(pinctrl_info->mi2s_active)) { + pr_err("%s: could not get mi2s_active pinstate\n", __func__); + goto err; + } + pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl, + "quat-tdm-sleep"); + if (IS_ERR(pinctrl_info->tdm_disable)) { + pr_err("%s: could not get tdm_disable pinstate\n", __func__); + goto err; + } + pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl, + "quat-tdm-active"); + if (IS_ERR(pinctrl_info->tdm_active)) { + pr_err("%s: could not get tdm_active pinstate\n", + __func__); + goto err; + } + /* Reset the TLMM pins to a default state */ + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_disable); + if (ret != 0) { + pr_err("%s: Disable TLMM pins failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + pinctrl_info->curr_state = STATE_DISABLE; + + return 0; + +err: + devm_pinctrl_put(pinctrl); + pinctrl_info->pinctrl = NULL; + return -EINVAL; +} + +static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + if (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) { + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + } else if (cpu_dai->id == AFE_PORT_ID_SECONDARY_TDM_RX) { + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + } else { + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n", + __func__, cpu_dai->id, channels->max, rate->max, + params_format(params)); + + return 0; +} + +static int sdm855_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + int slot_width = 32; + int channels, slots; + unsigned int slot_mask, rate, clk_freq; + unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; + + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + slots = tdm_rx_cfg[TDM_PRI][TDM_0].channels; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + slots = tdm_rx_cfg[TDM_SEC][TDM_0].channels; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + slots = tdm_rx_cfg[TDM_TERT][TDM_0].channels; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX: + slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX: + slots = tdm_tx_cfg[TDM_SEC][TDM_0].channels; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX: + slots = tdm_tx_cfg[TDM_TERT][TDM_0].channels; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + break; + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + /*2 slot config - bits 0 and 1 set for the first two slots */ + slot_mask = 0x0000FFFF >> (16-slots); + channels = slots; + + pr_debug("%s: tdm rx slot_width %d slots %d\n", + __func__, slot_width, slots); + + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm rx slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + 0, NULL, channels, slot_offset); + if (ret < 0) { + pr_err("%s: failed to set tdm rx channel map, err:%d\n", + __func__, ret); + goto end; + } + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + /*2 slot config - bits 0 and 1 set for the first two slots */ + slot_mask = 0x0000FFFF >> (16-slots); + channels = slots; + + pr_debug("%s: tdm tx slot_width %d slots %d\n", + __func__, slot_width, slots); + + ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm tx slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + channels, slot_offset, 0, NULL); + if (ret < 0) { + pr_err("%s: failed to set tdm tx channel map, err:%d\n", + __func__, ret); + goto end; + } + } else { + ret = -EINVAL; + pr_err("%s: invalid use case, err:%d\n", + __func__, ret); + goto end; + } + + rate = params_rate(params); + clk_freq = rate * slot_width * slots; + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, clk_freq, SND_SOC_CLOCK_OUT); + if (ret < 0) + pr_err("%s: failed to set tdm clk, err:%d\n", + __func__, ret); + +end: + return ret; +} + +static int sdm855_tdm_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || + (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { + ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); + if (ret) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret); + } + + return ret; +} + +static void sdm855_tdm_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || + (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { + ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); + if (ret) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret); + } +} + +static struct snd_soc_ops sdm855_tdm_be_ops = { + .hw_params = sdm855_tdm_snd_hw_params, + .startup = sdm855_tdm_snd_startup, + .shutdown = sdm855_tdm_snd_shutdown +}; + +static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) +{ + cpumask_t mask; + + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + + cpumask_clear(&mask); + cpumask_set_cpu(1, &mask); /* affine to core 1 */ + cpumask_set_cpu(2, &mask); /* affine to core 2 */ + cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); + + substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; + + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + MSM_LL_QOS_VALUE); + return 0; +} + +static struct snd_soc_ops msm_fe_qos_ops = { + .prepare = msm_fe_qos_prepare, +}; + +static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int index = cpu_dai->id; + unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret_pinctrl = 0; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + if (index < PRIM_MI2S || index >= MI2S_MAX) { + ret = -EINVAL; + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto err; + } + /* + * Mutex protection in case the same MI2S + * interface using for both TX and RX so + * that the same clock won't be enable twice. + */ + mutex_lock(&mi2s_intf_conf[index].lock); + if (++mi2s_intf_conf[index].ref_cnt == 1) { + /* Check if msm needs to provide the clock to the interface */ + if (!mi2s_intf_conf[index].msm_is_mi2s_master) { + mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; + fmt = SND_SOC_DAIFMT_CBM_CFM; + } + ret = msm_mi2s_set_sclk(substream, true); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed to enable MI2S clock, err:%d\n", + __func__, ret); + goto clean_up; + } + + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) { + pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n", + __func__, index, ret); + goto clk_off; + } + if (index == QUAT_MI2S) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_MI2S_ACTIVE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } + } +clk_off: + if (ret < 0) + msm_mi2s_set_sclk(substream, false); +clean_up: + if (ret < 0) + mi2s_intf_conf[index].ref_cnt--; + mutex_unlock(&mi2s_intf_conf[index].lock); +err: + return ret; +} + +static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int index = rtd->cpu_dai->id; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret_pinctrl = 0; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + if (index < PRIM_MI2S || index >= MI2S_MAX) { + pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); + return; + } + + mutex_lock(&mi2s_intf_conf[index].lock); + if (--mi2s_intf_conf[index].ref_cnt == 0) { + ret = msm_mi2s_set_sclk(substream, false); + if (ret < 0) + pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", + __func__, index, ret); + if (index == QUAT_MI2S) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_DISABLE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } + } + mutex_unlock(&mi2s_intf_conf[index].lock); +} + +static struct snd_soc_ops msm_mi2s_be_ops = { + .startup = msm_mi2s_snd_startup, + .shutdown = msm_mi2s_snd_shutdown, +}; + +static struct snd_soc_ops msm_be_ops = { + .hw_params = msm_snd_hw_params, +}; + +static struct snd_soc_ops msm_slimbus_2_be_ops = { + .hw_params = msm_slimbus_2_hw_params, +}; + +static struct snd_soc_ops msm_wcn_ops = { + .hw_params = msm_wcn_hw_params, +}; + + +/* Digital audio interface glue - connects codec <---> CPU */ +static struct snd_soc_dai_link msm_common_dai_links[] = { + /* FrontEnd DAI Links */ + { + .name = MSM_DAILINK_NAME(Media1), + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, + { + .name = MSM_DAILINK_NAME(Media2), + .stream_name = "MultiMedia2", + .cpu_dai_name = "MultiMedia2", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, + }, + { + .name = "VoiceMMode1", + .stream_name = "VoiceMMode1", + .cpu_dai_name = "VoiceMMode1", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE1, + }, + { + .name = "MSM VoIP", + .stream_name = "VoIP", + .cpu_dai_name = "VoIP", + .platform_name = "msm-voip-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_VOIP, + }, + { + .name = MSM_DAILINK_NAME(ULL), + .stream_name = "MultiMedia3", + .cpu_dai_name = "MultiMedia3", + .platform_name = "msm-pcm-dsp.2", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA3, + }, + /* Hostless PCM purpose */ + { + .name = "SLIMBUS_0 Hostless", + .stream_name = "SLIMBUS_0 Hostless", + .cpu_dai_name = "SLIMBUS0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "MSM AFE-PCM RX", + .stream_name = "AFE-PROXY RX", + .cpu_dai_name = "msm-dai-q6-dev.241", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .platform_name = "msm-pcm-afe", + .dpcm_playback = 1, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + }, + { + .name = "MSM AFE-PCM TX", + .stream_name = "AFE-PROXY TX", + .cpu_dai_name = "msm-dai-q6-dev.240", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .platform_name = "msm-pcm-afe", + .dpcm_capture = 1, + .ignore_suspend = 1, + }, + { + .name = MSM_DAILINK_NAME(Compress1), + .stream_name = "Compress1", + .cpu_dai_name = "MultiMedia4", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA4, + }, + { + .name = "AUXPCM Hostless", + .stream_name = "AUXPCM Hostless", + .cpu_dai_name = "AUXPCM_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_1 Hostless", + .stream_name = "SLIMBUS_1 Hostless", + .cpu_dai_name = "SLIMBUS1_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_3 Hostless", + .stream_name = "SLIMBUS_3 Hostless", + .cpu_dai_name = "SLIMBUS3_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_4 Hostless", + .stream_name = "SLIMBUS_4 Hostless", + .cpu_dai_name = "SLIMBUS4_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = MSM_DAILINK_NAME(LowLatency), + .stream_name = "MultiMedia5", + .cpu_dai_name = "MultiMedia5", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .ops = &msm_fe_qos_ops, + }, + { + .name = "Listen 1 Audio Service", + .stream_name = "Listen 1 Audio Service", + .cpu_dai_name = "LSM1", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM1, + }, + /* Multiple Tunnel instances */ + { + .name = MSM_DAILINK_NAME(Compress2), + .stream_name = "Compress2", + .cpu_dai_name = "MultiMedia7", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA7, + }, + { + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", + .cpu_dai_name = "MultiMedia10", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA10, + }, + { + .name = MSM_DAILINK_NAME(ULL_NOIRQ), + .stream_name = "MM_NOIRQ", + .cpu_dai_name = "MultiMedia8", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + .ops = &msm_fe_qos_ops, + }, + /* HDMI Hostless */ + { + .name = "HDMI_RX_HOSTLESS", + .stream_name = "HDMI_RX_HOSTLESS", + .cpu_dai_name = "HDMI_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "VoiceMMode2", + .stream_name = "VoiceMMode2", + .cpu_dai_name = "VoiceMMode2", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE2, + }, + /* LSM FE */ + { + .name = "Listen 2 Audio Service", + .stream_name = "Listen 2 Audio Service", + .cpu_dai_name = "LSM2", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM2, + }, + { + .name = "Listen 3 Audio Service", + .stream_name = "Listen 3 Audio Service", + .cpu_dai_name = "LSM3", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM3, + }, + { + .name = "Listen 4 Audio Service", + .stream_name = "Listen 4 Audio Service", + .cpu_dai_name = "LSM4", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM4, + }, + { + .name = "Listen 5 Audio Service", + .stream_name = "Listen 5 Audio Service", + .cpu_dai_name = "LSM5", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM5, + }, + { + .name = "Listen 6 Audio Service", + .stream_name = "Listen 6 Audio Service", + .cpu_dai_name = "LSM6", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM6, + }, + { + .name = "Listen 7 Audio Service", + .stream_name = "Listen 7 Audio Service", + .cpu_dai_name = "LSM7", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM7, + }, + { + .name = "Listen 8 Audio Service", + .stream_name = "Listen 8 Audio Service", + .cpu_dai_name = "LSM8", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM8, + }, + { + .name = MSM_DAILINK_NAME(Media9), + .stream_name = "MultiMedia9", + .cpu_dai_name = "MultiMedia9", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA9, + }, + { + .name = MSM_DAILINK_NAME(Compress4), + .stream_name = "Compress4", + .cpu_dai_name = "MultiMedia11", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA11, + }, + { + .name = MSM_DAILINK_NAME(Compress5), + .stream_name = "Compress5", + .cpu_dai_name = "MultiMedia12", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA12, + }, + { + .name = MSM_DAILINK_NAME(Compress6), + .stream_name = "Compress6", + .cpu_dai_name = "MultiMedia13", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA13, + }, + { + .name = MSM_DAILINK_NAME(Compress7), + .stream_name = "Compress7", + .cpu_dai_name = "MultiMedia14", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA14, + }, + { + .name = MSM_DAILINK_NAME(Compress8), + .stream_name = "Compress8", + .cpu_dai_name = "MultiMedia15", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA15, + }, + { + .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), + .stream_name = "MM_NOIRQ_2", + .cpu_dai_name = "MultiMedia16", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA16, + }, + { + .name = "SLIMBUS_8 Hostless", + .stream_name = "SLIMBUS8_HOSTLESS Capture", + .cpu_dai_name = "SLIMBUS8_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +}; + +static struct snd_soc_dai_link msm_pahu_fe_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_4_TX, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-hostless", + .codec_name = "pahu_codec", + .codec_dai_name = "pahu_vifeedback", + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + }, + /* Ultrasound RX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Playback", + .stream_name = "SLIMBUS_2 Hostless Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-hostless", + .codec_name = "pahu_codec", + .codec_dai_name = "pahu_rx2", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_slimbus_2_be_ops, + }, + /* Ultrasound TX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Capture", + .stream_name = "SLIMBUS_2 Hostless Capture", + .cpu_dai_name = "msm-dai-q6-dev.16389", + .platform_name = "msm-pcm-hostless", + .codec_name = "pahu_codec", + .codec_dai_name = "pahu_tx2", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_slimbus_2_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { + { + .name = MSM_DAILINK_NAME(ASM Loopback), + .stream_name = "MultiMedia6", + .cpu_dai_name = "MultiMedia6", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA6, + }, + { + .name = "USB Audio Hostless", + .stream_name = "USB Audio Hostless", + .cpu_dai_name = "USBAUDIO_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +}; + +static struct snd_soc_dai_link msm_common_be_dai_links[] = { + /* Backend AFE DAI Links */ + { + .name = LPASS_BE_AFE_PCM_RX, + .stream_name = "AFE Playback", + .cpu_dai_name = "msm-dai-q6-dev.224", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AFE_PCM_TX, + .stream_name = "AFE Capture", + .cpu_dai_name = "msm-dai-q6-dev.225", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Uplink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_TX, + .stream_name = "Voice Uplink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32772", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Downlink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_RX, + .stream_name = "Voice Downlink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32771", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music BACK END DAI Link */ + { + .name = LPASS_BE_VOICE_PLAYBACK_TX, + .stream_name = "Voice Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32773", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + /* Incall Music 2 BACK END DAI Link */ + { + .name = LPASS_BE_VOICE2_PLAYBACK_TX, + .stream_name = "Voice2 Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32770", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_RX, + .stream_name = "USB Audio Playback", + .cpu_dai_name = "msm-dai-q6-dev.28672", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_USB_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_TX, + .stream_name = "USB Audio Capture", + .cpu_dai_name = "msm-dai-q6-dev.28673", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_USB_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_0, + .stream_name = "Primary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36864", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &sdm855_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_0, + .stream_name = "Primary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36865", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &sdm855_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_0, + .stream_name = "Secondary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36880", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &sdm855_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_0, + .stream_name = "Secondary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36881", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &sdm855_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_0, + .stream_name = "Tertiary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36896", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &sdm855_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_0, + .stream_name = "Tertiary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36897", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &sdm855_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_0, + .stream_name = "Quaternary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36912", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sdm855_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_0, + .stream_name = "Quaternary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36913", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &sdm855_tdm_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_pahu_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "pahu_codec", + .codec_dai_name = "pahu_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_init, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "pahu_codec", + .codec_dai_name = "pahu_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_1_RX, + .stream_name = "Slimbus1 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16386", + .platform_name = "msm-pcm-routing", + .codec_name = "pahu_codec", + .codec_dai_name = "pahu_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_1_TX, + .stream_name = "Slimbus1 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16387", + .platform_name = "msm-pcm-routing", + .codec_name = "pahu_codec", + .codec_dai_name = "pahu_tx3", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_2_RX, + .stream_name = "Slimbus2 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-routing", + .codec_name = "pahu_codec", + .codec_dai_name = "pahu_rx2", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_2_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_RX, + .stream_name = "Slimbus3 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16390", + .platform_name = "msm-pcm-routing", + .codec_name = "pahu_codec", + .codec_dai_name = "pahu_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_TX, + .stream_name = "Slimbus3 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16391", + .platform_name = "msm-pcm-routing", + .codec_name = "pahu_codec", + .codec_dai_name = "pahu_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_4_RX, + .stream_name = "Slimbus4 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16392", + .platform_name = "msm-pcm-routing", + .codec_name = "pahu_codec", + .codec_dai_name = "pahu_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_5_RX, + .stream_name = "Slimbus5 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16394", + .platform_name = "msm-pcm-routing", + .codec_name = "pahu_codec", + .codec_dai_name = "pahu_rx3", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* MAD BE */ + { + .name = LPASS_BE_SLIMBUS_5_TX, + .stream_name = "Slimbus5 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16395", + .platform_name = "msm-pcm-routing", + .codec_name = "pahu_codec", + .codec_dai_name = "pahu_mad1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_6_RX, + .stream_name = "Slimbus6 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16396", + .platform_name = "msm-pcm-routing", + .codec_name = "pahu_codec", + .codec_dai_name = "pahu_rx4", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* Slimbus VI Recording */ + { + .name = LPASS_BE_SLIMBUS_TX_VI, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-routing", + .codec_name = "pahu_codec", + .codec_dai_name = "pahu_vifeedback", + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + .no_pcm = 1, + .dpcm_capture = 1, + }, +}; + +static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_7_RX, + .stream_name = "Slimbus7 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16398", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + /* BT codec driver determines capabilities based on + * dai name, bt codecdai name should always contains + * supported usecase information + */ + .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_7_TX, + .stream_name = "Slimbus7 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16399", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_bt_sco_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_8_TX, + .stream_name = "Slimbus8 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16401", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_fm_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_8_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .init = &msm_wcn_init, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link ext_disp_be_dai_link[] = { + /* DISP PORT BACK END DAI Link */ + { + .name = LPASS_BE_DISPLAY_PORT, + .stream_name = "Display Port Playback", + .cpu_dai_name = "msm-dai-q6-dp.24608", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-ext-disp-audio-codec-rx", + .codec_dai_name = "msm_dp_audio_codec_rx_dai", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { + { + .name = LPASS_BE_PRI_MI2S_RX, + .stream_name = "Primary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_MI2S_TX, + .stream_name = "Primary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX, + .stream_name = "Secondary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX, + .stream_name = "Secondary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX, + .stream_name = "Tertiary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX, + .stream_name = "Tertiary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX, + .stream_name = "Quaternary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, }; -static inline int param_is_mask(int p) -{ - return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && - (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); -} - -static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, - int n) -{ - return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); -} - -static void param_set_mask(struct snd_pcm_hw_params *p, int n, - unsigned int bit) -{ - if (bit >= SNDRV_MASK_MAX) - return; - if (param_is_mask(n)) { - struct snd_mask *m = param_to_mask(p, n); - - m->bits[0] = 0; - m->bits[1] = 0; - m->bits[bit >> 5] |= (1 << (bit & 31)); - } -} +static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { + /* Primary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_AUXPCM_RX, + .stream_name = "AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AUXPCM_TX, + .stream_name = "AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Secondary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_SEC_AUXPCM_RX, + .stream_name = "Sec AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_AUXPCM_TX, + .stream_name = "Sec AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Tertiary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_TERT_AUXPCM_RX, + .stream_name = "Tert AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_AUXPCM_TX, + .stream_name = "Tert AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Quaternary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUAT_AUXPCM_RX, + .stream_name = "Quat AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_AUXPCM_TX, + .stream_name = "Quat AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, +}; -static int msm_slim_get_ch_from_beid(int32_t be_id) +static struct snd_soc_dai_link msm_pahu_snd_card_dai_links[ + ARRAY_SIZE(msm_common_dai_links) + + ARRAY_SIZE(msm_pahu_fe_dai_links) + + ARRAY_SIZE(msm_common_misc_fe_dai_links) + + ARRAY_SIZE(msm_common_be_dai_links) + + ARRAY_SIZE(msm_pahu_be_dai_links) + + ARRAY_SIZE(msm_wcn_be_dai_links) + + ARRAY_SIZE(ext_disp_be_dai_link) + + ARRAY_SIZE(msm_mi2s_be_dai_links) + + ARRAY_SIZE(msm_auxpcm_be_dai_links)]; + +static int msm_snd_card_pahu_late_probe(struct snd_soc_card *card) { - int ch_id = 0; + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; - switch (be_id) { - case MSM_BACKEND_DAI_SLIMBUS_0_RX: - ch_id = SLIM_RX_0; - break; - case MSM_BACKEND_DAI_SLIMBUS_0_TX: - ch_id = SLIM_TX_0; - break; - default: - ch_id = SLIM_RX_0; - break; + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err; } - return ch_id; +err: + return ret; } -static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_dai_link *dai_link = rtd->dai_link; - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - int rc = 0; - int idx; - - pr_debug("%s: format = %d, rate = %d\n", - __func__, params_format(params), params_rate(params)); - - switch (dai_link->id) { - case MSM_BACKEND_DAI_SLIMBUS_0_RX: - idx = msm_slim_get_ch_from_beid(dai_link->id); - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_rx_cfg[idx].bit_format); - rate->min = rate->max = slim_rx_cfg[idx].sample_rate; - channels->min = channels->max = slim_rx_cfg[idx].channels; - break; - case MSM_BACKEND_DAI_SLIMBUS_0_TX: - idx = msm_slim_get_ch_from_beid(dai_link->id); - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_tx_cfg[idx].bit_format); - rate->min = rate->max = slim_tx_cfg[idx].sample_rate; - channels->min = channels->max = slim_tx_cfg[idx].channels; - break; - default: - rate->min = rate->max = SAMPLING_RATE_48KHZ; - break; - } - - return rc; -} +struct snd_soc_card snd_soc_card_pahu_msm = { + .name = "sdm855-pahu-snd-card", + .late_probe = msm_snd_card_pahu_late_probe, +}; static int msm_populate_dai_link_component_of_node( struct snd_soc_card *card) @@ -779,27 +5956,18 @@ struct snd_soc_card snd_soc_card_stub_msm = { }; static const struct of_device_id sdm855_asoc_machine_of_match[] = { + { .compatible = "qcom,sdm855-asoc-snd-pahu", + .data = "pahu_codec"}, { .compatible = "qcom,sdm855-asoc-snd-stub", .data = "stub_codec"}, {}, }; -static int sdm855_notifier_service_cb(struct notifier_block *this, - unsigned long opcode, void *ptr) -{ - return NOTIFY_OK; -} - -static struct notifier_block service_nb = { - .notifier_call = sdm855_notifier_service_cb, - .priority = -INT_MAX, -}; - static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) { struct snd_soc_card *card = NULL; struct snd_soc_dai_link *dailink; - int len_1, len_2; + int len_1, len_2, len_3, len_4; int total_links; const struct of_device_id *match; @@ -810,7 +5978,64 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) return NULL; } - if (!strcmp(match->data, "stub_codec")) { + if (!strcmp(match->data, "pahu_codec")) { + card = &snd_soc_card_pahu_msm; + len_1 = ARRAY_SIZE(msm_common_dai_links); + len_2 = len_1 + ARRAY_SIZE(msm_pahu_fe_dai_links); + len_3 = len_2 + ARRAY_SIZE(msm_common_misc_fe_dai_links); + len_4 = len_3 + ARRAY_SIZE(msm_common_be_dai_links); + total_links = len_4 + ARRAY_SIZE(msm_pahu_be_dai_links); + memcpy(msm_pahu_snd_card_dai_links, + msm_common_dai_links, + sizeof(msm_common_dai_links)); + memcpy(msm_pahu_snd_card_dai_links + len_1, + msm_pahu_fe_dai_links, + sizeof(msm_pahu_fe_dai_links)); + memcpy(msm_pahu_snd_card_dai_links + len_2, + msm_common_misc_fe_dai_links, + sizeof(msm_common_misc_fe_dai_links)); + memcpy(msm_pahu_snd_card_dai_links + len_3, + msm_common_be_dai_links, + sizeof(msm_common_be_dai_links)); + memcpy(msm_pahu_snd_card_dai_links + len_4, + msm_pahu_be_dai_links, + sizeof(msm_pahu_be_dai_links)); + + if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + dev_dbg(dev, "%s(): WCN BTFM support present\n", + __func__); + memcpy(msm_pahu_snd_card_dai_links + total_links, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + total_links += ARRAY_SIZE(msm_wcn_be_dai_links); + } + + if (of_property_read_bool(dev->of_node, + "qcom,ext-disp-audio-rx")) { + dev_dbg(dev, "%s(): ext disp audio support present\n", + __func__); + memcpy(msm_pahu_snd_card_dai_links + total_links, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + total_links += ARRAY_SIZE(ext_disp_be_dai_link); + } + if (of_property_read_bool(dev->of_node, + "qcom,mi2s-audio-intf")) { + memcpy(msm_pahu_snd_card_dai_links + total_links, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,auxpcm-audio-intf")) { + memcpy(msm_pahu_snd_card_dai_links + total_links, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + + dailink = msm_pahu_snd_card_dai_links; + } else if (!strcmp(match->data, "stub_codec")) { card = &snd_soc_card_stub_msm; len_1 = ARRAY_SIZE(msm_stub_fe_dai_links); len_2 = len_1 + ARRAY_SIZE(msm_stub_be_dai_links); @@ -1074,6 +6299,41 @@ static int msm_init_wsa_dev(struct platform_device *pdev, return ret; } +static void msm_i2s_auxpcm_init(struct platform_device *pdev) +{ + int count; + u32 mi2s_master_slave[MI2S_MAX]; + int ret; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_init(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-master", + mi2s_master_slave, MI2S_MAX); + if (ret) { + dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n", + __func__); + } else { + for (count = 0; count < MI2S_MAX; count++) { + mi2s_intf_conf[count].msm_is_mi2s_master = + mi2s_master_slave[count]; + } + } +} + +static void msm_i2s_auxpcm_deinit(void) +{ + int count; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_destroy(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + mi2s_intf_conf[count].msm_is_mi2s_master = 0; + } +} static int msm_asoc_machine_probe(struct platform_device *pdev) { struct snd_soc_card *card; @@ -1108,11 +6368,10 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) goto err; } - match = of_match_node(sdm855_asoc_machine_of_match, - pdev->dev.of_node); - if (!match) { - dev_err(&pdev->dev, "%s: no matched codec is found.\n", - __func__); + ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing"); + if (ret) { + dev_err(&pdev->dev, "parse audio routing failed, err:%d\n", + ret); goto err; } @@ -1126,15 +6385,31 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) goto err; ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) { - dev_err(&pdev->dev, "%s: snd_soc_register_card failed (%d)\n", - __func__, ret); + if (ret == -EPROBE_DEFER) { + if (codec_reg_done) + ret = -EINVAL; + goto err; + } else if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); goto err; } - dev_info(&pdev->dev, "%s: Sound card %s registered\n", - __func__, card->name); + dev_info(&pdev->dev, "Sound card %s registered\n", card->name); spdev = pdev; + /* Parse pinctrl info from devicetree */ + ret = msm_get_pinctrl(pdev); + if (!ret) { + pr_debug("%s: pinctrl parsing successful\n", __func__); + } else { + dev_dbg(&pdev->dev, + "%s: Parsing pinctrl failed with %d. Cannot use Ports\n", + __func__, ret); + ret = 0; + } + + msm_i2s_auxpcm_init(pdev); + is_initial_boot = true; ret = audio_notifier_register("sdm855", AUDIO_NOTIFIER_ADSP_DOMAIN, &service_nb); if (ret < 0) @@ -1143,6 +6418,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) return 0; err: + msm_release_pinctrl(pdev); devm_kfree(&pdev->dev, pdata); return ret; } @@ -1151,8 +6427,10 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - snd_soc_unregister_card(card); audio_notifier_deregister("sdm855"); + msm_i2s_auxpcm_deinit(); + + msm_release_pinctrl(pdev); return 0; } -- GitLab From 90d7b490c95b9f5d382eee789a7f869f97cc15e0 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 22 Feb 2018 14:42:41 +0530 Subject: [PATCH 0169/1645] ASoC: AQT1000: Fix return value and add config to include files Fix return value in aqt_codec_info_create_codec_entry function to return proper value and add target config to include files Change-Id: I063e199b1bf0e672b5afc20ed7de8447eed35dd4 Signed-off-by: Sudheer Papothi --- asoc/codecs/aqt1000/Kbuild | 2 +- asoc/codecs/aqt1000/aqt1000.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/aqt1000/Kbuild b/asoc/codecs/aqt1000/Kbuild index 40cc7d4ab47b..f982951ecff7 100644 --- a/asoc/codecs/aqt1000/Kbuild +++ b/asoc/codecs/aqt1000/Kbuild @@ -67,7 +67,7 @@ endif LINUX_INC += -Iinclude/linux -INCS := $(COMMON_INC) \ +INCS += $(COMMON_INC) \ $(UAPI_INC) EXTRA_CFLAGS += $(INCS) diff --git a/asoc/codecs/aqt1000/aqt1000.c b/asoc/codecs/aqt1000/aqt1000.c index 97043fbb6f2b..21baae762a1f 100644 --- a/asoc/codecs/aqt1000/aqt1000.c +++ b/asoc/codecs/aqt1000/aqt1000.c @@ -3194,7 +3194,7 @@ int aqt_codec_info_create_codec_entry(struct snd_info_entry *codec_root, aqt = snd_soc_codec_get_drvdata(codec); if (!aqt) { dev_dbg(codec->dev, "%s: aqt is NULL\n", __func__); - return _EINVAL; + return -EINVAL; } card = codec->component.card; aqt->entry = snd_info_create_subdir(codec_root->module, -- GitLab From 028ed8cc954c5f69b676a602338bc0197112fa86 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Fri, 26 Jan 2018 16:00:25 +0800 Subject: [PATCH 0170/1645] ASoC: msm: add support for quinary mi2s Add support for quinary mi2s/auxpcm/tdm for msmnile target. Change-Id: I0cbfa98129e6181662f7555735173eded12a0bf7 Signed-off-by: Meng Wang Signed-off-by: Vidyakumar Athota --- asoc/sdm855.c | 233 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 229 insertions(+), 4 deletions(-) diff --git a/asoc/sdm855.c b/asoc/sdm855.c index d6507369f5b1..173055701529 100644 --- a/asoc/sdm855.c +++ b/asoc/sdm855.c @@ -95,6 +95,7 @@ enum { SEC_MI2S, TERT_MI2S, QUAT_MI2S, + QUIN_MI2S, MI2S_MAX, }; @@ -103,6 +104,7 @@ enum { SEC_AUX_PCM, TERT_AUX_PCM, QUAT_AUX_PCM, + QUIN_AUX_PCM, AUX_PCM_MAX, }; @@ -116,7 +118,8 @@ static u32 mi2s_ebit_clk[MI2S_MAX] = { Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT, Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT, Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT, - Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT }; struct dev_config { @@ -180,6 +183,7 @@ enum { TDM_SEC, TDM_TERT, TDM_QUAT, + TDM_QUIN, TDM_INTERFACE_MAX, }; @@ -229,7 +233,18 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUIN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ } + }; /* TDM default config */ @@ -273,7 +288,18 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUIN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ } + }; /* Default configuration of slimbus channels */ @@ -329,6 +355,7 @@ static struct dev_config mi2s_rx_cfg[] = { [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, }; static struct dev_config mi2s_tx_cfg[] = { @@ -336,6 +363,7 @@ static struct dev_config mi2s_tx_cfg[] = { [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; static struct dev_config aux_pcm_rx_cfg[] = { @@ -343,6 +371,7 @@ static struct dev_config aux_pcm_rx_cfg[] = { [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; static struct dev_config aux_pcm_tx_cfg[] = { @@ -350,6 +379,7 @@ static struct dev_config aux_pcm_tx_cfg[] = { [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; static int msm_vi_feed_tx_ch = 2; static const char *const slim_rx_ch_text[] = {"One", "Two"}; @@ -435,18 +465,22 @@ static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); @@ -455,6 +489,8 @@ static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); @@ -510,7 +546,16 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = { Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, } + }; static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; @@ -1658,6 +1703,9 @@ static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, } else if (strnstr(kcontrol->id.name, "QUAT", sizeof(kcontrol->id.name))) { port->mode = TDM_QUAT; + } else if (strnstr(kcontrol->id.name, "QUIN", + sizeof(kcontrol->id.name))) { + port->mode = TDM_QUIN; } else { pr_err("%s: unsupported mode in: %s", __func__, kcontrol->id.name); @@ -2013,6 +2061,9 @@ static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", sizeof("QUAT_AUX_PCM"))) idx = QUAT_AUX_PCM; + else if (strnstr(kcontrol->id.name, "QUIN_AUX_PCM", + sizeof("QUIN_AUX_PCM"))) + idx = QUIN_AUX_PCM; else { pr_err("%s: unsupported port: %s", __func__, kcontrol->id.name); @@ -2110,6 +2161,9 @@ static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", sizeof("QUAT_MI2S_RX"))) idx = QUAT_MI2S; + else if (strnstr(kcontrol->id.name, "QUIN_MI2S_RX", + sizeof("QUIN_MI2S_RX"))) + idx = QUIN_MI2S; else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", sizeof("PRIM_MI2S_TX"))) idx = PRIM_MI2S; @@ -2122,6 +2176,9 @@ static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", sizeof("QUAT_MI2S_TX"))) idx = QUAT_MI2S; + else if (strnstr(kcontrol->id.name, "QUIN_MI2S_TX", + sizeof("QUIN_MI2S_TX"))) + idx = QUIN_MI2S; else { pr_err("%s: unsupported channel: %s", __func__, kcontrol->id.name); @@ -2663,6 +2720,24 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, tdm_tx_ch_get, tdm_tx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, aux_pcm_rx_sample_rate_get, aux_pcm_rx_sample_rate_put), @@ -2675,6 +2750,9 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate, aux_pcm_rx_sample_rate_get, aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_RX SampleRate", quin_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, aux_pcm_tx_sample_rate_get, aux_pcm_tx_sample_rate_put), @@ -2687,6 +2765,9 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, aux_pcm_tx_sample_rate_get, aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_TX SampleRate", quin_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, mi2s_rx_sample_rate_get, mi2s_rx_sample_rate_put), @@ -2699,6 +2780,9 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, mi2s_rx_sample_rate_get, mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_MI2S_RX SampleRate", quin_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, mi2s_tx_sample_rate_get, mi2s_tx_sample_rate_put), @@ -2711,6 +2795,9 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, mi2s_tx_sample_rate_get, mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_MI2S_TX SampleRate", quin_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, @@ -2727,6 +2814,10 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUIN_MI2S_RX Channels", quin_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUIN_MI2S_TX Channels", quin_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, @@ -2743,6 +2834,10 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), SOC_ENUM_EXT("QUAT_MI2S_TX Format", mi2s_tx_format, msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("QUIN_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("QUIN_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, @@ -2759,6 +2854,11 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), SOC_ENUM_EXT("QUAT_AUX_PCM_TX Format", aux_pcm_tx_format, msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + }; static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, @@ -3120,6 +3220,23 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; break; + case MSM_BACKEND_DAI_QUIN_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUIN_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_AUXPCM_RX: param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format); @@ -3192,6 +3309,24 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, aux_pcm_tx_cfg[QUAT_AUX_PCM].channels; break; + case MSM_BACKEND_DAI_QUIN_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[QUIN_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[QUIN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUIN_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUIN_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[QUIN_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[QUIN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUIN_AUX_PCM].channels; + break; + case MSM_BACKEND_DAI_PRI_MI2S_RX: param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, mi2s_rx_cfg[PRIM_MI2S].bit_format); @@ -3256,6 +3391,22 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, mi2s_tx_cfg[QUAT_MI2S].channels; break; + case MSM_BACKEND_DAI_QUINARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUIN_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[QUIN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUIN_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUIN_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[QUIN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUIN_MI2S].channels; + break; + default: rate->min = rate->max = SAMPLING_RATE_48KHZ; break; @@ -3772,6 +3923,12 @@ static int msm_get_port_id(int be_id) case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; break; + case MSM_BACKEND_DAI_QUINARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUINARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUINARY_MI2S_TX; + break; default: pr_err("%s: Invalid BE id: %d\n", __func__, be_id); afe_port_id = -EINVAL; @@ -4032,6 +4189,12 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + } else if (cpu_dai->id == AFE_PORT_ID_QUINARY_TDM_RX) { + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate; } else { pr_err("%s: dai id 0x%x not supported\n", __func__, cpu_dai->id); @@ -4072,6 +4235,9 @@ static int sdm855_tdm_snd_hw_params(struct snd_pcm_substream *substream, case AFE_PORT_ID_QUATERNARY_TDM_RX: slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; break; + case AFE_PORT_ID_QUINARY_TDM_RX: + slots = tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + break; case AFE_PORT_ID_PRIMARY_TDM_TX: slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels; break; @@ -4084,6 +4250,10 @@ static int sdm855_tdm_snd_hw_params(struct snd_pcm_substream *substream, case AFE_PORT_ID_QUATERNARY_TDM_TX: slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels; break; + case AFE_PORT_ID_QUINARY_TDM_TX: + slots = tdm_tx_cfg[TDM_QUIN][TDM_0].channels; + break; + default: pr_err("%s: dai id 0x%x not supported\n", __func__, cpu_dai->id); @@ -5599,6 +5769,36 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUIN_MI2S_RX, + .stream_name = "Quinary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_TX, + .stream_name = "Quinary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + }; static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { @@ -5713,6 +5913,34 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_suspend = 1, }, + /* Quinary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUIN_AUXPCM_RX, + .stream_name = "Quin AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_AUXPCM_TX, + .stream_name = "Quin AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link msm_pahu_snd_card_dai_links[ @@ -6338,7 +6566,6 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) { struct snd_soc_card *card; struct msm_asoc_mach_data *pdata; - const struct of_device_id *match; int ret; if (!pdev->dev.of_node) { @@ -6425,8 +6652,6 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) static int msm_asoc_machine_remove(struct platform_device *pdev) { - struct snd_soc_card *card = platform_get_drvdata(pdev); - audio_notifier_deregister("sdm855"); msm_i2s_auxpcm_deinit(); -- GitLab From 65b73c8f025532cf0413f2edb96d68f287678fcf Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Thu, 22 Feb 2018 21:49:35 -0800 Subject: [PATCH 0171/1645] audio: uapi: create audio_kernel_headers target Create a audio_kernel_headers target so that all audio UAPI header files can be copied to the right target specific OUT directory and make it easy for clients to mark dependency on the header files. Change-Id: I09ca422cbdd067e6e56fff13deaa4e92de3de1fc Signed-off-by: Banajit Goswami --- Android.mk | 1 + include/uapi/Android.mk | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 include/uapi/Android.mk diff --git a/Android.mk b/Android.mk index 74058a1cb1fb..6b4894bbf0f6 100644 --- a/Android.mk +++ b/Android.mk @@ -14,6 +14,7 @@ $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Modul $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers) +include $(MY_LOCAL_PATH)/include/uapi/Android.mk include $(MY_LOCAL_PATH)/ipc/Android.mk include $(MY_LOCAL_PATH)/dsp/Android.mk include $(MY_LOCAL_PATH)/dsp/codecs/Android.mk diff --git a/include/uapi/Android.mk b/include/uapi/Android.mk new file mode 100644 index 000000000000..36bcfdefae32 --- /dev/null +++ b/include/uapi/Android.mk @@ -0,0 +1,28 @@ +# Use this by setting +# LOCAL_HEADER_LIBRARIES := audio_kernel_headers + +LOCAL_PATH := $(call my-dir) +MYLOCAL_PATH := $(LOCAL_PATH) + +UAPI_OUT := $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/include + +AUDIO_KERNEL_HEADERS := $(call all-named-files-under,*.h,linux) $(call all-named-files-under,*.h,sound) + +HEADER_INSTALL_DIR := kernel/msm-$(TARGET_KERNEL_VERSION)/scripts + +BUILD_ROOT_RELATIVE := ../../../../../../../ + +include $(CLEAR_VARS) +LOCAL_MODULE := audio_kernel_headers +LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_PREBUILT_INT_KERNEL) + +GEN := $(addprefix $(UAPI_OUT)/,$(AUDIO_KERNEL_HEADERS)) +$(GEN): PRIVATE_PATH := $(MYLOCAL_PATH) +$(GEN): PRIVATE_CUSTOM_TOOL = $(shell cd $(PRODUCT_OUT)/obj/KERNEL_OBJ; $(BUILD_ROOT_RELATIVE)$(HEADER_INSTALL_DIR)/headers_install.sh $(BUILD_ROOT_RELATIVE)$(dir $@) $(BUILD_ROOT_RELATIVE)$(subst $(UAPI_OUT),$(MYLOCAL_PATH),$(dir $@)) $(notdir $@)) +$(GEN): $(addprefix $(MYLOCAL_PATH)/,$(AUDIO_KERNEL_HEADERS)) + $(transform-generated-source) + +LOCAL_GENERATED_SOURCES := $(GEN) +LOCAL_EXPORT_C_INCLUDE_DIRS := $(UAPI_OUT) + +include $(BUILD_HEADER_LIBRARY) -- GitLab From 7aeddaf315e114aed44d6c66e0bb20c62a638262 Mon Sep 17 00:00:00 2001 From: Vaishnavi Kommaraju Date: Wed, 21 Feb 2018 14:58:47 +0530 Subject: [PATCH 0172/1645] ASoC: wcd934x-dsp-cntl: Limit array size of val Limit size of val to WCD_MISCDEV_CMD_MAX_LEN to avoid stack overflow. CRs-Fixed: 2177167 Change-Id: I5d2b91e92305d6a485b2e8f959036504f0f55b13 Signed-off-by: Vaishnavi Kommaraju --- asoc/codecs/wcd934x/wcd934x-dsp-cntl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c index 35e12244cbfa..58987ad02ce8 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1007,7 +1007,7 @@ static ssize_t wcd_miscdev_write(struct file *filep, const char __user *ubuf, { struct wcd_dsp_cntl *cntl = container_of(filep->private_data, struct wcd_dsp_cntl, miscdev); - char val[count]; + char val[WCD_MISCDEV_CMD_MAX_LEN]; bool vote; int ret = 0; -- GitLab From 0754cfc272cb458167c76a7f82e3204f48f484dc Mon Sep 17 00:00:00 2001 From: Vaishnavi Kommaraju Date: Fri, 23 Feb 2018 11:55:08 +0530 Subject: [PATCH 0173/1645] ASoC: wcd9360-dsp-cntl: Limit array size of val Limit size of val to WCD_MISCDEV_CMD_MAX_LEN to avoid stack overflow. CRs-Fixed: 2177167 Change-Id: Ia0f5e3c5a786d06dbb7f0523a1d1919e93081f69 Signed-off-by: Vaishnavi Kommaraju --- asoc/codecs/wcd9360/wcd9360-dsp-cntl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c b/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c index 5a67aa62cd20..1110e04e48ed 100644 --- a/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c +++ b/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c @@ -31,6 +31,7 @@ #define WCD_PROCFS_ENTRY_MAX_LEN 16 #define WCD_9360_RAMDUMP_START_ADDR 0x20100000 #define WCD_9360_RAMDUMP_SIZE ((1024 * 1024) - 128) +#define WCD_MISCDEV_CMD_MAX_LEN 2 #define WCD_CNTL_MUTEX_LOCK(codec, lock) \ { \ @@ -893,11 +894,11 @@ static ssize_t wcd_miscdev_write(struct file *filep, const char __user *ubuf, { struct wcd_dsp_cntl *cntl = container_of(filep->private_data, struct wcd_dsp_cntl, miscdev); - char val[count]; + char val[WCD_MISCDEV_CMD_MAX_LEN]; bool vote; int ret = 0; - if (count == 0 || count > 2) { + if (count == 0 || count > WCD_MISCDEV_CMD_MAX_LEN) { pr_err("%s: Invalid count = %zd\n", __func__, count); ret = -EINVAL; goto done; -- GitLab From 8ed1b0ebcd64cbe5f4cb32e30935607bf0fbe841 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Fri, 23 Feb 2018 01:45:28 -0800 Subject: [PATCH 0174/1645] ipc: remove UAPI header copy The UAPI headers will be copied from the include/uapi directory. Remove support to copy the header files from ipc location. Change-Id: Ie7e92942e476fdfd16c0b0d226c40e90ae9da0c4 Signed-off-by: Banajit Goswami --- ipc/Kbuild | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/ipc/Kbuild b/ipc/Kbuild index 5c9c49254d95..aad47b47b071 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -112,38 +112,7 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ KBUILD_CPPFLAGS += $(CDEFINES) ifeq ($(KERNEL_BUILD), 0) - -HEADER_INSTALL_DIR := $(TOP)/kernel/msm-$(TARGET_KERNEL_VERSION)/scripts -UAPI_OUT := $(OUT)/obj/vendor/qcom/opensource/audio-kernel/include -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ avtimer.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_aac.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_ac3.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_alac.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_amrnb.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_amrwb.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_amrwbplus.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_ape.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_calibration.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_g711_dec.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_g711.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_mvs.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_qcp.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_sbc.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_voicememo.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_wma.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_wmapro.h;) - -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ audio_effects.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ audio_slimslave.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ devdep_params.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ lsm_params.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ msmcal-hwdep.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ voice_params.h;) -$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ wcd-dsp-glink.h;) - KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers - endif # Currently, for versions of gcc which support it, the kernel Makefile -- GitLab From 95668549c873417af2252913ab60533a082b8e9e Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 22 Feb 2018 14:35:56 -0800 Subject: [PATCH 0175/1645] asoc: codecs: change mic bias enum names Change mic bias enum names to be specific to codec to avoid conflict with mbhc mic bias enum. Change-Id: I7bae83aafd72753eaedebd533364ec404a54977a Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd9360/wcd9360.c | 30 ++++++++++++++++-------------- asoc/codecs/wcd9360/wcd9360.h | 16 ++++++++-------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/asoc/codecs/wcd9360/wcd9360.c b/asoc/codecs/wcd9360/wcd9360.c index f0f6b47a08a9..5be55962157d 100644 --- a/asoc/codecs/wcd9360/wcd9360.c +++ b/asoc/codecs/wcd9360/wcd9360.c @@ -3250,16 +3250,16 @@ int pahu_micbias_control(struct snd_soc_codec *codec, } switch (micb_num) { - case MIC_BIAS_1: + case WCD9360_MIC_BIAS_1: micb_reg = WCD9360_ANA_MICB1; break; - case MIC_BIAS_2: + case WCD9360_MIC_BIAS_2: micb_reg = WCD9360_ANA_MICB2; break; - case MIC_BIAS_3: + case WCD9360_MIC_BIAS_3: micb_reg = WCD9360_ANA_MICB3; break; - case MIC_BIAS_4: + case WCD9360_MIC_BIAS_4: micb_reg = WCD9360_ANA_MICB4; break; default: @@ -3270,25 +3270,25 @@ int pahu_micbias_control(struct snd_soc_codec *codec, mutex_lock(&pahu->micb_lock); switch (req) { - case MICB_PULLUP_ENABLE: + case WCD9360_MICB_PULLUP_ENABLE: pahu->pullup_ref[micb_index]++; if ((pahu->pullup_ref[micb_index] == 1) && (pahu->micb_ref[micb_index] == 0)) snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); break; - case MICB_PULLUP_DISABLE: + case WCD9360_MICB_PULLUP_DISABLE: if (pahu->pullup_ref[micb_index] > 0) pahu->pullup_ref[micb_index]--; if ((pahu->pullup_ref[micb_index] == 0) && (pahu->micb_ref[micb_index] == 0)) snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); break; - case MICB_ENABLE: + case WCD9360_MICB_ENABLE: pahu->micb_ref[micb_index]++; if (pahu->micb_ref[micb_index] == 1) snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); break; - case MICB_DISABLE: + case WCD9360_MICB_DISABLE: if (pahu->micb_ref[micb_index] > 0) pahu->micb_ref[micb_index]--; if ((pahu->micb_ref[micb_index] == 0) && @@ -3319,13 +3319,13 @@ static int __pahu_codec_enable_micbias(struct snd_soc_dapm_widget *w, __func__, w->name, event); if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) - micb_num = MIC_BIAS_1; + micb_num = WCD9360_MIC_BIAS_1; else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2"))) - micb_num = MIC_BIAS_2; + micb_num = WCD9360_MIC_BIAS_2; else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3"))) - micb_num = MIC_BIAS_3; + micb_num = WCD9360_MIC_BIAS_3; else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4"))) - micb_num = MIC_BIAS_4; + micb_num = WCD9360_MIC_BIAS_4; else return -EINVAL; @@ -3335,14 +3335,16 @@ static int __pahu_codec_enable_micbias(struct snd_soc_dapm_widget *w, * Use ref count to handle micbias pullup * and enable requests */ - pahu_micbias_control(codec, micb_num, MICB_ENABLE, true); + pahu_micbias_control(codec, micb_num, WCD9360_MICB_ENABLE, + true); break; case SND_SOC_DAPM_POST_PMU: /* wait for cnp time */ usleep_range(1000, 1100); break; case SND_SOC_DAPM_POST_PMD: - pahu_micbias_control(codec, micb_num, MICB_DISABLE, true); + pahu_micbias_control(codec, micb_num, WCD9360_MICB_DISABLE, + true); break; }; diff --git a/asoc/codecs/wcd9360/wcd9360.h b/asoc/codecs/wcd9360/wcd9360.h index 32e542472319..21f4e73fff73 100644 --- a/asoc/codecs/wcd9360/wcd9360.h +++ b/asoc/codecs/wcd9360/wcd9360.h @@ -108,17 +108,17 @@ enum { }; enum { - MIC_BIAS_1 = 1, - MIC_BIAS_2, - MIC_BIAS_3, - MIC_BIAS_4 + WCD9360_MIC_BIAS_1 = 1, + WCD9360_MIC_BIAS_2, + WCD9360_MIC_BIAS_3, + WCD9360_MIC_BIAS_4 }; enum { - MICB_PULLUP_ENABLE, - MICB_PULLUP_DISABLE, - MICB_ENABLE, - MICB_DISABLE, + WCD9360_MICB_PULLUP_ENABLE, + WCD9360_MICB_PULLUP_DISABLE, + WCD9360_MICB_ENABLE, + WCD9360_MICB_DISABLE, }; /* -- GitLab From 585fa1240fd9aadd1ff3a329f6373370bb767d55 Mon Sep 17 00:00:00 2001 From: Phani Kumar Uppalapati Date: Wed, 24 Jan 2018 19:22:15 -0800 Subject: [PATCH 0176/1645] ASoC: msmnile: enable MBHC support for msmnile target Add MBHC calibration parameters and enable MBHC support for msmnile platform. Change-Id: I09be59f806833464dd2381f248fa715ddd5663c1 Signed-off-by: Phani Kumar Uppalapati --- asoc/sdm855.c | 131 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 111 insertions(+), 20 deletions(-) diff --git a/asoc/sdm855.c b/asoc/sdm855.c index 173055701529..5944a89c9bb7 100644 --- a/asoc/sdm855.c +++ b/asoc/sdm855.c @@ -35,6 +35,7 @@ #include "codecs/msm-cdc-pinctrl.h" #include "codecs/wcd9360/wcd9360.h" #include "codecs/wsa881x.h" +#include "codecs/wcd-mbhc-v2.h" #define DRV_NAME "sdm855-asoc-snd" @@ -57,6 +58,8 @@ #define SAMPLING_RATE_352P8KHZ 352800 #define SAMPLING_RATE_384KHZ 384000 +#define WCD9XXX_MBHC_DEF_RLOADS 5 + #define WSA8810_NAME_1 "wsa881x.20170211" #define WSA8810_NAME_2 "wsa881x.20170212" #define WCN_CDC_SLIM_RX_CH_MAX 2 @@ -156,6 +159,7 @@ struct msm_pinctrl_info { struct msm_asoc_mach_data { struct snd_info_entry *codec_root; struct msm_pinctrl_info pinctrl_info; + struct device_node *us_euro_gpio_p; /* used by pinctrl API */ }; struct msm_asoc_wcd93xx_codec { @@ -508,6 +512,32 @@ static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable, bool dapm); static int msm_wsa881x_init(struct snd_soc_component *component); +/* + * Need to report LINEIN + * if R/L channel impedance is larger than 5K ohm + */ +static struct wcd_mbhc_config wcd_mbhc_cfg = { + .read_fw_bin = false, + .calibration = NULL, + .detect_extn_cable = true, + .mono_stero_detection = false, + .swap_gnd_mic = NULL, + .hs_ext_micbias = true, + .key_code[0] = KEY_MEDIA, + .key_code[1] = KEY_VOICECOMMAND, + .key_code[2] = KEY_VOLUMEUP, + .key_code[3] = KEY_VOLUMEDOWN, + .key_code[4] = 0, + .key_code[5] = 0, + .key_code[6] = 0, + .key_code[7] = 0, + .linein_th = 5000, + .moisture_en = true, + .mbhc_micbias = MIC_BIAS_2, + .anc_micbias = MIC_BIAS_2, + .enable_anc_mic_detect = false, +}; + static struct snd_soc_dapm_route wcd_audio_paths[] = { {"MIC BIAS1", NULL, "MCLK TX"}, {"MIC BIAS3", NULL, "MCLK TX"}, @@ -3416,6 +3446,49 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return rc; } +static bool msm_usbc_swap_gnd_mic(struct snd_soc_codec *codec, bool active) +{ + return false; +} + +static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) +{ + int value = 0; + bool ret = false; + struct snd_soc_card *card; + struct msm_asoc_mach_data *pdata; + + if (!codec) { + pr_err("%s codec is NULL\n", __func__); + return false; + } + card = codec->component.card; + pdata = snd_soc_card_get_drvdata(card); + + if (!pdata) + return false; + + if (wcd_mbhc_cfg.enable_usbc_analog) + return msm_usbc_swap_gnd_mic(codec, active); + + /* if usbc is not defined, swap using us_euro_gpio_p */ + if (pdata->us_euro_gpio_p) { + value = msm_cdc_pinctrl_get_state( + pdata->us_euro_gpio_p); + if (value) + msm_cdc_pinctrl_select_sleep_state( + pdata->us_euro_gpio_p); + else + msm_cdc_pinctrl_select_active_state( + pdata->us_euro_gpio_p); + dev_dbg(codec->dev, "%s: swap select switch %d to %d\n", + __func__, value, !value); + ret = true; + } + + return ret; +} + static int msm_afe_set_config(struct snd_soc_codec *codec) { int ret = 0; @@ -5954,28 +6027,8 @@ static struct snd_soc_dai_link msm_pahu_snd_card_dai_links[ ARRAY_SIZE(msm_mi2s_be_dai_links) + ARRAY_SIZE(msm_auxpcm_be_dai_links)]; -static int msm_snd_card_pahu_late_probe(struct snd_soc_card *card) -{ - const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; - struct snd_soc_pcm_runtime *rtd; - int ret = 0; - - rtd = snd_soc_get_pcm_runtime(card, be_dl_name); - if (!rtd) { - dev_err(card->dev, - "%s: snd_soc_get_pcm_runtime for %s failed!\n", - __func__, be_dl_name); - ret = -EINVAL; - goto err; - } - -err: - return ret; -} - struct snd_soc_card snd_soc_card_pahu_msm = { .name = "sdm855-pahu-snd-card", - .late_probe = msm_snd_card_pahu_late_probe, }; static int msm_populate_dai_link_component_of_node( @@ -6566,6 +6619,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) { struct snd_soc_card *card; struct msm_asoc_mach_data *pdata; + const char *mbhc_audio_jack_type = NULL; int ret; if (!pdev->dev.of_node) { @@ -6624,6 +6678,43 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Sound card %s registered\n", card->name); spdev = pdev; + ret = of_property_read_string(pdev->dev.of_node, + "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type); + if (ret) { + dev_dbg(&pdev->dev, "Looking up %s property in node %s failed\n", + "qcom,mbhc-audio-jack-type", + pdev->dev.of_node->full_name); + dev_dbg(&pdev->dev, "Jack type properties set to default\n"); + } else { + if (!strcmp(mbhc_audio_jack_type, "4-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = false; + dev_dbg(&pdev->dev, "This hardware has 4 pole jack"); + } else if (!strcmp(mbhc_audio_jack_type, "5-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = true; + dev_dbg(&pdev->dev, "This hardware has 5 pole jack"); + } else if (!strcmp(mbhc_audio_jack_type, "6-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = true; + dev_dbg(&pdev->dev, "This hardware has 6 pole jack"); + } else { + wcd_mbhc_cfg.enable_anc_mic_detect = false; + dev_dbg(&pdev->dev, "Unknown value, set to default\n"); + } + } + /* + * Parse US-Euro gpio info from DT. Report no error if us-euro + * entry is not found in DT file as some targets do not support + * US-Euro detection + */ + pdata->us_euro_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,us-euro-gpios", 0); + if (!pdata->us_euro_gpio_p) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,us-euro-gpios", pdev->dev.of_node->full_name); + } else { + dev_dbg(&pdev->dev, "%s detected\n", + "qcom,us-euro-gpios"); + wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; + } /* Parse pinctrl info from devicetree */ ret = msm_get_pinctrl(pdev); if (!ret) { -- GitLab From c50fe78896fd12af84339dca5012e2facf28b4cc Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 1 Mar 2018 04:38:30 +0530 Subject: [PATCH 0177/1645] ASoC: AQT1000: Disable AQT1000 codec driver on msmnile target Disable AQT1000 codec driver compilation on msmnile target. Change-Id: I55d47e7f29f26883eb045e0946e870fc67a0960a Signed-off-by: Sudheer Papothi --- asoc/codecs/aqt1000/Android.mk | 2 +- config/sdm855auto.conf | 1 - config/sdm855autoconf.h | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/asoc/codecs/aqt1000/Android.mk b/asoc/codecs/aqt1000/Android.mk index 63635da80746..7de1a63def8c 100644 --- a/asoc/codecs/aqt1000/Android.mk +++ b/asoc/codecs/aqt1000/Android.mk @@ -2,7 +2,7 @@ AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,sdm670 msmnile),true) +ifeq ($(call is-board-platform-in-list,sdm670),true) LOCAL_PATH := $(call my-dir) diff --git a/config/sdm855auto.conf b/config/sdm855auto.conf index 2ebdce0379a4..5257790c6173 100644 --- a/config/sdm855auto.conf +++ b/config/sdm855auto.conf @@ -35,4 +35,3 @@ CONFIG_DTS_SRS_TM=m CONFIG_SND_SOC_MSM_STUB=m CONFIG_MSM_AVTIMER=m CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m -CONFIG_SND_SOC_AQT1000=m diff --git a/config/sdm855autoconf.h b/config/sdm855autoconf.h index 651b04a49a04..593934adfee0 100644 --- a/config/sdm855autoconf.h +++ b/config/sdm855autoconf.h @@ -47,4 +47,3 @@ #define CONFIG_SND_SOC_MSM_STUB 1 #define CONFIG_MSM_AVTIMER 1 #define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 -#define CONFIG_SND_SOC_AQT1000 1 -- GitLab From aa0da7448df3047778a2481189ac8a30ab6ba555 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Wed, 28 Feb 2018 15:13:50 -0800 Subject: [PATCH 0178/1645] asoc: codecs: add wcd9360_regmap to the core Add wcd9360_regmap file compilation in the wcd_core dlkm to fix symbols mismatch. Change-Id: I666efc51e9e0eccccc7c3e6c57a456045b37824c Signed-off-by: Vidyakumar Athota --- asoc/codecs/Kbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 015164eb21e6..be4072bba8d8 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -74,6 +74,7 @@ ifdef CONFIG_WCD9XXX_CODEC_CORE CORE_OBJS += msm-cdc-supply.o CORE_OBJS += wcd934x/wcd934x-regmap.o CORE_OBJS += wcd934x/wcd934x-tables.o + CORE_OBJS += wcd9360/wcd9360-regmap.o endif ifdef CONFIG_SND_SOC_WCD9XXX_V2 -- GitLab From 57d3b66e17894874c5e60619a1929ebfb7208290 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 11 Dec 2017 15:37:06 -0800 Subject: [PATCH 0179/1645] asoc: codecs: Add i2c interface support for tavil Add i2c driver node for tavil codec for i2c communication with the codec. Change-Id: Ie28dfeca102251265a5f50153c3ba98dae84dde2 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd9xxx-core.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index 54f3eae0e62e..d3231a2833c1 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -51,7 +51,7 @@ * Number of return values needs to be checked for each * registration of Slimbus of I2C bus for each codec */ -#define NUM_WCD9XXX_REG_RET 4 +#define NUM_WCD9XXX_REG_RET 5 #define SLIM_USR_MC_REPEAT_CHANGE_VALUE 0x0 #define SLIM_REPEAT_WRITE_MAX_SLICE 16 @@ -92,6 +92,8 @@ static const int wcd9xxx_cdc_types[] = { }; static const struct of_device_id wcd9xxx_of_match[] = { + { .compatible = "qcom,tavil-i2c", + .data = (void *)&wcd9xxx_cdc_types[WCD934X]}, { .compatible = "qcom,tasha-i2c-pgd", .data = (void *)&wcd9xxx_cdc_types[WCD9335]}, { .compatible = "qcom,wcd9xxx-i2c", @@ -1625,6 +1627,11 @@ static struct i2c_device_id tasha_id_table[] = { {} }; +static struct i2c_device_id tavil_id_table[] = { + {"tavil-i2c", WCD9XXX_I2C_TOP_LEVEL}, + {} +}; + static struct i2c_device_id tabla_id_table[] = { {"tabla top level", WCD9XXX_I2C_TOP_LEVEL}, {"tabla analog", WCD9XXX_I2C_ANALOG}, @@ -1672,6 +1679,17 @@ static struct i2c_driver wcd9335_i2c_driver = { .remove = wcd9xxx_i2c_remove, }; +static struct i2c_driver wcd934x_i2c_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "tavil-i2c-core", + .pm = &wcd9xxx_i2c_pm_ops, + }, + .id_table = tavil_id_table, + .probe = wcd9xxx_i2c_probe, + .remove = wcd9xxx_i2c_remove, +}; + int wcd9xxx_init(void) { int ret[NUM_WCD9XXX_REG_RET] = {0}; @@ -1699,6 +1717,11 @@ int wcd9xxx_init(void) pr_err("%s: Failed to register wcd SB driver: %d\n", __func__, ret[3]); + ret[4] = i2c_add_driver(&wcd934x_i2c_driver); + if (ret[4]) + pr_err("%s: Failed to add the wcd934x I2C driver: %d\n", + __func__, ret[4]); + for (i = 0; i < NUM_WCD9XXX_REG_RET; i++) { if (ret[i]) return ret[i]; @@ -1714,6 +1737,7 @@ void wcd9xxx_exit(void) i2c_del_driver(&tabla_i2c_driver); i2c_del_driver(&wcd9xxx_i2c_driver); i2c_del_driver(&wcd9335_i2c_driver); + i2c_del_driver(&wcd934x_i2c_driver); slim_driver_unregister(&wcd_slim_driver); } -- GitLab From 98d3d590bbf8345827b513c94d7b750d1199db1b Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 12 Sep 2017 12:23:32 -0700 Subject: [PATCH 0180/1645] asoc: codecs: enable i2s mode for tavil Add support for tavil i2c access. Add audio routings dapm widgets for data and control. Change-Id: I96ebf7a5700b10f294f4fadfeeb21dab490a9313 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd934x/wcd934x-routing.h | 143 +++- asoc/codecs/wcd934x/wcd934x.c | 930 ++++++++++++++++++++++++-- 2 files changed, 966 insertions(+), 107 deletions(-) diff --git a/asoc/codecs/wcd934x/wcd934x-routing.h b/asoc/codecs/wcd934x/wcd934x-routing.h index 93a1ad3bab90..8adeef79a7f0 100644 --- a/asoc/codecs/wcd934x/wcd934x-routing.h +++ b/asoc/codecs/wcd934x/wcd934x-routing.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -17,13 +17,9 @@ const struct snd_soc_dapm_route tavil_slim_audio_map[] = { - /* Virtual input widgets */ - {"AIF1 CAP", NULL, "AIF1_CAP Mixer"}, - {"AIF2 CAP", NULL, "AIF2_CAP Mixer"}, - {"AIF3 CAP", NULL, "AIF3_CAP Mixer"}, {"AIF4 MAD", NULL, "AIF4_MAD Mixer"}, - /* Virtual input widget Mixer */ + /* Virtual input widget Mixer SLIMBUS*/ {"AIF1_CAP Mixer", "SLIM TX0", "SLIM TX0"}, {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1"}, {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2"}, @@ -68,6 +64,21 @@ const struct snd_soc_dapm_route tavil_slim_audio_map[] = { {"AIF4_MAD Mixer", "SLIM TX13", "SLIM TX13"}, + /* CDC Tx interface with SLIMBUS */ + {"SLIM TX0", NULL, "CDC_IF TX0 MUX"}, + {"SLIM TX1", NULL, "CDC_IF TX1 MUX"}, + {"SLIM TX2", NULL, "CDC_IF TX2 MUX"}, + {"SLIM TX3", NULL, "CDC_IF TX3 MUX"}, + {"SLIM TX4", NULL, "CDC_IF TX4 MUX"}, + {"SLIM TX5", NULL, "CDC_IF TX5 MUX"}, + {"SLIM TX6", NULL, "CDC_IF TX6 MUX"}, + {"SLIM TX7", NULL, "CDC_IF TX7 MUX"}, + {"SLIM TX8", NULL, "CDC_IF TX8 MUX"}, + {"SLIM TX9", NULL, "CDC_IF TX9 MUX"}, + {"SLIM TX10", NULL, "CDC_IF TX10 MUX"}, + {"SLIM TX11", NULL, "CDC_IF TX11 MUX"}, + {"SLIM TX13", NULL, "CDC_IF TX13 MUX"}, + {"SLIM RX0 MUX", "AIF1_PB", "AIF1 PB"}, {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"}, {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"}, @@ -113,10 +124,100 @@ const struct snd_soc_dapm_route tavil_slim_audio_map[] = { {"SLIM RX6", NULL, "SLIM RX6 MUX"}, {"SLIM RX7", NULL, "SLIM RX7 MUX"}, + /* CDC Rx interface with SLIMBUS */ + {"CDC_IF RX0 MUX", "SLIM RX0", "SLIM RX0"}, + {"CDC_IF RX1 MUX", "SLIM RX1", "SLIM RX1"}, + {"CDC_IF RX2 MUX", "SLIM RX2", "SLIM RX2"}, + {"CDC_IF RX3 MUX", "SLIM RX3", "SLIM RX3"}, + {"CDC_IF RX4 MUX", "SLIM RX4", "SLIM RX4"}, + {"CDC_IF RX5 MUX", "SLIM RX5", "SLIM RX5"}, + {"CDC_IF RX6 MUX", "SLIM RX6", "SLIM RX6"}, + {"CDC_IF RX7 MUX", "SLIM RX7", "SLIM RX7"}, + + /* VI Feedback */ + {"AIF4_VI Mixer", "SPKR_VI_1", "VIINPUT"}, + {"AIF4_VI Mixer", "SPKR_VI_2", "VIINPUT"}, + {"AIF4 VI", NULL, "AIF4_VI Mixer"}, + +}; + +const struct snd_soc_dapm_route tavil_i2s_audio_map[] = { + + /* Virtual input widget Mixer I2S*/ + {"AIF1_CAP Mixer", "I2S TX1", "I2S TX1"}, + {"AIF1_CAP Mixer", "I2S TX2", "I2S TX2"}, + {"AIF1_CAP Mixer", "I2S TX3", "I2S TX3"}, + {"AIF1_CAP Mixer", "I2S TX4", "I2S TX4"}, + {"AIF1_CAP Mixer", "I2S TX5", "I2S TX5"}, + {"AIF1_CAP Mixer", "I2S TX6", "I2S TX6"}, + {"AIF1_CAP Mixer", "I2S TX7", "I2S TX7"}, + + {"AIF2_CAP Mixer", "I2S TX8", "I2S TX8"}, + {"AIF2_CAP Mixer", "I2S TX11", "I2S TX11"}, + + {"AIF3_CAP Mixer", "I2S TX0", "I2S TX0"}, + {"AIF3_CAP Mixer", "I2S TX1", "I2S TX1"}, + + /* CDC Tx interface with I2S */ + {"I2S TX0", NULL, "CDC_IF TX0 MUX"}, + {"I2S TX1", NULL, "CDC_IF TX1 MUX"}, + {"I2S TX2", NULL, "CDC_IF TX2 MUX"}, + {"I2S TX3", NULL, "CDC_IF TX3 MUX"}, + {"I2S TX4", NULL, "CDC_IF TX4 MUX"}, + {"I2S TX5", NULL, "CDC_IF TX5 MUX"}, + {"I2S TX6", NULL, "CDC_IF TX6 MUX"}, + {"I2S TX7", NULL, "CDC_IF TX7 MUX"}, + {"I2S TX8", NULL, "CDC_IF TX8 MUX"}, + {"I2S TX11", NULL, "CDC_IF TX11 MUX"}, + + {"I2S RX0 MUX", "AIF1_PB", "AIF1 PB"}, + {"I2S RX1 MUX", "AIF1_PB", "AIF1 PB"}, + {"I2S RX2 MUX", "AIF1_PB", "AIF1 PB"}, + {"I2S RX3 MUX", "AIF1_PB", "AIF1 PB"}, + {"I2S RX4 MUX", "AIF1_PB", "AIF1 PB"}, + {"I2S RX5 MUX", "AIF1_PB", "AIF1 PB"}, + {"I2S RX6 MUX", "AIF1_PB", "AIF1 PB"}, + {"I2S RX7 MUX", "AIF1_PB", "AIF1 PB"}, + + {"I2S RX2 MUX", "AIF2_PB", "AIF2 PB"}, + {"I2S RX3 MUX", "AIF2_PB", "AIF2 PB"}, + + {"I2S RX4 MUX", "AIF3_PB", "AIF3 PB"}, + {"I2S RX5 MUX", "AIF3_PB", "AIF3 PB"}, + + {"I2S RX0", NULL, "I2S RX0 MUX"}, + {"I2S RX1", NULL, "I2S RX1 MUX"}, + {"I2S RX2", NULL, "I2S RX2 MUX"}, + {"I2S RX3", NULL, "I2S RX3 MUX"}, + {"I2S RX4", NULL, "I2S RX4 MUX"}, + {"I2S RX5", NULL, "I2S RX5 MUX"}, + {"I2S RX6", NULL, "I2S RX6 MUX"}, + {"I2S RX7", NULL, "I2S RX7 MUX"}, + + /* CDC Rx interface with I2S */ + {"CDC_IF RX0 MUX", "I2S RX0", "I2S RX0"}, + {"CDC_IF RX1 MUX", "I2S RX1", "I2S RX1"}, + {"CDC_IF RX2 MUX", "I2S RX2", "I2S RX2"}, + {"CDC_IF RX3 MUX", "I2S RX3", "I2S RX3"}, + {"CDC_IF RX4 MUX", "I2S RX4", "I2S RX4"}, + {"CDC_IF RX5 MUX", "I2S RX5", "I2S RX5"}, + {"CDC_IF RX6 MUX", "I2S RX6", "I2S RX6"}, + {"CDC_IF RX7 MUX", "I2S RX7", "I2S RX7"}, + }; const struct snd_soc_dapm_route tavil_audio_map[] = { + /* + * AIF CAP to Mixer routes are common + * for both SLIM as well as I2S + */ + + /* Virtual input widgets */ + {"AIF1 CAP", NULL, "AIF1_CAP Mixer"}, + {"AIF2 CAP", NULL, "AIF2_CAP Mixer"}, + {"AIF3 CAP", NULL, "AIF3_CAP Mixer"}, + /* WDMA3 */ {"WDMA3 PORT0 MUX", "DEC0", "ADC MUX0"}, {"WDMA3 PORT0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"}, @@ -195,26 +296,6 @@ const struct snd_soc_dapm_route tavil_audio_map[] = { {"MAD_CPE_OUT1", NULL, "MAD_CPE1"}, {"MAD_CPE_OUT2", NULL, "MAD_CPE2"}, - /* VI Feedback */ - {"AIF4_VI Mixer", "SPKR_VI_1", "VIINPUT"}, - {"AIF4_VI Mixer", "SPKR_VI_2", "VIINPUT"}, - {"AIF4 VI", NULL, "AIF4_VI Mixer"}, - - /* CDC Tx interface with SLIMBUS */ - {"SLIM TX0", NULL, "CDC_IF TX0 MUX"}, - {"SLIM TX1", NULL, "CDC_IF TX1 MUX"}, - {"SLIM TX2", NULL, "CDC_IF TX2 MUX"}, - {"SLIM TX3", NULL, "CDC_IF TX3 MUX"}, - {"SLIM TX4", NULL, "CDC_IF TX4 MUX"}, - {"SLIM TX5", NULL, "CDC_IF TX5 MUX"}, - {"SLIM TX6", NULL, "CDC_IF TX6 MUX"}, - {"SLIM TX7", NULL, "CDC_IF TX7 MUX"}, - {"SLIM TX8", NULL, "CDC_IF TX8 MUX"}, - {"SLIM TX9", NULL, "CDC_IF TX9 MUX"}, - {"SLIM TX10", NULL, "CDC_IF TX10 MUX"}, - {"SLIM TX11", NULL, "CDC_IF TX11 MUX"}, - {"SLIM TX13", NULL, "CDC_IF TX13 MUX"}, - {"CDC_IF TX0 MUX", "DEC0", "ADC MUX0"}, {"CDC_IF TX0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"}, {"CDC_IF TX0 MUX", "DEC0_192", "ADC US MUX0"}, @@ -568,16 +649,6 @@ const struct snd_soc_dapm_route tavil_audio_map[] = { {"ADC3", NULL, "AMIC3"}, {"ADC4", NULL, "AMIC4_5 SEL"}, - /* CDC Rx interface with SLIMBUS */ - {"CDC_IF RX0 MUX", "SLIM RX0", "SLIM RX0"}, - {"CDC_IF RX1 MUX", "SLIM RX1", "SLIM RX1"}, - {"CDC_IF RX2 MUX", "SLIM RX2", "SLIM RX2"}, - {"CDC_IF RX3 MUX", "SLIM RX3", "SLIM RX3"}, - {"CDC_IF RX4 MUX", "SLIM RX4", "SLIM RX4"}, - {"CDC_IF RX5 MUX", "SLIM RX5", "SLIM RX5"}, - {"CDC_IF RX6 MUX", "SLIM RX6", "SLIM RX6"}, - {"CDC_IF RX7 MUX", "SLIM RX7", "SLIM RX7"}, - {"RX INT0_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"}, {"RX INT0_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"}, {"RX INT0_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"}, diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index e7cec2b4d348..1be2f66ec7af 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1273,6 +1273,93 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, return 0; } +static int i2s_tx_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = tavil_p->tx_port_value; + return 0; +} + +static int i2s_tx_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_update *update = NULL; + struct soc_multi_mixer_control *mixer = + (struct soc_multi_mixer_control *)kcontrol->private_value; + u32 dai_id = widget->shift; + u32 port_id = mixer->shift; + u32 enable = ucontrol->value.integer.value[0]; + u32 vtable; + + dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", + __func__, + widget->name, ucontrol->id.name, tavil_p->tx_port_value, + widget->shift, ucontrol->value.integer.value[0]); + + mutex_lock(&tavil_p->codec_mutex); + if (dai_id >= ARRAY_SIZE(vport_slim_check_table)) { + dev_err(codec->dev, "%s: dai_id: %d, out of bounds\n", + __func__, dai_id); + mutex_unlock(&tavil_p->codec_mutex); + return -EINVAL; + } + vtable = vport_slim_check_table[dai_id]; + + switch (dai_id) { + case AIF1_CAP: + case AIF2_CAP: + case AIF3_CAP: + /* only add to the list if value not set */ + if (enable && !(tavil_p->tx_port_value & 1 << port_id)) { + if (wcd9xxx_tx_vport_validation(vtable, port_id, + tavil_p->dai, NUM_CODEC_DAIS)) { + dev_dbg(codec->dev, "%s: TX%u is used by other virtual port\n", + __func__, port_id); + mutex_unlock(&tavil_p->codec_mutex); + return 0; + } + tavil_p->tx_port_value |= 1 << port_id; + } else if (!enable && (tavil_p->tx_port_value & + 1 << port_id)) { + tavil_p->tx_port_value &= ~(1 << port_id); + } else { + if (enable) + dev_dbg(codec->dev, "%s: TX%u port is used by\n" + "this virtual port\n", + __func__, port_id); + else + dev_dbg(codec->dev, "%s: TX%u port is not used by\n" + "this virtual port\n", + __func__, port_id); + /* avoid update power function */ + mutex_unlock(&tavil_p->codec_mutex); + return 0; + } + break; + default: + dev_err(codec->dev, "Unknown AIF %d\n", dai_id); + mutex_unlock(&tavil_p->codec_mutex); + return -EINVAL; + } + dev_dbg(codec->dev, "%s: name %s sname %s updated value %u shift %d\n", + __func__, widget->name, widget->sname, tavil_p->tx_port_value, + widget->shift); + + mutex_unlock(&tavil_p->codec_mutex); + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update); + + return 0; +} + static int slim_rx_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1477,9 +1564,192 @@ static void tavil_codec_mute_dsd(struct snd_soc_codec *codec, } } -static int tavil_codec_enable_slimrx(struct snd_soc_dapm_widget *w, +static int tavil_codec_set_i2s_rx_ch(struct snd_soc_dapm_widget *w, + u32 i2s_reg, bool up) +{ + int rx_fs_rate = -EINVAL; + int i2s_bit_mode; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx_codec_dai_data *dai; + + dai = &tavil_p->dai[w->shift]; + dev_dbg(tavil_p->dev, "%s: %d up/down, %d width, %d rate\n", + __func__, up, dai->bit_width, dai->rate); + if (up) { + if (dai->bit_width == 16) + i2s_bit_mode = 0x01; + else + i2s_bit_mode = 0x00; + + switch (dai->rate) { + case 8000: + rx_fs_rate = 0; + break; + case 16000: + rx_fs_rate = 1; + break; + case 32000: + rx_fs_rate = 2; + break; + case 48000: + rx_fs_rate = 3; + break; + case 96000: + rx_fs_rate = 4; + break; + case 192000: + rx_fs_rate = 5; + break; + case 384000: + rx_fs_rate = 6; + break; + default: + dev_err(tavil_p->dev, "%s: Invalid RX sample rate: %d\n", + __func__, dai->rate); + return -EINVAL; + }; + snd_soc_update_bits(codec, i2s_reg, + 0x40, i2s_bit_mode << 6); + snd_soc_update_bits(codec, i2s_reg, + 0x3c, (rx_fs_rate << 2)); + } else { + snd_soc_update_bits(codec, i2s_reg, + 0x40, 0x00); + snd_soc_update_bits(codec, i2s_reg, + 0x3c, 0x00); + } + return 0; +} + +static int tavil_codec_set_i2s_tx_ch(struct snd_soc_dapm_widget *w, + u32 i2s_reg, bool up) +{ + int tx_fs_rate = -EINVAL; + int i2s_bit_mode; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx_codec_dai_data *dai; + + dai = &tavil_p->dai[w->shift]; + if (up) { + if (dai->bit_width == 16) + i2s_bit_mode = 0x01; + else + i2s_bit_mode = 0x00; + + snd_soc_update_bits(codec, i2s_reg, 0x40, i2s_bit_mode << 6); + + switch (dai->rate) { + case 8000: + tx_fs_rate = 0; + break; + case 16000: + tx_fs_rate = 1; + break; + case 32000: + tx_fs_rate = 2; + break; + case 48000: + tx_fs_rate = 3; + break; + case 96000: + tx_fs_rate = 4; + break; + case 192000: + tx_fs_rate = 5; + break; + case 384000: + tx_fs_rate = 6; + break; + default: + dev_err(tavil_p->dev, "%s: Invalid sample rate: %d\n", + __func__, dai->rate); + return -EINVAL; + }; + + snd_soc_update_bits(codec, i2s_reg, 0x3c, tx_fs_rate << 2); + + snd_soc_update_bits(codec, + WCD934X_DATA_HUB_I2S_TX0_CFG, + 0x03, 0x01); + + snd_soc_update_bits(codec, + WCD934X_DATA_HUB_I2S_TX0_CFG, + 0x0C, 0x01); + + snd_soc_update_bits(codec, + WCD934X_DATA_HUB_I2S_TX1_0_CFG, + 0x03, 0x01); + + snd_soc_update_bits(codec, + WCD934X_DATA_HUB_I2S_TX1_1_CFG, + 0x05, 0x05); + } else { + snd_soc_update_bits(codec, i2s_reg, 0x40, 0x00); + snd_soc_update_bits(codec, i2s_reg, 0x3c, 0x00); + + snd_soc_update_bits(codec, + WCD934X_DATA_HUB_I2S_TX0_CFG, + 0x03, 0x00); + + snd_soc_update_bits(codec, + WCD934X_DATA_HUB_I2S_TX0_CFG, + 0x0C, 0x00); + + snd_soc_update_bits(codec, + WCD934X_DATA_HUB_I2S_TX1_0_CFG, + 0x03, 0x00); + + snd_soc_update_bits(codec, + WCD934X_DATA_HUB_I2S_TX1_1_CFG, + 0x05, 0x00); + } + return 0; +} + +static int tavil_codec_enable_rx_i2c(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + int ret = -EINVAL; + u32 i2s_reg; + + switch (tavil_p->rx_port_value[w->shift]) { + case AIF1_PB: + case AIF1_CAP: + i2s_reg = WCD934X_DATA_HUB_I2S_0_CTL; + break; + case AIF2_PB: + case AIF2_CAP: + i2s_reg = WCD934X_DATA_HUB_I2S_1_CTL; + break; + case AIF3_PB: + case AIF3_CAP: + i2s_reg = WCD934X_DATA_HUB_I2S_2_CTL; + break; + default: + dev_err(codec->dev, "%s Invalid i2s Id received", __func__); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + ret = tavil_codec_set_i2s_rx_ch(w, i2s_reg, true); + break; + case SND_SOC_DAPM_POST_PMD: + ret = tavil_codec_set_i2s_rx_ch(w, i2s_reg, false); + break; + } + + return ret; +} + +static int tavil_codec_enable_rx(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) { struct wcd9xxx *core; struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); @@ -1499,6 +1769,11 @@ static int tavil_codec_enable_slimrx(struct snd_soc_dapm_widget *w, dev_dbg(codec->dev, "%s: w->name %s w->shift %d event %d\n", __func__, w->name, w->shift, event); + if (tavil_p->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { + ret = tavil_codec_enable_rx_i2c(w, kcontrol, event); + return ret; + } + switch (event) { case SND_SOC_DAPM_POST_PMU: dai->bus_down_in_recovery = false; @@ -1530,9 +1805,48 @@ static int tavil_codec_enable_slimrx(struct snd_soc_dapm_widget *w, return ret; } -static int tavil_codec_enable_slimtx(struct snd_soc_dapm_widget *w, +static int tavil_codec_enable_tx_i2c(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + int ret = -EINVAL; + u32 i2s_reg; + + switch (tavil_p->rx_port_value[w->shift]) { + case AIF1_PB: + case AIF1_CAP: + i2s_reg = WCD934X_DATA_HUB_I2S_0_CTL; + break; + case AIF2_PB: + case AIF2_CAP: + i2s_reg = WCD934X_DATA_HUB_I2S_1_CTL; + break; + case AIF3_PB: + case AIF3_CAP: + i2s_reg = WCD934X_DATA_HUB_I2S_2_CTL; + break; + default: + dev_err(codec->dev, "%s Invalid i2s Id received", __func__); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + ret = tavil_codec_set_i2s_tx_ch(w, i2s_reg, true); + break; + case SND_SOC_DAPM_POST_PMD: + ret = tavil_codec_set_i2s_tx_ch(w, i2s_reg, false); + break; + } + + return ret; +} + +static int tavil_codec_enable_tx(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); @@ -1548,6 +1862,11 @@ static int tavil_codec_enable_slimtx(struct snd_soc_dapm_widget *w, dai = &tavil_p->dai[w->shift]; core = dev_get_drvdata(codec->dev->parent); + if (tavil_p->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { + ret = tavil_codec_enable_tx_i2c(w, kcontrol, event); + return ret; + } + switch (event) { case SND_SOC_DAPM_POST_PMU: dai->bus_down_in_recovery = false; @@ -2234,6 +2553,83 @@ static int tavil_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w, return 0; } +static int i2s_rx_mux_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = + tavil_p->rx_port_value[widget->shift]; + return 0; +} + +static int i2s_rx_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + unsigned int rx_port_value; + u32 port_id = widget->shift; + + tavil_p->rx_port_value[port_id] = ucontrol->value.enumerated.item[0]; + rx_port_value = tavil_p->rx_port_value[port_id]; + + dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", + __func__, widget->name, ucontrol->id.name, + rx_port_value, widget->shift, + ucontrol->value.integer.value[0]); + + snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, + rx_port_value, e, update); + return 0; +} + +static int tavil_codec_enable_i2s_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + int ret = 0; + u32 i2s_reg; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + + switch (tavil_p->rx_port_value[w->shift]) { + case AIF1_PB: + case AIF1_CAP: + i2s_reg = WCD934X_DATA_HUB_I2S_0_CTL; + break; + case AIF2_PB: + case AIF2_CAP: + i2s_reg = WCD934X_DATA_HUB_I2S_1_CTL; + break; + case AIF3_PB: + case AIF3_CAP: + i2s_reg = WCD934X_DATA_HUB_I2S_2_CTL; + break; + default: + dev_err(codec->dev, "%s Invalid i2s Id received", __func__); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = snd_soc_update_bits(codec, i2s_reg, 0x01, 0x01); + break; + case SND_SOC_DAPM_POST_PMD: + ret = snd_soc_update_bits(codec, i2s_reg, 0x01, 0x00); + break; + } + + return ret; +} + static int tavil_codec_ear_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -6285,29 +6681,45 @@ static const char *const slim_rx_mux_text[] = { "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB" }; +static const char *const i2s_rx01_mux_text[] = { + "ZERO", "AIF1_PB" +}; + +static const char *const i2s_rx23_mux_text[] = { + "ZERO", "AIF1_PB", "AIF2_PB" +}; + +static const char *const i2s_rx45_mux_text[] = { + "ZERO", "AIF1_PB", "AIF3_PB" +}; + +static const char *const i2s_rx67_mux_text[] = { + "ZERO", "AIF1_PB" +}; + static const char *const cdc_if_rx0_mux_text[] = { - "SLIM RX0", "I2S_0 RX0" + "SLIM RX0", "I2S RX0" }; static const char *const cdc_if_rx1_mux_text[] = { - "SLIM RX1", "I2S_0 RX1" + "SLIM RX1", "I2S RX1" }; static const char *const cdc_if_rx2_mux_text[] = { - "SLIM RX2", "I2S_0 RX2" + "SLIM RX2", "I2S RX2" }; static const char *const cdc_if_rx3_mux_text[] = { - "SLIM RX3", "I2S_0 RX3" + "SLIM RX3", "I2S RX3" }; static const char *const cdc_if_rx4_mux_text[] = { - "SLIM RX4", "I2S_0 RX4" + "SLIM RX4", "I2S RX4" }; static const char *const cdc_if_rx5_mux_text[] = { - "SLIM RX5", "I2S_0 RX5" + "SLIM RX5", "I2S RX5" }; static const char *const cdc_if_rx6_mux_text[] = { - "SLIM RX6", "I2S_0 RX6" + "SLIM RX6", "I2S RX6" }; static const char *const cdc_if_rx7_mux_text[] = { - "SLIM RX7", "I2S_0 RX7" + "SLIM RX7", "I2S RX7" }; static const char * const asrc0_mux_text[] = { @@ -6370,7 +6782,7 @@ static const struct snd_kcontrol_new aif4_vi_mixer[] = { tavil_vi_feed_mixer_get, tavil_vi_feed_mixer_put), }; -static const struct snd_kcontrol_new aif1_cap_mixer[] = { +static const struct snd_kcontrol_new aif1_slim_cap_mixer[] = { SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD934X_TX0, 1, 0, slim_tx_mixer_get, slim_tx_mixer_put), SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD934X_TX1, 1, 0, @@ -6399,7 +6811,24 @@ static const struct snd_kcontrol_new aif1_cap_mixer[] = { slim_tx_mixer_get, slim_tx_mixer_put), }; -static const struct snd_kcontrol_new aif2_cap_mixer[] = { +static const struct snd_kcontrol_new aif1_i2s_cap_mixer[] = { + SOC_SINGLE_EXT("I2S TX1", SND_SOC_NOPM, WCD934X_TX1, 1, 0, + i2s_tx_mixer_get, i2s_tx_mixer_put), + SOC_SINGLE_EXT("I2S TX2", SND_SOC_NOPM, WCD934X_TX2, 1, 0, + i2s_tx_mixer_get, i2s_tx_mixer_put), + SOC_SINGLE_EXT("I2S TX3", SND_SOC_NOPM, WCD934X_TX3, 1, 0, + i2s_tx_mixer_get, i2s_tx_mixer_put), + SOC_SINGLE_EXT("I2S TX4", SND_SOC_NOPM, WCD934X_TX4, 1, 0, + i2s_tx_mixer_get, i2s_tx_mixer_put), + SOC_SINGLE_EXT("I2S TX5", SND_SOC_NOPM, WCD934X_TX5, 1, 0, + i2s_tx_mixer_get, i2s_tx_mixer_put), + SOC_SINGLE_EXT("I2S TX6", SND_SOC_NOPM, WCD934X_TX6, 1, 0, + i2s_tx_mixer_get, i2s_tx_mixer_put), + SOC_SINGLE_EXT("I2S TX7", SND_SOC_NOPM, WCD934X_TX7, 1, 0, + i2s_tx_mixer_get, i2s_tx_mixer_put), +}; + +static const struct snd_kcontrol_new aif2_slim_cap_mixer[] = { SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD934X_TX0, 1, 0, slim_tx_mixer_get, slim_tx_mixer_put), SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD934X_TX1, 1, 0, @@ -6428,7 +6857,14 @@ static const struct snd_kcontrol_new aif2_cap_mixer[] = { slim_tx_mixer_get, slim_tx_mixer_put), }; -static const struct snd_kcontrol_new aif3_cap_mixer[] = { +static const struct snd_kcontrol_new aif2_i2s_cap_mixer[] = { + SOC_SINGLE_EXT("I2S TX8", SND_SOC_NOPM, WCD934X_TX8, 1, 0, + i2s_tx_mixer_get, i2s_tx_mixer_put), + SOC_SINGLE_EXT("I2S TX11", SND_SOC_NOPM, WCD934X_TX11, 1, 0, + i2s_tx_mixer_get, i2s_tx_mixer_put), +}; + +static const struct snd_kcontrol_new aif3_slim_cap_mixer[] = { SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD934X_TX0, 1, 0, slim_tx_mixer_get, slim_tx_mixer_put), SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD934X_TX1, 1, 0, @@ -6457,9 +6893,16 @@ static const struct snd_kcontrol_new aif3_cap_mixer[] = { slim_tx_mixer_get, slim_tx_mixer_put), }; -static const struct snd_kcontrol_new aif4_mad_mixer[] = { +static const struct snd_kcontrol_new aif3_i2s_cap_mixer[] = { + SOC_SINGLE_EXT("I2S TX0", SND_SOC_NOPM, WCD934X_TX0, 1, 0, + i2s_tx_mixer_get, i2s_tx_mixer_put), + SOC_SINGLE_EXT("I2S TX1", SND_SOC_NOPM, WCD934X_TX1, 1, 0, + i2s_tx_mixer_get, i2s_tx_mixer_put), +}; + +static const struct snd_kcontrol_new aif4_slim_mad_mixer[] = { SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD934X_TX13, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), + slim_tx_mixer_get, slim_tx_mixer_put), }; WCD_DAPM_ENUM_EXT(slim_rx0, SND_SOC_NOPM, 0, slim_rx_mux_text, @@ -6768,6 +7211,22 @@ WCD_DAPM_ENUM(int8_2_native, SND_SOC_NOPM, 0, native_mux_text); WCD_DAPM_ENUM(anc0_fb, WCD934X_CDC_RX_INP_MUX_ANC_CFG0, 0, anc0_fb_mux_text); WCD_DAPM_ENUM(anc1_fb, WCD934X_CDC_RX_INP_MUX_ANC_CFG0, 3, anc1_fb_mux_text); +WCD_DAPM_ENUM_EXT(i2s_rx0, SND_SOC_NOPM, 0, i2s_rx01_mux_text, + i2s_rx_mux_get, i2s_rx_mux_put); +WCD_DAPM_ENUM_EXT(i2s_rx1, SND_SOC_NOPM, 0, i2s_rx01_mux_text, + i2s_rx_mux_get, i2s_rx_mux_put); +WCD_DAPM_ENUM_EXT(i2s_rx2, SND_SOC_NOPM, 0, i2s_rx23_mux_text, + i2s_rx_mux_get, i2s_rx_mux_put); +WCD_DAPM_ENUM_EXT(i2s_rx3, SND_SOC_NOPM, 0, i2s_rx23_mux_text, + i2s_rx_mux_get, i2s_rx_mux_put); +WCD_DAPM_ENUM_EXT(i2s_rx4, SND_SOC_NOPM, 0, i2s_rx45_mux_text, + i2s_rx_mux_get, i2s_rx_mux_put); +WCD_DAPM_ENUM_EXT(i2s_rx5, SND_SOC_NOPM, 0, i2s_rx45_mux_text, + i2s_rx_mux_get, i2s_rx_mux_put); +WCD_DAPM_ENUM_EXT(i2s_rx6, SND_SOC_NOPM, 0, i2s_rx67_mux_text, + i2s_rx_mux_get, i2s_rx_mux_put); +WCD_DAPM_ENUM_EXT(i2s_rx7, SND_SOC_NOPM, 0, i2s_rx67_mux_text, + i2s_rx_mux_get, i2s_rx_mux_put); WCD_DAPM_ENUM(wdma3_port0, WCD934X_DMA_WDMA3_PRT_CFG, 0, wdma3_port0_text); WCD_DAPM_ENUM(wdma3_port1, WCD934X_DMA_WDMA3_PRT_CFG, 1, wdma3_port1_text); @@ -6852,6 +7311,89 @@ static const struct snd_kcontrol_new rx_int4_asrc_switch[] = { static const struct snd_kcontrol_new wdma3_onoff_switch = SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); +static const struct snd_soc_dapm_widget tavil_dapm_i2s_widgets[] = { + + SND_SOC_DAPM_MUX_E("I2S RX0 MUX", SND_SOC_NOPM, WCD934X_RX0, 0, + &i2s_rx0_mux, tavil_codec_enable_i2s_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("I2S RX1 MUX", SND_SOC_NOPM, WCD934X_RX1, 0, + &i2s_rx1_mux, tavil_codec_enable_i2s_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("I2S RX2 MUX", SND_SOC_NOPM, WCD934X_RX2, 0, + &i2s_rx2_mux, tavil_codec_enable_i2s_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("I2S RX3 MUX", SND_SOC_NOPM, WCD934X_RX3, 0, + &i2s_rx3_mux, tavil_codec_enable_i2s_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("I2S RX4 MUX", SND_SOC_NOPM, WCD934X_RX4, 0, + &i2s_rx4_mux, tavil_codec_enable_i2s_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("I2S RX5 MUX", SND_SOC_NOPM, WCD934X_RX5, 0, + &i2s_rx5_mux, tavil_codec_enable_i2s_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("I2S RX6 MUX", SND_SOC_NOPM, WCD934X_RX6, 0, + &i2s_rx6_mux, tavil_codec_enable_i2s_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("I2S RX7 MUX", SND_SOC_NOPM, WCD934X_RX7, 0, + &i2s_rx7_mux, tavil_codec_enable_i2s_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER("I2S RX0", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I2S RX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I2S RX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I2S RX3", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I2S RX4", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I2S RX5", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I2S RX6", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I2S RX7", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MIXER_E("I2S TX0", SND_SOC_NOPM, WCD934X_TX0, 0, NULL, 0, + tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("I2S TX1", SND_SOC_NOPM, WCD934X_TX1, 0, NULL, 0, + tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("I2S TX2", SND_SOC_NOPM, WCD934X_TX2, 0, NULL, 0, + tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("I2S TX3", SND_SOC_NOPM, WCD934X_TX3, 0, NULL, 0, + tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("I2S TX4", SND_SOC_NOPM, WCD934X_TX4, 0, NULL, 0, + tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("I2S TX5", SND_SOC_NOPM, WCD934X_TX5, 0, NULL, 0, + tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("I2S TX6", SND_SOC_NOPM, WCD934X_TX6, 0, NULL, 0, + tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("I2S TX7", SND_SOC_NOPM, WCD934X_TX7, 0, NULL, 0, + tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("I2S TX8", SND_SOC_NOPM, WCD934X_TX8, 0, NULL, 0, + tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("I2S TX11", SND_SOC_NOPM, WCD934X_TX11, 0, NULL, 0, + tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0, + aif1_i2s_cap_mixer, ARRAY_SIZE(aif1_i2s_cap_mixer)), + SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0, + aif2_i2s_cap_mixer, ARRAY_SIZE(aif2_i2s_cap_mixer)), + SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0, + aif3_i2s_cap_mixer, ARRAY_SIZE(aif3_i2s_cap_mixer)), +}; + static int tavil_dsd_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -6917,19 +7459,22 @@ static const struct snd_kcontrol_new lo2_mixer[] = { tavil_dsd_mixer_get, tavil_dsd_mixer_put), }; -static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = { - SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM, - AIF1_PB, 0, tavil_codec_enable_slimrx, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM, - AIF2_PB, 0, tavil_codec_enable_slimrx, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM, - AIF3_PB, 0, tavil_codec_enable_slimrx, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), +static const struct snd_soc_dapm_widget tavil_dapm_slim_widgets[] = { SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM, - AIF4_PB, 0, tavil_codec_enable_slimrx, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + AIF4_PB, 0, tavil_codec_enable_rx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM, + AIF4_VIFEED, 0, + tavil_codec_enable_slimvi_feedback, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_AIF_OUT("AIF4 MAD", "AIF4 MAD TX", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_MIXER("AIF4_VI Mixer", SND_SOC_NOPM, AIF4_VIFEED, 0, + aif4_vi_mixer, ARRAY_SIZE(aif4_vi_mixer)), + SND_SOC_DAPM_INPUT("VIINPUT"), WCD_DAPM_MUX("SLIM RX0 MUX", WCD934X_RX0, slim_rx0), WCD_DAPM_MUX("SLIM RX1 MUX", WCD934X_RX1, slim_rx1), @@ -6949,6 +7494,31 @@ static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = { SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0, + aif1_slim_cap_mixer, + ARRAY_SIZE(aif1_slim_cap_mixer)), + SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0, + aif2_slim_cap_mixer, + ARRAY_SIZE(aif2_slim_cap_mixer)), + SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0, + aif3_slim_cap_mixer, + ARRAY_SIZE(aif3_slim_cap_mixer)), + SND_SOC_DAPM_MIXER("AIF4_MAD Mixer", SND_SOC_NOPM, AIF4_MAD_TX, 0, + aif4_slim_mad_mixer, + ARRAY_SIZE(aif4_slim_mad_mixer)), +}; + +static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM, + AIF1_PB, 0, tavil_codec_enable_rx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM, + AIF2_PB, 0, tavil_codec_enable_rx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM, + AIF3_PB, 0, tavil_codec_enable_rx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + WCD_DAPM_MUX("CDC_IF RX0 MUX", WCD934X_RX0, cdc_if_rx0), WCD_DAPM_MUX("CDC_IF RX1 MUX", WCD934X_RX1, cdc_if_rx1), WCD_DAPM_MUX("CDC_IF RX2 MUX", WCD934X_RX2, cdc_if_rx2), @@ -7237,33 +7807,14 @@ static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM, - AIF1_CAP, 0, tavil_codec_enable_slimtx, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + AIF1_CAP, 0, tavil_codec_enable_tx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM, - AIF2_CAP, 0, tavil_codec_enable_slimtx, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + AIF2_CAP, 0, tavil_codec_enable_tx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM, - AIF3_CAP, 0, tavil_codec_enable_slimtx, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0, - aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)), - SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0, - aif2_cap_mixer, ARRAY_SIZE(aif2_cap_mixer)), - SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0, - aif3_cap_mixer, ARRAY_SIZE(aif3_cap_mixer)), - SND_SOC_DAPM_MIXER("AIF4_MAD Mixer", SND_SOC_NOPM, AIF4_MAD_TX, 0, - aif4_mad_mixer, ARRAY_SIZE(aif4_mad_mixer)), - - SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM, - AIF4_VIFEED, 0, tavil_codec_enable_slimvi_feedback, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_AIF_OUT("AIF4 MAD", "AIF4 MAD TX", 0, - SND_SOC_NOPM, 0, 0), - - SND_SOC_DAPM_MIXER("AIF4_VI Mixer", SND_SOC_NOPM, AIF4_VIFEED, 0, - aif4_vi_mixer, ARRAY_SIZE(aif4_vi_mixer)), - SND_SOC_DAPM_INPUT("VIINPUT"), + AIF3_CAP, 0, tavil_codec_enable_tx, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MIXER("SLIM TX0", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("SLIM TX1", SND_SOC_NOPM, 0, 0, NULL, 0), @@ -8047,6 +8598,46 @@ static int tavil_hw_params(struct snd_pcm_substream *substream, return 0; } +static int tavil_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(dai->codec); + u32 i2s_reg; + + switch (dai->id) { + case AIF1_PB: + case AIF1_CAP: + i2s_reg = WCD934X_DATA_HUB_I2S_0_CTL; + break; + case AIF2_PB: + case AIF2_CAP: + i2s_reg = WCD934X_DATA_HUB_I2S_1_CTL; + break; + case AIF3_PB: + case AIF3_CAP: + i2s_reg = WCD934X_DATA_HUB_I2S_2_CTL; + break; + default: + dev_err(dai->codec->dev, "%s Invalid i2s Id", __func__); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + /* CPU is master */ + if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) + snd_soc_update_bits(dai->codec, i2s_reg, 0x2, 0x0); + break; + case SND_SOC_DAIFMT_CBM_CFM: + /* CPU is slave */ + if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) + snd_soc_update_bits(dai->codec, i2s_reg, 0x2, 0x2); + break; + default: + return -EINVAL; + } + return 0; +} + static struct snd_soc_dai_ops tavil_dai_ops = { .startup = tavil_startup, .shutdown = tavil_shutdown, @@ -8056,13 +8647,21 @@ static struct snd_soc_dai_ops tavil_dai_ops = { .get_channel_map = tavil_get_channel_map, }; +static struct snd_soc_dai_ops tavil_i2s_dai_ops = { + .startup = tavil_startup, + .shutdown = tavil_shutdown, + .hw_params = tavil_hw_params, + .prepare = tavil_prepare, + .set_fmt = tavil_set_dai_fmt, +}; + static struct snd_soc_dai_ops tavil_vi_dai_ops = { .hw_params = tavil_vi_hw_params, .set_channel_map = tavil_set_channel_map, .get_channel_map = tavil_get_channel_map, }; -static struct snd_soc_dai_driver tavil_dai[] = { +static struct snd_soc_dai_driver tavil_slim_dai[] = { { .name = "tavil_rx1", .id = AIF1_PB, @@ -8191,6 +8790,93 @@ static struct snd_soc_dai_driver tavil_dai[] = { }, }; +static struct snd_soc_dai_driver tavil_i2s_dai[] = { + { + .name = "tavil_i2s_rx1", + .id = AIF1_PB, + .playback = { + .stream_name = "AIF1 Playback", + .rates = WCD934X_RATES_MASK, + .formats = WCD934X_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tavil_i2s_dai_ops, + }, + { + .name = "tavil_i2s_tx1", + .id = AIF1_CAP, + .capture = { + .stream_name = "AIF1 Capture", + .rates = WCD934X_RATES_MASK, + .formats = WCD934X_FORMATS_S16_S24_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tavil_i2s_dai_ops, + }, + { + .name = "tavil_i2s_rx2", + .id = AIF2_PB, + .playback = { + .stream_name = "AIF2 Playback", + .rates = WCD934X_RATES_MASK, + .formats = WCD934X_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tavil_i2s_dai_ops, + }, + { + .name = "tavil_i2s_tx2", + .id = AIF2_CAP, + .capture = { + .stream_name = "AIF2 Capture", + .rates = WCD934X_RATES_MASK, + .formats = WCD934X_FORMATS_S16_S24_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tavil_i2s_dai_ops, + }, + { + .name = "tavil_i2s_rx3", + .id = AIF3_PB, + .playback = { + .stream_name = "AIF3 Playback", + .rates = WCD934X_RATES_MASK, + .formats = WCD934X_FORMATS_S16_S24_S32_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tavil_i2s_dai_ops, + }, + { + .name = "tavil_i2s_tx3", + .id = AIF3_CAP, + .capture = { + .stream_name = "AIF3 Capture", + .rates = WCD934X_RATES_MASK, + .formats = WCD934X_FORMATS_S16_S24_LE, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &tavil_i2s_dai_ops, + }, +}; + static void tavil_codec_power_gate_digital_core(struct tavil_priv *tavil) { mutex_lock(&tavil->power_lock); @@ -8747,6 +9433,22 @@ static void tavil_codec_init_reg(struct tavil_priv *priv) } } +static const struct tavil_reg_mask_val tavil_codec_reg_i2c_defaults[] = { + {WCD934X_CLK_SYS_MCLK_PRG, 0x40, 0x00}, + {WCD934X_CODEC_RPM_CLK_GATE, 0x03, 0x01}, + {WCD934X_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x00}, + {WCD934X_CODEC_RPM_CLK_MCLK_CFG, 0x05, 0x05}, + {WCD934X_DATA_HUB_RX0_CFG, 0x71, 0x31}, + {WCD934X_DATA_HUB_RX1_CFG, 0x71, 0x31}, + {WCD934X_DATA_HUB_RX2_CFG, 0x03, 0x01}, + {WCD934X_DATA_HUB_RX3_CFG, 0x03, 0x01}, + {WCD934X_DATA_HUB_I2S_TX0_CFG, 0x01, 0x01}, + {WCD934X_DATA_HUB_I2S_TX0_CFG, 0x04, 0x01}, + {WCD934X_DATA_HUB_I2S_TX1_0_CFG, 0x01, 0x01}, + {WCD934X_DATA_HUB_I2S_TX1_1_CFG, 0x05, 0x05}, + {WCD934X_CHIP_TIER_CTRL_ALT_FUNC_EN, 0x1, 0x1}, +}; + static void tavil_update_reg_defaults(struct tavil_priv *tavil) { u32 i; @@ -8758,6 +9460,15 @@ static void tavil_update_reg_defaults(struct tavil_priv *tavil) tavil_codec_reg_defaults[i].reg, tavil_codec_reg_defaults[i].mask, tavil_codec_reg_defaults[i].val); + + if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { + for (i = 0; i < ARRAY_SIZE(tavil_codec_reg_i2c_defaults); i++) { + regmap_update_bits(wcd9xxx->regmap, + tavil_codec_reg_i2c_defaults[i].reg, + tavil_codec_reg_i2c_defaults[i].mask, + tavil_codec_reg_i2c_defaults[i].val); + } + } } static void tavil_update_cpr_defaults(struct tavil_priv *tavil) @@ -9402,19 +10113,33 @@ static int tavil_soc_codec_probe(struct snd_soc_codec *codec) goto err_hwdep; } - snd_soc_dapm_add_routes(dapm, tavil_slim_audio_map, - ARRAY_SIZE(tavil_slim_audio_map)); + if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) + snd_soc_dapm_new_controls(dapm, tavil_dapm_i2s_widgets, + ARRAY_SIZE(tavil_dapm_i2s_widgets)); + else + snd_soc_dapm_new_controls(dapm, tavil_dapm_slim_widgets, + ARRAY_SIZE(tavil_dapm_slim_widgets)); + + if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) + snd_soc_dapm_add_routes(dapm, tavil_slim_audio_map, + ARRAY_SIZE(tavil_slim_audio_map)); + else + snd_soc_dapm_add_routes(dapm, tavil_i2s_audio_map, + ARRAY_SIZE(tavil_i2s_audio_map)); + for (i = 0; i < NUM_CODEC_DAIS; i++) { INIT_LIST_HEAD(&tavil->dai[i].wcd9xxx_ch_list); init_waitqueue_head(&tavil->dai[i].dai_wait); } - tavil_slimbus_slave_port_cfg.slave_dev_intfdev_la = - control->slim_slave->laddr; - tavil_slimbus_slave_port_cfg.slave_dev_pgd_la = - control->slim->laddr; - tavil_slimbus_slave_port_cfg.slave_port_mapping[0] = - WCD934X_TX13; - tavil_init_slim_slave_cfg(codec); + if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) { + tavil_slimbus_slave_port_cfg.slave_dev_intfdev_la = + control->slim_slave->laddr; + tavil_slimbus_slave_port_cfg.slave_dev_pgd_la = + control->slim->laddr; + tavil_slimbus_slave_port_cfg.slave_port_mapping[0] = + WCD934X_TX13; + tavil_init_slim_slave_cfg(codec); + } control->num_rx_port = WCD934X_RX_MAX; control->rx_chs = ptr; @@ -9469,9 +10194,11 @@ static int tavil_soc_codec_probe(struct snd_soc_codec *codec) snd_soc_dapm_ignore_suspend(dapm, "AIF2 Capture"); snd_soc_dapm_ignore_suspend(dapm, "AIF3 Playback"); snd_soc_dapm_ignore_suspend(dapm, "AIF3 Capture"); - snd_soc_dapm_ignore_suspend(dapm, "AIF4 Playback"); - snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX"); - snd_soc_dapm_ignore_suspend(dapm, "VIfeed"); + if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) { + snd_soc_dapm_ignore_suspend(dapm, "AIF4 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX"); + snd_soc_dapm_ignore_suspend(dapm, "VIfeed"); + } snd_soc_dapm_sync(dapm); @@ -9577,6 +10304,39 @@ static const struct dev_pm_ops tavil_pm_ops = { }; #endif +static int wcd9xxx_swrm_i2c_bulk_write(struct wcd9xxx *wcd9xxx, + struct wcd9xxx_reg_val *bulk_reg, + size_t len) +{ + int i, ret = 0; + unsigned short swr_wr_addr_base; + unsigned short swr_wr_data_base; + + swr_wr_addr_base = WCD934X_SWR_AHB_BRIDGE_WR_ADDR_0; + swr_wr_data_base = WCD934X_SWR_AHB_BRIDGE_WR_DATA_0; + + for (i = 0; i < (len * 2); i += 2) { + /* First Write the Data to register */ + ret = regmap_bulk_write(wcd9xxx->regmap, + swr_wr_data_base, bulk_reg[i].buf, 4); + if (ret < 0) { + dev_err(wcd9xxx->dev, "%s: WR Data Failure\n", + __func__); + break; + } + /* Next Write Address */ + ret = regmap_bulk_write(wcd9xxx->regmap, + swr_wr_addr_base, + bulk_reg[i+1].buf, 4); + if (ret < 0) { + dev_err(wcd9xxx->dev, "%s: WR Addr Failure\n", + __func__); + break; + } + } + return ret; +} + static int tavil_swrm_read(void *handle, int reg) { struct tavil_priv *tavil; @@ -9655,8 +10415,11 @@ static int tavil_swrm_bulk_write(void *handle, u32 *reg, u32 *val, size_t len) } mutex_lock(&tavil->swr.write_mutex); - ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, - (len * 2), false); + if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) + ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, + (len * 2), false); + else + ret = wcd9xxx_swrm_i2c_bulk_write(wcd9xxx, bulk_reg, len); if (ret) { dev_err(tavil->dev, "%s: swrm bulk write failed, ret: %d\n", __func__, ret); @@ -9695,7 +10458,10 @@ static int tavil_swrm_write(void *handle, int reg, int val) bulk_reg[1].bytes = 4; mutex_lock(&tavil->swr.write_mutex); - ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, 2, false); + if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) + ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, 2, false); + else + ret = wcd9xxx_swrm_i2c_bulk_write(wcd9xxx, bulk_reg, 1); if (ret < 0) dev_err(tavil->dev, "%s: WR Data Failure\n", __func__); mutex_unlock(&tavil->swr.write_mutex); @@ -10081,6 +10847,21 @@ static int tavil_probe(struct platform_device *pdev) if (!tavil) return -ENOMEM; + tavil->intf_type = wcd9xxx_get_intf_type(); + if (tavil->intf_type != WCD9XXX_INTERFACE_TYPE_I2C && + tavil->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) { + devm_kfree(&pdev->dev, tavil); + return -EPROBE_DEFER; + } + + if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { + if (apr_get_subsys_state() == APR_SUBSYS_DOWN) { + dev_err(&pdev->dev, "%s: dsp down\n", __func__); + devm_kfree(&pdev->dev, tavil); + return -EPROBE_DEFER; + } + } + platform_set_drvdata(pdev, tavil); tavil->wcd9xxx = dev_get_drvdata(pdev->dev.parent); @@ -10161,8 +10942,15 @@ static int tavil_probe(struct platform_device *pdev) tavil_update_cpr_defaults(tavil); /* Register with soc framework */ - ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tavil, - tavil_dai, ARRAY_SIZE(tavil_dai)); + if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) + ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tavil, + tavil_i2s_dai, + ARRAY_SIZE(tavil_i2s_dai)); + else + ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tavil, + tavil_slim_dai, + ARRAY_SIZE(tavil_slim_dai)); + if (ret) { dev_err(&pdev->dev, "%s: Codec registration failed\n", __func__); -- GitLab From f164580248d4e22484e1cbbd87310b92bac7fd97 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 20 Dec 2017 19:47:32 -0800 Subject: [PATCH 0181/1645] asoc: codecs: Fix tavil i2s max rate and cleanup Change i2s max rate supported for tavil to 384000Hz. Cleanup usage of intf_type to optimize differentiation between slim and i2s. Change-Id: If6451dae7c61e8f61be3d5a13549f98b382e5054 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd934x/wcd934x.c | 53 +++++++++++++++-------------------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 1be2f66ec7af..5e67cde28e1f 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -6682,19 +6682,19 @@ static const char *const slim_rx_mux_text[] = { }; static const char *const i2s_rx01_mux_text[] = { - "ZERO", "AIF1_PB" + "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB" }; static const char *const i2s_rx23_mux_text[] = { - "ZERO", "AIF1_PB", "AIF2_PB" + "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB" }; static const char *const i2s_rx45_mux_text[] = { - "ZERO", "AIF1_PB", "AIF3_PB" + "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB" }; static const char *const i2s_rx67_mux_text[] = { - "ZERO", "AIF1_PB" + "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB" }; static const char *const cdc_if_rx0_mux_text[] = { @@ -8600,7 +8600,6 @@ static int tavil_hw_params(struct snd_pcm_substream *substream, static int tavil_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) { - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(dai->codec); u32 i2s_reg; switch (dai->id) { @@ -8624,13 +8623,11 @@ static int tavil_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: /* CPU is master */ - if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) - snd_soc_update_bits(dai->codec, i2s_reg, 0x2, 0x0); + snd_soc_update_bits(dai->codec, i2s_reg, 0x2, 0x0); break; case SND_SOC_DAIFMT_CBM_CFM: /* CPU is slave */ - if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) - snd_soc_update_bits(dai->codec, i2s_reg, 0x2, 0x2); + snd_soc_update_bits(dai->codec, i2s_reg, 0x2, 0x2); break; default: return -EINVAL; @@ -8799,7 +8796,7 @@ static struct snd_soc_dai_driver tavil_i2s_dai[] = { .rates = WCD934X_RATES_MASK, .formats = WCD934X_FORMATS_S16_S24_S32_LE, .rate_min = 8000, - .rate_max = 192000, + .rate_max = 384000, .channels_min = 1, .channels_max = 2, }, @@ -8813,7 +8810,7 @@ static struct snd_soc_dai_driver tavil_i2s_dai[] = { .rates = WCD934X_RATES_MASK, .formats = WCD934X_FORMATS_S16_S24_LE, .rate_min = 8000, - .rate_max = 192000, + .rate_max = 384000, .channels_min = 1, .channels_max = 2, }, @@ -8827,7 +8824,7 @@ static struct snd_soc_dai_driver tavil_i2s_dai[] = { .rates = WCD934X_RATES_MASK, .formats = WCD934X_FORMATS_S16_S24_S32_LE, .rate_min = 8000, - .rate_max = 192000, + .rate_max = 384000, .channels_min = 1, .channels_max = 2, }, @@ -8841,7 +8838,7 @@ static struct snd_soc_dai_driver tavil_i2s_dai[] = { .rates = WCD934X_RATES_MASK, .formats = WCD934X_FORMATS_S16_S24_LE, .rate_min = 8000, - .rate_max = 192000, + .rate_max = 384000, .channels_min = 1, .channels_max = 2, }, @@ -8855,7 +8852,7 @@ static struct snd_soc_dai_driver tavil_i2s_dai[] = { .rates = WCD934X_RATES_MASK, .formats = WCD934X_FORMATS_S16_S24_S32_LE, .rate_min = 8000, - .rate_max = 192000, + .rate_max = 384000, .channels_min = 1, .channels_max = 2, }, @@ -8869,7 +8866,7 @@ static struct snd_soc_dai_driver tavil_i2s_dai[] = { .rates = WCD934X_RATES_MASK, .formats = WCD934X_FORMATS_S16_S24_LE, .rate_min = 8000, - .rate_max = 192000, + .rate_max = 384000, .channels_min = 1, .channels_max = 2, }, @@ -10113,25 +10110,16 @@ static int tavil_soc_codec_probe(struct snd_soc_codec *codec) goto err_hwdep; } - if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) - snd_soc_dapm_new_controls(dapm, tavil_dapm_i2s_widgets, - ARRAY_SIZE(tavil_dapm_i2s_widgets)); - else - snd_soc_dapm_new_controls(dapm, tavil_dapm_slim_widgets, - ARRAY_SIZE(tavil_dapm_slim_widgets)); - - if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) - snd_soc_dapm_add_routes(dapm, tavil_slim_audio_map, - ARRAY_SIZE(tavil_slim_audio_map)); - else - snd_soc_dapm_add_routes(dapm, tavil_i2s_audio_map, - ARRAY_SIZE(tavil_i2s_audio_map)); - for (i = 0; i < NUM_CODEC_DAIS; i++) { INIT_LIST_HEAD(&tavil->dai[i].wcd9xxx_ch_list); init_waitqueue_head(&tavil->dai[i].dai_wait); } + if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) { + snd_soc_dapm_new_controls(dapm, tavil_dapm_slim_widgets, + ARRAY_SIZE(tavil_dapm_slim_widgets)); + snd_soc_dapm_add_routes(dapm, tavil_slim_audio_map, + ARRAY_SIZE(tavil_slim_audio_map)); tavil_slimbus_slave_port_cfg.slave_dev_intfdev_la = control->slim_slave->laddr; tavil_slimbus_slave_port_cfg.slave_dev_pgd_la = @@ -10139,6 +10127,11 @@ static int tavil_soc_codec_probe(struct snd_soc_codec *codec) tavil_slimbus_slave_port_cfg.slave_port_mapping[0] = WCD934X_TX13; tavil_init_slim_slave_cfg(codec); + } else { + snd_soc_dapm_new_controls(dapm, tavil_dapm_i2s_widgets, + ARRAY_SIZE(tavil_dapm_i2s_widgets)); + snd_soc_dapm_add_routes(dapm, tavil_i2s_audio_map, + ARRAY_SIZE(tavil_i2s_audio_map)); } control->num_rx_port = WCD934X_RX_MAX; @@ -10856,7 +10849,7 @@ static int tavil_probe(struct platform_device *pdev) if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { if (apr_get_subsys_state() == APR_SUBSYS_DOWN) { - dev_err(&pdev->dev, "%s: dsp down\n", __func__); + dev_dbg(&pdev->dev, "%s: dsp down\n", __func__); devm_kfree(&pdev->dev, tavil); return -EPROBE_DEFER; } -- GitLab From 0575b6733a56fa73c02678752b3e78aa3e0cb7f3 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Sun, 10 Dec 2017 23:50:37 -0800 Subject: [PATCH 0182/1645] dsp: afe: Add 9.6MHz clock in osr clk list Add 9.6MHz osr clk frequency to support tavil mclk request. Change-Id: I79da9cf9ddb8588ca550956d9c07f751618741ac Signed-off-by: Karthikeyan Mani --- dsp/q6afe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index f926efbdc16b..255ebc27fb42 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -6507,6 +6507,7 @@ int q6afe_check_osr_clk_freq(u32 freq) switch (freq) { case Q6AFE_LPASS_OSR_CLK_12_P288_MHZ: + case Q6AFE_LPASS_OSR_CLK_9_P600_MHZ: case Q6AFE_LPASS_OSR_CLK_8_P192_MHZ: case Q6AFE_LPASS_OSR_CLK_6_P144_MHZ: case Q6AFE_LPASS_OSR_CLK_4_P096_MHZ: -- GitLab From 9f66f6f684c6ae4f141c9086f364a1a95d9346ea Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 13 Dec 2017 13:38:46 -0800 Subject: [PATCH 0183/1645] asoc: msm: Update routing and FE DAI drivers Update routing driver with port mixer commands between primary and secondary interfaces to enable AFE lopback between them. Update FE DAI driver to add hostless FEs for primary/secondary Auxpcm and secondary MI2S. Change-Id: I792e1cf4e0600d3b4726624e29e73e67828a3935 Signed-off-by: Viraja Kommaraju Signed-off-by: Karthikeyan Mani --- asoc/msm-dai-fe.c | 30 ++++++++++++++++++++++++++++++ asoc/msm-pcm-routing-v2.c | 22 ++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index 72883eb80641..b086fa6e97ec 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -696,6 +696,36 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "AUXPCM_HOSTLESS", .probe = fe_dai_probe, }, + { + .playback = { + .stream_name = "SEC_AUXPCM_HOSTLESS Playback", + .aif_name = "SEC_AUXPCM_DL_HL", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_min = 8000, + .rate_max = 16000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_AUXPCM_RX_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "SEC_AUXPCM_HOSTLESS Capture", + .aif_name = "SEC_AUXPCM_UL_HL", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_min = 8000, + .rate_max = 16000, + }, + .ops = &msm_fe_dai_ops, + .name = "SEC_AUXPCM_TX_HOSTLESS", + .probe = fe_dai_probe, + }, { .playback = { .stream_name = "VOICE_STUB Playback", diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index ef446087ac49..ff2be80b13e6 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -8949,6 +8949,9 @@ static const struct snd_kcontrol_new aux_pcm_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_AUXPCM_RX, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sec_auxpcm_rx_port_mixer_controls[] = { @@ -8961,6 +8964,9 @@ static const struct snd_kcontrol_new sec_auxpcm_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new tert_auxpcm_rx_port_mixer_controls[] = { @@ -9151,6 +9157,9 @@ static const struct snd_kcontrol_new primary_mi2s_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new usb_rx_port_mixer_controls[] = { @@ -10922,6 +10931,9 @@ static const struct snd_kcontrol_new sec_mi2s_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new lsm1_mixer_controls[] = { @@ -12382,6 +12394,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("AUXPCM_UL_HL", "AUXPCM_HOSTLESS Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_AUXPCM_DL_HL", "SEC_AUXPCM_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_AUXPCM_UL_HL", "SEC_AUXPCM_HOSTLESS Capture", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MI2S_UL_HL", "MI2S_TX_HOSTLESS Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("INT3_MI2S_UL_HL", @@ -15314,7 +15330,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"HFP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"}, {"AUX_PCM_RX", NULL, "AUXPCM_DL_HL"}, {"AUX_PCM_RX", NULL, "INTHFP_DL_HL"}, + {"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_DL_HL"}, {"AUXPCM_UL_HL", NULL, "AUX_PCM_TX"}, + {"SEC_AUXPCM_UL_HL", NULL, "SEC_AUX_PCM_TX"}, {"MI2S_RX", NULL, "MI2S_DL_HL"}, {"MI2S_UL_HL", NULL, "MI2S_TX"}, {"PCM_RX_DL_HL", "Switch", "SLIM0_DL_HL"}, @@ -15885,11 +15903,13 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUX_PCM_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"AUX_PCM_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, {"AUX_PCM_RX Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"AUX_PCM_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"AUX_PCM_RX", NULL, "AUX_PCM_RX Port Mixer"}, {"SEC_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"SEC_AUXPCM_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, {"SEC_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"SEC_AUXPCM_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_RX Port Mixer"}, {"TERT_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, @@ -16030,6 +16050,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"PRI_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"PRI_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"PRI_MI2S_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Port Mixer"}, {"SEC_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -16040,6 +16061,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"SEC_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"SEC_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"SEC_MI2S_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Port Mixer"}, {"TERT_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, -- GitLab From ef9ded2e710f77b45c8d5a6e9db1ccab62abf5ae Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Wed, 17 Jan 2018 11:30:35 -0800 Subject: [PATCH 0184/1645] asoc: wcd_cpe_core: add size check for WDSP ELF files Add size check to make sure the data sizes from WDSP ELF metadata and the split firmware ELF are the same. Change-Id: I7a1404cd15601d8d503e3355e6dc70e2949df72d Signed-off-by: Xiaoyu Ye --- asoc/codecs/wcd_cpe_core.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd_cpe_core.c b/asoc/codecs/wcd_cpe_core.c index a7fcce316e6d..2ce5652422d2 100644 --- a/asoc/codecs/wcd_cpe_core.c +++ b/asoc/codecs/wcd_cpe_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -329,6 +329,14 @@ static int wcd_cpe_load_each_segment(struct wcd_cpe_core *core, goto done; } + if (phdr->p_filesz != split_fw->size) { + dev_err(core->dev, + "%s: %s size mismatch, phdr_size: 0x%x fw_size: 0x%zx", + __func__, split_fname, phdr->p_filesz, split_fw->size); + ret = -EINVAL; + goto done; + } + segment->cpe_addr = phdr->p_paddr; segment->size = phdr->p_filesz; segment->data = (u8 *) split_fw->data; -- GitLab From 90fa02abb121d3d1114eddd94757f981ad5cac94 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Tue, 9 Jan 2018 12:27:29 -0800 Subject: [PATCH 0185/1645] asoc: wcd-dsp-utils: add size check for WDSP ELF files Add size check to make sure the data sizes from WDSP ELF metadata and the split firmware ELF are the same. Change-Id: I913087bc352850ceac2fcc07067ea8f480563ae2 Signed-off-by: Xiaoyu Ye --- asoc/codecs/wcd-dsp-utils.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd-dsp-utils.c b/asoc/codecs/wcd-dsp-utils.c index 4eafd55894c5..1c95d48a1a81 100644 --- a/asoc/codecs/wcd-dsp-utils.c +++ b/asoc/codecs/wcd-dsp-utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -82,6 +82,15 @@ static int wdsp_add_segment_to_list(struct device *dev, goto bad_seg; } + if (phdr->p_filesz != seg->split_fw->size) { + dev_err(dev, + "%s: %s size mismatch, phdr_size: 0x%x fw_size: 0x%zx", + __func__, seg->split_fname, phdr->p_filesz, + seg->split_fw->size); + ret = -EINVAL; + goto bad_elf; + } + seg->load_addr = phdr->p_paddr; seg->size = phdr->p_filesz; seg->data = (u8 *) seg->split_fw->data; @@ -89,6 +98,8 @@ static int wdsp_add_segment_to_list(struct device *dev, list_add_tail(&seg->list, seg_list); done: return ret; +bad_elf: + release_firmware(seg->split_fw); bad_seg: kfree(seg); return ret; -- GitLab From 89d1a77802a64228aa648af96445cb16c8ce2a75 Mon Sep 17 00:00:00 2001 From: Vaishnavi Kommaraju Date: Tue, 23 Jan 2018 18:10:21 +0530 Subject: [PATCH 0186/1645] asoc: codecs: Add mutex lock for CPE session Add mutex lock to ensure atomic access to core handle in CPE alloc and dealloc sessions. CRs-Fixed: 2169403 Change-Id: I7e046f349cc56ee06706cf15651dac3fdfe9d9a6 Signed-off-by: Vaishnavi Kommaraju --- asoc/codecs/wcd_cpe_core.c | 13 ++++++++++++- asoc/codecs/wcd_cpe_core.h | 5 ++++- asoc/codecs/wcd_cpe_services.c | 4 +++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/wcd_cpe_core.c b/asoc/codecs/wcd_cpe_core.c index a7fcce316e6d..086b3451537e 100644 --- a/asoc/codecs/wcd_cpe_core.c +++ b/asoc/codecs/wcd_cpe_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1936,6 +1936,7 @@ struct wcd_cpe_core *wcd_cpe_init(const char *img_fname, init_completion(&core->online_compl); init_waitqueue_head(&core->ssr_entry.offline_poll_wait); mutex_init(&core->ssr_lock); + mutex_init(&core->session_lock); core->cpe_users = 0; core->cpe_clk_ref = 0; @@ -3387,6 +3388,7 @@ static struct cpe_lsm_session *wcd_cpe_alloc_lsm_session( * If this is the first session to be allocated, * only then register the afe service. */ + WCD_CPE_GRAB_LOCK(&core->session_lock, "session_lock"); if (!wcd_cpe_lsm_session_active()) afe_register_service = true; @@ -3401,6 +3403,7 @@ static struct cpe_lsm_session *wcd_cpe_alloc_lsm_session( dev_err(core->dev, "%s: max allowed sessions already allocated\n", __func__); + WCD_CPE_REL_LOCK(&core->session_lock, "session_lock"); return NULL; } @@ -3409,6 +3412,7 @@ static struct cpe_lsm_session *wcd_cpe_alloc_lsm_session( dev_err(core->dev, "%s: Failed to enable cpe, err = %d\n", __func__, ret); + WCD_CPE_REL_LOCK(&core->session_lock, "session_lock"); return NULL; } @@ -3451,6 +3455,8 @@ static struct cpe_lsm_session *wcd_cpe_alloc_lsm_session( init_completion(&session->cmd_comp); lsm_sessions[session_id] = session; + + WCD_CPE_REL_LOCK(&core->session_lock, "session_lock"); return session; err_afe_mode_cmd: @@ -3465,6 +3471,7 @@ static struct cpe_lsm_session *wcd_cpe_alloc_lsm_session( err_session_alloc: wcd_cpe_vote(core, false); + WCD_CPE_REL_LOCK(&core->session_lock, "session_lock"); return NULL; } @@ -3615,9 +3622,11 @@ static int wcd_cpe_dealloc_lsm_session(void *core_handle, struct wcd_cpe_core *core = core_handle; int ret = 0; + WCD_CPE_GRAB_LOCK(&core->session_lock, "session_lock"); if (!session) { dev_err(core->dev, "%s: Invalid lsm session\n", __func__); + WCD_CPE_REL_LOCK(&core->session_lock, "session_lock"); return -EINVAL; } @@ -3628,6 +3637,7 @@ static int wcd_cpe_dealloc_lsm_session(void *core_handle, "%s: Wrong session id %d max allowed = %d\n", __func__, session->id, WCD_CPE_LSM_MAX_SESSIONS); + WCD_CPE_REL_LOCK(&core->session_lock, "session_lock"); return -EINVAL; } @@ -3648,6 +3658,7 @@ static int wcd_cpe_dealloc_lsm_session(void *core_handle, "%s: Failed to un-vote cpe, err = %d\n", __func__, ret); + WCD_CPE_REL_LOCK(&core->session_lock, "session_lock"); return ret; } diff --git a/asoc/codecs/wcd_cpe_core.h b/asoc/codecs/wcd_cpe_core.h index 3d672b860ff4..5884a528541f 100644 --- a/asoc/codecs/wcd_cpe_core.h +++ b/asoc/codecs/wcd_cpe_core.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -172,6 +172,9 @@ struct wcd_cpe_core { /* mutex to protect cpe ssr status variables */ struct mutex ssr_lock; + /* mutex to protect cpe session status variables */ + struct mutex session_lock; + /* Store the calibration data needed for cpe */ struct cal_type_data *cal_data[WCD_CPE_LSM_CAL_MAX]; diff --git a/asoc/codecs/wcd_cpe_services.c b/asoc/codecs/wcd_cpe_services.c index 522ce7abacd6..fc8242a91275 100644 --- a/asoc/codecs/wcd_cpe_services.c +++ b/asoc/codecs/wcd_cpe_services.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -606,8 +606,10 @@ static enum cpe_svc_result cpe_deregister_generic(struct cpe_info *t_info, return CPE_SVC_INVALID_HANDLE; } + CPE_SVC_GRAB_LOCK(&cpe_d.cpe_svc_lock, "cpe_svc"); list_del(&(n->list)); kfree(reg_handle); + CPE_SVC_REL_LOCK(&cpe_d.cpe_svc_lock, "cpe_svc"); return CPE_SVC_SUCCESS; } -- GitLab From 9147e38e71b9853edcdb19bc32bf6727c9f795b8 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Wed, 20 Dec 2017 14:20:40 -0800 Subject: [PATCH 0187/1645] asoc: codecs: update IIR cofficient values before IIR band enable Currently IIR coefficient values are written to HW everytime when digital core comes out of power collapse. This increases playback cold start latency. So update IIR coefficient values before IIR band enable. Change-Id: I57ad54b4674ed0a49fdfc55d77c519568f5a7893 Signed-off-by: Vidyakumar Athota --- asoc/codecs/wcd934x/wcd934x.c | 87 ++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 37 deletions(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index e7cec2b4d348..c584ea7ccbbf 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -127,6 +127,7 @@ static const struct snd_kcontrol_new name##_mux = \ #define WCD934X_STRING_LEN 100 #define WCD934X_CDC_SIDETONE_IIR_COEFF_MAX 5 +#define WCD934X_CDC_REPEAT_WRITES_MAX 16 #define WCD934X_DIG_CORE_REG_MIN WCD934X_CDC_ANC0_CLK_RESET_CTL #define WCD934X_DIG_CORE_REG_MAX 0xFFF @@ -628,8 +629,8 @@ struct tavil_priv { struct tavil_idle_detect_config idle_det_cfg; int power_active_ref; - int sidetone_coeff_array[IIR_MAX][BAND_MAX] - [WCD934X_CDC_SIDETONE_IIR_COEFF_MAX]; + u8 sidetone_coeff_array[IIR_MAX][BAND_MAX] + [WCD934X_CDC_SIDETONE_IIR_COEFF_MAX * 4]; struct spi_device *spi; struct platform_device *pdev_child_devices @@ -4927,6 +4928,36 @@ static int tavil_codec_reset_hph_registers(struct snd_soc_dapm_widget *w, return 0; } +static void tavil_restore_iir_coeff(struct tavil_priv *tavil, int iir_idx, + int band_idx) +{ + u16 reg_add; + int no_of_reg = 0; + + regmap_write(tavil->wcd9xxx->regmap, + (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); + + reg_add = WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx; + + if (tavil->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) + return; + /* + * Since wcd9xxx_slim_write_repeat() supports only maximum of 16 + * registers at a time, split total 20 writes(5 coefficients per + * band and 4 writes per coefficient) into 16 and 4. + */ + no_of_reg = WCD934X_CDC_REPEAT_WRITES_MAX; + wcd9xxx_slim_write_repeat(tavil->wcd9xxx, reg_add, no_of_reg, + &tavil->sidetone_coeff_array[iir_idx][band_idx][0]); + + no_of_reg = (WCD934X_CDC_SIDETONE_IIR_COEFF_MAX * 4) - + WCD934X_CDC_REPEAT_WRITES_MAX; + wcd9xxx_slim_write_repeat(tavil->wcd9xxx, reg_add, no_of_reg, + &tavil->sidetone_coeff_array[iir_idx][band_idx] + [WCD934X_CDC_REPEAT_WRITES_MAX]); +} + static int tavil_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -4951,6 +4982,7 @@ static int tavil_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); int iir_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->reg; int band_idx = ((struct soc_multi_mixer_control *) @@ -4959,6 +4991,8 @@ static int tavil_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol, int value = ucontrol->value.integer.value[0]; u16 iir_reg = WCD934X_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx; + tavil_restore_iir_coeff(tavil, iir_idx, band_idx); + /* Mask first 5 bits, 6-8 are reserved */ snd_soc_update_bits(codec, iir_reg, (1 << band_idx), (value << band_idx)); @@ -5085,7 +5119,7 @@ static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, kcontrol->private_value)->reg; int band_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; - int coeff_idx; + int coeff_idx, idx = 0; /* * Mask top bit it is reserved @@ -5098,11 +5132,19 @@ static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, /* Store the coefficients in sidetone coeff array */ for (coeff_idx = 0; coeff_idx < WCD934X_CDC_SIDETONE_IIR_COEFF_MAX; coeff_idx++) { - tavil->sidetone_coeff_array[iir_idx][band_idx][coeff_idx] = - ucontrol->value.integer.value[coeff_idx]; - set_iir_band_coeff(codec, iir_idx, band_idx, - tavil->sidetone_coeff_array[iir_idx][band_idx] - [coeff_idx]); + uint32_t value = ucontrol->value.integer.value[coeff_idx]; + + set_iir_band_coeff(codec, iir_idx, band_idx, value); + + /* Four 8 bit values(one 32 bit) per coefficient */ + tavil->sidetone_coeff_array[iir_idx][band_idx][idx++] = + (value & 0xFF); + tavil->sidetone_coeff_array[iir_idx][band_idx][idx++] = + (value >> 8) & 0xFF; + tavil->sidetone_coeff_array[iir_idx][band_idx][idx++] = + (value >> 16) & 0xFF; + tavil->sidetone_coeff_array[iir_idx][band_idx][idx++] = + (value >> 24) & 0xFF; } pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n" @@ -5123,33 +5165,6 @@ static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, return 0; } -static void tavil_restore_iir_coeff(struct tavil_priv *tavil, int iir_idx) -{ - int band_idx = 0, coeff_idx = 0; - struct snd_soc_codec *codec = tavil->codec; - - /* - * snd_soc_write call crashes at rmmod if there is no machine - * driver and hence no codec pointer available - */ - if (!codec) - return; - - for (band_idx = 0; band_idx < BAND_MAX; band_idx++) { - snd_soc_write(codec, - (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), - (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); - - for (coeff_idx = 0; - coeff_idx < WCD934X_CDC_SIDETONE_IIR_COEFF_MAX; - coeff_idx++) { - set_iir_band_coeff(codec, iir_idx, band_idx, - tavil->sidetone_coeff_array[iir_idx][band_idx] - [coeff_idx]); - } - } -} - static int tavil_compander_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -8250,8 +8265,6 @@ static int tavil_dig_core_remove_power_collapse(struct tavil_priv *tavil) WCD934X_DIG_CORE_REG_MIN, WCD934X_DIG_CORE_REG_MAX); - tavil_restore_iir_coeff(tavil, IIR0); - tavil_restore_iir_coeff(tavil, IIR1); return 0; } -- GitLab From b466d183fbc562c34ff5c01934972bbc0b865062 Mon Sep 17 00:00:00 2001 From: Bhalchandra Gajare Date: Mon, 8 Jan 2018 18:41:02 -0800 Subject: [PATCH 0188/1645] ASoC: wcd-spi: ignore failure from clearing the CLK_REQUEST It is possible that the spi transfer that clears the clock request on the slave may fail. In such case, it is not safe to assume that the clock request is still enabled as it can cause failures for further spi transfers if the clock request is cleared. Fix such issues by resetting the clock state in the driver even the clock request clearing fails. CRs-Fixed: 2169087 Change-Id: I699e72b59b4cb049dfacaa190823796a545f2dbb Signed-off-by: Bhalchandra Gajare --- asoc/codecs/wcd-spi.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/wcd-spi.c b/asoc/codecs/wcd-spi.c index 072a7538ef1d..a25c9a6141ab 100644 --- a/asoc/codecs/wcd-spi.c +++ b/asoc/codecs/wcd-spi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -603,8 +603,11 @@ static int wcd_spi_clk_disable(struct spi_device *spi) if (ret < 0) dev_err(&spi->dev, "%s: Failed, err = %d\n", __func__, ret); - else - clear_bit(WCD_SPI_CLK_STATE_ENABLED, &wcd_spi->status_mask); + /* + * clear this bit even if clock disable failed + * as the source clocks might get turned off. + */ + clear_bit(WCD_SPI_CLK_STATE_ENABLED, &wcd_spi->status_mask); return ret; } -- GitLab From a5e129f857827a4d3ddad81e9276b6e09646bbdb Mon Sep 17 00:00:00 2001 From: Satya Krishna Pindiproli Date: Wed, 10 Jan 2018 16:21:40 +0530 Subject: [PATCH 0189/1645] dsp: codecs: use native API to configure PCM output block in multiaac Usage of q6asm_enc_cfg_blk_pcm() does not trigger PortSettingsChanged event which is required for multi aac component. Configure the PCM output block using q6asm_enc_cfg_blk_pcm_native() which ensures that the event gets triggered. CRs-Fixed: 2169255 Change-Id: I168aa0156c9233d81e99ca2aa6142f33ef10805c Signed-off-by: Satya Krishna Pindiproli --- dsp/codecs/audio_multi_aac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dsp/codecs/audio_multi_aac.c b/dsp/codecs/audio_multi_aac.c index 93b1f504a64b..87e4f4ec0fdb 100644 --- a/dsp/codecs/audio_multi_aac.c +++ b/dsp/codecs/audio_multi_aac.c @@ -2,7 +2,7 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -59,7 +59,7 @@ static long audio_ioctl_shared(struct file *file, unsigned int cmd, audio->ac->session); if (audio->feedback == NON_TUNNEL_MODE) { /* Configure PCM output block */ - rc = q6asm_enc_cfg_blk_pcm(audio->ac, + rc = q6asm_enc_cfg_blk_pcm_native(audio->ac, audio->pcm_cfg.sample_rate, audio->pcm_cfg.channel_count); if (rc < 0) { -- GitLab From 76c5b45e7f79a7db93031830dc516f1105aad50e Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Thu, 25 Jan 2018 14:57:20 +0530 Subject: [PATCH 0190/1645] asoc: codecs: add a null pointer check in mbhc driver Add a missing function pointer null check condition in mbhc driver to avoid null access during fast insertion-removal. Change-Id: I6aa64325cea6f7aa551115969d1e6ba184ec8d14 Signed-off-by: Ramprasad Katkam --- asoc/codecs/wcd-mbhc-legacy.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-legacy.c b/asoc/codecs/wcd-mbhc-legacy.c index d03d8342a8df..9ebdeca01fff 100644 --- a/asoc/codecs/wcd-mbhc-legacy.c +++ b/asoc/codecs/wcd-mbhc-legacy.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -533,7 +533,8 @@ static void wcd_correct_swch_plug(struct work_struct *work) mbhc->hs_detect_work_stop); wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_NONE); - if (mbhc->micbias_enable) { + if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic && + mbhc->micbias_enable) { mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( mbhc->codec, MIC_BIAS_2, false); if (mbhc->mbhc_cb->set_micbias_value) @@ -558,7 +559,8 @@ static void wcd_correct_swch_plug(struct work_struct *work) mbhc->hs_detect_work_stop); wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_NONE); - if (mbhc->micbias_enable) { + if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic && + mbhc->micbias_enable) { mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( mbhc->codec, MIC_BIAS_2, false); if (mbhc->mbhc_cb->set_micbias_value) -- GitLab From 3a4607028c0773ca0bb26f8f1669a8c85294d825 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 8 Feb 2018 14:31:51 +0530 Subject: [PATCH 0191/1645] ASoC: wcd934x: Update OCP before HPH PA enable/disable Observe mute issue when PDR triggered while music playback on HPH. As per HW recommendation, ensure OCP is turned off before PA enable/disable. During PA enablement, turn off OCP to avoid false OCP interrupts. CRs-Fixed: 2167007 Change-Id: I0dc2cc6ded3416b635d14dc3b7aafa7997fe9a4d Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd934x/wcd934x.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index e7cec2b4d348..40b01b7e3391 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -1858,6 +1858,18 @@ static void tavil_codec_clear_anc_tx_hold(struct tavil_priv *tavil) tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC4, false); } + +static void tavil_ocp_control(struct snd_soc_codec *codec, bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, WCD934X_HPH_OCP_CTL, 0x10, 0x10); + snd_soc_update_bits(codec, WCD934X_RX_OCP_CTL, 0x0F, 0x02); + } else { + snd_soc_update_bits(codec, WCD934X_RX_OCP_CTL, 0x0F, 0x0F); + snd_soc_update_bits(codec, WCD934X_HPH_OCP_CTL, 0x10, 0x00); + } +} + static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -1871,6 +1883,7 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + tavil_ocp_control(codec, false); if (TAVIL_IS_1_0(tavil->wcd9xxx)) snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL, 0x06, (0x03 << 1)); @@ -1967,8 +1980,10 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, ret = tavil_codec_enable_anc(w, kcontrol, event); } tavil_codec_override(codec, tavil->hph_mode, event); + tavil_ocp_control(codec, true); break; case SND_SOC_DAPM_PRE_PMD: + tavil_ocp_control(codec, false); blocking_notifier_call_chain(&tavil->mbhc->notifier, WCD_EVENT_PRE_HPHR_PA_OFF, &tavil->mbhc->wcd_mbhc); @@ -2007,6 +2022,7 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, WCD934X_CDC_RX2_RX_PATH_CFG0, 0x10, 0x00); } + tavil_ocp_control(codec, true); break; }; @@ -2026,6 +2042,7 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + tavil_ocp_control(codec, false); if (TAVIL_IS_1_0(tavil->wcd9xxx)) snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL, 0x06, (0x03 << 1)); @@ -2119,8 +2136,10 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, ret = tavil_codec_enable_anc(w, kcontrol, event); } tavil_codec_override(codec, tavil->hph_mode, event); + tavil_ocp_control(codec, true); break; case SND_SOC_DAPM_PRE_PMD: + tavil_ocp_control(codec, false); blocking_notifier_call_chain(&tavil->mbhc->notifier, WCD_EVENT_PRE_HPHL_PA_OFF, &tavil->mbhc->wcd_mbhc); @@ -2160,6 +2179,7 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CFG0, 0x10, 0x00); } + tavil_ocp_control(codec, true); break; }; -- GitLab From dd3fa1d1e98f6d1f02bb489fd1b8f437beb6fe42 Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Fri, 23 Feb 2018 13:08:14 +0530 Subject: [PATCH 0192/1645] dsp: Add missing pdr interface definition. Fix for compilation error when pdr is not enabled. CRs-Fixed: 2165343 Change-Id: Ic192d481b2e387b8c970c68832c87846329fe72d Signed-off-by: Soumya Managoli --- dsp/audio_pdr.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dsp/audio_pdr.h b/dsp/audio_pdr.h index 2a45c6a61fac..d1235bcac39d 100644 --- a/dsp/audio_pdr.h +++ b/dsp/audio_pdr.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -83,6 +83,10 @@ static inline int audio_pdr_register(struct notifier_block *nb) return -ENODEV; } +static inline int audio_pdr_deregister(struct notifier_block *nb) +{ + return -ENODEV; +} static inline void *audio_pdr_service_register(int domain_id, struct notifier_block *nb, -- GitLab From 39a430ca29e7999f68c2cb2abdbbdbfa25656bd2 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Mon, 22 Jan 2018 15:44:58 -0800 Subject: [PATCH 0193/1645] swr-wcd-ctrl: update soundwire slave logical device number Soundwire slave logical device number is not updated properly for all the devices. Because of this, slave devices are pointed to wrong register regmap. Update logical device number properly for all the slave devices. Change-Id: Ic480585301d8e53500714bc136e23e95ac52b13c Signed-off-by: Vidyakumar Athota --- soc/swr-wcd-ctrl.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c index dc1f7866d40c..fec252bc605a 100644 --- a/soc/swr-wcd-ctrl.c +++ b/soc/swr-wcd-ctrl.c @@ -1291,6 +1291,7 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, u64 id = 0; int ret = -EINVAL; struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(mstr); + struct swr_device *swr_dev; if (!swrm) { pr_err("%s: Invalid handle to swr controller\n", @@ -1304,20 +1305,30 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, SWRM_ENUMERATOR_SLAVE_DEV_ID_2(i))) << 32); id |= swrm->read(swrm->handle, SWRM_ENUMERATOR_SLAVE_DEV_ID_1(i)); - if ((id & SWR_DEV_ID_MASK) == dev_id) { - if (swrm_get_device_status(swrm, i) == 0x01) { - *dev_num = i; - ret = 0; - } else { - dev_err(swrm->dev, "%s: device is not ready\n", - __func__); + /* + * As pm_runtime_get_sync() brings all slaves out of reset + * update logical device number for all slaves. + */ + list_for_each_entry(swr_dev, &mstr->devices, dev_list) { + if (swr_dev->addr == (id & SWR_DEV_ID_MASK)) { + u32 status = swrm_get_device_status(swrm, i); + + if ((status == 0x01) || (status == 0x02)) { + swr_dev->dev_num = i; + if ((id & SWR_DEV_ID_MASK) == dev_id) { + *dev_num = i; + ret = 0; + } + dev_dbg(swrm->dev, "%s: devnum %d is assigned for dev addr %lx\n", + __func__, i, swr_dev->addr); + } } - goto found; } } - dev_err(swrm->dev, "%s: device id 0x%llx does not match with 0x%llx\n", - __func__, id, dev_id); -found: + if (ret) + dev_err(swrm->dev, "%s: device 0x%llx is not ready\n", + __func__, dev_id); + pm_runtime_mark_last_busy(&swrm->pdev->dev); pm_runtime_put_autosuspend(&swrm->pdev->dev); return ret; -- GitLab From 55c95517735113d6b4c029a3d05f1421d8a306f9 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 26 Feb 2018 20:31:02 +0530 Subject: [PATCH 0194/1645] ASoC: Fix WSA enumeration failure In SDM450, WSA reset pin is shared for both WSA left and right speakers. When reset pin toggled, both devices enumerate and can be filled in any order in SWRM_DEV list. But get_logical_address loops only once for first slave addition and fails if the device entry is present at second in SWRM_DEV list. Update logic of get_logical_address to loop through max devices possible. CRs-Fixed: 2196399 Change-Id: Ie31cea5a9b22e09a3c5c01e177cd1b78e8d2f28d Signed-off-by: Laxminath Kasam --- soc/swr-wcd-ctrl.c | 20 +++++++++++++++++++- soc/swr-wcd-ctrl.h | 5 ++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c index fec252bc605a..583219023acb 100644 --- a/soc/swr-wcd-ctrl.c +++ b/soc/swr-wcd-ctrl.c @@ -1292,15 +1292,20 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, int ret = -EINVAL; struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(mstr); struct swr_device *swr_dev; + u32 num_dev = 0; if (!swrm) { pr_err("%s: Invalid handle to swr controller\n", __func__); return ret; } + if (swrm->num_dev) + num_dev = swrm->num_dev; + else + num_dev = mstr->num_dev; pm_runtime_get_sync(&swrm->pdev->dev); - for (i = 1; i < (mstr->num_dev + 1); i++) { + for (i = 1; i < (num_dev + 1); i++) { id = ((u64)(swrm->read(swrm->handle, SWRM_ENUMERATOR_SLAVE_DEV_ID_2(i))) << 32); id |= swrm->read(swrm->handle, @@ -1477,6 +1482,19 @@ static int swrm_probe(struct platform_device *pdev) INIT_LIST_HEAD(&swrm->mport_list); mutex_init(&swrm->reslock); + ret = of_property_read_u32(swrm->dev->of_node, "qcom,swr-num-dev", + &swrm->num_dev); + if (ret) + dev_dbg(&pdev->dev, "%s: Looking up %s property failed\n", + __func__, "qcom,swr-num-dev"); + else { + if (swrm->num_dev > SWR_MAX_SLAVE_DEVICES) { + dev_err(&pdev->dev, "%s: num_dev %d > max limit %d\n", + __func__, swrm->num_dev, SWR_MAX_SLAVE_DEVICES); + ret = -EINVAL; + goto err_pdata_fail; + } + } ret = swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, SWR_IRQ_REGISTER); if (ret) { diff --git a/soc/swr-wcd-ctrl.h b/soc/swr-wcd-ctrl.h index 52a60a3c6087..fcf0652a6434 100644 --- a/soc/swr-wcd-ctrl.h +++ b/soc/swr-wcd-ctrl.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -23,6 +23,8 @@ #define SWR_MSTR_PORT_LEN 8 /* Number of master ports */ +#define SWR_MAX_SLAVE_DEVICES 11 + #define SWRM_VERSION_1_0 0x01010000 #define SWRM_VERSION_1_2 0x01030000 #define SWRM_VERSION_1_3 0x01040000 @@ -94,6 +96,7 @@ struct swr_mstr_ctrl { void *data), void *swr_handle, int type); int irq; int version; + u32 num_dev; int num_enum_slaves; int slave_status; struct swr_mstr_port *mstr_port; -- GitLab From dd08b3db40dff0cbb0a05c5f731377e35e10266f Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Fri, 15 Dec 2017 15:33:57 +0530 Subject: [PATCH 0195/1645] asoc: sdm660: fix tasha lite detection issue Defer probe of soundcard registration until codec driver registration is complete to fix detection of codec version by machine driver. Change-Id: Ia93404a85c98bd50e63015073284d5bf290a3f9f Signed-off-by: Rohit kumar --- asoc/sdm660-ext-dai-links.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/asoc/sdm660-ext-dai-links.c b/asoc/sdm660-ext-dai-links.c index 02d35a9ebf7d..5f5a60e21ca0 100644 --- a/asoc/sdm660-ext-dai-links.c +++ b/asoc/sdm660-ext-dai-links.c @@ -2052,8 +2052,13 @@ struct snd_soc_card *populate_snd_card_dailinks(struct device *dev, if (strnstr(card->name, "tasha", strlen(card->name))) { codec_ver = tasha_codec_ver(); - if (codec_ver == WCD9326) - card->name = "sdm660-tashalite-snd-card"; + if (codec_ver == WCD9326) { + card->name = "sdm670-tashalite-snd-card"; + } else if (codec_ver == WCD9XXX) { + dev_err(dev, "%s: Invalid codec version %d\n", + __func__, codec_ver); + return NULL; + } len1 = ARRAY_SIZE(msm_ext_common_fe_dai); len2 = len1 + ARRAY_SIZE(msm_ext_tasha_fe_dai); -- GitLab From 30ad751aacb9f348e895d2fe110660d5bc440d0b Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 28 Nov 2017 12:40:22 +0530 Subject: [PATCH 0196/1645] ASoC: rmmod fixes for audio drivers For remove module(rmmod), update drivers to cleanup resources and allow insert module again without any issue. Change-Id: Iddc6e5e11d986359afd3100bf3c5eab70cb1c1eb Signed-off-by: Laxminath Kasam Signed-off-by: Meng Wang --- asoc/codecs/msm_sdw/msm_sdw.h | 6 +- asoc/codecs/msm_sdw/msm_sdw_cdc.c | 17 +++- asoc/codecs/sdm660_cdc/msm-analog-cdc.c | 15 ++- asoc/codecs/sdm660_cdc/msm-analog-cdc.h | 6 +- asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c | 7 +- asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h | 3 +- asoc/msm-dai-q6-v2.c | 3 +- dsp/audio_slimslave.c | 4 +- dsp/q6adm.c | 118 +++++++++++++----------- dsp/q6afe.c | 6 ++ soc/swr-wcd-ctrl.c | 7 +- 11 files changed, 120 insertions(+), 72 deletions(-) diff --git a/asoc/codecs/msm_sdw/msm_sdw.h b/asoc/codecs/msm_sdw/msm_sdw.h index d4ac43333392..3c7a07dca673 100644 --- a/asoc/codecs/msm_sdw/msm_sdw.h +++ b/asoc/codecs/msm_sdw/msm_sdw.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -17,6 +17,7 @@ #include "msm_sdw_registers.h" #define MSM_SDW_MAX_REGISTER 0x400 +#define MSM_SDW_CHILD_DEVICES_MAX 1 extern const struct regmap_config msm_sdw_regmap_config; extern const u8 msm_sdw_page_map[MSM_SDW_MAX_REGISTER]; @@ -154,6 +155,9 @@ struct msm_sdw_priv { /* Entry for version info */ struct snd_info_entry *entry; struct snd_info_entry *version_entry; + struct platform_device *pdev_child_devices + [MSM_SDW_CHILD_DEVICES_MAX]; + int child_count; }; #if IS_ENABLED(CONFIG_SND_SOC_MSM_SDW) diff --git a/asoc/codecs/msm_sdw/msm_sdw_cdc.c b/asoc/codecs/msm_sdw/msm_sdw_cdc.c index 7a5ba8f0c7c4..3e4921d10203 100644 --- a/asoc/codecs/msm_sdw/msm_sdw_cdc.c +++ b/asoc/codecs/msm_sdw/msm_sdw_cdc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1251,7 +1251,13 @@ static int msm_sdw_swrm_write(void *handle, int reg, int val) static int msm_sdw_swrm_clock(void *handle, bool enable) { - struct msm_sdw_priv *msm_sdw = (struct msm_sdw_priv *) handle; + struct msm_sdw_priv *msm_sdw; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + msm_sdw = (struct msm_sdw_priv *)handle; mutex_lock(&msm_sdw->sdw_clk_lock); @@ -1934,6 +1940,7 @@ static void msm_sdw_add_child_devices(struct work_struct *work) msm_sdw->nr = ctrl_num; msm_sdw->sdw_ctrl_data = sdw_ctrl_data; } + msm_sdw->pdev_child_devices[msm_sdw->child_count++] = pdev; } return; @@ -2050,15 +2057,21 @@ static int msm_sdw_probe(struct platform_device *pdev) static int msm_sdw_remove(struct platform_device *pdev) { struct msm_sdw_priv *msm_sdw; + int count; msm_sdw = dev_get_drvdata(&pdev->dev); + for (count = 0; count < msm_sdw->child_count && + count < MSM_SDW_CHILD_DEVICES_MAX; count++) + platform_device_unregister(msm_sdw->pdev_child_devices[count]); + mutex_destroy(&msm_sdw->io_lock); mutex_destroy(&msm_sdw->sdw_read_lock); mutex_destroy(&msm_sdw->sdw_write_lock); mutex_destroy(&msm_sdw->sdw_clk_lock); mutex_destroy(&msm_sdw->codec_mutex); mutex_destroy(&msm_sdw->cdc_int_mclk1_mutex); + devm_kfree(&pdev->dev, msm_sdw); snd_soc_unregister_codec(&pdev->dev); return 0; diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c index 9121baf0f418..64b99561b522 100644 --- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -4396,7 +4396,7 @@ static int msm_anlg_cdc_init_supplies(struct sdm660_cdc_priv *sdm660_cdc, return ret; err_supplies: - kfree(sdm660_cdc->supplies); + devm_kfree(sdm660_cdc->dev, sdm660_cdc->supplies); err: return ret; } @@ -4442,9 +4442,6 @@ static void msm_anlg_cdc_disable_supplies(struct sdm660_cdc_priv *sdm660_cdc, pdata->regulator[i].max_uv); regulator_set_load(sdm660_cdc->supplies[i].consumer, 0); } - regulator_bulk_free(sdm660_cdc->num_of_supplies, - sdm660_cdc->supplies); - kfree(sdm660_cdc->supplies); } static const struct of_device_id sdm660_codec_of_match[] = { @@ -4531,6 +4528,7 @@ static void msm_anlg_add_child_devices(struct work_struct *work) __func__); pdata->dig_ctrl_data = dig_ctrl_data; } + pdata->pdev_child_devices[pdata->child_count++] = pdev; } return; @@ -4639,9 +4637,16 @@ static int msm_anlg_cdc_remove(struct platform_device *pdev) { struct sdm660_cdc_priv *sdm660_cdc = dev_get_drvdata(&pdev->dev); struct sdm660_cdc_pdata *pdata = sdm660_cdc->dev->platform_data; + int count; + for (count = 0; count < sdm660_cdc->child_count && + count < ANLG_CDC_CHILD_DEVICES_MAX; count++) + platform_device_unregister( + sdm660_cdc->pdev_child_devices[count]); snd_soc_unregister_codec(&pdev->dev); msm_anlg_cdc_disable_supplies(sdm660_cdc, pdata); + wcd9xxx_spmi_irq_exit(); + devm_kfree(&pdev->dev, sdm660_cdc); return 0; } diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.h b/asoc/codecs/sdm660_cdc/msm-analog-cdc.h index 3ee3dee743d5..71d555f38846 100644 --- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.h +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -21,6 +21,7 @@ #define MICBIAS_EXT_BYP_CAP 0x00 #define MICBIAS_NO_EXT_BYP_CAP 0x01 +#define ANLG_CDC_CHILD_DEVICES_MAX 1 #define MSM89XX_NUM_IRQ_REGS 2 #define MAX_REGULATOR 7 @@ -215,6 +216,9 @@ struct sdm660_cdc_priv { /* Entry for version info */ struct snd_info_entry *entry; struct snd_info_entry *version_entry; + struct platform_device *pdev_child_devices + [ANLG_CDC_CHILD_DEVICES_MAX]; + int child_count; }; struct sdm660_cdc_pdata { diff --git a/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c b/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c index ee4ec34fa2d7..673b738b4eac 100644 --- a/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c +++ b/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -409,5 +409,10 @@ int wcd9xxx_spmi_irq_init(void) return 0; } +void wcd9xxx_spmi_irq_exit(void) +{ + pm_qos_remove_request(&map.pm_qos_req); + mutex_destroy(&map.pm_lock); +} MODULE_DESCRIPTION("MSM8x16 SPMI IRQ driver"); MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h b/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h index d0f48d0c2af2..0b9b56e12b8a 100644 --- a/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h +++ b/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -26,6 +26,7 @@ extern int wcd9xxx_spmi_free_irq(int irq, void *priv); extern void wcd9xxx_spmi_set_codec(struct snd_soc_codec *codec); extern void wcd9xxx_spmi_set_dev(struct platform_device *spmi, int i); extern int wcd9xxx_spmi_irq_init(void); +extern void wcd9xxx_spmi_irq_exit(void); extern int wcd9xxx_spmi_suspend(pm_message_t pmesg); extern int wcd9xxx_spmi_resume(void); bool wcd9xxx_spmi_lock_sleep(void); diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index bec7fcfbffbc..d0df70c5b016 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -8978,6 +8978,7 @@ int __init msm_dai_q6_init(void) void msm_dai_q6_exit(void) { + platform_driver_unregister(&msm_dai_tdm_q6); platform_driver_unregister(&msm_dai_q6_tdm_driver); platform_driver_unregister(&msm_dai_q6_spdif_driver); platform_driver_unregister(&msm_dai_mi2s_q6); diff --git a/dsp/audio_slimslave.c b/dsp/audio_slimslave.c index 25866d12ed73..55982f33474b 100644 --- a/dsp/audio_slimslave.c +++ b/dsp/audio_slimslave.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2017-2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -167,7 +167,7 @@ int __init audio_slimslave_init(void) void audio_slimslave_exit(void) { - + slim_driver_unregister(&audio_slimslave_driver); } /* Module information */ diff --git a/dsp/q6adm.c b/dsp/q6adm.c index dc900edbce4d..f8aef943439f 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -1440,10 +1440,68 @@ int adm_get_multi_ch_map(char *channel_map, int path) } EXPORT_SYMBOL(adm_get_multi_ch_map); +static void adm_reset_data(void) +{ + int i, j; + + apr_reset(this_adm.apr); + for (i = 0; i < AFE_MAX_PORTS; i++) { + for (j = 0; j < MAX_COPPS_PER_PORT; j++) { + atomic_set(&this_adm.copp.id[i][j], + RESET_COPP_ID); + atomic_set(&this_adm.copp.cnt[i][j], 0); + atomic_set( + &this_adm.copp.topology[i][j], 0); + atomic_set(&this_adm.copp.mode[i][j], + 0); + atomic_set(&this_adm.copp.stat[i][j], + 0); + atomic_set(&this_adm.copp.rate[i][j], + 0); + atomic_set( + &this_adm.copp.channels[i][j], + 0); + atomic_set( + &this_adm.copp.bit_width[i][j], 0); + atomic_set( + &this_adm.copp.app_type[i][j], 0); + atomic_set( + &this_adm.copp.acdb_id[i][j], 0); + this_adm.copp.adm_status[i][j] = + ADM_STATUS_CALIBRATION_REQUIRED; + } + } + this_adm.apr = NULL; + cal_utils_clear_cal_block_q6maps(ADM_MAX_CAL_TYPES, + this_adm.cal_data); + mutex_lock(&this_adm.cal_data + [ADM_CUSTOM_TOP_CAL]->lock); + this_adm.set_custom_topology = 1; + mutex_unlock(&this_adm.cal_data[ + ADM_CUSTOM_TOP_CAL]->lock); + rtac_clear_mapping(ADM_RTAC_CAL); + /* + * Free the ION memory and clear the map handles + * for Source Tracking + */ + if (this_adm.sourceTrackingData.memmap.paddr != 0) { + msm_audio_ion_free( + this_adm.sourceTrackingData.dma_buf); + this_adm.sourceTrackingData.dma_buf = NULL; + this_adm.sourceTrackingData.memmap.size = 0; + this_adm.sourceTrackingData.memmap.kvaddr = + NULL; + this_adm.sourceTrackingData.memmap.paddr = 0; + this_adm.sourceTrackingData.apr_cmd_status = -1; + atomic_set(&this_adm.mem_map_handles[ + ADM_MEM_MAP_INDEX_SOURCE_TRACKING], 0); + } +} + static int32_t adm_callback(struct apr_client_data *data, void *priv) { uint32_t *payload; - int i, j, port_idx, copp_idx, idx, client_id; + int i, port_idx, copp_idx, idx, client_id; if (data == NULL) { pr_err("%s: data parameter is null\n", __func__); @@ -1456,60 +1514,8 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) pr_debug("%s: Reset event is received: %d %d apr[%pK]\n", __func__, data->reset_event, data->reset_proc, this_adm.apr); - if (this_adm.apr) { - apr_reset(this_adm.apr); - for (i = 0; i < AFE_MAX_PORTS; i++) { - for (j = 0; j < MAX_COPPS_PER_PORT; j++) { - atomic_set(&this_adm.copp.id[i][j], - RESET_COPP_ID); - atomic_set(&this_adm.copp.cnt[i][j], 0); - atomic_set( - &this_adm.copp.topology[i][j], 0); - atomic_set(&this_adm.copp.mode[i][j], - 0); - atomic_set(&this_adm.copp.stat[i][j], - 0); - atomic_set(&this_adm.copp.rate[i][j], - 0); - atomic_set( - &this_adm.copp.channels[i][j], - 0); - atomic_set( - &this_adm.copp.bit_width[i][j], 0); - atomic_set( - &this_adm.copp.app_type[i][j], 0); - atomic_set( - &this_adm.copp.acdb_id[i][j], 0); - this_adm.copp.adm_status[i][j] = - ADM_STATUS_CALIBRATION_REQUIRED; - } - } - this_adm.apr = NULL; - cal_utils_clear_cal_block_q6maps(ADM_MAX_CAL_TYPES, - this_adm.cal_data); - mutex_lock(&this_adm.cal_data - [ADM_CUSTOM_TOP_CAL]->lock); - this_adm.set_custom_topology = 1; - mutex_unlock(&this_adm.cal_data[ - ADM_CUSTOM_TOP_CAL]->lock); - rtac_clear_mapping(ADM_RTAC_CAL); - /* - * Free the ION memory and clear the map handles - * for Source Tracking - */ - if (this_adm.sourceTrackingData.memmap.paddr != 0) { - msm_audio_ion_free( - this_adm.sourceTrackingData.dma_buf); - this_adm.sourceTrackingData.dma_buf = NULL; - this_adm.sourceTrackingData.memmap.size = 0; - this_adm.sourceTrackingData.memmap.kvaddr = - NULL; - this_adm.sourceTrackingData.memmap.paddr = 0; - this_adm.sourceTrackingData.apr_cmd_status = -1; - atomic_set(&this_adm.mem_map_handles[ - ADM_MEM_MAP_INDEX_SOURCE_TRACKING], 0); - } - } + if (this_adm.apr) + adm_reset_data(); return 0; } @@ -5256,6 +5262,8 @@ int __init adm_init(void) void adm_exit(void) { + if (this_adm.apr) + adm_reset_data(); mutex_destroy(&dts_srs_lock); adm_delete_cal_data(); } diff --git a/dsp/q6afe.c b/dsp/q6afe.c index f926efbdc16b..60e8e27b6ff1 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -7636,6 +7636,12 @@ int __init afe_init(void) void afe_exit(void) { + if (this_afe.apr) { + apr_reset(this_afe.apr); + atomic_set(&this_afe.state, 0); + this_afe.apr = NULL; + rtac_set_afe_handle(this_afe.apr); + } afe_delete_cal_data(); config_debug_fs_exit(); diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c index dc1f7866d40c..c2edb7a64345 100644 --- a/soc/swr-wcd-ctrl.c +++ b/soc/swr-wcd-ctrl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1538,8 +1538,9 @@ static int swrm_remove(struct platform_device *pdev) { struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); - swrm->reg_irq(swrm->handle, swr_mstr_interrupt, - swrm, SWR_IRQ_FREE); + if (swrm->reg_irq) + swrm->reg_irq(swrm->handle, swr_mstr_interrupt, + swrm, SWR_IRQ_FREE); if (swrm->mstr_port) { kfree(swrm->mstr_port->port); swrm->mstr_port->port = NULL; -- GitLab From 42121f7e0915470bd083c7e7f2ad41befac092eb Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Tue, 2 Jan 2018 18:17:22 +0530 Subject: [PATCH 0197/1645] asoc: msm-cpe-lsm: use kmalloc for slim_port_xfer buffers Use kmalloc instead of dma_alloc_coherent for slim buffers to support dma_mapping api in interrupt context. Change-Id: Idf06832b6a3bb30f6a16c168b4e5e5f13ad0a0ab Signed-off-by: Rohit kumar Signed-off-by: Meng Wang --- asoc/msm-cpe-lsm.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/asoc/msm-cpe-lsm.c b/asoc/msm-cpe-lsm.c index 2dc32f67fab1..4094c1ed8bf7 100644 --- a/asoc/msm-cpe-lsm.c +++ b/asoc/msm-cpe-lsm.c @@ -478,18 +478,21 @@ static int msm_cpe_lab_buf_alloc(struct snd_pcm_substream *substream, lab_d->pcm_buf = pcm_buf; dma_alloc = bufsz * bufcnt; pcm_buf->mem = NULL; - pcm_buf->mem = dma_alloc_coherent(dma_data->sdev->dev.parent, - dma_alloc, - &(pcm_buf->phys), - GFP_KERNEL); + pcm_buf->mem = kzalloc(dma_alloc, GFP_DMA); if (!pcm_buf->mem) { - dev_err(rtd->dev, - "%s:DMA alloc failed size = %x\n", - __func__, dma_alloc); rc = -ENOMEM; goto fail; } + pcm_buf->phys = dma_map_single(dma_data->sdev->dev.parent, + pcm_buf->mem, dma_alloc, DMA_BIDIRECTIONAL); + if (dma_mapping_error(dma_data->sdev->dev.parent, pcm_buf->phys)) { + dev_err(rtd->dev, "%s Error mapping DMA buffers\n", __func__); + pcm_buf->phys = (phys_addr_t)NULL; + rc = -EFAULT; + goto fail; + } + count = 0; while (count < bufcnt) { pcm_buf[count].mem = pcm_buf[0].mem + (count * bufsz); @@ -504,13 +507,10 @@ static int msm_cpe_lab_buf_alloc(struct snd_pcm_substream *substream, return 0; fail: - if (pcm_buf) { - if (pcm_buf->mem) - dma_free_coherent(dma_data->sdev->dev.parent, dma_alloc, - pcm_buf->mem, pcm_buf->phys); - kfree(pcm_buf); - lab_d->pcm_buf = NULL; - } + if (pcm_buf && pcm_buf->mem) + kfree(pcm_buf->mem); + kfree(pcm_buf); + lab_d->pcm_buf = NULL; exit: return rc; } @@ -544,8 +544,12 @@ static int msm_cpe_lab_buf_dealloc(struct snd_pcm_substream *substream, pcm_buf = lab_d->pcm_buf; dma_alloc = bufsz * bufcnt; if (dma_data && pcm_buf) - dma_free_coherent(dma_data->sdev->dev.parent, dma_alloc, - pcm_buf->mem, pcm_buf->phys); + if (pcm_buf->phys) + dma_unmap_single(dma_data->sdev->dev.parent, + pcm_buf->phys, dma_alloc, DMA_BIDIRECTIONAL); + if (pcm_buf) + kfree(pcm_buf->mem); + kfree(pcm_buf); lab_d->pcm_buf = NULL; return rc; @@ -633,7 +637,7 @@ static int msm_cpe_lab_thread(void *data) memset(lab_d->pcm_buf[0].mem, 0, lab_d->pcm_size); rc = slim_port_xfer(dma_data->sdev, dma_data->ph, - lab_d->pcm_buf[0].phys, + lab_d->pcm_buf[0].mem, hw_params->buf_sz, &lab_d->comp); if (rc) { dev_err(rtd->dev, @@ -643,7 +647,7 @@ static int msm_cpe_lab_thread(void *data) } rc = slim_port_xfer(dma_data->sdev, dma_data->ph, - lab_d->pcm_buf[1].phys, + lab_d->pcm_buf[1].mem, hw_params->buf_sz, &lab_d->comp); if (rc) { dev_err(rtd->dev, @@ -678,7 +682,7 @@ static int msm_cpe_lab_thread(void *data) lab_d->thread_status != MSM_LSM_LAB_THREAD_ERROR) { rc = slim_port_xfer(dma_data->sdev, dma_data->ph, - next_buf->phys, + next_buf->mem, hw_params->buf_sz, &lab_d->comp); if (rc) { dev_err(rtd->dev, -- GitLab From a3030c162cfd8ddcee6bef28428316479803ac21 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Thu, 1 Mar 2018 16:25:16 -0800 Subject: [PATCH 0198/1645] asoc: codecs: wcd9360: add delay after LDO_RXTX enable Add delay after LDO_RXTX supply is enabled as per hardware register sequence. Change-Id: I588d36c6c13ae8f545aba2b2cf6d1c73fde08d0a Signed-off-by: Vidyakumar Athota --- asoc/codecs/wcd9360/wcd9360.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/codecs/wcd9360/wcd9360.c b/asoc/codecs/wcd9360/wcd9360.c index 1e743c0a13c4..179e3d1033b7 100644 --- a/asoc/codecs/wcd9360/wcd9360.c +++ b/asoc/codecs/wcd9360/wcd9360.c @@ -1630,6 +1630,11 @@ static int pahu_codec_enable_ldo_rxtx(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD9360_LDORXTX_LDORXTX, 0x80, 0x80); + /* + * 200us sleep is required after LDO_RXTX is enabled as per + * HW requirement + */ + usleep_range(200, 250); } break; case SND_SOC_DAPM_POST_PMD: -- GitLab From a56add7f44e5c30f5d9b407b7be86a2e34611cad Mon Sep 17 00:00:00 2001 From: Shiv Maliyappanahalli Date: Thu, 1 Mar 2018 16:30:53 -0800 Subject: [PATCH 0199/1645] ipc: delete apr tal over glink On kernel 4.14, apr uses rpmsg as an ipc interface instead of glink. Delete apr_tal_glink source code. Change-Id: I5e27942de6b837d6b992a1b93e85c742a6a30494 Signed-off-by: Shiv Maliyappanahalli --- ipc/apr_tal_glink.c | 482 -------------------------------------------- 1 file changed, 482 deletions(-) delete mode 100644 ipc/apr_tal_glink.c diff --git a/ipc/apr_tal_glink.c b/ipc/apr_tal_glink.c deleted file mode 100644 index 6683348686aa..000000000000 --- a/ipc/apr_tal_glink.c +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define APR_MAXIMUM_NUM_OF_RETRIES 2 - -struct apr_tx_buf { - struct apr_pkt_priv pkt_priv; - char buf[APR_MAX_BUF]; -}; - -struct link_state { - uint32_t dest; - void *handle; - enum glink_link_state link_state; - wait_queue_head_t wait; -}; - -static struct link_state link_state[APR_DEST_MAX]; - -static char *svc_names[APR_DEST_MAX][APR_CLIENT_MAX] = { - { - "apr_audio_svc", - "apr_voice_svc", - }, - { - "apr_audio_svc", - "apr_voice_svc", - }, -}; - -static struct apr_svc_ch_dev - apr_svc_ch[APR_DL_MAX][APR_DEST_MAX][APR_CLIENT_MAX]; - -static struct apr_tx_buf *apr_alloc_buf(int len) -{ - - if (len > APR_MAX_BUF) { - pr_err("%s: buf too large [%d]\n", __func__, len); - return ERR_PTR(-EINVAL); - } - - return kzalloc(sizeof(struct apr_tx_buf), GFP_ATOMIC); -} - -static void apr_free_buf(const void *ptr) -{ - - struct apr_pkt_priv *apr_pkt_priv = (struct apr_pkt_priv *)ptr; - struct apr_tx_buf *tx_buf; - - if (!apr_pkt_priv) { - pr_err("%s: Invalid apr_pkt_priv\n", __func__); - return; - } - - if (apr_pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER) { - tx_buf = container_of((void *)apr_pkt_priv, - struct apr_tx_buf, pkt_priv); - pr_debug("%s: Freeing buffer %pK", __func__, tx_buf); - kfree(tx_buf); - } -} - - -static int __apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data, - struct apr_pkt_priv *pkt_priv, int len) -{ - int rc = 0; - unsigned long flags; - - spin_lock_irqsave(&apr_ch->w_lock, flags); - rc = glink_tx(apr_ch->handle, pkt_priv, data, len, GLINK_TX_ATOMIC); - spin_unlock_irqrestore(&apr_ch->w_lock, flags); - - if (rc) - pr_err("%s: glink_tx failed, rc[%d]\n", __func__, rc); - else - rc = len; - - return rc; -} - -int apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data, - struct apr_pkt_priv *pkt_priv, int len) -{ - int rc = 0, retries = 0; - void *pkt_data = NULL; - struct apr_tx_buf *tx_buf = NULL; - struct apr_pkt_priv *pkt_priv_ptr = pkt_priv; - - if (!apr_ch->handle || !pkt_priv) - return -EINVAL; - - if (pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER) { - tx_buf = apr_alloc_buf(len); - if (IS_ERR_OR_NULL(tx_buf)) { - rc = -EINVAL; - goto exit; - } - memcpy(tx_buf->buf, data, len); - memcpy(&tx_buf->pkt_priv, pkt_priv, sizeof(tx_buf->pkt_priv)); - pkt_priv_ptr = &tx_buf->pkt_priv; - pkt_data = tx_buf->buf; - } else { - pkt_data = data; - } - - do { - if (rc == -EAGAIN) - udelay(50); - - rc = __apr_tal_write(apr_ch, pkt_data, pkt_priv_ptr, len); - } while (rc == -EAGAIN && retries++ < APR_MAXIMUM_NUM_OF_RETRIES); - - if (rc < 0) { - pr_err("%s: Unable to send the packet, rc:%d\n", __func__, rc); - if (pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER) - kfree(tx_buf); - } -exit: - return rc; -} - -void apr_tal_notify_rx(void *handle, const void *priv, const void *pkt_priv, - const void *ptr, size_t size) -{ - struct apr_svc_ch_dev *apr_ch = (struct apr_svc_ch_dev *)priv; - unsigned long flags; - - if (!apr_ch || !ptr) { - pr_err("%s: Invalid apr_ch or ptr\n", __func__); - return; - } - - pr_debug("%s: Rx packet received\n", __func__); - - spin_lock_irqsave(&apr_ch->r_lock, flags); - if (apr_ch->func) - apr_ch->func((void *)ptr, size, (void *)pkt_priv); - spin_unlock_irqrestore(&apr_ch->r_lock, flags); - glink_rx_done(apr_ch->handle, ptr, true); -} - -static void apr_tal_notify_tx_abort(void *handle, const void *priv, - const void *pkt_priv) -{ - pr_debug("%s: tx_abort received for pkt_priv:%pK\n", - __func__, pkt_priv); - apr_free_buf(pkt_priv); -} - -void apr_tal_notify_tx_done(void *handle, const void *priv, - const void *pkt_priv, const void *ptr) -{ - pr_debug("%s: tx_done received for pkt_priv:%pK\n", - __func__, pkt_priv); - apr_free_buf(pkt_priv); -} - -bool apr_tal_notify_rx_intent_req(void *handle, const void *priv, - size_t req_size) -{ - struct apr_svc_ch_dev *apr_ch = (struct apr_svc_ch_dev *)priv; - - if (!apr_ch) { - pr_err("%s: Invalid apr_ch\n", __func__); - return false; - } - - pr_err("%s: No rx intents queued, unable to receive\n", __func__); - return false; -} - -static void apr_tal_notify_remote_rx_intent(void *handle, const void *priv, - size_t size) -{ - struct apr_svc_ch_dev *apr_ch = (struct apr_svc_ch_dev *)priv; - - if (!apr_ch) { - pr_err("%s: Invalid apr_ch\n", __func__); - return; - } - /* - * This is to make sure that the far end has queued at least one intent - * before we attmpt any IPC. A simple bool flag is used here instead of - * a counter, as the far end is required to guarantee intent - * availability for all use cases once the channel is fully opened. - */ - pr_debug("%s: remote queued an intent\n", __func__); - apr_ch->if_remote_intent_ready = true; - wake_up(&apr_ch->wait); -} - -void apr_tal_notify_state(void *handle, const void *priv, unsigned int event) -{ - struct apr_svc_ch_dev *apr_ch = (struct apr_svc_ch_dev *)priv; - - if (!apr_ch) { - pr_err("%s: Invalid apr_ch\n", __func__); - return; - } - - apr_ch->channel_state = event; - pr_info("%s: Channel state[%d]\n", __func__, event); - - if (event == GLINK_CONNECTED) - wake_up(&apr_ch->wait); -} - -int apr_tal_rx_intents_config(struct apr_svc_ch_dev *apr_ch, - int num_of_intents, uint32_t size) -{ - int i; - int rc = 0; - - if (!apr_ch || !num_of_intents || !size) { - pr_err("%s: Invalid parameter\n", __func__); - return -EINVAL; - } - - for (i = 0; i < num_of_intents; i++) { - rc = glink_queue_rx_intent(apr_ch->handle, apr_ch, size); - if (rc) { - pr_err("%s: Failed to queue rx intent, iteration[%d]\n", - __func__, i); - break; - } - } - - return rc; -} - -struct apr_svc_ch_dev *apr_tal_open(uint32_t clnt, uint32_t dest, uint32_t dl, - apr_svc_cb_fn func, void *priv) -{ - int rc; - struct glink_open_config open_cfg; - struct apr_svc_ch_dev *apr_ch; - - if ((clnt >= APR_CLIENT_MAX) || (dest >= APR_DEST_MAX) || - (dl >= APR_DL_MAX)) { - pr_err("%s: Invalid params, clnt:%d, dest:%d, dl:%d\n", - __func__, clnt, dest, dl); - return NULL; - } - - apr_ch = &apr_svc_ch[dl][dest][clnt]; - mutex_lock(&apr_ch->m_lock); - if (apr_ch->handle) { - pr_err("%s: This channel is already opened\n", __func__); - rc = -EBUSY; - goto unlock; - } - - if (link_state[dest].link_state != GLINK_LINK_STATE_UP) { - rc = wait_event_timeout(link_state[dest].wait, - link_state[dest].link_state == GLINK_LINK_STATE_UP, - msecs_to_jiffies(APR_OPEN_TIMEOUT_MS)); - if (rc == 0) { - pr_err("%s: Open timeout, dest:%d\n", __func__, dest); - rc = -ETIMEDOUT; - goto unlock; - } - pr_debug("%s: Wakeup done, dest:%d\n", __func__, dest); - } - - memset(&open_cfg, 0, sizeof(struct glink_open_config)); - open_cfg.options = GLINK_OPT_INITIAL_XPORT; - if (dest == APR_DEST_MODEM) - open_cfg.edge = "mpss"; - else - open_cfg.edge = "lpass"; - - open_cfg.name = svc_names[dest][clnt]; - open_cfg.notify_rx = apr_tal_notify_rx; - open_cfg.notify_tx_done = apr_tal_notify_tx_done; - open_cfg.notify_state = apr_tal_notify_state; - open_cfg.notify_rx_intent_req = apr_tal_notify_rx_intent_req; - open_cfg.notify_remote_rx_intent = apr_tal_notify_remote_rx_intent; - open_cfg.notify_tx_abort = apr_tal_notify_tx_abort; - open_cfg.priv = apr_ch; - open_cfg.transport = "smem"; - - apr_ch->channel_state = GLINK_REMOTE_DISCONNECTED; - apr_ch->handle = glink_open(&open_cfg); - if (IS_ERR_OR_NULL(apr_ch->handle)) { - pr_err("%s: glink_open failed %s\n", __func__, - svc_names[dest][clnt]); - apr_ch->handle = NULL; - rc = -EINVAL; - goto unlock; - } - - rc = wait_event_timeout(apr_ch->wait, - (apr_ch->channel_state == GLINK_CONNECTED), 5 * HZ); - if (rc == 0) { - pr_err("%s: TIMEOUT for OPEN event\n", __func__); - rc = -ETIMEDOUT; - goto close_link; - } - - /* - * Remote intent is not required for GLINK <--> SMD IPC, so this is - * designed not to fail the open call. - */ - rc = wait_event_timeout(apr_ch->wait, - apr_ch->if_remote_intent_ready, 5 * HZ); - if (rc == 0) - pr_err("%s: TIMEOUT for remote intent readiness\n", __func__); - - rc = apr_tal_rx_intents_config(apr_ch, APR_DEFAULT_NUM_OF_INTENTS, - APR_MAX_BUF); - if (rc) { - pr_err("%s: Unable to queue intents\n", __func__); - goto close_link; - } - - apr_ch->func = func; - apr_ch->priv = priv; - -close_link: - if (rc) { - glink_close(apr_ch->handle); - apr_ch->handle = NULL; - } -unlock: - mutex_unlock(&apr_ch->m_lock); - - return rc ? NULL : apr_ch; -} - -int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch) -{ - int rc = 0; - - if (!apr_ch || !apr_ch->handle) { - rc = -EINVAL; - goto exit; - } - - mutex_lock(&apr_ch->m_lock); - rc = glink_start_rx_rt(apr_ch->handle); - mutex_unlock(&apr_ch->m_lock); -exit: - return rc; -} - -int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch) -{ - int rc = 0; - - if (!apr_ch || !apr_ch->handle) { - rc = -EINVAL; - goto exit; - } - - mutex_lock(&apr_ch->m_lock); - rc = glink_end_rx_rt(apr_ch->handle); - mutex_unlock(&apr_ch->m_lock); -exit: - return rc; -} - -int apr_tal_close(struct apr_svc_ch_dev *apr_ch) -{ - int rc; - - if (!apr_ch || !apr_ch->handle) { - rc = -EINVAL; - goto exit; - } - - mutex_lock(&apr_ch->m_lock); - rc = glink_close(apr_ch->handle); - apr_ch->handle = NULL; - apr_ch->func = NULL; - apr_ch->priv = NULL; - apr_ch->if_remote_intent_ready = false; - mutex_unlock(&apr_ch->m_lock); -exit: - return rc; -} - -static void apr_tal_link_state_cb(struct glink_link_state_cb_info *cb_info, - void *priv) -{ - uint32_t dest; - - if (!cb_info) { - pr_err("%s: Invalid cb_info\n", __func__); - return; - } - - if (!strcmp(cb_info->edge, "mpss")) - dest = APR_DEST_MODEM; - else if (!strcmp(cb_info->edge, "lpass")) - dest = APR_DEST_QDSP6; - else { - pr_err("%s:Unknown edge[%s]\n", __func__, cb_info->edge); - return; - } - - pr_info("%s: edge[%s] link state[%d]\n", __func__, cb_info->edge, - cb_info->link_state); - - link_state[dest].link_state = cb_info->link_state; - if (link_state[dest].link_state == GLINK_LINK_STATE_UP) - wake_up(&link_state[dest].wait); -} - -static struct glink_link_info mpss_link_info = { - .transport = "smem", - .edge = "mpss", - .glink_link_state_notif_cb = apr_tal_link_state_cb, -}; - -static struct glink_link_info lpass_link_info = { - .transport = "smem", - .edge = "lpass", - .glink_link_state_notif_cb = apr_tal_link_state_cb, -}; - -int apr_tal_init(void) -{ - int i, j, k; - - for (i = 0; i < APR_DL_MAX; i++) { - for (j = 0; j < APR_DEST_MAX; j++) { - for (k = 0; k < APR_CLIENT_MAX; k++) { - init_waitqueue_head(&apr_svc_ch[i][j][k].wait); - spin_lock_init(&apr_svc_ch[i][j][k].w_lock); - spin_lock_init(&apr_svc_ch[i][j][k].r_lock); - mutex_init(&apr_svc_ch[i][j][k].m_lock); - } - } - } - - for (i = 0; i < APR_DEST_MAX; i++) - init_waitqueue_head(&link_state[i].wait); - - link_state[APR_DEST_MODEM].link_state = GLINK_LINK_STATE_DOWN; - link_state[APR_DEST_MODEM].handle = - glink_register_link_state_cb(&mpss_link_info, NULL); - if (!link_state[APR_DEST_MODEM].handle) - pr_err("%s: Unable to register mpss link state\n", __func__); - - link_state[APR_DEST_QDSP6].link_state = GLINK_LINK_STATE_DOWN; - link_state[APR_DEST_QDSP6].handle = - glink_register_link_state_cb(&lpass_link_info, NULL); - if (!link_state[APR_DEST_QDSP6].handle) - pr_err("%s: Unable to register lpass link state\n", __func__); - - return 0; -} -- GitLab From cc0a22d9d161a1f0395b86d15c733588af4dd3f2 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 2 Mar 2018 06:29:57 +0530 Subject: [PATCH 0200/1645] ASoC: wcd934x: Add support for WCD934x on msmnile target Add support for WCD934x codec on msmnile target for audio playback and capture usecases. Change-Id: Ia91fd532fcb3a127941f8dc7ba42aecea17a5ec2 Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd934x/Android.mk | 6 +++++- asoc/codecs/wcd934x/Kbuild | 5 +++++ asoc/codecs/wcd934x/wcd934x-dsp-cntl.h | 3 ++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd934x/Android.mk b/asoc/codecs/wcd934x/Android.mk index 0fe519ffded7..200f6c36a6ab 100644 --- a/asoc/codecs/wcd934x/Android.mk +++ b/asoc/codecs/wcd934x/Android.mk @@ -7,13 +7,17 @@ ifeq ($(call is-board-platform,sdm845),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m endif +ifeq ($(call is-board-platform,msmnile),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m +endif + ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index 7ea91ce677e1..60b24853e37f 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -31,6 +31,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM855), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h index 2f71d0e18edb..0127a0df2dba 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -14,6 +14,7 @@ #ifndef __WCD934X_DSP_CNTL_H__ #define __WCD934X_DSP_CNTL_H__ +#include #include #include -- GitLab From 9851706e7956428d2dc76a93aa7f3bb7ed936e1b Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 2 Mar 2018 06:32:16 +0530 Subject: [PATCH 0201/1645] ASoC: config: Enable configuration for WCD934x codec Enable configuration for WCD934x codec for msmnile target. Change-Id: I88bdc85b8f654c5658b84a4732b0a67ca1fcad1b Signed-off-by: Sudheer Papothi --- config/sdm855auto.conf | 3 +++ config/sdm855autoconf.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/config/sdm855auto.conf b/config/sdm855auto.conf index 2ebdce0379a4..fe02f7212854 100644 --- a/config/sdm855auto.conf +++ b/config/sdm855auto.conf @@ -6,6 +6,9 @@ CONFIG_SND_SOC_WSA881X=m CONFIG_SND_SOC_WCD9360=m CONFIG_SND_SOC_WCD_DSP_MGR=m CONFIG_SND_SOC_WCD_SPI=m +CONFIG_SND_SOC_WCD934X=m +CONFIG_SND_SOC_WCD934X_MBHC=m +CONFIG_SND_SOC_WCD934X_DSD=m CONFIG_SND_SOC_WCD_CPE=m CONFIG_SOUNDWIRE_WCD_CTRL=m CONFIG_WCD9XXX_CODEC_CORE=m diff --git a/config/sdm855autoconf.h b/config/sdm855autoconf.h index 651b04a49a04..94a6dc557756 100644 --- a/config/sdm855autoconf.h +++ b/config/sdm855autoconf.h @@ -18,6 +18,9 @@ #define CONFIG_SND_SOC_WCD9360 1 #define CONFIG_SND_SOC_WCD_DSP_MGR 1 #define CONFIG_SND_SOC_WCD_SPI 1 +#define CONFIG_SND_SOC_WCD934X 1 +#define CONFIG_SND_SOC_WCD934X_MBHC 1 +#define CONFIG_SND_SOC_WCD934X_DSD 1 #define CONFIG_SND_SOC_WCD_CPE 1 #define CONFIG_WCD9XXX_CODEC_CORE 1 #define CONFIG_MSM_CDC_PINCTRL 1 -- GitLab From d188b9586c5542fa5ec7b4d3d62a52585f2406c1 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Sat, 3 Mar 2018 01:24:56 -0800 Subject: [PATCH 0202/1645] dsp: update dma_buf cache ops Update the API call sequence for cache operation for dma_buf. Change-Id: I79ee36d083460b47c792120a857e92f26d9e3fe2 Signed-off-by: Banajit Goswami --- dsp/msm_audio_ion.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index 6ba29dce1075..a544dde71ad1 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -599,18 +599,11 @@ int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op) /* MSM_AUDIO_ION_INV_CACHES or MSM_AUDIO_ION_CLEAN_CACHES */ switch (cache_op) { case MSM_AUDIO_ION_INV_CACHES: - rc = dma_buf_begin_cpu_access(abuff->dma_buf, - DMA_BIDIRECTIONAL); - if (rc) - pr_err("%s: failed to invalidate caches. rc = %d\n", - __func__, rc); - break; case MSM_AUDIO_ION_CLEAN_CACHES: - rc = dma_buf_end_cpu_access(abuff->dma_buf, - DMA_BIDIRECTIONAL); - if (rc) - pr_err("%s: failed to clean caches. rc = %d\n", - __func__, rc); + dma_buf_begin_cpu_access(abuff->dma_buf, + DMA_BIDIRECTIONAL); + dma_buf_end_cpu_access(abuff->dma_buf, + DMA_BIDIRECTIONAL); break; default: pr_err("%s: Invalid cache operation %d\n", -- GitLab From 5c10992ad9af22f8e729ddee5fc8dd3ebd7acb3d Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Wed, 24 Jan 2018 17:36:18 -0800 Subject: [PATCH 0203/1645] ASoC: Expose APIs to get and set Instance ID support Expose APIs to get and set instance ID support by exposing a mixer control for userspace to set the support status as well as APIs for kernel components to querry for instance ID support. CRs-Fixed: 2151551 Change-Id: I3b462a4c0f31152a2865af8f4e9664a6c4d324c3 Signed-off-by: Vignesh Kulothungan --- asoc/msm-pcm-routing-v2.c | 47 ++++++++++++++++++++++++++++++++++++++- dsp/Kbuild | 1 + dsp/q6common.c | 43 +++++++++++++++++++++++++++++++++++ include/dsp/q6common.h | 21 +++++++++++++++++ 4 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 dsp/q6common.c create mode 100644 include/dsp/q6common.h diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index ff2be80b13e6..2b6a69f0bb29 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -37,6 +37,7 @@ #include #include #include +#include #include #include "msm-pcm-routing-v2.h" @@ -16829,6 +16830,46 @@ static const struct snd_kcontrol_new stereo_channel_reverse_control[] = { msm_routing_stereo_channel_reverse_control_put), }; +static int msm_routing_instance_id_support_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + return 0; +} + +static int msm_routing_instance_id_support_put( + struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + bool supported = ucontrol->value.integer.value[0] ? true : false; + + q6common_update_instance_id_support(supported); + return 0; +} + +static int msm_routing_instance_id_support_get( + struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + bool supported = false; + + supported = q6common_is_instance_id_supported(); + ucontrol->value.integer.value[0] = supported ? 1 : 0; + + return 0; +} + +static const struct snd_kcontrol_new + msm_routing_feature_support_mixer_controls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_READ | + SNDRV_CTL_ELEM_ACCESS_WRITE, + .info = msm_routing_instance_id_support_info, + .name = "Instance ID Support", + .put = msm_routing_instance_id_support_put, + .get = msm_routing_instance_id_support_get, + }, +}; + static const struct snd_pcm_ops msm_routing_pcm_ops = { .hw_params = msm_pcm_routing_hw_params, .close = msm_pcm_routing_close, @@ -16900,6 +16941,10 @@ static int msm_routing_probe(struct snd_soc_platform *platform) ARRAY_SIZE(aptx_dec_license_controls)); snd_soc_add_platform_controls(platform, stereo_channel_reverse_control, ARRAY_SIZE(stereo_channel_reverse_control)); + snd_soc_add_platform_controls( + platform, msm_routing_feature_support_mixer_controls, + ARRAY_SIZE(msm_routing_feature_support_mixer_controls)); + return 0; } diff --git a/dsp/Kbuild b/dsp/Kbuild index 2bf3b26a99cd..3eeca047e778 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -73,6 +73,7 @@ ifdef CONFIG_SND_SOC_MSM_QDSP6V2_INTF Q6_OBJS += q6audio-v2.o Q6_OBJS += q6voice.o Q6_OBJS += q6core.o + Q6_OBJS += q6common.o Q6_OBJS += rtac.o Q6_OBJS += q6lsm.o Q6_OBJS += audio_slimslave.o diff --git a/dsp/q6common.c b/dsp/q6common.c new file mode 100644 index 000000000000..014ab4ce4d3f --- /dev/null +++ b/dsp/q6common.c @@ -0,0 +1,43 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +struct q6common_ctl { + bool instance_id_supported; +}; + +static struct q6common_ctl common; + +/** + * q6common_update_instance_id_support + * + * Update instance ID support flag to true/false + * + * @supported: enable/disable for instance ID support + */ +void q6common_update_instance_id_support(bool supported) +{ + common.instance_id_supported = supported; +} +EXPORT_SYMBOL(q6common_update_instance_id_support); + +/** + * q6common_is_instance_id_supported + * + * Returns true/false for instance ID support + */ +bool q6common_is_instance_id_supported(void) +{ + return common.instance_id_supported; +} +EXPORT_SYMBOL(q6common_is_instance_id_supported); diff --git a/include/dsp/q6common.h b/include/dsp/q6common.h new file mode 100644 index 000000000000..587a6b645d56 --- /dev/null +++ b/include/dsp/q6common.h @@ -0,0 +1,21 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __Q6COMMON_H__ +#define __Q6COMMON_H__ + +#include + +void q6common_update_instance_id_support(bool supported); +bool q6common_is_instance_id_supported(void); + +#endif /* __Q6COMMON_H__ */ -- GitLab From 13d0d3561f282bdd7f231e6da4b0e463755bdc2f Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Wed, 24 Jan 2018 17:43:25 -0800 Subject: [PATCH 0204/1645] ASoC: dsp: Add utility function needed for Instance ID Add common structures and definitions used to support instance ID. Add helper function to populate header based on instance ID support and pack it with payload data. CRs-Fixed: 2151551 Change-Id: If9b7e497d0e8fdfed7d62a1ee34c415baabdda07 Signed-off-by: Vignesh Kulothungan --- dsp/q6common.c | 70 +++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 103 ++++++++++++++++++++++++++++++++++++- include/dsp/q6common.h | 4 +- 3 files changed, 175 insertions(+), 2 deletions(-) diff --git a/dsp/q6common.c b/dsp/q6common.c index 014ab4ce4d3f..7a186dc566c7 100644 --- a/dsp/q6common.c +++ b/dsp/q6common.c @@ -41,3 +41,73 @@ bool q6common_is_instance_id_supported(void) return common.instance_id_supported; } EXPORT_SYMBOL(q6common_is_instance_id_supported); + +/** + * q6common_pack_pp_params + * + * Populate params header based on instance ID support and pack + * it with payload. + * Instance ID support - + * yes - param_hdr_v3 + payload + * no - param_hdr_v1 + payload + * + * @dest: destination data pointer to be packed into + * @v3_hdr: param header v3 + * @param_data: param payload + * @total_size: total size of packed data (hdr + payload) + * + * Returns 0 on success or error on failure + */ +int q6common_pack_pp_params(u8 *dest, struct param_hdr_v3 *v3_hdr, + u8 *param_data, u32 *total_size) +{ + struct param_hdr_v1 *v1_hdr = NULL; + u32 packed_size = 0; + u32 param_size = 0; + bool iid_supported = q6common_is_instance_id_supported(); + + if (dest == NULL) { + pr_err("%s: Received NULL pointer for destination\n", __func__); + return -EINVAL; + } else if (v3_hdr == NULL) { + pr_err("%s: Received NULL pointer for header\n", __func__); + return -EINVAL; + } else if (total_size == NULL) { + pr_err("%s: Received NULL pointer for total size\n", __func__); + return -EINVAL; + } + + param_size = v3_hdr->param_size; + packed_size = iid_supported ? sizeof(struct param_hdr_v3) : + sizeof(struct param_hdr_v1); + + if (iid_supported) { + memcpy(dest, v3_hdr, packed_size); + } else { + v1_hdr = (struct param_hdr_v1 *) dest; + v1_hdr->module_id = v3_hdr->module_id; + v1_hdr->param_id = v3_hdr->param_id; + + if (param_size > U16_MAX) { + pr_err("%s: Invalid param size for V1 %d\n", __func__, + param_size); + return -EINVAL; + } + v1_hdr->param_size = param_size; + v1_hdr->reserved = 0; + } + + /* + * Make param_data optional for cases when there is no data + * present as in some set cases and all get cases. + */ + if (param_data != NULL) { + memcpy(dest + packed_size, param_data, param_size); + packed_size += param_size; + } + + *total_size = packed_size; + + return 0; +} +EXPORT_SYMBOL(q6common_pack_pp_params); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 4cef82ef065d..3c2f86ffbe9e 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -29,6 +29,107 @@ struct param_outband { phys_addr_t paddr; }; +/* Common structures and definitions used for instance ID support */ +/* Instance ID definitions */ +#define INSTANCE_ID_0 0x0000 + +struct mem_mapping_hdr { + /* + * LSW of parameter data payload address. Supported values: any. + * - Must be set to zero for in-band data. + */ + u32 data_payload_addr_lsw; + + /* + * MSW of Parameter data payload address. Supported values: any. + * - Must be set to zero for in-band data. + * - In the case of 32 bit Shared memory address, MSW field must be + * set to zero. + * - In the case of 36 bit shared memory address, bit 31 to bit 4 of + * MSW must be set to zero. + */ + u32 data_payload_addr_msw; + + /* + * Memory map handle returned by DSP through + * ASM_CMD_SHARED_MEM_MAP_REGIONS command. + * Supported Values: Any. + * If memory map handle is NULL, the parameter data payloads are + * within the message payload (in-band). + * If memory map handle is non-NULL, the parameter data payloads begin + * at the address specified in the address MSW and LSW (out-of-band). + */ + u32 mem_map_handle; + +} __packed; + +/* + * Payload format for parameter data. + * Immediately following these structures are param_size bytes of parameter + * data. + */ +struct param_hdr_v1 { + /* Valid ID of the module. */ + uint32_t module_id; + + /* Valid ID of the parameter. */ + uint32_t param_id; + + /* The size of the parameter specified by the module/param ID combo */ + uint16_t param_size; + + /* This field must be set to zero. */ + uint16_t reserved; +} __packed; + +struct param_hdr_v2 { + /* Valid ID of the module. */ + uint32_t module_id; + + /* Valid ID of the parameter. */ + uint32_t param_id; + + /* The size of the parameter specified by the module/param ID combo */ + uint32_t param_size; +} __packed; + +struct param_hdr_v3 { + /* Valid ID of the module. */ + uint32_t module_id; + + /* Instance of the module. */ + uint16_t instance_id; + + /* This field must be set to zero. */ + uint16_t reserved; + + /* Valid ID of the parameter. */ + uint32_t param_id; + + /* The size of the parameter specified by the module/param ID combo */ + uint32_t param_size; +} __packed; + +/* A union of all param_hdr versions for versitility and max size */ +union param_hdrs { + struct param_hdr_v1 v1; + struct param_hdr_v2 v2; + struct param_hdr_v3 v3; +}; + +struct module_instance_info { + /* Module ID. */ + u32 module_id; + + /* Instance of the module */ + u16 instance_id; + + /* Reserved. This field must be set to zero. */ + u16 reserved; +} __packed; + +/* Begin service specific definitions and structures */ + #define ADSP_ADM_VERSION 0x00070000 #define ADM_CMD_SHARED_MEM_MAP_REGIONS 0x00010322 diff --git a/include/dsp/q6common.h b/include/dsp/q6common.h index 587a6b645d56..552f97632d4d 100644 --- a/include/dsp/q6common.h +++ b/include/dsp/q6common.h @@ -13,9 +13,11 @@ #ifndef __Q6COMMON_H__ #define __Q6COMMON_H__ -#include +#include void q6common_update_instance_id_support(bool supported); bool q6common_is_instance_id_supported(void); +int q6common_pack_pp_params(u8 *dest, struct param_hdr_v3 *v3_hdr, + u8 *param_data, u32 *total_size); #endif /* __Q6COMMON_H__ */ -- GitLab From a65e3010a2734c572d9c2c86ac9743b6dc5583fb Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Wed, 24 Jan 2018 18:03:12 -0800 Subject: [PATCH 0205/1645] ASoC: dsp: Update LSM driver to support Instance ID Add support to set and get LSM module params with Instance ID support. Maintain support for non Instance ID set and get param structures as well. CRs-Fixed: 2151551 Change-Id: Id9aa5ee89bab1a4e15ff1f7868bceb42d6c25d19 Signed-off-by: Vignesh Kulothungan --- dsp/q6lsm.c | 934 ++++++++++++++++++------------------- include/dsp/apr_audio-v2.h | 1 + include/dsp/q6lsm.h | 120 +---- 3 files changed, 475 insertions(+), 580 deletions(-) diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 0dd6dbddce23..108e4be4026b 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "adsp_err.h" @@ -73,11 +74,6 @@ struct lsm_common { struct mutex apr_lock; }; -struct lsm_module_param_ids { - uint32_t module_id; - uint32_t param_id; -}; - static struct lsm_common lsm_common; /* * mmap_handle_p can point either client->sound_model.mem_map_handle or @@ -98,38 +94,6 @@ static int q6lsm_memory_map_regions(struct lsm_client *client, static int q6lsm_memory_unmap_regions(struct lsm_client *client, uint32_t handle); -static void q6lsm_set_param_hdr_info( - struct lsm_set_params_hdr *param_hdr, - u32 payload_size, u32 addr_lsw, u32 addr_msw, - u32 mmap_handle) -{ - param_hdr->data_payload_size = payload_size; - param_hdr->data_payload_addr_lsw = addr_lsw; - param_hdr->data_payload_addr_msw = addr_msw; - param_hdr->mem_map_handle = mmap_handle; -} - -static void q6lsm_set_param_common( - struct lsm_param_payload_common *common, - struct lsm_module_param_ids *ids, - u32 param_size, u32 set_param_version) -{ - common->module_id = ids->module_id; - common->param_id = ids->param_id; - - switch (set_param_version) { - case LSM_SESSION_CMD_SET_PARAMS_V2: - common->p_size.param_size = param_size; - break; - case LSM_SESSION_CMD_SET_PARAMS: - default: - common->p_size.sr.param_size = - (u16) param_size; - common->p_size.sr.reserved = 0; - break; - } -} - static int q6lsm_callback(struct apr_client_data *data, void *priv) { struct lsm_client *client = (struct lsm_client *)priv; @@ -204,6 +168,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) case LSM_SESSION_CMD_OPEN_TX_V2: case LSM_CMD_ADD_TOPOLOGIES: case LSM_SESSION_CMD_SET_PARAMS_V2: + case LSM_SESSION_CMD_SET_PARAMS_V3: if (token != client->session && payload[0] != LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL) { @@ -462,6 +427,184 @@ static void q6lsm_add_hdr(struct lsm_client *client, struct apr_hdr *hdr, hdr->token = client->session; } +static int q6lsm_pack_params(u8 *dest, struct param_hdr_v3 *param_info, + u8 *param_data, size_t *final_length, + u32 set_param_opcode) +{ + bool iid_supported = q6common_is_instance_id_supported(); + union param_hdrs *param_hdr = NULL; + u32 param_size = param_info->param_size; + size_t hdr_size; + size_t provided_size = *final_length; + + hdr_size = iid_supported ? sizeof(struct param_hdr_v3) : + sizeof(struct param_hdr_v2); + if (provided_size < hdr_size) { + pr_err("%s: Provided size %zu is not large enough, need %zu\n", + __func__, provided_size, hdr_size); + return -EINVAL; + } + + if (iid_supported) { + memcpy(dest, param_info, hdr_size); + } else { + /* MID, PID and structure size are the same in V1 and V2 */ + param_hdr = (union param_hdrs *) dest; + param_hdr->v2.module_id = param_info->module_id; + param_hdr->v2.param_id = param_info->param_id; + + switch (set_param_opcode) { + case LSM_SESSION_CMD_SET_PARAMS_V2: + param_hdr->v2.param_size = param_size; + break; + case LSM_SESSION_CMD_SET_PARAMS: + default: + if (param_size > U16_MAX) { + pr_err("%s: Invalid param size %d\n", __func__, + param_size); + return -EINVAL; + } + + param_hdr->v1.param_size = param_size; + param_hdr->v1.reserved = 0; + break; + } + } + + *final_length = hdr_size; + + if (param_data != NULL) { + if (provided_size < hdr_size + param_size) { + pr_err("%s: Provided size %zu is not large enough, need %zu\n", + __func__, provided_size, hdr_size + param_size); + return -EINVAL; + } + memcpy(dest + hdr_size, param_data, param_size); + *final_length += param_size; + } + return 0; +} + +static int q6lsm_set_params_v2(struct lsm_client *client, + struct mem_mapping_hdr *mem_hdr, + uint8_t *param_data, uint32_t param_size, + uint32_t set_param_opcode) +{ + struct lsm_session_cmd_set_params_v2 *lsm_set_param = NULL; + uint32_t pkt_size = 0; + int ret; + + pkt_size = sizeof(struct lsm_session_cmd_set_params_v2); + /* Only include param size in packet size when inband */ + if (param_data != NULL) + pkt_size += param_size; + + lsm_set_param = kzalloc(pkt_size, GFP_KERNEL); + if (!lsm_set_param) + return -ENOMEM; + + q6lsm_add_hdr(client, &lsm_set_param->apr_hdr, pkt_size, true); + lsm_set_param->apr_hdr.opcode = set_param_opcode; + lsm_set_param->payload_size = param_size; + + if (mem_hdr != NULL) { + lsm_set_param->mem_hdr = *mem_hdr; + } else if (param_data != NULL) { + memcpy(lsm_set_param->param_data, param_data, param_size); + } else { + pr_err("%s: Received NULL pointers for both memory header and data\n", + __func__); + ret = -EINVAL; + goto done; + } + + ret = q6lsm_apr_send_pkt(client, client->apr, lsm_set_param, true, + NULL); +done: + kfree(lsm_set_param); + return ret; +} + +static int q6lsm_set_params_v3(struct lsm_client *client, + struct mem_mapping_hdr *mem_hdr, + uint8_t *param_data, uint32_t param_size) +{ + struct lsm_session_cmd_set_params_v3 *lsm_set_param = NULL; + uint16_t pkt_size = 0; + int ret = 0; + + pkt_size = sizeof(struct lsm_session_cmd_set_params_v3); + /* Only include param size in packet size when inband */ + if (param_data != NULL) + pkt_size += param_size; + + lsm_set_param = kzalloc(pkt_size, GFP_KERNEL); + if (!lsm_set_param) + return -ENOMEM; + + q6lsm_add_hdr(client, &lsm_set_param->apr_hdr, pkt_size, true); + lsm_set_param->apr_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS_V3; + lsm_set_param->payload_size = param_size; + + if (mem_hdr != NULL) { + lsm_set_param->mem_hdr = *mem_hdr; + } else if (param_data != NULL) { + memcpy(lsm_set_param->param_data, param_data, param_size); + } else { + pr_err("%s: Received NULL pointers for both memory header and data\n", + __func__); + ret = -EINVAL; + goto done; + } + + ret = q6lsm_apr_send_pkt(client, client->apr, lsm_set_param, true, + NULL); +done: + kfree(lsm_set_param); + return ret; +} + +static int q6lsm_set_params(struct lsm_client *client, + struct mem_mapping_hdr *mem_hdr, + uint8_t *param_data, uint32_t param_size, + uint32_t set_param_opcode) + +{ + if (q6common_is_instance_id_supported()) + return q6lsm_set_params_v3(client, mem_hdr, param_data, + param_size); + else + return q6lsm_set_params_v2(client, mem_hdr, param_data, + param_size, set_param_opcode); +} + +static int q6lsm_pack_and_set_params(struct lsm_client *client, + struct param_hdr_v3 *param_info, + uint8_t *param_data, + uint32_t set_param_opcode) + +{ + u8 *packed_data = NULL; + size_t total_size = 0; + int ret = 0; + + total_size = sizeof(union param_hdrs) + param_info->param_size; + packed_data = kzalloc(total_size, GFP_KERNEL); + if (!packed_data) + return -ENOMEM; + + ret = q6lsm_pack_params(packed_data, param_info, param_data, + &total_size, set_param_opcode); + if (ret) + goto done; + + ret = q6lsm_set_params(client, NULL, packed_data, total_size, + set_param_opcode); + +done: + kfree(packed_data); + return ret; +} static int q6lsm_send_custom_topologies(struct lsm_client *client) { @@ -624,14 +767,20 @@ void q6lsm_sm_set_param_data(struct lsm_client *client, struct lsm_params_info *p_info, size_t *offset) { - struct lsm_param_payload_common *param; - - param = (struct lsm_param_payload_common *) - client->sound_model.data; - param->module_id = p_info->module_id; - param->param_id = p_info->param_id; - param->p_size.param_size = client->sound_model.size; - *offset = sizeof(*param); + struct param_hdr_v3 param_hdr; + int ret = 0; + + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = p_info->module_id; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = p_info->param_id; + param_hdr.param_size = client->sound_model.size; + + ret = q6lsm_pack_params(client->sound_model.data, ¶m_hdr, + NULL, offset, LSM_SESSION_CMD_SET_PARAMS_V2); + if (ret) + pr_err("%s: Failed to pack params, error %d\n", __func__, ret); } EXPORT_SYMBOL(q6lsm_sm_set_param_data); @@ -693,106 +842,65 @@ int q6lsm_open(struct lsm_client *client, uint16_t app_id) } EXPORT_SYMBOL(q6lsm_open); -static int q6lsm_send_confidence_levels( - struct lsm_client *client, - struct lsm_module_param_ids *ids, - u32 set_param_opcode) +static int q6lsm_send_confidence_levels(struct lsm_client *client, + struct param_hdr_v3 *param_info, + uint32_t set_param_opcode) { - u8 *packet; - size_t pkt_size; - struct lsm_cmd_set_params_conf *conf_params; - struct apr_hdr *msg_hdr; - struct lsm_param_min_confidence_levels *cfl; + struct lsm_param_confidence_levels *conf_levels = NULL; + uint32_t num_conf_levels = client->num_confidence_levels; uint8_t i = 0; uint8_t padd_size = 0; - u8 *conf_levels; - int rc; - u32 payload_size, param_size; + uint32_t param_size = 0; + int rc = 0; - padd_size = (4 - (client->num_confidence_levels % 4)) - 1; - pkt_size = sizeof(*conf_params) + padd_size + - client->num_confidence_levels; + /* Data must be 4 byte aligned so add any necessary padding. */ + padd_size = (4 - (num_conf_levels % 4)) - 1; + param_size = (sizeof(uint8_t) + num_conf_levels + padd_size) * + sizeof(uint8_t); + param_info->param_size = param_size; + pr_debug("%s: Set Conf Levels PARAM SIZE = %d\n", __func__, param_size); - packet = kzalloc(pkt_size, GFP_KERNEL); - if (!packet) + conf_levels = kzalloc(param_size, GFP_KERNEL); + if (!conf_levels) return -ENOMEM; - conf_params = (struct lsm_cmd_set_params_conf *) packet; - conf_levels = (u8 *) (packet + sizeof(*conf_params)); - msg_hdr = &conf_params->msg_hdr; - q6lsm_add_hdr(client, msg_hdr, - pkt_size, true); - msg_hdr->opcode = set_param_opcode; - payload_size = pkt_size - sizeof(*msg_hdr) - - sizeof(conf_params->params_hdr); - q6lsm_set_param_hdr_info(&conf_params->params_hdr, - payload_size, 0, 0, 0); - cfl = &conf_params->conf_payload; - param_size = ((sizeof(uint8_t) + padd_size + - client->num_confidence_levels)) * - sizeof(uint8_t); - q6lsm_set_param_common(&cfl->common, ids, - param_size, set_param_opcode); - cfl->num_confidence_levels = client->num_confidence_levels; - - pr_debug("%s: CMD PARAM SIZE = %d\n", - __func__, param_size); - pr_debug("%s: Num conf_level = %d\n", - __func__, client->num_confidence_levels); - - memcpy(conf_levels, client->confidence_levels, - client->num_confidence_levels); - for (i = 0; i < client->num_confidence_levels; i++) - pr_debug("%s: Confidence_level[%d] = %d\n", - __func__, i, conf_levels[i]); + conf_levels->num_confidence_levels = num_conf_levels; + pr_debug("%s: Num conf_level = %d\n", __func__, num_conf_levels); - rc = q6lsm_apr_send_pkt(client, client->apr, - packet, true, NULL); + memcpy(conf_levels->confidence_levels, client->confidence_levels, + num_conf_levels); + for (i = 0; i < num_conf_levels; i++) + pr_debug("%s: Confidence_level[%d] = %d\n", __func__, i, + conf_levels->confidence_levels[i]); + + rc = q6lsm_pack_and_set_params(client, param_info, + (uint8_t *) conf_levels, + set_param_opcode); if (rc) - pr_err("%s: confidence_levels cmd failed, err = %d\n", - __func__, rc); - kfree(packet); + pr_err("%s: Send confidence_levels cmd failed, err = %d\n", + __func__, rc); + kfree(conf_levels); return rc; } static int q6lsm_send_param_opmode(struct lsm_client *client, - struct lsm_module_param_ids *opmode_ids, - u32 set_param_opcode) + struct param_hdr_v3 *param_info, + u32 set_param_opcode) { - int rc; - struct lsm_cmd_set_params_opmode opmode_params; - struct apr_hdr *msg_hdr; - - struct lsm_param_op_mode *op_mode; - u32 data_payload_size, param_size; - - msg_hdr = &opmode_params.msg_hdr; - q6lsm_add_hdr(client, msg_hdr, - sizeof(opmode_params), true); - msg_hdr->opcode = set_param_opcode; - data_payload_size = sizeof(opmode_params) - - sizeof(*msg_hdr) - - sizeof(opmode_params.params_hdr); - q6lsm_set_param_hdr_info(&opmode_params.params_hdr, - data_payload_size, 0, 0, 0); - op_mode = &opmode_params.op_mode; - - - param_size = sizeof(struct lsm_param_op_mode) - - sizeof(op_mode->common); - q6lsm_set_param_common(&op_mode->common, - opmode_ids, param_size, - set_param_opcode); - op_mode->minor_version = QLSM_PARAM_ID_MINOR_VERSION; - op_mode->mode = client->mode; - op_mode->reserved = 0; - pr_debug("%s: mode = 0x%x", __func__, op_mode->mode); + struct lsm_param_op_mode op_mode; + int rc = 0; - rc = q6lsm_apr_send_pkt(client, client->apr, - &opmode_params, true, NULL); + memset(&op_mode, 0, sizeof(op_mode)); + param_info->param_size = sizeof(op_mode); + + op_mode.minor_version = QLSM_PARAM_ID_MINOR_VERSION; + op_mode.mode = client->mode; + pr_debug("%s: mode = 0x%x", __func__, op_mode.mode); + + rc = q6lsm_pack_and_set_params(client, param_info, (uint8_t *) &op_mode, + set_param_opcode); if (rc) - pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", - __func__, msg_hdr->opcode, rc); + pr_err("%s: Failed set_params, rc %d\n", __func__, rc); pr_debug("%s: leave %d\n", __func__, rc); return rc; @@ -824,92 +932,57 @@ int get_lsm_port(void) */ int q6lsm_set_port_connected(struct lsm_client *client) { - int rc; - struct lsm_cmd_set_connectport connectport; - struct lsm_module_param_ids connectport_ids; - struct apr_hdr *msg_hdr; - struct lsm_param_connect_to_port *connect_to_port; - u32 data_payload_size, param_size, set_param_opcode; + struct lsm_param_connect_to_port connect_port; + struct param_hdr_v3 connectport_hdr; + u32 set_param_opcode = 0; + int rc = 0; + + memset(&connect_port, 0, sizeof(connect_port)); + memset(&connectport_hdr, 0, sizeof(connectport_hdr)); if (client->use_topology) { set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2; - connectport_ids.module_id = LSM_MODULE_ID_FRAMEWORK; - connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; + connectport_hdr.module_id = LSM_MODULE_ID_FRAMEWORK; } else { set_param_opcode = LSM_SESSION_CMD_SET_PARAMS; - connectport_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP; - connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; + connectport_hdr.module_id = LSM_MODULE_ID_VOICE_WAKEUP; } - client->connect_to_port = get_lsm_port(); + connectport_hdr.instance_id = INSTANCE_ID_0; + connectport_hdr.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; + connectport_hdr.param_size = sizeof(connect_port); - msg_hdr = &connectport.msg_hdr; - q6lsm_add_hdr(client, msg_hdr, - sizeof(connectport), true); - msg_hdr->opcode = set_param_opcode; - data_payload_size = sizeof(connectport) - - sizeof(*msg_hdr) - - sizeof(connectport.params_hdr); - q6lsm_set_param_hdr_info(&connectport.params_hdr, - data_payload_size, 0, 0, 0); - connect_to_port = &connectport.connect_to_port; - - param_size = (sizeof(struct lsm_param_connect_to_port) - - sizeof(connect_to_port->common)); - q6lsm_set_param_common(&connect_to_port->common, - &connectport_ids, param_size, - set_param_opcode); - connect_to_port->minor_version = QLSM_PARAM_ID_MINOR_VERSION; - connect_to_port->port_id = client->connect_to_port; - connect_to_port->reserved = 0; - pr_debug("%s: port= %d", __func__, connect_to_port->port_id); + client->connect_to_port = get_lsm_port(); + connect_port.minor_version = QLSM_PARAM_ID_MINOR_VERSION; + connect_port.port_id = client->connect_to_port; - rc = q6lsm_apr_send_pkt(client, client->apr, - &connectport, true, NULL); + rc = q6lsm_pack_and_set_params(client, &connectport_hdr, + (uint8_t *) &connect_port, + set_param_opcode); if (rc) - pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", - __func__, msg_hdr->opcode, rc); - + pr_err("%s: Failed set_params, rc %d\n", __func__, rc); return rc; } EXPORT_SYMBOL(q6lsm_set_port_connected); static int q6lsm_send_param_polling_enable(struct lsm_client *client, - bool poll_en, - struct lsm_module_param_ids *poll_enable_ids, - u32 set_param_opcode) + bool poll_en, + struct param_hdr_v3 *param_info, + u32 set_param_opcode) { + struct lsm_param_poll_enable polling_enable; int rc = 0; - struct lsm_cmd_poll_enable cmd; - struct apr_hdr *msg_hdr; - struct lsm_param_poll_enable *poll_enable; - u32 data_payload_size, param_size; - - msg_hdr = &cmd.msg_hdr; - q6lsm_add_hdr(client, msg_hdr, - sizeof(struct lsm_cmd_poll_enable), true); - msg_hdr->opcode = set_param_opcode; - data_payload_size = sizeof(struct lsm_cmd_poll_enable) - - sizeof(struct apr_hdr) - - sizeof(struct lsm_set_params_hdr); - q6lsm_set_param_hdr_info(&cmd.params_hdr, - data_payload_size, 0, 0, 0); - poll_enable = &cmd.poll_enable; - - param_size = (sizeof(struct lsm_param_poll_enable) - - sizeof(poll_enable->common)); - q6lsm_set_param_common(&poll_enable->common, - poll_enable_ids, param_size, - set_param_opcode); - poll_enable->minor_version = QLSM_PARAM_ID_MINOR_VERSION; - poll_enable->polling_enable = (poll_en) ? 1 : 0; - pr_debug("%s: poll enable= %d", __func__, poll_enable->polling_enable); - rc = q6lsm_apr_send_pkt(client, client->apr, - &cmd, true, NULL); - if (rc) - pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", - __func__, msg_hdr->opcode, rc); + memset(&polling_enable, 0, sizeof(polling_enable)); + param_info->param_size = sizeof(polling_enable); + polling_enable.minor_version = QLSM_PARAM_ID_MINOR_VERSION; + polling_enable.polling_enable = (poll_en) ? 1 : 0; + + rc = q6lsm_pack_and_set_params(client, param_info, + (uint8_t *) &polling_enable, + set_param_opcode); + if (rc) + pr_err("%s: Failed set_params, rc %d\n", __func__, rc); return rc; } @@ -925,48 +998,32 @@ static int q6lsm_send_param_polling_enable(struct lsm_client *client, int q6lsm_set_fwk_mode_cfg(struct lsm_client *client, uint32_t event_mode) { + struct lsm_param_fwk_mode_cfg fwk_mode_cfg; + struct param_hdr_v3 fwk_mode_cfg_hdr; int rc = 0; - struct lsm_cmd_set_fwk_mode_cfg cmd; - struct lsm_module_param_ids fwk_mode_cfg_ids; - struct apr_hdr *msg_hdr; - struct lsm_param_fwk_mode_cfg *fwk_mode_cfg; - u32 data_payload_size, param_size, set_param_opcode; - if (client->use_topology) { - set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2; - fwk_mode_cfg_ids.module_id = LSM_MODULE_ID_FRAMEWORK; - fwk_mode_cfg_ids.param_id = LSM_PARAM_ID_FWK_MODE_CONFIG; - } else { + memset(&fwk_mode_cfg, 0, sizeof(fwk_mode_cfg)); + memset(&fwk_mode_cfg_hdr, 0, sizeof(fwk_mode_cfg_hdr)); + + if (!client->use_topology) { pr_debug("%s: Ignore sending event mode\n", __func__); return rc; } - msg_hdr = &cmd.msg_hdr; - q6lsm_add_hdr(client, msg_hdr, - sizeof(struct lsm_cmd_set_fwk_mode_cfg), true); - msg_hdr->opcode = set_param_opcode; - data_payload_size = sizeof(struct lsm_cmd_set_fwk_mode_cfg) - - sizeof(struct apr_hdr) - - sizeof(struct lsm_set_params_hdr); - q6lsm_set_param_hdr_info(&cmd.params_hdr, - data_payload_size, 0, 0, 0); - fwk_mode_cfg = &cmd.fwk_mode_cfg; - - param_size = (sizeof(struct lsm_param_fwk_mode_cfg) - - sizeof(fwk_mode_cfg->common)); - q6lsm_set_param_common(&fwk_mode_cfg->common, - &fwk_mode_cfg_ids, param_size, - set_param_opcode); + fwk_mode_cfg_hdr.module_id = LSM_MODULE_ID_FRAMEWORK; + fwk_mode_cfg_hdr.instance_id = INSTANCE_ID_0; + fwk_mode_cfg_hdr.param_id = LSM_PARAM_ID_FWK_MODE_CONFIG; + fwk_mode_cfg_hdr.param_size = sizeof(fwk_mode_cfg); - fwk_mode_cfg->minor_version = QLSM_PARAM_ID_MINOR_VERSION; - fwk_mode_cfg->mode = event_mode; - pr_debug("%s: mode = %d\n", __func__, fwk_mode_cfg->mode); + fwk_mode_cfg.minor_version = QLSM_PARAM_ID_MINOR_VERSION; + fwk_mode_cfg.mode = event_mode; + pr_debug("%s: mode = %d\n", __func__, fwk_mode_cfg.mode); - rc = q6lsm_apr_send_pkt(client, client->apr, - &cmd, true, NULL); + rc = q6lsm_pack_and_set_params(client, &fwk_mode_cfg_hdr, + (uint8_t *) &fwk_mode_cfg, + LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) - pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", - __func__, msg_hdr->opcode, rc); + pr_err("%s: Failed set_params, rc %d\n", __func__, rc); return rc; } EXPORT_SYMBOL(q6lsm_set_fwk_mode_cfg); @@ -1015,58 +1072,41 @@ static int q6lsm_arrange_mch_map(struct lsm_param_media_fmt *media_fmt, */ int q6lsm_set_media_fmt_params(struct lsm_client *client) { - int rc = 0; - struct lsm_cmd_set_media_fmt cmd; - struct lsm_module_param_ids media_fmt_ids; - struct apr_hdr *msg_hdr; - struct lsm_param_media_fmt *media_fmt; - u32 data_payload_size, param_size, set_param_opcode; + struct lsm_param_media_fmt media_fmt; struct lsm_hw_params param = client->hw_params; + struct param_hdr_v3 media_fmt_hdr; + int rc = 0; - if (client->use_topology) { - set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2; - media_fmt_ids.module_id = LSM_MODULE_ID_FRAMEWORK; - media_fmt_ids.param_id = LSM_PARAM_ID_MEDIA_FMT; - } else { + memset(&media_fmt, 0, sizeof(media_fmt)); + memset(&media_fmt_hdr, 0, sizeof(media_fmt_hdr)); + + if (!client->use_topology) { pr_debug("%s: Ignore sending media format\n", __func__); goto err_ret; } - msg_hdr = &cmd.msg_hdr; - q6lsm_add_hdr(client, msg_hdr, - sizeof(struct lsm_cmd_set_media_fmt), true); - msg_hdr->opcode = set_param_opcode; - data_payload_size = sizeof(struct lsm_cmd_set_media_fmt) - - sizeof(struct apr_hdr) - - sizeof(struct lsm_set_params_hdr); - q6lsm_set_param_hdr_info(&cmd.params_hdr, - data_payload_size, 0, 0, 0); - media_fmt = &cmd.media_fmt; - - param_size = (sizeof(struct lsm_param_media_fmt) - - sizeof(media_fmt->common)); - q6lsm_set_param_common(&media_fmt->common, - &media_fmt_ids, param_size, - set_param_opcode); - - media_fmt->minor_version = QLSM_PARAM_ID_MINOR_VERSION_2; - media_fmt->sample_rate = param.sample_rate; - media_fmt->num_channels = param.num_chs; - media_fmt->bit_width = param.sample_size; + media_fmt_hdr.module_id = LSM_MODULE_ID_FRAMEWORK; + media_fmt_hdr.instance_id = INSTANCE_ID_0; + media_fmt_hdr.param_id = LSM_PARAM_ID_MEDIA_FMT; + media_fmt_hdr.param_size = sizeof(media_fmt); - rc = q6lsm_arrange_mch_map(media_fmt, media_fmt->num_channels); + media_fmt.minor_version = QLSM_PARAM_ID_MINOR_VERSION_2; + media_fmt.sample_rate = param.sample_rate; + media_fmt.num_channels = param.num_chs; + media_fmt.bit_width = param.sample_size; + rc = q6lsm_arrange_mch_map(&media_fmt, media_fmt.num_channels); if (rc) goto err_ret; - pr_debug("%s: sample rate= %d, channels %d bit width %d\n", - __func__, media_fmt->sample_rate, media_fmt->num_channels, - media_fmt->bit_width); + pr_debug("%s: sample rate= %d, channels %d bit width %d\n", __func__, + media_fmt.sample_rate, media_fmt.num_channels, + media_fmt.bit_width); - rc = q6lsm_apr_send_pkt(client, client->apr, - &cmd, true, NULL); + rc = q6lsm_pack_and_set_params(client, &media_fmt_hdr, + (uint8_t *) &media_fmt, + LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) - pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", - __func__, msg_hdr->opcode, rc); + pr_err("%s: Failed set_params, rc %d\n", __func__, rc); err_ret: return rc; } @@ -1086,9 +1126,10 @@ int q6lsm_set_data(struct lsm_client *client, enum lsm_detection_mode mode, bool detectfailure) { + struct param_hdr_v3 param_hdr; int rc = 0; - struct lsm_module_param_ids opmode_ids; - struct lsm_module_param_ids conf_levels_ids; + + memset(¶m_hdr, 0, sizeof(param_hdr)); if (!client->confidence_levels) { /* @@ -1112,22 +1153,20 @@ int q6lsm_set_data(struct lsm_client *client, } client->mode |= detectfailure << 2; - opmode_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP; - opmode_ids.param_id = LSM_PARAM_ID_OPERATION_MODE; - - rc = q6lsm_send_param_opmode(client, &opmode_ids, - LSM_SESSION_CMD_SET_PARAMS); + param_hdr.module_id = LSM_MODULE_ID_VOICE_WAKEUP; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = LSM_PARAM_ID_OPERATION_MODE; + rc = q6lsm_send_param_opmode(client, ¶m_hdr, + LSM_SESSION_CMD_SET_PARAMS); if (rc) { pr_err("%s: Failed to set lsm config params %d\n", __func__, rc); goto err_ret; } - conf_levels_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP; - conf_levels_ids.param_id = LSM_PARAM_ID_MIN_CONFIDENCE_LEVELS; - - rc = q6lsm_send_confidence_levels(client, &conf_levels_ids, - LSM_SESSION_CMD_SET_PARAMS); + param_hdr.param_id = LSM_PARAM_ID_MIN_CONFIDENCE_LEVELS; + rc = q6lsm_send_confidence_levels(client, ¶m_hdr, + LSM_SESSION_CMD_SET_PARAMS); if (rc) { pr_err("%s: Failed to send conf_levels, err = %d\n", __func__, rc); @@ -1334,11 +1373,11 @@ static int q6lsm_send_cal(struct lsm_client *client, u32 set_params_opcode) { int rc = 0; - struct lsm_cmd_set_params params; - struct lsm_set_params_hdr *params_hdr = ¶ms.param_hdr; - struct apr_hdr *msg_hdr = ¶ms.msg_hdr; + struct mem_mapping_hdr mem_hdr; struct cal_block_data *cal_block = NULL; + memset(&mem_hdr, 0, sizeof(mem_hdr)); + pr_debug("%s: Session id %d\n", __func__, client->session); if (CHECK_SESSION(client->session)) { pr_err("%s: session[%d]", __func__, client->session); @@ -1366,21 +1405,16 @@ static int q6lsm_send_cal(struct lsm_client *client, } /* Cache mmap address, only map once or if new addr */ lsm_common.common_client[client->session].session = client->session; - q6lsm_add_hdr(client, msg_hdr, sizeof(params), true); - msg_hdr->opcode = set_params_opcode; - q6lsm_set_param_hdr_info(params_hdr, - cal_block->cal_data.size, - lower_32_bits(client->lsm_cal_phy_addr), - msm_audio_populate_upper_32_bits( - client->lsm_cal_phy_addr), - client->sound_model.mem_map_handle); - - pr_debug("%s: Cal Size = %zd", __func__, - cal_block->cal_data.size); - rc = q6lsm_apr_send_pkt(client, client->apr, ¶ms, true, NULL); + mem_hdr.data_payload_addr_lsw = lower_32_bits(client->lsm_cal_phy_addr); + mem_hdr.data_payload_addr_msw = + msm_audio_populate_upper_32_bits(client->lsm_cal_phy_addr); + mem_hdr.mem_map_handle = client->sound_model.mem_map_handle; + + pr_debug("%s: Cal Size = %zd", __func__, cal_block->cal_data.size); + rc = q6lsm_set_params(client, &mem_hdr, NULL, cal_block->cal_data.size, + set_params_opcode); if (rc) - pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", - __func__, msg_hdr->opcode, rc); + pr_err("%s: Failed set_params, rc %d\n", __func__, rc); unlock: mutex_unlock(&lsm_common.cal_data[LSM_CAL_IDX]->lock); done: @@ -1573,7 +1607,7 @@ int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len, * set_param payload as well. */ if (allocate_module_data) - len += sizeof(struct lsm_param_payload_common); + len += sizeof(union param_hdrs); client->sound_model.size = len; pad_zero = (LSM_ALIGN_BOUNDARY - @@ -1667,66 +1701,46 @@ static int q6lsm_cmd(struct lsm_client *client, int opcode, bool wait) return rc; } -static int q6lsm_send_param_epd_thres( - struct lsm_client *client, - void *data, struct lsm_module_param_ids *ids) +static int q6lsm_send_param_epd_thres(struct lsm_client *client, void *data, + struct param_hdr_v3 *param_info) { - struct snd_lsm_ep_det_thres *ep_det_data; - struct lsm_cmd_set_epd_threshold epd_cmd; - struct apr_hdr *msg_hdr = &epd_cmd.msg_hdr; - struct lsm_set_params_hdr *param_hdr = - &epd_cmd.param_hdr; - struct lsm_param_epd_thres *epd_thres = - &epd_cmd.epd_thres; - int rc; + struct snd_lsm_ep_det_thres *ep_det_data = NULL; + struct lsm_param_epd_thres epd_thres; + int rc = 0; + + memset(&epd_thres, 0, sizeof(epd_thres)); + param_info->param_size = sizeof(epd_thres); ep_det_data = (struct snd_lsm_ep_det_thres *) data; - q6lsm_add_hdr(client, msg_hdr, - sizeof(epd_cmd), true); - msg_hdr->opcode = LSM_SESSION_CMD_SET_PARAMS_V2; - q6lsm_set_param_hdr_info(param_hdr, - sizeof(*epd_thres), 0, 0, 0); - q6lsm_set_param_common(&epd_thres->common, ids, - sizeof(*epd_thres) - sizeof(epd_thres->common), - LSM_SESSION_CMD_SET_PARAMS_V2); - epd_thres->minor_version = QLSM_PARAM_ID_MINOR_VERSION; - epd_thres->epd_begin = ep_det_data->epd_begin; - epd_thres->epd_end = ep_det_data->epd_end; + epd_thres.minor_version = QLSM_PARAM_ID_MINOR_VERSION; + epd_thres.epd_begin = ep_det_data->epd_begin; + epd_thres.epd_end = ep_det_data->epd_end; - rc = q6lsm_apr_send_pkt(client, client->apr, - &epd_cmd, true, NULL); + rc = q6lsm_pack_and_set_params(client, param_info, + (uint8_t *) &epd_thres, + LSM_SESSION_CMD_SET_PARAMS_V2); if (unlikely(rc)) - pr_err("%s: EPD_THRESHOLD failed, rc %d\n", - __func__, rc); + pr_err("%s: EPD_THRESHOLD failed, rc %d\n", __func__, rc); return rc; } -static int q6lsm_send_param_gain( - struct lsm_client *client, - u16 gain, struct lsm_module_param_ids *ids) +static int q6lsm_send_param_gain(struct lsm_client *client, u16 gain, + struct param_hdr_v3 *param_info) { - struct lsm_cmd_set_gain lsm_cmd_gain; - struct apr_hdr *msg_hdr = &lsm_cmd_gain.msg_hdr; - struct lsm_param_gain *lsm_gain = &lsm_cmd_gain.lsm_gain; - int rc; + struct lsm_param_gain lsm_gain; + int rc = 0; - q6lsm_add_hdr(client, msg_hdr, - sizeof(lsm_cmd_gain), true); - msg_hdr->opcode = LSM_SESSION_CMD_SET_PARAMS_V2; - q6lsm_set_param_hdr_info(&lsm_cmd_gain.param_hdr, - sizeof(*lsm_gain), 0, 0, 0); - q6lsm_set_param_common(&lsm_gain->common, ids, - sizeof(*lsm_gain) - sizeof(lsm_gain->common), - LSM_SESSION_CMD_SET_PARAMS_V2); - lsm_gain->minor_version = QLSM_PARAM_ID_MINOR_VERSION; - lsm_gain->gain = gain; - lsm_gain->reserved = 0; + memset(&lsm_gain, 0, sizeof(lsm_gain)); + param_info->param_size = sizeof(lsm_gain); - rc = q6lsm_apr_send_pkt(client, client->apr, - &lsm_cmd_gain, true, NULL); + lsm_gain.minor_version = QLSM_PARAM_ID_MINOR_VERSION; + lsm_gain.gain = gain; + + rc = q6lsm_pack_and_set_params(client, param_info, + (uint8_t *) &lsm_gain, + LSM_SESSION_CMD_SET_PARAMS_V2); if (unlikely(rc)) - pr_err("%s: LSM_GAIN CMD send failed, rc %d\n", - __func__, rc); + pr_err("%s: LSM_GAIN CMD send failed, rc %d\n", __func__, rc); return rc; } @@ -1745,23 +1759,25 @@ int q6lsm_set_one_param(struct lsm_client *client, struct lsm_params_info *p_info, void *data, uint32_t param_type) { - int rc = 0, pkt_sz; - struct lsm_module_param_ids ids; - u8 *packet; + struct param_hdr_v3 param_info; + int rc = 0; + + memset(¶m_info, 0, sizeof(param_info)); - memset(&ids, 0, sizeof(ids)); switch (param_type) { case LSM_ENDPOINT_DETECT_THRESHOLD: { - ids.module_id = p_info->module_id; - ids.param_id = p_info->param_id; - rc = q6lsm_send_param_epd_thres(client, data, - &ids); + param_info.module_id = p_info->module_id; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = p_info->param_id; + rc = q6lsm_send_param_epd_thres(client, data, ¶m_info); + if (rc) + pr_err("%s: LSM_ENDPOINT_DETECT_THRESHOLD failed, rc %d\n", + __func__, rc); break; } case LSM_OPERATION_MODE: { struct snd_lsm_detect_mode *det_mode = data; - struct lsm_module_param_ids opmode_ids; if (det_mode->mode == LSM_MODE_KEYWORD_ONLY_DETECTION) { client->mode = 0x01; @@ -1775,11 +1791,12 @@ int q6lsm_set_one_param(struct lsm_client *client, client->mode |= det_mode->detect_failure << 2; - opmode_ids.module_id = p_info->module_id; - opmode_ids.param_id = p_info->param_id; + param_info.module_id = p_info->module_id; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = p_info->param_id; - rc = q6lsm_send_param_opmode(client, &opmode_ids, - LSM_SESSION_CMD_SET_PARAMS_V2); + rc = q6lsm_send_param_opmode(client, ¶m_info, + LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) pr_err("%s: OPERATION_MODE failed, rc %d\n", __func__, rc); @@ -1788,10 +1805,10 @@ int q6lsm_set_one_param(struct lsm_client *client, case LSM_GAIN: { struct snd_lsm_gain *lsm_gain = (struct snd_lsm_gain *) data; - - ids.module_id = p_info->module_id; - ids.param_id = p_info->param_id; - rc = q6lsm_send_param_gain(client, lsm_gain->gain, &ids); + param_info.module_id = p_info->module_id; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = p_info->param_id; + rc = q6lsm_send_param_gain(client, lsm_gain->gain, ¶m_info); if (rc) pr_err("%s: LSM_GAIN command failed, rc %d\n", __func__, rc); @@ -1799,10 +1816,11 @@ int q6lsm_set_one_param(struct lsm_client *client, } case LSM_MIN_CONFIDENCE_LEVELS: - ids.module_id = p_info->module_id; - ids.param_id = p_info->param_id; - rc = q6lsm_send_confidence_levels(client, &ids, - LSM_SESSION_CMD_SET_PARAMS_V2); + param_info.module_id = p_info->module_id; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = p_info->param_id; + rc = q6lsm_send_confidence_levels( + client, ¶m_info, LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) pr_err("%s: CONFIDENCE_LEVELS cmd failed, rc %d\n", __func__, rc); @@ -1810,11 +1828,12 @@ int q6lsm_set_one_param(struct lsm_client *client, case LSM_POLLING_ENABLE: { struct snd_lsm_poll_enable *lsm_poll_enable = (struct snd_lsm_poll_enable *) data; - ids.module_id = p_info->module_id; - ids.param_id = p_info->param_id; - rc = q6lsm_send_param_polling_enable(client, - lsm_poll_enable->poll_en, &ids, - LSM_SESSION_CMD_SET_PARAMS_V2); + param_info.module_id = p_info->module_id; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = p_info->param_id; + rc = q6lsm_send_param_polling_enable( + client, lsm_poll_enable->poll_en, ¶m_info, + LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) pr_err("%s: POLLING ENABLE cmd failed, rc %d\n", __func__, rc); @@ -1822,24 +1841,27 @@ int q6lsm_set_one_param(struct lsm_client *client, } case LSM_REG_SND_MODEL: { - struct lsm_cmd_set_params model_param; + struct mem_mapping_hdr mem_hdr; u32 payload_size; - memset(&model_param, 0, sizeof(model_param)); - q6lsm_add_hdr(client, &model_param.msg_hdr, - sizeof(model_param), true); - model_param.msg_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS_V2; - payload_size = p_info->param_size + - sizeof(struct lsm_param_payload_common); - q6lsm_set_param_hdr_info(&model_param.param_hdr, - payload_size, - lower_32_bits(client->sound_model.phys), - msm_audio_populate_upper_32_bits( - client->sound_model.phys), - client->sound_model.mem_map_handle); - - rc = q6lsm_apr_send_pkt(client, client->apr, - &model_param, true, NULL); + memset(&mem_hdr, 0, sizeof(mem_hdr)); + + if (q6common_is_instance_id_supported()) + payload_size = p_info->param_size + + sizeof(struct param_hdr_v3); + else + payload_size = p_info->param_size + + sizeof(struct param_hdr_v2); + + mem_hdr.data_payload_addr_lsw = + lower_32_bits(client->sound_model.phys); + mem_hdr.data_payload_addr_msw = + msm_audio_populate_upper_32_bits( + client->sound_model.phys), + mem_hdr.mem_map_handle = client->sound_model.mem_map_handle; + + rc = q6lsm_set_params(client, &mem_hdr, NULL, payload_size, + LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) { pr_err("%s: REG_SND_MODEL failed, rc %d\n", __func__, rc); @@ -1854,69 +1876,33 @@ int q6lsm_set_one_param(struct lsm_client *client, } case LSM_DEREG_SND_MODEL: { - struct lsm_param_payload_common *common; - struct lsm_cmd_set_params *param; - - pkt_sz = sizeof(*param) + sizeof(*common); - packet = kzalloc(pkt_sz, GFP_KERNEL); - if (!packet) { - pr_err("%s: No memory for DEREG_SND_MODEL pkt, size = %d\n", - __func__, pkt_sz); - return -ENOMEM; - } - - param = (struct lsm_cmd_set_params *) packet; - common = (struct lsm_param_payload_common *) - (packet + sizeof(*param)); - q6lsm_add_hdr(client, ¶m->msg_hdr, pkt_sz, true); - param->msg_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS_V2; - q6lsm_set_param_hdr_info(¶m->param_hdr, - sizeof(*common), - 0, 0, 0); - ids.module_id = p_info->module_id; - ids.param_id = p_info->param_id; - q6lsm_set_param_common(common, &ids, 0, - LSM_SESSION_CMD_SET_PARAMS_V2); - rc = q6lsm_apr_send_pkt(client, client->apr, - packet, true, NULL); + param_info.module_id = p_info->module_id; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = p_info->param_id; + param_info.param_size = 0; + rc = q6lsm_pack_and_set_params(client, ¶m_info, NULL, + LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) pr_err("%s: DEREG_SND_MODEL failed, rc %d\n", __func__, rc); - kfree(packet); break; } case LSM_CUSTOM_PARAMS: { - struct apr_hdr *hdr; - u8 *custom_data; + u32 param_size = p_info->param_size; - if (p_info->param_size < - sizeof(struct lsm_param_payload_common)) { - pr_err("%s: Invalid param_size %d\n", - __func__, p_info->param_size); + /* Check minimum size, V2 structure is smaller than V3 */ + if (param_size < sizeof(struct param_hdr_v2)) { + pr_err("%s: Invalid param_size %d\n", __func__, + param_size); return -EINVAL; } - pkt_sz = p_info->param_size + sizeof(*hdr); - packet = kzalloc(pkt_sz, GFP_KERNEL); - if (!packet) { - pr_err("%s: no memory for CUSTOM_PARAMS, size = %d\n", - __func__, pkt_sz); - return -ENOMEM; - } - - hdr = (struct apr_hdr *) packet; - custom_data = (u8 *) (packet + sizeof(*hdr)); - q6lsm_add_hdr(client, hdr, pkt_sz, true); - hdr->opcode = LSM_SESSION_CMD_SET_PARAMS_V2; - memcpy(custom_data, data, p_info->param_size); - - rc = q6lsm_apr_send_pkt(client, client->apr, - packet, true, NULL); + rc = q6lsm_set_params(client, NULL, data, param_size, + LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) pr_err("%s: CUSTOM_PARAMS failed, rc %d\n", __func__, rc); - kfree(packet); break; } default: @@ -1982,60 +1968,56 @@ EXPORT_SYMBOL(q6lsm_close); */ int q6lsm_lab_control(struct lsm_client *client, u32 enable) { + struct lsm_param_lab_enable lab_enable; + struct param_hdr_v3 lab_enable_hdr; + struct lsm_param_lab_config lab_config; + struct param_hdr_v3 lab_config_hdr; int rc = 0; - struct lsm_params_lab_enable lab_enable; - struct lsm_params_lab_config lab_config; - struct lsm_module_param_ids lab_ids; - u32 param_size; + + memset(&lab_enable, 0, sizeof(lab_enable)); + memset(&lab_enable_hdr, 0, sizeof(lab_enable_hdr)); + memset(&lab_config, 0, sizeof(lab_config)); + memset(&lab_config_hdr, 0, sizeof(lab_config_hdr)); if (!client) { pr_err("%s: invalid param client %pK\n", __func__, client); return -EINVAL; } + /* enable/disable lab on dsp */ - q6lsm_add_hdr(client, &lab_enable.msg_hdr, sizeof(lab_enable), true); - lab_enable.msg_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS; - q6lsm_set_param_hdr_info(&lab_enable.params_hdr, - sizeof(struct lsm_lab_enable), - 0, 0, 0); - param_size = (sizeof(struct lsm_lab_enable) - - sizeof(struct lsm_param_payload_common)); - lab_ids.module_id = LSM_MODULE_ID_LAB; - lab_ids.param_id = LSM_PARAM_ID_LAB_ENABLE; - q6lsm_set_param_common(&lab_enable.lab_enable.common, - &lab_ids, param_size, - LSM_SESSION_CMD_SET_PARAMS); - lab_enable.lab_enable.enable = (enable) ? 1 : 0; - rc = q6lsm_apr_send_pkt(client, client->apr, &lab_enable, true, NULL); + lab_enable_hdr.module_id = LSM_MODULE_ID_LAB; + lab_enable_hdr.instance_id = INSTANCE_ID_0; + lab_enable_hdr.param_id = LSM_PARAM_ID_LAB_ENABLE; + lab_enable_hdr.param_size = sizeof(lab_enable); + lab_enable.enable = (enable) ? 1 : 0; + rc = q6lsm_pack_and_set_params(client, &lab_enable_hdr, + (uint8_t *) &lab_enable, + LSM_SESSION_CMD_SET_PARAMS); if (rc) { pr_err("%s: Lab enable failed rc %d\n", __func__, rc); return rc; } if (!enable) goto exit; + /* lab session is being enabled set the config values */ - q6lsm_add_hdr(client, &lab_config.msg_hdr, sizeof(lab_config), true); - lab_config.msg_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS; - q6lsm_set_param_hdr_info(&lab_config.params_hdr, - sizeof(struct lsm_lab_config), - 0, 0, 0); - lab_ids.module_id = LSM_MODULE_ID_LAB; - lab_ids.param_id = LSM_PARAM_ID_LAB_CONFIG; - param_size = (sizeof(struct lsm_lab_config) - - sizeof(struct lsm_param_payload_common)); - q6lsm_set_param_common(&lab_config.lab_config.common, - &lab_ids, param_size, - LSM_SESSION_CMD_SET_PARAMS); - lab_config.lab_config.minor_version = 1; - lab_config.lab_config.wake_up_latency_ms = 250; - rc = q6lsm_apr_send_pkt(client, client->apr, &lab_config, true, NULL); + lab_config_hdr.module_id = LSM_MODULE_ID_LAB; + lab_config_hdr.instance_id = INSTANCE_ID_0; + lab_config_hdr.param_id = LSM_PARAM_ID_LAB_CONFIG; + lab_config_hdr.param_size = sizeof(lab_config); + lab_config.minor_version = 1; + lab_config.wake_up_latency_ms = 250; + rc = q6lsm_pack_and_set_params(client, &lab_config_hdr, + (uint8_t *) &lab_config, + LSM_SESSION_CMD_SET_PARAMS); if (rc) { pr_err("%s: Lab config failed rc %d disable lab\n", __func__, rc); /* Lab config failed disable lab */ - lab_enable.lab_enable.enable = 0; - if (q6lsm_apr_send_pkt(client, client->apr, - &lab_enable, true, NULL)) + lab_enable.enable = 0; + if (q6lsm_pack_and_set_params(client, &lab_enable_hdr, + (uint8_t *) &lab_enable, + LSM_SESSION_CMD_SET_PARAMS)) pr_err("%s: Lab disable failed\n", __func__); } exit: @@ -2350,6 +2332,8 @@ int __init q6lsm_init(void) int i = 0; pr_debug("%s:\n", __func__); + + memset(&lsm_common, 0, sizeof(lsm_common)); spin_lock_init(&lsm_session_lock); spin_lock_init(&mmap_lock); mutex_init(&lsm_common.apr_lock); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 3c2f86ffbe9e..4e859665d589 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -9569,6 +9569,7 @@ struct avcs_fwk_ver_info { #define LSM_SESSION_CMD_CLOSE_TX (0x00012A88) #define LSM_SESSION_CMD_SET_PARAMS (0x00012A83) #define LSM_SESSION_CMD_SET_PARAMS_V2 (0x00012A8F) +#define LSM_SESSION_CMD_SET_PARAMS_V3 (0x00012A92) #define LSM_SESSION_CMD_REGISTER_SOUND_MODEL (0x00012A84) #define LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL (0x00012A85) #define LSM_SESSION_CMD_START (0x00012A86) diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h index 9050a7ca86c6..73168d1271e3 100644 --- a/include/dsp/q6lsm.h +++ b/include/dsp/q6lsm.h @@ -110,31 +110,27 @@ struct lsm_custom_topologies { uint32_t buffer_size; } __packed; -struct lsm_param_size_reserved { - uint16_t param_size; - uint16_t reserved; -} __packed; - -union lsm_param_size { - uint32_t param_size; - struct lsm_param_size_reserved sr; +struct lsm_session_cmd_set_params_v2 { + struct apr_hdr apr_hdr; + uint32_t payload_size; + struct mem_mapping_hdr mem_hdr; + u32 param_data[0]; } __packed; -struct lsm_param_payload_common { - uint32_t module_id; - uint32_t param_id; - union lsm_param_size p_size; +struct lsm_session_cmd_set_params_v3 { + struct apr_hdr apr_hdr; + struct mem_mapping_hdr mem_hdr; + uint32_t payload_size; + u32 param_data[0]; } __packed; struct lsm_param_op_mode { - struct lsm_param_payload_common common; uint32_t minor_version; uint16_t mode; uint16_t reserved; } __packed; struct lsm_param_connect_to_port { - struct lsm_param_payload_common common; uint32_t minor_version; /* AFE port id that receives voice wake up data */ uint16_t port_id; @@ -142,20 +138,17 @@ struct lsm_param_connect_to_port { } __packed; struct lsm_param_poll_enable { - struct lsm_param_payload_common common; uint32_t minor_version; /* indicates to voice wakeup that HW MAD/SW polling is enabled or not */ uint32_t polling_enable; } __packed; struct lsm_param_fwk_mode_cfg { - struct lsm_param_payload_common common; uint32_t minor_version; uint32_t mode; } __packed; struct lsm_param_media_fmt { - struct lsm_param_payload_common common; uint32_t minor_version; uint32_t sample_rate; uint16_t num_channels; @@ -163,78 +156,23 @@ struct lsm_param_media_fmt { uint8_t channel_mapping[LSM_MAX_NUM_CHANNELS]; } __packed; -/* - * This param cannot be sent in this format. - * The actual number of confidence level values - * need to appended to this param payload. - */ -struct lsm_param_min_confidence_levels { - struct lsm_param_payload_common common; - uint8_t num_confidence_levels; -} __packed; - -struct lsm_set_params_hdr { - uint32_t data_payload_size; - uint32_t data_payload_addr_lsw; - uint32_t data_payload_addr_msw; - uint32_t mem_map_handle; -} __packed; - -struct lsm_cmd_set_params { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr param_hdr; -} __packed; - -struct lsm_cmd_set_params_conf { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr params_hdr; - struct lsm_param_min_confidence_levels conf_payload; -} __packed; - -struct lsm_cmd_set_params_opmode { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr params_hdr; - struct lsm_param_op_mode op_mode; -} __packed; - -struct lsm_cmd_set_connectport { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr params_hdr; - struct lsm_param_connect_to_port connect_to_port; -} __packed; - -struct lsm_cmd_poll_enable { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr params_hdr; - struct lsm_param_poll_enable poll_enable; +struct lsm_param_confidence_levels { + uint8_t num_confidence_levels; + uint8_t confidence_levels[0]; } __packed; struct lsm_param_epd_thres { - struct lsm_param_payload_common common; uint32_t minor_version; uint32_t epd_begin; uint32_t epd_end; } __packed; -struct lsm_cmd_set_epd_threshold { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr param_hdr; - struct lsm_param_epd_thres epd_thres; -} __packed; - struct lsm_param_gain { - struct lsm_param_payload_common common; uint32_t minor_version; uint16_t gain; uint16_t reserved; } __packed; -struct lsm_cmd_set_gain { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr param_hdr; - struct lsm_param_gain lsm_gain; -} __packed; - struct lsm_cmd_reg_snd_model { struct apr_hdr hdr; uint32_t model_size; @@ -243,31 +181,16 @@ struct lsm_cmd_reg_snd_model { uint32_t mem_map_handle; } __packed; -struct lsm_lab_enable { - struct lsm_param_payload_common common; +struct lsm_param_lab_enable { uint16_t enable; uint16_t reserved; } __packed; -struct lsm_params_lab_enable { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr params_hdr; - struct lsm_lab_enable lab_enable; -} __packed; - -struct lsm_lab_config { - struct lsm_param_payload_common common; +struct lsm_param_lab_config { uint32_t minor_version; uint32_t wake_up_latency_ms; } __packed; - -struct lsm_params_lab_config { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr params_hdr; - struct lsm_lab_config lab_config; -} __packed; - struct lsm_cmd_read { struct apr_hdr hdr; uint32_t buf_addr_lsw; @@ -289,19 +212,6 @@ struct lsm_cmd_read_done { uint32_t flags; } __packed; -struct lsm_cmd_set_fwk_mode_cfg { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr params_hdr; - struct lsm_param_fwk_mode_cfg fwk_mode_cfg; -} __packed; - -struct lsm_cmd_set_media_fmt { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr params_hdr; - struct lsm_param_media_fmt media_fmt; -} __packed; - - struct lsm_client *q6lsm_client_alloc(lsm_app_cb cb, void *priv); void q6lsm_client_free(struct lsm_client *client); int q6lsm_open(struct lsm_client *client, uint16_t app_id); -- GitLab From cc3ff17850e47f7fdcf4321cb0b2b61d6cc66f5f Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 25 Jan 2018 14:25:19 -0800 Subject: [PATCH 0206/1645] ASoC: dsp: Update voice driver to support Instance ID Add support to set and get voice module params with Instance ID support. Maintain support for non Instance ID set and get param structures as well. Use common pack and set param functions to set and get parameters to DSP instead of handling them at an individual module level. CRs-Fixed: 2151551 Change-Id: I045e27710d69304f234ace1ff6c80afdd4a4041c Signed-off-by: Vignesh Kulothungan --- asoc/msm-pcm-voice-v2.c | 9 +- dsp/q6voice.c | 465 +++++++++++++++++++++++-------------- include/dsp/apr_audio-v2.h | 3 + include/dsp/q6voice.h | 82 +++---- 4 files changed, 338 insertions(+), 221 deletions(-) diff --git a/asoc/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c index b82c5871795d..0a4aa0528d95 100644 --- a/asoc/msm-pcm-voice-v2.c +++ b/asoc/msm-pcm-voice-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -556,12 +556,15 @@ static int msm_voice_slowtalk_put(struct snd_kcontrol *kcontrol, { int st_enable = ucontrol->value.integer.value[0]; uint32_t session_id = ucontrol->value.integer.value[1]; + struct module_instance_info mod_inst_info; + memset(&mod_inst_info, 0, sizeof(mod_inst_info)); pr_debug("%s: st enable=%d session_id=%#x\n", __func__, st_enable, session_id); - voc_set_pp_enable(session_id, - MODULE_ID_VOICE_MODULE_ST, st_enable); + mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST; + mod_inst_info.instance_id = INSTANCE_ID_0; + voc_set_pp_enable(session_id, mod_inst_info, st_enable); return 0; } diff --git a/dsp/q6voice.c b/dsp/q6voice.c index e26d156b57d3..801e76168541 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -105,8 +106,9 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv); static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv); static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv); -static int voice_send_set_pp_enable_cmd(struct voice_data *v, - uint32_t module_id, int enable); +static int voice_send_set_pp_enable_cmd( + struct voice_data *v, struct module_instance_info mod_inst_info, + int enable); static int is_cal_memory_allocated(void); static bool is_cvd_version_queried(void); static int is_voip_memory_allocated(void); @@ -137,6 +139,12 @@ static int voice_send_get_sound_focus_cmd(struct voice_data *v, struct sound_focus_param *soundFocusData); static int voice_send_get_source_tracking_cmd(struct voice_data *v, struct source_tracking_param *sourceTrackingData); +static int voice_pack_and_set_cvp_param(struct voice_data *v, + struct param_hdr_v3 param_hdr, + u8 *param_data); +static int voice_pack_and_set_cvs_ui_property(struct voice_data *v, + struct param_hdr_v3 param_hdr, + u8 *param_data); static void voice_itr_init(struct voice_session_itr *itr, u32 session_id) @@ -1471,70 +1479,31 @@ static int voice_send_tty_mode_cmd(struct voice_data *v) return ret; } -static int voice_send_set_pp_enable_cmd(struct voice_data *v, - uint32_t module_id, int enable) +static int voice_send_set_pp_enable_cmd( + struct voice_data *v, struct module_instance_info mod_inst_info, + int enable) { - struct cvs_set_pp_enable_cmd cvs_set_pp_cmd; + struct enable_param enable_param; + struct param_hdr_v3 param_hdr; int ret = 0; - void *apr_cvs; - u16 cvs_handle; - if (v == NULL) { - pr_err("%s: v is NULL\n", __func__); - return -EINVAL; - } - apr_cvs = common.apr_q6_cvs; + memset(&enable_param, 0, sizeof(enable_param)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = mod_inst_info.module_id; + param_hdr.instance_id = mod_inst_info.instance_id; + param_hdr.param_id = VOICE_PARAM_MOD_ENABLE; + param_hdr.param_size = sizeof(enable_param); + enable_param.enable = enable ? 1 : 0; - if (!apr_cvs) { - pr_err("%s: apr_cvs is NULL.\n", __func__); - return -EINVAL; - } - cvs_handle = voice_get_cvs_handle(v); + pr_debug("%s: module_id=%d, instance_id=%d, enable=%d\n", + __func__, mod_inst_info.module_id, mod_inst_info.instance_id, + enable); - cvs_set_pp_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - cvs_set_pp_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, - sizeof(cvs_set_pp_cmd) - - APR_HDR_SIZE); - cvs_set_pp_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id); - cvs_set_pp_cmd.hdr.dest_port = cvs_handle; - cvs_set_pp_cmd.hdr.token = 0; - cvs_set_pp_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_UI_PROPERTY; - - cvs_set_pp_cmd.vss_set_pp.module_id = module_id; - cvs_set_pp_cmd.vss_set_pp.param_id = VOICE_PARAM_MOD_ENABLE; - cvs_set_pp_cmd.vss_set_pp.param_size = MOD_ENABLE_PARAM_LEN; - cvs_set_pp_cmd.vss_set_pp.reserved = 0; - cvs_set_pp_cmd.vss_set_pp.enable = enable; - cvs_set_pp_cmd.vss_set_pp.reserved_field = 0; - pr_debug("voice_send_set_pp_enable_cmd, module_id=%d, enable=%d\n", - module_id, enable); + ret = voice_pack_and_set_cvs_ui_property(v, param_hdr, + (uint8_t *) &enable_param); + if (ret < 0) + pr_err("Fail: sending cvs set pp enable\n"); - v->cvs_state = CMD_STATUS_FAIL; - v->async_err = 0; - ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_pp_cmd); - if (ret < 0) { - pr_err("Fail: sending cvs set pp enable,\n"); - goto fail; - } - ret = wait_event_timeout(v->cvs_wait, - (v->cvs_state == CMD_STATUS_SUCCESS), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - goto fail; - } - if (v->async_err > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - v->async_err)); - ret = adsp_err_get_lnx_err_code( - v->async_err); - goto fail; - } - return 0; -fail: return ret; } @@ -4245,8 +4214,10 @@ static int voice_get_avcs_version_per_service(uint32_t service_id) static int voice_setup_vocproc(struct voice_data *v) { + struct module_instance_info mod_inst_info; int ret = 0; + memset(&mod_inst_info, 0, sizeof(mod_inst_info)); ret = voice_send_cvp_create_cmd(v); if (ret < 0) { pr_err("%s: CVP create failed err:%d\n", __func__, ret); @@ -4288,6 +4259,9 @@ static int voice_setup_vocproc(struct voice_data *v) } } + mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST; + mod_inst_info.instance_id = INSTANCE_ID_0; + voice_send_cvs_register_cal_cmd(v); voice_send_cvp_register_dev_cfg_cmd(v); voice_send_cvp_register_cal_cmd(v); @@ -4321,9 +4295,7 @@ static int voice_setup_vocproc(struct voice_data *v) } if (v->st_enable && !v->tty_mode) - voice_send_set_pp_enable_cmd(v, - MODULE_ID_VOICE_MODULE_ST, - v->st_enable); + voice_send_set_pp_enable_cmd(v, mod_inst_info, v->st_enable); /* Start in-call music delivery if this feature is enabled */ if (v->music_info.play_enable) voice_cvs_start_playback(v); @@ -4467,14 +4439,12 @@ static int voice_send_cvp_media_fmt_info_cmd(struct voice_data *v) static int voice_send_cvp_media_format_cmd(struct voice_data *v, uint32_t param_type) { + struct vss_param_endpoint_media_format_info media_fmt_info; + struct param_hdr_v3 param_hdr; int ret = 0; - struct cvp_set_media_format_cmd cvp_set_media_format_cmd; - void *apr_cvp; - u16 cvp_handle; - struct vss_icommon_param_data_t *media_fmt_param_data = - &cvp_set_media_format_cmd.cvp_set_media_param_v2.param_data; - struct vss_param_endpoint_media_format_info_t *media_fmt_info = - &media_fmt_param_data->media_format_info; + + memset(&media_fmt_info, 0, sizeof(media_fmt_info)); + memset(¶m_hdr, 0, sizeof(param_hdr)); if (v == NULL) { pr_err("%s: v is NULL\n", __func__); @@ -4482,75 +4452,41 @@ static int voice_send_cvp_media_format_cmd(struct voice_data *v, goto done; } - apr_cvp = common.apr_q6_cvp; - if (!apr_cvp) { - pr_err("%s: apr_cvp is NULL.\n", __func__); - ret = -EINVAL; - goto done; - } + param_hdr.module_id = VSS_MODULE_CVD_GENERIC; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_size = sizeof(media_fmt_info); - cvp_handle = voice_get_cvp_handle(v); - memset(&cvp_set_media_format_cmd, 0, sizeof(cvp_set_media_format_cmd)); - - /* Fill header data */ - cvp_set_media_format_cmd.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - cvp_set_media_format_cmd.hdr.pkt_size = - APR_PKT_SIZE(APR_HDR_SIZE, - sizeof(cvp_set_media_format_cmd) - APR_HDR_SIZE); - cvp_set_media_format_cmd.hdr.src_svc = 0; - cvp_set_media_format_cmd.hdr.src_domain = APR_DOMAIN_APPS; - cvp_set_media_format_cmd.hdr.src_port = - voice_get_idx_for_session(v->session_id); - cvp_set_media_format_cmd.hdr.dest_svc = 0; - cvp_set_media_format_cmd.hdr.dest_domain = APR_DOMAIN_ADSP; - cvp_set_media_format_cmd.hdr.dest_port = cvp_handle; - cvp_set_media_format_cmd.hdr.token = VOC_SET_MEDIA_FORMAT_PARAM_TOKEN; - cvp_set_media_format_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2; - - /* Fill param data */ - cvp_set_media_format_cmd.cvp_set_media_param_v2.mem_size = - sizeof(struct vss_icommon_param_data_t); - media_fmt_param_data->module_id = VSS_MODULE_CVD_GENERIC; - media_fmt_param_data->param_size = - sizeof(struct vss_param_endpoint_media_format_info_t); - - /* Fill device specific data */ switch (param_type) { case RX_PATH: - media_fmt_param_data->param_id = - VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO; - media_fmt_info->port_id = v->dev_rx.port_id; - media_fmt_info->num_channels = v->dev_rx.no_of_channels; - media_fmt_info->bits_per_sample = v->dev_rx.bits_per_sample; - media_fmt_info->sample_rate = v->dev_rx.sample_rate; - memcpy(&media_fmt_info->channel_mapping, + param_hdr.param_id = VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO; + media_fmt_info.port_id = v->dev_rx.port_id; + media_fmt_info.num_channels = v->dev_rx.no_of_channels; + media_fmt_info.bits_per_sample = v->dev_rx.bits_per_sample; + media_fmt_info.sample_rate = v->dev_rx.sample_rate; + memcpy(&media_fmt_info.channel_mapping, &v->dev_rx.channel_mapping, VSS_CHANNEL_MAPPING_SIZE); break; case TX_PATH: - media_fmt_param_data->param_id = - VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO; - media_fmt_info->port_id = v->dev_tx.port_id; - media_fmt_info->num_channels = v->dev_tx.no_of_channels; - media_fmt_info->bits_per_sample = v->dev_tx.bits_per_sample; - media_fmt_info->sample_rate = v->dev_tx.sample_rate; - memcpy(&media_fmt_info->channel_mapping, + param_hdr.param_id = VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO; + media_fmt_info.port_id = v->dev_tx.port_id; + media_fmt_info.num_channels = v->dev_tx.no_of_channels; + media_fmt_info.bits_per_sample = v->dev_tx.bits_per_sample; + media_fmt_info.sample_rate = v->dev_tx.sample_rate; + memcpy(&media_fmt_info.channel_mapping, &v->dev_tx.channel_mapping, VSS_CHANNEL_MAPPING_SIZE); break; case EC_REF_PATH: - media_fmt_param_data->param_id = - VSS_PARAM_EC_REF_PORT_ENDPOINT_MEDIA_INFO; - media_fmt_info->port_id = common.ec_media_fmt_info.port_id; - media_fmt_info->num_channels = + param_hdr.param_id = VSS_PARAM_EC_REF_PORT_ENDPOINT_MEDIA_INFO; + media_fmt_info.port_id = common.ec_media_fmt_info.port_id; + media_fmt_info.num_channels = common.ec_media_fmt_info.num_channels; - media_fmt_info->bits_per_sample = + media_fmt_info.bits_per_sample = common.ec_media_fmt_info.bits_per_sample; - media_fmt_info->sample_rate = + media_fmt_info.sample_rate = common.ec_media_fmt_info.sample_rate; - memcpy(&media_fmt_info->channel_mapping, + memcpy(&media_fmt_info.channel_mapping, &common.ec_media_fmt_info.channel_mapping, VSS_CHANNEL_MAPPING_SIZE); break; @@ -4561,32 +4497,11 @@ static int voice_send_cvp_media_format_cmd(struct voice_data *v, goto done; } - /* Send command */ - v->cvp_state = CMD_STATUS_FAIL; - v->async_err = 0; - ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_set_media_format_cmd); - if (ret < 0) { - pr_err("%s: Fail in sending VSS_ICOMMON_CMD_SET_PARAM_V2\n", - __func__); - ret = -EINVAL; - goto done; - } - - ret = wait_event_timeout(v->cvp_wait, - (v->cvp_state == CMD_STATUS_SUCCESS), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto done; - } - - if (v->async_err > 0) { - pr_err("%s: DSP returned error[%s] handle = %d\n", __func__, - adsp_err_get_err_str(v->async_err), cvp_handle); - ret = adsp_err_get_lnx_err_code(v->async_err); - goto done; - } + ret = voice_pack_and_set_cvp_param(v, param_hdr, + (u8 *) &media_fmt_info); + if (ret) + pr_err("%s: Failed to set media format params on CVP, err %d\n", + __func__, ret); done: return ret; @@ -4982,10 +4897,13 @@ static int voice_destroy_vocproc(struct voice_data *v) { struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd; struct apr_hdr cvp_destroy_session_cmd; + struct module_instance_info mod_inst_info; int ret = 0; void *apr_mvm, *apr_cvp; u16 mvm_handle, cvp_handle; + memset(&mod_inst_info, 0, sizeof(mod_inst_info)); + if (v == NULL) { pr_err("%s: v is NULL\n", __func__); return -EINVAL; @@ -5000,9 +4918,12 @@ static int voice_destroy_vocproc(struct voice_data *v) mvm_handle = voice_get_mvm_handle(v); cvp_handle = voice_get_cvp_handle(v); + mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST; + mod_inst_info.instance_id = INSTANCE_ID_0; + /* disable slowtalk if st_enable is set */ if (v->st_enable) - voice_send_set_pp_enable_cmd(v, MODULE_ID_VOICE_MODULE_ST, 0); + voice_send_set_pp_enable_cmd(v, mod_inst_info, 0); /* Disable HD Voice if hd_enable is set */ if (v->hd_enable) @@ -6324,11 +6245,15 @@ EXPORT_SYMBOL(voc_get_tty_mode); * * Returns 0 on success or error on failure */ -int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, uint32_t enable) +int voc_set_pp_enable(uint32_t session_id, + struct module_instance_info mod_inst_info, + uint32_t enable) { struct voice_data *v = NULL; int ret = 0; struct voice_session_itr itr; + int mid = mod_inst_info.module_id; + int iid = mod_inst_info.instance_id; voice_itr_init(&itr, session_id); while (voice_itr_get_next_session(&itr, &v)) { @@ -6337,15 +6262,15 @@ int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, uint32_t enable) continue; mutex_lock(&v->lock); - if (module_id == MODULE_ID_VOICE_MODULE_ST) + if (mid == MODULE_ID_VOICE_MODULE_ST && + iid == INSTANCE_ID_0) v->st_enable = enable; if (v->voc_state == VOC_RUN) { - if ((module_id == MODULE_ID_VOICE_MODULE_ST) && - (!v->tty_mode)) - ret = voice_send_set_pp_enable_cmd(v, - MODULE_ID_VOICE_MODULE_ST, - enable); + if ((mid == MODULE_ID_VOICE_MODULE_ST) && + iid == INSTANCE_ID_0 && (!v->tty_mode)) + ret = voice_send_set_pp_enable_cmd( + v, mod_inst_info, enable); } mutex_unlock(&v->lock); } else { @@ -6455,8 +6380,8 @@ bool voc_get_afe_sidetone(void) return ret; } EXPORT_SYMBOL(voc_get_afe_sidetone); - -int voc_get_pp_enable(uint32_t session_id, uint32_t module_id) +int voc_get_pp_enable(uint32_t session_id, + struct module_instance_info mod_inst_info) { struct voice_data *v = voice_get_session(session_id); int ret = 0; @@ -6468,7 +6393,8 @@ int voc_get_pp_enable(uint32_t session_id, uint32_t module_id) } mutex_lock(&v->lock); - if (module_id == MODULE_ID_VOICE_MODULE_ST) + if (mod_inst_info.module_id == MODULE_ID_VOICE_MODULE_ST && + mod_inst_info.instance_id == INSTANCE_ID_0) ret = v->st_enable; mutex_unlock(&v->lock); @@ -6826,8 +6752,11 @@ EXPORT_SYMBOL(voc_disable_device); int voc_enable_device(uint32_t session_id) { struct voice_data *v = voice_get_session(session_id); + struct module_instance_info mod_inst_info; int ret = 0; + memset(&mod_inst_info, 0, sizeof(mod_inst_info)); + if (v == NULL) { pr_err("%s: v is NULL\n", __func__); return -EINVAL; @@ -6843,15 +6772,15 @@ int voc_enable_device(uint32_t session_id) /* Not a critical error, allow voice call to continue */ } + mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST; + mod_inst_info.instance_id = INSTANCE_ID_0; + if (v->tty_mode) { /* disable slowtalk */ - voice_send_set_pp_enable_cmd(v, - MODULE_ID_VOICE_MODULE_ST, - 0); + voice_send_set_pp_enable_cmd(v, mod_inst_info, 0); } else { /* restore slowtalk */ - voice_send_set_pp_enable_cmd(v, - MODULE_ID_VOICE_MODULE_ST, + voice_send_set_pp_enable_cmd(v, mod_inst_info, v->st_enable); } @@ -7506,6 +7435,7 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv) case VSS_ICOMMON_CMD_MAP_MEMORY: case VSS_ICOMMON_CMD_UNMAP_MEMORY: case VSS_ICOMMON_CMD_SET_UI_PROPERTY: + case VSS_ICOMMON_CMD_SET_UI_PROPERTY_V2: case VSS_IPLAYBACK_CMD_START: case VSS_IPLAYBACK_CMD_STOP: case VSS_IRECORD_CMD_START: @@ -7519,7 +7449,8 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv) wake_up(&v->cvs_wait); break; case VSS_ICOMMON_CMD_SET_PARAM_V2: - pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2\n", + case VSS_ICOMMON_CMD_SET_PARAM_V3: + pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM\n", __func__); rtac_make_voice_callback(RTAC_CVS, ptr, data->payload_size); @@ -7798,17 +7729,18 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv) case VSS_IVPCM_EVT_PUSH_BUFFER_V2: break; case VSS_ICOMMON_CMD_SET_PARAM_V2: + case VSS_ICOMMON_CMD_SET_PARAM_V3: switch (data->token) { case VOC_SET_MEDIA_FORMAT_PARAM_TOKEN: case VOC_GENERIC_SET_PARAM_TOKEN: - pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called\n", + pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM called by voice_send_cvp_media_format_cmd\n", __func__); v->cvp_state = CMD_STATUS_SUCCESS; v->async_err = ptr[1]; wake_up(&v->cvp_wait); break; case VOC_RTAC_SET_PARAM_TOKEN: - pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called by rtac\n", + pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM called by rtac\n", __func__); rtac_make_voice_callback( RTAC_CVP, ptr, @@ -9468,6 +9400,199 @@ int voc_get_source_tracking(struct source_tracking_param *sourceTrackingData) } EXPORT_SYMBOL(voc_get_source_tracking); +static int voice_set_cvp_param(struct voice_data *v, + struct vss_icommon_mem_mapping_hdr *mem_hdr, + u32 *param_data, u32 param_size) +{ + struct vss_icommon_cmd_set_param *set_param = NULL; + uint32_t pkt_size = sizeof(struct vss_icommon_cmd_set_param); + void *apr_cvp; + int ret = 0; + + apr_cvp = common.apr_q6_cvp; + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL\n", __func__); + return -EINVAL; + } + + if (param_data != NULL) + pkt_size += param_size; + set_param = kzalloc(pkt_size, GFP_KERNEL); + if (!set_param) + return -ENOMEM; + + set_param->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + set_param->apr_hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, pkt_size - APR_HDR_SIZE); + set_param->apr_hdr.src_svc = 0; + set_param->apr_hdr.src_domain = APR_DOMAIN_APPS; + set_param->apr_hdr.src_port = voice_get_idx_for_session(v->session_id); + set_param->apr_hdr.dest_svc = 0; + set_param->apr_hdr.dest_domain = APR_DOMAIN_ADSP; + set_param->apr_hdr.dest_port = voice_get_cvp_handle(v); + set_param->apr_hdr.token = VOC_SET_MEDIA_FORMAT_PARAM_TOKEN; + set_param->apr_hdr.opcode = q6common_is_instance_id_supported() ? + VSS_ICOMMON_CMD_SET_PARAM_V3 : + VSS_ICOMMON_CMD_SET_PARAM_V2; + + set_param->payload_size = param_size; + + if (mem_hdr != NULL) { + set_param->mem_hdr = *mem_hdr; + } else if (param_data != NULL) { + memcpy(set_param->param_data, param_data, param_size); + } else { + pr_err("%s: Both memory header and param data are NULL\n", + __func__); + ret = -EINVAL; + goto done; + } + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (u32 *) set_param); + if (ret < 0) { + pr_err("%s: Failed to send apr packet, error %d\n", __func__, + ret); + goto done; + } + + ret = wait_event_timeout(v->cvp_wait, + v->cvp_state == CMD_STATUS_SUCCESS, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(v->async_err)); + ret = adsp_err_get_lnx_err_code(v->async_err); + goto done; + } + ret = 0; + +done: + kfree(set_param); + return ret; +} + +static int voice_pack_and_set_cvp_param(struct voice_data *v, + struct param_hdr_v3 param_hdr, + u8 *param_data) +{ + u8 *packed_data = NULL; + u32 total_size = 0; + int ret = 0; + + total_size = sizeof(union param_hdrs) + param_hdr.param_size; + packed_data = kzalloc(total_size, GFP_KERNEL); + if (!packed_data) + return -ENOMEM; + + ret = q6common_pack_pp_params(packed_data, ¶m_hdr, param_data, + &total_size); + if (ret) { + pr_err("%s: Failed to pack params, error %d", __func__, ret); + goto done; + } + + ret = voice_set_cvp_param(v, NULL, (u32 *) packed_data, total_size); + +done: + kfree(packed_data); + return ret; +} + +/* + * Out of band is not supported and there are currently no pre-packed cases, + * so pack and set in the same function. When needed, split up. + */ +static int voice_pack_and_set_cvs_ui_property(struct voice_data *v, + struct param_hdr_v3 param_hdr, + u8 *param_data) +{ + struct vss_icommon_cmd_set_ui_property *set_ui_property = NULL; + u32 total_size = 0; + bool iid_supported = q6common_is_instance_id_supported(); + void *apr_cvs; + int ret = 0; + + apr_cvs = common.apr_q6_cvs; + if (!apr_cvs) { + pr_err("%s: apr_cvs is NULL\n", __func__); + return -EINVAL; + } + + total_size = sizeof(struct vss_icommon_cmd_set_ui_property) + + sizeof(union param_hdrs) + param_hdr.param_size; + set_ui_property = kzalloc(total_size, GFP_KERNEL); + if (!set_ui_property) + return -ENOMEM; + + ret = q6common_pack_pp_params(set_ui_property->param_data, ¶m_hdr, + param_data, &total_size); + if (ret) { + pr_err("%s: Failed to pack params, error %d", __func__, ret); + goto done; + } + + /* + * Pack the APR header after packing the data so we have the actual + * total size of the payload + */ + set_ui_property->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + set_ui_property->apr_hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, total_size - APR_HDR_SIZE); + set_ui_property->apr_hdr.src_svc = 0; + set_ui_property->apr_hdr.src_domain = APR_DOMAIN_APPS; + set_ui_property->apr_hdr.src_port = + voice_get_idx_for_session(v->session_id); + set_ui_property->apr_hdr.dest_svc = 0; + set_ui_property->apr_hdr.dest_domain = APR_DOMAIN_ADSP; + set_ui_property->apr_hdr.dest_port = voice_get_cvs_handle(v); + set_ui_property->apr_hdr.token = 0; + + set_ui_property->apr_hdr.opcode = + iid_supported ? VSS_ICOMMON_CMD_SET_UI_PROPERTY_V2 : + VSS_ICOMMON_CMD_SET_UI_PROPERTY; + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvs, (u32 *) set_ui_property); + if (ret < 0) { + pr_err("%s: Failed to send apr packet, error %d\n", __func__, + ret); + goto done; + } + + ret = wait_event_timeout(v->cvs_wait, + v->cvs_state == CMD_STATUS_SUCCESS, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(v->async_err)); + ret = adsp_err_get_lnx_err_code(v->async_err); + goto done; + } + ret = 0; +done: + kfree(set_ui_property); + return ret; +} + /** * is_voc_initialized: * diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 4e859665d589..9c7f39d13218 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -8818,6 +8818,9 @@ struct asm_eq_params { #define VSS_ICOMMON_CMD_SET_PARAM_V2 0x0001133D #define VSS_ICOMMON_CMD_GET_PARAM_V2 0x0001133E #define VSS_ICOMMON_RSP_GET_PARAM 0x00011008 +#define VSS_ICOMMON_CMD_SET_PARAM_V3 0x00013245 +#define VSS_ICOMMON_CMD_GET_PARAM_V3 0x00013246 +#define VSS_ICOMMON_RSP_GET_PARAM_V3 0x00013247 #define VSS_MAX_AVCS_NUM_SERVICES 25 diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index 5dfdccf84420..be72b72d34e4 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -169,6 +169,7 @@ struct mem_map_table { /* Common */ #define VSS_ICOMMON_CMD_SET_UI_PROPERTY 0x00011103 +#define VSS_ICOMMON_CMD_SET_UI_PROPERTY_V2 0x00013248 /* Set a UI property */ #define VSS_ICOMMON_CMD_MAP_MEMORY 0x00011025 #define VSS_ICOMMON_CMD_UNMAP_MEMORY 0x00011026 @@ -210,7 +211,7 @@ struct vss_unmap_memory_cmd { struct vss_icommon_cmd_unmap_memory_t vss_unmap_mem; } __packed; -struct vss_param_endpoint_media_format_info_t { +struct vss_param_endpoint_media_format_info { /* AFE port ID to which this media format corresponds to. */ uint32_t port_id; /* @@ -260,27 +261,6 @@ struct vss_param_mfc_config_info_t { uint16_t channel_type[VSS_NUM_CHANNELS_MAX]; } __packed; -struct vss_icommon_param_data_t { - /* Valid ID of the module. */ - uint32_t module_id; - /* Valid ID of the parameter. */ - uint32_t param_id; - /* - * Data size of the structure relating to the param_id/module_id - * combination in uint8_t bytes. - */ - uint16_t param_size; - /* This field must be set to zero. */ - uint16_t reserved; - /* - * Parameter data payload when inband. Should have size param_size. - * Bit size of payload must be a multiple of 4. - */ - union { - struct vss_param_endpoint_media_format_info_t media_format_info; - }; -} __packed; - struct vss_icommon_param_data_channel_info_v2_t { /* Valid ID of the module. */ uint32_t module_id; @@ -404,8 +384,7 @@ struct vss_icommon_cmd_set_param_mfc_config_v2_t { struct vss_icommon_param_data_mfc_config_v2_t param_data; } __packed; -/* Payload structure for the VSS_ICOMMON_CMD_SET_PARAM_V2 command. */ -struct vss_icommon_cmd_set_param_v2_t { +struct vss_icommon_mem_mapping_hdr { /* * Pointer to the unique identifier for an address (physical/virtual). * @@ -425,10 +404,23 @@ struct vss_icommon_cmd_set_param_v2_t { * mem_handle is 0, this field is ignored. */ uint64_t mem_address; +} __packed; + +struct vss_icommon_cmd_set_param { + /* APR Header */ + struct apr_hdr apr_hdr; + + /* The memory mapping header to be used when sending outband */ + struct vss_icommon_mem_mapping_hdr mem_hdr; + /* Size of the parameter data payload in bytes. */ - uint32_t mem_size; - /* Parameter data payload when the data is inband. */ - struct vss_icommon_param_data_t param_data; + uint32_t payload_size; + + /* + * Parameter data payload when inband. Should have size param_size. + * Bit size of payload must be a multiple of 4. + */ + uint8_t param_data[0]; } __packed; /* TO MVM commands */ @@ -781,7 +773,6 @@ struct vss_imemory_cmd_unmap_t { #define MODULE_ID_VOICE_MODULE_ST 0x00010EE3 #define VOICE_PARAM_MOD_ENABLE 0x00010E00 -#define MOD_ENABLE_PARAM_LEN 4 #define VSS_IPLAYBACK_CMD_START 0x000112BD /* Start in-call music delivery on the Tx voice path. */ @@ -1056,20 +1047,20 @@ struct vss_istream_cmd_register_calibration_data_v2_t { */ } __packed; -struct vss_icommon_cmd_set_ui_property_enable_t { - uint32_t module_id; - /* Unique ID of the module. */ - uint32_t param_id; - /* Unique ID of the parameter. */ - uint16_t param_size; - /* Size of the parameter in bytes: MOD_ENABLE_PARAM_LEN */ - uint16_t reserved; - /* Reserved; set to 0. */ +struct enable_param { uint16_t enable; uint16_t reserved_field; /* Reserved, set to 0. */ }; +struct vss_icommon_cmd_set_ui_property { + /* APR Header */ + struct apr_hdr apr_hdr; + + /* The parameter data to be filled when sent inband */ + u8 param_data[0]; +} __packed; + /* * Event sent by the stream to the client that enables Rx DTMF * detection whenever DTMF is detected in the Rx path. @@ -1178,10 +1169,6 @@ struct cvs_deregister_cal_data_cmd { struct apr_hdr hdr; } __packed; -struct cvs_set_pp_enable_cmd { - struct apr_hdr hdr; - struct vss_icommon_cmd_set_ui_property_enable_t vss_set_pp; -} __packed; struct cvs_start_record_cmd { struct apr_hdr hdr; struct vss_irecord_cmd_start_t rec_mode; @@ -1254,6 +1241,8 @@ struct vss_istream_cmd_set_packet_exchange_mode_t { */ #define VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG 0x00011372 +#define CVD_CAL_DATA_FORMAT_MINOR_VERSION_V0 0x00000000 +#define CVD_CAL_DATA_FORMAT_MINOR_VERSION_V1 0x00000001 #define VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2 0x00011373 #define VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA 0x00011276 @@ -1633,11 +1622,6 @@ struct cvp_set_dev_channels_cmd { struct vss_ivocproc_cmd_topology_set_dev_channels_t cvp_set_channels; } __packed; -struct cvp_set_media_format_cmd { - struct apr_hdr hdr; - struct vss_icommon_cmd_set_param_v2_t cvp_set_media_param_v2; -} __packed; - struct cvp_set_channel_info_cmd_v2 { struct apr_hdr hdr; struct vss_icommon_cmd_set_param_channel_info_v2_t @@ -1992,9 +1976,11 @@ enum { #define VSID_MAX ALL_SESSION_VSID /* called by alsa driver */ -int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, +int voc_set_pp_enable(uint32_t session_id, + struct module_instance_info mod_inst_info, uint32_t enable); -int voc_get_pp_enable(uint32_t session_id, uint32_t module_id); +int voc_get_pp_enable(uint32_t session_id, + struct module_instance_info mod_inst_info); int voc_set_hd_enable(uint32_t session_id, uint32_t enable); uint8_t voc_get_tty_mode(uint32_t session_id); int voc_set_tty_mode(uint32_t session_id, uint8_t tty_mode); -- GitLab From d5a6778200a65e4e0507cbb3b209129784a877a3 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Sat, 3 Mar 2018 23:19:50 -0800 Subject: [PATCH 0207/1645] dsp: Change default topology for voice Tx path Assign default topology to NULL topology instead of ECNS topology for voice Tx path. Change-Id: Ie39711b43b5d94ee93debc3054c26445e7583d70 Signed-off-by: Vikram Panduranga --- dsp/q6voice.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index e26d156b57d3..e80bb124ab43 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -8510,7 +8510,7 @@ uint32_t voice_get_topology(uint32_t topology_idx) if (topology_idx == CVP_VOC_RX_TOPOLOGY_CAL) { topology = VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT; } else if (topology_idx == CVP_VOC_TX_TOPOLOGY_CAL) { - topology = VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS_V2; + topology = VSS_IVOCPROC_TOPOLOGY_ID_NONE; } else { pr_err("%s: cal index %x is invalid!\n", __func__, topology_idx); -- GitLab From 9a8caf4aaf1c68c9480f8ec744a45868031226c8 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 3 Jan 2018 21:13:17 +0530 Subject: [PATCH 0208/1645] ASoC: Update config of SND_HWDEP As CONFIG_SND_HWDEP is defined by default in kernel tree, msm-pcm-routing-devdep.c file in audio drivers gets compiled always. Use CONFIG_SND_HWDEP_ROUTING config instead of CONFIG_SND_HWDEP to compile msm-pcm-routing-devdep.c file. Change-Id: I19c4b0a56dbe6c4890ece645fcf100687f762f5d Signed-off-by: Laxminath Kasam Signed-off-by: Meng Wang --- asoc/Kbuild | 2 +- config/sdm670auto.conf | 2 +- config/sdm670auto_static.conf | 2 +- config/sdm670autoconf.h | 4 ++-- config/sdm845auto.conf | 2 +- config/sdm845autoconf.h | 4 ++-- config/sdm855auto.conf | 2 +- config/sdm855autoconf.h | 2 +- config/sdxpoorwillsauto.conf | 2 +- config/sdxpoorwillsautoconf.h | 4 ++-- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/asoc/Kbuild b/asoc/Kbuild index 4ebce00485b1..00c2d38059ca 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -122,7 +122,7 @@ endif ifdef CONFIG_DOLBY_LICENSE PLATFORM_OBJS += msm-ds2-dap-config.o endif -ifdef CONFIG_SND_HWDEP +ifdef CONFIG_SND_HWDEP_ROUTING PLATFORM_OBJS += msm-pcm-routing-devdep.o endif ifdef CONFIG_QTI_PP diff --git a/config/sdm670auto.conf b/config/sdm670auto.conf index 07f195b28f7b..4c0b284c9c96 100644 --- a/config/sdm670auto.conf +++ b/config/sdm670auto.conf @@ -33,7 +33,7 @@ CONFIG_MSM_CDC_PINCTRL=m CONFIG_SND_SOC_WCD_MBHC_ADC=m CONFIG_SND_SOC_WCD_MBHC_LEGACY=m CONFIG_QTI_PP=m -CONFIG_SND_HWDEP=m +CONFIG_SND_HWDEP_ROUTING=m CONFIG_DTS_EAGLE=m CONFIG_DOLBY_DS2=m CONFIG_DOLBY_LICENSE=m diff --git a/config/sdm670auto_static.conf b/config/sdm670auto_static.conf index dc555646594d..91a84649da8f 100644 --- a/config/sdm670auto_static.conf +++ b/config/sdm670auto_static.conf @@ -33,7 +33,7 @@ CONFIG_MSM_CDC_PINCTRL=y CONFIG_SND_SOC_WCD_MBHC_ADC=y CONFIG_SND_SOC_WCD_MBHC_LEGACY=y CONFIG_QTI_PP=y -CONFIG_SND_HWDEP=y +CONFIG_SND_HWDEP_ROUTING=y CONFIG_DTS_EAGLE=y CONFIG_DOLBY_DS2=y CONFIG_DOLBY_LICENSE=y diff --git a/config/sdm670autoconf.h b/config/sdm670autoconf.h index 462862f31c50..55f9548fc44a 100644 --- a/config/sdm670autoconf.h +++ b/config/sdm670autoconf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -43,7 +43,7 @@ #define CONFIG_SND_SOC_QDSP6V2 1 #define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 #define CONFIG_QTI_PP 1 -#define CONFIG_SND_HWDEP 1 +#define CONFIG_SND_HWDEP_ROUTING 1 #define CONFIG_DTS_EAGLE 1 #define CONFIG_DOLBY_DS2 1 #define CONFIG_DOLBY_LICENSE 1 diff --git a/config/sdm845auto.conf b/config/sdm845auto.conf index 5234e2b3a618..4c195b43ddc6 100644 --- a/config/sdm845auto.conf +++ b/config/sdm845auto.conf @@ -27,7 +27,7 @@ CONFIG_SOUNDWIRE=y CONFIG_SND_SOC_QDSP6V2=y CONFIG_SND_SOC_WCD_MBHC_ADC=y CONFIG_QTI_PP=y -CONFIG_SND_HWDEP=y +CONFIG_SND_HWDEP_ROUTING=y CONFIG_DTS_EAGLE=y CONFIG_DOLBY_DS2=y CONFIG_DOLBY_LICENSE=y diff --git a/config/sdm845autoconf.h b/config/sdm845autoconf.h index fcef4c13e776..6ef465a61871 100644 --- a/config/sdm845autoconf.h +++ b/config/sdm845autoconf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -38,7 +38,7 @@ #define CONFIG_SND_SOC_QDSP6V2 1 #define CONFIG_MSM_CDC_PINCTRL 1 #define CONFIG_QTI_PP 1 -#define CONFIG_SND_HWDEP 1 +#define CONFIG_SND_HWDEP_ROUTING 1 #define CONFIG_DTS_EAGLE 1 #define CONFIG_DOLBY_DS2 1 #define CONFIG_DOLBY_LICENSE 1 diff --git a/config/sdm855auto.conf b/config/sdm855auto.conf index 5257790c6173..48d82f1cdb43 100644 --- a/config/sdm855auto.conf +++ b/config/sdm855auto.conf @@ -27,7 +27,7 @@ CONFIG_SOUNDWIRE=m CONFIG_SND_SOC_QDSP6V2=m CONFIG_SND_SOC_WCD_MBHC_ADC=m CONFIG_QTI_PP=m -CONFIG_SND_HWDEP=m +CONFIG_SND_HWDEP_ROUTING=m CONFIG_DTS_EAGLE=m CONFIG_DOLBY_DS2=m CONFIG_DOLBY_LICENSE=m diff --git a/config/sdm855autoconf.h b/config/sdm855autoconf.h index 593934adfee0..77923c88546e 100644 --- a/config/sdm855autoconf.h +++ b/config/sdm855autoconf.h @@ -39,7 +39,7 @@ #define CONFIG_SND_SOC_WCD_MBHC_ADC 1 #define CONFIG_SND_SOC_QDSP6V2 1 #define CONFIG_QTI_PP 1 -#define CONFIG_SND_HWDEP 1 +#define CONFIG_SND_HWDEP_ROUTING 1 #define CONFIG_DTS_EAGLE 1 #define CONFIG_DOLBY_DS2 1 #define CONFIG_DOLBY_LICENSE 1 diff --git a/config/sdxpoorwillsauto.conf b/config/sdxpoorwillsauto.conf index d9dd081e876a..dee34a08be5d 100644 --- a/config/sdxpoorwillsauto.conf +++ b/config/sdxpoorwillsauto.conf @@ -24,6 +24,6 @@ CONFIG_MSM_CDC_PINCTRL=y CONFIG_WCD9XXX_CODEC_CORE=y CONFIG_SND_SOC_WCD_MBHC_ADC=y CONFIG_QTI_PP=y -CONFIG_SND_HWDEP=y +CONFIG_SND_HWDEP_ROUTING=y CONFIG_SND_SOC_MACHINE_SDXPOORWILLS=y CONFIG_SND_SOC_MSM_STUB=y diff --git a/config/sdxpoorwillsautoconf.h b/config/sdxpoorwillsautoconf.h index 9fc6258fe1b3..7b7dac403b63 100644 --- a/config/sdxpoorwillsautoconf.h +++ b/config/sdxpoorwillsautoconf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -37,6 +37,6 @@ #define CONFIG_WCD9XXX_CODEC_CORE 1 #define CONFIG_SND_SOC_WCD_MBHC_ADC 1 #define CONFIG_QTI_PP 1 -#define CONFIG_SND_HWDEP 1 +#define CONFIG_SND_HWDEP_ROUTING 1 #define CONFIG_SND_SOC_MACHINE_SDXPOORWILLS 1 #define CONFIG_SND_SOC_MSM_STUB 1 -- GitLab From 7c944235ae7d92fd8ea84f1d5282a766c06b1d98 Mon Sep 17 00:00:00 2001 From: Sachin Mohan Gadag Date: Thu, 4 Jan 2018 11:04:00 +0530 Subject: [PATCH 0209/1645] asoc: Add new dais to support compress record Add new dais to support compress record usecase. Update media_encoder_format api to v4 version in compress driver. CRs-Fixed: 2167556 Change-Id: I8a2f8a4cdcec4bb31ad94730eb4f1259e800c70c Signed-off-by: Sachin Mohan Gadag --- asoc/msm-compress-q6-v2.c | 7 +- asoc/msm-dai-fe.c | 50 ++++++++- asoc/msm-pcm-routing-v2.c | 227 +++++++++++++++++++++++++++++++++++++- asoc/msm-pcm-routing-v2.h | 8 +- 4 files changed, 278 insertions(+), 14 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 3a3774a4e930..b644df701123 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1521,9 +1521,10 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream) pr_debug("%s: sample_rate = %d channels = %d bps = %d sample_word_size = %d\n", __func__, prtd->sample_rate, prtd->num_channels, bits_per_sample, sample_word_size); - ret = q6asm_enc_cfg_blk_pcm_format_support_v3(prtd->audio_client, + ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client, prtd->sample_rate, prtd->num_channels, - bits_per_sample, sample_word_size); + bits_per_sample, sample_word_size, + ASM_LITTLE_ENDIAN, DEFAULT_QF); return ret; } diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index b086fa6e97ec..3de797f1559f 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2483,7 +2483,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .capture = { .stream_name = "MultiMedia17 Capture", .aif_name = "MM_UL17", - .rates = (SNDRV_PCM_RATE_8000_48000| + .rates = (SNDRV_PCM_RATE_8000_192000| SNDRV_PCM_RATE_KNOT), .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | @@ -2491,7 +2491,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .channels_min = 1, .channels_max = 8, .rate_min = 8000, - .rate_max = 48000, + .rate_max = 192000, }, .ops = &msm_fe_Multimedia_dai_ops, .compress_new = snd_soc_new_compress, @@ -2502,7 +2502,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .capture = { .stream_name = "MultiMedia18 Capture", .aif_name = "MM_UL18", - .rates = (SNDRV_PCM_RATE_8000_48000| + .rates = (SNDRV_PCM_RATE_8000_192000| SNDRV_PCM_RATE_KNOT), .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | @@ -2521,7 +2521,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .capture = { .stream_name = "MultiMedia19 Capture", .aif_name = "MM_UL19", - .rates = (SNDRV_PCM_RATE_8000_48000| + .rates = (SNDRV_PCM_RATE_8000_192000| SNDRV_PCM_RATE_KNOT), .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | @@ -2529,7 +2529,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .channels_min = 1, .channels_max = 8, .rate_min = 8000, - .rate_max = 48000, + .rate_max = 192000, }, .ops = &msm_fe_Multimedia_dai_ops, .compress_new = snd_soc_new_compress, @@ -2569,6 +2569,44 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "MultiMedia20", .probe = fe_dai_probe, }, + { + .capture = { + .stream_name = "MultiMedia28 Capture", + .aif_name = "MM_UL28", + .rates = (SNDRV_PCM_RATE_8000_192000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia28", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "MultiMedia29 Capture", + .aif_name = "MM_UL29", + .rates = (SNDRV_PCM_RATE_8000_192000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia29", + .probe = fe_dai_probe, + }, }; static int msm_fe_dai_dev_probe(struct platform_device *pdev) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index ff2be80b13e6..9c30eb0a25bb 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -643,6 +643,12 @@ static struct msm_pcm_routing_fdai_data {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, /* MULTIMEDIA20 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA28 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA29 */ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, /* VOIP */ @@ -3727,6 +3733,16 @@ static const struct snd_kcontrol_new ext_ec_ref_mux_ul19 = msm_route_ec_ref_rx_enum[0], msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); +static const struct snd_kcontrol_new ext_ec_ref_mux_ul28 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL28 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + +static const struct snd_kcontrol_new ext_ec_ref_mux_ul29 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL29 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + static int msm_routing_ext_ec_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -3870,6 +3886,12 @@ static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = { @@ -3930,6 +3952,12 @@ static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new spdif_rx_mixer_controls[] = { @@ -3990,7 +4018,12 @@ static const struct snd_kcontrol_new spdif_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new slimbus_2_rx_mixer_controls[] = { @@ -4102,6 +4135,12 @@ static const struct snd_kcontrol_new slimbus_5_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = { @@ -4162,6 +4201,12 @@ static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = { @@ -4222,6 +4267,12 @@ static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = { @@ -4282,6 +4333,12 @@ static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quinary_mi2s_rx_mixer_controls[] = { @@ -4342,6 +4399,13 @@ static const struct snd_kcontrol_new quinary_mi2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + }; static const struct snd_kcontrol_new tertiary_mi2s_rx_mixer_controls[] = { @@ -4396,6 +4460,12 @@ static const struct snd_kcontrol_new tertiary_mi2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new secondary_mi2s_rx2_mixer_controls[] = { @@ -4462,6 +4532,12 @@ static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = { @@ -4522,6 +4598,13 @@ static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + }; static const struct snd_kcontrol_new int0_mi2s_rx_mixer_controls[] = { @@ -4684,6 +4767,12 @@ static const struct snd_kcontrol_new hdmi_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new display_port_mixer_controls[] = { @@ -4994,6 +5083,12 @@ static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new int_bt_a2dp_rx_mixer_controls[] = { @@ -5105,6 +5200,12 @@ static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = { @@ -5165,6 +5266,12 @@ static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = { @@ -5225,6 +5332,12 @@ static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = { @@ -5285,6 +5398,12 @@ static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_auxpcm_rx_mixer_controls[] = { @@ -7830,6 +7949,9 @@ static const struct snd_kcontrol_new mmul17_mixer_controls[] = { SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -7854,6 +7976,9 @@ static const struct snd_kcontrol_new mmul18_mixer_controls[] = { SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -7881,6 +8006,9 @@ static const struct snd_kcontrol_new mmul19_mixer_controls[] = { SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -7976,6 +8104,60 @@ static const struct snd_kcontrol_new mmul20_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new mmul28_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul29_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, @@ -13170,6 +13352,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { mmul19_mixer_controls, ARRAY_SIZE(mmul19_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia20 Mixer", SND_SOC_NOPM, 0, 0, mmul20_mixer_controls, ARRAY_SIZE(mmul20_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia28 Mixer", SND_SOC_NOPM, 0, 0, + mmul28_mixer_controls, ARRAY_SIZE(mmul28_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia29 Mixer", SND_SOC_NOPM, 0, 0, + mmul29_mixer_controls, ARRAY_SIZE(mmul29_mixer_controls)), SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)), SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, @@ -13752,14 +13938,27 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia17 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia18 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia19 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia28 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia29 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia8 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia2 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia4 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia17 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia18 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia19 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia28 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia29 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia8 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia17 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia18 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia19 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia28 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia29 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia17 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia18 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia19 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia28 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia29 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia8 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, @@ -14450,6 +14649,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia10 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia16 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia17 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia18 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia19 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia28 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia29 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia6 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"MultiMedia6 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, @@ -14757,6 +14961,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia17 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia18 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia19 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia28 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia29 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia5 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia8 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia16 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, @@ -14766,6 +14972,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia17 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia18 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia19 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia28 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia29 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia5 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia6 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia8 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, @@ -14777,6 +14985,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia17 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia18 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia19 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia28 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia29 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia5 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia8 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia16 Mixer", "AFE_PCM_TX", "PCM_TX"}, @@ -14795,6 +15005,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL18", NULL, "MultiMedia18 Mixer"}, {"MM_UL19", NULL, "MultiMedia19 Mixer"}, {"MM_UL20", NULL, "MultiMedia20 Mixer"}, + {"MM_UL28", NULL, "MultiMedia28 Mixer"}, + {"MM_UL29", NULL, "MultiMedia29 Mixer"}, {"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, @@ -15127,6 +15339,15 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUDIO_REF_EC_UL19 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"AUDIO_REF_EC_UL19 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"AUDIO_REF_EC_UL28 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL28 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL28 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL28 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"AUDIO_REF_EC_UL29 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL29 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL29 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL29 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"LSM1_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, {"LSM2_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, @@ -15150,6 +15371,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL17", NULL, "AUDIO_REF_EC_UL17 MUX"}, {"MM_UL18", NULL, "AUDIO_REF_EC_UL18 MUX"}, {"MM_UL19", NULL, "AUDIO_REF_EC_UL19 MUX"}, + {"MM_UL28", NULL, "AUDIO_REF_EC_UL28 MUX"}, + {"MM_UL29", NULL, "AUDIO_REF_EC_UL29 MUX"}, {"VoiceMMode1_Tx Mixer", "PRI_TX_MMode1", "PRI_I2S_TX"}, {"VoiceMMode1_Tx Mixer", "PRI_MI2S_TX_MMode1", "PRI_MI2S_TX"}, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index a1977b4b3737..19c710c4b4a5 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -211,6 +211,8 @@ enum { MSM_FRONTEND_DAI_MULTIMEDIA18, MSM_FRONTEND_DAI_MULTIMEDIA19, MSM_FRONTEND_DAI_MULTIMEDIA20, + MSM_FRONTEND_DAI_MULTIMEDIA28, + MSM_FRONTEND_DAI_MULTIMEDIA29, MSM_FRONTEND_DAI_VOIP, MSM_FRONTEND_DAI_AFE_RX, MSM_FRONTEND_DAI_AFE_TX, @@ -232,8 +234,8 @@ enum { MSM_FRONTEND_DAI_MAX, }; -#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA20 + 1) -#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA20 +#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA29 + 1) +#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA29 enum { MSM_BACKEND_DAI_PRI_I2S_RX = 0, -- GitLab From b52a3775e21b2b726d000580c8a173bd874d7f5f Mon Sep 17 00:00:00 2001 From: Sachin Mohan Gadag Date: Mon, 8 Jan 2018 15:13:33 +0530 Subject: [PATCH 0210/1645] asoc: sdm660: Add new dais for multiple record session Add new dais to support multiple record session in compress path. CRs-Fixed: 2167556 Change-Id: I2020adc2fd2e56e7ad76529e53a772963a64cdd9 Signed-off-by: Sachin Mohan Gadag --- asoc/sdm660-internal.c | 78 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/asoc/sdm660-internal.c b/asoc/sdm660-internal.c index 7e02e21f3629..fc141e32530e 100644 --- a/asoc/sdm660-internal.c +++ b/asoc/sdm660-internal.c @@ -2360,6 +2360,79 @@ static struct snd_soc_dai_link msm_int_wsa_dai[] = { }, }; +static struct snd_soc_dai_link msm_int_compress_capture_dai[] = { + {/* hw:x,41 */ + .name = "Compress9", + .stream_name = "Compress9", + .cpu_dai_name = "MultiMedia17", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA17, + }, + {/* hw:x,42 */ + .name = "Compress10", + .stream_name = "Compress10", + .cpu_dai_name = "MultiMedia18", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA18, + }, + {/* hw:x,43 */ + .name = "Compress11", + .stream_name = "Compress11", + .cpu_dai_name = "MultiMedia19", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA19, + }, + {/* hw:x,44 */ + .name = "Compress12", + .stream_name = "Compress12", + .cpu_dai_name = "MultiMedia28", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA28, + }, + {/* hw:x,45 */ + .name = "Compress13", + .stream_name = "Compress13", + .cpu_dai_name = "MultiMedia29", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA29, + }, +}; + static struct snd_soc_dai_link msm_int_be_dai[] = { /* Backend I2S DAI Links */ { @@ -3064,6 +3137,7 @@ static struct snd_soc_dai_link ext_disp_be_dai_link[] = { static struct snd_soc_dai_link msm_int_dai_links[ ARRAY_SIZE(msm_int_dai) + ARRAY_SIZE(msm_int_wsa_dai) + +ARRAY_SIZE(msm_int_compress_capture_dai) + ARRAY_SIZE(msm_int_be_dai) + ARRAY_SIZE(msm_mi2s_be_dai_links) + ARRAY_SIZE(msm_auxpcm_be_dai_links)+ @@ -3142,6 +3216,10 @@ static struct snd_soc_card *msm_int_populate_sndcard_dailinks( sizeof(msm_int_wsa_dai)); len1 += ARRAY_SIZE(msm_int_wsa_dai); } + memcpy(dailink + len1, msm_int_compress_capture_dai, + sizeof(msm_int_compress_capture_dai)); + len1 += ARRAY_SIZE(msm_int_compress_capture_dai); + memcpy(dailink + len1, msm_int_be_dai, sizeof(msm_int_be_dai)); len1 += ARRAY_SIZE(msm_int_be_dai); -- GitLab From e882fea9cd2289032664fb2ec8bdb58024014878 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 3 Mar 2018 07:47:38 +0530 Subject: [PATCH 0211/1645] ASoC: wcd9360: Fix re-definition errors due to dynamic detection Enablement of WCD934x and WCD9360 codecs for dynamic detection results in redefinition errors due to same enums and API definition in WCD934x and WCD9360 codec drivers. Resolve the same. Change-Id: Ifed50dc1df0562ba62b14187597cad2bed6c1115 Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd9360/wcd9360-dsp-cntl.c | 4 ++-- asoc/codecs/wcd9360/wcd9360.c | 17 ++++++++++++++++- asoc/codecs/wcd9360/wcd9360.h | 18 +----------------- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c b/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c index 5a67aa62cd20..4b46032ffc32 100644 --- a/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c +++ b/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c @@ -1078,7 +1078,7 @@ static int wcd_ctrl_component_bind(struct device *dev, return -EINVAL; } - cntl = pahu_get_wcd_dsp_cntl(dev); + cntl = (struct wcd_dsp_cntl *) pahu_get_wcd_dsp_cntl(dev); if (!cntl) { dev_err(dev, "%s: Failed to get cntl reference\n", __func__); @@ -1165,7 +1165,7 @@ static void wcd_ctrl_component_unbind(struct device *dev, return; } - cntl = pahu_get_wcd_dsp_cntl(dev); + cntl = (struct wcd_dsp_cntl *) pahu_get_wcd_dsp_cntl(dev); if (!cntl) { dev_err(dev, "%s: Failed to get cntl reference\n", __func__); diff --git a/asoc/codecs/wcd9360/wcd9360.c b/asoc/codecs/wcd9360/wcd9360.c index d195152d2a8d..5b8da208a61b 100644 --- a/asoc/codecs/wcd9360/wcd9360.c +++ b/asoc/codecs/wcd9360/wcd9360.c @@ -153,6 +153,21 @@ static const struct snd_kcontrol_new name##_mux = \ #define WCD9360_DIG_CORE_COLLAPSE_TIMER_MS (5 * 1000) +enum { + INTERP_EAR = 0, + /* Headset and Lineout are not avalible in pahu */ + INTERP_HPHL_NA, + INTERP_HPHR_NA, + INTERP_LO1_NA, + INTERP_LO2_NA, + INTERP_LO3_NA, + INTERP_LO4_NA, + INTERP_SPKR1, + INTERP_SPKR2, + INTERP_AUX, + INTERP_MAX, +}; + enum { POWER_COLLAPSE, POWER_RESUME, @@ -7904,7 +7919,7 @@ static int __pahu_enable_efuse_sensing(struct pahu_priv *pahu) * * This API gets the reference to codec's struct wcd_dsp_cntl */ -struct wcd_dsp_cntl *pahu_get_wcd_dsp_cntl(struct device *dev) +void *pahu_get_wcd_dsp_cntl(struct device *dev) { struct platform_device *pdev; struct pahu_priv *pahu; diff --git a/asoc/codecs/wcd9360/wcd9360.h b/asoc/codecs/wcd9360/wcd9360.h index 21f4e73fff73..2c70a6853499 100644 --- a/asoc/codecs/wcd9360/wcd9360.h +++ b/asoc/codecs/wcd9360/wcd9360.h @@ -14,7 +14,6 @@ #define __WCD9360_H__ #include -#include "wcd9360-dsp-cntl.h" #include "../wcd9xxx-slimslave.h" #include "../wcd9xxx-common-v2.h" @@ -75,21 +74,6 @@ enum { WCD9360_TX_MAX, }; -enum { - INTERP_EAR = 0, - /* Headset and Lineout are not avalible in pahu */ - INTERP_HPHL_NA, - INTERP_HPHR_NA, - INTERP_LO1_NA, - INTERP_LO2_NA, - INTERP_LO3_NA, - INTERP_LO4_NA, - INTERP_SPKR1, - INTERP_SPKR2, - INTERP_AUX, - INTERP_MAX, -}; - /* * Selects compander and smart boost settings * for a given speaker mode @@ -149,7 +133,7 @@ extern int pahu_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable); extern int pahu_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable); extern int pahu_set_spkr_mode(struct snd_soc_codec *codec, int mode); extern int pahu_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset); -extern struct wcd_dsp_cntl *pahu_get_wcd_dsp_cntl(struct device *dev); +extern void *pahu_get_wcd_dsp_cntl(struct device *dev); extern int wcd9360_get_micb_vout_ctl_val(u32 micb_mv); extern int pahu_codec_info_create_codec_entry( struct snd_info_entry *codec_root, -- GitLab From 85073c0432a0c500d5f680f5dc27a6210f424e65 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Fri, 26 Jan 2018 10:27:56 -0800 Subject: [PATCH 0212/1645] ASoC: dsp: Update AFE driver to support Instance ID Add support to set and get AFE module params with Instance ID support. Maintain support for non Instance ID set and get param structures as well. Use common pack and set param functions to set and get parameters to DSP instead of handling them at an individual module level. CRs-Fixed: 2151551 Change-Id: I15dac800bdf7f860d0fbeeff86f986c42a9eae34 Signed-off-by: Vignesh Kulothungan --- dsp/q6afe.c | 3121 +++++++++++++++--------------------- dsp/rtac.c | 68 +- include/dsp/apr_audio-v2.h | 405 ++--- 3 files changed, 1484 insertions(+), 2110 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index d1ef665115b9..9a6b6ada0644 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "adsp_err.h" @@ -199,100 +200,127 @@ static void afe_callback_debug_print(struct apr_client_data *data) __func__, data->opcode, data->payload_size); } -static void av_dev_drift_afe_cb_handler(uint32_t *payload, +static void av_dev_drift_afe_cb_handler(uint32_t opcode, uint32_t *payload, uint32_t payload_size) { u32 param_id; - struct afe_av_dev_drift_get_param_resp *resp = - (struct afe_av_dev_drift_get_param_resp *) payload; - - if (!(&(resp->pdata))) { - pr_err("%s: Error: resp pdata is NULL\n", __func__); + size_t expected_size = + sizeof(u32) + sizeof(struct afe_param_id_dev_timing_stats); + + /* Get param ID depending on command type */ + param_id = (opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) ? payload[3] : + payload[2]; + if (param_id != AFE_PARAM_ID_DEV_TIMING_STATS) { + pr_err("%s: Unrecognized param ID %d\n", __func__, param_id); return; } - param_id = resp->pdata.param_id; - if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) { - if (payload_size < sizeof(this_afe.av_dev_drift_resp)) { - pr_err("%s: Error: received size %d, resp size %zu\n", - __func__, payload_size, - sizeof(this_afe.av_dev_drift_resp)); + switch (opcode) { + case AFE_PORT_CMDRSP_GET_PARAM_V2: + expected_size += sizeof(struct param_hdr_v1); + if (payload_size < expected_size) { + pr_err("%s: Error: received size %d, expected size %zu\n", + __func__, payload_size, expected_size); + return; + } + /* Repack response to add IID */ + this_afe.av_dev_drift_resp.status = payload[0]; + this_afe.av_dev_drift_resp.pdata.module_id = payload[1]; + this_afe.av_dev_drift_resp.pdata.instance_id = INSTANCE_ID_0; + this_afe.av_dev_drift_resp.pdata.param_id = payload[2]; + this_afe.av_dev_drift_resp.pdata.param_size = payload[3]; + memcpy(&this_afe.av_dev_drift_resp.timing_stats, &payload[4], + sizeof(struct afe_param_id_dev_timing_stats)); + break; + case AFE_PORT_CMDRSP_GET_PARAM_V3: + expected_size += sizeof(struct param_hdr_v3); + if (payload_size < expected_size) { + pr_err("%s: Error: received size %d, expected size %zu\n", + __func__, payload_size, expected_size); return; } memcpy(&this_afe.av_dev_drift_resp, payload, sizeof(this_afe.av_dev_drift_resp)); - if (!this_afe.av_dev_drift_resp.status) { - atomic_set(&this_afe.state, 0); - } else { - pr_debug("%s: av_dev_drift_resp status: %d", __func__, - this_afe.av_dev_drift_resp.status); - atomic_set(&this_afe.state, -1); - } + break; + default: + pr_err("%s: Unrecognized command %d\n", __func__, opcode); + return; + } + + if (!this_afe.av_dev_drift_resp.status) { + atomic_set(&this_afe.state, 0); + } else { + pr_debug("%s: av_dev_drift_resp status: %d", __func__, + this_afe.av_dev_drift_resp.status); + atomic_set(&this_afe.state, -1); } } -static int32_t sp_make_afe_callback(uint32_t *payload, uint32_t payload_size) +static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, + uint32_t payload_size) { - u32 param_id; - struct afe_spkr_prot_calib_get_resp *resp = - (struct afe_spkr_prot_calib_get_resp *) payload; - - if (!(&(resp->pdata))) { - pr_err("%s: Error: resp pdata is NULL\n", __func__); + struct param_hdr_v3 param_hdr; + u32 *data_dest = NULL; + u32 *data_start = NULL; + size_t expected_size = sizeof(u32); + + memset(¶m_hdr, 0, sizeof(param_hdr)); + + /* Set command specific details */ + switch (opcode) { + case AFE_PORT_CMDRSP_GET_PARAM_V2: + expected_size += sizeof(struct param_hdr_v1); + param_hdr.module_id = payload[1]; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = payload[2]; + param_hdr.param_size = payload[3]; + data_start = &payload[4]; + break; + case AFE_PORT_CMDRSP_GET_PARAM_V3: + expected_size += sizeof(struct param_hdr_v3); + memcpy(¶m_hdr, &payload[1], sizeof(struct param_hdr_v3)); + data_start = &payload[5]; + break; + default: + pr_err("%s: Unrecognized command %d\n", __func__, opcode); return -EINVAL; } - param_id = resp->pdata.param_id; - if (param_id == AFE_PARAM_ID_CALIB_RES_CFG_V2) { - if (payload_size < sizeof(this_afe.calib_data)) { - pr_err("%s: Error: received size %d, calib_data size %zu\n", - __func__, payload_size, - sizeof(this_afe.calib_data)); - return -EINVAL; - } - memcpy(&this_afe.calib_data, payload, - sizeof(this_afe.calib_data)); - if (!this_afe.calib_data.status) { - atomic_set(&this_afe.state, 0); - } else { - pr_debug("%s: calib resp status: %d", __func__, - this_afe.calib_data.status); - atomic_set(&this_afe.state, -1); - } + switch (param_hdr.param_id) { + case AFE_PARAM_ID_CALIB_RES_CFG_V2: + expected_size += sizeof(struct asm_calib_res_cfg); + data_dest = (u32 *) &this_afe.calib_data; + break; + case AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS: + expected_size += sizeof(struct afe_sp_th_vi_ftm_params); + data_dest = (u32 *) &this_afe.th_vi_resp; + break; + case AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS: + expected_size += sizeof(struct afe_sp_ex_vi_ftm_params); + data_dest = (u32 *) &this_afe.ex_vi_resp; + break; + default: + pr_err("%s: Unrecognized param ID %d\n", __func__, + param_hdr.param_id); + return -EINVAL; } - if (param_id == AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS) { - if (payload_size < sizeof(this_afe.th_vi_resp)) { - pr_err("%s: Error: received size %d, th_vi_resp size %zu\n", - __func__, payload_size, - sizeof(this_afe.th_vi_resp)); - return -EINVAL; - } - memcpy(&this_afe.th_vi_resp, payload, - sizeof(this_afe.th_vi_resp)); - if (!this_afe.th_vi_resp.status) { - atomic_set(&this_afe.state, 0); - } else { - pr_debug("%s: th vi resp status: %d", __func__, - this_afe.th_vi_resp.status); - atomic_set(&this_afe.state, -1); - } + + if (payload_size < expected_size) { + pr_err("%s: Error: received size %d, expected size %zu for param %d\n", + __func__, payload_size, expected_size, + param_hdr.param_id); + return -EINVAL; } - if (param_id == AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS) { - if (payload_size < sizeof(this_afe.ex_vi_resp)) { - pr_err("%s: Error: received size %d, ex_vi_resp size %zu\n", - __func__, payload_size, - sizeof(this_afe.ex_vi_resp)); - return -EINVAL; - } - memcpy(&this_afe.ex_vi_resp, payload, - sizeof(this_afe.ex_vi_resp)); - if (!this_afe.ex_vi_resp.status) { - atomic_set(&this_afe.state, 0); - } else { - pr_debug("%s: ex vi resp status: %d", __func__, - this_afe.ex_vi_resp.status); - atomic_set(&this_afe.state, -1); - } + + data_dest[0] = payload[0]; + memcpy(&data_dest[1], ¶m_hdr, sizeof(struct param_hdr_v3)); + memcpy(&data_dest[5], data_start, param_hdr.param_size); + + if (!data_dest[0]) { + atomic_set(&this_afe.state, 0); + } else { + pr_debug("%s: status: %d", __func__, data_dest[0]); + atomic_set(&this_afe.state, -1); } return 0; @@ -350,8 +378,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) return 0; } afe_callback_debug_print(data); - if (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V2) { + if (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V2 || + data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) { uint32_t *payload = data->payload; + uint32_t param_id; if (!payload || (data->token >= AFE_MAX_PORTS)) { pr_err("%s: Error: size %d payload %pK token %d\n", @@ -360,15 +390,18 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) return -EINVAL; } - if (payload[2] == AFE_PARAM_ID_DEV_TIMING_STATS) { - av_dev_drift_afe_cb_handler(data->payload, + param_id = (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) ? + payload[3] : + payload[2]; + if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) { + av_dev_drift_afe_cb_handler(data->opcode, data->payload, data->payload_size); } else { if (rtac_make_afe_callback(data->payload, data->payload_size)) return 0; - if (sp_make_afe_callback(data->payload, + if (sp_make_afe_callback(data->opcode, data->payload, data->payload_size)) return -EINVAL; } @@ -390,8 +423,9 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) } switch (payload[0]) { case AFE_PORT_CMD_SET_PARAM_V2: + case AFE_PORT_CMD_SET_PARAM_V3: if (rtac_make_afe_callback(payload, - data->payload_size)) + data->payload_size)) return 0; case AFE_PORT_CMD_DEVICE_STOP: case AFE_PORT_CMD_DEVICE_START: @@ -402,6 +436,7 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) case AFE_SERVICE_CMD_UNREGISTER_RT_PORT_DRIVER: case AFE_PORTS_CMD_DTMF_CTL: case AFE_SVC_CMD_SET_PARAM: + case AFE_SVC_CMD_SET_PARAM_V2: atomic_set(&this_afe.state, 0); wake_up(&this_afe.wait[data->token]); break; @@ -419,6 +454,28 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) pr_debug("%s: AFE_CMD_ADD_TOPOLOGIES cmd 0x%x\n", __func__, payload[1]); break; + case AFE_PORT_CMD_GET_PARAM_V2: + case AFE_PORT_CMD_GET_PARAM_V3: + /* + * Should only come here if there is an APR + * error or malformed APR packet. Otherwise + * response will be returned as + * AFE_PORT_CMDRSP_GET_PARAM_V2/3 + */ + pr_debug("%s: AFE Get Param opcode 0x%x token 0x%x src %d dest %d\n", + __func__, data->opcode, data->token, + data->src_port, data->dest_port); + if (payload[1] != 0) { + pr_err("%s: AFE Get Param failed with error %d\n", + __func__, payload[1]); + if (rtac_make_afe_callback( + payload, + data->payload_size)) + return 0; + } + atomic_set(&this_afe.state, payload[1]); + wake_up(&this_afe.wait[data->token]); + break; default: pr_err("%s: Unknown cmd 0x%x\n", __func__, payload[0]); @@ -796,11 +853,403 @@ static int afe_apr_send_pkt(void *data, wait_queue_head_t *wait) return ret; } +/* This function shouldn't be called directly. Instead call q6afe_set_params. */ +static int q6afe_set_params_v2(u16 port_id, int index, + struct mem_mapping_hdr *mem_hdr, + u8 *packed_param_data, u32 packed_data_size) +{ + struct afe_port_cmd_set_param_v2 *set_param = NULL; + uint32_t size = sizeof(struct afe_port_cmd_set_param_v2); + int rc = 0; + + if (packed_param_data != NULL) + size += packed_data_size; + set_param = kzalloc(size, GFP_KERNEL); + if (set_param == NULL) + return -ENOMEM; + + set_param->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + set_param->apr_hdr.pkt_size = size; + set_param->apr_hdr.src_port = 0; + set_param->apr_hdr.dest_port = 0; + set_param->apr_hdr.token = index; + set_param->apr_hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + set_param->port_id = port_id; + if (packed_data_size > U16_MAX) { + pr_err("%s: Invalid data size for set params V2 %d\n", __func__, + packed_data_size); + rc = -EINVAL; + goto done; + } + set_param->payload_size = packed_data_size; + if (mem_hdr != NULL) { + set_param->mem_hdr = *mem_hdr; + } else if (packed_param_data != NULL) { + memcpy(&set_param->param_data, packed_param_data, + packed_data_size); + } else { + pr_err("%s: Both memory header and param data are NULL\n", + __func__); + rc = -EINVAL; + goto done; + } + + rc = afe_apr_send_pkt(set_param, &this_afe.wait[index]); +done: + kfree(set_param); + return rc; +} + +/* This function shouldn't be called directly. Instead call q6afe_set_params. */ +static int q6afe_set_params_v3(u16 port_id, int index, + struct mem_mapping_hdr *mem_hdr, + u8 *packed_param_data, u32 packed_data_size) +{ + struct afe_port_cmd_set_param_v3 *set_param = NULL; + uint32_t size = sizeof(struct afe_port_cmd_set_param_v3); + int rc = 0; + + if (packed_param_data != NULL) + size += packed_data_size; + set_param = kzalloc(size, GFP_KERNEL); + if (set_param == NULL) + return -ENOMEM; + + set_param->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + set_param->apr_hdr.pkt_size = size; + set_param->apr_hdr.src_port = 0; + set_param->apr_hdr.dest_port = 0; + set_param->apr_hdr.token = index; + set_param->apr_hdr.opcode = AFE_PORT_CMD_SET_PARAM_V3; + set_param->port_id = port_id; + set_param->payload_size = packed_data_size; + if (mem_hdr != NULL) { + set_param->mem_hdr = *mem_hdr; + } else if (packed_param_data != NULL) { + memcpy(&set_param->param_data, packed_param_data, + packed_data_size); + } else { + pr_err("%s: Both memory header and param data are NULL\n", + __func__); + rc = -EINVAL; + goto done; + } + + rc = afe_apr_send_pkt(set_param, &this_afe.wait[index]); +done: + kfree(set_param); + return rc; +} + +static int q6afe_set_params(u16 port_id, int index, + struct mem_mapping_hdr *mem_hdr, + u8 *packed_param_data, u32 packed_data_size) +{ + int ret = 0; + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + port_id = q6audio_get_port_id(port_id); + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Not a valid port id = 0x%x ret %d\n", __func__, + port_id, ret); + return -EINVAL; + } + + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid\n", __func__, index); + return -EINVAL; + } + + if (q6common_is_instance_id_supported()) + return q6afe_set_params_v3(port_id, index, mem_hdr, + packed_param_data, packed_data_size); + else + return q6afe_set_params_v2(port_id, index, mem_hdr, + packed_param_data, packed_data_size); +} + +static int q6afe_pack_and_set_param_in_band(u16 port_id, int index, + struct param_hdr_v3 param_hdr, + u8 *param_data) +{ + u8 *packed_param_data = NULL; + int packed_data_size = sizeof(union param_hdrs) + param_hdr.param_size; + int ret; + + packed_param_data = kzalloc(packed_data_size, GFP_KERNEL); + if (packed_param_data == NULL) + return -ENOMEM; + + ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, param_data, + &packed_data_size); + if (ret) { + pr_err("%s: Failed to pack param header and data, error %d\n", + __func__, ret); + goto fail_cmd; + } + + ret = q6afe_set_params(port_id, index, NULL, packed_param_data, + packed_data_size); + +fail_cmd: + kfree(packed_param_data); + return ret; +} + +/* This function shouldn't be called directly. Instead call q6afe_get_param. */ +static int q6afe_get_params_v2(u16 port_id, int index, + struct mem_mapping_hdr *mem_hdr, + struct param_hdr_v3 *param_hdr) +{ + struct afe_port_cmd_get_param_v2 afe_get_param; + u32 param_size = param_hdr->param_size; + + memset(&afe_get_param, 0, sizeof(afe_get_param)); + afe_get_param.apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + afe_get_param.apr_hdr.pkt_size = sizeof(afe_get_param) + param_size; + afe_get_param.apr_hdr.src_port = 0; + afe_get_param.apr_hdr.dest_port = 0; + afe_get_param.apr_hdr.token = index; + afe_get_param.apr_hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; + afe_get_param.port_id = port_id; + afe_get_param.payload_size = sizeof(struct param_hdr_v1) + param_size; + if (mem_hdr != NULL) + afe_get_param.mem_hdr = *mem_hdr; + /* Set MID and PID in command */ + afe_get_param.module_id = param_hdr->module_id; + afe_get_param.param_id = param_hdr->param_id; + /* Set param header in payload */ + afe_get_param.param_hdr.module_id = param_hdr->module_id; + afe_get_param.param_hdr.param_id = param_hdr->param_id; + afe_get_param.param_hdr.param_size = param_size; + + return afe_apr_send_pkt(&afe_get_param, &this_afe.wait[index]); +} + +/* This function shouldn't be called directly. Instead call q6afe_get_param. */ +static int q6afe_get_params_v3(u16 port_id, int index, + struct mem_mapping_hdr *mem_hdr, + struct param_hdr_v3 *param_hdr) +{ + struct afe_port_cmd_get_param_v3 afe_get_param; + + memset(&afe_get_param, 0, sizeof(afe_get_param)); + afe_get_param.apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + afe_get_param.apr_hdr.pkt_size = sizeof(afe_get_param); + afe_get_param.apr_hdr.src_port = 0; + afe_get_param.apr_hdr.dest_port = 0; + afe_get_param.apr_hdr.token = index; + afe_get_param.apr_hdr.opcode = AFE_PORT_CMD_GET_PARAM_V3; + afe_get_param.port_id = port_id; + if (mem_hdr != NULL) + afe_get_param.mem_hdr = *mem_hdr; + /* Set param header in command, no payload in V3 */ + afe_get_param.param_hdr = *param_hdr; + + return afe_apr_send_pkt(&afe_get_param, &this_afe.wait[index]); +} + +/* + * Calling functions copy param data directly from this_afe. Do not copy data + * back to caller here. + */ +static int q6afe_get_params(u16 port_id, struct mem_mapping_hdr *mem_hdr, + struct param_hdr_v3 *param_hdr) +{ + int index; + int ret; + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + port_id = q6audio_get_port_id(port_id); + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Not a valid port id = 0x%x ret %d\n", __func__, + port_id, ret); + return -EINVAL; + } + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid\n", __func__, index); + return -EINVAL; + } + + if (q6common_is_instance_id_supported()) + return q6afe_get_params_v3(port_id, index, NULL, param_hdr); + else + return q6afe_get_params_v2(port_id, index, NULL, param_hdr); +} + +/* + * This function shouldn't be called directly. Instead call + * q6afe_svc_set_params. + */ +static int q6afe_svc_set_params_v1(int index, struct mem_mapping_hdr *mem_hdr, + u8 *packed_param_data, u32 packed_data_size) +{ + struct afe_svc_cmd_set_param_v1 *svc_set_param = NULL; + uint32_t size = sizeof(struct afe_svc_cmd_set_param_v1); + int rc = 0; + + if (packed_param_data != NULL) + size += packed_data_size; + svc_set_param = kzalloc(size, GFP_KERNEL); + if (svc_set_param == NULL) + return -ENOMEM; + + svc_set_param->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + svc_set_param->apr_hdr.pkt_size = size; + svc_set_param->apr_hdr.src_port = 0; + svc_set_param->apr_hdr.dest_port = 0; + svc_set_param->apr_hdr.token = IDX_GLOBAL_CFG; + svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM; + svc_set_param->payload_size = packed_data_size; + + if (mem_hdr != NULL) { + /* Out of band case. */ + svc_set_param->mem_hdr = *mem_hdr; + } else if (packed_param_data != NULL) { + /* In band case. */ + memcpy(&svc_set_param->param_data, packed_param_data, + packed_data_size); + } else { + pr_err("%s: Both memory header and param data are NULL\n", + __func__); + rc = -EINVAL; + goto done; + } + + rc = afe_apr_send_pkt(svc_set_param, &this_afe.wait[index]); +done: + kfree(svc_set_param); + return rc; +} + +/* + * This function shouldn't be called directly. Instead call + * q6afe_svc_set_params. + */ +static int q6afe_svc_set_params_v2(int index, struct mem_mapping_hdr *mem_hdr, + u8 *packed_param_data, u32 packed_data_size) +{ + struct afe_svc_cmd_set_param_v2 *svc_set_param = NULL; + uint16_t size = sizeof(struct afe_svc_cmd_set_param_v2); + int rc = 0; + + if (packed_param_data != NULL) + size += packed_data_size; + svc_set_param = kzalloc(size, GFP_KERNEL); + if (svc_set_param == NULL) + return -ENOMEM; + + svc_set_param->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + svc_set_param->apr_hdr.pkt_size = size; + svc_set_param->apr_hdr.src_port = 0; + svc_set_param->apr_hdr.dest_port = 0; + svc_set_param->apr_hdr.token = IDX_GLOBAL_CFG; + svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM_V2; + svc_set_param->payload_size = packed_data_size; + + if (mem_hdr != NULL) { + /* Out of band case. */ + svc_set_param->mem_hdr = *mem_hdr; + } else if (packed_param_data != NULL) { + /* In band case. */ + memcpy(&svc_set_param->param_data, packed_param_data, + packed_data_size); + } else { + pr_err("%s: Both memory header and param data are NULL\n", + __func__); + rc = -EINVAL; + goto done; + } + + rc = afe_apr_send_pkt(svc_set_param, &this_afe.wait[index]); +done: + kfree(svc_set_param); + return rc; +} + +static int q6afe_svc_set_params(int index, struct mem_mapping_hdr *mem_hdr, + u8 *packed_param_data, u32 packed_data_size) +{ + int ret; + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + if (q6common_is_instance_id_supported()) + return q6afe_svc_set_params_v2(index, mem_hdr, + packed_param_data, + packed_data_size); + else + return q6afe_svc_set_params_v1(index, mem_hdr, + packed_param_data, + packed_data_size); +} + +static int q6afe_svc_pack_and_set_param_in_band(int index, + struct param_hdr_v3 param_hdr, + u8 *param_data) +{ + u8 *packed_param_data = NULL; + u32 packed_data_size = + sizeof(struct param_hdr_v3) + param_hdr.param_size; + int ret = 0; + + packed_param_data = kzalloc(packed_data_size, GFP_KERNEL); + if (!packed_param_data) + return -ENOMEM; + + ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, param_data, + &packed_data_size); + if (ret) { + pr_err("%s: Failed to pack parameter header and data, error %d\n", + __func__, ret); + goto done; + } + + ret = q6afe_svc_set_params(index, NULL, packed_param_data, + packed_data_size); + +done: + kfree(packed_param_data); + return ret; +} + static int afe_send_cal_block(u16 port_id, struct cal_block_data *cal_block) { - int result = 0; - int index = 0; - struct afe_audioif_config_command_no_payload afe_cal; + struct mem_mapping_hdr mem_hdr; + int payload_size = 0; + int result = 0; + + memset(&mem_hdr, 0, sizeof(mem_hdr)); if (!cal_block) { pr_debug("%s: No AFE cal to send!\n", __func__); @@ -813,34 +1262,19 @@ static int afe_send_cal_block(u16 port_id, struct cal_block_data *cal_block) goto done; } - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - result = -EINVAL; - goto done; - } - - afe_cal.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - afe_cal.hdr.pkt_size = sizeof(afe_cal); - afe_cal.hdr.src_port = 0; - afe_cal.hdr.dest_port = 0; - afe_cal.hdr.token = index; - afe_cal.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - afe_cal.param.port_id = port_id; - afe_cal.param.payload_size = cal_block->cal_data.size; - afe_cal.param.payload_address_lsw = + payload_size = cal_block->cal_data.size; + mem_hdr.data_payload_addr_lsw = lower_32_bits(cal_block->cal_data.paddr); - afe_cal.param.payload_address_msw = + mem_hdr.data_payload_addr_msw = msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr); - afe_cal.param.mem_map_handle = cal_block->map_data.q6map_handle; + mem_hdr.mem_map_handle = cal_block->map_data.q6map_handle; pr_debug("%s: AFE cal sent for device port = 0x%x, cal size = %zd, cal addr = 0x%pK\n", __func__, port_id, cal_block->cal_data.size, &cal_block->cal_data.paddr); - result = afe_apr_send_pkt(&afe_cal, &this_afe.wait[index]); + result = q6afe_set_params(port_id, q6audio_get_port_index(port_id), + &mem_hdr, NULL, payload_size); if (result) pr_err("%s: AFE cal for port 0x%x failed %d\n", __func__, port_id, result); @@ -936,9 +1370,10 @@ static void afe_send_custom_topology(void) static int afe_spk_ramp_dn_cfg(int port) { + struct param_hdr_v3 param_info; int ret = -EINVAL; - int index = 0; - struct afe_spkr_prot_config_command config; + + memset(¶m_info, 0, sizeof(param_info)); if (afe_get_port_type(port) != MSM_AFE_PORT_TYPE_RX) { pr_debug("%s: port doesn't match 0x%x\n", __func__, port); @@ -950,84 +1385,41 @@ static int afe_spk_ramp_dn_cfg(int port) __func__, port, ret, this_afe.vi_rx_port); return 0; } - memset(&config, 0, sizeof(config)); - ret = q6audio_validate_port(port); - if (ret < 0) { - pr_err("%s: Invalid port 0x%x ret %d", __func__, port, ret); - ret = -EINVAL; - goto fail_cmd; - } - index = q6audio_get_port_index(port); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - ret = -EINVAL; - goto fail_cmd; - } - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port); - config.param.payload_size = - sizeof(config) - sizeof(config.hdr) - sizeof(config.param) - - sizeof(config.prot_config); - config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; - config.pdata.param_id = AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG; - config.pdata.param_size = 0; - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config); - if (ret < 0) { - pr_err("%s: port = 0x%x param = 0x%x failed %d\n", - __func__, port, config.pdata.param_id, ret); - goto fail_cmd; - } - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); + param_info.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG; + param_info.param_size = 0; + + ret = q6afe_pack_and_set_param_in_band(port, + q6audio_get_port_index(port), + param_info, NULL); + if (ret) { + pr_err("%s: Failed to set speaker ramp duration param, err %d\n", + __func__, ret); goto fail_cmd; } + /* dsp needs atleast 15ms to ramp down pilot tone*/ usleep_range(15000, 15010); ret = 0; fail_cmd: - pr_debug("%s: config.pdata.param_id 0x%x status %d\n", - __func__, config.pdata.param_id, ret); -return ret; + pr_debug("%s: config.pdata.param_id 0x%x status %d\n", __func__, + param_info.param_id, ret); + return ret; } static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, - union afe_spkr_prot_config *prot_config) + union afe_spkr_prot_config *prot_config) { + struct param_hdr_v3 param_info; int ret = -EINVAL; - int index = 0; - struct afe_spkr_prot_config_command config; - memset(&config, 0, sizeof(config)); - if (!prot_config) { - pr_err("%s: Invalid params\n", __func__); - goto fail_cmd; - } + memset(¶m_info, 0, sizeof(param_info)); + ret = q6audio_validate_port(src_port); if (ret < 0) { - pr_err("%s: Invalid src port 0x%x ret %d", - __func__, src_port, ret); + pr_err("%s: Invalid src port 0x%x ret %d", __func__, src_port, + ret); ret = -EINVAL; goto fail_cmd; } @@ -1038,22 +1430,16 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, ret = -EINVAL; goto fail_cmd; } - index = q6audio_get_port_index(src_port); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - ret = -EINVAL; - goto fail_cmd; - } + switch (param_id) { case AFE_PARAM_ID_FBSP_MODE_RX_CFG: case AFE_PARAM_ID_SP_RX_LIMITER_TH: - config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; + param_info.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; break; case AFE_PARAM_ID_FEEDBACK_PATH_CFG: this_afe.vi_tx_port = src_port; this_afe.vi_rx_port = dst_port; - config.pdata.module_id = AFE_MODULE_FEEDBACK; + param_info.module_id = AFE_MODULE_FEEDBACK; break; /* * AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2 is same as @@ -1061,59 +1447,31 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, */ case AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2: case AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG: - config.pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; + param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; break; case AFE_PARAM_ID_SP_V2_EX_VI_MODE_CFG: case AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG: - config.pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; + param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; break; default: pr_err("%s: default case 0x%x\n", __func__, param_id); goto fail_cmd; } - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(src_port); - config.param.payload_size = sizeof(config) - sizeof(config.hdr) - - sizeof(config.param); - config.pdata.param_id = param_id; - config.pdata.param_size = sizeof(config.prot_config); - config.prot_config = *prot_config; - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config); - if (ret < 0) { - pr_err("%s: port = 0x%x param = 0x%x failed %d\n", - __func__, src_port, param_id, ret); - goto fail_cmd; - } - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } - ret = 0; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = param_id; + param_info.param_size = sizeof(union afe_spkr_prot_config); + + ret = q6afe_pack_and_set_param_in_band(src_port, + q6audio_get_port_index(src_port), + param_info, (u8 *) prot_config); + if (ret) + pr_err("%s: port = 0x%x param = 0x%x failed %d\n", __func__, + src_port, param_id, ret); + fail_cmd: - pr_debug("%s: config.pdata.param_id 0x%x status %d 0x%x\n", - __func__, config.pdata.param_id, ret, src_port); + pr_debug("%s: config.pdata.param_id 0x%x status %d 0x%x\n", __func__, + param_info.param_id, ret, src_port); return ret; } @@ -1286,14 +1644,16 @@ static void afe_send_cal_spkr_prot_rx(int port_id) static int afe_send_hw_delay(u16 port_id, u32 rate) { - struct audio_cal_hw_delay_entry delay_entry; - struct afe_audioif_config_command config; - int index = 0; + struct audio_cal_hw_delay_entry delay_entry; + struct afe_param_id_device_hw_delay_cfg hw_delay; + struct param_hdr_v3 param_info; int ret = -EINVAL; pr_debug("%s:\n", __func__); memset(&delay_entry, 0, sizeof(delay_entry)); + memset(¶m_info, 0, sizeof(param_info)); + delay_entry.sample_rate = rate; if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX) ret = afe_get_cal_hw_delay(TX_DEVICE, &delay_entry); @@ -1311,42 +1671,21 @@ static int afe_send_hw_delay(u16 port_id, u32 rate) goto fail_cmd; } - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - ret = -EINVAL; - goto fail_cmd; - } + param_info.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = AFE_PARAM_ID_DEVICE_HW_DELAY; + param_info.param_size = sizeof(hw_delay); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - config.pdata.param_id = AFE_PARAM_ID_DEVICE_HW_DELAY; - config.pdata.param_size = sizeof(config.port); - - config.port.hw_delay.delay_in_us = delay_entry.delay_usec; - config.port.hw_delay.device_hw_delay_minor_version = - AFE_API_VERSION_DEVICE_HW_DELAY; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); - if (ret) { + hw_delay.delay_in_us = delay_entry.delay_usec; + hw_delay.device_hw_delay_minor_version = + AFE_API_VERSION_DEVICE_HW_DELAY; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_info, (u8 *) &hw_delay); + if (ret) pr_err("%s: AFE hw delay for port 0x%x failed %d\n", __func__, port_id, ret); - goto fail_cmd; - } fail_cmd: pr_debug("%s: port_id 0x%x rate %u delay_usec %d status %d\n", @@ -1446,11 +1785,14 @@ static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id, static int afe_send_port_topology_id(u16 port_id) { - struct afe_audioif_config_command config; + struct afe_param_id_set_topology_cfg topology; + struct param_hdr_v3 param_info; + u32 topology_id = 0; int index = 0; int ret = 0; - u32 topology_id = 0; + memset(&topology, 0, sizeof(topology)); + memset(¶m_info, 0, sizeof(param_info)); index = q6audio_get_port_index(port_id); if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", @@ -1470,32 +1812,17 @@ static int afe_send_port_topology_id(u16 port_id) goto done; } - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - config.pdata.param_id = AFE_PARAM_ID_SET_TOPOLOGY; - config.pdata.param_size = sizeof(config.port); - config.port.topology.minor_version = AFE_API_VERSION_TOPOLOGY_V1; - config.port.topology.topology_id = topology_id; - - pr_debug("%s: param PL size=%d iparam_size[%d][%zd %zd %zd %zd] param_id[0x%x]\n", - __func__, config.param.payload_size, config.pdata.param_size, - sizeof(config), sizeof(config.param), sizeof(config.port), - sizeof(struct apr_hdr), config.pdata.param_id); - - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + param_info.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = AFE_PARAM_ID_SET_TOPOLOGY; + param_info.param_size = sizeof(topology); + + topology.minor_version = AFE_API_VERSION_TOPOLOGY_V1; + topology.topology_id = topology_id; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_info, (u8 *) &topology); if (ret) { pr_err("%s: AFE set topology id enable for port 0x%x failed %d\n", __func__, port_id, ret); @@ -1657,33 +1984,26 @@ void afe_send_cal(u16 port_id) int afe_turn_onoff_hw_mad(u16 mad_type, u16 enable) { + struct afe_param_hw_mad_ctrl mad_enable_param; + struct param_hdr_v3 param_info; int ret; - struct afe_cmd_hw_mad_ctrl config; pr_debug("%s: enter\n", __func__); - memset(&config, 0, sizeof(config)); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = IDX_GLOBAL_CFG; - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = SLIMBUS_5_TX; - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_HW_MAD; - config.pdata.param_id = AFE_PARAM_ID_HW_MAD_CTRL; - config.pdata.param_size = sizeof(config.payload); - config.payload.minor_version = 1; - config.payload.mad_type = mad_type; - config.payload.mad_enable = enable; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + + memset(&mad_enable_param, 0, sizeof(mad_enable_param)); + memset(¶m_info, 0, sizeof(param_info)); + param_info.module_id = AFE_MODULE_HW_MAD; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = AFE_PARAM_ID_HW_MAD_CTRL; + param_info.param_size = sizeof(mad_enable_param); + + mad_enable_param.minor_version = 1; + mad_enable_param.mad_type = mad_type; + mad_enable_param.mad_enable = enable; + + ret = q6afe_pack_and_set_param_in_band(SLIMBUS_5_TX, IDX_GLOBAL_CFG, + param_info, + (u8 *) &mad_enable_param); if (ret) pr_err("%s: AFE_PARAM_ID_HW_MAD_CTRL failed %d\n", __func__, ret); @@ -1693,31 +2013,19 @@ int afe_turn_onoff_hw_mad(u16 mad_type, u16 enable) static int afe_send_slimbus_slave_cfg( struct afe_param_cdc_slimbus_slave_cfg *sb_slave_cfg) { + struct param_hdr_v3 param_hdr; int ret; - struct afe_svc_cmd_sb_slave_cfg config; pr_debug("%s: enter\n", __func__); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = IDX_GLOBAL_CFG; - config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG; - config.pdata.param_id = AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG; - config.pdata.param_size = - sizeof(struct afe_param_cdc_slimbus_slave_cfg); - config.sb_slave_cfg = *sb_slave_cfg; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG; + param_hdr.param_size = sizeof(struct afe_param_cdc_slimbus_slave_cfg); + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + (u8 *) sb_slave_cfg); if (ret) pr_err("%s: AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG failed %d\n", __func__, ret); @@ -1729,29 +2037,17 @@ static int afe_send_slimbus_slave_cfg( static int afe_send_codec_reg_page_config( struct afe_param_cdc_reg_page_cfg *cdc_reg_page_cfg) { - struct afe_svc_cmd_cdc_reg_page_cfg config; + struct param_hdr_v3 param_hdr; int ret; - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = IDX_GLOBAL_CFG; - config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG; - config.pdata.param_id = AFE_PARAM_ID_CDC_REG_PAGE_CFG; - config.pdata.param_size = - sizeof(struct afe_param_cdc_reg_page_cfg); - config.cdc_reg_page_cfg = *cdc_reg_page_cfg; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CDC_REG_PAGE_CFG; + param_hdr.param_size = sizeof(struct afe_param_cdc_reg_page_cfg); + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + (u8 *) cdc_reg_page_cfg); if (ret) pr_err("%s: AFE_PARAM_ID_CDC_REG_PAGE_CFG failed %d\n", __func__, ret); @@ -1762,186 +2058,123 @@ static int afe_send_codec_reg_page_config( static int afe_send_codec_reg_config( struct afe_param_cdc_reg_cfg_data *cdc_reg_cfg) { - int i, j, ret = -EINVAL; - int pkt_size, payload_size, reg_per_pkt, num_pkts, num_regs; - struct afe_svc_cmd_cdc_reg_cfg *config; - struct afe_svc_cmd_set_param *param; + u8 *packed_param_data = NULL; + u32 packed_data_size = 0; + u32 single_param_size = 0; + u32 max_data_size = 0; + u32 max_single_param = 0; + struct param_hdr_v3 param_hdr; + int idx = 0; + int ret = -EINVAL; - reg_per_pkt = (APR_MAX_BUF - sizeof(*config)) / - sizeof(struct afe_param_cdc_reg_cfg_payload); - if (reg_per_pkt > 0) { - num_pkts = (cdc_reg_cfg->num_registers / reg_per_pkt) + - (cdc_reg_cfg->num_registers % reg_per_pkt == 0 ? 0 : 1); - } else { - pr_err("%s: Failed to build codec reg config APR packet\n", - __func__); - return -EINVAL; - } + memset(¶m_hdr, 0, sizeof(param_hdr)); + max_single_param = sizeof(struct param_hdr_v3) + + sizeof(struct afe_param_cdc_reg_cfg); + max_data_size = APR_MAX_BUF - sizeof(struct afe_svc_cmd_set_param_v2); + packed_param_data = kzalloc(max_data_size, GFP_KERNEL); + if (!packed_param_data) + return -ENOMEM; - for (j = 0; j < num_pkts; ++j) { - /* - * num_regs is set to reg_per_pkt on each pass through the loop - * except the last, when it is set to the number of registers - * remaining from the total - */ - num_regs = (j < (num_pkts - 1) ? reg_per_pkt : - cdc_reg_cfg->num_registers - (reg_per_pkt * j)); - payload_size = sizeof(struct afe_param_cdc_reg_cfg_payload) * - num_regs; - pkt_size = sizeof(*config) + payload_size; - pr_debug("%s: pkt_size %d, payload_size %d\n", __func__, - pkt_size, payload_size); - config = kzalloc(pkt_size, GFP_KERNEL); - if (!config) - return -ENOMEM; - - config->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - config->hdr.pkt_size = pkt_size; - config->hdr.src_port = 0; - config->hdr.dest_port = 0; - config->hdr.token = IDX_GLOBAL_CFG; - config->hdr.opcode = AFE_SVC_CMD_SET_PARAM; - - param = &config->param; - param->payload_size = payload_size; - param->payload_address_lsw = 0x00; - param->payload_address_msw = 0x00; - param->mem_map_handle = 0x00; - - for (i = 0; i < num_regs; i++) { - config->reg_data[i].common.module_id = - AFE_MODULE_CDC_DEV_CFG; - config->reg_data[i].common.param_id = - AFE_PARAM_ID_CDC_REG_CFG; - config->reg_data[i].common.param_size = - sizeof(config->reg_data[i].reg_cfg); - config->reg_data[i].reg_cfg = - cdc_reg_cfg->reg_data[i + (j * reg_per_pkt)]; + /* param_hdr is the same for all params sent, set once at top */ + param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CDC_REG_CFG; + param_hdr.param_size = sizeof(struct afe_param_cdc_reg_cfg); + + while (idx < cdc_reg_cfg->num_registers) { + memset(packed_param_data, 0, max_data_size); + packed_data_size = 0; + single_param_size = 0; + + while (packed_data_size + max_single_param < max_data_size && + idx < cdc_reg_cfg->num_registers) { + ret = q6common_pack_pp_params( + packed_param_data + packed_data_size, + ¶m_hdr, (u8 *) &cdc_reg_cfg->reg_data[idx], + &single_param_size); + if (ret) { + pr_err("%s: Failed to pack parameters with error %d\n", + __func__, ret); + goto done; + } + packed_data_size += single_param_size; + idx++; } - ret = afe_apr_send_pkt(config, &this_afe.wait[IDX_GLOBAL_CFG]); + ret = q6afe_svc_set_params(IDX_GLOBAL_CFG, NULL, + packed_param_data, packed_data_size); if (ret) { pr_err("%s: AFE_PARAM_ID_CDC_REG_CFG failed %d\n", __func__, ret); - kfree(config); break; } - kfree(config); } - +done: + kfree(packed_param_data); return ret; } static int afe_init_cdc_reg_config(void) { + struct param_hdr_v3 param_hdr; int ret; - struct afe_svc_cmd_init_cdc_reg_cfg config; pr_debug("%s: enter\n", __func__); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = IDX_GLOBAL_CFG; - config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; - - config.param.payload_size = sizeof(struct afe_port_param_data_v2); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - - config.init.module_id = AFE_MODULE_CDC_DEV_CFG; - config.init.param_id = AFE_PARAM_ID_CDC_REG_CFG_INIT; - config.init.param_size = 0; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); - if (ret) { + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CDC_REG_CFG_INIT; + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + NULL); + if (ret) pr_err("%s: AFE_PARAM_ID_CDC_INIT_REG_CFG failed %d\n", __func__, ret); - } return ret; } static int afe_send_slimbus_slave_port_cfg( - struct afe_param_slimbus_slave_port_cfg *port_config, u16 port_id) + struct afe_param_slimbus_slave_port_cfg *slim_slave_config, u16 port_id) { - int ret, index; - struct afe_cmd_hw_mad_slimbus_slave_port_cfg config; + struct param_hdr_v3 param_hdr; + int ret; pr_debug("%s: enter, port_id = 0x%x\n", __func__, port_id); - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(port_id); - if (ret < 0) { - pr_err("%s: port id = 0x%x ret %d\n", __func__, port_id, ret); - return -EINVAL; - } - - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = port_id; - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_HW_MAD; - config.pdata.param_id = AFE_PARAM_ID_SLIMBUS_SLAVE_PORT_CFG; - config.pdata.param_size = sizeof(*port_config); - config.sb_port_cfg = *port_config; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); - if (ret) { + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_HW_MAD; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.reserved = 0; + param_hdr.param_id = AFE_PARAM_ID_SLIMBUS_SLAVE_PORT_CFG; + param_hdr.param_size = sizeof(struct afe_param_slimbus_slave_port_cfg); + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) slim_slave_config); + if (ret) pr_err("%s: AFE_PARAM_ID_SLIMBUS_SLAVE_PORT_CFG failed %d\n", __func__, ret); - } + pr_debug("%s: leave %d\n", __func__, ret); return ret; } static int afe_aanc_port_cfg(void *apr, uint16_t tx_port, uint16_t rx_port) { - struct afe_port_cmd_set_aanc_param cfg; + struct afe_param_aanc_port_cfg aanc_port_cfg; + struct param_hdr_v3 param_hdr; int ret = 0; - int index = 0; pr_debug("%s: tx_port 0x%x, rx_port 0x%x\n", __func__, tx_port, rx_port); - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return -EINVAL; - } + pr_debug("%s: AANC sample rate tx rate: %d rx rate %d\n", __func__, + this_afe.aanc_info.aanc_tx_port_sample_rate, + this_afe.aanc_info.aanc_rx_port_sample_rate); + + memset(&aanc_port_cfg, 0, sizeof(aanc_port_cfg)); + memset(¶m_hdr, 0, sizeof(param_hdr)); - index = q6audio_get_port_index(tx_port); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(tx_port); - if (ret < 0) { - pr_err("%s: port id: 0x%x ret %d\n", __func__, tx_port, ret); - return -EINVAL; - } - pr_debug("%s: AANC sample rate tx rate: %d rx rate %d\n", - __func__, this_afe.aanc_info.aanc_tx_port_sample_rate, - this_afe.aanc_info.aanc_rx_port_sample_rate); /* * If aanc tx sample rate or rx sample rate is zero, skip aanc * configuration as AFE resampler will fail for invalid sample @@ -1952,177 +2185,107 @@ static int afe_aanc_port_cfg(void *apr, uint16_t tx_port, uint16_t rx_port) return -EINVAL; } - cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - cfg.hdr.pkt_size = sizeof(cfg); - cfg.hdr.src_port = 0; - cfg.hdr.dest_port = 0; - cfg.hdr.token = index; - cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - - cfg.param.port_id = tx_port; - cfg.param.payload_size = sizeof(struct afe_port_param_data_v2) + - sizeof(struct afe_param_aanc_port_cfg); - cfg.param.payload_address_lsw = 0; - cfg.param.payload_address_msw = 0; - cfg.param.mem_map_handle = 0; + param_hdr.module_id = AFE_MODULE_AANC; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_AANC_PORT_CONFIG; + param_hdr.param_size = sizeof(struct afe_param_aanc_port_cfg); - cfg.pdata.module_id = AFE_MODULE_AANC; - cfg.pdata.param_id = AFE_PARAM_ID_AANC_PORT_CONFIG; - cfg.pdata.param_size = sizeof(struct afe_param_aanc_port_cfg); - cfg.pdata.reserved = 0; - - cfg.data.aanc_port_cfg.aanc_port_cfg_minor_version = + aanc_port_cfg.aanc_port_cfg_minor_version = AFE_API_VERSION_AANC_PORT_CONFIG; - cfg.data.aanc_port_cfg.tx_port_sample_rate = + aanc_port_cfg.tx_port_sample_rate = this_afe.aanc_info.aanc_tx_port_sample_rate; - cfg.data.aanc_port_cfg.tx_port_channel_map[0] = AANC_TX_VOICE_MIC; - cfg.data.aanc_port_cfg.tx_port_channel_map[1] = AANC_TX_NOISE_MIC; - cfg.data.aanc_port_cfg.tx_port_channel_map[2] = AANC_TX_ERROR_MIC; - cfg.data.aanc_port_cfg.tx_port_channel_map[3] = AANC_TX_MIC_UNUSED; - cfg.data.aanc_port_cfg.tx_port_channel_map[4] = AANC_TX_MIC_UNUSED; - cfg.data.aanc_port_cfg.tx_port_channel_map[5] = AANC_TX_MIC_UNUSED; - cfg.data.aanc_port_cfg.tx_port_channel_map[6] = AANC_TX_MIC_UNUSED; - cfg.data.aanc_port_cfg.tx_port_channel_map[7] = AANC_TX_MIC_UNUSED; - cfg.data.aanc_port_cfg.tx_port_num_channels = 3; - cfg.data.aanc_port_cfg.rx_path_ref_port_id = rx_port; - cfg.data.aanc_port_cfg.ref_port_sample_rate = - this_afe.aanc_info.aanc_rx_port_sample_rate; - - ret = afe_apr_send_pkt((uint32_t *) &cfg, &this_afe.wait[index]); - if (ret) { + aanc_port_cfg.tx_port_channel_map[0] = AANC_TX_VOICE_MIC; + aanc_port_cfg.tx_port_channel_map[1] = AANC_TX_NOISE_MIC; + aanc_port_cfg.tx_port_channel_map[2] = AANC_TX_ERROR_MIC; + aanc_port_cfg.tx_port_channel_map[3] = AANC_TX_MIC_UNUSED; + aanc_port_cfg.tx_port_channel_map[4] = AANC_TX_MIC_UNUSED; + aanc_port_cfg.tx_port_channel_map[5] = AANC_TX_MIC_UNUSED; + aanc_port_cfg.tx_port_channel_map[6] = AANC_TX_MIC_UNUSED; + aanc_port_cfg.tx_port_channel_map[7] = AANC_TX_MIC_UNUSED; + aanc_port_cfg.tx_port_num_channels = 3; + aanc_port_cfg.rx_path_ref_port_id = rx_port; + aanc_port_cfg.ref_port_sample_rate = + this_afe.aanc_info.aanc_rx_port_sample_rate; + + ret = q6afe_pack_and_set_param_in_band(tx_port, + q6audio_get_port_index(tx_port), + param_hdr, + (u8 *) &aanc_port_cfg); + if (ret) pr_err("%s: AFE AANC port config failed for tx_port 0x%x, rx_port 0x%x ret %d\n", - __func__, tx_port, rx_port, ret); - } + __func__, tx_port, rx_port, ret); return ret; } static int afe_aanc_mod_enable(void *apr, uint16_t tx_port, uint16_t enable) { - struct afe_port_cmd_set_aanc_param cfg; + struct afe_mod_enable_param mod_enable; + struct param_hdr_v3 param_hdr; int ret = 0; - int index = 0; - - pr_debug("%s: tx_port 0x%x\n", - __func__, tx_port); - - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return -EINVAL; - } - - index = q6audio_get_port_index(tx_port); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(tx_port); - if (ret < 0) { - pr_err("%s: port id: 0x%x ret %d\n", __func__, tx_port, ret); - return -EINVAL; - } - - cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - cfg.hdr.pkt_size = sizeof(cfg); - cfg.hdr.src_port = 0; - cfg.hdr.dest_port = 0; - cfg.hdr.token = index; - cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - cfg.param.port_id = tx_port; - cfg.param.payload_size = sizeof(struct afe_port_param_data_v2) + - sizeof(struct afe_mod_enable_param); - cfg.param.payload_address_lsw = 0; - cfg.param.payload_address_lsw = 0; - cfg.param.mem_map_handle = 0; + pr_debug("%s: tx_port 0x%x\n", __func__, tx_port); - cfg.pdata.module_id = AFE_MODULE_AANC; - cfg.pdata.param_id = AFE_PARAM_ID_ENABLE; - cfg.pdata.param_size = sizeof(struct afe_mod_enable_param); - cfg.pdata.reserved = 0; + memset(&mod_enable, 0, sizeof(mod_enable)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_AANC; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_ENABLE; + param_hdr.param_size = sizeof(struct afe_mod_enable_param); - cfg.data.mod_enable.enable = enable; - cfg.data.mod_enable.reserved = 0; + mod_enable.enable = enable; + mod_enable.reserved = 0; - ret = afe_apr_send_pkt((uint32_t *) &cfg, &this_afe.wait[index]); - if (ret) { + ret = q6afe_pack_and_set_param_in_band(tx_port, + q6audio_get_port_index(tx_port), + param_hdr, (u8 *) &mod_enable); + if (ret) pr_err("%s: AFE AANC enable failed for tx_port 0x%x ret %d\n", __func__, tx_port, ret); - } return ret; } static int afe_send_bank_selection_clip( struct afe_param_id_clip_bank_sel *param) { + struct param_hdr_v3 param_hdr; int ret; - struct afe_svc_cmd_set_clip_bank_selection config; if (!param) { pr_err("%s: Invalid params", __func__); return -EINVAL; } - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = IDX_GLOBAL_CFG; - config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; - - config.param.payload_size = sizeof(struct afe_port_param_data_v2) + - sizeof(struct afe_param_id_clip_bank_sel); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - - config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG; - config.pdata.param_id = AFE_PARAM_ID_CLIP_BANK_SEL_CFG; - config.pdata.param_size = - sizeof(struct afe_param_id_clip_bank_sel); - config.bank_sel = *param; - ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); - if (ret) { + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CLIP_BANK_SEL_CFG; + param_hdr.param_size = sizeof(struct afe_param_id_clip_bank_sel); + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + (u8 *) param); + if (ret) pr_err("%s: AFE_PARAM_ID_CLIP_BANK_SEL_CFG failed %d\n", __func__, ret); - } return ret; } int afe_send_aanc_version( struct afe_param_id_cdc_aanc_version *version_cfg) { + struct param_hdr_v3 param_hdr; int ret; - struct afe_svc_cmd_cdc_aanc_version config; pr_debug("%s: enter\n", __func__); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = IDX_GLOBAL_CFG; - config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; - - config.param.payload_size = sizeof(struct afe_port_param_data_v2) + - sizeof(struct afe_param_id_cdc_aanc_version); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - - config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG; - config.pdata.param_id = AFE_PARAM_ID_CDC_AANC_VERSION; - config.pdata.param_size = - sizeof(struct afe_param_id_cdc_aanc_version); - config.version = *version_cfg; - ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); - if (ret) { + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CDC_AANC_VERSION; + param_hdr.param_size = sizeof(struct afe_param_id_cdc_aanc_version); + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + (u8 *) version_cfg); + if (ret) pr_err("%s: AFE_PARAM_ID_CDC_AANC_VERSION failed %d\n", __func__, ret); - } return ret; } @@ -2261,86 +2424,32 @@ bool afe_has_config(enum afe_config_type config) int afe_send_spdif_clk_cfg(struct afe_param_id_spdif_clk_cfg *cfg, u16 port_id) { - struct afe_spdif_clk_config_command clk_cfg; + struct afe_param_id_spdif_clk_cfg clk_cfg; + struct param_hdr_v3 param_hdr; int ret = 0; - int index = 0; if (!cfg) { pr_err("%s: Error, no configuration data\n", __func__); - ret = -EINVAL; - return ret; - } - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(port_id); - if (ret < 0) { - pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); return -EINVAL; } - ret = afe_q6_interface_prepare(); - if (ret) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return ret; - } - clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - clk_cfg.hdr.pkt_size = sizeof(clk_cfg); - clk_cfg.hdr.src_port = 0; - clk_cfg.hdr.dest_port = 0; - clk_cfg.hdr.token = index; - - clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - clk_cfg.param.port_id = q6audio_get_port_id(port_id); - clk_cfg.param.payload_address_lsw = 0x00; - clk_cfg.param.payload_address_msw = 0x00; - clk_cfg.param.mem_map_handle = 0x00; - clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - clk_cfg.pdata.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG; - clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); - clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) - - sizeof(clk_cfg.param); - clk_cfg.clk_cfg = *cfg; - - pr_debug("%s: Minor version = 0x%x clk val = %d\n" - "clk root = 0x%x\n port id = 0x%x\n", - __func__, cfg->clk_cfg_minor_version, - cfg->clk_value, cfg->clk_root, - q6audio_get_port_id(port_id)); + memset(&clk_cfg, 0, sizeof(clk_cfg)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG; + param_hdr.param_size = sizeof(struct afe_param_id_spdif_clk_cfg); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); - if (ret < 0) { + pr_debug("%s: Minor version = 0x%x clk val = %d clk root = 0x%x port id = 0x%x\n", + __func__, clk_cfg.clk_cfg_minor_version, clk_cfg.clk_value, + clk_cfg.clk_root, q6audio_get_port_id(port_id)); + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &clk_cfg); + if (ret < 0) pr_err("%s: AFE send clock config for port 0x%x failed ret = %d\n", __func__, port_id, ret); - ret = -EINVAL; - goto fail_cmd; - } - - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", - __func__); - ret = -EINVAL; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } - -fail_cmd: return ret; } @@ -2357,80 +2466,25 @@ int afe_send_spdif_clk_cfg(struct afe_param_id_spdif_clk_cfg *cfg, int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg *ch_status_cfg, u16 port_id) { - struct afe_spdif_chstatus_config_command ch_status; + struct param_hdr_v3 param_hdr; int ret = 0; - int index = 0; - if (!ch_status_cfg) { + if (!ch_status_cfg) pr_err("%s: Error, no configuration data\n", __func__); - ret = -EINVAL; - return ret; - } - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(port_id); - if (ret < 0) { - pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); - return -EINVAL; - } + return -EINVAL; - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return ret; - } - ch_status.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - ch_status.hdr.pkt_size = sizeof(ch_status_cfg); - ch_status.hdr.src_port = 0; - ch_status.hdr.dest_port = 0; - ch_status.hdr.token = index; - - ch_status.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - ch_status.param.port_id = q6audio_get_port_id(port_id); - ch_status.param.payload_address_lsw = 0x00; - ch_status.param.payload_address_msw = 0x00; - ch_status.param.mem_map_handle = 0x00; - ch_status.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - ch_status.pdata.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG; - ch_status.pdata.param_size = sizeof(ch_status.ch_status); - ch_status.param.payload_size = sizeof(ch_status) - - sizeof(struct apr_hdr) - sizeof(ch_status.param); - ch_status.ch_status = *ch_status_cfg; + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG; + param_hdr.param_size = sizeof(struct afe_param_id_spdif_ch_status_cfg); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &ch_status); - if (ret < 0) { + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) ch_status_cfg); + if (ret < 0) pr_err("%s: AFE send channel status for port 0x%x failed ret = %d\n", __func__, port_id, ret); - ret = -EINVAL; - goto fail_cmd; - } - - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", - __func__); - ret = -EINVAL; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } - -fail_cmd: return ret; } EXPORT_SYMBOL(afe_send_spdif_ch_status_cfg); @@ -2509,10 +2563,9 @@ static int afe_aanc_start(uint16_t tx_port_id, uint16_t rx_port_id) int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port, u32 rate) { - struct afe_audioif_config_command config; - int ret = 0; - int index = 0; + struct param_hdr_v3 param_hdr; uint16_t port_index; + int ret = 0; if (!spdif_port) { pr_err("%s: Error, no configuration data\n", __func__); @@ -2522,12 +2575,7 @@ int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port, pr_debug("%s: port id: 0x%x\n", __func__, port_id); - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } + memset(¶m_hdr, 0, sizeof(param_hdr)); ret = q6audio_validate_port(port_id); if (ret < 0) { pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); @@ -2537,24 +2585,14 @@ int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port, afe_send_cal(port_id); afe_send_hw_delay(port_id, rate); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - config.pdata.param_id = AFE_PARAM_ID_SPDIF_CONFIG; - config.pdata.param_size = sizeof(config.port); - config.port.spdif = spdif_port->cfg; - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SPDIF_CONFIG; + param_hdr.param_size = sizeof(struct afe_spdif_port_config); + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) spdif_port); if (ret) { pr_err("%s: AFE enable for port 0x%x failed ret = %d\n", __func__, port_id, ret); @@ -2587,9 +2625,8 @@ int afe_send_slot_mapping_cfg( struct afe_param_id_slot_mapping_cfg *slot_mapping_cfg, u16 port_id) { - struct afe_slot_mapping_config_command config; + struct param_hdr_v3 param_hdr; int ret = 0; - int index = 0; if (!slot_mapping_cfg) { pr_err("%s: Error, no configuration data\n", __func__); @@ -2598,67 +2635,19 @@ int afe_send_slot_mapping_cfg( pr_debug("%s: port id: 0x%x\n", __func__, port_id); - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(port_id); - if (ret < 0) { - pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); - return -EINVAL; - } - - memset(&config, 0, sizeof(config)); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - - sizeof(struct apr_hdr) - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_TDM; - config.pdata.param_id = AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG; - config.pdata.param_size = sizeof(config.slot_mapping); - config.slot_mapping = *slot_mapping_cfg; + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_TDM; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG; + param_hdr.param_size = sizeof(struct afe_param_id_slot_mapping_cfg); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config); - if (ret < 0) { + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) slot_mapping_cfg); + if (ret < 0) pr_err("%s: AFE send slot mapping for port 0x%x failed ret = %d\n", __func__, port_id, ret); - ret = -EINVAL; - goto fail_cmd; - } - - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", - __func__); - ret = -EINVAL; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } - -fail_cmd: return ret; } @@ -2666,9 +2655,8 @@ int afe_send_custom_tdm_header_cfg( struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header_cfg, u16 port_id) { - struct afe_custom_tdm_header_config_command config; + struct param_hdr_v3 param_hdr; int ret = 0; - int index = 0; if (!custom_tdm_header_cfg) { pr_err("%s: Error, no configuration data\n", __func__); @@ -2677,67 +2665,20 @@ int afe_send_custom_tdm_header_cfg( pr_debug("%s: port id: 0x%x\n", __func__, port_id); - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(port_id); - if (ret < 0) { - pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); - return -EINVAL; - } - - memset(&config, 0, sizeof(config)); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - - sizeof(struct apr_hdr) - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_TDM; - config.pdata.param_id = AFE_PARAM_ID_CUSTOM_TDM_HEADER_CONFIG; - config.pdata.param_size = sizeof(config.custom_tdm_header); - config.custom_tdm_header = *custom_tdm_header_cfg; - - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config); - if (ret < 0) { + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_TDM; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CUSTOM_TDM_HEADER_CONFIG; + param_hdr.param_size = + sizeof(struct afe_param_id_custom_tdm_header_cfg); + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) custom_tdm_header_cfg); + if (ret < 0) pr_err("%s: AFE send custom tdm header for port 0x%x failed ret = %d\n", __func__, port_id, ret); - ret = -EINVAL; - goto fail_cmd; - } - - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", - __func__); - ret = -EINVAL; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } - -fail_cmd: return ret; } @@ -2755,11 +2696,11 @@ int afe_send_custom_tdm_header_cfg( int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, u32 rate, u16 num_groups) { - struct afe_audioif_config_command config; - int ret = 0; + struct param_hdr_v3 param_hdr; int index = 0; uint16_t port_index = 0; enum afe_mad_type mad_type = MAD_HW_NONE; + int ret = 0; if (!tdm_port) { pr_err("%s: Error, no configuration data\n", __func__); @@ -2768,6 +2709,7 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, pr_debug("%s: port id: 0x%x\n", __func__, port_id); + memset(¶m_hdr, 0, sizeof(param_hdr)); index = q6audio_get_port_index(port_id); if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", @@ -2823,26 +2765,15 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, } } - memset(&config, 0, sizeof(config)); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - config.pdata.param_id = AFE_PARAM_ID_TDM_CONFIG; - config.pdata.param_size = sizeof(config.port); - config.port.tdm = tdm_port->tdm; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_TDM_CONFIG; + param_hdr.param_size = sizeof(struct afe_param_id_tdm_cfg); + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &tdm_port->tdm); if (ret) { pr_err("%s: AFE enable for port 0x%x failed ret = %d\n", __func__, port_id, ret); @@ -2913,61 +2844,48 @@ EXPORT_SYMBOL(afe_set_routing_callback); int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) { - struct afe_usb_audio_dev_param_command config; - int ret = 0, index = 0; + struct afe_param_id_usb_audio_dev_params usb_dev; + struct afe_param_id_usb_audio_dev_lpcm_fmt lpcm_fmt; + struct param_hdr_v3 param_hdr; + int ret = 0; if (!afe_config) { pr_err("%s: Error, no configuration data\n", __func__); ret = -EINVAL; goto exit; } - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid! for port ID 0x%x\n", - __func__, index, port_id); - ret = -EINVAL; - goto exit; - } - memset(&config, 0, sizeof(config)); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - config.pdata.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS; - config.pdata.param_size = sizeof(config.usb_dev); - config.usb_dev.cfg_minor_version = - AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG; - config.usb_dev.dev_token = afe_config->usb_audio.dev_token; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + + memset(&usb_dev, 0, sizeof(usb_dev)); + memset(&lpcm_fmt, 0, sizeof(lpcm_fmt)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + + param_hdr.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS; + param_hdr.param_size = sizeof(usb_dev); + usb_dev.cfg_minor_version = AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG; + usb_dev.dev_token = afe_config->usb_audio.dev_token; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &usb_dev); if (ret) { pr_err("%s: AFE device param cmd failed %d\n", __func__, ret); - ret = -EINVAL; goto exit; } - config.pdata.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_LPCM_FMT; - config.pdata.param_size = sizeof(config.lpcm_fmt); - config.lpcm_fmt.cfg_minor_version = - AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG; - config.lpcm_fmt.endian = afe_config->usb_audio.endian; + param_hdr.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_LPCM_FMT; + param_hdr.param_size = sizeof(lpcm_fmt); + lpcm_fmt.cfg_minor_version = AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG; + lpcm_fmt.endian = afe_config->usb_audio.endian; - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &lpcm_fmt); if (ret) { pr_err("%s: AFE device param cmd LPCM_FMT failed %d\n", __func__, ret); - ret = -EINVAL; goto exit; } @@ -2981,62 +2899,58 @@ static int q6afe_send_enc_config(u16 port_id, u16 afe_in_channels, u16 afe_in_bit_width, u32 scrambler_mode) { - struct afe_audioif_config_command config; - int index; + u32 enc_fmt; + struct afe_enc_cfg_blk_param_t enc_blk_param; + struct afe_param_id_aptx_sync_mode sync_mode_param; + struct avs_enc_packetizer_id_param_t enc_pkt_id_param; + struct avs_enc_set_scrambler_param_t enc_set_scrambler_param; + struct afe_port_media_type_t media_type; + struct param_hdr_v3 param_hdr; int ret; - int payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param) - sizeof(config.port); pr_debug("%s:update DSP for enc format = %d\n", __func__, format); + + memset(&enc_blk_param, 0, sizeof(enc_blk_param)); + memset(&sync_mode_param, 0, sizeof(sync_mode_param)); + memset(&enc_pkt_id_param, 0, sizeof(enc_pkt_id_param)); + memset(&enc_set_scrambler_param, 0, sizeof(enc_set_scrambler_param)); + memset(&media_type, 0, sizeof(media_type)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 && format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD && format != ASM_MEDIA_FMT_CELT && format != ASM_MEDIA_FMT_LDAC) { pr_err("%s:Unsuppported format Ignore AFE config\n", __func__); return 0; } - memset(&config, 0, sizeof(config)); - index = q6audio_get_port_index(port_id); - if (index < 0) { - pr_err("%s: Invalid index number: %d\n", __func__, index); - return -EINVAL; - } - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = payload_size + sizeof(config.port.enc_fmt); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_ID_ENCODER; - config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENC_FMT_ID; - config.pdata.param_size = sizeof(config.port.enc_fmt); - config.port.enc_fmt.fmt_id = format; - pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENC_FMT_ID payload: %d\n", - __func__, config.param.payload_size); - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + param_hdr.module_id = AFE_MODULE_ID_ENCODER; + param_hdr.instance_id = INSTANCE_ID_0; + + param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENC_FMT_ID; + param_hdr.param_size = sizeof(enc_fmt); + enc_fmt = format; + pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENC_FMT_ID payload\n", + __func__); + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &enc_fmt); if (ret) { pr_err("%s:unable to send AFE_ENCODER_PARAM_ID_ENC_FMT_ID", __func__); goto exit; } - config.param.payload_size = payload_size - + sizeof(config.port.enc_blk_param); - pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payload:%d\n", - __func__, config.param.payload_size); - config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK; - config.pdata.param_size = sizeof(config.port.enc_blk_param); - config.port.enc_blk_param.enc_cfg_blk_size = - sizeof(config.port.enc_blk_param.enc_blk_config); - config.port.enc_blk_param.enc_blk_config = *cfg; - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payloadn", + __func__); + param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK; + param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t); + enc_blk_param.enc_cfg_blk_size = sizeof(union afe_enc_config_data); + enc_blk_param.enc_blk_config = *cfg; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &enc_blk_param); if (ret) { pr_err("%s: AFE_ENCODER_PARAM_ID_ENC_CFG_BLK for port 0x%x failed %d\n", __func__, port_id, ret); @@ -3044,16 +2958,18 @@ static int q6afe_send_enc_config(u16 port_id, } if (format == ASM_MEDIA_FMT_APTX) { - config.param.payload_size = - payload_size + sizeof(config.port.sync_mode_param); pr_debug("%s: sending AFE_PARAM_ID_APTX_SYNC_MODE to DSP", __func__); - config.pdata.param_id = AFE_PARAM_ID_APTX_SYNC_MODE; - config.pdata.param_size = sizeof(config.port.sync_mode_param); - config.port.sync_mode_param.sync_mode = - config.port.enc_blk_param.enc_blk_config.aptx_config. + param_hdr.param_id = AFE_PARAM_ID_APTX_SYNC_MODE; + param_hdr.param_size = + sizeof(struct afe_param_id_aptx_sync_mode); + sync_mode_param.sync_mode = + enc_blk_param.enc_blk_config.aptx_config. aptx_v2_cfg.sync_mode; - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &sync_mode_param); if (ret) { pr_err("%s: AFE_PARAM_ID_APTX_SYNC_MODE for port 0x%x failed %d\n", __func__, port_id, ret); @@ -3061,67 +2977,57 @@ static int q6afe_send_enc_config(u16 port_id, } } - config.param.payload_size = - payload_size + sizeof(config.port.enc_pkt_id_param); - pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP payload = %d", - __func__, config.param.payload_size); - config.pdata.param_id = AFE_ENCODER_PARAM_ID_PACKETIZER_ID; - config.pdata.param_size = sizeof(config.port.enc_pkt_id_param); - config.port.enc_pkt_id_param.enc_packetizer_id = - AFE_MODULE_ID_PACKETIZER_COP; - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP\n", + __func__); + param_hdr.param_id = AFE_ENCODER_PARAM_ID_PACKETIZER_ID; + param_hdr.param_size = sizeof(struct avs_enc_packetizer_id_param_t); + enc_pkt_id_param.enc_packetizer_id = AFE_MODULE_ID_PACKETIZER_COP; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &enc_pkt_id_param); if (ret) { pr_err("%s: AFE_ENCODER_PARAM_ID_PACKETIZER for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } - config.param.payload_size = - payload_size + sizeof(config.port.enc_set_scrambler_param); - pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING mode= %d to DSP payload = %d\n", - __func__, scrambler_mode, config.param.payload_size); - config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING; - config.pdata.param_size = sizeof(config.port.enc_set_scrambler_param); - config.port.enc_set_scrambler_param.enable_scrambler = scrambler_mode; - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING mode= %d to DSP payload\n", + __func__, scrambler_mode); + param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING; + param_hdr.param_size = sizeof(struct avs_enc_set_scrambler_param_t); + enc_set_scrambler_param.enable_scrambler = scrambler_mode; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &enc_set_scrambler_param); if (ret) { pr_err("%s: AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } - config.param.payload_size = - payload_size + sizeof(config.port.media_type); - config.pdata.param_size = sizeof(config.port.media_type); - pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __func__); - config.pdata.module_id = AFE_MODULE_PORT; - config.pdata.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE; - config.port.media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE; - if (format == ASM_MEDIA_FMT_LDAC) { - config.port.media_type.sample_rate = - config.port.enc_blk_param.enc_blk_config.ldac_config. - custom_config.sample_rate; - } else { - config.port.media_type.sample_rate = - afe_config.slim_sch.sample_rate; - } - + param_hdr.module_id = AFE_MODULE_PORT; + param_hdr.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE; + param_hdr.param_size = sizeof(struct afe_port_media_type_t); + media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE; + media_type.sample_rate = afe_config.slim_sch.sample_rate; if (afe_in_bit_width) - config.port.media_type.bit_width = afe_in_bit_width; + media_type.bit_width = afe_in_bit_width; else - config.port.media_type.bit_width = - afe_config.slim_sch.bit_width; + media_type.bit_width = afe_config.slim_sch.bit_width; if (afe_in_channels) - config.port.media_type.num_channels = afe_in_channels; + media_type.num_channels = afe_in_channels; else - config.port.media_type.num_channels = - afe_config.slim_sch.num_channels; - config.port.media_type.data_format = AFE_PORT_DATA_FORMAT_PCM; - config.port.media_type.reserved = 0; + media_type.num_channels = afe_config.slim_sch.num_channels; + media_type.data_format = AFE_PORT_DATA_FORMAT_PCM; + media_type.reserved = 0; - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &media_type); if (ret) { pr_err("%s: AFE_API_VERSION_PORT_MEDIA_TYPE for port 0x%x failed %d\n", __func__, port_id, ret); @@ -3137,13 +3043,17 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, union afe_enc_config_data *cfg, u32 enc_format, u32 scrambler_mode) { - struct afe_audioif_config_command config; + union afe_port_config port_cfg; + struct param_hdr_v3 param_hdr; int ret = 0; int cfg_type; int index = 0; enum afe_mad_type mad_type; uint16_t port_index; + memset(¶m_hdr, 0, sizeof(param_hdr)); + memset(&port_cfg, 0, sizeof(port_cfg)); + if (!afe_config) { pr_err("%s: Error, no configuration data\n", __func__); ret = -EINVAL; @@ -3264,13 +3174,6 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, } } - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - switch (port_id) { case AFE_PORT_ID_PRIMARY_PCM_RX: case AFE_PORT_ID_PRIMARY_PCM_TX: @@ -3368,24 +3271,21 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, ret = -EINVAL; goto fail_cmd; } - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - config.pdata.param_id = cfg_type; - config.pdata.param_size = sizeof(config.port); - - config.port = *afe_config; + + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = cfg_type; + param_hdr.param_size = sizeof(union afe_port_config); + + port_cfg = *afe_config; if ((enc_format != ASM_MEDIA_FMT_NONE) && (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) { - config.port.slim_sch.data_format = - AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED; + port_cfg.slim_sch.data_format = + AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED; } - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &port_cfg); if (ret) { pr_err("%s: AFE enable for port 0x%x failed %d\n", __func__, port_id, ret); @@ -3778,11 +3678,16 @@ int afe_open(u16 port_id, union afe_port_config *afe_config, int rate) { struct afe_port_cmd_device_start start; - struct afe_audioif_config_command config; + union afe_port_config port_cfg; + struct param_hdr_v3 param_hdr; int ret = 0; int cfg_type; int index = 0; + memset(¶m_hdr, 0, sizeof(param_hdr)); + memset(&start, 0, sizeof(start)); + memset(&port_cfg, 0, sizeof(port_cfg)); + if (!afe_config) { pr_err("%s: Error, no configuration data\n", __func__); ret = -EINVAL; @@ -3837,12 +3742,6 @@ int afe_open(u16 port_id, } mutex_lock(&this_afe.afe_cmd_lock); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; switch (port_id) { case PRIMARY_I2S_RX: case PRIMARY_I2S_TX: @@ -3906,24 +3805,16 @@ int afe_open(u16 port_id, ret = -EINVAL; goto fail_cmd; } - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - config.pdata.param_id = cfg_type; - config.pdata.param_size = sizeof(config.port); - - config.port = *afe_config; - pr_debug("%s: param PL size=%d iparam_size[%d][%zd %zd %zd %zd] param_id[0x%x]\n", - __func__, config.param.payload_size, config.pdata.param_size, - sizeof(config), sizeof(config.param), sizeof(config.port), - sizeof(struct apr_hdr), config.pdata.param_id); - - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = cfg_type; + param_hdr.param_size = sizeof(union afe_port_config); + port_cfg = *afe_config; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &port_cfg); if (ret) { pr_err("%s: AFE enable for port 0x%x opcode[0x%x]failed %d\n", __func__, port_id, cfg_type, ret); @@ -3965,57 +3856,31 @@ EXPORT_SYMBOL(afe_open); */ int afe_loopback(u16 enable, u16 rx_port, u16 tx_port) { - struct afe_loopback_cfg_v1 lb_cmd; + struct afe_loopback_cfg_v1 lb_param; + struct param_hdr_v3 param_hdr; int ret = 0; - int index = 0; + + memset(&lb_param, 0, sizeof(lb_param)); + memset(¶m_hdr, 0, sizeof(param_hdr)); if (rx_port == MI2S_RX) rx_port = AFE_PORT_ID_PRIMARY_MI2S_RX; if (tx_port == MI2S_TX) tx_port = AFE_PORT_ID_PRIMARY_MI2S_TX; - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return ret; - } + param_hdr.module_id = AFE_MODULE_LOOPBACK; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG; + param_hdr.param_size = sizeof(struct afe_loopback_cfg_v1); - index = q6audio_get_port_index(rx_port); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(rx_port); - if (ret < 0) { - pr_err("%s: Invalid port 0x%x ret %d", __func__, rx_port, ret); - return -EINVAL; - } + lb_param.dst_port_id = rx_port; + lb_param.routing_mode = LB_MODE_DEFAULT; + lb_param.enable = (enable ? 1 : 0); + lb_param.loopback_cfg_minor_version = AFE_API_VERSION_LOOPBACK_CONFIG; - lb_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(20), APR_PKT_VER); - lb_cmd.hdr.pkt_size = sizeof(lb_cmd); - lb_cmd.hdr.src_port = 0; - lb_cmd.hdr.dest_port = 0; - lb_cmd.hdr.token = index; - lb_cmd.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - lb_cmd.param.port_id = tx_port; - lb_cmd.param.payload_size = (sizeof(lb_cmd) - sizeof(struct apr_hdr) - - sizeof(struct afe_port_cmd_set_param_v2)); - lb_cmd.param.payload_address_lsw = 0x00; - lb_cmd.param.payload_address_msw = 0x00; - lb_cmd.param.mem_map_handle = 0x00; - lb_cmd.pdata.module_id = AFE_MODULE_LOOPBACK; - lb_cmd.pdata.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG; - lb_cmd.pdata.param_size = lb_cmd.param.payload_size - - sizeof(struct afe_port_param_data_v2); - - lb_cmd.dst_port_id = rx_port; - lb_cmd.routing_mode = LB_MODE_DEFAULT; - lb_cmd.enable = (enable ? 1 : 0); - lb_cmd.loopback_cfg_minor_version = AFE_API_VERSION_LOOPBACK_CONFIG; - - ret = afe_apr_send_pkt(&lb_cmd, &this_afe.wait[index]); + ret = q6afe_pack_and_set_param_in_band(tx_port, + q6audio_get_port_index(tx_port), + param_hdr, (u8 *) &lb_param); if (ret) pr_err("%s: AFE loopback failed %d\n", __func__, ret); return ret; @@ -4034,8 +3899,11 @@ EXPORT_SYMBOL(afe_loopback); int afe_loopback_gain(u16 port_id, u16 volume) { struct afe_loopback_gain_per_path_param set_param; + struct param_hdr_v3 param_hdr; int ret = 0; - int index = 0; + + memset(&set_param, 0, sizeof(set_param)); + memset(¶m_hdr, 0, sizeof(param_hdr)); if (this_afe.apr == NULL) { this_afe.apr = apr_register("ADSP", "AFE", afe_callback, @@ -4056,18 +3924,6 @@ int afe_loopback_gain(u16 port_id, u16 volume) ret = -EINVAL; goto fail_cmd; } - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(port_id); - if (ret < 0) { - pr_err("%s: Invalid port 0x%x ret %d", - __func__, port_id, ret); - return -EINVAL; - } /* RX ports numbers are even .TX ports numbers are odd. */ if (port_id % 2 == 0) { @@ -4079,36 +3935,19 @@ int afe_loopback_gain(u16 port_id, u16 volume) pr_debug("%s: port 0x%x volume %d\n", __func__, port_id, volume); - set_param.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - set_param.hdr.pkt_size = sizeof(set_param); - set_param.hdr.src_port = 0; - set_param.hdr.dest_port = 0; - set_param.hdr.token = index; - set_param.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - - set_param.param.port_id = port_id; - set_param.param.payload_size = - (sizeof(struct afe_loopback_gain_per_path_param) - - sizeof(struct apr_hdr) - sizeof(struct afe_port_cmd_set_param_v2)); - set_param.param.payload_address_lsw = 0; - set_param.param.payload_address_msw = 0; - set_param.param.mem_map_handle = 0; - - set_param.pdata.module_id = AFE_MODULE_LOOPBACK; - set_param.pdata.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH; - set_param.pdata.param_size = - (set_param.param.payload_size - - sizeof(struct afe_port_param_data_v2)); + param_hdr.module_id = AFE_MODULE_LOOPBACK; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH; + param_hdr.param_size = sizeof(struct afe_loopback_gain_per_path_param); set_param.rx_port_id = port_id; set_param.gain = volume; - ret = afe_apr_send_pkt(&set_param, &this_afe.wait[index]); - if (ret) { + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &set_param); + if (ret) pr_err("%s: AFE param set failed for port 0x%x ret %d\n", __func__, port_id, ret); - goto fail_cmd; - } fail_cmd: return ret; @@ -4237,9 +4076,9 @@ int afe_pseudo_port_stop_nowait(u16 port_id) int afe_port_group_set_param(u16 group_id, union afe_port_group_config *afe_group_config) { - int ret; - struct afe_port_group_create config; + struct param_hdr_v3 param_hdr; int cfg_type; + int ret; if (!afe_group_config) { pr_err("%s: Error, no configuration data\n", __func__); @@ -4248,6 +4087,8 @@ int afe_port_group_set_param(u16 group_id, pr_debug("%s: group id: 0x%x\n", __func__, group_id); + memset(¶m_hdr, 0, sizeof(param_hdr)); + ret = afe_q6_interface_prepare(); if (ret != 0) { pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); @@ -4272,27 +4113,13 @@ int afe_port_group_set_param(u16 group_id, return -EINVAL; } - memset(&config, 0, sizeof(config)); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = IDX_GLOBAL_CFG; - config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; - - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_GROUP_DEVICE; - config.pdata.param_id = cfg_type; - config.pdata.param_size = sizeof(config.data); - config.data = *afe_group_config; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + param_hdr.module_id = AFE_MODULE_GROUP_DEVICE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = cfg_type; + param_hdr.param_size = sizeof(union afe_port_group_config); + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + (u8 *) afe_group_config); if (ret) pr_err("%s: AFE_PARAM_ID_GROUP_DEVICE_CFG failed %d\n", __func__, ret); @@ -4314,12 +4141,16 @@ int afe_port_group_enable(u16 group_id, union afe_port_group_config *afe_group_config, u16 enable) { + struct afe_group_device_enable group_enable; + struct param_hdr_v3 param_hdr; int ret; - struct afe_port_group_create config; pr_debug("%s: group id: 0x%x enable: %d\n", __func__, group_id, enable); + memset(&group_enable, 0, sizeof(group_enable)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + ret = afe_q6_interface_prepare(); if (ret != 0) { pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); @@ -4334,28 +4165,15 @@ int afe_port_group_enable(u16 group_id, } } - memset(&config, 0, sizeof(config)); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = IDX_GLOBAL_CFG; - config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; - - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_GROUP_DEVICE; - config.pdata.param_id = AFE_PARAM_ID_GROUP_DEVICE_ENABLE; - config.pdata.param_size = sizeof(config.data); - config.data.group_enable.group_id = group_id; - config.data.group_enable.enable = enable; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + param_hdr.module_id = AFE_MODULE_GROUP_DEVICE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_GROUP_DEVICE_ENABLE; + param_hdr.param_size = sizeof(struct afe_group_device_enable); + group_enable.group_id = group_id; + group_enable.enable = enable; + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + (u8 *) &group_enable); if (ret) pr_err("%s: AFE_PARAM_ID_GROUP_DEVICE_ENABLE failed %d\n", __func__, ret); @@ -5427,9 +5245,7 @@ EXPORT_SYMBOL(afe_dtmf_generate_rx); static int afe_sidetone_iir(u16 tx_port_id) { - struct afe_loopback_iir_cfg_v2 iir_sidetone; int ret; - int index = 0; uint16_t size = 0; int cal_index = AFE_SIDETONE_IIR_CAL; int iir_pregain = 0; @@ -5437,20 +5253,17 @@ static int afe_sidetone_iir(u16 tx_port_id) int iir_enable; struct cal_block_data *cal_block; int mid; - - memset(&iir_sidetone, 0, sizeof(iir_sidetone)); - index = q6audio_get_port_index(tx_port_id); - iir_sidetone.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - iir_sidetone.hdr.pkt_size = sizeof(iir_sidetone); - iir_sidetone.hdr.src_port = 0; - iir_sidetone.hdr.dest_port = 0; - iir_sidetone.hdr.token = index; - iir_sidetone.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - iir_sidetone.param.port_id = tx_port_id; - iir_sidetone.param.payload_address_lsw = 0x00; - iir_sidetone.param.payload_address_msw = 0x00; - iir_sidetone.param.mem_map_handle = 0x00; + struct afe_mod_enable_param enable; + struct afe_sidetone_iir_filter_config_params filter_data; + struct param_hdr_v3 param_hdr; + u8 *packed_param_data = NULL; + u32 packed_param_size = 0; + u32 single_param_size = 0; + struct audio_cal_info_sidetone_iir *st_iir_cal_info = NULL; + + memset(&enable, 0, sizeof(enable)); + memset(&filter_data, 0, sizeof(filter_data)); + memset(¶m_hdr, 0, sizeof(param_hdr)); if (this_afe.cal_data[cal_index] == NULL) { pr_err("%s: cal data is NULL\n", __func__); @@ -5466,14 +5279,13 @@ static int afe_sidetone_iir(u16 tx_port_id) goto done; } - iir_pregain = ((struct audio_cal_info_sidetone_iir *) - cal_block->cal_info)->pregain; - iir_enable = ((struct audio_cal_info_sidetone_iir *) - cal_block->cal_info)->iir_enable; - iir_num_biquad_stages = ((struct audio_cal_info_sidetone_iir *) - cal_block->cal_info)->num_biquad_stages; - mid = ((struct audio_cal_info_sidetone_iir *) - cal_block->cal_info)->mid; + /* Cache data from cal block while inside lock to reduce locked time */ + st_iir_cal_info = + (struct audio_cal_info_sidetone_iir *) cal_block->cal_info; + iir_pregain = st_iir_cal_info->pregain; + iir_enable = st_iir_cal_info->iir_enable; + iir_num_biquad_stages = st_iir_cal_info->num_biquad_stages; + mid = st_iir_cal_info->mid; /* * calculate the actual size of payload based on no of stages @@ -5489,80 +5301,102 @@ static int afe_sidetone_iir(u16 tx_port_id) pr_debug("%s: adding 2 to size:%d\n", __func__, size); size = size + 2; } - memcpy(&iir_sidetone.st_iir_filter_config_data.iir_config, - &((struct audio_cal_info_sidetone_iir *) - cal_block->cal_info)->iir_config, - sizeof(iir_sidetone.st_iir_filter_config_data.iir_config)); + memcpy(&filter_data.iir_config, &st_iir_cal_info->iir_config, size); mutex_unlock(&this_afe.cal_data[cal_index]->lock); - /* - * Calculate the payload size for setparams command - */ - iir_sidetone.param.payload_size = (sizeof(iir_sidetone) - - sizeof(struct apr_hdr) - - sizeof(struct afe_port_cmd_set_param_v2) - - (MAX_SIDETONE_IIR_DATA_SIZE - size)); - - pr_debug("%s: payload size :%d\n", __func__, - iir_sidetone.param.payload_size); + packed_param_size = + sizeof(param_hdr) * 2 + sizeof(enable) + sizeof(filter_data); + packed_param_data = kzalloc(packed_param_size, GFP_KERNEL); + if (!packed_param_data) + return -ENOMEM; + packed_param_size = 0; /* * Set IIR enable params */ - iir_sidetone.st_iir_enable_pdata.module_id = mid; - iir_sidetone.st_iir_enable_pdata.param_id = - AFE_PARAM_ID_ENABLE; - iir_sidetone.st_iir_enable_pdata.param_size = - sizeof(iir_sidetone.st_iir_mode_enable_data); - iir_sidetone.st_iir_mode_enable_data.enable = iir_enable; + param_hdr.module_id = mid; + param_hdr.param_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_ENABLE; + param_hdr.param_size = sizeof(enable); + enable.enable = iir_enable; + ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, + (u8 *) &enable, &single_param_size); + if (ret) { + pr_err("%s: Failed to pack param data, error %d\n", __func__, + ret); + goto done; + } + packed_param_size += single_param_size; /* * Set IIR filter config params */ - iir_sidetone.st_iir_filter_config_pdata.module_id = mid; - iir_sidetone.st_iir_filter_config_pdata.param_id = - AFE_PARAM_ID_SIDETONE_IIR_FILTER_CONFIG; - iir_sidetone.st_iir_filter_config_pdata.param_size = - sizeof(iir_sidetone.st_iir_filter_config_data.num_biquad_stages) - + - sizeof(iir_sidetone.st_iir_filter_config_data.pregain) + size; - iir_sidetone.st_iir_filter_config_pdata.reserved = 0; - iir_sidetone.st_iir_filter_config_data.num_biquad_stages = - iir_num_biquad_stages; - iir_sidetone.st_iir_filter_config_data.pregain = iir_pregain; + param_hdr.module_id = mid; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SIDETONE_IIR_FILTER_CONFIG; + param_hdr.param_size = sizeof(filter_data.num_biquad_stages) + + sizeof(filter_data.pregain) + size; + filter_data.num_biquad_stages = iir_num_biquad_stages; + filter_data.pregain = iir_pregain; + ret = q6common_pack_pp_params(packed_param_data + packed_param_size, + ¶m_hdr, (u8 *) &filter_data, + &single_param_size); + if (ret) { + pr_err("%s: Failed to pack param data, error %d\n", __func__, + ret); + goto done; + } + packed_param_size += single_param_size; + pr_debug("%s: tx(0x%x)mid(0x%x)iir_en(%d)stg(%d)gain(0x%x)size(%d)\n", - __func__, tx_port_id, mid, - iir_sidetone.st_iir_mode_enable_data.enable, - iir_sidetone.st_iir_filter_config_data.num_biquad_stages, - iir_sidetone.st_iir_filter_config_data.pregain, - iir_sidetone.st_iir_filter_config_pdata.param_size); - ret = afe_apr_send_pkt(&iir_sidetone, &this_afe.wait[index]); + __func__, tx_port_id, mid, enable.enable, + filter_data.num_biquad_stages, filter_data.pregain, + param_hdr.param_size); + + ret = q6afe_set_params(tx_port_id, q6audio_get_port_index(tx_port_id), + NULL, packed_param_data, packed_param_size); if (ret) pr_err("%s: AFE sidetone failed for tx_port(0x%x)\n", __func__, tx_port_id); done: + kfree(packed_param_data); return ret; - } static int afe_sidetone(u16 tx_port_id, u16 rx_port_id, bool enable) { - struct afe_st_loopback_cfg_v1 cmd_sidetone; int ret; - int index; int cal_index = AFE_SIDETONE_CAL; int sidetone_gain; int sidetone_enable; struct cal_block_data *cal_block; int mid = 0; + struct afe_loopback_sidetone_gain gain_data; + struct loopback_cfg_data cfg_data; + struct param_hdr_v3 param_hdr; + u8 *packed_param_data = NULL; + u32 packed_param_size = 0; + u32 single_param_size = 0; + struct audio_cal_info_sidetone *st_cal_info = NULL; - memset(&cmd_sidetone, 0, sizeof(cmd_sidetone)); if (this_afe.cal_data[cal_index] == NULL) { pr_err("%s: cal data is NULL\n", __func__); ret = -EINVAL; goto done; } + + memset(&gain_data, 0, sizeof(gain_data)); + memset(&cfg_data, 0, sizeof(cfg_data)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + packed_param_size = + sizeof(param_hdr) * 2 + sizeof(gain_data) + sizeof(cfg_data); + packed_param_data = kzalloc(packed_param_size, GFP_KERNEL); + if (!packed_param_data) + return -ENOMEM; + packed_param_size = 0; + mutex_lock(&this_afe.cal_data[cal_index]->lock); cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); if (cal_block == NULL) { @@ -5571,60 +5405,61 @@ static int afe_sidetone(u16 tx_port_id, u16 rx_port_id, bool enable) ret = -EINVAL; goto done; } - sidetone_gain = ((struct audio_cal_info_sidetone *) - cal_block->cal_info)->gain; - sidetone_enable = ((struct audio_cal_info_sidetone *) - cal_block->cal_info)->enable; - mid = ((struct audio_cal_info_sidetone *) - cal_block->cal_info)->mid; - mutex_unlock(&this_afe.cal_data[cal_index]->lock); - index = q6audio_get_port_index(tx_port_id); - cmd_sidetone.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - cmd_sidetone.hdr.pkt_size = sizeof(cmd_sidetone); - cmd_sidetone.hdr.src_port = 0; - cmd_sidetone.hdr.dest_port = 0; - cmd_sidetone.hdr.token = index; - cmd_sidetone.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - cmd_sidetone.param.port_id = tx_port_id; - cmd_sidetone.param.payload_size = (sizeof(cmd_sidetone) - - sizeof(struct apr_hdr) - - sizeof(struct afe_port_cmd_set_param_v2)); - cmd_sidetone.param.payload_address_lsw = 0x00; - cmd_sidetone.param.payload_address_msw = 0x00; - cmd_sidetone.param.mem_map_handle = 0x00; - cmd_sidetone.gain_pdata.module_id = AFE_MODULE_LOOPBACK; - cmd_sidetone.gain_pdata.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH; - /* - * size of actual payload only - */ - cmd_sidetone.gain_pdata.param_size = sizeof( - struct afe_loopback_sidetone_gain); - cmd_sidetone.gain_data.rx_port_id = rx_port_id; - cmd_sidetone.gain_data.gain = sidetone_gain; + /* Cache data from cal block while inside lock to reduce locked time */ + st_cal_info = (struct audio_cal_info_sidetone *) cal_block->cal_info; + sidetone_gain = st_cal_info->gain; + sidetone_enable = st_cal_info->enable; + mid = st_cal_info->mid; + mutex_unlock(&this_afe.cal_data[cal_index]->lock); - cmd_sidetone.cfg_pdata.module_id = AFE_MODULE_LOOPBACK; - cmd_sidetone.cfg_pdata.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG; - /* - * size of actual payload only - */ - cmd_sidetone.cfg_pdata.param_size = sizeof(struct loopback_cfg_data); - cmd_sidetone.cfg_data.loopback_cfg_minor_version = - AFE_API_VERSION_LOOPBACK_CONFIG; - cmd_sidetone.cfg_data.dst_port_id = rx_port_id; - cmd_sidetone.cfg_data.routing_mode = LB_MODE_SIDETONE; - cmd_sidetone.cfg_data.enable = enable; + /* Set gain data. */ + param_hdr.module_id = AFE_MODULE_LOOPBACK; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH; + param_hdr.param_size = sizeof(struct afe_loopback_sidetone_gain); + gain_data.rx_port_id = rx_port_id; + gain_data.gain = sidetone_gain; + ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, + (u8 *) &gain_data, &single_param_size); + if (ret) { + pr_err("%s: Failed to pack param data, error %d\n", __func__, + ret); + goto done; + } + packed_param_size += single_param_size; + + /* Set configuration data. */ + param_hdr.module_id = AFE_MODULE_LOOPBACK; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG; + param_hdr.param_size = sizeof(struct loopback_cfg_data); + cfg_data.loopback_cfg_minor_version = AFE_API_VERSION_LOOPBACK_CONFIG; + cfg_data.dst_port_id = rx_port_id; + cfg_data.routing_mode = LB_MODE_SIDETONE; + cfg_data.enable = enable; + ret = q6common_pack_pp_params(packed_param_data + packed_param_size, + ¶m_hdr, (u8 *) &cfg_data, + &single_param_size); + if (ret) { + pr_err("%s: Failed to pack param data, error %d\n", __func__, + ret); + goto done; + } + packed_param_size += single_param_size; pr_debug("%s rx(0x%x) tx(0x%x) enable(%d) mid(0x%x) gain(%d) sidetone_enable(%d)\n", __func__, rx_port_id, tx_port_id, enable, mid, sidetone_gain, sidetone_enable); - ret = afe_apr_send_pkt(&cmd_sidetone, &this_afe.wait[index]); + ret = q6afe_set_params(tx_port_id, q6audio_get_port_index(tx_port_id), + NULL, packed_param_data, packed_param_size); if (ret) pr_err("%s: AFE sidetone send failed for tx_port:%d rx_port:%d ret:%d\n", __func__, tx_port_id, rx_port_id, ret); + done: + kfree(packed_param_data); return ret; } @@ -6035,75 +5870,36 @@ EXPORT_SYMBOL(afe_close); int afe_set_digital_codec_core_clock(u16 port_id, struct afe_digital_clk_cfg *cfg) { - struct afe_lpass_digital_clk_config_command clk_cfg; - int index = 0; + struct afe_digital_clk_cfg clk_cfg; + struct param_hdr_v3 param_hdr; int ret = 0; if (!cfg) { pr_err("%s: clock cfg is NULL\n", __func__); - ret = -EINVAL; - return ret; - } - - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return ret; + return -EINVAL; } - clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - clk_cfg.hdr.pkt_size = sizeof(clk_cfg); - clk_cfg.hdr.src_port = 0; - clk_cfg.hdr.dest_port = 0; - clk_cfg.hdr.token = index; + memset(&clk_cfg, 0, sizeof(clk_cfg)); + memset(¶m_hdr, 0, sizeof(param_hdr)); - clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; /*default rx port is taken to enable the codec digital clock*/ - clk_cfg.param.port_id = q6audio_get_port_id(port_id); - clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) - - sizeof(clk_cfg.param); - clk_cfg.param.payload_address_lsw = 0x00; - clk_cfg.param.payload_address_msw = 0x00; - clk_cfg.param.mem_map_handle = 0x00; - clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - clk_cfg.pdata.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG; - clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); - clk_cfg.clk_cfg = *cfg; + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG; + param_hdr.param_size = sizeof(struct afe_digital_clk_cfg); + clk_cfg = *cfg; pr_debug("%s: Minor version =0x%x clk val = %d\n" "clk root = 0x%x resrv = 0x%x\n", - __func__, cfg->i2s_cfg_minor_version, - cfg->clk_val, cfg->clk_root, cfg->reserved); - - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); - if (ret < 0) { - pr_err("%s: AFE enable for port 0x%x ret %d\n", - __func__, port_id, ret); - ret = -EINVAL; - goto fail_cmd; - } + __func__, cfg->i2s_cfg_minor_version, cfg->clk_val, + cfg->clk_root, cfg->reserved); - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } - -fail_cmd: + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &clk_cfg); + if (ret < 0) + pr_err("%s: AFE enable for port 0x%x ret %d\n", __func__, + port_id, ret); return ret; } @@ -6117,21 +5913,18 @@ int afe_set_digital_codec_core_clock(u16 port_id, */ int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg) { - struct afe_lpass_clk_config_command clk_cfg; - int index = 0; + struct afe_clk_cfg clk_cfg; + struct param_hdr_v3 param_hdr; int ret = 0; if (!cfg) { pr_err("%s: clock cfg is NULL\n", __func__); - ret = -EINVAL; - return ret; - } - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); return -EINVAL; } + + memset(&clk_cfg, 0, sizeof(clk_cfg)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + ret = q6audio_is_digital_pcm_interface(port_id); if (ret < 0) { pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n", @@ -6139,31 +5932,12 @@ int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg) return -EINVAL; } - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return ret; - } - mutex_lock(&this_afe.afe_cmd_lock); - clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - clk_cfg.hdr.pkt_size = sizeof(clk_cfg); - clk_cfg.hdr.src_port = 0; - clk_cfg.hdr.dest_port = 0; - clk_cfg.hdr.token = index; - - clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - clk_cfg.param.port_id = q6audio_get_port_id(port_id); - clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) - - sizeof(clk_cfg.param); - clk_cfg.param.payload_address_lsw = 0x00; - clk_cfg.param.payload_address_msw = 0x00; - clk_cfg.param.mem_map_handle = 0x00; - clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - clk_cfg.pdata.param_id = AFE_PARAM_ID_LPAIF_CLK_CONFIG; - clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); - clk_cfg.clk_cfg = *cfg; + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_LPAIF_CLK_CONFIG; + param_hdr.param_size = sizeof(clk_cfg); + clk_cfg = *cfg; pr_debug("%s: Minor version =0x%x clk val1 = %d\n" "clk val2 = %d, clk src = 0x%x\n" @@ -6174,34 +5948,13 @@ int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg) cfg->clk_root, cfg->clk_set_mode, cfg->reserved, q6audio_get_port_id(port_id)); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); - if (ret < 0) { + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &clk_cfg); + if (ret < 0) pr_err("%s: AFE enable for port 0x%x ret %d\n", __func__, port_id, ret); - ret = -EINVAL; - goto fail_cmd; - } - - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } -fail_cmd: mutex_unlock(&this_afe.afe_cmd_lock); return ret; } @@ -6217,7 +5970,7 @@ EXPORT_SYMBOL(afe_set_lpass_clock); */ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg) { - struct afe_lpass_clk_config_command_v2 clk_cfg; + struct param_hdr_v3 param_hdr; int ret = 0; if (!cfg) { @@ -6231,6 +5984,8 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg) return -EINVAL; } + memset(¶m_hdr, 0, sizeof(param_hdr)); + ret = afe_q6_interface_prepare(); if (ret != 0) { pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); @@ -6238,23 +5993,10 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg) } mutex_lock(&this_afe.afe_cmd_lock); - clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - clk_cfg.hdr.pkt_size = sizeof(clk_cfg); - clk_cfg.hdr.src_port = 0; - clk_cfg.hdr.dest_port = 0; - clk_cfg.hdr.token = index; - - clk_cfg.hdr.opcode = AFE_SVC_CMD_SET_PARAM; - clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) - - sizeof(clk_cfg.param); - clk_cfg.param.payload_address_lsw = 0x00; - clk_cfg.param.payload_address_msw = 0x00; - clk_cfg.param.mem_map_handle = 0x00; - clk_cfg.pdata.module_id = AFE_MODULE_CLOCK_SET; - clk_cfg.pdata.param_id = AFE_PARAM_ID_CLOCK_SET; - clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); - clk_cfg.clk_cfg = *cfg; + param_hdr.module_id = AFE_MODULE_CLOCK_SET; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CLOCK_SET; + param_hdr.param_size = sizeof(struct afe_clk_set); pr_debug("%s: Minor version =0x%x clk id = %d\n" @@ -6264,34 +6006,12 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg) cfg->clk_id, cfg->clk_freq_in_hz, cfg->clk_attri, cfg->clk_root, cfg->enable); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); - if (ret < 0) { + ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr, + (u8 *) cfg); + if (ret < 0) pr_err("%s: AFE clk cfg failed with ret %d\n", __func__, ret); - ret = -EINVAL; - goto fail_cmd; - } - - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto fail_cmd; - } else { - /* set ret to 0 as no timeout happened */ - ret = 0; - } - if (atomic_read(&this_afe.status) != 0) { - pr_err("%s: config cmd failed\n", __func__); - ret = -EINVAL; - goto fail_cmd; - } -fail_cmd: mutex_unlock(&this_afe.afe_cmd_lock); return ret; } @@ -6335,21 +6055,18 @@ EXPORT_SYMBOL(afe_set_lpass_clock_v2); int afe_set_lpass_internal_digital_codec_clock(u16 port_id, struct afe_digital_clk_cfg *cfg) { - struct afe_lpass_digital_clk_config_command clk_cfg; - int index = 0; + struct afe_digital_clk_cfg clk_cfg; + struct param_hdr_v3 param_hdr; int ret = 0; if (!cfg) { pr_err("%s: clock cfg is NULL\n", __func__); - ret = -EINVAL; - return ret; - } - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); return -EINVAL; } + + memset(&clk_cfg, 0, sizeof(clk_cfg)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + ret = q6audio_is_digital_pcm_interface(port_id); if (ret < 0) { pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n", @@ -6357,30 +6074,11 @@ int afe_set_lpass_internal_digital_codec_clock(u16 port_id, return -EINVAL; } - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return ret; - } - - clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - clk_cfg.hdr.pkt_size = sizeof(clk_cfg); - clk_cfg.hdr.src_port = 0; - clk_cfg.hdr.dest_port = 0; - clk_cfg.hdr.token = index; - - clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - clk_cfg.param.port_id = q6audio_get_port_id(port_id); - clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) - - sizeof(clk_cfg.param); - clk_cfg.param.payload_address_lsw = 0x00; - clk_cfg.param.payload_address_msw = 0x00; - clk_cfg.param.mem_map_handle = 0x00; - clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - clk_cfg.pdata.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG; - clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); - clk_cfg.clk_cfg = *cfg; + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG; + param_hdr.param_size = sizeof(clk_cfg); + clk_cfg = *cfg; pr_debug("%s: Minor version =0x%x clk val = %d\n" "clk root = 0x%x resrv = 0x%x port id = 0x%x\n", @@ -6388,49 +6086,25 @@ int afe_set_lpass_internal_digital_codec_clock(u16 port_id, cfg->clk_val, cfg->clk_root, cfg->reserved, q6audio_get_port_id(port_id)); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); - if (ret < 0) { + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &clk_cfg); + if (ret < 0) pr_err("%s: AFE enable for port 0x0x%x ret %d\n", __func__, port_id, ret); - ret = -EINVAL; - goto fail_cmd; - } - - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } -fail_cmd: return ret; } int afe_enable_lpass_core_shared_clock(u16 port_id, u32 enable) { - struct afe_lpass_core_shared_clk_config_command clk_cfg; - int index = 0; + struct afe_param_id_lpass_core_shared_clk_cfg clk_cfg; + struct param_hdr_v3 param_hdr; int ret = 0; - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } + memset(&clk_cfg, 0, sizeof(clk_cfg)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + ret = q6audio_is_digital_pcm_interface(port_id); if (ret < 0) { pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n", @@ -6438,65 +6112,25 @@ int afe_enable_lpass_core_shared_clock(u16 port_id, u32 enable) return -EINVAL; } - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return ret; - } - mutex_lock(&this_afe.afe_cmd_lock); - clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - clk_cfg.hdr.pkt_size = sizeof(clk_cfg); - clk_cfg.hdr.src_port = 0; - clk_cfg.hdr.dest_port = 0; - clk_cfg.hdr.token = index; - - clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - clk_cfg.param.port_id = q6audio_get_port_id(port_id); - clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) - - sizeof(clk_cfg.param); - clk_cfg.param.payload_address_lsw = 0x00; - clk_cfg.param.payload_address_msw = 0x00; - clk_cfg.param.mem_map_handle = 0x00; - clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - clk_cfg.pdata.param_id = AFE_PARAM_ID_LPASS_CORE_SHARED_CLOCK_CONFIG; - clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); - clk_cfg.clk_cfg.lpass_core_shared_clk_cfg_minor_version = - AFE_API_VERSION_LPASS_CORE_SHARED_CLK_CONFIG; - clk_cfg.clk_cfg.enable = enable; + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_LPASS_CORE_SHARED_CLOCK_CONFIG; + param_hdr.param_size = sizeof(clk_cfg); + clk_cfg.lpass_core_shared_clk_cfg_minor_version = + AFE_API_VERSION_LPASS_CORE_SHARED_CLK_CONFIG; + clk_cfg.enable = enable; pr_debug("%s: port id = %d, enable = %d\n", __func__, q6audio_get_port_id(port_id), enable); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); - if (ret < 0) { + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &clk_cfg); + if (ret < 0) pr_err("%s: AFE enable for port 0x%x ret %d\n", __func__, port_id, ret); - ret = -EINVAL; - goto fail_cmd; - } - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } - -fail_cmd: mutex_unlock(&this_afe.afe_cmd_lock); return ret; } @@ -6519,7 +6153,7 @@ int q6afe_check_osr_clk_freq(u32 freq) case Q6AFE_LPASS_OSR_CLK_512_kHZ: break; default: - pr_err("%s: deafault freq 0x%x\n", + pr_err("%s: default freq 0x%x\n", __func__, freq); ret = -EINVAL; } @@ -6528,8 +6162,9 @@ int q6afe_check_osr_clk_freq(u32 freq) int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) { + struct param_hdr_v3 param_hdr; + int port = SLIMBUS_4_TX; int ret = -EINVAL; - int index = 0, port = SLIMBUS_4_TX; if (!th_vi) { pr_err("%s: Invalid params\n", __func__); @@ -6538,59 +6173,20 @@ int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) if (this_afe.vi_tx_port != -1) port = this_afe.vi_tx_port; - ret = q6audio_validate_port(port); - if (ret < 0) { - pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret); - goto done; - } - index = q6audio_get_port_index(port); - if (index < 0) { - pr_err("%s: invalid port 0x%x, index %d\n", - __func__, port, index); - ret = -EINVAL; - goto done; - } - th_vi->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - th_vi->hdr.pkt_size = sizeof(*th_vi); - th_vi->hdr.src_port = 0; - th_vi->hdr.dest_port = 0; - th_vi->hdr.token = index; - th_vi->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; - th_vi->get_param.mem_map_handle = 0; - th_vi->get_param.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; - th_vi->get_param.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS; - th_vi->get_param.payload_address_lsw = 0; - th_vi->get_param.payload_address_msw = 0; - th_vi->get_param.payload_size = sizeof(*th_vi) - - sizeof(th_vi->get_param) - sizeof(th_vi->hdr); - th_vi->get_param.port_id = q6audio_get_port_id(port); - th_vi->pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; - th_vi->pdata.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS; - th_vi->pdata.param_size = sizeof(th_vi->param); - atomic_set(&this_afe.status, 0); - atomic_set(&this_afe.state, 1); - ret = apr_send_pkt(this_afe.apr, (uint32_t *)th_vi); - if (ret < 0) { - pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", - __func__, port, th_vi->get_param.param_id, ret); - goto done; - } - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto done; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code(atomic_read(&this_afe.status)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS; + param_hdr.param_size = sizeof(struct afe_sp_th_vi_ftm_params); + + ret = q6afe_get_params(port, NULL, ¶m_hdr); + if (ret) { + pr_err("%s: Failed to get TH VI FTM data\n", __func__); goto done; } + + th_vi->pdata = param_hdr; memcpy(&th_vi->param, &this_afe.th_vi_resp.param, sizeof(this_afe.th_vi_resp.param)); pr_debug("%s: DC resistance %d %d temp %d %d status %d %d\n", @@ -6607,8 +6203,9 @@ int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) { + struct param_hdr_v3 param_hdr; + int port = SLIMBUS_4_TX; int ret = -EINVAL; - int index = 0, port = SLIMBUS_4_TX; if (!ex_vi) { pr_err("%s: Invalid params\n", __func__); @@ -6617,61 +6214,21 @@ int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) if (this_afe.vi_tx_port != -1) port = this_afe.vi_tx_port; - ret = q6audio_validate_port(port); - if (ret < 0) { - pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret); - goto done; - } + memset(¶m_hdr, 0, sizeof(param_hdr)); - index = q6audio_get_port_index(port); - if (index < 0) { - pr_err("%s: invalid index %d port 0x%x\n", __func__, - index, port); - ret = -EINVAL; - goto done; - } + param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS; + param_hdr.param_size = sizeof(struct afe_sp_ex_vi_ftm_params); - ex_vi->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - ex_vi->hdr.pkt_size = sizeof(*ex_vi); - ex_vi->hdr.src_port = 0; - ex_vi->hdr.dest_port = 0; - ex_vi->hdr.token = index; - ex_vi->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; - ex_vi->get_param.mem_map_handle = 0; - ex_vi->get_param.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; - ex_vi->get_param.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS; - ex_vi->get_param.payload_address_lsw = 0; - ex_vi->get_param.payload_address_msw = 0; - ex_vi->get_param.payload_size = sizeof(*ex_vi) - - sizeof(ex_vi->get_param) - sizeof(ex_vi->hdr); - ex_vi->get_param.port_id = q6audio_get_port_id(port); - ex_vi->pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; - ex_vi->pdata.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS; - ex_vi->pdata.param_size = sizeof(ex_vi->param); - atomic_set(&this_afe.status, 0); - atomic_set(&this_afe.state, 1); - ret = apr_send_pkt(this_afe.apr, (uint32_t *)ex_vi); + ret = q6afe_get_params(port, NULL, ¶m_hdr); if (ret < 0) { pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", - __func__, port, ex_vi->get_param.param_id, ret); - goto done; - } - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto done; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code(atomic_read(&this_afe.status)); + __func__, port, param_hdr.param_id, ret); goto done; } + + ex_vi->pdata = param_hdr; memcpy(&ex_vi->param, &this_afe.ex_vi_resp.param, sizeof(this_afe.ex_vi_resp.param)); pr_debug("%s: freq %d %d resistance %d %d qfactor %d %d state %d %d\n", @@ -6700,80 +6257,29 @@ int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats, u16 port) { + struct param_hdr_v3 param_hdr; int ret = -EINVAL; - int index = 0; - struct afe_av_dev_drift_get_param av_dev_drift; if (!timing_stats) { pr_err("%s: Invalid params\n", __func__); goto exit; } - ret = q6audio_validate_port(port); - if (ret < 0) { - pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret); - ret = -EINVAL; - goto exit; - } + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_DEV_TIMING_STATS; + param_hdr.param_size = sizeof(struct afe_param_id_dev_timing_stats); - index = q6audio_get_port_index(port); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: Invalid AFE port index[%d]\n", - __func__, index); - ret = -EINVAL; - goto exit; - } - - memset(&av_dev_drift, 0, sizeof(struct afe_av_dev_drift_get_param)); - - av_dev_drift.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - av_dev_drift.hdr.pkt_size = sizeof(av_dev_drift); - av_dev_drift.hdr.src_port = 0; - av_dev_drift.hdr.dest_port = 0; - av_dev_drift.hdr.token = index; - av_dev_drift.hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; - av_dev_drift.get_param.mem_map_handle = 0; - av_dev_drift.get_param.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - av_dev_drift.get_param.param_id = AFE_PARAM_ID_DEV_TIMING_STATS; - av_dev_drift.get_param.payload_address_lsw = 0; - av_dev_drift.get_param.payload_address_msw = 0; - av_dev_drift.get_param.payload_size = sizeof(av_dev_drift) - - sizeof(av_dev_drift.get_param) - sizeof(av_dev_drift.hdr); - av_dev_drift.get_param.port_id = q6audio_get_port_id(port); - av_dev_drift.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - av_dev_drift.pdata.param_id = AFE_PARAM_ID_DEV_TIMING_STATS; - av_dev_drift.pdata.param_size = sizeof(av_dev_drift.timing_stats); - atomic_set(&this_afe.status, 0); - atomic_set(&this_afe.state, 1); - ret = apr_send_pkt(this_afe.apr, (uint32_t *)&av_dev_drift); + ret = q6afe_get_params(port, NULL, ¶m_hdr); if (ret < 0) { pr_err("%s: get param port 0x%x param id[0x%x] failed %d\n", - __func__, port, av_dev_drift.get_param.param_id, ret); - goto exit; - } - - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto exit; - } - - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); + __func__, port, param_hdr.param_id, ret); goto exit; } memcpy(timing_stats, &this_afe.av_dev_drift_resp.timing_stats, - sizeof(this_afe.av_dev_drift_resp.timing_stats)); + param_hdr.param_size); ret = 0; exit: return ret; @@ -6782,8 +6288,9 @@ EXPORT_SYMBOL(afe_get_av_dev_drift); int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) { + struct param_hdr_v3 param_hdr; + int port = SLIMBUS_4_TX; int ret = -EINVAL; - int index = 0, port = SLIMBUS_4_TX; if (!calib_resp) { pr_err("%s: Invalid params\n", __func__); @@ -6792,60 +6299,16 @@ int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) if (this_afe.vi_tx_port != -1) port = this_afe.vi_tx_port; - ret = q6audio_validate_port(port); - if (ret < 0) { - pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret); - ret = -EINVAL; - goto fail_cmd; - } - index = q6audio_get_port_index(port); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - ret = -EINVAL; - goto fail_cmd; - } - calib_resp->hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - calib_resp->hdr.pkt_size = sizeof(*calib_resp); - calib_resp->hdr.src_port = 0; - calib_resp->hdr.dest_port = 0; - calib_resp->hdr.token = index; - calib_resp->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; - calib_resp->get_param.mem_map_handle = 0; - calib_resp->get_param.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2; - calib_resp->get_param.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2; - calib_resp->get_param.payload_address_lsw = 0; - calib_resp->get_param.payload_address_msw = 0; - calib_resp->get_param.payload_size = sizeof(*calib_resp) - - sizeof(calib_resp->get_param) - sizeof(calib_resp->hdr); - calib_resp->get_param.port_id = q6audio_get_port_id(port); - calib_resp->pdata.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2; - calib_resp->pdata.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2; - calib_resp->pdata.param_size = sizeof(calib_resp->res_cfg); - atomic_set(&this_afe.status, 0); - atomic_set(&this_afe.state, 1); - ret = apr_send_pkt(this_afe.apr, (uint32_t *)calib_resp); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2; + param_hdr.param_size = sizeof(struct afe_spkr_prot_get_vi_calib); + + ret = q6afe_get_params(port, NULL, ¶m_hdr); if (ret < 0) { pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", - __func__, port, calib_resp->get_param.param_id, ret); - goto fail_cmd; - } - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); + __func__, port, param_hdr.param_id, ret); goto fail_cmd; } memcpy(&calib_resp->res_cfg, &this_afe.calib_data.res_cfg, diff --git a/dsp/rtac.c b/dsp/rtac.c index 0785f5621f69..8f0db893d379 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -104,12 +104,12 @@ struct rtac_afe_user_data { uint32_t port_id; union { struct rtac_afe_set { - struct afe_port_cmd_set_param_v2 cmd; - struct afe_port_param_data_v2 data; + struct afe_rtac_set_param_v2 cmd; + struct param_hdr_v1 data; } rtac_afe_set; struct rtac_afe_get { - struct afe_port_cmd_get_param_v2 cmd; - struct afe_port_param_data_v2 data; + struct afe_rtac_get_param_v2 cmd; + struct param_hdr_v1 data; } rtac_afe_get; }; } __packed; @@ -1273,7 +1273,7 @@ static int send_rtac_afe_apr(void *buf, uint32_t opcode) goto err; } if (opcode == AFE_PORT_CMD_SET_PARAM_V2) { - struct afe_port_cmd_set_param_v2 *afe_set_apr_msg; + struct afe_rtac_set_param_v2 *afe_set_apr_msg; /* set data size to actual out of band payload size */ if (user_afe_buf.rtac_afe_set.cmd.payload_size > @@ -1286,11 +1286,12 @@ static int send_rtac_afe_apr(void *buf, uint32_t opcode) } /* Copy buffer to out-of-band payload */ - if (copy_from_user((void *) - rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr, - buf+offsetof(struct rtac_afe_user_data, - rtac_afe_set.data), - user_afe_buf.rtac_afe_set.cmd.payload_size)) { + if (copy_from_user( + (void *) rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr, + (void __user *) buf + + offsetof(struct rtac_afe_user_data, + rtac_afe_set.data), + user_afe_buf.rtac_afe_set.cmd.payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); result = -EINVAL; @@ -1298,14 +1299,14 @@ static int send_rtac_afe_apr(void *buf, uint32_t opcode) } /* Copy AFE APR Message */ - afe_set_apr_msg = (struct afe_port_cmd_set_param_v2 *) - ((u8 *)rtac_afe_buffer + - sizeof(struct apr_hdr)); - if (copy_from_user((void *) - afe_set_apr_msg, - buf + offsetof(struct rtac_afe_user_data, - rtac_afe_set.cmd), - sizeof(struct afe_port_cmd_set_param_v2))) { + afe_set_apr_msg = (struct afe_rtac_set_param_v2 + *) ((u8 *) rtac_afe_buffer + + sizeof(struct apr_hdr)); + if (copy_from_user((void *) afe_set_apr_msg, + (void __user *) buf + + offsetof(struct rtac_afe_user_data, + rtac_afe_set.cmd), + sizeof(struct afe_rtac_set_param_v2))) { pr_err("%s: Could not copy payload from user buffer\n", __func__); result = -EINVAL; @@ -1321,10 +1322,10 @@ static int send_rtac_afe_apr(void *buf, uint32_t opcode) rtac_cal[AFE_RTAC_CAL].map_data.map_handle; apr_msg_size = sizeof(struct apr_hdr) + - sizeof(struct afe_port_cmd_set_param_v2); + sizeof(struct afe_rtac_set_param_v2); } else { - struct afe_port_cmd_get_param_v2 *afe_get_apr_msg; + struct afe_rtac_get_param_v2 *afe_get_apr_msg; if (user_afe_buf.cmd_size > MAX_PAYLOAD_SIZE) { pr_err("%s: Invalid payload size = %d\n", @@ -1334,13 +1335,14 @@ static int send_rtac_afe_apr(void *buf, uint32_t opcode) } /* Copy buffer to in-band payload */ - afe_get_apr_msg = (struct afe_port_cmd_get_param_v2 *) - ((u8 *) rtac_afe_buffer + - sizeof(struct apr_hdr)); - if (copy_from_user((void *)afe_get_apr_msg, - buf+offsetof(struct rtac_afe_user_data, - rtac_afe_get.cmd), - sizeof(struct afe_port_cmd_get_param_v2))) { + afe_get_apr_msg = (struct afe_rtac_get_param_v2 + *) ((u8 *) rtac_afe_buffer + + sizeof(struct apr_hdr)); + if (copy_from_user((void *) afe_get_apr_msg, + (void __user *) buf + + offsetof(struct rtac_afe_user_data, + rtac_afe_get.cmd), + sizeof(struct afe_rtac_get_param_v2))) { pr_err("%s: Could not copy payload from user buffer\n", __func__); result = -EINVAL; @@ -1356,7 +1358,7 @@ static int send_rtac_afe_apr(void *buf, uint32_t opcode) rtac_cal[AFE_RTAC_CAL].map_data.map_handle; afe_get_apr_msg->payload_size -= sizeof(struct apr_hdr); apr_msg_size = sizeof(struct apr_hdr) + - sizeof(struct afe_port_cmd_get_param_v2); + sizeof(struct afe_rtac_get_param_v2); } fill_afe_apr_hdr((struct apr_hdr *) rtac_afe_buffer, @@ -1396,13 +1398,13 @@ static int send_rtac_afe_apr(void *buf, uint32_t opcode) } if (opcode == AFE_PORT_CMD_GET_PARAM_V2) { - struct afe_port_param_data_v2 *get_resp; + struct param_hdr_v1 *get_resp; - get_resp = (struct afe_port_param_data_v2 *) - rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr; + get_resp = (struct param_hdr_v1 *) rtac_cal[AFE_RTAC_CAL] + .cal_data.kvaddr; - bytes_returned = get_resp->param_size + - sizeof(struct afe_port_param_data_v2); + bytes_returned = + get_resp->param_size + sizeof(struct param_hdr_v1); if (bytes_returned > rtac_cal[AFE_RTAC_CAL]. map_data.map_size) { diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 9c7f39d13218..cbbed10df8f5 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1533,15 +1533,8 @@ struct afe_sidetone_iir_filter_config_params { #define AFE_MODULE_LOOPBACK 0x00010205 #define AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH 0x00010206 -/* Payload of the #AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH parameter, - * which gets/sets loopback gain of a port to an Rx port. - * The Tx port ID of the loopback is part of the set_param command. - */ - -/* Payload of the #AFE_PORT_CMD_SET_PARAM_V2 command's - * configuration/calibration settings for the AFE port. - */ -struct afe_port_cmd_set_param_v2 { +/* Used by RTAC */ +struct afe_rtac_set_param_v2 { u16 port_id; /* Port interface and direction (Rx or Tx) to start. */ @@ -1584,35 +1577,60 @@ u32 mem_map_handle; } __packed; #define AFE_PORT_CMD_SET_PARAM_V2 0x000100EF +struct afe_port_cmd_set_param_v2 { + /* APR Header */ + struct apr_hdr apr_hdr; -struct afe_port_param_data_v2 { - u32 module_id; -/* ID of the module to be configured. - * Supported values: Valid module ID - */ + /* Port interface and direction (Rx or Tx) to start. */ + u16 port_id; -u32 param_id; -/* ID of the parameter corresponding to the supported parameters - * for the module ID. - * Supported values: Valid parameter ID - */ + /* + * Actual size of the payload in bytes. + * This is used for parsing the parameter payload. + * Supported values: > 0 + */ + u16 payload_size; -u16 param_size; -/* Actual size of the data for the - * module_id/param_id pair. The size is a - * multiple of four bytes. - * Supported values: > 0 - */ + /* The header detailing the memory mapping for out of band. */ + struct mem_mapping_hdr mem_hdr; -u16 reserved; -/* This field must be set to zero. - */ + /* The parameter data to be filled when sent inband */ + u8 param_data[0]; +} __packed; + +#define AFE_PORT_CMD_SET_PARAM_V3 0x000100FA +struct afe_port_cmd_set_param_v3 { + /* APR Header */ + struct apr_hdr apr_hdr; + + /* Port ID of the AFE port to configure. Port interface and direction + * (Rx or Tx) to configure. An even number represents the Rx direction, + * and an odd number represents the Tx direction. + */ + u16 port_id; + + /* Reserved. This field must be set to zero. */ + u16 reserved; + + /* The memory mapping header to be used when sending outband */ + struct mem_mapping_hdr mem_hdr; + + /* The total size of the payload, including param_hdr_v3 */ + u32 payload_size; + + /* + * The parameter data to be filled when sent inband. + * Must include param_hdr packed correctly. + */ + u8 param_data[0]; } __packed; +/* Payload of the #AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH parameter, + * which gets/sets loopback gain of a port to an Rx port. + * The Tx port ID of the loopback is part of the set_param command. + */ + struct afe_loopback_gain_per_path_param { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; u16 rx_port_id; /* Rx port of the loopback. */ @@ -1648,9 +1666,6 @@ enum afe_loopback_routing_mode { * which enables/disables one AFE loopback. */ struct afe_loopback_cfg_v1 { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; u32 loopback_cfg_minor_version; /* Minor version used for tracking the version of the RMC module * configuration interface. @@ -1712,19 +1727,19 @@ struct loopback_cfg_data { struct afe_st_loopback_cfg_v1 { struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 gain_pdata; + struct mem_mapping_hdr mem_hdr; + struct param_hdr_v1 gain_pdata; struct afe_loopback_sidetone_gain gain_data; - struct afe_port_param_data_v2 cfg_pdata; + struct param_hdr_v1 cfg_pdata; struct loopback_cfg_data cfg_data; } __packed; struct afe_loopback_iir_cfg_v2 { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 st_iir_enable_pdata; - struct afe_mod_enable_param st_iir_mode_enable_data; - struct afe_port_param_data_v2 st_iir_filter_config_pdata; + struct apr_hdr hdr; + struct mem_mapping_hdr param; + struct param_hdr_v1 st_iir_enable_pdata; + struct afe_mod_enable_param st_iir_mode_enable_data; + struct param_hdr_v1 st_iir_filter_config_pdata; struct afe_sidetone_iir_filter_config_params st_iir_filter_config_data; } __packed; #define AFE_MODULE_SPEAKER_PROTECTION 0x00010209 @@ -2177,20 +2192,6 @@ struct afe_param_id_spdif_clk_cfg { */ } __packed; -struct afe_spdif_clk_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_param_id_spdif_clk_cfg clk_cfg; -} __packed; - -struct afe_spdif_chstatus_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_param_id_spdif_ch_status_cfg ch_status; -} __packed; - struct afe_spdif_port_config { struct afe_param_id_spdif_cfg cfg; struct afe_param_id_spdif_ch_status_cfg ch_status; @@ -2709,16 +2710,6 @@ struct afe_param_id_usb_audio_cfg { u32 endian; } __packed; -struct afe_usb_audio_dev_param_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - union { - struct afe_param_id_usb_audio_dev_params usb_dev; - struct afe_param_id_usb_audio_dev_lpcm_fmt lpcm_fmt; - }; -} __packed; - /* This param id is used to configure Real Time Proxy interface. */ #define AFE_PARAM_ID_RT_PROXY_CONFIG 0x00010213 @@ -3131,20 +3122,6 @@ struct afe_param_id_custom_tdm_header_cfg { */ } __packed; -struct afe_slot_mapping_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_param_id_slot_mapping_cfg slot_mapping; -} __packed; - -struct afe_custom_tdm_header_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_param_id_custom_tdm_header_cfg custom_tdm_header; -} __packed; - struct afe_tdm_port_config { struct afe_param_id_tdm_cfg tdm; struct afe_param_id_slot_mapping_cfg slot_mapping; @@ -3660,18 +3637,6 @@ union afe_port_config { struct avs_enc_set_scrambler_param_t enc_set_scrambler_param; } __packed; -struct afe_audioif_config_command_no_payload { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; -} __packed; - -struct afe_audioif_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - union afe_port_config port; -} __packed; - #define AFE_PORT_CMD_DEVICE_START 0x000100E5 /* Payload of the #AFE_PORT_CMD_DEVICE_START.*/ @@ -3833,13 +3798,8 @@ u32 mem_map_handle; */ } __packed; -#define AFE_PORT_CMD_GET_PARAM_V2 0x000100F0 - -/* Payload of the #AFE_PORT_CMD_GET_PARAM_V2 command, - * which queries for one post/preprocessing parameter of a - * stream. - */ -struct afe_port_cmd_get_param_v2 { +/* Used by RTAC */ +struct afe_rtac_get_param_v2 { u16 port_id; /* Port interface and direction (Rx or Tx) to start. */ @@ -3885,6 +3845,37 @@ struct afe_port_cmd_get_param_v2 { */ } __packed; +#define AFE_PORT_CMD_GET_PARAM_V2 0x000100F0 + +/* Payload of the #AFE_PORT_CMD_GET_PARAM_V2 command, + * which queries for one post/preprocessing parameter of a + * stream. + */ +struct afe_port_cmd_get_param_v2 { + struct apr_hdr apr_hdr; + + /* Port interface and direction (Rx or Tx) to start. */ + u16 port_id; + + /* Maximum data size of the parameter ID/module ID combination. + * This is a multiple of four bytes + * Supported values: > 0 + */ + u16 payload_size; + + /* The memory mapping header to be used when requesting outband */ + struct mem_mapping_hdr mem_hdr; + + /* The module ID of the parameter data requested */ + u32 module_id; + + /* The parameter ID of the parameter data requested */ + u32 param_id; + + /* The header information for the parameter data */ + struct param_hdr_v1 param_hdr; +} __packed; + #define AFE_PORT_CMDRSP_GET_PARAM_V2 0x00010106 /* Payload of the #AFE_PORT_CMDRSP_GET_PARAM_V2 message, which @@ -3900,6 +3891,41 @@ struct afe_port_cmd_get_param_v2 { struct afe_port_cmdrsp_get_param_v2 { u32 status; + struct param_hdr_v1 param_hdr; + u8 param_data[0]; +} __packed; + +#define AFE_PORT_CMD_GET_PARAM_V3 0x000100FB +struct afe_port_cmd_get_param_v3 { + /* APR Header */ + struct apr_hdr apr_hdr; + + /* Port ID of the AFE port to configure. Port interface and direction + * (Rx or Tx) to configure. An even number represents the Rx direction, + * and an odd number represents the Tx direction. + */ + u16 port_id; + + /* Reserved. This field must be set to zero. */ + u16 reserved; + + /* The memory mapping header to be used when requesting outband */ + struct mem_mapping_hdr mem_hdr; + + /* The header information for the parameter data */ + struct param_hdr_v3 param_hdr; +} __packed; + +#define AFE_PORT_CMDRSP_GET_PARAM_V3 0x00010108 +struct afe_port_cmdrsp_get_param_v3 { + /* The status of the command */ + uint32_t status; + + /* The header information for the parameter data */ + struct param_hdr_v3 param_hdr; + + /* The parameter data to be filled when sent inband */ + u8 param_data[0]; } __packed; #define AFE_PARAM_ID_LPASS_CORE_SHARED_CLOCK_CONFIG 0x0001028C @@ -3921,13 +3947,6 @@ struct afe_param_id_lpass_core_shared_clk_cfg { */ } __packed; -struct afe_lpass_core_shared_clk_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_param_id_lpass_core_shared_clk_cfg clk_cfg; -} __packed; - /* adsp_afe_service_commands.h */ #define ADSP_MEMORY_MAP_EBI_POOL 0 @@ -9206,15 +9225,13 @@ struct afe_sp_th_vi_ftm_params { } __packed; struct afe_sp_th_vi_get_param { - struct apr_hdr hdr; - struct afe_port_cmd_get_param_v2 get_param; - struct afe_port_param_data_v2 pdata; + struct param_hdr_v3 pdata; struct afe_sp_th_vi_ftm_params param; } __packed; struct afe_sp_th_vi_get_param_resp { uint32_t status; - struct afe_port_param_data_v2 pdata; + struct param_hdr_v3 pdata; struct afe_sp_th_vi_ftm_params param; } __packed; @@ -9280,15 +9297,13 @@ struct afe_sp_ex_vi_ftm_params { } __packed; struct afe_sp_ex_vi_get_param { - struct apr_hdr hdr; - struct afe_port_cmd_get_param_v2 get_param; - struct afe_port_param_data_v2 pdata; + struct param_hdr_v3 pdata; struct afe_sp_ex_vi_ftm_params param; } __packed; struct afe_sp_ex_vi_get_param_resp { uint32_t status; - struct afe_port_param_data_v2 pdata; + struct param_hdr_v3 pdata; struct afe_sp_ex_vi_ftm_params param; } __packed; @@ -9309,23 +9324,16 @@ union afe_spkr_prot_config { struct afe_sp_rx_limiter_th_param limiter_th_cfg; } __packed; -struct afe_spkr_prot_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - union afe_spkr_prot_config prot_config; -} __packed; - struct afe_spkr_prot_get_vi_calib { struct apr_hdr hdr; - struct afe_port_cmd_get_param_v2 get_param; - struct afe_port_param_data_v2 pdata; + struct mem_mapping_hdr mem_hdr; + struct param_hdr_v3 pdata; struct asm_calib_res_cfg res_cfg; } __packed; struct afe_spkr_prot_calib_get_resp { uint32_t status; - struct afe_port_param_data_v2 pdata; + struct param_hdr_v3 pdata; struct asm_calib_res_cfg res_cfg; } __packed; @@ -9619,6 +9627,7 @@ struct avcs_fwk_ver_info { /* Commands/Params to pass the codec/slimbus data to DSP */ #define AFE_SVC_CMD_SET_PARAM (0x000100f3) +#define AFE_SVC_CMD_SET_PARAM_V2 (0x000100fc) #define AFE_MODULE_CDC_DEV_CFG (0x00010234) #define AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG (0x00010235) #define AFE_PARAM_ID_CDC_REG_CFG (0x00010236) @@ -10018,13 +10027,6 @@ struct afe_clk_cfg { #define AFE_MODULE_CLOCK_SET 0x0001028F #define AFE_PARAM_ID_CLOCK_SET 0x00010290 -struct afe_lpass_clk_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_clk_cfg clk_cfg; -} __packed; - enum afe_lpass_digital_clk_src { Q6AFE_LPASS_DIGITAL_ROOT_INVALID, Q6AFE_LPASS_DIGITAL_ROOT_PRI_MI2S_OSR, @@ -10060,14 +10062,6 @@ struct afe_digital_clk_cfg { u16 reserved; } __packed; - -struct afe_lpass_digital_clk_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_digital_clk_cfg clk_cfg; -} __packed; - /* * Opcode for AFE to start DTMF. */ @@ -10176,107 +10170,43 @@ struct afe_param_cdc_reg_cfg_data { struct afe_param_cdc_reg_cfg *reg_data; } __packed; -struct afe_svc_cmd_set_param { - uint32_t payload_size; - uint32_t payload_address_lsw; - uint32_t payload_address_msw; - uint32_t mem_map_handle; -} __packed; - -struct afe_svc_param_data { - uint32_t module_id; - uint32_t param_id; - uint16_t param_size; - uint16_t reserved; -} __packed; - -struct afe_param_hw_mad_ctrl { - uint32_t minor_version; - uint16_t mad_type; - uint16_t mad_enable; -} __packed; - -struct afe_cmd_hw_mad_ctrl { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_param_hw_mad_ctrl payload; -} __packed; +struct afe_svc_cmd_set_param_v1 { + /* APR Header */ + struct apr_hdr apr_hdr; -struct afe_cmd_hw_mad_slimbus_slave_port_cfg { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_param_slimbus_slave_port_cfg sb_port_cfg; -} __packed; + /* The total size of the payload, including param_hdr_v3 */ + uint32_t payload_size; -struct afe_cmd_sw_mad_enable { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; -} __packed; + /* The memory mapping header to be used when sending outband */ + struct mem_mapping_hdr mem_hdr; -struct afe_param_cdc_reg_cfg_payload { - struct afe_svc_param_data common; - struct afe_param_cdc_reg_cfg reg_cfg; + /* The parameter data to be filled when sent inband */ + u32 param_data[0]; } __packed; -struct afe_lpass_clk_config_command_v2 { - struct apr_hdr hdr; - struct afe_svc_cmd_set_param param; - struct afe_svc_param_data pdata; - struct afe_clk_set clk_cfg; -} __packed; +struct afe_svc_cmd_set_param_v2 { + /* APR Header */ + struct apr_hdr apr_hdr; -/* - * reg_data's size can be up to AFE_MAX_CDC_REGISTERS_TO_CONFIG - */ -struct afe_svc_cmd_cdc_reg_cfg { - struct apr_hdr hdr; - struct afe_svc_cmd_set_param param; - struct afe_param_cdc_reg_cfg_payload reg_data[0]; -} __packed; + /* The memory mapping header to be used when sending outband */ + struct mem_mapping_hdr mem_hdr; -struct afe_svc_cmd_init_cdc_reg_cfg { - struct apr_hdr hdr; - struct afe_svc_cmd_set_param param; - struct afe_port_param_data_v2 init; -} __packed; + /* The total size of the payload, including param_hdr_v3 */ + u32 payload_size; -struct afe_svc_cmd_sb_slave_cfg { - struct apr_hdr hdr; - struct afe_svc_cmd_set_param param; - struct afe_port_param_data_v2 pdata; - struct afe_param_cdc_slimbus_slave_cfg sb_slave_cfg; + /* The parameter data to be filled when sent inband */ + u32 param_data[0]; } __packed; -struct afe_svc_cmd_cdc_reg_page_cfg { - struct apr_hdr hdr; - struct afe_svc_cmd_set_param param; - struct afe_port_param_data_v2 pdata; - struct afe_param_cdc_reg_page_cfg cdc_reg_page_cfg; -} __packed; - -struct afe_svc_cmd_cdc_aanc_version { - struct apr_hdr hdr; - struct afe_svc_cmd_set_param param; - struct afe_port_param_data_v2 pdata; - struct afe_param_id_cdc_aanc_version version; -} __packed; - -struct afe_port_cmd_set_aanc_param { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - union { - struct afe_param_aanc_port_cfg aanc_port_cfg; - struct afe_mod_enable_param mod_enable; - } __packed data; +struct afe_param_hw_mad_ctrl { + uint32_t minor_version; + uint16_t mad_type; + uint16_t mad_enable; } __packed; struct afe_port_cmd_set_aanc_acdb_table { struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; + struct mem_mapping_hdr mem_hdr; } __packed; /* Dolby DAP topology */ @@ -10299,13 +10229,6 @@ struct afe_port_cmd_set_aanc_acdb_table { #define Q14_GAIN_ZERO_POINT_FIVE 0x2000 #define Q14_GAIN_UNITY 0x4000 -struct afe_svc_cmd_set_clip_bank_selection { - struct apr_hdr hdr; - struct afe_svc_cmd_set_param param; - struct afe_port_param_data_v2 pdata; - struct afe_param_id_clip_bank_sel bank_sel; -} __packed; - /* Ultrasound supported formats */ #define US_POINT_EPOS_FORMAT_V2 0x0001272D #define US_RAW_FORMAT_V2 0x0001272C @@ -10532,13 +10455,6 @@ union afe_port_group_config { struct afe_param_id_group_device_tdm_cfg tdm_cfg; } __packed; -struct afe_port_group_create { - struct apr_hdr hdr; - struct afe_svc_cmd_set_param param; - struct afe_port_param_data_v2 pdata; - union afe_port_group_config data; -} __packed; - /* ID of the parameter used by #AFE_MODULE_AUDIO_DEV_INTERFACE to specify * the timing statistics of the corresponding device interface. * Client can periodically query for the device time statistics to help adjust @@ -10628,16 +10544,9 @@ struct afe_param_id_dev_timing_stats { u32 ref_timer_abs_ts_msw; } __packed; -struct afe_av_dev_drift_get_param { - struct apr_hdr hdr; - struct afe_port_cmd_get_param_v2 get_param; - struct afe_port_param_data_v2 pdata; - struct afe_param_id_dev_timing_stats timing_stats; -} __packed; - struct afe_av_dev_drift_get_param_resp { uint32_t status; - struct afe_port_param_data_v2 pdata; + struct param_hdr_v3 pdata; struct afe_param_id_dev_timing_stats timing_stats; } __packed; -- GitLab From 1ccc8752878b3a3382cd0454d669dac733832897 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Fri, 26 Jan 2018 14:24:39 -0800 Subject: [PATCH 0213/1645] ASoC: dsp: Update rtac driver to support Instance ID Add support to set and get rtac params with Instance ID support. Maintain support for non Instance ID set and get param structures as well. Use common pack and set param functions to set and get parameters to DSP instead of handling them at an individual module level. CRs-Fixed: 2151551 Change-Id: Ic96e83477e72dc5ffa4d87a1e98c34814bbd0b8d Signed-off-by: Vignesh Kulothungan --- dsp/q6asm.c | 20 +- dsp/q6voice.c | 10 +- dsp/rtac.c | 508 ++++++++++++++++++++++--------------- include/dsp/apr_audio-v2.h | 106 +++++--- 4 files changed, 395 insertions(+), 249 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 4f61fbec5df2..3bcf4f1cd05b 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -2005,10 +2005,10 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) break; } case ASM_STREAM_CMD_GET_PP_PARAMS_V2: - pr_debug("%s: ASM_STREAM_CMD_GET_PP_PARAMS_V2 session %d opcode 0x%x token 0x%x src %d dest %d\n", - __func__, ac->session, - data->opcode, data->token, - data->src_port, data->dest_port); + case ASM_STREAM_CMD_GET_PP_PARAMS_V3: + pr_debug("%s: ASM_STREAM_CMD_GET_PP_PARAMS session %d opcode 0x%x token 0x%x src %d dest %d\n", + __func__, ac->session, data->opcode, + data->token, data->src_port, data->dest_port); /* Should only come here if there is an APR */ /* error or malformed APR packet. Otherwise */ /* response will be returned as */ @@ -2085,13 +2085,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) break; } case ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2: - pr_debug("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 session %d opcode 0x%x token 0x%x src %d dest %d\n", - __func__, ac->session, data->opcode, - data->token, - data->src_port, data->dest_port); + case ASM_STREAM_CMDRSP_GET_PP_PARAMS_V3: + pr_debug("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS session %d opcode 0x%x token 0x%x src %d dest %d\n", + __func__, ac->session, data->opcode, data->token, + data->src_port, data->dest_port); if (payload[0] != 0) { - pr_err("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 returned error = 0x%x\n", - __func__, payload[0]); + pr_err("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS returned error = 0x%x\n", + __func__, payload[0]); } else if (generic_get_data) { generic_get_data->valid = 1; if (generic_get_data->is_inband) { diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 801e76168541..788805e0bdf5 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -7456,6 +7456,7 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv) data->payload_size); break; case VSS_ICOMMON_CMD_GET_PARAM_V2: + case VSS_ICOMMON_CMD_GET_PARAM_V3: pr_debug("%s: VSS_ICOMMON_CMD_GET_PARAM_V2\n", __func__); /* Should only come here if there is an APR */ @@ -7589,7 +7590,8 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv) pr_debug("Recd VSS_ISTREAM_EVT_NOT_READY\n"); } else if (data->opcode == VSS_ISTREAM_EVT_READY) { pr_debug("Recd VSS_ISTREAM_EVT_READY\n"); - } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM) { + } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM || + VSS_ICOMMON_RSP_GET_PARAM_V3) { pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__); ptr = data->payload; if (ptr[0] != 0) { @@ -7747,12 +7749,13 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv) data->payload_size); break; default: - pr_debug("%s: invalid token for command VSS_ICOMMON_CMD_SET_PARAM_V2: %d\n", + pr_debug("%s: invalid token for command VSS_ICOMMON_CMD_SET_PARAM: %d\n", __func__, data->token); break; } break; case VSS_ICOMMON_CMD_GET_PARAM_V2: + case VSS_ICOMMON_CMD_GET_PARAM_V3: pr_debug("%s: VSS_ICOMMON_CMD_GET_PARAM_V2\n", __func__); /* Should only come here if there is an APR */ @@ -7819,7 +7822,8 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv) break; } } - } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM) { + } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM || + VSS_ICOMMON_RSP_GET_PARAM_V3) { pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__); ptr = data->payload; if (ptr[0] != 0) { diff --git a/dsp/rtac.c b/dsp/rtac.c index 8f0db893d379..d23363597ea6 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "adsp_err.h" @@ -103,14 +104,10 @@ struct rtac_afe_user_data { uint32_t cmd_size; uint32_t port_id; union { - struct rtac_afe_set { - struct afe_rtac_set_param_v2 cmd; - struct param_hdr_v1 data; - } rtac_afe_set; - struct rtac_afe_get { - struct afe_rtac_get_param_v2 cmd; - struct param_hdr_v1 data; - } rtac_afe_get; + struct afe_rtac_user_data_set_v2 v2_set; + struct afe_rtac_user_data_set_v3 v3_set; + struct afe_rtac_user_data_get_v2 v2_get; + struct afe_rtac_user_data_get_v3 v3_get; }; } __packed; @@ -804,7 +801,9 @@ int send_adm_apr(void *buf, u32 opcode) goto err; } - if (opcode == ADM_CMD_SET_PP_PARAMS_V5) { + switch (opcode) { + case ADM_CMD_SET_PP_PARAMS_V5: + case ADM_CMD_SET_PP_PARAMS_V6: /* set payload size to in-band payload */ /* set data size to actual out of band payload size */ data_size = payload_size - 4 * sizeof(u32); @@ -822,12 +821,15 @@ int send_adm_apr(void *buf, u32 opcode) buf + 7 * sizeof(u32), data_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); - result = -EINVAL; + result = -EFAULT; goto err; } + /* set payload size in packet */ rtac_adm_buffer[8] = data_size; - } else { + break; + case ADM_CMD_GET_PP_PARAMS_V5: + case ADM_CMD_GET_PP_PARAMS_V6: if (payload_size > MAX_PAYLOAD_SIZE) { pr_err("%s: Invalid payload size = %d\n", __func__, payload_size); @@ -841,9 +843,14 @@ int send_adm_apr(void *buf, u32 opcode) buf + 3 * sizeof(u32), payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); - result = -EINVAL; + result = -EFAULT; goto err; } + break; + default: + pr_err("%s: Invalid opcode %d\n", __func__, opcode); + result = -EINVAL; + goto err; } /* Pack header */ @@ -904,33 +911,39 @@ int send_adm_apr(void *buf, u32 opcode) if (opcode == ADM_CMD_GET_PP_PARAMS_V5) { bytes_returned = ((u32 *)rtac_cal[ADM_RTAC_CAL].cal_data. kvaddr)[2] + 3 * sizeof(u32); + } else if (opcode == ADM_CMD_GET_PP_PARAMS_V6) { + bytes_returned = + ((u32 *) rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr)[3] + + 4 * sizeof(u32); + } else { + bytes_returned = data_size; + goto unlock; + } - if (bytes_returned > rtac_cal[ADM_RTAC_CAL]. - map_data.map_size) { - pr_err("%s: Invalid data size = %d\n", - __func__, bytes_returned); - result = -EINVAL; - goto err; - } + if (bytes_returned > rtac_cal[ADM_RTAC_CAL].map_data.map_size) { + pr_err("%s: Invalid data size = %d\n", __func__, + bytes_returned); + result = -EINVAL; + goto err; + } - if (bytes_returned > user_buf_size) { - pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n", - __func__, user_buf_size, bytes_returned); - result = -EINVAL; - goto err; - } + if (bytes_returned > user_buf_size) { + pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n", + __func__, user_buf_size, bytes_returned); + result = -EINVAL; + goto err; + } - if (copy_to_user(buf, (void *) - rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr, - bytes_returned)) { - pr_err("%s: Could not copy buffer to user,size = %d\n", - __func__, bytes_returned); - result = -EINVAL; - goto err; - } - } else { - bytes_returned = data_size; + if (copy_to_user((void __user *) buf, + rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr, + bytes_returned)) { + pr_err("%s: Could not copy buffer to user,size = %d\n", + __func__, bytes_returned); + result = -EFAULT; + goto err; } + +unlock: mutex_unlock(&rtac_adm_apr_mutex); done: return bytes_returned; @@ -1032,7 +1045,9 @@ int send_rtac_asm_apr(void *buf, u32 opcode) goto err; } - if (opcode == ASM_STREAM_CMD_SET_PP_PARAMS_V2) { + switch (opcode) { + case ASM_STREAM_CMD_SET_PP_PARAMS_V2: + case ASM_STREAM_CMD_SET_PP_PARAMS_V3: /* set payload size to in-band payload */ /* set data size to actual out of band payload size */ data_size = payload_size - 4 * sizeof(u32); @@ -1050,13 +1065,14 @@ int send_rtac_asm_apr(void *buf, u32 opcode) buf + 7 * sizeof(u32), data_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); - result = -EINVAL; + result = -EFAULT; goto err; } /* set payload size in packet */ rtac_asm_buffer[8] = data_size; - - } else { + break; + case ASM_STREAM_CMD_GET_PP_PARAMS_V2: + case ASM_STREAM_CMD_GET_PP_PARAMS_V3: if (payload_size > MAX_PAYLOAD_SIZE) { pr_err("%s: Invalid payload size = %d\n", __func__, payload_size); @@ -1070,9 +1086,15 @@ int send_rtac_asm_apr(void *buf, u32 opcode) buf + 3 * sizeof(u32), payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); - result = -EINVAL; + result = -EFAULT; goto err; } + + break; + default: + pr_err("%s: Invalid opcode %d\n", __func__, opcode); + result = -EINVAL; + goto err; } /* Pack header */ @@ -1135,33 +1157,39 @@ int send_rtac_asm_apr(void *buf, u32 opcode) if (opcode == ASM_STREAM_CMD_GET_PP_PARAMS_V2) { bytes_returned = ((u32 *)rtac_cal[ASM_RTAC_CAL].cal_data. kvaddr)[2] + 3 * sizeof(u32); + } else if (opcode == ASM_STREAM_CMD_GET_PP_PARAMS_V3) { + bytes_returned = + ((u32 *) rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr)[3] + + 4 * sizeof(u32); + } else { + bytes_returned = data_size; + goto unlock; + } - if (bytes_returned > rtac_cal[ASM_RTAC_CAL]. - map_data.map_size) { - pr_err("%s: Invalid data size = %d\n", - __func__, bytes_returned); - result = -EINVAL; - goto err; - } + if (bytes_returned > rtac_cal[ASM_RTAC_CAL].map_data.map_size) { + pr_err("%s: Invalid data size = %d\n", __func__, + bytes_returned); + result = -EINVAL; + goto err; + } - if (bytes_returned > user_buf_size) { - pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n", - __func__, user_buf_size, bytes_returned); - result = -EINVAL; - goto err; - } + if (bytes_returned > user_buf_size) { + pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n", + __func__, user_buf_size, bytes_returned); + result = -EINVAL; + goto err; + } - if (copy_to_user(buf, (void *) - rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr, - bytes_returned)) { - pr_err("%s: Could not copy buffer to user,size = %d\n", - __func__, bytes_returned); - result = -EINVAL; - goto err; - } - } else { - bytes_returned = data_size; + if (copy_to_user((void __user *) buf, + rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr, + bytes_returned)) { + pr_err("%s: Could not copy buffer to user,size = %d\n", + __func__, bytes_returned); + result = -EFAULT; + goto err; } + +unlock: mutex_unlock(&rtac_asm_apr_mutex); done: return bytes_returned; @@ -1218,13 +1246,18 @@ static int fill_afe_apr_hdr(struct apr_hdr *apr_hdr, uint32_t port, return 0; } -static int send_rtac_afe_apr(void *buf, uint32_t opcode) +static int send_rtac_afe_apr(void __user *buf, uint32_t opcode) { int32_t result; uint32_t bytes_returned = 0; + uint32_t payload_size = 0; uint32_t port_index = 0; + uint32_t *afe_cmd = NULL; uint32_t apr_msg_size = 0; struct rtac_afe_user_data user_afe_buf; + struct mem_mapping_hdr *mem_hdr = NULL; + struct param_hdr_v1 *get_resp_v2; + struct param_hdr_v3 *get_resp_v3; pr_debug("%s\n", __func__); @@ -1272,95 +1305,126 @@ static int send_rtac_afe_apr(void *buf, uint32_t opcode) result = -EINVAL; goto err; } - if (opcode == AFE_PORT_CMD_SET_PARAM_V2) { - struct afe_rtac_set_param_v2 *afe_set_apr_msg; - /* set data size to actual out of band payload size */ - if (user_afe_buf.rtac_afe_set.cmd.payload_size > - rtac_cal[AFE_RTAC_CAL].map_data.map_size) { - pr_err("%s: Invalid data size = %d\n", - __func__, - user_afe_buf.rtac_afe_set.cmd.payload_size); + afe_cmd = + (u32 *) rtac_afe_buffer + sizeof(struct apr_hdr) / sizeof(u32); + + switch (opcode) { + case AFE_PORT_CMD_SET_PARAM_V2: + apr_msg_size = sizeof(struct afe_port_cmd_set_param_v2); + payload_size = user_afe_buf.v2_set.payload_size; + if (payload_size > rtac_cal[AFE_RTAC_CAL].map_data.map_size) { + pr_err("%s: Invalid payload size = %d\n", __func__, + payload_size); result = -EINVAL; goto err; } - /* Copy buffer to out-of-band payload */ - if (copy_from_user( - (void *) rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr, - (void __user *) buf + - offsetof(struct rtac_afe_user_data, - rtac_afe_set.data), - user_afe_buf.rtac_afe_set.cmd.payload_size)) { + /* Copy the command to the rtac buffer */ + memcpy(afe_cmd, &user_afe_buf.v2_set, + sizeof(user_afe_buf.v2_set)); + + /* Copy the param data to the out-of-band location */ + if (copy_from_user(rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr, + (void __user *) buf + + offsetof(struct rtac_afe_user_data, + v2_set.param_hdr), + payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); + result = -EFAULT; + goto err; + } + break; + case AFE_PORT_CMD_SET_PARAM_V3: + apr_msg_size = sizeof(struct afe_port_cmd_set_param_v3); + payload_size = user_afe_buf.v3_set.payload_size; + if (payload_size > rtac_cal[AFE_RTAC_CAL].map_data.map_size) { + pr_err("%s: Invalid payload size = %d\n", __func__, + payload_size); result = -EINVAL; goto err; } - /* Copy AFE APR Message */ - afe_set_apr_msg = (struct afe_rtac_set_param_v2 - *) ((u8 *) rtac_afe_buffer + - sizeof(struct apr_hdr)); - if (copy_from_user((void *) afe_set_apr_msg, + /* Copy the command to the rtac buffer */ + memcpy(afe_cmd, &user_afe_buf.v3_set, + sizeof(user_afe_buf.v3_set)); + + /* Copy the param data to the out-of-band location */ + if (copy_from_user(rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr, (void __user *) buf + offsetof(struct rtac_afe_user_data, - rtac_afe_set.cmd), - sizeof(struct afe_rtac_set_param_v2))) { + v3_get.param_hdr), + payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); - result = -EINVAL; + result = -EFAULT; goto err; } + break; + case AFE_PORT_CMD_GET_PARAM_V2: + apr_msg_size = sizeof(struct afe_port_cmd_get_param_v2); - afe_set_apr_msg->payload_address_lsw = - lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr); - afe_set_apr_msg->payload_address_msw = - msm_audio_populate_upper_32_bits( - rtac_cal[AFE_RTAC_CAL].cal_data.paddr); - afe_set_apr_msg->mem_map_handle = - rtac_cal[AFE_RTAC_CAL].map_data.map_handle; - - apr_msg_size = sizeof(struct apr_hdr) + - sizeof(struct afe_rtac_set_param_v2); + if (user_afe_buf.cmd_size > MAX_PAYLOAD_SIZE) { + pr_err("%s: Invalid payload size = %d\n", __func__, + user_afe_buf.cmd_size); + result = -EINVAL; + goto err; + } - } else { - struct afe_rtac_get_param_v2 *afe_get_apr_msg; + /* Copy the command and param data in-band */ + if (copy_from_user(afe_cmd, + (void __user *) buf + + offsetof(struct rtac_afe_user_data, + v2_get), + user_afe_buf.cmd_size)) { + pr_err("%s: Could not copy payload from user buffer\n", + __func__); + result = -EFAULT; + goto err; + } + break; + case AFE_PORT_CMD_GET_PARAM_V3: + apr_msg_size = sizeof(struct afe_port_cmd_get_param_v3); if (user_afe_buf.cmd_size > MAX_PAYLOAD_SIZE) { - pr_err("%s: Invalid payload size = %d\n", - __func__, user_afe_buf.cmd_size); + pr_err("%s: Invalid payload size = %d\n", __func__, + user_afe_buf.cmd_size); result = -EINVAL; goto err; } - /* Copy buffer to in-band payload */ - afe_get_apr_msg = (struct afe_rtac_get_param_v2 - *) ((u8 *) rtac_afe_buffer + - sizeof(struct apr_hdr)); - if (copy_from_user((void *) afe_get_apr_msg, + /* Copy the command and param data in-band */ + if (copy_from_user(afe_cmd, (void __user *) buf + offsetof(struct rtac_afe_user_data, - rtac_afe_get.cmd), - sizeof(struct afe_rtac_get_param_v2))) { + v3_get), + user_afe_buf.cmd_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); - result = -EINVAL; + result = -EFAULT; goto err; } - - afe_get_apr_msg->payload_address_lsw = - lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr); - afe_get_apr_msg->payload_address_msw = - msm_audio_populate_upper_32_bits( - rtac_cal[AFE_RTAC_CAL].cal_data.paddr); - afe_get_apr_msg->mem_map_handle = - rtac_cal[AFE_RTAC_CAL].map_data.map_handle; - afe_get_apr_msg->payload_size -= sizeof(struct apr_hdr); - apr_msg_size = sizeof(struct apr_hdr) + - sizeof(struct afe_rtac_get_param_v2); + break; + default: + pr_err("%s: Invalid opcode %d\n", __func__, opcode); + result = -EINVAL; + goto err; } + /* + * The memory header is in the same location in all commands. Therefore, + * it doesn't matter what command the buffer is cast into. + */ + mem_hdr = &((struct afe_port_cmd_set_param_v3 *) rtac_afe_buffer) + ->mem_hdr; + mem_hdr->data_payload_addr_lsw = + lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr); + mem_hdr->data_payload_addr_msw = msm_audio_populate_upper_32_bits( + rtac_cal[AFE_RTAC_CAL].cal_data.paddr); + mem_hdr->mem_map_handle = rtac_cal[AFE_RTAC_CAL].map_data.map_handle; + + /* Fill the APR header at the end so we have the correct message size */ fill_afe_apr_hdr((struct apr_hdr *) rtac_afe_buffer, port_index, opcode, apr_msg_size); @@ -1398,41 +1462,44 @@ static int send_rtac_afe_apr(void *buf, uint32_t opcode) } if (opcode == AFE_PORT_CMD_GET_PARAM_V2) { - struct param_hdr_v1 *get_resp; - - get_resp = (struct param_hdr_v1 *) rtac_cal[AFE_RTAC_CAL] - .cal_data.kvaddr; - + get_resp_v2 = (struct param_hdr_v1 *) rtac_cal[AFE_RTAC_CAL] + .cal_data.kvaddr; bytes_returned = - get_resp->param_size + sizeof(struct param_hdr_v1); + get_resp_v2->param_size + sizeof(struct param_hdr_v1); + } else if (opcode == AFE_PORT_CMD_GET_PARAM_V3) { + get_resp_v3 = (struct param_hdr_v3 *) rtac_cal[AFE_RTAC_CAL] + .cal_data.kvaddr; + bytes_returned = + get_resp_v3->param_size + sizeof(struct param_hdr_v3); + } else { + bytes_returned = payload_size; + goto unlock; + } - if (bytes_returned > rtac_cal[AFE_RTAC_CAL]. - map_data.map_size) { - pr_err("%s: Invalid data size = %d\n", - __func__, bytes_returned); - result = -EINVAL; - goto err; - } + if (bytes_returned > rtac_cal[AFE_RTAC_CAL].map_data.map_size) { + pr_err("%s: Invalid data size = %d\n", __func__, + bytes_returned); + result = -EINVAL; + goto err; + } - if (bytes_returned > user_afe_buf.buf_size) { - pr_err("%s: user size = 0x%x, returned size = 0x%x\n", - __func__, user_afe_buf.buf_size, - bytes_returned); - result = -EINVAL; - goto err; - } + if (bytes_returned > user_afe_buf.buf_size) { + pr_err("%s: user size = 0x%x, returned size = 0x%x\n", __func__, + user_afe_buf.buf_size, bytes_returned); + result = -EINVAL; + goto err; + } - if (copy_to_user(buf, (void *) - rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr, - bytes_returned)) { - pr_err("%s: Could not copy buffer to user,size = %d\n", - __func__, bytes_returned); - result = -EINVAL; - goto err; - } - } else { - bytes_returned = user_afe_buf.rtac_afe_set.cmd.payload_size; + if (copy_to_user((void __user *) buf, + rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr, + bytes_returned)) { + pr_err("%s: Could not copy buffer to user,size = %d\n", + __func__, bytes_returned); + result = -EFAULT; + goto err; } + +unlock: mutex_unlock(&rtac_afe_apr_mutex); done: return bytes_returned; @@ -1535,7 +1602,9 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode) goto err; } - if (opcode == VSS_ICOMMON_CMD_SET_PARAM_V2) { + switch (opcode) { + case VSS_ICOMMON_CMD_SET_PARAM_V2: + case VSS_ICOMMON_CMD_SET_PARAM_V3: /* set payload size to in-band payload */ /* set data size to actual out of band payload size */ data_size = payload_size - 4 * sizeof(u32); @@ -1553,12 +1622,16 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode) buf + 7 * sizeof(u32), data_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); - result = -EINVAL; + result = -EFAULT; goto err; } /* set payload size in packet */ rtac_voice_buffer[8] = data_size; - } else { + /* set token for set param case */ + voice_params.token = VOC_RTAC_SET_PARAM_TOKEN; + break; + case VSS_ICOMMON_CMD_GET_PARAM_V2: + case VSS_ICOMMON_CMD_GET_PARAM_V3: if (payload_size > MAX_PAYLOAD_SIZE) { pr_err("%s: Invalid payload size = %d\n", __func__, payload_size); @@ -1572,9 +1645,16 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode) buf + 3 * sizeof(u32), payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); - result = -EINVAL; + result = -EFAULT; goto err; } + /* set token for get param case */ + voice_params.token = 0; + break; + default: + pr_err("%s: Invalid opcode %d\n", __func__, opcode); + result = -EINVAL; + goto err; } /* Pack header */ @@ -1588,18 +1668,14 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode) voice_params.dest_svc = 0; voice_params.dest_domain = APR_DOMAIN_MODEM; voice_params.dest_port = (u16)dest_port; - voice_params.token = (opcode == VSS_ICOMMON_CMD_SET_PARAM_V2) ? - VOC_RTAC_SET_PARAM_TOKEN : - 0; voice_params.opcode = opcode; /* fill for out-of-band */ rtac_voice_buffer[5] = rtac_cal[VOICE_RTAC_CAL].map_data.map_handle; rtac_voice_buffer[6] = lower_32_bits(rtac_cal[VOICE_RTAC_CAL].cal_data.paddr); - rtac_voice_buffer[7] = - msm_audio_populate_upper_32_bits( - rtac_cal[VOICE_RTAC_CAL].cal_data.paddr); + rtac_voice_buffer[7] = msm_audio_populate_upper_32_bits( + rtac_cal[VOICE_RTAC_CAL].cal_data.paddr); memcpy(rtac_voice_buffer, &voice_params, sizeof(voice_params)); atomic_set(&rtac_voice_apr_data[mode].cmd_state, 1); @@ -1638,33 +1714,39 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode) if (opcode == VSS_ICOMMON_CMD_GET_PARAM_V2) { bytes_returned = ((u32 *)rtac_cal[VOICE_RTAC_CAL].cal_data. kvaddr)[2] + 3 * sizeof(u32); + } else if (opcode == VSS_ICOMMON_CMD_GET_PARAM_V3) { + bytes_returned = + ((u32 *) rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr)[3] + + 4 * sizeof(u32); + } else { + bytes_returned = data_size; + goto unlock; + } - if (bytes_returned > rtac_cal[VOICE_RTAC_CAL]. - map_data.map_size) { - pr_err("%s: Invalid data size = %d\n", - __func__, bytes_returned); - result = -EINVAL; - goto err; - } + if (bytes_returned > rtac_cal[VOICE_RTAC_CAL].map_data.map_size) { + pr_err("%s: Invalid data size = %d\n", __func__, + bytes_returned); + result = -EINVAL; + goto err; + } - if (bytes_returned > user_buf_size) { - pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n", - __func__, user_buf_size, bytes_returned); - result = -EINVAL; - goto err; - } + if (bytes_returned > user_buf_size) { + pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n", + __func__, user_buf_size, bytes_returned); + result = -EINVAL; + goto err; + } - if (copy_to_user(buf, (void *) - rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr, - bytes_returned)) { - pr_err("%s: Could not copy buffer to user, size = %d\n", - __func__, bytes_returned); - result = -EINVAL; - goto err; - } - } else { - bytes_returned = data_size; + if (copy_to_user((void __user *) buf, + rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr, + bytes_returned)) { + pr_err("%s: Could not copy buffer to user, size = %d\n", + __func__, bytes_returned); + result = -EFAULT; + goto err; } + +unlock: mutex_unlock(&rtac_voice_apr_mutex); done: return bytes_returned; @@ -1684,8 +1766,8 @@ void get_rtac_adm_data(struct rtac_adm *adm_data) static long rtac_ioctl_shared(struct file *f, unsigned int cmd, void *arg) { + u32 opcode; int result = 0; - if (!arg) { pr_err("%s: No data sent to driver!\n", __func__); result = -EFAULT; @@ -1721,42 +1803,64 @@ static long rtac_ioctl_shared(struct file *f, } case AUDIO_GET_RTAC_ADM_CAL: - result = send_adm_apr((void *)arg, ADM_CMD_GET_PP_PARAMS_V5); + opcode = q6common_is_instance_id_supported() ? + ADM_CMD_GET_PP_PARAMS_V6 : + ADM_CMD_GET_PP_PARAMS_V5; + result = send_adm_apr((void *) arg, opcode); break; case AUDIO_SET_RTAC_ADM_CAL: - result = send_adm_apr((void *)arg, ADM_CMD_SET_PP_PARAMS_V5); + opcode = q6common_is_instance_id_supported() ? + ADM_CMD_SET_PP_PARAMS_V6 : + ADM_CMD_SET_PP_PARAMS_V5; + result = send_adm_apr((void *) arg, opcode); break; case AUDIO_GET_RTAC_ASM_CAL: - result = send_rtac_asm_apr((void *)arg, - ASM_STREAM_CMD_GET_PP_PARAMS_V2); + opcode = q6common_is_instance_id_supported() ? + ASM_STREAM_CMD_GET_PP_PARAMS_V3 : + ASM_STREAM_CMD_GET_PP_PARAMS_V2; + result = send_rtac_asm_apr((void *) arg, opcode); break; case AUDIO_SET_RTAC_ASM_CAL: - result = send_rtac_asm_apr((void *)arg, - ASM_STREAM_CMD_SET_PP_PARAMS_V2); + opcode = q6common_is_instance_id_supported() ? + ASM_STREAM_CMD_SET_PP_PARAMS_V3 : + ASM_STREAM_CMD_SET_PP_PARAMS_V2; + result = send_rtac_asm_apr((void *) arg, opcode); break; case AUDIO_GET_RTAC_CVS_CAL: - result = send_voice_apr(RTAC_CVS, (void *) arg, - VSS_ICOMMON_CMD_GET_PARAM_V2); + opcode = q6common_is_instance_id_supported() ? + VSS_ICOMMON_CMD_GET_PARAM_V3 : + VSS_ICOMMON_CMD_GET_PARAM_V2; + result = send_voice_apr(RTAC_CVS, (void *) arg, opcode); break; case AUDIO_SET_RTAC_CVS_CAL: - result = send_voice_apr(RTAC_CVS, (void *) arg, - VSS_ICOMMON_CMD_SET_PARAM_V2); + opcode = q6common_is_instance_id_supported() ? + VSS_ICOMMON_CMD_SET_PARAM_V3 : + VSS_ICOMMON_CMD_SET_PARAM_V2; + result = send_voice_apr(RTAC_CVS, (void *) arg, opcode); break; case AUDIO_GET_RTAC_CVP_CAL: - result = send_voice_apr(RTAC_CVP, (void *) arg, - VSS_ICOMMON_CMD_GET_PARAM_V2); + opcode = q6common_is_instance_id_supported() ? + VSS_ICOMMON_CMD_GET_PARAM_V3 : + VSS_ICOMMON_CMD_GET_PARAM_V2; + result = send_voice_apr(RTAC_CVP, (void *) arg, opcode); break; case AUDIO_SET_RTAC_CVP_CAL: - result = send_voice_apr(RTAC_CVP, (void *) arg, - VSS_ICOMMON_CMD_SET_PARAM_V2); + opcode = q6common_is_instance_id_supported() ? + VSS_ICOMMON_CMD_SET_PARAM_V3 : + VSS_ICOMMON_CMD_SET_PARAM_V2; + result = send_voice_apr(RTAC_CVP, (void *) arg, opcode); break; case AUDIO_GET_RTAC_AFE_CAL: - result = send_rtac_afe_apr((void *)arg, - AFE_PORT_CMD_GET_PARAM_V2); + opcode = q6common_is_instance_id_supported() ? + AFE_PORT_CMD_GET_PARAM_V3 : + AFE_PORT_CMD_GET_PARAM_V2; + result = send_rtac_afe_apr((void __user *) arg, opcode); break; case AUDIO_SET_RTAC_AFE_CAL: - result = send_rtac_afe_apr((void *)arg, - AFE_PORT_CMD_SET_PARAM_V2); + opcode = q6common_is_instance_id_supported() ? + AFE_PORT_CMD_SET_PARAM_V3 : + AFE_PORT_CMD_SET_PARAM_V2; + result = send_rtac_afe_apr((void __user *) arg, opcode); break; default: pr_err("%s: Invalid IOCTL, command = %d!\n", diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index cbbed10df8f5..d068e683ff75 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -498,6 +498,7 @@ struct adm_cmd_device_open_v6 { /* Sets one or more parameters to a COPP. */ #define ADM_CMD_SET_PP_PARAMS_V5 0x00010328 +#define ADM_CMD_SET_PP_PARAMS_V6 0x0001035D /* Payload of the #ADM_CMD_SET_PP_PARAMS_V5 command. * If the data_payload_addr_lsw and data_payload_addr_msw element @@ -639,6 +640,7 @@ struct adm_cmd_rsp_device_open_v5 { /* This command allows a query of one COPP parameter. */ #define ADM_CMD_GET_PP_PARAMS_V5 0x0001032A +#define ADM_CMD_GET_PP_PARAMS_V6 0x0001035E /* Payload an #ADM_CMD_GET_PP_PARAMS_V5 command. */ struct adm_cmd_get_pp_params_v5 { @@ -1534,46 +1536,79 @@ struct afe_sidetone_iir_filter_config_params { #define AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH 0x00010206 /* Used by RTAC */ -struct afe_rtac_set_param_v2 { +struct afe_rtac_user_data_set_v2 { + /* Port interface and direction (Rx or Tx) to start. */ u16 port_id; -/* Port interface and direction (Rx or Tx) to start. */ + /* Actual size of the payload in bytes. + * This is used for parsing the parameter payload. + * Supported values: > 0 + */ u16 payload_size; -/* Actual size of the payload in bytes. - * This is used for parsing the parameter payload. - * Supported values: > 0 - */ -u32 payload_address_lsw; -/* LSW of 64 bit Payload address. - * Address should be 32-byte, - * 4kbyte aligned and must be contiguous memory. - */ + /* The header detailing the memory mapping for out of band. */ + struct mem_mapping_hdr mem_hdr; -u32 payload_address_msw; -/* MSW of 64 bit Payload address. - * In case of 32-bit shared memory address, - * this field must be set to zero. - * In case of 36-bit shared memory address, - * bit-4 to bit-31 must be set to zero. - * Address should be 32-byte, 4kbyte aligned - * and must be contiguous memory. - */ + /* The parameter header for the parameter data to set */ + struct param_hdr_v1 param_hdr; -u32 mem_map_handle; -/* Memory map handle returned by - * AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS commands. - * Supported Values: - * - NULL -- Message. The parameter data is in-band. - * - Non-NULL -- The parameter data is Out-band.Pointer to - * the physical address - * in shared memory of the payload data. - * An optional field is available if parameter - * data is in-band: - * afe_param_data_v2 param_data[...]. - * For detailed payload content, see the - * afe_port_param_data_v2 structure. - */ + /* The parameter data to be filled when sent inband */ + u32 *param_data; +} __packed; + +struct afe_rtac_user_data_set_v3 { + /* Port interface and direction (Rx or Tx) to start. */ + u16 port_id; + /* Reserved for future enhancements. Must be 0. */ + u16 reserved; + + /* The header detailing the memory mapping for out of band. */ + struct mem_mapping_hdr mem_hdr; + + /* The size of the parameter header and parameter data */ + u32 payload_size; + + /* The parameter header for the parameter data to set */ + struct param_hdr_v3 param_hdr; + + /* The parameter data to be filled when sent inband */ + u32 *param_data; +} __packed; + +struct afe_rtac_user_data_get_v2 { + /* Port interface and direction (Rx or Tx) to start. */ + u16 port_id; + + /* Actual size of the payload in bytes. + * This is used for parsing the parameter payload. + * Supported values: > 0 + */ + u16 payload_size; + + /* The header detailing the memory mapping for out of band. */ + struct mem_mapping_hdr mem_hdr; + + /* The module ID of the parameter to get */ + u32 module_id; + + /* The parameter ID of the parameter to get */ + u32 param_id; + + /* The parameter data to be filled when sent inband */ + struct param_hdr_v1 param_hdr; +} __packed; + +struct afe_rtac_user_data_get_v3 { + /* Port interface and direction (Rx or Tx) to start. */ + u16 port_id; + /* Reserved for future enhancements. Must be 0. */ + u16 reserved; + + /* The header detailing the memory mapping for out of band. */ + struct mem_mapping_hdr mem_hdr; + + /* The parameter data to be filled when sent inband */ + struct param_hdr_v3 param_hdr; } __packed; #define AFE_PORT_CMD_SET_PARAM_V2 0x000100EF @@ -6571,6 +6606,7 @@ struct asm_stream_cmd_open_transcode_loopback_t { #define ASM_STREAM_CMD_FLUSH_READBUFS 0x00010C09 #define ASM_STREAM_CMD_SET_PP_PARAMS_V2 0x00010DA1 +#define ASM_STREAM_CMD_SET_PP_PARAMS_V3 0x0001320D struct asm_stream_cmd_set_pp_params_v2 { u32 data_payload_addr_lsw; @@ -6624,6 +6660,7 @@ struct asm_stream_param_data_v2 { } __packed; #define ASM_STREAM_CMD_GET_PP_PARAMS_V2 0x00010DA2 +#define ASM_STREAM_CMD_GET_PP_PARAMS_V3 0x0001320E struct asm_stream_cmd_get_pp_params_v2 { u32 data_payload_addr_lsw; @@ -6801,6 +6838,7 @@ struct asm_aac_dual_mono_mapping_param { } __packed; #define ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 0x00010DA4 +#define ASM_STREAM_CMDRSP_GET_PP_PARAMS_V3 0x0001320F struct asm_stream_cmdrsp_get_pp_params_v2 { u32 status; -- GitLab From 60cc03517fa5c6bb1b60344c0968cd047f85dc6a Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Mon, 29 Jan 2018 16:21:22 -0800 Subject: [PATCH 0214/1645] ASoC: dsp: Update ADM driver to support Instance ID Add support to set and get ADM module params with Instance ID support. Maintain support for non Instance ID set and get param structures as well. Use common pack and set param functions to set and get parameters to DSP instead of handling them at an individual module level. CRs-Fixed: 2151551 Change-Id: I5ef920448dd827d8a315e248087997f703061263 Signed-off-by: Vignesh Kulothungan --- asoc/msm-pcm-routing-v2.c | 63 +- asoc/msm-qti-pp-config.c | 114 +- dsp/q6adm.c | 2405 +++++++++++++----------------------- include/dsp/apr_audio-v2.h | 291 ++--- include/dsp/q6adm-v2.h | 21 + 5 files changed, 1086 insertions(+), 1808 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 2b6a69f0bb29..5e825506e74c 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -11517,10 +11517,11 @@ static int msm_routing_put_module_cfg_control(struct snd_kcontrol *kcontrol, int ret = 0; unsigned long copp; struct msm_pcm_routing_bdai_data *bedai; - char *param_data = NULL; - uint32_t *update_param_data = NULL; - uint32_t param_size = sizeof(uint32_t) + - sizeof(struct adm_param_data_v5); + u8 *packed_params = NULL; + struct param_hdr_v3 param_hdr; + u32 packed_param_size = (sizeof(struct param_hdr_v3) + + sizeof(uint32_t)); + int dir = ucontrol->value.integer.value[0] ? SESSION_TYPE_TX : SESSION_TYPE_RX; int app_type = ucontrol->value.integer.value[1]; @@ -11535,15 +11536,17 @@ static int msm_routing_put_module_cfg_control(struct snd_kcontrol *kcontrol, __func__, app_type, module_id, instance_id, param_id, param_value); - param_data = kzalloc(param_size, GFP_KERNEL); - if (!param_data) + packed_params = kzalloc(packed_param_size, GFP_KERNEL); + if (!packed_params) return -ENOMEM; - update_param_data = (uint32_t *)param_data; - *update_param_data++ = module_id; - *update_param_data++ = param_id; - *update_param_data++ = sizeof(uint32_t); - *update_param_data++ = param_value; + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = module_id; + param_hdr.instance_id = instance_id; + param_hdr.param_id = param_id; + param_hdr.param_size = sizeof(uint32_t); + + packed_param_size = 0; mutex_lock(&routing_lock); for (be_id = 0; be_id < MSM_BACKEND_DAI_MAX; be_id++) { @@ -11571,10 +11574,20 @@ static int msm_routing_put_module_cfg_control(struct snd_kcontrol *kcontrol, if (!test_bit(copp_idx, &copp)) continue; - ret = adm_send_params_v5(bedai->port_id, - copp_idx, - param_data, - param_size); + ret = q6common_pack_pp_params(packed_params, + ¶m_hdr, + (u8 *) ¶m_value, + &packed_param_size); + if (ret) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, ret); + goto done; + } + + ret = adm_set_pp_params(bedai->port_id, + copp_idx, NULL, + packed_params, + packed_param_size); if (ret) { pr_err("%s: Setting param failed with err=%d\n", __func__, ret); @@ -11586,7 +11599,7 @@ static int msm_routing_put_module_cfg_control(struct snd_kcontrol *kcontrol, } done: mutex_unlock(&routing_lock); - kfree(param_data); + kfree(packed_params); return ret; } @@ -11662,22 +11675,24 @@ int msm_routing_get_rms_value_control(struct snd_kcontrol *kcontrol, int be_idx = 0; char *param_value; int *update_param_value; - uint32_t param_length = sizeof(uint32_t); - uint32_t param_payload_len = RMS_PAYLOAD_LEN * sizeof(uint32_t); + uint32_t param_size = (RMS_PAYLOAD_LEN + 1) * sizeof(uint32_t); + struct param_hdr_v3 param_hdr; - param_value = kzalloc(param_length + param_payload_len, GFP_KERNEL); + param_value = kzalloc(param_size, GFP_KERNEL); if (!param_value) return -ENOMEM; + memset(¶m_hdr, 0, sizeof(param_hdr)); for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) if (msm_bedais[be_idx].port_id == SLIMBUS_0_TX) break; if ((be_idx < MSM_BACKEND_DAI_MAX) && msm_bedais[be_idx].active) { - rc = adm_get_params(SLIMBUS_0_TX, 0, - RMS_MODULEID_APPI_PASSTHRU, - RMS_PARAM_FIRST_SAMPLE, - param_length + param_payload_len, - param_value); + param_hdr.module_id = RMS_MODULEID_APPI_PASSTHRU; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = RMS_PARAM_FIRST_SAMPLE; + param_hdr.param_size = param_size; + rc = adm_get_pp_params(SLIMBUS_0_TX, 0, ADM_CLIENT_ID_DEFAULT, + NULL, ¶m_hdr, (u8 *) param_value); if (rc) { pr_err("%s: get parameters failed:%d\n", __func__, rc); kfree(param_value); diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index 00a29d71a55b..f210745fa69d 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -21,6 +21,7 @@ #include #include #include +#include #include "msm-qti-pp-config.h" #include "msm-pcm-routing-v2.h" @@ -263,6 +264,11 @@ int msm_qti_pp_send_stereo_to_custom_stereo_cmd(int port_id, int copp_idx, update_params_value32 = (int *)params_value; if (avail_length < 2 * sizeof(uint32_t)) goto skip_send_cmd; + + /* + * This module is internal to ADSP and cannot be configured with + * an instance id + */ *update_params_value32++ = MTMX_MODULE_ID_DEFAULT_CHMIXER; *update_params_value32++ = DEFAULT_CHMIXER_PARAM_ID_COEFF; avail_length = avail_length - (2 * sizeof(uint32_t)); @@ -329,14 +335,13 @@ static int msm_qti_pp_get_rms_value_control(struct snd_kcontrol *kcontrol, int be_idx = 0, copp_idx; char *param_value; int *update_param_value; - uint32_t param_length = sizeof(uint32_t); - uint32_t param_payload_len = RMS_PAYLOAD_LEN * sizeof(uint32_t); + uint32_t param_size = (RMS_PAYLOAD_LEN + 1) * sizeof(uint32_t); struct msm_pcm_routing_bdai_data msm_bedai; + struct param_hdr_v3 param_hdr; - param_value = kzalloc(param_length + param_payload_len, GFP_KERNEL); + param_value = kzalloc(param_size, GFP_KERNEL); if (!param_value) return -ENOMEM; - msm_pcm_routing_acquire_lock(); for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) { msm_pcm_routing_get_bedai_info(be_idx, &msm_bedai); @@ -356,11 +361,13 @@ static int msm_qti_pp_get_rms_value_control(struct snd_kcontrol *kcontrol, rc = -EINVAL; goto get_rms_value_err; } - rc = adm_get_params(SLIMBUS_0_TX, copp_idx, - RMS_MODULEID_APPI_PASSTHRU, - RMS_PARAM_FIRST_SAMPLE, - param_length + param_payload_len, - param_value); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = RMS_MODULEID_APPI_PASSTHRU; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = RMS_PARAM_FIRST_SAMPLE; + param_hdr.param_size = param_size; + rc = adm_get_pp_params(SLIMBUS_0_TX, copp_idx, ADM_CLIENT_ID_DEFAULT, + NULL, ¶m_hdr, param_value); if (rc) { pr_err("%s: get parameters failed rc=%d\n", __func__, rc); rc = -EINVAL; @@ -692,64 +699,83 @@ static void msm_qti_pp_asphere_init_state(void) static int msm_qti_pp_asphere_send_params(int port_id, int copp_idx, bool force) { - char *params_value = NULL; - uint32_t *update_params_value = NULL; - uint32_t param_size = sizeof(uint32_t) + - sizeof(struct adm_param_data_v5); - int params_length = 0, param_count = 0, ret = 0; + u8 *packed_params = NULL; + u32 packed_params_size = 0; + u32 param_size = 0; + struct param_hdr_v3 param_hdr; bool set_enable = force || (asphere_state.enabled != asphere_state.enabled_prev); bool set_strength = asphere_state.enabled == 1 && (set_enable || (asphere_state.strength != asphere_state.strength_prev)); + int param_count = 0; + int ret = 0; if (set_enable) param_count++; if (set_strength) param_count++; - params_length = param_count * param_size; + + if (param_count == 0) { + pr_debug("%s: Nothing to send, exiting\n", __func__); + return 0; + } pr_debug("%s: port_id %d, copp_id %d, forced %d, param_count %d\n", - __func__, port_id, copp_idx, force, param_count); + __func__, port_id, copp_idx, force, param_count); pr_debug("%s: enable prev:%u cur:%u, strength prev:%u cur:%u\n", __func__, asphere_state.enabled_prev, asphere_state.enabled, asphere_state.strength_prev, asphere_state.strength); - if (params_length > 0) - params_value = kzalloc(params_length, GFP_KERNEL); - if (!params_value) { - pr_err("%s, params memory alloc failed\n", __func__); + packed_params_size = + param_count * (sizeof(struct param_hdr_v3) + sizeof(uint32_t)); + packed_params = kzalloc(packed_params_size, GFP_KERNEL); + if (!packed_params) return -ENOMEM; - } - update_params_value = (uint32_t *)params_value; - params_length = 0; + + memset(¶m_hdr, 0, sizeof(param_hdr)); + packed_params_size = 0; + param_hdr.module_id = AUDPROC_MODULE_ID_AUDIOSPHERE; + param_hdr.instance_id = INSTANCE_ID_0; if (set_strength) { /* add strength command */ - *update_params_value++ = AUDPROC_MODULE_ID_AUDIOSPHERE; - *update_params_value++ = AUDPROC_PARAM_ID_AUDIOSPHERE_STRENGTH; - *update_params_value++ = sizeof(uint32_t); - *update_params_value++ = asphere_state.strength; - params_length += param_size; + param_hdr.param_id = AUDPROC_PARAM_ID_AUDIOSPHERE_STRENGTH; + param_hdr.param_size = sizeof(asphere_state.strength); + ret = q6common_pack_pp_params(packed_params + + packed_params_size, + ¶m_hdr, + (u8 *) &asphere_state.strength, + ¶m_size); + if (ret) { + pr_err("%s: Failed to pack params for audio sphere" + " strength, error %d\n", __func__, ret); + goto done; + } + packed_params_size += param_size; } if (set_enable) { /* add enable command */ - *update_params_value++ = AUDPROC_MODULE_ID_AUDIOSPHERE; - *update_params_value++ = AUDPROC_PARAM_ID_AUDIOSPHERE_ENABLE; - *update_params_value++ = sizeof(uint32_t); - *update_params_value++ = asphere_state.enabled; - params_length += param_size; - } - pr_debug("%s, param length: %d\n", __func__, params_length); - if (params_length) { - ret = adm_send_params_v5(port_id, copp_idx, - params_value, params_length); + param_hdr.param_id = AUDPROC_PARAM_ID_AUDIOSPHERE_ENABLE; + param_hdr.param_size = sizeof(asphere_state.enabled); + q6common_pack_pp_params(packed_params + packed_params_size, + ¶m_hdr, + (u8 *) &asphere_state.enabled, + ¶m_size); if (ret) { - pr_err("%s: setting param failed with err=%d\n", - __func__, ret); - kfree(params_value); - return -EINVAL; + pr_err("%s: Failed to pack params for audio sphere" + " enable, error %d\n", __func__, ret); + goto done; } + packed_params_size += param_size; } - kfree(params_value); + + pr_debug("%s: packed data size: %d\n", __func__, packed_params_size); + ret = adm_set_pp_params(port_id, copp_idx, NULL, packed_params, + packed_params_size); + if (ret) + pr_err("%s: set param failed with err=%d\n", __func__, ret); + +done: + kfree(packed_params); return 0; } diff --git a/dsp/q6adm.c b/dsp/q6adm.c index f8aef943439f..8ebab78ac1e4 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "adsp_err.h" @@ -32,8 +33,8 @@ #define RESET_COPP_ID 99 #define INVALID_COPP_ID 0xFF /* Used for inband payload copy, max size is 4k */ -/* 2 is to account for module & param ID in payload */ -#define ADM_GET_PARAMETER_LENGTH (4096 - APR_HDR_SIZE - 2 * sizeof(uint32_t)) +/* 3 is to account for module, instance & param ID in payload */ +#define ADM_GET_PARAMETER_LENGTH (4096 - APR_HDR_SIZE - 3 * sizeof(uint32_t)) #define ULL_SUPPORTED_BITS_PER_SAMPLE 16 #define ULL_SUPPORTED_SAMPLE_RATE 48000 @@ -124,8 +125,8 @@ static struct adm_multi_ch_map multi_ch_maps[2] = { }; static int adm_get_parameters[MAX_COPPS_PER_PORT * ADM_GET_PARAMETER_LENGTH]; -static int adm_module_topo_list[ - MAX_COPPS_PER_PORT * ADM_GET_TOPO_MODULE_LIST_LENGTH]; +static int adm_module_topo_list[MAX_COPPS_PER_PORT * + ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH]; static struct mutex dts_srs_lock; void msm_dts_srs_acquire_lock(void) @@ -316,266 +317,109 @@ static int adm_get_next_available_copp(int port_idx) int srs_trumedia_open(int port_id, int copp_idx, __s32 srs_tech_id, void *srs_params) { - struct adm_cmd_set_pp_params_inband_v5 *adm_params = NULL; - struct adm_cmd_set_pp_params_v5 *adm_params_ = NULL; - __s32 sz = 0, param_id, module_id = SRS_TRUMEDIA_MODULE_ID, outband = 0; - int ret = 0, port_idx; + struct param_hdr_v3 param_hdr; + struct mem_mapping_hdr mem_hdr; + u32 total_param_size = 0; + bool outband = false; + int port_idx; + int ret = 0; pr_debug("SRS - %s", __func__); + memset(¶m_hdr, 0, sizeof(param_hdr)); + memset(&mem_hdr, 0, sizeof(mem_hdr)); port_id = afe_convert_virtual_to_portid(port_id); port_idx = adm_validate_and_get_port_index(port_id); if (port_idx < 0) { pr_err("%s: Invalid port_id %#x\n", __func__, port_id); return -EINVAL; } + + param_hdr.module_id = SRS_TRUMEDIA_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + switch (srs_tech_id) { case SRS_ID_GLOBAL: { - struct srs_trumedia_params_GLOBAL *glb_params = NULL; - - sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + + param_hdr.param_id = SRS_TRUMEDIA_PARAMS; + param_hdr.param_size = sizeof(struct srs_trumedia_params_GLOBAL); - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed\n", - __func__); - return -ENOMEM; - } - adm_params->payload_size = - sizeof(struct srs_trumedia_params_GLOBAL) + - sizeof(struct adm_param_data_v5); - param_id = SRS_TRUMEDIA_PARAMS; - adm_params->params.param_size = - sizeof(struct srs_trumedia_params_GLOBAL); - glb_params = (struct srs_trumedia_params_GLOBAL *) - ((u8 *)adm_params + - sizeof(struct adm_cmd_set_pp_params_inband_v5)); - memcpy(glb_params, srs_params, - sizeof(struct srs_trumedia_params_GLOBAL)); break; } case SRS_ID_WOWHD: { - struct srs_trumedia_params_WOWHD *whd_params = NULL; - - sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + - sizeof(struct srs_trumedia_params_WOWHD); - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed\n", - __func__); - return -ENOMEM; - } - adm_params->payload_size = - sizeof(struct srs_trumedia_params_WOWHD) + - sizeof(struct adm_param_data_v5); - param_id = SRS_TRUMEDIA_PARAMS_WOWHD; - adm_params->params.param_size = - sizeof(struct srs_trumedia_params_WOWHD); - whd_params = (struct srs_trumedia_params_WOWHD *) - ((u8 *)adm_params + - sizeof(struct adm_cmd_set_pp_params_inband_v5)); - memcpy(whd_params, srs_params, - sizeof(struct srs_trumedia_params_WOWHD)); + param_hdr.param_id = SRS_TRUMEDIA_PARAMS_WOWHD; + param_hdr.param_size = sizeof(struct srs_trumedia_params_WOWHD); break; } case SRS_ID_CSHP: { - struct srs_trumedia_params_CSHP *chp_params = NULL; - - sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + - sizeof(struct srs_trumedia_params_CSHP); - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed\n", - __func__); - return -ENOMEM; - } - adm_params->payload_size = - sizeof(struct srs_trumedia_params_CSHP) + - sizeof(struct adm_param_data_v5); - param_id = SRS_TRUMEDIA_PARAMS_CSHP; - adm_params->params.param_size = - sizeof(struct srs_trumedia_params_CSHP); - chp_params = (struct srs_trumedia_params_CSHP *) - ((u8 *)adm_params + - sizeof(struct adm_cmd_set_pp_params_inband_v5)); - memcpy(chp_params, srs_params, - sizeof(struct srs_trumedia_params_CSHP)); + param_hdr.param_id = SRS_TRUMEDIA_PARAMS_CSHP; + param_hdr.param_size = sizeof(struct srs_trumedia_params_CSHP); break; } case SRS_ID_HPF: { - struct srs_trumedia_params_HPF *hpf_params = NULL; - - sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + - sizeof(struct srs_trumedia_params_HPF); - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed\n", - __func__); - return -ENOMEM; - } - adm_params->payload_size = - sizeof(struct srs_trumedia_params_HPF) + - sizeof(struct adm_param_data_v5); - param_id = SRS_TRUMEDIA_PARAMS_HPF; - adm_params->params.param_size = - sizeof(struct srs_trumedia_params_HPF); - hpf_params = (struct srs_trumedia_params_HPF *) - ((u8 *)adm_params + - sizeof(struct adm_cmd_set_pp_params_inband_v5)); - memcpy(hpf_params, srs_params, - sizeof(struct srs_trumedia_params_HPF)); + param_hdr.param_id = SRS_TRUMEDIA_PARAMS_HPF; + param_hdr.param_size = sizeof(struct srs_trumedia_params_HPF); break; } case SRS_ID_AEQ: { - int *update_params_ptr = (int *)this_adm.outband_memmap.kvaddr; - - outband = 1; - adm_params = kzalloc(sizeof(struct adm_cmd_set_pp_params_v5), - GFP_KERNEL); - adm_params_ = (struct adm_cmd_set_pp_params_v5 *)adm_params; - if (!adm_params_) { - pr_err("%s, adm params memory alloc failed\n", - __func__); - return -ENOMEM; - } + u8 *update_params_ptr = (u8 *) this_adm.outband_memmap.kvaddr; + + outband = true; - sz = sizeof(struct srs_trumedia_params_AEQ); if (update_params_ptr == NULL) { pr_err("ADM_SRS_TRUMEDIA - %s: null memmap for AEQ params\n", __func__); ret = -EINVAL; goto fail_cmd; } - param_id = SRS_TRUMEDIA_PARAMS_AEQ; - *update_params_ptr++ = module_id; - *update_params_ptr++ = param_id; - *update_params_ptr++ = sz; - memcpy(update_params_ptr, srs_params, sz); - adm_params_->payload_size = sz + 12; + param_hdr.param_id = SRS_TRUMEDIA_PARAMS_AEQ; + param_hdr.param_size = sizeof(struct srs_trumedia_params_AEQ); + ret = q6common_pack_pp_params(update_params_ptr, ¶m_hdr, + srs_params, &total_param_size); + if (ret) { + pr_err("%s: Failed to pack param header and data, error %d\n", + __func__, ret); + goto fail_cmd; + } break; } case SRS_ID_HL: { - struct srs_trumedia_params_HL *hl_params = NULL; - - sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + - sizeof(struct srs_trumedia_params_HL); - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed\n", - __func__); - return -ENOMEM; - } - adm_params->payload_size = - sizeof(struct srs_trumedia_params_HL) + - sizeof(struct adm_param_data_v5); - param_id = SRS_TRUMEDIA_PARAMS_HL; - adm_params->params.param_size = - sizeof(struct srs_trumedia_params_HL); - hl_params = (struct srs_trumedia_params_HL *) - ((u8 *)adm_params + - sizeof(struct adm_cmd_set_pp_params_inband_v5)); - memcpy(hl_params, srs_params, - sizeof(struct srs_trumedia_params_HL)); + param_hdr.param_id = SRS_TRUMEDIA_PARAMS_HL; + param_hdr.param_size = sizeof(struct srs_trumedia_params_HL); break; } case SRS_ID_GEQ: { - struct srs_trumedia_params_GEQ *geq_params = NULL; - - sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + - sizeof(struct srs_trumedia_params_GEQ); - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed\n", - __func__); - return -ENOMEM; - } - adm_params->payload_size = - sizeof(struct srs_trumedia_params_GEQ) + - sizeof(struct adm_param_data_v5); - param_id = SRS_TRUMEDIA_PARAMS_GEQ; - adm_params->params.param_size = - sizeof(struct srs_trumedia_params_GEQ); - geq_params = (struct srs_trumedia_params_GEQ *) - ((u8 *)adm_params + - sizeof(struct adm_cmd_set_pp_params_inband_v5)); - memcpy(geq_params, srs_params, - sizeof(struct srs_trumedia_params_GEQ)); - pr_debug("SRS - %s: GEQ params prepared\n", __func__); + param_hdr.param_id = SRS_TRUMEDIA_PARAMS_GEQ; + param_hdr.param_size = sizeof(struct srs_trumedia_params_GEQ); break; } default: goto fail_cmd; } - adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - adm_params->hdr.src_svc = APR_SVC_ADM; - adm_params->hdr.src_domain = APR_DOMAIN_APPS; - adm_params->hdr.src_port = port_id; - adm_params->hdr.dest_svc = APR_SVC_ADM; - adm_params->hdr.dest_domain = APR_DOMAIN_ADSP; - adm_params->hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - adm_params->hdr.token = port_idx << 16 | copp_idx; - adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; if (outband && this_adm.outband_memmap.paddr) { - adm_params->hdr.pkt_size = - sizeof(struct adm_cmd_set_pp_params_v5); - adm_params->payload_addr_lsw = lower_32_bits( - this_adm.outband_memmap.paddr); - adm_params->payload_addr_msw = msm_audio_populate_upper_32_bits( - this_adm.outband_memmap.paddr); - adm_params->mem_map_handle = atomic_read(&this_adm. - mem_map_handles[ADM_SRS_TRUMEDIA]); + mem_hdr.data_payload_addr_lsw = + lower_32_bits(this_adm.outband_memmap.paddr); + mem_hdr.data_payload_addr_msw = + msm_audio_populate_upper_32_bits( + this_adm.outband_memmap.paddr); + mem_hdr.mem_map_handle = atomic_read( + &this_adm.mem_map_handles[ADM_SRS_TRUMEDIA]); + + ret = adm_set_pp_params(port_id, copp_idx, &mem_hdr, NULL, + total_param_size); } else { - adm_params->hdr.pkt_size = sz; - adm_params->payload_addr_lsw = 0; - adm_params->payload_addr_msw = 0; - adm_params->mem_map_handle = 0; - - adm_params->params.module_id = module_id; - adm_params->params.param_id = param_id; - adm_params->params.reserved = 0; + ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, + param_hdr, + (u8 *) srs_params); } - pr_debug("SRS - %s: Command was sent now check Q6 - port id = %d, size %d, module id %x, param id %x.\n", - __func__, adm_params->hdr.dest_port, - adm_params->payload_size, module_id, param_id); - - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - ret = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); - if (ret < 0) { + if (ret < 0) pr_err("SRS - %s: ADM enable for port %d failed\n", __func__, port_id); - ret = -EINVAL; - goto fail_cmd; - } - /* Wait for the callback with copp id */ - ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: SRS set params timed out port = %d\n", - __func__, port_id); - ret = -EINVAL; - goto fail_cmd; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto fail_cmd; - } fail_cmd: - kfree(adm_params); return ret; } EXPORT_SYMBOL(srs_trumedia_open); @@ -636,7 +480,7 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, int channel_index) { struct adm_cmd_set_pspd_mtmx_strtr_params_v5 *adm_params = NULL; - struct adm_param_data_v5 data_v5; + struct param_hdr_v3 data_v5; int ret = 0, port_idx, sz = 0, param_size = 0; u16 *adm_pspd_params; u16 *ptr; @@ -668,8 +512,8 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, roundup(param_size, 4); sz = sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v5) + - sizeof(struct default_chmixer_param_id_coeff) + - sizeof(struct adm_param_data_v5) + param_size; + sizeof(struct default_chmixer_param_id_coeff) + + sizeof(struct param_hdr_v3) + param_size; pr_debug("%s: sz = %d\n", __func__, sz); adm_params = kzalloc(sz, GFP_KERNEL); if (!adm_params) @@ -687,13 +531,17 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, &this_adm.copp.id[port_idx][copp_idx]); adm_params->reserved = 0; + /* + * This module is internal to ADSP and cannot be configured with + * an instance id + */ data_v5.module_id = MTMX_MODULE_ID_DEFAULT_CHMIXER; data_v5.param_id = DEFAULT_CHMIXER_PARAM_ID_COEFF; data_v5.reserved = 0; data_v5.param_size = param_size; adm_params->payload_size = - sizeof(struct default_chmixer_param_id_coeff) + - sizeof(struct adm_param_data_v5) + data_v5.param_size; + sizeof(struct default_chmixer_param_id_coeff) + + sizeof(struct param_hdr_v3) + data_v5.param_size; adm_pspd_params = (u16 *)((u8 *)adm_params + sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v5)); memcpy(adm_pspd_params, &data_v5, sizeof(data_v5)); @@ -955,321 +803,306 @@ EXPORT_SYMBOL(adm_set_stereo_to_custom_stereo); int adm_dolby_dap_send_params(int port_id, int copp_idx, char *params, uint32_t params_length) { - struct adm_cmd_set_pp_params_v5 *adm_params = NULL; - int sz, rc = 0; - int port_idx; + /* Use as wrapper for adm_set_pp_params until no longer used */ + return adm_set_pp_params(port_id, copp_idx, NULL, params, + params_length); +} +EXPORT_SYMBOL(adm_dolby_dap_send_params); + +/* + * With pre-packed data, only the opcode differes from V5 and V6. + * Use q6common_pack_pp_params to pack the data correctly. + */ +int adm_set_pp_params(int port_id, int copp_idx, + struct mem_mapping_hdr *mem_hdr, u8 *param_data, + u32 param_size) +{ + struct adm_cmd_set_pp_params *adm_set_params = NULL; + int size = 0; + int port_idx = 0; + atomic_t *copp_stat = NULL; + int ret = 0; - pr_debug("%s:\n", __func__); port_id = afe_convert_virtual_to_portid(port_id); port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { + pr_err("%s: Invalid port_idx 0x%x\n", __func__, port_idx); + return -EINVAL; + } else if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_idx 0x%x\n", __func__, copp_idx); return -EINVAL; } - sz = sizeof(struct adm_cmd_set_pp_params_v5) + params_length; - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed", __func__); + /* Only add params_size in inband case */ + size = sizeof(struct adm_cmd_set_pp_params); + if (param_data != NULL) + size += param_size; + adm_set_params = kzalloc(size, GFP_KERNEL); + if (!adm_set_params) return -ENOMEM; - } - memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_set_pp_params_v5)), - params, params_length); - adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - adm_params->hdr.pkt_size = sz; - adm_params->hdr.src_svc = APR_SVC_ADM; - adm_params->hdr.src_domain = APR_DOMAIN_APPS; - adm_params->hdr.src_port = port_id; - adm_params->hdr.dest_svc = APR_SVC_ADM; - adm_params->hdr.dest_domain = APR_DOMAIN_ADSP; - adm_params->hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - adm_params->hdr.token = port_idx << 16 | copp_idx; - adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - adm_params->payload_addr_lsw = 0; - adm_params->payload_addr_msw = 0; - adm_params->mem_map_handle = 0; - adm_params->payload_size = params_length; + adm_set_params->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + adm_set_params->apr_hdr.pkt_size = size; + adm_set_params->apr_hdr.src_svc = APR_SVC_ADM; + adm_set_params->apr_hdr.src_domain = APR_DOMAIN_APPS; + adm_set_params->apr_hdr.src_port = port_id; + adm_set_params->apr_hdr.dest_svc = APR_SVC_ADM; + adm_set_params->apr_hdr.dest_domain = APR_DOMAIN_ADSP; + adm_set_params->apr_hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + adm_set_params->apr_hdr.token = port_idx << 16 | copp_idx; + + if (q6common_is_instance_id_supported()) + adm_set_params->apr_hdr.opcode = ADM_CMD_SET_PP_PARAMS_V6; + else + adm_set_params->apr_hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + + adm_set_params->payload_size = param_size; + + if (mem_hdr != NULL) { + /* Out of Band Case */ + adm_set_params->mem_hdr = *mem_hdr; + } else if (param_data != NULL) { + /* + * In band case. Parameter data must be pre-packed with its + * header before calling this function. Use + * q6common_pack_pp_params to pack parameter data and header + * correctly. + */ + memcpy(&adm_set_params->param_data, param_data, param_size); + } else { + pr_err("%s: Received NULL pointers for both memory header and param data\n", + __func__); + ret = -EINVAL; + goto done; + } - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); - if (rc < 0) { - pr_err("%s: Set params failed port = 0x%x rc %d\n", - __func__, port_id, rc); - rc = -EINVAL; - goto dolby_dap_send_param_return; + copp_stat = &this_adm.copp.stat[port_idx][copp_idx]; + atomic_set(copp_stat, -1); + ret = apr_send_pkt(this_adm.apr, (uint32_t *) adm_set_params); + if (ret < 0) { + pr_err("%s: Set params APR send failed port = 0x%x ret %d\n", + __func__, port_id, ret); + goto done; } - /* Wait for the callback */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: Set params timed out port = 0x%x\n", - __func__, port_id); - rc = -EINVAL; - goto dolby_dap_send_param_return; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto dolby_dap_send_param_return; + ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(copp_stat) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Set params timed out port = 0x%x\n", __func__, + port_id); + ret = -ETIMEDOUT; + goto done; } - rc = 0; -dolby_dap_send_param_return: - kfree(adm_params); - return rc; + if (atomic_read(copp_stat) > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(atomic_read(copp_stat))); + ret = adsp_err_get_lnx_err_code(atomic_read(copp_stat)); + goto done; + } + + ret = 0; +done: + kfree(adm_set_params); + return ret; } -EXPORT_SYMBOL(adm_dolby_dap_send_params); +EXPORT_SYMBOL(adm_set_pp_params); -/** - * adm_get_params_v5 - - * command to retrieve ADM params for given module - * - * @port_id: Port ID number - * @copp_idx: copp index of ADM copp - * @params: params pointer - * @param_length: length of params - * - * Returns 0 on success or error on failure - */ -int adm_send_params_v5(int port_id, int copp_idx, char *params, - uint32_t params_length) +int adm_pack_and_set_one_pp_param(int port_id, int copp_idx, + struct param_hdr_v3 param_hdr, u8 *param_data) { - struct adm_cmd_set_pp_params_v5 *adm_params = NULL; - int rc = 0; - int sz, port_idx; - - pr_debug("%s:\n", __func__); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); - return -EINVAL; - } + u8 *packed_data = NULL; + u32 total_size = 0; + int ret = 0; - sz = sizeof(struct adm_cmd_set_pp_params_v5) + params_length; - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed", __func__); + total_size = sizeof(union param_hdrs) + param_hdr.param_size; + packed_data = kzalloc(total_size, GFP_KERNEL); + if (!packed_data) return -ENOMEM; - } - memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_set_pp_params_v5)), - params, params_length); - adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - adm_params->hdr.pkt_size = sz; - adm_params->hdr.src_svc = APR_SVC_ADM; - adm_params->hdr.src_domain = APR_DOMAIN_APPS; - adm_params->hdr.src_port = port_id; - adm_params->hdr.dest_svc = APR_SVC_ADM; - adm_params->hdr.dest_domain = APR_DOMAIN_ADSP; - adm_params->hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - adm_params->hdr.token = port_idx << 16 | copp_idx; - adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - adm_params->payload_addr_lsw = 0; - adm_params->payload_addr_msw = 0; - adm_params->mem_map_handle = 0; - adm_params->payload_size = params_length; - - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); - if (rc < 0) { - pr_err("%s: Set params failed port = 0x%x rc %d\n", - __func__, port_id, rc); - rc = -EINVAL; - goto send_param_return; - } - /* Wait for the callback */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: Set params timed out port = 0x%x\n", - __func__, port_id); - rc = -EINVAL; - goto send_param_return; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto send_param_return; + ret = q6common_pack_pp_params(packed_data, ¶m_hdr, param_data, + &total_size); + if (ret) { + pr_err("%s: Failed to pack parameter data, error %d\n", + __func__, ret); + goto done; } - rc = 0; -send_param_return: - kfree(adm_params); - return rc; + + ret = adm_set_pp_params(port_id, copp_idx, NULL, packed_data, + total_size); + if (ret) + pr_err("%s: Failed to set parameter data, error %d\n", __func__, + ret); +done: + kfree(packed_data); + return ret; } -EXPORT_SYMBOL(adm_send_params_v5); +EXPORT_SYMBOL(adm_pack_and_set_one_pp_param); int adm_get_params_v2(int port_id, int copp_idx, uint32_t module_id, - uint32_t param_id, uint32_t params_length, - char *params, uint32_t client_id) + uint32_t param_id, uint32_t params_length, char *params, + uint32_t client_id) { - struct adm_cmd_get_pp_params_v5 *adm_params = NULL; - int rc = 0, i = 0; - int port_idx, idx; - int *params_data = (int *)params; - uint64_t sz = 0; + struct param_hdr_v3 param_hdr; - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = module_id; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = param_id; + param_hdr.param_size = params_length; + + return adm_get_pp_params(port_id, copp_idx, client_id, NULL, ¶m_hdr, + params); +} + +int adm_get_params(int port_id, int copp_idx, uint32_t module_id, + uint32_t param_id, uint32_t params_length, char *params) +{ + return adm_get_params_v2(port_id, copp_idx, module_id, param_id, + params_length, params, 0); +} + +/* + * Only one parameter can be requested at a time. Therefore, packing and sending + * the request can be handled locally. + */ +int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id, + struct mem_mapping_hdr *mem_hdr, + struct param_hdr_v3 *param_hdr, u8 *returned_param_data) +{ + struct adm_cmd_get_pp_params adm_get_params; + int total_size = 0; + int get_param_array_sz = ARRAY_SIZE(adm_get_parameters); + int returned_param_size = 0; + int returned_param_size_in_bytes = 0; + int port_idx = 0; + int idx = 0; + atomic_t *copp_stat = NULL; + int ret = 0; + + if (param_hdr == NULL) { + pr_err("%s: Received NULL pointer for parameter header\n", + __func__); return -EINVAL; } - sz = (uint64_t)sizeof(struct adm_cmd_get_pp_params_v5) + - (uint64_t)params_length; - /* - * Check if the value of "sz" (which is ultimately assigned to - * "hdr.pkt_size") crosses U16_MAX. - */ - if (sz > U16_MAX) { - pr_err("%s: Invalid params_length\n", __func__); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { + pr_err("%s: Invalid port_idx 0x%x\n", __func__, port_idx); return -EINVAL; } - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s: adm params memory alloc failed", __func__); - return -ENOMEM; + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_idx 0x%x\n", __func__, copp_idx); + return -EINVAL; } - memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_get_pp_params_v5)), - params, params_length); - adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - adm_params->hdr.pkt_size = sz; - adm_params->hdr.src_svc = APR_SVC_ADM; - adm_params->hdr.src_domain = APR_DOMAIN_APPS; - adm_params->hdr.src_port = port_id; - adm_params->hdr.dest_svc = APR_SVC_ADM; - adm_params->hdr.dest_domain = APR_DOMAIN_ADSP; - adm_params->hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - adm_params->hdr.token = port_idx << 16 | client_id << 8 | copp_idx; - adm_params->hdr.opcode = ADM_CMD_GET_PP_PARAMS_V5; - adm_params->data_payload_addr_lsw = 0; - adm_params->data_payload_addr_msw = 0; - adm_params->mem_map_handle = 0; - adm_params->module_id = module_id; - adm_params->param_id = param_id; - adm_params->param_max_size = params_length; - adm_params->reserved = 0; + memset(&adm_get_params, 0, sizeof(adm_get_params)); - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); - if (rc < 0) { - pr_err("%s: Failed to Get Params on port_id 0x%x %d\n", - __func__, port_id, rc); - rc = -EINVAL; - goto adm_get_param_return; + if (mem_hdr != NULL) + adm_get_params.mem_hdr = *mem_hdr; + + q6common_pack_pp_params((u8 *) &adm_get_params.param_hdr, param_hdr, + NULL, &total_size); + + /* Pack APR header after filling body so total_size has correct value */ + adm_get_params.apr_hdr.pkt_size = total_size; + adm_get_params.apr_hdr.src_svc = APR_SVC_ADM; + adm_get_params.apr_hdr.src_domain = APR_DOMAIN_APPS; + adm_get_params.apr_hdr.src_port = port_id; + adm_get_params.apr_hdr.dest_svc = APR_SVC_ADM; + adm_get_params.apr_hdr.dest_domain = APR_DOMAIN_ADSP; + adm_get_params.apr_hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + adm_get_params.apr_hdr.token = + port_idx << 16 | client_id << 8 | copp_idx; + + if (q6common_is_instance_id_supported()) + adm_get_params.apr_hdr.opcode = ADM_CMD_GET_PP_PARAMS_V6; + else + adm_get_params.apr_hdr.opcode = ADM_CMD_GET_PP_PARAMS_V5; + + copp_stat = &this_adm.copp.stat[port_idx][copp_idx]; + atomic_set(copp_stat, -1); + ret = apr_send_pkt(this_adm.apr, (uint32_t *) &adm_get_params); + if (ret) { + pr_err("%s: Get params APR send failed port = 0x%x ret %d\n", + __func__, port_id, ret); + ret = -EINVAL; + goto done; } - /* Wait for the callback with copp id */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: get params timed out port_id = 0x%x\n", __func__, - port_id); - rc = -EINVAL; - goto adm_get_param_return; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto adm_get_param_return; + ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(copp_stat) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Get params timed out port = 0x%x\n", __func__, + port_id); + ret = -ETIMEDOUT; + goto done; + } + if (atomic_read(copp_stat) > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(atomic_read(copp_stat))); + ret = adsp_err_get_lnx_err_code(atomic_read(copp_stat)); + goto done; } - idx = ADM_GET_PARAMETER_LENGTH * copp_idx; - if (adm_get_parameters[idx] < 0) { - pr_err("%s: Size is invalid %d\n", __func__, - adm_get_parameters[idx]); - rc = -EINVAL; - goto adm_get_param_return; - } - if ((params_data) && - (ARRAY_SIZE(adm_get_parameters) > - idx) && - (ARRAY_SIZE(adm_get_parameters) >= - 1+adm_get_parameters[idx]+idx) && - (params_length/sizeof(uint32_t) >= - adm_get_parameters[idx])) { - for (i = 0; i < adm_get_parameters[idx]; i++) - params_data[i] = adm_get_parameters[1+i+idx]; + ret = 0; - } else { - pr_err("%s: Get param data not copied! get_param array size %zd, index %d, params array size %zd, index %d\n", - __func__, ARRAY_SIZE(adm_get_parameters), - (1+adm_get_parameters[idx]+idx), - params_length/sizeof(int), - adm_get_parameters[idx]); + /* Copy data to caller if sent in band */ + if (!returned_param_data) { + pr_debug("%s: Received NULL pointer for param destination, not copying payload\n", + __func__); + return 0; } - rc = 0; -adm_get_param_return: - kfree(adm_params); - return rc; -} + idx = ADM_GET_PARAMETER_LENGTH * copp_idx; + returned_param_size = adm_get_parameters[idx]; + if (returned_param_size < 0 || + returned_param_size + idx + 1 > get_param_array_sz) { + pr_err("%s: Invalid parameter size %d\n", __func__, + returned_param_size); + return -EINVAL; + } -/** - * adm_get_params - - * command to retrieve ADM params for given module - * - * @port_id: Port ID number - * @copp_idx: copp index of ADM copp - * @module_id: module ID - * @param_id: Param index - * @param_length: length of params - * @params: params pointer - * - * Returns 0 on success or error on failure - */ -int adm_get_params(int port_id, int copp_idx, uint32_t module_id, - uint32_t param_id, uint32_t params_length, char *params) -{ - return adm_get_params_v2(port_id, copp_idx, module_id, param_id, - params_length, params, 0); + returned_param_size_in_bytes = returned_param_size * sizeof(uint32_t); + if (param_hdr->param_size < returned_param_size_in_bytes) { + pr_err("%s: Provided buffer is not big enough, provided buffer size(%d) size needed(%d)\n", + __func__, param_hdr->param_size, + returned_param_size_in_bytes); + return -EINVAL; + } + + memcpy(returned_param_data, &adm_get_parameters[idx + 1], + returned_param_size_in_bytes); +done: + return ret; } -EXPORT_SYMBOL(adm_get_params); +EXPORT_SYMBOL(adm_get_pp_params); -/** - * adm_get_pp_topo_module_list - - * command to update PP top module list - * - * @port_id: Port ID number - * @copp_idx: copp index of ADM copp - * @param_length: length of params - * @params: pointer with PP top module params - * - * Returns 0 on success or error on failure - */ int adm_get_pp_topo_module_list(int port_id, int copp_idx, int32_t param_length, char *params) { - struct adm_cmd_get_pp_topo_module_list_t *adm_pp_module_list = NULL; - int sz, rc = 0, i = 0; - int port_idx, idx; - int32_t *params_data = (int32_t *)params; + return adm_get_pp_topo_module_list_v2(port_id, copp_idx, param_length, + (int32_t *) params); +} +EXPORT_SYMBOL(adm_get_pp_topo_module_list); + +int adm_get_pp_topo_module_list_v2(int port_id, int copp_idx, + int32_t param_length, + int32_t *returned_params) +{ + struct adm_cmd_get_pp_topo_module_list adm_get_module_list; + bool iid_supported = q6common_is_instance_id_supported(); int *topo_list; + int num_modules = 0; + int list_size = 0; + int port_idx, idx; + int i = 0; + atomic_t *copp_stat = NULL; + int ret = 0; pr_debug("%s : port_id %x", __func__, port_id); port_id = afe_convert_virtual_to_portid(port_id); @@ -1284,81 +1117,96 @@ int adm_get_pp_topo_module_list(int port_id, int copp_idx, int32_t param_length, return -EINVAL; } - sz = sizeof(struct adm_cmd_get_pp_topo_module_list_t) + param_length; - adm_pp_module_list = kzalloc(sz, GFP_KERNEL); - if (!adm_pp_module_list) { - pr_err("%s, adm params memory alloc failed", __func__); - return -ENOMEM; - } + memset(&adm_get_module_list, 0, sizeof(adm_get_module_list)); - memcpy(((u8 *)adm_pp_module_list + - sizeof(struct adm_cmd_get_pp_topo_module_list_t)), - params, param_length); - adm_pp_module_list->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - adm_pp_module_list->hdr.pkt_size = sz; - adm_pp_module_list->hdr.src_svc = APR_SVC_ADM; - adm_pp_module_list->hdr.src_domain = APR_DOMAIN_APPS; - adm_pp_module_list->hdr.src_port = port_id; - adm_pp_module_list->hdr.dest_svc = APR_SVC_ADM; - adm_pp_module_list->hdr.dest_domain = APR_DOMAIN_ADSP; - adm_pp_module_list->hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - adm_pp_module_list->hdr.token = port_idx << 16 | copp_idx; - adm_pp_module_list->hdr.opcode = ADM_CMD_GET_PP_TOPO_MODULE_LIST; - adm_pp_module_list->param_max_size = param_length; - /* Payload address and mmap handle set to zero by kzalloc */ + adm_get_module_list.apr_hdr.pkt_size = sizeof(adm_get_module_list); + adm_get_module_list.apr_hdr.src_svc = APR_SVC_ADM; + adm_get_module_list.apr_hdr.src_domain = APR_DOMAIN_APPS; + adm_get_module_list.apr_hdr.src_port = port_id; + adm_get_module_list.apr_hdr.dest_svc = APR_SVC_ADM; + adm_get_module_list.apr_hdr.dest_domain = APR_DOMAIN_ADSP; + adm_get_module_list.apr_hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + adm_get_module_list.apr_hdr.token = port_idx << 16 | copp_idx; + /* + * Out of band functionality is not currently utilized. + * Assume in band. + */ + if (iid_supported) { + adm_get_module_list.apr_hdr.opcode = + ADM_CMD_GET_PP_TOPO_MODULE_LIST_V2; + adm_get_module_list.param_max_size = param_length; + } else { + adm_get_module_list.apr_hdr.opcode = + ADM_CMD_GET_PP_TOPO_MODULE_LIST; - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + if (param_length > U16_MAX) { + pr_err("%s: Invalid param length for V1 %d\n", __func__, + param_length); + return -EINVAL; + } + adm_get_module_list.param_max_size = param_length << 16; + } - rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_pp_module_list); - if (rc < 0) { - pr_err("%s: Failed to Get Params on port %d\n", __func__, - port_id); - rc = -EINVAL; - goto adm_pp_module_list_l; + copp_stat = &this_adm.copp.stat[port_idx][copp_idx]; + atomic_set(copp_stat, -1); + ret = apr_send_pkt(this_adm.apr, (uint32_t *) &adm_get_module_list); + if (ret) { + pr_err("%s: APR send pkt failed for port_id: 0x%x failed ret %d\n", + __func__, port_id, ret); + ret = -EINVAL; + goto done; } - /* Wait for the callback with copp id */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: get params timed out port = %d\n", __func__, - port_id); - rc = -EINVAL; - goto adm_pp_module_list_l; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto adm_pp_module_list_l; - } - if (params_data) { - idx = ADM_GET_TOPO_MODULE_LIST_LENGTH * copp_idx; - topo_list = (int *)(adm_module_topo_list + idx); - if (param_length <= ADM_GET_TOPO_MODULE_LIST_LENGTH && - idx < - (MAX_COPPS_PER_PORT * ADM_GET_TOPO_MODULE_LIST_LENGTH)) - memcpy(params_data, topo_list, param_length); - else - pr_debug("%s: i/p size:%d > MAX param size:%d\n", - __func__, param_length, - (int)ADM_GET_TOPO_MODULE_LIST_LENGTH); - for (i = 1; i <= params_data[0]; i++) - pr_debug("module = 0x%x\n", params_data[i]); + ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(copp_stat) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Timeout for port_id: 0x%x\n", __func__, port_id); + ret = -ETIMEDOUT; + goto done; } - rc = 0; -adm_pp_module_list_l: - kfree(adm_pp_module_list); - pr_debug("%s : rc = %d ", __func__, rc); - return rc; + if (atomic_read(copp_stat) > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(atomic_read(copp_stat))); + ret = adsp_err_get_lnx_err_code(atomic_read(copp_stat)); + goto done; + } + + ret = 0; + + if (returned_params) { + /* + * When processing ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST IID is + * added since it is not present. Therefore, there is no need to + * do anything different if IID is not supported here as it is + * already taken care of. + */ + idx = ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH * copp_idx; + num_modules = adm_module_topo_list[idx]; + if (num_modules < 0 || num_modules > MAX_MODULES_IN_TOPO) { + pr_err("%s: Invalid number of modules returned %d\n", + __func__, num_modules); + return -EINVAL; + } + + list_size = num_modules * sizeof(struct module_instance_info); + if (param_length < list_size) { + pr_err("%s: Provided buffer not big enough to hold module-instance list, provided size %d, needed size %d\n", + __func__, param_length, list_size); + return -EINVAL; + } + + topo_list = (int32_t *) (&adm_module_topo_list[idx]); + memcpy(returned_params, topo_list, list_size); + for (i = 1; i <= num_modules; i += 2) { + pr_debug("module = 0x%x instance = 0x%x\n", + returned_params[i], returned_params[i + 1]); + } + } +done: + return ret; } -EXPORT_SYMBOL(adm_get_pp_topo_module_list); +EXPORT_SYMBOL(adm_get_pp_topo_module_list_v2); static void adm_callback_debug_print(struct apr_client_data *data) { @@ -1440,6 +1288,114 @@ int adm_get_multi_ch_map(char *channel_map, int path) } EXPORT_SYMBOL(adm_get_multi_ch_map); +static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload, + u32 payload_size) +{ + struct adm_cmd_rsp_get_pp_params_v5 *v5_rsp = NULL; + struct adm_cmd_rsp_get_pp_params_v6 *v6_rsp = NULL; + u32 *param_data = NULL; + int data_size = 0; + int struct_size = 0; + + if (payload == NULL) { + pr_err("%s: Payload is NULL\n", __func__); + return -EINVAL; + } + + switch (opcode) { + case ADM_CMDRSP_GET_PP_PARAMS_V5: + struct_size = sizeof(struct adm_cmd_rsp_get_pp_params_v5); + v5_rsp = (struct adm_cmd_rsp_get_pp_params_v5 *) payload; + data_size = v5_rsp->param_hdr.param_size; + param_data = v5_rsp->param_data; + break; + case ADM_CMDRSP_GET_PP_PARAMS_V6: + struct_size = sizeof(struct adm_cmd_rsp_get_pp_params_v6); + v6_rsp = (struct adm_cmd_rsp_get_pp_params_v6 *) payload; + data_size = v6_rsp->param_hdr.param_size; + param_data = v6_rsp->param_data; + break; + default: + pr_err("%s: Invalid opcode %d\n", __func__, opcode); + return -EINVAL; + } + + /* + * Just store the returned parameter data, not the header. The calling + * function is expected to know what it asked for. Therefore, there is + * no difference between V5 and V6. + */ + if ((payload_size >= struct_size + data_size) && + (ARRAY_SIZE(adm_get_parameters) > idx) && + (ARRAY_SIZE(adm_get_parameters) >= idx + 1 + data_size)) { + /* + * data_size is expressed in number of bytes, store in number of + * ints + */ + adm_get_parameters[idx] = + data_size / sizeof(*adm_get_parameters); + pr_debug("%s: GET_PP PARAM: received parameter length: 0x%x\n", + __func__, adm_get_parameters[idx]); + /* store params after param_size */ + memcpy(&adm_get_parameters[idx + 1], param_data, data_size); + return 0; + } + + pr_err("%s: Invalid parameter combination, payload_size %d, idx %d\n", + __func__, payload_size, idx); + return -EINVAL; +} + +static int adm_process_get_topo_list_response(u32 opcode, int copp_idx, + u32 num_modules, u32 *payload, + u32 payload_size) +{ + u32 *fill_list = NULL; + int idx = 0; + int i = 0; + int j = 0; + + if (payload == NULL) { + pr_err("%s: Payload is NULL\n", __func__); + return -EINVAL; + } else if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid COPP index %d\n", __func__, copp_idx); + return -EINVAL; + } + + idx = ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH * copp_idx; + fill_list = adm_module_topo_list + idx; + *fill_list++ = num_modules; + for (i = 0; i < num_modules; i++) { + if (j > payload_size / sizeof(u32)) { + pr_err("%s: Invalid number of modules specified %d\n", + __func__, num_modules); + return -EINVAL; + } + + /* store module ID */ + *fill_list++ = payload[j]; + j++; + + switch (opcode) { + case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST_V2: + /* store instance ID */ + *fill_list++ = payload[j]; + j++; + break; + case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST: + /* Insert IID 0 when repacking */ + *fill_list++ = INSTANCE_ID_0; + break; + default: + pr_err("%s: Invalid opcode %d\n", __func__, opcode); + return -EINVAL; + } + } + + return 0; +} + static void adm_reset_data(void) { int i, j; @@ -1501,7 +1457,9 @@ static void adm_reset_data(void) static int32_t adm_callback(struct apr_client_data *data, void *priv) { uint32_t *payload; - int i, port_idx, copp_idx, idx, client_id; + int port_idx, copp_idx, idx, client_id; + int num_modules; + int ret; if (data == NULL) { pr_err("%s: data parameter is null\n", __func__); @@ -1548,8 +1506,9 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) } switch (payload[0]) { case ADM_CMD_SET_PP_PARAMS_V5: - pr_debug("%s: ADM_CMD_SET_PP_PARAMS_V5\n", - __func__); + case ADM_CMD_SET_PP_PARAMS_V6: + pr_debug("%s: ADM_CMD_SET_PP_PARAMS\n", + __func__); if (client_id == ADM_CLIENT_ID_SOURCE_TRACKING) this_adm.sourceTrackingData. apr_cmd_status = payload[1]; @@ -1605,8 +1564,9 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) } break; case ADM_CMD_GET_PP_PARAMS_V5: - pr_debug("%s: ADM_CMD_GET_PP_PARAMS_V5\n", - __func__); + case ADM_CMD_GET_PP_PARAMS_V6: + pr_debug("%s: ADM_CMD_GET_PP_PARAMS\n", + __func__); /* Should only come here if there is an APR */ /* error or malformed APR packet. Otherwise */ /* response will be returned as */ @@ -1643,11 +1603,12 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) &this_adm.copp.wait[port_idx][copp_idx]); break; case ADM_CMD_GET_PP_TOPO_MODULE_LIST: + case ADM_CMD_GET_PP_TOPO_MODULE_LIST_V2: pr_debug("%s:ADM_CMD_GET_PP_TOPO_MODULE_LIST\n", __func__); if (payload[1] != 0) - pr_err("%s: ADM get topo list error = %d,\n", - __func__, payload[1]); + pr_err("%s: ADM get topo list error = %d\n", + __func__, payload[1]); break; default: pr_err("%s: Unknown Cmd: 0x%x\n", __func__, @@ -1682,80 +1643,60 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) } break; case ADM_CMDRSP_GET_PP_PARAMS_V5: - pr_debug("%s: ADM_CMDRSP_GET_PP_PARAMS_V5\n", __func__); - if (payload[0] != 0) - pr_err("%s: ADM_CMDRSP_GET_PP_PARAMS_V5 returned error = 0x%x\n", - __func__, payload[0]); + case ADM_CMDRSP_GET_PP_PARAMS_V6: + pr_debug("%s: ADM_CMDRSP_GET_PP_PARAMS\n", __func__); if (client_id == ADM_CLIENT_ID_SOURCE_TRACKING) this_adm.sourceTrackingData.apr_cmd_status = - payload[0]; + payload[0]; else if (rtac_make_adm_callback(payload, - data->payload_size)) + data->payload_size)) break; idx = ADM_GET_PARAMETER_LENGTH * copp_idx; - if ((payload[0] == 0) && (data->payload_size > - (4 * sizeof(*payload))) && - (data->payload_size - 4 >= - payload[3]) && - (ARRAY_SIZE(adm_get_parameters) > - idx) && - (ARRAY_SIZE(adm_get_parameters)-idx-1 >= - payload[3])) { - adm_get_parameters[idx] = payload[3] / - sizeof(uint32_t); - /* - * payload[3] is param_size which is - * expressed in number of bytes - */ - pr_debug("%s: GET_PP PARAM:received parameter length: 0x%x\n", - __func__, adm_get_parameters[idx]); - /* storing param size then params */ - for (i = 0; i < payload[3] / - sizeof(uint32_t); i++) - adm_get_parameters[idx+1+i] = - payload[4+i]; - } else if (payload[0] == 0) { + if (payload[0] == 0 && data->payload_size > 0) { + pr_debug("%s: Received parameter data in band\n", + __func__); + ret = adm_process_get_param_response( + data->opcode, idx, payload, + data->payload_size); + if (ret) + pr_err("%s: Failed to process get param response, error %d\n", + __func__, ret); + } else if (payload[0] == 0 && data->payload_size == 0) { adm_get_parameters[idx] = -1; - pr_err("%s: Out of band case, setting size to %d\n", + pr_debug("%s: Out of band case, setting size to %d\n", __func__, adm_get_parameters[idx]); } else { adm_get_parameters[idx] = -1; - pr_err("%s: GET_PP_PARAMS failed, setting size to %d\n", - __func__, adm_get_parameters[idx]); + pr_err("%s: ADM_CMDRSP_GET_PP_PARAMS returned error 0x%x\n", + __func__, payload[0]); } - atomic_set(&this_adm.copp.stat - [port_idx][copp_idx], payload[0]); + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], + payload[0]); wake_up(&this_adm.copp.wait[port_idx][copp_idx]); break; case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST: + case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST_V2: pr_debug("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST\n", __func__); - if (payload[0] != 0) { - pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST", - __func__); - pr_err(":err = 0x%x\n", payload[0]); - } else if (payload[1] > - ((ADM_GET_TOPO_MODULE_LIST_LENGTH / - sizeof(uint32_t)) - 1)) { - pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST", - __func__); - pr_err(":size = %d\n", payload[1]); + num_modules = payload[1]; + pr_debug("%s: Num modules %d\n", __func__, num_modules); + if (payload[0]) { + pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST, error = %d\n", + __func__, payload[0]); + } else if (num_modules > MAX_MODULES_IN_TOPO) { + pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST invalid num modules received, num modules = %d\n", + __func__, num_modules); } else { - idx = ADM_GET_TOPO_MODULE_LIST_LENGTH * - copp_idx; - pr_debug("%s:Num modules payload[1] %d\n", - __func__, payload[1]); - adm_module_topo_list[idx] = payload[1]; - for (i = 1; i <= payload[1]; i++) { - adm_module_topo_list[idx+i] = - payload[1+i]; - pr_debug("%s:payload[%d] = %x\n", - __func__, (i+1), payload[1+i]); - } + ret = adm_process_get_topo_list_response( + data->opcode, copp_idx, num_modules, + payload, data->payload_size); + if (ret) + pr_err("%s: Failed to process get topo modules list response, error %d\n", + __func__, ret); } - atomic_set(&this_adm.copp.stat - [port_idx][copp_idx], payload[0]); + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], + payload[0]); wake_up(&this_adm.copp.wait[port_idx][copp_idx]); break; case ADM_CMDRSP_SHARED_MEM_MAP_REGIONS: @@ -2036,21 +1977,16 @@ static void send_adm_custom_topology(void) } static int send_adm_cal_block(int port_id, int copp_idx, - struct cal_block_data *cal_block, int perf_mode, - int app_type, int acdb_id, int sample_rate) + struct cal_block_data *cal_block, int perf_mode) { - s32 result = 0; - struct adm_cmd_set_pp_params_v5 adm_params; - int port_idx; + struct mem_mapping_hdr mem_hdr; + int payload_size = 0; + int port_idx = 0; + int topology = 0; + int result = 0; + + pr_debug("%s: Port id 0x%x,\n", __func__, port_id); - pr_debug("%s: Port id 0x%x sample_rate %d ,\n", __func__, - port_id, sample_rate); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); - return -EINVAL; - } if (!cal_block) { pr_debug("%s: No ADM cal to send for port_id = 0x%x!\n", __func__, port_id); @@ -2058,76 +1994,40 @@ static int send_adm_cal_block(int port_id, int copp_idx, goto done; } if (cal_block->cal_data.size <= 0) { - pr_debug("%s: No ADM cal send for port_id = 0x%x!\n", - __func__, port_id); + pr_debug("%s: No ADM cal sent for port_id = 0x%x!\n", __func__, + port_id); result = -EINVAL; goto done; } - if (perf_mode == LEGACY_PCM_MODE && - ((atomic_read(&this_adm.copp.topology[port_idx][copp_idx])) == - DS2_ADM_COPP_TOPOLOGY_ID)) { - pr_err("%s: perf_mode %d, topology 0x%x\n", __func__, perf_mode, - atomic_read( - &this_adm.copp.topology[port_idx][copp_idx])); - goto done; - } - - adm_params.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(20), APR_PKT_VER); - adm_params.hdr.pkt_size = sizeof(adm_params); - adm_params.hdr.src_svc = APR_SVC_ADM; - adm_params.hdr.src_domain = APR_DOMAIN_APPS; - adm_params.hdr.src_port = port_id; - adm_params.hdr.dest_svc = APR_SVC_ADM; - adm_params.hdr.dest_domain = APR_DOMAIN_ADSP; - - adm_params.hdr.token = port_idx << 16 | copp_idx; - adm_params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - adm_params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - adm_params.payload_addr_lsw = lower_32_bits(cal_block->cal_data.paddr); - adm_params.payload_addr_msw = msm_audio_populate_upper_32_bits( - cal_block->cal_data.paddr); - adm_params.mem_map_handle = cal_block->map_data.q6map_handle; - adm_params.payload_size = cal_block->cal_data.size; - - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - pr_debug("%s: Sending SET_PARAMS payload = 0x%pK, size = %d\n", - __func__, &cal_block->cal_data.paddr, - adm_params.payload_size); - result = apr_send_pkt(this_adm.apr, (uint32_t *)&adm_params); - if (result < 0) { - pr_err("%s: Set params failed port 0x%x result %d\n", - __func__, port_id, result); - pr_debug("%s: Set params failed port = 0x%x payload = 0x%pK result %d\n", - __func__, port_id, &cal_block->cal_data.paddr, result); - result = -EINVAL; - goto done; - } - /* Wait for the callback */ - result = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!result) { - pr_err("%s: Set params timed out port = 0x%x\n", - __func__, port_id); - pr_debug("%s: Set params timed out port = 0x%x, payload = 0x%pK\n", - __func__, port_id, &cal_block->cal_data.paddr); - result = -EINVAL; - goto done; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - result = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); + memset(&mem_hdr, 0, sizeof(mem_hdr)); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + return -EINVAL; + } else if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_idx 0x%x\n", __func__, copp_idx); + return -EINVAL; + } + + topology = atomic_read(&this_adm.copp.topology[port_idx][copp_idx]); + if (perf_mode == LEGACY_PCM_MODE && + topology == DS2_ADM_COPP_TOPOLOGY_ID) { + pr_err("%s: perf_mode %d, topology 0x%x\n", __func__, perf_mode, + topology); goto done; } + mem_hdr.data_payload_addr_lsw = + lower_32_bits(cal_block->cal_data.paddr); + mem_hdr.data_payload_addr_msw = + msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr); + mem_hdr.mem_map_handle = cal_block->map_data.q6map_handle; + payload_size = cal_block->cal_data.size; + + adm_set_pp_params(port_id, copp_idx, &mem_hdr, NULL, payload_size); + done: return result; } @@ -2255,8 +2155,7 @@ static int adm_remap_and_send_cal_block(int cal_index, int port_id, __func__, cal_index); goto done; } - ret = send_adm_cal_block(port_id, copp_idx, cal_block, perf_mode, - app_type, acdb_id, sample_rate); + ret = send_adm_cal_block(port_id, copp_idx, cal_block, perf_mode); if (ret < 0) pr_debug("%s: No cal sent for cal_index %d, port_id = 0x%x! ret %d sample_rate %d\n", __func__, cal_index, port_id, ret, sample_rate); @@ -2808,10 +2707,10 @@ EXPORT_SYMBOL(adm_open); */ void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate) { - struct audproc_mfc_output_media_fmt mfc_cfg; + struct audproc_mfc_param_media_fmt mfc_cfg; struct adm_cmd_device_open_v5 open; + struct param_hdr_v3 param_hdr; int port_idx; - int sz = 0; int rc = 0; int i = 0; @@ -2828,32 +2727,15 @@ void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate) goto fail_cmd; } - sz = sizeof(struct audproc_mfc_output_media_fmt); + memset(&mfc_cfg, 0, sizeof(mfc_cfg)); + memset(&open, 0, sizeof(open)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AUDPROC_MODULE_ID_MFC; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; + param_hdr.param_size = sizeof(mfc_cfg); - mfc_cfg.params.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - mfc_cfg.params.hdr.pkt_size = sz; - mfc_cfg.params.hdr.src_svc = APR_SVC_ADM; - mfc_cfg.params.hdr.src_domain = APR_DOMAIN_APPS; - mfc_cfg.params.hdr.src_port = port_id; - mfc_cfg.params.hdr.dest_svc = APR_SVC_ADM; - mfc_cfg.params.hdr.dest_domain = APR_DOMAIN_ADSP; - mfc_cfg.params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - mfc_cfg.params.hdr.token = port_idx << 16 | copp_idx; - mfc_cfg.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - mfc_cfg.params.payload_addr_lsw = 0; - mfc_cfg.params.payload_addr_msw = 0; - mfc_cfg.params.mem_map_handle = 0; - mfc_cfg.params.payload_size = sizeof(mfc_cfg) - - sizeof(mfc_cfg.params); - mfc_cfg.data.module_id = AUDPROC_MODULE_ID_MFC; - mfc_cfg.data.param_id = - AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; - mfc_cfg.data.param_size = mfc_cfg.params.payload_size - - sizeof(mfc_cfg.data); - mfc_cfg.data.reserved = 0; mfc_cfg.sampling_rate = dst_sample_rate; mfc_cfg.bits_per_sample = atomic_read(&this_adm.copp.bit_width[port_idx][copp_idx]); @@ -2879,31 +2761,12 @@ void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate) mfc_cfg.bits_per_sample, mfc_cfg.num_channels, mfc_cfg.sampling_rate); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)&mfc_cfg); + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &mfc_cfg); + if (rc) + pr_err("%s: Failed to set media format configuration data, err %d\n", + __func__, rc); - if (rc < 0) { - pr_err("%s: port_id: for[0x%x] failed %d\n", - __func__, port_id, rc); - goto fail_cmd; - } - /* Wait for the callback with copp id */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: mfc_cfg Set params timed out for port_id: for [0x%x]\n", - __func__, port_id); - goto fail_cmd; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - goto fail_cmd; - } - rc = 0; fail_cmd: return; } @@ -3727,79 +3590,25 @@ static int adm_init_cal_data(void) int adm_set_volume(int port_id, int copp_idx, int volume) { struct audproc_volume_ctrl_master_gain audproc_vol; - int sz = 0; + struct param_hdr_v3 param_hdr; int rc = 0; - int port_idx; pr_debug("%s: port_id %d, volume %d\n", __func__, port_id, volume); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id %#x\n", __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } - if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { - pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); - return -EINVAL; - } + memset(&audproc_vol, 0, sizeof(audproc_vol)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_VOL_CTRL; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_VOL_CTRL_MASTER_GAIN; + param_hdr.param_size = sizeof(audproc_vol); - sz = sizeof(struct audproc_volume_ctrl_master_gain); - audproc_vol.params.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - audproc_vol.params.hdr.pkt_size = sz; - audproc_vol.params.hdr.src_svc = APR_SVC_ADM; - audproc_vol.params.hdr.src_domain = APR_DOMAIN_APPS; - audproc_vol.params.hdr.src_port = port_id; - audproc_vol.params.hdr.dest_svc = APR_SVC_ADM; - audproc_vol.params.hdr.dest_domain = APR_DOMAIN_ADSP; - audproc_vol.params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - audproc_vol.params.hdr.token = port_idx << 16 | copp_idx; - audproc_vol.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - audproc_vol.params.payload_addr_lsw = 0; - audproc_vol.params.payload_addr_msw = 0; - audproc_vol.params.mem_map_handle = 0; - audproc_vol.params.payload_size = sizeof(audproc_vol) - - sizeof(audproc_vol.params); - audproc_vol.data.module_id = AUDPROC_MODULE_ID_VOL_CTRL; - audproc_vol.data.param_id = AUDPROC_PARAM_ID_VOL_CTRL_MASTER_GAIN; - audproc_vol.data.param_size = audproc_vol.params.payload_size - - sizeof(audproc_vol.data); - audproc_vol.data.reserved = 0; audproc_vol.master_gain = volume; - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)&audproc_vol); - if (rc < 0) { - pr_err("%s: Set params failed port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } - /* Wait for the callback */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: Vol cntrl Set params timed out port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto fail_cmd; - } - rc = 0; -fail_cmd: + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &audproc_vol); + if (rc) + pr_err("%s: Failed to set volume, err %d\n", __func__, rc); + return rc; } EXPORT_SYMBOL(adm_set_volume); @@ -3818,53 +3627,20 @@ int adm_set_softvolume(int port_id, int copp_idx, struct audproc_softvolume_params *softvol_param) { struct audproc_soft_step_volume_params audproc_softvol; - int sz = 0; + struct param_hdr_v3 param_hdr; int rc = 0; - int port_idx; pr_debug("%s: period %d step %d curve %d\n", __func__, softvol_param->period, softvol_param->step, softvol_param->rampingcurve); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id %#x\n", __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } - - if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { - pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); - return -EINVAL; - } - - sz = sizeof(struct audproc_soft_step_volume_params); + memset(&audproc_softvol, 0, sizeof(audproc_softvol)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_VOL_CTRL; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS; + param_hdr.param_size = sizeof(audproc_softvol); - audproc_softvol.params.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - audproc_softvol.params.hdr.pkt_size = sz; - audproc_softvol.params.hdr.src_svc = APR_SVC_ADM; - audproc_softvol.params.hdr.src_domain = APR_DOMAIN_APPS; - audproc_softvol.params.hdr.src_port = port_id; - audproc_softvol.params.hdr.dest_svc = APR_SVC_ADM; - audproc_softvol.params.hdr.dest_domain = APR_DOMAIN_ADSP; - audproc_softvol.params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - audproc_softvol.params.hdr.token = port_idx << 16 | copp_idx; - audproc_softvol.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - audproc_softvol.params.payload_addr_lsw = 0; - audproc_softvol.params.payload_addr_msw = 0; - audproc_softvol.params.mem_map_handle = 0; - audproc_softvol.params.payload_size = sizeof(audproc_softvol) - - sizeof(audproc_softvol.params); - audproc_softvol.data.module_id = AUDPROC_MODULE_ID_VOL_CTRL; - audproc_softvol.data.param_id = - AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS; - audproc_softvol.data.param_size = audproc_softvol.params.payload_size - - sizeof(audproc_softvol.data); - audproc_softvol.data.reserved = 0; audproc_softvol.period = softvol_param->period; audproc_softvol.step = softvol_param->step; audproc_softvol.ramping_curve = softvol_param->rampingcurve; @@ -3873,36 +3649,11 @@ int adm_set_softvolume(int port_id, int copp_idx, audproc_softvol.period, audproc_softvol.step, audproc_softvol.ramping_curve); - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)&audproc_softvol); - if (rc < 0) { - pr_err("%s: Set params failed port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } - /* Wait for the callback */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: Soft volume Set params timed out port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto fail_cmd; - } - rc = 0; -fail_cmd: + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &audproc_softvol); + if (rc) + pr_err("%s: Failed to set soft volume, err %d\n", __func__, rc); + return rc; } EXPORT_SYMBOL(adm_set_softvolume); @@ -3919,79 +3670,27 @@ EXPORT_SYMBOL(adm_set_softvolume); */ int adm_set_mic_gain(int port_id, int copp_idx, int volume) { - struct adm_set_mic_gain_params mic_gain_params; + struct admx_mic_gain mic_gain_params; + struct param_hdr_v3 param_hdr; int rc = 0; - int sz, port_idx; - pr_debug("%s:\n", __func__); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); - return -EINVAL; - } + pr_debug("%s: Setting mic gain to %d at port_id 0x%x\n", __func__, + volume, port_id); - sz = sizeof(struct adm_set_mic_gain_params); + memset(&mic_gain_params, 0, sizeof(mic_gain_params)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = ADM_MODULE_IDX_MIC_GAIN_CTRL; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = ADM_PARAM_IDX_MIC_GAIN; + param_hdr.param_size = sizeof(mic_gain_params); - mic_gain_params.params.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - mic_gain_params.params.hdr.pkt_size = sz; - mic_gain_params.params.hdr.src_svc = APR_SVC_ADM; - mic_gain_params.params.hdr.src_domain = APR_DOMAIN_APPS; - mic_gain_params.params.hdr.src_port = port_id; - mic_gain_params.params.hdr.dest_svc = APR_SVC_ADM; - mic_gain_params.params.hdr.dest_domain = APR_DOMAIN_ADSP; - mic_gain_params.params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - mic_gain_params.params.hdr.token = port_idx << 16 | copp_idx; - mic_gain_params.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - mic_gain_params.params.payload_addr_lsw = 0; - mic_gain_params.params.payload_addr_msw = 0; - mic_gain_params.params.mem_map_handle = 0; - mic_gain_params.params.payload_size = - sizeof(struct adm_param_data_v5) + - sizeof(struct admx_mic_gain); - mic_gain_params.data.module_id = ADM_MODULE_IDX_MIC_GAIN_CTRL; - mic_gain_params.data.param_id = ADM_PARAM_IDX_MIC_GAIN; - mic_gain_params.data.param_size = - sizeof(struct admx_mic_gain); - mic_gain_params.data.reserved = 0; - mic_gain_params.mic_gain_data.tx_mic_gain = volume; - mic_gain_params.mic_gain_data.reserved = 0; - pr_debug("%s: Mic Gain set to %d at port_id 0x%x\n", - __func__, volume, port_id); + mic_gain_params.tx_mic_gain = volume; + + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &mic_gain_params); + if (rc) + pr_err("%s: Failed to set mic gain, err %d\n", __func__, rc); - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)&mic_gain_params); - if (rc < 0) { - pr_err("%s: Set params failed port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } - /* Wait for the callback */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: Mic Gain Set params timed out port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto fail_cmd; - } - rc = 0; -fail_cmd: return rc; } EXPORT_SYMBOL(adm_set_mic_gain); @@ -4009,88 +3708,29 @@ EXPORT_SYMBOL(adm_set_mic_gain); int adm_send_set_multichannel_ec_primary_mic_ch(int port_id, int copp_idx, int primary_mic_ch) { - struct adm_set_sec_primary_ch_params sec_primary_ch_params; + struct admx_sec_primary_mic_ch sec_primary_ch_params; + struct param_hdr_v3 param_hdr; int rc = 0; - int sz, port_idx; pr_debug("%s port_id 0x%x, copp_idx 0x%x, primary_mic_ch %d\n", __func__, port_id, copp_idx, primary_mic_ch); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); - return -EINVAL; - } - if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { - pr_err("%s: Invalid copp_idx 0x%x\n", __func__, copp_idx); - return -EINVAL; - } + memset(&sec_primary_ch_params, 0, sizeof(sec_primary_ch_params)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_VOICE_TX_SECNS; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_IDX_SEC_PRIMARY_MIC_CH; + param_hdr.param_size = sizeof(sec_primary_ch_params); - sz = sizeof(struct adm_set_sec_primary_ch_params); + sec_primary_ch_params.version = 0; + sec_primary_ch_params.sec_primary_mic_ch = primary_mic_ch; - sec_primary_ch_params.params.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - sec_primary_ch_params.params.hdr.pkt_size = sz; - sec_primary_ch_params.params.hdr.src_svc = APR_SVC_ADM; - sec_primary_ch_params.params.hdr.src_domain = APR_DOMAIN_APPS; - sec_primary_ch_params.params.hdr.src_port = port_id; - sec_primary_ch_params.params.hdr.dest_svc = APR_SVC_ADM; - sec_primary_ch_params.params.hdr.dest_domain = APR_DOMAIN_ADSP; - sec_primary_ch_params.params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - sec_primary_ch_params.params.hdr.token = port_idx << 16 | copp_idx; - sec_primary_ch_params.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - sec_primary_ch_params.params.payload_addr_lsw = 0; - sec_primary_ch_params.params.payload_addr_msw = 0; - sec_primary_ch_params.params.mem_map_handle = 0; - sec_primary_ch_params.params.payload_size = - sizeof(struct adm_param_data_v5) + - sizeof(struct admx_sec_primary_mic_ch); - sec_primary_ch_params.data.module_id = - AUDPROC_MODULE_ID_VOICE_TX_SECNS; - sec_primary_ch_params.data.param_id = - AUDPROC_PARAM_IDX_SEC_PRIMARY_MIC_CH; - sec_primary_ch_params.data.param_size = - sizeof(struct admx_sec_primary_mic_ch); - sec_primary_ch_params.data.reserved = 0; - sec_primary_ch_params.sec_primary_mic_ch_data.version = 0; - sec_primary_ch_params.sec_primary_mic_ch_data.reserved = 0; - sec_primary_ch_params.sec_primary_mic_ch_data.sec_primary_mic_ch = - primary_mic_ch; - sec_primary_ch_params.sec_primary_mic_ch_data.reserved1 = 0; + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &sec_primary_ch_params); + if (rc) + pr_err("%s: Failed to set primary mic chanel, err %d\n", + __func__, rc); - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)&sec_primary_ch_params); - if (rc < 0) { - pr_err("%s: Set params failed port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } - /* Wait for the callback */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: Mic Set params timed out port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto fail_cmd; - } - rc = 0; -fail_cmd: return rc; } EXPORT_SYMBOL(adm_send_set_multichannel_ec_primary_mic_ch); @@ -4108,86 +3748,57 @@ EXPORT_SYMBOL(adm_send_set_multichannel_ec_primary_mic_ch); */ int adm_param_enable(int port_id, int copp_idx, int module_id, int enable) { - struct audproc_enable_param_t adm_mod_enable; - int sz = 0; - int rc = 0; - int port_idx; + struct module_instance_info mod_inst_info; - pr_debug("%s port_id %d, module_id 0x%x, enable %d\n", - __func__, port_id, module_id, enable); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id %#x\n", __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } + memset(&mod_inst_info, 0, sizeof(mod_inst_info)); + mod_inst_info.module_id = module_id; + mod_inst_info.instance_id = INSTANCE_ID_0; - if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { - pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); + return adm_param_enable_v2(port_id, copp_idx, mod_inst_info, enable); +} + +/** + * adm_param_enable_v2 - + * command to send params to ADM for given module + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * @mod_inst_info: module and instance ID info + * @enable: flag to enable or disable module + * + * Returns 0 on success or error on failure + */ +int adm_param_enable_v2(int port_id, int copp_idx, + struct module_instance_info mod_inst_info, int enable) +{ + uint32_t enable_param; + struct param_hdr_v3 param_hdr; + int rc = 0; + + if (enable < 0 || enable > 1) { + pr_err("%s: Invalid value for enable %d\n", __func__, enable); return -EINVAL; } - sz = sizeof(struct audproc_enable_param_t); + pr_debug("%s port_id %d, module_id 0x%x, instance_id 0x%x, enable %d\n", + __func__, port_id, mod_inst_info.module_id, + mod_inst_info.instance_id, enable); - adm_mod_enable.pp_params.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - adm_mod_enable.pp_params.hdr.pkt_size = sz; - adm_mod_enable.pp_params.hdr.src_svc = APR_SVC_ADM; - adm_mod_enable.pp_params.hdr.src_domain = APR_DOMAIN_APPS; - adm_mod_enable.pp_params.hdr.src_port = port_id; - adm_mod_enable.pp_params.hdr.dest_svc = APR_SVC_ADM; - adm_mod_enable.pp_params.hdr.dest_domain = APR_DOMAIN_ADSP; - adm_mod_enable.pp_params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - adm_mod_enable.pp_params.hdr.token = port_idx << 16 | copp_idx; - adm_mod_enable.pp_params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - adm_mod_enable.pp_params.payload_addr_lsw = 0; - adm_mod_enable.pp_params.payload_addr_msw = 0; - adm_mod_enable.pp_params.mem_map_handle = 0; - adm_mod_enable.pp_params.payload_size = sizeof(adm_mod_enable) - - sizeof(adm_mod_enable.pp_params) + - sizeof(adm_mod_enable.pp_params.params); - adm_mod_enable.pp_params.params.module_id = module_id; - adm_mod_enable.pp_params.params.param_id = AUDPROC_PARAM_ID_ENABLE; - adm_mod_enable.pp_params.params.param_size = - adm_mod_enable.pp_params.payload_size - - sizeof(adm_mod_enable.pp_params.params); - adm_mod_enable.pp_params.params.reserved = 0; - adm_mod_enable.enable = enable; + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = mod_inst_info.module_id; + param_hdr.instance_id = mod_inst_info.instance_id; + param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE; + param_hdr.param_size = sizeof(enable_param); - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + enable_param = enable; + + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &enable_param); + if (rc) + pr_err("%s: Failed to set enable of module(%d) instance(%d) to %d, err %d\n", + __func__, mod_inst_info.module_id, + mod_inst_info.instance_id, enable, rc); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)&adm_mod_enable); - if (rc < 0) { - pr_err("%s: Set params failed port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } - /* Wait for the callback */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: module %x enable %d timed out on port = %#x\n", - __func__, module_id, enable, port_id); - rc = -EINVAL; - goto fail_cmd; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto fail_cmd; - } - rc = 0; -fail_cmd: return rc; } @@ -4211,25 +3822,10 @@ int adm_send_calibration(int port_id, int copp_idx, int path, int perf_mode, int cal_type, char *params, int size) { - struct adm_cmd_set_pp_params_v5 *adm_params = NULL; - int sz, rc = 0; - int port_idx; - - pr_debug("%s:port_id %d, path %d, perf_mode %d, cal_type %d, size %d\n", - __func__, port_id, path, perf_mode, cal_type, size); - - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id %#x\n", __func__, port_id); - rc = -EINVAL; - goto end; - } + int rc = 0; - if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { - pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); - return -EINVAL; - } + pr_debug("%s:port_id %d, path %d, perf_mode %d, cal_type %d, size %d\n", + __func__, port_id, path, perf_mode, cal_type, size); /* Maps audio_dev_ctrl path definition to ACDB definition */ if (get_cal_path(path) != RX_DEVICE) { @@ -4238,64 +3834,9 @@ int adm_send_calibration(int port_id, int copp_idx, int path, int perf_mode, goto end; } - sz = sizeof(struct adm_cmd_set_pp_params_v5) + size; - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed", __func__); - rc = -ENOMEM; - goto end; - } - - memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_set_pp_params_v5)), - params, size); - - adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - adm_params->hdr.pkt_size = sz; - adm_params->hdr.src_svc = APR_SVC_ADM; - adm_params->hdr.src_domain = APR_DOMAIN_APPS; - adm_params->hdr.src_port = port_id; - adm_params->hdr.dest_svc = APR_SVC_ADM; - adm_params->hdr.dest_domain = APR_DOMAIN_ADSP; - adm_params->hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - adm_params->hdr.token = port_idx << 16 | copp_idx; - adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - /* payload address and mmap handle initialized to zero by kzalloc */ - adm_params->payload_size = size; - - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); - if (rc < 0) { - pr_err("%s: Set params failed port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto end; - } - /* Wait for the callback */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: Set params timed out port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto end; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto end; - } - rc = 0; + rc = adm_set_pp_params(port_id, copp_idx, NULL, (u8 *) params, size); end: - kfree(adm_params); return rc; } EXPORT_SYMBOL(adm_send_calibration); @@ -4526,78 +4067,24 @@ EXPORT_SYMBOL(adm_store_cal_data); */ int adm_send_compressed_device_mute(int port_id, int copp_idx, bool mute_on) { - struct adm_set_compressed_device_mute mute_params; + u32 mute_param = mute_on ? 1 : 0; + struct param_hdr_v3 param_hdr; int ret = 0; - int port_idx; pr_debug("%s port_id: 0x%x, copp_idx %d, mute_on: %d\n", __func__, port_id, copp_idx, mute_on); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { - pr_err("%s: Invalid port_id %#x copp_idx %d\n", - __func__, port_id, copp_idx); - ret = -EINVAL; - goto end; - } - mute_params.command.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - mute_params.command.hdr.pkt_size = - sizeof(struct adm_set_compressed_device_mute); - mute_params.command.hdr.src_svc = APR_SVC_ADM; - mute_params.command.hdr.src_domain = APR_DOMAIN_APPS; - mute_params.command.hdr.src_port = port_id; - mute_params.command.hdr.dest_svc = APR_SVC_ADM; - mute_params.command.hdr.dest_domain = APR_DOMAIN_ADSP; - mute_params.command.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - mute_params.command.hdr.token = port_idx << 16 | copp_idx; - mute_params.command.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - mute_params.command.payload_addr_lsw = 0; - mute_params.command.payload_addr_msw = 0; - mute_params.command.mem_map_handle = 0; - mute_params.command.payload_size = sizeof(mute_params) - - sizeof(mute_params.command); - mute_params.params.module_id = AUDPROC_MODULE_ID_COMPRESSED_MUTE; - mute_params.params.param_id = AUDPROC_PARAM_ID_COMPRESSED_MUTE; - mute_params.params.param_size = mute_params.command.payload_size - - sizeof(mute_params.params); - mute_params.params.reserved = 0; - mute_params.mute_on = mute_on; + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_COMPRESSED_MUTE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_COMPRESSED_MUTE; + param_hdr.param_size = sizeof(mute_param); - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - ret = apr_send_pkt(this_adm.apr, (uint32_t *)&mute_params); - if (ret < 0) { - pr_err("%s: device mute for port %d copp %d failed, ret %d\n", - __func__, port_id, copp_idx, ret); - ret = -EINVAL; - goto end; - } + ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &mute_param); + if (ret) + pr_err("%s: Failed to set mute, err %d\n", __func__, ret); - /* Wait for the callback */ - ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: send device mute for port %d copp %d failed\n", - __func__, port_id, copp_idx); - ret = -EINVAL; - goto end; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto end; - } - ret = 0; -end: return ret; } EXPORT_SYMBOL(adm_send_compressed_device_mute); @@ -4614,78 +4101,31 @@ EXPORT_SYMBOL(adm_send_compressed_device_mute); */ int adm_send_compressed_device_latency(int port_id, int copp_idx, int latency) { - struct adm_set_compressed_device_latency latency_params; - int port_idx; + u32 latency_param; + struct param_hdr_v3 param_hdr; int ret = 0; pr_debug("%s port_id: 0x%x, copp_idx %d latency: %d\n", __func__, port_id, copp_idx, latency); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { - pr_err("%s: Invalid port_id %#x copp_idx %d\n", - __func__, port_id, copp_idx); - ret = -EINVAL; - goto end; + + if (latency < 0) { + pr_err("%s: Invalid value for latency %d", __func__, latency); + return -EINVAL; } - latency_params.command.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - latency_params.command.hdr.pkt_size = - sizeof(struct adm_set_compressed_device_latency); - latency_params.command.hdr.src_svc = APR_SVC_ADM; - latency_params.command.hdr.src_domain = APR_DOMAIN_APPS; - latency_params.command.hdr.src_port = port_id; - latency_params.command.hdr.dest_svc = APR_SVC_ADM; - latency_params.command.hdr.dest_domain = APR_DOMAIN_ADSP; - latency_params.command.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - latency_params.command.hdr.token = port_idx << 16 | copp_idx; - latency_params.command.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - latency_params.command.payload_addr_lsw = 0; - latency_params.command.payload_addr_msw = 0; - latency_params.command.mem_map_handle = 0; - latency_params.command.payload_size = sizeof(latency_params) - - sizeof(latency_params.command); - latency_params.params.module_id = AUDPROC_MODULE_ID_COMPRESSED_LATENCY; - latency_params.params.param_id = AUDPROC_PARAM_ID_COMPRESSED_LATENCY; - latency_params.params.param_size = latency_params.command.payload_size - - sizeof(latency_params.params); - latency_params.params.reserved = 0; - latency_params.latency = latency; + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_COMPRESSED_LATENCY; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_COMPRESSED_LATENCY; + param_hdr.param_size = sizeof(latency_param); - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - ret = apr_send_pkt(this_adm.apr, (uint32_t *)&latency_params); - if (ret < 0) { - pr_err("%s: send device latency err %d for port %d copp %d\n", - __func__, port_id, copp_idx, ret); - ret = -EINVAL; - goto end; - } + latency_param = latency; + + ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &latency_param); + if (ret) + pr_err("%s: Failed to set latency, err %d\n", __func__, ret); - /* Wait for the callback */ - ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: send device latency for port %d failed\n", __func__, - port_id); - ret = -EINVAL; - goto end; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto end; - } - ret = 0; -end: return ret; } EXPORT_SYMBOL(adm_send_compressed_device_latency); @@ -4705,9 +4145,10 @@ EXPORT_SYMBOL(adm_send_compressed_device_latency); int adm_swap_speaker_channels(int port_id, int copp_idx, int sample_rate, bool spk_swap) { - struct audproc_mfc_output_media_fmt mfc_cfg; + struct audproc_mfc_param_media_fmt mfc_cfg; + struct param_hdr_v3 param_hdr; uint16_t num_channels; - int port_idx; + int port_idx = 0; int ret = 0; pr_debug("%s: Enter, port_id %d, copp_idx %d\n", @@ -4716,50 +4157,27 @@ int adm_swap_speaker_channels(int port_id, int copp_idx, port_idx = adm_validate_and_get_port_index(port_id); if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { pr_err("%s: Invalid port_id %#x\n", __func__, port_id); - ret = -EINVAL; - goto done; - } - - if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { - pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); - ret = -EINVAL; - goto done; + return -EINVAL; + } else if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_idx 0x%x\n", __func__, copp_idx); + return -EINVAL; } - num_channels = atomic_read( - &this_adm.copp.channels[port_idx][copp_idx]); + num_channels = atomic_read(&this_adm.copp.channels[port_idx][copp_idx]); if (num_channels != 2) { pr_debug("%s: Invalid number of channels: %d\n", __func__, num_channels); - ret = -EINVAL; - goto done; + return -EINVAL; } memset(&mfc_cfg, 0, sizeof(mfc_cfg)); - mfc_cfg.params.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - mfc_cfg.params.hdr.pkt_size = - sizeof(mfc_cfg); - mfc_cfg.params.hdr.src_svc = APR_SVC_ADM; - mfc_cfg.params.hdr.src_domain = APR_DOMAIN_APPS; - mfc_cfg.params.hdr.src_port = port_id; - mfc_cfg.params.hdr.dest_svc = APR_SVC_ADM; - mfc_cfg.params.hdr.dest_domain = APR_DOMAIN_ADSP; - mfc_cfg.params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - mfc_cfg.params.hdr.token = port_idx << 16 | copp_idx; - mfc_cfg.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - mfc_cfg.params.payload_addr_lsw = 0; - mfc_cfg.params.payload_addr_msw = 0; - mfc_cfg.params.mem_map_handle = 0; - mfc_cfg.params.payload_size = sizeof(mfc_cfg) - - sizeof(mfc_cfg.params); - mfc_cfg.data.module_id = AUDPROC_MODULE_ID_MFC; - mfc_cfg.data.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; - mfc_cfg.data.param_size = mfc_cfg.params.payload_size - - sizeof(mfc_cfg.data); - mfc_cfg.data.reserved = 0; + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AUDPROC_MODULE_ID_MFC; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; + param_hdr.param_size = sizeof(mfc_cfg); + mfc_cfg.sampling_rate = sample_rate; mfc_cfg.bits_per_sample = atomic_read(&this_adm.copp.bit_width[port_idx][copp_idx]); @@ -4778,45 +4196,16 @@ int adm_swap_speaker_channels(int port_id, int copp_idx, (uint16_t) PCM_CHANNEL_FR; } - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - pr_debug("%s: mfc config: port_idx %d copp_idx %d copp SR %d copp BW %d copp chan %d\n", - __func__, port_idx, copp_idx, mfc_cfg.sampling_rate, - mfc_cfg.bits_per_sample, mfc_cfg.num_channels); - - ret = apr_send_pkt(this_adm.apr, (uint32_t *)&mfc_cfg); + ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (u8 *) &mfc_cfg); if (ret < 0) { - pr_err("%s: port_id: for[0x%x] failed %d\n", - __func__, port_id, ret); - goto done; - } - /* Wait for the callback with copp id */ - ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: mfc_cfg Set params timed out for port_id: for [0x%x]\n", - __func__, port_id); - ret = -ETIMEDOUT; - goto done; - } - - if (atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto done; + pr_err("%s: Failed to set swap speaker channels on port[0x%x] failed %d\n", + __func__, port_id, ret); + return ret; } pr_debug("%s: mfc_cfg Set params returned success", __func__); - ret = 0; - -done: - return ret; + return 0; } EXPORT_SYMBOL(adm_swap_speaker_channels); @@ -4833,108 +4222,41 @@ EXPORT_SYMBOL(adm_swap_speaker_channels); int adm_set_sound_focus(int port_id, int copp_idx, struct sound_focus_param soundFocusData) { - struct adm_set_fluence_soundfocus_param soundfocus_params; - int sz = 0; + struct adm_param_fluence_soundfocus_t soundfocus_params; + struct param_hdr_v3 param_hdr; int ret = 0; - int port_idx; int i; pr_debug("%s: Enter, port_id %d, copp_idx %d\n", __func__, port_id, copp_idx); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id %#x\n", __func__, port_id); - - ret = -EINVAL; - goto done; - } - - if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { - pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); - - ret = -EINVAL; - goto done; - } + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = VOICEPROC_MODULE_ID_GENERIC_TX; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS; + param_hdr.param_size = sizeof(soundfocus_params); - sz = sizeof(struct adm_set_fluence_soundfocus_param); - soundfocus_params.params.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - soundfocus_params.params.hdr.pkt_size = sz; - soundfocus_params.params.hdr.src_svc = APR_SVC_ADM; - soundfocus_params.params.hdr.src_domain = APR_DOMAIN_APPS; - soundfocus_params.params.hdr.src_port = port_id; - soundfocus_params.params.hdr.dest_svc = APR_SVC_ADM; - soundfocus_params.params.hdr.dest_domain = APR_DOMAIN_ADSP; - soundfocus_params.params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - soundfocus_params.params.hdr.token = port_idx << 16 | - ADM_CLIENT_ID_SOURCE_TRACKING << 8 | copp_idx; - soundfocus_params.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - soundfocus_params.params.payload_addr_lsw = 0; - soundfocus_params.params.payload_addr_msw = 0; - soundfocus_params.params.mem_map_handle = 0; - soundfocus_params.params.payload_size = sizeof(soundfocus_params) - - sizeof(soundfocus_params.params); - soundfocus_params.data.module_id = VOICEPROC_MODULE_ID_GENERIC_TX; - soundfocus_params.data.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS; - soundfocus_params.data.param_size = - soundfocus_params.params.payload_size - - sizeof(soundfocus_params.data); - soundfocus_params.data.reserved = 0; - - memset(&(soundfocus_params.soundfocus_data), 0xFF, - sizeof(struct adm_param_fluence_soundfocus_t)); + memset(&(soundfocus_params), 0xFF, sizeof(soundfocus_params)); for (i = 0; i < MAX_SECTORS; i++) { - soundfocus_params.soundfocus_data.start_angles[i] = + soundfocus_params.start_angles[i] = soundFocusData.start_angle[i]; - soundfocus_params.soundfocus_data.enables[i] = - soundFocusData.enable[i]; + soundfocus_params.enables[i] = soundFocusData.enable[i]; pr_debug("%s: start_angle[%d] = %d\n", __func__, i, soundFocusData.start_angle[i]); pr_debug("%s: enable[%d] = %d\n", __func__, i, soundFocusData.enable[i]); } - soundfocus_params.soundfocus_data.gain_step = - soundFocusData.gain_step; + soundfocus_params.gain_step = soundFocusData.gain_step; pr_debug("%s: gain_step = %d\n", __func__, soundFocusData.gain_step); - soundfocus_params.soundfocus_data.reserved = 0; - - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - ret = apr_send_pkt(this_adm.apr, (uint32_t *)&soundfocus_params); - if (ret < 0) { - pr_err("%s: Set params failed\n", __func__); - - ret = -EINVAL; - goto done; - } - /* Wait for the callback */ - ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: Set params timed out\n", __func__); - - ret = -EINVAL; - goto done; - } - - if (this_adm.sourceTrackingData.apr_cmd_status != 0) { - pr_err("%s - set params returned error [%s]\n", - __func__, adsp_err_get_err_str( - this_adm.sourceTrackingData.apr_cmd_status)); - - ret = adsp_err_get_lnx_err_code( - this_adm.sourceTrackingData.apr_cmd_status); - goto done; - } + soundfocus_params.reserved = 0; - ret = 0; + ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &soundfocus_params); + if (ret) + pr_err("%s: Failed to set sound focus params, err %d\n", + __func__, ret); -done: pr_debug("%s: Exit, ret=%d\n", __func__, ret); return ret; @@ -4956,28 +4278,29 @@ int adm_get_sound_focus(int port_id, int copp_idx, { int ret = 0, i; char *params_value; - uint32_t param_payload_len = sizeof(struct adm_param_data_v5) + - sizeof(struct adm_param_fluence_soundfocus_t); - struct adm_param_fluence_soundfocus_t *soundfocus_params; + uint32_t max_param_size = 0; + struct adm_param_fluence_soundfocus_t *soundfocus_params = NULL; + struct param_hdr_v3 param_hdr; pr_debug("%s: Enter, port_id %d, copp_idx %d\n", __func__, port_id, copp_idx); - params_value = kzalloc(param_payload_len, GFP_KERNEL); - if (!params_value) { - ret = -ENOMEM; - goto done; - } - ret = adm_get_params_v2(port_id, copp_idx, - VOICEPROC_MODULE_ID_GENERIC_TX, - VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS, - param_payload_len, - params_value, - ADM_CLIENT_ID_SOURCE_TRACKING); + max_param_size = sizeof(struct adm_param_fluence_soundfocus_t) + + sizeof(union param_hdrs); + params_value = kzalloc(max_param_size, GFP_KERNEL); + if (!params_value) + return -ENOMEM; + + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = VOICEPROC_MODULE_ID_GENERIC_TX; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS; + param_hdr.param_size = max_param_size; + ret = adm_get_pp_params(port_id, copp_idx, + ADM_CLIENT_ID_SOURCE_TRACKING, NULL, ¶m_hdr, + params_value); if (ret) { pr_err("%s: get parameters failed ret:%d\n", __func__, ret); - - kfree(params_value); ret = -EINVAL; goto done; } @@ -4986,8 +4309,6 @@ int adm_get_sound_focus(int port_id, int copp_idx, pr_err("%s - get params returned error [%s]\n", __func__, adsp_err_get_err_str( this_adm.sourceTrackingData.apr_cmd_status)); - - kfree(params_value); ret = adsp_err_get_lnx_err_code( this_adm.sourceTrackingData.apr_cmd_status); goto done; @@ -5007,11 +4328,10 @@ int adm_get_sound_focus(int port_id, int copp_idx, soundFocusData->gain_step = soundfocus_params->gain_step; pr_debug("%s: gain_step = %d\n", __func__, soundFocusData->gain_step); - kfree(params_value); - done: pr_debug("%s: Exit, ret = %d\n", __func__, ret); + kfree(params_value); return ret; } EXPORT_SYMBOL(adm_get_sound_focus); @@ -5083,9 +4403,12 @@ static int adm_source_tracking_alloc_map_memory(void) int adm_get_source_tracking(int port_id, int copp_idx, struct source_tracking_param *sourceTrackingData) { - struct adm_cmd_get_pp_params_v5 admp; - int p_idx, ret = 0, i; - struct adm_param_fluence_sourcetracking_t *source_tracking_params; + struct adm_param_fluence_sourcetracking_t *source_tracking_params = + NULL; + struct mem_mapping_hdr mem_hdr; + struct param_hdr_v3 param_hdr; + int i = 0; + int ret = 0; pr_debug("%s: Enter, port_id %d, copp_idx %d\n", __func__, port_id, copp_idx); @@ -5099,68 +4422,36 @@ int adm_get_source_tracking(int port_id, int copp_idx, } } - port_id = afe_convert_virtual_to_portid(port_id); - p_idx = adm_validate_and_get_port_index(port_id); - if (p_idx < 0) { - pr_err("%s - invalid port index %i, port id %i, copp idx %i\n", - __func__, p_idx, port_id, copp_idx); - - ret = -EINVAL; - goto done; - } - - admp.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - admp.hdr.pkt_size = sizeof(admp); - admp.hdr.src_svc = APR_SVC_ADM; - admp.hdr.src_domain = APR_DOMAIN_APPS; - admp.hdr.src_port = port_id; - admp.hdr.dest_svc = APR_SVC_ADM; - admp.hdr.dest_domain = APR_DOMAIN_ADSP; - admp.hdr.dest_port = atomic_read(&this_adm.copp.id[p_idx][copp_idx]); - admp.hdr.token = p_idx << 16 | ADM_CLIENT_ID_SOURCE_TRACKING << 8 | - copp_idx; - admp.hdr.opcode = ADM_CMD_GET_PP_PARAMS_V5; - admp.data_payload_addr_lsw = + memset(&mem_hdr, 0, sizeof(mem_hdr)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + mem_hdr.data_payload_addr_lsw = lower_32_bits(this_adm.sourceTrackingData.memmap.paddr); - admp.data_payload_addr_msw = - msm_audio_populate_upper_32_bits( - this_adm.sourceTrackingData.memmap.paddr); - admp.mem_map_handle = atomic_read(&this_adm.mem_map_handles[ - ADM_MEM_MAP_INDEX_SOURCE_TRACKING]); - admp.module_id = VOICEPROC_MODULE_ID_GENERIC_TX; - admp.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOURCETRACKING; - admp.param_max_size = sizeof(struct adm_param_fluence_sourcetracking_t) - + sizeof(struct adm_param_data_v5); - admp.reserved = 0; - - atomic_set(&this_adm.copp.stat[p_idx][copp_idx], -1); - - ret = apr_send_pkt(this_adm.apr, (uint32_t *)&admp); - if (ret < 0) { - pr_err("%s - failed to get Source Tracking Params\n", - __func__); - - ret = -EINVAL; - goto done; - } - ret = wait_event_timeout(this_adm.copp.wait[p_idx][copp_idx], - atomic_read(&this_adm.copp.stat[p_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s - get params timed out\n", __func__); + mem_hdr.data_payload_addr_msw = msm_audio_populate_upper_32_bits( + this_adm.sourceTrackingData.memmap.paddr); + mem_hdr.mem_map_handle = atomic_read( + &this_adm.mem_map_handles[ADM_MEM_MAP_INDEX_SOURCE_TRACKING]); + + param_hdr.module_id = VOICEPROC_MODULE_ID_GENERIC_TX; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOURCETRACKING; + /* + * This size should be the max size of the calibration data + header. + * Use the union size to ensure max size is used. + */ + param_hdr.param_size = + sizeof(struct adm_param_fluence_sourcetracking_t) + + sizeof(union param_hdrs); - ret = -EINVAL; - goto done; - } else if (atomic_read(&this_adm.copp.stat - [p_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [p_idx][copp_idx]))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [p_idx][copp_idx])); + /* + * Retrieving parameters out of band, so no need to provide a buffer for + * the returned parameter data as it will be at the memory location + * provided. + */ + ret = adm_get_pp_params(port_id, copp_idx, + ADM_CLIENT_ID_SOURCE_TRACKING, &mem_hdr, + ¶m_hdr, NULL); + if (ret) { + pr_err("%s: Failed to get params, error %d\n", __func__, ret); goto done; } @@ -5174,9 +4465,11 @@ int adm_get_source_tracking(int port_id, int copp_idx, goto done; } - source_tracking_params = (struct adm_param_fluence_sourcetracking_t *) - (this_adm.sourceTrackingData.memmap.kvaddr + - sizeof(struct adm_param_data_v5)); + /* How do we know what the param data was retrieved with for hdr size */ + source_tracking_params = + (struct adm_param_fluence_sourcetracking_t + *) (this_adm.sourceTrackingData.memmap.kvaddr + + sizeof(struct param_hdr_v1)); for (i = 0; i < MAX_SECTORS; i++) { sourceTrackingData->vad[i] = source_tracking_params->vad[i]; pr_debug("%s: vad[%d] = %d\n", @@ -5212,36 +4505,16 @@ int __init adm_init(void) { int i = 0, j; - this_adm.apr = NULL; this_adm.ec_ref_rx = -1; - this_adm.num_ec_ref_rx_chans = 0; - this_adm.ec_ref_rx_bit_width = 0; - this_adm.ec_ref_rx_sampling_rate = 0; - atomic_set(&this_adm.matrix_map_stat, 0); init_waitqueue_head(&this_adm.matrix_map_wait); - atomic_set(&this_adm.adm_stat, 0); init_waitqueue_head(&this_adm.adm_wait); for (i = 0; i < AFE_MAX_PORTS; i++) { for (j = 0; j < MAX_COPPS_PER_PORT; j++) { atomic_set(&this_adm.copp.id[i][j], RESET_COPP_ID); - atomic_set(&this_adm.copp.cnt[i][j], 0); - atomic_set(&this_adm.copp.topology[i][j], 0); - atomic_set(&this_adm.copp.mode[i][j], 0); - atomic_set(&this_adm.copp.stat[i][j], 0); - atomic_set(&this_adm.copp.rate[i][j], 0); - atomic_set(&this_adm.copp.channels[i][j], 0); - atomic_set(&this_adm.copp.bit_width[i][j], 0); - atomic_set(&this_adm.copp.app_type[i][j], 0); - atomic_set(&this_adm.copp.acdb_id[i][j], 0); init_waitqueue_head(&this_adm.copp.wait[i][j]); - atomic_set(&this_adm.copp.adm_delay_stat[i][j], 0); init_waitqueue_head( &this_adm.copp.adm_delay_wait[i][j]); - atomic_set(&this_adm.copp.topology[i][j], 0); - this_adm.copp.adm_delay[i][j] = 0; - this_adm.copp.adm_status[i][j] = - ADM_STATUS_CALIBRATION_REQUIRED; } } @@ -5253,9 +4526,6 @@ int __init adm_init(void) this_adm.sourceTrackingData.memmap.kvaddr = NULL; this_adm.sourceTrackingData.memmap.paddr = 0; this_adm.sourceTrackingData.apr_cmd_status = -1; - atomic_set(&this_adm.mem_map_handles[ADM_MEM_MAP_INDEX_SOURCE_TRACKING], - 0); - mutex_init(&dts_srs_lock); return 0; } @@ -5264,6 +4534,5 @@ void adm_exit(void) { if (this_adm.apr) adm_reset_data(); - mutex_destroy(&dts_srs_lock); adm_delete_cal_data(); } diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index d068e683ff75..8438c37bea70 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -500,55 +500,39 @@ struct adm_cmd_device_open_v6 { #define ADM_CMD_SET_PP_PARAMS_V5 0x00010328 #define ADM_CMD_SET_PP_PARAMS_V6 0x0001035D -/* Payload of the #ADM_CMD_SET_PP_PARAMS_V5 command. - * If the data_payload_addr_lsw and data_payload_addr_msw element - * are NULL, a series of adm_param_datastructures immediately - * follows, whose total size is data_payload_size bytes. - */ -struct adm_cmd_set_pp_params_v5 { - struct apr_hdr hdr; - u32 payload_addr_lsw; -/* LSW of parameter data payload address. */ - u32 payload_addr_msw; -/* MSW of parameter data payload address. */ - - u32 mem_map_handle; -/* Memory map handle returned by ADM_CMD_SHARED_MEM_MAP_REGIONS - * command - * - * If mem_map_handle is zero implies the message is in - * the payload +/* + * Structure of the ADM Set PP Params command. Parameter data must be + * pre-packed with correct header for either V2 or V3 when sent in-band. + * Use q6core_pack_pp_params to pack the header and data correctly depending on + * Instance ID support. */ +struct adm_cmd_set_pp_params { + /* APR Header */ + struct apr_hdr apr_hdr; - u32 payload_size; -/* Size in bytes of the variable payload accompanying this - * message or - * in shared memory. This is used for parsing the parameter - * payload. - */ -} __packed; + /* The memory mapping header to be used when sending out of band */ + struct mem_mapping_hdr mem_hdr; -/* Payload format for COPP parameter data. - * Immediately following this structure are param_size bytes - * of parameter - * data. - */ -struct adm_param_data_v5 { - u32 module_id; - /* Unique ID of the module. */ - u32 param_id; - /* Unique ID of the parameter. */ - u16 param_size; - /* Data size of the param_id/module_id combination. - * This value is a - * multiple of 4 bytes. + /* + * Size in bytes of the variable payload accompanying this + * message or + * in shared memory. This is used for parsing the parameter + * payload. */ - u16 reserved; - /* Reserved for future enhancements. - * This field must be set to zero. + u32 payload_size; + + /* + * Parameter data for in band payload. This should be structured as the + * parameter header immediately followed by the parameter data. Multiple + * parameters can be set in one command by repeating the header followed + * by the data for as many parameters as need to be set. + * Use q6core_pack_pp_params to pack the header and data correctly + * depending on Instance ID support. */ + u8 param_data[0]; } __packed; + #define ASM_STREAM_CMD_REGISTER_PP_EVENTS 0x00013213 #define ASM_STREAM_PP_EVENT 0x00013214 #define ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE 0x13333 @@ -591,25 +575,6 @@ struct adm_cmd_set_pspd_mtmx_strtr_params_v5 { u16 reserved; } __packed; -/* Defined specifically for in-band use, includes params */ -struct adm_cmd_set_pp_params_inband_v5 { - struct apr_hdr hdr; - /* LSW of parameter data payload address.*/ - u32 payload_addr_lsw; - /* MSW of parameter data payload address.*/ - u32 payload_addr_msw; - /* Memory map handle returned by ADM_CMD_SHARED_MEM_MAP_REGIONS */ - /* command. If mem_map_handle is zero implies the message is in */ - /* the payload */ - u32 mem_map_handle; - /* Size in bytes of the variable payload accompanying this */ - /* message or in shared memory. This is used for parsing the */ - /* parameter payload. */ - u32 payload_size; - /* Parameters passed for in band payload */ - struct adm_param_data_v5 params; -} __packed; - /* Returns the status and COPP ID to an #ADM_CMD_DEVICE_OPEN_V5 command. */ #define ADM_CMDRSP_DEVICE_OPEN_V5 0x00010329 @@ -642,42 +607,19 @@ struct adm_cmd_rsp_device_open_v5 { #define ADM_CMD_GET_PP_PARAMS_V5 0x0001032A #define ADM_CMD_GET_PP_PARAMS_V6 0x0001035E -/* Payload an #ADM_CMD_GET_PP_PARAMS_V5 command. */ -struct adm_cmd_get_pp_params_v5 { - struct apr_hdr hdr; - u32 data_payload_addr_lsw; - /* LSW of parameter data payload address.*/ - - u32 data_payload_addr_msw; - /* MSW of parameter data payload address.*/ - - /* If the mem_map_handle is non zero, - * on ACK, the ParamData payloads begin at - * the address specified (out-of-band). - */ - - u32 mem_map_handle; - /* Memory map handle returned - * by ADM_CMD_SHARED_MEM_MAP_REGIONS command. - * If the mem_map_handle is 0, it implies that - * the ACK's payload will contain the ParamData (in-band). - */ - - u32 module_id; - /* Unique ID of the module. */ +/* + * Structure of the ADM Get PP Params command. Parameter header must be + * packed correctly for either V2 or V3. Use q6core_pack_pp_params to pack the + * header correctly depending on Instance ID support. + */ +struct adm_cmd_get_pp_params { + struct apr_hdr apr_hdr; - u32 param_id; - /* Unique ID of the parameter. */ + /* The memory mapping header to be used when requesting outband */ + struct mem_mapping_hdr mem_hdr; - u16 param_max_size; - /* Maximum data size of the parameter - *ID/module ID combination. This - * field is a multiple of 4 bytes. - */ - u16 reserved; - /* Reserved for future enhancements. - * This field must be set to zero. - */ + /* Parameter header for in band payload. */ + union param_hdrs param_hdr; } __packed; /* Returns parameter values @@ -689,15 +631,49 @@ struct adm_cmd_get_pp_params_v5 { * which returns parameter values in response * to an #ADM_CMD_GET_PP_PARAMS_V5 command. * Immediately following this - * structure is the adm_param_data_v5 + * structure is the param_hdr_v1 * structure containing the pre/postprocessing * parameter data. For an in-band * scenario, the variable payload depends * on the size of the parameter. */ struct adm_cmd_rsp_get_pp_params_v5 { - u32 status; /* Status message (error code).*/ + u32 status; + + /* The header that identifies the subsequent parameter data */ + struct param_hdr_v1 param_hdr; + + /* The parameter data returned */ + u32 param_data[0]; +} __packed; + +/* + * Returns parameter values in response to an #ADM_CMD_GET_PP_PARAMS_V5/6 + * command. + */ +#define ADM_CMDRSP_GET_PP_PARAMS_V6 0x0001035F + +/* + * Payload of the #ADM_CMDRSP_GET_PP_PARAMS_V6 message, + * which returns parameter values in response + * to an #ADM_CMD_GET_PP_PARAMS_V6 command. + * Immediately following this + * structure is the param_hdr_v3 + * structure containing the pre/postprocessing + * parameter data. For an in-band + * scenario, the variable payload depends + * on the size of the parameter. + */ +struct adm_cmd_rsp_get_pp_params_v6 { + /* Status message (error code).*/ + u32 status; + + /* The header that identifies the subsequent parameter data */ + struct param_hdr_v3 param_hdr; + + /* The parameter data returned */ + u32 param_data[0]; } __packed; /* Structure for holding soft stepping volume parameters. */ @@ -730,9 +706,40 @@ struct audproc_softvolume_params { #define AUDPROC_CHMIXER_PARAM_ID_COEFF 0x00010342 +struct adm_cmd_set_pp_params_v5 { + struct apr_hdr hdr; + u32 payload_addr_lsw; + /* LSW of parameter data payload address.*/ + u32 payload_addr_msw; + /* MSW of parameter data payload address.*/ + + u32 mem_map_handle; + /* + * Memory map handle returned by ADM_CMD_SHARED_MEM_MAP_REGIONS + * command. + * If mem_map_handle is zero implies the message is in + * the payload + */ + + u32 payload_size; + /* + * Size in bytes of the variable payload accompanying this + * message or + * in shared memory. This is used for parsing the parameter + * payload. + */ +} __packed; + struct audproc_mfc_output_media_fmt { struct adm_cmd_set_pp_params_v5 params; - struct adm_param_data_v5 data; + struct param_hdr_v1 data; + uint32_t sampling_rate; + uint16_t bits_per_sample; + uint16_t num_channels; + uint16_t channel_type[8]; +} __packed; + +struct audproc_mfc_param_media_fmt { uint32_t sampling_rate; uint16_t bits_per_sample; uint16_t num_channels; @@ -740,8 +747,6 @@ struct audproc_mfc_output_media_fmt { } __packed; struct audproc_volume_ctrl_master_gain { - struct adm_cmd_set_pp_params_v5 params; - struct adm_param_data_v5 data; /* Linear gain in Q13 format. */ uint16_t master_gain; /* Clients must set this field to zero. */ @@ -749,8 +754,6 @@ struct audproc_volume_ctrl_master_gain { } __packed; struct audproc_soft_step_volume_params { - struct adm_cmd_set_pp_params_v5 params; - struct adm_param_data_v5 data; /* * Period in milliseconds. * Supported values: 0 to 15000 @@ -772,7 +775,6 @@ struct audproc_soft_step_volume_params { } __packed; struct audproc_enable_param_t { - struct adm_cmd_set_pp_params_inband_v5 pp_params; /* * Specifies whether the Audio processing module is enabled. * This parameter is generic/common parameter to configure or @@ -7614,12 +7616,6 @@ struct admx_mic_gain { /*< Clients must set this field to zero. */ } __packed; -struct adm_set_mic_gain_params { - struct adm_cmd_set_pp_params_v5 params; - struct adm_param_data_v5 data; - struct admx_mic_gain mic_gain_data; -} __packed; - /* end_addtogroup audio_pp_param_ids */ /* @ingroup audio_pp_module_ids @@ -7977,56 +7973,23 @@ struct adm_qensemble_param_set_new_angle { #define ADM_CMD_GET_PP_TOPO_MODULE_LIST 0x00010349 #define ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST 0x00010350 +#define ADM_CMD_GET_PP_TOPO_MODULE_LIST_V2 0x00010360 +#define ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST_V2 0x00010361 #define AUDPROC_PARAM_ID_ENABLE 0x00010904 - /* - * Payload of the ADM_CMD_GET_PP_TOPO_MODULE_LIST command. - */ -struct adm_cmd_get_pp_topo_module_list_t { - struct apr_hdr hdr; - /* Lower 32 bits of the 64-bit parameter data payload address. */ - uint32_t data_payload_addr_lsw; - /* - * Upper 32 bits of the 64-bit parameter data payload address. - * - * - * The size of the shared memory, if specified, must be large enough to - * contain the entire parameter data payload, including the module ID, - * parameter ID, parameter size, and parameter values. - */ - uint32_t data_payload_addr_msw; - /* - * Unique identifier for an address. - * - * This memory map handle is returned by the aDSP through the - * #ADM_CMD_SHARED_MEM_MAP_REGIONS command. - * - * @values - * - Non-NULL -- On acknowledgment, the parameter data payloads begin at - * the address specified (out-of-band) - * - NULL -- The acknowledgment's payload contains the parameter data - * (in-band) @tablebulletend - */ - uint32_t mem_map_handle; +/* + * Payload of the ADM_CMD_GET_PP_TOPO_MODULE_LIST command. + */ +struct adm_cmd_get_pp_topo_module_list { + struct apr_hdr apr_hdr; + + /* The memory mapping header to be used when requesting out of band */ + struct mem_mapping_hdr mem_hdr; + /* * Maximum data size of the list of modules. This * field is a multiple of 4 bytes. */ - uint16_t param_max_size; - /* This field must be set to zero. */ - uint16_t reserved; -} __packed; - -/* - * Payload of the ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST message, which returns - * module ids in response to an ADM_CMD_GET_PP_TOPO_MODULE_LIST command. - * Immediately following this structure is the acknowledgment module id - * data variable payload containing the pre/postprocessing module id - * values. For an in-band scenario, the variable payload depends on the size - * of the parameter. - */ -struct adm_cmd_rsp_get_pp_topo_module_list_t { - /* Status message (error code). */ - uint32_t status; + uint32_t param_max_size; } __packed; struct audproc_topology_module_id_info_t { @@ -10926,18 +10889,14 @@ enum { #define AUDPROC_PARAM_ID_COMPRESSED_MUTE 0x00010771 struct adm_set_compressed_device_mute { - struct adm_cmd_set_pp_params_v5 command; - struct adm_param_data_v5 params; - u32 mute_on; + u32 mute_on; } __packed; #define AUDPROC_MODULE_ID_COMPRESSED_LATENCY 0x0001076E #define AUDPROC_PARAM_ID_COMPRESSED_LATENCY 0x0001076F struct adm_set_compressed_device_latency { - struct adm_cmd_set_pp_params_v5 command; - struct adm_param_data_v5 params; - u32 latency; + u32 latency; } __packed; #define VOICEPROC_MODULE_ID_GENERIC_TX 0x00010EF6 @@ -10967,12 +10926,6 @@ struct adm_param_fluence_soundfocus_t { uint16_t reserved; } __packed; -struct adm_set_fluence_soundfocus_param { - struct adm_cmd_set_pp_params_v5 params; - struct adm_param_data_v5 data; - struct adm_param_fluence_soundfocus_t soundfocus_data; -} __packed; - struct adm_param_fluence_sourcetracking_t { uint8_t vad[MAX_SECTORS]; uint16_t doa_speech; @@ -11002,10 +10955,4 @@ struct admx_sec_primary_mic_ch { uint16_t reserved1; } __packed; - -struct adm_set_sec_primary_ch_params { - struct adm_cmd_set_pp_params_v5 params; - struct adm_param_data_v5 data; - struct admx_sec_primary_mic_ch sec_primary_mic_ch_data; -} __packed; #endif /*_APR_AUDIO_V2_H_ */ diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 881943b464c3..0f7e7b240428 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -25,6 +25,8 @@ #define MAX_MODULES_IN_TOPO 16 #define ADM_GET_TOPO_MODULE_LIST_LENGTH\ ((MAX_MODULES_IN_TOPO + 1) * sizeof(uint32_t)) +#define ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH \ + ((MAX_MODULES_IN_TOPO + 1) * 2 * sizeof(uint32_t)) #define AUD_PROC_BLOCK_SIZE 4096 #define AUD_VOL_BLOCK_SIZE 4096 #define AUDIO_RX_CALIBRATION_SIZE (AUD_PROC_BLOCK_SIZE + \ @@ -94,12 +96,24 @@ void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate); int adm_get_params(int port_id, int copp_idx, uint32_t module_id, uint32_t param_id, uint32_t params_length, char *params); +int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id, + struct mem_mapping_hdr *mem_hdr, + struct param_hdr_v3 *param_hdr, u8 *returned_param_data); + int adm_send_params_v5(int port_id, int copp_idx, char *params, uint32_t params_length); int adm_dolby_dap_send_params(int port_id, int copp_idx, char *params, uint32_t params_length); +int adm_set_pp_params(int port_id, int copp_idx, + struct mem_mapping_hdr *mem_hdr, u8 *param_data, + u32 params_size); + +int adm_pack_and_set_one_pp_param(int port_id, int copp_idx, + struct param_hdr_v3 param_hdr, + u8 *param_data); + int adm_open(int port, int path, int rate, int mode, int topology, int perf_mode, uint16_t bits_per_sample, int app_type, int acdbdev_id); @@ -146,6 +160,10 @@ int adm_set_stereo_to_custom_stereo(int port_id, int copp_idx, int adm_get_pp_topo_module_list(int port_id, int copp_idx, int32_t param_length, char *params); +int adm_get_pp_topo_module_list_v2(int port_id, int copp_idx, + int32_t param_length, + int32_t *returned_params); + int adm_set_volume(int port_id, int copp_idx, int volume); int adm_set_softvolume(int port_id, int copp_idx, @@ -158,6 +176,9 @@ int adm_send_set_multichannel_ec_primary_mic_ch(int port_id, int copp_idx, int adm_param_enable(int port_id, int copp_idx, int module_id, int enable); +int adm_param_enable_v2(int port_id, int copp_idx, + struct module_instance_info mod_inst_info, int enable); + int adm_send_calibration(int port_id, int copp_idx, int path, int perf_mode, int cal_type, char *params, int size); -- GitLab From 916967ba228a9c141907b983fa49f36a0e999b46 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Mon, 29 Jan 2018 16:52:52 -0800 Subject: [PATCH 0215/1645] ASoC: dsp: Update dap driver to support Instance ID Add support to set and get dap modules params with Instance ID support for both Dolby and DS2. Maintain support for non Instance ID set and get param structures as well. Use common pack and set param functions to set and get parameters to DSP instead of handling them at an individual module level. CRs-Fixed: 2151551 Change-Id: I1633b63a1a598c0e4ea874d00655b09a240a47e3 Signed-off-by: Vignesh Kulothungan --- asoc/msm-ds2-dap-config.c | 542 ++++++++++++++++++++------------------ asoc/msm-ds2-dap-config.h | 31 ++- dsp/q6adm.c | 51 ---- include/dsp/q6adm-v2.h | 6 - 4 files changed, 315 insertions(+), 315 deletions(-) diff --git a/asoc/msm-ds2-dap-config.c b/asoc/msm-ds2-dap-config.c index 645ecf5cfd2d..ad7a3c6a406f 100644 --- a/asoc/msm-ds2-dap-config.c +++ b/asoc/msm-ds2-dap-config.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -17,6 +17,7 @@ #include #include #include +#include #include "msm-ds2-dap-config.h" #include "msm-pcm-routing-v2.h" @@ -196,18 +197,23 @@ static void msm_ds2_dap_check_and_update_ramp_wait(int port_id, int copp_idx, int32_t *update_params_value = NULL; uint32_t params_length = SOFT_VOLUME_PARAM_SIZE * sizeof(uint32_t); uint32_t param_payload_len = PARAM_PAYLOAD_SIZE * sizeof(uint32_t); + struct param_hdr_v3 param_hdr; int rc = 0; update_params_value = kzalloc(params_length + param_payload_len, GFP_KERNEL); - if (!update_params_value) + if (!update_params_value) { + pr_err("%s: params memory alloc failed\n", __func__); goto end; + } - rc = adm_get_params(port_id, copp_idx, - AUDPROC_MODULE_ID_VOL_CTRL, - AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS, - params_length + param_payload_len, - (char *) update_params_value); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_VOL_CTRL; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS; + param_hdr.param_size = params_length + param_payload_len; + rc = adm_get_pp_params(port_id, copp_idx, ADM_CLIENT_ID_DEFAULT, NULL, + ¶m_hdr, (char *) update_params_value); if (rc == 0) { pr_debug("%s: params_value [0x%x, 0x%x, 0x%x]\n", __func__, update_params_value[0], @@ -227,12 +233,13 @@ static void msm_ds2_dap_check_and_update_ramp_wait(int port_id, int copp_idx, static int msm_ds2_dap_set_vspe_vdhe(int dev_map_idx, bool is_custom_stereo_enabled) { - int32_t *update_params_value = NULL; - int32_t *param_val = NULL; - int idx, i, j, rc = 0, cdev; - uint32_t params_length = (TOTAL_LENGTH_DOLBY_PARAM + - 2 * DOLBY_PARAM_PAYLOAD_SIZE) * - sizeof(uint32_t); + u8 *packed_param_data = NULL; + u8 *param_data = NULL; + struct param_hdr_v3 param_hdr; + u32 packed_param_size = 0; + u32 param_size = 0; + int cdev; + int rc = 0; if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); @@ -260,74 +267,95 @@ static int msm_ds2_dap_set_vspe_vdhe(int dev_map_idx, goto end; } - update_params_value = kzalloc(params_length, GFP_KERNEL); - if (!update_params_value) { - rc = -ENOMEM; + /* Allocate the max space needed */ + packed_param_size = (TOTAL_LENGTH_DOLBY_PARAM * sizeof(uint32_t)) + + (2 * sizeof(union param_hdrs)); + packed_param_data = kzalloc(packed_param_size, GFP_KERNEL); + if (!packed_param_data) + return -ENOMEM; + + packed_param_size = 0; + memset(¶m_hdr, 0, sizeof(param_hdr)); + + /* Set common values */ + cdev = dev_map[dev_map_idx].cache_dev; + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + + /* Pack VDHE header + data */ + param_hdr.param_id = DOLBY_PARAM_ID_VDHE; + param_size = DOLBY_PARAM_VDHE_LENGTH * sizeof(uint32_t); + param_hdr.param_size = param_size; + + if (is_custom_stereo_enabled) + param_data = NULL; + else + param_data = (u8 *) &ds2_dap_params[cdev] + .params_val[DOLBY_PARAM_VDHE_OFFSET]; + + rc = q6common_pack_pp_params(packed_param_data, ¶m_hdr, param_data, + ¶m_size); + if (rc) { + pr_err("%s: Failed to pack params for dolby vdhe, error %d\n", + __func__, rc); goto end; } - params_length = 0; - param_val = update_params_value; - cdev = dev_map[dev_map_idx].cache_dev; - /* for VDHE and VSPE DAP params at index 0 and 1 in table */ - for (i = 0; i < 2; i++) { - *update_params_value++ = DOLBY_BUNDLE_MODULE_ID; - *update_params_value++ = ds2_dap_params_id[i]; - *update_params_value++ = ds2_dap_params_length[i] * - sizeof(uint32_t); - idx = ds2_dap_params_offset[i]; - for (j = 0; j < ds2_dap_params_length[i]; j++) { - if (is_custom_stereo_enabled) - *update_params_value++ = 0; - else - *update_params_value++ = - ds2_dap_params[cdev].params_val[idx+j]; - } - params_length += (DOLBY_PARAM_PAYLOAD_SIZE + - ds2_dap_params_length[i]) * - sizeof(uint32_t); - } - - pr_debug("%s: valid param length: %d\n", __func__, params_length); - if (params_length) { - rc = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id, - dev_map[dev_map_idx].copp_idx, - (char *)param_val, - params_length); - if (rc) { - pr_err("%s: send vdhe/vspe params failed with rc=%d\n", - __func__, rc); - rc = -EINVAL; - goto end; - } + packed_param_size += param_size; + + /* Pack VSPE header + data */ + param_hdr.param_id = DOLBY_PARAM_ID_VSPE; + param_size = DOLBY_PARAM_VSPE_LENGTH * sizeof(uint32_t); + param_hdr.param_size = param_size; + + if (is_custom_stereo_enabled) + param_data = NULL; + else + param_data = (u8 *) &ds2_dap_params[cdev] + .params_val[DOLBY_PARAM_VSPE_OFFSET]; + + rc = q6common_pack_pp_params(packed_param_data + packed_param_size, + ¶m_hdr, param_data, ¶m_size); + if (rc) { + pr_err("%s: Failed to pack params for dolby vspe, error %d\n", + __func__, rc); + goto end; + } + packed_param_size += param_size; + + rc = adm_set_pp_params(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, NULL, + packed_param_data, packed_param_size); + if (rc) { + pr_err("%s: send vdhe/vspe params failed with rc=%d\n", + __func__, rc); + rc = -EINVAL; + goto end; } end: - kfree(param_val); + kfree(packed_param_data); return rc; } int qti_set_custom_stereo_on(int port_id, int copp_idx, bool is_custom_stereo_on) { - + struct custom_stereo_param custom_stereo; + struct param_hdr_v3 param_hdr; uint16_t op_FL_ip_FL_weight; uint16_t op_FL_ip_FR_weight; uint16_t op_FR_ip_FL_weight; uint16_t op_FR_ip_FR_weight; - - int32_t *update_params_value32 = NULL, rc = 0; - int32_t *param_val = NULL; - int16_t *update_params_value16 = 0; - uint32_t params_length_bytes = CUSTOM_STEREO_PAYLOAD_SIZE * - sizeof(uint32_t); - uint32_t avail_length = params_length_bytes; + int rc = 0; if ((port_id != SLIMBUS_0_RX) && (port_id != RT_PROXY_PORT_001_RX)) { pr_debug("%s:No Custom stereo for port:0x%x\n", __func__, port_id); - goto skip_send_cmd; + return 0; } + memset(&custom_stereo, 0, sizeof(custom_stereo)); + memset(¶m_hdr, 0, sizeof(param_hdr)); pr_debug("%s: port 0x%x, copp_idx %d, is_custom_stereo_on %d\n", __func__, port_id, copp_idx, is_custom_stereo_on); if (is_custom_stereo_on) { @@ -346,76 +374,50 @@ int qti_set_custom_stereo_on(int port_id, int copp_idx, op_FR_ip_FR_weight = Q14_GAIN_UNITY; } - update_params_value32 = kzalloc(params_length_bytes, GFP_KERNEL); - if (!update_params_value32) { - rc = -ENOMEM; - goto skip_send_cmd; - } - param_val = update_params_value32; - if (avail_length < 2 * sizeof(uint32_t)) - goto skip_send_cmd; - *update_params_value32++ = MTMX_MODULE_ID_DEFAULT_CHMIXER; - *update_params_value32++ = DEFAULT_CHMIXER_PARAM_ID_COEFF; - avail_length = avail_length - (2 * sizeof(uint32_t)); - - update_params_value16 = (int16_t *)update_params_value32; - if (avail_length < 10 * sizeof(uint16_t)) - goto skip_send_cmd; - *update_params_value16++ = CUSTOM_STEREO_CMD_PARAM_SIZE; - /* for alignment only*/ - *update_params_value16++ = 0; + param_hdr.module_id = MTMX_MODULE_ID_DEFAULT_CHMIXER; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DEFAULT_CHMIXER_PARAM_ID_COEFF; + param_hdr.param_size = sizeof(struct custom_stereo_param); + /* index is 32-bit param in little endian*/ - *update_params_value16++ = CUSTOM_STEREO_INDEX_PARAM; - *update_params_value16++ = 0; + custom_stereo.index = CUSTOM_STEREO_INDEX_PARAM; + custom_stereo.reserved = 0; /* for stereo mixing num out ch*/ - *update_params_value16++ = CUSTOM_STEREO_NUM_OUT_CH; + custom_stereo.num_out_ch = CUSTOM_STEREO_NUM_OUT_CH; /* for stereo mixing num in ch*/ - *update_params_value16++ = CUSTOM_STEREO_NUM_IN_CH; + custom_stereo.num_in_ch = CUSTOM_STEREO_NUM_IN_CH; /* Out ch map FL/FR*/ - *update_params_value16++ = PCM_CHANNEL_FL; - *update_params_value16++ = PCM_CHANNEL_FR; + custom_stereo.out_fl = PCM_CHANNEL_FL; + custom_stereo.out_fr = PCM_CHANNEL_FR; /* In ch map FL/FR*/ - *update_params_value16++ = PCM_CHANNEL_FL; - *update_params_value16++ = PCM_CHANNEL_FR; - avail_length = avail_length - (10 * sizeof(uint16_t)); + custom_stereo.in_fl = PCM_CHANNEL_FL; + custom_stereo.in_fr = PCM_CHANNEL_FR; + /* weighting coefficients as name suggests, * mixing will be done according to these coefficients */ - if (avail_length < 4 * sizeof(uint16_t)) - goto skip_send_cmd; - *update_params_value16++ = op_FL_ip_FL_weight; - *update_params_value16++ = op_FL_ip_FR_weight; - *update_params_value16++ = op_FR_ip_FL_weight; - *update_params_value16++ = op_FR_ip_FR_weight; - avail_length = avail_length - (4 * sizeof(uint16_t)); - if (params_length_bytes != 0) { - rc = adm_dolby_dap_send_params(port_id, copp_idx, - (char *)param_val, - params_length_bytes); - if (rc) { - pr_err("%s: send params failed rc=%d\n", __func__, rc); - rc = -EINVAL; - goto skip_send_cmd; - } + custom_stereo.op_FL_ip_FL_weight = op_FL_ip_FL_weight; + custom_stereo.op_FL_ip_FR_weight = op_FL_ip_FR_weight; + custom_stereo.op_FR_ip_FL_weight = op_FR_ip_FL_weight; + custom_stereo.op_FR_ip_FR_weight = op_FR_ip_FR_weight; + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (u8 *) &custom_stereo); + if (rc) { + pr_err("%s: send params failed rc=%d\n", __func__, rc); + return -EINVAL; } - kfree(param_val); + return 0; -skip_send_cmd: - pr_err("%s: insufficient memory, send cmd failed\n", - __func__); - kfree(param_val); - return rc; } static int dap_set_custom_stereo_onoff(int dev_map_idx, bool is_custom_stereo_enabled) { + uint32_t enable = is_custom_stereo_enabled ? 1 : 0; + struct param_hdr_v3 param_hdr; + int rc = 0; - int32_t *update_params_value = NULL, rc = 0; - int32_t *param_val = NULL; - uint32_t params_length_bytes = (TOTAL_LENGTH_DOLBY_PARAM + - DOLBY_PARAM_PAYLOAD_SIZE) * sizeof(uint32_t); if ((dev_map[dev_map_idx].port_id != SLIMBUS_0_RX) && (dev_map[dev_map_idx].port_id != RT_PROXY_PORT_001_RX)) { pr_debug("%s:No Custom stereo for port:0x%x\n", @@ -429,41 +431,25 @@ static int dap_set_custom_stereo_onoff(int dev_map_idx, goto end; } + memset(¶m_hdr, 0, sizeof(param_hdr)); + /* DAP custom stereo */ msm_ds2_dap_set_vspe_vdhe(dev_map_idx, is_custom_stereo_enabled); - update_params_value = kzalloc(params_length_bytes, GFP_KERNEL); - if (!update_params_value) { - pr_err("%s: params memory alloc failed\n", __func__); - rc = -ENOMEM; - goto end; - } - params_length_bytes = 0; - param_val = update_params_value; - *update_params_value++ = DOLBY_BUNDLE_MODULE_ID; - *update_params_value++ = DOLBY_ENABLE_CUSTOM_STEREO; - *update_params_value++ = sizeof(uint32_t); - if (is_custom_stereo_enabled) - *update_params_value++ = 1; - else - *update_params_value++ = 0; - params_length_bytes += (DOLBY_PARAM_PAYLOAD_SIZE + 1) * - sizeof(uint32_t); - pr_debug("%s: valid param length: %d\n", __func__, params_length_bytes); - if (params_length_bytes) { - rc = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id, - dev_map[dev_map_idx].copp_idx, - (char *)param_val, - params_length_bytes); - if (rc) { - pr_err("%s: custom stereo param failed with rc=%d\n", - __func__, rc); - rc = -EINVAL; - goto end; - } + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DOLBY_ENABLE_CUSTOM_STEREO; + param_hdr.param_size = sizeof(enable); + + rc = adm_pack_and_set_one_pp_param(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, + param_hdr, (u8 *) &enable); + if (rc) { + pr_err("%s: set custom stereo enable failed with rc=%d\n", + __func__, rc); + rc = -EINVAL; } end: - kfree(param_val); return rc; } @@ -652,8 +638,11 @@ static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) { int rc = 0, i = 0, port_id, copp_idx; /* Account for 32 bit integer allocation */ - int32_t param_sz = (ADM_GET_TOPO_MODULE_LIST_LENGTH / sizeof(uint32_t)); + int32_t param_sz = + (ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH / sizeof(uint32_t)); int32_t *update_param_val = NULL; + struct module_instance_info mod_inst_info; + int mod_inst_info_sz = 0; if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); @@ -661,10 +650,12 @@ static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) goto end; } + memset(&mod_inst_info, 0, sizeof(mod_inst_info)); port_id = dev_map[dev_map_idx].port_id; copp_idx = dev_map[dev_map_idx].copp_idx; pr_debug("%s: port_id 0x%x copp_idx %d\n", __func__, port_id, copp_idx); - update_param_val = kzalloc(ADM_GET_TOPO_MODULE_LIST_LENGTH, GFP_KERNEL); + update_param_val = + kzalloc(ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH, GFP_KERNEL); if (!update_param_val) { pr_err("%s, param memory alloc failed\n", __func__); rc = -ENOMEM; @@ -673,9 +664,10 @@ static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) if (!ds2_dap_params_states.dap_bypass) { /* get modules from dsp */ - rc = adm_get_pp_topo_module_list(port_id, copp_idx, - ADM_GET_TOPO_MODULE_LIST_LENGTH, - (char *)update_param_val); + rc = adm_get_pp_topo_module_list_v2( + port_id, copp_idx, + ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH, + update_param_val); if (rc < 0) { pr_err("%s:topo list port %d, err %d,copp_idx %d\n", __func__, port_id, copp_idx, rc); @@ -689,11 +681,15 @@ static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) rc = -EINVAL; goto end; } + + mod_inst_info_sz = sizeof(struct module_instance_info) / + sizeof(uint32_t); /* Turn off modules */ - for (i = 1; i < update_param_val[0]; i++) { + for (i = 1; i < update_param_val[0] * mod_inst_info_sz; + i += mod_inst_info_sz) { if (!msm_ds2_dap_can_enable_module( - update_param_val[i]) || - (update_param_val[i] == DS2_MODULE_ID)) { + update_param_val[i]) || + (update_param_val[i] == DS2_MODULE_ID)) { pr_debug("%s: Do not enable/disable %d\n", __func__, update_param_val[i]); continue; @@ -701,15 +697,21 @@ static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) pr_debug("%s: param disable %d\n", __func__, update_param_val[i]); - adm_param_enable(port_id, copp_idx, update_param_val[i], - MODULE_DISABLE); + memcpy(&mod_inst_info, &update_param_val[i], + sizeof(mod_inst_info)); + adm_param_enable_v2(port_id, copp_idx, + mod_inst_info, + MODULE_DISABLE); } } else { msm_ds2_dap_send_cal_data(dev_map_idx); } - adm_param_enable(port_id, copp_idx, DS2_MODULE_ID, - !ds2_dap_params_states.dap_bypass); + + mod_inst_info.module_id = DS2_MODULE_ID; + mod_inst_info.instance_id = INSTANCE_ID_0; + adm_param_enable_v2(port_id, copp_idx, mod_inst_info, + !ds2_dap_params_states.dap_bypass); end: kfree(update_param_val); return rc; @@ -885,17 +887,22 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) { int rc = 0, i = 0, j = 0; /*Account for 32 bit integer allocation */ - int32_t param_sz = (ADM_GET_TOPO_MODULE_LIST_LENGTH / sizeof(uint32_t)); + int32_t param_sz = + (ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH / sizeof(uint32_t)); int32_t *mod_list = NULL; int port_id = 0, copp_idx = -1; bool cs_onoff = ds2_dap_params_states.custom_stereo_onoff; int ramp_wait = DOLBY_SOFT_VOLUME_PERIOD; + struct module_instance_info mod_inst_info; + int mod_inst_info_sz = 0; pr_debug("%s: bypass type %d bypass %d custom stereo %d\n", __func__, ds2_dap_params_states.dap_bypass_type, ds2_dap_params_states.dap_bypass, ds2_dap_params_states.custom_stereo_onoff); - mod_list = kzalloc(ADM_GET_TOPO_MODULE_LIST_LENGTH, GFP_KERNEL); + memset(&mod_inst_info, 0, sizeof(mod_inst_info)); + mod_list = + kzalloc(ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH, GFP_KERNEL); if (!mod_list) { pr_err("%s: param memory alloc failed\n", __func__); rc = -ENOMEM; @@ -922,9 +929,10 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) } /* getmodules from dsp */ - rc = adm_get_pp_topo_module_list(port_id, copp_idx, - ADM_GET_TOPO_MODULE_LIST_LENGTH, - (char *)mod_list); + rc = adm_get_pp_topo_module_list_v2( + port_id, copp_idx, + ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH, + mod_list); if (rc < 0) { pr_err("%s:adm get topo list port %d", __func__, port_id); @@ -976,8 +984,11 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) /* if dap bypass is set */ if (ds2_dap_params_states.dap_bypass) { /* Turn off dap module */ - adm_param_enable(port_id, copp_idx, - DS2_MODULE_ID, MODULE_DISABLE); + mod_inst_info.module_id = DS2_MODULE_ID; + mod_inst_info.instance_id = INSTANCE_ID_0; + adm_param_enable_v2(port_id, copp_idx, + mod_inst_info, + MODULE_DISABLE); /* * If custom stereo is on at the time of bypass, * switch off custom stereo on dap and turn on @@ -1000,8 +1011,13 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) copp_idx, rc); } } + + mod_inst_info_sz = + sizeof(struct module_instance_info) / + sizeof(uint32_t); /* Turn on qti modules */ - for (j = 1; j < mod_list[0]; j++) { + for (j = 1; j < mod_list[0] * mod_inst_info_sz; + j += mod_inst_info_sz) { if (!msm_ds2_dap_can_enable_module( mod_list[j]) || mod_list[j] == @@ -1009,9 +1025,11 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) continue; pr_debug("%s: param enable %d\n", __func__, mod_list[j]); - adm_param_enable(port_id, copp_idx, - mod_list[j], - MODULE_ENABLE); + memcpy(&mod_inst_info, &mod_list[j], + sizeof(mod_inst_info)); + adm_param_enable_v2(port_id, copp_idx, + mod_inst_info, + MODULE_ENABLE); } /* Add adm api to resend calibration on port */ @@ -1026,7 +1044,8 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) } } else { /* Turn off qti modules */ - for (j = 1; j < mod_list[0]; j++) { + for (j = 1; j < mod_list[0] * mod_inst_info_sz; + j += mod_inst_info_sz) { if (!msm_ds2_dap_can_enable_module( mod_list[j]) || mod_list[j] == @@ -1034,15 +1053,20 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) continue; pr_debug("%s: param disable %d\n", __func__, mod_list[j]); - adm_param_enable(port_id, copp_idx, - mod_list[j], - MODULE_DISABLE); + memcpy(&mod_inst_info, &mod_list[j], + sizeof(mod_inst_info)); + adm_param_enable_v2(port_id, copp_idx, + mod_inst_info, + MODULE_DISABLE); } /* Enable DAP modules */ pr_debug("%s:DS2 param enable\n", __func__); - adm_param_enable(port_id, copp_idx, - DS2_MODULE_ID, MODULE_ENABLE); + mod_inst_info.module_id = DS2_MODULE_ID; + mod_inst_info.instance_id = INSTANCE_ID_0; + adm_param_enable_v2(port_id, copp_idx, + mod_inst_info, + MODULE_ENABLE); /* * If custom stereo is on at the time of dap on, * switch off custom stereo on qti channel mixer @@ -1101,19 +1125,19 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) { - int rc = 0; - int32_t *update_params_value = NULL, *params_value = NULL; - uint32_t params_length = (DOLBY_PARAM_INT_ENDP_LENGTH + - DOLBY_PARAM_PAYLOAD_SIZE) * sizeof(uint32_t); + uint32_t offset = 0; + struct param_hdr_v3 param_hdr; int cache_device = 0; struct ds2_dap_params_s *ds2_ap_params_obj = NULL; int32_t *modified_param = NULL; + int rc = 0; if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); rc = -EINVAL; goto end; } + memset(¶m_hdr, 0, sizeof(param_hdr)); cache_device = dev_map[dev_map_idx].cache_dev; ds2_ap_params_obj = &ds2_dap_params[cache_device]; @@ -1122,12 +1146,6 @@ static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) pr_debug("%s: endp - %pK %pK\n", __func__, &ds2_dap_params[cache_device], ds2_ap_params_obj); - params_value = kzalloc(params_length, GFP_KERNEL); - if (!params_value) { - rc = -ENOMEM; - goto end; - } - if (dev_map[dev_map_idx].port_id == DOLBY_INVALID_PORT_ID) { pr_err("%s: invalid port\n", __func__); rc = -EINVAL; @@ -1141,21 +1159,20 @@ static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) goto end; } - update_params_value = params_value; - *update_params_value++ = DOLBY_BUNDLE_MODULE_ID; - *update_params_value++ = DOLBY_PARAM_ID_INIT_ENDP; - *update_params_value++ = DOLBY_PARAM_INT_ENDP_LENGTH * sizeof(uint32_t); - *update_params_value++ = ds2_ap_params_obj->params_val[ - ds2_dap_params_offset[endp_idx]]; + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DOLBY_PARAM_ID_INIT_ENDP; + param_hdr.param_size = sizeof(offset); + offset = ds2_ap_params_obj->params_val[ds2_dap_params_offset[endp_idx]]; pr_debug("%s: off %d, length %d\n", __func__, ds2_dap_params_offset[endp_idx], ds2_dap_params_length[endp_idx]); pr_debug("%s: param 0x%x, param val %d\n", __func__, ds2_dap_params_id[endp_idx], ds2_ap_params_obj-> params_val[ds2_dap_params_offset[endp_idx]]); - rc = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id, - dev_map[dev_map_idx].copp_idx, - (char *)params_value, params_length); + rc = adm_pack_and_set_one_pp_param(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, + param_hdr, (u8 *) &offset); if (rc) { pr_err("%s: send dolby params failed rc %d\n", __func__, rc); rc = -EINVAL; @@ -1172,19 +1189,17 @@ static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) ds2_ap_params_obj->dap_params_modified[endp_idx] = 0x00010001; end: - kfree(params_value); return rc; } static int msm_ds2_dap_send_cached_params(int dev_map_idx, int commit) { - int32_t *update_params_value = NULL, *params_value = NULL; - uint32_t idx, i, j, ret = 0; - uint32_t params_length = (TOTAL_LENGTH_DOLBY_PARAM + - (MAX_DS2_PARAMS - 1) * - DOLBY_PARAM_PAYLOAD_SIZE) * - sizeof(uint32_t); + uint8_t *packed_params = NULL; + uint32_t packed_params_size = 0; + uint32_t param_size = 0; + struct param_hdr_v3 param_hdr; + uint32_t idx, i, ret = 0; int cache_device = 0; struct ds2_dap_params_s *ds2_ap_params_obj = NULL; int32_t *modified_param = NULL; @@ -1194,6 +1209,7 @@ static int msm_ds2_dap_send_cached_params(int dev_map_idx, ret = -EINVAL; goto end; } + memset(¶m_hdr, 0, sizeof(param_hdr)); cache_device = dev_map[dev_map_idx].cache_dev; /* Use off profile cache in only for soft bypass */ @@ -1207,12 +1223,16 @@ static int msm_ds2_dap_send_cached_params(int dev_map_idx, pr_debug("%s: cached param - %pK %pK, cache_device %d\n", __func__, &ds2_dap_params[cache_device], ds2_ap_params_obj, cache_device); - params_value = kzalloc(params_length, GFP_KERNEL); - if (!params_value) { - pr_err("%s: params memory alloc failed\n", __func__); - ret = -ENOMEM; - goto end; - } + + /* + * Allocate the max space needed. This is enough space to hold the + * header for each param plus the total size of all the params. + */ + packed_params_size = (sizeof(param_hdr) * (MAX_DS2_PARAMS - 1)) + + (TOTAL_LENGTH_DOLBY_PARAM * sizeof(uint32_t)); + packed_params = kzalloc(packed_params_size, GFP_KERNEL); + if (!packed_params) + return -ENOMEM; if (dev_map[dev_map_idx].port_id == DOLBY_INVALID_PORT_ID) { pr_err("%s: invalid port id\n", __func__); @@ -1227,8 +1247,7 @@ static int msm_ds2_dap_send_cached_params(int dev_map_idx, goto end; } - update_params_value = params_value; - params_length = 0; + packed_params_size = 0; for (i = 0; i < (MAX_DS2_PARAMS-1); i++) { /*get the pointer to the param modified array in the cache*/ modified_param = ds2_ap_params_obj->dap_params_modified; @@ -1241,28 +1260,33 @@ static int msm_ds2_dap_send_cached_params(int dev_map_idx, if (!msm_ds2_dap_check_is_param_modified(modified_param, i, commit)) continue; - *update_params_value++ = DOLBY_BUNDLE_MODULE_ID; - *update_params_value++ = ds2_dap_params_id[i]; - *update_params_value++ = ds2_dap_params_length[i] * - sizeof(uint32_t); + + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = ds2_dap_params_id[i]; + param_hdr.param_size = + ds2_dap_params_length[i] * sizeof(uint32_t); + idx = ds2_dap_params_offset[i]; - for (j = 0; j < ds2_dap_params_length[i]; j++) { - *update_params_value++ = - ds2_ap_params_obj->params_val[idx+j]; - pr_debug("%s: id 0x%x,val %d\n", __func__, - ds2_dap_params_id[i], - ds2_ap_params_obj->params_val[idx+j]); + ret = q6common_pack_pp_params( + packed_params + packed_params_size, ¶m_hdr, + (u8 *) &ds2_ap_params_obj->params_val[idx], + ¶m_size); + if (ret) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, ret); + goto end; } - params_length += (DOLBY_PARAM_PAYLOAD_SIZE + - ds2_dap_params_length[i]) * sizeof(uint32_t); + + packed_params_size += param_size; } - pr_debug("%s: valid param length: %d\n", __func__, params_length); - if (params_length) { - ret = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id, - dev_map[dev_map_idx].copp_idx, - (char *)params_value, - params_length); + pr_debug("%s: total packed param length: %d\n", __func__, + packed_params_size); + if (packed_params_size) { + ret = adm_set_pp_params(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, NULL, + packed_params, packed_params_size); if (ret) { pr_err("%s: send dolby params failed ret %d\n", __func__, ret); @@ -1285,7 +1309,7 @@ static int msm_ds2_dap_send_cached_params(int dev_map_idx, } } end: - kfree(params_value); + kfree(packed_params); return ret; } @@ -1523,11 +1547,12 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) { int rc = 0, i, port_id = 0, copp_idx = -1; struct dolby_param_data *dolby_data = (struct dolby_param_data *)arg; - int32_t *update_params_value = NULL, *params_value = NULL; + int32_t *params_value = NULL; uint32_t params_length = DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM * sizeof(uint32_t); uint32_t param_payload_len = DOLBY_PARAM_PAYLOAD_SIZE * sizeof(uint32_t); + struct param_hdr_v3 param_hdr; /* Return error on get param in soft or hard bypass */ if (ds2_dap_params_states.dap_bypass == true) { @@ -1573,17 +1598,15 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) params_value = kzalloc(params_length + param_payload_len, GFP_KERNEL); - if (!params_value) { - rc = -ENOMEM; - goto end; - } + if (!params_value) + return -ENOMEM; + memset(¶m_hdr, 0, sizeof(param_hdr)); if (dolby_data->param_id == DOLBY_PARAM_ID_VER) { - rc = adm_get_params(port_id, copp_idx, - DOLBY_BUNDLE_MODULE_ID, - DOLBY_PARAM_ID_VER, - params_length + param_payload_len, - (char *)params_value); + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DOLBY_PARAM_ID_VER; + param_hdr.param_size = params_length + param_payload_len; } else { for (i = 0; i < MAX_DS2_PARAMS; i++) if (ds2_dap_params_id[i] == @@ -1596,25 +1619,25 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) goto end; } else { params_length = - ds2_dap_params_length[i] * sizeof(uint32_t); + ds2_dap_params_length[i] * sizeof(uint32_t); - rc = adm_get_params(port_id, copp_idx, - DOLBY_BUNDLE_MODULE_ID, - ds2_dap_params_id[i], - params_length + - param_payload_len, - (char *)params_value); + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = ds2_dap_params_id[i]; + param_hdr.param_size = + params_length + param_payload_len; } } + rc = adm_get_pp_params(port_id, copp_idx, ADM_CLIENT_ID_DEFAULT, NULL, + ¶m_hdr, (u8 *) params_value); if (rc) { pr_err("%s: get parameters failed rc %d\n", __func__, rc); rc = -EINVAL; goto end; } - update_params_value = params_value; - if (copy_to_user((void *)dolby_data->data, - &update_params_value[DOLBY_PARAM_PAYLOAD_SIZE], - (dolby_data->length * sizeof(uint32_t)))) { + if (copy_to_user((void __user *) dolby_data->data, + ¶ms_value[DOLBY_PARAM_PAYLOAD_SIZE], + (dolby_data->length * sizeof(uint32_t)))) { pr_err("%s: error getting param\n", __func__); rc = -EFAULT; goto end; @@ -1633,6 +1656,7 @@ static int msm_ds2_dap_param_visualizer_control_get(u32 cmd, void *arg) uint32_t offset, length, params_length; uint32_t param_payload_len = DOLBY_PARAM_PAYLOAD_SIZE * sizeof(uint32_t); + struct param_hdr_v3 param_hdr; for (i = 0; i < DS2_DEVICES_ALL; i++) { if ((dev_map[i].active)) { @@ -1651,6 +1675,7 @@ static int msm_ds2_dap_param_visualizer_control_get(u32 cmd, void *arg) goto end; } + memset(¶m_hdr, 0, sizeof(param_hdr)); length = ds2_dap_params[cache_dev].params_val[DOLBY_PARAM_VCNB_OFFSET]; if (length > DOLBY_PARAM_VCNB_MAX_LENGTH || length <= 0) { @@ -1665,6 +1690,7 @@ static int msm_ds2_dap_param_visualizer_control_get(u32 cmd, void *arg) visualizer_data = kzalloc(params_length, GFP_KERNEL); if (!visualizer_data) { + pr_err("%s: params memory alloc failed\n", __func__); ret = -ENOMEM; dolby_data->length = 0; goto end; @@ -1682,11 +1708,13 @@ static int msm_ds2_dap_param_visualizer_control_get(u32 cmd, void *arg) offset = 0; params_length = length * sizeof(uint32_t); - ret = adm_get_params(port_id, copp_idx, - DOLBY_BUNDLE_MODULE_ID, - DOLBY_PARAM_ID_VCBG, - params_length + param_payload_len, - (((char *)(visualizer_data)) + offset)); + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DOLBY_PARAM_ID_VCBG; + param_hdr.param_size = length * sizeof(uint32_t) + param_payload_len; + ret = adm_get_pp_params(port_id, copp_idx, ADM_CLIENT_ID_DEFAULT, NULL, + ¶m_hdr, + (((char *) (visualizer_data)) + offset)); if (ret) { pr_err("%s: get parameters failed ret %d\n", __func__, ret); ret = -EINVAL; @@ -1694,11 +1722,13 @@ static int msm_ds2_dap_param_visualizer_control_get(u32 cmd, void *arg) goto end; } offset = length * sizeof(uint32_t); - ret = adm_get_params(port_id, copp_idx, - DOLBY_BUNDLE_MODULE_ID, - DOLBY_PARAM_ID_VCBE, - params_length + param_payload_len, - (((char *)(visualizer_data)) + offset)); + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DOLBY_PARAM_ID_VCBE; + param_hdr.param_size = length * sizeof(uint32_t) + param_payload_len; + ret = adm_get_pp_params(port_id, copp_idx, ADM_CLIENT_ID_DEFAULT, NULL, + ¶m_hdr, + (((char *) (visualizer_data)) + offset)); if (ret) { pr_err("%s: get parameters failed ret %d\n", __func__, ret); ret = -EINVAL; diff --git a/asoc/msm-ds2-dap-config.h b/asoc/msm-ds2-dap-config.h index c90bd8fb83a4..4d6b5eb3d210 100644 --- a/asoc/msm-ds2-dap-config.h +++ b/asoc/msm-ds2-dap-config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014, 2017-2018 The Linux Foundation. All rights reserved. * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. @@ -33,7 +33,6 @@ struct dolby_param_license32 { compat_uptr_t license_key; }; - #define SNDRV_DEVDEP_DAP_IOCTL_SET_PARAM32\ _IOWR('U', 0x10, struct dolby_param_data32) #define SNDRV_DEVDEP_DAP_IOCTL_GET_PARAM32\ @@ -63,6 +62,34 @@ enum { DAP_CMD_SET_BYPASS_TYPE = 5, }; +struct custom_stereo_param { + /* Index is 32-bit param in little endian */ + u16 index; + u16 reserved; + + /* For stereo mixing, the number of out channels */ + u16 num_out_ch; + /* For stereo mixing, the number of in channels */ + u16 num_in_ch; + + /* Out channel map FL/FR*/ + u16 out_fl; + u16 out_fr; + + /* In channel map FL/FR*/ + u16 in_fl; + u16 in_fr; + + /* + * Weighting coefficients. Mixing will be done according to + * these coefficients. + */ + u16 op_FL_ip_FL_weight; + u16 op_FL_ip_FR_weight; + u16 op_FR_ip_FL_weight; + u16 op_FR_ip_FR_weight; +}; + #define DOLBY_PARAM_INT_ENDP_LENGTH 1 #define DOLBY_PARAM_INT_ENDP_OFFSET (DOLBY_PARAM_PSTG_OFFSET + \ DOLBY_PARAM_PSTG_LENGTH) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 8ebab78ac1e4..f0b7121977fb 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -789,26 +789,6 @@ int adm_set_stereo_to_custom_stereo(int port_id, int copp_idx, } EXPORT_SYMBOL(adm_set_stereo_to_custom_stereo); -/** - * adm_dolby_dap_send_params - - * command to send dolby dap params - * - * @port_id: Port ID number - * @copp_idx: copp index of ADM copp - * @params: params pointer - * @param_length: length of params - * - * Returns 0 on success or error on failure - */ -int adm_dolby_dap_send_params(int port_id, int copp_idx, char *params, - uint32_t params_length) -{ - /* Use as wrapper for adm_set_pp_params until no longer used */ - return adm_set_pp_params(port_id, copp_idx, NULL, params, - params_length); -} -EXPORT_SYMBOL(adm_dolby_dap_send_params); - /* * With pre-packed data, only the opcode differes from V5 and V6. * Use q6common_pack_pp_params to pack the data correctly. @@ -941,29 +921,6 @@ int adm_pack_and_set_one_pp_param(int port_id, int copp_idx, } EXPORT_SYMBOL(adm_pack_and_set_one_pp_param); -int adm_get_params_v2(int port_id, int copp_idx, uint32_t module_id, - uint32_t param_id, uint32_t params_length, char *params, - uint32_t client_id) -{ - struct param_hdr_v3 param_hdr; - - memset(¶m_hdr, 0, sizeof(param_hdr)); - param_hdr.module_id = module_id; - param_hdr.instance_id = INSTANCE_ID_0; - param_hdr.param_id = param_id; - param_hdr.param_size = params_length; - - return adm_get_pp_params(port_id, copp_idx, client_id, NULL, ¶m_hdr, - params); -} - -int adm_get_params(int port_id, int copp_idx, uint32_t module_id, - uint32_t param_id, uint32_t params_length, char *params) -{ - return adm_get_params_v2(port_id, copp_idx, module_id, param_id, - params_length, params, 0); -} - /* * Only one parameter can be requested at a time. Therefore, packing and sending * the request can be handled locally. @@ -1082,14 +1039,6 @@ int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id, } EXPORT_SYMBOL(adm_get_pp_params); -int adm_get_pp_topo_module_list(int port_id, int copp_idx, int32_t param_length, - char *params) -{ - return adm_get_pp_topo_module_list_v2(port_id, copp_idx, param_length, - (int32_t *) params); -} -EXPORT_SYMBOL(adm_get_pp_topo_module_list); - int adm_get_pp_topo_module_list_v2(int port_id, int copp_idx, int32_t param_length, int32_t *returned_params) diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 0f7e7b240428..bc3fdcfabfc5 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -93,9 +93,6 @@ int adm_dts_eagle_get(int port_id, int copp_idx, int param_id, void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate); -int adm_get_params(int port_id, int copp_idx, uint32_t module_id, - uint32_t param_id, uint32_t params_length, char *params); - int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id, struct mem_mapping_hdr *mem_hdr, struct param_hdr_v3 *param_hdr, u8 *returned_param_data); @@ -103,9 +100,6 @@ int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id, int adm_send_params_v5(int port_id, int copp_idx, char *params, uint32_t params_length); -int adm_dolby_dap_send_params(int port_id, int copp_idx, char *params, - uint32_t params_length); - int adm_set_pp_params(int port_id, int copp_idx, struct mem_mapping_hdr *mem_hdr, u8 *param_data, u32 params_size); -- GitLab From f20d5b7ea55335d696a2958bb6a5b877f6aa48d2 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Mon, 29 Jan 2018 17:02:58 -0800 Subject: [PATCH 0216/1645] ASoC: dsp: Update ASM driver to support Instance ID Add support to set and get ASM module params with Instance ID support. Maintain support for non Instance ID set and get param structures as well. Use common pack and set param functions to set and get parameters to DSP instead of handling them at an individual module level. CRs-Fixed: 2151551 Change-Id: I633ce10a83d9033d42fadb7bad0b26842459df84 Signed-off-by: Vignesh Kulothungan --- dsp/q6asm.c | 792 ++++++++++++++----------------------- include/dsp/apr_audio-v2.h | 115 +----- include/dsp/q6asm-v2.h | 11 + 3 files changed, 328 insertions(+), 590 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 3bcf4f1cd05b..fe1b39acb8fd 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "adsp_err.h" #define TRUE 0x01 @@ -1898,6 +1899,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) if (data->opcode == APR_BASIC_RSP_RESULT) { switch (payload[0]) { case ASM_STREAM_CMD_SET_PP_PARAMS_V2: + case ASM_STREAM_CMD_SET_PP_PARAMS_V3: if (rtac_make_asm_callback(ac->session, payload, data->payload_size)) break; @@ -1945,9 +1947,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) pr_err("%s: cmd = 0x%x returned error = 0x%x\n", __func__, payload[0], payload[1]); if (wakeup_flag) { - if ((is_adsp_reg_event(payload[0]) >= 0) - || (payload[0] == - ASM_STREAM_CMD_SET_PP_PARAMS_V2)) + if ((is_adsp_reg_event(payload[0]) >= + 0) || + (payload[0] == + ASM_STREAM_CMD_SET_PP_PARAMS_V2) || + (payload[0] == + ASM_STREAM_CMD_SET_PP_PARAMS_V3)) atomic_set(&ac->cmd_state_pp, payload[1]); else @@ -1960,7 +1965,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) return 0; } if ((is_adsp_reg_event(payload[0]) >= 0) || - (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2)) { + (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2) || + (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V3)) { if (atomic_read(&ac->cmd_state_pp) && wakeup_flag) { atomic_set(&ac->cmd_state_pp, 0); @@ -2619,6 +2625,174 @@ static void q6asm_add_mmaphdr(struct audio_client *ac, struct apr_hdr *hdr, hdr->pkt_size = pkt_size; } +/** + * q6asm_set_pp_params + * command to set ASM parameter data + * send memory mapping header for out of band case + * send pre-packed parameter data for in band case + * + * @ac: audio client handle + * @mem_hdr: memory mapping header + * @param_data: pre-packed parameter payload + * @param_size: size of pre-packed parameter data + * + * Returns 0 on success or error on failure + */ +int q6asm_set_pp_params(struct audio_client *ac, + struct mem_mapping_hdr *mem_hdr, u8 *param_data, + u32 param_size) +{ + struct asm_stream_cmd_set_pp_params *asm_set_param = NULL; + int pkt_size = 0; + int ret = 0; + + if (ac == NULL) { + pr_err("%s: Audio Client is NULL\n", __func__); + return -EINVAL; + } else if (ac->apr == NULL) { + pr_err("%s: APR pointer is NULL\n", __func__); + return -EINVAL; + } + + pkt_size = sizeof(struct asm_stream_cmd_set_pp_params); + /* Add param size to packet size when sending in-band only */ + if (param_data != NULL) + pkt_size += param_size; + asm_set_param = kzalloc(pkt_size, GFP_KERNEL); + if (!asm_set_param) + return -ENOMEM; + + q6asm_add_hdr_async(ac, &asm_set_param->apr_hdr, pkt_size, TRUE); + + /* With pre-packed data, only the opcode differs from V2 and V3. */ + if (q6common_is_instance_id_supported()) + asm_set_param->apr_hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V3; + else + asm_set_param->apr_hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; + + asm_set_param->payload_size = param_size; + + if (mem_hdr != NULL) { + /* Out of band case */ + asm_set_param->mem_hdr = *mem_hdr; + } else if (param_data != NULL) { + /* + * In band case. Parameter data must be pre-packed with its + * header before calling this function. Use + * q6common_pack_pp_params to pack parameter data and header + * correctly. + */ + memcpy(&asm_set_param->param_data, param_data, param_size); + } else { + pr_err("%s: Received NULL pointers for both mem header and param data\n", + __func__); + ret = -EINVAL; + goto done; + } + + atomic_set(&ac->cmd_state_pp, -1); + ret = apr_send_pkt(ac->apr, (uint32_t *)asm_set_param); + if (ret < 0) { + pr_err("%s: apr send failed rc %d\n", __func__, ret); + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(ac->cmd_wait, + atomic_read(&ac->cmd_state_pp) >= 0, 5 * HZ); + if (!ret) { + pr_err("%s: timeout sending apr pkt\n", __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (atomic_read(&ac->cmd_state_pp) > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(atomic_read(&ac->cmd_state_pp))); + ret = adsp_err_get_lnx_err_code(atomic_read(&ac->cmd_state_pp)); + goto done; + } + ret = 0; +done: + kfree(asm_set_param); + return ret; +} +EXPORT_SYMBOL(q6asm_set_pp_params); + +/** + * q6asm_pack_and_set_pp_param_in_band + * command to pack and set parameter data for in band case + * + * @ac: audio client handle + * @param_hdr: parameter header + * @param_data: parameter data + * + * Returns 0 on success or error on failure + */ +int q6asm_pack_and_set_pp_param_in_band(struct audio_client *ac, + struct param_hdr_v3 param_hdr, + u8 *param_data) +{ + u8 *packed_data = NULL; + u32 packed_size = sizeof(union param_hdrs) + param_hdr.param_size; + int ret = 0; + + if (ac == NULL) { + pr_err("%s: Audio Client is NULL\n", __func__); + return -EINVAL; + } + + packed_data = kzalloc(packed_size, GFP_KERNEL); + if (packed_data == NULL) + return -ENOMEM; + + ret = q6common_pack_pp_params(packed_data, ¶m_hdr, param_data, + &packed_size); + if (ret) { + pr_err("%s: Failed to pack params, error %d\n", __func__, ret); + goto done; + } + + ret = q6asm_set_pp_params(ac, NULL, packed_data, packed_size); +done: + kfree(packed_data); + return ret; +} +EXPORT_SYMBOL(q6asm_pack_and_set_pp_param_in_band); + +/** + * q6asm_set_soft_volume_module_instance_ids + * command to set module and instance ids for soft volume + * + * @instance: soft volume instance + * @param_hdr: parameter header + * + * Returns 0 on success or error on failure + */ +int q6asm_set_soft_volume_module_instance_ids(int instance, + struct param_hdr_v3 *param_hdr) +{ + if (param_hdr == NULL) { + pr_err("%s: Param header is NULL\n", __func__); + return -EINVAL; + } + + switch (instance) { + case SOFT_VOLUME_INSTANCE_2: + param_hdr->module_id = ASM_MODULE_ID_VOL_CTRL2; + param_hdr->instance_id = INSTANCE_ID_0; + return 0; + case SOFT_VOLUME_INSTANCE_1: + param_hdr->module_id = ASM_MODULE_ID_VOL_CTRL; + param_hdr->instance_id = INSTANCE_ID_0; + return 0; + default: + pr_err("%s: Invalid instance %d\n", __func__, instance); + return -EINVAL; + } +} +EXPORT_SYMBOL(q6asm_set_soft_volume_module_instance_ids); + static int __q6asm_open_read(struct audio_client *ac, uint32_t format, uint16_t bits_per_sample, uint32_t pcm_format_block_ver, @@ -7336,67 +7510,28 @@ EXPORT_SYMBOL(q6asm_memory_unmap_regions); int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain) { struct asm_volume_ctrl_multichannel_gain multi_ch_gain; - int sz = 0; + struct param_hdr_v3 param_info; int rc = 0; - if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - + memset(¶m_info, 0, sizeof(param_info)); memset(&multi_ch_gain, 0, sizeof(multi_ch_gain)); - sz = sizeof(struct asm_volume_ctrl_multichannel_gain); - q6asm_add_hdr_async(ac, &multi_ch_gain.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - multi_ch_gain.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - multi_ch_gain.param.data_payload_addr_lsw = 0; - multi_ch_gain.param.data_payload_addr_msw = 0; - multi_ch_gain.param.mem_map_handle = 0; - multi_ch_gain.param.data_payload_size = sizeof(multi_ch_gain) - - sizeof(multi_ch_gain.hdr) - sizeof(multi_ch_gain.param); - multi_ch_gain.data.module_id = ASM_MODULE_ID_VOL_CTRL; - multi_ch_gain.data.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN; - multi_ch_gain.data.param_size = multi_ch_gain.param.data_payload_size - - sizeof(multi_ch_gain.data); - multi_ch_gain.data.reserved = 0; + + param_info.module_id = ASM_MODULE_ID_VOL_CTRL; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN; + param_info.param_size = sizeof(multi_ch_gain); + multi_ch_gain.gain_data[0].channeltype = PCM_CHANNEL_FL; multi_ch_gain.gain_data[0].gain = left_gain << 15; multi_ch_gain.gain_data[1].channeltype = PCM_CHANNEL_FR; multi_ch_gain.gain_data[1].gain = right_gain << 15; multi_ch_gain.num_channels = 2; - rc = apr_send_pkt(ac->apr, (uint32_t *) &multi_ch_gain); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, + (u8 *) &multi_ch_gain); + if (rc < 0) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, multi_ch_gain.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } + __func__, param_info.param_id, rc); - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - multi_ch_gain.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] , set-params paramid[0x%x]\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp)), - multi_ch_gain.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - rc = 0; -fail_cmd: return rc; } @@ -7412,20 +7547,14 @@ int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, uint32_t *gains, uint8_t *ch_map, bool use_default) { struct asm_volume_ctrl_multichannel_gain multich_gain; - int sz = 0; + struct param_hdr_v3 param_info; int rc = 0; int i; u8 default_chmap[VOLUME_CONTROL_MAX_CHANNELS]; if (ac == NULL) { - pr_err("%s: ac is NULL\n", __func__); - rc = -EINVAL; - goto done; - } - if (ac->apr == NULL) { - dev_err(ac->dev, "%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto done; + pr_err("%s: Audio client is NULL\n", __func__); + return -EINVAL; } if (gains == NULL) { dev_err(ac->dev, "%s: gain_list is NULL\n", __func__); @@ -7444,21 +7573,12 @@ int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, goto done; } + memset(¶m_info, 0, sizeof(param_info)); memset(&multich_gain, 0, sizeof(multich_gain)); - sz = sizeof(struct asm_volume_ctrl_multichannel_gain); - q6asm_add_hdr_async(ac, &multich_gain.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - multich_gain.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - multich_gain.param.data_payload_addr_lsw = 0; - multich_gain.param.data_payload_addr_msw = 0; - multich_gain.param.mem_map_handle = 0; - multich_gain.param.data_payload_size = sizeof(multich_gain) - - sizeof(multich_gain.hdr) - sizeof(multich_gain.param); - multich_gain.data.module_id = ASM_MODULE_ID_VOL_CTRL; - multich_gain.data.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN; - multich_gain.data.param_size = multich_gain.param.data_payload_size - - sizeof(multich_gain.data); - multich_gain.data.reserved = 0; + param_info.module_id = ASM_MODULE_ID_VOL_CTRL; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN; + param_info.param_size = sizeof(multich_gain); if (use_default) { rc = q6asm_map_channels(default_chmap, channels, false); @@ -7477,29 +7597,11 @@ int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, } multich_gain.num_channels = channels; - rc = apr_send_pkt(ac->apr, (uint32_t *) &multich_gain); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, + (u8 *) &multich_gain); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, multich_gain.data.param_id, rc); - goto done; - } - - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - multich_gain.data.param_id); - rc = -EINVAL; - goto done; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%d] , set-params paramid[0x%x]\n", - __func__, atomic_read(&ac->cmd_state_pp), - multich_gain.data.param_id); - rc = -EINVAL; - goto done; - } - rc = 0; + __func__, param_info.param_id, rc); done: return rc; } @@ -7517,62 +7619,21 @@ EXPORT_SYMBOL(q6asm_set_multich_gain); int q6asm_set_mute(struct audio_client *ac, int muteflag) { struct asm_volume_ctrl_mute_config mute; - int sz = 0; + struct param_hdr_v3 param_info; int rc = 0; - if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - - sz = sizeof(struct asm_volume_ctrl_mute_config); - q6asm_add_hdr_async(ac, &mute.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - mute.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - mute.param.data_payload_addr_lsw = 0; - mute.param.data_payload_addr_msw = 0; - mute.param.mem_map_handle = 0; - mute.param.data_payload_size = sizeof(mute) - - sizeof(mute.hdr) - sizeof(mute.param); - mute.data.module_id = ASM_MODULE_ID_VOL_CTRL; - mute.data.param_id = ASM_PARAM_ID_VOL_CTRL_MUTE_CONFIG; - mute.data.param_size = mute.param.data_payload_size - sizeof(mute.data); - mute.data.reserved = 0; + memset(&mute, 0, sizeof(mute)); + memset(¶m_info, 0, sizeof(param_info)); + param_info.module_id = ASM_MODULE_ID_VOL_CTRL; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = ASM_PARAM_ID_VOL_CTRL_MUTE_CONFIG; + param_info.param_size = sizeof(mute); mute.mute_flag = muteflag; - rc = apr_send_pkt(ac->apr, (uint32_t *) &mute); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, (u8 *) &mute); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, mute.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } - - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - mute.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp)), - mute.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - rc = 0; -fail_cmd: + __func__, param_info.param_id, rc); return rc; } EXPORT_SYMBOL(q6asm_set_mute); @@ -7580,74 +7641,28 @@ EXPORT_SYMBOL(q6asm_set_mute); static int __q6asm_set_volume(struct audio_client *ac, int volume, int instance) { struct asm_volume_ctrl_master_gain vol; - int sz = 0; - int rc = 0; - int module_id; + struct param_hdr_v3 param_info; + int rc = 0; - if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } + memset(&vol, 0, sizeof(vol)); + memset(¶m_info, 0, sizeof(param_info)); - switch (instance) { - case SOFT_VOLUME_INSTANCE_2: - module_id = ASM_MODULE_ID_VOL_CTRL2; - break; - case SOFT_VOLUME_INSTANCE_1: - default: - module_id = ASM_MODULE_ID_VOL_CTRL; - break; + rc = q6asm_set_soft_volume_module_instance_ids(instance, ¶m_info); + if (rc) { + pr_err("%s: Failed to pack soft volume module and instance IDs, error %d\n", + __func__, rc); + return rc; } - sz = sizeof(struct asm_volume_ctrl_master_gain); - q6asm_add_hdr_async(ac, &vol.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - vol.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - vol.param.data_payload_addr_lsw = 0; - vol.param.data_payload_addr_msw = 0; - vol.param.mem_map_handle = 0; - vol.param.data_payload_size = sizeof(vol) - - sizeof(vol.hdr) - sizeof(vol.param); - vol.data.module_id = module_id; - vol.data.param_id = ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; - vol.data.param_size = vol.param.data_payload_size - sizeof(vol.data); - vol.data.reserved = 0; + param_info.param_id = ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; + param_info.param_size = sizeof(vol); vol.master_gain = volume; - rc = apr_send_pkt(ac->apr, (uint32_t *) &vol); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, (u8 *) &vol); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, vol.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } - - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - vol.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp)), - vol.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } + __func__, param_info.param_id, rc); - rc = 0; -fail_cmd: return rc; } @@ -7925,67 +7940,27 @@ int q6asm_set_softpause(struct audio_client *ac, struct asm_softpause_params *pause_param) { struct asm_soft_pause_params softpause; - int sz = 0; + struct param_hdr_v3 param_info; int rc = 0; - if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } + memset(&softpause, 0, sizeof(softpause)); + memset(¶m_info, 0, sizeof(param_info)); + param_info.module_id = ASM_MODULE_ID_VOL_CTRL; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = ASM_PARAM_ID_SOFT_PAUSE_PARAMETERS; + param_info.param_size = sizeof(softpause); - sz = sizeof(struct asm_soft_pause_params); - q6asm_add_hdr_async(ac, &softpause.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - softpause.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - - softpause.param.data_payload_addr_lsw = 0; - softpause.param.data_payload_addr_msw = 0; - softpause.param.mem_map_handle = 0; - softpause.param.data_payload_size = sizeof(softpause) - - sizeof(softpause.hdr) - sizeof(softpause.param); - softpause.data.module_id = ASM_MODULE_ID_VOL_CTRL; - softpause.data.param_id = ASM_PARAM_ID_SOFT_PAUSE_PARAMETERS; - softpause.data.param_size = softpause.param.data_payload_size - - sizeof(softpause.data); - softpause.data.reserved = 0; softpause.enable_flag = pause_param->enable; softpause.period = pause_param->period; softpause.step = pause_param->step; softpause.ramping_curve = pause_param->rampingcurve; - rc = apr_send_pkt(ac->apr, (uint32_t *) &softpause); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, + (u8 *) &softpause); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, softpause.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } + __func__, param_info.param_id, rc); - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - softpause.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp)), - softpause.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - rc = 0; -fail_cmd: return rc; } EXPORT_SYMBOL(q6asm_set_softpause); @@ -7995,76 +7970,32 @@ static int __q6asm_set_softvolume(struct audio_client *ac, int instance) { struct asm_soft_step_volume_params softvol; - int sz = 0; - int rc = 0; - int module_id; + struct param_hdr_v3 param_info; + int rc = 0; - if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } + memset(&softvol, 0, sizeof(softvol)); + memset(¶m_info, 0, sizeof(param_info)); - switch (instance) { - case SOFT_VOLUME_INSTANCE_2: - module_id = ASM_MODULE_ID_VOL_CTRL2; - break; - case SOFT_VOLUME_INSTANCE_1: - default: - module_id = ASM_MODULE_ID_VOL_CTRL; - break; + rc = q6asm_set_soft_volume_module_instance_ids(instance, ¶m_info); + if (rc) { + pr_err("%s: Failed to pack soft volume module and instance IDs, error %d\n", + __func__, rc); + return rc; } - sz = sizeof(struct asm_soft_step_volume_params); - q6asm_add_hdr_async(ac, &softvol.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - softvol.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - softvol.param.data_payload_addr_lsw = 0; - softvol.param.data_payload_addr_msw = 0; - softvol.param.mem_map_handle = 0; - softvol.param.data_payload_size = sizeof(softvol) - - sizeof(softvol.hdr) - sizeof(softvol.param); - softvol.data.module_id = module_id; - softvol.data.param_id = ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS; - softvol.data.param_size = softvol.param.data_payload_size - - sizeof(softvol.data); - softvol.data.reserved = 0; + param_info.param_id = ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS; + param_info.param_size = sizeof(softvol); + softvol.period = softvol_param->period; softvol.step = softvol_param->step; softvol.ramping_curve = softvol_param->rampingcurve; - rc = apr_send_pkt(ac->apr, (uint32_t *) &softvol); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, + (u8 *) &softvol); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, softvol.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } + __func__, param_info.param_id, rc); - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - softvol.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp)), - softvol.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - rc = 0; -fail_cmd: return rc; } @@ -8116,40 +8047,27 @@ int q6asm_equalizer(struct audio_client *ac, void *eq_p) { struct asm_eq_params eq; struct msm_audio_eq_stream_config *eq_params = NULL; + struct param_hdr_v3 param_info; int i = 0; - int sz = 0; int rc = 0; if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; + pr_err("%s: Audio client is NULL\n", __func__); + return -EINVAL; } - if (eq_p == NULL) { pr_err("%s: [%d]: Invalid Eq param\n", __func__, ac->session); rc = -EINVAL; goto fail_cmd; } - sz = sizeof(struct asm_eq_params); - eq_params = (struct msm_audio_eq_stream_config *) eq_p; - q6asm_add_hdr(ac, &eq.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - eq.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - eq.param.data_payload_addr_lsw = 0; - eq.param.data_payload_addr_msw = 0; - eq.param.mem_map_handle = 0; - eq.param.data_payload_size = sizeof(eq) - - sizeof(eq.hdr) - sizeof(eq.param); - eq.data.module_id = ASM_MODULE_ID_EQUALIZER; - eq.data.param_id = ASM_PARAM_ID_EQUALIZER_PARAMETERS; - eq.data.param_size = eq.param.data_payload_size - sizeof(eq.data); + memset(&eq, 0, sizeof(eq)); + memset(¶m_info, 0, sizeof(param_info)); + eq_params = (struct msm_audio_eq_stream_config *) eq_p; + param_info.module_id = ASM_MODULE_ID_EQUALIZER; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = ASM_PARAM_ID_EQUALIZER_PARAMETERS; + param_info.param_size = sizeof(eq); eq.enable_flag = eq_params->enable; eq.num_bands = eq_params->num_bands; @@ -8175,32 +8093,11 @@ int q6asm_equalizer(struct audio_client *ac, void *eq_p) pr_debug("%s: q_factor:%d bandnum:%d\n", __func__, eq_params->eq_bands[i].q_factor, i); } - rc = apr_send_pkt(ac->apr, (uint32_t *)&eq); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, (u8 *) &eq); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, eq.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } + __func__, param_info.param_id, rc); - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - eq.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp)), - eq.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - rc = 0; fail_cmd: return rc; } @@ -8797,7 +8694,7 @@ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) mtmx_params.param_info.param_id = ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3; mtmx_params.param_info.param_max_size = - sizeof(struct asm_stream_param_data_v2) + + sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_session_time_v3_t); atomic_set(&ac->time_flag, 1); @@ -8894,72 +8791,18 @@ EXPORT_SYMBOL(q6asm_get_session_time_legacy); int q6asm_send_audio_effects_params(struct audio_client *ac, char *params, uint32_t params_length) { - char *asm_params = NULL; - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 payload_params; - int sz, rc; + int rc; pr_debug("%s:\n", __func__); - if (!ac) { - pr_err("%s: APR handle NULL\n", __func__); - return -EINVAL; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - return -EINVAL; - } - if (params == NULL) { - pr_err("%s: params NULL\n", __func__); - return -EINVAL; - } - sz = sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2) + - params_length; - asm_params = kzalloc(sz, GFP_KERNEL); - if (!asm_params) { - pr_err("%s, asm params memory alloc failed", __func__); - return -ENOMEM; - } - q6asm_add_hdr_async(ac, &hdr, (sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2) + - params_length), TRUE); - atomic_set(&ac->cmd_state_pp, -1); - hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - payload_params.data_payload_addr_lsw = 0; - payload_params.data_payload_addr_msw = 0; - payload_params.mem_map_handle = 0; - payload_params.data_payload_size = params_length; - memcpy(((u8 *)asm_params), &hdr, sizeof(struct apr_hdr)); - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr)), &payload_params, - sizeof(struct asm_stream_cmd_set_pp_params_v2)); - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2)), - params, params_length); - rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params); - if (rc < 0) { + + /* + * Leave function as wrapper for use by effects. Params must be properly + * packed. Use q6common_pack_pp_param to pack params correctly. + */ + rc = q6asm_set_pp_params(ac, NULL, params, params_length); + if (rc) pr_err("%s: audio effects set-params send failed\n", __func__); - rc = -EINVAL; - goto fail_send_param; - } - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 1*HZ); - if (!rc) { - pr_err("%s: timeout, audio effects set-params\n", __func__); - rc = -ETIMEDOUT; - goto fail_send_param; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] set-params\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_send_param; - } - rc = 0; -fail_send_param: - kfree(asm_params); return rc; } EXPORT_SYMBOL(q6asm_send_audio_effects_params); @@ -9006,7 +8849,7 @@ int q6asm_send_mtmx_strtr_window(struct audio_client *ac, matrix.param.data_payload_addr_msw = 0; matrix.param.mem_map_handle = 0; matrix.param.data_payload_size = - sizeof(struct asm_stream_param_data_v2) + + sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_window_v2_t); matrix.param.direction = 0; /* RX */ matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; @@ -9101,7 +8944,7 @@ int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac, matrix.param.data_payload_addr_msw = 0; matrix.param.mem_map_handle = 0; matrix.param.data_payload_size = - sizeof(struct asm_stream_param_data_v2) + + sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_render_mode_t); matrix.param.direction = 0; /* RX */ matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; @@ -9196,7 +9039,7 @@ int q6asm_send_mtmx_strtr_clk_rec_mode(struct audio_client *ac, matrix.param.data_payload_addr_msw = 0; matrix.param.mem_map_handle = 0; matrix.param.data_payload_size = - sizeof(struct asm_stream_param_data_v2) + + sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_clk_rec_t); matrix.param.direction = 0; /* RX */ matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; @@ -9281,7 +9124,7 @@ int q6asm_send_mtmx_strtr_enable_adjust_session_clock(struct audio_client *ac, matrix.param.data_payload_addr_msw = 0; matrix.param.mem_map_handle = 0; matrix.param.data_payload_size = - sizeof(struct asm_stream_param_data_v2) + + sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_param_adjust_session_time_ctl_t); matrix.param.direction = 0; /* RX */ matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; @@ -10010,20 +9853,14 @@ static int q6asm_get_asm_app_type_cal(void) int q6asm_send_cal(struct audio_client *ac) { struct cal_block_data *cal_block = NULL; - struct apr_hdr hdr; - char *asm_params = NULL; - struct asm_stream_cmd_set_pp_params_v2 payload_params; - int sz, rc = -EINVAL; - + struct mem_mapping_hdr mem_hdr; + u32 payload_size = 0; + int rc = -EINVAL; pr_debug("%s:\n", __func__); if (!ac) { - pr_err("%s: APR handle NULL\n", __func__); - goto done; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - goto done; + pr_err("%s: Audio client is NULL\n", __func__); + return -EINVAL; } if (ac->io_mode & NT_MODE) { pr_debug("%s: called for NT MODE, exiting\n", __func__); @@ -10038,6 +9875,7 @@ int q6asm_send_cal(struct audio_client *ac) goto done; } + memset(&mem_hdr, 0, sizeof(mem_hdr)); mutex_lock(&cal_data[ASM_AUDSTRM_CAL]->lock); cal_block = cal_utils_get_only_cal_block(cal_data[ASM_AUDSTRM_CAL]); if (cal_block == NULL) { @@ -10060,62 +9898,26 @@ int q6asm_send_cal(struct audio_client *ac) goto unlock; } - sz = sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2); - asm_params = kzalloc(sz, GFP_KERNEL); - if (!asm_params) { - pr_err("%s, asm params memory alloc failed", __func__); - rc = -ENOMEM; - goto unlock; - } - - /* asm_stream_cmd_set_pp_params_v2 has no APR header in it */ - q6asm_add_hdr_async(ac, &hdr, (sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2)), TRUE); - - atomic_set(&ac->cmd_state_pp, -1); - hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - payload_params.data_payload_addr_lsw = - lower_32_bits(cal_block->cal_data.paddr); - payload_params.data_payload_addr_msw = - msm_audio_populate_upper_32_bits( - cal_block->cal_data.paddr); - payload_params.mem_map_handle = cal_block->map_data.q6map_handle; - payload_params.data_payload_size = cal_block->cal_data.size; - memcpy(((u8 *)asm_params), &hdr, sizeof(struct apr_hdr)); - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr)), &payload_params, - sizeof(struct asm_stream_cmd_set_pp_params_v2)); + mem_hdr.data_payload_addr_lsw = + lower_32_bits(cal_block->cal_data.paddr); + mem_hdr.data_payload_addr_msw = + msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr); + mem_hdr.mem_map_handle = cal_block->map_data.q6map_handle; + payload_size = cal_block->cal_data.size; pr_debug("%s: phyaddr lsw = %x msw = %x, maphdl = %x calsize = %d\n", - __func__, payload_params.data_payload_addr_lsw, - payload_params.data_payload_addr_msw, - payload_params.mem_map_handle, - payload_params.data_payload_size); + __func__, mem_hdr.data_payload_addr_lsw, + mem_hdr.data_payload_addr_msw, mem_hdr.mem_map_handle, + payload_size); - rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params); - if (rc < 0) { + rc = q6asm_set_pp_params(ac, &mem_hdr, NULL, payload_size); + if (rc) { pr_err("%s: audio audstrm cal send failed\n", __func__); - rc = -EINVAL; - goto free; - } - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5 * HZ); - if (!rc) { - pr_err("%s: timeout, audio audstrm cal send\n", __func__); - rc = -ETIMEDOUT; - goto free; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%d] audio audstrm cal send\n", - __func__, atomic_read(&ac->cmd_state_pp)); - rc = -EINVAL; - goto free; + goto unlock; } rc = 0; -free: - kfree(asm_params); unlock: mutex_unlock(&cal_data[ASM_AUDSTRM_CAL]->lock); done: diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 8438c37bea70..ae096e62606e 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -730,15 +730,6 @@ struct adm_cmd_set_pp_params_v5 { */ } __packed; -struct audproc_mfc_output_media_fmt { - struct adm_cmd_set_pp_params_v5 params; - struct param_hdr_v1 data; - uint32_t sampling_rate; - uint16_t bits_per_sample; - uint16_t num_channels; - uint16_t channel_type[8]; -} __packed; - struct audproc_mfc_param_media_fmt { uint32_t sampling_rate; uint16_t bits_per_sample; @@ -6610,55 +6601,27 @@ struct asm_stream_cmd_open_transcode_loopback_t { #define ASM_STREAM_CMD_SET_PP_PARAMS_V2 0x00010DA1 #define ASM_STREAM_CMD_SET_PP_PARAMS_V3 0x0001320D -struct asm_stream_cmd_set_pp_params_v2 { - u32 data_payload_addr_lsw; -/* LSW of parameter data payload address. Supported values: any. */ - u32 data_payload_addr_msw; -/* MSW of Parameter data payload address. Supported values: any. - * - Must be set to zero for in-band data. - * - In the case of 32 bit Shared memory address, msw field must be - * - set to zero. - * - In the case of 36 bit shared memory address, bit 31 to bit 4 of - * msw - * - * - must be set to zero. - */ - u32 mem_map_handle; -/* Supported Values: Any. - * memory map handle returned by DSP through - * ASM_CMD_SHARED_MEM_MAP_REGIONS - * command. - * if mmhandle is NULL, the ParamData payloads are within the - * message payload (in-band). - * If mmhandle is non-NULL, the ParamData payloads begin at the - * address specified in the address msw and lsw (out-of-band). - */ - - u32 data_payload_size; -/* Size in bytes of the variable payload accompanying the - * message, or in shared memory. This field is used for parsing the - * parameter payload. +/* + * Structure for the ASM Stream Set PP Params command. Parameter data must be + * pre-packed with the correct header for either V2 or V3 when sent in-band. + * Use q6core_pack_pp_params to pack the header and data correctly depending on + * Instance ID support. */ -} __packed; - - -struct asm_stream_param_data_v2 { - u32 module_id; - /* Unique module ID. */ - - u32 param_id; - /* Unique parameter ID. */ +struct asm_stream_cmd_set_pp_params { + /* APR Header */ + struct apr_hdr apr_hdr; - u16 param_size; -/* Data size of the param_id/module_id combination. This is - * a multiple of 4 bytes. - */ + /* The memory mapping header to be used when sending out of band */ + struct mem_mapping_hdr mem_hdr; - u16 reserved; -/* Reserved for future enhancements. This field must be set to - * zero. - */ + /* The total size of the payload, including the parameter header */ + u32 payload_size; + /* The parameter data to be filled when sent inband. Parameter data + * must be pre-packed with parameter header and then copied here. Use + * q6core_pack_pp_params to pack the header and param data correctly. + */ + u32 param_data[0]; } __packed; #define ASM_STREAM_CMD_GET_PP_PARAMS_V2 0x00010DA2 @@ -8082,9 +8045,6 @@ struct audproc_topology_module_id_info_t { struct asm_volume_ctrl_master_gain { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint16_t master_gain; /* Linear gain in Q13 format. */ @@ -8094,10 +8054,6 @@ struct asm_volume_ctrl_master_gain { struct asm_volume_ctrl_lr_chan_gain { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; - uint16_t l_chan_gain; /*< Linear gain in Q13 format for the left channel. */ @@ -8117,9 +8073,6 @@ struct asm_volume_ctrl_lr_chan_gain { struct asm_volume_ctrl_mute_config { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint32_t mute_flag; /*< Specifies whether mute is disabled (0) or enabled (nonzero).*/ @@ -8147,9 +8100,6 @@ struct asm_volume_ctrl_mute_config { * parameters used by the Volume Control module. */ struct asm_soft_step_volume_params { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint32_t period; /*< Period in milliseconds. * Supported values: 0 to 15000 @@ -8179,9 +8129,6 @@ struct asm_soft_step_volume_params { struct asm_soft_pause_params { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint32_t enable_flag; /*< Specifies whether soft pause is disabled (0) or enabled * (nonzero). @@ -8271,10 +8218,7 @@ struct asm_volume_ctrl_channeltype_gain_pair { struct asm_volume_ctrl_multichannel_gain { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; - uint32_t num_channels; + uint32_t num_channels; /* * Number of channels for which gain values are provided. Any * channels present in the data for which gain is not provided are @@ -8299,9 +8243,6 @@ struct asm_volume_ctrl_multichannel_gain { struct asm_volume_ctrl_channelype_mute_pair { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint8_t channelype; /*< Channel type for which the mute setting is to be applied. * Supported values: @@ -8350,9 +8291,6 @@ struct asm_volume_ctrl_channelype_mute_pair { struct asm_volume_ctrl_multichannel_mute { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint32_t num_channels; /*< Number of channels for which mute configuration is * provided. Any channels present in the data for which mute @@ -8797,9 +8735,6 @@ struct asm_eq_per_band_params { } __packed; struct asm_eq_params { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint32_t enable_flag; /*< Specifies whether the equalizer module is disabled (0) or enabled * (nonzero). @@ -9463,16 +9398,6 @@ struct srs_trumedia_params { #define ASM_STREAM_POSTPROC_TOPO_ID_DTS_HPX 0x00010DED #define ASM_STREAM_POSTPROC_TOPO_ID_HPX_PLUS 0x10015000 #define ASM_STREAM_POSTPROC_TOPO_ID_HPX_MASTER 0x10015001 -struct asm_dts_eagle_param { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; -} __packed; - -struct asm_dts_eagle_param_get { - struct apr_hdr hdr; - struct asm_stream_cmd_get_pp_params_v2 param; -} __packed; /* Opcode to set BT address and license for aptx decoder */ #define APTX_DECODER_BT_ADDRESS 0x00013201 @@ -10759,7 +10684,7 @@ union asm_session_mtmx_strtr_param_config { struct asm_mtmx_strtr_params { struct apr_hdr hdr; struct asm_session_cmd_set_mtmx_strstr_params_v2 param; - struct asm_stream_param_data_v2 data; + struct param_hdr_v1 data; union asm_session_mtmx_strtr_param_config config; } __packed; @@ -10869,7 +10794,7 @@ struct asm_mtmx_strtr_get_params { struct asm_mtmx_strtr_get_params_cmdrsp { uint32_t err_code; - struct asm_stream_param_data_v2 param_info; + struct param_hdr_v1 param_info; union asm_session_mtmx_strtr_data_type param_data; } __packed; diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index 27b360f376c5..693397a73bf3 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -264,6 +264,17 @@ int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir int q6asm_audio_client_buf_free_contiguous(unsigned int dir, struct audio_client *ac); +int q6asm_set_pp_params(struct audio_client *ac, + struct mem_mapping_hdr *mem_hdr, u8 *param_data, + u32 param_size); + +int q6asm_pack_and_set_pp_param_in_band(struct audio_client *ac, + struct param_hdr_v3 param_hdr, + u8 *param_data); + +int q6asm_set_soft_volume_module_instance_ids(int instance, + struct param_hdr_v3 *param_hdr); + int q6asm_open_read(struct audio_client *ac, uint32_t format /*, uint16_t bits_per_sample*/); -- GitLab From fa497d2051f93195b1e02376b8ebbd9bae7dca7b Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Mon, 29 Jan 2018 17:21:19 -0800 Subject: [PATCH 0217/1645] ASoC: dsp: Update audio effects driver to support Instance ID Add support to set and get audio effects module params with Instance ID support. Maintain support for non Instance ID set and get param structures as well. Use common pack and set param functions to set and get parameters to DSP instead of handling them at an individual module level. CRs-Fixed: 2151551 Change-Id: I0fdba2560950c931a2ec6f152499fd4bb9f59086 Signed-off-by: Vignesh Kulothungan --- asoc/msm-audio-effects-q6-v2.c | 1278 ++++++++++++++-------------- dsp/q6asm.c | 29 - include/dsp/q6asm-v2.h | 3 - include/uapi/sound/audio_effects.h | 4 + 4 files changed, 625 insertions(+), 689 deletions(-) diff --git a/asoc/msm-audio-effects-q6-v2.c b/asoc/msm-audio-effects-q6-v2.c index 5bab856d2290..8b2ca3168bcf 100644 --- a/asoc/msm-audio-effects-q6-v2.c +++ b/asoc/msm-audio-effects-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -16,6 +16,7 @@ #include #include #include +#include #define MAX_ENABLE_CMD_SIZE 32 @@ -67,44 +68,36 @@ int msm_audio_effects_enable_extn(struct audio_client *ac, struct msm_nt_eff_all_config *effects, bool flag) { - uint32_t updt_params[MAX_ENABLE_CMD_SIZE] = {0}; - uint32_t params_length; + u32 flag_param = flag ? 1 : 0; + struct param_hdr_v3 param_hdr; int rc = 0; pr_debug("%s\n", __func__); - if (!ac) { - pr_err("%s: cannot set audio effects\n", __func__); - return -EINVAL; - } - params_length = 0; - updt_params[0] = AUDPROC_MODULE_ID_VIRTUALIZER; - updt_params[1] = AUDPROC_PARAM_ID_ENABLE; - updt_params[2] = VIRTUALIZER_ENABLE_PARAM_SZ; - updt_params[3] = flag; - params_length += COMMAND_PAYLOAD_SZ + VIRTUALIZER_ENABLE_PARAM_SZ; + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_VIRTUALIZER; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE; + param_hdr.param_size = VIRTUALIZER_ENABLE_PARAM_SZ; if (effects->virtualizer.enable_flag) - q6asm_send_audio_effects_params(ac, (char *)&updt_params[0], - params_length); - memset(updt_params, 0, MAX_ENABLE_CMD_SIZE); - params_length = 0; - updt_params[0] = AUDPROC_MODULE_ID_BASS_BOOST; - updt_params[1] = AUDPROC_PARAM_ID_ENABLE; - updt_params[2] = BASS_BOOST_ENABLE_PARAM_SZ; - updt_params[3] = flag; - params_length += COMMAND_PAYLOAD_SZ + BASS_BOOST_ENABLE_PARAM_SZ; + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr, + (u8 *) &flag_param); + + param_hdr.module_id = AUDPROC_MODULE_ID_BASS_BOOST; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE; + param_hdr.param_size = BASS_BOOST_ENABLE_PARAM_SZ; if (effects->bass_boost.enable_flag) - q6asm_send_audio_effects_params(ac, (char *)&updt_params[0], - params_length); - memset(updt_params, 0, MAX_ENABLE_CMD_SIZE); - params_length = 0; - updt_params[0] = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; - updt_params[1] = AUDPROC_PARAM_ID_ENABLE; - updt_params[2] = EQ_ENABLE_PARAM_SZ; - updt_params[3] = flag; - params_length += COMMAND_PAYLOAD_SZ + EQ_ENABLE_PARAM_SZ; + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr, + (u8 *) &flag_param); + + param_hdr.module_id = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE; + param_hdr.param_size = EQ_ENABLE_PARAM_SZ; if (effects->equalizer.enable_flag) - q6asm_send_audio_effects_params(ac, (char *)&updt_params[0], - params_length); + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr, + (u8 *) &flag_param); + return rc; } @@ -124,24 +117,32 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, { long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; char *params = NULL; + u8 *updt_params; int rc = 0; int devices = GET_NEXT(values, param_max_offset, rc); int num_commands = GET_NEXT(values, param_max_offset, rc); - int *updt_params, i, prev_enable_flag; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + int i, prev_enable_flag; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr; + u8 *param_data = NULL; + u32 packed_data_size = 0; pr_debug("%s\n", __func__); if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); - if (!params) + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); + if (!params) { + pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; - + } pr_debug("%s: device: %d\n", __func__, devices); - updt_params = (int *)params; - params_length = 0; + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + param_hdr.module_id = AUDPROC_MODULE_ID_VIRTUALIZER; + param_hdr.instance_id = INSTANCE_ID_0; for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -163,23 +164,19 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s:VIRT ENABLE prev:%d, new:%d\n", __func__, prev_enable_flag, virtualizer->enable_flag); - if (prev_enable_flag != virtualizer->enable_flag) { - params_length += COMMAND_PAYLOAD_SZ + - VIRTUALIZER_ENABLE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VIRT ENABLE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_VIRTUALIZER; - *updt_params++ = + if (prev_enable_flag == virtualizer->enable_flag) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + VIRTUALIZER_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VIRT ENABLE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_VIRTUALIZER_ENABLE; - *updt_params++ = - VIRTUALIZER_ENABLE_PARAM_SZ; - *updt_params++ = - virtualizer->enable_flag; - } + param_hdr.param_size = VIRTUALIZER_ENABLE_PARAM_SZ; + param_data = (u8 *) &virtualizer->enable_flag; break; case VIRTUALIZER_STRENGTH: if (length != 1 || index_offset != 0) { @@ -191,23 +188,19 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: VIRT STRENGTH val: %d\n", __func__, virtualizer->strength); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - VIRTUALIZER_STRENGTH_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VIRT STRENGTH", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_VIRTUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_VIRTUALIZER_STRENGTH; - *updt_params++ = - VIRTUALIZER_STRENGTH_PARAM_SZ; - *updt_params++ = - virtualizer->strength; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + VIRTUALIZER_STRENGTH_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VIRT STRENGTH", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_VIRTUALIZER_STRENGTH; + param_hdr.param_size = VIRTUALIZER_STRENGTH_PARAM_SZ; + param_data = (u8 *) &virtualizer->strength; break; case VIRTUALIZER_OUT_TYPE: if (length != 1 || index_offset != 0) { @@ -219,23 +212,19 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: VIRT OUT_TYPE val:%d\n", __func__, virtualizer->out_type); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - VIRTUALIZER_OUT_TYPE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VIRT OUT_TYPE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_VIRTUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_VIRTUALIZER_OUT_TYPE; - *updt_params++ = - VIRTUALIZER_OUT_TYPE_PARAM_SZ; - *updt_params++ = - virtualizer->out_type; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + VIRTUALIZER_OUT_TYPE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VIRT OUT_TYPE", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_VIRTUALIZER_OUT_TYPE; + param_hdr.param_size = VIRTUALIZER_OUT_TYPE_PARAM_SZ; + param_data = (u8 *) &virtualizer->out_type; break; case VIRTUALIZER_GAIN_ADJUST: if (length != 1 || index_offset != 0) { @@ -247,32 +236,40 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: VIRT GAIN_ADJUST val:%d\n", __func__, virtualizer->gain_adjust); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - VIRTUALIZER_GAIN_ADJUST_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VIRT GAIN_ADJUST", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_VIRTUALIZER; - *updt_params++ = + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + VIRTUALIZER_GAIN_ADJUST_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VIRT GAIN_ADJUST", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_VIRTUALIZER_GAIN_ADJUST; - *updt_params++ = - VIRTUALIZER_GAIN_ADJUST_PARAM_SZ; - *updt_params++ = - virtualizer->gain_adjust; - } + param_hdr.param_size = VIRTUALIZER_GAIN_ADJUST_PARAM_SZ; + param_data = (u8 *) &virtualizer->gain_adjust; break; default: pr_err("%s: Invalid command to set config\n", __func__); - break; + continue; + } + if (rc) + goto invalid_config; + + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + param_data, &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); else pr_debug("%s: did not send pp params\n", __func__); invalid_config: @@ -297,24 +294,33 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, { long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; char *params = NULL; + u8 *updt_params; int rc = 0; int devices = GET_NEXT(values, param_max_offset, rc); int num_commands = GET_NEXT(values, param_max_offset, rc); - int *updt_params, i, prev_enable_flag; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + int i, prev_enable_flag; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr; + u8 *param_data = NULL; + u32 packed_data_size = 0; pr_debug("%s\n", __func__); if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); - if (!params) + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); + if (!params) { + pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; - + } pr_debug("%s: device: %d\n", __func__, devices); - updt_params = (int *)params; - params_length = 0; + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_REVERB; + param_hdr.instance_id = INSTANCE_ID_0; for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -336,23 +342,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s:REVERB_ENABLE prev:%d,new:%d\n", __func__, prev_enable_flag, reverb->enable_flag); - if (prev_enable_flag != reverb->enable_flag) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_ENABLE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_ENABLE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_ENABLE; - *updt_params++ = - REVERB_ENABLE_PARAM_SZ; - *updt_params++ = - reverb->enable_flag; - } + if (prev_enable_flag == reverb->enable_flag) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_ENABLE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_ENABLE; + param_hdr.param_size = REVERB_ENABLE_PARAM_SZ; + param_data = (u8 *) &reverb->enable_flag; break; case REVERB_MODE: if (length != 1 || index_offset != 0) { @@ -364,23 +365,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_MODE val:%d\n", __func__, reverb->mode); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_MODE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_MODE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_MODE; - *updt_params++ = - REVERB_MODE_PARAM_SZ; - *updt_params++ = - reverb->mode; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_MODE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_MODE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_MODE; + param_hdr.param_size = REVERB_MODE_PARAM_SZ; + param_data = (u8 *) &reverb->mode; break; case REVERB_PRESET: if (length != 1 || index_offset != 0) { @@ -392,23 +388,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_PRESET val:%d\n", __func__, reverb->preset); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_PRESET_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_PRESET", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_PRESET; - *updt_params++ = - REVERB_PRESET_PARAM_SZ; - *updt_params++ = - reverb->preset; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_PRESET_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_PRESET", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_PRESET; + param_hdr.param_size = REVERB_PRESET_PARAM_SZ; + param_data = (u8 *) &reverb->preset; break; case REVERB_WET_MIX: if (length != 1 || index_offset != 0) { @@ -420,23 +411,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_WET_MIX val:%d\n", __func__, reverb->wet_mix); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_WET_MIX_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_WET_MIX", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_WET_MIX; - *updt_params++ = - REVERB_WET_MIX_PARAM_SZ; - *updt_params++ = - reverb->wet_mix; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_WET_MIX_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_WET_MIX", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_WET_MIX; + param_hdr.param_size = REVERB_WET_MIX_PARAM_SZ; + param_data = (u8 *) &reverb->wet_mix; break; case REVERB_GAIN_ADJUST: if (length != 1 || index_offset != 0) { @@ -448,23 +434,19 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_GAIN_ADJUST val:%d\n", __func__, reverb->gain_adjust); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_GAIN_ADJUST_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_GAIN_ADJUST", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_GAIN_ADJUST; - *updt_params++ = - REVERB_GAIN_ADJUST_PARAM_SZ; - *updt_params++ = - reverb->gain_adjust; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_GAIN_ADJUST_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_GAIN_ADJUST", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_REVERB_GAIN_ADJUST; + param_hdr.param_size = REVERB_GAIN_ADJUST_PARAM_SZ; + param_data = (u8 *) &reverb->gain_adjust; break; case REVERB_ROOM_LEVEL: if (length != 1 || index_offset != 0) { @@ -476,23 +458,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_ROOM_LEVEL val:%d\n", __func__, reverb->room_level); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_ROOM_LEVEL_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_ROOM_LEVEL", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_ROOM_LEVEL; - *updt_params++ = - REVERB_ROOM_LEVEL_PARAM_SZ; - *updt_params++ = - reverb->room_level; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_ROOM_LEVEL_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_ROOM_LEVEL", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_ROOM_LEVEL; + param_hdr.param_size = REVERB_ROOM_LEVEL_PARAM_SZ; + param_data = (u8 *) &reverb->room_level; break; case REVERB_ROOM_HF_LEVEL: if (length != 1 || index_offset != 0) { @@ -504,23 +481,19 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_ROOM_HF_LEVEL val%d\n", __func__, reverb->room_hf_level); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_ROOM_HF_LEVEL_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_ROOM_HF_LEVEL", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_ROOM_HF_LEVEL; - *updt_params++ = - REVERB_ROOM_HF_LEVEL_PARAM_SZ; - *updt_params++ = - reverb->room_hf_level; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_ROOM_HF_LEVEL_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_ROOM_HF_LEVEL", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_REVERB_ROOM_HF_LEVEL; + param_hdr.param_size = REVERB_ROOM_HF_LEVEL_PARAM_SZ; + param_data = (u8 *) &reverb->room_hf_level; break; case REVERB_DECAY_TIME: if (length != 1 || index_offset != 0) { @@ -532,23 +505,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_DECAY_TIME val:%d\n", __func__, reverb->decay_time); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_DECAY_TIME_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_DECAY_TIME", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_DECAY_TIME; - *updt_params++ = - REVERB_DECAY_TIME_PARAM_SZ; - *updt_params++ = - reverb->decay_time; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_DECAY_TIME_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_DECAY_TIME", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DECAY_TIME; + param_hdr.param_size = REVERB_DECAY_TIME_PARAM_SZ; + param_data = (u8 *) &reverb->decay_time; break; case REVERB_DECAY_HF_RATIO: if (length != 1 || index_offset != 0) { @@ -560,23 +528,19 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_DECAY_HF_RATIO val%d\n", __func__, reverb->decay_hf_ratio); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_DECAY_HF_RATIO_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_DECAY_HF_RATIO", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_DECAY_HF_RATIO; - *updt_params++ = - REVERB_DECAY_HF_RATIO_PARAM_SZ; - *updt_params++ = - reverb->decay_hf_ratio; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_DECAY_HF_RATIO_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_DECAY_HF_RATIO", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_REVERB_DECAY_HF_RATIO; + param_hdr.param_size = REVERB_DECAY_HF_RATIO_PARAM_SZ; + param_data = (u8 *) &reverb->decay_hf_ratio; break; case REVERB_REFLECTIONS_LEVEL: if (length != 1 || index_offset != 0) { @@ -588,23 +552,20 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_REFLECTIONS_LEVEL val:%d\n", __func__, reverb->reflections_level); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_REFLECTIONS_LEVEL_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_REFLECTIONS_LEVEL", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_REFLECTIONS_LEVEL_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_REFLECTIONS_LEVEL", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_REFLECTIONS_LEVEL; - *updt_params++ = + param_hdr.param_size = REVERB_REFLECTIONS_LEVEL_PARAM_SZ; - *updt_params++ = - reverb->reflections_level; - } + param_data = (u8 *) &reverb->reflections_level; break; case REVERB_REFLECTIONS_DELAY: if (length != 1 || index_offset != 0) { @@ -616,23 +577,20 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_REFLECTIONS_DELAY val:%d\n", __func__, reverb->reflections_delay); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_REFLECTIONS_DELAY_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_REFLECTIONS_DELAY", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_REFLECTIONS_DELAY_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_REFLECTIONS_DELAY", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_REFLECTIONS_DELAY; - *updt_params++ = + param_hdr.param_size = REVERB_REFLECTIONS_DELAY_PARAM_SZ; - *updt_params++ = - reverb->reflections_delay; - } + param_data = (u8 *) &reverb->reflections_delay; break; case REVERB_LEVEL: if (length != 1 || index_offset != 0) { @@ -644,23 +602,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_LEVEL val:%d\n", __func__, reverb->level); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_LEVEL_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_LEVEL", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_LEVEL; - *updt_params++ = - REVERB_LEVEL_PARAM_SZ; - *updt_params++ = - reverb->level; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_LEVEL_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_LEVEL", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_LEVEL; + param_hdr.param_size = REVERB_LEVEL_PARAM_SZ; + param_data = (u8 *) &reverb->level; break; case REVERB_DELAY: if (length != 1 || index_offset != 0) { @@ -672,23 +625,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s:REVERB_DELAY val:%d\n", __func__, reverb->delay); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_DELAY_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_DELAY", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_DELAY; - *updt_params++ = - REVERB_DELAY_PARAM_SZ; - *updt_params++ = - reverb->delay; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_DELAY_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_DELAY", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DELAY; + param_hdr.param_size = REVERB_DELAY_PARAM_SZ; + param_data = (u8 *) &reverb->delay; break; case REVERB_DIFFUSION: if (length != 1 || index_offset != 0) { @@ -700,23 +648,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_DIFFUSION val:%d\n", __func__, reverb->diffusion); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_DIFFUSION_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_DIFFUSION", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_DIFFUSION; - *updt_params++ = - REVERB_DIFFUSION_PARAM_SZ; - *updt_params++ = - reverb->diffusion; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_DIFFUSION_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_DIFFUSION", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DIFFUSION; + param_hdr.param_size = REVERB_DIFFUSION_PARAM_SZ; + param_data = (u8 *) &reverb->diffusion; break; case REVERB_DENSITY: if (length != 1 || index_offset != 0) { @@ -728,32 +671,39 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_DENSITY val:%d\n", __func__, reverb->density); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_DENSITY_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_DENSITY", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_DENSITY; - *updt_params++ = - REVERB_DENSITY_PARAM_SZ; - *updt_params++ = - reverb->density; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_DENSITY_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_DENSITY", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DENSITY; + param_hdr.param_size = REVERB_DENSITY_PARAM_SZ; + param_data = (u8 *) &reverb->density; break; default: pr_err("%s: Invalid command to set config\n", __func__); - break; + continue; + } + if (rc) + goto invalid_config; + + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + param_data, &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); else pr_debug("%s: did not send pp params\n", __func__); invalid_config: @@ -778,24 +728,33 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, { long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; char *params = NULL; + u8 *updt_params; int rc = 0; int devices = GET_NEXT(values, param_max_offset, rc); int num_commands = GET_NEXT(values, param_max_offset, rc); - int *updt_params, i, prev_enable_flag; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + int i, prev_enable_flag; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr; + u8 *param_data = NULL; + u32 packed_data_size = 0; pr_debug("%s\n", __func__); if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); - if (!params) + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); + if (!params) { + pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; - + } pr_debug("%s: device: %d\n", __func__, devices); - updt_params = (int *)params; - params_length = 0; + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_BASS_BOOST; + param_hdr.instance_id = INSTANCE_ID_0; for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -818,23 +777,18 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, pr_debug("%s: BASS_BOOST_ENABLE prev:%d new:%d\n", __func__, prev_enable_flag, bass_boost->enable_flag); - if (prev_enable_flag != bass_boost->enable_flag) { - params_length += COMMAND_PAYLOAD_SZ + - BASS_BOOST_ENABLE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "BASS_BOOST_ENABLE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_BASS_BOOST; - *updt_params++ = - AUDPROC_PARAM_ID_BASS_BOOST_ENABLE; - *updt_params++ = - BASS_BOOST_ENABLE_PARAM_SZ; - *updt_params++ = - bass_boost->enable_flag; - } + if (prev_enable_flag == bass_boost->enable_flag) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + BASS_BOOST_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "BASS_BOOST_ENABLE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_BASS_BOOST_ENABLE; + param_hdr.param_size = BASS_BOOST_ENABLE_PARAM_SZ; + param_data = (u8 *) &bass_boost->enable_flag; break; case BASS_BOOST_MODE: if (length != 1 || index_offset != 0) { @@ -846,23 +800,18 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: BASS_BOOST_MODE val:%d\n", __func__, bass_boost->mode); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - BASS_BOOST_MODE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "BASS_BOOST_MODE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_BASS_BOOST; - *updt_params++ = - AUDPROC_PARAM_ID_BASS_BOOST_MODE; - *updt_params++ = - BASS_BOOST_MODE_PARAM_SZ; - *updt_params++ = - bass_boost->mode; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + BASS_BOOST_MODE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "BASS_BOOST_MODE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_BASS_BOOST_MODE; + param_hdr.param_size = BASS_BOOST_MODE_PARAM_SZ; + param_data = (u8 *) &bass_boost->mode; break; case BASS_BOOST_STRENGTH: if (length != 1 || index_offset != 0) { @@ -874,32 +823,40 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: BASS_BOOST_STRENGTH val:%d\n", __func__, bass_boost->strength); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - BASS_BOOST_STRENGTH_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "BASS_BOOST_STRENGTH", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_BASS_BOOST; - *updt_params++ = - AUDPROC_PARAM_ID_BASS_BOOST_STRENGTH; - *updt_params++ = - BASS_BOOST_STRENGTH_PARAM_SZ; - *updt_params++ = - bass_boost->strength; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + BASS_BOOST_STRENGTH_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "BASS_BOOST_STRENGTH", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_BASS_BOOST_STRENGTH; + param_hdr.param_size = BASS_BOOST_STRENGTH_PARAM_SZ; + param_data = (u8 *) &bass_boost->strength; break; default: pr_err("%s: Invalid command to set config\n", __func__); - break; + continue; + } + if (rc) + goto invalid_config; + + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + param_data, &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); else pr_debug("%s: did not send pp params\n", __func__); invalid_config: @@ -924,24 +881,33 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, { long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; char *params = NULL; + u8 *updt_params; int rc = 0; int devices = GET_NEXT(values, param_max_offset, rc); int num_commands = GET_NEXT(values, param_max_offset, rc); - int *updt_params, i, j, prev_enable_flag; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + int i, prev_enable_flag; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr; + u8 *param_data = NULL; + u32 packed_data_size = 0; pr_debug("%s\n", __func__); if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); - if (!params) + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); + if (!params) { + pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; - + } pr_debug("%s: device: %d\n", __func__, devices); - updt_params = (int *)params; - params_length = 0; + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_PBE; + param_hdr.instance_id = INSTANCE_ID_0; for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -962,23 +928,18 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, prev_enable_flag = pbe->enable_flag; pbe->enable_flag = GET_NEXT(values, param_max_offset, rc); - if (prev_enable_flag != pbe->enable_flag) { - params_length += COMMAND_PAYLOAD_SZ + - PBE_ENABLE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "PBE_ENABLE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_PBE; - *updt_params++ = - AUDPROC_PARAM_ID_PBE_ENABLE; - *updt_params++ = - PBE_ENABLE_PARAM_SZ; - *updt_params++ = - pbe->enable_flag; - } + if (prev_enable_flag == pbe->enable_flag) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + PBE_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "PBE_ENABLE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_PBE_ENABLE; + param_hdr.param_size = PBE_ENABLE_PARAM_SZ; + param_data = (u8 *) &pbe->enable_flag; break; case PBE_CONFIG: pr_debug("%s: PBE_PARAM length %u\n", __func__, length); @@ -989,37 +950,38 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, rc = -EINVAL; goto invalid_config; } - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + length; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "PBE_PARAM", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_PBE; - *updt_params++ = - AUDPROC_PARAM_ID_PBE_PARAM_CONFIG; - *updt_params++ = - length; - for (j = 0; j < length; ) { - j += sizeof(*updt_params); - *updt_params++ = - GET_NEXT( - values, - param_max_offset, - rc); - } - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = + params_length + COMMAND_IID_PAYLOAD_SZ + length; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "PBE_PARAM", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_PBE_PARAM_CONFIG; + param_hdr.param_size = length; + param_data = (u8 *) values; break; default: pr_err("%s: Invalid command to set config\n", __func__); - break; + continue; + } + if (rc) + goto invalid_config; + + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + param_data, &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); invalid_config: kfree(params); return rc; @@ -1042,24 +1004,36 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, { long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; char *params = NULL; + u8 *updt_params = NULL; int rc = 0; int devices = GET_NEXT(values, param_max_offset, rc); int num_commands = GET_NEXT(values, param_max_offset, rc); - int *updt_params, i, prev_enable_flag; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + int i, prev_enable_flag; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr; + u8 *param_data = NULL; + u32 packed_data_size = 0; + u8 *eq_config_data = NULL; + u32 *updt_config_data = NULL; + int config_param_length; pr_debug("%s\n", __func__); if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); - if (!params) + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); + if (!params) { + pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; - + } pr_debug("%s: device: %d\n", __func__, devices); - updt_params = (int *)params; - params_length = 0; + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; + param_hdr.instance_id = INSTANCE_ID_0; for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -1084,23 +1058,18 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: EQ_ENABLE prev:%d new:%d\n", __func__, prev_enable_flag, eq->enable_flag); - if (prev_enable_flag != eq->enable_flag) { - params_length += COMMAND_PAYLOAD_SZ + - EQ_ENABLE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "EQ_ENABLE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_POPLESS_EQUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_EQ_ENABLE; - *updt_params++ = - EQ_ENABLE_PARAM_SZ; - *updt_params++ = - eq->enable_flag; - } + if (prev_enable_flag == eq->enable_flag) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + EQ_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "EQ_ENABLE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_EQ_ENABLE; + param_hdr.param_size = EQ_ENABLE_PARAM_SZ; + param_data = (u8 *) &eq->enable_flag; break; case EQ_CONFIG: if (length < EQ_CONFIG_PARAM_LEN || index_offset != 0) { @@ -1149,43 +1118,50 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, eq->per_band_cfg[idx].quality_factor = GET_NEXT(values, param_max_offset, rc); } - if (command_config_state == CONFIG_SET) { - int config_param_length = EQ_CONFIG_PARAM_SZ + - (EQ_CONFIG_PER_BAND_PARAM_SZ* - eq->config.num_bands); - params_length += COMMAND_PAYLOAD_SZ + - config_param_length; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "EQ_CONFIG", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_POPLESS_EQUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_EQ_CONFIG; - *updt_params++ = - config_param_length; - *updt_params++ = - eq->config.eq_pregain; - *updt_params++ = - eq->config.preset_id; - *updt_params++ = - eq->config.num_bands; - for (idx = 0; idx < MAX_EQ_BANDS; idx++) { - if (eq->per_band_cfg[idx].band_idx < 0) - continue; - *updt_params++ = + if (command_config_state != CONFIG_SET) + break; + config_param_length = EQ_CONFIG_PARAM_SZ + + (EQ_CONFIG_PER_BAND_PARAM_SZ * + eq->config.num_bands); + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + config_param_length; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "EQ_CONFIG", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_EQ_CONFIG; + param_hdr.param_size = config_param_length; + + if (!eq_config_data) + eq_config_data = kzalloc(config_param_length, + GFP_KERNEL); + else + memset(eq_config_data, 0, config_param_length); + if (!eq_config_data) { + pr_err("%s, EQ_CONFIG:memory alloc failed\n", + __func__); + rc = -ENOMEM; + goto invalid_config; + } + param_data = eq_config_data; + updt_config_data = (u32 *) eq_config_data; + *updt_config_data++ = eq->config.eq_pregain; + *updt_config_data++ = eq->config.preset_id; + *updt_config_data++ = eq->config.num_bands; + for (idx = 0; idx < MAX_EQ_BANDS; idx++) { + if (eq->per_band_cfg[idx].band_idx < 0) + continue; + *updt_config_data++ = eq->per_band_cfg[idx].filter_type; - *updt_params++ = + *updt_config_data++ = eq->per_band_cfg[idx].freq_millihertz; - *updt_params++ = + *updt_config_data++ = eq->per_band_cfg[idx].gain_millibels; - *updt_params++ = + *updt_config_data++ = eq->per_band_cfg[idx].quality_factor; - *updt_params++ = + *updt_config_data++ = eq->per_band_cfg[idx].band_idx; - } } break; case EQ_BAND_INDEX: @@ -1203,23 +1179,18 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, eq->band_index = idx; pr_debug("%s: EQ_BAND_INDEX val:%d\n", __func__, eq->band_index); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - EQ_BAND_INDEX_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "EQ_BAND_INDEX", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_POPLESS_EQUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_EQ_BAND_INDEX; - *updt_params++ = - EQ_BAND_INDEX_PARAM_SZ; - *updt_params++ = - eq->band_index; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + EQ_BAND_INDEX_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "EQ_BAND_INDEX", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_EQ_BAND_INDEX; + param_hdr.param_size = EQ_BAND_INDEX_PARAM_SZ; + param_data = (u8 *) &eq->band_index; break; case EQ_SINGLE_BAND_FREQ: if (length != 1 || index_offset != 0) { @@ -1235,36 +1206,45 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: EQ_SINGLE_BAND_FREQ idx:%d, val:%d\n", __func__, eq->band_index, eq->freq_millihertz); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - EQ_SINGLE_BAND_FREQ_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "EQ_SINGLE_BAND_FREQ", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_POPLESS_EQUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_EQ_SINGLE_BAND_FREQ; - *updt_params++ = - EQ_SINGLE_BAND_FREQ_PARAM_SZ; - *updt_params++ = - eq->freq_millihertz; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + EQ_SINGLE_BAND_FREQ_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "EQ_SINGLE_BAND_FREQ", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_EQ_SINGLE_BAND_FREQ; + param_hdr.param_size = EQ_SINGLE_BAND_FREQ_PARAM_SZ; + param_data = (u8 *) &eq->freq_millihertz; break; default: pr_err("%s: Invalid command to set config\n", __func__); - break; + continue; } + if (rc) + goto invalid_config; + + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + param_data, &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; + } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); else pr_debug("%s: did not send pp params\n", __func__); invalid_config: kfree(params); + kfree(eq_config_data); return rc; } EXPORT_SYMBOL(msm_audio_effects_popless_eq_handler); @@ -1277,8 +1257,13 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, int devices; int num_commands; char *params = NULL; - int *updt_params, i; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + u8 *updt_params; + int i; + uint32_t vol_gain_2ch = 0; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr; + u32 packed_data_size = 0; long *param_max_offset; int rc = 0; @@ -1295,12 +1280,15 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); - if (!params) + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); + if (!params) { + pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; - - updt_params = (int *)params; - params_length = 0; + } + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + memset(¶m_hdr, 0, sizeof(param_hdr)); + q6asm_set_soft_volume_module_instance_ids(instance, ¶m_hdr); for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -1322,43 +1310,15 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, vol->right_gain = GET_NEXT(values, param_max_offset, rc); vol->master_gain = 0x2000; - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - SOFT_VOLUME_GAIN_2CH_PARAM_SZ; - params_length += COMMAND_PAYLOAD_SZ + - SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VOLUME/VOLUME2_GAIN_2CH", - rc); - if (rc != 0) - goto invalid_config; - if (instance == SOFT_VOLUME_INSTANCE_2) - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL2; - else - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL; - *updt_params++ = - ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN; - *updt_params++ = - SOFT_VOLUME_GAIN_2CH_PARAM_SZ; - *updt_params++ = - (vol->left_gain << 16) | - vol->right_gain; - if (instance == SOFT_VOLUME_INSTANCE_2) - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL2; - else - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL; - *updt_params++ = - ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; - *updt_params++ = - SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; - *updt_params++ = - vol->master_gain; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + SOFT_VOLUME_GAIN_2CH_PARAM_SZ + + COMMAND_IID_PAYLOAD_SZ + + SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VOLUME/VOLUME2_GAIN_2CH", rc); break; case SOFT_VOLUME_GAIN_MASTER: case SOFT_VOLUME2_GAIN_MASTER: @@ -1371,53 +1331,57 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, vol->right_gain = 0x2000; vol->master_gain = GET_NEXT(values, param_max_offset, rc); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - SOFT_VOLUME_GAIN_2CH_PARAM_SZ; - params_length += COMMAND_PAYLOAD_SZ + - SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VOLUME/VOLUME2_GAIN_MASTER", - rc); - if (rc != 0) - goto invalid_config; - if (instance == SOFT_VOLUME_INSTANCE_2) - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL2; - else - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL; - *updt_params++ = - ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN; - *updt_params++ = - SOFT_VOLUME_GAIN_2CH_PARAM_SZ; - *updt_params++ = - (vol->left_gain << 16) | - vol->right_gain; - if (instance == SOFT_VOLUME_INSTANCE_2) - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL2; - else - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL; - *updt_params++ = - ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; - *updt_params++ = - SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; - *updt_params++ = - vol->master_gain; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + SOFT_VOLUME_GAIN_2CH_PARAM_SZ + + COMMAND_IID_PAYLOAD_SZ + + SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VOLUME/VOLUME2_GAIN_MASTER", rc); break; default: pr_err("%s: Invalid command id: %d to set config\n", __func__, command_id); - break; + continue; + } + if (rc) + continue; + + /* Set Volume Control for Left/Right */ + param_hdr.param_id = ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN; + param_hdr.param_size = SOFT_VOLUME_GAIN_2CH_PARAM_SZ; + vol_gain_2ch = (vol->left_gain << 16) | vol->right_gain; + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + (u8 *) &vol_gain_2ch, + &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; } + + updt_params += packed_data_size; + params_length += packed_data_size; + + /* Set Master Volume Control */ + param_hdr.param_id = ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; + param_hdr.param_size = SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + (u8 *) &vol->master_gain, + &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; + } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); invalid_config: kfree(params); return rc; diff --git a/dsp/q6asm.c b/dsp/q6asm.c index fe1b39acb8fd..208c7e267827 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -8778,35 +8778,6 @@ int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp) } EXPORT_SYMBOL(q6asm_get_session_time_legacy); -/** - * q6asm_send_audio_effects_params - - * command to send audio effects params - * - * @ac: Audio client handle - * @params: audio effects params - * @params_length: size of params - * - * Returns 0 on success or error on failure - */ -int q6asm_send_audio_effects_params(struct audio_client *ac, char *params, - uint32_t params_length) -{ - int rc; - - pr_debug("%s:\n", __func__); - - /* - * Leave function as wrapper for use by effects. Params must be properly - * packed. Use q6common_pack_pp_param to pack params correctly. - */ - rc = q6asm_set_pp_params(ac, NULL, params, params_length); - if (rc) - pr_err("%s: audio effects set-params send failed\n", __func__); - - return rc; -} -EXPORT_SYMBOL(q6asm_send_audio_effects_params); - /** * q6asm_send_mtmx_strtr_window - * command to send matrix for window params diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index 693397a73bf3..c92cacf6c892 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -635,9 +635,6 @@ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp); int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp); -int q6asm_send_audio_effects_params(struct audio_client *ac, char *params, - uint32_t params_length); - int q6asm_send_stream_cmd(struct audio_client *ac, struct msm_adsp_event_data *data); diff --git a/include/uapi/sound/audio_effects.h b/include/uapi/sound/audio_effects.h index 7964c34f890d..f38b2121a56e 100644 --- a/include/uapi/sound/audio_effects.h +++ b/include/uapi/sound/audio_effects.h @@ -145,8 +145,12 @@ #define PBE_ENABLE_PARAM_LEN 1 #define PBE_CONFIG_PARAM_LEN 28 +/* Command Payload length and size for Non-IID commands */ #define COMMAND_PAYLOAD_LEN 3 #define COMMAND_PAYLOAD_SZ (COMMAND_PAYLOAD_LEN * sizeof(uint32_t)) +/* Command Payload length and size for IID commands */ +#define COMMAND_IID_PAYLOAD_LEN 4 +#define COMMAND_IID_PAYLOAD_SZ (COMMAND_IID_PAYLOAD_LEN * sizeof(uint32_t)) #define MAX_INBAND_PARAM_SZ 4096 #define Q27_UNITY (1 << 27) #define Q8_UNITY (1 << 8) -- GitLab From 15a617e25425a63a8812ccc473cfba5e443f12a7 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Mon, 26 Feb 2018 06:43:50 +0530 Subject: [PATCH 0218/1645] ASoC: msmnile: Add support for WCD934x codec on msmnile target Add frontend and backend dailinks for playback and capture paths of WCD934x codec and runtime detection support of WCD934x codec and WCD9360 codec on msmnile target. Change-Id: Iff189a89c6515a6196714a00d21a0fb4de939e3f Signed-off-by: Sudheer Papothi --- asoc/sdm855.c | 634 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 606 insertions(+), 28 deletions(-) diff --git a/asoc/sdm855.c b/asoc/sdm855.c index 5944a89c9bb7..2690ed5cd51d 100644 --- a/asoc/sdm855.c +++ b/asoc/sdm855.c @@ -33,6 +33,8 @@ #include "device_event.h" #include "msm-pcm-routing-v2.h" #include "codecs/msm-cdc-pinctrl.h" +#include "codecs/wcd934x/wcd934x.h" +#include "codecs/wcd934x/wcd934x-mbhc.h" #include "codecs/wcd9360/wcd9360.h" #include "codecs/wsa881x.h" #include "codecs/wcd-mbhc-v2.h" @@ -68,6 +70,7 @@ #define ADSP_STATE_READY_TIMEOUT_MS 3000 #define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ +#define MSM_HIFI_ON 1 enum { SLIM_RX_0 = 0, @@ -160,6 +163,8 @@ struct msm_asoc_mach_data { struct snd_info_entry *codec_root; struct msm_pinctrl_info pinctrl_info; struct device_node *us_euro_gpio_p; /* used by pinctrl API */ + struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ + struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ }; struct msm_asoc_wcd93xx_codec { @@ -499,15 +504,18 @@ static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(hifi_function, hifi_text); static struct platform_device *spdev; +static int msm_hifi_control; static bool is_initial_boot; static bool codec_reg_done; static struct snd_soc_aux_dev *msm_aux_dev; static struct snd_soc_codec_conf *msm_codec_conf; static struct msm_asoc_wcd93xx_codec msm_codec_fn; +static void *def_wcd_mbhc_cal(void); static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable, bool dapm); static int msm_wsa881x_init(struct snd_soc_component *component); @@ -544,6 +552,13 @@ static struct snd_soc_dapm_route wcd_audio_paths[] = { {"MIC BIAS4", NULL, "MCLK TX"}, }; +static struct snd_soc_dapm_route wcd_audio_paths_tavil[] = { + {"MIC BIAS1", NULL, "MCLK TX"}, + {"MIC BIAS2", NULL, "MCLK TX"}, + {"MIC BIAS3", NULL, "MCLK TX"}, + {"MIC BIAS4", NULL, "MCLK TX"}, +}; + static struct afe_clk_set mi2s_clk[MI2S_MAX] = { { AFE_API_VERSION_I2S_CONFIG, @@ -2619,6 +2634,57 @@ static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol, return 0; } + +static int msm_hifi_ctrl(struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + + dev_dbg(codec->dev, "%s: msm_hifi_control = %d\n", __func__, + msm_hifi_control); + + if (!pdata || !pdata->hph_en1_gpio_p) { + dev_err(codec->dev, "%s: hph_en1_gpio is invalid\n", __func__); + return -EINVAL; + } + if (msm_hifi_control == MSM_HIFI_ON) { + msm_cdc_pinctrl_select_active_state(pdata->hph_en1_gpio_p); + /* 5msec delay needed as per HW requirement */ + usleep_range(5000, 5010); + } else { + msm_cdc_pinctrl_select_sleep_state(pdata->hph_en1_gpio_p); + } + snd_soc_dapm_sync(dapm); + + return 0; +} + +static int msm_hifi_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_hifi_control = %d\n", + __func__, msm_hifi_control); + ucontrol->value.integer.value[0] = msm_hifi_control; + + return 0; +} + +static int msm_hifi_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + msm_hifi_control = ucontrol->value.integer.value[0]; + msm_hifi_ctrl(codec); + + return 0; +} + static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, slim_rx_ch_get, slim_rx_ch_put), @@ -2888,6 +2954,8 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), SOC_ENUM_EXT("QUIN_AUX_PCM_TX Format", aux_pcm_tx_format, msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get, + msm_hifi_put), }; @@ -2898,6 +2966,8 @@ static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, if (!strcmp(dev_name(codec->dev), "pahu_codec")) { ret = pahu_cdc_mclk_enable(codec, enable); + } else if (!strcmp(dev_name(codec->dev), "tavil_codec")) { + ret = tavil_cdc_mclk_enable(codec, enable); } else { dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", __func__); @@ -2913,6 +2983,8 @@ static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, if (!strcmp(dev_name(codec->dev), "pahu_codec")) { ret = pahu_cdc_mclk_tx_enable(codec, enable); + } else if (!strcmp(dev_name(codec->dev), "tavil_codec")) { + ret = tavil_cdc_mclk_tx_enable(codec, enable); } else { dev_err(codec->dev, "%s: unknown codec to enable TX ext clk\n", __func__); @@ -2954,6 +3026,40 @@ static int msm_mclk_event(struct snd_soc_dapm_widget *w, return 0; } +static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + + dev_dbg(codec->dev, "%s: msm_hifi_control = %d\n", + __func__, msm_hifi_control); + + if (!pdata || !pdata->hph_en0_gpio_p) { + dev_err(codec->dev, "%s: hph_en0_gpio is invalid\n", __func__); + return -EINVAL; + } + + if (msm_hifi_control != MSM_HIFI_ON) { + dev_dbg(codec->dev, "%s: HiFi mixer control is not set\n", + __func__); + return 0; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + msm_cdc_pinctrl_select_active_state(pdata->hph_en0_gpio_p); + break; + case SND_SOC_DAPM_PRE_PMD: + msm_cdc_pinctrl_select_sleep_state(pdata->hph_en0_gpio_p); + break; + } + + return 0; +} + static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, @@ -2976,6 +3082,33 @@ static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { SND_SOC_DAPM_MIC("Digital Mic7", NULL), }; +static const struct snd_soc_dapm_widget msm_dapm_widgets_tavil[] = { + + SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, + msm_mclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0, + msm_mclk_tx_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SPK("Lineout_1 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), + SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event), + SND_SOC_DAPM_MIC("Handset Mic", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), + SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL), + SND_SOC_DAPM_MIC("Analog Mic5", NULL), + + SND_SOC_DAPM_MIC("Digital Mic0", NULL), + SND_SOC_DAPM_MIC("Digital Mic1", NULL), + SND_SOC_DAPM_MIC("Digital Mic2", NULL), + SND_SOC_DAPM_MIC("Digital Mic3", NULL), + SND_SOC_DAPM_MIC("Digital Mic4", NULL), + SND_SOC_DAPM_MIC("Digital Mic5", NULL), +}; + static inline int param_is_mask(int p) { return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && @@ -3697,11 +3830,17 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) return ret; } - snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { + snd_soc_dapm_new_controls(dapm, msm_dapm_widgets_tavil, + ARRAY_SIZE(msm_dapm_widgets_tavil)); + snd_soc_dapm_add_routes(dapm, wcd_audio_paths_tavil, + ARRAY_SIZE(wcd_audio_paths_tavil)); + } else { + snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, ARRAY_SIZE(msm_dapm_widgets)); - - snd_soc_dapm_add_routes(dapm, wcd_audio_paths, - ARRAY_SIZE(wcd_audio_paths)); + snd_soc_dapm_add_routes(dapm, wcd_audio_paths, + ARRAY_SIZE(wcd_audio_paths)); + } snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); @@ -3711,8 +3850,6 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic6"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic7"); snd_soc_dapm_ignore_suspend(dapm, "MADINPUT"); snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT"); snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT1"); @@ -3724,12 +3861,31 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { + snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic5"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2"); + snd_soc_dapm_ignore_suspend(dapm, "HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR"); + } else { + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic6"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic7"); + } + snd_soc_dapm_sync(dapm); snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), tx_ch, ARRAY_SIZE(rx_ch), rx_ch); - msm_codec_fn.get_afe_config_fn = pahu_get_afe_config; + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) + msm_codec_fn.get_afe_config_fn = tavil_get_afe_config; + else + msm_codec_fn.get_afe_config_fn = pahu_get_afe_config; ret = msm_adsp_power_up_config(codec, rtd->card->snd_card); if (ret) { @@ -3754,29 +3910,56 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) */ pr_debug("%s: Number of aux devices: %d\n", __func__, rtd->card->num_aux_devs); - if (rtd->card->num_aux_devs && - !list_empty(&rtd->card->component_dev_list)) { - aux_comp = list_first_entry(&rtd->card->component_dev_list, - struct snd_soc_component, card_aux_list); - if (!strcmp(aux_comp->name, WSA8810_NAME_1) || - !strcmp(aux_comp->name, WSA8810_NAME_2)) { - pahu_set_spkr_mode(rtd->codec, WCD9360_SPKR_MODE_1); - pahu_set_spkr_gain_offset(rtd->codec, - WCD9360_RX_GAIN_OFFSET_M1P5_DB); + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->component_dev_list)) { + aux_comp = list_first_entry( + &rtd->card->component_dev_list, + struct snd_soc_component, + card_aux_list); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { + tavil_set_spkr_mode(rtd->codec, + WCD934X_SPKR_MODE_1); + tavil_set_spkr_gain_offset(rtd->codec, + WCD934X_RX_GAIN_OFFSET_M1P5_DB); + } } + card = rtd->card->snd_card; + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + pdata->codec_root = NULL; + goto done; + } + pdata->codec_root = entry; + tavil_codec_info_create_codec_entry(pdata->codec_root, codec); + } else { + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->component_dev_list)) { + aux_comp = list_first_entry(&rtd->card->component_dev_list, + struct snd_soc_component, card_aux_list); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { + pahu_set_spkr_mode(rtd->codec, WCD9360_SPKR_MODE_1); + pahu_set_spkr_gain_offset(rtd->codec, + WCD9360_RX_GAIN_OFFSET_M1P5_DB); + } + } + card = rtd->card->snd_card; + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + pdata->codec_root = NULL; + goto done; + } + pdata->codec_root = entry; + pahu_codec_info_create_codec_entry(pdata->codec_root, codec); } - card = rtd->card->snd_card; - entry = snd_info_create_subdir(card->module, "codecs", - card->proc_root); - if (!entry) { - pr_debug("%s: Cannot create codecs module entry\n", - __func__); - pdata->codec_root = NULL; - goto done; - } - pdata->codec_root = entry; - pahu_codec_info_create_codec_entry(pdata->codec_root, codec); - done: codec_reg_done = true; return 0; @@ -3795,6 +3978,40 @@ static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) tx_ch, ARRAY_SIZE(rx_ch), rx_ch); } +static void *def_wcd_mbhc_cal(void) +{ + void *wcd_mbhc_cal; + struct wcd_mbhc_btn_detect_cfg *btn_cfg; + u16 *btn_high; + + wcd_mbhc_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, + WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); + if (!wcd_mbhc_cal) + return NULL; + +#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(wcd_mbhc_cal)->X) = (Y)) + S(v_hs_max, 1600); +#undef S +#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal)->X) = (Y)) + S(num_btn, WCD_MBHC_DEF_BUTTONS); +#undef S + + btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal); + btn_high = ((void *)&btn_cfg->_v_btn_low) + + (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); + + btn_high[0] = 75; + btn_high[1] = 150; + btn_high[2] = 237; + btn_high[3] = 500; + btn_high[4] = 500; + btn_high[5] = 500; + btn_high[6] = 500; + btn_high[7] = 500; + + return wcd_mbhc_cal; +} + static int msm_snd_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -5199,6 +5416,47 @@ static struct snd_soc_dai_link msm_pahu_fe_dai_links[] = { }, }; +static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_4_TX, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_vifeedback", + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + }, + /* Ultrasound RX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Playback", + .stream_name = "SLIMBUS_2 Hostless Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx2", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_slimbus_2_be_ops, + }, + /* Ultrasound TX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Capture", + .stream_name = "SLIMBUS_2 Hostless Capture", + .cpu_dai_name = "msm-dai-q6-dev.16389", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx2", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_slimbus_2_be_ops, + }, +}; + static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { { .name = MSM_DAILINK_NAME(ASM Loopback), @@ -5655,6 +5913,193 @@ static struct snd_soc_dai_link msm_pahu_be_dai_links[] = { }, }; +static struct snd_soc_dai_link msm_tavil_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_init, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_1_RX, + .stream_name = "Slimbus1 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16386", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_1_TX, + .stream_name = "Slimbus1 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16387", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx3", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_2_RX, + .stream_name = "Slimbus2 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx2", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_2_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_RX, + .stream_name = "Slimbus3 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16390", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_TX, + .stream_name = "Slimbus3 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16391", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_4_RX, + .stream_name = "Slimbus4 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16392", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_5_RX, + .stream_name = "Slimbus5 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16394", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx3", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* MAD BE */ + { + .name = LPASS_BE_SLIMBUS_5_TX, + .stream_name = "Slimbus5 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16395", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_mad1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_6_RX, + .stream_name = "Slimbus6 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16396", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx4", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* Slimbus VI Recording */ + { + .name = LPASS_BE_SLIMBUS_TX_VI, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_vifeedback", + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + .no_pcm = 1, + .dpcm_capture = 1, + }, +}; + static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { { .name = LPASS_BE_SLIMBUS_7_RX, @@ -6027,10 +6472,63 @@ static struct snd_soc_dai_link msm_pahu_snd_card_dai_links[ ARRAY_SIZE(msm_mi2s_be_dai_links) + ARRAY_SIZE(msm_auxpcm_be_dai_links)]; +static struct snd_soc_dai_link msm_tavil_dai_links[ + ARRAY_SIZE(msm_common_dai_links) + + ARRAY_SIZE(msm_tavil_fe_dai_links) + + ARRAY_SIZE(msm_common_misc_fe_dai_links) + + ARRAY_SIZE(msm_common_be_dai_links) + + ARRAY_SIZE(msm_tavil_be_dai_links) + + ARRAY_SIZE(msm_wcn_be_dai_links) + + ARRAY_SIZE(ext_disp_be_dai_link) + + ARRAY_SIZE(msm_mi2s_be_dai_links) + + ARRAY_SIZE(msm_auxpcm_be_dai_links)]; + +static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) +{ + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + void *mbhc_calibration; + + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err_pcm_runtime; + } + + mbhc_calibration = def_wcd_mbhc_cal(); + if (!mbhc_calibration) { + ret = -ENOMEM; + goto err_mbhc_cal; + } + wcd_mbhc_cfg.calibration = mbhc_calibration; + ret = tavil_mbhc_hs_detect(rtd->codec, &wcd_mbhc_cfg); + if (ret) { + dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", + __func__, ret); + goto err_hs_detect; + } + return 0; + +err_hs_detect: + kfree(mbhc_calibration); +err_mbhc_cal: +err_pcm_runtime: + return ret; +} + struct snd_soc_card snd_soc_card_pahu_msm = { .name = "sdm855-pahu-snd-card", }; +struct snd_soc_card snd_soc_card_tavil_msm = { + .name = "sdm855-tavil-snd-card", + .late_probe = msm_snd_card_tavil_late_probe, +}; + static int msm_populate_dai_link_component_of_node( struct snd_soc_card *card) { @@ -6239,6 +6737,8 @@ struct snd_soc_card snd_soc_card_stub_msm = { static const struct of_device_id sdm855_asoc_machine_of_match[] = { { .compatible = "qcom,sdm855-asoc-snd-pahu", .data = "pahu_codec"}, + { .compatible = "qcom,sdm855-asoc-snd-tavil", + .data = "tavil_codec"}, { .compatible = "qcom,sdm855-asoc-snd-stub", .data = "stub_codec"}, {}, @@ -6316,6 +6816,62 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) } dailink = msm_pahu_snd_card_dai_links; + } else if (!strcmp(match->data, "tavil_codec")) { + card = &snd_soc_card_tavil_msm; + len_1 = ARRAY_SIZE(msm_common_dai_links); + len_2 = len_1 + ARRAY_SIZE(msm_tavil_fe_dai_links); + len_3 = len_2 + ARRAY_SIZE(msm_common_misc_fe_dai_links); + len_4 = len_3 + ARRAY_SIZE(msm_common_be_dai_links); + total_links = len_4 + ARRAY_SIZE(msm_tavil_be_dai_links); + memcpy(msm_tavil_dai_links, + msm_common_dai_links, + sizeof(msm_common_dai_links)); + memcpy(msm_tavil_dai_links + len_1, + msm_tavil_fe_dai_links, + sizeof(msm_tavil_fe_dai_links)); + memcpy(msm_tavil_dai_links + len_2, + msm_common_misc_fe_dai_links, + sizeof(msm_common_misc_fe_dai_links)); + memcpy(msm_tavil_dai_links + len_3, + msm_common_be_dai_links, + sizeof(msm_common_be_dai_links)); + memcpy(msm_tavil_dai_links + len_4, + msm_tavil_be_dai_links, + sizeof(msm_tavil_be_dai_links)); + + if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + dev_dbg(dev, "%s(): WCN BTFM support present\n", + __func__); + memcpy(msm_tavil_dai_links + total_links, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + total_links += ARRAY_SIZE(msm_wcn_be_dai_links); + } + + if (of_property_read_bool(dev->of_node, + "qcom,ext-disp-audio-rx")) { + dev_dbg(dev, "%s(): ext disp audio support present\n", + __func__); + memcpy(msm_tavil_dai_links + total_links, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + total_links += ARRAY_SIZE(ext_disp_be_dai_link); + } + if (of_property_read_bool(dev->of_node, + "qcom,mi2s-audio-intf")) { + memcpy(msm_tavil_dai_links + total_links, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,auxpcm-audio-intf")) { + memcpy(msm_tavil_dai_links + total_links, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + dailink = msm_tavil_dai_links; } else if (!strcmp(match->data, "stub_codec")) { card = &snd_soc_card_stub_msm; len_1 = ARRAY_SIZE(msm_stub_fe_dai_links); @@ -6678,6 +7234,28 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Sound card %s registered\n", card->name); spdev = pdev; + ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); + if (ret) { + dev_dbg(&pdev->dev, "%s: failed to add child nodes, ret=%d\n", + __func__, ret); + } else { + pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en1-gpio", 0); + if (!pdata->hph_en1_gpio_p) { + dev_dbg(&pdev->dev, "property %s not detected in node %s\n", + "qcom,hph-en1-gpio", + pdev->dev.of_node->full_name); + } + + pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en0-gpio", 0); + if (!pdata->hph_en0_gpio_p) { + dev_dbg(&pdev->dev, "property %s not detected in node %s\n", + "qcom,hph-en0-gpio", + pdev->dev.of_node->full_name); + } + } + ret = of_property_read_string(pdev->dev.of_node, "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type); if (ret) { -- GitLab From 8bb6f40917277bd83ad15efec74b9381abe1acc6 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 21 Feb 2018 04:48:21 +0530 Subject: [PATCH 0219/1645] ASoC: AQT1000: Fix hardware sequence for AQT1000 Fix hardware sequence for AQT1000 as per hardware requirements to bring codec out of reset for playback and capture usecases on headset. Change-Id: I7419aec36aefc2887583308a60d1ea246d000469 Signed-off-by: Sudheer Papothi --- asoc/codecs/aqt1000/aqt1000-core.c | 54 ++++++++++++++++++++++++++- asoc/codecs/aqt1000/aqt1000-irq.c | 25 ++++--------- asoc/codecs/aqt1000/aqt1000-routing.h | 30 ++++++++------- asoc/codecs/aqt1000/aqt1000.c | 37 ++++++++++++++++-- 4 files changed, 109 insertions(+), 37 deletions(-) diff --git a/asoc/codecs/aqt1000/aqt1000-core.c b/asoc/codecs/aqt1000/aqt1000-core.c index f6fee2063a09..e6313c13eafb 100644 --- a/asoc/codecs/aqt1000/aqt1000-core.c +++ b/asoc/codecs/aqt1000/aqt1000-core.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #include @@ -21,6 +23,9 @@ #include #include #include +#include +#include +#include #include #include "../msm-cdc-pinctrl.h" #include "../msm-cdc-supply.h" @@ -93,8 +98,22 @@ static int aqt1000_bringup(struct aqt1000 *aqt) regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG, 0x01, 0x01); + regmap_update_bits(aqt->regmap, AQT1000_CHIP_CFG0_CLK_CFG_MCLK, + 0x04, 0x00); + + /* Add 100usec delay as per HW requirement */ + usleep_range(100, 110); + regmap_update_bits(aqt->regmap, AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + regmap_update_bits(aqt->regmap, AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); + regmap_update_bits(aqt->regmap, AQT1000_CHIP_CFG0_CLK_CTL_CDC_DIG, + 0x01, 0x01); + /* Codec digital reset */ regmap_update_bits(aqt->regmap, AQT1000_CHIP_CFG0_RST_CTL, 0x01, 0x01); + /* Add 100usec delay as per HW requirement */ + usleep_range(100, 110); return 0; } @@ -378,6 +397,13 @@ static struct aqt1000_pdata *aqt1000_populate_dt_data(struct device *dev) goto err_parse_dt_prop; } + pdata->irq_gpio = of_get_named_gpio(dev->of_node, + "qcom,gpio-connect", 0); + if (!gpio_is_valid(pdata->irq_gpio)) { + dev_err(dev, "%s: TLMM connect gpio not found\n", __func__); + goto err_parse_dt_prop; + } + return pdata; err_parse_dt_prop: @@ -457,6 +483,7 @@ static int aqt1000_i2c_probe(struct i2c_client *client, aqt1000->dev = &client->dev; aqt1000->dev_up = true; aqt1000->mclk_rate = pdata->mclk_rate; + aqt1000->irq = client->irq; aqt1000->num_of_supplies = pdata->num_supplies; ret = msm_cdc_init_supplies(aqt1000->dev, &aqt1000->supplies, @@ -496,6 +523,9 @@ static int aqt1000_i2c_probe(struct i2c_client *client, goto err_supplies; } + pm_runtime_set_active(aqt1000->dev); + pm_runtime_enable(aqt1000->dev); + ret = aqt_register_codec(&client->dev); if (ret) { dev_err(aqt1000->dev, "%s: Codec registration failed\n", @@ -506,6 +536,7 @@ static int aqt1000_i2c_probe(struct i2c_client *client, return ret; err_cdc_register: + pm_runtime_disable(aqt1000->dev); aqt1000_device_exit(aqt1000); err_supplies: msm_cdc_release_supplies(aqt1000->dev, aqt1000->supplies, @@ -527,6 +558,7 @@ static int aqt1000_i2c_remove(struct i2c_client *client) aqt = dev_get_drvdata(&client->dev); + pm_runtime_disable(aqt->dev); msm_cdc_release_supplies(aqt->dev, aqt->supplies, pdata->regulator, pdata->num_supplies); @@ -535,6 +567,22 @@ static int aqt1000_i2c_remove(struct i2c_client *client) return 0; } +#ifdef CONFIG_PM +static int aqt1000_runtime_resume(struct device *dev) +{ + dev_dbg(dev, "%s system resume\n", __func__); + + return 0; +} + +static int aqt1000_runtime_suspend(struct device *dev) +{ + dev_dbg(dev, "%s system suspend\n", __func__); + + return 0; +} +#endif + #ifdef CONFIG_PM_SLEEP static int aqt1000_i2c_resume(struct device *dev) { @@ -556,8 +604,10 @@ static struct i2c_device_id aqt1000_id_table[] = { MODULE_DEVICE_TABLE(i2c, aqt1000_id_table); static const struct dev_pm_ops aqt1000_i2c_pm_ops = { - .suspend = aqt1000_i2c_suspend, - .resume = aqt1000_i2c_resume, + SET_RUNTIME_PM_OPS(aqt1000_runtime_suspend, + aqt1000_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(aqt1000_i2c_suspend, + aqt1000_i2c_resume) }; static const struct of_device_id aqt_match_table[] = { diff --git a/asoc/codecs/aqt1000/aqt1000-irq.c b/asoc/codecs/aqt1000/aqt1000-irq.c index 0c1335306465..321b490befee 100644 --- a/asoc/codecs/aqt1000/aqt1000-irq.c +++ b/asoc/codecs/aqt1000/aqt1000-irq.c @@ -77,7 +77,8 @@ int aqt_request_irq(struct aqt1000 *aqt, int irq, const char *name, if (irq < 0) return irq; - return request_threaded_irq(irq, NULL, handler, IRQF_ONESHOT, + return request_threaded_irq(irq, NULL, handler, + IRQF_ONESHOT | IRQF_TRIGGER_RISING, name, data); } EXPORT_SYMBOL(aqt_request_irq); @@ -160,6 +161,8 @@ static struct irq_chip aqt_irq_chip = { .irq_enable = aqt_irq_enable, }; +static struct lock_class_key aqt_irq_lock_class; + static int aqt_irq_map(struct irq_domain *irqd, unsigned int virq, irq_hw_number_t hw) { @@ -167,6 +170,7 @@ static int aqt_irq_map(struct irq_domain *irqd, unsigned int virq, irq_set_chip_data(virq, data); irq_set_chip_and_handler(virq, &aqt_irq_chip, handle_simple_irq); + irq_set_lockdep_class(virq, &aqt_irq_lock_class); irq_set_nested_thread(virq, 1); irq_set_noprobe(virq); @@ -196,12 +200,6 @@ int aqt_irq_init(struct aqt1000 *aqt) return -EINVAL; } - if (!aqt->irq) { - dev_dbg(aqt->dev, "%s: No interrupt specified\n", __func__); - aqt->irq_base = 0; - return 0; - } - pdata = dev_get_platdata(aqt->dev); if (!pdata) { dev_err(aqt->dev, "%s: Invalid platform data\n", __func__); @@ -214,13 +212,7 @@ int aqt_irq_init(struct aqt1000 *aqt) flags = pdata->irq_flags; if (pdata->irq_gpio) { - if (gpio_to_irq(pdata->irq_gpio) != aqt->irq) { - dev_warn(aqt->dev, "%s: IRQ %d is not GPIO %d (%d)\n", - __func__, aqt->irq, pdata->irq_gpio, - gpio_to_irq(pdata->irq_gpio)); - aqt->irq = gpio_to_irq(pdata->irq_gpio); - } - + aqt->irq = gpio_to_irq(pdata->irq_gpio); ret = devm_gpio_request_one(aqt->dev, pdata->irq_gpio, GPIOF_IN, "AQT IRQ"); if (ret) { @@ -229,10 +221,6 @@ int aqt_irq_init(struct aqt1000 *aqt) pdata->irq_gpio = 0; return ret; } - } else { - dev_dbg(aqt->dev, "%s: irq_gpio is %d\n", - __func__, pdata->irq_gpio); - return 0; } irq_data = irq_get_irq_data(aqt->irq); @@ -242,6 +230,7 @@ int aqt_irq_init(struct aqt1000 *aqt) return -EINVAL; } + aqt->num_irq_regs = aqt_regmap_irq_chip.num_regs; for (i = 0; i < aqt->num_irq_regs; i++) { regmap_write(aqt->regmap, (AQT1000_INTR_CTRL_INT_TYPE_2 + i), 0); diff --git a/asoc/codecs/aqt1000/aqt1000-routing.h b/asoc/codecs/aqt1000/aqt1000-routing.h index 9dc74a425ae3..7ae3276ff79a 100644 --- a/asoc/codecs/aqt1000/aqt1000-routing.h +++ b/asoc/codecs/aqt1000/aqt1000-routing.h @@ -85,30 +85,30 @@ const struct snd_soc_dapm_route aqt_audio_map[] = { {"AQT ANC0 FB MUX", "ANC_IN_HPHL", "AQT RX INT1 MIX2"}, {"AQT ANC1 FB MUX", "ANC_IN_HPHR", "AQT RX INT2 MIX2"}, - {"AQT I2S_L RX", "AIF1_PB", "AQT AIF1 PB"}, - {"AQT I2S_R RX", "AIF1_PB", "AQT AIF1 PB"}, + {"AQT I2S_L RX", NULL, "AQT AIF1 PB"}, + {"AQT I2S_R RX", NULL, "AQT AIF1 PB"}, - {"AQT RX INT1_1 MUX", "I2S_L", "AQT I2S_L RX"}, - {"AQT RX INT1_1 MUX", "I2S_R", "AQT I2S_R RX"}, + {"AQT RX INT1_1 MUX", "I2S0_L", "AQT I2S_L RX"}, + {"AQT RX INT1_1 MUX", "I2S0_R", "AQT I2S_R RX"}, {"AQT RX INT1_1 MUX", "DEC_L", "AQT ADC0 MUX"}, {"AQT RX INT1_1 MUX", "DEC_R", "AQT ADC1 MUX"}, {"AQT RX INT1_1 MUX", "DEC_V", "AQT ADC2 MUX"}, - {"AQT RX INT2_1 MUX", "I2S_L", "AQT I2S_L RX"}, - {"AQT RX INT2_1 MUX", "I2S_R", "AQT I2S_R RX"}, + {"AQT RX INT2_1 MUX", "I2S0_L", "AQT I2S_L RX"}, + {"AQT RX INT2_1 MUX", "I2S0_R", "AQT I2S_R RX"}, {"AQT RX INT2_1 MUX", "DEC_L", "AQT ADC0 MUX"}, {"AQT RX INT2_1 MUX", "DEC_R", "AQT ADC1 MUX"}, {"AQT RX INT2_1 MUX", "DEC_V", "AQT ADC2 MUX"}, - {"AQT RX INT1_2 MUX", "I2S_L", "AQT I2S_L RX"}, - {"AQT RX INT1_2 MUX", "I2S_R", "AQT I2S_R RX"}, + {"AQT RX INT1_2 MUX", "I2S0_L", "AQT I2S_L RX"}, + {"AQT RX INT1_2 MUX", "I2S0_R", "AQT I2S_R RX"}, {"AQT RX INT1_2 MUX", "DEC_L", "AQT ADC0 MUX"}, {"AQT RX INT1_2 MUX", "DEC_R", "AQT ADC1 MUX"}, {"AQT RX INT1_2 MUX", "DEC_V", "AQT ADC2 MUX"}, {"AQT RX INT1_2 MUX", "IIR0", "AQT IIR0"}, - {"AQT RX INT2_2 MUX", "I2S_L", "AQT I2S_L RX"}, - {"AQT RX INT2_2 MUX", "I2S_R", "AQT I2S_R RX"}, + {"AQT RX INT2_2 MUX", "I2S0_L", "AQT I2S_L RX"}, + {"AQT RX INT2_2 MUX", "I2S0_R", "AQT I2S_R RX"}, {"AQT RX INT2_2 MUX", "DEC_L", "AQT ADC0 MUX"}, {"AQT RX INT2_2 MUX", "DEC_R", "AQT ADC1 MUX"}, {"AQT RX INT2_2 MUX", "DEC_V", "AQT ADC2 MUX"}, @@ -137,6 +137,8 @@ const struct snd_soc_dapm_route aqt_audio_map[] = { {"AQT RX INT1 DEM MUX", "CLSH_DSM_OUT", "AQT RX INT1 MIX2"}, {"AQT RX INT1 DAC", NULL, "AQT RX INT1 DEM MUX"}, {"AQT RX INT1 DAC", NULL, "AQT RX_BIAS"}, + {"AQT RX_BIAS", NULL, "AQT MCLK"}, + {"AQT MIC BIAS1", NULL, "AQT MCLK"}, {"AQT HPHL PA", NULL, "AQT RX INT1 DAC"}, {"AQT HPHL", NULL, "AQT HPHL PA"}, @@ -152,10 +154,12 @@ const struct snd_soc_dapm_route aqt_audio_map[] = { {"AQT ANC HPHR PA", NULL, "AQT RX INT2 DAC"}, {"AQT ANC HPHR", NULL, "AQT ANC HPHR PA"}, - {"AQT IIR0", NULL, "AQT TX_PATH2"}, + {"AQT IIR0", NULL, "AQT ADC2 MUX"}, {"AQT SRC0", NULL, "AQT IIR0"}, - {"AQT RX INT1 MIX2", "SRC0", "AQT SRC0"}, - {"AQT RX INT2 MIX2", "SRC0", "AQT SRC0"}, + {"AQT RX ST MUX", "SRC0", "AQT SRC0"}, + + {"AQT RX INT1 MIX2", NULL, "AQT RX ST MUX"}, + {"AQT RX INT2 MIX2", NULL, "AQT RX ST MUX"}, /* Native clk main path routing */ {"AQT RX INT1_1 NATIVE MUX", "ON", "AQT RX INT1_1 MUX"}, diff --git a/asoc/codecs/aqt1000/aqt1000.c b/asoc/codecs/aqt1000/aqt1000.c index 21baae762a1f..8463d8223060 100644 --- a/asoc/codecs/aqt1000/aqt1000.c +++ b/asoc/codecs/aqt1000/aqt1000.c @@ -2542,6 +2542,26 @@ static const char * const native_mux_text[] = { AQT_DAPM_ENUM(int1_1_native, SND_SOC_NOPM, 0, native_mux_text); AQT_DAPM_ENUM(int2_1_native, SND_SOC_NOPM, 0, native_mux_text); +static int aqt_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int ret = 0; + + dev_dbg(codec->dev, "%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = aqt_cdc_mclk_enable(codec, true); + break; + case SND_SOC_DAPM_POST_PMD: + ret = aqt_cdc_mclk_enable(codec, false); + break; + } + + return ret; +} + static int aif_cap_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2561,8 +2581,17 @@ static const struct snd_kcontrol_new aif1_cap_mixer[] = { aif_cap_mixer_get, aif_cap_mixer_put), }; +static const char * const rx_inp_st_mux_text[] = { + "ZERO", "SRC0", +}; +AQT_DAPM_ENUM(rx_inp_st, AQT1000_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4, + rx_inp_st_mux_text); + static const struct snd_soc_dapm_widget aqt_dapm_widgets[] = { + SND_SOC_DAPM_SUPPLY("AQT MCLK", SND_SOC_NOPM, 0, 0, aqt_mclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_OUT_E("AQT AIF1 CAP", "AQT AIF1 Capture", 0, SND_SOC_NOPM, AIF1_CAP, 0, aqt_codec_enable_i2s_tx, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -2720,6 +2749,10 @@ static const struct snd_soc_dapm_widget aqt_dapm_widgets[] = { AQT_DAPM_MUX("AQT RX INT1_1 NATIVE MUX", 0, int1_1_native), AQT_DAPM_MUX("AQT RX INT2_1 NATIVE MUX", 0, int2_1_native), + + SND_SOC_DAPM_MUX("AQT RX ST MUX", + AQT1000_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2, 0, + &rx_inp_st_mux), }; static int aqt_startup(struct snd_pcm_substream *substream, @@ -3230,14 +3263,10 @@ int aqt_codec_info_create_codec_entry(struct snd_info_entry *codec_root, EXPORT_SYMBOL(aqt_codec_info_create_codec_entry); static const struct aqt_reg_mask_val aqt_codec_reg_init[] = { - {AQT1000_CHIP_CFG0_CLK_CFG_MCLK, 0x04, 0x00}, {AQT1000_CHIP_CFG0_EFUSE_CTL, 0x01, 0x01}, }; static const struct aqt_reg_mask_val aqt_codec_reg_update[] = { - {AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x01}, - {AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x01}, - {AQT1000_CHIP_CFG0_CLK_CTL_CDC_DIG, 0x01, 0x01}, {AQT1000_LDOH_MODE, 0x1F, 0x0B}, {AQT1000_MICB1_TEST_CTL_2, 0x07, 0x01}, {AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS, 0x03, 0x02}, -- GitLab From ca7ca2c80405e78abc15e5cbfaccdd78848997c7 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Mon, 4 Dec 2017 12:01:29 +0530 Subject: [PATCH 0220/1645] ASOC: wcd934x: Fix finding of correct AMIC During Tx path enablement, amic information is needed for proper power level settings and for better performance. Existing API returns incorrect amic information. Changes provide the correct amic information. Change-Id: I18f3f35212cae47e5d944c2e075f03889147722b Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd934x/wcd934x.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index b75df18da779..cc65084cb191 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -4132,7 +4132,7 @@ static int tavil_codec_find_amic_input(struct snd_soc_codec *codec, if (adc_mux_n < 3) { adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + - adc_mux_n; + 2 * adc_mux_n; mask = 0x03; shift = 0; amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + @@ -4145,7 +4145,7 @@ static int tavil_codec_find_amic_input(struct snd_soc_codec *codec, 2 * adc_mux_n; } else if (adc_mux_n < 7) { adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + - (adc_mux_n - 4); + 2 * (adc_mux_n - 4); mask = 0x0C; shift = 2; amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + @@ -4158,24 +4158,25 @@ static int tavil_codec_find_amic_input(struct snd_soc_codec *codec, adc_mux_n - 4; } else if (adc_mux_n < 12) { adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + - ((adc_mux_n == 8) ? (adc_mux_n - 8) : - (adc_mux_n - 9)); + 2 * (((adc_mux_n == 8) ? (adc_mux_n - 8) : + (adc_mux_n - 9))); mask = 0x30; shift = 4; - amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + - adc_mux_n - 4; + amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX8_CFG0 + + ((adc_mux_n == 8) ? (adc_mux_n - 8) : + (adc_mux_n - 9)); } else if (adc_mux_n < 13) { adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1; mask = 0x30; shift = 4; amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + - adc_mux_n - 4; + adc_mux_n - 5; } else { adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1; mask = 0xC0; shift = 6; amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + - adc_mux_n - 4; + adc_mux_n - 5; } is_amic = (((snd_soc_read(codec, adc_mux_in_reg) & mask) >> shift) -- GitLab From a74bac90507cda7b91327504526c1ce9de6813a2 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 7 Dec 2017 14:35:59 +0530 Subject: [PATCH 0221/1645] ASoC: Add Euro usb-c analog support for sdm670 internal codec Euro usb-c analog support is not present in machine driver for sdm670. Add support for corresponding gpio so that usb-c analog headset is reported correctly. CRs-Fixed: 2164436 Change-Id: I4bf73a9f13b7b8193289706ac21f96c557503fd8 Signed-off-by: Vatsal Bucha --- asoc/sdm660-common.c | 124 ++++++++++++++++++++++++++++++++++++++----- asoc/sdm660-common.h | 4 +- 2 files changed, 115 insertions(+), 13 deletions(-) diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c index ccfe528487dd..f2376b4ee29b 100644 --- a/asoc/sdm660-common.c +++ b/asoc/sdm660-common.c @@ -2824,27 +2824,123 @@ static int msm_prepare_us_euro(struct snd_soc_card *card) return ret; } + +static bool msm_usbc_swap_gnd_mic(struct snd_soc_codec *codec, bool active) +{ + int value = 0; + bool ret = false; + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct pinctrl_state *en2_pinctrl_active; + struct pinctrl_state *en2_pinctrl_sleep; + + if (!pdata->usbc_en2_gpio_p) { + if (active) { + /* if active and usbc_en2_gpio undefined, get pin */ + pdata->usbc_en2_gpio_p = devm_pinctrl_get(card->dev); + if (IS_ERR_OR_NULL(pdata->usbc_en2_gpio_p)) { + dev_err(card->dev, + "%s: Can't get EN2 gpio pinctrl:%ld\n", + __func__, + PTR_ERR(pdata->usbc_en2_gpio_p)); + pdata->usbc_en2_gpio_p = NULL; + return false; + } + } else { + /* if not active and usbc_en2_gpio undefined, return */ + return false; + } + } + + pdata->usbc_en2_gpio = of_get_named_gpio(card->dev->of_node, + "qcom,usbc-analog-en2-gpio", 0); + if (!gpio_is_valid(pdata->usbc_en2_gpio)) { + dev_err(card->dev, "%s, property %s not in node %s\n", + __func__, "qcom,usbc-analog-en2-gpio", + card->dev->of_node->full_name); + return false; + } + + en2_pinctrl_active = pinctrl_lookup_state( + pdata->usbc_en2_gpio_p, "aud_active"); + if (IS_ERR_OR_NULL(en2_pinctrl_active)) { + dev_err(card->dev, + "%s: Cannot get aud_active pinctrl state:%ld\n", + __func__, PTR_ERR(en2_pinctrl_active)); + ret = false; + goto err_lookup_state; + } + + en2_pinctrl_sleep = pinctrl_lookup_state( + pdata->usbc_en2_gpio_p, "aud_sleep"); + if (IS_ERR_OR_NULL(en2_pinctrl_sleep)) { + dev_err(card->dev, + "%s: Cannot get aud_sleep pinctrl state:%ld\n", + __func__, PTR_ERR(en2_pinctrl_sleep)); + ret = false; + goto err_lookup_state; + } + + /* if active and usbc_en2_gpio_p defined, swap using usbc_en2_gpio_p */ + if (active) { + dev_dbg(codec->dev, "%s: enter\n", __func__); + if (pdata->usbc_en2_gpio_p) { + value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); + if (value) + pinctrl_select_state(pdata->usbc_en2_gpio_p, + en2_pinctrl_sleep); + else + pinctrl_select_state(pdata->usbc_en2_gpio_p, + en2_pinctrl_active); + } else if (pdata->usbc_en2_gpio >= 0) { + value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); + gpio_set_value_cansleep(pdata->usbc_en2_gpio, !value); + } + pr_debug("%s: swap select switch %d to %d\n", __func__, + value, !value); + ret = true; + } else { + /* if not active, release usbc_en2_gpio_p pin */ + pinctrl_select_state(pdata->usbc_en2_gpio_p, + en2_pinctrl_sleep); + } + +err_lookup_state: + devm_pinctrl_put(pdata->usbc_en2_gpio_p); + pdata->usbc_en2_gpio_p = NULL; + return ret; +} + static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) { struct snd_soc_card *card = codec->component.card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); int value = 0; - - if (pdata->us_euro_gpio_p) { - value = msm_cdc_pinctrl_get_state(pdata->us_euro_gpio_p); - if (value) - msm_cdc_pinctrl_select_sleep_state( + bool ret = 0; + + if (!mbhc_cfg.enable_usbc_analog) { + if (pdata->us_euro_gpio_p) { + value = msm_cdc_pinctrl_get_state( + pdata->us_euro_gpio_p); + if (value) + msm_cdc_pinctrl_select_sleep_state( pdata->us_euro_gpio_p); - else - msm_cdc_pinctrl_select_active_state( + else + msm_cdc_pinctrl_select_active_state( pdata->us_euro_gpio_p); - } else if (pdata->us_euro_gpio >= 0) { - value = gpio_get_value_cansleep(pdata->us_euro_gpio); - gpio_set_value_cansleep(pdata->us_euro_gpio, !value); + } else if (pdata->us_euro_gpio >= 0) { + value = gpio_get_value_cansleep(pdata->us_euro_gpio); + gpio_set_value_cansleep(pdata->us_euro_gpio, !value); + } + pr_debug("%s: swap select switch %d to %d\n", + __func__, value, !value); + ret = true; + } else { + /* if usbc is defined, swap using usbc_en2 */ + ret = msm_usbc_swap_gnd_mic(codec, active); } - pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value); - return true; + return ret; } static int msm_populate_dai_link_component_of_node( @@ -3256,6 +3352,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) const char *mclk = "qcom,msm-mclk-freq"; int ret = -EINVAL, id; const struct of_device_id *match; + const char *usb_c_dt = "qcom,msm-mbhc-usbc-audio-supported"; pdata = devm_kzalloc(&pdev->dev, sizeof(struct msm_asoc_mach_data), @@ -3340,6 +3437,9 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; } + if (of_find_property(pdev->dev.of_node, usb_c_dt, NULL)) + mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; + ret = msm_prepare_us_euro(card); if (ret) dev_dbg(&pdev->dev, "msm_prepare_us_euro failed (%d)\n", diff --git a/asoc/sdm660-common.h b/asoc/sdm660-common.h index 030f5219a963..6c3eefa260e3 100644 --- a/asoc/sdm660-common.h +++ b/asoc/sdm660-common.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -93,9 +93,11 @@ enum { struct msm_asoc_mach_data { int us_euro_gpio; /* used by gpio driver API */ + int usbc_en2_gpio; /* used by gpio driver API */ int hph_en1_gpio; int hph_en0_gpio; struct device_node *us_euro_gpio_p; /* used by pinctrl API */ + struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */ struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ struct device_node *pdm_gpio_p; /* used by pinctrl API */ -- GitLab From 87f926a61218391b5c85533b3fde4a88c1f189dd Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Sun, 4 Mar 2018 22:47:50 -0800 Subject: [PATCH 0222/1645] ASoC: dsp: Fix LPASS clock timeout issue LPASS set clock time command times out because afe callback was waking up the incorrect wait queue. Use the appropriate index instead of the global index for wake up. CRs-Fixed: 2151551 Change-Id: I2d4f4c477913a9513ffae2992ecf777f7a3ed60d Signed-off-by: Vignesh Kulothungan --- dsp/q6afe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 9a6b6ada0644..0ecd3aaa16a1 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1122,7 +1122,7 @@ static int q6afe_svc_set_params_v1(int index, struct mem_mapping_hdr *mem_hdr, svc_set_param->apr_hdr.pkt_size = size; svc_set_param->apr_hdr.src_port = 0; svc_set_param->apr_hdr.dest_port = 0; - svc_set_param->apr_hdr.token = IDX_GLOBAL_CFG; + svc_set_param->apr_hdr.token = index; svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM; svc_set_param->payload_size = packed_data_size; @@ -1169,7 +1169,7 @@ static int q6afe_svc_set_params_v2(int index, struct mem_mapping_hdr *mem_hdr, svc_set_param->apr_hdr.pkt_size = size; svc_set_param->apr_hdr.src_port = 0; svc_set_param->apr_hdr.dest_port = 0; - svc_set_param->apr_hdr.token = IDX_GLOBAL_CFG; + svc_set_param->apr_hdr.token = index; svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM_V2; svc_set_param->payload_size = packed_data_size; -- GitLab From e61ddb01f8ec84eb9a0c74c445bee5de30c06779 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 7 Mar 2018 11:18:35 +0800 Subject: [PATCH 0223/1645] ASoC: Change PRODUCT_OUT to OUT in Kbuild Update module symbol folder from PRODUCT_OUT to OUT. Change-Id: I4542c3d2b5e9e39b69f15954ef425c1915a58456 Signed-off-by: Meng Wang --- asoc/Kbuild | 10 +++++----- asoc/codecs/Kbuild | 4 ++-- dsp/Kbuild | 2 +- dsp/codecs/Kbuild | 4 ++-- ipc/Kbuild | 2 +- soc/Kbuild | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/asoc/Kbuild b/asoc/Kbuild index 4ebce00485b1..3f4a8b13fea2 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -162,11 +162,11 @@ EXTRA_CFLAGS += -Wheader-guard endif ifeq ($(KERNEL_BUILD), 0) -KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers endif ifeq ($(KERNEL_BUILD), 1) obj-y += codecs/ diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index be4072bba8d8..01a6e2d74b41 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -162,8 +162,8 @@ endif ifeq ($(KERNEL_BUILD), 0) -KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers endif ifeq ($(KERNEL_BUILD), 1) diff --git a/dsp/Kbuild b/dsp/Kbuild index 3eeca047e778..df73215c4ef4 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -147,7 +147,7 @@ CDEFINES += -DMULTI_IF_NAME=\"$(CHIP_NAME)\" endif ifeq ($(KERNEL_BUILD), 0) -KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers endif ifeq ($(KERNEL_BUILD), 1) diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 0890920842d8..0f2adf71f9f5 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -126,8 +126,8 @@ EXTRA_CFLAGS += -Wheader-guard endif ifeq ($(KERNEL_BUILD), 0) -KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers endif # Module information used by KBuild framework diff --git a/ipc/Kbuild b/ipc/Kbuild index aad47b47b071..3cc021c457bd 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -112,7 +112,7 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ KBUILD_CPPFLAGS += $(CDEFINES) ifeq ($(KERNEL_BUILD), 0) -KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers endif # Currently, for versions of gcc which support it, the kernel Makefile diff --git a/soc/Kbuild b/soc/Kbuild index 263166745c2a..36a2c88d5197 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -103,7 +103,7 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ KBUILD_CPPFLAGS += $(CDEFINES) ifeq ($(KERNEL_BUILD), 0) -KBUILD_EXTRA_SYMBOLS +=$(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers endif # Currently, for versions of gcc which support it, the kernel Makefile -- GitLab From 3bda9b1de1d23f25942db5d5d6d605066bca8f1a Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Mon, 15 Jan 2018 15:00:42 -0800 Subject: [PATCH 0224/1645] asoc: wcd934x: optimize ANC enablement logic for Tavil codec In Tavil driver, both ANC0 and ANC1 channel registers are written when each ANC channel is enabled. This logic results in high latency during ANC enablement on Tavil codec. Optimize this logic by only writing the corresponding channel registers when enabling ANC0 or ANC1. Change-Id: I62e8572967e6ca6c851cbaaad5f1b8c19e5b1a5f Signed-off-by: Xiaoyu Ye --- asoc/codecs/wcd934x/wcd934x.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index cc65084cb191..21c7f12e7087 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -897,7 +897,6 @@ static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w, struct wcd9xxx_anc_header *anc_head; struct firmware_cal *hwdep_cal = NULL; u32 anc_writes_size = 0; - u32 anc_cal_size = 0; int anc_size_remaining; u32 *anc_ptr; u16 reg; @@ -986,8 +985,16 @@ static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w, goto err; } - anc_cal_size = anc_writes_size; - for (i = 0; i < anc_writes_size; i++) { + i = 0; + + if (!strcmp(w->name, "RX INT1 DAC") || + !strcmp(w->name, "RX INT3 DAC")) + anc_writes_size = anc_writes_size / 2; + else if (!strcmp(w->name, "RX INT2 DAC") || + !strcmp(w->name, "RX INT4 DAC")) + i = anc_writes_size / 2; + + for (; i < anc_writes_size; i++) { WCD934X_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val); snd_soc_write(codec, reg, (val & mask)); } -- GitLab From 8fe02478b7faa13d589ea3e2b98e74c6abb84fe1 Mon Sep 17 00:00:00 2001 From: Phani Kumar Uppalapati Date: Wed, 17 Jan 2018 18:42:52 -0800 Subject: [PATCH 0225/1645] asoc: wcd-mbhc: add support for usbc analog audio on msmnile Add support for usbc analog audio for msmnile platform by adding fsa driver calls in mbhc driver to make any switching orientation changes of gnd/mic. Change-Id: Iab7511907325a24345734402c10a4cf5f8ebfa23 Signed-off-by: Phani Kumar Uppalapati --- asoc/codecs/wcd-mbhc-v2.c | 299 ++++++-------------------------------- asoc/codecs/wcd-mbhc-v2.h | 18 +-- 2 files changed, 49 insertions(+), 268 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 93ff975e8371..97989dee1826 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include "msm-cdc-pinctrl.h" @@ -958,6 +959,9 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) mbhc->extn_cable_hph_rem = false; wcd_mbhc_report_plug(mbhc, 0, jack_type); + if (mbhc->mbhc_cfg->enable_usbc_analog) + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 0); + } else if (!detection_type) { /* Disable external voltage source to micbias if present */ if (mbhc->mbhc_cb->enable_mb_source) @@ -1291,8 +1295,8 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) * by an external source */ if (mbhc->mbhc_cfg->enable_usbc_analog) { - mbhc->hphl_swh = 1; - mbhc->gnd_swh = 1; + mbhc->hphl_swh = 0; + mbhc->gnd_swh = 0; if (mbhc->mbhc_cb->hph_pull_up_control_v2) mbhc->mbhc_cb->hph_pull_up_control_v2(codec, @@ -1310,7 +1314,16 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) if (mbhc->mbhc_cfg->gnd_det_en && mbhc->mbhc_cb->mbhc_gnd_det_ctrl) mbhc->mbhc_cb->mbhc_gnd_det_ctrl(codec, true); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL, 1); - WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1); + + /* + * Disable L_DET for USB-C analog audio to avoid spurious interrupts + * when a non-audio accessory is inserted. L_DET_EN sets to 1 when FSA + * I2C driver notifies that ANALOG_AUDIO_ADAPTER is inserted + */ + if (mbhc->mbhc_cfg->enable_usbc_analog) + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 0); + else + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1); if (mbhc->mbhc_cfg->enable_usbc_analog) { /* Insertion debounce set to 48ms */ @@ -1481,207 +1494,26 @@ static int wcd_mbhc_set_keycode(struct wcd_mbhc *mbhc) return result; } -static int wcd_mbhc_usb_c_analog_setup_gpios(struct wcd_mbhc *mbhc, - bool active) +static int wcd_mbhc_usbc_ana_event_handler(struct notifier_block *nb, + unsigned long mode, void *ptr) { - int rc = 0; - struct usbc_ana_audio_config *config = - &mbhc->mbhc_cfg->usbc_analog_cfg; - union power_supply_propval pval; - - dev_dbg(mbhc->codec->dev, "%s: setting GPIOs active = %d\n", - __func__, active); + struct wcd_mbhc *mbhc = container_of(nb, struct wcd_mbhc, fsa_nb); - memset(&pval, 0, sizeof(pval)); - - if (active) { - pval.intval = POWER_SUPPLY_TYPEC_PR_SOURCE; - if (power_supply_set_property(mbhc->usb_psy, - POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &pval)) - dev_info(mbhc->codec->dev, "%s: force PR_SOURCE mode unsuccessful\n", - __func__); - else - mbhc->usbc_force_pr_mode = true; - - if (config->usbc_en1_gpio_p) - rc = msm_cdc_pinctrl_select_active_state( - config->usbc_en1_gpio_p); - if (rc == 0 && config->usbc_force_gpio_p) - rc = msm_cdc_pinctrl_select_active_state( - config->usbc_force_gpio_p); - mbhc->usbc_mode = POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER; - } else { - /* no delay is required when disabling GPIOs */ - if (config->usbc_en1_gpio_p) - msm_cdc_pinctrl_select_sleep_state( - config->usbc_en1_gpio_p); - if (config->usbc_force_gpio_p) - msm_cdc_pinctrl_select_sleep_state( - config->usbc_force_gpio_p); - - if (mbhc->usbc_force_pr_mode) { - pval.intval = POWER_SUPPLY_TYPEC_PR_DUAL; - if (power_supply_set_property(mbhc->usb_psy, - POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &pval)) - dev_info(mbhc->codec->dev, "%s: force PR_DUAL mode unsuccessful\n", - __func__); - - mbhc->usbc_force_pr_mode = false; - } - - mbhc->usbc_mode = POWER_SUPPLY_TYPEC_NONE; - if (mbhc->mbhc_cfg->swap_gnd_mic) - mbhc->mbhc_cfg->swap_gnd_mic(mbhc->codec, false); - } - - return rc; -} - -/* workqueue */ -static void wcd_mbhc_usbc_analog_work_fn(struct work_struct *work) -{ - struct wcd_mbhc *mbhc = - container_of(work, struct wcd_mbhc, usbc_analog_work); - - wcd_mbhc_usb_c_analog_setup_gpios(mbhc, - mbhc->usbc_mode != POWER_SUPPLY_TYPEC_NONE); -} - -/* this callback function is used to process PMI notification */ -static int wcd_mbhc_usb_c_event_changed(struct notifier_block *nb, - unsigned long evt, void *ptr) -{ - int ret; - union power_supply_propval mode; - struct wcd_mbhc *mbhc = container_of(nb, struct wcd_mbhc, psy_nb); - struct snd_soc_codec *codec = mbhc->codec; - - if (ptr != mbhc->usb_psy || evt != PSY_EVENT_PROP_CHANGED) - return 0; - - ret = power_supply_get_property(mbhc->usb_psy, - POWER_SUPPLY_PROP_TYPEC_MODE, &mode); - if (ret) { - dev_err(codec->dev, "%s: Unable to read USB TYPEC_MODE: %d\n", - __func__, ret); - return ret; - } - - dev_dbg(codec->dev, "%s: USB change event received\n", - __func__); - dev_dbg(codec->dev, "%s: supply mode %d, expected %d\n", __func__, - mode.intval, POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER); - - switch (mode.intval) { - case POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER: - case POWER_SUPPLY_TYPEC_NONE: - dev_dbg(codec->dev, "%s: usbc_mode: %d; mode.intval: %d\n", - __func__, mbhc->usbc_mode, mode.intval); - - if (mbhc->usbc_mode == mode.intval) - break; /* filter notifications received before */ - mbhc->usbc_mode = mode.intval; - - dev_dbg(codec->dev, "%s: queueing usbc_analog_work\n", - __func__); - schedule_work(&mbhc->usbc_analog_work); - break; - default: - break; - } - return ret; -} - -/* PMI registration code */ -static int wcd_mbhc_usb_c_analog_init(struct wcd_mbhc *mbhc) -{ - int ret = 0; - struct snd_soc_codec *codec = mbhc->codec; + if (!mbhc) + return -EINVAL; - dev_dbg(mbhc->codec->dev, "%s: usb-c analog setup start\n", __func__); - INIT_WORK(&mbhc->usbc_analog_work, wcd_mbhc_usbc_analog_work_fn); + dev_dbg(mbhc->codec->dev, "%s: mode = %lu\n", __func__, mode); - mbhc->usb_psy = power_supply_get_by_name("usb"); - if (IS_ERR_OR_NULL(mbhc->usb_psy)) { - dev_err(codec->dev, "%s: could not get USB psy info\n", - __func__); - ret = -EPROBE_DEFER; - if (IS_ERR(mbhc->usb_psy)) - ret = PTR_ERR(mbhc->usb_psy); - mbhc->usb_psy = NULL; - goto err; + if (mode == POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) { + /* insertion detected, enable L_DET_EN */ + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1); } - - ret = wcd_mbhc_usb_c_analog_setup_gpios(mbhc, false); - if (ret) { - dev_err(codec->dev, "%s: error while setting USBC ana gpios\n", - __func__); - goto err; - } - - mbhc->psy_nb.notifier_call = wcd_mbhc_usb_c_event_changed; - mbhc->psy_nb.priority = 0; - ret = power_supply_reg_notifier(&mbhc->psy_nb); - if (ret) { - dev_err(codec->dev, "%s: power supply registration failed\n", - __func__); - goto err; - } - - /* - * as part of the init sequence check if there is a connected - * USB C analog adapter - */ - dev_dbg(mbhc->codec->dev, "%s: verify if USB adapter is already inserted\n", - __func__); - ret = wcd_mbhc_usb_c_event_changed(&mbhc->psy_nb, - PSY_EVENT_PROP_CHANGED, - mbhc->usb_psy); - -err: - return ret; -} - -static int wcd_mbhc_usb_c_analog_deinit(struct wcd_mbhc *mbhc) -{ - wcd_mbhc_usb_c_analog_setup_gpios(mbhc, false); - - /* deregister from PMI */ - power_supply_unreg_notifier(&mbhc->psy_nb); - return 0; } -static int wcd_mbhc_init_gpio(struct wcd_mbhc *mbhc, - struct wcd_mbhc_config *mbhc_cfg, - const char *gpio_dt_str, - int *gpio, struct device_node **gpio_dn) -{ - int rc = 0; - struct snd_soc_codec *codec = mbhc->codec; - struct snd_soc_card *card = codec->component.card; - - dev_dbg(mbhc->codec->dev, "%s: gpio %s\n", __func__, gpio_dt_str); - - *gpio_dn = of_parse_phandle(card->dev->of_node, gpio_dt_str, 0); - - if (!(*gpio_dn)) { - *gpio = of_get_named_gpio(card->dev->of_node, gpio_dt_str, 0); - if (!gpio_is_valid(*gpio)) { - dev_err(card->dev, "%s, property %s not in node %s", - __func__, gpio_dt_str, - card->dev->of_node->full_name); - rc = -EINVAL; - } - } - - return rc; -} - int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) { int rc = 0; - struct usbc_ana_audio_config *config; struct snd_soc_codec *codec; struct snd_soc_card *card; const char *usb_c_dt = "qcom,msm-mbhc-usbc-audio-supported"; @@ -1689,7 +1521,6 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) if (!mbhc || !mbhc_cfg) return -EINVAL; - config = &mbhc_cfg->usbc_analog_cfg; codec = mbhc->codec; card = codec->component.card; @@ -1705,42 +1536,24 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) &mbhc_cfg->enable_usbc_analog); } if (mbhc_cfg->enable_usbc_analog == 0 || rc != 0) { - dev_info(card->dev, + dev_dbg(card->dev, "%s: %s in dt node is missing or false\n", __func__, usb_c_dt); - dev_info(card->dev, + dev_dbg(card->dev, "%s: skipping USB c analog configuration\n", __func__); } - /* initialize GPIOs */ + /* Parse fsa switch handle */ if (mbhc_cfg->enable_usbc_analog) { dev_dbg(mbhc->codec->dev, "%s: usbc analog enabled\n", __func__); mbhc->swap_thr = GND_MIC_USBC_SWAP_THRESHOLD; - rc = wcd_mbhc_init_gpio(mbhc, mbhc_cfg, - "qcom,usbc-analog-en1-gpio", - &config->usbc_en1_gpio, - &config->usbc_en1_gpio_p); - if (rc) - goto err; - - if (of_find_property(card->dev->of_node, - "qcom,usbc-analog-force_detect_gpio", - NULL)) { - rc = wcd_mbhc_init_gpio(mbhc, mbhc_cfg, - "qcom,usbc-analog-force_detect_gpio", - &config->usbc_force_gpio, - &config->usbc_force_gpio_p); - if (rc) - goto err; - } - - dev_dbg(mbhc->codec->dev, "%s: calling usb_c_analog_init\n", - __func__); - /* init PMI notifier */ - rc = wcd_mbhc_usb_c_analog_init(mbhc); - if (rc) { - rc = EPROBE_DEFER; + mbhc->fsa_np = of_parse_phandle(card->dev->of_node, + "fsa4480-i2c-handle", 0); + if (!mbhc->fsa_np) { + dev_err(card->dev, "%s: fsa4480 i2c node not found\n", + __func__); + rc = -EINVAL; goto err; } } @@ -1753,6 +1566,11 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) (mbhc->mbhc_cfg->read_fw_bin && mbhc->mbhc_fw) || (mbhc->mbhc_cfg->read_fw_bin && mbhc->mbhc_cal)) { rc = wcd_mbhc_initialise(mbhc); + if (rc) { + dev_err(card->dev, "%s: wcd mbhc initialize failed\n", + __func__); + goto err; + } } else { if (!mbhc->mbhc_fw || !mbhc->mbhc_cal) schedule_delayed_work(&mbhc->mbhc_firmware_dwork, @@ -1762,24 +1580,14 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) __func__, mbhc->mbhc_fw, mbhc->mbhc_cal); } + if (mbhc_cfg->enable_usbc_analog) { + mbhc->fsa_nb.notifier_call = wcd_mbhc_usbc_ana_event_handler; + mbhc->fsa_nb.priority = 0; + rc = fsa4480_reg_notifier(&mbhc->fsa_nb, mbhc->fsa_np); + } + return rc; err: - if (config->usbc_en1_gpio > 0) { - dev_dbg(card->dev, "%s free usb en1 gpio %d\n", - __func__, config->usbc_en1_gpio); - gpio_free(config->usbc_en1_gpio); - config->usbc_en1_gpio = 0; - } - if (config->usbc_force_gpio > 0) { - dev_dbg(card->dev, "%s free usb_force gpio %d\n", - __func__, config->usbc_force_gpio); - gpio_free(config->usbc_force_gpio); - config->usbc_force_gpio = 0; - } - if (config->usbc_en1_gpio_p) - of_node_put(config->usbc_en1_gpio_p); - if (config->usbc_force_gpio_p) - of_node_put(config->usbc_force_gpio_p); dev_dbg(mbhc->codec->dev, "%s: leave %d\n", __func__, rc); return rc; } @@ -1787,8 +1595,6 @@ EXPORT_SYMBOL(wcd_mbhc_start); void wcd_mbhc_stop(struct wcd_mbhc *mbhc) { - struct usbc_ana_audio_config *config = &mbhc->mbhc_cfg->usbc_analog_cfg; - pr_debug("%s: enter\n", __func__); if (mbhc->current_plug != MBHC_PLUG_TYPE_NONE) { @@ -1813,19 +1619,8 @@ void wcd_mbhc_stop(struct wcd_mbhc *mbhc) mbhc->mbhc_cal = NULL; } - if (mbhc->mbhc_cfg->enable_usbc_analog) { - wcd_mbhc_usb_c_analog_deinit(mbhc); - /* free GPIOs */ - if (config->usbc_en1_gpio > 0) - gpio_free(config->usbc_en1_gpio); - if (config->usbc_force_gpio) - gpio_free(config->usbc_force_gpio); - - if (config->usbc_en1_gpio_p) - of_node_put(config->usbc_en1_gpio_p); - if (config->usbc_force_gpio_p) - of_node_put(config->usbc_force_gpio_p); - } + if (mbhc->mbhc_cfg->enable_usbc_analog) + fsa4480_unreg_notifier(&mbhc->fsa_nb, mbhc->fsa_np); pr_debug("%s: leave\n", __func__); } diff --git a/asoc/codecs/wcd-mbhc-v2.h b/asoc/codecs/wcd-mbhc-v2.h index fc8b3f8f484b..2fb09ff5be5c 100644 --- a/asoc/codecs/wcd-mbhc-v2.h +++ b/asoc/codecs/wcd-mbhc-v2.h @@ -422,15 +422,6 @@ enum mbhc_moisture_rref { R_184_KOHM, }; -struct usbc_ana_audio_config { - int usbc_en1_gpio; - int usbc_en2_gpio; - int usbc_force_gpio; - struct device_node *usbc_en1_gpio_p; /* used by pinctrl API */ - struct device_node *usbc_en2_gpio_p; /* used by pinctrl API */ - struct device_node *usbc_force_gpio_p; /* used by pinctrl API */ -}; - struct wcd_mbhc_config { bool read_fw_bin; void *calibration; @@ -446,7 +437,6 @@ struct wcd_mbhc_config { int anc_micbias; bool enable_anc_mic_detect; u32 enable_usbc_analog; - struct usbc_ana_audio_config usbc_analog_cfg; }; struct wcd_mbhc_intr { @@ -599,14 +589,10 @@ struct wcd_mbhc { unsigned long intr_status; bool is_hph_ocp_pending; - bool usbc_force_pr_mode; - int usbc_mode; - struct notifier_block psy_nb; - struct power_supply *usb_psy; - struct work_struct usbc_analog_work; - struct wcd_mbhc_fn *mbhc_fn; bool force_linein; + struct device_node *fsa_np; + struct notifier_block fsa_nb; }; void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc, -- GitLab From a29178a08eeca6471d5a2b75274c16107127dfcd Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 22 Feb 2018 01:36:23 -0800 Subject: [PATCH 0226/1645] asoc: msmnile: add usbc analog handle parsing Add change to parse fsa handle in machine driver to use it to call gnd/mic swap api of fsa driver. Change-Id: Ie9c2aede45138b0d4e3bf94f11feccab47874223 Signed-off-by: Karthikeyan Mani --- asoc/sdm855.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/asoc/sdm855.c b/asoc/sdm855.c index 2690ed5cd51d..79642d4e4a10 100644 --- a/asoc/sdm855.c +++ b/asoc/sdm855.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -165,6 +166,7 @@ struct msm_asoc_mach_data { struct device_node *us_euro_gpio_p; /* used by pinctrl API */ struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ + struct device_node *fsa_handle; }; struct msm_asoc_wcd93xx_codec { @@ -3581,7 +3583,14 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, static bool msm_usbc_swap_gnd_mic(struct snd_soc_codec *codec, bool active) { - return false; + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + + if (!pdata->fsa_handle) + return false; + + return fsa4480_switch_event(pdata->fsa_handle, FSA_MIC_GND_SWAP); } static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) @@ -7293,6 +7302,12 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) "qcom,us-euro-gpios"); wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; } + pdata->fsa_handle = of_parse_phandle(pdev->dev.of_node, + "fsa4480-i2c-handle", 0); + if (!pdata->fsa_handle) + dev_dbg(&pdev->dev, "property %s not detected in node %s\n", + "fsa4480-i2c-handle", pdev->dev.of_node->full_name); + /* Parse pinctrl info from devicetree */ ret = msm_get_pinctrl(pdev); if (!ret) { -- GitLab From f7dd63a169853c87114b02efcd5332467486261f Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Tue, 19 Dec 2017 16:56:24 +0800 Subject: [PATCH 0227/1645] soc: soundwire: use pm runtime function to tear down soundwire master Use pm_runtime_put_sync_suspend to tear down soundwire master. It makes sure the process is synced with the autosuspend call flow. Change-Id: Ib4feccd905bcbf046e58bd5eaffde40ee391feda Signed-off-by: Xiaojun Sang --- soc/swr-wcd-ctrl.c | 45 +++++++++++++++++++++++---------------------- soc/swr-wcd-ctrl.h | 3 +++ 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c index c5ba37bea84c..38f8a3d86c2e 100644 --- a/soc/swr-wcd-ctrl.c +++ b/soc/swr-wcd-ctrl.c @@ -1481,6 +1481,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_init(&swrm->mlock); INIT_LIST_HEAD(&swrm->mport_list); mutex_init(&swrm->reslock); + mutex_init(&swrm->force_down_lock); ret = of_property_read_u32(swrm->dev->of_node, "qcom,swr-num-dev", &swrm->num_dev); @@ -1557,6 +1558,9 @@ static int swrm_probe(struct platform_device *pdev) swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, SWR_IRQ_FREE); err_irq_fail: + mutex_destroy(&swrm->mlock); + mutex_destroy(&swrm->reslock); + mutex_destroy(&swrm->force_down_lock); err_pdata_fail: kfree(swrm); err_memory_fail: @@ -1581,6 +1585,7 @@ static int swrm_remove(struct platform_device *pdev) swr_unregister_master(&swrm->master); mutex_destroy(&swrm->mlock); mutex_destroy(&swrm->reslock); + mutex_destroy(&swrm->force_down_lock); kfree(swrm); return 0; } @@ -1644,13 +1649,20 @@ static int swrm_runtime_suspend(struct device *dev) int ret = 0; struct swr_master *mstr = &swrm->master; struct swr_device *swr_dev; + int current_state = 0; dev_dbg(dev, "%s: pm_runtime: suspend state: %d\n", __func__, swrm->state); mutex_lock(&swrm->reslock); - if ((swrm->state == SWR_MSTR_RESUME) || - (swrm->state == SWR_MSTR_UP)) { - if (swrm_is_port_en(&swrm->master)) { + mutex_lock(&swrm->force_down_lock); + current_state = swrm->state; + mutex_unlock(&swrm->force_down_lock); + if ((current_state == SWR_MSTR_RESUME) || + (current_state == SWR_MSTR_UP) || + (current_state == SWR_MSTR_SSR)) { + + if ((current_state != SWR_MSTR_SSR) && + swrm_is_port_en(&swrm->master)) { dev_dbg(dev, "%s ports are enabled\n", __func__); ret = -EBUSY; goto exit; @@ -1679,27 +1691,16 @@ static int swrm_device_down(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); int ret = 0; - struct swr_master *mstr = &swrm->master; - struct swr_device *swr_dev; dev_dbg(dev, "%s: swrm state: %d\n", __func__, swrm->state); - mutex_lock(&swrm->reslock); - if ((swrm->state == SWR_MSTR_RESUME) || - (swrm->state == SWR_MSTR_UP)) { - list_for_each_entry(swr_dev, &mstr->devices, dev_list) { - ret = swr_device_down(swr_dev); - if (ret) - dev_err(dev, - "%s: failed to shutdown swr dev %d\n", - __func__, swr_dev->dev_num); - } - dev_dbg(dev, "%s: Shutting down SWRM\n", __func__); - pm_runtime_disable(dev); - pm_runtime_set_suspended(dev); - pm_runtime_enable(dev); - swrm_clk_request(swrm, false); - } - mutex_unlock(&swrm->reslock); + + mutex_lock(&swrm->force_down_lock); + swrm->state = SWR_MSTR_SSR; + mutex_unlock(&swrm->force_down_lock); + /* Use pm runtime function to tear down */ + ret = pm_runtime_put_sync_suspend(dev); + pm_runtime_get_noresume(dev); + return ret; } diff --git a/soc/swr-wcd-ctrl.h b/soc/swr-wcd-ctrl.h index fcf0652a6434..dc8d7f51f34a 100644 --- a/soc/swr-wcd-ctrl.h +++ b/soc/swr-wcd-ctrl.h @@ -34,6 +34,7 @@ enum { SWR_MSTR_RESUME, SWR_MSTR_UP, SWR_MSTR_DOWN, + SWR_MSTR_SSR, }; enum { @@ -105,6 +106,8 @@ struct swr_mstr_ctrl { struct platform_device *pdev; int num_rx_chs; u8 num_cfg_devs; + struct mutex force_down_lock; + int force_down_state; }; #endif /* _SWR_WCD_CTRL_H */ -- GitLab From bb4029020d14caacdf9e30979f2d54acfc39a601 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 10 Jan 2018 15:25:57 +0800 Subject: [PATCH 0228/1645] asoc: wcd934x: update register default values before post SSR Update register default values before post SSR to avoid codec nack issue. Change-Id: Ibf1e3275d27c4b65ab179b9ddc5a51621c89eab7 Signed-off-by: Meng Wang --- asoc/codecs/wcd934x/wcd934x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 21c7f12e7087..bf9627c79335 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -10021,8 +10021,8 @@ static int tavil_post_reset_cb(struct wcd9xxx *wcd9xxx) else if (control->mclk_rate == WCD934X_MCLK_CLK_9P6MHZ) snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x01); - wcd_resmgr_post_ssr_v2(tavil->resmgr); tavil_update_reg_defaults(tavil); + wcd_resmgr_post_ssr_v2(tavil->resmgr); tavil_codec_init_reg(tavil); __tavil_enable_efuse_sensing(tavil); tavil_mclk2_reg_defaults(tavil); -- GitLab From 80b67f4e39f614a17ae21f30793522187f3f0bab Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Sat, 3 Mar 2018 01:44:55 -0800 Subject: [PATCH 0229/1645] dsp: msm_audio_ion: use dma_buf_vmap for mapping dma_buf to kernel Use the newly added dma_buf_vmap API for mapping a dma_buf to kernel address space. Change-Id: Idacada71eb827b4af96a793a180456ae910e30e8 Signed-off-by: Banajit Goswami --- dsp/msm_audio_ion.c | 40 ++++------------------------------------ 1 file changed, 4 insertions(+), 36 deletions(-) diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index 6ba29dce1075..24ef4af57dc4 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -208,10 +208,8 @@ static int msm_audio_ion_get_phys(struct dma_buf *dma_buf, static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf) { - int i = 0; int rc = 0; void *addr = NULL; - unsigned int pg_cnt = 0; struct msm_audio_alloc_data *alloc_data = NULL; rc = dma_buf_begin_cpu_access(dma_buf, DMA_BIDIRECTIONAL); @@ -220,30 +218,12 @@ static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf) goto exit; } - pg_cnt = dma_buf->size / PAGE_SIZE; - if (dma_buf->size % PAGE_SIZE) - pg_cnt++; - - if (pg_cnt == 0) { - pr_err("%s: Page count is NULL\n", __func__); - goto exit; - } - - /* Map the first page, and store the address to addr */ - addr = dma_buf_kmap(dma_buf, 0); + addr = dma_buf_vmap(dma_buf); if (!addr) { - pr_err("%s: mapping kernel buffer failed for page 0\n", + pr_err("%s: kernel mapping of dma_buf failed\n", __func__); goto exit; } - /* Map remaining pages */ - for (i = 1; i < pg_cnt; i++) { - if (!dma_buf_kmap(dma_buf, i)) { - pr_err("%s: mapping kernel buffer failed for page %d\n", - __func__, i); - goto err; - } - } /* * TBD: remove the below section once new API @@ -259,20 +239,13 @@ static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf) } mutex_unlock(&(msm_audio_ion_data.list_mutex)); - return addr; - -err: - for (; i > 0; i--) - dma_buf_kunmap(dma_buf, i - 1, addr); - addr = NULL; exit: return addr; } static void msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf) { - int i, rc = 0; - unsigned int pg_cnt = 0; + int rc = 0; void *vaddr = NULL; struct msm_audio_alloc_data *alloc_data = NULL; struct device *cb_dev = msm_audio_ion_data.cb_dev; @@ -298,12 +271,7 @@ static void msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf) goto err; } - pg_cnt = dma_buf->size / PAGE_SIZE; - if (dma_buf->size % PAGE_SIZE) - pg_cnt++; - - for (i = 0; i < pg_cnt; i++) - dma_buf_kunmap(dma_buf, i, vaddr); + dma_buf_vunmap(dma_buf, vaddr); rc = dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL); if (rc) { -- GitLab From e75ea788488f37f3ece921c5c56f3395596b06f6 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Wed, 14 Mar 2018 15:00:12 -0700 Subject: [PATCH 0230/1645] ipc: wcd-dsp-glink: fix channels name property Parse the right channel name property to get the number of wdsp channels supported. Change-Id: I77d367aeab759c3eaf4a42b56f8fcb1261fe6e44 Signed-off-by: Vidyakumar Athota --- ipc/wcd-dsp-glink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipc/wcd-dsp-glink.c b/ipc/wcd-dsp-glink.c index 04df026579ad..8e1d8a2757da 100644 --- a/ipc/wcd-dsp-glink.c +++ b/ipc/wcd-dsp-glink.c @@ -569,7 +569,7 @@ static int wdsp_register_rpmsg(struct platform_device *pdev, return -ENOMEM; no_of_channels = of_property_count_strings(pdev->dev.of_node, - "qcom,wdsp_channles"); + "qcom,wdsp-channels"); if (no_of_channels < 0) { dev_err(&pdev->dev, "%s: channel name parse error %d\n", __func__, no_of_channels); -- GitLab From 7dcd2d585f190223113d7d504a608f2794770479 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Wed, 14 Mar 2018 13:14:16 -0700 Subject: [PATCH 0231/1645] asoc: codecs: register pahu codec with slimbus Add pahu-slim-ngd under wcd_slim_device_id list to register pahu codec with slimbus driver. Change-Id: I87a9a56087fd1520fe592b39eb142297c2f176e0 Signed-off-by: Vidyakumar Athota --- asoc/codecs/wcd9xxx-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index d3231a2833c1..7cb7f68f352a 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -1350,7 +1350,8 @@ static int wcd9xxx_slim_probe(struct slim_device *slim) * Vout_D to be ready after BUCK_SIDO is powered up. * SYS_RST_N shouldn't be pulled high during this time */ - if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X) + if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X || + wcd9xxx->type == WCD9360) usleep_range(600, 650); else usleep_range(5, 10); @@ -1596,6 +1597,7 @@ static const struct slim_device_id wcd_slim_device_id[] = { {"tomtom-slim-pgd", WCD9330}, {"tasha-slim-pgd", WCD9335}, {"tavil-slim-pgd", WCD934X}, + {"pahu-slim-pgd", WCD9360}, {} }; -- GitLab From a347bbd7c84b1b281ceb6db012572d85013f6cdb Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Thu, 15 Mar 2018 19:20:14 -0700 Subject: [PATCH 0232/1645] asoc: codecs: remove devm clean up functions Devm clean up functions are removed to avoid calling twice as these are excuted during removal of device. Change-Id: Ifddde69d189b59456ef7627f32532198654e40d3 Signed-off-by: Vidyakumar Athota --- asoc/codecs/msm-cdc-supply.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/asoc/codecs/msm-cdc-supply.c b/asoc/codecs/msm-cdc-supply.c index 6687ec58a746..1b3c5f9381cf 100644 --- a/asoc/codecs/msm-cdc-supply.c +++ b/asoc/codecs/msm-cdc-supply.c @@ -309,10 +309,7 @@ int msm_cdc_release_supplies(struct device *dev, regulator_set_voltage(supplies[i].consumer, 0, cdc_vreg[i].max_uV); regulator_set_load(supplies[i].consumer, 0); - devm_regulator_put(supplies[i].consumer); - supplies[i].consumer = NULL; } - devm_kfree(dev, supplies); return rc; } @@ -430,14 +427,14 @@ int msm_cdc_init_supplies(struct device *dev, if (rc) { dev_err(dev, "%s: set regulator voltage failed for %s, err:%d\n", __func__, vsup[i].supply, rc); - goto err_set_supply; + goto err_supply; } rc = regulator_set_load(vsup[i].consumer, cdc_vreg[i].optimum_uA); if (rc < 0) { dev_err(dev, "%s: set regulator optimum mode failed for %s, err:%d\n", __func__, vsup[i].supply, rc); - goto err_set_supply; + goto err_supply; } } @@ -445,11 +442,7 @@ int msm_cdc_init_supplies(struct device *dev, return 0; -err_set_supply: - for (i = 0; i < num_supplies; i++) - devm_regulator_put(vsup[i].consumer); err_supply: - devm_kfree(dev, vsup); return rc; } EXPORT_SYMBOL(msm_cdc_init_supplies); @@ -548,7 +541,6 @@ int msm_cdc_get_power_supplies(struct device *dev, return 0; err_sup: - devm_kfree(dev, cdc_reg); err_supply_cnt: err_mem_alloc: return rc; -- GitLab From 98464a25ea77d343ab46440ebf486792d0fd46e1 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Thu, 15 Mar 2018 20:39:37 -0700 Subject: [PATCH 0233/1645] dsp: add export symbol for adm_param_enable_v2 Export symbol is added for adm_param_enable_v2 function so that it can be used by other modules. Change-Id: I373bb91c014a669b16d5e578eeaa82f9aae39332 Signed-off-by: Vidyakumar Athota --- dsp/q6adm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index f0b7121977fb..999eb6a9b474 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -3705,6 +3705,7 @@ int adm_param_enable(int port_id, int copp_idx, int module_id, int enable) return adm_param_enable_v2(port_id, copp_idx, mod_inst_info, enable); } +EXPORT_SYMBOL(adm_param_enable); /** * adm_param_enable_v2 - @@ -3751,7 +3752,7 @@ int adm_param_enable_v2(int port_id, int copp_idx, return rc; } -EXPORT_SYMBOL(adm_param_enable); +EXPORT_SYMBOL(adm_param_enable_v2); /** * adm_send_calibration - -- GitLab From 24afb6e39004956013dd47d851800e270add1834 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 6 Feb 2018 15:22:37 -0800 Subject: [PATCH 0234/1645] asoc: codecs: add null pointer check for swr control data Null check is needed before accessing swr control data to ensure proper error handling in case speaker path is issued when swr is not enabled. Change-Id: I5037a912652189b3ae58f1119d0534777a9c264a Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd934x/wcd934x.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 21c7f12e7087..54d07513f697 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -2957,6 +2957,11 @@ static int __tavil_codec_enable_swr(struct snd_soc_dapm_widget *w, int event) tavil = snd_soc_codec_get_drvdata(codec); + if (!tavil->swr.ctrl_data) + return -EINVAL; + if (!tavil->swr.ctrl_data[0].swr_pdev) + return -EINVAL; + switch (event) { case SND_SOC_DAPM_PRE_PMU: if (((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) || -- GitLab From 6bcd94a7ce44f79ac37588d9962c820d492a971e Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 14 Feb 2018 16:54:06 -0800 Subject: [PATCH 0235/1645] asoc: wcd-mbhc: disable button current source after removal After headset removal disable button current source to not have any voltages output in micbias after headset removal from extension cable. Change-Id: I2a751c16c704176381bb26f375aebf351686e911 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd-mbhc-adc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index 920796f2e39d..893df9a5e036 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -996,6 +996,7 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, 0); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 0); wcd_mbhc_elec_hs_report_unplug(mbhc); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0); if (hphpa_on) { hphpa_on = false; -- GitLab From 770b8383d20454e1d33693c65b427da50276f8b3 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Wed, 27 Sep 2017 12:17:36 -0700 Subject: [PATCH 0236/1645] dsp: Mark cal block after use After applying calibration on DSP, cal block is marked stale to ensure same calibration is not reused for future usecase. Change-Id: I9f446c0602f4ab34ca71b9d2611319624fb19cd2 Signed-off-by: Vikram Panduranga --- asoc/msm-pcm-routing-v2.c | 27 +++++++-- dsp/audio_cal_utils.c | 31 ++++++++++ dsp/q6adm.c | 18 ++++-- dsp/q6afe.c | 33 ++++++++--- dsp/q6asm.c | 103 ++++++++++++++++++---------------- include/dsp/audio_cal_utils.h | 5 ++ include/dsp/q6asm-v2.h | 5 ++ 7 files changed, 156 insertions(+), 66 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index c2ce0684f72c..0096688f5080 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -903,6 +903,9 @@ static struct cal_block_data *msm_routing_find_topology_by_path(int path, cal_block = list_entry(ptr, struct cal_block_data, list); + if (cal_utils_is_cal_stale(cal_block)) + continue; + if (((struct audio_cal_info_adm_top *)cal_block ->cal_info)->path == path) { return cal_block; @@ -929,6 +932,9 @@ static struct cal_block_data *msm_routing_find_topology(int path, cal_block = list_entry(ptr, struct cal_block_data, list); + if (cal_utils_is_cal_stale(cal_block)) + continue; + cal_info = (struct audio_cal_info_adm_top *) cal_block->cal_info; if ((cal_info->path == path) && @@ -939,9 +945,14 @@ static struct cal_block_data *msm_routing_find_topology(int path, } pr_debug("%s: Can't find topology for path %d, app %d, acdb_id %d defaulting to search by path\n", __func__, path, app_type, acdb_id); - return msm_routing_find_topology_by_path(cal_index, path); + return msm_routing_find_topology_by_path(path, cal_index); } +/* + * Retrieving cal_block will mark cal_block as stale. + * Hence it cannot be reused or resent unless the flag + * is reset. + */ static int msm_routing_get_adm_topology(int fedai_id, int session_type, int be_id) { @@ -963,20 +974,24 @@ static int msm_routing_get_adm_topology(int fedai_id, int session_type, cal_block = msm_routing_find_topology(session_type, app_type, acdb_dev_id, ADM_TOPOLOGY_CAL_TYPE_IDX); - if (cal_block != NULL) + if (cal_block != NULL) { topology = ((struct audio_cal_info_adm_top *) cal_block->cal_info)->topology; - mutex_unlock(&cal_data[ADM_TOPOLOGY_CAL_TYPE_IDX]->lock); + cal_utils_mark_cal_used(cal_block); + mutex_unlock(&cal_data[ADM_TOPOLOGY_CAL_TYPE_IDX]->lock); + } else { + mutex_unlock(&cal_data[ADM_TOPOLOGY_CAL_TYPE_IDX]->lock); - if (cal_block == NULL) { pr_debug("%s: Check for LSM topology\n", __func__); mutex_lock(&cal_data[ADM_LSM_TOPOLOGY_CAL_TYPE_IDX]->lock); cal_block = msm_routing_find_topology(session_type, app_type, acdb_dev_id, ADM_LSM_TOPOLOGY_CAL_TYPE_IDX); - if (cal_block != NULL) + if (cal_block != NULL) { topology = ((struct audio_cal_info_adm_top *) cal_block->cal_info)->topology; + cal_utils_mark_cal_used(cal_block); + } mutex_unlock(&cal_data[ADM_LSM_TOPOLOGY_CAL_TYPE_IDX]->lock); } @@ -1434,7 +1449,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { pr_err("%s: adm open failed copp_idx:%d\n", - __func__, copp_idx); + __func__, copp_idx); mutex_unlock(&routing_lock); return -EINVAL; } diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index 95794796c4f1..77cb1c5b6e1e 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -1033,9 +1033,40 @@ int cal_utils_set_cal(size_t data_size, void *data, ((uint8_t *)data + sizeof(struct audio_cal_type_basic)), data_size - sizeof(struct audio_cal_type_basic)); + /* reset buffer stale flag */ + cal_block->cal_stale = false; + err: mutex_unlock(&cal_type->lock); done: return ret; } EXPORT_SYMBOL(cal_utils_set_cal); + +/** + * cal_utils_mark_cal_used + * + * @cal_block: pointer to cal block + */ +void cal_utils_mark_cal_used(struct cal_block_data *cal_block) +{ + if (cal_block) + cal_block->cal_stale = true; +} +EXPORT_SYMBOL(cal_utils_mark_cal_used); + +/** + * cal_utils_is_cal_stale + * + * @cal_block: pointer to cal block + * + * Returns true if cal block is stale, false otherwise + */ +bool cal_utils_is_cal_stale(struct cal_block_data *cal_block) +{ + if ((cal_block) && (cal_block->cal_stale)) + return true; + + return false; +} +EXPORT_SYMBOL(cal_utils_is_cal_stale); diff --git a/dsp/q6adm.c b/dsp/q6adm.c index f0b7121977fb..0346013ef5e9 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -1856,7 +1856,7 @@ static void send_adm_custom_topology(void) this_adm.set_custom_topology = 0; cal_block = cal_utils_get_only_cal_block(this_adm.cal_data[cal_index]); - if (cal_block == NULL) + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) goto unlock; pr_debug("%s: Sending cal_index %d\n", __func__, cal_index); @@ -1996,8 +1996,11 @@ static struct cal_block_data *adm_find_cal_by_path(int cal_index, int path) cal_block = list_entry(ptr, struct cal_block_data, list); + if (cal_utils_is_cal_stale(cal_block)) + continue; + if (cal_index == ADM_AUDPROC_CAL || - cal_index == ADM_LSM_AUDPROC_CAL) { + cal_index == ADM_LSM_AUDPROC_CAL) { audproc_cal_info = cal_block->cal_info; if ((audproc_cal_info->path == path) && (cal_block->cal_data.size > 0)) @@ -2030,8 +2033,11 @@ static struct cal_block_data *adm_find_cal_by_app_type(int cal_index, int path, cal_block = list_entry(ptr, struct cal_block_data, list); + if (cal_utils_is_cal_stale(cal_block)) + continue; + if (cal_index == ADM_AUDPROC_CAL || - cal_index == ADM_LSM_AUDPROC_CAL) { + cal_index == ADM_LSM_AUDPROC_CAL) { audproc_cal_info = cal_block->cal_info; if ((audproc_cal_info->path == path) && (audproc_cal_info->app_type == app_type) && @@ -2067,6 +2073,8 @@ static struct cal_block_data *adm_find_cal(int cal_index, int path, cal_block = list_entry(ptr, struct cal_block_data, list); + if (cal_utils_is_cal_stale(cal_block)) + continue; if (cal_index == ADM_AUDPROC_CAL || cal_index == ADM_LSM_AUDPROC_CAL) { @@ -2135,6 +2143,8 @@ static void send_adm_cal_type(int cal_index, int path, int port_id, ret = adm_remap_and_send_cal_block(cal_index, port_id, copp_idx, cal_block, perf_mode, app_type, acdb_id, sample_rate); + + cal_utils_mark_cal_used(cal_block); unlock: mutex_unlock(&this_adm.cal_data[cal_index]->lock); done: @@ -3111,7 +3121,7 @@ int send_rtac_audvol_cal(void) cal_block = cal_utils_get_only_cal_block( this_adm.cal_data[ADM_RTAC_AUDVOL_CAL]); - if (cal_block == NULL) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { pr_err("%s: can't find cal block!\n", __func__); goto unlock; } diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 0ecd3aaa16a1..781a4361f9d1 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1344,7 +1344,7 @@ static void afe_send_custom_topology(void) goto unlock; this_afe.set_custom_topology = 0; cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); - if (cal_block == NULL) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { pr_err("%s cal_block not found!!\n", __func__); goto unlock; } @@ -1709,7 +1709,9 @@ static struct cal_block_data *afe_find_cal_topo_id_by_port( &cal_type->cal_blocks) { cal_block = list_entry(ptr, struct cal_block_data, list); - + /* Skip cal_block if it is already marked stale */ + if (cal_utils_is_cal_stale(cal_block)) + continue; path = ((afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX)?(TX_DEVICE):(RX_DEVICE)); afe_top = @@ -1737,6 +1739,11 @@ static struct cal_block_data *afe_find_cal_topo_id_by_port( return NULL; } +/* + * Retrieving cal_block will mark cal_block as stale. + * Hence it cannot be reused or resent unless the flag + * is reset. + */ static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id, int cal_type_index) { @@ -1746,7 +1753,8 @@ static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id, struct audio_cal_info_afe_top *afe_top_info = NULL; if (this_afe.cal_data[cal_type_index] == NULL) { - pr_err("%s: [AFE_TOPOLOGY_CAL] not initialized\n", __func__); + pr_err("%s: cal_type %d not initialized\n", __func__, + cal_type_index); return -EINVAL; } if (topology_id == NULL) { @@ -1759,8 +1767,8 @@ static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id, cal_block = afe_find_cal_topo_id_by_port( this_afe.cal_data[cal_type_index], port_id); if (cal_block == NULL) { - pr_err("%s: [AFE_TOPOLOGY_CAL] not initialized for this port %d\n", - __func__, port_id); + pr_err("%s: cal_type %d not initialized for this port %d\n", + __func__, cal_type_index, port_id); ret = -EINVAL; goto unlock; } @@ -1774,6 +1782,7 @@ static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id, goto unlock; } *topology_id = (u32)afe_top_info->topology; + cal_utils_mark_cal_used(cal_block); pr_debug("%s: port_id = %u acdb_id = %d topology_id = %u ret=%d\n", __func__, port_id, afe_top_info->acdb_id, @@ -1940,7 +1949,7 @@ static int send_afe_cal_type(int cal_index, int port_id) cal_block = cal_utils_get_only_cal_block( this_afe.cal_data[cal_index]); - if (cal_block == NULL) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { pr_err("%s cal_block not found!!\n", __func__); ret = -EINVAL; goto unlock; @@ -1959,6 +1968,9 @@ static int send_afe_cal_type(int cal_index, int port_id) if (ret < 0) pr_debug("%s: No cal sent for cal_index %d, port_id = 0x%x! ret %d\n", __func__, cal_index, port_id, ret); + + cal_utils_mark_cal_used(cal_block); + unlock: mutex_unlock(&this_afe.cal_data[cal_index]->lock); done: @@ -5272,7 +5284,7 @@ static int afe_sidetone_iir(u16 tx_port_id) } mutex_lock(&this_afe.cal_data[cal_index]->lock); cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); - if (cal_block == NULL) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { pr_err("%s: cal_block not found\n ", __func__); mutex_unlock(&this_afe.cal_data[cal_index]->lock); ret = -EINVAL; @@ -5399,7 +5411,7 @@ static int afe_sidetone(u16 tx_port_id, u16 rx_port_id, bool enable) mutex_lock(&this_afe.cal_data[cal_index]->lock); cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); - if (cal_block == NULL) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { pr_err("%s: cal_block not found\n", __func__); mutex_unlock(&this_afe.cal_data[cal_index]->lock); ret = -EINVAL; @@ -6533,6 +6545,9 @@ static struct cal_block_data *afe_find_hw_delay_by_path( cal_block = list_entry(ptr, struct cal_block_data, list); + if (cal_utils_is_cal_stale(cal_block)) + continue; + if (((struct audio_cal_info_hw_delay *)cal_block->cal_info) ->path == path) { return cal_block; @@ -6596,6 +6611,8 @@ static int afe_get_cal_hw_delay(int32_t path, ret = -EFAULT; goto unlock; } + + cal_utils_mark_cal_used(cal_block); pr_debug("%s: Path = %d samplerate = %u usec = %u status %d\n", __func__, path, entry->sample_rate, entry->delay_usec, ret); unlock: diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 208c7e267827..5bfed89dcc61 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -125,8 +125,7 @@ static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, void *q6asm_mmap_apr_reg(void); static int q6asm_is_valid_session(struct apr_client_data *data, void *priv); -static int q6asm_get_asm_topology_cal(void); -static int q6asm_get_asm_app_type_cal(void); +static int q6asm_get_asm_topology_apptype(struct q6asm_cal_info *cal_info); /* for ASM custom topology */ static struct cal_type_data *cal_data[ASM_MAX_CAL_TYPES]; @@ -759,7 +758,7 @@ int send_asm_custom_topology(struct audio_client *ac) set_custom_topology = 0; cal_block = cal_utils_get_only_cal_block(cal_data[ASM_CUSTOM_TOP_CAL]); - if (cal_block == NULL) + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) goto unlock; if (cal_block->cal_data.size == 0) { @@ -2800,6 +2799,7 @@ static int __q6asm_open_read(struct audio_client *ac, { int rc = 0x00; struct asm_stream_cmd_open_read_v3 open; + struct q6asm_cal_info cal_info; config_debug_fs_reset_index(); @@ -2819,12 +2819,15 @@ static int __q6asm_open_read(struct audio_client *ac, /* Stream prio : High, provide meta info with encoded frames */ open.src_endpointype = ASM_END_POINT_DEVICE_MATRIX; - open.preprocopo_id = q6asm_get_asm_topology_cal(); + rc = q6asm_get_asm_topology_apptype(&cal_info); + open.preprocopo_id = cal_info.topology_id; + + open.bits_per_sample = bits_per_sample; open.mode_flags = 0x0; ac->topology = open.preprocopo_id; - ac->app_type = q6asm_get_asm_app_type_cal(); + ac->app_type = cal_info.app_type; if (ac->perf_mode == LOW_LATENCY_PCM_MODE) { open.mode_flags |= ASM_LOW_LATENCY_TX_STREAM_SESSION << ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ; @@ -3086,6 +3089,7 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format, { int rc = 0x00; struct asm_stream_cmd_open_write_v3 open; + struct q6asm_cal_info cal_info; if (ac == NULL) { pr_err("%s: APR handle NULL\n", __func__); @@ -3134,7 +3138,9 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format, open.sink_endpointype = ASM_END_POINT_DEVICE_MATRIX; open.bits_per_sample = bits_per_sample; - open.postprocopo_id = q6asm_get_asm_topology_cal(); + rc = q6asm_get_asm_topology_apptype(&cal_info); + open.postprocopo_id = cal_info.topology_id; + if (ac->perf_mode != LEGACY_PCM_MODE) open.postprocopo_id = ASM_STREAM_POSTPROCOPO_ID_NONE; @@ -3147,7 +3153,7 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format, */ if (!ac->topology) { ac->topology = open.postprocopo_id; - ac->app_type = q6asm_get_asm_app_type_cal(); + ac->app_type = cal_info.app_type; } switch (format) { case FORMAT_LINEAR_PCM: @@ -3334,6 +3340,7 @@ static int __q6asm_open_read_write(struct audio_client *ac, uint32_t rd_format, { int rc = 0x00; struct asm_stream_cmd_open_readwrite_v2 open; + struct q6asm_cal_info cal_info; if (ac == NULL) { pr_err("%s: APR handle NULL\n", __func__); @@ -3355,12 +3362,13 @@ static int __q6asm_open_read_write(struct audio_client *ac, uint32_t rd_format, open.mode_flags = is_meta_data_mode ? BUFFER_META_ENABLE : 0; open.bits_per_sample = bits_per_sample; /* source endpoint : matrix */ - open.postprocopo_id = q6asm_get_asm_topology_cal(); + rc = q6asm_get_asm_topology_apptype(&cal_info); + open.postprocopo_id = cal_info.topology_id; open.postprocopo_id = overwrite_topology ? topology : open.postprocopo_id; ac->topology = open.postprocopo_id; - ac->app_type = q6asm_get_asm_app_type_cal(); + ac->app_type = cal_info.app_type; switch (wr_format) { @@ -3553,6 +3561,7 @@ EXPORT_SYMBOL(q6asm_open_read_write_v2); int q6asm_open_loopback_v2(struct audio_client *ac, uint16_t bits_per_sample) { int rc = 0x00; + struct q6asm_cal_info cal_info; if (ac == NULL) { pr_err("%s: APR handle NULL\n", __func__); @@ -3577,9 +3586,10 @@ int q6asm_open_loopback_v2(struct audio_client *ac, uint16_t bits_per_sample) open.src_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2; open.sink_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2; /* source endpoint : matrix */ - open.audproc_topo_id = q6asm_get_asm_topology_cal(); + rc = q6asm_get_asm_topology_apptype(&cal_info); + open.audproc_topo_id = cal_info.topology_id; - ac->app_type = q6asm_get_asm_app_type_cal(); + ac->app_type = cal_info.app_type; if (ac->perf_mode == LOW_LATENCY_PCM_MODE) open.mode_flags |= ASM_LOW_LATENCY_STREAM_SESSION; else @@ -3608,9 +3618,10 @@ int q6asm_open_loopback_v2(struct audio_client *ac, uint16_t bits_per_sample) open.src_endpointype = 0; open.sink_endpointype = 0; /* source endpoint : matrix */ - open.postprocopo_id = q6asm_get_asm_topology_cal(); + rc = q6asm_get_asm_topology_apptype(&cal_info); + open.postprocopo_id = cal_info.topology_id; - ac->app_type = q6asm_get_asm_app_type_cal(); + ac->app_type = cal_info.app_type; ac->topology = open.postprocopo_id; open.bits_per_sample = bits_per_sample; open.reserved = 0; @@ -3665,6 +3676,7 @@ int q6asm_open_transcode_loopback(struct audio_client *ac, { int rc = 0x00; struct asm_stream_cmd_open_transcode_loopback_t open; + struct q6asm_cal_info cal_info; if (ac == NULL) { pr_err("%s: APR handle NULL\n", __func__); @@ -3712,9 +3724,11 @@ int q6asm_open_transcode_loopback(struct audio_client *ac, } /* source endpoint : matrix */ - open.audproc_topo_id = q6asm_get_asm_topology_cal(); + rc = q6asm_get_asm_topology_apptype(&cal_info); + open.audproc_topo_id = cal_info.topology_id; + - ac->app_type = q6asm_get_asm_app_type_cal(); + ac->app_type = cal_info.app_type; if (ac->perf_mode == LOW_LATENCY_PCM_MODE) open.mode_flags |= ASM_LOW_LATENCY_STREAM_SESSION; else @@ -3884,6 +3898,7 @@ int q6asm_open_shared_io(struct audio_client *ac, struct asm_stream_cmd_open_shared_io *open; u8 *channel_mapping; int i, size_of_open, num_watermarks, bufsz, bufcnt, rc, flags = 0; + struct q6asm_cal_info cal_info; if (!ac || !config) return -EINVAL; @@ -3950,7 +3965,8 @@ int q6asm_open_shared_io(struct audio_client *ac, open->endpoint_type = ASM_END_POINT_DEVICE_MATRIX; open->topo_bits_per_sample = config->bits_per_sample; - open->topo_id = q6asm_get_asm_topology_cal(); + rc = q6asm_get_asm_topology_apptype(&cal_info); + open->topo_id = cal_info.topology_id; if (config->format == FORMAT_LINEAR_PCM) open->fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3; @@ -9766,51 +9782,39 @@ int q6asm_get_asm_app_type(int session_id) return app_type; } -static int q6asm_get_asm_topology_cal(void) +/* + * Retrieving cal_block will mark cal_block as stale. + * Hence it cannot be reused or resent unless the flag + * is reset. + */ +static int q6asm_get_asm_topology_apptype(struct q6asm_cal_info *cal_info) { - int topology = DEFAULT_POPP_TOPOLOGY; struct cal_block_data *cal_block = NULL; - if (cal_data[ASM_TOPOLOGY_CAL] == NULL) - goto done; - - mutex_lock(&cal_data[ASM_TOPOLOGY_CAL]->lock); - cal_block = cal_utils_get_only_cal_block(cal_data[ASM_TOPOLOGY_CAL]); - if (cal_block == NULL) - goto unlock; - - topology = ((struct audio_cal_info_asm_top *) - cal_block->cal_info)->topology; -unlock: - mutex_unlock(&cal_data[ASM_TOPOLOGY_CAL]->lock); -done: - pr_debug("%s: Using topology %d\n", __func__, topology); - return topology; -} - -static int q6asm_get_asm_app_type_cal(void) -{ - int app_type = DEFAULT_APP_TYPE; - struct cal_block_data *cal_block = NULL; + cal_info->topology_id = DEFAULT_POPP_TOPOLOGY; + cal_info->app_type = DEFAULT_APP_TYPE; if (cal_data[ASM_TOPOLOGY_CAL] == NULL) goto done; mutex_lock(&cal_data[ASM_TOPOLOGY_CAL]->lock); cal_block = cal_utils_get_only_cal_block(cal_data[ASM_TOPOLOGY_CAL]); - if (cal_block == NULL) + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) goto unlock; - - app_type = ((struct audio_cal_info_asm_top *) + cal_info->topology_id = ((struct audio_cal_info_asm_top *) + cal_block->cal_info)->topology; + cal_info->app_type = ((struct audio_cal_info_asm_top *) cal_block->cal_info)->app_type; - if (app_type == 0) - app_type = DEFAULT_APP_TYPE; + cal_utils_mark_cal_used(cal_block); + unlock: mutex_unlock(&cal_data[ASM_TOPOLOGY_CAL]->lock); done: - pr_debug("%s: Using app_type %d\n", __func__, app_type); - return app_type; + pr_debug("%s: Using topology %d app_type %d\n", __func__, + cal_info->topology_id, cal_info->app_type); + + return 0; } /** @@ -9849,8 +9853,9 @@ int q6asm_send_cal(struct audio_client *ac) memset(&mem_hdr, 0, sizeof(mem_hdr)); mutex_lock(&cal_data[ASM_AUDSTRM_CAL]->lock); cal_block = cal_utils_get_only_cal_block(cal_data[ASM_AUDSTRM_CAL]); - if (cal_block == NULL) { - pr_err("%s: cal_block is NULL\n", + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { + rc = 0; /* not error case */ + pr_err("%s: cal_block is NULL or stale\n", __func__); goto unlock; } @@ -9887,6 +9892,8 @@ int q6asm_send_cal(struct audio_client *ac) goto unlock; } + if (cal_block) + cal_utils_mark_cal_used(cal_block); rc = 0; unlock: diff --git a/include/dsp/audio_cal_utils.h b/include/dsp/audio_cal_utils.h index a4aa4e45d200..614ef236644d 100644 --- a/include/dsp/audio_cal_utils.h +++ b/include/dsp/audio_cal_utils.h @@ -37,6 +37,7 @@ struct cal_block_data { void *cal_info; struct list_head list; struct cal_data cal_data; + bool cal_stale; struct mem_map_data map_data; int32_t buffer_number; }; @@ -98,4 +99,8 @@ size_t get_user_cal_type_size(int32_t cal_type); /* Version of the cal type*/ int32_t cal_utils_get_cal_type_version(void *cal_type_data); + +void cal_utils_mark_cal_used(struct cal_block_data *cal_block); + +bool cal_utils_is_cal_stale(struct cal_block_data *cal_block); #endif diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index c92cacf6c892..ba35779a5788 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -245,6 +245,11 @@ struct audio_client { struct shared_io_config config; }; +struct q6asm_cal_info { + int topology_id; + int app_type; +}; + void q6asm_audio_client_free(struct audio_client *ac); struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv); -- GitLab From 293afe4ad4ba1552ead4916f2fef55b2e187eb59 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Fri, 16 Mar 2018 23:29:29 -0700 Subject: [PATCH 0237/1645] dsp: msm_audio_ion: update logic to pass pointer by reference Update logic for pointer meant to hold virtual address of ION buffers allocated, so that the pointer is available across function boundary. Change-Id: I7849498b9ccf0cbd7c357fa926eea6c4b65a194f Signed-off-by: Banajit Goswami --- dsp/msm_audio_ion.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index 61732b261c73..63a386beb7c2 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -285,7 +285,7 @@ static void msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf) } static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr, - size_t *plen, void *vaddr) + size_t *plen, void **vaddr) { int rc = 0; @@ -296,8 +296,8 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr, goto err; } - vaddr = msm_audio_ion_map_kernel(dma_buf); - if (IS_ERR_OR_NULL((void *)vaddr)) { + *vaddr = msm_audio_ion_map_kernel(dma_buf); + if (IS_ERR_OR_NULL(*vaddr)) { pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); rc = -ENOMEM; goto err; @@ -344,7 +344,7 @@ int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, goto err; } - rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, *vaddr); + rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr); if (rc) { pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc); goto err_dma_buf; @@ -352,7 +352,7 @@ int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, *vaddr, bufsz); - memset((void *)*vaddr, 0, bufsz); + memset(*vaddr, 0, bufsz); return rc; @@ -411,7 +411,7 @@ int msm_audio_ion_import(struct dma_buf **dma_buf, int fd, } } - rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, *vaddr); + rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr); if (rc) { pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc); goto err_ion_flag; -- GitLab From b41e711b68783ae8c9eb11dbf514e976ac19d6e6 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Mon, 19 Mar 2018 18:17:54 -0700 Subject: [PATCH 0238/1645] asoc: codecs: update wcd9360 interrupt table size WCD9360 interrupt table size is invalid. Update it to correct size. Change-Id: Ie2ec848d8a75b6889957954c9444d261a70f4c4e Signed-off-by: Vidyakumar Athota --- asoc/codecs/wcd9xxx-rst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/wcd9xxx-rst.c b/asoc/codecs/wcd9xxx-rst.c index b369556a1a6d..563dd78508f1 100644 --- a/asoc/codecs/wcd9xxx-rst.c +++ b/asoc/codecs/wcd9xxx-rst.c @@ -518,7 +518,7 @@ static int wcd9360_get_cdc_info(struct wcd9xxx *wcd9xxx, wcd_type->slim_slave_type = WCD9XXX_SLIM_SLAVE_ADDR_TYPE_1; wcd_type->i2c_chip_status = 0x01; wcd_type->intr_tbl = wcd9360_intr_table; - wcd_type->intr_tbl_size = ARRAY_SIZE(wcd934x_intr_table); + wcd_type->intr_tbl_size = ARRAY_SIZE(wcd9360_intr_table); wcd_type->intr_reg[WCD9XXX_INTR_STATUS_BASE] = WCD9360_INTR_PIN1_STATUS0; -- GitLab From 09cd2ac5e9167ff81edf05e381a9a58748dfda2a Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Mon, 12 Feb 2018 19:03:02 +0800 Subject: [PATCH 0239/1645] asoc: codecs: set boost state to MAX_STATE_2 for WSA8815 WSA8815 requires default boost state of MAX_STATE_2, when speaker protection feature is disabled. Set boost state to MAX_STATE_2 in all cases for WSA8815. Change-Id: Ic700d9a206e94a4cdd1d99f8547bed9df1e759e8 Signed-off-by: Xiaojun Sang --- asoc/codecs/msm_sdw/msm_sdw_cdc.c | 10 +++++----- asoc/codecs/msm_sdw/msm_sdw_regmap.c | 6 +++--- asoc/codecs/wcd9335-regmap.c | 6 +++--- asoc/codecs/wcd9335.c | 10 +++++----- asoc/codecs/wcd934x/wcd934x-regmap.c | 6 +++--- asoc/codecs/wcd934x/wcd934x.c | 10 +++++----- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/asoc/codecs/msm_sdw/msm_sdw_cdc.c b/asoc/codecs/msm_sdw/msm_sdw_cdc.c index 7a5ba8f0c7c4..95250e415097 100644 --- a/asoc/codecs/msm_sdw/msm_sdw_cdc.c +++ b/asoc/codecs/msm_sdw/msm_sdw_cdc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -82,8 +82,8 @@ static const struct msm_sdw_reg_mask_val msm_sdw_spkr_default[] = { {MSM_SDW_COMPANDER8_CTL3, 0x80, 0x80}, {MSM_SDW_COMPANDER7_CTL7, 0x01, 0x01}, {MSM_SDW_COMPANDER8_CTL7, 0x01, 0x01}, - {MSM_SDW_BOOST0_BOOST_CTL, 0x7C, 0x50}, - {MSM_SDW_BOOST1_BOOST_CTL, 0x7C, 0x50}, + {MSM_SDW_BOOST0_BOOST_CTL, 0x7C, 0x58}, + {MSM_SDW_BOOST1_BOOST_CTL, 0x7C, 0x58}, }; static const struct msm_sdw_reg_mask_val msm_sdw_spkr_mode1[] = { @@ -1699,8 +1699,8 @@ static const struct msm_sdw_reg_mask_val msm_sdw_reg_init[] = { {MSM_SDW_BOOST1_BOOST_CFG1, 0x3F, 0x12}, {MSM_SDW_BOOST1_BOOST_CFG2, 0x1C, 0x08}, {MSM_SDW_COMPANDER8_CTL7, 0x1E, 0x18}, - {MSM_SDW_BOOST0_BOOST_CTL, 0x70, 0x50}, - {MSM_SDW_BOOST1_BOOST_CTL, 0x70, 0x50}, + {MSM_SDW_BOOST0_BOOST_CTL, 0x70, 0x58}, + {MSM_SDW_BOOST1_BOOST_CTL, 0x70, 0x58}, {MSM_SDW_RX7_RX_PATH_CFG1, 0x08, 0x08}, {MSM_SDW_RX8_RX_PATH_CFG1, 0x08, 0x08}, {MSM_SDW_TOP_TOP_CFG1, 0x02, 0x02}, diff --git a/asoc/codecs/msm_sdw/msm_sdw_regmap.c b/asoc/codecs/msm_sdw/msm_sdw_regmap.c index 22663384ec35..412e92f5c7be 100644 --- a/asoc/codecs/msm_sdw/msm_sdw_regmap.c +++ b/asoc/codecs/msm_sdw/msm_sdw_regmap.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -65,11 +65,11 @@ static const struct reg_default msm_sdw_defaults[] = { { MSM_SDW_RX8_RX_PATH_MIX_SEC1, 0x00 }, /* Page #12 registers */ { MSM_SDW_BOOST0_BOOST_PATH_CTL, 0x00 }, - { MSM_SDW_BOOST0_BOOST_CTL, 0xb2 }, + { MSM_SDW_BOOST0_BOOST_CTL, 0xba }, { MSM_SDW_BOOST0_BOOST_CFG1, 0x00 }, { MSM_SDW_BOOST0_BOOST_CFG2, 0x00 }, { MSM_SDW_BOOST1_BOOST_PATH_CTL, 0x00 }, - { MSM_SDW_BOOST1_BOOST_CTL, 0xb2 }, + { MSM_SDW_BOOST1_BOOST_CTL, 0xba }, { MSM_SDW_BOOST1_BOOST_CFG1, 0x00 }, { MSM_SDW_BOOST1_BOOST_CFG2, 0x00 }, { MSM_SDW_AHB_BRIDGE_WR_DATA_0, 0x00 }, diff --git a/asoc/codecs/wcd9335-regmap.c b/asoc/codecs/wcd9335-regmap.c index ffb79b79da1b..c5ab181be3f5 100644 --- a/asoc/codecs/wcd9335-regmap.c +++ b/asoc/codecs/wcd9335-regmap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1213,11 +1213,11 @@ static const struct reg_default wcd9335_defaults[] = { { WCD9335_CDC_CLSH_TEST1, 0x00 }, { WCD9335_CDC_CLSH_OVR_VREF, 0x00 }, { WCD9335_CDC_BOOST0_BOOST_PATH_CTL, 0x00 }, - { WCD9335_CDC_BOOST0_BOOST_CTL, 0xb2 }, + { WCD9335_CDC_BOOST0_BOOST_CTL, 0xba }, { WCD9335_CDC_BOOST0_BOOST_CFG1, 0x00 }, { WCD9335_CDC_BOOST0_BOOST_CFG2, 0x00 }, { WCD9335_CDC_BOOST1_BOOST_PATH_CTL, 0x00 }, - { WCD9335_CDC_BOOST1_BOOST_CTL, 0xb2 }, + { WCD9335_CDC_BOOST1_BOOST_CTL, 0xba }, { WCD9335_CDC_BOOST1_BOOST_CFG1, 0x00 }, { WCD9335_CDC_BOOST1_BOOST_CFG2, 0x00 }, { WCD9335_SWR_AHB_BRIDGE_WR_DATA_0, 0x00 }, diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 7bc2272164a7..2f0c29ef4f79 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -845,8 +845,8 @@ static const struct tasha_reg_mask_val tasha_spkr_default[] = { {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80}, {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01}, {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01}, - {WCD9335_CDC_BOOST0_BOOST_CTL, 0x7C, 0x50}, - {WCD9335_CDC_BOOST1_BOOST_CTL, 0x7C, 0x50}, + {WCD9335_CDC_BOOST0_BOOST_CTL, 0x7C, 0x58}, + {WCD9335_CDC_BOOST1_BOOST_CTL, 0x7C, 0x58}, }; static const struct tasha_reg_mask_val tasha_spkr_mode1[] = { @@ -12405,8 +12405,8 @@ static const struct tasha_reg_mask_val tasha_codec_reg_init_common_val[] = { {WCD9335_CDC_CLSH_K2_MSB, 0x0F, 0x00}, {WCD9335_CDC_CLSH_K2_LSB, 0xFF, 0x60}, {WCD9335_CPE_SS_DMIC_CFG, 0x80, 0x00}, - {WCD9335_CDC_BOOST0_BOOST_CTL, 0x70, 0x50}, - {WCD9335_CDC_BOOST1_BOOST_CTL, 0x70, 0x50}, + {WCD9335_CDC_BOOST0_BOOST_CTL, 0x70, 0x58}, + {WCD9335_CDC_BOOST1_BOOST_CTL, 0x70, 0x58}, {WCD9335_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08}, {WCD9335_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08}, {WCD9335_ANA_LO_1_2, 0x3C, 0X3C}, diff --git a/asoc/codecs/wcd934x/wcd934x-regmap.c b/asoc/codecs/wcd934x/wcd934x-regmap.c index ff18bd80a971..c726c623e547 100644 --- a/asoc/codecs/wcd934x/wcd934x-regmap.c +++ b/asoc/codecs/wcd934x/wcd934x-regmap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1248,11 +1248,11 @@ static const struct reg_default wcd934x_defaults[] = { { WCD934X_CDC_CLSH_TEST1, 0x00 }, { WCD934X_CDC_CLSH_OVR_VREF, 0x00 }, { WCD934X_CDC_BOOST0_BOOST_PATH_CTL, 0x00 }, - { WCD934X_CDC_BOOST0_BOOST_CTL, 0xb2 }, + { WCD934X_CDC_BOOST0_BOOST_CTL, 0xba }, { WCD934X_CDC_BOOST0_BOOST_CFG1, 0x00 }, { WCD934X_CDC_BOOST0_BOOST_CFG2, 0x00 }, { WCD934X_CDC_BOOST1_BOOST_PATH_CTL, 0x00 }, - { WCD934X_CDC_BOOST1_BOOST_CTL, 0xb2 }, + { WCD934X_CDC_BOOST1_BOOST_CTL, 0xba }, { WCD934X_CDC_BOOST1_BOOST_CFG1, 0x00 }, { WCD934X_CDC_BOOST1_BOOST_CFG2, 0x00 }, { WCD934X_CDC_VBAT_VBAT_PATH_CTL, 0x00 }, diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index e7cec2b4d348..b68cc9af5854 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -642,8 +642,8 @@ static const struct tavil_reg_mask_val tavil_spkr_default[] = { {WCD934X_CDC_COMPANDER8_CTL3, 0x80, 0x80}, {WCD934X_CDC_COMPANDER7_CTL7, 0x01, 0x01}, {WCD934X_CDC_COMPANDER8_CTL7, 0x01, 0x01}, - {WCD934X_CDC_BOOST0_BOOST_CTL, 0x7C, 0x50}, - {WCD934X_CDC_BOOST1_BOOST_CTL, 0x7C, 0x50}, + {WCD934X_CDC_BOOST0_BOOST_CTL, 0x7C, 0x58}, + {WCD934X_CDC_BOOST1_BOOST_CTL, 0x7C, 0x58}, }; static const struct tavil_reg_mask_val tavil_spkr_mode1[] = { @@ -8700,8 +8700,8 @@ static const struct tavil_reg_mask_val tavil_codec_reg_init_common_val[] = { {WCD934X_CDC_CLSH_K2_MSB, 0x0F, 0x00}, {WCD934X_CDC_CLSH_K2_LSB, 0xFF, 0x60}, {WCD934X_CPE_SS_DMIC_CFG, 0x80, 0x00}, - {WCD934X_CDC_BOOST0_BOOST_CTL, 0x70, 0x50}, - {WCD934X_CDC_BOOST1_BOOST_CTL, 0x70, 0x50}, + {WCD934X_CDC_BOOST0_BOOST_CTL, 0x70, 0x58}, + {WCD934X_CDC_BOOST1_BOOST_CTL, 0x70, 0x58}, {WCD934X_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08}, {WCD934X_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08}, {WCD934X_CDC_TOP_TOP_CFG1, 0x02, 0x02}, -- GitLab From e60843d16c355338dc28779be05c60c3e6d4297c Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 21 Mar 2018 13:50:17 +0800 Subject: [PATCH 0240/1645] dsp: correct comparison condition for VSS_ICOMMON_RSP_GET_PARAM_V3 VSS_ICOMMON_RSP_GET_PARAM_V3 should be compared with opcode. Otherwise the if condition would always be true. Correct the comparison for VSS_ICOMMON_RSP_GET_PARAM_V3. Change-Id: I204c8c71e06b13332fd5b418a40b10618e19a901 Signed-off-by: Meng Wang --- dsp/q6voice.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 88b174158e03..91549f99a5ce 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -7591,7 +7591,7 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv) } else if (data->opcode == VSS_ISTREAM_EVT_READY) { pr_debug("Recd VSS_ISTREAM_EVT_READY\n"); } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM || - VSS_ICOMMON_RSP_GET_PARAM_V3) { + data->opcode == VSS_ICOMMON_RSP_GET_PARAM_V3) { pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__); ptr = data->payload; if (ptr[0] != 0) { @@ -7823,7 +7823,7 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv) } } } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM || - VSS_ICOMMON_RSP_GET_PARAM_V3) { + data->opcode == VSS_ICOMMON_RSP_GET_PARAM_V3) { pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__); ptr = data->payload; if (ptr[0] != 0) { -- GitLab From 4e6f1e37db7aa557ed3d36132a6c8ff7b65235c0 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Wed, 21 Mar 2018 17:04:20 -0700 Subject: [PATCH 0241/1645] asoc: msmnile: update audio mic widgets Remove unused mic widgets and add new mic widgets required for msmnile target. Change-Id: I5e5ed56a80324b48599a00a196d99ed4ab386412 Signed-off-by: Vidyakumar Athota --- asoc/sdm855.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/asoc/sdm855.c b/asoc/sdm855.c index 79642d4e4a10..7d6e67fa70ee 100644 --- a/asoc/sdm855.c +++ b/asoc/sdm855.c @@ -3072,7 +3072,8 @@ static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { msm_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MIC("Handset Mic", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Analog Mic3", NULL), + SND_SOC_DAPM_MIC("Analog Mic4", NULL), SND_SOC_DAPM_MIC("Digital Mic0", NULL), SND_SOC_DAPM_MIC("Digital Mic1", NULL), @@ -3852,7 +3853,6 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) } snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); @@ -3871,10 +3871,10 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic"); snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic"); snd_soc_dapm_ignore_suspend(dapm, "Analog Mic5"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6"); snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1"); snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2"); snd_soc_dapm_ignore_suspend(dapm, "HPHL"); @@ -3884,6 +3884,8 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) } else { snd_soc_dapm_ignore_suspend(dapm, "Digital Mic6"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic7"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic3"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4"); } snd_soc_dapm_sync(dapm); -- GitLab From e6c80a9d09a4a7de66367ec8c4d13861695c50d4 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Wed, 21 Mar 2018 17:09:26 -0700 Subject: [PATCH 0242/1645] asoc: codecs: update wcd routing to fix warnings WCD9360 audio routing map is updated to avoid boot up warning logs. Also updated on-demand supply name. Change-Id: I66b8a4e28ec31a5337bfe2aede9b347edb94b291 Signed-off-by: Vidyakumar Athota --- asoc/codecs/wcd9360/wcd9360-routing.h | 9 +++++++-- asoc/codecs/wcd9360/wcd9360.c | 6 ++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/wcd9360/wcd9360-routing.h b/asoc/codecs/wcd9360/wcd9360-routing.h index 1d41c0a4871c..c305d2e23bf7 100644 --- a/asoc/codecs/wcd9360/wcd9360-routing.h +++ b/asoc/codecs/wcd9360/wcd9360-routing.h @@ -862,8 +862,13 @@ const struct snd_soc_dapm_route pahu_audio_map[] = { {"RX INT8 SEC MIX", NULL, "ASRC3 MUX"}, /* SLIMBUS-I2S Bridge interface */ - {"I2S TX1_0 MUX", "AIF4_PB", "AIF4 PB"}, - {"I2S TX1_1 MUX", "AIF4_PB", "AIF4 PB"}, + {"I2S TX1_0 MUX", "SB_RX2", "SLIM RX2"}, + + {"I2S TX1_1 MUX", "SB_RX0", "SLIM RX0"}, + {"I2S TX1_1 MUX", "SB_RX1", "SLIM RX1"}, + {"I2S TX1_1 MUX", "SB_RX2", "SLIM RX2"}, + {"I2S TX1_1 MUX", "SB_RX3", "SLIM RX3"}, + {"I2S TX1 MIXER", NULL, "I2S TX1_0 MUX"}, {"I2S TX1 MIXER", NULL, "I2S TX1_1 MUX"}, {"I2S1 CAP", NULL, "I2S TX1 MIXER"}, diff --git a/asoc/codecs/wcd9360/wcd9360.c b/asoc/codecs/wcd9360/wcd9360.c index 5b8da208a61b..c5fe3a05f3f3 100644 --- a/asoc/codecs/wcd9360/wcd9360.c +++ b/asoc/codecs/wcd9360/wcd9360.c @@ -137,7 +137,7 @@ static const struct snd_kcontrol_new name##_mux = \ #define DAPM_MICBIAS3_STANDALONE "MIC BIAS3 Standalone" #define DAPM_MICBIAS4_STANDALONE "MIC BIAS4 Standalone" -#define WCD9360_LDO_RXTX_SUPPLY_NAME "vdd_ldo_rxtx_supply" +#define WCD9360_LDO_RXTX_SUPPLY_NAME "cdc-vdd-ldo-rxtx" #define TX_HPF_CUT_OFF_FREQ_MASK 0x60 #define CF_MIN_3DB_4HZ 0x0 @@ -4323,7 +4323,7 @@ static const struct snd_kcontrol_new pahu_snd_controls[] = { SOC_SINGLE_MULTI_EXT("IIR0 Band5", IIR0, BAND5, 255, 0, 5, pahu_iir_band_audio_mixer_get, pahu_iir_band_audio_mixer_put), - SOC_SINGLE_EXT("COMP0 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0, + SOC_SINGLE_EXT("COMP0 Switch", SND_SOC_NOPM, COMPANDER_0, 1, 0, pahu_compander_get, pahu_compander_put), SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0, pahu_compander_get, pahu_compander_put), @@ -6749,8 +6749,6 @@ static const struct pahu_reg_mask_val pahu_codec_reg_defaults[] = { {WCD9360_CDC_COMPANDER7_CTL7, 0x01, 0x01}, {WCD9360_CDC_COMPANDER8_CTL7, 0x01, 0x01}, {WCD9360_CODEC_RPM_CLK_GATE, 0x08, 0x00}, - {WCD9360_TLMM_DMIC3_CLK_PINCFG, 0xFF, 0x0a}, - {WCD9360_TLMM_DMIC3_DATA_PINCFG, 0xFF, 0x0a}, {WCD9360_CPE_SS_SVA_CFG, 0x60, 0x00}, {WCD9360_CPE_SS_CPAR_CFG, 0x10, 0x10}, }; -- GitLab From 24be60db0cc8d3e3320d656731f674f0c813cb42 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 21 Mar 2018 19:41:16 -0700 Subject: [PATCH 0243/1645] asoc: msm: assign mic gnd swap function Assign mic gnd swap function if usbc analog is enabled. This is irrespective of whether us_euro gpio is defined. Change-Id: I6cf5beadca18682a7488db2286986883dbbcdf3d Signed-off-by: Karthikeyan Mani --- asoc/sdm855.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asoc/sdm855.c b/asoc/sdm855.c index 79642d4e4a10..e450e130a63a 100644 --- a/asoc/sdm855.c +++ b/asoc/sdm855.c @@ -7302,6 +7302,10 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) "qcom,us-euro-gpios"); wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; } + + if (wcd_mbhc_cfg.enable_usbc_analog) + wcd_mbhc_cfg.swap_gnd_mic = msm_usbc_swap_gnd_mic; + pdata->fsa_handle = of_parse_phandle(pdev->dev.of_node, "fsa4480-i2c-handle", 0); if (!pdata->fsa_handle) -- GitLab From 8d772b0efb51f1b1bc12c4de88f846b1e5910438 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 21 Mar 2018 19:52:32 -0700 Subject: [PATCH 0244/1645] asoc: wcd-mbhc: enable mbhc clk based on L_DET Enable or disable mbhc clk in sync with L_DET so that L_DET interrupt is not raised for false positives for usbc analog. Change-Id: I69792e8dc82cdc80751f2c1c705f603074cb9a2f Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd-mbhc-v2.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 97989dee1826..fd02dce7cb1e 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -959,8 +959,11 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) mbhc->extn_cable_hph_rem = false; wcd_mbhc_report_plug(mbhc, 0, jack_type); - if (mbhc->mbhc_cfg->enable_usbc_analog) + if (mbhc->mbhc_cfg->enable_usbc_analog) { WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 0); + if (mbhc->mbhc_cb->clk_setup) + mbhc->mbhc_cb->clk_setup(mbhc->codec, false); + } } else if (!detection_type) { /* Disable external voltage source to micbias if present */ @@ -1342,8 +1345,12 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) /* enable bias */ mbhc->mbhc_cb->mbhc_bias(codec, true); /* enable MBHC clock */ - if (mbhc->mbhc_cb->clk_setup) - mbhc->mbhc_cb->clk_setup(codec, true); + if (mbhc->mbhc_cb->clk_setup) { + if (mbhc->mbhc_cfg->enable_usbc_analog) + mbhc->mbhc_cb->clk_setup(codec, false); + else + mbhc->mbhc_cb->clk_setup(codec, true); + } /* program HS_VREF value */ wcd_program_hs_vref(mbhc); @@ -1505,6 +1512,8 @@ static int wcd_mbhc_usbc_ana_event_handler(struct notifier_block *nb, dev_dbg(mbhc->codec->dev, "%s: mode = %lu\n", __func__, mode); if (mode == POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) { + if (mbhc->mbhc_cb->clk_setup) + mbhc->mbhc_cb->clk_setup(mbhc->codec, true); /* insertion detected, enable L_DET_EN */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1); } -- GitLab From 865440767a635e5047eb53315664c639f002c46d Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Wed, 14 Mar 2018 12:10:22 -0700 Subject: [PATCH 0245/1645] rtac: add error check for misc_register in init Add error check to validate the return value of misc_register. Clean up memory on an error to avoid memory leak. CRs-Fixed: 2204093 Change-Id: I8b94bacdc312fa410a7825c7e25764517469c19b Signed-off-by: Vignesh Kulothungan --- dsp/rtac.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dsp/rtac.c b/dsp/rtac.c index d23363597ea6..82d08bfa79fc 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -2046,17 +2046,23 @@ int __init rtac_init(void) goto nomem; } - return misc_register(&rtac_misc); + if (misc_register(&rtac_misc) != 0) { + kzfree(rtac_adm_buffer); + kzfree(rtac_asm_buffer); + kzfree(rtac_afe_buffer); + kzfree(rtac_voice_buffer); + } nomem: return -ENOMEM; } void rtac_exit(void) { + misc_deregister(&rtac_misc); kzfree(rtac_adm_buffer); kzfree(rtac_asm_buffer); kzfree(rtac_afe_buffer); - misc_deregister(&rtac_misc); + kzfree(rtac_voice_buffer); } MODULE_DESCRIPTION("SoC QDSP6v2 Real-Time Audio Calibration driver"); -- GitLab From 13d5a9666a2b82c325297eccc0f85d227821be0c Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Wed, 21 Mar 2018 14:30:07 -0700 Subject: [PATCH 0246/1645] dsp: Initialize variable before use Initialize variable before use in voice driver. CRs-Fixed: 2209691 Change-Id: I84b51262b5c3cb12ea23372eb7c7109c6ff844b4 Signed-off-by: Vignesh Kulothungan --- dsp/q6voice.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 91549f99a5ce..53b7f1e2ed32 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -7903,7 +7903,7 @@ static int voice_alloc_oob_shared_mem(void) int cnt = 0; int rc = 0; size_t len; - void *mem_addr; + void *mem_addr = NULL; dma_addr_t phys; int bufsz = BUFFER_BLOCK_SIZE; int bufcnt = NUM_OF_BUFFERS; -- GitLab From f6077636ee0a1864b823fe4353930be629224a30 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Sun, 11 Mar 2018 22:41:27 -0700 Subject: [PATCH 0247/1645] dsp: msm_audio_ion: add ION support for targets without SMMU ION memory allocator is used for audio use cases even on targets without SMMU. Add support for ION on those targets where ADSP might not have an SMMU in front of it. Change-Id: Iaacbd66edb32c8ee7c14a5ab291abe54960725b8 Signed-off-by: Banajit Goswami --- dsp/msm_audio_ion.c | 99 +++++++++++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 26 deletions(-) diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index 63a386beb7c2..e073d94a8cf1 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -41,7 +41,7 @@ #define MSM_AUDIO_SMMU_SID_OFFSET 32 struct msm_audio_ion_private { - bool audioheap_enabled; + bool smmu_enabled; struct device *cb_dev; struct dma_iommu_mapping *mapping; u8 device_status; @@ -83,6 +83,7 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf, struct msm_audio_alloc_data *alloc_data; struct device *cb_dev; + unsigned long ionflag = 0; int rc = 0; cb_dev = msm_audio_ion_data.cb_dev; @@ -104,9 +105,20 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf, dev_err(cb_dev, "%s: Fail to attach dma_buf to CB, rc = %d\n", __func__, rc); - goto err_attach; + goto free_alloc_data; + } + + /* For uncached buffers, avoid cache maintanance */ + rc = dma_buf_get_flags(alloc_data->dma_buf, &ionflag); + if (rc) { + dev_err(cb_dev, "%s: dma_buf_get_flags failed: %d\n", + __func__, rc); + goto detach_dma_buf; } + if (!(ionflag & ION_FLAG_CACHED)) + alloc_data->attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC; + /* * Get the scatter-gather list. * There is no info as this is a write buffer or @@ -120,7 +132,7 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf, dev_err(cb_dev, "%s: Fail to map attachment, rc = %d\n", __func__, rc); - goto err_map_attach; + goto detach_dma_buf; } /* physical address from mapping */ @@ -130,10 +142,10 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf, alloc_data); return rc; -err_map_attach: +detach_dma_buf: dma_buf_detach(alloc_data->dma_buf, alloc_data->attach); -err_attach: +free_alloc_data: kfree(alloc_data); return rc; @@ -198,8 +210,10 @@ static int msm_audio_ion_get_phys(struct dma_buf *dma_buf, __func__, rc); goto err; } - /* Append the SMMU SID information to the IOVA address */ - *addr |= msm_audio_ion_data.smmu_sid_bits; + if (msm_audio_ion_data.smmu_enabled) { + /* Append the SMMU SID information to the IOVA address */ + *addr |= msm_audio_ion_data.smmu_sid_bits; + } pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc); err: @@ -307,6 +321,14 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr, return rc; } +static u32 msm_audio_ion_get_smmu_sid_mode32(void) +{ + if (msm_audio_ion_data.smmu_enabled) + return upper_32_bits(msm_audio_ion_data.smmu_sid_bits); + else + return 0; +} + /** * msm_audio_ion_alloc - * Allocs ION memory for given client name @@ -325,7 +347,8 @@ int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, int rc = -EINVAL; unsigned long err_ion_ptr = 0; - if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { + if ((msm_audio_ion_data.smmu_enabled == true) && + !(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { pr_debug("%s:probe is not done, deferred\n", __func__); return -EPROBE_DEFER; } @@ -334,12 +357,18 @@ int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, return -EINVAL; } - *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_HEAP_ID), 0); + if (msm_audio_ion_data.smmu_enabled == true) { + pr_debug("%s: system heap is used\n", __func__); + *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_HEAP_ID), 0); + } else { + pr_debug("%s: audio heap is used\n", __func__); + *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_AUDIO_HEAP_ID), 0); + } if (IS_ERR_OR_NULL((void *)(*dma_buf))) { if (IS_ERR((void *)(*dma_buf))) err_ion_ptr = PTR_ERR((int *)(*dma_buf)); - pr_err("%s:ION alloc fail err ptr=%ld\n", - __func__, err_ion_ptr); + pr_err("%s: ION alloc fail err ptr=%ld, smmu_enabled=%d\n", + __func__, err_ion_ptr, msm_audio_ion_data.smmu_enabled); rc = -ENOMEM; goto err; } @@ -383,8 +412,9 @@ int msm_audio_ion_import(struct dma_buf **dma_buf, int fd, { int rc = 0; - if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { - pr_debug("%s:probe is not done, deferred\n", __func__); + if ((msm_audio_ion_data.smmu_enabled == true) && + !(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { + pr_debug("%s: probe is not done, deferred\n", __func__); return -EPROBE_DEFER; } @@ -598,7 +628,7 @@ EXPORT_SYMBOL(msm_audio_ion_cache_operations); u32 msm_audio_populate_upper_32_bits(dma_addr_t pa) { if (sizeof(dma_addr_t) == sizeof(u32)) - return upper_32_bits(msm_audio_ion_data.smmu_sid_bits); + return msm_audio_ion_get_smmu_sid_mode32(); else return upper_32_bits(pa); } @@ -643,32 +673,34 @@ MODULE_DEVICE_TABLE(of, msm_audio_ion_dt_match); static int msm_audio_ion_probe(struct platform_device *pdev) { int rc = 0; + u64 smmu_sid = 0; + u64 smmu_sid_mask = 0; + const char *msm_audio_ion_dt = "qcom,smmu-enabled"; const char *msm_audio_ion_smmu = "qcom,smmu-version"; const char *msm_audio_ion_smmu_sid_mask = "qcom,smmu-sid-mask"; + bool smmu_enabled; enum apr_subsys_state q6_state; struct device *dev = &pdev->dev; - u64 smmu_sid = 0; - u64 smmu_sid_mask = 0; struct of_phandle_args iommuspec; + if (dev->of_node == NULL) { dev_err(dev, "%s: device tree is not found\n", __func__); + msm_audio_ion_data.smmu_enabled = 0; return 0; } - rc = of_property_read_u32(dev->of_node, - msm_audio_ion_smmu, - &msm_audio_ion_data.smmu_version); - if (rc) { - dev_err(dev, - "%s: qcom,smmu_version missing in DT node\n", - __func__); - return rc; + smmu_enabled = of_property_read_bool(dev->of_node, + msm_audio_ion_dt); + msm_audio_ion_data.smmu_enabled = smmu_enabled; + + if (!smmu_enabled) { + dev_dbg(dev, "%s: SMMU is Disabled\n", __func__); + goto exit; } - dev_dbg(dev, "%s: SMMU version is (%d)", __func__, - msm_audio_ion_data.smmu_version); + q6_state = apr_get_q6_state(); if (q6_state == APR_SUBSYS_DOWN) { dev_dbg(dev, @@ -678,6 +710,18 @@ static int msm_audio_ion_probe(struct platform_device *pdev) } dev_dbg(dev, "%s: adsp is ready\n", __func__); + rc = of_property_read_u32(dev->of_node, + msm_audio_ion_smmu, + &msm_audio_ion_data.smmu_version); + if (rc) { + dev_err(dev, + "%s: qcom,smmu_version missing in DT node\n", + __func__); + return rc; + } + dev_dbg(dev, "%s: SMMU is Enabled. SMMU version is (%d)", + __func__, msm_audio_ion_data.smmu_version); + /* Get SMMU SID information from Devicetree */ rc = of_property_read_u64(dev->of_node, msm_audio_ion_smmu_sid_mask, @@ -688,6 +732,7 @@ static int msm_audio_ion_probe(struct platform_device *pdev) __func__); smmu_sid_mask = 0xFFFFFFFFFFFFFFFF; } + rc = of_parse_phandle_with_args(dev->of_node, "iommus", "#iommu-cells", 0, &iommuspec); if (rc) @@ -710,6 +755,7 @@ static int msm_audio_ion_probe(struct platform_device *pdev) dev_err(dev, "%s: smmu init failed, err = %d\n", __func__, rc); +exit: if (!rc) msm_audio_ion_data.device_status |= MSM_AUDIO_ION_PROBED; @@ -729,6 +775,7 @@ static int msm_audio_ion_remove(struct platform_device *pdev) arm_iommu_release_mapping(mapping); } + msm_audio_ion_data.smmu_enabled = 0; msm_audio_ion_data.device_status = 0; return 0; } -- GitLab From 3d99f7a130d8fb2037ef6ef9208a7d737b5478cb Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Sat, 3 Mar 2018 02:09:05 -0800 Subject: [PATCH 0248/1645] ipc: make APR driver a platform driver Change APR driver to platform driver and add any child device only after ADSP up notification is received. The idea is to have machine driver as a child device under APR, and add the platform device for machine driver only after ADSP is up. This will help invoke audio drivers waiting with deferred probe and eventually should help sound card registers successfully. Change-Id: Ib0c0f7ec1d7dd93a1b54a9a66260861223d55c67 Signed-off-by: Laxminath Kasam Signed-off-by: Meng Wang Signed-off-by: Banajit Goswami --- ipc/apr.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 143 insertions(+), 13 deletions(-) diff --git a/ipc/apr.c b/ipc/apr.c index 331f057c4135..3f07f6e87b6c 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -42,7 +43,6 @@ static void *apr_pkt_ctx; static wait_queue_head_t dsp_wait; static wait_queue_head_t modem_wait; static bool is_modem_up; -static bool is_initial_boot; /* Subsystem restart: QDSP6 data, functions */ static struct workqueue_struct *apr_reset_workqueue; static void apr_reset_deregister(struct work_struct *work); @@ -52,6 +52,21 @@ struct apr_reset_work { struct work_struct work; }; +struct apr_chld_device { + struct platform_device *pdev; + struct list_head node; +}; + +struct apr_private { + struct device *dev; + spinlock_t apr_lock; + bool is_initial_boot; + struct work_struct add_chld_dev_work; + spinlock_t apr_chld_lock; + struct list_head apr_chlds; +}; + +static struct apr_private *apr_priv; static bool apr_cf_debug; #ifdef CONFIG_DEBUG_FS @@ -275,15 +290,65 @@ enum apr_subsys_state apr_cmpxchg_q6_state(enum apr_subsys_state prev, static void apr_adsp_down(unsigned long opcode) { + pr_debug("%s: Q6 is Down\n", __func__); apr_set_q6_state(APR_SUBSYS_DOWN); dispatch_event(opcode, APR_DEST_QDSP6); } +static void apr_add_child_devices(struct work_struct *work) +{ + int ret; + struct device_node *node; + struct platform_device *pdev; + struct apr_chld_device *apr_chld_dev; + + for_each_child_of_node(apr_priv->dev->of_node, node) { + apr_chld_dev = kzalloc(sizeof(*apr_chld_dev), GFP_KERNEL); + if (!apr_chld_dev) + continue; + pdev = platform_device_alloc(node->name, -1); + if (!pdev) { + dev_err(apr_priv->dev, + "%s: pdev memory alloc failed for %s\n", + __func__, node->name); + kfree(apr_chld_dev); + continue; + } + pdev->dev.parent = apr_priv->dev; + pdev->dev.of_node = node; + + ret = platform_device_add(pdev); + if (ret) { + dev_err(apr_priv->dev, + "%s: Cannot add platform device %s\n", + __func__, node->name); + platform_device_put(pdev); + kfree(apr_chld_dev); + continue; + } + + apr_chld_dev->pdev = pdev; + + spin_lock(&apr_priv->apr_chld_lock); + list_add_tail(&apr_chld_dev->node, &apr_priv->apr_chlds); + spin_unlock(&apr_priv->apr_chld_lock); + + dev_dbg(apr_priv->dev, "%s: Added APR child dev: %s\n", + __func__, dev_name(&pdev->dev)); + } +} + static void apr_adsp_up(void) { + pr_debug("%s: Q6 is Up\n", __func__); if (apr_cmpxchg_q6_state(APR_SUBSYS_DOWN, APR_SUBSYS_LOADED) == APR_SUBSYS_DOWN) wake_up(&dsp_wait); + + spin_lock(&apr_priv->apr_lock); + if (apr_priv->is_initial_boot) + schedule_work(&apr_priv->add_chld_dev_work); + spin_unlock(&apr_priv->apr_lock); } int apr_wait_for_device_up(int dest_id) @@ -1044,21 +1109,25 @@ static int apr_notifier_service_cb(struct notifier_block *this, * recovery notifications during initial boot * up since everything is expected to be down. */ - if (is_initial_boot) { - is_initial_boot = false; + spin_lock(&apr_priv->apr_lock); + if (apr_priv->is_initial_boot) { + spin_unlock(&apr_priv->apr_lock); break; } + spin_unlock(&apr_priv->apr_lock); if (cb_data->domain == AUDIO_NOTIFIER_MODEM_DOMAIN) apr_modem_down(opcode); else apr_adsp_down(opcode); break; case AUDIO_NOTIFIER_SERVICE_UP: - is_initial_boot = false; if (cb_data->domain == AUDIO_NOTIFIER_MODEM_DOMAIN) apr_modem_up(); else apr_adsp_up(); + spin_lock(&apr_priv->apr_lock); + apr_priv->is_initial_boot = false; + spin_unlock(&apr_priv->apr_lock); break; default: break; @@ -1092,13 +1161,43 @@ static int __init apr_debug_init(void) ) #endif -static int __init apr_init(void) +static void apr_cleanup(void) +{ + int i, j, k; + + subsys_notif_deregister("apr_modem"); + subsys_notif_deregister("apr_adsp"); + if (apr_reset_workqueue) { + flush_workqueue(apr_reset_workqueue); + destroy_workqueue(apr_reset_workqueue); + } + mutex_destroy(&q6.lock); + for (i = 0; i < APR_DEST_MAX; i++) { + for (j = 0; j < APR_CLIENT_MAX; j++) { + mutex_destroy(&client[i][j].m_lock); + for (k = 0; k < APR_SVC_MAX; k++) + mutex_destroy(&client[i][j].svc[k].m_lock); + } + } +} + +static int apr_probe(struct platform_device *pdev) { int i, j, k; init_waitqueue_head(&dsp_wait); init_waitqueue_head(&modem_wait); + apr_priv = devm_kzalloc(&pdev->dev, sizeof(*apr_priv), GFP_KERNEL); + if (!apr_priv) + return -ENOMEM; + + apr_priv->dev = &pdev->dev; + spin_lock_init(&apr_priv->apr_lock); + spin_lock_init(&apr_priv->apr_chld_lock); + INIT_LIST_HEAD(&apr_priv->apr_chlds); + INIT_WORK(&apr_priv->add_chld_dev_work, apr_add_child_devices); + for (i = 0; i < APR_DEST_MAX; i++) for (j = 0; j < APR_CLIENT_MAX; j++) { mutex_init(&client[i][j].m_lock); @@ -1110,15 +1209,19 @@ static int __init apr_init(void) apr_set_subsys_state(); mutex_init(&q6.lock); apr_reset_workqueue = create_singlethread_workqueue("apr_driver"); - if (!apr_reset_workqueue) + if (!apr_reset_workqueue) { + apr_priv = NULL; return -ENOMEM; + } apr_pkt_ctx = ipc_log_context_create(APR_PKT_IPC_LOG_PAGE_CNT, "apr", 0); if (!apr_pkt_ctx) pr_err("%s: Unable to create ipc log context\n", __func__); - is_initial_boot = true; + spin_lock(&apr_priv->apr_lock); + apr_priv->is_initial_boot = true; + spin_unlock(&apr_priv->apr_lock); subsys_notif_register("apr_adsp", AUDIO_NOTIFIER_ADSP_DOMAIN, &adsp_service_nb); subsys_notif_register("apr_modem", AUDIO_NOTIFIER_MODEM_DOMAIN, @@ -1127,14 +1230,41 @@ static int __init apr_init(void) apr_tal_init(); return apr_debug_init(); } -module_init(apr_init); -void __exit apr_exit(void) +static int apr_remove(struct platform_device *pdev) { - subsys_notif_deregister("apr_modem"); - subsys_notif_deregister("apr_adsp"); + struct apr_chld_device *chld, *tmp; + + apr_cleanup(); apr_tal_exit(); + spin_lock(&apr_priv->apr_chld_lock); + list_for_each_entry_safe(chld, tmp, &apr_priv->apr_chlds, node) { + platform_device_unregister(chld->pdev); + list_del(&chld->node); + kfree(chld); + } + spin_unlock(&apr_priv->apr_chld_lock); + apr_priv = NULL; + return 0; } -module_exit(apr_exit); -MODULE_DESCRIPTION("APR module"); + +static const struct of_device_id apr_machine_of_match[] = { + { .compatible = "qcom,msm-audio-apr", }, + {}, +}; + +static struct platform_driver apr_driver = { + .probe = apr_probe, + .remove = apr_remove, + .driver = { + .name = "audio_apr", + .owner = THIS_MODULE, + .of_match_table = apr_machine_of_match, + } +}; + +module_platform_driver(apr_driver); + +MODULE_DESCRIPTION("APR DRIVER"); MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(of, apr_machine_of_match); -- GitLab From 249b1f9bf16f3b690848ca874d1a810fb85112ee Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Fri, 30 Mar 2018 09:21:47 +0800 Subject: [PATCH 0249/1645] ASoC: fix compilation warnings after enabling LLVM After enabling compilation with LLVM for audio drivers, some assignment warnings are reported. Add this change to resolve the compilation warnings. Change-Id: I571b2e210053bc0b80d65cd272ce1751e0ed10fb Signed-off-by: Meng Wang --- asoc/codecs/wcd_cpe_services.c | 4 ++-- dsp/q6lsm.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/wcd_cpe_services.c b/asoc/codecs/wcd_cpe_services.c index fc8242a91275..e584cf05a6ef 100644 --- a/asoc/codecs/wcd_cpe_services.c +++ b/asoc/codecs/wcd_cpe_services.c @@ -654,7 +654,7 @@ static void cpe_notify_cmi_client(struct cpe_info *t_info, u8 *payload, hdr = CMI_GET_HEADER(payload); service = CMI_HDR_GET_SERVICE(hdr); - notif.event = CPE_SVC_CMI_MSG; + notif.event = CMI_API_MSG; notif.result = result; notif.message = payload; @@ -1170,7 +1170,7 @@ static enum cpe_process_result cpe_boot_complete( } pr_debug("%s: boot complete\n", __func__); - return CPE_SVC_SUCCESS; + return CPE_PROC_SUCCESS; } static enum cpe_process_result cpe_process_send_msg( diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 108e4be4026b..3d87a8df5a9e 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -225,7 +225,7 @@ static void q6lsm_session_free(struct lsm_client *client) pr_debug("%s: Freeing session ID %d\n", __func__, client->session); spin_lock_irqsave(&lsm_session_lock, flags); - lsm_session[client->session] = LSM_INVALID_SESSION_ID; + lsm_session[client->session] = NULL; spin_unlock_irqrestore(&lsm_session_lock, flags); client->session = LSM_INVALID_SESSION_ID; } -- GitLab From c3b3df985d5b3574288f7f09e6675104e643363b Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Tue, 27 Mar 2018 20:50:35 -0700 Subject: [PATCH 0250/1645] asoc: codecs: probe defer till mclk is available for wcd9360 Sometimes codec enumerates before APPS APR communication happens with ADSP. Since wcd9360 MCLK request goes through APR, defer the codec probe till mclk is available. Change-Id: Ief5bb80f4c62fcf58a8cc93f11a9b4536f883d1e Signed-off-by: Vidyakumar Athota --- asoc/codecs/wcd9360/wcd9360.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/asoc/codecs/wcd9360/wcd9360.c b/asoc/codecs/wcd9360/wcd9360.c index 5b8da208a61b..7c9421f30b40 100644 --- a/asoc/codecs/wcd9360/wcd9360.c +++ b/asoc/codecs/wcd9360/wcd9360.c @@ -8013,6 +8013,16 @@ static int pahu_probe(struct platform_device *pdev) pahu->wcd_ext_clk = wcd_ext_clk; dev_dbg(&pdev->dev, "%s: MCLK Rate = %x\n", __func__, pahu->wcd9xxx->mclk_rate); + /* Probe defer if mlck is failed */ + ret = clk_prepare_enable(pahu->wcd_ext_clk); + if (ret) { + dev_dbg(pahu->dev, "%s: ext clk enable failed\n", + __func__); + ret = -EPROBE_DEFER; + goto err_cdc_reg; + } + clk_disable_unprepare(pahu->wcd_ext_clk); + /* Update codec register default values */ pahu_update_reg_defaults(pahu); __pahu_enable_efuse_sensing(pahu); -- GitLab From 7c54a1801d33eaec463372c8115feacec546508b Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Thu, 22 Mar 2018 11:55:06 -0700 Subject: [PATCH 0251/1645] ipc: wcd-dsp-glink: prevent potential NULL pointer dereference The current logic that checks pointer "rpdev" for NULL is not correct. Fix it to prevent potential NULL pointer dereference. Change-Id: Ieaad98396ff43b66b0dd41efbfbf9f6ae923a2bb Signed-off-by: Xiaoyu Ye --- ipc/wcd-dsp-glink.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ipc/wcd-dsp-glink.c b/ipc/wcd-dsp-glink.c index 8e1d8a2757da..21da65aae069 100644 --- a/ipc/wcd-dsp-glink.c +++ b/ipc/wcd-dsp-glink.c @@ -266,7 +266,7 @@ static void wdsp_tx_buf_work(struct work_struct *work) spin_lock(&ch->ch_lock); rpdev = ch->handle; - if (rpdev || ch->ch_state == WDSP_CH_CONNECTED) { + if (rpdev && ch->ch_state == WDSP_CH_CONNECTED) { spin_unlock(&ch->ch_lock); ret = rpmsg_send(rpdev->ept, cpkt->payload, cpkt->payload_size); @@ -275,8 +275,11 @@ static void wdsp_tx_buf_work(struct work_struct *work) __func__, ret); } else { spin_unlock(&ch->ch_lock); - dev_err(wpriv->dev, "%s: channel %s is not in connected state\n", - __func__, ch->ch_name); + if (rpdev) + dev_err(wpriv->dev, "%s: channel %s is not in connected state\n", + __func__, ch->ch_name); + else + dev_err(wpriv->dev, "%s: rpdev is NULL\n", __func__); } vfree(tx_buf); } -- GitLab From 992b2f0fa1cbb7b1aa4c35ecd058f5a433e7a817 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Tue, 20 Mar 2018 16:01:41 +0800 Subject: [PATCH 0252/1645] ASoC: codecs: wcd: avoid redundant component unbind Component unbind happens in component_bind_all, if component bind fails. There is no need to call extra component_unbind_all. Change-Id: I4ff2aececc5e10c5c4cfbe71778630c621768349 Signed-off-by: Xiaojun Sang --- asoc/codecs/wcd-dsp-mgr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd-dsp-mgr.c b/asoc/codecs/wcd-dsp-mgr.c index 9bcb6353e8dd..9e65deb473b1 100644 --- a/asoc/codecs/wcd-dsp-mgr.c +++ b/asoc/codecs/wcd-dsp-mgr.c @@ -1059,8 +1059,10 @@ static int wdsp_mgr_bind(struct device *dev) dev_info(dev, "%s: create_ramdump_device failed\n", __func__); ret = component_bind_all(dev, wdsp->ops); - if (ret < 0) + if (ret < 0) { WDSP_ERR(wdsp, "component_bind_all failed %d\n", ret); + return ret; + } /* Make sure all components registered ops */ for (idx = 0; idx < WDSP_CMPNT_TYPE_MAX; idx++) { -- GitLab From 75642c362c5341fbe45e2ead4ef50a55305c8e21 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Fri, 23 Mar 2018 08:57:33 +0800 Subject: [PATCH 0253/1645] ASoC: msm: check payload size before memory allocation Buffer from mixer ctl or ADSP is composed of payload size and actual payload. On a 32 bit platform, we could have an overflow if payload size is below UINT_MAX while payload size + sizeof(struct) is over UINT_MAX. Allocated memory size would be less than expected. Check payload size against limit before memory allocation. Change-Id: I0bf19ca7b8c93083177a21ad726122dc20f45551 Signed-off-by: Xiaojun Sang --- asoc/msm-compress-q6-v2.c | 4 ++-- asoc/msm-pcm-q6-v2.c | 4 ++-- asoc/msm-qti-pp-config.c | 5 +++-- asoc/msm-transcode-loopback-q6-v2.c | 6 +++--- dsp/q6asm.c | 7 +++++++ 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index b644df701123..7ba582a0c3aa 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -3681,8 +3681,8 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, goto done; } - if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >= - sizeof(ucontrol->value.bytes.data)) { + if (event_data->payload_len > sizeof(ucontrol->value.bytes.data) + - sizeof(struct msm_adsp_event_data)) { pr_err("%s param length=%d exceeds limit", __func__, event_data->payload_len); ret = -EINVAL; diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index bbcbab35957c..b82128e7fabe 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1138,8 +1138,8 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, goto done; } - if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >= - sizeof(ucontrol->value.bytes.data)) { + if (event_data->payload_len > sizeof(ucontrol->value.bytes.data) + - sizeof(struct msm_adsp_event_data)) { pr_err("%s param length=%d exceeds limit", __func__, event_data->payload_len); ret = -EINVAL; diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index f210745fa69d..ccbc0b76004b 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -1025,8 +1025,9 @@ int msm_adsp_inform_mixer_ctl(struct snd_soc_pcm_runtime *rtd, event_data = (struct msm_adsp_event_data *)payload; kctl->info(kctl, &kctl_info); - if (sizeof(struct msm_adsp_event_data) - + event_data->payload_len > kctl_info.count) { + + if (event_data->payload_len > + kctl_info.count - sizeof(struct msm_adsp_event_data)) { pr_err("%s: payload length exceeds limit of %u bytes.\n", __func__, kctl_info.count); ret = -EINVAL; diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index 3c8e917f4278..3d4f8bf3ffbc 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -539,8 +539,8 @@ static int msm_transcode_stream_cmd_put(struct snd_kcontrol *kcontrol, goto done; } - if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >= - sizeof(ucontrol->value.bytes.data)) { + if (event_data->payload_len > sizeof(ucontrol->value.bytes.data) + - sizeof(struct msm_adsp_event_data)) { pr_err("%s param length=%d exceeds limit", __func__, event_data->payload_len); ret = -EINVAL; diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 5bfed89dcc61..55d82b7ce93d 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -2230,6 +2230,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) * package is composed of event type + size + actual payload */ payload_size = data->payload_size; + if (payload_size > UINT_MAX - sizeof(struct msm_adsp_event_data)) { + pr_err("%s: payload size = %d exceeds limit.\n", + __func__, payload_size); + spin_unlock(&(session[session_id].session_lock)); + return -EINVAL; + } + pp_event_package = kzalloc(payload_size + sizeof(struct msm_adsp_event_data), GFP_ATOMIC); -- GitLab From b3c62d149ea5ff55a0f0e240fa880bcd6a7c4636 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 23 Mar 2018 15:07:57 -0700 Subject: [PATCH 0254/1645] asoc: remove tdm optional properties boot logs Move the tdm device property logs from probe function to prepare function to print them only when tdm usecase is started and not during bootup. Change-Id: I3844709d501bf510620d6f20f270e30c68e78b78 Signed-off-by: Karthikeyan Mani --- asoc/msm-dai-q6-v2.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index d0df70c5b016..c3c1fbdfcae5 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -5252,9 +5252,6 @@ static int msm_dai_tdm_q6_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "%s: Group ID from DT file 0x%x\n", __func__, tdm_group_cfg.group_id); - dev_info(&pdev->dev, "%s: dev_name: %s group_id: 0x%x\n", - __func__, dev_name(&pdev->dev), tdm_group_cfg.group_id); - rc = of_property_read_u32(pdev->dev.of_node, "qcom,msm-cpudai-tdm-group-num-ports", &num_tdm_group_ports); @@ -6920,6 +6917,13 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream, int group_idx = 0; atomic_t *group_ref = NULL; + dev_dbg(dai->dev, "%s: dev_name: %s dev_id: 0x%x group_id: 0x%x\n", + __func__, dev_name(dai->dev), dai->dev->id, group_id); + + if (dai_data->port_cfg.custom_tdm_header.minor_version == 0) + dev_dbg(dai->dev, + "%s: Custom tdm header not supported\n", __func__); + group_idx = msm_dai_q6_get_group_idx(dai->id); if (group_idx < 0) { dev_err(dai->dev, "%s port id 0x%x not supported\n", @@ -8688,9 +8692,6 @@ static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev) } pdev->id = tdm_dev_id; - dev_info(&pdev->dev, "%s: dev_name: %s dev_id: 0x%x\n", - __func__, dev_name(&pdev->dev), tdm_dev_id); - dai_data = kzalloc(sizeof(struct msm_dai_q6_tdm_dai_data), GFP_KERNEL); if (!dai_data) { @@ -8831,8 +8832,6 @@ static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev) custom_tdm_header->header_type = AFE_CUSTOM_TDM_HEADER_TYPE_INVALID; } else { - dev_info(&pdev->dev, - "%s: Custom tdm header not supported\n", __func__); /* CUSTOM TDM HEADER CFG -- set default */ custom_tdm_header->header_type = AFE_CUSTOM_TDM_HEADER_TYPE_INVALID; -- GitLab From 2c6dccdf9128f1049edfc388b5bf61ab606e3c2f Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 22 Mar 2018 14:18:43 -0700 Subject: [PATCH 0255/1645] dsp: update parameter header type in ADM Update parameter header type in ADM programmable channel mixer function. CRs-Fixed: 2209691 Change-Id: Iae0f5f832d14a111e1da75f85cf766d768b64a4b Signed-off-by: Vignesh Kulothungan --- dsp/q6adm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 282d7f7af736..7d59fbbce66a 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -480,7 +480,7 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, int channel_index) { struct adm_cmd_set_pspd_mtmx_strtr_params_v5 *adm_params = NULL; - struct param_hdr_v3 data_v5; + struct param_hdr_v1 data_v5; int ret = 0, port_idx, sz = 0, param_size = 0; u16 *adm_pspd_params; u16 *ptr; @@ -513,7 +513,7 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, sz = sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v5) + sizeof(struct default_chmixer_param_id_coeff) + - sizeof(struct param_hdr_v3) + param_size; + sizeof(struct param_hdr_v1) + param_size; pr_debug("%s: sz = %d\n", __func__, sz); adm_params = kzalloc(sz, GFP_KERNEL); if (!adm_params) @@ -541,7 +541,7 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, data_v5.param_size = param_size; adm_params->payload_size = sizeof(struct default_chmixer_param_id_coeff) + - sizeof(struct param_hdr_v3) + data_v5.param_size; + sizeof(struct param_hdr_v1) + data_v5.param_size; adm_pspd_params = (u16 *)((u8 *)adm_params + sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v5)); memcpy(adm_pspd_params, &data_v5, sizeof(data_v5)); -- GitLab From 05d5e9aeedf84eae026735258c708822223497eb Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 28 Mar 2018 16:45:03 +0800 Subject: [PATCH 0256/1645] asoc: fix possible overflow issue for routing driver The reg in soc_mixer_control is 32-bit. When using SOC_SINGLE_EXT, the value of FE DAI ID which is passed as shift(to be operated on the reg) may be more than 31, which may cause overflow. Use SOC_DOUBLE_EXT instead of SOC_SINGLE_EXT so that the reg field can be set to SOC_NO_PM to avoid any DAPM operation, while passing BE and FE IDs in shift and rshift fields. And these values can be retrieve in get/put functions and use them. This is to avoid any possible overflow in DAPM operation. Change-Id: I17fa4e059889ae725e6f015a779f518e6d0a813f Signed-off-by: Meng Wang --- asoc/msm-pcm-routing-v2.c | 6675 ++++++++++++++++++++++++------------- 1 file changed, 4428 insertions(+), 2247 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 0096688f5080..3db79906628a 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1799,12 +1799,12 @@ static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol, struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0])) + if (test_bit(mc->rshift, &msm_bedais[mc->shift].fe_sessions[0])) ucontrol->value.integer.value[0] = 1; else ucontrol->value.integer.value[0] = 0; - pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + pr_debug("%s: shift %x rshift %x val %ld\n", __func__, mc->shift, mc->rshift, ucontrol->value.integer.value[0]); return 0; @@ -1820,13 +1820,13 @@ static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol, struct snd_soc_dapm_update *update = NULL; if (ucontrol->value.integer.value[0] && - msm_pcm_routing_route_is_set(mc->reg, mc->shift) == false) { - msm_pcm_routing_process_audio(mc->reg, mc->shift, 1); + msm_pcm_routing_route_is_set(mc->shift, mc->rshift) == false) { + msm_pcm_routing_process_audio(mc->shift, mc->rshift, 1); snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, update); } else if (!ucontrol->value.integer.value[0] && - msm_pcm_routing_route_is_set(mc->reg, mc->shift) == true) { - msm_pcm_routing_process_audio(mc->reg, mc->shift, 0); + msm_pcm_routing_route_is_set(mc->shift, mc->rshift) == true) { + msm_pcm_routing_process_audio(mc->shift, mc->rshift, 0); snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, update); } @@ -1840,12 +1840,12 @@ static int msm_routing_get_listen_mixer(struct snd_kcontrol *kcontrol, struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0])) + if (test_bit(mc->rshift, &msm_bedais[mc->shift].fe_sessions[0])) ucontrol->value.integer.value[0] = 1; else ucontrol->value.integer.value[0] = 0; - pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + pr_debug("%s: shift %x rshift %x val %ld\n", __func__, mc->shift, mc->rshift, ucontrol->value.integer.value[0]); return 0; @@ -1860,17 +1860,17 @@ static int msm_routing_put_listen_mixer(struct snd_kcontrol *kcontrol, (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_dapm_update *update = NULL; - pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + pr_debug("%s: shift %x rshift %x val %ld\n", __func__, mc->shift, mc->rshift, ucontrol->value.integer.value[0]); if (ucontrol->value.integer.value[0]) { - if (msm_pcm_routing_route_is_set(mc->reg, mc->shift) == false) - msm_pcm_routing_process_audio(mc->reg, mc->shift, 1); + if (msm_pcm_routing_route_is_set(mc->shift, mc->rshift) == false) + msm_pcm_routing_process_audio(mc->shift, mc->rshift, 1); snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, update); } else if (!ucontrol->value.integer.value[0]) { - if (msm_pcm_routing_route_is_set(mc->reg, mc->shift) == true) - msm_pcm_routing_process_audio(mc->reg, mc->shift, 0); + if (msm_pcm_routing_route_is_set(mc->shift, mc->rshift) == true) + msm_pcm_routing_process_audio(mc->shift, mc->rshift, 0); snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, update); } @@ -1955,14 +1955,14 @@ static int msm_routing_get_voice_mixer(struct snd_kcontrol *kcontrol, mutex_lock(&routing_lock); - if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0])) + if (test_bit(mc->rshift, &msm_bedais[mc->shift].fe_sessions[0])) ucontrol->value.integer.value[0] = 1; else ucontrol->value.integer.value[0] = 0; mutex_unlock(&routing_lock); - pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + pr_debug("%s: shift %x rshift %x val %ld\n", __func__, mc->shift, mc->rshift, ucontrol->value.integer.value[0]); return 0; @@ -1978,11 +1978,11 @@ static int msm_routing_put_voice_mixer(struct snd_kcontrol *kcontrol, struct snd_soc_dapm_update *update = NULL; if (ucontrol->value.integer.value[0]) { - msm_pcm_routing_process_voice(mc->reg, mc->shift, 1); + msm_pcm_routing_process_voice(mc->shift, mc->rshift, 1); snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, update); } else { - msm_pcm_routing_process_voice(mc->reg, mc->shift, 0); + msm_pcm_routing_process_voice(mc->shift, mc->rshift, 0); snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, update); } @@ -1998,14 +1998,14 @@ static int msm_routing_get_voice_stub_mixer(struct snd_kcontrol *kcontrol, mutex_lock(&routing_lock); - if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0])) + if (test_bit(mc->rshift, &msm_bedais[mc->shift].fe_sessions[0])) ucontrol->value.integer.value[0] = 1; else ucontrol->value.integer.value[0] = 0; mutex_unlock(&routing_lock); - pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + pr_debug("%s: shift %x rshift %x val %ld\n", __func__, mc->shift, mc->rshift, ucontrol->value.integer.value[0]); return 0; @@ -2022,21 +2022,21 @@ static int msm_routing_put_voice_stub_mixer(struct snd_kcontrol *kcontrol, if (ucontrol->value.integer.value[0]) { mutex_lock(&routing_lock); - set_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0]); + set_bit(mc->rshift, &msm_bedais[mc->shift].fe_sessions[0]); mutex_unlock(&routing_lock); snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, update); } else { mutex_lock(&routing_lock); - clear_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0]); + clear_bit(mc->rshift, &msm_bedais[mc->shift].fe_sessions[0]); mutex_unlock(&routing_lock); snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, update); } - pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + pr_debug("%s: shift %x rshift %x val %ld\n", __func__, mc->shift, mc->rshift, ucontrol->value.integer.value[0]); return 1; @@ -2702,8 +2702,8 @@ static int msm_routing_get_port_mixer(struct snd_kcontrol *kcontrol, struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - idx = mc->shift/(sizeof(msm_bedais[mc->reg].port_sessions[0]) * 8); - shift = mc->shift%(sizeof(msm_bedais[mc->reg].port_sessions[0]) * 8); + idx = mc->rshift/(sizeof(msm_bedais[mc->shift].port_sessions[0]) * 8); + shift = mc->rshift%(sizeof(msm_bedais[mc->shift].port_sessions[0]) * 8); if (idx >= BE_DAI_PORT_SESSIONS_IDX_MAX) { pr_err("%s: Invalid idx = %d\n", __func__, idx); @@ -2711,12 +2711,12 @@ static int msm_routing_get_port_mixer(struct snd_kcontrol *kcontrol, } if (test_bit(shift, - (unsigned long *)&msm_bedais[mc->reg].port_sessions[idx])) + (unsigned long *)&msm_bedais[mc->shift].port_sessions[idx])) ucontrol->value.integer.value[0] = 1; else ucontrol->value.integer.value[0] = 0; - pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift, + pr_debug("%s: shift %x rshift %x val %ld\n", __func__, mc->shift, mc->rshift, ucontrol->value.integer.value[0]); return 0; @@ -2729,28 +2729,28 @@ static int msm_routing_put_port_mixer(struct snd_kcontrol *kcontrol, struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - idx = mc->shift/(sizeof(msm_bedais[mc->reg].port_sessions[0]) * 8); - shift = mc->shift%(sizeof(msm_bedais[mc->reg].port_sessions[0]) * 8); + idx = mc->rshift/(sizeof(msm_bedais[mc->shift].port_sessions[0]) * 8); + shift = mc->rshift%(sizeof(msm_bedais[mc->shift].port_sessions[0]) * 8); if (idx >= BE_DAI_PORT_SESSIONS_IDX_MAX) { pr_err("%s: Invalid idx = %d\n", __func__, idx); return -EINVAL; } - pr_debug("%s: reg 0x%x shift 0x%x val %ld idx %d reminder shift %d\n", - __func__, mc->reg, mc->shift, + pr_debug("%s: shift 0x%x rshift 0x%x val %ld idx %d reminder shift %d\n", + __func__, mc->shift, mc->rshift, ucontrol->value.integer.value[0], idx, shift); if (ucontrol->value.integer.value[0]) { - afe_loopback(1, msm_bedais[mc->reg].port_id, - msm_bedais[mc->shift].port_id); + afe_loopback(1, msm_bedais[mc->shift].port_id, + msm_bedais[mc->rshift].port_id); set_bit(shift, - (unsigned long *)&msm_bedais[mc->reg].port_sessions[idx]); + (unsigned long *)&msm_bedais[mc->shift].port_sessions[idx]); } else { - afe_loopback(0, msm_bedais[mc->reg].port_id, - msm_bedais[mc->shift].port_id); + afe_loopback(0, msm_bedais[mc->shift].port_id, + msm_bedais[mc->rshift].port_id); clear_bit(shift, - (unsigned long *)&msm_bedais[mc->reg].port_sessions[idx]); + (unsigned long *)&msm_bedais[mc->shift].port_sessions[idx]); } return 1; @@ -3845,7507 +3845,9688 @@ static const struct snd_kcontrol_new voc_ext_ec_mux = static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new spdif_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SPDIF_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new slimbus_2_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_2_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_2_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_2_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_2_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SLIMBUS_2_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SLIMBUS_2_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SLIMBUS_2_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SLIMBUS_2_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SLIMBUS_2_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SLIMBUS_2_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SLIMBUS_2_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SLIMBUS_2_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SLIMBUS_2_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SLIMBUS_2_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SLIMBUS_2_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_2_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new slimbus_5_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SLIMBUS_5_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quinary_mi2s_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tertiary_mi2s_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new secondary_mi2s_rx2_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_SD1, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX_SD1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new int0_mi2s_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new int4_mi2s_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new hdmi_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new display_port_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; /* incall music delivery mixer */ static const struct snd_kcontrol_new incall_music_delivery_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new incall_music2_delivery_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new slimbus_4_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_4_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_4_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SLIMBUS_4_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SLIMBUS_4_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new slimbus_6_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new slimbus_7_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new usb_audio_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new int_bt_a2dp_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_INT_BT_A2DP_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_INT_FM_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_auxpcm_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_auxpcm_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_auxpcm_rx_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_tx_0_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_tx_0_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_0_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_tx_0_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_1_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERT_TDM_RX_4, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERT_TDM_RX_4, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERT_TDM_RX_4, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERT_TDM_RX_4, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERT_TDM_RX_4, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERT_TDM_RX_4, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERT_TDM_RX_4, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERT_TDM_RX_4, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERT_TDM_RX_4, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERT_TDM_RX_4, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERT_TDM_RX_4, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERT_TDM_RX_4, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERT_TDM_RX_4, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERT_TDM_RX_4, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERT_TDM_RX_4, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_RX_4, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_tx_0_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_1_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_0_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_tx_0_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_1_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = { - SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul1_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_TX", MSM_BACKEND_DAI_PRI_I2S_TX, + SOC_DOUBLE_EXT("PRI_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + SOC_DOUBLE_EXT("SLIM_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX, + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_TX, + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_8_TX, + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul2_mixer_controls[] = { - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX, + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_TX, + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_8_TX, + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul3_mixer_controls[] = { - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AUX_PCM_TX", MSM_BACKEND_DAI_AUXPCM_TX, + SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_AUX_PCM_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul4_mixer_controls[] = { - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul5_mixer_controls[] = { - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_AUX_PCM_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_8_TX, + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul6_mixer_controls[] = { - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_TX, + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul8_mixer_controls[] = { - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX, + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul16_mixer_controls[] = { - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX, + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AUX_PCM_TX", MSM_BACKEND_DAI_AUXPCM_TX, + SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul9_mixer_controls[] = { - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX, + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul10_mixer_controls[] = { - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX, + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AUX_PCM_TX", MSM_BACKEND_DAI_AUXPCM_TX, + SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT2_MI2S_TX", MSM_BACKEND_DAI_INT2_MI2S_TX, + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul17_mixer_controls[] = { - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul18_mixer_controls[] = { - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul19_mixer_controls[] = { - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul20_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_TX, + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0, + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1, + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2, + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3, + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_TX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_TX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_TX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_TX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul28_mixer_controls[] = { - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul29_mixer_controls[] = { - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_PRI_I2S_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new sec_mi2s_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new slimbus_6_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new usb_audio_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new display_port_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new mi2s_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new pri_mi2s_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new int0_mi2s_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new int4_mi2s_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tert_mi2s_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new quat_mi2s_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new quin_mi2s_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new sec_aux_pcm_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tert_aux_pcm_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new quat_aux_pcm_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new quin_aux_pcm_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new slimbus_7_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SLIMBUS_7_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new slimbus_8_rx_voice_mixer_controls[] = { - SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SLIMBUS_8_RX, + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_SLIMBUS_8_RX, + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_SLIMBUS_8_RX, + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SLIMBUS_8_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SLIMBUS_8_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_2_voice_mixer_controls[] = { - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new stub_rx_mixer_controls[] = { - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_EXTPROC_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_EXTPROC_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new slimbus_1_rx_mixer_controls[] = { - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SLIMBUS_1_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SLIMBUS_1_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = { - SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SLIMBUS_3_RX, + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SLIMBUS_3_RX, + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_TX_MMode1", MSM_BACKEND_DAI_PRI_I2S_TX, + SOC_DOUBLE_EXT("PRI_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("MI2S_TX_MMode1", MSM_BACKEND_DAI_MI2S_TX, + SOC_DOUBLE_EXT("MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_0_TX_MMode1", + SOC_DOUBLE_EXT("SLIM_0_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("INT_BT_SCO_TX_MMode1", + SOC_DOUBLE_EXT("INT_BT_SCO_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX_MMode1", + SOC_DOUBLE_EXT("AFE_PCM_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("AUX_PCM_TX_MMode1", + SOC_DOUBLE_EXT("AUX_PCM_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_TX_MMode1", + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_TX_MMode1", + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_MMode1", + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUIN_AUX_PCM_TX_MMode1", + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX_MMode1", + SOC_DOUBLE_EXT("PRI_MI2S_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX_MMode1", + SOC_DOUBLE_EXT("TERT_MI2S_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX_MMode1", + SOC_DOUBLE_EXT("INT3_MI2S_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_7_TX_MMode1", + SOC_DOUBLE_EXT("SLIM_7_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_8_TX_MMode1", + SOC_DOUBLE_EXT("SLIM_8_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("USB_AUDIO_TX_MMode1", MSM_BACKEND_DAI_USB_TX, + SOC_DOUBLE_EXT("USB_AUDIO_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0_MMode1", - MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0_MMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_TX_MMode2", MSM_BACKEND_DAI_PRI_I2S_TX, + SOC_DOUBLE_EXT("PRI_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("MI2S_TX_MMode2", MSM_BACKEND_DAI_MI2S_TX, + SOC_DOUBLE_EXT("MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_0_TX_MMode2", + SOC_DOUBLE_EXT("SLIM_0_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("INT_BT_SCO_TX_MMode2", + SOC_DOUBLE_EXT("INT_BT_SCO_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX_MMode2", + SOC_DOUBLE_EXT("AFE_PCM_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("AUX_PCM_TX_MMode2", + SOC_DOUBLE_EXT("AUX_PCM_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_TX_MMode2", + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_TX_MMode2", + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_MMode2", + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUIN_AUX_PCM_TX_MMode2", + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX_MMode2", + SOC_DOUBLE_EXT("PRI_MI2S_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX_MMode2", + SOC_DOUBLE_EXT("TERT_MI2S_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX_MMode2", + SOC_DOUBLE_EXT("INT3_MI2S_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_7_TX_MMode2", + SOC_DOUBLE_EXT("SLIM_7_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_8_TX_MMode2", + SOC_DOUBLE_EXT("SLIM_8_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("USB_AUDIO_TX_MMode2", + SOC_DOUBLE_EXT("USB_AUDIO_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_TX_Voip", MSM_BACKEND_DAI_PRI_I2S_TX, + SOC_DOUBLE_EXT("PRI_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("MI2S_TX_Voip", MSM_BACKEND_DAI_MI2S_TX, + SOC_DOUBLE_EXT("MI2S_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_0_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_Voip", MSM_BACKEND_DAI_INT_BT_SCO_TX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX_Voip", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("AUX_PCM_TX_Voip", MSM_BACKEND_DAI_AUXPCM_TX, + SOC_DOUBLE_EXT("AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_TX_Voip", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_TX_Voip", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_Voip", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUIN_AUX_PCM_TX_Voip", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX_Voip", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX_Voip", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX_Voip", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_7_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_7_TX, + SOC_DOUBLE_EXT("SLIM_7_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_8_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_8_TX, + SOC_DOUBLE_EXT("SLIM_8_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("USB_AUDIO_TX_Voip", MSM_BACKEND_DAI_USB_TX, + SOC_DOUBLE_EXT("USB_AUDIO_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { - SOC_SINGLE_EXT("STUB_TX_HL", MSM_BACKEND_DAI_EXTPROC_TX, + SOC_DOUBLE_EXT("STUB_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("STUB_1_TX_HL", MSM_BACKEND_DAI_EXTPROC_EC_TX, + SOC_DOUBLE_EXT("STUB_1_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_EC_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("QUIN_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SLIM_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + SOC_DOUBLE_EXT("SLIM_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_8_TX, + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), }; static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = { - SOC_SINGLE_EXT("STUB_TX_HL", MSM_BACKEND_DAI_EXTPROC_TX, + SOC_DOUBLE_EXT("STUB_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("STUB_1_TX_HL", MSM_BACKEND_DAI_EXTPROC_EC_TX, + SOC_DOUBLE_EXT("STUB_1_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_EC_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("QUIN_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SLIM_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + SOC_DOUBLE_EXT("SLIM_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_8_TX, + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), }; static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = { - SOC_SINGLE_EXT("STUB_TX_HL", MSM_BACKEND_DAI_EXTPROC_TX, + SOC_DOUBLE_EXT("STUB_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("STUB_1_TX_HL", MSM_BACKEND_DAI_EXTPROC_EC_TX, + SOC_DOUBLE_EXT("STUB_1_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_EC_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("QUIN_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SLIM_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + SOC_DOUBLE_EXT("SLIM_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_8_TX, + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), }; static const struct snd_kcontrol_new tx_qchat_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_TX_QCHAT", MSM_BACKEND_DAI_PRI_I2S_TX, + SOC_DOUBLE_EXT("PRI_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_0_TX_QCHAT", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIM_0_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX_QCHAT", - MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX_QCHAT", MSM_BACKEND_DAI_AFE_PCM_TX, + SOC_DOUBLE_EXT("AFE_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("AUX_PCM_TX_QCHAT", MSM_BACKEND_DAI_AUXPCM_TX, + SOC_DOUBLE_EXT("AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_TX_QCHAT", MSM_BACKEND_DAI_SEC_AUXPCM_TX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_TX_QCHAT", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_TX_QCHAT", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("QUIN_AUX_PCM_TX_QCHAT", MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("MI2S_TX_QCHAT", MSM_BACKEND_DAI_MI2S_TX, + SOC_DOUBLE_EXT("MI2S_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX_QCHAT", MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("PRI_MI2S_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX_QCHAT", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX_QCHAT", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_7_TX_QCHAT", MSM_BACKEND_DAI_SLIMBUS_7_TX, + SOC_DOUBLE_EXT("SLIM_7_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("SLIM_8_TX_QCHAT", MSM_BACKEND_DAI_SLIMBUS_8_TX, + SOC_DOUBLE_EXT("SLIM_8_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("USB_AUDIO_TX_QCHAT", MSM_BACKEND_DAI_USB_TX, + SOC_DOUBLE_EXT("USB_AUDIO_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new int0_mi2s_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_BACKEND_DAI_INT3_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_INT0_MI2S_RX, + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new int4_mi2s_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_BACKEND_DAI_INT3_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_INT4_MI2S_RX, + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_AUXPCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_QUIN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_MI2S_RX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("PRI_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_PRI_MI2S_RX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_RX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("SEC_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_SECONDARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_RX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("TERT_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_TERTIARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_RX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_DOUBLE_EXT("QUAT_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_MI2S_RX", MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + SOC_DOUBLE_EXT("QUIN_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, +MSM_BACKEND_DAI_QUINARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new aux_pcm_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_AUXPCM_RX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sec_auxpcm_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new tert_auxpcm_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new quat_auxpcm_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new quin_auxpcm_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("QUIN_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_BACKEND_DAI_QUIN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sbus_1_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sbus_3_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("INTERNAL_BT_SCO_RX", MSM_BACKEND_DAI_SLIMBUS_3_RX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, MSM_BACKEND_DAI_INT_BT_SCO_RX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_3_RX, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_RX", MSM_BACKEND_DAI_SLIMBUS_3_RX, + SOC_DOUBLE_EXT("AFE_PCM_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, MSM_BACKEND_DAI_AFE_PCM_RX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_RX", MSM_BACKEND_DAI_SLIMBUS_3_RX, + SOC_DOUBLE_EXT("AUX_PCM_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, MSM_BACKEND_DAI_AUXPCM_RX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_0_RX", MSM_BACKEND_DAI_SLIMBUS_3_RX, + SOC_DOUBLE_EXT("SLIM_0_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, MSM_BACKEND_DAI_SLIMBUS_0_RX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sbus_6_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SLIMBUS_6_RX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new bt_sco_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_INT_BT_SCO_RX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new afe_pcm_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_AFE_PCM_RX, + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new hdmi_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_HDMI_RX, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new display_port_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_DISPLAY_PORT_RX, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sec_i2s_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_SEC_I2S_RX, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new mi2s_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("SLIM_1_TX", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_RX, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new primary_mi2s_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_MI2S_RX, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new usb_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_RX, + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, MSM_BACKEND_DAI_USB_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new quat_mi2s_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new quin_mi2s_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_0_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_1_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_2_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_3_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_0_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_1_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_2_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_3_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_0_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_1_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_2_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_3_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_0_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_1_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_2_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_3_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_0_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_0, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_1_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_1, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_2_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_2, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_3_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_0", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_1", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_2", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_TDM_TX_3", MSM_BACKEND_DAI_QUIN_TDM_RX_3, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new tert_mi2s_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sec_mi2s_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new lsm1_mixer_controls[] = { - SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm2_mixer_controls[] = { - SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + SOC_DOUBLE_EXT("SLIMBUS_1_TX", + SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm3_mixer_controls[] = { - SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm4_mixer_controls[] = { - SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm5_mixer_controls[] = { - SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm6_mixer_controls[] = { - SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm7_mixer_controls[] = { - SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm8_mixer_controls[] = { - SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX, + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX, + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX, + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX, + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), - SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), }; -- GitLab From 145e63390c56445496fda8709f301996760e572e Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 15 Feb 2018 17:46:25 -0800 Subject: [PATCH 0257/1645] dsp: q6asm: check for buffer size before read Check for debugfs ops buf size passed before reading to avoid reading out of bounds. Change-Id: Idd5e755ac16448af5751e2f3381097f234e74a74 Signed-off-by: Karthikeyan Mani --- dsp/q6asm.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 55d82b7ce93d..a12347966f5a 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -284,6 +284,11 @@ static ssize_t audio_output_latency_dbgfs_read(struct file *file, pr_err("%s: out_buffer is null\n", __func__); return 0; } + if (count < OUT_BUFFER_SIZE) { + pr_err("%s: read size %d exceeds buf size %zd\n", __func__, + OUT_BUFFER_SIZE, count); + return 0; + } snprintf(out_buffer, OUT_BUFFER_SIZE, "%ld,%ld,%ld,%ld,%ld,%ld,", out_cold_tv.tv_sec, out_cold_tv.tv_usec, out_warm_tv.tv_sec, out_warm_tv.tv_usec, out_cont_tv.tv_sec, out_cont_tv.tv_usec); @@ -336,6 +341,11 @@ static ssize_t audio_input_latency_dbgfs_read(struct file *file, pr_err("%s: in_buffer is null\n", __func__); return 0; } + if (count < IN_BUFFER_SIZE) { + pr_err("%s: read size %d exceeds buf size %zd\n", __func__, + IN_BUFFER_SIZE, count); + return 0; + } snprintf(in_buffer, IN_BUFFER_SIZE, "%ld,%ld,", in_cont_tv.tv_sec, in_cont_tv.tv_usec); return simple_read_from_buffer(buf, IN_BUFFER_SIZE, ppos, -- GitLab From e3842cf831b73f093b65e053a7f29f9de6617fb8 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 31 Mar 2018 02:27:42 +0530 Subject: [PATCH 0258/1645] ASoC: Add audio support for sdmshrike Add audio support for sdmshrike. Change-Id: I0b86ab7b123a3215617b81a645202785f6810d02 Signed-off-by: Sudheer Papothi --- Makefile | 8 ++++++++ asoc/Kbuild | 5 +++++ asoc/codecs/Kbuild | 5 +++++ asoc/codecs/aqt1000/Kbuild | 6 ++++++ asoc/codecs/wcd934x/Kbuild | 5 +++++ asoc/codecs/wcd9360/Kbuild | 6 ++++++ dsp/Kbuild | 5 +++++ dsp/codecs/Kbuild | 5 +++++ ipc/Kbuild | 9 +++++++++ soc/Kbuild | 5 +++++ 10 files changed, 59 insertions(+) diff --git a/Makefile b/Makefile index 4e123b6de43b..73185c98a3a9 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,10 @@ ifeq ($(CONFIG_ARCH_SDM855), y) include $(srctree)/techpack/audio/config/sdm855auto.conf export endif +ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) +include $(srctree)/techpack/audio/config/sdm855auto.conf +export +endif # Use USERINCLUDE when you must reference the UAPI directories only. USERINCLUDE += \ @@ -42,6 +46,10 @@ ifeq ($(CONFIG_ARCH_SDM855), y) LINUXINCLUDE += \ -include $(srctree)/techpack/audio/config/sdm855autoconf.h endif +ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) +LINUXINCLUDE += \ + -include $(srctree)/techpack/audio/config/sdm855autoconf.h +endif obj-y += asoc/ obj-y += dsp/ diff --git a/asoc/Kbuild b/asoc/Kbuild index eec59475d095..1a6d45a88871 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -35,6 +35,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h endif + ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 01a6e2d74b41..ef817fc7c6fb 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -34,6 +34,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h endif + ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/asoc/codecs/aqt1000/Kbuild b/asoc/codecs/aqt1000/Kbuild index f982951ecff7..b942988dc4ca 100644 --- a/asoc/codecs/aqt1000/Kbuild +++ b/asoc/codecs/aqt1000/Kbuild @@ -28,6 +28,12 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h endif + + ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index 60b24853e37f..e3d57b306ad4 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -36,6 +36,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h endif + ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/asoc/codecs/wcd9360/Kbuild b/asoc/codecs/wcd9360/Kbuild index a1b5fe44bac6..ddd64e057190 100644 --- a/asoc/codecs/wcd9360/Kbuild +++ b/asoc/codecs/wcd9360/Kbuild @@ -21,6 +21,12 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h endif + + ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/dsp/Kbuild b/dsp/Kbuild index df73215c4ef4..0a0490d438a9 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -34,6 +34,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h endif + ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif endif diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 0f2adf71f9f5..12e9cf05d920 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -35,6 +35,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h endif + ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/ipc/Kbuild b/ipc/Kbuild index 3cc021c457bd..4ad14cfbc6d2 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -20,6 +20,10 @@ ifeq ($(CONFIG_ARCH_SDM855), y) TARGET_KERNEL_VERSION := 4.14 endif +ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) + TARGET_KERNEL_VERSION := 4.14 +endif + KDIR := $(TOP)/kernel/msm-$(TARGET_KERNEL_VERSION) ifeq ($(KERNEL_BUILD), 1) @@ -47,6 +51,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h endif + ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/soc/Kbuild b/soc/Kbuild index 36a2c88d5197..f61ecdc03f45 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -34,6 +34,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h endif + ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) + include $(AUDIO_ROOT)/config/sdm855auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + endif endif # As per target team, build is done as follows: -- GitLab From f58e5fcf7210992e2a41fd0bc68e6dd820654320 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Wed, 11 Apr 2018 14:10:09 -0700 Subject: [PATCH 0259/1645] audio-kernel: update chipset name Update all audio drivers to use updated chipset name in architecture specific configurations and the device tree compatible strings. Change-Id: Ib1abe643c6914c1b0b57ef110c7b60e23e356d97 Signed-off-by: Banajit Goswami --- Makefile | 4 ++-- asoc/Kbuild | 2 +- asoc/codecs/Kbuild | 2 +- asoc/codecs/aqt1000/Kbuild | 2 +- asoc/codecs/wcd934x/Kbuild | 2 +- asoc/codecs/wcd9360/Kbuild | 2 +- asoc/sdm855.c | 6 +++--- dsp/Kbuild | 2 +- dsp/codecs/Kbuild | 2 +- ipc/Kbuild | 4 ++-- soc/Kbuild | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 4e123b6de43b..8143e3c24748 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ ifeq ($(CONFIG_ARCH_SDXPOORWILLS), y) include $(srctree)/techpack/audio/config/sdxpoorwillsauto.conf export endif -ifeq ($(CONFIG_ARCH_SDM855), y) +ifeq ($(CONFIG_ARCH_SM8150), y) include $(srctree)/techpack/audio/config/sdm855auto.conf export endif @@ -38,7 +38,7 @@ ifeq ($(CONFIG_ARCH_SDXPOORWILLS), y) LINUXINCLUDE += \ -include $(srctree)/techpack/audio/config/sdxpoorwillsautoconf.h endif -ifeq ($(CONFIG_ARCH_SDM855), y) +ifeq ($(CONFIG_ARCH_SM8150), y) LINUXINCLUDE += \ -include $(srctree)/techpack/audio/config/sdm855autoconf.h endif diff --git a/asoc/Kbuild b/asoc/Kbuild index eec59475d095..53694440385c 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -30,7 +30,7 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif - ifeq ($(CONFIG_ARCH_SDM855), y) + ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sdm855auto.conf export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 01a6e2d74b41..c42cb7a268c0 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -29,7 +29,7 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif - ifeq ($(CONFIG_ARCH_SDM855), y) + ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sdm855auto.conf export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h diff --git a/asoc/codecs/aqt1000/Kbuild b/asoc/codecs/aqt1000/Kbuild index f982951ecff7..6ee5d3f81184 100644 --- a/asoc/codecs/aqt1000/Kbuild +++ b/asoc/codecs/aqt1000/Kbuild @@ -23,7 +23,7 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif - ifeq ($(CONFIG_ARCH_SDM855), y) + ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sdm855auto.conf export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index 60b24853e37f..48c9ccdc0f1d 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -31,7 +31,7 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif - ifeq ($(CONFIG_ARCH_SDM855), y) + ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sdm855auto.conf export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h diff --git a/asoc/codecs/wcd9360/Kbuild b/asoc/codecs/wcd9360/Kbuild index a1b5fe44bac6..d4f5406337a7 100644 --- a/asoc/codecs/wcd9360/Kbuild +++ b/asoc/codecs/wcd9360/Kbuild @@ -16,7 +16,7 @@ ifeq ($(KERNEL_BUILD), 1) endif ifeq ($(KERNEL_BUILD), 0) - ifeq ($(CONFIG_ARCH_SDM855), y) + ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sdm855auto.conf export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h diff --git a/asoc/sdm855.c b/asoc/sdm855.c index 58808462a3ae..e45bbb4202b2 100644 --- a/asoc/sdm855.c +++ b/asoc/sdm855.c @@ -6746,11 +6746,11 @@ struct snd_soc_card snd_soc_card_stub_msm = { }; static const struct of_device_id sdm855_asoc_machine_of_match[] = { - { .compatible = "qcom,sdm855-asoc-snd-pahu", + { .compatible = "qcom,sm8150-asoc-snd-pahu", .data = "pahu_codec"}, - { .compatible = "qcom,sdm855-asoc-snd-tavil", + { .compatible = "qcom,sm8150-asoc-snd-tavil", .data = "tavil_codec"}, - { .compatible = "qcom,sdm855-asoc-snd-stub", + { .compatible = "qcom,sm8150-asoc-snd-stub", .data = "stub_codec"}, {}, }; diff --git a/dsp/Kbuild b/dsp/Kbuild index df73215c4ef4..9b4399424050 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -29,7 +29,7 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif - ifeq ($(CONFIG_ARCH_SDM855), y) + ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sdm855auto.conf export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 0f2adf71f9f5..96875c6557d7 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -30,7 +30,7 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif - ifeq ($(CONFIG_ARCH_SDM855), y) + ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sdm855auto.conf export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h diff --git a/ipc/Kbuild b/ipc/Kbuild index 3cc021c457bd..b666875a87fd 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -16,7 +16,7 @@ endif ifeq ($(CONFIG_ARCH_SDM670), y) TARGET_KERNEL_VERSION := 4.9 endif -ifeq ($(CONFIG_ARCH_SDM855), y) +ifeq ($(CONFIG_ARCH_SM8150), y) TARGET_KERNEL_VERSION := 4.14 endif @@ -42,7 +42,7 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif - ifeq ($(CONFIG_ARCH_SDM855), y) + ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sdm855auto.conf export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h diff --git a/soc/Kbuild b/soc/Kbuild index 36a2c88d5197..f2b884013d04 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -29,7 +29,7 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif - ifeq ($(CONFIG_ARCH_SDM855), y) + ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sdm855auto.conf export INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h -- GitLab From cb3ee0e10be4dfccbf712f0bdafce99b47763fd4 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Fri, 30 Mar 2018 13:17:39 -0700 Subject: [PATCH 0260/1645] dsp: adsp-loader: avoid updating APR state after ADSP loading APR state update should happen only after ADSP up notification recieved by APSS, and not just after ADSP is loaded and booted up. Avoid setting APR state to loaded after PIL loading of ADSP image is complete. Change-Id: I9b9f073279c306562e427ec2c7e73dfa7d71f956 Signed-off-by: Banajit Goswami --- dsp/adsp-loader.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dsp/adsp-loader.c b/dsp/adsp-loader.c index 07eeea4e4c8b..cc995db9069b 100644 --- a/dsp/adsp-loader.c +++ b/dsp/adsp-loader.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014, 2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014, 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -134,9 +134,6 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work) __func__); goto fail; } - - /* Set the state of the ADSP in APR driver */ - apr_set_q6_state(APR_SUBSYS_LOADED); } else if (adsp_state == APR_SUBSYS_LOADED) { dev_dbg(&pdev->dev, "%s: ADSP state = %x\n", __func__, adsp_state); -- GitLab From 60c105d5c9f10db335fcb59c650602a1d00e6611 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Thu, 12 Apr 2018 12:43:13 -0700 Subject: [PATCH 0261/1645] audio-kernel: update chipset name Update all audio drivers to use updated chipset name in files, functions, architecture specific configurations and the device tree compatible strings. Change-Id: I507948866213ddb8806edea71a57c1f29ce7e71b Signed-off-by: Xiaoyu Ye --- Makefile | 8 +-- asoc/Android.mk | 2 +- asoc/Kbuild | 16 ++--- asoc/codecs/Android.mk | 2 +- asoc/codecs/Kbuild | 8 +-- asoc/codecs/aqt1000/Kbuild | 8 +-- asoc/codecs/wcd934x/Android.mk | 2 +- asoc/codecs/wcd934x/Kbuild | 8 +-- asoc/codecs/wcd9360/Android.mk | 2 +- asoc/codecs/wcd9360/Kbuild | 8 +-- asoc/{sdm855.c => sm8150.c} | 60 +++++++++---------- config/{sdm855auto.conf => sm8150auto.conf} | 2 +- config/{sdm855autoconf.h => sm8150autoconf.h} | 2 +- dsp/Android.mk | 2 +- dsp/Kbuild | 8 +-- dsp/codecs/Android.mk | 2 +- dsp/codecs/Kbuild | 8 +-- ipc/Android.mk | 2 +- ipc/Kbuild | 8 +-- soc/Android.mk | 2 +- soc/Kbuild | 8 +-- 21 files changed, 84 insertions(+), 84 deletions(-) rename asoc/{sdm855.c => sm8150.c} (99%) rename config/{sdm855auto.conf => sm8150auto.conf} (97%) rename config/{sdm855autoconf.h => sm8150autoconf.h} (98%) diff --git a/Makefile b/Makefile index 69f3795c0080..fbf0ee1eab5e 100644 --- a/Makefile +++ b/Makefile @@ -12,11 +12,11 @@ include $(srctree)/techpack/audio/config/sdxpoorwillsauto.conf export endif ifeq ($(CONFIG_ARCH_SM8150), y) -include $(srctree)/techpack/audio/config/sdm855auto.conf +include $(srctree)/techpack/audio/config/sm8150auto.conf export endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) -include $(srctree)/techpack/audio/config/sdm855auto.conf +include $(srctree)/techpack/audio/config/sm8150auto.conf export endif @@ -44,11 +44,11 @@ LINUXINCLUDE += \ endif ifeq ($(CONFIG_ARCH_SM8150), y) LINUXINCLUDE += \ - -include $(srctree)/techpack/audio/config/sdm855autoconf.h + -include $(srctree)/techpack/audio/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) LINUXINCLUDE += \ - -include $(srctree)/techpack/audio/config/sdm855autoconf.h + -include $(srctree)/techpack/audio/config/sm8150autoconf.h endif obj-y += asoc/ diff --git a/asoc/Android.mk b/asoc/Android.mk index 6154917aafb9..cb2ce0c9f24f 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -15,7 +15,7 @@ endif ifeq ($(call is-board-platform,msmnile),true) TARGET := msmnile -AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m +AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif AUDIO_CHIPSET := audio diff --git a/asoc/Kbuild b/asoc/Kbuild index 453452c6215c..aea56621abbc 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -31,14 +31,14 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif @@ -90,9 +90,9 @@ ifdef CONFIG_SND_SOC_MACHINE_SDM845 MACHINE_OBJS += sdm845.o endif -# for SDM855 sound card driver -ifdef CONFIG_SND_SOC_SDM855 - MACHINE_OBJS += sdm855.o +# for SM8150 sound card driver +ifdef CONFIG_SND_SOC_SM8150 + MACHINE_OBJS += sm8150.o endif ifdef CONFIG_SND_SOC_CPE @@ -183,7 +183,7 @@ platform_dlkm-y := $(PLATFORM_OBJS) obj-$(CONFIG_SND_SOC_MACHINE_SDM845) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) -obj-$(CONFIG_SND_SOC_SDM855) += machine_dlkm.o +obj-$(CONFIG_SND_SOC_SM8150) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) obj-$(CONFIG_SND_SOC_EXT_CODEC) += machine_dlkm.o diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index 152f61705ae5..803e4809c30a 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -12,7 +12,7 @@ AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif ifeq ($(call is-board-platform,msmnile),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m +AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif AUDIO_CHIPSET := audio diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 412ec681c710..9f3cfce55288 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -30,14 +30,14 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif diff --git a/asoc/codecs/aqt1000/Kbuild b/asoc/codecs/aqt1000/Kbuild index 948471442f2a..6523ce6d6b09 100644 --- a/asoc/codecs/aqt1000/Kbuild +++ b/asoc/codecs/aqt1000/Kbuild @@ -24,15 +24,15 @@ ifeq ($(KERNEL_BUILD), 0) endif ifeq ($(CONFIG_ARCH_SM8150), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif diff --git a/asoc/codecs/wcd934x/Android.mk b/asoc/codecs/wcd934x/Android.mk index 200f6c36a6ab..313d51355d25 100644 --- a/asoc/codecs/wcd934x/Android.mk +++ b/asoc/codecs/wcd934x/Android.mk @@ -8,7 +8,7 @@ AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m endif ifeq ($(call is-board-platform,msmnile),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m +AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index ee8320635668..256f518535f3 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -32,14 +32,14 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif diff --git a/asoc/codecs/wcd9360/Android.mk b/asoc/codecs/wcd9360/Android.mk index bf65cffe8a4b..bee0364ecd41 100644 --- a/asoc/codecs/wcd9360/Android.mk +++ b/asoc/codecs/wcd9360/Android.mk @@ -4,7 +4,7 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m +AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif AUDIO_CHIPSET := audio diff --git a/asoc/codecs/wcd9360/Kbuild b/asoc/codecs/wcd9360/Kbuild index d9053a34a079..6bba0c525599 100644 --- a/asoc/codecs/wcd9360/Kbuild +++ b/asoc/codecs/wcd9360/Kbuild @@ -17,15 +17,15 @@ endif ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SM8150), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif diff --git a/asoc/sdm855.c b/asoc/sm8150.c similarity index 99% rename from asoc/sdm855.c rename to asoc/sm8150.c index e45bbb4202b2..e561ad5d7353 100644 --- a/asoc/sdm855.c +++ b/asoc/sm8150.c @@ -40,9 +40,9 @@ #include "codecs/wsa881x.h" #include "codecs/wcd-mbhc-v2.h" -#define DRV_NAME "sdm855-asoc-snd" +#define DRV_NAME "sm8150-asoc-snd" -#define __CHIPSET__ "SDM855 " +#define __CHIPSET__ "SM8150 " #define MSM_DAILINK_NAME(name) (__CHIPSET__#name) #define DEV_NAME_STR_LEN 32 @@ -3740,7 +3740,7 @@ static int msm_adsp_power_up_config(struct snd_soc_codec *codec, return ret; } -static int sdm855_notifier_service_cb(struct notifier_block *this, +static int sm8150_notifier_service_cb(struct notifier_block *this, unsigned long opcode, void *ptr) { int ret; @@ -3798,7 +3798,7 @@ static int sdm855_notifier_service_cb(struct notifier_block *this, } static struct notifier_block service_nb = { - .notifier_call = sdm855_notifier_service_cb, + .notifier_call = sm8150_notifier_service_cb, .priority = -INT_MAX, }; @@ -4509,7 +4509,7 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } -static int sdm855_tdm_snd_hw_params(struct snd_pcm_substream *substream, +static int sm8150_tdm_snd_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -4625,7 +4625,7 @@ static int sdm855_tdm_snd_hw_params(struct snd_pcm_substream *substream, return ret; } -static int sdm855_tdm_snd_startup(struct snd_pcm_substream *substream) +static int sm8150_tdm_snd_startup(struct snd_pcm_substream *substream) { int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -4646,7 +4646,7 @@ static int sdm855_tdm_snd_startup(struct snd_pcm_substream *substream) return ret; } -static void sdm855_tdm_snd_shutdown(struct snd_pcm_substream *substream) +static void sm8150_tdm_snd_shutdown(struct snd_pcm_substream *substream) { int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -4665,10 +4665,10 @@ static void sdm855_tdm_snd_shutdown(struct snd_pcm_substream *substream) } } -static struct snd_soc_ops sdm855_tdm_be_ops = { - .hw_params = sdm855_tdm_snd_hw_params, - .startup = sdm855_tdm_snd_startup, - .shutdown = sdm855_tdm_snd_shutdown +static struct snd_soc_ops sm8150_tdm_be_ops = { + .hw_params = sm8150_tdm_snd_hw_params, + .startup = sm8150_tdm_snd_startup, + .shutdown = sm8150_tdm_snd_shutdown }; static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) @@ -5630,7 +5630,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_playback = 1, .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &sdm855_tdm_be_ops, + .ops = &sm8150_tdm_be_ops, .ignore_suspend = 1, .ignore_pmdown_time = 1, }, @@ -5645,7 +5645,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &sdm855_tdm_be_ops, + .ops = &sm8150_tdm_be_ops, .ignore_suspend = 1, }, { @@ -5659,7 +5659,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_playback = 1, .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &sdm855_tdm_be_ops, + .ops = &sm8150_tdm_be_ops, .ignore_suspend = 1, .ignore_pmdown_time = 1, }, @@ -5674,7 +5674,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &sdm855_tdm_be_ops, + .ops = &sm8150_tdm_be_ops, .ignore_suspend = 1, }, { @@ -5688,7 +5688,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_playback = 1, .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &sdm855_tdm_be_ops, + .ops = &sm8150_tdm_be_ops, .ignore_suspend = 1, .ignore_pmdown_time = 1, }, @@ -5703,7 +5703,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &sdm855_tdm_be_ops, + .ops = &sm8150_tdm_be_ops, .ignore_suspend = 1, }, { @@ -5717,7 +5717,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_playback = 1, .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, - .ops = &sdm855_tdm_be_ops, + .ops = &sm8150_tdm_be_ops, .ignore_suspend = 1, .ignore_pmdown_time = 1, }, @@ -5732,7 +5732,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &sdm855_tdm_be_ops, + .ops = &sm8150_tdm_be_ops, .ignore_suspend = 1, }, }; @@ -6532,11 +6532,11 @@ static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) } struct snd_soc_card snd_soc_card_pahu_msm = { - .name = "sdm855-pahu-snd-card", + .name = "sm8150-pahu-snd-card", }; struct snd_soc_card snd_soc_card_tavil_msm = { - .name = "sdm855-tavil-snd-card", + .name = "sm8150-tavil-snd-card", .late_probe = msm_snd_card_tavil_late_probe, }; @@ -6742,10 +6742,10 @@ static struct snd_soc_dai_link msm_stub_dai_links[ ARRAY_SIZE(msm_stub_be_dai_links)]; struct snd_soc_card snd_soc_card_stub_msm = { - .name = "sdm855-stub-snd-card", + .name = "sm8150-stub-snd-card", }; -static const struct of_device_id sdm855_asoc_machine_of_match[] = { +static const struct of_device_id sm8150_asoc_machine_of_match[] = { { .compatible = "qcom,sm8150-asoc-snd-pahu", .data = "pahu_codec"}, { .compatible = "qcom,sm8150-asoc-snd-tavil", @@ -6763,7 +6763,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) int total_links; const struct of_device_id *match; - match = of_match_node(sdm855_asoc_machine_of_match, dev->of_node); + match = of_match_node(sm8150_asoc_machine_of_match, dev->of_node); if (!match) { dev_err(dev, "%s: No DT match found for sound card\n", __func__); @@ -7327,7 +7327,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) msm_i2s_auxpcm_init(pdev); is_initial_boot = true; - ret = audio_notifier_register("sdm855", AUDIO_NOTIFIER_ADSP_DOMAIN, + ret = audio_notifier_register("sm8150", AUDIO_NOTIFIER_ADSP_DOMAIN, &service_nb); if (ret < 0) pr_err("%s: Audio notifier register failed ret = %d\n", @@ -7342,26 +7342,26 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) static int msm_asoc_machine_remove(struct platform_device *pdev) { - audio_notifier_deregister("sdm855"); + audio_notifier_deregister("sm8150"); msm_i2s_auxpcm_deinit(); msm_release_pinctrl(pdev); return 0; } -static struct platform_driver sdm855_asoc_machine_driver = { +static struct platform_driver sm8150_asoc_machine_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, - .of_match_table = sdm855_asoc_machine_of_match, + .of_match_table = sm8150_asoc_machine_of_match, }, .probe = msm_asoc_machine_probe, .remove = msm_asoc_machine_remove, }; -module_platform_driver(sdm855_asoc_machine_driver); +module_platform_driver(sm8150_asoc_machine_driver); MODULE_DESCRIPTION("ALSA SoC msm"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:" DRV_NAME); -MODULE_DEVICE_TABLE(of, sdm855_asoc_machine_of_match); +MODULE_DEVICE_TABLE(of, sm8150_asoc_machine_of_match); diff --git a/config/sdm855auto.conf b/config/sm8150auto.conf similarity index 97% rename from config/sdm855auto.conf rename to config/sm8150auto.conf index cfddf95ce419..f00155f4b066 100644 --- a/config/sdm855auto.conf +++ b/config/sm8150auto.conf @@ -23,7 +23,7 @@ CONFIG_MSM_QDSP6_PDR=m CONFIG_MSM_QDSP6_NOTIFIER=m CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m -CONFIG_SND_SOC_SDM855=m +CONFIG_SND_SOC_SM8150=m CONFIG_MSM_GLINK_SPI_XPRT=m CONFIG_WCD_DSP_GLINK=m CONFIG_SOUNDWIRE=m diff --git a/config/sdm855autoconf.h b/config/sm8150autoconf.h similarity index 98% rename from config/sdm855autoconf.h rename to config/sm8150autoconf.h index 9906d4b0361a..fbaca24adae2 100644 --- a/config/sdm855autoconf.h +++ b/config/sm8150autoconf.h @@ -34,7 +34,7 @@ #define CONFIG_MSM_QDSP6_PDR 1 #define CONFIG_MSM_QDSP6_NOTIFIER 1 #define CONFIG_SND_SOC_MSM_HOSTLESS_PCM 1 -#define CONFIG_SND_SOC_SDM855 1 +#define CONFIG_SND_SOC_SM8150 1 #define CONFIG_MSM_GLINK_SPI_XPRT 1 #define CONFIG_WCD_DSP_GLINK 1 #define CONFIG_SOUNDWIRE 1 diff --git a/dsp/Android.mk b/dsp/Android.mk index cad30c8c9306..281ed8786e5e 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -12,7 +12,7 @@ AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif ifeq ($(call is-board-platform,msmnile),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m +AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif AUDIO_CHIPSET := audio diff --git a/dsp/Kbuild b/dsp/Kbuild index 11f63dc14e13..348e2ee39ea2 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -30,14 +30,14 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif diff --git a/dsp/codecs/Android.mk b/dsp/codecs/Android.mk index 50ec167bbdd7..a2fd453d91a6 100644 --- a/dsp/codecs/Android.mk +++ b/dsp/codecs/Android.mk @@ -12,7 +12,7 @@ AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif ifeq ($(call is-board-platform,msmnile),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m +AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif AUDIO_CHIPSET := audio diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 09d772606252..cc9a2db127e3 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -31,14 +31,14 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif diff --git a/ipc/Android.mk b/ipc/Android.mk index e6ad34678180..38b215f117bc 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -12,7 +12,7 @@ AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif ifeq ($(call is-board-platform,msmnile),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m +AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif AUDIO_CHIPSET := audio diff --git a/ipc/Kbuild b/ipc/Kbuild index a9bda63f4b81..afcb967fd989 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -47,14 +47,14 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif diff --git a/soc/Android.mk b/soc/Android.mk index fa2569a318a7..f92e238ff97e 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -12,7 +12,7 @@ AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif ifeq ($(call is-board-platform,msmnile),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m +AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif AUDIO_CHIPSET := audio diff --git a/soc/Kbuild b/soc/Kbuild index 8339028a5abf..9007b8e217a3 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -30,14 +30,14 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) - include $(AUDIO_ROOT)/config/sdm855auto.conf + include $(AUDIO_ROOT)/config/sm8150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif -- GitLab From 19a5e41637760cf8de8027419810654f0aa164e9 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Mon, 16 Apr 2018 18:44:38 -0700 Subject: [PATCH 0262/1645] codecs: wcd_spi: do not use on-stack memory for any transfers Currently, for some small (1/4/8 bytes) transfers, the driver uses on-stack memory to perform the transfer. This is not safe as the underlying master/dma driver could try to map/dma this memory. Change makes sure to never use on-stack memory for any transfers. Change-Id: I6b157e26ea7ca9f865004a87153c658756f6c368 Signed-off-by: Bhalchandra Gajare Signed-off-by: Xiaoyu Ye --- asoc/codecs/wcd-spi.c | 81 ++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 27 deletions(-) diff --git a/asoc/codecs/wcd-spi.c b/asoc/codecs/wcd-spi.c index a25c9a6141ab..bb9333485e3b 100644 --- a/asoc/codecs/wcd-spi.c +++ b/asoc/codecs/wcd-spi.c @@ -242,6 +242,7 @@ static int wcd_spi_read_single(struct spi_device *spi, struct spi_transfer *tx_xfer = &wcd_spi->xfer2[0]; struct spi_transfer *rx_xfer = &wcd_spi->xfer2[1]; u8 *tx_buf = wcd_spi->tx_buf; + u8 *rx_buf = wcd_spi->rx_buf; u32 frame = 0; int ret; @@ -264,10 +265,15 @@ static int wcd_spi_read_single(struct spi_device *spi, tx_xfer->len = WCD_SPI_READ_SINGLE_LEN; wcd_spi_reinit_xfer(rx_xfer); - rx_xfer->rx_buf = val; + rx_xfer->rx_buf = rx_buf; rx_xfer->len = sizeof(*val); ret = spi_sync(spi, &wcd_spi->msg2); + if (ret) + dev_err(&spi->dev, "%s: spi_sync failed, err %d\n", + __func__, ret); + else + memcpy((u8*) val, rx_buf, sizeof(*val)); return ret; } @@ -319,22 +325,22 @@ static int wcd_spi_write_single(struct spi_device *spi, { struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); struct spi_transfer *xfer = &wcd_spi->xfer1; - u8 buf[WCD_SPI_WRITE_SINGLE_LEN]; + u8 *tx_buf = wcd_spi->tx_buf; u32 frame = 0; dev_dbg(&spi->dev, "%s: remote_addr = 0x%x, val = 0x%x\n", __func__, remote_addr, val); - memset(buf, 0, WCD_SPI_WRITE_SINGLE_LEN); + memset(tx_buf, 0, WCD_SPI_WRITE_SINGLE_LEN); frame |= WCD_SPI_WRITE_FRAME_OPCODE; frame |= (remote_addr & WCD_CMD_ADDR_MASK); frame = cpu_to_be32(frame); - memcpy(buf, &frame, sizeof(frame)); - memcpy(buf + sizeof(frame), &val, sizeof(val)); + memcpy(tx_buf, &frame, sizeof(frame)); + memcpy(tx_buf + sizeof(frame), &val, sizeof(val)); wcd_spi_reinit_xfer(xfer); - xfer->tx_buf = buf; + xfer->tx_buf = tx_buf; xfer->len = WCD_SPI_WRITE_SINGLE_LEN; return spi_sync(spi, &wcd_spi->msg1); @@ -487,21 +493,26 @@ static int wcd_spi_transfer_split(struct spi_device *spi, static int wcd_spi_cmd_nop(struct spi_device *spi) { - u8 nop = WCD_SPI_CMD_NOP; + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + u8 *tx_buf = wcd_spi->tx_buf; - return spi_write(spi, &nop, WCD_SPI_CMD_NOP_LEN); + tx_buf[0] = WCD_SPI_CMD_NOP; + + return spi_write(spi, tx_buf, WCD_SPI_CMD_NOP_LEN); } static int wcd_spi_cmd_clkreq(struct spi_device *spi) { struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); struct spi_transfer *xfer = &wcd_spi->xfer1; + u8 *tx_buf = wcd_spi->tx_buf; u8 cmd[WCD_SPI_CMD_CLKREQ_LEN] = { WCD_SPI_CMD_CLKREQ, 0xBA, 0x80, 0x00}; + memcpy(tx_buf, cmd, WCD_SPI_CMD_CLKREQ_LEN); wcd_spi_reinit_xfer(xfer); - xfer->tx_buf = cmd; + xfer->tx_buf = tx_buf; xfer->len = WCD_SPI_CMD_CLKREQ_LEN; xfer->delay_usecs = WCD_SPI_CLKREQ_DELAY_USECS; @@ -510,9 +521,12 @@ static int wcd_spi_cmd_clkreq(struct spi_device *spi) static int wcd_spi_cmd_wr_en(struct spi_device *spi) { - u8 wr_en = WCD_SPI_CMD_WREN; + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + u8 *tx_buf = wcd_spi->tx_buf; + + tx_buf[0] = WCD_SPI_CMD_WREN; - return spi_write(spi, &wr_en, WCD_SPI_CMD_WREN_LEN); + return spi_write(spi, tx_buf, WCD_SPI_CMD_WREN_LEN); } static int wcd_spi_cmd_rdsr(struct spi_device *spi, @@ -521,19 +535,19 @@ static int wcd_spi_cmd_rdsr(struct spi_device *spi, struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); struct spi_transfer *tx_xfer = &wcd_spi->xfer2[0]; struct spi_transfer *rx_xfer = &wcd_spi->xfer2[1]; - u8 rdsr_cmd; - u32 status = 0; + u8 *tx_buf = wcd_spi->tx_buf; + u8 *rx_buf = wcd_spi->rx_buf; int ret; - rdsr_cmd = WCD_SPI_CMD_RDSR; + tx_buf[0] = WCD_SPI_CMD_RDSR; wcd_spi_reinit_xfer(tx_xfer); - tx_xfer->tx_buf = &rdsr_cmd; - tx_xfer->len = sizeof(rdsr_cmd); - + tx_xfer->tx_buf = tx_buf; + tx_xfer->len = WCD_SPI_OPCODE_LEN; + memset(rx_buf, 0, sizeof(*rdsr_status)); wcd_spi_reinit_xfer(rx_xfer); - rx_xfer->rx_buf = &status; - rx_xfer->len = sizeof(status); + rx_xfer->rx_buf = rx_buf; + rx_xfer->len = sizeof(*rdsr_status); ret = spi_sync(spi, &wcd_spi->msg2); if (ret < 0) { @@ -542,10 +556,10 @@ static int wcd_spi_cmd_rdsr(struct spi_device *spi, goto done; } - *rdsr_status = be32_to_cpu(status); + *rdsr_status = be32_to_cpu(*((u32*)rx_buf)); dev_dbg(&spi->dev, "%s: RDSR success, value = 0x%x\n", - __func__, *rdsr_status); + __func__, *rdsr_status); done: return ret; } @@ -1011,7 +1025,7 @@ static int wcd_spi_bus_gwrite(void *context, const void *reg, struct device *dev = context; struct spi_device *spi = to_spi_device(dev); struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); - u8 tx_buf[WCD_SPI_CMD_IRW_LEN]; + u8 *tx_buf = wcd_spi->tx_buf; if (!reg || !val || reg_len != wcd_spi->reg_bytes || val_len != wcd_spi->val_bytes) { @@ -1021,9 +1035,10 @@ static int wcd_spi_bus_gwrite(void *context, const void *reg, return -EINVAL; } + memset(tx_buf, 0, WCD_SPI_CMD_IRW_LEN); tx_buf[0] = WCD_SPI_CMD_IRW; tx_buf[1] = *((u8 *)reg); - memcpy(&tx_buf[WCD_SPI_OPCODE_LEN + reg_len], + memcpy(tx_buf + WCD_SPI_OPCODE_LEN + reg_len, val, val_len); return spi_write(spi, tx_buf, WCD_SPI_CMD_IRW_LEN); @@ -1057,7 +1072,9 @@ static int wcd_spi_bus_read(void *context, const void *reg, struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); struct spi_transfer *tx_xfer = &wcd_spi->xfer2[0]; struct spi_transfer *rx_xfer = &wcd_spi->xfer2[1]; - u8 tx_buf[WCD_SPI_CMD_IRR_LEN]; + u8 *tx_buf = wcd_spi->tx_buf; + u8 *rx_buf = wcd_spi->rx_buf; + int ret = 0; if (!reg || !val || reg_len != wcd_spi->reg_bytes || val_len != wcd_spi->val_bytes) { @@ -1067,7 +1084,7 @@ static int wcd_spi_bus_read(void *context, const void *reg, return -EINVAL; } - memset(tx_buf, 0, WCD_SPI_OPCODE_LEN); + memset(tx_buf, 0, WCD_SPI_CMD_IRR_LEN); tx_buf[0] = WCD_SPI_CMD_IRR; tx_buf[1] = *((u8 *)reg); @@ -1078,10 +1095,20 @@ static int wcd_spi_bus_read(void *context, const void *reg, wcd_spi_reinit_xfer(rx_xfer); rx_xfer->tx_buf = NULL; - rx_xfer->rx_buf = val; + rx_xfer->rx_buf = rx_buf; rx_xfer->len = val_len; - return spi_sync(spi, &wcd_spi->msg2); + ret = spi_sync(spi, &wcd_spi->msg2); + if (ret) { + dev_err(&spi->dev, "%s: spi_sync failed, err %d\n", + __func__, ret); + goto done; + } + + memcpy(val, rx_buf, val_len); + +done: + return ret; } static struct regmap_bus wcd_spi_regmap_bus = { -- GitLab From 21069793955ba68cf85b0b32c53eee230aea765a Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Wed, 11 Apr 2018 11:36:34 -0700 Subject: [PATCH 0263/1645] rtac: Fix return value of misc_register in init Return error only on failure else success. CRs-Fixed: 2204093 Change-Id: I616dbf41fb297f16b63d8108eff699703ea94177 Signed-off-by: Vignesh Kulothungan --- dsp/rtac.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dsp/rtac.c b/dsp/rtac.c index 82d08bfa79fc..b415ef0ed0ee 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -2051,7 +2051,10 @@ int __init rtac_init(void) kzfree(rtac_asm_buffer); kzfree(rtac_afe_buffer); kzfree(rtac_voice_buffer); + goto nomem; } + + return 0; nomem: return -ENOMEM; } -- GitLab From 82c2c2ca0056a2cce4b3c6e0b4817470b40ebab0 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Wed, 10 Jan 2018 18:04:54 -0800 Subject: [PATCH 0264/1645] asoc: Fix read offset for compress capture with timestamp In a compress capture usecase, read offset guides to move buffer pointer based on buffer length. When timestamp is enabled read offset also needs to include timestamp header offset along with buffer length. This fix addresses the issue of null memory map handle due to incorrect read offset. Change-Id: I93c3ec588e77d535b6c7a4a0d832c1e7ea5f62a7 Signed-off-by: Vikram Panduranga --- asoc/msm-compress-q6-v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 7ba582a0c3aa..c4fecdefa2b3 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -541,7 +541,7 @@ static int msm_compr_read_buffer(struct msm_compr_audio *prtd) return ret; } prtd->bytes_read += buffer_length; - prtd->bytes_read_offset += buffer_length; + prtd->bytes_read_offset += buffer_length + prtd->ts_header_offset; if (prtd->bytes_read_offset >= prtd->buffer_size) prtd->bytes_read_offset -= prtd->buffer_size; -- GitLab From 5c4bab792d586749814f290e5dfc83333a472e31 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 25 Apr 2018 10:40:01 +0800 Subject: [PATCH 0265/1645] ASoC: add missing mixer control and routings for MI2S Add missing mixer controls/widgets and routing paths to avoid audio error logs during bootup. Change-Id: I3c23cd3e5d1e5e95fcad5f49e3827ef26587e2a3 Signed-off-by: Meng Wang --- asoc/msm-pcm-routing-v2.c | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 3db79906628a..e7c6eea34e62 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -9294,6 +9294,14 @@ static const struct snd_kcontrol_new mmul17_mixer_controls[] = { MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul18_mixer_controls[] = { @@ -9309,6 +9317,10 @@ static const struct snd_kcontrol_new mmul18_mixer_controls[] = { MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, @@ -9368,6 +9380,14 @@ static const struct snd_kcontrol_new mmul19_mixer_controls[] = { MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul20_mixer_controls[] = { @@ -9506,6 +9526,15 @@ static const struct snd_kcontrol_new mmul28_mixer_controls[] = { MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + }; static const struct snd_kcontrol_new mmul29_mixer_controls[] = { @@ -9541,6 +9570,15 @@ static const struct snd_kcontrol_new mmul29_mixer_controls[] = { MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + }; static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { @@ -14708,6 +14746,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("MM_UL18", "MultiMedia18 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL19", "MultiMedia19 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL20", "MultiMedia20 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL28", "MultiMedia28 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL29", "MultiMedia29 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("VOICEMMODE1_DL", "VoiceMMode1 Playback", 0, 0, 0, 0), @@ -15916,6 +15956,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &ext_ec_ref_mux_ul18), SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL19 MUX", SND_SOC_NOPM, 0, 0, &ext_ec_ref_mux_ul19), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL28 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul28), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL29 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul29), }; static const struct snd_soc_dapm_route intercon[] = { -- GitLab From 502766a828258aa36fe803234d3920cd63cbfb38 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 24 Apr 2018 18:35:56 -0700 Subject: [PATCH 0266/1645] asoc: msm: remove machine driver trivial boot up logs Change info logs to debug logs for all trivial machine driver logs that appear in boot up. Change-Id: I37fb24fb758a81af9ae4be0e735cd9b467f88e70 Signed-off-by: Karthikeyan Mani --- asoc/sm8150.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/sm8150.c b/asoc/sm8150.c index e561ad5d7353..eceae67bcc0c 100644 --- a/asoc/sm8150.c +++ b/asoc/sm8150.c @@ -3828,7 +3828,7 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) 134, 135, 136, 137, 138, 139, 140, 141, 142, 143}; - pr_info("%s: dev_name:%s\n", __func__, dev_name(cpu_dai->dev)); + pr_debug("%s: dev_name:%s\n", __func__, dev_name(cpu_dai->dev)); rtd->pmdown_time = 0; -- GitLab From ca1c181f99b621e90844cc1ea0415c91e10db189 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 23 Apr 2018 18:13:15 -0700 Subject: [PATCH 0267/1645] asoc: msm: update names of MI2S and TDM pinctrl states The current names of MI2S and TDM pinctrl states are too similar to the actual pinctrl names. Update names of pinctrl states to avoid confusion. Change-Id: I1c775a29a32dad38dcc13ae395bd2557ec3a87c9 Signed-off-by: Karthikeyan Mani --- asoc/sm8150.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/asoc/sm8150.c b/asoc/sm8150.c index e561ad5d7353..535b6a8fbab2 100644 --- a/asoc/sm8150.c +++ b/asoc/sm8150.c @@ -4425,25 +4425,25 @@ static int msm_get_pinctrl(struct platform_device *pdev) /* get all the states handles from Device Tree */ pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl, - "quat-mi2s-sleep"); + "quat_mi2s_disable"); if (IS_ERR(pinctrl_info->mi2s_disable)) { pr_err("%s: could not get mi2s_disable pinstate\n", __func__); goto err; } pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl, - "quat-mi2s-active"); + "quat_mi2s_enable"); if (IS_ERR(pinctrl_info->mi2s_active)) { pr_err("%s: could not get mi2s_active pinstate\n", __func__); goto err; } pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl, - "quat-tdm-sleep"); + "quat_tdm_disable"); if (IS_ERR(pinctrl_info->tdm_disable)) { pr_err("%s: could not get tdm_disable pinstate\n", __func__); goto err; } pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl, - "quat-tdm-active"); + "quat_tdm_enable"); if (IS_ERR(pinctrl_info->tdm_active)) { pr_err("%s: could not get tdm_active pinstate\n", __func__); -- GitLab From ce6e7805bd3b1d0a639f105017d7a38e48848a2b Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Wed, 25 Apr 2018 22:29:47 -0700 Subject: [PATCH 0268/1645] dsp: msm_audio_ion: store device pointer locally for all cases Device pointer needs to be stored during probe of msm_audio_ion platform driver so that the same can be used later for mapping dma_buff allocated for different clients. Store device pointer for both cases where SMMU may be present or absent on a particular platform. Change-Id: I3d3d4ad254d41ac9490ff0dc98b95ffbc3e5042d Signed-off-by: Banajit Goswami --- dsp/msm_audio_ion.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index e073d94a8cf1..ec147fb8dd46 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -652,7 +652,6 @@ static int msm_audio_smmu_init(struct device *dev) goto fail_attach; } - msm_audio_ion_data.cb_dev = dev; msm_audio_ion_data.mapping = mapping; INIT_LIST_HEAD(&msm_audio_ion_data.alloc_list); mutex_init(&(msm_audio_ion_data.list_mutex)); @@ -759,6 +758,8 @@ static int msm_audio_ion_probe(struct platform_device *pdev) if (!rc) msm_audio_ion_data.device_status |= MSM_AUDIO_ION_PROBED; + msm_audio_ion_data.cb_dev = dev; + return rc; } -- GitLab From 6d74b706f036462971c470f39af81077cfffb7a8 Mon Sep 17 00:00:00 2001 From: Abhishek Arpure Date: Thu, 5 Apr 2018 13:50:25 +0530 Subject: [PATCH 0269/1645] Initial Android target definition for msmsteppe Add MSMSTEPPE in the makefile rules to enable compilation for SDM640. Change-Id: I36437404d98229c8b292fd63304498122d8c8687 Signed-off-by: Tanya Dixit --- Android.mk | 6 +++--- asoc/Android.mk | 7 ++++++- asoc/Kbuild | 5 +++++ asoc/codecs/Android.mk | 6 +++++- asoc/codecs/Kbuild | 5 +++++ asoc/codecs/aqt1000/Kbuild | 5 +++++ asoc/codecs/wcd934x/Android.mk | 6 +++++- asoc/codecs/wcd934x/Kbuild | 5 +++++ asoc/codecs/wcd9360/Android.mk | 6 +++++- asoc/codecs/wcd9360/Kbuild | 5 +++++ dsp/Android.mk | 6 +++++- dsp/Kbuild | 5 +++++ dsp/codecs/Android.mk | 6 +++++- dsp/codecs/Kbuild | 5 +++++ ipc/Android.mk | 6 +++++- soc/Android.mk | 6 +++++- soc/Kbuild | 5 +++++ 17 files changed, 84 insertions(+), 11 deletions(-) diff --git a/Android.mk b/Android.mk index 6b4894bbf0f6..55bcbf10d14e 100644 --- a/Android.mk +++ b/Android.mk @@ -3,7 +3,7 @@ MY_LOCAL_PATH := $(call my-dir) UAPI_OUT := $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/include -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) $(shell mkdir -p $(UAPI_OUT)/linux;) $(shell mkdir -p $(UAPI_OUT)/sound;) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers) @@ -24,7 +24,7 @@ include $(MY_LOCAL_PATH)/asoc/codecs/Android.mk include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk endif -ifeq ($(call is-board-platform-in-list,sdm670 msmnile),true) +ifeq ($(call is-board-platform-in-list,sdm670 msmnile $(MSMSTEPPE)),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/aqt1000/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/aqt1000/Android.mk endif @@ -36,7 +36,7 @@ include $(MY_LOCAL_PATH)/asoc/codecs/sdm660_cdc/Android.mk include $(MY_LOCAL_PATH)/asoc/codecs/msm_sdw/Android.mk endif -ifeq ($(call is-board-platform-in-list,msmnile),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE)),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd9360/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wcd9360/Android.mk endif diff --git a/asoc/Android.mk b/asoc/Android.mk index cb2ce0c9f24f..26c898bdb059 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -18,9 +18,14 @@ TARGET := msmnile AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif +ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +TARGET := $(MSMSTEPPE) +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/Kbuild b/asoc/Kbuild index aea56621abbc..893d95b06763 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -35,6 +35,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM640), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index 803e4809c30a..a35a64bb7b5d 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -15,9 +15,13 @@ ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif +ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 9f3cfce55288..d3789b553f5b 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -34,6 +34,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM640), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/asoc/codecs/aqt1000/Kbuild b/asoc/codecs/aqt1000/Kbuild index 6523ce6d6b09..d870c1df1278 100644 --- a/asoc/codecs/aqt1000/Kbuild +++ b/asoc/codecs/aqt1000/Kbuild @@ -28,6 +28,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM640), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf diff --git a/asoc/codecs/wcd934x/Android.mk b/asoc/codecs/wcd934x/Android.mk index 313d51355d25..6b5cca55e922 100644 --- a/asoc/codecs/wcd934x/Android.mk +++ b/asoc/codecs/wcd934x/Android.mk @@ -11,13 +11,17 @@ ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif +ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index 256f518535f3..40326113c549 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -31,6 +31,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM640), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/asoc/codecs/wcd9360/Android.mk b/asoc/codecs/wcd9360/Android.mk index bee0364ecd41..b7566a108054 100644 --- a/asoc/codecs/wcd9360/Android.mk +++ b/asoc/codecs/wcd9360/Android.mk @@ -7,9 +7,13 @@ ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif +ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE)),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wcd9360/Kbuild b/asoc/codecs/wcd9360/Kbuild index 6bba0c525599..e815e24675e3 100644 --- a/asoc/codecs/wcd9360/Kbuild +++ b/asoc/codecs/wcd9360/Kbuild @@ -21,6 +21,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM640), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf diff --git a/dsp/Android.mk b/dsp/Android.mk index 281ed8786e5e..48b068c732f5 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -15,9 +15,13 @@ ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif +ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/Kbuild b/dsp/Kbuild index 348e2ee39ea2..e75dbd1986fe 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -29,6 +29,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM640), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/dsp/codecs/Android.mk b/dsp/codecs/Android.mk index a2fd453d91a6..69af58eefdf5 100644 --- a/dsp/codecs/Android.mk +++ b/dsp/codecs/Android.mk @@ -15,9 +15,13 @@ ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif +ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index cc9a2db127e3..67ac30c02ec1 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -30,6 +30,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM640), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/ipc/Android.mk b/ipc/Android.mk index 38b215f117bc..fe9ce0f54915 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -15,9 +15,13 @@ ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif +ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) LOCAL_PATH := $(call my-dir) diff --git a/soc/Android.mk b/soc/Android.mk index f92e238ff97e..9ce525e4c378 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -15,9 +15,13 @@ ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif +ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) LOCAL_PATH := $(call my-dir) diff --git a/soc/Kbuild b/soc/Kbuild index 9007b8e217a3..5ea10931af30 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -34,6 +34,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM640), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export -- GitLab From 2c346abb3c152b619119c0fdc3f0a138b0586089 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 24 Apr 2018 18:33:21 -0700 Subject: [PATCH 0270/1645] asoc: codecs: remove audio codec core trivial boot up logs Change info logs to debug logs for all trivial audio codec core logs that appear in boot up. Change-Id: I797b876f2a9d72a72c3378acac0d8d7f11b5c4a5 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd9xxx-core.c | 2 +- asoc/codecs/wcd9xxx-utils.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index 7cb7f68f352a..3fe398e7cbd9 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -1248,7 +1248,7 @@ static int wcd9xxx_slim_probe(struct slim_device *slim) goto err; } if (slim->dev.of_node) { - dev_info(&slim->dev, "Platform data from device tree\n"); + dev_dbg(&slim->dev, "Platform data from device tree\n"); pdata = wcd9xxx_populate_dt_data(&slim->dev); if (!pdata) { dev_err(&slim->dev, diff --git a/asoc/codecs/wcd9xxx-utils.c b/asoc/codecs/wcd9xxx-utils.c index 1f521bca4b23..bc30c9c1bd01 100644 --- a/asoc/codecs/wcd9xxx-utils.c +++ b/asoc/codecs/wcd9xxx-utils.c @@ -982,7 +982,7 @@ int wcd9xxx_core_res_init( wcd9xxx_core_res->num_irq_regs = num_irq_regs; wcd9xxx_core_res->wcd_core_regmap = wcd_regmap; - pr_info("%s: num_irqs = %d, num_irq_regs = %d\n", + pr_debug("%s: num_irqs = %d, num_irq_regs = %d\n", __func__, wcd9xxx_core_res->num_irqs, wcd9xxx_core_res->num_irq_regs); -- GitLab From b424e05893c69bfdec7871924968420f8e1a14d8 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Thu, 26 Apr 2018 11:48:31 -0700 Subject: [PATCH 0271/1645] dsp: avtimer: add __user attribute to identify userspace address Add __user attribute for avtimer_ioctl's input parameter ioctl_param to explicitly identify user space pointer in copy_to_user. Change-Id: I59fa9d39e5ec3ff9cde3a06af9da2d38e36d557d Signed-off-by: Xiaoyu Ye --- dsp/avtimer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/avtimer.c b/dsp/avtimer.c index b6833ed788b2..c9ef9f4a8ac9 100644 --- a/dsp/avtimer.c +++ b/dsp/avtimer.c @@ -345,7 +345,7 @@ static long avtimer_ioctl(struct file *file, unsigned int ioctl_num, pr_debug_ratelimited("%s: AV Timer tick: time %llx\n", __func__, avtimer_tick); - if (copy_to_user((void *) ioctl_param, &avtimer_tick, + if (copy_to_user((void __user *)ioctl_param, &avtimer_tick, sizeof(avtimer_tick))) { pr_err("%s: copy_to_user failed\n", __func__); return -EFAULT; -- GitLab From 92edfde1e932562d150d982925ff2be8a277b059 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 24 Apr 2018 12:18:37 +0800 Subject: [PATCH 0272/1645] Revert "ASoC: disable source tracking get functionality for sdm855" This reverts commit 85b6208522c6a9ecbba4f571b33056a31f62eca4 (ASoC: disable source tracking get functionality for sm8150). Enable source tracking get functionality as the feature is completely enabled. Change-Id: I099fae3155f486f1fe89dbdad97c8cb1029f14df Signed-off-by: Meng Wang --- asoc/msm-pcm-routing-v2.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 3db79906628a..ba4770510158 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -14173,7 +14173,24 @@ static int msm_source_tracking_info(struct snd_kcontrol *kcontrol, static int msm_voice_source_tracking_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - return -EINVAL; + int ret = 0; + struct source_tracking_param sourceTrackingData; + + memset(&sourceTrackingData, 0, sizeof(struct source_tracking_param)); + + ret = voc_get_source_tracking(&sourceTrackingData); + if (ret) { + pr_err("%s: Error getting Source Tracking Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + memcpy(ucontrol->value.bytes.data, (void *)&sourceTrackingData, + sizeof(struct source_tracking_param)); + +done: + return ret; } static int msm_audio_get_copp_idx_from_port_id(int port_id, int session_type, -- GitLab From c0c314765f60c44949a87ec0179da92d62f91488 Mon Sep 17 00:00:00 2001 From: Aniket Kumar Lata Date: Thu, 22 Feb 2018 14:46:09 -0800 Subject: [PATCH 0273/1645] asoc: dsp: Add support for adaptive bitrate Add support for adaptive bitrate with A2DP offload. Set up Tx feedback path on SLIMBUS_7_TX from BT SoC to LPASS. Configure AFE encoder and decoder for ABR. Add bit width support to configure AFE port with 32bit for BT A2DP. Change-Id: I8e0afaf52561e5dc70318240ba238fc42844501f Signed-off-by: Aniket Kumar Lata --- asoc/msm-dai-q6-v2.c | 121 ++++++++++++++++++++-- asoc/msm-pcm-routing-v2.c | 38 +++++++ dsp/q6afe.c | 206 ++++++++++++++++++++++++++++++++----- include/dsp/apr_audio-v2.h | 141 +++++++++++++++++++++++++ include/dsp/q6afe-v2.h | 3 +- 5 files changed, 475 insertions(+), 34 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index c3c1fbdfcae5..2c1d10d51a57 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -46,6 +46,7 @@ enum { ENC_FMT_NONE, + DEC_FMT_NONE = ENC_FMT_NONE, ENC_FMT_SBC = ASM_MEDIA_FMT_SBC, ENC_FMT_AAC_V2 = ASM_MEDIA_FMT_AAC_V2, ENC_FMT_APTX = ASM_MEDIA_FMT_APTX, @@ -200,6 +201,7 @@ struct msm_dai_q6_dai_data { u32 afe_in_channels; u16 afe_in_bitformat; struct afe_enc_config enc_config; + struct afe_dec_config dec_config; union afe_port_config port_config; u16 vi_feed_mono; }; @@ -1538,22 +1540,46 @@ static int msm_dai_q6_prepare(struct snd_pcm_substream *substream, if (dai_data->enc_config.format != ENC_FMT_NONE) { int bitwidth = 0; - if (dai_data->afe_in_bitformat == - SNDRV_PCM_FORMAT_S24_LE) + switch (dai_data->afe_in_bitformat) { + case SNDRV_PCM_FORMAT_S32_LE: + bitwidth = 32; + break; + case SNDRV_PCM_FORMAT_S24_LE: bitwidth = 24; - else if (dai_data->afe_in_bitformat == - SNDRV_PCM_FORMAT_S16_LE) + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: bitwidth = 16; + break; + } pr_debug("%s: calling AFE_PORT_START_V2 with enc_format: %d\n", __func__, dai_data->enc_config.format); rc = afe_port_start_v2(dai->id, &dai_data->port_config, dai_data->rate, dai_data->afe_in_channels, bitwidth, - &dai_data->enc_config); + &dai_data->enc_config, NULL); if (rc < 0) pr_err("%s: afe_port_start_v2 failed error: %d\n", __func__, rc); + } else if (dai_data->dec_config.format != DEC_FMT_NONE) { + /* + * A dummy Tx session is established in LPASS to + * get the link statistics from BTSoC. + * Depacketizer extracts the bit rate levels and + * transmits them to the encoder on the Rx path. + * Since this is a dummy decoder - channels, bit + * width are sent as 0 and encoder config is NULL. + * This could be updated in the future if there is + * a complete Tx path set up that uses this decoder. + */ + rc = afe_port_start_v2(dai->id, &dai_data->port_config, + dai_data->rate, 0, 0, NULL, + &dai_data->dec_config); + if (rc < 0) { + pr_err("%s: fail to open AFE port 0x%x\n", + __func__, dai->id); + } } else { rc = afe_port_start(dai->id, &dai_data->port_config, dai_data->rate); @@ -2233,7 +2259,7 @@ static int msm_dai_q6_afe_enc_cfg_get(struct snd_kcontrol *kcontrol, if (dai_data) { int format_size = sizeof(dai_data->enc_config.format); - pr_debug("%s:encoder config for %d format\n", + pr_debug("%s: encoder config for %d format\n", __func__, dai_data->enc_config.format); memcpy(ucontrol->value.bytes.data, &dai_data->enc_config.format, @@ -2345,10 +2371,11 @@ static const struct soc_enum afe_input_chs_enum[] = { SOC_ENUM_SINGLE_EXT(3, afe_input_chs_text), }; -static const char *const afe_input_bit_format_text[] = {"S16_LE", "S24_LE"}; +static const char *const afe_input_bit_format_text[] = {"S16_LE", "S24_LE", + "S32_LE"}; static const struct soc_enum afe_input_bit_format_enum[] = { - SOC_ENUM_SINGLE_EXT(2, afe_input_bit_format_text), + SOC_ENUM_SINGLE_EXT(3, afe_input_bit_format_text), }; static int msm_dai_q6_afe_input_channel_get(struct snd_kcontrol *kcontrol, @@ -2391,6 +2418,9 @@ static int msm_dai_q6_afe_input_bit_format_get( } switch (dai_data->afe_in_bitformat) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 2; + break; case SNDRV_PCM_FORMAT_S24_LE: ucontrol->value.integer.value[0] = 1; break; @@ -2416,6 +2446,9 @@ static int msm_dai_q6_afe_input_bit_format_put( return -EINVAL; } switch (ucontrol->value.integer.value[0]) { + case 2: + dai_data->afe_in_bitformat = SNDRV_PCM_FORMAT_S32_LE; + break; case 1: dai_data->afe_in_bitformat = SNDRV_PCM_FORMAT_S24_LE; break; @@ -2483,6 +2516,73 @@ static const struct snd_kcontrol_new afe_enc_config_controls[] = { msm_dai_q6_afe_scrambler_mode_put), }; +static int msm_dai_q6_afe_dec_cfg_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(struct afe_dec_config); + + return 0; +} + +static int msm_dai_q6_afe_dec_cfg_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + int format_size = 0; + + if (!dai_data) { + pr_err("%s: Invalid dai data\n", __func__); + return -EINVAL; + } + + format_size = sizeof(dai_data->dec_config.format); + memcpy(ucontrol->value.bytes.data, + &dai_data->dec_config.format, + format_size); + memcpy(ucontrol->value.bytes.data + format_size, + &dai_data->dec_config.abr_dec_cfg, + sizeof(struct afe_abr_dec_cfg_t)); + + return 0; +} + +static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + int format_size = 0; + + if (!dai_data) { + pr_err("%s: Invalid dai data\n", __func__); + return -EINVAL; + } + + memset(&dai_data->dec_config, 0x0, + sizeof(struct afe_dec_config)); + format_size = sizeof(dai_data->dec_config.format); + memcpy(&dai_data->dec_config.format, + ucontrol->value.bytes.data, + format_size); + memcpy(&dai_data->dec_config.abr_dec_cfg, + ucontrol->value.bytes.data + format_size, + sizeof(struct afe_abr_dec_cfg_t)); + + return 0; +} + +static const struct snd_kcontrol_new afe_dec_config_controls[] = { + { + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_INACTIVE), + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "SLIM_7_TX Decoder Config", + .info = msm_dai_q6_afe_dec_cfg_info, + .get = msm_dai_q6_afe_dec_cfg_get, + .put = msm_dai_q6_afe_dec_cfg_put, + }, +}; + static int msm_dai_q6_slim_rx_drift_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -2650,6 +2750,11 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) snd_ctl_new1(&avd_drift_config_controls[2], dai)); break; + case SLIMBUS_7_TX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&afe_dec_config_controls[0], + dai_data)); + break; case RT_PROXY_DAI_001_RX: rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&rt_proxy_config_controls[0], diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index f88d30148472..e8eb7ce93885 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -62,6 +62,7 @@ static struct cal_type_data *cal_data[MAX_ROUTING_CAL_TYPES]; static int fm_switch_enable; static int hfp_switch_enable; +static int a2dp_switch_enable; static int int0_mi2s_switch_enable; static int int4_mi2s_switch_enable; static int pri_mi2s_switch_enable; @@ -2160,6 +2161,34 @@ static int msm_routing_put_hfp_switch_mixer(struct snd_kcontrol *kcontrol, return 1; } +static int msm_routing_a2dp_switch_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = a2dp_switch_enable; + pr_debug("%s: A2DP Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_a2dp_switch_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: A2DP Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + a2dp_switch_enable = ucontrol->value.integer.value[0]; + if (a2dp_switch_enable) + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, + 1, update); + else + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, + 0, update); + return 1; +} + static int msm_routing_get_int0_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -13659,6 +13688,11 @@ static const struct snd_kcontrol_new usb_switch_mixer_controls = 0, 1, 0, msm_routing_get_usb_switch_mixer, msm_routing_put_usb_switch_mixer); +static const struct snd_kcontrol_new a2dp_slim7_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_a2dp_switch_mixer_get, + msm_routing_a2dp_switch_mixer_put); + static const struct soc_enum lsm_port_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_port_text), lsm_port_text); @@ -15469,6 +15503,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &hfp_slim7_switch_mixer_controls), SND_SOC_DAPM_SWITCH("USB_DL_HL", SND_SOC_NOPM, 0, 0, &usb_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("A2DP_SLIM7_UL_HL", SND_SOC_NOPM, 0, 0, + &a2dp_slim7_switch_mixer_controls), /* Mixer definitions */ SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0, @@ -17826,6 +17862,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"HFP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"}, {"AUX_PCM_RX", NULL, "AUXPCM_DL_HL"}, {"AUX_PCM_RX", NULL, "INTHFP_DL_HL"}, + {"SLIM7_UL_HL", NULL, "A2DP_SLIM7_UL_HL"}, + {"A2DP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"}, {"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_DL_HL"}, {"AUXPCM_UL_HL", NULL, "AUX_PCM_TX"}, {"SEC_AUXPCM_UL_HL", NULL, "SEC_AUX_PCM_TX"}, diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 781a4361f9d1..142a21cd9f01 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2905,6 +2905,79 @@ int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) return ret; } +static int q6afe_send_dec_config(u16 port_id, + union afe_port_config afe_config, + struct afe_dec_config *cfg) +{ + struct avs_dec_depacketizer_id_param_t dec_depkt_id_param; + struct afe_enc_dec_imc_info_param_t imc_info_param; + struct afe_port_media_type_t media_type; + struct param_hdr_v3 param_hdr; + int ret; + + memset(&dec_depkt_id_param, 0, sizeof(dec_depkt_id_param)); + memset(&imc_info_param, 0, sizeof(imc_info_param)); + memset(&media_type, 0, sizeof(media_type)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AFE_MODULE_ID_DECODER; + param_hdr.instance_id = INSTANCE_ID_0; + + pr_debug("%s: sending AFE_DECODER_PARAM_ID_DEPACKETIZER to DSP payload\n", + __func__); + param_hdr.param_id = AFE_DECODER_PARAM_ID_DEPACKETIZER_ID; + param_hdr.param_size = sizeof(struct avs_dec_depacketizer_id_param_t); + dec_depkt_id_param.dec_depacketizer_id = + AFE_MODULE_ID_DEPACKETIZER_COP; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &dec_depkt_id_param); + if (ret) { + pr_err("%s: AFE_DECODER_PARAM_ID_DEPACKETIZER for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + + pr_debug("%s:sending AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION to DSP payload\n", + __func__); + param_hdr.param_id = AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION; + param_hdr.param_size = sizeof(struct afe_enc_dec_imc_info_param_t); + imc_info_param.imc_info = cfg->abr_dec_cfg.imc_info; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &imc_info_param); + if (ret) { + pr_err("%s: AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + + pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __func__); + param_hdr.module_id = AFE_MODULE_PORT; + param_hdr.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE; + param_hdr.param_size = sizeof(struct afe_port_media_type_t); + media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE; + media_type.sample_rate = afe_config.slim_sch.sample_rate; + media_type.bit_width = afe_config.slim_sch.bit_width; + media_type.num_channels = afe_config.slim_sch.num_channels; + media_type.data_format = AFE_PORT_DATA_FORMAT_PCM; + media_type.reserved = 0; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &media_type); + if (ret) { + pr_err("%s: AFE_API_VERSION_PORT_MEDIA_TYPE for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + +exit: + return ret; +} + static int q6afe_send_enc_config(u16 port_id, union afe_enc_config_data *cfg, u32 format, union afe_port_config afe_config, @@ -2916,6 +2989,8 @@ static int q6afe_send_enc_config(u16 port_id, struct afe_param_id_aptx_sync_mode sync_mode_param; struct avs_enc_packetizer_id_param_t enc_pkt_id_param; struct avs_enc_set_scrambler_param_t enc_set_scrambler_param; + struct afe_enc_level_to_bitrate_map_param_t map_param; + struct afe_enc_dec_imc_info_param_t imc_info_param; struct afe_port_media_type_t media_type; struct param_hdr_v3 param_hdr; int ret; @@ -2926,6 +3001,8 @@ static int q6afe_send_enc_config(u16 port_id, memset(&sync_mode_param, 0, sizeof(sync_mode_param)); memset(&enc_pkt_id_param, 0, sizeof(enc_pkt_id_param)); memset(&enc_set_scrambler_param, 0, sizeof(enc_set_scrambler_param)); + memset(&map_param, 0, sizeof(map_param)); + memset(&imc_info_param, 0, sizeof(imc_info_param)); memset(&media_type, 0, sizeof(media_type)); memset(¶m_hdr, 0, sizeof(param_hdr)); @@ -2953,11 +3030,20 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } + if (format == ASM_MEDIA_FMT_LDAC) { + param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t) + - sizeof(struct afe_abr_enc_cfg_t); + enc_blk_param.enc_cfg_blk_size = + sizeof(union afe_enc_config_data) + - sizeof(struct afe_abr_enc_cfg_t); + } else { + param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t); + enc_blk_param.enc_cfg_blk_size = + sizeof(union afe_enc_config_data); + } pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payloadn", __func__); param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK; - param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t); - enc_blk_param.enc_cfg_blk_size = sizeof(union afe_enc_config_data); enc_blk_param.enc_blk_config = *cfg; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), @@ -3019,12 +3105,55 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } + if (format == ASM_MEDIA_FMT_LDAC) { + pr_debug("%s:sending AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP to DSP payload", + __func__); + param_hdr.param_id = AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP; + param_hdr.param_size = + sizeof(struct afe_enc_level_to_bitrate_map_param_t); + map_param.mapping_table = + cfg->ldac_config.abr_config.mapping_info; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &map_param); + if (ret) { + pr_err("%s: AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + + pr_debug("%s: sending AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION to DSP payload", + __func__); + param_hdr.param_id = + AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION; + param_hdr.param_size = + sizeof(struct afe_enc_dec_imc_info_param_t); + imc_info_param.imc_info = + cfg->ldac_config.abr_config.imc_info; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &imc_info_param); + if (ret) { + pr_err("%s: AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + } + pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __func__); param_hdr.module_id = AFE_MODULE_PORT; param_hdr.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE; param_hdr.param_size = sizeof(struct afe_port_media_type_t); media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE; - media_type.sample_rate = afe_config.slim_sch.sample_rate; + if (format == ASM_MEDIA_FMT_LDAC) + media_type.sample_rate = + cfg->ldac_config.custom_config.sample_rate; + else + media_type.sample_rate = + afe_config.slim_sch.sample_rate; + if (afe_in_bit_width) media_type.bit_width = afe_in_bit_width; else @@ -3052,8 +3181,9 @@ static int q6afe_send_enc_config(u16 port_id, static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, - union afe_enc_config_data *cfg, u32 enc_format, - u32 scrambler_mode) + union afe_enc_config_data *enc_cfg, + u32 codec_format, u32 scrambler_mode, + struct afe_dec_config *dec_cfg) { union afe_port_config port_cfg; struct param_hdr_v3 param_hdr; @@ -3290,7 +3420,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, param_hdr.param_size = sizeof(union afe_port_config); port_cfg = *afe_config; - if ((enc_format != ASM_MEDIA_FMT_NONE) && + if (((enc_cfg != NULL) || (dec_cfg != NULL)) && + (codec_format != ASM_MEDIA_FMT_NONE) && (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) { port_cfg.slim_sch.data_format = AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED; @@ -3304,18 +3435,32 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, goto fail_cmd; } - if ((enc_format != ASM_MEDIA_FMT_NONE) && + if ((codec_format != ASM_MEDIA_FMT_NONE) && (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) { - pr_debug("%s: Found AFE encoder support for SLIMBUS enc_format = %d\n", - __func__, enc_format); - ret = q6afe_send_enc_config(port_id, cfg, enc_format, - *afe_config, afe_in_channels, - afe_in_bit_width, - scrambler_mode); - if (ret) { - pr_err("%s: AFE encoder config for port 0x%x failed %d\n", - __func__, port_id, ret); - goto fail_cmd; + if (enc_cfg != NULL) { + pr_debug("%s: Found AFE encoder support for SLIMBUS format = %d\n", + __func__, codec_format); + ret = q6afe_send_enc_config(port_id, enc_cfg, + codec_format, *afe_config, + afe_in_channels, + afe_in_bit_width, + scrambler_mode); + if (ret) { + pr_err("%s: AFE encoder config for port 0x%x failed %d\n", + __func__, port_id, ret); + goto fail_cmd; + } + } + if (dec_cfg != NULL) { + pr_debug("%s: Found AFE decoder support for SLIMBUS format = %d\n", + __func__, codec_format); + ret = q6afe_send_dec_config(port_id, *afe_config, + dec_cfg); + if (ret) { + pr_err("%s: AFE decoder config for port 0x%x failed %d\n", + __func__, port_id, ret); + goto fail_cmd; + } } } @@ -3364,31 +3509,42 @@ int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate) { return __afe_port_start(port_id, afe_config, rate, - 0, 0, NULL, ASM_MEDIA_FMT_NONE, 0); + 0, 0, NULL, ASM_MEDIA_FMT_NONE, 0, NULL); } EXPORT_SYMBOL(afe_port_start); /** * afe_port_start_v2 - to configure AFE session with - * specified port configuration and encoder params + * specified port configuration and encoder /decoder params * * @port_id: AFE port id number * @afe_config: port configutation * @rate: sampling rate of port - * @cfg: AFE encoder configuration information to setup encoder + * @enc_cfg: AFE enc configuration information to setup encoder * @afe_in_channels: AFE input channel configuration, this needs * update only if input channel is differ from AFE output + * @dec_cfg: AFE dec configuration information to set up decoder * * Returns 0 on success or error value on port start failure. */ int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, - struct afe_enc_config *enc_cfg) + struct afe_enc_config *enc_cfg, + struct afe_dec_config *dec_cfg) { - return __afe_port_start(port_id, afe_config, rate, - afe_in_channels, afe_in_bit_width, - &enc_cfg->data, enc_cfg->format, - enc_cfg->scrambler_mode); + int ret = 0; + + if (enc_cfg != NULL) + ret = __afe_port_start(port_id, afe_config, rate, + afe_in_channels, afe_in_bit_width, + &enc_cfg->data, enc_cfg->format, + enc_cfg->scrambler_mode, dec_cfg); + else if (dec_cfg != NULL) + ret = __afe_port_start(port_id, afe_config, rate, + afe_in_channels, afe_in_bit_width, + NULL, dec_cfg->format, 0, dec_cfg); + + return ret; } EXPORT_SYMBOL(afe_port_start_v2); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index ae096e62606e..b32324b81788 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -3180,6 +3180,72 @@ struct afe_param_id_set_topology_cfg { u32 topology_id; } __packed; +#define MAX_ABR_LEVELS 5 + +struct afe_bit_rate_level_map_t { + /* + * Key value pair for link quality level to bitrate + * mapping in AFE + */ + uint32_t link_quality_level; + uint32_t bitrate; +} __packed; + +struct afe_quality_level_to_bitrate_info { + /* + * Number of quality levels being mapped. + * This will be equal to the size of mapping table. + */ + uint32_t num_levels; + /* + * Quality level to bitrate mapping table + */ + struct afe_bit_rate_level_map_t bit_rate_level_map[MAX_ABR_LEVELS]; +} __packed; + +struct afe_imc_dec_enc_info { + /* + * Decoder to encoder communication direction. + * Transmit = 0 / Receive = 1 + */ + uint32_t direction; + /* + * Enable / disable IMC between decoder and encoder + */ + uint32_t enable; + /* + * Purpose of IMC being set up between decoder and encoder. + * Param ID defined for link quality feedback in LPASS will + * be the default value sent as purpose. + * Supported values: + * AFE_ENCDEC_PURPOSE_ID_BT_INFO + */ + uint32_t purpose; + /* + * Unique communication instance ID. + * Data type a2dp_abr_instance used to set instance ID. + * purpose and comm_instance together form the actual key + * used in IMC registration, which must be the same for + * encoder and decoder for which IMC is being set up. + */ + uint32_t comm_instance; +} __packed; + +struct afe_abr_dec_cfg_t { + struct afe_imc_dec_enc_info imc_info; +} __packed; + +struct afe_abr_enc_cfg_t { + /* + * Link quality level to bitrate mapping info sent to DSP. + */ + struct afe_quality_level_to_bitrate_info mapping_info; + /* + * Information to set up IMC between decoder and encoder. + */ + struct afe_imc_dec_enc_info imc_info; +} __packed; + #define AFE_PARAM_ID_APTX_SYNC_MODE 0x00013205 struct afe_param_id_aptx_sync_mode { @@ -3230,6 +3296,39 @@ struct afe_param_id_aptx_sync_mode { */ #define AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING 0x0001323C +/* + * Link quality level to bitrate mapping info sent to AFE Encoder. + * This parameter may be set runtime. + */ +#define AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP 0x000132E1 + +/* + * Parameter to set up Inter Module Communication (IMC) between + * AFE Decoder and Encoder. + * This parameter may be set runtime. + */ +#define AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION 0x0001323D + +/* + * Purpose of IMC set up between encoder and decoder. + * Communication instance and purpose together form the + * actual key used for IMC registration. + */ +#define AFE_ENCDEC_PURPOSE_ID_BT_INFO 0x000132E2 + +#define AFE_MODULE_ID_DECODER 0x00013231 + +/* + * Macro for defining the depacketizer ID: COP. + */ +#define AFE_MODULE_ID_DEPACKETIZER_COP 0x00013233 + +/* + * Depacketizer type parameter for the #AVS_MODULE_ID_DECODER module. + * This parameter cannot be set runtime. + */ +#define AFE_DECODER_PARAM_ID_DEPACKETIZER_ID 0x00013235 + /* * Data format to send compressed data * is transmitted/received over Slimbus lines. @@ -3531,6 +3630,7 @@ struct asm_ldac_specific_enc_cfg_t { struct asm_ldac_enc_cfg_t { struct asm_custom_enc_cfg_t custom_config; struct asm_ldac_specific_enc_cfg_t ldac_specific_config; + struct afe_abr_enc_cfg_t abr_config; } __packed; struct afe_enc_fmt_id_param_t { @@ -3612,6 +3712,11 @@ struct afe_enc_config { union afe_enc_config_data data; }; +struct afe_dec_config { + u32 format; + struct afe_abr_dec_cfg_t abr_dec_cfg; +}; + struct afe_enc_cfg_blk_param_t { uint32_t enc_cfg_blk_size; /* @@ -3644,6 +3749,39 @@ struct avs_enc_set_scrambler_param_t { uint32_t enable_scrambler; }; +/* + * Payload of the AVS_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP parameter. + */ +struct afe_enc_level_to_bitrate_map_param_t { + /* + * Parameter for mapping link quality level to bitrate. + */ + struct afe_quality_level_to_bitrate_info mapping_table; +}; + +/* + * Payload of the AVS_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION parameter. + */ +struct afe_enc_dec_imc_info_param_t { + /* + * Parameter to set up Inter Module Communication (IMC) between + * AFE Decoder and Encoder. + */ + struct afe_imc_dec_enc_info imc_info; +}; + +/* + * Payload of the AVS_DECODER_PARAM_ID_DEPACKETIZER_ID parameter. + */ +struct avs_dec_depacketizer_id_param_t { + /* + * Supported values: + * #AVS_MODULE_ID_DEPACKETIZER_COP + * Any OpenDSP supported values + */ + uint32_t dec_depacketizer_id; +}; + union afe_port_config { struct afe_param_id_pcm_cfg pcm; struct afe_param_id_i2s_cfg i2s; @@ -3663,6 +3801,9 @@ union afe_port_config { struct afe_enc_cfg_blk_param_t enc_blk_param; struct avs_enc_packetizer_id_param_t enc_pkt_id_param; struct avs_enc_set_scrambler_param_t enc_set_scrambler_param; + struct avs_dec_depacketizer_id_param_t dec_depkt_id_param; + struct afe_enc_level_to_bitrate_map_param_t map_param; + struct afe_enc_dec_imc_info_param_t imc_info_param; } __packed; #define AFE_PORT_CMD_DEVICE_START 0x000100E5 diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index ade124952236..7c849ba15595 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -318,7 +318,8 @@ int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate); int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, - struct afe_enc_config *enc_config); + struct afe_enc_config *enc_config, + struct afe_dec_config *dec_config); int afe_spk_prot_feed_back_cfg(int src_port, int dst_port, int l_ch, int r_ch, u32 enable); int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib); -- GitLab From ddd20a414f33fb52f46da962d13ff2aa49a0e77b Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Fri, 27 Apr 2018 12:02:29 -0700 Subject: [PATCH 0274/1645] uapi: audio: update maximum number of channels supported Audio calibration data supports 32 channels now so update maximum number of channels supported to 32. Change-Id: I0b94e23fe88c4382d78db85014a81e440f720660 Signed-off-by: Vidyakumar Athota --- include/dsp/q6voice.h | 2 +- include/uapi/linux/msm_audio_calibration.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index be72b72d34e4..d0ba99001d1d 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -21,7 +21,7 @@ #define SESSION_NAME_LEN 20 #define NUM_OF_MEMORY_BLOCKS 1 #define NUM_OF_BUFFERS 2 -#define VSS_NUM_CHANNELS_MAX 8 +#define VSS_NUM_CHANNELS_MAX 32 #define VSS_CHANNEL_MAPPING_SIZE (sizeof(uint8_t) * VSS_NUM_CHANNELS_MAX) /* * BUFFER BLOCK SIZE based on diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h index 3b97ab2bf1e0..0672ee311299 100644 --- a/include/uapi/linux/msm_audio_calibration.h +++ b/include/uapi/linux/msm_audio_calibration.h @@ -393,7 +393,7 @@ struct audio_cal_info_lsm { int32_t app_type; }; -#define VSS_NUM_CHANNELS_MAX 8 +#define VSS_NUM_CHANNELS_MAX 32 struct audio_cal_info_voc_top { int32_t topology; -- GitLab From 4da52505687d9a53038ed66bba78ebd3978fe837 Mon Sep 17 00:00:00 2001 From: Aniket Kumar Lata Date: Thu, 8 Mar 2018 16:28:26 -0800 Subject: [PATCH 0275/1645] asoc: msmnile: add configuration for adaptive bitrate Add hostless front end DAI to trigger backend configuration of BT backend dai required for configuring BT ABR statistics. Add mixer ctrls to independently configure TX and RX sample rates to allow BT RX and TX backends. Change-Id: Iba274253bca510e3899658306787e2ba15324bf2 Signed-off-by: Aniket Kumar Lata --- asoc/sm8150.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/asoc/sm8150.c b/asoc/sm8150.c index 7fa95190f9e5..a0b669216c38 100644 --- a/asoc/sm8150.c +++ b/asoc/sm8150.c @@ -409,6 +409,12 @@ static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_44P1", "KHZ_48", "KHZ_88P2", "KHZ_96"}; +static char const *bt_sample_rate_rx_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; +static char const *bt_sample_rate_tx_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; @@ -462,6 +468,8 @@ static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_rx, bt_sample_rate_rx_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_tx, bt_sample_rate_tx_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, @@ -1075,6 +1083,130 @@ static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, return 0; } +static int msm_bt_sample_rate_rx_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate rx = %d", __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_rx_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rate: slim7_rx = %d, value = %d\n", + __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_bt_sample_rate_tx_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (slim_tx_cfg[SLIM_TX_7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate tx = %d", __func__, + slim_tx_cfg[SLIM_TX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_tx_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rate: slim7_tx = %d, value = %d\n", + __func__, + slim_tx_cfg[SLIM_TX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2737,6 +2869,12 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, msm_bt_sample_rate_get, msm_bt_sample_rate_put), + SOC_ENUM_EXT("BT SampleRate RX", bt_sample_rate_rx, + msm_bt_sample_rate_rx_get, + msm_bt_sample_rate_rx_put), + SOC_ENUM_EXT("BT SampleRate TX", bt_sample_rate_tx, + msm_bt_sample_rate_tx_get, + msm_bt_sample_rate_tx_put), SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, usb_audio_rx_sample_rate_get, usb_audio_rx_sample_rate_put), @@ -5502,6 +5640,22 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, + { + .name = "SLIMBUS_7 Hostless", + .stream_name = "SLIMBUS_7 Hostless", + .cpu_dai_name = "SLIMBUS7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, }; static struct snd_soc_dai_link msm_common_be_dai_links[] = { -- GitLab From 7e2bf007843b77d6c3bb568631ad8413cf97726d Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Wed, 4 Apr 2018 15:24:45 -0700 Subject: [PATCH 0276/1645] asoc: fix error handling logic to avoid potential deadlock IOCTL command "SNDRV_LSM_EVENT_STATUS_V3_32" in msm_lsm_ioctl_compat has an incorrect error handling logic which can cause mutex deadlock. Change this logic to avoid potential mutex deadlock. Change-Id: I19b3509b5d40cff555536e4615132ea8c477d451 Signed-off-by: Xiaoyu Ye --- asoc/msm-lsm-client.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 666ad08be74d..c00f5c25cfa2 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -1368,7 +1368,8 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, if (copy_from_user(&userarg32, arg, sizeof(userarg32))) { dev_err(rtd->dev, "%s: err copyuser ioctl %s\n", __func__, "SNDRV_LSM_EVENT_STATUS_V3_32"); - return -EFAULT; + err = -EINVAL; + goto done; } if (userarg32.payload_size > @@ -1376,7 +1377,8 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, pr_err("%s: payload_size %d is invalid, max allowed = %d\n", __func__, userarg32.payload_size, LISTEN_MAX_STATUS_PAYLOAD_SIZE); - return -EINVAL; + err = -EINVAL; + goto done; } size = sizeof(*user) + userarg32.payload_size; @@ -1385,7 +1387,8 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: Allocation failed event status size %d\n", __func__, size); - return -EFAULT; + err = -ENOMEM; + goto done; } cmd = SNDRV_LSM_EVENT_STATUS_V3; user->payload_size = userarg32.payload_size; -- GitLab From 7f3f59a70ad4c6b90874019ab9f1a0d55fcb9ebe Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Wed, 21 Mar 2018 17:01:12 -0700 Subject: [PATCH 0277/1645] uapi: add support for ADSP Generic Detection Event ADSP detection engine module can raise Generic Detection Event to provide variable payload data based on the information requested by userspace. Adding required structs and macros in the LSM UAPI header file to expose them to userspace. Change-Id: I454fb26b53f821310b5138a0ed9f1cbe516e63c3 Signed-off-by: Xiaoyu Ye --- include/uapi/sound/lsm_params.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/include/uapi/sound/lsm_params.h b/include/uapi/sound/lsm_params.h index 9ca5930475ba..67dc36f0cd3b 100644 --- a/include/uapi/sound/lsm_params.h +++ b/include/uapi/sound/lsm_params.h @@ -29,11 +29,15 @@ #define LSM_DEREG_SND_MODEL (5) #define LSM_CUSTOM_PARAMS (6) #define LSM_POLLING_ENABLE (7) -#define LSM_PARAMS_MAX (LSM_POLLING_ENABLE + 1) +#define LSM_DET_EVENT_TYPE (8) +#define LSM_PARAMS_MAX (LSM_DET_EVENT_TYPE + 1) #define LSM_EVENT_NON_TIME_STAMP_MODE (0) #define LSM_EVENT_TIME_STAMP_MODE (1) +#define LSM_DET_EVENT_TYPE_LEGACY (0) +#define LSM_DET_EVENT_TYPE_GENERIC (1) + enum lsm_app_id { LSM_VOICE_WAKEUP_APP_ID = 1, LSM_VOICE_WAKEUP_APP_ID_V2 = 2, @@ -87,6 +91,15 @@ struct snd_lsm_poll_enable { bool poll_en; }; +/* + * Data for LSM_DET_EVENT_TYPE param_type + * @event_type: LSM_DET_EVENT_TYPE_LEGACY or LSM_DET_EVENT_TYPE_GENERIC + * @mode: Type of information in detection event payload + */ +struct snd_lsm_det_event_type { + __u32 event_type; + __u32 mode; +}; struct snd_lsm_sound_model_v2 { __u8 __user *data; @@ -196,5 +209,6 @@ struct snd_lsm_output_format_cfg { #define SNDRV_LSM_SET_FWK_MODE_CONFIG _IOW('U', 0x0E, uint32_t) #define SNDRV_LSM_EVENT_STATUS_V3 _IOW('U', 0x0F, \ struct snd_lsm_event_status_v3) +#define SNDRV_LSM_GENERIC_DET_EVENT _IOW('U', 0x10, struct snd_lsm_event_status) #endif -- GitLab From 16b697200c3cd4b5bd7b46b883168f3fa923ccb5 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 3 May 2018 18:26:21 -0700 Subject: [PATCH 0278/1645] dsp: afe: add interface to update dp audio stream index For DP audio Multi Stream Transport, add an interface to set DP controller and DP stream index for display port audio AFE port. Change-Id: I6efbb6937a7849e5840a93541961414eb9049863 Signed-off-by: Karthikeyan Mani --- dsp/q6afe.c | 79 ++++++++++++++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 14 ++++++- include/dsp/q6afe-v2.h | 1 + 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 142a21cd9f01..08a25cff77a7 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -5674,6 +5674,85 @@ int afe_sidetone_enable(u16 tx_port_id, u16 rx_port_id, bool enable) return ret; } +/** + * afe_set_display_stream - command to update AFE dp port params + * + * @rx_port_id: AFE port id + * @stream_idx: dp controller stream index + * @ctl_idx: dp controller index + * + * Returns 0 on success, appropriate error code otherwise + */ +int afe_set_display_stream(u16 rx_port_id, u32 stream_idx, u32 ctl_idx) +{ + int ret; + struct param_hdr_v3 param_hdr; + u32 packed_param_size = 0; + u8 *packed_param_data = NULL; + struct afe_display_stream_idx stream_data; + struct afe_display_ctl_idx ctl_data; + u32 single_param_size = 0; + + memset(¶m_hdr, 0, sizeof(param_hdr)); + memset(&stream_data, 0, sizeof(stream_data)); + memset(&ctl_data, 0, sizeof(ctl_data)); + + packed_param_size = + sizeof(param_hdr) * 2 + sizeof(stream_data) + sizeof(ctl_data); + packed_param_data = kzalloc(packed_param_size, GFP_KERNEL); + if (!packed_param_data) + return -ENOMEM; + packed_param_size = 0; + + /* Set stream index */ + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_HDMI_DP_MST_VID_IDX_CFG; + param_hdr.param_size = sizeof(struct afe_display_stream_idx); + stream_data.minor_version = 1; + stream_data.stream_idx = stream_idx; + ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, + (u8 *) &stream_data, &single_param_size); + if (ret) { + pr_err("%s: Failed to pack param data, error %d\n", __func__, + ret); + goto done; + } + packed_param_size += single_param_size; + + /* Set controller dptx index */ + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_HDMI_DPTX_IDX_CFG; + param_hdr.param_size = sizeof(struct afe_display_ctl_idx); + ctl_data.minor_version = 1; + ctl_data.ctl_idx = ctl_idx; + ret = q6common_pack_pp_params(packed_param_data + packed_param_size, + ¶m_hdr, (u8 *) &ctl_data, + &single_param_size); + if (ret) { + pr_err("%s: Failed to pack param data, error %d\n", __func__, + ret); + goto done; + } + packed_param_size += single_param_size; + + pr_debug("%s: rx(0x%x) stream(%d) controller(%d)\n", + __func__, rx_port_id, stream_idx, ctl_idx); + + ret = q6afe_set_params(rx_port_id, q6audio_get_port_index(rx_port_id), + NULL, packed_param_data, packed_param_size); + if (ret) + pr_err("%s: AFE display stream send failed for rx_port:%d ret:%d\n", + __func__, rx_port_id, ret); + +done: + kfree(packed_param_data); + return ret; + +} +EXPORT_SYMBOL(afe_set_display_stream); + int afe_validate_port(u16 port_id) { int ret; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index b32324b81788..0d454c75815a 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1726,6 +1726,16 @@ struct afe_loopback_sidetone_gain { u16 gain; } __packed; +struct afe_display_stream_idx { + u32 minor_version; + u32 stream_idx; +} __packed; + +struct afe_display_ctl_idx { + u32 minor_version; + u32 ctl_idx; +} __packed; + struct loopback_cfg_data { u32 loopback_cfg_minor_version; /* Minor version used for tracking the version of the RMC module @@ -2477,7 +2487,9 @@ struct afe_param_id_digi_mic_cfg { } __packed; /* This param id is used to configure HDMI interface */ -#define AFE_PARAM_ID_HDMI_CONFIG 0x00010210 +#define AFE_PARAM_ID_HDMI_CONFIG 0x00010210 +#define AFE_PARAM_ID_HDMI_DP_MST_VID_IDX_CFG 0x000102b5 +#define AFE_PARAM_ID_HDMI_DPTX_IDX_CFG 0x000102b6 /* This version information is used to handle the new * additions to the config interface in future in backward diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 7c849ba15595..b2bf54769259 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -286,6 +286,7 @@ int afe_open(u16 port_id, union afe_port_config *afe_config, int rate); int afe_close(int port_id); int afe_loopback(u16 enable, u16 rx_port, u16 tx_port); int afe_sidetone_enable(u16 tx_port_id, u16 rx_port_id, bool enable); +int afe_set_display_stream(u16 rx_port_id, u32 stream_idx, u32 ctl_idx); int afe_loopback_gain(u16 port_id, u16 volume); int afe_validate_port(u16 port_id); int afe_get_port_index(u16 port_id); -- GitLab From ad978894b998ee3efbfdca302b2e0a7509b85688 Mon Sep 17 00:00:00 2001 From: Salendarsingh Gaud Date: Mon, 14 May 2018 16:53:09 +0530 Subject: [PATCH 0279/1645] Configure CONFIG_ARCH to enable compilation Use CONFIG_ARCH_SM6150 for Talos to enable proper compilation. Change-Id: I14e06122116c431bf4b99da3a061d165f68e0d4f Signed-off-by: Tanya Dixit --- asoc/Kbuild | 2 +- asoc/codecs/Kbuild | 2 +- asoc/codecs/aqt1000/Kbuild | 2 +- asoc/codecs/wcd934x/Kbuild | 2 +- asoc/codecs/wcd9360/Kbuild | 2 +- dsp/Kbuild | 2 +- dsp/codecs/Kbuild | 2 +- ipc/Kbuild | 8 ++++++++ soc/Kbuild | 2 +- 9 files changed, 16 insertions(+), 8 deletions(-) diff --git a/asoc/Kbuild b/asoc/Kbuild index 893d95b06763..8c3791770220 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -35,7 +35,7 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif - ifeq ($(CONFIG_ARCH_SDM640), y) + ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index d3789b553f5b..10b80965991a 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -34,7 +34,7 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif - ifeq ($(CONFIG_ARCH_SDM640), y) + ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h diff --git a/asoc/codecs/aqt1000/Kbuild b/asoc/codecs/aqt1000/Kbuild index d870c1df1278..2b002df88175 100644 --- a/asoc/codecs/aqt1000/Kbuild +++ b/asoc/codecs/aqt1000/Kbuild @@ -28,7 +28,7 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif - ifeq ($(CONFIG_ARCH_SDM640), y) + ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index 40326113c549..1287dd73a3a8 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -31,7 +31,7 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif - ifeq ($(CONFIG_ARCH_SDM640), y) + ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h diff --git a/asoc/codecs/wcd9360/Kbuild b/asoc/codecs/wcd9360/Kbuild index e815e24675e3..5b87cde49837 100644 --- a/asoc/codecs/wcd9360/Kbuild +++ b/asoc/codecs/wcd9360/Kbuild @@ -21,7 +21,7 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif - ifeq ($(CONFIG_ARCH_SDM640), y) + ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h diff --git a/dsp/Kbuild b/dsp/Kbuild index e75dbd1986fe..f22573273f59 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -29,7 +29,7 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif - ifeq ($(CONFIG_ARCH_SDM640), y) + ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 67ac30c02ec1..bdcc9dc413d9 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -30,7 +30,7 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif - ifeq ($(CONFIG_ARCH_SDM640), y) + ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h diff --git a/ipc/Kbuild b/ipc/Kbuild index afcb967fd989..a860a751f148 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -19,6 +19,9 @@ endif ifeq ($(CONFIG_ARCH_SM8150), y) TARGET_KERNEL_VERSION := 4.14 endif +ifeq ($(CONFIG_ARCH_SM6150), y) + TARGET_KERNEL_VERSION := 4.14 +endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) TARGET_KERNEL_VERSION := 4.14 @@ -46,6 +49,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif + ifeq ($(CONFIG_ARCH_SM6150), y) + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/soc/Kbuild b/soc/Kbuild index 5ea10931af30..3aaa38814db3 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -34,7 +34,7 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif - ifeq ($(CONFIG_ARCH_SDM640), y) + ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h -- GitLab From 44d588893a446985bf3ec2edcd82a055877498b4 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 3 May 2018 18:30:02 -0700 Subject: [PATCH 0280/1645] asoc: dai-q6: set dp audio stream index Add mixer control to update ctl index and stream index to set to display port audio AFE port. Use the index to set AFE params for the same. Change-Id: If83b5b0802bb82a0e01fb01c7175472d2b1bb94e Signed-off-by: Karthikeyan Mani --- asoc/msm-dai-q6-hdmi-v2.c | 61 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/asoc/msm-dai-q6-hdmi-v2.c b/asoc/msm-dai-q6-hdmi-v2.c index c061c08b2d02..bcf21b5d9b7b 100644 --- a/asoc/msm-dai-q6-hdmi-v2.c +++ b/asoc/msm-dai-q6-hdmi-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -41,6 +41,8 @@ struct msm_dai_q6_hdmi_dai_data { DECLARE_BITMAP(status_mask, STATUS_MAX); u32 rate; u32 channels; + u32 stream_idx; + u32 ctl_idx; struct msm_ext_disp_ca ca; union afe_port_config port_config; }; @@ -80,6 +82,42 @@ static int msm_dai_q6_ext_disp_format_get(struct snd_kcontrol *kcontrol, return 0; } +static int msm_dai_q6_ext_disp_device_idx_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_hdmi_dai_data *dai_data = kcontrol->private_data; + + if (!dai_data) { + pr_err("%s: dai_data is NULL\n", __func__); + return -EINVAL; + } + + dai_data->ctl_idx = ucontrol->value.integer.value[0]; + dai_data->stream_idx = ucontrol->value.integer.value[1]; + pr_debug("%s: DP ctl id %d stream id %d\n", __func__, + dai_data->ctl_idx, dai_data->stream_idx); + + return 0; +} + +static int msm_dai_q6_ext_disp_device_idx_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_hdmi_dai_data *dai_data = kcontrol->private_data; + + if (!dai_data) { + pr_err("%s: dai_data is NULL\n", __func__); + return -EINVAL; + } + + ucontrol->value.integer.value[0] = dai_data->ctl_idx; + ucontrol->value.integer.value[1] = dai_data->stream_idx; + pr_debug("%s: DP ctl id %d stream id %d\n", __func__, + dai_data->ctl_idx, dai_data->stream_idx); + + return 0; +} + static int msm_dai_q6_ext_disp_ca_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -188,6 +226,10 @@ static const struct snd_kcontrol_new display_port_config_controls[] = { HDMI_RX_CA_MAX, 0, 1, msm_dai_q6_ext_disp_ca_get, msm_dai_q6_ext_disp_ca_put), + SOC_SINGLE_MULTI_EXT("Display Port RX DEVICE IDX", SND_SOC_NOPM, 0, + 1, 0, 1, + msm_dai_q6_ext_disp_device_idx_get, + msm_dai_q6_ext_disp_device_idx_put), { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -297,6 +339,18 @@ static int msm_dai_q6_hdmi_prepare(struct snd_pcm_substream *substream, dai_data->ca.ca; if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + + rc = afe_set_display_stream(dai->id, dai_data->stream_idx, + dai_data->ctl_idx); + if (rc < 0) { + dev_err(dai->dev, "fail to set AFE ctl, stream ID params %x\n", + dai->id); + if (rc != -EOPNOTSUPP) { + dev_err(dai->dev, "not starting AFE port\n"); + goto err; + } + } + rc = afe_port_start(dai->id, &dai_data->port_config, dai_data->rate); if (rc < 0) @@ -307,6 +361,7 @@ static int msm_dai_q6_hdmi_prepare(struct snd_pcm_substream *substream, dai_data->status_mask); } +err: return rc; } @@ -365,6 +420,10 @@ static int msm_dai_q6_hdmi_dai_probe(struct snd_soc_dai *dai) snd_ctl_new1(kcontrol, dai_data)); kcontrol = &display_port_config_controls[2]; + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(kcontrol, dai_data)); + + kcontrol = &display_port_config_controls[3]; rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(kcontrol, dai)); } else { -- GitLab From fc1e972139cfa81da61fdf28ea54d3f833fa302c Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 3 May 2018 18:38:56 -0700 Subject: [PATCH 0281/1645] asoc: codecs: add MST support for dp audio driver Add DP codec DAIs to support multiple streams that audio can be routed to dp controllers with multiple streams in them. Change-Id: Id28e6b8cc2989797dd07252cdc8913bc3b403f19 Signed-off-by: Karthikeyan Mani --- asoc/codecs/msm_hdmi_codec_rx.c | 194 +++++++++++++++++++++++++++++--- 1 file changed, 177 insertions(+), 17 deletions(-) diff --git a/asoc/codecs/msm_hdmi_codec_rx.c b/asoc/codecs/msm_hdmi_codec_rx.c index 3a48f530d1ef..07e1cef370d5 100644 --- a/asoc/codecs/msm_hdmi_codec_rx.c +++ b/asoc/codecs/msm_hdmi_codec_rx.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -24,18 +24,49 @@ #define AUD_EXT_DISP_ACK_CONNECT (AUDIO_ACK_CONNECT) #define AUD_EXT_DISP_ACK_ENABLE (AUDIO_ACK_SET_ENABLE | AUDIO_ACK_ENABLE) +#define SOC_EXT_DISP_AUDIO_TYPE(index) \ + static SOC_ENUM_SINGLE_DECL(ext_disp_audio_type##index, SND_SOC_NOPM, \ + index, ext_disp_audio_type_text) +#define SOC_EXT_DISP_AUDIO_ACK_STATE(index) \ + static SOC_ENUM_SINGLE_DECL(ext_disp_audio_ack_state##index, \ + SND_SOC_NOPM, index, ext_disp_audio_ack_text) + +#define SWITCH_DP_CODEC(codec_info, codec_data, dai_id) \ + codec_info.type = EXT_DISPLAY_TYPE_DP; \ + codec_info.ctrl_id = codec_data->ctl[dai_id]; \ + codec_info.stream_id = codec_data->stream[dai_id]; \ + msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, \ + &codec_info) + +enum { + DP_STREAM0 = 0, + DP_STREAM1, + DP_STREAM_MAX, +}; + +enum { + DP_DAI1 = 0, + DP_DAI2, + HDMI_DAI, + DP_DAI_MAX, +}; + static const char *const ext_disp_audio_type_text[] = {"None", "HDMI", "DP"}; static const char *const ext_disp_audio_ack_text[] = {"Disconnect", "Connect", "Ack_Enable"}; -static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_audio_type, ext_disp_audio_type_text); -static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_audio_ack_state, - ext_disp_audio_ack_text); +SOC_EXT_DISP_AUDIO_TYPE(0); +SOC_EXT_DISP_AUDIO_ACK_STATE(0); +SOC_EXT_DISP_AUDIO_TYPE(1); +SOC_EXT_DISP_AUDIO_ACK_STATE(1); struct msm_ext_disp_audio_codec_rx_data { struct platform_device *ext_disp_core_pdev; struct msm_ext_disp_audio_codec_ops ext_disp_ops; int cable_status; + struct mutex dp_ops_lock; + int stream[DP_DAI_MAX]; + int ctl[DP_DAI_MAX]; }; static int msm_ext_disp_edid_ctl_info(struct snd_kcontrol *kcontrol, @@ -44,7 +75,9 @@ static int msm_ext_disp_edid_ctl_info(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct msm_ext_disp_audio_codec_rx_data *codec_data; struct msm_ext_disp_audio_edid_blk edid_blk; - int rc; + int rc = 0; + struct msm_ext_disp_codec_id codec_info; + int dai_id = kcontrol->private_value; codec_data = snd_soc_codec_get_drvdata(codec); @@ -61,8 +94,14 @@ static int msm_ext_disp_edid_ctl_info(struct snd_kcontrol *kcontrol, return 0; } + dev_dbg(codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__, + codec_data->ctl[dai_id], codec_data->stream[dai_id]); + + mutex_lock(&codec_data->dp_ops_lock); + SWITCH_DP_CODEC(codec_info, codec_data, dai_id); rc = codec_data->ext_disp_ops.get_audio_edid_blk( codec_data->ext_disp_core_pdev, &edid_blk); + mutex_unlock(&codec_data->dp_ops_lock); if (rc >= 0) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; uinfo->count = edid_blk.audio_data_blk_size + @@ -79,7 +118,9 @@ static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct msm_ext_disp_audio_codec_rx_data *codec_data; struct msm_ext_disp_audio_edid_blk edid_blk; - int rc; + struct msm_ext_disp_codec_id codec_info; + int rc = 0; + int dai_id = kcontrol->private_value; codec_data = snd_soc_codec_get_drvdata(codec); if (!codec_data || !codec_data->ext_disp_ops.get_audio_edid_blk) { @@ -88,8 +129,14 @@ static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol, return -EINVAL; } + dev_dbg(codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__, + codec_data->ctl[dai_id], codec_data->stream[dai_id]); + + mutex_lock(&codec_data->dp_ops_lock); + SWITCH_DP_CODEC(codec_info, codec_data, dai_id); rc = codec_data->ext_disp_ops.get_audio_edid_blk( codec_data->ext_disp_core_pdev, &edid_blk); + mutex_unlock(&codec_data->dp_ops_lock); if (rc >= 0) { if (sizeof(ucontrol->value.bytes.data) < (edid_blk.audio_data_blk_size + @@ -123,7 +170,9 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, struct msm_ext_disp_audio_codec_rx_data *codec_data; enum msm_ext_disp_cable_state cable_state; enum msm_ext_disp_type disp_type; - int rc; + struct msm_ext_disp_codec_id codec_info; + int rc = 0; + int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l; codec_data = snd_soc_codec_get_drvdata(codec); if (!codec_data || @@ -134,13 +183,18 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, return -EINVAL; } + dev_dbg(codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__, + codec_data->ctl[dai_id], codec_data->stream[dai_id]); + + mutex_lock(&codec_data->dp_ops_lock); + SWITCH_DP_CODEC(codec_info, codec_data, dai_id); cable_state = codec_data->ext_disp_ops.cable_status( codec_data->ext_disp_core_pdev, 1); if (cable_state < 0) { dev_err(codec->dev, "%s: Error retrieving cable state from ext_disp, err:%d\n", __func__, cable_state); rc = cable_state; - goto done; + goto cable_err; } codec_data->cable_status = cable_state; @@ -149,11 +203,12 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, __func__); ucontrol->value.integer.value[0] = 0; rc = 0; - goto done; + goto cable_err; } disp_type = codec_data->ext_disp_ops.get_intf_id( codec_data->ext_disp_core_pdev); + mutex_unlock(&codec_data->dp_ops_lock); if (disp_type >= 0) { switch (disp_type) { case EXT_DISPLAY_TYPE_DP: @@ -177,7 +232,10 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, __func__, disp_type); rc = disp_type; } + return rc; +cable_err: + mutex_unlock(&codec_data->dp_ops_lock); done: return rc; } @@ -188,7 +246,9 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct msm_ext_disp_audio_codec_rx_data *codec_data; u32 ack_state = 0; - int rc; + struct msm_ext_disp_codec_id codec_info; + int rc = 0; + int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l; codec_data = snd_soc_codec_get_drvdata(codec); if (!codec_data || @@ -200,6 +260,9 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, goto done; } + dev_dbg(codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__, + codec_data->ctl[dai_id], codec_data->stream[dai_id]); + switch (ucontrol->value.enumerated.item[0]) { case 0: ack_state = AUD_EXT_DISP_ACK_DISCONNECT; @@ -220,8 +283,11 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, dev_dbg(codec->dev, "%s: control %d, ack set value 0x%x\n", __func__, ucontrol->value.enumerated.item[0], ack_state); + mutex_lock(&codec_data->dp_ops_lock); + SWITCH_DP_CODEC(codec_info, codec_data, dai_id); rc = codec_data->ext_disp_ops.acknowledge( codec_data->ext_disp_core_pdev, ack_state); + mutex_unlock(&codec_data->dp_ops_lock); if (rc < 0) { dev_err(codec->dev, "%s: error from acknowledge(), err:%d\n", __func__, rc); @@ -231,6 +297,32 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, return rc; } +static int msm_ext_disp_audio_device_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct msm_ext_disp_audio_codec_rx_data *codec_data; + int rc = 0; + int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l; + + codec_data = snd_soc_codec_get_drvdata(codec); + if (!codec_data) { + dev_err(codec->dev, + "%s: codec_data or ops acknowledge() is NULL\n", + __func__); + rc = -EINVAL; + goto done; + } + + mutex_lock(&codec_data->dp_ops_lock); + codec_data->ctl[dai_id] = ucontrol->value.enumerated.item[0]; + codec_data->stream[dai_id] = ucontrol->value.enumerated.item[1]; + mutex_unlock(&codec_data->dp_ops_lock); + +done: + return rc; +} + static const struct snd_kcontrol_new msm_ext_disp_codec_rx_controls[] = { { .access = SNDRV_CTL_ELEM_ACCESS_READ | @@ -239,6 +331,7 @@ static const struct snd_kcontrol_new msm_ext_disp_codec_rx_controls[] = { .name = "HDMI EDID", .info = msm_ext_disp_edid_ctl_info, .get = msm_ext_disp_edid_get, + .private_value = HDMI_DAI, }, { .access = SNDRV_CTL_ELEM_ACCESS_READ | @@ -247,11 +340,36 @@ static const struct snd_kcontrol_new msm_ext_disp_codec_rx_controls[] = { .name = "Display Port EDID", .info = msm_ext_disp_edid_ctl_info, .get = msm_ext_disp_edid_get, + .private_value = DP_DAI1, }, - SOC_ENUM_EXT("External Display Type", ext_disp_audio_type, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ | + SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "Display Port1 EDID", + .info = msm_ext_disp_edid_ctl_info, + .get = msm_ext_disp_edid_get, + .private_value = DP_DAI2, + }, + SOC_ENUM_EXT("External Display Type", + ext_disp_audio_type0, + msm_ext_disp_audio_type_get, NULL), + SOC_ENUM_EXT("External Display1 Type", + ext_disp_audio_type1, msm_ext_disp_audio_type_get, NULL), - SOC_ENUM_EXT("External Display Audio Ack", ext_disp_audio_ack_state, + SOC_ENUM_EXT("External Display Audio Ack", + ext_disp_audio_ack_state0, NULL, msm_ext_disp_audio_ack_set), + SOC_ENUM_EXT("External Display1 Audio Ack", + ext_disp_audio_ack_state1, + NULL, msm_ext_disp_audio_ack_set), + + SOC_SINGLE_EXT("External Display Audio Device", + SND_SOC_NOPM, DP_DAI1, DP_STREAM_MAX, 0, + NULL, msm_ext_disp_audio_device_set), + SOC_SINGLE_EXT("External Display1 Audio Device", + SND_SOC_NOPM, DP_DAI2, DP_STREAM_MAX, 0, + NULL, msm_ext_disp_audio_device_set), }; static int msm_ext_disp_audio_codec_rx_dai_startup( @@ -259,6 +377,7 @@ static int msm_ext_disp_audio_codec_rx_dai_startup( struct snd_soc_dai *dai) { int ret = 0; + struct msm_ext_disp_codec_id codec_info; struct msm_ext_disp_audio_codec_rx_data *codec_data = dev_get_drvdata(dai->codec->dev); @@ -268,9 +387,15 @@ static int msm_ext_disp_audio_codec_rx_dai_startup( return -EINVAL; } + dev_dbg(dai->codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__, + codec_data->ctl[dai->id], codec_data->stream[dai->id]); + + mutex_lock(&codec_data->dp_ops_lock); + SWITCH_DP_CODEC(codec_info, codec_data, dai->id); codec_data->cable_status = codec_data->ext_disp_ops.cable_status( codec_data->ext_disp_core_pdev, 1); + mutex_unlock(&codec_data->dp_ops_lock); if (codec_data->cable_status < 0) { dev_err(dai->dev, "%s() ext disp core is not ready (ret val = %d)\n", @@ -295,6 +420,7 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params( u32 level_shift = 0; /* 0dB */ bool down_mix = 0; u32 num_channels = params_channels(params); + struct msm_ext_disp_codec_id codec_info; int rc = 0; struct msm_ext_disp_audio_setup_params audio_setup_params = {0}; @@ -307,6 +433,9 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params( return -EINVAL; } + dev_dbg(dai->codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__, + codec_data->ctl[dai->id], codec_data->stream[dai->id]); + if (codec_data->cable_status < 0) { dev_err_ratelimited(dai->dev, "%s() ext disp core is not ready (ret val = %d)\n", @@ -364,8 +493,11 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params( audio_setup_params.level_shift = level_shift; audio_setup_params.down_mix = down_mix; + mutex_lock(&codec_data->dp_ops_lock); + SWITCH_DP_CODEC(codec_info, codec_data, dai->id); rc = codec_data->ext_disp_ops.audio_info_setup( codec_data->ext_disp_core_pdev, &audio_setup_params); + mutex_unlock(&codec_data->dp_ops_lock); if (rc < 0) { dev_err_ratelimited(dai->dev, "%s() ext disp core is not ready, rc: %d\n", @@ -379,7 +511,8 @@ static void msm_ext_disp_audio_codec_rx_dai_shutdown( struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - int rc; + int rc = 0; + struct msm_ext_disp_codec_id codec_info; struct msm_ext_disp_audio_codec_rx_data *codec_data = dev_get_drvdata(dai->codec->dev); @@ -391,6 +524,11 @@ static void msm_ext_disp_audio_codec_rx_dai_shutdown( return; } + dev_dbg(dai->codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__, + codec_data->ctl[dai->id], codec_data->stream[dai->id]); + + mutex_lock(&codec_data->dp_ops_lock); + SWITCH_DP_CODEC(codec_info, codec_data, dai->id); rc = codec_data->ext_disp_ops.cable_status( codec_data->ext_disp_core_pdev, 0); if (rc < 0) { @@ -401,6 +539,7 @@ static void msm_ext_disp_audio_codec_rx_dai_shutdown( codec_data->ext_disp_ops.teardown_done( codec_data->ext_disp_core_pdev); + mutex_unlock(&codec_data->dp_ops_lock); } static int msm_ext_disp_audio_codec_rx_probe(struct snd_soc_codec *codec) @@ -440,6 +579,7 @@ static int msm_ext_disp_audio_codec_rx_probe(struct snd_soc_codec *codec) return -ENODEV; } + mutex_init(&codec_data->dp_ops_lock); dev_set_drvdata(codec->dev, codec_data); dev_dbg(codec->dev, "%s(): registered %s with ext disp core\n", @@ -453,6 +593,7 @@ static int msm_ext_disp_audio_codec_rx_remove(struct snd_soc_codec *codec) struct msm_ext_disp_audio_codec_rx_data *codec_data; codec_data = dev_get_drvdata(codec->dev); + mutex_destroy(&codec_data->dp_ops_lock); kfree(codec_data); return 0; @@ -467,6 +608,7 @@ static struct snd_soc_dai_ops msm_ext_disp_audio_codec_rx_dai_ops = { static struct snd_soc_dai_driver msm_ext_disp_audio_codec_rx_dais[] = { { .name = "msm_hdmi_audio_codec_rx_dai", + .id = HDMI_DAI, .playback = { .stream_name = "HDMI Playback", .channels_min = 1, @@ -480,6 +622,7 @@ static struct snd_soc_dai_driver msm_ext_disp_audio_codec_rx_dais[] = { }, { .name = "msm_dp_audio_codec_rx_dai", + .id = DP_DAI1, .playback = { .stream_name = "Display Port Playback", .channels_min = 1, @@ -487,10 +630,27 @@ static struct snd_soc_dai_driver msm_ext_disp_audio_codec_rx_dais[] = { .rate_min = 48000, .rate_max = 192000, .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_192000, + SNDRV_PCM_RATE_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S24_3LE, + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + }, + .ops = &msm_ext_disp_audio_codec_rx_dai_ops, + }, + { + .name = "msm_dp_audio_codec_rx1_dai", + .id = DP_DAI2, + .playback = { + .stream_name = "Display Port1 Playback", + .channels_min = 1, + .channels_max = 8, + .rate_min = 48000, + .rate_max = 192000, + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, }, .ops = &msm_ext_disp_audio_codec_rx_dai_ops, }, @@ -541,7 +701,7 @@ static struct platform_driver msm_ext_disp_audio_codec_rx_driver = { static int __init msm_ext_disp_audio_codec_rx_init(void) { - int rc; + int rc = 0; rc = platform_driver_register(&msm_ext_disp_audio_codec_rx_driver); if (rc) { -- GitLab From 5755008e6db86a304b0ea27fff84a50f5c7f8b59 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 3 May 2018 18:43:58 -0700 Subject: [PATCH 0282/1645] asoc: msm-pcm-routing: add audio routes for DP MST Add audio routes to support Display Port audio MST. Each end device controller stream adds a route. Change-Id: Ifb2ea38ad38efaff17e0a9502e03b5b6a0c2de45 Signed-off-by: Karthikeyan Mani --- asoc/msm-pcm-routing-v2.c | 140 +++++++++++++++++++++++++++++++++++++- asoc/msm-pcm-routing-v2.h | 2 + 2 files changed, 141 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index e8eb7ce93885..1dbba55c8494 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -540,6 +540,8 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_USB_AUDIO_TX}, { DISPLAY_PORT_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_DISPLAY_PORT}, + { DISPLAY_PORT_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_DISPLAY_PORT1}, { AFE_PORT_ID_TERTIARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_TERT_AUXPCM_RX}, { AFE_PORT_ID_TERTIARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, @@ -2895,7 +2897,7 @@ static const char *const be_name[] = { "QUIN_TDM_RX_2", "QUIN_TDM_TX_2", "QUIN_TDM_RX_3", "QUIN_TDM_TX_3", "QUIN_TDM_RX_4", "QUIN_TDM_TX_4", "QUIN_TDM_RX_5", "QUIN_TDM_TX_5", "QUIN_TDM_RX_6", "QUIN_TDM_TX_6", "QUIN_TDM_RX_7", "QUIN_TDM_TX_7", -"INT_BT_A2DP_RX", "USB_RX", "USB_TX", "DISPLAY_PORT_RX", +"INT_BT_A2DP_RX", "USB_RX", "USB_TX", "DISPLAY_PORT_RX", "DISPLAY_PORT_RX1", "TERT_AUXPCM_RX", "TERT_AUXPCM_TX", "QUAT_AUXPCM_RX", "QUAT_AUXPCM_TX", "QUIN_AUXPCM_RX", "QUIN_AUXPCM_TX", "INT0_MI2S_RX", "INT0_MI2S_TX", "INT1_MI2S_RX", "INT1_MI2S_TX", @@ -5186,6 +5188,73 @@ static const struct snd_kcontrol_new display_port_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new display_port1_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + /* incall music delivery mixer */ static const struct snd_kcontrol_new incall_music_delivery_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, @@ -9763,6 +9832,29 @@ MSM_BACKEND_DAI_DISPLAY_PORT_RX, msm_routing_put_voice_mixer), }; +static const struct snd_kcontrol_new display_port_rx1_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = { SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_BT_SCO_RX, @@ -11049,6 +11141,13 @@ static const struct snd_kcontrol_new display_port_rx_port_mixer_controls[] = { msm_routing_put_port_mixer), }; +static const struct snd_kcontrol_new display_port_rx1_port_mixer_controls[] = { + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + static const struct snd_kcontrol_new sec_i2s_rx_port_mixer_controls[] = { SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_I2S_RX, @@ -15180,6 +15279,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT", "Display Port Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT1", "Display Port1 Playback", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX", "Quaternary MI2S Playback", 0, 0, 0, 0), @@ -15523,6 +15624,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { hdmi_mixer_controls, ARRAY_SIZE(hdmi_mixer_controls)), SND_SOC_DAPM_MIXER("DISPLAY_PORT Mixer", SND_SOC_NOPM, 0, 0, display_port_mixer_controls, ARRAY_SIZE(display_port_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT1 Mixer", SND_SOC_NOPM, 0, 0, + display_port1_mixer_controls, ARRAY_SIZE(display_port1_mixer_controls)), SND_SOC_DAPM_MIXER("SPDIF_RX Audio Mixer", SND_SOC_NOPM, 0, 0, spdif_rx_mixer_controls, ARRAY_SIZE(spdif_rx_mixer_controls)), SND_SOC_DAPM_MIXER("MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, @@ -15845,6 +15948,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX Port Mixer", SND_SOC_NOPM, 0, 0, display_port_rx_port_mixer_controls, ARRAY_SIZE(display_port_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX Port1 Mixer", + SND_SOC_NOPM, 0, 0, display_port_rx1_port_mixer_controls, + ARRAY_SIZE(display_port_rx1_port_mixer_controls)), SND_SOC_DAPM_MIXER("SEC_I2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, sec_i2s_rx_port_mixer_controls, ARRAY_SIZE(sec_i2s_rx_port_mixer_controls)), @@ -15949,6 +16055,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, display_port_rx_voice_mixer_controls, ARRAY_SIZE(display_port_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX1_Voice Mixer", + SND_SOC_NOPM, 0, 0, display_port_rx1_voice_mixer_controls, + ARRAY_SIZE(display_port_rx1_voice_mixer_controls)), /* lsm mixer definitions */ SND_SOC_DAPM_MIXER("LSM1 Mixer", SND_SOC_NOPM, 0, 0, lsm1_mixer_controls, ARRAY_SIZE(lsm1_mixer_controls)), @@ -16142,6 +16251,24 @@ static const struct snd_soc_dapm_route intercon[] = { {"DISPLAY_PORT Mixer", "MultiMedia16", "MM_DL16"}, {"DISPLAY_PORT", NULL, "DISPLAY_PORT Mixer"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia1", "MM_DL1"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia2", "MM_DL2"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia3", "MM_DL3"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia4", "MM_DL4"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia5", "MM_DL5"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia6", "MM_DL6"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia7", "MM_DL7"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia8", "MM_DL8"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia9", "MM_DL9"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia10", "MM_DL10"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia11", "MM_DL11"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia12", "MM_DL12"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia13", "MM_DL13"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia14", "MM_DL14"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia15", "MM_DL15"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia16", "MM_DL16"}, + {"DISPLAY_PORT1", NULL, "DISPLAY_PORT1 Mixer"}, + {"SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"SPDIF_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, {"SPDIF_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, @@ -17454,6 +17581,13 @@ static const struct snd_soc_dapm_route intercon[] = { {"DISPLAY_PORT_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"DISPLAY_PORT", NULL, "DISPLAY_PORT_RX_Voice Mixer"}, + {"DISPLAY_PORT_RX1_Voice Mixer", "Voip", "VOIP_DL"}, + {"DISPLAY_PORT_RX1_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"DISPLAY_PORT_RX1_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"DISPLAY_PORT_RX1_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"DISPLAY_PORT_RX1_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"DISPLAY_PORT1", NULL, "DISPLAY_PORT_RX1_Voice Mixer"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"INTERNAL_BT_SCO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"INTERNAL_BT_SCO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, @@ -18568,6 +18702,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"DISPLAY_PORT_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, {"DISPLAY_PORT", NULL, "DISPLAY_PORT_RX Port Mixer"}, + {"DISPLAY_PORT_RX1 Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"DISPLAY_PORT1", NULL, "DISPLAY_PORT_RX1 Port Mixer"}, + {"SEC_I2S_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, {"SEC_I2S_RX", NULL, "SEC_I2S_RX Port Mixer"}, @@ -18643,6 +18780,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "USB_AUDIO_RX"}, {"BE_OUT", NULL, "HDMI"}, {"BE_OUT", NULL, "DISPLAY_PORT"}, + {"BE_OUT", NULL, "DISPLAY_PORT1"}, {"BE_OUT", NULL, "SPDIF_RX"}, {"BE_OUT", NULL, "MI2S_RX"}, {"BE_OUT", NULL, "QUAT_MI2S_RX"}, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 19c710c4b4a5..b0026124000d 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -25,6 +25,7 @@ #define LPASS_BE_SLIMBUS_0_TX "SLIMBUS_0_TX" #define LPASS_BE_HDMI "HDMI" #define LPASS_BE_DISPLAY_PORT "DISPLAY_PORT" +#define LPASS_BE_DISPLAY_PORT1 "DISPLAY_PORT1" #define LPASS_BE_INT_BT_SCO_RX "INT_BT_SCO_RX" #define LPASS_BE_INT_BT_SCO_TX "INT_BT_SCO_TX" #define LPASS_BE_INT_BT_A2DP_RX "INT_BT_A2DP_RX" @@ -377,6 +378,7 @@ enum { MSM_BACKEND_DAI_USB_RX, MSM_BACKEND_DAI_USB_TX, MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_BACKEND_DAI_QUAT_AUXPCM_RX, -- GitLab From 29dfffc4b2797f7c44d8f5bfadb584590b8292ca Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 3 May 2018 18:48:14 -0700 Subject: [PATCH 0283/1645] asoc: sm8150: add dai link for dp audio multi stream transport Add dai link with the newly added BE codec dai and the same AFE CPU dai to support another stream for dp audio. Change-Id: I747107441a310e5e768dc9757093c7bba424a0d7 Signed-off-by: Karthikeyan Mani --- asoc/sm8150.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/asoc/sm8150.c b/asoc/sm8150.c index a0b669216c38..513d8447f913 100644 --- a/asoc/sm8150.c +++ b/asoc/sm8150.c @@ -6333,6 +6333,21 @@ static struct snd_soc_dai_link ext_disp_be_dai_link[] = { .ignore_pmdown_time = 1, .ignore_suspend = 1, }, + /* DISP PORT 1 BACK END DAI Link */ + { + .name = LPASS_BE_DISPLAY_PORT1, + .stream_name = "Display Port1 Playback", + .cpu_dai_name = "msm-dai-q6-dp.24608", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-ext-disp-audio-codec-rx", + .codec_dai_name = "msm_dp_audio_codec_rx1_dai", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { -- GitLab From dbfc6a776a0124de10155e45a5671cb6d7a3d878 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 17 May 2018 17:19:09 -0700 Subject: [PATCH 0284/1645] asoc: codecs: wcd934x: add stub functions for codec APIs If wcd934x config is removed, need to stub out the APIs to load any dependent audio modules and enumerate sound card. Change-Id: If885d4d1f0ee83448ac41ed66b51f078978cb7d1 Signed-off-by: Karthikeyan Mani Signed-off-by: Vidyakumar Athota --- asoc/codecs/wcd934x/wcd934x.c | 2 +- asoc/codecs/wcd934x/wcd934x.h | 68 ++++++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 9083aa663e8e..36a067432c64 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -9885,7 +9885,7 @@ static void tavil_cdc_vote_svs(struct snd_soc_codec *codec, bool vote) return tavil_vote_svs(tavil, vote); } -struct wcd_dsp_cdc_cb cdc_cb = { +static struct wcd_dsp_cdc_cb cdc_cb = { .cdc_clk_en = tavil_codec_internal_rco_ctrl, .cdc_vote_svs = tavil_cdc_vote_svs, }; diff --git a/asoc/codecs/wcd934x/wcd934x.h b/asoc/codecs/wcd934x/wcd934x.h index ccd48ff2099f..926096a7c12f 100644 --- a/asoc/codecs/wcd934x/wcd934x.h +++ b/asoc/codecs/wcd934x/wcd934x.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -134,6 +134,7 @@ struct tavil_reg_mask_val { u8 val; }; +#if IS_ENABLED(CONFIG_SND_SOC_WCD934X) extern void *tavil_get_afe_config(struct snd_soc_codec *codec, enum afe_config_type config_type); extern int tavil_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable); @@ -156,4 +157,69 @@ extern struct tavil_dsd_config *tavil_get_dsd_config( extern int tavil_codec_info_create_codec_entry( struct snd_info_entry *codec_root, struct snd_soc_codec *codec); +#else +extern void *tavil_get_afe_config(struct snd_soc_codec *codec, + enum afe_config_type config_type) +{ + return NULL; +} +extern int tavil_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable) +{ + return 0; +} +extern int tavil_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable) +{ + return 0; +} +extern int tavil_set_spkr_mode(struct snd_soc_codec *codec, int mode) +{ + return 0; +} +extern int tavil_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset) +{ + return 0; +} +extern struct wcd_dsp_cntl *tavil_get_wcd_dsp_cntl(struct device *dev) +{ + return NULL; +} +extern int wcd934x_get_micb_vout_ctl_val(u32 micb_mv) +{ + return 0; +} +extern int tavil_micbias_control(struct snd_soc_codec *codec, + int micb_num, + int req, bool is_dapm) +{ + return 0; +} +extern int tavil_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, + int req_volt, + int micb_num) +{ + return 0; +} +extern struct wcd934x_mbhc *tavil_soc_get_mbhc(struct snd_soc_codec *codec) +{ + return NULL; +} +extern int tavil_codec_enable_interp_clk(struct snd_soc_codec *codec, + int event, int intp_idx) +{ + return 0; +} +extern struct tavil_dsd_config *tavil_get_dsd_config( + struct snd_soc_codec *codec) +{ + return NULL; +} +extern int tavil_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + return 0; +} + +#endif + #endif -- GitLab From c9dd3be3c3e200568ff13c20e2ef5aeb4c7cc022 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 6 Apr 2018 00:51:48 +0530 Subject: [PATCH 0285/1645] ASoC: wsa881x: Avoid query temp during suspend Runtime suspend in slimbus driver makes QMI call which takes wakelock and result in first system suspend to fail. As a result of first suspend fail, POST_PM_SUSPEND event is dispatched to thermal core which registered to pm notifier. WSA being one of registered thermal zone gets query for temperature, and makes slimbus reads/writes which will result in runtime resume of slimbus driver to happen. System suspend fails again continuously in this endless loop as slimbus runtime suspend will make QMI call again. Update wsa temp sensor to handle suspend event by registering to pm notifier and ignore the temperature request from thermal core at resume. This will avoid slimbus reads/writes during suspend in progress and allow XO shutdown to happen. Change-Id: Id13a9701cffb1231ef7d563cbc30756fd71d5868 Signed-off-by: Laxminath Kasam Signed-off-by: Sudheer Papothi --- asoc/codecs/wsa881x-temp-sensor.c | 47 ++++++++++++++++++++++++++++++- asoc/codecs/wsa881x-temp-sensor.h | 6 +++- asoc/codecs/wsa881x.c | 28 ++++++++++++++++++ 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wsa881x-temp-sensor.c b/asoc/codecs/wsa881x-temp-sensor.c index 5ab0ecfdc022..b2ed963b7e22 100644 --- a/asoc/codecs/wsa881x-temp-sensor.c +++ b/asoc/codecs/wsa881x-temp-sensor.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. +/* Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -61,6 +62,20 @@ int wsa881x_get_temp(struct thermal_zone_device *thermal, pr_err("%s: pdata is NULL\n", __func__); return -EINVAL; } + if (atomic_cmpxchg(&pdata->is_suspend_spk, 1, 0)) { + /* + * get_temp query happens as part of POST_PM_SUSPEND + * from thermal core. To avoid calls to slimbus + * as part of this thermal query, return default temp + * and reset the suspend flag. + */ + if (!pdata->t0_init) { + if (temp) + *temp = pdata->curr_temp; + return 0; + } + } + temp_retry: if (pdata->wsa_temp_reg_read) { ret = pdata->wsa_temp_reg_read(codec, ®); @@ -108,6 +123,8 @@ int wsa881x_get_temp(struct thermal_zone_device *thermal, goto temp_retry; } } + pdata->curr_temp = temp_val; + if (temp) *temp = temp_val; pr_debug("%s: t0 measured: %d dmeas = %d, d1 = %d, d2 = %d\n", @@ -120,6 +137,23 @@ static struct thermal_zone_device_ops wsa881x_thermal_ops = { .get_temp = wsa881x_get_temp, }; + +static int wsa881x_pm_notify(struct notifier_block *nb, + unsigned long mode, void *_unused) +{ + struct wsa881x_tz_priv *pdata = + container_of(nb, struct wsa881x_tz_priv, pm_nb); + + switch (mode) { + case PM_SUSPEND_PREPARE: + atomic_set(&pdata->is_suspend_spk, 1); + break; + default: + break; + } + return 0; +} + int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata) { struct thermal_zone_device *tz_dev; @@ -137,12 +171,23 @@ int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata) return -EINVAL; } tz_pdata->tz_dev = tz_dev; + tz_pdata->pm_nb.notifier_call = wsa881x_pm_notify; + register_pm_notifier(&tz_pdata->pm_nb); + atomic_set(&tz_pdata->is_suspend_spk, 0); + return 0; } EXPORT_SYMBOL(wsa881x_init_thermal); void wsa881x_deinit_thermal(struct thermal_zone_device *tz_dev) { + struct wsa881x_tz_priv *pdata; + + if (tz_dev && tz_dev->devdata) { + pdata = tz_dev->devdata; + if (pdata) + unregister_pm_notifier(&pdata->pm_nb); + } if (tz_dev) thermal_zone_device_unregister(tz_dev); } diff --git a/asoc/codecs/wsa881x-temp-sensor.h b/asoc/codecs/wsa881x-temp-sensor.h index d6c1eb75e940..26828b716d07 100644 --- a/asoc/codecs/wsa881x-temp-sensor.h +++ b/asoc/codecs/wsa881x-temp-sensor.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -31,6 +31,10 @@ struct wsa881x_tz_priv { struct wsa_temp_register *wsa_temp_reg; char name[80]; wsa_temp_register_read wsa_temp_reg_read; + struct notifier_block pm_nb; + atomic_t is_suspend_spk; + int t0_init; + int curr_temp; }; int wsa881x_get_temp(struct thermal_zone_device *tz_dev, int *temp); diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index 0755cdcab8b6..2ef9e0a60478 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -200,12 +200,40 @@ static int wsa881x_set_mute(struct snd_kcontrol *kcontrol, return 0; } +static int wsa881x_get_t0_init(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct wsa881x_tz_priv *pdata = &wsa881x->tz_pdata; + + ucontrol->value.integer.value[0] = pdata->t0_init; + dev_dbg(codec->dev, "%s: t0 init %d\n", __func__, pdata->t0_init); + + return 0; +} + +static int wsa881x_set_t0_init(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct wsa881x_tz_priv *pdata = &wsa881x->tz_pdata; + + pdata->t0_init = ucontrol->value.integer.value[0]; + dev_dbg(codec->dev, "%s: t0 init %d\n", __func__, pdata->t0_init); + + return 0; +} static const struct snd_kcontrol_new wsa_snd_controls[] = { SOC_ENUM_EXT("WSA PA Gain", wsa_pa_gain_enum, wsa_pa_gain_get, wsa_pa_gain_put), SOC_SINGLE_EXT("WSA PA Mute", SND_SOC_NOPM, 0, 1, 0, wsa881x_get_mute, wsa881x_set_mute), + SOC_SINGLE_EXT("WSA T0 Init", SND_SOC_NOPM, 0, 1, 0, + wsa881x_get_t0_init, wsa881x_set_t0_init), }; static int codec_debug_open(struct inode *inode, struct file *file) -- GitLab From f0e329cb51e85132c5180db8334dda45d71090c5 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 17 May 2018 17:23:26 -0700 Subject: [PATCH 0286/1645] asoc: codecs: wcd9360: add stub functions for codec APIs If wcd9360 config is removed, need to stub out the APIs to load any dependent audio modules and enumerate sound card. Change-Id: I821938c68849984ee04565167488abe5fe15af40 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd9360/wcd9360.c | 2 +- asoc/codecs/wcd9360/wcd9360.h | 39 +++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd9360/wcd9360.c b/asoc/codecs/wcd9360/wcd9360.c index cb13e475ecdb..075a77fb60ca 100644 --- a/asoc/codecs/wcd9360/wcd9360.c +++ b/asoc/codecs/wcd9360/wcd9360.c @@ -7122,7 +7122,7 @@ static void pahu_cdc_vote_svs(struct snd_soc_codec *codec, bool vote) return pahu_vote_svs(pahu, vote); } -struct wcd_dsp_cdc_cb cdc_cb = { +static struct wcd_dsp_cdc_cb cdc_cb = { .cdc_clk_en = pahu_codec_internal_rco_ctrl, .cdc_vote_svs = pahu_cdc_vote_svs, }; diff --git a/asoc/codecs/wcd9360/wcd9360.h b/asoc/codecs/wcd9360/wcd9360.h index 2c70a6853499..04fb76d1a838 100644 --- a/asoc/codecs/wcd9360/wcd9360.h +++ b/asoc/codecs/wcd9360/wcd9360.h @@ -127,6 +127,7 @@ struct pahu_reg_mask_val { u8 val; }; +#if IS_ENABLED(CONFIG_SND_SOC_WCD9360) extern void *pahu_get_afe_config(struct snd_soc_codec *codec, enum afe_config_type config_type); extern int pahu_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable); @@ -138,4 +139,42 @@ extern int wcd9360_get_micb_vout_ctl_val(u32 micb_mv); extern int pahu_codec_info_create_codec_entry( struct snd_info_entry *codec_root, struct snd_soc_codec *codec); +#else +extern void *pahu_get_afe_config(struct snd_soc_codec *codec, + enum afe_config_type config_type) +{ + return NULL; +} +extern int pahu_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable) +{ + return 0; +} +extern int pahu_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable) +{ + return 0; +} +extern int pahu_set_spkr_mode(struct snd_soc_codec *codec, int mode) +{ + return 0; +} +extern int pahu_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset) +{ + return 0; +} +extern void *pahu_get_wcd_dsp_cntl(struct device *dev) +{ + return NULL; +} +extern int wcd9360_get_micb_vout_ctl_val(u32 micb_mv) +{ + return 0; +} +extern int pahu_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + return 0; +} +#endif + #endif -- GitLab From eab9a2b762288029deb49da9c05f507336d9ddec Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 2 May 2018 14:55:53 +0800 Subject: [PATCH 0287/1645] ipc: apr: use of_platform_populate to add child node of apr Use of_platform_populate to add child node of apr. Change-Id: I9f0ded5e39deaf37c79ecda4d960d64c9c14eec9 Signed-off-by: Meng Wang --- ipc/apr.c | 62 +++++++++---------------------------------------------- 1 file changed, 10 insertions(+), 52 deletions(-) diff --git a/ipc/apr.c b/ipc/apr.c index 3f07f6e87b6c..a8ff3631ee48 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -62,8 +63,6 @@ struct apr_private { spinlock_t apr_lock; bool is_initial_boot; struct work_struct add_chld_dev_work; - spinlock_t apr_chld_lock; - struct list_head apr_chlds; }; static struct apr_private *apr_priv; @@ -290,7 +289,7 @@ enum apr_subsys_state apr_cmpxchg_q6_state(enum apr_subsys_state prev, static void apr_adsp_down(unsigned long opcode) { - pr_debug("%s: Q6 is Down\n", __func__); + pr_info("%s: Q6 is Down\n", __func__); apr_set_q6_state(APR_SUBSYS_DOWN); dispatch_event(opcode, APR_DEST_QDSP6); } @@ -298,49 +297,17 @@ static void apr_adsp_down(unsigned long opcode) static void apr_add_child_devices(struct work_struct *work) { int ret; - struct device_node *node; - struct platform_device *pdev; - struct apr_chld_device *apr_chld_dev; - - for_each_child_of_node(apr_priv->dev->of_node, node) { - apr_chld_dev = kzalloc(sizeof(*apr_chld_dev), GFP_KERNEL); - if (!apr_chld_dev) - continue; - pdev = platform_device_alloc(node->name, -1); - if (!pdev) { - dev_err(apr_priv->dev, - "%s: pdev memory alloc failed for %s\n", - __func__, node->name); - kfree(apr_chld_dev); - continue; - } - pdev->dev.parent = apr_priv->dev; - pdev->dev.of_node = node; - - ret = platform_device_add(pdev); - if (ret) { - dev_err(apr_priv->dev, - "%s: Cannot add platform device %s\n", - __func__, node->name); - platform_device_put(pdev); - kfree(apr_chld_dev); - continue; - } - - apr_chld_dev->pdev = pdev; - spin_lock(&apr_priv->apr_chld_lock); - list_add_tail(&apr_chld_dev->node, &apr_priv->apr_chlds); - spin_unlock(&apr_priv->apr_chld_lock); - - dev_dbg(apr_priv->dev, "%s: Added APR child dev: %s\n", - __func__, dev_name(&pdev->dev)); - } + ret = of_platform_populate(apr_priv->dev->of_node, + NULL, NULL, apr_priv->dev); + if (ret) + dev_err(apr_priv->dev, "%s: failed to add child nodes, ret=%d\n", + __func__, ret); } static void apr_adsp_up(void) { - pr_debug("%s: Q6 is Up\n", __func__); + pr_info("%s: Q6 is Up\n", __func__); if (apr_cmpxchg_q6_state(APR_SUBSYS_DOWN, APR_SUBSYS_LOADED) == APR_SUBSYS_DOWN) wake_up(&dsp_wait); @@ -1165,6 +1132,7 @@ static void apr_cleanup(void) { int i, j, k; + of_platform_depopulate(apr_priv->dev); subsys_notif_deregister("apr_modem"); subsys_notif_deregister("apr_adsp"); if (apr_reset_workqueue) { @@ -1179,6 +1147,7 @@ static void apr_cleanup(void) mutex_destroy(&client[i][j].svc[k].m_lock); } } + debugfs_remove(debugfs_apr_debug); } static int apr_probe(struct platform_device *pdev) @@ -1194,8 +1163,6 @@ static int apr_probe(struct platform_device *pdev) apr_priv->dev = &pdev->dev; spin_lock_init(&apr_priv->apr_lock); - spin_lock_init(&apr_priv->apr_chld_lock); - INIT_LIST_HEAD(&apr_priv->apr_chlds); INIT_WORK(&apr_priv->add_chld_dev_work, apr_add_child_devices); for (i = 0; i < APR_DEST_MAX; i++) @@ -1233,17 +1200,8 @@ static int apr_probe(struct platform_device *pdev) static int apr_remove(struct platform_device *pdev) { - struct apr_chld_device *chld, *tmp; - apr_cleanup(); apr_tal_exit(); - spin_lock(&apr_priv->apr_chld_lock); - list_for_each_entry_safe(chld, tmp, &apr_priv->apr_chlds, node) { - platform_device_unregister(chld->pdev); - list_del(&chld->node); - kfree(chld); - } - spin_unlock(&apr_priv->apr_chld_lock); apr_priv = NULL; return 0; } -- GitLab From f0ec686d3b9bfa2eb2d2f4db73a8418a9e46add0 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Wed, 21 Mar 2018 17:43:38 -0700 Subject: [PATCH 0288/1645] asoc: msm-lsm-client: add support for ADSP Generic Detection Event ADSP detection engine module can raise Generic Detection Event to provide variable payload data based on the information requested by userspace. Adding new API/interface to provide support for Generic Detection Event in LSM drivers. Change-Id: Id5541f959ecdcf862dcfa1de1c1a1b3a796f260c Signed-off-by: Xiaoyu Ye --- asoc/msm-lsm-client.c | 382 ++++++++++++++++++++++++++++++------- dsp/q6lsm.c | 26 +++ include/dsp/apr_audio-v2.h | 1 + include/dsp/q6lsm.h | 7 + 4 files changed, 343 insertions(+), 73 deletions(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index c00f5c25cfa2..6f51236f9960 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -79,6 +79,7 @@ struct lsm_priv { struct snd_pcm_substream *substream; struct lsm_client *lsm_client; struct snd_lsm_event_status_v3 *event_status; + struct snd_lsm_event_status *det_event; spinlock_t event_lock; wait_queue_head_t event_wait; unsigned long event_avail; @@ -294,6 +295,46 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, payload_size); break; + case LSM_SESSION_DETECTION_ENGINE_GENERIC_EVENT: { + struct snd_lsm_event_status *tmp; + + status = ((uint16_t *)payload)[0]; + payload_size = ((uint16_t *)payload)[1]; + + spin_lock_irqsave(&prtd->event_lock, flags); + tmp = krealloc(prtd->det_event, + sizeof(struct snd_lsm_event_status) + + payload_size, GFP_ATOMIC); + if (!tmp) { + spin_unlock_irqrestore(&prtd->event_lock, flags); + dev_err(rtd->dev, + "%s: Failed to allocate memory for %s, size = %lu\n", + __func__, + "LSM_SESSION_DETECTION_ENGINE_GENERIC_EVENT", + sizeof(struct snd_lsm_event_status) + + payload_size); + return; + } + + prtd->det_event = tmp; + prtd->det_event->status = status; + prtd->det_event->payload_size = payload_size; + memcpy(prtd->det_event->payload, &((uint8_t *)payload)[4], + payload_size); + prtd->event_avail = 1; + spin_unlock_irqrestore(&prtd->event_lock, flags); + wake_up(&prtd->event_wait); + + if (substream->timer_running) + snd_timer_interrupt(substream->timer, 1); + + dev_dbg(rtd->dev, + "%s: Generic det event status = %d payload size = %d\n", + __func__, prtd->det_event->status, + prtd->det_event->payload_size); + break; + } + default: break; } @@ -719,6 +760,46 @@ static int msm_lsm_set_poll_enable(struct snd_pcm_substream *substream, return rc; } +static int msm_lsm_set_det_event_type(struct snd_pcm_substream *substream, + struct lsm_params_info *p_info) +{ + struct snd_lsm_det_event_type det_event_type; + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int rc = 0; + + if (p_info->param_size != sizeof(det_event_type)) { + dev_err(rtd->dev, + "%s: Invalid param_size %d\n", + __func__, p_info->param_size); + rc = -EINVAL; + goto done; + } + + if (copy_from_user(&det_event_type, p_info->param_data, + sizeof(det_event_type))) { + dev_err(rtd->dev, + "%s: copy_from_user failed, size = %zd\n", + __func__, sizeof(det_event_type)); + rc = -EFAULT; + goto done; + } + + rc = q6lsm_set_one_param(prtd->lsm_client, p_info, + &det_event_type, LSM_DET_EVENT_TYPE); + if (!rc) + prtd->lsm_client->event_type = det_event_type.event_type; + else + dev_err(rtd->dev, + "%s: Failed to set detection event type %s, err = %d\n", + __func__, (det_event_type.event_type ? + "LSM_DET_EVENT_TYPE_GENERIC" : + "LSM_DET_EVENT_TYPE_LEGACY"), rc); +done: + return rc; +} + static int msm_lsm_process_params(struct snd_pcm_substream *substream, struct snd_lsm_module_params *p_data, void *params) @@ -762,6 +843,9 @@ static int msm_lsm_process_params(struct snd_pcm_substream *substream, case LSM_POLLING_ENABLE: rc = msm_lsm_set_poll_enable(substream, p_info); break; + case LSM_DET_EVENT_TYPE: + rc = msm_lsm_set_det_event_type(substream, p_info); + break; default: dev_err(rtd->dev, "%s: Invalid param_type %d\n", @@ -781,6 +865,30 @@ static int msm_lsm_process_params(struct snd_pcm_substream *substream, return rc; } +static int msm_lsm_start_lab_buffer(struct lsm_priv *prtd, uint16_t status) +{ + struct lsm_client *lsm_client = prtd->lsm_client; + int rc = 0; + + if (lsm_client && lsm_client->lab_enable && + !lsm_client->lab_started && + status == LSM_VOICE_WAKEUP_STATUS_DETECTED) { + atomic_set(&prtd->read_abort, 0); + atomic_set(&prtd->buf_count, 0); + prtd->appl_cnt = 0; + prtd->dma_write = 0; + + rc = msm_lsm_queue_lab_buffer(prtd, 0); + if (rc) + pr_err("%s: Queue buffer failed for lab rc = %d\n", + __func__, rc); + else + prtd->lsm_client->lab_started = true; + } + + return rc; +} + static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) { @@ -1026,26 +1134,9 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, payload_size); } } - if (!rc) { - if (prtd->lsm_client->lab_enable - && !prtd->lsm_client->lab_started - && prtd->event_status->status == - LSM_VOICE_WAKEUP_STATUS_DETECTED) { - atomic_set(&prtd->read_abort, 0); - atomic_set(&prtd->buf_count, 0); - prtd->appl_cnt = 0; - prtd->dma_write = 0; - rc = msm_lsm_queue_lab_buffer(prtd, - 0); - if (rc) - dev_err(rtd->dev, - "%s: Queue buffer failed for lab rc = %d\n", - __func__, rc); - else - prtd->lsm_client->lab_started - = true; - } - } + + if (!rc) + rc = msm_lsm_start_lab_buffer(prtd, status); } else if (xchg) { dev_dbg(rtd->dev, "%s: Wait aborted\n", __func__); rc = 0; @@ -1053,6 +1144,76 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, break; } + case SNDRV_LSM_GENERIC_DET_EVENT: { + struct snd_lsm_event_status *user = arg; + uint16_t status = 0; + uint16_t payload_size = 0; + + dev_dbg(rtd->dev, + "%s: SNDRV_LSM_GENERIC_DET_EVENT\n", __func__); + + atomic_set(&prtd->event_wait_stop, 0); + + /* + * Release the api lock before wait to allow + * other IOCTLs to be invoked while waiting + * for event + */ + mutex_unlock(&prtd->lsm_api_lock); + rc = wait_event_freezable(prtd->event_wait, + (cmpxchg(&prtd->event_avail, 1, 0) || + (xchg = atomic_cmpxchg(&prtd->event_wait_stop, + 1, 0)))); + mutex_lock(&prtd->lsm_api_lock); + + dev_dbg(rtd->dev, "%s: wait_event_freezable %d event_wait_stop %d\n", + __func__, rc, xchg); + + if (!rc && !xchg) { + dev_dbg(rtd->dev, "%s: %s: New event available %ld\n", + __func__, "SNDRV_LSM_GENERIC_DET_EVENT", + prtd->event_avail); + + spin_lock_irqsave(&prtd->event_lock, flags); + + if (prtd->det_event) { + payload_size = prtd->det_event->payload_size; + status = prtd->det_event->status; + spin_unlock_irqrestore(&prtd->event_lock, + flags); + } else { + spin_unlock_irqrestore(&prtd->event_lock, + flags); + dev_err(rtd->dev, + "%s: %s: prtd->event_status is NULL\n", + __func__, + "SNDRV_LSM_GENERIC_DET_EVENT"); + rc = -EINVAL; + break; + } + + if (user->payload_size < payload_size) { + dev_err(rtd->dev, + "%s: provided %d bytes isn't enough, needs %d bytes\n", + __func__, user->payload_size, + payload_size); + rc = -ENOMEM; + break; + } + user->status = status; + user->payload_size = payload_size; + memcpy(user->payload, prtd->det_event->payload, + payload_size); + + rc = msm_lsm_start_lab_buffer(prtd, status); + } else if (xchg) { + dev_dbg(rtd->dev, "%s: %s: Wait aborted\n", + __func__, "SNDRV_LSM_GENERIC_DET_EVENT"); + rc = 0; + } + break; + } + case SNDRV_LSM_ABORT_EVENT: dev_dbg(rtd->dev, "%s: Aborting event status wait\n", __func__); @@ -1211,6 +1372,28 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, return rc; } + +static int msm_lsm_check_event_type(struct lsm_client *lsm_client, + unsigned int cmd) +{ + int err = 0; + uint32_t event_type = lsm_client->event_type; + + if (cmd == SNDRV_LSM_EVENT_STATUS && + event_type != LSM_DET_EVENT_TYPE_LEGACY) { + pr_err("%s: %s: Invalid event request\n", + __func__, "SNDRV_LSM_EVENT_STATUS"); + err = -EINVAL; + } else if (cmd == SNDRV_LSM_GENERIC_DET_EVENT && + event_type != LSM_DET_EVENT_TYPE_GENERIC) { + pr_err("%s: %s: Invalid event request\n", + __func__, "SNDRV_LSM_GENERIC_DET_EVENT"); + err = -EINVAL; + } + + return err; +} + #ifdef CONFIG_COMPAT struct snd_lsm_event_status32 { @@ -1292,20 +1475,34 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, mutex_lock(&prtd->lsm_api_lock); switch (cmd) { - case SNDRV_LSM_EVENT_STATUS: { - struct snd_lsm_event_status *user = NULL, userarg32; - struct snd_lsm_event_status *user32 = NULL; + case SNDRV_LSM_EVENT_STATUS: + case SNDRV_LSM_GENERIC_DET_EVENT: { + struct snd_lsm_event_status userarg32, *user32 = NULL; + struct snd_lsm_event_status *user = NULL; + + dev_dbg(rtd->dev, + "%s: %s\n", __func__, + (cmd == SNDRV_LSM_EVENT_STATUS) ? + "SNDRV_LSM_EVENT_STATUS" : + "SNDRV_LSM_GENERIC_DET_EVENT"); + + err = msm_lsm_check_event_type(prtd->lsm_client, cmd); + if (err) + goto done; if (copy_from_user(&userarg32, arg, sizeof(userarg32))) { - dev_err(rtd->dev, "%s: err copyuser ioctl %s\n", - __func__, "SNDRV_LSM_EVENT_STATUS"); + dev_err(rtd->dev, "%s: %s: Failed to copy from user\n", + __func__, (cmd == SNDRV_LSM_EVENT_STATUS) ? + "SNDRV_LSM_EVENT_STATUS" : + "SNDRV_LSM_GENERIC_DET_EVENT"); err = -EFAULT; goto done; } if (userarg32.payload_size > LISTEN_MAX_STATUS_PAYLOAD_SIZE) { - pr_err("%s: payload_size %d is invalid, max allowed = %d\n", + dev_err(rtd->dev, + "%s: payload_size %d is invalid, max allowed = %d\n", __func__, userarg32.payload_size, LISTEN_MAX_STATUS_PAYLOAD_SIZE); err = -EINVAL; @@ -1315,49 +1512,50 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, size = sizeof(*user) + userarg32.payload_size; user = kzalloc(size, GFP_KERNEL); if (!user) { + err = -ENOMEM; + goto done; + } + + user->payload_size = userarg32.payload_size; + err = msm_lsm_ioctl_shared(substream, cmd, user); + if (err) { dev_err(rtd->dev, - "%s: Allocation failed event status size %d\n", - __func__, size); - err = -EFAULT; + "%s: msm_lsm_ioctl_shared() failed, err = %d", + __func__, err); + kfree(user); goto done; - } else { - cmd = SNDRV_LSM_EVENT_STATUS; - user->payload_size = userarg32.payload_size; - err = msm_lsm_ioctl_shared(substream, cmd, user); } /* Update size with actual payload size */ size = sizeof(userarg32) + user->payload_size; - if (!err && !access_ok(VERIFY_WRITE, arg, size)) { + if (!access_ok(VERIFY_WRITE, arg, size)) { dev_err(rtd->dev, - "%s: write verify failed size %d\n", + "%s: Failed to verify write, size = %d\n", __func__, size); err = -EFAULT; + kfree(user); + goto done; } - if (!err) { - user32 = kzalloc(size, GFP_KERNEL); - if (!user32) { - dev_err(rtd->dev, - "%s: Allocation event user status size %d\n", - __func__, size); - err = -EFAULT; - } else { - user32->status = user->status; - user32->payload_size = user->payload_size; - memcpy(user32->payload, - user->payload, user32->payload_size); - } + + user32 = kzalloc(size, GFP_KERNEL); + if (!user32) { + err = -ENOMEM; + kfree(user); + goto done; } - if (!err && (copy_to_user(arg, user32, size))) { - dev_err(rtd->dev, "%s: failed to copy payload %d", + user32->status = user->status; + user32->payload_size = user->payload_size; + memcpy(user32->payload, user->payload, + user32->payload_size); + + if (copy_to_user(arg, user32, size)) { + dev_err(rtd->dev, + "%s: Failed to copy payload to user, size = %d", __func__, size); err = -EFAULT; } kfree(user); kfree(user32); - if (err) - dev_err(rtd->dev, "%s: lsmevent failed %d", - __func__, err); break; } @@ -1365,10 +1563,19 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, struct snd_lsm_event_status_v3_32 userarg32, *user32 = NULL; struct snd_lsm_event_status_v3 *user = NULL; + if (prtd->lsm_client->event_type != + LSM_DET_EVENT_TYPE_LEGACY) { + dev_err(rtd->dev, + "%s: %s: Invalid event request\n", + __func__, "SNDRV_LSM_EVENT_STATUS_V3_32"); + err = -EINVAL; + goto done; + } + if (copy_from_user(&userarg32, arg, sizeof(userarg32))) { dev_err(rtd->dev, "%s: err copyuser ioctl %s\n", __func__, "SNDRV_LSM_EVENT_STATUS_V3_32"); - err = -EINVAL; + err = -EFAULT; goto done; } @@ -1789,22 +1996,35 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, break; } - case SNDRV_LSM_EVENT_STATUS: { - struct snd_lsm_event_status *user = NULL, userarg; + case SNDRV_LSM_EVENT_STATUS: + case SNDRV_LSM_GENERIC_DET_EVENT: { + struct snd_lsm_event_status *user = NULL; + struct snd_lsm_event_status userarg; dev_dbg(rtd->dev, - "%s: SNDRV_LSM_EVENT_STATUS\n", __func__); + "%s: %s\n", __func__, + (cmd == SNDRV_LSM_EVENT_STATUS) ? + "SNDRV_LSM_EVENT_STATUS" : + "SNDRV_LSM_GENERIC_DET_EVENT"); + + err = msm_lsm_check_event_type(prtd->lsm_client, cmd); + if (err) + goto done; + if (copy_from_user(&userarg, arg, sizeof(userarg))) { dev_err(rtd->dev, - "%s: err copyuser event_status\n", - __func__); + "%s: %s: Copy from user failed\n", __func__, + (cmd == SNDRV_LSM_EVENT_STATUS) ? + "SNDRV_LSM_EVENT_STATUS" : + "SNDRV_LSM_GENERIC_DET_EVENT"); err = -EFAULT; goto done; } if (userarg.payload_size > LISTEN_MAX_STATUS_PAYLOAD_SIZE) { - pr_err("%s: payload_size %d is invalid, max allowed = %d\n", + dev_err(rtd->dev, + "%s: payload_size %d is invalid, max allowed = %d\n", __func__, userarg.payload_size, LISTEN_MAX_STATUS_PAYLOAD_SIZE); err = -EINVAL; @@ -1812,37 +2032,40 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, } size = sizeof(struct snd_lsm_event_status) + - userarg.payload_size; + userarg.payload_size; user = kzalloc(size, GFP_KERNEL); if (!user) { - dev_err(rtd->dev, - "%s: Allocation failed event status size %d\n", - __func__, size); - err = -EFAULT; + err = -ENOMEM; goto done; } + user->payload_size = userarg.payload_size; err = msm_lsm_ioctl_shared(substream, cmd, user); + if (err) { + dev_err(rtd->dev, + "%s: msm_lsm_ioctl_shared() failed, err = %d", + __func__, err); + kfree(user); + goto done; + } /* Update size with actual payload size */ size = sizeof(*user) + user->payload_size; - if (!err && !access_ok(VERIFY_WRITE, arg, size)) { + if (!access_ok(VERIFY_WRITE, arg, size)) { dev_err(rtd->dev, - "%s: write verify failed size %d\n", + "%s: Failed to verify write, size = %d\n", __func__, size); err = -EFAULT; } - if (!err && (copy_to_user(arg, user, size))) { + if (!err && copy_to_user(arg, user, size)) { dev_err(rtd->dev, - "%s: failed to copy payload %d", + "%s: Failed to copy payload to user, size = %d\n", __func__, size); err = -EFAULT; } + kfree(user); - if (err) - dev_err(rtd->dev, - "%s: lsmevent failed %d", __func__, err); - goto done; + break; } case SNDRV_LSM_EVENT_STATUS_V3: { @@ -1851,6 +2074,16 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, dev_dbg(rtd->dev, "%s: SNDRV_LSM_EVENT_STATUS_V3\n", __func__); + + if (prtd->lsm_client->event_type != + LSM_DET_EVENT_TYPE_LEGACY) { + dev_err(rtd->dev, + "%s: %s: Invalid event request\n", + __func__, "SNDRV_LSM_EVENT_STATUS_V3"); + err = -EINVAL; + goto done; + } + if (!arg) { dev_err(rtd->dev, "%s: Invalid params event_status_v3\n", @@ -1983,6 +2216,7 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) prtd->lsm_client->poll_enable = true; prtd->lsm_client->perf_mode = 0; prtd->lsm_client->event_mode = LSM_EVENT_NON_TIME_STAMP_MODE; + prtd->lsm_client->event_type = LSM_DET_EVENT_TYPE_LEGACY; return 0; } @@ -2090,6 +2324,8 @@ static int msm_lsm_close(struct snd_pcm_substream *substream) spin_lock_irqsave(&prtd->event_lock, flags); kfree(prtd->event_status); prtd->event_status = NULL; + kfree(prtd->det_event); + prtd->det_event = NULL; spin_unlock_irqrestore(&prtd->event_lock, flags); mutex_destroy(&prtd->lsm_api_lock); kfree(prtd); diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 3d87a8df5a9e..46996d40e08f 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -1905,6 +1905,32 @@ int q6lsm_set_one_param(struct lsm_client *client, __func__, rc); break; } + + case LSM_DET_EVENT_TYPE: { + struct lsm_param_det_event_type det_event_type; + struct snd_lsm_det_event_type *det_event_data = + (struct snd_lsm_det_event_type *)data; + + param_info.module_id = p_info->module_id; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = p_info->param_id; + param_info.param_size = sizeof(det_event_type); + + memset(&det_event_type, 0, sizeof(det_event_type)); + + det_event_type.minor_version = QLSM_PARAM_ID_MINOR_VERSION; + det_event_type.event_type = det_event_data->event_type; + det_event_type.mode = det_event_data->mode; + + rc = q6lsm_pack_and_set_params(client, ¶m_info, + (uint8_t *)&det_event_type, + LSM_SESSION_CMD_SET_PARAMS_V2); + if (rc) + pr_err("%s: DET_EVENT_TYPE cmd failed, rc %d\n", + __func__, rc); + break; + } + default: pr_err("%s: wrong param_type 0x%x\n", __func__, p_info->param_type); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 0d454c75815a..767c1a195f4d 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -9674,6 +9674,7 @@ struct avcs_fwk_ver_info { #define LSM_DATA_EVENT_READ_DONE (0x00012B02) #define LSM_DATA_EVENT_STATUS (0x00012B03) #define LSM_SESSION_EVENT_DETECTION_STATUS_V3 (0x00012B04) +#define LSM_SESSION_DETECTION_ENGINE_GENERIC_EVENT (0x00012B06) #define LSM_MODULE_ID_VOICE_WAKEUP (0x00012C00) #define LSM_PARAM_ID_ENDPOINT_DETECT_THRESHOLD (0x00012C01) diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h index 73168d1271e3..05cc350cf708 100644 --- a/include/dsp/q6lsm.h +++ b/include/dsp/q6lsm.h @@ -88,6 +88,7 @@ struct lsm_client { bool poll_enable; int perf_mode; uint32_t event_mode; + uint32_t event_type; }; struct lsm_stream_cmd_open_tx { @@ -212,6 +213,12 @@ struct lsm_cmd_read_done { uint32_t flags; } __packed; +struct lsm_param_det_event_type { + uint32_t minor_version; + uint32_t event_type; + uint32_t mode; +} __packed; + struct lsm_client *q6lsm_client_alloc(lsm_app_cb cb, void *priv); void q6lsm_client_free(struct lsm_client *client); int q6lsm_open(struct lsm_client *client, uint16_t app_id); -- GitLab From d27acb3622bc5e0777e311578ea65ff84d4c1cec Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 17 May 2018 17:32:47 -0700 Subject: [PATCH 0289/1645] asoc: codecs: add wcd9360 objects for kernel build option wcd9360 also has to be compiled if kernel build option is true for the case where modules are in y option. Change-Id: Ie3cea21d65ccc7e680cac675720bab52411ac492 Signed-off-by: Karthikeyan Mani Signed-off-by: Vidyakumar Athota --- asoc/codecs/Kbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 10b80965991a..3596143286f9 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -180,6 +180,7 @@ ifeq ($(KERNEL_BUILD), 1) obj-y += wcd934x/ obj-y += sdm660_cdc/ obj-y += msm_sdw/ + obj-y += wcd9360/ endif # Module information used by KBuild framework obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd_core_dlkm.o -- GitLab From 6b3f418d7ee874ce3cfaf72cdc75d62cc7e71eb7 Mon Sep 17 00:00:00 2001 From: Garmond Leung Date: Fri, 11 May 2018 12:29:34 -0700 Subject: [PATCH 0290/1645] dsp: Add support for setting USB packet service interval Add support for setting packet service interval for usb AFE Port. Change-Id: I2221c659f967deaccb9031a9a61b51fd475a0e22 --- asoc/msm-dai-q6-v2.c | 41 +++++++++++++++++++++++++++++++++++++- dsp/q6afe.c | 32 ++++++++++++++++++++++++++--- include/dsp/apr_audio-v2.h | 41 ++++++++++++++++++++++++++++++++++---- 3 files changed, 106 insertions(+), 8 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 2c1d10d51a57..12fb6968e9a8 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -1774,7 +1774,7 @@ static int msm_dai_q6_usb_audio_hw_params(struct snd_pcm_hw_params *params, return -EINVAL; } dai_data->port_config.usb_audio.cfg_minor_version = - AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG; + AFE_API_MINOR_VERSION_USB_AUDIO_CONFIG; dai_data->port_config.usb_audio.num_channels = dai_data->channels; dai_data->port_config.usb_audio.sample_rate = dai_data->rate; @@ -2241,6 +2241,38 @@ static int msm_dai_q6_usb_audio_endian_cfg_get(struct snd_kcontrol *kcontrol, return 0; } +static int msm_dai_q6_usb_audio_svc_interval_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + u32 val = ucontrol->value.integer.value[0]; + + if (!dai_data) { + pr_err("%s: dai_data is NULL\n", __func__); + return -EINVAL; + } + dai_data->port_config.usb_audio.service_interval = val; + pr_debug("%s: new service interval = %u\n", __func__, + dai_data->port_config.usb_audio.service_interval); + return 0; +} + +static int msm_dai_q6_usb_audio_svc_interval_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (!dai_data) { + pr_err("%s: dai_data is NULL\n", __func__); + return -EINVAL; + } + ucontrol->value.integer.value[0] = + dai_data->port_config.usb_audio.service_interval; + pr_debug("%s: service interval = %d\n", __func__, + dai_data->port_config.usb_audio.service_interval); + return 0; +} + static int msm_dai_q6_afe_enc_cfg_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -2671,6 +2703,10 @@ static const struct snd_kcontrol_new usb_audio_cfg_controls[] = { SOC_SINGLE_EXT("USB_AUDIO_TX endian", 0, 0, 1, 0, msm_dai_q6_usb_audio_endian_cfg_get, msm_dai_q6_usb_audio_endian_cfg_put), + SOC_SINGLE_EXT("USB_AUDIO_RX service_interval", SND_SOC_NOPM, 0, + UINT_MAX, 0, + msm_dai_q6_usb_audio_svc_interval_get, + msm_dai_q6_usb_audio_svc_interval_put), }; static const struct snd_kcontrol_new avd_drift_config_controls[] = { @@ -2772,6 +2808,9 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&usb_audio_cfg_controls[1], dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&usb_audio_cfg_controls[4], + dai_data)); break; case AFE_PORT_ID_USB_TX: rc = snd_ctl_add(dai->component->card->snd_card, diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 08a25cff77a7..63138fc06c43 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2858,8 +2858,9 @@ int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) { struct afe_param_id_usb_audio_dev_params usb_dev; struct afe_param_id_usb_audio_dev_lpcm_fmt lpcm_fmt; + struct afe_param_id_usb_audio_svc_interval svc_int; struct param_hdr_v3 param_hdr; - int ret = 0; + int ret = 0, index = 0; if (!afe_config) { pr_err("%s: Error, no configuration data\n", __func__); @@ -2867,6 +2868,13 @@ int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) goto exit; } + index = q6audio_get_port_index(port_id); + + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } memset(&usb_dev, 0, sizeof(usb_dev)); memset(&lpcm_fmt, 0, sizeof(lpcm_fmt)); memset(¶m_hdr, 0, sizeof(param_hdr)); @@ -2875,7 +2883,7 @@ int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) param_hdr.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS; param_hdr.param_size = sizeof(usb_dev); - usb_dev.cfg_minor_version = AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG; + usb_dev.cfg_minor_version = AFE_API_MINOR_VERSION_USB_AUDIO_CONFIG; usb_dev.dev_token = afe_config->usb_audio.dev_token; ret = q6afe_pack_and_set_param_in_band(port_id, @@ -2889,7 +2897,7 @@ int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) param_hdr.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_LPCM_FMT; param_hdr.param_size = sizeof(lpcm_fmt); - lpcm_fmt.cfg_minor_version = AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG; + lpcm_fmt.cfg_minor_version = AFE_API_MINOR_VERSION_USB_AUDIO_CONFIG; lpcm_fmt.endian = afe_config->usb_audio.endian; ret = q6afe_pack_and_set_param_in_band(port_id, @@ -2900,7 +2908,25 @@ int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) __func__, ret); goto exit; } + param_hdr.param_id = AFE_PARAM_ID_USB_AUDIO_SVC_INTERVAL; + param_hdr.param_size = sizeof(svc_int); + svc_int.cfg_minor_version = + AFE_API_MINOR_VERSION_USB_AUDIO_CONFIG; + svc_int.svc_interval = afe_config->usb_audio.service_interval; + + pr_debug("%s: AFE device param cmd sending SVC_INTERVAL %d\n", + __func__, svc_int.svc_interval); + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &svc_int); + + if (ret) { + pr_err("%s: AFE device param cmd svc_interval failed %d\n", + __func__, ret); + ret = -EINVAL; + goto exit; + } exit: return ret; } diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 767c1a195f4d..a282f78b33d6 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -2586,6 +2586,17 @@ struct afe_param_id_internal_bt_fm_cfg { * shared channel approach. */ +/* ID of the parameter used to set the latency mode of the + * USB audio device. + */ +#define AFE_PARAM_ID_PORT_LATENCY_MODE_CONFIG 0x000102B3 + +/* Minor version used for tracking USB audio latency mode */ +#define AFE_API_MINOR_VERSION_USB_AUDIO_LATENCY_MODE 0x1 + +/* Supported AFE port latency modes */ +#define AFE_PORT_DEFAULT_LATENCY_MODE 0x0 +#define AFE_PORT_LOW_LATENCY_MODE 0x1 #define AFE_PARAM_ID_SLIMBUS_CONFIG 0x00010212 @@ -2679,14 +2690,14 @@ struct afe_param_id_slimbus_cfg { #define AFE_PARAM_ID_USB_AUDIO_DEV_LPCM_FMT 0x000102AA /* Minor version used for tracking USB audio configuration */ -#define AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG 0x1 +#define AFE_API_MINOR_VERSION_USB_AUDIO_CONFIG 0x1 /* Payload of the AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS parameter used by * AFE_MODULE_AUDIO_DEV_INTERFACE. */ struct afe_param_id_usb_audio_dev_params { /* Minor version used for tracking USB audio device parameter. - * Supported values: AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG + * Supported values: AFE_API_MINOR_VERSION_USB_AUDIO_CONFIG */ u32 cfg_minor_version; /* Token of actual end USB aduio device */ @@ -2695,13 +2706,33 @@ struct afe_param_id_usb_audio_dev_params { struct afe_param_id_usb_audio_dev_lpcm_fmt { /* Minor version used for tracking USB audio device parameter. - * Supported values: AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG + * Supported values: AFE_API_MINOR_VERSION_USB_AUDIO_CONFIG */ u32 cfg_minor_version; /* Endianness of actual end USB audio device */ u32 endian; } __packed; +struct afe_param_id_usb_audio_dev_latency_mode { +/* Minor version used for tracking USB audio device parameter. + * Supported values: AFE_API_MINOR_VERSION_USB_AUDIO_LATENCY_MODE + */ + u32 minor_version; +/* latency mode for the USB audio device */ + u32 mode; +} __packed; + +#define AFE_PARAM_ID_USB_AUDIO_SVC_INTERVAL 0x000102B7 + +struct afe_param_id_usb_audio_svc_interval { +/* Minor version used for tracking USB audio device parameter. + * Supported values: AFE_API_MINOR_VERSION_USB_AUDIO_CONFIG + */ + u32 cfg_minor_version; +/* Endianness of actual end USB audio device */ + u32 svc_interval; +} __packed; + /* ID of the parameter used by AFE_PARAM_ID_USB_AUDIO_CONFIG to configure * USB audio interface. It should be used with AFE_MODULE_AUDIO_DEV_INTERFACE */ @@ -2712,7 +2743,7 @@ struct afe_param_id_usb_audio_dev_lpcm_fmt { */ struct afe_param_id_usb_audio_cfg { /* Minor version used for tracking USB audio device configuration. - * Supported values: AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG + * Supported values: AFE_API_MINOR_VERSION_USB_AUDIO_CONFIG */ u32 cfg_minor_version; /* Sampling rate of the port. @@ -2748,6 +2779,8 @@ struct afe_param_id_usb_audio_cfg { u32 dev_token; /* endianness of this interface */ u32 endian; +/* service interval */ + u32 service_interval; } __packed; /* This param id is used to configure Real Time Proxy interface. */ -- GitLab From 743a507eb04f57d119dee217eb70ab91b70e712a Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 23 Apr 2018 18:01:19 -0700 Subject: [PATCH 0291/1645] asoc: msm: add workqueue to handle SSR/PDR UP notification Use workqueue in machine driver to handle sending AFE configuration to DSP during SSR/PDR UP notification, so that the response to the notification is not delayed because of AVS not up or sound card not up. Change-Id: If537d214cfbbe7f85b66425cbd6a762f383c05ab Signed-off-by: Karthikeyan Mani --- asoc/sm8150.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/asoc/sm8150.c b/asoc/sm8150.c index 513d8447f913..f4bc02a0c5cb 100644 --- a/asoc/sm8150.c +++ b/asoc/sm8150.c @@ -167,6 +167,8 @@ struct msm_asoc_mach_data { struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ struct device_node *fsa_handle; + struct snd_soc_codec *codec; + struct work_struct adsp_power_up_work; }; struct msm_asoc_wcd93xx_codec { @@ -3878,6 +3880,19 @@ static int msm_adsp_power_up_config(struct snd_soc_codec *codec, return ret; } +static void msm_adsp_power_up_config_work(struct work_struct *work) +{ + struct msm_asoc_mach_data *pdata; + struct snd_soc_codec *codec; + struct snd_card *card; + + pdata = container_of(work, struct msm_asoc_mach_data, + adsp_power_up_work); + codec = pdata->codec; + card = codec->component.card->snd_card; + msm_adsp_power_up_config(codec, card); +} + static int sm8150_notifier_service_cb(struct notifier_block *this, unsigned long opcode, void *ptr) { @@ -3886,6 +3901,7 @@ static int sm8150_notifier_service_cb(struct notifier_block *this, const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; struct snd_soc_pcm_runtime *rtd; struct snd_soc_codec *codec; + struct msm_asoc_mach_data *pdata; pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); @@ -3920,13 +3936,9 @@ static int sm8150_notifier_service_cb(struct notifier_block *this, } codec = rtd->codec; - ret = msm_adsp_power_up_config(codec, card->snd_card); - if (ret < 0) { - dev_err(card->dev, - "%s: msm_adsp_power_up_config failed ret = %d!\n", - __func__, ret); - goto err; - } + pdata = snd_soc_card_get_drvdata(card); + pdata->codec = codec; + schedule_work(&pdata->adsp_power_up_work); break; default: break; @@ -7414,6 +7426,8 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Sound card %s registered\n", card->name); spdev = pdev; + INIT_WORK(&pdata->adsp_power_up_work, msm_adsp_power_up_config_work); + ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); if (ret) { dev_dbg(&pdev->dev, "%s: failed to add child nodes, ret=%d\n", -- GitLab From f1cba4d4b2c8c3591caf513ea1c48fca966ce65d Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Thu, 1 Mar 2018 13:38:39 -0800 Subject: [PATCH 0292/1645] dsp: add audio event notifier support Add support for audio event notifier framework to send/receive events across audio drivers. CRs-Fixed: 2244131 Change-Id: I1e36703a91625cd52333596d66dc21a0e8876738 Signed-off-by: Vidyakumar Athota Signed-off-by: Vignesh Kulothungan --- dsp/Kbuild | 1 + dsp/msm-audio-event-notify.c | 45 ++++++++++++++++++++++++++++ include/dsp/msm-audio-event-notify.h | 44 +++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 dsp/msm-audio-event-notify.c create mode 100644 include/dsp/msm-audio-event-notify.h diff --git a/dsp/Kbuild b/dsp/Kbuild index f22573273f59..74a2a7471e17 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -75,6 +75,7 @@ COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) ############ QDSP6V2 ############ ifdef CONFIG_SND_SOC_MSM_QDSP6V2_INTF + Q6_OBJS += msm-audio-event-notify.o Q6_OBJS += audio_calibration.o Q6_OBJS += audio_cal_utils.o Q6_OBJS += q6adm.o diff --git a/dsp/msm-audio-event-notify.c b/dsp/msm-audio-event-notify.c new file mode 100644 index 000000000000..6eb537d78c83 --- /dev/null +++ b/dsp/msm-audio-event-notify.c @@ -0,0 +1,45 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include + +static ATOMIC_NOTIFIER_HEAD(msm_aud_evt_notifier_list); + +/** + * msm_aud_evt_register_client - register a client notifier + * @nb: notifier block to callback on events + */ +int msm_aud_evt_register_client(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&msm_aud_evt_notifier_list, nb); +} +EXPORT_SYMBOL(msm_aud_evt_register_client); + +/** + * msm_aud_evt_unregister_client - unregister a client notifier + * @nb: notifier block to callback on events + */ +int msm_aud_evt_unregister_client(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&msm_aud_evt_notifier_list, nb); +} +EXPORT_SYMBOL(msm_aud_evt_unregister_client); + +/** + * msm_aud_evt_notifier_call_chain - notify clients of fb_events + * + */ +int msm_aud_evt_notifier_call_chain(unsigned long val, void *v) +{ + return atomic_notifier_call_chain(&msm_aud_evt_notifier_list, val, v); +} +EXPORT_SYMBOL_GPL(msm_aud_evt_notifier_call_chain); diff --git a/include/dsp/msm-audio-event-notify.h b/include/dsp/msm-audio-event-notify.h new file mode 100644 index 000000000000..5b85ad7e26c5 --- /dev/null +++ b/include/dsp/msm-audio-event-notify.h @@ -0,0 +1,44 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __MSM_AUDIO_EVENT_NOTIFY_H_ +#define __MSM_AUDIO_EVENT_NOTIFY_H_ + +#include + +#if IS_ENABLED(CONFIG_SND_SOC_MSM_QDSP6V2_INTF) +int msm_aud_evt_register_client(struct notifier_block *nb); +int msm_aud_evt_unregister_client(struct notifier_block *nb); +int msm_aud_evt_notifier_call_chain(unsigned long val, void *v); +#else +static inline int msm_aud_evt_register_client(struct notifier_block *nb) +{ + return -ENOSYS; +} + +static inline int msm_aud_evt_unregister_client(struct notifier_block *nb) +{ + return -ENOSYS; +} + +static inline int msm_aud_evt_notifier_call_chain(unsigned long val, void *v) +{ + return -ENOSYS; +} +#endif + +enum { + MSM_AUD_DC_EVENT = 1, +}; + +#endif -- GitLab From a6092aff591d7a7502f73755c094472024cb73d0 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 7 May 2018 15:08:26 +0800 Subject: [PATCH 0293/1645] ipc: apr: remove unused dsp-wait waitqueue waitqueue dsp_wait is not used anymore. Remove it from apr driver. Change-Id: Iab16d37cdc8dd495e2289acec3ee5625421465e4 Signed-off-by: Meng Wang --- ipc/apr.c | 34 ++++------------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/ipc/apr.c b/ipc/apr.c index a8ff3631ee48..6e1f7d3e7935 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -41,7 +41,6 @@ static struct apr_q6 q6; static struct apr_client client[APR_DEST_MAX][APR_CLIENT_MAX]; static void *apr_pkt_ctx; -static wait_queue_head_t dsp_wait; static wait_queue_head_t modem_wait; static bool is_modem_up; /* Subsystem restart: QDSP6 data, functions */ @@ -281,12 +280,6 @@ int apr_set_q6_state(enum apr_subsys_state state) } EXPORT_SYMBOL(apr_set_q6_state); -enum apr_subsys_state apr_cmpxchg_q6_state(enum apr_subsys_state prev, - enum apr_subsys_state new) -{ - return atomic_cmpxchg(&q6.q6_state, prev, new); -} - static void apr_adsp_down(unsigned long opcode) { pr_info("%s: Q6 is Down\n", __func__); @@ -308,9 +301,7 @@ static void apr_add_child_devices(struct work_struct *work) static void apr_adsp_up(void) { pr_info("%s: Q6 is Up\n", __func__); - if (apr_cmpxchg_q6_state(APR_SUBSYS_DOWN, APR_SUBSYS_LOADED) == - APR_SUBSYS_DOWN) - wake_up(&dsp_wait); + apr_set_q6_state(APR_SUBSYS_LOADED); spin_lock(&apr_priv->apr_lock); if (apr_priv->is_initial_boot) @@ -318,24 +309,6 @@ static void apr_adsp_up(void) spin_unlock(&apr_priv->apr_lock); } -int apr_wait_for_device_up(int dest_id) -{ - int rc = -1; - - if (dest_id == APR_DEST_MODEM) - rc = wait_event_interruptible_timeout(modem_wait, - (apr_get_modem_state() == APR_SUBSYS_UP), - (1 * HZ)); - else if (dest_id == APR_DEST_QDSP6) - rc = wait_event_interruptible_timeout(dsp_wait, - (apr_get_q6_state() == APR_SUBSYS_UP), - (1 * HZ)); - else - pr_err("%s: unknown dest_id %d\n", __func__, dest_id); - /* returns left time */ - return rc; -} - int apr_load_adsp_image(void) { int rc = 0; @@ -534,7 +507,9 @@ struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn, return NULL; } pr_debug("%s: Wait for modem to bootup\n", __func__); - rc = apr_wait_for_device_up(APR_DEST_MODEM); + rc = wait_event_interruptible_timeout(modem_wait, + (apr_get_modem_state() == APR_SUBSYS_UP), + (1 * HZ)); if (rc == 0) { pr_err("%s: Modem is not Up\n", __func__); return NULL; @@ -1154,7 +1129,6 @@ static int apr_probe(struct platform_device *pdev) { int i, j, k; - init_waitqueue_head(&dsp_wait); init_waitqueue_head(&modem_wait); apr_priv = devm_kzalloc(&pdev->dev, sizeof(*apr_priv), GFP_KERNEL); -- GitLab From e562a364d1cabe103e659e6fa58623323065afd8 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 12 Apr 2018 00:39:08 +0530 Subject: [PATCH 0294/1645] asoc: bolero: Add support for bolero codec Add bolero driver to provide interface to all macros and represent as a single codec to ASoC framework. Change-Id: Ie4cd3b9422ff9691dd37b40fc243573d7536860c Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero_cdc.c | 445 ++++++++++++ asoc/codecs/bolero/bolero_cdc.h | 61 ++ asoc/codecs/bolero/bolero_cdc_registers.h | 840 ++++++++++++++++++++++ asoc/codecs/bolero/bolero_cdc_regmap.c | 811 +++++++++++++++++++++ asoc/codecs/bolero/bolero_cdc_tables.c | 768 ++++++++++++++++++++ asoc/codecs/bolero/bolero_cdc_utils.c | 186 +++++ asoc/codecs/bolero/internal.h | 56 ++ 7 files changed, 3167 insertions(+) create mode 100644 asoc/codecs/bolero/bolero_cdc.c create mode 100644 asoc/codecs/bolero/bolero_cdc.h create mode 100644 asoc/codecs/bolero/bolero_cdc_registers.h create mode 100644 asoc/codecs/bolero/bolero_cdc_regmap.c create mode 100644 asoc/codecs/bolero/bolero_cdc_tables.c create mode 100644 asoc/codecs/bolero/bolero_cdc_utils.c create mode 100644 asoc/codecs/bolero/internal.h diff --git a/asoc/codecs/bolero/bolero_cdc.c b/asoc/codecs/bolero/bolero_cdc.c new file mode 100644 index 000000000000..479b71c949db --- /dev/null +++ b/asoc/codecs/bolero/bolero_cdc.c @@ -0,0 +1,445 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bolero_cdc.h" +#include "internal.h" + +static struct snd_soc_codec_driver bolero; + +static void bolero_ahb_write_device(char __iomem *io_base, + u16 reg, u8 value) +{ + u32 temp = (u32)(value) & 0x000000FF; + + iowrite32(temp, io_base + reg); +} + +static void bolero_ahb_read_device(char __iomem *io_base, + u16 reg, u8 *value) +{ + u32 temp; + + temp = ioread32(io_base + reg); + *value = (u8)temp; +} + +static int __bolero_reg_read(struct bolero_priv *priv, + u16 macro_id, u16 reg, u8 *val) +{ + int ret = -EINVAL; + + if (!priv->macro_params[macro_id].mclk_fn) { + dev_dbg_ratelimited(priv->dev, + "%s: mclk_fn not init for macro-id-%d\n", + __func__, macro_id); + return ret; + } + ret = priv->macro_params[macro_id].mclk_fn( + priv->macro_params[macro_id].dev, true); + if (ret) { + dev_dbg_ratelimited(priv->dev, + "%s: clock enable failed\n", __func__); + return ret; + } + bolero_ahb_read_device( + priv->macro_params[macro_id].io_base, reg, val); + priv->macro_params[macro_id].mclk_fn( + priv->macro_params[macro_id].dev, false); + return ret; +} + +static int __bolero_reg_write(struct bolero_priv *priv, + u16 macro_id, u16 reg, u8 val) +{ + int ret = -EINVAL; + + if (!priv->macro_params[macro_id].mclk_fn) { + dev_dbg_ratelimited(priv->dev, + "%s: mclk_fn not init for macro-id-%d\n", + __func__, macro_id); + return ret; + } + ret = priv->macro_params[macro_id].mclk_fn( + priv->macro_params[macro_id].dev, true); + if (ret) { + dev_dbg_ratelimited(priv->dev, + "%s: clock enable failed\n", __func__); + return ret; + } + bolero_ahb_write_device( + priv->macro_params[macro_id].io_base, reg, val); + priv->macro_params[macro_id].mclk_fn( + priv->macro_params[macro_id].dev, false); + return ret; +} + +static bool bolero_is_valid_macro_dev(struct device *dev) +{ + if (of_device_is_compatible(dev->parent->of_node, "qcom,bolero-codec")) + return true; + + return false; +} + +static bool bolero_is_valid_codec_dev(struct device *dev) +{ + if (of_device_is_compatible(dev->of_node, "qcom,bolero-codec")) + return true; + + return false; +} + +/** + * bolero_get_device_ptr - Get child or macro device ptr + * + * @dev: bolero device ptr. + * @macro_id: ID of macro calling this API. + * + * Returns dev ptr on success or NULL on error. + */ +struct device *bolero_get_device_ptr(struct device *dev, u16 macro_id) +{ + struct bolero_priv *priv; + + if (!dev) { + pr_err("%s: dev is null\n", __func__); + return NULL; + } + + if (!bolero_is_valid_codec_dev(dev)) { + pr_err("%s: invalid codec\n", __func__); + return NULL; + } + priv = dev_get_drvdata(dev); + if (!priv || (macro_id >= MAX_MACRO)) { + dev_err(dev, "%s: priv is null or invalid macro\n", __func__); + return NULL; + } + + return priv->macro_params[macro_id].dev; +} +EXPORT_SYMBOL(bolero_get_device_ptr); + +static int bolero_copy_dais_from_macro(struct bolero_priv *priv) +{ + struct snd_soc_dai_driver *dai_ptr; + u16 macro_idx; + + /* memcpy into bolero_dais all macro dais */ + if (!priv->bolero_dais) + priv->bolero_dais = devm_kzalloc(priv->dev, + priv->num_dais * + sizeof( + struct snd_soc_dai_driver), + GFP_KERNEL); + if (!priv->bolero_dais) + return -ENOMEM; + + dai_ptr = priv->bolero_dais; + + for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { + if (priv->macro_params[macro_idx].dai_ptr) { + memcpy(dai_ptr, + priv->macro_params[macro_idx].dai_ptr, + priv->macro_params[macro_idx].num_dais * + sizeof(struct snd_soc_dai_driver)); + dai_ptr += priv->macro_params[macro_idx].num_dais; + } + } + return 0; +} + +/** + * bolero_register_macro - Registers macro to bolero + * + * @dev: macro device ptr. + * @macro_id: ID of macro calling this API. + * @ops: macro params to register. + * + * Returns 0 on success or -EINVAL on error. + */ +int bolero_register_macro(struct device *dev, u16 macro_id, + struct macro_ops *ops) +{ + struct bolero_priv *priv; + int ret = -EINVAL; + + if (!dev || !ops) { + pr_err("%s: dev or ops is null\n", __func__); + return -EINVAL; + } + if (!bolero_is_valid_macro_dev(dev)) { + dev_err(dev, "%s: child device for macro:%d not added yet\n", + __func__, macro_id); + return -EINVAL; + } + priv = dev_get_drvdata(dev->parent); + if (!priv || (macro_id >= MAX_MACRO)) { + dev_err(dev, "%s: priv is null or invalid macro\n", __func__); + return -EINVAL; + } + + priv->macro_params[macro_id].init = ops->init; + priv->macro_params[macro_id].exit = ops->exit; + priv->macro_params[macro_id].io_base = ops->io_base; + priv->macro_params[macro_id].num_dais = ops->num_dais; + priv->macro_params[macro_id].dai_ptr = ops->dai_ptr; + priv->macro_params[macro_id].mclk_fn = ops->mclk_fn; + priv->macro_params[macro_id].dev = dev; + priv->num_dais += ops->num_dais; + priv->num_macros_registered++; + priv->macros_supported[macro_id] = true; + + if (priv->num_macros_registered == priv->child_num) { + ret = bolero_copy_dais_from_macro(priv); + if (ret < 0) { + dev_err(dev, "%s: copy_dais failed\n", __func__); + return ret; + } + ret = snd_soc_register_codec(dev->parent, &bolero, + priv->bolero_dais, priv->num_dais); + if (ret < 0) { + dev_err(dev, "%s: register codec failed\n", __func__); + return ret; + } + } + return 0; +} +EXPORT_SYMBOL(bolero_register_macro); + +/** + * bolero_unregister_macro - De-Register macro from bolero + * + * @dev: macro device ptr. + * @macro_id: ID of macro calling this API. + * + */ +void bolero_unregister_macro(struct device *dev, u16 macro_id) +{ + struct bolero_priv *priv; + + if (!dev) { + pr_err("%s: dev is null\n", __func__); + return; + } + if (!bolero_is_valid_macro_dev(dev)) { + dev_err(dev, "%s: macro:%d not in valid registered macro-list\n", + __func__, macro_id); + return; + } + priv = dev_get_drvdata(dev->parent); + if (!priv || (macro_id >= MAX_MACRO)) { + dev_err(dev, "%s: priv is null or invalid macro\n", __func__); + return; + } + + priv->macro_params[macro_id].init = NULL; + priv->macro_params[macro_id].num_dais = 0; + priv->macro_params[macro_id].dai_ptr = NULL; + priv->macro_params[macro_id].mclk_fn = NULL; + priv->macro_params[macro_id].dev = NULL; + priv->num_dais -= priv->macro_params[macro_id].num_dais; + priv->num_macros_registered--; + + /* UNREGISTER CODEC HERE */ + if (priv->child_num - 1 == priv->num_macros_registered) + snd_soc_unregister_codec(dev->parent); +} +EXPORT_SYMBOL(bolero_unregister_macro); + +static int bolero_soc_codec_probe(struct snd_soc_codec *codec) +{ + struct bolero_priv *priv = dev_get_drvdata(codec->dev); + int macro_idx, ret = 0; + + /* call init for supported macros */ + for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { + if (priv->macro_params[macro_idx].init) { + ret = priv->macro_params[macro_idx].init(codec); + if (ret < 0) { + dev_err(codec->dev, + "%s: init for macro %d failed\n", + __func__, macro_idx); + goto err; + } + } + } + priv->codec = codec; + dev_dbg(codec->dev, "%s: bolero soc codec probe success\n", __func__); +err: + return ret; +} + +static int bolero_soc_codec_remove(struct snd_soc_codec *codec) +{ + struct bolero_priv *priv = dev_get_drvdata(codec->dev); + int macro_idx; + + /* call exit for supported macros */ + for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) + if (priv->macro_params[macro_idx].exit) + priv->macro_params[macro_idx].exit(codec); + + return 0; +} + +static struct regmap *bolero_get_regmap(struct device *dev) +{ + struct bolero_priv *priv = dev_get_drvdata(dev); + + return priv->regmap; +} + +static struct snd_soc_codec_driver bolero = { + .probe = bolero_soc_codec_probe, + .remove = bolero_soc_codec_remove, + .get_regmap = bolero_get_regmap, +}; + +static void bolero_add_child_devices(struct work_struct *work) +{ + struct bolero_priv *priv; + struct platform_device *pdev; + struct device_node *node; + int ret, i, cnt = 0; + + priv = container_of(work, struct bolero_priv, + bolero_add_child_devices_work); + if (!priv) { + pr_err("%s: Memory for bolero priv does not exist\n", + __func__); + return; + } + if (!priv->dev->of_node) { + dev_err(priv->dev, "%s: DT node for bolero does not exist\n", + __func__); + return; + } + + for_each_child_of_node(priv->dev->of_node, node) { + pdev = platform_device_alloc(node->name, -1); + if (!pdev) { + dev_err(priv->dev, "%s: pdev memory alloc failed\n", + __func__); + ret = -ENOMEM; + goto fail_pdev_add; + } + pdev->dev.parent = priv->dev; + pdev->dev.of_node = node; + + ret = platform_device_add(pdev); + if (ret) { + dev_err(priv->dev, + "%s: Cannot add platform device\n", + __func__); + goto fail_pdev_add; + } + priv->pdev_child_devices[cnt] = pdev; + cnt++; + } + return; +fail_pdev_add: + for (i = cnt; i > 0; i--) + platform_device_put(priv->pdev_child_devices[i - 1]); +err: + return; +} + +static int bolero_probe(struct platform_device *pdev) +{ + struct bolero_priv *priv; + u32 num_macros = 0; + int ret; + + priv = devm_kzalloc(&pdev->dev, sizeof(struct bolero_priv), + GFP_KERNEL); + if (!priv) + return -ENOMEM; + ret = of_property_read_u32(pdev->dev.of_node, "qcom,num-macros", + &num_macros); + if (ret) { + dev_err(&pdev->dev, + "%s:num-macros property not found\n", + __func__); + return ret; + } + priv->child_num = num_macros; + if (priv->child_num > MAX_MACRO) { + dev_err(&pdev->dev, + "%s:child_num(%d) > MAX_MACRO(%d) than supported\n", + __func__, priv->child_num, MAX_MACRO); + return -EINVAL; + } + priv->va_without_decimation = of_property_read_bool(pdev->dev.of_node, + "qcom,va-without-decimation"); + if (priv->va_without_decimation) + bolero_reg_access[VA_MACRO] = bolero_va_top_reg_access; + + priv->dev = &pdev->dev; + priv->regmap = bolero_regmap_init(priv->dev, + &bolero_regmap_config); + if (IS_ERR_OR_NULL((void *)(priv->regmap))) { + dev_err(&pdev->dev, "%s:regmap init failed\n", __func__); + return -EINVAL; + } + priv->read_dev = __bolero_reg_read; + priv->write_dev = __bolero_reg_write; + + dev_set_drvdata(&pdev->dev, priv); + mutex_init(&priv->io_lock); + INIT_WORK(&priv->bolero_add_child_devices_work, + bolero_add_child_devices); + schedule_work(&priv->bolero_add_child_devices_work); + + return 0; +} + +static int bolero_remove(struct platform_device *pdev) +{ + struct bolero_priv *priv = dev_get_drvdata(&pdev->dev); + u16 i; + + for (i = priv->child_num; i > 0; i--) + platform_device_unregister(priv->pdev_child_devices[i - 1]); + mutex_destroy(&priv->io_lock); + return 0; +} + +static const struct of_device_id bolero_dt_match[] = { + {.compatible = "qcom,bolero-codec"}, + {} +}; +MODULE_DEVICE_TABLE(of, bolero_dt_match); + +static struct platform_driver bolero_drv = { + .driver = { + .name = "bolero-codec", + .owner = THIS_MODULE, + .of_match_table = bolero_dt_match, + }, + .probe = bolero_probe, + .remove = bolero_remove, +}; + +module_platform_driver(bolero_drv); + +MODULE_DESCRIPTION("Bolero driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/bolero/bolero_cdc.h b/asoc/codecs/bolero/bolero_cdc.h new file mode 100644 index 000000000000..7b3aad2a52e4 --- /dev/null +++ b/asoc/codecs/bolero/bolero_cdc.h @@ -0,0 +1,61 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef BOLERO_CDC_H +#define BOLERO_CDC_H + +#include +#include + +enum { + START_MACRO, + TX_MACRO = START_MACRO, + RX_MACRO, + WSA_MACRO, + VA_MACRO, + MAX_MACRO +}; + +struct macro_ops { + int (*init)(struct snd_soc_codec *codec); + int (*exit)(struct snd_soc_codec *codec); + u16 num_dais; + struct device *dev; + struct snd_soc_dai_driver *dai_ptr; + int (*mclk_fn)(struct device *dev, bool enable); + char __iomem *io_base; +}; + +#if IS_ENABLED(CONFIG_SND_SOC_BOLERO) +int bolero_register_macro(struct device *dev, u16 macro_id, + struct macro_ops *ops); +void bolero_unregister_macro(struct device *dev, u16 macro_id); +struct device *bolero_get_device_ptr(struct device *dev, u16 macro_id); +#else +static inline int bolero_register_macro(struct device *dev, + u16 macro_id, + struct macro_ops *ops) +{ + return 0; +} + +static inline void bolero_unregister_macro(struct device *dev, u16 macro_id) +{ +} + +static inline struct device *bolero_get_device_ptr(struct device *dev, + u16 macro_id) +{ + return NULL; +} +#endif /* CONFIG_SND_SOC_BOLERO */ +#endif /* BOLERO_CDC_H */ diff --git a/asoc/codecs/bolero/bolero_cdc_registers.h b/asoc/codecs/bolero/bolero_cdc_registers.h new file mode 100644 index 000000000000..d413ff9616f8 --- /dev/null +++ b/asoc/codecs/bolero/bolero_cdc_registers.h @@ -0,0 +1,840 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _BOLERO_CDC_REGISTERS_H +#define _BOLERO_CDC_REGISTERS_H + +#define TX_START_OFFSET 0x0000 + +#define BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL (TX_START_OFFSET + 0x0000) +#define BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL (TX_START_OFFSET + 0x0004) +#define BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL (TX_START_OFFSET + 0x0008) +#define BOLERO_CDC_TX_TOP_CSR_TOP_CFG0 (TX_START_OFFSET + 0x0080) +#define BOLERO_CDC_TX_TOP_CSR_ANC_CFG (TX_START_OFFSET + 0x0084) +#define BOLERO_CDC_TX_TOP_CSR_SWR_CTRL (TX_START_OFFSET + 0x0088) +#define BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK (TX_START_OFFSET + 0x0090) +#define BOLERO_CDC_TX_TOP_CSR_DEBUG_BUS (TX_START_OFFSET + 0x0094) +#define BOLERO_CDC_TX_TOP_CSR_DEBUG_EN (TX_START_OFFSET + 0x0098) +#define BOLERO_CDC_TX_TOP_CSR_TX_I2S_CTL (TX_START_OFFSET + 0x00A4) +#define BOLERO_CDC_TX_TOP_CSR_I2S_CLK (TX_START_OFFSET + 0x00A8) +#define BOLERO_CDC_TX_TOP_CSR_I2S_RESET (TX_START_OFFSET + 0x00AC) +#define BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL (TX_START_OFFSET + 0x00C0) +#define BOLERO_CDC_TX_TOP_CSR_SWR_DMIC1_CTL (TX_START_OFFSET + 0x00C4) +#define BOLERO_CDC_TX_TOP_CSR_SWR_DMIC2_CTL (TX_START_OFFSET + 0x00C8) +#define BOLERO_CDC_TX_TOP_CSR_SWR_DMIC3_CTL (TX_START_OFFSET + 0x00CC) +#define BOLERO_CDC_TX_TOP_CSR_SWR_AMIC0_CTL (TX_START_OFFSET + 0x00D0) +#define BOLERO_CDC_TX_TOP_CSR_SWR_AMIC1_CTL (TX_START_OFFSET + 0x00D4) +#define BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 (TX_START_OFFSET + 0x0100) +#define BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 (TX_START_OFFSET + 0x0104) +#define BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0 (TX_START_OFFSET + 0x0108) +#define BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG1 (TX_START_OFFSET + 0x010C) +#define BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0 (TX_START_OFFSET + 0x0110) +#define BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG1 (TX_START_OFFSET + 0x0114) +#define BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0 (TX_START_OFFSET + 0x0118) +#define BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG1 (TX_START_OFFSET + 0x011C) +#define BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0 (TX_START_OFFSET + 0x0120) +#define BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG1 (TX_START_OFFSET + 0x0124) +#define BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0 (TX_START_OFFSET + 0x0128) +#define BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG1 (TX_START_OFFSET + 0x012C) +#define BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0 (TX_START_OFFSET + 0x0130) +#define BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG1 (TX_START_OFFSET + 0x0134) +#define BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0 (TX_START_OFFSET + 0x0138) +#define BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG1 (TX_START_OFFSET + 0x013C) +#define BOLERO_CDC_TX_ANC0_CLK_RESET_CTL (TX_START_OFFSET + 0x0200) +#define BOLERO_CDC_TX_ANC0_MODE_1_CTL (TX_START_OFFSET + 0x0204) +#define BOLERO_CDC_TX_ANC0_MODE_2_CTL (TX_START_OFFSET + 0x0208) +#define BOLERO_CDC_TX_ANC0_FF_SHIFT (TX_START_OFFSET + 0x020C) +#define BOLERO_CDC_TX_ANC0_FB_SHIFT (TX_START_OFFSET + 0x0210) +#define BOLERO_CDC_TX_ANC0_LPF_FF_A_CTL (TX_START_OFFSET + 0x0214) +#define BOLERO_CDC_TX_ANC0_LPF_FF_B_CTL (TX_START_OFFSET + 0x0218) +#define BOLERO_CDC_TX_ANC0_LPF_FB_CTL (TX_START_OFFSET + 0x021C) +#define BOLERO_CDC_TX_ANC0_SMLPF_CTL (TX_START_OFFSET + 0x0220) +#define BOLERO_CDC_TX_ANC0_DCFLT_SHIFT_CTL (TX_START_OFFSET + 0x0224) +#define BOLERO_CDC_TX_ANC0_IIR_ADAPT_CTL (TX_START_OFFSET + 0x0228) +#define BOLERO_CDC_TX_ANC0_IIR_COEFF_1_CTL (TX_START_OFFSET + 0x022C) +#define BOLERO_CDC_TX_ANC0_IIR_COEFF_2_CTL (TX_START_OFFSET + 0x0230) +#define BOLERO_CDC_TX_ANC0_FF_A_GAIN_CTL (TX_START_OFFSET + 0x0234) +#define BOLERO_CDC_TX_ANC0_FF_B_GAIN_CTL (TX_START_OFFSET + 0x0238) +#define BOLERO_CDC_TX_ANC0_FB_GAIN_CTL (TX_START_OFFSET + 0x023C) +#define BOLERO_CDC_TX0_TX_PATH_CTL (TX_START_OFFSET + 0x0400) +#define BOLERO_CDC_TX0_TX_PATH_CFG0 (TX_START_OFFSET + 0x0404) +#define BOLERO_CDC_TX0_TX_PATH_CFG1 (TX_START_OFFSET + 0x0408) +#define BOLERO_CDC_TX0_TX_VOL_CTL (TX_START_OFFSET + 0x040C) +#define BOLERO_CDC_TX0_TX_PATH_SEC0 (TX_START_OFFSET + 0x0410) +#define BOLERO_CDC_TX0_TX_PATH_SEC1 (TX_START_OFFSET + 0x0414) +#define BOLERO_CDC_TX0_TX_PATH_SEC2 (TX_START_OFFSET + 0x0418) +#define BOLERO_CDC_TX0_TX_PATH_SEC3 (TX_START_OFFSET + 0x041C) +#define BOLERO_CDC_TX0_TX_PATH_SEC4 (TX_START_OFFSET + 0x0420) +#define BOLERO_CDC_TX0_TX_PATH_SEC5 (TX_START_OFFSET + 0x0424) +#define BOLERO_CDC_TX0_TX_PATH_SEC6 (TX_START_OFFSET + 0x0428) +#define BOLERO_CDC_TX0_TX_PATH_SEC7 (TX_START_OFFSET + 0x042C) +#define BOLERO_CDC_TX1_TX_PATH_CTL (TX_START_OFFSET + 0x0480) +#define BOLERO_CDC_TX1_TX_PATH_CFG0 (TX_START_OFFSET + 0x0484) +#define BOLERO_CDC_TX1_TX_PATH_CFG1 (TX_START_OFFSET + 0x0488) +#define BOLERO_CDC_TX1_TX_VOL_CTL (TX_START_OFFSET + 0x048C) +#define BOLERO_CDC_TX1_TX_PATH_SEC0 (TX_START_OFFSET + 0x0490) +#define BOLERO_CDC_TX1_TX_PATH_SEC1 (TX_START_OFFSET + 0x0494) +#define BOLERO_CDC_TX1_TX_PATH_SEC2 (TX_START_OFFSET + 0x0498) +#define BOLERO_CDC_TX1_TX_PATH_SEC3 (TX_START_OFFSET + 0x049C) +#define BOLERO_CDC_TX1_TX_PATH_SEC4 (TX_START_OFFSET + 0x04A0) +#define BOLERO_CDC_TX1_TX_PATH_SEC5 (TX_START_OFFSET + 0x04A4) +#define BOLERO_CDC_TX1_TX_PATH_SEC6 (TX_START_OFFSET + 0x04A8) +#define BOLERO_CDC_TX2_TX_PATH_CTL (TX_START_OFFSET + 0x0500) +#define BOLERO_CDC_TX2_TX_PATH_CFG0 (TX_START_OFFSET + 0x0504) +#define BOLERO_CDC_TX2_TX_PATH_CFG1 (TX_START_OFFSET + 0x0508) +#define BOLERO_CDC_TX2_TX_VOL_CTL (TX_START_OFFSET + 0x050C) +#define BOLERO_CDC_TX2_TX_PATH_SEC0 (TX_START_OFFSET + 0x0510) +#define BOLERO_CDC_TX2_TX_PATH_SEC1 (TX_START_OFFSET + 0x0514) +#define BOLERO_CDC_TX2_TX_PATH_SEC2 (TX_START_OFFSET + 0x0518) +#define BOLERO_CDC_TX2_TX_PATH_SEC3 (TX_START_OFFSET + 0x051C) +#define BOLERO_CDC_TX2_TX_PATH_SEC4 (TX_START_OFFSET + 0x0520) +#define BOLERO_CDC_TX2_TX_PATH_SEC5 (TX_START_OFFSET + 0x0524) +#define BOLERO_CDC_TX2_TX_PATH_SEC6 (TX_START_OFFSET + 0x0528) +#define BOLERO_CDC_TX3_TX_PATH_CTL (TX_START_OFFSET + 0x0580) +#define BOLERO_CDC_TX3_TX_PATH_CFG0 (TX_START_OFFSET + 0x0584) +#define BOLERO_CDC_TX3_TX_PATH_CFG1 (TX_START_OFFSET + 0x0588) +#define BOLERO_CDC_TX3_TX_VOL_CTL (TX_START_OFFSET + 0x058C) +#define BOLERO_CDC_TX3_TX_PATH_SEC0 (TX_START_OFFSET + 0x0590) +#define BOLERO_CDC_TX3_TX_PATH_SEC1 (TX_START_OFFSET + 0x0594) +#define BOLERO_CDC_TX3_TX_PATH_SEC2 (TX_START_OFFSET + 0x0598) +#define BOLERO_CDC_TX3_TX_PATH_SEC3 (TX_START_OFFSET + 0x059C) +#define BOLERO_CDC_TX3_TX_PATH_SEC4 (TX_START_OFFSET + 0x05A0) +#define BOLERO_CDC_TX3_TX_PATH_SEC5 (TX_START_OFFSET + 0x05A4) +#define BOLERO_CDC_TX3_TX_PATH_SEC6 (TX_START_OFFSET + 0x05A8) +#define BOLERO_CDC_TX4_TX_PATH_CTL (TX_START_OFFSET + 0x0600) +#define BOLERO_CDC_TX4_TX_PATH_CFG0 (TX_START_OFFSET + 0x0604) +#define BOLERO_CDC_TX4_TX_PATH_CFG1 (TX_START_OFFSET + 0x0608) +#define BOLERO_CDC_TX4_TX_VOL_CTL (TX_START_OFFSET + 0x060C) +#define BOLERO_CDC_TX4_TX_PATH_SEC0 (TX_START_OFFSET + 0x0610) +#define BOLERO_CDC_TX4_TX_PATH_SEC1 (TX_START_OFFSET + 0x0614) +#define BOLERO_CDC_TX4_TX_PATH_SEC2 (TX_START_OFFSET + 0x0618) +#define BOLERO_CDC_TX4_TX_PATH_SEC3 (TX_START_OFFSET + 0x061C) +#define BOLERO_CDC_TX4_TX_PATH_SEC4 (TX_START_OFFSET + 0x0620) +#define BOLERO_CDC_TX4_TX_PATH_SEC5 (TX_START_OFFSET + 0x0624) +#define BOLERO_CDC_TX4_TX_PATH_SEC6 (TX_START_OFFSET + 0x0628) +#define BOLERO_CDC_TX5_TX_PATH_CTL (TX_START_OFFSET + 0x0680) +#define BOLERO_CDC_TX5_TX_PATH_CFG0 (TX_START_OFFSET + 0x0684) +#define BOLERO_CDC_TX5_TX_PATH_CFG1 (TX_START_OFFSET + 0x0688) +#define BOLERO_CDC_TX5_TX_VOL_CTL (TX_START_OFFSET + 0x068C) +#define BOLERO_CDC_TX5_TX_PATH_SEC0 (TX_START_OFFSET + 0x0690) +#define BOLERO_CDC_TX5_TX_PATH_SEC1 (TX_START_OFFSET + 0x0694) +#define BOLERO_CDC_TX5_TX_PATH_SEC2 (TX_START_OFFSET + 0x0698) +#define BOLERO_CDC_TX5_TX_PATH_SEC3 (TX_START_OFFSET + 0x069C) +#define BOLERO_CDC_TX5_TX_PATH_SEC4 (TX_START_OFFSET + 0x06A0) +#define BOLERO_CDC_TX5_TX_PATH_SEC5 (TX_START_OFFSET + 0x06A4) +#define BOLERO_CDC_TX5_TX_PATH_SEC6 (TX_START_OFFSET + 0x06A8) +#define BOLERO_CDC_TX6_TX_PATH_CTL (TX_START_OFFSET + 0x0700) +#define BOLERO_CDC_TX6_TX_PATH_CFG0 (TX_START_OFFSET + 0x0704) +#define BOLERO_CDC_TX6_TX_PATH_CFG1 (TX_START_OFFSET + 0x0708) +#define BOLERO_CDC_TX6_TX_VOL_CTL (TX_START_OFFSET + 0x070C) +#define BOLERO_CDC_TX6_TX_PATH_SEC0 (TX_START_OFFSET + 0x0710) +#define BOLERO_CDC_TX6_TX_PATH_SEC1 (TX_START_OFFSET + 0x0714) +#define BOLERO_CDC_TX6_TX_PATH_SEC2 (TX_START_OFFSET + 0x0718) +#define BOLERO_CDC_TX6_TX_PATH_SEC3 (TX_START_OFFSET + 0x071C) +#define BOLERO_CDC_TX6_TX_PATH_SEC4 (TX_START_OFFSET + 0x0720) +#define BOLERO_CDC_TX6_TX_PATH_SEC5 (TX_START_OFFSET + 0x0724) +#define BOLERO_CDC_TX6_TX_PATH_SEC6 (TX_START_OFFSET + 0x0728) +#define BOLERO_CDC_TX7_TX_PATH_CTL (TX_START_OFFSET + 0x0780) +#define BOLERO_CDC_TX7_TX_PATH_CFG0 (TX_START_OFFSET + 0x0784) +#define BOLERO_CDC_TX7_TX_PATH_CFG1 (TX_START_OFFSET + 0x0788) +#define BOLERO_CDC_TX7_TX_VOL_CTL (TX_START_OFFSET + 0x078C) +#define BOLERO_CDC_TX7_TX_PATH_SEC0 (TX_START_OFFSET + 0x0790) +#define BOLERO_CDC_TX7_TX_PATH_SEC1 (TX_START_OFFSET + 0x0794) +#define BOLERO_CDC_TX7_TX_PATH_SEC2 (TX_START_OFFSET + 0x0798) +#define BOLERO_CDC_TX7_TX_PATH_SEC3 (TX_START_OFFSET + 0x079C) +#define BOLERO_CDC_TX7_TX_PATH_SEC4 (TX_START_OFFSET + 0x07A0) +#define BOLERO_CDC_TX7_TX_PATH_SEC5 (TX_START_OFFSET + 0x07A4) +#define BOLERO_CDC_TX7_TX_PATH_SEC6 (TX_START_OFFSET + 0x07A8) +#define TX_MAX_OFFSET (TX_START_OFFSET + 0x07A8) + +#define BOLERO_CDC_TX_MACRO_MAX 0x1EB /* 7A8/4 = 1EA + 1 */ + +#define RX_START_OFFSET 0x1000 +#define BOLERO_CDC_RX_TOP_TOP_CFG0 (RX_START_OFFSET + 0x0000) +#define BOLERO_CDC_RX_TOP_SWR_CTRL (RX_START_OFFSET + 0x0008) +#define BOLERO_CDC_RX_TOP_DEBUG (RX_START_OFFSET + 0x000C) +#define BOLERO_CDC_RX_TOP_DEBUG_BUS (RX_START_OFFSET + 0x0010) +#define BOLERO_CDC_RX_TOP_DEBUG_EN0 (RX_START_OFFSET + 0x0014) +#define BOLERO_CDC_RX_TOP_DEBUG_EN1 (RX_START_OFFSET + 0x0018) +#define BOLERO_CDC_RX_TOP_DEBUG_EN2 (RX_START_OFFSET + 0x001C) +#define BOLERO_CDC_RX_TOP_HPHL_COMP_WR_LSB (RX_START_OFFSET + 0x0020) +#define BOLERO_CDC_RX_TOP_HPHL_COMP_WR_MSB (RX_START_OFFSET + 0x0024) +#define BOLERO_CDC_RX_TOP_HPHL_COMP_LUT (RX_START_OFFSET + 0x0028) +#define BOLERO_CDC_RX_TOP_HPHL_COMP_RD_LSB (RX_START_OFFSET + 0x002C) +#define BOLERO_CDC_RX_TOP_HPHL_COMP_RD_MSB (RX_START_OFFSET + 0x0030) +#define BOLERO_CDC_RX_TOP_HPHR_COMP_WR_LSB (RX_START_OFFSET + 0x0034) +#define BOLERO_CDC_RX_TOP_HPHR_COMP_WR_MSB (RX_START_OFFSET + 0x0038) +#define BOLERO_CDC_RX_TOP_HPHR_COMP_LUT (RX_START_OFFSET + 0x003C) +#define BOLERO_CDC_RX_TOP_HPHR_COMP_RD_LSB (RX_START_OFFSET + 0x0040) +#define BOLERO_CDC_RX_TOP_HPHR_COMP_RD_MSB (RX_START_OFFSET + 0x0044) +#define BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG0 (RX_START_OFFSET + 0x0070) +#define BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG1 (RX_START_OFFSET + 0x0074) +#define BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG2 (RX_START_OFFSET + 0x0078) +#define BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG3 (RX_START_OFFSET + 0x007C) +#define BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG0 (RX_START_OFFSET + 0x0080) +#define BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG1 (RX_START_OFFSET + 0x0084) +#define BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG2 (RX_START_OFFSET + 0x0088) +#define BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG3 (RX_START_OFFSET + 0x008C) +#define BOLERO_CDC_RX_TOP_RX_I2S_CTL (RX_START_OFFSET + 0x0090) +#define BOLERO_CDC_RX_TOP_TX_I2S2_CTL (RX_START_OFFSET + 0x0094) +#define BOLERO_CDC_RX_TOP_I2S_CLK (RX_START_OFFSET + 0x0098) +#define BOLERO_CDC_RX_TOP_I2S_RESET (RX_START_OFFSET + 0x009C) +#define BOLERO_CDC_RX_TOP_I2S_MUX (RX_START_OFFSET + 0x00A0) +#define BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL (RX_START_OFFSET + 0x0100) +#define BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL \ + (RX_START_OFFSET + 0x0104) +#define BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL (RX_START_OFFSET + 0x0108) +#define BOLERO_CDC_RX_CLK_RST_CTRL_DSD_CONTROL (RX_START_OFFSET + 0x010C) +#define BOLERO_CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL \ + (RX_START_OFFSET + 0x0110) +#define BOLERO_CDC_RX_SOFTCLIP_CRC (RX_START_OFFSET + 0x0140) +#define BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL (RX_START_OFFSET + 0x0144) +#define BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0 (RX_START_OFFSET + 0x0180) +#define BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1 (RX_START_OFFSET + 0x0184) +#define BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0 (RX_START_OFFSET + 0x0188) +#define BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1 (RX_START_OFFSET + 0x018C) +#define BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG0 (RX_START_OFFSET + 0x0190) +#define BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG1 (RX_START_OFFSET + 0x0194) +#define BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4 (RX_START_OFFSET + 0x0198) +#define BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5 (RX_START_OFFSET + 0x019C) +#define BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0 (RX_START_OFFSET + 0x01A0) +#define BOLERO_CDC_RX_CLSH_CRC (RX_START_OFFSET + 0x0200) +#define BOLERO_CDC_RX_CLSH_DLY_CTRL (RX_START_OFFSET + 0x0204) +#define BOLERO_CDC_RX_CLSH_DECAY_CTRL (RX_START_OFFSET + 0x0208) +#define BOLERO_CDC_RX_CLSH_HPH_V_PA (RX_START_OFFSET + 0x020C) +#define BOLERO_CDC_RX_CLSH_EAR_V_PA (RX_START_OFFSET + 0x0210) +#define BOLERO_CDC_RX_CLSH_HPH_V_HD (RX_START_OFFSET + 0x0214) +#define BOLERO_CDC_RX_CLSH_EAR_V_HD (RX_START_OFFSET + 0x0218) +#define BOLERO_CDC_RX_CLSH_K1_MSB (RX_START_OFFSET + 0x021C) +#define BOLERO_CDC_RX_CLSH_K1_LSB (RX_START_OFFSET + 0x0220) +#define BOLERO_CDC_RX_CLSH_K2_MSB (RX_START_OFFSET + 0x0224) +#define BOLERO_CDC_RX_CLSH_K2_LSB (RX_START_OFFSET + 0x0228) +#define BOLERO_CDC_RX_CLSH_IDLE_CTRL (RX_START_OFFSET + 0x022C) +#define BOLERO_CDC_RX_CLSH_IDLE_HPH (RX_START_OFFSET + 0x0230) +#define BOLERO_CDC_RX_CLSH_IDLE_EAR (RX_START_OFFSET + 0x0234) +#define BOLERO_CDC_RX_CLSH_TEST0 (RX_START_OFFSET + 0x0238) +#define BOLERO_CDC_RX_CLSH_TEST1 (RX_START_OFFSET + 0x023C) +#define BOLERO_CDC_RX_CLSH_OVR_VREF (RX_START_OFFSET + 0x0240) +#define BOLERO_CDC_RX_CLSH_CLSG_CTL (RX_START_OFFSET + 0x0244) +#define BOLERO_CDC_RX_CLSH_CLSG_CFG1 (RX_START_OFFSET + 0x0248) +#define BOLERO_CDC_RX_CLSH_CLSG_CFG2 (RX_START_OFFSET + 0x024C) +#define BOLERO_CDC_RX_BCL_VBAT_PATH_CTL (RX_START_OFFSET + 0x0280) +#define BOLERO_CDC_RX_BCL_VBAT_CFG (RX_START_OFFSET + 0x0284) +#define BOLERO_CDC_RX_BCL_VBAT_ADC_CAL1 (RX_START_OFFSET + 0x0288) +#define BOLERO_CDC_RX_BCL_VBAT_ADC_CAL2 (RX_START_OFFSET + 0x028C) +#define BOLERO_CDC_RX_BCL_VBAT_ADC_CAL3 (RX_START_OFFSET + 0x0290) +#define BOLERO_CDC_RX_BCL_VBAT_PK_EST1 (RX_START_OFFSET + 0x0294) +#define BOLERO_CDC_RX_BCL_VBAT_PK_EST2 (RX_START_OFFSET + 0x0298) +#define BOLERO_CDC_RX_BCL_VBAT_PK_EST3 (RX_START_OFFSET + 0x029C) +#define BOLERO_CDC_RX_BCL_VBAT_RF_PROC1 (RX_START_OFFSET + 0x02A0) +#define BOLERO_CDC_RX_BCL_VBAT_RF_PROC2 (RX_START_OFFSET + 0x02A4) +#define BOLERO_CDC_RX_BCL_VBAT_TAC1 (RX_START_OFFSET + 0x02A8) +#define BOLERO_CDC_RX_BCL_VBAT_TAC2 (RX_START_OFFSET + 0x02AC) +#define BOLERO_CDC_RX_BCL_VBAT_TAC3 (RX_START_OFFSET + 0x02B0) +#define BOLERO_CDC_RX_BCL_VBAT_TAC4 (RX_START_OFFSET + 0x02B4) +#define BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD1 (RX_START_OFFSET + 0x02B8) +#define BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD2 (RX_START_OFFSET + 0x02BC) +#define BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD3 (RX_START_OFFSET + 0x02C0) +#define BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD4 (RX_START_OFFSET + 0x02C4) +#define BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD5 (RX_START_OFFSET + 0x02C8) +#define BOLERO_CDC_RX_BCL_VBAT_DEBUG1 (RX_START_OFFSET + 0x02CC) +#define BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD_MON (RX_START_OFFSET + 0x02D0) +#define BOLERO_CDC_RX_BCL_VBAT_GAIN_MON_VAL (RX_START_OFFSET + 0x02D4) +#define BOLERO_CDC_RX_BCL_VBAT_BAN (RX_START_OFFSET + 0x02D8) +#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1 (RX_START_OFFSET + 0x02DC) +#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2 (RX_START_OFFSET + 0x02E0) +#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3 (RX_START_OFFSET + 0x02E4) +#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4 (RX_START_OFFSET + 0x02E8) +#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5 (RX_START_OFFSET + 0x02EC) +#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6 (RX_START_OFFSET + 0x02F0) +#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7 (RX_START_OFFSET + 0x02F4) +#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8 (RX_START_OFFSET + 0x02F8) +#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9 (RX_START_OFFSET + 0x02FC) +#define BOLERO_CDC_RX_BCL_VBAT_ATTN1 (RX_START_OFFSET + 0x0300) +#define BOLERO_CDC_RX_BCL_VBAT_ATTN2 (RX_START_OFFSET + 0x0304) +#define BOLERO_CDC_RX_BCL_VBAT_ATTN3 (RX_START_OFFSET + 0x0308) +#define BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1 (RX_START_OFFSET + 0x030C) +#define BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL2 (RX_START_OFFSET + 0x0310) +#define BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1 (RX_START_OFFSET + 0x0314) +#define BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG2 (RX_START_OFFSET + 0x0318) +#define BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG3 (RX_START_OFFSET + 0x031C) +#define BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG4 (RX_START_OFFSET + 0x0320) +#define BOLERO_CDC_RX_BCL_VBAT_DECODE_ST (RX_START_OFFSET + 0x0324) +#define BOLERO_CDC_RX_INTR_CTRL_CFG (RX_START_OFFSET + 0x0340) +#define BOLERO_CDC_RX_INTR_CTRL_CLR_COMMIT (RX_START_OFFSET + 0x0344) +#define BOLERO_CDC_RX_INTR_CTRL_PIN1_MASK0 (RX_START_OFFSET + 0x0360) +#define BOLERO_CDC_RX_INTR_CTRL_PIN1_STATUS0 (RX_START_OFFSET + 0x0368) +#define BOLERO_CDC_RX_INTR_CTRL_PIN1_CLEAR0 (RX_START_OFFSET + 0x0370) +#define BOLERO_CDC_RX_INTR_CTRL_PIN2_MASK0 (RX_START_OFFSET + 0x0380) +#define BOLERO_CDC_RX_INTR_CTRL_PIN2_STATUS0 (RX_START_OFFSET + 0x0388) +#define BOLERO_CDC_RX_INTR_CTRL_PIN2_CLEAR0 (RX_START_OFFSET + 0x0390) +#define BOLERO_CDC_RX_INTR_CTRL_LEVEL0 (RX_START_OFFSET + 0x03C0) +#define BOLERO_CDC_RX_INTR_CTRL_BYPASS0 (RX_START_OFFSET + 0x03C8) +#define BOLERO_CDC_RX_INTR_CTRL_SET0 (RX_START_OFFSET + 0x03D0) +#define BOLERO_CDC_RX_RX0_RX_PATH_CTL (RX_START_OFFSET + 0x0400) +#define BOLERO_CDC_RX_RX0_RX_PATH_CFG0 (RX_START_OFFSET + 0x0404) +#define BOLERO_CDC_RX_RX0_RX_PATH_CFG1 (RX_START_OFFSET + 0x0408) +#define BOLERO_CDC_RX_RX0_RX_PATH_CFG2 (RX_START_OFFSET + 0x040C) +#define BOLERO_CDC_RX_RX0_RX_PATH_CFG3 (RX_START_OFFSET + 0x0410) +#define BOLERO_CDC_RX_RX0_RX_VOL_CTL (RX_START_OFFSET + 0x0414) +#define BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL (RX_START_OFFSET + 0x0418) +#define BOLERO_CDC_RX_RX0_RX_PATH_MIX_CFG (RX_START_OFFSET + 0x041C) +#define BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL (RX_START_OFFSET + 0x0420) +#define BOLERO_CDC_RX_RX0_RX_PATH_SEC1 (RX_START_OFFSET + 0x0424) +#define BOLERO_CDC_RX_RX0_RX_PATH_SEC2 (RX_START_OFFSET + 0x0428) +#define BOLERO_CDC_RX_RX0_RX_PATH_SEC3 (RX_START_OFFSET + 0x042C) +#define BOLERO_CDC_RX_RX0_RX_PATH_SEC4 (RX_START_OFFSET + 0x0430) +#define BOLERO_CDC_RX_RX0_RX_PATH_SEC7 (RX_START_OFFSET + 0x0434) +#define BOLERO_CDC_RX_RX0_RX_PATH_MIX_SEC0 (RX_START_OFFSET + 0x0438) +#define BOLERO_CDC_RX_RX0_RX_PATH_MIX_SEC1 (RX_START_OFFSET + 0x043C) +#define BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL (RX_START_OFFSET + 0x0440) +#define BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA1 (RX_START_OFFSET + 0x0444) +#define BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA2 (RX_START_OFFSET + 0x0448) +#define BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA3 (RX_START_OFFSET + 0x044C) +#define BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA4 (RX_START_OFFSET + 0x0450) +#define BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA5 (RX_START_OFFSET + 0x0454) +#define BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA6 (RX_START_OFFSET + 0x0458) +#define BOLERO_CDC_RX_RX1_RX_PATH_CTL (RX_START_OFFSET + 0x0480) +#define BOLERO_CDC_RX_RX1_RX_PATH_CFG0 (RX_START_OFFSET + 0x0484) +#define BOLERO_CDC_RX_RX1_RX_PATH_CFG1 (RX_START_OFFSET + 0x0488) +#define BOLERO_CDC_RX_RX1_RX_PATH_CFG2 (RX_START_OFFSET + 0x048C) +#define BOLERO_CDC_RX_RX1_RX_PATH_CFG3 (RX_START_OFFSET + 0x0490) +#define BOLERO_CDC_RX_RX1_RX_VOL_CTL (RX_START_OFFSET + 0x0494) +#define BOLERO_CDC_RX_RX1_RX_PATH_MIX_CTL (RX_START_OFFSET + 0x0498) +#define BOLERO_CDC_RX_RX1_RX_PATH_MIX_CFG (RX_START_OFFSET + 0x049C) +#define BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL (RX_START_OFFSET + 0x04A0) +#define BOLERO_CDC_RX_RX1_RX_PATH_SEC1 (RX_START_OFFSET + 0x04A4) +#define BOLERO_CDC_RX_RX1_RX_PATH_SEC2 (RX_START_OFFSET + 0x04A8) +#define BOLERO_CDC_RX_RX1_RX_PATH_SEC3 (RX_START_OFFSET + 0x04AC) +#define BOLERO_CDC_RX_RX1_RX_PATH_SEC4 (RX_START_OFFSET + 0x04B0) +#define BOLERO_CDC_RX_RX1_RX_PATH_SEC7 (RX_START_OFFSET + 0x04B4) +#define BOLERO_CDC_RX_RX1_RX_PATH_MIX_SEC0 (RX_START_OFFSET + 0x04B8) +#define BOLERO_CDC_RX_RX1_RX_PATH_MIX_SEC1 (RX_START_OFFSET + 0x04BC) +#define BOLERO_CDC_RX_RX1_RX_PATH_DSM_CTL (RX_START_OFFSET + 0x04C0) +#define BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA1 (RX_START_OFFSET + 0x04C4) +#define BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA2 (RX_START_OFFSET + 0x04C8) +#define BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA3 (RX_START_OFFSET + 0x04CC) +#define BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA4 (RX_START_OFFSET + 0x04D0) +#define BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA5 (RX_START_OFFSET + 0x04D4) +#define BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA6 (RX_START_OFFSET + 0x04D8) +#define BOLERO_CDC_RX_RX2_RX_PATH_CTL (RX_START_OFFSET + 0x0500) +#define BOLERO_CDC_RX_RX2_RX_PATH_CFG0 (RX_START_OFFSET + 0x0504) +#define BOLERO_CDC_RX_RX2_RX_PATH_CFG1 (RX_START_OFFSET + 0x0508) +#define BOLERO_CDC_RX_RX2_RX_PATH_CFG2 (RX_START_OFFSET + 0x050C) +#define BOLERO_CDC_RX_RX2_RX_PATH_CFG3 (RX_START_OFFSET + 0x0510) +#define BOLERO_CDC_RX_RX2_RX_VOL_CTL (RX_START_OFFSET + 0x0514) +#define BOLERO_CDC_RX_RX2_RX_PATH_MIX_CTL (RX_START_OFFSET + 0x0518) +#define BOLERO_CDC_RX_RX2_RX_PATH_MIX_CFG (RX_START_OFFSET + 0x051C) +#define BOLERO_CDC_RX_RX2_RX_VOL_MIX_CTL (RX_START_OFFSET + 0x0520) +#define BOLERO_CDC_RX_RX2_RX_PATH_SEC0 (RX_START_OFFSET + 0x0524) +#define BOLERO_CDC_RX_RX2_RX_PATH_SEC1 (RX_START_OFFSET + 0x0528) +#define BOLERO_CDC_RX_RX2_RX_PATH_SEC2 (RX_START_OFFSET + 0x052C) +#define BOLERO_CDC_RX_RX2_RX_PATH_SEC3 (RX_START_OFFSET + 0x0530) +#define BOLERO_CDC_RX_RX2_RX_PATH_SEC4 (RX_START_OFFSET + 0x0534) +#define BOLERO_CDC_RX_RX2_RX_PATH_SEC5 (RX_START_OFFSET + 0x0538) +#define BOLERO_CDC_RX_RX2_RX_PATH_SEC6 (RX_START_OFFSET + 0x053C) +#define BOLERO_CDC_RX_RX2_RX_PATH_SEC7 (RX_START_OFFSET + 0x0540) +#define BOLERO_CDC_RX_RX2_RX_PATH_MIX_SEC0 (RX_START_OFFSET + 0x0544) +#define BOLERO_CDC_RX_RX2_RX_PATH_MIX_SEC1 (RX_START_OFFSET + 0x0548) +#define BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL (RX_START_OFFSET + 0x054C) +#define BOLERO_CDC_RX_IDLE_DETECT_PATH_CTL (RX_START_OFFSET + 0x0780) +#define BOLERO_CDC_RX_IDLE_DETECT_CFG0 (RX_START_OFFSET + 0x0784) +#define BOLERO_CDC_RX_IDLE_DETECT_CFG1 (RX_START_OFFSET + 0x0788) +#define BOLERO_CDC_RX_IDLE_DETECT_CFG2 (RX_START_OFFSET + 0x078C) +#define BOLERO_CDC_RX_IDLE_DETECT_CFG3 (RX_START_OFFSET + 0x0790) +#define BOLERO_CDC_RX_COMPANDER0_CTL0 (RX_START_OFFSET + 0x0800) +#define BOLERO_CDC_RX_COMPANDER0_CTL1 (RX_START_OFFSET + 0x0804) +#define BOLERO_CDC_RX_COMPANDER0_CTL2 (RX_START_OFFSET + 0x0808) +#define BOLERO_CDC_RX_COMPANDER0_CTL3 (RX_START_OFFSET + 0x080C) +#define BOLERO_CDC_RX_COMPANDER0_CTL4 (RX_START_OFFSET + 0x0810) +#define BOLERO_CDC_RX_COMPANDER0_CTL5 (RX_START_OFFSET + 0x0814) +#define BOLERO_CDC_RX_COMPANDER0_CTL6 (RX_START_OFFSET + 0x0818) +#define BOLERO_CDC_RX_COMPANDER0_CTL7 (RX_START_OFFSET + 0x081C) +#define BOLERO_CDC_RX_COMPANDER1_CTL0 (RX_START_OFFSET + 0x0840) +#define BOLERO_CDC_RX_COMPANDER1_CTL1 (RX_START_OFFSET + 0x0844) +#define BOLERO_CDC_RX_COMPANDER1_CTL2 (RX_START_OFFSET + 0x0848) +#define BOLERO_CDC_RX_COMPANDER1_CTL3 (RX_START_OFFSET + 0x084C) +#define BOLERO_CDC_RX_COMPANDER1_CTL4 (RX_START_OFFSET + 0x0850) +#define BOLERO_CDC_RX_COMPANDER1_CTL5 (RX_START_OFFSET + 0x0854) +#define BOLERO_CDC_RX_COMPANDER1_CTL6 (RX_START_OFFSET + 0x0858) +#define BOLERO_CDC_RX_COMPANDER1_CTL7 (RX_START_OFFSET + 0x085C) +#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL \ + (RX_START_OFFSET + 0x0A00) +#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL \ + (RX_START_OFFSET + 0x0A04) +#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL \ + (RX_START_OFFSET + 0x0A08) +#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL \ + (RX_START_OFFSET + 0x0A0C) +#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL \ + (RX_START_OFFSET + 0x0A10) +#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL \ + (RX_START_OFFSET + 0x0A14) +#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL \ + (RX_START_OFFSET + 0x0A18) +#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL \ + (RX_START_OFFSET + 0x0A1C) +#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL \ + (RX_START_OFFSET + 0x0A20) +#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_CTL (RX_START_OFFSET + 0x0A24) +#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL \ + (RX_START_OFFSET + 0x0A28) +#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL \ + (RX_START_OFFSET + 0x0A2C) +#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL \ + (RX_START_OFFSET + 0x0A30) +#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL \ + (RX_START_OFFSET + 0x0A80) +#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL \ + (RX_START_OFFSET + 0x0A84) +#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL \ + (RX_START_OFFSET + 0x0A88) +#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL \ + (RX_START_OFFSET + 0x0A8C) +#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL \ + (RX_START_OFFSET + 0x0A90) +#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL \ + (RX_START_OFFSET + 0x0A94) +#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL \ + (RX_START_OFFSET + 0x0A98) +#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL \ + (RX_START_OFFSET + 0x0A9C) +#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL \ + (RX_START_OFFSET + 0x0AA0) +#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_CTL (RX_START_OFFSET + 0x0AA4) +#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL \ + (RX_START_OFFSET + 0x0AA8) +#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL \ + (RX_START_OFFSET + 0x0AAC) +#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL \ + (RX_START_OFFSET + 0x0AB0) +#define BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0 (RX_START_OFFSET + 0x0B00) +#define BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1 (RX_START_OFFSET + 0x0B04) +#define BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2 (RX_START_OFFSET + 0x0B08) +#define BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3 (RX_START_OFFSET + 0x0B0C) +#define BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0 (RX_START_OFFSET + 0x0B10) +#define BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1 (RX_START_OFFSET + 0x0B14) +#define BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2 (RX_START_OFFSET + 0x0B18) +#define BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3 (RX_START_OFFSET + 0x0B1C) +#define BOLERO_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL \ + (RX_START_OFFSET + 0x0B40) +#define BOLERO_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1 \ + (RX_START_OFFSET + 0x0B44) +#define BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL \ + (RX_START_OFFSET + 0x0B50) +#define BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1 \ + (RX_START_OFFSET + 0x0B54) +#define BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL \ + (RX_START_OFFSET + 0x0C00) +#define BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0 (RX_START_OFFSET + 0x0C04) +#define BOLERO_CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL \ + (RX_START_OFFSET + 0x0C40) +#define BOLERO_CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0 (RX_START_OFFSET + 0x0C44) +#define BOLERO_CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL \ + (RX_START_OFFSET + 0x0C80) +#define BOLERO_CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0 (RX_START_OFFSET + 0x0C84) +#define BOLERO_CDC_RX_EC_ASRC0_CLK_RST_CTL (RX_START_OFFSET + 0x0D00) +#define BOLERO_CDC_RX_EC_ASRC0_CTL0 (RX_START_OFFSET + 0x0D04) +#define BOLERO_CDC_RX_EC_ASRC0_CTL1 (RX_START_OFFSET + 0x0D08) +#define BOLERO_CDC_RX_EC_ASRC0_FIFO_CTL (RX_START_OFFSET + 0x0D0C) +#define BOLERO_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB \ + (RX_START_OFFSET + 0x0D10) +#define BOLERO_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB \ + (RX_START_OFFSET + 0x0D14) +#define BOLERO_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB \ + (RX_START_OFFSET + 0x0D18) +#define BOLERO_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB \ + (RX_START_OFFSET + 0x0D1C) +#define BOLERO_CDC_RX_EC_ASRC0_STATUS_FIFO (RX_START_OFFSET + 0x0D20) +#define BOLERO_CDC_RX_EC_ASRC1_CLK_RST_CTL (RX_START_OFFSET + 0x0D40) +#define BOLERO_CDC_RX_EC_ASRC1_CTL0 (RX_START_OFFSET + 0x0D44) +#define BOLERO_CDC_RX_EC_ASRC1_CTL1 (RX_START_OFFSET + 0x0D48) +#define BOLERO_CDC_RX_EC_ASRC1_FIFO_CTL (RX_START_OFFSET + 0x0D4C) +#define BOLERO_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB \ + (RX_START_OFFSET + 0x0D50) +#define BOLERO_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB \ + (RX_START_OFFSET + 0x0D54) +#define BOLERO_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB \ + (RX_START_OFFSET + 0x0D58) +#define BOLERO_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB \ + (RX_START_OFFSET + 0x0D5C) +#define BOLERO_CDC_RX_EC_ASRC1_STATUS_FIFO (RX_START_OFFSET + 0x0D60) +#define BOLERO_CDC_RX_EC_ASRC2_CLK_RST_CTL (RX_START_OFFSET + 0x0D80) +#define BOLERO_CDC_RX_EC_ASRC2_CTL0 (RX_START_OFFSET + 0x0D84) +#define BOLERO_CDC_RX_EC_ASRC2_CTL1 (RX_START_OFFSET + 0x0D88) +#define BOLERO_CDC_RX_EC_ASRC2_FIFO_CTL (RX_START_OFFSET + 0x0D8C) +#define BOLERO_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB \ + (RX_START_OFFSET + 0x0D90) +#define BOLERO_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB \ + (RX_START_OFFSET + 0x0D94) +#define BOLERO_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB \ + (RX_START_OFFSET + 0x0D98) +#define BOLERO_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB \ + (RX_START_OFFSET + 0x0D9C) +#define BOLERO_CDC_RX_EC_ASRC2_STATUS_FIFO (RX_START_OFFSET + 0x0DA0) +#define BOLERO_CDC_RX_DSD0_PATH_CTL (RX_START_OFFSET + 0x0F00) +#define BOLERO_CDC_RX_DSD0_CFG0 (RX_START_OFFSET + 0x0F04) +#define BOLERO_CDC_RX_DSD0_CFG1 (RX_START_OFFSET + 0x0F08) +#define BOLERO_CDC_RX_DSD0_CFG2 (RX_START_OFFSET + 0x0F0C) +#define BOLERO_CDC_RX_DSD1_PATH_CTL (RX_START_OFFSET + 0x0F80) +#define BOLERO_CDC_RX_DSD1_CFG0 (RX_START_OFFSET + 0x0F84) +#define BOLERO_CDC_RX_DSD1_CFG1 (RX_START_OFFSET + 0x0F88) +#define BOLERO_CDC_RX_DSD1_CFG2 (RX_START_OFFSET + 0x0F8C) +#define RX_MAX_OFFSET (RX_START_OFFSET + 0x0F8C) + +#define BOLERO_CDC_RX_MACRO_MAX 0x3E4 /* F8C/4 = 3E3 + 1 */ + +/* WSA - macro#2 */ +#define WSA_START_OFFSET 0x2000 +#define BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL \ + (WSA_START_OFFSET + 0x0000) +#define BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL \ + (WSA_START_OFFSET + 0x0004) +#define BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL (WSA_START_OFFSET + 0x0008) +#define BOLERO_CDC_WSA_TOP_TOP_CFG0 (WSA_START_OFFSET + 0x0080) +#define BOLERO_CDC_WSA_TOP_TOP_CFG1 (WSA_START_OFFSET + 0x0084) +#define BOLERO_CDC_WSA_TOP_FREQ_MCLK (WSA_START_OFFSET + 0x0088) +#define BOLERO_CDC_WSA_TOP_DEBUG_BUS_SEL (WSA_START_OFFSET + 0x008C) +#define BOLERO_CDC_WSA_TOP_DEBUG_EN0 (WSA_START_OFFSET + 0x0090) +#define BOLERO_CDC_WSA_TOP_DEBUG_EN1 (WSA_START_OFFSET + 0x0094) +#define BOLERO_CDC_WSA_TOP_DEBUG_DSM_LB (WSA_START_OFFSET + 0x0098) +#define BOLERO_CDC_WSA_TOP_RX_I2S_CTL (WSA_START_OFFSET + 0x009C) +#define BOLERO_CDC_WSA_TOP_TX_I2S_CTL (WSA_START_OFFSET + 0x00A0) +#define BOLERO_CDC_WSA_TOP_I2S_CLK (WSA_START_OFFSET + 0x00A4) +#define BOLERO_CDC_WSA_TOP_I2S_RESET (WSA_START_OFFSET + 0x00A8) +#define BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 (WSA_START_OFFSET + 0x0100) +#define BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1 (WSA_START_OFFSET + 0x0104) +#define BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0 (WSA_START_OFFSET + 0x0108) +#define BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1 (WSA_START_OFFSET + 0x010C) +#define BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0 (WSA_START_OFFSET + 0x0110) +#define BOLERO_CDC_WSA_RX_INP_MUX_RX_EC_CFG0 (WSA_START_OFFSET + 0x0114) +#define BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0 (WSA_START_OFFSET + 0x0118) +/* VBAT registers */ +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL (WSA_START_OFFSET + 0x0180) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG (WSA_START_OFFSET + 0x0184) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL1 (WSA_START_OFFSET + 0x0188) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL2 (WSA_START_OFFSET + 0x018C) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL3 (WSA_START_OFFSET + 0x0190) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST1 (WSA_START_OFFSET + 0x0194) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST2 (WSA_START_OFFSET + 0x0198) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST3 (WSA_START_OFFSET + 0x019C) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_RF_PROC1 (WSA_START_OFFSET + 0x01A0) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_RF_PROC2 (WSA_START_OFFSET + 0x01A4) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC1 (WSA_START_OFFSET + 0x01A8) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC2 (WSA_START_OFFSET + 0x01AC) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC3 (WSA_START_OFFSET + 0x01B0) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC4 (WSA_START_OFFSET + 0x01B4) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD1 (WSA_START_OFFSET + 0x01B8) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD2 (WSA_START_OFFSET + 0x01BC) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD3 (WSA_START_OFFSET + 0x01C0) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD4 (WSA_START_OFFSET + 0x01C4) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD5 (WSA_START_OFFSET + 0x01C8) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_DEBUG1 (WSA_START_OFFSET + 0x01CC) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD_MON \ + (WSA_START_OFFSET + 0x01D0) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_MON_VAL \ + (WSA_START_OFFSET + 0x01D4) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BAN (WSA_START_OFFSET + 0x01D8) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1 \ + (WSA_START_OFFSET + 0x01DC) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2 \ + (WSA_START_OFFSET + 0x01E0) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3 \ + (WSA_START_OFFSET + 0x01E4) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4 \ + (WSA_START_OFFSET + 0x01E8) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5 \ + (WSA_START_OFFSET + 0x01EC) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6 \ + (WSA_START_OFFSET + 0x01F0) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7 \ + (WSA_START_OFFSET + 0x01F4) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8 \ + (WSA_START_OFFSET + 0x01F8) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9 \ + (WSA_START_OFFSET + 0x01FC) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN1 (WSA_START_OFFSET + 0x0200) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN2 (WSA_START_OFFSET + 0x0204) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN3 (WSA_START_OFFSET + 0x0208) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1 \ + (WSA_START_OFFSET + 0x020C) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL2 \ + (WSA_START_OFFSET + 0x0210) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1 \ + (WSA_START_OFFSET + 0x0214) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2 \ + (WSA_START_OFFSET + 0x0218) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3 \ + (WSA_START_OFFSET + 0x021C) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4 \ + (WSA_START_OFFSET + 0x0220) +#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_ST (WSA_START_OFFSET + 0x0224) +#define BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL (WSA_START_OFFSET + 0x0244) +#define BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0 (WSA_START_OFFSET + 0x0248) +#define BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL (WSA_START_OFFSET + 0x0264) +#define BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0 (WSA_START_OFFSET + 0x0268) +#define BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL (WSA_START_OFFSET + 0x0284) +#define BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0 (WSA_START_OFFSET + 0x0288) +#define BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL (WSA_START_OFFSET + 0x02A4) +#define BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0 (WSA_START_OFFSET + 0x02A8) +#define BOLERO_CDC_WSA_INTR_CTRL_CFG (WSA_START_OFFSET + 0x0340) +#define BOLERO_CDC_WSA_INTR_CTRL_CLR_COMMIT (WSA_START_OFFSET + 0x0344) +#define BOLERO_CDC_WSA_INTR_CTRL_PIN1_MASK0 (WSA_START_OFFSET + 0x0360) +#define BOLERO_CDC_WSA_INTR_CTRL_PIN1_STATUS0 (WSA_START_OFFSET + 0x0368) +#define BOLERO_CDC_WSA_INTR_CTRL_PIN1_CLEAR0 (WSA_START_OFFSET + 0x0370) +#define BOLERO_CDC_WSA_INTR_CTRL_PIN2_MASK0 (WSA_START_OFFSET + 0x0380) +#define BOLERO_CDC_WSA_INTR_CTRL_PIN2_STATUS0 (WSA_START_OFFSET + 0x0388) +#define BOLERO_CDC_WSA_INTR_CTRL_PIN2_CLEAR0 (WSA_START_OFFSET + 0x0390) +#define BOLERO_CDC_WSA_INTR_CTRL_LEVEL0 (WSA_START_OFFSET + 0x03C0) +#define BOLERO_CDC_WSA_INTR_CTRL_BYPASS0 (WSA_START_OFFSET + 0x03C8) +#define BOLERO_CDC_WSA_INTR_CTRL_SET0 (WSA_START_OFFSET + 0x03D0) +#define BOLERO_CDC_WSA_RX0_RX_PATH_CTL (WSA_START_OFFSET + 0x0400) +#define BOLERO_CDC_WSA_RX0_RX_PATH_CFG0 (WSA_START_OFFSET + 0x0404) +#define BOLERO_CDC_WSA_RX0_RX_PATH_CFG1 (WSA_START_OFFSET + 0x0408) +#define BOLERO_CDC_WSA_RX0_RX_PATH_CFG2 (WSA_START_OFFSET + 0x040C) +#define BOLERO_CDC_WSA_RX0_RX_PATH_CFG3 (WSA_START_OFFSET + 0x0410) +#define BOLERO_CDC_WSA_RX0_RX_VOL_CTL (WSA_START_OFFSET + 0x0414) +#define BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL (WSA_START_OFFSET + 0x0418) +#define BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG (WSA_START_OFFSET + 0x041C) +#define BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL (WSA_START_OFFSET + 0x0420) +#define BOLERO_CDC_WSA_RX0_RX_PATH_SEC0 (WSA_START_OFFSET + 0x0424) +#define BOLERO_CDC_WSA_RX0_RX_PATH_SEC1 (WSA_START_OFFSET + 0x0428) +#define BOLERO_CDC_WSA_RX0_RX_PATH_SEC2 (WSA_START_OFFSET + 0x042C) +#define BOLERO_CDC_WSA_RX0_RX_PATH_SEC3 (WSA_START_OFFSET + 0x0430) +#define BOLERO_CDC_WSA_RX0_RX_PATH_SEC5 (WSA_START_OFFSET + 0x0438) +#define BOLERO_CDC_WSA_RX0_RX_PATH_SEC6 (WSA_START_OFFSET + 0x043C) +#define BOLERO_CDC_WSA_RX0_RX_PATH_SEC7 (WSA_START_OFFSET + 0x0440) +#define BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0 (WSA_START_OFFSET + 0x0444) +#define BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC1 (WSA_START_OFFSET + 0x0448) +#define BOLERO_CDC_WSA_RX0_RX_PATH_DSMDEM_CTL (WSA_START_OFFSET + 0x044C) +#define BOLERO_CDC_WSA_RX1_RX_PATH_CTL (WSA_START_OFFSET + 0x0480) +#define BOLERO_CDC_WSA_RX1_RX_PATH_CFG0 (WSA_START_OFFSET + 0x0484) +#define BOLERO_CDC_WSA_RX1_RX_PATH_CFG1 (WSA_START_OFFSET + 0x0488) +#define BOLERO_CDC_WSA_RX1_RX_PATH_CFG2 (WSA_START_OFFSET + 0x048C) +#define BOLERO_CDC_WSA_RX1_RX_PATH_CFG3 (WSA_START_OFFSET + 0x0490) +#define BOLERO_CDC_WSA_RX1_RX_VOL_CTL (WSA_START_OFFSET + 0x0494) +#define BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL (WSA_START_OFFSET + 0x0498) +#define BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG (WSA_START_OFFSET + 0x049C) +#define BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL (WSA_START_OFFSET + 0x04A0) +#define BOLERO_CDC_WSA_RX1_RX_PATH_SEC0 (WSA_START_OFFSET + 0x04A4) +#define BOLERO_CDC_WSA_RX1_RX_PATH_SEC1 (WSA_START_OFFSET + 0x04A8) +#define BOLERO_CDC_WSA_RX1_RX_PATH_SEC2 (WSA_START_OFFSET + 0x04AC) +#define BOLERO_CDC_WSA_RX1_RX_PATH_SEC3 (WSA_START_OFFSET + 0x04B0) +#define BOLERO_CDC_WSA_RX1_RX_PATH_SEC5 (WSA_START_OFFSET + 0x04B8) +#define BOLERO_CDC_WSA_RX1_RX_PATH_SEC6 (WSA_START_OFFSET + 0x04BC) +#define BOLERO_CDC_WSA_RX1_RX_PATH_SEC7 (WSA_START_OFFSET + 0x04C0) +#define BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0 (WSA_START_OFFSET + 0x04C4) +#define BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC1 (WSA_START_OFFSET + 0x04C8) +#define BOLERO_CDC_WSA_RX1_RX_PATH_DSMDEM_CTL (WSA_START_OFFSET + 0x04CC) +#define BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL (WSA_START_OFFSET + 0x0500) +#define BOLERO_CDC_WSA_BOOST0_BOOST_CTL (WSA_START_OFFSET + 0x0504) +#define BOLERO_CDC_WSA_BOOST0_BOOST_CFG1 (WSA_START_OFFSET + 0x0508) +#define BOLERO_CDC_WSA_BOOST0_BOOST_CFG2 (WSA_START_OFFSET + 0x050C) +#define BOLERO_CDC_WSA_BOOST1_BOOST_PATH_CTL (WSA_START_OFFSET + 0x0540) +#define BOLERO_CDC_WSA_BOOST1_BOOST_CTL (WSA_START_OFFSET + 0x0544) +#define BOLERO_CDC_WSA_BOOST1_BOOST_CFG1 (WSA_START_OFFSET + 0x0548) +#define BOLERO_CDC_WSA_BOOST1_BOOST_CFG2 (WSA_START_OFFSET + 0x054C) +#define BOLERO_CDC_WSA_COMPANDER0_CTL0 (WSA_START_OFFSET + 0x0580) +#define BOLERO_CDC_WSA_COMPANDER0_CTL1 (WSA_START_OFFSET + 0x0584) +#define BOLERO_CDC_WSA_COMPANDER0_CTL2 (WSA_START_OFFSET + 0x0588) +#define BOLERO_CDC_WSA_COMPANDER0_CTL3 (WSA_START_OFFSET + 0x058C) +#define BOLERO_CDC_WSA_COMPANDER0_CTL4 (WSA_START_OFFSET + 0x0590) +#define BOLERO_CDC_WSA_COMPANDER0_CTL5 (WSA_START_OFFSET + 0x0594) +#define BOLERO_CDC_WSA_COMPANDER0_CTL6 (WSA_START_OFFSET + 0x0598) +#define BOLERO_CDC_WSA_COMPANDER0_CTL7 (WSA_START_OFFSET + 0x059C) +#define BOLERO_CDC_WSA_COMPANDER1_CTL0 (WSA_START_OFFSET + 0x05C0) +#define BOLERO_CDC_WSA_COMPANDER1_CTL1 (WSA_START_OFFSET + 0x05C4) +#define BOLERO_CDC_WSA_COMPANDER1_CTL2 (WSA_START_OFFSET + 0x05C8) +#define BOLERO_CDC_WSA_COMPANDER1_CTL3 (WSA_START_OFFSET + 0x05CC) +#define BOLERO_CDC_WSA_COMPANDER1_CTL4 (WSA_START_OFFSET + 0x05D0) +#define BOLERO_CDC_WSA_COMPANDER1_CTL5 (WSA_START_OFFSET + 0x05D4) +#define BOLERO_CDC_WSA_COMPANDER1_CTL6 (WSA_START_OFFSET + 0x05D8) +#define BOLERO_CDC_WSA_COMPANDER1_CTL7 (WSA_START_OFFSET + 0x05DC) +#define BOLERO_CDC_WSA_SOFTCLIP0_CRC (WSA_START_OFFSET + 0x0600) +#define BOLERO_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL (WSA_START_OFFSET + 0x0604) +#define BOLERO_CDC_WSA_SOFTCLIP1_CRC (WSA_START_OFFSET + 0x0640) +#define BOLERO_CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL (WSA_START_OFFSET + 0x0644) +#define BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL \ + (WSA_START_OFFSET + 0x0680) +#define BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 (WSA_START_OFFSET + 0x0684) +#define BOLERO_CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL \ + (WSA_START_OFFSET + 0x06C0) +#define BOLERO_CDC_WSA_EC_HQ1_EC_REF_HQ_CFG0 (WSA_START_OFFSET + 0x06C4) +#define BOLERO_CDC_WSA_SPLINE_ASRC0_CLK_RST_CTL (WSA_START_OFFSET + 0x0700) +#define BOLERO_CDC_WSA_SPLINE_ASRC0_CTL0 (WSA_START_OFFSET + 0x0704) +#define BOLERO_CDC_WSA_SPLINE_ASRC0_CTL1 (WSA_START_OFFSET + 0x0708) +#define BOLERO_CDC_WSA_SPLINE_ASRC0_FIFO_CTL (WSA_START_OFFSET + 0x070C) +#define BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB \ + (WSA_START_OFFSET + 0x0710) +#define BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB \ + (WSA_START_OFFSET + 0x0714) +#define BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB \ + (WSA_START_OFFSET + 0x0718) +#define BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB \ + (WSA_START_OFFSET + 0x071C) +#define BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FIFO (WSA_START_OFFSET + 0x0720) +#define BOLERO_CDC_WSA_SPLINE_ASRC1_CLK_RST_CTL (WSA_START_OFFSET + 0x0740) +#define BOLERO_CDC_WSA_SPLINE_ASRC1_CTL0 (WSA_START_OFFSET + 0x0744) +#define BOLERO_CDC_WSA_SPLINE_ASRC1_CTL1 (WSA_START_OFFSET + 0x0748) +#define BOLERO_CDC_WSA_SPLINE_ASRC1_FIFO_CTL (WSA_START_OFFSET + 0x074C) +#define BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB \ + (WSA_START_OFFSET + 0x0750) +#define BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB \ + (WSA_START_OFFSET + 0x0754) +#define BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB \ + (WSA_START_OFFSET + 0x0758) +#define BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB \ + (WSA_START_OFFSET + 0x075C) +#define BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FIFO (WSA_START_OFFSET + 0x0760) +#define WSA_MAX_OFFSET (WSA_START_OFFSET + 0x0760) + +#define BOLERO_CDC_WSA_MACRO_MAX 0x1D9 /* 0x760/4 = 0x1D8 + 1 registers */ + +/* VA macro registers */ +#define VA_START_OFFSET 0x3000 +#define BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL (VA_START_OFFSET + 0x0000) +#define BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL \ + (VA_START_OFFSET + 0x0004) +#define BOLERO_CDC_VA_TOP_CSR_TOP_CFG0 (VA_START_OFFSET + 0x0080) +#define BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL (VA_START_OFFSET + 0x0084) +#define BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL (VA_START_OFFSET + 0x0088) +#define BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL (VA_START_OFFSET + 0x008C) +#define BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL (VA_START_OFFSET + 0x0090) +#define BOLERO_CDC_VA_TOP_CSR_DMIC_CFG (VA_START_OFFSET + 0x0094) +#define BOLERO_CDC_VA_TOP_CSR_DEBUG_BUS (VA_START_OFFSET + 0x009C) +#define BOLERO_CDC_VA_TOP_CSR_DEBUG_EN (VA_START_OFFSET + 0x00A0) +#define BOLERO_CDC_VA_TOP_CSR_TX_I2S_CTL (VA_START_OFFSET + 0x00A4) +#define BOLERO_CDC_VA_TOP_CSR_I2S_CLK (VA_START_OFFSET + 0x00A8) +#define BOLERO_CDC_VA_TOP_CSR_I2S_RESET (VA_START_OFFSET + 0x00AC) +#define BOLERO_CDC_VA_TOP_CSR_CORE_ID_0 (VA_START_OFFSET + 0x00C0) +#define BOLERO_CDC_VA_TOP_CSR_CORE_ID_1 (VA_START_OFFSET + 0x00C4) +#define BOLERO_CDC_VA_TOP_CSR_CORE_ID_2 (VA_START_OFFSET + 0x00C8) +#define BOLERO_CDC_VA_TOP_CSR_CORE_ID_3 (VA_START_OFFSET + 0x00CC) +#define VA_TOP_MAX_OFFSET (VA_START_OFFSET + 0x00CC) + +#define BOLERO_CDC_VA_MACRO_TOP_MAX 0x34 /* 0x0CC/4 = 0x33 + 1 = 0x34 */ + +#define BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0 (VA_START_OFFSET + 0x0100) +#define BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1 (VA_START_OFFSET + 0x0104) +#define BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG0 (VA_START_OFFSET + 0x0108) +#define BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG1 (VA_START_OFFSET + 0x010C) +#define BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG0 (VA_START_OFFSET + 0x0110) +#define BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG1 (VA_START_OFFSET + 0x0114) +#define BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG0 (VA_START_OFFSET + 0x0118) +#define BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG1 (VA_START_OFFSET + 0x011C) +#define BOLERO_CDC_VA_INP_MUX_ADC_MUX4_CFG0 (VA_START_OFFSET + 0x0120) +#define BOLERO_CDC_VA_INP_MUX_ADC_MUX4_CFG1 (VA_START_OFFSET + 0x0124) +#define BOLERO_CDC_VA_INP_MUX_ADC_MUX5_CFG0 (VA_START_OFFSET + 0x0128) +#define BOLERO_CDC_VA_INP_MUX_ADC_MUX5_CFG1 (VA_START_OFFSET + 0x012C) +#define BOLERO_CDC_VA_INP_MUX_ADC_MUX6_CFG0 (VA_START_OFFSET + 0x0130) +#define BOLERO_CDC_VA_INP_MUX_ADC_MUX6_CFG1 (VA_START_OFFSET + 0x0134) +#define BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG0 (VA_START_OFFSET + 0x0138) +#define BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG1 (VA_START_OFFSET + 0x013C) + +#define BOLERO_CDC_VA_TX0_TX_PATH_CTL (VA_START_OFFSET + 0x0400) +#define BOLERO_CDC_VA_TX0_TX_PATH_CFG0 (VA_START_OFFSET + 0x0404) +#define BOLERO_CDC_VA_TX0_TX_PATH_CFG1 (VA_START_OFFSET + 0x0408) +#define BOLERO_CDC_VA_TX0_TX_VOL_CTL (VA_START_OFFSET + 0x040C) +#define BOLERO_CDC_VA_TX0_TX_PATH_SEC0 (VA_START_OFFSET + 0x0410) +#define BOLERO_CDC_VA_TX0_TX_PATH_SEC1 (VA_START_OFFSET + 0x0414) +#define BOLERO_CDC_VA_TX0_TX_PATH_SEC2 (VA_START_OFFSET + 0x0418) +#define BOLERO_CDC_VA_TX0_TX_PATH_SEC3 (VA_START_OFFSET + 0x041C) +#define BOLERO_CDC_VA_TX0_TX_PATH_SEC4 (VA_START_OFFSET + 0x0420) +#define BOLERO_CDC_VA_TX0_TX_PATH_SEC5 (VA_START_OFFSET + 0x0424) +#define BOLERO_CDC_VA_TX0_TX_PATH_SEC6 (VA_START_OFFSET + 0x0428) +#define BOLERO_CDC_VA_TX0_TX_PATH_SEC7 (VA_START_OFFSET + 0x042C) +#define BOLERO_CDC_VA_TX1_TX_PATH_CTL (VA_START_OFFSET + 0x0480) +#define BOLERO_CDC_VA_TX1_TX_PATH_CFG0 (VA_START_OFFSET + 0x0484) +#define BOLERO_CDC_VA_TX1_TX_PATH_CFG1 (VA_START_OFFSET + 0x0488) +#define BOLERO_CDC_VA_TX1_TX_VOL_CTL (VA_START_OFFSET + 0x048C) +#define BOLERO_CDC_VA_TX1_TX_PATH_SEC0 (VA_START_OFFSET + 0x0490) +#define BOLERO_CDC_VA_TX1_TX_PATH_SEC1 (VA_START_OFFSET + 0x0494) +#define BOLERO_CDC_VA_TX1_TX_PATH_SEC2 (VA_START_OFFSET + 0x0498) +#define BOLERO_CDC_VA_TX1_TX_PATH_SEC3 (VA_START_OFFSET + 0x049C) +#define BOLERO_CDC_VA_TX1_TX_PATH_SEC4 (VA_START_OFFSET + 0x04A0) +#define BOLERO_CDC_VA_TX1_TX_PATH_SEC5 (VA_START_OFFSET + 0x04A4) +#define BOLERO_CDC_VA_TX1_TX_PATH_SEC6 (VA_START_OFFSET + 0x04A8) +#define BOLERO_CDC_VA_TX2_TX_PATH_CTL (VA_START_OFFSET + 0x0500) +#define BOLERO_CDC_VA_TX2_TX_PATH_CFG0 (VA_START_OFFSET + 0x0504) +#define BOLERO_CDC_VA_TX2_TX_PATH_CFG1 (VA_START_OFFSET + 0x0508) +#define BOLERO_CDC_VA_TX2_TX_VOL_CTL (VA_START_OFFSET + 0x050C) +#define BOLERO_CDC_VA_TX2_TX_PATH_SEC0 (VA_START_OFFSET + 0x0510) +#define BOLERO_CDC_VA_TX2_TX_PATH_SEC1 (VA_START_OFFSET + 0x0514) +#define BOLERO_CDC_VA_TX2_TX_PATH_SEC2 (VA_START_OFFSET + 0x0518) +#define BOLERO_CDC_VA_TX2_TX_PATH_SEC3 (VA_START_OFFSET + 0x051C) +#define BOLERO_CDC_VA_TX2_TX_PATH_SEC4 (VA_START_OFFSET + 0x0520) +#define BOLERO_CDC_VA_TX2_TX_PATH_SEC5 (VA_START_OFFSET + 0x0524) +#define BOLERO_CDC_VA_TX2_TX_PATH_SEC6 (VA_START_OFFSET + 0x0528) +#define BOLERO_CDC_VA_TX3_TX_PATH_CTL (VA_START_OFFSET + 0x0580) +#define BOLERO_CDC_VA_TX3_TX_PATH_CFG0 (VA_START_OFFSET + 0x0584) +#define BOLERO_CDC_VA_TX3_TX_PATH_CFG1 (VA_START_OFFSET + 0x0588) +#define BOLERO_CDC_VA_TX3_TX_VOL_CTL (VA_START_OFFSET + 0x058C) +#define BOLERO_CDC_VA_TX3_TX_PATH_SEC0 (VA_START_OFFSET + 0x0590) +#define BOLERO_CDC_VA_TX3_TX_PATH_SEC1 (VA_START_OFFSET + 0x0594) +#define BOLERO_CDC_VA_TX3_TX_PATH_SEC2 (VA_START_OFFSET + 0x0598) +#define BOLERO_CDC_VA_TX3_TX_PATH_SEC3 (VA_START_OFFSET + 0x059C) +#define BOLERO_CDC_VA_TX3_TX_PATH_SEC4 (VA_START_OFFSET + 0x05A0) +#define BOLERO_CDC_VA_TX3_TX_PATH_SEC5 (VA_START_OFFSET + 0x05A4) +#define BOLERO_CDC_VA_TX3_TX_PATH_SEC6 (VA_START_OFFSET + 0x05A8) +#define BOLERO_CDC_VA_TX4_TX_PATH_CTL (VA_START_OFFSET + 0x0600) +#define BOLERO_CDC_VA_TX4_TX_PATH_CFG0 (VA_START_OFFSET + 0x0604) +#define BOLERO_CDC_VA_TX4_TX_PATH_CFG1 (VA_START_OFFSET + 0x0608) +#define BOLERO_CDC_VA_TX4_TX_VOL_CTL (VA_START_OFFSET + 0x060C) +#define BOLERO_CDC_VA_TX4_TX_PATH_SEC0 (VA_START_OFFSET + 0x0610) +#define BOLERO_CDC_VA_TX4_TX_PATH_SEC1 (VA_START_OFFSET + 0x0614) +#define BOLERO_CDC_VA_TX4_TX_PATH_SEC2 (VA_START_OFFSET + 0x0618) +#define BOLERO_CDC_VA_TX4_TX_PATH_SEC3 (VA_START_OFFSET + 0x061C) +#define BOLERO_CDC_VA_TX4_TX_PATH_SEC4 (VA_START_OFFSET + 0x0620) +#define BOLERO_CDC_VA_TX4_TX_PATH_SEC5 (VA_START_OFFSET + 0x0624) +#define BOLERO_CDC_VA_TX4_TX_PATH_SEC6 (VA_START_OFFSET + 0x0628) +#define BOLERO_CDC_VA_TX5_TX_PATH_CTL (VA_START_OFFSET + 0x0680) +#define BOLERO_CDC_VA_TX5_TX_PATH_CFG0 (VA_START_OFFSET + 0x0684) +#define BOLERO_CDC_VA_TX5_TX_PATH_CFG1 (VA_START_OFFSET + 0x0688) +#define BOLERO_CDC_VA_TX5_TX_VOL_CTL (VA_START_OFFSET + 0x068C) +#define BOLERO_CDC_VA_TX5_TX_PATH_SEC0 (VA_START_OFFSET + 0x0690) +#define BOLERO_CDC_VA_TX5_TX_PATH_SEC1 (VA_START_OFFSET + 0x0694) +#define BOLERO_CDC_VA_TX5_TX_PATH_SEC2 (VA_START_OFFSET + 0x0698) +#define BOLERO_CDC_VA_TX5_TX_PATH_SEC3 (VA_START_OFFSET + 0x069C) +#define BOLERO_CDC_VA_TX5_TX_PATH_SEC4 (VA_START_OFFSET + 0x06A0) +#define BOLERO_CDC_VA_TX5_TX_PATH_SEC5 (VA_START_OFFSET + 0x06A4) +#define BOLERO_CDC_VA_TX5_TX_PATH_SEC6 (VA_START_OFFSET + 0x06A8) +#define BOLERO_CDC_VA_TX6_TX_PATH_CTL (VA_START_OFFSET + 0x0700) +#define BOLERO_CDC_VA_TX6_TX_PATH_CFG0 (VA_START_OFFSET + 0x0704) +#define BOLERO_CDC_VA_TX6_TX_PATH_CFG1 (VA_START_OFFSET + 0x0708) +#define BOLERO_CDC_VA_TX6_TX_VOL_CTL (VA_START_OFFSET + 0x070C) +#define BOLERO_CDC_VA_TX6_TX_PATH_SEC0 (VA_START_OFFSET + 0x0710) +#define BOLERO_CDC_VA_TX6_TX_PATH_SEC1 (VA_START_OFFSET + 0x0714) +#define BOLERO_CDC_VA_TX6_TX_PATH_SEC2 (VA_START_OFFSET + 0x0718) +#define BOLERO_CDC_VA_TX6_TX_PATH_SEC3 (VA_START_OFFSET + 0x071C) +#define BOLERO_CDC_VA_TX6_TX_PATH_SEC4 (VA_START_OFFSET + 0x0720) +#define BOLERO_CDC_VA_TX6_TX_PATH_SEC5 (VA_START_OFFSET + 0x0724) +#define BOLERO_CDC_VA_TX6_TX_PATH_SEC6 (VA_START_OFFSET + 0x0728) +#define BOLERO_CDC_VA_TX7_TX_PATH_CTL (VA_START_OFFSET + 0x0780) +#define BOLERO_CDC_VA_TX7_TX_PATH_CFG0 (VA_START_OFFSET + 0x0784) +#define BOLERO_CDC_VA_TX7_TX_PATH_CFG1 (VA_START_OFFSET + 0x0788) +#define BOLERO_CDC_VA_TX7_TX_VOL_CTL (VA_START_OFFSET + 0x078C) +#define BOLERO_CDC_VA_TX7_TX_PATH_SEC0 (VA_START_OFFSET + 0x0790) +#define BOLERO_CDC_VA_TX7_TX_PATH_SEC1 (VA_START_OFFSET + 0x0794) +#define BOLERO_CDC_VA_TX7_TX_PATH_SEC2 (VA_START_OFFSET + 0x0798) +#define BOLERO_CDC_VA_TX7_TX_PATH_SEC3 (VA_START_OFFSET + 0x079C) +#define BOLERO_CDC_VA_TX7_TX_PATH_SEC4 (VA_START_OFFSET + 0x07A0) +#define BOLERO_CDC_VA_TX7_TX_PATH_SEC5 (VA_START_OFFSET + 0x07A4) +#define BOLERO_CDC_VA_TX7_TX_PATH_SEC6 (VA_START_OFFSET + 0x07A8) +#define VA_MAX_OFFSET (VA_START_OFFSET + 0x07A8) + +#define BOLERO_CDC_VA_MACRO_MAX 0x1EB /* 7A8/4 = 1EA + 1 = 1EB */ + +#define BOLERO_CDC_MAX_REGISTER VA_MAX_OFFSET + +#define BOLERO_REG(reg) (((reg) & 0x0FFF)/4) + +#endif diff --git a/asoc/codecs/bolero/bolero_cdc_regmap.c b/asoc/codecs/bolero/bolero_cdc_regmap.c new file mode 100644 index 000000000000..ece2f779f531 --- /dev/null +++ b/asoc/codecs/bolero/bolero_cdc_regmap.c @@ -0,0 +1,811 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "bolero_cdc.h" +#include "internal.h" + +static const struct reg_default bolero_defaults[] = { + /* TX Macro */ + { BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, 0x00 }, + { BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00 }, + { BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, 0x00}, + { BOLERO_CDC_TX_TOP_CSR_TOP_CFG0, 0x00}, + { BOLERO_CDC_TX_TOP_CSR_ANC_CFG, 0x00}, + { BOLERO_CDC_TX_TOP_CSR_SWR_CTRL, 0x00}, + { BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK, 0x00}, + { BOLERO_CDC_TX_TOP_CSR_DEBUG_BUS, 0x00}, + { BOLERO_CDC_TX_TOP_CSR_DEBUG_EN, 0x00}, + { BOLERO_CDC_TX_TOP_CSR_TX_I2S_CTL, 0x0C}, + { BOLERO_CDC_TX_TOP_CSR_I2S_CLK, 0x00}, + { BOLERO_CDC_TX_TOP_CSR_I2S_RESET, 0x00}, + { BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL, 0x00}, + { BOLERO_CDC_TX_TOP_CSR_SWR_DMIC1_CTL, 0x00}, + { BOLERO_CDC_TX_TOP_CSR_SWR_DMIC2_CTL, 0x00}, + { BOLERO_CDC_TX_TOP_CSR_SWR_DMIC3_CTL, 0x00}, + { BOLERO_CDC_TX_TOP_CSR_SWR_AMIC0_CTL, 0x00}, + { BOLERO_CDC_TX_TOP_CSR_SWR_AMIC1_CTL, 0x00}, + { BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0x00}, + { BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0x00}, + { BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0x00}, + { BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0x00}, + { BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0x00}, + { BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0x00}, + { BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0x00}, + { BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0x00}, + { BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0x00}, + { BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG1, 0x00}, + { BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0x00}, + { BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG1, 0x00}, + { BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0x00}, + { BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG1, 0x00}, + { BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0x00}, + { BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG1, 0x00}, + { BOLERO_CDC_TX_ANC0_CLK_RESET_CTL, 0x00}, + { BOLERO_CDC_TX_ANC0_MODE_1_CTL, 0x00}, + { BOLERO_CDC_TX_ANC0_MODE_2_CTL, 0x00}, + { BOLERO_CDC_TX_ANC0_FF_SHIFT, 0x00}, + { BOLERO_CDC_TX_ANC0_FB_SHIFT, 0x00}, + { BOLERO_CDC_TX_ANC0_LPF_FF_A_CTL, 0x00}, + { BOLERO_CDC_TX_ANC0_LPF_FF_B_CTL, 0x00}, + { BOLERO_CDC_TX_ANC0_LPF_FB_CTL, 0x00}, + { BOLERO_CDC_TX_ANC0_SMLPF_CTL, 0x00}, + { BOLERO_CDC_TX_ANC0_DCFLT_SHIFT_CTL, 0x00}, + { BOLERO_CDC_TX_ANC0_IIR_ADAPT_CTL, 0x00}, + { BOLERO_CDC_TX_ANC0_IIR_COEFF_1_CTL, 0x00}, + { BOLERO_CDC_TX_ANC0_IIR_COEFF_2_CTL, 0x00}, + { BOLERO_CDC_TX_ANC0_FF_A_GAIN_CTL, 0x00}, + { BOLERO_CDC_TX_ANC0_FF_B_GAIN_CTL, 0x00}, + { BOLERO_CDC_TX_ANC0_FB_GAIN_CTL, 0x00}, + { BOLERO_CDC_TX0_TX_PATH_CTL, 0x04}, + { BOLERO_CDC_TX0_TX_PATH_CFG0, 0x10}, + { BOLERO_CDC_TX0_TX_PATH_CFG1, 0x0B}, + { BOLERO_CDC_TX0_TX_VOL_CTL, 0x00}, + { BOLERO_CDC_TX0_TX_PATH_SEC0, 0x00}, + { BOLERO_CDC_TX0_TX_PATH_SEC1, 0x00}, + { BOLERO_CDC_TX0_TX_PATH_SEC2, 0x01}, + { BOLERO_CDC_TX0_TX_PATH_SEC3, 0x3C}, + { BOLERO_CDC_TX0_TX_PATH_SEC4, 0x20}, + { BOLERO_CDC_TX0_TX_PATH_SEC5, 0x00}, + { BOLERO_CDC_TX0_TX_PATH_SEC6, 0x00}, + { BOLERO_CDC_TX0_TX_PATH_SEC7, 0x25}, + { BOLERO_CDC_TX1_TX_PATH_CTL, 0x04}, + { BOLERO_CDC_TX1_TX_PATH_CFG0, 0x10}, + { BOLERO_CDC_TX1_TX_PATH_CFG1, 0x0B}, + { BOLERO_CDC_TX1_TX_VOL_CTL, 0x00}, + { BOLERO_CDC_TX1_TX_PATH_SEC0, 0x00}, + { BOLERO_CDC_TX1_TX_PATH_SEC1, 0x00}, + { BOLERO_CDC_TX1_TX_PATH_SEC2, 0x01}, + { BOLERO_CDC_TX1_TX_PATH_SEC3, 0x3C}, + { BOLERO_CDC_TX1_TX_PATH_SEC4, 0x20}, + { BOLERO_CDC_TX1_TX_PATH_SEC5, 0x00}, + { BOLERO_CDC_TX1_TX_PATH_SEC6, 0x00}, + { BOLERO_CDC_TX2_TX_PATH_CTL, 0x04}, + { BOLERO_CDC_TX2_TX_PATH_CFG0, 0x10}, + { BOLERO_CDC_TX2_TX_PATH_CFG1, 0x0B}, + { BOLERO_CDC_TX2_TX_VOL_CTL, 0x00}, + { BOLERO_CDC_TX2_TX_PATH_SEC0, 0x00}, + { BOLERO_CDC_TX2_TX_PATH_SEC1, 0x00}, + { BOLERO_CDC_TX2_TX_PATH_SEC2, 0x01}, + { BOLERO_CDC_TX2_TX_PATH_SEC3, 0x3C}, + { BOLERO_CDC_TX2_TX_PATH_SEC4, 0x20}, + { BOLERO_CDC_TX2_TX_PATH_SEC5, 0x00}, + { BOLERO_CDC_TX2_TX_PATH_SEC6, 0x00}, + { BOLERO_CDC_TX3_TX_PATH_CTL, 0x04}, + { BOLERO_CDC_TX3_TX_PATH_CFG0, 0x10}, + { BOLERO_CDC_TX3_TX_PATH_CFG1, 0x0B}, + { BOLERO_CDC_TX3_TX_VOL_CTL, 0x00}, + { BOLERO_CDC_TX3_TX_PATH_SEC0, 0x00}, + { BOLERO_CDC_TX3_TX_PATH_SEC1, 0x00}, + { BOLERO_CDC_TX3_TX_PATH_SEC2, 0x01}, + { BOLERO_CDC_TX3_TX_PATH_SEC3, 0x3C}, + { BOLERO_CDC_TX3_TX_PATH_SEC4, 0x20}, + { BOLERO_CDC_TX3_TX_PATH_SEC5, 0x00}, + { BOLERO_CDC_TX3_TX_PATH_SEC6, 0x00}, + { BOLERO_CDC_TX4_TX_PATH_CTL, 0x04}, + { BOLERO_CDC_TX4_TX_PATH_CFG0, 0x10}, + { BOLERO_CDC_TX4_TX_PATH_CFG1, 0x0B}, + { BOLERO_CDC_TX4_TX_VOL_CTL, 0x00}, + { BOLERO_CDC_TX4_TX_PATH_SEC0, 0x00}, + { BOLERO_CDC_TX4_TX_PATH_SEC1, 0x00}, + { BOLERO_CDC_TX4_TX_PATH_SEC2, 0x01}, + { BOLERO_CDC_TX4_TX_PATH_SEC3, 0x3C}, + { BOLERO_CDC_TX4_TX_PATH_SEC4, 0x20}, + { BOLERO_CDC_TX4_TX_PATH_SEC5, 0x00}, + { BOLERO_CDC_TX4_TX_PATH_SEC6, 0x00}, + { BOLERO_CDC_TX5_TX_PATH_CTL, 0x04}, + { BOLERO_CDC_TX5_TX_PATH_CFG0, 0x10}, + { BOLERO_CDC_TX5_TX_PATH_CFG1, 0x0B}, + { BOLERO_CDC_TX5_TX_VOL_CTL, 0x00}, + { BOLERO_CDC_TX5_TX_PATH_SEC0, 0x00}, + { BOLERO_CDC_TX5_TX_PATH_SEC1, 0x00}, + { BOLERO_CDC_TX5_TX_PATH_SEC2, 0x01}, + { BOLERO_CDC_TX5_TX_PATH_SEC3, 0x3C}, + { BOLERO_CDC_TX5_TX_PATH_SEC4, 0x20}, + { BOLERO_CDC_TX5_TX_PATH_SEC5, 0x00}, + { BOLERO_CDC_TX5_TX_PATH_SEC6, 0x00}, + { BOLERO_CDC_TX6_TX_PATH_CTL, 0x04}, + { BOLERO_CDC_TX6_TX_PATH_CFG0, 0x10}, + { BOLERO_CDC_TX6_TX_PATH_CFG1, 0x0B}, + { BOLERO_CDC_TX6_TX_VOL_CTL, 0x00}, + { BOLERO_CDC_TX6_TX_PATH_SEC0, 0x00}, + { BOLERO_CDC_TX6_TX_PATH_SEC1, 0x00}, + { BOLERO_CDC_TX6_TX_PATH_SEC2, 0x01}, + { BOLERO_CDC_TX6_TX_PATH_SEC3, 0x3C}, + { BOLERO_CDC_TX6_TX_PATH_SEC4, 0x20}, + { BOLERO_CDC_TX6_TX_PATH_SEC5, 0x00}, + { BOLERO_CDC_TX6_TX_PATH_SEC6, 0x00}, + { BOLERO_CDC_TX7_TX_PATH_CTL, 0x04}, + { BOLERO_CDC_TX7_TX_PATH_CFG0, 0x10}, + { BOLERO_CDC_TX7_TX_PATH_CFG1, 0x0B}, + { BOLERO_CDC_TX7_TX_VOL_CTL, 0x00}, + { BOLERO_CDC_TX7_TX_PATH_SEC0, 0x00}, + { BOLERO_CDC_TX7_TX_PATH_SEC1, 0x00}, + { BOLERO_CDC_TX7_TX_PATH_SEC2, 0x01}, + { BOLERO_CDC_TX7_TX_PATH_SEC3, 0x3C}, + { BOLERO_CDC_TX7_TX_PATH_SEC4, 0x20}, + { BOLERO_CDC_TX7_TX_PATH_SEC5, 0x00}, + { BOLERO_CDC_TX7_TX_PATH_SEC6, 0x00}, + + /* RX Macro */ + { BOLERO_CDC_RX_TOP_TOP_CFG0, 0x00}, + { BOLERO_CDC_RX_TOP_SWR_CTRL, 0x00}, + { BOLERO_CDC_RX_TOP_DEBUG, 0x00}, + { BOLERO_CDC_RX_TOP_DEBUG_BUS, 0x00}, + { BOLERO_CDC_RX_TOP_DEBUG_EN0, 0x00}, + { BOLERO_CDC_RX_TOP_DEBUG_EN1, 0x00}, + { BOLERO_CDC_RX_TOP_DEBUG_EN2, 0x00}, + { BOLERO_CDC_RX_TOP_HPHL_COMP_WR_LSB, 0x00}, + { BOLERO_CDC_RX_TOP_HPHL_COMP_WR_MSB, 0x00}, + { BOLERO_CDC_RX_TOP_HPHL_COMP_LUT, 0x00}, + { BOLERO_CDC_RX_TOP_HPHL_COMP_RD_LSB, 0x00}, + { BOLERO_CDC_RX_TOP_HPHL_COMP_RD_MSB, 0x00}, + { BOLERO_CDC_RX_TOP_HPHR_COMP_WR_LSB, 0x00}, + { BOLERO_CDC_RX_TOP_HPHR_COMP_WR_MSB, 0x00}, + { BOLERO_CDC_RX_TOP_HPHR_COMP_LUT, 0x00}, + { BOLERO_CDC_RX_TOP_HPHR_COMP_RD_LSB, 0x00}, + { BOLERO_CDC_RX_TOP_HPHR_COMP_RD_MSB, 0x00}, + { BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG0, 0x11}, + { BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG1, 0x20}, + { BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG2, 0x00}, + { BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG3, 0x00}, + { BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG0, 0x11}, + { BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG1, 0x20}, + { BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG2, 0x00}, + { BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG3, 0x00}, + { BOLERO_CDC_RX_TOP_RX_I2S_CTL, 0x0C}, + { BOLERO_CDC_RX_TOP_TX_I2S2_CTL, 0x0C}, + { BOLERO_CDC_RX_TOP_I2S_CLK, 0x0C}, + { BOLERO_CDC_RX_TOP_I2S_RESET, 0x00}, + { BOLERO_CDC_RX_TOP_I2S_MUX, 0x00}, + { BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, 0x00}, + { BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00}, + { BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, 0x00}, + { BOLERO_CDC_RX_CLK_RST_CTRL_DSD_CONTROL, 0x00}, + { BOLERO_CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL, 0x08}, + { BOLERO_CDC_RX_SOFTCLIP_CRC, 0x00}, + { BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x38}, + { BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0, 0x00}, + { BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1, 0x00}, + { BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0, 0x00}, + { BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1, 0x00}, + { BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG0, 0x00}, + { BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG1, 0x00}, + { BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4, 0x00}, + { BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5, 0x00}, + { BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0x00}, + { BOLERO_CDC_RX_CLSH_CRC, 0x00}, + { BOLERO_CDC_RX_CLSH_DLY_CTRL, 0x03}, + { BOLERO_CDC_RX_CLSH_DECAY_CTRL, 0x02}, + { BOLERO_CDC_RX_CLSH_HPH_V_PA, 0x1C}, + { BOLERO_CDC_RX_CLSH_EAR_V_PA, 0x39}, + { BOLERO_CDC_RX_CLSH_HPH_V_HD, 0x0C}, + { BOLERO_CDC_RX_CLSH_EAR_V_HD, 0x0C}, + { BOLERO_CDC_RX_CLSH_K1_MSB, 0x01}, + { BOLERO_CDC_RX_CLSH_K1_LSB, 0x00}, + { BOLERO_CDC_RX_CLSH_K2_MSB, 0x00}, + { BOLERO_CDC_RX_CLSH_K2_LSB, 0x80}, + { BOLERO_CDC_RX_CLSH_IDLE_CTRL, 0x00}, + { BOLERO_CDC_RX_CLSH_IDLE_HPH, 0x00}, + { BOLERO_CDC_RX_CLSH_IDLE_EAR, 0x00}, + { BOLERO_CDC_RX_CLSH_TEST0, 0x07}, + { BOLERO_CDC_RX_CLSH_TEST1, 0x00}, + { BOLERO_CDC_RX_CLSH_OVR_VREF, 0x00}, + { BOLERO_CDC_RX_CLSH_CLSG_CTL, 0x02}, + { BOLERO_CDC_RX_CLSH_CLSG_CFG1, 0x9A}, + { BOLERO_CDC_RX_CLSH_CLSG_CFG2, 0x10}, + { BOLERO_CDC_RX_BCL_VBAT_PATH_CTL, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_CFG, 0x10}, + { BOLERO_CDC_RX_BCL_VBAT_ADC_CAL1, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_ADC_CAL2, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_ADC_CAL3, 0x04}, + { BOLERO_CDC_RX_BCL_VBAT_PK_EST1, 0xE0}, + { BOLERO_CDC_RX_BCL_VBAT_PK_EST2, 0x01}, + { BOLERO_CDC_RX_BCL_VBAT_PK_EST3, 0x40}, + { BOLERO_CDC_RX_BCL_VBAT_RF_PROC1, 0x2A}, + { BOLERO_CDC_RX_BCL_VBAT_RF_PROC1, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_TAC1, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_TAC2, 0x18}, + { BOLERO_CDC_RX_BCL_VBAT_TAC3, 0x18}, + { BOLERO_CDC_RX_BCL_VBAT_TAC4, 0x03}, + { BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD1, 0x01}, + { BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD2, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD3, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD4, 0x64}, + { BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD5, 0x01}, + { BOLERO_CDC_RX_BCL_VBAT_DEBUG1, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD_MON, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_GAIN_MON_VAL, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_BAN, 0x0C}, + { BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2, 0x77}, + { BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3, 0x01}, + { BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5, 0x4B}, + { BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7, 0x01}, + { BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_ATTN1, 0x04}, + { BOLERO_CDC_RX_BCL_VBAT_ATTN2, 0x08}, + { BOLERO_CDC_RX_BCL_VBAT_ATTN3, 0x0C}, + { BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1, 0xE0}, + { BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL2, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG2, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG3, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG4, 0x00}, + { BOLERO_CDC_RX_BCL_VBAT_DECODE_ST, 0x00}, + { BOLERO_CDC_RX_INTR_CTRL_CFG, 0x00}, + { BOLERO_CDC_RX_INTR_CTRL_CLR_COMMIT, 0x00}, + { BOLERO_CDC_RX_INTR_CTRL_PIN1_MASK0, 0xFF}, + { BOLERO_CDC_RX_INTR_CTRL_PIN1_STATUS0, 0x00}, + { BOLERO_CDC_RX_INTR_CTRL_PIN1_CLEAR0, 0x00}, + { BOLERO_CDC_RX_INTR_CTRL_PIN2_MASK0, 0xFF}, + { BOLERO_CDC_RX_INTR_CTRL_PIN2_STATUS0, 0x00}, + { BOLERO_CDC_RX_INTR_CTRL_PIN2_CLEAR0, 0x00}, + { BOLERO_CDC_RX_INTR_CTRL_LEVEL0, 0x00}, + { BOLERO_CDC_RX_INTR_CTRL_BYPASS0, 0x00}, + { BOLERO_CDC_RX_INTR_CTRL_SET0, 0x00}, + { BOLERO_CDC_RX_RX0_RX_PATH_CTL, 0x04}, + { BOLERO_CDC_RX_RX0_RX_PATH_CFG0, 0x00}, + { BOLERO_CDC_RX_RX0_RX_PATH_CFG1, 0x64}, + { BOLERO_CDC_RX_RX0_RX_PATH_CFG2, 0x8F}, + { BOLERO_CDC_RX_RX0_RX_PATH_CFG3, 0x00}, + { BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0x00}, + { BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL, 0x04}, + { BOLERO_CDC_RX_RX0_RX_PATH_MIX_CFG, 0x7E}, + { BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0x00}, + { BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x08}, + { BOLERO_CDC_RX_RX0_RX_PATH_SEC2, 0x00}, + { BOLERO_CDC_RX_RX0_RX_PATH_SEC3, 0x00}, + { BOLERO_CDC_RX_RX0_RX_PATH_SEC4, 0x00}, + { BOLERO_CDC_RX_RX0_RX_PATH_SEC7, 0x00}, + { BOLERO_CDC_RX_RX0_RX_PATH_MIX_SEC0, 0x08}, + { BOLERO_CDC_RX_RX0_RX_PATH_MIX_SEC1, 0x00}, + { BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL, 0x08}, + { BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA1, 0x00}, + { BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA2, 0x00}, + { BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA3, 0x00}, + { BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA4, 0x55}, + { BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA5, 0x55}, + { BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA6, 0x55}, + { BOLERO_CDC_RX_RX1_RX_PATH_CTL, 0x04}, + { BOLERO_CDC_RX_RX1_RX_PATH_CFG0, 0x00}, + { BOLERO_CDC_RX_RX1_RX_PATH_CFG1, 0x64}, + { BOLERO_CDC_RX_RX1_RX_PATH_CFG2, 0x8F}, + { BOLERO_CDC_RX_RX1_RX_PATH_CFG3, 0x00}, + { BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0x00}, + { BOLERO_CDC_RX_RX1_RX_PATH_MIX_CTL, 0x04}, + { BOLERO_CDC_RX_RX1_RX_PATH_MIX_CFG, 0x7E}, + { BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0x00}, + { BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x08}, + { BOLERO_CDC_RX_RX1_RX_PATH_SEC2, 0x00}, + { BOLERO_CDC_RX_RX1_RX_PATH_SEC3, 0x00}, + { BOLERO_CDC_RX_RX1_RX_PATH_SEC4, 0x00}, + { BOLERO_CDC_RX_RX1_RX_PATH_SEC7, 0x00}, + { BOLERO_CDC_RX_RX1_RX_PATH_MIX_SEC0, 0x08}, + { BOLERO_CDC_RX_RX1_RX_PATH_MIX_SEC1, 0x00}, + { BOLERO_CDC_RX_RX1_RX_PATH_DSM_CTL, 0x08}, + { BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA1, 0x00}, + { BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA2, 0x00}, + { BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA3, 0x00}, + { BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA4, 0x55}, + { BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA5, 0x55}, + { BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA6, 0x55}, + { BOLERO_CDC_RX_RX2_RX_PATH_CTL, 0x04}, + { BOLERO_CDC_RX_RX2_RX_PATH_CFG0, 0x00}, + { BOLERO_CDC_RX_RX2_RX_PATH_CFG1, 0x64}, + { BOLERO_CDC_RX_RX2_RX_PATH_CFG2, 0x8F}, + { BOLERO_CDC_RX_RX2_RX_PATH_CFG3, 0x00}, + { BOLERO_CDC_RX_RX2_RX_VOL_CTL, 0x00}, + { BOLERO_CDC_RX_RX2_RX_PATH_MIX_CTL, 0x04}, + { BOLERO_CDC_RX_RX2_RX_PATH_MIX_CFG, 0x7E}, + { BOLERO_CDC_RX_RX2_RX_VOL_MIX_CTL, 0x00}, + { BOLERO_CDC_RX_RX2_RX_PATH_SEC0, 0x04}, + { BOLERO_CDC_RX_RX2_RX_PATH_SEC1, 0x08}, + { BOLERO_CDC_RX_RX2_RX_PATH_SEC2, 0x00}, + { BOLERO_CDC_RX_RX2_RX_PATH_SEC3, 0x00}, + { BOLERO_CDC_RX_RX2_RX_PATH_SEC4, 0x00}, + { BOLERO_CDC_RX_RX2_RX_PATH_SEC5, 0x00}, + { BOLERO_CDC_RX_RX2_RX_PATH_SEC6, 0x00}, + { BOLERO_CDC_RX_RX2_RX_PATH_SEC7, 0x00}, + { BOLERO_CDC_RX_RX2_RX_PATH_MIX_SEC0, 0x08}, + { BOLERO_CDC_RX_RX2_RX_PATH_MIX_SEC1, 0x00}, + { BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL, 0x00}, + { BOLERO_CDC_RX_IDLE_DETECT_PATH_CTL, 0x00}, + { BOLERO_CDC_RX_IDLE_DETECT_CFG0, 0x07}, + { BOLERO_CDC_RX_IDLE_DETECT_CFG1, 0x3C}, + { BOLERO_CDC_RX_IDLE_DETECT_CFG2, 0x00}, + { BOLERO_CDC_RX_IDLE_DETECT_CFG3, 0x00}, + { BOLERO_CDC_RX_COMPANDER0_CTL0, 0x60}, + { BOLERO_CDC_RX_COMPANDER0_CTL1, 0xDB}, + { BOLERO_CDC_RX_COMPANDER0_CTL2, 0xFF}, + { BOLERO_CDC_RX_COMPANDER0_CTL3, 0x35}, + { BOLERO_CDC_RX_COMPANDER0_CTL4, 0xFF}, + { BOLERO_CDC_RX_COMPANDER0_CTL5, 0x00}, + { BOLERO_CDC_RX_COMPANDER0_CTL6, 0x01}, + { BOLERO_CDC_RX_COMPANDER0_CTL7, 0x28}, + { BOLERO_CDC_RX_COMPANDER1_CTL0, 0x60}, + { BOLERO_CDC_RX_COMPANDER1_CTL1, 0xDB}, + { BOLERO_CDC_RX_COMPANDER1_CTL2, 0xFF}, + { BOLERO_CDC_RX_COMPANDER1_CTL3, 0x35}, + { BOLERO_CDC_RX_COMPANDER1_CTL4, 0xFF}, + { BOLERO_CDC_RX_COMPANDER1_CTL5, 0x00}, + { BOLERO_CDC_RX_COMPANDER1_CTL6, 0x01}, + { BOLERO_CDC_RX_COMPANDER1_CTL7, 0x28}, + { BOLERO_CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR0_IIR_CTL, 0x40}, + { BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR1_IIR_CTL, 0x40}, + { BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL, 0x00}, + { BOLERO_CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL, 0x00}, + { BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0, 0x00}, + { BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1, 0x00}, + { BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2, 0x00}, + { BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3, 0x00}, + { BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0, 0x00}, + { BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1, 0x00}, + { BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2, 0x00}, + { BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3, 0x00}, + { BOLERO_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL, 0x04}, + { BOLERO_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1, 0x00}, + { BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL, 0x04}, + { BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1, 0x00}, + { BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL, 0x00}, + { BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0, 0x01}, + { BOLERO_CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL, 0x00}, + { BOLERO_CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0, 0x01}, + { BOLERO_CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL, 0x00}, + { BOLERO_CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0, 0x01}, + { BOLERO_CDC_RX_EC_ASRC0_CLK_RST_CTL, 0x00}, + { BOLERO_CDC_RX_EC_ASRC0_CTL0, 0x00}, + { BOLERO_CDC_RX_EC_ASRC0_CTL1, 0x00}, + { BOLERO_CDC_RX_EC_ASRC0_FIFO_CTL, 0xA8}, + { BOLERO_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00}, + { BOLERO_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00}, + { BOLERO_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00}, + { BOLERO_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00}, + { BOLERO_CDC_RX_EC_ASRC0_STATUS_FIFO, 0x00}, + { BOLERO_CDC_RX_EC_ASRC1_CLK_RST_CTL, 0x00}, + { BOLERO_CDC_RX_EC_ASRC1_CTL0, 0x00}, + { BOLERO_CDC_RX_EC_ASRC1_CTL1, 0x00}, + { BOLERO_CDC_RX_EC_ASRC1_FIFO_CTL, 0xA8}, + { BOLERO_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00}, + { BOLERO_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00}, + { BOLERO_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00}, + { BOLERO_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00}, + { BOLERO_CDC_RX_EC_ASRC1_STATUS_FIFO, 0x00}, + { BOLERO_CDC_RX_EC_ASRC2_CLK_RST_CTL, 0x00}, + { BOLERO_CDC_RX_EC_ASRC2_CTL0, 0x00}, + { BOLERO_CDC_RX_EC_ASRC2_CTL1, 0x00}, + { BOLERO_CDC_RX_EC_ASRC2_FIFO_CTL, 0xA8}, + { BOLERO_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB, 0x00}, + { BOLERO_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB, 0x00}, + { BOLERO_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB, 0x00}, + { BOLERO_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB, 0x00}, + { BOLERO_CDC_RX_EC_ASRC2_STATUS_FIFO, 0x00}, + { BOLERO_CDC_RX_DSD0_PATH_CTL, 0x00}, + { BOLERO_CDC_RX_DSD0_CFG0, 0x00}, + { BOLERO_CDC_RX_DSD0_CFG1, 0x62}, + { BOLERO_CDC_RX_DSD0_CFG2, 0x96}, + { BOLERO_CDC_RX_DSD1_PATH_CTL, 0x00}, + { BOLERO_CDC_RX_DSD1_CFG0, 0x00}, + { BOLERO_CDC_RX_DSD1_CFG1, 0x62}, + { BOLERO_CDC_RX_DSD1_CFG2, 0x96}, + + /* WSA Macro */ + { BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL, 0x00}, + { BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00}, + { BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 0x00}, + { BOLERO_CDC_WSA_TOP_TOP_CFG0, 0x00}, + { BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x00}, + { BOLERO_CDC_WSA_TOP_FREQ_MCLK, 0x00}, + { BOLERO_CDC_WSA_TOP_DEBUG_BUS_SEL, 0x00}, + { BOLERO_CDC_WSA_TOP_DEBUG_EN0, 0x00}, + { BOLERO_CDC_WSA_TOP_DEBUG_EN1, 0x00}, + { BOLERO_CDC_WSA_TOP_DEBUG_DSM_LB, 0x88}, + { BOLERO_CDC_WSA_TOP_RX_I2S_CTL, 0x0C}, + { BOLERO_CDC_WSA_TOP_TX_I2S_CTL, 0x0C}, + { BOLERO_CDC_WSA_TOP_I2S_CLK, 0x02}, + { BOLERO_CDC_WSA_TOP_I2S_RESET, 0x00}, + { BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0, 0x00}, + { BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1, 0x00}, + { BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0, 0x00}, + { BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1, 0x00}, + { BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0, 0x00}, + { BOLERO_CDC_WSA_RX_INP_MUX_RX_EC_CFG0, 0x00}, + { BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x10}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL1, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL2, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL3, 0x04}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST1, 0xE0}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST2, 0x01}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST3, 0x40}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_RF_PROC1, 0x2A}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_RF_PROC2, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC1, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC2, 0x18}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC3, 0x18}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC4, 0x03}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD1, 0x01}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD2, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD3, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD4, 0x64}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD5, 0x01}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_DEBUG1, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD_MON, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_MON_VAL, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_BAN, 0x0C}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2, 0x77}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3, 0x01}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5, 0x4B}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7, 0x01}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN1, 0x04}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN2, 0x08}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN3, 0x0C}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0xE0}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL2, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4, 0x00}, + { BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_ST, 0x00}, + { BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, 0x02}, + { BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x00}, + { BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL, 0x02}, + { BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x00}, + { BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, 0x02}, + { BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x00}, + { BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL, 0x02}, + { BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x00}, + { BOLERO_CDC_WSA_INTR_CTRL_CFG, 0x00}, + { BOLERO_CDC_WSA_INTR_CTRL_CLR_COMMIT, 0x00}, + { BOLERO_CDC_WSA_INTR_CTRL_PIN1_MASK0, 0xFF}, + { BOLERO_CDC_WSA_INTR_CTRL_PIN1_STATUS0, 0x00}, + { BOLERO_CDC_WSA_INTR_CTRL_PIN1_CLEAR0, 0x00}, + { BOLERO_CDC_WSA_INTR_CTRL_PIN2_MASK0, 0xFF}, + { BOLERO_CDC_WSA_INTR_CTRL_PIN2_STATUS0, 0x00}, + { BOLERO_CDC_WSA_INTR_CTRL_PIN2_CLEAR0, 0x00}, + { BOLERO_CDC_WSA_INTR_CTRL_LEVEL0, 0x00}, + { BOLERO_CDC_WSA_INTR_CTRL_BYPASS0, 0x00}, + { BOLERO_CDC_WSA_INTR_CTRL_SET0, 0x00}, + { BOLERO_CDC_WSA_RX0_RX_PATH_CTL, 0x04}, + { BOLERO_CDC_WSA_RX0_RX_PATH_CFG0, 0x00}, + { BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 0x64}, + { BOLERO_CDC_WSA_RX0_RX_PATH_CFG2, 0x8F}, + { BOLERO_CDC_WSA_RX0_RX_PATH_CFG3, 0x00}, + { BOLERO_CDC_WSA_RX0_RX_VOL_CTL, 0x00}, + { BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL, 0x04}, + { BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x7E}, + { BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL, 0x00}, + { BOLERO_CDC_WSA_RX0_RX_PATH_SEC0, 0x04}, + { BOLERO_CDC_WSA_RX0_RX_PATH_SEC1, 0x08}, + { BOLERO_CDC_WSA_RX0_RX_PATH_SEC2, 0x00}, + { BOLERO_CDC_WSA_RX0_RX_PATH_SEC3, 0x00}, + { BOLERO_CDC_WSA_RX0_RX_PATH_SEC5, 0x00}, + { BOLERO_CDC_WSA_RX0_RX_PATH_SEC6, 0x00}, + { BOLERO_CDC_WSA_RX0_RX_PATH_SEC7, 0x00}, + { BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0, 0x08}, + { BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC1, 0x00}, + { BOLERO_CDC_WSA_RX0_RX_PATH_DSMDEM_CTL, 0x00}, + { BOLERO_CDC_WSA_RX1_RX_PATH_CFG0, 0x00}, + { BOLERO_CDC_WSA_RX1_RX_PATH_CFG1, 0x64}, + { BOLERO_CDC_WSA_RX1_RX_PATH_CFG2, 0x8F}, + { BOLERO_CDC_WSA_RX1_RX_PATH_CFG3, 0x00}, + { BOLERO_CDC_WSA_RX1_RX_VOL_CTL, 0x00}, + { BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL, 0x04}, + { BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x7E}, + { BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL, 0x00}, + { BOLERO_CDC_WSA_RX1_RX_PATH_SEC0, 0x04}, + { BOLERO_CDC_WSA_RX1_RX_PATH_SEC1, 0x08}, + { BOLERO_CDC_WSA_RX1_RX_PATH_SEC2, 0x00}, + { BOLERO_CDC_WSA_RX1_RX_PATH_SEC3, 0x00}, + { BOLERO_CDC_WSA_RX1_RX_PATH_SEC5, 0x00}, + { BOLERO_CDC_WSA_RX1_RX_PATH_SEC6, 0x00}, + { BOLERO_CDC_WSA_RX1_RX_PATH_SEC7, 0x00}, + { BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0, 0x08}, + { BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC1, 0x00}, + { BOLERO_CDC_WSA_RX1_RX_PATH_DSMDEM_CTL, 0x00}, + { BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL, 0x00}, + { BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0xD0}, + { BOLERO_CDC_WSA_BOOST0_BOOST_CFG1, 0x89}, + { BOLERO_CDC_WSA_BOOST0_BOOST_CFG2, 0x04}, + { BOLERO_CDC_WSA_BOOST1_BOOST_PATH_CTL, 0x00}, + { BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0xD0}, + { BOLERO_CDC_WSA_BOOST1_BOOST_CFG1, 0x89}, + { BOLERO_CDC_WSA_BOOST1_BOOST_CFG2, 0x04}, + { BOLERO_CDC_WSA_COMPANDER0_CTL0, 0x60}, + { BOLERO_CDC_WSA_COMPANDER0_CTL1, 0xDB}, + { BOLERO_CDC_WSA_COMPANDER0_CTL2, 0xFF}, + { BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x35}, + { BOLERO_CDC_WSA_COMPANDER0_CTL4, 0xFF}, + { BOLERO_CDC_WSA_COMPANDER0_CTL5, 0x00}, + { BOLERO_CDC_WSA_COMPANDER0_CTL6, 0x01}, + { BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x28}, + { BOLERO_CDC_WSA_COMPANDER1_CTL0, 0x60}, + { BOLERO_CDC_WSA_COMPANDER1_CTL1, 0xDB}, + { BOLERO_CDC_WSA_COMPANDER1_CTL2, 0xFF}, + { BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x35}, + { BOLERO_CDC_WSA_COMPANDER1_CTL4, 0xFF}, + { BOLERO_CDC_WSA_COMPANDER1_CTL5, 0x00}, + { BOLERO_CDC_WSA_COMPANDER1_CTL6, 0x01}, + { BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x28}, + { BOLERO_CDC_WSA_SOFTCLIP0_CRC, 0x00}, + { BOLERO_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL, 0x38}, + { BOLERO_CDC_WSA_SOFTCLIP1_CRC, 0x00}, + { BOLERO_CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL, 0x38}, + { BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL, 0x00}, + { BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0, 0x01}, + { BOLERO_CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL, 0x00}, + { BOLERO_CDC_WSA_EC_HQ1_EC_REF_HQ_CFG0, 0x01}, + { BOLERO_CDC_WSA_SPLINE_ASRC0_CLK_RST_CTL, 0x00}, + { BOLERO_CDC_WSA_SPLINE_ASRC0_CTL0, 0x00}, + { BOLERO_CDC_WSA_SPLINE_ASRC0_CTL1, 0x00}, + { BOLERO_CDC_WSA_SPLINE_ASRC0_FIFO_CTL, 0xA8}, + { BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00}, + { BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00}, + { BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00}, + { BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00}, + { BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FIFO, 0x00}, + { BOLERO_CDC_WSA_SPLINE_ASRC1_CLK_RST_CTL, 0x00}, + { BOLERO_CDC_WSA_SPLINE_ASRC1_CTL0, 0x00}, + { BOLERO_CDC_WSA_SPLINE_ASRC1_CTL1, 0x00}, + { BOLERO_CDC_WSA_SPLINE_ASRC1_FIFO_CTL, 0xA8}, + { BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00}, + { BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00}, + { BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00}, + { BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00}, + { BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FIFO, 0x00}, + + /* VA macro */ + { BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, 0x00}, + { BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00}, + { BOLERO_CDC_VA_TOP_CSR_TOP_CFG0, 0x00}, + { BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL, 0x00}, + { BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL, 0x00}, + { BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL, 0x00}, + { BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL, 0x00}, + { BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, 0x80}, + { BOLERO_CDC_VA_TOP_CSR_DEBUG_BUS, 0x00}, + { BOLERO_CDC_VA_TOP_CSR_DEBUG_EN, 0x00}, + { BOLERO_CDC_VA_TOP_CSR_TX_I2S_CTL, 0x0C}, + { BOLERO_CDC_VA_TOP_CSR_I2S_CLK, 0x00}, + { BOLERO_CDC_VA_TOP_CSR_I2S_RESET, 0x00}, + { BOLERO_CDC_VA_TOP_CSR_CORE_ID_0, 0x00}, + { BOLERO_CDC_VA_TOP_CSR_CORE_ID_1, 0x00}, + { BOLERO_CDC_VA_TOP_CSR_CORE_ID_2, 0x00}, + { BOLERO_CDC_VA_TOP_CSR_CORE_ID_3, 0x00}, + + /* VA core */ + { BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0, 0x00}, + { BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1, 0x00}, + { BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG0, 0x00}, + { BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG1, 0x00}, + { BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG0, 0x00}, + { BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG1, 0x00}, + { BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG0, 0x00}, + { BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG1, 0x00}, + { BOLERO_CDC_VA_INP_MUX_ADC_MUX4_CFG0, 0x00}, + { BOLERO_CDC_VA_INP_MUX_ADC_MUX4_CFG1, 0x00}, + { BOLERO_CDC_VA_INP_MUX_ADC_MUX5_CFG0, 0x00}, + { BOLERO_CDC_VA_INP_MUX_ADC_MUX5_CFG1, 0x00}, + { BOLERO_CDC_VA_INP_MUX_ADC_MUX6_CFG0, 0x00}, + { BOLERO_CDC_VA_INP_MUX_ADC_MUX6_CFG1, 0x00}, + { BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG0, 0x00}, + { BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG1, 0x00}, + { BOLERO_CDC_VA_TX0_TX_PATH_CTL, 0x04}, + { BOLERO_CDC_VA_TX0_TX_PATH_CFG0, 0x10}, + { BOLERO_CDC_VA_TX0_TX_PATH_CFG1, 0x0B}, + { BOLERO_CDC_VA_TX0_TX_VOL_CTL, 0x00}, + { BOLERO_CDC_VA_TX0_TX_PATH_SEC0, 0x00}, + { BOLERO_CDC_VA_TX0_TX_PATH_SEC1, 0x00}, + { BOLERO_CDC_VA_TX0_TX_PATH_SEC2, 0x01}, + { BOLERO_CDC_VA_TX0_TX_PATH_SEC3, 0x3C}, + { BOLERO_CDC_VA_TX0_TX_PATH_SEC4, 0x20}, + { BOLERO_CDC_VA_TX0_TX_PATH_SEC5, 0x00}, + { BOLERO_CDC_VA_TX0_TX_PATH_SEC6, 0x00}, + { BOLERO_CDC_VA_TX0_TX_PATH_SEC7, 0x25}, + { BOLERO_CDC_VA_TX1_TX_PATH_CTL, 0x04}, + { BOLERO_CDC_VA_TX1_TX_PATH_CFG0, 0x10}, + { BOLERO_CDC_VA_TX1_TX_PATH_CFG1, 0x0B}, + { BOLERO_CDC_VA_TX1_TX_VOL_CTL, 0x00}, + { BOLERO_CDC_VA_TX1_TX_PATH_SEC0, 0x00}, + { BOLERO_CDC_VA_TX1_TX_PATH_SEC1, 0x00}, + { BOLERO_CDC_VA_TX1_TX_PATH_SEC2, 0x01}, + { BOLERO_CDC_VA_TX1_TX_PATH_SEC3, 0x3C}, + { BOLERO_CDC_VA_TX1_TX_PATH_SEC4, 0x20}, + { BOLERO_CDC_VA_TX1_TX_PATH_SEC5, 0x00}, + { BOLERO_CDC_VA_TX1_TX_PATH_SEC6, 0x00}, + { BOLERO_CDC_VA_TX2_TX_PATH_CTL, 0x04}, + { BOLERO_CDC_VA_TX2_TX_PATH_CFG0, 0x10}, + { BOLERO_CDC_VA_TX2_TX_PATH_CFG1, 0x0B}, + { BOLERO_CDC_VA_TX2_TX_VOL_CTL, 0x00}, + { BOLERO_CDC_VA_TX2_TX_PATH_SEC0, 0x00}, + { BOLERO_CDC_VA_TX2_TX_PATH_SEC1, 0x00}, + { BOLERO_CDC_VA_TX2_TX_PATH_SEC2, 0x01}, + { BOLERO_CDC_VA_TX2_TX_PATH_SEC3, 0x3C}, + { BOLERO_CDC_VA_TX2_TX_PATH_SEC4, 0x20}, + { BOLERO_CDC_VA_TX2_TX_PATH_SEC5, 0x00}, + { BOLERO_CDC_VA_TX2_TX_PATH_SEC6, 0x00}, + { BOLERO_CDC_VA_TX3_TX_PATH_CTL, 0x04}, + { BOLERO_CDC_VA_TX3_TX_PATH_CFG0, 0x10}, + { BOLERO_CDC_VA_TX3_TX_PATH_CFG1, 0x0B}, + { BOLERO_CDC_VA_TX3_TX_VOL_CTL, 0x00}, + { BOLERO_CDC_VA_TX3_TX_PATH_SEC0, 0x00}, + { BOLERO_CDC_VA_TX3_TX_PATH_SEC1, 0x00}, + { BOLERO_CDC_VA_TX3_TX_PATH_SEC2, 0x01}, + { BOLERO_CDC_VA_TX3_TX_PATH_SEC3, 0x3C}, + { BOLERO_CDC_VA_TX3_TX_PATH_SEC4, 0x20}, + { BOLERO_CDC_VA_TX3_TX_PATH_SEC5, 0x00}, + { BOLERO_CDC_VA_TX3_TX_PATH_SEC6, 0x00}, + { BOLERO_CDC_VA_TX4_TX_PATH_CTL, 0x04}, + { BOLERO_CDC_VA_TX4_TX_PATH_CFG0, 0x10}, + { BOLERO_CDC_VA_TX4_TX_PATH_CFG1, 0x0B}, + { BOLERO_CDC_VA_TX4_TX_VOL_CTL, 0x00}, + { BOLERO_CDC_VA_TX4_TX_PATH_SEC0, 0x00}, + { BOLERO_CDC_VA_TX4_TX_PATH_SEC1, 0x00}, + { BOLERO_CDC_VA_TX4_TX_PATH_SEC2, 0x01}, + { BOLERO_CDC_VA_TX4_TX_PATH_SEC3, 0x3C}, + { BOLERO_CDC_VA_TX4_TX_PATH_SEC4, 0x20}, + { BOLERO_CDC_VA_TX4_TX_PATH_SEC5, 0x00}, + { BOLERO_CDC_VA_TX4_TX_PATH_SEC6, 0x00}, + { BOLERO_CDC_VA_TX5_TX_PATH_CTL, 0x04}, + { BOLERO_CDC_VA_TX5_TX_PATH_CFG0, 0x10}, + { BOLERO_CDC_VA_TX5_TX_PATH_CFG1, 0x0B}, + { BOLERO_CDC_VA_TX5_TX_VOL_CTL, 0x00}, + { BOLERO_CDC_VA_TX5_TX_PATH_SEC0, 0x00}, + { BOLERO_CDC_VA_TX5_TX_PATH_SEC1, 0x00}, + { BOLERO_CDC_VA_TX5_TX_PATH_SEC2, 0x01}, + { BOLERO_CDC_VA_TX5_TX_PATH_SEC3, 0x3C}, + { BOLERO_CDC_VA_TX5_TX_PATH_SEC4, 0x20}, + { BOLERO_CDC_VA_TX5_TX_PATH_SEC5, 0x00}, + { BOLERO_CDC_VA_TX5_TX_PATH_SEC6, 0x00}, + { BOLERO_CDC_VA_TX6_TX_PATH_CTL, 0x04}, + { BOLERO_CDC_VA_TX6_TX_PATH_CFG0, 0x10}, + { BOLERO_CDC_VA_TX6_TX_PATH_CFG1, 0x0B}, + { BOLERO_CDC_VA_TX6_TX_VOL_CTL, 0x00}, + { BOLERO_CDC_VA_TX6_TX_PATH_SEC0, 0x00}, + { BOLERO_CDC_VA_TX6_TX_PATH_SEC1, 0x00}, + { BOLERO_CDC_VA_TX6_TX_PATH_SEC2, 0x01}, + { BOLERO_CDC_VA_TX6_TX_PATH_SEC3, 0x3C}, + { BOLERO_CDC_VA_TX6_TX_PATH_SEC4, 0x20}, + { BOLERO_CDC_VA_TX6_TX_PATH_SEC5, 0x00}, + { BOLERO_CDC_VA_TX6_TX_PATH_SEC6, 0x00}, + { BOLERO_CDC_VA_TX7_TX_PATH_CTL, 0x04}, + { BOLERO_CDC_VA_TX7_TX_PATH_CFG0, 0x10}, + { BOLERO_CDC_VA_TX7_TX_PATH_CFG1, 0x0B}, + { BOLERO_CDC_VA_TX7_TX_VOL_CTL, 0x00}, + { BOLERO_CDC_VA_TX7_TX_PATH_SEC0, 0x00}, + { BOLERO_CDC_VA_TX7_TX_PATH_SEC1, 0x00}, + { BOLERO_CDC_VA_TX7_TX_PATH_SEC2, 0x01}, + { BOLERO_CDC_VA_TX7_TX_PATH_SEC3, 0x3C}, + { BOLERO_CDC_VA_TX7_TX_PATH_SEC4, 0x20}, + { BOLERO_CDC_VA_TX7_TX_PATH_SEC5, 0x00}, + { BOLERO_CDC_VA_TX7_TX_PATH_SEC6, 0x00}, +}; + +static bool bolero_is_readable_register(struct device *dev, + unsigned int reg) +{ + struct bolero_priv *priv = dev_get_drvdata(dev); + u16 reg_offset; + int macro_id; + u8 *reg_tbl = NULL; + + if (!priv) + return false; + + macro_id = bolero_get_macro_id(priv->va_without_decimation, + reg); + if (macro_id < 0 || !priv->macros_supported[macro_id]) + return false; + + reg_tbl = bolero_reg_access[macro_id]; + reg_offset = reg - macro_id_base_offset[macro_id]; + + if (reg_tbl) + return (reg_tbl[reg_offset] & RD_REG); + + return false; +} + +static bool bolero_is_writeable_register(struct device *dev, + unsigned int reg) +{ + struct bolero_priv *priv = dev_get_drvdata(dev); + u16 reg_offset; + int macro_id; + const u8 *reg_tbl = NULL; + + if (!priv) + return false; + + macro_id = bolero_get_macro_id(priv->va_without_decimation, + reg); + if (macro_id < 0 || !priv->macros_supported[macro_id]) + return false; + + reg_tbl = bolero_reg_access[macro_id]; + reg_offset = reg - macro_id_base_offset[macro_id]; + + if (reg_tbl) + return (reg_tbl[reg_offset] & WR_REG); + + return false; +} + +static bool bolero_is_volatile_register(struct device *dev, + unsigned int reg) +{ + return true; +} + +const struct regmap_config bolero_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .reg_stride = 4, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = bolero_defaults, + .num_reg_defaults = ARRAY_SIZE(bolero_defaults), + .max_register = BOLERO_CDC_MAX_REGISTER, + .writeable_reg = bolero_is_writeable_register, + .volatile_reg = bolero_is_volatile_register, + .readable_reg = bolero_is_readable_register, +}; diff --git a/asoc/codecs/bolero/bolero_cdc_tables.c b/asoc/codecs/bolero/bolero_cdc_tables.c new file mode 100644 index 000000000000..f9d271c0b53f --- /dev/null +++ b/asoc/codecs/bolero/bolero_cdc_tables.c @@ -0,0 +1,768 @@ +/* + * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "bolero_cdc.h" +#include "internal.h" + +u8 bolero_tx_reg_access[BOLERO_CDC_TX_MACRO_MAX] = { + [BOLERO_REG(BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_TOP_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_ANC_CFG)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_CTRL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_DEBUG_BUS)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_DEBUG_EN)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_TX_I2S_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_I2S_CLK)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_I2S_RESET)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_DMIC1_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_DMIC2_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_DMIC3_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_AMIC0_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_AMIC1_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_CLK_RESET_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_MODE_1_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_MODE_2_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_FF_SHIFT)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_FB_SHIFT)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_LPF_FF_A_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_LPF_FF_B_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_LPF_FB_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_SMLPF_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_DCFLT_SHIFT_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_IIR_ADAPT_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_IIR_COEFF_1_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_IIR_COEFF_2_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_FF_A_GAIN_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_FF_B_GAIN_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_FB_GAIN_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC7)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX4_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX5_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX6_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX7_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_SEC6)] = RD_WR_REG, +}; + +u8 bolero_rx_reg_access[BOLERO_CDC_RX_MACRO_MAX] = { + [BOLERO_REG(BOLERO_CDC_RX_TOP_TOP_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_SWR_CTRL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_DEBUG)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_DEBUG_BUS)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_DEBUG_EN0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_DEBUG_EN1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_DEBUG_EN2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_HPHL_COMP_WR_LSB)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_HPHL_COMP_WR_MSB)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_HPHL_COMP_LUT)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_HPHL_COMP_RD_LSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_HPHL_COMP_RD_MSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_HPHR_COMP_WR_LSB)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_HPHR_COMP_WR_MSB)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_HPHR_COMP_LUT)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_HPHR_COMP_RD_LSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_HPHR_COMP_RD_MSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG2)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG2)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_RX_I2S_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_TX_I2S2_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_I2S_CLK)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_I2S_RESET)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_TOP_I2S_MUX)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLK_RST_CTRL_DSD_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SOFTCLIP_CRC)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_CRC)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_DLY_CTRL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_DECAY_CTRL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_HPH_V_PA)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_EAR_V_PA)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_HPH_V_HD)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_EAR_V_HD)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_K1_MSB)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_K1_LSB)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_K2_MSB)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_K2_LSB)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_IDLE_CTRL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_IDLE_HPH)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_IDLE_EAR)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_TEST0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_TEST1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_OVR_VREF)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_CLSG_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_CLSG_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_CLSH_CLSG_CFG2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_CFG)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_ADC_CAL1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_ADC_CAL2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_ADC_CAL3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_PK_EST1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_PK_EST2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_PK_EST3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_RF_PROC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_RF_PROC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_TAC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_TAC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_TAC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_TAC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_DEBUG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD_MON)] = WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_GAIN_MON_VAL)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BAN)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_ATTN1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_ATTN2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_ATTN3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_DECODE_ST)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_CFG)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_CLR_COMMIT)] = WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_PIN1_MASK0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_PIN1_STATUS0)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_PIN1_CLEAR0)] = WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_PIN2_MASK0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_PIN2_STATUS0)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_PIN2_CLEAR0)] = WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_LEVEL0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_BYPASS0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_SET0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_CFG2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_CFG3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_MIX_CFG)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_SEC7)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_MIX_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_MIX_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_CFG2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_CFG3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_MIX_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_MIX_CFG)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_SEC7)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_MIX_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_MIX_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_DSM_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_CFG2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_CFG3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_MIX_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_MIX_CFG)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_VOL_MIX_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_SEC7)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_MIX_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_MIX_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_IDLE_DETECT_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_IDLE_DETECT_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_IDLE_DETECT_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_IDLE_DETECT_CFG2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_IDLE_DETECT_CFG3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_COMPANDER0_CTL0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_COMPANDER0_CTL1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_COMPANDER0_CTL2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_COMPANDER0_CTL3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_COMPANDER0_CTL4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_COMPANDER0_CTL5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_COMPANDER0_CTL6)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_COMPANDER0_CTL7)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_COMPANDER1_CTL0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_COMPANDER1_CTL1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_COMPANDER1_CTL2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_COMPANDER1_CTL3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_COMPANDER1_CTL4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_COMPANDER1_CTL5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_COMPANDER1_CTL6)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_COMPANDER1_CTL7)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL)] = + RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL)] = + RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_CLK_RST_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_CTL0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_CTL1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_FIFO_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_STATUS_FIFO)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_CLK_RST_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_CTL0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_CTL1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_FIFO_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_STATUS_FIFO)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_CLK_RST_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_CTL0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_CTL1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_FIFO_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_STATUS_FIFO)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_RX_DSD0_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_DSD0_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_DSD0_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_DSD0_CFG2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_DSD1_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_DSD1_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_DSD1_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_RX_DSD1_CFG2)] = RD_WR_REG, +}; + +u8 bolero_va_reg_access[BOLERO_CDC_VA_MACRO_MAX] = { + [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TOP_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC_CFG)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DEBUG_BUS)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DEBUG_EN)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TX_I2S_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_I2S_CLK)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_I2S_RESET)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_0)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_1)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_2)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_3)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX4_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX4_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX5_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX5_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX6_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX6_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC7)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX4_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX5_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX6_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX7_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_SEC6)] = RD_WR_REG, +}; + +u8 bolero_va_top_reg_access[BOLERO_CDC_VA_MACRO_TOP_MAX] = { + [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TOP_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC_CFG)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DEBUG_BUS)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DEBUG_EN)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_0)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_1)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_2)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_3)] = RD_REG, +}; + +u8 bolero_wsa_reg_access[BOLERO_CDC_WSA_MACRO_MAX] = { + [BOLERO_REG(BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TOP_TOP_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TOP_TOP_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TOP_FREQ_MCLK)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TOP_DEBUG_BUS_SEL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TOP_DEBUG_EN0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TOP_DEBUG_EN1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TOP_DEBUG_DSM_LB)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TOP_RX_I2S_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TOP_TX_I2S_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TOP_I2S_CLK)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TOP_I2S_RESET)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX_INP_MUX_RX_EC_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_RF_PROC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_RF_PROC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_DEBUG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD_MON)] = WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_MON_VAL)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BAN)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_ST)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_CFG)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_CLR_COMMIT)] = WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_PIN1_MASK0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_PIN1_STATUS0)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_PIN1_CLEAR0)] = WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_PIN2_MASK0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_PIN2_STATUS0)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_PIN2_CLEAR0)] = WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_LEVEL0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_BYPASS0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_SET0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_CFG2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_CFG3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_SEC7)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_DSMDEM_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_CFG2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_CFG3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_SEC7)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_DSMDEM_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_BOOST0_BOOST_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_BOOST0_BOOST_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_BOOST0_BOOST_CFG2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_BOOST1_BOOST_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_BOOST1_BOOST_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_BOOST1_BOOST_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_BOOST1_BOOST_CFG2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_COMPANDER0_CTL0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_COMPANDER0_CTL1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_COMPANDER0_CTL2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_COMPANDER0_CTL3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_COMPANDER0_CTL4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_COMPANDER0_CTL5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_COMPANDER0_CTL6)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_WSA_COMPANDER0_CTL7)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_COMPANDER1_CTL0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_COMPANDER1_CTL1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_COMPANDER1_CTL2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_COMPANDER1_CTL3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_COMPANDER1_CTL4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_COMPANDER1_CTL5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_COMPANDER1_CTL6)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_WSA_COMPANDER1_CTL7)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SOFTCLIP0_CRC)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SOFTCLIP1_CRC)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_EC_HQ1_EC_REF_HQ_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_CLK_RST_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_CTL0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_CTL1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_FIFO_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FIFO)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_CLK_RST_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_CTL0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_CTL1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_FIFO_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FIFO)] = RD_REG, +}; + +u8 *bolero_reg_access[MAX_MACRO] = { + [TX_MACRO] = bolero_tx_reg_access, + [RX_MACRO] = bolero_rx_reg_access, + [WSA_MACRO] = bolero_wsa_reg_access, + [VA_MACRO] = bolero_va_reg_access, +}; diff --git a/asoc/codecs/bolero/bolero_cdc_utils.c b/asoc/codecs/bolero/bolero_cdc_utils.c new file mode 100644 index 000000000000..81a747ea360e --- /dev/null +++ b/asoc/codecs/bolero/bolero_cdc_utils.c @@ -0,0 +1,186 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "bolero_cdc.h" +#include "internal.h" + +#define REG_BYTES 2 +#define VAL_BYTES 1 + +const u16 macro_id_base_offset[MAX_MACRO] = { + TX_START_OFFSET, + RX_START_OFFSET, + WSA_START_OFFSET, + VA_START_OFFSET, +}; + +int bolero_get_macro_id(bool va_no_dec_flag, u16 reg) +{ + if (reg >= TX_START_OFFSET + && reg <= TX_MAX_OFFSET) + return TX_MACRO; + if (reg >= RX_START_OFFSET + && reg <= RX_MAX_OFFSET) + return RX_MACRO; + if (reg >= WSA_START_OFFSET + && reg <= WSA_MAX_OFFSET) + return WSA_MACRO; + if (!va_no_dec_flag && + (reg >= VA_START_OFFSET && + reg <= VA_MAX_OFFSET)) + return VA_MACRO; + if (va_no_dec_flag && + (reg >= VA_START_OFFSET && + reg <= VA_TOP_MAX_OFFSET)) + return VA_MACRO; + + return -EINVAL; +} + +static int regmap_bus_read(void *context, const void *reg, size_t reg_size, + void *val, size_t val_size) +{ + struct device *dev = context; + struct bolero_priv *priv = dev_get_drvdata(dev); + u16 *reg_p; + u16 __reg; + int macro_id, i; + u8 temp = 0; + int ret = -EINVAL; + + if (!priv) { + dev_err(dev, "%s: priv is NULL\n", __func__); + return ret; + } + if (!reg || !val) { + dev_err(dev, "%s: reg or val is NULL\n", __func__); + return ret; + } + if (reg_size != REG_BYTES) { + dev_err(dev, "%s: register size %zd bytes, not supported\n", + __func__, reg_size); + return ret; + } + + reg_p = (u16 *)reg; + macro_id = bolero_get_macro_id(priv->va_without_decimation, + reg_p[0]); + if (macro_id < 0 || !priv->macros_supported[macro_id]) { + dev_err_ratelimited(dev, + "%s: Unsupported macro %d or reg 0x%x is invalid\n", + __func__, macro_id, reg_p[0]); + return ret; + } + mutex_lock(&priv->io_lock); + for (i = 0; i < val_size; i++) { + __reg = reg_p[i] - macro_id_base_offset[macro_id]; + ret = priv->read_dev(priv, macro_id, __reg, &temp); + if (ret < 0) { + dev_err_ratelimited(dev, + "%s: Codec read failed (%d), reg: 0x%x, size:%zd\n", + __func__, ret, reg_p[i], val_size); + break; + } + ((u8 *)val)[i] = temp; + dev_dbg(dev, "%s: Read 0x%02x from reg 0x%x\n", + __func__, temp, reg_p[i]); + } + mutex_unlock(&priv->io_lock); + + return ret; +} + +static int regmap_bus_gather_write(void *context, + const void *reg, size_t reg_size, + const void *val, size_t val_size) +{ + struct device *dev = context; + struct bolero_priv *priv = dev_get_drvdata(dev); + u16 *reg_p; + u16 __reg; + int macro_id, i; + int ret = -EINVAL; + + if (!priv) { + dev_err(dev, "%s: priv is NULL\n", __func__); + return ret; + } + if (!reg || !val) { + dev_err(dev, "%s: reg or val is NULL\n", __func__); + return ret; + } + if (reg_size != REG_BYTES) { + dev_err(dev, "%s: register size %zd bytes, not supported\n", + __func__, reg_size); + return ret; + } + + reg_p = (u16 *)reg; + macro_id = bolero_get_macro_id(priv->va_without_decimation, + reg_p[0]); + if (macro_id < 0 || !priv->macros_supported[macro_id]) { + dev_err_ratelimited(dev, + "%s: Unsupported macro-id %d or reg 0x%x is invalid\n", + __func__, macro_id, reg_p[0]); + return ret; + } + mutex_lock(&priv->io_lock); + for (i = 0; i < val_size; i++) { + __reg = reg_p[i] - macro_id_base_offset[macro_id]; + ret = priv->write_dev(priv, macro_id, __reg, ((u8 *)val)[i]); + if (ret < 0) { + dev_err_ratelimited(dev, + "%s: Codec write failed (%d), reg:0x%x, size:%zd\n", + __func__, ret, reg_p[i], val_size); + break; + } + dev_dbg(dev, "Write %02x to reg 0x%x\n", ((u8 *)val)[i], + reg_p[i]); + } + mutex_unlock(&priv->io_lock); + return ret; +} + +static int regmap_bus_write(void *context, const void *data, size_t count) +{ + struct device *dev = context; + struct bolero_priv *priv = dev_get_drvdata(dev); + + if (!priv) + return -EINVAL; + + if (count < REG_BYTES) { + dev_err(dev, "%s: count %zd bytes < %d, not supported\n", + __func__, count, REG_BYTES); + return -EINVAL; + } + + return regmap_bus_gather_write(context, data, REG_BYTES, + data + REG_BYTES, + count - REG_BYTES); +} + +static struct regmap_bus regmap_bus_config = { + .write = regmap_bus_write, + .gather_write = regmap_bus_gather_write, + .read = regmap_bus_read, + .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, + .val_format_endian_default = REGMAP_ENDIAN_NATIVE, +}; + +struct regmap *bolero_regmap_init(struct device *dev, + const struct regmap_config *config) +{ + return devm_regmap_init(dev, ®map_bus_config, dev, config); +} diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h new file mode 100644 index 000000000000..63266a84c7b4 --- /dev/null +++ b/asoc/codecs/bolero/internal.h @@ -0,0 +1,56 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _BOLERO_INTERNAL_H +#define _BOLERO_INTERNAL_H + +#include "bolero_cdc_registers.h" + +enum { + REG_NO_ACCESS, + RD_REG, + WR_REG, + RD_WR_REG +}; + +struct bolero_priv { + struct device *dev; + struct snd_soc_codec *codec; + struct regmap *regmap; + struct mutex io_lock; + bool va_without_decimation; + bool macros_supported[MAX_MACRO]; + struct macro_ops macro_params[MAX_MACRO]; + struct snd_soc_dai_driver *bolero_dais; + u16 num_dais; + u16 num_macros_registered; + u16 child_num; + struct platform_device *pdev_child_devices[MAX_MACRO]; + + struct work_struct bolero_add_child_devices_work; + + int (*read_dev)(struct bolero_priv *priv, + u16 macro_id, u16 reg, u8 *val); + int (*write_dev)(struct bolero_priv *priv, + u16 macro_id, u16 reg, u8 val); +}; + +struct regmap *bolero_regmap_init(struct device *dev, + const struct regmap_config *config); +int bolero_get_macro_id(bool va_no_dec_flag, u16 reg); + +extern const struct regmap_config bolero_regmap_config; +extern u8 *bolero_reg_access[MAX_MACRO]; +extern u8 bolero_va_top_reg_access[BOLERO_CDC_VA_MACRO_TOP_MAX]; +extern const u16 macro_id_base_offset[MAX_MACRO]; + +#endif -- GitLab From 2df2d6185142b712cda1558d854d0ba664bf94dc Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 22 May 2018 15:45:42 +0530 Subject: [PATCH 0295/1645] asoc: bolero: Add bolero clock changes Add support for bolero clock changes for all macros. Change-Id: Ib7b238ffd9595b6fd2236f4a3d2bcfe545b3c5fb Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero_cdc.c | 168 +++++++++++++++++++++++++++----- asoc/codecs/bolero/bolero_cdc.h | 17 +++- asoc/codecs/bolero/internal.h | 2 + 3 files changed, 164 insertions(+), 23 deletions(-) diff --git a/asoc/codecs/bolero/bolero_cdc.c b/asoc/codecs/bolero/bolero_cdc.c index 479b71c949db..ab78ce869d6c 100644 --- a/asoc/codecs/bolero/bolero_cdc.c +++ b/asoc/codecs/bolero/bolero_cdc.c @@ -24,6 +24,14 @@ static struct snd_soc_codec_driver bolero; +/* MCLK_MUX table for all macros */ +static u16 bolero_mclk_mux_tbl[MAX_MACRO][MCLK_MUX_MAX] = { + {TX_MACRO, VA_MACRO}, + {TX_MACRO, RX_MACRO}, + {TX_MACRO, WSA_MACRO}, + {TX_MACRO, VA_MACRO}, +}; + static void bolero_ahb_write_device(char __iomem *io_base, u16 reg, u8 value) { @@ -45,24 +53,31 @@ static int __bolero_reg_read(struct bolero_priv *priv, u16 macro_id, u16 reg, u8 *val) { int ret = -EINVAL; + u16 current_mclk_mux_macro; - if (!priv->macro_params[macro_id].mclk_fn) { + mutex_lock(&priv->clk_lock); + current_mclk_mux_macro = + priv->current_mclk_mux_macro[macro_id]; + if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) { dev_dbg_ratelimited(priv->dev, - "%s: mclk_fn not init for macro-id-%d\n", - __func__, macro_id); - return ret; + "%s: mclk_fn not init for macro-id:%d, current_mclk_mux_macro:%d\n", + __func__, macro_id, current_mclk_mux_macro); + goto err; } - ret = priv->macro_params[macro_id].mclk_fn( - priv->macro_params[macro_id].dev, true); + ret = priv->macro_params[current_mclk_mux_macro].mclk_fn( + priv->macro_params[current_mclk_mux_macro].dev, true); if (ret) { dev_dbg_ratelimited(priv->dev, - "%s: clock enable failed\n", __func__); - return ret; + "%s: clock enable failed for macro-id:%d, current_mclk_mux_macro:%d\n", + __func__, macro_id, current_mclk_mux_macro); + goto err; } bolero_ahb_read_device( priv->macro_params[macro_id].io_base, reg, val); - priv->macro_params[macro_id].mclk_fn( - priv->macro_params[macro_id].dev, false); + priv->macro_params[current_mclk_mux_macro].mclk_fn( + priv->macro_params[current_mclk_mux_macro].dev, false); +err: + mutex_unlock(&priv->clk_lock); return ret; } @@ -70,24 +85,31 @@ static int __bolero_reg_write(struct bolero_priv *priv, u16 macro_id, u16 reg, u8 val) { int ret = -EINVAL; + u16 current_mclk_mux_macro; - if (!priv->macro_params[macro_id].mclk_fn) { + mutex_lock(&priv->clk_lock); + current_mclk_mux_macro = + priv->current_mclk_mux_macro[macro_id]; + if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) { dev_dbg_ratelimited(priv->dev, - "%s: mclk_fn not init for macro-id-%d\n", - __func__, macro_id); - return ret; + "%s: mclk_fn not init for macro-id:%d, current_mclk_mux_macro:%d\n", + __func__, macro_id, current_mclk_mux_macro); + goto err; } - ret = priv->macro_params[macro_id].mclk_fn( - priv->macro_params[macro_id].dev, true); + ret = priv->macro_params[current_mclk_mux_macro].mclk_fn( + priv->macro_params[current_mclk_mux_macro].dev, true); if (ret) { dev_dbg_ratelimited(priv->dev, - "%s: clock enable failed\n", __func__); - return ret; + "%s: clock enable failed for macro-id:%d, current_mclk_mux_macro:%d\n", + __func__, macro_id, current_mclk_mux_macro); + goto err; } bolero_ahb_write_device( priv->macro_params[macro_id].io_base, reg, val); - priv->macro_params[macro_id].mclk_fn( - priv->macro_params[macro_id].dev, false); + priv->macro_params[current_mclk_mux_macro].mclk_fn( + priv->macro_params[current_mclk_mux_macro].dev, false); +err: + mutex_unlock(&priv->clk_lock); return ret; } @@ -204,6 +226,8 @@ int bolero_register_macro(struct device *dev, u16 macro_id, priv->macro_params[macro_id].dai_ptr = ops->dai_ptr; priv->macro_params[macro_id].mclk_fn = ops->mclk_fn; priv->macro_params[macro_id].dev = dev; + priv->current_mclk_mux_macro[macro_id] = + bolero_mclk_mux_tbl[macro_id][MCLK_MUX0]; priv->num_dais += ops->num_dais; priv->num_macros_registered++; priv->macros_supported[macro_id] = true; @@ -214,6 +238,12 @@ int bolero_register_macro(struct device *dev, u16 macro_id, dev_err(dev, "%s: copy_dais failed\n", __func__); return ret; } + if (priv->macros_supported[TX_MACRO] == false) { + bolero_mclk_mux_tbl[WSA_MACRO][MCLK_MUX0] = WSA_MACRO; + priv->current_mclk_mux_macro[WSA_MACRO] = WSA_MACRO; + bolero_mclk_mux_tbl[VA_MACRO][MCLK_MUX0] = VA_MACRO; + priv->current_mclk_mux_macro[VA_MACRO] = VA_MACRO; + } ret = snd_soc_register_codec(dev->parent, &bolero, priv->bolero_dais, priv->num_dais); if (ret < 0) { @@ -265,6 +295,100 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) } EXPORT_SYMBOL(bolero_unregister_macro); +/** + * bolero_request_clock - request for clock enable/disable + * + * @dev: macro device ptr. + * @macro_id: ID of macro calling this API. + * @mclk_mux_id: MCLK_MUX ID. + * @enable: enable or disable clock flag + * + * Returns 0 on success or -EINVAL on error. + */ +int bolero_request_clock(struct device *dev, u16 macro_id, + enum mclk_mux mclk_mux_id, + bool enable) +{ + struct bolero_priv *priv; + u16 mclk_mux0_macro, mclk_mux1_macro; + int ret = 0; + + if (!dev) { + pr_err("%s: dev is null\n", __func__); + return -EINVAL; + } + if (!bolero_is_valid_macro_dev(dev)) { + dev_err(dev, "%s: macro:%d not in valid registered macro-list\n", + __func__, macro_id); + return -EINVAL; + } + priv = dev_get_drvdata(dev->parent); + if (!priv || (macro_id >= MAX_MACRO)) { + dev_err(dev, "%s: priv is null or invalid macro\n", __func__); + return -EINVAL; + } + mclk_mux0_macro = bolero_mclk_mux_tbl[macro_id][MCLK_MUX0]; + mutex_lock(&priv->clk_lock); + switch (mclk_mux_id) { + case MCLK_MUX0: + ret = priv->macro_params[mclk_mux0_macro].mclk_fn( + priv->macro_params[mclk_mux0_macro].dev, enable); + if (ret < 0) { + dev_err(dev, + "%s: MCLK_MUX0 %s failed for macro:%d, mclk_mux0_macro:%d\n", + __func__, + enable ? "enable" : "disable", + macro_id, mclk_mux0_macro); + goto err; + } + break; + case MCLK_MUX1: + mclk_mux1_macro = bolero_mclk_mux_tbl[macro_id][MCLK_MUX1]; + ret = priv->macro_params[mclk_mux0_macro].mclk_fn( + priv->macro_params[mclk_mux0_macro].dev, + true); + if (ret < 0) { + dev_err(dev, + "%s: MCLK_MUX0 en failed for macro:%d mclk_mux0_macro:%d\n", + __func__, macro_id, mclk_mux0_macro); + goto err; + } + ret = priv->macro_params[mclk_mux1_macro].mclk_fn( + priv->macro_params[mclk_mux1_macro].dev, enable); + if (ret < 0) { + dev_err(dev, + "%s: MCLK_MUX1 %s failed for macro:%d, mclk_mux1_macro:%d\n", + __func__, + enable ? "enable" : "disable", + macro_id, mclk_mux1_macro); + priv->macro_params[mclk_mux0_macro].mclk_fn( + priv->macro_params[mclk_mux0_macro].dev, + false); + goto err; + } + priv->macro_params[mclk_mux0_macro].mclk_fn( + priv->macro_params[mclk_mux0_macro].dev, + false); + break; + case MCLK_MUX_MAX: + default: + dev_err(dev, "%s: invalid mclk_mux_id: %d\n", + __func__, mclk_mux_id); + ret = -EINVAL; + goto err; + } + if (enable) + priv->current_mclk_mux_macro[macro_id] = + bolero_mclk_mux_tbl[macro_id][mclk_mux_id]; + else + priv->current_mclk_mux_macro[macro_id] = + bolero_mclk_mux_tbl[macro_id][MCLK_MUX0]; +err: + mutex_unlock(&priv->clk_lock); + return ret; +} +EXPORT_SYMBOL(bolero_request_clock); + static int bolero_soc_codec_probe(struct snd_soc_codec *codec) { struct bolero_priv *priv = dev_get_drvdata(codec->dev); @@ -359,8 +483,6 @@ static void bolero_add_child_devices(struct work_struct *work) fail_pdev_add: for (i = cnt; i > 0; i--) platform_device_put(priv->pdev_child_devices[i - 1]); -err: - return; } static int bolero_probe(struct platform_device *pdev) @@ -405,6 +527,7 @@ static int bolero_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, priv); mutex_init(&priv->io_lock); + mutex_init(&priv->clk_lock); INIT_WORK(&priv->bolero_add_child_devices_work, bolero_add_child_devices); schedule_work(&priv->bolero_add_child_devices_work); @@ -420,6 +543,7 @@ static int bolero_remove(struct platform_device *pdev) for (i = priv->child_num; i > 0; i--) platform_device_unregister(priv->pdev_child_devices[i - 1]); mutex_destroy(&priv->io_lock); + mutex_destroy(&priv->clk_lock); return 0; } diff --git a/asoc/codecs/bolero/bolero_cdc.h b/asoc/codecs/bolero/bolero_cdc.h index 7b3aad2a52e4..e8b8bb46a061 100644 --- a/asoc/codecs/bolero/bolero_cdc.h +++ b/asoc/codecs/bolero/bolero_cdc.h @@ -25,6 +25,12 @@ enum { MAX_MACRO }; +enum mclk_mux { + MCLK_MUX0, + MCLK_MUX1, + MCLK_MUX_MAX +}; + struct macro_ops { int (*init)(struct snd_soc_codec *codec); int (*exit)(struct snd_soc_codec *codec); @@ -40,6 +46,9 @@ int bolero_register_macro(struct device *dev, u16 macro_id, struct macro_ops *ops); void bolero_unregister_macro(struct device *dev, u16 macro_id); struct device *bolero_get_device_ptr(struct device *dev, u16 macro_id); +int bolero_request_clock(struct device *dev, u16 macro_id, + enum mclk_mux mclk_mux_id, + bool enable); #else static inline int bolero_register_macro(struct device *dev, u16 macro_id, @@ -53,9 +62,15 @@ static inline void bolero_unregister_macro(struct device *dev, u16 macro_id) } static inline struct device *bolero_get_device_ptr(struct device *dev, - u16 macro_id) + u16 macro_id) { return NULL; } +static inline int bolero_request_clock(struct device *dev, u16 macro_id, + enum mclk_mux mclk_mux_id, + bool enable) +{ + return 0; +} #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 63266a84c7b4..0fca99439652 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -27,6 +27,7 @@ struct bolero_priv { struct snd_soc_codec *codec; struct regmap *regmap; struct mutex io_lock; + struct mutex clk_lock; bool va_without_decimation; bool macros_supported[MAX_MACRO]; struct macro_ops macro_params[MAX_MACRO]; @@ -34,6 +35,7 @@ struct bolero_priv { u16 num_dais; u16 num_macros_registered; u16 child_num; + u16 current_mclk_mux_macro[MAX_MACRO]; struct platform_device *pdev_child_devices[MAX_MACRO]; struct work_struct bolero_add_child_devices_work; -- GitLab From c712c17ab0efde61ae2795e52cf1a193dd8eef46 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Fri, 17 Nov 2017 17:36:49 -0800 Subject: [PATCH 0296/1645] dsp: Add support for custom encoder Add support to set custom encoder in ASM which can be enabled through compress capture path. Change-Id: I563c59eb3a0213c26ce69d3c2f8d650cf3c7d32d Signed-off-by: Vikram Panduranga --- asoc/msm-compress-q6-v2.c | 30 ++++++++-- asoc/msm-pcm-q6-v2.c | 2 +- dsp/q6asm.c | 110 +++++++++++++++++++++++++++++++++++-- include/dsp/apr_audio-v2.h | 16 ++++++ include/dsp/q6asm-v2.h | 10 +++- 5 files changed, 155 insertions(+), 13 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index c4fecdefa2b3..c0d8614559f1 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -1432,6 +1432,7 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream) int dir = OUT, ret = 0; struct audio_client *ac = prtd->audio_client; uint32_t stream_index; + uint32_t enc_cfg_id = ENC_CFG_ID_NONE; switch (prtd->codec_param.codec.format) { case SNDRV_PCM_FORMAT_S24_LE: @@ -1450,6 +1451,9 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream) default: bits_per_sample = 16; sample_word_size = 16; + if (prtd->codec == FORMAT_BESPOKE) + enc_cfg_id = + prtd->codec_param.codec.options.generic.reserved[0]; break; } @@ -1457,11 +1461,11 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream) __func__, ac->stream_id, bits_per_sample); if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG) { - ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM, - bits_per_sample, true); + ret = q6asm_open_read_v4(prtd->audio_client, prtd->codec, + bits_per_sample, true, enc_cfg_id); } else { - ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM, - bits_per_sample, false); + ret = q6asm_open_read_v4(prtd->audio_client, prtd->codec, + bits_per_sample, false, enc_cfg_id); } if (ret < 0) { pr_err("%s: q6asm_open_read failed:%d\n", __func__, ret); @@ -1521,10 +1525,20 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream) pr_debug("%s: sample_rate = %d channels = %d bps = %d sample_word_size = %d\n", __func__, prtd->sample_rate, prtd->num_channels, bits_per_sample, sample_word_size); - ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client, + if (prtd->codec == FORMAT_BESPOKE) { + /* + * For BESPOKE codec, encoder specific config params are + * included as part of generic. + */ + ret = q6asm_enc_cfg_blk_custom(prtd->audio_client, prtd->sample_rate, + prtd->num_channels, prtd->codec, + (void *)&prtd->codec_param.codec.options.generic); + } else { + ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client, prtd->sample_rate, prtd->num_channels, bits_per_sample, sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); + } return ret; } @@ -2043,6 +2057,12 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream, break; } + case SND_AUDIOCODEC_BESPOKE: { + pr_debug("%s: SND_AUDIOCODEC_BESPOKE\n", __func__); + prtd->codec = FORMAT_BESPOKE; + break; + } + default: pr_err("codec not supported, id =%d\n", params->codec.id); return -EINVAL; diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index b82128e7fabe..8ae85b743686 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -490,7 +490,7 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) prtd->audio_client->perf_mode); ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM, - bits_per_sample, false); + bits_per_sample, false, ENC_CFG_ID_NONE); if (ret < 0) { pr_err("%s: q6asm_open_read failed\n", __func__); q6asm_audio_client_free(prtd->audio_client); diff --git a/dsp/q6asm.c b/dsp/q6asm.c index a12347966f5a..38ddc88b0f24 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -46,6 +46,8 @@ #define FALSE 0x00 #define SESSION_MAX 8 +#define ENC_FRAMES_PER_BUFFER 0x01 + enum { ASM_TOPOLOGY_CAL = 0, ASM_CUSTOM_TOP_CAL, @@ -2812,7 +2814,7 @@ EXPORT_SYMBOL(q6asm_set_soft_volume_module_instance_ids); static int __q6asm_open_read(struct audio_client *ac, uint32_t format, uint16_t bits_per_sample, uint32_t pcm_format_block_ver, - bool ts_mode) + bool ts_mode, uint32_t enc_cfg_id) { int rc = 0x00; struct asm_stream_cmd_open_read_v3 open; @@ -2888,6 +2890,12 @@ static int __q6asm_open_read(struct audio_client *ac, open.mode_flags |= BUFFER_META_ENABLE; open.enc_cfg_id = ASM_MEDIA_FMT_AMRWB_FS; break; + case FORMAT_BESPOKE: + open.mode_flags |= BUFFER_META_ENABLE; + open.enc_cfg_id = enc_cfg_id; + if (ts_mode) + open.mode_flags |= ABSOLUTE_TIMESTAMP_ENABLE; + break; default: pr_err("%s: Invalid format 0x%x\n", __func__, format); @@ -2939,7 +2947,7 @@ int q6asm_open_read(struct audio_client *ac, { return __q6asm_open_read(ac, format, 16, PCM_MEDIA_FORMAT_V2 /*media fmt block ver*/, - false/*ts_mode*/); + false/*ts_mode*/, ENC_CFG_ID_NONE); } EXPORT_SYMBOL(q6asm_open_read); @@ -2948,7 +2956,7 @@ int q6asm_open_read_v2(struct audio_client *ac, uint32_t format, { return __q6asm_open_read(ac, format, bits_per_sample, PCM_MEDIA_FORMAT_V2 /*media fmt block ver*/, - false/*ts_mode*/); + false/*ts_mode*/, ENC_CFG_ID_NONE); } /* @@ -2963,7 +2971,7 @@ int q6asm_open_read_v3(struct audio_client *ac, uint32_t format, { return __q6asm_open_read(ac, format, bits_per_sample, PCM_MEDIA_FORMAT_V3/*media fmt block ver*/, - false/*ts_mode*/); + false/*ts_mode*/, ENC_CFG_ID_NONE); } EXPORT_SYMBOL(q6asm_open_read_v3); @@ -2976,11 +2984,12 @@ EXPORT_SYMBOL(q6asm_open_read_v3); * @ts_mode: timestamp mode */ int q6asm_open_read_v4(struct audio_client *ac, uint32_t format, - uint16_t bits_per_sample, bool ts_mode) + uint16_t bits_per_sample, bool ts_mode, + uint32_t enc_cfg_id) { return __q6asm_open_read(ac, format, bits_per_sample, PCM_MEDIA_FORMAT_V4 /*media fmt block ver*/, - ts_mode); + ts_mode, enc_cfg_id); } EXPORT_SYMBOL(q6asm_open_read_v4); @@ -4287,6 +4296,95 @@ int q6asm_stream_run_nowait(struct audio_client *ac, uint32_t flags, return __q6asm_run_nowait(ac, flags, msw_ts, lsw_ts, stream_id); } +/** + * q6asm_enc_cfg_blk_custom - + * command to set encode cfg block for custom + * + * @ac: Audio client handle + * @sample_rate: Sample rate + * @channels: number of ASM channels + * @format: custom format flag + * @cfg: generic encoder config + * + * Returns 0 on success or error on failure + */ +int q6asm_enc_cfg_blk_custom(struct audio_client *ac, + uint32_t sample_rate, uint32_t channels, + uint32_t format, void *cfg) +{ + struct asm_custom_enc_cfg_t_v2 enc_cfg; + int rc = 0; + uint32_t custom_size; + struct snd_enc_generic *enc_generic = (struct snd_enc_generic *) cfg; + + custom_size = enc_generic->reserved[1]; + + pr_debug("%s: session[%d] size[%d] res[2]=[%d] res[3]=[%d]\n", + __func__, ac->session, custom_size, enc_generic->reserved[2], + enc_generic->reserved[3]); + + pr_debug("%s: res[4]=[%d] sr[%d] ch[%d] format[%d]\n", + __func__, enc_generic->reserved[4], sample_rate, + channels, format); + + memset(&enc_cfg, 0, sizeof(struct asm_custom_enc_cfg_t_v2)); + q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE); + atomic_set(&ac->cmd_state, -1); + + enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2; + enc_cfg.encdec.param_size = sizeof(struct asm_custom_enc_cfg_t_v2) - + sizeof(struct asm_stream_cmd_set_encdec_param); + enc_cfg.encblk.frames_per_buf = ENC_FRAMES_PER_BUFFER; + enc_cfg.encblk.enc_cfg_blk_size = enc_cfg.encdec.param_size - + sizeof(struct asm_enc_cfg_blk_param_v2); + + enc_cfg.num_channels = channels; + enc_cfg.sample_rate = sample_rate; + + if (q6asm_map_channels(enc_cfg.channel_mapping, channels, false)) { + pr_err("%s: map channels failed %d\n", + __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + + if (format == FORMAT_BESPOKE && custom_size && + custom_size <= sizeof(enc_cfg.custom_data)) { + memcpy(enc_cfg.custom_data, &enc_generic->reserved[2], + custom_size); + enc_cfg.custom_size = custom_size; + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg); + if (rc < 0) { + pr_err("%s: Comamnd %d failed %d\n", + __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for FORMAT_UPDATE\n", + __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} +EXPORT_SYMBOL(q6asm_enc_cfg_blk_custom); + /** * q6asm_enc_cfg_blk_aac - * command to set encode cfg block for aac diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index a282f78b33d6..5f62a2711d6e 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -4743,6 +4743,22 @@ struct asm_enc_cfg_blk_param_v2 { } __packed; +struct asm_custom_enc_cfg_t_v2 { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + struct asm_enc_cfg_blk_param_v2 encblk; + uint32_t sample_rate; + + uint16_t num_channels; + uint16_t reserved; + /* num_ch == 1, then PCM_CHANNEL_C, + * num_ch == 2, then {PCM_CHANNEL_L, PCM_CHANNEL_R} + */ + uint8_t channel_mapping[8]; + uint32_t custom_size; + uint8_t custom_data[15]; +} __packed; + /* @brief Dolby Digital Plus end point configuration structure */ struct asm_dec_ddp_endp_param_v2 { diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index ba35779a5788..e6f021db7e88 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -57,11 +57,14 @@ #define FORMAT_GEN_COMPR 0x001f #define FORMAT_TRUEHD 0x0020 #define FORMAT_IEC61937 0x0021 +#define FORMAT_BESPOKE 0x0022 #define ENCDEC_SBCBITRATE 0x0001 #define ENCDEC_IMMEDIATE_DECODE 0x0002 #define ENCDEC_CFG_BLK 0x0003 +#define ENC_CFG_ID_NONE 0x0000 + #define CMD_PAUSE 0x0001 #define CMD_FLUSH 0x0002 #define CMD_EOS 0x0003 @@ -290,7 +293,8 @@ int q6asm_open_read_v3(struct audio_client *ac, uint32_t format, uint16_t bits_per_sample); int q6asm_open_read_v4(struct audio_client *ac, uint32_t format, - uint16_t bits_per_sample, bool ts_mode); + uint16_t bits_per_sample, bool ts_mode, + uint32_t enc_cfg_id); int q6asm_open_write(struct audio_client *ac, uint32_t format /*, uint16_t bits_per_sample*/); @@ -454,6 +458,10 @@ int q6asm_enc_cfg_blk_pcm_format_support_v4(struct audio_client *ac, uint16_t endianness, uint16_t mode); +int q6asm_enc_cfg_blk_custom(struct audio_client *ac, + uint32_t sample_rate, uint32_t channels, + uint32_t format, void *cfg); + int q6asm_set_encdec_chan_map(struct audio_client *ac, uint32_t num_channels); -- GitLab From 3f030f19f9c23c453b3c03a6e8dcdeb0efc4b2a0 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Fri, 25 May 2018 16:17:32 -0700 Subject: [PATCH 0297/1645] asoc: sm8150: Add MultiMedia17 FE with capture support Add MultiMedia17 FE to support compress capture usecase. This can be used to enable recording on compress offload path. Change-Id: I2a570ec9f4950128aba77a257e98569c714c778c Signed-off-by: Vikram Panduranga --- asoc/sm8150.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/asoc/sm8150.c b/asoc/sm8150.c index f4bc02a0c5cb..df16270e8be6 100644 --- a/asoc/sm8150.c +++ b/asoc/sm8150.c @@ -5668,6 +5668,21 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, + { + .name = "Compress Capture", + .stream_name = "Compress9", + .cpu_dai_name = "MultiMedia17", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA17, + }, }; static struct snd_soc_dai_link msm_common_be_dai_links[] = { -- GitLab From f71f3504b7496e3c9412b2f81d827bae826fc0f1 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 7 May 2018 16:59:30 +0800 Subject: [PATCH 0298/1645] ipc: apr: add qcom,subsys-name for apr Add qcom,subsys-name for apr driver. Based on the property, registration of notifier is done for the right co-processor, from which notification needs to be received. Change-Id: Id492c8b24d1a4cf0bcab37700a1e9c61c9067041 Signed-off-by: Meng Wang --- ipc/apr.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/ipc/apr.c b/ipc/apr.c index 6e1f7d3e7935..cb72766a5ff5 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -43,6 +43,7 @@ static struct apr_client client[APR_DEST_MAX][APR_CLIENT_MAX]; static void *apr_pkt_ctx; static wait_queue_head_t modem_wait; static bool is_modem_up; +static char *subsys_name = NULL; /* Subsystem restart: QDSP6 data, functions */ static struct workqueue_struct *apr_reset_workqueue; static void apr_reset_deregister(struct work_struct *work); @@ -1108,8 +1109,7 @@ static void apr_cleanup(void) int i, j, k; of_platform_depopulate(apr_priv->dev); - subsys_notif_deregister("apr_modem"); - subsys_notif_deregister("apr_adsp"); + subsys_notif_deregister(subsys_name); if (apr_reset_workqueue) { flush_workqueue(apr_reset_workqueue); destroy_workqueue(apr_reset_workqueue); @@ -1127,7 +1127,7 @@ static void apr_cleanup(void) static int apr_probe(struct platform_device *pdev) { - int i, j, k; + int i, j, k, ret = 0; init_waitqueue_head(&modem_wait); @@ -1163,10 +1163,26 @@ static int apr_probe(struct platform_device *pdev) spin_lock(&apr_priv->apr_lock); apr_priv->is_initial_boot = true; spin_unlock(&apr_priv->apr_lock); - subsys_notif_register("apr_adsp", AUDIO_NOTIFIER_ADSP_DOMAIN, - &adsp_service_nb); - subsys_notif_register("apr_modem", AUDIO_NOTIFIER_MODEM_DOMAIN, - &modem_service_nb); + ret = of_property_read_string(pdev->dev.of_node, + "qcom,subsys-name", + (const char **)(&subsys_name)); + if (ret) { + pr_err("%s: missing subsys-name entry in dt node\n", __func__); + return -EINVAL; + } + + if (!strcmp(subsys_name, "apr_adsp")) { + subsys_notif_register("apr_adsp", + AUDIO_NOTIFIER_ADSP_DOMAIN, + &adsp_service_nb); + } else if (!strcmp(subsys_name, "apr_modem")) { + subsys_notif_register("apr_modem", + AUDIO_NOTIFIER_MODEM_DOMAIN, + &modem_service_nb); + } else { + pr_err("%s: invalid subsys-name %s\n", __func__, subsys_name); + return -EINVAL; + } apr_tal_init(); return apr_debug_init(); -- GitLab From da08f2f31562a8f6c3750aed1314dad940b591bd Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 17 May 2018 11:23:27 +0800 Subject: [PATCH 0299/1645] ASoC: wcd934x: Reset power_active_ref to 0 when it is negative Reset power_active_ref counter to 0 when it is negative to take digital core out of reset during next session. Change-Id: I724ffe6e3547655424238ca02a9bf8ac24b101fe Signed-off-by: Meng Wang --- asoc/codecs/wcd934x/wcd934x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 36a067432c64..b45631fc89c7 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -9002,8 +9002,10 @@ static int tavil_dig_core_power_collapse(struct tavil_priv *tavil, goto unlock_mutex; if (tavil->power_active_ref < 0) { - dev_dbg(tavil->dev, "%s: power_active_ref is negative\n", + dev_dbg(tavil->dev, + "%s: power_active_ref is negative, reset it\n", __func__); + tavil->power_active_ref = 0; goto unlock_mutex; } -- GitLab From 89438f3ee8f04a27c7d6c5758213cd093b81eb59 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 7 Jun 2018 12:44:17 +0530 Subject: [PATCH 0300/1645] asoc: codecs: Update file names of bolero Update file names of bolero to be compliance to driver file name convention. Change-Id: I138d0211803f93152ae7fb01eae68050dada082f Signed-off-by: Laxminath Kasam --- ...cdc_registers.h => bolero-cdc-registers.h} | 0 ...olero_cdc_regmap.c => bolero-cdc-regmap.c} | 2 +- ...olero_cdc_tables.c => bolero-cdc-tables.c} | 2 +- ...{bolero_cdc_utils.c => bolero-cdc-utils.c} | 2 +- .../bolero/{bolero_cdc.c => bolero-cdc.c} | 47 +++++-------------- .../bolero/{bolero_cdc.h => bolero-cdc.h} | 0 asoc/codecs/bolero/internal.h | 4 +- 7 files changed, 17 insertions(+), 40 deletions(-) rename asoc/codecs/bolero/{bolero_cdc_registers.h => bolero-cdc-registers.h} (100%) rename asoc/codecs/bolero/{bolero_cdc_regmap.c => bolero-cdc-regmap.c} (99%) rename asoc/codecs/bolero/{bolero_cdc_tables.c => bolero-cdc-tables.c} (99%) rename asoc/codecs/bolero/{bolero_cdc_utils.c => bolero-cdc-utils.c} (99%) rename asoc/codecs/bolero/{bolero_cdc.c => bolero-cdc.c} (94%) rename asoc/codecs/bolero/{bolero_cdc.h => bolero-cdc.h} (100%) diff --git a/asoc/codecs/bolero/bolero_cdc_registers.h b/asoc/codecs/bolero/bolero-cdc-registers.h similarity index 100% rename from asoc/codecs/bolero/bolero_cdc_registers.h rename to asoc/codecs/bolero/bolero-cdc-registers.h diff --git a/asoc/codecs/bolero/bolero_cdc_regmap.c b/asoc/codecs/bolero/bolero-cdc-regmap.c similarity index 99% rename from asoc/codecs/bolero/bolero_cdc_regmap.c rename to asoc/codecs/bolero/bolero-cdc-regmap.c index ece2f779f531..46c808607eca 100644 --- a/asoc/codecs/bolero/bolero_cdc_regmap.c +++ b/asoc/codecs/bolero/bolero-cdc-regmap.c @@ -11,7 +11,7 @@ */ #include -#include "bolero_cdc.h" +#include "bolero-cdc.h" #include "internal.h" static const struct reg_default bolero_defaults[] = { diff --git a/asoc/codecs/bolero/bolero_cdc_tables.c b/asoc/codecs/bolero/bolero-cdc-tables.c similarity index 99% rename from asoc/codecs/bolero/bolero_cdc_tables.c rename to asoc/codecs/bolero/bolero-cdc-tables.c index f9d271c0b53f..2407ac70e8f3 100644 --- a/asoc/codecs/bolero/bolero_cdc_tables.c +++ b/asoc/codecs/bolero/bolero-cdc-tables.c @@ -12,7 +12,7 @@ */ #include -#include "bolero_cdc.h" +#include "bolero-cdc.h" #include "internal.h" u8 bolero_tx_reg_access[BOLERO_CDC_TX_MACRO_MAX] = { diff --git a/asoc/codecs/bolero/bolero_cdc_utils.c b/asoc/codecs/bolero/bolero-cdc-utils.c similarity index 99% rename from asoc/codecs/bolero/bolero_cdc_utils.c rename to asoc/codecs/bolero/bolero-cdc-utils.c index 81a747ea360e..ff056085d35b 100644 --- a/asoc/codecs/bolero/bolero_cdc_utils.c +++ b/asoc/codecs/bolero/bolero-cdc-utils.c @@ -12,7 +12,7 @@ #include #include -#include "bolero_cdc.h" +#include "bolero-cdc.h" #include "internal.h" #define REG_BYTES 2 diff --git a/asoc/codecs/bolero/bolero_cdc.c b/asoc/codecs/bolero/bolero-cdc.c similarity index 94% rename from asoc/codecs/bolero/bolero_cdc.c rename to asoc/codecs/bolero/bolero-cdc.c index ab78ce869d6c..5a2005055810 100644 --- a/asoc/codecs/bolero/bolero_cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -19,7 +19,7 @@ #include #include -#include "bolero_cdc.h" +#include "bolero-cdc.h" #include "internal.h" static struct snd_soc_codec_driver bolero; @@ -441,9 +441,7 @@ static struct snd_soc_codec_driver bolero = { static void bolero_add_child_devices(struct work_struct *work) { struct bolero_priv *priv; - struct platform_device *pdev; - struct device_node *node; - int ret, i, cnt = 0; + int rc; priv = container_of(work, struct bolero_priv, bolero_add_child_devices_work); @@ -452,37 +450,17 @@ static void bolero_add_child_devices(struct work_struct *work) __func__); return; } - if (!priv->dev->of_node) { + if (!priv->dev || !priv->dev->of_node) { dev_err(priv->dev, "%s: DT node for bolero does not exist\n", __func__); return; } - - for_each_child_of_node(priv->dev->of_node, node) { - pdev = platform_device_alloc(node->name, -1); - if (!pdev) { - dev_err(priv->dev, "%s: pdev memory alloc failed\n", - __func__); - ret = -ENOMEM; - goto fail_pdev_add; - } - pdev->dev.parent = priv->dev; - pdev->dev.of_node = node; - - ret = platform_device_add(pdev); - if (ret) { - dev_err(priv->dev, - "%s: Cannot add platform device\n", - __func__); - goto fail_pdev_add; - } - priv->pdev_child_devices[cnt] = pdev; - cnt++; - } - return; -fail_pdev_add: - for (i = cnt; i > 0; i--) - platform_device_put(priv->pdev_child_devices[i - 1]); + rc = of_platform_populate(priv->dev->of_node, NULL, NULL, priv->dev); + if (rc) + dev_err(priv->dev, "%s: failed to add child nodes, rc=%d\n", + __func__, rc); + else + dev_dbg(priv->dev, "%s: added child node\n", __func__); } static int bolero_probe(struct platform_device *pdev) @@ -538,10 +516,11 @@ static int bolero_probe(struct platform_device *pdev) static int bolero_remove(struct platform_device *pdev) { struct bolero_priv *priv = dev_get_drvdata(&pdev->dev); - u16 i; - for (i = priv->child_num; i > 0; i--) - platform_device_unregister(priv->pdev_child_devices[i - 1]); + if (!priv) + return -EINVAL; + + of_platform_depopulate(&pdev->dev); mutex_destroy(&priv->io_lock); mutex_destroy(&priv->clk_lock); return 0; diff --git a/asoc/codecs/bolero/bolero_cdc.h b/asoc/codecs/bolero/bolero-cdc.h similarity index 100% rename from asoc/codecs/bolero/bolero_cdc.h rename to asoc/codecs/bolero/bolero-cdc.h diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 0fca99439652..0e310c8a4c24 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -13,7 +13,7 @@ #ifndef _BOLERO_INTERNAL_H #define _BOLERO_INTERNAL_H -#include "bolero_cdc_registers.h" +#include "bolero-cdc-registers.h" enum { REG_NO_ACCESS, @@ -36,8 +36,6 @@ struct bolero_priv { u16 num_macros_registered; u16 child_num; u16 current_mclk_mux_macro[MAX_MACRO]; - struct platform_device *pdev_child_devices[MAX_MACRO]; - struct work_struct bolero_add_child_devices_work; int (*read_dev)(struct bolero_priv *priv, -- GitLab From 243e2754ebadb01f38e765810b342461cbc479cf Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 12 Apr 2018 00:40:19 +0530 Subject: [PATCH 0301/1645] asoc: bolero: Add support for WSA macro driver Add support for WSA digital portion to register as macro to bolero codec. ASoC dapm and dai functionality of WSA macro is associated to bolero codec itself. Change-Id: Ida9647274e6a0aa392e131a9b08f83b2520802e5 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/wsa-macro.c | 2190 ++++++++++++++++++++++++++++++++ asoc/codecs/bolero/wsa-macro.h | 46 + 2 files changed, 2236 insertions(+) create mode 100644 asoc/codecs/bolero/wsa-macro.c create mode 100644 asoc/codecs/bolero/wsa-macro.h diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c new file mode 100644 index 000000000000..e8b84d8ceb2b --- /dev/null +++ b/asoc/codecs/bolero/wsa-macro.c @@ -0,0 +1,2190 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bolero-cdc.h" +#include "bolero-cdc-registers.h" +#include "wsa-macro.h" +#include "../msm-cdc-pinctrl.h" + +#define WSA_MACRO_MAX_OFFSET 0x1000 + +#define WSA_MACRO_RX_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) +#define WSA_MACRO_RX_MIX_RATES (SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) +#define WSA_MACRO_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) + +#define WSA_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_48000) +#define WSA_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_3LE) + +#define NUM_INTERPOLATORS 2 + +#define WSA_MACRO_MUX_INP_SHFT 0x3 +#define WSA_MACRO_MUX_INP_MASK1 0x38 +#define WSA_MACRO_MUX_INP_MASK2 0x38 +#define WSA_MACRO_MUX_CFG_OFFSET 0x8 +#define WSA_MACRO_MUX_CFG1_OFFSET 0x4 +#define WSA_MACRO_RX_COMP_OFFSET 0x40 +#define WSA_MACRO_RX_PATH_OFFSET 0x80 +#define WSA_MACRO_RX_PATH_CFG3_OFFSET 0x10 +#define WSA_MACRO_RX_PATH_DSMDEM_OFFSET 0x4C +#define WSA_MACRO_FS_RATE_MASK 0x0F + +enum { + WSA_MACRO_RX0 = 0, + WSA_MACRO_RX1, + WSA_MACRO_RX_MIX, + WSA_MACRO_RX_MIX0 = WSA_MACRO_RX_MIX, + WSA_MACRO_RX_MIX1, + WSA_MACRO_RX_MAX, +}; + +enum { + WSA_MACRO_TX0 = 0, + WSA_MACRO_TX1, + WSA_MACRO_TX_MAX, +}; + +enum { + WSA_MACRO_COMP1, /* SPK_L */ + WSA_MACRO_COMP2, /* SPK_R */ + WSA_MACRO_COMP_MAX +}; + +struct interp_sample_rate { + int sample_rate; + int rate_val; +}; + +/* + * Structure used to update codec + * register defaults after reset + */ +struct wsa_macro_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + +static struct interp_sample_rate int_prim_sample_rate_val[] = { + {8000, 0x0}, /* 8K */ + {16000, 0x1}, /* 16K */ + {24000, -EINVAL},/* 24K */ + {32000, 0x3}, /* 32K */ + {48000, 0x4}, /* 48K */ + {96000, 0x5}, /* 96K */ + {192000, 0x6}, /* 192K */ + {384000, 0x7}, /* 384K */ + {44100, 0x8}, /* 44.1K */ +}; + +static struct interp_sample_rate int_mix_sample_rate_val[] = { + {48000, 0x4}, /* 48K */ + {96000, 0x5}, /* 96K */ + {192000, 0x6}, /* 192K */ +}; + +#define WSA_MACRO_SWR_STRING_LEN 80 + +static int wsa_macro_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai); +static int wsa_macro_get_channel_map(struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot); +/* Hold instance to soundwire platform device */ +struct wsa_macro_swr_ctrl_data { + struct platform_device *wsa_swr_pdev; +}; + +struct wsa_macro_swr_ctrl_platform_data { + void *handle; /* holds codec private data */ + int (*read)(void *handle, int reg); + int (*write)(void *handle, int reg, int val); + int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); + int (*clk)(void *handle, bool enable); + int (*handle_irq)(void *handle, + irqreturn_t (*swrm_irq_handler)(int irq, + void *data), + void *swrm_handle, + int action); +}; + +enum { + WSA_MACRO_AIF1_PB = 0, + WSA_MACRO_AIF_MIX1_PB, + WSA_MACRO_AIF_VI, + WSA_MACRO_AIF_ECHO, + WSA_MACRO_MAX_DAIS, +}; + +#define WSA_MACRO_CHILD_DEVICES_MAX 3 + +/* + * @dev: wsa macro device pointer + * @comp_enabled: compander enable mixer value set + * @prim_int_users: Users of interpolator + * @wsa_mclk_users: WSA MCLK users count + * @swr_clk_users: SWR clk users count + * @vi_feed_value: VI sense mask + * @mclk_lock: to lock mclk operations + * @swr_clk_lock: to lock swr master clock operations + * @swr_ctrl_data: SoundWire data structure + * @swr_plat_data: Soundwire platform data + * @wsa_macro_add_child_devices_work: work for adding child devices + * @wsa_swr_gpio_p: used by pinctrl API + * @wsa_core_clk: MCLK for wsa macro + * @wsa_npl_clk: NPL clock for WSA soundwire + * @codec: codec handle + * @rx_0_count: RX0 interpolation users + * @rx_1_count: RX1 interpolation users + * @active_ch_mask: channel mask for all AIF DAIs + * @active_ch_cnt: channel count of all AIF DAIs + * @rx_port_value: mixer ctl value of WSA RX MUXes + * @wsa_io_base: Base address of WSA macro addr space + */ +struct wsa_macro_priv { + struct device *dev; + int comp_enabled[WSA_MACRO_COMP_MAX]; + u16 prim_int_users[WSA_MACRO_RX1 + 1]; + u16 wsa_mclk_users; + u16 swr_clk_users; + unsigned int vi_feed_value; + struct mutex mclk_lock; + struct mutex swr_clk_lock; + struct wsa_macro_swr_ctrl_data *swr_ctrl_data; + struct wsa_macro_swr_ctrl_platform_data swr_plat_data; + struct work_struct wsa_macro_add_child_devices_work; + struct device_node *wsa_swr_gpio_p; + struct clk *wsa_core_clk; + struct clk *wsa_npl_clk; + struct snd_soc_codec *codec; + int rx_0_count; + int rx_1_count; + unsigned long active_ch_mask[WSA_MACRO_MAX_DAIS]; + unsigned long active_ch_cnt[WSA_MACRO_MAX_DAIS]; + int rx_port_value[WSA_MACRO_RX_MAX]; + char __iomem *wsa_io_base; + struct platform_device *pdev_child_devices + [WSA_MACRO_CHILD_DEVICES_MAX]; + int child_count; + int ear_spkr_gain; + int spkr_gain_offset; + int spkr_mode; +}; + +static int wsa_macro_config_ear_spkr_gain(struct snd_soc_codec *codec, + struct wsa_macro_priv *wsa_priv, + int event, int gain_reg); +static struct snd_soc_dai_driver wsa_macro_dai[]; +static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); + +static const char *const rx_text[] = { + "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "DEC0", "DEC1" +}; + +static const char *const rx_mix_text[] = { + "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1" +}; + +static const char *const rx_mux_text[] = { + "ZERO", "AIF1_PB", "AIF_MIX1_PB" +}; + +static const char * const wsa_macro_ear_spkr_pa_gain_text[] = { + "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB", + "G_4_DB", "G_5_DB", "G_6_DB" +}; + +static const char * const wsa_macro_speaker_boost_stage_text[] = { + "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2" +}; + +static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_ear_spkr_pa_gain_enum, + wsa_macro_ear_spkr_pa_gain_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_spkr_boost_stage_enum, + wsa_macro_speaker_boost_stage_text); + +/* RX INT0 */ +static const struct soc_enum rx0_prim_inp0_chain_enum = + SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0, + 0, 7, rx_text); + +static const struct soc_enum rx0_prim_inp1_chain_enum = + SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0, + 3, 7, rx_text); + +static const struct soc_enum rx0_prim_inp2_chain_enum = + SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1, + 3, 7, rx_text); + +static const struct soc_enum rx0_mix_chain_enum = + SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1, + 0, 5, rx_mix_text); + +static const struct snd_kcontrol_new rx0_prim_inp0_mux = + SOC_DAPM_ENUM("WSA_RX0 INP0 Mux", rx0_prim_inp0_chain_enum); + +static const struct snd_kcontrol_new rx0_prim_inp1_mux = + SOC_DAPM_ENUM("WSA_RX0 INP1 Mux", rx0_prim_inp1_chain_enum); + +static const struct snd_kcontrol_new rx0_prim_inp2_mux = + SOC_DAPM_ENUM("WSA_RX0 INP2 Mux", rx0_prim_inp2_chain_enum); + +static const struct snd_kcontrol_new rx0_mix_mux = + SOC_DAPM_ENUM("WSA_RX0 MIX Mux", rx0_mix_chain_enum); + +/* RX INT1 */ +static const struct soc_enum rx1_prim_inp0_chain_enum = + SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0, + 0, 7, rx_text); + +static const struct soc_enum rx1_prim_inp1_chain_enum = + SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0, + 3, 7, rx_text); + +static const struct soc_enum rx1_prim_inp2_chain_enum = + SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1, + 3, 7, rx_text); + +static const struct soc_enum rx1_mix_chain_enum = + SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1, + 0, 5, rx_mix_text); + +static const struct snd_kcontrol_new rx1_prim_inp0_mux = + SOC_DAPM_ENUM("WSA_RX1 INP0 Mux", rx1_prim_inp0_chain_enum); + +static const struct snd_kcontrol_new rx1_prim_inp1_mux = + SOC_DAPM_ENUM("WSA_RX1 INP1 Mux", rx1_prim_inp1_chain_enum); + +static const struct snd_kcontrol_new rx1_prim_inp2_mux = + SOC_DAPM_ENUM("WSA_RX1 INP2 Mux", rx1_prim_inp2_chain_enum); + +static const struct snd_kcontrol_new rx1_mix_mux = + SOC_DAPM_ENUM("WSA_RX1 MIX Mux", rx1_mix_chain_enum); + +static struct snd_soc_dai_ops wsa_macro_dai_ops = { + .hw_params = wsa_macro_hw_params, + .get_channel_map = wsa_macro_get_channel_map, +}; + +static struct snd_soc_dai_driver wsa_macro_dai[] = { + { + .name = "wsa_macro_rx1", + .id = WSA_MACRO_AIF1_PB, + .playback = { + .stream_name = "WSA_AIF1 Playback", + .rates = WSA_MACRO_RX_RATES, + .formats = WSA_MACRO_RX_FORMATS, + .rate_max = 384000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &wsa_macro_dai_ops, + }, + { + .name = "wsa_macro_rx_mix", + .id = WSA_MACRO_AIF_MIX1_PB, + .playback = { + .stream_name = "WSA_AIF_MIX1 Playback", + .rates = WSA_MACRO_RX_MIX_RATES, + .formats = WSA_MACRO_RX_FORMATS, + .rate_max = 192000, + .rate_min = 48000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &wsa_macro_dai_ops, + }, + { + .name = "wsa_macro_vifeedback", + .id = WSA_MACRO_AIF_VI, + .capture = { + .stream_name = "WSA_AIF_VI Capture", + .rates = SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .rate_max = 8000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &wsa_macro_dai_ops, + }, + { + .name = "wsa_macro_echo", + .id = WSA_MACRO_AIF_ECHO, + .capture = { + .stream_name = "WSA_AIF_ECHO Capture", + .rates = WSA_MACRO_ECHO_RATES, + .formats = WSA_MACRO_ECHO_FORMATS, + .rate_max = 48000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &wsa_macro_dai_ops, + }, +}; + +static const struct wsa_macro_reg_mask_val wsa_macro_spkr_default[] = { + {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80}, + {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80}, + {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01}, + {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01}, + {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x58}, + {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x58}, +}; + +static const struct wsa_macro_reg_mask_val wsa_macro_spkr_mode1[] = { + {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x00}, + {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x00}, + {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x00}, + {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x00}, + {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x44}, + {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x44}, +}; + +static bool wsa_macro_get_data(struct snd_soc_codec *codec, + struct device **wsa_dev, + struct wsa_macro_priv **wsa_priv, + const char *func_name) +{ + *wsa_dev = bolero_get_device_ptr(codec->dev, WSA_MACRO); + if (!(*wsa_dev)) { + dev_err(codec->dev, + "%s: null device for macro!\n", func_name); + return false; + } + *wsa_priv = dev_get_drvdata((*wsa_dev)); + if (!(*wsa_priv) || !(*wsa_priv)->codec) { + dev_err(codec->dev, + "%s: priv is null for macro!\n", func_name); + return false; + } + return true; +} + +/** + * wsa_macro_set_spkr_gain_offset - offset the speaker path + * gain with the given offset value. + * + * @codec: codec instance + * @offset: Indicates speaker path gain offset value. + * + * Returns 0 on success or -EINVAL on error. + */ +int wsa_macro_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset) +{ + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!codec) { + pr_err("%s: NULL codec pointer!\n", __func__); + return -EINVAL; + } + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + wsa_priv->spkr_gain_offset = offset; + return 0; +} +EXPORT_SYMBOL(wsa_macro_set_spkr_gain_offset); + +/** + * wsa_macro_set_spkr_mode - Configures speaker compander and smartboost + * settings based on speaker mode. + * + * @codec: codec instance + * @mode: Indicates speaker configuration mode. + * + * Returns 0 on success or -EINVAL on error. + */ +int wsa_macro_set_spkr_mode(struct snd_soc_codec *codec, int mode) +{ + int i; + const struct wsa_macro_reg_mask_val *regs; + int size; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!codec) { + pr_err("%s: NULL codec pointer!\n", __func__); + return -EINVAL; + } + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + switch (mode) { + case SPKR_MODE_1: + regs = wsa_macro_spkr_mode1; + size = ARRAY_SIZE(wsa_macro_spkr_mode1); + break; + default: + regs = wsa_macro_spkr_default; + size = ARRAY_SIZE(wsa_macro_spkr_default); + break; + } + + wsa_priv->spkr_mode = mode; + for (i = 0; i < size; i++) + snd_soc_update_bits(codec, regs[i].reg, + regs[i].mask, regs[i].val); + return 0; +} +EXPORT_SYMBOL(wsa_macro_set_spkr_mode); + +static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, + u8 int_prim_fs_rate_reg_val, + u32 sample_rate) +{ + u8 int_1_mix1_inp; + u32 j, port; + u16 int_mux_cfg0, int_mux_cfg1; + u16 int_fs_reg; + u8 int_mux_cfg0_val, int_mux_cfg1_val; + u8 inp0_sel, inp1_sel, inp2_sel; + struct snd_soc_codec *codec = dai->codec; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id], + WSA_MACRO_RX_MAX) { + int_1_mix1_inp = port; + if ((int_1_mix1_inp < WSA_MACRO_RX0) || + (int_1_mix1_inp > WSA_MACRO_RX_MIX1)) { + dev_err(wsa_dev, + "%s: Invalid RX port, Dai ID is %d\n", + __func__, dai->id); + return -EINVAL; + } + + int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0; + + /* + * Loop through all interpolator MUX inputs and find out + * to which interpolator input, the cdc_dma rx port + * is connected + */ + for (j = 0; j < NUM_INTERPOLATORS; j++) { + int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET; + + int_mux_cfg0_val = snd_soc_read(codec, int_mux_cfg0); + int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1); + inp0_sel = int_mux_cfg0_val & WSA_MACRO_MUX_INP_MASK1; + inp1_sel = (int_mux_cfg0_val >> + WSA_MACRO_MUX_INP_SHFT) & + WSA_MACRO_MUX_INP_MASK2; + inp2_sel = (int_mux_cfg1_val >> + WSA_MACRO_MUX_INP_SHFT) & + WSA_MACRO_MUX_INP_MASK2; + if ((inp0_sel == int_1_mix1_inp) || + (inp1_sel == int_1_mix1_inp) || + (inp2_sel == int_1_mix1_inp)) { + int_fs_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL + + WSA_MACRO_RX_PATH_OFFSET * j; + dev_dbg(wsa_dev, + "%s: AIF_PB DAI(%d) connected to INT%u_1\n", + __func__, dai->id, j); + dev_dbg(wsa_dev, + "%s: set INT%u_1 sample rate to %u\n", + __func__, j, sample_rate); + /* sample_rate is in Hz */ + snd_soc_update_bits(codec, int_fs_reg, + WSA_MACRO_FS_RATE_MASK, + int_prim_fs_rate_reg_val); + } + int_mux_cfg0 += WSA_MACRO_MUX_CFG_OFFSET; + } + } + + return 0; +} + +static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, + u8 int_mix_fs_rate_reg_val, + u32 sample_rate) +{ + u8 int_2_inp; + u32 j, port; + u16 int_mux_cfg1, int_fs_reg; + u8 int_mux_cfg1_val; + struct snd_soc_codec *codec = dai->codec; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + + for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id], + WSA_MACRO_RX_MAX) { + int_2_inp = port; + if ((int_2_inp < WSA_MACRO_RX0) || + (int_2_inp > WSA_MACRO_RX_MIX1)) { + dev_err(wsa_dev, + "%s: Invalid RX port, Dai ID is %d\n", + __func__, dai->id); + return -EINVAL; + } + + int_mux_cfg1 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1; + for (j = 0; j < NUM_INTERPOLATORS; j++) { + int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1) & + WSA_MACRO_MUX_INP_MASK1; + if (int_mux_cfg1_val == int_2_inp) { + int_fs_reg = + BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL + + WSA_MACRO_RX_PATH_OFFSET * j; + + dev_dbg(wsa_dev, + "%s: AIF_PB DAI(%d) connected to INT%u_2\n", + __func__, dai->id, j); + dev_dbg(wsa_dev, + "%s: set INT%u_2 sample rate to %u\n", + __func__, j, sample_rate); + snd_soc_update_bits(codec, int_fs_reg, + WSA_MACRO_FS_RATE_MASK, + int_mix_fs_rate_reg_val); + } + int_mux_cfg1 += WSA_MACRO_MUX_CFG_OFFSET; + } + } + return 0; +} + +static int wsa_macro_set_interpolator_rate(struct snd_soc_dai *dai, + u32 sample_rate) +{ + int rate_val = 0; + int i, ret; + + /* set mixing path rate */ + for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) { + if (sample_rate == + int_mix_sample_rate_val[i].sample_rate) { + rate_val = + int_mix_sample_rate_val[i].rate_val; + break; + } + } + if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) || + (rate_val < 0)) + goto prim_rate; + ret = wsa_macro_set_mix_interpolator_rate(dai, + (u8) rate_val, sample_rate); +prim_rate: + /* set primary path sample rate */ + for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) { + if (sample_rate == + int_prim_sample_rate_val[i].sample_rate) { + rate_val = + int_prim_sample_rate_val[i].rate_val; + break; + } + } + if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) || + (rate_val < 0)) + return -EINVAL; + ret = wsa_macro_set_prim_interpolator_rate(dai, + (u8) rate_val, sample_rate); + return ret; +} + +static int wsa_macro_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + int ret; + + dev_dbg(codec->dev, + "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__, + dai->name, dai->id, params_rate(params), + params_channels(params)); + + switch (substream->stream) { + case SNDRV_PCM_STREAM_PLAYBACK: + ret = wsa_macro_set_interpolator_rate(dai, params_rate(params)); + if (ret) { + dev_err(codec->dev, + "%s: cannot set sample rate: %u\n", + __func__, params_rate(params)); + return ret; + } + break; + case SNDRV_PCM_STREAM_CAPTURE: + default: + break; + } + return 0; +} + +static int wsa_macro_get_channel_map(struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot) +{ + struct snd_soc_codec *codec = dai->codec; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + wsa_priv = dev_get_drvdata(wsa_dev); + if (!wsa_priv) + return -EINVAL; + + switch (dai->id) { + case WSA_MACRO_AIF_VI: + case WSA_MACRO_AIF_ECHO: + *tx_slot = wsa_priv->active_ch_mask[dai->id]; + *tx_num = wsa_priv->active_ch_cnt[dai->id]; + break; + case WSA_MACRO_AIF1_PB: + case WSA_MACRO_AIF_MIX1_PB: + *rx_slot = wsa_priv->active_ch_mask[dai->id]; + *rx_num = wsa_priv->active_ch_cnt[dai->id]; + break; + default: + dev_err(wsa_dev, "%s: Invalid AIF\n", __func__); + break; + } + return 0; +} + +static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv, + bool mclk_enable, bool dapm) +{ + struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL); + int ret = 0; + + dev_dbg(wsa_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", + __func__, mclk_enable, dapm, wsa_priv->wsa_mclk_users); + + mutex_lock(&wsa_priv->mclk_lock); + if (mclk_enable) { + wsa_priv->wsa_mclk_users++; + if (wsa_priv->wsa_mclk_users == 1) { + ret = bolero_request_clock(wsa_priv->dev, + WSA_MACRO, MCLK_MUX0, true); + if (ret < 0) { + dev_err(wsa_priv->dev, + "%s: wsa request clock enable failed\n", + __func__); + goto exit; + } + regcache_mark_dirty(regmap); + regcache_sync_region(regmap, + WSA_START_OFFSET, + WSA_MAX_OFFSET); + /* 9.6MHz MCLK, set value 0x00 if other frequency */ + regmap_update_bits(regmap, + BOLERO_CDC_WSA_TOP_FREQ_MCLK, 0x01, 0x01); + regmap_update_bits(regmap, + BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + regmap_update_bits(regmap, + BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); + } + } else { + wsa_priv->wsa_mclk_users--; + if (wsa_priv->wsa_mclk_users == 0) { + regmap_update_bits(regmap, + BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x00); + regmap_update_bits(regmap, + BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x00); + bolero_request_clock(wsa_priv->dev, + WSA_MACRO, MCLK_MUX0, false); + } + } +exit: + mutex_unlock(&wsa_priv->mclk_lock); + return ret; +} + +static int wsa_macro_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int ret = 0; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + dev_dbg(wsa_dev, "%s: event = %d\n", __func__, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = wsa_macro_mclk_enable(wsa_priv, 1, true); + break; + case SND_SOC_DAPM_POST_PMD: + wsa_macro_mclk_enable(wsa_priv, 0, true); + break; + default: + dev_err(wsa_priv->dev, + "%s: invalid DAPM event %d\n", __func__, event); + ret = -EINVAL; + } + return ret; +} + +static int wsa_macro_mclk_ctrl(struct device *dev, bool enable) +{ + struct wsa_macro_priv *wsa_priv = dev_get_drvdata(dev); + int ret = 0; + + if (!wsa_priv) + return -EINVAL; + + if (enable) { + ret = clk_prepare_enable(wsa_priv->wsa_core_clk); + if (ret < 0) { + dev_err(dev, "%s:wsa mclk enable failed\n", __func__); + goto exit; + } + ret = clk_prepare_enable(wsa_priv->wsa_npl_clk); + if (ret < 0) { + dev_err(dev, "%s:wsa npl_clk enable failed\n", + __func__); + clk_disable_unprepare(wsa_priv->wsa_core_clk); + goto exit; + } + } else { + clk_disable_unprepare(wsa_priv->wsa_npl_clk); + clk_disable_unprepare(wsa_priv->wsa_core_clk); + } +exit: + return ret; +} + +static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (test_bit(WSA_MACRO_TX0, + &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) { + dev_dbg(wsa_dev, "%s: spkr1 enabled\n", __func__); + /* Enable V&I sensing */ + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, + 0x20, 0x20); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL, + 0x20, 0x20); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, + 0x0F, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL, + 0x0F, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, + 0x10, 0x10); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL, + 0x10, 0x10); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, + 0x20, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL, + 0x20, 0x00); + } + if (test_bit(WSA_MACRO_TX1, + &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) { + dev_dbg(wsa_dev, "%s: spkr2 enabled\n", __func__); + /* Enable V&I sensing */ + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, + 0x20, 0x20); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL, + 0x20, 0x20); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, + 0x0F, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL, + 0x0F, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, + 0x10, 0x10); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL, + 0x10, 0x10); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, + 0x20, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL, + 0x20, 0x00); + } + break; + case SND_SOC_DAPM_POST_PMD: + if (test_bit(WSA_MACRO_TX0, + &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) { + /* Disable V&I sensing */ + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, + 0x20, 0x20); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL, + 0x20, 0x20); + dev_dbg(wsa_dev, "%s: spkr1 disabled\n", __func__); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, + 0x10, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL, + 0x10, 0x00); + } + if (test_bit(WSA_MACRO_TX1, + &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) { + /* Disable V&I sensing */ + dev_dbg(wsa_dev, "%s: spkr2 disabled\n", __func__); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, + 0x20, 0x20); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL, + 0x20, 0x20); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, + 0x10, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL, + 0x10, 0x00); + } + break; + } + + return 0; +} + +static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 gain_reg; + int offset_val = 0; + int val = 0; + + dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + + switch (w->reg) { + case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL: + gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL; + break; + case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL: + gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL; + break; + default: + dev_err(codec->dev, "%s: No gain register avail for %s\n", + __func__, w->name); + return 0; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + break; + case SND_SOC_DAPM_POST_PMD: + break; + } + + return 0; +} + +static void wsa_macro_hd2_control(struct snd_soc_codec *codec, + u16 reg, int event) +{ + u16 hd2_scale_reg; + u16 hd2_enable_reg = 0; + + if (reg == BOLERO_CDC_WSA_RX0_RX_PATH_CTL) { + hd2_scale_reg = BOLERO_CDC_WSA_RX0_RX_PATH_SEC3; + hd2_enable_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0; + } + if (reg == BOLERO_CDC_WSA_RX1_RX_PATH_CTL) { + hd2_scale_reg = BOLERO_CDC_WSA_RX1_RX_PATH_SEC3; + hd2_enable_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG0; + } + + if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { + snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x10); + snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x01); + snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x04); + } + + if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x00); + snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x00); + snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x00); + } +} + +static int wsa_macro_enable_swr(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int ch_cnt; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) && + !wsa_priv->rx_0_count) + wsa_priv->rx_0_count++; + if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) && + !wsa_priv->rx_1_count) + wsa_priv->rx_1_count++; + ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count; + + swrm_wcd_notify( + wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, + SWR_DEVICE_UP, NULL); + swrm_wcd_notify( + wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, + SWR_SET_NUM_RX_CH, &ch_cnt); + break; + case SND_SOC_DAPM_POST_PMD: + if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) && + wsa_priv->rx_0_count) + wsa_priv->rx_0_count--; + if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) && + wsa_priv->rx_1_count) + wsa_priv->rx_1_count--; + ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count; + + swrm_wcd_notify( + wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, + SWR_SET_NUM_RX_CH, &ch_cnt); + break; + } + dev_dbg(wsa_priv->dev, "%s: current swr ch cnt: %d\n", + __func__, wsa_priv->rx_0_count + wsa_priv->rx_1_count); + + return 0; +} + +static int wsa_macro_config_compander(struct snd_soc_codec *codec, + int comp, int event) +{ + u16 comp_ctl0_reg, rx_path_cfg0_reg; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n", + __func__, event, comp + 1, wsa_priv->comp_enabled[comp]); + + if (!wsa_priv->comp_enabled[comp]) + return 0; + + comp_ctl0_reg = BOLERO_CDC_WSA_COMPANDER0_CTL0 + + (comp * WSA_MACRO_RX_COMP_OFFSET); + rx_path_cfg0_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG0 + + (comp * WSA_MACRO_RX_PATH_OFFSET); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Compander Clock */ + snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); + snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); + } + + return 0; +} + +static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind) +{ + u16 prim_int_reg = 0; + + switch (reg) { + case BOLERO_CDC_WSA_RX0_RX_PATH_CTL: + case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL: + prim_int_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL; + *ind = 0; + break; + case BOLERO_CDC_WSA_RX1_RX_PATH_CTL: + case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL: + prim_int_reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL; + *ind = 1; + break; + } + + return prim_int_reg; +} + +static int wsa_macro_enable_prim_interpolator( + struct snd_soc_codec *codec, + u16 reg, int event) +{ + u16 prim_int_reg; + u16 ind = 0; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + prim_int_reg = wsa_macro_interp_get_primary_reg(reg, &ind); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wsa_priv->prim_int_users[ind]++; + if (wsa_priv->prim_int_users[ind] == 1) { + snd_soc_update_bits(codec, + prim_int_reg + WSA_MACRO_RX_PATH_CFG3_OFFSET, + 0x03, 0x03); + snd_soc_update_bits(codec, prim_int_reg, + 0x10, 0x10); + wsa_macro_hd2_control(codec, prim_int_reg, event); + snd_soc_update_bits(codec, + prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET, + 0x1, 0x1); + snd_soc_update_bits(codec, prim_int_reg, + 1 << 0x5, 1 << 0x5); + } + if ((reg != prim_int_reg) && + ((snd_soc_read(codec, prim_int_reg)) & 0x10)) + snd_soc_update_bits(codec, reg, 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMD: + wsa_priv->prim_int_users[ind]--; + if (wsa_priv->prim_int_users[ind] == 0) { + snd_soc_update_bits(codec, prim_int_reg, + 1 << 0x5, 0 << 0x5); + snd_soc_update_bits(codec, prim_int_reg, + 0x40, 0x40); + snd_soc_update_bits(codec, prim_int_reg, + 0x40, 0x00); + wsa_macro_hd2_control(codec, prim_int_reg, event); + } + break; + } + + dev_dbg(codec->dev, "%s: primary interpolator: INT%d, users: %d\n", + __func__, ind, wsa_priv->prim_int_users[ind]); + return 0; +} + +static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 gain_reg; + u16 reg; + int val; + int offset_val = 0; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + + if (!(strcmp(w->name, "WSA_RX INT0 INTERP"))) { + reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL; + gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_CTL; + } else if (!(strcmp(w->name, "WSA_RX INT1 INTERP"))) { + reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL; + gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_CTL; + } else { + dev_err(codec->dev, "%s: Interpolator reg not found\n", + __func__); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Reset if needed */ + wsa_macro_enable_prim_interpolator(codec, reg, event); + break; + case SND_SOC_DAPM_POST_PMU: + wsa_macro_config_compander(codec, w->shift, event); + /* apply gain after int clk is enabled */ + if ((wsa_priv->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && + (wsa_priv->comp_enabled[WSA_MACRO_COMP1] || + wsa_priv->comp_enabled[WSA_MACRO_COMP2]) && + (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL || + gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) { + snd_soc_update_bits(codec, BOLERO_CDC_WSA_RX0_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0, + 0x01, 0x01); + snd_soc_update_bits(codec, BOLERO_CDC_WSA_RX1_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0, + 0x01, 0x01); + offset_val = -2; + } + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + wsa_macro_config_ear_spkr_gain(codec, wsa_priv, + event, gain_reg); + break; + case SND_SOC_DAPM_POST_PMD: + wsa_macro_config_compander(codec, w->shift, event); + wsa_macro_enable_prim_interpolator(codec, reg, event); + if ((wsa_priv->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && + (wsa_priv->comp_enabled[WSA_MACRO_COMP1] || + wsa_priv->comp_enabled[WSA_MACRO_COMP2]) && + (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL || + gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) { + snd_soc_update_bits(codec, BOLERO_CDC_WSA_RX0_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0, + 0x01, 0x00); + snd_soc_update_bits(codec, BOLERO_CDC_WSA_RX1_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0, + 0x01, 0x00); + offset_val = 2; + val = snd_soc_read(codec, gain_reg); + val += offset_val; + snd_soc_write(codec, gain_reg, val); + } + wsa_macro_config_ear_spkr_gain(codec, wsa_priv, + event, gain_reg); + break; + } + + return 0; +} + +static int wsa_macro_config_ear_spkr_gain(struct snd_soc_codec *codec, + struct wsa_macro_priv *wsa_priv, + int event, int gain_reg) +{ + int comp_gain_offset, val; + + switch (wsa_priv->spkr_mode) { + /* Compander gain in SPKR_MODE1 case is 12 dB */ + case SPKR_MODE_1: + comp_gain_offset = -12; + break; + /* Default case compander gain is 15 dB */ + default: + comp_gain_offset = -15; + break; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* Apply ear spkr gain only if compander is enabled */ + if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] && + (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) && + (wsa_priv->ear_spkr_gain != 0)) { + /* For example, val is -8(-12+5-1) for 4dB of gain */ + val = comp_gain_offset + wsa_priv->ear_spkr_gain - 1; + snd_soc_write(codec, gain_reg, val); + + dev_dbg(wsa_priv->dev, "%s: RX0 Volume %d dB\n", + __func__, val); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* + * Reset RX0 volume to 0 dB if compander is enabled and + * ear_spkr_gain is non-zero. + */ + if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] && + (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) && + (wsa_priv->ear_spkr_gain != 0)) { + snd_soc_write(codec, gain_reg, 0x0); + + dev_dbg(wsa_priv->dev, "%s: Reset RX0 Volume to 0 dB\n", + __func__); + } + break; + } + + return 0; +} + +static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 boost_path_ctl, boost_path_cfg1; + u16 reg, reg_mix; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + + if (!strcmp(w->name, "WSA_RX INT0 CHAIN")) { + boost_path_ctl = BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL; + boost_path_cfg1 = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1; + reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL; + reg_mix = BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL; + } else if (!strcmp(w->name, "WSA_RX INT1 CHAIN")) { + boost_path_ctl = BOLERO_CDC_WSA_BOOST1_BOOST_PATH_CTL; + boost_path_cfg1 = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1; + reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL; + reg_mix = BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL; + } else { + dev_err(codec->dev, "%s: unknown widget: %s\n", + __func__, w->name); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x01); + snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x10); + snd_soc_update_bits(codec, reg, 0x10, 0x00); + if ((snd_soc_read(codec, reg_mix)) & 0x10) + snd_soc_update_bits(codec, reg_mix, 0x10, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x00); + snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x00); + break; + } + + return 0; +} + +static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = wsa_priv->comp_enabled[comp]; + return 0; +} + +static int wsa_macro_set_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int value = ucontrol->value.integer.value[0]; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n", + __func__, comp + 1, wsa_priv->comp_enabled[comp], value); + wsa_priv->comp_enabled[comp] = value; + + return 0; +} + +static int wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = wsa_priv->ear_spkr_gain; + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + wsa_priv->ear_spkr_gain = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: gain = %d\n", __func__, + wsa_priv->ear_spkr_gain); + + return 0; +} + +static int wsa_macro_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max = 0; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + bst_state_max = snd_soc_read(codec, BOLERO_CDC_WSA_BOOST0_BOOST_CTL); + bst_state_max = (bst_state_max & 0x0c) >> 2; + ucontrol->value.integer.value[0] = bst_state_max; + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int wsa_macro_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + bst_state_max = ucontrol->value.integer.value[0] << 2; + snd_soc_update_bits(codec, BOLERO_CDC_WSA_BOOST0_BOOST_CTL, + 0x0c, bst_state_max); + + return 0; +} + +static int wsa_macro_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max = 0; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + bst_state_max = snd_soc_read(codec, BOLERO_CDC_WSA_BOOST1_BOOST_CTL); + bst_state_max = (bst_state_max & 0x0c) >> 2; + ucontrol->value.integer.value[0] = bst_state_max; + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int wsa_macro_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + bst_state_max = ucontrol->value.integer.value[0] << 2; + snd_soc_update_bits(codec, BOLERO_CDC_WSA_BOOST1_BOOST_CTL, + 0x0c, bst_state_max); + + return 0; +} + +static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = + wsa_priv->rx_port_value[widget->shift]; + return 0; +} + +static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + u32 rx_port_value = ucontrol->value.integer.value[0]; + u32 bit_input = 0; + u32 aif_rst; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + aif_rst = wsa_priv->rx_port_value[widget->shift]; + if (!rx_port_value) { + if (aif_rst == 0) { + dev_err(wsa_dev, "%s: AIF reset already\n", __func__); + return 0; + } + } + wsa_priv->rx_port_value[widget->shift] = rx_port_value; + + bit_input = widget->shift; + if (widget->shift >= WSA_MACRO_RX_MIX) + bit_input %= WSA_MACRO_RX_MIX; + + switch (rx_port_value) { + case 0: + clear_bit(bit_input, + &wsa_priv->active_ch_mask[aif_rst - 1]); + wsa_priv->active_ch_cnt[aif_rst - 1]--; + break; + case 1: + case 2: + set_bit(bit_input, + &wsa_priv->active_ch_mask[rx_port_value - 1]); + wsa_priv->active_ch_cnt[rx_port_value - 1]++; + break; + default: + dev_err(wsa_dev, + "%s: Invalid AIF_ID for WSA RX MUX\n", __func__); + return -EINVAL; + } + + snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, + rx_port_value, e, update); + return 0; +} + +static const struct snd_kcontrol_new wsa_macro_snd_controls[] = { + SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum, + wsa_macro_ear_spkr_pa_gain_get, + wsa_macro_ear_spkr_pa_gain_put), + SOC_ENUM_EXT("SPKR Left Boost Max State", + wsa_macro_spkr_boost_stage_enum, + wsa_macro_spkr_left_boost_stage_get, + wsa_macro_spkr_left_boost_stage_put), + SOC_ENUM_EXT("SPKR Right Boost Max State", + wsa_macro_spkr_boost_stage_enum, + wsa_macro_spkr_right_boost_stage_get, + wsa_macro_spkr_right_boost_stage_put), + SOC_SINGLE_SX_TLV("WSA_RX0 Digital Volume", + BOLERO_CDC_WSA_RX0_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("WSA_RX1 Digital Volume", + BOLERO_CDC_WSA_RX1_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0, + wsa_macro_get_compander, wsa_macro_set_compander), + SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0, + wsa_macro_get_compander, wsa_macro_set_compander), +}; + +static const struct soc_enum rx_mux_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_mux_text), rx_mux_text); + +static const struct snd_kcontrol_new rx_mux[WSA_MACRO_RX_MAX] = { + SOC_DAPM_ENUM_EXT("WSA RX0 Mux", rx_mux_enum, + wsa_macro_rx_mux_get, wsa_macro_rx_mux_put), + SOC_DAPM_ENUM_EXT("WSA RX1 Mux", rx_mux_enum, + wsa_macro_rx_mux_get, wsa_macro_rx_mux_put), + SOC_DAPM_ENUM_EXT("WSA RX_MIX0 Mux", rx_mux_enum, + wsa_macro_rx_mux_get, wsa_macro_rx_mux_put), + SOC_DAPM_ENUM_EXT("WSA RX_MIX1 Mux", rx_mux_enum, + wsa_macro_rx_mux_get, wsa_macro_rx_mux_put), +}; + +static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_multi_mixer_control *mixer = + ((struct soc_multi_mixer_control *)kcontrol->private_value); + u32 dai_id = widget->shift; + u32 spk_tx_id = mixer->shift; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + if (test_bit(spk_tx_id, &wsa_priv->active_ch_mask[dai_id])) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; + + return 0; +} + +static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_multi_mixer_control *mixer = + ((struct soc_multi_mixer_control *)kcontrol->private_value); + u32 spk_tx_id = mixer->shift; + u32 enable = ucontrol->value.integer.value[0]; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + wsa_priv->vi_feed_value = ucontrol->value.integer.value[0]; + + if (enable) { + if (spk_tx_id == WSA_MACRO_TX0 && + !test_bit(WSA_MACRO_TX0, + &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) { + set_bit(WSA_MACRO_TX0, + &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]); + wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++; + } + if (spk_tx_id == WSA_MACRO_TX1 && + !test_bit(WSA_MACRO_TX1, + &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) { + set_bit(WSA_MACRO_TX1, + &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]); + wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]++; + } + } else { + if (spk_tx_id == WSA_MACRO_TX0 && + test_bit(WSA_MACRO_TX0, + &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) { + clear_bit(WSA_MACRO_TX0, + &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]); + wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--; + } + if (spk_tx_id == WSA_MACRO_TX1 && + test_bit(WSA_MACRO_TX1, + &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) { + clear_bit(WSA_MACRO_TX1, + &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI]); + wsa_priv->active_ch_cnt[WSA_MACRO_AIF_VI]--; + } + } + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL); + + return 0; +} + +static const struct snd_kcontrol_new aif_vi_mixer[] = { + SOC_SINGLE_EXT("WSA_SPKR_VI_1", SND_SOC_NOPM, WSA_MACRO_TX0, 1, 0, + wsa_macro_vi_feed_mixer_get, + wsa_macro_vi_feed_mixer_put), + SOC_SINGLE_EXT("WSA_SPKR_VI_2", SND_SOC_NOPM, WSA_MACRO_TX1, 1, 0, + wsa_macro_vi_feed_mixer_get, + wsa_macro_vi_feed_mixer_put), +}; + +static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN("WSA AIF1 PB", "WSA_AIF1 Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_IN("WSA AIF_MIX1 PB", "WSA_AIF_MIX1 Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_OUT_E("WSA AIF_VI", "WSA_AIF_VI Capture", 0, + SND_SOC_NOPM, WSA_MACRO_AIF_VI, 0, + wsa_macro_enable_vi_feedback, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_AIF_OUT("WSA AIF_ECHO", "WSA_AIF_ECHO Capture", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_MIXER("WSA_AIF_VI Mixer", SND_SOC_NOPM, WSA_MACRO_AIF_VI, + 0, aif_vi_mixer, ARRAY_SIZE(aif_vi_mixer)), + + SND_SOC_DAPM_MUX("WSA RX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX0, 0, + &rx_mux[WSA_MACRO_RX0]), + SND_SOC_DAPM_MUX("WSA RX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX1, 0, + &rx_mux[WSA_MACRO_RX1]), + SND_SOC_DAPM_MUX("WSA RX_MIX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 0, + &rx_mux[WSA_MACRO_RX_MIX0]), + SND_SOC_DAPM_MUX("WSA RX_MIX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 0, + &rx_mux[WSA_MACRO_RX_MIX1]), + + SND_SOC_DAPM_MIXER("WSA RX0", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("WSA RX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MUX_E("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0, + &rx0_prim_inp0_mux, wsa_macro_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0, + &rx0_prim_inp1_mux, wsa_macro_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0, + &rx0_prim_inp2_mux, wsa_macro_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, 0, 0, + &rx0_mix_mux, wsa_macro_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0, + &rx1_prim_inp0_mux, wsa_macro_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0, + &rx1_prim_inp1_mux, wsa_macro_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0, + &rx1_prim_inp2_mux, wsa_macro_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, 0, 0, + &rx1_mix_mux, wsa_macro_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("WSA_RX INT1 MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MIXER_E("WSA_RX INT0 INTERP", SND_SOC_NOPM, + WSA_MACRO_COMP1, 0, NULL, 0, wsa_macro_enable_interpolator, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("WSA_RX INT1 INTERP", SND_SOC_NOPM, + WSA_MACRO_COMP2, 0, NULL, 0, wsa_macro_enable_interpolator, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER_E("WSA_RX INT0 CHAIN", SND_SOC_NOPM, 0, 0, + NULL, 0, wsa_macro_spk_boost_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("WSA_RX INT1 CHAIN", SND_SOC_NOPM, 0, 0, + NULL, 0, wsa_macro_spk_boost_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_INPUT("VIINPUT_WSA"), + + SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"), + SND_SOC_DAPM_OUTPUT("WSA_SPK2 OUT"), + + SND_SOC_DAPM_SUPPLY_S("WSA_MCLK", 0, SND_SOC_NOPM, 0, 0, + wsa_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_route wsa_audio_map[] = { + /* VI Feedback */ + {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_1", "VIINPUT_WSA"}, + {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_2", "VIINPUT_WSA"}, + {"WSA AIF_VI", NULL, "WSA_AIF_VI Mixer"}, + {"WSA AIF_VI", NULL, "WSA_MCLK"}, + + {"WSA AIF1 PB", NULL, "WSA_MCLK"}, + {"WSA AIF_MIX1 PB", NULL, "WSA_MCLK"}, + + {"WSA RX0 MUX", "AIF1_PB", "WSA AIF1 PB"}, + {"WSA RX1 MUX", "AIF1_PB", "WSA AIF1 PB"}, + {"WSA RX_MIX0 MUX", "AIF1_PB", "WSA AIF1 PB"}, + {"WSA RX_MIX1 MUX", "AIF1_PB", "WSA AIF1 PB"}, + + {"WSA RX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"}, + {"WSA RX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"}, + {"WSA RX_MIX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"}, + {"WSA RX_MIX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"}, + + {"WSA RX0", NULL, "WSA RX0 MUX"}, + {"WSA RX1", NULL, "WSA RX1 MUX"}, + {"WSA RX_MIX0", NULL, "WSA RX_MIX0 MUX"}, + {"WSA RX_MIX1", NULL, "WSA RX_MIX1 MUX"}, + + {"WSA_RX0 INP0", "RX0", "WSA RX0"}, + {"WSA_RX0 INP0", "RX1", "WSA RX1"}, + {"WSA_RX0 INP0", "RX_MIX0", "WSA RX_MIX0"}, + {"WSA_RX0 INP0", "RX_MIX1", "WSA RX_MIX1"}, + {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP0"}, + + {"WSA_RX0 INP1", "RX0", "WSA RX0"}, + {"WSA_RX0 INP1", "RX1", "WSA RX1"}, + {"WSA_RX0 INP1", "RX_MIX0", "WSA RX_MIX0"}, + {"WSA_RX0 INP1", "RX_MIX1", "WSA RX_MIX1"}, + {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP1"}, + + {"WSA_RX0 INP2", "RX0", "WSA RX0"}, + {"WSA_RX0 INP2", "RX1", "WSA RX1"}, + {"WSA_RX0 INP2", "RX_MIX0", "WSA RX_MIX0"}, + {"WSA_RX0 INP2", "RX_MIX1", "WSA RX_MIX1"}, + {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP2"}, + + {"WSA_RX0 MIX INP", "RX0", "WSA RX0"}, + {"WSA_RX0 MIX INP", "RX1", "WSA RX1"}, + {"WSA_RX0 MIX INP", "RX_MIX0", "WSA RX_MIX0"}, + {"WSA_RX0 MIX INP", "RX_MIX1", "WSA RX_MIX1"}, + {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX0 MIX INP"}, + + {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"}, + {"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"}, + {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"}, + {"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"}, + + {"WSA_RX1 INP0", "RX0", "WSA RX0"}, + {"WSA_RX1 INP0", "RX1", "WSA RX1"}, + {"WSA_RX1 INP0", "RX_MIX0", "WSA RX_MIX0"}, + {"WSA_RX1 INP0", "RX_MIX1", "WSA RX_MIX1"}, + {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP0"}, + + {"WSA_RX1 INP1", "RX0", "WSA RX0"}, + {"WSA_RX1 INP1", "RX1", "WSA RX1"}, + {"WSA_RX1 INP1", "RX_MIX0", "WSA RX_MIX0"}, + {"WSA_RX1 INP1", "RX_MIX1", "WSA RX_MIX1"}, + {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP1"}, + + {"WSA_RX1 INP2", "RX0", "WSA RX0"}, + {"WSA_RX1 INP2", "RX1", "WSA RX1"}, + {"WSA_RX1 INP2", "RX_MIX0", "WSA RX_MIX0"}, + {"WSA_RX1 INP2", "RX_MIX1", "WSA RX_MIX1"}, + {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP2"}, + + {"WSA_RX1 MIX INP", "RX0", "WSA RX0"}, + {"WSA_RX1 MIX INP", "RX1", "WSA RX1"}, + {"WSA_RX1 MIX INP", "RX_MIX0", "WSA RX_MIX0"}, + {"WSA_RX1 MIX INP", "RX_MIX1", "WSA RX_MIX1"}, + {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX1 MIX INP"}, + + {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"}, + {"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"}, + {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"}, + {"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"}, +}; + +static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = { + {BOLERO_CDC_WSA_BOOST0_BOOST_CFG1, 0x3F, 0x12}, + {BOLERO_CDC_WSA_BOOST0_BOOST_CFG2, 0x1C, 0x08}, + {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x18}, + {BOLERO_CDC_WSA_BOOST1_BOOST_CFG1, 0x3F, 0x12}, + {BOLERO_CDC_WSA_BOOST1_BOOST_CFG2, 0x1C, 0x08}, + {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x18}, + {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x70, 0x58}, + {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x70, 0x58}, + {BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 0x08, 0x08}, + {BOLERO_CDC_WSA_RX1_RX_PATH_CFG1, 0x08, 0x08}, + {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x02, 0x02}, + {BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x01, 0x01}, + {BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80}, + {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80}, + {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01}, + {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01}, + {BOLERO_CDC_WSA_RX0_RX_PATH_CFG0, 0x01, 0x01}, + {BOLERO_CDC_WSA_RX1_RX_PATH_CFG0, 0x01, 0x01}, + {BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x01, 0x01}, + {BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x01, 0x01}, +}; + +static void wsa_macro_init_reg(struct snd_soc_codec *codec) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(wsa_macro_reg_init); i++) + snd_soc_update_bits(codec, + wsa_macro_reg_init[i].reg, + wsa_macro_reg_init[i].mask, + wsa_macro_reg_init[i].val); +} + +static int wsa_swrm_clock(void *handle, bool enable) +{ + struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle; + struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL); + + mutex_lock(&wsa_priv->swr_clk_lock); + + dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n", + __func__, (enable ? "enable" : "disable")); + if (enable) { + wsa_priv->swr_clk_users++; + if (wsa_priv->swr_clk_users == 1) { + wsa_macro_mclk_enable(wsa_priv, 1, true); + regmap_update_bits(regmap, + BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x01); + regmap_update_bits(regmap, + BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, + 0x1C, 0x0C); + msm_cdc_pinctrl_select_active_state( + wsa_priv->wsa_swr_gpio_p); + } + } else { + wsa_priv->swr_clk_users--; + if (wsa_priv->swr_clk_users == 0) { + regmap_update_bits(regmap, + BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x00); + msm_cdc_pinctrl_select_sleep_state( + wsa_priv->wsa_swr_gpio_p); + wsa_macro_mclk_enable(wsa_priv, 0, true); + } + } + dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n", + __func__, wsa_priv->swr_clk_users); + mutex_unlock(&wsa_priv->swr_clk_lock); + return 0; +} + +static int wsa_macro_init(struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + int ret; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + wsa_dev = bolero_get_device_ptr(codec->dev, WSA_MACRO); + if (!wsa_dev) { + dev_err(codec->dev, + "%s: null device for macro!\n", __func__); + return -EINVAL; + } + wsa_priv = dev_get_drvdata(wsa_dev); + if (!wsa_priv) { + dev_err(codec->dev, + "%s: priv is null for macro!\n", __func__); + return -EINVAL; + } + + ret = snd_soc_dapm_new_controls(dapm, wsa_macro_dapm_widgets, + ARRAY_SIZE(wsa_macro_dapm_widgets)); + if (ret < 0) { + dev_err(wsa_dev, "%s: Failed to add controls\n", __func__); + return ret; + } + + ret = snd_soc_dapm_add_routes(dapm, wsa_audio_map, + ARRAY_SIZE(wsa_audio_map)); + if (ret < 0) { + dev_err(wsa_dev, "%s: Failed to add routes\n", __func__); + return ret; + } + + ret = snd_soc_dapm_new_widgets(dapm->card); + if (ret < 0) { + dev_err(wsa_dev, "%s: Failed to add widgets\n", __func__); + return ret; + } + + ret = snd_soc_add_codec_controls(codec, wsa_macro_snd_controls, + ARRAY_SIZE(wsa_macro_snd_controls)); + if (ret < 0) { + dev_err(wsa_dev, "%s: Failed to add snd_ctls\n", __func__); + return ret; + } + + wsa_priv->codec = codec; + wsa_priv->spkr_gain_offset = RX_GAIN_OFFSET_0_DB; + wsa_macro_init_reg(codec); + + return 0; +} + +static int wsa_macro_deinit(struct snd_soc_codec *codec) +{ + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + wsa_priv->codec = NULL; + + return 0; +} + +static void wsa_macro_add_child_devices(struct work_struct *work) +{ + struct wsa_macro_priv *wsa_priv; + struct platform_device *pdev; + struct device_node *node; + struct wsa_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp; + int ret; + u16 count = 0, ctrl_num = 0; + struct wsa_macro_swr_ctrl_platform_data *platdata; + char plat_dev_name[WSA_MACRO_SWR_STRING_LEN]; + + wsa_priv = container_of(work, struct wsa_macro_priv, + wsa_macro_add_child_devices_work); + if (!wsa_priv) { + pr_err("%s: Memory for wsa_priv does not exist\n", + __func__); + return; + } + if (!!wsa_priv->dev || !wsa_priv->dev->of_node) { + dev_err(wsa_priv->dev, + "%s: DT node for wsa_priv does not exist\n", __func__); + return; + } + + platdata = &wsa_priv->swr_plat_data; + wsa_priv->child_count = 0; + + for_each_available_child_of_node(wsa_priv->dev->of_node, node) { + if (strnstr(node->name, "wsa_swr_master", + strlen("wsa_swr_master")) != NULL) + strlcpy(plat_dev_name, "wsa_swr_ctrl", + (WSA_MACRO_SWR_STRING_LEN - 1)); + else if (strnstr(node->name, "msm_cdc_pinctrl", + strlen("msm_cdc_pinctrl")) != NULL) + strlcpy(plat_dev_name, node->name, + (WSA_MACRO_SWR_STRING_LEN - 1)); + else + continue; + + pdev = platform_device_alloc(plat_dev_name, -1); + if (!pdev) { + dev_err(wsa_priv->dev, "%s: pdev memory alloc failed\n", + __func__); + ret = -ENOMEM; + goto err; + } + pdev->dev.parent = wsa_priv->dev; + pdev->dev.of_node = node; + + if (strnstr(node->name, "wsa_swr_master", + strlen("wsa_swr_master")) != NULL) { + ret = platform_device_add_data(pdev, platdata, + sizeof(*platdata)); + if (ret) { + dev_err(&pdev->dev, + "%s: cannot add plat data ctrl:%d\n", + __func__, ctrl_num); + goto fail_pdev_add; + } + } + + ret = platform_device_add(pdev); + if (ret) { + dev_err(&pdev->dev, + "%s: Cannot add platform device\n", + __func__); + goto fail_pdev_add; + } + + if (!strcmp(node->name, "wsa_swr_master")) { + temp = krealloc(swr_ctrl_data, + (ctrl_num + 1) * sizeof( + struct wsa_macro_swr_ctrl_data), + GFP_KERNEL); + if (!temp) { + dev_err(&pdev->dev, "out of memory\n"); + ret = -ENOMEM; + goto err; + } + swr_ctrl_data = temp; + swr_ctrl_data[ctrl_num].wsa_swr_pdev = pdev; + ctrl_num++; + dev_dbg(&pdev->dev, + "%s: Added soundwire ctrl device(s)\n", + __func__); + wsa_priv->swr_ctrl_data = swr_ctrl_data; + } + if (wsa_priv->child_count < WSA_MACRO_CHILD_DEVICES_MAX) + wsa_priv->pdev_child_devices[ + wsa_priv->child_count++] = pdev; + else + goto err; + } + + return; +fail_pdev_add: + for (count = 0; count < wsa_priv->child_count; count++) + platform_device_put(wsa_priv->pdev_child_devices[count]); +err: + return; +} + +static void wsa_macro_init_ops(struct macro_ops *ops, + char __iomem *wsa_io_base) +{ + memset(ops, 0, sizeof(struct macro_ops)); + ops->init = wsa_macro_init; + ops->exit = wsa_macro_deinit; + ops->io_base = wsa_io_base; + ops->dai_ptr = wsa_macro_dai; + ops->num_dais = ARRAY_SIZE(wsa_macro_dai); + ops->mclk_fn = wsa_macro_mclk_ctrl; +} + +static int wsa_macro_probe(struct platform_device *pdev) +{ + struct macro_ops ops; + struct wsa_macro_priv *wsa_priv; + u32 wsa_base_addr; + char __iomem *wsa_io_base; + int ret = 0; + struct clk *wsa_core_clk, *wsa_npl_clk; + + wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv), + GFP_KERNEL); + if (!wsa_priv) + return -ENOMEM; + + wsa_priv->dev = &pdev->dev; + ret = of_property_read_u32(pdev->dev.of_node, "reg", + &wsa_base_addr); + if (ret) { + dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "reg"); + return ret; + } + wsa_priv->wsa_swr_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,wsa-swr-gpios", 0); + if (!wsa_priv->wsa_swr_gpio_p) { + dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n", + __func__); + return -EINVAL; + } + wsa_io_base = devm_ioremap(&pdev->dev, + wsa_base_addr, WSA_MACRO_MAX_OFFSET); + if (!wsa_io_base) { + dev_err(&pdev->dev, "%s: ioremap failed\n", __func__); + return -EINVAL; + } + wsa_priv->wsa_io_base = wsa_io_base; + INIT_WORK(&wsa_priv->wsa_macro_add_child_devices_work, + wsa_macro_add_child_devices); + wsa_priv->swr_plat_data.handle = (void *) wsa_priv; + wsa_priv->swr_plat_data.read = NULL; + wsa_priv->swr_plat_data.write = NULL; + wsa_priv->swr_plat_data.bulk_write = NULL; + wsa_priv->swr_plat_data.clk = wsa_swrm_clock; + wsa_priv->swr_plat_data.handle_irq = NULL; + + /* Register MCLK for wsa macro */ + wsa_core_clk = devm_clk_get(&pdev->dev, "wsa_core_clk"); + if (IS_ERR(wsa_core_clk)) { + dev_err(&pdev->dev, "%s: clk get %s failed\n", + __func__, "wsa_core_clk"); + return -EINVAL; + } + wsa_priv->wsa_core_clk = wsa_core_clk; + /* Register npl clk for soundwire */ + wsa_npl_clk = devm_clk_get(&pdev->dev, "wsa_npl_clk"); + if (IS_ERR(wsa_npl_clk)) { + dev_err(&pdev->dev, "%s: clk get %s failed\n", + __func__, "wsa_npl_clk"); + return -EINVAL; + } + wsa_priv->wsa_npl_clk = wsa_npl_clk; + dev_set_drvdata(&pdev->dev, wsa_priv); + mutex_init(&wsa_priv->mclk_lock); + mutex_init(&wsa_priv->swr_clk_lock); + wsa_macro_init_ops(&ops, wsa_io_base); + ret = bolero_register_macro(&pdev->dev, WSA_MACRO, &ops); + if (ret < 0) { + dev_err(&pdev->dev, "%s: register macro failed\n", __func__); + goto reg_macro_fail; + } + schedule_work(&wsa_priv->wsa_macro_add_child_devices_work); + return ret; +reg_macro_fail: + mutex_destroy(&wsa_priv->mclk_lock); + mutex_destroy(&wsa_priv->swr_clk_lock); + return ret; +} + +static int wsa_macro_remove(struct platform_device *pdev) +{ + struct wsa_macro_priv *wsa_priv; + u16 count = 0; + + wsa_priv = dev_get_drvdata(&pdev->dev); + + if (!wsa_priv) + return -EINVAL; + + for (count = 0; count < wsa_priv->child_count && + count < WSA_MACRO_CHILD_DEVICES_MAX; count++) + platform_device_unregister(wsa_priv->pdev_child_devices[count]); + + bolero_unregister_macro(&pdev->dev, WSA_MACRO); + mutex_destroy(&wsa_priv->mclk_lock); + mutex_destroy(&wsa_priv->swr_clk_lock); + return 0; +} + +static const struct of_device_id wsa_macro_dt_match[] = { + {.compatible = "qcom,wsa-macro"}, + {} +}; + +static struct platform_driver wsa_macro_driver = { + .driver = { + .name = "wsa_macro", + .owner = THIS_MODULE, + .of_match_table = wsa_macro_dt_match, + }, + .probe = wsa_macro_probe, + .remove = wsa_macro_remove, +}; + +module_platform_driver(wsa_macro_driver); + +MODULE_DESCRIPTION("WSA macro driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/bolero/wsa-macro.h b/asoc/codecs/bolero/wsa-macro.h new file mode 100644 index 000000000000..e79de73bb2ef --- /dev/null +++ b/asoc/codecs/bolero/wsa-macro.h @@ -0,0 +1,46 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef WSA_MACRO_H +#define WSA_MACRO_H + +/* + * Selects compander and smart boost settings + * for a given speaker mode + */ +enum { + SPKR_MODE_DEFAULT, + SPKR_MODE_1, /* COMP Gain = 12dB, Smartboost Max = 5.5V */ +}; + +/* Rx path gain offsets */ +enum { + RX_GAIN_OFFSET_M1P5_DB, + RX_GAIN_OFFSET_0_DB, +}; + + +#if IS_ENABLED(CONFIG_WSA_MACRO) +extern int wsa_macro_set_spkr_mode(struct snd_soc_codec *codec, int mode); +extern int wsa_macro_set_spkr_gain_offset(struct snd_soc_codec *codec, + int offset); +#else /* CONFIG_WSA_MACRO */ +static inline int wsa_macro_set_spkr_mode(struct snd_soc_codec *codec, int mode) +{ + return 0; +} +static inline int wsa_macro_set_spkr_gain_offset(struct snd_soc_codec *codec, + int offset); +{ + return 0; +} +#endif /* CONFIG_WSA_MACRO */ +#endif -- GitLab From 3d70a35213e12ce178483f7537c0164349ef2396 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 12 Apr 2018 00:41:55 +0530 Subject: [PATCH 0302/1645] asoc: bolero: Add support for VA macro driver Add support for VA digital portion to register as macro to bolero codec. ASoC dapm and dai functionality of VA macro is associated to bolero codec itself. Change-Id: I3c5ae045c0e061bd9aa1281231cf2418093d1169 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/va-macro.c | 1382 +++++++++++++++++++++++++++++++++ 1 file changed, 1382 insertions(+) create mode 100644 asoc/codecs/bolero/va-macro.c diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c new file mode 100644 index 000000000000..1eff79d2bef0 --- /dev/null +++ b/asoc/codecs/bolero/va-macro.c @@ -0,0 +1,1382 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bolero-cdc.h" +#include "bolero-cdc-registers.h" + +#define VA_MACRO_MAX_OFFSET 0x1000 + +#define VA_MACRO_NUM_DECIMATORS 8 + +#define VA_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) +#define VA_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_3LE) + +#define TX_HPF_CUT_OFF_FREQ_MASK 0x60 +#define CF_MIN_3DB_4HZ 0x0 +#define CF_MIN_3DB_75HZ 0x1 +#define CF_MIN_3DB_150HZ 0x2 + +#define VA_MACRO_TX_PATH_OFFSET 0x80 + +#define BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS 40 + +static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); +static int va_tx_unmute_delay = BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS; +module_param(va_tx_unmute_delay, int, 0664); +MODULE_PARM_DESC(va_tx_unmute_delay, "delay to unmute the tx path"); + +enum { + VA_MACRO_AIF1_CAP = 0, + VA_MACRO_AIF2_CAP, + VA_MACRO_MAX_DAIS, +}; + +enum { + VA_MACRO_DEC0, + VA_MACRO_DEC1, + VA_MACRO_DEC2, + VA_MACRO_DEC3, + VA_MACRO_DEC4, + VA_MACRO_DEC5, + VA_MACRO_DEC6, + VA_MACRO_DEC7, + VA_MACRO_DEC_MAX, +}; + +struct va_mute_work { + struct va_macro_priv *va_priv; + u32 decimator; + struct delayed_work dwork; +}; + +struct hpf_work { + struct va_macro_priv *va_priv; + u8 decimator; + u8 hpf_cut_off_freq; + struct delayed_work dwork; +}; + +struct va_macro_priv { + struct device *dev; + bool dec_active[VA_MACRO_NUM_DECIMATORS]; + bool va_without_decimation; + struct clk *va_core_clk; + struct mutex mclk_lock; + struct snd_soc_codec *codec; + struct hpf_work va_hpf_work[VA_MACRO_NUM_DECIMATORS]; + struct va_mute_work va_mute_dwork[VA_MACRO_NUM_DECIMATORS]; + unsigned long active_ch_mask[VA_MACRO_MAX_DAIS]; + unsigned long active_ch_cnt[VA_MACRO_MAX_DAIS]; + s32 dmic_0_1_clk_cnt; + s32 dmic_2_3_clk_cnt; + s32 dmic_4_5_clk_cnt; + s32 dmic_6_7_clk_cnt; + u16 va_mclk_users; + char __iomem *va_io_base; +}; + +static bool va_macro_get_data(struct snd_soc_codec *codec, + struct device **va_dev, + struct va_macro_priv **va_priv, + const char *func_name) +{ + *va_dev = bolero_get_device_ptr(codec->dev, VA_MACRO); + if (!(*va_dev)) { + dev_err(codec->dev, + "%s: null device for macro!\n", func_name); + return false; + } + *va_priv = dev_get_drvdata((*va_dev)); + if (!(*va_priv) || !(*va_priv)->codec) { + dev_err(codec->dev, + "%s: priv is null for macro!\n", func_name); + return false; + } + return true; +} + +static int va_macro_mclk_enable(struct va_macro_priv *va_priv, + bool mclk_enable, bool dapm) +{ + struct regmap *regmap = dev_get_regmap(va_priv->dev->parent, NULL); + int ret = 0; + + dev_dbg(va_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", + __func__, mclk_enable, dapm, va_priv->va_mclk_users); + + mutex_lock(&va_priv->mclk_lock); + if (mclk_enable) { + va_priv->va_mclk_users++; + if (va_priv->va_mclk_users == 1) { + ret = bolero_request_clock(va_priv->dev, + VA_MACRO, MCLK_MUX0, true); + if (ret < 0) { + dev_err(va_priv->dev, + "%s: va request clock en failed\n", + __func__); + goto exit; + } + regcache_mark_dirty(regmap); + regcache_sync_region(regmap, + VA_START_OFFSET, + VA_MAX_OFFSET); + regmap_update_bits(regmap, + BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + regmap_update_bits(regmap, + BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); + regmap_update_bits(regmap, + BOLERO_CDC_VA_TOP_CSR_TOP_CFG0, + 0x02, 0x02); + } + } else { + va_priv->va_mclk_users--; + if (va_priv->va_mclk_users == 0) { + regmap_update_bits(regmap, + BOLERO_CDC_VA_TOP_CSR_TOP_CFG0, + 0x02, 0x00); + regmap_update_bits(regmap, + BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x00); + regmap_update_bits(regmap, + BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x00); + bolero_request_clock(va_priv->dev, + VA_MACRO, MCLK_MUX0, false); + } + } +exit: + mutex_unlock(&va_priv->mclk_lock); + return ret; +} + +static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int ret = 0; + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + return -EINVAL; + + dev_dbg(va_dev, "%s: event = %d\n", __func__, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = va_macro_mclk_enable(va_priv, 1, true); + break; + case SND_SOC_DAPM_POST_PMD: + va_macro_mclk_enable(va_priv, 0, true); + break; + default: + dev_err(va_priv->dev, + "%s: invalid DAPM event %d\n", __func__, event); + ret = -EINVAL; + } + return ret; +} + +static int va_macro_mclk_ctrl(struct device *dev, bool enable) +{ + struct va_macro_priv *va_priv = dev_get_drvdata(dev); + int ret = 0; + + if (enable) { + ret = clk_prepare_enable(va_priv->va_core_clk); + if (ret < 0) { + dev_err(dev, "%s:va mclk enable failed\n", __func__); + goto exit; + } + } else { + clk_disable_unprepare(va_priv->va_core_clk); + } + +exit: + return ret; +} + +static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) +{ + struct delayed_work *hpf_delayed_work; + struct hpf_work *hpf_work; + struct va_macro_priv *va_priv; + struct snd_soc_codec *codec; + u16 dec_cfg_reg; + u8 hpf_cut_off_freq; + + hpf_delayed_work = to_delayed_work(work); + hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); + va_priv = hpf_work->va_priv; + codec = va_priv->codec; + hpf_cut_off_freq = hpf_work->hpf_cut_off_freq; + + dec_cfg_reg = BOLERO_CDC_VA_TX0_TX_PATH_CFG0 + + VA_MACRO_TX_PATH_OFFSET * hpf_work->decimator; + + dev_dbg(va_priv->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", + __func__, hpf_work->decimator, hpf_cut_off_freq); + + snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); +} + +static void va_macro_mute_update_callback(struct work_struct *work) +{ + struct va_mute_work *va_mute_dwork; + struct snd_soc_codec *codec = NULL; + struct va_macro_priv *va_priv; + struct delayed_work *delayed_work; + u16 tx_vol_ctl_reg, hpf_gate_reg, decimator; + + delayed_work = to_delayed_work(work); + va_mute_dwork = container_of(delayed_work, struct va_mute_work, dwork); + va_priv = va_mute_dwork->va_priv; + codec = va_priv->codec; + decimator = va_mute_dwork->decimator; + + tx_vol_ctl_reg = + BOLERO_CDC_VA_TX0_TX_PATH_CTL + + VA_MACRO_TX_PATH_OFFSET * decimator; + hpf_gate_reg = BOLERO_CDC_VA_TX0_TX_PATH_SEC2 + + VA_MACRO_TX_PATH_OFFSET * decimator; + snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x01); + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00); + dev_dbg(va_priv->dev, "%s: decimator %u unmute\n", + __func__, decimator); +} + +static int va_macro_put_dec_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val; + u16 mic_sel_reg; + + val = ucontrol->value.enumerated.item[0]; + if (val > e->items - 1) + return -EINVAL; + + dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + widget->name, val); + + switch (e->reg) { + case BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0: + mic_sel_reg = BOLERO_CDC_VA_TX0_TX_PATH_CFG0; + break; + case BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG0: + mic_sel_reg = BOLERO_CDC_VA_TX1_TX_PATH_CFG0; + break; + case BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG0: + mic_sel_reg = BOLERO_CDC_VA_TX2_TX_PATH_CFG0; + break; + case BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG0: + mic_sel_reg = BOLERO_CDC_VA_TX3_TX_PATH_CFG0; + break; + case BOLERO_CDC_VA_INP_MUX_ADC_MUX4_CFG0: + mic_sel_reg = BOLERO_CDC_VA_TX4_TX_PATH_CFG0; + break; + case BOLERO_CDC_VA_INP_MUX_ADC_MUX5_CFG0: + mic_sel_reg = BOLERO_CDC_VA_TX5_TX_PATH_CFG0; + break; + case BOLERO_CDC_VA_INP_MUX_ADC_MUX6_CFG0: + mic_sel_reg = BOLERO_CDC_VA_TX6_TX_PATH_CFG0; + break; + case BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG0: + mic_sel_reg = BOLERO_CDC_VA_TX7_TX_PATH_CFG0; + break; + default: + dev_err(codec->dev, "%s: e->reg: 0x%x not expected\n", + __func__, e->reg); + return -EINVAL; + } + /* DMIC selected */ + if (val != 0) + snd_soc_update_bits(codec, mic_sel_reg, 1 << 7, 1 << 7); + + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +static int va_macro_tx_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_multi_mixer_control *mixer = + ((struct soc_multi_mixer_control *)kcontrol->private_value); + u32 dai_id = widget->shift; + u32 dec_id = mixer->shift; + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + return -EINVAL; + + if (test_bit(dec_id, &va_priv->active_ch_mask[dai_id])) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; + return 0; +} + +static int va_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_dapm_update *update = NULL; + struct soc_multi_mixer_control *mixer = + ((struct soc_multi_mixer_control *)kcontrol->private_value); + u32 dai_id = widget->shift; + u32 dec_id = mixer->shift; + u32 enable = ucontrol->value.integer.value[0]; + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + return -EINVAL; + + if (enable) { + set_bit(dec_id, &va_priv->active_ch_mask[dai_id]); + va_priv->active_ch_cnt[dai_id]++; + } else { + clear_bit(dec_id, &va_priv->active_ch_mask[dai_id]); + va_priv->active_ch_cnt[dai_id]--; + } + + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update); + + return 0; +} + +static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u8 dmic_clk_en = 0x01; + u16 dmic_clk_reg; + s32 *dmic_clk_cnt; + unsigned int dmic; + int ret; + char *wname; + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + return -EINVAL; + + wname = strpbrk(w->name, "01234567"); + if (!wname) { + dev_err(va_dev, "%s: widget not found\n", __func__); + return -EINVAL; + } + + ret = kstrtouint(wname, 10, &dmic); + if (ret < 0) { + dev_err(va_dev, "%s: Invalid DMIC line on the codec\n", + __func__); + return -EINVAL; + } + + switch (dmic) { + case 0: + case 1: + dmic_clk_cnt = &(va_priv->dmic_0_1_clk_cnt); + dmic_clk_reg = BOLERO_CDC_VA_TX0_TX_PATH_CTL; + break; + case 2: + case 3: + dmic_clk_cnt = &(va_priv->dmic_2_3_clk_cnt); + dmic_clk_reg = BOLERO_CDC_VA_TX1_TX_PATH_CTL; + break; + case 4: + case 5: + dmic_clk_cnt = &(va_priv->dmic_4_5_clk_cnt); + dmic_clk_reg = BOLERO_CDC_VA_TX2_TX_PATH_CTL; + break; + case 6: + case 7: + dmic_clk_cnt = &(va_priv->dmic_6_7_clk_cnt); + dmic_clk_reg = BOLERO_CDC_VA_TX3_TX_PATH_CTL; + break; + default: + dev_err(va_dev, "%s: Invalid DMIC Selection\n", + __func__); + return -EINVAL; + } + dev_dbg(va_dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", + __func__, event, dmic, *dmic_clk_cnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + (*dmic_clk_cnt)++; + if (*dmic_clk_cnt == 1) { + snd_soc_update_bits(codec, dmic_clk_reg, + dmic_clk_en, dmic_clk_en); + } + break; + case SND_SOC_DAPM_POST_PMD: + (*dmic_clk_cnt)--; + if (*dmic_clk_cnt == 0) { + snd_soc_update_bits(codec, dmic_clk_reg, + dmic_clk_en, 0); + } + break; + } + + return 0; +} + +static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + unsigned int decimator; + u16 tx_vol_ctl_reg, dec_cfg_reg, hpf_gate_reg; + u16 tx_gain_ctl_reg; + u8 hpf_cut_off_freq; + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + return -EINVAL; + + decimator = w->shift; + + dev_dbg(va_dev, "%s(): widget = %s decimator = %u\n", __func__, + w->name, decimator); + + tx_vol_ctl_reg = BOLERO_CDC_VA_TX0_TX_PATH_CTL + + VA_MACRO_TX_PATH_OFFSET * decimator; + hpf_gate_reg = BOLERO_CDC_VA_TX0_TX_PATH_SEC2 + + VA_MACRO_TX_PATH_OFFSET * decimator; + dec_cfg_reg = BOLERO_CDC_VA_TX0_TX_PATH_CFG0 + + VA_MACRO_TX_PATH_OFFSET * decimator; + tx_gain_ctl_reg = BOLERO_CDC_VA_TX0_TX_VOL_CTL + + VA_MACRO_TX_PATH_OFFSET * decimator; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) & + TX_HPF_CUT_OFF_FREQ_MASK) >> 5; + va_priv->va_hpf_work[decimator].hpf_cut_off_freq = + hpf_cut_off_freq; + + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) + snd_soc_update_bits(codec, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + CF_MIN_3DB_150HZ << 5); + /* Enable TX PGA Mute */ + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMU: + /* Enable TX CLK */ + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x20, 0x20); + snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00); + + /* schedule work queue to Remove Mute */ + schedule_delayed_work(&va_priv->va_mute_dwork[decimator].dwork, + msecs_to_jiffies(va_tx_unmute_delay)); + if (va_priv->va_hpf_work[decimator].hpf_cut_off_freq != + CF_MIN_3DB_150HZ) + schedule_delayed_work( + &va_priv->va_hpf_work[decimator].dwork, + msecs_to_jiffies(300)); + /* apply gain after decimator is enabled */ + snd_soc_write(codec, tx_gain_ctl_reg, + snd_soc_read(codec, tx_gain_ctl_reg)); + break; + case SND_SOC_DAPM_PRE_PMD: + hpf_cut_off_freq = + va_priv->va_hpf_work[decimator].hpf_cut_off_freq; + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + if (cancel_delayed_work_sync( + &va_priv->va_hpf_work[decimator].dwork)) { + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { + snd_soc_update_bits(codec, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + } + } + cancel_delayed_work_sync( + &va_priv->va_mute_dwork[decimator].dwork); + break; + case SND_SOC_DAPM_POST_PMD: + /* Disable TX CLK */ + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x20, 0x00); + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); + break; + } + return 0; +} + +static int va_macro_enable_micbias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + /* Add code to enable/disable regulalator? */ + return 0; +} + +static int va_macro_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + int tx_fs_rate = -EINVAL; + struct snd_soc_codec *codec = dai->codec; + u32 decimator, sample_rate; + u16 tx_fs_reg = 0; + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + return -EINVAL; + + dev_dbg(va_dev, + "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__, + dai->name, dai->id, params_rate(params), + params_channels(params)); + + sample_rate = params_rate(params); + switch (sample_rate) { + case 8000: + tx_fs_rate = 0; + break; + case 16000: + tx_fs_rate = 1; + break; + case 32000: + tx_fs_rate = 3; + break; + case 48000: + tx_fs_rate = 4; + break; + case 96000: + tx_fs_rate = 5; + break; + case 192000: + tx_fs_rate = 6; + break; + case 384000: + tx_fs_rate = 7; + break; + default: + dev_err(va_dev, "%s: Invalid TX sample rate: %d\n", + __func__, params_rate(params)); + return -EINVAL; + } + for_each_set_bit(decimator, &va_priv->active_ch_mask[dai->id], + VA_MACRO_DEC_MAX) { + if (decimator >= 0) { + tx_fs_reg = BOLERO_CDC_VA_TX0_TX_PATH_CTL + + VA_MACRO_TX_PATH_OFFSET * decimator; + dev_dbg(va_dev, "%s: set DEC%u rate to %u\n", + __func__, decimator, sample_rate); + snd_soc_update_bits(codec, tx_fs_reg, 0x0F, + tx_fs_rate); + } else { + dev_err(va_dev, + "%s: ERROR: Invalid decimator: %d\n", + __func__, decimator); + return -EINVAL; + } + } + return 0; +} + +static int va_macro_get_channel_map(struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot) +{ + struct snd_soc_codec *codec = dai->codec; + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + return -EINVAL; + + switch (dai->id) { + case VA_MACRO_AIF1_CAP: + case VA_MACRO_AIF2_CAP: + *tx_slot = va_priv->active_ch_mask[dai->id]; + *tx_num = va_priv->active_ch_cnt[dai->id]; + break; + default: + dev_err(va_dev, "%s: Invalid AIF\n", __func__); + break; + } + return 0; +} + +static struct snd_soc_dai_ops va_macro_dai_ops = { + .hw_params = va_macro_hw_params, + .get_channel_map = va_macro_get_channel_map, +}; + +static struct snd_soc_dai_driver va_macro_dai[] = { + { + .name = "va_macro_tx1", + .id = VA_MACRO_AIF1_CAP, + .capture = { + .stream_name = "VA_AIF1 Capture", + .rates = VA_MACRO_RATES, + .formats = VA_MACRO_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &va_macro_dai_ops, + }, + { + .name = "va_macro_tx2", + .id = VA_MACRO_AIF2_CAP, + .capture = { + .stream_name = "VA_AIF2 Capture", + .rates = VA_MACRO_RATES, + .formats = VA_MACRO_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &va_macro_dai_ops, + }, +}; + +#define STRING(name) #name +#define VA_MACRO_DAPM_ENUM(name, reg, offset, text) \ +static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ +static const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_ENUM(STRING(name), name##_enum) + +#define VA_MACRO_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \ +static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ +static const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname) + +#define VA_MACRO_DAPM_MUX(name, shift, kctl) \ + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux) + +static const char * const adc_mux_text[] = { + "MSM_DMIC", "SWR_MIC" +}; + +VA_MACRO_DAPM_ENUM(va_dec0, BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1, + 0, adc_mux_text); +VA_MACRO_DAPM_ENUM(va_dec1, BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG1, + 0, adc_mux_text); +VA_MACRO_DAPM_ENUM(va_dec2, BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG1, + 0, adc_mux_text); +VA_MACRO_DAPM_ENUM(va_dec3, BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG1, + 0, adc_mux_text); +VA_MACRO_DAPM_ENUM(va_dec4, BOLERO_CDC_VA_INP_MUX_ADC_MUX4_CFG1, + 0, adc_mux_text); +VA_MACRO_DAPM_ENUM(va_dec5, BOLERO_CDC_VA_INP_MUX_ADC_MUX5_CFG1, + 0, adc_mux_text); +VA_MACRO_DAPM_ENUM(va_dec6, BOLERO_CDC_VA_INP_MUX_ADC_MUX6_CFG1, + 0, adc_mux_text); +VA_MACRO_DAPM_ENUM(va_dec7, BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG1, + 0, adc_mux_text); + +static const char * const dmic_mux_text[] = { + "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", + "DMIC4", "DMIC5", "DMIC6", "DMIC7" +}; + +VA_MACRO_DAPM_ENUM_EXT(va_dmic0, BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0, + 4, dmic_mux_text, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_dmic1, BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG0, + 4, dmic_mux_text, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_dmic2, BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG0, + 4, dmic_mux_text, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_dmic3, BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG0, + 4, dmic_mux_text, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_dmic4, BOLERO_CDC_VA_INP_MUX_ADC_MUX4_CFG0, + 4, dmic_mux_text, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_dmic5, BOLERO_CDC_VA_INP_MUX_ADC_MUX5_CFG0, + 4, dmic_mux_text, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_dmic6, BOLERO_CDC_VA_INP_MUX_ADC_MUX6_CFG0, + 4, dmic_mux_text, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_dmic7, BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG0, + 4, dmic_mux_text, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +static const char * const smic_mux_text[] = { + "ZERO", "ADC0", "ADC1", "ADC2", "ADC3", + "SWR_DMIC0", "SWR_DMIC1", "SWR_DMIC2", "SWR_DMIC3", + "SWR_DMIC4", "SWR_DMIC5", "SWR_DMIC6", "SWR_DMIC7" +}; + +VA_MACRO_DAPM_ENUM_EXT(va_smic0, BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0, + 0, smic_mux_text, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_smic1, BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG0, + 0, smic_mux_text, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_smic2, BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG0, + 0, smic_mux_text, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_smic3, BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG0, + 0, smic_mux_text, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_smic4, BOLERO_CDC_VA_INP_MUX_ADC_MUX4_CFG0, + 0, smic_mux_text, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_smic5, BOLERO_CDC_VA_INP_MUX_ADC_MUX5_CFG0, + 0, smic_mux_text, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_smic6, BOLERO_CDC_VA_INP_MUX_ADC_MUX6_CFG0, + 0, smic_mux_text, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_smic7, BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG0, + 0, smic_mux_text, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +static const struct snd_kcontrol_new va_aif1_cap_mixer[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, VA_MACRO_DEC2, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, VA_MACRO_DEC3, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, VA_MACRO_DEC4, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, VA_MACRO_DEC5, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, VA_MACRO_DEC6, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, VA_MACRO_DEC7, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), +}; + +static const struct snd_kcontrol_new va_aif2_cap_mixer[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, VA_MACRO_DEC2, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, VA_MACRO_DEC3, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, VA_MACRO_DEC4, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, VA_MACRO_DEC5, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, VA_MACRO_DEC6, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, VA_MACRO_DEC7, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), +}; + +static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = { + SND_SOC_DAPM_AIF_OUT("VA_AIF1 CAP", "VA_AIF1 Capture", 0, + SND_SOC_NOPM, VA_MACRO_AIF1_CAP, 0), + + SND_SOC_DAPM_AIF_OUT("VA_AIF2 CAP", "VA_AIF2 Capture", 0, + SND_SOC_NOPM, VA_MACRO_AIF2_CAP, 0), + + SND_SOC_DAPM_MIXER("VA_AIF1_CAP Mixer", SND_SOC_NOPM, + VA_MACRO_AIF1_CAP, 0, + va_aif1_cap_mixer, ARRAY_SIZE(va_aif1_cap_mixer)), + + SND_SOC_DAPM_MIXER("VA_AIF2_CAP Mixer", SND_SOC_NOPM, + VA_MACRO_AIF2_CAP, 0, + va_aif2_cap_mixer, ARRAY_SIZE(va_aif2_cap_mixer)), + + + VA_MACRO_DAPM_MUX("VA DMIC MUX0", 0, va_dmic0), + VA_MACRO_DAPM_MUX("VA DMIC MUX1", 0, va_dmic1), + VA_MACRO_DAPM_MUX("VA DMIC MUX2", 0, va_dmic2), + VA_MACRO_DAPM_MUX("VA DMIC MUX3", 0, va_dmic3), + VA_MACRO_DAPM_MUX("VA DMIC MUX4", 0, va_dmic4), + VA_MACRO_DAPM_MUX("VA DMIC MUX5", 0, va_dmic5), + VA_MACRO_DAPM_MUX("VA DMIC MUX6", 0, va_dmic6), + VA_MACRO_DAPM_MUX("VA DMIC MUX7", 0, va_dmic7), + + VA_MACRO_DAPM_MUX("VA SMIC MUX0", 0, va_smic0), + VA_MACRO_DAPM_MUX("VA SMIC MUX1", 0, va_smic1), + VA_MACRO_DAPM_MUX("VA SMIC MUX2", 0, va_smic2), + VA_MACRO_DAPM_MUX("VA SMIC MUX3", 0, va_smic3), + VA_MACRO_DAPM_MUX("VA SMIC MUX4", 0, va_smic4), + VA_MACRO_DAPM_MUX("VA SMIC MUX5", 0, va_smic5), + VA_MACRO_DAPM_MUX("VA SMIC MUX6", 0, va_smic6), + VA_MACRO_DAPM_MUX("VA SMIC MUX7", 0, va_smic7), + + SND_SOC_DAPM_MICBIAS_E("VA MIC BIAS1", SND_SOC_NOPM, 0, 0, + va_macro_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("VA DMIC0", NULL, SND_SOC_NOPM, 0, 0, + va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("VA DMIC1", NULL, SND_SOC_NOPM, 0, 0, + va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("VA DMIC2", NULL, SND_SOC_NOPM, 0, 0, + va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("VA DMIC3", NULL, SND_SOC_NOPM, 0, 0, + va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("VA DMIC4", NULL, SND_SOC_NOPM, 0, 0, + va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("VA DMIC5", NULL, SND_SOC_NOPM, 0, 0, + va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("VA DMIC6", NULL, SND_SOC_NOPM, 0, 0, + va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("VA DMIC7", NULL, SND_SOC_NOPM, 0, 0, + va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_INPUT("VA SWR_ADC0"), + SND_SOC_DAPM_INPUT("VA SWR_ADC1"), + SND_SOC_DAPM_INPUT("VA SWR_ADC2"), + SND_SOC_DAPM_INPUT("VA SWR_ADC3"), + SND_SOC_DAPM_INPUT("VA SWR_MIC0"), + SND_SOC_DAPM_INPUT("VA SWR_MIC1"), + SND_SOC_DAPM_INPUT("VA SWR_MIC2"), + SND_SOC_DAPM_INPUT("VA SWR_MIC3"), + SND_SOC_DAPM_INPUT("VA SWR_MIC4"), + SND_SOC_DAPM_INPUT("VA SWR_MIC5"), + SND_SOC_DAPM_INPUT("VA SWR_MIC6"), + SND_SOC_DAPM_INPUT("VA SWR_MIC7"), + + SND_SOC_DAPM_MUX_E("VA DEC0 MUX", SND_SOC_NOPM, VA_MACRO_DEC0, 0, + &va_dec0_mux, va_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("VA DEC1 MUX", SND_SOC_NOPM, VA_MACRO_DEC1, 0, + &va_dec1_mux, va_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("VA DEC2 MUX", SND_SOC_NOPM, VA_MACRO_DEC2, 0, + &va_dec2_mux, va_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("VA DEC3 MUX", SND_SOC_NOPM, VA_MACRO_DEC3, 0, + &va_dec3_mux, va_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("VA DEC4 MUX", SND_SOC_NOPM, VA_MACRO_DEC4, 0, + &va_dec4_mux, va_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("VA DEC5 MUX", SND_SOC_NOPM, VA_MACRO_DEC5, 0, + &va_dec5_mux, va_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("VA DEC6 MUX", SND_SOC_NOPM, VA_MACRO_DEC6, 0, + &va_dec6_mux, va_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("VA DEC7 MUX", SND_SOC_NOPM, VA_MACRO_DEC7, 0, + &va_dec7_mux, va_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("VA_MCLK", 0, SND_SOC_NOPM, 0, 0, + va_macro_mclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_route va_audio_map[] = { + {"VA_AIF1 CAP", NULL, "VA_MCLK"}, + {"VA_AIF2 CAP", NULL, "VA_MCLK"}, + + {"VA_AIF1 CAP", NULL, "VA_AIF1_CAP Mixer"}, + {"VA_AIF2 CAP", NULL, "VA_AIF2_CAP Mixer"}, + + {"VA_AIF1_CAP Mixer", "DEC0", "VA DEC0 MUX"}, + {"VA_AIF1_CAP Mixer", "DEC1", "VA DEC1 MUX"}, + {"VA_AIF1_CAP Mixer", "DEC2", "VA DEC2 MUX"}, + {"VA_AIF1_CAP Mixer", "DEC3", "VA DEC3 MUX"}, + {"VA_AIF1_CAP Mixer", "DEC4", "VA DEC4 MUX"}, + {"VA_AIF1_CAP Mixer", "DEC5", "VA DEC5 MUX"}, + {"VA_AIF1_CAP Mixer", "DEC6", "VA DEC6 MUX"}, + {"VA_AIF1_CAP Mixer", "DEC7", "VA DEC7 MUX"}, + + {"VA_AIF2_CAP Mixer", "DEC0", "VA DEC0 MUX"}, + {"VA_AIF2_CAP Mixer", "DEC1", "VA DEC1 MUX"}, + {"VA_AIF2_CAP Mixer", "DEC2", "VA DEC2 MUX"}, + {"VA_AIF2_CAP Mixer", "DEC3", "VA DEC3 MUX"}, + {"VA_AIF2_CAP Mixer", "DEC4", "VA DEC4 MUX"}, + {"VA_AIF2_CAP Mixer", "DEC5", "VA DEC5 MUX"}, + {"VA_AIF2_CAP Mixer", "DEC6", "VA DEC6 MUX"}, + {"VA_AIF2_CAP Mixer", "DEC7", "VA DEC7 MUX"}, + + {"VA DEC0 MUX", "MSM_DMIC", "VA DMIC MUX0"}, + {"VA DMIC MUX0", "DMIC0", "VA DMIC0"}, + {"VA DMIC MUX0", "DMIC1", "VA DMIC1"}, + {"VA DMIC MUX0", "DMIC2", "VA DMIC2"}, + {"VA DMIC MUX0", "DMIC3", "VA DMIC3"}, + {"VA DMIC MUX0", "DMIC4", "VA DMIC4"}, + {"VA DMIC MUX0", "DMIC5", "VA DMIC5"}, + {"VA DMIC MUX0", "DMIC6", "VA DMIC6"}, + {"VA DMIC MUX0", "DMIC7", "VA DMIC7"}, + + {"VA DEC0 MUX", "SWR_MIC", "VA SMIC MUX0"}, + {"VA SMIC MUX0", "ADC0", "VA SWR_ADC0"}, + {"VA SMIC MUX0", "ADC1", "VA SWR_ADC1"}, + {"VA SMIC MUX0", "ADC2", "VA SWR_ADC2"}, + {"VA SMIC MUX0", "ADC3", "VA SWR_ADC3"}, + {"VA SMIC MUX0", "SWR_DMIC0", "VA SWR_MIC0"}, + {"VA SMIC MUX0", "SWR_DMIC1", "VA SWR_MIC1"}, + {"VA SMIC MUX0", "SWR_DMIC2", "VA SWR_MIC2"}, + {"VA SMIC MUX0", "SWR_DMIC3", "VA SWR_MIC3"}, + {"VA SMIC MUX0", "SWR_DMIC4", "VA SWR_MIC4"}, + {"VA SMIC MUX0", "SWR_DMIC5", "VA SWR_MIC5"}, + {"VA SMIC MUX0", "SWR_DMIC6", "VA SWR_MIC6"}, + {"VA SMIC MUX0", "SWR_DMIC7", "VA SWR_MIC7"}, + + {"VA DEC1 MUX", "MSM_DMIC", "VA DMIC MUX1"}, + {"VA DMIC MUX1", "DMIC0", "VA DMIC0"}, + {"VA DMIC MUX1", "DMIC1", "VA DMIC1"}, + {"VA DMIC MUX1", "DMIC2", "VA DMIC2"}, + {"VA DMIC MUX1", "DMIC3", "VA DMIC3"}, + {"VA DMIC MUX1", "DMIC4", "VA DMIC4"}, + {"VA DMIC MUX1", "DMIC5", "VA DMIC5"}, + {"VA DMIC MUX1", "DMIC6", "VA DMIC6"}, + {"VA DMIC MUX1", "DMIC7", "VA DMIC7"}, + + {"VA DEC1 MUX", "SWR_MIC", "VA SMIC MUX1"}, + {"VA SMIC MUX1", "ADC0", "VA SWR_ADC0"}, + {"VA SMIC MUX1", "ADC1", "VA SWR_ADC1"}, + {"VA SMIC MUX1", "ADC2", "VA SWR_ADC2"}, + {"VA SMIC MUX1", "ADC3", "VA SWR_ADC3"}, + {"VA SMIC MUX1", "SWR_DMIC0", "VA SWR_MIC0"}, + {"VA SMIC MUX1", "SWR_DMIC1", "VA SWR_MIC1"}, + {"VA SMIC MUX1", "SWR_DMIC2", "VA SWR_MIC2"}, + {"VA SMIC MUX1", "SWR_DMIC3", "VA SWR_MIC3"}, + {"VA SMIC MUX1", "SWR_DMIC4", "VA SWR_MIC4"}, + {"VA SMIC MUX1", "SWR_DMIC5", "VA SWR_MIC5"}, + {"VA SMIC MUX1", "SWR_DMIC6", "VA SWR_MIC6"}, + {"VA SMIC MUX1", "SWR_DMIC7", "VA SWR_MIC7"}, + + {"VA DEC2 MUX", "MSM_DMIC", "VA DMIC MUX2"}, + {"VA DMIC MUX2", "DMIC0", "VA DMIC0"}, + {"VA DMIC MUX2", "DMIC1", "VA DMIC1"}, + {"VA DMIC MUX2", "DMIC2", "VA DMIC2"}, + {"VA DMIC MUX2", "DMIC3", "VA DMIC3"}, + {"VA DMIC MUX2", "DMIC4", "VA DMIC4"}, + {"VA DMIC MUX2", "DMIC5", "VA DMIC5"}, + {"VA DMIC MUX2", "DMIC6", "VA DMIC6"}, + {"VA DMIC MUX2", "DMIC7", "VA DMIC7"}, + + {"VA DEC2 MUX", "SWR_MIC", "VA SMIC MUX2"}, + {"VA SMIC MUX2", "ADC0", "VA SWR_ADC0"}, + {"VA SMIC MUX2", "ADC1", "VA SWR_ADC1"}, + {"VA SMIC MUX2", "ADC2", "VA SWR_ADC2"}, + {"VA SMIC MUX2", "ADC3", "VA SWR_ADC3"}, + {"VA SMIC MUX2", "SWR_DMIC0", "VA SWR_MIC0"}, + {"VA SMIC MUX2", "SWR_DMIC1", "VA SWR_MIC1"}, + {"VA SMIC MUX2", "SWR_DMIC2", "VA SWR_MIC2"}, + {"VA SMIC MUX2", "SWR_DMIC3", "VA SWR_MIC3"}, + {"VA SMIC MUX2", "SWR_DMIC4", "VA SWR_MIC4"}, + {"VA SMIC MUX2", "SWR_DMIC5", "VA SWR_MIC5"}, + {"VA SMIC MUX2", "SWR_DMIC6", "VA SWR_MIC6"}, + {"VA SMIC MUX2", "SWR_DMIC7", "VA SWR_MIC7"}, + + {"VA DEC3 MUX", "MSM_DMIC", "VA DMIC MUX3"}, + {"VA DMIC MUX3", "DMIC0", "VA DMIC0"}, + {"VA DMIC MUX3", "DMIC1", "VA DMIC1"}, + {"VA DMIC MUX3", "DMIC2", "VA DMIC2"}, + {"VA DMIC MUX3", "DMIC3", "VA DMIC3"}, + {"VA DMIC MUX3", "DMIC4", "VA DMIC4"}, + {"VA DMIC MUX3", "DMIC5", "VA DMIC5"}, + {"VA DMIC MUX3", "DMIC6", "VA DMIC6"}, + {"VA DMIC MUX3", "DMIC7", "VA DMIC7"}, + + {"VA DEC3 MUX", "SWR_MIC", "VA SMIC MUX3"}, + {"VA SMIC MUX3", "ADC0", "VA SWR_ADC0"}, + {"VA SMIC MUX3", "ADC1", "VA SWR_ADC1"}, + {"VA SMIC MUX3", "ADC2", "VA SWR_ADC2"}, + {"VA SMIC MUX3", "ADC3", "VA SWR_ADC3"}, + {"VA SMIC MUX3", "SWR_DMIC0", "VA SWR_MIC0"}, + {"VA SMIC MUX3", "SWR_DMIC1", "VA SWR_MIC1"}, + {"VA SMIC MUX3", "SWR_DMIC2", "VA SWR_MIC2"}, + {"VA SMIC MUX3", "SWR_DMIC3", "VA SWR_MIC3"}, + {"VA SMIC MUX3", "SWR_DMIC4", "VA SWR_MIC4"}, + {"VA SMIC MUX3", "SWR_DMIC5", "VA SWR_MIC5"}, + {"VA SMIC MUX3", "SWR_DMIC6", "VA SWR_MIC6"}, + {"VA SMIC MUX3", "SWR_DMIC7", "VA SWR_MIC7"}, + + {"VA DEC4 MUX", "MSM_DMIC", "VA DMIC MUX4"}, + {"VA DMIC MUX4", "DMIC0", "VA DMIC0"}, + {"VA DMIC MUX4", "DMIC1", "VA DMIC1"}, + {"VA DMIC MUX4", "DMIC2", "VA DMIC2"}, + {"VA DMIC MUX4", "DMIC3", "VA DMIC3"}, + {"VA DMIC MUX4", "DMIC4", "VA DMIC4"}, + {"VA DMIC MUX4", "DMIC5", "VA DMIC5"}, + {"VA DMIC MUX4", "DMIC6", "VA DMIC6"}, + {"VA DMIC MUX4", "DMIC7", "VA DMIC7"}, + + {"VA DEC4 MUX", "SWR_MIC", "VA SMIC MUX4"}, + {"VA SMIC MUX4", "ADC0", "VA SWR_ADC0"}, + {"VA SMIC MUX4", "ADC1", "VA SWR_ADC1"}, + {"VA SMIC MUX4", "ADC2", "VA SWR_ADC2"}, + {"VA SMIC MUX4", "ADC3", "VA SWR_ADC3"}, + {"VA SMIC MUX4", "SWR_DMIC0", "VA SWR_MIC0"}, + {"VA SMIC MUX4", "SWR_DMIC1", "VA SWR_MIC1"}, + {"VA SMIC MUX4", "SWR_DMIC2", "VA SWR_MIC2"}, + {"VA SMIC MUX4", "SWR_DMIC3", "VA SWR_MIC3"}, + {"VA SMIC MUX4", "SWR_DMIC4", "VA SWR_MIC4"}, + {"VA SMIC MUX4", "SWR_DMIC5", "VA SWR_MIC5"}, + {"VA SMIC MUX4", "SWR_DMIC6", "VA SWR_MIC6"}, + {"VA SMIC MUX4", "SWR_DMIC7", "VA SWR_MIC7"}, + + {"VA DEC5 MUX", "MSM_DMIC", "VA DMIC MUX5"}, + {"VA DMIC MUX5", "DMIC0", "VA DMIC0"}, + {"VA DMIC MUX5", "DMIC1", "VA DMIC1"}, + {"VA DMIC MUX5", "DMIC2", "VA DMIC2"}, + {"VA DMIC MUX5", "DMIC3", "VA DMIC3"}, + {"VA DMIC MUX5", "DMIC4", "VA DMIC4"}, + {"VA DMIC MUX5", "DMIC5", "VA DMIC5"}, + {"VA DMIC MUX5", "DMIC6", "VA DMIC6"}, + {"VA DMIC MUX5", "DMIC7", "VA DMIC7"}, + + {"VA DEC5 MUX", "SWR_MIC", "VA SMIC MUX5"}, + {"VA SMIC MUX5", "ADC0", "VA SWR_ADC0"}, + {"VA SMIC MUX5", "ADC1", "VA SWR_ADC1"}, + {"VA SMIC MUX5", "ADC2", "VA SWR_ADC2"}, + {"VA SMIC MUX5", "ADC3", "VA SWR_ADC3"}, + {"VA SMIC MUX5", "SWR_DMIC0", "VA SWR_MIC0"}, + {"VA SMIC MUX5", "SWR_DMIC1", "VA SWR_MIC1"}, + {"VA SMIC MUX5", "SWR_DMIC2", "VA SWR_MIC2"}, + {"VA SMIC MUX5", "SWR_DMIC3", "VA SWR_MIC3"}, + {"VA SMIC MUX5", "SWR_DMIC4", "VA SWR_MIC4"}, + {"VA SMIC MUX5", "SWR_DMIC5", "VA SWR_MIC5"}, + {"VA SMIC MUX5", "SWR_DMIC6", "VA SWR_MIC6"}, + {"VA SMIC MUX5", "SWR_DMIC7", "VA SWR_MIC7"}, + + {"VA DEC6 MUX", "MSM_DMIC", "VA DMIC MUX6"}, + {"VA DMIC MUX6", "DMIC0", "VA DMIC0"}, + {"VA DMIC MUX6", "DMIC1", "VA DMIC1"}, + {"VA DMIC MUX6", "DMIC2", "VA DMIC2"}, + {"VA DMIC MUX6", "DMIC3", "VA DMIC3"}, + {"VA DMIC MUX6", "DMIC4", "VA DMIC4"}, + {"VA DMIC MUX6", "DMIC5", "VA DMIC5"}, + {"VA DMIC MUX6", "DMIC6", "VA DMIC6"}, + {"VA DMIC MUX6", "DMIC7", "VA DMIC7"}, + + {"VA DEC6 MUX", "SWR_MIC", "VA SMIC MUX6"}, + {"VA SMIC MUX6", "ADC0", "VA SWR_ADC0"}, + {"VA SMIC MUX6", "ADC1", "VA SWR_ADC1"}, + {"VA SMIC MUX6", "ADC2", "VA SWR_ADC2"}, + {"VA SMIC MUX6", "ADC3", "VA SWR_ADC3"}, + {"VA SMIC MUX6", "SWR_DMIC0", "VA SWR_MIC0"}, + {"VA SMIC MUX6", "SWR_DMIC1", "VA SWR_MIC1"}, + {"VA SMIC MUX6", "SWR_DMIC2", "VA SWR_MIC2"}, + {"VA SMIC MUX6", "SWR_DMIC3", "VA SWR_MIC3"}, + {"VA SMIC MUX6", "SWR_DMIC4", "VA SWR_MIC4"}, + {"VA SMIC MUX6", "SWR_DMIC5", "VA SWR_MIC5"}, + {"VA SMIC MUX6", "SWR_DMIC6", "VA SWR_MIC6"}, + {"VA SMIC MUX6", "SWR_DMIC7", "VA SWR_MIC7"}, + + {"VA DEC7 MUX", "MSM_DMIC", "VA DMIC MUX7"}, + {"VA DMIC MUX7", "DMIC0", "VA DMIC0"}, + {"VA DMIC MUX7", "DMIC1", "VA DMIC1"}, + {"VA DMIC MUX7", "DMIC2", "VA DMIC2"}, + {"VA DMIC MUX7", "DMIC3", "VA DMIC3"}, + {"VA DMIC MUX7", "DMIC4", "VA DMIC4"}, + {"VA DMIC MUX7", "DMIC5", "VA DMIC5"}, + {"VA DMIC MUX7", "DMIC6", "VA DMIC6"}, + {"VA DMIC MUX7", "DMIC7", "VA DMIC7"}, + + {"VA DEC7 MUX", "SWR_MIC", "VA SMIC MUX7"}, + {"VA SMIC MUX7", "ADC0", "VA SWR_ADC0"}, + {"VA SMIC MUX7", "ADC1", "VA SWR_ADC1"}, + {"VA SMIC MUX7", "ADC2", "VA SWR_ADC2"}, + {"VA SMIC MUX7", "ADC3", "VA SWR_ADC3"}, + {"VA SMIC MUX7", "SWR_DMIC0", "VA SWR_MIC0"}, + {"VA SMIC MUX7", "SWR_DMIC1", "VA SWR_MIC1"}, + {"VA SMIC MUX7", "SWR_DMIC2", "VA SWR_MIC2"}, + {"VA SMIC MUX7", "SWR_DMIC3", "VA SWR_MIC3"}, + {"VA SMIC MUX7", "SWR_DMIC4", "VA SWR_MIC4"}, + {"VA SMIC MUX7", "SWR_DMIC5", "VA SWR_MIC5"}, + {"VA SMIC MUX7", "SWR_DMIC6", "VA SWR_MIC6"}, + {"VA SMIC MUX7", "SWR_DMIC7", "VA SWR_MIC7"}, +}; + +static const struct snd_kcontrol_new va_macro_snd_controls[] = { + SOC_SINGLE_SX_TLV("VA_DEC0 Volume", + BOLERO_CDC_VA_TX0_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("VA_DEC1 Volume", + BOLERO_CDC_VA_TX1_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("VA_DEC2 Volume", + BOLERO_CDC_VA_TX2_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("VA_DEC3 Volume", + BOLERO_CDC_VA_TX3_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("VA_DEC4 Volume", + BOLERO_CDC_VA_TX4_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("VA_DEC5 Volume", + BOLERO_CDC_VA_TX5_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("VA_DEC6 Volume", + BOLERO_CDC_VA_TX6_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("VA_DEC7 Volume", + BOLERO_CDC_VA_TX7_TX_VOL_CTL, + 0, -84, 40, digital_gain), +}; + +static int va_macro_init(struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + int ret, i; + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + va_dev = bolero_get_device_ptr(codec->dev, VA_MACRO); + if (!va_dev) { + dev_err(codec->dev, + "%s: null device for macro!\n", __func__); + return -EINVAL; + } + va_priv = dev_get_drvdata(va_dev); + if (!va_priv) { + dev_err(codec->dev, + "%s: priv is null for macro!\n", __func__); + return -EINVAL; + } + + ret = snd_soc_dapm_new_controls(dapm, va_macro_dapm_widgets, + ARRAY_SIZE(va_macro_dapm_widgets)); + if (ret < 0) { + dev_err(va_dev, "%s: Failed to add controls\n", __func__); + return ret; + } + + ret = snd_soc_dapm_add_routes(dapm, va_audio_map, + ARRAY_SIZE(va_audio_map)); + if (ret < 0) { + dev_err(va_dev, "%s: Failed to add routes\n", __func__); + return ret; + } + + ret = snd_soc_dapm_new_widgets(dapm->card); + if (ret < 0) { + dev_err(va_dev, "%s: Failed to add widgets\n", __func__); + return ret; + } + ret = snd_soc_add_codec_controls(codec, va_macro_snd_controls, + ARRAY_SIZE(va_macro_snd_controls)); + if (ret < 0) { + dev_err(va_dev, "%s: Failed to add snd_ctls\n", __func__); + return ret; + } + + for (i = 0; i < VA_MACRO_NUM_DECIMATORS; i++) { + va_priv->va_hpf_work[i].va_priv = va_priv; + va_priv->va_hpf_work[i].decimator = i; + INIT_DELAYED_WORK(&va_priv->va_hpf_work[i].dwork, + va_macro_tx_hpf_corner_freq_callback); + } + + for (i = 0; i < VA_MACRO_NUM_DECIMATORS; i++) { + va_priv->va_mute_dwork[i].va_priv = va_priv; + va_priv->va_mute_dwork[i].decimator = i; + INIT_DELAYED_WORK(&va_priv->va_mute_dwork[i].dwork, + va_macro_mute_update_callback); + } + va_priv->codec = codec; + + return 0; +} + +static int va_macro_deinit(struct snd_soc_codec *codec) +{ + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + return -EINVAL; + + va_priv->codec = NULL; + return 0; +} + +static void va_macro_init_ops(struct macro_ops *ops, + char __iomem *va_io_base, + bool va_without_decimation) +{ + memset(ops, 0, sizeof(struct macro_ops)); + if (!va_without_decimation) { + ops->init = va_macro_init; + ops->exit = va_macro_deinit; + ops->dai_ptr = va_macro_dai; + ops->num_dais = ARRAY_SIZE(va_macro_dai); + } else { + ops->init = NULL; + ops->exit = NULL; + ops->dai_ptr = NULL; + ops->num_dais = 0; + } + ops->io_base = va_io_base; + ops->mclk_fn = va_macro_mclk_ctrl; +} + +static int va_macro_probe(struct platform_device *pdev) +{ + struct macro_ops ops; + struct va_macro_priv *va_priv; + u32 va_base_addr; + char __iomem *va_io_base; + struct clk *va_core_clk; + bool va_without_decimation = false; + int ret = 0; + + va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv), + GFP_KERNEL); + if (!va_priv) + return -ENOMEM; + + va_priv->dev = &pdev->dev; + ret = of_property_read_u32(pdev->dev.of_node, "reg", + &va_base_addr); + if (ret) { + dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "reg"); + return ret; + } + va_without_decimation = of_property_read_bool(pdev->dev.parent->of_node, + "qcom,va-without-decimation"); + + va_priv->va_without_decimation = va_without_decimation; + va_io_base = devm_ioremap(&pdev->dev, va_base_addr, + VA_MAX_OFFSET); + if (!va_io_base) { + dev_err(&pdev->dev, "%s: ioremap failed\n", __func__); + return -EINVAL; + } + va_priv->va_io_base = va_io_base; + /* Register MCLK for va macro */ + va_core_clk = devm_clk_get(&pdev->dev, "va_core_clk"); + if (IS_ERR(va_core_clk)) { + dev_err(&pdev->dev, "%s: clk get %s failed\n", + __func__, "va_core_clk"); + return -EINVAL; + } + va_priv->va_core_clk = va_core_clk; + + mutex_init(&va_priv->mclk_lock); + dev_set_drvdata(&pdev->dev, va_priv); + va_macro_init_ops(&ops, va_io_base, va_without_decimation); + ret = bolero_register_macro(&pdev->dev, VA_MACRO, &ops); + if (ret < 0) { + dev_err(&pdev->dev, "%s: register macro failed\n", __func__); + goto reg_macro_fail; + } + return ret; + +reg_macro_fail: + mutex_destroy(&va_priv->mclk_lock); + return ret; +} + +static int va_macro_remove(struct platform_device *pdev) +{ + struct va_macro_priv *va_priv; + + va_priv = dev_get_drvdata(&pdev->dev); + + if (!va_priv) + return -EINVAL; + + bolero_unregister_macro(&pdev->dev, VA_MACRO); + mutex_destroy(&va_priv->mclk_lock); + return 0; +} + + +static const struct of_device_id va_macro_dt_match[] = { + {.compatible = "qcom,va-macro"}, + {} +}; + +static struct platform_driver va_macro_driver = { + .driver = { + .name = "va_macro", + .owner = THIS_MODULE, + .of_match_table = va_macro_dt_match, + }, + .probe = va_macro_probe, + .remove = va_macro_remove, +}; + +module_platform_driver(va_macro_driver); + +MODULE_DESCRIPTION("VA macro driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From a0f8408a67192ab507aae5febf4b4e71799c1e09 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 31 May 2018 10:42:50 +0530 Subject: [PATCH 0303/1645] asoc: Add compile rules for bolero codec and macro drivers Add compile support for bolero codec driver and other interface files along with macro drivers. Change-Id: Ifa9c5454eebab1dbebb53d60a7a67458d1e6c8f6 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/Kbuild | 120 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 asoc/codecs/bolero/Kbuild diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild new file mode 100644 index 000000000000..cf996630982d --- /dev/null +++ b/asoc/codecs/bolero/Kbuild @@ -0,0 +1,120 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + + + +ifeq ($(KERNEL_BUILD), 1) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) + ifeq ($(CONFIG_ARCH_SM6150), y) + include $(AUDIO_ROOT)/config/sm6150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + endif +endif + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ BOLERO ############ + +# for BOLERO Codec +ifdef CONFIG_SND_SOC_BOLERO + BOLERO_OBJS += bolero-cdc.o + BOLERO_OBJS += bolero-cdc-utils.o + BOLERO_OBJS += bolero-cdc-regmap.o + BOLERO_OBJS += bolero-cdc-tables.o +endif + +ifdef CONFIG_WSA_MACRO + WSA_OBJS += wsa-macro.o +endif + +ifdef CONFIG_VA_MACRO + VA_OBJS += va-macro.o +endif + +LINUX_INC += -Iinclude/linux + +INCS += $(COMMON_INC) \ + $(UAPI_INC) + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +ifeq ($(KERNEL_BUILD), 0) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_BOLERO) += bolero_cdc_dlkm.o +bolero_cdc_dlkm-y := $(BOLERO_OBJS) + +obj-$(CONFIG_WSA_MACRO) += wsa_macro_dlkm.o +wsa_macro_dlkm-y := $(WSA_OBJS) + +obj-$(CONFIG_VA_MACRO) += va_macro_dlkm.o +va_macro_dlkm-y := $(VA_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" -- GitLab From 94bd8731aebdedabf5ecbd47c464d4a8a579b314 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Wed, 28 Feb 2018 17:13:35 -0800 Subject: [PATCH 0304/1645] dsp: add support for DC detection event in afe Add support to register with ADSP for DC detection event in speaker protection module. Add support to notify audio driver clients when DC detection occurs. CRs-Fixed: 2244131 Change-Id: Ieb467f62207546a785eac2e9b96ca677e0b10565 Signed-off-by: Vidyakumar Athota Signed-off-by: Vignesh Kulothungan --- dsp/q6afe.c | 111 +++++++++++++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 93 +++++++++++++++++++++++++++++++ 2 files changed, 204 insertions(+) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 63138fc06c43..36df3d3016f5 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "adsp_err.h" @@ -326,6 +327,11 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, return 0; } +static void afe_notify_dc_presence(void) +{ + msm_aud_evt_notifier_call_chain(MSM_AUD_DC_EVENT, NULL); +} + static int32_t afe_callback(struct apr_client_data *data, void *priv) { if (!data) { @@ -437,6 +443,7 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) case AFE_PORTS_CMD_DTMF_CTL: case AFE_SVC_CMD_SET_PARAM: case AFE_SVC_CMD_SET_PARAM_V2: + case AFE_PORT_CMD_MOD_EVENT_CFG: atomic_set(&this_afe.state, 0); wake_up(&this_afe.wait[data->token]); break; @@ -497,6 +504,35 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) wake_up(&this_afe.wait[data->token]); } else if (data->opcode == AFE_EVENT_RT_PROXY_PORT_STATUS) { port_id = (uint16_t)(0x0000FFFF & payload[0]); + } else if (data->opcode == AFE_PORT_MOD_EVENT) { + u32 flag_dc_presence[2]; + uint32_t *payload = data->payload; + struct afe_port_mod_evt_rsp_hdr *evt_pl = + (struct afe_port_mod_evt_rsp_hdr *)payload; + + if (!payload || (data->token >= AFE_MAX_PORTS)) { + pr_err("%s: Error: size %d payload %pK token %d\n", + __func__, data->payload_size, + payload, data->token); + return -EINVAL; + } + if ((evt_pl->module_id == AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI) && + (evt_pl->event_id == AFE_PORT_SP_DC_DETECTION_EVENT) && + (evt_pl->payload_size == sizeof(flag_dc_presence))) { + + memcpy(&flag_dc_presence, + payload + + sizeof(struct afe_port_mod_evt_rsp_hdr), + evt_pl->payload_size); + if (flag_dc_presence[0] == 1 || + flag_dc_presence[1] == 1) { + afe_notify_dc_presence(); + } + } else { + pr_debug("%s: mod ID = 0x%x event_id = 0x%x\n", + __func__, evt_pl->module_id, + evt_pl->event_id); + } } pr_debug("%s: port_id = 0x%x\n", __func__, port_id); switch (port_id) { @@ -1475,6 +1511,79 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, return ret; } +static int afe_spkr_prot_reg_event_cfg(u16 port_id) +{ + struct afe_port_cmd_event_cfg *config; + struct afe_port_cmd_mod_evt_cfg_payload pl; + int index; + int ret; + int num_events = 1; + int cmd_size = sizeof(struct afe_port_cmd_event_cfg) + + (num_events * sizeof(struct afe_port_cmd_mod_evt_cfg_payload)); + + config = kzalloc(cmd_size, GFP_KERNEL); + if (!config) + return -ENOMEM; + + index = q6audio_get_port_index(port_id); + if (index < 0) { + pr_err("%s: Invalid index number: %d\n", __func__, index); + ret = -EINVAL; + goto fail_idx; + } + + memset(&pl, 0, sizeof(pl)); + pl.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; + pl.event_id = AFE_PORT_SP_DC_DETECTION_EVENT; + pl.reg_flag = AFE_MODULE_REGISTER_EVENT_FLAG; + + + config->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config->hdr.pkt_size = cmd_size; + config->hdr.src_port = 0; + config->hdr.dest_port = 0; + config->hdr.token = index; + + config->hdr.opcode = AFE_PORT_CMD_MOD_EVENT_CFG; + config->port_id = q6audio_get_port_id(port_id); + config->num_events = num_events; + config->version = 1; + memcpy(config->payload, &pl, sizeof(pl)); + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) config); + if (ret < 0) { + pr_err("%s: port = 0x%x failed %d\n", + __func__, port_id, ret); + goto fail_cmd; + } + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto fail_idx; + } + ret = 0; +fail_cmd: + pr_debug("%s: config.opcode 0x%x status %d\n", + __func__, config->hdr.opcode, ret); + +fail_idx: + kfree(config); + return ret; +} + static void afe_send_cal_spkr_prot_tx(int port_id) { union afe_spkr_prot_config afe_spk_config; @@ -1585,6 +1694,8 @@ static void afe_send_cal_spkr_prot_tx(int port_id) } mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); + /* Register for DC detection event */ + afe_spkr_prot_reg_event_cfg(port_id); } static void afe_send_cal_spkr_prot_rx(int port_id) diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 5f62a2711d6e..f9fef5a86b36 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1780,6 +1780,99 @@ struct afe_loopback_iir_cfg_v2 { struct param_hdr_v1 st_iir_filter_config_pdata; struct afe_sidetone_iir_filter_config_params st_iir_filter_config_data; } __packed; + + +/* + * Param ID and related structures for AFE event + * registration. + */ +#define AFE_PORT_CMD_MOD_EVENT_CFG 0x000100FD + +struct afe_port_cmd_event_cfg { + struct apr_hdr hdr; + uint32_t version; + /* Version number. The current version is 0 */ + + uint32_t port_id; + /* + * Port ID for the AFE port hosting the modules + * being registered for the events + */ + + uint32_t num_events; + /* + * Number of events to be registered with the service + * Each event has the structure of + * afe_port_cmd_mod_evt_cfg_payload. + */ + uint8_t payload[0]; +}; + +/** Event registration for a module. */ +#define AFE_MODULE_REGISTER_EVENT_FLAG 1 + +/** Event de-registration for a module. */ +#define AFE_MODULE_DEREGISTER_EVENT_FLAG 0 + +struct afe_port_cmd_mod_evt_cfg_payload { + uint32_t module_id; + /* Valid ID of the module. */ + + uint16_t instance_id; + /* + * Valid ID of the module instance in the current topology. + * If both module_id and instance_id ID are set to 0, the event is + * registered with all modules and instances in the topology. + * If module_id is set to 0 and instance_id is set to a non-zero value, + * the payload is considered to be invalid. + */ + + uint16_t reserved; + /* Used for alignment; must be set to 0.*/ + + uint32_t event_id; + /* Unique ID of the event. */ + + uint32_t reg_flag; + /* + * Bit field for enabling or disabling event registration. + * values + * - #AFE_MODULE_REGISTER_EVENT_FLAG + * - #AFE_MODULE_DEREGISTER_EVENT_FLAG + */ +} __packed; + + +#define AFE_PORT_MOD_EVENT 0x0001010C + +struct afe_port_mod_evt_rsp_hdr { + uint32_t minor_version; + /* This indicates the minor version of the payload */ + + uint32_t port_id; + /* AFE port hosting this module */ + + uint32_t module_id; + /* Module ID which is raising the event */ + + uint16_t instance_id; + /* Instance ID of the module which is raising the event */ + + uint16_t reserved; + /* For alignment purpose, should be set to 0 */ + + uint32_t event_id; + /* Valid event ID registered by client */ + + uint32_t payload_size; + /* + * Size of the event payload + * This is followed by actual payload corresponding to the event + */ +} __packed; + +#define AFE_PORT_SP_DC_DETECTION_EVENT 0x0001010D + #define AFE_MODULE_SPEAKER_PROTECTION 0x00010209 #define AFE_PARAM_ID_SPKR_PROT_CONFIG 0x0001020a #define AFE_API_VERSION_SPKR_PROT_CONFIG 0x1 -- GitLab From 9ca8dc327c07d9bab90ba7bf8e4e6a5b99065dac Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Wed, 9 May 2018 17:41:11 -0700 Subject: [PATCH 0305/1645] soc: soundwire: Add support to listen for DC detection Add support to listen for DC detection event. Shutdown WSA on receiving DC detection event. CRs-Fixed: 2244131 Change-Id: Ifecab8bb9862976a647a161bad4c202b6e6459c7 Signed-off-by: Vignesh Kulothungan --- soc/swr-wcd-ctrl.c | 32 ++++++++++++++++++++++++++++++++ soc/swr-wcd-ctrl.h | 3 +++ 2 files changed, 35 insertions(+) diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c index 38f8a3d86c2e..ade883c33bf4 100644 --- a/soc/swr-wcd-ctrl.c +++ b/soc/swr-wcd-ctrl.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "swrm_registers.h" #include "swr-wcd-ctrl.h" @@ -1393,6 +1394,32 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) return ret; } +static int swrm_event_notify(struct notifier_block *self, + unsigned long action, void *data) +{ + struct swr_mstr_ctrl *swrm = container_of(self, struct swr_mstr_ctrl, + event_notifier); + if (!swrm || !swrm->pdev) { + pr_err("%s: swrm or pdev is NULL\n", __func__); + return -EINVAL; + } + if (action != MSM_AUD_DC_EVENT) { + dev_err(&swrm->pdev->dev, "%s: invalid event type: %lu\n", __func__, action); + return -EINVAL; + } + + schedule_work(&(swrm->dc_presence_work)); + + return 0; +} + +static void swrm_notify_work_fn(struct work_struct *work) +{ + struct swr_mstr_ctrl *swrm = container_of(work, struct swr_mstr_ctrl, + dc_presence_work); + swrm_wcd_notify(swrm->pdev, SWR_DEVICE_DOWN, NULL); +} + static int swrm_probe(struct platform_device *pdev) { struct swr_mstr_ctrl *swrm; @@ -1553,6 +1580,10 @@ static int swrm_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); pm_runtime_mark_last_busy(&pdev->dev); + INIT_WORK(&swrm->dc_presence_work, swrm_notify_work_fn); + swrm->event_notifier.notifier_call = swrm_event_notify; + msm_aud_evt_register_client(&swrm->event_notifier); + return 0; err_mstr_fail: swrm->reg_irq(swrm->handle, swr_mstr_interrupt, @@ -1583,6 +1614,7 @@ static int swrm_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); swr_unregister_master(&swrm->master); + msm_aud_evt_unregister_client(&swrm->event_notifier); mutex_destroy(&swrm->mlock); mutex_destroy(&swrm->reslock); mutex_destroy(&swrm->force_down_lock); diff --git a/soc/swr-wcd-ctrl.h b/soc/swr-wcd-ctrl.h index dc8d7f51f34a..14b2b48dbb84 100644 --- a/soc/swr-wcd-ctrl.h +++ b/soc/swr-wcd-ctrl.h @@ -108,6 +108,9 @@ struct swr_mstr_ctrl { u8 num_cfg_devs; struct mutex force_down_lock; int force_down_state; + + struct notifier_block event_notifier; + struct work_struct dc_presence_work; }; #endif /* _SWR_WCD_CTRL_H */ -- GitLab From cf6a1215b9d6567fdb115996be4cd45cbeb50ca8 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Wed, 21 Feb 2018 14:17:48 -0800 Subject: [PATCH 0306/1645] dsp: add support to send uevents Add a common function handle to send uevents from q6 layer. Add functions to initialize and cleanup the kernel object required to send uevents. CRs-Fixed: 2211324 Change-Id: I9dceb4eb16d6941600455602f78f4f1498171d19 Signed-off-by: Vignesh Kulothungan --- dsp/q6core.c | 104 +++++++++++++++++++++++++++++++++++++++++++ include/dsp/q6core.h | 11 ++++- 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/dsp/q6core.c b/dsp/q6core.c index c5b64096a234..4974ad22be0b 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include #include @@ -82,6 +84,106 @@ struct generic_get_data_ { }; static struct generic_get_data_ *generic_get_data; +static DEFINE_MUTEX(kset_lock); +static struct kset *audio_uevent_kset; + +static int q6core_init_uevent_kset(void) +{ + int ret = 0; + + mutex_lock(&kset_lock); + if (audio_uevent_kset) + goto done; + + /* Create a kset under /sys/kernel/ */ + audio_uevent_kset = kset_create_and_add("q6audio", NULL, kernel_kobj); + if (!audio_uevent_kset) { + pr_err("%s: error creating uevent kernel set", __func__); + ret = -EINVAL; + } +done: + mutex_unlock(&kset_lock); + return ret; +} + +static void q6core_destroy_uevent_kset(void) +{ + if (audio_uevent_kset) { + kset_unregister(audio_uevent_kset); + audio_uevent_kset = NULL; + } +} + +/** + * q6core_init_uevent_data - initialize kernel object required to send uevents. + * + * @uevent_data: uevent data (dynamically allocated memory). + * @name: name of the kernel object. + * + * Returns 0 on success or error otherwise. + */ +int q6core_init_uevent_data(struct audio_uevent_data *uevent_data, char *name) +{ + int ret = -EINVAL; + + if (!uevent_data || !name) + return ret; + + ret = q6core_init_uevent_kset(); + if (ret) + return ret; + + /* Set kset for kobject before initializing the kobject */ + uevent_data->kobj.kset = audio_uevent_kset; + + /* Initialize kobject and add it to kernel */ + ret = kobject_init_and_add(&uevent_data->kobj, &uevent_data->ktype, + NULL, "%s", name); + if (ret) { + pr_err("%s: error initializing uevent kernel object: %d", + __func__, ret); + kobject_put(&uevent_data->kobj); + return ret; + } + + /* Send kobject add event to the system */ + kobject_uevent(&uevent_data->kobj, KOBJ_ADD); + + return ret; +} +EXPORT_SYMBOL(q6core_init_uevent_data); + +/** + * q6core_destroy_uevent_data - destroy kernel object. + * + * @uevent_data: uevent data. + */ +void q6core_destroy_uevent_data(struct audio_uevent_data *uevent_data) +{ + if (uevent_data) + kobject_put(&uevent_data->kobj); +} +EXPORT_SYMBOL(q6core_destroy_uevent_data); + +/** + * q6core_send_uevent - send uevent to userspace. + * + * @uevent_data: uevent data. + * @event: event to send. + * + * Returns 0 on success or error otherwise. + */ +int q6core_send_uevent(struct audio_uevent_data *uevent_data, char *event) +{ + char *env[] = { event, NULL }; + + if (!event || !uevent_data) + return -EINVAL; + + return kobject_uevent_env(&uevent_data->kobj, KOBJ_CHANGE, env); +} +EXPORT_SYMBOL(q6core_send_uevent); + static int parse_fwk_version_info(uint32_t *payload) { size_t ver_size; @@ -1110,6 +1212,7 @@ int __init core_init(void) mutex_init(&q6core_lcl.ver_lock); q6core_init_cal_data(); + q6core_init_uevent_kset(); return 0; } @@ -1119,6 +1222,7 @@ void core_exit(void) mutex_destroy(&q6core_lcl.cmd_lock); mutex_destroy(&q6core_lcl.ver_lock); q6core_delete_cal_data(); + q6core_destroy_uevent_kset(); } MODULE_DESCRIPTION("ADSP core driver"); MODULE_LICENSE("GPL v2"); diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index f6240a33e6fd..03a7b31af52d 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -27,6 +27,15 @@ int q6core_get_service_version(uint32_t service_id, size_t size); size_t q6core_get_fwk_version_size(uint32_t service_id); +struct audio_uevent_data { + struct kobject kobj; + struct kobj_type ktype; +}; + +int q6core_init_uevent_data(struct audio_uevent_data *uevent_data, char *name); +void q6core_destroy_uevent_data(struct audio_uevent_data *uevent_data); +int q6core_send_uevent(struct audio_uevent_data *uevent_data, char *name); + #define ADSP_CMD_SET_DTS_EAGLE_DATA_ID 0x00012919 #define DTS_EAGLE_LICENSE_ID 0x00028346 struct adsp_dts_eagle { -- GitLab From c3f389877063639e57026a85ecb43558743dcd32 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Tue, 22 May 2018 18:08:20 -0700 Subject: [PATCH 0307/1645] dsp: add support to send uevent on dc detection On receiving DC detection notification, send an uevent to notify the userspace. CRs-Fixed: 2244131 Change-Id: I42b0bb2287d7f1edf5e7c344302a7ea97408ab13 Signed-off-by: Vignesh Kulothungan --- dsp/q6afe.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 36df3d3016f5..c813ad12bd4c 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include "adsp_err.h" @@ -124,6 +125,7 @@ struct afe_ctl { int set_custom_topology; int dev_acdb_id[AFE_MAX_PORTS]; routing_cb rt_cb; + struct audio_uevent_data *uevent_data; }; static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX]; @@ -329,7 +331,14 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, static void afe_notify_dc_presence(void) { + int ret = 0; + char event[] = "DC_PRESENCE=TRUE"; + msm_aud_evt_notifier_call_chain(MSM_AUD_DC_EVENT, NULL); + + ret = q6core_send_uevent(this_afe.uevent_data, event); + if (ret) + pr_err("%s: Send UEvent %s failed :%d\n", __func__, event, ret); } static int32_t afe_callback(struct apr_client_data *data, void *priv) @@ -7456,6 +7465,14 @@ int afe_unmap_rtac_block(uint32_t *mem_map_handle) return result; } +static void afe_release_uevent_data(struct kobject *kobj) +{ + struct audio_uevent_data *data = container_of(kobj, + struct audio_uevent_data, kobj); + + kfree(data); +} + int __init afe_init(void) { int i = 0, ret; @@ -7484,6 +7501,18 @@ int __init afe_init(void) pr_err("%s: could not init cal data! %d\n", __func__, ret); config_debug_fs_init(); + + this_afe.uevent_data = kzalloc(sizeof(*(this_afe.uevent_data)), GFP_KERNEL); + if (!this_afe.uevent_data) + return -ENOMEM; + + /* + * Set release function to cleanup memory related to kobject + * before initializing the kobject. + */ + this_afe.uevent_data->ktype.release = afe_release_uevent_data; + q6core_init_uevent_data(this_afe.uevent_data, "q6afe_uevent"); + return 0; } @@ -7495,6 +7524,9 @@ void afe_exit(void) this_afe.apr = NULL; rtac_set_afe_handle(this_afe.apr); } + + q6core_destroy_uevent_data(this_afe.uevent_data); + afe_delete_cal_data(); config_debug_fs_exit(); -- GitLab From b01240a15a40907346d987603ef8cf9b110af314 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 7 Jun 2018 18:00:15 -0700 Subject: [PATCH 0308/1645] dsp: Fix AFE RTC set parameter Fix offset address to use set parameter structure while copying data from user instead of get parameter structure for AFE_PORT_CMD_SET_PARAM_V3 case. CRs-Fixed: 2256728 Change-Id: I61e41f366f365734a47080b79179fbe3021ee8a7 Signed-off-by: Vignesh Kulothungan --- dsp/rtac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/rtac.c b/dsp/rtac.c index b415ef0ed0ee..9d7c0d472580 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -1354,7 +1354,7 @@ static int send_rtac_afe_apr(void __user *buf, uint32_t opcode) if (copy_from_user(rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr, (void __user *) buf + offsetof(struct rtac_afe_user_data, - v3_get.param_hdr), + v3_set.param_hdr), payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); -- GitLab From 4cb7b2354d8153381a37cca2b853dd2709e543d3 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 1 May 2018 19:31:51 +0530 Subject: [PATCH 0309/1645] dsp: Add platform driver support for q6core To add child devices under q6core, update q6core to support as platform driver. Change-Id: I5a923d1a16899c03428c8e54701ea1c07653f486 Signed-off-by: Laxminath Kasam --- dsp/q6core.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/dsp/q6core.c b/dsp/q6core.c index 4974ad22be0b..9b0b588fdda1 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -12,6 +12,8 @@ #include #include +#include +#include #include #include #include @@ -20,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +37,8 @@ */ #define Q6_READY_TIMEOUT_MS 100 +#define ADSP_STATE_READY_TIMEOUT_MS 3000 + enum { META_CAL, CUST_TOP_CAL, @@ -1201,6 +1206,69 @@ static int q6core_init_cal_data(void) return ret; } +static int q6core_probe(struct platform_device *pdev) +{ + unsigned long timeout; + int adsp_ready = 0, rc; + + timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + + do { + if (!adsp_ready) { + adsp_ready = q6core_is_adsp_ready(); + dev_dbg(&pdev->dev, "%s: ADSP Audio is %s\n", __func__, + adsp_ready ? "ready" : "not ready"); + } + if (adsp_ready) + break; + + /* + * ADSP will be coming up after loading (PD up event) and + * it might not be fully up when the control reaches + * here. So, wait for 50msec before checking ADSP state + */ + msleep(50); + } while (time_after(timeout, jiffies)); + + if (!adsp_ready) { + dev_err(&pdev->dev, "%s: Timeout. ADSP Audio is %s\n", + __func__, + adsp_ready ? "ready" : "not ready"); + return -ETIMEDOUT; + } + rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); + if (rc) { + dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n", + __func__, rc); + return -EINVAL; + } + dev_dbg(&pdev->dev, "%s: added child node\n", __func__); + + return 0; +} + +static int q6core_remove(struct platform_device *pdev) +{ + of_platform_depopulate(&pdev->dev); + return 0; +} + +static const struct of_device_id q6core_of_match[] = { + { .compatible = "qcom,q6core-audio", }, + {}, +}; + +static struct platform_driver q6core_driver = { + .probe = q6core_probe, + .remove = q6core_remove, + .driver = { + .name = "q6core_audio", + .owner = THIS_MODULE, + .of_match_table = q6core_of_match, + } +}; + int __init core_init(void) { memset(&q6core_lcl, 0, sizeof(struct q6core_str)); @@ -1214,7 +1282,7 @@ int __init core_init(void) q6core_init_cal_data(); q6core_init_uevent_kset(); - return 0; + return platform_driver_register(&q6core_driver); } void core_exit(void) @@ -1223,6 +1291,7 @@ void core_exit(void) mutex_destroy(&q6core_lcl.ver_lock); q6core_delete_cal_data(); q6core_destroy_uevent_kset(); + platform_driver_unregister(&q6core_driver); } MODULE_DESCRIPTION("ADSP core driver"); MODULE_LICENSE("GPL v2"); -- GitLab From e0c3f3f39dc6de1d8c5e5faaee61c88c678217ab Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Fri, 1 Jun 2018 11:15:31 +0800 Subject: [PATCH 0310/1645] ASoC: codecs: fix inconsistency of boost state register value Use hardware default value for boost state in regmap. Use correct mask for initial value of boost state. Change-Id: Ia8b707ba0128662d47059d25325693bc8eaff723 Signed-off-by: Xiaojun Sang --- asoc/codecs/msm_sdw/msm_sdw_cdc.c | 4 ++-- asoc/codecs/msm_sdw/msm_sdw_regmap.c | 4 ++-- asoc/codecs/wcd9335-regmap.c | 4 ++-- asoc/codecs/wcd9335.c | 4 ++-- asoc/codecs/wcd934x/wcd934x-regmap.c | 4 ++-- asoc/codecs/wcd934x/wcd934x.c | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/asoc/codecs/msm_sdw/msm_sdw_cdc.c b/asoc/codecs/msm_sdw/msm_sdw_cdc.c index 15c9b4ece07a..69e340736ad9 100644 --- a/asoc/codecs/msm_sdw/msm_sdw_cdc.c +++ b/asoc/codecs/msm_sdw/msm_sdw_cdc.c @@ -1705,8 +1705,8 @@ static const struct msm_sdw_reg_mask_val msm_sdw_reg_init[] = { {MSM_SDW_BOOST1_BOOST_CFG1, 0x3F, 0x12}, {MSM_SDW_BOOST1_BOOST_CFG2, 0x1C, 0x08}, {MSM_SDW_COMPANDER8_CTL7, 0x1E, 0x18}, - {MSM_SDW_BOOST0_BOOST_CTL, 0x70, 0x58}, - {MSM_SDW_BOOST1_BOOST_CTL, 0x70, 0x58}, + {MSM_SDW_BOOST0_BOOST_CTL, 0x7C, 0x58}, + {MSM_SDW_BOOST1_BOOST_CTL, 0x7C, 0x58}, {MSM_SDW_RX7_RX_PATH_CFG1, 0x08, 0x08}, {MSM_SDW_RX8_RX_PATH_CFG1, 0x08, 0x08}, {MSM_SDW_TOP_TOP_CFG1, 0x02, 0x02}, diff --git a/asoc/codecs/msm_sdw/msm_sdw_regmap.c b/asoc/codecs/msm_sdw/msm_sdw_regmap.c index 412e92f5c7be..7613e65d2c19 100644 --- a/asoc/codecs/msm_sdw/msm_sdw_regmap.c +++ b/asoc/codecs/msm_sdw/msm_sdw_regmap.c @@ -65,11 +65,11 @@ static const struct reg_default msm_sdw_defaults[] = { { MSM_SDW_RX8_RX_PATH_MIX_SEC1, 0x00 }, /* Page #12 registers */ { MSM_SDW_BOOST0_BOOST_PATH_CTL, 0x00 }, - { MSM_SDW_BOOST0_BOOST_CTL, 0xba }, + { MSM_SDW_BOOST0_BOOST_CTL, 0xb2 }, { MSM_SDW_BOOST0_BOOST_CFG1, 0x00 }, { MSM_SDW_BOOST0_BOOST_CFG2, 0x00 }, { MSM_SDW_BOOST1_BOOST_PATH_CTL, 0x00 }, - { MSM_SDW_BOOST1_BOOST_CTL, 0xba }, + { MSM_SDW_BOOST1_BOOST_CTL, 0xb2 }, { MSM_SDW_BOOST1_BOOST_CFG1, 0x00 }, { MSM_SDW_BOOST1_BOOST_CFG2, 0x00 }, { MSM_SDW_AHB_BRIDGE_WR_DATA_0, 0x00 }, diff --git a/asoc/codecs/wcd9335-regmap.c b/asoc/codecs/wcd9335-regmap.c index c5ab181be3f5..a21257c85e07 100644 --- a/asoc/codecs/wcd9335-regmap.c +++ b/asoc/codecs/wcd9335-regmap.c @@ -1213,11 +1213,11 @@ static const struct reg_default wcd9335_defaults[] = { { WCD9335_CDC_CLSH_TEST1, 0x00 }, { WCD9335_CDC_CLSH_OVR_VREF, 0x00 }, { WCD9335_CDC_BOOST0_BOOST_PATH_CTL, 0x00 }, - { WCD9335_CDC_BOOST0_BOOST_CTL, 0xba }, + { WCD9335_CDC_BOOST0_BOOST_CTL, 0xb2 }, { WCD9335_CDC_BOOST0_BOOST_CFG1, 0x00 }, { WCD9335_CDC_BOOST0_BOOST_CFG2, 0x00 }, { WCD9335_CDC_BOOST1_BOOST_PATH_CTL, 0x00 }, - { WCD9335_CDC_BOOST1_BOOST_CTL, 0xba }, + { WCD9335_CDC_BOOST1_BOOST_CTL, 0xb2 }, { WCD9335_CDC_BOOST1_BOOST_CFG1, 0x00 }, { WCD9335_CDC_BOOST1_BOOST_CFG2, 0x00 }, { WCD9335_SWR_AHB_BRIDGE_WR_DATA_0, 0x00 }, diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 2f0c29ef4f79..03958f39c3c7 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -12405,8 +12405,8 @@ static const struct tasha_reg_mask_val tasha_codec_reg_init_common_val[] = { {WCD9335_CDC_CLSH_K2_MSB, 0x0F, 0x00}, {WCD9335_CDC_CLSH_K2_LSB, 0xFF, 0x60}, {WCD9335_CPE_SS_DMIC_CFG, 0x80, 0x00}, - {WCD9335_CDC_BOOST0_BOOST_CTL, 0x70, 0x58}, - {WCD9335_CDC_BOOST1_BOOST_CTL, 0x70, 0x58}, + {WCD9335_CDC_BOOST0_BOOST_CTL, 0x7C, 0x58}, + {WCD9335_CDC_BOOST1_BOOST_CTL, 0x7C, 0x58}, {WCD9335_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08}, {WCD9335_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08}, {WCD9335_ANA_LO_1_2, 0x3C, 0X3C}, diff --git a/asoc/codecs/wcd934x/wcd934x-regmap.c b/asoc/codecs/wcd934x/wcd934x-regmap.c index c726c623e547..e62b69c6931f 100644 --- a/asoc/codecs/wcd934x/wcd934x-regmap.c +++ b/asoc/codecs/wcd934x/wcd934x-regmap.c @@ -1248,11 +1248,11 @@ static const struct reg_default wcd934x_defaults[] = { { WCD934X_CDC_CLSH_TEST1, 0x00 }, { WCD934X_CDC_CLSH_OVR_VREF, 0x00 }, { WCD934X_CDC_BOOST0_BOOST_PATH_CTL, 0x00 }, - { WCD934X_CDC_BOOST0_BOOST_CTL, 0xba }, + { WCD934X_CDC_BOOST0_BOOST_CTL, 0xb2 }, { WCD934X_CDC_BOOST0_BOOST_CFG1, 0x00 }, { WCD934X_CDC_BOOST0_BOOST_CFG2, 0x00 }, { WCD934X_CDC_BOOST1_BOOST_PATH_CTL, 0x00 }, - { WCD934X_CDC_BOOST1_BOOST_CTL, 0xba }, + { WCD934X_CDC_BOOST1_BOOST_CTL, 0xb2 }, { WCD934X_CDC_BOOST1_BOOST_CFG1, 0x00 }, { WCD934X_CDC_BOOST1_BOOST_CFG2, 0x00 }, { WCD934X_CDC_VBAT_VBAT_PATH_CTL, 0x00 }, diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index b45631fc89c7..91b469068ca9 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -9431,8 +9431,8 @@ static const struct tavil_reg_mask_val tavil_codec_reg_init_common_val[] = { {WCD934X_CDC_CLSH_K2_MSB, 0x0F, 0x00}, {WCD934X_CDC_CLSH_K2_LSB, 0xFF, 0x60}, {WCD934X_CPE_SS_DMIC_CFG, 0x80, 0x00}, - {WCD934X_CDC_BOOST0_BOOST_CTL, 0x70, 0x58}, - {WCD934X_CDC_BOOST1_BOOST_CTL, 0x70, 0x58}, + {WCD934X_CDC_BOOST0_BOOST_CTL, 0x7C, 0x58}, + {WCD934X_CDC_BOOST1_BOOST_CTL, 0x7C, 0x58}, {WCD934X_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08}, {WCD934X_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08}, {WCD934X_CDC_TOP_TOP_CFG1, 0x02, 0x02}, -- GitLab From e964a75f32c7594befa81bb1b0824fd7c76663e9 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 5 Jun 2018 19:27:33 -0700 Subject: [PATCH 0311/1645] asoc: codecs: cancel all delayed work during SSR/PDR Cancel any pending delayed work in device down call to ensure no work is scheduled during or after a SSR/PDR sequence. Change-Id: I4cc89cb1a9d8be732c978044d4eea3cf6644ec30 Signed-off-by: Karthikeyan Mani Signed-off-by: Banajit Goswami --- asoc/codecs/wcd934x/wcd934x.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 91b469068ca9..92395d3401df 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -9972,11 +9972,35 @@ static int tavil_device_down(struct wcd9xxx *wcd9xxx) struct snd_soc_codec *codec; struct tavil_priv *priv; int count; + int decimator; + int ret; codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); priv = snd_soc_codec_get_drvdata(codec); for (count = 0; count < NUM_CODEC_DAIS; count++) priv->dai[count].bus_down_in_recovery = true; + + if (delayed_work_pending(&priv->spk_anc_dwork.dwork)) + cancel_delayed_work(&priv->spk_anc_dwork.dwork); + for (decimator = 0; decimator < WCD934X_NUM_DECIMATORS; decimator++) { + if (delayed_work_pending + (&priv->tx_mute_dwork[decimator].dwork)) + cancel_delayed_work + (&priv->tx_mute_dwork[decimator].dwork); + if (delayed_work_pending + (&priv->tx_hpf_work[decimator].dwork)) + cancel_delayed_work + (&priv->tx_hpf_work[decimator].dwork); + } + if (delayed_work_pending(&priv->power_gate_work)) + cancel_delayed_work_sync(&priv->power_gate_work); + if (delayed_work_pending(&priv->mbhc->wcd_mbhc.mbhc_btn_dwork)) { + ret = cancel_delayed_work(&priv->mbhc->wcd_mbhc.mbhc_btn_dwork); + if (ret) + priv->mbhc->wcd_mbhc.mbhc_cb->lock_sleep + (&priv->mbhc->wcd_mbhc, false); + } + if (priv->swr.ctrl_data) swrm_wcd_notify(priv->swr.ctrl_data[0].swr_pdev, SWR_DEVICE_DOWN, NULL); -- GitLab From 8c706aba3497135e2f453bb1c1a657341975f485 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Wed, 4 Apr 2018 17:48:46 +0530 Subject: [PATCH 0312/1645] dsp: afe: Add support for codec dma interface New codec dma interfaces have been introduced to connect LPASS and Codec macros. This change is to add codec dma interface related updates to Q6 AFE native driver. Change-Id: Ia3d1e5e80c694c8c4a7f904151adfcb504964b08 Signed-off-by: Mangesh Kunchamwar --- dsp/q6afe.c | 205 ++++++------------------------------- dsp/q6audio-v2.c | 44 +++++++- include/dsp/apr_audio-v2.h | 89 ++++++++++++++++ include/dsp/q6afe-v2.h | 8 ++ 4 files changed, 173 insertions(+), 173 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index c813ad12bd4c..6d2a5733f55c 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -575,183 +575,17 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) * * @port_id: AFE Port ID number * - * Returns RX/TX type on success or -EINVAL on failure. + * Returns RX/TX type. */ int afe_get_port_type(u16 port_id) { - int ret; + int ret = MSM_AFE_PORT_TYPE_RX; - switch (port_id) { - case PRIMARY_I2S_RX: - case SECONDARY_I2S_RX: - case MI2S_RX: - case HDMI_RX: - case DISPLAY_PORT_RX: - case AFE_PORT_ID_SPDIF_RX: - case SLIMBUS_0_RX: - case SLIMBUS_1_RX: - case SLIMBUS_2_RX: - case SLIMBUS_3_RX: - case SLIMBUS_4_RX: - case SLIMBUS_5_RX: - case SLIMBUS_6_RX: - case SLIMBUS_7_RX: - case SLIMBUS_8_RX: - case INT_BT_SCO_RX: - case INT_BT_A2DP_RX: - case INT_FM_RX: - case VOICE_PLAYBACK_TX: - case VOICE2_PLAYBACK_TX: - case RT_PROXY_PORT_001_RX: - case AUDIO_PORT_ID_I2S_RX: - case AFE_PORT_ID_PRIMARY_MI2S_RX: - case AFE_PORT_ID_SECONDARY_MI2S_RX: - case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1: - case AFE_PORT_ID_TERTIARY_MI2S_RX: - case AFE_PORT_ID_QUATERNARY_MI2S_RX: - case AFE_PORT_ID_QUINARY_MI2S_RX: - case AFE_PORT_ID_PRIMARY_PCM_RX: - case AFE_PORT_ID_SECONDARY_PCM_RX: - case AFE_PORT_ID_TERTIARY_PCM_RX: - case AFE_PORT_ID_QUATERNARY_PCM_RX: - case AFE_PORT_ID_QUINARY_PCM_RX: - case AFE_PORT_ID_PRIMARY_TDM_RX: - case AFE_PORT_ID_PRIMARY_TDM_RX_1: - case AFE_PORT_ID_PRIMARY_TDM_RX_2: - case AFE_PORT_ID_PRIMARY_TDM_RX_3: - case AFE_PORT_ID_PRIMARY_TDM_RX_4: - case AFE_PORT_ID_PRIMARY_TDM_RX_5: - case AFE_PORT_ID_PRIMARY_TDM_RX_6: - case AFE_PORT_ID_PRIMARY_TDM_RX_7: - case AFE_PORT_ID_SECONDARY_TDM_RX: - case AFE_PORT_ID_SECONDARY_TDM_RX_1: - case AFE_PORT_ID_SECONDARY_TDM_RX_2: - case AFE_PORT_ID_SECONDARY_TDM_RX_3: - case AFE_PORT_ID_SECONDARY_TDM_RX_4: - case AFE_PORT_ID_SECONDARY_TDM_RX_5: - case AFE_PORT_ID_SECONDARY_TDM_RX_6: - case AFE_PORT_ID_SECONDARY_TDM_RX_7: - case AFE_PORT_ID_TERTIARY_TDM_RX: - case AFE_PORT_ID_TERTIARY_TDM_RX_1: - case AFE_PORT_ID_TERTIARY_TDM_RX_2: - case AFE_PORT_ID_TERTIARY_TDM_RX_3: - case AFE_PORT_ID_TERTIARY_TDM_RX_4: - case AFE_PORT_ID_TERTIARY_TDM_RX_5: - case AFE_PORT_ID_TERTIARY_TDM_RX_6: - case AFE_PORT_ID_TERTIARY_TDM_RX_7: - case AFE_PORT_ID_QUATERNARY_TDM_RX: - case AFE_PORT_ID_QUATERNARY_TDM_RX_1: - case AFE_PORT_ID_QUATERNARY_TDM_RX_2: - case AFE_PORT_ID_QUATERNARY_TDM_RX_3: - case AFE_PORT_ID_QUATERNARY_TDM_RX_4: - case AFE_PORT_ID_QUATERNARY_TDM_RX_5: - case AFE_PORT_ID_QUATERNARY_TDM_RX_6: - case AFE_PORT_ID_QUATERNARY_TDM_RX_7: - case AFE_PORT_ID_QUINARY_TDM_RX: - case AFE_PORT_ID_QUINARY_TDM_RX_1: - case AFE_PORT_ID_QUINARY_TDM_RX_2: - case AFE_PORT_ID_QUINARY_TDM_RX_3: - case AFE_PORT_ID_QUINARY_TDM_RX_4: - case AFE_PORT_ID_QUINARY_TDM_RX_5: - case AFE_PORT_ID_QUINARY_TDM_RX_6: - case AFE_PORT_ID_QUINARY_TDM_RX_7: - case AFE_PORT_ID_USB_RX: - case AFE_PORT_ID_INT0_MI2S_RX: - case AFE_PORT_ID_INT1_MI2S_RX: - case AFE_PORT_ID_INT2_MI2S_RX: - case AFE_PORT_ID_INT3_MI2S_RX: - case AFE_PORT_ID_INT4_MI2S_RX: - case AFE_PORT_ID_INT5_MI2S_RX: - case AFE_PORT_ID_INT6_MI2S_RX: - ret = MSM_AFE_PORT_TYPE_RX; - break; - - case PRIMARY_I2S_TX: - case SECONDARY_I2S_TX: - case MI2S_TX: - case DIGI_MIC_TX: - case VOICE_RECORD_TX: - case SLIMBUS_0_TX: - case SLIMBUS_1_TX: - case SLIMBUS_2_TX: - case SLIMBUS_3_TX: - case SLIMBUS_4_TX: - case SLIMBUS_5_TX: - case SLIMBUS_6_TX: - case SLIMBUS_7_TX: - case SLIMBUS_8_TX: - case INT_FM_TX: - case VOICE_RECORD_RX: - case INT_BT_SCO_TX: - case RT_PROXY_PORT_001_TX: - case AFE_PORT_ID_PRIMARY_MI2S_TX: - case AFE_PORT_ID_SECONDARY_MI2S_TX: - case AFE_PORT_ID_TERTIARY_MI2S_TX: - case AFE_PORT_ID_QUATERNARY_MI2S_TX: - case AFE_PORT_ID_QUINARY_MI2S_TX: - case AFE_PORT_ID_SENARY_MI2S_TX: - case AFE_PORT_ID_PRIMARY_PCM_TX: - case AFE_PORT_ID_SECONDARY_PCM_TX: - case AFE_PORT_ID_TERTIARY_PCM_TX: - case AFE_PORT_ID_QUATERNARY_PCM_TX: - case AFE_PORT_ID_QUINARY_PCM_TX: - case AFE_PORT_ID_PRIMARY_TDM_TX: - case AFE_PORT_ID_PRIMARY_TDM_TX_1: - case AFE_PORT_ID_PRIMARY_TDM_TX_2: - case AFE_PORT_ID_PRIMARY_TDM_TX_3: - case AFE_PORT_ID_PRIMARY_TDM_TX_4: - case AFE_PORT_ID_PRIMARY_TDM_TX_5: - case AFE_PORT_ID_PRIMARY_TDM_TX_6: - case AFE_PORT_ID_PRIMARY_TDM_TX_7: - case AFE_PORT_ID_SECONDARY_TDM_TX: - case AFE_PORT_ID_SECONDARY_TDM_TX_1: - case AFE_PORT_ID_SECONDARY_TDM_TX_2: - case AFE_PORT_ID_SECONDARY_TDM_TX_3: - case AFE_PORT_ID_SECONDARY_TDM_TX_4: - case AFE_PORT_ID_SECONDARY_TDM_TX_5: - case AFE_PORT_ID_SECONDARY_TDM_TX_6: - case AFE_PORT_ID_SECONDARY_TDM_TX_7: - case AFE_PORT_ID_TERTIARY_TDM_TX: - case AFE_PORT_ID_TERTIARY_TDM_TX_1: - case AFE_PORT_ID_TERTIARY_TDM_TX_2: - case AFE_PORT_ID_TERTIARY_TDM_TX_3: - case AFE_PORT_ID_TERTIARY_TDM_TX_4: - case AFE_PORT_ID_TERTIARY_TDM_TX_5: - case AFE_PORT_ID_TERTIARY_TDM_TX_6: - case AFE_PORT_ID_TERTIARY_TDM_TX_7: - case AFE_PORT_ID_QUATERNARY_TDM_TX: - case AFE_PORT_ID_QUATERNARY_TDM_TX_1: - case AFE_PORT_ID_QUATERNARY_TDM_TX_2: - case AFE_PORT_ID_QUATERNARY_TDM_TX_3: - case AFE_PORT_ID_QUATERNARY_TDM_TX_4: - case AFE_PORT_ID_QUATERNARY_TDM_TX_5: - case AFE_PORT_ID_QUATERNARY_TDM_TX_6: - case AFE_PORT_ID_QUATERNARY_TDM_TX_7: - case AFE_PORT_ID_QUINARY_TDM_TX: - case AFE_PORT_ID_QUINARY_TDM_TX_1: - case AFE_PORT_ID_QUINARY_TDM_TX_2: - case AFE_PORT_ID_QUINARY_TDM_TX_3: - case AFE_PORT_ID_QUINARY_TDM_TX_4: - case AFE_PORT_ID_QUINARY_TDM_TX_5: - case AFE_PORT_ID_QUINARY_TDM_TX_6: - case AFE_PORT_ID_QUINARY_TDM_TX_7: - case AFE_PORT_ID_USB_TX: - case AFE_PORT_ID_INT0_MI2S_TX: - case AFE_PORT_ID_INT1_MI2S_TX: - case AFE_PORT_ID_INT2_MI2S_TX: - case AFE_PORT_ID_INT3_MI2S_TX: - case AFE_PORT_ID_INT4_MI2S_TX: - case AFE_PORT_ID_INT5_MI2S_TX: - case AFE_PORT_ID_INT6_MI2S_TX: + /* Odd numbered ports are TX and Rx are Even numbered */ + if (port_id & 0x1) ret = MSM_AFE_PORT_TYPE_TX; - break; - - default: - WARN_ON(1); - pr_err("%s: Invalid port id = 0x%x\n", - __func__, port_id); - ret = -EINVAL; - } + else + ret = MSM_AFE_PORT_TYPE_RX; return ret; } @@ -815,6 +649,15 @@ int afe_sizeof_cfg_cmd(u16 port_id) case AFE_PORT_ID_USB_TX: ret_size = SIZEOF_CFG_CMD(afe_param_id_usb_audio_cfg); break; + case AFE_PORT_ID_WSA_CODEC_DMA_RX_0: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_0: + case AFE_PORT_ID_WSA_CODEC_DMA_RX_1: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_1: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: + case AFE_PORT_ID_VA_CODEC_DMA_TX_0: + case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + ret_size = SIZEOF_CFG_CMD(afe_param_id_cdc_dma_cfg_t); + break; case AFE_PORT_ID_PRIMARY_PCM_RX: case AFE_PORT_ID_PRIMARY_PCM_TX: case AFE_PORT_ID_SECONDARY_PCM_RX: @@ -3554,6 +3397,15 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, case INT_FM_TX: cfg_type = AFE_PARAM_ID_INTERNAL_BT_FM_CONFIG; break; + case AFE_PORT_ID_WSA_CODEC_DMA_RX_0: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_0: + case AFE_PORT_ID_WSA_CODEC_DMA_RX_1: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_1: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: + case AFE_PORT_ID_VA_CODEC_DMA_TX_0: + case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + cfg_type = AFE_PARAM_ID_CODEC_DMA_CONFIG; + break; default: pr_err("%s: Invalid port id 0x%x\n", __func__, port_id); ret = -EINVAL; @@ -4113,6 +3965,15 @@ int afe_open(u16 port_id, case AFE_PORT_ID_USB_TX: cfg_type = AFE_PARAM_ID_USB_AUDIO_CONFIG; break; + case AFE_PORT_ID_WSA_CODEC_DMA_RX_0: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_0: + case AFE_PORT_ID_WSA_CODEC_DMA_RX_1: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_1: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: + case AFE_PORT_ID_VA_CODEC_DMA_TX_0: + case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + cfg_type = AFE_PARAM_ID_CODEC_DMA_CONFIG; + break; default: pr_err("%s: Invalid port id 0x%x\n", __func__, port_id); diff --git a/dsp/q6audio-v2.c b/dsp/q6audio-v2.c index f3a756b5bca3..a49632700c85 100644 --- a/dsp/q6audio-v2.c +++ b/dsp/q6audio-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -301,6 +301,20 @@ int q6audio_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_INT6_MI2S_RX; case AFE_PORT_ID_INT6_MI2S_TX: return IDX_AFE_PORT_ID_INT6_MI2S_TX; + case AFE_PORT_ID_WSA_CODEC_DMA_RX_0: + return IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_0; + case AFE_PORT_ID_WSA_CODEC_DMA_TX_0: + return IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_0; + case AFE_PORT_ID_WSA_CODEC_DMA_RX_1: + return IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_1; + case AFE_PORT_ID_WSA_CODEC_DMA_TX_1: + return IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_1; + case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: + return IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_2; + case AFE_PORT_ID_VA_CODEC_DMA_TX_0: + return IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_0; + case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + return IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_1; default: return -EINVAL; } } @@ -588,6 +602,20 @@ int q6audio_get_port_id(u16 port_id) return AFE_PORT_ID_INT6_MI2S_RX; case AFE_PORT_ID_INT6_MI2S_TX: return AFE_PORT_ID_INT6_MI2S_TX; + case AFE_PORT_ID_WSA_CODEC_DMA_RX_0: + return AFE_PORT_ID_WSA_CODEC_DMA_RX_0; + case AFE_PORT_ID_WSA_CODEC_DMA_TX_0: + return AFE_PORT_ID_WSA_CODEC_DMA_TX_0; + case AFE_PORT_ID_WSA_CODEC_DMA_RX_1: + return AFE_PORT_ID_WSA_CODEC_DMA_RX_1; + case AFE_PORT_ID_WSA_CODEC_DMA_TX_1: + return AFE_PORT_ID_WSA_CODEC_DMA_TX_1; + case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: + return AFE_PORT_ID_WSA_CODEC_DMA_TX_2; + case AFE_PORT_ID_VA_CODEC_DMA_TX_0: + return AFE_PORT_ID_VA_CODEC_DMA_TX_0; + case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + return AFE_PORT_ID_VA_CODEC_DMA_TX_1; default: pr_warn("%s: Invalid port_id %d\n", __func__, port_id); return -EINVAL; @@ -742,6 +770,13 @@ int q6audio_is_digital_pcm_interface(u16 port_id) case AFE_PORT_ID_INT5_MI2S_TX: case AFE_PORT_ID_INT6_MI2S_RX: case AFE_PORT_ID_INT6_MI2S_TX: + case AFE_PORT_ID_WSA_CODEC_DMA_RX_0: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_0: + case AFE_PORT_ID_WSA_CODEC_DMA_RX_1: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_1: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: + case AFE_PORT_ID_VA_CODEC_DMA_TX_0: + case AFE_PORT_ID_VA_CODEC_DMA_TX_1: break; default: ret = -EINVAL; @@ -922,6 +957,13 @@ int q6audio_validate_port(u16 port_id) case AFE_PORT_ID_INT5_MI2S_TX: case AFE_PORT_ID_INT6_MI2S_RX: case AFE_PORT_ID_INT6_MI2S_TX: + case AFE_PORT_ID_WSA_CODEC_DMA_RX_0: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_0: + case AFE_PORT_ID_WSA_CODEC_DMA_RX_1: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_1: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: + case AFE_PORT_ID_VA_CODEC_DMA_TX_0: + case AFE_PORT_ID_VA_CODEC_DMA_TX_1: { ret = 0; break; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index f9fef5a86b36..5a5fb6f57bd9 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1263,6 +1263,27 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_PORT_ID_USB_RX 0x7000 #define AFE_PORT_ID_USB_TX 0x7001 +/* AFE WSA Codec DMA Rx port 0 */ +#define AFE_PORT_ID_WSA_CODEC_DMA_RX_0 0xB000 + +/* AFE WSA Codec DMA Tx port 0 */ +#define AFE_PORT_ID_WSA_CODEC_DMA_TX_0 0xB001 + +/* AFE WSA Codec DMA Rx port 1 */ +#define AFE_PORT_ID_WSA_CODEC_DMA_RX_1 0xB002 + +/* AFE WSA Codec DMA Tx port 1 */ +#define AFE_PORT_ID_WSA_CODEC_DMA_TX_1 0xB003 + +/* AFE WSA Codec DMA Tx port 2 */ +#define AFE_PORT_ID_WSA_CODEC_DMA_TX_2 0xB005 + +/* AFE VA Codec DMA Tx port 0 */ +#define AFE_PORT_ID_VA_CODEC_DMA_TX_0 0xB021 + +/* AFE VA Codec DMA Tx port 1 */ +#define AFE_PORT_ID_VA_CODEC_DMA_TX_1 0xB023 + /* Generic pseudoport 1. */ #define AFE_PORT_ID_PSEUDOPORT_01 0x8001 /* Generic pseudoport 2. */ @@ -3920,6 +3941,73 @@ struct avs_dec_depacketizer_id_param_t { uint32_t dec_depacketizer_id; }; +/* ID of the parameter used by #AFE_MODULE_AUDIO_DEV_INTERFACE to configure + * the Codec DMA interface. + */ + +#define AFE_PARAM_ID_CODEC_DMA_CONFIG 0x000102B8 + +/* Version information used to handle future additions to codec DMA + * configuration (for backward compatibility). + */ +#define AFE_API_VERSION_CODEC_DMA_CONFIG 0x1 + +/* Payload of the AFE_PARAM_ID_CODEC_DMA_CONFIG parameter used by + * AFE_MODULE_AUDIO_DEV_INTERFACE. + */ +struct afe_param_id_cdc_dma_cfg_t { + uint32_t cdc_dma_cfg_minor_version; + /* Tracks the configuration of this parameter. + * Supported values: #AFE_API_VERSION_CODEC_DMA_CONFIG + */ + + uint32_t sample_rate; + /* Sampling rate of the port. + * Supported values: + * - #AFE_PORT_SAMPLE_RATE_8K + * - #AFE_PORT_SAMPLE_RATE_11_025K + * - #AFE_PORT_SAMPLE_RATE_12K + * - #AFE_PORT_SAMPLE_RATE_16K + * - #AFE_PORT_SAMPLE_RATE_22_05K + * - #AFE_PORT_SAMPLE_RATE_24K + * - #AFE_PORT_SAMPLE_RATE_32K + * - #AFE_PORT_SAMPLE_RATE_44_1K + * - #AFE_PORT_SAMPLE_RATE_48K + * - #AFE_PORT_SAMPLE_RATE_88_2K + * - #AFE_PORT_SAMPLE_RATE_96K + * - #AFE_PORT_SAMPLE_RATE_176_4K + * - #AFE_PORT_SAMPLE_RATE_192K + * - #AFE_PORT_SAMPLE_RATE_352_8K + * - #AFE_PORT_SAMPLE_RATE_384K + */ + + uint16_t bit_width; + /* Bit width of the sample. + * Supported values: 16, 24, 32 + */ + + uint16_t data_format; + /* Data format supported by the codec DMA interface. + * Supported values: + * - #AFE_LINEAR_PCM_DATA + * - #AFE_LINEAR_PCM_DATA_PACKED_16BIT + */ + + uint16_t num_channels; + /* Number of channels. + * Supported values: 1 to Maximum number of channels supported + * for each interface + */ + + uint16_t active_channels_mask; + /* Active channels mask to denote the bit mask for active channels. + * Bits 0 to 7 denote channels 0 to 7. A 1 denotes the channel is active + * while a 0 denotes a channel is inactive. + * Supported values: + * Any mask with number of active bits equal to num_channels + */ +} __packed; + union afe_port_config { struct afe_param_id_pcm_cfg pcm; struct afe_param_id_i2s_cfg i2s; @@ -3942,6 +4030,7 @@ union afe_port_config { struct avs_dec_depacketizer_id_param_t dec_depkt_id_param; struct afe_enc_level_to_bitrate_map_param_t map_param; struct afe_enc_dec_imc_info_param_t imc_info_param; + struct afe_param_id_cdc_dma_cfg_t cdc_dma; } __packed; #define AFE_PORT_CMD_DEVICE_START 0x000100E5 diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index b2bf54769259..b420ef333b56 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -224,6 +224,14 @@ enum { IDX_AFE_PORT_ID_QUINARY_TDM_TX_6, IDX_AFE_PORT_ID_QUINARY_TDM_RX_7, IDX_AFE_PORT_ID_QUINARY_TDM_TX_7, + /* IDX 161 to 166 */ + IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_0, + IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_0, + IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_1, + IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_1, + IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_2, + IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_0, + IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_1, AFE_MAX_PORTS }; -- GitLab From a21bef610b333f6d0307b33c0e24cf052bfe5467 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Wed, 4 Apr 2018 16:38:54 +0530 Subject: [PATCH 0313/1645] asoc: msm: routing: Add support for codec dma interfaces in routing driver New codec dma interfaces have been introduced to connect LPASS and Codec macros. This change is to add support routing for codec dma interface backends and their corresponding front ends. Change-Id: I8145921559457c50408d35c90b13d018e1c32c8a Signed-off-by: Mangesh Kunchamwar --- asoc/msm-pcm-routing-v2.c | 757 +++++++++++++++++++++++++++++++++++++- asoc/msm-pcm-routing-v2.h | 17 + 2 files changed, 770 insertions(+), 4 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 1dbba55c8494..aca4ddb43811 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -582,6 +582,20 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_INT6_MI2S_RX}, { AFE_PORT_ID_INT6_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_INT6_MI2S_TX}, + { AFE_PORT_ID_WSA_CODEC_DMA_RX_0, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_WSA_CDC_DMA_RX_0}, + { AFE_PORT_ID_WSA_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_WSA_CDC_DMA_TX_0}, + { AFE_PORT_ID_WSA_CODEC_DMA_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_WSA_CDC_DMA_RX_1}, + { AFE_PORT_ID_WSA_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_WSA_CDC_DMA_TX_1}, + { AFE_PORT_ID_WSA_CODEC_DMA_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_WSA_CDC_DMA_TX_2}, + { AFE_PORT_ID_VA_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_VA_CDC_DMA_TX_0}, + { AFE_PORT_ID_VA_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_VA_CDC_DMA_TX_1}, }; /* Track ASM playback & capture sessions of DAI @@ -2903,7 +2917,9 @@ static const char *const be_name[] = { "INT0_MI2S_RX", "INT0_MI2S_TX", "INT1_MI2S_RX", "INT1_MI2S_TX", "INT2_MI2S_RX", "INT2_MI2S_TX", "INT3_MI2S_RX", "INT3_MI2S_TX", "INT4_MI2S_RX", "INT4_MI2S_TX", "INT5_MI2S_RX", "INT5_MI2S_TX", -"INT6_MI2S_RX", "INT6_MI2S_TX" +"INT6_MI2S_RX", "INT6_MI2S_TX", "WSA_CDC_DMA_RX_0", +"WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_RX_1", "WSA_CDC_DMA_TX_1", +"WSA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_1" }; static SOC_ENUM_SINGLE_DECL(mm1_channel_mux, @@ -3687,6 +3703,26 @@ static int msm_routing_ec_ref_rx_put(struct snd_kcontrol *kcontrol, msm_route_ec_ref_rx = 23; ec_ref_port_id = AFE_PORT_ID_HDMI_OVER_DP_RX; break; + case 24: + msm_route_ec_ref_rx = 24; + ec_ref_port_id = AFE_PORT_ID_WSA_CODEC_DMA_RX_0; + break; + case 25: + msm_route_ec_ref_rx = 25; + ec_ref_port_id = AFE_PORT_ID_WSA_CODEC_DMA_RX_1; + break; + case 26: + msm_route_ec_ref_rx = 26; + ec_ref_port_id = AFE_PORT_ID_WSA_CODEC_DMA_TX_0; + break; + case 27: + msm_route_ec_ref_rx = 27; + ec_ref_port_id = AFE_PORT_ID_WSA_CODEC_DMA_TX_1; + break; + case 28: + msm_route_ec_ref_rx = 28; + ec_ref_port_id = AFE_PORT_ID_WSA_CODEC_DMA_TX_2; + break; default: msm_route_ec_ref_rx = 0; /* NONE */ pr_err("%s EC ref rx %ld not valid\n", @@ -3709,7 +3745,10 @@ static const char *const ec_ref_rx[] = { "None", "SLIM_RX", "I2S_RX", "SLIM_5_RX", "SLIM_1_TX", "QUAT_TDM_TX_1", "QUAT_TDM_RX_0", "QUAT_TDM_RX_1", "QUAT_TDM_RX_2", "SLIM_6_RX", "TERT_MI2S_RX", "QUAT_MI2S_RX", "TERT_TDM_TX_0", "USB_AUDIO_RX", - "INT0_MI2S_RX", "INT4_MI2S_RX", "INT3_MI2S_TX", "DISPLAY_PORT"}; + "INT0_MI2S_RX", "INT4_MI2S_RX", "INT3_MI2S_TX", "DISPLAY_PORT", + "WSA_CDC_DMA_RX_0", "WSA_CDC_DMA_RX_1", + "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_2" +}; static const struct soc_enum msm_route_ec_ref_rx_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ec_ref_rx), ec_ref_rx), @@ -5380,6 +5419,140 @@ static const struct snd_kcontrol_new slimbus_6_rx_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new wsa_cdc_dma_rx_1_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new slimbus_7_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_7_RX, @@ -8171,6 +8344,26 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = { MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul2_mixer_controls[] = { @@ -8310,6 +8503,26 @@ static const struct snd_kcontrol_new mmul2_mixer_controls[] = { MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul3_mixer_controls[] = { @@ -8449,6 +8662,26 @@ static const struct snd_kcontrol_new mmul3_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul4_mixer_controls[] = { @@ -8584,6 +8817,26 @@ static const struct snd_kcontrol_new mmul4_mixer_controls[] = { MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul5_mixer_controls[] = { @@ -8743,6 +8996,26 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = { MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul6_mixer_controls[] = { @@ -8882,6 +9155,26 @@ static const struct snd_kcontrol_new mmul6_mixer_controls[] = { MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul8_mixer_controls[] = { @@ -9025,6 +9318,26 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = { MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul16_mixer_controls[] = { @@ -9168,6 +9481,26 @@ static const struct snd_kcontrol_new mmul16_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul9_mixer_controls[] = { @@ -9251,6 +9584,26 @@ static const struct snd_kcontrol_new mmul9_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul10_mixer_controls[] = { @@ -9358,6 +9711,26 @@ static const struct snd_kcontrol_new mmul10_mixer_controls[] = { MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul17_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, @@ -9400,6 +9773,26 @@ static const struct snd_kcontrol_new mmul17_mixer_controls[] = { MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul18_mixer_controls[] = { @@ -9443,6 +9836,26 @@ static const struct snd_kcontrol_new mmul18_mixer_controls[] = { MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul19_mixer_controls[] = { @@ -9486,6 +9899,26 @@ static const struct snd_kcontrol_new mmul19_mixer_controls[] = { MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul20_mixer_controls[] = { @@ -9589,6 +10022,26 @@ static const struct snd_kcontrol_new mmul20_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul28_mixer_controls[] = { @@ -9632,7 +10085,26 @@ static const struct snd_kcontrol_new mmul28_mixer_controls[] = { MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul29_mixer_controls[] = { @@ -9676,7 +10148,26 @@ static const struct snd_kcontrol_new mmul29_mixer_controls[] = { MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { @@ -10253,6 +10744,52 @@ static const struct snd_kcontrol_new quat_tdm_rx_2_voice_mixer_controls[] = { msm_routing_put_voice_mixer), }; +static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new wsa_cdc_dma_rx_1_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + static const struct snd_kcontrol_new stub_rx_mixer_controls[] = { SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_EXTPROC_RX, @@ -10341,6 +10878,12 @@ static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { SOC_DOUBLE_EXT("QUAT_TDM_TX_0_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { @@ -10394,6 +10937,12 @@ static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { SOC_DOUBLE_EXT("USB_AUDIO_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { @@ -10461,6 +11010,12 @@ static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { @@ -10540,6 +11095,14 @@ static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), }; static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = { @@ -10603,6 +11166,14 @@ static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), }; static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = { @@ -10666,6 +11237,15 @@ static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + }; static const struct snd_kcontrol_new tx_qchat_mixer_controls[] = { @@ -10733,6 +11313,12 @@ static const struct snd_kcontrol_new tx_qchat_mixer_controls[] = { MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new int0_mi2s_rx_port_mixer_controls[] = { @@ -14775,6 +15361,14 @@ static const char * const slim0_rx_vi_fb_tx_rch_mux_text[] = { "ZERO", "SLIM4_TX" }; +static const char * const wsa_rx_0_vi_fb_tx_lch_mux_text[] = { + "ZERO", "WSA_CDC_DMA_TX_0" +}; + +static const char * const wsa_rx_0_vi_fb_tx_rch_mux_text[] = { + "ZERO", "WSA_CDC_DMA_TX_0" +}; + static const char * const mi2s_rx_vi_fb_tx_mux_text[] = { "ZERO", "SENARY_TX" }; @@ -14795,6 +15389,15 @@ static const int const slim0_rx_vi_fb_tx_rch_value[] = { MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SLIMBUS_4_TX }; +static const int const wsa_rx_0_vi_fb_tx_lch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0 +}; + +static const int const wsa_rx_0_vi_fb_tx_rch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0 +}; + + static const int const mi2s_rx_vi_fb_tx_value[] = { MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SENARY_MI2S_TX }; @@ -14817,6 +15420,16 @@ static const struct soc_enum slim0_rx_vi_fb_rch_mux_enum = ARRAY_SIZE(slim0_rx_vi_fb_tx_rch_mux_text), slim0_rx_vi_fb_tx_rch_mux_text, slim0_rx_vi_fb_tx_rch_value); +static const struct soc_enum wsa_rx_0_vi_fb_lch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, 0, 0, + ARRAY_SIZE(wsa_rx_0_vi_fb_tx_lch_mux_text), + wsa_rx_0_vi_fb_tx_lch_mux_text, wsa_rx_0_vi_fb_tx_lch_value); + +static const struct soc_enum wsa_rx_0_vi_fb_rch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, 0, 0, + ARRAY_SIZE(wsa_rx_0_vi_fb_tx_rch_mux_text), + wsa_rx_0_vi_fb_tx_rch_mux_text, wsa_rx_0_vi_fb_tx_rch_value); + static const struct soc_enum mi2s_rx_vi_fb_mux_enum = SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_PRI_MI2S_RX, 0, 0, ARRAY_SIZE(mi2s_rx_vi_fb_tx_mux_text), @@ -14844,6 +15457,16 @@ static const struct snd_kcontrol_new slim0_rx_vi_fb_rch_mux = slim0_rx_vi_fb_rch_mux_enum, spkr_prot_get_vi_rch_port, spkr_prot_put_vi_rch_port); +static const struct snd_kcontrol_new wsa_rx_0_vi_fb_lch_mux = + SOC_DAPM_ENUM_EXT("WSA_RX_0_VI_FB_LCH_MUX", + wsa_rx_0_vi_fb_lch_mux_enum, spkr_prot_get_vi_lch_port, + spkr_prot_put_vi_lch_port); + +static const struct snd_kcontrol_new wsa_rx_0_vi_fb_rch_mux = + SOC_DAPM_ENUM_EXT("WSA_RX_0_VI_FB_RCH_MUX", + wsa_rx_0_vi_fb_rch_mux_enum, spkr_prot_get_vi_rch_port, + spkr_prot_put_vi_rch_port); + static const struct snd_kcontrol_new mi2s_rx_vi_fb_mux = SOC_DAPM_ENUM_EXT("PRI_MI2S_RX_VI_FB_MUX", mi2s_rx_vi_fb_mux_enum, spkr_prot_get_vi_lch_port, @@ -15503,6 +16126,20 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_7", "Quinary TDM7 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("WSA_CDC_DMA_RX_0", "WSA CDC DMA0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("WSA_CDC_DMA_TX_0", "WSA CDC DMA0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("WSA_CDC_DMA_RX_1", "WSA CDC DMA1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("WSA_CDC_DMA_TX_1", "WSA CDC DMA1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("WSA_CDC_DMA_TX_2", "WSA CDC DMA2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VA_CDC_DMA_TX_0", "VA CDC DMA0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VA_CDC_DMA_TX_1", "VA CDC DMA1 Capture", + 0, 0, 0, 0), /* incall */ SND_SOC_DAPM_AIF_OUT("VOICE_PLAYBACK_TX", "Voice Farend Playback", 0, 0, 0, 0), @@ -15732,6 +16369,12 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUIN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, quin_tdm_rx_3_mixer_controls, ARRAY_SIZE(quin_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + wsa_cdc_dma_rx_0_mixer_controls, + ARRAY_SIZE(wsa_cdc_dma_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + wsa_cdc_dma_rx_1_mixer_controls, + ARRAY_SIZE(wsa_cdc_dma_rx_1_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0, mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0, @@ -16083,6 +16726,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &slim0_rx_vi_fb_lch_mux), SND_SOC_DAPM_MUX("SLIM0_RX_VI_FB_RCH_MUX", SND_SOC_NOPM, 0, 0, &slim0_rx_vi_fb_rch_mux), + SND_SOC_DAPM_MUX("WSA_RX_0_VI_FB_LCH_MUX", SND_SOC_NOPM, 0, 0, + &wsa_rx_0_vi_fb_lch_mux), + SND_SOC_DAPM_MUX("WSA_RX_0_VI_FB_RCH_MUX", SND_SOC_NOPM, 0, 0, + &wsa_rx_0_vi_fb_rch_mux), SND_SOC_DAPM_MUX("PRI_MI2S_RX_VI_FB_MUX", SND_SOC_NOPM, 0, 0, &mi2s_rx_vi_fb_mux), SND_SOC_DAPM_MUX("INT4_MI2S_RX_VI_FB_MONO_CH_MUX", SND_SOC_NOPM, 0, 0, @@ -16215,6 +16862,42 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_5_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, {"SLIMBUS_5_RX", NULL, "SLIMBUS_5_RX Audio Mixer"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0 Audio Mixer"}, + + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"WSA_CDC_DMA_RX_1", NULL, "WSA_CDC_DMA_RX_1 Audio Mixer"}, + {"HDMI Mixer", "MultiMedia1", "MM_DL1"}, {"HDMI Mixer", "MultiMedia2", "MM_DL2"}, {"HDMI Mixer", "MultiMedia3", "MM_DL3"}, @@ -17116,6 +17799,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia1 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia1 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia2 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia2 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -17137,6 +17825,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia2 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia2 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia2 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia3 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia3 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -17158,6 +17851,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia3 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia3 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia3 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia4 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia4 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -17179,6 +17877,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia4 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia4 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia4 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia5 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia5 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -17200,6 +17903,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia5 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia5 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia6 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia6 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -17221,6 +17929,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia6 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia6 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia8 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia8 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -17242,6 +17955,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia8 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia8 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia9 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"MultiMedia9 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, @@ -17255,6 +17974,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia9 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia9 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia9 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia10 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"MultiMedia10 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, @@ -17289,6 +18014,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia20 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia20 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia20 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, @@ -17315,6 +18046,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia16 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia16 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, {"MultiMedia16 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, @@ -18831,6 +19568,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "QUIN_TDM_RX_1"}, {"BE_OUT", NULL, "QUIN_TDM_RX_2"}, {"BE_OUT", NULL, "QUIN_TDM_RX_3"}, + {"BE_OUT", NULL, "WSA_CDC_DMA_RX_0"}, + {"BE_OUT", NULL, "WSA_CDC_DMA_RX_1"}, {"PRI_I2S_TX", NULL, "BE_IN"}, {"MI2S_TX", NULL, "BE_IN"}, @@ -18871,11 +19610,15 @@ static const struct snd_soc_dapm_route intercon[] = { {"INCALL_RECORD_RX", NULL, "BE_IN"}, {"SLIM0_RX_VI_FB_LCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"}, {"SLIM0_RX_VI_FB_RCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"}, + {"WSA_RX_0_VI_FB_LCH_MUX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"WSA_RX_0_VI_FB_RCH_MUX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, {"PRI_MI2S_RX_VI_FB_MUX", "SENARY_TX", "SENARY_TX"}, {"INT4_MI2S_RX_VI_FB_MONO_CH_MUX", "INT5_MI2S_TX", "INT5_MI2S_TX"}, {"INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", "INT5_MI2S_TX", "INT5_MI2S_TX"}, {"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_LCH_MUX"}, {"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_RCH_MUX"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_RX_0_VI_FB_LCH_MUX"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_RX_0_VI_FB_RCH_MUX"}, {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_VI_FB_MUX"}, {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_MONO_CH_MUX"}, {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_STEREO_CH_MUX"}, @@ -18899,6 +19642,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_TX_1", NULL, "BE_IN"}, {"QUIN_TDM_TX_2", NULL, "BE_IN"}, {"QUIN_TDM_TX_3", NULL, "BE_IN"}, + {"WSA_CDC_DMA_TX_0", NULL, "BE_IN"}, + {"WSA_CDC_DMA_TX_1", NULL, "BE_IN"}, + {"WSA_CDC_DMA_TX_2", NULL, "BE_IN"}, + {"VA_CDC_DMA_TX_0", NULL, "BE_IN"}, + {"VA_CDC_DMA_TX_1", NULL, "BE_IN"}, + }; static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index b0026124000d..345e4d9cb98e 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -185,6 +185,16 @@ #define LPASS_BE_INT5_MI2S_TX "INT5_MI2S_TX" #define LPASS_BE_INT6_MI2S_RX "INT6_MI2S_RX" #define LPASS_BE_INT6_MI2S_TX "INT6_MI2S_TX" + +#define LPASS_BE_WSA_CDC_DMA_RX_0 "WSA_CDC_DMA_RX_0" +#define LPASS_BE_WSA_CDC_DMA_TX_0 "WSA_CDC_DMA_TX_0" +#define LPASS_BE_WSA_CDC_DMA_RX_1 "WSA_CDC_DMA_RX_1" +#define LPASS_BE_WSA_CDC_DMA_TX_1 "WSA_CDC_DMA_TX_1" +#define LPASS_BE_WSA_CDC_DMA_TX_2 "WSA_CDC_DMA_TX_2" +#define LPASS_BE_VA_CDC_DMA_TX_0 "VA_CDC_DMA_TX_0" +#define LPASS_BE_VA_CDC_DMA_TX_1 "VA_CDC_DMA_TX_1" + + /* For multimedia front-ends, asm session is allocated dynamically. * Hence, asm session/multimedia front-end mapping has to be maintained. * Due to this reason, additional multimedia front-end must be placed before @@ -399,6 +409,13 @@ enum { MSM_BACKEND_DAI_INT5_MI2S_TX, MSM_BACKEND_DAI_INT6_MI2S_RX, MSM_BACKEND_DAI_INT6_MI2S_TX, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_BACKEND_DAI_MAX, }; -- GitLab From d191c5fe1359a6dd2ca14173e1e2ceb6c1c6cd10 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Wed, 4 Apr 2018 10:56:58 +0530 Subject: [PATCH 0314/1645] asoc: Add support for codec dma interface New codec dma interfaces have been introduced to connect LPASS and Codec macros. This change is to add codec dma interface dai driver and corresponding dais. Change-Id: I307950ff3cbfe80c966bd9de21803655bb46e05c Signed-off-by: Mangesh Kunchamwar --- asoc/msm-dai-q6-v2.c | 543 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 543 insertions(+) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 12fb6968e9a8..7a3dd4e57afa 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -224,6 +224,15 @@ struct msm_dai_q6_mi2s_dai_data { struct msm_dai_q6_mi2s_dai_config rx_dai; }; +struct msm_dai_q6_cdc_dma_dai_data { + DECLARE_BITMAP(status_mask, STATUS_MAX); + DECLARE_BITMAP(hwfree_status, STATUS_MAX); + u32 rate; + u32 channels; + u32 bitwidth; + union afe_port_config port_config; +}; + struct msm_dai_q6_auxpcm_dai_data { /* BITMAP to track Rx and Tx port usage count */ DECLARE_BITMAP(auxpcm_port_status, STATUS_MAX); @@ -270,6 +279,15 @@ static const struct soc_enum mi2s_config_enum[] = { SOC_ENUM_SINGLE_EXT(2, mi2s_vi_feed_mono), }; +static const char *const cdc_dma_format[] = { + "UNPACKED", + "PACKED_16B", +}; + +static const struct soc_enum cdc_dma_config_enum[] = { + SOC_ENUM_SINGLE_EXT(2, cdc_dma_format), +}; + static const char *const sb_format[] = { "UNPACKED", "PACKED_16B", @@ -5223,6 +5241,7 @@ static int msm_dai_q6_probe(struct platform_device *pdev) static int msm_dai_q6_remove(struct platform_device *pdev) { + of_platform_depopulate(&pdev->dev); return 0; } @@ -9048,6 +9067,511 @@ static struct platform_driver msm_dai_q6_tdm_driver = { }, }; +static int msm_dai_q6_cdc_dma_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + int value = ucontrol->value.integer.value[0]; + + dai_data->port_config.cdc_dma.data_format = value; + pr_debug("%s: format = %d\n", __func__, value); + return 0; +} + +static int msm_dai_q6_cdc_dma_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + ucontrol->value.integer.value[0] = + dai_data->port_config.cdc_dma.data_format; + return 0; +} +static const struct snd_kcontrol_new cdc_dma_config_controls[] = { + SOC_ENUM_EXT("WSA_CDC_DMA_0 TX Format", cdc_dma_config_enum[0], + msm_dai_q6_cdc_dma_format_get, + msm_dai_q6_cdc_dma_format_put), +}; + +/* SOC probe for codec DMA interface */ +static int msm_dai_q6_dai_cdc_dma_probe(struct snd_soc_dai *dai) +{ + struct msm_dai_q6_cdc_dma_dai_data *dai_data = NULL; + int rc = 0; + + if (!dai) { + pr_err("%s: Invalid params dai\n", __func__); + return -EINVAL; + } + if (!dai->dev) { + pr_err("%s: Invalid params dai dev\n", __func__); + return -EINVAL; + } + + msm_dai_q6_set_dai_id(dai); + dai_data = dev_get_drvdata(dai->dev); + + switch (dai->id) { + case AFE_PORT_ID_WSA_CODEC_DMA_TX_0: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&cdc_dma_config_controls[0], + dai_data)); + break; + default: + break; + } + + if (rc < 0) + dev_err(dai->dev, "%s: err add config ctl, DAI = %s\n", + __func__, dai->name); + rc = msm_dai_q6_dai_add_route(dai); + return rc; +} + +static int msm_dai_q6_dai_cdc_dma_remove(struct snd_soc_dai *dai) +{ + struct msm_dai_q6_cdc_dma_dai_data *dai_data = + dev_get_drvdata(dai->dev); + int rc = 0; + + /* If AFE port is still up, close it */ + if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + dev_dbg(dai->dev, "%s: stop codec dma port:%d\n", __func__, + dai->id); + rc = afe_close(dai->id); /* can block */ + if (rc < 0) + dev_err(dai->dev, "fail to close AFE port\n"); + clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); + } + return rc; +} + +static int msm_dai_q6_cdc_dma_set_channel_map(struct snd_soc_dai *dai, + unsigned int tx_num_ch, unsigned int *tx_ch_mask, + unsigned int rx_num_ch, unsigned int *rx_ch_mask) + +{ + struct msm_dai_q6_cdc_dma_dai_data *dai_data = + dev_get_drvdata(dai->dev); + unsigned int ch_mask = 0, ch_num = 0; + + dev_dbg(dai->dev, "%s: id = %d\n", __func__, dai->id); + switch (dai->id) { + case AFE_PORT_ID_WSA_CODEC_DMA_RX_0: + case AFE_PORT_ID_WSA_CODEC_DMA_RX_1: + if (!rx_ch_mask) { + dev_err(dai->dev, "%s: invalid rx ch mask\n", __func__); + return -EINVAL; + } + if (rx_num_ch > AFE_PORT_MAX_AUDIO_CHAN_CNT) { + dev_err(dai->dev, "%s: invalid rx_num_ch %d\n", + __func__, rx_num_ch); + return -EINVAL; + } + ch_mask = *rx_ch_mask; + ch_num = rx_num_ch; + break; + case AFE_PORT_ID_WSA_CODEC_DMA_TX_0: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_1: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: + case AFE_PORT_ID_VA_CODEC_DMA_TX_0: + case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + if (!tx_ch_mask) { + dev_err(dai->dev, "%s: invalid tx ch mask\n", __func__); + return -EINVAL; + } + if (tx_num_ch > AFE_PORT_MAX_AUDIO_CHAN_CNT) { + dev_err(dai->dev, "%s: invalid tx_num_ch %d\n", + __func__, tx_num_ch); + return -EINVAL; + } + ch_mask = *tx_ch_mask; + ch_num = tx_num_ch; + break; + default: + dev_err(dai->dev, "%s: invalid dai id %d\n", __func__, dai->id); + return -EINVAL; + } + + dai_data->port_config.cdc_dma.active_channels_mask = ch_mask; + dev_dbg(dai->dev, "%s: CDC_DMA_%d_ch cnt[%d] ch mask[0x%x]\n", __func__, + dai->id, ch_num, ch_mask); + return 0; +} + +static int msm_dai_q6_cdc_dma_hw_params( + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_cdc_dma_dai_data *dai_data = + dev_get_drvdata(dai->dev); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + case SNDRV_PCM_FORMAT_SPECIAL: + dai_data->port_config.cdc_dma.bit_width = 16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + dai_data->port_config.cdc_dma.bit_width = 24; + break; + case SNDRV_PCM_FORMAT_S32_LE: + dai_data->port_config.cdc_dma.bit_width = 32; + break; + default: + dev_err(dai->dev, "%s: format %d\n", + __func__, params_format(params)); + return -EINVAL; + } + + dai_data->port_config.cdc_dma.cdc_dma_cfg_minor_version = + AFE_API_VERSION_CODEC_DMA_CONFIG; + dai_data->port_config.cdc_dma.sample_rate = dai_data->rate; + dai_data->port_config.cdc_dma.num_channels = dai_data->channels; + dev_dbg(dai->dev, "%s: bit_wd[%hu] format[%hu]\n" + "num_channel %hu sample_rate %d\n", __func__, + dai_data->port_config.cdc_dma.bit_width, + dai_data->port_config.cdc_dma.data_format, + dai_data->port_config.cdc_dma.num_channels, + dai_data->rate); + + return 0; +} + +static int msm_dai_q6_cdc_dma_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_cdc_dma_dai_data *dai_data = + dev_get_drvdata(dai->dev); + int rc = 0; + + if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + rc = afe_port_start(dai->id, &dai_data->port_config, + dai_data->rate); + if (rc < 0) + dev_err(dai->dev, "fail to open AFE port 0x%x\n", + dai->id); + else + set_bit(STATUS_PORT_STARTED, + dai_data->status_mask); + } + return rc; +} + + +static void msm_dai_q6_cdc_dma_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + int rc = 0; + + if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + dev_dbg(dai->dev, "%s: stop AFE port:%d\n", __func__, + dai->id); + rc = afe_close(dai->id); /* can block */ + if (rc < 0) + dev_err(dai->dev, "fail to close AFE port\n"); + + dev_dbg(dai->dev, "%s: dai_data->status_mask = %ld\n", __func__, + *dai_data->status_mask); + clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); + } + + if (test_bit(STATUS_PORT_STARTED, dai_data->hwfree_status)) + clear_bit(STATUS_PORT_STARTED, dai_data->hwfree_status); +} + + +static struct snd_soc_dai_ops msm_dai_q6_cdc_dma_ops = { + .prepare = msm_dai_q6_cdc_dma_prepare, + .hw_params = msm_dai_q6_cdc_dma_hw_params, + .shutdown = msm_dai_q6_cdc_dma_shutdown, + .set_channel_map = msm_dai_q6_cdc_dma_set_channel_map, +}; + +static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { + { + .playback = { + .stream_name = "WSA CDC DMA0 Playback", + .aif_name = "WSA_CDC_DMA_RX_0", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_WSA_CODEC_DMA_RX_0, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .capture = { + .stream_name = "WSA CDC DMA0 Capture", + .aif_name = "WSA_CDC_DMA_TX_0", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_WSA_CODEC_DMA_TX_0, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .playback = { + .stream_name = "WSA CDC DMA1 Playback", + .aif_name = "WSA_CDC_DMA_RX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_WSA_CODEC_DMA_RX_1, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .capture = { + .stream_name = "WSA CDC DMA1 Capture", + .aif_name = "WSA_CDC_DMA_TX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_WSA_CODEC_DMA_TX_1, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .capture = { + .stream_name = "WSA CDC DMA2 Capture", + .aif_name = "WSA_CDC_DMA_TX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 1, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_WSA_CODEC_DMA_TX_2, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .capture = { + .stream_name = "VA CDC DMA0 Capture", + .aif_name = "VA_CDC_DMA_TX_0", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_VA_CODEC_DMA_TX_0, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .capture = { + .stream_name = "VA CDC DMA1 Capture", + .aif_name = "VA_CDC_DMA_TX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_VA_CODEC_DMA_TX_1, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + +}; + +static const struct snd_soc_component_driver msm_q6_cdc_dma_dai_component = { + .name = "msm-dai-cdc-dma-dev", +}; + +/* DT related probe for each codec DMA interface device */ +static int msm_dai_q6_cdc_dma_dev_probe(struct platform_device *pdev) +{ + const char *q6_cdc_dma_dev_id = "qcom,msm-dai-cdc-dma-dev-id"; + u16 cdc_dma_id = 0; + int i; + int rc = 0; + struct msm_dai_q6_cdc_dma_dai_data *dai_data = NULL; + + rc = of_property_read_u16(pdev->dev.of_node, q6_cdc_dma_dev_id, + &cdc_dma_id); + if (rc) { + dev_err(&pdev->dev, + "%s: missing 0x%x in dt node\n", __func__, cdc_dma_id); + return rc; + } + + dev_dbg(&pdev->dev, "%s: dev name %s dev id 0x%x\n", __func__, + dev_name(&pdev->dev), cdc_dma_id); + + pdev->id = cdc_dma_id; + + dai_data = devm_kzalloc(&pdev->dev, + sizeof(struct msm_dai_q6_cdc_dma_dai_data), + GFP_KERNEL); + + if (!dai_data) + return -ENOMEM; + + dev_set_drvdata(&pdev->dev, dai_data); + + for (i = 0; i < ARRAY_SIZE(msm_dai_q6_cdc_dma_dai); i++) { + if (msm_dai_q6_cdc_dma_dai[i].id == cdc_dma_id) { + return snd_soc_register_component(&pdev->dev, + &msm_q6_cdc_dma_dai_component, + &msm_dai_q6_cdc_dma_dai[i], 1); + } + } + return -ENODEV; +} + +static int msm_dai_q6_cdc_dma_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_component(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_dai_q6_cdc_dma_dev_dt_match[] = { + { .compatible = "qcom,msm-dai-cdc-dma-dev", }, + { } +}; + +MODULE_DEVICE_TABLE(of, msm_dai_q6_cdc_dma_dev_dt_match); + +static struct platform_driver msm_dai_q6_cdc_dma_driver = { + .probe = msm_dai_q6_cdc_dma_dev_probe, + .remove = msm_dai_q6_cdc_dma_dev_remove, + .driver = { + .name = "msm-dai-cdc-dma-dev", + .owner = THIS_MODULE, + .of_match_table = msm_dai_q6_cdc_dma_dev_dt_match, + }, +}; + +/* DT related probe for codec DMA interface device group */ +static int msm_dai_cdc_dma_q6_probe(struct platform_device *pdev) +{ + int rc; + + rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); + if (rc) { + dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n", + __func__, rc); + } else + dev_dbg(&pdev->dev, "%s: added child node\n", __func__); + return rc; +} + +static int msm_dai_cdc_dma_q6_remove(struct platform_device *pdev) +{ + of_platform_depopulate(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_dai_cdc_dma_dt_match[] = { + { .compatible = "qcom,msm-dai-cdc-dma", }, + { } +}; + +MODULE_DEVICE_TABLE(of, msm_dai_cdc_dma_dt_match); + +static struct platform_driver msm_dai_cdc_dma_q6 = { + .probe = msm_dai_cdc_dma_q6_probe, + .remove = msm_dai_cdc_dma_q6_remove, + .driver = { + .name = "msm-dai-cdc-dma", + .owner = THIS_MODULE, + .of_match_table = msm_dai_cdc_dma_dt_match, + }, +}; + int __init msm_dai_q6_init(void) { int rc; @@ -9099,8 +9623,25 @@ int __init msm_dai_q6_init(void) pr_err("%s: fail to register dai TDM\n", __func__); goto dai_tdm_q6_fail; } + + rc = platform_driver_register(&msm_dai_q6_cdc_dma_driver); + if (rc) { + pr_err("%s: fail to register dai CDC DMA dev\n", __func__); + goto dai_cdc_dma_q6_dev_fail; + } + + + rc = platform_driver_register(&msm_dai_cdc_dma_q6); + if (rc) { + pr_err("%s: fail to register dai CDC DMA\n", __func__); + goto dai_cdc_dma_q6_fail; + } return rc; +dai_cdc_dma_q6_fail: + platform_driver_unregister(&msm_dai_q6_cdc_dma_driver); +dai_cdc_dma_q6_dev_fail: + platform_driver_unregister(&msm_dai_tdm_q6); dai_tdm_q6_fail: platform_driver_unregister(&msm_dai_q6_tdm_driver); dai_q6_tdm_drv_fail: @@ -9121,6 +9662,8 @@ int __init msm_dai_q6_init(void) void msm_dai_q6_exit(void) { + platform_driver_unregister(&msm_dai_cdc_dma_q6); + platform_driver_unregister(&msm_dai_q6_cdc_dma_driver); platform_driver_unregister(&msm_dai_tdm_q6); platform_driver_unregister(&msm_dai_q6_tdm_driver); platform_driver_unregister(&msm_dai_q6_spdif_driver); -- GitLab From cd74176d75e3c3f7edd50b328f5838703d862f0e Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Fri, 13 Apr 2018 23:54:22 +0530 Subject: [PATCH 0315/1645] asoc: qcs405: Add machine driver support for qcs405 Add DAI(Digital Audio Interface) links, internal codec macros & external codec configuration to support audio functionality on qcs405 Change-Id: Ibe88f6e670d300bf18a7d07c3575991bcc686389 Signed-off-by: Mangesh Kunchamwar --- asoc/qcs405.c | 7409 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 7409 insertions(+) create mode 100644 asoc/qcs405.c diff --git a/asoc/qcs405.c b/asoc/qcs405.c new file mode 100644 index 000000000000..f76e6af284c4 --- /dev/null +++ b/asoc/qcs405.c @@ -0,0 +1,7409 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "device_event.h" +#include "msm-pcm-routing-v2.h" +#include "codecs/msm-cdc-pinctrl.h" +#include "codecs/wcd9335.h" +#include "codecs/wsa881x.h" + +#define DRV_NAME "qcs405-asoc-snd" + +#define __CHIPSET__ "QCS405 " +#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) + +#define DEV_NAME_STR_LEN 32 + +#define SAMPLING_RATE_8KHZ 8000 +#define SAMPLING_RATE_11P025KHZ 11025 +#define SAMPLING_RATE_16KHZ 16000 +#define SAMPLING_RATE_22P05KHZ 22050 +#define SAMPLING_RATE_32KHZ 32000 +#define SAMPLING_RATE_44P1KHZ 44100 +#define SAMPLING_RATE_48KHZ 48000 +#define SAMPLING_RATE_88P2KHZ 88200 +#define SAMPLING_RATE_96KHZ 96000 +#define SAMPLING_RATE_176P4KHZ 176400 +#define SAMPLING_RATE_192KHZ 192000 +#define SAMPLING_RATE_352P8KHZ 352800 +#define SAMPLING_RATE_384KHZ 384000 + +#define WSA8810_NAME_1 "wsa881x.20170211" +#define WSA8810_NAME_2 "wsa881x.20170212" +#define WCN_CDC_SLIM_RX_CH_MAX 2 +#define WCN_CDC_SLIM_TX_CH_MAX 3 +#define TDM_CHANNEL_MAX 8 + +#define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ + +enum { + SLIM_RX_0 = 0, + SLIM_RX_1, + SLIM_RX_2, + SLIM_RX_3, + SLIM_RX_4, + SLIM_RX_5, + SLIM_RX_6, + SLIM_RX_7, + SLIM_RX_MAX, +}; + +enum { + SLIM_TX_0 = 0, + SLIM_TX_1, + SLIM_TX_2, + SLIM_TX_3, + SLIM_TX_4, + SLIM_TX_5, + SLIM_TX_6, + SLIM_TX_7, + SLIM_TX_8, + SLIM_TX_MAX, +}; + +enum { + PRIM_MI2S = 0, + SEC_MI2S, + TERT_MI2S, + QUAT_MI2S, + QUIN_MI2S, + MI2S_MAX, +}; + +enum { + PRIM_AUX_PCM = 0, + SEC_AUX_PCM, + TERT_AUX_PCM, + QUAT_AUX_PCM, + QUIN_AUX_PCM, + AUX_PCM_MAX, +}; + +enum { + WSA_CDC_DMA_RX_0 = 0, + WSA_CDC_DMA_RX_1, + CDC_DMA_RX_MAX, +}; + +enum { + WSA_CDC_DMA_TX_0 = 0, + WSA_CDC_DMA_TX_1, + WSA_CDC_DMA_TX_2, + VA_CDC_DMA_TX_0, + VA_CDC_DMA_TX_1, + CDC_DMA_TX_MAX, +}; + +struct mi2s_conf { + struct mutex lock; + u32 ref_cnt; + u32 msm_is_mi2s_master; +}; + +static u32 mi2s_ebit_clk[MI2S_MAX] = { + Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT +}; + +struct dev_config { + u32 sample_rate; + u32 bit_format; + u32 channels; +}; + +struct msm_wsa881x_dev_info { + struct device_node *of_node; + u32 index; +}; + +enum pinctrl_pin_state { + STATE_DISABLE = 0, /* All pins are in sleep state */ + STATE_MI2S_ACTIVE, /* I2S = active, TDM = sleep */ + STATE_TDM_ACTIVE, /* I2S = sleep, TDM = active */ +}; + +struct msm_pinctrl_info { + struct pinctrl *pinctrl; + struct pinctrl_state *mi2s_disable; + struct pinctrl_state *tdm_disable; + struct pinctrl_state *mi2s_active; + struct pinctrl_state *tdm_active; + enum pinctrl_pin_state curr_state; +}; + +struct msm_asoc_mach_data { + struct snd_info_entry *codec_root; + struct msm_pinctrl_info pinctrl_info; + struct device_node *dmic_01_gpio_p; /* used by pinctrl API */ + struct device_node *dmic_23_gpio_p; /* used by pinctrl API */ + struct device_node *dmic_45_gpio_p; /* used by pinctrl API */ + struct device_node *dmic_67_gpio_p; /* used by pinctrl API */ + int dmic_01_gpio_cnt; + int dmic_23_gpio_cnt; + int dmic_45_gpio_cnt; + int dmic_67_gpio_cnt; +}; + +struct msm_asoc_wcd93xx_codec { + void* (*get_afe_config_fn)(struct snd_soc_codec *codec, + enum afe_config_type config_type); +}; + +static const char *const pin_states[] = {"sleep", "i2s-active", + "tdm-active"}; + +enum { + TDM_0 = 0, + TDM_1, + TDM_2, + TDM_3, + TDM_4, + TDM_5, + TDM_6, + TDM_7, + TDM_PORT_MAX, +}; + +enum { + TDM_PRI = 0, + TDM_SEC, + TDM_TERT, + TDM_QUAT, + TDM_QUIN, + TDM_INTERFACE_MAX, +}; + +struct tdm_port { + u32 mode; + u32 channel; +}; + +/* TDM default config */ +static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUIN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + } + +}; + +/* TDM default config */ +static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUIN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + } +}; + + +/* Default configuration of slimbus channels */ +static struct dev_config slim_rx_cfg[] = { + [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config slim_tx_cfg[] = { + [SLIM_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +/* Default configuration of Codec DMA Interface Tx */ +static struct dev_config cdc_dma_rx_cfg[] = { + [WSA_CDC_DMA_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [WSA_CDC_DMA_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +/* Default configuration of Codec DMA Interface Rx */ +static struct dev_config cdc_dma_tx_cfg[] = { + [WSA_CDC_DMA_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [WSA_CDC_DMA_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [WSA_CDC_DMA_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [VA_CDC_DMA_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, + [VA_CDC_DMA_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, +}; + +static struct dev_config usb_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +static struct dev_config usb_tx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 1, +}; + +static struct dev_config proxy_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +/* Default configuration of MI2S channels */ +static struct dev_config mi2s_rx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config mi2s_tx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_rx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_tx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static int msm_vi_feed_tx_ch = 2; +static const char *const slim_rx_ch_text[] = {"One", "Two"}; +static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static const char *const vi_feed_ch_text[] = {"One", "Two"}; +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; +static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; +static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *ch_text[] = {"Two", "Three", "Four", "Five", + "Six", "Seven", "Eight"}; +static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", "Eight"}; +static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; +static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", + "KHZ_48", "KHZ_176P4", + "KHZ_352P8"}; +static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; +static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_16", + "KHZ_22P05", "KHZ_32", "KHZ_44P1", + "KHZ_48", "KHZ_96", "KHZ_192"}; +static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static const char *const qos_text[] = {"Disable", "Enable"}; + +static const char *const cdc_dma_rx_ch_text[] = {"One", "Two"}; +static const char *const cdc_dma_tx_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *cdc_dma_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; + +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_1_tx_chs, slim_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_0_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_1_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_2_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_0_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_1_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_1_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_2_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_0_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_1_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_1_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_2_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_1_sample_rate, + cdc_dma_sample_rate_text); + +static struct platform_device *spdev; + +static bool is_initial_boot; +static bool codec_reg_done; +static struct snd_soc_aux_dev *msm_aux_dev; +static struct snd_soc_codec_conf *msm_codec_conf; +static struct msm_asoc_wcd93xx_codec msm_codec_fn; + +static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, + int enable, bool dapm); +static int msm_wsa881x_init(struct snd_soc_component *component); + + +static struct snd_soc_dapm_route wcd_audio_paths[] = { + {"MIC BIAS1", NULL, "MCLK TX"}, + {"MIC BIAS2", NULL, "MCLK TX"}, + {"MIC BIAS3", NULL, "MCLK TX"}, + {"MIC BIAS4", NULL, "MCLK TX"}, +}; + +static struct afe_clk_set mi2s_clk[MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + } + +}; + +static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; + +static int slim_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 10; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int slim_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + sample_rate = SAMPLING_RATE_384KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int slim_get_bit_format_val(int bit_format) +{ + int val = 0; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + val = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + val = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + val = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + val = 0; + break; + } + return val; +} + +static int slim_get_bit_format(int val) +{ + int bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + + switch (val) { + case 0: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + bit_fmt = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + bit_fmt = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + bit_fmt = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return bit_fmt; +} + +static int slim_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int port_id = 0; + + if (strnstr(kcontrol->id.name, "SLIM_0_RX", sizeof("SLIM_0_RX"))) { + port_id = SLIM_RX_0; + } else if (strnstr(kcontrol->id.name, + "SLIM_2_RX", sizeof("SLIM_2_RX"))) { + port_id = SLIM_RX_2; + } else if (strnstr(kcontrol->id.name, + "SLIM_5_RX", sizeof("SLIM_5_RX"))) { + port_id = SLIM_RX_5; + } else if (strnstr(kcontrol->id.name, + "SLIM_6_RX", sizeof("SLIM_6_RX"))) { + port_id = SLIM_RX_6; + } else if (strnstr(kcontrol->id.name, + "SLIM_0_TX", sizeof("SLIM_0_TX"))) { + port_id = SLIM_TX_0; + } else if (strnstr(kcontrol->id.name, + "SLIM_1_TX", sizeof("SLIM_1_TX"))) { + port_id = SLIM_TX_1; + } else { + pr_err("%s: unsupported channel: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + + return port_id; +} + +static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_sample_rate_val(slim_rx_cfg[ch_num].sample_rate); + + pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].sample_rate = + slim_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_sample_rate_val(slim_tx_cfg[ch_num].sample_rate); + + pr_debug("%s: slim[%d]_tx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate = 0; + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + sample_rate = slim_get_sample_rate(ucontrol->value.enumerated.item[0]); + if (sample_rate == SAMPLING_RATE_44P1KHZ) { + pr_err("%s: Unsupported sample rate %d: for Tx path\n", + __func__, sample_rate); + return -EINVAL; + } + slim_tx_cfg[ch_num].sample_rate = sample_rate; + + pr_debug("%s: slim[%d]_tx_sample_rate = %d, value = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_bit_format_val(slim_rx_cfg[ch_num].bit_format); + + pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_rx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].bit_format = + slim_get_bit_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_rx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_bit_format_val(slim_tx_cfg[ch_num].bit_format); + + pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_tx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_tx_cfg[ch_num].bit_format = + slim_get_bit_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_tx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].channels); + ucontrol->value.enumerated.item[0] = slim_rx_cfg[ch_num].channels - 1; + + return 0; +} + +static int slim_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].channels); + + return 1; +} + +static int slim_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].channels); + ucontrol->value.enumerated.item[0] = slim_tx_cfg[ch_num].channels - 1; + + return 0; +} + +static int slim_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_tx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].channels); + + return 1; +} + +static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1; + pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch); + return 1; +} + +static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* + * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) + * when used for BT_SCO use case. Return either Rx or Tx sample rate + * value. + */ + switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate = %d", __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n", + __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate, + slim_tx_cfg[SLIM_TX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int cdc_dma_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx = 0; + + if (strnstr(kcontrol->id.name, "WSA_CDC_DMA_RX_0", + sizeof("WSA_CDC_DMA_RX_0"))) + idx = WSA_CDC_DMA_RX_0; + else if (strnstr(kcontrol->id.name, "WSA_CDC_DMA_RX_1", + sizeof("WSA_CDC_DMA_RX_0"))) + idx = WSA_CDC_DMA_RX_1; + else if (strnstr(kcontrol->id.name, "WSA_CDC_DMA_TX_0", + sizeof("WSA_CDC_DMA_TX_0"))) + idx = WSA_CDC_DMA_TX_0; + else if (strnstr(kcontrol->id.name, "WSA_CDC_DMA_TX_1", + sizeof("WSA_CDC_DMA_TX_1"))) + idx = WSA_CDC_DMA_TX_1; + else if (strnstr(kcontrol->id.name, "WSA_CDC_DMA_TX_2", + sizeof("WSA_CDC_DMA_TX_2"))) + idx = WSA_CDC_DMA_TX_2; + else if (strnstr(kcontrol->id.name, "VA_CDC_DMA_TX_0", + sizeof("VA_CDC_DMA_TX_0"))) + idx = VA_CDC_DMA_TX_0; + else if (strnstr(kcontrol->id.name, "VA_CDC_DMA_TX_1", + sizeof("VA_CDC_DMA_TX_1"))) + idx = VA_CDC_DMA_TX_1; + else { + pr_err("%s: unsupported port: %s\n", + __func__, kcontrol->id.name); + return -EINVAL; + } + + return idx; +} + +static int cdc_dma_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + pr_debug("%s: cdc_dma_rx_ch = %d\n", __func__, + cdc_dma_rx_cfg[ch_num].channels - 1); + ucontrol->value.integer.value[0] = cdc_dma_rx_cfg[ch_num].channels - 1; + return 0; +} + +static int cdc_dma_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + cdc_dma_rx_cfg[ch_num].channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: cdc_dma_rx_ch = %d\n", __func__, + cdc_dma_rx_cfg[ch_num].channels); + return 1; +} + +static int cdc_dma_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + switch (cdc_dma_rx_cfg[ch_num].bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: cdc_dma_rx_format = %d, ucontrol value = %ld\n", + __func__, cdc_dma_rx_cfg[ch_num].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int cdc_dma_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + int ch_num = cdc_dma_get_port_idx(kcontrol); + + switch (ucontrol->value.integer.value[0]) { + case 3: + cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: cdc_dma_rx_format = %d, ucontrol value = %ld\n", + __func__, cdc_dma_rx_cfg[ch_num].bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int cdc_dma_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 10; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int cdc_dma_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + sample_rate = SAMPLING_RATE_384KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + + +static int cdc_dma_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + cdc_dma_get_sample_rate_val(cdc_dma_rx_cfg[ch_num].sample_rate); + + pr_debug("%s: cdc_dma_rx_sample_rate = %d\n", __func__, + cdc_dma_rx_cfg[ch_num].sample_rate); + return 0; +} + +static int cdc_dma_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + cdc_dma_rx_cfg[ch_num].sample_rate = + cdc_dma_get_sample_rate(ucontrol->value.enumerated.item[0]); + + + pr_debug("%s: control value = %d, cdc_dma_rx_sample_rate = %d\n", + __func__, ucontrol->value.enumerated.item[0], + cdc_dma_rx_cfg[ch_num].sample_rate); + return 0; +} + +static int cdc_dma_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + pr_debug("%s: cdc_dma_tx_ch = %d\n", __func__, + cdc_dma_tx_cfg[ch_num].channels); + ucontrol->value.integer.value[0] = cdc_dma_tx_cfg[ch_num].channels - 1; + return 0; +} + +static int cdc_dma_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + cdc_dma_tx_cfg[ch_num].channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: cdc_dma_tx_ch = %d\n", __func__, + cdc_dma_tx_cfg[ch_num].channels); + return 1; +} + +static int cdc_dma_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + int ch_num = cdc_dma_get_port_idx(kcontrol); + + switch (cdc_dma_tx_cfg[ch_num].sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + default: + sample_rate_val = 6; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: cdc_dma_tx_sample_rate = %d\n", __func__, + cdc_dma_tx_cfg[ch_num].sample_rate); + return 0; +} + +static int cdc_dma_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + switch (ucontrol->value.integer.value[0]) { + case 12: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, cdc_dma_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + cdc_dma_tx_cfg[ch_num].sample_rate); + return 0; +} + +static int cdc_dma_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + switch (cdc_dma_tx_cfg[ch_num].bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: cdc_dma_tx_format = %d, ucontrol value = %ld\n", + __func__, cdc_dma_tx_cfg[ch_num].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int cdc_dma_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + int ch_num = cdc_dma_get_port_idx(kcontrol); + + switch (ucontrol->value.integer.value[0]) { + case 3: + cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: cdc_dma_tx_format = %d, ucontrol value = %ld\n", + __func__, cdc_dma_tx_cfg[ch_num].bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, + usb_rx_cfg.channels); + ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1; + return 0; +} + +static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels); + return 1; +} + +static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_rx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__, + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_rx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_rx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_rx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_rx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, + usb_tx_cfg.channels); + ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1; + return 0; +} + +static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels); + return 1; +} + +static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_tx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + default: + sample_rate_val = 6; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__, + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_tx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_tx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_tx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_tx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2; + + return 0; +} + +static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2; + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + + return 1; +} + +static int tdm_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int aux_pcm_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 0: + default: + sample_rate = SAMPLING_RATE_8KHZ; + break; + } + return sample_rate; +} + +static int tdm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 5; + break; + default: + sample_rate_val = 3; + break; + } + return sample_rate_val; +} + +static int aux_pcm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + return sample_rate_val; +} + +static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, + struct tdm_port *port) +{ + if (port) { + if (strnstr(kcontrol->id.name, "PRI", + sizeof(kcontrol->id.name))) { + port->mode = TDM_PRI; + } else if (strnstr(kcontrol->id.name, "SEC", + sizeof(kcontrol->id.name))) { + port->mode = TDM_SEC; + } else if (strnstr(kcontrol->id.name, "TERT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_TERT; + } else if (strnstr(kcontrol->id.name, "QUAT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_QUAT; + } else if (strnstr(kcontrol->id.name, "QUIN", + sizeof(kcontrol->id.name))) { + port->mode = TDM_QUIN; + } else { + pr_err("%s: unsupported mode in: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + + if (strnstr(kcontrol->id.name, "RX_0", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_0", + sizeof(kcontrol->id.name))) { + port->channel = TDM_0; + } else if (strnstr(kcontrol->id.name, "RX_1", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_1", + sizeof(kcontrol->id.name))) { + port->channel = TDM_1; + } else if (strnstr(kcontrol->id.name, "RX_2", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_2", + sizeof(kcontrol->id.name))) { + port->channel = TDM_2; + } else if (strnstr(kcontrol->id.name, "RX_3", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_3", + sizeof(kcontrol->id.name))) { + port->channel = TDM_3; + } else if (strnstr(kcontrol->id.name, "RX_4", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_4", + sizeof(kcontrol->id.name))) { + port->channel = TDM_4; + } else if (strnstr(kcontrol->id.name, "RX_5", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_5", + sizeof(kcontrol->id.name))) { + port->channel = TDM_5; + } else if (strnstr(kcontrol->id.name, "RX_6", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_6", + sizeof(kcontrol->id.name))) { + port->channel = TDM_6; + } else if (strnstr(kcontrol->id.name, "RX_7", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_7", + sizeof(kcontrol->id.name))) { + port->channel = TDM_7; + } else { + pr_err("%s: unsupported channel in: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + } else + return -EINVAL; + return 0; +} + +static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_rx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_tx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_get_format(int value) +{ + int format = 0; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int tdm_get_format_val(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 2; + break; + default: + value = 0; + break; + } + return value; +} + +static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_rx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_tx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + + ucontrol->value.enumerated.item[0] = + tdm_rx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = + tdm_tx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", + sizeof("PRIM_AUX_PCM"))) + idx = PRIM_AUX_PCM; + else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM", + sizeof("SEC_AUX_PCM"))) + idx = SEC_AUX_PCM; + else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", + sizeof("TERT_AUX_PCM"))) + idx = TERT_AUX_PCM; + else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", + sizeof("QUAT_AUX_PCM"))) + idx = QUAT_AUX_PCM; + else if (strnstr(kcontrol->id.name, "QUIN_AUX_PCM", + sizeof("QUIN_AUX_PCM"))) + idx = QUIN_AUX_PCM; + else { + pr_err("%s: unsupported port: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX", + sizeof("PRIM_MI2S_RX"))) + idx = PRIM_MI2S; + else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX", + sizeof("SEC_MI2S_RX"))) + idx = SEC_MI2S; + else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", + sizeof("TERT_MI2S_RX"))) + idx = TERT_MI2S; + else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", + sizeof("QUAT_MI2S_RX"))) + idx = QUAT_MI2S; + else if (strnstr(kcontrol->id.name, "QUIN_MI2S_RX", + sizeof("QUIN_MI2S_RX"))) + idx = QUIN_MI2S; + else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", + sizeof("PRIM_MI2S_TX"))) + idx = PRIM_MI2S; + else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX", + sizeof("SEC_MI2S_TX"))) + idx = SEC_MI2S; + else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", + sizeof("TERT_MI2S_TX"))) + idx = TERT_MI2S; + else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", + sizeof("QUAT_MI2S_TX"))) + idx = QUAT_MI2S; + else if (strnstr(kcontrol->id.name, "QUIN_MI2S_TX", + sizeof("QUIN_MI2S_TX"))) + idx = QUIN_MI2S; + else { + pr_err("%s: unsupported channel: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int mi2s_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + default: + sample_rate_val = 6; + break; + } + return sample_rate_val; +} + +static int mi2s_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_192KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int mi2s_auxpcm_get_format(int value) +{ + int format; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int mi2s_auxpcm_get_format_value(int format) +{ + int value; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + value = 2; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 3; + break; + default: + value = 0; + break; + } + return value; +} + +static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(mi2s_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(mi2s_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(aux_pcm_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(aux_pcm_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static const struct snd_kcontrol_new msm_snd_sb_controls[] = { + SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, + slim_rx_ch_get, slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs, + slim_rx_ch_get, slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs, + slim_tx_ch_get, slim_tx_ch_put), + SOC_ENUM_EXT("SLIM_1_TX Channels", slim_1_tx_chs, + slim_tx_ch_get, slim_tx_ch_put), + SOC_ENUM_EXT("SLIM_5_RX Channels", slim_5_rx_chs, + slim_rx_ch_get, slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_6_RX Channels", slim_6_rx_chs, + slim_rx_ch_get, slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_5_RX Format", slim_5_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_6_RX Format", slim_6_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format, + slim_tx_bit_format_get, slim_tx_bit_format_put), + SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate, + slim_tx_sample_rate_get, slim_tx_sample_rate_put), + SOC_ENUM_EXT("SLIM_5_RX SampleRate", slim_5_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_6_RX SampleRate", slim_6_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), +}; + +static const struct snd_kcontrol_new msm_snd_va_controls[] = { + SOC_ENUM_EXT("VA_CDC_DMA_TX_0 Channels", va_cdc_dma_tx_0_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_1 Channels", va_cdc_dma_tx_1_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_0 Format", va_cdc_dma_tx_0_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_1 Format", va_cdc_dma_tx_1_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_0 SampleRate", + va_cdc_dma_tx_0_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_1 SampleRate", + va_cdc_dma_tx_1_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), +}; + +static const struct snd_kcontrol_new msm_snd_wsa_controls[] = { + SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, + msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), + SOC_ENUM_EXT("WSA_CDC_DMA_RX_0 Channels", wsa_cdc_dma_rx_0_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("WSA_CDC_DMA_RX_1 Channels", wsa_cdc_dma_rx_1_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_0 Channels", wsa_cdc_dma_tx_0_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_1 Channels", wsa_cdc_dma_tx_1_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_2 Channels", wsa_cdc_dma_tx_2_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("WSA_CDC_DMA_RX_0 Format", wsa_cdc_dma_rx_0_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("WSA_CDC_DMA_RX_1 Format", wsa_cdc_dma_rx_1_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_1 Format", wsa_cdc_dma_tx_1_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_2 Format", wsa_cdc_dma_tx_2_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("WSA_CDC_DMA_RX_0 SampleRate", + wsa_cdc_dma_rx_0_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("WSA_CDC_DMA_RX_1 SampleRate", + wsa_cdc_dma_rx_1_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_0 SampleRate", + wsa_cdc_dma_tx_0_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_1 SampleRate", + wsa_cdc_dma_tx_1_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_2 SampleRate", + wsa_cdc_dma_tx_2_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), +}; + +static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, + usb_audio_rx_ch_get, usb_audio_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, + usb_audio_tx_ch_get, usb_audio_tx_ch_put), + SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, + proxy_rx_ch_get, proxy_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, + usb_audio_rx_format_get, usb_audio_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, + usb_audio_tx_format_get, usb_audio_tx_format_put), + SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, + usb_audio_rx_sample_rate_get, + usb_audio_rx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, + usb_audio_tx_sample_rate_get, + usb_audio_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_RX SampleRate", quin_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_TX SampleRate", quin_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_MI2S_RX SampleRate", quin_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_MI2S_TX SampleRate", quin_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUIN_MI2S_RX Channels", quin_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUIN_MI2S_TX Channels", quin_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("SEC_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("TERT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("TERT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("QUIN_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("QUIN_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), +}; + +static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, + int enable, bool dapm) +{ + int ret = 0; + + if (!strcmp(dev_name(codec->dev), "tasha_codec")) { + ret = tasha_cdc_mclk_enable(codec, enable, dapm); + } else { + dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", + __func__); + ret = -EINVAL; + } + return ret; +} + +static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, + int enable, bool dapm) +{ + int ret = 0; + + if (!strcmp(dev_name(codec->dev), "tasha_codec")) { + ret = tasha_cdc_mclk_tx_enable(codec, enable, dapm); + } else { + dev_err(codec->dev, "%s: unknown codec to enable TX ext clk\n", + __func__); + ret = -EINVAL; + } + + return ret; +} + +static int msm_mclk_tx_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + pr_debug("%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return msm_snd_enable_codec_ext_tx_clk(codec, 1, true); + case SND_SOC_DAPM_POST_PMD: + return msm_snd_enable_codec_ext_tx_clk(codec, 0, true); + } + return 0; +} + +static int msm_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + pr_debug("%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return msm_snd_enable_codec_ext_clk(codec, 1, true); + case SND_SOC_DAPM_POST_PMD: + return msm_snd_enable_codec_ext_clk(codec, 0, true); + } + return 0; +} + +static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { + + SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, + msm_mclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0, + msm_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIC("Analog Mic3", NULL), + SND_SOC_DAPM_MIC("Analog Mic4", NULL), + +}; + +static int msm_dmic_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct msm_asoc_mach_data *pdata = NULL; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int ret = 0; + uint32_t dmic_idx; + int *dmic_gpio_cnt; + struct device_node *dmic_gpio; + char *wname; + + wname = strpbrk(w->name, "01234567"); + if (!wname) { + dev_err(codec->dev, "%s: widget not found\n", __func__); + return -EINVAL; + } + + ret = kstrtouint(wname, 10, &dmic_idx); + if (ret < 0) { + dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n", + __func__); + return -EINVAL; + } + + pdata = snd_soc_card_get_drvdata(codec->component.card); + + switch (dmic_idx) { + case 0: + case 1: + dmic_gpio_cnt = &pdata->dmic_01_gpio_cnt; + dmic_gpio = pdata->dmic_01_gpio_p; + break; + case 2: + case 3: + dmic_gpio_cnt = &pdata->dmic_23_gpio_cnt; + dmic_gpio = pdata->dmic_23_gpio_p; + break; + case 4: + case 5: + dmic_gpio_cnt = &pdata->dmic_45_gpio_cnt; + dmic_gpio = pdata->dmic_45_gpio_p; + break; + case 6: + case 7: + dmic_gpio_cnt = &pdata->dmic_67_gpio_cnt; + dmic_gpio = pdata->dmic_67_gpio_p; + break; + default: + dev_err(codec->dev, "%s: Invalid DMIC Selection\n", + __func__); + return -EINVAL; + } + + dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_gpio_cnt %d\n", + __func__, event, dmic_idx, *dmic_gpio_cnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + (*dmic_gpio_cnt)++; + if (*dmic_gpio_cnt == 1) { + ret = msm_cdc_pinctrl_select_active_state( + dmic_gpio); + if (ret < 0) { + dev_err(codec->dev, "%s: gpio set cannot be activated %sd\n", + __func__, "dmic_gpio"); + return ret; + } + } + break; + case SND_SOC_DAPM_POST_PMD: + (*dmic_gpio_cnt)--; + if (*dmic_gpio_cnt == 0) { + ret = msm_cdc_pinctrl_select_sleep_state( + dmic_gpio); + if (ret < 0) { + dev_err(codec->dev, "%s: gpio set cannot be de-activated %sd\n", + __func__, "dmic_gpio"); + return ret; + } + } + break; + default: + dev_err(codec->dev, "%s: invalid DAPM event %d\n", + __func__, event); + return -EINVAL; + } + return 0; +} + + +static const struct snd_soc_dapm_widget msm_va_dapm_widgets[] = { + + SND_SOC_DAPM_MIC("Digital Mic0", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic1", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic2", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic3", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic4", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic5", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic6", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic7", msm_dmic_event), +}; + +static const struct snd_soc_dapm_widget msm_wsa_dapm_widgets[] = { + +}; + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, + int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, + unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +static int msm_slim_get_ch_from_beid(int32_t be_id) +{ + int ch_id = 0; + + switch (be_id) { + case MSM_BACKEND_DAI_SLIMBUS_0_RX: + ch_id = SLIM_RX_0; + break; + case MSM_BACKEND_DAI_SLIMBUS_1_RX: + ch_id = SLIM_RX_1; + break; + case MSM_BACKEND_DAI_SLIMBUS_2_RX: + ch_id = SLIM_RX_2; + break; + case MSM_BACKEND_DAI_SLIMBUS_3_RX: + ch_id = SLIM_RX_3; + break; + case MSM_BACKEND_DAI_SLIMBUS_4_RX: + ch_id = SLIM_RX_4; + break; + case MSM_BACKEND_DAI_SLIMBUS_6_RX: + ch_id = SLIM_RX_6; + break; + case MSM_BACKEND_DAI_SLIMBUS_0_TX: + ch_id = SLIM_TX_0; + break; + case MSM_BACKEND_DAI_SLIMBUS_3_TX: + ch_id = SLIM_TX_3; + break; + default: + ch_id = SLIM_RX_0; + break; + } + + return ch_id; +} + +static int msm_cdc_dma_get_idx_from_beid(int32_t be_id) +{ + int idx = 0; + + switch (be_id) { + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0: + idx = WSA_CDC_DMA_RX_0; + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0: + idx = WSA_CDC_DMA_TX_0; + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1: + idx = WSA_CDC_DMA_RX_1; + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1: + idx = WSA_CDC_DMA_TX_1; + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2: + idx = WSA_CDC_DMA_TX_2; + break; + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: + idx = VA_CDC_DMA_TX_0; + break; + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: + idx = VA_CDC_DMA_TX_1; + break; + default: + idx = VA_CDC_DMA_TX_0; + break; + } + + return idx; +} + +static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int rc = 0; + int idx; + void *config = NULL; + struct snd_soc_codec *codec = NULL; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->id) { + case MSM_BACKEND_DAI_SLIMBUS_0_RX: + case MSM_BACKEND_DAI_SLIMBUS_1_RX: + case MSM_BACKEND_DAI_SLIMBUS_2_RX: + case MSM_BACKEND_DAI_SLIMBUS_3_RX: + case MSM_BACKEND_DAI_SLIMBUS_4_RX: + case MSM_BACKEND_DAI_SLIMBUS_6_RX: + idx = msm_slim_get_ch_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[idx].bit_format); + rate->min = rate->max = slim_rx_cfg[idx].sample_rate; + channels->min = channels->max = slim_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_0_TX: + case MSM_BACKEND_DAI_SLIMBUS_3_TX: + idx = msm_slim_get_ch_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[idx].bit_format); + rate->min = rate->max = slim_tx_cfg[idx].sample_rate; + channels->min = channels->max = slim_tx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_1_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[1].bit_format); + rate->min = rate->max = slim_tx_cfg[1].sample_rate; + channels->min = channels->max = slim_tx_cfg[1].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_4_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + SNDRV_PCM_FORMAT_S32_LE); + rate->min = rate->max = SAMPLING_RATE_8KHZ; + channels->min = channels->max = msm_vi_feed_tx_ch; + break; + + case MSM_BACKEND_DAI_SLIMBUS_5_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[5].bit_format); + rate->min = rate->max = slim_rx_cfg[5].sample_rate; + channels->min = channels->max = slim_rx_cfg[5].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_5_TX: + codec = rtd->codec; + rate->min = rate->max = SAMPLING_RATE_16KHZ; + channels->min = channels->max = 1; + + config = msm_codec_fn.get_afe_config_fn(codec, + AFE_SLIMBUS_SLAVE_PORT_CONFIG); + if (config) { + rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, + config, SLIMBUS_5_TX); + if (rc) + pr_err("%s: Failed to set slimbus slave port config %d\n", + __func__, rc); + } + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[SLIM_RX_7].bit_format); + rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate; + channels->min = channels->max = + slim_rx_cfg[SLIM_RX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_8_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_8].channels; + break; + + case MSM_BACKEND_DAI_USB_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_rx_cfg.bit_format); + rate->min = rate->max = usb_rx_cfg.sample_rate; + channels->min = channels->max = usb_rx_cfg.channels; + break; + + case MSM_BACKEND_DAI_USB_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_tx_cfg.bit_format); + rate->min = rate->max = usb_tx_cfg.sample_rate; + channels->min = channels->max = usb_tx_cfg.channels; + break; + + case MSM_BACKEND_DAI_AFE_PCM_RX: + channels->min = channels->max = proxy_rx_cfg.channels; + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + + case MSM_BACKEND_DAI_PRI_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_PRI_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUIN_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUIN_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + + + case MSM_BACKEND_DAI_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[PRIM_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[SEC_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[SEC_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[TERT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[TERT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[QUAT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[QUAT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUIN_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[QUIN_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[QUIN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUIN_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUIN_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[QUIN_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[QUIN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUIN_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUAT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUAT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUINARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUIN_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[QUIN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUIN_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUIN_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[QUIN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUIN_MI2S].channels; + break; + + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0: + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1: + idx = msm_cdc_dma_get_idx_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + cdc_dma_rx_cfg[idx].bit_format); + rate->min = rate->max = cdc_dma_rx_cfg[idx].sample_rate; + channels->min = channels->max = cdc_dma_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1: + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: + idx = msm_cdc_dma_get_idx_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + cdc_dma_tx_cfg[idx].bit_format); + rate->min = rate->max = cdc_dma_tx_cfg[idx].sample_rate; + channels->min = channels->max = cdc_dma_tx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + SNDRV_PCM_FORMAT_S32_LE); + rate->min = rate->max = SAMPLING_RATE_8KHZ; + channels->min = channels->max = msm_vi_feed_tx_ch; + break; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + + return rc; +} + +static int msm_afe_set_config(struct snd_soc_codec *codec) +{ + int ret = 0; + void *config_data = NULL; + + if (!msm_codec_fn.get_afe_config_fn) { + dev_err(codec->dev, "%s: codec get afe config not init'ed\n", + __func__); + return -EINVAL; + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CDC_REGISTERS_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0); + if (ret) { + dev_err(codec->dev, + "%s: Failed to set codec registers config %d\n", + __func__, ret); + return ret; + } + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CDC_REGISTER_PAGE_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, + 0); + if (ret) + dev_err(codec->dev, + "%s: Failed to set cdc register page config\n", + __func__); + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_SLIMBUS_SLAVE_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0); + if (ret) { + dev_err(codec->dev, + "%s: Failed to set slimbus slave config %d\n", + __func__, ret); + return ret; + } + } + + return 0; +} + +static void msm_afe_clear_config(void) +{ + afe_clear_config(AFE_CDC_REGISTERS_CONFIG); + afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); +} + +static int msm_adsp_power_up_config(struct snd_soc_codec *codec, + struct snd_card *card) +{ + int ret = 0; + unsigned long timeout; + int adsp_ready = 0; + bool snd_card_online = 0; + + timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + + do { + if (!snd_card_online) { + snd_card_online = snd_card_is_online_state(card); + pr_debug("%s: Sound card is %s\n", __func__, + snd_card_online ? "Online" : "Offline"); + } + if (!adsp_ready) { + adsp_ready = q6core_is_adsp_ready(); + pr_debug("%s: ADSP Audio is %s\n", __func__, + adsp_ready ? "ready" : "not ready"); + } + if (snd_card_online && adsp_ready) + break; + + /* + * Sound card/ADSP will be coming up after subsystem restart and + * it might not be fully up when the control reaches + * here. So, wait for 50msec before checking ADSP state + */ + msleep(50); + } while (time_after(timeout, jiffies)); + + if (!snd_card_online || !adsp_ready) { + pr_err("%s: Timeout. Sound card is %s, ADSP Audio is %s\n", + __func__, + snd_card_online ? "Online" : "Offline", + adsp_ready ? "ready" : "not ready"); + ret = -ETIMEDOUT; + goto err; + } + + ret = msm_afe_set_config(codec); + if (ret) + pr_err("%s: Failed to set AFE config. err %d\n", + __func__, ret); + + return 0; + +err: + return ret; +} + +static int qcs405_notifier_service_cb(struct notifier_block *this, + unsigned long opcode, void *ptr) +{ + int ret; + struct snd_soc_card *card = NULL; + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + struct snd_soc_codec *codec; + + pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); + + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + /* + * Use flag to ignore initial boot notifications + * On initial boot msm_adsp_power_up_config is + * called on init. There is no need to clear + * and set the config again on initial boot. + */ + if (is_initial_boot) + break; + msm_afe_clear_config(); + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (is_initial_boot) { + is_initial_boot = false; + break; + } + if (!spdev) + return -EINVAL; + + card = platform_get_drvdata(spdev); + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err; + } + codec = rtd->codec; + + ret = msm_adsp_power_up_config(codec, card->snd_card); + if (ret < 0) { + dev_err(card->dev, + "%s: msm_adsp_power_up_config failed ret = %d!\n", + __func__, ret); + goto err; + } + break; + default: + break; + } +err: + return NOTIFY_OK; +} + +static struct notifier_block service_nb = { + .notifier_call = qcs405_notifier_service_cb, + .priority = -INT_MAX, +}; + +static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + void *config_data; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_card *card; + struct snd_info_entry *entry; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); + + /* + * Codec SLIMBUS configuration + * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8 + * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 + * TX14, TX15, TX16 + */ + unsigned int rx_ch[TASHA_RX_MAX] = {144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156}; + unsigned int tx_ch[TASHA_TX_MAX] = {128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143}; + + pr_info("%s: dev_name:%s\n", __func__, dev_name(cpu_dai->dev)); + + rtd->pmdown_time = 0; + + ret = snd_soc_add_codec_controls(codec, msm_snd_sb_controls, + ARRAY_SIZE(msm_snd_sb_controls)); + if (ret < 0) { + pr_err("%s: add_codec_controls failed, err %d\n", + __func__, ret); + return ret; + } + + snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, + ARRAY_SIZE(msm_dapm_widgets)); + + snd_soc_dapm_add_routes(dapm, wcd_audio_paths, + ARRAY_SIZE(wcd_audio_paths)); + + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic3"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4"); + + snd_soc_dapm_sync(dapm); + + snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); + + msm_codec_fn.get_afe_config_fn = tasha_get_afe_config; + + ret = msm_adsp_power_up_config(codec, rtd->card->snd_card); + if (ret) { + dev_err(codec->dev, "%s: Failed to set AFE config %d\n", + __func__, ret); + goto err; + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_AANC_VERSION); + if (config_data) { + ret = afe_set_config(AFE_AANC_VERSION, config_data, 0); + if (ret) { + dev_err(codec->dev, "%s: Failed to set aanc version %d\n", + __func__, ret); + goto err; + } + } + + card = rtd->card->snd_card; + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto err; + } + pdata->codec_root = entry; + tasha_codec_info_create_codec_entry(pdata->codec_root, codec); + + codec_reg_done = true; + return 0; + +err: + return ret; +} + +static int msm_va_cdc_dma_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + + ret = snd_soc_add_codec_controls(codec, msm_snd_va_controls, + ARRAY_SIZE(msm_snd_va_controls)); + if (ret < 0) { + dev_err(codec->dev, "%s: add_codec_controls for va failed, err %d\n", + __func__, ret); + return ret; + } + + snd_soc_dapm_new_controls(dapm, msm_va_dapm_widgets, + ARRAY_SIZE(msm_va_dapm_widgets)); + + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic6"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic7"); + + snd_soc_dapm_sync(dapm); + + return ret; +} + +static int msm_wsa_cdc_dma_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + + ret = snd_soc_add_codec_controls(codec, msm_snd_wsa_controls, + ARRAY_SIZE(msm_snd_wsa_controls)); + if (ret < 0) { + dev_err(codec->dev, "%s: add_codec_controls for va failed, err %d\n", + __func__, ret); + return ret; + } + snd_soc_dapm_new_controls(dapm, msm_wsa_dapm_widgets, + ARRAY_SIZE(msm_wsa_dapm_widgets)); + + snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK1 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK2 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "WSA AIF VI"); + snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_WSA"); + + snd_soc_dapm_sync(dapm); + + return ret; +} + +static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) +{ + unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; + unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); +} + +static int msm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + int ret = 0; + u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + u32 user_set_tx_ch = 0; + u32 rx_ch_count; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err; + } + if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_5_RX) { + pr_debug("%s: rx_5_ch=%d\n", __func__, + slim_rx_cfg[5].channels); + rx_ch_count = slim_rx_cfg[5].channels; + } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_2_RX) { + pr_debug("%s: rx_2_ch=%d\n", __func__, + slim_rx_cfg[2].channels); + rx_ch_count = slim_rx_cfg[2].channels; + } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_6_RX) { + pr_debug("%s: rx_6_ch=%d\n", __func__, + slim_rx_cfg[6].channels); + rx_ch_count = slim_rx_cfg[6].channels; + } else { + pr_debug("%s: rx_0_ch=%d\n", __func__, + slim_rx_cfg[0].channels); + rx_ch_count = slim_rx_cfg[0].channels; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + rx_ch_count, rx_ch); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + } else { + + pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__, + codec_dai->name, codec_dai->id, user_set_tx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get tx codec chan map, err:%d\n", + __func__, ret); + goto err; + } + /* For _tx1 case */ + if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_0_TX) + user_set_tx_ch = slim_tx_cfg[0].channels; + /* For _tx3 case */ + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_1_TX) + user_set_tx_ch = slim_tx_cfg[1].channels; + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_4_TX) + user_set_tx_ch = msm_vi_feed_tx_ch; + else + user_set_tx_ch = tx_ch_cnt; + + pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), BE id (%d)\n", + __func__, slim_tx_cfg[0].channels, user_set_tx_ch, + tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + user_set_tx_ch, tx_ch, 0, 0); + if (ret < 0) + pr_err("%s: failed to set tx cpu chan map, err:%d\n", + __func__, ret); + } + +err: + return ret; +} + + +static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + int ret = 0; + u32 rx_ch_cdc_dma, tx_ch_cdc_dma; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + u32 user_set_tx_ch = 0; + u32 user_set_rx_ch = 0; + u32 ch_id; + + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, &tx_ch_cdc_dma, &rx_ch_cnt, + &rx_ch_cdc_dma); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + switch (dai_link->id) { + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0: + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1: + { + ch_id = msm_cdc_dma_get_idx_from_beid(dai_link->id); + pr_debug("%s: id %d rx_ch=%d\n", __func__, + ch_id, cdc_dma_rx_cfg[ch_id].channels); + user_set_rx_ch = cdc_dma_rx_cfg[ch_id].channels; + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + user_set_rx_ch, &rx_ch_cdc_dma); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + + } + break; + } + } else { + switch (dai_link->id) { + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0: + { + user_set_tx_ch = msm_vi_feed_tx_ch; + } + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1: + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: + { + ch_id = msm_cdc_dma_get_idx_from_beid(dai_link->id); + pr_debug("%s: id %d tx_ch=%d\n", __func__, + ch_id, cdc_dma_tx_cfg[ch_id].channels); + user_set_tx_ch = cdc_dma_tx_cfg[ch_id].channels; + } + break; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, user_set_tx_ch, + &tx_ch_cdc_dma, 0, 0); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + } + +err: + return ret; +} + +static int msm_slimbus_2_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; + unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0; + unsigned int num_tx_ch = 0; + unsigned int num_rx_ch = 0; + int ret = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + num_rx_ch = params_channels(params); + pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__, + codec_dai->name, codec_dai->id, num_rx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + num_rx_ch, rx_ch); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + } else { + num_tx_ch = params_channels(params); + pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__, + codec_dai->name, codec_dai->id, num_tx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get tx codec chan map, err:%d\n", + __func__, ret); + goto err; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, + num_tx_ch, tx_ch, 0, 0); + if (ret < 0) { + pr_err("%s: failed to set tx cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + } + +err: + return ret; +} + +static int msm_wcn_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + int ret; + + dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret) { + dev_err(rtd->dev, + "%s: failed to get BTFM codec chan map\n, err:%d\n", + __func__, ret); + goto err; + } + + dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) BE id %d\n", + __func__, tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); + if (ret) + dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + +err: + return ret; +} + +static int msm_get_port_id(int be_id) +{ + int afe_port_id; + + switch (be_id) { + case MSM_BACKEND_DAI_PRI_MI2S_RX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_PRI_MI2S_TX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUINARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUINARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUINARY_MI2S_TX; + break; + default: + pr_err("%s: Invalid BE id: %d\n", __func__, be_id); + afe_port_id = -EINVAL; + } + + return afe_port_id; +} + +static u32 get_mi2s_bits_per_sample(u32 bit_format) +{ + u32 bit_per_sample; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + case SNDRV_PCM_FORMAT_S24_LE: + bit_per_sample = 32; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bit_per_sample = 16; + break; + } + + return bit_per_sample; +} + +static void update_mi2s_clk_val(int dai_id, int stream) +{ + u32 bit_per_sample; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } else { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } +} + +static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int port_id = 0; + int index = cpu_dai->id; + + port_id = msm_get_port_id(rtd->dai_link->id); + if (port_id < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto err; + } + + if (enable) { + update_mi2s_clk_val(index, substream->stream); + dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, + mi2s_clk[index].clk_freq_in_hz); + } + + mi2s_clk[index].enable = enable; + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_clk[index]); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed for port 0x%x , err:%d\n", + __func__, port_id, ret); + goto err; + } + +err: + return ret; +} + +static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, + enum pinctrl_pin_state new_state) +{ + int ret = 0; + int curr_state = 0; + + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + if (pinctrl_info->pinctrl == NULL) { + pr_err("%s: pinctrl_info->pinctrl is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + curr_state = pinctrl_info->curr_state; + pinctrl_info->curr_state = new_state; + pr_debug("%s: curr_state = %s new_state = %s\n", __func__, + pin_states[curr_state], pin_states[pinctrl_info->curr_state]); + + if (curr_state == pinctrl_info->curr_state) { + pr_debug("%s: Already in same state\n", __func__); + goto err; + } + + if (curr_state != STATE_DISABLE && + pinctrl_info->curr_state != STATE_DISABLE) { + pr_debug("%s: state already active cannot switch\n", __func__); + ret = -EIO; + goto err; + } + + switch (pinctrl_info->curr_state) { + case STATE_MI2S_ACTIVE: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_active); + if (ret) { + pr_err("%s: MI2S state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + case STATE_TDM_ACTIVE: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->tdm_active); + if (ret) { + pr_err("%s: TDM state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + case STATE_DISABLE: + if (curr_state == STATE_MI2S_ACTIVE) { + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_disable); + } else { + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->tdm_disable); + } + if (ret) { + pr_err("%s: state disable failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + default: + pr_err("%s: TLMM pin state is invalid\n", __func__); + return -EINVAL; + } + +err: + return ret; +} + +static void msm_release_pinctrl(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + if (pinctrl_info->pinctrl) { + devm_pinctrl_put(pinctrl_info->pinctrl); + pinctrl_info->pinctrl = NULL; + } +} + +static int msm_get_pinctrl(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = NULL; + struct pinctrl *pinctrl; + int ret; + + pinctrl_info = &pdata->pinctrl_info; + + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + return -EINVAL; + } + + pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR_OR_NULL(pinctrl)) { + pr_err("%s: Unable to get pinctrl handle\n", __func__); + return -EINVAL; + } + pinctrl_info->pinctrl = pinctrl; + + /* get all the states handles from Device Tree */ + pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl, + "quat-mi2s-sleep"); + if (IS_ERR(pinctrl_info->mi2s_disable)) { + pr_err("%s: could not get mi2s_disable pinstate\n", __func__); + goto err; + } + pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl, + "quat-mi2s-active"); + if (IS_ERR(pinctrl_info->mi2s_active)) { + pr_err("%s: could not get mi2s_active pinstate\n", __func__); + goto err; + } + pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl, + "quat-tdm-sleep"); + if (IS_ERR(pinctrl_info->tdm_disable)) { + pr_err("%s: could not get tdm_disable pinstate\n", __func__); + goto err; + } + pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl, + "quat-tdm-active"); + if (IS_ERR(pinctrl_info->tdm_active)) { + pr_err("%s: could not get tdm_active pinstate\n", + __func__); + goto err; + } + /* Reset the TLMM pins to a default state */ + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_disable); + if (ret != 0) { + pr_err("%s: Disable TLMM pins failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + pinctrl_info->curr_state = STATE_DISABLE; + + return 0; + +err: + devm_pinctrl_put(pinctrl); + pinctrl_info->pinctrl = NULL; + return -EINVAL; +} + +static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + if (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) { + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + } else if (cpu_dai->id == AFE_PORT_ID_SECONDARY_TDM_RX) { + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + } else if (cpu_dai->id == AFE_PORT_ID_QUINARY_TDM_RX) { + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate; + } else { + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n", + __func__, cpu_dai->id, channels->max, rate->max, + params_format(params)); + + return 0; +} + +static int qcs405_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + int slot_width = 32; + int channels, slots; + unsigned int slot_mask, rate, clk_freq; + unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; + + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + slots = tdm_rx_cfg[TDM_PRI][TDM_0].channels; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + slots = tdm_rx_cfg[TDM_SEC][TDM_0].channels; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + slots = tdm_rx_cfg[TDM_TERT][TDM_0].channels; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + break; + case AFE_PORT_ID_QUINARY_TDM_RX: + slots = tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX: + slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX: + slots = tdm_tx_cfg[TDM_SEC][TDM_0].channels; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX: + slots = tdm_tx_cfg[TDM_TERT][TDM_0].channels; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + break; + case AFE_PORT_ID_QUINARY_TDM_TX: + slots = tdm_tx_cfg[TDM_QUIN][TDM_0].channels; + break; + + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + /*2 slot config - bits 0 and 1 set for the first two slots */ + slot_mask = 0x0000FFFF >> (16-slots); + channels = slots; + + pr_debug("%s: tdm rx slot_width %d slots %d\n", + __func__, slot_width, slots); + + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm rx slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + 0, NULL, channels, slot_offset); + if (ret < 0) { + pr_err("%s: failed to set tdm rx channel map, err:%d\n", + __func__, ret); + goto end; + } + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + /*2 slot config - bits 0 and 1 set for the first two slots */ + slot_mask = 0x0000FFFF >> (16-slots); + channels = slots; + + pr_debug("%s: tdm tx slot_width %d slots %d\n", + __func__, slot_width, slots); + + ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm tx slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + channels, slot_offset, 0, NULL); + if (ret < 0) { + pr_err("%s: failed to set tdm tx channel map, err:%d\n", + __func__, ret); + goto end; + } + } else { + ret = -EINVAL; + pr_err("%s: invalid use case, err:%d\n", + __func__, ret); + goto end; + } + + rate = params_rate(params); + clk_freq = rate * slot_width * slots; + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, clk_freq, SND_SOC_CLOCK_OUT); + if (ret < 0) + pr_err("%s: failed to set tdm clk, err:%d\n", + __func__, ret); + +end: + return ret; +} + +static int qcs405_tdm_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || + (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { + ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); + if (ret) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret); + } + + return ret; +} + +static void qcs405_tdm_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || + (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { + ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); + if (ret) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret); + } +} + +static struct snd_soc_ops qcs405_tdm_be_ops = { + .hw_params = qcs405_tdm_snd_hw_params, + .startup = qcs405_tdm_snd_startup, + .shutdown = qcs405_tdm_snd_shutdown +}; + +static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) +{ + cpumask_t mask; + + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + + cpumask_clear(&mask); + cpumask_set_cpu(1, &mask); /* affine to core 1 */ + cpumask_set_cpu(2, &mask); /* affine to core 2 */ + cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); + + substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; + + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + MSM_LL_QOS_VALUE); + return 0; +} + +static struct snd_soc_ops msm_fe_qos_ops = { + .prepare = msm_fe_qos_prepare, +}; + +static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int index = cpu_dai->id; + unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret_pinctrl = 0; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + if (index < PRIM_MI2S || index >= MI2S_MAX) { + ret = -EINVAL; + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto err; + } + /* + * Mutex protection in case the same MI2S + * interface using for both TX and RX so + * that the same clock won't be enable twice. + */ + mutex_lock(&mi2s_intf_conf[index].lock); + if (++mi2s_intf_conf[index].ref_cnt == 1) { + /* Check if msm needs to provide the clock to the interface */ + if (!mi2s_intf_conf[index].msm_is_mi2s_master) { + mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; + fmt = SND_SOC_DAIFMT_CBM_CFM; + } + ret = msm_mi2s_set_sclk(substream, true); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed to enable MI2S clock, err:%d\n", + __func__, ret); + goto clean_up; + } + + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) { + pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n", + __func__, index, ret); + goto clk_off; + } + if (index == QUAT_MI2S) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_MI2S_ACTIVE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } + } +clk_off: + if (ret < 0) + msm_mi2s_set_sclk(substream, false); +clean_up: + if (ret < 0) + mi2s_intf_conf[index].ref_cnt--; + mutex_unlock(&mi2s_intf_conf[index].lock); +err: + return ret; +} + +static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int index = rtd->cpu_dai->id; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret_pinctrl = 0; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + if (index < PRIM_MI2S || index >= MI2S_MAX) { + pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); + return; + } + + mutex_lock(&mi2s_intf_conf[index].lock); + if (--mi2s_intf_conf[index].ref_cnt == 0) { + ret = msm_mi2s_set_sclk(substream, false); + if (ret < 0) + pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", + __func__, index, ret); + if (index == QUAT_MI2S) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_DISABLE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } + } + mutex_unlock(&mi2s_intf_conf[index].lock); +} + +static struct snd_soc_ops msm_mi2s_be_ops = { + .startup = msm_mi2s_snd_startup, + .shutdown = msm_mi2s_snd_shutdown, +}; + +static struct snd_soc_ops msm_cdc_dma_be_ops = { + .hw_params = msm_snd_cdc_dma_hw_params, +}; + +static struct snd_soc_ops msm_be_ops = { + .hw_params = msm_snd_hw_params, +}; + +static struct snd_soc_ops msm_slimbus_2_be_ops = { + .hw_params = msm_slimbus_2_hw_params, +}; + +static struct snd_soc_ops msm_wcn_ops = { + .hw_params = msm_wcn_hw_params, +}; + + +/* Digital audio interface glue - connects codec <---> CPU */ +static struct snd_soc_dai_link msm_common_dai_links[] = { + /* FrontEnd DAI Links */ + { + .name = MSM_DAILINK_NAME(Media1), + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, + { + .name = MSM_DAILINK_NAME(Media2), + .stream_name = "MultiMedia2", + .cpu_dai_name = "MultiMedia2", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, + }, + { + .name = "VoiceMMode1", + .stream_name = "VoiceMMode1", + .cpu_dai_name = "VoiceMMode1", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE1, + }, + { + .name = "MSM VoIP", + .stream_name = "VoIP", + .cpu_dai_name = "VoIP", + .platform_name = "msm-voip-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_VOIP, + }, + { + .name = MSM_DAILINK_NAME(ULL), + .stream_name = "MultiMedia3", + .cpu_dai_name = "MultiMedia3", + .platform_name = "msm-pcm-dsp.2", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA3, + }, + /* Hostless PCM purpose */ + { + .name = "SLIMBUS_0 Hostless", + .stream_name = "SLIMBUS_0 Hostless", + .cpu_dai_name = "SLIMBUS0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "MSM AFE-PCM RX", + .stream_name = "AFE-PROXY RX", + .cpu_dai_name = "msm-dai-q6-dev.241", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .platform_name = "msm-pcm-afe", + .dpcm_playback = 1, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + }, + { + .name = "MSM AFE-PCM TX", + .stream_name = "AFE-PROXY TX", + .cpu_dai_name = "msm-dai-q6-dev.240", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .platform_name = "msm-pcm-afe", + .dpcm_capture = 1, + .ignore_suspend = 1, + }, + { + .name = MSM_DAILINK_NAME(Compress1), + .stream_name = "Compress1", + .cpu_dai_name = "MultiMedia4", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA4, + }, + { + .name = "AUXPCM Hostless", + .stream_name = "AUXPCM Hostless", + .cpu_dai_name = "AUXPCM_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_1 Hostless", + .stream_name = "SLIMBUS_1 Hostless", + .cpu_dai_name = "SLIMBUS1_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_3 Hostless", + .stream_name = "SLIMBUS_3 Hostless", + .cpu_dai_name = "SLIMBUS3_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_4 Hostless", + .stream_name = "SLIMBUS_4 Hostless", + .cpu_dai_name = "SLIMBUS4_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = MSM_DAILINK_NAME(LowLatency), + .stream_name = "MultiMedia5", + .cpu_dai_name = "MultiMedia5", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .ops = &msm_fe_qos_ops, + }, + { + .name = "Listen 1 Audio Service", + .stream_name = "Listen 1 Audio Service", + .cpu_dai_name = "LSM1", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM1, + }, + /* Multiple Tunnel instances */ + { + .name = MSM_DAILINK_NAME(Compress2), + .stream_name = "Compress2", + .cpu_dai_name = "MultiMedia7", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA7, + }, + { + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", + .cpu_dai_name = "MultiMedia10", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA10, + }, + { + .name = MSM_DAILINK_NAME(ULL_NOIRQ), + .stream_name = "MM_NOIRQ", + .cpu_dai_name = "MultiMedia8", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + .ops = &msm_fe_qos_ops, + }, + /* HDMI Hostless */ + { + .name = "HDMI_RX_HOSTLESS", + .stream_name = "HDMI_RX_HOSTLESS", + .cpu_dai_name = "HDMI_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "VoiceMMode2", + .stream_name = "VoiceMMode2", + .cpu_dai_name = "VoiceMMode2", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE2, + }, + /* LSM FE */ + { + .name = "Listen 2 Audio Service", + .stream_name = "Listen 2 Audio Service", + .cpu_dai_name = "LSM2", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM2, + }, + { + .name = "Listen 3 Audio Service", + .stream_name = "Listen 3 Audio Service", + .cpu_dai_name = "LSM3", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM3, + }, + { + .name = "Listen 4 Audio Service", + .stream_name = "Listen 4 Audio Service", + .cpu_dai_name = "LSM4", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM4, + }, + { + .name = "Listen 5 Audio Service", + .stream_name = "Listen 5 Audio Service", + .cpu_dai_name = "LSM5", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM5, + }, + { + .name = "Listen 6 Audio Service", + .stream_name = "Listen 6 Audio Service", + .cpu_dai_name = "LSM6", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM6, + }, + { + .name = "Listen 7 Audio Service", + .stream_name = "Listen 7 Audio Service", + .cpu_dai_name = "LSM7", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM7, + }, + { + .name = "Listen 8 Audio Service", + .stream_name = "Listen 8 Audio Service", + .cpu_dai_name = "LSM8", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM8, + }, + { + .name = MSM_DAILINK_NAME(Media9), + .stream_name = "MultiMedia9", + .cpu_dai_name = "MultiMedia9", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA9, + }, + { + .name = MSM_DAILINK_NAME(Compress4), + .stream_name = "Compress4", + .cpu_dai_name = "MultiMedia11", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA11, + }, + { + .name = MSM_DAILINK_NAME(Compress5), + .stream_name = "Compress5", + .cpu_dai_name = "MultiMedia12", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA12, + }, + { + .name = MSM_DAILINK_NAME(Compress6), + .stream_name = "Compress6", + .cpu_dai_name = "MultiMedia13", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA13, + }, + { + .name = MSM_DAILINK_NAME(Compress7), + .stream_name = "Compress7", + .cpu_dai_name = "MultiMedia14", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA14, + }, + { + .name = MSM_DAILINK_NAME(Compress8), + .stream_name = "Compress8", + .cpu_dai_name = "MultiMedia15", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA15, + }, + { + .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), + .stream_name = "MM_NOIRQ_2", + .cpu_dai_name = "MultiMedia16", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA16, + }, + { + .name = "SLIMBUS_8 Hostless", + .stream_name = "SLIMBUS8_HOSTLESS Capture", + .cpu_dai_name = "SLIMBUS8_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +}; + +static struct snd_soc_dai_link msm_tasha_fe_dai_links[] = { + /* Ultrasound RX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Playback", + .stream_name = "SLIMBUS_2 Hostless Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx2", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_slimbus_2_be_ops, + }, + /* Ultrasound TX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Capture", + .stream_name = "SLIMBUS_2 Hostless Capture", + .cpu_dai_name = "msm-dai-q6-dev.16389", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx2", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_slimbus_2_be_ops, + }, + { + .name = "SLIMBUS_6 Hostless Playback", + .stream_name = "SLIMBUS_6 Hostless", + .cpu_dai_name = "SLIMBUS6_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +}; + +static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { + { + .name = MSM_DAILINK_NAME(ASM Loopback), + .stream_name = "MultiMedia6", + .cpu_dai_name = "MultiMedia6", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA6, + }, + { + .name = "USB Audio Hostless", + .stream_name = "USB Audio Hostless", + .cpu_dai_name = "USBAUDIO_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_7 Hostless", + .stream_name = "SLIMBUS_7 Hostless", + .cpu_dai_name = "SLIMBUS7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +}; + +static struct snd_soc_dai_link msm_common_be_dai_links[] = { + /* Backend AFE DAI Links */ + { + .name = LPASS_BE_AFE_PCM_RX, + .stream_name = "AFE Playback", + .cpu_dai_name = "msm-dai-q6-dev.224", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AFE_PCM_TX, + .stream_name = "AFE Capture", + .cpu_dai_name = "msm-dai-q6-dev.225", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Uplink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_TX, + .stream_name = "Voice Uplink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32772", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Downlink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_RX, + .stream_name = "Voice Downlink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32771", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music BACK END DAI Link */ + { + .name = LPASS_BE_VOICE_PLAYBACK_TX, + .stream_name = "Voice Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32773", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + /* Incall Music 2 BACK END DAI Link */ + { + .name = LPASS_BE_VOICE2_PLAYBACK_TX, + .stream_name = "Voice2 Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32770", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_RX, + .stream_name = "USB Audio Playback", + .cpu_dai_name = "msm-dai-q6-dev.28672", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_USB_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_TX, + .stream_name = "USB Audio Capture", + .cpu_dai_name = "msm-dai-q6-dev.28673", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_USB_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_0, + .stream_name = "Primary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36864", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &qcs405_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_0, + .stream_name = "Primary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36865", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &qcs405_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_0, + .stream_name = "Secondary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36880", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &qcs405_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_0, + .stream_name = "Secondary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36881", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &qcs405_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_0, + .stream_name = "Tertiary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36896", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &qcs405_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_0, + .stream_name = "Tertiary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36897", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &qcs405_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_0, + .stream_name = "Quaternary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36912", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &qcs405_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_0, + .stream_name = "Quaternary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36913", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &qcs405_tdm_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_tasha_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_init, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_1_RX, + .stream_name = "Slimbus1 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16386", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_1_TX, + .stream_name = "Slimbus1 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16387", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx3", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_2_RX, + .stream_name = "Slimbus2 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx2", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_2_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_RX, + .stream_name = "Slimbus3 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16390", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_TX, + .stream_name = "Slimbus3 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16391", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_4_RX, + .stream_name = "Slimbus4 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16392", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_5_RX, + .stream_name = "Slimbus5 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16394", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx3", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_6_RX, + .stream_name = "Slimbus6 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16396", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx4", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* Slimbus VI Recording */ + { + .name = LPASS_BE_SLIMBUS_TX_VI, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_vifeedback", + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + .no_pcm = 1, + .dpcm_capture = 1, + .ignore_pmdown_time = 1, + }, +}; + +static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_7_RX, + .stream_name = "Slimbus7 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16398", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + /* BT codec driver determines capabilities based on + * dai name, bt codecdai name should always contains + * supported usecase information + */ + .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_7_TX, + .stream_name = "Slimbus7 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16399", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_bt_sco_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_8_TX, + .stream_name = "Slimbus8 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16401", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_fm_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_8_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .init = &msm_wcn_init, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { + { + .name = LPASS_BE_PRI_MI2S_RX, + .stream_name = "Primary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_MI2S_TX, + .stream_name = "Primary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX, + .stream_name = "Secondary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX, + .stream_name = "Secondary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX, + .stream_name = "Tertiary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX, + .stream_name = "Tertiary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX, + .stream_name = "Quaternary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_RX, + .stream_name = "Quinary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_TX, + .stream_name = "Quinary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + +}; + +static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { + /* Primary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_AUXPCM_RX, + .stream_name = "AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AUXPCM_TX, + .stream_name = "AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Secondary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_SEC_AUXPCM_RX, + .stream_name = "Sec AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_AUXPCM_TX, + .stream_name = "Sec AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Tertiary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_TERT_AUXPCM_RX, + .stream_name = "Tert AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_AUXPCM_TX, + .stream_name = "Tert AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Quaternary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUAT_AUXPCM_RX, + .stream_name = "Quat AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_AUXPCM_TX, + .stream_name = "Quat AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Quinary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUIN_AUXPCM_RX, + .stream_name = "Quin AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_AUXPCM_TX, + .stream_name = "Quin AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = { + /* WSA CDC DMA Backend DAI Links */ + { + .name = LPASS_BE_WSA_CDC_DMA_RX_0, + .stream_name = "WSA CDC DMA0 Playback", + .cpu_dai_name = "msm-dai-cdc-dma.45056", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "wsa_macro_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .init = &msm_wsa_cdc_dma_init, + .id = MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_WSA_CDC_DMA_TX_0, + .stream_name = "WSA CDC DMA0 Capture", + .cpu_dai_name = "msm-dai-cdc-dma.45057", + .platform_name = "msm-pcm-hostless", + .codec_name = "bolero_codec", + .codec_dai_name = "wsa_macro_vifeedback", + .id = MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_WSA_CDC_DMA_RX_1, + .stream_name = "WSA CDC DMA1 Playback", + .cpu_dai_name = "msm-dai-cdc-dma.45058", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "wsa_macro_rx_mix", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_WSA_CDC_DMA_TX_1, + .stream_name = "WSA CDC DMA1 Capture", + .cpu_dai_name = "msm-dai-cdc-dma.45059", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "wsa_macro_echo", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_WSA_CDC_DMA_TX_2, + .stream_name = "WSA CDC DMA2 Capture", + .cpu_dai_name = "msm-dai-cdc-dma.45061", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_va_cdc_dma_be_dai_links[] = { + { + .name = LPASS_BE_VA_CDC_DMA_TX_0, + .stream_name = "VA CDC DMA0 Capture", + .cpu_dai_name = "msm-dai-cdc-dma.49153", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "va_macro_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .init = &msm_va_cdc_dma_init, + .id = MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_VA_CDC_DMA_TX_1, + .stream_name = "VA CDC DMA1 Capture", + .cpu_dai_name = "msm-dai-cdc-dma.49155", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "va_macro_tx2", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_qcs405_dai_links[ + ARRAY_SIZE(msm_common_dai_links) + + ARRAY_SIZE(msm_tasha_fe_dai_links) + + ARRAY_SIZE(msm_common_misc_fe_dai_links) + + ARRAY_SIZE(msm_common_be_dai_links) + + ARRAY_SIZE(msm_tasha_be_dai_links) + + ARRAY_SIZE(msm_wcn_be_dai_links) + + ARRAY_SIZE(msm_mi2s_be_dai_links) + + ARRAY_SIZE(msm_auxpcm_be_dai_links) + + ARRAY_SIZE(msm_va_cdc_dma_be_dai_links) + + ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links)]; + +static int msm_snd_card_tasha_late_probe(struct snd_soc_card *card) +{ + int ret = 0; + + ret = audio_notifier_register("qcs405", AUDIO_NOTIFIER_ADSP_DOMAIN, + &service_nb); + if (ret < 0) + pr_err("%s: Audio notifier register failed ret = %d\n", + __func__, ret); + + return ret; +} + +struct snd_soc_card snd_soc_card_qcs405_msm = { + .name = "qcs405-snd-card", + .controls = msm_snd_controls, + .num_controls = ARRAY_SIZE(msm_snd_controls), +}; + +static int msm_populate_dai_link_component_of_node( + struct snd_soc_card *card) +{ + int i, index, ret = 0; + struct device *cdev = card->dev; + struct snd_soc_dai_link *dai_link = card->dai_link; + struct device_node *np; + + if (!cdev) { + pr_err("%s: Sound card device memory NULL\n", __func__); + return -ENODEV; + } + + for (i = 0; i < card->num_links; i++) { + if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) + continue; + + /* populate platform_of_node for snd card dai links */ + if (dai_link[i].platform_name && + !dai_link[i].platform_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-platform-names", + dai_link[i].platform_name); + if (index < 0) { + pr_err("%s: No match found for platform name: %s\n", + __func__, dai_link[i].platform_name); + ret = index; + goto err; + } + np = of_parse_phandle(cdev->of_node, "asoc-platform", + index); + if (!np) { + pr_err("%s: retrieving phandle for platform %s, index %d failed\n", + __func__, dai_link[i].platform_name, + index); + ret = -ENODEV; + goto err; + } + dai_link[i].platform_of_node = np; + dai_link[i].platform_name = NULL; + } + + /* populate cpu_of_node for snd card dai links */ + if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-cpu-names", + dai_link[i].cpu_dai_name); + if (index >= 0) { + np = of_parse_phandle(cdev->of_node, "asoc-cpu", + index); + if (!np) { + pr_err("%s: retrieving phandle for cpu dai %s failed\n", + __func__, + dai_link[i].cpu_dai_name); + ret = -ENODEV; + goto err; + } + dai_link[i].cpu_of_node = np; + dai_link[i].cpu_dai_name = NULL; + } + } + + /* populate codec_of_node for snd card dai links */ + if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-codec-names", + dai_link[i].codec_name); + if (index < 0) + continue; + np = of_parse_phandle(cdev->of_node, "asoc-codec", + index); + if (!np) { + pr_err("%s: retrieving phandle for codec %s failed\n", + __func__, dai_link[i].codec_name); + ret = -ENODEV; + goto err; + } + dai_link[i].codec_of_node = np; + dai_link[i].codec_name = NULL; + } + } + +err: + return ret; +} + +static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd) +{ + return 0; +} + +static int msm_snd_stub_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + + int ret = 0; + unsigned int rx_ch[] = {144, 145, 146, 147, 148, 149, 150, + 151}; + unsigned int tx_ch[] = {128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143}; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + slim_rx_cfg[SLIM_RX_0].channels, + rx_ch); + if (ret < 0) + pr_err("%s: RX failed to set cpu chan map error %d\n", + __func__, ret); + } else { + ret = snd_soc_dai_set_channel_map(cpu_dai, + slim_tx_cfg[SLIM_TX_0].channels, + tx_ch, 0, 0); + if (ret < 0) + pr_err("%s: TX failed to set cpu chan map error %d\n", + __func__, ret); + } + + return ret; +} + +static struct snd_soc_ops msm_stub_be_ops = { + .hw_params = msm_snd_stub_hw_params, +}; + +static struct snd_soc_dai_link msm_stub_fe_dai_links[] = { + + /* FrontEnd DAI Links */ + { + .name = "MSMSTUB Media1", + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, +}; + +static struct snd_soc_dai_link msm_stub_be_dai_links[] = { + + /* Backend DAI Links */ + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_stub_init, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, /* dai link has playback support */ + .ignore_suspend = 1, + .ops = &msm_stub_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_stub_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_stub_dai_links[ + ARRAY_SIZE(msm_stub_fe_dai_links) + + ARRAY_SIZE(msm_stub_be_dai_links)]; + +struct snd_soc_card snd_soc_card_stub_msm = { + .name = "qcs405-stub-snd-card", +}; + +static const struct of_device_id qcs405_asoc_machine_of_match[] = { + { .compatible = "qcom,qcs405-asoc-snd", + .data = "codec"}, + { .compatible = "qcom,qcs405-asoc-snd-stub", + .data = "stub_codec"}, + {}, +}; + +static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) +{ + struct snd_soc_card *card = NULL; + struct snd_soc_dai_link *dailink; + int total_links = 0; + uint32_t tasha_codec = 0, auxpcm_audio_intf = 0; + uint32_t va_bolero_codec = 0, wsa_bolero_codec = 0, mi2s_audio_intf = 0; + const struct of_device_id *match; + int rc = 0; + + match = of_match_node(qcs405_asoc_machine_of_match, dev->of_node); + if (!match) { + dev_err(dev, "%s: No DT match found for sound card\n", + __func__); + return NULL; + } + + if (!strcmp(match->data, "codec")) { + card = &snd_soc_card_qcs405_msm; + memcpy(msm_qcs405_dai_links + total_links, + msm_common_dai_links, + sizeof(msm_common_dai_links)); + + total_links += ARRAY_SIZE(msm_common_dai_links); + rc = of_property_read_u32(dev->of_node, "qcom,tasha-codec", + &tasha_codec); + if (rc) { + dev_dbg(dev, "%s: No DT match tasha codec\n", + __func__); + } else { + if (tasha_codec) { + dev_dbg(dev, "%s(): Tasha codec is present\n", + __func__); + card->late_probe = + msm_snd_card_tasha_late_probe; + memcpy(msm_qcs405_dai_links + total_links, + msm_tasha_fe_dai_links, + sizeof(msm_tasha_fe_dai_links)); + total_links += + ARRAY_SIZE(msm_tasha_fe_dai_links); + } + } + + memcpy(msm_qcs405_dai_links + total_links, + msm_common_misc_fe_dai_links, + sizeof(msm_common_misc_fe_dai_links)); + + total_links += ARRAY_SIZE(msm_common_misc_fe_dai_links); + + memcpy(msm_qcs405_dai_links + total_links, + msm_common_be_dai_links, + sizeof(msm_common_be_dai_links)); + + total_links += ARRAY_SIZE(msm_common_be_dai_links); + + if (tasha_codec) { + memcpy(msm_qcs405_dai_links + total_links, + msm_tasha_be_dai_links, + sizeof(msm_tasha_be_dai_links)); + total_links += ARRAY_SIZE(msm_tasha_be_dai_links); + } + + rc = of_property_read_u32(dev->of_node, "qcom,va-bolero-codec", + &va_bolero_codec); + if (rc) { + dev_dbg(dev, "%s: No DT match VA Macro codec\n", + __func__); + } else { + if (va_bolero_codec) { + dev_dbg(dev, "%s(): VA macro in bolero codec present\n", + __func__); + + memcpy(msm_qcs405_dai_links + total_links, + msm_va_cdc_dma_be_dai_links, + sizeof(msm_va_cdc_dma_be_dai_links)); + total_links += + ARRAY_SIZE(msm_va_cdc_dma_be_dai_links); + } + } + + rc = of_property_read_u32(dev->of_node, "qcom,wsa-bolero-codec", + &wsa_bolero_codec); + if (rc) { + dev_dbg(dev, "%s: No DT match WSA Macro codec\n", + __func__); + } else { + if (wsa_bolero_codec) { + dev_dbg(dev, "%s(): WSAmacro in bolero codec present\n", + __func__); + + memcpy(msm_qcs405_dai_links + total_links, + msm_wsa_cdc_dma_be_dai_links, + sizeof(msm_wsa_cdc_dma_be_dai_links)); + total_links += + ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links); + } + } + + rc = of_property_read_u32(dev->of_node, "qcom,mi2s-audio-intf", + &mi2s_audio_intf); + if (rc) { + dev_dbg(dev, "%s: No DT match MI2S audio interface\n", + __func__); + } else { + if (mi2s_audio_intf) { + memcpy(msm_qcs405_dai_links + total_links, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + total_links += + ARRAY_SIZE(msm_mi2s_be_dai_links); + } + } + rc = of_property_read_u32(dev->of_node, + "qcom,auxpcm-audio-intf", + &auxpcm_audio_intf); + if (rc) { + dev_dbg(dev, "%s: No DT match Aux PCM interface\n", + __func__); + } else { + if (auxpcm_audio_intf) { + memcpy(msm_qcs405_dai_links + total_links, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + total_links += + ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + } + dailink = msm_qcs405_dai_links; + } else if (!strcmp(match->data, "stub_codec")) { + card = &snd_soc_card_stub_msm; + + memcpy(msm_stub_dai_links + total_links, + msm_stub_fe_dai_links, + sizeof(msm_stub_fe_dai_links)); + total_links += ARRAY_SIZE(msm_stub_fe_dai_links); + + memcpy(msm_stub_dai_links + total_links, + msm_stub_be_dai_links, + sizeof(msm_stub_be_dai_links)); + total_links += ARRAY_SIZE(msm_stub_be_dai_links); + + dailink = msm_stub_dai_links; + } + + if (card) { + card->dai_link = dailink; + card->num_links = total_links; + } + + return card; +} + +static int msm_wsa881x_init(struct snd_soc_component *component) +{ + u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106}; + u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107}; + unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; + unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + struct msm_asoc_mach_data *pdata; + struct snd_soc_dapm_context *dapm; + int ret = 0; + + if (!codec) { + pr_err("%s codec is NULL\n", __func__); + return -EINVAL; + } + + dapm = snd_soc_codec_get_dapm(codec); + + if (!strcmp(component->name_prefix, "SpkrLeft")) { + dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n", + __func__, codec->component.name); + wsa881x_set_channel_map(codec, &spkleft_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0]); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); + } + } else if (!strcmp(component->name_prefix, "SpkrRight")) { + dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n", + __func__, codec->component.name); + wsa881x_set_channel_map(codec, &spkright_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0]); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); + } + } else { + dev_err(codec->dev, "%s: wrong codec name %s\n", __func__, + codec->component.name); + ret = -EINVAL; + goto err; + } + pdata = snd_soc_card_get_drvdata(component->card); + if (pdata && pdata->codec_root) + wsa881x_codec_info_create_codec_entry(pdata->codec_root, + codec); + +err: + return ret; +} + +static int msm_init_wsa_dev(struct platform_device *pdev, + struct snd_soc_card *card) +{ + struct device_node *wsa_of_node; + u32 wsa_max_devs; + u32 wsa_dev_cnt; + int i; + struct msm_wsa881x_dev_info *wsa881x_dev_info; + const char *wsa_auxdev_name_prefix[1]; + char *dev_name_str = NULL; + int found = 0; + int ret = 0; + + /* Get maximum WSA device count for this platform */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,wsa-max-devs", &wsa_max_devs); + if (ret) { + dev_info(&pdev->dev, + "%s: wsa-max-devs property missing in DT %s, ret = %d\n", + __func__, pdev->dev.of_node->full_name, ret); + card->num_aux_devs = 0; + return 0; + } + if (wsa_max_devs == 0) { + dev_warn(&pdev->dev, + "%s: Max WSA devices is 0 for this target?\n", + __func__); + card->num_aux_devs = 0; + return 0; + } + + /* Get count of WSA device phandles for this platform */ + wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node, + "qcom,wsa-devs", NULL); + if (wsa_dev_cnt == -ENOENT) { + dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n", + __func__); + goto err; + } else if (wsa_dev_cnt <= 0) { + dev_err(&pdev->dev, + "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n", + __func__, wsa_dev_cnt); + ret = -EINVAL; + goto err; + } + + /* + * Expect total phandles count to be NOT less than maximum possible + * WSA count. However, if it is less, then assign same value to + * max count as well. + */ + if (wsa_dev_cnt < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n", + __func__, wsa_max_devs, wsa_dev_cnt); + wsa_max_devs = wsa_dev_cnt; + } + + /* Make sure prefix string passed for each WSA device */ + ret = of_property_count_strings(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix"); + if (ret != wsa_dev_cnt) { + dev_err(&pdev->dev, + "%s: expecting %d wsa prefix. Defined only %d in DT\n", + __func__, wsa_dev_cnt, ret); + ret = -EINVAL; + goto err; + } + + /* + * Alloc mem to store phandle and index info of WSA device, if already + * registered with ALSA core + */ + wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs, + sizeof(struct msm_wsa881x_dev_info), + GFP_KERNEL); + if (!wsa881x_dev_info) { + ret = -ENOMEM; + goto err; + } + + /* + * search and check whether all WSA devices are already + * registered with ALSA core or not. If found a node, store + * the node and the index in a local array of struct for later + * use. + */ + for (i = 0; i < wsa_dev_cnt; i++) { + wsa_of_node = of_parse_phandle(pdev->dev.of_node, + "qcom,wsa-devs", i); + if (unlikely(!wsa_of_node)) { + /* we should not be here */ + dev_err(&pdev->dev, + "%s: wsa dev node is not present\n", + __func__); + ret = -EINVAL; + goto err_free_dev_info; + } + if (soc_find_component(wsa_of_node, NULL)) { + /* WSA device registered with ALSA core */ + wsa881x_dev_info[found].of_node = wsa_of_node; + wsa881x_dev_info[found].index = i; + found++; + if (found == wsa_max_devs) + break; + } + } + + if (found < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: failed to find %d components. Found only %d\n", + __func__, wsa_max_devs, found); + return -EPROBE_DEFER; + } + dev_info(&pdev->dev, + "%s: found %d wsa881x devices registered with ALSA core\n", + __func__, found); + + card->num_aux_devs = wsa_max_devs; + card->num_configs = wsa_max_devs; + + /* Alloc array of AUX devs struct */ + msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_aux_dev), + GFP_KERNEL); + if (!msm_aux_dev) { + ret = -ENOMEM; + goto err_free_dev_info; + } + + /* Alloc array of codec conf struct */ + msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_codec_conf), + GFP_KERNEL); + if (!msm_codec_conf) { + ret = -ENOMEM; + goto err_free_aux_dev; + } + + for (i = 0; i < card->num_aux_devs; i++) { + dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN, + GFP_KERNEL); + if (!dev_name_str) { + ret = -ENOMEM; + goto err_free_cdc_conf; + } + + ret = of_property_read_string_index(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix", + wsa881x_dev_info[i].index, + wsa_auxdev_name_prefix); + if (ret) { + dev_err(&pdev->dev, + "%s: failed to read wsa aux dev prefix, ret = %d\n", + __func__, ret); + ret = -EINVAL; + goto err_free_dev_name_str; + } + + snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i); + msm_aux_dev[i].name = dev_name_str; + msm_aux_dev[i].codec_name = NULL; + msm_aux_dev[i].codec_of_node = + wsa881x_dev_info[i].of_node; + msm_aux_dev[i].init = msm_wsa881x_init; + msm_codec_conf[i].dev_name = NULL; + msm_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0]; + msm_codec_conf[i].of_node = + wsa881x_dev_info[i].of_node; + } + card->codec_conf = msm_codec_conf; + card->aux_dev = msm_aux_dev; + + return 0; + +err_free_dev_name_str: + devm_kfree(&pdev->dev, dev_name_str); +err_free_cdc_conf: + devm_kfree(&pdev->dev, msm_codec_conf); +err_free_aux_dev: + devm_kfree(&pdev->dev, msm_aux_dev); +err_free_dev_info: + devm_kfree(&pdev->dev, wsa881x_dev_info); +err: + return ret; +} + +static void msm_i2s_auxpcm_init(struct platform_device *pdev) +{ + int count; + u32 mi2s_master_slave[MI2S_MAX]; + int ret; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_init(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-master", + mi2s_master_slave, MI2S_MAX); + if (ret) { + dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n", + __func__); + } else { + for (count = 0; count < MI2S_MAX; count++) { + mi2s_intf_conf[count].msm_is_mi2s_master = + mi2s_master_slave[count]; + } + } +} + +static void msm_i2s_auxpcm_deinit(void) +{ + int count; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_destroy(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + mi2s_intf_conf[count].msm_is_mi2s_master = 0; + } +} + +static int msm_asoc_machine_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card; + struct msm_asoc_mach_data *pdata; + int ret; + + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, "No platform supplied from device tree\n"); + return -EINVAL; + } + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct msm_asoc_mach_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + card = populate_snd_card_dailinks(&pdev->dev); + if (!card) { + dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); + ret = -EINVAL; + goto err; + } + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, pdata); + + ret = snd_soc_of_parse_card_name(card, "qcom,model"); + if (ret) { + dev_err(&pdev->dev, "parse card name failed, err:%d\n", + ret); + goto err; + } + + ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing"); + if (ret) { + dev_err(&pdev->dev, "parse audio routing failed, err:%d\n", + ret); + goto err; + } + + ret = msm_populate_dai_link_component_of_node(card); + if (ret) { + ret = -EPROBE_DEFER; + goto err; + } + ret = msm_init_wsa_dev(pdev, card); + if (ret) + goto err; + + pdata->dmic_01_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-dmic01-gpios", + 0); + pdata->dmic_23_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-dmic23-gpios", + 0); + pdata->dmic_45_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-dmic45-gpios", + 0); + pdata->dmic_67_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-dmic67-gpios", + 0); + + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret == -EPROBE_DEFER) { + if (codec_reg_done) + ret = -EINVAL; + goto err; + } else if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); + goto err; + } + dev_info(&pdev->dev, "Sound card %s registered\n", card->name); + spdev = pdev; + + /* Parse pinctrl info from devicetree */ + ret = msm_get_pinctrl(pdev); + if (!ret) { + pr_debug("%s: pinctrl parsing successful\n", __func__); + } else { + dev_dbg(&pdev->dev, + "%s: Parsing pinctrl failed with %d. Cannot use Ports\n", + __func__, ret); + ret = 0; + } + + msm_i2s_auxpcm_init(pdev); + + is_initial_boot = true; + return 0; +err: + msm_release_pinctrl(pdev); + return ret; +} + +static int msm_asoc_machine_remove(struct platform_device *pdev) +{ + audio_notifier_deregister("qcs405"); + msm_i2s_auxpcm_deinit(); + + msm_release_pinctrl(pdev); + return 0; +} + +static struct platform_driver qcs405_asoc_machine_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = qcs405_asoc_machine_of_match, + }, + .probe = msm_asoc_machine_probe, + .remove = msm_asoc_machine_remove, +}; +module_platform_driver(qcs405_asoc_machine_driver); + +MODULE_DESCRIPTION("ALSA SoC QCS405 Machine driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, qcs405_asoc_machine_of_match); -- GitLab From 4e1e71885e9f148ab48b2b7d48b0d5d3a7c5d9c9 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Thu, 26 Apr 2018 17:58:58 +0530 Subject: [PATCH 0316/1645] dsp: afe: Add support for VAD in AFE native driver Update to AFE native driver to send VAD calibration to DSP. Add support for per service API version query in q6core driver. Change-Id: I6234879054e7b5622a40912da16072fd8dbd83fe Signed-off-by: Mangesh Kunchamwar --- dsp/Kbuild | 5 + dsp/q6afe.c | 229 ++++++++++++++++++++++++++++- dsp/q6afecal-hwdep.c | 235 ++++++++++++++++++++++++++++++ dsp/q6afecal-hwdep.h | 53 +++++++ dsp/q6core.c | 47 +++++- include/dsp/apr_audio-v2.h | 55 +++++++ include/dsp/q6afe-v2.h | 20 +++ include/dsp/q6core.h | 1 + include/uapi/sound/msmcal-hwdep.h | 16 ++ 9 files changed, 658 insertions(+), 3 deletions(-) create mode 100644 dsp/q6afecal-hwdep.c create mode 100644 dsp/q6afecal-hwdep.h diff --git a/dsp/Kbuild b/dsp/Kbuild index 74a2a7471e17..02a25e10fa19 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -92,11 +92,16 @@ ifdef CONFIG_SND_SOC_MSM_QDSP6V2_INTF Q6_OBJS += msm_audio_ion.o Q6_OBJS += avtimer.o Q6_OBJS += q6_init.o + endif ifdef CONFIG_DTS_SRS_TM Q6_OBJS += msm-dts-srs-tm-config.o endif +ifdef CONFIG_AFE_HWDEP + Q6_OBJS += q6afecal-hwdep.o +endif + ifdef CONFIG_MSM_ADSP_LOADER ADSP_LOADER_OBJS += adsp-loader.o endif diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 6d2a5733f55c..c17721046256 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -28,6 +28,7 @@ #include #include #include "adsp_err.h" +#include "q6afecal-hwdep.h" #define WAKELOCK_TIMEOUT 5000 enum { @@ -126,6 +127,10 @@ struct afe_ctl { int dev_acdb_id[AFE_MAX_PORTS]; routing_cb rt_cb; struct audio_uevent_data *uevent_data; + /* cal info for AFE */ + struct afe_fw_info *fw_data; + u32 island_mode[AFE_MAX_PORTS]; + struct vad_config vad_cfg[AFE_MAX_PORTS]; }; static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX]; @@ -1810,6 +1815,148 @@ static int afe_send_port_topology_id(u16 port_id) } + +static int afe_get_island_mode(u16 port_id, u32 *island_mode) +{ + int ret = 0; + int index = 0; + *island_mode = 0; + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + + *island_mode = this_afe.island_mode[index]; + return ret; +} + +/* + * afe_send_port_island_mode - + * for sending island mode to AFE + * + * @port_id: AFE port id number + * + * Returns 0 on success or error on failure. + */ +int afe_send_port_island_mode(u16 port_id) +{ + struct afe_param_id_island_cfg_t island_cfg; + struct param_hdr_v3 param_info; + u32 island_mode = 0; + int ret = 0; + + memset(&island_cfg, 0, sizeof(island_cfg)); + memset(¶m_info, 0, sizeof(param_info)); + + ret = afe_get_island_mode(port_id, &island_mode); + if (ret) { + pr_err("%s: AFE port[%d] get island mode is invalid!\n", + __func__, port_id); + return ret; + } + param_info.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = AFE_PARAM_ID_ISLAND_CONFIG; + param_info.param_size = sizeof(island_cfg); + + island_cfg.island_cfg_minor_version = AFE_API_VERSION_ISLAND_CONFIG; + island_cfg.island_enable = island_mode; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_info, (u8 *) &island_cfg); + if (ret) { + pr_err("%s: AFE set island mode enable for port 0x%x failed %d\n", + __func__, port_id, ret); + return ret; + } + pr_debug("%s: AFE set island mode 0x%x enable for port 0x%x ret %d\n", + __func__, island_mode, port_id, ret); + return ret; +} +EXPORT_SYMBOL(afe_send_port_island_mode); + +static int afe_get_vad_preroll_cfg(u16 port_id, u32 *preroll_cfg) +{ + int ret = 0; + int index = 0; + *preroll_cfg = 0; + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + + *preroll_cfg = this_afe.vad_cfg[index].pre_roll; + return ret; +} + +static int afe_send_port_vad_cfg_params(u16 port_id) +{ + struct afe_param_id_vad_cfg_t vad_cfg; + struct param_hdr_v3 param_info; + u32 pre_roll_cfg = 0; + struct firmware_cal *hwdep_cal = NULL; + int ret = 0; + + memset(&vad_cfg, 0, sizeof(vad_cfg)); + memset(¶m_info, 0, sizeof(param_info)); + + ret = afe_get_vad_preroll_cfg(port_id, &pre_roll_cfg); + if (ret) { + pr_err("%s: AFE port[%d] get preroll cfg is invalid!\n", + __func__, port_id); + return ret; + } + param_info.module_id = AFE_MODULE_VAD; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = AFE_PARAM_ID_VAD_CFG; + param_info.param_size = sizeof(vad_cfg); + + vad_cfg.vad_cfg_minor_version = AFE_API_VERSION_VAD_CFG; + vad_cfg.pre_roll_in_ms = pre_roll_cfg; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_info, (u8 *) &vad_cfg); + if (ret) { + pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n", + __func__, port_id, ret); + return ret; + } + + memset(¶m_info, 0, sizeof(param_info)); + + hwdep_cal = q6afecal_get_fw_cal(this_afe.fw_data, Q6AFE_VAD_CORE_CAL); + if (!hwdep_cal) { + pr_err("%s: error in retrieving vad core calibration", + __func__); + return -EINVAL; + } + + param_info.module_id = AFE_MODULE_VAD; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = AFE_PARAM_ID_VAD_CORE_CFG; + param_info.param_size = hwdep_cal->size; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_info, (u8 *) hwdep_cal->data); + if (ret) { + pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n", + __func__, port_id, ret); + return ret; + } + pr_debug("%s: AFE set preroll cfg %d vad core cfg port 0x%x ret %d\n", + __func__, pre_roll_cfg, port_id, ret); + return ret; +} + static int remap_cal_data(struct cal_block_data *cal_block, int cal_index) { int ret = 0; @@ -2804,6 +2951,44 @@ void afe_set_cal_mode(u16 port_id, enum afe_cal_mode afe_cal_mode) } EXPORT_SYMBOL(afe_set_cal_mode); +/** + * afe_set_vad_cfg - + * set configuration for VAD + * + * @port_id: AFE port id number + * @vad_enable: enable/disable vad + * @preroll_config: Preroll configuration + * + */ +void afe_set_vad_cfg(u32 vad_enable, u32 preroll_config, + u32 port_id) +{ + uint16_t port_index; + + port_index = afe_get_port_index(port_id); + this_afe.vad_cfg[port_index].is_enable = vad_enable; + this_afe.vad_cfg[port_index].pre_roll = preroll_config; +} +EXPORT_SYMBOL(afe_set_vad_cfg); + +/** + * afe_set_island_mode_cfg - + * set island mode configuration + * + * @port_id: AFE port id number + * @enable_flag: Enable or Disable + * + */ +void afe_set_island_mode_cfg(u16 port_id, u32 enable_flag) +{ + uint16_t port_index; + + port_index = afe_get_port_index(port_id); + this_afe.island_mode[port_index] = enable_flag; + +} +EXPORT_SYMBOL(afe_set_island_mode_cfg); + /** * afe_set_routing_callback - * Update callback function for routing @@ -3245,8 +3430,21 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, } mutex_lock(&this_afe.afe_cmd_lock); - /* Also send the topology id here: */ port_index = afe_get_port_index(port_id); + + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) { + /* send VAD configuration if is enabled */ + if (this_afe.vad_cfg[port_index].is_enable) { + ret = afe_send_port_vad_cfg_params(port_id); + if (ret) + pr_err("%s: afe send VAD config failed %d\n", + __func__, ret); + goto fail_cmd; + } + } + + /* Also send the topology id here: */ if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) { /* One time call: only for first time */ afe_send_custom_topology(); @@ -7354,6 +7552,9 @@ int __init afe_init(void) this_afe.afe_cal_mode[i] = AFE_CAL_MODE_DEFAULT; this_afe.afe_sample_rates[i] = 0; this_afe.dev_acdb_id[i] = 0; + this_afe.island_mode[i] = 0; + this_afe.vad_cfg[i].is_enable = 0; + this_afe.vad_cfg[i].pre_roll = 0; init_waitqueue_head(&this_afe.wait[i]); } wakeup_source_init(&wl.ws, "spkr-prot"); @@ -7394,3 +7595,29 @@ void afe_exit(void) mutex_destroy(&this_afe.afe_cmd_lock); wakeup_source_trash(&wl.ws); } + +/* + * afe_cal_init_hwdep - + * Initiliaze AFE HW dependent Node + * + * @card: pointer to sound card + * + */ +int afe_cal_init_hwdep(void *card) +{ + int ret = 0; + + this_afe.fw_data = kzalloc(sizeof(*(this_afe.fw_data)), + GFP_KERNEL); + if (!this_afe.fw_data) + return -ENOMEM; + + set_bit(Q6AFE_VAD_CORE_CAL, this_afe.fw_data->cal_bit); + ret = q6afe_cal_create_hwdep(this_afe.fw_data, Q6AFE_HWDEP_NODE, card); + if (ret < 0) { + pr_err("%s: couldn't create hwdep for AFE %d\n", __func__, ret); + return ret; + } + return ret; +} +EXPORT_SYMBOL(afe_cal_init_hwdep); diff --git a/dsp/q6afecal-hwdep.c b/dsp/q6afecal-hwdep.c new file mode 100644 index 000000000000..5fea2d27a40f --- /dev/null +++ b/dsp/q6afecal-hwdep.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2015, 2017 - 2018 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include "q6afecal-hwdep.h" + +const int cal_size_info[Q6AFE_MAX_CAL] = { + [Q6AFE_VAD_CORE_CAL] = 132, +}; + +const char *cal_name_info[Q6AFE_MAX_CAL] = { + [Q6AFE_VAD_CORE_CAL] = "vad_core", +}; + +#define AFE_HW_NAME_LENGTH 40 + +/* + * q6afecal_get_fw_cal - + * To get calibration from AFE HW dependent node + * + * @fw_data: pointer to firmware data + * type: AFE calibration type + * + */ +struct firmware_cal *q6afecal_get_fw_cal(struct afe_fw_info *fw_data, + enum q6afe_cal_type type) +{ + if (!fw_data) { + pr_err("%s: fw_data is NULL\n", __func__); + return NULL; + } + if (type >= Q6AFE_MAX_CAL || + type < Q6AFE_MIN_CAL) { + pr_err("%s: wrong cal type sent %d\n", __func__, type); + return NULL; + } + mutex_lock(&fw_data->lock); + if (!test_bit(Q6AFECAL_RECEIVED, + &fw_data->q6afecal_state[type])) { + pr_err("%s: cal not sent by userspace %d\n", + __func__, type); + mutex_unlock(&fw_data->lock); + return NULL; + } + set_bit(Q6AFECAL_INITIALISED, &fw_data->q6afecal_state[type]); + mutex_unlock(&fw_data->lock); + return fw_data->fw[type]; +} +EXPORT_SYMBOL(q6afecal_get_fw_cal); + +static int q6afecal_hwdep_ioctl_shared(struct snd_hwdep *hw, + struct q6afecal_ioctl_buffer fw_user) +{ + struct afe_fw_info *fw_data = hw->private_data; + struct firmware_cal **fw = fw_data->fw; + void *data; + + if (!test_bit(fw_user.cal_type, fw_data->cal_bit)) { + pr_err("%s: q6afe didn't set this %d!!\n", + __func__, fw_user.cal_type); + return -EFAULT; + } + if (fw_user.cal_type >= Q6AFE_MAX_CAL || + fw_user.cal_type < Q6AFE_MIN_CAL) { + pr_err("%s: wrong cal type sent %d\n", + __func__, fw_user.cal_type); + return -EFAULT; + } + if (fw_user.size > cal_size_info[fw_user.cal_type] || + fw_user.size <= 0) { + pr_err("%s: incorrect firmware size %d for %s\n", + __func__, fw_user.size, + cal_name_info[fw_user.cal_type]); + return -EFAULT; + } + data = fw[fw_user.cal_type]->data; + if (copy_from_user(data, fw_user.buffer, fw_user.size)) + return -EFAULT; + fw[fw_user.cal_type]->size = fw_user.size; + mutex_lock(&fw_data->lock); + set_bit(Q6AFECAL_RECEIVED, &fw_data->q6afecal_state[fw_user.cal_type]); + mutex_unlock(&fw_data->lock); + return 0; +} + +#ifdef CONFIG_COMPAT +struct q6afecal_ioctl_buffer32 { + u32 size; + compat_uptr_t buffer; + enum q6afe_cal_type cal_type; +}; + +enum { + SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE32 = + _IOW('U', 0x1, struct q6afecal_ioctl_buffer32), +}; + +static int q6afecal_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6afecal_ioctl_buffer __user *argp = (void __user *)arg; + struct q6afecal_ioctl_buffer32 fw_user32; + struct q6afecal_ioctl_buffer fw_user_compat; + + if (cmd != SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE32) { + pr_err("%s: wrong ioctl command sent %u!\n", __func__, cmd); + return -ENOIOCTLCMD; + } + if (copy_from_user(&fw_user32, argp, sizeof(fw_user32))) { + pr_err("%s: failed to copy\n", __func__); + return -EFAULT; + } + fw_user_compat.size = fw_user32.size; + fw_user_compat.buffer = compat_ptr(fw_user32.buffer); + fw_user_compat.cal_type = fw_user32.cal_type; + return q6afecal_hwdep_ioctl_shared(hw, fw_user_compat); +} +#else +#define q6afecal_hwdep_ioctl_compat NULL +#endif + +static int q6afecal_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct q6afecal_ioctl_buffer __user *argp = (void __user *)arg; + struct q6afecal_ioctl_buffer fw_user; + + if (cmd != SNDRV_IOCTL_HWDEP_VAD_CAL_TYPE) { + pr_err("%s: wrong ioctl command sent %d!\n", __func__, cmd); + return -ENOIOCTLCMD; + } + if (copy_from_user(&fw_user, argp, sizeof(fw_user))) { + pr_err("%s: failed to copy\n", __func__); + return -EFAULT; + } + return q6afecal_hwdep_ioctl_shared(hw, fw_user); +} + +static int q6afecal_hwdep_release(struct snd_hwdep *hw, struct file *file) +{ + struct afe_fw_info *fw_data = hw->private_data; + + mutex_lock(&fw_data->lock); + /* clear all the calibrations */ + memset(fw_data->q6afecal_state, 0, + sizeof(fw_data->q6afecal_state)); + mutex_unlock(&fw_data->lock); + return 0; +} + +/** + * q6afe_cal_create_hwdep - + * for creating HW dependent node for AFE + * + * @data: Pointer to hold fw data + * @node: node type + * @card: Pointer to sound card + * + */ +int q6afe_cal_create_hwdep(void *data, int node, void *card) +{ + char hwname[AFE_HW_NAME_LENGTH]; + struct snd_hwdep *hwdep; + struct firmware_cal **fw; + struct afe_fw_info *fw_data = data; + int err, cal_bit; + + if (!fw_data || !card) { + pr_err("%s: Invalid parameters\n", __func__); + return -EINVAL; + } + + fw = fw_data->fw; + snprintf(hwname, strlen("Q6AFE"), "Q6AFE"); + err = snd_hwdep_new(((struct snd_soc_card *)card)->snd_card, + hwname, node, &hwdep); + if (err < 0) { + pr_err("%s: new hwdep for q6afe failed %d\n", __func__, err); + return err; + } + snprintf(hwdep->name, strlen("Q6AFECAL"), "Q6AFECAL"); + hwdep->iface = SNDRV_HWDEP_IFACE_AUDIO_BE; + hwdep->private_data = fw_data; + hwdep->ops.ioctl_compat = q6afecal_hwdep_ioctl_compat; + hwdep->ops.ioctl = q6afecal_hwdep_ioctl; + hwdep->ops.release = q6afecal_hwdep_release; + mutex_init(&fw_data->lock); + + for_each_set_bit(cal_bit, fw_data->cal_bit, Q6AFE_MAX_CAL) { + set_bit(Q6AFECAL_UNINITIALISED, + &fw_data->q6afecal_state[cal_bit]); + fw[cal_bit] = kzalloc(sizeof *(fw[cal_bit]), GFP_KERNEL); + if (!fw[cal_bit]) { + pr_err("%s: no memory for %s cal\n", + __func__, cal_name_info[cal_bit]); + goto end; + } + } + for_each_set_bit(cal_bit, fw_data->cal_bit, Q6AFE_MAX_CAL) { + fw[cal_bit]->data = kzalloc(cal_size_info[cal_bit], + GFP_KERNEL); + if (!fw[cal_bit]->data) + goto exit; + set_bit(Q6AFECAL_INITIALISED, + &fw_data->q6afecal_state[cal_bit]); + } + return 0; +exit: + for_each_set_bit(cal_bit, fw_data->cal_bit, Q6AFE_MAX_CAL) { + kfree(fw[cal_bit]->data); + fw[cal_bit]->data = NULL; + } +end: + for_each_set_bit(cal_bit, fw_data->cal_bit, Q6AFE_MAX_CAL) { + kfree(fw[cal_bit]); + fw[cal_bit] = NULL; + } + return -ENOMEM; +} +EXPORT_SYMBOL(q6afe_cal_create_hwdep); diff --git a/dsp/q6afecal-hwdep.h b/dsp/q6afecal-hwdep.h new file mode 100644 index 000000000000..7e6efdac57f4 --- /dev/null +++ b/dsp/q6afecal-hwdep.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014,2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __Q6AFECAL_HWDEP_H__ +#define __Q6AFECAL_HWDEP_H__ +#include + +enum q6afe_cal_states { + Q6AFECAL_UNINITIALISED, + Q6AFECAL_INITIALISED, + Q6AFECAL_RECEIVED +}; + +struct afe_fw_info { + struct firmware_cal *fw[Q6AFE_MAX_CAL]; + DECLARE_BITMAP(cal_bit, Q6AFE_MAX_CAL); + /* for calibration tracking */ + unsigned long q6afecal_state[Q6AFE_MAX_CAL]; + struct mutex lock; +}; + +struct firmware_cal { + u8 *data; + size_t size; +}; + +#if IS_ENABLED(CONFIG_AFE_HWDEP) +int q6afe_cal_create_hwdep(void *fw, int node, void *card); +struct firmware_cal *q6afecal_get_fw_cal(struct afe_fw_info *fw_data, + enum q6afe_cal_type type); +#else /* CONFIG_AFE_HWDEP */ +static inline int q6afe_cal_create_hwdep(void *fw, int node, void *card) +{ + return 0; +} + +static inline struct firmware_cal *q6afecal_get_fw_cal( + struct afe_fw_info *fw_data, + enum q6afe_cal_type type) +{ + return NULL; +} +#endif /* CONFIG_AFE_HWDEP */ +#endif /* __Q6AFECAL_HWDEP_H__ */ diff --git a/dsp/q6core.c b/dsp/q6core.c index 9b0b588fdda1..d8fdb4c2a450 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -513,10 +513,9 @@ int q6core_get_service_version(uint32_t service_id, } EXPORT_SYMBOL(q6core_get_service_version); -size_t q6core_get_fwk_version_size(uint32_t service_id) +static int q6core_get_avcs_fwk_version(void) { int ret = 0; - uint32_t num_services; mutex_lock(&(q6core_lcl.ver_lock)); pr_debug("%s: q6core_avcs_ver_info.status(%d)\n", __func__, @@ -547,7 +546,15 @@ size_t q6core_get_fwk_version_size(uint32_t service_id) break; } mutex_unlock(&(q6core_lcl.ver_lock)); + return ret; +} + +size_t q6core_get_fwk_version_size(uint32_t service_id) +{ + int ret = 0; + uint32_t num_services; + ret = q6core_get_avcs_fwk_version(); if (ret) goto done; @@ -570,6 +577,42 @@ size_t q6core_get_fwk_version_size(uint32_t service_id) } EXPORT_SYMBOL(q6core_get_fwk_version_size); +/** + * q6core_get_avcs_version_per_service - + * to get api version of a particular service + * + * @service_id: id of the service + * + * Returns valid version on success or error (negative value) on failure + */ +int q6core_get_avcs_api_version_per_service(uint32_t service_id) +{ + struct avcs_fwk_ver_info *cached_ver_info = NULL; + int i; + uint32_t num_services; + int ret = 0; + + if (service_id == AVCS_SERVICE_ID_ALL) + return -EINVAL; + + ret = q6core_get_avcs_fwk_version(); + if (ret < 0) { + pr_err("%s: failure in getting AVCS version\n", __func__); + return ret; + } + + cached_ver_info = q6core_lcl.q6core_avcs_ver_info.ver_info; + num_services = cached_ver_info->avcs_fwk_version.num_services; + + for (i = 0; i < num_services; i++) { + if (cached_ver_info->services[i].service_id == service_id) + return cached_ver_info->services[i].api_version; + } + pr_err("%s: No service matching service ID %d\n", __func__, service_id); + return -EINVAL; +} +EXPORT_SYMBOL(q6core_get_avcs_api_version_per_service); + /** * core_set_license - * command to set license for module diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 5a5fb6f57bd9..4f03c17d1d94 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -3941,6 +3941,32 @@ struct avs_dec_depacketizer_id_param_t { uint32_t dec_depacketizer_id; }; +/* ID of the parameter used by #AFE_MODULE_AUDIO_DEV_INTERFACE to configure + * the island mode for a given AFE port. + */ +#define AFE_PARAM_ID_ISLAND_CONFIG 0x000102B4 + +/* Version information used to handle future additions to codec DMA + * configuration (for backward compatibility). + */ +#define AFE_API_VERSION_ISLAND_CONFIG 0x1 + +/* Payload of the AFE_PARAM_ID_ISLAND_CONFIG parameter used by + * AFE_MODULE_AUDIO_DEV_INTERFACE. + */ +struct afe_param_id_island_cfg_t { + uint32_t island_cfg_minor_version; + /* Tracks the configuration of this parameter. + * Supported values: #AFE_API_VERSION_ISLAND_CONFIG + */ + + uint32_t island_enable; + /* Specifies whether island mode should be enabled or disabled for the + * use-case being setup. + * Supported values: 0 - Disable, 1 - Enable + */ +} __packed; + /* ID of the parameter used by #AFE_MODULE_AUDIO_DEV_INTERFACE to configure * the Codec DMA interface. */ @@ -9814,6 +9840,7 @@ struct asm_aptx_dec_fmt_blk_v2 { #define AVCS_SERVICE_ID_ALL (0xFFFFFFFF) #define APRV2_IDS_SERVICE_ID_ADSP_CVP_V (0xB) +#define APRV2_IDS_SERVICE_ID_ADSP_AFE_V (0x4) struct avcs_get_fwk_version { /* @@ -11265,4 +11292,32 @@ struct admx_sec_primary_mic_ch { uint16_t reserved1; } __packed; +/** ID of the Voice Activity Detection (VAD) module, which is used to + * configure AFE VAD. + */ +#define AFE_MODULE_VAD 0x000102B9 + +/** ID of the parameter used by #AFE_MODULE_VAD to configure the VAD. + */ +#define AFE_PARAM_ID_VAD_CFG 0x000102BA + +#define AFE_API_VERSION_VAD_CFG 0x1 + +/* Payload of the AFE_PARAM_ID_VAD_CONFIG parameter used by + * AFE_MODULE_VAD. + */ +struct afe_param_id_vad_cfg_t { + uint32_t vad_cfg_minor_version; + /** Tracks the configuration of this parameter. + * Supported Values: #AFE_API_VERSION_VAD_CFG + */ + + uint32_t pre_roll_in_ms; + /** Pre-roll period in ms. + * Supported Values: 0x0 to 0x3E8 + */ +} __packed; + +#define AFE_PARAM_ID_VAD_CORE_CFG 0x000102BB + #endif /*_APR_AUDIO_V2_H_ */ diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index b420ef333b56..e3ec1bc971fa 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -41,7 +41,12 @@ #define AFE_CLK_VERSION_V1 1 #define AFE_CLK_VERSION_V2 2 + #define AFE_API_VERSION_SUPPORT_SPV3 2 +#define AFE_API_VERSION_V3 3 +/* for VAD and Island mode */ +#define AFE_API_VERSION_V4 4 + typedef int (*routing_cb)(int port); enum { @@ -248,6 +253,16 @@ enum afe_cal_mode { AFE_CAL_MODE_NONE, }; +enum afe_vad_cfg_type { + AFE_VAD_ENABLE = 0x00, + AFE_VAD_PREROLL, +}; + +struct vad_config { + u32 is_enable; + u32 pre_roll; +}; + struct afe_audio_buffer { dma_addr_t phys; void *data; @@ -323,6 +338,9 @@ int afe_rt_proxy_port_write(phys_addr_t buf_addr_p, int afe_rt_proxy_port_read(phys_addr_t buf_addr_p, u32 mem_map_handle, int bytes); void afe_set_cal_mode(u16 port_id, enum afe_cal_mode afe_cal_mode); +void afe_set_vad_cfg(u32 vad_enable, u32 preroll_config, + u32 port_id); +void afe_set_island_mode_cfg(u16 port_id, u32 enable_flag); int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate); int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, @@ -396,4 +414,6 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, void afe_set_routing_callback(routing_cb cb); int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats, u16 port); +int afe_cal_init_hwdep(void *card); +int afe_send_port_island_mode(u16 port_id); #endif /* __Q6AFE_V2_H__ */ diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index 03a7b31af52d..a4706a6d956d 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -35,6 +35,7 @@ struct audio_uevent_data { int q6core_init_uevent_data(struct audio_uevent_data *uevent_data, char *name); void q6core_destroy_uevent_data(struct audio_uevent_data *uevent_data); int q6core_send_uevent(struct audio_uevent_data *uevent_data, char *name); +int q6core_get_avcs_api_version_per_service(uint32_t service_id); #define ADSP_CMD_SET_DTS_EAGLE_DATA_ID 0x00012919 #define DTS_EAGLE_LICENSE_ID 0x00028346 diff --git a/include/uapi/sound/msmcal-hwdep.h b/include/uapi/sound/msmcal-hwdep.h index 2f6d37ad0a10..f2891863fa47 100644 --- a/include/uapi/sound/msmcal-hwdep.h +++ b/include/uapi/sound/msmcal-hwdep.h @@ -3,6 +3,7 @@ #define WCD9XXX_CODEC_HWDEP_NODE 1000 #define AQT1000_CODEC_HWDEP_NODE 1001 +#define Q6AFE_HWDEP_NODE 1002 enum wcd_cal_type { WCD9XXX_MIN_CAL, WCD9XXX_ANC_CAL = WCD9XXX_MIN_CAL, @@ -21,4 +22,19 @@ struct wcdcal_ioctl_buffer { #define SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE \ _IOW('U', 0x1, struct wcdcal_ioctl_buffer) +enum q6afe_cal_type { + Q6AFE_MIN_CAL, + Q6AFE_VAD_CORE_CAL = Q6AFE_MIN_CAL, + Q6AFE_MAX_CAL, +}; + +struct q6afecal_ioctl_buffer { + __u32 size; + __u8 __user *buffer; + enum q6afe_cal_type cal_type; +}; + +#define SNDRV_IOCTL_HWDEP_VAD_CAL_TYPE \ + _IOW('U', 0x1, struct q6afecal_ioctl_buffer) + #endif /*_CALIB_HWDEP_H*/ -- GitLab From 0c794ae9f46277c3dfa663df1624de6443353912 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Thu, 26 Apr 2018 22:09:53 +0530 Subject: [PATCH 0317/1645] asoc: Add support for VAD in DAI driver Update DAI driver to include VAD configuration related mixer controls for the supported DAIs. Change-Id: I7c1ff9a30c3afcf9bb66e40283e6909631df9aa6 Signed-off-by: Mangesh Kunchamwar --- asoc/msm-dai-q6-v2.c | 208 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 206 insertions(+), 2 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 7a3dd4e57afa..3b259bc389ed 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "msm-dai-q6-v2.h" #include "codecs/core.h" @@ -44,6 +45,8 @@ SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE) +static int msm_mi2s_get_port_id(u32 mi2s_id, int stream, u16 *port_id); + enum { ENC_FMT_NONE, DEC_FMT_NONE = ENC_FMT_NONE, @@ -202,6 +205,7 @@ struct msm_dai_q6_dai_data { u16 afe_in_bitformat; struct afe_enc_config enc_config; struct afe_dec_config dec_config; + u32 island_enable; union afe_port_config port_config; u16 vi_feed_mono; }; @@ -220,6 +224,7 @@ struct msm_dai_q6_mi2s_dai_config { }; struct msm_dai_q6_mi2s_dai_data { + u32 is_island_dai; struct msm_dai_q6_mi2s_dai_config tx_dai; struct msm_dai_q6_mi2s_dai_config rx_dai; }; @@ -230,6 +235,7 @@ struct msm_dai_q6_cdc_dma_dai_data { u32 rate; u32 channels; u32 bitwidth; + u32 is_island_dai; union afe_port_config port_config; }; @@ -240,6 +246,7 @@ struct msm_dai_q6_auxpcm_dai_data { u16 rx_pid; /* AUXPCM RX AFE port ID */ u16 tx_pid; /* AUXPCM TX AFE port ID */ u16 afe_clk_ver; + u32 is_island_dai; struct afe_clk_cfg clk_cfg; /* hold LPASS clock configuration */ struct afe_clk_set clk_set; /* hold LPASS clock configuration */ struct msm_dai_q6_dai_data bdai_data; /* incoporate base DAI data */ @@ -251,6 +258,7 @@ struct msm_dai_q6_tdm_dai_data { u32 channels; u32 bitwidth; u32 num_group_ports; + u32 is_island_dai; struct afe_clk_set clk_set; /* hold LPASS clock config. */ union afe_port_group_config group_cfg; /* hold tdm group config */ struct afe_tdm_port_config port_cfg; /* hold tdm config */ @@ -1038,6 +1046,17 @@ static int msm_dai_q6_auxpcm_prepare(struct snd_pcm_substream *substream, } afe_open(aux_dai_data->rx_pid, &dai_data->port_config, dai_data->rate); + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) { + /* + * send island mode config + * This should be the first configuration + */ + rc = afe_send_port_island_mode(aux_dai_data->tx_pid); + if (rc) + dev_err(dai->dev, "%s: afe send island mode failed %d\n", + __func__, rc); + } afe_open(aux_dai_data->tx_pid, &dai_data->port_config, dai_data->rate); goto exit; @@ -1108,9 +1127,78 @@ static int msm_dai_q6_dai_auxpcm_remove(struct snd_soc_dai *dai) return 0; } + +static int msm_dai_q6_island_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + int value = ucontrol->value.integer.value[0]; + u16 port_id = ((struct soc_enum *) kcontrol->private_value)->reg; + + dai_data->island_enable = value; + pr_debug("%s: island mode = %d\n", __func__, value); + + afe_set_island_mode_cfg(port_id, dai_data->island_enable); + return 0; +} + +static int msm_dai_q6_island_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + ucontrol->value.integer.value[0] = dai_data->island_enable; + return 0; +} + +static struct snd_kcontrol_new island_config_controls[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .get = msm_dai_q6_island_mode_get, + .put = msm_dai_q6_island_mode_put, + .private_value = SOC_SINGLE_VALUE(0, 0, 1, 0, 0) + }, +}; + +static int msm_dai_q6_add_island_mx_ctls(struct snd_card *card, + const char *dai_name, + int dai_id, void *dai_data) +{ + const char *mx_ctl_name = "TX island"; + char *mixer_str = NULL; + int dai_str_len = 0, ctl_len = 0; + int rc = 0; + + dai_str_len = strlen(dai_name) + 1; + + /* Add island related mixer controls */ + ctl_len = dai_str_len + strlen(mx_ctl_name) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + if (!mixer_str) + return -ENOMEM; + + snprintf(mixer_str, ctl_len + strlen(mx_ctl_name) + 1, + "%s %s", dai_name, mx_ctl_name); + island_config_controls[0].name = mixer_str; + ((struct soc_enum *) island_config_controls[0].private_value)->reg + = dai_id; + rc = snd_ctl_add(card, + snd_ctl_new1(&island_config_controls[0], + dai_data)); + if (rc < 0) + pr_err("%s: err add config ctl, DAI = %s\n", + __func__, dai_name); + kfree(mixer_str); + + return rc; +} + + static int msm_dai_q6_aux_pcm_probe(struct snd_soc_dai *dai) { int rc = 0; + struct msm_dai_q6_auxpcm_dai_data *dai_data = NULL; if (!dai) { pr_err("%s: Invalid params dai\n", __func__); @@ -1125,6 +1213,14 @@ static int msm_dai_q6_aux_pcm_probe(struct snd_soc_dai *dai) return -EINVAL; } dai->id = dai->driver->id; + dai_data = dev_get_drvdata(dai->dev); + + if (dai_data->is_island_dai) + rc = msm_dai_q6_add_island_mx_ctls( + dai->component->card->snd_card, + dai->name, dai_data->tx_pid, + (void *)dai_data); + rc = msm_dai_q6_dai_add_route(dai); return rc; } @@ -1164,6 +1260,7 @@ static struct snd_soc_dai_driver msm_dai_q6_aux_pcm_dai[] = { .rate_min = 8000, }, .id = MSM_DAI_PRI_AUXPCM_DT_DEV_ID, + .name = "Pri AUX PCM", .ops = &msm_dai_q6_auxpcm_ops, .probe = msm_dai_q6_aux_pcm_probe, .remove = msm_dai_q6_dai_auxpcm_remove, @@ -1190,6 +1287,7 @@ static struct snd_soc_dai_driver msm_dai_q6_aux_pcm_dai[] = { .rate_min = 8000, }, .id = MSM_DAI_SEC_AUXPCM_DT_DEV_ID, + .name = "Sec AUX PCM", .ops = &msm_dai_q6_auxpcm_ops, .probe = msm_dai_q6_aux_pcm_probe, .remove = msm_dai_q6_dai_auxpcm_remove, @@ -1216,6 +1314,7 @@ static struct snd_soc_dai_driver msm_dai_q6_aux_pcm_dai[] = { .rate_min = 8000, }, .id = MSM_DAI_TERT_AUXPCM_DT_DEV_ID, + .name = "Tert AUX PCM", .ops = &msm_dai_q6_auxpcm_ops, .probe = msm_dai_q6_aux_pcm_probe, .remove = msm_dai_q6_dai_auxpcm_remove, @@ -1242,6 +1341,7 @@ static struct snd_soc_dai_driver msm_dai_q6_aux_pcm_dai[] = { .rate_min = 8000, }, .id = MSM_DAI_QUAT_AUXPCM_DT_DEV_ID, + .name = "Quat AUX PCM", .ops = &msm_dai_q6_auxpcm_ops, .probe = msm_dai_q6_aux_pcm_probe, .remove = msm_dai_q6_dai_auxpcm_remove, @@ -1268,6 +1368,7 @@ static struct snd_soc_dai_driver msm_dai_q6_aux_pcm_dai[] = { .rate_min = 8000, }, .id = MSM_DAI_QUIN_AUXPCM_DT_DEV_ID, + .name = "Quin AUX PCM", .ops = &msm_dai_q6_auxpcm_ops, .probe = msm_dai_q6_aux_pcm_probe, .remove = msm_dai_q6_dai_auxpcm_remove, @@ -3176,6 +3277,12 @@ static int msm_auxpcm_dev_probe(struct platform_device *pdev) if (!dai_data) return -ENOMEM; + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-dai-is-island-supported", + &dai_data->is_island_dai); + if (rc) + dev_dbg(&pdev->dev, "island supported entry not found\n"); + auxpcm_pdata = kzalloc(sizeof(struct msm_dai_auxpcm_pdata), GFP_KERNEL); @@ -3870,6 +3977,7 @@ static int msm_dai_q6_dai_mi2s_probe(struct snd_soc_dai *dai) int rc = 0; const struct snd_kcontrol_new *ctrl = NULL; const struct snd_kcontrol_new *vi_feed_ctrl = NULL; + u16 dai_id = 0; dai->id = mi2s_pdata->intf_id; @@ -3942,6 +4050,15 @@ static int msm_dai_q6_dai_mi2s_probe(struct snd_soc_dai *dai) } } + if (mi2s_dai_data->is_island_dai) { + msm_mi2s_get_port_id(dai->id, SNDRV_PCM_STREAM_CAPTURE, + &dai_id); + rc = msm_dai_q6_add_island_mx_ctls( + dai->component->card->snd_card, + dai->name, dai_id, + (void *)mi2s_dai_data); + } + rc = msm_dai_q6_dai_add_route(dai); rtn: return rc; @@ -3981,7 +4098,6 @@ static int msm_dai_q6_mi2s_startup(struct snd_pcm_substream *substream, return 0; } - static int msm_mi2s_get_port_id(u32 mi2s_id, int stream, u16 *port_id) { int ret = 0; @@ -4115,6 +4231,18 @@ static int msm_dai_q6_mi2s_prepare(struct snd_pcm_substream *substream, dai->id, port_id, dai_data->channels, dai_data->rate); if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) { + /* + * send island mode config. + * This should be the first configuration + */ + rc = afe_send_port_island_mode(port_id); + if (rc) + dev_err(dai->dev, "%s: afe send island mode failed %d\n", + __func__, rc); + } + /* PORT START should be set if prepare called * in active state. */ @@ -4392,6 +4520,7 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .rate_max = 192000, }, .ops = &msm_dai_q6_mi2s_ops, + .name = "Primary MI2S", .id = MSM_PRIM_MI2S, .probe = msm_dai_q6_dai_mi2s_probe, .remove = msm_dai_q6_dai_mi2s_remove, @@ -4422,6 +4551,7 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .rate_max = 192000, }, .ops = &msm_dai_q6_mi2s_ops, + .name = "Secondary MI2S", .id = MSM_SEC_MI2S, .probe = msm_dai_q6_dai_mi2s_probe, .remove = msm_dai_q6_dai_mi2s_remove, @@ -4452,6 +4582,7 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .rate_max = 192000, }, .ops = &msm_dai_q6_mi2s_ops, + .name = "Tertiary MI2S", .id = MSM_TERT_MI2S, .probe = msm_dai_q6_dai_mi2s_probe, .remove = msm_dai_q6_dai_mi2s_remove, @@ -4482,6 +4613,7 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .rate_max = 192000, }, .ops = &msm_dai_q6_mi2s_ops, + .name = "Quaternary MI2S", .id = MSM_QUAT_MI2S, .probe = msm_dai_q6_dai_mi2s_probe, .remove = msm_dai_q6_dai_mi2s_remove, @@ -4507,6 +4639,7 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .rate_max = 48000, }, .ops = &msm_dai_q6_mi2s_ops, + .name = "Quinary MI2S", .id = MSM_QUIN_MI2S, .probe = msm_dai_q6_dai_mi2s_probe, .remove = msm_dai_q6_dai_mi2s_remove, @@ -4534,6 +4667,7 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .rate_max = 48000, }, .ops = &msm_dai_q6_mi2s_ops, + .name = "Senary MI2S", .id = MSM_SENARY_MI2S, .probe = msm_dai_q6_dai_mi2s_probe, .remove = msm_dai_q6_dai_mi2s_remove, @@ -4561,6 +4695,7 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .rate_max = 48000, }, .ops = &msm_dai_q6_mi2s_ops, + .name = "INT0 MI2S", .id = MSM_INT0_MI2S, .probe = msm_dai_q6_dai_mi2s_probe, .remove = msm_dai_q6_dai_mi2s_remove, @@ -4587,6 +4722,7 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .rate_max = 48000, }, .ops = &msm_dai_q6_mi2s_ops, + .name = "INT1 MI2S", .id = MSM_INT1_MI2S, .probe = msm_dai_q6_dai_mi2s_probe, .remove = msm_dai_q6_dai_mi2s_remove, @@ -4613,6 +4749,7 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .rate_max = 48000, }, .ops = &msm_dai_q6_mi2s_ops, + .name = "INT2 MI2S", .id = MSM_INT2_MI2S, .probe = msm_dai_q6_dai_mi2s_probe, .remove = msm_dai_q6_dai_mi2s_remove, @@ -4639,6 +4776,7 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .rate_max = 48000, }, .ops = &msm_dai_q6_mi2s_ops, + .name = "INT3 MI2S", .id = MSM_INT3_MI2S, .probe = msm_dai_q6_dai_mi2s_probe, .remove = msm_dai_q6_dai_mi2s_remove, @@ -4666,6 +4804,7 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .rate_max = 48000, }, .ops = &msm_dai_q6_mi2s_ops, + .name = "INT4 MI2S", .id = MSM_INT4_MI2S, .probe = msm_dai_q6_dai_mi2s_probe, .remove = msm_dai_q6_dai_mi2s_remove, @@ -4692,6 +4831,7 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .rate_max = 48000, }, .ops = &msm_dai_q6_mi2s_ops, + .name = "INT5 MI2S", .id = MSM_INT5_MI2S, .probe = msm_dai_q6_dai_mi2s_probe, .remove = msm_dai_q6_dai_mi2s_remove, @@ -4718,6 +4858,7 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .rate_max = 48000, }, .ops = &msm_dai_q6_mi2s_ops, + .name = "INT6 MI2S", .id = MSM_INT6_MI2S, .probe = msm_dai_q6_dai_mi2s_probe, .remove = msm_dai_q6_dai_mi2s_remove, @@ -4933,6 +5074,12 @@ static int msm_dai_q6_mi2s_dev_probe(struct platform_device *pdev) } else dev_set_drvdata(&pdev->dev, dai_data); + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-dai-is-island-supported", + &dai_data->is_island_dai); + if (rc) + dev_dbg(&pdev->dev, "island supported entry not found\n"); + pdev->dev.platform_data = mi2s_pdata; rc = msm_dai_q6_mi2s_platform_data_validation(pdev, @@ -6551,6 +6698,12 @@ static int msm_dai_q6_dai_tdm_probe(struct snd_soc_dai *dai) } } + if (tdm_dai_data->is_island_dai) + rc = msm_dai_q6_add_island_mx_ctls( + dai->component->card->snd_card, + dai->name, + dai->id, (void *)tdm_dai_data); + rc = msm_dai_q6_dai_add_route(dai); rtn: @@ -7099,6 +7252,19 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream, group_ref = &tdm_group_ref[group_idx]; if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) { + /* + * send island mode config. + * This should be the first configuration + */ + rc = afe_send_port_island_mode(dai->id); + if (rc) + dev_err(dai->dev, "%s: afe send island mode failed %d\n", + __func__, rc); + + } + /* PORT START should be set if prepare called * in active state. */ @@ -8866,6 +9032,12 @@ static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev) } memset(dai_data, 0, sizeof(*dai_data)); + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-dai-is-island-supported", + &dai_data->is_island_dai); + if (rc) + dev_dbg(&pdev->dev, "island supported entry not found\n"); + /* TDM CFG */ tdm_parent_node = of_get_parent(pdev->dev.of_node); rc = of_property_read_u32(tdm_parent_node, @@ -9124,6 +9296,13 @@ static int msm_dai_q6_dai_cdc_dma_probe(struct snd_soc_dai *dai) if (rc < 0) dev_err(dai->dev, "%s: err add config ctl, DAI = %s\n", __func__, dai->name); + + if (dai_data->is_island_dai) + rc = msm_dai_q6_add_island_mx_ctls( + dai->component->card->snd_card, + dai->name, dai->id, + (void *)dai_data); + rc = msm_dai_q6_dai_add_route(dai); return rc; } @@ -9151,6 +9330,7 @@ static int msm_dai_q6_cdc_dma_set_channel_map(struct snd_soc_dai *dai, unsigned int rx_num_ch, unsigned int *rx_ch_mask) { + int rc = 0; struct msm_dai_q6_cdc_dma_dai_data *dai_data = dev_get_drvdata(dai->dev); unsigned int ch_mask = 0, ch_num = 0; @@ -9196,7 +9376,7 @@ static int msm_dai_q6_cdc_dma_set_channel_map(struct snd_soc_dai *dai, dai_data->port_config.cdc_dma.active_channels_mask = ch_mask; dev_dbg(dai->dev, "%s: CDC_DMA_%d_ch cnt[%d] ch mask[0x%x]\n", __func__, dai->id, ch_num, ch_mask); - return 0; + return rc; } static int msm_dai_q6_cdc_dma_hw_params( @@ -9247,6 +9427,17 @@ static int msm_dai_q6_cdc_dma_prepare(struct snd_pcm_substream *substream, int rc = 0; if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) { + /* + * send island mode config. + * This should be the first configuration + */ + rc = afe_send_port_island_mode(dai->id); + if (rc) + pr_err("%s: afe send island mode failed %d\n", + __func__, rc); + } rc = afe_port_start(dai->id, &dai_data->port_config, dai_data->rate); if (rc < 0) @@ -9311,6 +9502,7 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { .rate_min = 8000, .rate_max = 384000, }, + .name = "WSA_CDC_DMA_RX_0", .ops = &msm_dai_q6_cdc_dma_ops, .id = AFE_PORT_ID_WSA_CODEC_DMA_RX_0, .probe = msm_dai_q6_dai_cdc_dma_probe, @@ -9336,6 +9528,7 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { .rate_min = 8000, .rate_max = 384000, }, + .name = "WSA_CDC_DMA_TX_0", .ops = &msm_dai_q6_cdc_dma_ops, .id = AFE_PORT_ID_WSA_CODEC_DMA_TX_0, .probe = msm_dai_q6_dai_cdc_dma_probe, @@ -9361,6 +9554,7 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { .rate_min = 8000, .rate_max = 384000, }, + .name = "WSA_CDC_DMA_RX_1", .ops = &msm_dai_q6_cdc_dma_ops, .id = AFE_PORT_ID_WSA_CODEC_DMA_RX_1, .probe = msm_dai_q6_dai_cdc_dma_probe, @@ -9386,6 +9580,7 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { .rate_min = 8000, .rate_max = 384000, }, + .name = "WSA_CDC_DMA_TX_1", .ops = &msm_dai_q6_cdc_dma_ops, .id = AFE_PORT_ID_WSA_CODEC_DMA_TX_1, .probe = msm_dai_q6_dai_cdc_dma_probe, @@ -9411,6 +9606,7 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { .rate_min = 8000, .rate_max = 384000, }, + .name = "WSA_CDC_DMA_TX_2", .ops = &msm_dai_q6_cdc_dma_ops, .id = AFE_PORT_ID_WSA_CODEC_DMA_TX_2, .probe = msm_dai_q6_dai_cdc_dma_probe, @@ -9435,6 +9631,7 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { .rate_min = 8000, .rate_max = 384000, }, + .name = "VA_CDC_DMA_TX_0", .ops = &msm_dai_q6_cdc_dma_ops, .id = AFE_PORT_ID_VA_CODEC_DMA_TX_0, .probe = msm_dai_q6_dai_cdc_dma_probe, @@ -9459,6 +9656,7 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { .rate_min = 8000, .rate_max = 384000, }, + .name = "VA_CDC_DMA_TX_1", .ops = &msm_dai_q6_cdc_dma_ops, .id = AFE_PORT_ID_VA_CODEC_DMA_TX_1, .probe = msm_dai_q6_dai_cdc_dma_probe, @@ -9500,6 +9698,12 @@ static int msm_dai_q6_cdc_dma_dev_probe(struct platform_device *pdev) if (!dai_data) return -ENOMEM; + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-dai-is-island-supported", + &dai_data->is_island_dai); + if (rc) + dev_dbg(&pdev->dev, "island supported entry not found\n"); + dev_set_drvdata(&pdev->dev, dai_data); for (i = 0; i < ARRAY_SIZE(msm_dai_q6_cdc_dma_dai); i++) { -- GitLab From d4a064213fe0f56e25936a4996447d1313006c60 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Thu, 26 Apr 2018 17:38:41 +0530 Subject: [PATCH 0318/1645] asoc: qcs405: Add support for VAD in QCS405 machine driver Update QCS405 machine driver to create HW dependent node for AFE to hold VAD core calibration. Change-Id: Ied9c11af87df0fb2b419f1e4a9c1e5cc67d84c00 Signed-off-by: Mangesh Kunchamwar --- asoc/qcs405.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 2 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index f76e6af284c4..e1e13ebc1566 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -3218,6 +3218,8 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), SOC_ENUM_EXT("QUIN_AUX_PCM_TX Format", aux_pcm_tx_format, msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_SINGLE_MULTI_EXT("VAD CFG", SND_SOC_NOPM, 0, 1000, 0, 3, NULL, + msm_snd_vad_cfg_put), }; static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, @@ -3466,6 +3468,29 @@ static int msm_slim_get_ch_from_beid(int32_t be_id) return ch_id; } +static int msm_vad_get_portid_from_beid(int32_t be_id, int *port_id) +{ + *port_id = 0xFFFF; + + switch (be_id) { + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: + *port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0; + break; + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + *port_id = AFE_PORT_ID_QUINARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUIN_TDM_TX_0: + *port_id = AFE_PORT_ID_QUINARY_TDM_TX; + break; + case MSM_BACKEND_DAI_QUIN_AUXPCM_TX: + *port_id = AFE_PORT_ID_QUINARY_PCM_TX; + break; + default: + return -EINVAL; + } + return 0; +} + static int msm_cdc_dma_get_idx_from_beid(int32_t be_id) { int idx = 0; @@ -6652,10 +6677,72 @@ static int msm_snd_card_tasha_late_probe(struct snd_soc_card *card) return ret; } + +static int msm_snd_vad_cfg_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int port_id; + uint32_t vad_enable = ucontrol->value.integer.value[0]; + uint32_t preroll_config = ucontrol->value.integer.value[1]; + uint32_t vad_intf = ucontrol->value.integer.value[2]; + + if ((preroll_config < 0) || (preroll_config > 1000) || + (vad_enable < 0) || (vad_enable > 1) || + (vad_intf > MSM_BACKEND_DAI_MAX)) { + pr_err("%s: Invalid arguments\n", __func__); + ret = -EINVAL; + goto done; + } + + pr_debug("%s: vad_enable=%d preroll_config=%d vad_intf=%d\n", __func__, + vad_enable, preroll_config, vad_intf); + + ret = msm_vad_get_portid_from_beid(vad_intf, &port_id); + if (ret) { + pr_err("%s: Invalid vad interface\n", __func__); + goto done; + } + + afe_set_vad_cfg(vad_enable, preroll_config, port_id); + +done: + return ret; +} + +static int msm_snd_card_codec_late_probe(struct snd_soc_card *card) +{ + int ret = 0; + uint32_t tasha_codec = 0; + + ret = afe_cal_init_hwdep(card); + if (ret) { + dev_err(card->dev, "afe cal hwdep init failed (%d)\n", ret); + ret = 0; + } + + /* tasha late probe when it is present */ + ret = of_property_read_u32(card->dev->of_node, "qcom,tasha-codec", + &tasha_codec); + if (ret) { + dev_err(card->dev, "%s: No DT match tasha codec\n", __func__); + ret = 0; + } else { + if (tasha_codec) { + ret = msm_snd_card_tasha_late_probe(card); + if (ret) + dev_err(card->dev, "%s: tasha late probe err\n", + __func__); + } + } + return ret; +} + struct snd_soc_card snd_soc_card_qcs405_msm = { .name = "qcs405-snd-card", .controls = msm_snd_controls, .num_controls = ARRAY_SIZE(msm_snd_controls), + .late_probe = msm_snd_card_codec_late_probe, }; static int msm_populate_dai_link_component_of_node( @@ -6892,8 +6979,6 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) if (tasha_codec) { dev_dbg(dev, "%s(): Tasha codec is present\n", __func__); - card->late_probe = - msm_snd_card_tasha_late_probe; memcpy(msm_qcs405_dai_links + total_links, msm_tasha_fe_dai_links, sizeof(msm_tasha_fe_dai_links)); -- GitLab From 0bf1f57c5960ddf9650b136bb4a977f81c75109b Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Thu, 24 May 2018 19:58:42 +0530 Subject: [PATCH 0319/1645] asoc: config: configuration update for QCS405 machine driver Add configuration updates for enabling QCS405 machine driver Change-Id: I5a426730388aeafcdd6fb2e7c6d4cc7a0af78e1c Signed-off-by: Mangesh Kunchamwar --- asoc/Kbuild | 13 ++++++++++ asoc/codecs/Kbuild | 5 ++++ asoc/codecs/bolero/Kbuild | 5 ++++ config/qcs405auto.conf | 40 +++++++++++++++++++++++++++++ config/qcs405autoconf.h | 53 +++++++++++++++++++++++++++++++++++++++ dsp/Kbuild | 5 ++++ dsp/codecs/Kbuild | 5 ++++ ipc/Kbuild | 9 +++++++ soc/Kbuild | 5 ++++ 9 files changed, 140 insertions(+) create mode 100644 config/qcs405auto.conf create mode 100644 config/qcs405autoconf.h diff --git a/asoc/Kbuild b/asoc/Kbuild index 8c3791770220..0211013647e7 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -45,6 +45,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif + ifeq ($(CONFIG_ARCH_QCS405), y) + include $(AUDIO_ROOT)/config/qcs405auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h + endif endif # As per target team, build is done as follows: @@ -100,6 +105,11 @@ ifdef CONFIG_SND_SOC_SM8150 MACHINE_OBJS += sm8150.o endif +# for qcs405 sound card driver +ifdef CONFIG_SND_SOC_QCS405 + MACHINE_OBJS += qcs405.o +endif + ifdef CONFIG_SND_SOC_CPE CPE_LSM_OBJS += msm-cpe-lsm.o endif @@ -191,6 +201,9 @@ machine_dlkm-y := $(MACHINE_OBJS) obj-$(CONFIG_SND_SOC_SM8150) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) +obj-$(CONFIG_SND_SOC_QCS405) += machine_dlkm.o +machine_dlkm-y := $(MACHINE_OBJS) + obj-$(CONFIG_SND_SOC_EXT_CODEC) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 3596143286f9..84e4a47d4bb2 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -44,6 +44,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif + ifeq ($(CONFIG_ARCH_QCS405), y) + include $(AUDIO_ROOT)/config/qcs405auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild index cf996630982d..57f561a7e2ff 100644 --- a/asoc/codecs/bolero/Kbuild +++ b/asoc/codecs/bolero/Kbuild @@ -21,6 +21,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_QCS405), y) + include $(AUDIO_ROOT)/config/qcs405auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/config/qcs405auto.conf b/config/qcs405auto.conf new file mode 100644 index 000000000000..127311dbb441 --- /dev/null +++ b/config/qcs405auto.conf @@ -0,0 +1,40 @@ +CONFIG_PINCTRL_WCD=m +CONFIG_PINCTRL_LPI=m +CONFIG_AUDIO_EXT_CLK=m +CONFIG_SND_SOC_WCD9XXX_V2=m +CONFIG_SND_SOC_WSA881X=m +CONFIG_SND_SOC_WCD_DSP_MGR=m +CONFIG_SOUNDWIRE_WCD_CTRL=m +CONFIG_WCD9XXX_CODEC_CORE=m +CONFIG_MSM_CDC_PINCTRL=m +CONFIG_SND_SOC_WCD9335=m +CONFIG_MSM_QDSP6V2_CODECS=m +CONFIG_MSM_ULTRASOUND=m +CONFIG_MSM_QDSP6_APRV2_RPMSG=m +CONFIG_MSM_ADSP_LOADER=m +CONFIG_REGMAP_SWR=m +CONFIG_MSM_QDSP6_SSR=m +CONFIG_MSM_QDSP6_PDR=m +CONFIG_MSM_QDSP6_NOTIFIER=m +CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +CONFIG_SND_SOC_QCS405=m +CONFIG_SND_SOC_BOLERO=m +CONFIG_WSA_MACRO=m +CONFIG_VA_MACRO=m +CONFIG_MSM_GLINK_SPI_XPRT=m +CONFIG_WCD_DSP_GLINK=m +CONFIG_SOUNDWIRE=m +CONFIG_WCD9XXX_CODEC_CORE=m +CONFIG_SND_SOC_QDSP6V2=m +CONFIG_SND_SOC_WCD_MBHC_LEGACY=m +CONFIG_QTI_PP=m +CONFIG_SND_HWDEP_ROUTING=m +CONFIG_SND_HWDEP=m +CONFIG_DTS_EAGLE=m +CONFIG_DOLBY_DS2=m +CONFIG_DOLBY_LICENSE=m +CONFIG_DTS_SRS_TM=m +CONFIG_SND_SOC_MSM_STUB=m +CONFIG_MSM_AVTIMER=m +CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m diff --git a/config/qcs405autoconf.h b/config/qcs405autoconf.h new file mode 100644 index 000000000000..0bb0463032c5 --- /dev/null +++ b/config/qcs405autoconf.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define CONFIG_PINCTRL_WCD 1 +#define CONFIG_PINCTRL_LPI 1 +#define CONFIG_AUDIO_EXT_CLK 1 +#define CONFIG_SND_SOC_WCD9XXX_V2 1 +#define CONFIG_SND_SOC_WSA881X 1 +#define CONFIG_SND_SOC_WCD_DSP_MGR 1 +#define CONFIG_SND_SOC_WCD_CPE 1 +#define CONFIG_SND_SOC_WCD9335 1 +#define CONFIG_WCD9XXX_CODEC_CORE 1 +#define CONFIG_MSM_CDC_PINCTRL 1 +#define CONFIG_MSM_QDSP6V2_CODECS 1 +#define CONFIG_MSM_ULTRASOUND 1 +#define CONFIG_MSM_QDSP6_APRV2_RPMSG 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_MSM_ADSP_LOADER 1 +#define CONFIG_REGMAP_SWR 1 +#define CONFIG_MSM_QDSP6_SSR 1 +#define CONFIG_MSM_QDSP6_PDR 1 +#define CONFIG_MSM_QDSP6_NOTIFIER 1 +#define CONFIG_SND_SOC_MSM_HOSTLESS_PCM 1 +#define CONFIG_SND_SOC_QCS405 1 +#define CONFIG_SND_SOC_BOLERO 1 +#define CONFIG_WSA_MACRO 1 +#define CONFIG_VA_MACRO 1 +#define CONFIG_MSM_GLINK_SPI_XPRT 1 +#define CONFIG_WCD_DSP_GLINK 1 +#define CONFIG_SOUNDWIRE 1 +#define CONFIG_SOUNDWIRE_WCD_CTRL 1 +#define CONFIG_SND_SOC_WCD_MBHC_LEGACY 1 +#define CONFIG_SND_SOC_QDSP6V2 1 +#define CONFIG_QTI_PP 1 +#define CONFIG_SND_HWDEP_ROUTING 1 +#define CONFIG_SND_HWDEP 1 +#define CONFIG_DTS_EAGLE 1 +#define CONFIG_DOLBY_DS2 1 +#define CONFIG_DOLBY_LICENSE 1 +#define CONFIG_DTS_SRS_TM 1 +#define CONFIG_WCD9XXX_CODEC_CORE 1 +#define CONFIG_SND_SOC_MSM_STUB 1 +#define CONFIG_MSM_AVTIMER 1 +#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 diff --git a/dsp/Kbuild b/dsp/Kbuild index 02a25e10fa19..1452221174ac 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -44,6 +44,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif + ifeq ($(CONFIG_ARCH_QCS405), y) + include $(AUDIO_ROOT)/config/qcs405auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h + endif endif diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index bdcc9dc413d9..81367198e781 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -45,6 +45,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif + ifeq ($(CONFIG_ARCH_QCS405), y) + include $(AUDIO_ROOT)/config/qcs405auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/ipc/Kbuild b/ipc/Kbuild index a860a751f148..35e785088cf2 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -23,6 +23,10 @@ ifeq ($(CONFIG_ARCH_SM6150), y) TARGET_KERNEL_VERSION := 4.14 endif +ifeq ($(CONFIG_ARCH_QCS405), y) + TARGET_KERNEL_VERSION := 4.14 +endif + ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) TARGET_KERNEL_VERSION := 4.14 endif @@ -59,6 +63,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif + ifeq ($(CONFIG_ARCH_QCS405), y) + include $(AUDIO_ROOT)/config/qcs405auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h + endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/soc/Kbuild b/soc/Kbuild index 3aaa38814db3..aee1a1fb6801 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -44,6 +44,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif + ifeq ($(CONFIG_ARCH_QCS405), y) + include $(AUDIO_ROOT)/config/qcs405auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h + endif endif # As per target team, build is done as follows: -- GitLab From 97f76efc86305b3f7aac40e84faa58e64022b509 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Tue, 12 Jun 2018 11:45:13 -0700 Subject: [PATCH 0320/1645] asoc: msm-lsm-client: add __user attribute for IOCTL Add __user attribute for msm_lsm_ioctl's input parameter "*arg" to explicitly identify it as user space pointer. Change-Id: I33e8a23cdef9eee9a55b77bb017716ccf2ba5f81 Signed-off-by: Xiaoyu Ye --- asoc/msm-lsm-client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 6f51236f9960..cea11b8599d5 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -1848,7 +1848,7 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, #endif static int msm_lsm_ioctl(struct snd_pcm_substream *substream, - unsigned int cmd, void *arg) + unsigned int cmd, void __user *arg) { int err = 0; u32 size = 0; -- GitLab From a1f21ebf064620d03615fb685ba9078728681723 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Tue, 12 Jun 2018 13:13:04 +0530 Subject: [PATCH 0321/1645] asoc: qcs405: Add machine driver changes for new swr master Send additional port types information from machine driver to wsa required for new soundwire driver. Change-Id: Ia3188cfe6e33dd5b219a12900cb0d04ca03fd02c Signed-off-by: Ramprasad Katkam --- asoc/qcs405.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index e1e13ebc1566..002286c858c9 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -35,6 +35,7 @@ #include "codecs/msm-cdc-pinctrl.h" #include "codecs/wcd9335.h" #include "codecs/wsa881x.h" +#include #define DRV_NAME "qcs405-asoc-snd" @@ -7098,8 +7099,12 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) static int msm_wsa881x_init(struct snd_soc_component *component) { - u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106}; - u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107}; + u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {0, 1, 2, 3}; + u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {0, 1, 2, 3}; + u8 spkleft_port_types[WSA881X_MAX_SWR_PORTS] = {SPKR_L, SPKR_L_COMP, + SPKR_L_BOOST, SPKR_L_VI}; + u8 spkright_port_types[WSA881X_MAX_SWR_PORTS] = {SPKR_R, SPKR_R_COMP, + SPKR_R_BOOST, SPKR_R_VI}; unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; struct snd_soc_codec *codec = snd_soc_component_to_codec(component); @@ -7119,7 +7124,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component) __func__, codec->component.name); wsa881x_set_channel_map(codec, &spkleft_ports[0], WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0]); + &ch_rate[0], &spkleft_port_types[0]); if (dapm->component) { snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); @@ -7129,7 +7134,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component) __func__, codec->component.name); wsa881x_set_channel_map(codec, &spkright_ports[0], WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0]); + &ch_rate[0], &spkright_port_types[0]); if (dapm->component) { snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); -- GitLab From 637d612f1b758c936d6e2f220532a6ab54d78215 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Wed, 13 Jun 2018 20:19:21 +0530 Subject: [PATCH 0322/1645] asoc: msm: routing: Add support for LSM routings for codec dma interfaces This change is to add support routing for codec dma interface backends and LSM front ends. Change-Id: Ia0d6a5a5969ca1a18ceed2b55b634146ecc3f956 Signed-off-by: Mangesh Kunchamwar --- asoc/msm-pcm-routing-v2.c | 90 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index aca4ddb43811..1ee5687e0f5d 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -110,6 +110,8 @@ enum { #define QUAT_MI2S_TX_TEXT "QUAT_MI2S_TX" #define ADM_LSM_TX_TEXT "ADM_LSM_TX" #define INT3_MI2S_TX_TEXT "INT3_MI2S_TX" +#define VA_CDC_DMA_TX_0_TEXT "VA_CDC_DMA_TX_0" +#define VA_CDC_DMA_TX_1_TEXT "VA_CDC_DMA_TX_1" #define LSM_FUNCTION_TEXT "LSM Function" static const char * const lsm_port_text[] = { @@ -117,7 +119,7 @@ static const char * const lsm_port_text[] = { SLIMBUS_0_TX_TEXT, SLIMBUS_1_TX_TEXT, SLIMBUS_2_TX_TEXT, SLIMBUS_3_TX_TEXT, SLIMBUS_4_TX_TEXT, SLIMBUS_5_TX_TEXT, TERT_MI2S_TX_TEXT, QUAT_MI2S_TX_TEXT, ADM_LSM_TX_TEXT, - INT3_MI2S_TX_TEXT + INT3_MI2S_TX_TEXT, VA_CDC_DMA_TX_0_TEXT, VA_CDC_DMA_TX_1_TEXT }; struct msm_pcm_route_bdai_pp_params { @@ -2515,6 +2517,12 @@ static int msm_routing_lsm_port_put(struct snd_kcontrol *kcontrol, case 10: lsm_port = AFE_PORT_ID_INT3_MI2S_TX; break; + case 11: + lsm_port = AFE_PORT_ID_VA_CODEC_DMA_TX_0; + break; + case 12: + lsm_port = AFE_PORT_ID_VA_CODEC_DMA_TX_1; + break; default: pr_err("Default lsm port"); break; @@ -14035,6 +14043,14 @@ static const struct snd_kcontrol_new lsm1_mixer_controls[] = { MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm2_mixer_controls[] = { @@ -14071,6 +14087,14 @@ static const struct snd_kcontrol_new lsm2_mixer_controls[] = { MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm3_mixer_controls[] = { @@ -14106,6 +14130,14 @@ static const struct snd_kcontrol_new lsm3_mixer_controls[] = { MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm4_mixer_controls[] = { @@ -14141,6 +14173,14 @@ static const struct snd_kcontrol_new lsm4_mixer_controls[] = { MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm5_mixer_controls[] = { @@ -14176,6 +14216,14 @@ static const struct snd_kcontrol_new lsm5_mixer_controls[] = { MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm6_mixer_controls[] = { @@ -14211,6 +14259,14 @@ static const struct snd_kcontrol_new lsm6_mixer_controls[] = { MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm7_mixer_controls[] = { @@ -14246,6 +14302,14 @@ static const struct snd_kcontrol_new lsm7_mixer_controls[] = { MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm8_mixer_controls[] = { @@ -14281,6 +14345,14 @@ static const struct snd_kcontrol_new lsm8_mixer_controls[] = { MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new slim_fm_switch_mixer_controls = @@ -18633,6 +18705,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"LSM1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"LSM1 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"LSM1_UL_HL", NULL, "LSM1 Mixer"}, {"LSM2 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -18643,6 +18717,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"LSM2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"LSM2 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"LSM2_UL_HL", NULL, "LSM2 Mixer"}, @@ -18654,6 +18730,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"LSM3 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"LSM3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"LSM3_UL_HL", NULL, "LSM3 Mixer"}, @@ -18665,6 +18743,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM4 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"LSM4 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"LSM4 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"LSM4_UL_HL", NULL, "LSM4 Mixer"}, {"LSM5 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -18675,6 +18755,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"LSM5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"LSM5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"LSM5_UL_HL", NULL, "LSM5 Mixer"}, {"LSM6 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -18683,6 +18765,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM6 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, {"LSM6 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, {"LSM6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"LSM6_UL_HL", NULL, "LSM6 Mixer"}, {"LSM7 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -18691,6 +18775,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM7 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, {"LSM7 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, {"LSM7 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM7 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM7 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"LSM7_UL_HL", NULL, "LSM7 Mixer"}, {"LSM8 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -18699,6 +18785,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM8 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, {"LSM8 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, {"LSM8 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"LSM8_UL_HL", NULL, "LSM8 Mixer"}, -- GitLab From e38aed40dbc690c005ee0f953b56d977d8155658 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 7 Mar 2018 16:26:49 +0530 Subject: [PATCH 0323/1645] Asoc: swr: Bus Driver changes to support new master driver soundwire bus driver changes to support new soundwire master driver for Talos/vipertooth. Change-Id: I70e52a72edd80abc72ccb99b29b1a642debec257 Signed-off-by: Ramprasad Katkam --- asoc/codecs/wsa881x.c | 55 +++++++++++++++++++++++++++++------------ asoc/codecs/wsa881x.h | 6 ++--- asoc/msm8998.c | 6 ++--- asoc/sdm660-common.c | 4 +-- asoc/sdm845.c | 6 ++--- asoc/sm8150.c | 4 +-- include/soc/soundwire.h | 49 +++++++++++++++++++++++++++--------- soc/soundwire.c | 31 +++++++++++++++-------- soc/swr-wcd-ctrl.c | 37 +++++++++++++-------------- soc/swrm_registers.h | 8 +++++- 10 files changed, 136 insertions(+), 70 deletions(-) diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index 2ef9e0a60478..0d1ab7b3870f 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -71,6 +71,7 @@ struct swr_port { u8 ch_mask; u32 ch_rate; u8 num_ch; + u8 port_type; }; enum { @@ -753,7 +754,8 @@ static const struct snd_kcontrol_new swr_dac_port[] = { }; static int wsa881x_set_port(struct snd_soc_codec *codec, int port_idx, - u8 *port_id, u8 *num_ch, u8 *ch_mask, u32 *ch_rate) + u8 *port_id, u8 *num_ch, u8 *ch_mask, u32 *ch_rate, + u8 *port_type) { struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); @@ -761,6 +763,7 @@ static int wsa881x_set_port(struct snd_soc_codec *codec, int port_idx, *num_ch = wsa881x->port[port_idx].num_ch; *ch_mask = wsa881x->port[port_idx].ch_mask; *ch_rate = wsa881x->port[port_idx].ch_rate; + *port_type = wsa881x->port[port_idx].port_type; return 0; } @@ -773,6 +776,7 @@ static int wsa881x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, u8 num_ch[WSA881X_MAX_SWR_PORTS]; u8 ch_mask[WSA881X_MAX_SWR_PORTS]; u32 ch_rate[WSA881X_MAX_SWR_PORTS]; + u8 port_type[WSA881X_MAX_SWR_PORTS]; u8 num_port = 0; dev_dbg(codec->dev, "%s: event %d name %s\n", __func__, @@ -784,53 +788,69 @@ static int wsa881x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMU: wsa881x_set_port(codec, SWR_DAC_PORT, &port_id[num_port], &num_ch[num_port], - &ch_mask[num_port], &ch_rate[num_port]); + &ch_mask[num_port], &ch_rate[num_port], + &port_type[num_port]); ++num_port; if (wsa881x->comp_enable) { wsa881x_set_port(codec, SWR_COMP_PORT, &port_id[num_port], &num_ch[num_port], - &ch_mask[num_port], &ch_rate[num_port]); + &ch_mask[num_port], &ch_rate[num_port], + &port_type[num_port]); ++num_port; } if (wsa881x->boost_enable) { wsa881x_set_port(codec, SWR_BOOST_PORT, &port_id[num_port], &num_ch[num_port], - &ch_mask[num_port], &ch_rate[num_port]); + &ch_mask[num_port], &ch_rate[num_port], + &port_type[num_port]); ++num_port; } if (wsa881x->visense_enable) { wsa881x_set_port(codec, SWR_VISENSE_PORT, &port_id[num_port], &num_ch[num_port], - &ch_mask[num_port], &ch_rate[num_port]); + &ch_mask[num_port], &ch_rate[num_port], + &port_type[num_port]); ++num_port; } swr_connect_port(wsa881x->swr_slave, &port_id[0], num_port, - &ch_mask[0], &ch_rate[0], &num_ch[0]); + &ch_mask[0], &ch_rate[0], &num_ch[0], + &port_type[0]); break; case SND_SOC_DAPM_POST_PMU: break; case SND_SOC_DAPM_PRE_PMD: break; case SND_SOC_DAPM_POST_PMD: - port_id[num_port] = wsa881x->port[SWR_DAC_PORT].port_id; + wsa881x_set_port(codec, SWR_DAC_PORT, + &port_id[num_port], &num_ch[num_port], + &ch_mask[num_port], &ch_rate[num_port], + &port_type[num_port]); ++num_port; + if (wsa881x->comp_enable) { - port_id[num_port] = - wsa881x->port[SWR_COMP_PORT].port_id; + wsa881x_set_port(codec, SWR_COMP_PORT, + &port_id[num_port], &num_ch[num_port], + &ch_mask[num_port], &ch_rate[num_port], + &port_type[num_port]); ++num_port; } if (wsa881x->boost_enable) { - port_id[num_port] = - wsa881x->port[SWR_BOOST_PORT].port_id; + wsa881x_set_port(codec, SWR_BOOST_PORT, + &port_id[num_port], &num_ch[num_port], + &ch_mask[num_port], &ch_rate[num_port], + &port_type[num_port]); ++num_port; } if (wsa881x->visense_enable) { - port_id[num_port] = - wsa881x->port[SWR_VISENSE_PORT].port_id; + wsa881x_set_port(codec, SWR_VISENSE_PORT, + &port_id[num_port], &num_ch[num_port], + &ch_mask[num_port], &ch_rate[num_port], + &port_type[num_port]); ++num_port; } - swr_disconnect_port(wsa881x->swr_slave, &port_id[0], num_port); + swr_disconnect_port(wsa881x->swr_slave, &port_id[0], num_port, + &ch_mask[0], &port_type[0]); break; default: break; @@ -1001,7 +1021,8 @@ static const struct snd_soc_dapm_route wsa881x_audio_map[] = { }; int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, u8 num_port, - unsigned int *ch_mask, unsigned int *ch_rate) + unsigned int *ch_mask, unsigned int *ch_rate, + u8 *port_type) { struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); int i; @@ -1018,6 +1039,8 @@ int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, u8 num_port, wsa881x->port[i].ch_mask = ch_mask[i]; wsa881x->port[i].ch_rate = ch_rate[i]; wsa881x->port[i].num_ch = __sw_hweight8(ch_mask[i]); + if (port_type) + wsa881x->port[i].port_type = port_type[i]; } return 0; } diff --git a/asoc/codecs/wsa881x.h b/asoc/codecs/wsa881x.h index fbc60d86a12b..9f998e37f9e5 100644 --- a/asoc/codecs/wsa881x.h +++ b/asoc/codecs/wsa881x.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -23,7 +23,7 @@ #if IS_ENABLED(CONFIG_SND_SOC_WSA881X) extern int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, u8 num_port, unsigned int *ch_mask, - unsigned int *ch_rate); + unsigned int *ch_rate, u8 *port_type); extern const u8 wsa881x_reg_readable[WSA881X_CACHE_SIZE]; extern struct regmap_config wsa881x_regmap_config; @@ -35,7 +35,7 @@ void wsa881x_regmap_defaults(struct regmap *regmap, u8 version); #else extern int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, u8 num_port, unsigned int *ch_mask, - unsigned int *ch_rate) + unsigned int *ch_rate, u8 *port_type); { return 0; } diff --git a/asoc/msm8998.c b/asoc/msm8998.c index 5f0128d05b0c..1faa1930cc02 100644 --- a/asoc/msm8998.c +++ b/asoc/msm8998.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -6975,7 +6975,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component) __func__, codec->component.name); wsa881x_set_channel_map(codec, &spkleft_ports[0], WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0]); + &ch_rate[0], NULL); if (dapm->component) { snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); @@ -6985,7 +6985,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component) __func__, codec->component.name); wsa881x_set_channel_map(codec, &spkright_ports[0], WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0]); + &ch_rate[0], NULL); if (dapm->component) { snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c index f2376b4ee29b..a33bbff22e56 100644 --- a/asoc/sdm660-common.c +++ b/asoc/sdm660-common.c @@ -3075,7 +3075,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component) __func__, codec->component.name); wsa881x_set_channel_map(codec, &spkleft_ports[0], WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0]); + &ch_rate[0], NULL); if (dapm->component) { snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); @@ -3085,7 +3085,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component) __func__, codec->component.name); wsa881x_set_channel_map(codec, &spkright_ports[0], WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0]); + &ch_rate[0], NULL); if (dapm->component) { snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); diff --git a/asoc/sdm845.c b/asoc/sdm845.c index f60e3a9f6e85..392ac85b9d78 100644 --- a/asoc/sdm845.c +++ b/asoc/sdm845.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -6603,7 +6603,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component) __func__, codec->component.name); wsa881x_set_channel_map(codec, &spkleft_ports[0], WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0]); + &ch_rate[0], NULL); if (dapm->component) { snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); @@ -6613,7 +6613,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component) __func__, codec->component.name); wsa881x_set_channel_map(codec, &spkright_ports[0], WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0]); + &ch_rate[0], NULL); if (dapm->component) { snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); diff --git a/asoc/sm8150.c b/asoc/sm8150.c index df16270e8be6..606ce1dc856c 100644 --- a/asoc/sm8150.c +++ b/asoc/sm8150.c @@ -7126,7 +7126,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component) __func__, codec->component.name); wsa881x_set_channel_map(codec, &spkleft_ports[0], WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0]); + &ch_rate[0], NULL); if (dapm->component) { snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); @@ -7136,7 +7136,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component) __func__, codec->component.name); wsa881x_set_channel_map(codec, &spkright_ports[0], WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0]); + &ch_rate[0], NULL); if (dapm->component) { snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); diff --git a/include/soc/soundwire.h b/include/soc/soundwire.h index a60d78cbd32b..d2ebb7621476 100644 --- a/include/soc/soundwire.h +++ b/include/soc/soundwire.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -38,16 +38,24 @@ enum { }; /* - * struct swr_port_info - represent soundwire frame shape - * @dev_id: logical device number of the soundwire slave device + * struct swr_port_info - represents new soundwire frame shape + * with full data ports + * @list: link with other soundwire port info nodes + * @dev_num: logical device number of the soundwire slave device * @port_en: flag indicates whether the port is enabled - * @port_id: logical port number of the soundwire slave device + * @slave_port_id: logical port number of the soundwire slave device * @offset1: sample offset indicating the offset of the channel * from the start of the frame * @offset2: channel offset indicating offset between to channels + * @hstart: start offset for subframe window. + * @hstop: start offset for subframe window. + * @master_port_id: logical port number of corresponding soundwire master device + * @blk_grp_count: grouping count for n.o of channels. + * @blk_pack_mode: packing mode for channels in each port. * @sinterval: sample interval indicates spacing from one sample * event to the next - * @ch_en: channels in a port that need to be enabled + * @ch_en: channels enabled in a port. + * @req_ch: channels requested to be enabled in a port. * @num_ch: number of channels enabled in a port * @ch_rate: sampling rate of the channel with which data will be * transferred @@ -56,13 +64,20 @@ enum { * parameters. */ struct swr_port_info { - u8 dev_id; + u8 dev_num; u8 port_en; - u8 port_id; + u8 slave_port_id; u8 offset1; u8 offset2; u8 sinterval; + struct list_head list; + u8 master_port_id; + u8 hstart; + u8 hstop; + u8 blk_grp_count; + u8 blk_pack_mode; u8 ch_en; + u8 req_ch; u8 num_ch; u32 ch_rate; }; @@ -71,22 +86,24 @@ struct swr_port_info { * struct swr_params - represent transfer of data from soundwire slave * to soundwire master * @tid: transaction ID to track each transaction - * @dev_id: logical device number of the soundwire slave device + * @dev_num: logical device number of the soundwire slave device * @num_port: number of ports that needs to be configured * @port_id: array of logical port numbers of the soundwire slave device * @num_ch: array of number of channels enabled * @ch_rate: array of sampling rate of different channels that need to * be configured * @ch_en: array of channels mask for all the ports + * @port_type: the required master port type */ struct swr_params { u8 tid; - u8 dev_id; + u8 dev_num; u8 num_port; u8 port_id[SWR_MAX_DEV_PORT_NUM]; u8 num_ch[SWR_MAX_DEV_PORT_NUM]; u32 ch_rate[SWR_MAX_DEV_PORT_NUM]; u8 ch_en[SWR_MAX_DEV_PORT_NUM]; + u8 port_type[SWR_MAX_DEV_PORT_NUM]; }; /* @@ -127,6 +144,7 @@ struct swr_reg { * @write: callback for soundwire slave register write * @get_logical_dev_num: callback to get soundwire slave logical * device number + * @port_en_mask: bit mask of active ports on soundwire master */ struct swr_master { struct device dev; @@ -151,8 +169,10 @@ struct swr_master { const void *buf, size_t len); int (*get_logical_dev_num)(struct swr_master *mstr, u64 dev_id, u8 *dev_num); - void (*slvdev_datapath_control)(struct swr_master *mstr, bool enable); + int (*slvdev_datapath_control)(struct swr_master *mstr, bool enable); bool (*remove_from_group)(struct swr_master *mstr); + u16 port_en_mask; + }; static inline struct swr_master *to_swr_master(struct device *dev) @@ -172,6 +192,8 @@ static inline struct swr_master *to_swr_master(struct device *dev) * @addr: represents "ea-addr" which is unique-id of soundwire slave * device * @group_id: group id supported by the slave device + * @slave_irq: irq handle of slave to be invoked by master + * during slave interrupt */ struct swr_device { char name[SOUNDWIRE_NAME_SIZE]; @@ -182,6 +204,7 @@ struct swr_device { struct device dev; unsigned long addr; u8 group_id; + u8 slave_irq; }; static inline struct swr_device *to_swr_device(struct device *dev) @@ -277,10 +300,12 @@ extern int swr_bulk_write(struct swr_device *dev, u8 dev_num, void *reg_addr, const void *buf, size_t len); extern int swr_connect_port(struct swr_device *dev, u8 *port_id, u8 num_port, - u8 *ch_mask, u32 *ch_rate, u8 *num_ch); + u8 *ch_mask, u32 *ch_rate, u8 *num_ch, + u8 *port_type); extern int swr_disconnect_port(struct swr_device *dev, - u8 *port_id, u8 num_port); + u8 *port_id, u8 num_port, u8 *ch_mask, + u8 *port_type); extern int swr_set_device_group(struct swr_device *swr_dev, u8 id); diff --git a/soc/soundwire.c b/soc/soundwire.c index cda4789d8d62..f05a5f9b1fb5 100644 --- a/soc/soundwire.c +++ b/soc/soundwire.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -268,6 +268,7 @@ int swr_slvdev_datapath_control(struct swr_device *dev, u8 dev_num, bool enable) { struct swr_master *master; + int ret = 0; if (!dev) return -ENODEV; @@ -287,9 +288,9 @@ int swr_slvdev_datapath_control(struct swr_device *dev, u8 dev_num, } if (master->slvdev_datapath_control) - master->slvdev_datapath_control(master, enable); + ret = master->slvdev_datapath_control(master, enable); - return 0; + return ret; } EXPORT_SYMBOL(swr_slvdev_datapath_control); @@ -308,7 +309,7 @@ EXPORT_SYMBOL(swr_slvdev_datapath_control); * and enable master and slave ports */ int swr_connect_port(struct swr_device *dev, u8 *port_id, u8 num_port, - u8 *ch_mask, u32 *ch_rate, u8 *num_ch) + u8 *ch_mask, u32 *ch_rate, u8 *num_ch, u8 *port_type) { u8 i = 0; int ret = 0; @@ -368,13 +369,14 @@ int swr_connect_port(struct swr_device *dev, u8 *port_id, u8 num_port, mutex_unlock(&master->mlock); txn->tid = i; - txn->dev_id = dev->dev_num; + txn->dev_num = dev->dev_num; txn->num_port = num_port; for (i = 0; i < num_port; i++) { txn->port_id[i] = port_id[i]; txn->num_ch[i] = num_ch[i]; txn->ch_rate[i] = ch_rate[i]; txn->ch_en[i] = ch_mask[i]; + txn->port_type[i] = port_type[i]; } ret = master->connect_port(master, txn); return ret; @@ -391,7 +393,8 @@ EXPORT_SYMBOL(swr_connect_port); * its ports. This API will call master disconnect_port callback function to * disable master and slave port and (re)configure frame structure */ -int swr_disconnect_port(struct swr_device *dev, u8 *port_id, u8 num_port) +int swr_disconnect_port(struct swr_device *dev, u8 *port_id, u8 num_port, + u8 *ch_mask, u8 *port_type) { u8 i = 0; int ret; @@ -445,10 +448,13 @@ int swr_disconnect_port(struct swr_device *dev, u8 *port_id, u8 num_port) mutex_unlock(&master->mlock); txn->tid = i; - txn->dev_id = dev->dev_num; + txn->dev_num = dev->dev_num; txn->num_port = num_port; - for (i = 0; i < num_port; i++) + for (i = 0; i < num_port; i++) { txn->port_id[i] = port_id[i]; + txn->ch_en[i] = ch_mask[i]; + txn->port_type[i] = port_type[i]; + } ret = master->disconnect_port(master, txn); return ret; } @@ -855,13 +861,18 @@ int swr_register_master(struct swr_master *master) int status = 0; mutex_lock(&swr_lock); + id = of_alias_get_id(master->dev.of_node, "swr"); + + if (id >= 0) + master->bus_num = id; id = idr_alloc(&master_idr, master, master->bus_num, - master->bus_num+1, GFP_KERNEL); + master->bus_num + 1, GFP_KERNEL); mutex_unlock(&swr_lock); + if (id < 0) return id; - master->bus_num = id; + master->bus_num = id; /* Can't register until driver model init */ if (WARN_ON(!soundwire_type.p)) { status = -EAGAIN; diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c index ade883c33bf4..729eb3850b2d 100644 --- a/soc/swr-wcd-ctrl.c +++ b/soc/swr-wcd-ctrl.c @@ -667,7 +667,7 @@ static struct swr_port_info *swrm_get_port(struct swr_master *master, for (i = 0; i < SWR_MSTR_PORT_LEN; i++) { port = &master->port[i]; - if (port->port_id == port_id) { + if (port->slave_port_id == port_id) { dev_dbg(&master->dev, "%s: port_id: %d, index: %d\n", __func__, port_id, i); return port; @@ -688,7 +688,7 @@ static struct swr_port_info *swrm_get_avail_port(struct swr_master *master) continue; dev_dbg(&master->dev, "%s: port_id: %d, index: %d\n", - __func__, port->port_id, i); + __func__, port->slave_port_id, i); return port; } @@ -703,7 +703,7 @@ static struct swr_port_info *swrm_get_enabled_port(struct swr_master *master, for (i = 0; i < SWR_MSTR_PORT_LEN; i++) { port = &master->port[i]; - if ((port->port_id == port_id) && (port->port_en == true)) + if ((port->slave_port_id == port_id) && (port->port_en == true)) break; } if (i == SWR_MSTR_PORT_LEN) @@ -781,7 +781,7 @@ static void swrm_cleanup_disabled_data_ports(struct swr_master *master, swrm->write(swrm->handle, SWRM_DP_PORT_CTRL_BANK((mport->id+1), bank), value); - swrm_cmd_fifo_wr_cmd(swrm, 0x00, port->dev_id, 0x00, + swrm_cmd_fifo_wr_cmd(swrm, 0x00, port->dev_num, 0x00, SWRS_DP_CHANNEL_ENABLE_BANK(port_type, bank)); dev_dbg(swrm->dev, "%s: mport :%d, reg: 0x%x, val: 0x%x\n", @@ -806,7 +806,7 @@ static void swrm_cleanup_disabled_data_ports(struct swr_master *master, __func__, port_disable_cnt, master->num_port); } -static void swrm_slvdev_datapath_control(struct swr_master *master, +static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) { u8 bank; @@ -819,7 +819,7 @@ static void swrm_slvdev_datapath_control(struct swr_master *master, if (!swrm) { pr_err("%s: swrm is null\n", __func__); - return; + return 0; } bank = get_inactive_bank_num(swrm); @@ -848,7 +848,7 @@ static void swrm_slvdev_datapath_control(struct swr_master *master, * BROADCAST and disabled in GROUP_NONE */ if (master->num_port == 0) - return; + return 0; } value = swrm->read(swrm->handle, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank)); @@ -875,6 +875,7 @@ static void swrm_slvdev_datapath_control(struct swr_master *master, pm_runtime_mark_last_busy(&swrm->pdev->dev); pm_runtime_put_autosuspend(&swrm->pdev->dev); } + return 0; } static void swrm_apply_port_config(struct swr_master *master) @@ -932,9 +933,9 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank) if (!port) continue; port_type = mstr_port_type[mport->id]; - if (!port->dev_id || (port->dev_id > master->num_dev)) { + if (!port->dev_num || (port->dev_num > master->num_dev)) { dev_dbg(swrm->dev, "%s: invalid device id = %d\n", - __func__, port->dev_id); + __func__, port->dev_num); continue; } value = ((port->ch_en) @@ -953,23 +954,23 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank) (SWRM_DP_PORT_CTRL_BANK((mport->id+1), bank)), value); reg[len] = SWRM_CMD_FIFO_WR_CMD; - val[len++] = SWR_REG_VAL_PACK(port->ch_en, port->dev_id, 0x00, + val[len++] = SWR_REG_VAL_PACK(port->ch_en, port->dev_num, 0x00, SWRS_DP_CHANNEL_ENABLE_BANK(port_type, bank)); reg[len] = SWRM_CMD_FIFO_WR_CMD; val[len++] = SWR_REG_VAL_PACK(port->sinterval, - port->dev_id, 0x00, + port->dev_num, 0x00, SWRS_DP_SAMPLE_CONTROL_1_BANK(port_type, bank)); reg[len] = SWRM_CMD_FIFO_WR_CMD; val[len++] = SWR_REG_VAL_PACK(port->offset1, - port->dev_id, 0x00, + port->dev_num, 0x00, SWRS_DP_OFFSET_CONTROL_1_BANK(port_type, bank)); if (port_type != 0) { reg[len] = SWRM_CMD_FIFO_WR_CMD; val[len++] = SWR_REG_VAL_PACK(port->offset2, - port->dev_id, 0x00, + port->dev_num, 0x00, SWRS_DP_OFFSET_CONTROL_2_BANK(port_type, bank)); } @@ -1028,15 +1029,15 @@ static int swrm_connect_port(struct swr_master *master, goto port_fail; } list_add(&mport->list, &swrm->mport_list); - port->dev_id = portinfo->dev_id; - port->port_id = portinfo->port_id[i]; + port->dev_num = portinfo->dev_num; + port->slave_port_id = portinfo->port_id[i]; port->num_ch = portinfo->num_ch[i]; port->ch_rate = portinfo->ch_rate[i]; port->ch_en = portinfo->ch_en[i]; port->port_en = true; dev_dbg(&master->dev, "%s: mstr port %d, slv port %d ch_rate %d num_ch %d\n", - __func__, mport->id, port->port_id, port->ch_rate, + __func__, mport->id, port->slave_port_id, port->ch_rate, port->num_ch); } master->num_port += portinfo->num_port; @@ -1120,7 +1121,7 @@ static int swrm_disconnect_port(struct swr_master *master, continue; } port_type = mstr_port_type[mport_id]; - port->dev_id = portinfo->dev_id; + port->dev_num = portinfo->dev_num; port->port_en = false; port->ch_en = 0; value = port->ch_en << SWRM_DP_PORT_CTRL_EN_CHAN_SHFT; @@ -1132,7 +1133,7 @@ static int swrm_disconnect_port(struct swr_master *master, swrm->write(swrm->handle, SWRM_DP_PORT_CTRL_BANK((mport_id+1), bank), value); - swrm_cmd_fifo_wr_cmd(swrm, 0x00, port->dev_id, 0x00, + swrm_cmd_fifo_wr_cmd(swrm, 0x00, port->dev_num, 0x00, SWRS_DP_CHANNEL_ENABLE_BANK(port_type, bank)); } diff --git a/soc/swrm_registers.h b/soc/swrm_registers.h index 50c3ecfdd47d..f1d2586944b2 100644 --- a/soc/swrm_registers.h +++ b/soc/swrm_registers.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. +/* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -33,6 +33,7 @@ #define SWRM_COMP_PARAMS_AUTO_ENUM_SLAVES 0x00F00000 #define SWRM_COMP_PARAMS_DATA_LANES 0x07000000 +#define SWRM_COMP_MASTER_ID (SWRM_BASE_ADDRESS+0x104) #define SWRM_INTERRUPT_STATUS (SWRM_BASE_ADDRESS+0x00000200) #define SWRM_INTERRUPT_STATUS_RMSK 0x1FFFD @@ -178,6 +179,11 @@ #define SWRM_DP_PORT_CTRL_OFFSET1_SHFT 0x08 #define SWRM_DP_PORT_CTRL_SAMPLE_INTERVAL 0x00 +#define SWRM_DIN_DPn_PCM_PORT_CTRL(n) (SWRM_BASE_ADDRESS + \ + 0x00001054 + 0x100*n) + +#define SWRM_MAX_REGISTER SWRM_DIN_DPn_PCM_PORT_CTRL(7) + /* Soundwire Slave Register definition */ #define SWRS_BASE_ADDRESS 0x00 -- GitLab From 0ebe6b86371e6984aa122b1d93652a2951a76779 Mon Sep 17 00:00:00 2001 From: Sachin Mohan Gadag Date: Mon, 12 Mar 2018 12:07:41 +0530 Subject: [PATCH 0324/1645] asoc: Add Makefile.am for audio modules compilation Add Makefile to compile audio modules for LE build compilation. Change-Id: I60710bd786d60dd29d1133acffdf098f0de5a6a2 Signed-off-by: Sachin Mohan Gadag --- Makefile.am | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Makefile.am diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000000..9fb3d45c7e1b --- /dev/null +++ b/Makefile.am @@ -0,0 +1,67 @@ +AUDIO_ROOT=$(PWD) +UAPI_OUT=$(PWD) +HEADER_INSTALL_DIR=$(KERNEL_SRC)/scripts +KERNEL_BINARY_DIR=$(KERNEL_SRC)/../kernel-build-artifacts + +KBUILD_OPTIONS := AUDIO_ROOT=$(PWD) +KBUILD_OPTIONS += MODNAME=audio +KBUILD_OPTIONS += UAPI_OUT=$(PWD) + +AUDIO_KERNEL_HEADERS_PATH1 = $(shell ls ./include/uapi/linux/*.h) +AUDIO_KERNEL_HEADERS_PATH2 = $(shell ls ./include/uapi/linux/mfd/wcd9xxx/*.h) +AUDIO_KERNEL_HEADERS_PATH3 = $(shell ls ./include/uapi/sound/*.h) + +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sdm670 qcs605)) +KBUILD_OPTIONS += CONFIG_ARCH_SDM670=y +endif +ifeq ($(TARGET_SUPPORT),sdm845) +KBUILD_OPTIONS += CONFIG_ARCH_SDM845=y +endif +ifeq ($(TARGET_SUPPORT),apq8053) +KBUILD_OPTIONS += CONFIG_ARCH_SDM450=y +endif +ifeq ($(TARGET_SUPPORT),qcs40x) +KBUILD_OPTIONS += CONFIG_ARCH_QCS405=y +endif + +obj-m := ipc/ +obj-m += dsp/ +obj-m += dsp/codecs/ +obj-m += soc/ +obj-m += asoc/ +obj-m += asoc/codecs/ +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sdm670 qcs605)) +obj-m += asoc/codecs/wcd934x/ +endif +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), apq8053 sdm670 qcs605)) +obj-m += asoc/codecs/sdm660_cdc/ +endif +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sdm670 qcs605)) +obj-m += asoc/codecs/msm_sdw/ +endif +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), qcs40x)) +obj-m += asoc/codecs/bolero/ +endif + +all: + $(shell rm -fr $(shell pwd)/soc/core.h) + $(shell ln -s $(KERNEL_SRC)/drivers/pinctrl/core.h $(shell pwd)/soc/core.h) + $(shell rm -fr $(shell pwd)/include/soc/internal.h) + $(shell ln -s $(KERNEL_SRC)/drivers/base/regmap/internal.h $(shell pwd)/include/soc/internal.h) + $(shell rm -fr $(shell pwd)/soc/pinctrl-utils.h) + $(shell ln -s $(KERNEL_SRC)/drivers/pinctrl/pinctrl-utils.h $(shell pwd)/soc/pinctrl-utils.h) + $(shell mkdir $(shell pwd)/linux) + $(shell mkdir $(shell pwd)/sound) + $(shell mkdir $(shell pwd)/linux/mfd) + $(shell mkdir $(shell pwd)/linux/mfd/wcd9xxx) + $(shell cd $(KERNEL_BINARY_DIR) && $(KERNEL_SRC)/scripts/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ $(notdir $(AUDIO_KERNEL_HEADERS_PATH1))) + $(shell cd $(KERNEL_BINARY_DIR) && $(KERNEL_SRC)/scripts/headers_install.sh $(UAPI_OUT)/linux/mfd/wcd9xxx/ $(AUDIO_ROOT)/include/uapi/linux/mfd/wcd9xxx/ $(notdir $(AUDIO_KERNEL_HEADERS_PATH2))) + $(shell cd $(KERNEL_BINARY_DIR) && $(KERNEL_SRC)/scripts/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ $(notdir $(AUDIO_KERNEL_HEADERS_PATH3))) + $(MAKE) -C $(KERNEL_SRC) M=$(shell pwd) modules $(KBUILD_OPTIONS) + +modules_install: + $(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(shell pwd) modules_install + +clean: + rm -f *.o *.ko *.mod.c *.mod.o *~ .*.cmd Module.symvers + rm -rf .tmp_versions -- GitLab From 6572b9d0e5aa1bb01399407346259176ec0bd152 Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Wed, 9 May 2018 12:30:10 -0700 Subject: [PATCH 0325/1645] asoc: fix lsm_event_handler function type Bug: 79254874 Bug: 67506682 Change-Id: I520634c3b55580004c38174bcf10513cf5f4fd3f Signed-off-by: Sami Tolvanen Signed-off-by: Banajit Goswami --- asoc/msm-lsm-client.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 6f51236f9960..ca397d20914a 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -196,7 +196,7 @@ static int lsm_lab_buffer_sanity(struct lsm_priv *prtd, } static void lsm_event_handler(uint32_t opcode, uint32_t token, - void *payload, void *priv) + uint32_t *payload, void *priv) { unsigned long flags; struct lsm_priv *prtd = priv; @@ -219,7 +219,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, switch (opcode) { case LSM_DATA_EVENT_READ_DONE: { int rc; - struct lsm_cmd_read_done *read_done = payload; + struct lsm_cmd_read_done *read_done = (struct lsm_cmd_read_done *)payload; int buf_index = 0; if (prtd->lsm_client->session != token || @@ -2204,7 +2204,7 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) pr_info("%s: constraint for buffer bytes step ret = %d\n", __func__, ret); prtd->lsm_client = q6lsm_client_alloc( - (lsm_app_cb)lsm_event_handler, prtd); + lsm_event_handler, prtd); if (!prtd->lsm_client) { pr_err("%s: Could not allocate memory\n", __func__); kfree(prtd); -- GitLab From ede0f05017b6903edaf511886c125164fd2a72e4 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 13 Jun 2018 04:48:36 +0530 Subject: [PATCH 0326/1645] ASoC: wcd-mbhc: Fix detection of special headset Comparison of headset threshold during special headset detection is not proper. This results in to improper detection of special headset and recording usecase failure on special headset. Fix the special headset detection issue by adding proper check condition while selection of headset threshold from device tree. Change-Id: I4c338ded1bcb9fa643e1584eb23c6260fe52acee Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd-mbhc-adc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index 893df9a5e036..981623748706 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -29,6 +29,7 @@ #include #include "wcd-mbhc-adc.h" #include "wcd-mbhc-v2.h" +#include "pdata.h" #define WCD_MBHC_ADC_HS_THRESHOLD_MV 1700 #define WCD_MBHC_ADC_HPH_THRESHOLD_MV 75 @@ -355,6 +356,8 @@ static bool wcd_mbhc_adc_check_for_spl_headset(struct wcd_mbhc *mbhc, bool spl_hs = false; int output_mv = 0; int adc_threshold = 0, adc_hph_threshold = 0; + struct snd_soc_codec *codec = mbhc->codec; + struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); pr_debug("%s: enter\n", __func__); if (!mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) @@ -370,7 +373,9 @@ static bool wcd_mbhc_adc_check_for_spl_headset(struct wcd_mbhc *mbhc, * btn press/relesae for HEADSET type during correct work. */ output_mv = wcd_measure_adc_once(mbhc, MUX_CTL_IN2P); - if (mbhc->hs_thr) + + if (mbhc->hs_thr && + (pdata->micbias.micb2_mv != WCD_MBHC_ADC_MICBIAS_MV)) adc_threshold = mbhc->hs_thr; else adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV * @@ -414,6 +419,8 @@ static bool wcd_is_special_headset(struct wcd_mbhc *mbhc) bool is_spl_hs = false; int output_mv = 0; int adc_threshold = 0; + struct snd_soc_codec *codec = mbhc->codec; + struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); /* * Increase micbias to 2.7V to detect headsets with @@ -433,7 +440,8 @@ static bool wcd_is_special_headset(struct wcd_mbhc *mbhc) return false; } } - if (mbhc->hs_thr) + if (mbhc->hs_thr && + (pdata->micbias.micb2_mv != WCD_MBHC_ADC_MICBIAS_MV)) adc_threshold = mbhc->hs_thr; else adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV * -- GitLab From e427c419f5fb58af15259117475cf8fa66a60de2 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Sat, 16 Jun 2018 00:02:46 -0700 Subject: [PATCH 0327/1645] dsp: fix return code check in adm driver Return error only if apr_send_pkt() function return code is less than 0. Change-Id: I98903c6c275f360d32c3af523352071d92d1ef85 Signed-off-by: Vidyakumar Athota --- dsp/q6adm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 7d59fbbce66a..e38ab41d0bb8 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -984,7 +984,7 @@ int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id, copp_stat = &this_adm.copp.stat[port_idx][copp_idx]; atomic_set(copp_stat, -1); ret = apr_send_pkt(this_adm.apr, (uint32_t *) &adm_get_params); - if (ret) { + if (ret < 0) { pr_err("%s: Get params APR send failed port = 0x%x ret %d\n", __func__, port_id, ret); ret = -EINVAL; @@ -1100,7 +1100,7 @@ int adm_get_pp_topo_module_list_v2(int port_id, int copp_idx, copp_stat = &this_adm.copp.stat[port_idx][copp_idx]; atomic_set(copp_stat, -1); ret = apr_send_pkt(this_adm.apr, (uint32_t *) &adm_get_module_list); - if (ret) { + if (ret < 0) { pr_err("%s: APR send pkt failed for port_id: 0x%x failed ret %d\n", __func__, port_id, ret); ret = -EINVAL; -- GitLab From 9f040f339ff1e8715c118effd73062e65a7a98f9 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 16 May 2018 10:19:25 +0530 Subject: [PATCH 0328/1645] Asoc: swr: New soundwire master driver New soundwire master driver to support multi master for Talos/vipertooth. Change-Id: I2616b940339e8f3d8d120e6705247d7bd1656bac Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 1850 ++++++++++++++++++++++++++++++++++++++++ soc/swr-mstr-ctrl.h | 135 +++ soc/swrm_port_config.h | 29 + 3 files changed, 2014 insertions(+) create mode 100644 soc/swr-mstr-ctrl.c create mode 100644 soc/swr-mstr-ctrl.h create mode 100644 soc/swrm_port_config.h diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c new file mode 100644 index 000000000000..4c5c3bd21354 --- /dev/null +++ b/soc/swr-mstr-ctrl.c @@ -0,0 +1,1850 @@ +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "swrm_registers.h" +#include "swr-mstr-ctrl.h" +#include "swrm_port_config.h" + + +#define SWR_BROADCAST_CMD_ID 0x0F +#define SWR_AUTO_SUSPEND_DELAY 3 /* delay in sec */ +#define SWR_DEV_ID_MASK 0xFFFFFFFF +#define SWR_REG_VAL_PACK(data, dev, id, reg) \ + ((reg) | ((id) << 16) | ((dev) << 20) | ((data) << 24)) + +/* pm runtime auto suspend timer in msecs */ +static int auto_suspend_timer = SWR_AUTO_SUSPEND_DELAY * 1000; +module_param(auto_suspend_timer, int, 0664); +MODULE_PARM_DESC(auto_suspend_timer, "timer for auto suspend"); + +enum { + SWR_NOT_PRESENT, /* Device is detached/not present on the bus */ + SWR_ATTACHED_OK, /* Device is attached */ + SWR_ALERT, /* Device alters master for any interrupts */ + SWR_RESERVED, /* Reserved */ +}; + +enum { + MASTER_ID_WSA = 1, + MASTER_ID_RX, + MASTER_ID_TX +}; +#define MASTER_ID_MASK 0xF +#define TRUE 1 +#define FALSE 0 + +#define SWRM_MAX_PORT_REG 40 +#define SWRM_MAX_INIT_REG 8 + +#define SWR_MSTR_MAX_REG_ADDR 0x1740 +#define SWR_MSTR_START_REG_ADDR 0x00 +#define SWR_MSTR_MAX_BUF_LEN 32 +#define BYTES_PER_LINE 12 +#define SWR_MSTR_RD_BUF_LEN 8 +#define SWR_MSTR_WR_BUF_LEN 32 + +static struct swr_mstr_ctrl *dbgswrm; +static struct dentry *debugfs_swrm_dent; +static struct dentry *debugfs_peek; +static struct dentry *debugfs_poke; +static struct dentry *debugfs_reg_dump; +static unsigned int read_data; + + +static bool swrm_is_msm_variant(int val) +{ + return (val == SWRM_VERSION_1_3); +} + +static int swrm_debug_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static int get_parameters(char *buf, u32 *param1, int num_of_par) +{ + char *token; + int base, cnt; + + token = strsep(&buf, " "); + for (cnt = 0; cnt < num_of_par; cnt++) { + if (token) { + if ((token[1] == 'x') || (token[1] == 'X')) + base = 16; + else + base = 10; + + if (kstrtou32(token, base, ¶m1[cnt]) != 0) + return -EINVAL; + + token = strsep(&buf, " "); + } else + return -EINVAL; + } + return 0; +} + +static ssize_t swrm_reg_show(char __user *ubuf, size_t count, + loff_t *ppos) +{ + int i, reg_val, len; + ssize_t total = 0; + char tmp_buf[SWR_MSTR_MAX_BUF_LEN]; + + if (!ubuf || !ppos) + return 0; + + for (i = (((int) *ppos / BYTES_PER_LINE) + SWR_MSTR_START_REG_ADDR); + i <= SWR_MSTR_MAX_REG_ADDR; i += 4) { + reg_val = dbgswrm->read(dbgswrm->handle, i); + len = snprintf(tmp_buf, 25, "0x%.3x: 0x%.2x\n", i, reg_val); + if ((total + len) >= count - 1) + break; + if (copy_to_user((ubuf + total), tmp_buf, len)) { + pr_err("%s: fail to copy reg dump\n", __func__); + total = -EFAULT; + goto copy_err; + } + *ppos += len; + total += len; + } + +copy_err: + return total; +} + +static ssize_t swrm_debug_read(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + char lbuf[SWR_MSTR_RD_BUF_LEN]; + char *access_str; + ssize_t ret_cnt; + + if (!count || !file || !ppos || !ubuf) + return -EINVAL; + + access_str = file->private_data; + if (*ppos < 0) + return -EINVAL; + + if (!strcmp(access_str, "swrm_peek")) { + snprintf(lbuf, sizeof(lbuf), "0x%x\n", read_data); + ret_cnt = simple_read_from_buffer(ubuf, count, ppos, lbuf, + strnlen(lbuf, 7)); + } else if (!strcmp(access_str, "swrm_reg_dump")) { + ret_cnt = swrm_reg_show(ubuf, count, ppos); + } else { + pr_err("%s: %s not permitted to read\n", __func__, access_str); + ret_cnt = -EPERM; + } + return ret_cnt; +} + +static ssize_t swrm_debug_write(struct file *filp, + const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char lbuf[SWR_MSTR_WR_BUF_LEN]; + int rc; + u32 param[5]; + char *access_str; + + if (!filp || !ppos || !ubuf) + return -EINVAL; + + access_str = filp->private_data; + if (cnt > sizeof(lbuf) - 1) + return -EINVAL; + + rc = copy_from_user(lbuf, ubuf, cnt); + if (rc) + return -EFAULT; + + lbuf[cnt] = '\0'; + if (!strcmp(access_str, "swrm_poke")) { + /* write */ + rc = get_parameters(lbuf, param, 2); + if ((param[0] <= SWR_MSTR_MAX_REG_ADDR) && + (param[1] <= 0xFFFFFFFF) && + (rc == 0)) + rc = dbgswrm->write(dbgswrm->handle, param[0], + param[1]); + else + rc = -EINVAL; + } else if (!strcmp(access_str, "swrm_peek")) { + /* read */ + rc = get_parameters(lbuf, param, 1); + if ((param[0] <= SWR_MSTR_MAX_REG_ADDR) && (rc == 0)) + read_data = dbgswrm->read(dbgswrm->handle, param[0]); + else + rc = -EINVAL; + } + if (rc == 0) + rc = cnt; + else + pr_err("%s: rc = %d\n", __func__, rc); + + return rc; +} + +static const struct file_operations swrm_debug_ops = { + .open = swrm_debug_open, + .write = swrm_debug_write, + .read = swrm_debug_read, +}; + +static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) +{ + if (!swrm->clk || !swrm->handle) + return -EINVAL; + + if (enable) { + swrm->clk_ref_count++; + if (swrm->clk_ref_count == 1) { + swrm->clk(swrm->handle, true); + swrm->state = SWR_MSTR_UP; + } + } else if (--swrm->clk_ref_count == 0) { + swrm->clk(swrm->handle, false); + swrm->state = SWR_MSTR_DOWN; + } else if (swrm->clk_ref_count < 0) { + pr_err("%s: swrm clk count mismatch\n", __func__); + swrm->clk_ref_count = 0; + } + return 0; +} + +static int swrm_ahb_write(struct swr_mstr_ctrl *swrm, + u16 reg, u32 *value) +{ + u32 temp = (u32)(*value) & 0x000000FF; + int ret; + + ret = swrm_clk_request(swrm, TRUE); + + if (ret) + return -EINVAL; + + iowrite32(temp, swrm->swrm_dig_base + reg); + + swrm_clk_request(swrm, TRUE); + + return 0; +} + +static int swrm_ahb_read(struct swr_mstr_ctrl *swrm, + u16 reg, u32 *value) +{ + u32 temp; + int ret; + + ret = swrm_clk_request(swrm, TRUE); + + if (ret) + return -EINVAL; + + temp = ioread32(swrm->swrm_dig_base + reg); + *value = (u8)temp; + swrm_clk_request(swrm, FALSE); + return 0; +} + +static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr) +{ + u32 val = 0; + + if (swrm->read) + val = swrm->read(swrm->handle, reg_addr); + else + swrm_ahb_read(swrm, reg_addr, &val); + return val; +} + +static void swr_master_write(struct swr_mstr_ctrl *swrm, u16 reg_addr, u32 val) +{ + if (swrm->write) + swrm->write(swrm->handle, reg_addr, val); + else + swrm_ahb_write(swrm, reg_addr, &val); +} + +static int swr_master_bulk_write(struct swr_mstr_ctrl *swrm, u32 *reg_addr, + u32 *val, unsigned int length) +{ + int i = 0; + + if (swrm->bulk_write) + swrm->bulk_write(swrm->handle, reg_addr, val, length); + else { + for (i = 0; i < length; i++) + swr_master_write(swrm, reg_addr[i], val[i]); + } + return 0; +} + +static bool swrm_is_port_en(struct swr_master *mstr) +{ + return !!(mstr->num_port); +} + +static int swrm_get_port_config(struct swr_mstr_ctrl *swrm) +{ + u8 master_device_id; + int i; + + if (swrm->version == SWRM_VERSION_1_5) + master_device_id = swr_master_read(swrm, SWRM_COMP_MASTER_ID); + else + master_device_id = MASTER_ID_WSA; + + switch (master_device_id & MASTER_ID_MASK) { + case MASTER_ID_WSA: + /* get port params for wsa */ + for (i = 0; i < SWR_MSTR_PORT_LEN; i++) { + /* wsa uses single frame structure for all configurations */ + if (!swrm->mport_cfg[i].port_en) + continue; + swrm->mport_cfg[i].sinterval = wsa_frame_superset[i].si; + swrm->mport_cfg[i].offset1 = wsa_frame_superset[i].off1; + swrm->mport_cfg[i].offset2 = wsa_frame_superset[i].off2; + } + break; + case MASTER_ID_RX: + /* get port params for rx */ + break; + case MASTER_ID_TX: + /* get port params for tx */ + break; + default: /* MASTER_GENERIC*/ + /* computer generic frame parameters */ + return -EINVAL; + } + return 0; +} + +static int swrm_get_master_port(struct swr_mstr_ctrl *swrm, u8 *mstr_port_id, + u8 *mstr_ch_mask, u8 mstr_prt_type, + u8 slv_port_id) +{ + int i, j; + *mstr_port_id = 0; + + for (i = 1; i <= swrm->num_ports; i++) { + for (j = 0; j < SWR_MAX_CH_PER_PORT; j++) { + if (swrm->port_mapping[i][j].port_type == mstr_prt_type) + goto found; + } + } +found: + if (i > swrm->num_ports || j == SWR_MAX_CH_PER_PORT) { + dev_err(swrm->dev, "%s: port type not supported by master\n", + __func__); + return -EINVAL; + } + /* id 0 corresponds to master port 1 */ + *mstr_port_id = i - 1; + *mstr_ch_mask = swrm->port_mapping[i][j].ch_mask; + + return 0; + +} + +static u32 swrm_get_packed_reg_val(u8 *cmd_id, u8 cmd_data, + u8 dev_addr, u16 reg_addr) +{ + u32 val; + u8 id = *cmd_id; + + if (id != SWR_BROADCAST_CMD_ID) { + if (id < 14) + id += 1; + else + id = 0; + *cmd_id = id; + } + val = SWR_REG_VAL_PACK(cmd_data, dev_addr, id, reg_addr); + + return val; +} + +static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, + u8 dev_addr, u8 cmd_id, u16 reg_addr, + u32 len) +{ + u32 val; + + val = swrm_get_packed_reg_val(&swrm->rcmd_id, len, dev_addr, reg_addr); + swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val); + + *cmd_data = swr_master_read(swrm, SWRM_CMD_FIFO_RD_FIFO_ADDR); + dev_dbg(swrm->dev, + "%s: reg: 0x%x, cmd_id: 0x%x, dev_num: 0x%x, cmd_data: 0x%x\n", + __func__, reg_addr, cmd_id, dev_addr, *cmd_data); + + return 0; +} + +static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data, + u8 dev_addr, u8 cmd_id, u16 reg_addr) +{ + u32 val; + int ret = 0; + + if (!cmd_id) + val = swrm_get_packed_reg_val(&swrm->wcmd_id, cmd_data, + dev_addr, reg_addr); + else + val = swrm_get_packed_reg_val(&cmd_id, cmd_data, + dev_addr, reg_addr); + + dev_dbg(swrm->dev, + "%s: reg: 0x%x, cmd_id: 0x%x, dev_num: 0x%x, cmd_data: 0x%x\n", + __func__, reg_addr, cmd_id, dev_addr, cmd_data); + swr_master_write(swrm, SWRM_CMD_FIFO_WR_CMD, val); + + if (cmd_id == 0xF) { + /* + * sleep for 10ms for MSM soundwire variant to allow broadcast + * command to complete. + */ + if (swrm_is_msm_variant(swrm->version)) + usleep_range(10000, 10100); + else + wait_for_completion_timeout(&swrm->broadcast, + (2 * HZ/10)); + } + return ret; +} + +static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr, + void *buf, u32 len) +{ + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + int ret = 0; + int val; + u8 *reg_val = (u8 *)buf; + + if (!swrm) { + dev_err(&master->dev, "%s: swrm is NULL\n", __func__); + return -EINVAL; + } + + if (dev_num) + ret = swrm_cmd_fifo_rd_cmd(swrm, &val, dev_num, 0, reg_addr, + len); + else + val = swr_master_read(swrm, reg_addr); + + if (!ret) + *reg_val = (u8)val; + + pm_runtime_mark_last_busy(swrm->dev); + + return ret; +} + +static int swrm_write(struct swr_master *master, u8 dev_num, u16 reg_addr, + const void *buf) +{ + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + int ret = 0; + u8 reg_val = *(u8 *)buf; + + if (!swrm) { + dev_err(&master->dev, "%s: swrm is NULL\n", __func__); + return -EINVAL; + } + + if (dev_num) + ret = swrm_cmd_fifo_wr_cmd(swrm, reg_val, dev_num, 0, reg_addr); + else + swr_master_write(swrm, reg_addr, reg_val); + pm_runtime_mark_last_busy(swrm->dev); + + return ret; +} + +static int swrm_bulk_write(struct swr_master *master, u8 dev_num, void *reg, + const void *buf, size_t len) +{ + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + int ret = 0; + int i; + u32 *val; + u32 *swr_fifo_reg; + + if (!swrm || !swrm->handle) { + dev_err(&master->dev, "%s: swrm is NULL\n", __func__); + return -EINVAL; + } + if (len <= 0) + return -EINVAL; + + if (dev_num) { + swr_fifo_reg = kcalloc(len, sizeof(u32), GFP_KERNEL); + if (!swr_fifo_reg) { + ret = -ENOMEM; + goto err; + } + val = kcalloc(len, sizeof(u32), GFP_KERNEL); + if (!val) { + ret = -ENOMEM; + goto mem_fail; + } + + for (i = 0; i < len; i++) { + val[i] = swrm_get_packed_reg_val(&swrm->wcmd_id, + ((u8 *)buf)[i], + dev_num, + ((u16 *)reg)[i]); + swr_fifo_reg[i] = SWRM_CMD_FIFO_WR_CMD; + } + ret = swr_master_bulk_write(swrm, swr_fifo_reg, val, len); + if (ret) { + dev_err(&master->dev, "%s: bulk write failed\n", + __func__); + ret = -EINVAL; + } + } else { + dev_err(&master->dev, + "%s: No support of Bulk write for master regs\n", + __func__); + ret = -EINVAL; + goto err; + } + kfree(val); +mem_fail: + kfree(swr_fifo_reg); +err: + pm_runtime_mark_last_busy(swrm->dev); + return ret; +} + +static u8 get_inactive_bank_num(struct swr_mstr_ctrl *swrm) +{ + return (swr_master_read(swrm, SWRM_MCP_STATUS) & + SWRM_MCP_STATUS_BANK_NUM_MASK) ? 0 : 1; +} + +static void enable_bank_switch(struct swr_mstr_ctrl *swrm, u8 bank, + u8 row, u8 col) +{ + swrm_cmd_fifo_wr_cmd(swrm, ((row << 3) | col), 0xF, 0xF, + SWRS_SCP_FRAME_CTRL_BANK(bank)); +} + +static struct swr_port_info *swrm_get_port_req(struct swrm_mports *mport, + u8 slv_port, u8 dev_num) +{ + struct swr_port_info *port_req = NULL; + + list_for_each_entry(port_req, &mport->port_req_list, list) { + /* Store dev_id instead of dev_num if enumeration is changed run_time */ + if ((port_req->slave_port_id == slv_port) + && (port_req->dev_num == dev_num)) + return port_req; + } + return NULL; +} + +static bool swrm_remove_from_group(struct swr_master *master) +{ + struct swr_device *swr_dev; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + bool is_removed = false; + + if (!swrm) + goto end; + + mutex_lock(&swrm->mlock); + if ((swrm->num_rx_chs > 1) && + (swrm->num_rx_chs == swrm->num_cfg_devs)) { + list_for_each_entry(swr_dev, &master->devices, + dev_list) { + swr_dev->group_id = SWR_GROUP_NONE; + master->gr_sid = 0; + } + is_removed = true; + } + mutex_unlock(&swrm->mlock); + +end: + return is_removed; +} + +static void swrm_disable_ports(struct swr_master *master, + u8 bank) +{ + u32 value; + struct swr_port_info *port_req; + int i; + struct swrm_mports *mport; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + + if (!swrm) { + pr_err("%s: swrm is null\n", __func__); + return; + } + + dev_dbg(swrm->dev, "%s: master num_port: %d\n", __func__, + master->num_port); + + + for (i = 0; i < SWR_MSTR_PORT_LEN ; i++) { + + mport = &(swrm->mport_cfg[i]); + if (!mport->port_en) + continue; + + list_for_each_entry(port_req, &mport->port_req_list, list) { + /* skip ports with no change req's*/ + if (port_req->req_ch == port_req->ch_en) + continue; + + swrm_cmd_fifo_wr_cmd(swrm, port_req->req_ch, + port_req->dev_num, 0x00, + SWRS_DP_CHANNEL_ENABLE_BANK(port_req->slave_port_id, + bank)); + dev_dbg(swrm->dev, "%s: mport :%d, reg: 0x%x\n", + __func__, i, + (SWRM_DP_PORT_CTRL_BANK(i + 1, bank))); + } + value = ((mport->req_ch) + << SWRM_DP_PORT_CTRL_EN_CHAN_SHFT); + value |= ((mport->offset2) + << SWRM_DP_PORT_CTRL_OFFSET2_SHFT); + value |= ((mport->offset1) + << SWRM_DP_PORT_CTRL_OFFSET1_SHFT); + value |= mport->sinterval; + + swr_master_write(swrm, + SWRM_DP_PORT_CTRL_BANK(i+1, bank), + value); + dev_dbg(swrm->dev, "%s: mport :%d, reg: 0x%x, val: 0x%x\n", + __func__, i, + (SWRM_DP_PORT_CTRL_BANK(i+1, bank)), value); + } +} + +static void swrm_cleanup_disabled_port_reqs(struct swr_master *master) +{ + struct swr_port_info *port_req, *next; + int i; + struct swrm_mports *mport; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + + if (!swrm) { + pr_err("%s: swrm is null\n", __func__); + return; + } + dev_dbg(swrm->dev, "%s: master num_port: %d\n", __func__, + master->num_port); + + for (i = 0; i < SWR_MSTR_PORT_LEN; i++) { + mport = &(swrm->mport_cfg[i]); + list_for_each_entry_safe(port_req, next, + &mport->port_req_list, list) { + /* skip ports without new ch req */ + if (port_req->ch_en == port_req->req_ch) + continue; + + /* remove new ch req's*/ + port_req->req_ch = port_req->ch_en; + + /* If no streams enabled on port, remove the port req */ + if (port_req->ch_en == 0) { + list_del(&port_req->list); + kfree(port_req); + } + } + /* remove new ch req's on mport*/ + mport->req_ch = mport->ch_en; + + if (!(mport->ch_en)) { + mport->port_en = false; + master->port_en_mask &= ~i; + } + } +} +static void swrm_copy_data_port_config(struct swr_master *master, u8 bank) +{ + u32 value, slv_id; + struct swr_port_info *port_req; + int i; + struct swrm_mports *mport; + u32 reg[SWRM_MAX_PORT_REG]; + u32 val[SWRM_MAX_PORT_REG]; + int len = 0; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + + if (!swrm) { + pr_err("%s: swrm is null\n", __func__); + return; + } + + dev_dbg(swrm->dev, "%s: master num_port: %d\n", __func__, + master->num_port); + + for (i = 0; i < SWR_MSTR_PORT_LEN; i++) { + mport = &(swrm->mport_cfg[i]); + if (!mport->port_en) + continue; + + list_for_each_entry(port_req, &mport->port_req_list, list) { + slv_id = port_req->slave_port_id; + reg[len] = SWRM_CMD_FIFO_WR_CMD; + val[len++] = SWR_REG_VAL_PACK(port_req->req_ch, + port_req->dev_num, 0x00, + SWRS_DP_CHANNEL_ENABLE_BANK(slv_id, + bank)); + + reg[len] = SWRM_CMD_FIFO_WR_CMD; + val[len++] = SWR_REG_VAL_PACK(mport->sinterval, + port_req->dev_num, 0x00, + SWRS_DP_SAMPLE_CONTROL_1_BANK(slv_id, + bank)); + + reg[len] = SWRM_CMD_FIFO_WR_CMD; + val[len++] = SWR_REG_VAL_PACK(mport->offset1, + port_req->dev_num, 0x00, + SWRS_DP_OFFSET_CONTROL_1_BANK(slv_id, + bank)); + + if (port_req->slave_port_id) { + reg[len] = SWRM_CMD_FIFO_WR_CMD; + val[len++] = SWR_REG_VAL_PACK(mport->offset2, + port_req->dev_num, 0x00, + SWRS_DP_OFFSET_CONTROL_2_BANK( + slv_id, bank)); + } + port_req->ch_en = port_req->req_ch; + } + value = ((mport->req_ch) + << SWRM_DP_PORT_CTRL_EN_CHAN_SHFT); + value |= ((mport->offset2) + << SWRM_DP_PORT_CTRL_OFFSET2_SHFT); + value |= ((mport->offset1) + << SWRM_DP_PORT_CTRL_OFFSET1_SHFT); + value |= mport->sinterval; + + + reg[len] = SWRM_DP_PORT_CTRL_BANK(i + 1, bank); + val[len++] = value; + + dev_dbg(swrm->dev, "%s: mport :%d, reg: 0x%x, val: 0x%x\n", + __func__, i, + (SWRM_DP_PORT_CTRL_BANK(i + 1, bank)), value); + + mport->ch_en = mport->req_ch; + + } + swr_master_bulk_write(swrm, reg, val, len); +} + +static void swrm_apply_port_config(struct swr_master *master) +{ + u8 bank; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + + if (!swrm) { + pr_err("%s: Invalid handle to swr controller\n", + __func__); + return; + } + + bank = get_inactive_bank_num(swrm); + dev_dbg(swrm->dev, "%s: enter bank: %d master_ports: %d\n", + __func__, bank, master->num_port); + + + swrm_cmd_fifo_wr_cmd(swrm, 0x01, 0xF, 0x00, + SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(bank)); + + swrm_copy_data_port_config(master, bank); +} + +static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) +{ + u8 bank; + u32 value, n_col; + int ret; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK | + SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK | + SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_BMSK); + u8 inactive_bank; + + if (!swrm) { + pr_err("%s: swrm is null\n", __func__); + return -EFAULT; + } + mutex_lock(&swrm->mlock); + + /* wakeup soundwire master if in sleep */ + pm_runtime_get_sync(swrm->dev); + + bank = get_inactive_bank_num(swrm); + + if (enable) { + ret = swrm_get_port_config(swrm); + if (ret) { + /* cannot accommodate ports */ + swrm_cleanup_disabled_port_reqs(master); + mutex_unlock(&swrm->mlock); + return -EINVAL; + } + /* apply the new port config*/ + swrm_apply_port_config(master); + } else { + swrm_disable_ports(master, bank); + } + dev_dbg(swrm->dev, "%s: enable: %d, cfg_devs: %d\n", + __func__, enable, swrm->num_cfg_devs); + + if (enable) { + /* set Row = 48 and col = 16 */ + n_col = SWR_MAX_COL; + } else { + /* + * Do not change to 48x2 if there are still active ports + */ + if (!master->num_port) + n_col = SWR_MIN_COL; + else + n_col = SWR_MAX_COL; + } + + value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank)); + value &= (~mask); + value |= ((0 << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | + (n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) | + (0 << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT)); + swr_master_write(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value); + + dev_dbg(swrm->dev, "%s: regaddr: 0x%x, value: 0x%x\n", __func__, + SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value); + + enable_bank_switch(swrm, bank, SWR_MAX_ROW, n_col); + inactive_bank = bank ? 0 : 1; + + if (enable) + swrm_copy_data_port_config(master, inactive_bank); + else { + swrm_disable_ports(master, inactive_bank); + swrm_cleanup_disabled_port_reqs(master); + } + if (!swrm_is_port_en(master)) { + dev_dbg(&master->dev, "%s: pm_runtime auto suspend triggered\n", + __func__); + pm_runtime_mark_last_busy(swrm->dev); + pm_runtime_put_autosuspend(swrm->dev); + } + mutex_unlock(&swrm->mlock); +return 0; +} + +static int swrm_connect_port(struct swr_master *master, + struct swr_params *portinfo) +{ + int i; + struct swr_port_info *port_req; + int ret = 0; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + struct swrm_mports *mport; + u8 mstr_port_id, mstr_ch_msk; + + dev_dbg(&master->dev, "%s: enter\n", __func__); + if (!portinfo) + return -EINVAL; + + if (!swrm) { + dev_err(&master->dev, + "%s: Invalid handle to swr controller\n", + __func__); + return -EINVAL; + } + + mutex_lock(&swrm->mlock); + + for (i = 0; i < portinfo->num_port; i++) { + ret = swrm_get_master_port(swrm, &mstr_port_id, &mstr_ch_msk, + portinfo->port_type[i], + portinfo->port_id[i]); + if (ret) { + dev_err(&master->dev, + "%s: mstr portid for slv port %d not found\n", + __func__, portinfo->port_id[i]); + goto port_fail; + } + + mport = &(swrm->mport_cfg[mstr_port_id]); + /* get port req */ + port_req = swrm_get_port_req(mport, portinfo->port_id[i], + portinfo->dev_num); + if (!port_req) { + dev_dbg(&master->dev, "%s: new req:port id %d dev %d\n", + __func__, portinfo->port_id[i], + portinfo->dev_num); + port_req = kzalloc(sizeof(struct swr_port_info), + GFP_KERNEL); + if (!port_req) { + ret = -ENOMEM; + goto mem_fail; + } + port_req->dev_num = portinfo->dev_num; + port_req->slave_port_id = portinfo->port_id[i]; + port_req->num_ch = portinfo->num_ch[i]; + port_req->ch_rate = portinfo->ch_rate[i]; + port_req->ch_en = 0; + port_req->master_port_id = mstr_port_id; + list_add(&port_req->list, &mport->port_req_list); + } + port_req->req_ch |= portinfo->ch_en[i]; + + dev_dbg(&master->dev, + "%s: mstr port %d, slv port %d ch_rate %d num_ch %d\n", + __func__, port_req->master_port_id, + port_req->slave_port_id, port_req->ch_rate, + port_req->num_ch); + /* Put the port req on master port */ + mport = &(swrm->mport_cfg[mstr_port_id]); + mport->port_en = true; + mport->req_ch |= mstr_ch_msk; + master->port_en_mask |= (1 << mstr_port_id); + } + master->num_port += portinfo->num_port; + swr_port_response(master, portinfo->tid); + + mutex_unlock(&swrm->mlock); + return 0; + +port_fail: +mem_fail: + /* cleanup port reqs in error condition */ + swrm_cleanup_disabled_port_reqs(master); + mutex_unlock(&swrm->mlock); + return ret; +} + +static int swrm_disconnect_port(struct swr_master *master, + struct swr_params *portinfo) +{ + int i, ret = 0; + struct swr_port_info *port_req; + struct swrm_mports *mport; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); + u8 mstr_port_id, mstr_ch_mask; + + if (!swrm) { + dev_err(&master->dev, + "%s: Invalid handle to swr controller\n", + __func__); + return -EINVAL; + } + + if (!portinfo) { + dev_err(&master->dev, "%s: portinfo is NULL\n", __func__); + return -EINVAL; + } + mutex_lock(&swrm->mlock); + + for (i = 0; i < portinfo->num_port; i++) { + + ret = swrm_get_master_port(swrm, &mstr_port_id, &mstr_ch_mask, + portinfo->port_type[i], portinfo->port_id[i]); + if (ret) { + dev_err(&master->dev, + "%s: mstr portid for slv port %d not found\n", + __func__, portinfo->port_id[i]); + mutex_unlock(&swrm->mlock); + return -EINVAL; + } + mport = &(swrm->mport_cfg[mstr_port_id]); + /* get port req */ + port_req = swrm_get_port_req(mport, portinfo->port_id[i], + portinfo->dev_num); + + if (!port_req) { + dev_err(&master->dev, "%s:port not enabled : port %d\n", + __func__, portinfo->port_id[i]); + return -EINVAL; + } + port_req->req_ch &= ~portinfo->ch_en[i]; + mport->req_ch &= ~mstr_ch_mask; + } + master->num_port -= portinfo->num_port; + swr_port_response(master, portinfo->tid); + mutex_unlock(&swrm->mlock); + + return 0; +} + +static int swrm_check_slave_change_status(struct swr_mstr_ctrl *swrm, + int status, u8 *devnum) +{ + int i; + int new_sts = status; + int ret = SWR_NOT_PRESENT; + + if (status != swrm->slave_status) { + for (i = 0; i < (swrm->master.num_dev + 1); i++) { + if ((status & SWRM_MCP_SLV_STATUS_MASK) != + (swrm->slave_status & SWRM_MCP_SLV_STATUS_MASK)) { + ret = (status & SWRM_MCP_SLV_STATUS_MASK); + *devnum = i; + break; + } + status >>= 2; + swrm->slave_status >>= 2; + } + swrm->slave_status = new_sts; + } + return ret; +} + +static irqreturn_t swr_mstr_interrupt(int irq, void *dev) +{ + struct swr_mstr_ctrl *swrm = dev; + u32 value, intr_sts; + int status, chg_sts, i; + u8 devnum = 0; + int ret = IRQ_HANDLED; + struct swr_device *swr_dev; + struct swr_master *mstr = &swrm->master; + + + mutex_lock(&swrm->reslock); + swrm_clk_request(swrm, true); + mutex_unlock(&swrm->reslock); + + intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); + intr_sts &= SWRM_INTERRUPT_STATUS_RMSK; + for (i = 0; i < SWRM_INTERRUPT_MAX; i++) { + value = intr_sts & (1 << i); + if (!value) + continue; + + swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, value); + switch (value) { + case SWRM_INTERRUPT_STATUS_SLAVE_PEND_IRQ: + dev_dbg(swrm->dev, "Trigger irq to slave device\n"); + status = swr_master_read(swrm, SWRM_MCP_SLV_STATUS); + swrm_check_slave_change_status(swrm, status, + &devnum); + list_for_each_entry(swr_dev, &mstr->devices, dev_list) { + if (swr_dev->dev_num != devnum) + continue; + if (swr_dev->slave_irq) + handle_nested_irq(swr_dev->slave_irq); + } + break; + case SWRM_INTERRUPT_STATUS_NEW_SLAVE_ATTACHED: + dev_dbg(swrm->dev, "SWR new slave attached\n"); + break; + case SWRM_INTERRUPT_STATUS_CHANGE_ENUM_SLAVE_STATUS: + status = swr_master_read(swrm, SWRM_MCP_SLV_STATUS); + if (status == swrm->slave_status) { + dev_dbg(swrm->dev, + "%s: No change in slave status: %d\n", + __func__, status); + break; + } + chg_sts = swrm_check_slave_change_status(swrm, status, + &devnum); + switch (chg_sts) { + case SWR_NOT_PRESENT: + dev_dbg(swrm->dev, "device %d got detached\n", + devnum); + break; + case SWR_ATTACHED_OK: + dev_dbg(swrm->dev, "device %d got attached\n", + devnum); + break; + case SWR_ALERT: + dev_dbg(swrm->dev, + "device %d has pending interrupt\n", + devnum); + break; + } + break; + case SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET: + dev_err_ratelimited(swrm->dev, + "SWR bus clsh detected\n"); + break; + case SWRM_INTERRUPT_STATUS_RD_FIFO_OVERFLOW: + dev_dbg(swrm->dev, "SWR read FIFO overflow\n"); + break; + case SWRM_INTERRUPT_STATUS_RD_FIFO_UNDERFLOW: + dev_dbg(swrm->dev, "SWR read FIFO underflow\n"); + break; + case SWRM_INTERRUPT_STATUS_WR_CMD_FIFO_OVERFLOW: + dev_dbg(swrm->dev, "SWR write FIFO overflow\n"); + break; + case SWRM_INTERRUPT_STATUS_CMD_ERROR: + value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS); + dev_err_ratelimited(swrm->dev, + "SWR CMD error, fifo status 0x%x, flushing fifo\n", + value); + swr_master_write(swrm, SWRM_CMD_FIFO_CMD, 0x1); + break; + case SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION: + dev_dbg(swrm->dev, "SWR Port collision detected\n"); + break; + case SWRM_INTERRUPT_STATUS_READ_EN_RD_VALID_MISMATCH: + dev_dbg(swrm->dev, "SWR read enable valid mismatch\n"); + break; + case SWRM_INTERRUPT_STATUS_SPECIAL_CMD_ID_FINISHED: + complete(&swrm->broadcast); + dev_dbg(swrm->dev, "SWR cmd id finished\n"); + break; + case SWRM_INTERRUPT_STATUS_NEW_SLAVE_AUTO_ENUM_FINISHED: + break; + case SWRM_INTERRUPT_STATUS_AUTO_ENUM_FAILED: + break; + case SWRM_INTERRUPT_STATUS_AUTO_ENUM_TABLE_IS_FULL: + break; + case SWRM_INTERRUPT_STATUS_BUS_RESET_FINISHED: + complete(&swrm->reset); + break; + case SWRM_INTERRUPT_STATUS_CLK_STOP_FINISHED: + break; + default: + dev_err_ratelimited(swrm->dev, + "SWR unknown interrupt\n"); + ret = IRQ_NONE; + break; + } + } + + mutex_lock(&swrm->reslock); + swrm_clk_request(swrm, false); + mutex_unlock(&swrm->reslock); + return ret; +} + +static int swrm_get_device_status(struct swr_mstr_ctrl *swrm, u8 devnum) +{ + u32 val; + + swrm->slave_status = swr_master_read(swrm, SWRM_MCP_SLV_STATUS); + val = (swrm->slave_status >> (devnum * 2)); + val &= SWRM_MCP_SLV_STATUS_MASK; + return val; +} + +static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, + u8 *dev_num) +{ + int i; + u64 id = 0; + int ret = -EINVAL; + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(mstr); + struct swr_device *swr_dev; + u32 num_dev = 0; + + if (!swrm) { + pr_err("%s: Invalid handle to swr controller\n", + __func__); + return ret; + } + if (swrm->num_dev) + num_dev = swrm->num_dev; + else + num_dev = mstr->num_dev; + + pm_runtime_get_sync(swrm->dev); + for (i = 1; i < (num_dev + 1); i++) { + id = ((u64)(swr_master_read(swrm, + SWRM_ENUMERATOR_SLAVE_DEV_ID_2(i))) << 32); + id |= swr_master_read(swrm, + SWRM_ENUMERATOR_SLAVE_DEV_ID_1(i)); + /* + * As pm_runtime_get_sync() brings all slaves out of reset + * update logical device number for all slaves. + */ + list_for_each_entry(swr_dev, &mstr->devices, dev_list) { + if (swr_dev->addr == (id & SWR_DEV_ID_MASK)) { + u32 status = swrm_get_device_status(swrm, i); + + if ((status == 0x01) || (status == 0x02)) { + swr_dev->dev_num = i; + if ((id & SWR_DEV_ID_MASK) == dev_id) { + *dev_num = i; + ret = 0; + } + dev_dbg(swrm->dev, + "%s: devnum %d is assigned for dev addr %lx\n", + __func__, i, swr_dev->addr); + } + } + } + } + if (ret) + dev_err(swrm->dev, "%s: device 0x%llx is not ready\n", + __func__, dev_id); + + pm_runtime_mark_last_busy(swrm->dev); + pm_runtime_put_autosuspend(swrm->dev); + return ret; +} +static int swrm_master_init(struct swr_mstr_ctrl *swrm) +{ + int ret = 0; + u32 val; + u8 row_ctrl = SWR_MAX_ROW; + u8 col_ctrl = SWR_MIN_COL; + u8 ssp_period = 1; + u8 retry_cmd_num = 3; + u32 reg[SWRM_MAX_INIT_REG]; + u32 value[SWRM_MAX_INIT_REG]; + int len = 0; + + /* Clear Rows and Cols */ + val = ((row_ctrl << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | + (col_ctrl << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) | + (ssp_period << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT)); + + reg[len] = SWRM_MCP_FRAME_CTRL_BANK_ADDR(0); + value[len++] = val; + + /* Set Auto enumeration flag */ + reg[len] = SWRM_ENUMERATOR_CFG_ADDR; + value[len++] = 1; + + /* Mask soundwire interrupts */ + reg[len] = SWRM_INTERRUPT_MASK_ADDR; + value[len++] = 0x1FFFD; + + /* Configure No pings */ + val = swr_master_read(swrm, SWRM_MCP_CFG_ADDR); + val &= ~SWRM_MCP_CFG_MAX_NUM_OF_CMD_NO_PINGS_BMSK; + val |= (0x1f << SWRM_MCP_CFG_MAX_NUM_OF_CMD_NO_PINGS_SHFT); + reg[len] = SWRM_MCP_CFG_ADDR; + value[len++] = val; + + /* Configure number of retries of a read/write cmd */ + val = (retry_cmd_num << SWRM_CMD_FIFO_CFG_NUM_OF_CMD_RETRY_SHFT); + reg[len] = SWRM_CMD_FIFO_CFG_ADDR; + value[len++] = val; + + /* Set IRQ to PULSE */ + reg[len] = SWRM_COMP_CFG_ADDR; + value[len++] = 0x02; + + reg[len] = SWRM_COMP_CFG_ADDR; + value[len++] = 0x03; + + reg[len] = SWRM_INTERRUPT_CLEAR; + value[len++] = 0x08; + + swr_master_bulk_write(swrm, reg, value, len); + + return ret; +} + +static int swrm_probe(struct platform_device *pdev) +{ + struct swr_mstr_ctrl *swrm; + struct swr_ctrl_platform_data *pdata; + u32 i, num_ports, port_num, port_type, ch_mask; + u32 *temp, map_size, map_length, ch_iter = 0, old_port_num = 0; + int ret = 0; + + /* Allocate soundwire master driver structure */ + swrm = devm_kzalloc(&pdev->dev, sizeof(struct swr_mstr_ctrl), + GFP_KERNEL); + if (!swrm) { + ret = -ENOMEM; + goto err_memory_fail; + } + swrm->dev = &pdev->dev; + platform_set_drvdata(pdev, swrm); + swr_set_ctrl_data(&swrm->master, swrm); + pdata = dev_get_platdata(&pdev->dev); + if (!pdata) { + dev_err(&pdev->dev, "%s: pdata from parent is NULL\n", + __func__); + ret = -EINVAL; + goto err_pdata_fail; + } + swrm->handle = (void *)pdata->handle; + if (!swrm->handle) { + dev_err(&pdev->dev, "%s: swrm->handle is NULL\n", + __func__); + ret = -EINVAL; + goto err_pdata_fail; + } + if (!(of_property_read_u32(pdev->dev.of_node, "swrm-io-base", NULL))) + swrm->swrm_base_reg = of_property_read_u32(pdev->dev.of_node, + "swrm-io-base", &swrm->swrm_base_reg); + if (!swrm->swrm_base_reg) { + swrm->read = pdata->read; + if (!swrm->read) { + dev_err(&pdev->dev, "%s: swrm->read is NULL\n", + __func__); + ret = -EINVAL; + goto err_pdata_fail; + } + swrm->write = pdata->write; + if (!swrm->write) { + dev_err(&pdev->dev, "%s: swrm->write is NULL\n", + __func__); + ret = -EINVAL; + goto err_pdata_fail; + } + swrm->bulk_write = pdata->bulk_write; + if (!swrm->bulk_write) { + dev_err(&pdev->dev, "%s: swrm->bulk_write is NULL\n", + __func__); + ret = -EINVAL; + goto err_pdata_fail; + } + } else { + swrm->swrm_dig_base = devm_ioremap(&pdev->dev, + swrm->swrm_base_reg, SWRM_MAX_REGISTER); + } + + swrm->clk = pdata->clk; + if (!swrm->clk) { + dev_err(&pdev->dev, "%s: swrm->clk is NULL\n", + __func__); + ret = -EINVAL; + goto err_pdata_fail; + } + + /* Parse soundwire port mapping */ + ret = of_property_read_u32(pdev->dev.of_node, "qcom,swr-num-ports", + &num_ports); + if (ret) { + dev_err(swrm->dev, "%s: Failed to get num_ports\n", __func__); + goto err_pdata_fail; + } + swrm->num_ports = num_ports; + + if (!of_find_property(pdev->dev.of_node, "qcom,swr-port-mapping", + &map_size)) { + dev_err(swrm->dev, "missing port mapping\n"); + goto err_pdata_fail; + } + + map_length = map_size / (3 * sizeof(u32)); + if (num_ports > SWR_MSTR_PORT_LEN) { + dev_err(&pdev->dev, "%s:invalid number of swr ports\n", + __func__); + ret = -EINVAL; + goto err_pdata_fail; + } + temp = devm_kzalloc(&pdev->dev, map_size, GFP_KERNEL); + + if (!temp) { + ret = -ENOMEM; + goto err_pdata_fail; + } + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,swr-port-mapping", temp, 3 * map_length); + if (ret) { + dev_err(swrm->dev, "%s: Failed to read port mapping\n", + __func__); + goto err_pdata_fail; + } + + for (i = 0; i < map_length; i++) { + port_num = temp[3 * i]; + port_type = temp[3 * i + 1]; + ch_mask = temp[3 * i + 2]; + + if (port_num != old_port_num) + ch_iter = 0; + swrm->port_mapping[port_num][ch_iter].port_type = port_type; + swrm->port_mapping[port_num][ch_iter++].ch_mask = ch_mask; + old_port_num = port_num; + } + devm_kfree(&pdev->dev, temp); + + swrm->reg_irq = pdata->reg_irq; + swrm->master.read = swrm_read; + swrm->master.write = swrm_write; + swrm->master.bulk_write = swrm_bulk_write; + swrm->master.get_logical_dev_num = swrm_get_logical_dev_num; + swrm->master.connect_port = swrm_connect_port; + swrm->master.disconnect_port = swrm_disconnect_port; + swrm->master.slvdev_datapath_control = swrm_slvdev_datapath_control; + swrm->master.remove_from_group = swrm_remove_from_group; + swrm->master.dev.parent = &pdev->dev; + swrm->master.dev.of_node = pdev->dev.of_node; + swrm->master.num_port = 0; + swrm->rcmd_id = 0; + swrm->wcmd_id = 0; + swrm->slave_status = 0; + swrm->num_rx_chs = 0; + swrm->clk_ref_count = 0; + swrm->state = SWR_MSTR_RESUME; + init_completion(&swrm->reset); + init_completion(&swrm->broadcast); + mutex_init(&swrm->mlock); + mutex_init(&swrm->reslock); + mutex_init(&swrm->force_down_lock); + + for (i = 0 ; i < SWR_MSTR_PORT_LEN; i++) + INIT_LIST_HEAD(&swrm->mport_cfg[i].port_req_list); + + if (swrm->reg_irq) { + ret = swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, + SWR_IRQ_REGISTER); + if (ret) { + dev_err(&pdev->dev, "%s: IRQ register failed ret %d\n", + __func__, ret); + goto err_irq_fail; + } + } else { + swrm->irq = platform_get_irq_byname(pdev, "swr_master_irq"); + if (swrm->irq < 0) { + dev_err(swrm->dev, "%s() error getting irq hdle: %d\n", + __func__, swrm->irq); + goto err_pdata_fail; + } + + ret = request_threaded_irq(swrm->irq, NULL, + swr_mstr_interrupt, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "swr_master_irq", swrm); + if (ret) { + dev_err(swrm->dev, "%s: Failed to request irq %d\n", + __func__, ret); + goto err_irq_fail; + } + + } + + ret = swr_register_master(&swrm->master); + if (ret) { + dev_err(&pdev->dev, "%s: error adding swr master\n", __func__); + goto err_mstr_fail; + } + + /* Add devices registered with board-info as the + * controller will be up now + */ + swr_master_add_boarddevices(&swrm->master); + mutex_lock(&swrm->mlock); + swrm_clk_request(swrm, true); + ret = swrm_master_init(swrm); + if (ret < 0) { + dev_err(&pdev->dev, + "%s: Error in master Initialization , err %d\n", + __func__, ret); + mutex_unlock(&swrm->mlock); + goto err_mstr_fail; + } + swrm->version = swr_master_read(swrm, SWRM_COMP_HW_VERSION); + + mutex_unlock(&swrm->mlock); + + if (pdev->dev.of_node) + of_register_swr_devices(&swrm->master); + + dbgswrm = swrm; + debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0); + if (!IS_ERR(debugfs_swrm_dent)) { + debugfs_peek = debugfs_create_file("swrm_peek", + S_IFREG | 0444, debugfs_swrm_dent, + (void *) "swrm_peek", &swrm_debug_ops); + + debugfs_poke = debugfs_create_file("swrm_poke", + S_IFREG | 0444, debugfs_swrm_dent, + (void *) "swrm_poke", &swrm_debug_ops); + + debugfs_reg_dump = debugfs_create_file("swrm_reg_dump", + S_IFREG | 0444, debugfs_swrm_dent, + (void *) "swrm_reg_dump", + &swrm_debug_ops); + } + pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + pm_runtime_mark_last_busy(&pdev->dev); + + return 0; +err_mstr_fail: + if (swrm->reg_irq) + swrm->reg_irq(swrm->handle, swr_mstr_interrupt, + swrm, SWR_IRQ_FREE); + else if (swrm->irq) + free_irq(swrm->irq, swrm); +err_irq_fail: + mutex_destroy(&swrm->mlock); + mutex_destroy(&swrm->reslock); + mutex_destroy(&swrm->force_down_lock); +err_pdata_fail: +err_memory_fail: + return ret; +} + +static int swrm_remove(struct platform_device *pdev) +{ + struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); + + if (swrm->reg_irq) + swrm->reg_irq(swrm->handle, swr_mstr_interrupt, + swrm, SWR_IRQ_FREE); + else if (swrm->irq) + free_irq(swrm->irq, swrm); + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + swr_unregister_master(&swrm->master); + mutex_destroy(&swrm->mlock); + mutex_destroy(&swrm->reslock); + mutex_destroy(&swrm->force_down_lock); + devm_kfree(&pdev->dev, swrm); + return 0; +} + +static int swrm_clk_pause(struct swr_mstr_ctrl *swrm) +{ + u32 val; + + dev_dbg(swrm->dev, "%s: state: %d\n", __func__, swrm->state); + swr_master_write(swrm, SWRM_INTERRUPT_MASK_ADDR, 0x1FDFD); + val = swr_master_read(swrm, SWRM_MCP_CFG_ADDR); + val |= SWRM_MCP_CFG_BUS_CLK_PAUSE_BMSK; + swr_master_write(swrm, SWRM_MCP_CFG_ADDR, val); + swrm->state = SWR_MSTR_PAUSE; + + return 0; +} + +#ifdef CONFIG_PM +static int swrm_runtime_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); + int ret = 0; + struct swr_master *mstr = &swrm->master; + struct swr_device *swr_dev; + + dev_dbg(dev, "%s: pm_runtime: resume, state:%d\n", + __func__, swrm->state); + mutex_lock(&swrm->reslock); + if ((swrm->state == SWR_MSTR_PAUSE) || + (swrm->state == SWR_MSTR_DOWN)) { + if (swrm->state == SWR_MSTR_DOWN) { + if (swrm_clk_request(swrm, true)) + goto exit; + } + list_for_each_entry(swr_dev, &mstr->devices, dev_list) { + ret = swr_device_up(swr_dev); + if (ret) { + dev_err(dev, + "%s: failed to wakeup swr dev %d\n", + __func__, swr_dev->dev_num); + swrm_clk_request(swrm, false); + goto exit; + } + } + swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01); + swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01); + swrm_master_init(swrm); + } +exit: + pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer); + mutex_unlock(&swrm->reslock); + return ret; +} + +static int swrm_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); + int ret = 0; + struct swr_master *mstr = &swrm->master; + struct swr_device *swr_dev; + int current_state = 0; + + dev_dbg(dev, "%s: pm_runtime: suspend state: %d\n", + __func__, swrm->state); + mutex_lock(&swrm->reslock); + mutex_lock(&swrm->force_down_lock); + current_state = swrm->state; + mutex_unlock(&swrm->force_down_lock); + if ((current_state == SWR_MSTR_RESUME) || + (current_state == SWR_MSTR_UP) || + (current_state == SWR_MSTR_SSR)) { + + if ((current_state != SWR_MSTR_SSR) && + swrm_is_port_en(&swrm->master)) { + dev_dbg(dev, "%s ports are enabled\n", __func__); + ret = -EBUSY; + goto exit; + } + swrm_clk_pause(swrm); + swr_master_write(swrm, SWRM_COMP_CFG_ADDR, 0x00); + list_for_each_entry(swr_dev, &mstr->devices, dev_list) { + ret = swr_device_down(swr_dev); + if (ret) { + dev_err(dev, + "%s: failed to shutdown swr dev %d\n", + __func__, swr_dev->dev_num); + goto exit; + } + } + swrm_clk_request(swrm, false); + } +exit: + mutex_unlock(&swrm->reslock); + return ret; +} +#endif /* CONFIG_PM */ + +static int swrm_device_down(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); + int ret = 0; + + dev_dbg(dev, "%s: swrm state: %d\n", __func__, swrm->state); + + mutex_lock(&swrm->force_down_lock); + swrm->state = SWR_MSTR_SSR; + mutex_unlock(&swrm->force_down_lock); + /* Use pm runtime function to tear down */ + ret = pm_runtime_put_sync_suspend(dev); + pm_runtime_get_noresume(dev); + + return ret; +} + +/** + * swrm_wcd_notify - parent device can notify to soundwire master through + * this function + * @pdev: pointer to platform device structure + * @id: command id from parent to the soundwire master + * @data: data from parent device to soundwire master + */ +int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) +{ + struct swr_mstr_ctrl *swrm; + int ret = 0; + struct swr_master *mstr; + struct swr_device *swr_dev; + + if (!pdev) { + pr_err("%s: pdev is NULL\n", __func__); + return -EINVAL; + } + swrm = platform_get_drvdata(pdev); + if (!swrm) { + dev_err(&pdev->dev, "%s: swrm is NULL\n", __func__); + return -EINVAL; + } + mstr = &swrm->master; + + switch (id) { + case SWR_DEVICE_DOWN: + dev_dbg(swrm->dev, "%s: swr master down called\n", __func__); + mutex_lock(&swrm->mlock); + if ((swrm->state == SWR_MSTR_PAUSE) || + (swrm->state == SWR_MSTR_DOWN)) + dev_dbg(swrm->dev, "%s:SWR master is already Down:%d\n", + __func__, swrm->state); + else + swrm_device_down(&pdev->dev); + mutex_unlock(&swrm->mlock); + break; + case SWR_DEVICE_UP: + dev_dbg(swrm->dev, "%s: swr master up called\n", __func__); + mutex_lock(&swrm->mlock); + mutex_lock(&swrm->reslock); + if ((swrm->state == SWR_MSTR_RESUME) || + (swrm->state == SWR_MSTR_UP)) { + dev_dbg(swrm->dev, "%s: SWR master is already UP: %d\n", + __func__, swrm->state); + } else { + pm_runtime_mark_last_busy(&pdev->dev); + mutex_unlock(&swrm->reslock); + pm_runtime_get_sync(&pdev->dev); + mutex_lock(&swrm->reslock); + list_for_each_entry(swr_dev, &mstr->devices, dev_list) { + ret = swr_reset_device(swr_dev); + if (ret) { + dev_err(swrm->dev, + "%s: failed to reset swr device %d\n", + __func__, swr_dev->dev_num); + swrm_clk_request(swrm, false); + } + } + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_put_autosuspend(&pdev->dev); + } + mutex_unlock(&swrm->reslock); + mutex_unlock(&swrm->mlock); + break; + case SWR_SET_NUM_RX_CH: + if (!data) { + dev_err(swrm->dev, "%s: data is NULL\n", __func__); + ret = -EINVAL; + } else { + mutex_lock(&swrm->mlock); + swrm->num_rx_chs = *(int *)data; + if ((swrm->num_rx_chs > 1) && !swrm->num_cfg_devs) { + list_for_each_entry(swr_dev, &mstr->devices, + dev_list) { + ret = swr_set_device_group(swr_dev, + SWR_BROADCAST); + if (ret) + dev_err(swrm->dev, + "%s: set num ch failed\n", + __func__); + } + } else { + list_for_each_entry(swr_dev, &mstr->devices, + dev_list) { + ret = swr_set_device_group(swr_dev, + SWR_GROUP_NONE); + if (ret) + dev_err(swrm->dev, + "%s: set num ch failed\n", + __func__); + } + } + mutex_unlock(&swrm->mlock); + } + break; + default: + dev_err(swrm->dev, "%s: swr master unknown id %d\n", + __func__, id); + break; + } + return ret; +} +EXPORT_SYMBOL(swrm_wcd_notify); + +#ifdef CONFIG_PM_SLEEP +static int swrm_suspend(struct device *dev) +{ + int ret = -EBUSY; + struct platform_device *pdev = to_platform_device(dev); + struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); + + dev_dbg(dev, "%s: system suspend, state: %d\n", __func__, swrm->state); + if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) { + ret = swrm_runtime_suspend(dev); + if (!ret) { + /* + * Synchronize runtime-pm and system-pm states: + * At this point, we are already suspended. If + * runtime-pm still thinks its active, then + * make sure its status is in sync with HW + * status. The three below calls let the + * runtime-pm know that we are suspended + * already without re-invoking the suspend + * callback + */ + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + pm_runtime_enable(dev); + } + } + if (ret == -EBUSY) { + /* + * There is a possibility that some audio stream is active + * during suspend. We dont want to return suspend failure in + * that case so that display and relevant components can still + * go to suspend. + * If there is some other error, then it should be passed-on + * to system level suspend + */ + ret = 0; + } + return ret; +} + +static int swrm_resume(struct device *dev) +{ + int ret = 0; + struct platform_device *pdev = to_platform_device(dev); + struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); + + dev_dbg(dev, "%s: system resume, state: %d\n", __func__, swrm->state); + if (!pm_runtime_enabled(dev) || !pm_runtime_suspend(dev)) { + ret = swrm_runtime_resume(dev); + if (!ret) { + pm_runtime_mark_last_busy(dev); + pm_request_autosuspend(dev); + } + } + return ret; +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops swrm_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS( + swrm_suspend, + swrm_resume + ) + SET_RUNTIME_PM_OPS( + swrm_runtime_suspend, + swrm_runtime_resume, + NULL + ) +}; + +static const struct of_device_id swrm_dt_match[] = { + { + .compatible = "qcom,swr-mstr", + }, + {} +}; + +static struct platform_driver swr_mstr_driver = { + .probe = swrm_probe, + .remove = swrm_remove, + .driver = { + .name = SWR_WCD_NAME, + .owner = THIS_MODULE, + .pm = &swrm_dev_pm_ops, + .of_match_table = swrm_dt_match, + }, +}; + +static int __init swrm_init(void) +{ + return platform_driver_register(&swr_mstr_driver); +} +module_init(swrm_init); + +static void __exit swrm_exit(void) +{ + platform_driver_unregister(&swr_mstr_driver); +} +module_exit(swrm_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("SoundWire Master Controller"); +MODULE_ALIAS("platform:swr-mstr"); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h new file mode 100644 index 000000000000..75d79c23ceb0 --- /dev/null +++ b/soc/swr-mstr-ctrl.h @@ -0,0 +1,135 @@ +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SWR_WCD_CTRL_H +#define _SWR_WCD_CTRL_H +#include +#include + +#define SWR_MAX_ROW 0 /* Rows = 48 */ +#define SWR_MAX_COL 7 /* Cols = 16 */ +#define SWR_MIN_COL 0 /* Cols = 2 */ + +#define SWR_WCD_NAME "swr-wcd" + +#define SWR_MSTR_PORT_LEN 8 /* Number of master ports */ + +#define SWRM_VERSION_1_0 0x01010000 +#define SWRM_VERSION_1_2 0x01030000 +#define SWRM_VERSION_1_3 0x01040000 +#define SWRM_VERSION_1_5 0x01050000 + +#define SWR_MAX_CH_PER_PORT 8 + + +enum { + SWR_MSTR_PAUSE, + SWR_MSTR_RESUME, + SWR_MSTR_UP, + SWR_MSTR_DOWN, + SWR_MSTR_SSR, +}; + +enum { + SWR_IRQ_FREE, + SWR_IRQ_REGISTER, +}; + +enum { + SWR_DAC_PORT, + SWR_COMP_PORT, + SWR_BOOST_PORT, + SWR_VISENSE_PORT, +}; + +struct usecase { + u8 num_port; + u8 num_ch; + u32 chrate; +}; + +struct port_params { + u8 si; + u8 off1; + u8 off2; +}; + +struct swrm_mports { + struct list_head port_req_list; + bool port_en; + u8 ch_en; + u8 req_ch; + u8 ch_rate; + u8 offset1; + u8 offset2; + u8 sinterval; + u8 hstart; + u8 hstop; + u8 blk_grp_count; + u8 blk_pack_mode; +}; + +struct swrm_port_type { + u8 port_type; + u8 ch_mask; +}; + +struct swr_ctrl_platform_data { + void *handle; /* holds priv data */ + int (*read)(void *handle, int reg); + int (*write)(void *handle, int reg, int val); + int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); + int (*clk)(void *handle, bool enable); + int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq, + void *data), void *swr_handle, int type); +}; + +struct swr_mstr_ctrl { + struct swr_master master; + struct device *dev; + struct resource *supplies; + struct clk *mclk; + int clk_ref_count; + struct completion reset; + struct completion broadcast; + struct mutex mlock; + struct mutex reslock; + u32 swrm_base_reg; + char __iomem *swrm_dig_base; + u8 rcmd_id; + u8 wcmd_id; + void *handle; /* SWR Master handle from client for read and writes */ + int (*read)(void *handle, int reg); + int (*write)(void *handle, int reg, int val); + int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); + int (*clk)(void *handle, bool enable); + int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq, + void *data), void *swr_handle, int type); + int irq; + int version; + u32 num_dev; + int slave_status; + struct swrm_mports mport_cfg[SWR_MAX_MSTR_PORT_NUM]; + struct list_head port_req_list; + int state; + struct platform_device *pdev; + int num_rx_chs; + u8 num_cfg_devs; + struct mutex force_down_lock; + int force_down_state; + u8 num_ports; + struct swrm_port_type + port_mapping[SWR_MSTR_PORT_LEN][SWR_MAX_CH_PER_PORT]; + int swr_irq; +}; + +#endif /* _SWR_WCD_CTRL_H */ diff --git a/soc/swrm_port_config.h b/soc/swrm_port_config.h new file mode 100644 index 000000000000..64ff6002fcc6 --- /dev/null +++ b/soc/swrm_port_config.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2018 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SWRM_PORT_CONFIG +#define _SWRM_PORT_CONFIG + +#define WSA_MSTR_PORT_MASK 0xFF + +struct port_params wsa_frame_superset[SWR_MSTR_PORT_LEN] = { + {7, 1, 0}, + {31, 2, 0}, + {63, 12, 31}, + {7, 6, 0}, + {31, 18, 0}, + {63, 13, 31}, + {15, 7, 0}, + {15, 10, 0}, +}; + +#endif /* _SWRM_REGISTERS_H */ -- GitLab From d66cc71409189b2c7393eb12028daff181aa928e Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 18 Jun 2018 11:59:09 +0530 Subject: [PATCH 0329/1645] dsp: Fix rtac memory unmap issue in ASM driver During unmap of rtac block in ASM, mem_map_handle address is set to zero instead of the value. Set the map handle value to zero to avoid issue in freeing the ion memory. CRs-Fixed: 2254339 Change-Id: I6584be029d4c8dde235e722149c758df0db9916e Signed-off-by: Aditya Bavanari --- dsp/q6asm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 38ddc88b0f24..0569d1572bec 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -952,7 +952,7 @@ int q6asm_unmap_rtac_block(uint32_t *mem_map_handle) __func__, result2); result = result2; } else { - mem_map_handle = 0; + *mem_map_handle = 0; } result2 = q6asm_mmap_apr_dereg(); -- GitLab From 43c1a132f2a89dc922651e5306bb65f786fe7aa3 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 15 Jun 2018 13:18:07 +0530 Subject: [PATCH 0330/1645] asoc: ext-clk: Allow clock probe without pinctrl for lpass nodes Currently audio ref clock probe for lpass clock nodes require pinctrl entry as mandatory. For bolero lpass clocks, there is no pinctrl required. Allow audio ref clock probe to proceed with pinctrl based on property of use-pinctrl set to non-zero value from dtsi. Change-Id: Ide4a10e89672f0adefd2e0d99830c38191119dfc Signed-off-by: Laxminath Kasam --- asoc/codecs/audio-ext-clk-up.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index d20aab2c83b2..1b0b2198464c 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -169,12 +169,6 @@ static int audio_get_pinctrl(struct platform_device *pdev) int ret; u32 reg; - if (clk_priv->clk_src == AUDIO_EXT_CLK_LNBB2) { - dev_dbg(dev, "%s no pinctrl for clk_src = %d\n", - __func__, clk_priv->clk_src); - return 0; - } - pnctrl_info = &clk_priv->audio_clk.pnctrl_info; if (pnctrl_info->pinctrl) { dev_err(dev, "%s: already requested before\n", @@ -286,8 +280,7 @@ static int audio_ref_clk_probe(struct platform_device *pdev) { int ret; struct audio_ext_clk_priv *clk_priv; - u32 clk_freq = 0, clk_id = 0, clk_src = 0; - + u32 clk_freq = 0, clk_id = 0, clk_src = 0, use_pinctrl = 0; clk_priv = devm_kzalloc(&pdev->dev, sizeof(*clk_priv), GFP_KERNEL); if (!clk_priv) @@ -336,11 +329,22 @@ static int audio_ref_clk_probe(struct platform_device *pdev) clk_priv->clk_cfg.clk_id, clk_priv->clk_src); platform_set_drvdata(pdev, clk_priv); - ret = audio_get_pinctrl(pdev); - if (ret) { - dev_err(&pdev->dev, "%s: Parsing PMI pinctrl failed\n", - __func__); - return ret; + /* + * property qcom,use-pinctrl to be defined in DTSI to val 1 + * for clock nodes using pinctrl + */ + of_property_read_u32(pdev->dev.of_node, "qcom,use-pinctrl", + &use_pinctrl); + dev_dbg(&pdev->dev, "%s: use-pinctrl : %d\n", + __func__, use_pinctrl); + + if (use_pinctrl) { + ret = audio_get_pinctrl(pdev); + if (ret) { + dev_err(&pdev->dev, "%s: Parsing PMI pinctrl failed\n", + __func__); + return ret; + } } ret = audio_get_clk_data(pdev); -- GitLab From 8d34b2e801b1d983b3759d7d5459204338021392 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 23 May 2018 06:34:36 +0530 Subject: [PATCH 0331/1645] ASoC: Add support for audio drivers compilation on kernel-4.14 Add support for audio drivers compilation on kernel-4.14. Change-Id: Id7689cef4ae7cdb6711fed386d2a6b0d427b3fc3 Signed-off-by: Sudheer Papothi --- Makefile | 4 ++-- asoc/Kbuild | 3 +-- asoc/codecs/Kbuild | 2 +- dsp/Kbuild | 16 ++++++++-------- dsp/codecs/Kbuild | 2 +- ipc/Kbuild | 25 +------------------------ soc/Kbuild | 2 +- 7 files changed, 15 insertions(+), 39 deletions(-) diff --git a/Makefile b/Makefile index fbf0ee1eab5e..159b68cd0e14 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ LINUXINCLUDE += \ -include $(srctree)/techpack/audio/config/sm8150autoconf.h endif -obj-y += asoc/ +obj-y += soc/ obj-y += dsp/ obj-y += ipc/ -obj-y += soc/ +obj-y += asoc/ diff --git a/asoc/Kbuild b/asoc/Kbuild index 0211013647e7..ccf2406d42bb 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -6,11 +6,10 @@ else KERNEL_BUILD := 0 endif - ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 84e4a47d4bb2..f4c9c106ab15 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -9,7 +9,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/dsp/Kbuild b/dsp/Kbuild index 1452221174ac..271fae463680 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -9,7 +9,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif @@ -111,14 +111,14 @@ ifdef CONFIG_MSM_ADSP_LOADER ADSP_LOADER_OBJS += adsp-loader.o endif -ifdef CONFIG_MSM_QDSP6_NOTIFIER -QDSP6_NOTIFIER_OBJS += audio_notifier.o audio_ssr.o -endif - ifdef CONFIG_MSM_QDSP6_PDR QDSP6_PDR_OBJS += audio_pdr.o endif +ifdef CONFIG_MSM_QDSP6_NOTIFIER +QDSP6_NOTIFIER_OBJS += audio_notifier.o audio_ssr.o +endif + ifdef CONFIG_MSM_ULTRASOUND USF_OBJS += usf.o usfcdev.o q6usm.o endif @@ -184,11 +184,11 @@ usf_dlkm-y := $(USF_OBJS) obj-$(CONFIG_MSM_ADSP_LOADER) += adsp_loader_dlkm.o adsp_loader_dlkm-y := $(ADSP_LOADER_OBJS) -obj-$(CONFIG_MSM_QDSP6_NOTIFIER) += q6_notifier_dlkm.o -q6_notifier_dlkm-y := $(QDSP6_NOTIFIER_OBJS) - obj-$(CONFIG_MSM_QDSP6_PDR) += q6_pdr_dlkm.o q6_pdr_dlkm-y := $(QDSP6_PDR_OBJS) +obj-$(CONFIG_MSM_QDSP6_NOTIFIER) += q6_notifier_dlkm.o +q6_notifier_dlkm-y := $(QDSP6_NOTIFIER_OBJS) + # inject some build related information DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 81367198e781..a65ec46275d8 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -9,7 +9,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/ipc/Kbuild b/ipc/Kbuild index 35e785088cf2..acb60a9284bf 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -6,32 +6,9 @@ else KERNEL_BUILD := 0 endif -TARGET_KERNEL_VERSION := 4.9 - # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds -ifeq ($(CONFIG_ARCH_SDM845), y) - TARGET_KERNEL_VERSION := 4.9 -endif -ifeq ($(CONFIG_ARCH_SDM670), y) - TARGET_KERNEL_VERSION := 4.9 -endif -ifeq ($(CONFIG_ARCH_SM8150), y) - TARGET_KERNEL_VERSION := 4.14 -endif -ifeq ($(CONFIG_ARCH_SM6150), y) - TARGET_KERNEL_VERSION := 4.14 -endif - -ifeq ($(CONFIG_ARCH_QCS405), y) - TARGET_KERNEL_VERSION := 4.14 -endif - -ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) - TARGET_KERNEL_VERSION := 4.14 -endif - -KDIR := $(TOP)/kernel/msm-$(TARGET_KERNEL_VERSION) +KDIR := $(TOP)/kernel/msm-4.14 ifeq ($(KERNEL_BUILD), 1) AUDIO_ROOT := $(KDIR)/techpack/audio diff --git a/soc/Kbuild b/soc/Kbuild index aee1a1fb6801..47b416285447 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -9,7 +9,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif -- GitLab From 1f6b04af93a421e56d5e6e1d1cb6b7336687d78b Mon Sep 17 00:00:00 2001 From: Bhalchandra Gajare Date: Thu, 7 Jun 2018 14:27:44 -0700 Subject: [PATCH 0332/1645] uapi: lsm_params: add support for lsm version 3.0 Listen v3.0 adds new algorithm and multichannel support. The input and output of LSM could have different media format, especially number of channels. Add required support to obtain input hardware params from userspace. Existing pcm_hw_params operations will be used to obtain the lsm output hw params. Change-Id: I3feca50b4b13ece59ceb39787199e2cec17b3cae Signed-off-by: Bhalchandra Gajare --- include/uapi/sound/lsm_params.h | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/include/uapi/sound/lsm_params.h b/include/uapi/sound/lsm_params.h index 67dc36f0cd3b..3c28baacd5b1 100644 --- a/include/uapi/sound/lsm_params.h +++ b/include/uapi/sound/lsm_params.h @@ -7,7 +7,7 @@ #include #include -#define SNDRV_LSM_VERSION SNDRV_PROTOCOL_VERSION(0, 1, 0) +#define SNDRV_LSM_VERSION SNDRV_PROTOCOL_VERSION(0, 3, 0) #define LSM_OUT_FORMAT_PCM (0) #define LSM_OUT_FORMAT_ADPCM (1 << 0) @@ -38,6 +38,18 @@ #define LSM_DET_EVENT_TYPE_LEGACY (0) #define LSM_DET_EVENT_TYPE_GENERIC (1) +/* Valid sample rates for input hw_params */ +#define LSM_INPUT_SAMPLE_RATE_16K 16000 +#define LSM_INPUT_SAMPLE_RATE_48K 48000 + +/* Valid bit-widths for input hw_params */ +#define LSM_INPUT_BIT_WIDTH_16 16 +#define LSM_INPUT_BIT_WIDTH_24 24 + +/* Min and Max channels for input hw_params */ +#define LSM_INPUT_NUM_CHANNELS_MIN 1 +#define LSM_INPUT_NUM_CHANNELS_MAX 9 + enum lsm_app_id { LSM_VOICE_WAKEUP_APP_ID = 1, LSM_VOICE_WAKEUP_APP_ID_V2 = 2, @@ -189,6 +201,22 @@ struct snd_lsm_output_format_cfg { __u8 mode; }; +/* + * Data passed to SNDRV_LSM_SET_INPUT_HW_PARAMS ioctl + * + * @sample_rate: Sample rate of input to lsm. + * valid values are 16000 and 48000 + * @bit_width: Bit width of audio samples input to lsm. + * valid values are 16 and 24 + * @num_channels: Number of channels input to lsm. + * valid values are range from 1 to 16 + */ +struct snd_lsm_input_hw_params { + __u32 sample_rate; + __u16 bit_width; + __u16 num_channels; +} __packed; + #define SNDRV_LSM_DEREG_SND_MODEL _IOW('U', 0x01, int) #define SNDRV_LSM_EVENT_STATUS _IOW('U', 0x02, struct snd_lsm_event_status) #define SNDRV_LSM_ABORT_EVENT _IOW('U', 0x03, int) @@ -210,5 +238,7 @@ struct snd_lsm_output_format_cfg { #define SNDRV_LSM_EVENT_STATUS_V3 _IOW('U', 0x0F, \ struct snd_lsm_event_status_v3) #define SNDRV_LSM_GENERIC_DET_EVENT _IOW('U', 0x10, struct snd_lsm_event_status) +#define SNDRV_LSM_SET_INPUT_HW_PARAMS _IOW('U', 0x11, \ + struct snd_lsm_input_hw_params) #endif -- GitLab From e80ab29892a3ea7d601405e86afdff21226dbf94 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 13 Jun 2018 07:00:59 +0530 Subject: [PATCH 0333/1645] asoc: swr: Add config flag for New soundiwre driver compilation Add new kconfig to control compilation of new soundwire driver Change-Id: I6eb8b30de9f6dc2ffa152b6dfffbc2b02d0a990c Signed-off-by: Ramprasad Katkam --- soc/Kbuild | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/soc/Kbuild b/soc/Kbuild index aee1a1fb6801..f04631b7acd4 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -92,6 +92,11 @@ ifdef CONFIG_SOUNDWIRE_WCD_CTRL SWR_CTRL_OBJS += swr-wcd-ctrl.o endif +# for new soundwire driver +ifdef CONFIG_SOUNDWIRE_MSTR_CTRL + SWR_CTRL_OBJS += swr-mstr-ctrl.o +endif + ifdef CONFIG_SOUNDWIRE SWR_OBJS += regmap-swr.o SWR_OBJS += soundwire.o -- GitLab From 75a24ba3cdefd02df757d492175e2ffa2d4c4899 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 13 Jun 2018 12:32:32 +0530 Subject: [PATCH 0334/1645] asoc: config: Update qsc405 config for new soundwire driver Update vipertooth auto conf files to include new soundwire master Change-Id: I1854e392cc376aec0eb36147231a8e38127b4102 Signed-off-by: Ramprasad Katkam --- config/qcs405auto.conf | 2 +- config/qcs405autoconf.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/qcs405auto.conf b/config/qcs405auto.conf index 127311dbb441..a85c0ed5d685 100644 --- a/config/qcs405auto.conf +++ b/config/qcs405auto.conf @@ -4,7 +4,7 @@ CONFIG_AUDIO_EXT_CLK=m CONFIG_SND_SOC_WCD9XXX_V2=m CONFIG_SND_SOC_WSA881X=m CONFIG_SND_SOC_WCD_DSP_MGR=m -CONFIG_SOUNDWIRE_WCD_CTRL=m +CONFIG_SOUNDWIRE_MSTR_CTRL=m CONFIG_WCD9XXX_CODEC_CORE=m CONFIG_MSM_CDC_PINCTRL=m CONFIG_SND_SOC_WCD9335=m diff --git a/config/qcs405autoconf.h b/config/qcs405autoconf.h index 0bb0463032c5..b76193e2517c 100644 --- a/config/qcs405autoconf.h +++ b/config/qcs405autoconf.h @@ -37,7 +37,7 @@ #define CONFIG_MSM_GLINK_SPI_XPRT 1 #define CONFIG_WCD_DSP_GLINK 1 #define CONFIG_SOUNDWIRE 1 -#define CONFIG_SOUNDWIRE_WCD_CTRL 1 +#define CONFIG_SOUNDWIRE_MSTR_CTRL 1 #define CONFIG_SND_SOC_WCD_MBHC_LEGACY 1 #define CONFIG_SND_SOC_QDSP6V2 1 #define CONFIG_QTI_PP 1 -- GitLab From d7ec18ce76066da3280b31f6ce0b1faf00f0f08b Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 13 Jun 2018 20:34:10 +0530 Subject: [PATCH 0335/1645] soc: pinctrl-lpi: Add support to read lpi offset from device tree In order to support variable lpi offsets from different chipsets read the lpi offset values of gpio groups from device tree. Any target which uses LPI has to define this gpio offset table in device tree. Change-Id: I3bd54017e4571deb9a189cfd6903698887a6413a Signed-off-by: Aditya Bavanari --- soc/pinctrl-lpi.c | 43 +++++++++---------------------------------- 1 file changed, 9 insertions(+), 34 deletions(-) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index 07a582e2e4de..f5ba3d64ad67 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -105,40 +105,8 @@ static const char *const lpi_gpio_groups[] = { "gpio29", "gpio30", "gpio31", }; -static const u32 lpi_offset[] = { - 0x00000000, - 0x00001000, - 0x00002000, - 0x00003000, - 0x00004000, - 0x00005000, - 0x00006000, - 0x00007000, - 0x00008000, - 0x00009000, - 0x0000A000, - 0x0000B000, - 0x0000C000, - 0x0000D000, - 0x0000E000, - 0x0000F000, - 0x00010000, - 0x00011000, - 0x00012000, - 0x00013000, - 0x00014000, - 0x00015000, - 0x00016000, - 0x00017000, - 0x00018000, - 0x00019000, - 0x0001A000, - 0x0001B000, - 0x0001C000, - 0x0001D000, - 0x0001E000, - 0x0001F000, -}; +#define LPI_TLMM_MAX_PINS 100 +static u32 lpi_offset[LPI_TLMM_MAX_PINS]; static const char *const lpi_gpio_functions[] = { [LPI_GPIO_FUNC_INDEX_GPIO] = LPI_GPIO_FUNC_GPIO, @@ -531,6 +499,13 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) WARN_ON(npins > ARRAY_SIZE(lpi_gpio_groups)); + ret = of_property_read_u32_array(dev->of_node, "qcom,lpi-offset-tbl", + lpi_offset, npins); + if (ret < 0) { + dev_err(dev, "error in reading lpi offset table: %d\n", ret); + return ret; + } + state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); if (!state) return -ENOMEM; -- GitLab From bb2d759893681d0696c396976a8a89eac066b3fa Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Tue, 19 Jun 2018 17:02:12 +0530 Subject: [PATCH 0336/1645] asoc: codecs: stub for WCD CPE core Add stub functions for WCD CPE core APIs Change-Id: Iddfdc8de9962d7a8d96cf7010c0b7ab18826ce37 Signed-off-by: Mangesh Kunchamwar --- asoc/codecs/wcd_cpe_core.h | 14 ++++++++++++++ config/qcs405auto.conf | 1 - config/qcs405autoconf.h | 1 - 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd_cpe_core.h b/asoc/codecs/wcd_cpe_core.h index 5884a528541f..269c5f2a5b00 100644 --- a/asoc/codecs/wcd_cpe_core.h +++ b/asoc/codecs/wcd_cpe_core.h @@ -222,8 +222,22 @@ struct wcd_cpe_params { struct cpe_svc_init_param *cpe_svc_params; }; +#if IS_ENABLED(CONFIG_SND_SOC_WCD_CPE) int wcd_cpe_ssr_event(void *core_handle, enum wcd_cpe_ssr_state_event event); struct wcd_cpe_core *wcd_cpe_init(const char *img_fname, struct snd_soc_codec *codec, struct wcd_cpe_params *params); +#else /* CONFIG_SND_SOC_WCD_CPE */ +static inline int wcd_cpe_ssr_event(void *core_handle, + enum wcd_cpe_ssr_state_event event) +{ + return 0; +} +static inline struct wcd_cpe_core *wcd_cpe_init(const char *img_fname, + struct snd_soc_codec *codec, + struct wcd_cpe_params *params) +{ + return NULL; +} +#endif /* CONFIG_SND_SOC_WCD_CPE */ #endif diff --git a/config/qcs405auto.conf b/config/qcs405auto.conf index 127311dbb441..ddd9741304b6 100644 --- a/config/qcs405auto.conf +++ b/config/qcs405auto.conf @@ -25,7 +25,6 @@ CONFIG_VA_MACRO=m CONFIG_MSM_GLINK_SPI_XPRT=m CONFIG_WCD_DSP_GLINK=m CONFIG_SOUNDWIRE=m -CONFIG_WCD9XXX_CODEC_CORE=m CONFIG_SND_SOC_QDSP6V2=m CONFIG_SND_SOC_WCD_MBHC_LEGACY=m CONFIG_QTI_PP=m diff --git a/config/qcs405autoconf.h b/config/qcs405autoconf.h index 0bb0463032c5..066f2909108b 100644 --- a/config/qcs405autoconf.h +++ b/config/qcs405autoconf.h @@ -16,7 +16,6 @@ #define CONFIG_SND_SOC_WCD9XXX_V2 1 #define CONFIG_SND_SOC_WSA881X 1 #define CONFIG_SND_SOC_WCD_DSP_MGR 1 -#define CONFIG_SND_SOC_WCD_CPE 1 #define CONFIG_SND_SOC_WCD9335 1 #define CONFIG_WCD9XXX_CODEC_CORE 1 #define CONFIG_MSM_CDC_PINCTRL 1 -- GitLab From fbea92ff45ebb2cd07adf978521ad1388c421cef Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 14 Jun 2018 16:38:15 -0700 Subject: [PATCH 0337/1645] asoc: msm: fix display port rx1 route Fix proper name for rx1 dp port widget for proper registration of the dp route. Change-Id: I31894c0b1f66ed8848f533728f3ca07ec9fefd34 Signed-off-by: Karthikeyan Mani --- asoc/msm-pcm-routing-v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 1ee5687e0f5d..cccb7f43a28f 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -16663,7 +16663,7 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX Port Mixer", SND_SOC_NOPM, 0, 0, display_port_rx_port_mixer_controls, ARRAY_SIZE(display_port_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX Port1 Mixer", + SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX1 Port Mixer", SND_SOC_NOPM, 0, 0, display_port_rx1_port_mixer_controls, ARRAY_SIZE(display_port_rx1_port_mixer_controls)), SND_SOC_DAPM_MIXER("SEC_I2S_RX Port Mixer", -- GitLab From 6ee5b50fd450ba9b3e5f57164425ecc78ca7bda0 Mon Sep 17 00:00:00 2001 From: Bhalchandra Gajare Date: Sat, 12 May 2018 20:43:40 -0700 Subject: [PATCH 0338/1645] msm-lsm-client: decouple input and output hardware parameters With multichannel voice activation support in LSM, it could be possible that the input media format/hw_params to LSM would be different than the output media format/hw_params. This change decouples the input and output hw_params for LSM. The output hw_params are obtained through ALSA pcm_hw_params operation, whereas the input hw_params are obtained though the LSM_SET_INPUT_HW_PARAMS ioctl to LSM. At the same time, the below parameter IDs are added to send the channel information to LSM service: - LSM_PARAM_ID_MEDIA_FMT_V2 - LSM_PARAM_ID_LAB_OUTPUT_CHANNEL_CONFIG Change-Id: Ie53a087b0ec54e83c4eba93a0828f9bdd6cc147d Signed-off-by: Bhalchandra Gajare --- asoc/msm-lsm-client.c | 174 +++++++++++++++++++++----------- dsp/q6lsm.c | 201 +++++++++++++++++++++++++++++-------- include/dsp/apr_audio-v2.h | 2 + include/dsp/q6lsm.h | 21 +++- 4 files changed, 293 insertions(+), 105 deletions(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index cea11b8599d5..3e49b295a4a3 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -53,8 +53,8 @@ static struct snd_pcm_hardware msm_pcm_hardware_capture = { SNDRV_PCM_RATE_48000), .rate_min = 16000, .rate_max = 48000, - .channels_min = 1, - .channels_max = 4, + .channels_min = LSM_INPUT_NUM_CHANNELS_MIN, + .channels_max = LSM_INPUT_NUM_CHANNELS_MAX, .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE, .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE, @@ -116,11 +116,11 @@ static int msm_lsm_queue_lab_buffer(struct lsm_priv *prtd, int i) rtd = prtd->substream->private_data; if (!prtd->lsm_client->lab_buffer || - i >= prtd->lsm_client->hw_params.period_count) { + i >= prtd->lsm_client->out_hw_params.period_count) { dev_err(rtd->dev, "%s: Lab buffer not setup %pK incorrect index %d period count %d\n", __func__, prtd->lsm_client->lab_buffer, i, - prtd->lsm_client->hw_params.period_count); + prtd->lsm_client->out_hw_params.period_count); return -EINVAL; } cmd_read.buf_addr_lsw = @@ -165,7 +165,7 @@ static int lsm_lab_buffer_sanity(struct lsm_priv *prtd, prtd->lsm_client->lab_buffer); return -EINVAL; } - for (i = 0; i < prtd->lsm_client->hw_params.period_count; i++) { + for (i = 0; i < prtd->lsm_client->out_hw_params.period_count; i++) { if ((lower_32_bits(prtd->lsm_client->lab_buffer[i].phys) == read_done->buf_addr_lsw) && (msm_audio_populate_upper_32_bits @@ -240,11 +240,11 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, "%s: process read done index %d\n", __func__, buf_index); if (buf_index >= - prtd->lsm_client->hw_params.period_count) { + prtd->lsm_client->out_hw_params.period_count) { dev_err(rtd->dev, "%s: Invalid index %d buf_index max cnt %d\n", __func__, buf_index, - prtd->lsm_client->hw_params.period_count); + prtd->lsm_client->out_hw_params.period_count); return; } prtd->dma_write += read_done->total_size; @@ -253,7 +253,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, wake_up(&prtd->period_wait); /* queue the next period buffer */ buf_index = (buf_index + 1) % - prtd->lsm_client->hw_params.period_count; + prtd->lsm_client->out_hw_params.period_count; rc = msm_lsm_queue_lab_buffer(prtd, buf_index); if (rc) dev_err(rtd->dev, @@ -405,8 +405,8 @@ static int msm_lsm_lab_buffer_alloc(struct lsm_priv *lsm, int alloc) dma_buf->private_data = NULL; dma_buf->area = lsm->lsm_client->lab_buffer[0].data; dma_buf->addr = lsm->lsm_client->lab_buffer[0].phys; - dma_buf->bytes = lsm->lsm_client->hw_params.buf_sz * - lsm->lsm_client->hw_params.period_count; + dma_buf->bytes = lsm->lsm_client->out_hw_params.buf_sz * + lsm->lsm_client->out_hw_params.period_count; snd_pcm_set_runtime_buffer(lsm->substream, dma_buf); } else { ret = q6lsm_lab_buffer_alloc(lsm->lsm_client, alloc); @@ -1260,7 +1260,10 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, break; } case SNDRV_LSM_LAB_CONTROL: { - u32 enable; + struct lsm_hw_params *out_hw_params = + &prtd->lsm_client->out_hw_params; + u8 chmap[out_hw_params->num_chs]; + u32 enable, ch_idx; if (copy_from_user(&enable, arg, sizeof(enable))) { dev_err(rtd->dev, "%s: %s: copy_frm_user failed\n", @@ -1270,39 +1273,61 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, dev_dbg(rtd->dev, "%s: ioctl %s, enable = %d\n", __func__, "SNDRV_LSM_LAB_CONTROL", enable); - if (!prtd->lsm_client->started) { - if (prtd->lsm_client->lab_enable == enable) { - dev_dbg(rtd->dev, - "%s: Lab for session %d already %s\n", - __func__, prtd->lsm_client->session, - enable ? "enabled" : "disabled"); - rc = 0; - break; - } - rc = q6lsm_lab_control(prtd->lsm_client, enable); - if (rc) { - dev_err(rtd->dev, - "%s: ioctl %s failed rc %d to %s lab for session %d\n", - __func__, "SNDRV_LAB_CONTROL", rc, - enable ? "enable" : "disable", - prtd->lsm_client->session); - } else { - rc = msm_lsm_lab_buffer_alloc(prtd, - enable ? LAB_BUFFER_ALLOC - : LAB_BUFFER_DEALLOC); - if (rc) - dev_err(rtd->dev, - "%s: msm_lsm_lab_buffer_alloc failed rc %d for %s", - __func__, rc, - enable ? "ALLOC" : "DEALLOC"); - if (!rc) - prtd->lsm_client->lab_enable = enable; - } - } else { + + if (prtd->lsm_client->started) { dev_err(rtd->dev, "%s: ioctl %s issued after start", __func__, "SNDRV_LSM_LAB_CONTROL"); rc = -EINVAL; + break; } + + if (prtd->lsm_client->lab_enable == enable) { + dev_dbg(rtd->dev, + "%s: Lab for session %d already %s\n", + __func__, prtd->lsm_client->session, + enable ? "enabled" : "disabled"); + rc = 0; + break; + } + + rc = q6lsm_lab_control(prtd->lsm_client, enable); + if (rc) { + dev_err(rtd->dev, + "%s: ioctl %s failed rc %d to %s lab for session %d\n", + __func__, "SNDRV_LAB_CONTROL", rc, + enable ? "enable" : "disable", + prtd->lsm_client->session); + break; + } + + rc = msm_lsm_lab_buffer_alloc(prtd, + enable ? LAB_BUFFER_ALLOC + : LAB_BUFFER_DEALLOC); + if (rc) { + dev_err(rtd->dev, + "%s: msm_lsm_lab_buffer_alloc failed rc %d for %s", + __func__, rc, + enable ? "ALLOC" : "DEALLOC"); + break; + } + + prtd->lsm_client->lab_enable = enable; + memset(chmap, 0, out_hw_params->num_chs); + /* + * First channel to be read from lab is always the + * best channel (0xff). For second channel onwards, + * the channel indices are 0, 1, .. etc + */ + chmap[0] = 0xFF; + for (ch_idx = 1; ch_idx < out_hw_params->num_chs; ch_idx++) + chmap[ch_idx] = ch_idx - 1; + + rc = q6lsm_lab_out_ch_cfg(prtd->lsm_client, chmap); + if (rc) + dev_err(rtd->dev, + "%s: Failed to set lab out ch cfg %d\n", + __func__, rc); + break; } case SNDRV_LSM_STOP_LAB: @@ -1354,6 +1379,23 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, } break; } + case SNDRV_LSM_SET_INPUT_HW_PARAMS: { + struct lsm_hw_params *in_params; + struct snd_lsm_input_hw_params params; + + if (copy_from_user(¶ms, arg, sizeof(params))) { + dev_err(rtd->dev, "%s: %s: copy_from_user failed\n", + __func__, "LSM_SET_INPUT_HW_PARAMS"); + return -EFAULT; + } + + in_params = &prtd->lsm_client->in_hw_params; + in_params->sample_rate = params.sample_rate; + in_params->sample_size = params.bit_width; + in_params->num_chs = params.num_channels; + + break; + } default: dev_dbg(rtd->dev, @@ -2241,7 +2283,7 @@ static int msm_lsm_prepare(struct snd_pcm_substream *substream) return -EINVAL; } - if (q6lsm_set_media_fmt_params(prtd->lsm_client)) + if (q6lsm_set_media_fmt_v2_params(prtd->lsm_client)) dev_dbg(rtd->dev, "%s: failed to set lsm media fmt params\n", __func__); @@ -2339,7 +2381,8 @@ static int msm_lsm_hw_params(struct snd_pcm_substream *substream, { struct snd_pcm_runtime *runtime = substream->runtime; struct lsm_priv *prtd = runtime->private_data; - struct lsm_hw_params *hw_params = NULL; + struct lsm_hw_params *out_hw_params = NULL; + struct lsm_hw_params *in_hw_params = NULL; struct snd_soc_pcm_runtime *rtd; if (!substream->private_data) { @@ -2354,37 +2397,48 @@ static int msm_lsm_hw_params(struct snd_pcm_substream *substream, __func__, prtd, params); return -EINVAL; } - hw_params = &prtd->lsm_client->hw_params; - hw_params->num_chs = params_channels(params); - hw_params->period_count = params_periods(params); - hw_params->sample_rate = params_rate(params); - if (((hw_params->sample_rate != 16000) && - (hw_params->sample_rate != 48000)) || - (hw_params->period_count == 0)) { + in_hw_params = &prtd->lsm_client->in_hw_params; + out_hw_params = &prtd->lsm_client->out_hw_params; + out_hw_params->num_chs = params_channels(params); + out_hw_params->period_count = params_periods(params); + out_hw_params->sample_rate = params_rate(params); + if (((out_hw_params->sample_rate != 16000) && + (out_hw_params->sample_rate != 48000)) || + (out_hw_params->period_count == 0)) { dev_err(rtd->dev, "%s: Invalid Params sample rate %d period count %d\n", - __func__, hw_params->sample_rate, - hw_params->period_count); + __func__, out_hw_params->sample_rate, + out_hw_params->period_count); return -EINVAL; } if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE) { - hw_params->sample_size = 16; + out_hw_params->sample_size = 16; } else if (params_format(params) == SNDRV_PCM_FORMAT_S24_LE) { - hw_params->sample_size = 24; + out_hw_params->sample_size = 24; } else { dev_err(rtd->dev, "%s: Invalid Format 0x%x\n", __func__, params_format(params)); return -EINVAL; } - hw_params->buf_sz = params_buffer_bytes(params) / - hw_params->period_count; + out_hw_params->buf_sz = params_buffer_bytes(params) / + out_hw_params->period_count; dev_dbg(rtd->dev, "%s: channels %d sample rate %d sample size %d buffer size %d period count %d\n", - __func__, hw_params->num_chs, hw_params->sample_rate, - hw_params->sample_size, hw_params->buf_sz, - hw_params->period_count); + __func__, out_hw_params->num_chs, out_hw_params->sample_rate, + out_hw_params->sample_size, out_hw_params->buf_sz, + out_hw_params->period_count); + + /* + * copy the out_hw_params to in_hw_params. in_hw_params will be + * over-written with LSM_SET_INPUT_HW_PARAMS ioctl from userspace. + * If this ioctl is not set, then it is assumed that input and + * output hw params for LSM are the same. + * Currently the period_count and buf_sz are unused for input params. + */ + memcpy(in_hw_params, out_hw_params, + sizeof(struct lsm_hw_params)); return 0; } @@ -2456,7 +2510,7 @@ static int msm_lsm_pcm_copy(struct snd_pcm_substream *substream, int ch, return -EIO; } prtd->appl_cnt = prtd->appl_cnt % - prtd->lsm_client->hw_params.period_count; + prtd->lsm_client->out_hw_params.period_count; pcm_buf = prtd->lsm_client->lab_buffer[prtd->appl_cnt].data; dev_dbg(rtd->dev, "%s: copy the pcm data size %lu\n", @@ -2474,7 +2528,7 @@ static int msm_lsm_pcm_copy(struct snd_pcm_substream *substream, int ch, return -EINVAL; } prtd->appl_cnt = (prtd->appl_cnt + 1) % - prtd->lsm_client->hw_params.period_count; + prtd->lsm_client->out_hw_params.period_count; atomic_dec(&prtd->buf_count); return 0; } diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 46996d40e08f..4e0f7247f5fc 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -1028,38 +1028,33 @@ int q6lsm_set_fwk_mode_cfg(struct lsm_client *client, } EXPORT_SYMBOL(q6lsm_set_fwk_mode_cfg); -static int q6lsm_arrange_mch_map(struct lsm_param_media_fmt *media_fmt, - int channel_count) +static int q6lsm_arrange_mch_map(uint8_t *ch_map, int ch_cnt) { - int rc = 0; + int ch_idx; + u8 mch_map[LSM_V3P0_MAX_NUM_CHANNELS] = { + PCM_CHANNEL_FL, PCM_CHANNEL_FR, PCM_CHANNEL_FC, + PCM_CHANNEL_LS, PCM_CHANNEL_RS, PCM_CHANNEL_LFE, + PCM_CHANNEL_LB, PCM_CHANNEL_RB, PCM_CHANNEL_CS}; - memset(media_fmt->channel_mapping, 0, LSM_MAX_NUM_CHANNELS); - switch (channel_count) { - case 1: - media_fmt->channel_mapping[0] = PCM_CHANNEL_FC; - break; - case 2: - media_fmt->channel_mapping[0] = PCM_CHANNEL_FL; - media_fmt->channel_mapping[1] = PCM_CHANNEL_FR; - break; - case 3: - media_fmt->channel_mapping[0] = PCM_CHANNEL_FL; - media_fmt->channel_mapping[1] = PCM_CHANNEL_FR; - media_fmt->channel_mapping[2] = PCM_CHANNEL_FC; - break; - case 4: - media_fmt->channel_mapping[0] = PCM_CHANNEL_FL; - media_fmt->channel_mapping[1] = PCM_CHANNEL_FR; - media_fmt->channel_mapping[2] = PCM_CHANNEL_LS; - media_fmt->channel_mapping[3] = PCM_CHANNEL_RS; - break; - default: - pr_err("%s: invalid num_chan %d\n", __func__, channel_count); - rc = -EINVAL; - break; + if (ch_cnt > LSM_V3P0_MAX_NUM_CHANNELS) { + pr_err("%s: invalid num_chan %d\n", __func__, ch_cnt); + return -EINVAL; } - return rc; + + if (ch_cnt == 1) { + ch_map[0] = PCM_CHANNEL_FC; + } else if (ch_cnt == 4) { + ch_map[0] = PCM_CHANNEL_FL; + ch_map[1] = PCM_CHANNEL_FR; + ch_map[2] = PCM_CHANNEL_LS; + ch_map[3] = PCM_CHANNEL_RS; + } else { + for (ch_idx = 0; ch_idx < ch_cnt; ch_idx++) + ch_map[ch_idx] = mch_map[ch_idx]; + } + + return 0; } /** @@ -1073,7 +1068,7 @@ static int q6lsm_arrange_mch_map(struct lsm_param_media_fmt *media_fmt, int q6lsm_set_media_fmt_params(struct lsm_client *client) { struct lsm_param_media_fmt media_fmt; - struct lsm_hw_params param = client->hw_params; + struct lsm_hw_params in_param = client->in_hw_params; struct param_hdr_v3 media_fmt_hdr; int rc = 0; @@ -1091,10 +1086,11 @@ int q6lsm_set_media_fmt_params(struct lsm_client *client) media_fmt_hdr.param_size = sizeof(media_fmt); media_fmt.minor_version = QLSM_PARAM_ID_MINOR_VERSION_2; - media_fmt.sample_rate = param.sample_rate; - media_fmt.num_channels = param.num_chs; - media_fmt.bit_width = param.sample_size; - rc = q6lsm_arrange_mch_map(&media_fmt, media_fmt.num_channels); + media_fmt.sample_rate = in_param.sample_rate; + media_fmt.num_channels = in_param.num_chs; + media_fmt.bit_width = in_param.sample_size; + rc = q6lsm_arrange_mch_map(media_fmt.channel_mapping, + media_fmt.num_channels); if (rc) goto err_ret; @@ -1112,6 +1108,65 @@ int q6lsm_set_media_fmt_params(struct lsm_client *client) } EXPORT_SYMBOL(q6lsm_set_media_fmt_params); +/* + * q6lsm_set_media_fmt_v2_params - + * command to set LSM media fmt (version2) params + * + * @client: LSM client handle + * + * Returns 0 on success or error on failure + */ +int q6lsm_set_media_fmt_v2_params(struct lsm_client *client) +{ + u8 *param_buf; + struct lsm_param_media_fmt_v2 *media_fmt_v2; + struct lsm_hw_params *in_param = &client->in_hw_params; + struct param_hdr_v3 media_fmt_v2_hdr; + int param_len = 0, rc = 0; + + memset(&media_fmt_v2_hdr, 0, sizeof(media_fmt_v2_hdr)); + + param_len = sizeof(*media_fmt_v2) + + (sizeof(uint8_t) * in_param->num_chs); + + /* Add padding to make sure total length is 4-byte aligned */ + if (param_len % 4) + param_len += (4 - (param_len % 4)); + + param_buf = kzalloc(param_len, GFP_KERNEL); + if (!param_buf) + return -ENOMEM; + media_fmt_v2 = (struct lsm_param_media_fmt_v2 *) param_buf; + media_fmt_v2->minor_version = QLSM_PARAM_ID_MINOR_VERSION; + media_fmt_v2->sample_rate = in_param->sample_rate; + media_fmt_v2->num_channels = in_param->num_chs; + media_fmt_v2->bit_width = in_param->sample_size; + rc = q6lsm_arrange_mch_map(media_fmt_v2->channel_mapping, + in_param->num_chs); + if (rc) + goto err_mch_map; + + media_fmt_v2_hdr.module_id = LSM_MODULE_ID_FRAMEWORK; + media_fmt_v2_hdr.instance_id = INSTANCE_ID_0; + media_fmt_v2_hdr.param_id = LSM_PARAM_ID_MEDIA_FMT_V2; + media_fmt_v2_hdr.param_size = param_len; + + pr_debug("%s: sample rate= %d, channels %d bit width %d\n", __func__, + media_fmt_v2->sample_rate, media_fmt_v2->num_channels, + media_fmt_v2->bit_width); + + rc = q6lsm_pack_and_set_params(client, &media_fmt_v2_hdr, + param_buf, + LSM_SESSION_CMD_SET_PARAMS_V2); + if (rc) + pr_err("%s: Failed set_params, rc %d\n", __func__, rc); + +err_mch_map: + kfree(param_buf); + return rc; +} +EXPORT_SYMBOL(q6lsm_set_media_fmt_v2_params); + /** * q6lsm_set_data - * Command to set LSM data @@ -2051,6 +2106,62 @@ int q6lsm_lab_control(struct lsm_client *client, u32 enable) } EXPORT_SYMBOL(q6lsm_lab_control); +/* + * q6lsm_lab_out_ch_cfg - + * Command to set the channel configuration + * for look-ahead buffer. + * + * @client: LSM client handle + * @ch_map: Channel map indicating the order + * of channels to be configured. + * + * Returns 0 on success or error on failure + */ +int q6lsm_lab_out_ch_cfg(struct lsm_client *client, + u8 *ch_map) +{ + u8 *param_buf; + struct lsm_param_lab_out_ch_cfg *lab_out_cfg; + struct param_hdr_v3 lab_out_cfg_hdr; + struct lsm_hw_params *out_params = &client->out_hw_params; + int i, rc = 0, param_len = 0; + + param_len = sizeof(*lab_out_cfg) + + sizeof(u8) * out_params->num_chs; + + if (param_len % 4) + param_len += (4 - (param_len % 4)); + + param_buf = kzalloc(param_len, GFP_KERNEL); + if (!param_buf) + return -ENOMEM; + + lab_out_cfg = (struct lsm_param_lab_out_ch_cfg *) param_buf; + lab_out_cfg->minor_version = QLSM_PARAM_ID_MINOR_VERSION; + lab_out_cfg->num_channels = out_params->num_chs; + + for (i = 0; i < out_params->num_chs; i++) + lab_out_cfg->channel_indices[i] = ch_map[i]; + + memset(&lab_out_cfg_hdr, 0, sizeof(lab_out_cfg_hdr)); + lab_out_cfg_hdr.module_id = LSM_MODULE_ID_LAB; + lab_out_cfg_hdr.instance_id = INSTANCE_ID_0; + lab_out_cfg_hdr.param_id = LSM_PARAM_ID_LAB_OUTPUT_CHANNEL_CONFIG; + lab_out_cfg_hdr.param_size = param_len; + + rc = q6lsm_pack_and_set_params(client, &lab_out_cfg_hdr, + param_buf, + LSM_SESSION_CMD_SET_PARAMS_V2); + if (rc) + pr_err("%s: Lab out channel config failed %d\n", + __func__, rc); + + kfree(param_buf); + + return rc; +} +EXPORT_SYMBOL(q6lsm_lab_out_ch_cfg); + /** * q6lsm_stop_lab - * command to stop LSM LAB @@ -2117,6 +2228,7 @@ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc) { int ret = 0, i = 0; size_t allocate_size = 0, len = 0; + struct lsm_hw_params *out_params = &client->out_hw_params; if (!client) { pr_err("%s: invalid client\n", __func__); @@ -2126,20 +2238,20 @@ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc) if (client->lab_buffer) { pr_err("%s: buffers are allocated period count %d period size %d\n", __func__, - client->hw_params.period_count, - client->hw_params.buf_sz); + out_params->period_count, + out_params->buf_sz); return -EINVAL; } - allocate_size = client->hw_params.period_count * - client->hw_params.buf_sz; + allocate_size = out_params->period_count * + out_params->buf_sz; allocate_size = PAGE_ALIGN(allocate_size); client->lab_buffer = kzalloc(sizeof(struct lsm_lab_buffer) * - client->hw_params.period_count, GFP_KERNEL); + out_params->period_count, GFP_KERNEL); if (!client->lab_buffer) { pr_err("%s: memory allocation for lab buffer failed count %d\n" , __func__, - client->hw_params.period_count); + out_params->period_count); return -ENOMEM; } ret = msm_audio_ion_alloc(&client->lab_buffer[0].dma_buf, @@ -2170,16 +2282,17 @@ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc) __func__, client->lab_buffer[0].mem_map_handle, &client->lab_buffer[0].phys, - client->hw_params.buf_sz); - for (i = 0; i < client->hw_params.period_count; i++) { + out_params->buf_sz); + + for (i = 0; i < out_params->period_count; i++) { client->lab_buffer[i].phys = client->lab_buffer[0].phys + - (i * client->hw_params.buf_sz); + (i * out_params->buf_sz); client->lab_buffer[i].size = - client->hw_params.buf_sz; + out_params->buf_sz; client->lab_buffer[i].data = (u8 *)(client->lab_buffer[0].data) + - (i * client->hw_params.buf_sz); + (i * out_params->buf_sz); client->lab_buffer[i].mem_map_handle = client->lab_buffer[0].mem_map_handle; } diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 4f03c17d1d94..58cd66d48790 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -9951,6 +9951,8 @@ struct avcs_fwk_ver_info { #define LSM_PARAM_ID_POLLING_ENABLE (0x00012C1B) #define LSM_PARAM_ID_MEDIA_FMT (0x00012C1E) #define LSM_PARAM_ID_FWK_MODE_CONFIG (0x00012C27) +#define LSM_PARAM_ID_MEDIA_FMT_V2 (0x00012C32) +#define LSM_PARAM_ID_LAB_OUTPUT_CHANNEL_CONFIG (0x00012C2D) /* HW MAD specific */ #define AFE_MODULE_HW_MAD (0x00010230) diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h index 05cc350cf708..740fba4e89b7 100644 --- a/include/dsp/q6lsm.h +++ b/include/dsp/q6lsm.h @@ -24,6 +24,7 @@ #define ADM_LSM_PORT_ID 0xADCB #define LSM_MAX_NUM_CHANNELS 8 +#define LSM_V3P0_MAX_NUM_CHANNELS 9 typedef void (*lsm_app_cb)(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv); @@ -82,7 +83,8 @@ struct lsm_client { bool lab_enable; bool lab_started; struct lsm_lab_buffer *lab_buffer; - struct lsm_hw_params hw_params; + struct lsm_hw_params out_hw_params; + struct lsm_hw_params in_hw_params; bool use_topology; int session_state; bool poll_enable; @@ -157,6 +159,15 @@ struct lsm_param_media_fmt { uint8_t channel_mapping[LSM_MAX_NUM_CHANNELS]; } __packed; +struct lsm_param_media_fmt_v2 { + uint32_t minor_version; + uint32_t sample_rate; + uint16_t bit_width; + uint16_t num_channels; + uint8_t channel_mapping[0]; +} __packed; + + struct lsm_param_confidence_levels { uint8_t num_confidence_levels; uint8_t confidence_levels[0]; @@ -192,6 +203,12 @@ struct lsm_param_lab_config { uint32_t wake_up_latency_ms; } __packed; +struct lsm_param_lab_out_ch_cfg { + uint32_t minor_version; + uint32_t num_channels; + uint8_t channel_indices[0]; +} __packed; + struct lsm_cmd_read { struct apr_hdr hdr; uint32_t buf_addr_lsw; @@ -250,4 +267,6 @@ void q6lsm_sm_set_param_data(struct lsm_client *client, int q6lsm_set_port_connected(struct lsm_client *client); int q6lsm_set_fwk_mode_cfg(struct lsm_client *client, uint32_t event_mode); int q6lsm_set_media_fmt_params(struct lsm_client *client); +int q6lsm_set_media_fmt_v2_params(struct lsm_client *client); +int q6lsm_lab_out_ch_cfg(struct lsm_client *client, u8 *ch_map); #endif /* __Q6LSM_H__ */ -- GitLab From 54b7fb7bce7530d429bfb0b83672b26a53f5d00f Mon Sep 17 00:00:00 2001 From: Bhalchandra Gajare Date: Thu, 10 May 2018 14:15:12 -0700 Subject: [PATCH 0339/1645] uapi: msm_audio_calibration: add new cal type for ADM_LSM New cal type ADM_LSM_AUDPROC_PERSISTENT is added to enable the larger calibration sizes for ADM that need to be kept persistent in memory. Change-Id: Ie23f52d6aad45dc1133a4a6fa692c1331b93d3e8 Signed-off-by: Bhalchandra Gajare --- include/uapi/linux/msm_audio_calibration.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h index 0672ee311299..9bd64aac8b53 100644 --- a/include/uapi/linux/msm_audio_calibration.h +++ b/include/uapi/linux/msm_audio_calibration.h @@ -103,6 +103,7 @@ enum { AFE_LSM_TX_CAL_TYPE, ADM_LSM_TOPOLOGY_CAL_TYPE, ADM_LSM_AUDPROC_CAL_TYPE, + ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE, MAX_CAL_TYPES, }; @@ -115,6 +116,7 @@ enum { #define AFE_LSM_TX_CAL_TYPE AFE_LSM_TX_CAL_TYPE #define ADM_LSM_TOPOLOGY_CAL_TYPE ADM_LSM_TOPOLOGY_CAL_TYPE #define ADM_LSM_AUDPROC_CAL_TYPE ADM_LSM_AUDPROC_CAL_TYPE +#define ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE #define LSM_CAL_TYPES #define TOPOLOGY_SPECIFIC_CHANNEL_INFO -- GitLab From bbb641427bccc09884da3f458b2c2bd489047c65 Mon Sep 17 00:00:00 2001 From: Bhalchandra Gajare Date: Thu, 10 May 2018 14:16:49 -0700 Subject: [PATCH 0340/1645] dsp: q6adm: add ADM_LSM_AUDPROC_PERSISTENT cal type ADM supports certain modules that can have very large calibration sizes, in such cases the calibration is expected to be persistent in memory. Add new cal type for this purpose. Change-Id: Ieb2e941036595b7dff4b8bfb341f2ec152cf648a Signed-off-by: Bhalchandra Gajare --- dsp/audio_cal_utils.c | 2 ++ dsp/q6adm.c | 35 ++++++++++++++++++++++++++++++----- include/dsp/q6adm-v2.h | 2 ++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index 77cb1c5b6e1e..47ac5becfc2b 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -63,6 +63,7 @@ size_t get_cal_info_size(int32_t cal_type) break; case ADM_AUDPROC_CAL_TYPE: case ADM_LSM_AUDPROC_CAL_TYPE: + case ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE: size = sizeof(struct audio_cal_info_audproc); break; case ADM_AUDVOL_CAL_TYPE: @@ -213,6 +214,7 @@ size_t get_user_cal_type_size(int32_t cal_type) break; case ADM_AUDPROC_CAL_TYPE: case ADM_LSM_AUDPROC_CAL_TYPE: + case ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE: size = sizeof(struct audio_cal_type_audproc); break; case ADM_AUDVOL_CAL_TYPE: diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 7d59fbbce66a..26402f38b1e2 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2000,7 +2000,8 @@ static struct cal_block_data *adm_find_cal_by_path(int cal_index, int path) continue; if (cal_index == ADM_AUDPROC_CAL || - cal_index == ADM_LSM_AUDPROC_CAL) { + cal_index == ADM_LSM_AUDPROC_CAL || + cal_index == ADM_LSM_AUDPROC_PERSISTENT_CAL) { audproc_cal_info = cal_block->cal_info; if ((audproc_cal_info->path == path) && (cal_block->cal_data.size > 0)) @@ -2037,7 +2038,8 @@ static struct cal_block_data *adm_find_cal_by_app_type(int cal_index, int path, continue; if (cal_index == ADM_AUDPROC_CAL || - cal_index == ADM_LSM_AUDPROC_CAL) { + cal_index == ADM_LSM_AUDPROC_CAL || + cal_index == ADM_LSM_AUDPROC_PERSISTENT_CAL) { audproc_cal_info = cal_block->cal_info; if ((audproc_cal_info->path == path) && (audproc_cal_info->app_type == app_type) && @@ -2077,7 +2079,8 @@ static struct cal_block_data *adm_find_cal(int cal_index, int path, continue; if (cal_index == ADM_AUDPROC_CAL || - cal_index == ADM_LSM_AUDPROC_CAL) { + cal_index == ADM_LSM_AUDPROC_CAL || + cal_index == ADM_LSM_AUDPROC_PERSISTENT_CAL) { audproc_cal_info = cal_block->cal_info; if ((audproc_cal_info->path == path) && (audproc_cal_info->app_type == app_type) && @@ -2165,12 +2168,18 @@ static void send_adm_cal(int port_id, int copp_idx, int path, int perf_mode, { pr_debug("%s: port id 0x%x copp_idx %d\n", __func__, port_id, copp_idx); - if (passthr_mode != LISTEN) + if (passthr_mode != LISTEN) { send_adm_cal_type(ADM_AUDPROC_CAL, path, port_id, copp_idx, perf_mode, app_type, acdb_id, sample_rate); - else + } else { send_adm_cal_type(ADM_LSM_AUDPROC_CAL, path, port_id, copp_idx, perf_mode, app_type, acdb_id, sample_rate); + + send_adm_cal_type(ADM_LSM_AUDPROC_PERSISTENT_CAL, path, + port_id, copp_idx, perf_mode, app_type, + acdb_id, sample_rate); + } + send_adm_cal_type(ADM_AUDVOL_CAL, path, port_id, copp_idx, perf_mode, app_type, acdb_id, sample_rate); } @@ -3297,6 +3306,9 @@ static int get_cal_type_index(int32_t cal_type) case ADM_RTAC_AUDVOL_CAL_TYPE: ret = ADM_RTAC_AUDVOL_CAL; break; + case ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE: + ret = ADM_LSM_AUDPROC_PERSISTENT_CAL; + break; default: pr_err("%s: invalid cal type %d!\n", __func__, cal_type); } @@ -3518,6 +3530,12 @@ static int adm_init_cal_data(void) adm_set_cal, NULL, NULL} }, {adm_map_cal_data, adm_unmap_cal_data, cal_utils_match_buf_num} }, + + {{ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE, + {adm_alloc_cal, adm_dealloc_cal, NULL, + adm_set_cal, NULL, NULL} }, + {adm_map_cal_data, adm_unmap_cal_data, + cal_utils_match_buf_num} }, }; pr_debug("%s:\n", __func__); @@ -3987,6 +4005,13 @@ int adm_store_cal_data(int port_id, int copp_idx, int path, int perf_mode, rc = -ENOMEM; goto unlock; } + } else if (cal_index == ADM_LSM_AUDPROC_PERSISTENT_CAL) { + if (cal_block->cal_data.size > AUD_PROC_PERSIST_BLOCK_SIZE) { + pr_err("%s:persist invalid size exp/actual[%zd, %d]\n", + __func__, cal_block->cal_data.size, *size); + rc = -ENOMEM; + goto unlock; + } } else if (cal_index == ADM_AUDVOL_CAL) { if (cal_block->cal_data.size > AUD_VOL_BLOCK_SIZE) { pr_err("%s:aud_vol:invalid size exp/actual[%zd, %d]\n", diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index bc3fdcfabfc5..3193b7f7efc1 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -29,6 +29,7 @@ ((MAX_MODULES_IN_TOPO + 1) * 2 * sizeof(uint32_t)) #define AUD_PROC_BLOCK_SIZE 4096 #define AUD_VOL_BLOCK_SIZE 4096 +#define AUD_PROC_PERSIST_BLOCK_SIZE (2 * 1024 * 1020) #define AUDIO_RX_CALIBRATION_SIZE (AUD_PROC_BLOCK_SIZE + \ AUD_VOL_BLOCK_SIZE) enum { @@ -40,6 +41,7 @@ enum { ADM_RTAC_APR_CAL, ADM_SRS_TRUMEDIA, ADM_RTAC_AUDVOL_CAL, + ADM_LSM_AUDPROC_PERSISTENT_CAL, ADM_MAX_CAL_TYPES }; -- GitLab From 3693b6559cf08c0b52d0d11dc6ae90713cf09bd0 Mon Sep 17 00:00:00 2001 From: Bhalchandra Gajare Date: Sat, 12 May 2018 18:52:56 -0700 Subject: [PATCH 0341/1645] asoc: msm-pcm-routing: add Listen app type config v2 mixer control It is required to know the number of output channels for any particular app_type so that channel mixing can be performed if the channels do not match as that of the listen stream. Add new Listen app type config V2 mixer control that reads the num_out_channels field along with the others. Change-Id: I49a74004e12dfa5a4c1ebaac4ac065acc6ff5bc3 Signed-off-by: Bhalchandra Gajare --- asoc/msm-pcm-routing-v2.c | 13 ++++++++++++- asoc/msm-pcm-routing-v2.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 1ee5687e0f5d..b1f008890410 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -14826,16 +14826,20 @@ static int msm_routing_put_lsm_app_type_cfg_control( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + int shift = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; int i = 0, j; int num_app_types = ucontrol->value.integer.value[i++]; memset(lsm_app_type_cfg, 0, MAX_APP_TYPES* - sizeof(struct msm_pcm_routing_app_type_data)); + sizeof(struct msm_pcm_routing_app_type_data)); + if (num_app_types > MAX_APP_TYPES) { pr_err("%s: number of app types exceed the max supported\n", __func__); return -EINVAL; } + for (j = 0; j < num_app_types; j++) { lsm_app_type_cfg[j].app_type = ucontrol->value.integer.value[i++]; @@ -14843,6 +14847,10 @@ static int msm_routing_put_lsm_app_type_cfg_control( ucontrol->value.integer.value[i++]; lsm_app_type_cfg[j].bit_width = ucontrol->value.integer.value[i++]; + /* Shift of 1 indicates this is V2 mixer control */ + if (shift == 1) + lsm_app_type_cfg[j].num_out_channels = + ucontrol->value.integer.value[i++]; } return 0; @@ -14852,6 +14860,9 @@ static const struct snd_kcontrol_new lsm_app_type_cfg_controls[] = { SOC_SINGLE_MULTI_EXT("Listen App Type Config", SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 128, msm_routing_get_lsm_app_type_cfg_control, msm_routing_put_lsm_app_type_cfg_control), + SOC_SINGLE_MULTI_EXT("Listen App Type Config V2", SND_SOC_NOPM, 1, + 0xFFFFFFFF, 0, 128, msm_routing_get_lsm_app_type_cfg_control, + msm_routing_put_lsm_app_type_cfg_control), }; static int msm_routing_get_use_ds1_or_ds2_control( diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 345e4d9cb98e..45a528d6f2f4 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -500,6 +500,7 @@ struct msm_pcm_routing_app_type_data { int app_type; u32 sample_rate; int bit_width; + u32 num_out_channels; }; struct msm_pcm_stream_app_type_cfg { -- GitLab From eed46bd5218a0ee8b6c519c84559ffbc08b86aa7 Mon Sep 17 00:00:00 2001 From: Bhalchandra Gajare Date: Tue, 15 May 2018 16:48:07 -0700 Subject: [PATCH 0342/1645] ASoC: msm: qdsp6v2: Add dynamic chmix config support Add support to dynamically configure channel mixing weightage coefficients for both ASM and LSM sessions. Currently the code is executed only for LSM session and can be extended to ASM as well. Change-Id: I727ea6fa2d3a99bbf6811005c5733535f680891b Signed-off-by: Chaithanya Krishna Bacharaju Signed-off-by: Bhalchandra Gajare --- asoc/msm-pcm-routing-v2.c | 63 +++++++++++++++ asoc/msm-pcm-routing-v2.h | 6 ++ asoc/msm-qti-pp-config.c | 156 +++++++++++++++++++++++++++++++++++++ asoc/msm-qti-pp-config.h | 11 +++ dsp/q6adm.c | 105 ++++++++++++++++++++++++- include/dsp/apr_audio-v2.h | 24 ++++++ include/dsp/q6adm-v2.h | 4 + 7 files changed, 368 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index b1f008890410..5c5d7811828d 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -802,6 +802,69 @@ static bool is_mm_lsm_fe_id(int fe_id) return rc; } +/* + * msm_pcm_routing_send_chmix_cfg: + * send the channel mixer command to mix the input channels + * into output channels. + * + * @fe_id: front end id + * @ip_channel_cnt: input channel count + * @op_channel_cnt: output channel count + * @ch_wght_coeff: channel weight co-efficients for channel mixing + * @session_type: indicates session is of type TX or RX + * @stream_type: indicates either Audio or Listen stream type + */ +int msm_pcm_routing_send_chmix_cfg(int fe_id, int ip_channel_cnt, + int op_channel_cnt, int *ch_wght_coeff, + int session_type, int stream_type) +{ + + int rc = 0, idx = 0; + int be_index = 0, port_id; + unsigned int session_id = 0; + + pr_debug("%s:fe_id[%d] ip_ch[%d] op_ch[%d] sess_type [%d], stream_type[%d]", + __func__, fe_id, ip_channel_cnt, op_channel_cnt, session_type, + stream_type); + if (!is_mm_lsm_fe_id(fe_id)) { + /* bad ID assigned in machine driver */ + pr_err("%s: bad MM ID %d\n", __func__, fe_id); + return -EINVAL; + } + + if (ch_wght_coeff == NULL) { + pr_err("%s: Null channel weightage coefficients passed\n", + __func__); + return -EINVAL; + } + + for (be_index = 0; be_index < MSM_BACKEND_DAI_MAX; be_index++) { + port_id = msm_bedais[be_index].port_id; + if (!msm_bedais[be_index].active || + !test_bit(fe_id, &msm_bedais[be_index].fe_sessions[0])) + continue; + + session_id = fe_dai_map[fe_id][session_type].strm_id; + + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { + unsigned long copp = + session_copp_map[fe_id][session_type][be_index]; + if (!test_bit(idx, &copp)) + continue; + msm_qti_pp_send_chmix_cfg_cmd(port_id, idx, + session_id, ip_channel_cnt, + op_channel_cnt, ch_wght_coeff, + session_type, stream_type); + if (rc < 0) + pr_err("%s: err setting channel mix config\n", + __func__); + } + } + + return 0; +} +EXPORT_SYMBOL(msm_pcm_routing_send_chmix_cfg); + int msm_pcm_routing_reg_stream_app_type_cfg( int fedai_id, int session_type, int be_id, struct msm_pcm_stream_app_type_cfg *cfg_data) diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 45a528d6f2f4..8f90b301225c 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -454,6 +454,9 @@ enum { #define BE_DAI_PORT_SESSIONS_IDX_MAX 4 #define BE_DAI_FE_SESSIONS_IDX_MAX 2 +#define STREAM_TYPE_ASM 0 +#define STREAM_TYPE_LSM 1 + enum { ADM_TOPOLOGY_CAL_TYPE_IDX = 0, ADM_LSM_TOPOLOGY_CAL_TYPE_IDX, @@ -543,4 +546,7 @@ int msm_pcm_routing_reg_stream_app_type_cfg( int msm_pcm_routing_get_stream_app_type_cfg( int fedai_id, int session_type, int *be_id, struct msm_pcm_stream_app_type_cfg *cfg_data); +int msm_pcm_routing_send_chmix_cfg(int fe_id, int ip_channel_cnt, + int op_channel_cnt, int *ch_wght_coeff, + int session_type, int stream_type); #endif /*_MSM_PCM_H*/ diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index ccbc0b76004b..7d64da66edbf 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -29,6 +29,7 @@ /* EQUALIZER */ /* Equal to Frontend after last of the MULTIMEDIA SESSIONS */ #define MAX_EQ_SESSIONS (MSM_FRONTEND_DAI_MULTIMEDIA20 + 1) +#define CHMIX_CFG_CONST_PARAM_SIZE 4 enum { EQ_BAND1 = 0, @@ -325,6 +326,161 @@ int msm_qti_pp_send_stereo_to_custom_stereo_cmd(int port_id, int copp_idx, kfree(params_value); return -ENOMEM; } + +static int msm_qti_pp_arrange_mch_map(int16_t *update_params_value16, + int channel_count) +{ + int i; + int16_t ch_map[PCM_FORMAT_MAX_CHANNELS_9] = { + PCM_CHANNEL_FL, PCM_CHANNEL_FR, PCM_CHANNEL_FC, + PCM_CHANNEL_LS, PCM_CHANNEL_RS, PCM_CHANNEL_LFE, + PCM_CHANNEL_LB, PCM_CHANNEL_RB, PCM_CHANNEL_CS }; + + if (channel_count < 1 || + channel_count > PCM_FORMAT_MAX_CHANNELS_9) { + pr_err("%s: invalid ch_cnt %d\n", + __func__, channel_count); + return -EINVAL; + } + + switch (channel_count) { + /* Add special cases here */ + case 1: + *update_params_value16++ = PCM_CHANNEL_FC; + break; + case 4: + *update_params_value16++ = PCM_CHANNEL_FL; + *update_params_value16++ = PCM_CHANNEL_FR; + *update_params_value16++ = PCM_CHANNEL_LS; + *update_params_value16++ = PCM_CHANNEL_RS; + break; + + /* Add standard cases here */ + default: + for (i = 0; i < channel_count; i++) + *update_params_value16++ = ch_map[i]; + break; + } + + return 0; +} + +static uint32_t msm_qti_pp_get_chmix_param_size(int ip_ch_cnt, int op_ch_cnt) +{ + uint32_t param_size; + /* Assign constant part of param length initially - + * Index, Num out channels, Num in channels. + */ + param_size = CHMIX_CFG_CONST_PARAM_SIZE * sizeof(uint16_t); + + /* Calculate variable part of param length using ip and op channels */ + + /* channel map for input and output channels */ + param_size += op_ch_cnt * sizeof(uint16_t); + param_size += ip_ch_cnt * sizeof(uint16_t); + + /* weightage coeff for each op ch corresponding to each ip ch */ + param_size += (ip_ch_cnt * op_ch_cnt) * sizeof(uint16_t); + + /* Params length should be multiple of 4 bytes i.e 32bit aligned*/ + param_size = (param_size + 3) & 0xFFFFFFFC; + + return param_size; +} + +/* + * msm_qti_pp_send_chmix_cfg_cmd: + * Send the custom channel mixer configuration command. + * + * @port_id: Backend port id + * @copp_idx: ADM copp index + * @session_id: id for the session requesting channel mixer + * @ip_channel_cnt: Input channel count + * @op_channel_cnt: Output channel count + * @ch_wght_coeff: Channel weight co-efficients for mixing + * @session_type: Indicates TX or RX session + * @stream_type: Indicates Audio or Listen stream type + */ +int msm_qti_pp_send_chmix_cfg_cmd(int port_id, int copp_idx, + unsigned int session_id, int ip_channel_cnt, + int op_channel_cnt, int *ch_wght_coeff, + int session_type, int stream_type) +{ + char *params_value; + int rc = 0, i, direction; + u8 *param_ptr; + int16_t *update_params_value16 = 0; + uint32_t param_size = msm_qti_pp_get_chmix_param_size(ip_channel_cnt, + op_channel_cnt); + struct param_hdr_v3 *param_hdr; + + /* constant payload data size represents module_id, param_id, + * param size, reserved field. + */ + uint32_t params_length = param_size + sizeof(*param_hdr); + + pr_debug("%s: port_id - %d, session id - %d\n", __func__, port_id, + session_id); + + params_value = kzalloc(params_length, GFP_KERNEL); + if (!params_value) + return -ENOMEM; + + param_ptr = params_value; + + param_hdr = (struct param_hdr_v3 *) param_ptr; + param_hdr->module_id = MTMX_MODULE_ID_DEFAULT_CHMIXER; + param_hdr->instance_id = INSTANCE_ID_0; + param_hdr->param_id = DEFAULT_CHMIXER_PARAM_ID_COEFF; + param_hdr->param_size = param_size; + + param_ptr += sizeof(*param_hdr); + + update_params_value16 = (int16_t *) param_ptr; + /*for alignment only*/ + *update_params_value16++ = 0; + /*index is 32-bit param in little endian*/ + *update_params_value16++ = CUSTOM_STEREO_INDEX_PARAM; + *update_params_value16++ = 0; + /*number of out ch*/ + *update_params_value16++ = op_channel_cnt; + /*number of in ch*/ + *update_params_value16++ = ip_channel_cnt; + + /* Out ch map FL/FR*/ + msm_qti_pp_arrange_mch_map(update_params_value16, op_channel_cnt); + update_params_value16 += op_channel_cnt; + + /* In ch map FL/FR*/ + msm_qti_pp_arrange_mch_map(update_params_value16, ip_channel_cnt); + update_params_value16 += ip_channel_cnt; + + /* weighting coefficients as name suggests, + * mixing will be done according to these coefficients. + */ + for (i = 0; i < ip_channel_cnt * op_channel_cnt; i++) + *update_params_value16++ = + ch_wght_coeff[i] ? Q14_GAIN_UNITY : 0; + if (params_length) { + direction = (session_type == SESSION_TYPE_RX) ? + ADM_MATRIX_ID_AUDIO_RX : ADM_MATRIX_ID_AUDIO_TX; + rc = adm_set_custom_chmix_cfg(port_id, + copp_idx, + session_id, + params_value, + params_length, + direction, + stream_type); + if (rc) { + pr_err("%s: send params failed rc=%d\n", __func__, rc); + kfree(params_value); + return -EINVAL; + } + } + kfree(params_value); + return 0; +} +EXPORT_SYMBOL(msm_qti_pp_send_chmix_cfg_cmd); #endif /* CONFIG_QTI_PP */ /* RMS */ diff --git a/asoc/msm-qti-pp-config.h b/asoc/msm-qti-pp-config.h index 3bf97b479e84..edbd603487c8 100644 --- a/asoc/msm-qti-pp-config.h +++ b/asoc/msm-qti-pp-config.h @@ -34,6 +34,10 @@ int msm_qti_pp_send_stereo_to_custom_stereo_cmd(int port_id, int copp_idx, uint16_t op_FR_ip_FL_weight, uint16_t op_FR_ip_FR_weight); void msm_qti_pp_add_controls(struct snd_soc_platform *platform); +int msm_qti_pp_send_chmix_cfg_cmd(int port_id, int copp_idx, + unsigned int session_id, int ip_channel_count, + int out_channel_cnt, int *ch_wght_coeff, + int session_type, int stream_type); #else /* CONFIG_QTI_PP */ static inline int msm_adsp_inform_mixer_ctl(struct snd_soc_pcm_runtime *rtd, uint32_t *payload) @@ -71,6 +75,13 @@ static inline int msm_adsp_stream_callback_info(struct snd_kcontrol *kcontrol, return 0; } +int msm_qti_pp_send_chmix_cfg_cmd(int port_id, int copp_idx, + unsigned int session_id, int ip_channel_count, + int out_channel_cnt, int *ch_wght_coeff, + int session_type, int stream_type) +{ + return 0; +} #define msm_qti_pp_send_eq_values(fedai_id) do {} while (0) #define msm_qti_pp_send_stereo_to_custom_stereo_cmd(port_id, copp_idx, \ session_id, op_FL_ip_FL_weight, op_FL_ip_FR_weight, \ diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 26402f38b1e2..b9893c458030 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -789,6 +789,106 @@ int adm_set_stereo_to_custom_stereo(int port_id, int copp_idx, } EXPORT_SYMBOL(adm_set_stereo_to_custom_stereo); +/* + * adm_set_custom_chmix_cfg: + * Set the custom channel mixer configuration for ADM + * + * @port_id: Backend port id + * @copp_idx: ADM copp index + * @session_id: ID of the requesting session + * @params: Expected packaged params for channel mixer + * @params_length: Length of the params to be set + * @direction: RX or TX direction + * @stream_type: Audio or Listen stream type + */ +int adm_set_custom_chmix_cfg(int port_id, int copp_idx, + unsigned int session_id, char *params, + uint32_t params_length, int direction, + int stream_type) +{ + struct adm_cmd_set_pspd_mtmx_strtr_params_v6 *adm_params = NULL; + int sz, rc = 0, port_idx; + + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + return -EINVAL; + } + + sz = sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v6) + + params_length; + adm_params = kzalloc(sz, GFP_KERNEL); + if (!adm_params) { + pr_err("%s, adm params memory alloc failed\n", __func__); + return -ENOMEM; + } + + memcpy(((u8 *)adm_params + + sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v6)), + params, params_length); + adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + adm_params->hdr.pkt_size = sz; + adm_params->hdr.src_svc = APR_SVC_ADM; + adm_params->hdr.src_domain = APR_DOMAIN_APPS; + adm_params->hdr.src_port = port_id; + adm_params->hdr.dest_svc = APR_SVC_ADM; + adm_params->hdr.dest_domain = APR_DOMAIN_ADSP; + adm_params->hdr.dest_port = 0; /* Ignored */; + adm_params->hdr.token = port_idx << 16 | copp_idx; + adm_params->hdr.opcode = ADM_CMD_SET_PSPD_MTMX_STRTR_PARAMS_V6; + adm_params->payload_addr_lsw = 0; + adm_params->payload_addr_msw = 0; + adm_params->mem_map_handle = 0; + adm_params->payload_size = params_length; + adm_params->direction = direction; + /* session id for this cmd to be applied on */ + adm_params->sessionid = session_id; + adm_params->deviceid = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + /* connecting stream type i.e. lsm or asm */ + adm_params->stream_type = stream_type; + pr_debug("%s: deviceid %d, session_id %d, src_port %d, dest_port %d\n", + __func__, adm_params->deviceid, adm_params->sessionid, + adm_params->hdr.src_port, adm_params->hdr.dest_port); + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); + if (rc < 0) { + pr_err("%s: Set params failed port = 0x%x rc %d\n", + __func__, port_id, rc); + rc = -EINVAL; + goto exit; + } + /* Wait for the callback */ + rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]), + msecs_to_jiffies(TIMEOUT_MS)); + if (!rc) { + pr_err("%s: Set params timed out port = 0x%x\n", __func__, + port_id); + rc = -EINVAL; + goto exit; + } else if (atomic_read(&this_adm.copp.stat + [port_idx][copp_idx]) > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(atomic_read( + &this_adm.copp.stat + [port_idx][copp_idx]))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&this_adm.copp.stat + [port_idx][copp_idx])); + goto exit; + } + + rc = 0; +exit: + kfree(adm_params); + return rc; +} +EXPORT_SYMBOL(adm_set_custom_chmix_cfg); + /* * With pre-packed data, only the opcode differes from V5 and V6. * Use q6common_pack_pp_params to pack the data correctly. @@ -1544,7 +1644,8 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) } break; case ADM_CMD_SET_PSPD_MTMX_STRTR_PARAMS_V5: - pr_debug("%s: ADM_CMD_SET_PSPD_MTMX_STRTR_PARAMS_V5\n", + case ADM_CMD_SET_PSPD_MTMX_STRTR_PARAMS_V6: + pr_debug("%s:callback received PSPD MTMX, wake up\n", __func__); atomic_set(&this_adm.copp.stat[port_idx] [copp_idx], payload[1]); @@ -2280,6 +2381,8 @@ int adm_arrange_mch_map(struct adm_cmd_device_open_v5 *open, int path, { int rc = 0, idx; + pr_debug("%s: channel mode %d", __func__, channel_mode); + memset(open->dev_channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); switch (path) { case ADM_PATH_PLAYBACK: diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 58cd66d48790..ae1e0c3d7449 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -575,6 +575,29 @@ struct adm_cmd_set_pspd_mtmx_strtr_params_v5 { u16 reserved; } __packed; +/* set customized mixing on matrix mixer. + * Updated to account for both LSM as well as ASM path. + */ +#define ADM_CMD_SET_PSPD_MTMX_STRTR_PARAMS_V6 0x00010364 +struct adm_cmd_set_pspd_mtmx_strtr_params_v6 { + struct apr_hdr hdr; + /* LSW of parameter data payload address.*/ + u32 payload_addr_lsw; + /* MSW of parameter data payload address.*/ + u32 payload_addr_msw; + /* Memory map handle returned by ADM_CMD_SHARED_MEM_MAP_REGIONS */ + /* command. If mem_map_handle is zero implies the message is in */ + /* the payload */ + u32 mem_map_handle; + /* Size in bytes of the variable payload accompanying this */ + /* message or in shared memory. This is used for parsing the */ + /* parameter payload. */ + u32 payload_size; + u16 direction; + u16 sessionid; + u16 deviceid; + u16 stream_type; +} __packed; /* Returns the status and COPP ID to an #ADM_CMD_DEVICE_OPEN_V5 command. */ #define ADM_CMDRSP_DEVICE_OPEN_V5 0x00010329 @@ -4683,6 +4706,7 @@ struct asm_softvolume_params { #define PCM_CHANNEL_RRC 16 #define PCM_FORMAT_MAX_NUM_CHANNEL 8 +#define PCM_FORMAT_MAX_CHANNELS_9 9 #define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2 0x00010DA5 diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 3193b7f7efc1..eafd2ad3b0e3 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -196,6 +196,10 @@ int adm_get_sound_focus(int port_id, int copp_idx, struct sound_focus_param *soundFocusData); int adm_get_source_tracking(int port_id, int copp_idx, struct source_tracking_param *sourceTrackingData); +int adm_set_custom_chmix_cfg(int port_id, int copp_idx, + unsigned int session_id, char *params, + uint32_t params_length, int direction, + int stream_type); int adm_swap_speaker_channels(int port_id, int copp_idx, int sample_rate, bool spk_swap); int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, -- GitLab From 3b1c926e42febeee1f6d43459497faee8008ca67 Mon Sep 17 00:00:00 2001 From: Bhalchandra Gajare Date: Thu, 17 May 2018 00:09:19 -0700 Subject: [PATCH 0343/1645] asoc: msm-pcm-routing: add msm_pcm_routing_get_pp_ch_cnt Based on the type of pre/post processing, it is possible that the processed channel count could be different from the input channel count. As an example, the FFECNS processing block could accept 3 channel input and has the ability to output upto 9 channels of processed data. In cases like these, the stream side needs to know the processed channel count to set up its own configuration. Change adds functionality in routing driver to read the processed channel count. Change-Id: I06c365f8c53270712709631bc23649d37434f405 Signed-off-by: Bhalchandra Gajare --- asoc/msm-pcm-routing-v2.c | 33 +++++++++++++++++++++++++++++++++ asoc/msm-pcm-routing-v2.h | 1 + 2 files changed, 34 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 5c5d7811828d..bf611512ceaa 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1197,6 +1197,39 @@ static bool route_check_fe_id_adm_support(int fe_id) return rc; } +/* + * msm_pcm_routing_get_pp_ch_cnt: + * Read the processed channel count + * + * @fe_id: Front end ID + * @session_type: Inidicates RX or TX session type + */ +int msm_pcm_routing_get_pp_ch_cnt(int fe_id, int session_type) +{ + struct msm_pcm_stream_app_type_cfg cfg_data; + int be_id = 0, app_type_idx = 0, app_type = 0; + int ret; + + memset(&cfg_data, 0, sizeof(cfg_data)); + + if (!is_mm_lsm_fe_id(fe_id)) { + pr_err("%s: bad MM ID\n", __func__); + return -EINVAL; + } + + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + &be_id, &cfg_data); + if (ret) { + pr_err("%s: cannot get stream app type cfg\n"); + return ret; + } + + app_type = cfg_data.app_type; + app_type_idx = msm_pcm_routing_get_lsm_app_type_idx(app_type); + return lsm_app_type_cfg[app_type_idx].num_out_channels; +} +EXPORT_SYMBOL(msm_pcm_routing_get_pp_ch_cnt); + int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, int dspst_id, int stream_type, uint32_t passthr_mode) diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 8f90b301225c..074341130e09 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -549,4 +549,5 @@ int msm_pcm_routing_get_stream_app_type_cfg( int msm_pcm_routing_send_chmix_cfg(int fe_id, int ip_channel_cnt, int op_channel_cnt, int *ch_wght_coeff, int session_type, int stream_type); +int msm_pcm_routing_get_pp_ch_cnt(int fe_id, int session_type); #endif /*_MSM_PCM_H*/ -- GitLab From 74cc9e08b5bdc6092fa28bf9707fdf9bc80380e9 Mon Sep 17 00:00:00 2001 From: Bhalchandra Gajare Date: Thu, 17 May 2018 01:57:46 -0700 Subject: [PATCH 0344/1645] lsm_client: add support to perform channel mixing With pre-processing applied, it is possible that the processed number of channels could be different than the number of channels that voice wakeup can run with. In such cases, the channel mixer should be setup to downmix the channel. For voice wakeup to detect keywords properly, preprocessed channels cannot be mixed hence the channel mixer is always setup with unity co-efficients or 0 to either select or drop the channel. In this case the channel mixer acts more like an channel selector. Change-Id: I79b578b56ad5484e27f433404a5371540618a2ae Signed-off-by: Bhalchandra Gajare --- asoc/msm-lsm-client.c | 78 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 3e49b295a4a3..3ecafbccec65 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -2263,6 +2263,77 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) return 0; } +static int msm_lsm_send_ch_mix_config(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd; + struct lsm_hw_params *in_params; + int pp_ch_cnt; + int *ch_wght_coeff; + int ret = 0, i, idx; + + /* + * The output channels from channel mixer is the input to LSM (stream) + * side and is read from in_params->num_chs. + * + * The input channels to channel mixer are the output channels from + * the device side (routing) and is obtained by reading the + * pp_ch_cnt. + * + * For LSM to be functional, only unity channel mixing is allowed. + */ + + in_params = &prtd->lsm_client->in_hw_params; + rtd = prtd->substream->private_data; + pp_ch_cnt = msm_pcm_routing_get_pp_ch_cnt(rtd->dai_link->id, + SESSION_TYPE_TX); + if (pp_ch_cnt < 0 || + pp_ch_cnt > LSM_V3P0_MAX_NUM_CHANNELS || + in_params->num_chs > LSM_V3P0_MAX_NUM_CHANNELS) { + dev_err(rtd->dev, + "%s: invalid ch cnt, pp_ch_cnt %d in_ch_cnt %d\n", + __func__, pp_ch_cnt, in_params->num_chs); + return -EINVAL; + } + + if (!pp_ch_cnt || + (pp_ch_cnt == in_params->num_chs)) { + dev_dbg(rtd->dev, + "%s: Skip ch mixing, pp_ch_cnt %d in_ch_cnt %d\n", + __func__, pp_ch_cnt, in_params->num_chs); + return 0; + } + + ch_wght_coeff = kzalloc(in_params->num_chs * pp_ch_cnt * sizeof(int), + GFP_KERNEL); + if (!ch_wght_coeff) + return -ENOMEM; + + /* + * channel weight co-efficients is a m X n array, where + * m = number of input channels to ch mixer (pp_ch_cnt) + * n = number of output channels from ch mixer (in_params->num_chs) + */ + for (i = 0; i < in_params->num_chs; i++) { + idx = (i * pp_ch_cnt) + i; + ch_wght_coeff[idx] = 1; + } + + ret = msm_pcm_routing_send_chmix_cfg(rtd->dai_link->id, + pp_ch_cnt, in_params->num_chs, + ch_wght_coeff, + SESSION_TYPE_TX, STREAM_TYPE_LSM); + if (ret) + dev_err(rtd->dev, + "%s: Failed to configure channel mixer err %d\n", + __func__, ret); + + kfree(ch_wght_coeff); + + return ret; +} + static int msm_lsm_prepare(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -2300,6 +2371,13 @@ static int msm_lsm_prepare(struct snd_pcm_substream *substream) __func__, ret); return ret; } + + ret = msm_lsm_send_ch_mix_config(substream); + if (ret) { + msm_pcm_routing_dereg_phy_stream(rtd->dai_link->id, + SNDRV_PCM_STREAM_CAPTURE); + return ret; + } } prtd->lsm_client->session_state = RUNNING; -- GitLab From 9c6c107239ad2e32a954dc96bfa16bf1bf52b0f5 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Thu, 21 Jun 2018 17:18:06 +0530 Subject: [PATCH 0345/1645] asoc: qcs405: fix compilation issue fix compilation issue due to missing forward declartion. Change-Id: I64feb9e1baf25ad725f4333931726feceee2979a Signed-off-by: Mangesh Kunchamwar --- asoc/qcs405.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 002286c858c9..c2d99425676a 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -564,7 +564,8 @@ static struct msm_asoc_wcd93xx_codec msm_codec_fn; static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable, bool dapm); static int msm_wsa881x_init(struct snd_soc_component *component); - +static int msm_snd_vad_cfg_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); static struct snd_soc_dapm_route wcd_audio_paths[] = { {"MIC BIAS1", NULL, "MCLK TX"}, -- GitLab From f2687c989a24716f543080060395805a77efb772 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 14 Jun 2018 12:44:04 +0530 Subject: [PATCH 0346/1645] asoc: wcd9335: register speaker wsa controls only if WSA attached In vipertooth, both wsa-macro and wcd9335 are present. wcd9335 doesn't have wsa attached, and wsa-macro supports wsa attached which defines spkr wsa controls. wcd9335 driver needs to avoid register same controls if wsa is not attached to it. Change-Id: Ia3db8982b5214ade95e6d8f27a44a68e20b772a0 Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd9335.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 03958f39c3c7..7bc94018d5ad 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -717,6 +717,7 @@ struct tasha_priv { u32 anc_slot; bool anc_func; + bool is_wsa_attach; /* Vbat module */ struct wcd_vbat vbat; @@ -9049,17 +9050,6 @@ static const struct snd_kcontrol_new tasha_analog_gain_controls[] = { SOC_ENUM_EXT("EAR PA Gain", tasha_ear_pa_gain_enum, tasha_ear_pa_gain_get, tasha_ear_pa_gain_put), - SOC_ENUM_EXT("EAR SPKR PA Gain", tasha_ear_spkr_pa_gain_enum, - tasha_ear_spkr_pa_gain_get, tasha_ear_spkr_pa_gain_put), - - SOC_ENUM_EXT("SPKR Left Boost Max State", tasha_spkr_boost_stage_enum, - tasha_spkr_left_boost_stage_get, - tasha_spkr_left_boost_stage_put), - - SOC_ENUM_EXT("SPKR Right Boost Max State", tasha_spkr_boost_stage_enum, - tasha_spkr_right_boost_stage_get, - tasha_spkr_right_boost_stage_put), - SOC_SINGLE_TLV("HPHL Volume", WCD9335_HPH_L_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("HPHR Volume", WCD9335_HPH_R_EN, 0, 20, 1, @@ -9087,6 +9077,19 @@ static const struct snd_kcontrol_new tasha_analog_gain_controls[] = { analog_gain), }; +static const struct snd_kcontrol_new tasha_spkr_wsa_controls[] = { + SOC_ENUM_EXT("EAR SPKR PA Gain", tasha_ear_spkr_pa_gain_enum, + tasha_ear_spkr_pa_gain_get, tasha_ear_spkr_pa_gain_put), + + SOC_ENUM_EXT("SPKR Left Boost Max State", tasha_spkr_boost_stage_enum, + tasha_spkr_left_boost_stage_get, + tasha_spkr_left_boost_stage_put), + + SOC_ENUM_EXT("SPKR Right Boost Max State", tasha_spkr_boost_stage_enum, + tasha_spkr_right_boost_stage_get, + tasha_spkr_right_boost_stage_put), +}; + static const char * const spl_src0_mux_text[] = { "ZERO", "SRC_IN_HPHL", "SRC_IN_LO1", }; @@ -13583,6 +13586,10 @@ static int tasha_codec_probe(struct snd_soc_codec *codec) snd_soc_add_codec_controls(codec, tasha_analog_gain_controls, ARRAY_SIZE(tasha_analog_gain_controls)); + if (tasha->is_wsa_attach) + snd_soc_add_codec_controls(codec, + tasha_spkr_wsa_controls, + ARRAY_SIZE(tasha_wsa_controls)); control->num_rx_port = TASHA_RX_MAX; control->rx_chs = ptr; memcpy(control->rx_chs, tasha_rx_chs, sizeof(tasha_rx_chs)); @@ -14053,6 +14060,7 @@ static void tasha_add_child_devices(struct work_struct *work) __func__, ctrl_num); goto fail_pdev_add; } + tasha->is_wsa_attach = true; } ret = platform_device_add(pdev); -- GitLab From 21c8b2284936c5025eadc436ff2d16f17b252786 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 21 Jun 2018 18:47:22 +0530 Subject: [PATCH 0347/1645] asoc: bolero: Add codec entry for bolero for rtac support Add codec entry for bolero codec under proc codecs list. Update the names of wsa-macro gain offset and mode for wsa8810 variant to avoid conflict with wcd9335. Change-Id: Icaa2ef7c2f7253060cd7cccd44130b0b12dc0713 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc.c | 93 +++++++++++++++++++++++++++++++++ asoc/codecs/bolero/bolero-cdc.h | 11 ++++ asoc/codecs/bolero/internal.h | 5 ++ asoc/codecs/bolero/wsa-macro.c | 16 +++--- asoc/codecs/bolero/wsa-macro.h | 8 +-- 5 files changed, 122 insertions(+), 11 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 5a2005055810..51e56df51c55 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -22,6 +22,9 @@ #include "bolero-cdc.h" #include "internal.h" +#define BOLERO_VERSION_1_0 0x0001 +#define BOLERO_VERSION_ENTRY_SIZE 32 + static struct snd_soc_codec_driver bolero; /* MCLK_MUX table for all macros */ @@ -389,6 +392,95 @@ int bolero_request_clock(struct device *dev, u16 macro_id, } EXPORT_SYMBOL(bolero_request_clock); +static ssize_t bolero_version_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, size_t count, + loff_t pos) +{ + struct bolero_priv *priv; + char buffer[BOLERO_VERSION_ENTRY_SIZE]; + int len = 0; + + priv = (struct bolero_priv *) entry->private_data; + if (!priv) { + pr_err("%s: bolero priv is null\n", __func__); + return -EINVAL; + } + + switch (priv->version) { + case BOLERO_VERSION_1_0: + len = snprintf(buffer, sizeof(buffer), "BOLERO_1_0\n"); + break; + default: + len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + } + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops bolero_info_ops = { + .read = bolero_version_read, +}; + +/* + * bolero_info_create_codec_entry - creates bolero module + * @codec_root: The parent directory + * @codec: Codec instance + * + * Creates bolero module and version entry under the given + * parent directory. + * + * Return: 0 on success or negative error code on failure. + */ +int bolero_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + struct snd_info_entry *version_entry; + struct bolero_priv *priv; + struct snd_soc_card *card; + + if (!codec_root || !codec) + return -EINVAL; + + priv = snd_soc_codec_get_drvdata(codec); + if (priv->entry) { + dev_dbg(priv->dev, + "%s:bolero module already created\n", __func__); + return 0; + } + card = codec->component.card; + priv->entry = snd_info_create_subdir(codec_root->module, + "bolero", codec_root); + if (!priv->entry) { + dev_dbg(codec->dev, "%s: failed to create bolero entry\n", + __func__); + return -ENOMEM; + } + version_entry = snd_info_create_card_entry(card->snd_card, + "version", + priv->entry); + if (!version_entry) { + dev_err(codec->dev, "%s: failed to create bolero version entry\n", + __func__); + return -ENOMEM; + } + + version_entry->private_data = priv; + version_entry->size = BOLERO_VERSION_ENTRY_SIZE; + version_entry->content = SNDRV_INFO_CONTENT_DATA; + version_entry->c.ops = &bolero_info_ops; + + if (snd_info_register(version_entry) < 0) { + snd_info_free_entry(version_entry); + return -ENOMEM; + } + priv->version_entry = version_entry; + + return 0; +} +EXPORT_SYMBOL(bolero_info_create_codec_entry); + static int bolero_soc_codec_probe(struct snd_soc_codec *codec) { struct bolero_priv *priv = dev_get_drvdata(codec->dev); @@ -407,6 +499,7 @@ static int bolero_soc_codec_probe(struct snd_soc_codec *codec) } } priv->codec = codec; + priv->version = BOLERO_VERSION_1_0; dev_dbg(codec->dev, "%s: bolero soc codec probe success\n", __func__); err: return ret; diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index e8b8bb46a061..f7e95eeae2f9 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -49,6 +49,9 @@ struct device *bolero_get_device_ptr(struct device *dev, u16 macro_id); int bolero_request_clock(struct device *dev, u16 macro_id, enum mclk_mux mclk_mux_id, bool enable); +int bolero_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_codec *codec); #else static inline int bolero_register_macro(struct device *dev, u16 macro_id, @@ -66,11 +69,19 @@ static inline struct device *bolero_get_device_ptr(struct device *dev, { return NULL; } + static inline int bolero_request_clock(struct device *dev, u16 macro_id, enum mclk_mux mclk_mux_id, bool enable) { return 0; } + +static int bolero_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + return 0; +} #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 0e310c8a4c24..2979ee066972 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -37,6 +37,11 @@ struct bolero_priv { u16 child_num; u16 current_mclk_mux_macro[MAX_MACRO]; struct work_struct bolero_add_child_devices_work; + u32 version; + + /* Entry for version info */ + struct snd_info_entry *entry; + struct snd_info_entry *version_entry; int (*read_dev)(struct bolero_priv *priv, u16 macro_id, u16 reg, u8 *val); diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index e8b84d8ceb2b..fe22cb3cb609 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -443,7 +443,7 @@ int wsa_macro_set_spkr_mode(struct snd_soc_codec *codec, int mode) return -EINVAL; switch (mode) { - case SPKR_MODE_1: + case WSA_MACRO_SPKR_MODE_1: regs = wsa_macro_spkr_mode1; size = ARRAY_SIZE(wsa_macro_spkr_mode1); break; @@ -1168,7 +1168,8 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: wsa_macro_config_compander(codec, w->shift, event); /* apply gain after int clk is enabled */ - if ((wsa_priv->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && + if ((wsa_priv->spkr_gain_offset == + WSA_MACRO_GAIN_OFFSET_M1P5_DB) && (wsa_priv->comp_enabled[WSA_MACRO_COMP1] || wsa_priv->comp_enabled[WSA_MACRO_COMP2]) && (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL || @@ -1194,7 +1195,8 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMD: wsa_macro_config_compander(codec, w->shift, event); wsa_macro_enable_prim_interpolator(codec, reg, event); - if ((wsa_priv->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && + if ((wsa_priv->spkr_gain_offset == + WSA_MACRO_GAIN_OFFSET_M1P5_DB) && (wsa_priv->comp_enabled[WSA_MACRO_COMP1] || wsa_priv->comp_enabled[WSA_MACRO_COMP2]) && (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL || @@ -1229,8 +1231,8 @@ static int wsa_macro_config_ear_spkr_gain(struct snd_soc_codec *codec, int comp_gain_offset, val; switch (wsa_priv->spkr_mode) { - /* Compander gain in SPKR_MODE1 case is 12 dB */ - case SPKR_MODE_1: + /* Compander gain in WSA_MACRO_SPKR_MODE1 case is 12 dB */ + case WSA_MACRO_SPKR_MODE_1: comp_gain_offset = -12; break; /* Default case compander gain is 15 dB */ @@ -1938,7 +1940,7 @@ static int wsa_macro_init(struct snd_soc_codec *codec) } wsa_priv->codec = codec; - wsa_priv->spkr_gain_offset = RX_GAIN_OFFSET_0_DB; + wsa_priv->spkr_gain_offset = WSA_MACRO_GAIN_OFFSET_0_DB; wsa_macro_init_reg(codec); return 0; @@ -1975,7 +1977,7 @@ static void wsa_macro_add_child_devices(struct work_struct *work) __func__); return; } - if (!!wsa_priv->dev || !wsa_priv->dev->of_node) { + if (!wsa_priv->dev || !wsa_priv->dev->of_node) { dev_err(wsa_priv->dev, "%s: DT node for wsa_priv does not exist\n", __func__); return; diff --git a/asoc/codecs/bolero/wsa-macro.h b/asoc/codecs/bolero/wsa-macro.h index e79de73bb2ef..ec1aa9a280f6 100644 --- a/asoc/codecs/bolero/wsa-macro.h +++ b/asoc/codecs/bolero/wsa-macro.h @@ -17,14 +17,14 @@ * for a given speaker mode */ enum { - SPKR_MODE_DEFAULT, - SPKR_MODE_1, /* COMP Gain = 12dB, Smartboost Max = 5.5V */ + WSA_MACRO_SPKR_MODE_DEFAULT, + WSA_MACRO_SPKR_MODE_1, /* COMP Gain = 12dB, Smartboost Max = 5.5V */ }; /* Rx path gain offsets */ enum { - RX_GAIN_OFFSET_M1P5_DB, - RX_GAIN_OFFSET_0_DB, + WSA_MACRO_GAIN_OFFSET_M1P5_DB, + WSA_MACRO_GAIN_OFFSET_0_DB, }; -- GitLab From aadecdf6c3dda5851114c4543eb0aafa27e7aebc Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Wed, 20 Jun 2018 15:08:24 -0700 Subject: [PATCH 0348/1645] dsp: adm: Update get params packet size Update apr header packet size in get pp params. Add header field for the apr packet. Update the check condition to differentiate between in-band and out-band case in adm callback. CRs-Fixed: 2262638 Change-Id: I57ef88e0638c09b203503f4c1cff2f810ef51c6e Signed-off-by: Vignesh Kulothungan --- dsp/q6adm.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index ef9f64a46313..11e20a35816a 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -1065,7 +1065,10 @@ int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id, NULL, &total_size); /* Pack APR header after filling body so total_size has correct value */ - adm_get_params.apr_hdr.pkt_size = total_size; + adm_get_params.apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + adm_get_params.apr_hdr.pkt_size = sizeof(adm_get_params); adm_get_params.apr_hdr.src_svc = APR_SVC_ADM; adm_get_params.apr_hdr.src_domain = APR_DOMAIN_APPS; adm_get_params.apr_hdr.src_port = port_id; @@ -1083,6 +1086,7 @@ int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id, copp_stat = &this_adm.copp.stat[port_idx][copp_idx]; atomic_set(copp_stat, -1); + ret = apr_send_pkt(this_adm.apr, (uint32_t *) &adm_get_params); if (ret < 0) { pr_err("%s: Get params APR send failed port = 0x%x ret %d\n", @@ -1377,6 +1381,8 @@ static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload, if ((payload_size >= struct_size + data_size) && (ARRAY_SIZE(adm_get_parameters) > idx) && (ARRAY_SIZE(adm_get_parameters) >= idx + 1 + data_size)) { + pr_debug("%s: Received parameter data in band\n", + __func__); /* * data_size is expressed in number of bytes, store in number of * ints @@ -1387,12 +1393,16 @@ static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload, __func__, adm_get_parameters[idx]); /* store params after param_size */ memcpy(&adm_get_parameters[idx + 1], param_data, data_size); - return 0; + } else if (payload_size == sizeof(uint32_t)) { + adm_get_parameters[idx] = -1; + pr_debug("%s: Out of band case, setting size to %d\n", + __func__, adm_get_parameters[idx]); + } else { + pr_err("%s: Invalid parameter combination, payload_size %d, idx %d\n", + __func__, payload_size, idx); + return -EINVAL; } - - pr_err("%s: Invalid parameter combination, payload_size %d, idx %d\n", - __func__, payload_size, idx); - return -EINVAL; + return 0; } static int adm_process_get_topo_list_response(u32 opcode, int copp_idx, @@ -1704,18 +1714,12 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) idx = ADM_GET_PARAMETER_LENGTH * copp_idx; if (payload[0] == 0 && data->payload_size > 0) { - pr_debug("%s: Received parameter data in band\n", - __func__); ret = adm_process_get_param_response( data->opcode, idx, payload, data->payload_size); if (ret) pr_err("%s: Failed to process get param response, error %d\n", __func__, ret); - } else if (payload[0] == 0 && data->payload_size == 0) { - adm_get_parameters[idx] = -1; - pr_debug("%s: Out of band case, setting size to %d\n", - __func__, adm_get_parameters[idx]); } else { adm_get_parameters[idx] = -1; pr_err("%s: ADM_CMDRSP_GET_PP_PARAMS returned error 0x%x\n", -- GitLab From 6f75e7b36910a3884373668e98be15f7683eae14 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 21 Jun 2018 18:05:44 -0700 Subject: [PATCH 0349/1645] dsp: adm: Update module id for sound focus and source tracking Update module id used in get/set for sound focus and source tracking. CRs-Fixed: 2262638 Change-Id: Ieb35c12b8f6ec8a5db6f699f70bf85ef29b29178 Signed-off-by: Vignesh Kulothungan --- dsp/q6adm.c | 6 +++--- include/dsp/apr_audio-v2.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index ef9f64a46313..d7669510df7d 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -4319,7 +4319,7 @@ int adm_set_sound_focus(int port_id, int copp_idx, __func__, port_id, copp_idx); memset(¶m_hdr, 0, sizeof(param_hdr)); - param_hdr.module_id = VOICEPROC_MODULE_ID_GENERIC_TX; + param_hdr.module_id = VOICEPROC_MODULE_ID_FLUENCE_PRO_VC_TX; param_hdr.instance_id = INSTANCE_ID_0; param_hdr.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS; param_hdr.param_size = sizeof(soundfocus_params); @@ -4380,7 +4380,7 @@ int adm_get_sound_focus(int port_id, int copp_idx, return -ENOMEM; memset(¶m_hdr, 0, sizeof(param_hdr)); - param_hdr.module_id = VOICEPROC_MODULE_ID_GENERIC_TX; + param_hdr.module_id = VOICEPROC_MODULE_ID_FLUENCE_PRO_VC_TX; param_hdr.instance_id = INSTANCE_ID_0; param_hdr.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS; param_hdr.param_size = max_param_size; @@ -4519,7 +4519,7 @@ int adm_get_source_tracking(int port_id, int copp_idx, mem_hdr.mem_map_handle = atomic_read( &this_adm.mem_map_handles[ADM_MEM_MAP_INDEX_SOURCE_TRACKING]); - param_hdr.module_id = VOICEPROC_MODULE_ID_GENERIC_TX; + param_hdr.module_id = VOICEPROC_MODULE_ID_FLUENCE_PRO_VC_TX; param_hdr.instance_id = INSTANCE_ID_0; param_hdr.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOURCETRACKING; /* diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index ae1e0c3d7449..92271e604c70 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -11263,6 +11263,7 @@ struct adm_set_compressed_device_latency { } __packed; #define VOICEPROC_MODULE_ID_GENERIC_TX 0x00010EF6 +#define VOICEPROC_MODULE_ID_FLUENCE_PRO_VC_TX 0x00010F35 #define VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS 0x00010E37 #define VOICEPROC_PARAM_ID_FLUENCE_SOURCETRACKING 0x00010E38 #define MAX_SECTORS 8 -- GitLab From 5e8453b03efadb73392730872c4a79b244fe6ffd Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Fri, 15 Jun 2018 17:03:42 +0800 Subject: [PATCH 0350/1645] ipc: Implement FIFO queue to fix sequence inconsistency The SVA history buffer is out of order if there are more than 2 continuous RX buffer done from GLINK. Implement FIFO to ensure sequence consistency. Change-Id: If70e2d0160e8f3140d621298b0db03bd89ba88ba Signed-off-by: Xiaojun Sang --- ipc/wcd-dsp-glink.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/ipc/wcd-dsp-glink.c b/ipc/wcd-dsp-glink.c index 21da65aae069..8c89418cc90a 100644 --- a/ipc/wcd-dsp-glink.c +++ b/ipc/wcd-dsp-glink.c @@ -79,6 +79,8 @@ struct wdsp_glink_priv { /* Respone buffer related */ u8 rsp_cnt; struct wdsp_rsp_que rsp[RESP_QUEUE_SIZE]; + u8 write_idx; + u8 read_idx; struct completion rsp_complete; spinlock_t rsp_lock; @@ -139,14 +141,15 @@ static int wdsp_rpmsg_callback(struct rpmsg_device *rpdev, void *data, wpriv->rsp_cnt); if (wpriv->rsp_cnt >= RESP_QUEUE_SIZE) { - dev_info_ratelimited(wpriv->dev, "%s: Resp Queue is Full\n", + dev_info_ratelimited(wpriv->dev, "%s: Resp Queue is Full. Ignore new one.\n", __func__); - rsp_cnt = 0; + return -EINVAL; } spin_lock_irqsave(&wpriv->rsp_lock, flags); rsp_cnt = wpriv->rsp_cnt; - memcpy(wpriv->rsp[rsp_cnt].buf, rx_buf, len); - wpriv->rsp[rsp_cnt].buf_size = len; + memcpy(wpriv->rsp[wpriv->write_idx].buf, rx_buf, len); + wpriv->rsp[wpriv->write_idx].buf_size = len; + wpriv->write_idx = (wpriv->write_idx + 1) % RESP_QUEUE_SIZE; wpriv->rsp_cnt = ++rsp_cnt; spin_unlock_irqrestore(&wpriv->rsp_lock, flags); @@ -327,11 +330,12 @@ static ssize_t wdsp_glink_read(struct file *file, char __user *buf, spin_lock_irqsave(&wpriv->rsp_lock, flags); if (wpriv->rsp_cnt) { wpriv->rsp_cnt--; - dev_dbg(wpriv->dev, "%s: read from buffer %d\n", - __func__, wpriv->rsp_cnt); + dev_dbg(wpriv->dev, "%s: rsp_cnt=%d read from buffer %d\n", + __func__, wpriv->rsp_cnt, wpriv->read_idx); - memcpy(read_rsp, &wpriv->rsp[wpriv->rsp_cnt], + memcpy(read_rsp, &wpriv->rsp[wpriv->read_idx], sizeof(struct wdsp_rsp_que)); + wpriv->read_idx = (wpriv->read_idx + 1) % RESP_QUEUE_SIZE; spin_unlock_irqrestore(&wpriv->rsp_lock, flags); if (count < read_rsp->buf_size) { -- GitLab From e81de8fbb488a13d0908abf029c199b7667c107a Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Fri, 22 Jun 2018 22:22:27 +0530 Subject: [PATCH 0351/1645] asoc: config: add path to build CSRA66X0 codec Add path to CSRA66X0 codec to build in QCS405 Change-Id: I88fa4378e46636a2edd9256e90919c2fb052f8a5 Signed-off-by: Mangesh Kunchamwar --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index 9fb3d45c7e1b..d9724cd70d32 100644 --- a/Makefile.am +++ b/Makefile.am @@ -41,6 +41,7 @@ obj-m += asoc/codecs/msm_sdw/ endif ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), qcs40x)) obj-m += asoc/codecs/bolero/ +obj-m += asoc/codecs/csra66x0/ endif all: -- GitLab From af431ad7c93573431ef0471022d03df7836a58f5 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 4 May 2018 05:06:11 +0530 Subject: [PATCH 0352/1645] dsp: q6afe: Add support to control AANC noise level Existing software supports only high AANC level with minimum noise. Requirement is to support different noise levels when AANC is enabled for better AANC effect. Change-Id: I343d00473937f68eb86533e88b25083d554b79b1 Signed-off-by: Sudheer Papothi --- dsp/q6afe.c | 57 ++++++++++++++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 11 ++++++++ include/dsp/q6afe-v2.h | 2 ++ 3 files changed, 70 insertions(+) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index c17721046256..e2d19ab34259 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -899,6 +899,61 @@ static int q6afe_pack_and_set_param_in_band(u16 port_id, int index, return ret; } +static int q6afe_set_aanc_level(void) +{ + struct param_hdr_v3 param_hdr; + struct afe_param_id_aanc_noise_reduction aanc_noise_level; + int ret = 0; + uint16_t tx_port = 0; + + if (!this_afe.aanc_info.aanc_active) + return -EINVAL; + + pr_debug("%s: level: %d\n", __func__, this_afe.aanc_info.level); + memset(&aanc_noise_level, 0, sizeof(aanc_noise_level)); + aanc_noise_level.minor_version = 1; + aanc_noise_level.ad_beta = this_afe.aanc_info.level; + + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_AANC; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_AANC_NOISE_REDUCTION; + param_hdr.param_size = sizeof(struct afe_param_id_aanc_noise_reduction); + + tx_port = this_afe.aanc_info.aanc_tx_port; + ret = q6afe_pack_and_set_param_in_band(tx_port, + q6audio_get_port_index(tx_port), + param_hdr, + (u8 *) &aanc_noise_level); + if (ret) + pr_err("%s: AANC noise level enable failed for tx_port 0x%x ret %d\n", + __func__, tx_port, ret); + return ret; +} + +/** + * afe_set_aanc_noise_level - controls aanc noise reduction strength + * + * @level: Noise level to be controlled + * + * Returns 0 on success or error on failure. + */ +int afe_set_aanc_noise_level(int level) +{ + int ret = 0; + + if (this_afe.aanc_info.level == level) + return ret; + + mutex_lock(&this_afe.afe_cmd_lock); + this_afe.aanc_info.level = level; + ret = q6afe_set_aanc_level(); + mutex_unlock(&this_afe.afe_cmd_lock); + + return ret; +} +EXPORT_SYMBOL(afe_set_aanc_noise_level); + /* This function shouldn't be called directly. Instead call q6afe_get_param. */ static int q6afe_get_params_v2(u16 port_id, int index, struct mem_mapping_hdr *mem_hdr, @@ -2336,6 +2391,8 @@ static int afe_aanc_port_cfg(void *apr, uint16_t tx_port, uint16_t rx_port) if (ret) pr_err("%s: AFE AANC port config failed for tx_port 0x%x, rx_port 0x%x ret %d\n", __func__, tx_port, rx_port, ret); + else + q6afe_set_aanc_level(); return ret; } diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 4f03c17d1d94..ef161439aae6 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -10027,6 +10027,17 @@ struct afe_param_id_cdc_aanc_version { uint32_t aanc_hw_version; } __packed; +#define AFE_PARAM_ID_AANC_NOISE_REDUCTION 0x000102AB +struct afe_param_id_aanc_noise_reduction { + /* Minor version used for tracking the version of the module's + * hw version + */ + uint32_t minor_version; + + /* Target noise level */ + int32_t ad_beta; +} __packed; + struct afe_param_id_clip_bank_sel { /* Minor version used for tracking the version of the module's * hw version diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index e3ec1bc971fa..e39d0b89d578 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -303,6 +303,7 @@ struct aanc_data { uint16_t aanc_tx_port; uint32_t aanc_rx_port_sample_rate; uint32_t aanc_tx_port_sample_rate; + int level; }; int afe_open(u16 port_id, union afe_port_config *afe_config, int rate); @@ -397,6 +398,7 @@ void afe_clear_config(enum afe_config_type config); bool afe_has_config(enum afe_config_type config); void afe_set_aanc_info(struct aanc_data *aanc_info); +int afe_set_aanc_noise_level(int val); int afe_port_group_set_param(u16 group_id, union afe_port_group_config *afe_group_config); int afe_port_group_enable(u16 group_id, -- GitLab From b8526cc457162de404f0c07c9592ac921a96df65 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Mon, 25 Jun 2018 13:14:02 +0530 Subject: [PATCH 0353/1645] asoc: fix for reading dt file for codec dma node Read 32bit instead of 16bit from dt files for codec dma dai id. CRs-Fixed: 2248380 Change-Id: I7d49e0530df7261a9a5d2bb8a742ebe3095cc9d0 Signed-off-by: Mangesh Kunchamwar --- asoc/msm-dai-q6-v2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 3b259bc389ed..da83894a4e6d 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -9673,12 +9673,12 @@ static const struct snd_soc_component_driver msm_q6_cdc_dma_dai_component = { static int msm_dai_q6_cdc_dma_dev_probe(struct platform_device *pdev) { const char *q6_cdc_dma_dev_id = "qcom,msm-dai-cdc-dma-dev-id"; - u16 cdc_dma_id = 0; + u32 cdc_dma_id = 0; int i; int rc = 0; struct msm_dai_q6_cdc_dma_dai_data *dai_data = NULL; - rc = of_property_read_u16(pdev->dev.of_node, q6_cdc_dma_dev_id, + rc = of_property_read_u32(pdev->dev.of_node, q6_cdc_dma_dev_id, &cdc_dma_id); if (rc) { dev_err(&pdev->dev, -- GitLab From 811fbfda8b13bd52fe1cc28b461804e3ee01fa63 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Mon, 25 Jun 2018 14:25:12 +0530 Subject: [PATCH 0354/1645] asoc: qcs405: fix codec dma dai ids Fix codec dma dai ids in machine driver same as ids present in DT files. CRs-Fixed: 2248380 Change-Id: I48d121e7343a695d67fc82da0a5c335970ccb819 Signed-off-by: Mangesh Kunchamwar --- asoc/qcs405.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index c2d99425676a..80f7acc02dcf 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -6626,7 +6626,7 @@ static struct snd_soc_dai_link msm_va_cdc_dma_be_dai_links[] = { { .name = LPASS_BE_VA_CDC_DMA_TX_0, .stream_name = "VA CDC DMA0 Capture", - .cpu_dai_name = "msm-dai-cdc-dma.49153", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45089", .platform_name = "msm-pcm-routing", .codec_name = "bolero_codec", .codec_dai_name = "va_macro_tx1", @@ -6641,7 +6641,7 @@ static struct snd_soc_dai_link msm_va_cdc_dma_be_dai_links[] = { { .name = LPASS_BE_VA_CDC_DMA_TX_1, .stream_name = "VA CDC DMA1 Capture", - .cpu_dai_name = "msm-dai-cdc-dma.49155", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45091", .platform_name = "msm-pcm-routing", .codec_name = "bolero_codec", .codec_dai_name = "va_macro_tx2", @@ -6901,34 +6901,33 @@ static struct snd_soc_dai_link msm_stub_be_dai_links[] = { /* Backend DAI Links */ { - .name = LPASS_BE_SLIMBUS_0_RX, - .stream_name = "Slimbus Playback", - .cpu_dai_name = "msm-dai-q6-dev.16384", + .name = LPASS_BE_VA_CDC_DMA_TX_0, + .stream_name = "VA CDC DMA0 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45089", .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", + .codec_name = "bolero_codec", + .codec_dai_name = "va_macro_tx1", .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, - .init = &msm_audrx_stub_init, + .dpcm_capture = 1, + .init = &msm_va_cdc_dma_init, + .id = MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, /* dai link has playback support */ .ignore_suspend = 1, - .ops = &msm_stub_be_ops, + .ops = &msm_cdc_dma_be_ops, }, { - .name = LPASS_BE_SLIMBUS_0_TX, - .stream_name = "Slimbus Capture", - .cpu_dai_name = "msm-dai-q6-dev.16385", + .name = LPASS_BE_VA_CDC_DMA_TX_1, + .stream_name = "VA CDC DMA1 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45091", .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", + .codec_name = "bolero_codec", + .codec_dai_name = "va_macro_tx2", .no_pcm = 1, .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .id = MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_suspend = 1, - .ops = &msm_stub_be_ops, + .ops = &msm_cdc_dma_be_ops, }, }; -- GitLab From fa05d98918db0b871e701501682d3379a134c5c1 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 14 Jun 2018 20:19:17 +0530 Subject: [PATCH 0355/1645] asoc: bolero: Add micbias support for VA DMICs Add support for regulator enable and disable to source micbias for VA digital mics. Change-Id: Ie25fb65103704b04127b23f4c515d6d270f4abf0 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/va-macro.c | 100 +++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 1eff79d2bef0..5e9e096275cb 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -95,6 +96,10 @@ struct va_macro_priv { s32 dmic_6_7_clk_cnt; u16 va_mclk_users; char __iomem *va_io_base; + struct regulator *micb_supply; + u32 micb_voltage; + u32 micb_current; + int micb_users; }; static bool va_macro_get_data(struct snd_soc_codec *codec, @@ -541,7 +546,65 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, static int va_macro_enable_micbias(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - /* Add code to enable/disable regulalator? */ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + int ret = 0; + + if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + return -EINVAL; + + if (!va_priv->micb_supply) { + dev_err(va_dev, + "%s:regulator not provided in dtsi\n", __func__); + return -EINVAL; + } + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (va_priv->micb_users++ > 0) + return 0; + ret = regulator_set_voltage(va_priv->micb_supply, + va_priv->micb_voltage, + va_priv->micb_voltage); + if (ret) { + dev_err(va_dev, "%s: Setting voltage failed, err = %d\n", + __func__, ret); + return ret; + } + ret = regulator_set_load(va_priv->micb_supply, + va_priv->micb_current); + if (ret) { + dev_err(va_dev, "%s: Setting current failed, err = %d\n", + __func__, ret); + return ret; + } + ret = regulator_enable(va_priv->micb_supply); + if (ret) { + dev_err(va_dev, "%s: regulator enable failed, err = %d\n", + __func__, ret); + return ret; + } + break; + case SND_SOC_DAPM_POST_PMD: + if (--va_priv->micb_users > 0) + return 0; + if (va_priv->micb_users < 0) { + va_priv->micb_users = 0; + dev_dbg(va_dev, "%s: regulator already disabled\n", + __func__); + return 0; + } + ret = regulator_disable(va_priv->micb_supply); + if (ret) { + dev_err(va_dev, "%s: regulator disable failed, err = %d\n", + __func__, ret); + return ret; + } + regulator_set_voltage(va_priv->micb_supply, 0, + va_priv->micb_voltage); + regulator_set_load(va_priv->micb_supply, 0); + break; + } return 0; } @@ -1296,6 +1359,9 @@ static int va_macro_probe(struct platform_device *pdev) char __iomem *va_io_base; struct clk *va_core_clk; bool va_without_decimation = false; + const char *micb_supply_str = "va-vdd-micb-supply"; + const char *micb_voltage_str = "qcom,va-vdd-micb-voltage"; + const char *micb_current_str = "qcom,va-vdd-micb-current"; int ret = 0; va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv), @@ -1331,6 +1397,38 @@ static int va_macro_probe(struct platform_device *pdev) } va_priv->va_core_clk = va_core_clk; + if (of_parse_phandle(pdev->dev.of_node, micb_supply_str, 0)) { + va_priv->micb_supply = devm_regulator_get(&pdev->dev, + micb_supply_str); + if (IS_ERR(va_priv->micb_supply)) { + ret = PTR_ERR(va_priv->micb_supply); + dev_err(&pdev->dev, + "%s:Failed to get micbias supply for VA Mic\n", + __func__, ret); + return ret; + } + ret = of_property_read_u32(pdev->dev.of_node, + micb_voltage_str, + &va_priv->micb_voltage); + if (ret) { + dev_err(&pdev->dev, + "%s:Looking up %s property in node %s failed\n", + __func__, micb_voltage_str, + pdev->dev.of_node->full_name); + return ret; + } + ret = of_property_read_u32(pdev->dev.of_node, + micb_current_str, + &va_priv->micb_current); + if (ret) { + dev_err(&pdev->dev, + "%s:Looking up %s property in node %s failed\n", + __func__, micb_current_str, + pdev->dev.of_node->full_name); + return ret; + } + } + mutex_init(&va_priv->mclk_lock); dev_set_drvdata(&pdev->dev, va_priv); va_macro_init_ops(&ops, va_io_base, va_without_decimation); -- GitLab From 135d405d2e68183ad64c2a5b48ea63683a3819f2 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 18 Jun 2018 20:28:53 +0530 Subject: [PATCH 0356/1645] asoc: bolero: Update dmic sample rate config for VA macro Add support for DMICs of different sampling rates with respective clk_div config update in VA macro register. Change-Id: I8faa46774cf1fe561af3bd7a284bc7d37f85cb9d Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/va-macro.c | 91 +++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 5e9e096275cb..554ed90415d5 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -39,7 +39,11 @@ #define CF_MIN_3DB_75HZ 0x1 #define CF_MIN_3DB_150HZ 0x2 +#define VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED 0 +#define VA_MACRO_MCLK_FREQ 9600000 #define VA_MACRO_TX_PATH_OFFSET 0x80 +#define VA_MACRO_TX_DMIC_CLK_DIV_MASK 0x0E +#define VA_MACRO_TX_DMIC_CLK_DIV_SHFT 0x01 #define BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS 40 @@ -66,6 +70,15 @@ enum { VA_MACRO_DEC_MAX, }; +enum { + VA_MACRO_CLK_DIV_2, + VA_MACRO_CLK_DIV_3, + VA_MACRO_CLK_DIV_4, + VA_MACRO_CLK_DIV_6, + VA_MACRO_CLK_DIV_8, + VA_MACRO_CLK_DIV_16, +}; + struct va_mute_work { struct va_macro_priv *va_priv; u32 decimator; @@ -94,6 +107,7 @@ struct va_macro_priv { s32 dmic_2_3_clk_cnt; s32 dmic_4_5_clk_cnt; s32 dmic_6_7_clk_cnt; + u16 dmic_clk_div; u16 va_mclk_users; char __iomem *va_io_base; struct regulator *micb_supply; @@ -415,22 +429,22 @@ static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w, case 0: case 1: dmic_clk_cnt = &(va_priv->dmic_0_1_clk_cnt); - dmic_clk_reg = BOLERO_CDC_VA_TX0_TX_PATH_CTL; + dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL; break; case 2: case 3: dmic_clk_cnt = &(va_priv->dmic_2_3_clk_cnt); - dmic_clk_reg = BOLERO_CDC_VA_TX1_TX_PATH_CTL; + dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL; break; case 4: case 5: dmic_clk_cnt = &(va_priv->dmic_4_5_clk_cnt); - dmic_clk_reg = BOLERO_CDC_VA_TX2_TX_PATH_CTL; + dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL; break; case 6: case 7: dmic_clk_cnt = &(va_priv->dmic_6_7_clk_cnt); - dmic_clk_reg = BOLERO_CDC_VA_TX3_TX_PATH_CTL; + dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL; break; default: dev_err(va_dev, "%s: Invalid DMIC Selection\n", @@ -446,6 +460,10 @@ static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w, if (*dmic_clk_cnt == 1) { snd_soc_update_bits(codec, dmic_clk_reg, dmic_clk_en, dmic_clk_en); + snd_soc_update_bits(codec, dmic_clk_reg, + VA_MACRO_TX_DMIC_CLK_DIV_MASK, + va_priv->dmic_clk_div << + VA_MACRO_TX_DMIC_CLK_DIV_SHFT); } break; case SND_SOC_DAPM_POST_PMD: @@ -1255,6 +1273,56 @@ static const struct snd_kcontrol_new va_macro_snd_controls[] = { 0, -84, 40, digital_gain), }; +static int va_macro_validate_dmic_sample_rate(u32 dmic_sample_rate, + struct va_macro_priv *va_priv) +{ + u32 div_factor; + u32 mclk_rate = VA_MACRO_MCLK_FREQ; + + if (dmic_sample_rate == VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED || + mclk_rate % dmic_sample_rate != 0) + goto undefined_rate; + + div_factor = mclk_rate / dmic_sample_rate; + + switch (div_factor) { + case 2: + va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_2; + break; + case 3: + va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_3; + break; + case 4: + va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_4; + break; + case 6: + va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_6; + break; + case 8: + va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_8; + break; + case 16: + va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_16; + break; + default: + /* Any other DIV factor is invalid */ + goto undefined_rate; + } + + /* Valid dmic DIV factors */ + dev_dbg(va_priv->dev, "%s: DMIC_DIV = %u, mclk_rate = %u\n", + __func__, div_factor, mclk_rate); + + return dmic_sample_rate; + +undefined_rate: + dev_dbg(va_priv->dev, "%s: Invalid rate %d, for mclk %d\n", + __func__, dmic_sample_rate, mclk_rate); + dmic_sample_rate = VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED; + + return dmic_sample_rate; +} + static int va_macro_init(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); @@ -1355,7 +1423,7 @@ static int va_macro_probe(struct platform_device *pdev) { struct macro_ops ops; struct va_macro_priv *va_priv; - u32 va_base_addr; + u32 va_base_addr, sample_rate = 0; char __iomem *va_io_base; struct clk *va_core_clk; bool va_without_decimation = false; @@ -1363,6 +1431,7 @@ static int va_macro_probe(struct platform_device *pdev) const char *micb_voltage_str = "qcom,va-vdd-micb-voltage"; const char *micb_current_str = "qcom,va-vdd-micb-current"; int ret = 0; + const char *dmic_sample_rate = "qcom,va-dmic-sample-rate"; va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv), GFP_KERNEL); @@ -1381,6 +1450,18 @@ static int va_macro_probe(struct platform_device *pdev) "qcom,va-without-decimation"); va_priv->va_without_decimation = va_without_decimation; + ret = of_property_read_u32(pdev->dev.of_node, dmic_sample_rate, + &sample_rate); + if (ret) { + dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, sample_rate); + va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_2; + } else { + if (va_macro_validate_dmic_sample_rate( + sample_rate, va_priv) == VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED) + return -EINVAL; + } + va_io_base = devm_ioremap(&pdev->dev, va_base_addr, VA_MAX_OFFSET); if (!va_io_base) { -- GitLab From baf28399224bf9dfe4a330ed13f26eb5a42a1186 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Fri, 22 Jun 2018 15:22:27 -0700 Subject: [PATCH 0357/1645] dsp: q6afe: fix sleeping function called from invalid context afe_callback indirectly calls q6core_send_uevent which might sleep due to use of mutex. Move this send uevent function call to work queue to prevent the issue. Change-Id: I74ad151a9bae84860059d0a11042cda6475394c2 Signed-off-by: Xiaoyu Ye --- dsp/q6afe.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index c17721046256..0b92052885df 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -131,6 +131,7 @@ struct afe_ctl { struct afe_fw_info *fw_data; u32 island_mode[AFE_MAX_PORTS]; struct vad_config vad_cfg[AFE_MAX_PORTS]; + struct work_struct afe_dc_work; }; static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX]; @@ -335,15 +336,21 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, } static void afe_notify_dc_presence(void) +{ + msm_aud_evt_notifier_call_chain(MSM_AUD_DC_EVENT, NULL); + + schedule_work(&this_afe.afe_dc_work); +} + +static void afe_notify_dc_presence_work_fn(struct work_struct *work) { int ret = 0; char event[] = "DC_PRESENCE=TRUE"; - msm_aud_evt_notifier_call_chain(MSM_AUD_DC_EVENT, NULL); - ret = q6core_send_uevent(this_afe.uevent_data, event); if (ret) - pr_err("%s: Send UEvent %s failed :%d\n", __func__, event, ret); + pr_err("%s: Send UEvent %s failed :%d\n", + __func__, event, ret); } static int32_t afe_callback(struct apr_client_data *data, void *priv) @@ -7575,6 +7582,8 @@ int __init afe_init(void) this_afe.uevent_data->ktype.release = afe_release_uevent_data; q6core_init_uevent_data(this_afe.uevent_data, "q6afe_uevent"); + INIT_WORK(&this_afe.afe_dc_work, afe_notify_dc_presence_work_fn); + return 0; } -- GitLab From a6a8b113f34c30e46863054ccf7943602e301873 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Fri, 22 Jun 2018 14:51:33 +0530 Subject: [PATCH 0358/1645] asoc: configs: cleanup qcs405 config files Remove not needed modules from the config files. CRs-Fixed: 2248380 Change-Id: I38982c81bc79b7ed24aa835f011e40cbebee3df8 Signed-off-by: Mangesh Kunchamwar --- config/qcs405auto.conf | 13 ++++--------- config/qcs405autoconf.h | 6 ------ 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/config/qcs405auto.conf b/config/qcs405auto.conf index d15f44b1525c..c211830865a0 100644 --- a/config/qcs405auto.conf +++ b/config/qcs405auto.conf @@ -1,35 +1,30 @@ -CONFIG_PINCTRL_WCD=m CONFIG_PINCTRL_LPI=m CONFIG_AUDIO_EXT_CLK=m CONFIG_SND_SOC_WCD9XXX_V2=m CONFIG_SND_SOC_WSA881X=m -CONFIG_SND_SOC_WCD_DSP_MGR=m -CONFIG_SOUNDWIRE_MSTR_CTRL=m +CONFIG_SND_SOC_WCD9335=m CONFIG_WCD9XXX_CODEC_CORE=m CONFIG_MSM_CDC_PINCTRL=m -CONFIG_SND_SOC_WCD9335=m CONFIG_MSM_QDSP6V2_CODECS=m CONFIG_MSM_ULTRASOUND=m CONFIG_MSM_QDSP6_APRV2_RPMSG=m +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m CONFIG_MSM_ADSP_LOADER=m CONFIG_REGMAP_SWR=m CONFIG_MSM_QDSP6_SSR=m CONFIG_MSM_QDSP6_PDR=m CONFIG_MSM_QDSP6_NOTIFIER=m CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m CONFIG_SND_SOC_QCS405=m CONFIG_SND_SOC_BOLERO=m CONFIG_WSA_MACRO=m CONFIG_VA_MACRO=m -CONFIG_MSM_GLINK_SPI_XPRT=m -CONFIG_WCD_DSP_GLINK=m CONFIG_SOUNDWIRE=m -CONFIG_SND_SOC_QDSP6V2=m +CONFIG_SOUNDWIRE_MSTR_CTRL=m CONFIG_SND_SOC_WCD_MBHC_LEGACY=m +CONFIG_SND_SOC_QDSP6V2=m CONFIG_QTI_PP=m CONFIG_SND_HWDEP_ROUTING=m -CONFIG_SND_HWDEP=m CONFIG_DTS_EAGLE=m CONFIG_DOLBY_DS2=m CONFIG_DOLBY_LICENSE=m diff --git a/config/qcs405autoconf.h b/config/qcs405autoconf.h index c9ce150c8934..e4591e30e27b 100644 --- a/config/qcs405autoconf.h +++ b/config/qcs405autoconf.h @@ -10,12 +10,10 @@ * GNU General Public License for more details. */ -#define CONFIG_PINCTRL_WCD 1 #define CONFIG_PINCTRL_LPI 1 #define CONFIG_AUDIO_EXT_CLK 1 #define CONFIG_SND_SOC_WCD9XXX_V2 1 #define CONFIG_SND_SOC_WSA881X 1 -#define CONFIG_SND_SOC_WCD_DSP_MGR 1 #define CONFIG_SND_SOC_WCD9335 1 #define CONFIG_WCD9XXX_CODEC_CORE 1 #define CONFIG_MSM_CDC_PINCTRL 1 @@ -33,20 +31,16 @@ #define CONFIG_SND_SOC_BOLERO 1 #define CONFIG_WSA_MACRO 1 #define CONFIG_VA_MACRO 1 -#define CONFIG_MSM_GLINK_SPI_XPRT 1 -#define CONFIG_WCD_DSP_GLINK 1 #define CONFIG_SOUNDWIRE 1 #define CONFIG_SOUNDWIRE_MSTR_CTRL 1 #define CONFIG_SND_SOC_WCD_MBHC_LEGACY 1 #define CONFIG_SND_SOC_QDSP6V2 1 #define CONFIG_QTI_PP 1 #define CONFIG_SND_HWDEP_ROUTING 1 -#define CONFIG_SND_HWDEP 1 #define CONFIG_DTS_EAGLE 1 #define CONFIG_DOLBY_DS2 1 #define CONFIG_DOLBY_LICENSE 1 #define CONFIG_DTS_SRS_TM 1 -#define CONFIG_WCD9XXX_CODEC_CORE 1 #define CONFIG_SND_SOC_MSM_STUB 1 #define CONFIG_MSM_AVTIMER 1 #define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 -- GitLab From 36ab7bb29c9572afc58bc283c58e5e115fcc848f Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 18 Jun 2018 18:43:46 +0530 Subject: [PATCH 0359/1645] asoc: bolero: Add EC support for WSA macro WSA macro supports both ec_legacy and ec_hq. Add support to capture echo for both types based on mixer control value. Change-Id: I3c8a6cd13dabbee3f3687d5e63dc6d4c7bbc4eef Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/wsa-macro.c | 124 +++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index fe22cb3cb609..ff15e14faa66 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -70,6 +70,12 @@ enum { WSA_MACRO_TX_MAX, }; +enum { + WSA_MACRO_EC0_MUX = 0, + WSA_MACRO_EC1_MUX, + WSA_MACRO_EC_MUX_MAX, +}; + enum { WSA_MACRO_COMP1, /* SPK_L */ WSA_MACRO_COMP2, /* SPK_R */ @@ -148,6 +154,7 @@ enum { /* * @dev: wsa macro device pointer * @comp_enabled: compander enable mixer value set + * @ec_hq: echo HQ enable mixer value set * @prim_int_users: Users of interpolator * @wsa_mclk_users: WSA MCLK users count * @swr_clk_users: SWR clk users count @@ -171,6 +178,7 @@ enum { struct wsa_macro_priv { struct device *dev; int comp_enabled[WSA_MACRO_COMP_MAX]; + int ec_hq[WSA_MACRO_RX1 + 1]; u16 prim_int_users[WSA_MACRO_RX1 + 1]; u16 wsa_mclk_users; u16 swr_clk_users; @@ -212,6 +220,10 @@ static const char *const rx_mix_text[] = { "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1" }; +static const char *const rx_mix_ec_text[] = { + "ZERO", "RX_MIX_TX0", "RX_MIX_TX1" +}; + static const char *const rx_mux_text[] = { "ZERO", "AIF1_PB", "AIF_MIX1_PB" }; @@ -288,6 +300,20 @@ static const struct snd_kcontrol_new rx1_prim_inp2_mux = static const struct snd_kcontrol_new rx1_mix_mux = SOC_DAPM_ENUM("WSA_RX1 MIX Mux", rx1_mix_chain_enum); +static const struct soc_enum rx_mix_ec0_enum = + SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0, + 0, 3, rx_mix_ec_text); + +static const struct soc_enum rx_mix_ec1_enum = + SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0, + 3, 3, rx_mix_ec_text); + +static const struct snd_kcontrol_new rx_mix_ec0_mux = + SOC_DAPM_ENUM("WSA RX_MIX EC0_Mux", rx_mix_ec0_enum); + +static const struct snd_kcontrol_new rx_mix_ec1_mux = + SOC_DAPM_ENUM("WSA RX_MIX EC1_Mux", rx_mix_ec1_enum); + static struct snd_soc_dai_ops wsa_macro_dai_ops = { .hw_params = wsa_macro_hw_params, .get_channel_map = wsa_macro_get_channel_map, @@ -1317,6 +1343,84 @@ static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w, return 0; } +static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + u16 val, ec_tx = 0, ec_hq_reg; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + dev_dbg(wsa_dev, "%s %d %s\n", __func__, event, w->name); + + val = snd_soc_read(codec, BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0); + if (!(strcmp(w->name, "WSA RX_MIX EC0_MUX"))) + ec_tx = (val & 0x07) - 1; + else + ec_tx = ((val & 0x38) >> 0x3) - 1; + + if (ec_tx < 0 || ec_tx >= (WSA_MACRO_RX1 + 1)) { + dev_err(wsa_dev, "%s: EC mix control not set correctly\n", + __func__); + return -EINVAL; + } + if (wsa_priv->ec_hq[ec_tx]) { + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0, + 0x1 << ec_tx, 0x1 << ec_tx); + ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL + + 0x20 * ec_tx; + snd_soc_update_bits(codec, ec_hq_reg, 0x01, 0x01); + ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 + + 0x20 * ec_tx; + /* default set to 48k */ + snd_soc_update_bits(codec, ec_hq_reg, 0x1E, 0x08); + } + + return 0; +} + +static int wsa_macro_get_ec_hq(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int ec_tx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = wsa_priv->ec_hq[ec_tx]; + return 0; +} + +static int wsa_macro_set_ec_hq(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int ec_tx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int value = ucontrol->value.integer.value[0]; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + dev_dbg(wsa_dev, "%s: enable current %d, new %d\n", + __func__, wsa_priv->ec_hq[ec_tx], value); + wsa_priv->ec_hq[ec_tx] = value; + + return 0; +} + static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1542,6 +1646,10 @@ static const struct snd_kcontrol_new wsa_macro_snd_controls[] = { wsa_macro_get_compander, wsa_macro_set_compander), SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0, wsa_macro_get_compander, wsa_macro_set_compander), + SOC_SINGLE_EXT("WSA_RX0 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX0, + 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq), + SOC_SINGLE_EXT("WSA_RX1 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX1, + 1, 0, wsa_macro_get_ec_hq, wsa_macro_set_ec_hq), }; static const struct soc_enum rx_mux_enum = @@ -1662,6 +1770,14 @@ static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = { SND_SOC_DAPM_MIXER("WSA_AIF_VI Mixer", SND_SOC_NOPM, WSA_MACRO_AIF_VI, 0, aif_vi_mixer, ARRAY_SIZE(aif_vi_mixer)), + SND_SOC_DAPM_MUX_E("WSA RX_MIX EC0_MUX", SND_SOC_NOPM, + WSA_MACRO_EC0_MUX, 0, + &rx_mix_ec0_mux, wsa_macro_enable_echo, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("WSA RX_MIX EC1_MUX", SND_SOC_NOPM, + WSA_MACRO_EC1_MUX, 0, + &rx_mix_ec1_mux, wsa_macro_enable_echo, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MUX("WSA RX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX0, 0, &rx_mux[WSA_MACRO_RX0]), @@ -1738,6 +1854,14 @@ static const struct snd_soc_dapm_route wsa_audio_map[] = { {"WSA AIF_VI", NULL, "WSA_AIF_VI Mixer"}, {"WSA AIF_VI", NULL, "WSA_MCLK"}, + {"WSA RX_MIX EC0_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"}, + {"WSA RX_MIX EC1_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"}, + {"WSA RX_MIX EC0_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"}, + {"WSA RX_MIX EC1_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"}, + {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC0_MUX"}, + {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC1_MUX"}, + {"WSA AIF_ECHO", NULL, "WSA_MCLK"}, + {"WSA AIF1 PB", NULL, "WSA_MCLK"}, {"WSA AIF_MIX1 PB", NULL, "WSA_MCLK"}, -- GitLab From f7b5f39f7471f0ce5d0dfeedf956310351bdb3a9 Mon Sep 17 00:00:00 2001 From: Dhananjay Kumar Date: Tue, 19 Jun 2018 06:01:46 +0530 Subject: [PATCH 0360/1645] uapi: lsm_params: add support for ADSP multi stage VA Enhance APIs to get instance id and stage info from userspace, required for multi-stage Voice Activation in ADSP. Change-Id: I82703c63214925173f3f978339188ccddff8ba91 Signed-off-by: Dhananjay Kumar --- include/uapi/sound/lsm_params.h | 75 ++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/include/uapi/sound/lsm_params.h b/include/uapi/sound/lsm_params.h index 3c28baacd5b1..57dc3be5d454 100644 --- a/include/uapi/sound/lsm_params.h +++ b/include/uapi/sound/lsm_params.h @@ -7,7 +7,10 @@ #include #include -#define SNDRV_LSM_VERSION SNDRV_PROTOCOL_VERSION(0, 3, 0) +#define SNDRV_LSM_VERSION SNDRV_PROTOCOL_VERSION(0, 3, 1) + +#define LSM_MAX_STAGES_PER_SESSION 2 +#define LSM_STAGE_INDEX_FIRST 0 #define LSM_OUT_FORMAT_PCM (0) #define LSM_OUT_FORMAT_ADPCM (1 << 0) @@ -30,7 +33,8 @@ #define LSM_CUSTOM_PARAMS (6) #define LSM_POLLING_ENABLE (7) #define LSM_DET_EVENT_TYPE (8) -#define LSM_PARAMS_MAX (LSM_DET_EVENT_TYPE + 1) +#define LSM_LAB_CONTROL (9) +#define LSM_PARAMS_MAX (LSM_LAB_CONTROL + 1) #define LSM_EVENT_NON_TIME_STAMP_MODE (0) #define LSM_EVENT_TIME_STAMP_MODE (1) @@ -126,6 +130,36 @@ struct snd_lsm_session_data { enum lsm_app_id app_id; }; +/* + * Stage info for multi-stage session + * @app_type: acdb app_type to be used to map topology/cal for the stage + * @lpi_enable: low power island mode applicable for the stage + */ +struct snd_lsm_stage_info { + __u32 app_type; + __u32 lpi_enable; +}; + +/* + * Session info for multi-stage session + * @app_id: VoiceWakeup engine id, this is now used to just validate input arg + * @num_stages: number of detection stages to be used + * @stage_info: stage info for each of the stage being used, ordered by index + */ +struct snd_lsm_session_data_v2 { + enum lsm_app_id app_id; + __u32 num_stages; + struct snd_lsm_stage_info stage_info[LSM_MAX_STAGES_PER_SESSION]; +}; + +/* + * Data for LSM_LAB_CONTROL param_type + * @enable: lab enable or disable + */ +struct snd_lsm_lab_control { + __u32 enable; +}; + struct snd_lsm_event_status { __u16 status; __u16 payload_size; @@ -162,6 +196,7 @@ struct snd_lsm_detection_params { * For CONFIDENCE_LEVELS, this is array of confidence levels * For REG_SND_MODEL, this is the sound model data * For CUSTOM_PARAMS, this is the blob of custom data. + * @param_type: Parameter type as defined in values upto LSM_PARAMS_MAX */ struct lsm_params_info { __u32 module_id; @@ -171,6 +206,38 @@ struct lsm_params_info { uint32_t param_type; }; +/* + * Param info(version 2) for each parameter type + * + * Existing member variables: + * @module_id: Module to which parameter is to be set + * @param_id: Parameter that is to be set + * @param_size: size (in number of bytes) for the data + * in param_data. + * For confidence levels, this is num_conf_levels + * For REG_SND_MODEL, this is size of sound model + * For CUSTOM_PARAMS, this is size of the entire blob of data + * @param_data: Data for the parameter. + * For some param_types this is a structure defined, ex: LSM_GAIN + * For CONFIDENCE_LEVELS, this is array of confidence levels + * For REG_SND_MODEL, this is the sound model data + * For CUSTOM_PARAMS, this is the blob of custom data. + * @param_type: Parameter type as defined in values upto LSM_PARAMS_MAX + * + * Member variables applicable only to V2: + * @instance_id: instance id of the param to which parameter is to be set + * @stage_idx: detection stage for which the param is applicable + */ +struct lsm_params_info_v2 { + __u32 module_id; + __u32 param_id; + __u32 param_size; + __u8 __user *param_data; + uint32_t param_type; + __u16 instance_id; + __u16 stage_idx; +}; + /* * Data passed to the SET_PARAM_V2 IOCTL * @num_params: Number of params that are to be set @@ -240,5 +307,9 @@ struct snd_lsm_input_hw_params { #define SNDRV_LSM_GENERIC_DET_EVENT _IOW('U', 0x10, struct snd_lsm_event_status) #define SNDRV_LSM_SET_INPUT_HW_PARAMS _IOW('U', 0x11, \ struct snd_lsm_input_hw_params) +#define SNDRV_LSM_SET_SESSION_DATA_V2 _IOW('U', 0x12, \ + struct snd_lsm_session_data_v2) +#define SNDRV_LSM_SET_MODULE_PARAMS_V2 _IOW('U', 0x13, \ + struct snd_lsm_module_params) #endif -- GitLab From ce6ec5fcf269c6b13c5619bac186e13a9eebd0fb Mon Sep 17 00:00:00 2001 From: Dhananjay Kumar Date: Tue, 19 Jun 2018 06:07:29 +0530 Subject: [PATCH 0361/1645] lsm: add support for ADSP multi stage VA Enhance APIs to get instance id and stage info from userspace, required for multi-stage Voice Activation in ADSP. Change-Id: Ie39a3d002a56fb8df0c241089a50d55ef700a538 Signed-off-by: Dhananjay Kumar --- asoc/msm-lsm-client.c | 565 ++++++++++++++++++++++++------------- dsp/q6lsm.c | 503 ++++++++++++++++++++++----------- include/dsp/apr_audio-v2.h | 1 + include/dsp/q6lsm.h | 52 +++- 4 files changed, 757 insertions(+), 364 deletions(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 3ecafbccec65..e0eeef3c4973 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -42,6 +42,9 @@ #define LAB_BUFFER_ALLOC 1 #define LAB_BUFFER_DEALLOC 0 +#define LSM_IS_LAST_STAGE(client, stage_idx) \ + (client->num_stages == (stage_idx + 1)) + static struct snd_pcm_hardware msm_pcm_hardware_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -463,7 +466,7 @@ static int msm_lsm_get_conf_levels(struct lsm_client *client, } static int msm_lsm_set_epd(struct snd_pcm_substream *substream, - struct lsm_params_info *p_info) + struct lsm_params_info_v2 *p_info) { struct snd_pcm_runtime *runtime = substream->runtime; struct lsm_priv *prtd = runtime->private_data; @@ -499,7 +502,7 @@ static int msm_lsm_set_epd(struct snd_pcm_substream *substream, } static int msm_lsm_set_mode(struct snd_pcm_substream *substream, - struct lsm_params_info *p_info) + struct lsm_params_info_v2 *p_info) { struct snd_pcm_runtime *runtime = substream->runtime; struct lsm_priv *prtd = runtime->private_data; @@ -535,7 +538,7 @@ static int msm_lsm_set_mode(struct snd_pcm_substream *substream, } static int msm_lsm_set_gain(struct snd_pcm_substream *substream, - struct lsm_params_info *p_info) + struct lsm_params_info_v2 *p_info) { struct snd_pcm_runtime *runtime = substream->runtime; struct lsm_priv *prtd = runtime->private_data; @@ -571,7 +574,7 @@ static int msm_lsm_set_gain(struct snd_pcm_substream *substream, } static int msm_lsm_set_conf(struct snd_pcm_substream *substream, - struct lsm_params_info *p_info) + struct lsm_params_info_v2 *p_info) { struct snd_pcm_runtime *runtime = substream->runtime; struct lsm_priv *prtd = runtime->private_data; @@ -608,18 +611,17 @@ static int msm_lsm_set_conf(struct snd_pcm_substream *substream, } static int msm_lsm_reg_model(struct snd_pcm_substream *substream, - struct lsm_params_info *p_info) + struct lsm_params_info_v2 *p_info) { struct snd_pcm_runtime *runtime = substream->runtime; struct lsm_priv *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data; int rc = 0; - u8 *snd_model_ptr; - size_t offset; + struct lsm_sound_model *sm = NULL; + size_t offset = sizeof(union param_hdrs); rc = q6lsm_snd_model_buf_alloc(prtd->lsm_client, - p_info->param_size, - true); + p_info->param_size, p_info); if (rc) { dev_err(rtd->dev, "%s: snd_model buf alloc failed, size = %d\n", @@ -633,9 +635,9 @@ static int msm_lsm_reg_model(struct snd_pcm_substream *substream, * For set_param, advance the sound model data with the * number of bytes required by param_data. */ - snd_model_ptr = ((u8 *) prtd->lsm_client->sound_model.data) + offset; - if (copy_from_user(snd_model_ptr, + sm = &prtd->lsm_client->stage_cfg[p_info->stage_idx].sound_model; + if (copy_from_user((u8 *)sm->data + offset, p_info->param_data, p_info->param_size)) { dev_err(rtd->dev, "%s: copy_from_user for snd_model failed, size = %d\n", @@ -654,12 +656,12 @@ static int msm_lsm_reg_model(struct snd_pcm_substream *substream, return rc; err_copy: - q6lsm_snd_model_buf_free(prtd->lsm_client); + q6lsm_snd_model_buf_free(prtd->lsm_client, p_info); return rc; } static int msm_lsm_dereg_model(struct snd_pcm_substream *substream, - struct lsm_params_info *p_info) + struct lsm_params_info_v2 *p_info) { struct snd_pcm_runtime *runtime = substream->runtime; struct lsm_priv *prtd = runtime->private_data; @@ -673,13 +675,13 @@ static int msm_lsm_dereg_model(struct snd_pcm_substream *substream, "%s: Failed to set det_mode param, err = %d\n", __func__, rc); - q6lsm_snd_model_buf_free(prtd->lsm_client); + q6lsm_snd_model_buf_free(prtd->lsm_client, p_info); return rc; } static int msm_lsm_set_custom(struct snd_pcm_substream *substream, - struct lsm_params_info *p_info) + struct lsm_params_info_v2 *p_info) { struct snd_pcm_runtime *runtime = substream->runtime; struct lsm_priv *prtd = runtime->private_data; @@ -712,8 +714,96 @@ static int msm_lsm_set_custom(struct snd_pcm_substream *substream, return rc; } +static int msm_lsm_check_and_set_lab_controls(struct snd_pcm_substream *substream, + u32 enable, struct lsm_params_info_v2 *p_info) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct lsm_hw_params *out_hw_params = &prtd->lsm_client->out_hw_params; + u8 chmap[out_hw_params->num_chs]; + u32 ch_idx; + int rc = 0, stage_idx = p_info->stage_idx; + + if (prtd->lsm_client->stage_cfg[stage_idx].lab_enable == enable) { + dev_dbg(rtd->dev, "%s: Lab for session %d, stage %d already %s\n", + __func__, prtd->lsm_client->session, + stage_idx, enable ? "enabled" : "disabled"); + return rc; + } + + rc = q6lsm_lab_control(prtd->lsm_client, enable, p_info); + if (rc) { + dev_err(rtd->dev, "%s: Failed to set lab_control param, err = %d\n", + __func__, rc); + return rc; + } else { + if (LSM_IS_LAST_STAGE(prtd->lsm_client, stage_idx)) { + rc = msm_lsm_lab_buffer_alloc(prtd, + enable ? LAB_BUFFER_ALLOC : LAB_BUFFER_DEALLOC); + if (rc) { + dev_err(rtd->dev, + "%s: msm_lsm_lab_buffer_alloc failed rc %d for %s\n", + __func__, rc, enable ? "ALLOC" : "DEALLOC"); + return rc; + } else { + /* set client level flag based on last stage control */ + prtd->lsm_client->lab_enable = enable; + } + } + if (!rc) + prtd->lsm_client->stage_cfg[stage_idx].lab_enable = enable; + } + + memset(chmap, 0, out_hw_params->num_chs); + /* + * First channel to be read from lab is always the + * best channel (0xff). For second channel onwards, + * the channel indices are 0, 1, .. etc + */ + chmap[0] = 0xFF; + for (ch_idx = 1; ch_idx < out_hw_params->num_chs; ch_idx++) + chmap[ch_idx] = ch_idx - 1; + + rc = q6lsm_lab_out_ch_cfg(prtd->lsm_client, chmap, p_info); + if (rc) + dev_err(rtd->dev, "%s: Failed to set lab out ch cfg %d\n", + __func__, rc); + + return rc; +} + +static int msm_lsm_set_lab_control(struct snd_pcm_substream *substream, + struct lsm_params_info_v2 *p_info) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_lsm_lab_control lab_ctrl; + int rc = 0; + + if (p_info->param_size != sizeof(lab_ctrl)) + return -EINVAL; + + if (prtd->lsm_client->started) { + dev_err(rtd->dev, "%s: lab control sent after start\n", __func__); + return -EAGAIN; + } + + if (copy_from_user(&lab_ctrl, p_info->param_data, + p_info->param_size)) { + dev_err(rtd->dev, + "%s: copy_from_user failed for lab_control params, size = %d\n", + __func__, p_info->param_size); + return -EFAULT; + } + + rc = msm_lsm_check_and_set_lab_controls(substream, lab_ctrl.enable, p_info); + return rc; +} + static int msm_lsm_set_poll_enable(struct snd_pcm_substream *substream, - struct lsm_params_info *p_info) + struct lsm_params_info_v2 *p_info) { struct snd_pcm_runtime *runtime = substream->runtime; struct lsm_priv *prtd = runtime->private_data; @@ -761,7 +851,7 @@ static int msm_lsm_set_poll_enable(struct snd_pcm_substream *substream, } static int msm_lsm_set_det_event_type(struct snd_pcm_substream *substream, - struct lsm_params_info *p_info) + struct lsm_params_info_v2 *p_info) { struct snd_lsm_det_event_type det_event_type; struct snd_pcm_runtime *runtime = substream->runtime; @@ -801,65 +891,68 @@ static int msm_lsm_set_det_event_type(struct snd_pcm_substream *substream, } static int msm_lsm_process_params(struct snd_pcm_substream *substream, - struct snd_lsm_module_params *p_data, - void *params) + struct lsm_params_info_v2 *p_info) { + struct snd_pcm_runtime *runtime = substream->runtime; + struct lsm_priv *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct lsm_params_info *p_info; - int i; int rc = 0; - p_info = (struct lsm_params_info *) params; + dev_dbg(rtd->dev, + "%s: mid=0x%x, pid=0x%x, iid=0x%x, stage_idx=%d, size=0x%x, type=%d\n", + __func__, p_info->module_id, p_info->param_id, p_info->instance_id, + p_info->stage_idx, p_info->param_size, p_info->param_type); - for (i = 0; i < p_data->num_params; i++) { - dev_dbg(rtd->dev, - "%s: param (%d), module_id = 0x%x, param_id = 0x%x, param_size = 0x%x, param_type = 0x%x\n", - __func__, i, p_info->module_id, - p_info->param_id, p_info->param_size, - p_info->param_type); - - switch (p_info->param_type) { - case LSM_ENDPOINT_DETECT_THRESHOLD: - rc = msm_lsm_set_epd(substream, p_info); - break; - case LSM_OPERATION_MODE: - rc = msm_lsm_set_mode(substream, p_info); - break; - case LSM_GAIN: - rc = msm_lsm_set_gain(substream, p_info); - break; - case LSM_MIN_CONFIDENCE_LEVELS: - rc = msm_lsm_set_conf(substream, p_info); - break; - case LSM_REG_SND_MODEL: - rc = msm_lsm_reg_model(substream, p_info); - break; - case LSM_DEREG_SND_MODEL: - rc = msm_lsm_dereg_model(substream, p_info); - break; - case LSM_CUSTOM_PARAMS: - rc = msm_lsm_set_custom(substream, p_info); - break; - case LSM_POLLING_ENABLE: - rc = msm_lsm_set_poll_enable(substream, p_info); - break; - case LSM_DET_EVENT_TYPE: - rc = msm_lsm_set_det_event_type(substream, p_info); - break; - default: - dev_err(rtd->dev, - "%s: Invalid param_type %d\n", - __func__, p_info->param_type); - rc = -EINVAL; - break; - } - if (rc) { - pr_err("%s: set_param fail for param_type %d\n", - __func__, p_info->param_type); - return rc; - } + if (!prtd->lsm_client || + prtd->lsm_client->num_stages <= p_info->stage_idx) { + dev_err(rtd->dev, + "%s: invalid stage_idx(%d) for client(%p) having num_stages(%d)\n", + __func__, p_info->stage_idx, prtd->lsm_client, + prtd->lsm_client ? prtd->lsm_client->num_stages : 0); + return -EINVAL; + } - p_info++; + switch (p_info->param_type) { + case LSM_ENDPOINT_DETECT_THRESHOLD: + rc = msm_lsm_set_epd(substream, p_info); + break; + case LSM_OPERATION_MODE: + rc = msm_lsm_set_mode(substream, p_info); + break; + case LSM_GAIN: + rc = msm_lsm_set_gain(substream, p_info); + break; + case LSM_MIN_CONFIDENCE_LEVELS: + rc = msm_lsm_set_conf(substream, p_info); + break; + case LSM_REG_SND_MODEL: + rc = msm_lsm_reg_model(substream, p_info); + break; + case LSM_DEREG_SND_MODEL: + rc = msm_lsm_dereg_model(substream, p_info); + break; + case LSM_CUSTOM_PARAMS: + rc = msm_lsm_set_custom(substream, p_info); + break; + case LSM_POLLING_ENABLE: + rc = msm_lsm_set_poll_enable(substream, p_info); + break; + case LSM_DET_EVENT_TYPE: + rc = msm_lsm_set_det_event_type(substream, p_info); + break; + case LSM_LAB_CONTROL: + rc = msm_lsm_set_lab_control(substream, p_info); + break; + default: + dev_err(rtd->dev, + "%s: Invalid param_type %d\n", + __func__, p_info->param_type); + rc = -EINVAL; + break; + } + if (rc) { + pr_err("%s: set_param fail for param_type %d\n", + __func__, p_info->param_type); } return rc; @@ -897,12 +990,14 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, int ret; struct snd_lsm_sound_model_v2 snd_model_v2; struct snd_lsm_session_data session_data; - int rc = 0; + struct snd_lsm_session_data_v2 ses_data_v2 = {0}; + int rc = 0, stage_idx; int xchg = 0; struct snd_pcm_runtime *runtime; struct lsm_priv *prtd; struct snd_lsm_detection_params det_params; uint8_t *confidence_level = NULL; + uint32_t max_detection_stages_supported = LSM_MAX_STAGES_PER_SESSION; if (!substream || !substream->private_data) { pr_err("%s: Invalid %s\n", __func__, @@ -916,15 +1011,26 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_LSM_SET_SESSION_DATA: - dev_dbg(rtd->dev, "%s: set session data\n", __func__); - if (copy_from_user(&session_data, arg, - sizeof(session_data))) { + case SNDRV_LSM_SET_SESSION_DATA_V2: + + if (cmd == SNDRV_LSM_SET_SESSION_DATA) { + dev_dbg(rtd->dev, "%s: set session data\n", __func__); + rc = copy_from_user(&session_data, arg, sizeof(session_data)); + if (!rc) { + ses_data_v2.app_id = session_data.app_id; + ses_data_v2.num_stages = 1; + } + } else { + dev_dbg(rtd->dev, "%s: set session data_v2\n", __func__); + rc = copy_from_user(&ses_data_v2, arg, sizeof(ses_data_v2)); + } + if (rc) { dev_err(rtd->dev, "%s: %s: copy_from_user failed\n", - __func__, "LSM_SET_SESSION_DATA"); + __func__, "LSM_SET_SESSION_DATA(_V2)"); return -EFAULT; } - if (session_data.app_id != LSM_VOICE_WAKEUP_APP_ID_V2) { + if (ses_data_v2.app_id != LSM_VOICE_WAKEUP_APP_ID_V2) { dev_err(rtd->dev, "%s:Invalid App id %d for Listen client\n", __func__, session_data.app_id); @@ -932,9 +1038,38 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, break; } - prtd->lsm_client->app_id = session_data.app_id; - ret = q6lsm_open(prtd->lsm_client, - prtd->lsm_client->app_id); + /* + * Before validating num_stages from user argument. + * Check ADSP support for multi-stage session, + * and reset max_detection_stages_supported to "1" if required. + */ + if (!q6lsm_adsp_supports_multi_stage_detection()) { + dev_dbg(rtd->dev, + "%s: multi-stage session not supported by adsp\n", __func__); + max_detection_stages_supported = 1; + } + + if (ses_data_v2.num_stages <= 0 || + ses_data_v2.num_stages > max_detection_stages_supported) { + dev_err(rtd->dev, + "%s: Unsupported number of stages req(%d)/max(%d)\n", + __func__, ses_data_v2.num_stages, + max_detection_stages_supported); + rc = -EINVAL; + break; + } + + prtd->lsm_client->app_id = ses_data_v2.app_id; + prtd->lsm_client->num_stages = ses_data_v2.num_stages; + for (stage_idx = LSM_STAGE_INDEX_FIRST; + stage_idx < ses_data_v2.num_stages; stage_idx++) { + prtd->lsm_client->stage_cfg[stage_idx].app_type = + ses_data_v2.stage_info[stage_idx].app_type; + prtd->lsm_client->stage_cfg[stage_idx].lpi_enable = + ses_data_v2.stage_info[stage_idx].lpi_enable; + } + + ret = q6lsm_open(prtd->lsm_client, ses_data_v2.app_id); if (ret < 0) { dev_err(rtd->dev, "%s: lsm open failed, %d\n", @@ -942,12 +1077,24 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, return ret; } prtd->lsm_client->opened = true; - dev_dbg(rtd->dev, "%s: Session_ID = %d, APP ID = %d\n", + dev_dbg(rtd->dev, "%s: Session_ID = %d, APP ID = %d, Num stages %d\n", __func__, prtd->lsm_client->session, - prtd->lsm_client->app_id); + prtd->lsm_client->app_id, + prtd->lsm_client->num_stages); break; - case SNDRV_LSM_REG_SND_MODEL_V2: + case SNDRV_LSM_REG_SND_MODEL_V2: { + /* + * With multi-stage support sm buff allocation/free usage param info + * to check stage index for which this sound model is being set, and + * to check whether sm data is sent using set param command or not. + * Hence, set param ids to '0' to indicate allocation is for legacy + * reg_sm cmd, where buffer for param header need not be allocated, + * also set stage index to LSM_STAGE_INDEX_FIRST. + */ + struct lsm_params_info_v2 p_info = {0}; + p_info.stage_idx = LSM_STAGE_INDEX_FIRST; + dev_dbg(rtd->dev, "%s: Registering sound model V2\n", __func__); memcpy(&snd_model_v2, arg, @@ -962,20 +1109,21 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, break; } rc = q6lsm_snd_model_buf_alloc(prtd->lsm_client, - snd_model_v2.data_size, false); + snd_model_v2.data_size, &p_info); if (rc) { dev_err(rtd->dev, "%s: q6lsm buffer alloc failed V2, size %d\n", __func__, snd_model_v2.data_size); break; } - if (copy_from_user(prtd->lsm_client->sound_model.data, - snd_model_v2.data, snd_model_v2.data_size)) { + if (copy_from_user( + prtd->lsm_client->stage_cfg[stage_idx].sound_model.data, + snd_model_v2.data, snd_model_v2.data_size)) { dev_err(rtd->dev, "%s: copy from user data failed\n" "data %pK size %d\n", __func__, snd_model_v2.data, snd_model_v2.data_size); - q6lsm_snd_model_buf_free(prtd->lsm_client); + q6lsm_snd_model_buf_free(prtd->lsm_client, &p_info); rc = -EFAULT; break; } @@ -1004,13 +1152,13 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, "%s: Register snd Model v2 failed =%d\n", __func__, rc); kfree(confidence_level); - q6lsm_snd_model_buf_free(prtd->lsm_client); + q6lsm_snd_model_buf_free(prtd->lsm_client, &p_info); } kfree(prtd->lsm_client->confidence_levels); prtd->lsm_client->confidence_levels = NULL; break; - + } case SNDRV_LSM_SET_PARAMS: dev_dbg(rtd->dev, "%s: set_params\n", __func__); memcpy(&det_params, arg, @@ -1260,10 +1408,14 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, break; } case SNDRV_LSM_LAB_CONTROL: { - struct lsm_hw_params *out_hw_params = - &prtd->lsm_client->out_hw_params; - u8 chmap[out_hw_params->num_chs]; - u32 enable, ch_idx; + u32 enable = 0; + struct lsm_params_info_v2 p_info = {0}; + + if (prtd->lsm_client->num_stages > 1) { + dev_err(rtd->dev, "%s: %s: not supported for multi stage session\n", + __func__, "LSM_LAB_CONTROL"); + return -EINVAL; + } if (copy_from_user(&enable, arg, sizeof(enable))) { dev_err(rtd->dev, "%s: %s: copy_frm_user failed\n", @@ -1281,53 +1433,19 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, break; } - if (prtd->lsm_client->lab_enable == enable) { - dev_dbg(rtd->dev, - "%s: Lab for session %d already %s\n", - __func__, prtd->lsm_client->session, - enable ? "enabled" : "disabled"); - rc = 0; - break; - } - - rc = q6lsm_lab_control(prtd->lsm_client, enable); - if (rc) { - dev_err(rtd->dev, - "%s: ioctl %s failed rc %d to %s lab for session %d\n", - __func__, "SNDRV_LAB_CONTROL", rc, - enable ? "enable" : "disable", - prtd->lsm_client->session); - break; - } - - rc = msm_lsm_lab_buffer_alloc(prtd, - enable ? LAB_BUFFER_ALLOC - : LAB_BUFFER_DEALLOC); - if (rc) { - dev_err(rtd->dev, - "%s: msm_lsm_lab_buffer_alloc failed rc %d for %s", - __func__, rc, - enable ? "ALLOC" : "DEALLOC"); - break; - } - - prtd->lsm_client->lab_enable = enable; - memset(chmap, 0, out_hw_params->num_chs); /* - * First channel to be read from lab is always the - * best channel (0xff). For second channel onwards, - * the channel indices are 0, 1, .. etc + * With multi-stage support lab control needs to set param info + * specifying stage index for which this lab control is issued, + * along with values of module/instance ids applicable for the stage. + * Hence, set param info with default lab module/instance ids, and + * set stage index to LSM_STAGE_INDEX_FIRST. */ - chmap[0] = 0xFF; - for (ch_idx = 1; ch_idx < out_hw_params->num_chs; ch_idx++) - chmap[ch_idx] = ch_idx - 1; - - rc = q6lsm_lab_out_ch_cfg(prtd->lsm_client, chmap); - if (rc) - dev_err(rtd->dev, - "%s: Failed to set lab out ch cfg %d\n", - __func__, rc); - + p_info.param_type = LSM_LAB_CONTROL; + p_info.module_id = LSM_MODULE_ID_LAB; + p_info.instance_id = INSTANCE_ID_0; + p_info.stage_idx = LSM_STAGE_INDEX_FIRST; + p_info.param_size = 0; + rc = msm_lsm_check_and_set_lab_controls(substream, enable, &p_info); break; } case SNDRV_LSM_STOP_LAB: @@ -1476,6 +1594,16 @@ struct lsm_params_info_32 { uint32_t param_type; }; +struct lsm_params_info_v2_32 { + u32 module_id; + u32 param_id; + u32 param_size; + compat_uptr_t param_data; + uint32_t param_type; + u16 instance_id; + u16 stage_idx; +}; + struct snd_lsm_module_params_32 { compat_uptr_t params; u32 num_params; @@ -1491,6 +1619,8 @@ enum { _IOW('U', 0x0B, struct snd_lsm_module_params_32), SNDRV_LSM_EVENT_STATUS_V3_32 = _IOW('U', 0x0F, struct snd_lsm_event_status_v3_32), + SNDRV_LSM_SET_MODULE_PARAMS_V2_32 = + _IOW('U', 0x13, struct snd_lsm_module_params_32), }; static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, @@ -1760,19 +1890,20 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, break; } - case SNDRV_LSM_SET_MODULE_PARAMS_32: { + case SNDRV_LSM_SET_MODULE_PARAMS_32: + case SNDRV_LSM_SET_MODULE_PARAMS_V2_32: { struct snd_lsm_module_params_32 p_data_32; struct snd_lsm_module_params p_data; - u8 *params, *params32; - size_t p_size; - struct lsm_params_info_32 *p_info_32; - struct lsm_params_info *p_info; - int i; + u8 *params32; + size_t expected_size = 0, count; + struct lsm_params_info_32 *p_info_32 = NULL; + struct lsm_params_info_v2_32 *p_info_v2_32 = NULL; + struct lsm_params_info_v2 p_info; if (!prtd->lsm_client->use_topology) { dev_err(rtd->dev, "%s: %s: not supported if not using topology\n", - __func__, "SET_MODULE_PARAMS_32"); + __func__, "SET_MODULE_PARAMS(_V2)_32"); err = -EINVAL; goto done; } @@ -1781,7 +1912,7 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, sizeof(p_data_32))) { dev_err(rtd->dev, "%s: %s: copy_from_user failed, size = %zd\n", - __func__, "SET_MODULE_PARAMS_32", + __func__, "SET_MODULE_PARAMS(_V2)_32", sizeof(p_data_32)); err = -EFAULT; goto done; @@ -1794,79 +1925,85 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, if (p_data.num_params > LSM_PARAMS_MAX) { dev_err(rtd->dev, "%s: %s: Invalid num_params %d\n", - __func__, "SET_MODULE_PARAMS_32", + __func__, "SET_MODULE_PARAMS(_V2)_32", p_data.num_params); err = -EINVAL; goto done; } - if (p_data.data_size != - (p_data.num_params * sizeof(struct lsm_params_info_32))) { + expected_size = (cmd == SNDRV_LSM_SET_MODULE_PARAMS_32) ? + p_data.num_params * sizeof(struct lsm_params_info_32) : + p_data.num_params * sizeof(struct lsm_params_info_v2_32); + + if (p_data.data_size != expected_size) { dev_err(rtd->dev, "%s: %s: Invalid size %d\n", - __func__, "SET_MODULE_PARAMS_32", + __func__, "SET_MODULE_PARAMS(_V2)_32", p_data.data_size); err = -EINVAL; goto done; } - p_size = sizeof(struct lsm_params_info_32) * - p_data.num_params; - - params32 = kzalloc(p_size, GFP_KERNEL); + params32 = kzalloc(p_data.data_size, GFP_KERNEL); if (!params32) { err = -ENOMEM; goto done; } - p_size = sizeof(struct lsm_params_info) * p_data.num_params; - params = kzalloc(p_size, GFP_KERNEL); - if (!params) { - dev_err(rtd->dev, - "%s: no memory for params, size = %zd\n", - __func__, p_size); - kfree(params32); - err = -ENOMEM; - goto done; - } - if (copy_from_user(params32, p_data.params, p_data.data_size)) { dev_err(rtd->dev, "%s: %s: copy_from_user failed, size = %d\n", __func__, "params32", p_data.data_size); kfree(params32); - kfree(params); err = -EFAULT; goto done; } - p_info_32 = (struct lsm_params_info_32 *) params32; - p_info = (struct lsm_params_info *) params; - for (i = 0; i < p_data.num_params; i++) { - p_info->module_id = p_info_32->module_id; - p_info->param_id = p_info_32->param_id; - p_info->param_size = p_info_32->param_size; - p_info->param_data = compat_ptr(p_info_32->param_data); - p_info->param_type = p_info_32->param_type; + if (cmd == SNDRV_LSM_SET_MODULE_PARAMS_32) + p_info_32 = (struct lsm_params_info_32 *) params32; + else + p_info_v2_32 = (struct lsm_params_info_v2_32 *) params32; + + for (count = 0; count < p_data.num_params; count++) { + if (cmd == SNDRV_LSM_SET_MODULE_PARAMS_32) { + p_info.module_id = p_info_32->module_id; + p_info.param_id = p_info_32->param_id; + p_info.param_size = p_info_32->param_size; + p_info.param_data = compat_ptr(p_info_32->param_data); + p_info.param_type = p_info_32->param_type; - p_info_32++; - p_info++; + p_info.instance_id = INSTANCE_ID_0; + p_info.stage_idx = LSM_STAGE_INDEX_FIRST; + + p_info_32++; + } else { + p_info.module_id = p_info_v2_32->module_id; + p_info.param_id = p_info_v2_32->param_id; + p_info.param_size = p_info_v2_32->param_size; + p_info.param_data = compat_ptr(p_info_v2_32->param_data); + p_info.param_type = p_info_v2_32->param_type; + + p_info.instance_id = p_info_v2_32->instance_id; + p_info.stage_idx = p_info_v2_32->stage_idx; + + p_info_v2_32++; + } + + err = msm_lsm_process_params(substream, &p_info); + if (err) + dev_err(rtd->dev, + "%s: Failed to process param, type%d stage=%d err=%d\n", + __func__, p_info.param_type, p_info.stage_idx, err); } - err = msm_lsm_process_params(substream, - &p_data, params); - if (err) - dev_err(rtd->dev, - "%s: Failed to process params, err = %d\n", - __func__, err); - kfree(params); kfree(params32); break; } case SNDRV_LSM_REG_SND_MODEL_V2: case SNDRV_LSM_SET_PARAMS: case SNDRV_LSM_SET_MODULE_PARAMS: + case SNDRV_LSM_SET_MODULE_PARAMS_V2: /* * In ideal cases, the compat_ioctl should never be called * with the above unlocked ioctl commands. Print error @@ -1970,15 +2107,19 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, goto done; } - case SNDRV_LSM_SET_MODULE_PARAMS: { + case SNDRV_LSM_SET_MODULE_PARAMS: + case SNDRV_LSM_SET_MODULE_PARAMS_V2: { struct snd_lsm_module_params p_data; - size_t p_size; + struct lsm_params_info *temp_ptr_info = NULL; + struct lsm_params_info_v2 info_v2; + struct lsm_params_info_v2 *ptr_info_v2 = NULL, *temp_ptr_info_v2 = NULL; + size_t p_size = 0, count; u8 *params; if (!prtd->lsm_client->use_topology) { dev_err(rtd->dev, "%s: %s: not supported if not using topology\n", - __func__, "SET_MODULE_PARAMS"); + __func__, "SET_MODULE_PARAMS(_V2)"); err = -EINVAL; goto done; } @@ -1995,20 +2136,22 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, if (p_data.num_params > LSM_PARAMS_MAX) { dev_err(rtd->dev, "%s: %s: Invalid num_params %d\n", - __func__, "SET_MODULE_PARAMS", + __func__, "SET_MODULE_PARAMS(_V2)", p_data.num_params); err = -EINVAL; goto done; } - p_size = p_data.num_params * - sizeof(struct lsm_params_info); + if (cmd == SNDRV_LSM_SET_MODULE_PARAMS) + p_size = p_data.num_params * sizeof(struct lsm_params_info); + else + p_size = p_data.num_params * sizeof(struct lsm_params_info_v2); if (p_data.data_size != p_size) { dev_err(rtd->dev, - "%s: %s: Invalid size %zd\n", - __func__, "SET_MODULE_PARAMS", p_size); - + "%s: %s: Invalid data_size(%zd) against expected(%zd)\n", + __func__, "SET_MODULE_PARAMS(_V2)", + p_data.data_size, p_size); err = -EFAULT; goto done; } @@ -2020,20 +2163,46 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, } if (copy_from_user(params, p_data.params, - p_data.data_size)) { + p_data.data_size)) { dev_err(rtd->dev, "%s: %s: copy_from_user failed, size = %d\n", - __func__, "params", p_data.data_size); + __func__, "set module params", p_data.data_size); kfree(params); err = -EFAULT; goto done; } - err = msm_lsm_process_params(substream, &p_data, params); - if (err) - dev_err(rtd->dev, - "%s: %s: Failed to set params, err = %d\n", - __func__, "SET_MODULE_PARAMS", err); + if (cmd == SNDRV_LSM_SET_MODULE_PARAMS) + temp_ptr_info = (struct lsm_params_info *)params; + else + temp_ptr_info_v2 = (struct lsm_params_info_v2 *)params; + + for (count = 0; count < p_data.num_params; count++) { + if (cmd == SNDRV_LSM_SET_MODULE_PARAMS) { + /* convert to V2 param info struct from legacy param info */ + info_v2.module_id = temp_ptr_info->module_id; + info_v2.param_id = temp_ptr_info->param_id; + info_v2.param_size = temp_ptr_info->param_size; + info_v2.param_data = temp_ptr_info->param_data; + info_v2.param_type = temp_ptr_info->param_type; + + info_v2.instance_id = INSTANCE_ID_0; + info_v2.stage_idx = LSM_STAGE_INDEX_FIRST; + + ptr_info_v2 = &info_v2; + temp_ptr_info++; + } else { + /* Just copy the pointer as user already provided v2 params */ + ptr_info_v2 = temp_ptr_info_v2; + temp_ptr_info_v2++; + } + err = msm_lsm_process_params(substream, ptr_info_v2); + if (err) + dev_err(rtd->dev, + "%s: Failed to process param, type%d stage=%d err=%d\n", + __func__, ptr_info_v2->param_type, + ptr_info_v2->stage_idx, err); + } kfree(params); break; } diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 4e0f7247f5fc..8146b65d95a6 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -87,7 +87,8 @@ static spinlock_t lsm_session_lock; static struct lsm_client *lsm_session[LSM_MAX_SESSION_ID + 1]; static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv); -static int q6lsm_send_cal(struct lsm_client *client, u32 set_params_opcode); +static int q6lsm_send_cal(struct lsm_client *client, + u32 set_params_opcode, struct lsm_params_info_v2 *p_info); static int q6lsm_memory_map_regions(struct lsm_client *client, dma_addr_t dma_addr_p, uint32_t dma_buf_sz, uint32_t *mmap_p); @@ -166,6 +167,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) case LSM_SESSION_CMD_EOB: case LSM_SESSION_CMD_READ: case LSM_SESSION_CMD_OPEN_TX_V2: + case LSM_SESSION_CMD_OPEN_TX_V3: case LSM_CMD_ADD_TOPOLOGIES: case LSM_SESSION_CMD_SET_PARAMS_V2: case LSM_SESSION_CMD_SET_PARAMS_V3: @@ -689,6 +691,94 @@ static int q6lsm_send_custom_topologies(struct lsm_client *client) return rc; } +static int q6lsm_get_topology_for_app_type(struct lsm_client *client, + int app_type, uint32_t *topology) +{ + int rc = -EINVAL; + struct cal_block_data *cal_block = NULL; + struct audio_cal_info_lsm_top *lsm_top; + struct list_head *ptr; + + if (lsm_common.cal_data[LSM_TOP_IDX] == NULL) { + pr_err("%s: LSM_TOP_IDX invalid\n", __func__); + return rc; + } + + mutex_lock(&lsm_common.cal_data[LSM_TOP_IDX]->lock); + list_for_each(ptr, &lsm_common.cal_data[LSM_TOP_IDX]->cal_blocks) { + cal_block = list_entry(ptr, struct cal_block_data, list); + if (!cal_block) { + pr_err("%s: Cal block for LSM_TOP_IDX not found\n", + __func__); + break; + } + + lsm_top = (struct audio_cal_info_lsm_top *) cal_block->cal_info; + if (!lsm_top) { + pr_err("%s: cal_info for LSM_TOP_IDX not found\n", + __func__); + break; + } + + pr_debug("%s: checking topology 0x%x, app_type 0x%x\n", + __func__, lsm_top->topology, lsm_top->app_type); + + if (app_type == 0 || lsm_top->app_type == app_type) { + *topology = lsm_top->topology; + rc = 0; + break; + } + } + mutex_unlock(&lsm_common.cal_data[LSM_TOP_IDX]->lock); + + pr_debug("%s: found topology_id = 0x%x, app_type = 0x%x\n", + __func__, *topology, app_type); + + return rc; +} + +static int q6lsm_do_open_v3(struct lsm_client *client) +{ + int rc, app_type; + struct lsm_stream_cmd_open_tx_v3 *open_v3; + size_t cmd_size = 0, stage_idx = LSM_STAGE_INDEX_FIRST; + uint32_t topology_id = 0, *uint32_ptr = NULL; + + cmd_size = sizeof(struct lsm_stream_cmd_open_tx_v3); + cmd_size += client->num_stages * sizeof(struct lsm_stream_stage_info); + open_v3 = kzalloc(cmd_size, GFP_KERNEL); + if (!open_v3) + return -ENOMEM; + + q6lsm_add_hdr(client, &open_v3->hdr, cmd_size, true); + open_v3->hdr.opcode = LSM_SESSION_CMD_OPEN_TX_V3; + open_v3->num_stages = client->num_stages; + uint32_ptr = &open_v3->num_stages; + uint32_ptr++; + + for (; stage_idx < client->num_stages; stage_idx++) { + app_type = client->stage_cfg[stage_idx].app_type; + rc = q6lsm_get_topology_for_app_type(client, app_type, &topology_id); + if (rc) { + pr_err("%s: failed to get topology for stage %d\n", + __func__, stage_idx); + return -EINVAL; + } + *uint32_ptr++ = topology_id; + *uint32_ptr++ = client->stage_cfg[stage_idx].lpi_enable; + } + + rc = q6lsm_apr_send_pkt(client, client->apr, open_v3, true, NULL); + if (rc) + pr_err("%s: open_v3 failed, err = %d\n", __func__, rc); + else + client->use_topology = true; + + kfree(open_v3); + return rc; + +} + static int q6lsm_do_open_v2(struct lsm_client *client, uint16_t app_id) { @@ -722,9 +812,8 @@ static int q6lsm_do_open_v2(struct lsm_client *client, goto unlock; } - pr_debug("%s: topology_id = 0x%x, acdb_id = 0x%x, app_type = 0x%x\n", - __func__, lsm_top->topology, lsm_top->acdb_id, - lsm_top->app_type); + pr_debug("%s: topology_id = 0x%x, app_type = 0x%x\n", + __func__, lsm_top->topology, lsm_top->app_type); if (lsm_top->topology == 0) { pr_err("%s: toplogy id not sent for app_type 0x%x\n", @@ -764,26 +853,41 @@ static int q6lsm_do_open_v2(struct lsm_client *client, * */ void q6lsm_sm_set_param_data(struct lsm_client *client, - struct lsm_params_info *p_info, + struct lsm_params_info_v2 *p_info, size_t *offset) { struct param_hdr_v3 param_hdr; - int ret = 0; + int ret; + struct lsm_sound_model *sm; + sm = &client->stage_cfg[p_info->stage_idx].sound_model; memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = p_info->module_id; - param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.instance_id = p_info->instance_id; param_hdr.param_id = p_info->param_id; - param_hdr.param_size = client->sound_model.size; + param_hdr.param_size = sm->size; - ret = q6lsm_pack_params(client->sound_model.data, ¶m_hdr, + ret = q6lsm_pack_params(sm->data, ¶m_hdr, NULL, offset, LSM_SESSION_CMD_SET_PARAMS_V2); if (ret) pr_err("%s: Failed to pack params, error %d\n", __func__, ret); } EXPORT_SYMBOL(q6lsm_sm_set_param_data); +/** + * q6lsm_support_multi_stage_detection - + * check for multi-stage support in adsp lsm framework service + * + * Returns true if multi-stage support available, else false + */ +bool q6lsm_adsp_supports_multi_stage_detection(void) +{ + return q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_LSM_V) >= LSM_API_VERSION_V3; +} +EXPORT_SYMBOL(q6lsm_adsp_supports_multi_stage_detection); + /** * q6lsm_open - * command to open LSM session @@ -807,9 +911,13 @@ int q6lsm_open(struct lsm_client *client, uint16_t app_id) } /* Try to open with topology first */ - rc = q6lsm_do_open_v2(client, app_id); + if ((client->stage_cfg[LSM_STAGE_INDEX_FIRST].app_type != 0) && + q6lsm_adsp_supports_multi_stage_detection()) + rc = q6lsm_do_open_v3(client); + else + rc = q6lsm_do_open_v2(client, app_id); if (!rc) - /* open_v2 was successful */ + /* open_v2/v3 was successful */ goto done; pr_debug("%s: try without topology\n", @@ -1183,6 +1291,7 @@ int q6lsm_set_data(struct lsm_client *client, { struct param_hdr_v3 param_hdr; int rc = 0; + struct lsm_params_info_v2 p_info = {0}; memset(¶m_hdr, 0, sizeof(param_hdr)); @@ -1228,7 +1337,8 @@ int q6lsm_set_data(struct lsm_client *client, goto err_ret; } - rc = q6lsm_send_cal(client, LSM_SESSION_CMD_SET_PARAMS); + p_info.stage_idx = LSM_STAGE_INDEX_FIRST; + rc = q6lsm_send_cal(client, LSM_SESSION_CMD_SET_PARAMS, &p_info); if (rc) { pr_err("%s: Failed to send calibration data %d\n", __func__, rc); @@ -1254,6 +1364,7 @@ int q6lsm_register_sound_model(struct lsm_client *client, { int rc; struct lsm_cmd_reg_snd_model cmd; + struct lsm_sound_model *sm; memset(&cmd, 0, sizeof(cmd)); rc = q6lsm_set_data(client, mode, detectfailure); @@ -1263,18 +1374,19 @@ int q6lsm_register_sound_model(struct lsm_client *client, return rc; } + sm = &client->stage_cfg[LSM_STAGE_INDEX_FIRST].sound_model; + q6lsm_add_hdr(client, &cmd.hdr, sizeof(cmd), true); cmd.hdr.opcode = LSM_SESSION_CMD_REGISTER_SOUND_MODEL; - cmd.model_addr_lsw = lower_32_bits(client->sound_model.phys); - cmd.model_addr_msw = msm_audio_populate_upper_32_bits( - client->sound_model.phys); - cmd.model_size = client->sound_model.size; + cmd.model_addr_lsw = lower_32_bits(sm->phys); + cmd.model_addr_msw = msm_audio_populate_upper_32_bits(sm->phys); + cmd.model_size = sm->size; /* read updated mem_map_handle by q6lsm_mmapcallback */ rmb(); - cmd.mem_map_handle = client->sound_model.mem_map_handle; + cmd.mem_map_handle = sm->mem_map_handle; pr_debug("%s: addr %pK, size %d, handle 0x%x\n", __func__, - &client->sound_model.phys, cmd.model_size, cmd.mem_map_handle); + &sm->phys, cmd.model_size, cmd.mem_map_handle); rc = q6lsm_apr_send_pkt(client, client->apr, &cmd, true, NULL); if (rc) pr_err("%s: Failed cmd op[0x%x]rc[%d]\n", __func__, @@ -1298,6 +1410,16 @@ int q6lsm_deregister_sound_model(struct lsm_client *client) { int rc; struct lsm_cmd_reg_snd_model cmd; + /* + * With multi-stage support sm buff allocation/free usage param info + * to check stage index for which this sound model is being set, and + * to check whether sm data is sent using set param command or not. + * Hence, set param ids to '0' to indicate allocation is for legacy + * reg_sm cmd, where buffer for param header need not be allocated, + * also set stage index to LSM_STAGE_INDEX_FIRST. + */ + struct lsm_params_info_v2 p_info = {0}; + p_info.stage_idx = LSM_STAGE_INDEX_FIRST; if (!client) { pr_err("APR handle NULL\n"); @@ -1325,7 +1447,7 @@ int q6lsm_deregister_sound_model(struct lsm_client *client) pr_debug("%s: Deregister sound model succeeded\n", __func__); } - q6lsm_snd_model_buf_free(client); + q6lsm_snd_model_buf_free(client, &p_info); return rc; } @@ -1425,11 +1547,11 @@ static int q6lsm_memory_unmap_regions(struct lsm_client *client, } static int q6lsm_send_cal(struct lsm_client *client, - u32 set_params_opcode) + u32 set_params_opcode, struct lsm_params_info_v2 *p_info) { - int rc = 0; + int rc = 0, stage_idx = p_info->stage_idx; struct mem_mapping_hdr mem_hdr; - struct cal_block_data *cal_block = NULL; + dma_addr_t lsm_cal_phy_addr; memset(&mem_hdr, 0, sizeof(mem_hdr)); @@ -1439,40 +1561,132 @@ static int q6lsm_send_cal(struct lsm_client *client, return -EINVAL; } - if (lsm_common.cal_data[LSM_CAL_IDX] == NULL) - goto done; + lsm_cal_phy_addr = client->stage_cfg[stage_idx].cal_info.phys; + if (lsm_cal_phy_addr != 0) { + lsm_common.common_client[client->session].session = client->session; + mem_hdr.data_payload_addr_lsw = lower_32_bits(lsm_cal_phy_addr); + mem_hdr.data_payload_addr_msw = + msm_audio_populate_upper_32_bits(lsm_cal_phy_addr); + mem_hdr.mem_map_handle = + client->stage_cfg[stage_idx].cal_info.mem_map_handle; + + rc = q6lsm_set_params(client, &mem_hdr, NULL, + client->stage_cfg[stage_idx].cal_info.size, set_params_opcode); + if (rc) + pr_err("%s: Failed set_params, rc %d\n", __func__, rc); + } + + return rc; +} + +static int q6lsm_snd_cal_free(struct lsm_client *client, + struct lsm_params_info_v2 *p_info) +{ + int rc = 0, stage_idx = p_info->stage_idx; + struct lsm_cal_data_info *cal = NULL; + + if (!client->stage_cfg[stage_idx].cal_info.data) + return 0; + + mutex_lock(&client->cmd_lock); + cal = &client->stage_cfg[stage_idx].cal_info; + if (cal->mem_map_handle != 0) { + rc = q6lsm_memory_unmap_regions(client, cal->mem_map_handle); + if (rc) + pr_err("%s: CMD Memory_unmap_regions failed %d\n", + __func__, rc); + cal->mem_map_handle = 0; + } + msm_audio_ion_free(cal->dma_buf); + cal->dma_buf = NULL; + cal->data = NULL; + cal->phys = 0; + mutex_unlock(&client->cmd_lock); + + return rc; +} + +static int q6lsm_snd_cal_alloc(struct lsm_client *client, + struct lsm_params_info_v2 *p_info) +{ + int rc = 0; + size_t len = 0, total_mem = 0; + struct lsm_cal_data_info *cal = NULL; + struct cal_block_data *cal_block = NULL; + struct audio_cal_info_lsm *lsm_cal_info = NULL; + struct list_head *ptr = NULL; + int app_type, stage_idx = p_info->stage_idx; + bool cal_block_found = false; + + app_type = client->stage_cfg[stage_idx].app_type; + pr_debug("%s: app_type %d, stage_idx %d\n", + __func__, app_type, stage_idx); + mutex_lock(&client->cmd_lock); mutex_lock(&lsm_common.cal_data[LSM_CAL_IDX]->lock); - cal_block = cal_utils_get_only_cal_block( - lsm_common.cal_data[LSM_CAL_IDX]); + list_for_each(ptr, &lsm_common.cal_data[LSM_CAL_IDX]->cal_blocks) { + cal_block = list_entry(ptr, struct cal_block_data, list); + lsm_cal_info = (struct audio_cal_info_lsm *) + (cal_block) ? cal_block->cal_info : NULL; + if ((cal_block && cal_block->cal_data.paddr) && + (lsm_cal_info != NULL) && + (app_type == 0 || app_type == lsm_cal_info->app_type)) { + cal_block_found = true; + len = cal_block->cal_data.size; + break; + } + } - if (!cal_block || cal_block->cal_data.size <= 0) { - pr_debug("%s: No cal to send!\n", __func__); - goto unlock; + if (!cal_block_found) { + pr_info("%s: cal not found for stage_idx %d\n", __func__, stage_idx); + goto exit; } - if (cal_block->cal_data.size != client->lsm_cal_size) { - pr_err("%s: Cal size %zd doesn't match lsm cal size %d\n", - __func__, cal_block->cal_data.size, - client->lsm_cal_size); - rc = -EINVAL; - goto unlock; + if (!len) { + pr_debug("%s: cal size is 0, for stage_idx %d\n", __func__, stage_idx); + goto exit; } - /* Cache mmap address, only map once or if new addr */ - lsm_common.common_client[client->session].session = client->session; - mem_hdr.data_payload_addr_lsw = lower_32_bits(client->lsm_cal_phy_addr); - mem_hdr.data_payload_addr_msw = - msm_audio_populate_upper_32_bits(client->lsm_cal_phy_addr); - mem_hdr.mem_map_handle = client->sound_model.mem_map_handle; - pr_debug("%s: Cal Size = %zd", __func__, cal_block->cal_data.size); - rc = q6lsm_set_params(client, &mem_hdr, NULL, cal_block->cal_data.size, - set_params_opcode); - if (rc) - pr_err("%s: Failed set_params, rc %d\n", __func__, rc); -unlock: + cal = &client->stage_cfg[stage_idx].cal_info; + if (cal->data) { + pr_debug("%s: cal data for stage_idx(%d) is already set \n", + __func__, stage_idx); + goto exit; + } + + cal->size = len; + total_mem = PAGE_ALIGN(len); + pr_debug("%s: cal info data size %zd Total mem %zd, stage_idx %d\n", + __func__, len, total_mem, stage_idx); + + rc = msm_audio_ion_alloc(&cal->dma_buf, total_mem, + &cal->phys, &len, &cal->data); + if (rc) { + pr_err("%s: Audio ION alloc is failed for stage_idx %d, rc = %d\n", + __func__, stage_idx, rc); + cal->dma_buf = NULL; + cal->data = NULL; + goto exit; + } + + memcpy(cal->data, (uint32_t *)cal_block->cal_data.kvaddr, cal->size); mutex_unlock(&lsm_common.cal_data[LSM_CAL_IDX]->lock); -done: + mutex_unlock(&client->cmd_lock); + rc = q6lsm_memory_map_regions(client, cal->phys, len, &cal->mem_map_handle); + if (rc) { + pr_err("%s: CMD Memory_map_regions failed for stage_idx %d, rc = %d\n", + __func__, stage_idx, rc); + cal->mem_map_handle = 0; + goto fail; + } + + return 0; + +exit: + mutex_unlock(&client->cmd_lock); + mutex_unlock(&lsm_common.cal_data[LSM_CAL_IDX]->lock); +fail: + q6lsm_snd_cal_free(client, p_info); return rc; } @@ -1481,12 +1695,15 @@ static int q6lsm_send_cal(struct lsm_client *client, * Free memory for LSM snd model * * @client: LSM client handle + * @p_info: sound model param info * * Returns 0 on success or error on failure */ -int q6lsm_snd_model_buf_free(struct lsm_client *client) +int q6lsm_snd_model_buf_free(struct lsm_client *client, + struct lsm_params_info_v2 *p_info) { - int rc; + int rc = 0, stage_idx = p_info->stage_idx; + struct lsm_sound_model *sm = NULL; pr_debug("%s: Session id %d\n", __func__, client->session); if (CHECK_SESSION(client->session)) { @@ -1494,22 +1711,25 @@ int q6lsm_snd_model_buf_free(struct lsm_client *client) return -EINVAL; } - mutex_lock(&client->cmd_lock); - rc = q6lsm_memory_unmap_regions(client, - client->sound_model.mem_map_handle); - if (rc) - pr_err("%s: CMD Memory_unmap_regions failed %d\n", - __func__, rc); + if (!client->stage_cfg[stage_idx].sound_model.data) + return 0; - if (client->sound_model.data) { - msm_audio_ion_free(client->sound_model.dma_buf); - client->sound_model.dma_buf = NULL; - client->sound_model.data = NULL; - client->sound_model.phys = 0; - client->lsm_cal_phy_addr = 0; - client->lsm_cal_size = 0; + mutex_lock(&client->cmd_lock); + sm = &client->stage_cfg[stage_idx].sound_model; + if (sm->mem_map_handle != 0) { + rc = q6lsm_memory_unmap_regions(client, sm->mem_map_handle); + if (rc) + pr_err("%s: CMD Memory_unmap_regions failed %d\n", + __func__, rc); + sm->mem_map_handle = 0; } + msm_audio_ion_free(sm->dma_buf); + sm->dma_buf = NULL; + sm->data = NULL; + sm->phys = 0; mutex_unlock(&client->cmd_lock); + + rc = q6lsm_snd_cal_free(client, p_info); return rc; } EXPORT_SYMBOL(q6lsm_snd_model_buf_free); @@ -1551,7 +1771,6 @@ static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv) apr_reset(lsm_common.apr); lsm_common.apr = NULL; atomic_set(&lsm_common.apr_users, 0); - lsm_common.common_client[sid].lsm_cal_phy_addr = 0; cal_utils_clear_cal_block_q6maps(LSM_MAX_CAL_IDX, lsm_common.cal_data); lsm_common.set_custom_topology = 1; @@ -1623,109 +1842,73 @@ static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv) * * @client: LSM client handle * @len: size of sound model - * @allocate_module_data: flag to allocate for set_param payload + * @p_info: sound model param info + * p_info->param_id != 0 when using set param to register sound model * * Returns 0 on success or error on failure */ int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len, - bool allocate_module_data) + struct lsm_params_info_v2 *p_info) { - int rc = -EINVAL; - struct cal_block_data *cal_block = NULL; - - size_t pad_zero = 0, total_mem = 0; + int rc = -EINVAL, stage_idx = p_info->stage_idx; + size_t total_mem = 0; + struct lsm_sound_model *sm = NULL; if (!client || len <= LSM_ALIGN_BOUNDARY) return rc; - mutex_lock(&client->cmd_lock); - - mutex_lock(&lsm_common.cal_data[LSM_CAL_IDX]->lock); - cal_block = cal_utils_get_only_cal_block( - lsm_common.cal_data[LSM_CAL_IDX]); - if (cal_block == NULL) - goto fail; - - pr_debug("%s:Snd Model len = %zd cal size %zd phys addr %pK", __func__, - len, cal_block->cal_data.size, - &cal_block->cal_data.paddr); - if (!cal_block->cal_data.paddr) { - pr_err("%s: No LSM calibration set for session", __func__); - rc = -EINVAL; - goto fail; - } - if (!client->sound_model.data) { + pr_debug("%s:Snd Model len = %zd, stage idx %d\n", + __func__, len, stage_idx); + mutex_lock(&client->cmd_lock); + sm = &client->stage_cfg[stage_idx].sound_model; + if (!sm->data) { /* - * if sound module is sent as set_param + * If sound model is sent as set_param, i.e. param_id != 0, * Then memory needs to be allocated for * set_param payload as well. */ - if (allocate_module_data) + if (p_info->param_id != 0) len += sizeof(union param_hdrs); - client->sound_model.size = len; - pad_zero = (LSM_ALIGN_BOUNDARY - - (len % LSM_ALIGN_BOUNDARY)); - if ((len > SIZE_MAX - pad_zero) || - (len + pad_zero > - SIZE_MAX - cal_block->cal_data.size)) { - pr_err("%s: invalid allocation size, len = %zd, pad_zero =%zd, cal_size = %zd\n", - __func__, len, pad_zero, - cal_block->cal_data.size); - rc = -EINVAL; - goto fail; - } - - total_mem = PAGE_ALIGN(pad_zero + len + - cal_block->cal_data.size); - pr_debug("%s: Pad zeros sound model %zd Total mem %zd\n", - __func__, pad_zero, total_mem); - rc = msm_audio_ion_alloc(&client->sound_model.dma_buf, - total_mem, - &client->sound_model.phys, - &len, - &client->sound_model.data); + sm->size = len; + total_mem = PAGE_ALIGN(len); + pr_debug("%s: sm param size %zd Total mem %zd, stage_idx %d\n", + __func__, len, total_mem, stage_idx); + rc = msm_audio_ion_alloc(&sm->dma_buf, total_mem, + &sm->phys, &len, &sm->data); if (rc) { - pr_err("%s: Audio ION alloc is failed, rc = %d\n", - __func__, rc); + pr_err("%s: Audio ION alloc is failed, rc = %d, stage_idx = %d\n", + __func__, rc, stage_idx); goto fail; } - pr_debug("%s: Length = %zd\n", __func__, len); - client->lsm_cal_phy_addr = (pad_zero + - client->sound_model.phys + - client->sound_model.size); - client->lsm_cal_size = cal_block->cal_data.size; - memcpy((client->sound_model.data + pad_zero + - client->sound_model.size), - (uint32_t *)cal_block->cal_data.kvaddr, client->lsm_cal_size); - pr_debug("%s: Copy cal start virt_addr %pK phy_addr %pK\n" - "Offset cal virtual Addr %pK\n", __func__, - client->sound_model.data, &client->sound_model.phys, - (pad_zero + client->sound_model.data + - client->sound_model.size)); } else { - pr_err("%s: sound model busy\n", __func__); + pr_err("%s: sound model busy, stage_idx %d\n", __func__, stage_idx); rc = -EBUSY; goto fail; } - mutex_unlock(&lsm_common.cal_data[LSM_CAL_IDX]->lock); + + rc = q6lsm_memory_map_regions(client, sm->phys, len, &sm->mem_map_handle); + if (rc) { + pr_err("%s: CMD Memory_map_regions failed %d, stage_idx %d\n", + __func__, rc, stage_idx); + sm->mem_map_handle = 0; + goto fail; + } mutex_unlock(&client->cmd_lock); - rc = q6lsm_memory_map_regions(client, client->sound_model.phys, - len, - &client->sound_model.mem_map_handle); + rc = q6lsm_snd_cal_alloc(client, p_info); if (rc) { - pr_err("%s: CMD Memory_map_regions failed %d\n", __func__, rc); - goto exit; + pr_err("%s: cal alloc failed %d, stage_idx %d\n", + __func__, rc, stage_idx); + goto fail_1; } + return rc; - return 0; fail: - mutex_unlock(&lsm_common.cal_data[LSM_CAL_IDX]->lock); mutex_unlock(&client->cmd_lock); -exit: - q6lsm_snd_model_buf_free(client); +fail_1: + q6lsm_snd_model_buf_free(client, p_info); return rc; } EXPORT_SYMBOL(q6lsm_snd_model_buf_alloc); @@ -1811,7 +1994,7 @@ static int q6lsm_send_param_gain(struct lsm_client *client, u16 gain, * Returns 0 on success or error on failure */ int q6lsm_set_one_param(struct lsm_client *client, - struct lsm_params_info *p_info, void *data, + struct lsm_params_info_v2 *p_info, void *data, uint32_t param_type) { struct param_hdr_v3 param_info; @@ -1822,7 +2005,7 @@ int q6lsm_set_one_param(struct lsm_client *client, switch (param_type) { case LSM_ENDPOINT_DETECT_THRESHOLD: { param_info.module_id = p_info->module_id; - param_info.instance_id = INSTANCE_ID_0; + param_info.instance_id = p_info->instance_id; param_info.param_id = p_info->param_id; rc = q6lsm_send_param_epd_thres(client, data, ¶m_info); if (rc) @@ -1847,7 +2030,7 @@ int q6lsm_set_one_param(struct lsm_client *client, client->mode |= det_mode->detect_failure << 2; param_info.module_id = p_info->module_id; - param_info.instance_id = INSTANCE_ID_0; + param_info.instance_id = p_info->instance_id; param_info.param_id = p_info->param_id; rc = q6lsm_send_param_opmode(client, ¶m_info, @@ -1861,7 +2044,7 @@ int q6lsm_set_one_param(struct lsm_client *client, case LSM_GAIN: { struct snd_lsm_gain *lsm_gain = (struct snd_lsm_gain *) data; param_info.module_id = p_info->module_id; - param_info.instance_id = INSTANCE_ID_0; + param_info.instance_id = p_info->instance_id; param_info.param_id = p_info->param_id; rc = q6lsm_send_param_gain(client, lsm_gain->gain, ¶m_info); if (rc) @@ -1872,7 +2055,7 @@ int q6lsm_set_one_param(struct lsm_client *client, case LSM_MIN_CONFIDENCE_LEVELS: param_info.module_id = p_info->module_id; - param_info.instance_id = INSTANCE_ID_0; + param_info.instance_id = p_info->instance_id; param_info.param_id = p_info->param_id; rc = q6lsm_send_confidence_levels( client, ¶m_info, LSM_SESSION_CMD_SET_PARAMS_V2); @@ -1884,7 +2067,7 @@ int q6lsm_set_one_param(struct lsm_client *client, struct snd_lsm_poll_enable *lsm_poll_enable = (struct snd_lsm_poll_enable *) data; param_info.module_id = p_info->module_id; - param_info.instance_id = INSTANCE_ID_0; + param_info.instance_id = p_info->instance_id; param_info.param_id = p_info->param_id; rc = q6lsm_send_param_polling_enable( client, lsm_poll_enable->poll_en, ¶m_info, @@ -1898,6 +2081,7 @@ int q6lsm_set_one_param(struct lsm_client *client, case LSM_REG_SND_MODEL: { struct mem_mapping_hdr mem_hdr; u32 payload_size; + struct lsm_sound_model *sm = NULL; memset(&mem_hdr, 0, sizeof(mem_hdr)); @@ -1908,12 +2092,14 @@ int q6lsm_set_one_param(struct lsm_client *client, payload_size = p_info->param_size + sizeof(struct param_hdr_v2); + sm = &client->stage_cfg[p_info->stage_idx].sound_model; + mem_hdr.data_payload_addr_lsw = - lower_32_bits(client->sound_model.phys); + lower_32_bits(sm->phys); mem_hdr.data_payload_addr_msw = msm_audio_populate_upper_32_bits( - client->sound_model.phys), - mem_hdr.mem_map_handle = client->sound_model.mem_map_handle; + sm->phys), + mem_hdr.mem_map_handle = sm->mem_map_handle; rc = q6lsm_set_params(client, &mem_hdr, NULL, payload_size, LSM_SESSION_CMD_SET_PARAMS_V2); @@ -1923,7 +2109,7 @@ int q6lsm_set_one_param(struct lsm_client *client, return rc; } - rc = q6lsm_send_cal(client, LSM_SESSION_CMD_SET_PARAMS); + rc = q6lsm_send_cal(client, LSM_SESSION_CMD_SET_PARAMS, p_info); if (rc) pr_err("%s: Failed to send lsm cal, err = %d\n", __func__, rc); @@ -1932,7 +2118,7 @@ int q6lsm_set_one_param(struct lsm_client *client, case LSM_DEREG_SND_MODEL: { param_info.module_id = p_info->module_id; - param_info.instance_id = INSTANCE_ID_0; + param_info.instance_id = p_info->instance_id; param_info.param_id = p_info->param_id; param_info.param_size = 0; rc = q6lsm_pack_and_set_params(client, ¶m_info, NULL, @@ -1967,7 +2153,7 @@ int q6lsm_set_one_param(struct lsm_client *client, (struct snd_lsm_det_event_type *)data; param_info.module_id = p_info->module_id; - param_info.instance_id = INSTANCE_ID_0; + param_info.instance_id = p_info->instance_id; param_info.param_id = p_info->param_id; param_info.param_size = sizeof(det_event_type); @@ -2044,10 +2230,12 @@ EXPORT_SYMBOL(q6lsm_close); * * @client: LSM client handle * @enable: bool flag to enable or disable LAB on DSP + * @p_info: param info to be used for sending lab control param * * Returns 0 on success or error on failure */ -int q6lsm_lab_control(struct lsm_client *client, u32 enable) +int q6lsm_lab_control(struct lsm_client *client, u32 enable, + struct lsm_params_info_v2 *p_info) { struct lsm_param_lab_enable lab_enable; struct param_hdr_v3 lab_enable_hdr; @@ -2066,8 +2254,8 @@ int q6lsm_lab_control(struct lsm_client *client, u32 enable) } /* enable/disable lab on dsp */ - lab_enable_hdr.module_id = LSM_MODULE_ID_LAB; - lab_enable_hdr.instance_id = INSTANCE_ID_0; + lab_enable_hdr.module_id = p_info->module_id; + lab_enable_hdr.instance_id = p_info->instance_id; lab_enable_hdr.param_id = LSM_PARAM_ID_LAB_ENABLE; lab_enable_hdr.param_size = sizeof(lab_enable); lab_enable.enable = (enable) ? 1 : 0; @@ -2082,8 +2270,8 @@ int q6lsm_lab_control(struct lsm_client *client, u32 enable) goto exit; /* lab session is being enabled set the config values */ - lab_config_hdr.module_id = LSM_MODULE_ID_LAB; - lab_config_hdr.instance_id = INSTANCE_ID_0; + lab_config_hdr.module_id = p_info->module_id; + lab_config_hdr.instance_id = p_info->instance_id; lab_config_hdr.param_id = LSM_PARAM_ID_LAB_CONFIG; lab_config_hdr.param_size = sizeof(lab_config); lab_config.minor_version = 1; @@ -2114,11 +2302,12 @@ EXPORT_SYMBOL(q6lsm_lab_control); * @client: LSM client handle * @ch_map: Channel map indicating the order * of channels to be configured. + * @p_info: param info to be used for sending lab config param * * Returns 0 on success or error on failure */ int q6lsm_lab_out_ch_cfg(struct lsm_client *client, - u8 *ch_map) + u8 *ch_map, struct lsm_params_info_v2 *p_info) { u8 *param_buf; struct lsm_param_lab_out_ch_cfg *lab_out_cfg; @@ -2144,8 +2333,8 @@ int q6lsm_lab_out_ch_cfg(struct lsm_client *client, lab_out_cfg->channel_indices[i] = ch_map[i]; memset(&lab_out_cfg_hdr, 0, sizeof(lab_out_cfg_hdr)); - lab_out_cfg_hdr.module_id = LSM_MODULE_ID_LAB; - lab_out_cfg_hdr.instance_id = INSTANCE_ID_0; + lab_out_cfg_hdr.module_id = p_info->module_id; + lab_out_cfg_hdr.instance_id = p_info->instance_id; lab_out_cfg_hdr.param_id = LSM_PARAM_ID_LAB_OUTPUT_CHANNEL_CONFIG; lab_out_cfg_hdr.param_size = param_len; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 49ad902894d2..535f09f1d3a9 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -9949,6 +9949,7 @@ struct avcs_fwk_ver_info { #define LSM_SESSION_CMD_EOB (0x00012A89) #define LSM_SESSION_CMD_READ (0x00012A8A) #define LSM_SESSION_CMD_OPEN_TX_V2 (0x00012A8B) +#define LSM_SESSION_CMD_OPEN_TX_V3 (0x00012A95) #define LSM_CMD_ADD_TOPOLOGIES (0x00012A8C) #define LSM_SESSION_EVENT_DETECTION_STATUS (0x00012B00) diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h index 740fba4e89b7..5670d776c58d 100644 --- a/include/dsp/q6lsm.h +++ b/include/dsp/q6lsm.h @@ -26,6 +26,8 @@ #define LSM_MAX_NUM_CHANNELS 8 #define LSM_V3P0_MAX_NUM_CHANNELS 9 +#define LSM_API_VERSION_V3 3 + typedef void (*lsm_app_cb)(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv); @@ -60,6 +62,24 @@ struct lsm_hw_params { u16 num_chs; }; +struct lsm_cal_data_info { + dma_addr_t phys; + void *data; + size_t size; + struct dma_buf *dma_buf; + uint32_t mem_map_handle; +}; + +struct lsm_stage_config { + uint32_t app_type; + uint32_t topology_id; + bool lpi_enable; + bool lab_enable; + struct lsm_sound_model sound_model; + struct lsm_cal_data_info cal_info; +}; + + struct lsm_client { int session; lsm_app_cb cb; @@ -68,7 +88,6 @@ struct lsm_client { struct apr_svc *apr; struct apr_svc *mmap_apr; struct mutex cmd_lock; - struct lsm_sound_model sound_model; wait_queue_head_t cmd_wait; uint32_t cmd_err_code; uint16_t mode; @@ -77,8 +96,6 @@ struct lsm_client { uint8_t *confidence_levels; bool opened; bool started; - dma_addr_t lsm_cal_phy_addr; - uint32_t lsm_cal_size; uint32_t app_id; bool lab_enable; bool lab_started; @@ -91,6 +108,8 @@ struct lsm_client { int perf_mode; uint32_t event_mode; uint32_t event_type; + uint32_t num_stages; + struct lsm_stage_config stage_cfg[LSM_MAX_STAGES_PER_SESSION]; }; struct lsm_stream_cmd_open_tx { @@ -105,6 +124,17 @@ struct lsm_stream_cmd_open_tx_v2 { uint32_t topology_id; } __packed; +struct lsm_stream_stage_info { + uint32_t topology_id; + uint32_t island_enable; +} __packed; + +struct lsm_stream_cmd_open_tx_v3 { + struct apr_hdr hdr; + uint32_t num_stages; + struct lsm_stream_stage_info stage_info[0]; +} __packed; + struct lsm_custom_topologies { struct apr_hdr hdr; uint32_t data_payload_addr_lsw; @@ -242,8 +272,9 @@ int q6lsm_open(struct lsm_client *client, uint16_t app_id); int q6lsm_start(struct lsm_client *client, bool wait); int q6lsm_stop(struct lsm_client *client, bool wait); int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len, - bool allocate_module_data); -int q6lsm_snd_model_buf_free(struct lsm_client *client); + struct lsm_params_info_v2 *p_info); +int q6lsm_snd_model_buf_free(struct lsm_client *client, + struct lsm_params_info_v2 *p_info); int q6lsm_close(struct lsm_client *client); int q6lsm_register_sound_model(struct lsm_client *client, enum lsm_detection_mode mode, @@ -254,19 +285,22 @@ int q6lsm_set_data(struct lsm_client *client, int q6lsm_deregister_sound_model(struct lsm_client *client); void set_lsm_port(int lsm_port); int get_lsm_port(void); -int q6lsm_lab_control(struct lsm_client *client, u32 enable); +int q6lsm_lab_control(struct lsm_client *client, u32 enable, + struct lsm_params_info_v2 *p_info); int q6lsm_stop_lab(struct lsm_client *client); int q6lsm_read(struct lsm_client *client, struct lsm_cmd_read *read); int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc); int q6lsm_set_one_param(struct lsm_client *client, - struct lsm_params_info *p_info, void *data, + struct lsm_params_info_v2 *p_info, void *data, uint32_t param_type); void q6lsm_sm_set_param_data(struct lsm_client *client, - struct lsm_params_info *p_info, + struct lsm_params_info_v2 *p_info, size_t *offset); int q6lsm_set_port_connected(struct lsm_client *client); int q6lsm_set_fwk_mode_cfg(struct lsm_client *client, uint32_t event_mode); int q6lsm_set_media_fmt_params(struct lsm_client *client); int q6lsm_set_media_fmt_v2_params(struct lsm_client *client); -int q6lsm_lab_out_ch_cfg(struct lsm_client *client, u8 *ch_map); +int q6lsm_lab_out_ch_cfg(struct lsm_client *client, u8 *ch_map, + struct lsm_params_info_v2 *p_info); +bool q6lsm_adsp_supports_multi_stage_detection(void); #endif /* __Q6LSM_H__ */ -- GitLab From dfae8ef1bbb7c9e81e9864a82b3085db59bd7bbb Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Tue, 26 Jun 2018 15:44:10 -0700 Subject: [PATCH 0362/1645] dsp: add an exception in determining port type AFE ports have been identified as RX or TX based on a certain rule. Add an exception for VOICE_RECORD_TX port from this rule. Change-Id: I8a2fa4b6053baaf7747493aa385da887e6dd170c Signed-off-by: Vikram Panduranga --- dsp/q6afe.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index e2d19ab34259..38d5274f1b58 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -586,11 +586,23 @@ int afe_get_port_type(u16 port_id) { int ret = MSM_AFE_PORT_TYPE_RX; - /* Odd numbered ports are TX and Rx are Even numbered */ - if (port_id & 0x1) + switch (port_id) { + case VOICE_RECORD_RX: + case VOICE_RECORD_TX: ret = MSM_AFE_PORT_TYPE_TX; - else + break; + case VOICE_PLAYBACK_TX: + case VOICE2_PLAYBACK_TX: ret = MSM_AFE_PORT_TYPE_RX; + break; + default: + /* Odd numbered ports are TX and Rx are Even numbered */ + if (port_id & 0x1) + ret = MSM_AFE_PORT_TYPE_TX; + else + ret = MSM_AFE_PORT_TYPE_RX; + break; + } return ret; } -- GitLab From 1274b76c1db0f5d6723e17b526868ffaed9cf3d2 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Thu, 28 Jun 2018 15:40:57 +0530 Subject: [PATCH 0363/1645] dsp: afe: add missing codec dma port indices Add codec dma port indices in get port index function. CRs-Fixed: 2248380 Change-Id: I62fcf502ce997e1537c0ea47dd0292612cb297ad Signed-off-by: Mangesh Kunchamwar --- dsp/q6afe.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index d6f3521c12be..a01b9fd2cb55 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -4086,6 +4086,20 @@ int afe_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_INT6_MI2S_RX; case AFE_PORT_ID_INT6_MI2S_TX: return IDX_AFE_PORT_ID_INT6_MI2S_TX; + case AFE_PORT_ID_VA_CODEC_DMA_TX_0: + return IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_0; + case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + return IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_1; + case AFE_PORT_ID_WSA_CODEC_DMA_RX_0: + return IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_0; + case AFE_PORT_ID_WSA_CODEC_DMA_TX_0: + return IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_0; + case AFE_PORT_ID_WSA_CODEC_DMA_RX_1: + return IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_1; + case AFE_PORT_ID_WSA_CODEC_DMA_TX_1: + return IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_1; + case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: + return IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_2; default: pr_err("%s: port 0x%x\n", __func__, port_id); return -EINVAL; -- GitLab From daf02b01f2fa4a62cc6a5b99e3fa5e01b2ded677 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Thu, 28 Jun 2018 19:42:24 +0530 Subject: [PATCH 0364/1645] asoc: fix compilation issues Fix compilation issues for qcs405. CRs-Fixed: 2248380 Change-Id: I1a4929dbcd888cb6be30a155d2f492cbf314a25a Signed-off-by: Mangesh Kunchamwar --- asoc/codecs/bolero/va-macro.c | 13 ++++++----- asoc/codecs/wcd9335.c | 2 +- asoc/msm-pcm-routing-v2.c | 2 +- asoc/qcs405.c | 41 ----------------------------------- 4 files changed, 10 insertions(+), 48 deletions(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 554ed90415d5..113e341f5367 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -283,7 +283,7 @@ static void va_macro_mute_update_callback(struct work_struct *work) hpf_gate_reg = BOLERO_CDC_VA_TX0_TX_PATH_SEC2 + VA_MACRO_TX_PATH_OFFSET * decimator; snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x01); - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00); + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); dev_dbg(va_priv->dev, "%s: decimator %u unmute\n", __func__, decimator); } @@ -458,12 +458,15 @@ static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMU: (*dmic_clk_cnt)++; if (*dmic_clk_cnt == 1) { - snd_soc_update_bits(codec, dmic_clk_reg, - dmic_clk_en, dmic_clk_en); + snd_soc_update_bits(codec, + BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, + 0x80, 0x00); snd_soc_update_bits(codec, dmic_clk_reg, VA_MACRO_TX_DMIC_CLK_DIV_MASK, va_priv->dmic_clk_div << VA_MACRO_TX_DMIC_CLK_DIV_SHFT); + snd_soc_update_bits(codec, dmic_clk_reg, + dmic_clk_en, dmic_clk_en); } break; case SND_SOC_DAPM_POST_PMD: @@ -1453,7 +1456,7 @@ static int va_macro_probe(struct platform_device *pdev) ret = of_property_read_u32(pdev->dev.of_node, dmic_sample_rate, &sample_rate); if (ret) { - dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", + dev_err(&pdev->dev, "%s: could not find %d entry in dt\n", __func__, sample_rate); va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_2; } else { @@ -1484,7 +1487,7 @@ static int va_macro_probe(struct platform_device *pdev) if (IS_ERR(va_priv->micb_supply)) { ret = PTR_ERR(va_priv->micb_supply); dev_err(&pdev->dev, - "%s:Failed to get micbias supply for VA Mic\n", + "%s:Failed to get micbias supply for VA Mic %d\n", __func__, ret); return ret; } diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 7bc94018d5ad..8564ac1a00c3 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -13589,7 +13589,7 @@ static int tasha_codec_probe(struct snd_soc_codec *codec) if (tasha->is_wsa_attach) snd_soc_add_codec_controls(codec, tasha_spkr_wsa_controls, - ARRAY_SIZE(tasha_wsa_controls)); + ARRAY_SIZE(tasha_spkr_wsa_controls)); control->num_rx_port = TASHA_RX_MAX; control->rx_chs = ptr; memcpy(control->rx_chs, tasha_rx_chs, sizeof(tasha_rx_chs)); diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 1e433300c3b1..d490de735750 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1220,7 +1220,7 @@ int msm_pcm_routing_get_pp_ch_cnt(int fe_id, int session_type) ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, &be_id, &cfg_data); if (ret) { - pr_err("%s: cannot get stream app type cfg\n"); + pr_err("%s: cannot get stream app type cfg\n", __func__); return ret; } diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 80f7acc02dcf..646da3ee6b3f 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -6833,47 +6833,6 @@ static int msm_populate_dai_link_component_of_node( return ret; } -static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd) -{ - return 0; -} - -static int msm_snd_stub_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - - int ret = 0; - unsigned int rx_ch[] = {144, 145, 146, 147, 148, 149, 150, - 151}; - unsigned int tx_ch[] = {128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143}; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, - slim_rx_cfg[SLIM_RX_0].channels, - rx_ch); - if (ret < 0) - pr_err("%s: RX failed to set cpu chan map error %d\n", - __func__, ret); - } else { - ret = snd_soc_dai_set_channel_map(cpu_dai, - slim_tx_cfg[SLIM_TX_0].channels, - tx_ch, 0, 0); - if (ret < 0) - pr_err("%s: TX failed to set cpu chan map error %d\n", - __func__, ret); - } - - return ret; -} - -static struct snd_soc_ops msm_stub_be_ops = { - .hw_params = msm_snd_stub_hw_params, -}; - static struct snd_soc_dai_link msm_stub_fe_dai_links[] = { /* FrontEnd DAI Links */ -- GitLab From 9d2cada0af209421415d33f6dd5c8666c26e26e7 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Thu, 28 Jun 2018 20:07:16 +0530 Subject: [PATCH 0365/1645] asoc: fix for applying parameters for codec dma Fix for getting the parameters for codec dma interface from mixer controls and apply to port config. CRs-Fixed: 2248380 Change-Id: I351c32e868b8fd3fde3eabbeef89b625a7bf8598 Signed-off-by: Mangesh Kunchamwar --- asoc/msm-dai-q6-v2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index da83894a4e6d..5d43547d2476 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -9405,6 +9405,9 @@ static int msm_dai_q6_cdc_dma_hw_params( return -EINVAL; } + dai_data->rate = params_rate(params); + dai_data->channels = params_channels(params); + dai_data->port_config.cdc_dma.cdc_dma_cfg_minor_version = AFE_API_VERSION_CODEC_DMA_CONFIG; dai_data->port_config.cdc_dma.sample_rate = dai_data->rate; -- GitLab From bfba054b89e5b0f2a18e49a308882107e1ad5837 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 20 Jun 2018 15:20:28 -0700 Subject: [PATCH 0366/1645] asoc: msm-pcm-routing: Add TDM ext ec ref route Add SEC TDM interface TX to external echo reference routing. Change-Id: I79c62cd21e88de67f6f896cb6b7c8651bf1fb3e0 Signed-off-by: Karthikeyan Mani --- asoc/msm-pcm-routing-v2.c | 5 ++++- asoc/msm-pcm-routing-v2.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 1ee5687e0f5d..fd0e2424b7ce 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -3887,6 +3887,9 @@ static int msm_routing_ext_ec_put(struct snd_kcontrol *kcontrol, case EXT_EC_REF_SLIM_1_TX: ext_ec_ref_port_id = SLIMBUS_1_TX; break; + case EXT_EC_REF_SEC_TDM_TX: + ext_ec_ref_port_id = AFE_PORT_ID_SECONDARY_TDM_TX; + break; case EXT_EC_REF_NONE: default: ext_ec_ref_port_id = AFE_PORT_INVALID; @@ -3911,7 +3914,7 @@ static int msm_routing_ext_ec_put(struct snd_kcontrol *kcontrol, static const char * const ext_ec_ref_rx[] = {"NONE", "PRI_MI2S_TX", "SEC_MI2S_TX", "TERT_MI2S_TX", "QUAT_MI2S_TX", "QUIN_MI2S_TX", - "SLIM_1_TX"}; + "SLIM_1_TX", "SEC_TDM_TX"}; static const struct soc_enum msm_route_ext_ec_ref_rx_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ext_ec_ref_rx), ext_ec_ref_rx), diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 345e4d9cb98e..61b8bdf63936 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -433,6 +433,7 @@ enum { EXT_EC_REF_QUAT_MI2S_TX, EXT_EC_REF_QUIN_MI2S_TX, EXT_EC_REF_SLIM_1_TX, + EXT_EC_REF_SEC_TDM_TX, }; #define INVALID_SESSION -1 -- GitLab From 6e55ad86b2dec8febca1e3966e1f1f05131c5980 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Wed, 14 Mar 2018 13:56:18 -0700 Subject: [PATCH 0367/1645] dsp: preload voice and copp topologies Set topology info to q6core service in ADSP so that the modules in a topology can be loaded before the usecase starts, thus reducing usecase setup latency. The same topology is unloaded before vocproc or copp is destroyed or replaced. Change-Id: I5f8872130fb09f049e080c61edb8bb0b05e5e2de Signed-off-by: Vikram Panduranga --- asoc/msm-pcm-routing-v2.c | 65 ++++++++++++++++++++++++++++++++++++ dsp/q6core.c | 69 +++++++++++++++++++++++++++++++++++++++ dsp/q6voice.c | 42 ++++++++++++++++++++++++ include/dsp/q6core.h | 18 +++++++++- 4 files changed, 193 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 5e825506e74c..bd023929b17e 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -147,6 +147,9 @@ static struct msm_pcm_route_bdai_name be_dai_name_table[MSM_BACKEND_DAI_MAX]; static int msm_routing_send_device_pp_params(int port_id, int copp_idx, int fe_id); +static void msm_routing_load_topology(size_t data_size, void *data); +static void msm_routing_unload_topology(uint32_t topology_id); + static int msm_routing_get_bit_width(unsigned int format) { int bit_width; @@ -1547,6 +1550,7 @@ void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type) } topology = adm_get_topology_for_port_copp_idx( msm_bedais[i].port_id, idx); + msm_routing_unload_topology(topology); adm_close(msm_bedais[i].port_id, fdai->perf_mode, idx); pr_debug("%s:copp:%ld,idx bit fe:%d,type:%d,be:%d\n", __func__, copp, fedai_id, session_type, i); @@ -1745,6 +1749,7 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) port_id = msm_bedais[reg].port_id; topology = adm_get_topology_for_port_copp_idx(port_id, idx); + msm_routing_unload_topology(topology); adm_close(msm_bedais[reg].port_id, fdai->perf_mode, idx); pr_debug("%s: copp: %ld, reset idx bit fe:%d, type: %d, be:%d topology=0x%x\n", @@ -16308,6 +16313,7 @@ static int msm_pcm_routing_close(struct snd_pcm_substream *substream) port_id = bedai->port_id; topology = adm_get_topology_for_port_copp_idx(port_id, idx); + msm_routing_unload_topology(topology); adm_close(bedai->port_id, fdai->perf_mode, idx); pr_debug("%s: copp:%ld,idx bit fe:%d, type:%d,be:%d topology=0x%x\n", __func__, copp, i, session_type, be_id, @@ -16600,6 +16606,60 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx, return 0; } +static uint32_t msm_routing_get_topology(size_t data_size, void *data) +{ + uint32_t topology = NULL_COPP_TOPOLOGY; + void *cal_info = NULL; + uint32_t size = 0; + + /* Retrieve cal_info size from cal data*/ + size = data_size - sizeof(struct audio_cal_type_basic); + cal_info = kzalloc(size, GFP_KERNEL); + + if (!cal_info) + goto done; + + memcpy(cal_info, + ((uint8_t *)data + sizeof(struct audio_cal_type_basic)), size); + + topology = ((struct audio_cal_info_adm_top *)cal_info)->topology; + kfree(cal_info); + cal_info = NULL; + +done: + pr_debug("%s: Using topology %d\n", __func__, topology); + + return topology; +} + +static void msm_routing_load_topology(size_t data_size, void *data) +{ + uint32_t topology_id; + int ret; + + topology_id = msm_routing_get_topology(data_size, data); + if (topology_id != NULL_COPP_TOPOLOGY) + ret = q6core_load_unload_topo_modules(topology_id, + CORE_LOAD_TOPOLOGY); + if (ret < 0) + pr_debug("%s %d load topology failed\n", + __func__, topology_id); + +} + +static void msm_routing_unload_topology(uint32_t topology_id) +{ + int ret; + + if (topology_id != NULL_COPP_TOPOLOGY) + ret = q6core_load_unload_topo_modules(topology_id, + CORE_UNLOAD_TOPOLOGY); + if (ret < 0) + pr_debug("%s %d unload topology failed\n", + __func__, topology_id); + +} + static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -17065,6 +17125,11 @@ static int msm_routing_set_cal(int32_t cal_type, ret = -EINVAL; goto done; } + /* Pre-load if it is ADM topology */ + if ((cal_index == ADM_TOPOLOGY_CAL_TYPE_IDX) || + (cal_index == ADM_LSM_TOPOLOGY_CAL_TYPE_IDX)) { + msm_routing_load_topology(data_size, data); + } done: return ret; } diff --git a/dsp/q6core.c b/dsp/q6core.c index c5b64096a234..cc163ff67fa9 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -184,6 +184,17 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) q6core_lcl.avcs_fwk_ver_resp_received = 1; wake_up(&q6core_lcl.avcs_fwk_ver_req_wait); break; + case AVCS_CMD_LOAD_TOPO_MODULES: + case AVCS_CMD_UNLOAD_TOPO_MODULES: + pr_debug("%s: Cmd = %s status[%s]\n", + __func__, + (payload1[0] == AVCS_CMD_LOAD_TOPO_MODULES) ? + "AVCS_CMD_LOAD_TOPO_MODULES" : + "AVCS_CMD_UNLOAD_TOPO_MODULES", + adsp_err_get_err_str(payload1[1])); + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; default: pr_err("%s: Invalid cmd rsp[0x%x][0x%x] opcode %d\n", __func__, @@ -655,6 +666,64 @@ uint32_t core_set_dolby_manufacturer_id(int manufacturer_id) } EXPORT_SYMBOL(core_set_dolby_manufacturer_id); +int32_t q6core_load_unload_topo_modules(uint32_t topo_id, + bool preload_type) +{ + struct avcs_cmd_load_unload_topo_modules load_unload_topo_modules; + int ret = 0; + + mutex_lock(&(q6core_lcl.cmd_lock)); + ocm_core_open(); + if (q6core_lcl.core_handle_q == NULL) { + pr_err("%s: apr registration for CORE failed\n", __func__); + ret = -ENODEV; + goto done; + } + + memset(&load_unload_topo_modules, 0, sizeof(load_unload_topo_modules)); + load_unload_topo_modules.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + load_unload_topo_modules.hdr.pkt_size = + sizeof(struct avcs_cmd_load_unload_topo_modules); + load_unload_topo_modules.hdr.src_port = 0; + load_unload_topo_modules.hdr.dest_port = 0; + load_unload_topo_modules.hdr.token = 0; + + if (preload_type == CORE_LOAD_TOPOLOGY) + load_unload_topo_modules.hdr.opcode = + AVCS_CMD_LOAD_TOPO_MODULES; + else + load_unload_topo_modules.hdr.opcode = + AVCS_CMD_UNLOAD_TOPO_MODULES; + + load_unload_topo_modules.topology_id = topo_id; + q6core_lcl.bus_bw_resp_received = 0; + ret = apr_send_pkt(q6core_lcl.core_handle_q, + (uint32_t *) &load_unload_topo_modules); + if (ret < 0) { + pr_err("%s: Load/unload topo modules failed for topology = %d ret = %d\n", + __func__, topo_id, ret); + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(q6core_lcl.bus_bw_req_wait, + (q6core_lcl.bus_bw_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout for load/unload topo modules\n", + __func__); + ret = -ETIME; + goto done; + } +done: + mutex_unlock(&(q6core_lcl.cmd_lock)); + + return ret; +} +EXPORT_SYMBOL(q6core_load_unload_topo_modules); + /** * q6core_is_adsp_ready - check adsp ready status * diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 788805e0bdf5..af933a804e0b 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -96,6 +96,8 @@ static int voice_send_cvp_channel_info_v2(struct voice_data *v, uint32_t param_type); static int voice_get_avcs_version_per_service(uint32_t service_id); +static void voice_load_topo_modules(int cal_index); +static void voice_unload_topo_modules(void); static int voice_cvs_stop_playback(struct voice_data *v); static int voice_cvs_start_playback(struct voice_data *v); @@ -2698,6 +2700,35 @@ static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v) } +static void voice_load_topo_modules(int cal_index) +{ + uint32_t topology_id; + int ret; + + topology_id = voice_get_topology(cal_index); + ret = q6core_load_unload_topo_modules(topology_id, CORE_LOAD_TOPOLOGY); + if (ret < 0) + pr_debug("%s ret:%d load topo modules %d failed\n", + __func__, ret, topology_id); + +} + +static void voice_unload_topo_modules(void) +{ + uint32_t topology_id; + int i, ret; + + for (i = CVP_VOC_RX_TOPOLOGY_CAL; i <= CVP_VOC_TX_TOPOLOGY_CAL; i++) { + topology_id = voice_get_topology(i); + ret = q6core_load_unload_topo_modules(topology_id, + CORE_UNLOAD_TOPOLOGY); + if (ret < 0) { + pr_debug("%s ret:%d unload topo modules %d failed\n", + __func__, ret, topology_id); + } + } +} + static int voice_send_cvp_create_cmd(struct voice_data *v) { struct cvp_create_full_ctl_session_cmd cvp_session_cmd; @@ -5000,6 +5031,9 @@ static int voice_destroy_vocproc(struct voice_data *v) voice_send_cvp_deregister_dev_cfg_cmd(v); voice_send_cvs_deregister_cal_cmd(v); + /* Unload topology modules */ + voice_unload_topo_modules(); + /* destrop cvp session */ cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), @@ -6728,6 +6762,9 @@ int voc_disable_device(uint32_t session_id) voice_send_cvp_deregister_cal_cmd(v); voice_send_cvp_deregister_dev_cfg_cmd(v); + /* Unload topology modules */ + voice_unload_topo_modules(); + v->voc_state = VOC_CHANGE; } else { pr_debug("%s: called in voc state=%d, No_OP\n", @@ -8721,6 +8758,11 @@ static int voice_set_cal(int32_t cal_type, ret = -EINVAL; goto done; } + /* Pre-load if it is voice Rx or Tx topology */ + if ((cal_index == CVP_VOC_RX_TOPOLOGY_CAL) || + (cal_index == CVP_VOC_TX_TOPOLOGY_CAL)) { + voice_load_topo_modules(cal_index); + } done: return ret; } diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index f6240a33e6fd..e7f135a0bcdf 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -158,8 +158,24 @@ struct avcs_cmd_deregister_topologies { #define AVCS_MODE_DEREGISTER_ALL_CUSTOM_TOPOLOGIES 2 +#define AVCS_CMD_LOAD_TOPO_MODULES 0x0001296C + +#define AVCS_CMD_UNLOAD_TOPO_MODULES 0x0001296D + +#define CORE_LOAD_TOPOLOGY 0 + +#define CORE_UNLOAD_TOPOLOGY 1 + +struct avcs_cmd_load_unload_topo_modules { + struct apr_hdr hdr; + uint32_t topology_id; +} __packed; + int32_t core_set_license(uint32_t key, uint32_t module_id); int32_t core_get_license_status(uint32_t module_id); +int32_t q6core_load_unload_topo_modules(uint32_t topology_id, + bool preload_type); + #endif /* __Q6CORE_H__ */ -- GitLab From bfc919ea4324e30f790abcddda0fa6cd63ebc010 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Mon, 25 Jun 2018 19:03:09 -0700 Subject: [PATCH 0368/1645] dsp: msm_audio_ion: check only for probe complete for ION alloc While allocating and importing ION buffers, make sure to check for probe complete flag before proceeding instead of checking for the flag AND smmu_enabled flag. This way the restriction will be centralized for either types of targets with and without SMMU. Change-Id: I558e19724d1002a602377a636e274bc90ca8262d Signed-off-by: Banajit Goswami --- dsp/msm_audio_ion.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index ec147fb8dd46..018b1a9c3c76 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -347,8 +347,7 @@ int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, int rc = -EINVAL; unsigned long err_ion_ptr = 0; - if ((msm_audio_ion_data.smmu_enabled == true) && - !(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { + if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { pr_debug("%s:probe is not done, deferred\n", __func__); return -EPROBE_DEFER; } @@ -412,8 +411,7 @@ int msm_audio_ion_import(struct dma_buf **dma_buf, int fd, { int rc = 0; - if ((msm_audio_ion_data.smmu_enabled == true) && - !(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { + if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { pr_debug("%s: probe is not done, deferred\n", __func__); return -EPROBE_DEFER; } -- GitLab From bc394037dd9436827b4fd0e573173ec4c2ad28ec Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Tue, 19 Jun 2018 17:07:57 +0530 Subject: [PATCH 0369/1645] rtac: Add mutex protection for rtac cal apis Add mutex lock protection to synchronize rtac calibration set and get api calls. Change-Id: Ieb2d01642ecefff6405bb59554157c304b4b651d Signed-off-by: Ramprasad Katkam --- dsp/rtac.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/dsp/rtac.c b/dsp/rtac.c index 9d7c0d472580..7102ae2927c6 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -122,6 +122,10 @@ struct mutex rtac_asm_apr_mutex; struct mutex rtac_voice_mutex; struct mutex rtac_voice_apr_mutex; struct mutex rtac_afe_apr_mutex; +struct mutex rtac_asm_cal_mutex; +struct mutex rtac_adm_cal_mutex; +struct mutex rtac_afe_cal_mutex; +struct mutex rtac_voice_cal_mutex; int rtac_clear_mapping(uint32_t cal_type) { @@ -1803,64 +1807,84 @@ static long rtac_ioctl_shared(struct file *f, } case AUDIO_GET_RTAC_ADM_CAL: + mutex_lock(&rtac_adm_cal_mutex); opcode = q6common_is_instance_id_supported() ? ADM_CMD_GET_PP_PARAMS_V6 : ADM_CMD_GET_PP_PARAMS_V5; result = send_adm_apr((void *) arg, opcode); + mutex_unlock(&rtac_adm_cal_mutex); break; case AUDIO_SET_RTAC_ADM_CAL: + mutex_lock(&rtac_adm_cal_mutex); opcode = q6common_is_instance_id_supported() ? ADM_CMD_SET_PP_PARAMS_V6 : ADM_CMD_SET_PP_PARAMS_V5; result = send_adm_apr((void *) arg, opcode); + mutex_unlock(&rtac_adm_cal_mutex); break; case AUDIO_GET_RTAC_ASM_CAL: + mutex_lock(&rtac_asm_cal_mutex); opcode = q6common_is_instance_id_supported() ? ASM_STREAM_CMD_GET_PP_PARAMS_V3 : ASM_STREAM_CMD_GET_PP_PARAMS_V2; result = send_rtac_asm_apr((void *) arg, opcode); + mutex_unlock(&rtac_asm_cal_mutex); break; case AUDIO_SET_RTAC_ASM_CAL: + mutex_lock(&rtac_asm_cal_mutex); opcode = q6common_is_instance_id_supported() ? ASM_STREAM_CMD_SET_PP_PARAMS_V3 : ASM_STREAM_CMD_SET_PP_PARAMS_V2; result = send_rtac_asm_apr((void *) arg, opcode); + mutex_unlock(&rtac_asm_cal_mutex); break; case AUDIO_GET_RTAC_CVS_CAL: + mutex_lock(&rtac_voice_cal_mutex); opcode = q6common_is_instance_id_supported() ? VSS_ICOMMON_CMD_GET_PARAM_V3 : VSS_ICOMMON_CMD_GET_PARAM_V2; result = send_voice_apr(RTAC_CVS, (void *) arg, opcode); + mutex_unlock(&rtac_voice_cal_mutex); break; case AUDIO_SET_RTAC_CVS_CAL: + mutex_lock(&rtac_voice_cal_mutex); opcode = q6common_is_instance_id_supported() ? VSS_ICOMMON_CMD_SET_PARAM_V3 : VSS_ICOMMON_CMD_SET_PARAM_V2; result = send_voice_apr(RTAC_CVS, (void *) arg, opcode); + mutex_unlock(&rtac_voice_cal_mutex); break; case AUDIO_GET_RTAC_CVP_CAL: + mutex_lock(&rtac_voice_cal_mutex); opcode = q6common_is_instance_id_supported() ? VSS_ICOMMON_CMD_GET_PARAM_V3 : VSS_ICOMMON_CMD_GET_PARAM_V2; result = send_voice_apr(RTAC_CVP, (void *) arg, opcode); + mutex_unlock(&rtac_voice_cal_mutex); break; case AUDIO_SET_RTAC_CVP_CAL: + mutex_lock(&rtac_voice_cal_mutex); opcode = q6common_is_instance_id_supported() ? VSS_ICOMMON_CMD_SET_PARAM_V3 : VSS_ICOMMON_CMD_SET_PARAM_V2; result = send_voice_apr(RTAC_CVP, (void *) arg, opcode); + mutex_unlock(&rtac_voice_cal_mutex); break; case AUDIO_GET_RTAC_AFE_CAL: + mutex_lock(&rtac_afe_cal_mutex); opcode = q6common_is_instance_id_supported() ? AFE_PORT_CMD_GET_PARAM_V3 : AFE_PORT_CMD_GET_PARAM_V2; result = send_rtac_afe_apr((void __user *) arg, opcode); + mutex_unlock(&rtac_afe_cal_mutex); break; case AUDIO_SET_RTAC_AFE_CAL: + mutex_lock(&rtac_afe_cal_mutex); opcode = q6common_is_instance_id_supported() ? AFE_PORT_CMD_SET_PARAM_V3 : AFE_PORT_CMD_SET_PARAM_V2; result = send_rtac_afe_apr((void __user *) arg, opcode); + mutex_unlock(&rtac_afe_cal_mutex); break; default: pr_err("%s: Invalid IOCTL, command = %d!\n", @@ -1992,6 +2016,7 @@ int __init rtac_init(void) init_waitqueue_head(&rtac_adm_apr_data.cmd_wait); mutex_init(&rtac_adm_mutex); mutex_init(&rtac_adm_apr_mutex); + mutex_init(&rtac_adm_cal_mutex); rtac_adm_buffer = kzalloc( rtac_cal[ADM_RTAC_CAL].map_data.map_size, GFP_KERNEL); @@ -2005,6 +2030,7 @@ int __init rtac_init(void) init_waitqueue_head(&rtac_asm_apr_data[i].cmd_wait); } mutex_init(&rtac_asm_apr_mutex); + mutex_init(&rtac_asm_cal_mutex); rtac_asm_buffer = kzalloc( rtac_cal[ASM_RTAC_CAL].map_data.map_size, GFP_KERNEL); @@ -2018,6 +2044,7 @@ int __init rtac_init(void) atomic_set(&rtac_afe_apr_data.cmd_state, 0); init_waitqueue_head(&rtac_afe_apr_data.cmd_wait); mutex_init(&rtac_afe_apr_mutex); + mutex_init(&rtac_afe_cal_mutex); rtac_afe_buffer = kzalloc( rtac_cal[AFE_RTAC_CAL].map_data.map_size, GFP_KERNEL); @@ -2036,6 +2063,7 @@ int __init rtac_init(void) } mutex_init(&rtac_voice_mutex); mutex_init(&rtac_voice_apr_mutex); + mutex_init(&rtac_voice_cal_mutex); rtac_voice_buffer = kzalloc( rtac_cal[VOICE_RTAC_CAL].map_data.map_size, GFP_KERNEL); -- GitLab From 353723e8e08b6f5538e354ec78a3f06fe9793bf6 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Mon, 22 Jan 2018 15:25:26 +0800 Subject: [PATCH 0370/1645] ASoC: wcd934x: skip mutex lock for WDSP boot timeout debug dump In the case of WDSP boot timeout, api_mutex and ssr_mutex have already been acquired. There is no need to do mutex lock again during debug dump. Check the signal enum to see if it's the internal WDSP boot timeout case. Change-Id: I6fe5e77b1bff72ed5ad463bb1df76c6b02c84c92 Signed-off-by: Xiaojun Sang --- asoc/codecs/wcd-dsp-mgr.c | 39 ++++++++++++++++++++++---- asoc/codecs/wcd934x/wcd934x-dsp-cntl.c | 16 +++++++---- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/asoc/codecs/wcd-dsp-mgr.c b/asoc/codecs/wcd-dsp-mgr.c index 9e65deb473b1..50716e4d57c6 100644 --- a/asoc/codecs/wcd-dsp-mgr.c +++ b/asoc/codecs/wcd-dsp-mgr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -839,21 +839,20 @@ static int wdsp_ssr_handler(struct wdsp_mgr_priv *wdsp, void *arg, } #ifdef CONFIG_DEBUG_FS -static int wdsp_debug_dump_handler(struct wdsp_mgr_priv *wdsp, void *arg) +static int __wdsp_dbg_dump_locked(struct wdsp_mgr_priv *wdsp, void *arg) { struct wdsp_err_signal_arg *err_data; int ret = 0; - WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex); /* If there is no SSR, set the SSR type to collect ramdumps */ if (wdsp->ssr_type == WDSP_SSR_TYPE_NO_SSR) { wdsp->ssr_type = WDSP_SSR_TYPE_WDSP_DOWN; } else { WDSP_DBG(wdsp, "SSR handling is running, skip debug ramdump"); ret = 0; - WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex); goto done; } + if (arg) { err_data = (struct wdsp_err_signal_arg *) arg; memcpy(&wdsp->dump_data.err_data, err_data, @@ -861,16 +860,29 @@ static int wdsp_debug_dump_handler(struct wdsp_mgr_priv *wdsp, void *arg) } else { WDSP_DBG(wdsp, "Invalid input, arg is NULL"); ret = -EINVAL; - WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex); goto done; } wdsp_collect_ramdumps(wdsp); wdsp->ssr_type = WDSP_SSR_TYPE_NO_SSR; - WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex); done: return ret; } +static int wdsp_debug_dump_handler(struct wdsp_mgr_priv *wdsp, void *arg) +{ + int ret = 0; + + WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex); + ret = __wdsp_dbg_dump_locked(wdsp, arg); + WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex); + + return ret; +} #else +static int __wdsp_dbg_dump_locked(struct wdsp_mgr_priv *wdsp, void *arg) +{ + return 0; +} + static int wdsp_debug_dump_handler(struct wdsp_mgr_priv *wdsp, void *arg) { return 0; @@ -887,7 +899,13 @@ static int wdsp_signal_handler(struct device *wdsp_dev, return -EINVAL; wdsp = dev_get_drvdata(wdsp_dev); + +#ifdef CONFIG_DEBUG_FS + if (signal != WDSP_DEBUG_DUMP_INTERNAL) + WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->api_mutex); +#else WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->api_mutex); +#endif WDSP_DBG(wdsp, "Raised signal %d", signal); @@ -908,6 +926,9 @@ static int wdsp_signal_handler(struct device *wdsp_dev, case WDSP_DEBUG_DUMP: ret = wdsp_debug_dump_handler(wdsp, arg); break; + case WDSP_DEBUG_DUMP_INTERNAL: + ret = __wdsp_dbg_dump_locked(wdsp, arg); + break; default: ret = -EINVAL; break; @@ -916,7 +937,13 @@ static int wdsp_signal_handler(struct device *wdsp_dev, if (ret < 0) WDSP_ERR(wdsp, "handling signal %d failed with error %d", signal, ret); + +#ifdef CONFIG_DEBUG_FS + if (signal != WDSP_DEBUG_DUMP_INTERNAL) + WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->api_mutex); +#else WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->api_mutex); +#endif return ret; } diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c index 58987ad02ce8..662f484028ee 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c @@ -101,6 +101,7 @@ static u16 wdsp_reg_for_debug_dump[] = { WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL, WCD934X_CPE_SS_MAD_CTL, WCD934X_CPE_SS_CPAR_CTL, + WCD934X_CPE_SS_CPAR_CFG, WCD934X_CPE_SS_WDOG_CFG, WCD934X_CPE_SS_STATUS, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, @@ -113,10 +114,12 @@ static u16 wdsp_reg_for_debug_dump[] = { WCD934X_CPE_SS_SS_ERROR_INT_STATUS_1B, }; -static void wcd_cntl_collect_debug_dumps(struct wcd_dsp_cntl *cntl) +static void wcd_cntl_collect_debug_dumps(struct wcd_dsp_cntl *cntl, + bool internal) { struct snd_soc_codec *codec = cntl->codec; struct wdsp_err_signal_arg arg; + enum wdsp_signal signal; int i; u8 val; @@ -146,8 +149,8 @@ static void wcd_cntl_collect_debug_dumps(struct wcd_dsp_cntl *cntl) arg.mem_dumps_enabled = cntl->ramdump_enable; arg.remote_start_addr = WCD_934X_RAMDUMP_START_ADDR; arg.dump_size = WCD_934X_RAMDUMP_SIZE; - cntl->m_ops->signal_handler(cntl->m_dev, WDSP_DEBUG_DUMP, - &arg); + signal = internal ? WDSP_DEBUG_DUMP_INTERNAL : WDSP_DEBUG_DUMP; + cntl->m_ops->signal_handler(cntl->m_dev, signal, &arg); } /* Unmask the fatal irqs */ @@ -161,7 +164,8 @@ static void wcd_cntl_collect_debug_dumps(struct wcd_dsp_cntl *cntl) #else #define WCD_CNTL_SET_ERR_IRQ_FLAG(cntl) 0 #define WCD_CNTL_CLR_ERR_IRQ_FLAG(cntl) do {} while (0) -static void wcd_cntl_collect_debug_dumps(struct wcd_dsp_cntl *cntl) +static void wcd_cntl_collect_debug_dumps(struct wcd_dsp_cntl *cntl, + bool internal) { } #endif @@ -753,7 +757,7 @@ static int wcd_cntl_do_boot(struct wcd_dsp_cntl *cntl) if (!ret) { dev_err(codec->dev, "%s: WDSP boot timed out\n", __func__); - wcd_cntl_collect_debug_dumps(cntl); + wcd_cntl_collect_debug_dumps(cntl, true); ret = -ETIMEDOUT; goto err_boot; } else { @@ -1041,7 +1045,7 @@ static ssize_t wcd_miscdev_write(struct file *filep, const char __user *ubuf, } else if (!strcmp(val, "DEBUG_DUMP")) { dev_dbg(cntl->codec->dev, "%s: Collect dumps for debug use\n", __func__); - wcd_cntl_collect_debug_dumps(cntl); + wcd_cntl_collect_debug_dumps(cntl, false); goto done; } else { dev_err(cntl->codec->dev, "%s: Invalid value %s\n", -- GitLab From e5e322cff04b96ce50df575e3e673d2085d45614 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Wed, 20 Jun 2018 19:00:56 +0530 Subject: [PATCH 0371/1645] asoc: config: support for CSRA66X0 device Add config for CSRA66X0 device to be enabled in QCS405 Change-Id: I3cddb26fa7ebb03da89113d7f051b25d614c9ad0 Signed-off-by: Mangesh Kunchamwar --- config/qcs405auto.conf | 1 + config/qcs405autoconf.h | 1 + 2 files changed, 2 insertions(+) diff --git a/config/qcs405auto.conf b/config/qcs405auto.conf index c211830865a0..b2c80cd7ce4e 100644 --- a/config/qcs405auto.conf +++ b/config/qcs405auto.conf @@ -5,6 +5,7 @@ CONFIG_SND_SOC_WSA881X=m CONFIG_SND_SOC_WCD9335=m CONFIG_WCD9XXX_CODEC_CORE=m CONFIG_MSM_CDC_PINCTRL=m +CONFIG_SND_SOC_CSRA66X0=m CONFIG_MSM_QDSP6V2_CODECS=m CONFIG_MSM_ULTRASOUND=m CONFIG_MSM_QDSP6_APRV2_RPMSG=m diff --git a/config/qcs405autoconf.h b/config/qcs405autoconf.h index e4591e30e27b..039b67baf9e9 100644 --- a/config/qcs405autoconf.h +++ b/config/qcs405autoconf.h @@ -15,6 +15,7 @@ #define CONFIG_SND_SOC_WCD9XXX_V2 1 #define CONFIG_SND_SOC_WSA881X 1 #define CONFIG_SND_SOC_WCD9335 1 +#define CONFIG_SND_SOC_CSRA66X0 1 #define CONFIG_WCD9XXX_CODEC_CORE 1 #define CONFIG_MSM_CDC_PINCTRL 1 #define CONFIG_MSM_QDSP6V2_CODECS 1 -- GitLab From 3dd07e69379fcba0c511bc4a1453ada7c1c90c4a Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 28 Jun 2018 18:25:08 -0700 Subject: [PATCH 0372/1645] asoc: mbhc: ignore mbhc event report during ssr When ssr is in progress, during some race conditions mbhc events are getting reported when codec is still coming up. Ignore such events without reporting. Change-Id: I3d3f78f97c2b855fc36a480f38c166bda2d979f0 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd-mbhc-v2.c | 6 ++++++ asoc/codecs/wcd-mbhc-v2.h | 1 + asoc/codecs/wcd934x/wcd934x.c | 1 + 3 files changed, 8 insertions(+) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index fd02dce7cb1e..6f3b19ba6c1b 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -776,6 +776,11 @@ void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc, bool anc_mic_found = false; enum snd_jack_types jack_type; + if (mbhc->deinit_in_progress) { + pr_info("%s: mbhc deinit in progess: ignore report\n"); + return; + } + pr_debug("%s: enter current_plug(%d) new_plug(%d)\n", __func__, mbhc->current_plug, plug_type); @@ -1882,6 +1887,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, goto err_hphr_ocp_irq; } + mbhc->deinit_in_progress = false; pr_debug("%s: leave ret %d\n", __func__, ret); return ret; diff --git a/asoc/codecs/wcd-mbhc-v2.h b/asoc/codecs/wcd-mbhc-v2.h index 2fb09ff5be5c..04735741047b 100644 --- a/asoc/codecs/wcd-mbhc-v2.h +++ b/asoc/codecs/wcd-mbhc-v2.h @@ -582,6 +582,7 @@ struct wcd_mbhc { struct completion btn_press_compl; struct mutex hphl_pa_lock; struct mutex hphr_pa_lock; + bool deinit_in_progress; /* Holds mbhc detection method - ADC/Legacy */ unsigned int mbhc_detection_logic; diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 92395d3401df..4f28ae99c344 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -9980,6 +9980,7 @@ static int tavil_device_down(struct wcd9xxx *wcd9xxx) for (count = 0; count < NUM_CODEC_DAIS; count++) priv->dai[count].bus_down_in_recovery = true; + priv->mbhc->wcd_mbhc.deinit_in_progress = true; if (delayed_work_pending(&priv->spk_anc_dwork.dwork)) cancel_delayed_work(&priv->spk_anc_dwork.dwork); for (decimator = 0; decimator < WCD934X_NUM_DECIMATORS; decimator++) { -- GitLab From c07b37a4c3ad581c8904aafca93f9c441ab931f0 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 4 May 2018 05:56:47 +0530 Subject: [PATCH 0373/1645] ASoC: msm-pcm-routing: Add mixer control for AANC noise level Add mixer control for AANC noise level to control AANC noise level from userspace when AANC functionality is enabled. Change-Id: Id47b77e054008853e5b5ddb0e9cc126626b407b8 Signed-off-by: Sudheer Papothi --- asoc/msm-pcm-routing-v2.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 9fc3d435d1ab..f42ac546bd45 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -83,6 +83,7 @@ static int msm_route_ext_ec_ref; static bool is_custom_stereo_on; static bool is_ds2_on; static bool swap_ch; +static int aanc_level; #define WEIGHT_0_DB 0x4000 /* all the FEs which can support channel mixer */ @@ -14622,6 +14623,34 @@ static const struct snd_kcontrol_new aanc_slim_0_rx_mux[] = { msm_routing_slim_0_rx_aanc_mux_put) }; +static int msm_routing_aanc_noise_level_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = aanc_level; + + return 0; +} + +static int msm_routing_aanc_noise_level_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + + mutex_lock(&routing_lock); + aanc_level = ucontrol->value.integer.value[0]; + pr_debug("%s: value: %ld\n", + __func__, ucontrol->value.integer.value[0]); + ret = afe_set_aanc_noise_level(aanc_level); + mutex_unlock(&routing_lock); + + return ret; +} + +static const struct snd_kcontrol_new aanc_noise_level[] = { + SOC_SINGLE_EXT("AANC Noise Level", SND_SOC_NOPM, 0, 255, + 0, msm_routing_aanc_noise_level_get, msm_routing_aanc_noise_level_put) +}; + static int msm_routing_get_stereo_to_custom_stereo_control( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -20567,6 +20596,9 @@ static int msm_routing_probe(struct snd_soc_platform *platform) snd_soc_add_platform_controls(platform, aanc_slim_0_rx_mux, ARRAY_SIZE(aanc_slim_0_rx_mux)); + snd_soc_add_platform_controls(platform, aanc_noise_level, + ARRAY_SIZE(aanc_noise_level)); + snd_soc_add_platform_controls(platform, msm_voc_session_controls, ARRAY_SIZE(msm_voc_session_controls)); -- GitLab From d5d1092c0cfdb3835642aac51f18ee798ac2e2db Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 30 Nov 2017 17:55:05 +0800 Subject: [PATCH 0374/1645] ASOC: dsp: add spin_lock for q6asm_add_hdr During SSR, ac could get freed after unlock the session lock during the execution of q6asm_callback. If we try to get the ac->cmd_lock after ac freed, kernel panic happens. Remove mutex_lock in reset_event to avoid kernel panic. Add spin_lock_irqsave in q6asm_add_hdr and change spin_lock to spin_lock_irqsave in q6asm_callback to add synchronize between q6asm_add_hdr and q6asm_callback to avoid kernel panic. Change-Id: I72cf959fe6a764920a13d565c72243a80ac4f236 Signed-off-by: Meng Wang --- dsp/q6asm.c | 84 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 31 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 0569d1572bec..e60497682e96 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -575,11 +575,12 @@ static bool q6asm_is_valid_audio_client(struct audio_client *ac) static void q6asm_session_free(struct audio_client *ac) { int session_id; + unsigned long flags = 0; pr_debug("%s: sessionid[%d]\n", __func__, ac->session); session_id = ac->session; rtac_remove_popp_from_adm_devices(ac->session); - spin_lock_bh(&(session[session_id].session_lock)); + spin_lock_irqsave(&(session[session_id].session_lock), flags); session[ac->session].ac = NULL; ac->session = 0; ac->perf_mode = LEGACY_PCM_MODE; @@ -588,7 +589,7 @@ static void q6asm_session_free(struct audio_client *ac) ac->priv = NULL; kfree(ac); ac = NULL; - spin_unlock_bh(&(session[session_id].session_lock)); + spin_unlock_irqrestore(&(session[session_id].session_lock), flags); } static uint32_t q6asm_get_next_buf(struct audio_client *ac, @@ -1607,6 +1608,7 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) uint32_t i = IN; uint32_t *payload; unsigned long dsp_flags; + unsigned long flags = 0; struct asm_buffer_node *buf_node = NULL; struct list_head *ptr, *next; union asm_token_struct asm_token; @@ -1660,7 +1662,7 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) session_id = asm_token._token.session_id; if ((session_id > 0 && session_id <= ASM_ACTIVE_STREAMS_ALLOWED)) - spin_lock(&(session[session_id].session_lock)); + spin_lock_irqsave(&(session[session_id].session_lock), flags); ac = q6asm_get_audio_client(session_id); dir = q6asm_get_flag_from_token(&asm_token, ASM_DIRECTION_OFFSET); @@ -1670,7 +1672,8 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) __func__, session_id); if ((session_id > 0 && session_id <= ASM_ACTIVE_STREAMS_ALLOWED)) - spin_unlock(&(session[session_id].session_lock)); + spin_unlock_irqrestore( + &(session[session_id].session_lock), flags); return 0; } @@ -1723,7 +1726,8 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) } if ((session_id > 0 && session_id <= ASM_ACTIVE_STREAMS_ALLOWED)) - spin_unlock(&(session[session_id].session_lock)); + spin_unlock_irqrestore( + &(session[session_id].session_lock), flags); return 0; } @@ -1759,7 +1763,8 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) ac->cb(data->opcode, data->token, data->payload, ac->priv); if ((session_id > 0 && session_id <= ASM_ACTIVE_STREAMS_ALLOWED)) - spin_unlock(&(session[session_id].session_lock)); + spin_unlock_irqrestore( + &(session[session_id].session_lock), flags); return 0; } @@ -1827,7 +1832,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) uint8_t buf_index; struct msm_adsp_event_data *pp_event_package = NULL; uint32_t payload_size = 0; - + unsigned long flags = 0; int session_id; if (ac == NULL) { @@ -1845,12 +1850,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) session_id); return -EINVAL; } - spin_lock(&(session[session_id].session_lock)); + spin_lock_irqsave(&(session[session_id].session_lock), flags); if (!q6asm_is_valid_audio_client(ac)) { pr_err("%s: audio client pointer is invalid, ac = %pK\n", __func__, ac); - spin_unlock(&(session[session_id].session_lock)); + spin_unlock_irqrestore( + &(session[session_id].session_lock), flags); return -EINVAL; } @@ -1863,9 +1869,6 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) } if (data->opcode == RESET_EVENTS) { - spin_unlock(&(session[session_id].session_lock)); - mutex_lock(&ac->cmd_lock); - spin_lock(&(session[session_id].session_lock)); atomic_set(&ac->reset, 1); if (ac->apr == NULL) { ac->apr = ac->apr2; @@ -1886,8 +1889,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) wake_up(&ac->time_wait); wake_up(&ac->cmd_wait); wake_up(&ac->mem_wait); - spin_unlock(&(session[session_id].session_lock)); - mutex_unlock(&ac->cmd_lock); + spin_unlock_irqrestore( + &(session[session_id].session_lock), flags); return 0; } @@ -1901,7 +1904,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) (data->opcode != ASM_SESSION_EVENT_RX_UNDERFLOW)) { if (payload == NULL) { pr_err("%s: payload is null\n", __func__); - spin_unlock(&(session[session_id].session_lock)); + spin_unlock_irqrestore( + &(session[session_id].session_lock), flags); return -EINVAL; } dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x] opcode 0x%x\n", @@ -1928,7 +1932,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) ret = q6asm_is_valid_session(data, priv); if (ret != 0) { pr_err("%s: session invalid %d\n", __func__, ret); - spin_unlock(&(session[session_id].session_lock)); + spin_unlock_irqrestore( + &(session[session_id].session_lock), flags); return ret; } case ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2: @@ -1971,8 +1976,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) payload[1]); wake_up(&ac->cmd_wait); } - spin_unlock( - &(session[session_id].session_lock)); + spin_unlock_irqrestore( + &(session[session_id].session_lock), + flags); return 0; } if ((is_adsp_reg_event(payload[0]) >= 0) || @@ -2004,8 +2010,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) atomic_set(&ac->mem_state, payload[1]); wake_up(&ac->mem_wait); } - spin_unlock( - &(session[session_id].session_lock)); + spin_unlock_irqrestore( + &(session[session_id].session_lock), + flags); return 0; } if (atomic_read(&ac->mem_state) && wakeup_flag) { @@ -2054,7 +2061,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) break; } - spin_unlock(&(session[session_id].session_lock)); + spin_unlock_irqrestore( + &(session[session_id].session_lock), flags); return 0; } @@ -2069,8 +2077,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) if (port->buf == NULL) { pr_err("%s: Unexpected Write Done\n", __func__); - spin_unlock( - &(session[session_id].session_lock)); + spin_unlock_irqrestore( + &(session[session_id].session_lock), + flags); return -EINVAL; } spin_lock_irqsave(&port->dsp_lock, dsp_flags); @@ -2085,8 +2094,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) __func__, payload[0], payload[1]); spin_unlock_irqrestore(&port->dsp_lock, dsp_flags); - spin_unlock( - &(session[session_id].session_lock)); + spin_unlock_irqrestore( + &(session[session_id].session_lock), + flags); return -EINVAL; } port->buf[buf_index].used = 1; @@ -2157,8 +2167,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) if (ac->io_mode & SYNC_IO_MODE) { if (port->buf == NULL) { pr_err("%s: Unexpected Write Done\n", __func__); - spin_unlock( - &(session[session_id].session_lock)); + spin_unlock_irqrestore( + &(session[session_id].session_lock), + flags); return -EINVAL; } spin_lock_irqsave(&port->dsp_lock, dsp_flags); @@ -2234,7 +2245,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) __func__, payload[0], payload[1]); i = is_adsp_raise_event(data->opcode); if (i < 0) { - spin_unlock(&(session[session_id].session_lock)); + spin_unlock_irqrestore( + &(session[session_id].session_lock), flags); return 0; } @@ -2253,7 +2265,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) + sizeof(struct msm_adsp_event_data), GFP_ATOMIC); if (!pp_event_package) { - spin_unlock(&(session[session_id].session_lock)); + spin_unlock_irqrestore( + &(session[session_id].session_lock), flags); return -ENOMEM; } @@ -2264,7 +2277,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) ac->cb(data->opcode, data->token, (void *)pp_event_package, ac->priv); kfree(pp_event_package); - spin_unlock(&(session[session_id].session_lock)); + spin_unlock_irqrestore( + &(session[session_id].session_lock), flags); return 0; case ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2: pr_debug("%s: ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2 sesion %d status 0x%x msw %u lsw %u\n", @@ -2290,7 +2304,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) if (ac->cb) ac->cb(data->opcode, data->token, data->payload, ac->priv); - spin_unlock(&(session[session_id].session_lock)); + spin_unlock_irqrestore( + &(session[session_id].session_lock), flags); return 0; } @@ -2506,11 +2521,16 @@ int q6asm_is_dsp_buf_avail(int dir, struct audio_client *ac) static void __q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr, uint32_t pkt_size, uint32_t cmd_flg, uint32_t stream_id) { + unsigned long flags = 0; + dev_vdbg(ac->dev, "%s: pkt_size=%d cmd_flg=%d session=%d stream_id=%d\n", __func__, pkt_size, cmd_flg, ac->session, stream_id); mutex_lock(&ac->cmd_lock); + spin_lock_irqsave(&(session[ac->session].session_lock), flags); if (ac->apr == NULL) { pr_err("%s: AC APR handle NULL", __func__); + spin_unlock_irqrestore( + &(session[ac->session].session_lock), flags); mutex_unlock(&ac->cmd_lock); return; } @@ -2533,6 +2553,8 @@ static void __q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr, WAIT_CMD); hdr->pkt_size = pkt_size; + spin_unlock_irqrestore( + &(session[ac->session].session_lock), flags); mutex_unlock(&ac->cmd_lock); } -- GitLab From 9836489e2384f1884d6498a13c2312d92325637f Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Fri, 23 Mar 2018 14:20:47 +0800 Subject: [PATCH 0375/1645] asoc: wcd-dsp-mgr: clear work queue for wcd dsp manager wdsp_mgr_bind would schedule work to load wdsp firmware. Before loading wdsp firmware, sound card registeration may fail. wcd_dsp_cntl_deinit would get called to free cntl which would be used in wdsp_load_fw_image which would cause kernel panic. Clear work queue in wdsp_mgr_unbind to avoid kernel panic. Change-Id: I6c052fa8ea1ff62a8b075ba191085612242a5005 Signed-off-by: Meng Wang --- asoc/codecs/wcd-dsp-mgr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/codecs/wcd-dsp-mgr.c b/asoc/codecs/wcd-dsp-mgr.c index 9e65deb473b1..e48daa4dcfe8 100644 --- a/asoc/codecs/wcd-dsp-mgr.c +++ b/asoc/codecs/wcd-dsp-mgr.c @@ -1091,6 +1091,8 @@ static void wdsp_mgr_unbind(struct device *dev) struct wdsp_cmpnt *cmpnt; int idx; + cancel_work_sync(&wdsp->load_fw_work); + component_unbind_all(dev, wdsp->ops); wdsp_mgr_debugfs_remove(wdsp); -- GitLab From d1942a26d8db64b9a3c88946d223352e5f169175 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 27 Feb 2018 11:16:32 +0800 Subject: [PATCH 0376/1645] dsp: add null check for temp handle Variable mem_state in audio client(ac) is set to zero when there is a successful memory mapping. However the same variable is updated for various mapping commands. Ensure to check for both memstate and specific mem_handle to be updated in the wait condition to wake up the right waiting command. Change-Id: Iabba61cef0a90f636de50e9d27eecf886dc59a27 Signed-off-by: Meng Wang --- dsp/q6asm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 0569d1572bec..3098152d9898 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -7503,8 +7503,8 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, } rc = wait_event_timeout(ac->mem_wait, - (atomic_read(&ac->mem_state) >= 0) - , 5*HZ); + (atomic_read(&ac->mem_state) >= 0 && + ac->port[dir].tmp_hdl), 5*HZ); if (!rc) { pr_err("%s: timeout. waited for memory_map\n", __func__); rc = -ETIMEDOUT; -- GitLab From f1f4a2982ff5c51032f4d54e43db184fd6be50d5 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Mon, 2 Jul 2018 18:26:08 -0700 Subject: [PATCH 0377/1645] include: dsp: avoid returning error code from stubbed function If MSM_QDSP6_NOTIFIER is not enabled for a target, audio_notifier feature will not be available for that target. Whenever a call is made to audio_notifier when its not supported, returning error from stubbed function may confuse the error with real failure (even though the feature is not enabled on the target). Avoid returning error code from stubbed function, when feature is disabled. Change-Id: I37eb2e25e45b25948aff55f2a231195a22b16f05 Signed-off-by: Banajit Goswami --- include/dsp/audio_notifier.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dsp/audio_notifier.h b/include/dsp/audio_notifier.h index c7794ac602de..7eda2c35c2d0 100644 --- a/include/dsp/audio_notifier.h +++ b/include/dsp/audio_notifier.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -92,7 +92,7 @@ int audio_notifier_deregister(char *client_name); static inline int audio_notifier_register(char *client_name, int domain, struct notifier_block *nb) { - return -ENODEV; + return 0; } static inline int audio_notifier_deregister(char *client_name) -- GitLab From 96ba1625dc19651e85184509fe45b9b65f9fa119 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 4 Jan 2018 13:49:12 -0800 Subject: [PATCH 0378/1645] dsp: Avoid excessive list iterations Exit list iteration after the required conditions for the loop has been satisfied to avoid additional list iteration. Change-Id: I96872d3be469420e613ec0244588a0a8ecb50e58 Signed-off-by: Vignesh Kulothungan --- dsp/q6asm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 0569d1572bec..38f34a73f9d5 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -8284,8 +8284,10 @@ static int __q6asm_read(struct audio_client *ac, bool is_custom_len_reqd, list_for_each_safe(ptr, next, &ac->port[OUT].mem_map_handle) { buf_node = list_entry(ptr, struct asm_buffer_node, list); - if (buf_node->buf_phys_addr == ab->phys) + if (buf_node->buf_phys_addr == ab->phys) { read.mem_map_handle = buf_node->mmap_hdl; + break; + } } dev_vdbg(ac->dev, "memory_map handle in q6asm_read: [%0x]:", read.mem_map_handle); -- GitLab From 82f6168cf58928fdbfad783017a11493866aa825 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Thu, 17 May 2018 18:47:47 +0530 Subject: [PATCH 0379/1645] asoc: codecs: codec driver support for CSRA66X0 Codec driver to support direct digital feedback amplifier (DDFA) CSRA66X0 CRs-Fixed: 2248380 Change-Id: I0aa1b5a2b6e18b6d2dcd5393a10b7d4aebb570e5 Signed-off-by: Mangesh Kunchamwar --- asoc/codecs/csra66x0/Kbuild | 105 +++++ asoc/codecs/csra66x0/csra66x0.c | 767 ++++++++++++++++++++++++++++++++ asoc/codecs/csra66x0/csra66x0.h | 230 ++++++++++ 3 files changed, 1102 insertions(+) create mode 100644 asoc/codecs/csra66x0/Kbuild create mode 100644 asoc/codecs/csra66x0/csra66x0.c create mode 100644 asoc/codecs/csra66x0/csra66x0.h diff --git a/asoc/codecs/csra66x0/Kbuild b/asoc/codecs/csra66x0/Kbuild new file mode 100644 index 000000000000..c23811c23a65 --- /dev/null +++ b/asoc/codecs/csra66x0/Kbuild @@ -0,0 +1,105 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + + +ifeq ($(KERNEL_BUILD), 1) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) + ifeq ($(CONFIG_ARCH_QCS405), y) + include $(AUDIO_ROOT)/config/qcs405auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h + endif +endif + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ CSRA66X0 ############ + +# for CSRA66X0 Codec +ifdef CONFIG_SND_SOC_CSRA66X0 + CSRA66X0_OBJS += csra66x0.o +endif + +LINUX_INC += -Iinclude/linux + +INCS += $(COMMON_INC) \ + $(UAPI_INC) + +#EXTRA_CFLAGS += $(INCS) +ccflags-y += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +#EXTRA_CFLAGS += -Wmaybe-uninitialized +ccflags-y += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +#EXTRA_CFLAGS += -Wheader-guard +ccflags-y += -Wheader-guard +endif + +ifeq ($(KERNEL_BUILD), 0) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_CSRA66X0) += csra66x0_dlkm.o +csra66x0_dlkm-y := $(CSRA66X0_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/csra66x0/csra66x0.c b/asoc/codecs/csra66x0/csra66x0.c new file mode 100644 index 000000000000..e9e11cb3872f --- /dev/null +++ b/asoc/codecs/csra66x0/csra66x0.c @@ -0,0 +1,767 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "csra66x0.h" + +/* CSRA66X0 register default values */ +static struct reg_default csra66x0_reg_defaults[] = { + {CSRA66X0_AUDIO_IF_RX_CONFIG1, 0x00}, + {CSRA66X0_AUDIO_IF_RX_CONFIG2, 0x0B}, + {CSRA66X0_AUDIO_IF_RX_CONFIG3, 0x0F}, + {CSRA66X0_AUDIO_IF_TX_EN, 0x00}, + {CSRA66X0_AUDIO_IF_TX_CONFIG1, 0x6B}, + {CSRA66X0_AUDIO_IF_TX_CONFIG2, 0x02}, + {CSRA66X0_I2C_DEVICE_ADDRESS, 0x0D}, + {CSRA66X0_CHIP_ID_FA, 0x39}, + {CSRA66X0_ROM_VER_FA, 0x08}, + {CSRA66X0_CHIP_REV_0_FA, 0x05}, + {CSRA66X0_CHIP_REV_1_FA, 0x03}, + {CSRA66X0_CH1_MIX_SEL, 0x01}, + {CSRA66X0_CH2_MIX_SEL, 0x10}, + {CSRA66X0_CH1_SAMPLE1_SCALE_0, 0x00}, + {CSRA66X0_CH1_SAMPLE1_SCALE_1, 0x20}, + {CSRA66X0_CH1_SAMPLE3_SCALE_0, 0x00}, + {CSRA66X0_CH1_SAMPLE3_SCALE_1, 0x20}, + {CSRA66X0_CH1_SAMPLE5_SCALE_0, 0x00}, + {CSRA66X0_CH1_SAMPLE5_SCALE_1, 0x20}, + {CSRA66X0_CH1_SAMPLE7_SCALE_0, 0x00}, + {CSRA66X0_CH1_SAMPLE7_SCALE_1, 0x20}, + {CSRA66X0_CH1_SAMPLE2_SCALE_0, 0x00}, + {CSRA66X0_CH1_SAMPLE2_SCALE_1, 0x20}, + {CSRA66X0_CH1_SAMPLE4_SCALE_0, 0x00}, + {CSRA66X0_CH1_SAMPLE4_SCALE_1, 0x20}, + {CSRA66X0_CH1_SAMPLE6_SCALE_0, 0x00}, + {CSRA66X0_CH1_SAMPLE6_SCALE_1, 0x20}, + {CSRA66X0_CH1_SAMPLE8_SCALE_0, 0x00}, + {CSRA66X0_CH1_SAMPLE8_SCALE_1, 0x20}, + {CSRA66X0_CH2_SAMPLE1_SCALE_0, 0x00}, + {CSRA66X0_CH2_SAMPLE1_SCALE_1, 0x20}, + {CSRA66X0_CH2_SAMPLE3_SCALE_0, 0x00}, + {CSRA66X0_CH2_SAMPLE3_SCALE_1, 0x20}, + {CSRA66X0_CH2_SAMPLE5_SCALE_0, 0x00}, + {CSRA66X0_CH2_SAMPLE5_SCALE_1, 0x20}, + {CSRA66X0_CH2_SAMPLE7_SCALE_0, 0x00}, + {CSRA66X0_CH2_SAMPLE7_SCALE_1, 0x20}, + {CSRA66X0_CH2_SAMPLE2_SCALE_0, 0x00}, + {CSRA66X0_CH2_SAMPLE2_SCALE_1, 0x20}, + {CSRA66X0_CH2_SAMPLE4_SCALE_0, 0x00}, + {CSRA66X0_CH2_SAMPLE4_SCALE_1, 0x20}, + {CSRA66X0_CH2_SAMPLE6_SCALE_0, 0x00}, + {CSRA66X0_CH2_SAMPLE6_SCALE_1, 0x20}, + {CSRA66X0_CH2_SAMPLE8_SCALE_0, 0x00}, + {CSRA66X0_CH2_SAMPLE8_SCALE_1, 0x20}, + {CSRA66X0_VOLUME_CONFIG_FA, 0x26}, + {CSRA66X0_STARTUP_DELAY_FA, 0x00}, + {CSRA66X0_CH1_VOLUME_0_FA, 0x19}, + {CSRA66X0_CH1_VOLUME_1_FA, 0x01}, + {CSRA66X0_CH2_VOLUME_0_FA, 0x19}, + {CSRA66X0_CH2_VOLUME_1_FA, 0x01}, + {CSRA66X0_QUAD_ENC_COUNT_0_FA, 0x00}, + {CSRA66X0_QUAD_ENC_COUNT_1_FA, 0x00}, + {CSRA66X0_SOFT_CLIP_CONFIG, 0x00}, + {CSRA66X0_CH1_HARD_CLIP_THRESH, 0x00}, + {CSRA66X0_CH2_HARD_CLIP_THRESH, 0x00}, + {CSRA66X0_SOFT_CLIP_THRESH, 0x00}, + {CSRA66X0_DS_ENABLE_THRESH_0, 0x05}, + {CSRA66X0_DS_ENABLE_THRESH_1, 0x00}, + {CSRA66X0_DS_TARGET_COUNT_0, 0x00}, + {CSRA66X0_DS_TARGET_COUNT_1, 0xFF}, + {CSRA66X0_DS_TARGET_COUNT_2, 0xFF}, + {CSRA66X0_DS_DISABLE_THRESH_0, 0x0F}, + {CSRA66X0_DS_DISABLE_THRESH_1, 0x00}, + {CSRA66X0_DCA_CTRL, 0x07}, + {CSRA66X0_CH1_DCA_THRESH, 0x40}, + {CSRA66X0_CH2_DCA_THRESH, 0x40}, + {CSRA66X0_DCA_ATTACK_RATE, 0x00}, + {CSRA66X0_DCA_RELEASE_RATE, 0x00}, + {CSRA66X0_CH1_OUTPUT_INVERT_EN, 0x00}, + {CSRA66X0_CH2_OUTPUT_INVERT_EN, 0x00}, + {CSRA66X0_CH1_176P4K_DELAY, 0x00}, + {CSRA66X0_CH2_176P4K_DELAY, 0x00}, + {CSRA66X0_CH1_192K_DELAY, 0x00}, + {CSRA66X0_CH2_192K_DELAY, 0x00}, + {CSRA66X0_DEEMP_CONFIG_FA, 0x00}, + {CSRA66X0_CH1_TREBLE_GAIN_CTRL_FA, 0x00}, + {CSRA66X0_CH2_TREBLE_GAIN_CTRL_FA, 0x00}, + {CSRA66X0_CH1_TREBLE_FC_CTRL_FA, 0x00}, + {CSRA66X0_CH2_TREBLE_FC_CTRL_FA, 0x00}, + {CSRA66X0_CH1_BASS_GAIN_CTRL_FA, 0x00}, + {CSRA66X0_CH2_BASS_GAIN_CTRL_FA, 0x00}, + {CSRA66X0_CH1_BASS_FC_CTRL_FA, 0x00}, + {CSRA66X0_CH2_BASS_FC_CTRL_FA, 0x00}, + {CSRA66X0_FILTER_SEL_8K, 0x00}, + {CSRA66X0_FILTER_SEL_11P025K, 0x00}, + {CSRA66X0_FILTER_SEL_16K, 0x00}, + {CSRA66X0_FILTER_SEL_22P05K, 0x00}, + {CSRA66X0_FILTER_SEL_32K, 0x00}, + {CSRA66X0_FILTER_SEL_44P1K_48K, 0x00}, + {CSRA66X0_FILTER_SEL_88P2K_96K, 0x00}, + {CSRA66X0_FILTER_SEL_176P4K_192K, 0x00}, + /* RESERVED */ + {CSRA66X0_USER_DSP_CTRL, 0x00}, + {CSRA66X0_TEST_TONE_CTRL, 0x00}, + {CSRA66X0_TEST_TONE_FREQ_0, 0x00}, + {CSRA66X0_TEST_TONE_FREQ_1, 0x00}, + {CSRA66X0_TEST_TONE_FREQ_2, 0x00}, + {CSRA66X0_AUDIO_RATE_CTRL_FA, 0x08}, + {CSRA66X0_MODULATION_INDEX_CTRL, 0x3F}, + {CSRA66X0_MODULATION_INDEX_COUNT, 0x10}, + {CSRA66X0_MIN_MODULATION_PULSE_WIDTH, 0x7A}, + {CSRA66X0_DEAD_TIME_CTRL, 0x00}, + {CSRA66X0_DEAD_TIME_THRESHOLD_0, 0xE7}, + {CSRA66X0_DEAD_TIME_THRESHOLD_1, 0x26}, + {CSRA66X0_DEAD_TIME_THRESHOLD_2, 0x40}, + {CSRA66X0_CH1_LOW_SIDE_DLY, 0x00}, + {CSRA66X0_CH2_LOW_SIDE_DLY, 0x00}, + {CSRA66X0_SPECTRUM_CTRL, 0x00}, + /* RESERVED */ + {CSRA66X0_SPECTRUM_SPREAD_CTRL, 0x0C}, + /* RESERVED */ + {CSRA66X0_EXT_PA_PROTECT_POLARITY, 0x03}, + {CSRA66X0_TEMP0_BACKOFF_COMP_VALUE, 0x98}, + {CSRA66X0_TEMP0_SHUTDOWN_COMP_VALUE, 0xA3}, + {CSRA66X0_TEMP1_BACKOFF_COMP_VALUE, 0x98}, + {CSRA66X0_TEMP1_SHUTDOWN_COMP_VALUE, 0xA3}, + {CSRA66X0_TEMP_PROT_BACKOFF, 0x00}, + {CSRA66X0_TEMP_READ0_FA, 0x00}, + {CSRA66X0_TEMP_READ1_FA, 0x00}, + {CSRA66X0_CHIP_STATE_CTRL_FA, 0x02}, + /* RESERVED */ + {CSRA66X0_PWM_OUTPUT_CONFIG, 0x00}, + {CSRA66X0_MISC_CONTROL_STATUS_0, 0x08}, + {CSRA66X0_MISC_CONTROL_STATUS_1_FA, 0x40}, + {CSRA66X0_PIO0_SELECT, 0x00}, + {CSRA66X0_PIO1_SELECT, 0x00}, + {CSRA66X0_PIO2_SELECT, 0x00}, + {CSRA66X0_PIO3_SELECT, 0x00}, + {CSRA66X0_PIO4_SELECT, 0x00}, + {CSRA66X0_PIO5_SELECT, 0x00}, + {CSRA66X0_PIO6_SELECT, 0x00}, + {CSRA66X0_PIO7_SELECT, 0x00}, + {CSRA66X0_PIO8_SELECT, 0x00}, + {CSRA66X0_PIO_DIRN0, 0xFF}, + {CSRA66X0_PIO_DIRN1, 0x01}, + {CSRA66X0_PIO_PULL_EN0, 0xFF}, + {CSRA66X0_PIO_PULL_EN1, 0x01}, + {CSRA66X0_PIO_PULL_DIR0, 0x00}, + {CSRA66X0_PIO_PULL_DIR1, 0x00}, + {CSRA66X0_PIO_DRIVE_OUT0_FA, 0x00}, + {CSRA66X0_PIO_DRIVE_OUT1_FA, 0x00}, + {CSRA66X0_PIO_STATUS_IN0_FA, 0x00}, + {CSRA66X0_PIO_STATUS_IN1_FA, 0x00}, + /* RESERVED */ + {CSRA66X0_IRQ_OUTPUT_ENABLE, 0x00}, + {CSRA66X0_IRQ_OUTPUT_POLARITY, 0x01}, + {CSRA66X0_IRQ_OUTPUT_STATUS_FA, 0x00}, + {CSRA66X0_CLIP_DCA_STATUS_FA, 0x00}, + {CSRA66X0_CHIP_STATE_STATUS_FA, 0x02}, + {CSRA66X0_FAULT_STATUS_FA, 0x00}, + {CSRA66X0_OTP_STATUS_FA, 0x00}, + {CSRA66X0_AUDIO_IF_STATUS_FA, 0x00}, + /* RESERVED */ + {CSRA66X0_DSP_SATURATION_STATUS_FA, 0x00}, + {CSRA66X0_AUDIO_RATE_STATUS_FA, 0x00}, + /* RESERVED */ + {CSRA66X0_DISABLE_PWM_OUTPUT, 0x00}, + /* RESERVED */ + {CSRA66X0_OTP_VER_FA, 0x03}, + {CSRA66X0_RAM_VER_FA, 0x02}, + /* RESERVED */ + {CSRA66X0_AUDIO_SATURATION_FLAGS_FA, 0x00}, + {CSRA66X0_DCOFFSET_CHAN_1_01_FA, 0x00}, + {CSRA66X0_DCOFFSET_CHAN_1_02_FA, 0x00}, + {CSRA66X0_DCOFFSET_CHAN_1_03_FA, 0x00}, + {CSRA66X0_DCOFFSET_CHAN_2_01_FA, 0x00}, + {CSRA66X0_DCOFFSET_CHAN_2_02_FA, 0x00}, + {CSRA66X0_DCOFFSET_CHAN_2_03_FA, 0x00}, + {CSRA66X0_FORCED_PA_SWITCHING_CTRL, 0x90}, + {CSRA66X0_PA_FORCE_PULSE_WIDTH, 0x07}, + {CSRA66X0_PA_HIGH_MODULATION_CTRL_CH1, 0x00}, + /* RESERVED */ + {CSRA66X0_HIGH_MODULATION_THRESHOLD_LOW, 0xD4}, + {CSRA66X0_HIGH_MODULATION_THRESHOLD_HIGH, 0x78}, + /* RESERVED */ + {CSRA66X0_PA_FREEZE_CTRL, 0x00}, + {CSRA66X0_DCA_FREEZE_CTRL, 0x3C}, + /* RESERVED */ +}; + +static bool csra66x0_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CSRA66X0_CHIP_ID_FA: + case CSRA66X0_TEMP_READ0_FA: + case CSRA66X0_TEMP_READ1_FA: + case CSRA66X0_MISC_CONTROL_STATUS_1_FA: + case CSRA66X0_IRQ_OUTPUT_STATUS_FA: + case CSRA66X0_CLIP_DCA_STATUS_FA: + case CSRA66X0_CHIP_STATE_STATUS_FA: + case CSRA66X0_FAULT_STATUS_FA: + case CSRA66X0_OTP_STATUS_FA: + case CSRA66X0_AUDIO_IF_STATUS_FA: + case CSRA66X0_DSP_SATURATION_STATUS_FA: + case CSRA66X0_AUDIO_RATE_STATUS_FA: + return true; + default: + return false; + } +} + +static bool csra66x0_writeable_registers(struct device *dev, unsigned int reg) +{ + if ((reg >= CSRA66X0_AUDIO_IF_RX_CONFIG1) + && (reg <= CSRA66X0_MAX_REGISTER_ADDR)) + return true; + + return false; +} + +static bool csra66x0_readable_registers(struct device *dev, unsigned int reg) +{ + if ((reg >= CSRA66X0_AUDIO_IF_RX_CONFIG1) + && (reg <= CSRA66X0_MAX_REGISTER_ADDR)) + return true; + + return false; +} + +/* codec private data */ +struct csra66x0_priv { + struct regmap *regmap; + struct snd_soc_codec *codec; + int spk_volume_ch1; + int spk_volume_ch2; + int irq; + int vreg_gpio; + u32 irq_active_low; + u32 in_cluster; + u32 is_master; +}; + +/* + * CSRA66X0 Controls + */ +static const DECLARE_TLV_DB_SCALE(csra66x0_volume_tlv, -9000, 25, 0); +static const DECLARE_TLV_DB_RANGE(csra66x0_bass_treble_tlv, + 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), + 1, 15, TLV_DB_SCALE_ITEM(-1500, 100, 0), + 16, 30, TLV_DB_SCALE_ITEM(100, 100, 0) +); + +static int csra66x0_get_volume(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + unsigned int reg_l = mc->reg; + unsigned int reg_r = mc->rreg; + unsigned int val_l, val_r; + + val_l = (snd_soc_read(codec, reg_l) & 0xff) | + ((snd_soc_read(codec, + CSRA66X0_CH1_VOLUME_1_FA) & (0x01)) << 8); + val_r = (snd_soc_read(codec, reg_r) & 0xff) | + ((snd_soc_read(codec, + CSRA66X0_CH2_VOLUME_1_FA) & (0x01)) << 8); + ucontrol->value.integer.value[0] = val_l; + ucontrol->value.integer.value[1] = val_r; + return 0; +} + +static int csra66x0_set_volume(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct csra66x0_priv *csra66x0 = snd_soc_codec_get_drvdata(codec); + unsigned int reg_l = mc->reg; + unsigned int reg_r = mc->rreg; + unsigned int val_l[2]; + unsigned int val_r[2]; + + csra66x0->spk_volume_ch1 = (ucontrol->value.integer.value[0]); + csra66x0->spk_volume_ch2 = (ucontrol->value.integer.value[1]); + val_l[0] = csra66x0->spk_volume_ch1 & SPK_VOLUME_LSB_MSK; + val_l[1] = (csra66x0->spk_volume_ch1 & SPK_VOLUME_MSB_MSK) ? 1 : 0; + val_r[0] = csra66x0->spk_volume_ch2 & SPK_VOLUME_LSB_MSK; + val_r[1] = (csra66x0->spk_volume_ch2 & SPK_VOLUME_MSB_MSK) ? 1 : 0; + snd_soc_write(codec, reg_l, val_l[0]); + snd_soc_write(codec, reg_r, val_r[0]); + snd_soc_write(codec, CSRA66X0_CH1_VOLUME_1_FA, val_l[1]); + snd_soc_write(codec, CSRA66X0_CH2_VOLUME_1_FA, val_r[1]); + return 0; +} + +/* enumerated controls */ +static const char * const csra66x0_mute_output_text[] = {"PLAY", "MUTE"}; +static const char * const csra66x0_output_invert_text[] = { + "UNCHANGED", "INVERTED"}; +static const char * const csra66x0_deemp_config_text[] = { + "DISABLED", "ENABLED"}; + +SOC_ENUM_SINGLE_DECL(csra66x0_mute_output_enum, + CSRA66X0_MISC_CONTROL_STATUS_1_FA, 2, + csra66x0_mute_output_text); +SOC_ENUM_SINGLE_DECL(csra66x0_ch1_output_invert_enum, + CSRA66X0_CH1_OUTPUT_INVERT_EN, 0, + csra66x0_output_invert_text); +SOC_ENUM_SINGLE_DECL(csra66x0_ch2_output_invert_enum, + CSRA66X0_CH2_OUTPUT_INVERT_EN, 0, + csra66x0_output_invert_text); +SOC_ENUM_DOUBLE_DECL(csra66x0_deemp_config_enum, + CSRA66X0_DEEMP_CONFIG_FA, 0, 1, + csra66x0_deemp_config_text); + +static const struct snd_kcontrol_new csra66x0_snd_controls[] = { + /* volume */ + SOC_DOUBLE_R_EXT_TLV("PA VOLUME", CSRA66X0_CH1_VOLUME_0_FA, + CSRA66X0_CH2_VOLUME_0_FA, 0, 0x1C9, 0, + csra66x0_get_volume, csra66x0_set_volume, + csra66x0_volume_tlv), + + /* bass treble */ + SOC_DOUBLE_R_TLV("PA BASS GAIN", CSRA66X0_CH1_BASS_GAIN_CTRL_FA, + CSRA66X0_CH2_BASS_GAIN_CTRL_FA, 0, 0x1E, 0, + csra66x0_bass_treble_tlv), + SOC_DOUBLE_R_TLV("PA TREBLE GAIN", CSRA66X0_CH1_TREBLE_GAIN_CTRL_FA, + CSRA66X0_CH2_TREBLE_GAIN_CTRL_FA, 0, 0x1E, 0, + csra66x0_bass_treble_tlv), + SOC_DOUBLE_R("PA BASS_XOVER FREQ", CSRA66X0_CH1_BASS_FC_CTRL_FA, + CSRA66X0_CH2_BASS_FC_CTRL_FA, 0, 2, 0), + SOC_DOUBLE_R("PA TREBLE_XOVER FREQ", CSRA66X0_CH1_TREBLE_FC_CTRL_FA, + CSRA66X0_CH2_TREBLE_FC_CTRL_FA, 0, 2, 0), + + /* switch */ + SOC_ENUM("PA MUTE_OUTPUT SWITCH", csra66x0_mute_output_enum), + SOC_ENUM("PA DE-EMPHASIS SWITCH", csra66x0_deemp_config_enum), +}; + +static const struct snd_kcontrol_new csra_mix_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_soc_dapm_widget csra66x0_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("IN"), + SND_SOC_DAPM_MIXER("MIXER", SND_SOC_NOPM, 0, 0, + csra_mix_switch, ARRAY_SIZE(csra_mix_switch)), + SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_PGA("PGA", CSRA66X0_CHIP_STATE_CTRL_FA, 0, 0, NULL, 0), + SND_SOC_DAPM_OUTPUT("SPKR"), + + SND_SOC_DAPM_SUPPLY("POWER", CSRA66X0_CHIP_STATE_CTRL_FA, + 1, 1, NULL, 0), +}; + +static const struct snd_soc_dapm_route csra66x0_dapm_routes[] = { + {"MIXER", "Switch", "IN"}, + {"DAC", NULL, "MIXER"}, + {"PGA", NULL, "DAC"}, + {"SPKR", NULL, "PGA"}, + {"SPKR", NULL, "POWER"}, +}; + +static int csra66x0_init(struct snd_soc_codec *codec, + struct csra66x0_priv *csra66x0) +{ + /* config */ + snd_soc_write(codec, CSRA66X0_CHIP_STATE_CTRL_FA, CONFIG_STATE); + /* settle time in HW is min. 500ms before proceeding */ + msleep(500); + + /* setup */ + snd_soc_write(codec, CSRA66X0_MISC_CONTROL_STATUS_0, 0x09); + snd_soc_write(codec, CSRA66X0_TEMP_PROT_BACKOFF, 0x0C); + snd_soc_write(codec, CSRA66X0_EXT_PA_PROTECT_POLARITY, 0x03); + snd_soc_write(codec, CSRA66X0_PWM_OUTPUT_CONFIG, 0xC8); + csra66x0->spk_volume_ch1 = SPK_VOLUME_M20DB; + csra66x0->spk_volume_ch2 = SPK_VOLUME_M20DB; + snd_soc_write(codec, CSRA66X0_CH1_VOLUME_0_FA, SPK_VOLUME_M20DB_LSB); + snd_soc_write(codec, CSRA66X0_CH2_VOLUME_0_FA, SPK_VOLUME_M20DB_LSB); + snd_soc_write(codec, CSRA66X0_CH1_VOLUME_1_FA, SPK_VOLUME_M20DB_MSB); + snd_soc_write(codec, CSRA66X0_CH2_VOLUME_1_FA, SPK_VOLUME_M20DB_MSB); + + snd_soc_write(codec, CSRA66X0_DEAD_TIME_CTRL, 0x0); + snd_soc_write(codec, CSRA66X0_DEAD_TIME_THRESHOLD_0, 0xE7); + snd_soc_write(codec, CSRA66X0_DEAD_TIME_THRESHOLD_1, 0x26); + snd_soc_write(codec, CSRA66X0_DEAD_TIME_THRESHOLD_2, 0x40); + + snd_soc_write(codec, CSRA66X0_MIN_MODULATION_PULSE_WIDTH, 0x7A); + snd_soc_write(codec, CSRA66X0_CH1_HARD_CLIP_THRESH, 0x00); + snd_soc_write(codec, CSRA66X0_CH2_HARD_CLIP_THRESH, 0x00); + + snd_soc_write(codec, CSRA66X0_CH1_DCA_THRESH, 0x40); + snd_soc_write(codec, CSRA66X0_CH2_DCA_THRESH, 0x40); + snd_soc_write(codec, CSRA66X0_DCA_ATTACK_RATE, 0x00); + snd_soc_write(codec, CSRA66X0_DCA_RELEASE_RATE, 0x00); + + if (csra66x0->irq) { + snd_soc_write(codec, CSRA66X0_PIO0_SELECT, 0x1); + if (csra66x0->irq_active_low) + snd_soc_write(codec, CSRA66X0_IRQ_OUTPUT_POLARITY, 0x0); + else + snd_soc_write(codec, CSRA66X0_IRQ_OUTPUT_POLARITY, 0x1); + + snd_soc_write(codec, CSRA66X0_IRQ_OUTPUT_ENABLE, 0x01); + } else { + snd_soc_write(codec, CSRA66X0_IRQ_OUTPUT_ENABLE, 0x00); + } + /* settle time in HW is min. 500ms before slave initializing */ + msleep(500); + return 0; +} + +static int csra66x0_soc_probe(struct snd_soc_codec *codec) +{ + struct csra66x0_priv *csra66x0 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm; + char name[50]; + + if (csra66x0->in_cluster) { + dapm = snd_soc_codec_get_dapm(codec); + dev_dbg(codec->dev, "%s: setting %s to codec %s\n", + __func__, codec->component.name_prefix, + codec->component.name); + snd_soc_write(codec, CSRA66X0_CHIP_STATE_CTRL_FA, + CONFIG_STATE); + /* settle time in HW is min. 500ms before proceeding */ + msleep(500); + snd_soc_write(codec, CSRA66X0_PIO7_SELECT, 0x04); + snd_soc_write(codec, CSRA66X0_PIO8_SELECT, 0x04); + if (csra66x0->is_master) { + /* Master specific config */ + snd_soc_write(codec, CSRA66X0_PIO_PULL_EN0, 0xFF); + snd_soc_write(codec, CSRA66X0_PIO_PULL_DIR0, 0x80); + snd_soc_write(codec, CSRA66X0_PIO_PULL_EN1, 0x01); + snd_soc_write(codec, CSRA66X0_PIO_PULL_DIR1, 0x01); + } else { + /* Slave specific config */ + snd_soc_write(codec, CSRA66X0_PIO_PULL_EN0, 0x7F); + snd_soc_write(codec, CSRA66X0_PIO_PULL_EN1, 0x00); + } + snd_soc_write(codec, CSRA66X0_DCA_CTRL, 0x05); + if (dapm->component) { + strlcpy(name, dapm->component->name_prefix, + sizeof(name)); + strlcat(name, " IN", sizeof(name)); + snd_soc_dapm_ignore_suspend(dapm, name); + strlcpy(name, dapm->component->name_prefix, + sizeof(name)); + strlcat(name, " SPKR", sizeof(name)); + snd_soc_dapm_ignore_suspend(dapm, name); + } + } + + csra66x0->codec = codec; + + /* common configuration */ + csra66x0_init(codec, csra66x0); + return 0; +} + +static int csra66x0_soc_remove(struct snd_soc_codec *codec) +{ + snd_soc_write(codec, CSRA66X0_CHIP_STATE_CTRL_FA, STDBY_STATE); + return 0; +} + +static int csra66x0_soc_suspend(struct snd_soc_codec *codec) +{ + u16 state_reg = snd_soc_read(codec, CSRA66X0_CHIP_STATE_CTRL_FA) & 0xFC; + + snd_soc_write(codec, CSRA66X0_CHIP_STATE_CTRL_FA, state_reg | + STDBY_STATE); + return 0; +} + +static int csra66x0_soc_resume(struct snd_soc_codec *codec) +{ + u16 state_reg = snd_soc_read(codec, CSRA66X0_CHIP_STATE_CTRL_FA) & 0xFC; + + snd_soc_write(codec, CSRA66X0_CHIP_STATE_CTRL_FA, state_reg | + RUN_STATE); + return 0; +} + +static struct regmap *csra66x0_get_regmap(struct device *dev) +{ + struct csra66x0_priv *csra66x0_ctrl = dev_get_drvdata(dev); + + if (!csra66x0_ctrl) + return NULL; + return csra66x0_ctrl->regmap; +} + +static struct snd_soc_codec_driver soc_codec_drv_csra66x0 = { + .probe = csra66x0_soc_probe, + .remove = csra66x0_soc_remove, + .suspend = csra66x0_soc_suspend, + .resume = csra66x0_soc_resume, + .get_regmap = csra66x0_get_regmap, + .component_driver = { + .controls = csra66x0_snd_controls, + .num_controls = ARRAY_SIZE(csra66x0_snd_controls), + .dapm_widgets = csra66x0_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(csra66x0_dapm_widgets), + .dapm_routes = csra66x0_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(csra66x0_dapm_routes), + }, +}; + +static struct regmap_config csra66x0_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = csra66x0_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(csra66x0_reg_defaults), + .max_register = CSRA66X0_MAX_REGISTER_ADDR, + .volatile_reg = csra66x0_volatile_register, + .writeable_reg = csra66x0_writeable_registers, + .readable_reg = csra66x0_readable_registers, +}; + +static irqreturn_t csra66x0_irq(int irq, void *data) +{ + struct csra66x0_priv *csra66x0 = (struct csra66x0_priv *) data; + struct snd_soc_codec *codec = csra66x0->codec; + u16 val; + + /* Treat interrupt before codec is initialized as spurious */ + if (codec == NULL) + return IRQ_NONE; + + dev_dbg(codec->dev, "%s: csra66x0_interrupt\n", __func__); + + /* fault indication */ + val = snd_soc_read(codec, CSRA66X0_IRQ_OUTPUT_STATUS_FA) & 0x1; + if (val) { + val = snd_soc_read(codec, CSRA66X0_FAULT_STATUS_FA); + if (val & FAULT_STATUS_INTERNAL) + dev_dbg(codec->dev, "%s: FAULT_STATUS_INTERNAL 0x%X\n", + __func__, val); + if (val & FAULT_STATUS_OTP_INTEGRITY) + dev_dbg(codec->dev, "%s: FAULT_STATUS_OTP_INTEGRITY 0x%X\n", + __func__, val); + if (val & FAULT_STATUS_PADS2) + dev_dbg(codec->dev, "%s: FAULT_STATUS_PADS2 0x%X\n", + __func__, val); + if (val & FAULT_STATUS_SMPS) + dev_dbg(codec->dev, "%s: FAULT_STATUS_SMPS 0x%X\n", + __func__, val); + if (val & FAULT_STATUS_TEMP) + dev_dbg(codec->dev, "%s: FAULT_STATUS_TEMP 0x%X\n", + __func__, val); + if (val & FAULT_STATUS_PROTECT) + dev_dbg(codec->dev, "%s: FAULT_STATUS_PROTECT 0x%X\n", + __func__, val); + + /* clear fault state and re-init */ + snd_soc_write(codec, CSRA66X0_FAULT_STATUS_FA, 0x00); + csra66x0_init(codec, csra66x0); + } else { + return IRQ_NONE; + } + return IRQ_HANDLED; +}; + +static const struct of_device_id csra66x0_of_match[] = { + { .compatible = "qcom,csra66x0", }, + { } +}; +MODULE_DEVICE_TABLE(of, csra66x0_of_match); + +#if IS_ENABLED(CONFIG_I2C) +static int csra66x0_i2c_probe(struct i2c_client *client_i2c, + const struct i2c_device_id *id) +{ + struct csra66x0_priv *csra66x0; + int ret, irq_trigger; + + csra66x0 = devm_kzalloc(&client_i2c->dev, sizeof(struct csra66x0_priv), + GFP_KERNEL); + if (csra66x0 == NULL) + return -ENOMEM; + + csra66x0->regmap = devm_regmap_init_i2c(client_i2c, + &csra66x0_regmap_config); + if (IS_ERR(csra66x0->regmap)) { + ret = PTR_ERR(csra66x0->regmap); + dev_err(&client_i2c->dev, + "%s %d: Failed to allocate register map for I2C device: %d\n", + __func__, __LINE__, ret); + return ret; + } + + i2c_set_clientdata(client_i2c, csra66x0); + + /* get data from device tree */ + if (client_i2c->dev.of_node) { + /* cluster of multiple devices */ + ret = of_property_read_u32( + client_i2c->dev.of_node, "qcom,csra-cluster", + &csra66x0->in_cluster); + if (ret) { + dev_info(&client_i2c->dev, + "%s: qcom,csra-cluster property not defined in DT\n", __func__); + csra66x0->in_cluster = 0; + } + /* master or slave device */ + ret = of_property_read_u32( + client_i2c->dev.of_node, "qcom,csra-cluster-master", + &csra66x0->is_master); + if (ret) { + dev_info(&client_i2c->dev, + "%s: qcom,csra-cluster-master property not defined in DT\n", __func__); + csra66x0->is_master = 0; + } + + /* gpio setup for vreg */ + csra66x0->vreg_gpio = of_get_named_gpio(client_i2c->dev.of_node, + "qcom,csra-vreg-en-gpio", 0); + if (!gpio_is_valid(csra66x0->vreg_gpio)) { + dev_err(&client_i2c->dev, "%s: %s property is not found %d\n", + __func__, "qcom,csra-vreg-en-gpio", + csra66x0->vreg_gpio); + return -ENODEV; + } + dev_dbg(&client_i2c->dev, "%s: vreg_en gpio %d\n", __func__, + csra66x0->vreg_gpio); + ret = gpio_request(csra66x0->vreg_gpio, dev_name(&client_i2c->dev)); + if (ret) { + if (ret == -EBUSY) { + /* GPIO was already requested */ + dev_dbg(&client_i2c->dev, + "%s: gpio %d is already set\n", + __func__, csra66x0->vreg_gpio); + } else { + dev_err(&client_i2c->dev, "%s: Failed to request gpio %d, err: %d\n", + __func__, csra66x0->vreg_gpio, ret); + } + } else { + gpio_direction_output(csra66x0->vreg_gpio, 1); + gpio_set_value(csra66x0->vreg_gpio, 1); + } + + /* register interrupt handle */ + if (client_i2c->irq) { + csra66x0->irq = client_i2c->irq; + /* interrupt polarity */ + ret = of_property_read_u32( + client_i2c->dev.of_node, "irq-active-low", + &csra66x0->irq_active_low); + if (ret) { + dev_info(&client_i2c->dev, + "%s: irq-active-low property not defined in DT\n", __func__); + csra66x0->irq_active_low = 0; + } + if (csra66x0->irq_active_low) + irq_trigger = IRQF_TRIGGER_LOW; + else + irq_trigger = IRQF_TRIGGER_HIGH; + + ret = devm_request_threaded_irq(&client_i2c->dev, + csra66x0->irq, NULL, csra66x0_irq, + irq_trigger | IRQF_ONESHOT, + "csra66x0_irq", csra66x0); + if (ret) { + dev_err(&client_i2c->dev, + "%s: Failed to request IRQ %d: %d\n", + __func__, csra66x0->irq, ret); + csra66x0->irq = 0; + } + } + } + + /* register codec */ + ret = snd_soc_register_codec(&client_i2c->dev, + &soc_codec_drv_csra66x0, NULL, 0); + if (ret != 0) { + dev_err(&client_i2c->dev, "%s %d: Failed to register CODEC: %d\n", + __func__, __LINE__, ret); + if (gpio_is_valid(csra66x0->vreg_gpio)) { + gpio_set_value(csra66x0->vreg_gpio, 0); + gpio_free(csra66x0->vreg_gpio); + } + return ret; + } + return 0; +} + +static int csra66x0_i2c_remove(struct i2c_client *i2c_client) +{ + struct csra66x0_priv *csra66x0 = i2c_get_clientdata(i2c_client); + + if (csra66x0) { + if (gpio_is_valid(csra66x0->vreg_gpio)) { + gpio_set_value(csra66x0->vreg_gpio, 0); + gpio_free(csra66x0->vreg_gpio); + } + } + snd_soc_unregister_codec(&i2c_client->dev); + return 0; +} + +static const struct i2c_device_id csra66x0_i2c_id[] = { + { "csra66x0", 0}, + { } +}; +MODULE_DEVICE_TABLE(i2c, csra66x0_i2c_id); + +static struct i2c_driver csra66x0_i2c_driver = { + .probe = csra66x0_i2c_probe, + .remove = csra66x0_i2c_remove, + .id_table = csra66x0_i2c_id, + .driver = { + .name = "csra66x0", + .owner = THIS_MODULE, + .of_match_table = csra66x0_of_match + }, +}; +#endif + +static int __init csra66x0_codec_init(void) +{ + int ret = 0; +#if IS_ENABLED(CONFIG_I2C) + ret = i2c_add_driver(&csra66x0_i2c_driver); + if (ret != 0) + pr_err("%s: Failed to register CSRA66X0 I2C driver, ret = %d\n", + __func__, ret); +#endif + return ret; +} +module_init(csra66x0_codec_init); + +static void __exit csra66x0_codec_exit(void) +{ +#if IS_ENABLED(CONFIG_I2C) + i2c_del_driver(&csra66x0_i2c_driver); +#endif +} +module_exit(csra66x0_codec_exit); + +MODULE_DESCRIPTION("CSRA66X0 Codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/csra66x0/csra66x0.h b/asoc/codecs/csra66x0/csra66x0.h new file mode 100644 index 000000000000..43d83d847a52 --- /dev/null +++ b/asoc/codecs/csra66x0/csra66x0.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _CSRA66X0_H +#define _CSRA66X0_H + +/* CSRA66X0 register addresses */ +#define CSRA66X0_BASE 0x7000 + +#define CSRA66X0_AUDIO_IF_RX_CONFIG1 (CSRA66X0_BASE+0x0000) +#define CSRA66X0_AUDIO_IF_RX_CONFIG2 (CSRA66X0_BASE+0x0001) +#define CSRA66X0_AUDIO_IF_RX_CONFIG3 (CSRA66X0_BASE+0x0002) +#define CSRA66X0_AUDIO_IF_TX_EN (CSRA66X0_BASE+0x0003) +#define CSRA66X0_AUDIO_IF_TX_CONFIG1 (CSRA66X0_BASE+0x0004) +#define CSRA66X0_AUDIO_IF_TX_CONFIG2 (CSRA66X0_BASE+0x0005) +#define CSRA66X0_I2C_DEVICE_ADDRESS (CSRA66X0_BASE+0x0006) +#define CSRA66X0_CHIP_ID_FA (CSRA66X0_BASE+0x0007) +#define CSRA66X0_ROM_VER_FA (CSRA66X0_BASE+0x0008) +#define CSRA66X0_CHIP_REV_0_FA (CSRA66X0_BASE+0x0009) +#define CSRA66X0_CHIP_REV_1_FA (CSRA66X0_BASE+0x000A) +#define CSRA66X0_CH1_MIX_SEL (CSRA66X0_BASE+0x000B) +#define CSRA66X0_CH2_MIX_SEL (CSRA66X0_BASE+0x000C) +#define CSRA66X0_CH1_SAMPLE1_SCALE_0 (CSRA66X0_BASE+0x000D) +#define CSRA66X0_CH1_SAMPLE1_SCALE_1 (CSRA66X0_BASE+0x000E) +#define CSRA66X0_CH1_SAMPLE3_SCALE_0 (CSRA66X0_BASE+0x000F) +#define CSRA66X0_CH1_SAMPLE3_SCALE_1 (CSRA66X0_BASE+0x0010) +#define CSRA66X0_CH1_SAMPLE5_SCALE_0 (CSRA66X0_BASE+0x0011) +#define CSRA66X0_CH1_SAMPLE5_SCALE_1 (CSRA66X0_BASE+0x0012) +#define CSRA66X0_CH1_SAMPLE7_SCALE_0 (CSRA66X0_BASE+0x0013) +#define CSRA66X0_CH1_SAMPLE7_SCALE_1 (CSRA66X0_BASE+0x0014) +#define CSRA66X0_CH1_SAMPLE2_SCALE_0 (CSRA66X0_BASE+0x0015) +#define CSRA66X0_CH1_SAMPLE2_SCALE_1 (CSRA66X0_BASE+0x0016) +#define CSRA66X0_CH1_SAMPLE4_SCALE_0 (CSRA66X0_BASE+0x0017) +#define CSRA66X0_CH1_SAMPLE4_SCALE_1 (CSRA66X0_BASE+0x0018) +#define CSRA66X0_CH1_SAMPLE6_SCALE_0 (CSRA66X0_BASE+0x0019) +#define CSRA66X0_CH1_SAMPLE6_SCALE_1 (CSRA66X0_BASE+0x001A) +#define CSRA66X0_CH1_SAMPLE8_SCALE_0 (CSRA66X0_BASE+0x001B) +#define CSRA66X0_CH1_SAMPLE8_SCALE_1 (CSRA66X0_BASE+0x001C) +#define CSRA66X0_CH2_SAMPLE1_SCALE_0 (CSRA66X0_BASE+0x001D) +#define CSRA66X0_CH2_SAMPLE1_SCALE_1 (CSRA66X0_BASE+0x001E) +#define CSRA66X0_CH2_SAMPLE3_SCALE_0 (CSRA66X0_BASE+0x001F) +#define CSRA66X0_CH2_SAMPLE3_SCALE_1 (CSRA66X0_BASE+0x0020) +#define CSRA66X0_CH2_SAMPLE5_SCALE_0 (CSRA66X0_BASE+0x0021) +#define CSRA66X0_CH2_SAMPLE5_SCALE_1 (CSRA66X0_BASE+0x0022) +#define CSRA66X0_CH2_SAMPLE7_SCALE_0 (CSRA66X0_BASE+0x0023) +#define CSRA66X0_CH2_SAMPLE7_SCALE_1 (CSRA66X0_BASE+0x0024) +#define CSRA66X0_CH2_SAMPLE2_SCALE_0 (CSRA66X0_BASE+0x0025) +#define CSRA66X0_CH2_SAMPLE2_SCALE_1 (CSRA66X0_BASE+0x0026) +#define CSRA66X0_CH2_SAMPLE4_SCALE_0 (CSRA66X0_BASE+0x0027) +#define CSRA66X0_CH2_SAMPLE4_SCALE_1 (CSRA66X0_BASE+0x0028) +#define CSRA66X0_CH2_SAMPLE6_SCALE_0 (CSRA66X0_BASE+0x0029) +#define CSRA66X0_CH2_SAMPLE6_SCALE_1 (CSRA66X0_BASE+0x002A) +#define CSRA66X0_CH2_SAMPLE8_SCALE_0 (CSRA66X0_BASE+0x002B) +#define CSRA66X0_CH2_SAMPLE8_SCALE_1 (CSRA66X0_BASE+0x002C) +#define CSRA66X0_VOLUME_CONFIG_FA (CSRA66X0_BASE+0x002D) +#define CSRA66X0_STARTUP_DELAY_FA (CSRA66X0_BASE+0x002E) +#define CSRA66X0_CH1_VOLUME_0_FA (CSRA66X0_BASE+0x002F) +#define CSRA66X0_CH1_VOLUME_1_FA (CSRA66X0_BASE+0x0030) +#define CSRA66X0_CH2_VOLUME_0_FA (CSRA66X0_BASE+0x0031) +#define CSRA66X0_CH2_VOLUME_1_FA (CSRA66X0_BASE+0x0032) +#define CSRA66X0_QUAD_ENC_COUNT_0_FA (CSRA66X0_BASE+0x0033) +#define CSRA66X0_QUAD_ENC_COUNT_1_FA (CSRA66X0_BASE+0x0034) +#define CSRA66X0_SOFT_CLIP_CONFIG (CSRA66X0_BASE+0x0035) +#define CSRA66X0_CH1_HARD_CLIP_THRESH (CSRA66X0_BASE+0x0036) +#define CSRA66X0_CH2_HARD_CLIP_THRESH (CSRA66X0_BASE+0x0037) +#define CSRA66X0_SOFT_CLIP_THRESH (CSRA66X0_BASE+0x0038) +#define CSRA66X0_DS_ENABLE_THRESH_0 (CSRA66X0_BASE+0x0039) +#define CSRA66X0_DS_ENABLE_THRESH_1 (CSRA66X0_BASE+0x003A) +#define CSRA66X0_DS_TARGET_COUNT_0 (CSRA66X0_BASE+0x003B) +#define CSRA66X0_DS_TARGET_COUNT_1 (CSRA66X0_BASE+0x003C) +#define CSRA66X0_DS_TARGET_COUNT_2 (CSRA66X0_BASE+0x003D) +#define CSRA66X0_DS_DISABLE_THRESH_0 (CSRA66X0_BASE+0x003E) +#define CSRA66X0_DS_DISABLE_THRESH_1 (CSRA66X0_BASE+0x003F) +#define CSRA66X0_DCA_CTRL (CSRA66X0_BASE+0x0040) +#define CSRA66X0_CH1_DCA_THRESH (CSRA66X0_BASE+0x0041) +#define CSRA66X0_CH2_DCA_THRESH (CSRA66X0_BASE+0x0042) +#define CSRA66X0_DCA_ATTACK_RATE (CSRA66X0_BASE+0x0043) +#define CSRA66X0_DCA_RELEASE_RATE (CSRA66X0_BASE+0x0044) +#define CSRA66X0_CH1_OUTPUT_INVERT_EN (CSRA66X0_BASE+0x0045) +#define CSRA66X0_CH2_OUTPUT_INVERT_EN (CSRA66X0_BASE+0x0046) +#define CSRA66X0_CH1_176P4K_DELAY (CSRA66X0_BASE+0x0047) +#define CSRA66X0_CH2_176P4K_DELAY (CSRA66X0_BASE+0x0048) +#define CSRA66X0_CH1_192K_DELAY (CSRA66X0_BASE+0x0049) +#define CSRA66X0_CH2_192K_DELAY (CSRA66X0_BASE+0x004A) +#define CSRA66X0_DEEMP_CONFIG_FA (CSRA66X0_BASE+0x004B) +#define CSRA66X0_CH1_TREBLE_GAIN_CTRL_FA (CSRA66X0_BASE+0x004C) +#define CSRA66X0_CH2_TREBLE_GAIN_CTRL_FA (CSRA66X0_BASE+0x004D) +#define CSRA66X0_CH1_TREBLE_FC_CTRL_FA (CSRA66X0_BASE+0x004E) +#define CSRA66X0_CH2_TREBLE_FC_CTRL_FA (CSRA66X0_BASE+0x004F) +#define CSRA66X0_CH1_BASS_GAIN_CTRL_FA (CSRA66X0_BASE+0x0050) +#define CSRA66X0_CH2_BASS_GAIN_CTRL_FA (CSRA66X0_BASE+0x0051) +#define CSRA66X0_CH1_BASS_FC_CTRL_FA (CSRA66X0_BASE+0x0052) +#define CSRA66X0_CH2_BASS_FC_CTRL_FA (CSRA66X0_BASE+0x0053) +#define CSRA66X0_FILTER_SEL_8K (CSRA66X0_BASE+0x0054) +#define CSRA66X0_FILTER_SEL_11P025K (CSRA66X0_BASE+0x0055) +#define CSRA66X0_FILTER_SEL_16K (CSRA66X0_BASE+0x0056) +#define CSRA66X0_FILTER_SEL_22P05K (CSRA66X0_BASE+0x0057) +#define CSRA66X0_FILTER_SEL_32K (CSRA66X0_BASE+0x0058) +#define CSRA66X0_FILTER_SEL_44P1K_48K (CSRA66X0_BASE+0x0059) +#define CSRA66X0_FILTER_SEL_88P2K_96K (CSRA66X0_BASE+0x005A) +#define CSRA66X0_FILTER_SEL_176P4K_192K (CSRA66X0_BASE+0x005B) +/* RESERVED (CSRA66X0_BASE+0x005C) */ +#define CSRA66X0_USER_DSP_CTRL (CSRA66X0_BASE+0x005D) +#define CSRA66X0_TEST_TONE_CTRL (CSRA66X0_BASE+0x005E) +#define CSRA66X0_TEST_TONE_FREQ_0 (CSRA66X0_BASE+0x005F) +#define CSRA66X0_TEST_TONE_FREQ_1 (CSRA66X0_BASE+0x0060) +#define CSRA66X0_TEST_TONE_FREQ_2 (CSRA66X0_BASE+0x0061) +#define CSRA66X0_AUDIO_RATE_CTRL_FA (CSRA66X0_BASE+0x0062) +#define CSRA66X0_MODULATION_INDEX_CTRL (CSRA66X0_BASE+0x0063) +#define CSRA66X0_MODULATION_INDEX_COUNT (CSRA66X0_BASE+0x0064) +#define CSRA66X0_MIN_MODULATION_PULSE_WIDTH (CSRA66X0_BASE+0x0065) +#define CSRA66X0_DEAD_TIME_CTRL (CSRA66X0_BASE+0x0066) +#define CSRA66X0_DEAD_TIME_THRESHOLD_0 (CSRA66X0_BASE+0x0067) +#define CSRA66X0_DEAD_TIME_THRESHOLD_1 (CSRA66X0_BASE+0x0068) +#define CSRA66X0_DEAD_TIME_THRESHOLD_2 (CSRA66X0_BASE+0x0069) +#define CSRA66X0_CH1_LOW_SIDE_DLY (CSRA66X0_BASE+0x006A) +#define CSRA66X0_CH2_LOW_SIDE_DLY (CSRA66X0_BASE+0x006B) +#define CSRA66X0_SPECTRUM_CTRL (CSRA66X0_BASE+0x006C) +/* RESERVED (CSRA66X0_BASE+0x006D) */ +#define CSRA66X0_SPECTRUM_SPREAD_CTRL (CSRA66X0_BASE+0x006E) +/* RESERVED (CSRA66X0_BASE+0x006F) */ +/* ... */ +/* RESERVED (CSRA66X0_BASE+0x007C) */ +#define CSRA66X0_EXT_PA_PROTECT_POLARITY (CSRA66X0_BASE+0x007D) +#define CSRA66X0_TEMP0_BACKOFF_COMP_VALUE (CSRA66X0_BASE+0x007E) +#define CSRA66X0_TEMP0_SHUTDOWN_COMP_VALUE (CSRA66X0_BASE+0x007F) +#define CSRA66X0_TEMP1_BACKOFF_COMP_VALUE (CSRA66X0_BASE+0x0080) +#define CSRA66X0_TEMP1_SHUTDOWN_COMP_VALUE (CSRA66X0_BASE+0x0081) +#define CSRA66X0_TEMP_PROT_BACKOFF (CSRA66X0_BASE+0x0082) +#define CSRA66X0_TEMP_READ0_FA (CSRA66X0_BASE+0x0083) +#define CSRA66X0_TEMP_READ1_FA (CSRA66X0_BASE+0x0084) +#define CSRA66X0_CHIP_STATE_CTRL_FA (CSRA66X0_BASE+0x0085) +/* RESERVED (CSRA66X0_BASE+0x0086) */ +#define CSRA66X0_PWM_OUTPUT_CONFIG (CSRA66X0_BASE+0x0087) +#define CSRA66X0_MISC_CONTROL_STATUS_0 (CSRA66X0_BASE+0x0088) +#define CSRA66X0_MISC_CONTROL_STATUS_1_FA (CSRA66X0_BASE+0x0089) +#define CSRA66X0_PIO0_SELECT (CSRA66X0_BASE+0x008A) +#define CSRA66X0_PIO1_SELECT (CSRA66X0_BASE+0x008B) +#define CSRA66X0_PIO2_SELECT (CSRA66X0_BASE+0x008C) +#define CSRA66X0_PIO3_SELECT (CSRA66X0_BASE+0x008D) +#define CSRA66X0_PIO4_SELECT (CSRA66X0_BASE+0x008E) +#define CSRA66X0_PIO5_SELECT (CSRA66X0_BASE+0x008F) +#define CSRA66X0_PIO6_SELECT (CSRA66X0_BASE+0x0090) +#define CSRA66X0_PIO7_SELECT (CSRA66X0_BASE+0x0091) +#define CSRA66X0_PIO8_SELECT (CSRA66X0_BASE+0x0092) +#define CSRA66X0_PIO_DIRN0 (CSRA66X0_BASE+0x0093) +#define CSRA66X0_PIO_DIRN1 (CSRA66X0_BASE+0x0094) +#define CSRA66X0_PIO_PULL_EN0 (CSRA66X0_BASE+0x0095) +#define CSRA66X0_PIO_PULL_EN1 (CSRA66X0_BASE+0x0096) +#define CSRA66X0_PIO_PULL_DIR0 (CSRA66X0_BASE+0x0097) +#define CSRA66X0_PIO_PULL_DIR1 (CSRA66X0_BASE+0x0098) +#define CSRA66X0_PIO_DRIVE_OUT0_FA (CSRA66X0_BASE+0x0099) +#define CSRA66X0_PIO_DRIVE_OUT1_FA (CSRA66X0_BASE+0x009A) +#define CSRA66X0_PIO_STATUS_IN0_FA (CSRA66X0_BASE+0x009B) +#define CSRA66X0_PIO_STATUS_IN1_FA (CSRA66X0_BASE+0x009C) +/* RESERVED (CSRA66X0_BASE+0x009D) */ +#define CSRA66X0_IRQ_OUTPUT_ENABLE (CSRA66X0_BASE+0x009E) +#define CSRA66X0_IRQ_OUTPUT_POLARITY (CSRA66X0_BASE+0x009F) +#define CSRA66X0_IRQ_OUTPUT_STATUS_FA (CSRA66X0_BASE+0x00A0) +#define CSRA66X0_CLIP_DCA_STATUS_FA (CSRA66X0_BASE+0x00A1) +#define CSRA66X0_CHIP_STATE_STATUS_FA (CSRA66X0_BASE+0x00A2) +#define CSRA66X0_FAULT_STATUS_FA (CSRA66X0_BASE+0x00A3) +#define CSRA66X0_OTP_STATUS_FA (CSRA66X0_BASE+0x00A4) +#define CSRA66X0_AUDIO_IF_STATUS_FA (CSRA66X0_BASE+0x00A5) +/* RESERVED (CSRA66X0_BASE+0x00A6) */ +#define CSRA66X0_DSP_SATURATION_STATUS_FA (CSRA66X0_BASE+0x00A7) +#define CSRA66X0_AUDIO_RATE_STATUS_FA (CSRA66X0_BASE+0x00A8) +/* RESERVED (CSRA66X0_BASE+0x00A9) */ +/* ... */ +/* RESERVED (CSRA66X0_BASE+0x00AB) */ +#define CSRA66X0_DISABLE_PWM_OUTPUT (CSRA66X0_BASE+0x00AC) +/* RESERVED (CSRA66X0_BASE+0x00AD) */ +/* ... */ +/* RESERVED (CSRA66X0_BASE+0x00B0) */ +#define CSRA66X0_OTP_VER_FA (CSRA66X0_BASE+0x00B1) +#define CSRA66X0_RAM_VER_FA (CSRA66X0_BASE+0x00B2) +/* RESERVED (CSRA66X0_BASE+0x00B3) */ +#define CSRA66X0_AUDIO_SATURATION_FLAGS_FA (CSRA66X0_BASE+0x00B4) +#define CSRA66X0_DCOFFSET_CHAN_1_01_FA (CSRA66X0_BASE+0x00B5) +#define CSRA66X0_DCOFFSET_CHAN_1_02_FA (CSRA66X0_BASE+0x00B6) +#define CSRA66X0_DCOFFSET_CHAN_1_03_FA (CSRA66X0_BASE+0x00B7) +#define CSRA66X0_DCOFFSET_CHAN_2_01_FA (CSRA66X0_BASE+0x00B8) +#define CSRA66X0_DCOFFSET_CHAN_2_02_FA (CSRA66X0_BASE+0x00B9) +#define CSRA66X0_DCOFFSET_CHAN_2_03_FA (CSRA66X0_BASE+0x00BA) +#define CSRA66X0_FORCED_PA_SWITCHING_CTRL (CSRA66X0_BASE+0x00BB) +#define CSRA66X0_PA_FORCE_PULSE_WIDTH (CSRA66X0_BASE+0x00BC) +#define CSRA66X0_PA_HIGH_MODULATION_CTRL_CH1 (CSRA66X0_BASE+0x00BD) +/* RESERVED (CSRA66X0_BASE+0x00BE) */ +/* RESERVED (CSRA66X0_BASE+0x00BF) */ +#define CSRA66X0_HIGH_MODULATION_THRESHOLD_LOW (CSRA66X0_BASE+0x00C0) +#define CSRA66X0_HIGH_MODULATION_THRESHOLD_HIGH (CSRA66X0_BASE+0x00C1) +/* RESERVED (CSRA66X0_BASE+0x00C2) */ +/* RESERVED (CSRA66X0_BASE+0x00C3) */ +#define CSRA66X0_PA_FREEZE_CTRL (CSRA66X0_BASE+0x00C4) +#define CSRA66X0_DCA_FREEZE_CTRL (CSRA66X0_BASE+0x00C5) +/* RESERVED (CSRA66X0_BASE+0x00C6) */ +/* ... */ +/* RESERVED (CSRA66X0_BASE+0x00FF) */ +#define CSRA66X0_MAX_REGISTER_ADDR CSRA66X0_DCA_FREEZE_CTRL + +#define EXPECTED_CSRA66X0_CHIP_ID 0x39 + +#define SPK_VOLUME_M20DB 0x119 +#define SPK_VOLUME_M20DB_LSB (SPK_VOLUME_M20DB & 0x0FF) +#define SPK_VOLUME_M20DB_MSB ((SPK_VOLUME_M20DB & 0x100)>>8) +#define SPK_VOLUME_LSB_MSK 0x00FF +#define SPK_VOLUME_MSB_MSK 0x0100 + +#define CONFIG_STATE 0x0 +#define RUN_STATE 0x1 +#define STDBY_STATE 0x2 + +#define FAULT_STATUS_INTERNAL 0x01 +#define FAULT_STATUS_OTP_INTEGRITY 0x02 +#define FAULT_STATUS_PADS2 0x04 +#define FAULT_STATUS_SMPS 0x08 +#define FAULT_STATUS_TEMP 0x10 +#define FAULT_STATUS_PROTECT 0x20 + +#endif /* _CSRA66X0_H */ -- GitLab From 66ae4136f5a1144c46aea96f3e2138d3e95f46cc Mon Sep 17 00:00:00 2001 From: Dhananjay Kumar Date: Thu, 28 Jun 2018 19:24:46 +0530 Subject: [PATCH 0380/1645] lsm: miscellaneous fixes for multi-stage adsp VA Fix compilation warnings from multi-stage VA code changes. Correct sound model param size value to avoid failure from second stage sound model registration. Change-Id: I7f589f0ddece167233b61236b3e5b6585927f62d Signed-off-by: Dhananjay Kumar --- asoc/msm-lsm-client.c | 4 ++-- dsp/q6lsm.c | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index e0eeef3c4973..c6393adad3fc 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -1117,7 +1117,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, break; } if (copy_from_user( - prtd->lsm_client->stage_cfg[stage_idx].sound_model.data, + prtd->lsm_client->stage_cfg[p_info.stage_idx].sound_model.data, snd_model_v2.data, snd_model_v2.data_size)) { dev_err(rtd->dev, "%s: copy from user data failed\n" @@ -2149,7 +2149,7 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, if (p_data.data_size != p_size) { dev_err(rtd->dev, - "%s: %s: Invalid data_size(%zd) against expected(%zd)\n", + "%s: %s: Invalid data_size(%u) against expected(%zd)\n", __func__, "SET_MODULE_PARAMS(_V2)", p_data.data_size, p_size); err = -EFAULT; diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 8146b65d95a6..f34187d1fdfc 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -741,7 +741,8 @@ static int q6lsm_do_open_v3(struct lsm_client *client) { int rc, app_type; struct lsm_stream_cmd_open_tx_v3 *open_v3; - size_t cmd_size = 0, stage_idx = LSM_STAGE_INDEX_FIRST; + size_t cmd_size = 0; + int stage_idx = LSM_STAGE_INDEX_FIRST; uint32_t topology_id = 0, *uint32_ptr = NULL; cmd_size = sizeof(struct lsm_stream_cmd_open_tx_v3); @@ -866,7 +867,7 @@ void q6lsm_sm_set_param_data(struct lsm_client *client, param_hdr.module_id = p_info->module_id; param_hdr.instance_id = p_info->instance_id; param_hdr.param_id = p_info->param_id; - param_hdr.param_size = sm->size; + param_hdr.param_size = p_info->param_size; ret = q6lsm_pack_params(sm->data, ¶m_hdr, NULL, offset, LSM_SESSION_CMD_SET_PARAMS_V2); -- GitLab From ca8ac8a57a95df2608e9abec28b8edf3799d9dca Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Wed, 20 Jun 2018 18:52:08 +0530 Subject: [PATCH 0381/1645] asoc: qcs405: Add support for CSRA66X0 device Add support for CSRA66X0 amplifier to glue as aux codec in asoc qcs405 machine driver Change-Id: I3413a0df52149da84c05d703226a3845119ab8b2 Signed-off-by: Mangesh Kunchamwar Signed-off-by: Srikanth Katta --- asoc/qcs405.c | 219 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 216 insertions(+), 3 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 646da3ee6b3f..73b743d32e74 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -35,6 +35,7 @@ #include "codecs/msm-cdc-pinctrl.h" #include "codecs/wcd9335.h" #include "codecs/wsa881x.h" +#include "codecs/csra66x0/csra66x0.h" #include #define DRV_NAME "qcs405-asoc-snd" @@ -150,6 +151,11 @@ struct msm_wsa881x_dev_info { u32 index; }; +struct msm_csra66x0_dev_info { + struct device_node *of_node; + u32 index; +}; + enum pinctrl_pin_state { STATE_DISABLE = 0, /* All pins are in sleep state */ STATE_MI2S_ACTIVE, /* I2S = active, TDM = sleep */ @@ -7300,6 +7306,200 @@ static int msm_init_wsa_dev(struct platform_device *pdev, return ret; } +static int msm_csra66x0_init(struct snd_soc_component *component) +{ + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + + if (!codec) { + pr_err("%s codec is NULL\n", __func__); + return -EINVAL; + } + return 0; +} + +static int msm_init_csra_dev(struct platform_device *pdev, + struct snd_soc_card *card) +{ + struct device_node *csra_of_node; + u32 csra_max_devs; + u32 csra_dev_cnt; + char *dev_name_str = NULL; + struct msm_csra66x0_dev_info *csra66x0_dev_info; + const char *csra_auxdev_name_prefix[1]; + int i; + int found = 0; + int ret = 0; + + /* Get maximum CSRA device count for this platform */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,csra-max-devs", &csra_max_devs); + if (ret) { + dev_info(&pdev->dev, + "%s: csra-max-devs property missing in DT %s, ret = %d\n", + __func__, pdev->dev.of_node->full_name, ret); + card->num_aux_devs = 0; + return 0; + } + if (csra_max_devs == 0) { + dev_warn(&pdev->dev, + "%s: Max CSRA devices is 0 for this target?\n", + __func__); + return 0; + } + + /* Get count of CSRA device phandles for this platform */ + csra_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node, + "qcom,csra-devs", NULL); + if (csra_dev_cnt == -ENOENT) { + dev_warn(&pdev->dev, "%s: No csra device defined in DT.\n", + __func__); + goto err; + } else if (csra_dev_cnt <= 0) { + dev_err(&pdev->dev, + "%s: Error reading csra device from DT. csra_dev_cnt = %d\n", + __func__, csra_dev_cnt); + ret = -EINVAL; + goto err; + } + + /* + * Expect total phandles count to be NOT less than maximum possible + * CSRA count. However, if it is less, then assign same value to + * max count as well. + */ + if (csra_dev_cnt < csra_max_devs) { + dev_dbg(&pdev->dev, + "%s: csra_max_devs = %d cannot exceed csra_dev_cnt = %d\n", + __func__, csra_max_devs, csra_dev_cnt); + csra_max_devs = csra_dev_cnt; + } + + /* Make sure prefix string passed for each CSRA device */ + ret = of_property_count_strings(pdev->dev.of_node, + "qcom,csra-aux-dev-prefix"); + if (ret != csra_dev_cnt) { + dev_err(&pdev->dev, + "%s: expecting %d csra prefix. Defined only %d in DT\n", + __func__, csra_dev_cnt, ret); + ret = -EINVAL; + goto err; + } + + /* + * Alloc mem to store phandle and index info of CSRA device, if already + * registered with ALSA core + */ + csra66x0_dev_info = devm_kcalloc(&pdev->dev, csra_max_devs, + sizeof(struct msm_csra66x0_dev_info), + GFP_KERNEL); + if (!csra66x0_dev_info) { + ret = -ENOMEM; + goto err; + } + + /* + * search and check whether all CSRA devices are already + * registered with ALSA core or not. If found a node, store + * the node and the index in a local array of struct for later + * use. + */ + for (i = 0; i < csra_dev_cnt; i++) { + csra_of_node = of_parse_phandle(pdev->dev.of_node, + "qcom,csra-devs", i); + if (unlikely(!csra_of_node)) { + /* we should not be here */ + dev_err(&pdev->dev, + "%s: csra dev node is not present\n", + __func__); + ret = -EINVAL; + goto err_free_dev_info; + } + if (soc_find_component(csra_of_node, NULL)) { + /* CSRA device registered with ALSA core */ + csra66x0_dev_info[found].of_node = csra_of_node; + csra66x0_dev_info[found].index = i; + found++; + if (found == csra_max_devs) + break; + } + } + + if (found < csra_max_devs) { + dev_dbg(&pdev->dev, + "%s: failed to find %d components. Found only %d\n", + __func__, csra_max_devs, found); + return -EPROBE_DEFER; + } + dev_info(&pdev->dev, + "%s: found %d csra66x0 devices registered with ALSA core\n", + __func__, found); + + card->num_aux_devs = csra_max_devs; + card->num_configs = csra_max_devs; + + /* Alloc array of AUX devs struct */ + msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_aux_dev), GFP_KERNEL); + if (!msm_aux_dev) { + ret = -ENOMEM; + goto err_free_dev_info; + } + + /* Alloc array of codec conf struct */ + msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_codec_conf), GFP_KERNEL); + if (!msm_codec_conf) { + ret = -ENOMEM; + goto err_free_aux_dev; + } + + for (i = 0; i < card->num_aux_devs; i++) { + dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN, + GFP_KERNEL); + if (!dev_name_str) { + ret = -ENOMEM; + goto err_free_cdc_conf; + } + + ret = of_property_read_string_index(pdev->dev.of_node, + "qcom,csra-aux-dev-prefix", + csra66x0_dev_info[i].index, + csra_auxdev_name_prefix); + if (ret) { + dev_err(&pdev->dev, + "%s: failed to read csra aux dev prefix, ret = %d\n", + __func__, ret); + ret = -EINVAL; + goto err_free_dev_name_str; + } + + snprintf(dev_name_str, strlen("csra66x0.%d"), "csra66x0.%d", i); + msm_aux_dev[i].name = dev_name_str; + msm_aux_dev[i].codec_name = NULL; + msm_aux_dev[i].codec_of_node = + csra66x0_dev_info[i].of_node; + msm_aux_dev[i].init = msm_csra66x0_init; /* codec specific init */ + msm_codec_conf[i].dev_name = NULL; + msm_codec_conf[i].name_prefix = csra_auxdev_name_prefix[0]; + msm_codec_conf[i].of_node = csra66x0_dev_info[i].of_node; + } + card->codec_conf = msm_codec_conf; + card->aux_dev = msm_aux_dev; + + return 0; + +err_free_dev_name_str: + devm_kfree(&pdev->dev, dev_name_str); +err_free_cdc_conf: + devm_kfree(&pdev->dev, msm_codec_conf); +err_free_aux_dev: + devm_kfree(&pdev->dev, msm_aux_dev); +err_free_dev_info: + devm_kfree(&pdev->dev, csra66x0_dev_info); +err: + return ret; +} + static void msm_i2s_auxpcm_init(struct platform_device *pdev) { int count; @@ -7341,6 +7541,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) struct snd_soc_card *card; struct msm_asoc_mach_data *pdata; int ret; + u32 val; if (!pdev->dev.of_node) { dev_err(&pdev->dev, "No platform supplied from device tree\n"); @@ -7381,9 +7582,21 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) ret = -EPROBE_DEFER; goto err; } - ret = msm_init_wsa_dev(pdev, card); - if (ret) - goto err; + + ret = of_property_read_u32(pdev->dev.of_node, "qcom,csra-codec", &val); + if (ret) { + dev_info(&pdev->dev, "no 'qcom,csra-codec' in DT\n"); + val = 0; + } + if (val) { + ret = msm_init_csra_dev(pdev, card); + if (ret) + goto err; + } else { + ret = msm_init_wsa_dev(pdev, card); + if (ret) + goto err; + } pdata->dmic_01_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,cdc-dmic01-gpios", -- GitLab From d8d43d2490bb8f8a6f9ba7ad17fa1b809727dc06 Mon Sep 17 00:00:00 2001 From: Ramu Gottipati Date: Sat, 7 Jul 2018 23:17:16 +0530 Subject: [PATCH 0382/1645] asoc: Fix compilation errors Compiler throwing compilation erros for uninitialized variables. So, initialized with default error value. Change-Id: I7d90e739ae8e174bfb4d2c50e5eead338b66fec9 Signed-off-by: Ramu Gottipati --- asoc/msm-pcm-routing-v2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 33d0cef7489c..df5ce1dbd551 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1212,7 +1212,7 @@ int msm_pcm_routing_get_pp_ch_cnt(int fe_id, int session_type) { struct msm_pcm_stream_app_type_cfg cfg_data; int be_id = 0, app_type_idx = 0, app_type = 0; - int ret; + int ret = -EINVAL; memset(&cfg_data, 0, sizeof(cfg_data)); @@ -20267,7 +20267,7 @@ static uint32_t msm_routing_get_topology(size_t data_size, void *data) static void msm_routing_load_topology(size_t data_size, void *data) { uint32_t topology_id; - int ret; + int ret = -EINVAL; topology_id = msm_routing_get_topology(data_size, data); if (topology_id != NULL_COPP_TOPOLOGY) @@ -20281,7 +20281,7 @@ static void msm_routing_load_topology(size_t data_size, void *data) static void msm_routing_unload_topology(uint32_t topology_id) { - int ret; + int ret = -EINVAL; if (topology_id != NULL_COPP_TOPOLOGY) ret = q6core_load_unload_topo_modules(topology_id, @@ -20430,7 +20430,7 @@ static int msm_routing_be_dai_name_table_tlv_get(struct snd_kcontrol *kcontrol, unsigned int size) { int i; - int ret; + int ret = 0; if (size < sizeof(be_dai_name_table)) { pr_err("%s: invalid size %d requested, returning\n", -- GitLab From b167db1aeef64656c42c4750ac33e4964c1bbc99 Mon Sep 17 00:00:00 2001 From: Zhou Song Date: Mon, 2 Jul 2018 17:14:00 +0800 Subject: [PATCH 0383/1645] asoc: msm-pcm-routing: add support for a2dp echo ref Add support for a2dp echo reference for SVA. This is used to cancel a2dp playback echo from voice activation input samples. When phone connects to A2DP speaker like car kit, selecting A2DP as echo reference can have better VA performance. Change-Id: I287ded27421cbda9621f2b2846c3ec8350f080dc Signed-off-by: Zhou Song --- asoc/msm-pcm-routing-v2.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 33d0cef7489c..5c7a4cbe3b2c 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -3833,6 +3833,10 @@ static int msm_routing_ec_ref_rx_put(struct snd_kcontrol *kcontrol, msm_route_ec_ref_rx = 28; ec_ref_port_id = AFE_PORT_ID_WSA_CODEC_DMA_TX_2; break; + case 29: + msm_route_ec_ref_rx = 29; + ec_ref_port_id = SLIMBUS_7_RX; + break; default: msm_route_ec_ref_rx = 0; /* NONE */ pr_err("%s EC ref rx %ld not valid\n", @@ -3857,7 +3861,8 @@ static const char *const ec_ref_rx[] = { "None", "SLIM_RX", "I2S_RX", "TERT_MI2S_RX", "QUAT_MI2S_RX", "TERT_TDM_TX_0", "USB_AUDIO_RX", "INT0_MI2S_RX", "INT4_MI2S_RX", "INT3_MI2S_TX", "DISPLAY_PORT", "WSA_CDC_DMA_RX_0", "WSA_CDC_DMA_RX_1", - "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_2" + "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_2", + "SLIM_7_RX" }; static const struct soc_enum msm_route_ec_ref_rx_enum[] = { -- GitLab From c31faba93bfe1c29b3f76055890e0d5e31787bae Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Mon, 9 Jul 2018 16:00:21 +0530 Subject: [PATCH 0384/1645] asoc: qcs405: update tasha codec dais Updating tasha codec backend dai links. Change-Id: I293685c44455ec3b8ed61af24ec6be06201bd2f6 Signed-off-by: Surendar Karka Signed-off-by: Mangesh Kunchamwar --- asoc/qcs405.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 646da3ee6b3f..480e20a158f2 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -6037,7 +6037,7 @@ static struct snd_soc_dai_link msm_tasha_be_dai_links[] = { .cpu_dai_name = "msm-dai-q6-dev.16384", .platform_name = "msm-pcm-routing", .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx1", + .codec_dai_name = "tasha_mix_rx1", .no_pcm = 1, .dpcm_playback = 1, .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, @@ -6068,7 +6068,7 @@ static struct snd_soc_dai_link msm_tasha_be_dai_links[] = { .cpu_dai_name = "msm-dai-q6-dev.16386", .platform_name = "msm-pcm-routing", .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx1", + .codec_dai_name = "tasha_mix_rx1", .no_pcm = 1, .dpcm_playback = 1, .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, @@ -6113,7 +6113,7 @@ static struct snd_soc_dai_link msm_tasha_be_dai_links[] = { .cpu_dai_name = "msm-dai-q6-dev.16390", .platform_name = "msm-pcm-routing", .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx1", + .codec_dai_name = "tasha_mix_rx1", .no_pcm = 1, .dpcm_playback = 1, .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, @@ -6143,7 +6143,7 @@ static struct snd_soc_dai_link msm_tasha_be_dai_links[] = { .cpu_dai_name = "msm-dai-q6-dev.16392", .platform_name = "msm-pcm-routing", .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx1", + .codec_dai_name = "tasha_mix_rx1", .no_pcm = 1, .dpcm_playback = 1, .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, -- GitLab From a9c69199a77c68ee7f70b7644d234cbd0a882835 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Tue, 3 Jul 2018 18:00:40 +0530 Subject: [PATCH 0385/1645] asoc: bolero: Bringup fixes in Vipertooth Add bringup fixes for bolero regmap and va-macro micbias property setting. Change-Id: I536b7bf6ff625da1f2f639a93cf1f9174cfd6447 Signed-off-by: Mangesh Kunchamwar --- asoc/codecs/bolero/bolero-cdc-regmap.c | 4 ++-- asoc/codecs/bolero/va-macro.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc-regmap.c b/asoc/codecs/bolero/bolero-cdc-regmap.c index 46c808607eca..f026c26f9aeb 100644 --- a/asoc/codecs/bolero/bolero-cdc-regmap.c +++ b/asoc/codecs/bolero/bolero-cdc-regmap.c @@ -758,7 +758,7 @@ static bool bolero_is_readable_register(struct device *dev, return false; reg_tbl = bolero_reg_access[macro_id]; - reg_offset = reg - macro_id_base_offset[macro_id]; + reg_offset = (reg - macro_id_base_offset[macro_id])/4; if (reg_tbl) return (reg_tbl[reg_offset] & RD_REG); @@ -783,7 +783,7 @@ static bool bolero_is_writeable_register(struct device *dev, return false; reg_tbl = bolero_reg_access[macro_id]; - reg_offset = reg - macro_id_base_offset[macro_id]; + reg_offset = (reg - macro_id_base_offset[macro_id])/4; if (reg_tbl) return (reg_tbl[reg_offset] & WR_REG); diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 113e341f5367..a9c27e6d953d 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -1430,7 +1430,7 @@ static int va_macro_probe(struct platform_device *pdev) char __iomem *va_io_base; struct clk *va_core_clk; bool va_without_decimation = false; - const char *micb_supply_str = "va-vdd-micb-supply"; + const char *micb_supply_str = "va-vdd-micb"; const char *micb_voltage_str = "qcom,va-vdd-micb-voltage"; const char *micb_current_str = "qcom,va-vdd-micb-current"; int ret = 0; -- GitLab From 2f39a329bfd05e0c153e79c75e2e5def358a55cc Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Tue, 10 Jul 2018 20:11:06 +0530 Subject: [PATCH 0386/1645] asoc: bolero: Bringup fixes for qcs405 Add bringup fixes for va-macro micbias property setting. Change-Id: Ie1c35d8519f819bed227885e1c2a18e3de7fd82a Signed-off-by: Mangesh Kunchamwar --- asoc/codecs/bolero/va-macro.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index a9c27e6d953d..45e1dbbdb9a6 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -1430,7 +1430,8 @@ static int va_macro_probe(struct platform_device *pdev) char __iomem *va_io_base; struct clk *va_core_clk; bool va_without_decimation = false; - const char *micb_supply_str = "va-vdd-micb"; + const char *micb_supply_str = "va-vdd-micb-supply"; + const char *micb_supply_str1 = "va-vdd-micb"; const char *micb_voltage_str = "qcom,va-vdd-micb-voltage"; const char *micb_current_str = "qcom,va-vdd-micb-current"; int ret = 0; @@ -1483,7 +1484,7 @@ static int va_macro_probe(struct platform_device *pdev) if (of_parse_phandle(pdev->dev.of_node, micb_supply_str, 0)) { va_priv->micb_supply = devm_regulator_get(&pdev->dev, - micb_supply_str); + micb_supply_str1); if (IS_ERR(va_priv->micb_supply)) { ret = PTR_ERR(va_priv->micb_supply); dev_err(&pdev->dev, -- GitLab From 91c2173c2f733f8bb985337bdcf992f72182b993 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Tue, 10 Jul 2018 17:02:46 +0530 Subject: [PATCH 0387/1645] asoc: Add Hostless DAI for WSA CDC DMA Rx interface Enable hostless DAI for WSA CDC DMA Rx interface for hands free profile use case. Change-Id: I3c4246414dc477cdad382b46a6dbe6770dc5b89e Signed-off-by: Mangesh Kunchamwar --- asoc/msm-dai-fe.c | 42 +++++++++++++++++++++++++++++++++++++++ asoc/msm-pcm-routing-v2.c | 15 +++++++++++++- asoc/qcs405.c | 18 +++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index 3de797f1559f..a711a25e20c3 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -533,6 +533,48 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "SLIMBUS8_HOSTLESS", .probe = fe_dai_probe, }, + { + .playback = { + .stream_name = "CDC_DMA_HOSTLESS Playback", + .aif_name = "CDC_DMA_DL_HL", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "CDC_DMA_HOSTLESS Capture", + .aif_name = "CDC_DMA_UL_HL", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_dai_ops, + .name = "CDC_DMA_HOSTLESS", + .probe = fe_dai_probe, + }, { .playback = { .stream_name = "INT_FM_HOSTLESS Playback", diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index fe5ac1df9db4..bda838718855 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -14485,6 +14485,11 @@ static const struct snd_kcontrol_new slim4_fm_switch_mixer_controls = 0, 1, 0, msm_routing_get_switch_mixer, msm_routing_put_switch_mixer); +static const struct snd_kcontrol_new cdc_dma_fm_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + static const struct snd_kcontrol_new slim6_fm_switch_mixer_controls = SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, 0, 1, 0, msm_routing_get_switch_mixer, @@ -15755,6 +15760,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("SLIM0_UL_HL", "SLIMBUS0_HOSTLESS Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("CDC_DMA_DL_HL", "CDC_DMA_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("CDC_DMA_UL_HL", "CDC_DMA_HOSTLESS Capture", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("CPE_LSM_UL_HL", "CPE LSM capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("SLIM1_DL_HL", "SLIMBUS1_HOSTLESS Playback", @@ -16464,6 +16473,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &usb_switch_mixer_controls), SND_SOC_DAPM_SWITCH("A2DP_SLIM7_UL_HL", SND_SOC_NOPM, 0, 0, &a2dp_slim7_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("WSA_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, + &cdc_dma_fm_switch_mixer_controls), /* Mixer definitions */ SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0, @@ -18845,7 +18856,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIM3_UL_HL", NULL, "SLIMBUS_3_TX"}, {"SLIM4_UL_HL", NULL, "SLIMBUS_4_TX"}, {"SLIM8_UL_HL", NULL, "SLIMBUS_8_TX"}, - + {"WSA_CDC_DMA_RX_0_DL_HL", "Switch", "CDC_DMA_DL_HL"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0_DL_HL"}, + {"CDC_DMA_UL_HL", NULL, "VA_CDC_DMA_TX_0"}, {"LSM1 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, {"LSM1 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, {"LSM1 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 73b743d32e74..d78ce6d81f42 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -5245,6 +5245,24 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, + /* Hostless PCM purpose */ + { + .name = "CDC_DMA Hostless", + .stream_name = "CDC_DMA Hostless", + .cpu_dai_name = "CDC_DMA_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, { .name = "MSM AFE-PCM RX", .stream_name = "AFE-PROXY RX", -- GitLab From 1603e0d72b9e70c980da99192c5db9c9775e3573 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Wed, 11 Jul 2018 19:19:10 +0530 Subject: [PATCH 0388/1645] asoc: compilation fix for qcs403 Fix compilation issue with qcs403 variant compilation Change-Id: Iae877e1a1c3c81edd9c26c9bb143216e2d3550d6 Signed-off-by: Mangesh Kunchamwar --- asoc/msm-lsm-client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index c302be5a6166..e9ec63f0fc49 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -311,7 +311,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, if (!tmp) { spin_unlock_irqrestore(&prtd->event_lock, flags); dev_err(rtd->dev, - "%s: Failed to allocate memory for %s, size = %lu\n", + "%s: Failed to allocate memory for %s, size = %zu\n", __func__, "LSM_SESSION_DETECTION_ENGINE_GENERIC_EVENT", sizeof(struct snd_lsm_event_status) + -- GitLab From 2d84e4aedc0b8207e1f5637de73c26f491d2524f Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Tue, 10 Jul 2018 17:50:35 +0530 Subject: [PATCH 0389/1645] asoc: Enable VAD in QCS405 Add AFE HW CAL dep node in config and fix the set sampling rate for codec dma interface Change-Id: I9165a80da00bfb5b61bbf4f0391ff794d8fba352 Signed-off-by: Mangesh Kunchamwar --- asoc/msm-dai-q6-v2.c | 5 ++--- asoc/qcs405.c | 32 +++++++++++++++++++++++++++++++- config/qcs405auto.conf | 1 + config/qcs405autoconf.h | 1 + dsp/q6afe.c | 3 ++- 5 files changed, 37 insertions(+), 5 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 5d43547d2476..c7faf296a431 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -1127,7 +1127,6 @@ static int msm_dai_q6_dai_auxpcm_remove(struct snd_soc_dai *dai) return 0; } - static int msm_dai_q6_island_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1155,6 +1154,7 @@ static struct snd_kcontrol_new island_config_controls[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "?", + .info = snd_ctl_boolean_mono_info, .get = msm_dai_q6_island_mode_get, .put = msm_dai_q6_island_mode_put, .private_value = SOC_SINGLE_VALUE(0, 0, 1, 0, 0) @@ -1178,8 +1178,7 @@ static int msm_dai_q6_add_island_mx_ctls(struct snd_card *card, if (!mixer_str) return -ENOMEM; - snprintf(mixer_str, ctl_len + strlen(mx_ctl_name) + 1, - "%s %s", dai_name, mx_ctl_name); + snprintf(mixer_str, ctl_len, "%s %s", dai_name, mx_ctl_name); island_config_controls[0].name = mixer_str; ((struct soc_enum *) island_config_controls[0].private_value)->reg = dai_id; diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 73b743d32e74..f1f4df711955 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -462,7 +462,8 @@ static const char *const cdc_dma_rx_ch_text[] = {"One", "Two"}; static const char *const cdc_dma_tx_ch_text[] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; -static char const *cdc_dma_sample_rate_text[] = {"KHZ_8", "KHZ_16", +static char const *cdc_dma_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", "KHZ_32", "KHZ_44P1", "KHZ_48", "KHZ_88P2", "KHZ_96", "KHZ_176P4", "KHZ_192", "KHZ_352P8", "KHZ_384"}; @@ -6034,6 +6035,35 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .ops = &qcs405_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUIN_TDM_RX_0, + .stream_name = "Quinary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36928", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &qcs405_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_TDM_TX_0, + .stream_name = "Quinary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36929", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &qcs405_tdm_be_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link msm_tasha_be_dai_links[] = { diff --git a/config/qcs405auto.conf b/config/qcs405auto.conf index b2c80cd7ce4e..a30f01a635c3 100644 --- a/config/qcs405auto.conf +++ b/config/qcs405auto.conf @@ -26,6 +26,7 @@ CONFIG_SND_SOC_WCD_MBHC_LEGACY=m CONFIG_SND_SOC_QDSP6V2=m CONFIG_QTI_PP=m CONFIG_SND_HWDEP_ROUTING=m +CONFIG_AFE_HWDEP=m CONFIG_DTS_EAGLE=m CONFIG_DOLBY_DS2=m CONFIG_DOLBY_LICENSE=m diff --git a/config/qcs405autoconf.h b/config/qcs405autoconf.h index 039b67baf9e9..75332935ea6e 100644 --- a/config/qcs405autoconf.h +++ b/config/qcs405autoconf.h @@ -38,6 +38,7 @@ #define CONFIG_SND_SOC_QDSP6V2 1 #define CONFIG_QTI_PP 1 #define CONFIG_SND_HWDEP_ROUTING 1 +#define CONFIG_AFE_HWDEP 1 #define CONFIG_DTS_EAGLE 1 #define CONFIG_DOLBY_DS2 1 #define CONFIG_DOLBY_LICENSE 1 diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 5320ef4937c7..a2f4046b41b0 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -3513,10 +3513,11 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, /* send VAD configuration if is enabled */ if (this_afe.vad_cfg[port_index].is_enable) { ret = afe_send_port_vad_cfg_params(port_id); - if (ret) + if (ret) { pr_err("%s: afe send VAD config failed %d\n", __func__, ret); goto fail_cmd; + } } } -- GitLab From 5873163b9dd8de30247fd295b5d83242685b5160 Mon Sep 17 00:00:00 2001 From: David Ng Date: Fri, 22 Jun 2018 18:33:02 -0700 Subject: [PATCH 0390/1645] audio: uapi: Add kernel symlink dependency make-style Add kernel symlink creation $(KERNEL_USR) as make-style dependency. The LOCAL_ADDITIONAL_DEPENDENCIES flag in place is not active for the generated-source mechanism. Change-Id: I9b93679bf73cf28c244119ec34a440775579b18a --- include/uapi/Android.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/Android.mk b/include/uapi/Android.mk index 36bcfdefae32..b8c209adaa0e 100644 --- a/include/uapi/Android.mk +++ b/include/uapi/Android.mk @@ -17,6 +17,7 @@ LOCAL_MODULE := audio_kernel_headers LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_PREBUILT_INT_KERNEL) GEN := $(addprefix $(UAPI_OUT)/,$(AUDIO_KERNEL_HEADERS)) +$(GEN): $(KERNEL_USR) $(GEN): PRIVATE_PATH := $(MYLOCAL_PATH) $(GEN): PRIVATE_CUSTOM_TOOL = $(shell cd $(PRODUCT_OUT)/obj/KERNEL_OBJ; $(BUILD_ROOT_RELATIVE)$(HEADER_INSTALL_DIR)/headers_install.sh $(BUILD_ROOT_RELATIVE)$(dir $@) $(BUILD_ROOT_RELATIVE)$(subst $(UAPI_OUT),$(MYLOCAL_PATH),$(dir $@)) $(notdir $@)) $(GEN): $(addprefix $(MYLOCAL_PATH)/,$(AUDIO_KERNEL_HEADERS)) -- GitLab From 50bb24444e309ec2dd5f1d678df48cdfde17edb6 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Thu, 12 Jul 2018 11:31:37 -0700 Subject: [PATCH 0391/1645] dsp: Remove wait for preload command Remove wait and wake up for module load/unload commands in order to reduce audio startup and teardown latencies. Change-Id: I6ce67656c4ec8a843b9c2dd75176155ca0ce61df Signed-off-by: Vikram Panduranga --- dsp/q6core.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/dsp/q6core.c b/dsp/q6core.c index debcc26ff3b5..51b8ef0c4e9d 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -299,8 +299,6 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) "AVCS_CMD_LOAD_TOPO_MODULES" : "AVCS_CMD_UNLOAD_TOPO_MODULES", adsp_err_get_err_str(payload1[1])); - q6core_lcl.bus_bw_resp_received = 1; - wake_up(&q6core_lcl.bus_bw_req_wait); break; default: pr_err("%s: Invalid cmd rsp[0x%x][0x%x] opcode %d\n", @@ -848,25 +846,14 @@ int32_t q6core_load_unload_topo_modules(uint32_t topo_id, AVCS_CMD_UNLOAD_TOPO_MODULES; load_unload_topo_modules.topology_id = topo_id; - q6core_lcl.bus_bw_resp_received = 0; ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) &load_unload_topo_modules); if (ret < 0) { pr_err("%s: Load/unload topo modules failed for topology = %d ret = %d\n", __func__, topo_id, ret); ret = -EINVAL; - goto done; } - ret = wait_event_timeout(q6core_lcl.bus_bw_req_wait, - (q6core_lcl.bus_bw_resp_received == 1), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout for load/unload topo modules\n", - __func__); - ret = -ETIME; - goto done; - } done: mutex_unlock(&(q6core_lcl.cmd_lock)); -- GitLab From 82777e54d56817c21f4e3bf708e480d8cf3c666f Mon Sep 17 00:00:00 2001 From: Sharad Sangle Date: Wed, 20 Jun 2018 19:06:08 +0530 Subject: [PATCH 0392/1645] asoc: dsp: add support for aptX adaptive Add support for new A2DP profile aptX adaptive. This is just like any other A2DP profiles. CRs-fixed: 2272343 Change-Id: I219dec038e84b7b98ebb2d5233ddf576c8bbe70a Signed-off-by: Sharad Sangle --- asoc/msm-dai-q6-v2.c | 11 +++++++++++ dsp/q6afe.c | 40 ++++++++++++++++++++++++++++++++------ include/dsp/apr_audio-v2.h | 27 +++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 6 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 5d43547d2476..7b29c5e74a6a 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -56,6 +56,7 @@ enum { ENC_FMT_APTX_HD = ASM_MEDIA_FMT_APTX_HD, ENC_FMT_CELT = ASM_MEDIA_FMT_CELT, ENC_FMT_LDAC = ASM_MEDIA_FMT_LDAC, + ENC_FMT_APTX_ADAPTIVE = ASM_MEDIA_FMT_APTX_ADAPTIVE, }; enum { @@ -2446,6 +2447,11 @@ static int msm_dai_q6_afe_enc_cfg_get(struct snd_kcontrol *kcontrol, &dai_data->enc_config.data, sizeof(struct asm_ldac_enc_cfg_t)); break; + case ENC_FMT_APTX_ADAPTIVE: + memcpy(ucontrol->value.bytes.data + format_size, + &dai_data->enc_config.data, + sizeof(struct asm_aptx_ad_enc_cfg_t)); + break; default: pr_debug("%s: unknown format = %d\n", __func__, dai_data->enc_config.format); @@ -2504,6 +2510,11 @@ static int msm_dai_q6_afe_enc_cfg_put(struct snd_kcontrol *kcontrol, ucontrol->value.bytes.data + format_size, sizeof(struct asm_ldac_enc_cfg_t)); break; + case ENC_FMT_APTX_ADAPTIVE: + memcpy(&dai_data->enc_config.data, + ucontrol->value.bytes.data + format_size, + sizeof(struct asm_aptx_ad_enc_cfg_t)); + break; default: pr_debug("%s: Ignore enc config for unknown format = %d\n", __func__, dai_data->enc_config.format); diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 5320ef4937c7..c651cfdbe372 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -3178,7 +3178,10 @@ static int q6afe_send_dec_config(u16 port_id, param_hdr.param_id = AFE_DECODER_PARAM_ID_DEPACKETIZER_ID; param_hdr.param_size = sizeof(struct avs_dec_depacketizer_id_param_t); dec_depkt_id_param.dec_depacketizer_id = - AFE_MODULE_ID_DEPACKETIZER_COP; + AFE_MODULE_ID_DEPACKETIZER_COP; + if (cfg->format == ASM_MEDIA_FMT_APTX_ADAPTIVE) + dec_depkt_id_param.dec_depacketizer_id = + AFE_MODULE_ID_DEPACKETIZER_COP_V1; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, @@ -3237,6 +3240,7 @@ static int q6afe_send_enc_config(u16 port_id, u32 enc_fmt; struct afe_enc_cfg_blk_param_t enc_blk_param; struct afe_param_id_aptx_sync_mode sync_mode_param; + struct afe_id_aptx_adaptive_enc_init aptx_adaptive_enc_init; struct avs_enc_packetizer_id_param_t enc_pkt_id_param; struct avs_enc_set_scrambler_param_t enc_set_scrambler_param; struct afe_enc_level_to_bitrate_map_param_t map_param; @@ -3249,6 +3253,7 @@ static int q6afe_send_enc_config(u16 port_id, memset(&enc_blk_param, 0, sizeof(enc_blk_param)); memset(&sync_mode_param, 0, sizeof(sync_mode_param)); + memset(&aptx_adaptive_enc_init, 0, sizeof(aptx_adaptive_enc_init)); memset(&enc_pkt_id_param, 0, sizeof(enc_pkt_id_param)); memset(&enc_set_scrambler_param, 0, sizeof(enc_set_scrambler_param)); memset(&map_param, 0, sizeof(map_param)); @@ -3257,8 +3262,9 @@ static int q6afe_send_enc_config(u16 port_id, memset(¶m_hdr, 0, sizeof(param_hdr)); if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 && - format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD && - format != ASM_MEDIA_FMT_CELT && format != ASM_MEDIA_FMT_LDAC) { + format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD && + format != ASM_MEDIA_FMT_CELT && format != ASM_MEDIA_FMT_LDAC && + format != ASM_MEDIA_FMT_APTX_ADAPTIVE) { pr_err("%s:Unsuppported format Ignore AFE config\n", __func__); return 0; } @@ -3324,7 +3330,25 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } } - + if (format == ASM_MEDIA_FMT_APTX_ADAPTIVE) { + pr_debug("%s: sending AFE_ID_APTX_ADAPTIVE_ENC_INIT to DSP\n", + __func__); + param_hdr.param_id = AFE_ID_APTX_ADAPTIVE_ENC_INIT; + param_hdr.param_size = + sizeof(struct afe_id_aptx_adaptive_enc_init); + aptx_adaptive_enc_init = + enc_blk_param.enc_blk_config.aptx_ad_config. + aptx_ad_cfg; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &aptx_adaptive_enc_init); + if (ret) { + pr_err("%s: AFE_ID_APTX_ADAPTIVE_ENC_INIT for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + } pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP\n", __func__); param_hdr.param_id = AFE_ENCODER_PARAM_ID_PACKETIZER_ID; @@ -3355,7 +3379,7 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } - if (format == ASM_MEDIA_FMT_LDAC) { + if (format == ASM_MEDIA_FMT_LDAC || format == ASM_MEDIA_FMT_APTX_ADAPTIVE) { pr_debug("%s:sending AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP to DSP payload", __func__); param_hdr.param_id = AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP; @@ -3379,7 +3403,11 @@ static int q6afe_send_enc_config(u16 port_id, AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION; param_hdr.param_size = sizeof(struct afe_enc_dec_imc_info_param_t); - imc_info_param.imc_info = + if (format == ASM_MEDIA_FMT_APTX_ADAPTIVE) + imc_info_param.imc_info = + cfg->aptx_ad_config.abr_cfg.imc_info; + else + imc_info_param.imc_info = cfg->ldac_config.abr_config.imc_info; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 535f09f1d3a9..337f66f27b25 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -3439,6 +3439,21 @@ struct afe_param_id_aptx_sync_mode { uint32_t sync_mode; } __packed; +#define AFE_ID_APTX_ADAPTIVE_ENC_INIT 0x00013324 + +struct afe_id_aptx_adaptive_enc_init +{ + uint32_t sampling_freq; + uint32_t mtu; + uint32_t channel_mode; + uint32_t min_sink_modeA; + uint32_t max_sink_modeA; + uint32_t min_sink_modeB; + uint32_t max_sink_modeB; + uint32_t min_sink_modeC; + uint32_t max_sink_modeC; +} __attribute__ ((packed)); + /* * Generic encoder module ID. * This module supports the following parameter IDs: @@ -3504,6 +3519,7 @@ struct afe_param_id_aptx_sync_mode { * Macro for defining the depacketizer ID: COP. */ #define AFE_MODULE_ID_DEPACKETIZER_COP 0x00013233 +#define AFE_MODULE_ID_DEPACKETIZER_COP_V1 0x000132E9 /* * Depacketizer type parameter for the #AVS_MODULE_ID_DECODER module. @@ -3693,6 +3709,9 @@ struct asm_aac_enc_cfg_v2_t { /* FMT ID for apt-X HD */ #define ASM_MEDIA_FMT_APTX_HD 0x00013200 +/* FMT ID for apt-X Adaptive */ +#define ASM_MEDIA_FMT_APTX_ADAPTIVE 0x00013204 + #define PCM_CHANNEL_L 1 #define PCM_CHANNEL_R 2 #define PCM_CHANNEL_C 3 @@ -3723,6 +3742,13 @@ struct asm_aptx_enc_cfg_t { struct asm_aptx_v2_enc_cfg_ext_t aptx_v2_cfg; } __packed; +struct asm_aptx_ad_enc_cfg_t +{ + struct asm_custom_enc_cfg_t custom_cfg; + struct afe_id_aptx_adaptive_enc_init aptx_ad_cfg; + struct afe_abr_enc_cfg_t abr_cfg; +} __attribute__ ((packed)); + #define ASM_MEDIA_FMT_CELT 0x00013221 struct asm_celt_specific_enc_cfg_t { /* @@ -3886,6 +3912,7 @@ union afe_enc_config_data { struct asm_celt_enc_cfg_t celt_config; struct asm_aptx_enc_cfg_t aptx_config; struct asm_ldac_enc_cfg_t ldac_config; + struct asm_aptx_ad_enc_cfg_t aptx_ad_config; }; struct afe_enc_config { -- GitLab From 0a915f8c6852a680fb2c6dcb202781c6dc3e25c7 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Mon, 9 Jul 2018 20:30:03 +0530 Subject: [PATCH 0393/1645] asoc: ext-clk: dynamically configure clk parent name Add support to dynamically configure clk parent name from device tree. Change-Id: I9ae0c34c248503625523a2d1e33d800b2138ed39 Signed-off-by: Surendar Karka --- asoc/codecs/audio-ext-clk-up.c | 39 ++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index 1b0b2198464c..1bcdbe3d74b8 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -47,6 +47,7 @@ struct audio_ext_clk_priv { int clk_src; struct afe_clk_set clk_cfg; struct audio_ext_clk audio_clk; + const char *clk_name; }; static inline struct audio_ext_clk_priv *to_audio_clk(struct clk_hw *hw) @@ -113,9 +114,34 @@ static void audio_ext_clk_unprepare(struct clk_hw *hw) iowrite32(0, pnctrl_info->base); } +static u8 audio_ext_clk_get_parent(struct clk_hw *hw) +{ + struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw); + int num_parents = clk_hw_get_num_parents(hw); + const char * const *parent_names = hw->init->parent_names; + u8 i = 0, ret = hw->init->num_parents + 1; + + if ((clk_priv->clk_src == AUDIO_EXT_CLK_PMI) && clk_priv->clk_name) { + for (i = 0; i < num_parents; i++) { + if (!strcmp(parent_names[i], clk_priv->clk_name)) + ret = i; + } + pr_debug("%s: parent index = %u\n", __func__, ret); + return ret; + } else + return 0; +} + static const struct clk_ops audio_ext_clk_ops = { .prepare = audio_ext_clk_prepare, .unprepare = audio_ext_clk_unprepare, + .get_parent = audio_ext_clk_get_parent, +}; + +static const char * const audio_ext_pmi_div_clk[] = { + "qpnp_clkdiv_1", + "pms405_div_clk1", + "pm6150_div_clk1", }; static struct audio_ext_clk audio_clk_array[] = { @@ -126,9 +152,9 @@ static struct audio_ext_clk audio_clk_array[] = { .div = 1, .hw.init = &(struct clk_init_data){ .name = "audio_ext_pmi_clk", - .parent_names = (const char *[]) - { "qpnp_clkdiv_1" }, - .num_parents = 1, + .parent_names = audio_ext_pmi_div_clk, + .num_parents = + ARRAY_SIZE(audio_ext_pmi_div_clk), .ops = &audio_ext_clk_ops, }, }, @@ -300,7 +326,7 @@ static int audio_ref_clk_probe(struct platform_device *pdev) __func__, clk_src); return -EINVAL; } - + clk_priv->clk_name = NULL; clk_priv->clk_src = clk_src; memcpy(&clk_priv->audio_clk, &audio_clk_array[clk_src], sizeof(struct audio_ext_clk)); @@ -329,6 +355,11 @@ static int audio_ref_clk_probe(struct platform_device *pdev) clk_priv->clk_cfg.clk_id, clk_priv->clk_src); platform_set_drvdata(pdev, clk_priv); + ret = of_property_read_string(pdev->dev.of_node, "pmic-clock-names", + &clk_priv->clk_name); + if (ret) + dev_dbg(&pdev->dev, "%s: could not find pmic clock names\n", + __func__); /* * property qcom,use-pinctrl to be defined in DTSI to val 1 * for clock nodes using pinctrl -- GitLab From d712cc7c15cd7411d2e0cdae5034348dfc2419bd Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 17 Jul 2018 23:43:21 +0530 Subject: [PATCH 0394/1645] asoc: audio-ext-clk: Add support for multiple lpass clock nodes In bolero, for VA and WSA macros require multiple lpass clock sources. Update audio clock driver to support lpass clocks instances as required for VA and WSA. Change-Id: I7bb676dcbd5c0db09079dd73a30d1b47ce0f8ace Signed-off-by: Laxminath Kasam --- asoc/codecs/audio-ext-clk-up.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index 1b0b2198464c..1ccca108fbc6 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -27,7 +27,10 @@ enum { AUDIO_EXT_CLK_PMI, AUDIO_EXT_CLK_LNBB2, AUDIO_EXT_CLK_LPASS, - AUDIO_EXT_CLK_MAX, + AUDIO_EXT_CLK_LPASS2, + AUDIO_EXT_CLK_LPASS3, + AUDIO_EXT_CLK_LPASS_MAX, + AUDIO_EXT_CLK_MAX = AUDIO_EXT_CLK_LPASS_MAX, }; struct pinctrl_info { @@ -60,7 +63,8 @@ static int audio_ext_clk_prepare(struct clk_hw *hw) struct pinctrl_info *pnctrl_info = &clk_priv->audio_clk.pnctrl_info; int ret; - if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS) { + if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS) && + (clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX)) { clk_priv->clk_cfg.enable = 1; ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg); if (ret < 0) { @@ -101,7 +105,8 @@ static void audio_ext_clk_unprepare(struct clk_hw *hw) } } - if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS) { + if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS) && + (clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX)) { clk_priv->clk_cfg.enable = 0; ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg); if (ret < 0) @@ -158,6 +163,28 @@ static struct audio_ext_clk audio_clk_array[] = { }, }, }, + { + .pnctrl_info = {NULL}, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_lpass_mclk2", + .ops = &audio_ext_clk_ops, + }, + }, + }, + { + .pnctrl_info = {NULL}, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_lpass_mclk3", + .ops = &audio_ext_clk_ops, + }, + }, + }, }; static int audio_get_pinctrl(struct platform_device *pdev) -- GitLab From 0c85700fdb8c73ee2cc457bcc451ecef71d8dada Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 17 Jul 2018 23:47:17 +0530 Subject: [PATCH 0395/1645] asoc: bolero: Fix wsa playback mute issue Update volatile registers list of bolero VA and WSA macros. Fix sequence for wsa mute and register access in regmap read/write. Change-Id: I7984f7e2309933536f3855f6fd4a2e2fd1c4d13b Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc-regmap.c | 26 +++++++++++++++++++++++++- asoc/codecs/bolero/bolero-cdc-utils.c | 12 ++++++------ asoc/codecs/bolero/wsa-macro.c | 10 +++++++--- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc-regmap.c b/asoc/codecs/bolero/bolero-cdc-regmap.c index f026c26f9aeb..ef5b5908591f 100644 --- a/asoc/codecs/bolero/bolero-cdc-regmap.c +++ b/asoc/codecs/bolero/bolero-cdc-regmap.c @@ -794,7 +794,31 @@ static bool bolero_is_writeable_register(struct device *dev, static bool bolero_is_volatile_register(struct device *dev, unsigned int reg) { - return true; + /* Update volatile list for rx/tx macros */ + switch (reg) { + case BOLERO_CDC_VA_TOP_CSR_CORE_ID_0: + case BOLERO_CDC_VA_TOP_CSR_CORE_ID_1: + case BOLERO_CDC_VA_TOP_CSR_CORE_ID_2: + case BOLERO_CDC_VA_TOP_CSR_CORE_ID_3: + case BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_MON_VAL: + case BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_ST: + case BOLERO_CDC_WSA_INTR_CTRL_PIN1_STATUS0: + case BOLERO_CDC_WSA_INTR_CTRL_PIN2_STATUS0: + case BOLERO_CDC_WSA_COMPANDER0_CTL6: + case BOLERO_CDC_WSA_COMPANDER1_CTL6: + case BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB: + case BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB: + case BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB: + case BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB: + case BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FIFO: + case BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB: + case BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB: + case BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB: + case BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB: + case BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FIFO: + return true; + } + return false; } const struct regmap_config bolero_regmap_config = { diff --git a/asoc/codecs/bolero/bolero-cdc-utils.c b/asoc/codecs/bolero/bolero-cdc-utils.c index ff056085d35b..b7f41420d0fe 100644 --- a/asoc/codecs/bolero/bolero-cdc-utils.c +++ b/asoc/codecs/bolero/bolero-cdc-utils.c @@ -84,17 +84,17 @@ static int regmap_bus_read(void *context, const void *reg, size_t reg_size, } mutex_lock(&priv->io_lock); for (i = 0; i < val_size; i++) { - __reg = reg_p[i] - macro_id_base_offset[macro_id]; + __reg = (reg_p[0] + i * 4) - macro_id_base_offset[macro_id]; ret = priv->read_dev(priv, macro_id, __reg, &temp); if (ret < 0) { dev_err_ratelimited(dev, "%s: Codec read failed (%d), reg: 0x%x, size:%zd\n", - __func__, ret, reg_p[i], val_size); + __func__, ret, reg_p[0] + i * 4, val_size); break; } ((u8 *)val)[i] = temp; dev_dbg(dev, "%s: Read 0x%02x from reg 0x%x\n", - __func__, temp, reg_p[i]); + __func__, temp, reg_p[0] + i * 4); } mutex_unlock(&priv->io_lock); @@ -137,16 +137,16 @@ static int regmap_bus_gather_write(void *context, } mutex_lock(&priv->io_lock); for (i = 0; i < val_size; i++) { - __reg = reg_p[i] - macro_id_base_offset[macro_id]; + __reg = (reg_p[0] + i * 4) - macro_id_base_offset[macro_id]; ret = priv->write_dev(priv, macro_id, __reg, ((u8 *)val)[i]); if (ret < 0) { dev_err_ratelimited(dev, "%s: Codec write failed (%d), reg:0x%x, size:%zd\n", - __func__, ret, reg_p[i], val_size); + __func__, ret, reg_p[0] + i * 4, val_size); break; } dev_dbg(dev, "Write %02x to reg 0x%x\n", ((u8 *)val)[i], - reg_p[i]); + reg_p[0] + i * 4); } mutex_unlock(&priv->io_lock); return ret; diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index ff15e14faa66..d73193c639f5 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -1330,10 +1330,12 @@ static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMU: snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x01); snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x10); - snd_soc_update_bits(codec, reg, 0x10, 0x00); if ((snd_soc_read(codec, reg_mix)) & 0x10) snd_soc_update_bits(codec, reg_mix, 0x10, 0x00); break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, reg, 0x10, 0x00); + break; case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x00); snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x00); @@ -1833,10 +1835,12 @@ static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = { SND_SOC_DAPM_MIXER_E("WSA_RX INT0 CHAIN", SND_SOC_NOPM, 0, 0, NULL, 0, wsa_macro_spk_boost_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MIXER_E("WSA_RX INT1 CHAIN", SND_SOC_NOPM, 0, 0, NULL, 0, wsa_macro_spk_boost_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_INPUT("VIINPUT_WSA"), -- GitLab From 2a935198bddb0e484a4501cb8ae1e2390b9b7e47 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 17 Jul 2018 23:57:26 +0530 Subject: [PATCH 0396/1645] asoc: qcs405: Update wsa cpu dai names In qcs405 machine driver, fix cpu dai names same as created in dai q6 driver. Change-Id: I364864ceac8bc555d0a1c982a06629bd5bc774ef Signed-off-by: Laxminath Kasam --- asoc/qcs405.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index ec3d7d955cc8..eed0bc62b05b 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -6605,7 +6605,7 @@ static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = { { .name = LPASS_BE_WSA_CDC_DMA_RX_0, .stream_name = "WSA CDC DMA0 Playback", - .cpu_dai_name = "msm-dai-cdc-dma.45056", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45056", .platform_name = "msm-pcm-routing", .codec_name = "bolero_codec", .codec_dai_name = "wsa_macro_rx1", @@ -6621,7 +6621,7 @@ static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = { { .name = LPASS_BE_WSA_CDC_DMA_TX_0, .stream_name = "WSA CDC DMA0 Capture", - .cpu_dai_name = "msm-dai-cdc-dma.45057", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45057", .platform_name = "msm-pcm-hostless", .codec_name = "bolero_codec", .codec_dai_name = "wsa_macro_vifeedback", @@ -6634,7 +6634,7 @@ static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = { { .name = LPASS_BE_WSA_CDC_DMA_RX_1, .stream_name = "WSA CDC DMA1 Playback", - .cpu_dai_name = "msm-dai-cdc-dma.45058", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45058", .platform_name = "msm-pcm-routing", .codec_name = "bolero_codec", .codec_dai_name = "wsa_macro_rx_mix", @@ -6649,7 +6649,7 @@ static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = { { .name = LPASS_BE_WSA_CDC_DMA_TX_1, .stream_name = "WSA CDC DMA1 Capture", - .cpu_dai_name = "msm-dai-cdc-dma.45059", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45059", .platform_name = "msm-pcm-routing", .codec_name = "bolero_codec", .codec_dai_name = "wsa_macro_echo", @@ -6660,20 +6660,6 @@ static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = { .ignore_suspend = 1, .ops = &msm_cdc_dma_be_ops, }, - { - .name = LPASS_BE_WSA_CDC_DMA_TX_2, - .stream_name = "WSA CDC DMA2 Capture", - .cpu_dai_name = "msm-dai-cdc-dma.45061", - .platform_name = "msm-pcm-routing", - .codec_name = "bolero_codec", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_cdc_dma_be_ops, - }, }; static struct snd_soc_dai_link msm_va_cdc_dma_be_dai_links[] = { @@ -7276,7 +7262,7 @@ static int msm_init_wsa_dev(struct platform_device *pdev, } if (found < wsa_max_devs) { - dev_dbg(&pdev->dev, + dev_err(&pdev->dev, "%s: failed to find %d components. Found only %d\n", __func__, wsa_max_devs, found); return -EPROBE_DEFER; -- GitLab From 03c84fa06ef22f26aad516af3decb0447efdfeb5 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 21 Jun 2018 18:53:00 +0530 Subject: [PATCH 0397/1645] asoc: bolero: Add codec entry for bolero for rtac support Add codec entry for bolero codec under proc codecs list. Change-Id: I4155dd92b57423b9927bebc9b66fcb491f7ddc57 Signed-off-by: Laxminath Kasam --- asoc/qcs405.c | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index ec3d7d955cc8..f6ccd976ceda 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -37,6 +37,7 @@ #include "codecs/wsa881x.h" #include "codecs/csra66x0/csra66x0.h" #include +#include "codecs/bolero/bolero-cdc.h" #define DRV_NAME "qcs405-asoc-snd" @@ -4114,7 +4115,6 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_card *card; - struct snd_info_entry *entry; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); @@ -4179,15 +4179,15 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) } card = rtd->card->snd_card; - entry = snd_info_create_subdir(card->module, "codecs", - card->proc_root); - if (!entry) { - pr_debug("%s: Cannot create codecs module entry\n", + if (!pdata->codec_root) + pdata->codec_root = snd_info_create_subdir(card->module, + "codecs", card->proc_root); + if (!pdata->codec_root) { + dev_dbg(codec->dev, "%s: Cannot create codecs module entry\n", __func__); ret = 0; goto err; } - pdata->codec_root = entry; tasha_codec_info_create_codec_entry(pdata->codec_root, codec); codec_reg_done = true; @@ -4202,6 +4202,9 @@ static int msm_va_cdc_dma_init(struct snd_soc_pcm_runtime *rtd) int ret = 0; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_card *card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); ret = snd_soc_add_codec_controls(codec, msm_snd_va_controls, ARRAY_SIZE(msm_snd_va_controls)); @@ -4225,6 +4228,18 @@ static int msm_va_cdc_dma_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_sync(dapm); + card = rtd->card->snd_card; + if (!pdata->codec_root) + pdata->codec_root = snd_info_create_subdir(card->module, + "codecs", card->proc_root); + if (!pdata->codec_root) { + dev_dbg(codec->dev, "%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto done; + } + bolero_info_create_codec_entry(pdata->codec_root, codec); +done: return ret; } @@ -4233,11 +4248,14 @@ static int msm_wsa_cdc_dma_init(struct snd_soc_pcm_runtime *rtd) int ret = 0; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_card *card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); ret = snd_soc_add_codec_controls(codec, msm_snd_wsa_controls, ARRAY_SIZE(msm_snd_wsa_controls)); if (ret < 0) { - dev_err(codec->dev, "%s: add_codec_controls for va failed, err %d\n", + dev_err(codec->dev, "%s: add_codec_controls for wsa failed, err %d\n", __func__, ret); return ret; } @@ -4251,6 +4269,18 @@ static int msm_wsa_cdc_dma_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_sync(dapm); + card = rtd->card->snd_card; + if (!pdata->codec_root) + pdata->codec_root = snd_info_create_subdir(card->module, + "codecs", card->proc_root); + if (!pdata->codec_root) { + dev_dbg(codec->dev, "%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto done; + } + bolero_info_create_codec_entry(pdata->codec_root, codec); +done: return ret; } -- GitLab From a92bc13a24e1c1604f312949c9b0dfaa8531cee4 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 19 Jul 2018 12:09:28 +0530 Subject: [PATCH 0398/1645] asoc: qcs405: Update gain offset and mode for wsa8810 Update the wsa-macro gain offset and mode for wsa8810 variant. Change-Id: If0a0f08290ef91944f1fbbfab02d6b52d3ea6966 Signed-off-by: Laxminath Kasam --- asoc/qcs405.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index f6ccd976ceda..6ec2a0da7028 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -38,6 +38,7 @@ #include "codecs/csra66x0/csra66x0.h" #include #include "codecs/bolero/bolero-cdc.h" +#include "codecs/bolero/wsa-macro.h" #define DRV_NAME "qcs405-asoc-snd" @@ -4248,6 +4249,7 @@ static int msm_wsa_cdc_dma_init(struct snd_soc_pcm_runtime *rtd) int ret = 0; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_component *aux_comp; struct snd_card *card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); @@ -4269,6 +4271,26 @@ static int msm_wsa_cdc_dma_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_sync(dapm); + /* + * Send speaker configuration only for WSA8810. + * Default configuration is for WSA8815. + */ + dev_dbg(codec->dev, "%s: Number of aux devices: %d\n", + __func__, rtd->card->num_aux_devs); + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->component_dev_list)) { + aux_comp = list_first_entry( + &rtd->card->component_dev_list, + struct snd_soc_component, + card_aux_list); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { + wsa_macro_set_spkr_mode(rtd->codec, + WSA_MACRO_SPKR_MODE_1); + wsa_macro_set_spkr_gain_offset(rtd->codec, + WSA_MACRO_GAIN_OFFSET_M1P5_DB); + } + } card = rtd->card->snd_card; if (!pdata->codec_root) pdata->codec_root = snd_info_create_subdir(card->module, -- GitLab From fbcaf324286ded278aa46233157da6cf944413b3 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 18 Jul 2018 00:38:14 +0530 Subject: [PATCH 0399/1645] soc: swr-ctrl: Update master controller for WSA mute issue Add delay in master read/write fifo for slave register update. Handle pm runtime for clock disable to happen after usecase. Change-Id: Ia1abc4ee3db500cbc8f42b9f08760463fb77acef Signed-off-by: Laxminath Kasam --- include/soc/swr-wcd.h | 5 +-- soc/Kbuild | 1 + soc/swr-mstr-ctrl.c | 79 ++++++++++++++++++++++++++++++------------- soc/swr-mstr-ctrl.h | 1 + 4 files changed, 60 insertions(+), 26 deletions(-) diff --git a/include/soc/swr-wcd.h b/include/soc/swr-wcd.h index f6ff61a22fe2..360815043709 100644 --- a/include/soc/swr-wcd.h +++ b/include/soc/swr-wcd.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. +/* Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -30,7 +30,8 @@ struct swr_mstr_port { u8 *port; }; -#if IS_ENABLED(CONFIG_SOUNDWIRE_WCD_CTRL) +#if (IS_ENABLED(CONFIG_SOUNDWIRE_WCD_CTRL) || \ + IS_ENABLED(CONFIG_SOUNDWIRE_MSTR_CTRL)) extern int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data); #else /* CONFIG_SOUNDWIRE_WCD_CTRL */ static inline int swrm_wcd_notify(struct platform_device *pdev, u32 id, diff --git a/soc/Kbuild b/soc/Kbuild index de56a2b07374..acee7f646540 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -150,6 +150,7 @@ obj-$(CONFIG_SOUNDWIRE) += swr_dlkm.o swr_dlkm-y := $(SWR_OBJS) obj-$(CONFIG_SOUNDWIRE_WCD_CTRL) += swr_ctrl_dlkm.o +obj-$(CONFIG_SOUNDWIRE_MSTR_CTRL) += swr_ctrl_dlkm.o swr_ctrl_dlkm-y := $(SWR_CTRL_OBJS) # inject some build related information diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 4c5c3bd21354..68354b81367f 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -69,6 +69,8 @@ enum { #define SWR_MSTR_RD_BUF_LEN 8 #define SWR_MSTR_WR_BUF_LEN 32 +#define MAX_FIFO_RD_FAIL_RETRY 3 + static struct swr_mstr_ctrl *dbgswrm; static struct dentry *debugfs_swrm_dent; static struct dentry *debugfs_peek; @@ -243,7 +245,7 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) static int swrm_ahb_write(struct swr_mstr_ctrl *swrm, u16 reg, u32 *value) { - u32 temp = (u32)(*value) & 0x000000FF; + u32 temp = (u32)(*value); int ret; ret = swrm_clk_request(swrm, TRUE); @@ -253,7 +255,7 @@ static int swrm_ahb_write(struct swr_mstr_ctrl *swrm, iowrite32(temp, swrm->swrm_dig_base + reg); - swrm_clk_request(swrm, TRUE); + swrm_clk_request(swrm, FALSE); return 0; } @@ -261,7 +263,7 @@ static int swrm_ahb_write(struct swr_mstr_ctrl *swrm, static int swrm_ahb_read(struct swr_mstr_ctrl *swrm, u16 reg, u32 *value) { - u32 temp; + u32 temp = 0; int ret; ret = swrm_clk_request(swrm, TRUE); @@ -270,7 +272,7 @@ static int swrm_ahb_read(struct swr_mstr_ctrl *swrm, return -EINVAL; temp = ioread32(swrm->swrm_dig_base + reg); - *value = (u8)temp; + *value = temp; swrm_clk_request(swrm, FALSE); return 0; } @@ -302,8 +304,11 @@ static int swr_master_bulk_write(struct swr_mstr_ctrl *swrm, u32 *reg_addr, if (swrm->bulk_write) swrm->bulk_write(swrm->handle, reg_addr, val, length); else { - for (i = 0; i < length; i++) + for (i = 0; i < length; i++) { + /* wait for FIFO WR command to complete to avoid overflow */ + usleep_range(100, 105); swr_master_write(swrm, reg_addr[i], val[i]); + } } return 0; } @@ -318,10 +323,8 @@ static int swrm_get_port_config(struct swr_mstr_ctrl *swrm) u8 master_device_id; int i; - if (swrm->version == SWRM_VERSION_1_5) - master_device_id = swr_master_read(swrm, SWRM_COMP_MASTER_ID); - else - master_device_id = MASTER_ID_WSA; + /* update device_id for tx/rx */ + master_device_id = MASTER_ID_WSA; switch (master_device_id & MASTER_ID_MASK) { case MASTER_ID_WSA: @@ -398,15 +401,30 @@ static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, u32 len) { u32 val; + u32 retry_attempt = 0; val = swrm_get_packed_reg_val(&swrm->rcmd_id, len, dev_addr, reg_addr); + /* wait for FIFO RD to complete to avoid overflow */ + usleep_range(100, 105); swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val); - + /* wait for FIFO RD CMD complete to avoid overflow */ + usleep_range(250, 255); +retry_read: *cmd_data = swr_master_read(swrm, SWRM_CMD_FIFO_RD_FIFO_ADDR); dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, cmd_id, dev_addr, *cmd_data); - + if ((((*cmd_data) & 0xF00) >> 8) != swrm->rcmd_id) { + if (retry_attempt < MAX_FIFO_RD_FAIL_RETRY) { + /* wait 500 us before retry on fifo read failure */ + usleep_range(500, 505); + retry_attempt++; + goto retry_read; + } else { + dev_err_ratelimited(swrm->dev, + "%s: failed to read fifo\n", __func__); + } + } return 0; } @@ -422,12 +440,12 @@ static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data, else val = swrm_get_packed_reg_val(&cmd_id, cmd_data, dev_addr, reg_addr); - dev_dbg(swrm->dev, - "%s: reg: 0x%x, cmd_id: 0x%x, dev_num: 0x%x, cmd_data: 0x%x\n", - __func__, reg_addr, cmd_id, dev_addr, cmd_data); + "%s: reg: 0x%x, cmd_id: 0x%x, val:0x%x, dev_num: 0x%x, cmd_data: 0x%x\n", + __func__, reg_addr, cmd_id, val, dev_addr, cmd_data); + /* wait for FIFO WR command to complete to avoid overflow */ + usleep_range(250, 255); swr_master_write(swrm, SWRM_CMD_FIFO_WR_CMD, val); - if (cmd_id == 0xF) { /* * sleep for 10ms for MSM soundwire variant to allow broadcast @@ -806,9 +824,8 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) } mutex_lock(&swrm->mlock); - /* wakeup soundwire master if in sleep */ - pm_runtime_get_sync(swrm->dev); - + if (enable) + pm_runtime_get_sync(swrm->dev); bank = get_inactive_bank_num(swrm); if (enable) { @@ -816,6 +833,8 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) if (ret) { /* cannot accommodate ports */ swrm_cleanup_disabled_port_reqs(master); + pm_runtime_mark_last_busy(swrm->dev); + pm_runtime_put_autosuspend(swrm->dev); mutex_unlock(&swrm->mlock); return -EINVAL; } @@ -858,8 +877,6 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) else { swrm_disable_ports(master, inactive_bank); swrm_cleanup_disabled_port_reqs(master); - } - if (!swrm_is_port_en(master)) { dev_dbg(&master->dev, "%s: pm_runtime auto suspend triggered\n", __func__); pm_runtime_mark_last_busy(swrm->dev); @@ -1300,8 +1317,9 @@ static int swrm_probe(struct platform_device *pdev) ret = -EINVAL; goto err_pdata_fail; } - if (!(of_property_read_u32(pdev->dev.of_node, "swrm-io-base", NULL))) - swrm->swrm_base_reg = of_property_read_u32(pdev->dev.of_node, + if (!(of_property_read_u32(pdev->dev.of_node, + "swrm-io-base", &swrm->swrm_base_reg))) + ret = of_property_read_u32(pdev->dev.of_node, "swrm-io-base", &swrm->swrm_base_reg); if (!swrm->swrm_base_reg) { swrm->read = pdata->read; @@ -1414,6 +1432,19 @@ static int swrm_probe(struct platform_device *pdev) for (i = 0 ; i < SWR_MSTR_PORT_LEN; i++) INIT_LIST_HEAD(&swrm->mport_cfg[i].port_req_list); + ret = of_property_read_u32(swrm->dev->of_node, "qcom,swr-num-dev", + &swrm->num_dev); + if (ret) { + dev_dbg(&pdev->dev, "%s: Looking up %s property failed\n", + __func__, "qcom,swr-num-dev"); + } else { + if (swrm->num_dev > SWR_MAX_SLAVE_DEVICES) { + dev_err(&pdev->dev, "%s: num_dev %d > max limit %d\n", + __func__, swrm->num_dev, SWR_MAX_SLAVE_DEVICES); + ret = -EINVAL; + goto err_pdata_fail; + } + } if (swrm->reg_irq) { ret = swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, SWR_IRQ_REGISTER); @@ -1427,12 +1458,12 @@ static int swrm_probe(struct platform_device *pdev) if (swrm->irq < 0) { dev_err(swrm->dev, "%s() error getting irq hdle: %d\n", __func__, swrm->irq); - goto err_pdata_fail; + goto err_irq_fail; } ret = request_threaded_irq(swrm->irq, NULL, swr_mstr_interrupt, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, "swr_master_irq", swrm); if (ret) { dev_err(swrm->dev, "%s: Failed to request irq %d\n", diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 75d79c23ceb0..17d6c938c72f 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -30,6 +30,7 @@ #define SWR_MAX_CH_PER_PORT 8 +#define SWR_MAX_SLAVE_DEVICES 11 enum { SWR_MSTR_PAUSE, -- GitLab From 9b51e3e0ca88ead0dcb0cb90e8779f21cc584c65 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 21 Jul 2018 05:20:10 +0530 Subject: [PATCH 0400/1645] ASoC: audio-ext-clk: Replace clock dummy ops Replace clock framework's clock dummy ops with audio external clock ops to access correct structure that avoids out of bounds memory access. Change-Id: I51db63bba414cff0343cbf68e90b1e1bbf7929ac Signed-off-by: Sudheer Papothi --- asoc/codecs/audio-ext-clk-up.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index 1bcdbe3d74b8..9f2e4022bccd 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -144,6 +144,21 @@ static const char * const audio_ext_pmi_div_clk[] = { "pm6150_div_clk1", }; +static int audio_ext_clk_dummy_prepare(struct clk_hw *hw) +{ + return 0; +} + +static void audio_ext_clk_dummy_unprepare(struct clk_hw *hw) +{ + +} + +static const struct clk_ops audio_ext_clk_dummy_ops = { + .prepare = audio_ext_clk_dummy_prepare, + .unprepare = audio_ext_clk_dummy_unprepare, +}; + static struct audio_ext_clk audio_clk_array[] = { { .pnctrl_info = {NULL}, @@ -169,7 +184,7 @@ static struct audio_ext_clk audio_clk_array[] = { .parent_names = (const char *[]) { "ln_bb_clk2" }, .num_parents = 1, - .ops = &clk_dummy_ops, + .ops = &audio_ext_clk_dummy_ops, }, }, }, -- GitLab From d7c45292bada143aa6ccf4176f8b59f0ade4e1aa Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Fri, 20 Jul 2018 15:01:29 +0530 Subject: [PATCH 0401/1645] asoc: qcs405: Fix FE DAIs for hostless Fix hostless FE DAIs for HFP and speaker protection usecases Change-Id: If57b1d02f89923d9ce2fbefcec600e7f833a7c91 Signed-off-by: Mangesh Kunchamwar --- asoc/qcs405.c | 197 +++++++++++++------------------------------------- 1 file changed, 51 insertions(+), 146 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index eed0bc62b05b..1ee8f4cccbb1 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -4425,60 +4425,6 @@ static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream, return ret; } -static int msm_slimbus_2_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; - unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0; - unsigned int num_tx_ch = 0; - unsigned int num_rx_ch = 0; - int ret = 0; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - num_rx_ch = params_channels(params); - pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__, - codec_dai->name, codec_dai->id, num_rx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map, err:%d\n", - __func__, ret); - goto err; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, - num_rx_ch, rx_ch); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto err; - } - } else { - num_tx_ch = params_channels(params); - pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__, - codec_dai->name, codec_dai->id, num_tx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get tx codec chan map, err:%d\n", - __func__, ret); - goto err; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, - num_tx_ch, tx_ch, 0, 0); - if (ret < 0) { - pr_err("%s: failed to set tx cpu chan map, err:%d\n", - __func__, ret); - goto err; - } - } - -err: - return ret; -} - static int msm_wcn_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -5130,10 +5076,6 @@ static struct snd_soc_ops msm_be_ops = { .hw_params = msm_snd_hw_params, }; -static struct snd_soc_ops msm_slimbus_2_be_ops = { - .hw_params = msm_slimbus_2_hw_params, -}; - static struct snd_soc_ops msm_wcn_ops = { .hw_params = msm_wcn_hw_params, }; @@ -5246,24 +5188,6 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, - /* Hostless PCM purpose */ - { - .name = "CDC_DMA Hostless", - .stream_name = "CDC_DMA Hostless", - .cpu_dai_name = "CDC_DMA_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, { .name = "MSM AFE-PCM RX", .stream_name = "AFE-PROXY RX", @@ -5725,40 +5649,15 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, -}; - -static struct snd_soc_dai_link msm_tasha_fe_dai_links[] = { - /* Ultrasound RX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Playback", - .stream_name = "SLIMBUS_2 Hostless Playback", - .cpu_dai_name = "msm-dai-q6-dev.16388", - .platform_name = "msm-pcm-hostless", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx2", - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm_slimbus_2_be_ops, - }, - /* Ultrasound TX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Capture", - .stream_name = "SLIMBUS_2 Hostless Capture", - .cpu_dai_name = "msm-dai-q6-dev.16389", - .platform_name = "msm-pcm-hostless", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx2", - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm_slimbus_2_be_ops, - }, + /* Hostless PCM purpose */ { - .name = "SLIMBUS_6 Hostless Playback", - .stream_name = "SLIMBUS_6 Hostless", - .cpu_dai_name = "SLIMBUS6_HOSTLESS", + .name = "CDC_DMA Hostless", + .stream_name = "CDC_DMA Hostless", + .cpu_dai_name = "CDC_DMA_HOSTLESS", .platform_name = "msm-pcm-hostless", .dynamic = 1, .dpcm_playback = 1, + .dpcm_capture = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, @@ -5770,6 +5669,22 @@ static struct snd_soc_dai_link msm_tasha_fe_dai_links[] = { }, }; +static struct snd_soc_dai_link msm_bolero_fe_dai_links[] = { + { + .name = LPASS_BE_WSA_CDC_DMA_TX_0, + .stream_name = "WSA CDC DMA0 Capture", + .cpu_dai_name = "msm-dai-cdc-dma.45057", + .platform_name = "msm-pcm-hostless", + .codec_name = "bolero_codec", + .codec_dai_name = "wsa_macro_vifeedback", + .id = MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_cdc_dma_be_ops, + }, +}; + static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { { .name = MSM_DAILINK_NAME(ASM Loopback), @@ -6618,19 +6533,6 @@ static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = { .ignore_suspend = 1, .ops = &msm_cdc_dma_be_ops, }, - { - .name = LPASS_BE_WSA_CDC_DMA_TX_0, - .stream_name = "WSA CDC DMA0 Capture", - .cpu_dai_name = "msm-dai-cdc-dma-dev.45057", - .platform_name = "msm-pcm-hostless", - .codec_name = "bolero_codec", - .codec_dai_name = "wsa_macro_vifeedback", - .id = MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm_cdc_dma_be_ops, - }, { .name = LPASS_BE_WSA_CDC_DMA_RX_1, .stream_name = "WSA CDC DMA1 Playback", @@ -6696,7 +6598,6 @@ static struct snd_soc_dai_link msm_va_cdc_dma_be_dai_links[] = { static struct snd_soc_dai_link msm_qcs405_dai_links[ ARRAY_SIZE(msm_common_dai_links) + - ARRAY_SIZE(msm_tasha_fe_dai_links) + ARRAY_SIZE(msm_common_misc_fe_dai_links) + ARRAY_SIZE(msm_common_be_dai_links) + ARRAY_SIZE(msm_tasha_be_dai_links) + @@ -6704,7 +6605,8 @@ static struct snd_soc_dai_link msm_qcs405_dai_links[ ARRAY_SIZE(msm_mi2s_be_dai_links) + ARRAY_SIZE(msm_auxpcm_be_dai_links) + ARRAY_SIZE(msm_va_cdc_dma_be_dai_links) + - ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links)]; + ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links) + + ARRAY_SIZE(msm_bolero_fe_dai_links)]; static int msm_snd_card_tasha_late_probe(struct snd_soc_card *card) { @@ -6970,20 +6872,22 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) sizeof(msm_common_dai_links)); total_links += ARRAY_SIZE(msm_common_dai_links); - rc = of_property_read_u32(dev->of_node, "qcom,tasha-codec", - &tasha_codec); + + rc = of_property_read_u32(dev->of_node, "qcom,wsa-bolero-codec", + &wsa_bolero_codec); if (rc) { - dev_dbg(dev, "%s: No DT match tasha codec\n", + dev_dbg(dev, "%s: No DT match WSA Macro codec\n", __func__); } else { - if (tasha_codec) { - dev_dbg(dev, "%s(): Tasha codec is present\n", + if (wsa_bolero_codec) { + dev_dbg(dev, "%s(): WSA macro in bolero codec present\n", __func__); + memcpy(msm_qcs405_dai_links + total_links, - msm_tasha_fe_dai_links, - sizeof(msm_tasha_fe_dai_links)); + msm_bolero_fe_dai_links, + sizeof(msm_bolero_fe_dai_links)); total_links += - ARRAY_SIZE(msm_tasha_fe_dai_links); + ARRAY_SIZE(msm_bolero_fe_dai_links); } } @@ -6999,11 +6903,19 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) total_links += ARRAY_SIZE(msm_common_be_dai_links); - if (tasha_codec) { - memcpy(msm_qcs405_dai_links + total_links, + rc = of_property_read_u32(dev->of_node, "qcom,tasha-codec", + &tasha_codec); + if (rc) { + dev_dbg(dev, "%s: No DT match tasha codec\n", + __func__); + } else { + if (tasha_codec) { + memcpy(msm_qcs405_dai_links + total_links, msm_tasha_be_dai_links, sizeof(msm_tasha_be_dai_links)); - total_links += ARRAY_SIZE(msm_tasha_be_dai_links); + total_links += + ARRAY_SIZE(msm_tasha_be_dai_links); + } } rc = of_property_read_u32(dev->of_node, "qcom,va-bolero-codec", @@ -7024,22 +6936,15 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) } } - rc = of_property_read_u32(dev->of_node, "qcom,wsa-bolero-codec", - &wsa_bolero_codec); - if (rc) { - dev_dbg(dev, "%s: No DT match WSA Macro codec\n", + if (wsa_bolero_codec) { + dev_dbg(dev, "%s(): WSAmacro in bolero codec present\n", __func__); - } else { - if (wsa_bolero_codec) { - dev_dbg(dev, "%s(): WSAmacro in bolero codec present\n", - __func__); - memcpy(msm_qcs405_dai_links + total_links, - msm_wsa_cdc_dma_be_dai_links, - sizeof(msm_wsa_cdc_dma_be_dai_links)); - total_links += - ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links); - } + memcpy(msm_qcs405_dai_links + total_links, + msm_wsa_cdc_dma_be_dai_links, + sizeof(msm_wsa_cdc_dma_be_dai_links)); + total_links += + ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links); } rc = of_property_read_u32(dev->of_node, "qcom,mi2s-audio-intf", -- GitLab From 20f6c1416f7d4e853d7a3fc3ba3fe71a2ee07217 Mon Sep 17 00:00:00 2001 From: Romed Schur Date: Thu, 19 Jul 2018 18:16:24 +0200 Subject: [PATCH 0402/1645] asoc: codecs: Fix recovery behavior for CSRA66X0 Fix recovery behavior for CSRA66X0 codec to recover from fault state and add debugfs interface. CRs-Fixed: 2283380 Change-Id: I796b9e3b36db851f2bf1469e324a7c347510e232 Signed-off-by: Romed Schur --- asoc/codecs/csra66x0/csra66x0.c | 201 +++++++++++++++++++++++++++++++- 1 file changed, 197 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/csra66x0/csra66x0.c b/asoc/codecs/csra66x0/csra66x0.c index e9e11cb3872f..a6460a9237fc 100644 --- a/asoc/codecs/csra66x0/csra66x0.c +++ b/asoc/codecs/csra66x0/csra66x0.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "csra66x0.h" /* CSRA66X0 register default values */ @@ -258,8 +260,137 @@ struct csra66x0_priv { u32 irq_active_low; u32 in_cluster; u32 is_master; +#if IS_ENABLED(CONFIG_DEBUG_FS) + struct dentry *debugfs_dir; + struct dentry *debugfs_file_wo; + struct dentry *debugfs_file_ro; +#endif /* CONFIG_DEBUG_FS */ }; +#if IS_ENABLED(CONFIG_DEBUG_FS) +static int debugfs_codec_open_op(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static int debugfs_get_parameters(char *buf, u32 *param1, int num_of_par) +{ + char *token; + int base, cnt; + + token = strsep(&buf, " "); + for (cnt = 0; cnt < num_of_par; cnt++) { + if (token) { + if ((token[1] == 'x') || (token[1] == 'X')) + base = 16; + else + base = 10; + + if (kstrtou32(token, base, ¶m1[cnt]) != 0) + return -EINVAL; + + token = strsep(&buf, " "); + } else { + return -EINVAL; + } + } + return 0; +} + +static ssize_t debugfs_codec_write_op(struct file *filp, + const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + struct csra66x0_priv *csra66x0 = + (struct csra66x0_priv *) filp->private_data; + struct snd_soc_codec *codec = csra66x0->codec; + char lbuf[32]; + int rc; + u32 param[2]; + + if (!filp || !ppos || !ubuf) + return -EINVAL; + if (cnt > sizeof(lbuf) - 1) + return -EINVAL; + rc = copy_from_user(lbuf, ubuf, cnt); + if (rc) + return -EFAULT; + lbuf[cnt] = '\0'; + rc = debugfs_get_parameters(lbuf, param, 2); + if ((param[0] < CSRA66X0_AUDIO_IF_RX_CONFIG1) + || (param[0] > CSRA66X0_MAX_REGISTER_ADDR)) { + dev_err(codec->dev, "%s: register address 0x%04X out of range\n", + __func__, param[0]); + return -EINVAL; + } + if ((param[1] < 0) || (param[1] > 255)) { + dev_err(codec->dev, "%s: register data 0x%02X out of range\n", + __func__, param[1]); + return -EINVAL; + } + if (rc == 0) + { + rc = cnt; + dev_info(codec->dev, "%s: reg[0x%04X]=0x%02X\n", + __func__, param[0], param[1]); + snd_soc_write(codec, param[0], param[1]); + } else { + dev_err(codec->dev, "%s: write to register addr=0x%04X failed\n", + __func__, param[0]); + } + return rc; +} + +static ssize_t debugfs_csra66x0_reg_show(struct snd_soc_codec *codec, + char __user *ubuf, size_t count, loff_t *ppos) +{ + int i, reg_val, len; + ssize_t total = 0; + char tmp_buf[20]; + + if (!ubuf || !ppos || !codec || *ppos < 0) + return -EINVAL; + + for (i = ((int) *ppos + CSRA66X0_BASE); + i <= CSRA66X0_MAX_REGISTER_ADDR; i++) { + reg_val = snd_soc_read(codec, i); + len = snprintf(tmp_buf, 20, "0x%04X: 0x%02X\n", i, (reg_val & 0xFF)); + if ((total + len) >= count - 1) + break; + if (copy_to_user((ubuf + total), tmp_buf, len)) { + dev_err(codec->dev, "%s: fail to copy reg dump\n", __func__); + total = -EFAULT; + goto copy_err; + } + *ppos += len; + total += len; + } + +copy_err: + return total; +} + +static ssize_t debugfs_codec_read_op(struct file *filp, + char __user *ubuf, size_t cnt, loff_t *ppos) +{ + struct csra66x0_priv *csra66x0 = + (struct csra66x0_priv *) filp->private_data; + struct snd_soc_codec *codec = csra66x0->codec; + ssize_t ret_cnt; + + if (!filp || !ppos || !ubuf || *ppos < 0) + return -EINVAL; + ret_cnt = debugfs_csra66x0_reg_show(codec, ubuf, cnt, ppos); + return ret_cnt; +} + +static const struct file_operations debugfs_codec_ops = { + .open = debugfs_codec_open_op, + .write = debugfs_codec_write_op, + .read = debugfs_codec_read_op, +}; +#endif /* CONFIG_DEBUG_FS */ + /* * CSRA66X0 Controls */ @@ -442,7 +573,7 @@ static int csra66x0_soc_probe(struct snd_soc_codec *codec) if (csra66x0->in_cluster) { dapm = snd_soc_codec_get_dapm(codec); - dev_dbg(codec->dev, "%s: setting %s to codec %s\n", + dev_dbg(codec->dev, "%s: assign prefix %s to codec device %s\n", __func__, codec->component.name_prefix, codec->component.name); snd_soc_write(codec, CSRA66X0_CHIP_STATE_CTRL_FA, @@ -580,6 +711,31 @@ static irqreturn_t csra66x0_irq(int irq, void *data) /* clear fault state and re-init */ snd_soc_write(codec, CSRA66X0_FAULT_STATUS_FA, 0x00); + snd_soc_write(codec, CSRA66X0_IRQ_OUTPUT_STATUS_FA, 0x00); + /* apply reset to CSRA66X0 */ + val = snd_soc_read(codec, CSRA66X0_MISC_CONTROL_STATUS_1_FA); + snd_soc_write(codec, CSRA66X0_MISC_CONTROL_STATUS_1_FA, val | 0x08); + /* wait 2s after reset to recover CSRA66X0 */ + msleep(2000); + /* re-init */ + snd_soc_write(codec, CSRA66X0_CHIP_STATE_CTRL_FA, + CONFIG_STATE); + /* settle time in HW is min. 500ms before proceeding */ + msleep(500); + snd_soc_write(codec, CSRA66X0_PIO7_SELECT, 0x04); + snd_soc_write(codec, CSRA66X0_PIO8_SELECT, 0x04); + if (csra66x0->is_master) { + /* Master specific config */ + snd_soc_write(codec, CSRA66X0_PIO_PULL_EN0, 0xFF); + snd_soc_write(codec, CSRA66X0_PIO_PULL_DIR0, 0x80); + snd_soc_write(codec, CSRA66X0_PIO_PULL_EN1, 0x01); + snd_soc_write(codec, CSRA66X0_PIO_PULL_DIR1, 0x01); + } else { + /* Slave specific config */ + snd_soc_write(codec, CSRA66X0_PIO_PULL_EN0, 0x7F); + snd_soc_write(codec, CSRA66X0_PIO_PULL_EN1, 0x00); + } + snd_soc_write(codec, CSRA66X0_DCA_CTRL, 0x05); csra66x0_init(codec, csra66x0); } else { return IRQ_NONE; @@ -599,6 +755,7 @@ static int csra66x0_i2c_probe(struct i2c_client *client_i2c, { struct csra66x0_priv *csra66x0; int ret, irq_trigger; + char debugfs_dir_name[32]; csra66x0 = devm_kzalloc(&client_i2c->dev, sizeof(struct csra66x0_priv), GFP_KERNEL); @@ -662,7 +819,7 @@ static int csra66x0_i2c_probe(struct i2c_client *client_i2c, } } else { gpio_direction_output(csra66x0->vreg_gpio, 1); - gpio_set_value(csra66x0->vreg_gpio, 1); + gpio_set_value(csra66x0->vreg_gpio, 0); } /* register interrupt handle */ @@ -695,12 +852,45 @@ static int csra66x0_i2c_probe(struct i2c_client *client_i2c, } } +#if IS_ENABLED(CONFIG_DEBUG_FS) + /* debugfs interface */ + snprintf(debugfs_dir_name, sizeof(debugfs_dir_name), "%s-%s", + client_i2c->name, dev_name(&client_i2c->dev)); + csra66x0->debugfs_dir = debugfs_create_dir(debugfs_dir_name, NULL); + if (!csra66x0->debugfs_dir) { + dev_dbg(&client_i2c->dev, + "%s: Failed to create /sys/kernel/debug/%s for debugfs\n", + __func__, debugfs_dir_name); + return -ENOMEM; + } + csra66x0->debugfs_file_wo = debugfs_create_file( + "write_reg_val", S_IFREG | S_IRUGO, csra66x0->debugfs_dir, + (void *) csra66x0, + &debugfs_codec_ops); + if (!csra66x0->debugfs_file_wo) { + dev_dbg(&client_i2c->dev, + "%s: Failed to create /sys/kernel/debug/%s/write_reg_val\n", + __func__, debugfs_dir_name); + return -ENOMEM; + } + csra66x0->debugfs_file_ro = debugfs_create_file( + "show_reg_dump", S_IFREG | S_IRUGO, csra66x0->debugfs_dir, + (void *) csra66x0, + &debugfs_codec_ops); + if (!csra66x0->debugfs_file_ro) { + dev_dbg(&client_i2c->dev, + "%s: Failed to create /sys/kernel/debug/%s/show_reg_dump\n", + __func__, debugfs_dir_name); + return -ENOMEM; + } +#endif /* CONFIG_DEBUG_FS */ + /* register codec */ ret = snd_soc_register_codec(&client_i2c->dev, &soc_codec_drv_csra66x0, NULL, 0); if (ret != 0) { - dev_err(&client_i2c->dev, "%s %d: Failed to register CODEC: %d\n", - __func__, __LINE__, ret); + dev_err(&client_i2c->dev, "%s %d: Failed to register codec: %d\n", + __func__, __LINE__, ret); if (gpio_is_valid(csra66x0->vreg_gpio)) { gpio_set_value(csra66x0->vreg_gpio, 0); gpio_free(csra66x0->vreg_gpio); @@ -719,6 +909,9 @@ static int csra66x0_i2c_remove(struct i2c_client *i2c_client) gpio_set_value(csra66x0->vreg_gpio, 0); gpio_free(csra66x0->vreg_gpio); } +#if IS_ENABLED(CONFIG_DEBUG_FS) + debugfs_remove_recursive(csra66x0->debugfs_dir); +#endif } snd_soc_unregister_codec(&i2c_client->dev); return 0; -- GitLab From 968be0ae5b8563e3441ce3977a40a9049ba8309a Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Thu, 12 Jul 2018 16:39:44 -0700 Subject: [PATCH 0403/1645] dsp: q6afe: fix payload copy issue in module event Payload is copied incorrectly in AFE module event callback. Fix this issue with proper typecast of payload pointer. Change-Id: I58642a054667912bcc01ae19c8c73d28c28b5589 Signed-off-by: Vidyakumar Athota --- dsp/q6afe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 405c24faa75b..03fbdb76dc19 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -337,6 +337,7 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, static void afe_notify_dc_presence(void) { + pr_debug("%s: DC detected\n", __func__); msm_aud_evt_notifier_call_chain(MSM_AUD_DC_EVENT, NULL); schedule_work(&this_afe.afe_dc_work); @@ -542,7 +543,7 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) (evt_pl->payload_size == sizeof(flag_dc_presence))) { memcpy(&flag_dc_presence, - payload + + (uint8_t *)payload + sizeof(struct afe_port_mod_evt_rsp_hdr), evt_pl->payload_size); if (flag_dc_presence[0] == 1 || -- GitLab From cc29b9e83946703486e9b1d57a679ae6cca7db8a Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Tue, 17 Jul 2018 20:19:04 +0530 Subject: [PATCH 0404/1645] dsp: support for AFE SPDIF input interface Support two SPDIF input and two SPDIF output interfaces in AFE. Support 61937 compressed capture. Change-Id: Ie71434eb53be798567a6240e0f4bf171aee305b8 Signed-off-by: Ralf Herz --- dsp/q6afe.c | 288 ++++++++++++++++++++++++++++++++++++- dsp/q6asm.c | 82 ++++++++++- dsp/q6audio-v2.c | 23 ++- dsp/q6core.c | 17 +++ include/dsp/apr_audio-v2.h | 97 +++++++++++-- include/dsp/q6afe-v2.h | 13 +- include/dsp/q6asm-v2.h | 3 + include/dsp/q6core.h | 1 + 8 files changed, 501 insertions(+), 23 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 405c24faa75b..47102f442a4f 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -103,6 +103,19 @@ struct afe_ctl { void *rx_private_data; uint32_t mmap_handle; + void (*pri_spdif_tx_cb)(uint32_t opcode, + uint32_t token, uint32_t *payload, void *priv); + void (*sec_spdif_tx_cb)(uint32_t opcode, + uint32_t token, uint32_t *payload, void *priv); + void *pri_spdif_tx_private_data; + void *sec_spdif_tx_private_data; + struct afe_port_mod_evt_rsp_hdr pri_spdif_evt_pl; + struct afe_event_fmt_update pri_spdif_fmt_event; + struct afe_port_mod_evt_rsp_hdr sec_spdif_evt_pl; + struct afe_event_fmt_update sec_spdif_fmt_event; + struct work_struct afe_pri_spdif_work; + struct work_struct afe_sec_spdif_work; + int topology[AFE_MAX_PORTS]; struct cal_type_data *cal_data[MAX_AFE_CAL_TYPES]; @@ -353,6 +366,128 @@ static void afe_notify_dc_presence_work_fn(struct work_struct *work) __func__, event, ret); } + +static const char *const afe_event_port_text[] = { + "PORT=Primary", + "PORT=Secondary", +}; + +static const char * const afe_event_state_text[] = { + "STATE=Inactive", + "STATE=Active", + "STATE=EOS", +}; + +static const char *const afe_event_rate_text[] = { + "RATE=32000", + "RATE=44100", + "RATE=48000", + "RATE=88200", + "RATE=96000", + "RATE=176400", + "RATE=192000", +}; + +static const char *const afe_event_format_text[] = { + "FORMAT=LPCM", + "FORMAT=Compr", +}; + +static void afe_notify_spdif_fmt_update_common(void *payload) +{ + int ret = 0; + char *env[6]; + struct afe_port_mod_evt_rsp_hdr *evt_pl; + struct afe_event_fmt_update *fmt_event; + + evt_pl = (struct afe_port_mod_evt_rsp_hdr *)payload; + fmt_event = (struct afe_event_fmt_update *) + (payload + sizeof(struct afe_port_mod_evt_rsp_hdr)); + + env[0] = "SPDIF_FMT_UPDATE=TRUE"; + if (evt_pl->port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) + env[1] = (char *)afe_event_port_text[0]; + else + env[1] = (char *)afe_event_port_text[1]; + + switch (fmt_event->status) { + case AFE_PORT_STATUS_AUDIO_ACTIVE: + env[2] = (char *)afe_event_state_text[1]; + break; + case AFE_PORT_STATUS_AUDIO_EOS: + env[2] = (char *)afe_event_state_text[2]; + break; + default: + env[2] = (char *)afe_event_state_text[0]; + } + + switch (fmt_event->sample_rate) { + case 32000: + env[3] = (char *)afe_event_rate_text[0]; + break; + case 44100: + env[3] = (char *)afe_event_rate_text[1]; + break; + case 48000: + env[3] = (char *)afe_event_rate_text[2]; + break; + case 88200: + env[3] = (char *)afe_event_rate_text[3]; + break; + case 96000: + env[3] = (char *)afe_event_rate_text[4]; + break; + case 176400: + env[3] = (char *)afe_event_rate_text[5]; + break; + case 192000: + env[3] = (char *)afe_event_rate_text[6]; + break; + default: + env[3] = (char *)afe_event_rate_text[2]; + } + + if (fmt_event->data_format == AFE_NON_LINEAR_DATA) + env[4] = (char *)afe_event_format_text[1]; + else + env[4] = (char *)afe_event_format_text[0]; + + env[5] = NULL; + + ret = q6core_send_uevent_env(this_afe.uevent_data, env); + if (ret) + pr_err("%s: Send UEvent %s failed: %d\n", __func__, + env[0], ret); +} + +static void afe_notify_pri_spdif_fmt_update_work_fn(struct work_struct *work) +{ + afe_notify_spdif_fmt_update_common(&this_afe.pri_spdif_evt_pl); +} + +static void afe_notify_sec_spdif_fmt_update_work_fn(struct work_struct *work) +{ + afe_notify_spdif_fmt_update_common(&this_afe.sec_spdif_evt_pl); +} + +static void afe_notify_spdif_fmt_update(void *payload) +{ + struct afe_port_mod_evt_rsp_hdr *evt_pl; + + evt_pl = (struct afe_port_mod_evt_rsp_hdr *)payload; + if (evt_pl->port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) { + memcpy(&this_afe.pri_spdif_evt_pl, payload, + sizeof(struct afe_port_mod_evt_rsp_hdr) + + sizeof(struct afe_event_fmt_update)); + schedule_work(&this_afe.afe_pri_spdif_work); + } else { + memcpy(&this_afe.sec_spdif_evt_pl, payload, + sizeof(struct afe_port_mod_evt_rsp_hdr) + + sizeof(struct afe_event_fmt_update)); + schedule_work(&this_afe.afe_sec_spdif_work); + } +} + static int32_t afe_callback(struct apr_client_data *data, void *priv) { if (!data) { @@ -549,6 +684,20 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) flag_dc_presence[1] == 1) { afe_notify_dc_presence(); } + } else if (evt_pl->port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) { + if (this_afe.pri_spdif_tx_cb) { + this_afe.pri_spdif_tx_cb(data->opcode, + data->token, data->payload, + this_afe.pri_spdif_tx_private_data); + } + afe_notify_spdif_fmt_update(data->payload); + } else if (evt_pl->port_id == AFE_PORT_ID_SECONDARY_SPDIF_TX) { + if (this_afe.sec_spdif_tx_cb) { + this_afe.sec_spdif_tx_cb(data->opcode, + data->token, data->payload, + this_afe.sec_spdif_tx_private_data); + } + afe_notify_spdif_fmt_update(data->payload); } else { pr_debug("%s: mod ID = 0x%x event_id = 0x%x\n", __func__, evt_pl->module_id, @@ -639,6 +788,13 @@ int afe_sizeof_cfg_cmd(u16 port_id) ret_size = SIZEOF_CFG_CMD(afe_param_id_hdmi_multi_chan_audio_cfg); break; + case AFE_PORT_ID_PRIMARY_SPDIF_RX: + case AFE_PORT_ID_PRIMARY_SPDIF_TX: + case AFE_PORT_ID_SECONDARY_SPDIF_RX: + case AFE_PORT_ID_SECONDARY_SPDIF_TX: + ret_size = + SIZEOF_CFG_CMD(afe_param_id_spdif_cfg_v2); + break; case SLIMBUS_0_RX: case SLIMBUS_0_TX: case SLIMBUS_1_RX: @@ -2793,7 +2949,7 @@ int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port, param_hdr, (u8 *) spdif_port); if (ret) { pr_err("%s: AFE enable for port 0x%x failed ret = %d\n", - __func__, port_id, ret); + __func__, port_id, ret); goto fail_cmd; } @@ -2806,10 +2962,13 @@ int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port, goto fail_cmd; } - ret = afe_send_spdif_ch_status_cfg(&spdif_port->ch_status, port_id); - if (ret < 0) { - pr_err("%s: afe send failed %d\n", __func__, ret); - goto fail_cmd; + if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) { + ret = afe_send_spdif_ch_status_cfg(&spdif_port->ch_status, + port_id); + if (ret < 0) { + pr_err("%s: afe send failed %d\n", __func__, ret); + goto fail_cmd; + } } return afe_send_cmd_port_start(port_id); @@ -2819,6 +2978,105 @@ int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port, } EXPORT_SYMBOL(afe_spdif_port_start); +/** + * afe_spdif_reg_event_cfg - + * register for event from AFE spdif port + * + * @port_id: Port ID to register event + * @reg_flag: register or unregister + * @cb: callback function to invoke for events from module + * @private_data: private data to sent back in callback fn + * + * Returns 0 on success or error on failure + */ +int afe_spdif_reg_event_cfg(u16 port_id, u16 reg_flag, + void (*cb)(uint32_t opcode, + uint32_t token, uint32_t *payload, void *priv), + void *private_data) +{ + struct afe_port_cmd_event_cfg *config; + struct afe_port_cmd_mod_evt_cfg_payload pl; + int index; + int ret; + int num_events = 1; + int cmd_size = sizeof(struct afe_port_cmd_event_cfg) + + (num_events * sizeof(struct afe_port_cmd_mod_evt_cfg_payload)); + + config = kzalloc(cmd_size, GFP_KERNEL); + if (!config) + return -ENOMEM; + + if (port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) { + this_afe.pri_spdif_tx_cb = cb; + this_afe.pri_spdif_tx_private_data = private_data; + } else if (port_id == AFE_PORT_ID_SECONDARY_SPDIF_TX) { + this_afe.sec_spdif_tx_cb = cb; + this_afe.sec_spdif_tx_private_data = private_data; + } else { + pr_err("%s: wrong port id 0x%x\n", __func__, port_id); + ret = -EINVAL; + goto fail_idx; + } + + index = q6audio_get_port_index(port_id); + if (index < 0) { + pr_err("%s: Invalid index number: %d\n", __func__, index); + ret = -EINVAL; + goto fail_idx; + } + + memset(&pl, 0, sizeof(pl)); + pl.module_id = AFE_MODULE_CUSTOM_EVENTS; + pl.event_id = AFE_PORT_FMT_UPDATE_EVENT; + pl.reg_flag = reg_flag; + + config->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config->hdr.pkt_size = cmd_size; + config->hdr.src_port = 1; + config->hdr.dest_port = 1; + config->hdr.token = index; + + config->hdr.opcode = AFE_PORT_CMD_MOD_EVENT_CFG; + config->port_id = q6audio_get_port_id(port_id); + config->num_events = num_events; + config->version = 1; + memcpy(config->payload, &pl, sizeof(pl)); + atomic_set(&this_afe.state, 1); + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) config); + if (ret < 0) { + pr_err("%s: port = 0x%x failed %d\n", + __func__, port_id, ret); + goto fail_cmd; + } + ret = wait_event_timeout(this_afe.wait[index], + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -EINVAL; + goto fail_cmd; + } + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: config cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto fail_idx; + } + ret = 0; +fail_cmd: + pr_debug("%s: config.opcode 0x%x status %d\n", + __func__, config->hdr.opcode, ret); + +fail_idx: + kfree(config); + return ret; +} +EXPORT_SYMBOL(afe_spdif_reg_event_cfg); + int afe_send_slot_mapping_cfg( struct afe_param_id_slot_mapping_cfg *slot_mapping_cfg, u16 port_id) @@ -3880,7 +4138,10 @@ int afe_get_port_index(u16 port_id) case MI2S_TX: return IDX_MI2S_TX; case HDMI_RX: return IDX_HDMI_RX; case DISPLAY_PORT_RX: return IDX_DISPLAY_PORT_RX; - case AFE_PORT_ID_SPDIF_RX: return IDX_SPDIF_RX; + case AFE_PORT_ID_PRIMARY_SPDIF_RX: return IDX_PRIMARY_SPDIF_RX; + case AFE_PORT_ID_PRIMARY_SPDIF_TX: return IDX_PRIMARY_SPDIF_TX; + case AFE_PORT_ID_SECONDARY_SPDIF_RX: return IDX_SECONDARY_SPDIF_RX; + case AFE_PORT_ID_SECONDARY_SPDIF_TX: return IDX_SECONDARY_SPDIF_TX; case RSVD_2: return IDX_RSVD_2; case RSVD_3: return IDX_RSVD_3; case DIGI_MIC_TX: return IDX_DIGI_MIC_TX; @@ -4259,6 +4520,12 @@ int afe_open(u16 port_id, case DISPLAY_PORT_RX: cfg_type = AFE_PARAM_ID_HDMI_CONFIG; break; + case AFE_PORT_ID_PRIMARY_SPDIF_RX: + case AFE_PORT_ID_PRIMARY_SPDIF_TX: + case AFE_PORT_ID_SECONDARY_SPDIF_RX: + case AFE_PORT_ID_SECONDARY_SPDIF_TX: + cfg_type = AFE_PARAM_ID_SPDIF_CONFIG; + break; case SLIMBUS_0_RX: case SLIMBUS_0_TX: case SLIMBUS_1_RX: @@ -6100,7 +6367,10 @@ int afe_validate_port(u16 port_id) case MI2S_TX: case HDMI_RX: case DISPLAY_PORT_RX: - case AFE_PORT_ID_SPDIF_RX: + case AFE_PORT_ID_PRIMARY_SPDIF_RX: + case AFE_PORT_ID_PRIMARY_SPDIF_TX: + case AFE_PORT_ID_SECONDARY_SPDIF_RX: + case AFE_PORT_ID_SECONDARY_SPDIF_TX: case RSVD_2: case RSVD_3: case DIGI_MIC_TX: @@ -7695,6 +7965,10 @@ int __init afe_init(void) q6core_init_uevent_data(this_afe.uevent_data, "q6afe_uevent"); INIT_WORK(&this_afe.afe_dc_work, afe_notify_dc_presence_work_fn); + INIT_WORK(&this_afe.afe_pri_spdif_work, + afe_notify_pri_spdif_fmt_update_work_fn); + INIT_WORK(&this_afe.afe_sec_spdif_work, + afe_notify_sec_spdif_fmt_update_work_fn); return 0; } diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 8deb64a723ab..059fa83567c3 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1953,6 +1953,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) case ASM_DATA_CMD_REMOVE_INITIAL_SILENCE: case ASM_DATA_CMD_REMOVE_TRAILING_SILENCE: case ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS: + case ASM_STREAM_CMD_OPEN_READ_COMPRESSED: case ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED: pr_debug("%s: session %d opcode 0x%x token 0x%x Payload = [0x%x] stat 0x%x src %d dest %d\n", __func__, ac->session, @@ -2166,7 +2167,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) if (ac->io_mode & SYNC_IO_MODE) { if (port->buf == NULL) { - pr_err("%s: Unexpected Write Done\n", __func__); + pr_err("%s: Unexpected Read Done\n", __func__); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); @@ -2833,6 +2834,85 @@ int q6asm_set_soft_volume_module_instance_ids(int instance, } EXPORT_SYMBOL(q6asm_set_soft_volume_module_instance_ids); +/** + * q6asm_open_read_compressed - + * command to open ASM in compressed read mode + * + * @ac: Audio client handle + * @format: capture format for ASM + * @passthrough_flag: flag to indicate passthrough option + * + * Returns 0 on success or error on failure + */ +int q6asm_open_read_compressed(struct audio_client *ac, uint32_t format, + uint32_t passthrough_flag) +{ + int rc = 0; + struct asm_stream_cmd_open_read_compressed open; + + if (ac == NULL) { + pr_err("%s: ac[%pK] NULL\n", __func__, ac); + rc = -EINVAL; + goto fail_cmd; + } + + if (ac->apr == NULL) { + pr_err("%s: APR handle[%pK] NULL\n", __func__, ac->apr); + rc = -EINVAL; + goto fail_cmd; + } + pr_debug("%s: session[%d] wr_format[0x%x]\n", __func__, ac->session, + format); + + q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE); + open.hdr.opcode = ASM_STREAM_CMD_OPEN_READ_COMPRESSED; + atomic_set(&ac->cmd_state, -1); + + /* + * Below flag indicates whether DSP shall keep IEC61937 packing or + * unpack to raw compressed format + */ + if (format == FORMAT_IEC61937) { + open.mode_flags = 0x1; + pr_debug("%s: Flag 1 IEC61937 output\n", __func__); + } else { + open.mode_flags = 0; + open.frames_per_buf = 1; + pr_debug("%s: Flag 0 RAW_COMPR output\n", __func__); + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &open); + if (rc < 0) { + pr_err("%s: open failed op[0x%x]rc[%d]\n", + __func__, open.hdr.opcode, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 1*HZ); + if (!rc) { + pr_err("%s: timeout. waited for OPEN_READ_COMPR rc[%d]\n", + __func__, rc); + rc = -ETIMEDOUT; + goto fail_cmd; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + + return 0; + +fail_cmd: + return rc; +} +EXPORT_SYMBOL(q6asm_open_read_compressed); + static int __q6asm_open_read(struct audio_client *ac, uint32_t format, uint16_t bits_per_sample, uint32_t pcm_format_block_ver, diff --git a/dsp/q6audio-v2.c b/dsp/q6audio-v2.c index a49632700c85..b48c9b69cf55 100644 --- a/dsp/q6audio-v2.c +++ b/dsp/q6audio-v2.c @@ -50,7 +50,10 @@ int q6audio_get_port_index(u16 port_id) case MI2S_TX: return IDX_MI2S_TX; case HDMI_RX: return IDX_HDMI_RX; case DISPLAY_PORT_RX: return IDX_DISPLAY_PORT_RX; - case AFE_PORT_ID_SPDIF_RX: return IDX_SPDIF_RX; + case AFE_PORT_ID_PRIMARY_SPDIF_RX: return IDX_PRIMARY_SPDIF_RX; + case AFE_PORT_ID_PRIMARY_SPDIF_TX: return IDX_PRIMARY_SPDIF_TX; + case AFE_PORT_ID_SECONDARY_SPDIF_RX: return IDX_SECONDARY_SPDIF_RX; + case AFE_PORT_ID_SECONDARY_SPDIF_TX: return IDX_SECONDARY_SPDIF_TX; case RSVD_2: return IDX_RSVD_2; case RSVD_3: return IDX_RSVD_3; case DIGI_MIC_TX: return IDX_DIGI_MIC_TX; @@ -351,7 +354,14 @@ int q6audio_get_port_id(u16 port_id) case HDMI_RX: return AFE_PORT_ID_MULTICHAN_HDMI_RX; case DISPLAY_PORT_RX: return AFE_PORT_ID_HDMI_OVER_DP_RX; - case AFE_PORT_ID_SPDIF_RX: return AFE_PORT_ID_SPDIF_RX; + case AFE_PORT_ID_PRIMARY_SPDIF_RX: + return AFE_PORT_ID_PRIMARY_SPDIF_RX; + case AFE_PORT_ID_PRIMARY_SPDIF_TX: + return AFE_PORT_ID_PRIMARY_SPDIF_TX; + case AFE_PORT_ID_SECONDARY_SPDIF_RX: + return AFE_PORT_ID_SECONDARY_SPDIF_RX; + case AFE_PORT_ID_SECONDARY_SPDIF_TX: + return AFE_PORT_ID_SECONDARY_SPDIF_TX; case RSVD_2: return IDX_RSVD_2; case RSVD_3: return IDX_RSVD_3; case DIGI_MIC_TX: return AFE_PORT_ID_DIGITAL_MIC_TX; @@ -777,6 +787,10 @@ int q6audio_is_digital_pcm_interface(u16 port_id) case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: case AFE_PORT_ID_VA_CODEC_DMA_TX_0: case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + case AFE_PORT_ID_PRIMARY_SPDIF_RX: + case AFE_PORT_ID_PRIMARY_SPDIF_TX: + case AFE_PORT_ID_SECONDARY_SPDIF_RX: + case AFE_PORT_ID_SECONDARY_SPDIF_TX: break; default: ret = -EINVAL; @@ -854,7 +868,10 @@ int q6audio_validate_port(u16 port_id) case AFE_PORT_ID_QUATERNARY_MI2S_TX: case AFE_PORT_ID_SECONDARY_MI2S_RX: case AFE_PORT_ID_SECONDARY_MI2S_TX: - case AFE_PORT_ID_SPDIF_RX: + case AFE_PORT_ID_PRIMARY_SPDIF_RX: + case AFE_PORT_ID_PRIMARY_SPDIF_TX: + case AFE_PORT_ID_SECONDARY_SPDIF_RX: + case AFE_PORT_ID_SECONDARY_SPDIF_TX: case AFE_PORT_ID_TERTIARY_MI2S_RX: case AFE_PORT_ID_TERTIARY_MI2S_TX: case AFE_PORT_ID_QUINARY_MI2S_RX: diff --git a/dsp/q6core.c b/dsp/q6core.c index 51b8ef0c4e9d..34f0dd091189 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -189,6 +189,23 @@ int q6core_send_uevent(struct audio_uevent_data *uevent_data, char *event) } EXPORT_SYMBOL(q6core_send_uevent); +/** + * q6core_send_uevent_env - send uevent with list of keys to userspace. + * + * @uevent_data: uevent data. + * @event: array of event keys to send. + * + * Returns 0 on success or error otherwise. + */ +int q6core_send_uevent_env(struct audio_uevent_data *uevent_data, char *env[]) +{ + if (!env || !uevent_data) + return -EINVAL; + + return kobject_uevent_env(&uevent_data->kobj, KOBJ_CHANGE, env); +} +EXPORT_SYMBOL(q6core_send_uevent_env); + static int parse_fwk_version_info(uint32_t *payload) { size_t ver_size; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 337f66f27b25..b9ae3f55843e 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1236,7 +1236,11 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_PORT_ID_QUINARY_PCM_RX 0x103C #define AFE_PORT_ID_QUINARY_PCM_TX 0x103D -#define AFE_PORT_ID_SPDIF_RX 0x5000 +#define AFE_PORT_ID_PRIMARY_SPDIF_RX 0x5000 +#define AFE_PORT_ID_PRIMARY_SPDIF_TX 0x5001 +#define AFE_PORT_ID_SECONDARY_SPDIF_RX 0x5002 +#define AFE_PORT_ID_SECONDARY_SPDIF_TX 0x5003 + #define AFE_PORT_ID_RT_PROXY_PORT_001_RX 0x2000 #define AFE_PORT_ID_RT_PROXY_PORT_001_TX 0x2001 #define AFE_PORT_ID_INTERNAL_BT_SCO_RX 0x3000 @@ -2270,6 +2274,7 @@ struct afe_param_id_i2s_cfg { * This param id is used to configure PCM interface */ +#define AFE_API_VERSION_SPDIF_CONFIG_V2 0x2 #define AFE_API_VERSION_SPDIF_CONFIG 0x1 #define AFE_API_VERSION_SPDIF_CH_STATUS_CONFIG 0x1 #define AFE_API_VERSION_SPDIF_CLK_CONFIG 0x1 @@ -2283,10 +2288,20 @@ struct afe_param_id_i2s_cfg { #define AFE_PORT_CLK_ROOT_LPAPLL 0x3 #define AFE_PORT_CLK_ROOT_LPAQ6PLL 0x4 -struct afe_param_id_spdif_cfg { +#define AFE_MODULE_CUSTOM_EVENTS 0x00010251 + +#define AFE_PORT_FMT_UPDATE_EVENT 0x0001010E + +#define AFE_API_VERSION_EVENT_FMT_UPDATE 0x1 +#define AFE_PORT_STATUS_NO_SIGNAL 0 +#define AFE_PORT_STATUS_AUDIO_ACTIVE 1 +#define AFE_PORT_STATUS_AUDIO_EOS 2 + +struct afe_param_id_spdif_cfg_v2 { /* Minor version used for tracking the version of the SPDIF * configuration interface. - * Supported values: #AFE_API_VERSION_SPDIF_CONFIG + * Supported values: #AFE_API_VERSION_SPDIF_CONFIG, + * #AFE_API_VERSION_SPDIF_CONFIG_V2 */ u32 spdif_cfg_minor_version; @@ -2318,6 +2333,8 @@ struct afe_param_id_spdif_cfg { u16 bit_width; /* This field must be set to zero. */ u16 reserved; +/* Input select for spdif input, must be set to 0 for spdif output. */ + u32 src_sel; } __packed; struct afe_param_id_spdif_ch_status_cfg { @@ -2344,6 +2361,7 @@ struct afe_param_id_spdif_ch_status_cfg { */ } __packed; +/* deprecated */ struct afe_param_id_spdif_clk_cfg { u32 clk_cfg_minor_version; /* Minor version used for tracking the version of SPDIF @@ -2367,8 +2385,43 @@ struct afe_param_id_spdif_clk_cfg { */ } __packed; +struct afe_event_fmt_update { + /* Tracks the configuration of this event. */ + u32 minor_version; + + /* Detected port status. + * Supported values: + * - #AFE_PORT_STATUS_NO_SIGNAL + * - #AFE_PORT_STATUS_AUDIO_ACTIVE + * - #AFE_PORT_STATUS_AUDIO_EOS + */ + u32 status; + + /* Sampling rate of the port. + * Supported values: + * - #AFE_PORT_SAMPLE_RATE_32K + * - #AFE_PORT_SAMPLE_RATE_44_1K + * - #AFE_PORT_SAMPLE_RATE_48K + * - #AFE_PORT_SAMPLE_RATE_88_2K + * - #AFE_PORT_SAMPLE_RATE_96K + * - #AFE_PORT_SAMPLE_RATE_176_4K + * - #AFE_PORT_SAMPLE_RATE_192K + */ + u32 sample_rate; + + /* Data format of the port. + * Supported values: + * - #AFE_LINEAR_PCM_DATA + * - #AFE_NON_LINEAR_DATA + */ + u16 data_format; + + /* First 6 bytes of channel status bits */ + u8 channel_status[6]; +} __packed; + struct afe_spdif_port_config { - struct afe_param_id_spdif_cfg cfg; + struct afe_param_id_spdif_cfg_v2 cfg; struct afe_param_id_spdif_ch_status_cfg ch_status; } __packed; @@ -4093,7 +4146,7 @@ union afe_port_config { struct afe_param_id_internal_bt_fm_cfg int_bt_fm; struct afe_param_id_pseudo_port_cfg pseudo_port; struct afe_param_id_device_hw_delay_cfg hw_delay; - struct afe_param_id_spdif_cfg spdif; + struct afe_param_id_spdif_cfg_v2 spdif; struct afe_param_id_set_topology_cfg topology; struct afe_param_id_tdm_cfg tdm; struct afe_param_id_usb_audio_cfg usb_audio; @@ -4793,7 +4846,7 @@ struct asm_generic_compressed_fmt_blk_t { /* Command to send sample rate & channels for IEC61937 (compressed) or IEC60958 * (pcm) streams. Both audio standards use the same format and are used for - * HDMI or SPDIF. + * HDMI or SPDIF output. */ #define ASM_DATA_CMD_IEC_60958_MEDIA_FMT 0x0001321E @@ -7669,11 +7722,23 @@ struct asm_data_cmd_remove_silence { #define ASM_STREAM_CMD_OPEN_READ_COMPRESSED 0x00010D95 +/* Bitmask for the IEC 61937 to 61937 pass-through capture. */ +#define ASM_BIT_MASK_IEC_61937_PASS_THROUGH_FLAG (0x00000001UL) + +/* Shift value for the IEC 61937 to 61937 pass-through capture. */ +#define ASM_SHIFT_IEC_61937_PASS_THROUGH_FLAG 0 + struct asm_stream_cmd_open_read_compressed { struct apr_hdr hdr; u32 mode_flags; /* Mode flags that indicate whether meta information per encoded - * frame is to be provided. + * frame is to be provided and packaging. + * Supported values for bit 0: (IEC 61937 pass-through mode) + * - 0 -- Unpack the IEC 61937 format stream to RAW compressed format + * - 1 -- Pass-through transfer of the IEC 61937 format stream + * - Use #ASM_BIT_MASK_IEC_61937_PASS_THROUGH_FLAG to set the bitmask + * and #ASM_SHIFT_IEC_61937_PASS_THROUGH_FLAG to set the shift value + * for this bit. * Supported values for bit 4: * - 0 -- Return data buffer contains all encoded frames only; it does * not contain frame metadata. @@ -7687,7 +7752,9 @@ struct asm_stream_cmd_open_read_compressed { u32 frames_per_buf; /* Indicates the number of frames that need to be returned per * read buffer - * Supported values: should be greater than 0 + * Supported values: should be greater than 0 for IEC to RAW compressed + * unpack mode. + * Value is don't care for IEC 61937 pass-through mode. */ } __packed; @@ -10321,8 +10388,18 @@ enum afe_lpass_clk_mode { /* Clock ID for AHB HDMI input */ #define Q6AFE_LPASS_CLK_ID_AHB_HDMI_INPUT 0x400 -/* Clock ID for SPDIF core */ -#define Q6AFE_LPASS_CLK_ID_SPDIF_CORE 0x500 +/* Clock ID for the primary SPDIF output core. */ +#define AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_OUTPUT_CORE 0x500 +/* Clock ID for the secondary SPDIF output core. */ +#define AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_OUTPUT_CORE 0x501 +/* Clock ID for the primary SPDIF input core. */ +#define AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_INPUT_CORE 0x502 +/* Clock ID for the secondary SPDIF input core. */ +#define AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_INPUT_CORE 0x503 +/* Clock ID for the secondary SPDIF output NPL clk. */ +#define AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_OUTPUT_NPL 0x504 +/* Clock ID for the primary SPDIF output NPL clk. */ +#define AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_OUTPUT_NPL 0x505 /* Clock attribute for invalid use (reserved for internal usage) */ diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index e39d0b89d578..930682836f32 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -107,7 +107,7 @@ enum { /* IDX 45->49 */ IDX_SLIMBUS_6_RX, IDX_SLIMBUS_6_TX, - IDX_SPDIF_RX, + IDX_PRIMARY_SPDIF_RX, IDX_GLOBAL_CFG, IDX_AUDIO_PORT_ID_I2S_RX, /* IDX 50->53 */ @@ -229,7 +229,7 @@ enum { IDX_AFE_PORT_ID_QUINARY_TDM_TX_6, IDX_AFE_PORT_ID_QUINARY_TDM_RX_7, IDX_AFE_PORT_ID_QUINARY_TDM_TX_7, - /* IDX 161 to 166 */ + /* IDX 161 to 167 */ IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_0, IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_0, IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_1, @@ -237,6 +237,10 @@ enum { IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_2, IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_0, IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_1, + /* IDX 168 to 170 */ + IDX_SECONDARY_SPDIF_RX, + IDX_PRIMARY_SPDIF_TX, + IDX_SECONDARY_SPDIF_TX, AFE_MAX_PORTS }; @@ -389,6 +393,11 @@ int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port, u32 rate); +int afe_spdif_reg_event_cfg(u16 port_id, u16 reg_flag, + void (*cb)(uint32_t opcode, + uint32_t token, uint32_t *payload, void *priv), + void *private_data); + int afe_turn_onoff_hw_mad(u16 mad_type, u16 mad_enable); int afe_port_set_mad_type(u16 port_id, enum afe_mad_type mad_type); enum afe_mad_type afe_port_get_mad_type(u16 port_id); diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index e6f021db7e88..633e16c07e70 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -323,6 +323,9 @@ int q6asm_stream_open_write_v4(struct audio_client *ac, uint32_t format, uint16_t bits_per_sample, int32_t stream_id, bool is_gapless_mode); +int q6asm_open_read_compressed(struct audio_client *ac, uint32_t format, + uint32_t passthrough_flag); + int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format, uint32_t passthrough_flag); diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index ac364511513a..cdee048c38bf 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -35,6 +35,7 @@ struct audio_uevent_data { int q6core_init_uevent_data(struct audio_uevent_data *uevent_data, char *name); void q6core_destroy_uevent_data(struct audio_uevent_data *uevent_data); int q6core_send_uevent(struct audio_uevent_data *uevent_data, char *name); +int q6core_send_uevent_env(struct audio_uevent_data *uevent_data, char *env[]); int q6core_get_avcs_api_version_per_service(uint32_t service_id); #define ADSP_CMD_SET_DTS_EAGLE_DATA_ID 0x00012919 -- GitLab From c8701f776ad12fd0a3b970307a758ab19d69edba Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Wed, 20 Jun 2018 11:37:35 +0200 Subject: [PATCH 0405/1645] asoc: Add support to handle SPDIF input and output interfaces Support two SPDIF input and two SPDIF output interfaces in AFE. Change-Id: Ie2eb97e85c3b21cb112282dbdf0049a271e7cc93 Signed-off-by: Ralf Herz --- asoc/msm-dai-q6-v2.c | 397 +++++++++++++++++++++++++++++++++---- asoc/msm-pcm-routing-v2.c | 403 +++++++++++++++++++++++++++++++++----- asoc/msm-pcm-routing-v2.h | 10 +- 3 files changed, 721 insertions(+), 89 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 2c1eea17ff4a..ec6807a7964f 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -216,7 +216,14 @@ struct msm_dai_q6_spdif_dai_data { u32 rate; u32 channels; u32 bitwidth; + u16 port_id; struct afe_spdif_port_config spdif_port; + struct afe_event_fmt_update fmt_event; +}; + +struct msm_dai_q6_spdif_event_msg { + struct afe_port_mod_evt_rsp_hdr evt_hdr; + struct afe_event_fmt_update fmt_event; }; struct msm_dai_q6_mi2s_dai_config { @@ -1398,15 +1405,89 @@ static int msm_dai_q6_spdif_format_get(struct snd_kcontrol *kcontrol, return 0; } +static int msm_dai_q6_spdif_source_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; + int value = ucontrol->value.integer.value[0]; + + dai_data->spdif_port.cfg.src_sel = value; + pr_debug("%s: value = %d\n", __func__, value); + return 0; +} + +static int msm_dai_q6_spdif_source_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; + + ucontrol->value.integer.value[0] = + dai_data->spdif_port.cfg.src_sel; + return 0; +} + +static int msm_dai_q6_spdif_ext_state_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; + + ucontrol->value.integer.value[0] = + dai_data->fmt_event.status & 0x3; + return 0; +} + +static int msm_dai_q6_spdif_ext_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; + + ucontrol->value.integer.value[0] = + dai_data->fmt_event.data_format & 0x1; + return 0; +} + +static int msm_dai_q6_spdif_ext_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; + + ucontrol->value.integer.value[0] = + dai_data->fmt_event.sample_rate; + return 0; +} + static const char * const spdif_format[] = { "LPCM", "Compr" }; -static const struct soc_enum spdif_config_enum[] = { - SOC_ENUM_SINGLE_EXT(2, spdif_format), +static const char * const spdif_source[] = { + "Optical", "EXT-ARC", "Coaxial", "VT-ARC" +}; + +static const char * const spdif_state[] = { + "Inactive", "Active", "EOS" +}; + +static const struct soc_enum spdif_rx_config_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format), +}; + +static const struct soc_enum spdif_tx_config_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_source), spdif_source), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format), }; +static const struct soc_enum spdif_tx_status_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_state), spdif_state), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format), + }; + static int msm_dai_q6_spdif_chstatus_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1428,7 +1509,7 @@ static int msm_dai_q6_spdif_chstatus_put(struct snd_kcontrol *kcontrol, __func__); ret = afe_send_spdif_ch_status_cfg( &dai_data->spdif_port.ch_status, - AFE_PORT_ID_SPDIF_RX); + dai_data->port_id); } return ret; } @@ -1453,7 +1534,8 @@ static int msm_dai_q6_spdif_chstatus_info(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new spdif_config_controls[] = { +static const struct snd_kcontrol_new spdif_rx_config_controls[] = { + /* Primary SPDIF output */ { .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE), @@ -1463,11 +1545,76 @@ static const struct snd_kcontrol_new spdif_config_controls[] = { .get = msm_dai_q6_spdif_chstatus_get, .put = msm_dai_q6_spdif_chstatus_put, }, - SOC_ENUM_EXT("SPDIF RX Format", spdif_config_enum[0], + SOC_ENUM_EXT("PRI SPDIF RX Format", spdif_rx_config_enum[0], + msm_dai_q6_spdif_format_get, + msm_dai_q6_spdif_format_put), + /* Secondary SPDIF output */ + { + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_INACTIVE), + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("SEC", PLAYBACK, PCM_STREAM), + .info = msm_dai_q6_spdif_chstatus_info, + .get = msm_dai_q6_spdif_chstatus_get, + .put = msm_dai_q6_spdif_chstatus_put, + }, + SOC_ENUM_EXT("SEC SPDIF RX Format", spdif_rx_config_enum[0], msm_dai_q6_spdif_format_get, msm_dai_q6_spdif_format_put) }; +static const struct snd_kcontrol_new spdif_tx_config_controls[] = { + SOC_ENUM_EXT("PRI SPDIF TX Source", spdif_tx_config_enum[0], + msm_dai_q6_spdif_source_get, + msm_dai_q6_spdif_source_put), + SOC_ENUM_EXT("PRI SPDIF TX Format", spdif_tx_config_enum[1], + msm_dai_q6_spdif_format_get, + msm_dai_q6_spdif_format_put), + SOC_ENUM_EXT("SEC SPDIF TX Source", spdif_tx_config_enum[0], + msm_dai_q6_spdif_source_get, + msm_dai_q6_spdif_source_put), + SOC_ENUM_EXT("SEC SPDIF TX Format", spdif_tx_config_enum[1], + msm_dai_q6_spdif_format_get, + msm_dai_q6_spdif_format_put) +}; + +static const struct snd_kcontrol_new spdif_tx_status_controls[] = { + SOC_ENUM_EXT("PRI SPDIF TX EXT State", spdif_tx_status_enum[0], + msm_dai_q6_spdif_ext_state_get, NULL), + SOC_ENUM_EXT("PRI SPDIF TX EXT Format", spdif_tx_status_enum[1], + msm_dai_q6_spdif_ext_format_get, NULL), + SOC_SINGLE_EXT("PRI SPDIF TX EXT Rate", 0, 0, 192000, 0, + msm_dai_q6_spdif_ext_rate_get, NULL), + SOC_ENUM_EXT("SEC SPDIF TX EXT State", spdif_tx_status_enum[0], + msm_dai_q6_spdif_ext_state_get, NULL), + SOC_ENUM_EXT("SEC SPDIF TX EXT Format", spdif_tx_status_enum[1], + msm_dai_q6_spdif_ext_format_get, NULL), + SOC_SINGLE_EXT("SEC SPDIF TX EXT Rate", 0, 0, 192000, 0, + msm_dai_q6_spdif_ext_rate_get, NULL) +}; + +static void msm_dai_q6_spdif_process_event(uint32_t opcode, uint32_t token, + uint32_t *payload, void *private_data) +{ + struct msm_dai_q6_spdif_event_msg *evt; + struct msm_dai_q6_spdif_dai_data *dai_data; + + evt = (struct msm_dai_q6_spdif_event_msg *)payload; + dai_data = (struct msm_dai_q6_spdif_dai_data *)private_data; + + pr_debug("%s: old state %d, fmt %d, rate %d\n", + __func__, dai_data->fmt_event.status, + dai_data->fmt_event.data_format, + dai_data->fmt_event.sample_rate); + pr_debug("%s: new state %d, fmt %d, rate %d\n", + __func__, evt->fmt_event.status, + evt->fmt_event.data_format, + evt->fmt_event.sample_rate); + + dai_data->fmt_event.status = evt->fmt_event.status; + dai_data->fmt_event.data_format = evt->fmt_event.data_format; + dai_data->fmt_event.sample_rate = evt->fmt_event.sample_rate; +} static int msm_dai_q6_spdif_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, @@ -1475,7 +1622,6 @@ static int msm_dai_q6_spdif_hw_params(struct snd_pcm_substream *substream, { struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dai->dev); - dai->id = AFE_PORT_ID_SPDIF_RX; dai_data->channels = params_channels(params); dai_data->spdif_port.cfg.num_channels = dai_data->channels; switch (params_format(params)) { @@ -1496,7 +1642,7 @@ static int msm_dai_q6_spdif_hw_params(struct snd_pcm_substream *substream, dai_data->bitwidth = dai_data->spdif_port.cfg.bit_width; dai_data->spdif_port.cfg.sample_rate = dai_data->rate; dai_data->spdif_port.cfg.spdif_cfg_minor_version = - AFE_API_VERSION_SPDIF_CONFIG; + AFE_API_VERSION_SPDIF_CONFIG_V2; dev_dbg(dai->dev, " channel %d sample rate %d bit width %d\n", dai_data->channels, dai_data->rate, dai_data->spdif_port.cfg.bit_width); @@ -1520,13 +1666,14 @@ static void msm_dai_q6_spdif_shutdown(struct snd_pcm_substream *substream, if (rc < 0) dev_err(dai->dev, "fail to close AFE port\n"); + dai_data->fmt_event.status = 0; /* report invalid line state */ + pr_debug("%s: dai_data->status_mask = %ld\n", __func__, *dai_data->status_mask); clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); } - static int msm_dai_q6_spdif_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -1534,6 +1681,15 @@ static int msm_dai_q6_spdif_prepare(struct snd_pcm_substream *substream, int rc = 0; if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + rc = afe_spdif_reg_event_cfg(dai->id, + AFE_MODULE_REGISTER_EVENT_FLAG, + msm_dai_q6_spdif_process_event, + dai_data); + if (rc < 0) + dev_err(dai->dev, + "fail to register event for port 0x%x\n", + dai->id); + rc = afe_spdif_port_start(dai->id, &dai_data->spdif_port, dai_data->rate); if (rc < 0) @@ -1550,7 +1706,6 @@ static int msm_dai_q6_spdif_prepare(struct snd_pcm_substream *substream, static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai) { struct msm_dai_q6_spdif_dai_data *dai_data; - const struct snd_kcontrol_new *kcontrol; int rc = 0; struct snd_soc_dapm_route intercon; struct snd_soc_dapm_context *dapm; @@ -1563,17 +1718,67 @@ static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai) GFP_KERNEL); if (!dai_data) { - dev_err(dai->dev, "DAI-%d: fail to allocate dai data\n", - AFE_PORT_ID_SPDIF_RX); rc = -ENOMEM; } else dev_set_drvdata(dai->dev, dai_data); - kcontrol = &spdif_config_controls[1]; - dapm = snd_soc_component_get_dapm(dai->component); + dai->id = dai->driver->id; + dai_data->port_id = dai->id; + + switch (dai->id) { + case AFE_PORT_ID_PRIMARY_SPDIF_RX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&spdif_rx_config_controls[1], + dai_data)); + break; + case AFE_PORT_ID_SECONDARY_SPDIF_RX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&spdif_rx_config_controls[3], + dai_data)); + break; + case AFE_PORT_ID_PRIMARY_SPDIF_TX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&spdif_tx_config_controls[0], + dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&spdif_tx_config_controls[1], + dai_data)); + + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&spdif_tx_status_controls[0], + dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&spdif_tx_status_controls[1], + dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&spdif_tx_status_controls[2], + dai_data)); + break; + case AFE_PORT_ID_SECONDARY_SPDIF_TX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&spdif_tx_config_controls[2], + dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&spdif_tx_config_controls[3], + dai_data)); + + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&spdif_tx_status_controls[3], + dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&spdif_tx_status_controls[4], + dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&spdif_tx_status_controls[5], + dai_data)); + break; + } + if (rc < 0) + dev_err(dai->dev, + "%s: err add config ctl, DAI = %s\n", + __func__, dai->name); - rc = snd_ctl_add(dai->component->card->snd_card, - snd_ctl_new1(kcontrol, dai_data)); + dapm = snd_soc_component_get_dapm(dai->component); memset(&intercon, 0, sizeof(intercon)); if (!rc && dai && dai->driver) { @@ -1610,6 +1815,15 @@ static int msm_dai_q6_spdif_dai_remove(struct snd_soc_dai *dai) /* If AFE port is still up, close it */ if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + rc = afe_spdif_reg_event_cfg(dai->id, + AFE_MODULE_DEREGISTER_EVENT_FLAG, + NULL, + dai_data); + if (rc < 0) + dev_err(dai->dev, + "fail to deregister event for port 0x%x\n", + dai->id); + rc = afe_close(dai->id); /* can block */ if (rc < 0) dev_err(dai->dev, "fail to close AFE port\n"); @@ -1628,21 +1842,106 @@ static struct snd_soc_dai_ops msm_dai_q6_spdif_ops = { .shutdown = msm_dai_q6_spdif_shutdown, }; -static struct snd_soc_dai_driver msm_dai_q6_spdif_spdif_rx_dai = { - .playback = { - .stream_name = "SPDIF Playback", - .aif_name = "SPDIF_RX", - .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | - SNDRV_PCM_RATE_16000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, - .channels_min = 1, - .channels_max = 4, - .rate_min = 8000, - .rate_max = 48000, +static struct snd_soc_dai_driver msm_dai_q6_spdif_spdif_rx_dai[] = { + { + .playback = { + .stream_name = "Primary SPDIF Playback", + .aif_name = "PRI_SPDIF_RX", + .rates = SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 32000, + .rate_max = 192000, + }, + .name = "PRI_SPDIF_RX", + .ops = &msm_dai_q6_spdif_ops, + .id = AFE_PORT_ID_PRIMARY_SPDIF_RX, + .probe = msm_dai_q6_spdif_dai_probe, + .remove = msm_dai_q6_spdif_dai_remove, + }, + { + .playback = { + .stream_name = "Secondary SPDIF Playback", + .aif_name = "SEC_SPDIF_RX", + .rates = SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 32000, + .rate_max = 192000, + }, + .name = "SEC_SPDIF_RX", + .ops = &msm_dai_q6_spdif_ops, + .id = AFE_PORT_ID_SECONDARY_SPDIF_RX, + .probe = msm_dai_q6_spdif_dai_probe, + .remove = msm_dai_q6_spdif_dai_remove, + }, +}; + +static struct snd_soc_dai_driver msm_dai_q6_spdif_spdif_tx_dai[] = { + { + .capture = { + .stream_name = "Primary SPDIF Capture", + .aif_name = "PRI_SPDIF_TX", + .rates = SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 32000, + .rate_max = 192000, + }, + .name = "PRI_SPDIF_TX", + .ops = &msm_dai_q6_spdif_ops, + .id = AFE_PORT_ID_PRIMARY_SPDIF_TX, + .probe = msm_dai_q6_spdif_dai_probe, + .remove = msm_dai_q6_spdif_dai_remove, + }, + { + .capture = { + .stream_name = "Secondary SPDIF Capture", + .aif_name = "SEC_SPDIF_TX", + .rates = SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 32000, + .rate_max = 192000, + }, + .name = "SEC_SPDIF_TX", + .ops = &msm_dai_q6_spdif_ops, + .id = AFE_PORT_ID_SECONDARY_SPDIF_TX, + .probe = msm_dai_q6_spdif_dai_probe, + .remove = msm_dai_q6_spdif_dai_remove, }, - .ops = &msm_dai_q6_spdif_ops, - .probe = msm_dai_q6_spdif_dai_probe, - .remove = msm_dai_q6_spdif_dai_remove, }; static const struct snd_soc_component_driver msm_dai_spdif_q6_component = { @@ -5471,16 +5770,48 @@ static struct platform_driver msm_dai_q6_mi2s_driver = { static int msm_dai_q6_spdif_dev_probe(struct platform_device *pdev) { - int rc; + int rc, id; + const char *q6_dev_id = "qcom,msm-dai-q6-dev-id"; + + rc = of_property_read_u32(pdev->dev.of_node, q6_dev_id, &id); + if (rc) { + dev_err(&pdev->dev, + "%s: missing %s in dt node\n", __func__, q6_dev_id); + return rc; + } - pdev->id = AFE_PORT_ID_SPDIF_RX; + pdev->id = id; pr_debug("%s: dev name %s, id:%d\n", __func__, dev_name(&pdev->dev), pdev->id); - rc = snd_soc_register_component(&pdev->dev, + switch (pdev->id) { + case AFE_PORT_ID_PRIMARY_SPDIF_RX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_spdif_q6_component, + &msm_dai_q6_spdif_spdif_rx_dai[0], 1); + break; + case AFE_PORT_ID_SECONDARY_SPDIF_RX: + rc = snd_soc_register_component(&pdev->dev, &msm_dai_spdif_q6_component, - &msm_dai_q6_spdif_spdif_rx_dai, 1); + &msm_dai_q6_spdif_spdif_rx_dai[1], 1); + break; + case AFE_PORT_ID_PRIMARY_SPDIF_TX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_spdif_q6_component, + &msm_dai_q6_spdif_spdif_tx_dai[0], 1); + break; + case AFE_PORT_ID_SECONDARY_SPDIF_TX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_spdif_q6_component, + &msm_dai_q6_spdif_spdif_tx_dai[1], 1); + break; + default: + dev_err(&pdev->dev, "invalid device ID %d\n", pdev->id); + rc = -ENODEV; + break; + } + return rc; } diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index bda838718855..7ad7460368a8 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -368,8 +368,8 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_SEC_AUXPCM_RX}, { AFE_PORT_ID_SECONDARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SEC_AUXPCM_TX}, - { AFE_PORT_ID_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, - LPASS_BE_SPDIF_RX}, + { AFE_PORT_ID_PRIMARY_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_SPDIF_RX}, { AFE_PORT_ID_SECONDARY_MI2S_RX_SD1, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SEC_MI2S_RX_SD1}, { AFE_PORT_ID_QUINARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, @@ -602,6 +602,12 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_VA_CDC_DMA_TX_0}, { AFE_PORT_ID_VA_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_VA_CDC_DMA_TX_1}, + { AFE_PORT_ID_PRIMARY_SPDIF_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_PRI_SPDIF_TX}, + { AFE_PORT_ID_SECONDARY_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_SPDIF_RX}, + { AFE_PORT_ID_SECONDARY_SPDIF_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_SPDIF_TX}, }; /* Track ASM playback & capture sessions of DAI @@ -1337,7 +1343,9 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, i); if ((passthr_mode == COMPRESSED_PASSTHROUGH_DSD) || (passthr_mode == - COMPRESSED_PASSTHROUGH_GEN)) + COMPRESSED_PASSTHROUGH_GEN) + || (passthr_mode == + COMPRESSED_PASSTHROUGH_IEC61937)) topology = COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY; pr_debug("%s: Before adm open topology %d\n", __func__, topology); @@ -1389,12 +1397,12 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, } } if (passthr_mode != COMPRESSED_PASSTHROUGH_DSD + && passthr_mode != COMPRESSED_PASSTHROUGH_GEN && passthr_mode != - COMPRESSED_PASSTHROUGH_GEN) { + COMPRESSED_PASSTHROUGH_IEC61937) msm_routing_send_device_pp_params( - msm_bedais[i].port_id, - copp_idx, fe_id); - } + msm_bedais[i].port_id, + copp_idx, fe_id); } } if (num_copps) { @@ -1758,7 +1766,7 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) path_type = ADM_PATH_PLAYBACK; } else { session_type = SESSION_TYPE_TX; - if (passthr_mode != LEGACY_PCM) + if ((passthr_mode != LEGACY_PCM) && (passthr_mode != LISTEN)) path_type = ADM_PATH_COMPRESSED_TX; else path_type = ADM_PATH_LIVE_REC; @@ -2999,7 +3007,7 @@ static const char *const be_name[] = { "SLIM_8_TX", "EXTPROC_RX", "EXTPROC_TX", "EXPROC_EC_TX", "QUAT_MI2S_RX", "QUAT_MI2S_TX", "SECOND_MI2S_RX", "SECOND_MI2S_TX", "PRI_MI2S_RX", "PRI_MI2S_TX", "TERT_MI2S_RX", "TERT_MI2S_TX", -"AUDIO_I2S_RX", "SEC_AUXPCM_RX", "SEC_AUXPCM_TX", "SPDIF_RX", +"AUDIO_I2S_RX", "SEC_AUXPCM_RX", "SEC_AUXPCM_TX", "PRI_SPDIF_RX", "SECOND_MI2S_RX_SD1", "QUIN_MI2S_RX", "QUIN_MI2S_TX", "SENARY_MI2S_TX", "PRI_TDM_RX_0", "PRI_TDM_TX_0", "PRI_TDM_RX_1", "PRI_TDM_TX_1", "PRI_TDM_RX_2", "PRI_TDM_TX_2", "PRI_TDM_RX_3", "PRI_TDM_TX_3", @@ -3029,7 +3037,8 @@ static const char *const be_name[] = { "INT4_MI2S_RX", "INT4_MI2S_TX", "INT5_MI2S_RX", "INT5_MI2S_TX", "INT6_MI2S_RX", "INT6_MI2S_TX", "WSA_CDC_DMA_RX_0", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_RX_1", "WSA_CDC_DMA_TX_1", -"WSA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_1" +"WSA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_1", +"PRI_SPDIF_TX", "SEC_SPDIF_RX", "SEC_SPDIF_TX" }; static SOC_ENUM_SINGLE_DECL(mm1_channel_mux, @@ -4206,89 +4215,176 @@ static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = { msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new spdif_rx_mixer_controls[] = { +static const struct snd_kcontrol_new pri_spdif_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sec_spdif_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; @@ -8482,6 +8578,14 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul2_mixer_controls[] = { @@ -8641,6 +8745,14 @@ static const struct snd_kcontrol_new mmul2_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul3_mixer_controls[] = { @@ -8800,6 +8912,14 @@ static const struct snd_kcontrol_new mmul3_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul4_mixer_controls[] = { @@ -8955,6 +9075,14 @@ static const struct snd_kcontrol_new mmul4_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul5_mixer_controls[] = { @@ -9134,6 +9262,14 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul6_mixer_controls[] = { @@ -9293,6 +9429,14 @@ static const struct snd_kcontrol_new mmul6_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul8_mixer_controls[] = { @@ -9456,6 +9600,14 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul16_mixer_controls[] = { @@ -9619,6 +9771,14 @@ static const struct snd_kcontrol_new mmul16_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul9_mixer_controls[] = { @@ -9722,6 +9882,14 @@ static const struct snd_kcontrol_new mmul9_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul10_mixer_controls[] = { @@ -9849,6 +10017,14 @@ static const struct snd_kcontrol_new mmul10_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul17_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, @@ -9911,6 +10087,14 @@ static const struct snd_kcontrol_new mmul17_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul18_mixer_controls[] = { @@ -9926,6 +10110,10 @@ static const struct snd_kcontrol_new mmul18_mixer_controls[] = { MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, @@ -9974,6 +10162,14 @@ static const struct snd_kcontrol_new mmul18_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul19_mixer_controls[] = { @@ -10037,6 +10233,14 @@ static const struct snd_kcontrol_new mmul19_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul20_mixer_controls[] = { @@ -10160,6 +10364,14 @@ static const struct snd_kcontrol_new mmul20_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul28_mixer_controls[] = { @@ -10223,6 +10435,14 @@ static const struct snd_kcontrol_new mmul28_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul29_mixer_controls[] = { @@ -10286,6 +10506,14 @@ static const struct snd_kcontrol_new mmul29_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { @@ -16125,7 +16353,14 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("SEC_I2S_RX", "Secondary I2S Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SPDIF_RX", "SPDIF Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_SPDIF_RX", "Primary SPDIF Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_SPDIF_TX", "Primary SPDIF Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_SPDIF_RX", "Secondary SPDIF Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_SPDIF_TX", "Secondary SPDIF Capture", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_RX", "Slimbus2 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_RX", "Slimbus5 Playback", 0, 0, 0, 0), @@ -16495,8 +16730,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { display_port_mixer_controls, ARRAY_SIZE(display_port_mixer_controls)), SND_SOC_DAPM_MIXER("DISPLAY_PORT1 Mixer", SND_SOC_NOPM, 0, 0, display_port1_mixer_controls, ARRAY_SIZE(display_port1_mixer_controls)), - SND_SOC_DAPM_MIXER("SPDIF_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - spdif_rx_mixer_controls, ARRAY_SIZE(spdif_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_SPDIF_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_spdif_rx_mixer_controls, ARRAY_SIZE(pri_spdif_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_SPDIF_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_spdif_rx_mixer_controls, ARRAY_SIZE(sec_spdif_rx_mixer_controls)), SND_SOC_DAPM_MIXER("MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, mi2s_rx_mixer_controls, ARRAY_SIZE(mi2s_rx_mixer_controls)), SND_SOC_DAPM_MIXER("QUAT_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, @@ -17184,23 +17421,41 @@ static const struct snd_soc_dapm_route intercon[] = { {"DISPLAY_PORT1 Mixer", "MultiMedia16", "MM_DL16"}, {"DISPLAY_PORT1", NULL, "DISPLAY_PORT1 Mixer"}, - {"SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SPDIF_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SPDIF_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SPDIF_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SPDIF_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SPDIF_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SPDIF_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SPDIF_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SPDIF_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SPDIF_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SPDIF_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SPDIF_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SPDIF_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SPDIF_RX", NULL, "SPDIF_RX Audio Mixer"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_SPDIF_RX", NULL, "PRI_SPDIF_RX Audio Mixer"}, + + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_SPDIF_RX", NULL, "SEC_SPDIF_RX Audio Mixer"}, /* incall */ {"Incall_Music Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17300,6 +17555,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia28 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia29 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia8 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia18 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"MultiMedia17 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia18 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia19 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, @@ -17318,6 +17574,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"MultiMedia5 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"MultiMedia10 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia18 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia18 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, {"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, @@ -18036,6 +18295,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia1 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia1 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MultiMedia2 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia2 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -18062,6 +18323,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia2 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia2 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MultiMedia3 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia3 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -18088,6 +18351,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia3 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia3 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MultiMedia4 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia4 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -18114,6 +18379,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia4 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia4 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MultiMedia5 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia5 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -18140,6 +18407,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia5 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia5 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MultiMedia6 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia6 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -18166,6 +18435,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia6 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia6 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MultiMedia8 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia8 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -18193,6 +18464,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia8 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia8 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MultiMedia9 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"MultiMedia9 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, @@ -18212,6 +18485,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia9 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia9 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MultiMedia10 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"MultiMedia10 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, @@ -18252,6 +18527,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia20 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia20 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, @@ -18284,6 +18561,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia16 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia16 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, @@ -19768,7 +20047,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "HDMI"}, {"BE_OUT", NULL, "DISPLAY_PORT"}, {"BE_OUT", NULL, "DISPLAY_PORT1"}, - {"BE_OUT", NULL, "SPDIF_RX"}, + {"BE_OUT", NULL, "PRI_SPDIF_RX"}, + {"BE_OUT", NULL, "SEC_SPDIF_RX"}, {"BE_OUT", NULL, "MI2S_RX"}, {"BE_OUT", NULL, "QUAT_MI2S_RX"}, {"BE_OUT", NULL, "QUIN_MI2S_RX"}, @@ -19897,6 +20177,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"WSA_CDC_DMA_TX_2", NULL, "BE_IN"}, {"VA_CDC_DMA_TX_0", NULL, "BE_IN"}, {"VA_CDC_DMA_TX_1", NULL, "BE_IN"}, + {"PRI_SPDIF_TX", NULL, "BE_IN"}, + {"SEC_SPDIF_TX", NULL, "BE_IN"}, }; @@ -20036,7 +20318,11 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) path_type = ADM_PATH_PLAYBACK; session_type = SESSION_TYPE_RX; } else { - path_type = ADM_PATH_LIVE_REC; + if ((bedai->passthr_mode[i] != LEGACY_PCM) && + (bedai->passthr_mode[i] != LISTEN)) + path_type = ADM_PATH_COMPRESSED_TX; + else + path_type = ADM_PATH_LIVE_REC; session_type = SESSION_TYPE_TX; } @@ -20094,6 +20380,15 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) fe_dai_app_type_cfg[i][session_type][be_id].acdb_dev_id; topology = msm_routing_get_adm_topology(i, session_type, be_id); + + if ((bedai->passthr_mode[i] == + COMPRESSED_PASSTHROUGH_DSD) + || (bedai->passthr_mode[i] == + COMPRESSED_PASSTHROUGH_GEN) + || (bedai->passthr_mode[i] == + COMPRESSED_PASSTHROUGH_IEC61937)) + topology = COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY; + copp_idx = adm_open(bedai->port_id, path_type, sample_rate, channels, topology, fdai->perf_mode, bits_per_sample, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index b8006bc13e6c..2a786af79eb1 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -48,7 +48,10 @@ #define LPASS_BE_INCALL_RECORD_RX "INCALL_RECORD_RX" #define LPASS_BE_INCALL_RECORD_TX "INCALL_RECORD_TX" #define LPASS_BE_SEC_I2S_RX "SECONDARY_I2S_RX" -#define LPASS_BE_SPDIF_RX "SPDIF_RX" +#define LPASS_BE_PRI_SPDIF_RX "PRI_SPDIF_RX" +#define LPASS_BE_PRI_SPDIF_TX "PRI_SPDIF_TX" +#define LPASS_BE_SEC_SPDIF_RX "SEC_SPDIF_RX" +#define LPASS_BE_SEC_SPDIF_TX "SEC_SPDIF_TX" #define LPASS_BE_MI2S_RX "MI2S_RX" #define LPASS_BE_MI2S_TX "MI2S_TX" @@ -299,7 +302,7 @@ enum { MSM_BACKEND_DAI_AUDIO_I2S_RX, MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_BACKEND_DAI_SPDIF_RX, + MSM_BACKEND_DAI_PRI_SPDIF_RX, MSM_BACKEND_DAI_SECONDARY_MI2S_RX_SD1, MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_BACKEND_DAI_QUINARY_MI2S_TX, @@ -416,6 +419,9 @@ enum { MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_BACKEND_DAI_SEC_SPDIF_RX, + MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_BACKEND_DAI_MAX, }; -- GitLab From 2257355fe4091dd589b672537e1527c7ea4bdef7 Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Wed, 20 Jun 2018 11:30:58 +0200 Subject: [PATCH 0406/1645] asoc: Support compressed capture from AFE interfaces Support compressed IEC61937 audio capture from AFE interfaces with variable data packet lengths. Change-Id: Iffd5a06ed5fe1a96f34e225d54fab660b21d2a48 Signed-off-by: Ralf Herz --- asoc/msm-compress-q6-v2.c | 73 ++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index c0d8614559f1..6fb61da19536 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -540,7 +540,7 @@ static int msm_compr_read_buffer(struct msm_compr_audio *prtd) __func__, ret); return ret; } - prtd->bytes_read += buffer_length; + prtd->bytes_read += buffer_length + prtd->ts_header_offset; prtd->bytes_read_offset += buffer_length + prtd->ts_header_offset; if (prtd->bytes_read_offset >= prtd->buffer_size) prtd->bytes_read_offset -= prtd->buffer_size; @@ -676,9 +676,8 @@ static void compr_event_handler(uint32_t opcode, if (prtd->ts_header_offset) { /* Update the header for received buffer */ buff_addr = prtd->buffer + prtd->byte_offset; - /* Write the length of the buffer */ - *buff_addr = prtd->codec_param.buffer.fragment_size - - prtd->ts_header_offset; + /* Write the actual length of the received buffer */ + *buff_addr = payload[4]; buff_addr++; /* Write the offset */ *buff_addr = prtd->ts_header_offset; @@ -1457,28 +1456,54 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream) break; } - pr_debug("%s: stream_id %d bits_per_sample %d\n", - __func__, ac->stream_id, bits_per_sample); + pr_debug("%s: stream_id %d bits_per_sample %d compr_passthr %d\n", + __func__, ac->stream_id, bits_per_sample, + prtd->compr_passthr); - if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG) { - ret = q6asm_open_read_v4(prtd->audio_client, prtd->codec, - bits_per_sample, true, enc_cfg_id); + if (prtd->compr_passthr != LEGACY_PCM) { + ret = q6asm_open_read_compressed(prtd->audio_client, + prtd->codec, prtd->compr_passthr); + if (ret < 0) { + pr_err("%s:ASM open read err[%d] for compr_type[%d]\n", + __func__, ret, prtd->compr_passthr); + return ret; + } + + ret = msm_pcm_routing_reg_phy_compr_stream( + soc_prtd->dai_link->id, + ac->perf_mode, + prtd->session_id, + SNDRV_PCM_STREAM_CAPTURE, + prtd->compr_passthr); + if (ret) { + pr_err("%s: compr stream reg failed:%d\n", + __func__, ret); + return ret; + } } else { - ret = q6asm_open_read_v4(prtd->audio_client, prtd->codec, - bits_per_sample, false, enc_cfg_id); - } - if (ret < 0) { - pr_err("%s: q6asm_open_read failed:%d\n", __func__, ret); - return ret; - } + if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG) { + ret = q6asm_open_read_v4(prtd->audio_client, + prtd->codec, + bits_per_sample, true, enc_cfg_id); + } else { + ret = q6asm_open_read_v4(prtd->audio_client, + prtd->codec, + bits_per_sample, false, enc_cfg_id); + } + if (ret < 0) { + pr_err("%s: q6asm_open_read failed:%d\n", + __func__, ret); + return ret; + } - ret = msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->id, - ac->perf_mode, - prtd->session_id, - SNDRV_PCM_STREAM_CAPTURE); - if (ret) { - pr_err("%s: stream reg failed:%d\n", __func__, ret); - return ret; + ret = msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->id, + ac->perf_mode, + prtd->session_id, + SNDRV_PCM_STREAM_CAPTURE); + if (ret) { + pr_err("%s: stream reg failed:%d\n", __func__, ret); + return ret; + } } ret = q6asm_set_io_mode(ac, (COMPRESSED_STREAM_IO | ASYNC_IO_MODE)); @@ -1533,7 +1558,7 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream) ret = q6asm_enc_cfg_blk_custom(prtd->audio_client, prtd->sample_rate, prtd->num_channels, prtd->codec, (void *)&prtd->codec_param.codec.options.generic); - } else { + } else if (prtd->compr_passthr == LEGACY_PCM) { ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client, prtd->sample_rate, prtd->num_channels, bits_per_sample, sample_word_size, -- GitLab From bdc080d18fae1dc9d306788e752aebc38052173a Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Thu, 21 Jun 2018 18:56:10 +0200 Subject: [PATCH 0407/1645] asoc: qcs405: Add support for AFE SPDIF interfaces Add support for AFE SPDIF input and output interfaces for QCS405 platform Change-Id: Ieacd0524046376f237b325d6dcab071c80a4b657 Signed-off-by: Ralf Herz --- asoc/qcs405.c | 670 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 669 insertions(+), 1 deletion(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 1f62d66683c8..e274db21b758 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -61,6 +61,10 @@ #define SAMPLING_RATE_352P8KHZ 352800 #define SAMPLING_RATE_384KHZ 384000 +#define SPDIF_TX_CORE_CLK_204_P8_MHZ 204800000 +#define TLMM_EAST_SPARE 0x07BA0000 +#define TLMM_SPDIF_HDMI_ARC_CTL 0x07BA2000 + #define WSA8810_NAME_1 "wsa881x.20170211" #define WSA8810_NAME_2 "wsa881x.20170212" #define WCN_CDC_SLIM_RX_CH_MAX 2 @@ -128,6 +132,18 @@ enum { CDC_DMA_TX_MAX, }; +enum { + PRIM_SPDIF_RX = 0, + SEC_SPDIF_RX, + SPDIF_RX_MAX, +}; + +enum { + PRIM_SPDIF_TX = 0, + SEC_SPDIF_TX, + SPDIF_TX_MAX, +}; + struct mi2s_conf { struct mutex lock; u32 ref_cnt; @@ -396,6 +412,17 @@ static struct dev_config mi2s_rx_cfg[] = { [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, }; +/* Default configuration of SPDIF channels */ +static struct dev_config spdif_rx_cfg[] = { + [PRIM_SPDIF_RX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SEC_SPDIF_RX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config spdif_tx_cfg[] = { + [PRIM_SPDIF_TX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SEC_SPDIF_TX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + static struct dev_config mi2s_tx_cfg[] = { [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, @@ -470,6 +497,12 @@ static char const *cdc_dma_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_88P2", "KHZ_96", "KHZ_176P4", "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static const char *spdif_rate_text[] = {"KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192"}; +static const char *spdif_ch_text[] = {"One", "Two"}; +static const char *spdif_bit_format_text[] = {"S16_LE", "S24_LE"}; + static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text); @@ -561,6 +594,12 @@ static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_0_sample_rate, cdc_dma_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_1_sample_rate, cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(spdif_rx_sample_rate, spdif_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(spdif_tx_sample_rate, spdif_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(spdif_rx_chs, spdif_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(spdif_tx_chs, spdif_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(spdif_rx_format, spdif_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(spdif_tx_format, spdif_bit_format_text); static struct platform_device *spdev; @@ -2904,6 +2943,337 @@ static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol, return 0; } +static int spdif_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_SPDIF_RX", + sizeof("PRIM_SPDIF_RX"))) + idx = PRIM_SPDIF_RX; + else if (strnstr(kcontrol->id.name, "SEC_SPDIF_RX", + sizeof("SEC_SPDIF_RX"))) + idx = SEC_SPDIF_RX; + else if (strnstr(kcontrol->id.name, "PRIM_SPDIF_TX", + sizeof("PRIM_SPDIF_TX"))) + idx = PRIM_SPDIF_TX; + else if (strnstr(kcontrol->id.name, "SEC_SPDIF_TX", + sizeof("SEC_SPDIF_TX"))) + idx = SEC_SPDIF_TX; + else { + pr_err("%s: unsupported channel: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int spdif_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_32KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 6; + break; + default: + sample_rate_val = 2; + break; + } + return sample_rate_val; +} + +static int spdif_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_192KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int spdif_get_format(int value) +{ + int format; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int spdif_get_format_value(int format) +{ + int value; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + default: + value = 0; + break; + } + return value; +} + +static int msm_spdif_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = spdif_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + spdif_rx_cfg[idx].sample_rate = + spdif_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, spdif_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_spdif_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = spdif_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + spdif_get_sample_rate_val(spdif_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, spdif_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_spdif_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = spdif_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + spdif_tx_cfg[idx].sample_rate = + spdif_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, spdif_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_spdif_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = spdif_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + spdif_get_sample_rate_val(spdif_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, spdif_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_spdif_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = spdif_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_spdif_[%d]_rx_ch = %d\n", __func__, + idx, spdif_rx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = spdif_rx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_spdif_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = spdif_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + spdif_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_spdif_[%d]_rx_ch = %d\n", __func__, + idx, spdif_rx_cfg[idx].channels); + + return 1; +} + +static int msm_spdif_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = spdif_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_spdif_[%d]_tx_ch = %d\n", __func__, + idx, spdif_tx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = spdif_tx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_spdif_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = spdif_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + spdif_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_spdif_[%d]_tx_ch = %d\n", __func__, + idx, spdif_tx_cfg[idx].channels); + + return 1; +} + +static int msm_spdif_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = spdif_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + spdif_get_format_value(spdif_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, spdif_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_spdif_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = spdif_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + spdif_rx_cfg[idx].bit_format = + spdif_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, spdif_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_spdif_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = spdif_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + spdif_get_format_value(spdif_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, spdif_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_spdif_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = spdif_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + spdif_tx_cfg[idx].bit_format = + spdif_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, spdif_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + static const struct snd_kcontrol_new msm_snd_sb_controls[] = { SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, slim_rx_ch_get, slim_rx_ch_put), @@ -3231,6 +3601,34 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), SOC_SINGLE_MULTI_EXT("VAD CFG", SND_SOC_NOPM, 0, 1000, 0, 3, NULL, msm_snd_vad_cfg_put), + SOC_ENUM_EXT("PRIM_SPDIF_RX SampleRate", spdif_rx_sample_rate, + msm_spdif_rx_sample_rate_get, + msm_spdif_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_SPDIF_TX SampleRate", spdif_tx_sample_rate, + msm_spdif_tx_sample_rate_get, + msm_spdif_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_SPDIF_RX SampleRate", spdif_rx_sample_rate, + msm_spdif_rx_sample_rate_get, + msm_spdif_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_SPDIF_TX SampleRate", spdif_tx_sample_rate, + msm_spdif_tx_sample_rate_get, + msm_spdif_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_SPDIF_RX Channels", spdif_rx_chs, + msm_spdif_rx_ch_get, msm_spdif_rx_ch_put), + SOC_ENUM_EXT("PRIM_SPDIF_TX Channels", spdif_tx_chs, + msm_spdif_tx_ch_get, msm_spdif_tx_ch_put), + SOC_ENUM_EXT("SEC_SPDIF_RX Channels", spdif_rx_chs, + msm_spdif_rx_ch_get, msm_spdif_rx_ch_put), + SOC_ENUM_EXT("SEC_SPDIF_TX Channels", spdif_tx_chs, + msm_spdif_tx_ch_get, msm_spdif_tx_ch_put), + SOC_ENUM_EXT("PRIM_SPDIF_RX Format", spdif_rx_format, + msm_spdif_rx_format_get, msm_spdif_rx_format_put), + SOC_ENUM_EXT("PRIM_SPDIF_TX Format", spdif_tx_format, + msm_spdif_tx_format_get, msm_spdif_tx_format_put), + SOC_ENUM_EXT("SEC_SPDIF_RX Format", spdif_rx_format, + msm_spdif_rx_format_get, msm_spdif_rx_format_put), + SOC_ENUM_EXT("SEC_SPDIF_TX Format", spdif_tx_format, + msm_spdif_tx_format_get, msm_spdif_tx_format_put), }; static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, @@ -3929,6 +4327,42 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, channels->min = channels->max = msm_vi_feed_tx_ch; break; + case MSM_BACKEND_DAI_PRI_SPDIF_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + spdif_rx_cfg[PRIM_SPDIF_RX].bit_format); + rate->min = rate->max = + spdif_rx_cfg[PRIM_SPDIF_RX].sample_rate; + channels->min = channels->max = + spdif_rx_cfg[PRIM_SPDIF_RX].channels; + break; + + case MSM_BACKEND_DAI_PRI_SPDIF_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + spdif_tx_cfg[PRIM_SPDIF_TX].bit_format); + rate->min = rate->max = + spdif_tx_cfg[PRIM_SPDIF_TX].sample_rate; + channels->min = channels->max = + spdif_tx_cfg[PRIM_SPDIF_TX].channels; + break; + + case MSM_BACKEND_DAI_SEC_SPDIF_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + spdif_rx_cfg[SEC_SPDIF_RX].bit_format); + rate->min = rate->max = + spdif_rx_cfg[SEC_SPDIF_RX].sample_rate; + channels->min = channels->max = + spdif_rx_cfg[SEC_SPDIF_RX].channels; + break; + + case MSM_BACKEND_DAI_SEC_SPDIF_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + spdif_tx_cfg[SEC_SPDIF_TX].bit_format); + rate->min = rate->max = + spdif_tx_cfg[SEC_SPDIF_TX].sample_rate; + channels->min = channels->max = + spdif_tx_cfg[SEC_SPDIF_TX].channels; + break; + default: rate->min = rate->max = SAMPLING_RATE_48KHZ; break; @@ -5115,6 +5549,136 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) mutex_unlock(&mi2s_intf_conf[index].lock); } +static int msm_spdif_set_clk(struct snd_pcm_substream *substream, bool enable) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int port_id = cpu_dai->id; + struct afe_clk_set clk_cfg; + + clk_cfg.clk_set_minor_version = Q6AFE_LPASS_CLK_CONFIG_API_VERSION; + clk_cfg.clk_attri = Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO; + clk_cfg.clk_root = Q6AFE_LPASS_CLK_ROOT_DEFAULT; + clk_cfg.enable = enable; + + /* Set core clock (based on sample rate for RX, fixed for TX) */ + switch (port_id) { + case AFE_PORT_ID_PRIMARY_SPDIF_RX: + clk_cfg.clk_id = AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_OUTPUT_CORE; + /* rate x 2ch x 2_for_biphase_coding x 32_bits_per_sample */ + clk_cfg.clk_freq_in_hz = + spdif_rx_cfg[PRIM_SPDIF_RX].sample_rate * 2 * 2 * 32; + break; + case AFE_PORT_ID_SECONDARY_SPDIF_RX: + clk_cfg.clk_id = AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_OUTPUT_CORE; + clk_cfg.clk_freq_in_hz = + spdif_rx_cfg[SEC_SPDIF_RX].sample_rate * 2 * 2 * 32; + break; + case AFE_PORT_ID_PRIMARY_SPDIF_TX: + clk_cfg.clk_id = AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_INPUT_CORE; + clk_cfg.clk_freq_in_hz = SPDIF_TX_CORE_CLK_204_P8_MHZ; + break; + case AFE_PORT_ID_SECONDARY_SPDIF_TX: + clk_cfg.clk_id = AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_INPUT_CORE; + clk_cfg.clk_freq_in_hz = SPDIF_TX_CORE_CLK_204_P8_MHZ; + break; + } + + ret = afe_set_lpass_clock_v2(port_id, &clk_cfg); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed for port 0x%x , err:%d\n", + __func__, port_id, ret); + goto err; + } + + /* Set NPL clock for RX in addition */ + switch (port_id) { + case AFE_PORT_ID_PRIMARY_SPDIF_RX: + clk_cfg.clk_id = AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_OUTPUT_NPL; + + ret = afe_set_lpass_clock_v2(port_id, &clk_cfg); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe NPL failed port 0x%x, err:%d\n", + __func__, port_id, ret); + goto err; + } + break; + case AFE_PORT_ID_SECONDARY_SPDIF_RX: + clk_cfg.clk_id = AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_OUTPUT_NPL; + + ret = afe_set_lpass_clock_v2(port_id, &clk_cfg); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe NPL failed for port 0x%x, err:%d\n", + __func__, port_id, ret); + goto err; + } + break; + } + + if (enable) { + dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, + clk_cfg.clk_freq_in_hz); + } + +err: + return ret; +} + +static int msm_spdif_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int port_id = cpu_dai->id; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + if (port_id < AFE_PORT_ID_PRIMARY_SPDIF_RX || + port_id > AFE_PORT_ID_SECONDARY_SPDIF_TX) { + ret = -EINVAL; + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto err; + } + + ret = msm_spdif_set_clk(substream, true); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed to enable (%d), err:%d\n", + __func__, port_id, ret); + } +err: + return ret; +} + +static void msm_spdif_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int port_id = rtd->cpu_dai->id; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + if (port_id < AFE_PORT_ID_PRIMARY_SPDIF_RX || + port_id > AFE_PORT_ID_SECONDARY_SPDIF_TX) { + pr_err("%s:invalid SPDIF DAI(%d)\n", __func__, port_id); + return; + } + + ret = msm_spdif_set_clk(substream, false); + if (ret < 0) + pr_err("%s:clock disable failed for SPDIF (%d); ret=%d\n", + __func__, port_id, ret); +} + static struct snd_soc_ops msm_mi2s_be_ops = { .startup = msm_mi2s_snd_startup, .shutdown = msm_mi2s_snd_shutdown, @@ -5132,6 +5696,11 @@ static struct snd_soc_ops msm_wcn_ops = { .hw_params = msm_wcn_hw_params, }; +static struct snd_soc_ops msm_spdif_be_ops = { + .startup = msm_spdif_snd_startup, + .shutdown = msm_spdif_snd_shutdown, +}; + /* Digital audio interface glue - connects codec <---> CPU */ static struct snd_soc_dai_link msm_common_dai_links[] = { @@ -5787,6 +6356,20 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, + { + .name = MSM_DAILINK_NAME(Compr Capture), + .stream_name = "Compr Capture", + .cpu_dai_name = "MultiMedia18", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA18, + }, }; static struct snd_soc_dai_link msm_common_be_dai_links[] = { @@ -6648,6 +7231,67 @@ static struct snd_soc_dai_link msm_va_cdc_dma_be_dai_links[] = { }, }; +static struct snd_soc_dai_link msm_spdif_be_dai_links[] = { + { + .name = LPASS_BE_PRI_SPDIF_RX, + .stream_name = "Primary SPDIF Playback", + .cpu_dai_name = "msm-dai-q6-spdif.20480", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_SPDIF_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_spdif_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_SPDIF_TX, + .stream_name = "Primary SPDIF Capture", + .cpu_dai_name = "msm-dai-q6-spdif.20481", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_SPDIF_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_spdif_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_SPDIF_RX, + .stream_name = "Secondary SPDIF Playback", + .cpu_dai_name = "msm-dai-q6-spdif.20482", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_SPDIF_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_spdif_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_SPDIF_TX, + .stream_name = "Secondary SPDIF Capture", + .cpu_dai_name = "msm-dai-q6-spdif.20483", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_SPDIF_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_spdif_be_ops, + .ignore_suspend = 1, + }, +}; + static struct snd_soc_dai_link msm_qcs405_dai_links[ ARRAY_SIZE(msm_common_dai_links) + ARRAY_SIZE(msm_common_misc_fe_dai_links) + @@ -6658,7 +7302,8 @@ static struct snd_soc_dai_link msm_qcs405_dai_links[ ARRAY_SIZE(msm_auxpcm_be_dai_links) + ARRAY_SIZE(msm_va_cdc_dma_be_dai_links) + ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links) + - ARRAY_SIZE(msm_bolero_fe_dai_links)]; + ARRAY_SIZE(msm_bolero_fe_dai_links) + + ARRAY_SIZE(msm_spdif_be_dai_links)]; static int msm_snd_card_tasha_late_probe(struct snd_soc_card *card) { @@ -6907,7 +7552,9 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) int total_links = 0; uint32_t tasha_codec = 0, auxpcm_audio_intf = 0; uint32_t va_bolero_codec = 0, wsa_bolero_codec = 0, mi2s_audio_intf = 0; + uint32_t spdif_audio_intf = 0; const struct of_device_id *match; + char __iomem *spdif_cfg, *spdif_pin_ctl; int rc = 0; match = of_match_node(qcs405_asoc_machine_of_match, dev->of_node); @@ -7028,6 +7675,27 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) ARRAY_SIZE(msm_auxpcm_be_dai_links); } } + rc = of_property_read_u32(dev->of_node, "qcom,spdif-audio-intf", + &spdif_audio_intf); + if (rc) { + dev_dbg(dev, "%s: No DT match SPDIF audio interface\n", + __func__); + } else { + if (spdif_audio_intf) { + memcpy(msm_qcs405_dai_links + total_links, + msm_spdif_be_dai_links, + sizeof(msm_spdif_be_dai_links)); + total_links += + ARRAY_SIZE(msm_spdif_be_dai_links); + + /* enable spdif coax pins */ + spdif_cfg = ioremap(TLMM_EAST_SPARE, 0x4); + spdif_pin_ctl = + ioremap(TLMM_SPDIF_HDMI_ARC_CTL, 0x4); + iowrite32(0xc0, spdif_cfg); + iowrite32(0x2220, spdif_pin_ctl); + } + } dailink = msm_qcs405_dai_links; } else if (!strcmp(match->data, "stub_codec")) { card = &snd_soc_card_stub_msm; -- GitLab From 68fa135810e4257ed19ea590cb25de540887912b Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 27 Jul 2018 00:41:11 +0530 Subject: [PATCH 0408/1645] ASoC: sm8150: change of_property_read_bool to type u32 of_property_read_bool prevents an overlay to set it false as /delete-property/ is not supported in device tree overlay. Use of_property_read_u32 to read property to allow it to be changed in overlay device tree. Change-Id: Ic1ae38d99999b3ff7e268a6360d55fc2624c0b6f Signed-off-by: Sudheer Papothi --- asoc/sm8150.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/asoc/sm8150.c b/asoc/sm8150.c index 606ce1dc856c..5f3fc8f6e9c7 100644 --- a/asoc/sm8150.c +++ b/asoc/sm8150.c @@ -6958,6 +6958,8 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) int len_1, len_2, len_3, len_4; int total_links; const struct of_device_id *match; + int ret = 0; + u32 val = 0; match = of_match_node(sm8150_asoc_machine_of_match, dev->of_node); if (!match) { @@ -6989,7 +6991,8 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) msm_pahu_be_dai_links, sizeof(msm_pahu_be_dai_links)); - if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + ret = of_property_read_u32(dev->of_node, "qcom,wcn-btfm", &val); + if (!ret && val) { dev_dbg(dev, "%s(): WCN BTFM support present\n", __func__); memcpy(msm_pahu_snd_card_dai_links + total_links, @@ -6998,8 +7001,9 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) total_links += ARRAY_SIZE(msm_wcn_be_dai_links); } - if (of_property_read_bool(dev->of_node, - "qcom,ext-disp-audio-rx")) { + ret = of_property_read_u32(dev->of_node, + "qcom,ext-disp-audio-rx", &val); + if (!ret && val) { dev_dbg(dev, "%s(): ext disp audio support present\n", __func__); memcpy(msm_pahu_snd_card_dai_links + total_links, @@ -7007,15 +7011,19 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) sizeof(ext_disp_be_dai_link)); total_links += ARRAY_SIZE(ext_disp_be_dai_link); } - if (of_property_read_bool(dev->of_node, - "qcom,mi2s-audio-intf")) { + + ret = of_property_read_u32(dev->of_node, + "qcom,mi2s-audio-intf", &val); + if (!ret && val) { memcpy(msm_pahu_snd_card_dai_links + total_links, msm_mi2s_be_dai_links, sizeof(msm_mi2s_be_dai_links)); total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); } - if (of_property_read_bool(dev->of_node, - "qcom,auxpcm-audio-intf")) { + + ret = of_property_read_u32(dev->of_node, + "qcom,auxpcm-audio-intf", &val); + if (!ret && val) { memcpy(msm_pahu_snd_card_dai_links + total_links, msm_auxpcm_be_dai_links, sizeof(msm_auxpcm_be_dai_links)); @@ -7046,7 +7054,8 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) msm_tavil_be_dai_links, sizeof(msm_tavil_be_dai_links)); - if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + ret = of_property_read_u32(dev->of_node, "qcom,wcn-btfm", &val); + if (!ret && val) { dev_dbg(dev, "%s(): WCN BTFM support present\n", __func__); memcpy(msm_tavil_dai_links + total_links, @@ -7055,8 +7064,9 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) total_links += ARRAY_SIZE(msm_wcn_be_dai_links); } - if (of_property_read_bool(dev->of_node, - "qcom,ext-disp-audio-rx")) { + ret = of_property_read_u32(dev->of_node, + "qcom,ext-disp-audio-rx", &val); + if (!ret && val) { dev_dbg(dev, "%s(): ext disp audio support present\n", __func__); memcpy(msm_tavil_dai_links + total_links, @@ -7064,15 +7074,19 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) sizeof(ext_disp_be_dai_link)); total_links += ARRAY_SIZE(ext_disp_be_dai_link); } - if (of_property_read_bool(dev->of_node, - "qcom,mi2s-audio-intf")) { + + ret = of_property_read_u32(dev->of_node, + "qcom,mi2s-audio-intf", &val); + if (!ret && val) { memcpy(msm_tavil_dai_links + total_links, msm_mi2s_be_dai_links, sizeof(msm_mi2s_be_dai_links)); total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); } - if (of_property_read_bool(dev->of_node, - "qcom,auxpcm-audio-intf")) { + + ret = of_property_read_u32(dev->of_node, + "qcom,auxpcm-audio-intf", &val); + if (!ret && val) { memcpy(msm_tavil_dai_links + total_links, msm_auxpcm_be_dai_links, sizeof(msm_auxpcm_be_dai_links)); -- GitLab From 9bc7b45fc90097f27a2925ae2a2609b641687368 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 25 Jul 2018 12:41:03 -0700 Subject: [PATCH 0409/1645] asoc: codecs: delay codec irq handler during ssr Put the irq handler of codec device to sleep if device is not up, to allow other threads to execute meanwhile the device will be up. Change-Id: Ic7421bdf236be52070b6d5fcd774b0641368bf2b Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd9xxx-irq.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/asoc/codecs/wcd9xxx-irq.c b/asoc/codecs/wcd9xxx-irq.c index b192e992d1fa..ad15470a393f 100644 --- a/asoc/codecs/wcd9xxx-irq.c +++ b/asoc/codecs/wcd9xxx-irq.c @@ -295,6 +295,7 @@ static irqreturn_t wcd9xxx_irq_thread(int irq, void *data) static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 1); struct wcd9xxx_core_resource *wcd9xxx_res = data; int num_irq_regs = wcd9xxx_res->num_irq_regs; + struct wcd9xxx *wcd9xxx; u8 status[4], status1[4] = {0}, unmask_status[4] = {0}; if (unlikely(wcd9xxx_lock_sleep(wcd9xxx_res) == false)) { @@ -309,6 +310,23 @@ static irqreturn_t wcd9xxx_irq_thread(int irq, void *data) goto err_disable_irq; } + wcd9xxx = (struct wcd9xxx *)wcd9xxx_res->parent; + if (!wcd9xxx) { + dev_err(wcd9xxx_res->dev, + "%s: Codec core not supplied\n", __func__); + goto err_disable_irq; + } + + if (!wcd9xxx->dev_up) { + dev_info_ratelimited(wcd9xxx_res->dev, "wcd9xxx dev not up\n"); + /* + * sleep to not block the core when device is + * not up (slimbus will not be available) to + * process interrupts. + */ + msleep(10); + } + memset(status, 0, sizeof(status)); ret = regmap_bulk_read(wcd9xxx_res->wcd_core_regmap, wcd9xxx_res->intr_reg[WCD9XXX_INTR_STATUS_BASE], -- GitLab From a1eb93864a50ba240a6799478907e2e5c2110d00 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 25 Jul 2018 10:52:58 -0700 Subject: [PATCH 0410/1645] asoc: msm-pcm-routing: add tdm echo reference route Add route to connect echo reference mux to secondary tdm port for tdm ec ref use cases. Change-Id: I8ae7abadca6f19683d689299bc15c41e0e42472f Signed-off-by: Karthikeyan Mani --- asoc/msm-pcm-routing-v2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index bda838718855..bbdea86ef388 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -18670,6 +18670,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VOC_EXT_EC MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"VOC_EXT_EC MUX", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"VOC_EXT_EC MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"VOC_EXT_EC MUX", "SEC_TDM_TX", "SEC_TDM_TX_0"}, {"VOIP_UL", NULL, "VOC_EXT_EC MUX"}, {"VOICEMMODE1_UL", NULL, "VOC_EXT_EC MUX"}, {"VOICEMMODE2_UL", NULL, "VOC_EXT_EC MUX"}, -- GitLab From 706e66e16e22d9799295481c3e4aefd82505f9b0 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 27 Jul 2018 17:55:25 +0530 Subject: [PATCH 0411/1645] asoc: qcs405: Fix cpu dai node of VI sense dailink In qcs405 machine driver, update cpu dai node name to use same name as defined in dai q6 driver. Change-Id: I21baf5445bb35c0cc8e030436cfd310c91168ea1 Signed-off-by: Laxminath Kasam --- asoc/qcs405.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 1f62d66683c8..be9ed2f0066a 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -5725,7 +5725,7 @@ static struct snd_soc_dai_link msm_bolero_fe_dai_links[] = { { .name = LPASS_BE_WSA_CDC_DMA_TX_0, .stream_name = "WSA CDC DMA0 Capture", - .cpu_dai_name = "msm-dai-cdc-dma.45057", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45057", .platform_name = "msm-pcm-hostless", .codec_name = "bolero_codec", .codec_dai_name = "wsa_macro_vifeedback", -- GitLab From 5f30251f7e4976229f14d1b179d2ecc52995e591 Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Thu, 21 Jun 2018 18:50:09 +0200 Subject: [PATCH 0412/1645] asoc: codecs: codec driver support for ep92 HDMI bridge Codec driver to support Explore EP92A6 HDMI bridge chip. Change-Id: I18132ee465180703a018a4e3c1f3d6418253410c Signed-off-by: Ralf Herz --- Makefile.am | 1 + asoc/codecs/ep92/Android.mk | 50 ++ asoc/codecs/ep92/Kbuild | 106 +++ asoc/codecs/ep92/ep92.c | 1382 +++++++++++++++++++++++++++++++++++ asoc/codecs/ep92/ep92.h | 202 +++++ 5 files changed, 1741 insertions(+) create mode 100644 asoc/codecs/ep92/Android.mk create mode 100644 asoc/codecs/ep92/Kbuild create mode 100644 asoc/codecs/ep92/ep92.c create mode 100644 asoc/codecs/ep92/ep92.h diff --git a/Makefile.am b/Makefile.am index d9724cd70d32..bd60e53769a6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -42,6 +42,7 @@ endif ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), qcs40x)) obj-m += asoc/codecs/bolero/ obj-m += asoc/codecs/csra66x0/ +obj-m += asoc/codecs/ep92/ endif all: diff --git a/asoc/codecs/ep92/Android.mk b/asoc/codecs/ep92/Android.mk new file mode 100644 index 000000000000..c2ac0599f7d8 --- /dev/null +++ b/asoc/codecs/ep92/Android.mk @@ -0,0 +1,50 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,qcs405),true) +AUDIO_SELECT := CONFIG_SND_SOC_QCS405=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,qcs405),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=ep92_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_ep92.ko +LOCAL_MODULE_KBUILD_NAME := ep92_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/asoc/codecs/ep92/Kbuild b/asoc/codecs/ep92/Kbuild new file mode 100644 index 000000000000..1c54a44dcfa9 --- /dev/null +++ b/asoc/codecs/ep92/Kbuild @@ -0,0 +1,106 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + + + +ifeq ($(KERNEL_BUILD), 1) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) + ifeq ($(CONFIG_ARCH_QCS405), y) + include $(AUDIO_ROOT)/config/qcs405auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h + endif +endif + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ EP92 ############ + +# for EP92 Codec +ifdef CONFIG_SND_SOC_EP92 + EP92_OBJS += ep92.o +endif + +LINUX_INC += -Iinclude/linux + +INCS += $(COMMON_INC) \ + $(UAPI_INC) + +#EXTRA_CFLAGS += $(INCS) +ccflags-y += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +#EXTRA_CFLAGS += -Wmaybe-uninitialized +ccflags-y += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +#EXTRA_CFLAGS += -Wheader-guard +ccflags-y += -Wheader-guard +endif + +ifeq ($(KERNEL_BUILD), 0) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_EP92) += ep92_dlkm.o +ep92_dlkm-y := $(EP92_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/ep92/ep92.c b/asoc/codecs/ep92/ep92.c new file mode 100644 index 000000000000..73110da7ec04 --- /dev/null +++ b/asoc/codecs/ep92/ep92.c @@ -0,0 +1,1382 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ep92.h" + +#define EP92_POLL_INTERVAL_OFF_MSEC 2000 +#define EP92_POLL_INTERVAL_ON_MSEC 100 + + +#define EP92_RATES (SNDRV_PCM_RATE_32000 |\ + SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000) + +#define EP92_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) + +#define EP92_UEVENT_CTRL_NUM_KEYS 8 +#define EP92_UEVENT_AUDIO_NUM_KEYS 9 + +static const unsigned int ep92_samp_freq_table[8] = { + 32000, 44100, 48000, 88200, 96000, 176400, 192000, 768000 +}; + +static const char hex_to_char[] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + +struct ep92_uevent_data { + struct kobject kobj; + struct kobj_type ktype; +}; + +static struct kset *ep92_uevent_kset; +static struct ep92_uevent_data *ep92_uevent_ctrl; +static struct ep92_uevent_data *ep92_uevent_audio; + +static void ep92_release_uevent_data(struct kobject *kobj) +{ + struct ep92_uevent_data *data = container_of(kobj, + struct ep92_uevent_data, kobj); + + kfree(data); +} + +static int ep92_init_uevent_data(struct ep92_uevent_data *uevent_data, + char *name) +{ + int ret = -EINVAL; + + if (!uevent_data || !name) + return ret; + + /* Set kset for kobject before initializing the kobject */ + uevent_data->kobj.kset = ep92_uevent_kset; + + /* Initialize kobject and add it to kernel */ + ret = kobject_init_and_add(&uevent_data->kobj, &uevent_data->ktype, + NULL, "%s", name); + if (ret) { + pr_err("%s: error initializing uevent kernel object: %d", + __func__, ret); + kobject_put(&uevent_data->kobj); + return ret; + } + + /* Send kobject add event to the system */ + kobject_uevent(&uevent_data->kobj, KOBJ_ADD); + + return ret; +} + +/** + * ep92_destroy_uevent_data - destroy kernel object. + * + * @uevent_data: uevent data. + */ +static void ep92_destroy_uevent_data(struct ep92_uevent_data *uevent_data) +{ + if (uevent_data) + kobject_put(&uevent_data->kobj); +} + +static bool ep92_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case EP92_BI_GENERAL_INFO_0: + case EP92_BI_GENERAL_INFO_1: + case EP92_BI_GENERAL_INFO_2: + case EP92_BI_GENERAL_INFO_3: + case EP92_BI_GENERAL_INFO_4: + case EP92_BI_GENERAL_INFO_5: + case EP92_BI_GENERAL_INFO_6: + case EP92_GENERAL_CONTROL_0: + case EP92_GENERAL_CONTROL_1: + case EP92_GENERAL_CONTROL_2: + case EP92_GENERAL_CONTROL_3: + case EP92_GENERAL_CONTROL_4: + case EP92_AUDIO_INFO_SYSTEM_STATUS_0: + case EP92_AUDIO_INFO_SYSTEM_STATUS_1: + case EP92_AUDIO_INFO_AUDIO_STATUS: + case EP92_AUDIO_INFO_CHANNEL_STATUS_0: + case EP92_AUDIO_INFO_CHANNEL_STATUS_1: + case EP92_AUDIO_INFO_CHANNEL_STATUS_2: + case EP92_AUDIO_INFO_CHANNEL_STATUS_3: + case EP92_AUDIO_INFO_CHANNEL_STATUS_4: + case EP92_AUDIO_INFO_ADO_INFO_FRAME_0: + case EP92_AUDIO_INFO_ADO_INFO_FRAME_1: + case EP92_AUDIO_INFO_ADO_INFO_FRAME_2: + case EP92_AUDIO_INFO_ADO_INFO_FRAME_3: + case EP92_AUDIO_INFO_ADO_INFO_FRAME_4: + case EP92_AUDIO_INFO_ADO_INFO_FRAME_5: + return true; + default: + return false; + } +} + +static bool ep92_writeable_registers(struct device *dev, unsigned int reg) +{ + if (reg >= EP92_ISP_MODE_ENTER_ISP && reg <= EP92_GENERAL_CONTROL_4) + return true; + + return false; +} + +static bool ep92_readable_registers(struct device *dev, unsigned int reg) +{ + if (reg >= EP92_BI_VENDOR_ID_0 && reg <= EP92_MAX_REGISTER_ADDR) + return true; + + return false; +} + +/* codec private data */ +struct ep92_pdata { + struct regmap *regmap; + struct snd_soc_codec *codec; + struct timer_list timer; + struct work_struct read_status_worker; + int irq; + + struct { + u8 ctl; + u8 rx_sel; + u8 cec_volume; + } gc; /* General Control block */ + + struct { + u8 system_status_0; + u8 system_status_1; + u8 audio_status; + u8 cs[5]; + u8 cc; + u8 ca; + } ai; /* Audio Info block */ + + u8 old_mode; +}; + +/* + * EP92 Controls + */ + +/* enumerated controls */ +static const char * const ep92_off_on_text[] = {"Off", "On"}; +static const char * const ep92_aud_path_text[] = {"TV", "Speaker"}; +static const char * const ep92_rx_sel_text[] = {"Port 0", "Port 1", "Port 2", + "Res 3", "Res 4", "Res 5", "None", "Res 7"}; +static const char * const ep92_cec_mute_text[] = {"Normal", "Muted"}; + +static const char * const ep92_state_text[] = {"Inactive", "Active"}; +static const char * const ep92_avmute_text[] = {"Normal", "Muted"}; +static const char * const ep92_layout_text[] = {"Layout 0", "Layout 1"}; +static const char * const ep92_mode_text[] = {"LPCM", "Compr"}; + +SOC_ENUM_SINGLE_DECL(ep92_power_enum, EP92_GENERAL_CONTROL_0, + EP92_GC_POWER_SHIFT, ep92_off_on_text); +SOC_ENUM_SINGLE_DECL(ep92_audio_path_enum, EP92_GENERAL_CONTROL_0, + EP92_GC_AUDIO_PATH_SHIFT, ep92_aud_path_text); +SOC_ENUM_SINGLE_DECL(ep92_rx_sel_enum, EP92_GENERAL_CONTROL_1, + EP92_GC_RX_SEL_SHIFT, ep92_rx_sel_text); +SOC_ENUM_SINGLE_DECL(ep92_arc_en_enum, EP92_GENERAL_CONTROL_0, + EP92_GC_ARC_EN_SHIFT, ep92_off_on_text); +SOC_ENUM_SINGLE_DECL(ep92_cec_mute_enum, EP92_GENERAL_CONTROL_0, + EP92_GC_CEC_MUTE_SHIFT, ep92_cec_mute_text); + +SOC_ENUM_SINGLE_DECL(ep92_state_enum, EP92_AUDIO_INFO_SYSTEM_STATUS_0, + EP92_AI_MCLK_ON_SHIFT, ep92_state_text); +SOC_ENUM_SINGLE_DECL(ep92_avmute_enum, EP92_AUDIO_INFO_SYSTEM_STATUS_0, + EP92_AI_AVMUTE_SHIFT, ep92_avmute_text); +SOC_ENUM_SINGLE_DECL(ep92_layout_enum, EP92_AUDIO_INFO_SYSTEM_STATUS_0, + EP92_AI_LAYOUT_SHIFT, ep92_layout_text); +SOC_ENUM_SINGLE_DECL(ep92_mode_enum, EP92_AUDIO_INFO_AUDIO_STATUS, + EP92_AI_STD_ADO_SHIFT, ep92_mode_text); + +/* get/set functions */ +static int ep92_power_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + unsigned int val; + + val = snd_soc_read(codec, e->reg); + ucontrol->value.enumerated.item[0] = + (val >> e->shift_l) & EP92_2CHOICE_MASK; + + pr_debug("%s: item = %d (%s)\n", __func__, + ucontrol->value.enumerated.item[0], + ep92_off_on_text[ucontrol->value.enumerated.item[0]]); + return 0; +} + +static int ep92_power_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct ep92_pdata *ep92 = snd_soc_codec_get_drvdata(codec); + unsigned int val; + + val = snd_soc_read(codec, e->reg); + val &= ~EP92_GC_POWER_MASK; + val |= (ucontrol->value.enumerated.item[0] & EP92_2CHOICE_MASK) + << e->shift_l; + snd_soc_write(codec, e->reg, val); + ep92->gc.ctl &= ~EP92_GC_POWER_MASK; + ep92->gc.ctl |= val & EP92_GC_POWER_MASK; + + pr_debug("%s: item = %d (%s)\n", __func__, + ucontrol->value.enumerated.item[0], + ep92_off_on_text[ucontrol->value.enumerated.item[0] & + EP92_2CHOICE_MASK]); + return 0; +} + +static int ep92_audio_path_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + unsigned int val; + + val = snd_soc_read(codec, e->reg); + ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & + EP92_2CHOICE_MASK; + + pr_debug("%s: item = %d (%s)\n", __func__, + ucontrol->value.enumerated.item[0], + ep92_aud_path_text[ucontrol->value.enumerated.item[0]]); + return 0; +} + +static int ep92_audio_path_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct ep92_pdata *ep92 = snd_soc_codec_get_drvdata(codec); + unsigned int val; + + val = snd_soc_read(codec, e->reg); + val &= ~EP92_GC_AUDIO_PATH_MASK; + val |= (ucontrol->value.enumerated.item[0] & EP92_2CHOICE_MASK) + << e->shift_l; + snd_soc_write(codec, e->reg, val); + ep92->gc.ctl &= ~EP92_GC_AUDIO_PATH_MASK; + ep92->gc.ctl |= val & EP92_GC_AUDIO_PATH_MASK; + + pr_debug("%s: item = %d (%s)\n", __func__, + ucontrol->value.enumerated.item[0], + ep92_aud_path_text[ucontrol->value.enumerated.item[0] & + EP92_2CHOICE_MASK]); + return 0; +} + +static int ep92_cec_mute_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + unsigned int val; + + val = snd_soc_read(codec, e->reg); + ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & + EP92_2CHOICE_MASK; + + pr_debug("%s: item = %d (%s)\n", __func__, + ucontrol->value.enumerated.item[0], + ep92_cec_mute_text[ucontrol->value.enumerated.item[0]]); + return 0; +} + +static int ep92_cec_mute_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct ep92_pdata *ep92 = snd_soc_codec_get_drvdata(codec); + unsigned int val; + + val = snd_soc_read(codec, e->reg); + val &= ~EP92_GC_CEC_MUTE_MASK; + val |= (ucontrol->value.enumerated.item[0] & EP92_2CHOICE_MASK) + << e->shift_l; + snd_soc_write(codec, e->reg, val); + ep92->gc.ctl &= ~EP92_GC_CEC_MUTE_MASK; + ep92->gc.ctl |= val & EP92_GC_CEC_MUTE_MASK; + + pr_debug("%s: item = %d (%s)\n", __func__, + ucontrol->value.enumerated.item[0], + ep92_cec_mute_text[ucontrol->value.enumerated.item[0] & + EP92_2CHOICE_MASK]); + return 0; +} + +static int ep92_arc_en_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + unsigned int val; + + val = snd_soc_read(codec, e->reg); + ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & + EP92_2CHOICE_MASK; + + pr_debug("%s: item = %d (%s)\n", __func__, + ucontrol->value.enumerated.item[0], + ep92_off_on_text[ucontrol->value.enumerated.item[0]]); + return 0; +} + +static int ep92_arc_en_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct ep92_pdata *ep92 = snd_soc_codec_get_drvdata(codec); + unsigned int val; + + val = snd_soc_read(codec, e->reg); + val &= ~EP92_GC_ARC_EN_MASK; + val |= (ucontrol->value.enumerated.item[0] & EP92_2CHOICE_MASK) + << e->shift_l; + snd_soc_write(codec, e->reg, val); + ep92->gc.ctl &= ~EP92_GC_ARC_EN_MASK; + ep92->gc.ctl |= val & EP92_GC_ARC_EN_MASK; + + pr_debug("%s: item = %d (%s)\n", __func__, + ucontrol->value.enumerated.item[0], + ep92_off_on_text[ucontrol->value.enumerated.item[0] & 0x01]); + return 0; +} + +static int ep92_rx_sel_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + unsigned int val; + + val = snd_soc_read(codec, e->reg); + ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & + EP92_GC_RX_SEL_MASK; + + pr_debug("%s: item = %d (%s)\n", __func__, + ucontrol->value.enumerated.item[0], + ep92_rx_sel_text[ucontrol->value.enumerated.item[0]]); + return 0; +} + +static int ep92_rx_sel_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct ep92_pdata *ep92 = snd_soc_codec_get_drvdata(codec); + unsigned int val; + + val = snd_soc_read(codec, e->reg); + val &= ~EP92_GC_RX_SEL_MASK; + val |= (ucontrol->value.enumerated.item[0] & EP92_GC_RX_SEL_MASK) + << e->shift_l; + snd_soc_write(codec, e->reg, val); + ep92->gc.rx_sel &= ~EP92_GC_RX_SEL_MASK; + ep92->gc.rx_sel |= val & EP92_GC_RX_SEL_MASK; + + pr_debug("%s: item = %d (%s)\n", __func__, + ucontrol->value.enumerated.item[0], + ep92_rx_sel_text[ucontrol->value.enumerated.item[0] & + EP92_GC_RX_SEL_MASK]); + return 0; +} + +static int ep92_cec_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + unsigned int val; + + val = snd_soc_read(codec, mc->reg); + ucontrol->value.integer.value[0] = (val >> mc->shift) & + EP92_GC_CEC_VOLUME_MASK; + + pr_debug("%s: volume = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int ep92_cec_volume_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct ep92_pdata *ep92 = snd_soc_codec_get_drvdata(codec); + unsigned int val; + + val = ucontrol->value.integer.value[0] & EP92_GC_CEC_VOLUME_MASK; + if (val > EP92_GC_CEC_VOLUME_MAX) + val = EP92_GC_CEC_VOLUME_MAX; + snd_soc_write(codec, mc->reg, val); + ep92->gc.cec_volume = val; + + pr_debug("%s: volume = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int ep92_state_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + unsigned int val; + + val = snd_soc_read(codec, e->reg); + ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & + EP92_2CHOICE_MASK; + + pr_debug("%s: item = %d (%s)\n", __func__, + ucontrol->value.enumerated.item[0], + ep92_state_text[ucontrol->value.enumerated.item[0]]); + return 0; +} + +static int ep92_avmute_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + unsigned int val; + + val = snd_soc_read(codec, e->reg); + ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & + EP92_2CHOICE_MASK; + + pr_debug("%s: item = %d (%s)\n", __func__, + ucontrol->value.enumerated.item[0], + ep92_avmute_text[ucontrol->value.enumerated.item[0]]); + return 0; +} + +static int ep92_layout_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + unsigned int val; + + val = snd_soc_read(codec, e->reg); + ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & + EP92_2CHOICE_MASK; + + pr_debug("%s: item = %d (%s)\n", __func__, + ucontrol->value.enumerated.item[0], + ep92_layout_text[ucontrol->value.enumerated.item[0]]); + return 0; +} + +static int ep92_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct ep92_pdata *ep92 = snd_soc_codec_get_drvdata(codec); + unsigned int val; + + val = snd_soc_read(codec, e->reg); + if (val & EP92_AI_STD_ADO_MASK) { + val = snd_soc_read(codec, EP92_AUDIO_INFO_CHANNEL_STATUS_0); + if (val & EP92_AI_NPCM_MASK) + ucontrol->value.enumerated.item[0] = 1; /* Compr */ + else + ucontrol->value.enumerated.item[0] = 0; /* LPCM */ + } else if (val & EP92_AI_HBR_ADO_MASK) { + ucontrol->value.enumerated.item[0] = 1; /* Compr */ + } else { + ucontrol->value.enumerated.item[0] = ep92->old_mode; + } + pr_debug("%s: item = %d (%s)\n", __func__, + ucontrol->value.enumerated.item[0], + ep92_mode_text[ucontrol->value.enumerated.item[0]]); + return 0; +} + +static int ep92_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + unsigned int val; + + val = snd_soc_read(codec, mc->reg); + val &= EP92_AI_RATE_MASK; + val = ep92_samp_freq_table[val]; + ucontrol->value.integer.value[0] = val; + + pr_debug("%s: rate = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int ep92_ch_count_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + unsigned int val; + + val = snd_soc_read(codec, mc->reg) & EP92_AI_CH_COUNT_MASK; + /* mapping is ch_count = reg_val + 1, with exception: 0 = unknown */ + if (val > 0) + val += 1; + + ucontrol->value.integer.value[0] = val; + + pr_debug("%s: ch_count = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int ep92_ch_alloc_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + unsigned int val; + + val = snd_soc_read(codec, mc->reg); + ucontrol->value.integer.value[0] = (val >> mc->shift) & + EP92_AI_CH_ALLOC_MASK; + + pr_debug("%s: ch_alloc = 0x%02lx\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static const struct snd_kcontrol_new ep92_snd_controls[] = { + + SOC_ENUM_EXT("HDMI_IN POWER", ep92_power_enum, + ep92_power_get, ep92_power_put), + SOC_ENUM_EXT("HDMI_IN AUDIO_PATH", ep92_audio_path_enum, + ep92_audio_path_get, ep92_audio_path_put), + SOC_ENUM_EXT("HDMI_IN RX_SEL", ep92_rx_sel_enum, + ep92_rx_sel_get, ep92_rx_sel_put), + SOC_ENUM_EXT("HDMI_IN ARC_EN", ep92_arc_en_enum, + ep92_arc_en_get, ep92_arc_en_put), + SOC_ENUM_EXT("HDMI_IN CEC_MUTE", ep92_cec_mute_enum, + ep92_cec_mute_get, ep92_cec_mute_put), + SOC_SINGLE_EXT("HDMI_IN CEC_VOLUME", EP92_GENERAL_CONTROL_3, + EP92_GC_CEC_VOLUME_MIN, EP92_GC_CEC_VOLUME_MAX, + 0, ep92_cec_volume_get, ep92_cec_volume_put), + + SOC_ENUM_EXT("HDMI_IN STATE", ep92_state_enum, ep92_state_get, NULL), + SOC_ENUM_EXT("HDMI_IN AVMUTE", ep92_avmute_enum, ep92_avmute_get, NULL), + SOC_ENUM_EXT("HDMI_IN LAYOUT", ep92_layout_enum, ep92_layout_get, NULL), + SOC_ENUM_EXT("HDMI_IN MODE", ep92_mode_enum, ep92_mode_get, NULL), + SOC_SINGLE_EXT("HDMI_IN RATE", EP92_AUDIO_INFO_AUDIO_STATUS, + EP92_AI_RATE_MIN, EP92_AI_RATE_MAX, 0, ep92_rate_get, NULL), + SOC_SINGLE_EXT("HDMI_IN CH_COUNT", EP92_AUDIO_INFO_ADO_INFO_FRAME_1, + EP92_AI_CH_COUNT_MIN, EP92_AI_CH_COUNT_MAX, + 0, ep92_ch_count_get, NULL), + SOC_SINGLE_EXT("HDMI_IN CH_ALLOC", EP92_AUDIO_INFO_ADO_INFO_FRAME_4, + EP92_AI_CH_ALLOC_MIN, EP92_AI_CH_ALLOC_MAX, 0, + ep92_ch_alloc_get, NULL), +}; + +static int ep92_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + return 0; +} + +static void ep92_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ +} + +static int ep92_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + return 0; +} + +static struct snd_soc_dai_ops ep92_dai_ops = { + .startup = ep92_startup, + .shutdown = ep92_shutdown, + .hw_params = ep92_hw_params, +}; + +static struct snd_soc_dai_driver ep92_dai[] = { + { + .name = "ep92-hdmi", + .id = 1, + .capture = { + .stream_name = "HDMI Capture", + .rate_max = 192000, + .rate_min = 32000, + .channels_min = 1, + .channels_max = 8, + .rates = EP92_RATES, + .formats = EP92_FORMATS, + }, + .ops = &ep92_dai_ops, /* callbacks */ + }, + { + .name = "ep92-arc", + .id = 2, + .capture = { + .stream_name = "ARC Capture", + .rate_max = 192000, + .rate_min = 32000, + .channels_min = 1, + .channels_max = 2, + .rates = EP92_RATES, + .formats = EP92_FORMATS, + }, + .ops = &ep92_dai_ops, /* callbacks */ + }, +}; + +static const char * const ep92_event_power_text[] = { + "POWER=Off", + "POWER=On", +}; + +static const char * const ep92_event_arc_en_text[] = { + "ARC_EN=Off", + "ARC_EN=On", +}; + +static const char * const ep92_event_audio_path_text[] = { + "AUDIO_PATH=TV", + "AUDIO_PATH=Speaker", +}; + +static const char *const ep92_event_rx_sel_text[] = { + "RX_SEL=Port0", + "RX_SEL=Port1", + "RX_SEL=Port2", + "RX_SEL=Res3", + "RX_SEL=Res4", + "RX_SEL=Res5", + "RX_SEL=None", + "RX_SEL=Res7", +}; + +static const char *const ep92_event_cec_mute_text[] = { + "CEC_MUTE=Normal", + "CEC_MUTE=Muted", +}; + +static int ep92_send_uevent_ctrl(struct ep92_pdata *ep92) +{ + char *env[EP92_UEVENT_CTRL_NUM_KEYS]; + u8 idx = 0; + u8 cec_volume; + char cec_volume_text[] = "CEC_VOLUME=0x00"; + char *ptr; + + env[idx++] = "HDMI_CONTROL=TRUE"; + + if ((ep92->gc.ctl >> EP92_GC_POWER_SHIFT) & + EP92_2CHOICE_MASK) + env[idx++] = (char *)ep92_event_power_text[1]; + else + env[idx++] = (char *)ep92_event_power_text[0]; + + if (ep92->gc.ctl & EP92_2CHOICE_MASK) + env[idx++] = (char *)ep92_event_arc_en_text[1]; + else + env[idx++] = (char *)ep92_event_arc_en_text[0]; + + if ((ep92->gc.ctl >> EP92_GC_AUDIO_PATH_SHIFT) & + EP92_2CHOICE_MASK) + env[idx++] = (char *)ep92_event_audio_path_text[1]; + else + env[idx++] = (char *)ep92_event_audio_path_text[0]; + + switch (ep92->gc.rx_sel & EP92_GC_RX_SEL_MASK) { + case 0: + env[idx++] = (char *)ep92_event_rx_sel_text[0]; + break; + case 1: + env[idx++] = (char *)ep92_event_rx_sel_text[1]; + break; + case 2: + env[idx++] = (char *)ep92_event_rx_sel_text[2]; + break; + case 3: + env[idx++] = (char *)ep92_event_rx_sel_text[3]; + break; + case 4: + env[idx++] = (char *)ep92_event_rx_sel_text[4]; + break; + case 5: + env[idx++] = (char *)ep92_event_rx_sel_text[5]; + break; + case 6: + env[idx++] = (char *)ep92_event_rx_sel_text[6]; + break; + case 7: + env[idx++] = (char *)ep92_event_rx_sel_text[7]; + break; + default: + env[idx++] = (char *)ep92_event_rx_sel_text[0]; + } + + if ((ep92->gc.ctl >> EP92_GC_CEC_MUTE_SHIFT) & + EP92_2CHOICE_MASK) + env[idx++] = (char *)ep92_event_cec_mute_text[1]; + else + env[idx++] = (char *)ep92_event_cec_mute_text[0]; + + ptr = &cec_volume_text[strlen(cec_volume_text)-2]; + cec_volume = (ep92->ai.ca) & EP92_GC_CEC_VOLUME_MASK; + *ptr++ = hex_to_char[(cec_volume >> 4) & 0x0f]; + *ptr++ = hex_to_char[cec_volume & 0x0f]; + env[idx++] = (char *)cec_volume_text; + + env[idx++] = NULL; + + if (idx != EP92_UEVENT_CTRL_NUM_KEYS) { + pr_err("ep92 wrong number of audio uevent keys (%d).\n", + idx); + return -EINVAL; + } + + return kobject_uevent_env(&ep92_uevent_ctrl->kobj, KOBJ_CHANGE, env); +} + +static const char * const ep92_event_state_text[] = { + "STATE=Inactive", + "STATE=Active", +}; + +static const char *const ep92_event_rate_text[] = { + "RATE=32000", + "RATE=44100", + "RATE=48000", + "RATE=88200", + "RATE=96000", + "RATE=176400", + "RATE=192000", + "RATE=768000", +}; + +static const char *const ep92_event_format_text[] = { + "FORMAT=LPCM", + "FORMAT=Compr", +}; + +static const char *const ep92_event_layout_text[] = { + "LAYOUT=2ch", + "LAYOUT=8ch", +}; + +static const char *const ep92_event_avmute_text[] = { + "AVMUTE=Normal", + "AVMUTE=Muted", +}; + +static const char *const ep92_event_ch_count_text[] = { + "CH_COUNT=One", + "CH_COUNT=Two", + "CH_COUNT=Three", + "CH_COUNT=Four", + "CH_COUNT=Five", + "CH_COUNT=Six", + "CH_COUNT=Seven", + "CH_COUNT=Eight", +}; + +static int ep92_send_uevent_audio(struct ep92_pdata *ep92) +{ + char *env[EP92_UEVENT_AUDIO_NUM_KEYS]; + u8 idx = 0; + u8 ch_alloc; + char ch_alloc_text[] = "CH_ALLOC=0x00"; + char *ptr; + + env[idx++] = "HDMI_FMT_UPDATE=TRUE"; + + if (((ep92->ai.system_status_0 >> EP92_AI_MCLK_ON_SHIFT) & + EP92_2CHOICE_MASK) == EP92_STATUS_AUDIO_ACTIVE) + env[idx++] = (char *)ep92_event_state_text[1]; + else + env[idx++] = (char *)ep92_event_state_text[0]; + + switch (ep92->ai.audio_status & EP92_AI_RATE_MASK) { + case 0: + env[idx++] = (char *)ep92_event_rate_text[0]; + break; + case 1: + env[idx++] = (char *)ep92_event_rate_text[1]; + break; + case 2: + env[idx++] = (char *)ep92_event_rate_text[2]; + break; + case 3: + env[idx++] = (char *)ep92_event_rate_text[3]; + break; + case 4: + env[idx++] = (char *)ep92_event_rate_text[4]; + break; + case 5: + env[idx++] = (char *)ep92_event_rate_text[5]; + break; + case 6: + env[idx++] = (char *)ep92_event_rate_text[6]; + break; + case 7: + env[idx++] = (char *)ep92_event_rate_text[7]; + break; + default: + env[idx++] = (char *)ep92_event_rate_text[2]; + } + + if (ep92->old_mode) + env[idx++] = (char *)ep92_event_format_text[1]; + else + env[idx++] = (char *)ep92_event_format_text[0]; + + if (ep92->ai.system_status_0 & EP92_2CHOICE_MASK) + env[idx++] = (char *)ep92_event_layout_text[1]; + else + env[idx++] = (char *)ep92_event_layout_text[0]; + + if ((ep92->ai.system_status_0 >> EP92_AI_AVMUTE_SHIFT) & + EP92_2CHOICE_MASK) + env[idx++] = (char *)ep92_event_avmute_text[1]; + else + env[idx++] = (char *)ep92_event_avmute_text[0]; + + /* cc==0 signals n/a and is treated as stereo */ + switch (ep92->ai.cc & EP92_AI_CH_COUNT_MASK) { + case 0: + env[idx++] = (char *)ep92_event_ch_count_text[1]; + break; + case 1: + env[idx++] = (char *)ep92_event_ch_count_text[1]; + break; + case 2: + env[idx++] = (char *)ep92_event_ch_count_text[2]; + break; + case 3: + env[idx++] = (char *)ep92_event_ch_count_text[3]; + break; + case 4: + env[idx++] = (char *)ep92_event_ch_count_text[4]; + break; + case 5: + env[idx++] = (char *)ep92_event_ch_count_text[5]; + break; + case 6: + env[idx++] = (char *)ep92_event_ch_count_text[6]; + break; + case 7: + env[idx++] = (char *)ep92_event_ch_count_text[7]; + break; + default: + env[idx++] = (char *)ep92_event_ch_count_text[1]; + } + + ptr = &ch_alloc_text[strlen(ch_alloc_text)-2]; + ch_alloc = (ep92->ai.ca) & EP92_AI_CH_ALLOC_MASK; + *ptr++ = hex_to_char[(ch_alloc >> 4) & 0x0f]; + *ptr++ = hex_to_char[ch_alloc & 0x0f]; + env[idx++] = (char *)ch_alloc_text; + + env[idx++] = NULL; + + if (idx != EP92_UEVENT_AUDIO_NUM_KEYS) { + pr_err("ep92 wrong number of audio uevent keys (%d).\n", + idx); + return -EINVAL; + } + + return kobject_uevent_env(&ep92_uevent_audio->kobj, KOBJ_CHANGE, env); +} + +static void ep92_read_general_control(struct snd_soc_codec *codec, + struct ep92_pdata *ep92) +{ + u8 old, change; + bool send_uevent = false; + + old = ep92->gc.ctl; + ep92->gc.ctl = snd_soc_read(codec, EP92_GENERAL_CONTROL_0); + change = ep92->gc.ctl ^ old; + if (change & EP92_GC_POWER_MASK) { + pr_debug("ep92 power changed to %d (%s)\n", + (ep92->gc.ctl >> EP92_GC_POWER_SHIFT) & + EP92_2CHOICE_MASK, + ep92_off_on_text[(ep92->gc.ctl + >> EP92_GC_POWER_SHIFT) & EP92_2CHOICE_MASK]); + send_uevent = true; + } + if (change & EP92_GC_AUDIO_PATH_MASK) { + pr_debug("ep92 audio_path changed to %d (%s)\n", + (ep92->gc.ctl >> EP92_GC_AUDIO_PATH_SHIFT) & + EP92_2CHOICE_MASK, + ep92_aud_path_text[(ep92->gc.ctl + >> EP92_GC_AUDIO_PATH_SHIFT) & EP92_2CHOICE_MASK]); + send_uevent = true; + } + if (change & EP92_GC_CEC_MUTE_MASK) { + pr_debug("ep92 cec_mute changed to %d (%s)\n", + (ep92->gc.ctl >> EP92_GC_CEC_MUTE_SHIFT) & + EP92_2CHOICE_MASK, + ep92_cec_mute_text[(ep92->gc.ctl + >> EP92_GC_CEC_MUTE_SHIFT) & EP92_2CHOICE_MASK]); + send_uevent = true; + } + if (change & EP92_GC_ARC_EN_MASK) { + pr_debug("ep92 arc_en changed to %d (%s)\n", + ep92->gc.ctl & EP92_2CHOICE_MASK, + ep92_off_on_text[ep92->gc.ctl & EP92_2CHOICE_MASK]); + send_uevent = true; + } + + old = ep92->gc.rx_sel; + ep92->gc.rx_sel = snd_soc_read(codec, EP92_GENERAL_CONTROL_1); + change = ep92->gc.rx_sel ^ old; + if (change & EP92_GC_RX_SEL_MASK) { + pr_debug("ep92 rx_sel changed to %d (%s)\n", + ep92->gc.rx_sel & EP92_GC_RX_SEL_MASK, + ep92_rx_sel_text[ep92->gc.rx_sel & + EP92_GC_RX_SEL_MASK]); + send_uevent = true; + } + + old = ep92->gc.cec_volume; + ep92->gc.cec_volume = snd_soc_read(codec, EP92_GENERAL_CONTROL_3); + change = ep92->gc.cec_volume ^ old; + if (change & EP92_GC_CEC_VOLUME_MASK) { + pr_debug("ep92 cec_volume changed to %d\n", + ep92->gc.cec_volume & EP92_GC_CEC_VOLUME_MASK); + send_uevent = true; + } + + if (send_uevent) + ep92_send_uevent_ctrl(ep92); +} + +static void ep92_read_audio_info(struct snd_soc_codec *codec, + struct ep92_pdata *ep92) +{ + u8 old, change; + u8 new_mode; + bool send_uevent = false; + + old = ep92->ai.system_status_0; + ep92->ai.system_status_0 = snd_soc_read(codec, + EP92_AUDIO_INFO_SYSTEM_STATUS_0); + change = ep92->ai.system_status_0 ^ old; + if (change & EP92_AI_MCLK_ON_MASK) { + pr_debug("ep92 status changed to %d (%s)\n", + (ep92->ai.system_status_0 >> EP92_AI_MCLK_ON_SHIFT) & + EP92_2CHOICE_MASK, + ep92_state_text[(ep92->ai.system_status_0 + >> EP92_AI_MCLK_ON_SHIFT) & EP92_2CHOICE_MASK]); + send_uevent = true; + } + if (change & EP92_AI_AVMUTE_MASK) { + pr_debug("ep92 avmute changed to %d (%s)\n", + (ep92->ai.system_status_0 >> EP92_AI_AVMUTE_SHIFT) & + EP92_2CHOICE_MASK, + ep92_avmute_text[(ep92->ai.system_status_0 + >> EP92_AI_AVMUTE_SHIFT) & EP92_2CHOICE_MASK]); + send_uevent = true; + } + if (change & EP92_AI_LAYOUT_MASK) { + pr_debug("ep92 layout changed to %d (%s)\n", + (ep92->ai.system_status_0) & EP92_2CHOICE_MASK, + ep92_layout_text[(ep92->ai.system_status_0) & + EP92_2CHOICE_MASK]); + send_uevent = true; + } + + old = ep92->ai.audio_status; + ep92->ai.audio_status = snd_soc_read(codec, + EP92_AUDIO_INFO_AUDIO_STATUS); + change = ep92->ai.audio_status ^ old; + if (change & EP92_AI_RATE_MASK) { + pr_debug("ep92 rate changed to %d\n", + ep92_samp_freq_table[(ep92->ai.audio_status) & + EP92_AI_RATE_MASK]); + send_uevent = true; + } + + new_mode = ep92->old_mode; + if (ep92->ai.audio_status & EP92_AI_STD_ADO_MASK) { + ep92->ai.cs[0] = snd_soc_read(codec, + EP92_AUDIO_INFO_CHANNEL_STATUS_0); + if (ep92->ai.cs[0] & EP92_AI_NPCM_MASK) + new_mode = 1; /* Compr */ + else + new_mode = 0; /* LPCM */ + } else if (ep92->ai.audio_status & EP92_AI_HBR_ADO_MASK) + new_mode = 1; /* Compr */ + + if (ep92->old_mode != new_mode) { + pr_debug("ep92 mode changed to %d (%s)\n", new_mode, + ep92_mode_text[new_mode]); + send_uevent = true; + } + ep92->old_mode = new_mode; + + old = ep92->ai.cc; + ep92->ai.cc = snd_soc_read(codec, EP92_AUDIO_INFO_ADO_INFO_FRAME_1); + change = ep92->ai.cc ^ old; + if (change & EP92_AI_CH_COUNT_MASK) { + pr_debug("ep92 ch_count changed to %d (%d)\n", + ep92->ai.cc & EP92_AI_CH_COUNT_MASK, + (ep92->ai.cc & EP92_AI_CH_COUNT_MASK) == 0 ? 0 : + (ep92->ai.cc & EP92_AI_CH_COUNT_MASK) + 1); + send_uevent = true; + } + + old = ep92->ai.ca; + ep92->ai.ca = snd_soc_read(codec, EP92_AUDIO_INFO_ADO_INFO_FRAME_4); + change = ep92->ai.ca ^ old; + if (change & EP92_AI_CH_ALLOC_MASK) { + pr_debug("ep92 ch_alloc changed to 0x%02x\n", + (ep92->ai.ca) & EP92_AI_CH_ALLOC_MASK); + send_uevent = true; + } + + if (send_uevent) + ep92_send_uevent_audio(ep92); +} + +static void ep92_init(struct snd_soc_codec *codec, struct ep92_pdata *ep92) +{ + /* update the format information in mixer controls */ + ep92_read_general_control(codec, ep92); + ep92_read_audio_info(codec, ep92); +} + +static int ep92_probe(struct snd_soc_codec *codec) +{ + struct ep92_pdata *ep92 = snd_soc_codec_get_drvdata(codec); + + ep92->codec = codec; + ep92_init(codec, ep92); + + return 0; +} + +static int ep92_remove(struct snd_soc_codec *codec) +{ + return 0; +} + +static struct regmap *ep92_get_regmap(struct device *dev) +{ + struct ep92_pdata *ep92_ctrl = dev_get_drvdata(dev); + + if (!ep92_ctrl) + return NULL; + + return ep92_ctrl->regmap; +} + +static struct snd_soc_codec_driver soc_codec_drv_ep92 = { + .probe = ep92_probe, + .remove = ep92_remove, + .get_regmap = ep92_get_regmap, + .component_driver = { + .controls = ep92_snd_controls, + .num_controls = ARRAY_SIZE(ep92_snd_controls), + }, +}; + +static struct regmap_config ep92_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = ep92_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(ep92_reg_defaults), + .max_register = EP92_MAX_REGISTER_ADDR, + .volatile_reg = ep92_volatile_register, + .writeable_reg = ep92_writeable_registers, + .readable_reg = ep92_readable_registers, +}; + +void ep92_read_status(struct work_struct *work) +{ + struct ep92_pdata *ep92 = container_of(work, struct ep92_pdata, + read_status_worker); + struct snd_soc_codec *codec = ep92->codec; + u8 val; + + /* No polling before codec is initialized */ + if (codec == NULL) + return; + + /* check ADO_CHF that is set when audio format has changed */ + val = snd_soc_read(codec, EP92_BI_GENERAL_INFO_1); + if (val == 0xff) { + /* workaround for Nak'ed first read */ + val = snd_soc_read(codec, EP92_BI_GENERAL_INFO_1); + if (val == 0xff) + return; /* assume device not present */ + } + + if (val & EP92_GI_ADO_CHF_MASK) + pr_debug("ep92 audio mode change trigger.\n"); + + if (val & EP92_GI_CEC_ECF_MASK) + pr_debug("ep92 CEC change trigger.\n"); + + /* check for general control changes */ + ep92_read_general_control(codec, ep92); + + /* update the format information in mixer controls */ + ep92_read_audio_info(codec, ep92); +} + +static irqreturn_t ep92_irq(int irq, void *data) +{ + struct ep92_pdata *ep92 = data; + struct snd_soc_codec *codec = ep92->codec; + + /* Treat interrupt before codec is initialized as spurious */ + if (codec == NULL) + return IRQ_NONE; + + dev_dbg(codec->dev, "ep92_interrupt\n"); + + schedule_work(&ep92->read_status_worker); + + return IRQ_HANDLED; +}; + +void ep92_poll_status(unsigned long data) +{ + struct ep92_pdata *ep92 = (struct ep92_pdata *)data; + u32 poll_msec; + + if ((ep92->gc.ctl & EP92_GC_POWER_MASK) == 0) + poll_msec = EP92_POLL_INTERVAL_OFF_MSEC; + else + poll_msec = EP92_POLL_INTERVAL_ON_MSEC; + + mod_timer(&ep92->timer, jiffies + msecs_to_jiffies(poll_msec)); + + schedule_work(&ep92->read_status_worker); +} + +static const struct of_device_id ep92_of_match[] = { + { .compatible = "explore,ep92a6", }, + { } +}; +MODULE_DEVICE_TABLE(of, ep92_of_match); + +static int ep92_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct ep92_pdata *ep92; + int ret; + + ep92 = devm_kzalloc(&client->dev, sizeof(struct ep92_pdata), + GFP_KERNEL); + if (ep92 == NULL) + return -ENOMEM; + + ep92->regmap = devm_regmap_init_i2c(client, &ep92_regmap_config); + if (IS_ERR(ep92->regmap)) { + ret = PTR_ERR(ep92->regmap); + dev_err(&client->dev, + "%s %d: Failed to allocate regmap for I2C device: %d\n", + __func__, __LINE__, ret); + return ret; + } + + i2c_set_clientdata(client, ep92); + + /* register interrupt handler */ + INIT_WORK(&ep92->read_status_worker, ep92_read_status); + ep92->irq = client->irq; + if (ep92->irq) { + ret = devm_request_threaded_irq(&client->dev, ep92->irq, + NULL, ep92_irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + "ep92_irq", ep92); + if (ret) { + dev_err(&client->dev, + "%s: Failed to request IRQ %d: %d\n", + __func__, ep92->irq, ret); + ep92->irq = 0; + } + } + /* poll status if IRQ is not configured */ + if (ep92->irq == 0) { + setup_timer(&ep92->timer, ep92_poll_status, + (unsigned long)ep92); + mod_timer(&ep92->timer, jiffies + + msecs_to_jiffies(EP92_POLL_INTERVAL_OFF_MSEC)); + } + + /* register codec */ + ret = snd_soc_register_codec(&client->dev, &soc_codec_drv_ep92, + ep92_dai, ARRAY_SIZE(ep92_dai)); + if (ret) { + dev_err(&client->dev, + "%s %d: Failed to register CODEC: %d\n", + __func__, __LINE__, ret); + goto err_reg; + } + + /* Create a kset under /sys/kernel/ */ + ep92_uevent_kset = kset_create_and_add("ep92-hdmi", NULL, kernel_kobj); + if (!ep92_uevent_kset) { + pr_err("%s: error creating uevent kernel set", __func__); + ret = -EINVAL; + goto err_kset; + } + + /* uevent to signal control changes */ + ep92_uevent_ctrl = devm_kzalloc(&client->dev, + sizeof(*ep92_uevent_ctrl), GFP_KERNEL); + if (!ep92_uevent_ctrl) { + ret = -ENOMEM; + goto err_ue_ctrl; + } + + ep92_uevent_ctrl->ktype.release = ep92_release_uevent_data; + ret = ep92_init_uevent_data(ep92_uevent_ctrl, "ctrl-uevent"); + if (ret) { + dev_err(&client->dev, + "%s: Failed to init ctrl-uevent: %d\n", + __func__, ret); + goto err_ue_init_ctrl; + } + + /* uevent to signal audio format changes */ + ep92_uevent_audio = devm_kzalloc(&client->dev, + sizeof(*ep92_uevent_audio), GFP_KERNEL); + if (!ep92_uevent_audio) { + ret = -ENOMEM; + goto err_ue_audio; + } + + ep92_uevent_audio->ktype.release = ep92_release_uevent_data; + ret = ep92_init_uevent_data(ep92_uevent_audio, "audio-uevent"); + if (ret) { + dev_err(&client->dev, + "%s: Failed to init ctrl-uevent: %d\n", + __func__, ret); + goto err_ue_init_audio; + } + return 0; + +err_ue_init_audio: + devm_kfree(&client->dev, ep92_uevent_audio); +err_ue_audio: + ep92_destroy_uevent_data(ep92_uevent_ctrl); +err_ue_init_ctrl: + devm_kfree(&client->dev, ep92_uevent_ctrl); +err_ue_ctrl: + kset_unregister(ep92_uevent_kset); +err_kset: + snd_soc_unregister_codec(&client->dev); +err_reg: + if (ep92->irq == 0) + del_timer(&ep92->timer); + + return ret; +} + +static int ep92_i2c_remove(struct i2c_client *client) +{ + struct ep92_pdata *ep92; + + ep92 = i2c_get_clientdata(client); + if ((ep92 != NULL) && (ep92->irq == 0)) + del_timer(&ep92->timer); + + snd_soc_unregister_codec(&client->dev); + + ep92_destroy_uevent_data(ep92_uevent_ctrl); + devm_kfree(&client->dev, ep92_uevent_ctrl); + + ep92_destroy_uevent_data(ep92_uevent_audio); + devm_kfree(&client->dev, ep92_uevent_audio); + + if (ep92_uevent_kset) { + kset_unregister(ep92_uevent_kset); + ep92_uevent_kset = NULL; + } + + return 0; +} + +static const struct i2c_device_id ep92_i2c_id[] = { + { "ep92-dev", 0}, + { } +}; +MODULE_DEVICE_TABLE(i2c, ep92_i2c_id); + +static struct i2c_driver ep92_i2c_driver = { + .probe = ep92_i2c_probe, + .remove = ep92_i2c_remove, + .id_table = ep92_i2c_id, + .driver = { + .name = "ep92", + .owner = THIS_MODULE, + .of_match_table = ep92_of_match + }, +}; + +static int __init ep92_codec_init(void) +{ + int ret = 0; + + ret = i2c_add_driver(&ep92_i2c_driver); + if (ret) + pr_err("Failed to register EP92 I2C driver: %d\n", ret); + + return ret; +} +module_init(ep92_codec_init); + +static void __exit ep92_codec_exit(void) +{ + i2c_del_driver(&ep92_i2c_driver); +} +module_exit(ep92_codec_exit); + +MODULE_DESCRIPTION("EP92 HDMI repeater/switch driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/ep92/ep92.h b/asoc/codecs/ep92/ep92.h new file mode 100644 index 000000000000..237c9eac2a42 --- /dev/null +++ b/asoc/codecs/ep92/ep92.h @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __EP92_H__ +#define __EP92_H__ + +/* EP92 register addresses */ +/* BI = Basic Info */ +#define EP92_BI_VENDOR_ID_0 0x00 +#define EP92_BI_VENDOR_ID_1 0x01 +#define EP92_BI_DEVICE_ID_0 0x02 +#define EP92_BI_DEVICE_ID_1 0x03 +#define EP92_BI_VERSION_NUM 0x04 +#define EP92_BI_VERSION_YEAR 0x05 +#define EP92_BI_VERSION_MONTH 0x06 +#define EP92_BI_VERSION_DATE 0x07 +#define EP92_BI_GENERAL_INFO_0 0x08 +#define EP92_BI_GENERAL_INFO_1 0x09 +#define EP92_BI_GENERAL_INFO_2 0x0A +#define EP92_BI_GENERAL_INFO_3 0x0B +#define EP92_BI_GENERAL_INFO_4 0x0C +#define EP92_BI_GENERAL_INFO_5 0x0D +#define EP92_BI_GENERAL_INFO_6 0x0E + +#define EP92_ISP_MODE_ENTER_ISP 0x0F + +#define EP92_GENERAL_CONTROL_0 0x10 +#define EP92_GENERAL_CONTROL_1 0x11 +#define EP92_GENERAL_CONTROL_2 0x12 +#define EP92_GENERAL_CONTROL_3 0x13 +#define EP92_GENERAL_CONTROL_4 0x14 + +#define EP92_CEC_EVENT_CODE 0x15 +#define EP92_CEC_EVENT_PARAM_1 0x16 +#define EP92_CEC_EVENT_PARAM_2 0x17 +#define EP92_CEC_EVENT_PARAM_3 0x18 +#define EP92_CEC_EVENT_PARAM_4 0x19 +/* RESERVED 0x1A */ +/* ... ... */ +/* RESERVED 0x1F */ +#define EP92_AUDIO_INFO_SYSTEM_STATUS_0 0x20 +#define EP92_AUDIO_INFO_SYSTEM_STATUS_1 0x21 +#define EP92_AUDIO_INFO_AUDIO_STATUS 0x22 +#define EP92_AUDIO_INFO_CHANNEL_STATUS_0 0x23 +#define EP92_AUDIO_INFO_CHANNEL_STATUS_1 0x24 +#define EP92_AUDIO_INFO_CHANNEL_STATUS_2 0x25 +#define EP92_AUDIO_INFO_CHANNEL_STATUS_3 0x26 +#define EP92_AUDIO_INFO_CHANNEL_STATUS_4 0x27 +#define EP92_AUDIO_INFO_ADO_INFO_FRAME_0 0x28 +#define EP92_AUDIO_INFO_ADO_INFO_FRAME_1 0x29 +#define EP92_AUDIO_INFO_ADO_INFO_FRAME_2 0x2A +#define EP92_AUDIO_INFO_ADO_INFO_FRAME_3 0x2B +#define EP92_AUDIO_INFO_ADO_INFO_FRAME_4 0x2C +#define EP92_AUDIO_INFO_ADO_INFO_FRAME_5 0x2D + +#define EP92_OTHER_PACKETS_HDMI_VS_0 0x2E +#define EP92_OTHER_PACKETS_HDMI_VS_1 0x2F +#define EP92_OTHER_PACKETS_ACP_PACKET 0x30 +#define EP92_OTHER_PACKETS_AVI_INFO_FRAME_0 0x31 +#define EP92_OTHER_PACKETS_AVI_INFO_FRAME_1 0x32 +#define EP92_OTHER_PACKETS_AVI_INFO_FRAME_2 0x33 +#define EP92_OTHER_PACKETS_AVI_INFO_FRAME_3 0x34 +#define EP92_OTHER_PACKETS_AVI_INFO_FRAME_4 0x35 +#define EP92_OTHER_PACKETS_GC_PACKET_0 0x36 +#define EP92_OTHER_PACKETS_GC_PACKET_1 0x37 +#define EP92_OTHER_PACKETS_GC_PACKET_2 0x38 + +#define EP92_MAX_REGISTER_ADDR EP92_OTHER_PACKETS_GC_PACKET_2 + + +/* EP92 register default values */ +static struct reg_default ep92_reg_defaults[] = { + {EP92_BI_VENDOR_ID_0, 0x17}, + {EP92_BI_VENDOR_ID_1, 0x7A}, + {EP92_BI_DEVICE_ID_0, 0x94}, + {EP92_BI_DEVICE_ID_1, 0xA3}, + {EP92_BI_VERSION_NUM, 0x10}, + {EP92_BI_VERSION_YEAR, 0x09}, + {EP92_BI_VERSION_MONTH, 0x07}, + {EP92_BI_VERSION_DATE, 0x06}, + {EP92_BI_GENERAL_INFO_0, 0x00}, + {EP92_BI_GENERAL_INFO_1, 0x00}, + {EP92_BI_GENERAL_INFO_2, 0x00}, + {EP92_BI_GENERAL_INFO_3, 0x00}, + {EP92_BI_GENERAL_INFO_4, 0x00}, + {EP92_BI_GENERAL_INFO_5, 0x00}, + {EP92_BI_GENERAL_INFO_6, 0x00}, + {EP92_ISP_MODE_ENTER_ISP, 0x00}, + {EP92_GENERAL_CONTROL_0, 0x20}, + {EP92_GENERAL_CONTROL_1, 0x00}, + {EP92_GENERAL_CONTROL_2, 0x00}, + {EP92_GENERAL_CONTROL_3, 0x10}, + {EP92_GENERAL_CONTROL_4, 0x00}, + {EP92_CEC_EVENT_CODE, 0x00}, + {EP92_CEC_EVENT_PARAM_1, 0x00}, + {EP92_CEC_EVENT_PARAM_2, 0x00}, + {EP92_CEC_EVENT_PARAM_3, 0x00}, + {EP92_CEC_EVENT_PARAM_4, 0x00}, + {EP92_AUDIO_INFO_SYSTEM_STATUS_0, 0x00}, + {EP92_AUDIO_INFO_SYSTEM_STATUS_1, 0x00}, + {EP92_AUDIO_INFO_AUDIO_STATUS, 0x00}, + {EP92_AUDIO_INFO_CHANNEL_STATUS_0, 0x00}, + {EP92_AUDIO_INFO_CHANNEL_STATUS_1, 0x00}, + {EP92_AUDIO_INFO_CHANNEL_STATUS_2, 0x00}, + {EP92_AUDIO_INFO_CHANNEL_STATUS_3, 0x00}, + {EP92_AUDIO_INFO_CHANNEL_STATUS_4, 0x00}, + {EP92_AUDIO_INFO_ADO_INFO_FRAME_0, 0x00}, + {EP92_AUDIO_INFO_ADO_INFO_FRAME_1, 0x00}, + {EP92_AUDIO_INFO_ADO_INFO_FRAME_2, 0x00}, + {EP92_AUDIO_INFO_ADO_INFO_FRAME_3, 0x00}, + {EP92_AUDIO_INFO_ADO_INFO_FRAME_4, 0x00}, + {EP92_AUDIO_INFO_ADO_INFO_FRAME_5, 0x00}, + {EP92_OTHER_PACKETS_HDMI_VS_0, 0x00}, + {EP92_OTHER_PACKETS_HDMI_VS_1, 0x00}, + {EP92_OTHER_PACKETS_ACP_PACKET, 0x00}, + {EP92_OTHER_PACKETS_AVI_INFO_FRAME_0, 0x00}, + {EP92_OTHER_PACKETS_AVI_INFO_FRAME_1, 0x00}, + {EP92_OTHER_PACKETS_AVI_INFO_FRAME_2, 0x00}, + {EP92_OTHER_PACKETS_AVI_INFO_FRAME_3, 0x00}, + {EP92_OTHER_PACKETS_AVI_INFO_FRAME_4, 0x00}, + {EP92_OTHER_PACKETS_GC_PACKET_0, 0x00}, + {EP92_OTHER_PACKETS_GC_PACKET_1, 0x00}, + {EP92_OTHER_PACKETS_GC_PACKET_2, 0x00}, +}; + + +/* shift/masks for register bits + * GI = General Info + * GC = General Control + * AI = Audio Info + */ +#define EP92_GI_ADO_CHF_MASK 0x01 +#define EP92_GI_CEC_ECF_MASK 0x02 +#define EP92_GC_POWER_SHIFT 7 +#define EP92_GC_POWER_MASK 0x80 +#define EP92_GC_AUDIO_PATH_SHIFT 5 +#define EP92_GC_AUDIO_PATH_MASK 0x20 +#define EP92_GC_CEC_MUTE_SHIFT 1 +#define EP92_GC_CEC_MUTE_MASK 0x02 +#define EP92_GC_ARC_EN_SHIFT 0 +#define EP92_GC_ARC_EN_MASK 0x01 +#define EP92_GC_RX_SEL_SHIFT 0 +#define EP92_GC_RX_SEL_MASK 0x07 +#define EP92_GC_CEC_VOLUME_SHIFT 0 +#define EP92_GC_CEC_VOLUME_MASK 0xff +#define EP92_AI_MCLK_ON_SHIFT 6 +#define EP92_AI_MCLK_ON_MASK 0x40 +#define EP92_AI_AVMUTE_SHIFT 5 +#define EP92_AI_AVMUTE_MASK 0x20 +#define EP92_AI_LAYOUT_SHIFT 0 +#define EP92_AI_LAYOUT_MASK 0x01 +#define EP92_AI_HBR_ADO_SHIFT 5 +#define EP92_AI_HBR_ADO_MASK 0x20 +#define EP92_AI_STD_ADO_SHIFT 3 +#define EP92_AI_STD_ADO_MASK 0x08 +#define EP92_AI_RATE_MASK 0x07 +#define EP92_AI_NPCM_MASK 0x02 +#define EP92_AI_CH_COUNT_MASK 0x07 +#define EP92_AI_CH_ALLOC_MASK 0xff + +#define EP92_2CHOICE_MASK 1 +#define EP92_GC_CEC_VOLUME_MIN 0 +#define EP92_GC_CEC_VOLUME_MAX 100 +#define EP92_AI_RATE_MIN 0 +#define EP92_AI_RATE_MAX 768000 +#define EP92_AI_CH_COUNT_MIN 0 +#define EP92_AI_CH_COUNT_MAX 8 +#define EP92_AI_CH_ALLOC_MIN 0 +#define EP92_AI_CH_ALLOC_MAX 0xff + +#define EP92_STATUS_NO_SIGNAL 0 +#define EP92_STATUS_AUDIO_ACTIVE 1 + +/* kcontrol storage indices */ +enum { + EP92_KCTL_POWER = 0, + EP92_KCTL_AUDIO_PATH, + EP92_KCTL_CEC_MUTE, + EP92_KCTL_ARC_EN, + EP92_KCTL_RX_SEL, + EP92_KCTL_CEC_VOLUME, + EP92_KCTL_STATE, + EP92_KCTL_AVMUTE, + EP92_KCTL_LAYOUT, + EP92_KCTL_MODE, + EP92_KCTL_RATE, + EP92_KCTL_CH_COUNT, + EP92_KCTL_CH_ALLOC, + EP92_KCTL_MAX +}; + +#endif /* __EP92_H__ */ -- GitLab From ed30d2c2235fee477211c17a364795af414f01aa Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Fri, 27 Jul 2018 18:31:10 +0530 Subject: [PATCH 0413/1645] asoc: config: Support for ep92 HDMI bridge device Add config for ep92 device to be enabled in QCS405 Change-Id: I9f1529ff9917866986dd2ab81ac5ed9381592be0 Signed-off-by: Ralf Herz --- config/qcs405auto.conf | 1 + config/qcs405autoconf.h | 1 + 2 files changed, 2 insertions(+) diff --git a/config/qcs405auto.conf b/config/qcs405auto.conf index a30f01a635c3..f5a99f1cee34 100644 --- a/config/qcs405auto.conf +++ b/config/qcs405auto.conf @@ -34,3 +34,4 @@ CONFIG_DTS_SRS_TM=m CONFIG_SND_SOC_MSM_STUB=m CONFIG_MSM_AVTIMER=m CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m +CONFIG_SND_SOC_EP92=m diff --git a/config/qcs405autoconf.h b/config/qcs405autoconf.h index 75332935ea6e..4562621c6b95 100644 --- a/config/qcs405autoconf.h +++ b/config/qcs405autoconf.h @@ -46,3 +46,4 @@ #define CONFIG_SND_SOC_MSM_STUB 1 #define CONFIG_MSM_AVTIMER 1 #define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 +#define CONFIG_SND_SOC_EP92 1 -- GitLab From 6d96dd41d32e520f19ea688439c36c63ddbec9a9 Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Mon, 25 Jun 2018 10:30:10 +0200 Subject: [PATCH 0414/1645] asoc: qcs405: Add support for ep92 HDMI bridge chip Add support for ep92 HDMI bridge chip for QCS405 platform Change-Id: Ifa8a6e60cee69c88276b50d5f61b3e13fac82b60 Signed-off-by: Ralf Herz --- asoc/qcs405.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 1f62d66683c8..8989bf7b1541 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -7527,6 +7528,119 @@ static void msm_i2s_auxpcm_deinit(void) } } +static int msm_scan_i2c_addr(struct platform_device *pdev, + uint32_t busnum, uint32_t addr) +{ + struct i2c_adapter *adap; + u8 rbuf; + struct i2c_msg msg; + int status = 0; + + adap = i2c_get_adapter(busnum); + if (!adap) { + dev_err(&pdev->dev, "%s: Cannot get I2C adapter %d\n", + __func__, busnum); + return -EBUSY; + } + + /* to test presence, read one byte from device */ + msg.addr = addr; + msg.flags = I2C_M_RD; + msg.len = 1; + msg.buf = &rbuf; + + status = i2c_transfer(adap, &msg, 1); + + i2c_put_adapter(adap); + + if (status != 1) { + dev_dbg(&pdev->dev, "%s: I2C read from addr 0x%02x failed\n", + __func__, addr); + return -ENODEV; + } + + dev_dbg(&pdev->dev, "%s: I2C read from addr 0x%02x successful\n", + __func__, addr); + + return 0; +} + +static int msm_detect_ep92_dev(struct platform_device *pdev, + struct snd_soc_card *card) +{ + int i; + uint32_t ep92_busnum = 0; + uint32_t ep92_reg = 0; + const char *ep92_name = NULL; + struct snd_soc_dai_link *dai; + int rc = 0; + + rc = of_property_read_u32(pdev->dev.of_node, "qcom,ep92-busnum", + &ep92_busnum); + if (rc) { + dev_info(&pdev->dev, "%s: No DT match ep92-reg\n", __func__); + return 0; + } + + rc = of_property_read_u32(pdev->dev.of_node, "qcom,ep92-reg", + &ep92_reg); + if (rc) { + dev_info(&pdev->dev, "%s: No DT match ep92-busnum\n", __func__); + return 0; + } + + rc = of_property_read_string(pdev->dev.of_node, "qcom,ep92-name", + &ep92_name); + if (rc) { + dev_info(&pdev->dev, "%s: No DT match ep92-name\n", __func__); + return 0; + } + + /* check I2C bus for connected ep92 chip */ + if (msm_scan_i2c_addr(pdev, ep92_busnum, ep92_reg) < 0) { + /* check a second time after a short delay */ + msleep(20); + if (msm_scan_i2c_addr(pdev, ep92_busnum, ep92_reg) < 0) { + dev_info(&pdev->dev, "%s: No ep92 device found\n", + __func__); + /* continue with snd_card registration without ep92 */ + return 0; + } + } + + dev_info(&pdev->dev, "%s: ep92 device found\n", __func__); + + /* update codec info in MI2S dai link */ + dai = &msm_mi2s_be_dai_links[0]; + for (i=0; iname, LPASS_BE_SEC_MI2S_TX) == 0) { + dev_dbg(&pdev->dev, + "%s: Set Sec MI2S dai to ep92 codec\n", + __func__); + dai->codec_name = ep92_name; + dai->codec_dai_name = "ep92-hdmi"; + break; + } + dai++; + } + + /* update codec info in SPDIF dai link */ + dai = &msm_spdif_be_dai_links[0]; + for (i=0; iname, LPASS_BE_SEC_SPDIF_TX) == 0) { + dev_dbg(&pdev->dev, + "%s: Set Sec SPDIF dai to ep92 codec\n", + __func__); + dai->codec_name = ep92_name; + dai->codec_dai_name = "ep92-arc"; + break; + } + dai++; + } + + return 0; +} + static int msm_asoc_machine_probe(struct platform_device *pdev) { struct snd_soc_card *card; @@ -7544,6 +7658,11 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) if (!pdata) return -ENOMEM; + /* test for ep92 HDMI bridge and update dai links accordingly */ + ret = msm_detect_ep92_dev(pdev, card); + if (ret) + goto err; + card = populate_snd_card_dailinks(&pdev->dev); if (!card) { dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); -- GitLab From 2eabdc730902ffadc8af31960d1792483d415756 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Fri, 27 Jul 2018 21:16:07 +0530 Subject: [PATCH 0415/1645] asoc: dsp: add check for integer overflow Add check for integer overflow of user supplied data for ADSP stream command. CRs-Fixed: 2173850 Change-Id: Idde5665c770398629b1b0cfa2c18d3c023b0f9a2 Signed-off-by: Mangesh Kunchamwar --- dsp/q6asm.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 8deb64a723ab..db5b57b8947c 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1189,7 +1189,9 @@ int q6asm_send_stream_cmd(struct audio_client *ac, { char *asm_params = NULL; struct apr_hdr hdr; - int sz, rc; + int rc; + uint32_t sz = 0; + uint64_t actual_sz = 0; if (!data || !ac) { pr_err("%s: %s is NULL\n", __func__, @@ -1206,7 +1208,15 @@ int q6asm_send_stream_cmd(struct audio_client *ac, goto done; } - sz = sizeof(struct apr_hdr) + data->payload_len; + actual_sz = sizeof(struct apr_hdr) + data->payload_len; + if (actual_sz > U32_MAX) { + pr_err("%s: payload size 0x%X exceeds limit\n", + __func__, data->payload_len); + rc = -EINVAL; + goto done; + } + + sz = (uint32_t)actual_sz; asm_params = kzalloc(sz, GFP_KERNEL); if (!asm_params) { rc = -ENOMEM; -- GitLab From 989fccf8757d6d31841d9c43f7680bdb4b29218a Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 15 Jun 2018 16:53:31 +0530 Subject: [PATCH 0416/1645] asoc: bolero: Add support for TX macro driver Add support for TX digital portion to register as macro to bolero codec. ASoC dapm and dai functionality of TX macro is associated to bolero codec itself. Change-Id: I1e222610d1750eccd6822d9901b17ec2ea509389 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/tx-macro.c | 1712 +++++++++++++++++++++++++++++++++ 1 file changed, 1712 insertions(+) create mode 100644 asoc/codecs/bolero/tx-macro.c diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c new file mode 100644 index 000000000000..0795d47c8138 --- /dev/null +++ b/asoc/codecs/bolero/tx-macro.c @@ -0,0 +1,1712 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bolero-cdc.h" +#include "bolero-cdc-registers.h" +#include "../msm-cdc-pinctrl.h" + +#define TX_MACRO_MAX_OFFSET 0x1000 + +#define NUM_DECIMATORS 8 + +#define TX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) +#define TX_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_3LE) + +#define TX_HPF_CUT_OFF_FREQ_MASK 0x60 +#define CF_MIN_3DB_4HZ 0x0 +#define CF_MIN_3DB_75HZ 0x1 +#define CF_MIN_3DB_150HZ 0x2 + +#define TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED 0 +#define TX_MACRO_MCLK_FREQ 9600000 +#define TX_MACRO_TX_PATH_OFFSET 0x80 + +#define TX_MACRO_TX_UNMUTE_DELAY_MS 40 + +static int tx_unmute_delay = TX_MACRO_TX_UNMUTE_DELAY_MS; +module_param(tx_unmute_delay, int, 0664); +MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path"); + +static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); + +static int tx_macro_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai); +static int tx_macro_get_channel_map(struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot); + +#define TX_MACRO_SWR_STRING_LEN 80 +#define TX_MACRO_CHILD_DEVICES_MAX 3 + +/* Hold instance to soundwire platform device */ +struct tx_macro_swr_ctrl_data { + struct platform_device *tx_swr_pdev; +}; + +struct tx_macro_swr_ctrl_platform_data { + void *handle; /* holds codec private data */ + int (*read)(void *handle, int reg); + int (*write)(void *handle, int reg, int val); + int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); + int (*clk)(void *handle, bool enable); + int (*handle_irq)(void *handle, + irqreturn_t (*swrm_irq_handler)(int irq, + void *data), + void *swrm_handle, + int action); +}; + +enum { + TX_MACRO_AIF1_CAP = 0, + TX_MACRO_AIF2_CAP, + TX_MACRO_MAX_DAIS +}; + +enum { + TX_MACRO_DEC0, + TX_MACRO_DEC1, + TX_MACRO_DEC2, + TX_MACRO_DEC3, + TX_MACRO_DEC4, + TX_MACRO_DEC5, + TX_MACRO_DEC6, + TX_MACRO_DEC7, + TX_MACRO_DEC_MAX, +}; + +enum { + TX_MACRO_CLK_DIV_2, + TX_MACRO_CLK_DIV_3, + TX_MACRO_CLK_DIV_4, + TX_MACRO_CLK_DIV_6, + TX_MACRO_CLK_DIV_8, + TX_MACRO_CLK_DIV_16, +}; + +struct tx_mute_work { + struct tx_macro_priv *tx_priv; + u32 decimator; + struct delayed_work dwork; +}; + +struct hpf_work { + struct tx_macro_priv *tx_priv; + u8 decimator; + u8 hpf_cut_off_freq; + struct delayed_work dwork; +}; + +struct tx_macro_priv { + struct device *dev; + bool dec_active[NUM_DECIMATORS]; + int tx_mclk_users; + int swr_clk_users; + struct clk *tx_core_clk; + struct clk *tx_npl_clk; + struct mutex mclk_lock; + struct mutex swr_clk_lock; + struct snd_soc_codec *codec; + struct device_node *tx_swr_gpio_p; + struct tx_macro_swr_ctrl_data *swr_ctrl_data; + struct tx_macro_swr_ctrl_platform_data swr_plat_data; + struct work_struct tx_macro_add_child_devices_work; + struct hpf_work tx_hpf_work[NUM_DECIMATORS]; + struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS]; + s32 dmic_0_1_clk_cnt; + s32 dmic_2_3_clk_cnt; + s32 dmic_4_5_clk_cnt; + s32 dmic_6_7_clk_cnt; + u16 dmic_clk_div; + unsigned long active_ch_mask[TX_MACRO_MAX_DAIS]; + unsigned long active_ch_cnt[TX_MACRO_MAX_DAIS]; + char __iomem *tx_io_base; + struct platform_device *pdev_child_devices + [TX_MACRO_CHILD_DEVICES_MAX]; + int child_count; +}; + +static bool tx_macro_get_data(struct snd_soc_codec *codec, + struct device **tx_dev, + struct tx_macro_priv **tx_priv, + const char *func_name) +{ + *tx_dev = bolero_get_device_ptr(codec->dev, TX_MACRO); + if (!(*tx_dev)) { + dev_err(codec->dev, + "%s: null device for macro!\n", func_name); + return false; + } + + *tx_priv = dev_get_drvdata((*tx_dev)); + if (!(*tx_priv)) { + dev_err(codec->dev, + "%s: priv is null for macro!\n", func_name); + return false; + } + + if (!(*tx_priv)->codec) { + dev_err(codec->dev, + "%s: tx_priv->codec not initialized!\n", func_name); + return false; + } + + return true; +} + +static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv, + bool mclk_enable) +{ + struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL); + int ret = 0; + + dev_dbg(tx_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", + __func__, mclk_enable, dapm, tx_priv->tx_mclk_users); + + mutex_lock(&tx_priv->mclk_lock); + if (mclk_enable) { + if (tx_priv->tx_mclk_users == 0) { + ret = bolero_request_clock(tx_priv->dev, + TX_MACRO, MCLK_MUX0, true); + if (ret < 0) { + dev_err(tx_priv->dev, + "%s: request clock enable failed\n", + __func__); + goto exit; + } + regcache_mark_dirty(regmap); + regcache_sync_region(regmap, + TX_START_OFFSET, + TX_MAX_OFFSET); + /* 9.6MHz MCLK, set value 0x00 if other frequency */ + regmap_update_bits(regmap, + BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK, 0x01, 0x01); + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); + } + tx_priv->tx_mclk_users++; + } else { + if (tx_priv->tx_mclk_users <= 0) { + dev_err(tx_priv->dev, "%s: clock already disabled\n", + __func__); + tx_priv->tx_mclk_users = 0; + goto exit; + } + tx_priv->tx_mclk_users--; + if (tx_priv->tx_mclk_users == 0) { + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x00); + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x00); + bolero_request_clock(tx_priv->dev, + TX_MACRO, MCLK_MUX0, false); + } + } +exit: + mutex_unlock(&tx_priv->mclk_lock); + return ret; +} + +static int tx_macro_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int ret = 0; + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + + if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + dev_dbg(tx_dev, "%s: event = %d\n", __func__, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = tx_macro_mclk_enable(tx_priv, 1); + break; + case SND_SOC_DAPM_POST_PMD: + ret = tx_macro_mclk_enable(tx_priv, 0); + break; + default: + dev_err(tx_priv->dev, + "%s: invalid DAPM event %d\n", __func__, event); + ret = -EINVAL; + } + return ret; +} + +static int tx_macro_mclk_ctrl(struct device *dev, bool enable) +{ + struct tx_macro_priv *tx_priv = dev_get_drvdata(dev); + int ret = 0; + + if (enable) { + ret = clk_prepare_enable(tx_priv->tx_core_clk); + if (ret < 0) { + dev_err(dev, "%s:tx mclk enable failed\n", __func__); + goto exit; + } + ret = clk_prepare_enable(tx_priv->tx_npl_clk); + if (ret < 0) { + dev_err(dev, "%s:tx npl_clk enable failed\n", + __func__); + clk_disable_unprepare(tx_priv->tx_core_clk); + goto exit; + } + } else { + clk_disable_unprepare(tx_priv->tx_npl_clk); + clk_disable_unprepare(tx_priv->tx_core_clk); + } + +exit: + return ret; +} + +static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) +{ + struct delayed_work *hpf_delayed_work = NULL; + struct hpf_work *hpf_work = NULL; + struct tx_macro_priv *tx_priv = NULL; + struct snd_soc_codec *codec = NULL; + u16 dec_cfg_reg = 0; + u8 hpf_cut_off_freq = 0; + + hpf_delayed_work = to_delayed_work(work); + hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); + tx_priv = hpf_work->tx_priv; + codec = tx_priv->codec; + hpf_cut_off_freq = hpf_work->hpf_cut_off_freq; + + dec_cfg_reg = BOLERO_CDC_TX0_TX_PATH_CFG0 + + TX_MACRO_TX_PATH_OFFSET * hpf_work->decimator; + + dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", + __func__, hpf_work->decimator, hpf_cut_off_freq); + + snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); +} + +static void tx_macro_mute_update_callback(struct work_struct *work) +{ + struct tx_mute_work *tx_mute_dwork = NULL; + struct snd_soc_codec *codec = NULL; + struct tx_macro_priv *tx_priv = NULL; + struct delayed_work *delayed_work = NULL; + u16 tx_vol_ctl_reg = 0, hpf_gate_reg = 0; + u8 decimator = 0; + + delayed_work = to_delayed_work(work); + tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); + tx_priv = tx_mute_dwork->tx_priv; + codec = tx_priv->codec; + decimator = tx_mute_dwork->decimator; + + tx_vol_ctl_reg = + BOLERO_CDC_TX0_TX_PATH_CTL + + TX_MACRO_TX_PATH_OFFSET * decimator; + hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 + + TX_MACRO_TX_PATH_OFFSET * decimator; + snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x01); + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00); + dev_dbg(tx_priv->dev, "%s: decimator %u unmute\n", + __func__, decimator); +} + +static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val = 0; + u16 mic_sel_reg = 0; + + val = ucontrol->value.enumerated.item[0]; + if (val > e->items - 1) + return -EINVAL; + + dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + widget->name, val); + + switch (e->reg) { + case BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0: + mic_sel_reg = BOLERO_CDC_TX0_TX_PATH_CFG0; + break; + case BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0: + mic_sel_reg = BOLERO_CDC_TX1_TX_PATH_CFG0; + break; + case BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0: + mic_sel_reg = BOLERO_CDC_TX2_TX_PATH_CFG0; + break; + case BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0: + mic_sel_reg = BOLERO_CDC_TX3_TX_PATH_CFG0; + break; + case BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0: + mic_sel_reg = BOLERO_CDC_TX4_TX_PATH_CFG0; + break; + case BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0: + mic_sel_reg = BOLERO_CDC_TX5_TX_PATH_CFG0; + break; + case BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0: + mic_sel_reg = BOLERO_CDC_TX6_TX_PATH_CFG0; + break; + case BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0: + mic_sel_reg = BOLERO_CDC_TX7_TX_PATH_CFG0; + break; + default: + dev_err(codec->dev, "%s: e->reg: 0x%x not expected\n", + __func__, e->reg); + return -EINVAL; + } + if (strnstr(widget->name, "smic", strlen(widget->name))) { + if (val != 0) { + if (val < 5) + snd_soc_update_bits(codec, mic_sel_reg, + 1 << 7, 0x0 << 7); + else + snd_soc_update_bits(codec, mic_sel_reg, + 1 << 7, 0x1 << 7); + } + } else { + /* DMIC selected */ + if (val != 0) + snd_soc_update_bits(codec, mic_sel_reg, 1 << 7, 1 << 7); + } + + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +static int tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_multi_mixer_control *mixer = + ((struct soc_multi_mixer_control *)kcontrol->private_value); + u32 dai_id = widget->shift; + u32 dec_id = mixer->shift; + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + + if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + if (test_bit(dec_id, &tx_priv->active_ch_mask[dai_id])) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; + return 0; +} + +static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_dapm_update *update = NULL; + struct soc_multi_mixer_control *mixer = + ((struct soc_multi_mixer_control *)kcontrol->private_value); + u32 dai_id = widget->shift; + u32 dec_id = mixer->shift; + u32 enable = ucontrol->value.integer.value[0]; + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + + if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + if (enable) { + set_bit(dec_id, &tx_priv->active_ch_mask[dai_id]); + tx_priv->active_ch_cnt[dai_id]++; + } else { + tx_priv->active_ch_cnt[dai_id]--; + clear_bit(dec_id, &tx_priv->active_ch_mask[dai_id]); + } + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update); + + return 0; +} + +static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u8 dmic_clk_en = 0x01; + u16 dmic_clk_reg = 0; + s32 *dmic_clk_cnt = NULL; + unsigned int dmic = 0; + int ret = 0; + char *wname = NULL; + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + + if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + wname = strpbrk(w->name, "01234567"); + if (!wname) { + dev_err(codec->dev, "%s: widget not found\n", __func__); + return -EINVAL; + } + + ret = kstrtouint(wname, 10, &dmic); + if (ret < 0) { + dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n", + __func__); + return -EINVAL; + } + + switch (dmic) { + case 0: + case 1: + dmic_clk_cnt = &(tx_priv->dmic_0_1_clk_cnt); + dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL; + break; + case 2: + case 3: + dmic_clk_cnt = &(tx_priv->dmic_2_3_clk_cnt); + dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL; + break; + case 4: + case 5: + dmic_clk_cnt = &(tx_priv->dmic_4_5_clk_cnt); + dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL; + break; + case 6: + case 7: + dmic_clk_cnt = &(tx_priv->dmic_6_7_clk_cnt); + dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL; + break; + default: + dev_err(codec->dev, "%s: Invalid DMIC Selection\n", + __func__); + return -EINVAL; + } + dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", + __func__, event, dmic, *dmic_clk_cnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + (*dmic_clk_cnt)++; + if (*dmic_clk_cnt == 1) { + snd_soc_update_bits(codec, dmic_clk_reg, + 0x0E, tx_priv->dmic_clk_div << 0x1); + snd_soc_update_bits(codec, dmic_clk_reg, + dmic_clk_en, dmic_clk_en); + } + break; + case SND_SOC_DAPM_POST_PMD: + (*dmic_clk_cnt)--; + if (*dmic_clk_cnt == 0) + snd_soc_update_bits(codec, dmic_clk_reg, + dmic_clk_en, 0); + break; + } + + return 0; +} + +static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + unsigned int decimator = 0; + u16 tx_vol_ctl_reg = 0; + u16 dec_cfg_reg = 0; + u16 hpf_gate_reg = 0; + u16 tx_gain_ctl_reg = 0; + u8 hpf_cut_off_freq = 0; + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + + if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + decimator = w->shift; + + dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__, + w->name, decimator); + + tx_vol_ctl_reg = BOLERO_CDC_TX0_TX_PATH_CTL + + TX_MACRO_TX_PATH_OFFSET * decimator; + hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 + + TX_MACRO_TX_PATH_OFFSET * decimator; + dec_cfg_reg = BOLERO_CDC_TX0_TX_PATH_CFG0 + + TX_MACRO_TX_PATH_OFFSET * decimator; + tx_gain_ctl_reg = BOLERO_CDC_TX0_TX_VOL_CTL + + TX_MACRO_TX_PATH_OFFSET * decimator; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) & + TX_HPF_CUT_OFF_FREQ_MASK) >> 5; + tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq = + hpf_cut_off_freq; + + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) + snd_soc_update_bits(codec, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + CF_MIN_3DB_150HZ << 5); + /* Enable TX PGA Mute */ + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00); + + /* schedule work queue to Remove Mute */ + schedule_delayed_work(&tx_priv->tx_mute_dwork[decimator].dwork, + msecs_to_jiffies(tx_unmute_delay)); + if (tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq != + CF_MIN_3DB_150HZ) + schedule_delayed_work( + &tx_priv->tx_hpf_work[decimator].dwork, + msecs_to_jiffies(300)); + /* apply gain after decimator is enabled */ + snd_soc_write(codec, tx_gain_ctl_reg, + snd_soc_read(codec, tx_gain_ctl_reg)); + break; + case SND_SOC_DAPM_PRE_PMD: + hpf_cut_off_freq = + tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq; + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + if (cancel_delayed_work_sync( + &tx_priv->tx_hpf_work[decimator].dwork)) { + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { + snd_soc_update_bits(codec, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + } + } + cancel_delayed_work_sync( + &tx_priv->tx_mute_dwork[decimator].dwork); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); + break; + } + return 0; +} + +static int tx_macro_enable_micbias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + return 0; +} + +static int tx_macro_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + int tx_fs_rate = -EINVAL; + struct snd_soc_codec *codec = dai->codec; + u32 decimator = 0; + u16 sample_rate = 0; + u16 tx_fs_reg = 0; + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + + if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__, + dai->name, dai->id, params_rate(params), + params_channels(params)); + + sample_rate = params_rate(params); + switch (sample_rate) { + case 8000: + tx_fs_rate = 0; + break; + case 16000: + tx_fs_rate = 1; + break; + case 32000: + tx_fs_rate = 3; + break; + case 48000: + tx_fs_rate = 4; + break; + case 96000: + tx_fs_rate = 5; + break; + case 192000: + tx_fs_rate = 6; + break; + case 384000: + tx_fs_rate = 7; + break; + default: + dev_err(codec->dev, "%s: Invalid TX sample rate: %d\n", + __func__, params_rate(params)); + return -EINVAL; + } + for_each_set_bit(decimator, &tx_priv->active_ch_mask[dai->id], + TX_MACRO_DEC_MAX) { + if (decimator >= 0) { + tx_fs_reg = BOLERO_CDC_TX0_TX_PATH_CTL + + TX_MACRO_TX_PATH_OFFSET * decimator; + dev_dbg(codec->dev, "%s: set DEC%u rate to %u\n", + __func__, decimator, sample_rate); + snd_soc_update_bits(codec, tx_fs_reg, 0x0F, + tx_fs_rate); + } else { + dev_err(codec->dev, + "%s: ERROR: Invalid decimator: %d\n", + __func__, decimator); + return -EINVAL; + } + } + return 0; +} + +static int tx_macro_get_channel_map(struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot) +{ + struct snd_soc_codec *codec = dai->codec; + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + + if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + switch (dai->id) { + case TX_MACRO_AIF1_CAP: + case TX_MACRO_AIF2_CAP: + *tx_slot = tx_priv->active_ch_mask[dai->id]; + *tx_num = tx_priv->active_ch_cnt[dai->id]; + break; + default: + dev_err(tx_dev, "%s: Invalid AIF\n", __func__); + break; + } + return 0; +} + +static struct snd_soc_dai_ops tx_macro_dai_ops = { + .hw_params = tx_macro_hw_params, + .get_channel_map = tx_macro_get_channel_map, +}; + +static struct snd_soc_dai_driver tx_macro_dai[] = { + { + .name = "tx_macro_tx1", + .id = TX_MACRO_AIF1_CAP, + .capture = { + .stream_name = "TX_AIF1 Capture", + .rates = TX_MACRO_RATES, + .formats = TX_MACRO_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &tx_macro_dai_ops, + }, + { + .name = "tx_macro_tx2", + .id = TX_MACRO_AIF2_CAP, + .capture = { + .stream_name = "TX_AIF2 Capture", + .rates = TX_MACRO_RATES, + .formats = TX_MACRO_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &tx_macro_dai_ops, + }, +}; + +#define STRING(name) #name +#define TX_MACRO_DAPM_ENUM(name, reg, offset, text) \ +static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ +static const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_ENUM(STRING(name), name##_enum) + +#define TX_MACRO_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \ +static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ +static const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname) + +#define TX_MACRO_DAPM_MUX(name, shift, kctl) \ + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux) + +static const char * const adc_mux_text[] = { + "MSM_DMIC", "SWR_MIC", "ANC_FB_TUNE1" +}; + +TX_MACRO_DAPM_ENUM(tx_dec0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1, + 0, adc_mux_text); +TX_MACRO_DAPM_ENUM(tx_dec1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG1, + 0, adc_mux_text); +TX_MACRO_DAPM_ENUM(tx_dec2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG1, + 0, adc_mux_text); +TX_MACRO_DAPM_ENUM(tx_dec3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG1, + 0, adc_mux_text); +TX_MACRO_DAPM_ENUM(tx_dec4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG1, + 0, adc_mux_text); +TX_MACRO_DAPM_ENUM(tx_dec5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG1, + 0, adc_mux_text); +TX_MACRO_DAPM_ENUM(tx_dec6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG1, + 0, adc_mux_text); +TX_MACRO_DAPM_ENUM(tx_dec7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG1, + 0, adc_mux_text); + + +static const char * const dmic_mux_text[] = { + "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", + "DMIC4", "DMIC5", "DMIC6", "DMIC7" +}; + +TX_MACRO_DAPM_ENUM_EXT(tx_dmic0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0, + 4, dmic_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_dmic1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0, + 4, dmic_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_dmic2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0, + 4, dmic_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_dmic3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0, + 4, dmic_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_dmic4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0, + 4, dmic_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_dmic5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0, + 4, dmic_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_dmic6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0, + 4, dmic_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_dmic7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0, + 4, dmic_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +static const char * const smic_mux_text[] = { + "ZERO", "ADC0", "ADC1", "ADC2", "ADC3", + "SWR_DMIC0", "SWR_DMIC1", "SWR_DMIC2", "SWR_DMIC3", + "SWR_DMIC4", "SWR_DMIC5", "SWR_DMIC6", "SWR_DMIC7" +}; + +TX_MACRO_DAPM_ENUM_EXT(tx_smic0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0, + 0, smic_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic1, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0, + 0, smic_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0, + 0, smic_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic3, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0, + 0, smic_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic4, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0, + 0, smic_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic5, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0, + 0, smic_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic6, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0, + 0, smic_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0, + 0, smic_mux_text, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +static const struct snd_kcontrol_new tx_aif1_cap_mixer[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), +}; + +static const struct snd_kcontrol_new tx_aif2_cap_mixer[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), +}; + +static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = { + SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0, + SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0), + + SND_SOC_DAPM_AIF_OUT("TX_AIF2 CAP", "TX_AIF2 Capture", 0, + SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0), + + SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0, + tx_aif1_cap_mixer, ARRAY_SIZE(tx_aif1_cap_mixer)), + + SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0, + tx_aif2_cap_mixer, ARRAY_SIZE(tx_aif2_cap_mixer)), + + + TX_MACRO_DAPM_MUX("TX DMIC MUX0", 0, tx_dmic0), + TX_MACRO_DAPM_MUX("TX DMIC MUX1", 0, tx_dmic1), + TX_MACRO_DAPM_MUX("TX DMIC MUX2", 0, tx_dmic2), + TX_MACRO_DAPM_MUX("TX DMIC MUX3", 0, tx_dmic3), + TX_MACRO_DAPM_MUX("TX DMIC MUX4", 0, tx_dmic4), + TX_MACRO_DAPM_MUX("TX DMIC MUX5", 0, tx_dmic5), + TX_MACRO_DAPM_MUX("TX DMIC MUX6", 0, tx_dmic6), + TX_MACRO_DAPM_MUX("TX DMIC MUX7", 0, tx_dmic7), + + TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0), + TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1), + TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2), + TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3), + TX_MACRO_DAPM_MUX("TX SMIC MUX4", 0, tx_smic4), + TX_MACRO_DAPM_MUX("TX SMIC MUX5", 0, tx_smic5), + TX_MACRO_DAPM_MUX("TX SMIC MUX6", 0, tx_smic6), + TX_MACRO_DAPM_MUX("TX SMIC MUX7", 0, tx_smic7), + + SND_SOC_DAPM_MICBIAS_E("TX MIC BIAS1", SND_SOC_NOPM, 0, 0, + tx_macro_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("TX DMIC0", NULL, SND_SOC_NOPM, 0, 0, + tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("TX DMIC1", NULL, SND_SOC_NOPM, 0, 0, + tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("TX DMIC2", NULL, SND_SOC_NOPM, 0, 0, + tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("TX DMIC3", NULL, SND_SOC_NOPM, 0, 0, + tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("TX DMIC4", NULL, SND_SOC_NOPM, 0, 0, + tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("TX DMIC5", NULL, SND_SOC_NOPM, 0, 0, + tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("TX DMIC6", NULL, SND_SOC_NOPM, 0, 0, + tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("TX DMIC7", NULL, SND_SOC_NOPM, 0, 0, + tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_INPUT("TX SWR_ADC0"), + SND_SOC_DAPM_INPUT("TX SWR_ADC1"), + SND_SOC_DAPM_INPUT("TX SWR_ADC2"), + SND_SOC_DAPM_INPUT("TX SWR_ADC3"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC0"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC1"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC2"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC3"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC4"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC5"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC6"), + SND_SOC_DAPM_INPUT("TX SWR_DMIC7"), + + SND_SOC_DAPM_MUX_E("TX DEC0 MUX", BOLERO_CDC_TX0_TX_PATH_CTL, + TX_MACRO_DEC0, 0, + &tx_dec0_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC1 MUX", BOLERO_CDC_TX1_TX_PATH_CTL, + TX_MACRO_DEC1, 0, + &tx_dec1_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC2 MUX", BOLERO_CDC_TX2_TX_PATH_CTL, + TX_MACRO_DEC2, 0, + &tx_dec2_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC3 MUX", BOLERO_CDC_TX3_TX_PATH_CTL, + TX_MACRO_DEC3, 0, + &tx_dec3_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC4 MUX", BOLERO_CDC_TX4_TX_PATH_CTL, + TX_MACRO_DEC4, 0, + &tx_dec4_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC5 MUX", BOLERO_CDC_TX5_TX_PATH_CTL, + TX_MACRO_DEC5, 0, + &tx_dec5_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC6 MUX", BOLERO_CDC_TX6_TX_PATH_CTL, + TX_MACRO_DEC6, 0, + &tx_dec6_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC7 MUX", BOLERO_CDC_TX7_TX_PATH_CTL, + TX_MACRO_DEC7, 0, + &tx_dec7_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0, + tx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_route tx_audio_map[] = { + {"TX_AIF1 CAP", NULL, "TX_MCLK"}, + {"TX_AIF2 CAP", NULL, "TX_MCLK"}, + + {"TX_AIF1 CAP", NULL, "TX_AIF1_CAP Mixer"}, + {"TX_AIF2 CAP", NULL, "TX_AIF2_CAP Mixer"}, + + {"TX_AIF1_CAP Mixer", "DEC0", "TX DEC0 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC1", "TX DEC1 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC2", "TX DEC2 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC3", "TX DEC3 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC4", "TX DEC4 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC5", "TX DEC5 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC6", "TX DEC6 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC7", "TX DEC7 MUX"}, + + {"TX_AIF2_CAP Mixer", "DEC0", "TX DEC0 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC1", "TX DEC1 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC2", "TX DEC2 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC3", "TX DEC3 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC4", "TX DEC4 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC5", "TX DEC5 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC6", "TX DEC6 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC7", "TX DEC7 MUX"}, + + {"TX DEC0 MUX", "MSM_DMIC", "TX DMIC MUX0"}, + {"TX DMIC MUX0", "DMIC0", "TX DMIC0"}, + {"TX DMIC MUX0", "DMIC1", "TX DMIC1"}, + {"TX DMIC MUX0", "DMIC2", "TX DMIC2"}, + {"TX DMIC MUX0", "DMIC3", "TX DMIC3"}, + {"TX DMIC MUX0", "DMIC4", "TX DMIC4"}, + {"TX DMIC MUX0", "DMIC5", "TX DMIC5"}, + {"TX DMIC MUX0", "DMIC6", "TX DMIC6"}, + {"TX DMIC MUX0", "DMIC7", "TX DMIC7"}, + + {"TX DEC0 MUX", "SWR_MIC", "TX SMIC MUX0"}, + {"TX SMIC MUX0", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX0", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX0", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX0", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX0", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX0", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX0", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX0", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX0", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX0", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX0", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX0", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC1 MUX", "MSM_DMIC", "TX DMIC MUX1"}, + {"TX DMIC MUX1", "DMIC0", "TX DMIC0"}, + {"TX DMIC MUX1", "DMIC1", "TX DMIC1"}, + {"TX DMIC MUX1", "DMIC2", "TX DMIC2"}, + {"TX DMIC MUX1", "DMIC3", "TX DMIC3"}, + {"TX DMIC MUX1", "DMIC4", "TX DMIC4"}, + {"TX DMIC MUX1", "DMIC5", "TX DMIC5"}, + {"TX DMIC MUX1", "DMIC6", "TX DMIC6"}, + {"TX DMIC MUX1", "DMIC7", "TX DMIC7"}, + + {"TX DEC1 MUX", "SWR_MIC", "TX SMIC MUX1"}, + {"TX SMIC MUX1", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX1", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX1", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX1", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX1", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX1", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX1", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX1", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX1", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX1", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX1", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX1", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC2 MUX", "MSM_DMIC", "TX DMIC MUX2"}, + {"TX DMIC MUX2", "DMIC0", "TX DMIC0"}, + {"TX DMIC MUX2", "DMIC1", "TX DMIC1"}, + {"TX DMIC MUX2", "DMIC2", "TX DMIC2"}, + {"TX DMIC MUX2", "DMIC3", "TX DMIC3"}, + {"TX DMIC MUX2", "DMIC4", "TX DMIC4"}, + {"TX DMIC MUX2", "DMIC5", "TX DMIC5"}, + {"TX DMIC MUX2", "DMIC6", "TX DMIC6"}, + {"TX DMIC MUX2", "DMIC7", "TX DMIC7"}, + + {"TX DEC2 MUX", "SWR_MIC", "TX SMIC MUX2"}, + {"TX SMIC MUX2", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX2", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX2", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX2", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX2", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX2", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX2", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX2", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX2", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX2", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX2", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX2", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC3 MUX", "MSM_DMIC", "TX DMIC MUX3"}, + {"TX DMIC MUX3", "DMIC0", "TX DMIC0"}, + {"TX DMIC MUX3", "DMIC1", "TX DMIC1"}, + {"TX DMIC MUX3", "DMIC2", "TX DMIC2"}, + {"TX DMIC MUX3", "DMIC3", "TX DMIC3"}, + {"TX DMIC MUX3", "DMIC4", "TX DMIC4"}, + {"TX DMIC MUX3", "DMIC5", "TX DMIC5"}, + {"TX DMIC MUX3", "DMIC6", "TX DMIC6"}, + {"TX DMIC MUX3", "DMIC7", "TX DMIC7"}, + + {"TX DEC3 MUX", "SWR_MIC", "TX SMIC MUX3"}, + {"TX SMIC MUX3", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX3", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX3", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX3", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX3", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX3", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX3", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX3", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX3", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX3", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX3", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX3", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC4 MUX", "MSM_DMIC", "TX DMIC MUX4"}, + {"TX DMIC MUX4", "DMIC0", "TX DMIC0"}, + {"TX DMIC MUX4", "DMIC1", "TX DMIC1"}, + {"TX DMIC MUX4", "DMIC2", "TX DMIC2"}, + {"TX DMIC MUX4", "DMIC3", "TX DMIC3"}, + {"TX DMIC MUX4", "DMIC4", "TX DMIC4"}, + {"TX DMIC MUX4", "DMIC5", "TX DMIC5"}, + {"TX DMIC MUX4", "DMIC6", "TX DMIC6"}, + {"TX DMIC MUX4", "DMIC7", "TX DMIC7"}, + + {"TX DEC4 MUX", "SWR_MIC", "TX SMIC MUX4"}, + {"TX SMIC MUX4", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX4", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX4", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX4", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX4", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX4", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX4", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX4", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX4", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX4", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX4", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX4", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC5 MUX", "MSM_DMIC", "TX DMIC MUX5"}, + {"TX DMIC MUX5", "DMIC0", "TX DMIC0"}, + {"TX DMIC MUX5", "DMIC1", "TX DMIC1"}, + {"TX DMIC MUX5", "DMIC2", "TX DMIC2"}, + {"TX DMIC MUX5", "DMIC3", "TX DMIC3"}, + {"TX DMIC MUX5", "DMIC4", "TX DMIC4"}, + {"TX DMIC MUX5", "DMIC5", "TX DMIC5"}, + {"TX DMIC MUX5", "DMIC6", "TX DMIC6"}, + {"TX DMIC MUX5", "DMIC7", "TX DMIC7"}, + + {"TX DEC5 MUX", "SWR_MIC", "TX SMIC MUX5"}, + {"TX SMIC MUX5", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX5", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX5", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX5", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX5", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX5", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX5", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX5", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX5", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX5", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX5", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX5", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC6 MUX", "MSM_DMIC", "TX DMIC MUX6"}, + {"TX DMIC MUX6", "DMIC0", "TX DMIC0"}, + {"TX DMIC MUX6", "DMIC1", "TX DMIC1"}, + {"TX DMIC MUX6", "DMIC2", "TX DMIC2"}, + {"TX DMIC MUX6", "DMIC3", "TX DMIC3"}, + {"TX DMIC MUX6", "DMIC4", "TX DMIC4"}, + {"TX DMIC MUX6", "DMIC5", "TX DMIC5"}, + {"TX DMIC MUX6", "DMIC6", "TX DMIC6"}, + {"TX DMIC MUX6", "DMIC7", "TX DMIC7"}, + + {"TX DEC6 MUX", "SWR_MIC", "TX SMIC MUX6"}, + {"TX SMIC MUX6", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX6", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX6", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX6", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX6", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX6", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX6", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX6", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX6", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX6", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX6", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX6", "SWR_DMIC7", "TX SWR_DMIC7"}, + + {"TX DEC7 MUX", "MSM_DMIC", "TX DMIC MUX7"}, + {"TX DMIC MUX7", "DMIC0", "TX DMIC0"}, + {"TX DMIC MUX7", "DMIC1", "TX DMIC1"}, + {"TX DMIC MUX7", "DMIC2", "TX DMIC2"}, + {"TX DMIC MUX7", "DMIC3", "TX DMIC3"}, + {"TX DMIC MUX7", "DMIC4", "TX DMIC4"}, + {"TX DMIC MUX7", "DMIC5", "TX DMIC5"}, + {"TX DMIC MUX7", "DMIC6", "TX DMIC6"}, + {"TX DMIC MUX7", "DMIC7", "TX DMIC7"}, + + {"TX DEC7 MUX", "SWR_MIC", "TX SMIC MUX7"}, + {"TX SMIC MUX7", "ADC0", "TX SWR_ADC0"}, + {"TX SMIC MUX7", "ADC1", "TX SWR_ADC1"}, + {"TX SMIC MUX7", "ADC2", "TX SWR_ADC2"}, + {"TX SMIC MUX7", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX7", "SWR_DMIC0", "TX SWR_DMIC0"}, + {"TX SMIC MUX7", "SWR_DMIC1", "TX SWR_DMIC1"}, + {"TX SMIC MUX7", "SWR_DMIC2", "TX SWR_DMIC2"}, + {"TX SMIC MUX7", "SWR_DMIC3", "TX SWR_DMIC3"}, + {"TX SMIC MUX7", "SWR_DMIC4", "TX SWR_DMIC4"}, + {"TX SMIC MUX7", "SWR_DMIC5", "TX SWR_DMIC5"}, + {"TX SMIC MUX7", "SWR_DMIC6", "TX SWR_DMIC6"}, + {"TX SMIC MUX7", "SWR_DMIC7", "TX SWR_DMIC7"}, +}; + +static const struct snd_kcontrol_new tx_macro_snd_controls[] = { + SOC_SINGLE_SX_TLV("TX_DEC0 Volume", + BOLERO_CDC_TX0_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("TX_DEC1 Volume", + BOLERO_CDC_TX1_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("TX_DEC2 Volume", + BOLERO_CDC_TX2_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("TX_DEC3 Volume", + BOLERO_CDC_TX3_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("TX_DEC4 Volume", + BOLERO_CDC_TX4_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("TX_DEC5 Volume", + BOLERO_CDC_TX5_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("TX_DEC6 Volume", + BOLERO_CDC_TX6_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("TX_DEC7 Volume", + BOLERO_CDC_TX7_TX_VOL_CTL, + 0, -84, 40, digital_gain), +}; + +static int tx_macro_swrm_clock(void *handle, bool enable) +{ + struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle; + struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL); + int ret = 0; + + mutex_lock(&tx_priv->swr_clk_lock); + + dev_dbg(tx_priv->dev, "%s: swrm clock %s\n", + __func__, (enable ? "enable" : "disable")); + if (enable) { + if (tx_priv->swr_clk_users == 0) { + ret = tx_macro_mclk_enable(tx_priv, 1); + if (ret < 0) { + dev_err(tx_priv->dev, + "%s: request clock enable failed\n", + __func__); + goto exit; + } + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x01); + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, + 0x1C, 0x0C); + msm_cdc_pinctrl_select_active_state( + tx_priv->tx_swr_gpio_p); + } + tx_priv->swr_clk_users++; + } else { + if (tx_priv->swr_clk_users <= 0) { + dev_err(tx_priv->dev, + "tx swrm clock users already 0\n"); + tx_priv->swr_clk_users = 0; + goto exit; + } + tx_priv->swr_clk_users--; + if (tx_priv->swr_clk_users == 0) { + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x00); + msm_cdc_pinctrl_select_sleep_state( + tx_priv->tx_swr_gpio_p); + tx_macro_mclk_enable(tx_priv, 0); + } + } + dev_dbg(tx_priv->dev, "%s: swrm clock users %d\n", + __func__, tx_priv->swr_clk_users); +exit: + mutex_unlock(&tx_priv->swr_clk_lock); + return ret; +} + +static int tx_macro_validate_dmic_sample_rate(u32 dmic_sample_rate, + struct tx_macro_priv *tx_priv) +{ + u32 div_factor = TX_MACRO_CLK_DIV_2; + u32 mclk_rate = TX_MACRO_MCLK_FREQ; + + if (dmic_sample_rate == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED || + mclk_rate % dmic_sample_rate != 0) + goto undefined_rate; + + div_factor = mclk_rate / dmic_sample_rate; + + switch (div_factor) { + case 2: + tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_2; + break; + case 3: + tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_3; + break; + case 4: + tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_4; + break; + case 6: + tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_6; + break; + case 8: + tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_8; + break; + case 16: + tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_16; + break; + default: + /* Any other DIV factor is invalid */ + goto undefined_rate; + } + + /* Valid dmic DIV factors */ + dev_dbg(tx_priv->dev, "%s: DMIC_DIV = %u, mclk_rate = %u\n", + __func__, div_factor, mclk_rate); + + return dmic_sample_rate; + +undefined_rate: + dev_dbg(tx_priv->dev, "%s: Invalid rate %d, for mclk %d\n", + __func__, dmic_sample_rate, mclk_rate); + dmic_sample_rate = TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED; + + return dmic_sample_rate; +} + +static int tx_macro_init(struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + int ret = 0, i = 0; + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + + tx_dev = bolero_get_device_ptr(codec->dev, TX_MACRO); + if (!tx_dev) { + dev_err(codec->dev, + "%s: null device for macro!\n", __func__); + return -EINVAL; + } + tx_priv = dev_get_drvdata(tx_dev); + if (!tx_priv) { + dev_err(codec->dev, + "%s: priv is null for macro!\n", __func__); + return -EINVAL; + } + ret = snd_soc_dapm_new_controls(dapm, tx_macro_dapm_widgets, + ARRAY_SIZE(tx_macro_dapm_widgets)); + if (ret < 0) { + dev_err(tx_dev, "%s: Failed to add controls\n", __func__); + return ret; + } + + ret = snd_soc_dapm_add_routes(dapm, tx_audio_map, + ARRAY_SIZE(tx_audio_map)); + if (ret < 0) { + dev_err(tx_dev, "%s: Failed to add routes\n", __func__); + return ret; + } + + ret = snd_soc_dapm_new_widgets(dapm->card); + if (ret < 0) { + dev_err(tx_dev, "%s: Failed to add widgets\n", __func__); + return ret; + } + + ret = snd_soc_add_codec_controls(codec, tx_macro_snd_controls, + ARRAY_SIZE(tx_macro_snd_controls)); + if (ret < 0) { + dev_err(tx_dev, "%s: Failed to add snd_ctls\n", __func__); + return ret; + } + for (i = 0; i < NUM_DECIMATORS; i++) { + tx_priv->tx_hpf_work[i].tx_priv = tx_priv; + tx_priv->tx_hpf_work[i].decimator = i; + INIT_DELAYED_WORK(&tx_priv->tx_hpf_work[i].dwork, + tx_macro_tx_hpf_corner_freq_callback); + } + + for (i = 0; i < NUM_DECIMATORS; i++) { + tx_priv->tx_mute_dwork[i].tx_priv = tx_priv; + tx_priv->tx_mute_dwork[i].decimator = i; + INIT_DELAYED_WORK(&tx_priv->tx_mute_dwork[i].dwork, + tx_macro_mute_update_callback); + } + tx_priv->codec = codec; + + return 0; +} + +static int tx_macro_deinit(struct snd_soc_codec *codec) +{ + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + + if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + tx_priv->codec = NULL; + return 0; +} + +static void tx_macro_add_child_devices(struct work_struct *work) +{ + struct tx_macro_priv *tx_priv = NULL; + struct platform_device *pdev = NULL; + struct device_node *node = NULL; + struct tx_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp = NULL; + int ret = 0; + u16 count = 0, ctrl_num = 0; + struct tx_macro_swr_ctrl_platform_data *platdata = NULL; + char plat_dev_name[TX_MACRO_SWR_STRING_LEN] = ""; + bool tx_swr_master_node = false; + + tx_priv = container_of(work, struct tx_macro_priv, + tx_macro_add_child_devices_work); + if (!tx_priv) { + pr_err("%s: Memory for tx_priv does not exist\n", + __func__); + return; + } + + if (!tx_priv->dev) { + pr_err("%s: tx dev does not exist\n", __func__); + return; + } + + if (!tx_priv->dev->of_node) { + dev_err(tx_priv->dev, + "%s: DT node for tx_priv does not exist\n", __func__); + return; + } + + platdata = &tx_priv->swr_plat_data; + tx_priv->child_count = 0; + + for_each_available_child_of_node(tx_priv->dev->of_node, node) { + tx_swr_master_node = false; + if (strnstr(node->name, "tx_swr_master", + strlen("tx_swr_master")) != NULL) + tx_swr_master_node = true; + + if (tx_swr_master_node) + strlcpy(plat_dev_name, "tx_swr_ctrl", + (TX_MACRO_SWR_STRING_LEN - 1)); + else + strlcpy(plat_dev_name, node->name, + (TX_MACRO_SWR_STRING_LEN - 1)); + + pdev = platform_device_alloc(plat_dev_name, -1); + if (!pdev) { + dev_err(tx_priv->dev, "%s: pdev memory alloc failed\n", + __func__); + ret = -ENOMEM; + goto err; + } + pdev->dev.parent = tx_priv->dev; + pdev->dev.of_node = node; + + if (tx_swr_master_node) { + ret = platform_device_add_data(pdev, platdata, + sizeof(*platdata)); + if (ret) { + dev_err(&pdev->dev, + "%s: cannot add plat data ctrl:%d\n", + __func__, ctrl_num); + goto fail_pdev_add; + } + } + + ret = platform_device_add(pdev); + if (ret) { + dev_err(&pdev->dev, + "%s: Cannot add platform device\n", + __func__); + goto fail_pdev_add; + } + + if (tx_swr_master_node) { + temp = krealloc(swr_ctrl_data, + (ctrl_num + 1) * sizeof( + struct tx_macro_swr_ctrl_data), + GFP_KERNEL); + if (!temp) { + ret = -ENOMEM; + goto fail_pdev_add; + } + swr_ctrl_data = temp; + swr_ctrl_data[ctrl_num].tx_swr_pdev = pdev; + ctrl_num++; + dev_dbg(&pdev->dev, + "%s: Added soundwire ctrl device(s)\n", + __func__); + tx_priv->swr_ctrl_data = swr_ctrl_data; + } + if (tx_priv->child_count < TX_MACRO_CHILD_DEVICES_MAX) + tx_priv->pdev_child_devices[ + tx_priv->child_count++] = pdev; + else + goto err; + } + return; +fail_pdev_add: + for (count = 0; count < tx_priv->child_count; count++) + platform_device_put(tx_priv->pdev_child_devices[count]); +err: + return; +} + +static void tx_macro_init_ops(struct macro_ops *ops, + char __iomem *tx_io_base) +{ + memset(ops, 0, sizeof(struct macro_ops)); + ops->init = tx_macro_init; + ops->exit = tx_macro_deinit; + ops->io_base = tx_io_base; + ops->dai_ptr = tx_macro_dai; + ops->num_dais = ARRAY_SIZE(tx_macro_dai); + ops->mclk_fn = tx_macro_mclk_ctrl; +} + +static int tx_macro_probe(struct platform_device *pdev) +{ + struct macro_ops ops = {0}; + struct tx_macro_priv *tx_priv = NULL; + u32 tx_base_addr = 0, sample_rate = 0; + char __iomem *tx_io_base = NULL; + struct clk *tx_core_clk = NULL, *tx_npl_clk = NULL; + int ret = 0; + const char *dmic_sample_rate = "qcom,tx-dmic-sample-rate"; + + tx_priv = devm_kzalloc(&pdev->dev, sizeof(struct tx_macro_priv), + GFP_KERNEL); + if (!tx_priv) + return -ENOMEM; + platform_set_drvdata(pdev, tx_priv); + + tx_priv->dev = &pdev->dev; + ret = of_property_read_u32(pdev->dev.of_node, "reg", + &tx_base_addr); + if (ret) { + dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "reg"); + return ret; + } + dev_set_drvdata(&pdev->dev, tx_priv); + tx_priv->tx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,tx-swr-gpios", 0); + if (!tx_priv->tx_swr_gpio_p) { + dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n", + __func__); + return -EINVAL; + } + tx_io_base = devm_ioremap(&pdev->dev, + tx_base_addr, TX_MACRO_MAX_OFFSET); + if (!tx_io_base) { + dev_err(&pdev->dev, "%s: ioremap failed\n", __func__); + return -ENOMEM; + } + tx_priv->tx_io_base = tx_io_base; + ret = of_property_read_u32(pdev->dev.of_node, dmic_sample_rate, + &sample_rate); + if (ret) { + dev_err(&pdev->dev, + "%s: could not find sample_rate entry in dt\n", + __func__); + tx_priv->dmic_clk_div = TX_MACRO_CLK_DIV_2; + } else { + if (tx_macro_validate_dmic_sample_rate( + sample_rate, tx_priv) == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED) + return -EINVAL; + } + + INIT_WORK(&tx_priv->tx_macro_add_child_devices_work, + tx_macro_add_child_devices); + tx_priv->swr_plat_data.handle = (void *) tx_priv; + tx_priv->swr_plat_data.read = NULL; + tx_priv->swr_plat_data.write = NULL; + tx_priv->swr_plat_data.bulk_write = NULL; + tx_priv->swr_plat_data.clk = tx_macro_swrm_clock; + tx_priv->swr_plat_data.handle_irq = NULL; + /* Register MCLK for tx macro */ + tx_core_clk = devm_clk_get(&pdev->dev, "tx_core_clk"); + if (IS_ERR(tx_core_clk)) { + ret = PTR_ERR(tx_core_clk); + dev_err(&pdev->dev, "%s: clk get %s failed %d\n", + __func__, "tx_core_clk", ret); + return ret; + } + tx_priv->tx_core_clk = tx_core_clk; + /* Register npl clk for soundwire */ + tx_npl_clk = devm_clk_get(&pdev->dev, "tx_npl_clk"); + if (IS_ERR(tx_npl_clk)) { + ret = PTR_ERR(tx_npl_clk); + dev_err(&pdev->dev, "%s: clk get %s failed %d\n", + __func__, "tx_npl_clk", ret); + return ret; + } + tx_priv->tx_npl_clk = tx_npl_clk; + + mutex_init(&tx_priv->mclk_lock); + mutex_init(&tx_priv->swr_clk_lock); + tx_macro_init_ops(&ops, tx_io_base); + ret = bolero_register_macro(&pdev->dev, TX_MACRO, &ops); + if (ret) { + dev_err(&pdev->dev, + "%s: register macro failed\n", __func__); + goto err_reg_macro; + } + schedule_work(&tx_priv->tx_macro_add_child_devices_work); + return 0; +err_reg_macro: + mutex_destroy(&tx_priv->mclk_lock); + mutex_destroy(&tx_priv->swr_clk_lock); + return ret; +} + +static int tx_macro_remove(struct platform_device *pdev) +{ + struct tx_macro_priv *tx_priv = NULL; + u16 count = 0; + + tx_priv = platform_get_drvdata(pdev); + + if (!tx_priv) + return -EINVAL; + + kfree(tx_priv->swr_ctrl_data); + for (count = 0; count < tx_priv->child_count && + count < TX_MACRO_CHILD_DEVICES_MAX; count++) + platform_device_unregister(tx_priv->pdev_child_devices[count]); + + mutex_destroy(&tx_priv->mclk_lock); + mutex_destroy(&tx_priv->swr_clk_lock); + bolero_unregister_macro(&pdev->dev, TX_MACRO); + return 0; +} + + +static const struct of_device_id tx_macro_dt_match[] = { + {.compatible = "qcom,tx-macro"}, + {} +}; + +static struct platform_driver tx_macro_driver = { + .driver = { + .name = "tx_macro", + .owner = THIS_MODULE, + .of_match_table = tx_macro_dt_match, + }, + .probe = tx_macro_probe, + .remove = tx_macro_remove, +}; + +module_platform_driver(tx_macro_driver); + +MODULE_DESCRIPTION("TX macro driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From a7ecc58a35c3155ef1bc2cc66b4dfb4fdecf895c Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 15 Jun 2018 16:55:02 +0530 Subject: [PATCH 0417/1645] asoc: bolero: Add support for RX macro driver Add support for RX digital portion to register as macro to bolero codec. ASoC dapm and dai functionality of RX macro is associated to bolero codec itself. Change-Id: Idb924b33cfc5d258d2f876a31603e724ad9699e9 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc-regmap.c | 27 + asoc/codecs/bolero/rx-macro.c | 2560 ++++++++++++++++++++++++ 2 files changed, 2587 insertions(+) create mode 100644 asoc/codecs/bolero/rx-macro.c diff --git a/asoc/codecs/bolero/bolero-cdc-regmap.c b/asoc/codecs/bolero/bolero-cdc-regmap.c index ef5b5908591f..ecc13243d999 100644 --- a/asoc/codecs/bolero/bolero-cdc-regmap.c +++ b/asoc/codecs/bolero/bolero-cdc-regmap.c @@ -816,6 +816,33 @@ static bool bolero_is_volatile_register(struct device *dev, case BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB: case BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB: case BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FIFO: + case BOLERO_CDC_RX_TOP_HPHL_COMP_RD_LSB: + case BOLERO_CDC_RX_TOP_HPHL_COMP_RD_MSB: + case BOLERO_CDC_RX_TOP_HPHR_COMP_RD_LSB: + case BOLERO_CDC_RX_TOP_HPHR_COMP_RD_MSB: + case BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG2: + case BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG2: + case BOLERO_CDC_RX_BCL_VBAT_GAIN_MON_VAL: + case BOLERO_CDC_RX_BCL_VBAT_DECODE_ST: + case BOLERO_CDC_RX_INTR_CTRL_PIN1_STATUS0: + case BOLERO_CDC_RX_INTR_CTRL_PIN2_STATUS0: + case BOLERO_CDC_RX_COMPANDER0_CTL6: + case BOLERO_CDC_RX_COMPANDER1_CTL6: + case BOLERO_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB: + case BOLERO_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB: + case BOLERO_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB: + case BOLERO_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB: + case BOLERO_CDC_RX_EC_ASRC0_STATUS_FIFO: + case BOLERO_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB: + case BOLERO_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB: + case BOLERO_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB: + case BOLERO_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB: + case BOLERO_CDC_RX_EC_ASRC1_STATUS_FIFO: + case BOLERO_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB: + case BOLERO_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB: + case BOLERO_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB: + case BOLERO_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB: + case BOLERO_CDC_RX_EC_ASRC2_STATUS_FIFO: return true; } return false; diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c new file mode 100644 index 000000000000..d5071279f53f --- /dev/null +++ b/asoc/codecs/bolero/rx-macro.c @@ -0,0 +1,2560 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bolero-cdc.h" +#include "bolero-cdc-registers.h" +#include "../msm-cdc-pinctrl.h" + +#define RX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\ + SNDRV_PCM_RATE_384000) +/* Fractional Rates */ +#define RX_MACRO_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800) + +#define RX_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) + +#define RX_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_48000) +#define RX_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_3LE) + +#define RX_MACRO_MAX_OFFSET 0x1000 + +#define RX_MACRO_MAX_DMA_CH_PER_PORT 2 +#define RX_SWR_STRING_LEN 80 +#define RX_MACRO_CHILD_DEVICES_MAX 3 + +#define RX_MACRO_INTERP_MUX_NUM_INPUTS 3 +#define RX_MACRO_SIDETONE_IIR_COEFF_MAX 5 + +#define STRING(name) #name +#define RX_MACRO_DAPM_ENUM(name, reg, offset, text) \ +static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ +static const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_ENUM(STRING(name), name##_enum) + +#define RX_MACRO_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \ +static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ +static const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname) + +#define RX_MACRO_DAPM_MUX(name, shift, kctl) \ + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux) + +#define RX_MACRO_RX_PATH_OFFSET 0x80 +#define RX_MACRO_COMP_OFFSET 0x40 + +enum { + INTERP_HPHL, + INTERP_HPHR, + INTERP_AUX, + INTERP_MAX +}; + +enum { + RX_MACRO_RX0, + RX_MACRO_RX1, + RX_MACRO_RX2, + RX_MACRO_RX3, + RX_MACRO_RX4, + RX_MACRO_RX5, + RX_MACRO_PORTS_MAX +}; + +enum { + RX_MACRO_COMP1, /* HPH_L */ + RX_MACRO_COMP2, /* HPH_R */ + RX_MACRO_COMP_MAX +}; + +enum { + INTn_1_INP_SEL_ZERO = 0, + INTn_1_INP_SEL_DEC0, + INTn_1_INP_SEL_DEC1, + INTn_1_INP_SEL_IIR0, + INTn_1_INP_SEL_IIR1, + INTn_1_INP_SEL_RX0, + INTn_1_INP_SEL_RX1, + INTn_1_INP_SEL_RX2, + INTn_1_INP_SEL_RX3, + INTn_1_INP_SEL_RX4, + INTn_1_INP_SEL_RX5, +}; + +enum { + INTn_2_INP_SEL_ZERO = 0, + INTn_2_INP_SEL_RX0, + INTn_2_INP_SEL_RX1, + INTn_2_INP_SEL_RX2, + INTn_2_INP_SEL_RX3, + INTn_2_INP_SEL_RX4, + INTn_2_INP_SEL_RX5, +}; + +enum { + INTERP_MAIN_PATH, + INTERP_MIX_PATH, +}; + +/* Codec supports 2 IIR filters */ +enum { + IIR0 = 0, + IIR1, + IIR_MAX, +}; + +/* Each IIR has 5 Filter Stages */ +enum { + BAND1 = 0, + BAND2, + BAND3, + BAND4, + BAND5, + BAND_MAX, +}; + +struct rx_macro_idle_detect_config { + u8 hph_idle_thr; + u8 hph_idle_detect_en; +}; + +struct interp_sample_rate { + int sample_rate; + int rate_val; +}; + +static struct interp_sample_rate sr_val_tbl[] = { + {8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5}, + {192000, 0x6}, {384000, 0x7}, {44100, 0x9}, {88200, 0xA}, + {176400, 0xB}, {352800, 0xC}, +}; + +static int rx_macro_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai); +static int rx_macro_get_channel_map(struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot); +static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int rx_macro_mux_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int rx_macro_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, + int event, int interp_idx); + +/* Hold instance to soundwire platform device */ +struct rx_swr_ctrl_data { + struct platform_device *rx_swr_pdev; +}; + +struct rx_swr_ctrl_platform_data { + void *handle; /* holds codec private data */ + int (*read)(void *handle, int reg); + int (*write)(void *handle, int reg, int val); + int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); + int (*clk)(void *handle, bool enable); + int (*handle_irq)(void *handle, + irqreturn_t (*swrm_irq_handler)(int irq, + void *data), + void *swrm_handle, + int action); +}; + +enum { + RX_MACRO_AIF1_PB = 0, + RX_MACRO_AIF2_PB, + RX_MACRO_AIF3_PB, + RX_MACRO_AIF4_PB, + RX_MACRO_MAX_DAIS, +}; + +enum { + RX_MACRO_AIF1_CAP = 0, + RX_MACRO_AIF2_CAP, + RX_MACRO_AIF3_CAP, + RX_MACRO_MAX_AIF_CAP_DAIS +}; +/* + * @dev: rx macro device pointer + * @comp_enabled: compander enable mixer value set + * @prim_int_users: Users of interpolator + * @rx_mclk_users: RX MCLK users count + * @vi_feed_value: VI sense mask + * @swr_clk_lock: to lock swr master clock operations + * @swr_ctrl_data: SoundWire data structure + * @swr_plat_data: Soundwire platform data + * @rx_macro_add_child_devices_work: work for adding child devices + * @rx_swr_gpio_p: used by pinctrl API + * @rx_core_clk: MCLK for rx macro + * @rx_npl_clk: NPL clock for RX soundwire + * @codec: codec handle + */ +struct rx_macro_priv { + struct device *dev; + int comp_enabled[RX_MACRO_COMP_MAX]; + /* Main path clock users count */ + int main_clk_users[INTERP_MAX]; + int rx_port_value[RX_MACRO_PORTS_MAX]; + u16 prim_int_users[INTERP_MAX]; + int rx_mclk_users; + int swr_clk_users; + int rx_mclk_cnt; + struct mutex mclk_lock; + struct mutex swr_clk_lock; + struct rx_swr_ctrl_data *swr_ctrl_data; + struct rx_swr_ctrl_platform_data swr_plat_data; + struct work_struct rx_macro_add_child_devices_work; + struct device_node *rx_swr_gpio_p; + struct clk *rx_core_clk; + struct clk *rx_npl_clk; + struct snd_soc_codec *codec; + unsigned long active_ch_mask[RX_MACRO_MAX_DAIS]; + unsigned long active_ch_cnt[RX_MACRO_MAX_DAIS]; + u16 bit_width[RX_MACRO_MAX_DAIS]; + char __iomem *rx_io_base; + char __iomem *rx_mclk_mode_muxsel; + struct rx_macro_idle_detect_config idle_det_cfg; + u8 sidetone_coeff_array[IIR_MAX][BAND_MAX] + [RX_MACRO_SIDETONE_IIR_COEFF_MAX * 4]; + + struct platform_device *pdev_child_devices + [RX_MACRO_CHILD_DEVICES_MAX]; + int child_count; +}; + +static struct snd_soc_dai_driver rx_macro_dai[]; +static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); + +static const char * const rx_int_mix_mux_text[] = { + "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5" +}; + +static const char * const rx_prim_mix_text[] = { + "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2", + "RX3", "RX4", "RX5" +}; + +static const char * const rx_sidetone_mix_text[] = { + "ZERO", "SRC0", "SRC1", "SRC_SUM" +}; + +static const char * const rx_echo_mux_text[] = { + "ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2" +}; + +static const char * const iir_inp_mux_text[] = { + "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", + "RX0", "RX1", "RX2", "RX3", "RX4", "RX5" +}; + +static const char * const rx_int_dem_inp_mux_text[] = { + "NORMAL_DSM_OUT", "CLSH_DSM_OUT", +}; + +static const char * const rx_int0_1_interp_mux_text[] = { + "ZERO", "RX INT0_1 MIX1", +}; + +static const char * const rx_int1_1_interp_mux_text[] = { + "ZERO", "RX INT1_1 MIX1", +}; + +static const char * const rx_int2_1_interp_mux_text[] = { + "ZERO", "RX INT2_1 MIX1", +}; + +static const char * const rx_int0_2_interp_mux_text[] = { + "ZERO", "RX INT0_2 MUX", +}; + +static const char * const rx_int1_2_interp_mux_text[] = { + "ZERO", "RX INT1_2 MUX", +}; + +static const char * const rx_int2_2_interp_mux_text[] = { + "ZERO", "RX INT2_2 MUX", +}; + +static const char *const rx_macro_mux_text[] = { + "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB" +}; + +RX_MACRO_DAPM_ENUM(rx_int0_2, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, + rx_int_mix_mux_text); +RX_MACRO_DAPM_ENUM(rx_int1_2, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, + rx_int_mix_mux_text); +RX_MACRO_DAPM_ENUM(rx_int2_2, BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, + rx_int_mix_mux_text); + + +RX_MACRO_DAPM_ENUM(rx_int0_1_mix_inp0, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0, 0, + rx_prim_mix_text); +RX_MACRO_DAPM_ENUM(rx_int0_1_mix_inp1, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0, 4, + rx_prim_mix_text); +RX_MACRO_DAPM_ENUM(rx_int0_1_mix_inp2, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1, 4, + rx_prim_mix_text); +RX_MACRO_DAPM_ENUM(rx_int1_1_mix_inp0, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0, 0, + rx_prim_mix_text); +RX_MACRO_DAPM_ENUM(rx_int1_1_mix_inp1, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0, 4, + rx_prim_mix_text); +RX_MACRO_DAPM_ENUM(rx_int1_1_mix_inp2, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1, 4, + rx_prim_mix_text); +RX_MACRO_DAPM_ENUM(rx_int2_1_mix_inp0, BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, + rx_prim_mix_text); +RX_MACRO_DAPM_ENUM(rx_int2_1_mix_inp1, BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG0, 4, + rx_prim_mix_text); +RX_MACRO_DAPM_ENUM(rx_int2_1_mix_inp2, BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG1, 4, + rx_prim_mix_text); + +RX_MACRO_DAPM_ENUM(rx_int0_mix2_inp, BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2, + rx_sidetone_mix_text); +RX_MACRO_DAPM_ENUM(rx_int1_mix2_inp, BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4, + rx_sidetone_mix_text); +RX_MACRO_DAPM_ENUM(rx_int2_mix2_inp, BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6, + rx_sidetone_mix_text); + +RX_MACRO_DAPM_ENUM(rx_mix_tx0, BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4, 4, + rx_echo_mux_text); +RX_MACRO_DAPM_ENUM(rx_mix_tx1, BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, + rx_echo_mux_text); +RX_MACRO_DAPM_ENUM(rx_mix_tx2, BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, + rx_echo_mux_text); + +RX_MACRO_DAPM_ENUM(iir0_inp0, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0, 0, + iir_inp_mux_text); +RX_MACRO_DAPM_ENUM(iir0_inp1, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1, 0, + iir_inp_mux_text); +RX_MACRO_DAPM_ENUM(iir0_inp2, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2, 0, + iir_inp_mux_text); +RX_MACRO_DAPM_ENUM(iir0_inp3, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3, 0, + iir_inp_mux_text); +RX_MACRO_DAPM_ENUM(iir1_inp0, BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0, 0, + iir_inp_mux_text); +RX_MACRO_DAPM_ENUM(iir1_inp1, BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1, 0, + iir_inp_mux_text); +RX_MACRO_DAPM_ENUM(iir1_inp2, BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2, 0, + iir_inp_mux_text); +RX_MACRO_DAPM_ENUM(iir1_inp3, BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3, 0, + iir_inp_mux_text); + +RX_MACRO_DAPM_ENUM(rx_int0_1_interp, SND_SOC_NOPM, 0, + rx_int0_1_interp_mux_text); +RX_MACRO_DAPM_ENUM(rx_int1_1_interp, SND_SOC_NOPM, 0, + rx_int1_1_interp_mux_text); +RX_MACRO_DAPM_ENUM(rx_int2_1_interp, SND_SOC_NOPM, 0, + rx_int2_1_interp_mux_text); + +RX_MACRO_DAPM_ENUM(rx_int0_2_interp, SND_SOC_NOPM, 0, + rx_int0_2_interp_mux_text); +RX_MACRO_DAPM_ENUM(rx_int1_2_interp, SND_SOC_NOPM, 0, + rx_int1_2_interp_mux_text); +RX_MACRO_DAPM_ENUM(rx_int2_2_interp, SND_SOC_NOPM, 0, + rx_int2_2_interp_mux_text); + +RX_MACRO_DAPM_ENUM_EXT(rx_int0_dem_inp, BOLERO_CDC_RX_RX0_RX_PATH_CFG1, 0, + rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double, + rx_macro_int_dem_inp_mux_put); +RX_MACRO_DAPM_ENUM_EXT(rx_int1_dem_inp, BOLERO_CDC_RX_RX1_RX_PATH_CFG1, 0, + rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double, + rx_macro_int_dem_inp_mux_put); + +RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx0, SND_SOC_NOPM, 0, rx_macro_mux_text, + rx_macro_mux_get, rx_macro_mux_put); +RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx1, SND_SOC_NOPM, 0, rx_macro_mux_text, + rx_macro_mux_get, rx_macro_mux_put); +RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx2, SND_SOC_NOPM, 0, rx_macro_mux_text, + rx_macro_mux_get, rx_macro_mux_put); +RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx3, SND_SOC_NOPM, 0, rx_macro_mux_text, + rx_macro_mux_get, rx_macro_mux_put); +RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx4, SND_SOC_NOPM, 0, rx_macro_mux_text, + rx_macro_mux_get, rx_macro_mux_put); +RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx5, SND_SOC_NOPM, 0, rx_macro_mux_text, + rx_macro_mux_get, rx_macro_mux_put); + +static struct snd_soc_dai_ops rx_macro_dai_ops = { + .hw_params = rx_macro_hw_params, + .get_channel_map = rx_macro_get_channel_map, +}; + +static struct snd_soc_dai_driver rx_macro_dai[] = { + { + .name = "rx_macro_rx1", + .id = RX_MACRO_AIF1_PB, + .playback = { + .stream_name = "RX_MACRO_AIF1 Playback", + .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES, + .formats = RX_MACRO_FORMATS, + .rate_max = 384000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &rx_macro_dai_ops, + }, + { + .name = "rx_macro_rx2", + .id = RX_MACRO_AIF2_PB, + .playback = { + .stream_name = "RX_MACRO_AIF2 Playback", + .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES, + .formats = RX_MACRO_FORMATS, + .rate_max = 384000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &rx_macro_dai_ops, + }, + { + .name = "rx_macro_rx3", + .id = RX_MACRO_AIF3_PB, + .playback = { + .stream_name = "RX_MACRO_AIF3 Playback", + .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES, + .formats = RX_MACRO_FORMATS, + .rate_max = 384000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &rx_macro_dai_ops, + }, + { + .name = "rx_macro_rx4", + .id = RX_MACRO_AIF4_PB, + .playback = { + .stream_name = "RX_MACRO_AIF4 Playback", + .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES, + .formats = RX_MACRO_FORMATS, + .rate_max = 384000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &rx_macro_dai_ops, + }, +}; + +static bool rx_macro_get_data(struct snd_soc_codec *codec, + struct device **rx_dev, + struct rx_macro_priv **rx_priv, + const char *func_name) +{ + *rx_dev = bolero_get_device_ptr(codec->dev, RX_MACRO); + + if (!(*rx_dev)) { + dev_err(codec->dev, + "%s: null device for macro!\n", func_name); + return false; + } + + *rx_priv = dev_get_drvdata((*rx_dev)); + if (!(*rx_priv)) { + dev_err(codec->dev, + "%s: priv is null for macro!\n", func_name); + return false; + } + + if (!(*rx_priv)->codec) { + dev_err(codec->dev, + "%s: tx_priv codec is not initialized!\n", func_name); + return false; + } + + return true; +} + +static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val = 0; + unsigned short look_ahead_dly_reg = + BOLERO_CDC_RX_RX0_RX_PATH_CFG0; + + val = ucontrol->value.enumerated.item[0]; + if (val >= e->items) + return -EINVAL; + + dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + widget->name, val); + + if (e->reg == BOLERO_CDC_RX_RX0_RX_PATH_CFG1) + look_ahead_dly_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0; + else if (e->reg == BOLERO_CDC_RX_RX1_RX_PATH_CFG1) + look_ahead_dly_reg = BOLERO_CDC_RX_RX1_RX_PATH_CFG0; + + /* Set Look Ahead Delay */ + snd_soc_update_bits(codec, look_ahead_dly_reg, + 0x08, (val ? 0x08 : 0x00)); + /* Set DEM INP Select */ + return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); +} + +static int rx_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, + u8 rate_reg_val, + u32 sample_rate) +{ + u8 int_1_mix1_inp = 0; + u32 j = 0, port = 0; + u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0; + u16 int_fs_reg = 0; + u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0; + u8 inp0_sel = 0, inp1_sel = 0, inp2_sel = 0; + struct snd_soc_codec *codec = dai->codec; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + for_each_set_bit(port, &rx_priv->active_ch_mask[dai->id], + RX_MACRO_PORTS_MAX) { + int_1_mix1_inp = port; + if ((int_1_mix1_inp < RX_MACRO_RX0) || + (int_1_mix1_inp > RX_MACRO_PORTS_MAX)) { + pr_err("%s: Invalid RX port, Dai ID is %d\n", + __func__, dai->id); + return -EINVAL; + } + + int_mux_cfg0 = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0; + + /* + * Loop through all interpolator MUX inputs and find out + * to which interpolator input, the rx port + * is connected + */ + for (j = 0; j < INTERP_MAX; j++) { + int_mux_cfg1 = int_mux_cfg0 + 4; + + int_mux_cfg0_val = snd_soc_read(codec, int_mux_cfg0); + int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1); + inp0_sel = int_mux_cfg0_val & 0x07; + inp1_sel = (int_mux_cfg0_val >> 4) & 0x038; + inp2_sel = (int_mux_cfg1_val >> 4) & 0x038; + if ((inp0_sel == int_1_mix1_inp) || + (inp1_sel == int_1_mix1_inp) || + (inp2_sel == int_1_mix1_inp)) { + int_fs_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + + 0x80 * j; + pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_1\n", + __func__, dai->id, j); + pr_debug("%s: set INT%u_1 sample rate to %u\n", + __func__, j, sample_rate); + /* sample_rate is in Hz */ + snd_soc_update_bits(codec, int_fs_reg, + 0x0F, rate_reg_val); + } + int_mux_cfg0 += 8; + } + } + + return 0; +} + +static int rx_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, + u8 rate_reg_val, + u32 sample_rate) +{ + u8 int_2_inp = 0; + u32 j = 0, port = 0; + u16 int_mux_cfg1 = 0, int_fs_reg = 0; + u8 int_mux_cfg1_val = 0; + struct snd_soc_codec *codec = dai->codec; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + for_each_set_bit(port, &rx_priv->active_ch_mask[dai->id], + RX_MACRO_PORTS_MAX) { + int_2_inp = port; + if ((int_2_inp < RX_MACRO_RX0) || + (int_2_inp > RX_MACRO_PORTS_MAX)) { + pr_err("%s: Invalid RX port, Dai ID is %d\n", + __func__, dai->id); + return -EINVAL; + } + + int_mux_cfg1 = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1; + for (j = 0; j < INTERP_MAX; j++) { + int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1) & + 0x07; + if (int_mux_cfg1_val == int_2_inp) { + int_fs_reg = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL + + 0x80 * j; + pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_2\n", + __func__, dai->id, j); + pr_debug("%s: set INT%u_2 sample rate to %u\n", + __func__, j, sample_rate); + snd_soc_update_bits(codec, int_fs_reg, + 0x0F, rate_reg_val); + } + int_mux_cfg1 += 8; + } + } + return 0; +} + +static int rx_macro_set_interpolator_rate(struct snd_soc_dai *dai, + u32 sample_rate) +{ + struct snd_soc_codec *codec = dai->codec; + int rate_val = 0; + int i = 0, ret = 0; + + for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) { + if (sample_rate == sr_val_tbl[i].sample_rate) { + rate_val = sr_val_tbl[i].rate_val; + break; + } + } + if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) { + dev_err(codec->dev, "%s: Unsupported sample rate: %d\n", + __func__, sample_rate); + return -EINVAL; + } + + ret = rx_macro_set_prim_interpolator_rate(dai, (u8)rate_val, sample_rate); + if (ret) + return ret; + ret = rx_macro_set_mix_interpolator_rate(dai, (u8)rate_val, sample_rate); + if (ret) + return ret; + + return ret; +} + +static int rx_macro_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + int ret = 0; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + dev_dbg(codec->dev, + "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__, + dai->name, dai->id, params_rate(params), + params_channels(params)); + + switch (substream->stream) { + case SNDRV_PCM_STREAM_PLAYBACK: + ret = rx_macro_set_interpolator_rate(dai, params_rate(params)); + if (ret) { + pr_err("%s: cannot set sample rate: %u\n", + __func__, params_rate(params)); + return ret; + } + rx_priv->bit_width[dai->id] = params_width(params); + break; + case SNDRV_PCM_STREAM_CAPTURE: + default: + break; + } + return 0; +} + +static int rx_macro_get_channel_map(struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot) +{ + struct snd_soc_codec *codec = dai->codec; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + unsigned int temp = 0, ch_mask = 0; + u16 i = 0; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + switch (dai->id) { + case RX_MACRO_AIF1_PB: + case RX_MACRO_AIF2_PB: + case RX_MACRO_AIF3_PB: + case RX_MACRO_AIF4_PB: + for_each_set_bit(temp, &rx_priv->active_ch_mask[dai->id], + RX_MACRO_PORTS_MAX) { + ch_mask |= (1 << i); + if (++i == RX_MACRO_MAX_DMA_CH_PER_PORT) + break; + } + *rx_slot = ch_mask; + *rx_num = rx_priv->active_ch_cnt[dai->id]; + break; + default: + dev_err(rx_dev, "%s: Invalid AIF\n", __func__); + break; + } + return 0; +} + +static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, + bool mclk_enable, bool dapm) +{ + struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL); + int ret = 0; + + dev_dbg(rx_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", + __func__, mclk_enable, dapm, rx_priv->rx_mclk_users); + + mutex_lock(&rx_priv->mclk_lock); + if (mclk_enable) { + if (rx_priv->rx_mclk_users == 0) { + ret = bolero_request_clock(rx_priv->dev, + RX_MACRO, MCLK_MUX0, true); + if (ret < 0) { + dev_err(rx_priv->dev, + "%s: rx request clock enable failed\n", + __func__); + goto exit; + } + regcache_mark_dirty(regmap); + regcache_sync_region(regmap, + RX_START_OFFSET, + RX_MAX_OFFSET); + regmap_update_bits(regmap, + BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + regmap_update_bits(regmap, + BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); + } + rx_priv->rx_mclk_users++; + } else { + if (rx_priv->rx_mclk_users <= 0) { + dev_err(rx_priv->dev, "%s: clock already disabled\n", + __func__); + rx_priv->rx_mclk_users = 0; + goto exit; + } + rx_priv->rx_mclk_users--; + if (rx_priv->rx_mclk_users == 0) { + regmap_update_bits(regmap, + BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x00); + regmap_update_bits(regmap, + BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x00); + bolero_request_clock(rx_priv->dev, + RX_MACRO, MCLK_MUX0, false); + } + } +exit: + mutex_unlock(&rx_priv->mclk_lock); + return ret; +} + +static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int ret = 0; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + dev_dbg(rx_dev, "%s: event = %d\n", __func__, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = rx_macro_mclk_enable(rx_priv, 1, true); + break; + case SND_SOC_DAPM_POST_PMD: + ret = rx_macro_mclk_enable(rx_priv, 0, true); + break; + default: + dev_err(rx_priv->dev, + "%s: invalid DAPM event %d\n", __func__, event); + ret = -EINVAL; + } + return ret; +} + +static int rx_macro_mclk_ctrl(struct device *dev, bool enable) +{ + struct rx_macro_priv *rx_priv = dev_get_drvdata(dev); + int ret = 0; + + if (enable) { + ret = clk_prepare_enable(rx_priv->rx_core_clk); + if (ret < 0) { + dev_err(dev, "%s:rx mclk enable failed\n", __func__); + return ret; + } + ret = clk_prepare_enable(rx_priv->rx_npl_clk); + if (ret < 0) { + clk_disable_unprepare(rx_priv->rx_core_clk); + dev_err(dev, "%s:rx npl_clk enable failed\n", + __func__); + return ret; + } + if (rx_priv->rx_mclk_cnt++ == 0) + iowrite32(0x1, rx_priv->rx_mclk_mode_muxsel); + } else { + if (rx_priv->rx_mclk_cnt <= 0) { + dev_dbg(dev, "%s:rx mclk already disabled\n", __func__); + rx_priv->rx_mclk_cnt = 0; + return 0; + } + if (--rx_priv->rx_mclk_cnt == 0) + iowrite32(0x0, rx_priv->rx_mclk_mode_muxsel); + clk_disable_unprepare(rx_priv->rx_npl_clk); + clk_disable_unprepare(rx_priv->rx_core_clk); + } + + return 0; +} + +static int rx_macro_find_playback_dai_id_for_port(int port_id, + struct rx_macro_priv *rx_priv) +{ + int i = 0; + + for (i = RX_MACRO_AIF1_PB; i < RX_MACRO_MAX_DAIS; i++) { + if (test_bit(port_id, &rx_priv->active_ch_mask[i])) + return i; + } + + return -EINVAL; +} + +static int rx_macro_set_idle_detect_thr(struct snd_soc_codec *codec, + struct rx_macro_priv *rx_priv, + int interp, int path_type) +{ + int port_id[4] = { 0, 0, 0, 0 }; + int *port_ptr = NULL, num_ports = NULL; + int bit_width = 0, i = 0; + int mux_reg = 0, mux_reg_val = 0; + int dai_id = 0, idle_thr = 0; + + if ((interp != INTERP_HPHL) && (interp != INTERP_HPHR)) + return 0; + + if (!rx_priv->idle_det_cfg.hph_idle_detect_en) + return 0; + + port_ptr = &port_id[0]; + num_ports = 0; + + /* + * Read interpolator MUX input registers and find + * which cdc_dma port is connected and store the port + * numbers in port_id array. + */ + if (path_type == INTERP_MIX_PATH) { + mux_reg = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1 + + 2 * interp; + mux_reg_val = snd_soc_read(codec, mux_reg) & 0x0f; + + if ((mux_reg_val >= INTn_2_INP_SEL_RX0) && + (mux_reg_val <= INTn_2_INP_SEL_RX5)) { + *port_ptr++ = mux_reg_val - 1; + num_ports++; + } + } + + if (path_type == INTERP_MAIN_PATH) { + mux_reg = BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0 + + 2 * (interp - 1); + mux_reg_val = snd_soc_read(codec, mux_reg) & 0x0f; + i = RX_MACRO_INTERP_MUX_NUM_INPUTS; + + while (i) { + if ((mux_reg_val >= INTn_1_INP_SEL_RX0) && + (mux_reg_val <= INTn_1_INP_SEL_RX5)) { + *port_ptr++ = mux_reg_val - + INTn_1_INP_SEL_RX0; + num_ports++; + } + mux_reg_val = (snd_soc_read(codec, mux_reg) & + 0xf0) >> 4; + mux_reg += 1; + i--; + } + } + + dev_dbg(codec->dev, "%s: num_ports: %d, ports[%d %d %d %d]\n", + __func__, num_ports, port_id[0], port_id[1], + port_id[2], port_id[3]); + + i = 0; + while (num_ports) { + dai_id = rx_macro_find_playback_dai_id_for_port(port_id[i++], + rx_priv); + + if ((dai_id >= 0) && (dai_id < RX_MACRO_MAX_DAIS)) { + dev_dbg(codec->dev, "%s: dai_id: %d bit_width: %d\n", + __func__, dai_id, + rx_priv->bit_width[dai_id]); + + if (rx_priv->bit_width[dai_id] > bit_width) + bit_width = rx_priv->bit_width[dai_id]; + } + num_ports--; + } + + switch (bit_width) { + case 16: + idle_thr = 0xff; /* F16 */ + break; + case 24: + case 32: + idle_thr = 0x03; /* F22 */ + break; + default: + idle_thr = 0x00; + break; + } + + dev_dbg(codec->dev, "%s: (new) idle_thr: %d, (cur) idle_thr: %d\n", + __func__, idle_thr, rx_priv->idle_det_cfg.hph_idle_thr); + + if ((rx_priv->idle_det_cfg.hph_idle_thr == 0) || + (idle_thr < rx_priv->idle_det_cfg.hph_idle_thr)) { + snd_soc_write(codec, BOLERO_CDC_RX_IDLE_DETECT_CFG3, idle_thr); + rx_priv->idle_det_cfg.hph_idle_thr = idle_thr; + } + + return 0; +} + +static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 gain_reg = 0, mix_reg = 0; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + if (w->shift >= INTERP_MAX) { + dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", + __func__, w->shift, w->name); + return -EINVAL; + } + + gain_reg = BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL + + (w->shift * RX_MACRO_RX_PATH_OFFSET); + mix_reg = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL + + (w->shift * RX_MACRO_RX_PATH_OFFSET); + + dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rx_macro_set_idle_detect_thr(codec, rx_priv, w->shift, + INTERP_MIX_PATH); + rx_macro_enable_interp_clk(codec, event, w->shift); + /* Clk enable */ + snd_soc_update_bits(codec, mix_reg, 0x20, 0x20); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_write(codec, gain_reg, + snd_soc_read(codec, gain_reg)); + break; + case SND_SOC_DAPM_POST_PMD: + /* Clk Disable */ + snd_soc_update_bits(codec, mix_reg, 0x20, 0x00); + rx_macro_enable_interp_clk(codec, event, w->shift); + /* Reset enable and disable */ + snd_soc_update_bits(codec, mix_reg, 0x40, 0x40); + snd_soc_update_bits(codec, mix_reg, 0x40, 0x00); + break; + } + + return 0; +} + +static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 gain_reg = 0; + u16 reg = 0; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + + if (w->shift >= INTERP_MAX) { + dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", + __func__, w->shift, w->name); + return -EINVAL; + } + + reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + (w->shift * + RX_MACRO_RX_PATH_OFFSET); + gain_reg = BOLERO_CDC_RX_RX0_RX_VOL_CTL + (w->shift * + RX_MACRO_RX_PATH_OFFSET); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rx_macro_set_idle_detect_thr(codec, rx_priv, w->shift, + INTERP_MAIN_PATH); + rx_macro_enable_interp_clk(codec, event, w->shift); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_write(codec, gain_reg, + snd_soc_read(codec, gain_reg)); + break; + case SND_SOC_DAPM_POST_PMD: + rx_macro_enable_interp_clk(codec, event, w->shift); + break; + } + + return 0; +} + +static int rx_macro_config_compander(struct snd_soc_codec *codec, + struct rx_macro_priv *rx_priv, + int interp_n, int event) +{ + int comp = 0; + u16 comp_ctl0_reg = 0, rx_path_cfg0_reg = 0; + + /* AUX does not have compander */ + if (interp_n == INTERP_AUX) + return 0; + + comp = interp_n; + dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n", + __func__, event, comp + 1, rx_priv->comp_enabled[comp]); + + if (!rx_priv->comp_enabled[comp]) + return 0; + + comp_ctl0_reg = BOLERO_CDC_RX_COMPANDER0_CTL0 + + (comp * RX_MACRO_COMP_OFFSET); + rx_path_cfg0_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0 + + (comp * RX_MACRO_RX_PATH_OFFSET); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Compander Clock */ + snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); + snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); + snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); + } + + return 0; +} + +static void rx_macro_hd2_control(struct snd_soc_codec *codec, + u16 interp_idx, int event) +{ + u16 hd2_scale_reg = 0; + u16 hd2_enable_reg = 0; + + switch (interp_idx) { + case INTERP_HPHL: + hd2_scale_reg = BOLERO_CDC_RX_RX1_RX_PATH_SEC3; + hd2_enable_reg = BOLERO_CDC_RX_RX1_RX_PATH_CFG0; + break; + case INTERP_HPHR: + hd2_scale_reg = BOLERO_CDC_RX_RX2_RX_PATH_SEC3; + hd2_enable_reg = BOLERO_CDC_RX_RX2_RX_PATH_CFG0; + break; + } + + if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { + snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x14); + snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x04); + } + + if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x00); + snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x00); + } +} + +static int rx_macro_get_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = rx_priv->comp_enabled[comp]; + return 0; +} + +static int rx_macro_set_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int value = ucontrol->value.integer.value[0]; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n", + __func__, comp + 1, rx_priv->comp_enabled[comp], value); + rx_priv->comp_enabled[comp] = value; + + return 0; +} + +static int rx_macro_mux_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = + rx_priv->rx_port_value[widget->shift]; + return 0; +} + +static int rx_macro_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + u32 rx_port_value = ucontrol->value.integer.value[0]; + u32 aif_rst = 0; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + aif_rst = rx_priv->rx_port_value[widget->shift]; + if (!rx_port_value) { + if (aif_rst == 0) { + dev_err(rx_dev, "%s:AIF reset already\n", __func__); + return 0; + } + } + rx_priv->rx_port_value[widget->shift] = rx_port_value; + + switch (rx_port_value) { + case 0: + clear_bit(widget->shift, + &rx_priv->active_ch_mask[aif_rst - 1]); + rx_priv->active_ch_cnt[aif_rst - 1]--; + break; + case 1: + case 2: + case 3: + case 4: + set_bit(widget->shift, + &rx_priv->active_ch_mask[rx_port_value - 1]); + rx_priv->active_ch_cnt[rx_port_value - 1]++; + break; + default: + dev_err(codec->dev, + "%s:Invalid AIF_ID for RX_MACRO MUX\n", __func__); + goto err; + } + + snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, + rx_port_value, e, update); + return 0; +err: + return -EINVAL; +} + +static void rx_macro_idle_detect_control(struct snd_soc_codec *codec, + struct rx_macro_priv *rx_priv, + int interp, int event) +{ + int reg = 0, mask = 0, val = 0; + + if (!rx_priv->idle_det_cfg.hph_idle_detect_en) + return; + + if (interp == INTERP_HPHL) { + reg = BOLERO_CDC_RX_IDLE_DETECT_PATH_CTL; + mask = 0x01; + val = 0x01; + } + if (interp == INTERP_HPHR) { + reg = BOLERO_CDC_RX_IDLE_DETECT_PATH_CTL; + mask = 0x02; + val = 0x02; + } + + if (reg && SND_SOC_DAPM_EVENT_ON(event)) + snd_soc_update_bits(codec, reg, mask, val); + + if (reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, reg, mask, 0x00); + rx_priv->idle_det_cfg.hph_idle_thr = 0; + snd_soc_write(codec, BOLERO_CDC_RX_IDLE_DETECT_CFG3, 0x0); + } +} + +static void rx_macro_hphdelay_lutbypass(struct snd_soc_codec *codec, + struct rx_macro_priv *rx_priv, + u16 interp_idx, int event) +{ + u8 hph_dly_mask = 0; + u16 hph_lut_bypass_reg = 0; + u16 hph_comp_ctrl7 = 0; + + switch (interp_idx) { + case INTERP_HPHL: + hph_dly_mask = 1; + hph_lut_bypass_reg = BOLERO_CDC_RX_TOP_HPHL_COMP_LUT; + hph_comp_ctrl7 = BOLERO_CDC_RX_COMPANDER0_CTL7; + break; + case INTERP_HPHR: + hph_dly_mask = 2; + hph_lut_bypass_reg = BOLERO_CDC_RX_TOP_HPHR_COMP_LUT; + hph_comp_ctrl7 = BOLERO_CDC_RX_COMPANDER1_CTL7; + break; + default: + break; + } + + if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) { + snd_soc_update_bits(codec, BOLERO_CDC_RX_CLSH_TEST0, + hph_dly_mask, 0x0); + snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x80); + } + + if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, BOLERO_CDC_RX_CLSH_TEST0, + hph_dly_mask, hph_dly_mask); + snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x00); + snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x0); + } +} + +static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, + int event, int interp_idx) +{ + u16 main_reg = 0; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!codec) { + pr_err("%s: codec is NULL\n", __func__); + return -EINVAL; + } + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + main_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + + (interp_idx * RX_MACRO_RX_PATH_OFFSET); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + if (rx_priv->main_clk_users[interp_idx] == 0) { + /* Main path PGA mute enable */ + snd_soc_update_bits(codec, main_reg, 0x10, 0x10); + /* Clk enable */ + snd_soc_update_bits(codec, main_reg, 0x20, 0x20); + rx_macro_idle_detect_control(codec, rx_priv, + interp_idx, event); + rx_macro_hd2_control(codec, interp_idx, event); + rx_macro_hphdelay_lutbypass(codec, rx_priv, interp_idx, + event); + rx_macro_config_compander(codec, rx_priv, + interp_idx, event); + } + rx_priv->main_clk_users[interp_idx]++; + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + rx_priv->main_clk_users[interp_idx]--; + if (rx_priv->main_clk_users[interp_idx] <= 0) { + rx_priv->main_clk_users[interp_idx] = 0; + rx_macro_config_compander(codec, rx_priv, + interp_idx, event); + rx_macro_hphdelay_lutbypass(codec, rx_priv, interp_idx, + event); + rx_macro_hd2_control(codec, interp_idx, event); + rx_macro_idle_detect_control(codec, rx_priv, + interp_idx, event); + /* Clk Disable */ + snd_soc_update_bits(codec, main_reg, 0x20, 0x00); + /* Reset enable and disable */ + snd_soc_update_bits(codec, main_reg, 0x40, 0x40); + snd_soc_update_bits(codec, main_reg, 0x40, 0x00); + /* Reset rate to 48K*/ + snd_soc_update_bits(codec, main_reg, 0x0F, 0x04); + } + } + + dev_dbg(codec->dev, "%s event %d main_clk_users %d\n", + __func__, event, rx_priv->main_clk_users[interp_idx]); + + return rx_priv->main_clk_users[interp_idx]; +} + +static int rx_macro_enable_rx_path_clk(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 sidetone_reg = 0; + + dev_dbg(codec->dev, "%s %d %d\n", __func__, event, w->shift); + sidetone_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG1 + + RX_MACRO_RX_PATH_OFFSET * (w->shift); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rx_macro_enable_interp_clk(codec, event, w->shift); + snd_soc_update_bits(codec, sidetone_reg, 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, sidetone_reg, 0x10, 0x00); + rx_macro_enable_interp_clk(codec, event, w->shift); + break; + default: + break; + }; + return 0; +} + +static void rx_macro_restore_iir_coeff(struct rx_macro_priv *rx_priv, int iir_idx, + int band_idx) +{ + u16 reg_add = 0, coeff_idx = 0, idx = 0; + struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL); + + regmap_write(regmap, + (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx), + (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); + + reg_add = BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx; + + /* 5 coefficients per band and 4 writes per coefficient */ + for (coeff_idx = 0; coeff_idx < RX_MACRO_SIDETONE_IIR_COEFF_MAX; + coeff_idx++) { + /* Four 8 bit values(one 32 bit) per coefficient */ + regmap_write(regmap, reg_add, + rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]); + regmap_write(regmap, reg_add, + rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]); + regmap_write(regmap, reg_add, + rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]); + regmap_write(regmap, reg_add, + rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]); + } +} + +static int rx_macro_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + /* IIR filter band registers are at integer multiples of 0x80 */ + u16 iir_reg = BOLERO_CDC_RX_SIDETONE_IIR0_IIR_CTL + 0x80 * iir_idx; + + ucontrol->value.integer.value[0] = (snd_soc_read(codec, iir_reg) & + (1 << band_idx)) != 0; + + dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, + iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[0]); + return 0; +} + +static int rx_macro_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + bool iir_band_en_status = 0; + int value = ucontrol->value.integer.value[0]; + u16 iir_reg = BOLERO_CDC_RX_SIDETONE_IIR0_IIR_CTL + 0x80 * iir_idx; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + rx_macro_restore_iir_coeff(rx_priv, iir_idx, band_idx); + + /* Mask first 5 bits, 6-8 are reserved */ + snd_soc_update_bits(codec, iir_reg, (1 << band_idx), + (value << band_idx)); + + iir_band_en_status = ((snd_soc_read(codec, iir_reg) & + (1 << band_idx)) != 0); + dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, + iir_idx, band_idx, iir_band_en_status); + return 0; +} + +static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec, + int iir_idx, int band_idx, + int coeff_idx) +{ + uint32_t value = 0; + + /* Address does not automatically update if reading */ + snd_soc_write(codec, + (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t)) & 0x7F); + + value |= snd_soc_read(codec, + (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx)); + + snd_soc_write(codec, + (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 1) & 0x7F); + + value |= (snd_soc_read(codec, + (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + + 0x80 * iir_idx)) << 8); + + snd_soc_write(codec, + (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 2) & 0x7F); + + value |= (snd_soc_read(codec, + (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + + 0x80 * iir_idx)) << 16); + + snd_soc_write(codec, + (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 3) & 0x7F); + + /* Mask bits top 2 bits since they are reserved */ + value |= ((snd_soc_read(codec, + (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + + 16 * iir_idx)) & 0x3F) << 24); + + return value; +} + +static int rx_macro_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + ucontrol->value.integer.value[0] = + get_iir_band_coeff(codec, iir_idx, band_idx, 0); + ucontrol->value.integer.value[1] = + get_iir_band_coeff(codec, iir_idx, band_idx, 1); + ucontrol->value.integer.value[2] = + get_iir_band_coeff(codec, iir_idx, band_idx, 2); + ucontrol->value.integer.value[3] = + get_iir_band_coeff(codec, iir_idx, band_idx, 3); + ucontrol->value.integer.value[4] = + get_iir_band_coeff(codec, iir_idx, band_idx, 4); + + dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n" + "%s: IIR #%d band #%d b1 = 0x%x\n" + "%s: IIR #%d band #%d b2 = 0x%x\n" + "%s: IIR #%d band #%d a1 = 0x%x\n" + "%s: IIR #%d band #%d a2 = 0x%x\n", + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[0], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[1], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[2], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[3], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[4]); + return 0; +} + +static void set_iir_band_coeff(struct snd_soc_codec *codec, + int iir_idx, int band_idx, + uint32_t value) +{ + snd_soc_write(codec, + (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx), + (value & 0xFF)); + + snd_soc_write(codec, + (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx), + (value >> 8) & 0xFF); + + snd_soc_write(codec, + (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx), + (value >> 16) & 0xFF); + + /* Mask top 2 bits, 7-8 are reserved */ + snd_soc_write(codec, + (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx), + (value >> 24) & 0x3F); +} + +static int rx_macro_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int coeff_idx, idx = 0; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + /* + * Mask top bit it is reserved + * Updates addr automatically for each B2 write + */ + snd_soc_write(codec, + (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), + (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); + + /* Store the coefficients in sidetone coeff array */ + for (coeff_idx = 0; coeff_idx < RX_MACRO_SIDETONE_IIR_COEFF_MAX; + coeff_idx++) { + uint32_t value = ucontrol->value.integer.value[coeff_idx]; + + set_iir_band_coeff(codec, iir_idx, band_idx, value); + + /* Four 8 bit values(one 32 bit) per coefficient */ + rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] = + (value & 0xFF); + rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] = + (value >> 8) & 0xFF; + rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] = + (value >> 16) & 0xFF; + rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] = + (value >> 24) & 0xFF; + } + + pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n" + "%s: IIR #%d band #%d b1 = 0x%x\n" + "%s: IIR #%d band #%d b2 = 0x%x\n" + "%s: IIR #%d band #%d a1 = 0x%x\n" + "%s: IIR #%d band #%d a2 = 0x%x\n", + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 0), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 1), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 2), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 3), + __func__, iir_idx, band_idx, + get_iir_band_coeff(codec, iir_idx, band_idx, 4)); + return 0; +} + +static int rx_macro_set_iir_gain(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: /* fall through */ + case SND_SOC_DAPM_PRE_PMD: + if (strnstr(w->name, "IIR0", sizeof("IIR0"))) { + snd_soc_write(codec, + BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, + snd_soc_read(codec, + BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL)); + snd_soc_write(codec, + BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, + snd_soc_read(codec, + BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL)); + snd_soc_write(codec, + BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, + snd_soc_read(codec, + BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL)); + snd_soc_write(codec, + BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, + snd_soc_read(codec, + BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL)); + } else { + snd_soc_write(codec, + BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, + snd_soc_read(codec, + BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL)); + snd_soc_write(codec, + BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, + snd_soc_read(codec, + BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL)); + snd_soc_write(codec, + BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, + snd_soc_read(codec, + BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL)); + snd_soc_write(codec, + BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, + snd_soc_read(codec, + BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL)); + } + break; + } + return 0; +} + +static const struct snd_kcontrol_new rx_macro_snd_controls[] = { + SOC_SINGLE_SX_TLV("RX_RX0 Digital Volume", + BOLERO_CDC_RX_RX0_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX_RX1 Digital Volume", + BOLERO_CDC_RX_RX1_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX_RX2 Digital Volume", + BOLERO_CDC_RX_RX2_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX_RX0 Mix Digital Volume", + BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX_RX1 Mix Digital Volume", + BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX_RX2 Mix Digital Volume", + BOLERO_CDC_RX_RX2_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), + + SOC_SINGLE_EXT("RX_COMP1 Switch", SND_SOC_NOPM, RX_MACRO_COMP1, 1, 0, + rx_macro_get_compander, rx_macro_set_compander), + SOC_SINGLE_EXT("RX_COMP2 Switch", SND_SOC_NOPM, RX_MACRO_COMP2, 1, 0, + rx_macro_get_compander, rx_macro_set_compander), + + SOC_SINGLE_SX_TLV("IIR0 INP0 Volume", + BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR0 INP1 Volume", + BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR0 INP2 Volume", + BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR0 INP3 Volume", + BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP0 Volume", + BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP1 Volume", + BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP2 Volume", + BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0, -84, 40, + digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP3 Volume", + BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0, -84, 40, + digital_gain), + + SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0, + rx_macro_iir_enable_audio_mixer_get, + rx_macro_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR0 Enable Band2", IIR0, BAND2, 1, 0, + rx_macro_iir_enable_audio_mixer_get, + rx_macro_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR0 Enable Band3", IIR0, BAND3, 1, 0, + rx_macro_iir_enable_audio_mixer_get, + rx_macro_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR0 Enable Band4", IIR0, BAND4, 1, 0, + rx_macro_iir_enable_audio_mixer_get, + rx_macro_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR0 Enable Band5", IIR0, BAND5, 1, 0, + rx_macro_iir_enable_audio_mixer_get, + rx_macro_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0, + rx_macro_iir_enable_audio_mixer_get, + rx_macro_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0, + rx_macro_iir_enable_audio_mixer_get, + rx_macro_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0, + rx_macro_iir_enable_audio_mixer_get, + rx_macro_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0, + rx_macro_iir_enable_audio_mixer_get, + rx_macro_iir_enable_audio_mixer_put), + SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0, + rx_macro_iir_enable_audio_mixer_get, + rx_macro_iir_enable_audio_mixer_put), + + SOC_SINGLE_MULTI_EXT("IIR0 Band1", IIR0, BAND1, 255, 0, 5, + rx_macro_iir_band_audio_mixer_get, + rx_macro_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR0 Band2", IIR0, BAND2, 255, 0, 5, + rx_macro_iir_band_audio_mixer_get, + rx_macro_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR0 Band3", IIR0, BAND3, 255, 0, 5, + rx_macro_iir_band_audio_mixer_get, + rx_macro_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR0 Band4", IIR0, BAND4, 255, 0, 5, + rx_macro_iir_band_audio_mixer_get, + rx_macro_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR0 Band5", IIR0, BAND5, 255, 0, 5, + rx_macro_iir_band_audio_mixer_get, + rx_macro_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5, + rx_macro_iir_band_audio_mixer_get, + rx_macro_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5, + rx_macro_iir_band_audio_mixer_get, + rx_macro_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5, + rx_macro_iir_band_audio_mixer_get, + rx_macro_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5, + rx_macro_iir_band_audio_mixer_get, + rx_macro_iir_band_audio_mixer_put), + SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5, + rx_macro_iir_band_audio_mixer_get, + rx_macro_iir_band_audio_mixer_put), +}; + +static const struct snd_soc_dapm_widget rx_macro_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN("RX AIF1 PB", "RX_MACRO_AIF1 Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_IN("RX AIF2 PB", "RX_MACRO_AIF2 Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_IN("RX AIF3 PB", "RX_MACRO_AIF3 Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_IN("RX AIF4 PB", "RX_MACRO_AIF4 Playback", 0, + SND_SOC_NOPM, 0, 0), + + RX_MACRO_DAPM_MUX("RX_MACRO RX0 MUX", RX_MACRO_RX0, rx_macro_rx0), + RX_MACRO_DAPM_MUX("RX_MACRO RX1 MUX", RX_MACRO_RX1, rx_macro_rx1), + RX_MACRO_DAPM_MUX("RX_MACRO RX2 MUX", RX_MACRO_RX2, rx_macro_rx2), + RX_MACRO_DAPM_MUX("RX_MACRO RX3 MUX", RX_MACRO_RX3, rx_macro_rx3), + RX_MACRO_DAPM_MUX("RX_MACRO RX4 MUX", RX_MACRO_RX4, rx_macro_rx4), + RX_MACRO_DAPM_MUX("RX_MACRO RX5 MUX", RX_MACRO_RX5, rx_macro_rx5), + + SND_SOC_DAPM_MIXER("RX_RX0", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX_RX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX_RX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX_RX3", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX_RX4", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX_RX5", SND_SOC_NOPM, 0, 0, NULL, 0), + + RX_MACRO_DAPM_MUX("IIR0 INP0 MUX", 0, iir0_inp0), + RX_MACRO_DAPM_MUX("IIR0 INP1 MUX", 0, iir0_inp1), + RX_MACRO_DAPM_MUX("IIR0 INP2 MUX", 0, iir0_inp2), + RX_MACRO_DAPM_MUX("IIR0 INP3 MUX", 0, iir0_inp3), + RX_MACRO_DAPM_MUX("IIR1 INP0 MUX", 0, iir1_inp0), + RX_MACRO_DAPM_MUX("IIR1 INP1 MUX", 0, iir1_inp1), + RX_MACRO_DAPM_MUX("IIR1 INP2 MUX", 0, iir1_inp2), + RX_MACRO_DAPM_MUX("IIR1 INP3 MUX", 0, iir1_inp3), + + SND_SOC_DAPM_MIXER_E("IIR0", BOLERO_CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL, + 4, 0, NULL, 0, rx_macro_set_iir_gain, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_MIXER_E("IIR1", BOLERO_CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL, + 4, 0, NULL, 0, rx_macro_set_iir_gain, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_MIXER("SRC0", BOLERO_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL, + 4, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SRC1", BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL, + 4, 0, NULL, 0), + + RX_MACRO_DAPM_MUX("RX MIX TX0 MUX", 0, rx_mix_tx0), + RX_MACRO_DAPM_MUX("RX MIX TX1 MUX", 0, rx_mix_tx1), + RX_MACRO_DAPM_MUX("RX MIX TX2 MUX", 0, rx_mix_tx2), + RX_MACRO_DAPM_MUX("RX INT0 DEM MUX", 0, rx_int0_dem_inp), + RX_MACRO_DAPM_MUX("RX INT1 DEM MUX", 0, rx_int1_dem_inp), + + SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", SND_SOC_NOPM, INTERP_HPHL, 0, + &rx_int0_2_mux, rx_macro_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", SND_SOC_NOPM, INTERP_HPHR, 0, + &rx_int1_2_mux, rx_macro_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", SND_SOC_NOPM, INTERP_AUX, 0, + &rx_int2_2_mux, rx_macro_enable_mix_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + RX_MACRO_DAPM_MUX("RX INT0_1 MIX1 INP0", 0, rx_int0_1_mix_inp0), + RX_MACRO_DAPM_MUX("RX INT0_1 MIX1 INP1", 0, rx_int0_1_mix_inp1), + RX_MACRO_DAPM_MUX("RX INT0_1 MIX1 INP2", 0, rx_int0_1_mix_inp2), + RX_MACRO_DAPM_MUX("RX INT1_1 MIX1 INP0", 0, rx_int1_1_mix_inp0), + RX_MACRO_DAPM_MUX("RX INT1_1 MIX1 INP1", 0, rx_int1_1_mix_inp1), + RX_MACRO_DAPM_MUX("RX INT1_1 MIX1 INP2", 0, rx_int1_1_mix_inp2), + RX_MACRO_DAPM_MUX("RX INT2_1 MIX1 INP0", 0, rx_int2_1_mix_inp0), + RX_MACRO_DAPM_MUX("RX INT2_1 MIX1 INP1", 0, rx_int2_1_mix_inp1), + RX_MACRO_DAPM_MUX("RX INT2_1 MIX1 INP2", 0, rx_int2_1_mix_inp2), + + SND_SOC_DAPM_MUX_E("RX INT0_1 INTERP", SND_SOC_NOPM, INTERP_HPHL, 0, + &rx_int0_1_interp_mux, rx_macro_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT1_1 INTERP", SND_SOC_NOPM, INTERP_HPHR, 0, + &rx_int1_1_interp_mux, rx_macro_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT2_1 INTERP", SND_SOC_NOPM, INTERP_AUX, 0, + &rx_int2_1_interp_mux, rx_macro_enable_main_path, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + RX_MACRO_DAPM_MUX("RX INT0_2 INTERP", 0, rx_int0_2_interp), + RX_MACRO_DAPM_MUX("RX INT1_2 INTERP", 0, rx_int1_2_interp), + RX_MACRO_DAPM_MUX("RX INT2_2 INTERP", 0, rx_int2_2_interp), + + SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MUX_E("RX INT0 MIX2 INP", SND_SOC_NOPM, INTERP_HPHL, + 0, &rx_int0_mix2_inp_mux, rx_macro_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT1 MIX2 INP", SND_SOC_NOPM, INTERP_HPHR, + 0, &rx_int1_mix2_inp_mux, rx_macro_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT2 MIX2 INP", SND_SOC_NOPM, INTERP_AUX, + 0, &rx_int2_mix2_inp_mux, rx_macro_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_OUTPUT("HPHL_OUT"), + SND_SOC_DAPM_OUTPUT("HPHR_OUT"), + SND_SOC_DAPM_OUTPUT("AUX_OUT"), + + SND_SOC_DAPM_INPUT("RX_TX DEC0_INP"), + SND_SOC_DAPM_INPUT("RX_TX DEC1_INP"), + SND_SOC_DAPM_INPUT("RX_TX DEC2_INP"), + SND_SOC_DAPM_INPUT("RX_TX DEC3_INP"), + + SND_SOC_DAPM_SUPPLY_S("RX_MCLK", 0, SND_SOC_NOPM, 0, 0, + rx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_route rx_audio_map[] = { + {"RX AIF1 PB", NULL, "RX_MCLK"}, + {"RX AIF2 PB", NULL, "RX_MCLK"}, + {"RX AIF3 PB", NULL, "RX_MCLK"}, + {"RX AIF4 PB", NULL, "RX_MCLK"}, + + {"RX_MACRO RX0 MUX", "AIF1_PB", "RX AIF1 PB"}, + {"RX_MACRO RX1 MUX", "AIF1_PB", "RX AIF1 PB"}, + {"RX_MACRO RX2 MUX", "AIF1_PB", "RX AIF1 PB"}, + {"RX_MACRO RX3 MUX", "AIF1_PB", "RX AIF1 PB"}, + {"RX_MACRO RX4 MUX", "AIF1_PB", "RX AIF1 PB"}, + {"RX_MACRO RX5 MUX", "AIF1_PB", "RX AIF1 PB"}, + + {"RX_MACRO RX0 MUX", "AIF2_PB", "RX AIF2 PB"}, + {"RX_MACRO RX1 MUX", "AIF2_PB", "RX AIF2 PB"}, + {"RX_MACRO RX2 MUX", "AIF2_PB", "RX AIF2 PB"}, + {"RX_MACRO RX3 MUX", "AIF2_PB", "RX AIF2 PB"}, + {"RX_MACRO RX4 MUX", "AIF2_PB", "RX AIF2 PB"}, + {"RX_MACRO RX5 MUX", "AIF2_PB", "RX AIF2 PB"}, + + {"RX_MACRO RX0 MUX", "AIF3_PB", "RX AIF3 PB"}, + {"RX_MACRO RX1 MUX", "AIF3_PB", "RX AIF3 PB"}, + {"RX_MACRO RX2 MUX", "AIF3_PB", "RX AIF3 PB"}, + {"RX_MACRO RX3 MUX", "AIF3_PB", "RX AIF3 PB"}, + {"RX_MACRO RX4 MUX", "AIF3_PB", "RX AIF3 PB"}, + {"RX_MACRO RX5 MUX", "AIF3_PB", "RX AIF3 PB"}, + + {"RX_MACRO RX0 MUX", "AIF4_PB", "RX AIF4 PB"}, + {"RX_MACRO RX1 MUX", "AIF4_PB", "RX AIF4 PB"}, + {"RX_MACRO RX2 MUX", "AIF4_PB", "RX AIF4 PB"}, + {"RX_MACRO RX3 MUX", "AIF4_PB", "RX AIF4 PB"}, + {"RX_MACRO RX4 MUX", "AIF4_PB", "RX AIF4 PB"}, + {"RX_MACRO RX5 MUX", "AIF4_PB", "RX AIF4 PB"}, + + {"RX_RX0", NULL, "RX_MACRO RX0 MUX"}, + {"RX_RX1", NULL, "RX_MACRO RX1 MUX"}, + {"RX_RX2", NULL, "RX_MACRO RX2 MUX"}, + {"RX_RX3", NULL, "RX_MACRO RX3 MUX"}, + {"RX_RX4", NULL, "RX_MACRO RX4 MUX"}, + {"RX_RX5", NULL, "RX_MACRO RX5 MUX"}, + + {"RX INT0_1 MIX1 INP0", "RX0", "RX_RX0"}, + {"RX INT0_1 MIX1 INP0", "RX1", "RX_RX1"}, + {"RX INT0_1 MIX1 INP0", "RX2", "RX_RX2"}, + {"RX INT0_1 MIX1 INP0", "RX3", "RX_RX3"}, + {"RX INT0_1 MIX1 INP0", "RX4", "RX_RX4"}, + {"RX INT0_1 MIX1 INP0", "RX5", "RX_RX5"}, + {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT0_1 MIX1 INP1", "RX0", "RX_RX0"}, + {"RX INT0_1 MIX1 INP1", "RX1", "RX_RX1"}, + {"RX INT0_1 MIX1 INP1", "RX2", "RX_RX2"}, + {"RX INT0_1 MIX1 INP1", "RX3", "RX_RX3"}, + {"RX INT0_1 MIX1 INP1", "RX4", "RX_RX4"}, + {"RX INT0_1 MIX1 INP1", "RX5", "RX_RX5"}, + {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT0_1 MIX1 INP2", "RX0", "RX_RX0"}, + {"RX INT0_1 MIX1 INP2", "RX1", "RX_RX1"}, + {"RX INT0_1 MIX1 INP2", "RX2", "RX_RX2"}, + {"RX INT0_1 MIX1 INP2", "RX3", "RX_RX3"}, + {"RX INT0_1 MIX1 INP2", "RX4", "RX_RX4"}, + {"RX INT0_1 MIX1 INP2", "RX5", "RX_RX5"}, + {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT0_1 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX INT1_1 MIX1 INP0", "RX0", "RX_RX0"}, + {"RX INT1_1 MIX1 INP0", "RX1", "RX_RX1"}, + {"RX INT1_1 MIX1 INP0", "RX2", "RX_RX2"}, + {"RX INT1_1 MIX1 INP0", "RX3", "RX_RX3"}, + {"RX INT1_1 MIX1 INP0", "RX4", "RX_RX4"}, + {"RX INT1_1 MIX1 INP0", "RX5", "RX_RX5"}, + {"RX INT1_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT1_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT1_1 MIX1 INP1", "RX0", "RX_RX0"}, + {"RX INT1_1 MIX1 INP1", "RX1", "RX_RX1"}, + {"RX INT1_1 MIX1 INP1", "RX2", "RX_RX2"}, + {"RX INT1_1 MIX1 INP1", "RX3", "RX_RX3"}, + {"RX INT1_1 MIX1 INP1", "RX4", "RX_RX4"}, + {"RX INT1_1 MIX1 INP1", "RX5", "RX_RX5"}, + {"RX INT1_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT1_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT1_1 MIX1 INP2", "RX0", "RX_RX0"}, + {"RX INT1_1 MIX1 INP2", "RX1", "RX_RX1"}, + {"RX INT1_1 MIX1 INP2", "RX2", "RX_RX2"}, + {"RX INT1_1 MIX1 INP2", "RX3", "RX_RX3"}, + {"RX INT1_1 MIX1 INP2", "RX4", "RX_RX4"}, + {"RX INT1_1 MIX1 INP2", "RX5", "RX_RX5"}, + {"RX INT1_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT1_1 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX INT2_1 MIX1 INP0", "RX0", "RX_RX0"}, + {"RX INT2_1 MIX1 INP0", "RX1", "RX_RX1"}, + {"RX INT2_1 MIX1 INP0", "RX2", "RX_RX2"}, + {"RX INT2_1 MIX1 INP0", "RX3", "RX_RX3"}, + {"RX INT2_1 MIX1 INP0", "RX4", "RX_RX4"}, + {"RX INT2_1 MIX1 INP0", "RX5", "RX_RX5"}, + {"RX INT2_1 MIX1 INP0", "IIR0", "IIR0"}, + {"RX INT2_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP1", "RX0", "RX_RX0"}, + {"RX INT2_1 MIX1 INP1", "RX1", "RX_RX1"}, + {"RX INT2_1 MIX1 INP1", "RX2", "RX_RX2"}, + {"RX INT2_1 MIX1 INP1", "RX3", "RX_RX3"}, + {"RX INT2_1 MIX1 INP1", "RX4", "RX_RX4"}, + {"RX INT2_1 MIX1 INP1", "RX5", "RX_RX5"}, + {"RX INT2_1 MIX1 INP1", "IIR0", "IIR0"}, + {"RX INT2_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP2", "RX0", "RX_RX0"}, + {"RX INT2_1 MIX1 INP2", "RX1", "RX_RX1"}, + {"RX INT2_1 MIX1 INP2", "RX2", "RX_RX2"}, + {"RX INT2_1 MIX1 INP2", "RX3", "RX_RX3"}, + {"RX INT2_1 MIX1 INP2", "RX4", "RX_RX4"}, + {"RX INT2_1 MIX1 INP2", "RX5", "RX_RX5"}, + {"RX INT2_1 MIX1 INP2", "IIR0", "IIR0"}, + {"RX INT2_1 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"}, + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"}, + {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"}, + {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP0"}, + {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP1"}, + {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP2"}, + {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP0"}, + {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP1"}, + {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP2"}, + + /* Mixing path INT0 */ + {"RX INT0_2 MUX", "RX0", "RX_RX0"}, + {"RX INT0_2 MUX", "RX1", "RX_RX1"}, + {"RX INT0_2 MUX", "RX2", "RX_RX2"}, + {"RX INT0_2 MUX", "RX3", "RX_RX3"}, + {"RX INT0_2 MUX", "RX4", "RX_RX4"}, + {"RX INT0_2 MUX", "RX5", "RX_RX5"}, + {"RX INT0_2 INTERP", NULL, "RX INT0_2 MUX"}, + {"RX INT0 SEC MIX", NULL, "RX INT0_2 INTERP"}, + + /* Mixing path INT1 */ + {"RX INT1_2 MUX", "RX0", "RX_RX0"}, + {"RX INT1_2 MUX", "RX1", "RX_RX1"}, + {"RX INT1_2 MUX", "RX2", "RX_RX2"}, + {"RX INT1_2 MUX", "RX3", "RX_RX3"}, + {"RX INT1_2 MUX", "RX4", "RX_RX4"}, + {"RX INT1_2 MUX", "RX5", "RX_RX5"}, + {"RX INT1_2 INTERP", NULL, "RX INT1_2 MUX"}, + {"RX INT1 SEC MIX", NULL, "RX INT1_2 INTERP"}, + + /* Mixing path INT2 */ + {"RX INT2_2 MUX", "RX0", "RX_RX0"}, + {"RX INT2_2 MUX", "RX1", "RX_RX1"}, + {"RX INT2_2 MUX", "RX2", "RX_RX2"}, + {"RX INT2_2 MUX", "RX3", "RX_RX3"}, + {"RX INT2_2 MUX", "RX4", "RX_RX4"}, + {"RX INT2_2 MUX", "RX5", "RX_RX5"}, + {"RX INT2_2 INTERP", NULL, "RX INT2_2 MUX"}, + {"RX INT2 SEC MIX", NULL, "RX INT2_2 INTERP"}, + + {"RX INT0_1 INTERP", NULL, "RX INT0_1 MIX1"}, + {"RX INT0 SEC MIX", NULL, "RX INT0_1 INTERP"}, + {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"}, + {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"}, + {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 MIX2"}, + {"HPHL_OUT", NULL, "RX INT0 DEM MUX"}, + + {"RX INT1_1 INTERP", NULL, "RX INT1_1 MIX1"}, + {"RX INT1 SEC MIX", NULL, "RX INT1_1 INTERP"}, + {"RX INT1 MIX2", NULL, "RX INT1 SEC MIX"}, + {"RX INT1 MIX2", NULL, "RX INT1 MIX2 INP"}, + {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 MIX2"}, + {"HPHR_OUT", NULL, "RX INT1 DEM MUX"}, + + {"RX INT2_1 INTERP", NULL, "RX INT2_1 MIX1"}, + {"RX INT2 SEC MIX", NULL, "RX INT2_1 INTERP"}, + {"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"}, + {"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"}, + {"AUX_OUT", NULL, "RX INT2 MIX2"}, + + {"IIR0", NULL, "IIR0 INP0 MUX"}, + {"IIR0 INP0 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR0 INP0 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR0 INP0 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR0 INP0 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR0 INP0 MUX", "RX0", "RX_RX0"}, + {"IIR0 INP0 MUX", "RX1", "RX_RX1"}, + {"IIR0 INP0 MUX", "RX2", "RX_RX2"}, + {"IIR0 INP0 MUX", "RX3", "RX_RX3"}, + {"IIR0 INP0 MUX", "RX4", "RX_RX4"}, + {"IIR0 INP0 MUX", "RX5", "RX_RX5"}, + {"IIR0", NULL, "IIR0 INP1 MUX"}, + {"IIR0 INP1 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR0 INP1 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR0 INP1 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR0 INP1 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR0 INP1 MUX", "RX0", "RX_RX0"}, + {"IIR0 INP1 MUX", "RX1", "RX_RX1"}, + {"IIR0 INP1 MUX", "RX2", "RX_RX2"}, + {"IIR0 INP1 MUX", "RX3", "RX_RX3"}, + {"IIR0 INP1 MUX", "RX4", "RX_RX4"}, + {"IIR0 INP1 MUX", "RX5", "RX_RX5"}, + {"IIR0", NULL, "IIR0 INP2 MUX"}, + {"IIR0 INP2 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR0 INP2 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR0 INP2 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR0 INP2 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR0 INP2 MUX", "RX0", "RX_RX0"}, + {"IIR0 INP2 MUX", "RX1", "RX_RX1"}, + {"IIR0 INP2 MUX", "RX2", "RX_RX2"}, + {"IIR0 INP2 MUX", "RX3", "RX_RX3"}, + {"IIR0 INP2 MUX", "RX4", "RX_RX4"}, + {"IIR0 INP2 MUX", "RX5", "RX_RX5"}, + {"IIR0", NULL, "IIR0 INP3 MUX"}, + {"IIR0 INP3 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR0 INP3 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR0 INP3 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR0 INP3 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR0 INP3 MUX", "RX0", "RX_RX0"}, + {"IIR0 INP3 MUX", "RX1", "RX_RX1"}, + {"IIR0 INP3 MUX", "RX2", "RX_RX2"}, + {"IIR0 INP3 MUX", "RX3", "RX_RX3"}, + {"IIR0 INP3 MUX", "RX4", "RX_RX4"}, + {"IIR0 INP3 MUX", "RX5", "RX_RX5"}, + + {"IIR1", NULL, "IIR1 INP0 MUX"}, + {"IIR1 INP0 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR1 INP0 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR1 INP0 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR1 INP0 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR1 INP0 MUX", "RX0", "RX_RX0"}, + {"IIR1 INP0 MUX", "RX1", "RX_RX1"}, + {"IIR1 INP0 MUX", "RX2", "RX_RX2"}, + {"IIR1 INP0 MUX", "RX3", "RX_RX3"}, + {"IIR1 INP0 MUX", "RX4", "RX_RX4"}, + {"IIR1 INP0 MUX", "RX5", "RX_RX5"}, + {"IIR1", NULL, "IIR1 INP1 MUX"}, + {"IIR1 INP1 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR1 INP1 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR1 INP1 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR1 INP1 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR1 INP1 MUX", "RX0", "RX_RX0"}, + {"IIR1 INP1 MUX", "RX1", "RX_RX1"}, + {"IIR1 INP1 MUX", "RX2", "RX_RX2"}, + {"IIR1 INP1 MUX", "RX3", "RX_RX3"}, + {"IIR1 INP1 MUX", "RX4", "RX_RX4"}, + {"IIR1 INP1 MUX", "RX5", "RX_RX5"}, + {"IIR1", NULL, "IIR1 INP2 MUX"}, + {"IIR1 INP2 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR1 INP2 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR1 INP2 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR1 INP2 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR1 INP2 MUX", "RX0", "RX_RX0"}, + {"IIR1 INP2 MUX", "RX1", "RX_RX1"}, + {"IIR1 INP2 MUX", "RX2", "RX_RX2"}, + {"IIR1 INP2 MUX", "RX3", "RX_RX3"}, + {"IIR1 INP2 MUX", "RX4", "RX_RX4"}, + {"IIR1 INP2 MUX", "RX5", "RX_RX5"}, + {"IIR1", NULL, "IIR1 INP3 MUX"}, + {"IIR1 INP3 MUX", "DEC0", "RX_TX DEC0_INP"}, + {"IIR1 INP3 MUX", "DEC1", "RX_TX DEC1_INP"}, + {"IIR1 INP3 MUX", "DEC2", "RX_TX DEC2_INP"}, + {"IIR1 INP3 MUX", "DEC3", "RX_TX DEC3_INP"}, + {"IIR1 INP3 MUX", "RX0", "RX_RX0"}, + {"IIR1 INP3 MUX", "RX1", "RX_RX1"}, + {"IIR1 INP3 MUX", "RX2", "RX_RX2"}, + {"IIR1 INP3 MUX", "RX3", "RX_RX3"}, + {"IIR1 INP3 MUX", "RX4", "RX_RX4"}, + {"IIR1 INP3 MUX", "RX5", "RX_RX5"}, + + {"SRC0", NULL, "IIR0"}, + {"SRC1", NULL, "IIR1"}, + {"RX INT0 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT0 MIX2 INP", "SRC1", "SRC1"}, + {"RX INT1 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT1 MIX2 INP", "SRC1", "SRC1"}, + {"RX INT2 MIX2 INP", "SRC0", "SRC0"}, + {"RX INT2 MIX2 INP", "SRC1", "SRC1"}, +}; + +static int rx_swrm_clock(void *handle, bool enable) +{ + struct rx_macro_priv *rx_priv = (struct rx_macro_priv *) handle; + struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL); + int ret = 0; + + mutex_lock(&rx_priv->swr_clk_lock); + + dev_dbg(rx_priv->dev, "%s: swrm clock %s\n", + __func__, (enable ? "enable" : "disable")); + if (enable) { + if (rx_priv->swr_clk_users == 0) { + ret = rx_macro_mclk_enable(rx_priv, 1, true); + if (ret < 0) { + dev_err(rx_priv->dev, + "%s: rx request clock enable failed\n", + __func__); + goto exit; + } + regmap_update_bits(regmap, + BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x01); + regmap_update_bits(regmap, + BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, + 0x1C, 0x0C); + msm_cdc_pinctrl_select_active_state( + rx_priv->rx_swr_gpio_p); + } + rx_priv->swr_clk_users++; + } else { + if (rx_priv->swr_clk_users <= 0) { + dev_err(rx_priv->dev, + "%s: rx swrm clock users already reset\n", + __func__); + rx_priv->swr_clk_users = 0; + goto exit; + } + rx_priv->swr_clk_users--; + if (rx_priv->swr_clk_users == 0) { + regmap_update_bits(regmap, + BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x00); + msm_cdc_pinctrl_select_sleep_state( + rx_priv->rx_swr_gpio_p); + rx_macro_mclk_enable(rx_priv, 0, true); + } + } + dev_dbg(rx_priv->dev, "%s: swrm clock users %d\n", + __func__, rx_priv->swr_clk_users); +exit: + mutex_unlock(&rx_priv->swr_clk_lock); + return ret; +} + +static int rx_macro_init(struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + int ret = 0; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + rx_dev = bolero_get_device_ptr(codec->dev, RX_MACRO); + if (!rx_dev) { + dev_err(codec->dev, + "%s: null device for macro!\n", __func__); + return -EINVAL; + } + rx_priv = dev_get_drvdata(rx_dev); + if (!rx_priv) { + dev_err(codec->dev, + "%s: priv is null for macro!\n", __func__); + return -EINVAL; + } + + ret = snd_soc_dapm_new_controls(dapm, rx_macro_dapm_widgets, + ARRAY_SIZE(rx_macro_dapm_widgets)); + if (ret < 0) { + dev_err(rx_dev, "%s: failed to add controls\n", __func__); + return ret; + } + ret = snd_soc_dapm_add_routes(dapm, rx_audio_map, + ARRAY_SIZE(rx_audio_map)); + if (ret < 0) { + dev_err(rx_dev, "%s: failed to add routes\n", __func__); + return ret; + } + ret = snd_soc_dapm_new_widgets(dapm->card); + if (ret < 0) { + dev_err(rx_dev, "%s: failed to add widgets\n", __func__); + return ret; + } + ret = snd_soc_add_codec_controls(codec, rx_macro_snd_controls, + ARRAY_SIZE(rx_macro_snd_controls)); + if (ret < 0) { + dev_err(rx_dev, "%s: failed to add snd_ctls\n", __func__); + return ret; + } + + rx_priv->codec = codec; + + return 0; +} + +static int rx_macro_deinit(struct snd_soc_codec *codec) +{ + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + rx_priv->codec = NULL; + + return 0; +} + +static void rx_macro_add_child_devices(struct work_struct *work) +{ + struct rx_macro_priv *rx_priv = NULL; + struct platform_device *pdev = NULL; + struct device_node *node = NULL; + struct rx_swr_ctrl_data *swr_ctrl_data = NULL, *temp = NULL; + int ret = 0; + u16 count = 0, ctrl_num = 0; + struct rx_swr_ctrl_platform_data *platdata = NULL; + char plat_dev_name[RX_SWR_STRING_LEN] = ""; + bool rx_swr_master_node = false; + + rx_priv = container_of(work, struct rx_macro_priv, + rx_macro_add_child_devices_work); + if (!rx_priv) { + pr_err("%s: Memory for rx_priv does not exist\n", + __func__); + return; + } + + if (!rx_priv->dev) { + pr_err("%s: RX device does not exist\n", __func__); + return; + } + + if(!rx_priv->dev->of_node) { + dev_err(rx_priv->dev, + "%s: DT node for RX dev does not exist\n", __func__); + return; + } + + platdata = &rx_priv->swr_plat_data; + rx_priv->child_count = 0; + + for_each_available_child_of_node(rx_priv->dev->of_node, node) { + rx_swr_master_node = false; + if (strnstr(node->name, "rx_swr_master", + strlen("rx_swr_master")) != NULL) + rx_swr_master_node = true; + + if(rx_swr_master_node) + strlcpy(plat_dev_name, "rx_swr_ctrl", + (RX_SWR_STRING_LEN - 1)); + else + strlcpy(plat_dev_name, node->name, + (RX_SWR_STRING_LEN - 1)); + + pdev = platform_device_alloc(plat_dev_name, -1); + if (!pdev) { + dev_err(rx_priv->dev, "%s: pdev memory alloc failed\n", + __func__); + ret = -ENOMEM; + goto err; + } + pdev->dev.parent = rx_priv->dev; + pdev->dev.of_node = node; + + if (rx_swr_master_node) { + ret = platform_device_add_data(pdev, platdata, + sizeof(*platdata)); + if (ret) { + dev_err(&pdev->dev, + "%s: cannot add plat data ctrl:%d\n", + __func__, ctrl_num); + goto fail_pdev_add; + } + } + + ret = platform_device_add(pdev); + if (ret) { + dev_err(&pdev->dev, + "%s: Cannot add platform device\n", + __func__); + goto fail_pdev_add; + } + + if (rx_swr_master_node) { + temp = krealloc(swr_ctrl_data, + (ctrl_num + 1) * sizeof( + struct rx_swr_ctrl_data), + GFP_KERNEL); + if (!temp) { + ret = -ENOMEM; + goto fail_pdev_add; + } + swr_ctrl_data = temp; + swr_ctrl_data[ctrl_num].rx_swr_pdev = pdev; + ctrl_num++; + dev_dbg(&pdev->dev, + "%s: Added soundwire ctrl device(s)\n", + __func__); + rx_priv->swr_ctrl_data = swr_ctrl_data; + } + if (rx_priv->child_count < RX_MACRO_CHILD_DEVICES_MAX) + rx_priv->pdev_child_devices[ + rx_priv->child_count++] = pdev; + else + goto err; + } + return; +fail_pdev_add: + for (count = 0; count < rx_priv->child_count; count++) + platform_device_put(rx_priv->pdev_child_devices[count]); +err: + return; +} + +static void rx_macro_init_ops(struct macro_ops *ops, char __iomem *rx_io_base) +{ + memset(ops, 0, sizeof(struct macro_ops)); + ops->init = rx_macro_init; + ops->exit = rx_macro_deinit; + ops->io_base = rx_io_base; + ops->dai_ptr = rx_macro_dai; + ops->num_dais = ARRAY_SIZE(rx_macro_dai); + ops->mclk_fn = rx_macro_mclk_ctrl; +} + +static int rx_macro_probe(struct platform_device *pdev) +{ + struct macro_ops ops = {0}; + struct rx_macro_priv *rx_priv = NULL; + u32 rx_base_addr = 0, muxsel = 0; + char __iomem *rx_io_base = NULL, *muxsel_io = NULL; + int ret = 0; + struct clk *rx_core_clk = NULL, *rx_npl_clk = NULL; + + rx_priv = devm_kzalloc(&pdev->dev, sizeof(struct rx_macro_priv), + GFP_KERNEL); + if (!rx_priv) + return -ENOMEM; + + rx_priv->dev = &pdev->dev; + ret = of_property_read_u32(pdev->dev.of_node, "reg", + &rx_base_addr); + if (ret) { + dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "reg"); + return ret; + } + ret = of_property_read_u32(pdev->dev.of_node, "qcom,rx_mclk_mode_muxsel", + &muxsel); + if (ret) { + dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "reg"); + return ret; + } + rx_priv->rx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,rx-swr-gpios", 0); + if (!rx_priv->rx_swr_gpio_p) { + dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n", + __func__); + return -EINVAL; + } + rx_io_base = devm_ioremap(&pdev->dev, rx_base_addr, + RX_MACRO_MAX_OFFSET); + if (!rx_io_base) { + dev_err(&pdev->dev, "%s: ioremap failed\n", __func__); + return -ENOMEM; + } + rx_priv->rx_io_base = rx_io_base; + muxsel_io = devm_ioremap(&pdev->dev, muxsel, 0x4); + if (!muxsel_io) { + dev_err(&pdev->dev, "%s: ioremap failed for muxsel\n", + __func__); + return -ENOMEM; + } + rx_priv->rx_mclk_mode_muxsel = muxsel_io; + INIT_WORK(&rx_priv->rx_macro_add_child_devices_work, + rx_macro_add_child_devices); + rx_priv->swr_plat_data.handle = (void *) rx_priv; + rx_priv->swr_plat_data.read = NULL; + rx_priv->swr_plat_data.write = NULL; + rx_priv->swr_plat_data.bulk_write = NULL; + rx_priv->swr_plat_data.clk = rx_swrm_clock; + rx_priv->swr_plat_data.handle_irq = NULL; + + /* Register MCLK for rx macro */ + rx_core_clk = devm_clk_get(&pdev->dev, "rx_core_clk"); + if (IS_ERR(rx_core_clk)) { + ret = PTR_ERR(rx_core_clk); + dev_err(&pdev->dev, "%s: clk get %s failed %d\n", + __func__, "rx_core_clk", ret); + return ret; + } + rx_priv->rx_core_clk = rx_core_clk; + /* Register npl clk for soundwire */ + rx_npl_clk = devm_clk_get(&pdev->dev, "rx_npl_clk"); + if (IS_ERR(rx_npl_clk)) { + ret = PTR_ERR(rx_npl_clk); + dev_err(&pdev->dev, "%s: clk get %s failed %d\n", + __func__, "rx_npl_clk", ret); + return ret; + } + rx_priv->rx_npl_clk = rx_npl_clk; + dev_set_drvdata(&pdev->dev, rx_priv); + mutex_init(&rx_priv->mclk_lock); + mutex_init(&rx_priv->swr_clk_lock); + rx_macro_init_ops(&ops, rx_io_base); + + ret = bolero_register_macro(&pdev->dev, RX_MACRO, &ops); + if (ret) { + dev_err(&pdev->dev, + "%s: register macro failed\n", __func__); + goto err_reg_macro; + } + schedule_work(&rx_priv->rx_macro_add_child_devices_work); + + return 0; + +err_reg_macro: + mutex_destroy(&rx_priv->mclk_lock); + mutex_destroy(&rx_priv->swr_clk_lock); + return ret; +} + +static int rx_macro_remove(struct platform_device *pdev) +{ + struct rx_macro_priv *rx_priv = NULL; + u16 count = 0; + + rx_priv = dev_get_drvdata(&pdev->dev); + + if (!rx_priv) + return -EINVAL; + + for (count = 0; count < rx_priv->child_count && + count < RX_MACRO_CHILD_DEVICES_MAX; count++) + platform_device_unregister(rx_priv->pdev_child_devices[count]); + + bolero_unregister_macro(&pdev->dev, RX_MACRO); + mutex_destroy(&rx_priv->mclk_lock); + mutex_destroy(&rx_priv->swr_clk_lock); + kfree(rx_priv->swr_ctrl_data); + return 0; +} + +static const struct of_device_id rx_macro_dt_match[] = { + {.compatible = "qcom,rx-macro"}, + {} +}; + +static struct platform_driver rx_macro_driver = { + .driver = { + .name = "rx_macro", + .owner = THIS_MODULE, + .of_match_table = rx_macro_dt_match, + }, + .probe = rx_macro_probe, + .remove = rx_macro_remove, +}; + +module_platform_driver(rx_macro_driver); + +MODULE_DESCRIPTION("RX macro driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From bee0819ac7ba35ec077cb898e949a24f24652837 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Sun, 1 Jul 2018 14:38:55 +0530 Subject: [PATCH 0418/1645] asoc: bolero: Add mclk switching support for rx-macro RX macro supports both native and non-native family sample rates. Add changes to support both family frequencies. As soundwire is active for few seconds after teardown of a session and say next session is of different family(native) which needs switching the clock at soundwire before configure native MCLK frequency. Change-Id: I7f6652f1569cfeef5075d92bfd2beadc203b7036 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 60 +++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index d5071279f53f..449b73e4d97c 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -227,6 +227,8 @@ struct rx_macro_priv { int rx_mclk_users; int swr_clk_users; int rx_mclk_cnt; + bool is_native_on; + u16 mclk_mux; struct mutex mclk_lock; struct mutex swr_clk_lock; struct rx_swr_ctrl_data *swr_ctrl_data; @@ -307,6 +309,10 @@ static const char *const rx_macro_mux_text[] = { "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB" }; +static const char *const rx_macro_native_text[] = {"OFF", "ON"}; +static const struct soc_enum rx_macro_native_enum = + SOC_ENUM_SINGLE_EXT(2, rx_macro_native_text); + RX_MACRO_DAPM_ENUM(rx_int0_2, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, rx_int_mix_mux_text); RX_MACRO_DAPM_ENUM(rx_int1_2, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, @@ -730,22 +736,25 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, bool mclk_enable, bool dapm) { struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL); - int ret = 0; + int ret = 0, mclk_mux = MCLK_MUX0; dev_dbg(rx_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", __func__, mclk_enable, dapm, rx_priv->rx_mclk_users); + if(rx_priv->is_native_on) + mclk_mux = MCLK_MUX1; mutex_lock(&rx_priv->mclk_lock); if (mclk_enable) { if (rx_priv->rx_mclk_users == 0) { ret = bolero_request_clock(rx_priv->dev, - RX_MACRO, MCLK_MUX0, true); + RX_MACRO, mclk_mux, true); if (ret < 0) { dev_err(rx_priv->dev, "%s: rx request clock enable failed\n", __func__); goto exit; } + rx_priv->mclk_mux = mclk_mux; regcache_mark_dirty(regmap); regcache_sync_region(regmap, RX_START_OFFSET, @@ -774,7 +783,8 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x00); bolero_request_clock(rx_priv->dev, - RX_MACRO, MCLK_MUX0, false); + RX_MACRO, mclk_mux, false); + rx_priv->mclk_mux = MCLK_MUX0; } } exit: @@ -796,6 +806,17 @@ static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w, dev_dbg(rx_dev, "%s: event = %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: + /* if swr_clk_users > 0, call device down */ + if (rx_priv->swr_clk_users > 0) { + if ((rx_priv->mclk_mux == MCLK_MUX0 && + rx_priv->is_native_on) || + (rx_priv->mclk_mux == MCLK_MUX1 && + !rx_priv->is_native_on)) { + swrm_wcd_notify( + rx_priv->swr_ctrl_data[0].rx_swr_pdev, + SWR_DEVICE_DOWN, NULL); + } + } ret = rx_macro_mclk_enable(rx_priv, 1, true); break; case SND_SOC_DAPM_POST_PMD: @@ -1227,6 +1248,36 @@ static int rx_macro_mux_put(struct snd_kcontrol *kcontrol, return -EINVAL; } +static int rx_macro_get_native(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = + (rx_priv->is_native_on == true ? 1 : 0); + return 0; +} + +static int rx_macro_put_native(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + rx_priv->is_native_on = + (!ucontrol->value.integer.value[0] ? false : true); + return 0; +} + static void rx_macro_idle_detect_control(struct snd_soc_codec *codec, struct rx_macro_priv *rx_priv, int interp, int event) @@ -1695,6 +1746,9 @@ static const struct snd_kcontrol_new rx_macro_snd_controls[] = { SOC_SINGLE_EXT("RX_COMP2 Switch", SND_SOC_NOPM, RX_MACRO_COMP2, 1, 0, rx_macro_get_compander, rx_macro_set_compander), + SOC_ENUM_EXT("RX_Native", rx_macro_native_enum, rx_macro_get_native, + rx_macro_put_native), + SOC_SINGLE_SX_TLV("IIR0 INP0 Volume", BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40, digital_gain), -- GitLab From f8ef43ea45cc88b168f91361e1ab0fca5edbb0fb Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 15 Jun 2018 16:57:46 +0530 Subject: [PATCH 0419/1645] asoc: codecs: Add compile rules for RX/TX macro modules Add compile rules for RX and TX macro drivers. Change-Id: Icede86ab2f1e75e3b10f445cf01e204647a48471 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/Android.mk | 82 +++++++++++++++++++++++++++++++++++ asoc/codecs/bolero/Kbuild | 14 ++++++ 2 files changed, 96 insertions(+) create mode 100644 asoc/codecs/bolero/Android.mk diff --git a/asoc/codecs/bolero/Android.mk b/asoc/codecs/bolero/Android.mk new file mode 100644 index 000000000000..7b28789535c0 --- /dev/null +++ b/asoc/codecs/bolero/Android.mk @@ -0,0 +1,82 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE)),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=bolero_cdc_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_bolero_cdc.ko +LOCAL_MODULE_KBUILD_NAME := bolero_cdc_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_wsa_macro.ko +LOCAL_MODULE_KBUILD_NAME := wsa_macro_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_va_macro.ko +LOCAL_MODULE_KBUILD_NAME := va_macro_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_tx_macro.ko +LOCAL_MODULE_KBUILD_NAME := tx_macro_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_rx_macro.ko +LOCAL_MODULE_KBUILD_NAME := rx_macro_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild index 57f561a7e2ff..dee3463a2459 100644 --- a/asoc/codecs/bolero/Kbuild +++ b/asoc/codecs/bolero/Kbuild @@ -70,6 +70,14 @@ ifdef CONFIG_VA_MACRO VA_OBJS += va-macro.o endif +ifdef CONFIG_TX_MACRO + TX_OBJS += tx-macro.o +endif + +ifdef CONFIG_RX_MACRO + RX_OBJS += rx-macro.o +endif + LINUX_INC += -Iinclude/linux INCS += $(COMMON_INC) \ @@ -121,5 +129,11 @@ wsa_macro_dlkm-y := $(WSA_OBJS) obj-$(CONFIG_VA_MACRO) += va_macro_dlkm.o va_macro_dlkm-y := $(VA_OBJS) +obj-$(CONFIG_TX_MACRO) += tx_macro_dlkm.o +tx_macro_dlkm-y := $(TX_OBJS) + +obj-$(CONFIG_RX_MACRO) += rx_macro_dlkm.o +rx_macro_dlkm-y := $(RX_OBJS) + # inject some build related information DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" -- GitLab From 07b8dc90a9633c53ae5e237fd9db5731086d4657 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Mon, 16 Jul 2018 19:46:25 +0530 Subject: [PATCH 0420/1645] asoc: Update mixer control for island mode setting Fix overwriting of port ID in island mode mixer control. Change-Id: Ibf650e94519ffde7655e14a88ccc9042b3a3544b Signed-off-by: Mangesh Kunchamwar --- asoc/msm-dai-q6-v2.c | 57 +++++++++++++++++++++++++----------------- dsp/q6afe.c | 26 +++++++++++++++++++ include/dsp/q6afe-v2.h | 1 + 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 2c1eea17ff4a..529f0df9bb2a 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -206,7 +206,6 @@ struct msm_dai_q6_dai_data { u16 afe_in_bitformat; struct afe_enc_config enc_config; struct afe_dec_config dec_config; - u32 island_enable; union afe_port_config port_config; u16 vi_feed_mono; }; @@ -1131,36 +1130,32 @@ static int msm_dai_q6_dai_auxpcm_remove(struct snd_soc_dai *dai) static int msm_dai_q6_island_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; int value = ucontrol->value.integer.value[0]; - u16 port_id = ((struct soc_enum *) kcontrol->private_value)->reg; + u16 port_id = (u16)kcontrol->private_value; - dai_data->island_enable = value; pr_debug("%s: island mode = %d\n", __func__, value); - afe_set_island_mode_cfg(port_id, dai_data->island_enable); + afe_set_island_mode_cfg(port_id, value); return 0; } static int msm_dai_q6_island_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + int value; + u16 port_id = (u16)kcontrol->private_value; - ucontrol->value.integer.value[0] = dai_data->island_enable; + afe_get_island_mode_cfg(port_id, &value); + ucontrol->value.integer.value[0] = value; return 0; } -static struct snd_kcontrol_new island_config_controls[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "?", - .info = snd_ctl_boolean_mono_info, - .get = msm_dai_q6_island_mode_get, - .put = msm_dai_q6_island_mode_put, - .private_value = SOC_SINGLE_VALUE(0, 0, 1, 0, 0) - }, -}; +static void island_mx_ctl_private_free(struct snd_kcontrol *kcontrol) +{ + struct snd_kcontrol_new *knew = snd_kcontrol_chip(kcontrol); + + kfree(knew); +} static int msm_dai_q6_add_island_mx_ctls(struct snd_card *card, const char *dai_name, @@ -1170,6 +1165,8 @@ static int msm_dai_q6_add_island_mx_ctls(struct snd_card *card, char *mixer_str = NULL; int dai_str_len = 0, ctl_len = 0; int rc = 0; + struct snd_kcontrol_new *knew = NULL; + struct snd_kcontrol *kctl = NULL; dai_str_len = strlen(dai_name) + 1; @@ -1180,12 +1177,26 @@ static int msm_dai_q6_add_island_mx_ctls(struct snd_card *card, return -ENOMEM; snprintf(mixer_str, ctl_len, "%s %s", dai_name, mx_ctl_name); - island_config_controls[0].name = mixer_str; - ((struct soc_enum *) island_config_controls[0].private_value)->reg - = dai_id; - rc = snd_ctl_add(card, - snd_ctl_new1(&island_config_controls[0], - dai_data)); + + knew = kzalloc(sizeof(struct snd_kcontrol_new), GFP_KERNEL); + if (!knew) { + kfree(mixer_str); + return -ENOMEM; + } + knew->iface = SNDRV_CTL_ELEM_IFACE_MIXER; + knew->info = snd_ctl_boolean_mono_info; + knew->get = msm_dai_q6_island_mode_get; + knew->put = msm_dai_q6_island_mode_put; + knew->name = mixer_str; + knew->private_value = dai_id; + kctl = snd_ctl_new1(knew, knew); + if (!kctl) { + kfree(knew); + kfree(mixer_str); + return -ENOMEM; + } + kctl->private_free = island_mx_ctl_private_free; + rc = snd_ctl_add(card, kctl); if (rc < 0) pr_err("%s: err add config ctl, DAI = %s\n", __func__, dai_name); diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 03fbdb76dc19..53a9c9beed08 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -3048,6 +3048,25 @@ void afe_set_vad_cfg(u32 vad_enable, u32 preroll_config, } EXPORT_SYMBOL(afe_set_vad_cfg); +/** + * afe_get_island_mode_cfg - + * get island mode configuration + * + * @port_id: AFE port id number + * @enable_flag: Enable or Disable + * + */ +void afe_get_island_mode_cfg(u16 port_id, u32 *enable_flag) +{ + uint16_t port_index; + + if (enable_flag) { + port_index = afe_get_port_index(port_id); + *enable_flag = this_afe.island_mode[port_index]; + } +} +EXPORT_SYMBOL(afe_get_island_mode_cfg); + /** * afe_set_island_mode_cfg - * set island mode configuration @@ -6239,6 +6258,13 @@ int afe_validate_port(u16 port_id) case AFE_PORT_ID_INT4_MI2S_TX: case AFE_PORT_ID_INT5_MI2S_TX: case AFE_PORT_ID_INT6_MI2S_TX: + case AFE_PORT_ID_WSA_CODEC_DMA_RX_0: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_0: + case AFE_PORT_ID_WSA_CODEC_DMA_RX_1: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_1: + case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: + case AFE_PORT_ID_VA_CODEC_DMA_TX_0: + case AFE_PORT_ID_VA_CODEC_DMA_TX_1: { ret = 0; break; diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index e39d0b89d578..f94ede4b7927 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -342,6 +342,7 @@ void afe_set_cal_mode(u16 port_id, enum afe_cal_mode afe_cal_mode); void afe_set_vad_cfg(u32 vad_enable, u32 preroll_config, u32 port_id); void afe_set_island_mode_cfg(u16 port_id, u32 enable_flag); +void afe_get_island_mode_cfg(u16 port_id, u32 *enable_flag); int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate); int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, -- GitLab From 07c6d1cd5f72de8376f89d2edf265a75f82f12d4 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Thu, 5 Jul 2018 10:39:25 -0700 Subject: [PATCH 0421/1645] asoc: add multimedia21 frontend and routing support Add multimedia21 frontend dai as well as capture and playback routing support from/to AUXPCM and TDM interfaces. CRs-fixed: 2273671 Change-Id: I5c1e3a2a549015636f7160c3cfc3f15420c9727c Signed-off-by: Derek Chen --- asoc/msm-dai-fe.c | 33 ++++++ asoc/msm-pcm-routing-v2.c | 237 ++++++++++++++++++++++++++++++++++++++ asoc/msm-pcm-routing-v2.h | 1 + 3 files changed, 271 insertions(+) diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index a711a25e20c3..c352cb379cb4 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -2611,6 +2611,39 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "MultiMedia20", .probe = fe_dai_probe, }, + { + .playback = { + .stream_name = "MultiMedia21 Playback", + .aif_name = "MM_DL21", + .rates = (SNDRV_PCM_RATE_8000_384000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "MultiMedia21 Capture", + .aif_name = "MM_UL21", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .name = "MultiMedia21", + .probe = fe_dai_probe, + }, { .capture = { .stream_name = "MultiMedia28 Capture", diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index bda838718855..e3a884d25418 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -667,6 +667,9 @@ static struct msm_pcm_routing_fdai_data {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, /* MULTIMEDIA20 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA21 */ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, /* MULTIMEDIA28 */ @@ -6210,6 +6213,10 @@ static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = { MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -6297,6 +6304,10 @@ static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = { MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -6572,6 +6583,10 @@ static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = { @@ -6639,6 +6654,10 @@ static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = { @@ -6706,6 +6725,10 @@ static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = { @@ -6773,6 +6796,10 @@ static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_tx_0_mixer_controls[] = { @@ -6907,6 +6934,10 @@ static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = { @@ -6974,6 +7005,10 @@ static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = { @@ -7041,6 +7076,10 @@ static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = { @@ -7108,6 +7147,10 @@ static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_tx_0_mixer_controls[] = { @@ -7242,6 +7285,10 @@ static const struct snd_kcontrol_new tert_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_tx_0_mixer_controls[] = { @@ -7376,6 +7423,10 @@ static const struct snd_kcontrol_new tert_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = { @@ -7443,6 +7494,10 @@ static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = { @@ -7510,6 +7565,10 @@ static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = { @@ -7577,6 +7636,10 @@ static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = { @@ -7648,6 +7711,10 @@ static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_tx_0_mixer_controls[] = { @@ -7786,6 +7853,10 @@ static const struct snd_kcontrol_new quat_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = { @@ -7857,6 +7928,10 @@ static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = { @@ -7928,6 +8003,10 @@ static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_0_mixer_controls[] = { @@ -7999,6 +8078,10 @@ static const struct snd_kcontrol_new quin_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_tx_0_mixer_controls[] = { @@ -8137,6 +8220,10 @@ static const struct snd_kcontrol_new quin_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = { @@ -8208,6 +8295,10 @@ static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = { @@ -8279,6 +8370,10 @@ static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul1_mixer_controls[] = { @@ -10140,6 +10235,97 @@ static const struct snd_kcontrol_new mmul20_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul21_mixer_controls[] = { + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, @@ -15730,6 +15916,7 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_IN("MM_DL15", "MultiMedia15 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("MM_DL16", "MultiMedia16 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("MM_DL20", "MultiMedia20 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL21", "MultiMedia21 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0), @@ -15745,6 +15932,7 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("MM_UL18", "MultiMedia18 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL19", "MultiMedia19 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL20", "MultiMedia20 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL21", "MultiMedia21 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL28", "MultiMedia28 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL29", "MultiMedia29 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0), @@ -16635,6 +16823,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { mmul19_mixer_controls, ARRAY_SIZE(mmul19_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia20 Mixer", SND_SOC_NOPM, 0, 0, mmul20_mixer_controls, ARRAY_SIZE(mmul20_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia21 Mixer", SND_SOC_NOPM, 0, 0, + mmul21_mixer_controls, ARRAY_SIZE(mmul21_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia28 Mixer", SND_SOC_NOPM, 0, 0, mmul28_mixer_controls, ARRAY_SIZE(mmul28_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia29 Mixer", SND_SOC_NOPM, 0, 0, @@ -17477,6 +17667,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Audio Mixer"}, {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17495,6 +17686,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Audio Mixer"}, {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17513,6 +17705,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Audio Mixer"}, {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17531,6 +17724,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Audio Mixer"}, {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17567,6 +17761,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Audio Mixer"}, {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17585,6 +17780,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Audio Mixer"}, {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17603,6 +17799,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Audio Mixer"}, {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17621,6 +17818,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Audio Mixer"}, {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17657,6 +17855,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Audio Mixer"}, {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17693,6 +17892,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Audio Mixer"}, {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17711,6 +17911,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Audio Mixer"}, {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17729,6 +17930,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Audio Mixer"}, {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17747,6 +17949,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"TERT_TDM_RX_4", NULL, "TERT_TDM_RX_4 Audio Mixer"}, {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17766,6 +17969,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Audio Mixer"}, {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17803,6 +18007,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Audio Mixer"}, {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17822,6 +18027,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Audio Mixer"}, {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17841,6 +18047,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Audio Mixer"}, {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17860,6 +18067,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0 Audio Mixer"}, {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17897,6 +18105,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1 Audio Mixer"}, {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17916,6 +18125,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2 Audio Mixer"}, {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -17935,6 +18145,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Audio Mixer"}, {"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"}, @@ -18253,6 +18464,29 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia21 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"MultiMedia21 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia21 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia21 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia21 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia21 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia21 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia21 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia21 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia21 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia21 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia21 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia21 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia21 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia21 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia21 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia21 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia21 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia21 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia21 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia21 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia21 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia4 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, @@ -18410,6 +18644,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL18", NULL, "MultiMedia18 Mixer"}, {"MM_UL19", NULL, "MultiMedia19 Mixer"}, {"MM_UL20", NULL, "MultiMedia20 Mixer"}, + {"MM_UL21", NULL, "MultiMedia21 Mixer"}, {"MM_UL28", NULL, "MultiMedia28 Mixer"}, {"MM_UL29", NULL, "MultiMedia29 Mixer"}, @@ -18429,6 +18664,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia21", "MM_DL21"}, {"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"}, {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -18447,6 +18683,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia21", "MM_DL21"}, {"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX Audio Mixer"}, {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index b8006bc13e6c..d3dee0ed6f86 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -222,6 +222,7 @@ enum { MSM_FRONTEND_DAI_MULTIMEDIA18, MSM_FRONTEND_DAI_MULTIMEDIA19, MSM_FRONTEND_DAI_MULTIMEDIA20, + MSM_FRONTEND_DAI_MULTIMEDIA21, MSM_FRONTEND_DAI_MULTIMEDIA28, MSM_FRONTEND_DAI_MULTIMEDIA29, MSM_FRONTEND_DAI_VOIP, -- GitLab From 1e84a93ac41c58146c39bb28c06f0ef29cc95945 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 18 Jun 2018 19:40:08 +0530 Subject: [PATCH 0422/1645] asoc: msm: routing: Add support for Rx and Tx codec dma interfaces New codec dma interfaces have been introduced to connect LPASS and Codec macros. This change is to add support routing for RX and TX codec dma interface backends and their corresponding front ends. CRs-Fixed: 2281591 Change-Id: I625c66352c61176cd82b801e97e9d565919e2715 Signed-off-by: Aditya Bavanari --- asoc/msm-pcm-routing-v2.c | 1667 ++++++++++++++++++++++++++++++++++++- asoc/msm-pcm-routing-v2.h | 28 + 2 files changed, 1691 insertions(+), 4 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 7ad7460368a8..84f98e78a518 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -602,6 +602,34 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_VA_CDC_DMA_TX_0}, { AFE_PORT_ID_VA_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_VA_CDC_DMA_TX_1}, + { AFE_PORT_ID_RX_CODEC_DMA_RX_0, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_RX_CDC_DMA_RX_0}, + { AFE_PORT_ID_TX_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TX_CDC_DMA_TX_0}, + { AFE_PORT_ID_RX_CODEC_DMA_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_RX_CDC_DMA_RX_1}, + { AFE_PORT_ID_TX_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TX_CDC_DMA_TX_1}, + { AFE_PORT_ID_RX_CODEC_DMA_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_RX_CDC_DMA_RX_2}, + { AFE_PORT_ID_TX_CODEC_DMA_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TX_CDC_DMA_TX_2}, + { AFE_PORT_ID_RX_CODEC_DMA_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_RX_CDC_DMA_RX_3}, + { AFE_PORT_ID_TX_CODEC_DMA_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TX_CDC_DMA_TX_3}, + { AFE_PORT_ID_RX_CODEC_DMA_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_RX_CDC_DMA_RX_4}, + { AFE_PORT_ID_TX_CODEC_DMA_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TX_CDC_DMA_TX_4}, + { AFE_PORT_ID_RX_CODEC_DMA_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_RX_CDC_DMA_RX_5}, + { AFE_PORT_ID_TX_CODEC_DMA_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TX_CDC_DMA_TX_5}, + { AFE_PORT_ID_RX_CODEC_DMA_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_RX_CDC_DMA_RX_6}, + { AFE_PORT_ID_RX_CODEC_DMA_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_RX_CDC_DMA_RX_7}, { AFE_PORT_ID_PRIMARY_SPDIF_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_PRI_SPDIF_TX}, { AFE_PORT_ID_SECONDARY_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, @@ -3038,7 +3066,11 @@ static const char *const be_name[] = { "INT6_MI2S_RX", "INT6_MI2S_TX", "WSA_CDC_DMA_RX_0", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_RX_1", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_1", -"PRI_SPDIF_TX", "SEC_SPDIF_RX", "SEC_SPDIF_TX" +"RX_CDC_DMA_RX_0", "TX_CDC_DMA_TX_0", "RX_CDC_DMA_RX_1", "TX_CDC_DMA_TX_1", +"RX_CDC_DMA_RX_2", "TX_CDC_DMA_TX_2", "RX_CDC_DMA_RX_3", "TX_CDC_DMA_TX_3", +"RX_CDC_DMA_RX_4", "TX_CDC_DMA_TX_4", "RX_CDC_DMA_RX_5", "TX_CDC_DMA_TX_5", +"RX_CDC_DMA_RX_6", "RX_CDC_DMA_RX_7", +"PRI_SPDIF_TX", "SEC_SPDIF_RX", "SEC_SPDIF_TX", }; static SOC_ENUM_SINGLE_DECL(mm1_channel_mux, @@ -3846,6 +3878,26 @@ static int msm_routing_ec_ref_rx_put(struct snd_kcontrol *kcontrol, msm_route_ec_ref_rx = 29; ec_ref_port_id = SLIMBUS_7_RX; break; + case 30: + msm_route_ec_ref_rx = 30; + ec_ref_port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_0; + break; + case 31: + msm_route_ec_ref_rx = 31; + ec_ref_port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_1; + break; + case 32: + msm_route_ec_ref_rx = 32; + ec_ref_port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_2; + break; + case 33: + msm_route_ec_ref_rx = 33; + ec_ref_port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_3; + break; + case 34: + msm_route_ec_ref_rx = 34; + ec_ref_port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_0; + break; default: msm_route_ec_ref_rx = 0; /* NONE */ pr_err("%s EC ref rx %ld not valid\n", @@ -3871,7 +3923,8 @@ static const char *const ec_ref_rx[] = { "None", "SLIM_RX", "I2S_RX", "INT0_MI2S_RX", "INT4_MI2S_RX", "INT3_MI2S_TX", "DISPLAY_PORT", "WSA_CDC_DMA_RX_0", "WSA_CDC_DMA_RX_1", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_2", - "SLIM_7_RX" + "SLIM_7_RX", "RX_CDC_DMA_RX_0", "RX_CDC_DMA_RX_1", "RX_CDC_DMA_RX_2", + "RX_CDC_DMA_RX_3", "TX_CDC_DMA_TX_0", }; static const struct soc_enum msm_route_ec_ref_rx_enum[] = { @@ -5767,6 +5820,542 @@ static const struct snd_kcontrol_new wsa_cdc_dma_rx_1_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new rx_cdc_dma_rx_0_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_1_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_2_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_3_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_4_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_5_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_6_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_7_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new slimbus_7_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_7_RX, @@ -8578,6 +9167,30 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, @@ -8745,6 +9358,30 @@ static const struct snd_kcontrol_new mmul2_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, @@ -8912,6 +9549,30 @@ static const struct snd_kcontrol_new mmul3_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, @@ -9075,6 +9736,30 @@ static const struct snd_kcontrol_new mmul4_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, @@ -9262,6 +9947,30 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, @@ -9429,6 +10138,30 @@ static const struct snd_kcontrol_new mmul6_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, @@ -9600,6 +10333,30 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, @@ -9771,6 +10528,36 @@ static const struct snd_kcontrol_new mmul16_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, @@ -9882,6 +10669,30 @@ static const struct snd_kcontrol_new mmul9_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, @@ -10017,6 +10828,36 @@ static const struct snd_kcontrol_new mmul10_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, @@ -10087,6 +10928,36 @@ static const struct snd_kcontrol_new mmul17_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, @@ -10162,6 +11033,36 @@ static const struct snd_kcontrol_new mmul18_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, @@ -10233,6 +11134,36 @@ static const struct snd_kcontrol_new mmul19_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, @@ -10364,6 +11295,36 @@ static const struct snd_kcontrol_new mmul20_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, @@ -10435,6 +11396,36 @@ static const struct snd_kcontrol_new mmul28_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -10506,6 +11497,36 @@ static const struct snd_kcontrol_new mmul29_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, @@ -11136,6 +12157,190 @@ static const struct snd_kcontrol_new wsa_cdc_dma_rx_1_voice_mixer_controls[] = { msm_routing_put_voice_mixer), }; +static const struct snd_kcontrol_new rx_cdc_dma_rx_0_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_1_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_2_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_3_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_4_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_5_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_6_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_7_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + static const struct snd_kcontrol_new stub_rx_mixer_controls[] = { SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_EXTPROC_RX, @@ -11230,6 +12435,24 @@ MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { @@ -11289,6 +12512,24 @@ static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { @@ -11362,6 +12603,24 @@ static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_Voip", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { @@ -11449,6 +12708,30 @@ static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), }; static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = { @@ -11520,6 +12803,30 @@ static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), }; static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = { @@ -11591,7 +12898,30 @@ static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), }; static const struct snd_kcontrol_new tx_qchat_mixer_controls[] = { @@ -11665,6 +12995,24 @@ static const struct snd_kcontrol_new tx_qchat_mixer_controls[] = { SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_QCHAT", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new int0_mi2s_rx_port_mixer_controls[] = { @@ -16605,6 +17953,34 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("VA_CDC_DMA_TX_1", "VA CDC DMA1 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("RX_CDC_DMA_RX_0", "RX CDC DMA0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TX_CDC_DMA_TX_0", "TX CDC DMA0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("RX_CDC_DMA_RX_1", "RX CDC DMA1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TX_CDC_DMA_TX_1", "TX CDC DMA1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("RX_CDC_DMA_RX_2", "RX CDC DMA2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TX_CDC_DMA_TX_2", "TX CDC DMA2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("RX_CDC_DMA_RX_3", "RX CDC DMA3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TX_CDC_DMA_TX_3", "TX CDC DMA3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("RX_CDC_DMA_RX_4", "RX CDC DMA4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TX_CDC_DMA_TX_4", "TX CDC DMA4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("RX_CDC_DMA_RX_5", "RX CDC DMA5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TX_CDC_DMA_TX_5", "TX CDC DMA5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("RX_CDC_DMA_RX_6", "RX CDC DMA6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("RX_CDC_DMA_RX_7", "RX CDC DMA7 Playback", + 0, 0, 0, 0), /* incall */ SND_SOC_DAPM_AIF_OUT("VOICE_PLAYBACK_TX", "Voice Farend Playback", 0, 0, 0, 0), @@ -16844,6 +18220,30 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, wsa_cdc_dma_rx_1_mixer_controls, ARRAY_SIZE(wsa_cdc_dma_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_0_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_1_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_2_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_3_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_4_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_4_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_5 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_5_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_5_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_6 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_6_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_6_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_7 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_7_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_7_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0, mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0, @@ -17367,6 +18767,150 @@ static const struct snd_soc_dapm_route intercon[] = { {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"WSA_CDC_DMA_RX_1", NULL, "WSA_CDC_DMA_RX_1 Audio Mixer"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0 Audio Mixer"}, + + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1 Audio Mixer"}, + + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_2", NULL, "RX_CDC_DMA_RX_2 Audio Mixer"}, + + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_3", NULL, "RX_CDC_DMA_RX_3 Audio Mixer"}, + + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_4", NULL, "RX_CDC_DMA_RX_4 Audio Mixer"}, + + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_5", NULL, "RX_CDC_DMA_RX_5 Audio Mixer"}, + + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_6", NULL, "RX_CDC_DMA_RX_6 Audio Mixer"}, + + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_7", NULL, "RX_CDC_DMA_RX_7 Audio Mixer"}, + {"HDMI Mixer", "MultiMedia1", "MM_DL1"}, {"HDMI Mixer", "MultiMedia2", "MM_DL2"}, {"HDMI Mixer", "MultiMedia3", "MM_DL3"}, @@ -18295,6 +19839,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia1 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia1 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, @@ -18323,6 +19873,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia2 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia2 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, @@ -18351,6 +19907,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia3 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia3 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, @@ -18379,6 +19941,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia4 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia4 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, @@ -18407,6 +19975,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia5 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia5 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, @@ -18435,6 +20009,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia6 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia6 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, @@ -18464,6 +20044,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia8 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia8 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, @@ -18485,6 +20071,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia9 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia9 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, @@ -18496,6 +20088,13 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia10 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia10 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia10 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia20 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia20 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"MultiMedia20 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, @@ -18527,6 +20126,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia20 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia20 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, @@ -18561,9 +20166,50 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia16 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia16 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, @@ -20100,6 +21746,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "QUIN_TDM_RX_3"}, {"BE_OUT", NULL, "WSA_CDC_DMA_RX_0"}, {"BE_OUT", NULL, "WSA_CDC_DMA_RX_1"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_0"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_1"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_2"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_3"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_4"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_5"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_6"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_7"}, {"PRI_I2S_TX", NULL, "BE_IN"}, {"MI2S_TX", NULL, "BE_IN"}, @@ -20177,9 +21831,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"WSA_CDC_DMA_TX_2", NULL, "BE_IN"}, {"VA_CDC_DMA_TX_0", NULL, "BE_IN"}, {"VA_CDC_DMA_TX_1", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_0", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_1", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_2", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_3", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_4", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_5", NULL, "BE_IN"}, {"PRI_SPDIF_TX", NULL, "BE_IN"}, {"SEC_SPDIF_TX", NULL, "BE_IN"}, - }; static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 2a786af79eb1..fe40b77f9d2a 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -197,6 +197,20 @@ #define LPASS_BE_VA_CDC_DMA_TX_0 "VA_CDC_DMA_TX_0" #define LPASS_BE_VA_CDC_DMA_TX_1 "VA_CDC_DMA_TX_1" +#define LPASS_BE_RX_CDC_DMA_RX_0 "RX_CDC_DMA_RX_0" +#define LPASS_BE_RX_CDC_DMA_RX_1 "RX_CDC_DMA_RX_1" +#define LPASS_BE_RX_CDC_DMA_RX_2 "RX_CDC_DMA_RX_2" +#define LPASS_BE_RX_CDC_DMA_RX_3 "RX_CDC_DMA_RX_3" +#define LPASS_BE_RX_CDC_DMA_RX_4 "RX_CDC_DMA_RX_4" +#define LPASS_BE_RX_CDC_DMA_RX_5 "RX_CDC_DMA_RX_5" +#define LPASS_BE_RX_CDC_DMA_RX_6 "RX_CDC_DMA_RX_6" +#define LPASS_BE_RX_CDC_DMA_RX_7 "RX_CDC_DMA_RX_7" +#define LPASS_BE_TX_CDC_DMA_TX_0 "TX_CDC_DMA_TX_0" +#define LPASS_BE_TX_CDC_DMA_TX_1 "TX_CDC_DMA_TX_1" +#define LPASS_BE_TX_CDC_DMA_TX_2 "TX_CDC_DMA_TX_2" +#define LPASS_BE_TX_CDC_DMA_TX_3 "TX_CDC_DMA_TX_3" +#define LPASS_BE_TX_CDC_DMA_TX_4 "TX_CDC_DMA_TX_4" +#define LPASS_BE_TX_CDC_DMA_TX_5 "TX_CDC_DMA_TX_5" /* For multimedia front-ends, asm session is allocated dynamically. * Hence, asm session/multimedia front-end mapping has to be maintained. @@ -419,6 +433,20 @@ enum { MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_BACKEND_DAI_SEC_SPDIF_TX, -- GitLab From 348a4a6d2a09ecc6252a99d493b4d93437e8ff1a Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 16 May 2018 21:48:45 +0530 Subject: [PATCH 0423/1645] dsp: afe: Add support for Rx and TX codec dma interface New codec dma interfaces have been introduced to connect LPASS and Codec macros. This change is to add Rx and Tx codec dma interface related updates to Q6 AFE native driver. CRs-Fixed: 2281591 Change-Id: I2edbe904cd4c13801f06cdd7bd226a82db5d6d51 Signed-off-by: Aditya Bavanari --- dsp/q6afe.c | 42 +++++++++++++++++++ dsp/q6audio-v2.c | 84 ++++++++++++++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 42 +++++++++++++++++++ include/dsp/q6afe-v2.h | 18 +++++++- 4 files changed, 184 insertions(+), 2 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 47102f442a4f..0549d612fb47 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -836,6 +836,20 @@ int afe_sizeof_cfg_cmd(u16 port_id) case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: case AFE_PORT_ID_VA_CODEC_DMA_TX_0: case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + case AFE_PORT_ID_RX_CODEC_DMA_RX_0: + case AFE_PORT_ID_TX_CODEC_DMA_TX_0: + case AFE_PORT_ID_RX_CODEC_DMA_RX_1: + case AFE_PORT_ID_TX_CODEC_DMA_TX_1: + case AFE_PORT_ID_RX_CODEC_DMA_RX_2: + case AFE_PORT_ID_TX_CODEC_DMA_TX_2: + case AFE_PORT_ID_RX_CODEC_DMA_RX_3: + case AFE_PORT_ID_TX_CODEC_DMA_TX_3: + case AFE_PORT_ID_RX_CODEC_DMA_RX_4: + case AFE_PORT_ID_TX_CODEC_DMA_TX_4: + case AFE_PORT_ID_RX_CODEC_DMA_RX_5: + case AFE_PORT_ID_TX_CODEC_DMA_TX_5: + case AFE_PORT_ID_RX_CODEC_DMA_RX_6: + case AFE_PORT_ID_RX_CODEC_DMA_RX_7: ret_size = SIZEOF_CFG_CMD(afe_param_id_cdc_dma_cfg_t); break; case AFE_PORT_ID_PRIMARY_PCM_RX: @@ -3965,6 +3979,20 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: case AFE_PORT_ID_VA_CODEC_DMA_TX_0: case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + case AFE_PORT_ID_RX_CODEC_DMA_RX_0: + case AFE_PORT_ID_TX_CODEC_DMA_TX_0: + case AFE_PORT_ID_RX_CODEC_DMA_RX_1: + case AFE_PORT_ID_TX_CODEC_DMA_TX_1: + case AFE_PORT_ID_RX_CODEC_DMA_RX_2: + case AFE_PORT_ID_TX_CODEC_DMA_TX_2: + case AFE_PORT_ID_RX_CODEC_DMA_RX_3: + case AFE_PORT_ID_TX_CODEC_DMA_TX_3: + case AFE_PORT_ID_RX_CODEC_DMA_RX_4: + case AFE_PORT_ID_TX_CODEC_DMA_TX_4: + case AFE_PORT_ID_RX_CODEC_DMA_RX_5: + case AFE_PORT_ID_TX_CODEC_DMA_TX_5: + case AFE_PORT_ID_RX_CODEC_DMA_RX_6: + case AFE_PORT_ID_RX_CODEC_DMA_RX_7: cfg_type = AFE_PARAM_ID_CODEC_DMA_CONFIG; break; default: @@ -4556,6 +4584,20 @@ int afe_open(u16 port_id, case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: case AFE_PORT_ID_VA_CODEC_DMA_TX_0: case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + case AFE_PORT_ID_RX_CODEC_DMA_RX_0: + case AFE_PORT_ID_TX_CODEC_DMA_TX_0: + case AFE_PORT_ID_RX_CODEC_DMA_RX_1: + case AFE_PORT_ID_TX_CODEC_DMA_TX_1: + case AFE_PORT_ID_RX_CODEC_DMA_RX_2: + case AFE_PORT_ID_TX_CODEC_DMA_TX_2: + case AFE_PORT_ID_RX_CODEC_DMA_RX_3: + case AFE_PORT_ID_TX_CODEC_DMA_TX_3: + case AFE_PORT_ID_RX_CODEC_DMA_RX_4: + case AFE_PORT_ID_TX_CODEC_DMA_TX_4: + case AFE_PORT_ID_RX_CODEC_DMA_RX_5: + case AFE_PORT_ID_TX_CODEC_DMA_TX_5: + case AFE_PORT_ID_RX_CODEC_DMA_RX_6: + case AFE_PORT_ID_RX_CODEC_DMA_RX_7: cfg_type = AFE_PARAM_ID_CODEC_DMA_CONFIG; break; default: diff --git a/dsp/q6audio-v2.c b/dsp/q6audio-v2.c index b48c9b69cf55..00732f3d75be 100644 --- a/dsp/q6audio-v2.c +++ b/dsp/q6audio-v2.c @@ -318,6 +318,34 @@ int q6audio_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_0; case AFE_PORT_ID_VA_CODEC_DMA_TX_1: return IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_1; + case AFE_PORT_ID_RX_CODEC_DMA_RX_0: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_0; + case AFE_PORT_ID_TX_CODEC_DMA_TX_0: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_0; + case AFE_PORT_ID_RX_CODEC_DMA_RX_1: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_1; + case AFE_PORT_ID_TX_CODEC_DMA_TX_1: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_1; + case AFE_PORT_ID_RX_CODEC_DMA_RX_2: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_2; + case AFE_PORT_ID_TX_CODEC_DMA_TX_2: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_2; + case AFE_PORT_ID_RX_CODEC_DMA_RX_3: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_3; + case AFE_PORT_ID_TX_CODEC_DMA_TX_3: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_3; + case AFE_PORT_ID_RX_CODEC_DMA_RX_4: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_4; + case AFE_PORT_ID_TX_CODEC_DMA_TX_4: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_4; + case AFE_PORT_ID_RX_CODEC_DMA_RX_5: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_5; + case AFE_PORT_ID_TX_CODEC_DMA_TX_5: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_5; + case AFE_PORT_ID_RX_CODEC_DMA_RX_6: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_6; + case AFE_PORT_ID_RX_CODEC_DMA_RX_7: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_7; default: return -EINVAL; } } @@ -626,6 +654,34 @@ int q6audio_get_port_id(u16 port_id) return AFE_PORT_ID_VA_CODEC_DMA_TX_0; case AFE_PORT_ID_VA_CODEC_DMA_TX_1: return AFE_PORT_ID_VA_CODEC_DMA_TX_1; + case AFE_PORT_ID_RX_CODEC_DMA_RX_0: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_0; + case AFE_PORT_ID_TX_CODEC_DMA_TX_0: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_0; + case AFE_PORT_ID_RX_CODEC_DMA_RX_1: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_1; + case AFE_PORT_ID_TX_CODEC_DMA_TX_1: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_1; + case AFE_PORT_ID_RX_CODEC_DMA_RX_2: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_2; + case AFE_PORT_ID_TX_CODEC_DMA_TX_2: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_2; + case AFE_PORT_ID_RX_CODEC_DMA_RX_3: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_3; + case AFE_PORT_ID_TX_CODEC_DMA_TX_3: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_3; + case AFE_PORT_ID_RX_CODEC_DMA_RX_4: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_4; + case AFE_PORT_ID_TX_CODEC_DMA_TX_4: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_4; + case AFE_PORT_ID_RX_CODEC_DMA_RX_5: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_5; + case AFE_PORT_ID_TX_CODEC_DMA_TX_5: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_5; + case AFE_PORT_ID_RX_CODEC_DMA_RX_6: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_6; + case AFE_PORT_ID_RX_CODEC_DMA_RX_7: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_7; default: pr_warn("%s: Invalid port_id %d\n", __func__, port_id); return -EINVAL; @@ -787,6 +843,20 @@ int q6audio_is_digital_pcm_interface(u16 port_id) case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: case AFE_PORT_ID_VA_CODEC_DMA_TX_0: case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + case AFE_PORT_ID_RX_CODEC_DMA_RX_0: + case AFE_PORT_ID_TX_CODEC_DMA_TX_0: + case AFE_PORT_ID_RX_CODEC_DMA_RX_1: + case AFE_PORT_ID_TX_CODEC_DMA_TX_1: + case AFE_PORT_ID_RX_CODEC_DMA_RX_2: + case AFE_PORT_ID_TX_CODEC_DMA_TX_2: + case AFE_PORT_ID_RX_CODEC_DMA_RX_3: + case AFE_PORT_ID_TX_CODEC_DMA_TX_3: + case AFE_PORT_ID_RX_CODEC_DMA_RX_4: + case AFE_PORT_ID_TX_CODEC_DMA_TX_4: + case AFE_PORT_ID_RX_CODEC_DMA_RX_5: + case AFE_PORT_ID_TX_CODEC_DMA_TX_5: + case AFE_PORT_ID_RX_CODEC_DMA_RX_6: + case AFE_PORT_ID_RX_CODEC_DMA_RX_7: case AFE_PORT_ID_PRIMARY_SPDIF_RX: case AFE_PORT_ID_PRIMARY_SPDIF_TX: case AFE_PORT_ID_SECONDARY_SPDIF_RX: @@ -981,6 +1051,20 @@ int q6audio_validate_port(u16 port_id) case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: case AFE_PORT_ID_VA_CODEC_DMA_TX_0: case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + case AFE_PORT_ID_RX_CODEC_DMA_RX_0: + case AFE_PORT_ID_TX_CODEC_DMA_TX_0: + case AFE_PORT_ID_RX_CODEC_DMA_RX_1: + case AFE_PORT_ID_TX_CODEC_DMA_TX_1: + case AFE_PORT_ID_RX_CODEC_DMA_RX_2: + case AFE_PORT_ID_TX_CODEC_DMA_TX_2: + case AFE_PORT_ID_RX_CODEC_DMA_RX_3: + case AFE_PORT_ID_TX_CODEC_DMA_TX_3: + case AFE_PORT_ID_RX_CODEC_DMA_RX_4: + case AFE_PORT_ID_TX_CODEC_DMA_TX_4: + case AFE_PORT_ID_RX_CODEC_DMA_RX_5: + case AFE_PORT_ID_TX_CODEC_DMA_TX_5: + case AFE_PORT_ID_RX_CODEC_DMA_RX_6: + case AFE_PORT_ID_RX_CODEC_DMA_RX_7: { ret = 0; break; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index b9ae3f55843e..f4e1f7696636 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1311,6 +1311,48 @@ struct adm_cmd_connect_afe_port_v5 { /* AFE VA Codec DMA Tx port 1 */ #define AFE_PORT_ID_VA_CODEC_DMA_TX_1 0xB023 +/* AFE Rx Codec DMA Rx port 0 */ +#define AFE_PORT_ID_RX_CODEC_DMA_RX_0 0xB030 + +/* AFE Tx Codec DMA Tx port 0 */ +#define AFE_PORT_ID_TX_CODEC_DMA_TX_0 0xB031 + +/* AFE Rx Codec DMA Rx port 1 */ +#define AFE_PORT_ID_RX_CODEC_DMA_RX_1 0xB032 + +/* AFE Tx Codec DMA Tx port 1 */ +#define AFE_PORT_ID_TX_CODEC_DMA_TX_1 0xB033 + +/* AFE Rx Codec DMA Rx port 2 */ +#define AFE_PORT_ID_RX_CODEC_DMA_RX_2 0xB034 + +/* AFE Tx Codec DMA Tx port 2 */ +#define AFE_PORT_ID_TX_CODEC_DMA_TX_2 0xB035 + +/* AFE Rx Codec DMA Rx port 3 */ +#define AFE_PORT_ID_RX_CODEC_DMA_RX_3 0xB036 + +/* AFE Tx Codec DMA Tx port 3 */ +#define AFE_PORT_ID_TX_CODEC_DMA_TX_3 0xB037 + +/* AFE Rx Codec DMA Rx port 4 */ +#define AFE_PORT_ID_RX_CODEC_DMA_RX_4 0xB038 + +/* AFE Tx Codec DMA Tx port 4 */ +#define AFE_PORT_ID_TX_CODEC_DMA_TX_4 0xB039 + +/* AFE Rx Codec DMA Rx port 5 */ +#define AFE_PORT_ID_RX_CODEC_DMA_RX_5 0xB03A + +/* AFE Tx Codec DMA Tx port 5 */ +#define AFE_PORT_ID_TX_CODEC_DMA_TX_5 0xB03B + +/* AFE Rx Codec DMA Rx port 6 */ +#define AFE_PORT_ID_RX_CODEC_DMA_RX_6 0xB03C + +/* AFE Rx Codec DMA Rx port 7 */ +#define AFE_PORT_ID_RX_CODEC_DMA_RX_7 0xB03E + /* Generic pseudoport 1. */ #define AFE_PORT_ID_PSEUDOPORT_01 0x8001 /* Generic pseudoport 2. */ diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 930682836f32..a0074b49739b 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -229,7 +229,7 @@ enum { IDX_AFE_PORT_ID_QUINARY_TDM_TX_6, IDX_AFE_PORT_ID_QUINARY_TDM_RX_7, IDX_AFE_PORT_ID_QUINARY_TDM_TX_7, - /* IDX 161 to 167 */ + /* IDX 161 to 181 */ IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_0, IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_0, IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_1, @@ -237,7 +237,21 @@ enum { IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_2, IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_0, IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_1, - /* IDX 168 to 170 */ + IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_0, + IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_0, + IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_1, + IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_1, + IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_2, + IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_2, + IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_3, + IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_3, + IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_4, + IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_4, + IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_5, + IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_5, + IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_6, + IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_7, + /* IDX 182 to 185 */ IDX_SECONDARY_SPDIF_RX, IDX_PRIMARY_SPDIF_TX, IDX_SECONDARY_SPDIF_TX, -- GitLab From e90adf0fe7b9690f12ad46f4c70c35426c455818 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 16 May 2018 22:10:34 +0530 Subject: [PATCH 0424/1645] asoc: Add support for Rx and Tx codec dma interface New codec dma interfaces have been introduced to connect LPASS and Codec macros. Add playback and capture DAIs for Rx and Tx codec. CRs-Fixed: 2281591 Change-Id: I26ba49660d62accb96ea7b063e00b35917dfbdca Signed-off-by: Aditya Bavanari --- asoc/msm-dai-q6-v2.c | 364 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 363 insertions(+), 1 deletion(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index ec6807a7964f..7f305cf52f78 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -9680,6 +9680,14 @@ static int msm_dai_q6_cdc_dma_set_channel_map(struct snd_soc_dai *dai, switch (dai->id) { case AFE_PORT_ID_WSA_CODEC_DMA_RX_0: case AFE_PORT_ID_WSA_CODEC_DMA_RX_1: + case AFE_PORT_ID_RX_CODEC_DMA_RX_0: + case AFE_PORT_ID_RX_CODEC_DMA_RX_1: + case AFE_PORT_ID_RX_CODEC_DMA_RX_2: + case AFE_PORT_ID_RX_CODEC_DMA_RX_3: + case AFE_PORT_ID_RX_CODEC_DMA_RX_4: + case AFE_PORT_ID_RX_CODEC_DMA_RX_5: + case AFE_PORT_ID_RX_CODEC_DMA_RX_6: + case AFE_PORT_ID_RX_CODEC_DMA_RX_7: if (!rx_ch_mask) { dev_err(dai->dev, "%s: invalid rx ch mask\n", __func__); return -EINVAL; @@ -9697,6 +9705,12 @@ static int msm_dai_q6_cdc_dma_set_channel_map(struct snd_soc_dai *dai, case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: case AFE_PORT_ID_VA_CODEC_DMA_TX_0: case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + case AFE_PORT_ID_TX_CODEC_DMA_TX_0: + case AFE_PORT_ID_TX_CODEC_DMA_TX_1: + case AFE_PORT_ID_TX_CODEC_DMA_TX_2: + case AFE_PORT_ID_TX_CODEC_DMA_TX_3: + case AFE_PORT_ID_TX_CODEC_DMA_TX_4: + case AFE_PORT_ID_TX_CODEC_DMA_TX_5: if (!tx_ch_mask) { dev_err(dai->dev, "%s: invalid tx ch mask\n", __func__); return -EINVAL; @@ -10006,7 +10020,355 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { .probe = msm_dai_q6_dai_cdc_dma_probe, .remove = msm_dai_q6_dai_cdc_dma_remove, }, - + { + .playback = { + .stream_name = "RX CDC DMA0 Playback", + .aif_name = "RX_CDC_DMA_RX_0", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_RX_CODEC_DMA_RX_0, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .capture = { + .stream_name = "TX CDC DMA0 Capture", + .aif_name = "TX_CDC_DMA_TX_0", + .rates = SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 3, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_TX_CODEC_DMA_TX_0, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .playback = { + .stream_name = "RX CDC DMA1 Playback", + .aif_name = "RX_CDC_DMA_RX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_RX_CODEC_DMA_RX_1, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .capture = { + .stream_name = "TX CDC DMA1 Capture", + .aif_name = "TX_CDC_DMA_TX_1", + .rates = SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 3, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_TX_CODEC_DMA_TX_1, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .playback = { + .stream_name = "RX CDC DMA2 Playback", + .aif_name = "RX_CDC_DMA_RX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 1, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_RX_CODEC_DMA_RX_2, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .capture = { + .stream_name = "TX CDC DMA2 Capture", + .aif_name = "TX_CDC_DMA_TX_2", + .rates = SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 4, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_TX_CODEC_DMA_TX_2, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, { + .playback = { + .stream_name = "RX CDC DMA3 Playback", + .aif_name = "RX_CDC_DMA_RX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 1, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_RX_CODEC_DMA_RX_3, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .capture = { + .stream_name = "TX CDC DMA3 Capture", + .aif_name = "TX_CDC_DMA_TX_3", + .rates = SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_TX_CODEC_DMA_TX_3, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .playback = { + .stream_name = "RX CDC DMA4 Playback", + .aif_name = "RX_CDC_DMA_RX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 6, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_RX_CODEC_DMA_RX_4, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .capture = { + .stream_name = "TX CDC DMA4 Capture", + .aif_name = "TX_CDC_DMA_TX_4", + .rates = SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_TX_CODEC_DMA_TX_4, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .playback = { + .stream_name = "RX CDC DMA5 Playback", + .aif_name = "RX_CDC_DMA_RX_5", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 1, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_RX_CODEC_DMA_RX_5, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .capture = { + .stream_name = "TX CDC DMA5 Capture", + .aif_name = "TX_CDC_DMA_TX_5", + .rates = SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 4, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_TX_CODEC_DMA_TX_5, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .playback = { + .stream_name = "RX CDC DMA6 Playback", + .aif_name = "RX_CDC_DMA_RX_6", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 4, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_RX_CODEC_DMA_RX_6, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, + { + .playback = { + .stream_name = "RX CDC DMA7 Playback", + .aif_name = "RX_CDC_DMA_RX_7", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_RX_CODEC_DMA_RX_7, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, }; static const struct snd_soc_component_driver msm_q6_cdc_dma_dai_component = { -- GitLab From 44eb89512ef5ee569b327c7994b2e88d26c1f348 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 9 May 2018 19:01:50 +0530 Subject: [PATCH 0425/1645] asoc: sm6150: Add machine driver support for SM6150 Add DAI(Digital Audio Interface) links, WSA, VA, Rx, Tx macros and external codec (tavil) configuration to support audio functionality on SM6150. Change-Id: Ic4be86b3e675c80bd02a029fe92f3141824d5073 Signed-off-by: Aditya Bavanari --- asoc/sm6150.c | 8332 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 8332 insertions(+) create mode 100644 asoc/sm6150.c diff --git a/asoc/sm6150.c b/asoc/sm6150.c new file mode 100644 index 000000000000..de76951a1295 --- /dev/null +++ b/asoc/sm6150.c @@ -0,0 +1,8332 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "device_event.h" +#include "msm-pcm-routing-v2.h" +#include "codecs/msm-cdc-pinctrl.h" +#include "codecs/wcd934x/wcd934x.h" +#include "codecs/wcd934x/wcd934x-mbhc.h" +#include "codecs/wsa881x.h" +#include "codecs/bolero/bolero-cdc.h" +#include + +#define DRV_NAME "sm6150-asoc-snd" + +#define __CHIPSET__ "SM6150 " +#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) + +#define SAMPLING_RATE_8KHZ 8000 +#define SAMPLING_RATE_11P025KHZ 11025 +#define SAMPLING_RATE_16KHZ 16000 +#define SAMPLING_RATE_22P05KHZ 22050 +#define SAMPLING_RATE_32KHZ 32000 +#define SAMPLING_RATE_44P1KHZ 44100 +#define SAMPLING_RATE_48KHZ 48000 +#define SAMPLING_RATE_88P2KHZ 88200 +#define SAMPLING_RATE_96KHZ 96000 +#define SAMPLING_RATE_176P4KHZ 176400 +#define SAMPLING_RATE_192KHZ 192000 +#define SAMPLING_RATE_352P8KHZ 352800 +#define SAMPLING_RATE_384KHZ 384000 + +#define WCD9XXX_MBHC_DEF_BUTTONS 8 +#define WCD9XXX_MBHC_DEF_RLOADS 5 +#define CODEC_EXT_CLK_RATE 9600000 +#define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define DEV_NAME_STR_LEN 32 + +#define WSA8810_NAME_1 "wsa881x.20170211" +#define WSA8810_NAME_2 "wsa881x.20170212" +#define WCN_CDC_SLIM_RX_CH_MAX 2 +#define WCN_CDC_SLIM_TX_CH_MAX 3 +#define TDM_CHANNEL_MAX 8 + +#define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ +#define MSM_HIFI_ON 1 + +enum { + SLIM_RX_0 = 0, + SLIM_RX_1, + SLIM_RX_2, + SLIM_RX_3, + SLIM_RX_4, + SLIM_RX_5, + SLIM_RX_6, + SLIM_RX_7, + SLIM_RX_MAX, +}; +enum { + SLIM_TX_0 = 0, + SLIM_TX_1, + SLIM_TX_2, + SLIM_TX_3, + SLIM_TX_4, + SLIM_TX_5, + SLIM_TX_6, + SLIM_TX_7, + SLIM_TX_8, + SLIM_TX_MAX, +}; + +enum { + PRIM_MI2S = 0, + SEC_MI2S, + TERT_MI2S, + QUAT_MI2S, + QUIN_MI2S, + MI2S_MAX, +}; + +enum { + PRIM_AUX_PCM = 0, + SEC_AUX_PCM, + TERT_AUX_PCM, + QUAT_AUX_PCM, + QUIN_AUX_PCM, + AUX_PCM_MAX, +}; + +enum { + WSA_CDC_DMA_RX_0 = 0, + WSA_CDC_DMA_RX_1, + RX_CDC_DMA_RX_0, + RX_CDC_DMA_RX_1, + RX_CDC_DMA_RX_2, + RX_CDC_DMA_RX_3, + RX_CDC_DMA_RX_5, + CDC_DMA_RX_MAX, +}; + +enum { + WSA_CDC_DMA_TX_0 = 0, + WSA_CDC_DMA_TX_1, + WSA_CDC_DMA_TX_2, + TX_CDC_DMA_TX_0, + TX_CDC_DMA_TX_3, + TX_CDC_DMA_TX_4, + CDC_DMA_TX_MAX, +}; + +struct mi2s_conf { + struct mutex lock; + u32 ref_cnt; + u32 msm_is_mi2s_master; +}; + +static u32 mi2s_ebit_clk[MI2S_MAX] = { + Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT +}; + +struct dev_config { + u32 sample_rate; + u32 bit_format; + u32 channels; +}; + +enum { + DP_RX_IDX = 0, + EXT_DISP_RX_IDX_MAX, +}; + +struct msm_wsa881x_dev_info { + struct device_node *of_node; + u32 index; +}; + +struct aux_codec_dev_info { + struct device_node *of_node; + u32 index; +}; + +enum pinctrl_pin_state { + STATE_DISABLE = 0, /* All pins are in sleep state */ + STATE_MI2S_ACTIVE, /* I2S = active, TDM = sleep */ + STATE_TDM_ACTIVE, /* I2S = sleep, TDM = active */ +}; + +struct msm_pinctrl_info { + struct pinctrl *pinctrl; + struct pinctrl_state *mi2s_disable; + struct pinctrl_state *tdm_disable; + struct pinctrl_state *mi2s_active; + struct pinctrl_state *tdm_active; + enum pinctrl_pin_state curr_state; +}; + +struct msm_asoc_mach_data { + struct snd_info_entry *codec_root; + struct msm_pinctrl_info pinctrl_info; + int usbc_en2_gpio; /* used by gpio driver API */ + struct device_node *dmic01_gpio_p; /* used by pinctrl API */ + struct device_node *dmic23_gpio_p; /* used by pinctrl API */ + struct device_node *us_euro_gpio_p; /* used by pinctrl API */ + struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */ + struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ + struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ +}; + +struct msm_asoc_wcd93xx_codec { + void* (*get_afe_config_fn)(struct snd_soc_codec *codec, + enum afe_config_type config_type); +}; + +static const char *const pin_states[] = {"sleep", "i2s-active", + "tdm-active"}; + +static struct snd_soc_card snd_soc_card_sm6150_msm; + +enum { + TDM_0 = 0, + TDM_1, + TDM_2, + TDM_3, + TDM_4, + TDM_5, + TDM_6, + TDM_7, + TDM_PORT_MAX, +}; + +enum { + TDM_PRI = 0, + TDM_SEC, + TDM_TERT, + TDM_QUAT, + TDM_QUIN, + TDM_INTERFACE_MAX, +}; + +struct tdm_port { + u32 mode; + u32 channel; +}; + +/* TDM default config */ +static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUIN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + } + +}; + +/* TDM default config */ +static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUIN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + } +}; + + +/* Default configuration of slimbus channels */ +static struct dev_config slim_rx_cfg[] = { + [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config slim_tx_cfg[] = { + [SLIM_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +/* Default configuration of Codec DMA Interface Tx */ +static struct dev_config cdc_dma_rx_cfg[] = { + [WSA_CDC_DMA_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [WSA_CDC_DMA_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [RX_CDC_DMA_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [RX_CDC_DMA_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [RX_CDC_DMA_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [RX_CDC_DMA_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [RX_CDC_DMA_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +/* Default configuration of Codec DMA Interface Rx */ +static struct dev_config cdc_dma_tx_cfg[] = { + [WSA_CDC_DMA_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [WSA_CDC_DMA_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [WSA_CDC_DMA_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TX_CDC_DMA_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TX_CDC_DMA_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TX_CDC_DMA_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +/* Default configuration of external display BE */ +static struct dev_config ext_disp_rx_cfg[] = { + [DP_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config usb_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +static struct dev_config usb_tx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 1, +}; + +static struct dev_config proxy_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +/* Default configuration of MI2S channels */ +static struct dev_config mi2s_rx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config mi2s_tx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_rx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_tx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; +static int msm_vi_feed_tx_ch = 2; +static const char *const slim_rx_ch_text[] = {"One", "Two"}; +static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static const char *const vi_feed_ch_text[] = {"One", "Two"}; +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; +static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE", + "S24_3LE"}; +static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; +static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *ch_text[] = {"Two", "Three", "Four", "Five", + "Six", "Seven", "Eight"}; +static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_32", "KHZ_44P1", + "KHZ_88P2", "KHZ_176P4" }; +static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", "Eight"}; +static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; +static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", + "KHZ_48", "KHZ_176P4", + "KHZ_352P8"}; +static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; +static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_16", + "KHZ_22P05", "KHZ_32", "KHZ_44P1", + "KHZ_48", "KHZ_96", "KHZ_192"}; +static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static const char *const hifi_text[] = {"Off", "On"}; +static const char *const qos_text[] = {"Disable", "Enable"}; + +static const char *const cdc_dma_rx_ch_text[] = {"One", "Two"}; +static const char *const cdc_dma_tx_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *cdc_dma_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; + +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_1_tx_chs, slim_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, + ext_disp_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(hifi_function, hifi_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_0_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_1_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_2_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_0_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_3_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_1_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_2_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_0_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_3_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_1_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_2_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_3_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_sample_rate, + cdc_dma_sample_rate_text); + +static struct platform_device *spdev; + +static int msm_hifi_control; +static bool is_initial_boot; +static bool codec_reg_done; +static struct snd_soc_aux_dev *msm_aux_dev; +static struct snd_soc_codec_conf *msm_codec_conf; +static struct msm_asoc_wcd93xx_codec msm_codec_fn; + +static int dmic_0_1_gpio_cnt; +static int dmic_2_3_gpio_cnt; + +static void *def_wcd_mbhc_cal(void); +static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, + int enable, bool dapm); +static int msm_wsa881x_init(struct snd_soc_component *component); +static int msm_aux_codec_init(struct snd_soc_component *component); + +/* + * Need to report LINEIN + * if R/L channel impedance is larger than 5K ohm + */ +static struct wcd_mbhc_config wcd_mbhc_cfg = { + .read_fw_bin = false, + .calibration = NULL, + .detect_extn_cable = true, + .mono_stero_detection = false, + .swap_gnd_mic = NULL, + .hs_ext_micbias = true, + .key_code[0] = KEY_MEDIA, + .key_code[1] = KEY_VOICECOMMAND, + .key_code[2] = KEY_VOLUMEUP, + .key_code[3] = KEY_VOLUMEDOWN, + .key_code[4] = 0, + .key_code[5] = 0, + .key_code[6] = 0, + .key_code[7] = 0, + .linein_th = 5000, + .moisture_en = true, + .mbhc_micbias = MIC_BIAS_2, + .anc_micbias = MIC_BIAS_2, + .enable_anc_mic_detect = false, +}; + +static struct snd_soc_dapm_route wcd_audio_paths_tavil[] = { + {"MIC BIAS1", NULL, "MCLK TX"}, + {"MIC BIAS2", NULL, "MCLK TX"}, + {"MIC BIAS3", NULL, "MCLK TX"}, + {"MIC BIAS4", NULL, "MCLK TX"}, +}; + +static struct afe_clk_set mi2s_clk[MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + } + +}; + +static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; + +static int slim_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 10; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int slim_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + sample_rate = SAMPLING_RATE_384KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int slim_get_bit_format_val(int bit_format) +{ + int val = 0; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + val = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + val = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + val = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + val = 0; + break; + } + return val; +} + +static int slim_get_bit_format(int val) +{ + int bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + + switch (val) { + case 0: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + bit_fmt = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + bit_fmt = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + bit_fmt = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return bit_fmt; +} + +static int slim_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int port_id = 0; + + if (strnstr(kcontrol->id.name, "SLIM_0_RX", sizeof("SLIM_0_RX"))) { + port_id = SLIM_RX_0; + } else if (strnstr(kcontrol->id.name, + "SLIM_2_RX", sizeof("SLIM_2_RX"))) { + port_id = SLIM_RX_2; + } else if (strnstr(kcontrol->id.name, + "SLIM_5_RX", sizeof("SLIM_5_RX"))) { + port_id = SLIM_RX_5; + } else if (strnstr(kcontrol->id.name, + "SLIM_6_RX", sizeof("SLIM_6_RX"))) { + port_id = SLIM_RX_6; + } else if (strnstr(kcontrol->id.name, + "SLIM_0_TX", sizeof("SLIM_0_TX"))) { + port_id = SLIM_TX_0; + } else if (strnstr(kcontrol->id.name, + "SLIM_1_TX", sizeof("SLIM_1_TX"))) { + port_id = SLIM_TX_1; + } else { + pr_err("%s: unsupported channel: %s\n", + __func__, kcontrol->id.name); + return -EINVAL; + } + + return port_id; +} + +static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_sample_rate_val(slim_rx_cfg[ch_num].sample_rate); + + pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].sample_rate = + slim_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_sample_rate_val(slim_tx_cfg[ch_num].sample_rate); + + pr_debug("%s: slim[%d]_tx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate = 0; + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + sample_rate = slim_get_sample_rate(ucontrol->value.enumerated.item[0]); + if (sample_rate == SAMPLING_RATE_44P1KHZ) { + pr_err("%s: Unsupported sample rate %d: for Tx path\n", + __func__, sample_rate); + return -EINVAL; + } + slim_tx_cfg[ch_num].sample_rate = sample_rate; + + pr_debug("%s: slim[%d]_tx_sample_rate = %d, value = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_bit_format_val(slim_rx_cfg[ch_num].bit_format); + + pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_rx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].bit_format = + slim_get_bit_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_rx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_bit_format_val(slim_tx_cfg[ch_num].bit_format); + + pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_tx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_tx_cfg[ch_num].bit_format = + slim_get_bit_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_tx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].channels); + ucontrol->value.enumerated.item[0] = slim_rx_cfg[ch_num].channels - 1; + + return 0; +} + +static int slim_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].channels); + + return 1; +} + +static int slim_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].channels); + ucontrol->value.enumerated.item[0] = slim_tx_cfg[ch_num].channels - 1; + + return 0; +} + +static int slim_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_tx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].channels); + + return 1; +} + +static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1; + pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch); + return 1; +} + +static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* + * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) + * when used for BT_SCO use case. Return either Rx or Tx sample rate + * value. + */ + switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate = %d\n", __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n", + __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate, + slim_tx_cfg[SLIM_TX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int cdc_dma_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx = 0; + + if (strnstr(kcontrol->id.name, "WSA_CDC_DMA_RX_0", + sizeof("WSA_CDC_DMA_RX_0"))) + idx = WSA_CDC_DMA_RX_0; + else if (strnstr(kcontrol->id.name, "WSA_CDC_DMA_RX_1", + sizeof("WSA_CDC_DMA_RX_0"))) + idx = WSA_CDC_DMA_RX_1; + else if (strnstr(kcontrol->id.name, "RX_CDC_DMA_RX_0", + sizeof("RX_CDC_DMA_RX_0"))) + idx = RX_CDC_DMA_RX_0; + else if (strnstr(kcontrol->id.name, "RX_CDC_DMA_RX_1", + sizeof("RX_CDC_DMA_RX_1"))) + idx = RX_CDC_DMA_RX_1; + else if (strnstr(kcontrol->id.name, "RX_CDC_DMA_RX_2", + sizeof("RX_CDC_DMA_RX_2"))) + idx = RX_CDC_DMA_RX_2; + else if (strnstr(kcontrol->id.name, "RX_CDC_DMA_RX_3", + sizeof("RX_CDC_DMA_RX_3"))) + idx = RX_CDC_DMA_RX_3; + else if (strnstr(kcontrol->id.name, "RX_CDC_DMA_RX_5", + sizeof("RX_CDC_DMA_RX_5"))) + idx = RX_CDC_DMA_RX_5; + else if (strnstr(kcontrol->id.name, "WSA_CDC_DMA_TX_0", + sizeof("WSA_CDC_DMA_TX_0"))) + idx = WSA_CDC_DMA_TX_0; + else if (strnstr(kcontrol->id.name, "WSA_CDC_DMA_TX_1", + sizeof("WSA_CDC_DMA_TX_1"))) + idx = WSA_CDC_DMA_TX_1; + else if (strnstr(kcontrol->id.name, "WSA_CDC_DMA_TX_2", + sizeof("WSA_CDC_DMA_TX_2"))) + idx = WSA_CDC_DMA_TX_2; + else if (strnstr(kcontrol->id.name, "TX_CDC_DMA_TX_0", + sizeof("TX_CDC_DMA_TX_0"))) + idx = TX_CDC_DMA_TX_0; + else if (strnstr(kcontrol->id.name, "TX_CDC_DMA_TX_3", + sizeof("TX_CDC_DMA_TX_3"))) + idx = TX_CDC_DMA_TX_3; + else if (strnstr(kcontrol->id.name, "TX_CDC_DMA_TX_4", + sizeof("TX_CDC_DMA_TX_4"))) + idx = TX_CDC_DMA_TX_4; + else { + pr_err("%s: unsupported channel: %s\n", + __func__, kcontrol->id.name); + return -EINVAL; + } + + return idx; +} + +static int cdc_dma_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + pr_debug("%s: cdc_dma_rx_ch = %d\n", __func__, + cdc_dma_rx_cfg[ch_num].channels - 1); + ucontrol->value.integer.value[0] = cdc_dma_rx_cfg[ch_num].channels - 1; + return 0; +} + +static int cdc_dma_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + cdc_dma_rx_cfg[ch_num].channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: cdc_dma_rx_ch = %d\n", __func__, + cdc_dma_rx_cfg[ch_num].channels); + return 1; +} + +static int cdc_dma_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + switch (cdc_dma_rx_cfg[ch_num].bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: cdc_dma_rx_format = %d, ucontrol value = %ld\n", + __func__, cdc_dma_rx_cfg[ch_num].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int cdc_dma_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + int ch_num = cdc_dma_get_port_idx(kcontrol); + + switch (ucontrol->value.integer.value[0]) { + case 3: + cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: cdc_dma_rx_format = %d, ucontrol value = %ld\n", + __func__, cdc_dma_rx_cfg[ch_num].bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int cdc_dma_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 10; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int cdc_dma_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + sample_rate = SAMPLING_RATE_384KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + + +static int cdc_dma_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + cdc_dma_get_sample_rate_val(cdc_dma_rx_cfg[ch_num].sample_rate); + + pr_debug("%s: cdc_dma_rx_sample_rate = %d\n", __func__, + cdc_dma_rx_cfg[ch_num].sample_rate); + return 0; +} + +static int cdc_dma_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + cdc_dma_rx_cfg[ch_num].sample_rate = + cdc_dma_get_sample_rate(ucontrol->value.enumerated.item[0]); + + + pr_debug("%s: control value = %d, cdc_dma_rx_sample_rate = %d\n", + __func__, ucontrol->value.enumerated.item[0], + cdc_dma_rx_cfg[ch_num].sample_rate); + return 0; +} + +static int cdc_dma_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + pr_debug("%s: cdc_dma_tx_ch = %d\n", __func__, + cdc_dma_tx_cfg[ch_num].channels); + ucontrol->value.integer.value[0] = cdc_dma_tx_cfg[ch_num].channels - 1; + return 0; +} + +static int cdc_dma_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + cdc_dma_tx_cfg[ch_num].channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: cdc_dma_tx_ch = %d\n", __func__, + cdc_dma_tx_cfg[ch_num].channels); + return 1; +} + +static int cdc_dma_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + int ch_num = cdc_dma_get_port_idx(kcontrol); + + switch (cdc_dma_tx_cfg[ch_num].sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + default: + sample_rate_val = 6; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: cdc_dma_tx_sample_rate = %d\n", __func__, + cdc_dma_tx_cfg[ch_num].sample_rate); + return 0; +} + +static int cdc_dma_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + switch (ucontrol->value.integer.value[0]) { + case 12: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, cdc_dma_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + cdc_dma_tx_cfg[ch_num].sample_rate); + return 0; +} + +static int cdc_dma_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + switch (cdc_dma_tx_cfg[ch_num].bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: cdc_dma_tx_format = %d, ucontrol value = %ld\n", + __func__, cdc_dma_tx_cfg[ch_num].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int cdc_dma_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + int ch_num = cdc_dma_get_port_idx(kcontrol); + + switch (ucontrol->value.integer.value[0]) { + case 3: + cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: cdc_dma_tx_format = %d, ucontrol value = %ld\n", + __func__, cdc_dma_tx_cfg[ch_num].bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +/***************/ +static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, + usb_rx_cfg.channels); + ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1; + return 0; +} + +static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels); + return 1; +} + +static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_rx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__, + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_rx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_rx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_rx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_rx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, + usb_tx_cfg.channels); + ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1; + return 0; +} + +static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels); + return 1; +} + +static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_tx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + default: + sample_rate_val = 6; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__, + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_tx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_tx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_tx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_tx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "Display Port RX", + sizeof("Display Port RX"))) { + idx = DP_RX_IDX; + } else { + pr_err("%s: unsupported BE: %s\n", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].bit_format) { + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 2: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int ext_disp_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.integer.value[0] = + ext_disp_rx_cfg[idx].channels - 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + + return 0; +} + +static int ext_disp_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ext_disp_rx_cfg[idx].channels = + ucontrol->value.integer.value[0] + 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + return 1; +} + +static int ext_disp_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].sample_rate) { + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 6; + break; + + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 4; + break; + + case SAMPLING_RATE_32KHZ: + sample_rate_val = 3; + break; + + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: ext_disp_rx[%d].sample_rate = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].sample_rate); + + return 0; +} + +static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 6: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 5: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 4: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_32KHZ; + break; + case 2: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, ext_disp_rx[%d].sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], idx, + ext_disp_rx_cfg[idx].sample_rate); + return 0; +} + +static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2; + + return 0; +} + +static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2; + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + + return 1; +} + +static int tdm_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int aux_pcm_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 0: + default: + sample_rate = SAMPLING_RATE_8KHZ; + break; + } + return sample_rate; +} + +static int tdm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 5; + break; + default: + sample_rate_val = 3; + break; + } + return sample_rate_val; +} + +static int aux_pcm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + return sample_rate_val; +} + +static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, + struct tdm_port *port) +{ + if (port) { + if (strnstr(kcontrol->id.name, "PRI", + sizeof(kcontrol->id.name))) { + port->mode = TDM_PRI; + } else if (strnstr(kcontrol->id.name, "SEC", + sizeof(kcontrol->id.name))) { + port->mode = TDM_SEC; + } else if (strnstr(kcontrol->id.name, "TERT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_TERT; + } else if (strnstr(kcontrol->id.name, "QUAT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_QUAT; + } else if (strnstr(kcontrol->id.name, "QUIN", + sizeof(kcontrol->id.name))) { + port->mode = TDM_QUIN; + } else { + pr_err("%s: unsupported mode in: %s\n", + __func__, kcontrol->id.name); + return -EINVAL; + } + + if (strnstr(kcontrol->id.name, "RX_0", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_0", + sizeof(kcontrol->id.name))) { + port->channel = TDM_0; + } else if (strnstr(kcontrol->id.name, "RX_1", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_1", + sizeof(kcontrol->id.name))) { + port->channel = TDM_1; + } else if (strnstr(kcontrol->id.name, "RX_2", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_2", + sizeof(kcontrol->id.name))) { + port->channel = TDM_2; + } else if (strnstr(kcontrol->id.name, "RX_3", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_3", + sizeof(kcontrol->id.name))) { + port->channel = TDM_3; + } else if (strnstr(kcontrol->id.name, "RX_4", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_4", + sizeof(kcontrol->id.name))) { + port->channel = TDM_4; + } else if (strnstr(kcontrol->id.name, "RX_5", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_5", + sizeof(kcontrol->id.name))) { + port->channel = TDM_5; + } else if (strnstr(kcontrol->id.name, "RX_6", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_6", + sizeof(kcontrol->id.name))) { + port->channel = TDM_6; + } else if (strnstr(kcontrol->id.name, "RX_7", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_7", + sizeof(kcontrol->id.name))) { + port->channel = TDM_7; + } else { + pr_err("%s: unsupported channel in: %s\n", + __func__, kcontrol->id.name); + return -EINVAL; + } + } else { + return -EINVAL; + } + return 0; +} + +static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_rx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_tx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_get_format(int value) +{ + int format = 0; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int tdm_get_format_val(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 2; + break; + default: + value = 0; + break; + } + return value; +} + +static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_rx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_tx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + + ucontrol->value.enumerated.item[0] = + tdm_rx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = + tdm_tx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", + sizeof("PRIM_AUX_PCM"))) { + idx = PRIM_AUX_PCM; + } else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM", + sizeof("SEC_AUX_PCM"))) { + idx = SEC_AUX_PCM; + } else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", + sizeof("TERT_AUX_PCM"))) { + idx = TERT_AUX_PCM; + } else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", + sizeof("QUAT_AUX_PCM"))) { + idx = QUAT_AUX_PCM; + } else if (strnstr(kcontrol->id.name, "QUIN_AUX_PCM", + sizeof("QUIN_AUX_PCM"))) { + idx = QUIN_AUX_PCM; + } else { + pr_err("%s: unsupported port: %s\n", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX", + sizeof("PRIM_MI2S_RX"))) { + idx = PRIM_MI2S; + } else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX", + sizeof("SEC_MI2S_RX"))) { + idx = SEC_MI2S; + } else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", + sizeof("TERT_MI2S_RX"))) { + idx = TERT_MI2S; + } else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", + sizeof("QUAT_MI2S_RX"))) { + idx = QUAT_MI2S; + } else if (strnstr(kcontrol->id.name, "QUIN_MI2S_RX", + sizeof("QUIN_MI2S_RX"))) { + idx = QUIN_MI2S; + } else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", + sizeof("PRIM_MI2S_TX"))) { + idx = PRIM_MI2S; + } else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX", + sizeof("SEC_MI2S_TX"))) { + idx = SEC_MI2S; + } else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", + sizeof("TERT_MI2S_TX"))) { + idx = TERT_MI2S; + } else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", + sizeof("QUAT_MI2S_TX"))) { + idx = QUAT_MI2S; + } else if (strnstr(kcontrol->id.name, "QUIN_MI2S_TX", + sizeof("QUIN_MI2S_TX"))) { + idx = QUIN_MI2S; + } else { + pr_err("%s: unsupported channel: %s\n", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int mi2s_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + default: + sample_rate_val = 6; + break; + } + return sample_rate_val; +} + +static int mi2s_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_192KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int mi2s_auxpcm_get_format(int value) +{ + int format; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int mi2s_auxpcm_get_format_value(int format) +{ + int value; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + value = 2; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 3; + break; + default: + value = 0; + break; + } + return value; +} + +static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(mi2s_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(mi2s_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(aux_pcm_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(aux_pcm_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_hifi_ctrl(struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + + dev_dbg(codec->dev, "%s: msm_hifi_control = %d\n", __func__, + msm_hifi_control); + + if (!pdata || !pdata->hph_en1_gpio_p) { + dev_err(codec->dev, "%s: hph_en1_gpio is invalid\n", __func__); + return -EINVAL; + } + if (msm_hifi_control == MSM_HIFI_ON) { + msm_cdc_pinctrl_select_active_state(pdata->hph_en1_gpio_p); + /* 5msec delay needed as per HW requirement */ + usleep_range(5000, 5010); + } else { + msm_cdc_pinctrl_select_sleep_state(pdata->hph_en1_gpio_p); + } + snd_soc_dapm_sync(dapm); + + return 0; +} + +static int msm_hifi_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_hifi_control = %d\n", + __func__, msm_hifi_control); + ucontrol->value.integer.value[0] = msm_hifi_control; + + return 0; +} + +static int msm_hifi_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + msm_hifi_control = ucontrol->value.integer.value[0]; + msm_hifi_ctrl(codec); + + return 0; +} + +static const struct snd_kcontrol_new msm_int_snd_controls[] = { + SOC_ENUM_EXT("WSA_CDC_DMA_RX_0 Channels", wsa_cdc_dma_rx_0_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("WSA_CDC_DMA_RX_1 Channels", wsa_cdc_dma_rx_1_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 Channels", rx_cdc_dma_rx_0_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 Channels", rx_cdc_dma_rx_1_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 Channels", rx_cdc_dma_rx_2_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 Channels", rx_cdc_dma_rx_3_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 Channels", rx_cdc_dma_rx_5_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_0 Channels", wsa_cdc_dma_tx_0_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_1 Channels", wsa_cdc_dma_tx_1_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_2 Channels", wsa_cdc_dma_tx_2_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_0 Channels", tx_cdc_dma_tx_0_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_3 Channels", tx_cdc_dma_tx_3_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_4 Channels", tx_cdc_dma_tx_4_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("WSA_CDC_DMA_RX_0 Format", wsa_cdc_dma_rx_0_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("WSA_CDC_DMA_RX_1 Format", wsa_cdc_dma_rx_1_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 Format", rx_cdc_dma_rx_0_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 Format", rx_cdc_dma_rx_1_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 Format", rx_cdc_dma_rx_2_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 Format", rx_cdc_dma_rx_3_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 Format", rx_cdc_dma_rx_5_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_1 Format", wsa_cdc_dma_tx_1_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_2 Format", wsa_cdc_dma_tx_2_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_0 Format", tx_cdc_dma_tx_0_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_3 Format", tx_cdc_dma_tx_3_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_4 Format", tx_cdc_dma_tx_4_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("WSA_CDC_DMA_RX_0 SampleRate", + wsa_cdc_dma_rx_0_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("WSA_CDC_DMA_RX_1 SampleRate", + wsa_cdc_dma_rx_1_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 SampleRate", + rx_cdc_dma_rx_0_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 SampleRate", + rx_cdc_dma_rx_1_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 SampleRate", + rx_cdc_dma_rx_2_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 SampleRate", + rx_cdc_dma_rx_3_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 SampleRate", + rx_cdc_dma_rx_5_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_0 SampleRate", + wsa_cdc_dma_tx_0_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_1 SampleRate", + wsa_cdc_dma_tx_1_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_2 SampleRate", + wsa_cdc_dma_tx_2_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_0 SampleRate", + tx_cdc_dma_tx_0_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_3 SampleRate", + tx_cdc_dma_tx_3_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_4 SampleRate", + tx_cdc_dma_tx_4_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), +}; + +static const struct snd_kcontrol_new msm_tavil_snd_controls[] = { + SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, + slim_rx_ch_get, slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs, + slim_rx_ch_get, slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs, + slim_tx_ch_get, slim_tx_ch_put), + SOC_ENUM_EXT("SLIM_1_TX Channels", slim_1_tx_chs, + slim_tx_ch_get, slim_tx_ch_put), + SOC_ENUM_EXT("SLIM_5_RX Channels", slim_5_rx_chs, + slim_rx_ch_get, slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_6_RX Channels", slim_6_rx_chs, + slim_rx_ch_get, slim_rx_ch_put), + SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, + msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), + SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_5_RX Format", slim_5_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_6_RX Format", slim_6_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format, + slim_tx_bit_format_get, slim_tx_bit_format_put), + SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate, + slim_tx_sample_rate_get, slim_tx_sample_rate_put), + SOC_ENUM_EXT("SLIM_5_RX SampleRate", slim_5_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_6_RX SampleRate", slim_6_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), +}; + +static const struct snd_kcontrol_new msm_common_snd_controls[] = { + SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, + usb_audio_rx_ch_get, usb_audio_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, + usb_audio_tx_ch_get, usb_audio_tx_ch_put), + SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, + ext_disp_rx_ch_get, ext_disp_rx_ch_put), + SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, + proxy_rx_ch_get, proxy_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, + usb_audio_rx_format_get, usb_audio_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, + usb_audio_tx_format_get, usb_audio_tx_format_put), + SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, + ext_disp_rx_format_get, ext_disp_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, + usb_audio_rx_sample_rate_get, + usb_audio_rx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, + usb_audio_tx_sample_rate_get, + usb_audio_tx_sample_rate_put), + SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, + ext_disp_rx_sample_rate_get, + ext_disp_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_RX SampleRate", quin_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_TX SampleRate", quin_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_MI2S_RX SampleRate", quin_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_MI2S_TX SampleRate", quin_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUIN_MI2S_RX Channels", quin_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUIN_MI2S_TX Channels", quin_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("SEC_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("TERT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("TERT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("QUIN_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("QUIN_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get, + msm_hifi_put), + SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), +}; + +static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, + int enable, bool dapm) +{ + int ret = 0; + + if (!strcmp(dev_name(codec->dev), "tavil_codec")) { + ret = tavil_cdc_mclk_enable(codec, enable); + } else { + dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", + __func__); + ret = -EINVAL; + } + return ret; +} + +static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, + int enable, bool dapm) +{ + int ret = 0; + + if (!strcmp(dev_name(codec->dev), "tavil_codec")) { + ret = tavil_cdc_mclk_tx_enable(codec, enable); + } else { + dev_err(codec->dev, "%s: unknown codec to enable TX ext clk\n", + __func__); + ret = -EINVAL; + } + + return ret; +} + +static int msm_mclk_tx_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + pr_debug("%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return msm_snd_enable_codec_ext_tx_clk(codec, 1, true); + case SND_SOC_DAPM_POST_PMD: + return msm_snd_enable_codec_ext_tx_clk(codec, 0, true); + } + return 0; +} + +static int msm_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + pr_debug("%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return msm_snd_enable_codec_ext_clk(codec, 1, true); + case SND_SOC_DAPM_POST_PMD: + return msm_snd_enable_codec_ext_clk(codec, 0, true); + } + return 0; +} + +static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + + dev_dbg(codec->dev, "%s: msm_hifi_control = %d\n", + __func__, msm_hifi_control); + + if (!pdata || !pdata->hph_en0_gpio_p) { + dev_err(codec->dev, "%s: hph_en0_gpio is invalid\n", __func__); + return -EINVAL; + } + + if (msm_hifi_control != MSM_HIFI_ON) { + dev_dbg(codec->dev, "%s: HiFi mixer control is not set\n", + __func__); + return 0; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + msm_cdc_pinctrl_select_active_state(pdata->hph_en0_gpio_p); + break; + case SND_SOC_DAPM_PRE_PMD: + msm_cdc_pinctrl_select_sleep_state(pdata->hph_en0_gpio_p); + break; + } + + return 0; +} + +static const struct snd_soc_dapm_widget msm_dapm_widgets_tavil[] = { + + SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, + msm_mclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0, + msm_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SPK("Lineout_1 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), + SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event), + SND_SOC_DAPM_MIC("Handset Mic", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), + SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL), + SND_SOC_DAPM_MIC("Analog Mic5", NULL), + + SND_SOC_DAPM_MIC("Digital Mic0", NULL), + SND_SOC_DAPM_MIC("Digital Mic1", NULL), + SND_SOC_DAPM_MIC("Digital Mic2", NULL), + SND_SOC_DAPM_MIC("Digital Mic3", NULL), + SND_SOC_DAPM_MIC("Digital Mic4", NULL), + SND_SOC_DAPM_MIC("Digital Mic5", NULL), +}; + +static int msm_dmic_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct msm_asoc_mach_data *pdata = NULL; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int ret = 0; + uint32_t dmic_idx; + int *dmic_gpio_cnt; + struct device_node *dmic_gpio; + char *wname; + + wname = strpbrk(w->name, "0123"); + if (!wname) { + dev_err(codec->dev, "%s: widget not found\n", __func__); + return -EINVAL; + } + + ret = kstrtouint(wname, 10, &dmic_idx); + if (ret < 0) { + dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n", + __func__); + return -EINVAL; + } + + pdata = snd_soc_card_get_drvdata(codec->component.card); + + switch (dmic_idx) { + case 0: + case 1: + dmic_gpio_cnt = &dmic_0_1_gpio_cnt; + dmic_gpio = pdata->dmic01_gpio_p; + break; + case 2: + case 3: + dmic_gpio_cnt = &dmic_2_3_gpio_cnt; + dmic_gpio = pdata->dmic23_gpio_p; + break; + default: + dev_err(codec->dev, "%s: Invalid DMIC Selection\n", + __func__); + return -EINVAL; + } + + dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_gpio_cnt %d\n", + __func__, event, dmic_idx, *dmic_gpio_cnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + (*dmic_gpio_cnt)++; + if (*dmic_gpio_cnt == 1) { + ret = msm_cdc_pinctrl_select_active_state( + dmic_gpio); + if (ret < 0) { + pr_err("%s: gpio set cannot be activated %sd", + __func__, "dmic_gpio"); + return ret; + } + } + + break; + case SND_SOC_DAPM_POST_PMD: + (*dmic_gpio_cnt)--; + if (*dmic_gpio_cnt == 0) { + ret = msm_cdc_pinctrl_select_sleep_state( + dmic_gpio); + if (ret < 0) { + pr_err("%s: gpio set cannot be de-activated %sd", + __func__, "dmic_gpio"); + return ret; + } + } + break; + default: + pr_err("%s: invalid DAPM event %d\n", __func__, event); + return -EINVAL; + } + return 0; +} + +static const struct snd_soc_dapm_widget msm_int_dapm_widgets[] = { + SND_SOC_DAPM_MIC("Analog Mic1", NULL), + SND_SOC_DAPM_MIC("Analog Mic2", NULL), + SND_SOC_DAPM_MIC("Analog Mic3", NULL), + SND_SOC_DAPM_MIC("Analog Mic4", NULL), + SND_SOC_DAPM_MIC("Digital Mic0", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic1", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic2", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic3", msm_dmic_event), +}; + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, + int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, + unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +static int msm_slim_get_ch_from_beid(int32_t be_id) +{ + int ch_id = 0; + + switch (be_id) { + case MSM_BACKEND_DAI_SLIMBUS_0_RX: + ch_id = SLIM_RX_0; + break; + case MSM_BACKEND_DAI_SLIMBUS_1_RX: + ch_id = SLIM_RX_1; + break; + case MSM_BACKEND_DAI_SLIMBUS_2_RX: + ch_id = SLIM_RX_2; + break; + case MSM_BACKEND_DAI_SLIMBUS_3_RX: + ch_id = SLIM_RX_3; + break; + case MSM_BACKEND_DAI_SLIMBUS_4_RX: + ch_id = SLIM_RX_4; + break; + case MSM_BACKEND_DAI_SLIMBUS_6_RX: + ch_id = SLIM_RX_6; + break; + case MSM_BACKEND_DAI_SLIMBUS_0_TX: + ch_id = SLIM_TX_0; + break; + case MSM_BACKEND_DAI_SLIMBUS_3_TX: + ch_id = SLIM_TX_3; + break; + default: + ch_id = SLIM_RX_0; + break; + } + + return ch_id; +} + +static int msm_cdc_dma_get_idx_from_beid(int32_t be_id) +{ + int idx = 0; + + switch (be_id) { + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0: + idx = WSA_CDC_DMA_RX_0; + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0: + idx = WSA_CDC_DMA_TX_0; + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1: + idx = WSA_CDC_DMA_RX_1; + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1: + idx = WSA_CDC_DMA_TX_1; + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2: + idx = WSA_CDC_DMA_TX_2; + break; + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_0: + idx = RX_CDC_DMA_RX_0; + break; + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_1: + idx = RX_CDC_DMA_RX_1; + break; + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_2: + idx = RX_CDC_DMA_RX_2; + break; + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_3: + idx = RX_CDC_DMA_RX_3; + break; + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_5: + idx = RX_CDC_DMA_RX_5; + break; + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_0: + idx = TX_CDC_DMA_TX_0; + break; + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_3: + idx = TX_CDC_DMA_TX_3; + break; + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_4: + idx = TX_CDC_DMA_TX_4; + break; + default: + idx = RX_CDC_DMA_RX_0; + break; + } + + return idx; +} + +static int msm_ext_disp_get_idx_from_beid(int32_t be_id) +{ + int idx = -EINVAL; + + switch (be_id) { + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = DP_RX_IDX; + break; + default: + pr_err("%s: Incorrect ext_disp BE id %d\n", __func__, be_id); + idx = -EINVAL; + break; + } + + return idx; +} + +static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int rc = 0; + int idx; + void *config = NULL; + struct snd_soc_codec *codec = NULL; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->id) { + case MSM_BACKEND_DAI_SLIMBUS_0_RX: + case MSM_BACKEND_DAI_SLIMBUS_1_RX: + case MSM_BACKEND_DAI_SLIMBUS_2_RX: + case MSM_BACKEND_DAI_SLIMBUS_3_RX: + case MSM_BACKEND_DAI_SLIMBUS_4_RX: + case MSM_BACKEND_DAI_SLIMBUS_6_RX: + idx = msm_slim_get_ch_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[idx].bit_format); + rate->min = rate->max = slim_rx_cfg[idx].sample_rate; + channels->min = channels->max = slim_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_0_TX: + case MSM_BACKEND_DAI_SLIMBUS_3_TX: + idx = msm_slim_get_ch_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[idx].bit_format); + rate->min = rate->max = slim_tx_cfg[idx].sample_rate; + channels->min = channels->max = slim_tx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_1_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[1].bit_format); + rate->min = rate->max = slim_tx_cfg[1].sample_rate; + channels->min = channels->max = slim_tx_cfg[1].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_4_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + SNDRV_PCM_FORMAT_S32_LE); + rate->min = rate->max = SAMPLING_RATE_8KHZ; + channels->min = channels->max = msm_vi_feed_tx_ch; + break; + + case MSM_BACKEND_DAI_SLIMBUS_5_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[5].bit_format); + rate->min = rate->max = slim_rx_cfg[5].sample_rate; + channels->min = channels->max = slim_rx_cfg[5].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_5_TX: + codec = rtd->codec; + rate->min = rate->max = SAMPLING_RATE_16KHZ; + channels->min = channels->max = 1; + + config = msm_codec_fn.get_afe_config_fn(codec, + AFE_SLIMBUS_SLAVE_PORT_CONFIG); + if (config) { + rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, + config, SLIMBUS_5_TX); + if (rc) + pr_err("%s: Failed to set slimbus slave port config %d\n", + __func__, rc); + } + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[SLIM_RX_7].bit_format); + rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate; + channels->min = channels->max = + slim_rx_cfg[SLIM_RX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_8_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_8].channels; + break; + + case MSM_BACKEND_DAI_USB_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_rx_cfg.bit_format); + rate->min = rate->max = usb_rx_cfg.sample_rate; + channels->min = channels->max = usb_rx_cfg.channels; + break; + + case MSM_BACKEND_DAI_USB_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_tx_cfg.bit_format); + rate->min = rate->max = usb_tx_cfg.sample_rate; + channels->min = channels->max = usb_tx_cfg.channels; + break; + + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = msm_ext_disp_get_idx_from_beid(dai_link->id); + if (idx < 0) { + pr_err("%s: Incorrect ext disp idx %d\n", + __func__, idx); + rc = idx; + goto done; + } + + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + ext_disp_rx_cfg[idx].bit_format); + rate->min = rate->max = ext_disp_rx_cfg[idx].sample_rate; + channels->min = channels->max = ext_disp_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_AFE_PCM_RX: + channels->min = channels->max = proxy_rx_cfg.channels; + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + + case MSM_BACKEND_DAI_PRI_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_PRI_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUIN_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUIN_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + + + case MSM_BACKEND_DAI_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[PRIM_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[SEC_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[SEC_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[TERT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[TERT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[QUAT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[QUAT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUIN_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[QUIN_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[QUIN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUIN_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUIN_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[QUIN_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[QUIN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUIN_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUAT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUAT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUINARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUIN_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[QUIN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUIN_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUIN_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[QUIN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUIN_MI2S].channels; + break; + + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0: + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_0: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_1: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_2: + idx = msm_cdc_dma_get_idx_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + cdc_dma_rx_cfg[idx].bit_format); + rate->min = rate->max = cdc_dma_rx_cfg[idx].sample_rate; + channels->min = channels->max = cdc_dma_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1: + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_0: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_1: + idx = msm_cdc_dma_get_idx_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + cdc_dma_tx_cfg[idx].bit_format); + rate->min = rate->max = cdc_dma_tx_cfg[idx].sample_rate; + channels->min = channels->max = cdc_dma_tx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + SNDRV_PCM_FORMAT_S32_LE); + rate->min = rate->max = SAMPLING_RATE_8KHZ; + channels->min = channels->max = msm_vi_feed_tx_ch; + break; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + +done: + return rc; +} + +static bool msm_usbc_swap_gnd_mic(struct snd_soc_codec *codec, bool active) +{ + int value = 0; + bool ret = 0; + struct snd_soc_card *card = codec->component.card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct pinctrl_state *en2_pinctrl_active; + struct pinctrl_state *en2_pinctrl_sleep; + + if (!pdata->usbc_en2_gpio_p) { + if (active) { + /* if active and usbc_en2_gpio undefined, get pin */ + pdata->usbc_en2_gpio_p = devm_pinctrl_get(card->dev); + if (IS_ERR_OR_NULL(pdata->usbc_en2_gpio_p)) { + dev_err(card->dev, + "%s: Can't get EN2 gpio pinctrl:%ld\n", + __func__, + PTR_ERR(pdata->usbc_en2_gpio_p)); + pdata->usbc_en2_gpio_p = NULL; + return false; + } + } else { + /* if not active and usbc_en2_gpio undefined, return */ + return false; + } + } + + pdata->usbc_en2_gpio = of_get_named_gpio(card->dev->of_node, + "qcom,usbc-analog-en2-gpio", 0); + if (!gpio_is_valid(pdata->usbc_en2_gpio)) { + dev_err(card->dev, "%s, property %s not in node %s", + __func__, "qcom,usbc-analog-en2-gpio", + card->dev->of_node->full_name); + return false; + } + + en2_pinctrl_active = pinctrl_lookup_state( + pdata->usbc_en2_gpio_p, "aud_active"); + if (IS_ERR_OR_NULL(en2_pinctrl_active)) { + dev_err(card->dev, + "%s: Cannot get aud_active pinctrl state:%ld\n", + __func__, PTR_ERR(en2_pinctrl_active)); + ret = false; + goto err_lookup_state; + } + + en2_pinctrl_sleep = pinctrl_lookup_state( + pdata->usbc_en2_gpio_p, "aud_sleep"); + if (IS_ERR_OR_NULL(en2_pinctrl_sleep)) { + dev_err(card->dev, + "%s: Cannot get aud_sleep pinctrl state:%ld\n", + __func__, PTR_ERR(en2_pinctrl_sleep)); + ret = false; + goto err_lookup_state; + } + + /* if active and usbc_en2_gpio_p defined, swap using usbc_en2_gpio_p */ + if (active) { + dev_dbg(codec->dev, "%s: enter\n", __func__); + if (pdata->usbc_en2_gpio_p) { + value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); + if (value) + pinctrl_select_state(pdata->usbc_en2_gpio_p, + en2_pinctrl_sleep); + else + pinctrl_select_state(pdata->usbc_en2_gpio_p, + en2_pinctrl_active); + } else if (pdata->usbc_en2_gpio >= 0) { + value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); + gpio_set_value_cansleep(pdata->usbc_en2_gpio, !value); + } + pr_debug("%s: swap select switch %d to %d\n", __func__, + value, !value); + ret = true; + } else { + /* if not active, release usbc_en2_gpio_p pin */ + pinctrl_select_state(pdata->usbc_en2_gpio_p, + en2_pinctrl_sleep); + } + +err_lookup_state: + devm_pinctrl_put(pdata->usbc_en2_gpio_p); + pdata->usbc_en2_gpio_p = NULL; + return ret; +} + +static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) +{ + int value = 0; + bool ret = false; + struct snd_soc_card *card; + struct msm_asoc_mach_data *pdata; + + if (!codec) { + pr_err("%s codec is NULL\n", __func__); + return false; + } + card = codec->component.card; + pdata = snd_soc_card_get_drvdata(card); + + if (!pdata) + return false; + + if (wcd_mbhc_cfg.enable_usbc_analog) + return msm_usbc_swap_gnd_mic(codec, active); + + /* if usbc is not defined, swap using us_euro_gpio_p */ + if (pdata->us_euro_gpio_p) { + value = msm_cdc_pinctrl_get_state( + pdata->us_euro_gpio_p); + if (value) + msm_cdc_pinctrl_select_sleep_state( + pdata->us_euro_gpio_p); + else + msm_cdc_pinctrl_select_active_state( + pdata->us_euro_gpio_p); + dev_dbg(codec->dev, "%s: swap select switch %d to %d\n", + __func__, value, !value); + ret = true; + } + return ret; +} + +static int msm_afe_set_config(struct snd_soc_codec *codec) +{ + int ret = 0; + void *config_data = NULL; + + if (!msm_codec_fn.get_afe_config_fn) { + dev_err(codec->dev, "%s: codec get afe config not init'ed\n", + __func__); + return -EINVAL; + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CDC_REGISTERS_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0); + if (ret) { + dev_err(codec->dev, + "%s: Failed to set codec registers config %d\n", + __func__, ret); + return ret; + } + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_CDC_REGISTER_PAGE_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, + 0); + if (ret) + dev_err(codec->dev, + "%s: Failed to set cdc register page config\n", + __func__); + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_SLIMBUS_SLAVE_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0); + if (ret) { + dev_err(codec->dev, + "%s: Failed to set slimbus slave config %d\n", + __func__, ret); + return ret; + } + } + + return 0; +} + +static void msm_afe_clear_config(void) +{ + afe_clear_config(AFE_CDC_REGISTERS_CONFIG); + afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); +} + +static int msm_adsp_power_up_config(struct snd_soc_codec *codec, + struct snd_card *card) +{ + int ret = 0; + unsigned long timeout; + int adsp_ready = 0; + bool snd_card_online = 0; + + timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + + do { + if (!snd_card_online) { + snd_card_online = snd_card_is_online_state(card); + pr_debug("%s: Sound card is %s\n", __func__, + snd_card_online ? "Online" : "Offline"); + } + if (!adsp_ready) { + adsp_ready = q6core_is_adsp_ready(); + pr_debug("%s: ADSP Audio is %s\n", __func__, + adsp_ready ? "ready" : "not ready"); + } + if (snd_card_online && adsp_ready) + break; + + /* + * Sound card/ADSP will be coming up after subsystem restart and + * it might not be fully up when the control reaches + * here. So, wait for 50msec before checking ADSP state + */ + msleep(50); + } while (time_after(timeout, jiffies)); + + if (!snd_card_online || !adsp_ready) { + pr_err("%s: Timeout. Sound card is %s, ADSP Audio is %s\n", + __func__, + snd_card_online ? "Online" : "Offline", + adsp_ready ? "ready" : "not ready"); + ret = -ETIMEDOUT; + goto err; + } + + ret = msm_afe_set_config(codec); + if (ret) + pr_err("%s: Failed to set AFE config. err %d\n", + __func__, ret); + + return 0; + +err: + return ret; +} + +static int sm6150_notifier_service_cb(struct notifier_block *this, + unsigned long opcode, void *ptr) +{ + int ret; + struct snd_soc_card *card = NULL; + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + struct snd_soc_codec *codec; + + pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); + + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + /* + * Use flag to ignore initial boot notifications + * On initial boot msm_adsp_power_up_config is + * called on init. There is no need to clear + * and set the config again on initial boot. + */ + if (is_initial_boot) + break; + msm_afe_clear_config(); + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (is_initial_boot) { + is_initial_boot = false; + break; + } + if (!spdev) + return -EINVAL; + + card = platform_get_drvdata(spdev); + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err; + } + codec = rtd->codec; + + ret = msm_adsp_power_up_config(codec, card->snd_card); + if (ret < 0) { + dev_err(card->dev, + "%s: msm_adsp_power_up_config failed ret = %d!\n", + __func__, ret); + goto err; + } + break; + default: + break; + } +err: + return NOTIFY_OK; +} + +static struct notifier_block service_nb = { + .notifier_call = sm6150_notifier_service_cb, + .priority = -INT_MAX, +}; + +static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + void *config_data; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_component *aux_comp; + struct snd_card *card; + struct snd_info_entry *entry; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); + + /* + * Codec SLIMBUS configuration + * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8 + * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 + * TX14, TX15, TX16 + */ + unsigned int rx_ch[WCD934X_RX_MAX] = {144, 145, 146, 147, 148, 149, + 150, 151}; + unsigned int tx_ch[WCD934X_TX_MAX] = {128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143}; + + pr_info("%s: dev_name:%s\n", __func__, dev_name(cpu_dai->dev)); + + rtd->pmdown_time = 0; + + ret = snd_soc_add_codec_controls(codec, msm_tavil_snd_controls, + ARRAY_SIZE(msm_tavil_snd_controls)); + if (ret < 0) { + pr_err("%s: add_codec_controls failed, err %d\n", + __func__, ret); + return ret; + } + + ret = snd_soc_add_codec_controls(codec, msm_common_snd_controls, + ARRAY_SIZE(msm_common_snd_controls)); + if (ret < 0) { + pr_err("%s: add_codec_controls failed, err %d\n", + __func__, ret); + return ret; + } + + snd_soc_dapm_new_controls(dapm, msm_dapm_widgets_tavil, + ARRAY_SIZE(msm_dapm_widgets_tavil)); + + snd_soc_dapm_add_routes(dapm, wcd_audio_paths_tavil, + ARRAY_SIZE(wcd_audio_paths_tavil)); + + snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic5"); + snd_soc_dapm_ignore_suspend(dapm, "MADINPUT"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT1"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT2"); + snd_soc_dapm_ignore_suspend(dapm, "EAR"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2"); + snd_soc_dapm_ignore_suspend(dapm, "ANC EAR"); + snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); + snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR"); + + snd_soc_dapm_sync(dapm); + + snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); + + msm_codec_fn.get_afe_config_fn = tavil_get_afe_config; + + ret = msm_adsp_power_up_config(codec, rtd->card->snd_card); + if (ret) { + pr_err("%s: Failed to set AFE config %d\n", __func__, ret); + goto err; + } + + config_data = msm_codec_fn.get_afe_config_fn(codec, + AFE_AANC_VERSION); + if (config_data) { + ret = afe_set_config(AFE_AANC_VERSION, config_data, 0); + if (ret) { + pr_err("%s: Failed to set aanc version %d\n", + __func__, ret); + goto err; + } + } + + /* + * Send speaker configuration only for WSA8810. + * Default configuration is for WSA8815. + */ + pr_debug("%s: Number of aux devices: %d\n", + __func__, rtd->card->num_aux_devs); + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->aux_comp_list)) { + aux_comp = list_first_entry(&rtd->card->aux_comp_list, + struct snd_soc_component, card_aux_list); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { + tavil_set_spkr_mode(rtd->codec, WCD934X_SPKR_MODE_1); + tavil_set_spkr_gain_offset(rtd->codec, + WCD934X_RX_GAIN_OFFSET_M1P5_DB); + } + } + + card = rtd->card->snd_card; + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto err; + } + pdata->codec_root = entry; + tavil_codec_info_create_codec_entry(pdata->codec_root, codec); + + codec_reg_done = true; + return 0; +err: + return ret; +} + +static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_card *card; + struct snd_info_entry *entry; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); + + ret = snd_soc_add_codec_controls(codec, msm_int_snd_controls, + ARRAY_SIZE(msm_int_snd_controls)); + if (ret < 0) { + pr_err("%s: add_codec_controls failed: %d\n", + __func__, ret); + return ret; + } + ret = snd_soc_add_codec_controls(codec, msm_common_snd_controls, + ARRAY_SIZE(msm_common_snd_controls)); + if (ret < 0) { + pr_err("%s: add common snd controls failed: %d\n", + __func__, ret); + return ret; + } + + snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets, + ARRAY_SIZE(msm_int_dapm_widgets)); + + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); + + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic2"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic3"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4"); + + snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); + snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); + + snd_soc_dapm_sync(dapm); + + card = rtd->card->snd_card; + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto err; + } + pdata->codec_root = entry; + bolero_info_create_codec_entry(pdata->codec_root, codec); + codec_reg_done = true; + return 0; +err: + return ret; +} + +static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) +{ + unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; + unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); +} + +static void *def_wcd_mbhc_cal(void) +{ + void *wcd_mbhc_cal; + struct wcd_mbhc_btn_detect_cfg *btn_cfg; + u16 *btn_high; + + wcd_mbhc_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, + WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); + if (!wcd_mbhc_cal) + return NULL; + +#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(wcd_mbhc_cal)->X) = (Y)) + S(v_hs_max, 1600); +#undef S +#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal)->X) = (Y)) + S(num_btn, WCD_MBHC_DEF_BUTTONS); +#undef S + + btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal); + btn_high = ((void *)&btn_cfg->_v_btn_low) + + (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); + + btn_high[0] = 75; + btn_high[1] = 150; + btn_high[2] = 237; + btn_high[3] = 500; + btn_high[4] = 500; + btn_high[5] = 500; + btn_high[6] = 500; + btn_high[7] = 500; + + return wcd_mbhc_cal; +} + +static int msm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + int ret = 0; + u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + u32 user_set_tx_ch = 0; + u32 rx_ch_count; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err; + } + if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_5_RX) { + pr_debug("%s: rx_5_ch=%d\n", __func__, + slim_rx_cfg[5].channels); + rx_ch_count = slim_rx_cfg[5].channels; + } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_2_RX) { + pr_debug("%s: rx_2_ch=%d\n", __func__, + slim_rx_cfg[2].channels); + rx_ch_count = slim_rx_cfg[2].channels; + } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_6_RX) { + pr_debug("%s: rx_6_ch=%d\n", __func__, + slim_rx_cfg[6].channels); + rx_ch_count = slim_rx_cfg[6].channels; + } else { + pr_debug("%s: rx_0_ch=%d\n", __func__, + slim_rx_cfg[0].channels); + rx_ch_count = slim_rx_cfg[0].channels; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + rx_ch_count, rx_ch); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + } else { + + pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__, + codec_dai->name, codec_dai->id, user_set_tx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get tx codec chan map, err:%d\n", + __func__, ret); + goto err; + } + /* For _tx1 case */ + if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_0_TX) + user_set_tx_ch = slim_tx_cfg[0].channels; + /* For _tx3 case */ + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_1_TX) + user_set_tx_ch = slim_tx_cfg[1].channels; + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_4_TX) + user_set_tx_ch = msm_vi_feed_tx_ch; + else + user_set_tx_ch = tx_ch_cnt; + + pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), BE id (%d)\n", + __func__, slim_tx_cfg[0].channels, user_set_tx_ch, + tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + user_set_tx_ch, tx_ch, 0, 0); + if (ret < 0) + pr_err("%s: failed to set tx cpu chan map, err:%d\n", + __func__, ret); + } + +err: + return ret; +} + + +static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + int ret = 0; + u32 rx_ch_cdc_dma, tx_ch_cdc_dma; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + u32 user_set_tx_ch = 0; + u32 user_set_rx_ch = 0; + u32 ch_id; + + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, &tx_ch_cdc_dma, &rx_ch_cnt, + &rx_ch_cdc_dma); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + switch (dai_link->id) { + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0: + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_0: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_1: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_2: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_3: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_4: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_5: + { + ch_id = msm_cdc_dma_get_idx_from_beid(dai_link->id); + pr_debug("%s: id %d rx_ch=%d\n", __func__, + ch_id, cdc_dma_rx_cfg[ch_id].channels); + user_set_rx_ch = cdc_dma_rx_cfg[ch_id].channels; + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + user_set_rx_ch, &rx_ch_cdc_dma); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + + } + break; + } + } else { + switch (dai_link->id) { + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0: + { + user_set_tx_ch = msm_vi_feed_tx_ch; + } + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1: + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_0: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_1: + { + ch_id = msm_cdc_dma_get_idx_from_beid(dai_link->id); + pr_debug("%s: id %d tx_ch=%d\n", __func__, + ch_id, cdc_dma_tx_cfg[ch_id].channels); + user_set_tx_ch = cdc_dma_tx_cfg[ch_id].channels; + } + break; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, user_set_tx_ch, + &tx_ch_cdc_dma, 0, 0); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + } + +err: + return ret; +} + +static int msm_slimbus_2_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; + unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0; + unsigned int num_tx_ch = 0; + unsigned int num_rx_ch = 0; + int ret = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + num_rx_ch = params_channels(params); + pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__, + codec_dai->name, codec_dai->id, num_rx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + num_rx_ch, rx_ch); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + } else { + num_tx_ch = params_channels(params); + pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__, + codec_dai->name, codec_dai->id, num_tx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get tx codec chan map, err:%d\n", + __func__, ret); + goto err; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, + num_tx_ch, tx_ch, 0, 0); + if (ret < 0) { + pr_err("%s: failed to set tx cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + } + +err: + return ret; +} + +static int msm_wcn_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + int ret; + + dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret) { + dev_err(rtd->dev, + "%s: failed to get BTFM codec chan map\n, err:%d\n", + __func__, ret); + goto err; + } + + dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) BE id %d\n", + __func__, tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); + if (ret) + dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + +err: + return ret; +} + +static int msm_get_port_id(int be_id) +{ + int afe_port_id; + + switch (be_id) { + case MSM_BACKEND_DAI_PRI_MI2S_RX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_PRI_MI2S_TX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUINARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUINARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUINARY_MI2S_TX; + break; + default: + pr_err("%s: Invalid BE id: %d\n", __func__, be_id); + afe_port_id = -EINVAL; + } + + return afe_port_id; +} + +static u32 get_mi2s_bits_per_sample(u32 bit_format) +{ + u32 bit_per_sample; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + case SNDRV_PCM_FORMAT_S24_LE: + bit_per_sample = 32; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bit_per_sample = 16; + break; + } + + return bit_per_sample; +} + +static void update_mi2s_clk_val(int dai_id, int stream) +{ + u32 bit_per_sample; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } else { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } +} + +static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int port_id = 0; + int index = cpu_dai->id; + + port_id = msm_get_port_id(rtd->dai_link->id); + if (port_id < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto err; + } + + if (enable) { + update_mi2s_clk_val(index, substream->stream); + dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, + mi2s_clk[index].clk_freq_in_hz); + } + + mi2s_clk[index].enable = enable; + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_clk[index]); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed for port 0x%x , err:%d\n", + __func__, port_id, ret); + goto err; + } + +err: + return ret; +} + +static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, + enum pinctrl_pin_state new_state) +{ + int ret = 0; + int curr_state = 0; + + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + if (pinctrl_info->pinctrl == NULL) { + pr_err("%s: pinctrl_info->pinctrl is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + curr_state = pinctrl_info->curr_state; + pinctrl_info->curr_state = new_state; + pr_debug("%s: curr_state = %s new_state = %s\n", __func__, + pin_states[curr_state], pin_states[pinctrl_info->curr_state]); + + if (curr_state == pinctrl_info->curr_state) { + pr_debug("%s: Already in same state\n", __func__); + goto err; + } + + if (curr_state != STATE_DISABLE && + pinctrl_info->curr_state != STATE_DISABLE) { + pr_debug("%s: state already active cannot switch\n", __func__); + ret = -EIO; + goto err; + } + + switch (pinctrl_info->curr_state) { + case STATE_MI2S_ACTIVE: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_active); + if (ret) { + pr_err("%s: MI2S state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + case STATE_TDM_ACTIVE: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->tdm_active); + if (ret) { + pr_err("%s: TDM state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + case STATE_DISABLE: + if (curr_state == STATE_MI2S_ACTIVE) { + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_disable); + } else { + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->tdm_disable); + } + if (ret) { + pr_err("%s: state disable failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + default: + pr_err("%s: TLMM pin state is invalid\n", __func__); + return -EINVAL; + } + +err: + return ret; +} + +static int msm_get_pinctrl(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = NULL; + struct pinctrl *pinctrl; + int ret = 0; + + pinctrl_info = &pdata->pinctrl_info; + + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + return -EINVAL; + } + + pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR_OR_NULL(pinctrl)) { + pr_err("%s: Unable to get pinctrl handle\n", __func__); + return -EINVAL; + } + pinctrl_info->pinctrl = pinctrl; + + /* get all the states handles from Device Tree */ + pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl, + "quat-mi2s-sleep"); + if (IS_ERR(pinctrl_info->mi2s_disable)) { + pr_err("%s: could not get mi2s_disable pinstate\n", __func__); + goto err; + } + pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl, + "quat-mi2s-active"); + if (IS_ERR(pinctrl_info->mi2s_active)) { + pr_err("%s: could not get mi2s_active pinstate\n", __func__); + goto err; + } + pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl, + "quat-tdm-sleep"); + if (IS_ERR(pinctrl_info->tdm_disable)) { + pr_err("%s: could not get tdm_disable pinstate\n", __func__); + goto err; + } + pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl, + "quat-tdm-active"); + if (IS_ERR(pinctrl_info->tdm_active)) { + pr_err("%s: could not get tdm_active pinstate\n", + __func__); + goto err; + } + /* Reset the TLMM pins to a default state */ + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_disable); + if (ret != 0) { + pr_err("%s: Disable TLMM pins failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + pinctrl_info->curr_state = STATE_DISABLE; + + return 0; + +err: + devm_pinctrl_put(pinctrl); + pinctrl_info->pinctrl = NULL; + return -EINVAL; +} + +static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + if (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) { + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + } else if (cpu_dai->id == AFE_PORT_ID_SECONDARY_TDM_RX) { + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + } else if (cpu_dai->id == AFE_PORT_ID_QUINARY_TDM_RX) { + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate; + } else { + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n", + __func__, cpu_dai->id, channels->max, rate->max, + params_format(params)); + + return 0; +} + +static int sm6150_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + int slot_width = 32; + int channels, slots; + unsigned int slot_mask, rate, clk_freq; + unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; + + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + slots = tdm_rx_cfg[TDM_PRI][TDM_0].channels; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + slots = tdm_rx_cfg[TDM_SEC][TDM_0].channels; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + slots = tdm_rx_cfg[TDM_TERT][TDM_0].channels; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + break; + case AFE_PORT_ID_QUINARY_TDM_RX: + slots = tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX: + slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX: + slots = tdm_tx_cfg[TDM_SEC][TDM_0].channels; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX: + slots = tdm_tx_cfg[TDM_TERT][TDM_0].channels; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + break; + case AFE_PORT_ID_QUINARY_TDM_TX: + slots = tdm_tx_cfg[TDM_QUIN][TDM_0].channels; + break; + + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + /*2 slot config - bits 0 and 1 set for the first two slots */ + slot_mask = 0x0000FFFF >> (16-slots); + channels = slots; + + pr_debug("%s: tdm rx slot_width %d slots %d\n", + __func__, slot_width, slots); + + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm rx slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + 0, NULL, channels, slot_offset); + if (ret < 0) { + pr_err("%s: failed to set tdm rx channel map, err:%d\n", + __func__, ret); + goto end; + } + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + /*2 slot config - bits 0 and 1 set for the first two slots */ + slot_mask = 0x0000FFFF >> (16-slots); + channels = slots; + + pr_debug("%s: tdm tx slot_width %d slots %d\n", + __func__, slot_width, slots); + + ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm tx slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + channels, slot_offset, 0, NULL); + if (ret < 0) { + pr_err("%s: failed to set tdm tx channel map, err:%d\n", + __func__, ret); + goto end; + } + } else { + ret = -EINVAL; + pr_err("%s: invalid use case, err:%d\n", + __func__, ret); + goto end; + } + + rate = params_rate(params); + clk_freq = rate * slot_width * slots; + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, clk_freq, SND_SOC_CLOCK_OUT); + if (ret < 0) + pr_err("%s: failed to set tdm clk, err:%d\n", + __func__, ret); + +end: + return ret; +} + +static int sm6150_tdm_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || + (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { + ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); + if (ret) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret); + } + + return ret; +} + +static void sm6150_tdm_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || + (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { + ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); + if (ret) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret); + } +} + +static struct snd_soc_ops sm6150_tdm_be_ops = { + .hw_params = sm6150_tdm_snd_hw_params, + .startup = sm6150_tdm_snd_startup, + .shutdown = sm6150_tdm_snd_shutdown +}; + +static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) +{ + cpumask_t mask; + + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + + cpumask_clear(&mask); + cpumask_set_cpu(1, &mask); /* affine to core 1 */ + cpumask_set_cpu(2, &mask); /* affine to core 2 */ + cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); + + substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; + + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + MSM_LL_QOS_VALUE); + return 0; +} + +static struct snd_soc_ops msm_fe_qos_ops = { + .prepare = msm_fe_qos_prepare, +}; + +static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int index = cpu_dai->id; + unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret_pinctrl = 0; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + if (index < PRIM_MI2S || index >= MI2S_MAX) { + ret = -EINVAL; + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto err; + } + /* + * Mutex protection in case the same MI2S + * interface using for both TX and RX so + * that the same clock won't be enable twice. + */ + mutex_lock(&mi2s_intf_conf[index].lock); + if (++mi2s_intf_conf[index].ref_cnt == 1) { + /* Check if msm needs to provide the clock to the interface */ + if (!mi2s_intf_conf[index].msm_is_mi2s_master) { + mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; + fmt = SND_SOC_DAIFMT_CBM_CFM; + } + ret = msm_mi2s_set_sclk(substream, true); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed to enable MI2S clock, err:%d\n", + __func__, ret); + goto clean_up; + } + + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) { + pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n", + __func__, index, ret); + goto clk_off; + } + if (index == QUAT_MI2S) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_MI2S_ACTIVE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } + } +clk_off: + if (ret < 0) + msm_mi2s_set_sclk(substream, false); +clean_up: + if (ret < 0) + mi2s_intf_conf[index].ref_cnt--; + mutex_unlock(&mi2s_intf_conf[index].lock); +err: + return ret; +} + +static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int index = rtd->cpu_dai->id; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret_pinctrl = 0; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + if (index < PRIM_MI2S || index >= MI2S_MAX) { + pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); + return; + } + + mutex_lock(&mi2s_intf_conf[index].lock); + if (--mi2s_intf_conf[index].ref_cnt == 0) { + ret = msm_mi2s_set_sclk(substream, false); + if (ret < 0) + pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", + __func__, index, ret); + if (index == QUAT_MI2S) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_DISABLE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } + } + mutex_unlock(&mi2s_intf_conf[index].lock); +} + +static struct snd_soc_ops msm_mi2s_be_ops = { + .startup = msm_mi2s_snd_startup, + .shutdown = msm_mi2s_snd_shutdown, +}; + +static struct snd_soc_ops msm_cdc_dma_be_ops = { + .hw_params = msm_snd_cdc_dma_hw_params, +}; + +static struct snd_soc_ops msm_be_ops = { + .hw_params = msm_snd_hw_params, +}; + +static struct snd_soc_ops msm_slimbus_2_be_ops = { + .hw_params = msm_slimbus_2_hw_params, +}; + +static struct snd_soc_ops msm_wcn_ops = { + .hw_params = msm_wcn_hw_params, +}; + + +/* Digital audio interface glue - connects codec <---> CPU */ +static struct snd_soc_dai_link msm_common_dai_links[] = { + /* FrontEnd DAI Links */ + { + .name = MSM_DAILINK_NAME(Media1), + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, + { + .name = MSM_DAILINK_NAME(Media2), + .stream_name = "MultiMedia2", + .cpu_dai_name = "MultiMedia2", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, + }, + { + .name = "VoiceMMode1", + .stream_name = "VoiceMMode1", + .cpu_dai_name = "VoiceMMode1", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE1, + }, + { + .name = "MSM VoIP", + .stream_name = "VoIP", + .cpu_dai_name = "VoIP", + .platform_name = "msm-voip-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_VOIP, + }, + { + .name = MSM_DAILINK_NAME(ULL), + .stream_name = "MultiMedia3", + .cpu_dai_name = "MultiMedia3", + .platform_name = "msm-pcm-dsp.2", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA3, + }, + /* Hostless PCM purpose */ + { + .name = "SLIMBUS_0 Hostless", + .stream_name = "SLIMBUS_0 Hostless", + .cpu_dai_name = "SLIMBUS0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "MSM AFE-PCM RX", + .stream_name = "AFE-PROXY RX", + .cpu_dai_name = "msm-dai-q6-dev.241", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .platform_name = "msm-pcm-afe", + .dpcm_playback = 1, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + }, + { + .name = "MSM AFE-PCM TX", + .stream_name = "AFE-PROXY TX", + .cpu_dai_name = "msm-dai-q6-dev.240", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .platform_name = "msm-pcm-afe", + .dpcm_capture = 1, + .ignore_suspend = 1, + }, + { + .name = MSM_DAILINK_NAME(Compress1), + .stream_name = "Compress1", + .cpu_dai_name = "MultiMedia4", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA4, + }, + { + .name = "AUXPCM Hostless", + .stream_name = "AUXPCM Hostless", + .cpu_dai_name = "AUXPCM_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_1 Hostless", + .stream_name = "SLIMBUS_1 Hostless", + .cpu_dai_name = "SLIMBUS1_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_3 Hostless", + .stream_name = "SLIMBUS_3 Hostless", + .cpu_dai_name = "SLIMBUS3_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_4 Hostless", + .stream_name = "SLIMBUS_4 Hostless", + .cpu_dai_name = "SLIMBUS4_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = MSM_DAILINK_NAME(LowLatency), + .stream_name = "MultiMedia5", + .cpu_dai_name = "MultiMedia5", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .ops = &msm_fe_qos_ops, + }, + { + .name = "Listen 1 Audio Service", + .stream_name = "Listen 1 Audio Service", + .cpu_dai_name = "LSM1", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM1, + }, + /* Multiple Tunnel instances */ + { + .name = MSM_DAILINK_NAME(Compress2), + .stream_name = "Compress2", + .cpu_dai_name = "MultiMedia7", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA7, + }, + { + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", + .cpu_dai_name = "MultiMedia10", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA10, + }, + { + .name = MSM_DAILINK_NAME(ULL_NOIRQ), + .stream_name = "MM_NOIRQ", + .cpu_dai_name = "MultiMedia8", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + .ops = &msm_fe_qos_ops, + }, + /* HDMI Hostless */ + { + .name = "HDMI_RX_HOSTLESS", + .stream_name = "HDMI_RX_HOSTLESS", + .cpu_dai_name = "HDMI_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "VoiceMMode2", + .stream_name = "VoiceMMode2", + .cpu_dai_name = "VoiceMMode2", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE2, + }, + /* LSM FE */ + { + .name = "Listen 2 Audio Service", + .stream_name = "Listen 2 Audio Service", + .cpu_dai_name = "LSM2", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM2, + }, + { + .name = "Listen 3 Audio Service", + .stream_name = "Listen 3 Audio Service", + .cpu_dai_name = "LSM3", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM3, + }, + { + .name = "Listen 4 Audio Service", + .stream_name = "Listen 4 Audio Service", + .cpu_dai_name = "LSM4", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM4, + }, + { + .name = "Listen 5 Audio Service", + .stream_name = "Listen 5 Audio Service", + .cpu_dai_name = "LSM5", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM5, + }, + { + .name = "Listen 6 Audio Service", + .stream_name = "Listen 6 Audio Service", + .cpu_dai_name = "LSM6", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM6, + }, + { + .name = "Listen 7 Audio Service", + .stream_name = "Listen 7 Audio Service", + .cpu_dai_name = "LSM7", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM7, + }, + { + .name = "Listen 8 Audio Service", + .stream_name = "Listen 8 Audio Service", + .cpu_dai_name = "LSM8", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM8, + }, + { + .name = MSM_DAILINK_NAME(Media9), + .stream_name = "MultiMedia9", + .cpu_dai_name = "MultiMedia9", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA9, + }, + { + .name = MSM_DAILINK_NAME(Compress4), + .stream_name = "Compress4", + .cpu_dai_name = "MultiMedia11", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA11, + }, + { + .name = MSM_DAILINK_NAME(Compress5), + .stream_name = "Compress5", + .cpu_dai_name = "MultiMedia12", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA12, + }, + { + .name = MSM_DAILINK_NAME(Compress6), + .stream_name = "Compress6", + .cpu_dai_name = "MultiMedia13", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA13, + }, + { + .name = MSM_DAILINK_NAME(Compress7), + .stream_name = "Compress7", + .cpu_dai_name = "MultiMedia14", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA14, + }, + { + .name = MSM_DAILINK_NAME(Compress8), + .stream_name = "Compress8", + .cpu_dai_name = "MultiMedia15", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA15, + }, + { + .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), + .stream_name = "MM_NOIRQ_2", + .cpu_dai_name = "MultiMedia16", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA16, + }, + { + .name = "SLIMBUS_8 Hostless", + .stream_name = "SLIMBUS8_HOSTLESS Capture", + .cpu_dai_name = "SLIMBUS8_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +}; + + +static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_4_TX, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_vifeedback", + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + }, + /* Ultrasound RX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Playback", + .stream_name = "SLIMBUS_2 Hostless Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx2", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_slimbus_2_be_ops, + }, + /* Ultrasound TX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Capture", + .stream_name = "SLIMBUS_2 Hostless Capture", + .cpu_dai_name = "msm-dai-q6-dev.16389", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx2", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_slimbus_2_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_bolero_fe_dai_links[] = { + { + .name = LPASS_BE_WSA_CDC_DMA_TX_0, + .stream_name = "WSA CDC DMA0 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45057", + .platform_name = "msm-pcm-hostless", + .codec_name = "bolero_codec", + .codec_dai_name = "wsa_macro_vifeedback", + .id = MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_cdc_dma_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { + { + .name = MSM_DAILINK_NAME(ASM Loopback), + .stream_name = "MultiMedia6", + .cpu_dai_name = "MultiMedia6", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA6, + }, + { + .name = "USB Audio Hostless", + .stream_name = "USB Audio Hostless", + .cpu_dai_name = "USBAUDIO_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +}; + +static struct snd_soc_dai_link msm_common_be_dai_links[] = { + /* Backend AFE DAI Links */ + { + .name = LPASS_BE_AFE_PCM_RX, + .stream_name = "AFE Playback", + .cpu_dai_name = "msm-dai-q6-dev.224", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AFE_PCM_TX, + .stream_name = "AFE Capture", + .cpu_dai_name = "msm-dai-q6-dev.225", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Uplink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_TX, + .stream_name = "Voice Uplink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32772", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Downlink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_RX, + .stream_name = "Voice Downlink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32771", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music BACK END DAI Link */ + { + .name = LPASS_BE_VOICE_PLAYBACK_TX, + .stream_name = "Voice Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32773", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + /* Incall Music 2 BACK END DAI Link */ + { + .name = LPASS_BE_VOICE2_PLAYBACK_TX, + .stream_name = "Voice2 Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32770", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_RX, + .stream_name = "USB Audio Playback", + .cpu_dai_name = "msm-dai-q6-dev.28672", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_USB_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_TX, + .stream_name = "USB Audio Capture", + .cpu_dai_name = "msm-dai-q6-dev.28673", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_USB_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_0, + .stream_name = "Primary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36864", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &sm6150_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_0, + .stream_name = "Primary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36865", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &sm6150_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_0, + .stream_name = "Secondary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36880", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &sm6150_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_0, + .stream_name = "Secondary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36881", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &sm6150_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_0, + .stream_name = "Tertiary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36896", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &sm6150_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_0, + .stream_name = "Tertiary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36897", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &sm6150_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_0, + .stream_name = "Quaternary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36912", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sm6150_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_0, + .stream_name = "Quaternary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36913", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &sm6150_tdm_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_tavil_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_tavil_init, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_1_RX, + .stream_name = "Slimbus1 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16386", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_1_TX, + .stream_name = "Slimbus1 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16387", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx3", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_2_RX, + .stream_name = "Slimbus2 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx2", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_2_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_RX, + .stream_name = "Slimbus3 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16390", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_TX, + .stream_name = "Slimbus3 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16391", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_4_RX, + .stream_name = "Slimbus4 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16392", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_5_RX, + .stream_name = "Slimbus5 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16394", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx3", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* MAD BE */ + { + .name = LPASS_BE_SLIMBUS_5_TX, + .stream_name = "Slimbus5 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16395", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_mad1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_6_RX, + .stream_name = "Slimbus6 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16396", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx4", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* Slimbus VI Recording */ + { + .name = LPASS_BE_SLIMBUS_TX_VI, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_vifeedback", + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + .no_pcm = 1, + .dpcm_capture = 1, + }, +}; + +static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_7_RX, + .stream_name = "Slimbus7 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16398", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + /* BT codec driver determines capabilities based on + * dai name, bt codecdai name should always contains + * supported usecase information + */ + .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_7_TX, + .stream_name = "Slimbus7 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16399", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_bt_sco_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_8_TX, + .stream_name = "Slimbus8 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16401", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_fm_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_8_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .init = &msm_wcn_init, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link ext_disp_be_dai_link[] = { + /* DISP PORT BACK END DAI Link */ + { + .name = LPASS_BE_DISPLAY_PORT, + .stream_name = "Display Port Playback", + .cpu_dai_name = "msm-dai-q6-dp.24608", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-ext-disp-audio-codec-rx", + .codec_dai_name = "msm_dp_audio_codec_rx_dai", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { + { + .name = LPASS_BE_PRI_MI2S_RX, + .stream_name = "Primary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_MI2S_TX, + .stream_name = "Primary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX, + .stream_name = "Secondary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX, + .stream_name = "Secondary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX, + .stream_name = "Tertiary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX, + .stream_name = "Tertiary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX, + .stream_name = "Quaternary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_RX, + .stream_name = "Quinary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_TX, + .stream_name = "Quinary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + +}; + +static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { + /* Primary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_AUXPCM_RX, + .stream_name = "AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AUXPCM_TX, + .stream_name = "AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Secondary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_SEC_AUXPCM_RX, + .stream_name = "Sec AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_AUXPCM_TX, + .stream_name = "Sec AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Tertiary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_TERT_AUXPCM_RX, + .stream_name = "Tert AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_AUXPCM_TX, + .stream_name = "Tert AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Quaternary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUAT_AUXPCM_RX, + .stream_name = "Quat AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_AUXPCM_TX, + .stream_name = "Quat AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Quinary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUIN_AUXPCM_RX, + .stream_name = "Quin AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_AUXPCM_TX, + .stream_name = "Quin AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = { + /* WSA CDC DMA Backend DAI Links */ + { + .name = LPASS_BE_WSA_CDC_DMA_RX_0, + .stream_name = "WSA CDC DMA0 Playback", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45056", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "wsa_macro_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .init = &msm_int_audrx_init, + .id = MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_WSA_CDC_DMA_RX_1, + .stream_name = "WSA CDC DMA1 Playback", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45058", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "wsa_macro_rx_mix", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_WSA_CDC_DMA_TX_1, + .stream_name = "WSA CDC DMA1 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45059", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "wsa_macro_echo", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_WSA_CDC_DMA_TX_2, + .stream_name = "WSA CDC DMA2 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45061", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { + /* RX CDC DMA Backend DAI Links */ + { + .name = LPASS_BE_RX_CDC_DMA_RX_0, + .stream_name = "RX CDC DMA0 Playback", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45120", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "rx_macro_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .init = &msm_int_audrx_init, + .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_RX_CDC_DMA_RX_1, + .stream_name = "RX CDC DMA1 Playback", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45122", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "rx_macro_rx2", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_RX_CDC_DMA_RX_2, + .stream_name = "RX CDC DMA2 Playback", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45124", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "rx_macro_rx3", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_RX_CDC_DMA_RX_3, + .stream_name = "RX CDC DMA3 Playback", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45126", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "rx_macro_rx4", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + /* TX CDC DMA Backend DAI Links */ + { + .name = LPASS_BE_TX_CDC_DMA_TX_3, + .stream_name = "TX CDC DMA3 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45127", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "tx_macro_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .init = &msm_int_audrx_init, + .id = MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_TX_CDC_DMA_TX_4, + .stream_name = "TX CDC DMA4 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45129", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "tx_macro_tx2", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_sm6150_dai_links[ + ARRAY_SIZE(msm_common_dai_links) + + ARRAY_SIZE(msm_tavil_fe_dai_links) + + ARRAY_SIZE(msm_bolero_fe_dai_links) + + ARRAY_SIZE(msm_common_misc_fe_dai_links) + + ARRAY_SIZE(msm_common_be_dai_links) + + ARRAY_SIZE(msm_tavil_be_dai_links) + + ARRAY_SIZE(msm_wcn_be_dai_links) + + ARRAY_SIZE(ext_disp_be_dai_link) + + ARRAY_SIZE(msm_mi2s_be_dai_links) + + ARRAY_SIZE(msm_auxpcm_be_dai_links) + + ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links) + + ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links)]; + +static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) +{ + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + void *mbhc_calibration; + + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err_pcm_runtime; + } + + mbhc_calibration = def_wcd_mbhc_cal(); + if (!mbhc_calibration) { + ret = -ENOMEM; + goto err_mbhc_cal; + } + wcd_mbhc_cfg.calibration = mbhc_calibration; + ret = tavil_mbhc_hs_detect(rtd->codec, &wcd_mbhc_cfg); + if (ret) { + dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", + __func__, ret); + goto err_hs_detect; + } + return 0; + +err_hs_detect: + kfree(mbhc_calibration); +err_mbhc_cal: +err_pcm_runtime: + return ret; +} + + +static int msm_populate_dai_link_component_of_node( + struct snd_soc_card *card) +{ + int i, index, ret = 0; + struct device *cdev = card->dev; + struct snd_soc_dai_link *dai_link = card->dai_link; + struct device_node *np; + + if (!cdev) { + pr_err("%s: Sound card device memory NULL\n", __func__); + return -ENODEV; + } + + for (i = 0; i < card->num_links; i++) { + if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) + continue; + + /* populate platform_of_node for snd card dai links */ + if (dai_link[i].platform_name && + !dai_link[i].platform_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-platform-names", + dai_link[i].platform_name); + if (index < 0) { + pr_err("%s: No match found for platform name: %s\n", + __func__, dai_link[i].platform_name); + ret = index; + goto err; + } + np = of_parse_phandle(cdev->of_node, "asoc-platform", + index); + if (!np) { + pr_err("%s: retrieving phandle for platform %s, index %d failed\n", + __func__, dai_link[i].platform_name, + index); + ret = -ENODEV; + goto err; + } + dai_link[i].platform_of_node = np; + dai_link[i].platform_name = NULL; + } + + /* populate cpu_of_node for snd card dai links */ + if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-cpu-names", + dai_link[i].cpu_dai_name); + if (index >= 0) { + np = of_parse_phandle(cdev->of_node, "asoc-cpu", + index); + if (!np) { + pr_err("%s: retrieving phandle for cpu dai %s failed\n", + __func__, + dai_link[i].cpu_dai_name); + ret = -ENODEV; + goto err; + } + dai_link[i].cpu_of_node = np; + dai_link[i].cpu_dai_name = NULL; + } + } + + /* populate codec_of_node for snd card dai links */ + if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-codec-names", + dai_link[i].codec_name); + if (index < 0) + continue; + np = of_parse_phandle(cdev->of_node, "asoc-codec", + index); + if (!np) { + pr_err("%s: retrieving phandle for codec %s failed\n", + __func__, dai_link[i].codec_name); + ret = -ENODEV; + goto err; + } + dai_link[i].codec_of_node = np; + dai_link[i].codec_name = NULL; + } + } + +err: + return ret; +} + +static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + struct snd_soc_codec *codec = rtd->codec; + + ret = snd_soc_add_codec_controls(codec, msm_tavil_snd_controls, + ARRAY_SIZE(msm_tavil_snd_controls)); + if (ret < 0) { + dev_err(codec->dev, + "%s: add_codec_controls failed, err = %d\n", + __func__, ret); + return ret; + } + + return 0; +} + +static int msm_snd_stub_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + + int ret = 0; + unsigned int rx_ch[] = {144, 145, 146, 147, 148, 149, 150, + 151}; + unsigned int tx_ch[] = {128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143}; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + slim_rx_cfg[SLIM_RX_0].channels, + rx_ch); + if (ret < 0) + pr_err("%s: RX failed to set cpu chan map error %d\n", + __func__, ret); + } else { + ret = snd_soc_dai_set_channel_map(cpu_dai, + slim_tx_cfg[SLIM_TX_0].channels, + tx_ch, 0, 0); + if (ret < 0) + pr_err("%s: TX failed to set cpu chan map error %d\n", + __func__, ret); + } + + return ret; +} + +static struct snd_soc_ops msm_stub_be_ops = { + .hw_params = msm_snd_stub_hw_params, +}; + +static struct snd_soc_dai_link msm_stub_fe_dai_links[] = { + + /* FrontEnd DAI Links */ + { + .name = "MSMSTUB Media1", + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, +}; + +static struct snd_soc_dai_link msm_stub_be_dai_links[] = { + + /* Backend DAI Links */ + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_stub_init, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, /* dai link has playback support */ + .ignore_suspend = 1, + .ops = &msm_stub_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_stub_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_stub_dai_links[ + ARRAY_SIZE(msm_stub_fe_dai_links) + + ARRAY_SIZE(msm_stub_be_dai_links)]; + +struct snd_soc_card snd_soc_card_stub_msm = { + .name = "sm6150-stub-snd-card", +}; + +static const struct of_device_id sm6150_asoc_machine_of_match[] = { + { .compatible = "qcom,sm6150-asoc-snd", + .data = "codec"}, + { .compatible = "qcom,sm6150-asoc-snd-stub", + .data = "stub_codec"}, + {}, +}; + +static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) +{ + struct snd_soc_card *card = NULL; + struct snd_soc_dai_link *dailink; + int total_links = 0; + const struct of_device_id *match; + + match = of_match_node(sm6150_asoc_machine_of_match, dev->of_node); + if (!match) { + dev_err(dev, "%s: No DT match found for sound card\n", + __func__); + return NULL; + } + + if (!strcmp(match->data, "codec")) { + card = &snd_soc_card_sm6150_msm; + memcpy(msm_sm6150_dai_links + total_links, + msm_common_dai_links, + sizeof(msm_common_dai_links)); + + total_links += ARRAY_SIZE(msm_common_dai_links); + + memcpy(msm_sm6150_dai_links + total_links, + msm_common_misc_fe_dai_links, + sizeof(msm_common_misc_fe_dai_links)); + + total_links += ARRAY_SIZE(msm_common_misc_fe_dai_links); + + if (of_property_read_bool(dev->of_node, "qcom,tavil_codec")) { + + dev_dbg(dev, "%s(): Tavil codec is present\n", + __func__); + card->late_probe = msm_snd_card_tavil_late_probe; + memcpy(msm_sm6150_dai_links + total_links, + msm_tavil_fe_dai_links, + sizeof(msm_tavil_fe_dai_links)); + total_links += ARRAY_SIZE(msm_tavil_fe_dai_links); + } else { + memcpy(msm_sm6150_dai_links + total_links, + msm_bolero_fe_dai_links, + sizeof(msm_bolero_fe_dai_links)); + total_links += ARRAY_SIZE(msm_bolero_fe_dai_links); + } + + memcpy(msm_sm6150_dai_links + total_links, + msm_common_be_dai_links, + sizeof(msm_common_be_dai_links)); + + total_links += ARRAY_SIZE(msm_common_be_dai_links); + + if (of_property_read_bool(dev->of_node, "qcom,tavil_codec")) { + memcpy(msm_sm6150_dai_links + total_links, + msm_tavil_be_dai_links, + sizeof(msm_tavil_be_dai_links)); + total_links += ARRAY_SIZE(msm_tavil_be_dai_links); + } else { + memcpy(msm_sm6150_dai_links + total_links, + msm_wsa_cdc_dma_be_dai_links, + sizeof(msm_wsa_cdc_dma_be_dai_links)); + total_links += ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links); + + memcpy(msm_sm6150_dai_links + total_links, + msm_rx_tx_cdc_dma_be_dai_links, + sizeof(msm_rx_tx_cdc_dma_be_dai_links)); + total_links += + ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links); + } + + if (of_property_read_bool(dev->of_node, + "qcom,ext-disp-audio-rx")) { + dev_dbg(dev, "%s(): External display audio support present\n", + __func__); + memcpy(msm_sm6150_dai_links + total_links, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + total_links += ARRAY_SIZE(ext_disp_be_dai_link); + } + if (of_property_read_bool(dev->of_node, + "qcom,mi2s-audio-intf")) { + memcpy(msm_sm6150_dai_links + total_links, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,auxpcm-audio-intf")) { + memcpy(msm_sm6150_dai_links + total_links, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + dev_dbg(dev, "%s(): WCN BTFM support present\n", + __func__); + memcpy(msm_sm6150_dai_links + total_links, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + total_links += ARRAY_SIZE(msm_wcn_be_dai_links); + } + dailink = msm_sm6150_dai_links; + } else if (!strcmp(match->data, "stub_codec")) { + card = &snd_soc_card_stub_msm; + + memcpy(msm_stub_dai_links + total_links, + msm_stub_fe_dai_links, + sizeof(msm_stub_fe_dai_links)); + total_links += ARRAY_SIZE(msm_stub_fe_dai_links); + + memcpy(msm_stub_dai_links + total_links, + msm_stub_be_dai_links, + sizeof(msm_stub_be_dai_links)); + total_links += ARRAY_SIZE(msm_stub_be_dai_links); + + dailink = msm_stub_dai_links; + } + + if (card) { + card->dai_link = dailink; + card->num_links = total_links; + } + + return card; +} + +static int msm_wsa881x_init(struct snd_soc_component *component) +{ + u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {0, 1, 2, 3}; + u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {0, 1, 2, 3}; + u8 spkleft_port_types[WSA881X_MAX_SWR_PORTS] = {SPKR_L, SPKR_L_COMP, + SPKR_L_BOOST, SPKR_L_VI}; + u8 spkright_port_types[WSA881X_MAX_SWR_PORTS] = {SPKR_R, SPKR_R_COMP, + SPKR_R_BOOST, SPKR_R_VI}; + unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; + unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + struct msm_asoc_mach_data *pdata; + struct snd_soc_dapm_context *dapm; + int ret = 0; + + if (!codec) { + pr_err("%s codec is NULL\n", __func__); + return -EINVAL; + } + + dapm = snd_soc_codec_get_dapm(codec); + + if (!strcmp(component->name_prefix, "SpkrLeft")) { + dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n", + __func__, codec->component.name); + wsa881x_set_channel_map(codec, &spkleft_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0], &spkleft_port_types[0]); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); + } + } else if (!strcmp(component->name_prefix, "SpkrRight")) { + dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n", + __func__, codec->component.name); + wsa881x_set_channel_map(codec, &spkright_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0], &spkright_port_types[0]); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); + } + } else { + dev_err(codec->dev, "%s: wrong codec name %s\n", __func__, + codec->component.name); + ret = -EINVAL; + goto err; + } + pdata = snd_soc_card_get_drvdata(component->card); + if (pdata && pdata->codec_root) + wsa881x_codec_info_create_codec_entry(pdata->codec_root, + codec); + +err: + return ret; +} + +static int msm_aux_codec_init(struct snd_soc_component *component) +{ + return 0; +} + +static int msm_init_aux_dev(struct platform_device *pdev, + struct snd_soc_card *card) +{ + struct device_node *wsa_of_node; + struct device_node *aux_codec_of_node; + u32 wsa_max_devs; + u32 wsa_dev_cnt; + u32 codec_aux_dev_cnt = 0; + int i; + struct msm_wsa881x_dev_info *wsa881x_dev_info; + struct aux_codec_dev_info *aux_cdc_dev_info; + const char *auxdev_name_prefix[1]; + char *dev_name_str = NULL; + int found = 0; + int codecs_found = 0; + int ret = 0; + + /* Get maximum WSA device count for this platform */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,wsa-max-devs", &wsa_max_devs); + if (ret) { + dev_info(&pdev->dev, + "%s: wsa-max-devs property missing in DT %s, ret = %d\n", + __func__, pdev->dev.of_node->full_name, ret); + wsa_max_devs = 0; + goto codec_aux_dev; + } + if (wsa_max_devs == 0) { + dev_warn(&pdev->dev, + "%s: Max WSA devices is 0 for this target?\n", + __func__); + goto codec_aux_dev; + } + + /* Get count of WSA device phandles for this platform */ + wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node, + "qcom,wsa-devs", NULL); + if (wsa_dev_cnt == -ENOENT) { + dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n", + __func__); + goto err; + } else if (wsa_dev_cnt <= 0) { + dev_err(&pdev->dev, + "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n", + __func__, wsa_dev_cnt); + ret = -EINVAL; + goto err; + } + + /* + * Expect total phandles count to be NOT less than maximum possible + * WSA count. However, if it is less, then assign same value to + * max count as well. + */ + if (wsa_dev_cnt < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n", + __func__, wsa_max_devs, wsa_dev_cnt); + wsa_max_devs = wsa_dev_cnt; + } + + /* Make sure prefix string passed for each WSA device */ + ret = of_property_count_strings(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix"); + if (ret != wsa_dev_cnt) { + dev_err(&pdev->dev, + "%s: expecting %d wsa prefix. Defined only %d in DT\n", + __func__, wsa_dev_cnt, ret); + ret = -EINVAL; + goto err; + } + + /* + * Alloc mem to store phandle and index info of WSA device, if already + * registered with ALSA core + */ + wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs, + sizeof(struct msm_wsa881x_dev_info), + GFP_KERNEL); + if (!wsa881x_dev_info) { + ret = -ENOMEM; + goto err; + } + + /* + * search and check whether all WSA devices are already + * registered with ALSA core or not. If found a node, store + * the node and the index in a local array of struct for later + * use. + */ + for (i = 0; i < wsa_dev_cnt; i++) { + wsa_of_node = of_parse_phandle(pdev->dev.of_node, + "qcom,wsa-devs", i); + if (unlikely(!wsa_of_node)) { + /* we should not be here */ + dev_err(&pdev->dev, + "%s: wsa dev node is not present\n", + __func__); + ret = -EINVAL; + goto err; + } + if (soc_find_component(wsa_of_node, NULL)) { + /* WSA device registered with ALSA core */ + wsa881x_dev_info[found].of_node = wsa_of_node; + wsa881x_dev_info[found].index = i; + found++; + if (found == wsa_max_devs) + break; + } + } + + if (found < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: failed to find %d components. Found only %d\n", + __func__, wsa_max_devs, found); + return -EPROBE_DEFER; + } + dev_info(&pdev->dev, + "%s: found %d wsa881x devices registered with ALSA core\n", + __func__, found); + +codec_aux_dev: + if (strcmp(card->name, "sm6150-tavil-snd-card")) { + /* Get count of aux codec device phandles for this platform */ + codec_aux_dev_cnt = of_count_phandle_with_args( + pdev->dev.of_node, + "qcom,codec-aux-devs", NULL); + if (codec_aux_dev_cnt == -ENOENT) { + dev_warn(&pdev->dev, "%s: No aux codec defined in DT.\n", + __func__); + goto err; + } else if (codec_aux_dev_cnt <= 0) { + dev_err(&pdev->dev, + "%s: Error reading aux codec device from DT, dev_cnt=%d\n", + __func__, codec_aux_dev_cnt); + ret = -EINVAL; + goto err; + } + + /* + * Alloc mem to store phandle and index info of aux codec + * if already registered with ALSA core + */ + aux_cdc_dev_info = devm_kcalloc(&pdev->dev, codec_aux_dev_cnt, + sizeof(struct aux_codec_dev_info), + GFP_KERNEL); + if (!aux_cdc_dev_info) { + ret = -ENOMEM; + goto err; + } + + /* + * search and check whether all aux codecs are already + * registered with ALSA core or not. If found a node, store + * the node and the index in a local array of struct for later + * use. + */ + for (i = 0; i < codec_aux_dev_cnt; i++) { + aux_codec_of_node = of_parse_phandle(pdev->dev.of_node, + "qcom,codec-aux-devs", i); + if (unlikely(!aux_codec_of_node)) { + /* we should not be here */ + dev_err(&pdev->dev, + "%s: aux codec dev node is not present\n", + __func__); + ret = -EINVAL; + goto err; + } + if (soc_find_component(aux_codec_of_node, NULL)) { + /* AUX codec registered with ALSA core */ + aux_cdc_dev_info[codecs_found].of_node = + aux_codec_of_node; + aux_cdc_dev_info[codecs_found].index = i; + codecs_found++; + } + } + + if (codecs_found < codec_aux_dev_cnt) { + dev_dbg(&pdev->dev, + "%s: failed to find %d components. Found only %d\n", + __func__, codec_aux_dev_cnt, codecs_found); + return -EPROBE_DEFER; + } + dev_info(&pdev->dev, + "%s: found %d AUX codecs registered with ALSA core\n", + __func__, codecs_found); + + } + + card->num_aux_devs = wsa_max_devs + codec_aux_dev_cnt; + card->num_configs = wsa_max_devs + codec_aux_dev_cnt; + + /* Alloc array of AUX devs struct */ + msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_aux_dev), + GFP_KERNEL); + if (!msm_aux_dev) { + ret = -ENOMEM; + goto err; + } + + /* Alloc array of codec conf struct */ + msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_configs, + sizeof(struct snd_soc_codec_conf), + GFP_KERNEL); + if (!msm_codec_conf) { + ret = -ENOMEM; + goto err; + } + + for (i = 0; i < wsa_max_devs; i++) { + dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN, + GFP_KERNEL); + if (!dev_name_str) { + ret = -ENOMEM; + goto err; + } + + ret = of_property_read_string_index(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix", + wsa881x_dev_info[i].index, + auxdev_name_prefix); + if (ret) { + dev_err(&pdev->dev, + "%s: failed to read wsa aux dev prefix, ret = %d\n", + __func__, ret); + ret = -EINVAL; + goto err; + } + + snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i); + msm_aux_dev[i].name = dev_name_str; + msm_aux_dev[i].codec_name = NULL; + msm_aux_dev[i].codec_of_node = + wsa881x_dev_info[i].of_node; + msm_aux_dev[i].init = msm_wsa881x_init; + msm_codec_conf[i].dev_name = NULL; + msm_codec_conf[i].name_prefix = auxdev_name_prefix[0]; + msm_codec_conf[i].of_node = + wsa881x_dev_info[i].of_node; + } + + for (i = 0; i < codec_aux_dev_cnt; i++) { + msm_aux_dev[wsa_max_devs + i].name = NULL; + msm_aux_dev[wsa_max_devs + i].codec_name = NULL; + msm_aux_dev[wsa_max_devs + i].codec_of_node = + aux_cdc_dev_info[i].of_node; + msm_aux_dev[wsa_max_devs + i].init = msm_aux_codec_init; + msm_codec_conf[wsa_max_devs + i].dev_name = NULL; + msm_codec_conf[wsa_max_devs + i].name_prefix = + NULL; + msm_codec_conf[wsa_max_devs + i].of_node = + aux_cdc_dev_info[i].of_node; + } + + card->codec_conf = msm_codec_conf; + card->aux_dev = msm_aux_dev; +err: + return ret; +} + +static void msm_i2s_auxpcm_init(struct platform_device *pdev) +{ + int count; + u32 mi2s_master_slave[MI2S_MAX]; + int ret; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_init(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-master", + mi2s_master_slave, MI2S_MAX); + if (ret) { + dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n", + __func__); + } else { + for (count = 0; count < MI2S_MAX; count++) { + mi2s_intf_conf[count].msm_is_mi2s_master = + mi2s_master_slave[count]; + } + } +} + +static void msm_i2s_auxpcm_deinit(void) +{ + int count; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_destroy(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + mi2s_intf_conf[count].msm_is_mi2s_master = 0; + } +} +static int msm_asoc_machine_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card; + struct msm_asoc_mach_data *pdata; + const char *mbhc_audio_jack_type = NULL; + int ret; + + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, "No platform supplied from device tree\n"); + return -EINVAL; + } + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct msm_asoc_mach_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + card = populate_snd_card_dailinks(&pdev->dev); + if (!card) { + dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); + ret = -EINVAL; + goto err; + } + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, pdata); + + ret = snd_soc_of_parse_card_name(card, "qcom,model"); + if (ret) { + dev_err(&pdev->dev, "parse card name failed, err:%d\n", + ret); + goto err; + } + + ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing"); + if (ret) { + dev_err(&pdev->dev, "parse audio routing failed, err:%d\n", + ret); + goto err; + } + + ret = msm_populate_dai_link_component_of_node(card); + if (ret) { + ret = -EPROBE_DEFER; + goto err; + } + + ret = msm_init_aux_dev(pdev, card); + if (ret) + goto err; + + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret == -EPROBE_DEFER) { + if (codec_reg_done) + ret = -EINVAL; + goto err; + } else if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); + goto err; + } + dev_info(&pdev->dev, "Sound card %s registered\n", card->name); + spdev = pdev; + + pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en1-gpio", 0); + if (!pdata->hph_en1_gpio_p) { + dev_dbg(&pdev->dev, "property %s not detected in node %s\n", + "qcom,hph-en1-gpio", + pdev->dev.of_node->full_name); + } + + pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en0-gpio", 0); + if (!pdata->hph_en0_gpio_p) { + dev_dbg(&pdev->dev, "property %s not detected in node %s\n", + "qcom,hph-en0-gpio", + pdev->dev.of_node->full_name); + } + + ret = of_property_read_string(pdev->dev.of_node, + "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type); + if (ret) { + dev_dbg(&pdev->dev, "Looking up %s property in node %s failed\n", + "qcom,mbhc-audio-jack-type", + pdev->dev.of_node->full_name); + dev_dbg(&pdev->dev, "Jack type properties set to default\n"); + } else { + if (!strcmp(mbhc_audio_jack_type, "4-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = false; + dev_dbg(&pdev->dev, "This hardware has 4 pole jack"); + } else if (!strcmp(mbhc_audio_jack_type, "5-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = true; + dev_dbg(&pdev->dev, "This hardware has 5 pole jack"); + } else if (!strcmp(mbhc_audio_jack_type, "6-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = true; + dev_dbg(&pdev->dev, "This hardware has 6 pole jack"); + } else { + wcd_mbhc_cfg.enable_anc_mic_detect = false; + dev_dbg(&pdev->dev, "Unknown value, set to default\n"); + } + } + /* + * Parse US-Euro gpio info from DT. Report no error if us-euro + * entry is not found in DT file as some targets do not support + * US-Euro detection + */ + pdata->us_euro_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,us-euro-gpios", 0); + if (!pdata->us_euro_gpio_p) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,us-euro-gpios", pdev->dev.of_node->full_name); + } else { + dev_dbg(&pdev->dev, "%s detected\n", + "qcom,us-euro-gpios"); + wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; + } + /* Parse pinctrl info from devicetree */ + ret = msm_get_pinctrl(pdev); + if (!ret) { + pr_debug("%s: pinctrl parsing successful\n", __func__); + } else { + dev_dbg(&pdev->dev, + "%s: Parsing pinctrl failed with %d. Cannot use Ports\n", + __func__, ret); + ret = 0; + } + + msm_i2s_auxpcm_init(pdev); + if (!strcmp(card->name, "sm6150-tavil-snd-card")) { + is_initial_boot = true; + ret = audio_notifier_register("sm6150", + AUDIO_NOTIFIER_ADSP_DOMAIN, + &service_nb); + if (ret < 0) + pr_err("%s: Audio notifier register failed ret = %d\n", + __func__, ret); + } else { + pdata->dmic01_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-dmic01-gpios", + 0); + pdata->dmic23_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-dmic23-gpios", + 0); + } +err: + return ret; +} + +static int msm_asoc_machine_remove(struct platform_device *pdev) +{ + audio_notifier_deregister("sm6150"); + msm_i2s_auxpcm_deinit(); + + return 0; +} + +static struct platform_driver sm6150_asoc_machine_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = sm6150_asoc_machine_of_match, + }, + .probe = msm_asoc_machine_probe, + .remove = msm_asoc_machine_remove, +}; +module_platform_driver(sm6150_asoc_machine_driver); + +MODULE_DESCRIPTION("ALSA SoC msm"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, sm6150_asoc_machine_of_match); -- GitLab From 144eabc3ee8757b49e4b51963fff09d63f9f9c6e Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 31 May 2018 10:44:53 +0530 Subject: [PATCH 0426/1645] audio: Add support for audio on msmsteppe Update config file and make rules for msmsteppe compilation. Change-Id: I374a0725a7dd36edc9e04652fb07dc719310565c Signed-off-by: Laxminath Kasam --- Android.mk | 9 ++++-- asoc/Kbuild | 12 +++++-- asoc/codecs/Kbuild | 4 +-- asoc/codecs/aqt1000/Kbuild | 5 --- asoc/codecs/wcd934x/Kbuild | 4 +-- asoc/codecs/wcd9360/Android.mk | 6 +--- asoc/codecs/wcd9360/Kbuild | 5 --- config/sm6150auto.conf | 44 ++++++++++++++++++++++++++ config/sm6150autoconf.h | 57 ++++++++++++++++++++++++++++++++++ dsp/Kbuild | 4 +-- dsp/codecs/Kbuild | 4 +-- ipc/Kbuild | 4 +-- soc/Android.mk | 2 +- soc/Kbuild | 4 +-- 14 files changed, 132 insertions(+), 32 deletions(-) create mode 100644 config/sm6150auto.conf create mode 100644 config/sm6150autoconf.h diff --git a/Android.mk b/Android.mk index 55bcbf10d14e..b4278fa6845b 100644 --- a/Android.mk +++ b/Android.mk @@ -24,11 +24,16 @@ include $(MY_LOCAL_PATH)/asoc/codecs/Android.mk include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk endif -ifeq ($(call is-board-platform-in-list,sdm670 msmnile $(MSMSTEPPE)),true) +ifeq ($(call is-board-platform-in-list,sdm670 msmnile),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/aqt1000/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/aqt1000/Android.mk endif +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE)),true) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/bolero/Module.symvers) +include $(MY_LOCAL_PATH)/asoc/codecs/bolero/Android.mk +endif + ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers) @@ -36,7 +41,7 @@ include $(MY_LOCAL_PATH)/asoc/codecs/sdm660_cdc/Android.mk include $(MY_LOCAL_PATH)/asoc/codecs/msm_sdw/Android.mk endif -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE)),true) +ifeq ($(call is-board-platform-in-list,msmnile),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd9360/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wcd9360/Android.mk endif diff --git a/asoc/Kbuild b/asoc/Kbuild index ccf2406d42bb..aa051761a14c 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -35,9 +35,9 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SM6150), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf + include $(AUDIO_ROOT)/config/sm6150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf @@ -104,6 +104,11 @@ ifdef CONFIG_SND_SOC_SM8150 MACHINE_OBJS += sm8150.o endif +# for SM6150 sound card driver +ifdef CONFIG_SND_SOC_SM6150 + MACHINE_OBJS += sm6150.o +endif + # for qcs405 sound card driver ifdef CONFIG_SND_SOC_QCS405 MACHINE_OBJS += qcs405.o @@ -200,6 +205,9 @@ machine_dlkm-y := $(MACHINE_OBJS) obj-$(CONFIG_SND_SOC_SM8150) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) +obj-$(CONFIG_SND_SOC_SM6150) += machine_dlkm.o +machine_dlkm-y := $(MACHINE_OBJS) + obj-$(CONFIG_SND_SOC_QCS405) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index f4c9c106ab15..662c62f4c529 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -35,9 +35,9 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SM6150), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf + include $(AUDIO_ROOT)/config/sm6150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf diff --git a/asoc/codecs/aqt1000/Kbuild b/asoc/codecs/aqt1000/Kbuild index 2b002df88175..6523ce6d6b09 100644 --- a/asoc/codecs/aqt1000/Kbuild +++ b/asoc/codecs/aqt1000/Kbuild @@ -28,11 +28,6 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif - ifeq ($(CONFIG_ARCH_SM6150), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h - endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index 1287dd73a3a8..5566ecbb26fb 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -32,9 +32,9 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif ifeq ($(CONFIG_ARCH_SM6150), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf + include $(AUDIO_ROOT)/config/sm6150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf diff --git a/asoc/codecs/wcd9360/Android.mk b/asoc/codecs/wcd9360/Android.mk index b7566a108054..bee0364ecd41 100644 --- a/asoc/codecs/wcd9360/Android.mk +++ b/asoc/codecs/wcd9360/Android.mk @@ -7,13 +7,9 @@ ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif -ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) -AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m -endif - AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE)),true) +ifeq ($(call is-board-platform-in-list,msmnile),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wcd9360/Kbuild b/asoc/codecs/wcd9360/Kbuild index 5b87cde49837..6bba0c525599 100644 --- a/asoc/codecs/wcd9360/Kbuild +++ b/asoc/codecs/wcd9360/Kbuild @@ -21,11 +21,6 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif - ifeq ($(CONFIG_ARCH_SM6150), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h - endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf diff --git a/config/sm6150auto.conf b/config/sm6150auto.conf new file mode 100644 index 000000000000..cd06ead71d29 --- /dev/null +++ b/config/sm6150auto.conf @@ -0,0 +1,44 @@ +CONFIG_PINCTRL_WCD=m +CONFIG_PINCTRL_LPI=m +CONFIG_AUDIO_EXT_CLK=m +CONFIG_SND_SOC_WCD9XXX_V2=m +CONFIG_SND_SOC_WCD_MBHC=m +CONFIG_SND_SOC_WSA881X=m +CONFIG_SND_SOC_WCD_DSP_MGR=m +CONFIG_SND_SOC_WCD_SPI=m +CONFIG_SND_SOC_WCD934X=m +CONFIG_SND_SOC_WCD934X_MBHC=m +CONFIG_SND_SOC_WCD934X_DSD=m +CONFIG_WCD9XXX_CODEC_CORE=m +CONFIG_MSM_CDC_PINCTRL=m +CONFIG_MSM_QDSP6V2_CODECS=m +CONFIG_MSM_ULTRASOUND=m +CONFIG_MSM_QDSP6_APRV2_RPMSG=m +CONFIG_MSM_ADSP_LOADER=m +CONFIG_REGMAP_SWR=m +CONFIG_MSM_QDSP6_SSR=m +CONFIG_MSM_QDSP6_PDR=m +CONFIG_MSM_QDSP6_NOTIFIER=m +CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +CONFIG_SND_SOC_SM6150=m +CONFIG_MSM_GLINK_SPI_XPRT=m +CONFIG_WCD_DSP_GLINK=m +CONFIG_SOUNDWIRE=m +CONFIG_SOUNDWIRE_MSTR_CTRL=m +CONFIG_SND_SOC_QDSP6V2=m +CONFIG_SND_SOC_WCD_MBHC_ADC=m +CONFIG_QTI_PP=m +CONFIG_SND_HWDEP_ROUTING=m +CONFIG_DTS_EAGLE=m +CONFIG_DOLBY_DS2=m +CONFIG_DOLBY_LICENSE=m +CONFIG_DTS_SRS_TM=m +CONFIG_SND_SOC_MSM_STUB=m +CONFIG_MSM_AVTIMER=m +CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m +CONFIG_SND_SOC_BOLERO=m +CONFIG_WSA_MACRO=m +CONFIG_VA_MACRO=m +CONFIG_RX_MACRO=m +CONFIG_TX_MACRO=m diff --git a/config/sm6150autoconf.h b/config/sm6150autoconf.h new file mode 100644 index 000000000000..f64e863ad1b4 --- /dev/null +++ b/config/sm6150autoconf.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define CONFIG_PINCTRL_WCD 1 +#define CONFIG_PINCTRL_LPI 1 +#define CONFIG_AUDIO_EXT_CLK 1 +#define CONFIG_SND_SOC_WCD9XXX_V2 1 +#define CONFIG_SND_SOC_WCD_MBHC 1 +#define CONFIG_SND_SOC_WSA881X 1 +#define CONFIG_SND_SOC_WCD_DSP_MGR 1 +#define CONFIG_SND_SOC_WCD_SPI 1 +#define CONFIG_SND_SOC_WCD934X 1 +#define CONFIG_SND_SOC_WCD934X_MBHC 1 +#define CONFIG_SND_SOC_WCD934X_DSD 1 +#define CONFIG_SND_SOC_WCD_CPE 1 +#define CONFIG_WCD9XXX_CODEC_CORE 1 +#define CONFIG_MSM_CDC_PINCTRL 1 +#define CONFIG_MSM_QDSP6V2_CODECS 1 +#define CONFIG_MSM_ULTRASOUND 1 +#define CONFIG_MSM_QDSP6_APRV2_RPMSG 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_MSM_ADSP_LOADER 1 +#define CONFIG_REGMAP_SWR 1 +#define CONFIG_MSM_QDSP6_SSR 1 +#define CONFIG_MSM_QDSP6_PDR 1 +#define CONFIG_MSM_QDSP6_NOTIFIER 1 +#define CONFIG_SND_SOC_MSM_HOSTLESS_PCM 1 +#define CONFIG_SND_SOC_SM6150 1 +#define CONFIG_MSM_GLINK_SPI_XPRT 1 +#define CONFIG_WCD_DSP_GLINK 1 +#define CONFIG_SOUNDWIRE 1 +#define CONFIG_SOUNDWIRE_MSTR_CTRL 1 +#define CONFIG_SND_SOC_WCD_MBHC_ADC 1 +#define CONFIG_SND_SOC_QDSP6V2 1 +#define CONFIG_QTI_PP 1 +#define CONFIG_SND_HWDEP_ROUTING 1 +#define CONFIG_DTS_EAGLE 1 +#define CONFIG_DOLBY_DS2 1 +#define CONFIG_DOLBY_LICENSE 1 +#define CONFIG_DTS_SRS_TM 1 +#define CONFIG_SND_SOC_MSM_STUB 1 +#define CONFIG_MSM_AVTIMER 1 +#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 +#define CONFIG_SND_SOC_BOLERO 1 +#define CONFIG_WSA_MACRO 1 +#define CONFIG_VA_MACRO 1 +#define CONFIG_RX_MACRO 1 +#define CONFIG_TX_MACRO 1 diff --git a/dsp/Kbuild b/dsp/Kbuild index 271fae463680..1cad5cea65c8 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -30,9 +30,9 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif ifeq ($(CONFIG_ARCH_SM6150), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf + include $(AUDIO_ROOT)/config/sm6150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index a65ec46275d8..7d7268b694ee 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -31,9 +31,9 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif ifeq ($(CONFIG_ARCH_SM6150), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf + include $(AUDIO_ROOT)/config/sm6150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf diff --git a/ipc/Kbuild b/ipc/Kbuild index acb60a9284bf..0c77ed8c95aa 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -31,9 +31,9 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif ifeq ($(CONFIG_ARCH_SM6150), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf + include $(AUDIO_ROOT)/config/sm6150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf diff --git a/soc/Android.mk b/soc/Android.mk index 9ce525e4c378..dc6a5b32f822 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -48,7 +48,7 @@ KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) KBUILD_OPTIONS += $(AUDIO_SELECT) ########################################################### -ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605 $(MSMSTEPPE)),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_lpi.ko LOCAL_MODULE_KBUILD_NAME := pinctrl_lpi_dlkm.ko diff --git a/soc/Kbuild b/soc/Kbuild index acee7f646540..54ca077e4936 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -35,9 +35,9 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SM6150), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf + include $(AUDIO_ROOT)/config/sm6150auto.conf export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf -- GitLab From 7259ca6cfed084419b6a02c172b03bf96fe02416 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 30 Jul 2018 12:03:03 +0530 Subject: [PATCH 0427/1645] asoc: audio-ext-clk: Add support for multiple lpass clock sources In bolero, Rx and Tx macros require multiple lpass clock sources. Update audio clock driver to support multiple lpass clock instances as required for Rx and Tx macros. Change-Id: Ia7d766c52c8edb65f3ceb0585c6fd5a2fee6c5a6 Signed-off-by: Aditya Bavanari --- asoc/codecs/audio-ext-clk-up.c | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index 2664b15b590a..0c02e14d7dce 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -29,6 +29,10 @@ enum { AUDIO_EXT_CLK_LPASS, AUDIO_EXT_CLK_LPASS2, AUDIO_EXT_CLK_LPASS3, + AUDIO_EXT_CLK_LPASS4, + AUDIO_EXT_CLK_LPASS5, + AUDIO_EXT_CLK_LPASS6, + AUDIO_EXT_CLK_LPASS7, AUDIO_EXT_CLK_LPASS_MAX, AUDIO_EXT_CLK_MAX = AUDIO_EXT_CLK_LPASS_MAX, }; @@ -211,6 +215,50 @@ static struct audio_ext_clk audio_clk_array[] = { }, }, }, + { + .pnctrl_info = {NULL}, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_lpass_mclk4", + .ops = &audio_ext_clk_ops, + }, + }, + }, + { + .pnctrl_info = {NULL}, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_lpass_mclk5", + .ops = &audio_ext_clk_ops, + }, + }, + }, + { + .pnctrl_info = {NULL}, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_lpass_mclk6", + .ops = &audio_ext_clk_ops, + }, + }, + }, + { + .pnctrl_info = {NULL}, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_lpass_mclk7", + .ops = &audio_ext_clk_ops, + }, + }, + }, }; static int audio_get_pinctrl(struct platform_device *pdev) -- GitLab From 485ec2c8513468a1b8dbd4ba7cda139604291589 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 9 Jul 2018 19:34:44 +0530 Subject: [PATCH 0428/1645] ASoC: codecs: Add IRQ utils support based on regmap Add irq utils support for tanggu codec. It is based on regmap-irq framework. Change-Id: I93ad71f41a8bf62313bee5b6c374809c93219f5c Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd-irq.c | 191 +++++++++++++++++++++++++++++++++++++++++ include/asoc/wcd-irq.h | 63 ++++++++++++++ 2 files changed, 254 insertions(+) create mode 100644 asoc/codecs/wcd-irq.c create mode 100644 include/asoc/wcd-irq.h diff --git a/asoc/codecs/wcd-irq.c b/asoc/codecs/wcd-irq.c new file mode 100644 index 000000000000..12bbf36a5209 --- /dev/null +++ b/asoc/codecs/wcd-irq.c @@ -0,0 +1,191 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int wcd_map_irq(struct wcd_irq_info *irq_info, int irq) +{ + if (!irq_info) { + pr_err("%s: Null IRQ handle\n", __func__); + return -EINVAL; + } + return regmap_irq_get_virq(irq_info->irq_chip, irq); +} + +/** + * wcd_request_irq: Request a thread handler for the given IRQ + * @irq_info: pointer to IRQ info structure + * @irq: irq number + * @name: name for the IRQ thread + * @handler: irq handler + * @data: data pointer + * + * Returns 0 on success or error on failure + */ +int wcd_request_irq(struct wcd_irq_info *irq_info, int irq, const char *name, + irq_handler_t handler, void *data) +{ + if (!irq_info) { + pr_err("%s: Null IRQ handle\n", __func__); + return -EINVAL; + } + irq = wcd_map_irq(irq_info, irq); + if (irq < 0) + return irq; + + return request_threaded_irq(irq, NULL, handler, + IRQF_ONESHOT | IRQF_TRIGGER_RISING, + name, data); +} +EXPORT_SYMBOL(wcd_request_irq); + +/** + * wcd_free_irq: Free the IRQ resources allocated during request_irq + * @irq_info: pointer to IRQ info structure + * @irq: irq number + * @data: data pointer + */ +void wcd_free_irq(struct wcd_irq_info *irq_info, int irq, void *data) +{ + if (!irq_info) { + pr_err("%s: Null IRQ handle\n", __func__); + return; + } + + irq = wcd_map_irq(irq_info, irq); + if (irq < 0) + return; + + free_irq(irq, data); +} +EXPORT_SYMBOL(wcd_free_irq); + +/** + * wcd_enable_irq: Enable the given IRQ + * @irq_info: pointer to IRQ info structure + * @irq: irq number + */ +void wcd_enable_irq(struct wcd_irq_info *irq_info, int irq) +{ + if (!irq_info) + pr_err("%s: Null IRQ handle\n", __func__); + else + enable_irq(wcd_map_irq(irq_info, irq)); +} +EXPORT_SYMBOL(wcd_enable_irq); + +/** + * wcd_disable_irq: Disable the given IRQ + * @irq_info: pointer to IRQ info structure + * @irq: irq number + */ +void wcd_disable_irq(struct wcd_irq_info *irq_info, int irq) +{ + if (!irq_info) + pr_err("%s: Null IRQ handle\n", __func__); + else + disable_irq(wcd_map_irq(irq_info, irq)); +} +EXPORT_SYMBOL(wcd_disable_irq); + +static void wcd_irq_chip_disable(struct irq_data *data) +{ +} + +static void wcd_irq_chip_enable(struct irq_data *data) +{ +} + +static struct irq_chip wcd_irq_chip = { + .name = NULL, + .irq_disable = wcd_irq_chip_disable, + .irq_enable = wcd_irq_chip_enable, +}; + +static struct lock_class_key wcd_irq_lock_class; + +static int wcd_irq_chip_map(struct irq_domain *irqd, unsigned int virq, + irq_hw_number_t hw) +{ + irq_set_chip_and_handler(virq, &wcd_irq_chip, handle_simple_irq); + irq_set_lockdep_class(virq, &wcd_irq_lock_class); + irq_set_nested_thread(virq, 1); + irq_set_noprobe(virq); + + return 0; +} + +static const struct irq_domain_ops wcd_domain_ops = { + .map = wcd_irq_chip_map, +}; + +/** + * wcd_irq_init: Initializes IRQ module + * @irq_info: pointer to IRQ info structure + * + * Returns 0 on success or error on failure + */ +int wcd_irq_init(struct wcd_irq_info *irq_info, struct irq_domain **virq) +{ + int ret = 0; + + if (!irq_info) { + pr_err("%s: Null IRQ handle\n", __func__); + return -EINVAL; + } + + wcd_irq_chip.name = irq_info->codec_name; + + *virq = irq_domain_add_linear(NULL, 1, &wcd_domain_ops, NULL); + if (!(*virq)) { + pr_err("%s: Failed to add IRQ domain\n", __func__); + return -EINVAL; + } + + ret = devm_regmap_add_irq_chip(irq_info->dev, irq_info->regmap, + irq_create_mapping(*virq, 0), + IRQF_ONESHOT, 0, irq_info->wcd_regmap_irq_chip, + &irq_info->irq_chip); + if (ret) + pr_err("%s: Failed to add IRQs: %d\n", + __func__, ret); + + return ret; +} +EXPORT_SYMBOL(wcd_irq_init); + +/** + * wcd_irq_exit: Uninitialize regmap IRQ and free IRQ resources + * @irq_info: pointer to IRQ info structure + * + * Returns 0 on success or error on failure + */ +int wcd_irq_exit(struct wcd_irq_info *irq_info, struct irq_domain *virq) +{ + if (!irq_info) { + pr_err("%s: Null pointer handle\n", __func__); + return -EINVAL; + } + + regmap_del_irq_chip(irq_find_mapping(virq, 0), irq_info->irq_chip); + + return 0; +} +EXPORT_SYMBOL(wcd_irq_exit); diff --git a/include/asoc/wcd-irq.h b/include/asoc/wcd-irq.h new file mode 100644 index 000000000000..63502f828ed8 --- /dev/null +++ b/include/asoc/wcd-irq.h @@ -0,0 +1,63 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __WCD_IRQ_H_ +#define __WCD_IRQ_H_ + +#include +#include +#include + +struct wcd_irq_info { + struct regmap_irq_chip *wcd_regmap_irq_chip; + char *codec_name; + struct regmap *regmap; + struct regmap_irq_chip_data *irq_chip; + struct device *dev; +}; + +#if IS_ENABLED(CONFIG_WCD9XXX_CODEC_CORE) +int wcd_irq_init(struct wcd_irq_info *irq_info, struct irq_domain **virq); +int wcd_irq_exit(struct wcd_irq_info *irq_info, struct irq_domain *virq); +int wcd_request_irq(struct wcd_irq_info *irq_info, int irq, const char *name, + irq_handler_t handler, void *data); +void wcd_free_irq(struct wcd_irq_info *irq_info, int irq, void *data); +void wcd_enable_irq(struct wcd_irq_info *irq_info, int irq); +void wcd_disable_irq(struct wcd_irq_info *irq_info, int irq); +#else +static inline int wcd_irq_init(struct wcd_irq_info *irq_info, + struct irq_domain **virq) +{ + return 0; +}; +static inline int wcd_irq_exit(struct wcd_irq_info *irq_info, + struct irq_domain *virq) +{ + return 0; +}; +static inline int wcd_request_irq(struct wcd_irq_info *irq, + int irq, const char *name, + irq_handler_t handler, void *data) +{ + return 0; +}; +static inline void wcd_free_irq(struct wcd_irq_info *irq, int irq, void *data); +{ +}; +static inline void wcd_enable_irq(struct wcd_irq_info *irq, int irq); +{ +}; +static inline void wcd_disable_irq(struct wcd_irq_info *irq, int irq); +{ +}; +#endif +#endif /* __WCD_IRQ_H_ */ -- GitLab From ec5eab5556994af876dd63194a4bfed247ec2208 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 24 Jul 2018 11:28:04 +0530 Subject: [PATCH 0429/1645] ASoC: codecs: Compile wcd irq as part of CONFIG_SND_SOC_WCD_IRQ Add separate config for generic IRQ using regmap-irq and compile it as a part of wcd_core ko. Change-Id: I844ad72bf039c851a67d968e4b67c10105389932 Signed-off-by: Vatsal Bucha --- asoc/codecs/Kbuild | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index f4c9c106ab15..4a02959760ea 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -141,6 +141,10 @@ ifdef CONFIG_SND_SOC_MSM_HDMI_CODEC_RX HDMICODEC_OBJS += msm_hdmi_codec_rx.o endif +ifdef CONFIG_SND_SOC_WCD_IRQ + CORE_OBJS += wcd-irq.o +endif + LINUX_INC += -Iinclude/linux INCS += $(COMMON_INC) \ -- GitLab From 39955471cde2ba06ddc309d1ee8a2abcd8e105ba Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Tue, 26 Jun 2018 21:52:59 -0400 Subject: [PATCH 0430/1645] asoc: add machine driver for sa8155 based automotive platform Add machine driver for SA8155 based automotive platform, which is based on mobile machine driver with addition of extended support for TDM interfaces which is used for data transfer between SA8155 SoC and the automotive COODEC H/W. Changes include TDM backend and refactored automotive frontend DAI links as well as kcontrol functions to configure TDM slot and offset configuration. Add 815x machine driver init wrapper to allow registration of multiple machine driver in single module init call. CRs-fixed: 2268293 Change-Id: I30eb22a7c5d6b2d963a5ea621b5a00e8dbc27fed Signed-off-by: Derek Chen --- asoc/Kbuild | 2 + asoc/machine_815x_init.c | 36 + asoc/machine_815x_init.h | 23 + asoc/sa8155.c | 7133 ++++++++++++++++++++++++++++++++++++++ asoc/sm8150.c | 13 +- 5 files changed, 7206 insertions(+), 1 deletion(-) create mode 100644 asoc/machine_815x_init.c create mode 100644 asoc/machine_815x_init.h create mode 100644 asoc/sa8155.c diff --git a/asoc/Kbuild b/asoc/Kbuild index aa051761a14c..311fbae090e9 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -101,7 +101,9 @@ endif # for SM8150 sound card driver ifdef CONFIG_SND_SOC_SM8150 + MACHINE_OBJS += sa8155.o MACHINE_OBJS += sm8150.o + MACHINE_OBJS += machine_815x_init.o endif # for SM6150 sound card driver diff --git a/asoc/machine_815x_init.c b/asoc/machine_815x_init.c new file mode 100644 index 000000000000..ab1bdc1f6d29 --- /dev/null +++ b/asoc/machine_815x_init.c @@ -0,0 +1,36 @@ +/* +Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2 and +only version 2 as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +* +*/ + +#include +#include +#include "machine_815x_init.h" + +static int __init audio_machine_815x_init(void) +{ + sm8150_init(); + sa8155_init(); + return 0; +} + +static void audio_machine_815x_exit(void) +{ + sm8150_exit(); + sa8155_exit(); +} + +module_init(audio_machine_815x_init); +module_exit(audio_machine_815x_exit); + +MODULE_DESCRIPTION("Audio Machine 815X Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/machine_815x_init.h b/asoc/machine_815x_init.h new file mode 100644 index 000000000000..4ee6d4f96dc2 --- /dev/null +++ b/asoc/machine_815x_init.h @@ -0,0 +1,23 @@ +/* +Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2 and +only version 2 as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +* +*/ + +#ifndef __MACHINE_815X_INIT_H__ +#define __MACHINE_815X_INIT_H__ +int sm8150_init(void); +int sa8155_init(void); + +void sm8150_exit(void); +void sa8155_exit(void); +#endif + diff --git a/asoc/sa8155.c b/asoc/sa8155.c new file mode 100644 index 000000000000..5e51f0969e39 --- /dev/null +++ b/asoc/sa8155.c @@ -0,0 +1,7133 @@ +/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +/* + * Copyright 2011, The Android Open Source Project + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Android Open Source Project nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "device_event.h" +#include "msm-pcm-routing-v2.h" + +#define DRV_NAME "sa8155-asoc-snd" + +#define __CHIPSET__ "SA8155 " +#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) + +#define DEV_NAME_STR_LEN 32 + +#define SAMPLING_RATE_8KHZ 8000 +#define SAMPLING_RATE_11P025KHZ 11025 +#define SAMPLING_RATE_16KHZ 16000 +#define SAMPLING_RATE_22P05KHZ 22050 +#define SAMPLING_RATE_32KHZ 32000 +#define SAMPLING_RATE_44P1KHZ 44100 +#define SAMPLING_RATE_48KHZ 48000 +#define SAMPLING_RATE_88P2KHZ 88200 +#define SAMPLING_RATE_96KHZ 96000 +#define SAMPLING_RATE_176P4KHZ 176400 +#define SAMPLING_RATE_192KHZ 192000 +#define SAMPLING_RATE_352P8KHZ 352800 +#define SAMPLING_RATE_384KHZ 384000 + +#define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ + +enum { + PRIM_MI2S = 0, + SEC_MI2S, + TERT_MI2S, + QUAT_MI2S, + QUIN_MI2S, + MI2S_MAX, +}; + +enum { + PRIM_AUX_PCM = 0, + SEC_AUX_PCM, + TERT_AUX_PCM, + QUAT_AUX_PCM, + QUIN_AUX_PCM, + AUX_PCM_MAX, +}; + +struct mi2s_conf { + struct mutex lock; + u32 ref_cnt; + u32 msm_is_mi2s_master; +}; + +static u32 mi2s_ebit_clk[MI2S_MAX] = { + Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT +}; + +struct dev_config { + u32 sample_rate; + u32 bit_format; + u32 channels; +}; + +enum { + DP_RX_IDX = 0, + EXT_DISP_RX_IDX_MAX, +}; + +enum pinctrl_pin_state { + STATE_DISABLE = 0, /* All pins are in sleep state */ + STATE_MI2S_ACTIVE, /* IS2 = active, TDM = sleep */ + STATE_TDM_ACTIVE, /* IS2 = sleep, TDM = active */ +}; + +struct msm_pinctrl_info { + struct pinctrl *pinctrl; + struct pinctrl_state *mi2s_disable; + struct pinctrl_state *tdm_disable; + struct pinctrl_state *mi2s_active; + struct pinctrl_state *tdm_active; + enum pinctrl_pin_state curr_state; +}; + +struct msm_asoc_mach_data { + struct msm_pinctrl_info pinctrl_info; +}; + +static const char *const pin_states[] = {"sleep", "i2s-active", + "tdm-active"}; + +enum { + TDM_0 = 0, + TDM_1, + TDM_2, + TDM_3, + TDM_4, + TDM_5, + TDM_6, + TDM_7, + TDM_PORT_MAX, +}; + +enum { + TDM_PRI = 0, + TDM_SEC, + TDM_TERT, + TDM_QUAT, + TDM_QUIN, + TDM_INTERFACE_MAX, +}; + +struct tdm_port { + u32 mode; + u32 channel; +}; + +/* TDM default config */ +static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUIN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + } +}; + +/* TDM default config */ +static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 4}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUIN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + } +}; + +/* Default configuration of external display BE */ +static struct dev_config ext_disp_rx_cfg[] = { + [DP_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config usb_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +static struct dev_config usb_tx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 1, +}; + +static struct dev_config proxy_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +/* Default configuration of MI2S channels */ +static struct dev_config mi2s_rx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config mi2s_tx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_rx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_tx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +/* TDM default slot config */ +struct tdm_slot_cfg { + u32 width; + u32 num; +}; + +static struct tdm_slot_cfg tdm_slot[TDM_INTERFACE_MAX] = { + /* PRI TDM */ + {32, 8}, + /* SEC TDM */ + {32, 8}, + /* TERT TDM */ + {32, 8}, + /* QUAT TDM */ + {32, 8}, + /* QUIN TDM */ + {32, 8} +}; + +/***************************************************************************** +* TO BE UPDATED: Codec/Platform specific tdm slot table +*****************************************************************************/ +static struct tdm_slot_cfg tdm_slot_custom[TDM_INTERFACE_MAX] = { + /* PRI TDM */ + {16, 16}, + /* SEC TDM */ + {16, 16}, + /* TERT TDM */ + {16, 16}, + /* QUAT TDM */ + {16, 16}, + /* QUIN TDM */ + {16, 16} +}; + + +/* TDM default slot offset config */ +#define TDM_SLOT_OFFSET_MAX 32 + +static unsigned int tdm_rx_slot_offset + [TDM_INTERFACE_MAX][TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { + {/* PRI TDM */ + {0, 4, 0xFFFF}, + {8, 12, 0xFFFF}, + {16, 20, 0xFFFF}, + {24, 28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* SEC TDM */ + {0, 4, 0xFFFF}, + {8, 12, 0xFFFF}, + {16, 20, 0xFFFF}, + {24, 28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* TERT TDM */ + {0, 4, 8, 12, 16, 20, 0xFFFF}, + {24, 0xFFFF}, + {28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUAT TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUIN TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + } +}; + +static unsigned int tdm_tx_slot_offset + [TDM_INTERFACE_MAX][TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { + {/* PRI TDM */ + {0, 4, 0xFFFF}, + {8, 12, 0xFFFF}, + {16, 20, 0xFFFF}, + {24, 28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* SEC TDM */ + {0, 4, 8, 12, 16, 20, 0xFFFF}, + {24, 0xFFFF}, + {28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* TERT TDM */ + {0, 4, 8, 12, 0xFFFF}, + {16, 20, 0xFFFF}, + {24, 28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUAT TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUIN TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + } +}; + +/***************************************************************************** +* TO BE UPDATED: Codec/Platform specific tdm slot offset table +* NOTE: +* Each entry represents the slot offset array of one backend tdm device +* valid offset represents the starting offset in byte for the channel +* use 0xFFFF for end or unused slot offset entry. +*****************************************************************************/ +static unsigned int tdm_rx_slot_offset_custom + [TDM_INTERFACE_MAX][TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { + {/* PRI TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* SEC TDM */ + {0, 2, 0xFFFF}, + {4, 0xFFFF}, + {6, 0xFFFF}, + {8, 0xFFFF}, + {10, 0xFFFF}, + {12, 14, 16, 18, 20, 22, 24, 26, 0xFFFF}, + {28, 30, 0xFFFF}, + {0xFFFF}, /* not used */ + }, + {/* TERT TDM */ + {0, 2, 0xFFFF}, + {4, 6, 8, 10, 12, 14, 16, 18, 0xFFFF}, + {20, 22, 24, 26, 28, 30, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUAT TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUIN TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + } +}; + +static unsigned int tdm_tx_slot_offset_custom + [TDM_INTERFACE_MAX][TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { + {/* PRI TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* SEC TDM */ + {0, 2, 0xFFFF}, + {4, 6, 8, 10, 12, 14, 16, 18, 0xFFFF}, + {20, 22, 24, 26, 28, 30, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* TERT TDM */ + {0, 2, 4, 6, 8, 10, 12, 0xFFFF}, + {14, 16, 0xFFFF}, + {18, 20, 22, 24, 26, 28, 30, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUAT TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUIN TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + } +}; + + +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; +static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE", + "S24_3LE"}; +static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *ch_text[] = {"Two", "Three", "Four", "Five", + "Six", "Seven", "Eight"}; +static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_32", "KHZ_44P1", + "KHZ_88P2", "KHZ_176P4" }; +static char const *tdm_ch_text[] = { + "One", "Two", "Three", "Four", + "Five", "Six", "Seven", "Eight", + "Nine", "Ten", "Eleven", "Twelve", + "Thirteen", "Fourteen", "Fifteen", "Sixteen", + "Seventeen", "Eighteen", "Nineteen", "Twenty", + "TwentyOne", "TwentyTwo", "TwentyThree", "TwentyFour", + "TwentyFive", "TwentySix", "TwentySeven", "TwentyEight", + "TwentyNine", "Thirty", "ThirtyOne", "ThirtyTwo"}; +static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; +static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", + "KHZ_48", "KHZ_176P4", + "KHZ_352P8"}; +static const char *const tdm_slot_num_text[] = {"One", "Two", "Four", + "Eight", "Sixteen", "ThirtyTwo"}; +static const char *const tdm_slot_width_text[] = {"16", "24", "32"}; +static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; +static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_16", + "KHZ_22P05", "KHZ_32", "KHZ_44P1", + "KHZ_48", "KHZ_96", "KHZ_192"}; +static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static const char *const qos_text[] = {"Disable", "Enable"}; + +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, + ext_disp_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_slot_num, tdm_slot_num_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_slot_width, tdm_slot_width_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); + +static bool is_initial_boot = true; + +static struct afe_clk_set mi2s_clk[MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + } + +}; + +static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; + +static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, + usb_rx_cfg.channels); + ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1; + return 0; +} + +static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels); + return 1; +} + +static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_rx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__, + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_rx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_rx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_rx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_rx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, + usb_tx_cfg.channels); + ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1; + return 0; +} + +static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels); + return 1; +} + +static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_tx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + default: + sample_rate_val = 6; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__, + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_tx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_tx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_tx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_tx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "Display Port RX", + sizeof("Display Port RX"))) { + idx = DP_RX_IDX; + } else { + pr_err("%s: unsupported BE: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].bit_format) { + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 2: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int ext_disp_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.integer.value[0] = + ext_disp_rx_cfg[idx].channels - 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + + return 0; +} + +static int ext_disp_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ext_disp_rx_cfg[idx].channels = + ucontrol->value.integer.value[0] + 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + return 1; +} + +static int ext_disp_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].sample_rate) { + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 6; + break; + + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 4; + break; + + case SAMPLING_RATE_32KHZ: + sample_rate_val = 3; + break; + + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: ext_disp_rx[%d].sample_rate = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].sample_rate); + + return 0; +} + +static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 6: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 5: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 4: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_32KHZ; + break; + case 2: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, ext_disp_rx[%d].sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], idx, + ext_disp_rx_cfg[idx].sample_rate); + return 0; +} + +static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2; + + return 0; +} + +static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2; + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + + return 1; +} + +static int tdm_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int aux_pcm_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 0: + default: + sample_rate = SAMPLING_RATE_8KHZ; + break; + } + return sample_rate; +} + +static int tdm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 5; + break; + default: + sample_rate_val = 3; + break; + } + return sample_rate_val; +} + +static int aux_pcm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + return sample_rate_val; +} + +static int tdm_get_mode(struct snd_kcontrol *kcontrol) +{ + int mode; + + if (strnstr(kcontrol->id.name, "PRI", + sizeof(kcontrol->id.name))) { + mode = TDM_PRI; + } else if (strnstr(kcontrol->id.name, "SEC", + sizeof(kcontrol->id.name))) { + mode = TDM_SEC; + } else if (strnstr(kcontrol->id.name, "TERT", + sizeof(kcontrol->id.name))) { + mode = TDM_TERT; + } else if (strnstr(kcontrol->id.name, "QUAT", + sizeof(kcontrol->id.name))) { + mode = TDM_QUAT; + } else if (strnstr(kcontrol->id.name, "QUIN", + sizeof(kcontrol->id.name))) { + mode = TDM_QUIN; + } else { + pr_err("%s: unsupported mode in: %s", + __func__, kcontrol->id.name); + mode = -EINVAL; + } + + return mode; +} + +static int tdm_get_channel(struct snd_kcontrol *kcontrol) +{ + int channel; + + if (strnstr(kcontrol->id.name, "RX_0", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_0", + sizeof(kcontrol->id.name))) { + channel = TDM_0; + } else if (strnstr(kcontrol->id.name, "RX_1", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_1", + sizeof(kcontrol->id.name))) { + channel = TDM_1; + } else if (strnstr(kcontrol->id.name, "RX_2", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_2", + sizeof(kcontrol->id.name))) { + channel = TDM_2; + } else if (strnstr(kcontrol->id.name, "RX_3", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_3", + sizeof(kcontrol->id.name))) { + channel = TDM_3; + } else if (strnstr(kcontrol->id.name, "RX_4", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_4", + sizeof(kcontrol->id.name))) { + channel = TDM_4; + } else if (strnstr(kcontrol->id.name, "RX_5", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_5", + sizeof(kcontrol->id.name))) { + channel = TDM_5; + } else if (strnstr(kcontrol->id.name, "RX_6", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_6", + sizeof(kcontrol->id.name))) { + channel = TDM_6; + } else if (strnstr(kcontrol->id.name, "RX_7", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_7", + sizeof(kcontrol->id.name))) { + channel = TDM_7; + } else { + pr_err("%s: unsupported channel in: %s", + __func__, kcontrol->id.name); + channel = -EINVAL; + } + + return channel; +} + +static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, + struct tdm_port *port) +{ + if (port) { + port->mode = tdm_get_mode(kcontrol); + if (port->mode < 0) + return port->mode; + + port->channel = tdm_get_channel(kcontrol); + if (port->channel < 0) + return port->channel; + } else + return -EINVAL; + return 0; +} + +static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_rx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_tx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_get_format(int value) +{ + int format = 0; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int tdm_get_format_val(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 2; + break; + default: + value = 0; + break; + } + return value; +} + +static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_rx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_tx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + + ucontrol->value.enumerated.item[0] = + tdm_rx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = + tdm_tx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int tdm_get_slot_num_val(int slot_num) +{ + int slot_num_val; + + switch (slot_num) { + case 1: + slot_num_val = 0; + break; + case 2: + slot_num_val = 1; + break; + case 4: + slot_num_val = 2; + break; + case 8: + slot_num_val = 3; + break; + case 16: + slot_num_val = 4; + break; + case 32: + slot_num_val = 5; + break; + default: + slot_num_val = 5; + break; + } + return slot_num_val; +} + +static int tdm_slot_num_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int mode = tdm_get_mode(kcontrol); + + if (mode < 0) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + return mode; + } + + ucontrol->value.enumerated.item[0] = + tdm_get_slot_num_val(tdm_slot[mode].num); + + pr_debug("%s: mode = %d, tdm_slot_num = %d, item = %d\n", __func__, + mode, tdm_slot[mode].num, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int tdm_get_slot_num(int value) +{ + int slot_num; + + switch (value) { + case 0: + slot_num = 1; + break; + case 1: + slot_num = 2; + break; + case 2: + slot_num = 4; + break; + case 3: + slot_num = 8; + break; + case 4: + slot_num = 16; + break; + case 5: + slot_num = 32; + break; + default: + slot_num = 8; + break; + } + return slot_num; +} + +static int tdm_slot_num_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int mode = tdm_get_mode(kcontrol); + + if (mode < 0) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + return mode; + } + + tdm_slot[mode].num = + tdm_get_slot_num(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: mode = %d, tdm_slot_num = %d, item = %d\n", __func__, + mode, tdm_slot[mode].num, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int tdm_get_slot_width_val(int slot_width) +{ + int slot_width_val; + + switch (slot_width) { + case 16: + slot_width_val = 0; + break; + case 24: + slot_width_val = 1; + break; + case 32: + slot_width_val = 2; + break; + default: + slot_width_val = 2; + break; + } + return slot_width_val; +} + +static int tdm_slot_width_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int mode = tdm_get_mode(kcontrol); + + if (mode < 0) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + return mode; + } + + ucontrol->value.enumerated.item[0] = + tdm_get_slot_width_val(tdm_slot[mode].width); + + pr_debug("%s: mode = %d, tdm_slot_width = %d, item = %d\n", __func__, + mode, tdm_slot[mode].width, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int tdm_get_slot_width(int value) +{ + int slot_width; + + switch (value) { + case 0: + slot_width = 16; + break; + case 1: + slot_width = 24; + break; + case 2: + slot_width = 32; + break; + default: + slot_width = 32; + break; + } + return slot_width; +} + +static int tdm_slot_width_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int mode = tdm_get_mode(kcontrol); + + if (mode < 0) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + return mode; + } + + tdm_slot[mode].width = + tdm_get_slot_width(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: mode = %d, tdm_slot_width = %d, item = %d\n", __func__, + mode, tdm_slot[mode].width, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int tdm_rx_slot_mapping_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int *slot_offset; + int i; + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + slot_offset = tdm_rx_slot_offset[port.mode][port.channel]; + pr_debug("%s: mode = %d, channel = %d\n", + __func__, port.mode, port.channel); + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + ucontrol->value.integer.value[i] = slot_offset[i]; + pr_debug("%s: offset %d, value %d\n", + __func__, i, slot_offset[i]); + } + } + return ret; +} + +static int tdm_rx_slot_mapping_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int *slot_offset; + int i; + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + slot_offset = tdm_rx_slot_offset[port.mode][port.channel]; + pr_debug("%s: mode = %d, channel = %d\n", + __func__, port.mode, port.channel); + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + slot_offset[i] = ucontrol->value.integer.value[i]; + pr_debug("%s: offset %d, value %d\n", + __func__, i, slot_offset[i]); + } + } + return ret; +} + +static int tdm_tx_slot_mapping_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int *slot_offset; + int i; + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + slot_offset = tdm_tx_slot_offset[port.mode][port.channel]; + pr_debug("%s: mode = %d, channel = %d\n", + __func__, port.mode, port.channel); + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + ucontrol->value.integer.value[i] = slot_offset[i]; + pr_debug("%s: offset %d, value %d\n", + __func__, i, slot_offset[i]); + } + } + return ret; +} + +static int tdm_tx_slot_mapping_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int *slot_offset; + int i; + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + slot_offset = tdm_tx_slot_offset[port.mode][port.channel]; + pr_debug("%s: mode = %d, channel = %d\n", + __func__, port.mode, port.channel); + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + slot_offset[i] = ucontrol->value.integer.value[i]; + pr_debug("%s: offset %d, value %d\n", + __func__, i, slot_offset[i]); + } + } + return ret; +} + +static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", + sizeof("PRIM_AUX_PCM"))) + idx = PRIM_AUX_PCM; + else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM", + sizeof("SEC_AUX_PCM"))) + idx = SEC_AUX_PCM; + else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", + sizeof("TERT_AUX_PCM"))) + idx = TERT_AUX_PCM; + else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", + sizeof("QUAT_AUX_PCM"))) + idx = QUAT_AUX_PCM; + else if (strnstr(kcontrol->id.name, "QUIN_AUX_PCM", + sizeof("QUIN_AUX_PCM"))) + idx = QUIN_AUX_PCM; + else { + pr_err("%s: unsupported port: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX", + sizeof("PRIM_MI2S_RX"))) + idx = PRIM_MI2S; + else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX", + sizeof("SEC_MI2S_RX"))) + idx = SEC_MI2S; + else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", + sizeof("TERT_MI2S_RX"))) + idx = TERT_MI2S; + else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", + sizeof("QUAT_MI2S_RX"))) + idx = QUAT_MI2S; + else if (strnstr(kcontrol->id.name, "QUIN_MI2S_RX", + sizeof("QUIN_MI2S_RX"))) + idx = QUIN_MI2S; + else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", + sizeof("PRIM_MI2S_TX"))) + idx = PRIM_MI2S; + else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX", + sizeof("SEC_MI2S_TX"))) + idx = SEC_MI2S; + else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", + sizeof("TERT_MI2S_TX"))) + idx = TERT_MI2S; + else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", + sizeof("QUAT_MI2S_TX"))) + idx = QUAT_MI2S; + else if (strnstr(kcontrol->id.name, "QUIN_MI2S_TX", + sizeof("QUIN_MI2S_TX"))) + idx = QUIN_MI2S; + else { + pr_err("%s: unsupported channel: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int mi2s_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + default: + sample_rate_val = 6; + break; + } + return sample_rate_val; +} + +static int mi2s_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_192KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int mi2s_auxpcm_get_format(int value) +{ + int format; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int mi2s_auxpcm_get_format_value(int format) +{ + int value; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + value = 2; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 3; + break; + default: + value = 0; + break; + } + return value; +} + +static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(mi2s_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(mi2s_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(aux_pcm_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(aux_pcm_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, + usb_audio_rx_ch_get, usb_audio_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, + usb_audio_tx_ch_get, usb_audio_tx_ch_put), + SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, + ext_disp_rx_ch_get, ext_disp_rx_ch_put), + SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, + proxy_rx_ch_get, proxy_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, + usb_audio_rx_format_get, usb_audio_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, + usb_audio_tx_format_get, usb_audio_tx_format_put), + SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, + ext_disp_rx_format_get, ext_disp_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, + usb_audio_rx_sample_rate_get, + usb_audio_rx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, + usb_audio_tx_sample_rate_get, + usb_audio_tx_sample_rate_put), + SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, + ext_disp_rx_sample_rate_get, + ext_disp_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_1 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_2 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_3 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_1 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_2 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_3 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_1 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_2 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_3 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_1 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_2 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_3 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_RX_1 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_RX_2 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_RX_3 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_1 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_2 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_3 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_1 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_2 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_3 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_1 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_2 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_3 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_1 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_2 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_3 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_1 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_2 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_3 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_1 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_2 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_3 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_1 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_2 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_3 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_1 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_2 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_3 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_4 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_1 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_2 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_3 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_1 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_2 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_3 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_4 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_1 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_2 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_3 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_1 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_2 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_3 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_4 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_1 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_2 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_3 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_1 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_2 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_3 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_1 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_2 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_3 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_1 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_2 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_3 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_1 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_2 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_3 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_1 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_2 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_3 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_1 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_2 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_3 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_RX_1 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_RX_2 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_RX_3 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_TX_1 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_TX_2 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_TX_3 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_1 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_2 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_3 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_1 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_2 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_3 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_RX_1 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_RX_2 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_RX_3 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_TX_1 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_TX_2 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_TX_3 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRI_TDM SlotNumber", tdm_slot_num, + tdm_slot_num_get, tdm_slot_num_put), + SOC_ENUM_EXT("PRI_TDM SlotWidth", tdm_slot_width, + tdm_slot_width_get, tdm_slot_width_put), + SOC_ENUM_EXT("SEC_TDM SlotNumber", tdm_slot_num, + tdm_slot_num_get, tdm_slot_num_put), + SOC_ENUM_EXT("SEC_TDM SlotWidth", tdm_slot_width, + tdm_slot_width_get, tdm_slot_width_put), + SOC_ENUM_EXT("TERT_TDM SlotNumber", tdm_slot_num, + tdm_slot_num_get, tdm_slot_num_put), + SOC_ENUM_EXT("TERT_TDM SlotWidth", tdm_slot_width, + tdm_slot_width_get, tdm_slot_width_put), + SOC_ENUM_EXT("QUAT_TDM SlotNumber", tdm_slot_num, + tdm_slot_num_get, tdm_slot_num_put), + SOC_ENUM_EXT("QUAT_TDM SlotWidth", tdm_slot_width, + tdm_slot_width_get, tdm_slot_width_put), + SOC_ENUM_EXT("QUIN_TDM SlotNumber", tdm_slot_num, + tdm_slot_num_get, tdm_slot_num_put), + SOC_ENUM_EXT("QUIN_TDM SlotWidth", tdm_slot_width, + tdm_slot_width_get, tdm_slot_width_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_4 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_RX SampleRate", quin_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_TX SampleRate", quin_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_MI2S_RX SampleRate", quin_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_MI2S_TX SampleRate", quin_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUIN_MI2S_RX Channels", quin_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUIN_MI2S_TX Channels", quin_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("SEC_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("TERT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("TERT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("QUIN_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("QUIN_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), +}; + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, + int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, + unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +static int msm_ext_disp_get_idx_from_beid(int32_t be_id) +{ + int idx; + + switch (be_id) { + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = DP_RX_IDX; + break; + default: + pr_err("%s: Incorrect ext_disp BE id %d\n", __func__, be_id); + idx = -EINVAL; + break; + } + + return idx; +} + +static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int rc = 0; + int idx; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->id) { + case MSM_BACKEND_DAI_USB_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_rx_cfg.bit_format); + rate->min = rate->max = usb_rx_cfg.sample_rate; + channels->min = channels->max = usb_rx_cfg.channels; + break; + + case MSM_BACKEND_DAI_USB_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_tx_cfg.bit_format); + rate->min = rate->max = usb_tx_cfg.sample_rate; + channels->min = channels->max = usb_tx_cfg.channels; + break; + + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = msm_ext_disp_get_idx_from_beid(dai_link->id); + if (idx < 0) { + pr_err("%s: Incorrect ext disp idx %d\n", + __func__, idx); + rc = idx; + goto done; + } + + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + ext_disp_rx_cfg[idx].bit_format); + rate->min = rate->max = ext_disp_rx_cfg[idx].sample_rate; + channels->min = channels->max = ext_disp_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_AFE_PCM_RX: + channels->min = channels->max = proxy_rx_cfg.channels; + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + + case MSM_BACKEND_DAI_PRI_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_PRI_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUIN_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUIN_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + + + case MSM_BACKEND_DAI_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[PRIM_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[SEC_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[SEC_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[TERT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[TERT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[QUAT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[QUAT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUIN_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[QUIN_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[QUIN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUIN_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUIN_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[QUIN_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[QUIN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUIN_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUAT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUAT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUINARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUIN_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[QUIN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUIN_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUIN_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[QUIN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUIN_MI2S].channels; + break; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + +done: + return rc; +} + +static int msm_get_port_id(int be_id) +{ + int afe_port_id; + + switch (be_id) { + case MSM_BACKEND_DAI_PRI_MI2S_RX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_PRI_MI2S_TX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUINARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUINARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUINARY_MI2S_TX; + break; + default: + pr_err("%s: Invalid BE id: %d\n", __func__, be_id); + afe_port_id = -EINVAL; + } + + return afe_port_id; +} + +static u32 get_mi2s_bits_per_sample(u32 bit_format) +{ + u32 bit_per_sample; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + case SNDRV_PCM_FORMAT_S24_LE: + bit_per_sample = 32; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bit_per_sample = 16; + break; + } + + return bit_per_sample; +} + +static void update_mi2s_clk_val(int dai_id, int stream) +{ + u32 bit_per_sample; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } else { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } +} + +static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int port_id = 0; + int index = cpu_dai->id; + + port_id = msm_get_port_id(rtd->dai_link->id); + if (port_id < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto err; + } + + if (enable) { + update_mi2s_clk_val(index, substream->stream); + dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, + mi2s_clk[index].clk_freq_in_hz); + } + + mi2s_clk[index].enable = enable; + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_clk[index]); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed for port 0x%x , err:%d\n", + __func__, port_id, ret); + goto err; + } + +err: + return ret; +} + +#ifdef ENABLE_PINCTRL +static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, + enum pinctrl_pin_state new_state) +{ + int ret = 0; + int curr_state = 0; + + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + if (pinctrl_info->pinctrl == NULL) { + pr_err("%s: pinctrl_info->pinctrl is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + curr_state = pinctrl_info->curr_state; + pinctrl_info->curr_state = new_state; + pr_debug("%s: curr_state = %s new_state = %s\n", __func__, + pin_states[curr_state], pin_states[pinctrl_info->curr_state]); + + if (curr_state == pinctrl_info->curr_state) { + pr_debug("%s: Already in same state\n", __func__); + goto err; + } + + if (curr_state != STATE_DISABLE && + pinctrl_info->curr_state != STATE_DISABLE) { + pr_debug("%s: state already active cannot switch\n", __func__); + ret = -EIO; + goto err; + } + + switch (pinctrl_info->curr_state) { + case STATE_MI2S_ACTIVE: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_active); + if (ret) { + pr_err("%s: MI2S state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + case STATE_TDM_ACTIVE: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->tdm_active); + if (ret) { + pr_err("%s: TDM state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + case STATE_DISABLE: + if (curr_state == STATE_MI2S_ACTIVE) { + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_disable); + } else { + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->tdm_disable); + } + if (ret) { + pr_err("%s: state disable failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + default: + pr_err("%s: TLMM pin state is invalid\n", __func__); + return -EINVAL; + } + +err: + return ret; +} + +static void msm_release_pinctrl(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + if (pinctrl_info->pinctrl) { + devm_pinctrl_put(pinctrl_info->pinctrl); + pinctrl_info->pinctrl = NULL; + } +} + +static int msm_get_pinctrl(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = NULL; + struct pinctrl *pinctrl; + int ret; + + pinctrl_info = &pdata->pinctrl_info; + + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + return -EINVAL; + } + + pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR_OR_NULL(pinctrl)) { + pr_err("%s: Unable to get pinctrl handle\n", __func__); + return -EINVAL; + } + pinctrl_info->pinctrl = pinctrl; + + /* get all the states handles from Device Tree */ + pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl, + "quat_mi2s_disable"); + if (IS_ERR(pinctrl_info->mi2s_disable)) { + pr_err("%s: could not get mi2s_disable pinstate\n", __func__); + goto err; + } + pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl, + "quat_mi2s_enable"); + if (IS_ERR(pinctrl_info->mi2s_active)) { + pr_err("%s: could not get mi2s_active pinstate\n", __func__); + goto err; + } + pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl, + "quat_tdm_disable"); + if (IS_ERR(pinctrl_info->tdm_disable)) { + pr_err("%s: could not get tdm_disable pinstate\n", __func__); + goto err; + } + pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl, + "quat_tdm_enable"); + if (IS_ERR(pinctrl_info->tdm_active)) { + pr_err("%s: could not get tdm_active pinstate\n", + __func__); + goto err; + } + /* Reset the TLMM pins to a default state */ + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_disable); + if (ret != 0) { + pr_err("%s: Disable TLMM pins failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + pinctrl_info->curr_state = STATE_DISABLE; + + return 0; + +err: + devm_pinctrl_put(pinctrl); + pinctrl_info->pinctrl = NULL; + return -EINVAL; +} +#else +static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, + enum pinctrl_pin_state new_state) +{ + return 0; +} + +static void msm_release_pinctrl(struct platform_device *pdev) +{ + return; +} + +static int msm_get_pinctrl(struct platform_device *pdev) +{ + return 0; +} +#endif + +static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_1].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_PRI][TDM_1].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_2].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_PRI][TDM_2].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_3].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_PRI][TDM_3].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_1].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_PRI][TDM_1].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_2].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_PRI][TDM_2].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_3].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_PRI][TDM_3].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_1].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_1].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_2].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_2].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_3].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_3].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_1].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_SEC][TDM_1].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_2].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_SEC][TDM_2].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_3].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_SEC][TDM_3].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_1].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_1].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_2].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_2].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_3].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_3].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_4].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_4].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_4].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_1].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_1].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_2].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_2].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_3].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_3].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_1].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_1].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_2].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_2].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_3].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_3].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_1].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_1].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_2].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_2].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_3].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_3].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_RX: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_1: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_1].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_1].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_2: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_2].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_2].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_3: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_3].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_3].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_TX: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_1: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_1].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_1].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_2: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_2].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_2].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_3: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_3].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_3].sample_rate; + break; + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n", + __func__, cpu_dai->id, channels->max, rate->max, + params_format(params)); + + return 0; +} + +static unsigned int tdm_param_set_slot_mask(int slots) +{ + unsigned int slot_mask = 0; + int i = 0; + + if ((slots <= 0) || (slots > 32)) { + pr_err("%s: invalid slot number %d\n", __func__, slots); + return -EINVAL; + } + + for (i = 0; i < slots ; i++) + slot_mask |= 1 << i; + return slot_mask; +} + +static int sa8155_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + int channels, slot_width, slots, rate, format; + unsigned int slot_mask; + unsigned int *slot_offset; + int offset_channels = 0; + int i; + int clk_freq; + + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + + channels = params_channels(params); + if (channels < 1 || channels > 32) { + pr_err("%s: invalid param channels %d\n", + __func__, channels); + return -EINVAL; + } + + format = params_format(params); + if (format != SNDRV_PCM_FORMAT_S32_LE && + format != SNDRV_PCM_FORMAT_S24_LE && + format != SNDRV_PCM_FORMAT_S16_LE) { + /* + * Up to 8 channel HW configuration should + * use 32 bit slot width for max support of + * stream bit width. (slot_width > bit_width) + */ + pr_err("%s: invalid param format 0x%x\n", + __func__, format); + return -EINVAL; + } + + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_0]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_1]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_2]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_3]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_0]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_1]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_2]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_3]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_0]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_1]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_2]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_3]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_0]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_1]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_2]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_3]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_0]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_1]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_2]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_3]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_4]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_0]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_1]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_2]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_3]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_0]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_1]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_2]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_3]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_0]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_1]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_2]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_3]; + break; + case AFE_PORT_ID_QUINARY_TDM_RX: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_0]; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_1: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_1]; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_2: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_2]; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_3: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_3]; + break; + case AFE_PORT_ID_QUINARY_TDM_TX: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_0]; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_1: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_1]; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_2: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_2]; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_3: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_3]; + break; + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) + offset_channels++; + else + break; + } + + if (offset_channels == 0) { + pr_err("%s: invalid offset_channels %d\n", + __func__, offset_channels); + return -EINVAL; + } + + if (channels > offset_channels) { + pr_err("%s: channels %d exceed offset_channels %d\n", + __func__, channels, offset_channels); + return -EINVAL; + } + + slot_mask = tdm_param_set_slot_mask(slots); + if (!slot_mask) { + pr_err("%s: invalid slot_mask 0x%x\n", + __func__, slot_mask); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + 0, NULL, channels, slot_offset); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + channels, slot_offset, 0, NULL); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } else { + ret = -EINVAL; + pr_err("%s: invalid use case, err:%d\n", + __func__, ret); + goto end; + } + + rate = params_rate(params); + clk_freq = rate * slot_width * slots; + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, clk_freq, SND_SOC_CLOCK_OUT); + if (ret < 0) { + pr_err("%s: failed to set tdm clk, err:%d\n", + __func__, ret); + } + +end: + return ret; +} + +static int sa8155_tdm_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || + (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { + ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); + if (ret) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret); + } + + return ret; +} + +static void sa8155_tdm_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || + (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { + ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); + if (ret) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret); + } +} + +static struct snd_soc_ops sa8155_tdm_be_ops = { + .hw_params = sa8155_tdm_snd_hw_params, + .startup = sa8155_tdm_snd_startup, + .shutdown = sa8155_tdm_snd_shutdown +}; + +static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) +{ + cpumask_t mask; + + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + + cpumask_clear(&mask); + cpumask_set_cpu(1, &mask); /* affine to core 1 */ + cpumask_set_cpu(2, &mask); /* affine to core 2 */ + cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); + + substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; + + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + MSM_LL_QOS_VALUE); + return 0; +} + +static struct snd_soc_ops msm_fe_qos_ops = { + .prepare = msm_fe_qos_prepare, +}; + +static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int index = cpu_dai->id; + unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret_pinctrl = 0; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + if (index < PRIM_MI2S || index >= MI2S_MAX) { + ret = -EINVAL; + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto err; + } + /* + * Mutex protection in case the same MI2S + * interface using for both TX and RX so + * that the same clock won't be enable twice. + */ + mutex_lock(&mi2s_intf_conf[index].lock); + if (++mi2s_intf_conf[index].ref_cnt == 1) { + /* Check if msm needs to provide the clock to the interface */ + if (!mi2s_intf_conf[index].msm_is_mi2s_master) { + mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; + fmt = SND_SOC_DAIFMT_CBM_CFM; + } + ret = msm_mi2s_set_sclk(substream, true); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed to enable MI2S clock, err:%d\n", + __func__, ret); + goto clean_up; + } + + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) { + pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n", + __func__, index, ret); + goto clk_off; + } + if (index == QUAT_MI2S) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_MI2S_ACTIVE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } + } +clk_off: + if (ret < 0) + msm_mi2s_set_sclk(substream, false); +clean_up: + if (ret < 0) + mi2s_intf_conf[index].ref_cnt--; + mutex_unlock(&mi2s_intf_conf[index].lock); +err: + return ret; +} + +static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int index = rtd->cpu_dai->id; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret_pinctrl = 0; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + if (index < PRIM_MI2S || index >= MI2S_MAX) { + pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); + return; + } + + mutex_lock(&mi2s_intf_conf[index].lock); + if (--mi2s_intf_conf[index].ref_cnt == 0) { + ret = msm_mi2s_set_sclk(substream, false); + if (ret < 0) + pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", + __func__, index, ret); + if (index == QUAT_MI2S) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_DISABLE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } + } + mutex_unlock(&mi2s_intf_conf[index].lock); +} + +static struct snd_soc_ops msm_mi2s_be_ops = { + .startup = msm_mi2s_snd_startup, + .shutdown = msm_mi2s_snd_shutdown, +}; + + +/* Digital audio interface glue - connects codec <---> CPU */ +static struct snd_soc_dai_link msm_common_dai_links[] = { + /* FrontEnd DAI Links */ + { + .name = MSM_DAILINK_NAME(Media1), + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, + { + .name = MSM_DAILINK_NAME(Media2), + .stream_name = "MultiMedia2", + .cpu_dai_name = "MultiMedia2", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, + }, + { + .name = "VoiceMMode1", + .stream_name = "VoiceMMode1", + .cpu_dai_name = "VoiceMMode1", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE1, + }, + { + .name = "MSM VoIP", + .stream_name = "VoIP", + .cpu_dai_name = "VoIP", + .platform_name = "msm-voip-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_VOIP, + }, + { + .name = MSM_DAILINK_NAME(ULL), + .stream_name = "MultiMedia3", + .cpu_dai_name = "MultiMedia3", + .platform_name = "msm-pcm-dsp.2", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA3, + }, + /* - SLIMBUS_0 Hostless */ + { + .name = "MSM AFE-PCM RX", + .stream_name = "AFE-PROXY RX", + .cpu_dai_name = "msm-dai-q6-dev.241", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .platform_name = "msm-pcm-afe", + .dpcm_playback = 1, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + }, + { + .name = "MSM AFE-PCM TX", + .stream_name = "AFE-PROXY TX", + .cpu_dai_name = "msm-dai-q6-dev.240", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .platform_name = "msm-pcm-afe", + .dpcm_capture = 1, + .ignore_suspend = 1, + }, + { + .name = MSM_DAILINK_NAME(Compress1), + .stream_name = "Compress1", + .cpu_dai_name = "MultiMedia4", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA4, + }, + /* Hostless PCM purpose */ + { + .name = "AUXPCM Hostless", + .stream_name = "AUXPCM Hostless", + .cpu_dai_name = "AUXPCM_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + /* - SLIMBUS_1 Hostless */ + /* - SLIMBUS_3 Hostless */ + /* - SLIMBUS_4 Hostless */ + { + .name = MSM_DAILINK_NAME(LowLatency), + .stream_name = "MultiMedia5", + .cpu_dai_name = "MultiMedia5", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .ops = &msm_fe_qos_ops, + }, + { + .name = "Listen 1 Audio Service", + .stream_name = "Listen 1 Audio Service", + .cpu_dai_name = "LSM1", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM1, + }, + /* Multiple Tunnel instances */ + { + .name = MSM_DAILINK_NAME(Compress2), + .stream_name = "Compress2", + .cpu_dai_name = "MultiMedia7", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA7, + }, + { + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", + .cpu_dai_name = "MultiMedia10", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA10, + }, + { + .name = MSM_DAILINK_NAME(ULL_NOIRQ), + .stream_name = "MM_NOIRQ", + .cpu_dai_name = "MultiMedia8", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + .ops = &msm_fe_qos_ops, + }, + /* HDMI Hostless */ + { + .name = "HDMI_RX_HOSTLESS", + .stream_name = "HDMI_RX_HOSTLESS", + .cpu_dai_name = "HDMI_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "VoiceMMode2", + .stream_name = "VoiceMMode2", + .cpu_dai_name = "VoiceMMode2", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE2, + }, + /* LSM FE */ + { + .name = "Listen 2 Audio Service", + .stream_name = "Listen 2 Audio Service", + .cpu_dai_name = "LSM2", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM2, + }, + { + .name = "Listen 3 Audio Service", + .stream_name = "Listen 3 Audio Service", + .cpu_dai_name = "LSM3", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM3, + }, + { + .name = "Listen 4 Audio Service", + .stream_name = "Listen 4 Audio Service", + .cpu_dai_name = "LSM4", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM4, + }, + { + .name = "Listen 5 Audio Service", + .stream_name = "Listen 5 Audio Service", + .cpu_dai_name = "LSM5", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM5, + }, + { + .name = "Listen 6 Audio Service", + .stream_name = "Listen 6 Audio Service", + .cpu_dai_name = "LSM6", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM6, + }, + { + .name = "Listen 7 Audio Service", + .stream_name = "Listen 7 Audio Service", + .cpu_dai_name = "LSM7", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM7, + }, + { + .name = "Listen 8 Audio Service", + .stream_name = "Listen 8 Audio Service", + .cpu_dai_name = "LSM8", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM8, + }, + /* - Multimedia9 */ + { + .name = MSM_DAILINK_NAME(Compress4), + .stream_name = "Compress4", + .cpu_dai_name = "MultiMedia11", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA11, + }, + { + .name = MSM_DAILINK_NAME(Compress5), + .stream_name = "Compress5", + .cpu_dai_name = "MultiMedia12", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA12, + }, + { + .name = MSM_DAILINK_NAME(Compress6), + .stream_name = "Compress6", + .cpu_dai_name = "MultiMedia13", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA13, + }, + { + .name = MSM_DAILINK_NAME(Compress7), + .stream_name = "Compress7", + .cpu_dai_name = "MultiMedia14", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA14, + }, + { + .name = MSM_DAILINK_NAME(Compress8), + .stream_name = "Compress8", + .cpu_dai_name = "MultiMedia15", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA15, + }, + { + .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), + .stream_name = "MM_NOIRQ_2", + .cpu_dai_name = "MultiMedia16", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA16, + }, + /* - SLIMBUS_8 Hostless */ + /* - Slimbus4 Capture */ + /* - SLIMBUS_2 Hostless Playback */ + /* - SLIMBUS_2 Hostless Capture */ + /* HFP TX */ + { + .name = MSM_DAILINK_NAME(ASM Loopback), + .stream_name = "MultiMedia6", + .cpu_dai_name = "MultiMedia6", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA6, + }, + { + .name = "USB Audio Hostless", + .stream_name = "USB Audio Hostless", + .cpu_dai_name = "USBAUDIO_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + /* - SLIMBUS_7 Hostless */ + { + .name = "Compress Capture", + .stream_name = "Compress9", + .cpu_dai_name = "MultiMedia17", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA17, + }, +}; + +static struct snd_soc_dai_link msm_auto_fe_dai_links[] = { + { + .name = "INT_HFP_BT Hostless", + .stream_name = "INT_HFP_BT Hostless", + .cpu_dai_name = "INT_HFP_BT_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + /* Low latency ASM loopback for ICC */ + { + .name = MSM_DAILINK_NAME(LowLatency Loopback), + .stream_name = "MultiMedia9", + .cpu_dai_name = "MultiMedia9", + .platform_name = "msm-pcm-loopback.1", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA9, + }, + { + .name = "Tertiary MI2S TX_Hostless", + .stream_name = "Tertiary MI2S_TX Hostless Capture", + .cpu_dai_name = "TERT_MI2S_TX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = MSM_DAILINK_NAME(Media20), + .stream_name = "MultiMedia20", + .cpu_dai_name = "MultiMedia20", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA20, + }, + { + .name = MSM_DAILINK_NAME(HFP RX), + .stream_name = "MultiMedia21", + .cpu_dai_name = "MultiMedia21", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA21, + }, + /* TDM Hostless */ + { + .name = "Primary TDM RX 0 Hostless", + .stream_name = "Primary TDM RX 0 Hostless", + .cpu_dai_name = "PRI_TDM_RX_0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Primary TDM TX 0 Hostless", + .stream_name = "Primary TDM TX 0 Hostless", + .cpu_dai_name = "PRI_TDM_TX_0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Secondary TDM RX 0 Hostless", + .stream_name = "Secondary TDM RX 0 Hostless", + .cpu_dai_name = "SEC_TDM_RX_0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Secondary TDM TX 0 Hostless", + .stream_name = "Secondary TDM TX 0 Hostless", + .cpu_dai_name = "SEC_TDM_TX_0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Tertiary TDM RX 0 Hostless", + .stream_name = "Tertiary TDM RX 0 Hostless", + .cpu_dai_name = "TERT_TDM_RX_0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Tertiary TDM TX 0 Hostless", + .stream_name = "Tertiary TDM TX 0 Hostless", + .cpu_dai_name = "TERT_TDM_TX_0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Quaternary TDM RX 0 Hostless", + .stream_name = "Quaternary TDM RX 0 Hostless", + .cpu_dai_name = "QUAT_TDM_RX_0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Quaternary TDM TX 0 Hostless", + .stream_name = "Quaternary TDM TX 0 Hostless", + .cpu_dai_name = "QUAT_TDM_TX_0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Quaternary MI2S_RX Hostless Playback", + .stream_name = "Quaternary MI2S_RX Hostless Playback", + .cpu_dai_name = "QUAT_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Secondary MI2S_TX Hostless Capture", + .stream_name = "Secondary MI2S_TX Hostless Capture", + .cpu_dai_name = "SEC_MI2S_TX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "DTMF RX Hostless", + .stream_name = "DTMF RX Hostless", + .cpu_dai_name = "DTMF_RX_HOSTLESS", + .platform_name = "msm-pcm-dtmf", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_DTMF_RX, + } +}; + +static struct snd_soc_dai_link msm_custom_fe_dai_links[] = { + /* FrontEnd DAI Links */ + { + .name = MSM_DAILINK_NAME(Media1), + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1, + .ops = &msm_fe_qos_ops, + }, + { + .name = MSM_DAILINK_NAME(Media2), + .stream_name = "MultiMedia2", + .cpu_dai_name = "MultiMedia2", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, + .ops = &msm_fe_qos_ops, + }, + { + .name = MSM_DAILINK_NAME(Media3), + .stream_name = "MultiMedia3", + .cpu_dai_name = "MultiMedia3", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA3, + .ops = &msm_fe_qos_ops, + }, + { + .name = MSM_DAILINK_NAME(Media5), + .stream_name = "MultiMedia5", + .cpu_dai_name = "MultiMedia5", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .ops = &msm_fe_qos_ops, + }, + { + .name = MSM_DAILINK_NAME(Media6), + .stream_name = "MultiMedia6", + .cpu_dai_name = "MultiMedia6", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA6, + .ops = &msm_fe_qos_ops, + }, + { + .name = MSM_DAILINK_NAME(Media8), + .stream_name = "MultiMedia8", + .cpu_dai_name = "MultiMedia8", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + .ops = &msm_fe_qos_ops, + }, + { + .name = MSM_DAILINK_NAME(Media9), + .stream_name = "MultiMedia9", + .cpu_dai_name = "MultiMedia9", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA9, + .ops = &msm_fe_qos_ops, + }, + { + .name = "INT_HFP_BT Hostless", + .stream_name = "INT_HFP_BT Hostless", + .cpu_dai_name = "INT_HFP_BT_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "AUXPCM Hostless", + .stream_name = "AUXPCM Hostless", + .cpu_dai_name = "AUXPCM_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = MSM_DAILINK_NAME(Media20), + .stream_name = "MultiMedia20", + .cpu_dai_name = "MultiMedia20", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA20, + }, +}; + +static struct snd_soc_dai_link msm_common_be_dai_links[] = { + /* Backend AFE DAI Links */ + { + .name = LPASS_BE_AFE_PCM_RX, + .stream_name = "AFE Playback", + .cpu_dai_name = "msm-dai-q6-dev.224", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AFE_PCM_TX, + .stream_name = "AFE Capture", + .cpu_dai_name = "msm-dai-q6-dev.225", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Uplink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_TX, + .stream_name = "Voice Uplink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32772", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Downlink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_RX, + .stream_name = "Voice Downlink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32771", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music BACK END DAI Link */ + { + .name = LPASS_BE_VOICE_PLAYBACK_TX, + .stream_name = "Voice Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32773", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + /* Incall Music 2 BACK END DAI Link */ + { + .name = LPASS_BE_VOICE2_PLAYBACK_TX, + .stream_name = "Voice2 Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32770", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_RX, + .stream_name = "USB Audio Playback", + .cpu_dai_name = "msm-dai-q6-dev.28672", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_USB_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_TX, + .stream_name = "USB Audio Capture", + .cpu_dai_name = "msm-dai-q6-dev.28673", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_USB_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_0, + .stream_name = "Primary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36864", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_0, + .stream_name = "Primary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36865", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_0, + .stream_name = "Secondary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36880", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_0, + .stream_name = "Secondary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36881", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_0, + .stream_name = "Tertiary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36896", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_0, + .stream_name = "Tertiary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36897", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_0, + .stream_name = "Quaternary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36912", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_0, + .stream_name = "Quaternary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36913", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_auto_be_dai_links[] = { + /* Backend DAI Links */ + { + .name = LPASS_BE_PRI_TDM_RX_1, + .stream_name = "Primary TDM1 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36866", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_2, + .stream_name = "Primary TDM2 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36868", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_3, + .stream_name = "Primary TDM3 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36870", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_1, + .stream_name = "Primary TDM1 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36867", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_2, + .stream_name = "Primary TDM2 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36869", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_3, + .stream_name = "Primary TDM3 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36871", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_1, + .stream_name = "Secondary TDM1 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36882", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_2, + .stream_name = "Secondary TDM2 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36884", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_3, + .stream_name = "Secondary TDM3 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36886", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_1, + .stream_name = "Secondary TDM1 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36883", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_2, + .stream_name = "Secondary TDM2 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36885", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_3, + .stream_name = "Secondary TDM3 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36887", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_1, + .stream_name = "Tertiary TDM1 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36898", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_2, + .stream_name = "Tertiary TDM2 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36900", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_3, + .stream_name = "Tertiary TDM3 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36902", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_4, + .stream_name = "Tertiary TDM4 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36904", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_4, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_1, + .stream_name = "Tertiary TDM1 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36899", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_2, + .stream_name = "Tertiary TDM2 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36901", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_3, + .stream_name = "Tertiary TDM3 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36903", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_1, + .stream_name = "Quaternary TDM1 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36914", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_2, + .stream_name = "Quaternary TDM2 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36916", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_3, + .stream_name = "Quaternary TDM3 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36918", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_1, + .stream_name = "Quaternary TDM1 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36915", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_2, + .stream_name = "Quaternary TDM2 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36917", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_3, + .stream_name = "Quaternary TDM3 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36919", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link ext_disp_be_dai_link[] = { + /* DISP PORT BACK END DAI Link */ + { + .name = LPASS_BE_DISPLAY_PORT, + .stream_name = "Display Port Playback", + .cpu_dai_name = "msm-dai-q6-dp.24608", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-ext-disp-audio-codec-rx", + .codec_dai_name = "msm_dp_audio_codec_rx_dai", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { + { + .name = LPASS_BE_PRI_MI2S_RX, + .stream_name = "Primary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_MI2S_TX, + .stream_name = "Primary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX, + .stream_name = "Secondary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX, + .stream_name = "Secondary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX, + .stream_name = "Tertiary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX, + .stream_name = "Tertiary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX, + .stream_name = "Quaternary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_RX, + .stream_name = "Quinary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_TX, + .stream_name = "Quinary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { + /* Primary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_AUXPCM_RX, + .stream_name = "AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AUXPCM_TX, + .stream_name = "AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Secondary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_SEC_AUXPCM_RX, + .stream_name = "Sec AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_AUXPCM_TX, + .stream_name = "Sec AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Tertiary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_TERT_AUXPCM_RX, + .stream_name = "Tert AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_AUXPCM_TX, + .stream_name = "Tert AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Quaternary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUAT_AUXPCM_RX, + .stream_name = "Quat AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_AUXPCM_TX, + .stream_name = "Quat AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Quinary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUIN_AUXPCM_RX, + .stream_name = "Quin AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_AUXPCM_TX, + .stream_name = "Quin AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_auto_dai_links[ + ARRAY_SIZE(msm_common_dai_links) + + ARRAY_SIZE(msm_auto_fe_dai_links) + + ARRAY_SIZE(msm_common_be_dai_links) + + ARRAY_SIZE(msm_auto_be_dai_links) + + ARRAY_SIZE(ext_disp_be_dai_link) + + ARRAY_SIZE(msm_mi2s_be_dai_links) + + ARRAY_SIZE(msm_auxpcm_be_dai_links)]; + +static struct snd_soc_dai_link msm_auto_custom_dai_links[ + ARRAY_SIZE(msm_custom_fe_dai_links) + + ARRAY_SIZE(msm_auto_fe_dai_links) + + ARRAY_SIZE(msm_common_be_dai_links) + + ARRAY_SIZE(msm_auto_be_dai_links) + + ARRAY_SIZE(ext_disp_be_dai_link) + + ARRAY_SIZE(msm_mi2s_be_dai_links) + + ARRAY_SIZE(msm_auxpcm_be_dai_links)]; + +struct snd_soc_card snd_soc_card_auto_msm = { + .name = "sa8155-adp-star-snd-card", +}; + +struct snd_soc_card snd_soc_card_auto_custom_msm = { + .name = "sa8155-custom-snd-card", +}; + +static int msm_populate_dai_link_component_of_node( + struct snd_soc_card *card) +{ + int i, index, ret = 0; + struct device *cdev = card->dev; + struct snd_soc_dai_link *dai_link = card->dai_link; + struct device_node *np; + + if (!cdev) { + pr_err("%s: Sound card device memory NULL\n", __func__); + return -ENODEV; + } + + for (i = 0; i < card->num_links; i++) { + if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) + continue; + + /* populate platform_of_node for snd card dai links */ + if (dai_link[i].platform_name && + !dai_link[i].platform_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-platform-names", + dai_link[i].platform_name); + if (index < 0) { + pr_err("%s: No match found for platform name: %s\n", + __func__, dai_link[i].platform_name); + ret = index; + goto err; + } + np = of_parse_phandle(cdev->of_node, "asoc-platform", + index); + if (!np) { + pr_err("%s: retrieving phandle for platform %s, index %d failed\n", + __func__, dai_link[i].platform_name, + index); + ret = -ENODEV; + goto err; + } + dai_link[i].platform_of_node = np; + dai_link[i].platform_name = NULL; + } + + /* populate cpu_of_node for snd card dai links */ + if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-cpu-names", + dai_link[i].cpu_dai_name); + if (index >= 0) { + np = of_parse_phandle(cdev->of_node, "asoc-cpu", + index); + if (!np) { + pr_err("%s: retrieving phandle for cpu dai %s failed\n", + __func__, + dai_link[i].cpu_dai_name); + ret = -ENODEV; + goto err; + } + dai_link[i].cpu_of_node = np; + dai_link[i].cpu_dai_name = NULL; + } + } + + /* populate codec_of_node for snd card dai links */ + if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-codec-names", + dai_link[i].codec_name); + if (index < 0) + continue; + np = of_parse_phandle(cdev->of_node, "asoc-codec", + index); + if (!np) { + pr_err("%s: retrieving phandle for codec %s failed\n", + __func__, dai_link[i].codec_name); + ret = -ENODEV; + goto err; + } + dai_link[i].codec_of_node = np; + dai_link[i].codec_name = NULL; + } + } + +err: + return ret; +} + +static const struct of_device_id sa8155_asoc_machine_of_match[] = { + { .compatible = "qcom,sa8155-asoc-snd-adp-star", + .data = "adp_star_codec"}, + { .compatible = "qcom,sa8155-asoc-snd-custom", + .data = "custom_codec"}, + {}, +}; + +static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) +{ + struct snd_soc_card *card = NULL; + struct snd_soc_dai_link *dailink; + int len_1, len_2, len_3; + int total_links; + const struct of_device_id *match; + + match = of_match_node(sa8155_asoc_machine_of_match, dev->of_node); + if (!match) { + dev_err(dev, "%s: No DT match found for sound card\n", + __func__); + return NULL; + } + + if (!strcmp(match->data, "adp_star_codec")) { + card = &snd_soc_card_auto_msm; + len_1 = ARRAY_SIZE(msm_common_dai_links); + len_2 = len_1 + ARRAY_SIZE(msm_auto_fe_dai_links); + len_3 = len_2 + ARRAY_SIZE(msm_common_be_dai_links); + total_links = len_3 + ARRAY_SIZE(msm_auto_be_dai_links); + memcpy(msm_auto_dai_links, + msm_common_dai_links, + sizeof(msm_common_dai_links)); + memcpy(msm_auto_dai_links + len_1, + msm_auto_fe_dai_links, + sizeof(msm_auto_fe_dai_links)); + memcpy(msm_auto_dai_links + len_2, + msm_common_be_dai_links, + sizeof(msm_common_be_dai_links)); + memcpy(msm_auto_dai_links + len_3, + msm_auto_be_dai_links, + sizeof(msm_auto_be_dai_links)); + + if (of_property_read_bool(dev->of_node, + "qcom,ext-disp-audio-rx")) { + dev_dbg(dev, "%s(): ext disp audio support present\n", + __func__); + memcpy(msm_auto_dai_links + total_links, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + total_links += ARRAY_SIZE(ext_disp_be_dai_link); + } + if (of_property_read_bool(dev->of_node, + "qcom,mi2s-audio-intf")) { + memcpy(msm_auto_dai_links + total_links, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,auxpcm-audio-intf")) { + memcpy(msm_auto_dai_links + total_links, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + + dailink = msm_auto_dai_links; + } else if (!strcmp(match->data, "custom_codec")) { + card = &snd_soc_card_auto_custom_msm; + len_1 = ARRAY_SIZE(msm_custom_fe_dai_links); + len_2 = len_1 + ARRAY_SIZE(msm_auto_fe_dai_links); + len_3 = len_2 + ARRAY_SIZE(msm_common_be_dai_links); + total_links = len_3 + ARRAY_SIZE(msm_auto_be_dai_links); + memcpy(msm_auto_custom_dai_links, + msm_custom_fe_dai_links, + sizeof(msm_custom_fe_dai_links)); + memcpy(msm_auto_custom_dai_links + len_1, + msm_auto_fe_dai_links, + sizeof(msm_auto_fe_dai_links)); + memcpy(msm_auto_custom_dai_links + len_2, + msm_common_be_dai_links, + sizeof(msm_common_be_dai_links)); + memcpy(msm_auto_custom_dai_links + len_3, + msm_auto_be_dai_links, + sizeof(msm_auto_be_dai_links)); + + if (of_property_read_bool(dev->of_node, + "qcom,ext-disp-audio-rx")) { + dev_dbg(dev, "%s(): ext disp audio support present\n", + __func__); + memcpy(msm_auto_custom_dai_links + total_links, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + total_links += ARRAY_SIZE(ext_disp_be_dai_link); + } + if (of_property_read_bool(dev->of_node, + "qcom,mi2s-audio-intf")) { + memcpy(msm_auto_custom_dai_links + total_links, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,auxpcm-audio-intf")) { + memcpy(msm_auto_custom_dai_links + total_links, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + dailink = msm_auto_custom_dai_links; + } else { + dev_err(dev, "%s: Codec not supported\n", + __func__); + return NULL; + } + + if (card) { + card->dai_link = dailink; + card->num_links = total_links; + } + + return card; +} + +/***************************************************************************** +* TO BE UPDATED: Codec/Platform specific tdm slot and offset table selection +*****************************************************************************/ +static int msm_tdm_init(struct device *dev) +{ + const struct of_device_id *match; + + match = of_match_node(sa8155_asoc_machine_of_match, dev->of_node); + if (!match) { + dev_err(dev, "%s: No DT match found for sound card\n", + __func__); + return -EINVAL; + } + + if (!strcmp(match->data, "custom_codec")) { + dev_dbg(dev, "%s: custom tdm configuration\n", __func__); + + memcpy(tdm_rx_slot_offset, + tdm_rx_slot_offset_custom, + sizeof(tdm_rx_slot_offset_custom)); + memcpy(tdm_tx_slot_offset, + tdm_tx_slot_offset_custom, + sizeof(tdm_tx_slot_offset_custom)); + memcpy(tdm_slot, + tdm_slot_custom, + sizeof(tdm_slot_custom)); + } else { + dev_dbg(dev, "%s: default tdm configuration\n", __func__); + } + + return 0; +} + +static void msm_i2s_auxpcm_init(struct platform_device *pdev) +{ + int count; + u32 mi2s_master_slave[MI2S_MAX]; + int ret; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_init(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-master", + mi2s_master_slave, MI2S_MAX); + if (ret) { + dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n", + __func__); + } else { + for (count = 0; count < MI2S_MAX; count++) { + mi2s_intf_conf[count].msm_is_mi2s_master = + mi2s_master_slave[count]; + } + } +} + +static void msm_i2s_auxpcm_deinit(void) +{ + int count; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_destroy(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + mi2s_intf_conf[count].msm_is_mi2s_master = 0; + } +} +static int msm_asoc_machine_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card; + struct msm_asoc_mach_data *pdata; + int ret; + enum apr_subsys_state q6_state; + + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, "No platform supplied from device tree\n"); + return -EINVAL; + } + + q6_state = apr_get_q6_state(); + if (q6_state == APR_SUBSYS_DOWN) { + dev_dbg(&pdev->dev, "deferring %s, adsp_state %d\n", + __func__, q6_state); + return -EPROBE_DEFER; + } + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct msm_asoc_mach_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + card = populate_snd_card_dailinks(&pdev->dev); + if (!card) { + dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); + ret = -EINVAL; + goto err; + } + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, pdata); + + ret = snd_soc_of_parse_card_name(card, "qcom,model"); + if (ret) { + dev_err(&pdev->dev, "parse card name failed, err:%d\n", + ret); + goto err; + } + + ret = msm_populate_dai_link_component_of_node(card); + if (ret) { + ret = -EPROBE_DEFER; + goto err; + } + + /* Populate controls of snd card */ + card->controls = msm_snd_controls; + card->num_controls = ARRAY_SIZE(msm_snd_controls); + + ret = msm_tdm_init(&pdev->dev); + if (ret) { + ret = -EPROBE_DEFER; + goto err; + } + + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret == -EPROBE_DEFER) { + goto err; + } else if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); + goto err; + } + dev_info(&pdev->dev, "Sound card %s registered\n", card->name); + + /* Parse pinctrl info from devicetree */ + ret = msm_get_pinctrl(pdev); + if (!ret) { + pr_debug("%s: pinctrl parsing successful\n", __func__); + } else { + dev_dbg(&pdev->dev, + "%s: Parsing pinctrl failed with %d. Cannot use Ports\n", + __func__, ret); + ret = 0; + } + + msm_i2s_auxpcm_init(pdev); + + return 0; +err: + msm_release_pinctrl(pdev); + devm_kfree(&pdev->dev, pdata); + return ret; +} + +static int msm_asoc_machine_remove(struct platform_device *pdev) +{ + msm_i2s_auxpcm_deinit(); + + msm_release_pinctrl(pdev); + return 0; +} + +static struct platform_driver sa8155_asoc_machine_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = sa8155_asoc_machine_of_match, + }, + .probe = msm_asoc_machine_probe, + .remove = msm_asoc_machine_remove, +}; + +static int dummy_asoc_machine_probe(struct platform_device *pdev) +{ + return 0; +} + +static int dummy_asoc_machine_remove(struct platform_device *pdev) +{ + return 0; +} + +static struct platform_device sa8155_dummy_asoc_machine_device = { + .name = "sa8155-asoc-snd-dummy", +}; + +static struct platform_driver sa8155_dummy_asoc_machine_driver = { + .driver = { + .name = "sa8155-asoc-snd-dummy", + .owner = THIS_MODULE, + }, + .probe = dummy_asoc_machine_probe, + .remove = dummy_asoc_machine_remove, +}; + +static int sa8155_notifier_service_cb(struct notifier_block *this, + unsigned long opcode, void *ptr) +{ + pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); + + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (is_initial_boot) { + platform_driver_register(&sa8155_dummy_asoc_machine_driver); + platform_device_register(&sa8155_dummy_asoc_machine_device); + is_initial_boot = false; + } + break; + default: + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block service_nb = { + .notifier_call = sa8155_notifier_service_cb, + .priority = -INT_MAX, +}; + +int __init sa8155_init(void) +{ + pr_debug("%s\n", __func__); + audio_notifier_register("sa8155", AUDIO_NOTIFIER_ADSP_DOMAIN, + &service_nb); + return platform_driver_register(&sa8155_asoc_machine_driver); +} + +void sa8155_exit(void) +{ + pr_debug("%s\n", __func__); + platform_driver_unregister(&sa8155_asoc_machine_driver); + audio_notifier_deregister("sa8155"); +} + +MODULE_DESCRIPTION("ALSA SoC msm"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, sa8155_asoc_machine_of_match); diff --git a/asoc/sm8150.c b/asoc/sm8150.c index 606ce1dc856c..3138423b91d8 100644 --- a/asoc/sm8150.c +++ b/asoc/sm8150.c @@ -7557,7 +7557,18 @@ static struct platform_driver sm8150_asoc_machine_driver = { .probe = msm_asoc_machine_probe, .remove = msm_asoc_machine_remove, }; -module_platform_driver(sm8150_asoc_machine_driver); + +int __init sm8150_init(void) +{ + pr_debug("%s\n", __func__); + return platform_driver_register(&sm8150_asoc_machine_driver); +} + +void sm8150_exit(void) +{ + pr_debug("%s\n", __func__); + platform_driver_unregister(&sm8150_asoc_machine_driver); +} MODULE_DESCRIPTION("ALSA SoC msm"); MODULE_LICENSE("GPL v2"); -- GitLab From 5628e8bc988c9f0f6ba881c04d5649f4d4c80f65 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Mon, 23 Jul 2018 10:41:58 +0530 Subject: [PATCH 0431/1645] asoc: msm: update asm channel map for push pull mode In noirq push pull mode channel map needs to be set during ASM open shared io stream. Add support for no irq driver to set channel map during ASM shared io stream open. CRs-Fixed: 2267809 Change-Id: Ic1abfe60bb54b6529fbb4cf999e50196befaba46 Signed-off-by: Surendar Karka --- asoc/msm-pcm-q6-noirq.c | 193 +++++++++++++++++++++++++--------------- asoc/msm-pcm-q6-v2.h | 8 +- dsp/q6asm.c | 25 ++++-- include/dsp/q6asm-v2.h | 3 +- 4 files changed, 149 insertions(+), 80 deletions(-) diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index 249f8a5b1e9b..c89efb9773bd 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -275,6 +275,8 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream, int dir = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? IN : OUT; unsigned long topology; int perf_mode; + bool use_default_chmap = true; + char *chmap = NULL; pdata = (struct msm_plat_data *) dev_get_drvdata(soc_prtd->platform->dev); @@ -311,6 +313,13 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream, if (prtd->enabled) return 0; + if (pdata->ch_map[soc_prtd->dai_link->id]) { + use_default_chmap = + !(pdata->ch_map[soc_prtd->dai_link->id]->set_ch_map); + chmap = + pdata->ch_map[soc_prtd->dai_link->id]->channel_map; + } + switch (runtime->format) { case SNDRV_PCM_FORMAT_S24_LE: bits_per_sample = 24; @@ -335,7 +344,8 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream, config.bufsz = params_buffer_bytes(params) / params_periods(params); config.bufcnt = params_periods(params); - ret = q6asm_open_shared_io(prtd->audio_client, &config, dir); + ret = q6asm_open_shared_io(prtd->audio_client, &config, dir, + use_default_chmap, chmap); if (ret) { pr_err("%s: q6asm_open_write_shared_io failed ret: %d\n", __func__, ret); @@ -718,89 +728,126 @@ static int msm_pcm_add_volume_control(struct snd_soc_pcm_runtime *rtd) return 0; } -static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int msm_pcm_channel_map_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - int i; - struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); - unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - struct snd_pcm_substream *substream; - struct msm_audio *prtd; + struct snd_soc_component *pcm = snd_kcontrol_chip(kcontrol); + u64 fe_id = kcontrol->private_value; + struct msm_plat_data *pdata = (struct msm_plat_data *) + snd_soc_component_get_drvdata(pcm); + int rc = 0, i = 0; - pr_debug("%s", __func__); - substream = snd_pcm_chmap_substream(info, idx); - if (!substream) - return -ENODEV; - if (!substream->runtime) - return 0; + pr_debug("%s: fe_id- %llu\n", __func__, fe_id); - prtd = substream->runtime->private_data; - if (prtd) { - prtd->set_channel_map = true; - for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) - prtd->channel_map[i] = + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bounds fe_id %llu\n", + __func__, fe_id); + rc = -EINVAL; + goto end; + } + + if (pdata->ch_map[fe_id]) { + pdata->ch_map[fe_id]->set_ch_map = true; + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + pdata->ch_map[fe_id]->channel_map[i] = (char)(ucontrol->value.integer.value[i]); + } else { + pr_debug("%s: no memory for ch_map, default will be set\n", + __func__); } - return 0; +end: + pr_debug("%s: ret %d\n", __func__, rc); + return rc; } -static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int msm_pcm_channel_map_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { - int i; - struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); - unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - struct snd_pcm_substream *substream; - struct msm_audio *prtd; - - pr_debug("%s", __func__); - substream = snd_pcm_chmap_substream(info, idx); - if (!substream) - return -ENODEV; - memset(ucontrol->value.integer.value, 0, - sizeof(ucontrol->value.integer.value)); - if (!substream->runtime) - return 0; /* no channels set */ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 8; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0xFFFFFFFF; + return 0; +} - prtd = substream->runtime->private_data; +static int msm_pcm_channel_map_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *pcm = snd_kcontrol_chip(kcontrol); + u64 fe_id = kcontrol->private_value; + struct msm_plat_data *pdata = (struct msm_plat_data *) + snd_soc_component_get_drvdata(pcm); + int rc = 0, i = 0; - if (prtd && prtd->set_channel_map == true) { + pr_debug("%s: fe_id- %llu\n", __func__, fe_id); + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s: Received out of bounds fe_id %llu\n", + __func__, fe_id); + rc = -EINVAL; + goto end; + } + if (pdata->ch_map[fe_id]) { for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) ucontrol->value.integer.value[i] = - (int)prtd->channel_map[i]; - } else { - for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) - ucontrol->value.integer.value[i] = 0; + pdata->ch_map[fe_id]->channel_map[i]; } - - return 0; +end: + pr_debug("%s: ret %d\n", __func__, rc); + return rc; } -static int msm_pcm_add_chmap_control(struct snd_soc_pcm_runtime *rtd) +static int msm_pcm_add_channel_map_control(struct snd_soc_pcm_runtime *rtd) { - struct snd_pcm *pcm = rtd->pcm; - struct snd_pcm_chmap *chmap_info; - struct snd_kcontrol *kctl; - char device_num[12]; - int i, ret; - - pr_debug("%s, Channel map cntrl add\n", __func__); - ret = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, - snd_pcm_std_chmaps, - PCM_FORMAT_MAX_NUM_CHANNEL, 0, - &chmap_info); - if (ret) - return ret; + const char *mixer_ctl_name = "Playback Channel Map"; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + struct msm_plat_data *pdata = NULL; + int ctl_len = 0; + struct snd_kcontrol_new fe_channel_map_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_pcm_channel_map_info, + .get = msm_pcm_channel_map_get, + .put = msm_pcm_channel_map_put, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s: NULL rtd\n", __func__); + return -EINVAL; + } + + pr_debug("%s: added new pcm FE with name %s, id %d, cpu dai %s, device no %d\n", + __func__, rtd->dai_link->name, rtd->dai_link->id, + rtd->dai_link->cpu_dai_name, rtd->pcm->device); - kctl = chmap_info->kctl; - for (i = 0; i < kctl->count; i++) - kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE; - snprintf(device_num, sizeof(device_num), "%d", pcm->device); - strlcat(kctl->id.name, device_num, sizeof(kctl->id.name)); - pr_debug("%s, Overwriting channel map control name to: %s", - __func__, kctl->id.name); - kctl->put = msm_pcm_chmap_ctl_put; - kctl->get = msm_pcm_chmap_ctl_get; + ctl_len = strlen(mixer_ctl_name) + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + if (!mixer_str) + return -ENOMEM; + + snprintf(mixer_str, ctl_len, "%s%d", mixer_ctl_name, rtd->pcm->device); + + fe_channel_map_control[0].name = mixer_str; + fe_channel_map_control[0].private_value = rtd->dai_link->id; + pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); + snd_soc_add_platform_controls(rtd->platform, + fe_channel_map_control, + ARRAY_SIZE(fe_channel_map_control)); + + pdata = snd_soc_platform_get_drvdata(rtd->platform); + pdata->ch_map[rtd->dai_link->id] = + kzalloc(sizeof(struct msm_pcm_ch_map), GFP_KERNEL); + if (!pdata->ch_map[rtd->dai_link->id]) { + pr_err("%s: Could not allocate memory for channel map\n", + __func__); + kfree(mixer_str); + return -ENOMEM; + } + kfree(mixer_str); return 0; } @@ -1155,11 +1202,11 @@ static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - ret = msm_pcm_add_chmap_control(rtd); - if (ret) { - pr_err("%s failed to add chmap cntls\n", __func__); - goto exit; - } + ret = msm_pcm_add_channel_map_control(rtd); + if (ret) + pr_err("%s: Could not add pcm Channel Map Control\n", + __func__); + ret = msm_pcm_add_volume_control(rtd); if (ret) { pr_err("%s: Could not add pcm Volume Control %d\n", @@ -1181,7 +1228,7 @@ static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) if (ret) pr_err("%s: Could not add hw dep node\n", __func__); pcm->nonatomic = true; -exit: + return ret; } diff --git a/asoc/msm-pcm-q6-v2.h b/asoc/msm-pcm-q6-v2.h index 0177b2d6ce79..21d09cde6e6e 100644 --- a/asoc/msm-pcm-q6-v2.h +++ b/asoc/msm-pcm-q6-v2.h @@ -20,7 +20,7 @@ #define _MSM_PCM_H #include #include - +#include "msm-pcm-routing-v2.h" /* Support unconventional sample rates 12000, 24000 as well */ @@ -125,6 +125,12 @@ struct output_meta_data_st { struct msm_plat_data { int perf_mode; struct snd_pcm *pcm; + struct msm_pcm_ch_map *ch_map[MSM_FRONTEND_DAI_MAX]; +}; + +struct msm_pcm_ch_map { + bool set_ch_map; + char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL]; }; #endif /*_MSM_PCM_H*/ diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 8deb64a723ab..4945f67c639e 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -3937,11 +3937,13 @@ int q6asm_set_shared_pos_buff(struct audio_client *ac, * parameters * config - session parameters (channels, bits_per_sample, sr) * dir - stream direction (IN for playback, OUT for capture) + * use_default_chmap: true if default channel map to be used + * channel_map: input channel map * returns 0 if successful, error code otherwise */ int q6asm_open_shared_io(struct audio_client *ac, struct shared_io_config *config, - int dir) + int dir, bool use_default_chmap, u8 *channel_map) { struct asm_stream_cmd_open_shared_io *open; u8 *channel_mapping; @@ -3951,6 +3953,12 @@ int q6asm_open_shared_io(struct audio_client *ac, if (!ac || !config) return -EINVAL; + if (!use_default_chmap && (channel_map == NULL)) { + pr_err("%s: No valid chan map and can't use default\n", + __func__); + return -EINVAL; + } + bufsz = config->bufsz; bufcnt = config->bufcnt; num_watermarks = 0; @@ -4047,10 +4055,17 @@ int q6asm_open_shared_io(struct audio_client *ac, memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL); - rc = q6asm_map_channels(channel_mapping, config->channels, false); - if (rc) { - pr_err("%s: Map channels failed, ret: %d\n", __func__, rc); - goto done; + if (use_default_chmap) { + rc = q6asm_map_channels(channel_mapping, config->channels, + false); + if (rc) { + pr_err("%s: Map channels failed, ret: %d\n", + __func__, rc); + goto done; + } + } else { + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL); } open->num_watermark_levels = num_watermarks; diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index e6f021db7e88..40a152ba0039 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -303,7 +303,8 @@ int q6asm_open_write_v2(struct audio_client *ac, uint32_t format, uint16_t bits_per_sample); int q6asm_open_shared_io(struct audio_client *ac, - struct shared_io_config *c, int dir); + struct shared_io_config *c, int dir, + bool use_default_chmap, u8 *channel_map); int q6asm_open_write_v3(struct audio_client *ac, uint32_t format, uint16_t bits_per_sample); -- GitLab From b7f823c4d128b0f22dc218a1908935ad215c50b0 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 2 Aug 2018 13:23:11 +0530 Subject: [PATCH 0432/1645] asoc: bolero: Fix compile errors on rx/tx macro Fix compilation issue on bolero rx/tx macros. Change-Id: I1bb9da552d4719ed3417a56fe77f147cab92dc1d Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 3 ++- asoc/codecs/bolero/tx-macro.c | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 449b73e4d97c..49919de17cf7 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -883,7 +883,8 @@ static int rx_macro_set_idle_detect_thr(struct snd_soc_codec *codec, int interp, int path_type) { int port_id[4] = { 0, 0, 0, 0 }; - int *port_ptr = NULL, num_ports = NULL; + int *port_ptr = NULL; + int num_ports = 0; int bit_width = 0, i = 0; int mux_reg = 0, mux_reg_val = 0; int dai_id = 0, idle_thr = 0; diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 0795d47c8138..dabc345f22b9 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -182,8 +182,8 @@ static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv, struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL); int ret = 0; - dev_dbg(tx_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", - __func__, mclk_enable, dapm, tx_priv->tx_mclk_users); + dev_dbg(tx_priv->dev, "%s: mclk_enable = %u,clk_users= %d\n", + __func__, mclk_enable, tx_priv->tx_mclk_users); mutex_lock(&tx_priv->mclk_lock); if (mclk_enable) { @@ -631,7 +631,7 @@ static int tx_macro_hw_params(struct snd_pcm_substream *substream, int tx_fs_rate = -EINVAL; struct snd_soc_codec *codec = dai->codec; u32 decimator = 0; - u16 sample_rate = 0; + u32 sample_rate = 0; u16 tx_fs_reg = 0; struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; -- GitLab From fe99d5b2d12121e6b78dc7f50acf4c698d575339 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Fri, 29 Jun 2018 14:52:28 +0800 Subject: [PATCH 0433/1645] ASoC: q6asm: use session lock to avoid use-after-free It is possible that audio session free and param set happens simultaneously. Audio client might be freed while param set is doing wait_event_timeout. Use session lock to make sure client_free happens after param set. Change-Id: I0947c309c8e445fa2e220680e329d88bd5fe2418 Signed-off-by: Xiaojun Sang --- dsp/q6asm.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 378279a5f18a..7aa5f5ce2468 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -98,6 +98,7 @@ static struct asm_mmap this_mmap; struct audio_session { struct audio_client *ac; spinlock_t session_lock; + struct mutex mutex_lock_per_session; }; /* session id: 0 reserved */ static struct audio_session session[ASM_ACTIVE_STREAMS_ALLOWED + 1]; @@ -564,6 +565,10 @@ static int q6asm_get_session_id_from_audio_client(struct audio_client *ac) if (session[n].ac == ac) return n; } + + pr_debug("%s: cannot find matching audio client. ac = %pK\n", + __func__, ac); + return 0; } @@ -579,6 +584,7 @@ static void q6asm_session_free(struct audio_client *ac) pr_debug("%s: sessionid[%d]\n", __func__, ac->session); session_id = ac->session; + mutex_lock(&session[session_id].mutex_lock_per_session); rtac_remove_popp_from_adm_devices(ac->session); spin_lock_irqsave(&(session[session_id].session_lock), flags); session[ac->session].ac = NULL; @@ -590,6 +596,7 @@ static void q6asm_session_free(struct audio_client *ac) kfree(ac); ac = NULL; spin_unlock_irqrestore(&(session[session_id].session_lock), flags); + mutex_unlock(&session[session_id].mutex_lock_per_session); } static uint32_t q6asm_get_next_buf(struct audio_client *ac, @@ -1192,6 +1199,7 @@ int q6asm_send_stream_cmd(struct audio_client *ac, int rc; uint32_t sz = 0; uint64_t actual_sz = 0; + int session_id = 0; if (!data || !ac) { pr_err("%s: %s is NULL\n", __func__, @@ -1200,6 +1208,12 @@ int q6asm_send_stream_cmd(struct audio_client *ac, goto done; } + session_id = q6asm_get_session_id_from_audio_client(ac); + if (!session_id) { + rc = -EINVAL; + goto done; + } + if (data->event_type >= ARRAY_SIZE(adsp_reg_event_opcode)) { pr_err("%s: event %u out of boundary of array size of (%lu)\n", __func__, data->event_type, @@ -1223,6 +1237,12 @@ int q6asm_send_stream_cmd(struct audio_client *ac, goto done; } + mutex_lock(&session[session_id].mutex_lock_per_session); + if (!q6asm_is_valid_audio_client(ac)) { + rc = -EINVAL; + goto fail_send_param; + } + q6asm_add_hdr_async(ac, &hdr, sz, TRUE); atomic_set(&ac->cmd_state_pp, -1); hdr.opcode = adsp_reg_event_opcode[data->event_type]; @@ -1255,6 +1275,7 @@ int q6asm_send_stream_cmd(struct audio_client *ac, rc = 0; fail_send_param: + mutex_unlock(&session[session_id].mutex_lock_per_session); kfree(asm_params); done: return rc; @@ -2696,6 +2717,7 @@ int q6asm_set_pp_params(struct audio_client *ac, struct asm_stream_cmd_set_pp_params *asm_set_param = NULL; int pkt_size = 0; int ret = 0; + int session_id = 0; if (ac == NULL) { pr_err("%s: Audio Client is NULL\n", __func__); @@ -2705,6 +2727,10 @@ int q6asm_set_pp_params(struct audio_client *ac, return -EINVAL; } + session_id = q6asm_get_session_id_from_audio_client(ac); + if (!session_id) + return -EINVAL; + pkt_size = sizeof(struct asm_stream_cmd_set_pp_params); /* Add param size to packet size when sending in-band only */ if (param_data != NULL) @@ -2713,6 +2739,18 @@ int q6asm_set_pp_params(struct audio_client *ac, if (!asm_set_param) return -ENOMEM; + mutex_lock(&session[session_id].mutex_lock_per_session); + if (!q6asm_is_valid_audio_client(ac)) { + ret = -EINVAL; + goto done; + } + + if (ac->apr == NULL) { + pr_err("%s: AC APR handle NULL\n", __func__); + ret = -EINVAL; + goto done; + } + q6asm_add_hdr_async(ac, &asm_set_param->apr_hdr, pkt_size, TRUE); /* With pre-packed data, only the opcode differs from V2 and V3. */ @@ -2765,6 +2803,7 @@ int q6asm_set_pp_params(struct audio_client *ac, } ret = 0; done: + mutex_unlock(&session[session_id].mutex_lock_per_session); kfree(asm_set_param); return ret; } @@ -10313,8 +10352,10 @@ int __init q6asm_init(void) memset(session, 0, sizeof(struct audio_session) * (ASM_ACTIVE_STREAMS_ALLOWED + 1)); - for (lcnt = 0; lcnt <= ASM_ACTIVE_STREAMS_ALLOWED; lcnt++) + for (lcnt = 0; lcnt <= ASM_ACTIVE_STREAMS_ALLOWED; lcnt++) { spin_lock_init(&(session[lcnt].session_lock)); + mutex_init(&(session[lcnt].mutex_lock_per_session)); + } set_custom_topology = 1; /*setup common client used for cal mem map */ -- GitLab From 9c8f0f495fc7f078a30c7f27b96bbc03e0af33d2 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Thu, 2 Aug 2018 19:22:40 +0530 Subject: [PATCH 0434/1645] asoc: qcs405: Fix end to end playback on WSA Fix set sampling rate for RX codec dma interface. Change-Id: Id0e7719a3f6a6a815228f2327d4e11dd93722c07 Signed-off-by: Mangesh Kunchamwar --- asoc/qcs405.c | 52 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index be9ed2f0066a..a91a7e7d4305 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -1223,38 +1223,44 @@ static int cdc_dma_get_sample_rate_val(int sample_rate) case SAMPLING_RATE_8KHZ: sample_rate_val = 0; break; - case SAMPLING_RATE_16KHZ: + case SAMPLING_RATE_11P025KHZ: sample_rate_val = 1; break; - case SAMPLING_RATE_32KHZ: + case SAMPLING_RATE_16KHZ: sample_rate_val = 2; break; - case SAMPLING_RATE_44P1KHZ: + case SAMPLING_RATE_22P05KHZ: sample_rate_val = 3; break; - case SAMPLING_RATE_48KHZ: + case SAMPLING_RATE_32KHZ: sample_rate_val = 4; break; - case SAMPLING_RATE_88P2KHZ: + case SAMPLING_RATE_44P1KHZ: sample_rate_val = 5; break; - case SAMPLING_RATE_96KHZ: + case SAMPLING_RATE_48KHZ: sample_rate_val = 6; break; - case SAMPLING_RATE_176P4KHZ: + case SAMPLING_RATE_88P2KHZ: sample_rate_val = 7; break; - case SAMPLING_RATE_192KHZ: + case SAMPLING_RATE_96KHZ: sample_rate_val = 8; break; - case SAMPLING_RATE_352P8KHZ: + case SAMPLING_RATE_176P4KHZ: sample_rate_val = 9; break; - case SAMPLING_RATE_384KHZ: + case SAMPLING_RATE_192KHZ: sample_rate_val = 10; break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; default: - sample_rate_val = 4; + sample_rate_val = 6; break; } return sample_rate_val; @@ -1269,33 +1275,39 @@ static int cdc_dma_get_sample_rate(int value) sample_rate = SAMPLING_RATE_8KHZ; break; case 1: - sample_rate = SAMPLING_RATE_16KHZ; + sample_rate = SAMPLING_RATE_11P025KHZ; break; case 2: - sample_rate = SAMPLING_RATE_32KHZ; + sample_rate = SAMPLING_RATE_16KHZ; break; case 3: - sample_rate = SAMPLING_RATE_44P1KHZ; + sample_rate = SAMPLING_RATE_22P05KHZ; break; case 4: - sample_rate = SAMPLING_RATE_48KHZ; + sample_rate = SAMPLING_RATE_32KHZ; break; case 5: - sample_rate = SAMPLING_RATE_88P2KHZ; + sample_rate = SAMPLING_RATE_44P1KHZ; break; case 6: - sample_rate = SAMPLING_RATE_96KHZ; + sample_rate = SAMPLING_RATE_48KHZ; break; case 7: - sample_rate = SAMPLING_RATE_176P4KHZ; + sample_rate = SAMPLING_RATE_88P2KHZ; break; case 8: - sample_rate = SAMPLING_RATE_192KHZ; + sample_rate = SAMPLING_RATE_96KHZ; break; case 9: - sample_rate = SAMPLING_RATE_352P8KHZ; + sample_rate = SAMPLING_RATE_176P4KHZ; break; case 10: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 11: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 12: sample_rate = SAMPLING_RATE_384KHZ; break; default: -- GitLab From 542582cba276b459f2443d005276a9b12edca4d1 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 26 Jun 2018 18:41:06 +0530 Subject: [PATCH 0435/1645] dsp: support mdf memory share cmd Add support for MultiDSP framework (MDF) memory share command in q6core driver. Change-Id: Iff0da10fe835f1fce50d2725960ded5c96237955 Signed-off-by: Aditya Bavanari --- dsp/Kbuild | 4 + dsp/msm_audio_ion.c | 22 ++ dsp/msm_mdf.c | 637 ++++++++++++++++++++++++++++++++++++ dsp/q6_init.c | 2 + dsp/q6_init.h | 14 + dsp/q6core.c | 138 +++++++- include/dsp/apr_audio-v2.h | 48 +++ include/dsp/msm_audio_ion.h | 1 + include/dsp/msm_mdf.h | 44 +++ include/dsp/q6core.h | 21 +- 10 files changed, 924 insertions(+), 7 deletions(-) create mode 100644 dsp/msm_mdf.c create mode 100644 include/dsp/msm_mdf.h diff --git a/dsp/Kbuild b/dsp/Kbuild index 1cad5cea65c8..ba5f82cb71ac 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -123,6 +123,10 @@ ifdef CONFIG_MSM_ULTRASOUND USF_OBJS += usf.o usfcdev.o q6usm.o endif +ifdef CONFIG_MSM_MDF + Q6_OBJS += msm_mdf.o +endif + LINUX_INC += -Iinclude/linux INCS += $(COMMON_INC) \ diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index 018b1a9c3c76..5a80916c1f84 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -220,6 +220,28 @@ static int msm_audio_ion_get_phys(struct dma_buf *dma_buf, return rc; } +int msm_audio_ion_get_smmu_info(struct device **cb_dev, + u64 *smmu_sid) +{ + if (!cb_dev || !smmu_sid) { + pr_err("%s: Invalid params\n", + __func__); + return -EINVAL; + } + + if (!msm_audio_ion_data.cb_dev || + !msm_audio_ion_data.smmu_sid_bits) { + pr_err("%s: Params not initialized\n", + __func__); + return -EINVAL; + } + + *cb_dev = msm_audio_ion_data.cb_dev; + *smmu_sid = msm_audio_ion_data.smmu_sid_bits; + + return 0; +} + static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf) { int rc = 0; diff --git a/dsp/msm_mdf.c b/dsp/msm_mdf.c new file mode 100644 index 000000000000..849b76ce230d --- /dev/null +++ b/dsp/msm_mdf.c @@ -0,0 +1,637 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VMID_SSC_Q6 5 +#define VMID_LPASS 6 +#define VMID_MSS_MSA 15 +#define VMID_CDSP 8 + +#define MSM_MDF_PROBED (1 << 0) +#define MSM_MDF_INITIALIZED (1 << 1) +#define MSM_MDF_MEM_ALLOCATED (1 << 2) +#define MSM_MDF_MEM_MAPPED (1 << 3) +#define MSM_MDF_MEM_PERMISSION (1 << 4) /* 0 - HLOS, 1 - Subsys */ + +/* TODO: Update IOVA range for subsys SMMUs */ +#define MSM_MDF_IOVA_START 0x80000000 +#define MSM_MDF_IOVA_LEN 0x800000 + +#define MSM_MDF_SMMU_SID_OFFSET 32 + +#define ADSP_STATE_READY_TIMEOUT_MS 3000 + +enum { + SUBSYS_ADSP, /* Audio DSP must have index 0 */ + SUBSYS_SCC, /* Sensor DSP */ + SUBSYS_MSS, /* Modem DSP */ + SUBSYS_CDSP, /* Compute DSP */ + SUBSYS_MAX, +}; + +struct msm_mdf_mem { + struct device *dev; + uint8_t device_status; + uint32_t map_handle; + struct dma_buf *dma_buf; + dma_addr_t dma_addr; + size_t size; + void *va; +}; + +static struct msm_mdf_mem mdf_mem_data = {NULL,}; + +struct msm_mdf_smmu { + bool enabled; + char *subsys; + int vmid; + uint32_t proc_id; + struct device *cb_dev; + uint8_t device_status; + uint64_t sid; + struct dma_iommu_mapping *mapping; + dma_addr_t pa; + size_t pa_len; +}; + +static struct msm_mdf_smmu mdf_smmu_data[SUBSYS_MAX] = { + { + .subsys = "adsp", + .vmid = VMID_LPASS, + }, + { + .subsys = "dsps", + .vmid = VMID_SSC_Q6, + .proc_id = AVS_MDF_SSC_PROC_ID, + }, + { + .subsys = "modem", + .vmid = VMID_MSS_MSA, + .proc_id = AVS_MDF_MDSP_PROC_ID, + }, + { + .subsys = "cdsp", + .vmid = VMID_CDSP, + .proc_id = AVS_MDF_CDSP_PROC_ID, + }, +}; + +static void *ssr_handle; + +static inline uint64_t buf_page_start(uint64_t buf) +{ + uint64_t start = (uint64_t) buf & PAGE_MASK; + return start; +} + +static inline uint64_t buf_page_offset(uint64_t buf) +{ + uint64_t offset = (uint64_t) buf & (PAGE_SIZE - 1); + return offset; +} + +static inline int buf_num_pages(uint64_t buf, ssize_t len) +{ + uint64_t start = buf_page_start(buf) >> PAGE_SHIFT; + uint64_t end = (((uint64_t) buf + len - 1) & PAGE_MASK) >> PAGE_SHIFT; + int nPages = end - start + 1; + return nPages; +} + +static inline uint64_t buf_page_size(uint32_t size) +{ + uint64_t sz = (size + (PAGE_SIZE - 1)) & PAGE_MASK; + + return sz > PAGE_SIZE ? sz : PAGE_SIZE; +} + +static inline void *uint64_to_ptr(uint64_t addr) +{ + void *ptr = (void *)((uintptr_t)addr); + return ptr; +} + +static inline uint64_t ptr_to_uint64(void *ptr) +{ + uint64_t addr = (uint64_t)((uintptr_t)ptr); + return addr; +} + +static int msm_mdf_dma_buf_map(struct msm_mdf_mem *mem, + struct msm_mdf_smmu *smmu) +{ + int rc = 0; + + if (!smmu) + return -EINVAL; + if (smmu->device_status & MSM_MDF_MEM_MAPPED) + return 0; + if (smmu->enabled) { + if (smmu->cb_dev == NULL) { + pr_err("%s: cb device is not initialized\n", + __func__); + /* Retry if LPASS cb device is not ready + * from audio ION during probing. + */ + if (!strcmp("adsp", smmu->subsys)) { + rc = msm_audio_ion_get_smmu_info(&smmu->cb_dev, + &smmu->sid); + if (rc) { + pr_err("%s: msm_audio_ion_get_smmu_info failed, rc = %d\n", + __func__, rc); + goto err; + } + } else + return -ENODEV; + } + + smmu->pa = dma_map_single(smmu->cb_dev, mem->va, + mem->size, DMA_BIDIRECTIONAL); + if (dma_mapping_error(smmu->cb_dev, smmu->pa)) { + rc = -ENOMEM; + pr_err("%s: failed to map single, rc = %d\n", + __func__, rc); + goto err; + } + smmu->pa_len = mem->size; + + /* Append the SMMU SID information to the IOVA address */ + if (smmu->sid) + smmu->pa |= smmu->sid; + } else { + smmu->pa = mem->dma_addr; + smmu->pa_len = mem->size; + } + pr_err("%s: pa=%pa, pa_len=%zd\n", __func__, + &smmu->pa, smmu->pa_len); + + smmu->device_status |= MSM_MDF_MEM_MAPPED; + + return 0; +err: + return rc; +} + +static int msm_mdf_alloc_dma_buf(struct msm_mdf_mem *mem) +{ + int rc = 0; + + if (!mem) + return -EINVAL; + + if (mem->device_status & MSM_MDF_MEM_ALLOCATED) + return 0; + + if (mem->dev == NULL) { + pr_err("%s: device is not initialized\n", + __func__); + return -ENODEV; + } + + mem->va = dma_alloc_coherent(mem->dev, mem->size, + &mem->dma_addr, GFP_KERNEL); + if (IS_ERR_OR_NULL(mem->va)) { + pr_err("%s: failed to allocate dma memory, rc = %d\n", + __func__, rc); + return -ENOMEM; + } + mem->va = phys_to_virt(mem->dma_addr); + mem->device_status |= MSM_MDF_MEM_ALLOCATED; + return rc; +} + +static int msm_mdf_free_dma_buf(struct msm_mdf_mem *mem) +{ + if (!mem) + return -EINVAL; + + if (mem->dev == NULL) { + pr_err("%s: device is not initialized\n", + __func__); + return -ENODEV; + } + + //dma_free_coherent(mem->dev, mem->size, mem->va, + // mem->dma_addr); + + mem->device_status &= ~MSM_MDF_MEM_ALLOCATED; + return 0; +} + +static int msm_mdf_dma_buf_unmap(struct msm_mdf_mem *mem, + struct msm_mdf_smmu *smmu) +{ + if (!smmu) + return -EINVAL; + + if (smmu->enabled) { + if (smmu->cb_dev == NULL) { + pr_err("%s: cb device is not initialized\n", + __func__); + return -ENODEV; + } + //if (smmu->pa && mem->size) + //dma_unmap_single(smmu->cb_dev, smmu->pa, + // mem->size, DMA_BIDIRECTIONAL); + } + + smmu->device_status &= ~MSM_MDF_MEM_MAPPED; + + return 0; +} + +static int msm_mdf_map_memory_to_subsys(struct msm_mdf_mem *mem, + struct msm_mdf_smmu *smmu) +{ + int rc = 0; + + if (!mem || !smmu) + return -EINVAL; + + /* Map mdf shared memory to ADSP */ + if (!strcmp("adsp", smmu->subsys)) { + rc = q6core_map_memory_regions((phys_addr_t *)&smmu->pa, + ADSP_MEMORY_MAP_MDF_SHMEM_4K_POOL, + (uint32_t *)&smmu->pa_len, 1, &mem->map_handle); + if (rc) { + pr_err("%s: q6core_map_memory_regions failed, rc = %d\n", + __func__, rc); + } + } else { + if (mem->map_handle) { + /* Map mdf shared memory to remote DSPs */ + rc = q6core_map_mdf_shared_memory(mem->map_handle, + (phys_addr_t *)&smmu->pa, smmu->proc_id, + (uint32_t *)&smmu->pa_len, 1); + if (rc) { + pr_err("%s: q6core_map_mdf_shared_memory failed, rc = %d\n", + __func__, rc); + } + } + } + return rc; +} + +static void msm_mdf_unmap_memory_to_subsys(struct msm_mdf_mem *mem, + struct msm_mdf_smmu *smmu) +{ + if (!mem || !smmu) + return; + + if (!strcmp("adsp", smmu->subsys)) { + if (mem->map_handle) + q6core_memory_unmap_regions(mem->map_handle); + } +} + +/** + * msm_mdf_mem_init - Initializes MDF memory pool and + * map memory to subsystem + * + * Returns 0 on success or ret on failure. + */ + +int msm_mdf_mem_init(void) +{ + int rc = 0, i, j; + struct msm_mdf_mem *mem = &mdf_mem_data; + struct msm_mdf_smmu *smmu; + unsigned long timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + int adsp_ready = 0; + + if (!(mdf_mem_data.device_status & MSM_MDF_PROBED)) + return -ENODEV; + + if (mdf_mem_data.device_status & MSM_MDF_INITIALIZED) + return 0; + + /* TODO: pulling may not be needed as Q6 Core state should be + * checked during machine driver probing. + */ + do { + if (!q6core_is_adsp_ready()) { + pr_err("%s: ADSP Audio NOT Ready\n", + __func__); + /* ADSP will be coming up after subsystem restart and + * it might not be fully up when the control reaches + * here. So, wait for 50msec before checking ADSP state + */ + msleep(50); + } else { + pr_debug("%s: ADSP Audio Ready\n", + __func__); + adsp_ready = 1; + break; + } + } while (time_after(timeout, jiffies)); + + if (!adsp_ready) { + pr_err("%s: timed out waiting for ADSP Audio\n", + __func__); + return -ETIMEDOUT; + } + + if (mem->device_status & MSM_MDF_MEM_ALLOCATED) { + for (i = 0; i < SUBSYS_MAX; i++) { + smmu = &mdf_smmu_data[i]; + rc = msm_mdf_dma_buf_map(mem, smmu); + if (rc) { + pr_err("%s: msm_mdf_dma_buf_map failed, rc = %d\n", + __func__, rc); + goto err; + } + } + + for (j = 0; j < SUBSYS_MAX; j++) { + smmu = &mdf_smmu_data[j]; + rc = msm_mdf_map_memory_to_subsys(mem, smmu); + if (rc) { + pr_err("%s: msm_mdf_map_memory_to_subsys failed\n", + __func__); + goto err; + } + } + + mdf_mem_data.device_status |= MSM_MDF_INITIALIZED; + } + return 0; +err: + return rc; +} +EXPORT_SYMBOL(msm_mdf_mem_init); + +int msm_mdf_mem_deinit(void) +{ + int rc = 0, i; + struct msm_mdf_mem *mem = &mdf_mem_data; + struct msm_mdf_smmu *smmu; + + if (!(mdf_mem_data.device_status & MSM_MDF_INITIALIZED)) + return -ENODEV; + + for (i = SUBSYS_MAX - 1; i >= 0; i--) { + smmu = &mdf_smmu_data[i]; + msm_mdf_unmap_memory_to_subsys(mem, smmu); + } + + if (!rc) { + for (i = SUBSYS_MAX - 1; i >= 0; i--) { + smmu = &mdf_smmu_data[i]; + msm_mdf_dma_buf_unmap(mem, smmu); + } + + msm_mdf_free_dma_buf(mem); + mem->device_status &= ~MSM_MDF_MEM_ALLOCATED; + } + + mdf_mem_data.device_status &= ~MSM_MDF_INITIALIZED; + + return 0; +} +EXPORT_SYMBOL(msm_mdf_mem_deinit); + +static int msm_mdf_restart_notifier_cb(struct notifier_block *this, + unsigned long code, + void *_cmd) +{ + static int boot_count = 3; + + /* During LPASS boot, HLOS receives events: + * SUBSYS_BEFORE_POWERUP + * SUBSYS_PROXY_VOTE + * SUBSYS_AFTER_POWERUP - need skip + * SUBSYS_PROXY_UNVOTE + */ + if (boot_count) { + boot_count--; + return NOTIFY_OK; + } + + switch (code) { + case SUBSYS_BEFORE_SHUTDOWN: + pr_debug("Subsys Notify: Shutdown Started\n"); + /* Unmap and free memory upon restart event. */ + msm_mdf_mem_deinit(); + break; + case SUBSYS_AFTER_SHUTDOWN: + pr_debug("Subsys Notify: Shutdown Completed\n"); + break; + case SUBSYS_BEFORE_POWERUP: + pr_debug("Subsys Notify: Bootup Started\n"); + break; + case SUBSYS_AFTER_POWERUP: + pr_debug("Subsys Notify: Bootup Completed\n"); + /* Allocate and map memory after restart complete. */ + if (msm_mdf_mem_init()) + pr_err("msm_mdf_mem_init failed\n"); + break; + default: + pr_err("Subsys Notify: Generel: %lu\n", code); + break; + } + return NOTIFY_DONE; +} + +static const struct of_device_id msm_mdf_match_table[] = { + { .compatible = "qcom,msm-mdf", }, + { .compatible = "qcom,msm-mdf-mem-region", }, + { .compatible = "qcom,msm-mdf-cb", }, + {} +}; +MODULE_DEVICE_TABLE(of, msm_mdf_match_table); + +static int msm_mdf_cb_probe(struct device *dev) +{ + struct msm_mdf_smmu *smmu; + const char *subsys; + int rc = 0, i; + + subsys = of_get_property(dev->of_node, "label", NULL); + if (!subsys) { + dev_err(dev, "%s: could not get label\n", + __func__); + return -EINVAL; + } + + for (i = 0; i < SUBSYS_MAX; i++) { + if (!mdf_smmu_data[i].subsys) + continue; + if (!strcmp(subsys, mdf_smmu_data[i].subsys)) + break; + } + if (i >= SUBSYS_MAX) { + dev_err(dev, "%s: subsys %s not supported\n", + __func__, subsys); + return -EINVAL; + } + + smmu = &mdf_smmu_data[i]; + + smmu->enabled = of_property_read_bool(dev->of_node, + "qcom,smmu-enabled"); + + dev_info(dev, "%s: SMMU is %s for %s\n", __func__, + (smmu->enabled) ? "enabled" : "disabled", + smmu->subsys); + + if (smmu->enabled) { + if (!strcmp("adsp", smmu->subsys)) { + /* Get SMMU info from audio ION */ + rc = msm_audio_ion_get_smmu_info(&smmu->cb_dev, + &smmu->sid); + if (rc) { + dev_err(dev, "%s: msm_audio_ion_get_smmu_info failed, rc = %d\n", + __func__, rc); + goto err; + } + } + } else { + /* Setup SMMU CB if enabled for subsys other than ADSP */ + } + return 0; +err: + return rc; +} + +static int msm_mdf_remove(struct platform_device *pdev) +{ + int rc = 0, i; + + for (i = 0; i < SUBSYS_MAX; i++) { + if (!IS_ERR_OR_NULL(mdf_smmu_data[i].cb_dev)) + arm_iommu_detach_device(mdf_smmu_data[i].cb_dev); + if (!IS_ERR_OR_NULL(mdf_smmu_data[i].mapping)) + arm_iommu_release_mapping(mdf_smmu_data[i].mapping); + mdf_smmu_data[i].enabled = 0; + } + mdf_mem_data.device_status = 0; + + return rc; +} + +static int msm_mdf_probe(struct platform_device *pdev) +{ + int rc = 0; + enum apr_subsys_state q6_state; + struct device *dev = &pdev->dev; + uint32_t mdf_mem_data_size = 0; + + /* TODO: MDF probing should have no dependency + * on ADSP Q6 state. + */ + q6_state = apr_get_q6_state(); + if (q6_state == APR_SUBSYS_DOWN) { + dev_dbg(dev, "defering %s, adsp_state %d\n", + __func__, q6_state); + rc = -EPROBE_DEFER; + goto err; + } else + dev_dbg(dev, "%s: adsp is ready\n", __func__); + + if (of_device_is_compatible(dev->of_node, + "qcom,msm-mdf-cb")) + return msm_mdf_cb_probe(dev); + + if (of_device_is_compatible(dev->of_node, + "qcom,msm-mdf-mem-region")) { + mdf_mem_data.dev = dev; + + rc = of_property_read_u32(dev->of_node, + "qcom,msm-mdf-mem-data-size", + &mdf_mem_data_size); + if (rc) { + dev_dbg(&pdev->dev, "MDF mem data size entry not found\n"); + goto err; + } + + mdf_mem_data.size = mdf_mem_data_size; + dev_info(dev, "%s: mem region size %zd\n", + __func__, mdf_mem_data.size); + msm_mdf_alloc_dma_buf(&mdf_mem_data); + return 0; + } + + rc = of_platform_populate(pdev->dev.of_node, + msm_mdf_match_table, + NULL, &pdev->dev); + if (rc) { + dev_err(&pdev->dev, "%s: failed to populate child nodes", + __func__); + goto err; + } + mdf_mem_data.device_status |= MSM_MDF_PROBED; + +err: + return rc; +} + +static struct platform_driver msm_mdf_driver = { + .probe = msm_mdf_probe, + .remove = msm_mdf_remove, + .driver = { + .name = "msm-mdf", + .owner = THIS_MODULE, + .of_match_table = msm_mdf_match_table, + }, +}; + +static struct notifier_block nb = { + .priority = 0, + .notifier_call = msm_mdf_restart_notifier_cb, +}; + +int __init msm_mdf_init(void) +{ + /* Only need to monitor SSR from ADSP, which + * is the master DSP managing MDF memory. + */ + ssr_handle = subsys_notif_register_notifier("adsp", &nb); + return platform_driver_register(&msm_mdf_driver); +} + +void __exit msm_mdf_exit(void) +{ + platform_driver_unregister(&msm_mdf_driver); + + if (ssr_handle) + subsys_notif_unregister_notifier(ssr_handle, &nb); +} + +MODULE_DESCRIPTION("MSM MDF Module"); +MODULE_LICENSE("GPL v2"); diff --git a/dsp/q6_init.c b/dsp/q6_init.c index 3b885dcb9095..5c194fb06a4d 100644 --- a/dsp/q6_init.c +++ b/dsp/q6_init.c @@ -30,11 +30,13 @@ static int __init audio_q6_init(void) msm_audio_ion_init(); audio_slimslave_init(); avtimer_init(); + msm_mdf_init(); return 0; } static void __exit audio_q6_exit(void) { + msm_mdf_exit(); avtimer_exit(); audio_slimslave_exit(); msm_audio_ion_exit(); diff --git a/dsp/q6_init.h b/dsp/q6_init.h index 971e9b29e177..541fbe762ee3 100644 --- a/dsp/q6_init.h +++ b/dsp/q6_init.h @@ -26,6 +26,20 @@ int rtac_init(void); int msm_audio_ion_init(void); int audio_slimslave_init(void); int avtimer_init(void); +#ifdef CONFIG_MSM_MDF +int msm_mdf_init(void); +void msm_mdf_exit(void); +#else +static inline int msm_mdf_init(void) +{ + return 0; +} + +static inline void msm_mdf_exit(void) +{ + return; +} +#endif void avtimer_exit(void); void audio_slimslave_exit(void); diff --git a/dsp/q6core.c b/dsp/q6core.c index 34f0dd091189..b94d264ff415 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -39,6 +39,8 @@ #define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define APR_ENOTREADY 10 + enum { META_CAL, CUST_TOP_CAL, @@ -274,12 +276,24 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) case AVCS_CMD_SHARED_MEM_UNMAP_REGIONS: pr_debug("%s: Cmd = AVCS_CMD_SHARED_MEM_UNMAP_REGIONS status[0x%x]\n", __func__, payload1[1]); + /* -ADSP status to match Linux error standard */ + q6core_lcl.adsp_status = -payload1[1]; q6core_lcl.bus_bw_resp_received = 1; wake_up(&q6core_lcl.bus_bw_req_wait); break; case AVCS_CMD_SHARED_MEM_MAP_REGIONS: pr_debug("%s: Cmd = AVCS_CMD_SHARED_MEM_MAP_REGIONS status[0x%x]\n", __func__, payload1[1]); + /* -ADSP status to match Linux error standard */ + q6core_lcl.adsp_status = -payload1[1]; + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + break; + case AVCS_CMD_MAP_MDF_SHARED_MEMORY: + pr_debug("%s: Cmd = AVCS_CMD_MAP_MDF_SHARED_MEMORY status[0x%x]\n", + __func__, payload1[1]); + /* -ADSP status to match Linux error standard */ + q6core_lcl.adsp_status = -payload1[1]; q6core_lcl.bus_bw_resp_received = 1; wake_up(&q6core_lcl.bus_bw_req_wait); break; @@ -923,7 +937,7 @@ bool q6core_is_adsp_ready(void) } EXPORT_SYMBOL(q6core_is_adsp_ready); -static int q6core_map_memory_regions(phys_addr_t *buf_add, uint32_t mempool_id, +int q6core_map_memory_regions(phys_addr_t *buf_add, uint32_t mempool_id, uint32_t *bufsz, uint32_t bufcnt, uint32_t *map_handle) { struct avs_cmd_shared_mem_map_regions *mmap_regions = NULL; @@ -951,7 +965,7 @@ static int q6core_map_memory_regions(phys_addr_t *buf_add, uint32_t mempool_id, mmap_regions->hdr.dest_port = 0; mmap_regions->hdr.token = 0; mmap_regions->hdr.opcode = AVCS_CMD_SHARED_MEM_MAP_REGIONS; - mmap_regions->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL & 0x00ff; + mmap_regions->mem_pool_id = mempool_id & 0x00ff; mmap_regions->num_regions = bufcnt & 0x00ff; mmap_regions->property_flag = 0x00; @@ -971,6 +985,7 @@ static int q6core_map_memory_regions(phys_addr_t *buf_add, uint32_t mempool_id, __func__, buf_add, bufsz[0], mmap_regions->num_regions); *map_handle = 0; + q6core_lcl.adsp_status = 0; q6core_lcl.bus_bw_resp_received = 0; ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) mmap_regions); @@ -988,6 +1003,16 @@ static int q6core_map_memory_regions(phys_addr_t *buf_add, uint32_t mempool_id, pr_err("%s: timeout. waited for memory map\n", __func__); ret = -ETIME; goto done; + } else { + /* set ret to 0 as no timeout happened */ + ret = 0; + } + + if (q6core_lcl.adsp_status < 0) { + pr_err("%s: DSP returned error %d\n", + __func__, q6core_lcl.adsp_status); + ret = q6core_lcl.adsp_status; + goto done; } *map_handle = q6core_lcl.mem_map_cal_handle; @@ -996,7 +1021,7 @@ static int q6core_map_memory_regions(phys_addr_t *buf_add, uint32_t mempool_id, return ret; } -static int q6core_memory_unmap_regions(uint32_t mem_map_handle) +int q6core_memory_unmap_regions(uint32_t mem_map_handle) { struct avs_cmd_shared_mem_unmap_regions unmap_regions; int ret = 0; @@ -1015,6 +1040,7 @@ static int q6core_memory_unmap_regions(uint32_t mem_map_handle) unmap_regions.hdr.opcode = AVCS_CMD_SHARED_MEM_UNMAP_REGIONS; unmap_regions.mem_map_handle = mem_map_handle; + q6core_lcl.adsp_status = 0; q6core_lcl.bus_bw_resp_received = 0; pr_debug("%s: unmap regions map handle %d\n", @@ -1037,11 +1063,110 @@ static int q6core_memory_unmap_regions(uint32_t mem_map_handle) __func__); ret = -ETIME; goto done; + } else { + /* set ret to 0 as no timeout happened */ + ret = 0; + } + if (q6core_lcl.adsp_status < 0) { + pr_err("%s: DSP returned error %d\n", + __func__, q6core_lcl.adsp_status); + ret = q6core_lcl.adsp_status; + goto done; } done: return ret; } + +int q6core_map_mdf_shared_memory(uint32_t map_handle, phys_addr_t *buf_add, + uint32_t proc_id, uint32_t *bufsz, uint32_t bufcnt) +{ + struct avs_cmd_map_mdf_shared_memory *mmap_regions = NULL; + struct avs_shared_map_region_payload *mregions = NULL; + void *mmap_region_cmd = NULL; + void *payload = NULL; + int ret = 0; + int i = 0; + int cmd_size = 0; + + cmd_size = sizeof(struct avs_cmd_map_mdf_shared_memory) + + sizeof(struct avs_shared_map_region_payload) + * bufcnt; + + mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL); + if (mmap_region_cmd == NULL) + return -ENOMEM; + + mmap_regions = (struct avs_cmd_map_mdf_shared_memory *)mmap_region_cmd; + mmap_regions->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mmap_regions->hdr.pkt_size = cmd_size; + mmap_regions->hdr.src_port = 0; + mmap_regions->hdr.dest_port = 0; + mmap_regions->hdr.token = 0; + mmap_regions->hdr.opcode = AVCS_CMD_MAP_MDF_SHARED_MEMORY; + mmap_regions->mem_map_handle = map_handle; + mmap_regions->proc_id = proc_id & 0x00ff; + mmap_regions->num_regions = bufcnt & 0x00ff; + + payload = ((u8 *) mmap_region_cmd + + sizeof(struct avs_cmd_map_mdf_shared_memory)); + mregions = (struct avs_shared_map_region_payload *)payload; + + for (i = 0; i < bufcnt; i++) { + mregions->shm_addr_lsw = lower_32_bits(buf_add[i]); + mregions->shm_addr_msw = + msm_audio_populate_upper_32_bits(buf_add[i]); + mregions->mem_size_bytes = bufsz[i]; + ++mregions; + } + + pr_debug("%s: sending mdf memory map, addr %pa, size %d, bufcnt = %d\n", + __func__, buf_add, bufsz[0], mmap_regions->num_regions); + + q6core_lcl.adsp_status = 0; + q6core_lcl.bus_bw_resp_received = 0; + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) + mmap_regions); + if (ret < 0) { + pr_err("%s: mdf memory map failed %d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(q6core_lcl.bus_bw_req_wait, + (q6core_lcl.bus_bw_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: timeout. waited for mdf memory map\n", + __func__); + ret = -ETIME; + goto done; + } else { + /* set ret to 0 as no timeout happened */ + ret = 0; + } + + /* + * When the remote DSP is not ready, the ADSP will validate and store + * the memory information and return APR_ENOTREADY to HLOS. The ADSP + * will map the memory with remote DSP when it is ready. HLOS should + * not treat APR_ENOTREADY as an error. + */ + if (q6core_lcl.adsp_status != -APR_ENOTREADY) { + pr_err("%s: DSP returned error %d\n", + __func__, q6core_lcl.adsp_status); + ret = q6core_lcl.adsp_status; + goto done; + } + +done: + kfree(mmap_region_cmd); + return ret; +} + static int q6core_dereg_all_custom_topologies(void) { int ret = 0; @@ -1119,10 +1244,11 @@ static int q6core_send_custom_topologies(void) q6core_dereg_all_custom_topologies(); - ret = q6core_map_memory_regions(&cal_block->cal_data.paddr, 0, + ret = q6core_map_memory_regions(&cal_block->cal_data.paddr, + ADSP_MEMORY_MAP_SHMEM8_4K_POOL, (uint32_t *)&cal_block->map_data.map_size, 1, &cal_block->map_data.q6map_handle); - if (!ret) { + if (ret) { pr_err("%s: q6core_map_memory_regions failed\n", __func__); goto unlock; } @@ -1172,7 +1298,7 @@ static int q6core_send_custom_topologies(void) ret = q6core_lcl.adsp_status; unmap: ret2 = q6core_memory_unmap_regions(cal_block->map_data.q6map_handle); - if (!ret2) { + if (ret2) { pr_err("%s: q6core_memory_unmap_regions failed for map handle %d\n", __func__, cal_block->map_data.q6map_handle); ret = ret2; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index f4e1f7696636..4ce997384d31 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -4521,6 +4521,7 @@ struct afe_param_id_lpass_core_shared_clk_cfg { #define ADSP_MEMORY_MAP_SMI_POOL 1 #define ADSP_MEMORY_MAP_IMEM_POOL 2 #define ADSP_MEMORY_MAP_SHMEM8_4K_POOL 3 +#define ADSP_MEMORY_MAP_MDF_SHMEM_4K_POOL 4 /* Definition of virtual memory flag */ #define ADSP_MEMORY_MAP_VIRTUAL_MEMORY 1 @@ -4645,6 +4646,53 @@ struct avs_cmdrsp_shared_mem_map_regions { } __packed; +#define AVS_MDF_MDSP_PROC_ID 0x2 +#define AVS_MDF_SSC_PROC_ID 0x3 +#define AVS_MDF_CDSP_PROC_ID 0x4 + +/* Shared memory map command payload used by the + * #AVCS_CMD_MAP_MDF_SHARED_MEMORY. + * + * This structure allows clients to map multiple shared memory + * regions with remote processor ID. All mapped regions must be + * from the same memory pool. Following this structure are + * num_regions of avs_shared_map_region_payload. + */ +struct avs_cmd_map_mdf_shared_memory { + struct apr_hdr hdr; + uint32_t mem_map_handle; +/* Unique identifier for the shared memory address. + * + * The aDSP returns this handle for + * #AVCS_CMD_SHARED_MEM_MAP_REGIONS + * + * Supported values: + * Any 32-bit value + * + * The aDSP uses this handle to retrieve the shared memory + * attributes. This handle can be an abstract representation + * of the shared memory regions that are being mapped. + */ + + uint32_t proc_id; +/* Supported values: + * #AVS_MDF_MDSP_PROC_ID + * #AVS_MDF_SSC_PROC_ID + * #AVS_MDF_CDSP_PROC_ID + */ + + uint32_t num_regions; +/* Number of regions to be mapped with the remote DSP processor + * mentioned by proc_id field. + * + * Array of structures of avs_shared_map_region_payload will follow. + * The address fields in those arrays should correspond to the remote + * processor mentioned by proc_id. + * In case of DSPs with SMMU enabled, the address should be IOVA. + * And for DSPs without SMMU, the address should be physical address. + */ +} __packed; + /*adsp_audio_memmap_api.h*/ /* ASM related data structures */ diff --git a/include/dsp/msm_audio_ion.h b/include/dsp/msm_audio_ion.h index dae1d1d7f485..9235adc1e0e4 100644 --- a/include/dsp/msm_audio_ion.h +++ b/include/dsp/msm_audio_ion.h @@ -33,4 +33,5 @@ int msm_audio_ion_mmap(struct audio_buffer *abuff, struct vm_area_struct *vma); int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op); u32 msm_audio_populate_upper_32_bits(dma_addr_t pa); +int msm_audio_ion_get_smmu_info(struct device **cb_dev, u64 *smmu_sid); #endif /* _LINUX_MSM_AUDIO_ION_H */ diff --git a/include/dsp/msm_mdf.h b/include/dsp/msm_mdf.h new file mode 100644 index 000000000000..5b27f1211ae0 --- /dev/null +++ b/include/dsp/msm_mdf.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _LINUX_MSM_MDF_H +#define _LINUX_MSM_MDF_H + +#ifdef CONFIG_MSM_MDF + +/** + * msm_mdf_mem_init - allocate and map memory to ADSP be shared + * across multiple remote DSPs. + */ +int msm_mdf_mem_init(void); + +/** + * msm_mdf_mem_init - unmap and free memory to ADSP. + */ +int msm_mdf_mem_deinit(void); + +#else + +static inline int msm_mdf_mem_init(void) +{ + return 0; +} + +static inline int msm_mdf_mem_deinit(void) +{ + return 0; +} + +#endif /* CONFIG_MSM_MDF */ + +#endif /* _LINUX_MSM_MDF_H */ diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index cdee048c38bf..4d5a973d2956 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -110,6 +110,20 @@ struct avcs_cmdrsp_get_license_validation_result { #define AVCS_CMDRSP_SHARED_MEM_MAP_REGIONS 0x00012925 #define AVCS_CMD_SHARED_MEM_UNMAP_REGIONS 0x00012926 +/* Commands the AVCS to map multiple shared memory regions with remote + * processor ID. All mapped regions must be from the same memory pool. + * + * Return: + * ADSP_EOK : SUCCESS + * ADSP_EHANDLE : Failed due to incorrect handle. + * ADSP_EBADPARAM : Failed due to bad parameters. + * + * Dependencies: + * The mem_map_handle should be obtained earlier + * using AVCS_CMD_SHARED_MEM_MAP_REGIONS with pool ID + * ADSP_MEMORY_MAP_MDF_SHMEM_4K_POOL. + */ +#define AVCS_CMD_MAP_MDF_SHARED_MEMORY 0x00012930 #define AVCS_CMD_REGISTER_TOPOLOGIES 0x00012923 @@ -183,10 +197,15 @@ struct avcs_cmd_load_unload_topo_modules { } __packed; +int q6core_map_memory_regions(phys_addr_t *buf_add, uint32_t mempool_id, + uint32_t *bufsz, uint32_t bufcnt, uint32_t *map_handle); +int q6core_memory_unmap_regions(uint32_t mem_map_handle); +int q6core_map_mdf_shared_memory(uint32_t map_handle, phys_addr_t *buf_add, + uint32_t proc_id, uint32_t *bufsz, uint32_t bufcnt); + int32_t core_set_license(uint32_t key, uint32_t module_id); int32_t core_get_license_status(uint32_t module_id); int32_t q6core_load_unload_topo_modules(uint32_t topology_id, bool preload_type); - #endif /* __Q6CORE_H__ */ -- GitLab From 6824cec26ba364db72281990694ee596963d76d2 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 31 Jul 2018 12:57:37 +0530 Subject: [PATCH 0436/1645] Asoc: swr: Handle MBHC and IRQ interrupts from tx slave Interrupts will be handled by slave driver. This needs slave pointer to store virtual interrupt and pass it as a parameter to handle_nested_irq. Change-Id: I356102a04b4fda7e5863f809cd848d7a82b82f36 Signed-off-by: Vatsal Bucha --- include/soc/soundwire.h | 3 ++- soc/swr-mstr-ctrl.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/soc/soundwire.h b/include/soc/soundwire.h index d2ebb7621476..28b3b30f8681 100644 --- a/include/soc/soundwire.h +++ b/include/soc/soundwire.h @@ -15,6 +15,7 @@ #include #include #include +#include extern struct bus_type soundwire_type; @@ -204,7 +205,7 @@ struct swr_device { struct device dev; unsigned long addr; u8 group_id; - u8 slave_irq; + struct irq_domain *slave_irq; }; static inline struct swr_device *to_swr_device(struct device *dev) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 68354b81367f..b2449e7e937d 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1078,7 +1078,9 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) if (swr_dev->dev_num != devnum) continue; if (swr_dev->slave_irq) - handle_nested_irq(swr_dev->slave_irq); + handle_nested_irq( + irq_find_mapping( + swr_dev->slave_irq, 0)); } break; case SWRM_INTERRUPT_STATUS_NEW_SLAVE_ATTACHED: -- GitLab From b2b9d42ce12ab0dd6ae6125a5fdd5b8faafd58e8 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 26 Jun 2018 18:42:04 +0530 Subject: [PATCH 0437/1645] asoc: enable MDF initialization in qcs405 target Enable MultiDSP framework (MDF) initialization during qcs405 machine driver registration. Add MDF config to enable compilation of MDF platform driver. Change-Id: I227a0a7b3dd284dcf750c7b424b240f8c3cd1202 Signed-off-by: Aditya Bavanari --- asoc/qcs405.c | 7 +++++++ config/qcs405auto.conf | 1 + config/qcs405autoconf.h | 1 + 3 files changed, 9 insertions(+) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 0045bebc08ac..6e1e6ec4112c 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "device_event.h" #include "msm-pcm-routing-v2.h" #include "codecs/msm-cdc-pinctrl.h" @@ -8402,6 +8403,11 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Sound card %s registered\n", card->name); spdev = pdev; + ret = msm_mdf_mem_init(); + if (ret) + dev_err(&pdev->dev, "msm_mdf_mem_init failed (%d)\n", + ret); + /* Parse pinctrl info from devicetree */ ret = msm_get_pinctrl(pdev); if (!ret) { @@ -8426,6 +8432,7 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) { audio_notifier_deregister("qcs405"); msm_i2s_auxpcm_deinit(); + msm_mdf_mem_deinit(); msm_release_pinctrl(pdev); return 0; diff --git a/config/qcs405auto.conf b/config/qcs405auto.conf index f5a99f1cee34..61620ebb6d39 100644 --- a/config/qcs405auto.conf +++ b/config/qcs405auto.conf @@ -31,6 +31,7 @@ CONFIG_DTS_EAGLE=m CONFIG_DOLBY_DS2=m CONFIG_DOLBY_LICENSE=m CONFIG_DTS_SRS_TM=m +CONFIG_MSM_MDF=m CONFIG_SND_SOC_MSM_STUB=m CONFIG_MSM_AVTIMER=m CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m diff --git a/config/qcs405autoconf.h b/config/qcs405autoconf.h index 4562621c6b95..98cd1660335c 100644 --- a/config/qcs405autoconf.h +++ b/config/qcs405autoconf.h @@ -44,6 +44,7 @@ #define CONFIG_DOLBY_LICENSE 1 #define CONFIG_DTS_SRS_TM 1 #define CONFIG_SND_SOC_MSM_STUB 1 +#define CONFIG_MSM_MDF 1 #define CONFIG_MSM_AVTIMER 1 #define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 #define CONFIG_SND_SOC_EP92 1 -- GitLab From 9776f499e1e0cf292d22e7e98ba709805ed6c311 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 2 Aug 2018 19:53:48 +0530 Subject: [PATCH 0438/1645] Config: sm6150: Enable config for talos Enable irq, core and slave config for talos. Change-Id: I97f702f2bbf6e6acc694bbd32ab3c357d3ae178c Signed-off-by: Vatsal Bucha --- config/sm6150auto.conf | 3 +++ config/sm6150autoconf.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/config/sm6150auto.conf b/config/sm6150auto.conf index cd06ead71d29..1fb50df16f7c 100644 --- a/config/sm6150auto.conf +++ b/config/sm6150auto.conf @@ -42,3 +42,6 @@ CONFIG_WSA_MACRO=m CONFIG_VA_MACRO=m CONFIG_RX_MACRO=m CONFIG_TX_MACRO=m +CONFIG_SND_SOC_WCD_IRQ=m +CONFIG_SND_SOC_WCD937X=m +CONFIG_SND_SOC_WCD937X_SLAVE=m diff --git a/config/sm6150autoconf.h b/config/sm6150autoconf.h index f64e863ad1b4..5cc79c348c7b 100644 --- a/config/sm6150autoconf.h +++ b/config/sm6150autoconf.h @@ -55,3 +55,6 @@ #define CONFIG_VA_MACRO 1 #define CONFIG_RX_MACRO 1 #define CONFIG_TX_MACRO 1 +#define CONFIG_SND_SOC_WCD_IRQ 1 +#define CONFIG_SND_SOC_WCD937X 1 +#define CONFIG_SND_SOC_WCD937X_SLAVE 1 -- GitLab From 759426ec4b0b27130526052867d39d9a618dd679 Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Mon, 14 May 2018 18:21:52 +0530 Subject: [PATCH 0439/1645] ASoC: Add WCD937X slave and core driver Add wcd937x swr slave and codec driver. This adds only basic support for codec registration. Change-Id: I87519a234f14d34a019c8f66652b7224759e639c Signed-off-by: Rohit kumar --- Android.mk | 4 +- asoc/codecs/Kbuild | 1 + asoc/codecs/wcd937x/Android.mk | 57 +++++ asoc/codecs/wcd937x/Kbuild | 110 ++++++++++ asoc/codecs/wcd937x/wcd937x.c | 310 ++++++++++++++++++++++++++++ asoc/codecs/wcd937x/wcd937x_slave.c | 124 +++++++++++ include/soc/soundwire.h | 3 + soc/soundwire.c | 20 ++ 8 files changed, 627 insertions(+), 2 deletions(-) create mode 100644 asoc/codecs/wcd937x/Android.mk create mode 100644 asoc/codecs/wcd937x/Kbuild create mode 100644 asoc/codecs/wcd937x/wcd937x.c create mode 100644 asoc/codecs/wcd937x/wcd937x_slave.c diff --git a/Android.mk b/Android.mk index b4278fa6845b..69bc5fda4cb6 100644 --- a/Android.mk +++ b/Android.mk @@ -30,8 +30,8 @@ include $(MY_LOCAL_PATH)/asoc/codecs/aqt1000/Android.mk endif ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE)),true) -$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/bolero/Module.symvers) -include $(MY_LOCAL_PATH)/asoc/codecs/bolero/Android.mk +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd937x/Module.symvers) +include $(MY_LOCAL_PATH)/asoc/codecs/wcd937x/Android.mk endif ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 662c62f4c529..330a353c00cd 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -186,6 +186,7 @@ ifeq ($(KERNEL_BUILD), 1) obj-y += sdm660_cdc/ obj-y += msm_sdw/ obj-y += wcd9360/ + obj-y += wcd937x/ endif # Module information used by KBuild framework obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd_core_dlkm.o diff --git a/asoc/codecs/wcd937x/Android.mk b/asoc/codecs/wcd937x/Android.mk new file mode 100644 index 000000000000..51c4bc00f0b1 --- /dev/null +++ b/asoc/codecs/wcd937x/Android.mk @@ -0,0 +1,57 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=wcd937x_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd937x.ko +LOCAL_MODULE_KBUILD_NAME := wcd937x_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd937x_slave.ko +LOCAL_MODULE_KBUILD_NAME := wcd937x_slave_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/asoc/codecs/wcd937x/Kbuild b/asoc/codecs/wcd937x/Kbuild new file mode 100644 index 000000000000..087aa44f6107 --- /dev/null +++ b/asoc/codecs/wcd937x/Kbuild @@ -0,0 +1,110 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + + + +ifeq ($(KERNEL_BUILD), 1) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) + ifeq ($(CONFIG_ARCH_SM6150), y) + include $(AUDIO_ROOT)/config/sm6150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + endif +endif + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ WCD937X ############ + +# for WCD937X Codec +ifdef CONFIG_SND_SOC_WCD937X + WCD937X_OBJS += wcd937x.o +endif + +ifdef CONFIG_SND_SOC_WCD937X_SLAVE + WCD937X_SLAVE_OBJS += wcd937x_slave.o +endif + +LINUX_INC += -Iinclude/linux + +INCS += $(COMMON_INC) \ + $(UAPI_INC) + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +ifeq ($(KERNEL_BUILD), 0) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_WCD937X) += wcd937x_dlkm.o +wcd937x_dlkm-y := $(WCD937X_OBJS) + +obj-$(CONFIG_SND_SOC_WCD937X_SLAVE) += wcd937x_slave_dlkm.o +wcd937x_slave_dlkm-y := $(WCD937X_SLAVE_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c new file mode 100644 index 000000000000..e2c6ddf9659f --- /dev/null +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../msm-cdc-pinctrl.h" + +struct wcd937x_priv { + struct device *dev; + struct snd_soc_codec *codec; + struct device_node *rst_np; + struct swr_device *rx_swr_dev; + struct swr_device *tx_swr_dev; +}; + +struct wcd937x_pdata { + struct device_node *rst_np; + struct device_node *rx_slave; + struct device_node *tx_slave; +}; + +static int wcd937x_soc_codec_probe(struct snd_soc_codec *codec) +{ + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + + if (!wcd937x) + return -EINVAL; + + return 0; +} + +static int wcd937x_soc_codec_remove(struct snd_soc_codec *codec) +{ + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + + if (!wcd937x) + return -EINVAL; + + return 0; +} + +static struct regmap *wcd937x_get_regmap(struct device *dev) +{ + struct wcd937x_priv *wcd937x = dev_get_drvdata(dev); + + return wcd937x->regmap; +} + +static const struct snd_kcontrol_new wcd937x_snd_controls[] = { +}; + +static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = { +}; + +static const struct snd_soc_dapm_route wcd937x_audio_map[] = { +}; + +static struct snd_soc_codec_driver soc_codec_dev_wcd937x = { + .probe = wcd937x_soc_codec_probe, + .remove = wcd937x_soc_codec_remove, + .get_regmap = wcd937x_get_regmap, + .component_driver = { + .controls = wcd937x_snd_controls, + .num_controls = ARRAY_SIZE(wcd937x_snd_controls), + .dapm_widgets = wcd937x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wcd937x_dapm_widgets), + .dapm_routes = wcd937x_audio_map, + .num_dapm_routes = ARRAY_SIZE(wcd937x_audio_map), + }, +}; + +int wcd937x_reset(struct device *dev) +{ + struct wcd937x_priv *wcd937x = NULL; + int rc = 0; + int value = 0; + + if (!dev) + return -ENODEV; + + wcd937x = dev_get_drvdata(dev); + if (!wcd937x) + return -EINVAL; + + if (!wcd937x->rst_np) { + dev_err(dev, "%s: reset gpio device node not specified\n", + __func__); + return -EINVAL; + } + + value = msm_cdc_pinctrl_get_state(wcd937x->rst_np); + if (value > 0) + return 0; + + rc = msm_cdc_pinctrl_select_sleep_state(wcd937x->rst_np); + if (rc) { + dev_err(dev, "%s: wcd sleep state request fail!\n", + __func__); + return rc; + } + + /* 20ms sleep required after pulling the reset gpio to LOW */ + msleep(20); + + rc = msm_cdc_pinctrl_select_active_state(wcd937x->rst_np); + if (rc) { + dev_err(dev, "%s: wcd active state request fail!\n", + __func__); + return rc; + } + msleep(20); + + return rc; +} + +struct wcd937x_pdata *wcd937x_populate_dt_data(struct device *dev) +{ + struct wcd937x_pdata *pdata = NULL; + + pdata = devm_kzalloc(dev, sizeof(struct wcd937x_pdata), + GFP_KERNEL); + if (!pdata) + return NULL; + + pdata->rst_np = of_parse_phandle(dev->of_node, + "qcom,wcd937x-reset-node", 0); + if (!pdata->rst_np) { + dev_err(dev, "%s: Looking up %s property in node %s failed\n", + __func__, "qcom,wcd937x-reset-node", + dev->of_node->full_name); + return NULL; + } + + pdata->rx_slave = of_parse_phandle(dev->of_node, "qcom,rx-slave", 0); + pdata->tx_slave = of_parse_phandle(dev->of_node, "qcom,tx-slave", 0); + + return pdata; +} + +static int wcd937x_bind(struct device *dev) +{ + int ret = 0; + struct wcd937x_priv *wcd937x = NULL; + struct wcd937x_pdata *pdata = NULL; + + wcd937x = devm_kzalloc(dev, sizeof(struct wcd937x_priv), GFP_KERNEL); + if (!wcd937x) + return -ENOMEM; + + dev_set_drvdata(dev, wcd937x); + + pdata = wcd937x_populate_dt_data(dev); + if (!pdata) { + dev_err(dev, "%s: Fail to obtain platform data\n", __func__); + return -EINVAL; + } + + wcd937x->rst_np = pdata->rst_np; + wcd937x_reset(dev); + /* + * Add 5msec delay to provide sufficient time for + * soundwire auto enumeration of slave devices as + * as per HW requirement. + */ + usleep_range(5000, 5010); + ret = component_bind_all(dev, wcd937x); + if (ret) { + dev_err(dev, "%s: Slave bind failed, ret = %d\n", + __func__, ret); + return ret; + } + + wcd937x->rx_swr_dev = get_matching_swr_slave_device(pdata->rx_slave); + if (!wcd937x->rx_swr_dev) { + dev_err(dev, "%s: Could not find RX swr slave device\n", + __func__); + ret = -ENODEV; + goto err; + } + + wcd937x->tx_swr_dev = get_matching_swr_slave_device(pdata->tx_slave); + if (!wcd937x->tx_swr_dev) { + dev_err(dev, "%s: Could not find TX swr slave device\n", + __func__); + ret = -ENODEV; + goto err; + } + + ret = snd_soc_register_codec(dev, &soc_codec_dev_wcd937x, + NULL, 0); + if (ret) { + dev_err(dev, "%s: Codec registration failed\n", + __func__); + goto err; + } + + return ret; +err: + component_unbind_all(dev, wcd937x); + return ret; +} + +static void wcd937x_unbind(struct device *dev) +{ + struct wcd937x_priv *wcd937x = dev_get_drvdata(dev); + + snd_soc_unregister_codec(dev); + component_unbind_all(dev, wcd937x); +} + +static const struct of_device_id wcd937x_dt_match[] = { + { .compatible = "qcom,wcd937x-codec" }, + {} +}; + +static const struct component_master_ops wcd937x_comp_ops = { + .bind = wcd937x_bind, + .unbind = wcd937x_unbind, +}; + +static int wcd937x_compare_of(struct device *dev, void *data) +{ + return dev->of_node == data; +} + +static void wcd937x_release_of(struct device *dev, void *data) +{ + of_node_put(data); +} + +static int wcd937x_add_slave_components(struct device *dev, + struct component_match **matchptr) +{ + struct device_node *np, *rx_node, *tx_node; + + np = dev->of_node; + + rx_node = of_parse_phandle(np, "qcom,rx-slave", 0); + if (!rx_node) { + dev_err(dev, "%s: Rx-slave node not defined\n", __func__); + return -ENODEV; + } + of_node_get(rx_node); + component_match_add_release(dev, matchptr, + wcd937x_release_of, + wcd937x_compare_of, + rx_node); + + tx_node = of_parse_phandle(np, "qcom,tx-slave", 0); + if (!tx_node) { + dev_err(dev, "%s: Tx-slave node not defined\n", __func__); + return -ENODEV; + } + of_node_get(tx_node); + component_match_add_release(dev, matchptr, + wcd937x_release_of, + wcd937x_compare_of, + tx_node); + return 0; +} + +static int wcd937x_probe(struct platform_device *pdev) +{ + struct component_match *match = NULL; + int ret; + + ret = wcd937x_add_slave_components(&pdev->dev, &match); + if (ret) + return ret; + + return component_master_add_with_match(&pdev->dev, + &wcd937x_comp_ops, match); +} + +static int wcd937x_remove(struct platform_device *pdev) +{ + component_master_del(&pdev->dev, &wcd937x_comp_ops); + return 0; +} + +static struct platform_driver wcd937x_codec_driver = { + .probe = wcd937x_probe, + .remove = wcd937x_remove, + .driver = { + .name = "wcd937x_codec", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(wcd937x_dt_match), + }, +}; + +module_platform_driver(wcd937x_codec_driver); +MODULE_DESCRIPTION("WCD937X Codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/wcd937x/wcd937x_slave.c b/asoc/codecs/wcd937x/wcd937x_slave.c new file mode 100644 index 000000000000..36c2af1e710e --- /dev/null +++ b/asoc/codecs/wcd937x/wcd937x_slave.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +struct wcd937x_slave_priv { + struct swr_device *swr_slave; +}; + +static int wcd937x_slave_bind(struct device *dev, + struct device *master, void *data) +{ + int ret = 0; + struct wcd937x_slave_priv *wcd937x_slave = NULL; + uint8_t devnum = 0; + struct swr_device *pdev = to_swr_device(dev); + + wcd937x_slave = devm_kzalloc(&pdev->dev, + sizeof(struct wcd937x_slave_priv), GFP_KERNEL); + if (!wcd937x_slave) + return -ENOMEM; + + swr_set_dev_data(pdev, wcd937x_slave); + + wcd937x_slave->swr_slave = pdev; + + ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum); + if (ret) { + dev_dbg(&pdev->dev, + "%s get devnum %d for dev addr %lx failed\n", + __func__, devnum, pdev->addr); + swr_remove_device(pdev); + return ret; + } + pdev->dev_num = devnum; + + return ret; +} + +static void wcd937x_slave_unbind(struct device *dev, + struct device *master, void *data) +{ + struct wcd937x_slave_priv *wcd937x_slave = NULL; + struct swr_device *pdev = to_swr_device(dev); + + wcd937x_slave = swr_get_dev_data(pdev); + if (!wcd937x_slave) { + dev_err(&pdev->dev, "%s: wcd937x_slave is NULL\n", __func__); + return; + } + + swr_set_dev_data(pdev, NULL); +} + +static const struct swr_device_id wcd937x_swr_id[] = { + {"wcd937x-slave", 0}, + {} +}; + +static const struct of_device_id wcd937x_swr_dt_match[] = { + { + .compatible = "qcom,wcd937x-slave", + }, + {} +}; + +static const struct component_ops wcd937x_slave_comp_ops = { + .bind = wcd937x_slave_bind, + .unbind = wcd937x_slave_unbind, +}; + +static int wcd937x_swr_probe(struct swr_device *pdev) +{ + return component_add(&pdev->dev, &wcd937x_slave_comp_ops); +} + +static int wcd937x_swr_remove(struct swr_device *pdev) +{ + component_del(&pdev->dev, &wcd937x_slave_comp_ops); + return 0; +} + +static struct swr_driver wcd937x_slave_driver = { + .driver = { + .name = "wcd937x-slave", + .owner = THIS_MODULE, + .of_match_table = wcd937x_swr_dt_match, + }, + .probe = wcd937x_swr_probe, + .remove = wcd937x_swr_remove, + .id_table = wcd937x_swr_id, +}; + +static int __init wcd937x_slave_init(void) +{ + return swr_driver_register(&wcd937x_slave_driver); +} + +static void __exit wcd937x_slave_exit(void) +{ + swr_driver_unregister(&wcd937x_slave_driver); +} + +module_init(wcd937x_slave_init); +module_exit(wcd937x_slave_exit); + +MODULE_DESCRIPTION("WCD937X Swr Slave driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/soc/soundwire.h b/include/soc/soundwire.h index d2ebb7621476..c0ce11a6ae14 100644 --- a/include/soc/soundwire.h +++ b/include/soc/soundwire.h @@ -334,4 +334,7 @@ extern int swr_slvdev_datapath_control(struct swr_device *swr_dev, u8 dev_num, extern int swr_remove_from_group(struct swr_device *dev, u8 dev_num); extern void swr_remove_device(struct swr_device *swr_dev); + +extern struct swr_device *get_matching_swr_slave_device(struct device_node *np); + #endif /* _LINUX_SOUNDWIRE_H */ diff --git a/soc/soundwire.c b/soc/soundwire.c index f05a5f9b1fb5..51aa43ab2776 100644 --- a/soc/soundwire.c +++ b/soc/soundwire.c @@ -792,6 +792,26 @@ void swr_master_add_boarddevices(struct swr_master *master) } EXPORT_SYMBOL(swr_master_add_boarddevices); +struct swr_device *get_matching_swr_slave_device(struct device_node *np) +{ + struct swr_device *swr = NULL; + struct swr_master *master; + + mutex_lock(&board_lock); + list_for_each_entry(master, &swr_master_list, list) { + mutex_lock(&master->mlock); + list_for_each_entry(swr, &master->devices, dev_list) { + if (swr->dev.of_node == np) + break; + } + mutex_unlock(&master->mlock); + } + mutex_unlock(&board_lock); + + return swr; +} +EXPORT_SYMBOL(get_matching_swr_slave_device); + static void swr_unregister_device(struct swr_device *swr) { if (swr) -- GitLab From 0b26ab3e61d7c325c45e03c9284b646e2f78fe8d Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 3 Aug 2018 23:53:01 +0530 Subject: [PATCH 0440/1645] asoc: sm6150: Fix sampling rate enum mismatch Fix set sampling rates for Rx Codec DMA interfaces. Use uint32 instead of boolean properties for audio interfaces and tavil codec enablement in sm6150 target. CRs-Fixed: 2281591 Change-Id: Id5cb212a8e319437c0efd02e9a900eedf63eae58 Signed-off-by: Aditya Bavanari --- asoc/sm6150.c | 252 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 166 insertions(+), 86 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index de76951a1295..f7105d4953ac 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -39,6 +39,7 @@ #include "codecs/wsa881x.h" #include "codecs/bolero/bolero-cdc.h" #include +#include "codecs/bolero/wsa-macro.h" #define DRV_NAME "sm6150-asoc-snd" @@ -496,10 +497,13 @@ static const char *const cdc_dma_rx_ch_text[] = {"One", "Two"}; static const char *const cdc_dma_tx_ch_text[] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; -static char const *cdc_dma_sample_rate_text[] = {"KHZ_8", "KHZ_16", - "KHZ_32", "KHZ_44P1", "KHZ_48", - "KHZ_88P2", "KHZ_96", "KHZ_176P4", - "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static char const *cdc_dma_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", + "KHZ_176P4", "KHZ_192", + "KHZ_352P8", "KHZ_384"}; + static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text); @@ -1323,6 +1327,7 @@ static int cdc_dma_rx_format_put(struct snd_kcontrol *kcontrol, return rc; } + static int cdc_dma_get_sample_rate_val(int sample_rate) { int sample_rate_val = 0; @@ -1331,38 +1336,44 @@ static int cdc_dma_get_sample_rate_val(int sample_rate) case SAMPLING_RATE_8KHZ: sample_rate_val = 0; break; - case SAMPLING_RATE_16KHZ: + case SAMPLING_RATE_11P025KHZ: sample_rate_val = 1; break; - case SAMPLING_RATE_32KHZ: + case SAMPLING_RATE_16KHZ: sample_rate_val = 2; break; - case SAMPLING_RATE_44P1KHZ: + case SAMPLING_RATE_22P05KHZ: sample_rate_val = 3; break; - case SAMPLING_RATE_48KHZ: + case SAMPLING_RATE_32KHZ: sample_rate_val = 4; break; - case SAMPLING_RATE_88P2KHZ: + case SAMPLING_RATE_44P1KHZ: sample_rate_val = 5; break; - case SAMPLING_RATE_96KHZ: + case SAMPLING_RATE_48KHZ: sample_rate_val = 6; break; - case SAMPLING_RATE_176P4KHZ: + case SAMPLING_RATE_88P2KHZ: sample_rate_val = 7; break; - case SAMPLING_RATE_192KHZ: + case SAMPLING_RATE_96KHZ: sample_rate_val = 8; break; - case SAMPLING_RATE_352P8KHZ: + case SAMPLING_RATE_176P4KHZ: sample_rate_val = 9; break; - case SAMPLING_RATE_384KHZ: + case SAMPLING_RATE_192KHZ: sample_rate_val = 10; break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; default: - sample_rate_val = 4; + sample_rate_val = 6; break; } return sample_rate_val; @@ -1377,33 +1388,39 @@ static int cdc_dma_get_sample_rate(int value) sample_rate = SAMPLING_RATE_8KHZ; break; case 1: - sample_rate = SAMPLING_RATE_16KHZ; + sample_rate = SAMPLING_RATE_11P025KHZ; break; case 2: - sample_rate = SAMPLING_RATE_32KHZ; + sample_rate = SAMPLING_RATE_16KHZ; break; case 3: - sample_rate = SAMPLING_RATE_44P1KHZ; + sample_rate = SAMPLING_RATE_22P05KHZ; break; case 4: - sample_rate = SAMPLING_RATE_48KHZ; + sample_rate = SAMPLING_RATE_32KHZ; break; case 5: - sample_rate = SAMPLING_RATE_88P2KHZ; + sample_rate = SAMPLING_RATE_44P1KHZ; break; case 6: - sample_rate = SAMPLING_RATE_96KHZ; + sample_rate = SAMPLING_RATE_48KHZ; break; case 7: - sample_rate = SAMPLING_RATE_176P4KHZ; + sample_rate = SAMPLING_RATE_88P2KHZ; break; case 8: - sample_rate = SAMPLING_RATE_192KHZ; + sample_rate = SAMPLING_RATE_96KHZ; break; case 9: - sample_rate = SAMPLING_RATE_352P8KHZ; + sample_rate = SAMPLING_RATE_176P4KHZ; break; case 10: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 11: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 12: sample_rate = SAMPLING_RATE_384KHZ; break; default: @@ -1413,7 +1430,6 @@ static int cdc_dma_get_sample_rate(int value) return sample_rate; } - static int cdc_dma_rx_sample_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1639,7 +1655,6 @@ static int cdc_dma_tx_format_put(struct snd_kcontrol *kcontrol, return rc; } -/***************/ static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -3763,7 +3778,7 @@ static int msm_dmic_event(struct snd_soc_dapm_widget *w, struct msm_asoc_mach_data *pdata = NULL; struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); int ret = 0; - uint32_t dmic_idx; + u32 dmic_idx; int *dmic_gpio_cnt; struct device_node *dmic_gpio; char *wname; @@ -4839,6 +4854,7 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct snd_card *card; struct snd_info_entry *entry; + struct snd_soc_component *aux_comp; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); @@ -4860,23 +4876,43 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets, ARRAY_SIZE(msm_int_dapm_widgets)); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); snd_soc_dapm_ignore_suspend(dapm, "Analog Mic1"); snd_soc_dapm_ignore_suspend(dapm, "Analog Mic2"); snd_soc_dapm_ignore_suspend(dapm, "Analog Mic3"); snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4"); - snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); - snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); - snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); - snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); + snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK1 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK2 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "WSA AIF VI"); + snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_WSA"); snd_soc_dapm_sync(dapm); + /* + * Send speaker configuration only for WSA8810. + * Default configuration is for WSA8815. + */ + dev_dbg(codec->dev, "%s: Number of aux devices: %d\n", + __func__, rtd->card->num_aux_devs); + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->component_dev_list)) { + aux_comp = list_first_entry( + &rtd->card->component_dev_list, + struct snd_soc_component, + card_aux_list); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { + wsa_macro_set_spkr_mode(rtd->codec, + WSA_MACRO_SPKR_MODE_1); + wsa_macro_set_spkr_gain_offset(rtd->codec, + WSA_MACRO_GAIN_OFFSET_M1P5_DB); + } + } card = rtd->card->snd_card; entry = snd_info_create_subdir(card->module, "codecs", card->proc_root); @@ -7299,20 +7335,6 @@ static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = { .ignore_suspend = 1, .ops = &msm_cdc_dma_be_ops, }, - { - .name = LPASS_BE_WSA_CDC_DMA_TX_2, - .stream_name = "WSA CDC DMA2 Capture", - .cpu_dai_name = "msm-dai-cdc-dma-dev.45061", - .platform_name = "msm-pcm-routing", - .codec_name = "bolero_codec", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_cdc_dma_be_ops, - }, }; static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { @@ -7679,7 +7701,10 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) { struct snd_soc_card *card = NULL; struct snd_soc_dai_link *dailink; - int total_links = 0; + int total_links = 0, rc = 0; + u32 tavil_codec = 0, auxpcm_audio_intf = 0; + u32 mi2s_audio_intf = 0, ext_disp_audio_intf = 0; + u32 wcn_btfm_intf = 0; const struct of_device_id *match; match = of_match_node(sm6150_asoc_machine_of_match, dev->of_node); @@ -7703,20 +7728,29 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) total_links += ARRAY_SIZE(msm_common_misc_fe_dai_links); - if (of_property_read_bool(dev->of_node, "qcom,tavil_codec")) { - - dev_dbg(dev, "%s(): Tavil codec is present\n", + rc = of_property_read_u32(dev->of_node, "qcom,tavil_codec", + &tavil_codec); + if (rc) { + dev_dbg(dev, "%s: No DT match for tavil codec\n", __func__); - card->late_probe = msm_snd_card_tavil_late_probe; - memcpy(msm_sm6150_dai_links + total_links, + } else { + if (tavil_codec) { + card->late_probe = + msm_snd_card_tavil_late_probe; + memcpy(msm_sm6150_dai_links + total_links, msm_tavil_fe_dai_links, sizeof(msm_tavil_fe_dai_links)); - total_links += ARRAY_SIZE(msm_tavil_fe_dai_links); - } else { + total_links += + ARRAY_SIZE(msm_tavil_fe_dai_links); + } + } + + if (!tavil_codec) { memcpy(msm_sm6150_dai_links + total_links, - msm_bolero_fe_dai_links, - sizeof(msm_bolero_fe_dai_links)); - total_links += ARRAY_SIZE(msm_bolero_fe_dai_links); + msm_bolero_fe_dai_links, + sizeof(msm_bolero_fe_dai_links)); + total_links += + ARRAY_SIZE(msm_bolero_fe_dai_links); } memcpy(msm_sm6150_dai_links + total_links, @@ -7725,7 +7759,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) total_links += ARRAY_SIZE(msm_common_be_dai_links); - if (of_property_read_bool(dev->of_node, "qcom,tavil_codec")) { + if (tavil_codec) { memcpy(msm_sm6150_dai_links + total_links, msm_tavil_be_dai_links, sizeof(msm_tavil_be_dai_links)); @@ -7734,7 +7768,8 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) memcpy(msm_sm6150_dai_links + total_links, msm_wsa_cdc_dma_be_dai_links, sizeof(msm_wsa_cdc_dma_be_dai_links)); - total_links += ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links); + total_links += + ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links); memcpy(msm_sm6150_dai_links + total_links, msm_rx_tx_cdc_dma_be_dai_links, @@ -7743,37 +7778,69 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links); } - if (of_property_read_bool(dev->of_node, - "qcom,ext-disp-audio-rx")) { - dev_dbg(dev, "%s(): External display audio support present\n", + rc = of_property_read_u32(dev->of_node, + "qcom,ext-disp-audio-rx", + &ext_disp_audio_intf); + if (rc) { + dev_dbg(dev, "%s: No DT match Ext Disp interface\n", __func__); - memcpy(msm_sm6150_dai_links + total_links, - ext_disp_be_dai_link, - sizeof(ext_disp_be_dai_link)); - total_links += ARRAY_SIZE(ext_disp_be_dai_link); + } else { + if (auxpcm_audio_intf) { + memcpy(msm_sm6150_dai_links + total_links, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + total_links += + ARRAY_SIZE(ext_disp_be_dai_link); + } } - if (of_property_read_bool(dev->of_node, - "qcom,mi2s-audio-intf")) { - memcpy(msm_sm6150_dai_links + total_links, - msm_mi2s_be_dai_links, - sizeof(msm_mi2s_be_dai_links)); - total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); + + rc = of_property_read_u32(dev->of_node, "qcom,mi2s-audio-intf", + &mi2s_audio_intf); + if (rc) { + dev_dbg(dev, "%s: No DT match MI2S audio interface\n", + __func__); + } else { + if (mi2s_audio_intf) { + memcpy(msm_sm6150_dai_links + total_links, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + total_links += + ARRAY_SIZE(msm_mi2s_be_dai_links); + } } - if (of_property_read_bool(dev->of_node, - "qcom,auxpcm-audio-intf")) { - memcpy(msm_sm6150_dai_links + total_links, - msm_auxpcm_be_dai_links, - sizeof(msm_auxpcm_be_dai_links)); - total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links); + + + rc = of_property_read_u32(dev->of_node, "qcom,wcn-btfm", + &wcn_btfm_intf); + if (rc) { + dev_dbg(dev, "%s: No DT match wcn btfm interface\n", + __func__); + } else { + if (wcn_btfm_intf) { + memcpy(msm_sm6150_dai_links + total_links, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + total_links += + ARRAY_SIZE(msm_wcn_be_dai_links); + } } - if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { - dev_dbg(dev, "%s(): WCN BTFM support present\n", - __func__); - memcpy(msm_sm6150_dai_links + total_links, - msm_wcn_be_dai_links, - sizeof(msm_wcn_be_dai_links)); - total_links += ARRAY_SIZE(msm_wcn_be_dai_links); + + rc = of_property_read_u32(dev->of_node, + "qcom,auxpcm-audio-intf", + &auxpcm_audio_intf); + if (rc) { + dev_dbg(dev, "%s: No DT match Aux PCM interface\n", + __func__); + } else { + if (auxpcm_audio_intf) { + memcpy(msm_sm6150_dai_links + total_links, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + total_links += + ARRAY_SIZE(msm_auxpcm_be_dai_links); + } } + dailink = msm_sm6150_dai_links; } else if (!strcmp(match->data, "stub_codec")) { card = &snd_soc_card_stub_msm; @@ -7858,6 +7925,19 @@ static int msm_wsa881x_init(struct snd_soc_component *component) static int msm_aux_codec_init(struct snd_soc_component *component) { + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + + snd_soc_dapm_ignore_suspend(dapm, "EAR"); + snd_soc_dapm_ignore_suspend(dapm, "AUX"); + snd_soc_dapm_ignore_suspend(dapm, "HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC4"); + snd_soc_dapm_sync(dapm); + return 0; } @@ -8326,7 +8406,7 @@ static struct platform_driver sm6150_asoc_machine_driver = { }; module_platform_driver(sm6150_asoc_machine_driver); -MODULE_DESCRIPTION("ALSA SoC msm"); +MODULE_DESCRIPTION("ALSA SoC SM6150 Machine driver"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:" DRV_NAME); MODULE_DEVICE_TABLE(of, sm6150_asoc_machine_of_match); -- GitLab From 9b37ac95f1ef804df18fe9c86bfea5edd28ca9be Mon Sep 17 00:00:00 2001 From: Tanya Dixit Date: Fri, 27 Jul 2018 16:52:47 +0530 Subject: [PATCH 0441/1645] asoc: codecs: Tanggu TX RX changes Tanggu codec driver changes for RX and TX widgets, dapm sequences and routes update. CRs-Fixed: 2281591 Change-Id: I769255e80c8569f7d954a5e5e5c62b8048d62b0b Signed-off-by: Tanya Dixit --- asoc/codecs/wcd937x/Kbuild | 2 + asoc/codecs/wcd937x/internal.h | 58 ++ asoc/codecs/wcd937x/wcd937x-registers.h | 446 +++++++++ asoc/codecs/wcd937x/wcd937x-regmap.c | 462 +++++++++ asoc/codecs/wcd937x/wcd937x-tables.c | 432 +++++++++ asoc/codecs/wcd937x/wcd937x.c | 1148 ++++++++++++++++++++++- 6 files changed, 2525 insertions(+), 23 deletions(-) create mode 100644 asoc/codecs/wcd937x/internal.h create mode 100644 asoc/codecs/wcd937x/wcd937x-registers.h create mode 100644 asoc/codecs/wcd937x/wcd937x-regmap.c create mode 100644 asoc/codecs/wcd937x/wcd937x-tables.c diff --git a/asoc/codecs/wcd937x/Kbuild b/asoc/codecs/wcd937x/Kbuild index 087aa44f6107..20c4d4682baa 100644 --- a/asoc/codecs/wcd937x/Kbuild +++ b/asoc/codecs/wcd937x/Kbuild @@ -52,6 +52,8 @@ COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) # for WCD937X Codec ifdef CONFIG_SND_SOC_WCD937X WCD937X_OBJS += wcd937x.o + WCD937X_OBJS += wcd937x-regmap.o + WCD937X_OBJS += wcd937x-tables.o endif ifdef CONFIG_SND_SOC_WCD937X_SLAVE diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h new file mode 100644 index 000000000000..dcb7fd8dd78e --- /dev/null +++ b/asoc/codecs/wcd937x/internal.h @@ -0,0 +1,58 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _WCD937X_INTERNAL_H +#define _WCD937X_INTERNAL_H + +#include "../wcd-mbhc-v2.h" + +#define WCD937X_MAX_MICBIAS 3 + +extern struct regmap_config wcd937x_regmap_config; + +struct wcd937x_priv { + struct device *dev; + + int variant; + struct snd_soc_codec *codec; + struct device_node *rst_np; + struct regmap *regmap; + + struct swr_device *rx_swr_dev; + struct swr_device *tx_swr_dev; + + s32 micb_ref[WCD937X_MAX_MICBIAS]; + s32 pullup_ref[WCD937X_MAX_MICBIAS]; + + struct fw_info *fw_data; + struct device_node *wcd_rst_np; + + s32 dmic_0_1_clk_cnt; + s32 dmic_2_3_clk_cnt; + s32 dmic_4_5_clk_cnt; + /* mbhc module */ + struct wcd_mbhc mbhc; + struct blocking_notifier_head notifier; + struct mutex micb_lock; + + u32 hph_mode; + + u32 rx_clk_cnt; +}; + +struct wcd937x_pdata { + struct device_node *rst_np; + struct device_node *rx_slave; + struct device_node *tx_slave; +}; + +#endif diff --git a/asoc/codecs/wcd937x/wcd937x-registers.h b/asoc/codecs/wcd937x/wcd937x-registers.h new file mode 100644 index 000000000000..1f89f803c0d3 --- /dev/null +++ b/asoc/codecs/wcd937x/wcd937x-registers.h @@ -0,0 +1,446 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _WCD937X_REGISTERS_H +#define _WCD937X_REGISTERS_H + +#define WCD937X_BASE_ADDRESS 0x3000 + +#define WCD937X_REG(reg) (reg - WCD937X_BASE_ADDRESS) + +enum { + REG_NO_ACCESS, + RD_REG, + WR_REG, + RD_WR_REG +}; + +#define WCD937X_ANA_BIAS (WCD937X_BASE_ADDRESS+0x001) +#define WCD937X_ANA_RX_SUPPLIES (WCD937X_BASE_ADDRESS+0x008) +#define WCD937X_ANA_HPH (WCD937X_BASE_ADDRESS+0x009) +#define WCD937X_ANA_EAR (WCD937X_BASE_ADDRESS+0x00A) +#define WCD937X_ANA_EAR_COMPANDER_CTL (WCD937X_BASE_ADDRESS+0x00B) +#define WCD937X_ANA_TX_CH1 (WCD937X_BASE_ADDRESS+0x00E) +#define WCD937X_ANA_TX_CH2 (WCD937X_BASE_ADDRESS+0x00F) +#define WCD937X_ANA_TX_CH3 (WCD937X_BASE_ADDRESS+0x010) +#define WCD937X_ANA_TX_CH3_HPF (WCD937X_BASE_ADDRESS+0x011) +#define WCD937X_ANA_MICB1_MICB2_DSP_EN_LOGIC (WCD937X_BASE_ADDRESS+0x012) +#define WCD937X_ANA_MICB3_DSP_EN_LOGIC (WCD937X_BASE_ADDRESS+0x013) +#define WCD937X_ANA_MBHC_MECH (WCD937X_BASE_ADDRESS+0x014) +#define WCD937X_ANA_MBHC_ELECT (WCD937X_BASE_ADDRESS+0x015) +#define WCD937X_ANA_MBHC_ZDET (WCD937X_BASE_ADDRESS+0x016) +#define WCD937X_ANA_MBHC_RESULT_1 (WCD937X_BASE_ADDRESS+0x017) +#define WCD937X_ANA_MBHC_RESULT_2 (WCD937X_BASE_ADDRESS+0x018) +#define WCD937X_ANA_MBHC_RESULT_3 (WCD937X_BASE_ADDRESS+0x019) +#define WCD937X_ANA_MBHC_BTN0 (WCD937X_BASE_ADDRESS+0x01A) +#define WCD937X_ANA_MBHC_BTN1 (WCD937X_BASE_ADDRESS+0x01B) +#define WCD937X_ANA_MBHC_BTN2 (WCD937X_BASE_ADDRESS+0x01C) +#define WCD937X_ANA_MBHC_BTN3 (WCD937X_BASE_ADDRESS+0x01D) +#define WCD937X_ANA_MBHC_BTN4 (WCD937X_BASE_ADDRESS+0x01E) +#define WCD937X_ANA_MBHC_BTN5 (WCD937X_BASE_ADDRESS+0x01F) +#define WCD937X_ANA_MBHC_BTN6 (WCD937X_BASE_ADDRESS+0x020) +#define WCD937X_ANA_MBHC_BTN7 (WCD937X_BASE_ADDRESS+0x021) +#define WCD937X_ANA_MICB1 (WCD937X_BASE_ADDRESS+0x022) +#define WCD937X_ANA_MICB2 (WCD937X_BASE_ADDRESS+0x023) +#define WCD937X_ANA_MICB2_RAMP (WCD937X_BASE_ADDRESS+0x024) +#define WCD937X_ANA_MICB3 (WCD937X_BASE_ADDRESS+0x025) +#define WCD937X_BIAS_CTL (WCD937X_BASE_ADDRESS+0x028) +#define WCD937X_BIAS_VBG_FINE_ADJ (WCD937X_BASE_ADDRESS+0x029) +#define WCD937X_LDOL_VDDCX_ADJUST (WCD937X_BASE_ADDRESS+0x040) +#define WCD937X_LDOL_DISABLE_LDOL (WCD937X_BASE_ADDRESS+0x041) +#define WCD937X_MBHC_CTL_CLK (WCD937X_BASE_ADDRESS+0x056) +#define WCD937X_MBHC_CTL_ANA (WCD937X_BASE_ADDRESS+0x057) +#define WCD937X_MBHC_CTL_SPARE_1 (WCD937X_BASE_ADDRESS+0x058) +#define WCD937X_MBHC_CTL_SPARE_2 (WCD937X_BASE_ADDRESS+0x059) +#define WCD937X_MBHC_CTL_BCS (WCD937X_BASE_ADDRESS+0x05A) +#define WCD937X_MBHC_MOISTURE_DET_FSM_STATUS (WCD937X_BASE_ADDRESS+0x05B) +#define WCD937X_MBHC_TEST_CTL (WCD937X_BASE_ADDRESS+0x05C) +#define WCD937X_LDOH_MODE (WCD937X_BASE_ADDRESS+0x067) +#define WCD937X_LDOH_BIAS (WCD937X_BASE_ADDRESS+0x068) +#define WCD937X_LDOH_STB_LOADS (WCD937X_BASE_ADDRESS+0x069) +#define WCD937X_LDOH_SLOWRAMP (WCD937X_BASE_ADDRESS+0x06A) +#define WCD937X_MICB1_TEST_CTL_1 (WCD937X_BASE_ADDRESS+0x06B) +#define WCD937X_MICB1_TEST_CTL_2 (WCD937X_BASE_ADDRESS+0x06C) +#define WCD937X_MICB1_TEST_CTL_3 (WCD937X_BASE_ADDRESS+0x06D) +#define WCD937X_MICB2_TEST_CTL_1 (WCD937X_BASE_ADDRESS+0x06E) +#define WCD937X_MICB2_TEST_CTL_2 (WCD937X_BASE_ADDRESS+0x06F) +#define WCD937X_MICB2_TEST_CTL_3 (WCD937X_BASE_ADDRESS+0x070) +#define WCD937X_MICB3_TEST_CTL_1 (WCD937X_BASE_ADDRESS+0x071) +#define WCD937X_MICB3_TEST_CTL_2 (WCD937X_BASE_ADDRESS+0x072) +#define WCD937X_MICB3_TEST_CTL_3 (WCD937X_BASE_ADDRESS+0x073) +#define WCD937X_TX_COM_ADC_VCM (WCD937X_BASE_ADDRESS+0x077) +#define WCD937X_TX_COM_BIAS_ATEST (WCD937X_BASE_ADDRESS+0x078) +#define WCD937X_TX_COM_ADC_INT1_IB (WCD937X_BASE_ADDRESS+0x079) +#define WCD937X_TX_COM_ADC_INT2_IB (WCD937X_BASE_ADDRESS+0x07A) +#define WCD937X_TX_COM_TXFE_DIV_CTL (WCD937X_BASE_ADDRESS+0x07B) +#define WCD937X_TX_COM_TXFE_DIV_START (WCD937X_BASE_ADDRESS+0x07C) +#define WCD937X_TX_COM_TXFE_DIV_STOP_9P6M (WCD937X_BASE_ADDRESS+0x07D) +#define WCD937X_TX_COM_TXFE_DIV_STOP_12P288M (WCD937X_BASE_ADDRESS+0x07E) +#define WCD937X_TX_1_2_TEST_EN (WCD937X_BASE_ADDRESS+0x07F) +#define WCD937X_TX_1_2_ADC_IB (WCD937X_BASE_ADDRESS+0x080) +#define WCD937X_TX_1_2_ATEST_REFCTL (WCD937X_BASE_ADDRESS+0x081) +#define WCD937X_TX_1_2_TEST_CTL (WCD937X_BASE_ADDRESS+0x082) +#define WCD937X_TX_1_2_TEST_BLK_EN (WCD937X_BASE_ADDRESS+0x083) +#define WCD937X_TX_1_2_TXFE_CLKDIV (WCD937X_BASE_ADDRESS+0x084) +#define WCD937X_TX_1_2_SAR2_ERR (WCD937X_BASE_ADDRESS+0x085) +#define WCD937X_TX_1_2_SAR1_ERR (WCD937X_BASE_ADDRESS+0x086) +#define WCD937X_TX_3_TEST_EN (WCD937X_BASE_ADDRESS+0x087) +#define WCD937X_TX_3_ADC_IB (WCD937X_BASE_ADDRESS+0x088) +#define WCD937X_TX_3_ATEST_REFCTL (WCD937X_BASE_ADDRESS+0x089) +#define WCD937X_TX_3_TEST_CTL (WCD937X_BASE_ADDRESS+0x08A) +#define WCD937X_TX_3_TEST_BLK_EN (WCD937X_BASE_ADDRESS+0x08B) +#define WCD937X_TX_3_TXFE_CLKDIV (WCD937X_BASE_ADDRESS+0x08C) +#define WCD937X_TX_3_SPARE_MONO (WCD937X_BASE_ADDRESS+0x08D) +#define WCD937X_TX_3_SAR1_ERR (WCD937X_BASE_ADDRESS+0x08E) +#define WCD937X_CLASSH_MODE_1 (WCD937X_BASE_ADDRESS+0x097) +#define WCD937X_CLASSH_MODE_2 (WCD937X_BASE_ADDRESS+0x098) +#define WCD937X_CLASSH_MODE_3 (WCD937X_BASE_ADDRESS+0x099) +#define WCD937X_CLASSH_CTRL_VCL_1 (WCD937X_BASE_ADDRESS+0x09A) +#define WCD937X_CLASSH_CTRL_VCL_2 (WCD937X_BASE_ADDRESS+0x09B) +#define WCD937X_CLASSH_CTRL_CCL_1 (WCD937X_BASE_ADDRESS+0x09C) +#define WCD937X_CLASSH_CTRL_CCL_2 (WCD937X_BASE_ADDRESS+0x09D) +#define WCD937X_CLASSH_CTRL_CCL_3 (WCD937X_BASE_ADDRESS+0x09E) +#define WCD937X_CLASSH_CTRL_CCL_4 (WCD937X_BASE_ADDRESS+0x09F) +#define WCD937X_CLASSH_CTRL_CCL_5 (WCD937X_BASE_ADDRESS+0x0A0) +#define WCD937X_CLASSH_BUCK_TMUX_A_D (WCD937X_BASE_ADDRESS+0x0A1) +#define WCD937X_CLASSH_BUCK_SW_DRV_CNTL (WCD937X_BASE_ADDRESS+0x0A2) +#define WCD937X_CLASSH_SPARE (WCD937X_BASE_ADDRESS+0x0A3) +#define WCD937X_FLYBACK_EN (WCD937X_BASE_ADDRESS+0x0A4) +#define WCD937X_FLYBACK_VNEG_CTRL_1 (WCD937X_BASE_ADDRESS+0x0A5) +#define WCD937X_FLYBACK_VNEG_CTRL_2 (WCD937X_BASE_ADDRESS+0x0A6) +#define WCD937X_FLYBACK_VNEG_CTRL_3 (WCD937X_BASE_ADDRESS+0x0A7) +#define WCD937X_FLYBACK_VNEG_CTRL_4 (WCD937X_BASE_ADDRESS+0x0A8) +#define WCD937X_FLYBACK_VNEG_CTRL_5 (WCD937X_BASE_ADDRESS+0x0A9) +#define WCD937X_FLYBACK_VNEG_CTRL_6 (WCD937X_BASE_ADDRESS+0x0AA) +#define WCD937X_FLYBACK_VNEG_CTRL_7 (WCD937X_BASE_ADDRESS+0x0AB) +#define WCD937X_FLYBACK_VNEG_CTRL_8 (WCD937X_BASE_ADDRESS+0x0AC) +#define WCD937X_FLYBACK_VNEG_CTRL_9 (WCD937X_BASE_ADDRESS+0x0AD) +#define WCD937X_FLYBACK_VNEGDAC_CTRL_1 (WCD937X_BASE_ADDRESS+0x0AE) +#define WCD937X_FLYBACK_VNEGDAC_CTRL_2 (WCD937X_BASE_ADDRESS+0x0AF) +#define WCD937X_FLYBACK_VNEGDAC_CTRL_3 (WCD937X_BASE_ADDRESS+0x0B0) +#define WCD937X_FLYBACK_CTRL_1 (WCD937X_BASE_ADDRESS+0x0B1) +#define WCD937X_FLYBACK_TEST_CTL (WCD937X_BASE_ADDRESS+0x0B2) +#define WCD937X_RX_AUX_SW_CTL (WCD937X_BASE_ADDRESS+0x0B3) +#define WCD937X_RX_PA_AUX_IN_CONN (WCD937X_BASE_ADDRESS+0x0B4) +#define WCD937X_RX_TIMER_DIV (WCD937X_BASE_ADDRESS+0x0B5) +#define WCD937X_RX_OCP_CTL (WCD937X_BASE_ADDRESS+0x0B6) +#define WCD937X_RX_OCP_COUNT (WCD937X_BASE_ADDRESS+0x0B7) +#define WCD937X_RX_BIAS_EAR_DAC (WCD937X_BASE_ADDRESS+0x0B8) +#define WCD937X_RX_BIAS_EAR_AMP (WCD937X_BASE_ADDRESS+0x0B9) +#define WCD937X_RX_BIAS_HPH_LDO (WCD937X_BASE_ADDRESS+0x0BA) +#define WCD937X_RX_BIAS_HPH_PA (WCD937X_BASE_ADDRESS+0x0BB) +#define WCD937X_RX_BIAS_HPH_RDACBUFF_CNP2 (WCD937X_BASE_ADDRESS+0x0BC) +#define WCD937X_RX_BIAS_HPH_RDAC_LDO (WCD937X_BASE_ADDRESS+0x0BD) +#define WCD937X_RX_BIAS_HPH_CNP1 (WCD937X_BASE_ADDRESS+0x0BE) +#define WCD937X_RX_BIAS_HPH_LOWPOWER (WCD937X_BASE_ADDRESS+0x0BF) +#define WCD937X_RX_BIAS_AUX_DAC (WCD937X_BASE_ADDRESS+0x0C0) +#define WCD937X_RX_BIAS_AUX_AMP (WCD937X_BASE_ADDRESS+0x0C1) +#define WCD937X_RX_BIAS_VNEGDAC_BLEEDER (WCD937X_BASE_ADDRESS+0x0C2) +#define WCD937X_RX_BIAS_MISC (WCD937X_BASE_ADDRESS+0x0C3) +#define WCD937X_RX_BIAS_BUCK_RST (WCD937X_BASE_ADDRESS+0x0C4) +#define WCD937X_RX_BIAS_BUCK_VREF_ERRAMP (WCD937X_BASE_ADDRESS+0x0C5) +#define WCD937X_RX_BIAS_FLYB_ERRAMP (WCD937X_BASE_ADDRESS+0x0C6) +#define WCD937X_RX_BIAS_FLYB_BUFF (WCD937X_BASE_ADDRESS+0x0C7) +#define WCD937X_RX_BIAS_FLYB_MID_RST (WCD937X_BASE_ADDRESS+0x0C8) +#define WCD937X_HPH_L_STATUS (WCD937X_BASE_ADDRESS+0x0C9) +#define WCD937X_HPH_R_STATUS (WCD937X_BASE_ADDRESS+0x0CA) +#define WCD937X_HPH_CNP_EN (WCD937X_BASE_ADDRESS+0x0CB) +#define WCD937X_HPH_CNP_WG_CTL (WCD937X_BASE_ADDRESS+0x0CC) +#define WCD937X_HPH_CNP_WG_TIME (WCD937X_BASE_ADDRESS+0x0CD) +#define WCD937X_HPH_OCP_CTL (WCD937X_BASE_ADDRESS+0x0CE) +#define WCD937X_HPH_AUTO_CHOP (WCD937X_BASE_ADDRESS+0x0CF) +#define WCD937X_HPH_CHOP_CTL (WCD937X_BASE_ADDRESS+0x0D0) +#define WCD937X_HPH_PA_CTL1 (WCD937X_BASE_ADDRESS+0x0D1) +#define WCD937X_HPH_PA_CTL2 (WCD937X_BASE_ADDRESS+0x0D2) +#define WCD937X_HPH_L_EN (WCD937X_BASE_ADDRESS+0x0D3) +#define WCD937X_HPH_L_TEST (WCD937X_BASE_ADDRESS+0x0D4) +#define WCD937X_HPH_L_ATEST (WCD937X_BASE_ADDRESS+0x0D5) +#define WCD937X_HPH_R_EN (WCD937X_BASE_ADDRESS+0x0D6) +#define WCD937X_HPH_R_TEST (WCD937X_BASE_ADDRESS+0x0D7) +#define WCD937X_HPH_R_ATEST (WCD937X_BASE_ADDRESS+0x0D8) +#define WCD937X_HPH_RDAC_CLK_CTL1 (WCD937X_BASE_ADDRESS+0x0D9) +#define WCD937X_HPH_RDAC_CLK_CTL2 (WCD937X_BASE_ADDRESS+0x0DA) +#define WCD937X_HPH_RDAC_LDO_CTL (WCD937X_BASE_ADDRESS+0x0DB) +#define WCD937X_HPH_RDAC_CHOP_CLK_LP_CTL (WCD937X_BASE_ADDRESS+0x0DC) +#define WCD937X_HPH_REFBUFF_UHQA_CTL (WCD937X_BASE_ADDRESS+0x0DD) +#define WCD937X_HPH_REFBUFF_LP_CTL (WCD937X_BASE_ADDRESS+0x0DE) +#define WCD937X_HPH_L_DAC_CTL (WCD937X_BASE_ADDRESS+0x0DF) +#define WCD937X_HPH_R_DAC_CTL (WCD937X_BASE_ADDRESS+0x0E0) +#define WCD937X_HPH_SURGE_HPHLR_SURGE_COMP_SEL (WCD937X_BASE_ADDRESS+0x0E1) +#define WCD937X_HPH_SURGE_HPHLR_SURGE_EN (WCD937X_BASE_ADDRESS+0x0E2) +#define WCD937X_HPH_SURGE_HPHLR_SURGE_MISC1 (WCD937X_BASE_ADDRESS+0x0E3) +#define WCD937X_HPH_SURGE_HPHLR_SURGE_STATUS (WCD937X_BASE_ADDRESS+0x0E4) +#define WCD937X_EAR_EAR_EN_REG (WCD937X_BASE_ADDRESS+0x0E9) +#define WCD937X_EAR_EAR_PA_CON (WCD937X_BASE_ADDRESS+0x0EA) +#define WCD937X_EAR_EAR_SP_CON (WCD937X_BASE_ADDRESS+0x0EB) +#define WCD937X_EAR_EAR_DAC_CON (WCD937X_BASE_ADDRESS+0x0EC) +#define WCD937X_EAR_EAR_CNP_FSM_CON (WCD937X_BASE_ADDRESS+0x0ED) +#define WCD937X_EAR_TEST_CTL (WCD937X_BASE_ADDRESS+0x0EE) +#define WCD937X_EAR_STATUS_REG_1 (WCD937X_BASE_ADDRESS+0x0EF) +#define WCD937X_EAR_STATUS_REG_2 (WCD937X_BASE_ADDRESS+0x0F0) +#define WCD937X_ANA_NEW_PAGE_REGISTER (WCD937X_BASE_ADDRESS+0x100) +#define WCD937X_HPH_NEW_ANA_HPH2 (WCD937X_BASE_ADDRESS+0x101) +#define WCD937X_HPH_NEW_ANA_HPH3 (WCD937X_BASE_ADDRESS+0x102) +#define WCD937X_SLEEP_CTL (WCD937X_BASE_ADDRESS+0x103) +#define WCD937X_SLEEP_WATCHDOG_CTL (WCD937X_BASE_ADDRESS+0x104) +#define WCD937X_MBHC_NEW_ELECT_REM_CLAMP_CTL (WCD937X_BASE_ADDRESS+0x11F) +#define WCD937X_MBHC_NEW_CTL_1 (WCD937X_BASE_ADDRESS+0x120) +#define WCD937X_MBHC_NEW_CTL_2 (WCD937X_BASE_ADDRESS+0x121) +#define WCD937X_MBHC_NEW_PLUG_DETECT_CTL (WCD937X_BASE_ADDRESS+0x122) +#define WCD937X_MBHC_NEW_ZDET_ANA_CTL (WCD937X_BASE_ADDRESS+0x123) +#define WCD937X_MBHC_NEW_ZDET_RAMP_CTL (WCD937X_BASE_ADDRESS+0x124) +#define WCD937X_MBHC_NEW_FSM_STATUS (WCD937X_BASE_ADDRESS+0x125) +#define WCD937X_MBHC_NEW_ADC_RESULT (WCD937X_BASE_ADDRESS+0x126) +#define WCD937X_TX_NEW_TX_CH2_SEL (WCD937X_BASE_ADDRESS+0x127) +#define WCD937X_AUX_AUXPA (WCD937X_BASE_ADDRESS+0x128) +#define WCD937X_LDORXTX_MODE (WCD937X_BASE_ADDRESS+0x129) +#define WCD937X_LDORXTX_CONFIG (WCD937X_BASE_ADDRESS+0x12A) +#define WCD937X_DIE_CRACK_DIE_CRK_DET_EN (WCD937X_BASE_ADDRESS+0x12C) +#define WCD937X_DIE_CRACK_DIE_CRK_DET_OUT (WCD937X_BASE_ADDRESS+0x12D) +#define WCD937X_HPH_NEW_INT_RDAC_GAIN_CTL (WCD937X_BASE_ADDRESS+0x132) +#define WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L (WCD937X_BASE_ADDRESS+0x133) +#define WCD937X_HPH_NEW_INT_RDAC_VREF_CTL (WCD937X_BASE_ADDRESS+0x134) +#define WCD937X_HPH_NEW_INT_RDAC_OVERRIDE_CTL (WCD937X_BASE_ADDRESS+0x135) +#define WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R (WCD937X_BASE_ADDRESS+0x136) +#define WCD937X_HPH_NEW_INT_PA_MISC1 (WCD937X_BASE_ADDRESS+0x137) +#define WCD937X_HPH_NEW_INT_PA_MISC2 (WCD937X_BASE_ADDRESS+0x138) +#define WCD937X_HPH_NEW_INT_PA_RDAC_MISC (WCD937X_BASE_ADDRESS+0x139) +#define WCD937X_HPH_NEW_INT_HPH_TIMER1 (WCD937X_BASE_ADDRESS+0x13A) +#define WCD937X_HPH_NEW_INT_HPH_TIMER2 (WCD937X_BASE_ADDRESS+0x13B) +#define WCD937X_HPH_NEW_INT_HPH_TIMER3 (WCD937X_BASE_ADDRESS+0x13C) +#define WCD937X_HPH_NEW_INT_HPH_TIMER4 (WCD937X_BASE_ADDRESS+0x13D) +#define WCD937X_HPH_NEW_INT_PA_RDAC_MISC2 (WCD937X_BASE_ADDRESS+0x13E) +#define WCD937X_HPH_NEW_INT_PA_RDAC_MISC3 (WCD937X_BASE_ADDRESS+0x13F) +#define WCD937X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI (WCD937X_BASE_ADDRESS+0x145) +#define WCD937X_RX_NEW_INT_HPH_RDAC_BIAS_ULP (WCD937X_BASE_ADDRESS+0x146) +#define WCD937X_RX_NEW_INT_HPH_RDAC_LDO_LP (WCD937X_BASE_ADDRESS+0x147) +#define WCD937X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL (WCD937X_BASE_ADDRESS+0x1AF) +#define WCD937X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL \ + (WCD937X_BASE_ADDRESS+0x1B0) +#define WCD937X_MBHC_NEW_INT_MECH_DET_CURRENT (WCD937X_BASE_ADDRESS+0x1B1) +#define WCD937X_MBHC_NEW_INT_SPARE_2 (WCD937X_BASE_ADDRESS+0x1B2) +#define WCD937X_EAR_INT_NEW_EAR_CHOPPER_CON (WCD937X_BASE_ADDRESS+0x1B7) +#define WCD937X_EAR_INT_NEW_CNP_VCM_CON1 (WCD937X_BASE_ADDRESS+0x1B8) +#define WCD937X_EAR_INT_NEW_CNP_VCM_CON2 (WCD937X_BASE_ADDRESS+0x1B9) +#define WCD937X_EAR_INT_NEW_EAR_DYNAMIC_BIAS (WCD937X_BASE_ADDRESS+0x1BA) +#define WCD937X_AUX_INT_EN_REG (WCD937X_BASE_ADDRESS+0x1BD) +#define WCD937X_AUX_INT_PA_CTRL (WCD937X_BASE_ADDRESS+0x1BE) +#define WCD937X_AUX_INT_SP_CTRL (WCD937X_BASE_ADDRESS+0x1BF) +#define WCD937X_AUX_INT_DAC_CTRL (WCD937X_BASE_ADDRESS+0x1C0) +#define WCD937X_AUX_INT_CLK_CTRL (WCD937X_BASE_ADDRESS+0x1C1) +#define WCD937X_AUX_INT_TEST_CTRL (WCD937X_BASE_ADDRESS+0x1C2) +#define WCD937X_AUX_INT_STATUS_REG (WCD937X_BASE_ADDRESS+0x1C3) +#define WCD937X_AUX_INT_MISC (WCD937X_BASE_ADDRESS+0x1C4) +#define WCD937X_LDORXTX_INT_BIAS (WCD937X_BASE_ADDRESS+0x1C5) +#define WCD937X_LDORXTX_INT_STB_LOADS_DTEST (WCD937X_BASE_ADDRESS+0x1C6) +#define WCD937X_LDORXTX_INT_TEST0 (WCD937X_BASE_ADDRESS+0x1C7) +#define WCD937X_LDORXTX_INT_STARTUP_TIMER (WCD937X_BASE_ADDRESS+0x1C8) +#define WCD937X_LDORXTX_INT_TEST1 (WCD937X_BASE_ADDRESS+0x1C9) +#define WCD937X_LDORXTX_INT_STATUS (WCD937X_BASE_ADDRESS+0x1CA) +#define WCD937X_SLEEP_INT_WATCHDOG_CTL_1 (WCD937X_BASE_ADDRESS+0x1D0) +#define WCD937X_SLEEP_INT_WATCHDOG_CTL_2 (WCD937X_BASE_ADDRESS+0x1D1) +#define WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT1 (WCD937X_BASE_ADDRESS+0x1D3) +#define WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT2 (WCD937X_BASE_ADDRESS+0x1D4) +#define WCD937X_DIGITAL_PAGE_REGISTER (WCD937X_BASE_ADDRESS+0x400) +#define WCD937X_DIGITAL_CHIP_ID0 (WCD937X_BASE_ADDRESS+0x401) +#define WCD937X_DIGITAL_CHIP_ID1 (WCD937X_BASE_ADDRESS+0x402) +#define WCD937X_DIGITAL_CHIP_ID2 (WCD937X_BASE_ADDRESS+0x403) +#define WCD937X_DIGITAL_CHIP_ID3 (WCD937X_BASE_ADDRESS+0x404) +#define WCD937X_DIGITAL_CDC_RST_CTL (WCD937X_BASE_ADDRESS+0x406) +#define WCD937X_DIGITAL_TOP_CLK_CFG (WCD937X_BASE_ADDRESS+0x407) +#define WCD937X_DIGITAL_CDC_ANA_CLK_CTL (WCD937X_BASE_ADDRESS+0x408) +#define WCD937X_DIGITAL_CDC_DIG_CLK_CTL (WCD937X_BASE_ADDRESS+0x409) +#define WCD937X_DIGITAL_SWR_RST_EN (WCD937X_BASE_ADDRESS+0x40A) +#define WCD937X_DIGITAL_CDC_PATH_MODE (WCD937X_BASE_ADDRESS+0x40B) +#define WCD937X_DIGITAL_CDC_RX_RST (WCD937X_BASE_ADDRESS+0x40C) +#define WCD937X_DIGITAL_CDC_RX0_CTL (WCD937X_BASE_ADDRESS+0x40D) +#define WCD937X_DIGITAL_CDC_RX1_CTL (WCD937X_BASE_ADDRESS+0x40E) +#define WCD937X_DIGITAL_CDC_RX2_CTL (WCD937X_BASE_ADDRESS+0x40F) +#define WCD937X_DIGITAL_DEM_BYPASS_DATA0 (WCD937X_BASE_ADDRESS+0x410) +#define WCD937X_DIGITAL_DEM_BYPASS_DATA1 (WCD937X_BASE_ADDRESS+0x411) +#define WCD937X_DIGITAL_DEM_BYPASS_DATA2 (WCD937X_BASE_ADDRESS+0x412) +#define WCD937X_DIGITAL_DEM_BYPASS_DATA3 (WCD937X_BASE_ADDRESS+0x413) +#define WCD937X_DIGITAL_CDC_COMP_CTL_0 (WCD937X_BASE_ADDRESS+0x414) +#define WCD937X_DIGITAL_CDC_RX_DELAY_CTL (WCD937X_BASE_ADDRESS+0x417) +#define WCD937X_DIGITAL_CDC_HPH_DSM_A1_0 (WCD937X_BASE_ADDRESS+0x418) +#define WCD937X_DIGITAL_CDC_HPH_DSM_A1_1 (WCD937X_BASE_ADDRESS+0x419) +#define WCD937X_DIGITAL_CDC_HPH_DSM_A2_0 (WCD937X_BASE_ADDRESS+0x41A) +#define WCD937X_DIGITAL_CDC_HPH_DSM_A2_1 (WCD937X_BASE_ADDRESS+0x41B) +#define WCD937X_DIGITAL_CDC_HPH_DSM_A3_0 (WCD937X_BASE_ADDRESS+0x41C) +#define WCD937X_DIGITAL_CDC_HPH_DSM_A3_1 (WCD937X_BASE_ADDRESS+0x41D) +#define WCD937X_DIGITAL_CDC_HPH_DSM_A4_0 (WCD937X_BASE_ADDRESS+0x41E) +#define WCD937X_DIGITAL_CDC_HPH_DSM_A4_1 (WCD937X_BASE_ADDRESS+0x41F) +#define WCD937X_DIGITAL_CDC_HPH_DSM_A5_0 (WCD937X_BASE_ADDRESS+0x420) +#define WCD937X_DIGITAL_CDC_HPH_DSM_A5_1 (WCD937X_BASE_ADDRESS+0x421) +#define WCD937X_DIGITAL_CDC_HPH_DSM_A6_0 (WCD937X_BASE_ADDRESS+0x422) +#define WCD937X_DIGITAL_CDC_HPH_DSM_A7_0 (WCD937X_BASE_ADDRESS+0x423) +#define WCD937X_DIGITAL_CDC_HPH_DSM_C_0 (WCD937X_BASE_ADDRESS+0x424) +#define WCD937X_DIGITAL_CDC_HPH_DSM_C_1 (WCD937X_BASE_ADDRESS+0x425) +#define WCD937X_DIGITAL_CDC_HPH_DSM_C_2 (WCD937X_BASE_ADDRESS+0x426) +#define WCD937X_DIGITAL_CDC_HPH_DSM_C_3 (WCD937X_BASE_ADDRESS+0x427) +#define WCD937X_DIGITAL_CDC_HPH_DSM_R1 (WCD937X_BASE_ADDRESS+0x428) +#define WCD937X_DIGITAL_CDC_HPH_DSM_R2 (WCD937X_BASE_ADDRESS+0x429) +#define WCD937X_DIGITAL_CDC_HPH_DSM_R3 (WCD937X_BASE_ADDRESS+0x42A) +#define WCD937X_DIGITAL_CDC_HPH_DSM_R4 (WCD937X_BASE_ADDRESS+0x42B) +#define WCD937X_DIGITAL_CDC_HPH_DSM_R5 (WCD937X_BASE_ADDRESS+0x42C) +#define WCD937X_DIGITAL_CDC_HPH_DSM_R6 (WCD937X_BASE_ADDRESS+0x42D) +#define WCD937X_DIGITAL_CDC_HPH_DSM_R7 (WCD937X_BASE_ADDRESS+0x42E) +#define WCD937X_DIGITAL_CDC_AUX_DSM_A1_0 (WCD937X_BASE_ADDRESS+0x42F) +#define WCD937X_DIGITAL_CDC_AUX_DSM_A1_1 (WCD937X_BASE_ADDRESS+0x430) +#define WCD937X_DIGITAL_CDC_AUX_DSM_A2_0 (WCD937X_BASE_ADDRESS+0x431) +#define WCD937X_DIGITAL_CDC_AUX_DSM_A2_1 (WCD937X_BASE_ADDRESS+0x432) +#define WCD937X_DIGITAL_CDC_AUX_DSM_A3_0 (WCD937X_BASE_ADDRESS+0x433) +#define WCD937X_DIGITAL_CDC_AUX_DSM_A3_1 (WCD937X_BASE_ADDRESS+0x434) +#define WCD937X_DIGITAL_CDC_AUX_DSM_A4_0 (WCD937X_BASE_ADDRESS+0x435) +#define WCD937X_DIGITAL_CDC_AUX_DSM_A4_1 (WCD937X_BASE_ADDRESS+0x436) +#define WCD937X_DIGITAL_CDC_AUX_DSM_A5_0 (WCD937X_BASE_ADDRESS+0x437) +#define WCD937X_DIGITAL_CDC_AUX_DSM_A5_1 (WCD937X_BASE_ADDRESS+0x438) +#define WCD937X_DIGITAL_CDC_AUX_DSM_A6_0 (WCD937X_BASE_ADDRESS+0x439) +#define WCD937X_DIGITAL_CDC_AUX_DSM_A7_0 (WCD937X_BASE_ADDRESS+0x43A) +#define WCD937X_DIGITAL_CDC_AUX_DSM_C_0 (WCD937X_BASE_ADDRESS+0x43B) +#define WCD937X_DIGITAL_CDC_AUX_DSM_C_1 (WCD937X_BASE_ADDRESS+0x43C) +#define WCD937X_DIGITAL_CDC_AUX_DSM_C_2 (WCD937X_BASE_ADDRESS+0x43D) +#define WCD937X_DIGITAL_CDC_AUX_DSM_C_3 (WCD937X_BASE_ADDRESS+0x43E) +#define WCD937X_DIGITAL_CDC_AUX_DSM_R1 (WCD937X_BASE_ADDRESS+0x43F) +#define WCD937X_DIGITAL_CDC_AUX_DSM_R2 (WCD937X_BASE_ADDRESS+0x440) +#define WCD937X_DIGITAL_CDC_AUX_DSM_R3 (WCD937X_BASE_ADDRESS+0x441) +#define WCD937X_DIGITAL_CDC_AUX_DSM_R4 (WCD937X_BASE_ADDRESS+0x442) +#define WCD937X_DIGITAL_CDC_AUX_DSM_R5 (WCD937X_BASE_ADDRESS+0x443) +#define WCD937X_DIGITAL_CDC_AUX_DSM_R6 (WCD937X_BASE_ADDRESS+0x444) +#define WCD937X_DIGITAL_CDC_AUX_DSM_R7 (WCD937X_BASE_ADDRESS+0x445) +#define WCD937X_DIGITAL_CDC_HPH_GAIN_RX_0 (WCD937X_BASE_ADDRESS+0x446) +#define WCD937X_DIGITAL_CDC_HPH_GAIN_RX_1 (WCD937X_BASE_ADDRESS+0x447) +#define WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_0 (WCD937X_BASE_ADDRESS+0x448) +#define WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_1 (WCD937X_BASE_ADDRESS+0x449) +#define WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_2 (WCD937X_BASE_ADDRESS+0x44A) +#define WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_0 (WCD937X_BASE_ADDRESS+0x44B) +#define WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_1 (WCD937X_BASE_ADDRESS+0x44C) +#define WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_2 (WCD937X_BASE_ADDRESS+0x44D) +#define WCD937X_DIGITAL_CDC_HPH_GAIN_CTL (WCD937X_BASE_ADDRESS+0x44E) +#define WCD937X_DIGITAL_CDC_AUX_GAIN_CTL (WCD937X_BASE_ADDRESS+0x44F) +#define WCD937X_DIGITAL_CDC_EAR_PATH_CTL (WCD937X_BASE_ADDRESS+0x450) +#define WCD937X_DIGITAL_CDC_SWR_CLH (WCD937X_BASE_ADDRESS+0x451) +#define WCD937X_DIGITAL_SWR_CLH_BYP (WCD937X_BASE_ADDRESS+0x452) +#define WCD937X_DIGITAL_CDC_TX0_CTL (WCD937X_BASE_ADDRESS+0x453) +#define WCD937X_DIGITAL_CDC_TX1_CTL (WCD937X_BASE_ADDRESS+0x454) +#define WCD937X_DIGITAL_CDC_TX2_CTL (WCD937X_BASE_ADDRESS+0x455) +#define WCD937X_DIGITAL_CDC_TX_RST (WCD937X_BASE_ADDRESS+0x456) +#define WCD937X_DIGITAL_CDC_REQ_CTL (WCD937X_BASE_ADDRESS+0x457) +#define WCD937X_DIGITAL_CDC_AMIC_CTL (WCD937X_BASE_ADDRESS+0x45A) +#define WCD937X_DIGITAL_CDC_DMIC_CTL (WCD937X_BASE_ADDRESS+0x45B) +#define WCD937X_DIGITAL_CDC_DMIC0_CTL (WCD937X_BASE_ADDRESS+0x45C) +#define WCD937X_DIGITAL_CDC_DMIC1_CTL (WCD937X_BASE_ADDRESS+0x45D) +#define WCD937X_DIGITAL_CDC_DMIC2_CTL (WCD937X_BASE_ADDRESS+0x45E) +#define WCD937X_DIGITAL_EFUSE_CTL (WCD937X_BASE_ADDRESS+0x45F) +#define WCD937X_DIGITAL_EFUSE_PRG_CTL (WCD937X_BASE_ADDRESS+0x460) +#define WCD937X_DIGITAL_EFUSE_TEST_CTL_0 (WCD937X_BASE_ADDRESS+0x461) +#define WCD937X_DIGITAL_EFUSE_TEST_CTL_1 (WCD937X_BASE_ADDRESS+0x462) +#define WCD937X_DIGITAL_EFUSE_T_DATA_0 (WCD937X_BASE_ADDRESS+0x463) +#define WCD937X_DIGITAL_EFUSE_T_DATA_1 (WCD937X_BASE_ADDRESS+0x464) +#define WCD937X_DIGITAL_PDM_WD_CTL0 (WCD937X_BASE_ADDRESS+0x465) +#define WCD937X_DIGITAL_PDM_WD_CTL1 (WCD937X_BASE_ADDRESS+0x466) +#define WCD937X_DIGITAL_PDM_WD_CTL2 (WCD937X_BASE_ADDRESS+0x467) +#define WCD937X_DIGITAL_INTR_MODE (WCD937X_BASE_ADDRESS+0x46A) +#define WCD937X_DIGITAL_INTR_MASK_0 (WCD937X_BASE_ADDRESS+0x46B) +#define WCD937X_DIGITAL_INTR_MASK_1 (WCD937X_BASE_ADDRESS+0x46C) +#define WCD937X_DIGITAL_INTR_MASK_2 (WCD937X_BASE_ADDRESS+0x46D) +#define WCD937X_DIGITAL_INTR_STATUS_0 (WCD937X_BASE_ADDRESS+0x46E) +#define WCD937X_DIGITAL_INTR_STATUS_1 (WCD937X_BASE_ADDRESS+0x46F) +#define WCD937X_DIGITAL_INTR_STATUS_2 (WCD937X_BASE_ADDRESS+0x470) +#define WCD937X_DIGITAL_INTR_CLEAR_0 (WCD937X_BASE_ADDRESS+0x471) +#define WCD937X_DIGITAL_INTR_CLEAR_1 (WCD937X_BASE_ADDRESS+0x472) +#define WCD937X_DIGITAL_INTR_CLEAR_2 (WCD937X_BASE_ADDRESS+0x473) +#define WCD937X_DIGITAL_INTR_LEVEL_0 (WCD937X_BASE_ADDRESS+0x474) +#define WCD937X_DIGITAL_INTR_LEVEL_1 (WCD937X_BASE_ADDRESS+0x475) +#define WCD937X_DIGITAL_INTR_LEVEL_2 (WCD937X_BASE_ADDRESS+0x476) +#define WCD937X_DIGITAL_INTR_SET_0 (WCD937X_BASE_ADDRESS+0x477) +#define WCD937X_DIGITAL_INTR_SET_1 (WCD937X_BASE_ADDRESS+0x478) +#define WCD937X_DIGITAL_INTR_SET_2 (WCD937X_BASE_ADDRESS+0x479) +#define WCD937X_DIGITAL_INTR_TEST_0 (WCD937X_BASE_ADDRESS+0x47A) +#define WCD937X_DIGITAL_INTR_TEST_1 (WCD937X_BASE_ADDRESS+0x47B) +#define WCD937X_DIGITAL_INTR_TEST_2 (WCD937X_BASE_ADDRESS+0x47C) +#define WCD937X_DIGITAL_CDC_CONN_RX0_CTL (WCD937X_BASE_ADDRESS+0x47F) +#define WCD937X_DIGITAL_CDC_CONN_RX1_CTL (WCD937X_BASE_ADDRESS+0x480) +#define WCD937X_DIGITAL_CDC_CONN_RX2_CTL (WCD937X_BASE_ADDRESS+0x481) +#define WCD937X_DIGITAL_CDC_CONN_TX_CTL (WCD937X_BASE_ADDRESS+0x482) +#define WCD937X_DIGITAL_LOOP_BACK_MODE (WCD937X_BASE_ADDRESS+0x483) +#define WCD937X_DIGITAL_SWR_DAC_TEST (WCD937X_BASE_ADDRESS+0x484) +#define WCD937X_DIGITAL_SWR_HM_TEST_RX_0 (WCD937X_BASE_ADDRESS+0x485) +#define WCD937X_DIGITAL_SWR_HM_TEST_TX_0 (WCD937X_BASE_ADDRESS+0x491) +#define WCD937X_DIGITAL_SWR_HM_TEST_RX_1 (WCD937X_BASE_ADDRESS+0x492) +#define WCD937X_DIGITAL_SWR_HM_TEST_TX_1 (WCD937X_BASE_ADDRESS+0x493) +#define WCD937X_DIGITAL_SWR_HM_TEST (WCD937X_BASE_ADDRESS+0x494) +#define WCD937X_DIGITAL_PAD_CTL_PDM_RX0 (WCD937X_BASE_ADDRESS+0x495) +#define WCD937X_DIGITAL_PAD_CTL_PDM_RX1 (WCD937X_BASE_ADDRESS+0x496) +#define WCD937X_DIGITAL_PAD_CTL_PDM_RX2 (WCD937X_BASE_ADDRESS+0x497) +#define WCD937X_DIGITAL_PAD_CTL_PDM_TX (WCD937X_BASE_ADDRESS+0x498) +#define WCD937X_DIGITAL_PAD_INP_DIS_0 (WCD937X_BASE_ADDRESS+0x499) +#define WCD937X_DIGITAL_PAD_INP_DIS_1 (WCD937X_BASE_ADDRESS+0x49A) +#define WCD937X_DIGITAL_DRIVE_STRENGTH_0 (WCD937X_BASE_ADDRESS+0x49B) +#define WCD937X_DIGITAL_DRIVE_STRENGTH_1 (WCD937X_BASE_ADDRESS+0x49C) +#define WCD937X_DIGITAL_DRIVE_STRENGTH_2 (WCD937X_BASE_ADDRESS+0x49D) +#define WCD937X_DIGITAL_RX_DATA_EDGE_CTL (WCD937X_BASE_ADDRESS+0x49E) +#define WCD937X_DIGITAL_TX_DATA_EDGE_CTL (WCD937X_BASE_ADDRESS+0x49F) +#define WCD937X_DIGITAL_GPIO_MODE (WCD937X_BASE_ADDRESS+0x4A0) +#define WCD937X_DIGITAL_PIN_CTL_OE (WCD937X_BASE_ADDRESS+0x4A1) +#define WCD937X_DIGITAL_PIN_CTL_DATA_0 (WCD937X_BASE_ADDRESS+0x4A2) +#define WCD937X_DIGITAL_PIN_CTL_DATA_1 (WCD937X_BASE_ADDRESS+0x4A3) +#define WCD937X_DIGITAL_PIN_STATUS_0 (WCD937X_BASE_ADDRESS+0x4A4) +#define WCD937X_DIGITAL_PIN_STATUS_1 (WCD937X_BASE_ADDRESS+0x4A5) +#define WCD937X_DIGITAL_DIG_DEBUG_CTL (WCD937X_BASE_ADDRESS+0x4A6) +#define WCD937X_DIGITAL_DIG_DEBUG_EN (WCD937X_BASE_ADDRESS+0x4A7) +#define WCD937X_DIGITAL_ANA_CSR_DBG_ADD (WCD937X_BASE_ADDRESS+0x4A8) +#define WCD937X_DIGITAL_ANA_CSR_DBG_CTL (WCD937X_BASE_ADDRESS+0x4A9) +#define WCD937X_DIGITAL_SSP_DBG (WCD937X_BASE_ADDRESS+0x4AA) +#define WCD937X_DIGITAL_MODE_STATUS_0 (WCD937X_BASE_ADDRESS+0x4AB) +#define WCD937X_DIGITAL_MODE_STATUS_1 (WCD937X_BASE_ADDRESS+0x4AC) +#define WCD937X_DIGITAL_SPARE_0 (WCD937X_BASE_ADDRESS+0x4AD) +#define WCD937X_DIGITAL_SPARE_1 (WCD937X_BASE_ADDRESS+0x4AE) +#define WCD937X_DIGITAL_SPARE_2 (WCD937X_BASE_ADDRESS+0x4AF) +#define WCD937X_DIGITAL_EFUSE_REG_0 (WCD937X_BASE_ADDRESS+0x4B0) +#define WCD937X_DIGITAL_EFUSE_REG_1 (WCD937X_BASE_ADDRESS+0x4B1) +#define WCD937X_DIGITAL_EFUSE_REG_2 (WCD937X_BASE_ADDRESS+0x4B2) +#define WCD937X_DIGITAL_EFUSE_REG_3 (WCD937X_BASE_ADDRESS+0x4B3) +#define WCD937X_DIGITAL_EFUSE_REG_4 (WCD937X_BASE_ADDRESS+0x4B4) +#define WCD937X_DIGITAL_EFUSE_REG_5 (WCD937X_BASE_ADDRESS+0x4B5) +#define WCD937X_DIGITAL_EFUSE_REG_6 (WCD937X_BASE_ADDRESS+0x4B6) +#define WCD937X_DIGITAL_EFUSE_REG_7 (WCD937X_BASE_ADDRESS+0x4B7) +#define WCD937X_DIGITAL_EFUSE_REG_8 (WCD937X_BASE_ADDRESS+0x4B8) +#define WCD937X_DIGITAL_EFUSE_REG_9 (WCD937X_BASE_ADDRESS+0x4B9) +#define WCD937X_DIGITAL_EFUSE_REG_10 (WCD937X_BASE_ADDRESS+0x4BA) +#define WCD937X_DIGITAL_EFUSE_REG_11 (WCD937X_BASE_ADDRESS+0x4BB) +#define WCD937X_DIGITAL_EFUSE_REG_12 (WCD937X_BASE_ADDRESS+0x4BC) +#define WCD937X_DIGITAL_EFUSE_REG_13 (WCD937X_BASE_ADDRESS+0x4BD) +#define WCD937X_DIGITAL_EFUSE_REG_14 (WCD937X_BASE_ADDRESS+0x4BE) +#define WCD937X_DIGITAL_EFUSE_REG_15 (WCD937X_BASE_ADDRESS+0x4BF) +#define WCD937X_DIGITAL_EFUSE_REG_16 (WCD937X_BASE_ADDRESS+0x4C0) +#define WCD937X_DIGITAL_EFUSE_REG_17 (WCD937X_BASE_ADDRESS+0x4C1) +#define WCD937X_DIGITAL_EFUSE_REG_18 (WCD937X_BASE_ADDRESS+0x4C2) +#define WCD937X_DIGITAL_EFUSE_REG_19 (WCD937X_BASE_ADDRESS+0x4C3) +#define WCD937X_DIGITAL_EFUSE_REG_20 (WCD937X_BASE_ADDRESS+0x4C4) +#define WCD937X_DIGITAL_EFUSE_REG_21 (WCD937X_BASE_ADDRESS+0x4C5) +#define WCD937X_DIGITAL_EFUSE_REG_22 (WCD937X_BASE_ADDRESS+0x4C6) +#define WCD937X_DIGITAL_EFUSE_REG_23 (WCD937X_BASE_ADDRESS+0x4C7) +#define WCD937X_DIGITAL_EFUSE_REG_24 (WCD937X_BASE_ADDRESS+0x4C8) +#define WCD937X_DIGITAL_EFUSE_REG_25 (WCD937X_BASE_ADDRESS+0x4C9) +#define WCD937X_DIGITAL_EFUSE_REG_26 (WCD937X_BASE_ADDRESS+0x4CA) +#define WCD937X_DIGITAL_EFUSE_REG_27 (WCD937X_BASE_ADDRESS+0x4CB) +#define WCD937X_DIGITAL_EFUSE_REG_28 (WCD937X_BASE_ADDRESS+0x4CC) +#define WCD937X_DIGITAL_EFUSE_REG_29 (WCD937X_BASE_ADDRESS+0x4CD) +#define WCD937X_DIGITAL_EFUSE_REG_30 (WCD937X_BASE_ADDRESS+0x4CE) +#define WCD937X_DIGITAL_EFUSE_REG_31 (WCD937X_BASE_ADDRESS+0x4CF) + +#define WCD937X_REGISTERS_MAX_SIZE (WCD937X_BASE_ADDRESS+0x4D0) +#define WCD937X_MAX_REGISTER (WCD937X_REGISTERS_MAX_SIZE - 1) + +#endif diff --git a/asoc/codecs/wcd937x/wcd937x-regmap.c b/asoc/codecs/wcd937x/wcd937x-regmap.c new file mode 100644 index 000000000000..cccf8dbdbf59 --- /dev/null +++ b/asoc/codecs/wcd937x/wcd937x-regmap.c @@ -0,0 +1,462 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "wcd937x-registers.h" + +extern const u8 wcd937x_reg_access[WCD937X_REGISTERS_MAX_SIZE]; + +static const struct reg_default wcd937x_defaults[] = { + { WCD937X_ANA_BIAS, 0x00 }, + { WCD937X_ANA_RX_SUPPLIES, 0x00 }, + { WCD937X_ANA_HPH, 0x0C }, + { WCD937X_ANA_EAR, 0x00 }, + { WCD937X_ANA_EAR_COMPANDER_CTL, 0x02 }, + { WCD937X_ANA_TX_CH1, 0x20 }, + { WCD937X_ANA_TX_CH2, 0x00 }, + { WCD937X_ANA_TX_CH3, 0x20 }, + { WCD937X_ANA_TX_CH3_HPF, 0x00 }, + { WCD937X_ANA_MICB1_MICB2_DSP_EN_LOGIC, 0x00 }, + { WCD937X_ANA_MICB3_DSP_EN_LOGIC, 0x00 }, + { WCD937X_ANA_MBHC_MECH, 0x39 }, + { WCD937X_ANA_MBHC_ELECT, 0x08 }, + { WCD937X_ANA_MBHC_ZDET, 0x00 }, + { WCD937X_ANA_MBHC_RESULT_1, 0x00 }, + { WCD937X_ANA_MBHC_RESULT_2, 0x00 }, + { WCD937X_ANA_MBHC_RESULT_3, 0x00 }, + { WCD937X_ANA_MBHC_BTN0, 0x00 }, + { WCD937X_ANA_MBHC_BTN1, 0x10 }, + { WCD937X_ANA_MBHC_BTN2, 0x20 }, + { WCD937X_ANA_MBHC_BTN3, 0x30 }, + { WCD937X_ANA_MBHC_BTN4, 0x40 }, + { WCD937X_ANA_MBHC_BTN5, 0x50 }, + { WCD937X_ANA_MBHC_BTN6, 0x60 }, + { WCD937X_ANA_MBHC_BTN7, 0x70 }, + { WCD937X_ANA_MICB1, 0x10 }, + { WCD937X_ANA_MICB2, 0x10 }, + { WCD937X_ANA_MICB2_RAMP, 0x00 }, + { WCD937X_ANA_MICB3, 0x10 }, + { WCD937X_BIAS_CTL, 0x2A }, + { WCD937X_BIAS_VBG_FINE_ADJ, 0x55 }, + { WCD937X_LDOL_VDDCX_ADJUST, 0x01 }, + { WCD937X_LDOL_DISABLE_LDOL, 0x00 }, + { WCD937X_MBHC_CTL_CLK, 0x00 }, + { WCD937X_MBHC_CTL_ANA, 0x00 }, + { WCD937X_MBHC_CTL_SPARE_1, 0x00 }, + { WCD937X_MBHC_CTL_SPARE_2, 0x00 }, + { WCD937X_MBHC_CTL_BCS, 0x00 }, + { WCD937X_MBHC_MOISTURE_DET_FSM_STATUS, 0x00 }, + { WCD937X_MBHC_TEST_CTL, 0x00 }, + { WCD937X_LDOH_MODE, 0x2B }, + { WCD937X_LDOH_BIAS, 0x68 }, + { WCD937X_LDOH_STB_LOADS, 0x00 }, + { WCD937X_LDOH_SLOWRAMP, 0x50 }, + { WCD937X_MICB1_TEST_CTL_1, 0x1A }, + { WCD937X_MICB1_TEST_CTL_2, 0x18 }, + { WCD937X_MICB1_TEST_CTL_3, 0xA4 }, + { WCD937X_MICB2_TEST_CTL_1, 0x1A }, + { WCD937X_MICB2_TEST_CTL_2, 0x18 }, + { WCD937X_MICB2_TEST_CTL_3, 0xA4 }, + { WCD937X_MICB3_TEST_CTL_1, 0x1A }, + { WCD937X_MICB3_TEST_CTL_2, 0x18 }, + { WCD937X_MICB3_TEST_CTL_3, 0xA4 }, + { WCD937X_TX_COM_ADC_VCM, 0x39 }, + { WCD937X_TX_COM_BIAS_ATEST, 0xC0 }, + { WCD937X_TX_COM_ADC_INT1_IB, 0x6F }, + { WCD937X_TX_COM_ADC_INT2_IB, 0x4F }, + { WCD937X_TX_COM_TXFE_DIV_CTL, 0x2E }, + { WCD937X_TX_COM_TXFE_DIV_START, 0x00 }, + { WCD937X_TX_COM_TXFE_DIV_STOP_9P6M, 0xC7 }, + { WCD937X_TX_COM_TXFE_DIV_STOP_12P288M, 0xFF }, + { WCD937X_TX_1_2_TEST_EN, 0xCC }, + { WCD937X_TX_1_2_ADC_IB, 0x09 }, + { WCD937X_TX_1_2_ATEST_REFCTL, 0x0A }, + { WCD937X_TX_1_2_TEST_CTL, 0x38 }, + { WCD937X_TX_1_2_TEST_BLK_EN, 0xFF }, + { WCD937X_TX_1_2_TXFE_CLKDIV, 0x00 }, + { WCD937X_TX_1_2_SAR2_ERR, 0x00 }, + { WCD937X_TX_1_2_SAR1_ERR, 0x00 }, + { WCD937X_TX_3_TEST_EN, 0xCC }, + { WCD937X_TX_3_ADC_IB, 0x09 }, + { WCD937X_TX_3_ATEST_REFCTL, 0x0A }, + { WCD937X_TX_3_TEST_CTL, 0x38 }, + { WCD937X_TX_3_TEST_BLK_EN, 0xFF }, + { WCD937X_TX_3_TXFE_CLKDIV, 0x00 }, + { WCD937X_TX_3_SPARE_MONO, 0x00 }, + { WCD937X_TX_3_SAR1_ERR, 0x00 }, + { WCD937X_CLASSH_MODE_1, 0x40 }, + { WCD937X_CLASSH_MODE_2, 0x3A }, + { WCD937X_CLASSH_MODE_3, 0x00 }, + { WCD937X_CLASSH_CTRL_VCL_1, 0x70 }, + { WCD937X_CLASSH_CTRL_VCL_2, 0x82 }, + { WCD937X_CLASSH_CTRL_CCL_1, 0x31 }, + { WCD937X_CLASSH_CTRL_CCL_2, 0x80 }, + { WCD937X_CLASSH_CTRL_CCL_3, 0x80 }, + { WCD937X_CLASSH_CTRL_CCL_4, 0x51 }, + { WCD937X_CLASSH_CTRL_CCL_5, 0x00 }, + { WCD937X_CLASSH_BUCK_TMUX_A_D, 0x00 }, + { WCD937X_CLASSH_BUCK_SW_DRV_CNTL, 0x77 }, + { WCD937X_CLASSH_SPARE, 0x00 }, + { WCD937X_FLYBACK_EN, 0x4E }, + { WCD937X_FLYBACK_VNEG_CTRL_1, 0x0B }, + { WCD937X_FLYBACK_VNEG_CTRL_2, 0x45 }, + { WCD937X_FLYBACK_VNEG_CTRL_3, 0x74 }, + { WCD937X_FLYBACK_VNEG_CTRL_4, 0x7F }, + { WCD937X_FLYBACK_VNEG_CTRL_5, 0x83 }, + { WCD937X_FLYBACK_VNEG_CTRL_6, 0x98 }, + { WCD937X_FLYBACK_VNEG_CTRL_7, 0xA9 }, + { WCD937X_FLYBACK_VNEG_CTRL_8, 0x68 }, + { WCD937X_FLYBACK_VNEG_CTRL_9, 0x64 }, + { WCD937X_FLYBACK_VNEGDAC_CTRL_1, 0xED }, + { WCD937X_FLYBACK_VNEGDAC_CTRL_2, 0xF0 }, + { WCD937X_FLYBACK_VNEGDAC_CTRL_3, 0xA6 }, + { WCD937X_FLYBACK_CTRL_1, 0x65 }, + { WCD937X_FLYBACK_TEST_CTL, 0x00 }, + { WCD937X_RX_AUX_SW_CTL, 0x00 }, + { WCD937X_RX_PA_AUX_IN_CONN, 0x00 }, + { WCD937X_RX_TIMER_DIV, 0x32 }, + { WCD937X_RX_OCP_CTL, 0x1F }, + { WCD937X_RX_OCP_COUNT, 0x77 }, + { WCD937X_RX_BIAS_EAR_DAC, 0xA0 }, + { WCD937X_RX_BIAS_EAR_AMP, 0xAA }, + { WCD937X_RX_BIAS_HPH_LDO, 0xA9 }, + { WCD937X_RX_BIAS_HPH_PA, 0xAA }, + { WCD937X_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8A }, + { WCD937X_RX_BIAS_HPH_RDAC_LDO, 0x88 }, + { WCD937X_RX_BIAS_HPH_CNP1, 0x82 }, + { WCD937X_RX_BIAS_HPH_LOWPOWER, 0x82 }, + { WCD937X_RX_BIAS_AUX_DAC, 0xA0 }, + { WCD937X_RX_BIAS_AUX_AMP, 0xAA }, + { WCD937X_RX_BIAS_VNEGDAC_BLEEDER, 0x50 }, + { WCD937X_RX_BIAS_MISC, 0x00 }, + { WCD937X_RX_BIAS_BUCK_RST, 0x08 }, + { WCD937X_RX_BIAS_BUCK_VREF_ERRAMP, 0x44 }, + { WCD937X_RX_BIAS_FLYB_ERRAMP, 0x40 }, + { WCD937X_RX_BIAS_FLYB_BUFF, 0xAA }, + { WCD937X_RX_BIAS_FLYB_MID_RST, 0x14 }, + { WCD937X_HPH_L_STATUS, 0x04 }, + { WCD937X_HPH_R_STATUS, 0x04 }, + { WCD937X_HPH_CNP_EN, 0x80 }, + { WCD937X_HPH_CNP_WG_CTL, 0x9A }, + { WCD937X_HPH_CNP_WG_TIME, 0x14 }, + { WCD937X_HPH_OCP_CTL, 0x28 }, + { WCD937X_HPH_AUTO_CHOP, 0x16 }, + { WCD937X_HPH_CHOP_CTL, 0x83 }, + { WCD937X_HPH_PA_CTL1, 0x46 }, + { WCD937X_HPH_PA_CTL2, 0x50 }, + { WCD937X_HPH_L_EN, 0x80 }, + { WCD937X_HPH_L_TEST, 0xE0 }, + { WCD937X_HPH_L_ATEST, 0x50 }, + { WCD937X_HPH_R_EN, 0x80 }, + { WCD937X_HPH_R_TEST, 0xE0 }, + { WCD937X_HPH_R_ATEST, 0x54 }, + { WCD937X_HPH_RDAC_CLK_CTL1, 0x99 }, + { WCD937X_HPH_RDAC_CLK_CTL2, 0x9B }, + { WCD937X_HPH_RDAC_LDO_CTL, 0x33 }, + { WCD937X_HPH_RDAC_CHOP_CLK_LP_CTL, 0x00 }, + { WCD937X_HPH_REFBUFF_UHQA_CTL, 0xA8 }, + { WCD937X_HPH_REFBUFF_LP_CTL, 0x0E }, + { WCD937X_HPH_L_DAC_CTL, 0x20 }, + { WCD937X_HPH_R_DAC_CTL, 0x20 }, + { WCD937X_HPH_SURGE_HPHLR_SURGE_COMP_SEL, 0x55 }, + { WCD937X_HPH_SURGE_HPHLR_SURGE_EN, 0x19 }, + { WCD937X_HPH_SURGE_HPHLR_SURGE_MISC1, 0xA0 }, + { WCD937X_HPH_SURGE_HPHLR_SURGE_STATUS, 0x00 }, + { WCD937X_EAR_EAR_EN_REG, 0x22 }, + { WCD937X_EAR_EAR_PA_CON, 0x44 }, + { WCD937X_EAR_EAR_SP_CON, 0xDB }, + { WCD937X_EAR_EAR_DAC_CON, 0x80 }, + { WCD937X_EAR_EAR_CNP_FSM_CON, 0xB2 }, + { WCD937X_EAR_TEST_CTL, 0x00 }, + { WCD937X_EAR_STATUS_REG_1, 0x00 }, + { WCD937X_EAR_STATUS_REG_2, 0x00 }, + { WCD937X_ANA_NEW_PAGE_REGISTER, 0x00 }, + { WCD937X_HPH_NEW_ANA_HPH2, 0x00 }, + { WCD937X_HPH_NEW_ANA_HPH3, 0x00 }, + { WCD937X_SLEEP_CTL, 0x16 }, + { WCD937X_SLEEP_WATCHDOG_CTL, 0x00 }, + { WCD937X_MBHC_NEW_ELECT_REM_CLAMP_CTL, 0x00 }, + { WCD937X_MBHC_NEW_CTL_1, 0x02 }, + { WCD937X_MBHC_NEW_CTL_2, 0x05 }, + { WCD937X_MBHC_NEW_PLUG_DETECT_CTL, 0xE9 }, + { WCD937X_MBHC_NEW_ZDET_ANA_CTL, 0x0F }, + { WCD937X_MBHC_NEW_ZDET_RAMP_CTL, 0x00 }, + { WCD937X_MBHC_NEW_FSM_STATUS, 0x00 }, + { WCD937X_MBHC_NEW_ADC_RESULT, 0x00 }, + { WCD937X_TX_NEW_TX_CH2_SEL, 0x00 }, + { WCD937X_AUX_AUXPA, 0x00 }, + { WCD937X_LDORXTX_MODE, 0x0C }, + { WCD937X_LDORXTX_CONFIG, 0x10 }, + { WCD937X_DIE_CRACK_DIE_CRK_DET_EN, 0x00 }, + { WCD937X_DIE_CRACK_DIE_CRK_DET_OUT, 0x00 }, + { WCD937X_HPH_NEW_INT_RDAC_GAIN_CTL, 0x40 }, + { WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x81 }, + { WCD937X_HPH_NEW_INT_RDAC_VREF_CTL, 0x10 }, + { WCD937X_HPH_NEW_INT_RDAC_OVERRIDE_CTL, 0x00 }, + { WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x81 }, + { WCD937X_HPH_NEW_INT_PA_MISC1, 0x22 }, + { WCD937X_HPH_NEW_INT_PA_MISC2, 0x00 }, + { WCD937X_HPH_NEW_INT_PA_RDAC_MISC, 0x00 }, + { WCD937X_HPH_NEW_INT_HPH_TIMER1, 0xFE }, + { WCD937X_HPH_NEW_INT_HPH_TIMER2, 0x02 }, + { WCD937X_HPH_NEW_INT_HPH_TIMER3, 0x4E }, + { WCD937X_HPH_NEW_INT_HPH_TIMER4, 0x54 }, + { WCD937X_HPH_NEW_INT_PA_RDAC_MISC2, 0x00 }, + { WCD937X_HPH_NEW_INT_PA_RDAC_MISC3, 0x00 }, + { WCD937X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI, 0x62 }, + { WCD937X_RX_NEW_INT_HPH_RDAC_BIAS_ULP, 0x01 }, + { WCD937X_RX_NEW_INT_HPH_RDAC_LDO_LP, 0x11 }, + { WCD937X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL, 0x57 }, + { WCD937X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL, 0x01 }, + { WCD937X_MBHC_NEW_INT_MECH_DET_CURRENT, 0x00 }, + { WCD937X_MBHC_NEW_INT_SPARE_2, 0x00 }, + { WCD937X_EAR_INT_NEW_EAR_CHOPPER_CON, 0xA8 }, + { WCD937X_EAR_INT_NEW_CNP_VCM_CON1, 0x42 }, + { WCD937X_EAR_INT_NEW_CNP_VCM_CON2, 0x22 }, + { WCD937X_EAR_INT_NEW_EAR_DYNAMIC_BIAS, 0x00 }, + { WCD937X_AUX_INT_EN_REG, 0x00 }, + { WCD937X_AUX_INT_PA_CTRL, 0x06 }, + { WCD937X_AUX_INT_SP_CTRL, 0xD2 }, + { WCD937X_AUX_INT_DAC_CTRL, 0x80 }, + { WCD937X_AUX_INT_CLK_CTRL, 0x50 }, + { WCD937X_AUX_INT_TEST_CTRL, 0x00 }, + { WCD937X_AUX_INT_STATUS_REG, 0x00 }, + { WCD937X_AUX_INT_MISC, 0x00 }, + { WCD937X_LDORXTX_INT_BIAS, 0x6E }, + { WCD937X_LDORXTX_INT_STB_LOADS_DTEST, 0x50 }, + { WCD937X_LDORXTX_INT_TEST0, 0x1C }, + { WCD937X_LDORXTX_INT_STARTUP_TIMER, 0xFF }, + { WCD937X_LDORXTX_INT_TEST1, 0x1F }, + { WCD937X_LDORXTX_INT_STATUS, 0x00 }, + { WCD937X_SLEEP_INT_WATCHDOG_CTL_1, 0x0A }, + { WCD937X_SLEEP_INT_WATCHDOG_CTL_2, 0x0A }, + { WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT1, 0x02 }, + { WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT2, 0x60 }, + { WCD937X_DIGITAL_PAGE_REGISTER, 0x00 }, + { WCD937X_DIGITAL_CHIP_ID0, 0x00 }, + { WCD937X_DIGITAL_CHIP_ID1, 0x00 }, + { WCD937X_DIGITAL_CHIP_ID2, 0x0A }, + { WCD937X_DIGITAL_CHIP_ID3, 0x01 }, + { WCD937X_DIGITAL_CDC_RST_CTL, 0x03 }, + { WCD937X_DIGITAL_TOP_CLK_CFG, 0x00 }, + { WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x00 }, + { WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x00 }, + { WCD937X_DIGITAL_SWR_RST_EN, 0x00 }, + { WCD937X_DIGITAL_CDC_PATH_MODE, 0x55 }, + { WCD937X_DIGITAL_CDC_RX_RST, 0x00 }, + { WCD937X_DIGITAL_CDC_RX0_CTL, 0xFC }, + { WCD937X_DIGITAL_CDC_RX1_CTL, 0xFC }, + { WCD937X_DIGITAL_CDC_RX2_CTL, 0xFC }, + { WCD937X_DIGITAL_DEM_BYPASS_DATA0, 0x55 }, + { WCD937X_DIGITAL_DEM_BYPASS_DATA1, 0x55 }, + { WCD937X_DIGITAL_DEM_BYPASS_DATA2, 0x55 }, + { WCD937X_DIGITAL_DEM_BYPASS_DATA3, 0x01 }, + { WCD937X_DIGITAL_CDC_COMP_CTL_0, 0x00 }, + { WCD937X_DIGITAL_CDC_RX_DELAY_CTL, 0x66 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_A1_0, 0x00 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_A1_1, 0x01 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_A2_0, 0x63 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_A2_1, 0x04 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_A3_0, 0xAC }, + { WCD937X_DIGITAL_CDC_HPH_DSM_A3_1, 0x04 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_A4_0, 0x1A }, + { WCD937X_DIGITAL_CDC_HPH_DSM_A4_1, 0x03 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_A5_0, 0xBC }, + { WCD937X_DIGITAL_CDC_HPH_DSM_A5_1, 0x02 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_A6_0, 0xC7 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_A7_0, 0xF8 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_C_0, 0x47 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_C_1, 0x43 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_C_2, 0xB1 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_C_3, 0x17 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_R1, 0x4B }, + { WCD937X_DIGITAL_CDC_HPH_DSM_R2, 0x27 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_R3, 0x32 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_R4, 0x57 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_R4, 0x63 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_R4, 0x7C }, + { WCD937X_DIGITAL_CDC_HPH_DSM_R4, 0x57 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_A1_0, 0x00 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_A1_1, 0x01 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_A2_0, 0x96 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_A2_1, 0x09 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_A3_0, 0xAB }, + { WCD937X_DIGITAL_CDC_AUX_DSM_A3_1, 0x05 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_A4_0, 0x1C }, + { WCD937X_DIGITAL_CDC_AUX_DSM_A4_1, 0x02 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_A5_0, 0x17 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_A5_1, 0x02 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_A6_0, 0xAA }, + { WCD937X_DIGITAL_CDC_AUX_DSM_A7_0, 0xE3 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_C_0, 0x69 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_C_1, 0x54 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_C_2, 0x02 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_C_3, 0x15 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_R1, 0xA4 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_R2, 0xB5 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_R3, 0x86 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_R4, 0x85 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_R5, 0xAA }, + { WCD937X_DIGITAL_CDC_AUX_DSM_R6, 0xE2 }, + { WCD937X_DIGITAL_CDC_AUX_DSM_R7, 0x62 }, + { WCD937X_DIGITAL_CDC_HPH_GAIN_RX_0, 0x55 }, + { WCD937X_DIGITAL_CDC_HPH_GAIN_RX_1, 0xA9 }, + { WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_0, 0x3D }, + { WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_1, 0x2E }, + { WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_2, 0x01 }, + { WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_0, 0x00 }, + { WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_1, 0xFC }, + { WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_2, 0x01 }, + { WCD937X_DIGITAL_CDC_HPH_GAIN_CTL, 0x00 }, + { WCD937X_DIGITAL_CDC_AUX_GAIN_CTL, 0x00 }, + { WCD937X_DIGITAL_CDC_EAR_PATH_CTL, 0x00 }, + { WCD937X_DIGITAL_CDC_SWR_CLH, 0x00 }, + { WCD937X_DIGITAL_SWR_CLH_BYP, 0x00 }, + { WCD937X_DIGITAL_CDC_TX0_CTL, 0x68 }, + { WCD937X_DIGITAL_CDC_TX1_CTL, 0x68 }, + { WCD937X_DIGITAL_CDC_TX2_CTL, 0x68 }, + { WCD937X_DIGITAL_CDC_TX_RST, 0x00 }, + { WCD937X_DIGITAL_CDC_REQ_CTL, 0x01 }, + { WCD937X_DIGITAL_CDC_AMIC_CTL, 0x07 }, + { WCD937X_DIGITAL_CDC_DMIC_CTL, 0x00 }, + { WCD937X_DIGITAL_CDC_DMIC0_CTL, 0x01 }, + { WCD937X_DIGITAL_CDC_DMIC1_CTL, 0x01 }, + { WCD937X_DIGITAL_CDC_DMIC2_CTL, 0x01 }, + { WCD937X_DIGITAL_EFUSE_CTL, 0x2B }, + { WCD937X_DIGITAL_EFUSE_PRG_CTL, 0x00 }, + { WCD937X_DIGITAL_EFUSE_TEST_CTL_0, 0x00 }, + { WCD937X_DIGITAL_EFUSE_TEST_CTL_1, 0x00 }, + { WCD937X_DIGITAL_EFUSE_T_DATA_0, 0x00 }, + { WCD937X_DIGITAL_EFUSE_T_DATA_1, 0x00 }, + { WCD937X_DIGITAL_PDM_WD_CTL0, 0x00 }, + { WCD937X_DIGITAL_PDM_WD_CTL1, 0x00 }, + { WCD937X_DIGITAL_PDM_WD_CTL2, 0x00 }, + { WCD937X_DIGITAL_INTR_MODE, 0x00 }, + { WCD937X_DIGITAL_INTR_MASK_0, 0xFF }, + { WCD937X_DIGITAL_INTR_MASK_1, 0xFF }, + { WCD937X_DIGITAL_INTR_MASK_2, 0xFF }, + { WCD937X_DIGITAL_INTR_STATUS_0, 0x00 }, + { WCD937X_DIGITAL_INTR_STATUS_1, 0x00 }, + { WCD937X_DIGITAL_INTR_STATUS_2, 0x00 }, + { WCD937X_DIGITAL_INTR_CLEAR_0, 0x00 }, + { WCD937X_DIGITAL_INTR_CLEAR_1, 0x00 }, + { WCD937X_DIGITAL_INTR_CLEAR_2, 0x00 }, + { WCD937X_DIGITAL_INTR_LEVEL_0, 0x00 }, + { WCD937X_DIGITAL_INTR_LEVEL_1, 0x00 }, + { WCD937X_DIGITAL_INTR_LEVEL_2, 0x00 }, + { WCD937X_DIGITAL_INTR_SET_0, 0x00 }, + { WCD937X_DIGITAL_INTR_SET_1, 0x00 }, + { WCD937X_DIGITAL_INTR_SET_2, 0x00 }, + { WCD937X_DIGITAL_INTR_TEST_0, 0x00 }, + { WCD937X_DIGITAL_INTR_TEST_1, 0x00 }, + { WCD937X_DIGITAL_INTR_TEST_2, 0x00 }, + { WCD937X_DIGITAL_CDC_CONN_RX0_CTL, 0x00 }, + { WCD937X_DIGITAL_CDC_CONN_RX1_CTL, 0x00 }, + { WCD937X_DIGITAL_CDC_CONN_RX2_CTL, 0x00 }, + { WCD937X_DIGITAL_CDC_CONN_TX_CTL, 0x00 }, + { WCD937X_DIGITAL_LOOP_BACK_MODE, 0x00 }, + { WCD937X_DIGITAL_SWR_DAC_TEST, 0x00 }, + { WCD937X_DIGITAL_SWR_HM_TEST_RX_0, 0x40 }, + { WCD937X_DIGITAL_SWR_HM_TEST_TX_0, 0x40 }, + { WCD937X_DIGITAL_SWR_HM_TEST_RX_1, 0x00 }, + { WCD937X_DIGITAL_SWR_HM_TEST_TX_1, 0x00 }, + { WCD937X_DIGITAL_SWR_HM_TEST, 0x00 }, + { WCD937X_DIGITAL_PAD_CTL_PDM_RX0, 0xF1 }, + { WCD937X_DIGITAL_PAD_CTL_PDM_RX1, 0xF1 }, + { WCD937X_DIGITAL_PAD_CTL_PDM_RX2, 0xF1 }, + { WCD937X_DIGITAL_PAD_CTL_PDM_TX, 0xF1 }, + { WCD937X_DIGITAL_PAD_INP_DIS_1, 0x00 }, + { WCD937X_DIGITAL_DRIVE_STRENGTH_0, 0x00 }, + { WCD937X_DIGITAL_DRIVE_STRENGTH_1, 0x00 }, + { WCD937X_DIGITAL_DRIVE_STRENGTH_2, 0x00 }, + { WCD937X_DIGITAL_RX_DATA_EDGE_CTL, 0x1F }, + { WCD937X_DIGITAL_TX_DATA_EDGE_CTL, 0x10 }, + { WCD937X_DIGITAL_GPIO_MODE, 0x00 }, + { WCD937X_DIGITAL_PIN_CTL_OE, 0x00 }, + { WCD937X_DIGITAL_PIN_CTL_DATA_0, 0x00 }, + { WCD937X_DIGITAL_PIN_CTL_DATA_1, 0x00 }, + { WCD937X_DIGITAL_PIN_STATUS_0, 0x00 }, + { WCD937X_DIGITAL_PIN_STATUS_1, 0x00 }, + { WCD937X_DIGITAL_DIG_DEBUG_CTL, 0x00 }, + { WCD937X_DIGITAL_DIG_DEBUG_EN, 0x00 }, + { WCD937X_DIGITAL_ANA_CSR_DBG_ADD, 0x00 }, + { WCD937X_DIGITAL_ANA_CSR_DBG_CTL, 0x48 }, + { WCD937X_DIGITAL_SSP_DBG, 0x00 }, + { WCD937X_DIGITAL_MODE_STATUS_0, 0x00 }, + { WCD937X_DIGITAL_MODE_STATUS_1, 0x00 }, + { WCD937X_DIGITAL_SPARE_0, 0x00 }, + { WCD937X_DIGITAL_SPARE_1, 0x00 }, + { WCD937X_DIGITAL_SPARE_2, 0x00 }, + { WCD937X_DIGITAL_EFUSE_REG_0, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_1, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_2, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_3, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_4, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_5, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_6, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_7, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_8, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_9, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_10, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_11, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_12, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_13, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_14, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_15, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_16, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_17, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_18, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_19, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_20, 0x0E }, + { WCD937X_DIGITAL_EFUSE_REG_21, 0x8F }, + { WCD937X_DIGITAL_EFUSE_REG_22, 0x16 }, + { WCD937X_DIGITAL_EFUSE_REG_23, 0x00 }, + { WCD937X_DIGITAL_EFUSE_REG_24, 0x00 }, + { WCD937X_DIGITAL_EFUSE_REG_25, 0x00 }, + { WCD937X_DIGITAL_EFUSE_REG_26, 0x00 }, + { WCD937X_DIGITAL_EFUSE_REG_27, 0x00 }, + { WCD937X_DIGITAL_EFUSE_REG_28, 0x00 }, + { WCD937X_DIGITAL_EFUSE_REG_29, 0x00 }, + { WCD937X_DIGITAL_EFUSE_REG_30, 0x00 }, + { WCD937X_DIGITAL_EFUSE_REG_31, 0x00 }, +}; + +static bool wcd937x_readable_register(struct device *dev, unsigned int reg) +{ + return wcd937x_reg_access[WCD937X_REG(reg)] & RD_REG; +} + +static bool wcd937x_writeable_register(struct device *dev, unsigned int reg) +{ + return wcd937x_reg_access[WCD937X_REG(reg)] & WR_REG; +} + +static bool wcd937x_volatile_register(struct device *dev, unsigned int reg) +{ + return (wcd937x_reg_access[WCD937X_REG(reg)] & RD_REG) + & ~(wcd937x_reg_access[WCD937X_REG(reg)] & WR_REG); +} + +struct regmap_config wcd937x_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wcd937x_defaults, + .num_reg_defaults = ARRAY_SIZE(wcd937x_defaults), + .max_register = WCD937X_MAX_REGISTER, + .readable_reg = wcd937x_readable_register, + .writeable_reg = wcd937x_writeable_register, + .volatile_reg = wcd937x_volatile_register, + .can_multi_write = true, +}; diff --git a/asoc/codecs/wcd937x/wcd937x-tables.c b/asoc/codecs/wcd937x/wcd937x-tables.c new file mode 100644 index 000000000000..70507306a5e6 --- /dev/null +++ b/asoc/codecs/wcd937x/wcd937x-tables.c @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2018 , The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "wcd937x-registers.h" + +const u8 wcd937x_reg_access[WCD937X_REG(WCD937X_REGISTERS_MAX_SIZE)] = { + [WCD937X_REG(WCD937X_ANA_BIAS)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_RX_SUPPLIES)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_HPH)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_EAR)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_EAR_COMPANDER_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_TX_CH1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_TX_CH2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_TX_CH3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_TX_CH3_HPF)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MICB1_MICB2_DSP_EN_LOGIC)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MICB3_DSP_EN_LOGIC)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MBHC_MECH)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MBHC_ELECT)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MBHC_ZDET)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MBHC_RESULT_1)] = RD_REG, + [WCD937X_REG(WCD937X_ANA_MBHC_RESULT_2)] = RD_REG, + [WCD937X_REG(WCD937X_ANA_MBHC_RESULT_3)] = RD_REG, + [WCD937X_REG(WCD937X_ANA_MBHC_BTN0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MBHC_BTN1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MBHC_BTN2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MBHC_BTN3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MBHC_BTN4)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MBHC_BTN5)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MBHC_BTN6)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MBHC_BTN7)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MICB1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MICB2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MICB2_RAMP)] = RD_WR_REG, + [WCD937X_REG(WCD937X_ANA_MICB3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_BIAS_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_BIAS_VBG_FINE_ADJ)] = RD_WR_REG, + [WCD937X_REG(WCD937X_LDOL_VDDCX_ADJUST)] = RD_WR_REG, + [WCD937X_REG(WCD937X_LDOL_DISABLE_LDOL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_CTL_CLK)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_CTL_ANA)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_CTL_SPARE_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_CTL_SPARE_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_CTL_BCS)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_MOISTURE_DET_FSM_STATUS)] = RD_REG, + [WCD937X_REG(WCD937X_MBHC_TEST_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_LDOH_MODE)] = RD_WR_REG, + [WCD937X_REG(WCD937X_LDOH_BIAS)] = RD_WR_REG, + [WCD937X_REG(WCD937X_LDOH_STB_LOADS)] = RD_WR_REG, + [WCD937X_REG(WCD937X_LDOH_SLOWRAMP)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MICB1_TEST_CTL_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MICB1_TEST_CTL_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MICB1_TEST_CTL_3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MICB2_TEST_CTL_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MICB2_TEST_CTL_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MICB2_TEST_CTL_3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MICB3_TEST_CTL_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MICB3_TEST_CTL_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MICB3_TEST_CTL_3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_COM_ADC_VCM)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_COM_BIAS_ATEST)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_COM_ADC_INT1_IB)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_COM_ADC_INT2_IB)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_COM_TXFE_DIV_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_COM_TXFE_DIV_START)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_COM_TXFE_DIV_STOP_9P6M)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_COM_TXFE_DIV_STOP_12P288M)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_1_2_TEST_EN)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_1_2_ADC_IB)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_1_2_ATEST_REFCTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_1_2_TEST_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_1_2_TEST_BLK_EN)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_1_2_TXFE_CLKDIV)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_1_2_SAR2_ERR)] = RD_REG, + [WCD937X_REG(WCD937X_TX_1_2_SAR1_ERR)] = RD_REG, + [WCD937X_REG(WCD937X_TX_3_TEST_EN)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_3_ADC_IB)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_3_ATEST_REFCTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_3_TEST_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_3_TEST_BLK_EN)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_3_TXFE_CLKDIV)] = RD_WR_REG, + [WCD937X_REG(WCD937X_TX_3_SPARE_MONO)] = RD_REG, + [WCD937X_REG(WCD937X_TX_3_SAR1_ERR)] = RD_REG, + [WCD937X_REG(WCD937X_CLASSH_MODE_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_CLASSH_MODE_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_CLASSH_MODE_3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_CLASSH_CTRL_VCL_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_CLASSH_CTRL_VCL_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_CLASSH_CTRL_CCL_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_CLASSH_CTRL_CCL_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_CLASSH_CTRL_CCL_3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_CLASSH_CTRL_CCL_4)] = RD_WR_REG, + [WCD937X_REG(WCD937X_CLASSH_CTRL_CCL_5)] = RD_WR_REG, + [WCD937X_REG(WCD937X_CLASSH_BUCK_TMUX_A_D)] = RD_WR_REG, + [WCD937X_REG(WCD937X_CLASSH_BUCK_SW_DRV_CNTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_CLASSH_SPARE)] = RD_WR_REG, + [WCD937X_REG(WCD937X_FLYBACK_EN)] = RD_WR_REG, + [WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_4)] = RD_WR_REG, + [WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_5)] = RD_WR_REG, + [WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_6)] = RD_WR_REG, + [WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_7)] = RD_WR_REG, + [WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_8)] = RD_WR_REG, + [WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_9)] = RD_WR_REG, + [WCD937X_REG(WCD937X_FLYBACK_VNEGDAC_CTRL_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_FLYBACK_VNEGDAC_CTRL_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_FLYBACK_VNEGDAC_CTRL_3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_FLYBACK_CTRL_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_FLYBACK_TEST_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_AUX_SW_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_PA_AUX_IN_CONN)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_TIMER_DIV)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_OCP_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_OCP_COUNT)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_EAR_DAC)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_EAR_AMP)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_HPH_LDO)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_HPH_PA)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_HPH_RDACBUFF_CNP2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_HPH_RDAC_LDO)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_HPH_CNP1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_HPH_LOWPOWER)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_AUX_DAC)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_AUX_AMP)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_VNEGDAC_BLEEDER)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_MISC)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_BUCK_RST)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_BUCK_VREF_ERRAMP)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_FLYB_ERRAMP)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_FLYB_BUFF)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_BIAS_FLYB_MID_RST)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_L_STATUS)] = RD_REG, + [WCD937X_REG(WCD937X_HPH_R_STATUS)] = RD_REG, + [WCD937X_REG(WCD937X_HPH_CNP_EN)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_CNP_WG_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_CNP_WG_TIME)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_OCP_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_AUTO_CHOP)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_CHOP_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_PA_CTL1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_PA_CTL2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_L_EN)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_L_TEST)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_L_ATEST)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_R_EN)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_R_TEST)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_R_ATEST)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_RDAC_CLK_CTL1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_RDAC_CLK_CTL2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_RDAC_LDO_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_RDAC_CHOP_CLK_LP_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_REFBUFF_UHQA_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_REFBUFF_LP_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_L_DAC_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_R_DAC_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_SURGE_HPHLR_SURGE_COMP_SEL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_SURGE_HPHLR_SURGE_EN)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_SURGE_HPHLR_SURGE_MISC1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_SURGE_HPHLR_SURGE_STATUS)] = RD_REG, + [WCD937X_REG(WCD937X_EAR_EAR_EN_REG)] = RD_WR_REG, + [WCD937X_REG(WCD937X_EAR_EAR_PA_CON)] = RD_WR_REG, + [WCD937X_REG(WCD937X_EAR_EAR_SP_CON)] = RD_WR_REG, + [WCD937X_REG(WCD937X_EAR_EAR_DAC_CON)] = RD_WR_REG, + [WCD937X_REG(WCD937X_EAR_EAR_CNP_FSM_CON)] = RD_WR_REG, + [WCD937X_REG(WCD937X_EAR_TEST_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_EAR_STATUS_REG_1)] = RD_REG, + [WCD937X_REG(WCD937X_EAR_STATUS_REG_2)] = RD_REG, + [WCD937X_REG(WCD937X_ANA_NEW_PAGE_REGISTER)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_NEW_ANA_HPH2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_NEW_ANA_HPH3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_SLEEP_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_SLEEP_WATCHDOG_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_NEW_ELECT_REM_CLAMP_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_NEW_CTL_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_NEW_CTL_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_NEW_PLUG_DETECT_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_NEW_ZDET_ANA_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_NEW_ZDET_RAMP_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_NEW_FSM_STATUS)] = RD_REG, + [WCD937X_REG(WCD937X_MBHC_NEW_ADC_RESULT)] = RD_REG, + [WCD937X_REG(WCD937X_TX_NEW_TX_CH2_SEL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_AUX_AUXPA)] = RD_WR_REG, + [WCD937X_REG(WCD937X_LDORXTX_MODE)] = RD_WR_REG, + [WCD937X_REG(WCD937X_LDORXTX_CONFIG)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIE_CRACK_DIE_CRK_DET_EN)] = RD_REG, + [WCD937X_REG(WCD937X_DIE_CRACK_DIE_CRK_DET_OUT)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_NEW_INT_RDAC_GAIN_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_NEW_INT_RDAC_VREF_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_NEW_INT_RDAC_OVERRIDE_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_NEW_INT_PA_MISC1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_NEW_INT_PA_MISC2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_NEW_INT_PA_RDAC_MISC)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_NEW_INT_HPH_TIMER1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_NEW_INT_HPH_TIMER2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_NEW_INT_HPH_TIMER3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_NEW_INT_HPH_TIMER4)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_NEW_INT_PA_RDAC_MISC2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_HPH_NEW_INT_PA_RDAC_MISC3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_NEW_INT_HPH_RDAC_BIAS_ULP)] = RD_WR_REG, + [WCD937X_REG(WCD937X_RX_NEW_INT_HPH_RDAC_LDO_LP)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL)] + = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_NEW_INT_MECH_DET_CURRENT)] = RD_WR_REG, + [WCD937X_REG(WCD937X_MBHC_NEW_INT_SPARE_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_EAR_INT_NEW_EAR_CHOPPER_CON)] = RD_WR_REG, + [WCD937X_REG(WCD937X_EAR_INT_NEW_CNP_VCM_CON1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_EAR_INT_NEW_CNP_VCM_CON2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_EAR_INT_NEW_EAR_DYNAMIC_BIAS)] = RD_WR_REG, + [WCD937X_REG(WCD937X_AUX_INT_EN_REG)] = RD_WR_REG, + [WCD937X_REG(WCD937X_AUX_INT_PA_CTRL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_AUX_INT_SP_CTRL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_AUX_INT_DAC_CTRL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_AUX_INT_CLK_CTRL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_AUX_INT_TEST_CTRL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_AUX_INT_STATUS_REG)] = RD_REG, + [WCD937X_REG(WCD937X_AUX_INT_MISC)] = RD_WR_REG, + [WCD937X_REG(WCD937X_LDORXTX_INT_BIAS)] = RD_WR_REG, + [WCD937X_REG(WCD937X_LDORXTX_INT_STB_LOADS_DTEST)] = RD_WR_REG, + [WCD937X_REG(WCD937X_LDORXTX_INT_TEST0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_LDORXTX_INT_STARTUP_TIMER)] = RD_WR_REG, + [WCD937X_REG(WCD937X_LDORXTX_INT_TEST1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_LDORXTX_INT_STATUS)] = RD_REG, + [WCD937X_REG(WCD937X_SLEEP_INT_WATCHDOG_CTL_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_SLEEP_INT_WATCHDOG_CTL_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PAGE_REGISTER)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CHIP_ID0)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_CHIP_ID1)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_CHIP_ID2)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_CHIP_ID3)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_RST_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_TOP_CLK_CFG)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_ANA_CLK_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_DIG_CLK_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_SWR_RST_EN)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_PATH_MODE)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_RX_RST)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_RX0_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_RX1_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_RX2_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_DEM_BYPASS_DATA0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_DEM_BYPASS_DATA1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_DEM_BYPASS_DATA2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_DEM_BYPASS_DATA3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_COMP_CTL_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_RX_DELAY_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A1_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A1_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A2_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A2_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A3_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A3_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A4_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A4_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A5_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A5_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A6_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A7_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_C_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_C_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_C_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_C_3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R4)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R4)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R4)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R4)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A1_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A1_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A2_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A2_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A3_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A3_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A4_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A4_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A5_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A5_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A6_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A7_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_C_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_C_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_C_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_C_3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_R1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_R2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_R3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_R4)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_R5)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_R6)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_R7)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_GAIN_RX_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_GAIN_RX_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_GAIN_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_GAIN_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_EAR_PATH_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_SWR_CLH)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_SWR_CLH_BYP)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_TX0_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_TX1_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_TX2_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_TX_RST)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_REQ_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_AMIC_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_DMIC_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_DMIC0_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_DMIC1_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_DMIC2_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_PRG_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_TEST_CTL_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_TEST_CTL_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_T_DATA_0)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_T_DATA_1)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_PDM_WD_CTL0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PDM_WD_CTL1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PDM_WD_CTL2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_MODE)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_MASK_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_MASK_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_MASK_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_STATUS_0)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_STATUS_1)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_STATUS_2)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_CLEAR_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_CLEAR_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_CLEAR_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_LEVEL_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_LEVEL_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_LEVEL_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_SET_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_SET_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_SET_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_TEST_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_TEST_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_INTR_TEST_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_CONN_RX0_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_CONN_RX1_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_CONN_RX2_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_CONN_TX_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_LOOP_BACK_MODE)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_SWR_DAC_TEST)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_SWR_HM_TEST_RX_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_SWR_HM_TEST_TX_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_SWR_HM_TEST_RX_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_SWR_HM_TEST_TX_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_SWR_HM_TEST)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_RX0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_RX1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_RX2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_TX)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_TX)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PAD_INP_DIS_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_DRIVE_STRENGTH_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_DRIVE_STRENGTH_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_DRIVE_STRENGTH_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_RX_DATA_EDGE_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_TX_DATA_EDGE_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_GPIO_MODE)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PIN_CTL_OE)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PIN_CTL_DATA_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PIN_CTL_DATA_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PIN_STATUS_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PIN_STATUS_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_DIG_DEBUG_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_DIG_DEBUG_EN)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_ANA_CSR_DBG_ADD)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_ANA_CSR_DBG_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_SSP_DBG)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_MODE_STATUS_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_MODE_STATUS_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_SPARE_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_SPARE_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_SPARE_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_1)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_2)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_3)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_4)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_5)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_6)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_7)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_8)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_9)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_10)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_11)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_12)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_13)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_14)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_15)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_16)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_17)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_18)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_19)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_20)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_21)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_22)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_23)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_24)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_25)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_26)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_27)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_28)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_29)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_30)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_31)] = RD_WR_REG, +}; diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index e2c6ddf9659f..78bd8634fa30 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -19,59 +19,1152 @@ #include #include #include +#include #include +#include +#include +#include +#include "internal.h" +#include "../wcdcal-hwdep.h" +#include "wcd937x-registers.h" #include "../msm-cdc-pinctrl.h" -struct wcd937x_priv { - struct device *dev; - struct snd_soc_codec *codec; - struct device_node *rst_np; - struct swr_device *rx_swr_dev; - struct swr_device *tx_swr_dev; -}; +#define WCD9370_VARIANT 0 +#define WCD9375_VARIANT 5 -struct wcd937x_pdata { - struct device_node *rst_np; - struct device_node *rx_slave; - struct device_node *tx_slave; -}; +static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); +static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); -static int wcd937x_soc_codec_probe(struct snd_soc_codec *codec) +static int wcd937x_init_reg(struct snd_soc_codec *codec) +{ + snd_soc_update_bits(codec, WCD937X_SLEEP_CTL, 0x0E, 0x0E); + snd_soc_update_bits(codec, WCD937X_SLEEP_CTL, 0x80, 0x80); + usleep_range(1000, 1010); + snd_soc_update_bits(codec, WCD937X_SLEEP_CTL, 0x40, 0x40); + usleep_range(1000, 1010); + snd_soc_update_bits(codec, WCD937X_LDORXTX_CONFIG, 0x10, 0x00); + snd_soc_update_bits(codec, WCD937X_BIAS_VBG_FINE_ADJ, 0xF0, 0x80); + snd_soc_update_bits(codec, WCD937X_ANA_BIAS, 0x80, 0x80); + snd_soc_update_bits(codec, WCD937X_ANA_BIAS, 0x40, 0x40); + usleep_range(10000, 10010); + snd_soc_update_bits(codec, WCD937X_ANA_BIAS, 0x40, 0x00); + + return 0; +} + +static int wcd937x_rx_clk_enable(struct snd_soc_codec *codec) { + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); - if (!wcd937x) + if (wcd937x->rx_clk_cnt == 0) { + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x08, 0x08); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, + 0x01, 0x01); + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x01, 0x01); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_RX0_CTL, + 0x40, 0x00); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, + 0x02, 0x02); + } + wcd937x->rx_clk_cnt++; + + return 0; +} + +static int wcd937x_rx_clk_disable(struct snd_soc_codec *codec) +{ + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + + wcd937x->rx_clk_cnt--; + if (wcd937x->rx_clk_cnt == 0) { + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x40, 0x00); + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x80, 0x00); + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x01, 0x00); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, + 0x02, 0x00); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, + 0x01, 0x00); + } + return 0; +} + +static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd937x_rx_clk_enable(codec); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x01, 0x01); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_HPH_GAIN_CTL, + 0x04, 0x04); + snd_soc_update_bits(codec, WCD937X_HPH_RDAC_CLK_CTL1, + 0x80, 0x00); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, + 0x0F, 0x02); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, + 0x02, 0x02); + usleep_range(5000, 5010); + snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x00); + break; + } + + return 0; +} + +static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd937x_rx_clk_enable(codec); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x02, 0x02); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_HPH_GAIN_CTL, + 0x08, 0x08); + snd_soc_update_bits(codec, WCD937X_HPH_RDAC_CLK_CTL1, + 0x80, 0x00); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, + 0x0F, 0x02); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, + 0x01, 0x01); + usleep_range(5000, 5010); + snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x00); + break; + } + + return 0; +} + +static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd937x_rx_clk_enable(codec); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_HPH_GAIN_CTL, + 0x04, 0x04); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x01, 0x01); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, + 0x02, 0x02); + usleep_range(5000, 5010); + break; + }; + return 0; + +} + +static int wcd937x_codec_aux_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd937x_rx_clk_enable(codec); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, + 0x04, 0x04); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x04, 0x04); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_AUX_GAIN_CTL, + 0x01, 0x01); + break; + case SND_SOC_DAPM_POST_PMD: + wcd937x_rx_clk_disable(codec); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, + 0x04, 0x00); + break; + }; + return 0; + +} + +static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x10, 0x10); + usleep_range(100, 110); + break; + case SND_SOC_DAPM_POST_PMU: + usleep_range(7000, 7010); + snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x02); + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, + 0x02, 0x02); + break; + case SND_SOC_DAPM_POST_PMD: + usleep_range(7000, 7010); + snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x10, 0x00); + break; + }; + return 0; +} + +static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x0C, 0x08); + snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x20, 0x20); + usleep_range(100, 110); + break; + case SND_SOC_DAPM_POST_PMU: + usleep_range(7000, 7010); + snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x02); + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, + 0x02, 0x02); + break; + case SND_SOC_DAPM_POST_PMD: + usleep_range(7000, 7010); + snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x20, 0x00); + break; + }; + return 0; +} + +static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, + 0x80, 0x80); + usleep_range(500, 510); + snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, 0xFF, 0x3A); + usleep_range(500, 510); + break; + case SND_SOC_DAPM_POST_PMU: + usleep_range(1000, 1010); + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, + 0x20, 0x20); + break; + case SND_SOC_DAPM_POST_PMD: + usleep_range(1000, 1010); + usleep_range(1000, 1010); + break; + }; + return 0; +} + +static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, + 0x08, 0x08); + usleep_range(500, 510); + snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, 0xFF, 0x3A); + usleep_range(500, 510); + break; + case SND_SOC_DAPM_POST_PMU: + usleep_range(6000, 6010); + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, + 0x02, 0x02); + break; + case SND_SOC_DAPM_POST_PMD: + usleep_range(7000, 7010); + break; + }; + return 0; +} + +static int wcd937x_enable_rx1(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEG_CTRL_4, + 0xF0, 0x80); + snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEGDAC_CTRL_2, + 0xE0, 0xA0); + snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_3, + 0x02, 0x02); + snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, + 0xFF, 0x1C); + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, + 0x40, 0x40); + usleep_range(100, 110); + snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEGDAC_CTRL_2, + 0xE0, 0xE0); + usleep_range(100, 110); + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, + 0x80, 0x80); + usleep_range(500, 510); + snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, 0xFF, 0x3A); + usleep_range(500, 510); + break; + case SND_SOC_DAPM_POST_PMD: + wcd937x_rx_clk_disable(codec); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x01, 0x00); + break; + }; + return 0; +} +static int wcd937x_enable_rx2(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEG_CTRL_4, + 0xF0, 0x80); + snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEGDAC_CTRL_2, + 0xE0, 0xA0); + snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_3, 0x02, 0x02); + snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, 0xFF, 0x1C); + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, + 0x40, 0x40); + usleep_range(100, 110); + snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEGDAC_CTRL_2, + 0xE0, 0xE0); + usleep_range(100, 110); + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, + 0x80, 0x80); + usleep_range(500, 510); + snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, 0xFF, 0x3A); + usleep_range(500, 510); + break; + case SND_SOC_DAPM_POST_PMD: + wcd937x_rx_clk_disable(codec); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x02, 0x00); + break; + }; + + return 0; +} + +static int wcd937x_enable_rx3(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEG_CTRL_2, + 0xE0, 0xA0); + snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_3, 0x02, 0x02); + snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, 0xFF, 0x1C); + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, + 0x40, 0x40); + usleep_range(100, 110); + snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEG_CTRL_2, + 0xE0, 0xE0); + usleep_range(100, 110); + break; + case SND_SOC_DAPM_POST_PMD: + usleep_range(6000, 6010); + wcd937x_rx_clk_disable(codec); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x04, 0x00); + break; + } + return 0; + +} + +static int wcd937x_codec_enable_dmic(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + u16 dmic_clk_reg; + s32 *dmic_clk_cnt; + unsigned int dmic; + char *wname; + int ret = 0; + + wname = strpbrk(w->name, "012345"); + + if (!wname) { + dev_err(codec->dev, "%s: widget not found\n", __func__); + return -EINVAL; + } + + ret = kstrtouint(wname, 10, &dmic); + if (ret < 0) { + dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n", + __func__); + return -EINVAL; + } + + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (dmic) { + case 0: + case 1: + dmic_clk_cnt = &(wcd937x->dmic_0_1_clk_cnt); + dmic_clk_reg = WCD937X_DIGITAL_CDC_DMIC0_CTL; + break; + case 2: + case 3: + dmic_clk_cnt = &(wcd937x->dmic_2_3_clk_cnt); + dmic_clk_reg = WCD937X_DIGITAL_CDC_DMIC1_CTL; + break; + case 4: + case 5: + dmic_clk_cnt = &(wcd937x->dmic_4_5_clk_cnt); + dmic_clk_reg = WCD937X_DIGITAL_CDC_DMIC2_CTL; + break; + default: + dev_err(codec->dev, "%s: Invalid DMIC Selection\n", + __func__); return -EINVAL; + }; + dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", + __func__, event, dmic, *dmic_clk_cnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x80); + snd_soc_update_bits(codec, dmic_clk_reg, 0x07, 0x02); + snd_soc_update_bits(codec, dmic_clk_reg, 0x08, 0x08); + snd_soc_update_bits(codec, dmic_clk_reg, 0x70, 0x20); + break; + case SND_SOC_DAPM_POST_PMD: + break; + }; return 0; } -static int wcd937x_soc_codec_remove(struct snd_soc_codec *codec) +static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event){ + + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x80); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, + 0x08, 0x08); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, + 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, + 0x08, 0x00); + break; + }; + + return 0; +} + +static int wcd937x_enable_req(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) { + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_REQ_CTL, + 0x02, 0x02); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_REQ_CTL, 0x01, + 0x00); + snd_soc_update_bits(codec, WCD937X_ANA_TX_CH2, 0x40, 0x40); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x10, 0x10); + snd_soc_update_bits(codec, WCD937X_ANA_TX_CH1, 0x80, 0x80); + snd_soc_update_bits(codec, WCD937X_ANA_TX_CH2, 0x40, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, WCD937X_ANA_TX_CH1, 0x80, 0x00); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x10, 0x00); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, + 0x10, 0x00); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x00); + break; + }; + return 0; +} + +static int wcd937x_micbias_control(struct snd_soc_codec *codec, + int micb_num, int req, bool is_dapm) +{ + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int micb_index = micb_num - 1; + u16 micb_reg; + int pre_off_event = 0, post_off_event = 0; + int post_on_event = 0, post_dapm_off = 0; + int post_dapm_on = 0; - if (!wcd937x) + if ((micb_index < 0) || (micb_index > WCD937X_MAX_MICBIAS - 1)) { + dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n", + __func__, micb_index); return -EINVAL; + } + switch (micb_num) { + case MIC_BIAS_1: + micb_reg = WCD937X_ANA_MICB1; + break; + case MIC_BIAS_2: + micb_reg = WCD937X_ANA_MICB2; + pre_off_event = WCD_EVENT_PRE_MICBIAS_2_OFF; + post_off_event = WCD_EVENT_POST_MICBIAS_2_OFF; + post_on_event = WCD_EVENT_POST_MICBIAS_2_ON; + post_dapm_on = WCD_EVENT_POST_DAPM_MICBIAS_2_ON; + post_dapm_off = WCD_EVENT_POST_DAPM_MICBIAS_2_OFF; + break; + case MIC_BIAS_3: + micb_reg = WCD937X_ANA_MICB3; + break; + default: + dev_err(codec->dev, "%s: Invalid micbias number: %d\n", + __func__, micb_num); + return -EINVAL; + }; + mutex_lock(&wcd937x->micb_lock); + + switch (req) { + case MICB_PULLUP_ENABLE: + wcd937x->pullup_ref[micb_index]++; + if ((wcd937x->pullup_ref[micb_index] == 1) && + (wcd937x->micb_ref[micb_index] == 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + break; + case MICB_PULLUP_DISABLE: + if (wcd937x->pullup_ref[micb_index] > 0) + wcd937x->pullup_ref[micb_index]--; + if ((wcd937x->pullup_ref[micb_index] == 0) && + (wcd937x->micb_ref[micb_index] == 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + break; + case MICB_ENABLE: + wcd937x->micb_ref[micb_index]++; + if (wcd937x->micb_ref[micb_index] == 1) { + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + if (post_on_event) + blocking_notifier_call_chain(&wcd937x->notifier, + post_on_event, + &wcd937x->mbhc); + } + if (is_dapm && post_dapm_on) + blocking_notifier_call_chain(&wcd937x->notifier, + post_dapm_on, + &wcd937x->mbhc); + break; + case MICB_DISABLE: + if (wcd937x->micb_ref[micb_index] > 0) + wcd937x->micb_ref[micb_index]--; + if ((wcd937x->micb_ref[micb_index] == 0) && + (wcd937x->pullup_ref[micb_index] > 0)) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + else if ((wcd937x->micb_ref[micb_index] == 0) && + (wcd937x->pullup_ref[micb_index] == 0)) { + if (pre_off_event) + blocking_notifier_call_chain(&wcd937x->notifier, + pre_off_event, + &wcd937x->mbhc); + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + if (post_off_event) + blocking_notifier_call_chain(&wcd937x->notifier, + post_off_event, + &wcd937x->mbhc); + } + if (is_dapm && post_dapm_off) + blocking_notifier_call_chain(&wcd937x->notifier, + post_dapm_off, + &wcd937x->mbhc); + break; + }; + + dev_dbg(codec->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", + __func__, micb_num, wcd937x->micb_ref[micb_index], + wcd937x->pullup_ref[micb_index]); + mutex_unlock(&wcd937x->micb_lock); return 0; } -static struct regmap *wcd937x_get_regmap(struct device *dev) +static int __wcd937x_codec_enable_micbias(struct snd_soc_dapm_widget *w, + int event) { - struct wcd937x_priv *wcd937x = dev_get_drvdata(dev); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int micb_num; + + dev_dbg(codec->dev, "%s: wname: %s, event: %d\n", + __func__, w->name, event); + + if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) + micb_num = MIC_BIAS_1; + else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2"))) + micb_num = MIC_BIAS_2; + else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3"))) + micb_num = MIC_BIAS_3; + else + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd937x_micbias_control(codec, micb_num, MICB_ENABLE, true); + break; + case SND_SOC_DAPM_POST_PMU: + usleep_range(1000, 1100); + break; + case SND_SOC_DAPM_POST_PMD: + wcd937x_micbias_control(codec, micb_num, MICB_DISABLE, true); + break; + }; + + return 0; - return wcd937x->regmap; } +static int wcd937x_codec_enable_micbias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + return __wcd937x_codec_enable_micbias(w, event); +} + +static int wcd937x_rx_hph_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = wcd937x->hph_mode; + return 0; +} + +static int wcd937x_rx_hph_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + u32 mode_val; + + mode_val = ucontrol->value.enumerated.item[0]; + + dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val); + + if (mode_val == 0) { + dev_warn(codec->dev, "%s:Invalid HPH Mode, default to class_AB\n", + __func__); + mode_val = 3; /* enum will be updated later */ + } + wcd937x->hph_mode = mode_val; + return 0; +} + +static const char * const rx_hph_mode_mux_text[] = { + "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI", + "CLS_H_ULP", "CLS_AB_HIFI", +}; + +static const struct soc_enum rx_hph_mode_mux_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text), + rx_hph_mode_mux_text); + static const struct snd_kcontrol_new wcd937x_snd_controls[] = { + SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum, + wcd937x_rx_hph_mode_get, wcd937x_rx_hph_mode_put), + + SOC_SINGLE_TLV("HPHL Volume", WCD937X_HPH_L_EN, 0, 20, 1, line_gain), + SOC_SINGLE_TLV("HPHR Volume", WCD937X_HPH_R_EN, 0, 20, 1, line_gain), + SOC_SINGLE_TLV("ADC1 Volume", WCD937X_ANA_TX_CH1, 0, 20, 0, analog_gain), + SOC_SINGLE_TLV("ADC2 Volume", WCD937X_ANA_TX_CH2, 0, 20, 0, analog_gain), + SOC_SINGLE_TLV("ADC3 Volume", WCD937X_ANA_TX_CH3, 0, 20, 0, analog_gain), +}; + +static const struct snd_kcontrol_new adc1_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new adc2_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new adc3_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new dmic1_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new dmic2_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new dmic3_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new dmic4_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new dmic5_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new dmic6_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new ear_rdac_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) }; +static const struct snd_kcontrol_new aux_rdac_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new hphl_rdac_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new hphr_rdac_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const char * const adc2_mux_text[] = { + "INP2", "INP3" +}; + +static const char * const rdac3_mux_text[] = { + "RX1", "RX3" +}; + +static const struct soc_enum adc2_enum = + SOC_ENUM_SINGLE(WCD937X_TX_NEW_TX_CH2_SEL, 7, + ARRAY_SIZE(adc2_mux_text), adc2_mux_text); + + +static const struct soc_enum rdac3_enum = + SOC_ENUM_SINGLE(WCD937X_DIGITAL_CDC_EAR_PATH_CTL, 0, + ARRAY_SIZE(rdac3_mux_text), rdac3_mux_text); + +static const struct snd_kcontrol_new tx_adc2_mux = + SOC_DAPM_ENUM("ADC2 MUX Mux", adc2_enum); + +static const struct snd_kcontrol_new rx_rdac3_mux = + SOC_DAPM_ENUM("RDAC3_MUX Mux", rdac3_enum); + static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = { + + /*input widgets*/ + + SND_SOC_DAPM_INPUT("AMIC1"), + SND_SOC_DAPM_INPUT("AMIC2"), + SND_SOC_DAPM_INPUT("AMIC3"), + SND_SOC_DAPM_INPUT("IN1_HPHL"), + SND_SOC_DAPM_INPUT("IN2_HPHR"), + SND_SOC_DAPM_INPUT("IN3_AUX"), + + /*tx widgets*/ + SND_SOC_DAPM_ADC_E("ADC1", NULL, SND_SOC_NOPM, 0, 0, + wcd937x_codec_enable_adc, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("ADC2", NULL, SND_SOC_NOPM, 0, 0, + wcd937x_codec_enable_adc, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER_E("ADC1 REQ", SND_SOC_NOPM, 0, 0, + NULL, 0, wcd937x_enable_req, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("ADC2 REQ", SND_SOC_NOPM, 0, 0, + NULL, 0, wcd937x_enable_req, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, + &tx_adc2_mux), + + /*tx mixers*/ + SND_SOC_DAPM_MIXER("ADC1_MIXER", SND_SOC_NOPM, 0, + 0, adc1_switch, ARRAY_SIZE(adc1_switch)), + SND_SOC_DAPM_MIXER("ADC2_MIXER", SND_SOC_NOPM, 0, + 0, adc2_switch, ARRAY_SIZE(adc2_switch)), + + /* micbias widgets*/ + SND_SOC_DAPM_MICBIAS_E("MIC BIAS1", SND_SOC_NOPM, 0, 0, + wcd937x_codec_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS2", SND_SOC_NOPM, 0, 0, + wcd937x_codec_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS3", SND_SOC_NOPM, 0, 0, + wcd937x_codec_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + /*rx widgets*/ + SND_SOC_DAPM_PGA_E("EAR PGA", WCD937X_ANA_EAR, 7, 0, NULL, 0, + wcd937x_codec_enable_ear_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("AUX PGA", WCD937X_AUX_AUXPA, 7, 0, NULL, 0, + wcd937x_codec_enable_aux_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("HPHL PGA", WCD937X_ANA_HPH, 7, 0, NULL, 0, + wcd937x_codec_enable_hphl_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("HPHR PGA", WCD937X_ANA_HPH, 6, 0, NULL, 0, + wcd937x_codec_enable_hphr_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_DAC_E("RDAC1", NULL, SND_SOC_NOPM, 0, 0, + wcd937x_codec_hphl_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RDAC2", NULL, SND_SOC_NOPM, 0, 0, + wcd937x_codec_hphr_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RDAC3", NULL, SND_SOC_NOPM, 0, 0, + wcd937x_codec_ear_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RDAC4", NULL, SND_SOC_NOPM, 0, 0, + wcd937x_codec_aux_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("RDAC3_MUX", SND_SOC_NOPM, 0, 0, &rx_rdac3_mux), + + SND_SOC_DAPM_MIXER_E("RX1", SND_SOC_NOPM, 0, 0, NULL, 0, + wcd937x_enable_rx1, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX2", SND_SOC_NOPM, 0, 0, NULL, 0, + wcd937x_enable_rx2, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX3", SND_SOC_NOPM, 0, 0, NULL, 0, + wcd937x_enable_rx3, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + /* rx mixer widgets*/ + + SND_SOC_DAPM_MIXER("EAR_RDAC", SND_SOC_NOPM, 0, 0, + ear_rdac_switch, ARRAY_SIZE(ear_rdac_switch)), + SND_SOC_DAPM_MIXER("AUX_RDAC", SND_SOC_NOPM, 0, 0, + aux_rdac_switch, ARRAY_SIZE(aux_rdac_switch)), + SND_SOC_DAPM_MIXER("HPHL_RDAC", SND_SOC_NOPM, 0, 0, + hphl_rdac_switch, ARRAY_SIZE(hphl_rdac_switch)), + SND_SOC_DAPM_MIXER("HPHR_RDAC", SND_SOC_NOPM, 0, 0, + hphr_rdac_switch, ARRAY_SIZE(hphr_rdac_switch)), + + /*output widgets tx*/ + + SND_SOC_DAPM_OUTPUT("ADC1_OUTPUT"), + SND_SOC_DAPM_OUTPUT("ADC2_OUTPUT"), + + /*output widgets rx*/ + SND_SOC_DAPM_OUTPUT("EAR"), + SND_SOC_DAPM_OUTPUT("AUX"), + SND_SOC_DAPM_OUTPUT("HPHL"), + SND_SOC_DAPM_OUTPUT("HPHR"), + +}; + +static const struct snd_soc_dapm_widget wcd9375_dapm_widgets[] = { + + /*input widgets*/ + SND_SOC_DAPM_INPUT("AMIC4"), + + /*tx widgets*/ + SND_SOC_DAPM_ADC_E("ADC3", NULL, SND_SOC_NOPM, 0, 0, + wcd937x_codec_enable_adc, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER_E("ADC3 REQ", SND_SOC_NOPM, 0, 0, + NULL, 0, wcd937x_enable_req, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0, + wcd937x_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0, + wcd937x_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0, + wcd937x_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0, + wcd937x_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0, + wcd937x_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 0, 0, + wcd937x_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /*tx mixer widgets*/ + SND_SOC_DAPM_MIXER("DMIC1_MIXER", SND_SOC_NOPM, 0, + 0, dmic1_switch, ARRAY_SIZE(dmic1_switch)), + SND_SOC_DAPM_MIXER("DMIC2_MIXER", SND_SOC_NOPM, 0, + 0, dmic2_switch, ARRAY_SIZE(dmic2_switch)), + SND_SOC_DAPM_MIXER("DMIC3_MIXER", SND_SOC_NOPM, 0, + 0, dmic3_switch, ARRAY_SIZE(dmic3_switch)), + SND_SOC_DAPM_MIXER("DMIC4_MIXER", SND_SOC_NOPM, 0, + 0, dmic4_switch, ARRAY_SIZE(dmic4_switch)), + SND_SOC_DAPM_MIXER("DMIC5_MIXER", SND_SOC_NOPM, 0, + 0, dmic5_switch, ARRAY_SIZE(dmic5_switch)), + SND_SOC_DAPM_MIXER("DMIC6_MIXER", SND_SOC_NOPM, 0, + 0, dmic6_switch, ARRAY_SIZE(dmic6_switch)), + SND_SOC_DAPM_MIXER("ADC3_MIXER", SND_SOC_NOPM, 0, + 0, adc3_switch, ARRAY_SIZE(adc3_switch)), + + /*output widgets*/ + SND_SOC_DAPM_OUTPUT("DMIC1_OUTPUT"), + SND_SOC_DAPM_OUTPUT("DMIC2_OUTPUT"), + SND_SOC_DAPM_OUTPUT("DMIC3_OUTPUT"), + SND_SOC_DAPM_OUTPUT("DMIC4_OUTPUT"), + SND_SOC_DAPM_OUTPUT("DMIC5_OUTPUT"), + SND_SOC_DAPM_OUTPUT("DMIC6_OUTPUT"), + SND_SOC_DAPM_OUTPUT("ADC3_OUTPUT"), + }; static const struct snd_soc_dapm_route wcd937x_audio_map[] = { + + {"ADC2_OUTPUT", NULL, "ADC2_MIXER"}, + {"ADC2_MIXER", "Switch", "ADC2 REQ"}, + {"ADC2 REQ", "NULL", "ADC2"}, + {"ADC2", "NULL", "ADC2 MUX"}, + {"ADC2 MUX", "INP3", "AMIC3"}, + {"ADC2 MUX", "INP2", "AMIC2"}, + + + {"ADC1_OUTPUT", NULL, "ADC1_MIXER"}, + {"ADC1_MIXER", "Switch", "ADC1 REQ"}, + {"ADC1 REQ", NULL, "ADC1"}, + {"ADC1", NULL, "AMIC1"}, + + {"RX1", NULL, "IN1_HPHL"}, + {"RDAC1", NULL, "RX1"}, + {"HPHL_RDAC", "Switch", "RDAC1"}, + {"HPHL PGA", NULL, "HPHL_RDAC"}, + {"HPHL", NULL, "HPHL PGA"}, + + {"RX2", NULL, "IN2_HPHR"}, + {"RDAC2", NULL, "RX2"}, + {"HPHR_RDAC", "Switch", "RDAC2"}, + {"HPHR PGA", NULL, "HPHR_RDAC"}, + {"HPHR", NULL, "HPHR PGA"}, + + {"RX3", NULL, "IN3_AUX"}, + {"RDAC4", NULL, "RX3"}, + {"AUX_RDAC", "Switch", "RDAC4"}, + {"AUX PGA", NULL, "AUX_RDAC"}, + {"AUX", NULL, "AUX PGA"}, + + {"RDAC3_MUX", "RX3", "RX3"}, + {"RDAC3_MUX", "RX1", "RX1"}, + {"RDAC3", NULL, "RDAC3_MUX"}, + {"EAR_RDAC", "Switch", "RDAC3"}, + {"EAR PGA", NULL, "EAR_RDAC"}, + {"EAR", NULL, "EAR PGA"}, + }; +static const struct snd_soc_dapm_route wcd9375_audio_map[] = { + + {"ADC3_OUTPUT", NULL, "ADC3_MIXER"}, + {"ADC3_MIXER", "Switch", "ADC3 REQ"}, + {"ADC3 REQ", NULL, "ADC3"}, + {"ADC3", NULL, "AMIC4"}, + + {"DMIC1_OUTPUT", NULL, "DMIC1_MIXER"}, + {"DMIC1_MIXER", "Switch", "DMIC1"}, + + {"DMIC2_OUTPUT", NULL, "DMIC2_MIXER"}, + {"DMIC2_MIXER", "Switch", "DMIC2"}, + + {"DMIC3_OUTPUT", NULL, "DMIC3_MIXER"}, + {"DMIC3_MIXER", "Switch", "DMIC3"}, + + {"DMIC4_OUTPUT", NULL, "DMIC4_MIXER"}, + {"DMIC4_MIXER", "Switch", "DMIC4"}, + + {"DMIC5_OUTPUT", NULL, "DMIC5_MIXER"}, + {"DMIC5_MIXER", "Switch", "DMIC5"}, + + {"DMIC6_OUTPUT", NULL, "DMIC6_MIXER"}, + {"DMIC6_MIXER", "Switch", "DMIC6"}, + +}; + +static int wcd937x_soc_codec_probe(struct snd_soc_codec *codec) +{ + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + int variant; + int ret = -EINVAL; + + dev_info(codec->dev, "%s()\n", __func__); + wcd937x = snd_soc_codec_get_drvdata(codec); + + if (!wcd937x) + return -EINVAL; + + wcd937x->codec = codec; + + variant = (snd_soc_read(codec, WCD937X_DIGITAL_EFUSE_REG_0) & 0x0E) >> 1; + wcd937x->variant = variant; + + wcd937x->fw_data = devm_kzalloc(codec->dev, + sizeof(*(wcd937x->fw_data)), + GFP_KERNEL); + if (!wcd937x->fw_data) { + dev_err(codec->dev, "Failed to allocate fw_data\n"); + ret = -ENOMEM; + goto err; + } + + set_bit(WCD9XXX_MBHC_CAL, wcd937x->fw_data->cal_bit); + ret = wcd_cal_create_hwdep(wcd937x->fw_data, + WCD9XXX_CODEC_HWDEP_NODE, codec); + + if (ret < 0) { + dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret); + goto err_hwdep; + } + + wcd937x_init_reg(codec); + + if (wcd937x->variant == WCD9375_VARIANT) { + ret = snd_soc_dapm_new_controls(dapm, wcd9375_dapm_widgets, + ARRAY_SIZE(wcd9375_dapm_widgets)); + if (ret < 0) { + dev_err(codec->dev, "%s: Failed to add snd_ctls\n", + __func__); + goto err_hwdep; + } + ret = snd_soc_dapm_add_routes(dapm, wcd9375_audio_map, + ARRAY_SIZE(wcd9375_audio_map)); + if (ret < 0) { + dev_err(codec->dev, "%s: Failed to add routes\n", + __func__); + goto err_hwdep; + } + ret = snd_soc_dapm_new_widgets(dapm->card); + if (ret < 0) { + dev_err(codec->dev, "%s: Failed to add widgets\n", + __func__); + goto err_hwdep; + } + } + return ret; + +err_hwdep: + wcd937x->fw_data = NULL; + +err: + return ret; +} + +static int wcd937x_soc_codec_remove(struct snd_soc_codec *codec) +{ + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + + if (!wcd937x) + return -EINVAL; + + return 0; +} + +static struct regmap *wcd937x_get_regmap(struct device *dev) +{ + struct wcd937x_priv *wcd937x = dev_get_drvdata(dev); + + return wcd937x->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_wcd937x = { .probe = wcd937x_soc_codec_probe, .remove = wcd937x_soc_codec_remove, @@ -115,9 +1208,8 @@ int wcd937x_reset(struct device *dev) __func__); return rc; } - /* 20ms sleep required after pulling the reset gpio to LOW */ - msleep(20); + usleep_range(20, 30); rc = msm_cdc_pinctrl_select_active_state(wcd937x->rst_np); if (rc) { @@ -125,7 +1217,8 @@ int wcd937x_reset(struct device *dev) __func__); return rc; } - msleep(20); + /* 20ms sleep required after pulling the reset gpio to HIGH */ + usleep_range(20, 30); return rc; } @@ -141,6 +1234,7 @@ struct wcd937x_pdata *wcd937x_populate_dt_data(struct device *dev) pdata->rst_np = of_parse_phandle(dev->of_node, "qcom,wcd937x-reset-node", 0); + if (!pdata->rst_np) { dev_err(dev, "%s: Looking up %s property in node %s failed\n", __func__, "qcom,wcd937x-reset-node", @@ -203,8 +1297,16 @@ static int wcd937x_bind(struct device *dev) goto err; } + wcd937x->regmap = devm_regmap_init_swr(wcd937x->tx_swr_dev, + &wcd937x_regmap_config); + if (!wcd937x->regmap) { + dev_err(dev, "%s: Regmap init failed\n", + __func__); + goto err; + } + ret = snd_soc_register_codec(dev, &soc_codec_dev_wcd937x, - NULL, 0); + NULL, 0); if (ret) { dev_err(dev, "%s: Codec registration failed\n", __func__); -- GitLab From e45af077d807ab3a0878ab9bd69e36c3afdb85b4 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Tue, 31 Jul 2018 12:03:27 -0700 Subject: [PATCH 0442/1645] asoc: wcd9360-dsp-cntl: initialize local char array val Due to the local char array that stores the codec dsp control command is not initialized, an invalid command could cause the stack content to be printed out in kernel dmesg. Initialize the array with memset. Change-Id: I07211c4cc06b2c2df21b674e6812c4d5efc45dc4 Signed-off-by: Xiaoyu Ye --- asoc/codecs/wcd9360/wcd9360-dsp-cntl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c b/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c index 863024a98b64..37536f86c54c 100644 --- a/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c +++ b/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c @@ -894,10 +894,12 @@ static ssize_t wcd_miscdev_write(struct file *filep, const char __user *ubuf, { struct wcd_dsp_cntl *cntl = container_of(filep->private_data, struct wcd_dsp_cntl, miscdev); - char val[WCD_MISCDEV_CMD_MAX_LEN]; + char val[WCD_MISCDEV_CMD_MAX_LEN + 1]; bool vote; int ret = 0; + memset(val, 0, WCD_MISCDEV_CMD_MAX_LEN + 1); + if (count == 0 || count > WCD_MISCDEV_CMD_MAX_LEN) { pr_err("%s: Invalid count = %zd\n", __func__, count); ret = -EINVAL; -- GitLab From 6095db3f9e688f4f30f533a26b1e3a66dc09576c Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Tue, 31 Jul 2018 11:53:36 -0700 Subject: [PATCH 0443/1645] ASoC: wcd934x-dsp-cntl: initialize local char array val Due to the local char array that stores the codec dsp control command is not initialized, an invalid command could cause the stack content to be printed out in kernel dmesg. Initialize the array with memset. Change-Id: I739eacb5058275c91bef67505531097cb364b93e Signed-off-by: Xiaoyu Ye --- asoc/codecs/wcd934x/wcd934x-dsp-cntl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c index 662f484028ee..de4f3997d476 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c @@ -1011,10 +1011,12 @@ static ssize_t wcd_miscdev_write(struct file *filep, const char __user *ubuf, { struct wcd_dsp_cntl *cntl = container_of(filep->private_data, struct wcd_dsp_cntl, miscdev); - char val[WCD_MISCDEV_CMD_MAX_LEN]; + char val[WCD_MISCDEV_CMD_MAX_LEN + 1]; bool vote; int ret = 0; + memset(val, 0, WCD_MISCDEV_CMD_MAX_LEN + 1); + if (count == 0 || count > WCD_MISCDEV_CMD_MAX_LEN) { pr_err("%s: Invalid count = %zd\n", __func__, count); ret = -EINVAL; -- GitLab From c0684fc6cd2e36bd128b64191a7518c1b5aeec0e Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 31 Jul 2018 19:26:56 +0530 Subject: [PATCH 0444/1645] ASoC: wsa881x: Fix regcache sync issue during playback When temperature on a single wsa881x device is being read, then soundwire master wakes up both wsa881x devices but regcache_sync is happening only for one wsa881x device on which the temperature is being read. This results in audio playback mute after temperature read. Fix the regcache sync during temperature read and playback usecase. Change-Id: I054f4432d7ae7bce922341ad62b20544cccd5865 Signed-off-by: Sudheer Papothi --- asoc/codecs/wsa881x.c | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index 0d1ab7b3870f..c8ae53d27b76 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -77,6 +77,7 @@ struct swr_port { enum { WSA881X_DEV_DOWN, WSA881X_DEV_UP, + WSA881X_DEV_READY, }; /* @@ -100,6 +101,7 @@ struct wsa881x_priv { int version; struct mutex bg_lock; struct mutex res_lock; + struct mutex temp_lock; struct snd_info_entry *entry; struct snd_info_entry *version_entry; int state; @@ -492,6 +494,17 @@ static const struct file_operations codec_debug_ops = { .read = codec_debug_read, }; +static void wsa881x_regcache_sync(struct wsa881x_priv *wsa881x) +{ + mutex_lock(&wsa881x->res_lock); + if (wsa881x->state != WSA881X_DEV_READY) { + regcache_mark_dirty(wsa881x->regmap); + regcache_sync(wsa881x->regmap); + wsa881x->state = WSA881X_DEV_READY; + } + mutex_unlock(&wsa881x->res_lock); +} + static const struct reg_sequence wsa881x_pre_pmu_pa[] = { {WSA881X_SPKR_DRV_GAIN, 0x41, 0}, {WSA881X_SPKR_MISC_CTL1, 0x01, 0}, @@ -870,7 +883,9 @@ static int wsa881x_rdac_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + mutex_lock(&wsa881x->temp_lock); wsa881x_resource_acquire(codec, ENABLE); + mutex_unlock(&wsa881x->temp_lock); wsa881x_boost_ctrl(codec, ENABLE); break; case SND_SOC_DAPM_POST_PMD: @@ -878,7 +893,9 @@ static int wsa881x_rdac_event(struct snd_soc_dapm_widget *w, wsa881x->swr_slave->dev_num, false); wsa881x_boost_ctrl(codec, DISABLE); + mutex_lock(&wsa881x->temp_lock); wsa881x_resource_acquire(codec, DISABLE); + mutex_unlock(&wsa881x->temp_lock); break; } return 0; @@ -1126,13 +1143,8 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec, return -EINVAL; } } - mutex_lock(&wsa881x->res_lock); - if (!wsa881x->clk_cnt) { - regcache_mark_dirty(wsa881x->regmap); - regcache_sync(wsa881x->regmap); - } - mutex_unlock(&wsa881x->res_lock); - + wsa881x_regcache_sync(wsa881x); + mutex_lock(&wsa881x->temp_lock); wsa881x_resource_acquire(codec, ENABLE); snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x00); @@ -1145,6 +1157,7 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec, wsa_temp_reg->d2_lsb = snd_soc_read(codec, WSA881X_OTP_REG_4); wsa881x_resource_acquire(codec, DISABLE); + mutex_unlock(&wsa881x->temp_lock); return 0; } @@ -1160,7 +1173,6 @@ static int wsa881x_probe(struct snd_soc_codec *codec) dev = wsa881x->swr_slave; wsa881x->codec = codec; mutex_init(&wsa881x->bg_lock); - mutex_init(&wsa881x->res_lock); wsa881x_init(codec); snprintf(wsa881x->tz_pdata.name, sizeof(wsa881x->tz_pdata.name), "%s.%x", "wsatz", (u8)dev->addr); @@ -1182,7 +1194,6 @@ static int wsa881x_remove(struct snd_soc_codec *codec) if (wsa881x->tz_pdata.tz_dev) wsa881x_deinit_thermal(wsa881x->tz_pdata.tz_dev); mutex_destroy(&wsa881x->bg_lock); - mutex_destroy(&wsa881x->res_lock); return 0; } @@ -1365,6 +1376,8 @@ static int wsa881x_swr_probe(struct swr_device *pdev) __func__); goto dev_err; } + mutex_init(&wsa881x->res_lock); + mutex_init(&wsa881x->temp_lock); return 0; @@ -1387,6 +1400,8 @@ static int wsa881x_swr_remove(struct swr_device *pdev) } debugfs_remove_recursive(debugfs_wsa881x_dent); debugfs_wsa881x_dent = NULL; + mutex_destroy(&wsa881x->res_lock); + mutex_destroy(&wsa881x->temp_lock); snd_soc_unregister_codec(&pdev->dev); if (wsa881x->pd_gpio) gpio_free(wsa881x->pd_gpio); @@ -1445,6 +1460,11 @@ static int wsa881x_swr_reset(struct swr_device *pdev) dev_err(&pdev->dev, "%s: wsa881x is NULL\n", __func__); return -EINVAL; } + if (wsa881x->state == WSA881X_DEV_READY) { + dev_dbg(&pdev->dev, "%s: device already active\n", __func__); + return 0; + } + wsa881x->bg_cnt = 0; wsa881x->clk_cnt = 0; while (swr_get_logical_dev_num(pdev, pdev->addr, &devnum) && retry--) { @@ -1452,8 +1472,8 @@ static int wsa881x_swr_reset(struct swr_device *pdev) usleep_range(1000, 1100); } pdev->dev_num = devnum; - regcache_mark_dirty(wsa881x->regmap); - regcache_sync(wsa881x->regmap); + wsa881x_regcache_sync(wsa881x); + return 0; } -- GitLab From 3fda075378da508468d330057ba5d65646227fc9 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 31 Jul 2018 19:27:44 +0530 Subject: [PATCH 0445/1645] soc: swr-wcd-ctrl: Fix wsa mute issue for stereo playback When temperature on a single wsa881x device is being read, then soundwire master wakes up both wsa881x devices but regcache_sync is happening only for one wsa881x device on which the temperature is being read. This results in audio playback mute after temperature read. Fix the regcache sync during temperature read and playback usecase. Change-Id: I856b96517c629ac685bbc25caabee841037106c8 Signed-off-by: Laxminath Kasam --- soc/swr-wcd-ctrl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c index 729eb3850b2d..ecca5f699fde 100644 --- a/soc/swr-wcd-ctrl.c +++ b/soc/swr-wcd-ctrl.c @@ -1790,6 +1790,8 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) (swrm->state == SWR_MSTR_UP)) { dev_dbg(swrm->dev, "%s: SWR master is already UP: %d\n", __func__, swrm->state); + list_for_each_entry(swr_dev, &mstr->devices, dev_list) + swr_reset_device(swr_dev); } else { pm_runtime_mark_last_busy(&pdev->dev); mutex_unlock(&swrm->reslock); -- GitLab From 846ad08f106a2a61ff03fade9c5d806716c06f10 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 31 Jul 2018 19:30:32 +0530 Subject: [PATCH 0446/1645] soc: soundwire: Fix wsa mute issue for stereo playback When stereo playback start and temperature read initiated at same time, one of speaker PA bits are not set in particular race scenario. Handle the broadcast check in soundwire framework to ensure broadcast is disabled only when respective gr_sid slave calls swr_remove_from_group. Change-Id: I6f82a8c3c0f39dc20c1def09c1728ce4c26c2f5d Signed-off-by: Laxminath Kasam --- soc/soundwire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/soundwire.c b/soc/soundwire.c index f05a5f9b1fb5..79bf75f785d5 100644 --- a/soc/soundwire.c +++ b/soc/soundwire.c @@ -245,7 +245,7 @@ int swr_remove_from_group(struct swr_device *dev, u8 dev_num) if (!dev->group_id) return 0; - if (master->gr_sid == dev_num) + if (master->gr_sid != dev_num) return 0; if (master->remove_from_group && master->remove_from_group(master)) -- GitLab From 92fad90ae55abe93a7d8abb7eb11e2f48068fc98 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 30 Jul 2018 20:17:41 +0530 Subject: [PATCH 0447/1645] ASoC: Add MBHC and IRQ driver for WCD937X Add MBHC and IRQ driver for tanggu codec. MBHC and IRQ for tanggu are initialized from core driver. IRQ driver uses REGMAP-IRQ framework. CRs-Fixed: 2281591 Change-Id: I06adb3081dd17f896b3e6a3ce0c4c46b5ef1cbea Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/Kbuild | 1 + asoc/codecs/wcd937x/internal.h | 55 +- asoc/codecs/wcd937x/wcd937x-mbhc.c | 1011 ++++++++++++++++++++++++++++ asoc/codecs/wcd937x/wcd937x-mbhc.h | 70 ++ asoc/codecs/wcd937x/wcd937x.c | 248 ++++++- 5 files changed, 1379 insertions(+), 6 deletions(-) create mode 100644 asoc/codecs/wcd937x/wcd937x-mbhc.c create mode 100644 asoc/codecs/wcd937x/wcd937x-mbhc.h diff --git a/asoc/codecs/wcd937x/Kbuild b/asoc/codecs/wcd937x/Kbuild index 20c4d4682baa..c3d8e38c3844 100644 --- a/asoc/codecs/wcd937x/Kbuild +++ b/asoc/codecs/wcd937x/Kbuild @@ -54,6 +54,7 @@ ifdef CONFIG_SND_SOC_WCD937X WCD937X_OBJS += wcd937x.o WCD937X_OBJS += wcd937x-regmap.o WCD937X_OBJS += wcd937x-tables.o + WCD937X_OBJS += wcd937x-mbhc.o endif ifdef CONFIG_SND_SOC_WCD937X_SLAVE diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index dcb7fd8dd78e..e8ac70d9a98c 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -14,9 +14,14 @@ #define _WCD937X_INTERNAL_H #include "../wcd-mbhc-v2.h" +#include "asoc/wcd-irq.h" +#include "wcd937x-mbhc.h" #define WCD937X_MAX_MICBIAS 3 +/* Convert from vout ctl to micbias voltage in mV */ +#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50) + extern struct regmap_config wcd937x_regmap_config; struct wcd937x_priv { @@ -36,23 +41,69 @@ struct wcd937x_priv { struct fw_info *fw_data; struct device_node *wcd_rst_np; + struct mutex micb_lock; s32 dmic_0_1_clk_cnt; s32 dmic_2_3_clk_cnt; s32 dmic_4_5_clk_cnt; /* mbhc module */ - struct wcd_mbhc mbhc; + struct wcd937x_mbhc *mbhc; struct blocking_notifier_head notifier; - struct mutex micb_lock; u32 hph_mode; + struct irq_domain *virq; + struct wcd_irq_info *irq_info; u32 rx_clk_cnt; + int num_irq_regs; +}; + +struct wcd937x_micbias_setting { + u8 ldoh_v; + u32 cfilt1_mv; + u32 micb2_mv; + u8 bias1_cfilt_sel; }; struct wcd937x_pdata { struct device_node *rst_np; struct device_node *rx_slave; struct device_node *tx_slave; + struct wcd937x_micbias_setting micbias; +}; + +enum { + /* INTR_CTRL_INT_MASK_0 */ + WCD937X_IRQ_MBHC_BUTTON_RELEASE_DET = 0, + WCD937X_IRQ_MBHC_BUTTON_PRESS_DET, + WCD937X_IRQ_MBHC_ELECT_INS_REM_DET, + WCD937X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, + WCD937X_IRQ_MBHC_SW_DET, + WCD937X_IRQ_HPHR_OCP_INT, + WCD937X_IRQ_HPHR_CNP_INT, + WCD937X_IRQ_HPHL_OCP_INT, + + /* INTR_CTRL_INT_MASK_1 */ + WCD937X_IRQ_HPHL_CNP_INT, + WCD937X_IRQ_EAR_CNP_INT, + WCD937X_IRQ_EAR_SCD_INT, + WCD937X_IRQ_AUX_CNP_INT, + WCD937X_IRQ_AUX_SCD_INT, + WCD937X_IRQ_HPHL_PDM_WD_INT, + WCD937X_IRQ_HPHR_PDM_WD_INT, + WCD937X_IRQ_AUX_PDM_WD_INT, + + /* INTR_CTRL_INT_MASK_2 */ + WCD937X_IRQ_LDORT_SCD_INT, + WCD937X_IRQ_MBHC_MOISTURE_INT, + WCD937X_IRQ_HPHL_SURGE_DET_INT, + WCD937X_IRQ_HPHR_SURGE_DET_INT, + WCD937X_NUM_IRQS, }; +extern struct wcd937x_mbhc *wcd937x_soc_get_mbhc(struct snd_soc_codec *codec); +extern int wcd937x_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, + int volt, int micb_num); +extern int wcd937x_get_micb_vout_ctl_val(u32 micb_mv); +extern int wcd937x_micbias_control(struct snd_soc_codec *codec, int micb_num, + int req, bool is_dapm); #endif diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c new file mode 100644 index 000000000000..d1a36ba72de5 --- /dev/null +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -0,0 +1,1011 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcd937x-registers.h" +#include "../wcdcal-hwdep.h" +#include "../wcd-mbhc-v2-api.h" +#include "internal.h" + +#define WCD937X_ZDET_SUPPORTED true +/* Z value defined in milliohm */ +#define WCD937X_ZDET_VAL_32 32000 +#define WCD937X_ZDET_VAL_400 400000 +#define WCD937X_ZDET_VAL_1200 1200000 +#define WCD937X_ZDET_VAL_100K 100000000 +/* Z floating defined in ohms */ +#define WCD937X_ZDET_FLOATING_IMPEDANCE 0x0FFFFFFE + +#define WCD937X_ZDET_NUM_MEASUREMENTS 900 +#define WCD937X_MBHC_GET_C1(c) ((c & 0xC000) >> 14) +#define WCD937X_MBHC_GET_X1(x) (x & 0x3FFF) +/* Z value compared in milliOhm */ +#define WCD937X_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000)) +#define WCD937X_MBHC_ZDET_CONST (86 * 16384) +#define WCD937X_MBHC_MOISTURE_RREF R_24_KOHM + +static struct wcd_mbhc_register + wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = { + WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN", + WCD937X_ANA_MBHC_MECH, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_DET_EN", + WCD937X_ANA_MBHC_MECH, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MECH_DETECTION_TYPE", + WCD937X_ANA_MBHC_MECH, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_CLAMP_CTL", + WCD937X_MBHC_NEW_PLUG_DETECT_CTL, 0x30, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_DETECTION_TYPE", + WCD937X_ANA_MBHC_ELECT, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_CTRL", + WCD937X_MBHC_NEW_INT_MECH_DET_CURRENT, 0x1F, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL", + WCD937X_ANA_MBHC_MECH, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PLUG_TYPE", + WCD937X_ANA_MBHC_MECH, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_PLUG_TYPE", + WCD937X_ANA_MBHC_MECH, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SW_HPH_LP_100K_TO_GND", + WCD937X_ANA_MBHC_MECH, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_SCHMT_ISRC", + WCD937X_ANA_MBHC_ELECT, 0x06, 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_EN", + WCD937X_ANA_MBHC_ELECT, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_INSREM_DBNC", + WCD937X_MBHC_NEW_PLUG_DETECT_CTL, 0x0F, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_DBNC", + WCD937X_MBHC_NEW_CTL_1, 0x03, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_VREF", + WCD937X_MBHC_NEW_CTL_2, 0x03, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT", + WCD937X_ANA_MBHC_RESULT_3, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT", + WCD937X_ANA_MBHC_RESULT_3, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT", + WCD937X_ANA_MBHC_RESULT_3, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_SCHMT_RESULT", + WCD937X_ANA_MBHC_RESULT_3, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_OCP_FSM_EN", + WCD937X_HPH_OCP_CTL, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_RESULT", + WCD937X_ANA_MBHC_RESULT_3, 0x07, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_ISRC_CTL", + WCD937X_ANA_MBHC_ELECT, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT", + WCD937X_ANA_MBHC_RESULT_3, 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL", + WCD937X_ANA_MICB2, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME", + WCD937X_HPH_CNP_WG_TIME, 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN", + WCD937X_ANA_HPH, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PA_EN", + WCD937X_ANA_HPH, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_PA_EN", + WCD937X_ANA_HPH, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE", + WCD937X_ANA_MBHC_RESULT_3, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL", + 0, 0, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN", + WCD937X_MBHC_CTL_BCS, 0x02, 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_STATUS", + WCD937X_MBHC_NEW_FSM_STATUS, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL", + WCD937X_MBHC_NEW_CTL_2, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MOISTURE_STATUS", + WCD937X_MBHC_NEW_FSM_STATUS, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_GND", + WCD937X_HPH_PA_CTL2, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_GND", + WCD937X_HPH_PA_CTL2, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_DET_EN", + WCD937X_HPH_L_TEST, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_DET_EN", + WCD937X_HPH_R_TEST, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_STATUS", + WCD937X_DIGITAL_INTR_STATUS_0, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_STATUS", + WCD937X_DIGITAL_INTR_STATUS_0, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_EN", + WCD937X_MBHC_NEW_CTL_1, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_COMPLETE", WCD937X_MBHC_NEW_FSM_STATUS, + 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_TIMEOUT", WCD937X_MBHC_NEW_FSM_STATUS, + 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_RESULT", WCD937X_MBHC_NEW_ADC_RESULT, + 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB2_VOUT", WCD937X_ANA_MICB1, 0x3F, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_MODE", + WCD937X_MBHC_NEW_CTL_1, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_DETECTION_DONE", + WCD937X_MBHC_NEW_CTL_1, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_ISRC_EN", + WCD937X_ANA_MBHC_ZDET, 0x02, 1, 0), +}; + +static const struct wcd_mbhc_intr intr_ids = { + .mbhc_sw_intr = WCD937X_IRQ_MBHC_SW_DET, + .mbhc_btn_press_intr = WCD937X_IRQ_MBHC_BUTTON_PRESS_DET, + .mbhc_btn_release_intr = WCD937X_IRQ_MBHC_BUTTON_RELEASE_DET, + .mbhc_hs_ins_intr = WCD937X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, + .mbhc_hs_rem_intr = WCD937X_IRQ_MBHC_ELECT_INS_REM_DET, + .hph_left_ocp = WCD937X_IRQ_HPHL_OCP_INT, + .hph_right_ocp = WCD937X_IRQ_HPHR_OCP_INT, +}; + +struct wcd937x_mbhc_zdet_param { + u16 ldo_ctl; + u16 noff; + u16 nshift; + u16 btn5; + u16 btn6; + u16 btn7; +}; + +static int wcd937x_mbhc_request_irq(struct snd_soc_codec *codec, + int irq, irq_handler_t handler, + const char *name, void *data) +{ + struct wcd937x_priv *wcd937x = dev_get_drvdata(codec->dev); + + return wcd_request_irq(wcd937x->irq_info, irq, name, handler, data); +} + +static void wcd937x_mbhc_irq_control(struct snd_soc_codec *codec, + int irq, bool enable) +{ + struct wcd937x_priv *wcd937x = dev_get_drvdata(codec->dev); + + if (enable) + wcd_enable_irq(wcd937x->irq_info, irq); + else + wcd_disable_irq(wcd937x->irq_info, irq); +} + +static int wcd937x_mbhc_free_irq(struct snd_soc_codec *codec, + int irq, void *data) +{ + struct wcd937x_priv *wcd937x = dev_get_drvdata(codec->dev); + + wcd_free_irq(wcd937x->irq_info, irq, data); + + return 0; +} + +static void wcd937x_mbhc_clk_setup(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) + snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_1, + 0x80, 0x80); + else + snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_1, + 0x80, 0x00); +} + +static int wcd937x_mbhc_btn_to_num(struct snd_soc_codec *codec) +{ + return snd_soc_read(codec, WCD937X_ANA_MBHC_RESULT_3) & 0x7; +} + +static void wcd937x_mbhc_mbhc_bias_control(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) + snd_soc_update_bits(codec, WCD937X_ANA_MBHC_ELECT, + 0x01, 0x01); + else + snd_soc_update_bits(codec, WCD937X_ANA_MBHC_ELECT, + 0x01, 0x00); +} + +static void wcd937x_mbhc_program_btn_thr(struct snd_soc_codec *codec, + s16 *btn_low, s16 *btn_high, + int num_btn, bool is_micbias) +{ + int i; + int vth; + + if (num_btn > WCD_MBHC_DEF_BUTTONS) { + dev_err(codec->dev, "%s: invalid number of buttons: %d\n", + __func__, num_btn); + return; + } + + for (i = 0; i < num_btn; i++) { + vth = ((btn_high[i] * 2) / 25) & 0x3F; + snd_soc_update_bits(codec, WCD937X_ANA_MBHC_BTN0 + i, + 0xFC, vth << 2); + dev_dbg(codec->dev, "%s: btn_high[%d]: %d, vth: %d\n", + __func__, i, btn_high[i], vth); + } +} + +static bool wcd937x_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock) +{ + return true; +} + +static int wcd937x_mbhc_register_notifier(struct wcd_mbhc *mbhc, + struct notifier_block *nblock, + bool enable) +{ + struct wcd937x_mbhc *wcd937x_mbhc; + + wcd937x_mbhc = container_of(mbhc, struct wcd937x_mbhc, wcd_mbhc); + + if (enable) + return blocking_notifier_chain_register(&wcd937x_mbhc->notifier, + nblock); + else + return blocking_notifier_chain_unregister( + &wcd937x_mbhc->notifier, nblock); +} + +static bool wcd937x_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) +{ + u8 val = 0; + + if (micb_num == MIC_BIAS_2) { + val = ((snd_soc_read(mbhc->codec, WCD937X_ANA_MICB2) & 0xC0) + >> 6); + if (val == 0x01) + return true; + } + return false; +} + +static bool wcd937x_mbhc_hph_pa_on_status(struct snd_soc_codec *codec) +{ + return (snd_soc_read(codec, WCD937X_ANA_HPH) & 0xC0) ? true : false; +} + +static void wcd937x_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec, + int pull_up_cur) +{ + /* Default pull up current to 2uA */ + if (pull_up_cur > HS_PULLUP_I_OFF || pull_up_cur < HS_PULLUP_I_3P0_UA || + pull_up_cur == HS_PULLUP_I_DEFAULT) + pull_up_cur = HS_PULLUP_I_2P0_UA; + + dev_dbg(codec->dev, "%s: HS pull up current:%d\n", + __func__, pull_up_cur); + + snd_soc_update_bits(codec, WCD937X_MBHC_NEW_INT_MECH_DET_CURRENT, + 0x1F, pull_up_cur); +} + +static int wcd937x_mbhc_request_micbias(struct snd_soc_codec *codec, + int micb_num, int req) +{ + int ret = 0; + + ret = wcd937x_micbias_control(codec, micb_num, req, false); + + return ret; +} + +static void wcd937x_mbhc_micb_ramp_control(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, WCD937X_ANA_MICB2_RAMP, + 0x1C, 0x0C); + snd_soc_update_bits(codec, WCD937X_ANA_MICB2_RAMP, + 0x80, 0x80); + } else { + snd_soc_update_bits(codec, WCD937X_ANA_MICB2_RAMP, + 0x80, 0x00); + snd_soc_update_bits(codec, WCD937X_ANA_MICB2_RAMP, + 0x1C, 0x00); + } +} + +static struct firmware_cal *wcd937x_get_hwdep_fw_cal(struct wcd_mbhc *mbhc, + enum wcd_cal_type type) +{ + struct wcd937x_mbhc *wcd937x_mbhc; + struct firmware_cal *hwdep_cal; + struct snd_soc_codec *codec = mbhc->codec; + + wcd937x_mbhc = container_of(mbhc, struct wcd937x_mbhc, wcd_mbhc); + + if (!codec) { + pr_err("%s: NULL codec pointer\n", __func__); + return NULL; + } + hwdep_cal = wcdcal_get_fw_cal(wcd937x_mbhc->fw_data, type); + if (!hwdep_cal) + dev_err(codec->dev, "%s: cal not sent by %d\n", + __func__, type); + + return hwdep_cal; +} + +static int wcd937x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec, + int micb_num, bool req_en) +{ + struct wcd937x_pdata *pdata = dev_get_platdata(codec->dev); + int rc, micb_mv; + + if (micb_num != MIC_BIAS_2) + return -EINVAL; + /* + * If device tree micbias level is already above the minimum + * voltage needed to detect threshold microphone, then do + * not change the micbias, just return. + */ + if (pdata->micbias.micb2_mv >= WCD_MBHC_THR_HS_MICB_MV) + return 0; + + micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb2_mv; + + rc = wcd937x_mbhc_micb_adjust_voltage(codec, micb_mv, MIC_BIAS_2); + + return rc; +} + +static inline void wcd937x_mbhc_get_result_params(struct wcd937x_priv *wcd937x, + s16 *d1_a, u16 noff, + int32_t *zdet) +{ + int i; + int val, val1; + s16 c1; + s32 x1, d1; + int32_t denom; + int minCode_param[] = { + 3277, 1639, 820, 410, 205, 103, 52, 26 + }; + + regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MBHC_ZDET, 0x20, 0x20); + for (i = 0; i < WCD937X_ZDET_NUM_MEASUREMENTS; i++) { + regmap_read(wcd937x->regmap, WCD937X_ANA_MBHC_RESULT_2, &val); + if (val & 0x80) + break; + } + val = val << 0x8; + regmap_read(wcd937x->regmap, WCD937X_ANA_MBHC_RESULT_1, &val1); + val |= val1; + regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MBHC_ZDET, 0x20, 0x00); + x1 = WCD937X_MBHC_GET_X1(val); + c1 = WCD937X_MBHC_GET_C1(val); + /* If ramp is not complete, give additional 5ms */ + if ((c1 < 2) && x1) + usleep_range(5000, 5050); + + if (!c1 || !x1) { + dev_dbg(wcd937x->dev, + "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n", + __func__, c1, x1); + goto ramp_down; + } + d1 = d1_a[c1]; + denom = (x1 * d1) - (1 << (14 - noff)); + if (denom > 0) + *zdet = (WCD937X_MBHC_ZDET_CONST * 1000) / denom; + else if (x1 < minCode_param[noff]) + *zdet = WCD937X_ZDET_FLOATING_IMPEDANCE; + + dev_dbg(wcd937x->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n", + __func__, d1, c1, x1, *zdet); +ramp_down: + i = 0; + while (x1) { + regmap_bulk_read(wcd937x->regmap, + WCD937X_ANA_MBHC_RESULT_1, (u8 *)&val, 2); + x1 = WCD937X_MBHC_GET_X1(val); + i++; + if (i == WCD937X_ZDET_NUM_MEASUREMENTS) + break; + } +} + +static void wcd937x_mbhc_zdet_ramp(struct snd_soc_codec *codec, + struct wcd937x_mbhc_zdet_param *zdet_param, + int32_t *zl, int32_t *zr, s16 *d1_a) +{ + struct wcd937x_priv *wcd937x = dev_get_drvdata(codec->dev); + int32_t zdet = 0; + + snd_soc_update_bits(codec, WCD937X_MBHC_NEW_ZDET_ANA_CTL, 0x70, + zdet_param->ldo_ctl << 4); + snd_soc_update_bits(codec, WCD937X_ANA_MBHC_BTN5, 0xFC, + zdet_param->btn5); + snd_soc_update_bits(codec, WCD937X_ANA_MBHC_BTN6, 0xFC, + zdet_param->btn6); + snd_soc_update_bits(codec, WCD937X_ANA_MBHC_BTN7, 0xFC, + zdet_param->btn7); + snd_soc_update_bits(codec, WCD937X_MBHC_NEW_ZDET_ANA_CTL, 0x0F, + zdet_param->noff); + snd_soc_update_bits(codec, WCD937X_MBHC_NEW_ZDET_RAMP_CTL, 0x0F, + zdet_param->nshift); + + if (!zl) + goto z_right; + /* Start impedance measurement for HPH_L */ + regmap_update_bits(wcd937x->regmap, + WCD937X_ANA_MBHC_ZDET, 0x80, 0x80); + dev_dbg(wcd937x->dev, "%s: ramp for HPH_L, noff = %d\n", + __func__, zdet_param->noff); + wcd937x_mbhc_get_result_params(wcd937x, d1_a, zdet_param->noff, &zdet); + regmap_update_bits(wcd937x->regmap, + WCD937X_ANA_MBHC_ZDET, 0x80, 0x00); + + *zl = zdet; + +z_right: + if (!zr) + return; + /* Start impedance measurement for HPH_R */ + regmap_update_bits(wcd937x->regmap, + WCD937X_ANA_MBHC_ZDET, 0x40, 0x40); + dev_dbg(wcd937x->dev, "%s: ramp for HPH_R, noff = %d\n", + __func__, zdet_param->noff); + wcd937x_mbhc_get_result_params(wcd937x, d1_a, zdet_param->noff, &zdet); + regmap_update_bits(wcd937x->regmap, + WCD937X_ANA_MBHC_ZDET, 0x40, 0x00); + + *zr = zdet; +} + +static inline void wcd937x_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec, + int32_t *z_val, int flag_l_r) +{ + s16 q1; + int q1_cal; + + if (*z_val < (WCD937X_ZDET_VAL_400/1000)) + q1 = snd_soc_read(codec, + WCD937X_DIGITAL_EFUSE_REG_23 + (2 * flag_l_r)); + else + q1 = snd_soc_read(codec, + WCD937X_DIGITAL_EFUSE_REG_24 + (2 * flag_l_r)); + if (q1 & 0x80) + q1_cal = (10000 - ((q1 & 0x7F) * 25)); + else + q1_cal = (10000 + (q1 * 25)); + if (q1_cal > 0) + *z_val = ((*z_val) * 10000) / q1_cal; +} + +static void wcd937x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, + uint32_t *zr) +{ + struct snd_soc_codec *codec = mbhc->codec; + struct wcd937x_priv *wcd937x = dev_get_drvdata(codec->dev); + s16 reg0, reg1, reg2, reg3, reg4; + int32_t z1L, z1R, z1Ls; + int zMono, z_diff1, z_diff2; + bool is_fsm_disable = false; + struct wcd937x_mbhc_zdet_param zdet_param[] = { + {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */ + {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */ + {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */ + {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */ + }; + struct wcd937x_mbhc_zdet_param *zdet_param_ptr = NULL; + s16 d1_a[][4] = { + {0, 30, 90, 30}, + {0, 30, 30, 5}, + {0, 30, 30, 5}, + {0, 30, 30, 5}, + }; + s16 *d1 = NULL; + + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + + reg0 = snd_soc_read(codec, WCD937X_ANA_MBHC_BTN5); + reg1 = snd_soc_read(codec, WCD937X_ANA_MBHC_BTN6); + reg2 = snd_soc_read(codec, WCD937X_ANA_MBHC_BTN7); + reg3 = snd_soc_read(codec, WCD937X_MBHC_CTL_CLK); + reg4 = snd_soc_read(codec, WCD937X_MBHC_NEW_ZDET_ANA_CTL); + + if (snd_soc_read(codec, WCD937X_ANA_MBHC_ELECT) & 0x80) { + is_fsm_disable = true; + regmap_update_bits(wcd937x->regmap, + WCD937X_ANA_MBHC_ELECT, 0x80, 0x00); + } + + /* For NO-jack, disable L_DET_EN before Z-det measurements */ + if (mbhc->hphl_swh) + regmap_update_bits(wcd937x->regmap, + WCD937X_ANA_MBHC_MECH, 0x80, 0x00); + + /* Turn off 100k pull down on HPHL */ + regmap_update_bits(wcd937x->regmap, + WCD937X_ANA_MBHC_MECH, 0x01, 0x00); + + /* First get impedance on Left */ + d1 = d1_a[1]; + zdet_param_ptr = &zdet_param[1]; + wcd937x_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + + if (!WCD937X_MBHC_IS_SECOND_RAMP_REQUIRED(z1L)) + goto left_ch_impedance; + + /* Second ramp for left ch */ + if (z1L < WCD937X_ZDET_VAL_32) { + zdet_param_ptr = &zdet_param[0]; + d1 = d1_a[0]; + } else if ((z1L > WCD937X_ZDET_VAL_400) && + (z1L <= WCD937X_ZDET_VAL_1200)) { + zdet_param_ptr = &zdet_param[2]; + d1 = d1_a[2]; + } else if (z1L > WCD937X_ZDET_VAL_1200) { + zdet_param_ptr = &zdet_param[3]; + d1 = d1_a[3]; + } + wcd937x_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + +left_ch_impedance: + if ((z1L == WCD937X_ZDET_FLOATING_IMPEDANCE) || + (z1L > WCD937X_ZDET_VAL_100K)) { + *zl = WCD937X_ZDET_FLOATING_IMPEDANCE; + zdet_param_ptr = &zdet_param[1]; + d1 = d1_a[1]; + } else { + *zl = z1L/1000; + wcd937x_wcd_mbhc_qfuse_cal(codec, zl, 0); + } + dev_dbg(codec->dev, "%s: impedance on HPH_L = %d(ohms)\n", + __func__, *zl); + + /* Start of right impedance ramp and calculation */ + wcd937x_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + if (WCD937X_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) { + if (((z1R > WCD937X_ZDET_VAL_1200) && + (zdet_param_ptr->noff == 0x6)) || + ((*zl) != WCD937X_ZDET_FLOATING_IMPEDANCE)) + goto right_ch_impedance; + /* Second ramp for right ch */ + if (z1R < WCD937X_ZDET_VAL_32) { + zdet_param_ptr = &zdet_param[0]; + d1 = d1_a[0]; + } else if ((z1R > WCD937X_ZDET_VAL_400) && + (z1R <= WCD937X_ZDET_VAL_1200)) { + zdet_param_ptr = &zdet_param[2]; + d1 = d1_a[2]; + } else if (z1R > WCD937X_ZDET_VAL_1200) { + zdet_param_ptr = &zdet_param[3]; + d1 = d1_a[3]; + } + wcd937x_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + } +right_ch_impedance: + if ((z1R == WCD937X_ZDET_FLOATING_IMPEDANCE) || + (z1R > WCD937X_ZDET_VAL_100K)) { + *zr = WCD937X_ZDET_FLOATING_IMPEDANCE; + } else { + *zr = z1R/1000; + wcd937x_wcd_mbhc_qfuse_cal(codec, zr, 1); + } + dev_dbg(codec->dev, "%s: impedance on HPH_R = %d(ohms)\n", + __func__, *zr); + + /* Mono/stereo detection */ + if ((*zl == WCD937X_ZDET_FLOATING_IMPEDANCE) && + (*zr == WCD937X_ZDET_FLOATING_IMPEDANCE)) { + dev_dbg(codec->dev, + "%s: plug type is invalid or extension cable\n", + __func__); + goto zdet_complete; + } + if ((*zl == WCD937X_ZDET_FLOATING_IMPEDANCE) || + (*zr == WCD937X_ZDET_FLOATING_IMPEDANCE) || + ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) || + ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) { + dev_dbg(codec->dev, + "%s: Mono plug type with one ch floating or shorted to GND\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_MONO; + goto zdet_complete; + } + snd_soc_update_bits(codec, WCD937X_HPH_R_ATEST, 0x02, 0x02); + snd_soc_update_bits(codec, WCD937X_HPH_PA_CTL2, 0x40, 0x01); + if (*zl < (WCD937X_ZDET_VAL_32/1000)) + wcd937x_mbhc_zdet_ramp(codec, &zdet_param[0], &z1Ls, NULL, d1); + else + wcd937x_mbhc_zdet_ramp(codec, &zdet_param[1], &z1Ls, NULL, d1); + snd_soc_update_bits(codec, WCD937X_HPH_PA_CTL2, 0x40, 0x00); + snd_soc_update_bits(codec, WCD937X_HPH_R_ATEST, 0x02, 0x00); + z1Ls /= 1000; + wcd937x_wcd_mbhc_qfuse_cal(codec, &z1Ls, 0); + /* Parallel of left Z and 9 ohm pull down resistor */ + zMono = ((*zl) * 9) / ((*zl) + 9); + z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls); + z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl)); + if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) { + dev_dbg(codec->dev, "%s: stereo plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_STEREO; + } else { + dev_dbg(codec->dev, "%s: MONO plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_MONO; + } + +zdet_complete: + snd_soc_write(codec, WCD937X_ANA_MBHC_BTN5, reg0); + snd_soc_write(codec, WCD937X_ANA_MBHC_BTN6, reg1); + snd_soc_write(codec, WCD937X_ANA_MBHC_BTN7, reg2); + /* Turn on 100k pull down on HPHL */ + regmap_update_bits(wcd937x->regmap, + WCD937X_ANA_MBHC_MECH, 0x01, 0x01); + + /* For NO-jack, re-enable L_DET_EN after Z-det measurements */ + if (mbhc->hphl_swh) + regmap_update_bits(wcd937x->regmap, + WCD937X_ANA_MBHC_MECH, 0x80, 0x80); + + snd_soc_write(codec, WCD937X_MBHC_NEW_ZDET_ANA_CTL, reg4); + snd_soc_write(codec, WCD937X_MBHC_CTL_CLK, reg3); + if (is_fsm_disable) + regmap_update_bits(wcd937x->regmap, + WCD937X_ANA_MBHC_ELECT, 0x80, 0x80); +} + +static void wcd937x_mbhc_gnd_det_ctrl(struct snd_soc_codec *codec, bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, WCD937X_ANA_MBHC_MECH, + 0x02, 0x02); + snd_soc_update_bits(codec, WCD937X_ANA_MBHC_MECH, + 0x40, 0x40); + } else { + snd_soc_update_bits(codec, WCD937X_ANA_MBHC_MECH, + 0x40, 0x00); + snd_soc_update_bits(codec, WCD937X_ANA_MBHC_MECH, + 0x02, 0x00); + } +} + +static void wcd937x_mbhc_hph_pull_down_ctrl(struct snd_soc_codec *codec, + bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, WCD937X_HPH_PA_CTL2, + 0x40, 0x40); + snd_soc_update_bits(codec, WCD937X_HPH_PA_CTL2, + 0x10, 0x10); + } else { + snd_soc_update_bits(codec, WCD937X_HPH_PA_CTL2, + 0x40, 0x00); + snd_soc_update_bits(codec, WCD937X_HPH_PA_CTL2, + 0x10, 0x00); + } +} + +static void wcd937x_mbhc_moisture_config(struct wcd_mbhc *mbhc) +{ + struct snd_soc_codec *codec = mbhc->codec; + + if ((mbhc->moist_rref == R_OFF) || + (mbhc->mbhc_cfg->enable_usbc_analog)) { + snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); + return; + } + + /* Do not enable moisture detection if jack type is NC */ + if (!mbhc->hphl_swh) { + dev_dbg(codec->dev, "%s: disable moisture detection for NC\n", + __func__); + snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); + return; + } + + snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_2, + 0x0C, mbhc->moist_rref << 2); +} + +static const struct wcd_mbhc_cb mbhc_cb = { + .request_irq = wcd937x_mbhc_request_irq, + .irq_control = wcd937x_mbhc_irq_control, + .free_irq = wcd937x_mbhc_free_irq, + .clk_setup = wcd937x_mbhc_clk_setup, + .map_btn_code_to_num = wcd937x_mbhc_btn_to_num, + .mbhc_bias = wcd937x_mbhc_mbhc_bias_control, + .set_btn_thr = wcd937x_mbhc_program_btn_thr, + .lock_sleep = wcd937x_mbhc_lock_sleep, + .register_notifier = wcd937x_mbhc_register_notifier, + .micbias_enable_status = wcd937x_mbhc_micb_en_status, + .hph_pa_on_status = wcd937x_mbhc_hph_pa_on_status, + .hph_pull_up_control_v2 = wcd937x_mbhc_hph_l_pull_up_control, + .mbhc_micbias_control = wcd937x_mbhc_request_micbias, + .mbhc_micb_ramp_control = wcd937x_mbhc_micb_ramp_control, + .get_hwdep_fw_cal = wcd937x_get_hwdep_fw_cal, + .mbhc_micb_ctrl_thr_mic = wcd937x_mbhc_micb_ctrl_threshold_mic, + .compute_impedance = wcd937x_wcd_mbhc_calc_impedance, + .mbhc_gnd_det_ctrl = wcd937x_mbhc_gnd_det_ctrl, + .hph_pull_down_ctrl = wcd937x_mbhc_hph_pull_down_ctrl, + .mbhc_moisture_config = wcd937x_mbhc_moisture_config, +}; + +static int wcd937x_get_hph_type(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wcd937x_mbhc *wcd937x_mbhc = wcd937x_soc_get_mbhc(codec); + struct wcd_mbhc *mbhc; + + if (!wcd937x_mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + + mbhc = &wcd937x_mbhc->wcd_mbhc; + + ucontrol->value.integer.value[0] = (u32) mbhc->hph_type; + dev_dbg(codec->dev, "%s: hph_type = %u\n", __func__, mbhc->hph_type); + + return 0; +} + +static int wcd937x_hph_impedance_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + uint32_t zl, zr; + bool hphr; + struct soc_multi_mixer_control *mc; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wcd937x_mbhc *wcd937x_mbhc = wcd937x_soc_get_mbhc(codec); + + if (!wcd937x_mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + + mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); + hphr = mc->shift; + wcd_mbhc_get_impedance(&wcd937x_mbhc->wcd_mbhc, &zl, &zr); + dev_dbg(codec->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr); + ucontrol->value.integer.value[0] = hphr ? zr : zl; + + return 0; +} + +static const struct snd_kcontrol_new hph_type_detect_controls[] = { + SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0, + wcd937x_get_hph_type, NULL), +}; + +static const struct snd_kcontrol_new impedance_detect_controls[] = { + SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0, + wcd937x_hph_impedance_get, NULL), + SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0, + wcd937x_hph_impedance_get, NULL), +}; + +/* + * wcd937x_mbhc_get_impedance: get impedance of headphone + * left and right channels + * @wcd937x_mbhc: handle to struct wcd937x_mbhc * + * @zl: handle to left-ch impedance + * @zr: handle to right-ch impedance + * return 0 for success or error code in case of failure + */ +int wcd937x_mbhc_get_impedance(struct wcd937x_mbhc *wcd937x_mbhc, + uint32_t *zl, uint32_t *zr) +{ + if (!wcd937x_mbhc) { + pr_err("%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + if (!zl || !zr) { + pr_err("%s: zl or zr null!\n", __func__); + return -EINVAL; + } + + return wcd_mbhc_get_impedance(&wcd937x_mbhc->wcd_mbhc, zl, zr); +} +EXPORT_SYMBOL(wcd937x_mbhc_get_impedance); + +/* + * wcd937x_mbhc_hs_detect: starts mbhc insertion/removal functionality + * @codec: handle to snd_soc_codec * + * @mbhc_cfg: handle to mbhc configuration structure + * return 0 if mbhc_start is success or error code in case of failure + */ +int wcd937x_mbhc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg) +{ + struct wcd937x_priv *wcd937x = NULL; + struct wcd937x_mbhc *wcd937x_mbhc = NULL; + + if (!codec) { + pr_err("%s: codec is NULL\n", __func__); + return -EINVAL; + } + + wcd937x = snd_soc_codec_get_drvdata(codec); + if (!wcd937x) { + pr_err("%s: wcd937x is NULL\n", __func__); + return -EINVAL; + } + + wcd937x_mbhc = wcd937x->mbhc; + if (!wcd937x_mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + + return wcd_mbhc_start(&wcd937x_mbhc->wcd_mbhc, mbhc_cfg); +} +EXPORT_SYMBOL(wcd937x_mbhc_hs_detect); + +/* + * wcd937x_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality + * @codec: handle to snd_soc_codec * + */ +void wcd937x_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +{ + struct wcd937x_priv *wcd937x = NULL; + struct wcd937x_mbhc *wcd937x_mbhc = NULL; + + if (!codec) { + pr_err("%s: codec is NULL\n", __func__); + return; + } + + wcd937x = snd_soc_codec_get_drvdata(codec); + if (!wcd937x) { + pr_err("%s: wcd937x is NULL\n", __func__); + return; + } + + wcd937x_mbhc = wcd937x->mbhc; + if (!wcd937x_mbhc) { + dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + return; + } + wcd_mbhc_stop(&wcd937x_mbhc->wcd_mbhc); +} +EXPORT_SYMBOL(wcd937x_mbhc_hs_detect_exit); + +/* + * wcd937x_mbhc_post_ssr_init: initialize mbhc for + * wcd937x post subsystem restart + * @mbhc: poniter to wcd937x_mbhc structure + * @codec: handle to snd_soc_codec * + * + * return 0 if mbhc_init is success or error code in case of failure + */ +int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc, + struct snd_soc_codec *codec) +{ + int ret = 0; + struct wcd_mbhc *wcd_mbhc = NULL; + + if (!mbhc || !codec) + return -EINVAL; + + wcd_mbhc = &mbhc->wcd_mbhc; + if (wcd_mbhc == NULL) { + pr_err("%s: wcd_mbhc is NULL\n", __func__); + return -EINVAL; + } + + wcd_mbhc_deinit(wcd_mbhc); + ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids, + wcd_mbhc_registers, WCD937X_ZDET_SUPPORTED); + if (ret) { + dev_err(codec->dev, "%s: mbhc initialization failed\n", + __func__); + goto done; + } + +done: + return ret; +} +EXPORT_SYMBOL(wcd937x_mbhc_post_ssr_init); + +/* + * wcd937x_mbhc_init: initialize mbhc for wcd937x + * @mbhc: poniter to wcd937x_mbhc struct pointer to store the configs + * @codec: handle to snd_soc_codec * + * @fw_data: handle to firmware data + * + * return 0 if mbhc_init is success or error code in case of failure + */ +int wcd937x_mbhc_init(struct wcd937x_mbhc **mbhc, struct snd_soc_codec *codec, + struct fw_info *fw_data) +{ + struct wcd937x_mbhc *wcd937x_mbhc = NULL; + struct wcd_mbhc *wcd_mbhc = NULL; + int ret = 0; + + if (!codec) { + pr_err("%s: codec is NULL\n", __func__); + return -EINVAL; + } + + wcd937x_mbhc = devm_kzalloc(codec->dev, sizeof(struct wcd937x_mbhc), + GFP_KERNEL); + if (!wcd937x_mbhc) + return -ENOMEM; + + wcd937x_mbhc->fw_data = fw_data; + BLOCKING_INIT_NOTIFIER_HEAD(&wcd937x_mbhc->notifier); + wcd_mbhc = &wcd937x_mbhc->wcd_mbhc; + if (wcd_mbhc == NULL) { + pr_err("%s: wcd_mbhc is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + + /* Setting default mbhc detection logic to ADC */ + wcd_mbhc->mbhc_detection_logic = WCD_DETECTION_ADC; + + ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, + &intr_ids, wcd_mbhc_registers, + WCD937X_ZDET_SUPPORTED); + if (ret) { + dev_err(codec->dev, "%s: mbhc initialization failed\n", + __func__); + goto err; + } + + (*mbhc) = wcd937x_mbhc; + snd_soc_add_codec_controls(codec, impedance_detect_controls, + ARRAY_SIZE(impedance_detect_controls)); + snd_soc_add_codec_controls(codec, hph_type_detect_controls, + ARRAY_SIZE(hph_type_detect_controls)); + + return 0; +err: + devm_kfree(codec->dev, wcd937x_mbhc); + return ret; +} +EXPORT_SYMBOL(wcd937x_mbhc_init); + +/* + * wcd937x_mbhc_deinit: deinitialize mbhc for wcd937x + * @codec: handle to snd_soc_codec * + */ +void wcd937x_mbhc_deinit(struct snd_soc_codec *codec) +{ + struct wcd937x_priv *wcd937x; + struct wcd937x_mbhc *wcd937x_mbhc; + + if (!codec) { + pr_err("%s: codec is NULL\n", __func__); + return; + } + + wcd937x = snd_soc_codec_get_drvdata(codec); + if (!wcd937x) { + pr_err("%s: wcd937x is NULL\n", __func__); + return; + } + + wcd937x_mbhc = wcd937x->mbhc; + if (wcd937x_mbhc) { + wcd_mbhc_deinit(&wcd937x_mbhc->wcd_mbhc); + devm_kfree(codec->dev, wcd937x_mbhc); + } +} +EXPORT_SYMBOL(wcd937x_mbhc_deinit); diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.h b/asoc/codecs/wcd937x/wcd937x-mbhc.h new file mode 100644 index 000000000000..648d81c9be71 --- /dev/null +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.h @@ -0,0 +1,70 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __WCD937X_MBHC_H__ +#define __WCD937X_MBHC_H__ +#include "../wcd-mbhc-v2.h" + +struct wcd937x_mbhc { + struct wcd_mbhc wcd_mbhc; + struct blocking_notifier_head notifier; + struct fw_info *fw_data; + bool mbhc_started; +}; + +#if IS_ENABLED(CONFIG_SND_SOC_WCD937X) +extern int wcd937x_mbhc_init(struct wcd937x_mbhc **mbhc, + struct snd_soc_codec *codec, + struct fw_info *fw_data); +extern void wcd937x_mbhc_hs_detect_exit(struct snd_soc_codec *codec); +extern int wcd937x_mbhc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg); +extern void wcd937x_mbhc_deinit(struct snd_soc_codec *codec); +extern int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc, + struct snd_soc_codec *codec); +extern int wcd937x_mbhc_get_impedance(struct wcd937x_mbhc *wcd937x_mbhc, + uint32_t *zl, uint32_t *zr); +#else +static inline int wcd937x_mbhc_init(struct wcd937x_mbhc **mbhc, + struct snd_soc_codec *codec, + struct fw_info *fw_data) +{ + return 0; +} +static inline void wcd937x_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +{ +} +static inline int wcd937x_mbhc_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg) +{ + return 0; +} +static inline void wcd937x_mbhc_deinit(struct snd_soc_codec *codec) +{ +} +static inline int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc, + struct snd_soc_codec *codec) +{ + return 0; +} + +static inline int wcd937x_mbhc_get_impedance(struct wcd937x_mbhc *wcd937x_mbhc, + uint32_t *zl, uint32_t *zr) +{ + if (zl) + *zl = 0; + if (zr) + *zr = 0; + return -EINVAL; +} +#endif + +#endif /* __WCD937X_MBHC_H__ */ diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 78bd8634fa30..008f8f55e46e 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -34,6 +34,99 @@ static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); +static int wcd937x_handle_pre_irq(void *data); +static int wcd937x_handle_post_irq(void *data); + +static const struct regmap_irq wcd937x_irqs[WCD937X_NUM_IRQS] = { + REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x01), + REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_BUTTON_RELEASE_DET, 0, 0x02), + REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_ELECT_INS_REM_DET, 0, 0x04), + REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, 0, 0x08), + REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_SW_DET, 0, 0x10), + REGMAP_IRQ_REG(WCD937X_IRQ_HPHR_OCP_INT, 0, 0x20), + REGMAP_IRQ_REG(WCD937X_IRQ_HPHR_CNP_INT, 0, 0x40), + REGMAP_IRQ_REG(WCD937X_IRQ_HPHL_OCP_INT, 0, 0x80), + REGMAP_IRQ_REG(WCD937X_IRQ_HPHL_CNP_INT, 1, 0x01), + REGMAP_IRQ_REG(WCD937X_IRQ_EAR_CNP_INT, 1, 0x02), + REGMAP_IRQ_REG(WCD937X_IRQ_EAR_SCD_INT, 1, 0x04), + REGMAP_IRQ_REG(WCD937X_IRQ_AUX_CNP_INT, 1, 0x08), + REGMAP_IRQ_REG(WCD937X_IRQ_AUX_SCD_INT, 1, 0x10), + REGMAP_IRQ_REG(WCD937X_IRQ_HPHL_PDM_WD_INT, 1, 0x20), + REGMAP_IRQ_REG(WCD937X_IRQ_HPHR_PDM_WD_INT, 1, 0x40), + REGMAP_IRQ_REG(WCD937X_IRQ_AUX_PDM_WD_INT, 1, 0x80), + REGMAP_IRQ_REG(WCD937X_IRQ_LDORT_SCD_INT, 2, 0x01), + REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_MOISTURE_INT, 2, 0x02), + REGMAP_IRQ_REG(WCD937X_IRQ_HPHL_SURGE_DET_INT, 2, 0x04), + REGMAP_IRQ_REG(WCD937X_IRQ_HPHR_SURGE_DET_INT, 2, 0x08), +}; + +static struct regmap_irq_chip wcd937x_regmap_irq_chip = { + .name = "wcd937x", + .irqs = wcd937x_irqs, + .num_irqs = ARRAY_SIZE(wcd937x_irqs), + .num_regs = 3, + .status_base = WCD937X_DIGITAL_INTR_STATUS_0, + .mask_base = WCD937X_DIGITAL_INTR_MASK_0, + .type_base = WCD937X_DIGITAL_INTR_LEVEL_0, + .runtime_pm = true, + .handle_post_irq = wcd937x_handle_post_irq, + .handle_pre_irq = wcd937x_handle_pre_irq, +}; + +static int wcd937x_handle_pre_irq(void *data) +{ + struct wcd937x_priv *wcd937x = data; + int num_irq_regs = wcd937x->num_irq_regs; + int ret = 0; + u8 sts[num_irq_regs]; + struct wcd937x_pdata *pdata; + + pdata = dev_get_platdata(wcd937x->dev); + + memset(sts, 0, sizeof(sts)); + ret = regmap_bulk_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_0, + sts, num_irq_regs); + if (ret < 0) { + dev_err(wcd937x->dev, "%s: Failed to read intr status: %d\n", + __func__, ret); + } else if (ret == 0) { + dev_dbg(wcd937x->dev, + "%s: clear interrupts except OCP and SCD\n", __func__); + /* Do not affect OCP and SCD interrupts */ + sts[0] = sts[0] & 0x5F; + sts[1] = sts[1] & 0xEB; + regmap_write(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_0, + sts[0]); + regmap_write(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_1, + sts[1]); + regmap_write(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_2, + sts[2]); + } + return IRQ_HANDLED; +} + +static int wcd937x_handle_post_irq(void *data) +{ + struct wcd937x_priv *wcd937x = data; + int val = 0; + struct wcd937x_pdata *pdata = NULL; + + pdata = dev_get_platdata(wcd937x->dev); + + regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_0, &val); + if ((val & 0xA0) != 0) { + dev_dbg(wcd937x->dev, "%s Clear OCP interupts\n", __func__); + regmap_update_bits(wcd937x->regmap, + WCD937X_DIGITAL_INTR_CLEAR_0, 0xA0, 0x00); + } + regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_1, &val); + if ((val & 0x14) != 0) { + dev_dbg(wcd937x->dev, "%s Clear SCD interupts\n", __func__); + regmap_update_bits(wcd937x->regmap, + WCD937X_DIGITAL_INTR_CLEAR_1, 0x14, 0x00); + } + return IRQ_HANDLED; +} static int wcd937x_init_reg(struct snd_soc_codec *codec) { @@ -90,6 +183,31 @@ static int wcd937x_rx_clk_disable(struct snd_soc_codec *codec) return 0; } +/* + * wcd937x_soc_get_mbhc: get wcd937x_mbhc handle of corresponding codec + * @codec: handle to snd_soc_codec * + * + * return wcd937x_mbhc handle or error code in case of failure + */ +struct wcd937x_mbhc *wcd937x_soc_get_mbhc(struct snd_soc_codec *codec) +{ + struct wcd937x_priv *wcd937x; + + if (!codec) { + pr_err("%s: Invalid params, NULL codec\n", __func__); + return NULL; + } + wcd937x = snd_soc_codec_get_drvdata(codec); + + if (!wcd937x) { + pr_err("%s: Invalid params, NULL tavil\n", __func__); + return NULL; + } + + return wcd937x->mbhc; +} +EXPORT_SYMBOL(wcd937x_soc_get_mbhc); + static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -505,6 +623,100 @@ static int wcd937x_codec_enable_dmic(struct snd_soc_dapm_widget *w, return 0; } +/* + * wcd937x_get_micb_vout_ctl_val: converts micbias from volts to register value + * @micb_mv: micbias in mv + * + * return register value converted + */ +int wcd937x_get_micb_vout_ctl_val(u32 micb_mv) +{ + /* min micbias voltage is 1V and maximum is 2.85V */ + if (micb_mv < 1000 || micb_mv > 2850) { + pr_err("%s: unsupported micbias voltage\n", __func__); + return -EINVAL; + } + + return (micb_mv - 1000) / 50; +} +EXPORT_SYMBOL(wcd937x_get_micb_vout_ctl_val); + +/* + * wcd937x_mbhc_micb_adjust_voltage: adjust specific micbias voltage + * @codec: handle to snd_soc_codec * + * @req_volt: micbias voltage to be set + * @micb_num: micbias to be set, e.g. micbias1 or micbias2 + * + * return 0 if adjustment is success or error code in case of failure + */ +int wcd937x_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, + int req_volt, int micb_num) +{ + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int cur_vout_ctl, req_vout_ctl; + int micb_reg, micb_val, micb_en; + int ret = 0; + + switch (micb_num) { + case MIC_BIAS_1: + micb_reg = WCD937X_ANA_MICB1; + break; + case MIC_BIAS_2: + micb_reg = WCD937X_ANA_MICB2; + break; + case MIC_BIAS_3: + micb_reg = WCD937X_ANA_MICB3; + break; + default: + return -EINVAL; + } + mutex_lock(&wcd937x->micb_lock); + + /* + * If requested micbias voltage is same as current micbias + * voltage, then just return. Otherwise, adjust voltage as + * per requested value. If micbias is already enabled, then + * to avoid slow micbias ramp-up or down enable pull-up + * momentarily, change the micbias value and then re-enable + * micbias. + */ + micb_val = snd_soc_read(codec, micb_reg); + micb_en = (micb_val & 0xC0) >> 6; + cur_vout_ctl = micb_val & 0x3F; + + req_vout_ctl = wcd937x_get_micb_vout_ctl_val(req_volt); + if (req_vout_ctl < 0) { + ret = -EINVAL; + goto exit; + } + if (cur_vout_ctl == req_vout_ctl) { + ret = 0; + goto exit; + } + + dev_dbg(codec->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n", + __func__, micb_num, WCD_VOUT_CTL_TO_MICB(cur_vout_ctl), + req_volt, micb_en); + + if (micb_en == 0x1) + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + + snd_soc_update_bits(codec, micb_reg, 0x3F, req_vout_ctl); + + if (micb_en == 0x1) { + snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + /* + * Add 2ms delay as per HW requirement after enabling + * micbias + */ + usleep_range(2000, 2100); + } +exit: + mutex_unlock(&wcd937x->micb_lock); + return ret; +} +EXPORT_SYMBOL(wcd937x_mbhc_micb_adjust_voltage); + static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event){ @@ -565,8 +777,8 @@ static int wcd937x_enable_req(struct snd_soc_dapm_widget *w, return 0; } -static int wcd937x_micbias_control(struct snd_soc_codec *codec, - int micb_num, int req, bool is_dapm) +int wcd937x_micbias_control(struct snd_soc_codec *codec, + int micb_num, int req, bool is_dapm) { struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); @@ -663,6 +875,7 @@ static int wcd937x_micbias_control(struct snd_soc_codec *codec, return 0; } +EXPORT_SYMBOL(wcd937x_micbias_control); static int __wcd937x_codec_enable_micbias(struct snd_soc_dapm_widget *w, int event) @@ -1115,6 +1328,12 @@ static int wcd937x_soc_codec_probe(struct snd_soc_codec *codec) goto err_hwdep; } + ret = wcd937x_mbhc_init(&wcd937x->mbhc, codec, wcd937x->fw_data); + if (ret) { + pr_err("%s: mbhc initialization failed\n", __func__); + goto err_hwdep; + } + wcd937x_init_reg(codec); if (wcd937x->variant == WCD9375_VARIANT) { @@ -1250,7 +1469,7 @@ struct wcd937x_pdata *wcd937x_populate_dt_data(struct device *dev) static int wcd937x_bind(struct device *dev) { - int ret = 0; + int ret = 0, i = 0; struct wcd937x_priv *wcd937x = NULL; struct wcd937x_pdata *pdata = NULL; @@ -1305,15 +1524,35 @@ static int wcd937x_bind(struct device *dev) goto err; } + /* Set all interupts as edge triggered */ + for (i = 0; i < wcd937x_regmap_irq_chip.num_regs; i++) + regmap_write(wcd937x->regmap, + (WCD937X_DIGITAL_INTR_LEVEL_0 + i), 0); + + wcd937x->irq_info->wcd_regmap_irq_chip = &wcd937x_regmap_irq_chip; + wcd937x->irq_info->codec_name = "WCD937X"; + wcd937x->irq_info->regmap = wcd937x->regmap; + wcd937x->irq_info->dev = dev; + ret = wcd_irq_init(wcd937x->irq_info, &wcd937x->virq); + + if (ret) { + dev_err(wcd937x->dev, "%s: IRQ init failed: %d\n", + __func__, ret); + goto err; + } + wcd937x->tx_swr_dev->slave_irq = wcd937x->virq; + ret = snd_soc_register_codec(dev, &soc_codec_dev_wcd937x, NULL, 0); if (ret) { dev_err(dev, "%s: Codec registration failed\n", __func__); - goto err; + goto err_irq; } return ret; +err_irq: + wcd_irq_exit(wcd937x->irq_info, wcd937x->virq); err: component_unbind_all(dev, wcd937x); return ret; @@ -1323,6 +1562,7 @@ static void wcd937x_unbind(struct device *dev) { struct wcd937x_priv *wcd937x = dev_get_drvdata(dev); + wcd_irq_exit(wcd937x->irq_info, wcd937x->virq); snd_soc_unregister_codec(dev); component_unbind_all(dev, wcd937x); } -- GitLab From d2d8d9f683d64e204c17a251d670648df81b0a02 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 6 Aug 2018 18:10:14 +0530 Subject: [PATCH 0448/1645] asoc: bolero: Enable class-H for all interpolators On bolero and tanggu combination, enable digital side class-H by default. Change-Id: I366a7217dbbe7640846275eea57ef0c61cfcdf5e Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 129 +++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 49919de17cf7..43d3e92aaa5d 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -226,8 +226,10 @@ struct rx_macro_priv { u16 prim_int_users[INTERP_MAX]; int rx_mclk_users; int swr_clk_users; + int clsh_users; int rx_mclk_cnt; bool is_native_on; + bool is_ear_mode_on; u16 mclk_mux; struct mutex mclk_lock; struct mutex swr_clk_lock; @@ -313,6 +315,10 @@ static const char *const rx_macro_native_text[] = {"OFF", "ON"}; static const struct soc_enum rx_macro_native_enum = SOC_ENUM_SINGLE_EXT(2, rx_macro_native_text); +static const char *const rx_macro_ear_mode_text[] = {"OFF", "ON"}; +static const struct soc_enum rx_macro_ear_mode_enum = + SOC_ENUM_SINGLE_EXT(2, rx_macro_ear_mode_text); + RX_MACRO_DAPM_ENUM(rx_int0_2, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, rx_int_mix_mux_text); RX_MACRO_DAPM_ENUM(rx_int1_2, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, @@ -1116,6 +1122,76 @@ static int rx_macro_config_compander(struct snd_soc_codec *codec, return 0; } +static inline void +rx_macro_enable_clsh_block(struct rx_macro_priv *rx_priv, bool enable) +{ + if ((enable && ++rx_priv->clsh_users == 1) || + (!enable && --rx_priv->clsh_users == 0)) + snd_soc_update_bits(rx_priv->codec, + BOLERO_CDC_RX_CLSH_CRC, 0x01, + (u8) enable); + if (rx_priv->clsh_users < 0) + rx_priv->clsh_users = 0; + dev_dbg(rx_priv->dev, "%s: clsh_users %d, enable %d", __func__, + rx_priv->clsh_users, enable); +} + +static int rx_macro_config_classh(struct snd_soc_codec *codec, + struct rx_macro_priv *rx_priv, + int interp_n, int event) +{ + if (SND_SOC_DAPM_EVENT_OFF(event)) { + rx_macro_enable_clsh_block(rx_priv, false); + return 0; + } + + if (!SND_SOC_DAPM_EVENT_ON(event)) + return 0; + + rx_macro_enable_clsh_block(rx_priv, true); + if (interp_n == INTERP_HPHL || + interp_n == INTERP_HPHR) { + /* + * These K1 values depend on the Headphone Impedance + * For now it is assumed to be 16 ohm + */ + snd_soc_update_bits(codec, BOLERO_CDC_RX_CLSH_K1_LSB, + 0xFF, 0xC0); + snd_soc_update_bits(codec, BOLERO_CDC_RX_CLSH_K1_MSB, + 0x0F, 0x00); + } + switch (interp_n) { + case INTERP_HPHL: + if (rx_priv->is_ear_mode_on) + snd_soc_update_bits(codec, + BOLERO_CDC_RX_CLSH_HPH_V_PA, + 0x3F, 0x39); + else + snd_soc_update_bits(codec, + BOLERO_CDC_RX_CLSH_HPH_V_PA, + 0x3F, 0x1C); + snd_soc_update_bits(codec, BOLERO_CDC_RX_CLSH_DECAY_CTRL, + 0x07, 0x00); + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX0_RX_PATH_CFG0, + 0x40, 0x40); + break; + case INTERP_HPHR: + snd_soc_update_bits(codec, BOLERO_CDC_RX_CLSH_HPH_V_PA, + 0x3F, 0x1C); + snd_soc_update_bits(codec, BOLERO_CDC_RX_CLSH_DECAY_CTRL, + 0x07, 0x00); + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX1_RX_PATH_CFG0, + 0x40, 0x40); + break; + case INTERP_AUX: + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG0, + 0x10, 0x10); + break; + } + + return 0; +} + static void rx_macro_hd2_control(struct snd_soc_codec *codec, u16 interp_idx, int event) { @@ -1279,6 +1355,35 @@ static int rx_macro_put_native(struct snd_kcontrol *kcontrol, return 0; } +static int rx_macro_get_ear_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = rx_priv->is_ear_mode_on; + return 0; +} + +static int rx_macro_put_ear_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + rx_priv->is_ear_mode_on = + (!ucontrol->value.integer.value[0] ? false : true); + return 0; +} + static void rx_macro_idle_detect_control(struct snd_soc_codec *codec, struct rx_macro_priv *rx_priv, int interp, int event) @@ -1335,12 +1440,27 @@ static void rx_macro_hphdelay_lutbypass(struct snd_soc_codec *codec, if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) { snd_soc_update_bits(codec, BOLERO_CDC_RX_CLSH_TEST0, hph_dly_mask, 0x0); - snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x80); + if (interp_idx == INTERP_HPHL) { + if (rx_priv->is_ear_mode_on) + snd_soc_update_bits(codec, + BOLERO_CDC_RX_RX0_RX_PATH_CFG1, + 0x02, 0x02); + else + snd_soc_update_bits(codec, + hph_lut_bypass_reg, + 0x80, 0x80); + } else { + snd_soc_update_bits(codec, + hph_lut_bypass_reg, + 0x80, 0x80); + } } if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) { snd_soc_update_bits(codec, BOLERO_CDC_RX_CLSH_TEST0, hph_dly_mask, hph_dly_mask); + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX0_RX_PATH_CFG1, + 0x02, 0x00); snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x00); snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x0); } @@ -1377,6 +1497,8 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, event); rx_macro_config_compander(codec, rx_priv, interp_idx, event); + rx_macro_config_classh(codec, rx_priv, + interp_idx, event); } rx_priv->main_clk_users[interp_idx]++; } @@ -1385,6 +1507,8 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, rx_priv->main_clk_users[interp_idx]--; if (rx_priv->main_clk_users[interp_idx] <= 0) { rx_priv->main_clk_users[interp_idx] = 0; + rx_macro_config_classh(codec, rx_priv, + interp_idx, event); rx_macro_config_compander(codec, rx_priv, interp_idx, event); rx_macro_hphdelay_lutbypass(codec, rx_priv, interp_idx, @@ -1750,6 +1874,9 @@ static const struct snd_kcontrol_new rx_macro_snd_controls[] = { SOC_ENUM_EXT("RX_Native", rx_macro_native_enum, rx_macro_get_native, rx_macro_put_native), + SOC_ENUM_EXT("RX_EAR Mode", rx_macro_ear_mode_enum, + rx_macro_get_ear_mode, rx_macro_put_ear_mode), + SOC_SINGLE_SX_TLV("IIR0 INP0 Volume", BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40, digital_gain), -- GitLab From fc281adbdd8f974f39f9a242c112bbc15fada30c Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 6 Aug 2018 20:19:40 +0530 Subject: [PATCH 0449/1645] asoc: bolero: Update route map to enable MCLK for adie loopback For ADIE loopback, MCLK needs to be enabled. Associate the macro MCLK widgets to respective rx and tx paths in route map. Change-Id: I5632c3016146c5c5d822ae6fe438010904cf434b Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 5 +++++ asoc/codecs/bolero/tx-macro.c | 9 +++++++++ asoc/codecs/bolero/wsa-macro.c | 2 ++ 3 files changed, 16 insertions(+) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 43d3e92aaa5d..ea464c257b31 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -2254,6 +2254,7 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"}, {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 MIX2"}, {"HPHL_OUT", NULL, "RX INT0 DEM MUX"}, + {"HPHL_OUT", NULL, "RX_MCLK"}, {"RX INT1_1 INTERP", NULL, "RX INT1_1 MIX1"}, {"RX INT1 SEC MIX", NULL, "RX INT1_1 INTERP"}, @@ -2261,13 +2262,16 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { {"RX INT1 MIX2", NULL, "RX INT1 MIX2 INP"}, {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 MIX2"}, {"HPHR_OUT", NULL, "RX INT1 DEM MUX"}, + {"HPHR_OUT", NULL, "RX_MCLK"}, {"RX INT2_1 INTERP", NULL, "RX INT2_1 MIX1"}, {"RX INT2 SEC MIX", NULL, "RX INT2_1 INTERP"}, {"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"}, {"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"}, {"AUX_OUT", NULL, "RX INT2 MIX2"}, + {"AUX_OUT", NULL, "RX_MCLK"}, + {"IIR0", NULL, "RX_MCLK"}, {"IIR0", NULL, "IIR0 INP0 MUX"}, {"IIR0 INP0 MUX", "DEC0", "RX_TX DEC0_INP"}, {"IIR0 INP0 MUX", "DEC1", "RX_TX DEC1_INP"}, @@ -2313,6 +2317,7 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { {"IIR0 INP3 MUX", "RX4", "RX_RX4"}, {"IIR0 INP3 MUX", "RX5", "RX_RX5"}, + {"IIR1", NULL, "RX_MCLK"}, {"IIR1", NULL, "IIR1 INP0 MUX"}, {"IIR1 INP0 MUX", "DEC0", "RX_TX DEC0_INP"}, {"IIR1 INP0 MUX", "DEC1", "RX_TX DEC1_INP"}, diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index dabc345f22b9..5ad0e73ab3d7 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1056,6 +1056,15 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX_AIF2_CAP Mixer", "DEC6", "TX DEC6 MUX"}, {"TX_AIF2_CAP Mixer", "DEC7", "TX DEC7 MUX"}, + {"TX DEC0 MUX", NULL, "TX_MCLK"}, + {"TX DEC1 MUX", NULL, "TX_MCLK"}, + {"TX DEC2 MUX", NULL, "TX_MCLK"}, + {"TX DEC3 MUX", NULL, "TX_MCLK"}, + {"TX DEC4 MUX", NULL, "TX_MCLK"}, + {"TX DEC5 MUX", NULL, "TX_MCLK"}, + {"TX DEC6 MUX", NULL, "TX_MCLK"}, + {"TX DEC7 MUX", NULL, "TX_MCLK"}, + {"TX DEC0 MUX", "MSM_DMIC", "TX DMIC MUX0"}, {"TX DMIC MUX0", "DMIC0", "TX DMIC0"}, {"TX DMIC MUX0", "DMIC1", "TX DMIC1"}, diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index d73193c639f5..5a7adb30f022 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -1912,6 +1912,7 @@ static const struct snd_soc_dapm_route wsa_audio_map[] = { {"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"}, {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"}, {"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"}, + {"WSA_SPK1 OUT", NULL, "WSA_MCLK"}, {"WSA_RX1 INP0", "RX0", "WSA RX0"}, {"WSA_RX1 INP0", "RX1", "WSA RX1"}, @@ -1941,6 +1942,7 @@ static const struct snd_soc_dapm_route wsa_audio_map[] = { {"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"}, {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"}, {"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"}, + {"WSA_SPK2 OUT", NULL, "WSA_MCLK"}, }; static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = { -- GitLab From 0ffc608139338baab2b2d33c768b0f59fd87a5f0 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Fri, 3 Aug 2018 10:46:42 -0700 Subject: [PATCH 0450/1645] dsp: q6afe: Add check for DC detection registration Check if speaker protection is enabled before registering for DC detection events. CRs-Fixed: 2244131 Change-Id: If2f9f777534ee5fe9024ba1080d0b73d3f750159 Signed-off-by: Vignesh Kulothungan --- dsp/q6afe.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 31f86d6ff6a1..b2d43bd0f994 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1796,8 +1796,11 @@ static void afe_send_cal_spkr_prot_tx(int port_id) } mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); - /* Register for DC detection event */ - afe_spkr_prot_reg_event_cfg(port_id); + /* Register for DC detection event if speaker protection is enabled */ + if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED && + (this_afe.vi_tx_port == port_id)) { + afe_spkr_prot_reg_event_cfg(port_id); + } } static void afe_send_cal_spkr_prot_rx(int port_id) -- GitLab From 858c45e8b887eec0a7d2db6e56cb1087c1908363 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 8 Aug 2018 00:25:04 +0530 Subject: [PATCH 0451/1645] ASOC: Add bolero compilation in makefile Add bolero codec modules compilation in makefile. Change-Id: I5a060de93a95b9b150303df025c03abcf4bddd65 Signed-off-by: Ramprasad Katkam --- Android.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Android.mk b/Android.mk index 69bc5fda4cb6..c515dc5ea006 100644 --- a/Android.mk +++ b/Android.mk @@ -30,6 +30,8 @@ include $(MY_LOCAL_PATH)/asoc/codecs/aqt1000/Android.mk endif ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE)),true) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/bolero/Module.symvers) +include $(MY_LOCAL_PATH)/asoc/codecs/bolero/Android.mk $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd937x/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wcd937x/Android.mk endif -- GitLab From 95cfa1516b81200a353e8494672e4437cd622cdf Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Fri, 27 Jul 2018 22:15:58 +0530 Subject: [PATCH 0452/1645] asoc: wcd937x: Add swr port connections for wcd937x Add interface to read swr port mapping from device tree and call connect port to swr interface from wcd937x codec driver. Change-Id: I82e8d7a8063b725292e0d7ca5e519f279289efe0 Signed-off-by: Ramprasad Katkam --- asoc/codecs/wcd937x/internal.h | 16 ++ asoc/codecs/wcd937x/wcd937x.c | 356 ++++++++++++++++++++++++++++++--- 2 files changed, 339 insertions(+), 33 deletions(-) diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index e8ac70d9a98c..ba1b626c9171 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -21,9 +21,18 @@ /* Convert from vout ctl to micbias voltage in mV */ #define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50) +#define MAX_PORT 8 +#define MAX_CH_PER_PORT 8 extern struct regmap_config wcd937x_regmap_config; +struct codec_port_info { + u32 slave_port_type; + u32 master_port_type; + u32 ch_mask; + u32 num_ch; + u32 ch_rate; +}; struct wcd937x_priv { struct device *dev; @@ -55,6 +64,13 @@ struct wcd937x_priv { struct wcd_irq_info *irq_info; u32 rx_clk_cnt; int num_irq_regs; + + u8 num_tx_ports; + u8 num_rx_ports; + struct codec_port_info + tx_port_mapping[MAX_PORT][MAX_CH_PER_PORT]; + struct codec_port_info + rx_port_mapping[MAX_PORT][MAX_CH_PER_PORT]; }; struct wcd937x_micbias_setting { diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 008f8f55e46e..45a3b96bd541 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -28,10 +28,18 @@ #include "../wcdcal-hwdep.h" #include "wcd937x-registers.h" #include "../msm-cdc-pinctrl.h" +#include #define WCD9370_VARIANT 0 #define WCD9375_VARIANT 5 +#define NUM_SWRS_DT_PARAMS 5 + +enum { + CODEC_TX = 0, + CODEC_RX, +}; + static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); static int wcd937x_handle_pre_irq(void *data); @@ -145,6 +153,176 @@ static int wcd937x_init_reg(struct snd_soc_codec *codec) return 0; } +static int wcd937x_set_port_params(struct snd_soc_codec *codec, u8 slv_prt_type, + u8 *port_id, u8 *num_ch, u8 *ch_mask, u32 *ch_rate, + u8 *port_type, u8 path) +{ + int i, j; + u8 num_ports; + struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT]; + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + + switch (path) { + case CODEC_RX: + map = &wcd937x->rx_port_mapping; + num_ports = wcd937x->num_rx_ports; + break; + case CODEC_TX: + map = &wcd937x->tx_port_mapping; + num_ports = wcd937x->num_tx_ports; + break; + } + + for (i = 0; i <= num_ports; i++) { + for (j = 0; j < MAX_CH_PER_PORT; j++) { + if ((*map)[i][j].slave_port_type == slv_prt_type) + goto found; + } + } +found: + if (i > num_ports || j == MAX_CH_PER_PORT) { + dev_err(codec->dev, "%s Failed to find slave port for type %u\n", + __func__, slv_prt_type); + return -EINVAL; + } + *port_id = i; + *num_ch = (*map)[i][j].num_ch; + *ch_mask = (*map)[i][j].ch_mask; + *ch_rate = (*map)[i][j].ch_rate; + *port_type = (*map)[i][j].master_port_type; + + return 0; +} + +static int wcd937x_parse_port_mapping(struct device *dev, + char *prop, u8 path) +{ + u32 *dt_array, map_size, map_length; + u32 port_num, ch_mask, ch_rate, old_port_num = 0; + u32 slave_port_type, master_port_type; + u32 i, ch_iter = 0; + int ret = 0; + u8 *num_ports; + struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT]; + struct wcd937x_priv *wcd937x = dev_get_drvdata(dev); + + switch (path) { + case CODEC_RX: + map = &wcd937x->rx_port_mapping; + num_ports = &wcd937x->num_rx_ports; + break; + case CODEC_TX: + map = &wcd937x->tx_port_mapping; + num_ports = &wcd937x->num_tx_ports; + break; + } + + if (!of_find_property(dev->of_node, prop, + &map_size)) { + dev_err(dev, "missing port mapping prop %s\n", prop); + goto err_pdata_fail; + } + + map_length = map_size / (NUM_SWRS_DT_PARAMS * sizeof(u32)); + + dt_array = kzalloc(map_size, GFP_KERNEL); + + if (!dt_array) { + ret = -ENOMEM; + goto err_pdata_fail; + } + ret = of_property_read_u32_array(dev->of_node, prop, dt_array, + NUM_SWRS_DT_PARAMS * map_length); + if (ret) { + dev_err(dev, "%s: Failed to read port mapping from prop %s\n", + __func__, prop); + goto err_pdata_fail; + } + + for (i = 0; i < map_length; i++) { + port_num = dt_array[NUM_SWRS_DT_PARAMS * i]; + slave_port_type = dt_array[NUM_SWRS_DT_PARAMS * i + 1]; + ch_mask = dt_array[NUM_SWRS_DT_PARAMS * i + 2]; + ch_rate = dt_array[NUM_SWRS_DT_PARAMS * i + 3]; + master_port_type = dt_array[NUM_SWRS_DT_PARAMS * i + 4]; + + if (port_num != old_port_num) + ch_iter = 0; + + (*map)[port_num][ch_iter].slave_port_type = slave_port_type; + (*map)[port_num][ch_iter].ch_mask = ch_mask; + (*map)[port_num][ch_iter].master_port_type = master_port_type; + (*map)[port_num][ch_iter].num_ch = __sw_hweight8(ch_mask); + (*map)[port_num][ch_iter++].ch_rate = ch_rate; + old_port_num = port_num; + } + *num_ports = port_num; + kfree(dt_array); + return 0; + +err_pdata_fail: + kfree(dt_array); + return -EINVAL; +} + +static int wcd937x_tx_connect_port(struct snd_soc_codec *codec, + u8 slv_port_type, u8 enable) +{ + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + u8 port_id; + u8 num_ch; + u8 ch_mask; + u32 ch_rate; + u8 port_type; + u8 num_port = 1; + int ret = 0; + + ret = wcd937x_set_port_params(codec, slv_port_type, &port_id, + &num_ch, &ch_mask, &ch_rate, + &port_type, CODEC_TX); + + if (ret) + return ret; + + if (enable) + ret = swr_connect_port(wcd937x->tx_swr_dev, &port_id, + num_port, &ch_mask, &ch_rate, + &num_ch, &port_type); + else + ret = swr_disconnect_port(wcd937x->tx_swr_dev, &port_id, + num_port, &ch_mask, &port_type); + return ret; + +} +static int wcd937x_rx_connect_port(struct snd_soc_codec *codec, + u8 slv_port_type, u8 enable) +{ + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + u8 port_id; + u8 num_ch; + u8 ch_mask; + u32 ch_rate; + u8 port_type; + u8 num_port = 1; + int ret = 0; + + ret = wcd937x_set_port_params(codec, slv_port_type, &port_id, + &num_ch, &ch_mask, &ch_rate, + &port_type, CODEC_RX); + + if (ret) + return ret; + + if (enable) + ret = swr_connect_port(wcd937x->rx_swr_dev, &port_id, + num_port, &ch_mask, &ch_rate, + &num_ch, &port_type); + else + ret = swr_disconnect_port(wcd937x->rx_swr_dev, &port_id, + num_port, &ch_mask, &port_type); + return ret; +} + static int wcd937x_rx_clk_enable(struct snd_soc_codec *codec) { @@ -213,6 +391,8 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, int event) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -236,9 +416,14 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); break; + case SND_SOC_DAPM_POST_PMD: + ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, + wcd937x->rx_swr_dev->dev_num, + false); + break; } - return 0; + return ret; } static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, @@ -246,6 +431,9 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, int event) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int ret = 0; + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -269,9 +457,14 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); break; + case SND_SOC_DAPM_POST_PMD: + ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, + wcd937x->rx_swr_dev->dev_num, + false); + break; } - return 0; + return ret; } static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, @@ -279,6 +472,8 @@ static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, int event) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -294,8 +489,13 @@ static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, 0x02, 0x02); usleep_range(5000, 5010); break; + case SND_SOC_DAPM_POST_PMD: + ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, + wcd937x->rx_swr_dev->dev_num, + false); + break; }; - return 0; + return ret; } @@ -304,6 +504,8 @@ static int wcd937x_codec_aux_dac_event(struct snd_soc_dapm_widget *w, int event) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -319,12 +521,15 @@ static int wcd937x_codec_aux_dac_event(struct snd_soc_dapm_widget *w, 0x01, 0x01); break; case SND_SOC_DAPM_POST_PMD: + ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, + wcd937x->rx_swr_dev->dev_num, + false); wcd937x_rx_clk_disable(codec); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x04, 0x00); break; }; - return 0; + return ret; } @@ -333,6 +538,8 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, int event) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -348,13 +555,16 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, 0x02, 0x02); snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x02, 0x02); + ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, + wcd937x->rx_swr_dev->dev_num, + true); break; case SND_SOC_DAPM_POST_PMD: usleep_range(7000, 7010); snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x10, 0x00); break; }; - return 0; + return ret; } static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, @@ -362,6 +572,8 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, int event) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int ret = 0; switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -375,13 +587,16 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, 0x02, 0x02); snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x02, 0x02); + ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, + wcd937x->rx_swr_dev->dev_num, + true); break; case SND_SOC_DAPM_POST_PMD: usleep_range(7000, 7010); snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x20, 0x00); break; }; - return 0; + return ret; } static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, @@ -389,6 +604,8 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, int event) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -405,13 +622,16 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, usleep_range(1000, 1010); snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x20, 0x20); + ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, + wcd937x->rx_swr_dev->dev_num, + true); break; case SND_SOC_DAPM_POST_PMD: usleep_range(1000, 1010); usleep_range(1000, 1010); break; }; - return 0; + return ret; } static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, @@ -419,6 +639,8 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, int event) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -435,12 +657,15 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, usleep_range(6000, 6010); snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x02, 0x02); + ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, + wcd937x->rx_swr_dev->dev_num, + true); break; case SND_SOC_DAPM_POST_PMD: usleep_range(7000, 7010); break; }; - return 0; + return ret; } static int wcd937x_enable_rx1(struct snd_soc_dapm_widget *w, @@ -474,8 +699,13 @@ static int wcd937x_enable_rx1(struct snd_soc_dapm_widget *w, usleep_range(500, 510); snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, 0xFF, 0x3A); usleep_range(500, 510); + + wcd937x_rx_connect_port(codec, HPH_L, true); + wcd937x_rx_connect_port(codec, COMP_L, true); break; case SND_SOC_DAPM_POST_PMD: + wcd937x_rx_connect_port(codec, HPH_L, false); + wcd937x_rx_connect_port(codec, COMP_L, false); wcd937x_rx_clk_disable(codec); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x00); @@ -510,8 +740,13 @@ static int wcd937x_enable_rx2(struct snd_soc_dapm_widget *w, usleep_range(500, 510); snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, 0xFF, 0x3A); usleep_range(500, 510); + + wcd937x_rx_connect_port(codec, HPH_R, true); + wcd937x_rx_connect_port(codec, COMP_R, true); break; case SND_SOC_DAPM_POST_PMD: + wcd937x_rx_connect_port(codec, HPH_R, false); + wcd937x_rx_connect_port(codec, COMP_R, false); wcd937x_rx_clk_disable(codec); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x02, 0x00); @@ -543,8 +778,10 @@ static int wcd937x_enable_rx3(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEG_CTRL_2, 0xE0, 0xE0); usleep_range(100, 110); + wcd937x_rx_connect_port(codec, LO, true); break; case SND_SOC_DAPM_POST_PMD: + wcd937x_rx_connect_port(codec, LO, false); usleep_range(6000, 6010); wcd937x_rx_clk_disable(codec); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, @@ -615,8 +852,10 @@ static int wcd937x_codec_enable_dmic(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, dmic_clk_reg, 0x07, 0x02); snd_soc_update_bits(codec, dmic_clk_reg, 0x08, 0x08); snd_soc_update_bits(codec, dmic_clk_reg, 0x70, 0x20); + wcd937x_tx_connect_port(codec, DMIC0 + (w->shift), true); break; case SND_SOC_DAPM_POST_PMD: + wcd937x_tx_connect_port(codec, DMIC0 + (w->shift), false); break; }; @@ -717,6 +956,30 @@ int wcd937x_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, } EXPORT_SYMBOL(wcd937x_mbhc_micb_adjust_voltage); +static int wcd937x_tx_swr_ctrl(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = swr_slvdev_datapath_control(wcd937x->tx_swr_dev, + wcd937x->tx_swr_dev->dev_num, + true); + break; + case SND_SOC_DAPM_POST_PMD: + ret = swr_slvdev_datapath_control(wcd937x->tx_swr_dev, + wcd937x->tx_swr_dev->dev_num, + false); + break; + }; + + return ret; +} + static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event){ @@ -734,8 +997,10 @@ static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w, 0x08, 0x08); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); + wcd937x_tx_connect_port(codec, ADC1 + (w->shift), true); break; case SND_SOC_DAPM_POST_PMD: + wcd937x_tx_connect_port(codec, ADC1 + (w->shift), false); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00); break; @@ -1058,7 +1323,7 @@ static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = { SND_SOC_DAPM_ADC_E("ADC1", NULL, SND_SOC_NOPM, 0, 0, wcd937x_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("ADC2", NULL, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_ADC_E("ADC2", NULL, SND_SOC_NOPM, 0, 1, wcd937x_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -1073,10 +1338,14 @@ static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = { &tx_adc2_mux), /*tx mixers*/ - SND_SOC_DAPM_MIXER("ADC1_MIXER", SND_SOC_NOPM, 0, - 0, adc1_switch, ARRAY_SIZE(adc1_switch)), - SND_SOC_DAPM_MIXER("ADC2_MIXER", SND_SOC_NOPM, 0, - 0, adc2_switch, ARRAY_SIZE(adc2_switch)), + SND_SOC_DAPM_MIXER_E("ADC1_MIXER", SND_SOC_NOPM, 0, 0, + adc1_switch, ARRAY_SIZE(adc1_switch), + wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("ADC2_MIXER", SND_SOC_NOPM, 0, 0, + adc2_switch, ARRAY_SIZE(adc2_switch), + wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), /* micbias widgets*/ SND_SOC_DAPM_MICBIAS_E("MIC BIAS1", SND_SOC_NOPM, 0, 0, @@ -1169,7 +1438,7 @@ static const struct snd_soc_dapm_widget wcd9375_dapm_widgets[] = { SND_SOC_DAPM_INPUT("AMIC4"), /*tx widgets*/ - SND_SOC_DAPM_ADC_E("ADC3", NULL, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_ADC_E("ADC3", NULL, SND_SOC_NOPM, 0, 2, wcd937x_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -1180,37 +1449,50 @@ static const struct snd_soc_dapm_widget wcd9375_dapm_widgets[] = { SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0, wcd937x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 1, wcd937x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 2, wcd937x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 3, wcd937x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 4, wcd937x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 0, 5, wcd937x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), /*tx mixer widgets*/ - SND_SOC_DAPM_MIXER("DMIC1_MIXER", SND_SOC_NOPM, 0, - 0, dmic1_switch, ARRAY_SIZE(dmic1_switch)), - SND_SOC_DAPM_MIXER("DMIC2_MIXER", SND_SOC_NOPM, 0, - 0, dmic2_switch, ARRAY_SIZE(dmic2_switch)), - SND_SOC_DAPM_MIXER("DMIC3_MIXER", SND_SOC_NOPM, 0, - 0, dmic3_switch, ARRAY_SIZE(dmic3_switch)), - SND_SOC_DAPM_MIXER("DMIC4_MIXER", SND_SOC_NOPM, 0, - 0, dmic4_switch, ARRAY_SIZE(dmic4_switch)), - SND_SOC_DAPM_MIXER("DMIC5_MIXER", SND_SOC_NOPM, 0, - 0, dmic5_switch, ARRAY_SIZE(dmic5_switch)), - SND_SOC_DAPM_MIXER("DMIC6_MIXER", SND_SOC_NOPM, 0, - 0, dmic6_switch, ARRAY_SIZE(dmic6_switch)), - SND_SOC_DAPM_MIXER("ADC3_MIXER", SND_SOC_NOPM, 0, - 0, adc3_switch, ARRAY_SIZE(adc3_switch)), + SND_SOC_DAPM_MIXER_E("DMIC1_MIXER", SND_SOC_NOPM, 0, + 0, dmic1_switch, ARRAY_SIZE(dmic1_switch), + wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("DMIC2_MIXER", SND_SOC_NOPM, 0, + 0, dmic2_switch, ARRAY_SIZE(dmic2_switch), + wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("DMIC3_MIXER", SND_SOC_NOPM, 0, + 0, dmic3_switch, ARRAY_SIZE(dmic3_switch), + wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("DMIC4_MIXER", SND_SOC_NOPM, 0, + 0, dmic4_switch, ARRAY_SIZE(dmic4_switch), + wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("DMIC5_MIXER", SND_SOC_NOPM, 0, + 0, dmic5_switch, ARRAY_SIZE(dmic5_switch), + wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("DMIC6_MIXER", SND_SOC_NOPM, 0, + 0, dmic6_switch, ARRAY_SIZE(dmic6_switch), + wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("ADC3_MIXER", SND_SOC_NOPM, 0, 0, adc3_switch, + ARRAY_SIZE(adc3_switch), wcd937x_tx_swr_ctrl, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), /*output widgets*/ SND_SOC_DAPM_OUTPUT("DMIC1_OUTPUT"), @@ -1500,6 +1782,14 @@ static int wcd937x_bind(struct device *dev) return ret; } + ret = wcd937x_parse_port_mapping(dev, "qcom,rx_swr_ch_map", CODEC_RX); + ret |= wcd937x_parse_port_mapping(dev, "qcom,tx_swr_ch_map", CODEC_TX); + + if (ret) { + dev_err(dev, "Failed to read port mapping\n"); + goto err; + } + wcd937x->rx_swr_dev = get_matching_swr_slave_device(pdata->rx_slave); if (!wcd937x->rx_swr_dev) { dev_err(dev, "%s: Could not find RX swr slave device\n", -- GitLab From 59c7a1de1533467a4e6cfe10cf200f96176379bb Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 9 Aug 2018 16:11:17 +0530 Subject: [PATCH 0453/1645] asoc: bolero: Update AIF dai-id to start with value 1 ASoC core assigns dai id value to num_dais if AIF dai-id passed is 0. Since we have different macros passing AIF dai-id as 0, they are replaced in ASoC core. To handle this, update AIF dai-id in respective macros to start with value 1. Change-Id: I222c088289292aa226c90710e56a8c94af5615cd Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 11 ++++++----- asoc/codecs/bolero/tx-macro.c | 3 ++- asoc/codecs/bolero/va-macro.c | 3 ++- asoc/codecs/bolero/wsa-macro.c | 11 ++++++----- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 43d3e92aaa5d..6f5eedf6f388 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -189,7 +189,8 @@ struct rx_swr_ctrl_platform_data { }; enum { - RX_MACRO_AIF1_PB = 0, + RX_MACRO_AIF_INVALID = 0, + RX_MACRO_AIF1_PB, RX_MACRO_AIF2_PB, RX_MACRO_AIF3_PB, RX_MACRO_AIF4_PB, @@ -1301,16 +1302,16 @@ static int rx_macro_mux_put(struct snd_kcontrol *kcontrol, switch (rx_port_value) { case 0: clear_bit(widget->shift, - &rx_priv->active_ch_mask[aif_rst - 1]); - rx_priv->active_ch_cnt[aif_rst - 1]--; + &rx_priv->active_ch_mask[aif_rst]); + rx_priv->active_ch_cnt[aif_rst]--; break; case 1: case 2: case 3: case 4: set_bit(widget->shift, - &rx_priv->active_ch_mask[rx_port_value - 1]); - rx_priv->active_ch_cnt[rx_port_value - 1]++; + &rx_priv->active_ch_mask[rx_port_value]); + rx_priv->active_ch_cnt[rx_port_value]++; break; default: dev_err(codec->dev, diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index dabc345f22b9..b8542cbcb66d 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -80,7 +80,8 @@ struct tx_macro_swr_ctrl_platform_data { }; enum { - TX_MACRO_AIF1_CAP = 0, + TX_MACRO_AIF_INVALID = 0, + TX_MACRO_AIF1_CAP, TX_MACRO_AIF2_CAP, TX_MACRO_MAX_DAIS }; diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 45e1dbbdb9a6..53e01cc5fc5d 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -53,7 +53,8 @@ module_param(va_tx_unmute_delay, int, 0664); MODULE_PARM_DESC(va_tx_unmute_delay, "delay to unmute the tx path"); enum { - VA_MACRO_AIF1_CAP = 0, + VA_MACRO_AIF_INVALID = 0, + VA_MACRO_AIF1_CAP, VA_MACRO_AIF2_CAP, VA_MACRO_MAX_DAIS, }; diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index d73193c639f5..ba1ed1f06287 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -142,7 +142,8 @@ struct wsa_macro_swr_ctrl_platform_data { }; enum { - WSA_MACRO_AIF1_PB = 0, + WSA_MACRO_AIF_INVALID = 0, + WSA_MACRO_AIF1_PB, WSA_MACRO_AIF_MIX1_PB, WSA_MACRO_AIF_VI, WSA_MACRO_AIF_ECHO, @@ -1606,14 +1607,14 @@ static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol, switch (rx_port_value) { case 0: clear_bit(bit_input, - &wsa_priv->active_ch_mask[aif_rst - 1]); - wsa_priv->active_ch_cnt[aif_rst - 1]--; + &wsa_priv->active_ch_mask[aif_rst]); + wsa_priv->active_ch_cnt[aif_rst]--; break; case 1: case 2: set_bit(bit_input, - &wsa_priv->active_ch_mask[rx_port_value - 1]); - wsa_priv->active_ch_cnt[rx_port_value - 1]++; + &wsa_priv->active_ch_mask[rx_port_value]); + wsa_priv->active_ch_cnt[rx_port_value]++; break; default: dev_err(wsa_dev, -- GitLab From 99b0a75be7e84652dbde5893eddd7c1af3538765 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Tue, 7 Aug 2018 17:06:25 -0700 Subject: [PATCH 0454/1645] dsp: fix total size in set ui property Total size was incorrectly adjusted after determining IID param size in SET_UI_PROPERTY. Fix total size with correct APR packet and param sizes. Change-Id: I5874b470811733e60b40cc240d4c0db995b30bac Signed-off-by: Vikram Panduranga --- dsp/q6voice.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index dc505fd96377..32e85f952c9b 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -9564,6 +9564,8 @@ static int voice_pack_and_set_cvs_ui_property(struct voice_data *v, { struct vss_icommon_cmd_set_ui_property *set_ui_property = NULL; u32 total_size = 0; + u32 pkt_size = 0; + u32 param_size = 0; bool iid_supported = q6common_is_instance_id_supported(); void *apr_cvs; int ret = 0; @@ -9574,14 +9576,15 @@ static int voice_pack_and_set_cvs_ui_property(struct voice_data *v, return -EINVAL; } - total_size = sizeof(struct vss_icommon_cmd_set_ui_property) + - sizeof(union param_hdrs) + param_hdr.param_size; + pkt_size = sizeof(struct vss_icommon_cmd_set_ui_property); + param_size = sizeof(union param_hdrs) + param_hdr.param_size; + total_size = pkt_size + param_size; set_ui_property = kzalloc(total_size, GFP_KERNEL); if (!set_ui_property) return -ENOMEM; ret = q6common_pack_pp_params(set_ui_property->param_data, ¶m_hdr, - param_data, &total_size); + param_data, ¶m_size); if (ret) { pr_err("%s: Failed to pack params, error %d", __func__, ret); goto done; @@ -9591,11 +9594,11 @@ static int voice_pack_and_set_cvs_ui_property(struct voice_data *v, * Pack the APR header after packing the data so we have the actual * total size of the payload */ + total_size = pkt_size + param_size; set_ui_property->apr_hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - set_ui_property->apr_hdr.pkt_size = - APR_PKT_SIZE(APR_HDR_SIZE, total_size - APR_HDR_SIZE); + set_ui_property->apr_hdr.pkt_size = total_size; set_ui_property->apr_hdr.src_svc = 0; set_ui_property->apr_hdr.src_domain = APR_DOMAIN_APPS; set_ui_property->apr_hdr.src_port = -- GitLab From 6256c5b9892ff0a0395ab322e7c27960db2ae900 Mon Sep 17 00:00:00 2001 From: Tanya Dixit Date: Thu, 9 Aug 2018 14:29:51 +0530 Subject: [PATCH 0455/1645] asoc: codecs: Tanggu reset pin and supplies Enable power supplies and reset of Tanggu CRs-Fixed: 2281591 Change-Id: I7d693263f328b51d2f333bddac5e15e98a5f9f51 Signed-off-by: Tanya Dixit --- asoc/codecs/wcd937x/internal.h | 4 ++++ asoc/codecs/wcd937x/wcd937x.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index ba1b626c9171..b693f6a9bc16 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -71,6 +71,7 @@ struct wcd937x_priv { tx_port_mapping[MAX_PORT][MAX_CH_PER_PORT]; struct codec_port_info rx_port_mapping[MAX_PORT][MAX_CH_PER_PORT]; + struct regulator_bulk_data *supplies; }; struct wcd937x_micbias_setting { @@ -85,6 +86,9 @@ struct wcd937x_pdata { struct device_node *rx_slave; struct device_node *tx_slave; struct wcd937x_micbias_setting micbias; + + struct cdc_regulator *regulator; + int num_supplies; }; enum { diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 45a3b96bd541..96e859c88ccf 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -29,6 +29,7 @@ #include "wcd937x-registers.h" #include "../msm-cdc-pinctrl.h" #include +#include "../msm-cdc-supply.h" #define WCD9370_VARIANT 0 #define WCD9375_VARIANT 5 @@ -1734,15 +1735,24 @@ struct wcd937x_pdata *wcd937x_populate_dt_data(struct device *dev) return NULL; pdata->rst_np = of_parse_phandle(dev->of_node, - "qcom,wcd937x-reset-node", 0); + "qcom,wcd-rst-gpio-node", 0); if (!pdata->rst_np) { dev_err(dev, "%s: Looking up %s property in node %s failed\n", - __func__, "qcom,wcd937x-reset-node", + __func__, "qcom,wcd-rst-gpio-node", dev->of_node->full_name); return NULL; } + /* Parse power supplies */ + msm_cdc_get_power_supplies(dev, &pdata->regulator, + &pdata->num_supplies); + if (!pdata->regulator || (pdata->num_supplies <= 0)) { + dev_err(dev, "%s: no power supplies defined for codec\n", + __func__); + return NULL; + } + pdata->rx_slave = of_parse_phandle(dev->of_node, "qcom,rx-slave", 0); pdata->tx_slave = of_parse_phandle(dev->of_node, "qcom,tx-slave", 0); @@ -1775,6 +1785,24 @@ static int wcd937x_bind(struct device *dev) * as per HW requirement. */ usleep_range(5000, 5010); + + ret = msm_cdc_init_supplies(dev, &wcd937x->supplies, + pdata->regulator, pdata->num_supplies); + if (!wcd937x->supplies) { + dev_err(dev, "%s: Cannot init wcd supplies\n", + __func__); + return ret; + } + + ret = msm_cdc_enable_static_supplies(dev, wcd937x->supplies, + pdata->regulator, + pdata->num_supplies); + if (ret) { + dev_err(dev, "%s: wcd static supply enable failed!\n", + __func__); + return ret; + } + ret = component_bind_all(dev, wcd937x); if (ret) { dev_err(dev, "%s: Slave bind failed, ret = %d\n", -- GitLab From 9e90df7393c7c84bb3db7b8f24422d239dcac3e7 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Fri, 10 Aug 2018 16:11:08 +0530 Subject: [PATCH 0456/1645] asoc: swr: Add new parameters for swr port Add wordlength and lanectrl parameters for swr port. Change-Id: Id36a1b0750b7e8f13e4d1eed6a9abaddc2f39a83 Signed-off-by: Ramprasad Katkam --- include/soc/soundwire.h | 2 ++ soc/swrm_registers.h | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/soc/soundwire.h b/include/soc/soundwire.h index d2ebb7621476..64a99d8c271d 100644 --- a/include/soc/soundwire.h +++ b/include/soc/soundwire.h @@ -76,6 +76,8 @@ struct swr_port_info { u8 hstop; u8 blk_grp_count; u8 blk_pack_mode; + u8 word_length; + u8 lane_ctrl; u8 ch_en; u8 req_ch; u8 num_ch; diff --git a/soc/swrm_registers.h b/soc/swrm_registers.h index f1d2586944b2..0147e459d76d 100644 --- a/soc/swrm_registers.h +++ b/soc/swrm_registers.h @@ -179,6 +179,30 @@ #define SWRM_DP_PORT_CTRL_OFFSET1_SHFT 0x08 #define SWRM_DP_PORT_CTRL_SAMPLE_INTERVAL 0x00 +#define SWRM_DP_PORT_CTRL_2_BANK(n, m) (SWRM_BASE_ADDRESS + \ + 0x00001128 + \ + 0x100*(n-1) + \ + 0x40*m) + +#define SWRM_DP_BLOCK_CTRL_1(n) (SWRM_BASE_ADDRESS + \ + 0x0000112C + 0x100*n) + +#define SWRM_DP_BLOCK_CTRL2_BANK(n, m) (SWRM_BASE_ADDRESS + \ + 0x00001130 + \ + 0x100*(n-1) + \ + 0x40*m) + +#define SWRM_DP_PORT_HCTRL_BANK(n, m) (SWRM_BASE_ADDRESS + \ + 0x00001134 + \ + 0x100*(n-1) + \ + 0x40*m) + +#define SWRM_DP_BLOCK_CTRL3_BANK(n, m) (SWRM_BASE_ADDRESS + \ + 0x00001138 + \ + 0x100*(n-1) + \ + 0x40*m) + + #define SWRM_DIN_DPn_PCM_PORT_CTRL(n) (SWRM_BASE_ADDRESS + \ 0x00001054 + 0x100*n) @@ -190,8 +214,14 @@ #define SWRS_DP_REG_OFFSET(port, bank) ((0x100*port)+(0x10*bank)) +#define SWRS_SCP_CONTROL 0x44 +#define SWRS_DP_BLOCK_CONTROL_1(n) (SWRS_BASE_ADDRESS + 0x120 + \ + 0x100 * n) + #define SWRS_DP_CHANNEL_ENABLE_BANK(n, m) (SWRS_BASE_ADDRESS + 0x120 + \ SWRS_DP_REG_OFFSET(n, m)) +#define SWRS_DP_BLOCK_CONTROL_2_BANK(n, m) (SWRS_BASE_ADDRESS + 0x121 + \ + SWRS_DP_REG_OFFSET(n, m)) #define SWRS_DP_SAMPLE_CONTROL_1_BANK(n, m) (SWRS_BASE_ADDRESS + 0x122 + \ SWRS_DP_REG_OFFSET(n, m)) #define SWRS_DP_OFFSET_CONTROL_1_BANK(n, m) (SWRS_BASE_ADDRESS + 0x124 + \ @@ -202,6 +232,8 @@ SWRS_DP_REG_OFFSET(n, m)) #define SWRS_DP_BLOCK_CONTROL_3_BANK(n, m) (SWRS_BASE_ADDRESS + 0x127 + \ SWRS_DP_REG_OFFSET(n, m)) +#define SWRS_DP_LANE_CONTROL_BANK(n, m) (SWRS_BASE_ADDRESS + 0x128 + \ + SWRS_DP_REG_OFFSET(n, m)) #define SWRS_SCP_FRAME_CTRL_BANK(m) (SWRS_BASE_ADDRESS + 0x60 + \ 0x10*m) #define SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(m) (SWRS_BASE_ADDRESS + 0xE0 + \ -- GitLab From ddb6e41cd42a84a006f3a8b3e52253a6bb98d109 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Thu, 9 Aug 2018 18:21:34 +0530 Subject: [PATCH 0457/1645] audio-kernel: Assign target name msmsteppe for sm6150 Use msmsteppe target name instead of macro as macro cannot be used in target rc file. Signed-off-by: Ramprasad Katkam Change-Id: I0f3ec299b28b7dfd9f8ac9985eea0c22a4611f9e --- asoc/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/Android.mk b/asoc/Android.mk index 26c898bdb059..a5d1c7edad3c 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -19,7 +19,7 @@ AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) -TARGET := $(MSMSTEPPE) +TARGET := talos AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif -- GitLab From f83acfb0f220d30a100ce4409f3764ff35924a9a Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Sat, 11 Aug 2018 23:28:57 +0530 Subject: [PATCH 0458/1645] asoc: Binrgup fixes for talos Add fixes related to audio bringup Change-Id: I46fa0bb9c6f914fe9034f4fb78ef2248de7ebd50 Signed-off-by: Ramprasad Katkam --- asoc/codecs/bolero/tx-macro.c | 16 ++++++++-------- asoc/codecs/bolero/va-macro.c | 28 +++++++++++++++++++++++----- asoc/codecs/bolero/wsa-macro.c | 6 ++++-- asoc/codecs/wcd937x/wcd937x.c | 16 ++++++++-------- asoc/sm6150.c | 14 ++++++-------- 5 files changed, 49 insertions(+), 31 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 05642c98d2f8..e2eac593b6e3 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -980,49 +980,49 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = { SND_SOC_DAPM_INPUT("TX SWR_DMIC6"), SND_SOC_DAPM_INPUT("TX SWR_DMIC7"), - SND_SOC_DAPM_MUX_E("TX DEC0 MUX", BOLERO_CDC_TX0_TX_PATH_CTL, + SND_SOC_DAPM_MUX_E("TX DEC0 MUX", SND_SOC_NOPM, TX_MACRO_DEC0, 0, &tx_dec0_mux, tx_macro_enable_dec, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("TX DEC1 MUX", BOLERO_CDC_TX1_TX_PATH_CTL, + SND_SOC_DAPM_MUX_E("TX DEC1 MUX", SND_SOC_NOPM, TX_MACRO_DEC1, 0, &tx_dec1_mux, tx_macro_enable_dec, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("TX DEC2 MUX", BOLERO_CDC_TX2_TX_PATH_CTL, + SND_SOC_DAPM_MUX_E("TX DEC2 MUX", SND_SOC_NOPM, TX_MACRO_DEC2, 0, &tx_dec2_mux, tx_macro_enable_dec, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("TX DEC3 MUX", BOLERO_CDC_TX3_TX_PATH_CTL, + SND_SOC_DAPM_MUX_E("TX DEC3 MUX", SND_SOC_NOPM, TX_MACRO_DEC3, 0, &tx_dec3_mux, tx_macro_enable_dec, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("TX DEC4 MUX", BOLERO_CDC_TX4_TX_PATH_CTL, + SND_SOC_DAPM_MUX_E("TX DEC4 MUX", SND_SOC_NOPM, TX_MACRO_DEC4, 0, &tx_dec4_mux, tx_macro_enable_dec, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("TX DEC5 MUX", BOLERO_CDC_TX5_TX_PATH_CTL, + SND_SOC_DAPM_MUX_E("TX DEC5 MUX", SND_SOC_NOPM, TX_MACRO_DEC5, 0, &tx_dec5_mux, tx_macro_enable_dec, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("TX DEC6 MUX", BOLERO_CDC_TX6_TX_PATH_CTL, + SND_SOC_DAPM_MUX_E("TX DEC6 MUX", SND_SOC_NOPM, TX_MACRO_DEC6, 0, &tx_dec6_mux, tx_macro_enable_dec, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("TX DEC7 MUX", BOLERO_CDC_TX7_TX_PATH_CTL, + SND_SOC_DAPM_MUX_E("TX DEC7 MUX", SND_SOC_NOPM, TX_MACRO_DEC7, 0, &tx_dec7_mux, tx_macro_enable_dec, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 53e01cc5fc5d..f2a2d62f3869 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -1032,6 +1032,12 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; +static const struct snd_soc_dapm_widget va_macro_wod_dapm_widgets[] = { + SND_SOC_DAPM_SUPPLY_S("VA_MCLK", 0, SND_SOC_NOPM, 0, 0, + va_macro_mclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + static const struct snd_soc_dapm_route va_audio_map[] = { {"VA_AIF1 CAP", NULL, "VA_MCLK"}, {"VA_AIF2 CAP", NULL, "VA_MCLK"}, @@ -1347,6 +1353,19 @@ static int va_macro_init(struct snd_soc_codec *codec) return -EINVAL; } + if (va_priv->va_without_decimation) { + ret = snd_soc_dapm_new_controls(dapm, va_macro_wod_dapm_widgets, + ARRAY_SIZE(va_macro_wod_dapm_widgets)); + if (ret < 0) { + dev_err(va_dev, + "%s: Failed to add without dec controls\n", + __func__); + return ret; + } + va_priv->codec = codec; + return 0; + } + ret = snd_soc_dapm_new_controls(dapm, va_macro_dapm_widgets, ARRAY_SIZE(va_macro_dapm_widgets)); if (ret < 0) { @@ -1409,16 +1428,14 @@ static void va_macro_init_ops(struct macro_ops *ops, { memset(ops, 0, sizeof(struct macro_ops)); if (!va_without_decimation) { - ops->init = va_macro_init; - ops->exit = va_macro_deinit; ops->dai_ptr = va_macro_dai; ops->num_dais = ARRAY_SIZE(va_macro_dai); } else { - ops->init = NULL; - ops->exit = NULL; ops->dai_ptr = NULL; ops->num_dais = 0; } + ops->init = va_macro_init; + ops->exit = va_macro_deinit; ops->io_base = va_io_base; ops->mclk_fn = va_macro_mclk_ctrl; } @@ -1477,9 +1494,10 @@ static int va_macro_probe(struct platform_device *pdev) /* Register MCLK for va macro */ va_core_clk = devm_clk_get(&pdev->dev, "va_core_clk"); if (IS_ERR(va_core_clk)) { + ret = PTR_ERR(va_core_clk); dev_err(&pdev->dev, "%s: clk get %s failed\n", __func__, "va_core_clk"); - return -EINVAL; + return ret; } va_priv->va_core_clk = va_core_clk; diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 1f1af22fe9a0..ecfe28f15f00 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -2252,17 +2252,19 @@ static int wsa_macro_probe(struct platform_device *pdev) /* Register MCLK for wsa macro */ wsa_core_clk = devm_clk_get(&pdev->dev, "wsa_core_clk"); if (IS_ERR(wsa_core_clk)) { + ret = PTR_ERR(wsa_core_clk); dev_err(&pdev->dev, "%s: clk get %s failed\n", __func__, "wsa_core_clk"); - return -EINVAL; + return ret; } wsa_priv->wsa_core_clk = wsa_core_clk; /* Register npl clk for soundwire */ wsa_npl_clk = devm_clk_get(&pdev->dev, "wsa_npl_clk"); if (IS_ERR(wsa_npl_clk)) { + ret = PTR_ERR(wsa_npl_clk); dev_err(&pdev->dev, "%s: clk get %s failed\n", __func__, "wsa_npl_clk"); - return -EINVAL; + return ret; } wsa_priv->wsa_npl_clk = wsa_npl_clk; dev_set_drvdata(&pdev->dev, wsa_priv); diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 96e859c88ccf..f445540eb343 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1778,14 +1778,6 @@ static int wcd937x_bind(struct device *dev) } wcd937x->rst_np = pdata->rst_np; - wcd937x_reset(dev); - /* - * Add 5msec delay to provide sufficient time for - * soundwire auto enumeration of slave devices as - * as per HW requirement. - */ - usleep_range(5000, 5010); - ret = msm_cdc_init_supplies(dev, &wcd937x->supplies, pdata->regulator, pdata->num_supplies); if (!wcd937x->supplies) { @@ -1803,6 +1795,14 @@ static int wcd937x_bind(struct device *dev) return ret; } + wcd937x_reset(dev); + /* + * Add 5msec delay to provide sufficient time for + * soundwire auto enumeration of slave devices as + * as per HW requirement. + */ + usleep_range(5000, 5010); + ret = component_bind_all(dev, wcd937x); if (ret) { dev_err(dev, "%s: Slave bind failed, ret = %d\n", diff --git a/asoc/sm6150.c b/asoc/sm6150.c index f7105d4953ac..8d9d32dc283e 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -7342,13 +7342,12 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { { .name = LPASS_BE_RX_CDC_DMA_RX_0, .stream_name = "RX CDC DMA0 Playback", - .cpu_dai_name = "msm-dai-cdc-dma-dev.45120", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45104", .platform_name = "msm-pcm-routing", .codec_name = "bolero_codec", .codec_dai_name = "rx_macro_rx1", .no_pcm = 1, .dpcm_playback = 1, - .init = &msm_int_audrx_init, .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_pmdown_time = 1, @@ -7358,7 +7357,7 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { { .name = LPASS_BE_RX_CDC_DMA_RX_1, .stream_name = "RX CDC DMA1 Playback", - .cpu_dai_name = "msm-dai-cdc-dma-dev.45122", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45106", .platform_name = "msm-pcm-routing", .codec_name = "bolero_codec", .codec_dai_name = "rx_macro_rx2", @@ -7373,7 +7372,7 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { { .name = LPASS_BE_RX_CDC_DMA_RX_2, .stream_name = "RX CDC DMA2 Playback", - .cpu_dai_name = "msm-dai-cdc-dma-dev.45124", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45108", .platform_name = "msm-pcm-routing", .codec_name = "bolero_codec", .codec_dai_name = "rx_macro_rx3", @@ -7388,7 +7387,7 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { { .name = LPASS_BE_RX_CDC_DMA_RX_3, .stream_name = "RX CDC DMA3 Playback", - .cpu_dai_name = "msm-dai-cdc-dma-dev.45126", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45110", .platform_name = "msm-pcm-routing", .codec_name = "bolero_codec", .codec_dai_name = "rx_macro_rx4", @@ -7404,13 +7403,12 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { { .name = LPASS_BE_TX_CDC_DMA_TX_3, .stream_name = "TX CDC DMA3 Capture", - .cpu_dai_name = "msm-dai-cdc-dma-dev.45127", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45111", .platform_name = "msm-pcm-routing", .codec_name = "bolero_codec", .codec_dai_name = "tx_macro_tx1", .no_pcm = 1, .dpcm_capture = 1, - .init = &msm_int_audrx_init, .id = MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_suspend = 1, @@ -7419,7 +7417,7 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { { .name = LPASS_BE_TX_CDC_DMA_TX_4, .stream_name = "TX CDC DMA4 Capture", - .cpu_dai_name = "msm-dai-cdc-dma-dev.45129", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45113", .platform_name = "msm-pcm-routing", .codec_name = "bolero_codec", .codec_dai_name = "tx_macro_tx2", -- GitLab From 0b9c8c186f42eb651fa33d9718652b2ddd8dd1b9 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Tue, 14 Aug 2018 10:57:27 -0700 Subject: [PATCH 0459/1645] apr: fix race condition in apr reset Since apr reset is scheduled in a workqueue, it is possible that before completion of previous session apr_deregister(), new session of apr_register() can happen in ssr scenario. Some of the variables are not reset properly due to this race condition. Fix this issue by failing apr_register() till apr_deregister() is completed. Change-Id: I203e356e8330d8633d78bbfc6ae0165afa79f1f3 Signed-off-by: Vidyakumar Athota --- ipc/apr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ipc/apr.c b/ipc/apr.c index cb72766a5ff5..ff393e372869 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -543,6 +543,7 @@ struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn, if (svc->need_reset) { mutex_unlock(&svc->m_lock); pr_err("APR: Service needs reset\n"); + svc = NULL; goto done; } svc->id = svc_id; -- GitLab From a45a56e82401695b4110b08985ab94dc88eb5eee Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 3 Aug 2018 05:30:24 +0530 Subject: [PATCH 0460/1645] ASoC: wcd-mbhc: Avoid headset jack corrosion due to moisture Detect moisture in the headset jack and avoid headset jack corrosion due to presence of moisture over prolonged duration. Change-Id: I0227e516feb58c96ddf6a8fbc32423bfe7733ca6 Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd-mbhc-v2.c | 51 ++++++++++++++++++++++++++++++++++++++- asoc/codecs/wcd-mbhc-v2.h | 4 +++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 6f3b19ba6c1b..363b90b1d5f5 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -850,6 +850,36 @@ void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc, } EXPORT_SYMBOL(wcd_mbhc_find_plug_and_report); +static bool wcd_mbhc_moisture_detect(struct wcd_mbhc *mbhc, bool detection_type) +{ + bool ret = false; + + if (!mbhc->mbhc_cfg->moisture_en || + !mbhc->mbhc_cfg->moisture_duty_cycle_en) + return ret; + + if (!mbhc->mbhc_cb->mbhc_get_moisture_status || + !mbhc->mbhc_cb->mbhc_moisture_polling_ctrl || + !mbhc->mbhc_cb->mbhc_moisture_detect_en) + return ret; + + if (mbhc->mbhc_cb->mbhc_get_moisture_status(mbhc)) { + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 0); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_GND_DET_EN, 0); + mbhc->mbhc_cb->mbhc_moisture_polling_ctrl(mbhc, true); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MECH_DETECTION_TYPE, + detection_type); + ret = true; + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_GND_DET_EN, 1); + } else { + mbhc->mbhc_cb->mbhc_moisture_polling_ctrl(mbhc, false); + mbhc->mbhc_cb->mbhc_moisture_detect_en(mbhc, false); + } + + return ret; +} + static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) { bool detection_type = 0; @@ -885,6 +915,13 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) if ((mbhc->current_plug == MBHC_PLUG_TYPE_NONE) && detection_type) { + + /* If moisture is present, then enable polling, disable + * moisture detection and wait for interrupt + */ + if (wcd_mbhc_moisture_detect(mbhc, detection_type)) + goto done; + /* Make sure MASTER_BIAS_CTL is enabled */ mbhc->mbhc_cb->mbhc_bias(codec, true); @@ -970,6 +1007,16 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) mbhc->mbhc_cb->clk_setup(mbhc->codec, false); } + if (mbhc->mbhc_cfg->moisture_en && + mbhc->mbhc_cfg->moisture_duty_cycle_en) { + if (mbhc->mbhc_cb->mbhc_moisture_polling_ctrl) + mbhc->mbhc_cb->mbhc_moisture_polling_ctrl(mbhc, + false); + if (mbhc->mbhc_cb->mbhc_moisture_detect_en) + mbhc->mbhc_cb->mbhc_moisture_detect_en(mbhc, + false); + } + } else if (!detection_type) { /* Disable external voltage source to micbias if present */ if (mbhc->mbhc_cb->enable_mb_source) @@ -980,6 +1027,7 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) mbhc->extn_cable_hph_rem = false; } +done: mbhc->in_swch_irq_handler = false; WCD_MBHC_RSC_UNLOCK(mbhc); pr_debug("%s: leave\n", __func__); @@ -1294,7 +1342,8 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) else WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, 3); - if (mbhc->mbhc_cfg->moisture_en && mbhc->mbhc_cb->mbhc_moisture_config) + if (mbhc->mbhc_cfg->moisture_en && mbhc->mbhc_cb->mbhc_moisture_config + && !mbhc->mbhc_cfg->moisture_duty_cycle_en) mbhc->mbhc_cb->mbhc_moisture_config(mbhc); /* diff --git a/asoc/codecs/wcd-mbhc-v2.h b/asoc/codecs/wcd-mbhc-v2.h index 04735741047b..4d00c2bb9800 100644 --- a/asoc/codecs/wcd-mbhc-v2.h +++ b/asoc/codecs/wcd-mbhc-v2.h @@ -437,6 +437,7 @@ struct wcd_mbhc_config { int anc_micbias; bool enable_anc_mic_detect; u32 enable_usbc_analog; + bool moisture_duty_cycle_en; }; struct wcd_mbhc_intr { @@ -502,6 +503,9 @@ struct wcd_mbhc_cb { bool enable, int anc_num); bool (*is_anc_on)(struct wcd_mbhc *mbhc); void (*hph_pull_up_control_v2)(struct snd_soc_codec *, int); + bool (*mbhc_get_moisture_status)(struct wcd_mbhc *); + void (*mbhc_moisture_polling_ctrl)(struct wcd_mbhc *, bool); + void (*mbhc_moisture_detect_en)(struct wcd_mbhc *, bool); }; struct wcd_mbhc_fn { -- GitLab From d4e11ac7a47d75c803796e7e3b7984f7d807650e Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 25 Jul 2018 16:31:40 +0800 Subject: [PATCH 0461/1645] asoc: wcd-dsp-mgr: reinit ssr ready flag for adsp/wdsp ssr When adsp/wdsp SSR happens, WDSP_SSR_TYPE_WDSP_DOWN/WDSP_SSR_TYPE_CDC_DOWN would get received by wcd-dsp-mgr. wcd-dsp-mgr would clear current work and init wdsp when adsp is up and ready_compl flag is set to ready. Sometimes ready_compl flag is not cleared and wdsp initialization would happen when adsp/wdsp is down which would cause kernel panic. Reinit ready_compl flag when adsp/wdsp SSR happens. Change-Id: I45186abba7992ee6912c5b0da171ef37b04e2e71 Signed-off-by: Meng Wang --- asoc/codecs/wcd-dsp-mgr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd-dsp-mgr.c b/asoc/codecs/wcd-dsp-mgr.c index 7695b16a6dd5..b45a9b3b7516 100644 --- a/asoc/codecs/wcd-dsp-mgr.c +++ b/asoc/codecs/wcd-dsp-mgr.c @@ -802,6 +802,7 @@ static int wdsp_ssr_handler(struct wdsp_mgr_priv *wdsp, void *arg, __wdsp_clr_ready_locked(wdsp, WDSP_SSR_STATUS_WDSP_READY); wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_PRE_SHUTDOWN, NULL); + reinit_completion(&wdsp->ready_compl); schedule_work(&wdsp->ssr_work); break; @@ -818,7 +819,7 @@ static int wdsp_ssr_handler(struct wdsp_mgr_priv *wdsp, void *arg, WDSP_EVENT_PRE_SHUTDOWN, NULL); } - + reinit_completion(&wdsp->ready_compl); schedule_work(&wdsp->ssr_work); break; -- GitLab From 30765fcae378671743988f0dc002d0253bb2ad18 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Wed, 15 Aug 2018 18:13:19 -0700 Subject: [PATCH 0462/1645] ASoC: wcd934x-dsp-cntl: add debugfs node to perform debug dumps Currently, for any WDSP errors, the driver collects the debug dumps/information based on trigger from userspace. This is protected under CONFIG_DEBUG_FS and should not be run unless stress tests are executed and this functionality is explicitly enabled since performing debug dumps could possible leave the WDSP in bad state. Add debug node to control dumping debug information and not rely only on CONFIG_DEBUG_FS To enable debug dumps: echo 1 > /sys/kernel/debug/wdsp0/debug_dump_enable To disable debug dumps: echo 0 > /sys/kernel/debug/wdsp0/debug_dump_enable Change-Id: I67d8781839d9caee16e6bf6a5befd9010ccaafc0 Signed-off-by: Bhalchandra Gajare Signed-off-by: Xiaoyu Ye --- asoc/codecs/wcd934x/wcd934x-dsp-cntl.c | 20 +++++++++++++++----- asoc/codecs/wcd934x/wcd934x-dsp-cntl.h | 1 + 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c index de4f3997d476..f18cc81a91f8 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c @@ -757,7 +757,8 @@ static int wcd_cntl_do_boot(struct wcd_dsp_cntl *cntl) if (!ret) { dev_err(codec->dev, "%s: WDSP boot timed out\n", __func__); - wcd_cntl_collect_debug_dumps(cntl, true); + if (cntl->dbg_dmp_enable) + wcd_cntl_collect_debug_dumps(cntl, true); ret = -ETIMEDOUT; goto err_boot; } else { @@ -976,6 +977,8 @@ static void wcd_cntl_debugfs_init(char *dir, struct wcd_dsp_cntl *cntl) cntl->entry, &cntl->debug_mode); debugfs_create_bool("ramdump_enable", 0644, cntl->entry, &cntl->ramdump_enable); + debugfs_create_bool("debug_dump_enable", 0644, + cntl->entry, &cntl->dbg_dmp_enable); done: return; } @@ -1038,16 +1041,23 @@ static ssize_t wcd_miscdev_write(struct file *filep, const char __user *ubuf, } else if (val[0] == '0') { if (cntl->boot_reqs == 0) { dev_err(cntl->codec->dev, - "%s: WDSP already disabled\n", __func__); + "%s: WDSP already disabled\n", + __func__); ret = -EINVAL; goto done; } cntl->boot_reqs--; vote = false; } else if (!strcmp(val, "DEBUG_DUMP")) { - dev_dbg(cntl->codec->dev, - "%s: Collect dumps for debug use\n", __func__); - wcd_cntl_collect_debug_dumps(cntl, false); + if (cntl->dbg_dmp_enable) { + dev_dbg(cntl->codec->dev, + "%s: Collect dumps for debug use\n", __func__); + wcd_cntl_collect_debug_dumps(cntl, false); + } + /* + * simply ignore the request from userspace + * if dbg_dump_enable is not set from debugfs + */ goto done; } else { dev_err(cntl->codec->dev, "%s: Invalid value %s\n", diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h index 0127a0df2dba..5ce4fd85da13 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h @@ -91,6 +91,7 @@ struct wcd_dsp_cntl { struct dentry *entry; u32 debug_mode; bool ramdump_enable; + bool dbg_dmp_enable; /* WDSP manager drivers data */ struct device *m_dev; -- GitLab From 4b9d12f1e97c89827c8032bcd4e42546f9681ce9 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 18 Aug 2018 05:02:58 +0530 Subject: [PATCH 0463/1645] ASoC: wsa881x: Update temperature value during device down when wsa881x device is down, reading temperature from driver returns error. Instead of propagating the error, return the cached temperature value to the thermal framework to avoid iterative calls to read the temperature that results in excessive logging. Change-Id: I529c83eafec63004c2469bf16a0b53bd5accbdbb Signed-off-by: Sudheer Papothi --- asoc/codecs/wsa881x-temp-sensor.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/wsa881x-temp-sensor.c b/asoc/codecs/wsa881x-temp-sensor.c index b2ed963b7e22..2a1291f34f02 100644 --- a/asoc/codecs/wsa881x-temp-sensor.c +++ b/asoc/codecs/wsa881x-temp-sensor.c @@ -80,9 +80,11 @@ int wsa881x_get_temp(struct thermal_zone_device *thermal, if (pdata->wsa_temp_reg_read) { ret = pdata->wsa_temp_reg_read(codec, ®); if (ret) { - pr_err("%s: temperature register read failed: %d\n", - __func__, ret); - return ret; + pr_err("%s: temp read failed: %d, current temp: %d\n", + __func__, ret, pdata->curr_temp); + if (temp) + *temp = pdata->curr_temp; + return 0; } } else { pr_err("%s: wsa_temp_reg_read is NULL\n", __func__); -- GitLab From eb8d8cb1009cf82ef8835f9a31d1deac3a8b67bf Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 4 Aug 2018 04:52:51 +0530 Subject: [PATCH 0464/1645] ASoC: wcd937x-mbhc: Add support for headset moisture detection Add support for headset moisture detection on wcd937x codec. Change-Id: Ib9021869a5d3a0d4e5b8a912b235b68fad90f94f Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd937x/wcd937x-mbhc.c | 60 ++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index d1a36ba72de5..f83271b083e5 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -721,6 +721,63 @@ static void wcd937x_mbhc_moisture_config(struct wcd_mbhc *mbhc) 0x0C, mbhc->moist_rref << 2); } +static void wcd937x_mbhc_moisture_detect_en(struct wcd_mbhc *mbhc, bool enable) +{ + struct snd_soc_codec *codec = mbhc->codec; + + if (enable) + snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_2, + 0x0C, mbhc->moist_rref << 2); + else + snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); +} + +static bool wcd937x_mbhc_get_moisture_status(struct wcd_mbhc *mbhc) +{ + struct snd_soc_codec *codec = mbhc->codec; + bool ret = false; + + if ((mbhc->moist_rref == R_OFF) || + (mbhc->mbhc_cfg->enable_usbc_analog)) { + snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); + goto done; + } + + /* Do not enable moisture detection if jack type is NC */ + if (!mbhc->hphl_swh) { + dev_dbg(codec->dev, "%s: disable moisture detection for NC\n", + __func__); + snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); + goto done; + } + + /* If moisture_en is already enabled, then skip to plug type + * detection. + */ + if ((snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_2) & 0x0C)) + goto done; + + wcd937x_mbhc_moisture_detect_en(mbhc, true); + /* Read moisture comparator status */ + ret = ((snd_soc_read(codec, WCD937X_MBHC_NEW_FSM_STATUS) + & 0x20) ? 0 : 1); + +done: + return ret; + +} + +static void wcd937x_mbhc_moisture_polling_ctrl(struct wcd_mbhc *mbhc, + bool enable) +{ + snd_soc_update_bits(codec, + WCD937X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL, + 0x04, (enable << 2)); +} + static const struct wcd_mbhc_cb mbhc_cb = { .request_irq = wcd937x_mbhc_request_irq, .irq_control = wcd937x_mbhc_irq_control, @@ -742,6 +799,9 @@ static const struct wcd_mbhc_cb mbhc_cb = { .mbhc_gnd_det_ctrl = wcd937x_mbhc_gnd_det_ctrl, .hph_pull_down_ctrl = wcd937x_mbhc_hph_pull_down_ctrl, .mbhc_moisture_config = wcd937x_mbhc_moisture_config, + .mbhc_get_moisture_status = wcd937x_mbhc_get_moisture_status, + .mbhc_moisture_polling_ctrl = wcd937x_mbhc_moisture_polling_ctrl, + .mbhc_moisture_detect_en = wcd937x_mbhc_moisture_detect_en, }; static int wcd937x_get_hph_type(struct snd_kcontrol *kcontrol, -- GitLab From 06183689db23693ce74eee392675ff8cd160b37f Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Tue, 31 Jul 2018 00:31:14 -0700 Subject: [PATCH 0465/1645] soc: add support for SND event framework Add support for SND event framework for helping with notifications among different audio modules/drivers. The SND event framework functions with a master/client mechanism, where each client and the master register with the framework, and then notifies its own status (UP/DOWN). Each master will share a list of clients it is interested in, and once all the clients are registered and notified UP, the framework's state will be UP. On the other hand, as and when any one of the client, or the master reports its state as DOWN while the framework is UP, the framework state would be changed to DOWN, and all clients and the master would be let know about the change. Change-Id: Ief6f26c5d5626c29246472ad71c247d71ee9e92f Signed-off-by: Banajit Goswami --- include/soc/snd_event.h | 79 +++++++ soc/Android.mk | 10 + soc/Kbuild | 7 + soc/snd_event.c | 490 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 586 insertions(+) create mode 100644 include/soc/snd_event.h create mode 100644 soc/snd_event.c diff --git a/include/soc/snd_event.h b/include/soc/snd_event.h new file mode 100644 index 000000000000..af566735343e --- /dev/null +++ b/include/soc/snd_event.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _SND_EVENT_H_ +#define _SND_EVENT_H_ + +enum { + SND_EVENT_DOWN = 0, + SND_EVENT_UP, +}; + +struct snd_event_clients; + +struct snd_event_ops { + int (*enable)(struct device *dev, void *data); + void (*disable)(struct device *dev, void *data); +}; + +#ifdef CONFIG_SND_EVENT +int snd_event_client_register(struct device *dev, + const struct snd_event_ops *snd_ev_ops, + void *data); +int snd_event_client_deregister(struct device *dev); +int snd_event_master_register(struct device *dev, + const struct snd_event_ops *ops, + struct snd_event_clients *clients, + void *data); +int snd_event_master_deregister(struct device *dev); +int snd_event_notify(struct device *dev, unsigned int state); + +void snd_event_mstr_add_client(struct snd_event_clients **snd_clients, + int (*compare)(struct device *, void *), + void *data); +inline bool is_snd_event_fwk_enabled(void) +{ + return 1; +} +#else +int snd_event_client_register(struct device *dev, + const struct snd_event_ops *snd_ev_ops, + void *data) +{ + return 0; +} +int snd_event_client_deregister(struct device *dev) +{ + return 0; +} +int snd_event_master_register(struct device *dev, + const struct snd_event_ops *ops, + struct snd_event_clients *clients, + void *data) +{ + return 0; +} +int snd_event_master_deregister(struct device *dev) +{ + return 0; +} +int snd_event_notify(struct device *dev, unsigned int state) +{ + return 0; +} + +void snd_event_mstr_add_client(struct snd_event_clients **snd_clients, + int (*compare)(struct device *, void *), + void *data) +{ + return; +} +inline bool is_snd_event_fwk_enabled(void) +{ + return 0; +} + +#endif /* CONFIG_SND_EVENT */ +#endif /* _SND_EVENT_H_ */ diff --git a/soc/Android.mk b/soc/Android.mk index dc6a5b32f822..24016adacb63 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -82,6 +82,16 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### +ifeq ($(call is-board-platform-in-list, ),true) +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_snd_event.ko +LOCAL_MODULE_KBUILD_NAME := snd_event_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +endif +########################################################### endif # DLKM check endif # supported target check diff --git a/soc/Kbuild b/soc/Kbuild index 54ca077e4936..cb067bbb54a1 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -102,6 +102,10 @@ ifdef CONFIG_SOUNDWIRE SWR_OBJS += soundwire.o endif +ifdef CONFIG_SND_EVENT + SND_EVENT_OBJS += snd_event.o +endif + LINUX_INC += -Iinclude/linux INCS += $(COMMON_INC) \ @@ -149,6 +153,9 @@ pinctrl_lpi_dlkm-y := $(PINCTRL_LPI_OBJS) obj-$(CONFIG_SOUNDWIRE) += swr_dlkm.o swr_dlkm-y := $(SWR_OBJS) +obj-$(CONFIG_SND_EVENT) += snd_event_dlkm.o +snd_event_dlkm-y := $(SND_EVENT_OBJS) + obj-$(CONFIG_SOUNDWIRE_WCD_CTRL) += swr_ctrl_dlkm.o obj-$(CONFIG_SOUNDWIRE_MSTR_CTRL) += swr_ctrl_dlkm.o swr_ctrl_dlkm-y := $(SWR_CTRL_OBJS) diff --git a/soc/snd_event.c b/soc/snd_event.c new file mode 100644 index 000000000000..32407742b2a2 --- /dev/null +++ b/soc/snd_event.c @@ -0,0 +1,490 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include + +struct snd_event_client { + struct list_head node; + + struct device *dev; + const struct snd_event_ops *ops; + void *data; + + bool attached; + bool state; +}; + +struct snd_event_client_array { + struct device *dev; + struct snd_event_client *clnt; + void *data; + int (*compare)(struct device *, void *); +}; + +struct snd_event_clients { + size_t num_clients; + struct snd_event_client_array *cl_arr; +}; + +struct snd_master { + struct device *dev; + const struct snd_event_ops *ops; + void *data; + + bool state; + bool fwk_state; + bool clients_found; + struct snd_event_clients *clients; +}; + +static DEFINE_MUTEX(snd_event_mutex); +static LIST_HEAD(snd_event_client_list); +static struct snd_master *master; + +static struct snd_event_client *find_snd_event_client(struct device *dev) +{ + struct snd_event_client *c; + + list_for_each_entry(c, &snd_event_client_list, node) + if ((c->dev == dev) && c->ops) + return c; + + return NULL; +} + +static int check_and_update_fwk_state(void) +{ + bool new_fwk_state = true; + struct snd_event_client *c; + int ret = 0; + int i = 0; + + for (i = 0; i < master->clients->num_clients; i++) { + c = master->clients->cl_arr[i].clnt; + new_fwk_state &= c->state; + } + new_fwk_state &= master->state; + + if (master->fwk_state ^ new_fwk_state) { + if (new_fwk_state) { + for (i = 0; i < master->clients->num_clients; i++) { + c = master->clients->cl_arr[i].clnt; + if (c->ops->enable) { + ret = c->ops->enable(c->dev, c->data); + if (ret) { + dev_err(c->dev, + "%s: enable failed\n", + __func__); + goto dev_en_failed; + } + } + } + if (master->ops->enable) { + ret = master->ops->enable(master->dev, + master->data); + if (ret) { + dev_err(master->dev, + "%s: enable failed\n", + __func__); + goto mstr_en_failed; + } + } + } else { + if (master->ops->disable) + master->ops->disable(master->dev, + master->data); + for (i = 0; i < master->clients->num_clients; i++) { + c = master->clients->cl_arr[i].clnt; + if (c->ops->disable) + c->ops->disable(c->dev, c->data); + } + } + master->fwk_state = new_fwk_state; + } + goto exit; + +mstr_en_failed: + i = master->clients->num_clients; +dev_en_failed: + for (; i > 0; i--) { + c = master->clients->cl_arr[i - 1].clnt; + if (c->ops->disable) + c->ops->disable(c->dev, c->data); + } +exit: + return ret; +} + +static int snd_event_find_clients(struct snd_master *master) +{ + struct snd_event_clients *clients = master->clients; + int i = 0; + int ret = 0; + + for (i = 0; i < clients->num_clients; i++) { + struct snd_event_client_array *c_arr = &clients->cl_arr[i]; + struct snd_event_client *c; + + if (c_arr->dev) { + pr_err("%s: client already present dev=%pK\n", + __func__, c_arr->dev); + continue; + } + + list_for_each_entry(c, &snd_event_client_list, node) { + if (c->attached) + continue; + + if (c_arr->compare(c->dev, c_arr->data)) { + dev_dbg(master->dev, + "%s: found client, dev=%pK\n", + __func__, c->dev); + c_arr->dev = c->dev; + c_arr->clnt = c; + c->attached = true; + break; + } + } + if (!c_arr->dev) { + dev_dbg(master->dev, + "%s: failed to find some client\n", + __func__); + ret = -ENXIO; + break; + } + } + + return ret; +} + +/* + * snd_event_client_register - Register a client with the SND event FW + * + * @dev: Pointer to the "struct device" associated with the client + * @snd_ev_ops: Pointer to the snd_event_ops struct for the client containing + * callback functions + * @data: Pointer to any additional data that the caller wants to get back + * with callback functions + * + * Returns 0 on success or error on failure. + */ +int snd_event_client_register(struct device *dev, + const struct snd_event_ops *snd_ev_ops, + void *data) +{ + struct snd_event_client *c; + + if (!dev) { + pr_err("%s: dev is NULL\n", __func__); + return -EINVAL; + } + + c = kzalloc(sizeof(*c), GFP_KERNEL); + if (!c) + return -ENOMEM; + + c->dev = dev; + c->ops = snd_ev_ops; + c->data = data; + + dev_dbg(dev, "%s: adding client to SND event FW (ops %pK)\n", + __func__, snd_ev_ops); + + mutex_lock(&snd_event_mutex); + list_add_tail(&c->node, &snd_event_client_list); + + if (master && !master->clients_found) { + if (snd_event_find_clients(master)) { + dev_dbg(dev, "%s: Failed to find all clients\n", + __func__); + goto exit; + } + master->clients_found = true; + } + +exit: + mutex_unlock(&snd_event_mutex); + return 0; +} +EXPORT_SYMBOL(snd_event_client_register); + +/* + * snd_event_client_deregister - Remove a client from the SND event FW + * + * @dev: Pointer to the "struct device" associated with the client + * + * Returns 0 on success or error on failure. + */ +int snd_event_client_deregister(struct device *dev) +{ + struct snd_event_client *c; + int ret = 0; + int i = 0; + + if (!dev) { + pr_err("%s: dev is NULL\n", __func__); + return -EINVAL; + } + + mutex_lock(&snd_event_mutex); + if (list_empty(&snd_event_client_list)) { + dev_dbg(dev, "%s: No SND client registered\n", __func__); + ret = -ENODEV; + goto exit; + } + + c = find_snd_event_client(dev); + if (!c || (c->dev != dev)) { + dev_dbg(dev, "%s: No matching snd dev found\n", __func__); + ret = -ENODEV; + goto exit; + } + + c->state = false; + + if (master && master->clients_found) { + struct snd_event_client *d; + bool dev_found = false; + + for (i = 0; i < master->clients->num_clients; i++) { + d = master->clients->cl_arr[i].clnt; + if (c->dev == d->dev) { + dev_found = true; + break; + } + } + if (dev_found) { + ret = check_and_update_fwk_state(); + master->clients_found = false; + } + } + + list_del(&c->node); + kfree(c); +exit: + mutex_unlock(&snd_event_mutex); + return ret; +} +EXPORT_SYMBOL(snd_event_client_deregister); + +/* + * snd_event_mstr_add_client - Add a client to the master's list of clients + * + * @snd_clients: list of clients associated with this master + * @compare: Pointer to the compare callback function that master will use to + * confirm the clients + * @data: Address to any additional data that the master wants to get back with + * compare callback functions + */ +void snd_event_mstr_add_client(struct snd_event_clients **snd_clients, + int (*compare)(struct device *, void *), + void *data) +{ + struct snd_event_clients *client = *snd_clients; + + if (IS_ERR(client)) { + pr_err("%s: snd_clients is invalid\n", __func__); + return; + } + + if (!client) { + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client) { + *snd_clients = ERR_PTR(-ENOMEM); + return; + } + client->cl_arr = kzalloc(sizeof(struct snd_event_client_array), + GFP_KERNEL); + *snd_clients = client; + } else { + struct snd_event_client_array *new; + + new = krealloc(client->cl_arr, + (client->num_clients + 1) * sizeof(*new), + GFP_KERNEL | __GFP_ZERO); + if (!new) { + *snd_clients = ERR_PTR(-ENOMEM); + return; + } + client->cl_arr = new; + } + + client->cl_arr[client->num_clients].dev = NULL; + client->cl_arr[client->num_clients].data = data; + client->cl_arr[client->num_clients].compare = compare; + client->num_clients++; +} +EXPORT_SYMBOL(snd_event_mstr_add_client); + +/* + * snd_event_master_register - Register a master with the SND event FW + * + * @dev: Pointer to the "struct device" associated with the master + * @ops: Pointer to the snd_event_ops struct for the master containing + * callback functions + * @clients: List of clients for the master + * @data: Pointer to any additional data that the caller wants to get back + * with callback functions + * + * Returns 0 on success or error on failure. + * + * Prerequisite: + * clients list must not be empty. + * All clients for the master must have to be registered by calling + * snd_event_mstr_add_client() before calling this API to register a + * master with SND event fwk. + */ +int snd_event_master_register(struct device *dev, + const struct snd_event_ops *ops, + struct snd_event_clients *clients, + void *data) +{ + struct snd_master *new_master; + int ret = 0; + + if (!dev) { + pr_err("%s: dev is NULL\n", __func__); + return -EINVAL; + } + + mutex_lock(&snd_event_mutex); + if (master) { + dev_err(dev, "%s: master already allocated with %pK\n", + __func__, master->dev); + ret = -EALREADY; + goto exit; + } + mutex_unlock(&snd_event_mutex); + + if (!clients || IS_ERR(clients)) { + dev_err(dev, "%s: Invalid clients ptr\n", __func__); + return -EINVAL; + } + + new_master = kzalloc(sizeof(*new_master), GFP_KERNEL); + if (!new_master) + return -ENOMEM; + + new_master->dev = dev; + new_master->ops = ops; + new_master->data = data; + new_master->clients = clients; + + dev_dbg(dev, "adding master to SND event FW (ops %pK)\n", ops); + + mutex_lock(&snd_event_mutex); + + master = new_master; + + ret = snd_event_find_clients(master); + if (ret) { + dev_dbg(dev, "%s: Failed to find all clients\n", __func__); + ret = 0; + goto exit; + } + master->clients_found = true; + +exit: + mutex_unlock(&snd_event_mutex); + return ret; +} +EXPORT_SYMBOL(snd_event_master_register); + +/* + * snd_event_master_deregister - Remove a master from the SND event FW + * + * @dev: Pointer to the "struct device" associated with the master + * + * Returns 0 on success or error on failure. + */ +int snd_event_master_deregister(struct device *dev) +{ + int ret = 0; + + if (!dev) { + pr_err("%s: dev is NULL\n", __func__); + return -EINVAL; + } + + mutex_lock(&snd_event_mutex); + if (!master) { + dev_dbg(dev, "%s: No master found\n", __func__); + ret = -ENODEV; + goto exit; + } + + if (master->dev != dev) { + dev_dbg(dev, "%s: device is not a Master\n", __func__); + ret = -ENXIO; + goto exit; + } + + master->state = false; + + if (master && master->clients_found) + ret = check_and_update_fwk_state(); + + kfree(master->clients->cl_arr); + kfree(master->clients); + kfree(master); + master = NULL; +exit: + mutex_unlock(&snd_event_mutex); + return ret; +} +EXPORT_SYMBOL(snd_event_master_deregister); + +/* + * snd_event_notify - Update the state of the Master/client in the SND event FW + * + * @dev: Pointer to the "struct device" associated with the master/client + * @state: UP/DOWN state of the caller (master/client) + * + * Returns 0 on success or error on failure. + */ +int snd_event_notify(struct device *dev, unsigned int state) +{ + struct snd_event_client *c; + int ret = 0; + + if (!dev) { + pr_err("%s: dev is NULL\n", __func__); + return -EINVAL; + } + + mutex_lock(&snd_event_mutex); + if (list_empty(&snd_event_client_list) && !master) { + dev_err(dev, "%s: No device registered\n", __func__); + ret = -ENODEV; + goto exit; + } + + c = find_snd_event_client(dev); + if (!c && (!master || (master->dev != dev))) { + dev_err(dev, "%s: No snd dev entry found\n", __func__); + ret = -ENXIO; + goto exit; + } + + if (c) + c->state = !!state; + else + master->state = !!state; + + if (master && master->clients_found) + ret = check_and_update_fwk_state(); + +exit: + mutex_unlock(&snd_event_mutex); + return ret; +} +EXPORT_SYMBOL(snd_event_notify); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("SND event module"); -- GitLab From 40bdd6b55a537933bb5d32c7b4d2551f326f1a7f Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Fri, 20 Jul 2018 19:24:54 -0700 Subject: [PATCH 0466/1645] ipc: apr: add support for SSR handing using SND event FWK Add support for SSR/PDR notification handling using SND event framework. Change-Id: I2d147738c3ba2b498b0ce9824201adce71689e2d Signed-off-by: Banajit Goswami --- ipc/apr.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/ipc/apr.c b/ipc/apr.c index ff393e372869..373c235e0f33 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -281,9 +282,19 @@ int apr_set_q6_state(enum apr_subsys_state state) } EXPORT_SYMBOL(apr_set_q6_state); +static void apr_ssr_disable(struct device *dev, void *data) +{ + apr_set_q6_state(APR_SUBSYS_DOWN); +} + +static const struct snd_event_ops apr_ssr_ops = { + .disable = apr_ssr_disable, +}; + static void apr_adsp_down(unsigned long opcode) { pr_info("%s: Q6 is Down\n", __func__); + snd_event_notify(apr_priv->dev, SND_EVENT_DOWN); apr_set_q6_state(APR_SUBSYS_DOWN); dispatch_event(opcode, APR_DEST_QDSP6); } @@ -308,6 +319,7 @@ static void apr_adsp_up(void) if (apr_priv->is_initial_boot) schedule_work(&apr_priv->add_chld_dev_work); spin_unlock(&apr_priv->apr_lock); + snd_event_notify(apr_priv->dev, SND_EVENT_UP); } int apr_load_adsp_image(void) @@ -1186,11 +1198,20 @@ static int apr_probe(struct platform_device *pdev) } apr_tal_init(); + + ret = snd_event_client_register(&pdev->dev, &apr_ssr_ops, NULL); + if (ret) { + pr_err("%s: Registration with Audio SSR FW failed ret = %d\n", + __func__, ret); + ret = 0; + } + return apr_debug_init(); } static int apr_remove(struct platform_device *pdev) { + snd_event_client_deregister(&pdev->dev); apr_cleanup(); apr_tal_exit(); apr_priv = NULL; -- GitLab From 09618575ad109c7a2e04121b6002399f8a17c94b Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Fri, 20 Jul 2018 19:25:52 -0700 Subject: [PATCH 0467/1645] dsp: q6core: add support for SSR handling with SND event FWK Add support for SSR/PDR event handling using SND event framework. Change-Id: Ia80c0bc7b99866fbb5c0b8c8ee7cdadeeb0fb0e9 Signed-off-by: Banajit Goswami --- dsp/q6core.c | 95 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 79 insertions(+), 16 deletions(-) diff --git a/dsp/q6core.c b/dsp/q6core.c index b94d264ff415..5160c3dc9c1f 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "adsp_err.h" @@ -79,6 +80,7 @@ struct q6core_str { struct cal_type_data *cal_data[CORE_MAX_CAL]; uint32_t mem_map_cal_handle; int32_t adsp_status; + int32_t avs_state; struct q6core_avcs_ver_info q6core_avcs_ver_info; }; @@ -1448,50 +1450,111 @@ static int q6core_init_cal_data(void) return ret; } -static int q6core_probe(struct platform_device *pdev) +static int q6core_is_avs_up(int32_t *avs_state) { unsigned long timeout; - int adsp_ready = 0, rc; + int32_t adsp_ready = 0; + int ret = 0; timeout = jiffies + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); do { - if (!adsp_ready) { - adsp_ready = q6core_is_adsp_ready(); - dev_dbg(&pdev->dev, "%s: ADSP Audio is %s\n", __func__, - adsp_ready ? "ready" : "not ready"); - } + adsp_ready = q6core_is_adsp_ready(); + pr_debug("%s: ADSP Audio is %s\n", __func__, + adsp_ready ? "ready" : "not ready"); if (adsp_ready) break; /* - * ADSP will be coming up after loading (PD up event) and - * it might not be fully up when the control reaches - * here. So, wait for 50msec before checking ADSP state + * ADSP will be coming up after boot up and AVS might + * not be fully up when the control reaches here. + * So, wait for 50msec before checking ADSP state again. */ msleep(50); } while (time_after(timeout, jiffies)); + *avs_state = adsp_ready; + pr_debug("%s: ADSP Audio is %s\n", __func__, + adsp_ready ? "ready" : "not ready"); + if (!adsp_ready) { - dev_err(&pdev->dev, "%s: Timeout. ADSP Audio is %s\n", - __func__, - adsp_ready ? "ready" : "not ready"); - return -ETIMEDOUT; + pr_err_ratelimited("%s: Timeout. ADSP Audio is not ready\n", + __func__); + ret = -ETIMEDOUT; + } + + return ret; +} + +static int q6core_ssr_enable(struct device *dev, void *data) +{ + int32_t avs_state = 0; + int ret = 0; + + if (!dev) { + pr_err("%s: dev is NULL\n", __func__); + return -EINVAL; } + + if (!q6core_lcl.avs_state) { + ret = q6core_is_avs_up(&avs_state); + if (ret < 0) + goto err; + q6core_lcl.avs_state = avs_state; + } + +err: + return ret; +} + +static void q6core_ssr_disable(struct device *dev, void *data) +{ + /* Reset AVS state to 0 */ + q6core_lcl.avs_state = 0; +} + +static const struct snd_event_ops q6core_ssr_ops = { + .enable = q6core_ssr_enable, + .disable = q6core_ssr_disable, +}; + +static int q6core_probe(struct platform_device *pdev) +{ + int32_t avs_state = 0; + int rc = 0; + + rc = q6core_is_avs_up(&avs_state); + if (rc < 0) + goto err; + q6core_lcl.avs_state = avs_state; + rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); if (rc) { dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n", __func__, rc); - return -EINVAL; + rc = -EINVAL; + goto err; } dev_dbg(&pdev->dev, "%s: added child node\n", __func__); - return 0; + rc = snd_event_client_register(&pdev->dev, &q6core_ssr_ops, NULL); + if (!rc) { + snd_event_notify(&pdev->dev, SND_EVENT_UP); + } else { + dev_err(&pdev->dev, + "%s: Registration with SND event fwk failed rc = %d\n", + __func__, rc); + rc = 0; + } + +err: + return rc; } static int q6core_remove(struct platform_device *pdev) { + snd_event_client_deregister(&pdev->dev); of_platform_depopulate(&pdev->dev); return 0; } -- GitLab From 57245da21e8e68709509df27130b30ec8648ac0a Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Fri, 20 Jul 2018 19:26:57 -0700 Subject: [PATCH 0468/1645] asoc: wcd934x: add support for SSR handling using SND event FWK Add support for SSR/PDR handling using SND event framework. Change-Id: Ia96858ed6dc43cbb80d01a7797abb57442813d3b Signed-off-by: Banajit Goswami --- asoc/codecs/wcd934x/wcd934x.c | 42 +++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 4f28ae99c344..49c17c41e4b9 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -9979,6 +9980,7 @@ static int tavil_device_down(struct wcd9xxx *wcd9xxx) priv = snd_soc_codec_get_drvdata(codec); for (count = 0; count < NUM_CODEC_DAIS; count++) priv->dai[count].bus_down_in_recovery = true; + snd_event_notify(priv->dev->parent, SND_EVENT_DOWN); priv->mbhc->wcd_mbhc.deinit_in_progress = true; if (delayed_work_pending(&priv->spk_anc_dwork.dwork)) @@ -10006,7 +10008,8 @@ static int tavil_device_down(struct wcd9xxx *wcd9xxx) swrm_wcd_notify(priv->swr.ctrl_data[0].swr_pdev, SWR_DEVICE_DOWN, NULL); tavil_dsd_reset(priv->dsd_config); - snd_soc_card_change_online_state(codec->component.card, 0); + if (!is_snd_event_fwk_enabled()) + snd_soc_card_change_online_state(codec->component.card, 0); wcd_dsp_ssr_event(priv->wdsp_cntl, WCD_CDC_DOWN_EVENT); wcd_resmgr_set_sido_input_src_locked(priv->resmgr, SIDO_SOURCE_INTERNAL); @@ -10039,7 +10042,8 @@ static int tavil_post_reset_cb(struct wcd9xxx *wcd9xxx) tavil_slimbus_slave_port_cfg.slave_dev_pgd_la = control->slim->laddr; tavil_init_slim_slave_cfg(codec); - snd_soc_card_change_online_state(codec->component.card, 1); + if (!is_snd_event_fwk_enabled()) + snd_soc_card_change_online_state(codec->component.card, 1); for (i = 0; i < TAVIL_MAX_MICBIAS; i++) tavil->micb_ref[i] = 0; @@ -10102,6 +10106,7 @@ static int tavil_post_reset_cb(struct wcd9xxx *wcd9xxx) */ tavil_vote_svs(tavil, false); wcd_dsp_ssr_event(tavil->wdsp_cntl, WCD_CDC_UP_EVENT); + snd_event_notify(tavil->dev->parent, SND_EVENT_UP); done: mutex_unlock(&tavil->codec_mutex); @@ -10900,6 +10905,28 @@ struct wcd_dsp_cntl *tavil_get_wcd_dsp_cntl(struct device *dev) } EXPORT_SYMBOL(tavil_get_wcd_dsp_cntl); +static void wcd934x_ssr_disable(struct device *dev, void *data) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(dev); + struct tavil_priv *tavil; + struct snd_soc_codec *codec; + int count = 0; + + if (!wcd9xxx) { + dev_dbg(dev, "%s: wcd9xxx pointer NULL.\n", __func__); + return; + } + codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); + tavil = snd_soc_codec_get_drvdata(codec); + + for (count = 0; count < NUM_CODEC_DAIS; count++) + tavil->dai[count].bus_down_in_recovery = true; +} + +static const struct snd_event_ops wcd934x_ssr_ops = { + .disable = wcd934x_ssr_disable, +}; + static int tavil_probe(struct platform_device *pdev) { int ret = 0; @@ -11024,6 +11051,15 @@ static int tavil_probe(struct platform_device *pdev) } schedule_work(&tavil->tavil_add_child_devices_work); + ret = snd_event_client_register(pdev->dev.parent, &wcd934x_ssr_ops, NULL); + if (!ret) { + snd_event_notify(pdev->dev.parent, SND_EVENT_UP); + } else { + pr_err("%s: Registration with SND event fwk failed ret = %d\n", + __func__, ret); + ret = 0; + } + return ret; err_cdc_reg: @@ -11057,6 +11093,8 @@ static int tavil_remove(struct platform_device *pdev) tavil->dsd_config = NULL; } + snd_event_client_deregister(pdev->dev.parent); + if (tavil->spi) spi_unregister_device(tavil->spi); for (count = 0; count < tavil->child_count && -- GitLab From c366b45381b71bd049522447d295befa2f808d0f Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Wed, 22 Aug 2018 17:53:25 -0700 Subject: [PATCH 0469/1645] ipc: fix error message to reflect the correct error Fix error message when registration with SND event fwk fails, to reflect the correct information. Change-Id: I15133557666ff1b83073e1ce26ee9c4f1b4441ae Signed-off-by: Banajit Goswami --- ipc/apr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipc/apr.c b/ipc/apr.c index 373c235e0f33..990a1032719c 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -1201,7 +1201,7 @@ static int apr_probe(struct platform_device *pdev) ret = snd_event_client_register(&pdev->dev, &apr_ssr_ops, NULL); if (ret) { - pr_err("%s: Registration with Audio SSR FW failed ret = %d\n", + pr_err("%s: Registration with SND event fwk failed ret = %d\n", __func__, ret); ret = 0; } -- GitLab From b2438de066578c66c5a3d60eab03f85285e1441d Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Thu, 16 Aug 2018 21:38:15 +0530 Subject: [PATCH 0470/1645] asoc: qcs405: add missing dai links Add WCN dai links for enabling BT use cases. Change-Id: I1de1de0d9de0115d89e6a10f79a2cbf0a54d0e44 Signed-off-by: Mangesh Kunchamwar --- asoc/qcs405.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 6697859002b0..b075a21a33ed 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -7566,7 +7566,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) int total_links = 0; uint32_t tasha_codec = 0, auxpcm_audio_intf = 0; uint32_t va_bolero_codec = 0, wsa_bolero_codec = 0, mi2s_audio_intf = 0; - uint32_t spdif_audio_intf = 0; + uint32_t spdif_audio_intf = 0, wcn_audio_intf = 0; const struct of_device_id *match; char __iomem *spdif_cfg, *spdif_pin_ctl; int rc = 0; @@ -7710,6 +7710,20 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) iowrite32(0x2220, spdif_pin_ctl); } } + rc = of_property_read_u32(dev->of_node, "qcom,wcn-btfm", + &wcn_audio_intf); + if (rc) { + dev_dbg(dev, "%s: No DT match WCN audio interface\n", + __func__); + } else { + if (wcn_audio_intf) { + memcpy(msm_qcs405_dai_links + total_links, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + total_links += + ARRAY_SIZE(msm_wcn_be_dai_links); + } + } dailink = msm_qcs405_dai_links; } else if (!strcmp(match->data, "stub_codec")) { card = &snd_soc_card_stub_msm; -- GitLab From 654b06b0ef1f3898c6811aa3c7f83db54af25e88 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Thu, 2 Aug 2018 20:29:47 +0530 Subject: [PATCH 0471/1645] asoc: routing: sound tracking updates for qcs405 Add support for codec dma interface to sound tracking mixer control. Change-Id: Ic8296e61d14526469c62a709f19c6357b3ada8d6 Signed-off-by: Mangesh Kunchamwar --- asoc/msm-pcm-routing-v2.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index e67224e0b2e5..bb10858de749 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -17014,6 +17014,9 @@ static int msm_audio_sound_focus_derive_port_id(struct snd_kcontrol *kcontrol, } else if (!strcmp(kcontrol->id.name + strlen(prefix), "INT3_MI2S")) { *port_id = AFE_PORT_ID_INT3_MI2S_TX; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "VA_CDC_DMA_TX_0")) { + *port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0; } else { pr_err("%s: mixer ctl name=%s, could not derive valid port id\n", __func__, kcontrol->id.name); @@ -17248,6 +17251,36 @@ static const struct snd_kcontrol_new msm_source_tracking_controls[] = { .info = msm_source_tracking_info, .get = msm_audio_source_tracking_get, }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx VA_CDC_DMA_TX_0", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx VA_CDC_DMA_TX_0", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx VA_CDC_DMA_TX_0", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx VA_CDC_DMA_TX_0", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, }; static int spkr_prot_put_vi_lch_port(struct snd_kcontrol *kcontrol, -- GitLab From 54ca7d1b91d921194f72163eed71376c0c228779 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 8 Aug 2018 13:59:54 +0530 Subject: [PATCH 0472/1645] asoc: Add hostless entries in routing driver Add hostless nodes for RX_CDC_DMA_RX_0 and TX_CDC_DMA_TX_3 interfaces to support HFP/FM use cases. Add missing port-ids in afe driver. CRs-Fixed: 2281591 Change-Id: I634a6970b7c47320120cb850ad94bd69376ac181 Signed-off-by: Aditya Bavanari --- asoc/msm-dai-fe.c | 23 +++++++++++++++++++++ asoc/msm-pcm-routing-v2.c | 35 ++++++++++++++++++++++++++++++++ dsp/q6afe.c | 42 +++++++++++++++++++++++++++++++++++++++ dsp/q6audio-v2.c | 28 +++++++++++++------------- 4 files changed, 114 insertions(+), 14 deletions(-) diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index c352cb379cb4..40613a74e881 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -575,6 +575,29 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "CDC_DMA_HOSTLESS", .probe = fe_dai_probe, }, + { + .capture = { + .stream_name = "TX3_CDC_DMA_HOSTLESS Capture", + .aif_name = "TX3_CDC_DMA_UL_HL", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_dai_ops, + .name = "TX3_CDC_DMA_HOSTLESS", + .probe = fe_dai_probe, + }, { .playback = { .stream_name = "INT_FM_HOSTLESS Playback", diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index e67224e0b2e5..39cfd4b2e281 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -17528,6 +17528,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("CDC_DMA_UL_HL", "CDC_DMA_HOSTLESS Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TX3_CDC_DMA_UL_HL", + "TX3_CDC_DMA_HOSTLESS Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("CPE_LSM_UL_HL", "CPE LSM capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("SLIM1_DL_HL", "SLIMBUS1_HOSTLESS Playback", @@ -18274,6 +18276,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &a2dp_slim7_switch_mixer_controls), SND_SOC_DAPM_SWITCH("WSA_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, &cdc_dma_fm_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("RX_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, + &cdc_dma_fm_switch_mixer_controls), /* Mixer definitions */ SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0, @@ -18575,6 +18579,14 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_NOPM, 0, 0, quat_tdm_rx_2_voice_mixer_controls, ARRAY_SIZE(quat_tdm_rx_2_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0_Voice Mixer", + SND_SOC_NOPM, 0, 0, + wsa_cdc_dma_rx_0_voice_mixer_controls, + ARRAY_SIZE(wsa_cdc_dma_rx_0_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0_Voice Mixer", + SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_0_voice_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_0_voice_mixer_controls)), SND_SOC_DAPM_MIXER("Voip_Tx Mixer", SND_SOC_NOPM, 0, 0, tx_voip_mixer_controls, ARRAY_SIZE(tx_voip_mixer_controls)), @@ -20826,6 +20838,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_Voice Mixer"}, + {"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0_Voice Mixer"}, + + {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0_Voice Mixer"}, + {"VOC_EXT_EC MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"VOC_EXT_EC MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"VOC_EXT_EC MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, @@ -20966,6 +20986,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode1_Tx Mixer", "QUAT_AUX_PCM_TX_MMode1", "QUAT_AUX_PCM_TX"}, {"VoiceMMode1_Tx Mixer", "QUIN_AUX_PCM_TX_MMode1", "QUIN_AUX_PCM_TX"}, {"VoiceMMode1_Tx Mixer", "QUAT_TDM_TX_0_MMode1", "QUAT_TDM_TX_0"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_0_MMode1", "TX_CDC_DMA_TX_0"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_1_MMode1", "TX_CDC_DMA_TX_1"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_2_MMode1", "TX_CDC_DMA_TX_2"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_3_MMode1", "TX_CDC_DMA_TX_3"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_4_MMode1", "TX_CDC_DMA_TX_4"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_5_MMode1", "TX_CDC_DMA_TX_5"}, {"VOICEMMODE1_UL", NULL, "VoiceMMode1_Tx Mixer"}, {"VoiceMMode2_Tx Mixer", "PRI_TX_MMode2", "PRI_I2S_TX"}, @@ -20984,6 +21010,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode2_Tx Mixer", "TERT_AUX_PCM_TX_MMode2", "TERT_AUX_PCM_TX"}, {"VoiceMMode2_Tx Mixer", "QUAT_AUX_PCM_TX_MMode2", "QUAT_AUX_PCM_TX"}, {"VoiceMMode2_Tx Mixer", "QUIN_AUX_PCM_TX_MMode2", "QUIN_AUX_PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_0_MMode2", "TX_CDC_DMA_TX_0"}, + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_1_MMode2", "TX_CDC_DMA_TX_1"}, + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_2_MMode2", "TX_CDC_DMA_TX_2"}, + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_3_MMode2", "TX_CDC_DMA_TX_3"}, + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_4_MMode2", "TX_CDC_DMA_TX_4"}, + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_5_MMode2", "TX_CDC_DMA_TX_5"}, {"VOICEMMODE2_UL", NULL, "VoiceMMode2_Tx Mixer"}, {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"}, @@ -21022,6 +21054,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"WSA_CDC_DMA_RX_0_DL_HL", "Switch", "CDC_DMA_DL_HL"}, {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0_DL_HL"}, {"CDC_DMA_UL_HL", NULL, "VA_CDC_DMA_TX_0"}, + {"RX_CDC_DMA_RX_0_DL_HL", "Switch", "CDC_DMA_DL_HL"}, + {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0_DL_HL"}, + {"TX3_CDC_DMA_UL_HL", NULL, "TX_CDC_DMA_TX_3"}, {"LSM1 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, {"LSM1 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, {"LSM1 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, diff --git a/dsp/q6afe.c b/dsp/q6afe.c index b2d43bd0f994..3fbbbbc3f8b3 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -4453,6 +4453,34 @@ int afe_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_1; case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: return IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_2; + case AFE_PORT_ID_RX_CODEC_DMA_RX_0: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_0; + case AFE_PORT_ID_TX_CODEC_DMA_TX_0: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_0; + case AFE_PORT_ID_RX_CODEC_DMA_RX_1: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_1; + case AFE_PORT_ID_TX_CODEC_DMA_TX_1: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_1; + case AFE_PORT_ID_RX_CODEC_DMA_RX_2: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_2; + case AFE_PORT_ID_TX_CODEC_DMA_TX_2: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_2; + case AFE_PORT_ID_RX_CODEC_DMA_RX_3: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_3; + case AFE_PORT_ID_TX_CODEC_DMA_TX_3: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_3; + case AFE_PORT_ID_RX_CODEC_DMA_RX_4: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_4; + case AFE_PORT_ID_TX_CODEC_DMA_TX_4: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_4; + case AFE_PORT_ID_RX_CODEC_DMA_RX_5: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_5; + case AFE_PORT_ID_TX_CODEC_DMA_TX_5: + return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_5; + case AFE_PORT_ID_RX_CODEC_DMA_RX_6: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_6; + case AFE_PORT_ID_RX_CODEC_DMA_RX_7: + return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_7; default: pr_err("%s: port 0x%x\n", __func__, port_id); return -EINVAL; @@ -6580,6 +6608,20 @@ int afe_validate_port(u16 port_id) case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: case AFE_PORT_ID_VA_CODEC_DMA_TX_0: case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + case AFE_PORT_ID_RX_CODEC_DMA_RX_0: + case AFE_PORT_ID_TX_CODEC_DMA_TX_0: + case AFE_PORT_ID_RX_CODEC_DMA_RX_1: + case AFE_PORT_ID_TX_CODEC_DMA_TX_1: + case AFE_PORT_ID_RX_CODEC_DMA_RX_2: + case AFE_PORT_ID_TX_CODEC_DMA_TX_2: + case AFE_PORT_ID_RX_CODEC_DMA_RX_3: + case AFE_PORT_ID_TX_CODEC_DMA_TX_3: + case AFE_PORT_ID_RX_CODEC_DMA_RX_4: + case AFE_PORT_ID_TX_CODEC_DMA_TX_4: + case AFE_PORT_ID_RX_CODEC_DMA_RX_5: + case AFE_PORT_ID_TX_CODEC_DMA_TX_5: + case AFE_PORT_ID_RX_CODEC_DMA_RX_6: + case AFE_PORT_ID_RX_CODEC_DMA_RX_7: { ret = 0; break; diff --git a/dsp/q6audio-v2.c b/dsp/q6audio-v2.c index 00732f3d75be..3108c042dd02 100644 --- a/dsp/q6audio-v2.c +++ b/dsp/q6audio-v2.c @@ -655,33 +655,33 @@ int q6audio_get_port_id(u16 port_id) case AFE_PORT_ID_VA_CODEC_DMA_TX_1: return AFE_PORT_ID_VA_CODEC_DMA_TX_1; case AFE_PORT_ID_RX_CODEC_DMA_RX_0: - return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_0; + return AFE_PORT_ID_RX_CODEC_DMA_RX_0; case AFE_PORT_ID_TX_CODEC_DMA_TX_0: - return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_0; + return AFE_PORT_ID_TX_CODEC_DMA_TX_0; case AFE_PORT_ID_RX_CODEC_DMA_RX_1: - return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_1; + return AFE_PORT_ID_RX_CODEC_DMA_RX_1; case AFE_PORT_ID_TX_CODEC_DMA_TX_1: - return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_1; + return AFE_PORT_ID_TX_CODEC_DMA_TX_1; case AFE_PORT_ID_RX_CODEC_DMA_RX_2: - return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_2; + return AFE_PORT_ID_RX_CODEC_DMA_RX_2; case AFE_PORT_ID_TX_CODEC_DMA_TX_2: - return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_2; + return AFE_PORT_ID_TX_CODEC_DMA_TX_2; case AFE_PORT_ID_RX_CODEC_DMA_RX_3: - return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_3; + return AFE_PORT_ID_RX_CODEC_DMA_RX_3; case AFE_PORT_ID_TX_CODEC_DMA_TX_3: - return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_3; + return AFE_PORT_ID_TX_CODEC_DMA_TX_3; case AFE_PORT_ID_RX_CODEC_DMA_RX_4: - return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_4; + return AFE_PORT_ID_RX_CODEC_DMA_RX_4; case AFE_PORT_ID_TX_CODEC_DMA_TX_4: - return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_4; + return AFE_PORT_ID_TX_CODEC_DMA_TX_4; case AFE_PORT_ID_RX_CODEC_DMA_RX_5: - return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_5; + return AFE_PORT_ID_RX_CODEC_DMA_RX_5; case AFE_PORT_ID_TX_CODEC_DMA_TX_5: - return IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_5; + return AFE_PORT_ID_TX_CODEC_DMA_TX_5; case AFE_PORT_ID_RX_CODEC_DMA_RX_6: - return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_6; + return AFE_PORT_ID_RX_CODEC_DMA_RX_6; case AFE_PORT_ID_RX_CODEC_DMA_RX_7: - return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_7; + return AFE_PORT_ID_RX_CODEC_DMA_RX_7; default: pr_warn("%s: Invalid port_id %d\n", __func__, port_id); return -EINVAL; -- GitLab From 67ef04b0ba81b88bb361e73335dde6aa2ae92bc6 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 21 Aug 2018 16:06:57 +0530 Subject: [PATCH 0473/1645] asoc: Add changes to support AFE loopback Add port mixer controls corresponding to WSA_CDC_DMA_RX_0 and RX_CDC_DMA_RX_0 to support AFE loopback. Change-Id: I6e0e19fe45bd6c6060c842d1ed5073de6f4f6ef5 Signed-off-by: Aditya Bavanari --- asoc/msm-pcm-routing-v2.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 39cfd4b2e281..4f0ea8343f9c 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -13287,6 +13287,24 @@ static const struct snd_kcontrol_new int4_mi2s_rx_port_mixer_controls[] = { msm_routing_put_port_mixer), }; +static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_port_mixer_controls[] = { + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_0_port_mixer_controls[] = { + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_RX, @@ -16247,7 +16265,12 @@ static const struct snd_kcontrol_new slim4_fm_switch_mixer_controls = 0, 1, 0, msm_routing_get_switch_mixer, msm_routing_put_switch_mixer); -static const struct snd_kcontrol_new cdc_dma_fm_switch_mixer_controls = +static const struct snd_kcontrol_new cdc_dma_wsa_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new cdc_dma_rx_switch_mixer_controls = SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, 0, 1, 0, msm_routing_get_switch_mixer, msm_routing_put_switch_mixer); @@ -18275,9 +18298,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_SWITCH("A2DP_SLIM7_UL_HL", SND_SOC_NOPM, 0, 0, &a2dp_slim7_switch_mixer_controls), SND_SOC_DAPM_SWITCH("WSA_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, - &cdc_dma_fm_switch_mixer_controls), + &cdc_dma_wsa_switch_mixer_controls), SND_SOC_DAPM_SWITCH("RX_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, - &cdc_dma_fm_switch_mixer_controls), + &cdc_dma_rx_switch_mixer_controls), /* Mixer definitions */ SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0, @@ -18757,6 +18780,12 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("INT4_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, int4_mi2s_rx_port_mixer_controls, ARRAY_SIZE(int4_mi2s_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, + wsa_cdc_dma_rx_0_port_mixer_controls, + ARRAY_SIZE(wsa_cdc_dma_rx_0_port_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_0_port_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_0_port_mixer_controls)), SND_SOC_DAPM_MIXER("QCHAT_Tx Mixer", SND_SOC_NOPM, 0, 0, tx_qchat_mixer_controls, ARRAY_SIZE(tx_qchat_mixer_controls)), @@ -21723,6 +21752,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"INT4_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX Port Mixer"}, + {"WSA_CDC_DMA_RX_0 Port Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"WSA_CDC_DMA_RX_0 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"RX_CDC_DMA_RX_0 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"SLIMBUS_0_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, -- GitLab From 61e56a95a3149bb475b9eeb075d7f616fdd7b95c Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 21 Jun 2018 14:53:21 -0700 Subject: [PATCH 0474/1645] dsp: asm: initialize variables before use Initialize flag variables before use in spinlocks. CRs-Fixed: 2257317 Change-Id: I8b5973c1dfe3c7266a71d4e8ef4d5884b685ae5d Signed-off-by: Vignesh Kulothungan --- dsp/q6asm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index db95d3b50927..faedfc1b5cbf 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1638,7 +1638,7 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) uint32_t dir = 0; uint32_t i = IN; uint32_t *payload; - unsigned long dsp_flags; + unsigned long dsp_flags = 0; unsigned long flags = 0; struct asm_buffer_node *buf_node = NULL; struct list_head *ptr, *next; @@ -1855,7 +1855,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) { int i = 0; struct audio_client *ac = (struct audio_client *)priv; - unsigned long dsp_flags; + unsigned long dsp_flags = 0; uint32_t *payload; uint32_t wakeup_flag = 1; int32_t ret = 0; -- GitLab From c65c7e4e60209c6117daa139aff56350085a97a4 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 8 Aug 2018 14:10:20 +0530 Subject: [PATCH 0475/1645] asoc: sm6150: Add hostless DAIs to support fm/hfp usecases Add playback and capture hostless DAIs in common fe dai links to support fm and hfp use cases. CRs-Fixed: 2281591 Change-Id: I63b86d0de286b0c06c0be4b7c4976cd683c80b3c Signed-off-by: Aditya Bavanari --- asoc/sm6150.c | 121 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 77 insertions(+), 44 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 8d9d32dc283e..40a9fd81e0fd 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -4390,7 +4390,8 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1: case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2: case MSM_BACKEND_DAI_TX_CDC_DMA_TX_0: - case MSM_BACKEND_DAI_TX_CDC_DMA_TX_1: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_3: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_4: idx = msm_cdc_dma_get_idx_from_beid(dai_link->id); param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, cdc_dma_tx_cfg[idx].bit_format); @@ -5118,7 +5119,8 @@ static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream, case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1: case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2: case MSM_BACKEND_DAI_TX_CDC_DMA_TX_0: - case MSM_BACKEND_DAI_TX_CDC_DMA_TX_1: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_3: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_4: { ch_id = msm_cdc_dma_get_idx_from_beid(dai_link->id); pr_debug("%s: id %d tx_ch=%d\n", __func__, @@ -5846,7 +5848,7 @@ static struct snd_soc_ops msm_wcn_ops = { /* Digital audio interface glue - connects codec <---> CPU */ static struct snd_soc_dai_link msm_common_dai_links[] = { /* FrontEnd DAI Links */ - { + {/* hw:x,0 */ .name = MSM_DAILINK_NAME(Media1), .stream_name = "MultiMedia1", .cpu_dai_name = "MultiMedia1", @@ -5864,7 +5866,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA1 }, - { + {/* hw:x,1 */ .name = MSM_DAILINK_NAME(Media2), .stream_name = "MultiMedia2", .cpu_dai_name = "MultiMedia2", @@ -5881,7 +5883,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA2, }, - { + {/* hw:x,2 */ .name = "VoiceMMode1", .stream_name = "VoiceMMode1", .cpu_dai_name = "VoiceMMode1", @@ -5898,7 +5900,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_VOICEMMODE1, }, - { + {/* hw:x,3 */ .name = "MSM VoIP", .stream_name = "VoIP", .cpu_dai_name = "VoIP", @@ -5915,7 +5917,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_VOIP, }, - { + {/* hw:x,4 */ .name = MSM_DAILINK_NAME(ULL), .stream_name = "MultiMedia3", .cpu_dai_name = "MultiMedia3", @@ -5933,7 +5935,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .id = MSM_FRONTEND_DAI_MULTIMEDIA3, }, /* Hostless PCM purpose */ - { + {/* hw:x,5 */ .name = "SLIMBUS_0 Hostless", .stream_name = "SLIMBUS_0 Hostless", .cpu_dai_name = "SLIMBUS0_HOSTLESS", @@ -5950,7 +5952,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, - { + {/* hw:x,6 */ .name = "MSM AFE-PCM RX", .stream_name = "AFE-PROXY RX", .cpu_dai_name = "msm-dai-q6-dev.241", @@ -5962,7 +5964,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { /* this dainlink has playback support */ .ignore_pmdown_time = 1, }, - { + {/* hw:x,7 */ .name = "MSM AFE-PCM TX", .stream_name = "AFE-PROXY TX", .cpu_dai_name = "msm-dai-q6-dev.240", @@ -5972,7 +5974,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .dpcm_capture = 1, .ignore_suspend = 1, }, - { + {/* hw:x,8 */ .name = MSM_DAILINK_NAME(Compress1), .stream_name = "Compress1", .cpu_dai_name = "MultiMedia4", @@ -5990,7 +5992,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { /* this dainlink has playback support */ .id = MSM_FRONTEND_DAI_MULTIMEDIA4, }, - { + {/* hw:x,9 */ .name = "AUXPCM Hostless", .stream_name = "AUXPCM Hostless", .cpu_dai_name = "AUXPCM_HOSTLESS", @@ -6007,7 +6009,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, - { + {/* hw:x,10 */ .name = "SLIMBUS_1 Hostless", .stream_name = "SLIMBUS_1 Hostless", .cpu_dai_name = "SLIMBUS1_HOSTLESS", @@ -6024,7 +6026,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, - { + {/* hw:x,11 */ .name = "SLIMBUS_3 Hostless", .stream_name = "SLIMBUS_3 Hostless", .cpu_dai_name = "SLIMBUS3_HOSTLESS", @@ -6041,10 +6043,10 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, - { - .name = "SLIMBUS_4 Hostless", - .stream_name = "SLIMBUS_4 Hostless", - .cpu_dai_name = "SLIMBUS4_HOSTLESS", + {/* hw:x,12 */ + .name = "SLIMBUS_7 Hostless", + .stream_name = "SLIMBUS_7 Hostless", + .cpu_dai_name = "SLIMBUS7_HOSTLESS", .platform_name = "msm-pcm-hostless", .dynamic = 1, .dpcm_playback = 1, @@ -6058,7 +6060,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, - { + {/* hw:x,13 */ .name = MSM_DAILINK_NAME(LowLatency), .stream_name = "MultiMedia5", .cpu_dai_name = "MultiMedia5", @@ -6077,7 +6079,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .id = MSM_FRONTEND_DAI_MULTIMEDIA5, .ops = &msm_fe_qos_ops, }, - { + {/* hw:x,14 */ .name = "Listen 1 Audio Service", .stream_name = "Listen 1 Audio Service", .cpu_dai_name = "LSM1", @@ -6093,7 +6095,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .id = MSM_FRONTEND_DAI_LSM1, }, /* Multiple Tunnel instances */ - { + {/* hw:x,15 */ .name = MSM_DAILINK_NAME(Compress2), .stream_name = "Compress2", .cpu_dai_name = "MultiMedia7", @@ -6109,7 +6111,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { /* this dainlink has playback support */ .id = MSM_FRONTEND_DAI_MULTIMEDIA7, }, - { + {/* hw:x,16 */ .name = MSM_DAILINK_NAME(MultiMedia10), .stream_name = "MultiMedia10", .cpu_dai_name = "MultiMedia10", @@ -6126,7 +6128,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { /* this dainlink has playback support */ .id = MSM_FRONTEND_DAI_MULTIMEDIA10, }, - { + {/* hw:x,17 */ .name = MSM_DAILINK_NAME(ULL_NOIRQ), .stream_name = "MM_NOIRQ", .cpu_dai_name = "MultiMedia8", @@ -6145,7 +6147,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .ops = &msm_fe_qos_ops, }, /* HDMI Hostless */ - { + {/* hw:x,18 */ .name = "HDMI_RX_HOSTLESS", .stream_name = "HDMI_RX_HOSTLESS", .cpu_dai_name = "HDMI_HOSTLESS", @@ -6160,7 +6162,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, - { + {/* hw:x,19 */ .name = "VoiceMMode2", .stream_name = "VoiceMMode2", .cpu_dai_name = "VoiceMMode2", @@ -6178,7 +6180,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .id = MSM_FRONTEND_DAI_VOICEMMODE2, }, /* LSM FE */ - { + {/* hw:x,20 */ .name = "Listen 2 Audio Service", .stream_name = "Listen 2 Audio Service", .cpu_dai_name = "LSM2", @@ -6193,7 +6195,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM2, }, - { + {/* hw:x,21 */ .name = "Listen 3 Audio Service", .stream_name = "Listen 3 Audio Service", .cpu_dai_name = "LSM3", @@ -6208,7 +6210,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM3, }, - { + {/* hw:x,22 */ .name = "Listen 4 Audio Service", .stream_name = "Listen 4 Audio Service", .cpu_dai_name = "LSM4", @@ -6223,7 +6225,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM4, }, - { + {/* hw:x,23 */ .name = "Listen 5 Audio Service", .stream_name = "Listen 5 Audio Service", .cpu_dai_name = "LSM5", @@ -6238,7 +6240,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM5, }, - { + {/* hw:x,24 */ .name = "Listen 6 Audio Service", .stream_name = "Listen 6 Audio Service", .cpu_dai_name = "LSM6", @@ -6253,7 +6255,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM6, }, - { + {/* hw:x,25 */ .name = "Listen 7 Audio Service", .stream_name = "Listen 7 Audio Service", .cpu_dai_name = "LSM7", @@ -6268,7 +6270,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM7, }, - { + {/* hw:x,26 */ .name = "Listen 8 Audio Service", .stream_name = "Listen 8 Audio Service", .cpu_dai_name = "LSM8", @@ -6283,7 +6285,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_LSM8, }, - { + {/* hw:x,27 */ .name = MSM_DAILINK_NAME(Media9), .stream_name = "MultiMedia9", .cpu_dai_name = "MultiMedia9", @@ -6300,7 +6302,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA9, }, - { + {/* hw:x,28 */ .name = MSM_DAILINK_NAME(Compress4), .stream_name = "Compress4", .cpu_dai_name = "MultiMedia11", @@ -6316,7 +6318,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { /* this dainlink has playback support */ .id = MSM_FRONTEND_DAI_MULTIMEDIA11, }, - { + {/* hw:x,29 */ .name = MSM_DAILINK_NAME(Compress5), .stream_name = "Compress5", .cpu_dai_name = "MultiMedia12", @@ -6332,7 +6334,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { /* this dainlink has playback support */ .id = MSM_FRONTEND_DAI_MULTIMEDIA12, }, - { + {/* hw:x,30 */ .name = MSM_DAILINK_NAME(Compress6), .stream_name = "Compress6", .cpu_dai_name = "MultiMedia13", @@ -6348,7 +6350,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { /* this dainlink has playback support */ .id = MSM_FRONTEND_DAI_MULTIMEDIA13, }, - { + {/* hw:x,31 */ .name = MSM_DAILINK_NAME(Compress7), .stream_name = "Compress7", .cpu_dai_name = "MultiMedia14", @@ -6364,7 +6366,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { /* this dainlink has playback support */ .id = MSM_FRONTEND_DAI_MULTIMEDIA14, }, - { + {/* hw:x,32 */ .name = MSM_DAILINK_NAME(Compress8), .stream_name = "Compress8", .cpu_dai_name = "MultiMedia15", @@ -6380,7 +6382,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { /* this dainlink has playback support */ .id = MSM_FRONTEND_DAI_MULTIMEDIA15, }, - { + {/* hw:x,33 */ .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), .stream_name = "MM_NOIRQ_2", .cpu_dai_name = "MultiMedia16", @@ -6397,7 +6399,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { /* this dainlink has playback support */ .id = MSM_FRONTEND_DAI_MULTIMEDIA16, }, - { + {/* hw:x,34 */ .name = "SLIMBUS_8 Hostless", .stream_name = "SLIMBUS8_HOSTLESS Capture", .cpu_dai_name = "SLIMBUS8_HOSTLESS", @@ -6411,11 +6413,42 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, + {/* hw:x,35 */ + .name = "CDC_DMA Hostless", + .stream_name = "CDC_DMA Hostless", + .cpu_dai_name = "CDC_DMA_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,36 */ + .name = "TX3_CDC_DMA Hostless", + .stream_name = "TX3_CDC_DMA Hostless", + .cpu_dai_name = "TX3_CDC_DMA_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, }; static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = { - { + {/* hw:x,37 */ .name = LPASS_BE_SLIMBUS_4_TX, .stream_name = "Slimbus4 Capture", .cpu_dai_name = "msm-dai-q6-dev.16393", @@ -6429,7 +6462,7 @@ static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = { .ignore_suspend = 1, }, /* Ultrasound RX DAI Link */ - { + {/* hw:x,38 */ .name = "SLIMBUS_2 Hostless Playback", .stream_name = "SLIMBUS_2 Hostless Playback", .cpu_dai_name = "msm-dai-q6-dev.16388", @@ -6442,7 +6475,7 @@ static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = { .ops = &msm_slimbus_2_be_ops, }, /* Ultrasound TX DAI Link */ - { + {/* hw:x,39 */ .name = "SLIMBUS_2 Hostless Capture", .stream_name = "SLIMBUS_2 Hostless Capture", .cpu_dai_name = "msm-dai-q6-dev.16389", @@ -6456,7 +6489,7 @@ static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = { }; static struct snd_soc_dai_link msm_bolero_fe_dai_links[] = { - { + {/* hw:x,37 */ .name = LPASS_BE_WSA_CDC_DMA_TX_0, .stream_name = "WSA CDC DMA0 Capture", .cpu_dai_name = "msm-dai-cdc-dma-dev.45057", -- GitLab From 6fc2e746e788d7c2e849ef6816651bfbb9bd06f3 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Sun, 26 Aug 2018 23:32:57 +0530 Subject: [PATCH 0476/1645] asoc: bolero: Add wsa macro sidetone and loopback routes Add support for wsa macro sidetone and adie loopback widgets and route connections. Change-Id: I5d830bc868e6fa0f0a56474f11867e6dd55ae535 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/wsa-macro.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index ecfe28f15f00..c0af520ca029 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -229,6 +229,10 @@ static const char *const rx_mux_text[] = { "ZERO", "AIF1_PB", "AIF_MIX1_PB" }; +static const char *const rx_sidetone_mix_text[] = { + "ZERO", "SRC0" +}; + static const char * const wsa_macro_ear_spkr_pa_gain_text[] = { "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB", "G_4_DB", "G_5_DB", "G_6_DB" @@ -260,6 +264,9 @@ static const struct soc_enum rx0_mix_chain_enum = SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1, 0, 5, rx_mix_text); +static const struct soc_enum rx0_sidetone_mix_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_sidetone_mix_text); + static const struct snd_kcontrol_new rx0_prim_inp0_mux = SOC_DAPM_ENUM("WSA_RX0 INP0 Mux", rx0_prim_inp0_chain_enum); @@ -272,6 +279,9 @@ static const struct snd_kcontrol_new rx0_prim_inp2_mux = static const struct snd_kcontrol_new rx0_mix_mux = SOC_DAPM_ENUM("WSA_RX0 MIX Mux", rx0_mix_chain_enum); +static const struct snd_kcontrol_new rx0_sidetone_mix_mux = + SOC_DAPM_ENUM("WSA_RX0 SIDETONE MIX Mux", rx0_sidetone_mix_enum); + /* RX INT1 */ static const struct soc_enum rx1_prim_inp0_chain_enum = SOC_ENUM_SINGLE(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0, @@ -1825,6 +1835,15 @@ static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = { SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MUX_E("WSA_RX0 INT0 SIDETONE MIX", + BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 4, 0, + &rx0_sidetone_mix_mux, wsa_macro_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_INPUT("WSA SRC0_INP"), + + SND_SOC_DAPM_INPUT("WSA_TX DEC0_INP"), + SND_SOC_DAPM_INPUT("WSA_TX DEC1_INP"), + SND_SOC_DAPM_MIXER_E("WSA_RX INT0 INTERP", SND_SOC_NOPM, WSA_MACRO_COMP1, 0, NULL, 0, wsa_macro_enable_interpolator, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | @@ -1889,18 +1908,24 @@ static const struct snd_soc_dapm_route wsa_audio_map[] = { {"WSA_RX0 INP0", "RX1", "WSA RX1"}, {"WSA_RX0 INP0", "RX_MIX0", "WSA RX_MIX0"}, {"WSA_RX0 INP0", "RX_MIX1", "WSA RX_MIX1"}, + {"WSA_RX0 INP0", "DEC0", "WSA_TX DEC0_INP"}, + {"WSA_RX0 INP0", "DEC1", "WSA_TX DEC1_INP"}, {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP0"}, {"WSA_RX0 INP1", "RX0", "WSA RX0"}, {"WSA_RX0 INP1", "RX1", "WSA RX1"}, {"WSA_RX0 INP1", "RX_MIX0", "WSA RX_MIX0"}, {"WSA_RX0 INP1", "RX_MIX1", "WSA RX_MIX1"}, + {"WSA_RX0 INP1", "DEC0", "WSA_TX DEC0_INP"}, + {"WSA_RX0 INP1", "DEC1", "WSA_TX DEC1_INP"}, {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP1"}, {"WSA_RX0 INP2", "RX0", "WSA RX0"}, {"WSA_RX0 INP2", "RX1", "WSA RX1"}, {"WSA_RX0 INP2", "RX_MIX0", "WSA RX_MIX0"}, {"WSA_RX0 INP2", "RX_MIX1", "WSA RX_MIX1"}, + {"WSA_RX0 INP2", "DEC0", "WSA_TX DEC0_INP"}, + {"WSA_RX0 INP2", "DEC1", "WSA_TX DEC1_INP"}, {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP2"}, {"WSA_RX0 MIX INP", "RX0", "WSA RX0"}, @@ -1911,6 +1936,8 @@ static const struct snd_soc_dapm_route wsa_audio_map[] = { {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"}, {"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"}, + {"WSA_RX0 INT0 SIDETONE MIX", "SRC0", "WSA SRC0_INP"}, + {"WSA_RX INT0 INTERP", NULL, "WSA_RX0 INT0 SIDETONE MIX"}, {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"}, {"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"}, {"WSA_SPK1 OUT", NULL, "WSA_MCLK"}, @@ -1919,18 +1946,24 @@ static const struct snd_soc_dapm_route wsa_audio_map[] = { {"WSA_RX1 INP0", "RX1", "WSA RX1"}, {"WSA_RX1 INP0", "RX_MIX0", "WSA RX_MIX0"}, {"WSA_RX1 INP0", "RX_MIX1", "WSA RX_MIX1"}, + {"WSA_RX1 INP0", "DEC0", "WSA_TX DEC0_INP"}, + {"WSA_RX1 INP0", "DEC1", "WSA_TX DEC1_INP"}, {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP0"}, {"WSA_RX1 INP1", "RX0", "WSA RX0"}, {"WSA_RX1 INP1", "RX1", "WSA RX1"}, {"WSA_RX1 INP1", "RX_MIX0", "WSA RX_MIX0"}, {"WSA_RX1 INP1", "RX_MIX1", "WSA RX_MIX1"}, + {"WSA_RX1 INP1", "DEC0", "WSA_TX DEC0_INP"}, + {"WSA_RX1 INP1", "DEC1", "WSA_TX DEC1_INP"}, {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP1"}, {"WSA_RX1 INP2", "RX0", "WSA RX0"}, {"WSA_RX1 INP2", "RX1", "WSA RX1"}, {"WSA_RX1 INP2", "RX_MIX0", "WSA RX_MIX0"}, {"WSA_RX1 INP2", "RX_MIX1", "WSA RX_MIX1"}, + {"WSA_RX1 INP2", "DEC0", "WSA_TX DEC0_INP"}, + {"WSA_RX1 INP2", "DEC1", "WSA_TX DEC1_INP"}, {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP2"}, {"WSA_RX1 MIX INP", "RX0", "WSA RX0"}, -- GitLab From e9454c6269ba4c30103d29b0a8ce0d29d306d9ac Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 23 Aug 2018 23:45:20 +0530 Subject: [PATCH 0477/1645] asoc: Add LSM routing changes for TX_CDC_DMA_TX_3 Add LSM mixer and function related routing changes for TX_CDC_DMA_TX_3 interface to support SVA. CRs-Fixed: 2281591 Change-Id: I9ff7e9d51069ec0467c464ddb5c640e533e81d90 Signed-off-by: Aditya Bavanari --- asoc/msm-pcm-routing-v2.c | 57 ++++++++++++++++++++++++++++++++++++++- dsp/q6afe.c | 6 +++-- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 4f0ea8343f9c..3fd4a59f77c4 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -113,6 +113,7 @@ enum { #define INT3_MI2S_TX_TEXT "INT3_MI2S_TX" #define VA_CDC_DMA_TX_0_TEXT "VA_CDC_DMA_TX_0" #define VA_CDC_DMA_TX_1_TEXT "VA_CDC_DMA_TX_1" +#define TX_CDC_DMA_TX_3_TEXT "TX_CDC_DMA_TX_3" #define LSM_FUNCTION_TEXT "LSM Function" static const char * const lsm_port_text[] = { @@ -120,7 +121,8 @@ static const char * const lsm_port_text[] = { SLIMBUS_0_TX_TEXT, SLIMBUS_1_TX_TEXT, SLIMBUS_2_TX_TEXT, SLIMBUS_3_TX_TEXT, SLIMBUS_4_TX_TEXT, SLIMBUS_5_TX_TEXT, TERT_MI2S_TX_TEXT, QUAT_MI2S_TX_TEXT, ADM_LSM_TX_TEXT, - INT3_MI2S_TX_TEXT, VA_CDC_DMA_TX_0_TEXT, VA_CDC_DMA_TX_1_TEXT + INT3_MI2S_TX_TEXT, VA_CDC_DMA_TX_0_TEXT, VA_CDC_DMA_TX_1_TEXT, + TX_CDC_DMA_TX_3_TEXT }; struct msm_pcm_route_bdai_pp_params { @@ -2664,6 +2666,9 @@ static int msm_routing_lsm_port_put(struct snd_kcontrol *kcontrol, case 12: lsm_port = AFE_PORT_ID_VA_CODEC_DMA_TX_1; break; + case 13: + lsm_port = AFE_PORT_ID_TX_CODEC_DMA_TX_3; + break; default: pr_err("Default lsm port"); break; @@ -2707,6 +2712,10 @@ static int msm_routing_lsm_func_get(struct snd_kcontrol *kcontrol, strlen(lsm_port_text[10]))) port_id = AFE_PORT_ID_INT3_MI2S_TX; + if (strnstr(kcontrol->id.name, lsm_port_text[13], + strlen(lsm_port_text[13]))) + port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3; + mad_type = afe_port_get_mad_type(port_id); pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, mad_type); @@ -2786,6 +2795,10 @@ static int msm_routing_lsm_func_put(struct snd_kcontrol *kcontrol, strlen(lsm_port_text[10]))) port_id = AFE_PORT_ID_INT3_MI2S_TX; + if (strnstr(kcontrol->id.name, lsm_port_text[13], + strlen(lsm_port_text[13]))) + port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3; + pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, mad_type); return afe_port_set_mad_type(port_id, mad_type); @@ -15941,6 +15954,10 @@ static const struct snd_kcontrol_new lsm1_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm2_mixer_controls[] = { @@ -15985,6 +16002,10 @@ static const struct snd_kcontrol_new lsm2_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm3_mixer_controls[] = { @@ -16028,6 +16049,10 @@ static const struct snd_kcontrol_new lsm3_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm4_mixer_controls[] = { @@ -16071,6 +16096,10 @@ static const struct snd_kcontrol_new lsm4_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm5_mixer_controls[] = { @@ -16114,6 +16143,10 @@ static const struct snd_kcontrol_new lsm5_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm6_mixer_controls[] = { @@ -16157,6 +16190,10 @@ static const struct snd_kcontrol_new lsm6_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm7_mixer_controls[] = { @@ -16200,6 +16237,10 @@ static const struct snd_kcontrol_new lsm7_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm8_mixer_controls[] = { @@ -16243,6 +16284,10 @@ static const struct snd_kcontrol_new lsm8_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new slim_fm_switch_mixer_controls = @@ -16379,6 +16424,8 @@ static const struct snd_kcontrol_new lsm_controls[] = { msm_routing_lsm_func_get, msm_routing_lsm_func_put), SOC_ENUM_EXT(INT3_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(TX_CDC_DMA_TX_3_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), /* kcontrol of lsm_port */ SOC_ENUM_EXT("LSM1 Port", lsm_port_enum, msm_routing_lsm_port_get, @@ -21096,6 +21143,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM1 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"LSM1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM1 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM1_UL_HL", NULL, "LSM1 Mixer"}, {"LSM2 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -21108,6 +21156,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM2 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"LSM2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM2 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM2_UL_HL", NULL, "LSM2 Mixer"}, @@ -21121,6 +21170,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"LSM3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM3 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM3_UL_HL", NULL, "LSM3 Mixer"}, @@ -21134,6 +21184,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM4 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"LSM4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM4 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM4_UL_HL", NULL, "LSM4 Mixer"}, {"LSM5 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -21146,6 +21197,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"LSM5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM5 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM5_UL_HL", NULL, "LSM5 Mixer"}, {"LSM6 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -21156,6 +21208,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"LSM6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM6 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM6_UL_HL", NULL, "LSM6 Mixer"}, {"LSM7 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -21166,6 +21219,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM7 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"LSM7 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM7 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM7 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM7_UL_HL", NULL, "LSM7 Mixer"}, {"LSM8 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -21176,6 +21230,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM8 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"LSM8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM8 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM8_UL_HL", NULL, "LSM8 Mixer"}, diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 3fbbbbc3f8b3..b69558f49978 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2675,7 +2675,8 @@ int afe_port_set_mad_type(u16 port_id, enum afe_mad_type mad_type) int i; if (port_id == AFE_PORT_ID_TERTIARY_MI2S_TX || - port_id == AFE_PORT_ID_INT3_MI2S_TX) { + port_id == AFE_PORT_ID_INT3_MI2S_TX || + port_id == AFE_PORT_ID_TX_CODEC_DMA_TX_3) { mad_type = MAD_SW_AUDIO; return 0; } @@ -2703,7 +2704,8 @@ enum afe_mad_type afe_port_get_mad_type(u16 port_id) int i; if (port_id == AFE_PORT_ID_TERTIARY_MI2S_TX || - port_id == AFE_PORT_ID_INT3_MI2S_TX) + port_id == AFE_PORT_ID_INT3_MI2S_TX || + port_id == AFE_PORT_ID_TX_CODEC_DMA_TX_3) return MAD_SW_AUDIO; i = port_id - SLIMBUS_0_RX; -- GitLab From c5c7d44d9635353e8fe1f67f69a4543c23f84d50 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 23 Aug 2018 15:39:15 +0530 Subject: [PATCH 0478/1645] asoc: routing: update routing to support sound tracking Add support for TX codec dma interface to support source tracking and sound focus mixer controls. Change-Id: I11dc36a2f86164c7dc3a24357e68a04a8099cb4a Signed-off-by: Aditya Bavanari --- asoc/msm-pcm-routing-v2.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index bb10858de749..f8567b390093 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -17017,6 +17017,9 @@ static int msm_audio_sound_focus_derive_port_id(struct snd_kcontrol *kcontrol, } else if (!strcmp(kcontrol->id.name + strlen(prefix), "VA_CDC_DMA_TX_0")) { *port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "TX_CDC_DMA_TX_3")) { + *port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3; } else { pr_err("%s: mixer ctl name=%s, could not derive valid port id\n", __func__, kcontrol->id.name); @@ -17281,6 +17284,36 @@ static const struct snd_kcontrol_new msm_source_tracking_controls[] = { .info = msm_source_tracking_info, .get = msm_audio_source_tracking_get, }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx TX_CDC_DMA_TX_3", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx TX_CDC_DMA_TX_3", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx TX_CDC_DMA_TX_3", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx TX_CDC_DMA_TX_3", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, }; static int spkr_prot_put_vi_lch_port(struct snd_kcontrol *kcontrol, -- GitLab From 0c1f938992f1bbc39cf934698b9a70fb7def23f3 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 28 Aug 2018 14:28:02 -0700 Subject: [PATCH 0479/1645] dsp: rate limit read/write error logs Rate limit dsp read/write error logs to reduce log prints during SSR scenario for read/write failures. Change-Id: I031be5ebd39bdd11dc8e1eb92c77ed782f1dc149 Signed-off-by: Karthikeyan Mani --- dsp/codecs/audio_utils_aio.c | 4 ++-- dsp/q6asm.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c index 7f332f4f7aa6..db07d3f263c3 100644 --- a/dsp/codecs/audio_utils_aio.c +++ b/dsp/codecs/audio_utils_aio.c @@ -1104,7 +1104,7 @@ static int audio_aio_async_write(struct q6audio_aio *audio, buf_node->token = ac->session; rc = q6asm_async_write(ac, ¶m); if (rc < 0) - pr_err("%s[%pK]:failed\n", __func__, audio); + pr_err_ratelimited("%s[%pK]:failed\n", __func__, audio); return rc; } @@ -1157,7 +1157,7 @@ static int audio_aio_async_read(struct q6audio_aio *audio, buf_node->token = ac->session; rc = q6asm_async_read(ac, ¶m); if (rc < 0) - pr_err("%s[%pK]:failed\n", __func__, audio); + pr_err_ratelimited("%s[%pK]:failed\n", __func__, audio); return rc; } diff --git a/dsp/q6asm.c b/dsp/q6asm.c index faedfc1b5cbf..b7d92ad85e29 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -8625,7 +8625,7 @@ int q6asm_async_write(struct audio_client *ac, return -EINVAL; } if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); + pr_err_ratelimited("%s: AC APR handle NULL\n", __func__); return -EINVAL; } @@ -8718,7 +8718,7 @@ int q6asm_async_read(struct audio_client *ac, return -EINVAL; } if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); + pr_err_ratelimited("%s: AC APR handle NULL\n", __func__); return -EINVAL; } -- GitLab From f7476772347acba2e6c264e4ccf949055974f940 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 29 Aug 2018 10:38:18 +0530 Subject: [PATCH 0480/1645] asoc: wcd937x: fix compilation issue in mbhc Fix compilation issue in wcd937x mbhc file. Change-Id: I49057cdf108268f60795f568cc7efb43d53d01a3 Signed-off-by: Ramprasad Katkam --- asoc/codecs/wcd937x/wcd937x-mbhc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index f83271b083e5..d23801953944 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -757,7 +757,7 @@ static bool wcd937x_mbhc_get_moisture_status(struct wcd_mbhc *mbhc) /* If moisture_en is already enabled, then skip to plug type * detection. */ - if ((snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_2) & 0x0C)) + if ((snd_soc_read(codec, WCD937X_MBHC_NEW_CTL_2) & 0x0C)) goto done; wcd937x_mbhc_moisture_detect_en(mbhc, true); @@ -773,6 +773,8 @@ static bool wcd937x_mbhc_get_moisture_status(struct wcd_mbhc *mbhc) static void wcd937x_mbhc_moisture_polling_ctrl(struct wcd_mbhc *mbhc, bool enable) { + struct snd_soc_codec *codec = mbhc->codec; + snd_soc_update_bits(codec, WCD937X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL, 0x04, (enable << 2)); -- GitLab From 9c2394a6e4e5470c5a43edf6e06e2c20e648411a Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Thu, 23 Aug 2018 13:13:48 +0530 Subject: [PATCH 0481/1645] asoc: Talos-tanggu bringup fixes Bringup fixes to enumerate tanggu codec on talos. Change-Id: Ic9c43ec0b870f6fec3c6d21fd4d77606c7ed94b1 Signed-off-by: Ramprasad Katkam --- asoc/codecs/bolero/rx-macro.c | 19 +++++++++- asoc/codecs/bolero/tx-macro.c | 7 +++- asoc/codecs/wcd937x/internal.h | 2 +- asoc/codecs/wcd937x/wcd937x-mbhc.c | 8 ++-- asoc/codecs/wcd937x/wcd937x-regmap.c | 7 ++++ asoc/codecs/wcd937x/wcd937x.c | 55 ++++++++++++++++------------ 6 files changed, 68 insertions(+), 30 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 905a0edc7023..fbacdc028375 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -769,6 +769,9 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, regmap_update_bits(regmap, BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x01); + regmap_update_bits(regmap, + BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, + 0x02, 0x02); regmap_update_bits(regmap, BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x01); @@ -1022,6 +1025,7 @@ static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: snd_soc_write(codec, gain_reg, snd_soc_read(codec, gain_reg)); + snd_soc_update_bits(codec, mix_reg, 0x10, 0x00); break; case SND_SOC_DAPM_POST_PMD: /* Clk Disable */ @@ -1071,6 +1075,7 @@ static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: snd_soc_write(codec, gain_reg, snd_soc_read(codec, gain_reg)); + snd_soc_update_bits(codec, reg, 0x10, 0x00); break; case SND_SOC_DAPM_POST_PMD: rx_macro_enable_interp_clk(codec, event, w->shift); @@ -2393,12 +2398,15 @@ static int rx_swrm_clock(void *handle, bool enable) __func__); goto exit; } + regmap_update_bits(regmap, + BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, + 0x02, 0x02); regmap_update_bits(regmap, BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x01); regmap_update_bits(regmap, BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, - 0x1C, 0x0C); + 0x02, 0x00); msm_cdc_pinctrl_select_active_state( rx_priv->rx_swr_gpio_p); } @@ -2471,6 +2479,15 @@ static int rx_macro_init(struct snd_soc_codec *codec) dev_err(rx_dev, "%s: failed to add snd_ctls\n", __func__); return ret; } + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL, 0x01, 0x01); + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX1_RX_PATH_DSM_CTL, 0x01, 0x01); + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL, 0x01, 0x01); + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX0_RX_PATH_SEC7, 0x07, 0x02); + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX1_RX_PATH_SEC7, 0x07, 0x02); + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_SEC7, 0x07, 0x02); + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX0_RX_PATH_CFG3, 0x03, 0x02); + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX1_RX_PATH_CFG3, 0x03, 0x02); + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG3, 0x03, 0x02); rx_priv->codec = codec; diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index e2eac593b6e3..f8c762b8c91c 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -336,7 +336,7 @@ static void tx_macro_mute_update_callback(struct work_struct *work) hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 + TX_MACRO_TX_PATH_OFFSET * decimator; snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x01); - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00); + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); dev_dbg(tx_priv->dev, "%s: decimator %u unmute\n", __func__, decimator); } @@ -521,6 +521,9 @@ static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMU: (*dmic_clk_cnt)++; if (*dmic_clk_cnt == 1) { + snd_soc_update_bits(codec, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, + 0x80, 0x00); + snd_soc_update_bits(codec, dmic_clk_reg, 0x0E, tx_priv->dmic_clk_div << 0x1); snd_soc_update_bits(codec, dmic_clk_reg, @@ -583,6 +586,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); break; case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x20, 0x20); snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00); /* schedule work queue to Remove Mute */ @@ -613,6 +617,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, &tx_priv->tx_mute_dwork[decimator].dwork); break; case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x20, 0x00); snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); break; } diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index b693f6a9bc16..06e64d038b73 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -61,7 +61,7 @@ struct wcd937x_priv { u32 hph_mode; struct irq_domain *virq; - struct wcd_irq_info *irq_info; + struct wcd_irq_info irq_info; u32 rx_clk_cnt; int num_irq_regs; diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index f83271b083e5..4a2fa615f747 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -169,7 +169,7 @@ static int wcd937x_mbhc_request_irq(struct snd_soc_codec *codec, { struct wcd937x_priv *wcd937x = dev_get_drvdata(codec->dev); - return wcd_request_irq(wcd937x->irq_info, irq, name, handler, data); + return wcd_request_irq(&wcd937x->irq_info, irq, name, handler, data); } static void wcd937x_mbhc_irq_control(struct snd_soc_codec *codec, @@ -178,9 +178,9 @@ static void wcd937x_mbhc_irq_control(struct snd_soc_codec *codec, struct wcd937x_priv *wcd937x = dev_get_drvdata(codec->dev); if (enable) - wcd_enable_irq(wcd937x->irq_info, irq); + wcd_enable_irq(&wcd937x->irq_info, irq); else - wcd_disable_irq(wcd937x->irq_info, irq); + wcd_disable_irq(&wcd937x->irq_info, irq); } static int wcd937x_mbhc_free_irq(struct snd_soc_codec *codec, @@ -188,7 +188,7 @@ static int wcd937x_mbhc_free_irq(struct snd_soc_codec *codec, { struct wcd937x_priv *wcd937x = dev_get_drvdata(codec->dev); - wcd_free_irq(wcd937x->irq_info, irq, data); + wcd_free_irq(&wcd937x->irq_info, irq, data); return 0; } diff --git a/asoc/codecs/wcd937x/wcd937x-regmap.c b/asoc/codecs/wcd937x/wcd937x-regmap.c index cccf8dbdbf59..f445abceed9a 100644 --- a/asoc/codecs/wcd937x/wcd937x-regmap.c +++ b/asoc/codecs/wcd937x/wcd937x-regmap.c @@ -434,21 +434,28 @@ static const struct reg_default wcd937x_defaults[] = { static bool wcd937x_readable_register(struct device *dev, unsigned int reg) { + if(reg <= WCD937X_BASE_ADDRESS) + return 0; return wcd937x_reg_access[WCD937X_REG(reg)] & RD_REG; } static bool wcd937x_writeable_register(struct device *dev, unsigned int reg) { + if(reg <= WCD937X_BASE_ADDRESS) + return 0; return wcd937x_reg_access[WCD937X_REG(reg)] & WR_REG; } static bool wcd937x_volatile_register(struct device *dev, unsigned int reg) { + if(reg <= WCD937X_BASE_ADDRESS) + return 0; return (wcd937x_reg_access[WCD937X_REG(reg)] & RD_REG) & ~(wcd937x_reg_access[WCD937X_REG(reg)] & WR_REG); } struct regmap_config wcd937x_regmap_config = { + .name = "wcd937x_csr", .reg_bits = 16, .val_bits = 8, .cache_type = REGCACHE_RBTREE, diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index f445540eb343..d26b81923ecb 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -337,6 +337,10 @@ static int wcd937x_rx_clk_enable(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x01, 0x01); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_RX0_CTL, 0x40, 0x00); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_RX1_CTL, + 0x40, 0x00); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_RX2_CTL, + 0x40, 0x00); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x02); } @@ -1026,9 +1030,10 @@ static int wcd937x_enable_req(struct snd_soc_dapm_widget *w, 0x00); snd_soc_update_bits(codec, WCD937X_ANA_TX_CH2, 0x40, 0x40); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, - 0x10, 0x10); + 0x30, 0x30); snd_soc_update_bits(codec, WCD937X_ANA_TX_CH1, 0x80, 0x80); snd_soc_update_bits(codec, WCD937X_ANA_TX_CH2, 0x40, 0x00); + snd_soc_update_bits(codec, WCD937X_ANA_TX_CH2, 0x80, 0x80); break; case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, WCD937X_ANA_TX_CH1, 0x80, 0x00); @@ -1098,6 +1103,11 @@ int wcd937x_micbias_control(struct snd_soc_codec *codec, case MICB_ENABLE: wcd937x->micb_ref[micb_index]++; if (wcd937x->micb_ref[micb_index] == 1) { + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0xE0, 0xE0); + snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); + snd_soc_update_bits(codec, WCD937X_MICB1_TEST_CTL_2, 0x01, 0x01); + snd_soc_update_bits(codec, WCD937X_MICB2_TEST_CTL_2, 0x01, 0x01); + snd_soc_update_bits(codec, WCD937X_MICB3_TEST_CTL_2, 0x01, 0x01); snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); if (post_on_event) blocking_notifier_call_chain(&wcd937x->notifier, @@ -1324,7 +1334,7 @@ static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = { SND_SOC_DAPM_ADC_E("ADC1", NULL, SND_SOC_NOPM, 0, 0, wcd937x_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("ADC2", NULL, SND_SOC_NOPM, 0, 1, + SND_SOC_DAPM_ADC_E("ADC2", NULL, SND_SOC_NOPM, 1, 0, wcd937x_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -1439,7 +1449,7 @@ static const struct snd_soc_dapm_widget wcd9375_dapm_widgets[] = { SND_SOC_DAPM_INPUT("AMIC4"), /*tx widgets*/ - SND_SOC_DAPM_ADC_E("ADC3", NULL, SND_SOC_NOPM, 0, 2, + SND_SOC_DAPM_ADC_E("ADC3", NULL, SND_SOC_NOPM, 2, 0, wcd937x_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -1450,19 +1460,19 @@ static const struct snd_soc_dapm_widget wcd9375_dapm_widgets[] = { SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0, wcd937x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 1, + SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 1, 0, wcd937x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 2, + SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 2, 0, wcd937x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 3, + SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 3, 0, wcd937x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 4, + SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 4, 0, wcd937x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 0, 5, + SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 5, 0, wcd937x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -1508,19 +1518,18 @@ static const struct snd_soc_dapm_widget wcd9375_dapm_widgets[] = { static const struct snd_soc_dapm_route wcd937x_audio_map[] = { - {"ADC2_OUTPUT", NULL, "ADC2_MIXER"}, - {"ADC2_MIXER", "Switch", "ADC2 REQ"}, - {"ADC2 REQ", "NULL", "ADC2"}, - {"ADC2", "NULL", "ADC2 MUX"}, - {"ADC2 MUX", "INP3", "AMIC3"}, - {"ADC2 MUX", "INP2", "AMIC2"}, - - {"ADC1_OUTPUT", NULL, "ADC1_MIXER"}, {"ADC1_MIXER", "Switch", "ADC1 REQ"}, {"ADC1 REQ", NULL, "ADC1"}, {"ADC1", NULL, "AMIC1"}, + {"ADC2_OUTPUT", NULL, "ADC2_MIXER"}, + {"ADC2_MIXER", "Switch", "ADC2 REQ"}, + {"ADC2 REQ", NULL, "ADC2"}, + {"ADC2", NULL, "ADC2 MUX"}, + {"ADC2 MUX", "INP3", "AMIC3"}, + {"ADC2 MUX", "INP2", "AMIC2"}, + {"RX1", NULL, "IN1_HPHL"}, {"RDAC1", NULL, "RX1"}, {"HPHL_RDAC", "Switch", "RDAC1"}, @@ -1847,11 +1856,11 @@ static int wcd937x_bind(struct device *dev) regmap_write(wcd937x->regmap, (WCD937X_DIGITAL_INTR_LEVEL_0 + i), 0); - wcd937x->irq_info->wcd_regmap_irq_chip = &wcd937x_regmap_irq_chip; - wcd937x->irq_info->codec_name = "WCD937X"; - wcd937x->irq_info->regmap = wcd937x->regmap; - wcd937x->irq_info->dev = dev; - ret = wcd_irq_init(wcd937x->irq_info, &wcd937x->virq); + wcd937x->irq_info.wcd_regmap_irq_chip = &wcd937x_regmap_irq_chip; + wcd937x->irq_info.codec_name = "WCD937X"; + wcd937x->irq_info.regmap = wcd937x->regmap; + wcd937x->irq_info.dev = dev; + ret = wcd_irq_init(&wcd937x->irq_info, &wcd937x->virq); if (ret) { dev_err(wcd937x->dev, "%s: IRQ init failed: %d\n", @@ -1870,7 +1879,7 @@ static int wcd937x_bind(struct device *dev) return ret; err_irq: - wcd_irq_exit(wcd937x->irq_info, wcd937x->virq); + wcd_irq_exit(&wcd937x->irq_info, wcd937x->virq); err: component_unbind_all(dev, wcd937x); return ret; @@ -1880,7 +1889,7 @@ static void wcd937x_unbind(struct device *dev) { struct wcd937x_priv *wcd937x = dev_get_drvdata(dev); - wcd_irq_exit(wcd937x->irq_info, wcd937x->virq); + wcd_irq_exit(&wcd937x->irq_info, wcd937x->virq); snd_soc_unregister_codec(dev); component_unbind_all(dev, wcd937x); } -- GitLab From a72eb7843abf451e6134273ee71d76ae4d21af32 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Tue, 28 Aug 2018 02:56:15 +0530 Subject: [PATCH 0482/1645] asoc: swr: Fix logic to retrieve swr slave device handle Fix issue in the loop logic of retrieving swr slave device handle by passing device node. Change-Id: I5c31259b1257de730748b8522537afa9870f24e4 Signed-off-by: Ramprasad Katkam --- soc/soundwire.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/soc/soundwire.c b/soc/soundwire.c index fff5c1546145..573d39dcd7b9 100644 --- a/soc/soundwire.c +++ b/soc/soundwire.c @@ -796,18 +796,24 @@ struct swr_device *get_matching_swr_slave_device(struct device_node *np) { struct swr_device *swr = NULL; struct swr_master *master; + bool found = false; mutex_lock(&board_lock); list_for_each_entry(master, &swr_master_list, list) { mutex_lock(&master->mlock); list_for_each_entry(swr, &master->devices, dev_list) { - if (swr->dev.of_node == np) - break; + if (swr->dev.of_node == np) { + found = true; + mutex_unlock(&master->mlock); + goto exit; + } } mutex_unlock(&master->mlock); } +exit: mutex_unlock(&board_lock); - + if (!found) + return NULL; return swr; } EXPORT_SYMBOL(get_matching_swr_slave_device); @@ -888,7 +894,6 @@ int swr_register_master(struct swr_master *master) id = idr_alloc(&master_idr, master, master->bus_num, master->bus_num + 1, GFP_KERNEL); mutex_unlock(&swr_lock); - if (id < 0) return id; -- GitLab From 1f22126590b621d612fec72ddc2a1300798cbeaf Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Thu, 23 Aug 2018 15:01:22 +0530 Subject: [PATCH 0483/1645] asoc: swr: master controller fixes for tanggu Add locking for soundwire fifo operation as same function call can be used at a time by a different thread like mbhc, and fix register definitions in header. Add soundwire slave interrupt clear registers as part of slave interrupt event in master interrupt handler. Change-Id: I94d9b7ac09192dbf8aa3248d35956b380430ee0b Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 107 +++++++++++++++++++++++++++++++++---------- soc/swr-mstr-ctrl.h | 1 + soc/swrm_registers.h | 12 +++-- 3 files changed, 92 insertions(+), 28 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index b2449e7e937d..40d8aa5e5a8f 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -59,8 +59,8 @@ enum { #define TRUE 1 #define FALSE 0 -#define SWRM_MAX_PORT_REG 40 -#define SWRM_MAX_INIT_REG 8 +#define SWRM_MAX_PORT_REG 120 +#define SWRM_MAX_INIT_REG 10 #define SWR_MSTR_MAX_REG_ADDR 0x1740 #define SWR_MSTR_START_REG_ADDR 0x00 @@ -304,11 +304,13 @@ static int swr_master_bulk_write(struct swr_mstr_ctrl *swrm, u32 *reg_addr, if (swrm->bulk_write) swrm->bulk_write(swrm->handle, reg_addr, val, length); else { + mutex_lock(&swrm->iolock); for (i = 0; i < length; i++) { /* wait for FIFO WR command to complete to avoid overflow */ usleep_range(100, 105); swr_master_write(swrm, reg_addr[i], val[i]); } + mutex_unlock(&swrm->iolock); } return 0; } @@ -403,6 +405,7 @@ static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, u32 val; u32 retry_attempt = 0; + mutex_lock(&swrm->iolock); val = swrm_get_packed_reg_val(&swrm->rcmd_id, len, dev_addr, reg_addr); /* wait for FIFO RD to complete to avoid overflow */ usleep_range(100, 105); @@ -411,9 +414,9 @@ static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, usleep_range(250, 255); retry_read: *cmd_data = swr_master_read(swrm, SWRM_CMD_FIFO_RD_FIFO_ADDR); - dev_dbg(swrm->dev, - "%s: reg: 0x%x, cmd_id: 0x%x, dev_num: 0x%x, cmd_data: 0x%x\n", - __func__, reg_addr, cmd_id, dev_addr, *cmd_data); + dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, rcmd_id: 0x%x, \ + dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, + cmd_id, swrm->rcmd_id, dev_addr, *cmd_data); if ((((*cmd_data) & 0xF00) >> 8) != swrm->rcmd_id) { if (retry_attempt < MAX_FIFO_RD_FAIL_RETRY) { /* wait 500 us before retry on fifo read failure */ @@ -421,10 +424,17 @@ static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, retry_attempt++; goto retry_read; } else { + dev_err_ratelimited(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, \ + rcmd_id: 0x%x, dev_num: 0x%x, cmd_data: 0x%x\n", + __func__, reg_addr, cmd_id, swrm->rcmd_id, + dev_addr, *cmd_data); + dev_err_ratelimited(swrm->dev, "%s: failed to read fifo\n", __func__); } } + mutex_unlock(&swrm->iolock); + return 0; } @@ -434,15 +444,16 @@ static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data, u32 val; int ret = 0; + mutex_lock(&swrm->iolock); if (!cmd_id) val = swrm_get_packed_reg_val(&swrm->wcmd_id, cmd_data, dev_addr, reg_addr); else val = swrm_get_packed_reg_val(&cmd_id, cmd_data, dev_addr, reg_addr); - dev_dbg(swrm->dev, - "%s: reg: 0x%x, cmd_id: 0x%x, val:0x%x, dev_num: 0x%x, cmd_data: 0x%x\n", - __func__, reg_addr, cmd_id, val, dev_addr, cmd_data); + dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x,wcmd_id: 0x%x, \ + dev_num: 0x%x, cmd_data: 0x%x\n", __func__, + reg_addr, cmd_id, swrm->wcmd_id,dev_addr, cmd_data); /* wait for FIFO WR command to complete to avoid overflow */ usleep_range(250, 255); swr_master_write(swrm, SWRM_CMD_FIFO_WR_CMD, val); @@ -457,6 +468,7 @@ static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data, wait_for_completion_timeout(&swrm->broadcast, (2 * HZ/10)); } + mutex_unlock(&swrm->iolock); return ret; } @@ -472,7 +484,7 @@ static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr, dev_err(&master->dev, "%s: swrm is NULL\n", __func__); return -EINVAL; } - + pm_runtime_get_sync(swrm->dev); if (dev_num) ret = swrm_cmd_fifo_rd_cmd(swrm, &val, dev_num, 0, reg_addr, len); @@ -482,8 +494,8 @@ static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr, if (!ret) *reg_val = (u8)val; + pm_runtime_put_autosuspend(swrm->dev); pm_runtime_mark_last_busy(swrm->dev); - return ret; } @@ -499,12 +511,14 @@ static int swrm_write(struct swr_master *master, u8 dev_num, u16 reg_addr, return -EINVAL; } + pm_runtime_get_sync(swrm->dev); if (dev_num) ret = swrm_cmd_fifo_wr_cmd(swrm, reg_val, dev_num, 0, reg_addr); else swr_master_write(swrm, reg_addr, reg_val); - pm_runtime_mark_last_busy(swrm->dev); + pm_runtime_put_autosuspend(swrm->dev); + pm_runtime_mark_last_busy(swrm->dev); return ret; } @@ -524,6 +538,7 @@ static int swrm_bulk_write(struct swr_master *master, u8 dev_num, void *reg, if (len <= 0) return -EINVAL; + pm_runtime_get_sync(swrm->dev); if (dev_num) { swr_fifo_reg = kcalloc(len, sizeof(u32), GFP_KERNEL); if (!swr_fifo_reg) { @@ -560,6 +575,7 @@ static int swrm_bulk_write(struct swr_master *master, u8 dev_num, void *reg, mem_fail: kfree(swr_fifo_reg); err: + pm_runtime_put_autosuspend(swrm->dev); pm_runtime_mark_last_busy(swrm->dev); return ret; } @@ -1022,6 +1038,26 @@ static int swrm_disconnect_port(struct swr_master *master, return 0; } +static int swrm_find_alert_slave(struct swr_mstr_ctrl *swrm, + int status, u8 *devnum) +{ + int i; + bool found = false; + + for (i = 0; i < (swrm->master.num_dev + 1); i++) { + if ((status & SWRM_MCP_SLV_STATUS_MASK) == SWR_ALERT) { + *devnum = i; + found = true; + break; + } + status >>= 2; + } + if (found) + return 0; + else + return -EINVAL; +} + static int swrm_check_slave_change_status(struct swr_mstr_ctrl *swrm, int status, u8 *devnum) { @@ -1049,7 +1085,8 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) { struct swr_mstr_ctrl *swrm = dev; u32 value, intr_sts; - int status, chg_sts, i; + u32 temp = 0; + u32 status, chg_sts, i; u8 devnum = 0; int ret = IRQ_HANDLED; struct swr_device *swr_dev; @@ -1067,13 +1104,16 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) if (!value) continue; - swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, value); switch (value) { case SWRM_INTERRUPT_STATUS_SLAVE_PEND_IRQ: dev_dbg(swrm->dev, "Trigger irq to slave device\n"); status = swr_master_read(swrm, SWRM_MCP_SLV_STATUS); - swrm_check_slave_change_status(swrm, status, - &devnum); + ret = swrm_find_alert_slave(swrm, status, &devnum); + if (ret) { + dev_err(swrm->dev, "no slave alert found.\ + spurious interrupt\n"); + return ret; + } list_for_each_entry(swr_dev, &mstr->devices, dev_list) { if (swr_dev->dev_num != devnum) continue; @@ -1082,6 +1122,12 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) irq_find_mapping( swr_dev->slave_irq, 0)); } + swrm_cmd_fifo_rd_cmd(swrm, &temp, devnum, 0x0, + SWRS_SCP_INT_STATUS_CLEAR_1, 1); + swrm_cmd_fifo_wr_cmd(swrm, 0x4, devnum, 0x0, + SWRS_SCP_INT_STATUS_CLEAR_1); + swrm_cmd_fifo_wr_cmd(swrm, 0x0, devnum, 0x0, + SWRS_SCP_INT_STATUS_CLEAR_1); break; case SWRM_INTERRUPT_STATUS_NEW_SLAVE_ATTACHED: dev_dbg(swrm->dev, "SWR new slave attached\n"); @@ -1160,7 +1206,8 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) break; } } - + swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, intr_sts); + swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, 0x0); mutex_lock(&swrm->reslock); swrm_clk_request(swrm, false); mutex_unlock(&swrm->reslock); @@ -1196,13 +1243,13 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, num_dev = swrm->num_dev; else num_dev = mstr->num_dev; - pm_runtime_get_sync(swrm->dev); for (i = 1; i < (num_dev + 1); i++) { id = ((u64)(swr_master_read(swrm, SWRM_ENUMERATOR_SLAVE_DEV_ID_2(i))) << 32); id |= swr_master_read(swrm, SWRM_ENUMERATOR_SLAVE_DEV_ID_1(i)); + /* * As pm_runtime_get_sync() brings all slaves out of reset * update logical device number for all slaves. @@ -1220,6 +1267,11 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, dev_dbg(swrm->dev, "%s: devnum %d is assigned for dev addr %lx\n", __func__, i, swr_dev->addr); + swrm_cmd_fifo_wr_cmd(swrm, 0xFF, i, 0xF, + SWRS_SCP_INT_STATUS_CLEAR_1); + swrm_cmd_fifo_wr_cmd(swrm, 0x4, i, 0xF, + SWRS_SCP_INT_STATUS_MASK_1); + } } } @@ -1256,10 +1308,6 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) reg[len] = SWRM_ENUMERATOR_CFG_ADDR; value[len++] = 1; - /* Mask soundwire interrupts */ - reg[len] = SWRM_INTERRUPT_MASK_ADDR; - value[len++] = 0x1FFFD; - /* Configure No pings */ val = swr_master_read(swrm, SWRM_MCP_CFG_ADDR); val &= ~SWRM_MCP_CFG_MAX_NUM_OF_CMD_NO_PINGS_BMSK; @@ -1272,15 +1320,22 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) reg[len] = SWRM_CMD_FIFO_CFG_ADDR; value[len++] = val; - /* Set IRQ to PULSE */ - reg[len] = SWRM_COMP_CFG_ADDR; - value[len++] = 0x02; + reg[len] = SWRM_MCP_BUS_CTRL_ADDR; + value[len++] = 0x2; + /* Set IRQ to PULSE */ reg[len] = SWRM_COMP_CFG_ADDR; value[len++] = 0x03; reg[len] = SWRM_INTERRUPT_CLEAR; - value[len++] = 0x08; + value[len++] = 0xFFFFFFFF; + + /* Mask soundwire interrupts */ + reg[len] = SWRM_INTERRUPT_MASK_ADDR; + value[len++] = 0x1FFFD; + + reg[len] = SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN; + value[len++] = 0x1; swr_master_bulk_write(swrm, reg, value, len); @@ -1430,6 +1485,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_init(&swrm->mlock); mutex_init(&swrm->reslock); mutex_init(&swrm->force_down_lock); + mutex_init(&swrm->iolock); for (i = 0 ; i < SWR_MSTR_PORT_LEN; i++) INIT_LIST_HEAD(&swrm->mport_cfg[i].port_req_list); @@ -1535,6 +1591,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_destroy(&swrm->mlock); mutex_destroy(&swrm->reslock); mutex_destroy(&swrm->force_down_lock); + mutex_destroy(&swrm->iolock); err_pdata_fail: err_memory_fail: return ret; diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 17d6c938c72f..075ace9bd632 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -102,6 +102,7 @@ struct swr_mstr_ctrl { int clk_ref_count; struct completion reset; struct completion broadcast; + struct mutex iolock; struct mutex mlock; struct mutex reslock; u32 swrm_base_reg; diff --git a/soc/swrm_registers.h b/soc/swrm_registers.h index 0147e459d76d..ecff48d69941 100644 --- a/soc/swrm_registers.h +++ b/soc/swrm_registers.h @@ -114,6 +114,8 @@ #define SWRM_INTERRUPT_CLEAR (SWRM_BASE_ADDRESS+0x00000208) +#define SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN (SWRM_BASE_ADDRESS+0x00000210) + #define SWRM_CMD_FIFO_WR_CMD (SWRM_BASE_ADDRESS + 0x00000300) #define SWRM_CMD_FIFO_WR_CMD_MASK 0xFFFFFFFF #define SWRM_CMD_FIFO_RD_CMD (SWRM_BASE_ADDRESS + 0x00000304) @@ -185,7 +187,8 @@ 0x40*m) #define SWRM_DP_BLOCK_CTRL_1(n) (SWRM_BASE_ADDRESS + \ - 0x0000112C + 0x100*n) + 0x0000112C + \ + 0x100*(n-1)) #define SWRM_DP_BLOCK_CTRL2_BANK(n, m) (SWRM_BASE_ADDRESS + \ 0x00001130 + \ @@ -204,7 +207,7 @@ #define SWRM_DIN_DPn_PCM_PORT_CTRL(n) (SWRM_BASE_ADDRESS + \ - 0x00001054 + 0x100*n) + 0x00001054 + 0x100*(n-1)) #define SWRM_MAX_REGISTER SWRM_DIN_DPn_PCM_PORT_CTRL(7) @@ -214,8 +217,11 @@ #define SWRS_DP_REG_OFFSET(port, bank) ((0x100*port)+(0x10*bank)) +#define SWRS_SCP_INT_STATUS_CLEAR_1 0x40 +#define SWRS_SCP_INT_STATUS_MASK_1 0x41 + #define SWRS_SCP_CONTROL 0x44 -#define SWRS_DP_BLOCK_CONTROL_1(n) (SWRS_BASE_ADDRESS + 0x120 + \ +#define SWRS_DP_BLOCK_CONTROL_1(n) (SWRS_BASE_ADDRESS + 0x103 + \ 0x100 * n) #define SWRS_DP_CHANNEL_ENABLE_BANK(n, m) (SWRS_BASE_ADDRESS + 0x120 + \ -- GitLab From 5c1f1aada7e59c6796b73295b2b7a75d4506f14a Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 13 Aug 2018 12:15:38 +0530 Subject: [PATCH 0484/1645] asoc: bolero: Add codec version info to support ADIE RTC In order to differentiate between targets, codec version info is used. Assign codec version based on number of macros registered in bolero. CRs-Fixed: 2281591 Change-Id: I0f4cf0e49645d3acf0c413ea93d9c0261ac98848 Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/bolero-cdc.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 51e56df51c55..749f87b973c3 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -23,6 +23,8 @@ #include "internal.h" #define BOLERO_VERSION_1_0 0x0001 +#define BOLERO_VERSION_1_1 0x0002 +#define BOLERO_VERSION_1_2 0x0003 #define BOLERO_VERSION_ENTRY_SIZE 32 static struct snd_soc_codec_driver bolero; @@ -412,6 +414,12 @@ static ssize_t bolero_version_read(struct snd_info_entry *entry, case BOLERO_VERSION_1_0: len = snprintf(buffer, sizeof(buffer), "BOLERO_1_0\n"); break; + case BOLERO_VERSION_1_1: + len = snprintf(buffer, sizeof(buffer), "BOLERO_1_1\n"); + break; + case BOLERO_VERSION_1_2: + len = snprintf(buffer, sizeof(buffer), "BOLERO_1_2\n"); + break; default: len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); } @@ -499,7 +507,20 @@ static int bolero_soc_codec_probe(struct snd_soc_codec *codec) } } priv->codec = codec; - priv->version = BOLERO_VERSION_1_0; + /* + * In order for the ADIE RTC to differentiate between targets + * version info is used. + * Assign 1.0 for target with only one macro + * Assign 1.1 for target with two macros + * Assign 1.2 for target with more than two macros + */ + if (priv->num_macros_registered == 1) + priv->version = BOLERO_VERSION_1_0; + else if (priv->num_macros_registered == 2) + priv->version = BOLERO_VERSION_1_1; + else if (priv->num_macros_registered > 2) + priv->version = BOLERO_VERSION_1_2; + dev_dbg(codec->dev, "%s: bolero soc codec probe success\n", __func__); err: return ret; -- GitLab From 2a9a3fe071d13a1a1454b0eb4e14831113a03629 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Wed, 29 Aug 2018 15:35:23 +0800 Subject: [PATCH 0485/1645] asoc: add routing for FM playback on sm6150 Add routes to support FM playback over speaker and headphones. Change-Id: I36b992a38602a460319551ba473cbaac604021c0 Signed-off-by: Xiaojun Sang --- asoc/msm-pcm-routing-v2.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 4f0ea8343f9c..428371017bd5 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -13296,6 +13296,10 @@ static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_port_mixer_controls[] = { MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new rx_cdc_dma_rx_0_port_mixer_controls[] = { @@ -13303,6 +13307,10 @@ static const struct snd_kcontrol_new rx_cdc_dma_rx_0_port_mixer_controls[] = { MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { @@ -21755,6 +21763,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"WSA_CDC_DMA_RX_0 Port Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"WSA_CDC_DMA_RX_0 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"RX_CDC_DMA_RX_0 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"WSA_CDC_DMA_RX_0 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"RX_CDC_DMA_RX_0 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, -- GitLab From 8ef5a483e8f020f873030da12b2a207ac4a32e0d Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 29 Aug 2018 12:31:11 +0530 Subject: [PATCH 0486/1645] asoc: routing: Fix routing entries of Multimedia20 mixer Add routing entries for Multimedia20 Tx mixer in order to fix boot up warnings in routing driver. CRs-Fixed: 2281591 Change-Id: I9ac35dab53811bd6ede64d69d221cdc6fbd622f4 Signed-off-by: Aditya Bavanari --- asoc/msm-pcm-routing-v2.c | 135 +++++++++++++++++++++++++++----------- 1 file changed, 95 insertions(+), 40 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 3fd4a59f77c4..920f4794b731 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -11383,6 +11383,58 @@ static const struct snd_kcontrol_new mmul20_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul21_mixer_controls[] = { @@ -11475,62 +11527,56 @@ static const struct snd_kcontrol_new mmul21_mixer_controls[] = { MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; @@ -20342,7 +20388,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, @@ -20369,7 +20414,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, @@ -20424,7 +20468,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, @@ -20456,6 +20499,19 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia21 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia21 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia21 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia21 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia21 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, @@ -20487,7 +20543,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, -- GitLab From dd5037184772e337e69b8bfff193606b46070573 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 1 Feb 2018 14:07:41 -0800 Subject: [PATCH 0487/1645] asoc: mbhc: fix for fake ins irq Check for in2p clamp state in insertion irq and ignore the interrupt if the clamp is already set, which means the mechanical removal is about to happen next. Change-Id: I55691d427cf07d5b61862b6dbd39f3ec34d873e5 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd-mbhc-adc.c | 18 +++++++++++++++++- asoc/codecs/wcd-mbhc-v2.h | 1 + asoc/codecs/wcd934x/wcd934x-mbhc.c | 4 +++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index 981623748706..1f0c5ba4d1c1 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -34,6 +34,7 @@ #define WCD_MBHC_ADC_HS_THRESHOLD_MV 1700 #define WCD_MBHC_ADC_HPH_THRESHOLD_MV 75 #define WCD_MBHC_ADC_MICBIAS_MV 1800 +#define WCD_MBHC_FAKE_INS_RETRY 4 static int wcd_mbhc_get_micbias(struct wcd_mbhc *mbhc) { @@ -1021,6 +1022,8 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) static irqreturn_t wcd_mbhc_adc_hs_ins_irq(int irq, void *data) { struct wcd_mbhc *mbhc = data; + u8 clamp_state = 0; + u8 clamp_retry = WCD_MBHC_FAKE_INS_RETRY; pr_debug("%s: enter\n", __func__); @@ -1035,6 +1038,19 @@ static irqreturn_t wcd_mbhc_adc_hs_ins_irq(int irq, void *data) return IRQ_HANDLED; } + do { + WCD_MBHC_REG_READ(WCD_MBHC_IN2P_CLAMP_STATE, clamp_state); + if (clamp_state) { + pr_debug("%s: fake insertion irq, leave\n", __func__); + return IRQ_HANDLED; + } + /* + * check clamp for 120ms but at 30ms chunks to leave + * room for other interrupts to be processed + */ + usleep_range(30000, 30100); + } while (--clamp_retry); + WCD_MBHC_RSC_LOCK(mbhc); /* * If current plug is headphone then there is no chance to diff --git a/asoc/codecs/wcd-mbhc-v2.h b/asoc/codecs/wcd-mbhc-v2.h index 4d00c2bb9800..fafac14083a4 100644 --- a/asoc/codecs/wcd-mbhc-v2.h +++ b/asoc/codecs/wcd-mbhc-v2.h @@ -189,6 +189,7 @@ enum wcd_mbhc_register_function { WCD_MBHC_BTN_DBNC, WCD_MBHC_HS_VREF, WCD_MBHC_HS_COMP_RESULT, + WCD_MBHC_IN2P_CLAMP_STATE, WCD_MBHC_MIC_SCHMT_RESULT, WCD_MBHC_HPHL_SCHMT_RESULT, WCD_MBHC_HPHR_SCHMT_RESULT, diff --git a/asoc/codecs/wcd934x/wcd934x-mbhc.c b/asoc/codecs/wcd934x/wcd934x-mbhc.c index ae147ca0f411..bfe1e17a4534 100644 --- a/asoc/codecs/wcd934x/wcd934x-mbhc.c +++ b/asoc/codecs/wcd934x/wcd934x-mbhc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -86,6 +86,8 @@ static struct wcd_mbhc_register WCD934X_MBHC_NEW_CTL_2, 0x03, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT", WCD934X_ANA_MBHC_RESULT_3, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_IN2P_CLAMP_STATE", + WCD934X_ANA_MBHC_RESULT_3, 0x10, 4, 0), WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT", WCD934X_ANA_MBHC_RESULT_3, 0x20, 5, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT", -- GitLab From 477f211b8a6418bc3614b8b5e2e834cff8a9c26a Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 29 Aug 2018 12:28:57 +0530 Subject: [PATCH 0488/1645] ASoC: sm6150: Add logic to parse micbias from dt Add logic to parse micbias info if it is specified in dt. CRs-Fixed: 2281591 Change-Id: I943cedcadeceaa4a7da3422cf427d5679fe703b6 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/internal.h | 2 ++ asoc/codecs/wcd937x/wcd937x.c | 65 ++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index b693f6a9bc16..2ad716567413 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -77,7 +77,9 @@ struct wcd937x_priv { struct wcd937x_micbias_setting { u8 ldoh_v; u32 cfilt1_mv; + u32 micb1_mv; u32 micb2_mv; + u32 micb3_mv; u8 bias1_cfilt_sel; }; diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index f445540eb343..d6135dd46043 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1725,6 +1725,65 @@ int wcd937x_reset(struct device *dev) return rc; } +static int wcd937x_read_of_property_u32(struct device *dev, const char *name, + u32 *val) +{ + int rc = 0; + + rc = of_property_read_u32(dev->of_node, name, val); + if (rc) + dev_err(dev, "%s: Looking up %s property in node %s failed\n", + __func__, name, dev->of_node->full_name); + + return rc; +} + +static void wcd937x_dt_parse_micbias_info(struct device *dev, + struct wcd937x_micbias_setting *mb) +{ + u32 prop_val = 0; + int rc = 0; + + /* MB1 */ + if (of_find_property(dev->of_node, "qcom,cdc-micbias1-mv", + NULL)) { + rc = wcd937x_read_of_property_u32(dev, + "qcom,cdc-micbias1-mv", + &prop_val); + if (!rc) + mb->micb1_mv = prop_val; + } else { + dev_info(dev, "%s: Micbias1 DT property not found\n", + __func__); + } + + /* MB2 */ + if (of_find_property(dev->of_node, "qcom,cdc-micbias2-mv", + NULL)) { + rc = wcd937x_read_of_property_u32(dev, + "qcom,cdc-micbias2-mv", + &prop_val); + if (!rc) + mb->micb2_mv = prop_val; + } else { + dev_info(dev, "%s: Micbias2 DT property not found\n", + __func__); + } + + /* MB3 */ + if (of_find_property(dev->of_node, "qcom,cdc-micbias3-mv", + NULL)) { + rc = wcd937x_read_of_property_u32(dev, + "qcom,cdc-micbias3-mv", + &prop_val); + if (!rc) + mb->micb3_mv = prop_val; + } else { + dev_info(dev, "%s: Micbias3 DT property not found\n", + __func__); + } +} + struct wcd937x_pdata *wcd937x_populate_dt_data(struct device *dev) { struct wcd937x_pdata *pdata = NULL; @@ -1755,6 +1814,7 @@ struct wcd937x_pdata *wcd937x_populate_dt_data(struct device *dev) pdata->rx_slave = of_parse_phandle(dev->of_node, "qcom,rx-slave", 0); pdata->tx_slave = of_parse_phandle(dev->of_node, "qcom,tx-slave", 0); + wcd937x_dt_parse_micbias_info(dev, &pdata->micbias); return pdata; } @@ -1776,7 +1836,8 @@ static int wcd937x_bind(struct device *dev) dev_err(dev, "%s: Fail to obtain platform data\n", __func__); return -EINVAL; } - + wcd937x->dev = dev; + wcd937x->dev->platform_data = pdata; wcd937x->rst_np = pdata->rst_np; ret = msm_cdc_init_supplies(dev, &wcd937x->supplies, pdata->regulator, pdata->num_supplies); @@ -1854,7 +1915,7 @@ static int wcd937x_bind(struct device *dev) ret = wcd_irq_init(wcd937x->irq_info, &wcd937x->virq); if (ret) { - dev_err(wcd937x->dev, "%s: IRQ init failed: %d\n", + dev_err(dev, "%s: IRQ init failed: %d\n", __func__, ret); goto err; } -- GitLab From 997da40118c577f37bde0d1629410779fdde0c61 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Fri, 17 Aug 2018 20:20:06 +0530 Subject: [PATCH 0489/1645] asoc: wcd937x: enable headset detection Enable mbhc on wcd937x for headset insertion and removal detection. Change-Id: I0b2ae7ea061a99ad89f9adea00c898dac4442ca6 Signed-off-by: Ramprasad Katkam --- asoc/Kbuild | 1 + asoc/codecs/wcd937x/wcd937x.c | 73 +++++++++++++---------------------- asoc/sm6150.c | 12 +++++- 3 files changed, 39 insertions(+), 47 deletions(-) diff --git a/asoc/Kbuild b/asoc/Kbuild index 311fbae090e9..253ceefb849b 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -191,6 +191,7 @@ ifeq ($(KERNEL_BUILD), 0) KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd937x/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers endif diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index d26b81923ecb..d60b9f37b673 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -43,7 +43,7 @@ enum { static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); -static int wcd937x_handle_pre_irq(void *data); + static int wcd937x_handle_post_irq(void *data); static const struct regmap_irq wcd937x_irqs[WCD937X_NUM_IRQS] = { @@ -77,43 +77,10 @@ static struct regmap_irq_chip wcd937x_regmap_irq_chip = { .status_base = WCD937X_DIGITAL_INTR_STATUS_0, .mask_base = WCD937X_DIGITAL_INTR_MASK_0, .type_base = WCD937X_DIGITAL_INTR_LEVEL_0, - .runtime_pm = true, + .runtime_pm = false, .handle_post_irq = wcd937x_handle_post_irq, - .handle_pre_irq = wcd937x_handle_pre_irq, + .irq_drv_data = NULL, }; - -static int wcd937x_handle_pre_irq(void *data) -{ - struct wcd937x_priv *wcd937x = data; - int num_irq_regs = wcd937x->num_irq_regs; - int ret = 0; - u8 sts[num_irq_regs]; - struct wcd937x_pdata *pdata; - - pdata = dev_get_platdata(wcd937x->dev); - - memset(sts, 0, sizeof(sts)); - ret = regmap_bulk_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_0, - sts, num_irq_regs); - if (ret < 0) { - dev_err(wcd937x->dev, "%s: Failed to read intr status: %d\n", - __func__, ret); - } else if (ret == 0) { - dev_dbg(wcd937x->dev, - "%s: clear interrupts except OCP and SCD\n", __func__); - /* Do not affect OCP and SCD interrupts */ - sts[0] = sts[0] & 0x5F; - sts[1] = sts[1] & 0xEB; - regmap_write(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_0, - sts[0]); - regmap_write(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_1, - sts[1]); - regmap_write(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_2, - sts[2]); - } - return IRQ_HANDLED; -} - static int wcd937x_handle_post_irq(void *data) { struct wcd937x_priv *wcd937x = data; @@ -123,17 +90,30 @@ static int wcd937x_handle_post_irq(void *data) pdata = dev_get_platdata(wcd937x->dev); regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_0, &val); - if ((val & 0xA0) != 0) { - dev_dbg(wcd937x->dev, "%s Clear OCP interupts\n", __func__); - regmap_update_bits(wcd937x->regmap, - WCD937X_DIGITAL_INTR_CLEAR_0, 0xA0, 0x00); - } + dev_dbg(wcd937x->dev, "%s Clear OCP interupts\n", __func__); + regmap_write(wcd937x->regmap, + WCD937X_DIGITAL_INTR_CLEAR_0, 0xFF); + regmap_write(wcd937x->regmap, + WCD937X_DIGITAL_INTR_CLEAR_0, 0x0); regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_1, &val); - if ((val & 0x14) != 0) { - dev_dbg(wcd937x->dev, "%s Clear SCD interupts\n", __func__); - regmap_update_bits(wcd937x->regmap, - WCD937X_DIGITAL_INTR_CLEAR_1, 0x14, 0x00); - } + dev_dbg(wcd937x->dev, "%s Clear SCD interupts\n", __func__); + regmap_write(wcd937x->regmap, + WCD937X_DIGITAL_INTR_CLEAR_1, 0xFF); + regmap_write(wcd937x->regmap, + WCD937X_DIGITAL_INTR_CLEAR_1, 0x0); + + regmap_write(wcd937x->regmap, + WCD937X_DIGITAL_INTR_CLEAR_2, 0xFF); + regmap_write(wcd937x->regmap, + WCD937X_DIGITAL_INTR_CLEAR_2, 0x0); + + regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_0, &val); + regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_1, &val); + regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_2, &val); + regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_0, &val); + regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_1, &val); + regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_2, &val); + return IRQ_HANDLED; } @@ -1856,6 +1836,7 @@ static int wcd937x_bind(struct device *dev) regmap_write(wcd937x->regmap, (WCD937X_DIGITAL_INTR_LEVEL_0 + i), 0); + wcd937x_regmap_irq_chip.irq_drv_data = wcd937x; wcd937x->irq_info.wcd_regmap_irq_chip = &wcd937x_regmap_irq_chip; wcd937x->irq_info.codec_name = "WCD937X"; wcd937x->irq_info.regmap = wcd937x->regmap; diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 8d9d32dc283e..46b5c70b9494 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -36,6 +36,7 @@ #include "codecs/msm-cdc-pinctrl.h" #include "codecs/wcd934x/wcd934x.h" #include "codecs/wcd934x/wcd934x-mbhc.h" +#include "codecs/wcd937x/wcd937x-mbhc.h" #include "codecs/wsa881x.h" #include "codecs/bolero/bolero-cdc.h" #include @@ -7925,6 +7926,8 @@ static int msm_aux_codec_init(struct snd_soc_component *component) { struct snd_soc_codec *codec = snd_soc_component_to_codec(component); struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + int ret = 0; + void *mbhc_calibration; snd_soc_dapm_ignore_suspend(dapm, "EAR"); snd_soc_dapm_ignore_suspend(dapm, "AUX"); @@ -7936,7 +7939,14 @@ static int msm_aux_codec_init(struct snd_soc_component *component) snd_soc_dapm_ignore_suspend(dapm, "AMIC4"); snd_soc_dapm_sync(dapm); - return 0; + mbhc_calibration = def_wcd_mbhc_cal(); + if (!mbhc_calibration) { + return -ENOMEM; + } + wcd_mbhc_cfg.calibration = mbhc_calibration; + ret = wcd937x_mbhc_hs_detect(codec, &wcd_mbhc_cfg); + + return ret; } static int msm_init_aux_dev(struct platform_device *pdev, -- GitLab From 14f47cc8a66b61cf82113634b6469e4b2316aa8b Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 25 Jul 2018 17:20:18 +0530 Subject: [PATCH 0490/1645] asoc: swr-mstr: add rx and tx master frame configuration Add Rx and TX master frame configuration. Change-Id: I067931565270e7390d9c5311e0869dfdb6685999 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 194 +++++++++++++++++++++++++++++++---------- soc/swr-mstr-ctrl.h | 14 ++- soc/swrm_port_config.h | 45 ++++++++-- 3 files changed, 199 insertions(+), 54 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 40d8aa5e5a8f..a9d755b89442 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -38,6 +38,8 @@ #define SWR_REG_VAL_PACK(data, dev, id, reg) \ ((reg) | ((id) << 16) | ((dev) << 20) | ((data) << 24)) +#define SWR_INVALID_PARAM 0xFF + /* pm runtime auto suspend timer in msecs */ static int auto_suspend_timer = SWR_AUTO_SUSPEND_DELAY * 1000; module_param(auto_suspend_timer, int, 0664); @@ -55,7 +57,6 @@ enum { MASTER_ID_RX, MASTER_ID_TX }; -#define MASTER_ID_MASK 0xF #define TRUE 1 #define FALSE 0 @@ -320,36 +321,51 @@ static bool swrm_is_port_en(struct swr_master *mstr) return !!(mstr->num_port); } -static int swrm_get_port_config(struct swr_mstr_ctrl *swrm) +static void copy_port_tables(struct swr_mstr_ctrl *swrm, + struct port_params *params) { - u8 master_device_id; - int i; + u8 i; + struct port_params *config = params; - /* update device_id for tx/rx */ - master_device_id = MASTER_ID_WSA; + for (i = 0; i < SWR_MSTR_PORT_LEN; i++) { + /* wsa uses single frame structure for all configurations */ + if (!swrm->mport_cfg[i].port_en) + continue; + swrm->mport_cfg[i].sinterval = config[i].si; + swrm->mport_cfg[i].offset1 = config[i].off1; + swrm->mport_cfg[i].offset2 = config[i].off2; + swrm->mport_cfg[i].hstart = config[i].hstart; + swrm->mport_cfg[i].hstop = config[i].hstop; + swrm->mport_cfg[i].blk_pack_mode = config[i].bp_mode; + swrm->mport_cfg[i].blk_grp_count = config[i].bgp_ctrl; + swrm->mport_cfg[i].word_length = config[i].wd_len; + swrm->mport_cfg[i].lane_ctrl = config[i].lane_ctrl; + } +} +static int swrm_get_port_config(struct swr_mstr_ctrl *swrm) +{ + struct port_params *params; - switch (master_device_id & MASTER_ID_MASK) { + switch (swrm->master_id) { case MASTER_ID_WSA: - /* get port params for wsa */ - for (i = 0; i < SWR_MSTR_PORT_LEN; i++) { - /* wsa uses single frame structure for all configurations */ - if (!swrm->mport_cfg[i].port_en) - continue; - swrm->mport_cfg[i].sinterval = wsa_frame_superset[i].si; - swrm->mport_cfg[i].offset1 = wsa_frame_superset[i].off1; - swrm->mport_cfg[i].offset2 = wsa_frame_superset[i].off2; - } + params = wsa_frame_superset; break; case MASTER_ID_RX: - /* get port params for rx */ + /* Two RX tables for dsd and without dsd enabled */ + if (swrm->mport_cfg[4].port_en) + params = rx_frame_params_dsd; + else + params = rx_frame_params; break; case MASTER_ID_TX: - /* get port params for tx */ + params = tx_frame_params_superset; break; default: /* MASTER_GENERIC*/ /* computer generic frame parameters */ return -EINVAL; } + + copy_port_tables(swrm, params); return 0; } @@ -735,6 +751,7 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank) u32 reg[SWRM_MAX_PORT_REG]; u32 val[SWRM_MAX_PORT_REG]; int len = 0; + u8 hparams; struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); if (!swrm) { @@ -770,13 +787,54 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank) SWRS_DP_OFFSET_CONTROL_1_BANK(slv_id, bank)); - if (port_req->slave_port_id) { + if (mport->offset2 != SWR_INVALID_PARAM) { reg[len] = SWRM_CMD_FIFO_WR_CMD; val[len++] = SWR_REG_VAL_PACK(mport->offset2, port_req->dev_num, 0x00, SWRS_DP_OFFSET_CONTROL_2_BANK( slv_id, bank)); } + if (mport->hstart != SWR_INVALID_PARAM + && mport->hstop != SWR_INVALID_PARAM) { + hparams = (mport->hstart << 4) | mport->hstop; + + reg[len] = SWRM_CMD_FIFO_WR_CMD; + val[len++] = SWR_REG_VAL_PACK(hparams, + port_req->dev_num, 0x00, + SWRS_DP_HCONTROL_BANK(slv_id, + bank)); + } + if (mport->word_length != SWR_INVALID_PARAM) { + reg[len] = SWRM_CMD_FIFO_WR_CMD; + val[len++] = + SWR_REG_VAL_PACK(mport->word_length, + port_req->dev_num, 0x00, + SWRS_DP_BLOCK_CONTROL_1(slv_id)); + } + if (mport->blk_pack_mode != SWR_INVALID_PARAM) { + reg[len] = SWRM_CMD_FIFO_WR_CMD; + val[len++] = + SWR_REG_VAL_PACK(mport->blk_pack_mode, + port_req->dev_num, 0x00, + SWRS_DP_BLOCK_CONTROL_3_BANK(slv_id, + bank)); + } + if (mport->blk_grp_count != SWR_INVALID_PARAM) { + reg[len] = SWRM_CMD_FIFO_WR_CMD; + val[len++] = + SWR_REG_VAL_PACK(mport->blk_grp_count, + port_req->dev_num, 0x00, + SWRS_DP_BLOCK_CONTROL_2_BANK(slv_id, + bank)); + } + if (mport->lane_ctrl != SWR_INVALID_PARAM) { + reg[len] = SWRM_CMD_FIFO_WR_CMD; + val[len++] = + SWR_REG_VAL_PACK(mport->lane_ctrl, + port_req->dev_num, 0x00, + SWRS_DP_LANE_CONTROL_BANK(slv_id, + bank)); + } port_req->ch_en = port_req->req_ch; } value = ((mport->req_ch) @@ -790,11 +848,33 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank) reg[len] = SWRM_DP_PORT_CTRL_BANK(i + 1, bank); val[len++] = value; - dev_dbg(swrm->dev, "%s: mport :%d, reg: 0x%x, val: 0x%x\n", __func__, i, (SWRM_DP_PORT_CTRL_BANK(i + 1, bank)), value); + if (mport->lane_ctrl != SWR_INVALID_PARAM) { + reg[len] = SWRM_DP_PORT_CTRL_2_BANK(i + 1, bank); + val[len++] = mport->lane_ctrl; + } + if (mport->word_length != SWR_INVALID_PARAM) { + reg[len] = SWRM_DP_BLOCK_CTRL_1(i + 1); + val[len++] = mport->word_length; + } + + if (mport->blk_grp_count != SWR_INVALID_PARAM) { + reg[len] = SWRM_DP_BLOCK_CTRL2_BANK(i + 1, bank); + val[len++] = mport->blk_grp_count; + } + if (mport->hstart != SWR_INVALID_PARAM + && mport->hstop != SWR_INVALID_PARAM) { + reg[len] = SWRM_DP_PORT_HCTRL_BANK(i + 1, bank); + hparams = (mport->hstart << 4) | mport->hstop; + val[len++] = hparams; + } + if (mport->blk_pack_mode != SWR_INVALID_PARAM) { + reg[len] = SWRM_DP_BLOCK_CTRL3_BANK(i + 1, bank); + val[len++] = mport->blk_pack_mode; + } mport->ch_en = mport->req_ch; } @@ -826,7 +906,7 @@ static void swrm_apply_port_config(struct swr_master *master) static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) { u8 bank; - u32 value, n_col; + u32 value, n_row, n_col; int ret; struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK | @@ -863,21 +943,22 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) __func__, enable, swrm->num_cfg_devs); if (enable) { - /* set Row = 48 and col = 16 */ + /* set col = 16 */ n_col = SWR_MAX_COL; } else { /* - * Do not change to 48x2 if there are still active ports + * Do not change to col = 2 if there are still active ports */ if (!master->num_port) n_col = SWR_MIN_COL; else n_col = SWR_MAX_COL; } - + /* Use default 50 * x, frame shape. Change based on mclk */ + n_row = SWR_ROW_50; value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank)); value &= (~mask); - value |= ((0 << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | + value |= ((n_row << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | (n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) | (0 << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT)); swr_master_write(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value); @@ -885,7 +966,7 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) dev_dbg(swrm->dev, "%s: regaddr: 0x%x, value: 0x%x\n", __func__, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value); - enable_bank_switch(swrm, bank, SWR_MAX_ROW, n_col); + enable_bank_switch(swrm, bank, n_row, n_col); inactive_bank = bank ? 0 : 1; if (enable) @@ -1288,7 +1369,7 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) { int ret = 0; u32 val; - u8 row_ctrl = SWR_MAX_ROW; + u8 row_ctrl = SWR_ROW_50; u8 col_ctrl = SWR_MIN_COL; u8 ssp_period = 1; u8 retry_cmd_num = 3; @@ -1374,6 +1455,12 @@ static int swrm_probe(struct platform_device *pdev) ret = -EINVAL; goto err_pdata_fail; } + ret = of_property_read_u32(pdev->dev.of_node, "qcom,swr_master_id", + &swrm->master_id); + if (ret) { + dev_err(&pdev->dev, "%s: failed to get master id\n", __func__); + goto err_pdata_fail; + } if (!(of_property_read_u32(pdev->dev.of_node, "swrm-io-base", &swrm->swrm_base_reg))) ret = of_property_read_u32(pdev->dev.of_node, @@ -1412,7 +1499,11 @@ static int swrm_probe(struct platform_device *pdev) ret = -EINVAL; goto err_pdata_fail; } - + if (of_property_read_u32(pdev->dev.of_node, + "qcom,swr-clock-stop-mode0", + &swrm->clk_stop_mode0_supp)) { + swrm->clk_stop_mode0_supp = FALSE; + } /* Parse soundwire port mapping */ ret = of_property_read_u32(pdev->dev.of_node, "qcom,swr-num-ports", &num_ports); @@ -1648,15 +1739,21 @@ static int swrm_runtime_resume(struct device *dev) if (swrm_clk_request(swrm, true)) goto exit; } - list_for_each_entry(swr_dev, &mstr->devices, dev_list) { - ret = swr_device_up(swr_dev); - if (ret) { - dev_err(dev, - "%s: failed to wakeup swr dev %d\n", - __func__, swr_dev->dev_num); - swrm_clk_request(swrm, false); - goto exit; + if (!swrm->clk_stop_mode0_supp) { + list_for_each_entry(swr_dev, &mstr->devices, dev_list) { + ret = swr_device_up(swr_dev); + if (ret) { + dev_err(dev, + "%s: failed to wakeup swr dev %d\n", + __func__, swr_dev->dev_num); + swrm_clk_request(swrm, false); + goto exit; + } } + } else { + /*wake up from clock stop*/ + swr_master_write(swrm, SWRM_MCP_BUS_CTRL_ADDR, 0x2); + usleep_range(100, 105); } swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01); swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01); @@ -1693,16 +1790,23 @@ static int swrm_runtime_suspend(struct device *dev) ret = -EBUSY; goto exit; } - swrm_clk_pause(swrm); - swr_master_write(swrm, SWRM_COMP_CFG_ADDR, 0x00); - list_for_each_entry(swr_dev, &mstr->devices, dev_list) { - ret = swr_device_down(swr_dev); - if (ret) { - dev_err(dev, - "%s: failed to shutdown swr dev %d\n", - __func__, swr_dev->dev_num); - goto exit; + if (!swrm->clk_stop_mode0_supp) { + swrm_clk_pause(swrm); + swr_master_write(swrm, SWRM_COMP_CFG_ADDR, 0x00); + list_for_each_entry(swr_dev, &mstr->devices, dev_list) { + ret = swr_device_down(swr_dev); + if (ret) { + dev_err(dev, + "%s: failed to shutdown swr dev %d\n", + __func__, swr_dev->dev_num); + goto exit; + } } + } else { + /* clock stop sequence */ + swrm_cmd_fifo_wr_cmd(swrm, 0x2, 0xF, 0xF, + SWRS_SCP_CONTROL); + usleep_range(100, 105); } swrm_clk_request(swrm, false); } diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 075ace9bd632..59c7e76c94b3 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -15,7 +15,9 @@ #include #include -#define SWR_MAX_ROW 0 /* Rows = 48 */ +#define SWR_ROW_48 0 +#define SWR_ROW_50 1 +#define SWR_ROW_64 2 #define SWR_MAX_COL 7 /* Cols = 16 */ #define SWR_MIN_COL 0 /* Cols = 2 */ @@ -62,6 +64,12 @@ struct port_params { u8 si; u8 off1; u8 off2; + u8 hstart;/* head start */ + u8 hstop; /* head stop */ + u8 wd_len;/* word length */ + u8 bp_mode; /* block pack mode */ + u8 bgp_ctrl;/* block group control */ + u8 lane_ctrl;/* lane to be used */ }; struct swrm_mports { @@ -77,6 +85,8 @@ struct swrm_mports { u8 hstop; u8 blk_grp_count; u8 blk_pack_mode; + u8 word_length; + u8 lane_ctrl; }; struct swrm_port_type { @@ -109,6 +119,7 @@ struct swr_mstr_ctrl { char __iomem *swrm_dig_base; u8 rcmd_id; u8 wcmd_id; + u32 master_id; void *handle; /* SWR Master handle from client for read and writes */ int (*read)(void *handle, int reg); int (*write)(void *handle, int reg, int val); @@ -132,6 +143,7 @@ struct swr_mstr_ctrl { struct swrm_port_type port_mapping[SWR_MSTR_PORT_LEN][SWR_MAX_CH_PER_PORT]; int swr_irq; + u32 clk_stop_mode0_supp; }; #endif /* _SWR_WCD_CTRL_H */ diff --git a/soc/swrm_port_config.h b/soc/swrm_port_config.h index 64ff6002fcc6..86cc9221a1da 100644 --- a/soc/swrm_port_config.h +++ b/soc/swrm_port_config.h @@ -15,15 +15,44 @@ #define WSA_MSTR_PORT_MASK 0xFF + +/* + * Add port configuration in the format + *{ si, off1, off2, hstart, hstop, wd_len, bp_mode, bgp_ctrl, lane_ctrl} + */ + struct port_params wsa_frame_superset[SWR_MSTR_PORT_LEN] = { - {7, 1, 0}, - {31, 2, 0}, - {63, 12, 31}, - {7, 6, 0}, - {31, 18, 0}, - {63, 13, 31}, - {15, 7, 0}, - {15, 10, 0}, + {7, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {31, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {63, 12, 31, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {7, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {31, 18, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {63, 13, 31, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {15, 7, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {15, 10, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, +}; + +struct port_params rx_frame_params[SWR_MSTR_PORT_LEN] = { + {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1}, + {31, 0, 0, 3, 6, 7, 0, 0xFF, 0}, + {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0}, + {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0}, + {0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0}, +}; + +struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = { + {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1}, + {31, 0, 0, 3, 6, 7, 0, 0xFF, 0}, + {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0}, + {7, 9, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0}, + {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 3, 0}, +}; + +struct port_params tx_frame_params_superset[SWR_MSTR_PORT_LEN] = { + {1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, + {1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, + {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, + {3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, }; #endif /* _SWRM_REGISTERS_H */ -- GitLab From d1b694d0bb51f9def7eef7a3858ce69f8d085510 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 31 Aug 2018 11:47:32 +0530 Subject: [PATCH 0491/1645] ASoC: bolero: Change params for vi feedback Change max no of channels supported, format and rates for wsa macro vi feedback. CRs-Fixed: 2281591 Change-Id: Ie54ce4f63a02d661939ed732b388a3c26dd8ea2f Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/wsa-macro.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index ecfe28f15f00..fc4105a0d7ef 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -354,12 +354,12 @@ static struct snd_soc_dai_driver wsa_macro_dai[] = { .id = WSA_MACRO_AIF_VI, .capture = { .stream_name = "WSA_AIF_VI Capture", - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S32_LE, - .rate_max = 8000, + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, + .formats = WSA_MACRO_RX_FORMATS, + .rate_max = 48000, .rate_min = 8000, .channels_min = 1, - .channels_max = 2, + .channels_max = 4, }, .ops = &wsa_macro_dai_ops, }, -- GitLab From e003f502de50e901bac68a9a240dd35ea6f800ba Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 31 Aug 2018 11:59:15 +0530 Subject: [PATCH 0492/1645] dsp: Add macro for packed 16B format CDC DMA TX uses PACKED_16B format if speaker prot is enabled. Add macro AFE_LINEAR_PCM_DATA_PACKED_16BIT for proper value of format. Change-Id: I1070e00d26a18c77e26ff2518ef4a1256a674e20 Signed-off-by: Vatsal Bucha --- include/dsp/apr_audio-v2.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 4ce997384d31..73304fb545ec 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -2225,6 +2225,7 @@ struct afe_port_data_cmd_rt_proxy_port_read_v2 { #define AFE_LINEAR_PCM_DATA_PACKED_60958 0x2 #define AFE_NON_LINEAR_DATA_PACKED_60958 0x3 #define AFE_GENERIC_COMPRESSED 0x8 +#define AFE_LINEAR_PCM_DATA_PACKED_16BIT 0X6 /* This param id is used to configure I2S interface */ #define AFE_PARAM_ID_I2S_CONFIG 0x0001020D -- GitLab From 680384aad13dde90233d1a47da7bc7d7ed2bcec2 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 31 Aug 2018 11:50:42 +0530 Subject: [PATCH 0493/1645] ASoC: Update params for CDC_DMA to fix speaker protection Update channels_max and dai_format for cdc dma hostless, cdc dma playback and capture to fix speaker protection. Also, use correct struct i.e. msm_dai_q6_cdc_dma_dai_data in get/put functions. Change-Id: I8f37a0c9411054830fdec2b4c072315c882ffc7c Signed-off-by: Vatsal Bucha --- asoc/msm-dai-fe.c | 2 +- asoc/msm-dai-q6-v2.c | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index c352cb379cb4..3ae1cc2733b5 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -549,7 +549,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 2, + .channels_max = 4, .rate_min = 8000, .rate_max = 384000, }, diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index bc5778759b7d..19952c87b5ff 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -9594,7 +9594,7 @@ static struct platform_driver msm_dai_q6_tdm_driver = { static int msm_dai_q6_cdc_dma_format_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + struct msm_dai_q6_cdc_dma_dai_data *dai_data = kcontrol->private_data; int value = ucontrol->value.integer.value[0]; dai_data->port_config.cdc_dma.data_format = value; @@ -9605,7 +9605,7 @@ static int msm_dai_q6_cdc_dma_format_put(struct snd_kcontrol *kcontrol, static int msm_dai_q6_cdc_dma_format_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + struct msm_dai_q6_cdc_dma_dai_data *dai_data = kcontrol->private_data; ucontrol->value.integer.value[0] = dai_data->port_config.cdc_dma.data_format; @@ -9807,6 +9807,11 @@ static int msm_dai_q6_cdc_dma_prepare(struct snd_pcm_substream *substream, pr_err("%s: afe send island mode failed %d\n", __func__, rc); } + if ((dai->id == AFE_PORT_ID_WSA_CODEC_DMA_TX_0) && + (dai_data->port_config.cdc_dma.data_format == 1)) + dai_data->port_config.cdc_dma.data_format = + AFE_LINEAR_PCM_DATA_PACKED_16BIT; + rc = afe_port_start(dai->id, &dai_data->port_config, dai_data->rate); if (rc < 0) @@ -9867,7 +9872,7 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 2, + .channels_max = 4, .rate_min = 8000, .rate_max = 384000, }, @@ -9893,7 +9898,7 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 2, + .channels_max = 4, .rate_min = 8000, .rate_max = 384000, }, -- GitLab From 89262e64f99e20104533a83ae080ae57ceb68ffa Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 31 Aug 2018 11:57:09 +0530 Subject: [PATCH 0494/1645] ASoC: sm6150: Add vi_feed_tx channels to common controls VI_Feed_TX Channels is common for both internal and external codec. Add it in common controls. Change-Id: I9354adebc3238a4d332e244d9dedccf02ddd9604 Signed-off-by: Vatsal Bucha --- asoc/sm6150.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 8d9d32dc283e..cff5b56a04a9 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -3386,8 +3386,6 @@ static const struct snd_kcontrol_new msm_tavil_snd_controls[] = { slim_rx_ch_get, slim_rx_ch_put), SOC_ENUM_EXT("SLIM_6_RX Channels", slim_6_rx_chs, slim_rx_ch_get, slim_rx_ch_put), - SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, - msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format, slim_rx_bit_format_get, slim_rx_bit_format_put), SOC_ENUM_EXT("SLIM_5_RX Format", slim_5_rx_format, @@ -3647,6 +3645,8 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, msm_bt_sample_rate_get, msm_bt_sample_rate_put), + SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, + msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), }; static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, -- GitLab From 8d16db1ee12def08597798f392e78d24f1fba672 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Wed, 29 Aug 2018 12:09:32 +0530 Subject: [PATCH 0495/1645] dsp: updates to MDF for enabling access control Add access specifiers to MDF memory for DSPs in the system. Change-Id: Ifa36394a8892fdd8a9ee6d25f2671a90c384d4e8 Signed-off-by: Mangesh Kunchamwar --- dsp/msm_mdf.c | 127 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 109 insertions(+), 18 deletions(-) diff --git a/dsp/msm_mdf.c b/dsp/msm_mdf.c index 849b76ce230d..9c73e55f12dd 100644 --- a/dsp/msm_mdf.c +++ b/dsp/msm_mdf.c @@ -34,13 +34,15 @@ #include #include #include +#include #include #include +#include #define VMID_SSC_Q6 5 #define VMID_LPASS 6 #define VMID_MSS_MSA 15 -#define VMID_CDSP 8 +#define VMID_CDSP 30 #define MSM_MDF_PROBED (1 << 0) #define MSM_MDF_INITIALIZED (1 << 1) @@ -56,6 +58,13 @@ #define ADSP_STATE_READY_TIMEOUT_MS 3000 +/* mem protection defines */ +#define TZ_MPU_LOCK_NS_REGION 0x00000025 +#define MEM_PROTECT_AC_PERM_READ 0x4 +#define MEM_PROTECT_AC_PERM_WRITE 0x2 + +#define MSM_AUDIO_SMMU_SID_OFFSET 32 + enum { SUBSYS_ADSP, /* Audio DSP must have index 0 */ SUBSYS_SCC, /* Sensor DSP */ @@ -64,6 +73,24 @@ enum { SUBSYS_MAX, }; +struct msm_mdf_dest_vm_and_perm_info { + uint32_t dst_vm; + /* Destination VM defined by ACVirtualMachineId. */ + uint32_t dst_vm_perm; + /* Permissions of the IPA to be mapped to VM, bitwise OR of AC_PERM. */ + uint64_t ctx; + /* Destination of the VM-specific context information. */ + uint32_t ctx_size; + /* Size of context buffer in bytes. */ +}; + +struct msm_mdf_protect_mem { + uint64_t dma_start_address; + uint64_t dma_end_address; + struct msm_mdf_dest_vm_and_perm_info dest_info[SUBSYS_MAX]; + uint32_t dest_info_size; +}; + struct msm_mdf_mem { struct device *dev; uint8_t device_status; @@ -180,8 +207,8 @@ static int msm_mdf_dma_buf_map(struct msm_mdf_mem *mem, return -ENODEV; } - smmu->pa = dma_map_single(smmu->cb_dev, mem->va, - mem->size, DMA_BIDIRECTIONAL); + smmu->pa = dma_map_single_attrs(smmu->cb_dev, mem->va, + mem->size, DMA_BIDIRECTIONAL, DMA_ATTR_SKIP_CPU_SYNC); if (dma_mapping_error(smmu->cb_dev, smmu->pa)) { rc = -ENOMEM; pr_err("%s: failed to map single, rc = %d\n", @@ -223,8 +250,8 @@ static int msm_mdf_alloc_dma_buf(struct msm_mdf_mem *mem) return -ENODEV; } - mem->va = dma_alloc_coherent(mem->dev, mem->size, - &mem->dma_addr, GFP_KERNEL); + mem->va = dma_alloc_attrs(mem->dev, mem->size, + &mem->dma_addr, GFP_KERNEL, DMA_ATTR_NO_KERNEL_MAPPING); if (IS_ERR_OR_NULL(mem->va)) { pr_err("%s: failed to allocate dma memory, rc = %d\n", __func__, rc); @@ -319,6 +346,51 @@ static void msm_mdf_unmap_memory_to_subsys(struct msm_mdf_mem *mem, } } +static int msm_mdf_assign_memory_to_subsys(struct msm_mdf_mem *mem) +{ + int ret = 0, i; + struct scm_desc desc = {0}; + struct msm_mdf_protect_mem *scm_buffer; + uint32_t fnid; + + scm_buffer = kzalloc(sizeof(struct msm_mdf_protect_mem), GFP_KERNEL); + if (!scm_buffer) + return -ENOMEM; + + scm_buffer->dma_start_address = mem->dma_addr; + scm_buffer->dma_end_address = mem->dma_addr + buf_page_size(mem->size); + for (i = 0; i < SUBSYS_MAX; i++) { + scm_buffer->dest_info[i].dst_vm = mdf_smmu_data[i].vmid; + scm_buffer->dest_info[i].dst_vm_perm = + MEM_PROTECT_AC_PERM_READ | MEM_PROTECT_AC_PERM_WRITE; + scm_buffer->dest_info[i].ctx = 0; + scm_buffer->dest_info[i].ctx_size = 0; + } + scm_buffer->dest_info_size = + sizeof(struct msm_mdf_dest_vm_and_perm_info) * SUBSYS_MAX; + + /* flush cache required by scm_call2 */ + dmac_flush_range(scm_buffer, ((void *)scm_buffer) + + sizeof(struct msm_mdf_protect_mem)); + + desc.args[0] = scm_buffer->dma_start_address; + desc.args[1] = scm_buffer->dma_end_address; + desc.args[2] = virt_to_phys(&(scm_buffer->dest_info[0])); + desc.args[3] = scm_buffer->dest_info_size; + + desc.arginfo = SCM_ARGS(4, SCM_VAL, SCM_VAL, SCM_RO, SCM_VAL); + + fnid = SCM_SIP_FNID(SCM_SVC_MP, TZ_MPU_LOCK_NS_REGION); + ret = scm_call2(fnid, &desc); + if (ret < 0) { + pr_err("%s: SCM call2 failed, ret %d scm_resp %llu\n", + __func__, ret, desc.ret[0]); + } + /* No More need for scm_buffer, freeing the same */ + kfree(scm_buffer); + return ret; +} + /** * msm_mdf_mem_init - Initializes MDF memory pool and * map memory to subsystem @@ -378,6 +450,13 @@ int msm_mdf_mem_init(void) } } + rc = msm_mdf_assign_memory_to_subsys(mem); + if (rc) { + pr_err("%s: msm_mdf_assign_memory_to_subsys failed\n", + __func__); + goto err; + } + for (j = 0; j < SUBSYS_MAX; j++) { smmu = &mdf_smmu_data[j]; rc = msm_mdf_map_memory_to_subsys(mem, smmu); @@ -479,6 +558,9 @@ MODULE_DEVICE_TABLE(of, msm_mdf_match_table); static int msm_mdf_cb_probe(struct device *dev) { struct msm_mdf_smmu *smmu; + u64 smmu_sid = 0; + u64 smmu_sid_mask = 0; + struct of_phandle_args iommuspec; const char *subsys; int rc = 0, i; @@ -511,22 +593,31 @@ static int msm_mdf_cb_probe(struct device *dev) smmu->subsys); if (smmu->enabled) { - if (!strcmp("adsp", smmu->subsys)) { - /* Get SMMU info from audio ION */ - rc = msm_audio_ion_get_smmu_info(&smmu->cb_dev, - &smmu->sid); - if (rc) { - dev_err(dev, "%s: msm_audio_ion_get_smmu_info failed, rc = %d\n", - __func__, rc); - goto err; - } + /* Get SMMU SID information from Devicetree */ + rc = of_property_read_u64(dev->of_node, + "qcom,smmu-sid-mask", + &smmu_sid_mask); + if (rc) { + dev_err(dev, + "%s: qcom,smmu-sid-mask missing in DT node, using default\n", + __func__); + smmu_sid_mask = 0xFFFFFFFFFFFFFFFF; } - } else { - /* Setup SMMU CB if enabled for subsys other than ADSP */ + + rc = of_parse_phandle_with_args(dev->of_node, "iommus", + "#iommu-cells", 0, &iommuspec); + if (rc) + dev_err(dev, "%s: could not get smmu SID, ret = %d\n", + __func__, rc); + else + smmu_sid = (iommuspec.args[0] & smmu_sid_mask); + + smmu->sid = + smmu_sid << MSM_AUDIO_SMMU_SID_OFFSET; + + smmu->cb_dev = dev; } return 0; -err: - return rc; } static int msm_mdf_remove(struct platform_device *pdev) -- GitLab From 4ae32fc38e87788b1420ac46fe3f166f7cc81e6c Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 13 Aug 2018 13:08:34 +0530 Subject: [PATCH 0496/1645] asoc: Add codec entry node for wcd937x to support ADIE RTAC Add changes to create codec entry node for wcd937x to support ADIE RTC calibration. CRs-Fixed: 2281591 Change-Id: I87f3c94995a8ec0c8c5e056891cb293946683885 Signed-off-by: Aditya Bavanari --- asoc/codecs/wcd937x/internal.h | 7 +++ asoc/codecs/wcd937x/wcd937x.c | 93 ++++++++++++++++++++++++++++++++++ asoc/sm6150.c | 55 +++++++++++++++----- 3 files changed, 143 insertions(+), 12 deletions(-) diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index 06e64d038b73..f85c7f658cdf 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -72,6 +72,11 @@ struct wcd937x_priv { struct codec_port_info rx_port_mapping[MAX_PORT][MAX_CH_PER_PORT]; struct regulator_bulk_data *supplies; + + u32 version; + /* Entry for version info */ + struct snd_info_entry *entry; + struct snd_info_entry *version_entry; }; struct wcd937x_micbias_setting { @@ -126,4 +131,6 @@ extern int wcd937x_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, extern int wcd937x_get_micb_vout_ctl_val(u32 micb_mv); extern int wcd937x_micbias_control(struct snd_soc_codec *codec, int micb_num, int req, bool is_dapm); +extern int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_codec *codec); #endif diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index d60b9f37b673..9e033ca81bda 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -36,6 +36,9 @@ #define NUM_SWRS_DT_PARAMS 5 +#define WCD937X_VERSION_1_0 1 +#define WCD937X_VERSION_ENTRY_SIZE 32 + enum { CODEC_TX = 0, CODEC_RX, @@ -1564,6 +1567,95 @@ static const struct snd_soc_dapm_route wcd9375_audio_map[] = { }; +static ssize_t wcd937x_version_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, size_t count, + loff_t pos) +{ + struct wcd937x_priv *priv; + char buffer[WCD937X_VERSION_ENTRY_SIZE]; + int len = 0; + + priv = (struct wcd937x_priv *) entry->private_data; + if (!priv) { + pr_err("%s: wcd937x priv is null\n", __func__); + return -EINVAL; + } + + switch (priv->version) { + case WCD937X_VERSION_1_0: + len = snprintf(buffer, sizeof(buffer), "WCD937X_1_0\n"); + break; + default: + len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + } + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops wcd937x_info_ops = { + .read = wcd937x_version_read, +}; + +/* + * wcd937x_info_create_codec_entry - creates wcd937x module + * @codec_root: The parent directory + * @codec: Codec instance + * + * Creates wcd937x module and version entry under the given + * parent directory. + * + * Return: 0 on success or negative error code on failure. + */ +int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + struct snd_info_entry *version_entry; + struct wcd937x_priv *priv; + struct snd_soc_card *card; + + if (!codec_root || !codec) + return -EINVAL; + + priv = snd_soc_codec_get_drvdata(codec); + if (priv->entry) { + dev_dbg(priv->dev, + "%s:wcd937x module already created\n", __func__); + return 0; + } + card = codec->component.card; + priv->entry = snd_info_create_subdir(codec_root->module, + "wcd937x", codec_root); + if (!priv->entry) { + dev_dbg(codec->dev, "%s: failed to create wcd937x entry\n", + __func__); + return -ENOMEM; + } + version_entry = snd_info_create_card_entry(card->snd_card, + "version", + priv->entry); + if (!version_entry) { + dev_dbg(codec->dev, "%s: failed to create wcd937x version entry\n", + __func__); + return -ENOMEM; + } + + version_entry->private_data = priv; + version_entry->size = WCD937X_VERSION_ENTRY_SIZE; + version_entry->content = SNDRV_INFO_CONTENT_DATA; + version_entry->c.ops = &wcd937x_info_ops; + + if (snd_info_register(version_entry) < 0) { + snd_info_free_entry(version_entry); + return -ENOMEM; + } + priv->version_entry = version_entry; + + return 0; +} +EXPORT_SYMBOL(wcd937x_info_create_codec_entry); + static int wcd937x_soc_codec_probe(struct snd_soc_codec *codec) { struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); @@ -1630,6 +1722,7 @@ static int wcd937x_soc_codec_probe(struct snd_soc_codec *codec) goto err_hwdep; } } + wcd937x->version = WCD937X_VERSION_1_0; return ret; err_hwdep: diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 46b5c70b9494..e35800804e30 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -41,6 +41,7 @@ #include "codecs/bolero/bolero-cdc.h" #include #include "codecs/bolero/wsa-macro.h" +#include "codecs/wcd937x/internal.h" #define DRV_NAME "sm6150-asoc-snd" @@ -4915,15 +4916,17 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) } } card = rtd->card->snd_card; - entry = snd_info_create_subdir(card->module, "codecs", - card->proc_root); - if (!entry) { - pr_debug("%s: Cannot create codecs module entry\n", - __func__); - ret = 0; - goto err; + if (!pdata->codec_root) { + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto err; + } + pdata->codec_root = entry; } - pdata->codec_root = entry; bolero_info_create_codec_entry(pdata->codec_root, codec); codec_reg_done = true; return 0; @@ -7878,6 +7881,8 @@ static int msm_wsa881x_init(struct snd_soc_component *component) struct snd_soc_codec *codec = snd_soc_component_to_codec(component); struct msm_asoc_mach_data *pdata; struct snd_soc_dapm_context *dapm; + struct snd_card *card = component->card->snd_card; + struct snd_info_entry *entry; int ret = 0; if (!codec) { @@ -7914,10 +7919,19 @@ static int msm_wsa881x_init(struct snd_soc_component *component) goto err; } pdata = snd_soc_card_get_drvdata(component->card); - if (pdata && pdata->codec_root) - wsa881x_codec_info_create_codec_entry(pdata->codec_root, - codec); - + if (!pdata->codec_root) { + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_err("%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto err; + } + pdata->codec_root = entry; + } + wsa881x_codec_info_create_codec_entry(pdata->codec_root, + codec); err: return ret; } @@ -7928,6 +7942,9 @@ static int msm_aux_codec_init(struct snd_soc_component *component) struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); int ret = 0; void *mbhc_calibration; + struct snd_info_entry *entry; + struct snd_card *card = component->card->snd_card; + struct msm_asoc_mach_data *pdata; snd_soc_dapm_ignore_suspend(dapm, "EAR"); snd_soc_dapm_ignore_suspend(dapm, "AUX"); @@ -7939,6 +7956,20 @@ static int msm_aux_codec_init(struct snd_soc_component *component) snd_soc_dapm_ignore_suspend(dapm, "AMIC4"); snd_soc_dapm_sync(dapm); + pdata = snd_soc_card_get_drvdata(component->card); + if (!pdata->codec_root) { + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_err("%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto codec_root_err; + } + pdata->codec_root = entry; + } + wcd937x_info_create_codec_entry(pdata->codec_root, codec); +codec_root_err: mbhc_calibration = def_wcd_mbhc_cal(); if (!mbhc_calibration) { return -ENOMEM; -- GitLab From 4d7fb3fca934e800bebe0ca06e285741688763de Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 31 Aug 2018 11:02:53 -0700 Subject: [PATCH 0497/1645] asoc: codecs: add missing mbhc register for wcd9335 IN2P clamp state mbhc register was added in tavil codec to fix fake insertion irq. Add this register in wcd9335 as well for proper indexing of mbhc registers. Change-Id: I93038c4e215bd75b42e895835773b6854d523dd5 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd9335.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 8564ac1a00c3..5de60c2f92fa 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -613,6 +613,8 @@ static struct wcd_mbhc_register WCD9335_MBHC_CTL_2, 0x03, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT", WCD9335_ANA_MBHC_RESULT_3, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_IN2P_CLAMP_STATE", + WCD9335_ANA_MBHC_RESULT_3, 0x10, 4, 0), WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT", WCD9335_ANA_MBHC_RESULT_3, 0x20, 5, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT", -- GitLab From 4721b16381136dc1aad03ba726ed4818173ab51f Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 31 Aug 2018 15:20:21 +0530 Subject: [PATCH 0498/1645] soc: swr-mstr-ctrl: porting fix from wcd controller to mstr controller When temperature on a single wsa881x device is being read, then soundwire master wakes up both wsa881x devices but regcache_sync is happening only for one wsa881x device on which the temperature is being read. This results in audio playback mute after temperature read. Fix the regcache sync during temperature read and playback usecase. Change-Id: Icee46d5105bb449f14855d33bdcb00cf5c77cb91 Signed-off-by: Laxminath Kasam --- soc/swr-mstr-ctrl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index a9d755b89442..06b20d678c35 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1879,6 +1879,8 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) (swrm->state == SWR_MSTR_UP)) { dev_dbg(swrm->dev, "%s: SWR master is already UP: %d\n", __func__, swrm->state); + list_for_each_entry(swr_dev, &mstr->devices, dev_list) + swr_reset_device(swr_dev); } else { pm_runtime_mark_last_busy(&pdev->dev); mutex_unlock(&swrm->reslock); -- GitLab From c8d52a1f562831195a6c9db662a6d80d992930d8 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Fri, 31 Aug 2018 02:30:00 +0530 Subject: [PATCH 0499/1645] soc: swr-mstr: fix noise issue with mono speaker Fix noise issue with mono speaker by properly disabling the previous port config. Change-Id: I55fde87fcea5c8a7f05ff82a0d8967bc7688882b Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index a9d755b89442..5c2fcdbcd089 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -725,7 +725,7 @@ static void swrm_cleanup_disabled_port_reqs(struct swr_master *master) continue; /* remove new ch req's*/ - port_req->req_ch = port_req->ch_en; + port_req->ch_en = port_req->req_ch; /* If no streams enabled on port, remove the port req */ if (port_req->ch_en == 0) { @@ -734,7 +734,7 @@ static void swrm_cleanup_disabled_port_reqs(struct swr_master *master) } } /* remove new ch req's on mport*/ - mport->req_ch = mport->ch_en; + mport->ch_en = mport->req_ch; if (!(mport->ch_en)) { mport->port_en = false; -- GitLab From 9eb80226a08d6e66f6be51a09bc05c257dcf9f45 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 29 Aug 2018 21:53:14 +0530 Subject: [PATCH 0500/1645] asoc: bolero: fix pop issue at start of record Observe pop at start of recording. Change the order of HPF setting in decimator enable path and update freq_change bit for HPF corner frequency change. Change-Id: I6257671224a792a2afd71209fdc4e0102a83ced8 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/tx-macro.c | 40 +++++++++++++++++++++++++-------- asoc/codecs/bolero/va-macro.c | 42 ++++++++++++++++++++++++++--------- 2 files changed, 63 insertions(+), 19 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index f8c762b8c91c..4f9736efeef4 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -296,7 +296,7 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) struct hpf_work *hpf_work = NULL; struct tx_macro_priv *tx_priv = NULL; struct snd_soc_codec *codec = NULL; - u16 dec_cfg_reg = 0; + u16 dec_cfg_reg = 0, hpf_gate_reg = 0; u8 hpf_cut_off_freq = 0; hpf_delayed_work = to_delayed_work(work); @@ -307,12 +307,18 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) dec_cfg_reg = BOLERO_CDC_TX0_TX_PATH_CFG0 + TX_MACRO_TX_PATH_OFFSET * hpf_work->decimator; + hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 + + TX_MACRO_TX_PATH_OFFSET * hpf_work->decimator; dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", __func__, hpf_work->decimator, hpf_cut_off_freq); snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, hpf_cut_off_freq << 5); + snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); + /* Minimum 1 clk cycle delay is required as per HW spec */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00); } static void tx_macro_mute_update_callback(struct work_struct *work) @@ -573,6 +579,13 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + /* Enable TX PGA Mute */ + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x20, 0x20); + snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00); + hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) & TX_HPF_CUT_OFF_FREQ_MASK) >> 5; tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq = @@ -582,21 +595,21 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, CF_MIN_3DB_150HZ << 5); - /* Enable TX PGA Mute */ - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); - break; - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x20, 0x20); - snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00); - /* schedule work queue to Remove Mute */ schedule_delayed_work(&tx_priv->tx_mute_dwork[decimator].dwork, msecs_to_jiffies(tx_unmute_delay)); if (tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq != - CF_MIN_3DB_150HZ) + CF_MIN_3DB_150HZ) { schedule_delayed_work( &tx_priv->tx_hpf_work[decimator].dwork, msecs_to_jiffies(300)); + snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); + /* + * Minimum 1 clk cycle delay is required as per HW spec + */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00); + } /* apply gain after decimator is enabled */ snd_soc_write(codec, tx_gain_ctl_reg, snd_soc_read(codec, tx_gain_ctl_reg)); @@ -611,6 +624,15 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, hpf_cut_off_freq << 5); + snd_soc_update_bits(codec, hpf_gate_reg, + 0x02, 0x02); + /* + * Minimum 1 clk cycle delay is required + * as per HW spec + */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, hpf_gate_reg, + 0x02, 0x00); } } cancel_delayed_work_sync( diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index f2a2d62f3869..03bdfa19a7ef 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -245,7 +245,7 @@ static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) struct hpf_work *hpf_work; struct va_macro_priv *va_priv; struct snd_soc_codec *codec; - u16 dec_cfg_reg; + u16 dec_cfg_reg, hpf_gate_reg; u8 hpf_cut_off_freq; hpf_delayed_work = to_delayed_work(work); @@ -256,12 +256,18 @@ static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) dec_cfg_reg = BOLERO_CDC_VA_TX0_TX_PATH_CFG0 + VA_MACRO_TX_PATH_OFFSET * hpf_work->decimator; + hpf_gate_reg = BOLERO_CDC_VA_TX0_TX_PATH_SEC2 + + VA_MACRO_TX_PATH_OFFSET * hpf_work->decimator; dev_dbg(va_priv->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", __func__, hpf_work->decimator, hpf_cut_off_freq); snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, hpf_cut_off_freq << 5); + snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); + /* Minimum 1 clk cycle delay is required as per HW spec */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00); } static void va_macro_mute_update_callback(struct work_struct *work) @@ -512,15 +518,6 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) & - TX_HPF_CUT_OFF_FREQ_MASK) >> 5; - va_priv->va_hpf_work[decimator].hpf_cut_off_freq = - hpf_cut_off_freq; - - if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) - snd_soc_update_bits(codec, dec_cfg_reg, - TX_HPF_CUT_OFF_FREQ_MASK, - CF_MIN_3DB_150HZ << 5); /* Enable TX PGA Mute */ snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); break; @@ -529,6 +526,22 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x20, 0x20); snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00); + hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) & + TX_HPF_CUT_OFF_FREQ_MASK) >> 5; + va_priv->va_hpf_work[decimator].hpf_cut_off_freq = + hpf_cut_off_freq; + + if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { + snd_soc_update_bits(codec, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + CF_MIN_3DB_150HZ << 5); + snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); + /* + * Minimum 1 clk cycle delay is required as per HW spec + */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00); + } /* schedule work queue to Remove Mute */ schedule_delayed_work(&va_priv->va_mute_dwork[decimator].dwork, msecs_to_jiffies(va_tx_unmute_delay)); @@ -551,6 +564,15 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, hpf_cut_off_freq << 5); + snd_soc_update_bits(codec, hpf_gate_reg, + 0x02, 0x02); + /* + * Minimum 1 clk cycle delay is required + * as per HW spec + */ + usleep_range(1000, 1010); + snd_soc_update_bits(codec, hpf_gate_reg, + 0x02, 0x00); } } cancel_delayed_work_sync( -- GitLab From 201911d93e34dd623878220bf75421381ae93017 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 29 Aug 2018 11:27:34 +0530 Subject: [PATCH 0501/1645] asoc: wcd937x: fix wcd9375 widgets override issue wcd9375 widgets addition override wcd9370 widgets registered already in dapm. Need to call snd_soc_dapm_sync only after adding new widgets/routes. Change-Id: I285d2f971ca2daae865156e050904fdcc9ea8c3c signed-off-by: Ramprasad Katkam --- asoc/codecs/wcd937x/wcd937x.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index d60b9f37b673..3056b26e13db 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1623,12 +1623,7 @@ static int wcd937x_soc_codec_probe(struct snd_soc_codec *codec) __func__); goto err_hwdep; } - ret = snd_soc_dapm_new_widgets(dapm->card); - if (ret < 0) { - dev_err(codec->dev, "%s: Failed to add widgets\n", - __func__); - goto err_hwdep; - } + snd_soc_dapm_sync(dapm); } return ret; -- GitLab From b5528d39f2247f71d9f71883cb3d27c90c31b910 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Fri, 31 Aug 2018 03:29:24 +0530 Subject: [PATCH 0502/1645] dsp: add blocking call support in event notifier Add support for blocking call events in event notifier to support functions which require waiting for events. Change-Id: I255c19bc956506ea5076bb5fb1f09327141611a6 Signed-off-by: Ramprasad Katkam --- dsp/msm-audio-event-notify.c | 36 ++++++++++++++++++++++++++++ include/dsp/msm-audio-event-notify.h | 24 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/dsp/msm-audio-event-notify.c b/dsp/msm-audio-event-notify.c index 6eb537d78c83..3f02ebb6a7b2 100644 --- a/dsp/msm-audio-event-notify.c +++ b/dsp/msm-audio-event-notify.c @@ -13,6 +13,7 @@ #include static ATOMIC_NOTIFIER_HEAD(msm_aud_evt_notifier_list); +static BLOCKING_NOTIFIER_HEAD(msm_aud_evt_blocking_notifier_list); /** * msm_aud_evt_register_client - register a client notifier @@ -43,3 +44,38 @@ int msm_aud_evt_notifier_call_chain(unsigned long val, void *v) return atomic_notifier_call_chain(&msm_aud_evt_notifier_list, val, v); } EXPORT_SYMBOL_GPL(msm_aud_evt_notifier_call_chain); + +/** + * msm_aud_evt_blocking_register_client - register a client notifier + * @nb: notifier block to callback on events + */ +int msm_aud_evt_blocking_register_client(struct notifier_block *nb) +{ + return blocking_notifier_chain_register( + &msm_aud_evt_blocking_notifier_list, nb); +} +EXPORT_SYMBOL(msm_aud_evt_blocking_register_client); + +/** + * msm_aud_evt_unregister_client - unregister a client notifier + * @nb: notifier block to callback on events + */ +int msm_aud_evt_blocking_unregister_client(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister( + &msm_aud_evt_blocking_notifier_list, nb); +} +EXPORT_SYMBOL(msm_aud_evt_blocking_unregister_client); + +/** + * msm_aud_evt_notifier_call_chain - notify clients of fb_events + * @val: event or enum maintained by caller + * @v: private data pointer + * + */ +int msm_aud_evt_blocking_notifier_call_chain(unsigned long val, void *v) +{ + return blocking_notifier_call_chain( + &msm_aud_evt_blocking_notifier_list, val, v); +} +EXPORT_SYMBOL_GPL(msm_aud_evt_blocking_notifier_call_chain); diff --git a/include/dsp/msm-audio-event-notify.h b/include/dsp/msm-audio-event-notify.h index 5b85ad7e26c5..fc47eff8abbf 100644 --- a/include/dsp/msm-audio-event-notify.h +++ b/include/dsp/msm-audio-event-notify.h @@ -20,6 +20,9 @@ int msm_aud_evt_register_client(struct notifier_block *nb); int msm_aud_evt_unregister_client(struct notifier_block *nb); int msm_aud_evt_notifier_call_chain(unsigned long val, void *v); +int msm_aud_evt_blocking_register_client(struct notifier_block *nb); +int msm_aud_evt_blocking_unregister_client(struct notifier_block *nb); +int msm_aud_evt_blocking_notifier_call_chain(unsigned long val, void *v); #else static inline int msm_aud_evt_register_client(struct notifier_block *nb) { @@ -35,10 +38,31 @@ static inline int msm_aud_evt_notifier_call_chain(unsigned long val, void *v) { return -ENOSYS; } + +static inline int msm_aud_evt_blocking_register_client( + struct notifier_block *nb) +{ + return -ENOSYS; +} + +static inline int msm_aud_evt_blocking_unregister_client( + struct notifier_block *nb) +{ + return -ENOSYS; +} + +static inline int msm_aud_evt_blocking_notifier_call_chain( + unsigned long val, void *v) +{ + return -ENOSYS; +} #endif enum { MSM_AUD_DC_EVENT = 1, + SWR_WAKE_IRQ_REGISTER, + SWR_WAKE_IRQ_DEREGISTER, + SWR_WAKE_IRQ_EVENT, }; #endif -- GitLab From 250075f808c15616f1590f461c7484671eddfcb2 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Fri, 31 Aug 2018 03:31:54 +0530 Subject: [PATCH 0503/1645] dsp: afe: add support for swr wakeup irq events Add support for soundwire wakeup irq registration and event notification from afe. Change-Id: I97abe0a8bb571b997a52f90e0a0f57a26c714251 Signed-off-by: Ramprasad Katkam --- dsp/q6afe.c | 63 ++++++++++++++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 63 ++++++++++++++++++++++++++++++++++++++ include/dsp/q6afe-v2.h | 3 ++ 3 files changed, 129 insertions(+) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index b69558f49978..9eb8599c3e49 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -94,6 +94,7 @@ struct afe_ctl { atomic_t state; atomic_t status; wait_queue_head_t wait[AFE_MAX_PORTS]; + wait_queue_head_t wait_wakeup; struct task_struct *task; void (*tx_cb)(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv); @@ -145,6 +146,7 @@ struct afe_ctl { u32 island_mode[AFE_MAX_PORTS]; struct vad_config vad_cfg[AFE_MAX_PORTS]; struct work_struct afe_dc_work; + struct notifier_block event_notifier; }; static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX]; @@ -367,6 +369,23 @@ static void afe_notify_dc_presence_work_fn(struct work_struct *work) __func__, event, ret); } +static int afe_aud_event_notify(struct notifier_block *self, + unsigned long action, void *data) +{ + switch (action) { + case SWR_WAKE_IRQ_REGISTER: + afe_send_cmd_wakeup_register(data, true); + break; + case SWR_WAKE_IRQ_DEREGISTER: + afe_send_cmd_wakeup_register(data, false); + break; + default: + pr_err("%s: invalid event type: %lu\n", __func__, action); + return -EINVAL; + } + + return 0; +} static const char *const afe_event_port_text[] = { "PORT=Primary", @@ -569,6 +588,8 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) return -EINVAL; } wake_up(&this_afe.wait[data->token]); + } else if (data->opcode == AFE_EVENT_MBHC_DETECTION_SW_WA) { + msm_aud_evt_notifier_call_chain(SWR_WAKE_IRQ_EVENT, NULL); } else if (data->payload_size) { uint32_t *payload; uint16_t port_id = 0; @@ -640,6 +661,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) atomic_set(&this_afe.state, payload[1]); wake_up(&this_afe.wait[data->token]); break; + case AFE_SVC_CMD_EVENT_CFG: + atomic_set(&this_afe.state, payload[1]); + wake_up(&this_afe.wait_wakeup); + break; default: pr_err("%s: Unknown cmd 0x%x\n", __func__, payload[0]); @@ -2863,6 +2888,40 @@ int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg } EXPORT_SYMBOL(afe_send_spdif_ch_status_cfg); +int afe_send_cmd_wakeup_register(void *handle, bool enable) +{ + struct afe_svc_cmd_evt_cfg_payload wakeup_irq; + int ret; + + pr_debug("%s: enter\n", __func__); + + wakeup_irq.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + wakeup_irq.hdr.pkt_size = sizeof(wakeup_irq); + wakeup_irq.hdr.src_port = 0; + wakeup_irq.hdr.dest_port = 0; + wakeup_irq.hdr.token = 0x0; + wakeup_irq.hdr.opcode = AFE_SVC_CMD_EVENT_CFG; + wakeup_irq.event_id = AFE_EVENT_ID_MBHC_DETECTION_SW_WA; + wakeup_irq.reg_flag = enable; + pr_debug("%s: cmd device start opcode[0x%x] register:%d\n", + __func__, wakeup_irq.hdr.opcode, wakeup_irq.reg_flag); + + ret = afe_apr_send_pkt(&wakeup_irq, &this_afe.wait_wakeup); + if (ret) { + pr_err("%s: AFE wakeup command register %d failed %d\n", + __func__, enable, ret); + } else if (this_afe.task != current) { + this_afe.task = current; + pr_debug("task_name = %s pid = %d\n", + this_afe.task->comm, this_afe.task->pid); + } + + return ret; +} +EXPORT_SYMBOL(afe_send_cmd_wakeup_register); + static int afe_send_cmd_port_start(u16 port_id) { struct afe_port_cmd_device_start start; @@ -8062,6 +8121,7 @@ int __init afe_init(void) this_afe.vad_cfg[i].pre_roll = 0; init_waitqueue_head(&this_afe.wait[i]); } + init_waitqueue_head(&this_afe.wait_wakeup); wakeup_source_init(&wl.ws, "spkr-prot"); ret = afe_init_cal_data(); if (ret) @@ -8086,6 +8146,9 @@ int __init afe_init(void) INIT_WORK(&this_afe.afe_sec_spdif_work, afe_notify_sec_spdif_fmt_update_work_fn); + this_afe.event_notifier.notifier_call = afe_aud_event_notify; + msm_aud_evt_blocking_register_client(&this_afe.event_notifier); + return 0; } diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 73304fb545ec..e4f0c3bf7943 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -4205,6 +4205,69 @@ union afe_port_config { struct afe_param_id_cdc_dma_cfg_t cdc_dma; } __packed; + +/* + * AFE event registration related APIs and corresponding payloads + */ +#define AFE_SVC_CMD_EVENT_CFG 0x000100FE + +#define AFE_CMD_APPS_WAKEUP_IRQ_REGISTER_MINOR_VERSION 0x1 + +/* Flag to indicate AFE to register APPS wakeup Interrupt */ +#define AFE_APPS_WAKEUP_IRQ_REGISTER_FLAG 1 + +/* Flag to indicate AFE to de-register APPS wakeup Interrupt */ +#define AFE_APPS_WAKEUP_IRQ_DEREGISTER_FLAG 0 + +/* Default interrupt trigger value. */ +#define DEFAULT_SETTINGS 0x00000001 + +/* Interrupt is triggered only if the input signal at the source is high. */ +#define LEVEL_HIGH_TRIGGER 0x00000002 + +/* Interrupt is triggered only if the input signal at the source is low. */ +#define LEVEL_LOW_TRIGGER 0x00000003 + +/* Interrupt is triggered only if the input signal at the source transitions + *from low to high. + */ +#define RISING_EDGE_TRIGGER 0x00000004 + +/* Interrupt is triggered only if the input signal at the source transitions + *from high to low. + */ +#define FALLING_EDGE_TRIGGER 0x00000005 + +/* Macro for invalid trigger type. This should not be used. */ +#define INVALID_TRIGGER 0x00000006 + +#define AFE_EVENT_ID_MBHC_DETECTION_SW_WA 0x1 + +/* @weakgroup weak_afe_svc_cmd_evt_cfg_payload + * + * This is payload of each event that is to be + * registered with AFE service. + */ +struct afe_svc_cmd_evt_cfg_payload { + struct apr_hdr hdr; + + uint32_t event_id; +/* Unique ID of the event. + * + * @values + * -# AFE_EVENT_ID_MBHC_DETECTION_SW_WA + */ + + uint32_t reg_flag; +/* Flag for registering or de-registering an event. + * @values + * - #AFE_SVC_REGISTER_EVENT_FLAG + * - #AFE_SVC_DEREGISTER_EVENT_FLAG + */ +} __packed; + +#define AFE_EVENT_MBHC_DETECTION_SW_WA 0x0001010F + #define AFE_PORT_CMD_DEVICE_START 0x000100E5 /* Payload of the #AFE_PORT_CMD_DEVICE_START.*/ diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index ef1603f685b7..cf004d036eca 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -442,4 +442,7 @@ int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats, u16 port); int afe_cal_init_hwdep(void *card); int afe_send_port_island_mode(u16 port_id); +int afe_send_cmd_wakeup_register(void *handle, bool enable); +void afe_register_wakeup_irq_callback( + void (*afe_cb_wakeup_irq)(void *handle)); #endif /* __Q6AFE_V2_H__ */ -- GitLab From 68765abe1116899df7dedc734ca2f5b2f599644a Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Thu, 30 Aug 2018 11:46:32 +0530 Subject: [PATCH 0504/1645] soc: swr-mstr: Add support to listen for DC detection Add support to listen for DC detection event. Shutdown WSA on receiving DC detection event. Porting the changes from old master driver to new driver. Change-Id: I4d323bb8074d447b2969dd01c7129e57160b6c04 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 33 +++++++++++++++++++++++++++++++++ soc/swr-mstr-ctrl.h | 2 ++ 2 files changed, 35 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index a9d755b89442..25f0353ba0a6 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "swrm_registers.h" #include "swr-mstr-ctrl.h" #include "swrm_port_config.h" @@ -1423,6 +1424,33 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) return ret; } +static int swrm_event_notify(struct notifier_block *self, + unsigned long action, void *data) +{ + struct swr_mstr_ctrl *swrm = container_of(self, struct swr_mstr_ctrl, + event_notifier); + if (!swrm || !swrm->pdev) { + pr_err("%s: swrm or pdev is NULL\n", __func__); + return -EINVAL; + } + if (action != MSM_AUD_DC_EVENT) { + dev_err(&swrm->pdev->dev, "%s: invalid event type: %lu\n", + __func__, action); + return -EINVAL; + } + + schedule_work(&(swrm->dc_presence_work)); + + return 0; +} + +static void swrm_notify_work_fn(struct work_struct *work) +{ + struct swr_mstr_ctrl *swrm = container_of(work, struct swr_mstr_ctrl, + dc_presence_work); + swrm_wcd_notify(swrm->pdev, SWR_DEVICE_DOWN, NULL); +} + static int swrm_probe(struct platform_device *pdev) { struct swr_mstr_ctrl *swrm; @@ -1671,6 +1699,10 @@ static int swrm_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); pm_runtime_mark_last_busy(&pdev->dev); + INIT_WORK(&swrm->dc_presence_work, swrm_notify_work_fn); + swrm->event_notifier.notifier_call = swrm_event_notify; + msm_aud_evt_register_client(&swrm->event_notifier); + return 0; err_mstr_fail: if (swrm->reg_irq) @@ -1700,6 +1732,7 @@ static int swrm_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); swr_unregister_master(&swrm->master); + msm_aud_evt_unregister_client(&swrm->event_notifier); mutex_destroy(&swrm->mlock); mutex_destroy(&swrm->reslock); mutex_destroy(&swrm->force_down_lock); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 59c7e76c94b3..9d8fd94b2028 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -139,6 +139,8 @@ struct swr_mstr_ctrl { u8 num_cfg_devs; struct mutex force_down_lock; int force_down_state; + struct notifier_block event_notifier; + struct work_struct dc_presence_work; u8 num_ports; struct swrm_port_type port_mapping[SWR_MSTR_PORT_LEN][SWR_MAX_CH_PER_PORT]; -- GitLab From f0128ef1690bdc4c5b578072f329727aae1b3c43 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 31 Aug 2018 15:15:09 +0530 Subject: [PATCH 0505/1645] soc: swr-mstr: Add wakeup irq support from afe using event notifier Register and handle swr wakeup irq from afe, using aud event notifier codec interrupts during clock stop mode. Change-Id: I76d250adcaa8af4a413f6274482beb5a3469601d Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 65 ++++++++++++++++++++++++++++++++++++++------- soc/swr-mstr-ctrl.h | 2 ++ 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 25f0353ba0a6..354d9047cb8b 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1296,6 +1296,25 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) return ret; } +static void swrm_wakeup_work(struct work_struct *work) +{ + struct swr_mstr_ctrl *swrm; + + swrm = container_of(work, struct swr_mstr_ctrl, + wakeup_work); + if (!swrm || !(swrm->dev)) { + pr_err("%s: swrm or dev is null\n", __func__); + return; + } + pm_runtime_get_sync(swrm->dev); + + swrm_cmd_fifo_wr_cmd(swrm, 0x4, 0xF, 0xF, + SWRS_SCP_INT_STATUS_MASK_1); + + pm_runtime_mark_last_busy(swrm->dev); + pm_runtime_put_autosuspend(swrm->dev); +} + static int swrm_get_device_status(struct swr_mstr_ctrl *swrm, u8 devnum) { u32 val; @@ -1425,29 +1444,41 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) } static int swrm_event_notify(struct notifier_block *self, - unsigned long action, void *data) + unsigned long action, void *data) { struct swr_mstr_ctrl *swrm = container_of(self, struct swr_mstr_ctrl, - event_notifier); - if (!swrm || !swrm->pdev) { - pr_err("%s: swrm or pdev is NULL\n", __func__); + event_notifier); + + if (!swrm || !(swrm->dev)) { + pr_err("%s: swrm or dev is NULL\n", __func__); return -EINVAL; } - if (action != MSM_AUD_DC_EVENT) { - dev_err(&swrm->pdev->dev, "%s: invalid event type: %lu\n", + switch (action) { + case MSM_AUD_DC_EVENT: + schedule_work(&(swrm->dc_presence_work)); + break; + case SWR_WAKE_IRQ_EVENT: + if (swrm->wakeup_req) + schedule_work(&swrm->wakeup_work); + break; + default: + dev_err(swrm->dev, "%s: invalid event type: %lu\n", __func__, action); return -EINVAL; } - schedule_work(&(swrm->dc_presence_work)); - return 0; } static void swrm_notify_work_fn(struct work_struct *work) { struct swr_mstr_ctrl *swrm = container_of(work, struct swr_mstr_ctrl, - dc_presence_work); + dc_presence_work); + + if (!swrm || !swrm->pdev) { + pr_err("%s: swrm or pdev is NULL\n", __func__); + return; + } swrm_wcd_notify(swrm->pdev, SWR_DEVICE_DOWN, NULL); } @@ -1466,6 +1497,7 @@ static int swrm_probe(struct platform_device *pdev) ret = -ENOMEM; goto err_memory_fail; } + swrm->pdev = pdev; swrm->dev = &pdev->dev; platform_set_drvdata(pdev, swrm); swr_set_ctrl_data(&swrm->master, swrm); @@ -1622,6 +1654,12 @@ static int swrm_probe(struct platform_device *pdev) goto err_pdata_fail; } } + + if (of_property_read_u32(swrm->dev->of_node, + "qcom,swr-wakeup-required", &swrm->wakeup_req)) { + swrm->wakeup_req = false; + } + if (swrm->reg_irq) { ret = swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, SWR_IRQ_REGISTER); @@ -1673,6 +1711,7 @@ static int swrm_probe(struct platform_device *pdev) swrm->version = swr_master_read(swrm, SWRM_COMP_HW_VERSION); mutex_unlock(&swrm->mlock); + INIT_WORK(&swrm->wakeup_work, swrm_wakeup_work); if (pdev->dev.of_node) of_register_swr_devices(&swrm->master); @@ -1768,6 +1807,11 @@ static int swrm_runtime_resume(struct device *dev) mutex_lock(&swrm->reslock); if ((swrm->state == SWR_MSTR_PAUSE) || (swrm->state == SWR_MSTR_DOWN)) { + if (swrm->clk_stop_mode0_supp && swrm->wakeup_req) { + msm_aud_evt_blocking_notifier_call_chain( + SWR_WAKE_IRQ_DEREGISTER, (void *)swrm); + } + if (swrm->state == SWR_MSTR_DOWN) { if (swrm_clk_request(swrm, true)) goto exit; @@ -1840,6 +1884,9 @@ static int swrm_runtime_suspend(struct device *dev) swrm_cmd_fifo_wr_cmd(swrm, 0x2, 0xF, 0xF, SWRS_SCP_CONTROL); usleep_range(100, 105); + if (swrm->wakeup_req) + msm_aud_evt_blocking_notifier_call_chain( + SWR_WAKE_IRQ_REGISTER, (void *)swrm); } swrm_clk_request(swrm, false); } diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 9d8fd94b2028..fd133928593c 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -146,6 +146,8 @@ struct swr_mstr_ctrl { port_mapping[SWR_MSTR_PORT_LEN][SWR_MAX_CH_PER_PORT]; int swr_irq; u32 clk_stop_mode0_supp; + struct work_struct wakeup_work; + u32 wakeup_req; }; #endif /* _SWR_WCD_CTRL_H */ -- GitLab From 5f713097e1d2b6d21a342f6bcce145800f816911 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 4 Sep 2018 11:40:19 +0530 Subject: [PATCH 0506/1645] asoc: wcd937x: set default power level as ULP for wcd937x headphones For headphone playback, update default power level to Ultra_Low_Power(ULP) on wcd9370. Change-Id: Ic5e76d8f8fca1806780a4dbc679166a68c31edf3 Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd937x/wcd937x.c | 1 - 1 file changed, 1 deletion(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 9ef004519647..f18fe745f566 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -565,7 +565,6 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x0C, 0x08); snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x20, 0x20); usleep_range(100, 110); break; -- GitLab From 302075bb10f8f3b95f1a0baba0c46c8d97bd2a8e Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 4 Sep 2018 14:57:50 +0530 Subject: [PATCH 0507/1645] ASoC: wcd937x: Add fix to enable button detection Add notifier call chain to enable button detection. Change-Id: Ibd432691e4b820b8b2e86ebc8e8c2015bb26d2b1 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/internal.h | 1 - asoc/codecs/wcd937x/wcd937x-mbhc.c | 4 +- asoc/codecs/wcd937x/wcd937x-mbhc.h | 1 - asoc/codecs/wcd937x/wcd937x.c | 61 +++++++++++++++++++----------- 4 files changed, 41 insertions(+), 26 deletions(-) diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index 81b1e5df2c58..f883e961d106 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -56,7 +56,6 @@ struct wcd937x_priv { s32 dmic_4_5_clk_cnt; /* mbhc module */ struct wcd937x_mbhc *mbhc; - struct blocking_notifier_head notifier; u32 hph_mode; diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index e54710707d24..c7be66d8aedb 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -972,7 +972,7 @@ int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc, wcd_mbhc_deinit(wcd_mbhc); ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids, - wcd_mbhc_registers, WCD937X_ZDET_SUPPORTED); + wcd_mbhc_registers, false); if (ret) { dev_err(codec->dev, "%s: mbhc initialization failed\n", __func__); @@ -1024,7 +1024,7 @@ int wcd937x_mbhc_init(struct wcd937x_mbhc **mbhc, struct snd_soc_codec *codec, ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids, wcd_mbhc_registers, - WCD937X_ZDET_SUPPORTED); + false); if (ret) { dev_err(codec->dev, "%s: mbhc initialization failed\n", __func__); diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.h b/asoc/codecs/wcd937x/wcd937x-mbhc.h index 648d81c9be71..554cb88781fc 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.h +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.h @@ -17,7 +17,6 @@ struct wcd937x_mbhc { struct wcd_mbhc wcd_mbhc; struct blocking_notifier_head notifier; struct fw_info *fw_data; - bool mbhc_started; }; #if IS_ENABLED(CONFIG_SND_SOC_WCD937X) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 9ef004519647..0b7004d67a92 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -547,8 +547,16 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, wcd937x->rx_swr_dev->dev_num, true); break; + case SND_SOC_DAPM_PRE_PMD: + blocking_notifier_call_chain(&wcd937x->mbhc->notifier, + WCD_EVENT_PRE_HPHR_PA_OFF, + &wcd937x->mbhc->wcd_mbhc); + break; case SND_SOC_DAPM_POST_PMD: usleep_range(7000, 7010); + blocking_notifier_call_chain(&wcd937x->mbhc->notifier, + WCD_EVENT_POST_HPHR_PA_OFF, + &wcd937x->mbhc->wcd_mbhc); snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x10, 0x00); break; }; @@ -579,8 +587,16 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, wcd937x->rx_swr_dev->dev_num, true); break; + case SND_SOC_DAPM_PRE_PMD: + blocking_notifier_call_chain(&wcd937x->mbhc->notifier, + WCD_EVENT_PRE_HPHL_PA_OFF, + &wcd937x->mbhc->wcd_mbhc); + break; case SND_SOC_DAPM_POST_PMD: usleep_range(7000, 7010); + blocking_notifier_call_chain(&wcd937x->mbhc->notifier, + WCD_EVENT_POST_HPHL_PA_OFF, + &wcd937x->mbhc->wcd_mbhc); snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x20, 0x00); break; }; @@ -1092,15 +1108,15 @@ int wcd937x_micbias_control(struct snd_soc_codec *codec, snd_soc_update_bits(codec, WCD937X_MICB2_TEST_CTL_2, 0x01, 0x01); snd_soc_update_bits(codec, WCD937X_MICB3_TEST_CTL_2, 0x01, 0x01); snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); - if (post_on_event) - blocking_notifier_call_chain(&wcd937x->notifier, - post_on_event, - &wcd937x->mbhc); + if (post_on_event && wcd937x->mbhc) + blocking_notifier_call_chain( + &wcd937x->mbhc->notifier, post_on_event, + &wcd937x->mbhc->wcd_mbhc); } - if (is_dapm && post_dapm_on) - blocking_notifier_call_chain(&wcd937x->notifier, - post_dapm_on, - &wcd937x->mbhc); + if (is_dapm && post_dapm_on && wcd937x->mbhc) + blocking_notifier_call_chain( + &wcd937x->mbhc->notifier, post_dapm_on, + &wcd937x->mbhc->wcd_mbhc); break; case MICB_DISABLE: if (wcd937x->micb_ref[micb_index] > 0) @@ -1110,20 +1126,21 @@ int wcd937x_micbias_control(struct snd_soc_codec *codec, snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); else if ((wcd937x->micb_ref[micb_index] == 0) && (wcd937x->pullup_ref[micb_index] == 0)) { - if (pre_off_event) - blocking_notifier_call_chain(&wcd937x->notifier, - pre_off_event, - &wcd937x->mbhc); + if (pre_off_event && wcd937x->mbhc) + blocking_notifier_call_chain( + &wcd937x->mbhc->notifier, pre_off_event, + &wcd937x->mbhc->wcd_mbhc); snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); - if (post_off_event) - blocking_notifier_call_chain(&wcd937x->notifier, - post_off_event, - &wcd937x->mbhc); + if (post_off_event && wcd937x->mbhc) + blocking_notifier_call_chain( + &wcd937x->mbhc->notifier, + post_off_event, + &wcd937x->mbhc->wcd_mbhc); } - if (is_dapm && post_dapm_off) - blocking_notifier_call_chain(&wcd937x->notifier, - post_dapm_off, - &wcd937x->mbhc); + if (is_dapm && post_dapm_off && wcd937x->mbhc) + blocking_notifier_call_chain( + &wcd937x->mbhc->notifier, post_dapm_off, + &wcd937x->mbhc->wcd_mbhc); break; }; @@ -1367,11 +1384,11 @@ static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = { SND_SOC_DAPM_PGA_E("HPHL PGA", WCD937X_ANA_HPH, 7, 0, NULL, 0, wcd937x_codec_enable_hphl_pa, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PGA_E("HPHR PGA", WCD937X_ANA_HPH, 6, 0, NULL, 0, wcd937x_codec_enable_hphr_pa, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_DAC_E("RDAC1", NULL, SND_SOC_NOPM, 0, 0, wcd937x_codec_hphl_dac_event, -- GitLab From 9dce5048342869b93d17b9fefc1641e2844f0c9f Mon Sep 17 00:00:00 2001 From: Aniket Kumar Lata Date: Thu, 16 Aug 2018 16:23:46 -0700 Subject: [PATCH 0508/1645] dsp: Do not send ABR parameters if bitrate is fixed ABR encoder config parameters should be sent to DSP only when ABR is enabled. Do not send these parameters for fixed bitrate. Change-Id: Icf7e4feef65d01c8ae3f6c6123d490cadef46c97 Signed-off-by: Aniket Kumar Lata --- dsp/q6afe.c | 4 +++- include/dsp/apr_audio-v2.h | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 9eb8599c3e49..353df6a904c4 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -3735,7 +3735,9 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } - if (format == ASM_MEDIA_FMT_LDAC || format == ASM_MEDIA_FMT_APTX_ADAPTIVE) { + if ((format == ASM_MEDIA_FMT_LDAC && + cfg->ldac_config.abr_config.is_abr_enabled) || + format == ASM_MEDIA_FMT_APTX_ADAPTIVE) { pr_debug("%s:sending AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP to DSP payload", __func__); param_hdr.param_id = AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index e4f0c3bf7943..134281936992 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -3522,6 +3522,10 @@ struct afe_abr_enc_cfg_t { * Information to set up IMC between decoder and encoder. */ struct afe_imc_dec_enc_info imc_info; + /* + * Flag to indicate whether ABR is enabled. + */ + bool is_abr_enabled; } __packed; #define AFE_PARAM_ID_APTX_SYNC_MODE 0x00013205 -- GitLab From 6905ecf0279ef601dfe8cf757b3c006332f7ee6f Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Tue, 13 Mar 2018 16:05:20 -0700 Subject: [PATCH 0509/1645] dsp: add support for mic break detection Add capability to receive notifications from voice service when there is a change in mic break status during a voice call. On receiving notification, send an uevent with mic status to userspace. CRs-Fixed: 2211324 Change-Id: Ie55bd1490fd8cead7261b70169ae36eba95e4011 Signed-off-by: Vignesh Kulothungan --- asoc/msm-pcm-voice-v2.c | 18 ++++ dsp/q6voice.c | 211 ++++++++++++++++++++++++++++++++++++++++ include/dsp/q6voice.h | 48 +++++++++ 3 files changed, 277 insertions(+) diff --git a/asoc/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c index 0a4aa0528d95..38da7e7d765a 100644 --- a/asoc/msm-pcm-voice-v2.c +++ b/asoc/msm-pcm-voice-v2.c @@ -519,6 +519,22 @@ static int msm_voice_rx_device_mute_put(struct snd_kcontrol *kcontrol, return ret; } +static int msm_voice_mbd_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = voc_get_mbd_enable(); + return 0; +} + +static int msm_voice_mbd_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + bool enable = ucontrol->value.integer.value[0]; + + voc_set_mbd_enable(enable); + + return 0; +} static const char * const tty_mode[] = {"OFF", "HCO", "VCO", "FULL"}; @@ -664,6 +680,8 @@ static struct snd_kcontrol_new msm_voice_controls[] = { }, SOC_SINGLE_MULTI_EXT("Voice Sidetone Enable", SND_SOC_NOPM, 0, 1, 0, 1, msm_voice_sidetone_get, msm_voice_sidetone_put), + SOC_SINGLE_BOOL_EXT("Voice Mic Break Enable", 0, msm_voice_mbd_get, + msm_voice_mbd_put), }; static const struct snd_pcm_ops msm_pcm_ops = { diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 32e85f952c9b..ce86564b151f 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -72,6 +72,9 @@ static int voice_send_mvm_unmap_memory_physical_cmd(struct voice_data *v, static int voice_send_mvm_cal_network_cmd(struct voice_data *v); static int voice_send_mvm_media_type_cmd(struct voice_data *v); static int voice_send_mvm_cvd_version_cmd(struct voice_data *v); +static int voice_send_mvm_event_class_cmd(struct voice_data *v, + uint32_t event_id, + uint32_t class_id); static int voice_send_cvs_data_exchange_mode_cmd(struct voice_data *v); static int voice_send_cvs_packet_exchange_config_cmd(struct voice_data *v); static int voice_set_packet_exchange_mode_and_config(uint32_t session_id, @@ -767,6 +770,70 @@ static int voice_send_mvm_cvd_version_cmd(struct voice_data *v) return ret; } +static int voice_send_mvm_event_class_cmd(struct voice_data *v, + uint32_t event_id, + uint32_t class_id) +{ + struct vss_inotify_cmd_event_class_t mvm_event; + int ret = 0; + void *apr_mvm = NULL; + u16 mvm_handle = 0; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + return -EINVAL; + } + + apr_mvm = common.apr_q6_mvm; + if (!apr_mvm) { + pr_err("%s: apr_mvm is NULL.\n", __func__); + return -EINVAL; + } + + memset(&mvm_event, 0, sizeof(mvm_event)); + mvm_handle = voice_get_mvm_handle(v); + mvm_event.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mvm_event.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mvm_event) - APR_HDR_SIZE); + mvm_event.hdr.src_port = + voice_get_idx_for_session(v->session_id); + mvm_event.hdr.dest_port = mvm_handle; + mvm_event.hdr.token = 0; + mvm_event.hdr.opcode = event_id; + mvm_event.class_id = class_id; + + v->mvm_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_event); + if (ret < 0) { + pr_err("%s: Error %d sending %x event\n", __func__, ret, + event_id); + goto fail; + } + + ret = wait_event_timeout(v->mvm_wait, + (v->mvm_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout %d\n", __func__, ret); + ret = -ETIMEDOUT; + goto fail; + } + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + v->async_err)); + ret = adsp_err_get_lnx_err_code( + v->async_err); + goto fail; + } + return 0; +fail: + return ret; +} + static int voice_send_dual_control_cmd(struct voice_data *v) { int ret = 0; @@ -4243,6 +4310,23 @@ static int voice_get_avcs_version_per_service(uint32_t service_id) return ret; } +static void voice_mic_break_work_fn(struct work_struct *work) +{ + int ret = 0; + char event[25] = ""; + struct voice_data *v = container_of(work, struct voice_data, + voice_mic_break_work); + + snprintf(event, sizeof(event), "MIC_BREAK_STATUS=%s", + v->mic_break_status ? "TRUE" : "FALSE"); + + mutex_lock(&common.common_lock); + ret = q6core_send_uevent(common.uevent_data, event); + if (ret) + pr_err("%s: Send UEvent %s failed :%d\n", __func__, event, ret); + mutex_unlock(&common.common_lock); +} + static int voice_setup_vocproc(struct voice_data *v) { struct module_instance_info mod_inst_info; @@ -4341,6 +4425,11 @@ static int voice_setup_vocproc(struct voice_data *v) if (v->hd_enable) voice_send_hd_cmd(v, v->hd_enable); + if (common.mic_break_enable) + voice_send_mvm_event_class_cmd(v, + VSS_INOTIFY_CMD_LISTEN_FOR_EVENT_CLASS, + VSS_ICOMMON_EVENT_CLASS_VOICE_ACTIVITY_UPDATE); + rtac_add_voice(voice_get_cvs_handle(v), voice_get_cvp_handle(v), v->dev_rx.port_id, v->dev_tx.port_id, @@ -5034,6 +5123,11 @@ static int voice_destroy_vocproc(struct voice_data *v) /* Unload topology modules */ voice_unload_topo_modules(); + if (common.mic_break_enable) + voice_send_mvm_event_class_cmd(v, + VSS_INOTIFY_CMD_CANCEL_EVENT_CLASS, + VSS_ICOMMON_EVENT_CLASS_VOICE_ACTIVITY_UPDATE); + /* destrop cvp session */ cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), @@ -6625,6 +6719,70 @@ uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir) } EXPORT_SYMBOL(voc_get_route_flag); +/** + * voc_get_mbd_enable - + * Retrieve mic break detection enable state + * + * Returns true if mic break detection is enabled or false if disabled + */ +bool voc_get_mbd_enable(void) +{ + bool enable = false; + + mutex_lock(&common.common_lock); + enable = common.mic_break_enable; + mutex_unlock(&common.common_lock); + + return enable; +} +EXPORT_SYMBOL(voc_get_mbd_enable); + +/** + * voc_set_mbd_enable - + * Set mic break detection enable state + * + * @enable: mic break detection state to set + * + * Returns 0 + */ +uint8_t voc_set_mbd_enable(bool enable) +{ + struct voice_data *v = NULL; + struct voice_session_itr itr; + bool check_and_send_event = false; + uint32_t event_id = VSS_INOTIFY_CMD_LISTEN_FOR_EVENT_CLASS; + uint32_t class_id = VSS_ICOMMON_EVENT_CLASS_VOICE_ACTIVITY_UPDATE; + + mutex_lock(&common.common_lock); + if (common.mic_break_enable != enable) + check_and_send_event = true; + common.mic_break_enable = enable; + mutex_unlock(&common.common_lock); + + if (!check_and_send_event) + return 0; + + if (!enable) + event_id = VSS_INOTIFY_CMD_CANCEL_EVENT_CLASS; + + memset(&itr, 0, sizeof(itr)); + + voice_itr_init(&itr, ALL_SESSION_VSID); + while (voice_itr_get_next_session(&itr, &v)) { + if (v != NULL) { + mutex_lock(&v->lock); + if (is_voc_state_active(v->voc_state)) { + voice_send_mvm_event_class_cmd(v, event_id, + class_id); + } + mutex_unlock(&v->lock); + } + } + + return 0; +} +EXPORT_SYMBOL(voc_set_mbd_enable); + /** * voc_end_voice_call - * command to end voice call @@ -7171,6 +7329,7 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) uint32_t *ptr = NULL; struct common_data *c = NULL; struct voice_data *v = NULL; + struct vss_evt_voice_activity *voice_act_update = NULL; int i = 0; struct vss_iversion_rsp_get_t *version_rsp = NULL; @@ -7276,6 +7435,8 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) case VSS_IMVM_CMD_STANDBY_VOICE: case VSS_IHDVOICE_CMD_ENABLE: case VSS_IHDVOICE_CMD_DISABLE: + case VSS_INOTIFY_CMD_LISTEN_FOR_EVENT_CLASS: + case VSS_INOTIFY_CMD_CANCEL_EVENT_CLASS: pr_debug("%s: cmd = 0x%x\n", __func__, ptr[0]); v->mvm_state = CMD_STATUS_SUCCESS; v->async_err = ptr[1]; @@ -7380,7 +7541,33 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) v->mvm_state = CMD_STATUS_SUCCESS; wake_up(&v->mvm_wait); } + } else if (data->opcode == VSS_ICOMMON_EVT_VOICE_ACTIVITY_UPDATE) { + if (data->payload_size == sizeof(struct vss_evt_voice_activity)) { + voice_act_update = + (struct vss_evt_voice_activity *) + data->payload; + + /* Drop notifications other than Mic Break */ + if ((voice_act_update->activity + != VSS_ICOMMON_VOICE_ACTIVITY_MIC_BREAK) + && (voice_act_update->activity + != VSS_ICOMMON_VOICE_ACITIVTY_MIC_UNBREAK)) + return 0; + + switch (voice_act_update->activity) { + case VSS_ICOMMON_VOICE_ACTIVITY_MIC_BREAK: + v->mic_break_status = true; + break; + case VSS_ICOMMON_VOICE_ACITIVTY_MIC_UNBREAK: + v->mic_break_status = false; + break; + } + + if (c->mic_break_enable) + schedule_work(&(v->voice_mic_break_work)); + } } + return 0; } @@ -9642,6 +9829,14 @@ static int voice_pack_and_set_cvs_ui_property(struct voice_data *v, return ret; } +static void voc_release_uevent_data(struct kobject *kobj) +{ + struct audio_uevent_data *data = container_of(kobj, + struct audio_uevent_data, + kobj); + kfree(data); +} + /** * is_voc_initialized: * @@ -9694,6 +9889,18 @@ int __init voice_init(void) mutex_init(&common.common_lock); + common.uevent_data = kzalloc(sizeof(*(common.uevent_data)), GFP_KERNEL); + if (!common.uevent_data) + return -ENOMEM; + + /* + * Set release function to cleanup memory related to kobject + * before initializing the kobject. + */ + common.uevent_data->ktype.release = voc_release_uevent_data; + q6core_init_uevent_data(common.uevent_data, "q6voice_uevent"); + common.mic_break_enable = false; + /* Initialize session id with vsid */ init_session_id(); @@ -9734,6 +9941,9 @@ int __init voice_init(void) common.voice[i].voc_state = VOC_INIT; + INIT_WORK(&common.voice[i].voice_mic_break_work, + voice_mic_break_work_fn); + init_waitqueue_head(&common.voice[i].mvm_wait); init_waitqueue_head(&common.voice[i].cvs_wait); init_waitqueue_head(&common.voice[i].cvp_wait); @@ -9754,6 +9964,7 @@ int __init voice_init(void) void voice_exit(void) { + q6core_destroy_uevent_data(common.uevent_data); voice_delete_cal_data(); free_cal_map_table(); } diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index d0ba99001d1d..ca4250872591 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #define MAX_VOC_PKT_SIZE 642 @@ -494,6 +495,19 @@ struct vss_icommon_cmd_set_param { #define VSS_IHDVOICE_CMD_ENABLE 0x000130A2 #define VSS_IHDVOICE_CMD_DISABLE 0x000130A3 +/* To listen for events from MVM module */ +#define VSS_INOTIFY_CMD_LISTEN_FOR_EVENT_CLASS 0x00012E56 +/* To cancel listening for events from MVM module */ +#define VSS_INOTIFY_CMD_CANCEL_EVENT_CLASS 0x00012E57 +/* To receive ongoing voice activity notification */ +#define VSS_ICOMMON_EVENT_CLASS_VOICE_ACTIVITY_UPDATE 0x000131EF +/* Voice activity notification from MVM */ +#define VSS_ICOMMON_EVT_VOICE_ACTIVITY_UPDATE 0x000131F0 +/* Mic path is broken. */ +#define VSS_ICOMMON_VOICE_ACTIVITY_MIC_BREAK 0x000131F3 +/* Mic path is restored. */ +#define VSS_ICOMMON_VOICE_ACITIVTY_MIC_UNBREAK 0x000131F4 + enum msm_audio_voc_rate { VOC_0_RATE, /* Blank frame */ VOC_8_RATE, /* 1/8 rate */ @@ -719,6 +733,33 @@ struct vss_imemory_cmd_unmap_t { uint32_t mem_handle; } __packed; +/* + * Payload structure for VSS_INOTIFY_CMD_LISTEN_FOR_EVENT_CLASS and + * VSS_INOTIFY_CMD_CANCEL_EVENT_CLASS commands. + */ +struct vss_inotify_cmd_event_class_t { + struct apr_hdr hdr; + /* Event class ID to listen for. */ + uint32_t class_id; +} __packed; + +/* Payload structure for the VSS_ICOMMOM_EVT_VOICE_ACTIVITY_UPDATE event. */ +struct vss_evt_voice_activity { + uint32_t activity; + /* + * Specifies the voice acitivity. + * @values + * #VSS_ICOMMON_VOICE_ACTIVITY_VPTX_MUTE + * #VSS_ICOMMON_VOICE_ACTIVITY_VPTX_UNMUTE + * #VSS_ICOMMON_VOICE_ACTIVITY_MIC_BREAK + * #VSS_ICOMMON_VOICE_ACITIVTY_MIC_UNBREAK + * #VSS_ICOMMON_VOICE_ACTIVITY_UI_STREAM_TX_MUTE + * #VSS_ICOMMON_VOICE_ACTIVITY_UI_STREAM_TX_UNMUTE + * #VSS_ICOMMON_VOICE_ACTIVITY_UI_VOCPROC_TX_MUTE + * #VSS_ICOMMON_VOICE_ACTIVITY_UI_VOCPROC_TX_UNMUTE + */ +} __packed; + /* TO CVS commands */ #define VSS_ISTREAM_CMD_CREATE_PASSIVE_CONTROL_SESSION 0x00011140 /**< Wait for APRV2_IBASIC_RSP_RESULT response. */ @@ -1854,6 +1895,9 @@ struct voice_data { struct incall_music_info music_info; struct voice_rec_route_state rec_route_state; + + bool mic_break_status; + struct work_struct voice_mic_break_work; }; #define MAX_VOC_SESSIONS 8 @@ -1907,6 +1951,8 @@ struct common_data { struct shared_mem_info source_tracking_sh_mem; struct vss_isourcetrack_activity_data_t sourceTrackingResponse; bool sidetone_enable; + bool mic_break_enable; + struct audio_uevent_data *uevent_data; }; struct voice_session_itr { @@ -1998,6 +2044,8 @@ int voc_set_device_mute(uint32_t session_id, uint32_t dir, uint32_t mute, int voc_get_rx_device_mute(uint32_t session_id); int voc_set_route_flag(uint32_t session_id, uint8_t path_dir, uint8_t set); uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir); +bool voc_get_mbd_enable(void); +uint8_t voc_set_mbd_enable(bool enable); int voc_enable_dtmf_rx_detection(uint32_t session_id, uint32_t enable); void voc_disable_dtmf_det_on_active_sessions(void); int voc_alloc_cal_shared_memory(void); -- GitLab From 169ac5878bdf1df2171c6339e7d9dc8889fa54d5 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Mon, 13 Aug 2018 16:55:42 -0700 Subject: [PATCH 0510/1645] asoc: return when memory allocation fails Return with ENOMEM error when memory allocation fails to avoid NULL pointer access failure. Add NULL check before accessing dai driver pointer. CRs-Fixed: 2296013 Change-Id: I1c513d6550587216d338957b07c4b72475709f44 Signed-off-by: Vignesh Kulothungan --- asoc/msm-dai-q6-v2.c | 70 ++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 19952c87b5ff..742457c1ef34 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -1212,6 +1212,29 @@ static int msm_dai_q6_add_island_mx_ctls(struct snd_card *card, return rc; } +/* + * For single CPU DAI registration, the dai id needs to be + * set explicitly in the dai probe as ASoC does not read + * the cpu->driver->id field rather it assigns the dai id + * from the device name that is in the form %s.%d. This dai + * id should be assigned to back-end AFE port id and used + * during dai prepare. For multiple dai registration, it + * is not required to call this function, however the dai-> + * driver->id field must be defined and set to corresponding + * AFE Port id. + */ +static inline void msm_dai_q6_set_dai_id(struct snd_soc_dai *dai) +{ + if (!dai->driver) { + dev_err(dai->dev, "DAI driver is not set\n"); + return; + } + if (!dai->driver->id) { + dev_dbg(dai->dev, "DAI driver id is not set\n"); + return; + } + dai->id = dai->driver->id; +} static int msm_dai_q6_aux_pcm_probe(struct snd_soc_dai *dai) { @@ -1226,11 +1249,8 @@ static int msm_dai_q6_aux_pcm_probe(struct snd_soc_dai *dai) pr_err("%s: Invalid params dai dev\n", __func__); return -EINVAL; } - if (!dai->driver->id) { - dev_warn(dai->dev, "DAI driver id is not set\n"); - return -EINVAL; - } - dai->id = dai->driver->id; + + msm_dai_q6_set_dai_id(dai); dai_data = dev_get_drvdata(dai->dev); if (dai_data->is_island_dai) @@ -1725,15 +1745,20 @@ static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai) pr_err("%s: dai not found!!\n", __func__); return -EINVAL; } + if (!dai->dev) { + pr_err("%s: Invalid params dai dev\n", __func__); + return -EINVAL; + } + dai_data = kzalloc(sizeof(struct msm_dai_q6_spdif_dai_data), GFP_KERNEL); - if (!dai_data) { - rc = -ENOMEM; - } else + if (!dai_data) + return -ENOMEM; + else dev_set_drvdata(dai->dev, dai_data); - dai->id = dai->driver->id; + msm_dai_q6_set_dai_id(dai); dai_data->port_id = dai->id; switch (dai->id) { @@ -2530,26 +2555,6 @@ static struct snd_soc_dai_ops msm_dai_q6_ops = { .set_channel_map = msm_dai_q6_set_channel_map, }; -/* - * For single CPU DAI registration, the dai id needs to be - * set explicitly in the dai probe as ASoC does not read - * the cpu->driver->id field rather it assigns the dai id - * from the device name that is in the form %s.%d. This dai - * id should be assigned to back-end AFE port id and used - * during dai prepare. For multiple dai registration, it - * is not required to call this function, however the dai-> - * driver->id field must be defined and set to corresponding - * AFE Port id. - */ -static inline void msm_dai_q6_set_dai_id(struct snd_soc_dai *dai) -{ - if (!dai->driver->id) { - dev_warn(dai->dev, "DAI driver id is not set\n"); - return; - } - dai->id = dai->driver->id; -} - static int msm_dai_q6_cal_info_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -3188,7 +3193,7 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) dai_data = kzalloc(sizeof(struct msm_dai_q6_dai_data), GFP_KERNEL); if (!dai_data) - rc = -ENOMEM; + return -ENOMEM; else dev_set_drvdata(dai->dev, dai_data); @@ -6978,8 +6983,7 @@ static int msm_dai_q6_tdm_set_clk( static int msm_dai_q6_dai_tdm_probe(struct snd_soc_dai *dai) { int rc = 0; - struct msm_dai_q6_tdm_dai_data *tdm_dai_data = - dev_get_drvdata(dai->dev); + struct msm_dai_q6_tdm_dai_data *tdm_dai_data = NULL; struct snd_kcontrol *data_format_kcontrol = NULL; struct snd_kcontrol *header_type_kcontrol = NULL; struct snd_kcontrol *header_kcontrol = NULL; @@ -6988,6 +6992,8 @@ static int msm_dai_q6_dai_tdm_probe(struct snd_soc_dai *dai) const struct snd_kcontrol_new *header_type_ctrl = NULL; const struct snd_kcontrol_new *header_ctrl = NULL; + tdm_dai_data = dev_get_drvdata(dai->dev); + msm_dai_q6_set_dai_id(dai); port_idx = msm_dai_q6_get_port_idx(dai->id); -- GitLab From 9bdadace520b4b793940b93d1145ee721de4b34c Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 10 Sep 2018 10:30:18 +0530 Subject: [PATCH 0511/1645] ASoC: wcd937x: Add alias for in2p clamp register Add alias for in2p clamp register to check in2p clamp state in insertion irq and ignore the interrupt if the clamp is already set. Change-Id: Ibd4ff2cef8690894a01072e74ce130f824656f5d Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x-mbhc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index d1a36ba72de5..0b721b23922e 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -79,6 +79,8 @@ static struct wcd_mbhc_register WCD937X_MBHC_NEW_CTL_2, 0x03, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT", WCD937X_ANA_MBHC_RESULT_3, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_IN2P_CLAMP_STATE", + WCD937X_ANA_MBHC_RESULT_3, 0x10, 4, 0), WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT", WCD937X_ANA_MBHC_RESULT_3, 0x20, 5, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT", -- GitLab From 3b0d43d89ec725178360bf5d37dc8773311ff23d Mon Sep 17 00:00:00 2001 From: Vaishnavi Kommaraju Date: Tue, 31 Jul 2018 18:02:56 +0530 Subject: [PATCH 0512/1645] ASoC: codecs: Fix slim_tx port configuration for wcd9335 Add check for valid dai_id in slim_tx_mixer_put(). Change-Id: Ic231c81c2cba02ad25fc07783169601dedd352c0 Signed-off-by: Vaishnavi Kommaraju --- asoc/codecs/wcd9335.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 8564ac1a00c3..3ec94fe7d988 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -2372,10 +2372,10 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, mutex_lock(&tasha_p->codec_mutex); - if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) { - if (dai_id != AIF1_CAP) { - dev_err(codec->dev, "%s: invalid AIF for I2C mode\n", - __func__); + if (tasha_p->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) { + if (dai_id >= ARRAY_SIZE(vport_slim_check_table)) { + dev_err(codec->dev, "%s: dai_id: %d, out of bounds\n", + __func__, dai_id); mutex_unlock(&tasha_p->codec_mutex); return -EINVAL; } -- GitLab From f6ecc2a139339c49fd7ced9cc3d3db47805e73c8 Mon Sep 17 00:00:00 2001 From: Tanya Dixit Date: Mon, 10 Sep 2018 16:20:33 +0530 Subject: [PATCH 0513/1645] rtac: Add mutex lock to ensure proper fops access Add mutex lock in rtac_open and rtac_release to avoid usage count discrepancies leading to multiple calls to unmap memory resulting in null pointer dereference. CRs-Fixed: 2271712 Change-Id: Ie6da28837c352030b8d7e377d68a70cf04e7072a Signed-off-by: Tanya Dixit --- dsp/rtac.c | 42 +++++++++++++----------------------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/dsp/rtac.c b/dsp/rtac.c index 7102ae2927c6..c6bca9874270 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -54,6 +54,7 @@ struct rtac_cal_block_data rtac_cal[MAX_RTAC_BLOCKS] = { struct rtac_common_data { atomic_t usage_count; atomic_t apr_err_code; + struct mutex rtac_fops_mutex; }; static struct rtac_common_data rtac_common; @@ -122,10 +123,6 @@ struct mutex rtac_asm_apr_mutex; struct mutex rtac_voice_mutex; struct mutex rtac_voice_apr_mutex; struct mutex rtac_afe_apr_mutex; -struct mutex rtac_asm_cal_mutex; -struct mutex rtac_adm_cal_mutex; -struct mutex rtac_afe_cal_mutex; -struct mutex rtac_voice_cal_mutex; int rtac_clear_mapping(uint32_t cal_type) { @@ -322,7 +319,9 @@ static int rtac_open(struct inode *inode, struct file *f) pr_debug("%s\n", __func__); + mutex_lock(&rtac_common.rtac_fops_mutex); atomic_inc(&rtac_common.usage_count); + mutex_unlock(&rtac_common.rtac_fops_mutex); return result; } @@ -334,12 +333,15 @@ static int rtac_release(struct inode *inode, struct file *f) pr_debug("%s\n", __func__); + mutex_lock(&rtac_common.rtac_fops_mutex); atomic_dec(&rtac_common.usage_count); pr_debug("%s: ref count %d!\n", __func__, atomic_read(&rtac_common.usage_count)); - if (atomic_read(&rtac_common.usage_count) > 0) + if (atomic_read(&rtac_common.usage_count) > 0) { + mutex_unlock(&rtac_common.rtac_fops_mutex); goto done; + } for (i = 0; i < MAX_RTAC_BLOCKS; i++) { result2 = rtac_unmap_cal_buffer(i); @@ -356,6 +358,7 @@ static int rtac_release(struct inode *inode, struct file *f) result = result2; } } + mutex_unlock(&rtac_common.rtac_fops_mutex); done: return result; } @@ -1807,84 +1810,64 @@ static long rtac_ioctl_shared(struct file *f, } case AUDIO_GET_RTAC_ADM_CAL: - mutex_lock(&rtac_adm_cal_mutex); opcode = q6common_is_instance_id_supported() ? ADM_CMD_GET_PP_PARAMS_V6 : ADM_CMD_GET_PP_PARAMS_V5; result = send_adm_apr((void *) arg, opcode); - mutex_unlock(&rtac_adm_cal_mutex); break; case AUDIO_SET_RTAC_ADM_CAL: - mutex_lock(&rtac_adm_cal_mutex); opcode = q6common_is_instance_id_supported() ? ADM_CMD_SET_PP_PARAMS_V6 : ADM_CMD_SET_PP_PARAMS_V5; result = send_adm_apr((void *) arg, opcode); - mutex_unlock(&rtac_adm_cal_mutex); break; case AUDIO_GET_RTAC_ASM_CAL: - mutex_lock(&rtac_asm_cal_mutex); opcode = q6common_is_instance_id_supported() ? ASM_STREAM_CMD_GET_PP_PARAMS_V3 : ASM_STREAM_CMD_GET_PP_PARAMS_V2; result = send_rtac_asm_apr((void *) arg, opcode); - mutex_unlock(&rtac_asm_cal_mutex); break; case AUDIO_SET_RTAC_ASM_CAL: - mutex_lock(&rtac_asm_cal_mutex); opcode = q6common_is_instance_id_supported() ? ASM_STREAM_CMD_SET_PP_PARAMS_V3 : ASM_STREAM_CMD_SET_PP_PARAMS_V2; result = send_rtac_asm_apr((void *) arg, opcode); - mutex_unlock(&rtac_asm_cal_mutex); break; case AUDIO_GET_RTAC_CVS_CAL: - mutex_lock(&rtac_voice_cal_mutex); opcode = q6common_is_instance_id_supported() ? VSS_ICOMMON_CMD_GET_PARAM_V3 : VSS_ICOMMON_CMD_GET_PARAM_V2; result = send_voice_apr(RTAC_CVS, (void *) arg, opcode); - mutex_unlock(&rtac_voice_cal_mutex); break; case AUDIO_SET_RTAC_CVS_CAL: - mutex_lock(&rtac_voice_cal_mutex); opcode = q6common_is_instance_id_supported() ? VSS_ICOMMON_CMD_SET_PARAM_V3 : VSS_ICOMMON_CMD_SET_PARAM_V2; result = send_voice_apr(RTAC_CVS, (void *) arg, opcode); - mutex_unlock(&rtac_voice_cal_mutex); break; case AUDIO_GET_RTAC_CVP_CAL: - mutex_lock(&rtac_voice_cal_mutex); opcode = q6common_is_instance_id_supported() ? VSS_ICOMMON_CMD_GET_PARAM_V3 : VSS_ICOMMON_CMD_GET_PARAM_V2; result = send_voice_apr(RTAC_CVP, (void *) arg, opcode); - mutex_unlock(&rtac_voice_cal_mutex); break; case AUDIO_SET_RTAC_CVP_CAL: - mutex_lock(&rtac_voice_cal_mutex); opcode = q6common_is_instance_id_supported() ? VSS_ICOMMON_CMD_SET_PARAM_V3 : VSS_ICOMMON_CMD_SET_PARAM_V2; result = send_voice_apr(RTAC_CVP, (void *) arg, opcode); - mutex_unlock(&rtac_voice_cal_mutex); break; case AUDIO_GET_RTAC_AFE_CAL: - mutex_lock(&rtac_afe_cal_mutex); opcode = q6common_is_instance_id_supported() ? AFE_PORT_CMD_GET_PARAM_V3 : AFE_PORT_CMD_GET_PARAM_V2; result = send_rtac_afe_apr((void __user *) arg, opcode); - mutex_unlock(&rtac_afe_cal_mutex); break; case AUDIO_SET_RTAC_AFE_CAL: - mutex_lock(&rtac_afe_cal_mutex); opcode = q6common_is_instance_id_supported() ? AFE_PORT_CMD_SET_PARAM_V3 : AFE_PORT_CMD_SET_PARAM_V2; result = send_rtac_afe_apr((void __user *) arg, opcode); - mutex_unlock(&rtac_afe_cal_mutex); break; default: pr_err("%s: Invalid IOCTL, command = %d!\n", @@ -1900,6 +1883,7 @@ static long rtac_ioctl(struct file *f, { int result = 0; + mutex_lock(&rtac_common.rtac_fops_mutex); if (!arg) { pr_err("%s: No data sent to driver!\n", __func__); result = -EFAULT; @@ -1907,6 +1891,7 @@ static long rtac_ioctl(struct file *f, result = rtac_ioctl_shared(f, cmd, (void __user *)arg); } + mutex_unlock(&rtac_common.rtac_fops_mutex); return result; } @@ -1929,6 +1914,7 @@ static long rtac_compat_ioctl(struct file *f, { int result = 0; + mutex_lock(&rtac_common.rtac_fops_mutex); if (!arg) { pr_err("%s: No data sent to driver!\n", __func__); result = -EINVAL; @@ -1981,6 +1967,7 @@ static long rtac_compat_ioctl(struct file *f, break; } done: + mutex_unlock(&rtac_common.rtac_fops_mutex); return result; } #else @@ -2008,6 +1995,7 @@ int __init rtac_init(void) /* Driver */ atomic_set(&rtac_common.usage_count, 0); atomic_set(&rtac_common.apr_err_code, 0); + mutex_init(&rtac_common.rtac_fops_mutex); /* ADM */ memset(&rtac_adm_data, 0, sizeof(rtac_adm_data)); @@ -2016,7 +2004,6 @@ int __init rtac_init(void) init_waitqueue_head(&rtac_adm_apr_data.cmd_wait); mutex_init(&rtac_adm_mutex); mutex_init(&rtac_adm_apr_mutex); - mutex_init(&rtac_adm_cal_mutex); rtac_adm_buffer = kzalloc( rtac_cal[ADM_RTAC_CAL].map_data.map_size, GFP_KERNEL); @@ -2030,7 +2017,6 @@ int __init rtac_init(void) init_waitqueue_head(&rtac_asm_apr_data[i].cmd_wait); } mutex_init(&rtac_asm_apr_mutex); - mutex_init(&rtac_asm_cal_mutex); rtac_asm_buffer = kzalloc( rtac_cal[ASM_RTAC_CAL].map_data.map_size, GFP_KERNEL); @@ -2044,7 +2030,6 @@ int __init rtac_init(void) atomic_set(&rtac_afe_apr_data.cmd_state, 0); init_waitqueue_head(&rtac_afe_apr_data.cmd_wait); mutex_init(&rtac_afe_apr_mutex); - mutex_init(&rtac_afe_cal_mutex); rtac_afe_buffer = kzalloc( rtac_cal[AFE_RTAC_CAL].map_data.map_size, GFP_KERNEL); @@ -2063,7 +2048,6 @@ int __init rtac_init(void) } mutex_init(&rtac_voice_mutex); mutex_init(&rtac_voice_apr_mutex); - mutex_init(&rtac_voice_cal_mutex); rtac_voice_buffer = kzalloc( rtac_cal[VOICE_RTAC_CAL].map_data.map_size, GFP_KERNEL); -- GitLab From b0f27cd9f094f11c23fc543abad0e8be4c8c9e8a Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 6 Sep 2018 12:17:11 +0530 Subject: [PATCH 0514/1645] soc: swr-mstr: add changes to support native playback For MCLK frequency switching to 11.2896 for native playback support, frameshape also needs to be changed accordingly. Add changes to support frameshape switch based on mclk frequency for given master. Change-Id: I0c4dd69b743f83b45eeed73f27ad10e878b9244b Signed-off-by: Laxminath Kasam --- include/soc/swr-wcd.h | 4 ++++ soc/swr-mstr-ctrl.c | 21 ++++++++++++++++++++- soc/swr-mstr-ctrl.h | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/include/soc/swr-wcd.h b/include/soc/swr-wcd.h index 360815043709..75d0e6512267 100644 --- a/include/soc/swr-wcd.h +++ b/include/soc/swr-wcd.h @@ -23,6 +23,7 @@ enum { SWR_DEVICE_UP, SWR_SUBSYS_RESTART, SWR_SET_NUM_RX_CH, + SWR_CLK_FREQ, }; struct swr_mstr_port { @@ -30,6 +31,9 @@ struct swr_mstr_port { u8 *port; }; +#define MCLK_FREQ 9600000 +#define MCLK_FREQ_NATIVE 11289600 + #if (IS_ENABLED(CONFIG_SOUNDWIRE_WCD_CTRL) || \ IS_ENABLED(CONFIG_SOUNDWIRE_MSTR_CTRL)) extern int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data); diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 26cc1f45d9f5..d3fb08769850 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -956,7 +956,15 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) n_col = SWR_MAX_COL; } /* Use default 50 * x, frame shape. Change based on mclk */ - n_row = SWR_ROW_50; + if (swrm->mclk_freq == MCLK_FREQ_NATIVE) { + dev_dbg(swrm->dev, "setting 64 x %d frameshape\n", + n_col ? 16 : 2); + n_row = SWR_ROW_64; + } else { + dev_dbg(swrm->dev, "setting 50 x %d frameshape\n", + n_col ? 16 : 2); + n_row = SWR_ROW_50; + } value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank)); value &= (~mask); value |= ((n_row << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | @@ -1630,6 +1638,7 @@ static int swrm_probe(struct platform_device *pdev) swrm->slave_status = 0; swrm->num_rx_chs = 0; swrm->clk_ref_count = 0; + swrm->mclk_freq = MCLK_FREQ; swrm->state = SWR_MSTR_RESUME; init_completion(&swrm->reset); init_completion(&swrm->broadcast); @@ -1940,6 +1949,16 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) mstr = &swrm->master; switch (id) { + case SWR_CLK_FREQ: + if (!data) { + dev_err(swrm->dev, "%s: data is NULL\n", __func__); + ret = -EINVAL; + } else { + mutex_lock(&swrm->mlock); + swrm->mclk_freq = *(int *)data; + mutex_unlock(&swrm->mlock); + } + break; case SWR_DEVICE_DOWN: dev_dbg(swrm->dev, "%s: swr master down called\n", __func__); mutex_lock(&swrm->mlock); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index fd133928593c..b3dfd7d3a3d1 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -129,6 +129,7 @@ struct swr_mstr_ctrl { void *data), void *swr_handle, int type); int irq; int version; + int mclk_freq; u32 num_dev; int slave_status; struct swrm_mports mport_cfg[SWR_MAX_MSTR_PORT_NUM]; -- GitLab From f27e351051d90136da48dbc9bbce786bf76476ec Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Wed, 23 May 2018 17:14:31 +0800 Subject: [PATCH 0515/1645] ASoC: msm: remove unnecessary error log in audio kernel PP event queue is not used by capture path. Initialize PP event queue for playback path only to remove unnecessary log. Change log level from error to debug when no matching afe cal block is found. Change-Id: Ibc323449f2fdc74cccd350ae30ac76d937898ffa Signed-off-by: Xiaojun Sang --- asoc/msm-pcm-q6-v2.c | 5 ++++- dsp/q6afe.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 8ae85b743686..f40769b4b8d9 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -704,7 +704,10 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) prtd->set_channel_map = false; prtd->reset_event = false; runtime->private_data = prtd; - msm_adsp_init_mixer_ctl_pp_event_queue(soc_prtd); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + msm_adsp_init_mixer_ctl_pp_event_queue(soc_prtd); + /* Vote to update the Rx thread priority to RT Thread for playback */ if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) && (pdata->perf_mode == LOW_LATENCY_PCM_MODE)) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 353df6a904c4..f5e7267f7c9e 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2292,7 +2292,7 @@ static struct cal_block_data *afe_find_cal(int cal_index, int port_id) goto exit; } } - pr_err("%s: no matching cal_block found\n", __func__); + pr_debug("%s: no matching cal_block found\n", __func__); cal_block = NULL; exit: -- GitLab From ac396d57341557943e4cf8a6dee4303d1e1147f1 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 6 Sep 2018 12:53:26 +0530 Subject: [PATCH 0516/1645] asoc: bolero: add support for native playback On bolero rx macro, add support to switch mclk frequency based on native usecase active. Change-Id: I2f915475dcfdadf1027507b7ed83a4a852ece1c7 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 76 +++++++++++++++++------------------ 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index fbacdc028375..006f863bd0aa 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -44,6 +44,11 @@ SNDRV_PCM_FMTBIT_S24_LE |\ SNDRV_PCM_FMTBIT_S24_3LE) +#define SAMPLING_RATE_44P1KHZ 44100 +#define SAMPLING_RATE_88P2KHZ 88200 +#define SAMPLING_RATE_176P4KHZ 176400 +#define SAMPLING_RATE_352P8KHZ 352800 + #define RX_MACRO_MAX_OFFSET 0x1000 #define RX_MACRO_MAX_DMA_CH_PER_PORT 2 @@ -312,10 +317,6 @@ static const char *const rx_macro_mux_text[] = { "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB" }; -static const char *const rx_macro_native_text[] = {"OFF", "ON"}; -static const struct soc_enum rx_macro_native_enum = - SOC_ENUM_SINGLE_EXT(2, rx_macro_native_text); - static const char *const rx_macro_ear_mode_text[] = {"OFF", "ON"}; static const struct soc_enum rx_macro_ear_mode_enum = SOC_ENUM_SINGLE_EXT(2, rx_macro_ear_mode_text); @@ -642,16 +643,40 @@ static int rx_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, return 0; } +static bool rx_macro_is_fractional_sample_rate(u32 sample_rate) +{ + switch (sample_rate) { + case SAMPLING_RATE_44P1KHZ: + case SAMPLING_RATE_88P2KHZ: + case SAMPLING_RATE_176P4KHZ: + case SAMPLING_RATE_352P8KHZ: + return true; + default: + return false; + } + return false; +} + static int rx_macro_set_interpolator_rate(struct snd_soc_dai *dai, u32 sample_rate) { struct snd_soc_codec *codec = dai->codec; int rate_val = 0; int i = 0, ret = 0; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) { if (sample_rate == sr_val_tbl[i].sample_rate) { rate_val = sr_val_tbl[i].rate_val; + if (rx_macro_is_fractional_sample_rate(sample_rate)) + rx_priv->is_native_on = true; + else + rx_priv->is_native_on = false; break; } } @@ -748,7 +773,7 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, dev_dbg(rx_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", __func__, mclk_enable, dapm, rx_priv->rx_mclk_users); - if(rx_priv->is_native_on) + if (rx_priv->is_native_on) mclk_mux = MCLK_MUX1; mutex_lock(&rx_priv->mclk_lock); if (mclk_enable) { @@ -809,6 +834,7 @@ static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w, int ret = 0; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; + int mclk_freq = MCLK_FREQ; if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) return -EINVAL; @@ -820,13 +846,18 @@ static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w, if (rx_priv->swr_clk_users > 0) { if ((rx_priv->mclk_mux == MCLK_MUX0 && rx_priv->is_native_on) || - (rx_priv->mclk_mux == MCLK_MUX1 && + (rx_priv->mclk_mux == MCLK_MUX1 && !rx_priv->is_native_on)) { swrm_wcd_notify( rx_priv->swr_ctrl_data[0].rx_swr_pdev, SWR_DEVICE_DOWN, NULL); } } + if (rx_priv->is_native_on) + mclk_freq = MCLK_FREQ_NATIVE; + swrm_wcd_notify( + rx_priv->swr_ctrl_data[0].rx_swr_pdev, + SWR_CLK_FREQ, &mclk_freq); ret = rx_macro_mclk_enable(rx_priv, 1, true); break; case SND_SOC_DAPM_POST_PMD: @@ -1331,36 +1362,6 @@ static int rx_macro_mux_put(struct snd_kcontrol *kcontrol, return -EINVAL; } -static int rx_macro_get_native(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct device *rx_dev = NULL; - struct rx_macro_priv *rx_priv = NULL; - - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) - return -EINVAL; - - ucontrol->value.integer.value[0] = - (rx_priv->is_native_on == true ? 1 : 0); - return 0; -} - -static int rx_macro_put_native(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct device *rx_dev = NULL; - struct rx_macro_priv *rx_priv = NULL; - - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) - return -EINVAL; - - rx_priv->is_native_on = - (!ucontrol->value.integer.value[0] ? false : true); - return 0; -} - static int rx_macro_get_ear_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1877,9 +1878,6 @@ static const struct snd_kcontrol_new rx_macro_snd_controls[] = { SOC_SINGLE_EXT("RX_COMP2 Switch", SND_SOC_NOPM, RX_MACRO_COMP2, 1, 0, rx_macro_get_compander, rx_macro_set_compander), - SOC_ENUM_EXT("RX_Native", rx_macro_native_enum, rx_macro_get_native, - rx_macro_put_native), - SOC_ENUM_EXT("RX_EAR Mode", rx_macro_ear_mode_enum, rx_macro_get_ear_mode, rx_macro_put_ear_mode), -- GitLab From e5159cdc9021a98f331405f3b34016a4be8bd390 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 6 Sep 2018 17:45:31 -0700 Subject: [PATCH 0517/1645] dsp: asm: split check condition for NULL and stale Split the muli-check condition into two separate check conditions. Suppress the logs for stale condition to debug. CRs-Fixed: 2307741 Change-Id: I984a2ea7928de052e993e77db807df83109ab423 Signed-off-by: Vignesh Kulothungan --- dsp/q6asm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index b7d92ad85e29..fd647e6c62bc 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -10136,9 +10136,15 @@ int q6asm_send_cal(struct audio_client *ac) memset(&mem_hdr, 0, sizeof(mem_hdr)); mutex_lock(&cal_data[ASM_AUDSTRM_CAL]->lock); cal_block = cal_utils_get_only_cal_block(cal_data[ASM_AUDSTRM_CAL]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { + if (cal_block == NULL) { + pr_err("%s: cal_block is NULL\n", + __func__); + goto unlock; + } + + if (cal_utils_is_cal_stale(cal_block)) { rc = 0; /* not error case */ - pr_err("%s: cal_block is NULL or stale\n", + pr_debug("%s: cal_block is stale\n", __func__); goto unlock; } -- GitLab From 9c09cbdbb532b2e6c7b466178a82ac8b0d18c718 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Sat, 30 Jun 2018 19:57:10 +0530 Subject: [PATCH 0518/1645] dsp: q6lsm: Avoid null pointer access in SSR Synchronize both contexts of SSR and SVA close to avoid access of client handle after free. Check whether the client is valid or not when retrieved from private data in q6lsm_callback along with NULL check to avoid invalidated pointer access. Change-Id: I51c13cd79fd947c624bf0cade4c93a3fdf07353e Signed-off-by: Aditya Bavanari --- dsp/q6lsm.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index f34187d1fdfc..46e20132f180 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -75,6 +75,8 @@ struct lsm_common { }; static struct lsm_common lsm_common; +static DEFINE_MUTEX(session_lock); + /* * mmap_handle_p can point either client->sound_model.mem_map_handle or * lsm_common.mmap_handle_for_cal. @@ -95,6 +97,24 @@ static int q6lsm_memory_map_regions(struct lsm_client *client, static int q6lsm_memory_unmap_regions(struct lsm_client *client, uint32_t handle); +static int q6lsm_get_session_id_from_lsm_client(struct lsm_client *client) +{ + int n; + + for (n = LSM_MIN_SESSION_ID; n <= LSM_MAX_SESSION_ID; n++) { + if (lsm_session[n] == client) + return n; + } + pr_err("%s: cannot find matching lsm client. client = %pa\n", + __func__, client); + return LSM_INVALID_SESSION_ID; +} + +static bool q6lsm_is_valid_lsm_client(struct lsm_client *client) +{ + return q6lsm_get_session_id_from_lsm_client(client) ? 1 : 0; +} + static int q6lsm_callback(struct apr_client_data *data, void *priv) { struct lsm_client *client = (struct lsm_client *)priv; @@ -113,6 +133,13 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) __func__, data->opcode, data->reset_event, data->reset_proc); + mutex_lock(&session_lock); + if (!client || !q6lsm_is_valid_lsm_client(client)) { + pr_err("%s: client already freed/invalid, return\n", + __func__); + mutex_unlock(&session_lock); + return 0; + } apr_reset(client->apr); client->apr = NULL; atomic_set(&client->cmd_state, CMD_STATE_CLEARED); @@ -122,6 +149,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) mutex_lock(&lsm_common.cal_data[LSM_CUSTOM_TOP_IDX]->lock); lsm_common.set_custom_topology = 1; mutex_unlock(&lsm_common.cal_data[LSM_CUSTOM_TOP_IDX]->lock); + mutex_unlock(&session_lock); return 0; } @@ -334,6 +362,7 @@ void q6lsm_client_free(struct lsm_client *client) pr_err("%s: Invalid Session %d\n", __func__, client->session); return; } + mutex_lock(&session_lock); apr_deregister(client->apr); client->mmap_apr = NULL; q6lsm_session_free(client); @@ -341,6 +370,7 @@ void q6lsm_client_free(struct lsm_client *client) mutex_destroy(&client->cmd_lock); kfree(client); client = NULL; + mutex_unlock(&session_lock); } EXPORT_SYMBOL(q6lsm_client_free); -- GitLab From 8530fb9b5ddb19e7cec18565ed8dea40c4e284d5 Mon Sep 17 00:00:00 2001 From: Tanya Dixit Date: Fri, 14 Sep 2018 16:01:25 +0530 Subject: [PATCH 0519/1645] asoc: codecs: Add proper null checks and initialize variables Add proper null checks and initialize variables in rx-macro, tx-macro, va-macro and wcd937x drivers. Change-Id: I90899c84d3391305b9a24d4b043adc08b7c0332a Signed-off-by: Tanya Dixit --- asoc/codecs/bolero/rx-macro.c | 15 +++++++++++++++ asoc/codecs/bolero/tx-macro.c | 10 ++++++++++ asoc/codecs/bolero/va-macro.c | 5 +++++ asoc/codecs/wcd937x/wcd937x.c | 8 ++++---- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 006f863bd0aa..1a618d0eac96 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -770,6 +770,11 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL); int ret = 0, mclk_mux = MCLK_MUX0; + if (regmap == NULL) { + dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__); + return -EINVAL; + } + dev_dbg(rx_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", __func__, mclk_enable, dapm, rx_priv->rx_mclk_users); @@ -1570,6 +1575,11 @@ static void rx_macro_restore_iir_coeff(struct rx_macro_priv *rx_priv, int iir_id u16 reg_add = 0, coeff_idx = 0, idx = 0; struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL); + if (regmap == NULL) { + dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__); + return; + } + regmap_write(regmap, (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx), (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); @@ -2383,6 +2393,11 @@ static int rx_swrm_clock(void *handle, bool enable) struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL); int ret = 0; + if (regmap == NULL) { + dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__); + return -EINVAL; + } + mutex_lock(&rx_priv->swr_clk_lock); dev_dbg(rx_priv->dev, "%s: swrm clock %s\n", diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 4f9736efeef4..76d424be6bc1 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -183,6 +183,11 @@ static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv, struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL); int ret = 0; + if (regmap == NULL) { + dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__); + return -EINVAL; + } + dev_dbg(tx_priv->dev, "%s: mclk_enable = %u,clk_users= %d\n", __func__, mclk_enable, tx_priv->tx_mclk_users); @@ -1319,6 +1324,11 @@ static int tx_macro_swrm_clock(void *handle, bool enable) struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL); int ret = 0; + if (regmap == NULL) { + dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__); + return -EINVAL; + } + mutex_lock(&tx_priv->swr_clk_lock); dev_dbg(tx_priv->dev, "%s: swrm clock %s\n", diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 03bdfa19a7ef..eb069fa0c324 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -143,6 +143,11 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, struct regmap *regmap = dev_get_regmap(va_priv->dev->parent, NULL); int ret = 0; + if (regmap == NULL) { + dev_err(va_priv->dev, "%s: regmap is NULL\n", __func__); + return -EINVAL; + } + dev_dbg(va_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", __func__, mclk_enable, dapm, va_priv->va_mclk_users); diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 5e34ad263a66..f4c45bb14e6b 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -142,8 +142,8 @@ static int wcd937x_set_port_params(struct snd_soc_codec *codec, u8 slv_prt_type, u8 *port_type, u8 path) { int i, j; - u8 num_ports; - struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT]; + u8 num_ports = 0; + struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT] = NULL; struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); switch (path) { @@ -186,8 +186,8 @@ static int wcd937x_parse_port_mapping(struct device *dev, u32 slave_port_type, master_port_type; u32 i, ch_iter = 0; int ret = 0; - u8 *num_ports; - struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT]; + u8 *num_ports = NULL; + struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT] = NULL; struct wcd937x_priv *wcd937x = dev_get_drvdata(dev); switch (path) { -- GitLab From 34b51819036f6f74b74030dfca50e041113a3cea Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 14 Sep 2018 19:49:31 +0530 Subject: [PATCH 0520/1645] ASoC: wcd937x: Reduce latency in case of impedance detection Bulk read api does not work properly for swr regmap, causing failure/delay in impedance detection. Use regmap read api to avoid the issue. CRs-Fixed: 2301798 Change-Id: I5727cfcb7846f40f5b0f75b7976b492e2a2bfde0 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x-mbhc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index c7be66d8aedb..cd7039369563 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -413,8 +413,10 @@ static inline void wcd937x_mbhc_get_result_params(struct wcd937x_priv *wcd937x, ramp_down: i = 0; while (x1) { - regmap_bulk_read(wcd937x->regmap, - WCD937X_ANA_MBHC_RESULT_1, (u8 *)&val, 2); + regmap_read(wcd937x->regmap, WCD937X_ANA_MBHC_RESULT_1, &val); + regmap_read(wcd937x->regmap, WCD937X_ANA_MBHC_RESULT_2, &val1); + val = val << 0x8; + val |= val1; x1 = WCD937X_MBHC_GET_X1(val); i++; if (i == WCD937X_ZDET_NUM_MEASUREMENTS) @@ -972,7 +974,7 @@ int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc, wcd_mbhc_deinit(wcd_mbhc); ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids, - wcd_mbhc_registers, false); + wcd_mbhc_registers, WCD937X_ZDET_SUPPORTED); if (ret) { dev_err(codec->dev, "%s: mbhc initialization failed\n", __func__); @@ -1024,7 +1026,7 @@ int wcd937x_mbhc_init(struct wcd937x_mbhc **mbhc, struct snd_soc_codec *codec, ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids, wcd_mbhc_registers, - false); + WCD937X_ZDET_SUPPORTED); if (ret) { dev_err(codec->dev, "%s: mbhc initialization failed\n", __func__); -- GitLab From 567bcd3b7a4abb1daf4c7490be498b5d0705511f Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 18 Sep 2018 09:47:06 +0800 Subject: [PATCH 0521/1645] ASoC: wcd934x: check sound card state to avoid pointer dereference When codec probe is not correctly completed and ADSP SSR happens before sound card is registered, calling SSR callback may result into NULL pointer dereference and kernel panic happens. Check sound card state when calling device_down and post_reset to avoid NULL pointer dereference. Change-Id: I35fd84af51edf45db6fd451dc68dbcaaed11fee7 Signed-off-by: Meng Wang --- asoc/codecs/wcd934x/wcd934x.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 49c17c41e4b9..36676767fb90 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -9977,6 +9977,12 @@ static int tavil_device_down(struct wcd9xxx *wcd9xxx) int ret; codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); + if (!codec->component.card) { + dev_err(codec->dev, "%s: sound card is not enumerated.\n", + __func__); + return -EINVAL; + } + priv = snd_soc_codec_get_drvdata(codec); for (count = 0; count < NUM_CODEC_DAIS; count++) priv->dai[count].bus_down_in_recovery = true; @@ -10027,6 +10033,11 @@ static int tavil_post_reset_cb(struct wcd9xxx *wcd9xxx) struct wcd_mbhc *mbhc; codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); + if (!codec->component.card) { + dev_err(codec->dev, "%s: sound card is not enumerated.\n", + __func__); + return -EINVAL; + } tavil = snd_soc_codec_get_drvdata(codec); control = dev_get_drvdata(codec->dev->parent); -- GitLab From 33367f849afa6765e9c199bc72b0b8ead7d3248a Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 18 Sep 2018 20:55:25 +0530 Subject: [PATCH 0522/1645] asoc: wcd937x: add support for disable HPH compander On wcd937x, add controls for HPH compander. Handle sequences for headphone path based on compander enabled or disabled. Change-Id: I2ebdd03a4f79dc6156327d0613fab2f26710393f Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd937x/internal.h | 2 + asoc/codecs/wcd937x/wcd937x.c | 84 ++++++++++++++++++++++++++++++---- 2 files changed, 78 insertions(+), 8 deletions(-) diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index f883e961d106..e2f1e03b3487 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -58,6 +58,8 @@ struct wcd937x_priv { struct wcd937x_mbhc *mbhc; u32 hph_mode; + bool comp1_enable; + bool comp2_enable; struct irq_domain *virq; struct wcd_irq_info irq_info; diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 5e34ad263a66..75ff26b48f01 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -398,8 +398,19 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x02); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, - 0x02, 0x02); + if (wcd937x->comp1_enable) { + snd_soc_update_bits(codec, + WCD937X_DIGITAL_CDC_COMP_CTL_0, + 0x02, 0x02); + snd_soc_update_bits(codec, + WCD937X_HPH_L_EN, 0x20, 0x00); + } else { + snd_soc_update_bits(codec, + WCD937X_DIGITAL_CDC_COMP_CTL_0, + 0x02, 0x00); + snd_soc_update_bits(codec, + WCD937X_HPH_L_EN, 0x20, 0x20); + } usleep_range(5000, 5010); snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); @@ -439,8 +450,19 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x0F, 0x02); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, - 0x01, 0x01); + if (wcd937x->comp2_enable) { + snd_soc_update_bits(codec, + WCD937X_DIGITAL_CDC_COMP_CTL_0, + 0x01, 0x01); + snd_soc_update_bits(codec, + WCD937X_HPH_R_EN, 0x20, 0x00); + } else { + snd_soc_update_bits(codec, + WCD937X_DIGITAL_CDC_COMP_CTL_0, + 0x01, 0x00); + snd_soc_update_bits(codec, + WCD937X_HPH_R_EN, 0x20, 0x20); + } usleep_range(5000, 5010); snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); @@ -677,6 +699,7 @@ static int wcd937x_enable_rx1(struct snd_soc_dapm_widget *w, { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -704,11 +727,13 @@ static int wcd937x_enable_rx1(struct snd_soc_dapm_widget *w, usleep_range(500, 510); wcd937x_rx_connect_port(codec, HPH_L, true); - wcd937x_rx_connect_port(codec, COMP_L, true); + if (wcd937x->comp1_enable) + wcd937x_rx_connect_port(codec, COMP_L, true); break; case SND_SOC_DAPM_POST_PMD: wcd937x_rx_connect_port(codec, HPH_L, false); - wcd937x_rx_connect_port(codec, COMP_L, false); + if (wcd937x->comp1_enable) + wcd937x_rx_connect_port(codec, COMP_L, false); wcd937x_rx_clk_disable(codec); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x00); @@ -720,6 +745,7 @@ static int wcd937x_enable_rx2(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -745,11 +771,13 @@ static int wcd937x_enable_rx2(struct snd_soc_dapm_widget *w, usleep_range(500, 510); wcd937x_rx_connect_port(codec, HPH_R, true); - wcd937x_rx_connect_port(codec, COMP_R, true); + if (wcd937x->comp2_enable) + wcd937x_rx_connect_port(codec, COMP_R, true); break; case SND_SOC_DAPM_POST_PMD: wcd937x_rx_connect_port(codec, HPH_R, false); - wcd937x_rx_connect_port(codec, COMP_R, false); + if (wcd937x->comp2_enable) + wcd937x_rx_connect_port(codec, COMP_R, false); wcd937x_rx_clk_disable(codec); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x02, 0x00); @@ -1223,6 +1251,42 @@ static int wcd937x_rx_hph_mode_put(struct snd_kcontrol *kcontrol, return 0; } +static int wcd937x_get_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + bool hphr; + struct soc_multi_mixer_control *mc; + + mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); + hphr = mc->shift; + + ucontrol->value.integer.value[0] = hphr ? wcd937x->comp2_enable : + wcd937x->comp1_enable; + return 0; +} + +static int wcd937x_set_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int value = ucontrol->value.integer.value[0]; + bool hphr; + struct soc_multi_mixer_control *mc; + + mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); + hphr = mc->shift; + if (hphr) + wcd937x->comp2_enable = value; + else + wcd937x->comp1_enable = value; + + return 0; +} + static const char * const rx_hph_mode_mux_text[] = { "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI", "CLS_H_ULP", "CLS_AB_HIFI", @@ -1235,6 +1299,10 @@ static const struct soc_enum rx_hph_mode_mux_enum = static const struct snd_kcontrol_new wcd937x_snd_controls[] = { SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum, wcd937x_rx_hph_mode_get, wcd937x_rx_hph_mode_put), + SOC_SINGLE_EXT("HPHL_COMP Switch", SND_SOC_NOPM, 0, 1, 0, + wcd937x_get_compander, wcd937x_set_compander), + SOC_SINGLE_EXT("HPHR_COMP Switch", SND_SOC_NOPM, 1, 1, 0, + wcd937x_get_compander, wcd937x_set_compander), SOC_SINGLE_TLV("HPHL Volume", WCD937X_HPH_L_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("HPHR Volume", WCD937X_HPH_R_EN, 0, 20, 1, line_gain), -- GitLab From c226e86c15cea3a450f23611038638fdf2e722c6 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Thu, 6 Sep 2018 14:34:03 +0800 Subject: [PATCH 0523/1645] ASoC: rate limit for error log Use rate limit to reduce redundant log. Change-Id: I7cd7403c42ddce7915c5ecb82504e6c38bcf0572 Signed-off-by: Xiaojun Sang --- dsp/codecs/audio_aac.c | 6 +++--- dsp/codecs/audio_alac.c | 6 +++--- dsp/codecs/audio_ape.c | 6 +++--- dsp/codecs/audio_utils_aio.c | 34 +++++++++++++++++----------------- dsp/codecs/audio_wma.c | 6 +++--- dsp/codecs/audio_wmapro.c | 6 +++--- dsp/q6asm.c | 12 ++++++------ 7 files changed, 38 insertions(+), 38 deletions(-) diff --git a/dsp/codecs/audio_aac.c b/dsp/codecs/audio_aac.c index c742f722ee84..44444efef477 100644 --- a/dsp/codecs/audio_aac.c +++ b/dsp/codecs/audio_aac.c @@ -2,7 +2,7 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2018, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -230,7 +230,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); if (rc) - pr_err("%s[%pK]:Failed in utils_ioctl: %d\n", + pr_err_ratelimited("%s[%pK]:Failed in utils_ioctl: %d\n", __func__, audio, rc); } } @@ -339,7 +339,7 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_compat_ioctl(file, cmd, arg); if (rc) - pr_err("%s[%pK]:Failed in utils_ioctl: %d\n", + pr_err_ratelimited("%s[%pK]:Failed in utils_ioctl: %d\n", __func__, audio, rc); } } diff --git a/dsp/codecs/audio_alac.c b/dsp/codecs/audio_alac.c index cfb3087fec46..975a1e903937 100644 --- a/dsp/codecs/audio_alac.c +++ b/dsp/codecs/audio_alac.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -151,7 +151,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) default: { rc = audio->codec_ioctl(file, cmd, arg); if (rc) - pr_err("Failed in utils_ioctl: %d\n", rc); + pr_err_ratelimited("Failed in utils_ioctl: %d\n", rc); break; } } @@ -253,7 +253,7 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, default: { rc = audio->codec_compat_ioctl(file, cmd, arg); if (rc) - pr_err("Failed in utils_ioctl: %d\n", rc); + pr_err_ratelimited("Failed in utils_ioctl: %d\n", rc); break; } } diff --git a/dsp/codecs/audio_ape.c b/dsp/codecs/audio_ape.c index 3df634713a69..f2a6bf7ccd99 100644 --- a/dsp/codecs/audio_ape.c +++ b/dsp/codecs/audio_ape.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -137,7 +137,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); if (rc) - pr_err("Failed in utils_ioctl: %d\n", rc); + pr_err_ratelimited("Failed in utils_ioctl: %d\n", rc); break; } } @@ -235,7 +235,7 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_compat_ioctl(file, cmd, arg); if (rc) - pr_err("Failed in utils_ioctl: %d\n", rc); + pr_err_ratelimited("Failed in utils_ioctl: %d\n", rc); break; } } diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c index db07d3f263c3..298a77d0d401 100644 --- a/dsp/codecs/audio_utils_aio.c +++ b/dsp/codecs/audio_utils_aio.c @@ -201,17 +201,17 @@ static int audio_aio_pause(struct q6audio_aio *audio) if (audio->enabled) { rc = q6asm_cmd(audio->ac, CMD_PAUSE); if (rc < 0) - pr_err("%s[%pK]: pause cmd failed rc=%d\n", + pr_err_ratelimited("%s[%pK]: pause cmd failed rc=%d\n", __func__, audio, rc); if (rc == 0) { /* Send suspend only if pause was successful */ rc = q6asm_cmd(audio->ac, CMD_SUSPEND); if (rc < 0) - pr_err("%s[%pK]: suspend cmd failed rc=%d\n", + pr_err_ratelimited("%s[%pK]: suspend cmd failed rc=%d\n", __func__, audio, rc); } else - pr_err("%s[%pK]: not sending suspend since pause failed\n", + pr_err_ratelimited("%s[%pK]: not sending suspend since pause failed\n", __func__, audio); } else @@ -230,7 +230,7 @@ static int audio_aio_flush(struct q6audio_aio *audio) if (!(audio->drv_status & ADRV_STATUS_PAUSE)) { rc = audio_aio_pause(audio); if (rc < 0) - pr_err("%s[%pK}: pause cmd failed rc=%d\n", + pr_err_ratelimited("%s[%pK}: pause cmd failed rc=%d\n", __func__, audio, rc); else @@ -238,13 +238,13 @@ static int audio_aio_flush(struct q6audio_aio *audio) } rc = q6asm_cmd(audio->ac, CMD_FLUSH); if (rc < 0) - pr_err("%s[%pK]: flush cmd failed rc=%d\n", + pr_err_ratelimited("%s[%pK]: flush cmd failed rc=%d\n", __func__, audio, rc); /* Not in stop state, reenable the stream */ if (audio->stopped == 0) { rc = audio_aio_enable(audio); if (rc) - pr_err("%s[%pK]:audio re-enable failed\n", + pr_err_ratelimited("%s[%pK]:audio re-enable failed\n", __func__, audio); else { audio->enabled = 1; @@ -268,7 +268,7 @@ static int audio_aio_outport_flush(struct q6audio_aio *audio) rc = q6asm_cmd(audio->ac, CMD_OUT_FLUSH); if (rc < 0) - pr_err("%s[%pK}: output port flush cmd failed rc=%d\n", + pr_err_ratelimited("%s[%pK}: output port flush cmd failed rc=%d\n", __func__, audio, rc); return rc; } @@ -402,7 +402,7 @@ int audio_aio_disable(struct q6audio_aio *audio) /* Close the session */ rc = q6asm_cmd(audio->ac, CMD_CLOSE); if (rc < 0) - pr_err("%s[%pK]:Failed to close the session rc=%d\n", + pr_err_ratelimited("%s[%pK]:Failed to close the session rc=%d\n", __func__, audio, rc); audio->stopped = 1; wake_up(&audio->write_wait); @@ -676,7 +676,7 @@ int audio_aio_fsync(struct file *file, loff_t start, loff_t end, int datasync) pr_debug("%s[%pK]: EOS cmd sent to DSP\n", __func__, audio); if (rc < 0) - pr_err("%s[%pK]: q6asm_cmd failed, rc = %d", + pr_err_ratelimited("%s[%pK]: q6asm_cmd failed, rc = %d", __func__, audio, rc); pr_debug("%s[%pK]: wait for RENDERED_EOS from DSP\n" @@ -1409,7 +1409,7 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, mutex_lock(&audio->read_lock); rc = audio_aio_outport_flush(audio); if (rc < 0) { - pr_err("%s[%pK]: AUDIO_OUTPORT_FLUSH failed\n", + pr_err_ratelimited("%s[%pK]: AUDIO_OUTPORT_FLUSH failed\n", __func__, audio); rc = -EINTR; } @@ -1423,7 +1423,7 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, audio->stopped = 1; rc = audio_aio_flush(audio); if (rc < 0) { - pr_err("%s[%pK]:Audio Stop procedure failed rc=%d\n", + pr_err_ratelimited("%s[%pK]:Audio Stop procedure failed rc=%d\n", __func__, audio, rc); mutex_unlock(&audio->lock); break; @@ -1444,7 +1444,7 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, if (arg == 1) { rc = audio_aio_pause(audio); if (rc < 0) { - pr_err("%s[%pK]: pause FAILED rc=%d\n", + pr_err_ratelimited("%s[%pK]: pause FAILED rc=%d\n", __func__, audio, rc); mutex_unlock(&audio->lock); break; @@ -1454,7 +1454,7 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, if (audio->drv_status & ADRV_STATUS_PAUSE) { rc = audio_aio_enable(audio); if (rc) - pr_err("%s[%pK]: audio enable failed\n", + pr_err_ratelimited("%s[%pK]: audio enable failed\n", __func__, audio); else { audio->drv_status &= ~ADRV_STATUS_PAUSE; @@ -1481,7 +1481,7 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, /* Flush input / Output buffer in software*/ audio_aio_ioport_reset(audio); if (rc < 0) { - pr_err("%s[%pK]:AUDIO_FLUSH interrupted\n", + pr_err_ratelimited("%s[%pK]:AUDIO_FLUSH interrupted\n", __func__, audio); rc = -EINTR; } else { @@ -1501,7 +1501,7 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, mutex_lock(&audio->lock); if (copy_to_user((void *)arg, &audio->ac->session, sizeof(u16))) { - pr_err("%s: copy_to_user for AUDIO_GET_SESSION_ID failed\n", + pr_err_ratelimited("%s: copy_to_user for AUDIO_GET_SESSION_ID failed\n", __func__); rc = -EFAULT; } @@ -1511,7 +1511,7 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, case AUDIO_PM_AWAKE: { if ((audio->audio_ws_mgr == NULL) || (audio->miscdevice == NULL)) { - pr_err("%s[%pK]: invalid ws_mgr or miscdevice", + pr_err_ratelimited("%s[%pK]: invalid ws_mgr or miscdevice", __func__, audio); rc = -EACCES; break; @@ -1531,7 +1531,7 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, case AUDIO_PM_RELAX: { if ((audio->audio_ws_mgr == NULL) || (audio->miscdevice == NULL)) { - pr_err("%s[%pK]: invalid ws_mgr or miscdevice", + pr_err_ratelimited("%s[%pK]: invalid ws_mgr or miscdevice", __func__, audio); rc = -EACCES; break; diff --git a/dsp/codecs/audio_wma.c b/dsp/codecs/audio_wma.c index ef9c8c65c085..0e8341e1088c 100644 --- a/dsp/codecs/audio_wma.c +++ b/dsp/codecs/audio_wma.c @@ -2,7 +2,7 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -126,7 +126,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); if (rc) - pr_err("Failed in utils_ioctl: %d\n", rc); + pr_err_ratelimited("Failed in utils_ioctl: %d\n", rc); break; } } @@ -215,7 +215,7 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_compat_ioctl(file, cmd, arg); if (rc) - pr_err("Failed in utils_ioctl: %d\n", rc); + pr_err_ratelimited("Failed in utils_ioctl: %d\n", rc); break; } } diff --git a/dsp/codecs/audio_wmapro.c b/dsp/codecs/audio_wmapro.c index 21826189b6a0..6b1e46f45b60 100644 --- a/dsp/codecs/audio_wmapro.c +++ b/dsp/codecs/audio_wmapro.c @@ -2,7 +2,7 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -177,7 +177,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_ioctl(file, cmd, arg); if (rc) - pr_err("Failed in utils_ioctl: %d\n", rc); + pr_err_ratelimited("Failed in utils_ioctl: %d\n", rc); break; } } @@ -287,7 +287,7 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio); rc = audio->codec_compat_ioctl(file, cmd, arg); if (rc) - pr_err("Failed in utils_ioctl: %d\n", rc); + pr_err_ratelimited("Failed in utils_ioctl: %d\n", rc); break; } } diff --git a/dsp/q6asm.c b/dsp/q6asm.c index b7d92ad85e29..b153bb9528f7 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -9444,11 +9444,11 @@ static int __q6asm_cmd(struct audio_client *ac, int cmd, uint32_t stream_id) int cnt = 0; if (!ac) { - pr_err("%s: APR handle NULL\n", __func__); + pr_err_ratelimited("%s: APR handle NULL\n", __func__); return -EINVAL; } if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); + pr_err_ratelimited("%s: AC APR handle NULL\n", __func__); return -EINVAL; } q6asm_stream_add_hdr(ac, &hdr, sizeof(hdr), TRUE, stream_id); @@ -9608,11 +9608,11 @@ static int __q6asm_cmd_nowait(struct audio_client *ac, int cmd, int rc; if (!ac) { - pr_err("%s: APR handle NULL\n", __func__); + pr_err_ratelimited("%s: APR handle NULL\n", __func__); return -EINVAL; } if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); + pr_err_ratelimited("%s: AC APR handle NULL\n", __func__); return -EINVAL; } q6asm_stream_add_hdr_async(ac, &hdr, sizeof(hdr), TRUE, stream_id); @@ -9697,11 +9697,11 @@ int __q6asm_send_meta_data(struct audio_client *ac, uint32_t stream_id, int rc = 0; if (!ac) { - pr_err("%s: APR handle NULL\n", __func__); + pr_err_ratelimited("%s: APR handle NULL\n", __func__); return -EINVAL; } if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); + pr_err_ratelimited("%s: AC APR handle NULL\n", __func__); return -EINVAL; } pr_debug("%s: session[%d]\n", __func__, ac->session); -- GitLab From d85e6f3384b02ba77355fef4be6a24ab73172034 Mon Sep 17 00:00:00 2001 From: Tanya Dixit Date: Fri, 14 Sep 2018 16:06:20 +0530 Subject: [PATCH 0524/1645] asoc: sm6150: Add proper checks for ch_num Check the value of ch_num and return if less than zero to avoid out of bound access in cdc_dma_cfg arrays. Change-Id: Ie59f5e7ed063d65a61033a142acd2bcf2287c39b Signed-off-by: Tanya Dixit --- asoc/sm6150.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 72181221ea1f..f62c39ec0fc5 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -1250,8 +1250,10 @@ static int cdc_dma_rx_ch_get(struct snd_kcontrol *kcontrol, { int ch_num = cdc_dma_get_port_idx(kcontrol); - if (ch_num < 0) + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); return ch_num; + } pr_debug("%s: cdc_dma_rx_ch = %d\n", __func__, cdc_dma_rx_cfg[ch_num].channels - 1); @@ -1264,8 +1266,10 @@ static int cdc_dma_rx_ch_put(struct snd_kcontrol *kcontrol, { int ch_num = cdc_dma_get_port_idx(kcontrol); - if (ch_num < 0) + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); return ch_num; + } cdc_dma_rx_cfg[ch_num].channels = ucontrol->value.integer.value[0] + 1; @@ -1279,6 +1283,11 @@ static int cdc_dma_rx_format_get(struct snd_kcontrol *kcontrol, { int ch_num = cdc_dma_get_port_idx(kcontrol); + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + switch (cdc_dma_rx_cfg[ch_num].bit_format) { case SNDRV_PCM_FORMAT_S32_LE: ucontrol->value.integer.value[0] = 3; @@ -1307,6 +1316,11 @@ static int cdc_dma_rx_format_put(struct snd_kcontrol *kcontrol, int rc = 0; int ch_num = cdc_dma_get_port_idx(kcontrol); + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + switch (ucontrol->value.integer.value[0]) { case 3: cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S32_LE; @@ -1437,8 +1451,10 @@ static int cdc_dma_rx_sample_rate_get(struct snd_kcontrol *kcontrol, { int ch_num = cdc_dma_get_port_idx(kcontrol); - if (ch_num < 0) + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); return ch_num; + } ucontrol->value.enumerated.item[0] = cdc_dma_get_sample_rate_val(cdc_dma_rx_cfg[ch_num].sample_rate); @@ -1453,8 +1469,10 @@ static int cdc_dma_rx_sample_rate_put(struct snd_kcontrol *kcontrol, { int ch_num = cdc_dma_get_port_idx(kcontrol); - if (ch_num < 0) + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); return ch_num; + } cdc_dma_rx_cfg[ch_num].sample_rate = cdc_dma_get_sample_rate(ucontrol->value.enumerated.item[0]); @@ -1471,6 +1489,11 @@ static int cdc_dma_tx_ch_get(struct snd_kcontrol *kcontrol, { int ch_num = cdc_dma_get_port_idx(kcontrol); + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + pr_debug("%s: cdc_dma_tx_ch = %d\n", __func__, cdc_dma_tx_cfg[ch_num].channels); ucontrol->value.integer.value[0] = cdc_dma_tx_cfg[ch_num].channels - 1; @@ -1482,6 +1505,11 @@ static int cdc_dma_tx_ch_put(struct snd_kcontrol *kcontrol, { int ch_num = cdc_dma_get_port_idx(kcontrol); + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + cdc_dma_tx_cfg[ch_num].channels = ucontrol->value.integer.value[0] + 1; pr_debug("%s: cdc_dma_tx_ch = %d\n", __func__, @@ -1495,6 +1523,11 @@ static int cdc_dma_tx_sample_rate_get(struct snd_kcontrol *kcontrol, int sample_rate_val; int ch_num = cdc_dma_get_port_idx(kcontrol); + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + switch (cdc_dma_tx_cfg[ch_num].sample_rate) { case SAMPLING_RATE_384KHZ: sample_rate_val = 12; @@ -1551,6 +1584,11 @@ static int cdc_dma_tx_sample_rate_put(struct snd_kcontrol *kcontrol, { int ch_num = cdc_dma_get_port_idx(kcontrol); + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + switch (ucontrol->value.integer.value[0]) { case 12: cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_384KHZ; @@ -1607,6 +1645,11 @@ static int cdc_dma_tx_format_get(struct snd_kcontrol *kcontrol, { int ch_num = cdc_dma_get_port_idx(kcontrol); + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + switch (cdc_dma_tx_cfg[ch_num].bit_format) { case SNDRV_PCM_FORMAT_S32_LE: ucontrol->value.integer.value[0] = 3; @@ -1635,6 +1678,11 @@ static int cdc_dma_tx_format_put(struct snd_kcontrol *kcontrol, int rc = 0; int ch_num = cdc_dma_get_port_idx(kcontrol); + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + switch (ucontrol->value.integer.value[0]) { case 3: cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S32_LE; -- GitLab From 4f3d5643bdc87ec1562fb79fe675c2e790889512 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 18 Sep 2018 22:19:10 +0530 Subject: [PATCH 0525/1645] asoc: codecs: Add support for BCL feature Add mixer widgets, routing and mixer controls in order to support BCL feature on WSA and RX macros of bolero codec. CRs-Fixed: 2225097 Change-Id: I463f89a517bb3878e51a6aca0c1d73bc652ab8c5 Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/rx-macro.c | 333 +++++++++++++++++++++++++++ asoc/codecs/bolero/wsa-macro.c | 396 +++++++++++++++++++++++++++++++++ 2 files changed, 729 insertions(+) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 006f863bd0aa..d387baf0fe6d 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -160,6 +160,12 @@ static struct interp_sample_rate sr_val_tbl[] = { {176400, 0xB}, {352800, 0xC}, }; +struct rx_macro_bcl_pmic_params { + u8 id; + u8 sid; + u8 ppid; +}; + static int rx_macro_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai); @@ -258,6 +264,9 @@ struct rx_macro_priv { struct platform_device *pdev_child_devices [RX_MACRO_CHILD_DEVICES_MAX]; int child_count; + int is_softclip_on; + int softclip_clk_users; + struct rx_macro_bcl_pmic_params bcl_pmic_params; }; static struct snd_soc_dai_driver rx_macro_dai[]; @@ -321,6 +330,14 @@ static const char *const rx_macro_ear_mode_text[] = {"OFF", "ON"}; static const struct soc_enum rx_macro_ear_mode_enum = SOC_ENUM_SINGLE_EXT(2, rx_macro_ear_mode_text); +static const char * const rx_macro_vbat_bcl_gsm_mode_text[] = {"OFF", "ON"}; +static const struct soc_enum rx_macro_vbat_bcl_gsm_mode_enum = + SOC_ENUM_SINGLE_EXT(2, rx_macro_vbat_bcl_gsm_mode_text); + +static const struct snd_kcontrol_new rx_int2_1_vbat_mix_switch[] = { + SOC_DAPM_SINGLE("RX AUX VBAT Enable", SND_SOC_NOPM, 0, 1, 0) +}; + RX_MACRO_DAPM_ENUM(rx_int0_2, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, rx_int_mix_mux_text); RX_MACRO_DAPM_ENUM(rx_int1_2, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, @@ -1159,6 +1176,52 @@ static int rx_macro_config_compander(struct snd_soc_codec *codec, return 0; } +static void rx_macro_enable_softclip_clk(struct snd_soc_codec *codec, + struct rx_macro_priv *rx_priv, + bool enable) +{ + if (enable) { + if (rx_priv->softclip_clk_users == 0) + snd_soc_update_bits(codec, + BOLERO_CDC_RX_SOFTCLIP_CRC, + 0x01, 0x01); + rx_priv->softclip_clk_users++; + } else { + rx_priv->softclip_clk_users--; + if (rx_priv->softclip_clk_users == 0) + snd_soc_update_bits(codec, + BOLERO_CDC_RX_SOFTCLIP_CRC, + 0x01, 0x00); + } +} + +static int rx_macro_config_softclip(struct snd_soc_codec *codec, + struct rx_macro_priv *rx_priv, + int event) +{ + dev_dbg(codec->dev, "%s: event %d, enabled %d\n", + __func__, event, rx_priv->is_softclip_on); + + if (!rx_priv->is_softclip_on) + return 0; + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Softclip clock */ + rx_macro_enable_softclip_clk(codec, rx_priv, true); + /* Enable Softclip control */ + snd_soc_update_bits(codec, + BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x01, 0x01); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, + BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x01, 0x00); + rx_macro_enable_softclip_clk(codec, rx_priv, false); + } + + return 0; +} + static inline void rx_macro_enable_clsh_block(struct rx_macro_priv *rx_priv, bool enable) { @@ -1391,6 +1454,191 @@ static int rx_macro_put_ear_mode(struct snd_kcontrol *kcontrol, return 0; } +static int rx_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + ucontrol->value.integer.value[0] = + ((snd_soc_read(codec, BOLERO_CDC_RX_BCL_VBAT_CFG) & 0x04) ? + 1 : 0); + + dev_dbg(codec->dev, "%s: value: %lu\n", __func__, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int rx_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: value: %lu\n", __func__, + ucontrol->value.integer.value[0]); + + /* Set Vbat register configuration for GSM mode bit based on value */ + if (ucontrol->value.integer.value[0]) + snd_soc_update_bits(codec, BOLERO_CDC_RX_BCL_VBAT_CFG, + 0x04, 0x04); + else + snd_soc_update_bits(codec, BOLERO_CDC_RX_BCL_VBAT_CFG, + 0x04, 0x00); + + return 0; +} + +static int rx_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = rx_priv->is_softclip_on; + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int rx_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + rx_priv->is_softclip_on = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: soft clip enable = %d\n", __func__, + rx_priv->is_softclip_on); + + return 0; +} + +static int rx_macro_enable_vbat(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Enable clock for VBAT block */ + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_PATH_CTL, 0x10, 0x10); + /* Enable VBAT block */ + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_CFG, 0x01, 0x01); + /* Update interpolator with 384K path */ + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG1, + 0x80, 0x80); + /* Update DSM FS rate */ + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_SEC7, + 0x02, 0x02); + /* Use attenuation mode */ + snd_soc_update_bits(codec, BOLERO_CDC_RX_BCL_VBAT_CFG, + 0x02, 0x00); + /* BCL block needs softclip clock to be enabled */ + rx_macro_enable_softclip_clk(codec, rx_priv, true); + /* Enable VBAT at channel level */ + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG1, + 0x02, 0x02); + /* Set the ATTK1 gain */ + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1, + 0xFF, 0xFF); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2, + 0xFF, 0x03); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3, + 0xFF, 0x00); + /* Set the ATTK2 gain */ + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4, + 0xFF, 0xFF); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5, + 0xFF, 0x03); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6, + 0xFF, 0x00); + /* Set the ATTK3 gain */ + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7, + 0xFF, 0xFF); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8, + 0xFF, 0x03); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9, + 0xFF, 0x00); + break; + + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG1, + 0x80, 0x00); + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_SEC7, + 0x02, 0x00); + snd_soc_update_bits(codec, BOLERO_CDC_RX_BCL_VBAT_CFG, + 0x02, 0x02); + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG1, + 0x02, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1, + 0xFF, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2, + 0xFF, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3, + 0xFF, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4, + 0xFF, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5, + 0xFF, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6, + 0xFF, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7, + 0xFF, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8, + 0xFF, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9, + 0xFF, 0x00); + rx_macro_enable_softclip_clk(codec, rx_priv, false); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_CFG, 0x01, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_PATH_CTL, 0x10, 0x00); + break; + default: + dev_err(rx_dev, "%s: Invalid event %d\n", __func__, event); + break; + } + return 0; +} + static void rx_macro_idle_detect_control(struct snd_soc_codec *codec, struct rx_macro_priv *rx_priv, int interp, int event) @@ -1504,6 +1752,9 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, event); rx_macro_config_compander(codec, rx_priv, interp_idx, event); + if (interp_idx == INTERP_AUX) + rx_macro_config_softclip(codec, rx_priv, + event); rx_macro_config_classh(codec, rx_priv, interp_idx, event); } @@ -1518,6 +1769,9 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, interp_idx, event); rx_macro_config_compander(codec, rx_priv, interp_idx, event); + if (interp_idx == INTERP_AUX) + rx_macro_config_softclip(codec, rx_priv, + event); rx_macro_hphdelay_lutbypass(codec, rx_priv, interp_idx, event); rx_macro_hd2_control(codec, interp_idx, event); @@ -1881,6 +2135,13 @@ static const struct snd_kcontrol_new rx_macro_snd_controls[] = { SOC_ENUM_EXT("RX_EAR Mode", rx_macro_ear_mode_enum, rx_macro_get_ear_mode, rx_macro_put_ear_mode), + SOC_ENUM_EXT("RX_GSM mode Enable", rx_macro_vbat_bcl_gsm_mode_enum, + rx_macro_vbat_bcl_gsm_mode_func_get, + rx_macro_vbat_bcl_gsm_mode_func_put), + SOC_SINGLE_EXT("RX_Softclip Enable", SND_SOC_NOPM, 0, 1, 0, + rx_macro_soft_clip_enable_get, + rx_macro_soft_clip_enable_put), + SOC_SINGLE_SX_TLV("IIR0 INP0 Volume", BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40, digital_gain), @@ -2079,6 +2340,12 @@ static const struct snd_soc_dapm_widget rx_macro_dapm_widgets[] = { 0, &rx_int2_mix2_inp_mux, rx_macro_enable_rx_path_clk, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX INT2_1 VBAT", SND_SOC_NOPM, + 0, 0, rx_int2_1_vbat_mix_switch, + ARRAY_SIZE(rx_int2_1_vbat_mix_switch), + rx_macro_enable_vbat, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), @@ -2269,6 +2536,10 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { {"HPHR_OUT", NULL, "RX_MCLK"}, {"RX INT2_1 INTERP", NULL, "RX INT2_1 MIX1"}, + + {"RX INT2_1 VBAT", "RX AUX VBAT Enable", "RX INT2_1 INTERP"}, + {"RX INT2 SEC MIX", NULL, "RX INT2_1 VBAT"}, + {"RX INT2 SEC MIX", NULL, "RX INT2_1 INTERP"}, {"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"}, {"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"}, @@ -2434,6 +2705,53 @@ static int rx_swrm_clock(void *handle, bool enable) return ret; } +static void rx_macro_init_bcl_pmic_reg(struct snd_soc_codec *codec) +{ + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!codec) { + pr_err("%s: NULL codec pointer!\n", __func__); + return; + } + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return; + + switch (rx_priv->bcl_pmic_params.id) { + case 0: + /* Enable ID0 to listen to respective PMIC group interrupts */ + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1, 0x02, 0x02); + /* Update MC_SID0 */ + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1, 0x0F, + rx_priv->bcl_pmic_params.sid); + /* Update MC_PPID0 */ + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG2, 0xFF, + rx_priv->bcl_pmic_params.ppid); + break; + case 1: + /* Enable ID1 to listen to respective PMIC group interrupts */ + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1, 0x01, 0x01); + /* Update MC_SID1 */ + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG3, 0x0F, + rx_priv->bcl_pmic_params.sid); + /* Update MC_PPID1 */ + snd_soc_update_bits(codec, + BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1, 0xFF, + rx_priv->bcl_pmic_params.ppid); + break; + default: + dev_err(rx_dev, "%s: PMIC ID is invalid\n", + __func__, rx_priv->bcl_pmic_params.id); + break; + } +} + static int rx_macro_init(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); @@ -2486,6 +2804,7 @@ static int rx_macro_init(struct snd_soc_codec *codec) snd_soc_update_bits(codec, BOLERO_CDC_RX_RX0_RX_PATH_CFG3, 0x03, 0x02); snd_soc_update_bits(codec, BOLERO_CDC_RX_RX1_RX_PATH_CFG3, 0x03, 0x02); snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG3, 0x03, 0x02); + rx_macro_init_bcl_pmic_reg(codec); rx_priv->codec = codec; @@ -2631,6 +2950,7 @@ static int rx_macro_probe(struct platform_device *pdev) char __iomem *rx_io_base = NULL, *muxsel_io = NULL; int ret = 0; struct clk *rx_core_clk = NULL, *rx_npl_clk = NULL; + u8 bcl_pmic_params[3]; rx_priv = devm_kzalloc(&pdev->dev, sizeof(struct rx_macro_priv), GFP_KERNEL); @@ -2700,6 +3020,19 @@ static int rx_macro_probe(struct platform_device *pdev) return ret; } rx_priv->rx_npl_clk = rx_npl_clk; + + ret = of_property_read_u8_array(pdev->dev.of_node, + "qcom,rx-bcl-pmic-params", bcl_pmic_params, + sizeof(bcl_pmic_params)); + if (ret) { + dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "qcom,rx-bcl-pmic-params"); + } else { + rx_priv->bcl_pmic_params.id = bcl_pmic_params[0]; + rx_priv->bcl_pmic_params.sid = bcl_pmic_params[1]; + rx_priv->bcl_pmic_params.ppid = bcl_pmic_params[2]; + } + dev_set_drvdata(&pdev->dev, rx_priv); mutex_init(&rx_priv->mclk_lock); mutex_init(&rx_priv->swr_clk_lock); diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 47c5cd4bfca8..3fe637e9a3b2 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -50,6 +50,7 @@ #define WSA_MACRO_MUX_CFG_OFFSET 0x8 #define WSA_MACRO_MUX_CFG1_OFFSET 0x4 #define WSA_MACRO_RX_COMP_OFFSET 0x40 +#define WSA_MACRO_RX_SOFTCLIP_OFFSET 0x40 #define WSA_MACRO_RX_PATH_OFFSET 0x80 #define WSA_MACRO_RX_PATH_CFG3_OFFSET 0x10 #define WSA_MACRO_RX_PATH_DSMDEM_OFFSET 0x4C @@ -82,6 +83,12 @@ enum { WSA_MACRO_COMP_MAX }; +enum { + WSA_MACRO_SOFTCLIP0, /* RX0 */ + WSA_MACRO_SOFTCLIP1, /* RX1 */ + WSA_MACRO_SOFTCLIP_MAX +}; + struct interp_sample_rate { int sample_rate; int rate_val; @@ -141,6 +148,12 @@ struct wsa_macro_swr_ctrl_platform_data { int action); }; +struct wsa_macro_bcl_pmic_params { + u8 id; + u8 sid; + u8 ppid; +}; + enum { WSA_MACRO_AIF_INVALID = 0, WSA_MACRO_AIF1_PB, @@ -205,6 +218,9 @@ struct wsa_macro_priv { int ear_spkr_gain; int spkr_gain_offset; int spkr_mode; + int is_softclip_on[WSA_MACRO_SOFTCLIP_MAX]; + int softclip_clk_users[WSA_MACRO_SOFTCLIP_MAX]; + struct wsa_macro_bcl_pmic_params bcl_pmic_params; }; static int wsa_macro_config_ear_spkr_gain(struct snd_soc_codec *codec, @@ -242,10 +258,24 @@ static const char * const wsa_macro_speaker_boost_stage_text[] = { "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2" }; +static const char * const wsa_macro_vbat_bcl_gsm_mode_text[] = { + "OFF", "ON" +}; + +static const struct snd_kcontrol_new wsa_int0_vbat_mix_switch[] = { + SOC_DAPM_SINGLE("WSA RX0 VBAT Enable", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new wsa_int1_vbat_mix_switch[] = { + SOC_DAPM_SINGLE("WSA RX1 VBAT Enable", SND_SOC_NOPM, 0, 1, 0) +}; + static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_ear_spkr_pa_gain_enum, wsa_macro_ear_spkr_pa_gain_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_spkr_boost_stage_enum, wsa_macro_speaker_boost_stage_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_vbat_bcl_gsm_mode_enum, + wsa_macro_vbat_bcl_gsm_mode_text); /* RX INT0 */ static const struct soc_enum rx0_prim_inp0_chain_enum = @@ -1095,6 +1125,82 @@ static int wsa_macro_config_compander(struct snd_soc_codec *codec, return 0; } +static void wsa_macro_enable_softclip_clk(struct snd_soc_codec *codec, + struct wsa_macro_priv *wsa_priv, + int path, + bool enable) +{ + u16 softclip_clk_reg = BOLERO_CDC_WSA_SOFTCLIP0_CRC + + (path * WSA_MACRO_RX_SOFTCLIP_OFFSET); + u8 softclip_mux_mask = (1 << path); + u8 softclip_mux_value = (1 << path); + + dev_dbg(codec->dev, "%s: path %d, enable %d\n", + __func__, path, enable); + if (enable) { + if (wsa_priv->softclip_clk_users[path] == 0) { + snd_soc_update_bits(codec, + softclip_clk_reg, 0x01, 0x01); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0, + softclip_mux_mask, softclip_mux_value); + } + wsa_priv->softclip_clk_users[path]++; + } else { + wsa_priv->softclip_clk_users[path]--; + if (wsa_priv->softclip_clk_users[path] == 0) { + snd_soc_update_bits(codec, + softclip_clk_reg, 0x01, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0, + softclip_mux_mask, 0x00); + } + } +} + +static int wsa_macro_config_softclip(struct snd_soc_codec *codec, + int path, int event) +{ + u16 softclip_ctrl_reg = 0; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + int softclip_path = 0; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + if (path == WSA_MACRO_COMP1) + softclip_path = WSA_MACRO_SOFTCLIP0; + else if (path == WSA_MACRO_COMP2) + softclip_path = WSA_MACRO_SOFTCLIP1; + + dev_dbg(codec->dev, "%s: event %d path %d, enabled %d\n", + __func__, event, softclip_path, + wsa_priv->is_softclip_on[softclip_path]); + + if (!wsa_priv->is_softclip_on[softclip_path]) + return 0; + + softclip_ctrl_reg = BOLERO_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL + + (softclip_path * WSA_MACRO_RX_SOFTCLIP_OFFSET); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Softclip clock and mux */ + wsa_macro_enable_softclip_clk(codec, wsa_priv, softclip_path, + true); + /* Enable Softclip control */ + snd_soc_update_bits(codec, softclip_ctrl_reg, 0x01, 0x01); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_update_bits(codec, softclip_ctrl_reg, 0x01, 0x00); + wsa_macro_enable_softclip_clk(codec, wsa_priv, softclip_path, + false); + } + + return 0; +} + static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind) { u16 prim_int_reg = 0; @@ -1204,6 +1310,7 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMU: wsa_macro_config_compander(codec, w->shift, event); + wsa_macro_config_softclip(codec, w->shift, event); /* apply gain after int clk is enabled */ if ((wsa_priv->spkr_gain_offset == WSA_MACRO_GAIN_OFFSET_M1P5_DB) && @@ -1231,6 +1338,7 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: wsa_macro_config_compander(codec, w->shift, event); + wsa_macro_config_softclip(codec, w->shift, event); wsa_macro_enable_prim_interpolator(codec, reg, event); if ((wsa_priv->spkr_gain_offset == WSA_MACRO_GAIN_OFFSET_M1P5_DB) && @@ -1356,6 +1464,127 @@ static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w, return 0; } + +static int wsa_macro_enable_vbat(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + u16 vbat_path_cfg = 0; + int softclip_path = 0; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + if (!strcmp(w->name, "WSA_RX INT0 VBAT")) { + vbat_path_cfg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1; + softclip_path = WSA_MACRO_SOFTCLIP0; + } else if (!strcmp(w->name, "WSA_RX INT1 VBAT")) { + vbat_path_cfg = BOLERO_CDC_WSA_RX1_RX_PATH_CFG1; + softclip_path = WSA_MACRO_SOFTCLIP1; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Enable clock for VBAT block */ + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x10); + /* Enable VBAT block */ + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x01); + /* Update interpolator with 384K path */ + snd_soc_update_bits(codec, vbat_path_cfg, 0x80, 0x80); + /* Use attenuation mode */ + snd_soc_update_bits(codec, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, + 0x02, 0x00); + /* + * BCL block needs softclip clock and mux config to be enabled + */ + wsa_macro_enable_softclip_clk(codec, wsa_priv, softclip_path, + true); + /* Enable VBAT at channel level */ + snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x02); + /* Set the ATTK1 gain */ + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1, + 0xFF, 0xFF); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2, + 0xFF, 0x03); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3, + 0xFF, 0x00); + /* Set the ATTK2 gain */ + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4, + 0xFF, 0xFF); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5, + 0xFF, 0x03); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6, + 0xFF, 0x00); + /* Set the ATTK3 gain */ + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7, + 0xFF, 0xFF); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8, + 0xFF, 0x03); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9, + 0xFF, 0x00); + break; + + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, vbat_path_cfg, 0x80, 0x00); + snd_soc_update_bits(codec, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, + 0x02, 0x02); + snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1, + 0xFF, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2, + 0xFF, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3, + 0xFF, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4, + 0xFF, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5, + 0xFF, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6, + 0xFF, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7, + 0xFF, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8, + 0xFF, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9, + 0xFF, 0x00); + wsa_macro_enable_softclip_clk(codec, wsa_priv, softclip_path, + false); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x00); + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x00); + break; + default: + dev_err(wsa_dev, "%s: Invalid event %d\n", __func__, event); + break; + } + return 0; +} + static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -1637,6 +1866,80 @@ static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol, return 0; } +static int wsa_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + ucontrol->value.integer.value[0] = + ((snd_soc_read(codec, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG) & 0x04) ? + 1 : 0); + + dev_dbg(codec->dev, "%s: value: %lu\n", __func__, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int wsa_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + + dev_dbg(codec->dev, "%s: value: %lu\n", __func__, + ucontrol->value.integer.value[0]); + + /* Set Vbat register configuration for GSM mode bit based on value */ + if (ucontrol->value.integer.value[0]) + snd_soc_update_bits(codec, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, + 0x04, 0x04); + else + snd_soc_update_bits(codec, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, + 0x04, 0x00); + + return 0; +} + +static int wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + int path = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = wsa_priv->is_softclip_on[path]; + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + int path = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + wsa_priv->is_softclip_on[path] = ucontrol->value.integer.value[0]; + + dev_dbg(codec->dev, "%s: soft clip enable for %d: %d\n", __func__, + path, wsa_priv->is_softclip_on[path]); + + return 0; +} + static const struct snd_kcontrol_new wsa_macro_snd_controls[] = { SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum, wsa_macro_ear_spkr_pa_gain_get, @@ -1649,6 +1952,17 @@ static const struct snd_kcontrol_new wsa_macro_snd_controls[] = { wsa_macro_spkr_boost_stage_enum, wsa_macro_spkr_right_boost_stage_get, wsa_macro_spkr_right_boost_stage_put), + SOC_ENUM_EXT("GSM mode Enable", wsa_macro_vbat_bcl_gsm_mode_enum, + wsa_macro_vbat_bcl_gsm_mode_func_get, + wsa_macro_vbat_bcl_gsm_mode_func_put), + SOC_SINGLE_EXT("WSA_Softclip0 Enable", SND_SOC_NOPM, + WSA_MACRO_SOFTCLIP0, 1, 0, + wsa_macro_soft_clip_enable_get, + wsa_macro_soft_clip_enable_put), + SOC_SINGLE_EXT("WSA_Softclip1 Enable", SND_SOC_NOPM, + WSA_MACRO_SOFTCLIP1, 1, 0, + wsa_macro_soft_clip_enable_get, + wsa_macro_soft_clip_enable_put), SOC_SINGLE_SX_TLV("WSA_RX0 Digital Volume", BOLERO_CDC_WSA_RX0_RX_VOL_CTL, 0, -84, 40, digital_gain), @@ -1862,6 +2176,17 @@ static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("WSA_RX INT0 VBAT", SND_SOC_NOPM, + 0, 0, wsa_int0_vbat_mix_switch, + ARRAY_SIZE(wsa_int0_vbat_mix_switch), + wsa_macro_enable_vbat, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("WSA_RX INT1 VBAT", SND_SOC_NOPM, + 0, 0, wsa_int1_vbat_mix_switch, + ARRAY_SIZE(wsa_int1_vbat_mix_switch), + wsa_macro_enable_vbat, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_INPUT("VIINPUT_WSA"), SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"), @@ -1939,6 +2264,10 @@ static const struct snd_soc_dapm_route wsa_audio_map[] = { {"WSA_RX0 INT0 SIDETONE MIX", "SRC0", "WSA SRC0_INP"}, {"WSA_RX INT0 INTERP", NULL, "WSA_RX0 INT0 SIDETONE MIX"}, {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"}, + + {"WSA_RX INT0 VBAT", "WSA RX0 VBAT Enable", "WSA_RX INT0 INTERP"}, + {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 VBAT"}, + {"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"}, {"WSA_SPK1 OUT", NULL, "WSA_MCLK"}, @@ -1974,6 +2303,10 @@ static const struct snd_soc_dapm_route wsa_audio_map[] = { {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"}, {"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"}, + + {"WSA_RX INT1 VBAT", "WSA RX1 VBAT Enable", "WSA_RX INT1 INTERP"}, + {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 VBAT"}, + {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"}, {"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"}, {"WSA_SPK2 OUT", NULL, "WSA_MCLK"}, @@ -2006,6 +2339,53 @@ static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = { {BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x01, 0x01}, }; +static void wsa_macro_init_bcl_pmic_reg(struct snd_soc_codec *codec) +{ + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!codec) { + pr_err("%s: NULL codec pointer!\n", __func__); + return; + } + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return; + + switch (wsa_priv->bcl_pmic_params.id) { + case 0: + /* Enable ID0 to listen to respective PMIC group interrupts */ + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x02, 0x02); + /* Update MC_SID0 */ + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1, 0x0F, + wsa_priv->bcl_pmic_params.sid); + /* Update MC_PPID0 */ + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2, 0xFF, + wsa_priv->bcl_pmic_params.ppid); + break; + case 1: + /* Enable ID1 to listen to respective PMIC group interrupts */ + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x01, 0x01); + /* Update MC_SID1 */ + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3, 0x0F, + wsa_priv->bcl_pmic_params.sid); + /* Update MC_PPID1 */ + snd_soc_update_bits(codec, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4, 0xFF, + wsa_priv->bcl_pmic_params.ppid); + break; + default: + dev_err(wsa_dev, "%s: PMIC ID is invalid %d\n", + __func__, wsa_priv->bcl_pmic_params.id); + break; + } +} + static void wsa_macro_init_reg(struct snd_soc_codec *codec) { int i; @@ -2015,6 +2395,8 @@ static void wsa_macro_init_reg(struct snd_soc_codec *codec) wsa_macro_reg_init[i].reg, wsa_macro_reg_init[i].mask, wsa_macro_reg_init[i].val); + + wsa_macro_init_bcl_pmic_reg(codec); } static int wsa_swrm_clock(void *handle, bool enable) @@ -2245,6 +2627,7 @@ static int wsa_macro_probe(struct platform_device *pdev) char __iomem *wsa_io_base; int ret = 0; struct clk *wsa_core_clk, *wsa_npl_clk; + u8 bcl_pmic_params[3]; wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv), GFP_KERNEL); @@ -2300,6 +2683,19 @@ static int wsa_macro_probe(struct platform_device *pdev) return ret; } wsa_priv->wsa_npl_clk = wsa_npl_clk; + + ret = of_property_read_u8_array(pdev->dev.of_node, + "qcom,wsa-bcl-pmic-params", bcl_pmic_params, + sizeof(bcl_pmic_params)); + if (ret) { + dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "qcom,wsa-bcl-pmic-params"); + } else { + wsa_priv->bcl_pmic_params.id = bcl_pmic_params[0]; + wsa_priv->bcl_pmic_params.sid = bcl_pmic_params[1]; + wsa_priv->bcl_pmic_params.ppid = bcl_pmic_params[2]; + } + dev_set_drvdata(&pdev->dev, wsa_priv); mutex_init(&wsa_priv->mclk_lock); mutex_init(&wsa_priv->swr_clk_lock); -- GitLab From e5a1d4f094d04bb761872ecc0387a48de75c8dc1 Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Mon, 17 Sep 2018 11:36:25 +0530 Subject: [PATCH 0526/1645] asoc: sm6150: Add support for audio over display port Fix condition to register display port dai link as part of soundcard registration. CRs-Fixed: 2321275 Change-Id: I196163599299fa4aea21c930c0bfe3f8e5425223 Signed-off-by: Rohit kumar Signed-off-by: Aditya Bavanari --- asoc/sm6150.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 72181221ea1f..0128d52ceb22 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -7820,7 +7820,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) dev_dbg(dev, "%s: No DT match Ext Disp interface\n", __func__); } else { - if (auxpcm_audio_intf) { + if (ext_disp_audio_intf) { memcpy(msm_sm6150_dai_links + total_links, ext_disp_be_dai_link, sizeof(ext_disp_be_dai_link)); -- GitLab From 497a651ef8d1eadf63f70ab7e1799bc4f90a5c55 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 17 Sep 2018 16:11:52 +0530 Subject: [PATCH 0527/1645] asoc: codecs: Add parent child relation for bolero and tanggu In bolero and tanggu combination, make bolero parent of tanggu. Bolero and tanggu can communicate mutually using notifier and plat_data callback APIs. Change-Id: Iecd119df7f0ad1ba225c0427f3f42f217146b092 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc.c | 178 +++++++++++++++++++++++++-- asoc/codecs/bolero/bolero-cdc.h | 21 ++++ asoc/codecs/bolero/internal.h | 30 ++++- asoc/codecs/bolero/rx-macro.c | 209 +++++++++++++++++++++++++++++++- asoc/codecs/bolero/tx-macro.c | 24 +++- asoc/codecs/wcd937x/internal.h | 32 +++++ asoc/codecs/wcd937x/wcd937x.c | 112 ++++++++++++++++- 7 files changed, 586 insertions(+), 20 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 749f87b973c3..e9ccee430a56 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -26,6 +26,7 @@ #define BOLERO_VERSION_1_1 0x0002 #define BOLERO_VERSION_1_2 0x0003 #define BOLERO_VERSION_ENTRY_SIZE 32 +#define BOLERO_CDC_STRING_LEN 80 static struct snd_soc_codec_driver bolero; @@ -118,6 +119,65 @@ static int __bolero_reg_write(struct bolero_priv *priv, return ret; } +static int bolero_cdc_update_wcd_event(void *handle, u16 event, u32 data) +{ + struct bolero_priv *priv = (struct bolero_priv *)handle; + + if (!priv) { + pr_err("%s:Invalid bolero priv handle\n", __func__); + return -EINVAL; + } + + switch (event) { + case WCD_BOLERO_EVT_RX_MUTE: + if (priv->macro_params[RX_MACRO].event_handler) + priv->macro_params[RX_MACRO].event_handler(priv->codec, + BOLERO_MACRO_EVT_RX_MUTE, data); + break; + case WCD_BOLERO_EVT_IMPED_TRUE: + if (priv->macro_params[RX_MACRO].event_handler) + priv->macro_params[RX_MACRO].event_handler(priv->codec, + BOLERO_MACRO_EVT_IMPED_TRUE, data); + break; + case WCD_BOLERO_EVT_IMPED_FALSE: + if (priv->macro_params[RX_MACRO].event_handler) + priv->macro_params[RX_MACRO].event_handler(priv->codec, + BOLERO_MACRO_EVT_IMPED_FALSE, data); + break; + default: + dev_err(priv->dev, "%s: Invalid event %d trigger from wcd\n", + __func__, event); + return -EINVAL; + } + return 0; +} + +static int bolero_cdc_register_notifier(void *handle, + struct notifier_block *nblock, + bool enable) +{ + struct bolero_priv *priv = (struct bolero_priv *)handle; + + if (!priv) { + pr_err("%s: bolero priv is null\n", __func__); + return -EINVAL; + } + if (enable) + return blocking_notifier_chain_register(&priv->notifier, + nblock); + + return blocking_notifier_chain_unregister(&priv->notifier, + nblock); +} + +static void bolero_cdc_notifier_call(struct bolero_priv *priv, + u32 data) +{ + dev_dbg(priv->dev, "%s: notifier call, data:%d\n", __func__, data); + blocking_notifier_call_chain(&priv->notifier, + data, (void *)priv->wcd_dev); +} + static bool bolero_is_valid_macro_dev(struct device *dev) { if (of_device_is_compatible(dev->parent->of_node, "qcom,bolero-codec")) @@ -134,6 +194,46 @@ static bool bolero_is_valid_codec_dev(struct device *dev) return false; } +/** + * bolero_clear_amic_tx_hold - clears AMIC register on analog codec + * + * @dev: bolero device ptr. + * + */ +void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n) +{ + struct bolero_priv *priv; + u16 event; + u16 amic = 0; + + if (!dev) { + pr_err("%s: dev is null\n", __func__); + return; + } + + if (!bolero_is_valid_codec_dev(dev)) { + pr_err("%s: invalid codec\n", __func__); + return; + } + priv = dev_get_drvdata(dev); + if (!priv) { + dev_err(dev, "%s: priv is null\n", __func__); + return; + } + event = BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR; + if (adc_n == BOLERO_ADC0) + amic = 0x1; + else if (adc_n == BOLERO_ADC2) + amic = 0x2; + else if (adc_n == BOLERO_ADC3) + amic = 0x3; + else + return; + + bolero_cdc_notifier_call(priv, (amic << 0x10 | event)); +} +EXPORT_SYMBOL(bolero_clear_amic_tx_hold); + /** * bolero_get_device_ptr - Get child or macro device ptr * @@ -230,6 +330,7 @@ int bolero_register_macro(struct device *dev, u16 macro_id, priv->macro_params[macro_id].num_dais = ops->num_dais; priv->macro_params[macro_id].dai_ptr = ops->dai_ptr; priv->macro_params[macro_id].mclk_fn = ops->mclk_fn; + priv->macro_params[macro_id].event_handler = ops->event_handler; priv->macro_params[macro_id].dev = dev; priv->current_mclk_mux_macro[macro_id] = bolero_mclk_mux_tbl[macro_id][MCLK_MUX0]; @@ -237,7 +338,7 @@ int bolero_register_macro(struct device *dev, u16 macro_id, priv->num_macros_registered++; priv->macros_supported[macro_id] = true; - if (priv->num_macros_registered == priv->child_num) { + if (priv->num_macros_registered == priv->num_macros) { ret = bolero_copy_dais_from_macro(priv); if (ret < 0) { dev_err(dev, "%s: copy_dais failed\n", __func__); @@ -290,12 +391,13 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) priv->macro_params[macro_id].num_dais = 0; priv->macro_params[macro_id].dai_ptr = NULL; priv->macro_params[macro_id].mclk_fn = NULL; + priv->macro_params[macro_id].event_handler = NULL; priv->macro_params[macro_id].dev = NULL; priv->num_dais -= priv->macro_params[macro_id].num_dais; priv->num_macros_registered--; /* UNREGISTER CODEC HERE */ - if (priv->child_num - 1 == priv->num_macros_registered) + if (priv->num_macros - 1 == priv->num_macros_registered) snd_soc_unregister_codec(dev->parent); } EXPORT_SYMBOL(bolero_unregister_macro); @@ -555,7 +657,12 @@ static struct snd_soc_codec_driver bolero = { static void bolero_add_child_devices(struct work_struct *work) { struct bolero_priv *priv; - int rc; + bool wcd937x_node = false; + struct platform_device *pdev; + struct device_node *node; + int ret = 0, count = 0; + struct wcd_ctrl_platform_data *platdata = NULL; + char plat_dev_name[BOLERO_CDC_STRING_LEN] = ""; priv = container_of(work, struct bolero_priv, bolero_add_child_devices_work); @@ -569,12 +676,53 @@ static void bolero_add_child_devices(struct work_struct *work) __func__); return; } - rc = of_platform_populate(priv->dev->of_node, NULL, NULL, priv->dev); - if (rc) - dev_err(priv->dev, "%s: failed to add child nodes, rc=%d\n", - __func__, rc); - else - dev_dbg(priv->dev, "%s: added child node\n", __func__); + + platdata = &priv->plat_data; + priv->child_count = 0; + + for_each_available_child_of_node(priv->dev->of_node, node) { + wcd937x_node = false; + if (strnstr(node->name, "wcd937x", strlen("wcd937x")) != NULL) + wcd937x_node = true; + + strlcpy(plat_dev_name, node->name, + (BOLERO_CDC_STRING_LEN - 1)); + + pdev = platform_device_alloc(plat_dev_name, -1); + if (!pdev) { + dev_err(priv->dev, "%s: pdev memory alloc failed\n", + __func__); + ret = -ENOMEM; + goto err; + } + pdev->dev.parent = priv->dev; + pdev->dev.of_node = node; + + if (wcd937x_node) { + priv->dev->platform_data = platdata; + priv->wcd_dev = &pdev->dev; + } + + ret = platform_device_add(pdev); + if (ret) { + dev_err(&pdev->dev, + "%s: Cannot add platform device\n", + __func__); + platform_device_put(pdev); + goto fail_pdev_add; + } + + if (priv->child_count < BOLERO_CDC_CHILD_DEVICES_MAX) + priv->pdev_child_devices[priv->child_count++] = pdev; + else + goto err; + } + return; +fail_pdev_add: + for (count = 0; count < priv->child_count; count++) + platform_device_put(priv->pdev_child_devices[count]); +err: + return; } static int bolero_probe(struct platform_device *pdev) @@ -595,11 +743,11 @@ static int bolero_probe(struct platform_device *pdev) __func__); return ret; } - priv->child_num = num_macros; - if (priv->child_num > MAX_MACRO) { + priv->num_macros = num_macros; + if (priv->num_macros > MAX_MACRO) { dev_err(&pdev->dev, - "%s:child_num(%d) > MAX_MACRO(%d) than supported\n", - __func__, priv->child_num, MAX_MACRO); + "%s:num_macros(%d) > MAX_MACRO(%d) than supported\n", + __func__, priv->num_macros, MAX_MACRO); return -EINVAL; } priv->va_without_decimation = of_property_read_bool(pdev->dev.of_node, @@ -617,6 +765,10 @@ static int bolero_probe(struct platform_device *pdev) priv->read_dev = __bolero_reg_read; priv->write_dev = __bolero_reg_write; + priv->plat_data.handle = (void *) priv; + priv->plat_data.update_wcd_event = bolero_cdc_update_wcd_event; + priv->plat_data.register_notifier = bolero_cdc_register_notifier; + dev_set_drvdata(&pdev->dev, priv); mutex_init(&priv->io_lock); mutex_init(&priv->clk_lock); diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index f7e95eeae2f9..3e8197d58ee2 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -31,6 +31,20 @@ enum mclk_mux { MCLK_MUX_MAX }; +enum { + BOLERO_ADC0 = 1, + BOLERO_ADC1, + BOLERO_ADC2, + BOLERO_ADC3, + BOLERO_ADC_MAX +}; + +enum { + BOLERO_MACRO_EVT_RX_MUTE = 1, /* for RX mute/unmute */ + BOLERO_MACRO_EVT_IMPED_TRUE, /* for imped true */ + BOLERO_MACRO_EVT_IMPED_FALSE, /* for imped false */ +}; + struct macro_ops { int (*init)(struct snd_soc_codec *codec); int (*exit)(struct snd_soc_codec *codec); @@ -38,6 +52,8 @@ struct macro_ops { struct device *dev; struct snd_soc_dai_driver *dai_ptr; int (*mclk_fn)(struct device *dev, bool enable); + int (*event_handler)(struct snd_soc_codec *codec, u16 event, + u32 data); char __iomem *io_base; }; @@ -52,6 +68,7 @@ int bolero_request_clock(struct device *dev, u16 macro_id, int bolero_info_create_codec_entry( struct snd_info_entry *codec_root, struct snd_soc_codec *codec); +void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n); #else static inline int bolero_register_macro(struct device *dev, u16 macro_id, @@ -83,5 +100,9 @@ static int bolero_info_create_codec_entry( { return 0; } + +static inline void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n) +{ +} #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 2979ee066972..9e8a74c5e34f 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -15,6 +15,13 @@ #include "bolero-cdc-registers.h" +#define BOLERO_CDC_CHILD_DEVICES_MAX 5 + +/* from bolero to WCD events */ +enum { + BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1, +}; + enum { REG_NO_ACCESS, RD_REG, @@ -22,6 +29,21 @@ enum { RD_WR_REG }; +/* from WCD to bolero events */ +enum { + WCD_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */ + WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */ + WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */ +}; + +struct wcd_ctrl_platform_data { + void *handle; + int (*update_wcd_event)(void *handle, u16 event, u32 data); + int (*register_notifier)(void *handle, + struct notifier_block *nblock, + bool enable); +}; + struct bolero_priv { struct device *dev; struct snd_soc_codec *codec; @@ -34,7 +56,7 @@ struct bolero_priv { struct snd_soc_dai_driver *bolero_dais; u16 num_dais; u16 num_macros_registered; - u16 child_num; + u16 num_macros; u16 current_mclk_mux_macro[MAX_MACRO]; struct work_struct bolero_add_child_devices_work; u32 version; @@ -47,6 +69,12 @@ struct bolero_priv { u16 macro_id, u16 reg, u8 *val); int (*write_dev)(struct bolero_priv *priv, u16 macro_id, u16 reg, u8 val); + struct platform_device *pdev_child_devices + [BOLERO_CDC_CHILD_DEVICES_MAX]; + u16 child_count; + struct wcd_ctrl_platform_data plat_data; + struct device *wcd_dev; + struct blocking_notifier_head notifier; }; struct regmap *bolero_regmap_init(struct device *dev, diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 62c4a371cf4c..a0e189b5d5df 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -75,6 +75,107 @@ static const struct snd_kcontrol_new name##_mux = \ #define RX_MACRO_RX_PATH_OFFSET 0x80 #define RX_MACRO_COMP_OFFSET 0x40 +#define MAX_IMPED_PARAMS 6 + +struct wcd_imped_val { + u32 imped_val; + u8 index; +}; + +static const struct wcd_imped_val imped_index[] = { + {4, 0}, + {5, 1}, + {6, 2}, + {7, 3}, + {8, 4}, + {9, 5}, + {10, 6}, + {11, 7}, + {12, 8}, + {13, 9}, +}; + +struct rx_macro_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + +static const struct rx_macro_reg_mask_val imped_table[][MAX_IMPED_PARAMS] = { + { + {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf2}, + {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf2}, + {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00}, + {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf2}, + {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf2}, + {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf4}, + {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf4}, + {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00}, + {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf4}, + {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf4}, + {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf7}, + {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf7}, + {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x01}, + {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf7}, + {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf7}, + {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x01}, + }, + { + {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf9}, + {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf9}, + {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00}, + {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf9}, + {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf9}, + {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfa}, + {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfa}, + {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00}, + {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfa}, + {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfa}, + {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfb}, + {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfb}, + {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00}, + {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfb}, + {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfb}, + {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfc}, + {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfc}, + {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00}, + {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfc}, + {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfc}, + {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfd}, + {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00}, + {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfd}, + {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00}, + }, + { + {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfd}, + {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x01}, + {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfd}, + {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd}, + {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x01}, + }, +}; + enum { INTERP_HPHL, INTERP_HPHR, @@ -494,6 +595,80 @@ static struct snd_soc_dai_driver rx_macro_dai[] = { }, }; +static int get_impedance_index(int imped) +{ + int i = 0; + + if (imped < imped_index[i].imped_val) { + pr_debug("%s, detected impedance is less than %d Ohm\n", + __func__, imped_index[i].imped_val); + i = 0; + goto ret; + } + if (imped >= imped_index[ARRAY_SIZE(imped_index) - 1].imped_val) { + pr_debug("%s, detected impedance is greater than %d Ohm\n", + __func__, + imped_index[ARRAY_SIZE(imped_index) - 1].imped_val); + i = ARRAY_SIZE(imped_index) - 1; + goto ret; + } + for (i = 0; i < ARRAY_SIZE(imped_index) - 1; i++) { + if (imped >= imped_index[i].imped_val && + imped < imped_index[i + 1].imped_val) + break; + } +ret: + pr_debug("%s: selected impedance index = %d\n", + __func__, imped_index[i].index); + return imped_index[i].index; +} + +/* + * rx_macro_wcd_clsh_imped_config - + * This function updates HPHL and HPHR gain settings + * according to the impedance value. + * + * @codec: codec pointer handle + * @imped: impedance value of HPHL/R + * @reset: bool variable to reset registers when teardown + */ +static void rx_macro_wcd_clsh_imped_config(struct snd_soc_codec *codec, + int imped, bool reset) +{ + int i; + int index = 0; + int table_size; + + static const struct rx_macro_reg_mask_val + (*imped_table_ptr)[MAX_IMPED_PARAMS]; + + table_size = ARRAY_SIZE(imped_table); + imped_table_ptr = imped_table; + /* reset = 1, which means request is to reset the register values */ + if (reset) { + for (i = 0; i < MAX_IMPED_PARAMS; i++) + snd_soc_update_bits(codec, + imped_table_ptr[index][i].reg, + imped_table_ptr[index][i].mask, 0); + return; + } + index = get_impedance_index(imped); + if (index >= (ARRAY_SIZE(imped_index) - 1)) { + pr_debug("%s, impedance not in range = %d\n", __func__, imped); + return; + } + if (index >= table_size) { + pr_debug("%s, impedance index not in range = %d\n", __func__, + index); + return; + } + for (i = 0; i < MAX_IMPED_PARAMS; i++) + snd_soc_update_bits(codec, + imped_table_ptr[index][i].reg, + imped_table_ptr[index][i].mask, + imped_table_ptr[index][i].val); +} + static bool rx_macro_get_data(struct snd_soc_codec *codec, struct device **rx_dev, struct rx_macro_priv **rx_priv, @@ -928,6 +1103,37 @@ static int rx_macro_mclk_ctrl(struct device *dev, bool enable) return 0; } +static int rx_macro_event_handler(struct snd_soc_codec *codec, u16 event, + u32 data) +{ + u16 reg = 0, reg_mix = 0, rx_idx = 0, mute = 0x0; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + switch (event) { + case BOLERO_MACRO_EVT_RX_MUTE: + rx_idx = data >> 0x10; + mute = data & 0xffff; + reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + (rx_idx * + RX_MACRO_RX_PATH_OFFSET); + reg_mix = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL + (rx_idx * + RX_MACRO_RX_PATH_OFFSET); + snd_soc_update_bits(codec, reg, 0x10, mute << 0x10); + snd_soc_update_bits(codec, reg_mix, 0x10, mute << 0x10); + break; + case BOLERO_MACRO_EVT_IMPED_TRUE: + rx_macro_wcd_clsh_imped_config(codec, data, true); + break; + case BOLERO_MACRO_EVT_IMPED_FALSE: + rx_macro_wcd_clsh_imped_config(codec, data, false); + break; + } + return 0; +} + static int rx_macro_find_playback_dai_id_for_port(int port_id, struct rx_macro_priv *rx_priv) { @@ -1078,7 +1284,6 @@ static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: snd_soc_write(codec, gain_reg, snd_soc_read(codec, gain_reg)); - snd_soc_update_bits(codec, mix_reg, 0x10, 0x00); break; case SND_SOC_DAPM_POST_PMD: /* Clk Disable */ @@ -1128,7 +1333,6 @@ static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: snd_soc_write(codec, gain_reg, snd_soc_read(codec, gain_reg)); - snd_soc_update_bits(codec, reg, 0x10, 0x00); break; case SND_SOC_DAPM_POST_PMD: rx_macro_enable_interp_clk(codec, event, w->shift); @@ -2955,6 +3159,7 @@ static void rx_macro_init_ops(struct macro_ops *ops, char __iomem *rx_io_base) ops->dai_ptr = rx_macro_dai; ops->num_dais = ARRAY_SIZE(rx_macro_dai); ops->mclk_fn = rx_macro_mclk_ctrl; + ops->event_handler = rx_macro_event_handler; } static int rx_macro_probe(struct platform_device *pdev) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 76d424be6bc1..9cfd94d6b6d6 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -42,6 +42,8 @@ #define TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED 0 #define TX_MACRO_MCLK_FREQ 9600000 #define TX_MACRO_TX_PATH_OFFSET 0x80 +#define TX_MACRO_SWR_MIC_MUX_SEL_MASK 0xF +#define TX_MACRO_ADC_MUX_CFG_OFFSET 0x2 #define TX_MACRO_TX_UNMUTE_DELAY_MS 40 @@ -107,6 +109,12 @@ enum { TX_MACRO_CLK_DIV_16, }; +enum { + MSM_DMIC, + SWR_MIC, + ANC_FB_TUNE1 +}; + struct tx_mute_work { struct tx_macro_priv *tx_priv; u32 decimator; @@ -303,6 +311,7 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) struct snd_soc_codec *codec = NULL; u16 dec_cfg_reg = 0, hpf_gate_reg = 0; u8 hpf_cut_off_freq = 0; + u16 adc_mux_reg = 0, adc_n = 0, adc_reg = 0; hpf_delayed_work = to_delayed_work(work); hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); @@ -318,6 +327,19 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", __func__, hpf_work->decimator, hpf_cut_off_freq); + adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + + TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator; + if (snd_soc_read(codec, adc_mux_reg) & SWR_MIC) { + adc_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + + TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator; + adc_n = snd_soc_read(codec, adc_reg) & + TX_MACRO_SWR_MIC_MUX_SEL_MASK; + if (adc_n >= BOLERO_ADC_MAX) + goto tx_hpf_set; + /* analog mic clear TX hold */ + bolero_clear_amic_tx_hold(codec->dev, adc_n); + } +tx_hpf_set: snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, hpf_cut_off_freq << 5); snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); @@ -399,7 +421,7 @@ static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol, __func__, e->reg); return -EINVAL; } - if (strnstr(widget->name, "smic", strlen(widget->name))) { + if (strnstr(widget->name, "SMIC", strlen(widget->name))) { if (val != 0) { if (val < 5) snd_soc_update_bits(codec, mic_sel_reg, diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index e2f1e03b3487..0818c05eb65f 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -74,6 +74,14 @@ struct wcd937x_priv { rx_port_mapping[MAX_PORT][MAX_CH_PER_PORT]; struct regulator_bulk_data *supplies; + struct notifier_block nblock; + /* wcd callback to bolero */ + void *handle; + int (*update_wcd_event)(void *handle, u16 event, u32 data); + int (*register_notifier)(void *handle, + struct notifier_block *nblock, + bool enable); + u32 version; /* Entry for version info */ struct snd_info_entry *entry; @@ -99,6 +107,30 @@ struct wcd937x_pdata { int num_supplies; }; +struct wcd_ctrl_platform_data { + void *handle; + int (*update_wcd_event)(void *handle, u16 event, u32 data); + int (*register_notifier)(void *handle, + struct notifier_block *nblock, + bool enable); +}; + +enum { + WCD_RX1, + WCD_RX2, + WCD_RX3 +}; + +enum { + BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1, +}; + +enum { + WCD_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */ + WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */ + WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */ +}; + enum { /* INTR_CTRL_INT_MASK_0 */ WCD937X_IRQ_MBHC_BUTTON_RELEASE_DET = 0, diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 2d7f40a3ff74..b599b1f3270d 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -568,8 +568,16 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, true); + if (wcd937x->update_wcd_event) + wcd937x->update_wcd_event(wcd937x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX2 << 0x10)); break; case SND_SOC_DAPM_PRE_PMD: + if (wcd937x->update_wcd_event) + wcd937x->update_wcd_event(wcd937x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX2 << 0x10 | 0x1)); blocking_notifier_call_chain(&wcd937x->mbhc->notifier, WCD_EVENT_PRE_HPHR_PA_OFF, &wcd937x->mbhc->wcd_mbhc); @@ -607,8 +615,16 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, true); + if (wcd937x->update_wcd_event) + wcd937x->update_wcd_event(wcd937x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10)); break; case SND_SOC_DAPM_PRE_PMD: + if (wcd937x->update_wcd_event) + wcd937x->update_wcd_event(wcd937x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10 | 0x1)); blocking_notifier_call_chain(&wcd937x->mbhc->notifier, WCD_EVENT_PRE_HPHL_PA_OFF, &wcd937x->mbhc->wcd_mbhc); @@ -650,6 +666,16 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, true); + if (wcd937x->update_wcd_event) + wcd937x->update_wcd_event(wcd937x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX3 << 0x10)); + break; + case SND_SOC_DAPM_PRE_PMD: + if (wcd937x->update_wcd_event) + wcd937x->update_wcd_event(wcd937x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX3 << 0x10 | 0x1)); break; case SND_SOC_DAPM_POST_PMD: usleep_range(1000, 1010); @@ -685,6 +711,16 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, true); + if (wcd937x->update_wcd_event) + wcd937x->update_wcd_event(wcd937x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10)); + break; + case SND_SOC_DAPM_PRE_PMD: + if (wcd937x->update_wcd_event) + wcd937x->update_wcd_event(wcd937x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10 | 0x1)); break; case SND_SOC_DAPM_POST_PMD: usleep_range(7000, 7010); @@ -1180,6 +1216,35 @@ int wcd937x_micbias_control(struct snd_soc_codec *codec, } EXPORT_SYMBOL(wcd937x_micbias_control); +static int wcd937x_event_notify(struct notifier_block *block, + unsigned long val, + void *data) +{ + u16 event = (val & 0xffff); + u16 amic = (val >> 0x10); + u16 mask = 0x40, reg = 0x0; + struct wcd937x_priv *wcd937x = dev_get_drvdata((struct device *)data); + struct snd_soc_codec *codec = wcd937x->codec; + + switch (event) { + case BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR: + if (amic == 0x1 || amic == 0x2) + reg = WCD937X_ANA_TX_CH2; + else if (amic == 0x3) + reg = WCD937X_ANA_TX_CH3_HPF; + else + return 0; + if (amic == 0x2) + mask = 0x20; + snd_soc_update_bits(codec, reg, mask, 0x00); + break; + default: + dev_err(codec->dev, "%s: invalid event %d\n", __func__, event); + break; + } + return 0; +} + static int __wcd937x_codec_enable_micbias(struct snd_soc_dapm_widget *w, int event) { @@ -1443,11 +1508,11 @@ static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = { SND_SOC_DAPM_PGA_E("EAR PGA", WCD937X_ANA_EAR, 7, 0, NULL, 0, wcd937x_codec_enable_ear_pa, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PGA_E("AUX PGA", WCD937X_AUX_AUXPA, 7, 0, NULL, 0, wcd937x_codec_enable_aux_pa, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PGA_E("HPHL PGA", WCD937X_ANA_HPH, 7, 0, NULL, 0, wcd937x_codec_enable_hphl_pa, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | @@ -1754,7 +1819,6 @@ static int wcd937x_soc_codec_probe(struct snd_soc_codec *codec) return -EINVAL; wcd937x->codec = codec; - variant = (snd_soc_read(codec, WCD937X_DIGITAL_EFUSE_REG_0) & 0x0E) >> 1; wcd937x->variant = variant; @@ -1802,6 +1866,19 @@ static int wcd937x_soc_codec_probe(struct snd_soc_codec *codec) snd_soc_dapm_sync(dapm); } wcd937x->version = WCD937X_VERSION_1_0; + /* Register event notifier */ + wcd937x->nblock.notifier_call = wcd937x_event_notify; + if (wcd937x->register_notifier) { + ret = wcd937x->register_notifier(wcd937x->handle, + &wcd937x->nblock, + true); + if (ret) { + dev_err(codec->dev, + "%s: Failed to register notifier %d\n", + __func__, ret); + return ret; + } + } return ret; err_hwdep: @@ -1818,6 +1895,10 @@ static int wcd937x_soc_codec_remove(struct snd_soc_codec *codec) if (!wcd937x) return -EINVAL; + if (wcd937x->register_notifier) + return wcd937x->register_notifier(wcd937x->handle, + &wcd937x->nblock, + false); return 0; } @@ -1985,6 +2066,7 @@ static int wcd937x_bind(struct device *dev) int ret = 0, i = 0; struct wcd937x_priv *wcd937x = NULL; struct wcd937x_pdata *pdata = NULL; + struct wcd_ctrl_platform_data *plat_data = NULL; wcd937x = devm_kzalloc(dev, sizeof(struct wcd937x_priv), GFP_KERNEL); if (!wcd937x) @@ -2008,6 +2090,30 @@ static int wcd937x_bind(struct device *dev) return ret; } + plat_data = dev_get_platdata(dev->parent); + if (!plat_data) { + dev_err(dev, "%s: platform data from parent is NULL\n", + __func__); + return -EINVAL; + } + wcd937x->handle = (void *)plat_data->handle; + if (!wcd937x->handle) { + dev_err(dev, "%s: handle is NULL\n", __func__); + return -EINVAL; + } + wcd937x->update_wcd_event = plat_data->update_wcd_event; + if (!wcd937x->update_wcd_event) { + dev_err(dev, "%s: update_wcd_event api is null!\n", + __func__); + return -EINVAL; + } + wcd937x->register_notifier = plat_data->register_notifier; + if (!wcd937x->register_notifier) { + dev_err(dev, "%s: register_notifier api is null!\n", + __func__); + return -EINVAL; + } + ret = msm_cdc_enable_static_supplies(dev, wcd937x->supplies, pdata->regulator, pdata->num_supplies); -- GitLab From 7cb4ff6b651f11d344e2bc96d9b06e0342d6f166 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 12 Sep 2018 04:00:26 +0530 Subject: [PATCH 0528/1645] soc: swr-mstr: Use single pm runtime call during port enable Add changes to call pm runtime calls only once for soundwire master active, to be able to decrement and put to suspend during SSR. Change-Id: I068040e2a224d1ee97f472f69f25af77ae632be2 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index d3fb08769850..15e3511edb98 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -921,8 +921,6 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) } mutex_lock(&swrm->mlock); - if (enable) - pm_runtime_get_sync(swrm->dev); bank = get_inactive_bank_num(swrm); if (enable) { @@ -983,6 +981,8 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) else { swrm_disable_ports(master, inactive_bank); swrm_cleanup_disabled_port_reqs(master); + } + if (!swrm_is_port_en(master)) { dev_dbg(&master->dev, "%s: pm_runtime auto suspend triggered\n", __func__); pm_runtime_mark_last_busy(swrm->dev); @@ -1014,6 +1014,8 @@ static int swrm_connect_port(struct swr_master *master, } mutex_lock(&swrm->mlock); + if (!swrm_is_port_en(master)) + pm_runtime_get_sync(swrm->dev); for (i = 0; i < portinfo->num_port; i++) { ret = swrm_get_master_port(swrm, &mstr_port_id, &mstr_ch_msk, -- GitLab From 1df09a82e59e5c00a2a59486de525a4752a838de Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 20 Sep 2018 18:57:49 +0530 Subject: [PATCH 0529/1645] soc: add SSR changes for swr mstr controller Add changes to recover audio during SSR and PDR in swr master controller driver. Change-Id: Ibe3ae097b5f9d59b135d861c5f50f6bbc1c05af6 Signed-off-by: Rohit kumar Signed-off-by: Laxminath Kasam --- include/soc/swr-wcd.h | 2 ++ soc/swr-mstr-ctrl.c | 84 +++++++++++++++++++++++++++++++++---------- soc/swr-mstr-ctrl.h | 3 ++ 3 files changed, 71 insertions(+), 18 deletions(-) diff --git a/include/soc/swr-wcd.h b/include/soc/swr-wcd.h index 75d0e6512267..8ea8616572a4 100644 --- a/include/soc/swr-wcd.h +++ b/include/soc/swr-wcd.h @@ -24,6 +24,8 @@ enum { SWR_SUBSYS_RESTART, SWR_SET_NUM_RX_CH, SWR_CLK_FREQ, + SWR_DEVICE_SSR_DOWN, + SWR_DEVICE_SSR_UP, }; struct swr_mstr_port { diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 15e3511edb98..7232fe83caa8 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -248,35 +248,47 @@ static int swrm_ahb_write(struct swr_mstr_ctrl *swrm, u16 reg, u32 *value) { u32 temp = (u32)(*value); - int ret; - - ret = swrm_clk_request(swrm, TRUE); + int ret = 0; - if (ret) - return -EINVAL; + mutex_lock(&swrm->devlock); + if (!swrm->dev_up) + goto err; + ret = swrm_clk_request(swrm, TRUE); + if (ret) { + dev_err_ratelimited(swrm->dev, "%s: clock request failed\n", + __func__); + goto err; + } iowrite32(temp, swrm->swrm_dig_base + reg); - swrm_clk_request(swrm, FALSE); - - return 0; +err: + mutex_unlock(&swrm->devlock); + return ret; } static int swrm_ahb_read(struct swr_mstr_ctrl *swrm, u16 reg, u32 *value) { u32 temp = 0; - int ret; - - ret = swrm_clk_request(swrm, TRUE); + int ret = 0; - if (ret) - return -EINVAL; + mutex_lock(&swrm->devlock); + if (!swrm->dev_up) + goto err; + ret = swrm_clk_request(swrm, TRUE); + if (ret) { + dev_err_ratelimited(swrm->dev, "%s: clock request failed\n", + __func__); + goto err; + } temp = ioread32(swrm->swrm_dig_base + reg); *value = temp; swrm_clk_request(swrm, FALSE); - return 0; +err: + mutex_unlock(&swrm->devlock); + return ret; } static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr) @@ -501,6 +513,13 @@ static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr, dev_err(&master->dev, "%s: swrm is NULL\n", __func__); return -EINVAL; } + mutex_lock(&swrm->devlock); + if (!swrm->dev_up) { + mutex_unlock(&swrm->devlock); + return 0; + } + mutex_unlock(&swrm->devlock); + pm_runtime_get_sync(swrm->dev); if (dev_num) ret = swrm_cmd_fifo_rd_cmd(swrm, &val, dev_num, 0, reg_addr, @@ -527,6 +546,12 @@ static int swrm_write(struct swr_master *master, u8 dev_num, u16 reg_addr, dev_err(&master->dev, "%s: swrm is NULL\n", __func__); return -EINVAL; } + mutex_lock(&swrm->devlock); + if (!swrm->dev_up) { + mutex_unlock(&swrm->devlock); + return 0; + } + mutex_unlock(&swrm->devlock); pm_runtime_get_sync(swrm->dev); if (dev_num) @@ -554,6 +579,12 @@ static int swrm_bulk_write(struct swr_master *master, u8 dev_num, void *reg, } if (len <= 0) return -EINVAL; + mutex_lock(&swrm->devlock); + if (!swrm->dev_up) { + mutex_unlock(&swrm->devlock); + return 0; + } + mutex_unlock(&swrm->devlock); pm_runtime_get_sync(swrm->dev); if (dev_num) { @@ -1641,6 +1672,7 @@ static int swrm_probe(struct platform_device *pdev) swrm->num_rx_chs = 0; swrm->clk_ref_count = 0; swrm->mclk_freq = MCLK_FREQ; + swrm->dev_up = true; swrm->state = SWR_MSTR_RESUME; init_completion(&swrm->reset); init_completion(&swrm->broadcast); @@ -1648,6 +1680,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_init(&swrm->reslock); mutex_init(&swrm->force_down_lock); mutex_init(&swrm->iolock); + mutex_init(&swrm->devlock); for (i = 0 ; i < SWR_MSTR_PORT_LEN; i++) INIT_LIST_HEAD(&swrm->mport_cfg[i].port_req_list); @@ -1918,11 +1951,16 @@ static int swrm_device_down(struct device *dev) mutex_lock(&swrm->force_down_lock); swrm->state = SWR_MSTR_SSR; mutex_unlock(&swrm->force_down_lock); - /* Use pm runtime function to tear down */ - ret = pm_runtime_put_sync_suspend(dev); - pm_runtime_get_noresume(dev); + if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) { + ret = swrm_runtime_suspend(dev); + if (!ret) { + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + pm_runtime_enable(dev); + } + } - return ret; + return 0; } /** @@ -1961,6 +1999,16 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) mutex_unlock(&swrm->mlock); } break; + case SWR_DEVICE_SSR_DOWN: + mutex_lock(&swrm->devlock); + swrm->dev_up = false; + mutex_unlock(&swrm->devlock); + break; + case SWR_DEVICE_SSR_UP: + mutex_lock(&swrm->devlock); + swrm->dev_up = true; + mutex_unlock(&swrm->devlock); + break; case SWR_DEVICE_DOWN: dev_dbg(swrm->dev, "%s: swr master down called\n", __func__); mutex_lock(&swrm->mlock); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index b3dfd7d3a3d1..862596651df4 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -113,6 +113,7 @@ struct swr_mstr_ctrl { struct completion reset; struct completion broadcast; struct mutex iolock; + struct mutex devlock; struct mutex mlock; struct mutex reslock; u32 swrm_base_reg; @@ -149,6 +150,8 @@ struct swr_mstr_ctrl { u32 clk_stop_mode0_supp; struct work_struct wakeup_work; u32 wakeup_req; + + bool dev_up; }; #endif /* _SWR_WCD_CTRL_H */ -- GitLab From d7262ae1e01def48367c5d58722651f03321533d Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 24 Sep 2018 17:54:58 +0530 Subject: [PATCH 0530/1645] asoc: wcd934x: add SSR events to trigger to new swr master controller For new swr master controller to recover WSA on wcd934x variant, trigger events from wcd934x driver for ssr down and up. Change-Id: I8f0163178708760ef3ad2a765a80682611693e9b Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd934x/wcd934x.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 36676767fb90..2a6d829f2443 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -10010,9 +10010,13 @@ static int tavil_device_down(struct wcd9xxx *wcd9xxx) (&priv->mbhc->wcd_mbhc, false); } - if (priv->swr.ctrl_data) + if (priv->swr.ctrl_data) { + if (is_snd_event_fwk_enabled()) + swrm_wcd_notify(priv->swr.ctrl_data[0].swr_pdev, + SWR_DEVICE_SSR_DOWN, NULL); swrm_wcd_notify(priv->swr.ctrl_data[0].swr_pdev, SWR_DEVICE_DOWN, NULL); + } tavil_dsd_reset(priv->dsd_config); if (!is_snd_event_fwk_enabled()) snd_soc_card_change_online_state(codec->component.card, 0); @@ -10110,6 +10114,9 @@ static int tavil_post_reset_cb(struct wcd9xxx *wcd9xxx) goto done; } + if (tavil->swr.ctrl_data && is_snd_event_fwk_enabled()) + swrm_wcd_notify(tavil->swr.ctrl_data[0].swr_pdev, + SWR_DEVICE_SSR_UP, NULL); tavil_set_spkr_mode(codec, tavil->swr.spkr_mode); /* * Once the codec initialization is completed, the svs vote -- GitLab From 27b1bbc54b6be45a2b59c32c86537f990ca1f704 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Sat, 22 Sep 2018 01:39:56 +0530 Subject: [PATCH 0531/1645] soc: pinctrl-lpi: add SSR changes based on snd event fwk Add changes to support SSR in pinctrl lpi driver based on snd event framework. Change-Id: If4fb3085ab69ae04628ef10a8b528d0cdc20f40d Signed-off-by: Laxminath Kasam --- soc/pinctrl-lpi.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index f5ba3d64ad67..21d51fb0ee22 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "core.h" @@ -59,6 +60,7 @@ #define LPI_GPIO_FUNC_FUNC5 "func5" static bool lpi_dev_up; +static struct device *lpi_dev; /* The index of each function in lpi_gpio_functions[] array */ enum lpi_gpio_func_index { @@ -384,12 +386,14 @@ static int lpi_notifier_service_cb(struct notifier_block *this, initial_boot = false; break; } + snd_event_notify(lpi_dev, SND_EVENT_DOWN); lpi_dev_up = false; break; case AUDIO_NOTIFIER_SERVICE_UP: if (initial_boot) initial_boot = false; lpi_dev_up = true; + snd_event_notify(lpi_dev, SND_EVENT_UP); break; default: break; @@ -402,6 +406,15 @@ static struct notifier_block service_nb = { .priority = -INT_MAX, }; +static void lpi_pinctrl_ssr_disable(struct device *dev, void *data) +{ + lpi_dev_up = false; +} + +static const struct snd_event_ops lpi_pinctrl_ssr_ops = { + .disable = lpi_pinctrl_ssr_disable, +}; + #ifdef CONFIG_DEBUG_FS #include @@ -576,6 +589,7 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) goto err_range; } + lpi_dev = &pdev->dev; lpi_dev_up = true; ret = audio_notifier_register("lpi_tlmm", AUDIO_NOTIFIER_ADSP_DOMAIN, &service_nb); @@ -585,8 +599,19 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) goto err_range; } + ret = snd_event_client_register(dev, &lpi_pinctrl_ssr_ops, NULL); + if (!ret) { + snd_event_notify(dev, SND_EVENT_UP); + } else { + dev_err(dev, "%s: snd_event registration failed, ret [%d]\n", + __func__, ret); + goto err_snd_evt; + } + return 0; +err_snd_evt: + audio_notifier_deregister("lpi_tlmm"); err_range: gpiochip_remove(&state->chip); err_chip: @@ -597,6 +622,7 @@ static int lpi_pinctrl_remove(struct platform_device *pdev) { struct lpi_gpio_state *state = platform_get_drvdata(pdev); + snd_event_client_deregister(&pdev->dev); audio_notifier_deregister("lpi_tlmm"); gpiochip_remove(&state->chip); return 0; -- GitLab From fb0d683b3788f25782949b25bae8a294c12e3b37 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Sat, 22 Sep 2018 01:49:52 +0530 Subject: [PATCH 0532/1645] asoc: bolero: add SSR changes support on bolero codec Add changes for audio SSR and PDR on bolero codec and respective macro drivers. Change-Id: I146de15022cebb788ccb52ed6b8ab85b7cba2ba0 Signed-off-by: Vaishnavi Kommaraju Signed-off-by: Rohit kumar Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc.c | 79 ++++++++++++++++++++++++++++++++- asoc/codecs/bolero/bolero-cdc.h | 3 ++ asoc/codecs/bolero/internal.h | 4 ++ asoc/codecs/bolero/rx-macro.c | 13 ++++++ asoc/codecs/bolero/tx-macro.c | 29 ++++++++++++ asoc/codecs/bolero/va-macro.c | 44 ++++++++++++++++-- asoc/codecs/bolero/wsa-macro.c | 28 ++++++++++++ 7 files changed, 195 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index e9ccee430a56..5001b7f26be3 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -18,7 +18,7 @@ #include #include #include - +#include #include "bolero-cdc.h" #include "internal.h" @@ -62,6 +62,11 @@ static int __bolero_reg_read(struct bolero_priv *priv, u16 current_mclk_mux_macro; mutex_lock(&priv->clk_lock); + if (!priv->dev_up) { + dev_dbg_ratelimited(priv->dev, + "%s: SSR in progress, exit\n", __func__); + goto err; + } current_mclk_mux_macro = priv->current_mclk_mux_macro[macro_id]; if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) { @@ -94,6 +99,11 @@ static int __bolero_reg_write(struct bolero_priv *priv, u16 current_mclk_mux_macro; mutex_lock(&priv->clk_lock); + if (!priv->dev_up) { + dev_dbg_ratelimited(priv->dev, + "%s: SSR in progress, exit\n", __func__); + goto err; + } current_mclk_mux_macro = priv->current_mclk_mux_macro[macro_id]; if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) { @@ -529,10 +539,64 @@ static ssize_t bolero_version_read(struct snd_info_entry *entry, return simple_read_from_buffer(buf, count, &pos, buffer, len); } +static int bolero_ssr_enable(struct device *dev, void *data) +{ + struct bolero_priv *priv = data; + int macro_idx; + + if (priv->initial_boot) { + priv->initial_boot = false; + return 0; + } + + if (priv->macro_params[VA_MACRO].event_handler) + priv->macro_params[VA_MACRO].event_handler(priv->codec, + BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET, 0x0); + + regcache_cache_only(priv->regmap, false); + /* call ssr event for supported macros */ + for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { + if (!priv->macro_params[macro_idx].event_handler) + continue; + priv->macro_params[macro_idx].event_handler(priv->codec, + BOLERO_MACRO_EVT_SSR_UP, 0x0); + } + mutex_lock(&priv->clk_lock); + priv->dev_up = true; + mutex_unlock(&priv->clk_lock); + bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_SSR_UP); + return 0; +} + +static void bolero_ssr_disable(struct device *dev, void *data) +{ + struct bolero_priv *priv = data; + int macro_idx; + + regcache_cache_only(priv->regmap, true); + + mutex_lock(&priv->clk_lock); + priv->dev_up = false; + mutex_unlock(&priv->clk_lock); + /* call ssr event for supported macros */ + for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { + if (!priv->macro_params[macro_idx].event_handler) + continue; + priv->macro_params[macro_idx].event_handler(priv->codec, + BOLERO_MACRO_EVT_SSR_DOWN, 0x0); + } + bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_SSR_DOWN); +} + static struct snd_info_entry_ops bolero_info_ops = { .read = bolero_version_read, }; +static const struct snd_event_ops bolero_ssr_ops = { + .enable = bolero_ssr_enable, + .disable = bolero_ssr_disable, +}; + /* * bolero_info_create_codec_entry - creates bolero module * @codec_root: The parent directory @@ -623,6 +687,16 @@ static int bolero_soc_codec_probe(struct snd_soc_codec *codec) else if (priv->num_macros_registered > 2) priv->version = BOLERO_VERSION_1_2; + ret = snd_event_client_register(priv->dev, &bolero_ssr_ops, priv); + if (!ret) { + snd_event_notify(priv->dev, SND_EVENT_UP); + } else { + dev_err(codec->dev, + "%s: Registration with SND event FWK failed ret = %d\n", + __func__, ret); + goto err; + } + dev_dbg(codec->dev, "%s: bolero soc codec probe success\n", __func__); err: return ret; @@ -633,6 +707,7 @@ static int bolero_soc_codec_remove(struct snd_soc_codec *codec) struct bolero_priv *priv = dev_get_drvdata(codec->dev); int macro_idx; + snd_event_client_deregister(priv->dev); /* call exit for supported macros */ for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) if (priv->macro_params[macro_idx].exit) @@ -756,6 +831,8 @@ static int bolero_probe(struct platform_device *pdev) bolero_reg_access[VA_MACRO] = bolero_va_top_reg_access; priv->dev = &pdev->dev; + priv->dev_up = true; + priv->initial_boot = true; priv->regmap = bolero_regmap_init(priv->dev, &bolero_regmap_config); if (IS_ERR_OR_NULL((void *)(priv->regmap))) { diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 3e8197d58ee2..aa524918e64f 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -43,6 +43,9 @@ enum { BOLERO_MACRO_EVT_RX_MUTE = 1, /* for RX mute/unmute */ BOLERO_MACRO_EVT_IMPED_TRUE, /* for imped true */ BOLERO_MACRO_EVT_IMPED_FALSE, /* for imped false */ + BOLERO_MACRO_EVT_SSR_DOWN, + BOLERO_MACRO_EVT_SSR_UP, + BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET }; struct macro_ops { diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 9e8a74c5e34f..0129c395f1b9 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -20,6 +20,8 @@ /* from bolero to WCD events */ enum { BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1, + BOLERO_WCD_EVT_SSR_DOWN, + BOLERO_WCD_EVT_SSR_UP, }; enum { @@ -52,6 +54,8 @@ struct bolero_priv { struct mutex clk_lock; bool va_without_decimation; bool macros_supported[MAX_MACRO]; + bool dev_up; + bool initial_boot; struct macro_ops macro_params[MAX_MACRO]; struct snd_soc_dai_driver *bolero_dais; u16 num_dais; diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index a0e189b5d5df..6c936cbc014c 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1130,6 +1130,19 @@ static int rx_macro_event_handler(struct snd_soc_codec *codec, u16 event, case BOLERO_MACRO_EVT_IMPED_FALSE: rx_macro_wcd_clsh_imped_config(codec, data, false); break; + case BOLERO_MACRO_EVT_SSR_DOWN: + swrm_wcd_notify( + rx_priv->swr_ctrl_data[0].rx_swr_pdev, + SWR_DEVICE_SSR_DOWN, NULL); + swrm_wcd_notify( + rx_priv->swr_ctrl_data[0].rx_swr_pdev, + SWR_DEVICE_DOWN, NULL); + break; + case BOLERO_MACRO_EVT_SSR_UP: + swrm_wcd_notify( + rx_priv->swr_ctrl_data[0].rx_swr_pdev, + SWR_DEVICE_SSR_UP, NULL); + break; } return 0; } diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 9cfd94d6b6d6..44826de51f54 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "bolero-cdc.h" #include "bolero-cdc-registers.h" #include "../msm-cdc-pinctrl.h" @@ -303,6 +304,33 @@ static int tx_macro_mclk_ctrl(struct device *dev, bool enable) return ret; } +static int tx_macro_event_handler(struct snd_soc_codec *codec, u16 event, + u32 data) +{ + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + + if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + switch (event) { + case BOLERO_MACRO_EVT_SSR_DOWN: + swrm_wcd_notify( + tx_priv->swr_ctrl_data[0].tx_swr_pdev, + SWR_DEVICE_SSR_DOWN, NULL); + swrm_wcd_notify( + tx_priv->swr_ctrl_data[0].tx_swr_pdev, + SWR_DEVICE_DOWN, NULL); + break; + case BOLERO_MACRO_EVT_SSR_UP: + swrm_wcd_notify( + tx_priv->swr_ctrl_data[0].tx_swr_pdev, + SWR_DEVICE_SSR_UP, NULL); + break; + } + return 0; +} + static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) { struct delayed_work *hpf_delayed_work = NULL; @@ -1640,6 +1668,7 @@ static void tx_macro_init_ops(struct macro_ops *ops, ops->dai_ptr = tx_macro_dai; ops->num_dais = ARRAY_SIZE(tx_macro_dai); ops->mclk_fn = tx_macro_mclk_ctrl; + ops->event_handler = tx_macro_event_handler; } static int tx_macro_probe(struct platform_device *pdev) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index eb069fa0c324..1d28e411fa1a 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -46,6 +46,7 @@ #define VA_MACRO_TX_DMIC_CLK_DIV_SHFT 0x01 #define BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS 40 +#define MAX_RETRY_ATTEMPTS 50 static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); static int va_tx_unmute_delay = BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS; @@ -178,8 +179,7 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, 0x02, 0x02); } } else { - va_priv->va_mclk_users--; - if (va_priv->va_mclk_users == 0) { + if (va_priv->va_mclk_users == 1) { regmap_update_bits(regmap, BOLERO_CDC_VA_TOP_CSR_TOP_CFG0, 0x02, 0x00); @@ -192,12 +192,47 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, bolero_request_clock(va_priv->dev, VA_MACRO, MCLK_MUX0, false); } + va_priv->va_mclk_users--; } exit: mutex_unlock(&va_priv->mclk_lock); return ret; } +static int va_macro_event_handler(struct snd_soc_codec *codec, u16 event, + u32 data) +{ + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + int retry_cnt = MAX_RETRY_ATTEMPTS; + + if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + return -EINVAL; + + switch (event) { + case BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET: + while ((va_priv->va_mclk_users != 0) && (retry_cnt != 0)) { + dev_dbg(va_dev, "%s:retry_cnt: %d\n", + __func__, retry_cnt); + /* + * loop and check every 20ms for va_mclk user count + * to get reset to 0 which ensures userspace teardown + * is done and SSR powerup seq can proceed. + */ + msleep(20); + retry_cnt--; + } + if (retry_cnt == 0) + dev_err(va_dev, + "%s: va_mclk_users is non-zero still, audio SSR fail!!\n", + __func__); + break; + default: + break; + } + return 0; +} + static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -1054,13 +1089,13 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY_S("VA_MCLK", 0, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0, va_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; static const struct snd_soc_dapm_widget va_macro_wod_dapm_widgets[] = { - SND_SOC_DAPM_SUPPLY_S("VA_MCLK", 0, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0, va_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; @@ -1465,6 +1500,7 @@ static void va_macro_init_ops(struct macro_ops *ops, ops->exit = va_macro_deinit; ops->io_base = va_io_base; ops->mclk_fn = va_macro_mclk_ctrl; + ops->event_handler = va_macro_event_handler; } static int va_macro_probe(struct platform_device *pdev) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 3fe637e9a3b2..d5271865b2f5 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -859,6 +859,33 @@ static int wsa_macro_mclk_ctrl(struct device *dev, bool enable) return ret; } +static int wsa_macro_event_handler(struct snd_soc_codec *codec, u16 event, + u32 data) +{ + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + switch (event) { + case BOLERO_MACRO_EVT_SSR_DOWN: + swrm_wcd_notify( + wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, + SWR_DEVICE_SSR_DOWN, NULL); + swrm_wcd_notify( + wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, + SWR_DEVICE_DOWN, NULL); + break; + case BOLERO_MACRO_EVT_SSR_UP: + swrm_wcd_notify( + wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, + SWR_DEVICE_SSR_UP, NULL); + break; + } + return 0; +} + static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -2617,6 +2644,7 @@ static void wsa_macro_init_ops(struct macro_ops *ops, ops->dai_ptr = wsa_macro_dai; ops->num_dais = ARRAY_SIZE(wsa_macro_dai); ops->mclk_fn = wsa_macro_mclk_ctrl; + ops->event_handler = wsa_macro_event_handler; } static int wsa_macro_probe(struct platform_device *pdev) -- GitLab From 1aab2c064a6931a07a22bf5b74b81ce9e8dd8708 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Sat, 22 Sep 2018 01:58:18 +0530 Subject: [PATCH 0533/1645] asoc: wcd937x: add SSR changes for wcd937x codec driver Add changes to recover audio after SSR on wcd937x driver. Change-Id: I661605e9b1bd71f08f331d14ae52f89ba8423d4f Signed-off-by: Rohit kumar Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd937x/internal.h | 2 + asoc/codecs/wcd937x/wcd937x-mbhc.c | 1 + asoc/codecs/wcd937x/wcd937x-regmap.c | 6 ++- asoc/codecs/wcd937x/wcd937x.c | 72 +++++++++++++++++++++++++++- asoc/codecs/wcd937x/wcd937x_slave.c | 18 +++++++ 5 files changed, 96 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index 0818c05eb65f..4ca82726a5ce 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -123,6 +123,8 @@ enum { enum { BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1, + BOLERO_WCD_EVT_SSR_DOWN, + BOLERO_WCD_EVT_SSR_UP, }; enum { diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index 52bc009d87b5..c95de4bad700 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -974,6 +974,7 @@ int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc, return -EINVAL; } + wcd937x_mbhc_hs_detect_exit(codec); wcd_mbhc_deinit(wcd_mbhc); ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids, wcd_mbhc_registers, WCD937X_ZDET_SUPPORTED); diff --git a/asoc/codecs/wcd937x/wcd937x-regmap.c b/asoc/codecs/wcd937x/wcd937x-regmap.c index f445abceed9a..0d15c105f2c8 100644 --- a/asoc/codecs/wcd937x/wcd937x-regmap.c +++ b/asoc/codecs/wcd937x/wcd937x-regmap.c @@ -450,8 +450,10 @@ static bool wcd937x_volatile_register(struct device *dev, unsigned int reg) { if(reg <= WCD937X_BASE_ADDRESS) return 0; - return (wcd937x_reg_access[WCD937X_REG(reg)] & RD_REG) - & ~(wcd937x_reg_access[WCD937X_REG(reg)] & WR_REG); + if ((wcd937x_reg_access[WCD937X_REG(reg)] & RD_REG) + && !(wcd937x_reg_access[WCD937X_REG(reg)] & WR_REG)) + return true; + return false; } struct regmap_config wcd937x_regmap_config = { diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index b599b1f3270d..0bdfda1a52f6 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -48,6 +48,8 @@ static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); static int wcd937x_handle_post_irq(void *data); +static int wcd937x_reset(struct device *dev); +static int wcd937x_reset_low(struct device *dev); static const struct regmap_irq wcd937x_irqs[WCD937X_NUM_IRQS] = { REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x01), @@ -1216,6 +1218,23 @@ int wcd937x_micbias_control(struct snd_soc_codec *codec, } EXPORT_SYMBOL(wcd937x_micbias_control); +static int wcd937x_get_logical_addr(struct swr_device *swr_dev) +{ + int ret = 0; + uint8_t devnum = 0; + + ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum); + if (ret) { + dev_err(&swr_dev->dev, + "%s get devnum %d for dev addr %lx failed\n", + __func__, devnum, swr_dev->addr); + swr_remove_device(swr_dev); + return ret; + } + swr_dev->dev_num = devnum; + return 0; +} + static int wcd937x_event_notify(struct notifier_block *block, unsigned long val, void *data) @@ -1223,8 +1242,10 @@ static int wcd937x_event_notify(struct notifier_block *block, u16 event = (val & 0xffff); u16 amic = (val >> 0x10); u16 mask = 0x40, reg = 0x0; + int ret = 0; struct wcd937x_priv *wcd937x = dev_get_drvdata((struct device *)data); struct snd_soc_codec *codec = wcd937x->codec; + struct wcd_mbhc *mbhc; switch (event) { case BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR: @@ -1238,6 +1259,25 @@ static int wcd937x_event_notify(struct notifier_block *block, mask = 0x20; snd_soc_update_bits(codec, reg, mask, 0x00); break; + case BOLERO_WCD_EVT_SSR_DOWN: + wcd937x_reset_low(wcd937x->dev); + break; + case BOLERO_WCD_EVT_SSR_UP: + wcd937x_reset(wcd937x->dev); + wcd937x_get_logical_addr(wcd937x->tx_swr_dev); + wcd937x_get_logical_addr(wcd937x->rx_swr_dev); + regcache_mark_dirty(wcd937x->regmap); + regcache_sync(wcd937x->regmap); + /* Initialize MBHC module */ + mbhc = &wcd937x->mbhc->wcd_mbhc; + ret = wcd937x_mbhc_post_ssr_init(wcd937x->mbhc, codec); + if (ret) { + dev_err(codec->dev, "%s: mbhc initialization failed\n", + __func__); + } else { + wcd937x_mbhc_hs_detect(codec, mbhc->mbhc_cfg); + } + break; default: dev_err(codec->dev, "%s: invalid event %d\n", __func__, event); break; @@ -1923,7 +1963,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wcd937x = { }, }; -int wcd937x_reset(struct device *dev) +static int wcd937x_reset(struct device *dev) { struct wcd937x_priv *wcd937x = NULL; int rc = 0; @@ -2026,6 +2066,36 @@ static void wcd937x_dt_parse_micbias_info(struct device *dev, } } +static int wcd937x_reset_low(struct device *dev) +{ + struct wcd937x_priv *wcd937x = NULL; + int rc = 0; + + if (!dev) + return -ENODEV; + + wcd937x = dev_get_drvdata(dev); + if (!wcd937x) + return -EINVAL; + + if (!wcd937x->rst_np) { + dev_err(dev, "%s: reset gpio device node not specified\n", + __func__); + return -EINVAL; + } + + rc = msm_cdc_pinctrl_select_sleep_state(wcd937x->rst_np); + if (rc) { + dev_err(dev, "%s: wcd sleep state request fail!\n", + __func__); + return rc; + } + /* 20ms sleep required after pulling the reset gpio to LOW */ + usleep_range(20, 30); + + return rc; +} + struct wcd937x_pdata *wcd937x_populate_dt_data(struct device *dev) { struct wcd937x_pdata *pdata = NULL; diff --git a/asoc/codecs/wcd937x/wcd937x_slave.c b/asoc/codecs/wcd937x/wcd937x_slave.c index 36c2af1e710e..252504fe0f08 100644 --- a/asoc/codecs/wcd937x/wcd937x_slave.c +++ b/asoc/codecs/wcd937x/wcd937x_slave.c @@ -85,6 +85,21 @@ static const struct component_ops wcd937x_slave_comp_ops = { .unbind = wcd937x_slave_unbind, }; +static int wcd937x_swr_up(struct swr_device *pdev) +{ + return 0; +} + +static int wcd937x_swr_down(struct swr_device *pdev) +{ + return 0; +} + +static int wcd937x_swr_reset(struct swr_device *pdev) +{ + return 0; +} + static int wcd937x_swr_probe(struct swr_device *pdev) { return component_add(&pdev->dev, &wcd937x_slave_comp_ops); @@ -105,6 +120,9 @@ static struct swr_driver wcd937x_slave_driver = { .probe = wcd937x_swr_probe, .remove = wcd937x_swr_remove, .id_table = wcd937x_swr_id, + .device_up = wcd937x_swr_up, + .device_down = wcd937x_swr_down, + .reset_device = wcd937x_swr_reset, }; static int __init wcd937x_slave_init(void) -- GitLab From 9a3d5ebc7ca7350b60947e649d98fe870005dab9 Mon Sep 17 00:00:00 2001 From: Vaishnavi Kommaraju Date: Wed, 19 Sep 2018 18:16:39 +0530 Subject: [PATCH 0534/1645] asoc: sm6150: Add SND event FWK support for talos Add snd_event support for talos required for SSR. Change-Id: If689d9cda131324b99e0dda0b91f237b495eeadc Signed-off-by: Vaishnavi Kommaraju --- asoc/sm6150.c | 245 +++++++++++++++++++++++--------------------------- 1 file changed, 114 insertions(+), 131 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 72181221ea1f..467fba7d17ee 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include "device_event.h" @@ -201,6 +201,7 @@ struct msm_asoc_mach_data { struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */ struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ + bool is_afe_config_done; }; struct msm_asoc_wcd93xx_codec { @@ -628,10 +629,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_3_sample_rate, static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_sample_rate, cdc_dma_sample_rate_text); -static struct platform_device *spdev; - static int msm_hifi_control; -static bool is_initial_boot; static bool codec_reg_done; static struct snd_soc_aux_dev *msm_aux_dev; static struct snd_soc_codec_conf *msm_codec_conf; @@ -4595,121 +4593,6 @@ static void msm_afe_clear_config(void) afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); } -static int msm_adsp_power_up_config(struct snd_soc_codec *codec, - struct snd_card *card) -{ - int ret = 0; - unsigned long timeout; - int adsp_ready = 0; - bool snd_card_online = 0; - - timeout = jiffies + - msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); - - do { - if (!snd_card_online) { - snd_card_online = snd_card_is_online_state(card); - pr_debug("%s: Sound card is %s\n", __func__, - snd_card_online ? "Online" : "Offline"); - } - if (!adsp_ready) { - adsp_ready = q6core_is_adsp_ready(); - pr_debug("%s: ADSP Audio is %s\n", __func__, - adsp_ready ? "ready" : "not ready"); - } - if (snd_card_online && adsp_ready) - break; - - /* - * Sound card/ADSP will be coming up after subsystem restart and - * it might not be fully up when the control reaches - * here. So, wait for 50msec before checking ADSP state - */ - msleep(50); - } while (time_after(timeout, jiffies)); - - if (!snd_card_online || !adsp_ready) { - pr_err("%s: Timeout. Sound card is %s, ADSP Audio is %s\n", - __func__, - snd_card_online ? "Online" : "Offline", - adsp_ready ? "ready" : "not ready"); - ret = -ETIMEDOUT; - goto err; - } - - ret = msm_afe_set_config(codec); - if (ret) - pr_err("%s: Failed to set AFE config. err %d\n", - __func__, ret); - - return 0; - -err: - return ret; -} - -static int sm6150_notifier_service_cb(struct notifier_block *this, - unsigned long opcode, void *ptr) -{ - int ret; - struct snd_soc_card *card = NULL; - const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; - struct snd_soc_pcm_runtime *rtd; - struct snd_soc_codec *codec; - - pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); - - switch (opcode) { - case AUDIO_NOTIFIER_SERVICE_DOWN: - /* - * Use flag to ignore initial boot notifications - * On initial boot msm_adsp_power_up_config is - * called on init. There is no need to clear - * and set the config again on initial boot. - */ - if (is_initial_boot) - break; - msm_afe_clear_config(); - break; - case AUDIO_NOTIFIER_SERVICE_UP: - if (is_initial_boot) { - is_initial_boot = false; - break; - } - if (!spdev) - return -EINVAL; - - card = platform_get_drvdata(spdev); - rtd = snd_soc_get_pcm_runtime(card, be_dl_name); - if (!rtd) { - dev_err(card->dev, - "%s: snd_soc_get_pcm_runtime for %s failed!\n", - __func__, be_dl_name); - ret = -EINVAL; - goto err; - } - codec = rtd->codec; - - ret = msm_adsp_power_up_config(codec, card->snd_card); - if (ret < 0) { - dev_err(card->dev, - "%s: msm_adsp_power_up_config failed ret = %d!\n", - __func__, ret); - goto err; - } - break; - default: - break; - } -err: - return NOTIFY_OK; -} - -static struct notifier_block service_nb = { - .notifier_call = sm6150_notifier_service_cb, - .priority = -INT_MAX, -}; - static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; @@ -4797,11 +4680,12 @@ static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) msm_codec_fn.get_afe_config_fn = tavil_get_afe_config; - ret = msm_adsp_power_up_config(codec, rtd->card->snd_card); + ret = msm_afe_set_config(codec); if (ret) { pr_err("%s: Failed to set AFE config %d\n", __func__, ret); goto err; } + pdata->is_afe_config_done = true; config_data = msm_codec_fn.get_afe_config_fn(codec, AFE_AANC_VERSION); @@ -8309,6 +8193,108 @@ static void msm_i2s_auxpcm_deinit(void) mi2s_intf_conf[count].msm_is_mi2s_master = 0; } } + +static int sm6150_ssr_enable(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata; + int ret = 0; + + if (!card) { + dev_err(dev, "%s: card is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + if (!strcmp(card->name, "sm6150-tavil-snd-card")) { + pdata = snd_soc_card_get_drvdata(card); + if (!pdata->is_afe_config_done) { + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err; + } + ret = msm_afe_set_config(rtd->codec); + if (ret) + dev_err(dev, "%s: Failed to set AFE config. err %d\n", + __func__, ret); + else + pdata->is_afe_config_done = true; + } + } + snd_soc_card_change_online_state(card, 1); + dev_dbg(dev, "%s: setting snd_card to ONLINE\n", __func__); + +err: + return ret; +} + +static void sm6150_ssr_disable(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata; + + if (!card) { + dev_err(dev, "%s: card is NULL\n", __func__); + return; + } + + dev_dbg(dev, "%s: setting snd_card to OFFLINE\n", __func__); + snd_soc_card_change_online_state(card, 0); + + if (!strcmp(card->name, "sm6150-tavil-snd-card")) { + pdata = snd_soc_card_get_drvdata(card); + msm_afe_clear_config(); + pdata->is_afe_config_done = false; + } +} + +static const struct snd_event_ops sm6150_ssr_ops = { + .enable = sm6150_ssr_enable, + .disable = sm6150_ssr_disable, +}; + +static int msm_audio_ssr_compare(struct device *dev, void *data) +{ + struct device_node *node = data; + + dev_dbg(dev, "%s: dev->of_node = 0x%p, node = 0x%p\n", + __func__, dev->of_node, node); + return (dev->of_node && dev->of_node == node); +} + +static int msm_audio_ssr_register(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct snd_event_clients *ssr_clients = NULL; + struct device_node *node; + int ret; + int i; + + for (i = 0; ; i++) { + node = of_parse_phandle(np, "qcom,msm_audio_ssr_devs", i); + if (!node) + break; + snd_event_mstr_add_client(&ssr_clients, + msm_audio_ssr_compare, node); + } + + ret = snd_event_master_register(dev, &sm6150_ssr_ops, + ssr_clients, NULL); + if (!ret) + snd_event_notify(dev, SND_EVENT_UP); + + return ret; +} + static int msm_asoc_machine_probe(struct platform_device *pdev) { struct snd_soc_card *card; @@ -8371,7 +8357,6 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) goto err; } dev_info(&pdev->dev, "Sound card %s registered\n", card->name); - spdev = pdev; pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,hph-en1-gpio", 0); @@ -8438,15 +8423,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) } msm_i2s_auxpcm_init(pdev); - if (!strcmp(card->name, "sm6150-tavil-snd-card")) { - is_initial_boot = true; - ret = audio_notifier_register("sm6150", - AUDIO_NOTIFIER_ADSP_DOMAIN, - &service_nb); - if (ret < 0) - pr_err("%s: Audio notifier register failed ret = %d\n", - __func__, ret); - } else { + if (strcmp(card->name, "sm6150-tavil-snd-card")) { pdata->dmic01_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,cdc-dmic01-gpios", 0); @@ -8454,13 +8431,19 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) "qcom,cdc-dmic23-gpios", 0); } + + ret = msm_audio_ssr_register(&pdev->dev); + if (ret) + pr_err("%s: Registration with SND event FWK failed ret = %d\n", + __func__, ret); + err: return ret; } static int msm_asoc_machine_remove(struct platform_device *pdev) { - audio_notifier_deregister("sm6150"); + snd_event_master_deregister(&pdev->dev); msm_i2s_auxpcm_deinit(); return 0; -- GitLab From 27138766db6824fc1ce1eb4a39d645ed9e9eb2d3 Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Mon, 17 Sep 2018 17:42:44 +0530 Subject: [PATCH 0535/1645] config: sm6150: Enable compilation of snd_event Enable compilation of snd_event driver for sm6150. Change-Id: Ia6c62fea8d3660e187e79d1743a1b6862f3dd228 Signed-off-by: Rohit kumar --- config/sm6150auto.conf | 1 + config/sm6150autoconf.h | 1 + soc/Android.mk | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config/sm6150auto.conf b/config/sm6150auto.conf index 1fb50df16f7c..f6074abbac0b 100644 --- a/config/sm6150auto.conf +++ b/config/sm6150auto.conf @@ -45,3 +45,4 @@ CONFIG_TX_MACRO=m CONFIG_SND_SOC_WCD_IRQ=m CONFIG_SND_SOC_WCD937X=m CONFIG_SND_SOC_WCD937X_SLAVE=m +CONFIG_SND_EVENT=m diff --git a/config/sm6150autoconf.h b/config/sm6150autoconf.h index 5cc79c348c7b..d69a9dec0f2e 100644 --- a/config/sm6150autoconf.h +++ b/config/sm6150autoconf.h @@ -58,3 +58,4 @@ #define CONFIG_SND_SOC_WCD_IRQ 1 #define CONFIG_SND_SOC_WCD937X 1 #define CONFIG_SND_SOC_WCD937X_SLAVE 1 +#define CONFIG_SND_EVENT 1 diff --git a/soc/Android.mk b/soc/Android.mk index 24016adacb63..67e6576c4251 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -82,7 +82,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### -ifeq ($(call is-board-platform-in-list, ),true) +ifeq ($(call is-board-platform-in-list, $(MSMSTEPPE)),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_snd_event.ko LOCAL_MODULE_KBUILD_NAME := snd_event_dlkm.ko -- GitLab From 3d8cc2ed33cb3e13c5573d8c82cef151be021027 Mon Sep 17 00:00:00 2001 From: Dhananjay Kumar Date: Wed, 5 Sep 2018 20:04:23 +0530 Subject: [PATCH 0536/1645] asoc: fix routing error during switch from non-adm to adm path Fix routing error from incorrect usage of passthrough mode while switching LSM session from direct AFE connection to path using ADM before AFE connection. Issue is due to loss of passthrough mode for an FE not opened with ADM during initial session setup or while moving the FE from one BE port to another BE port, i.e. device switch usecases. Since passthrough mode for an FE is supposed to be same for all the BEs connecting to the FE and is directly decided from FE driver having single value, decouple passthrough mode from BE and store the required mode in an FE config independent of BE usage. This allows storing passthrough mode for future usage irrespective of initial setup path which can be with or without ADM. Change-Id: I53106b49effd9b267363aedd77477eed103b317c Signed-off-by: Dhananjay Kumar --- asoc/msm-pcm-routing-v2.c | 635 +++++++++++++++++++------------------- asoc/msm-pcm-routing-v2.h | 2 +- 2 files changed, 315 insertions(+), 322 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 9e445946bbf0..1c9ad1a9d4ba 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -301,342 +301,342 @@ static void msm_pcm_routng_cfg_matrix_map_pp(struct route_payload payload, #define SLIMBUS_EXTPROC_RX AFE_PORT_INVALID struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { - { PRIMARY_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_PRI_I2S_RX}, - { PRIMARY_I2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_PRI_I2S_TX}, - { SLIMBUS_0_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_0_RX}, - { SLIMBUS_0_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_0_TX}, - { HDMI_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_HDMI}, - { INT_BT_SCO_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_INT_BT_SCO_RX}, - { INT_BT_SCO_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_INT_BT_SCO_TX}, - { INT_FM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_INT_FM_RX}, - { INT_FM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_INT_FM_TX}, - { RT_PROXY_PORT_001_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { PRIMARY_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_I2S_RX}, + { PRIMARY_I2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_I2S_TX}, + { SLIMBUS_0_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_0_RX}, + { SLIMBUS_0_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_0_TX}, + { HDMI_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_HDMI}, + { INT_BT_SCO_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT_BT_SCO_RX}, + { INT_BT_SCO_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT_BT_SCO_TX}, + { INT_FM_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT_FM_RX}, + { INT_FM_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT_FM_TX}, + { RT_PROXY_PORT_001_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_AFE_PCM_RX}, - { RT_PROXY_PORT_001_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { RT_PROXY_PORT_001_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_AFE_PCM_TX}, - { AFE_PORT_ID_PRIMARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_AUXPCM_RX}, - { AFE_PORT_ID_PRIMARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_AUXPCM_TX}, - { VOICE_PLAYBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { VOICE_PLAYBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_VOICE_PLAYBACK_TX}, - { VOICE2_PLAYBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { VOICE2_PLAYBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_VOICE2_PLAYBACK_TX}, - { VOICE_RECORD_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { VOICE_RECORD_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INCALL_RECORD_RX}, - { VOICE_RECORD_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { VOICE_RECORD_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INCALL_RECORD_TX}, - { MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_MI2S_RX}, - { MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_MI2S_TX}, - { SECONDARY_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SEC_I2S_RX}, - { SLIMBUS_1_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_1_RX}, - { SLIMBUS_1_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_1_TX}, - { SLIMBUS_2_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_2_RX}, - { SLIMBUS_2_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_2_TX}, - { SLIMBUS_3_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_3_RX}, - { SLIMBUS_3_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_3_TX}, - { SLIMBUS_4_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_4_RX}, - { SLIMBUS_4_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_4_TX}, - { SLIMBUS_5_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_5_RX}, - { SLIMBUS_5_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_5_TX}, - { SLIMBUS_6_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_6_RX}, - { SLIMBUS_6_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_6_TX}, - { SLIMBUS_7_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_7_RX}, - { SLIMBUS_7_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_7_TX}, - { SLIMBUS_8_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_8_RX}, - { SLIMBUS_8_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_SLIMBUS_8_TX}, - { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_STUB_RX}, - { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_STUB_TX}, - { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_STUB_1_TX}, - { AFE_PORT_ID_QUATERNARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_MI2S_RX}, + { MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_MI2S_TX}, + { SECONDARY_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_I2S_RX}, + { SLIMBUS_1_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_RX}, + { SLIMBUS_1_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_TX}, + { SLIMBUS_2_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_RX}, + { SLIMBUS_2_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_TX}, + { SLIMBUS_3_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_RX}, + { SLIMBUS_3_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_TX}, + { SLIMBUS_4_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_RX}, + { SLIMBUS_4_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_TX}, + { SLIMBUS_5_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_RX}, + { SLIMBUS_5_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_TX}, + { SLIMBUS_6_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_RX}, + { SLIMBUS_6_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_TX}, + { SLIMBUS_7_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_RX}, + { SLIMBUS_7_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_TX}, + { SLIMBUS_8_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_RX}, + { SLIMBUS_8_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_TX}, + { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_STUB_RX}, + { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_STUB_TX}, + { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_STUB_1_TX}, + { AFE_PORT_ID_QUATERNARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_MI2S_RX}, - { AFE_PORT_ID_QUATERNARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_MI2S_TX}, - { AFE_PORT_ID_SECONDARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_MI2S_RX}, - { AFE_PORT_ID_SECONDARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_MI2S_TX}, - { AFE_PORT_ID_PRIMARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_MI2S_RX}, - { AFE_PORT_ID_PRIMARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_MI2S_TX}, - { AFE_PORT_ID_TERTIARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_MI2S_RX}, - { AFE_PORT_ID_TERTIARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_MI2S_TX}, - { AUDIO_PORT_ID_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AUDIO_PORT_ID_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_AUDIO_I2S_RX}, - { AFE_PORT_ID_SECONDARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_AUXPCM_RX}, - { AFE_PORT_ID_SECONDARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_AUXPCM_TX}, - { AFE_PORT_ID_PRIMARY_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_SPDIF_RX}, - { AFE_PORT_ID_SECONDARY_MI2S_RX_SD1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_MI2S_RX_SD1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_MI2S_RX_SD1}, - { AFE_PORT_ID_QUINARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_MI2S_RX}, - { AFE_PORT_ID_QUINARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_MI2S_TX}, - { AFE_PORT_ID_SENARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SENARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SENARY_MI2S_TX}, - { AFE_PORT_ID_PRIMARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_0}, - { AFE_PORT_ID_PRIMARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_0}, - { AFE_PORT_ID_PRIMARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_1}, - { AFE_PORT_ID_PRIMARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_1}, - { AFE_PORT_ID_PRIMARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_2}, - { AFE_PORT_ID_PRIMARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_2}, - { AFE_PORT_ID_PRIMARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_3}, - { AFE_PORT_ID_PRIMARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_3}, - { AFE_PORT_ID_PRIMARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_4}, - { AFE_PORT_ID_PRIMARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_4}, - { AFE_PORT_ID_PRIMARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_5}, - { AFE_PORT_ID_PRIMARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_5}, - { AFE_PORT_ID_PRIMARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_6}, - { AFE_PORT_ID_PRIMARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_6}, - { AFE_PORT_ID_PRIMARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_TDM_RX_7}, - { AFE_PORT_ID_PRIMARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_TDM_TX_7}, - { AFE_PORT_ID_SECONDARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_0}, - { AFE_PORT_ID_SECONDARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_0}, - { AFE_PORT_ID_SECONDARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_1}, - { AFE_PORT_ID_SECONDARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_1}, - { AFE_PORT_ID_SECONDARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_2}, - { AFE_PORT_ID_SECONDARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_2}, - { AFE_PORT_ID_SECONDARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_3}, - { AFE_PORT_ID_SECONDARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_3}, - { AFE_PORT_ID_SECONDARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_4}, - { AFE_PORT_ID_SECONDARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_4}, - { AFE_PORT_ID_SECONDARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_5}, - { AFE_PORT_ID_SECONDARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_5}, - { AFE_PORT_ID_SECONDARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_6}, - { AFE_PORT_ID_SECONDARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_6}, - { AFE_PORT_ID_SECONDARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_TDM_RX_7}, - { AFE_PORT_ID_SECONDARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_TDM_TX_7}, - { AFE_PORT_ID_TERTIARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_0}, - { AFE_PORT_ID_TERTIARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_0}, - { AFE_PORT_ID_TERTIARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_1}, - { AFE_PORT_ID_TERTIARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_1}, - { AFE_PORT_ID_TERTIARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_2}, - { AFE_PORT_ID_TERTIARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_2}, - { AFE_PORT_ID_TERTIARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_3}, - { AFE_PORT_ID_TERTIARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_3}, - { AFE_PORT_ID_TERTIARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_4}, - { AFE_PORT_ID_TERTIARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_4}, - { AFE_PORT_ID_TERTIARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_5}, - { AFE_PORT_ID_TERTIARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_5}, - { AFE_PORT_ID_TERTIARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_6}, - { AFE_PORT_ID_TERTIARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_6}, - { AFE_PORT_ID_TERTIARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_TDM_RX_7}, - { AFE_PORT_ID_TERTIARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_TDM_TX_7}, - { AFE_PORT_ID_QUATERNARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_0}, - { AFE_PORT_ID_QUATERNARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_0}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_1}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_1}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_2}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_2}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_3}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_3}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_4}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_4}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_5}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_5}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_6}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_6}, - { AFE_PORT_ID_QUATERNARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_RX_7}, - { AFE_PORT_ID_QUATERNARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_7}, - { AFE_PORT_ID_QUINARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_RX_0}, - { AFE_PORT_ID_QUINARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_TX_0}, - { AFE_PORT_ID_QUINARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_RX_1}, - { AFE_PORT_ID_QUINARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_TX_1}, - { AFE_PORT_ID_QUINARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_RX_2}, - { AFE_PORT_ID_QUINARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_TX_2}, - { AFE_PORT_ID_QUINARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_RX_3}, - { AFE_PORT_ID_QUINARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_TX_3}, - { AFE_PORT_ID_QUINARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_RX_4}, - { AFE_PORT_ID_QUINARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_TX_4}, - { AFE_PORT_ID_QUINARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_RX_5}, - { AFE_PORT_ID_QUINARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_TX_5}, - { AFE_PORT_ID_QUINARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_RX_6}, - { AFE_PORT_ID_QUINARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_TX_6}, - { AFE_PORT_ID_QUINARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_RX_7}, - { AFE_PORT_ID_QUINARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_TX_7}, - { INT_BT_A2DP_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { INT_BT_A2DP_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT_BT_A2DP_RX}, - { AFE_PORT_ID_USB_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_USB_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_USB_AUDIO_RX}, - { AFE_PORT_ID_USB_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_USB_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_USB_AUDIO_TX}, - { DISPLAY_PORT_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { DISPLAY_PORT_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_DISPLAY_PORT}, - { DISPLAY_PORT_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { DISPLAY_PORT_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_DISPLAY_PORT1}, - { AFE_PORT_ID_TERTIARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_AUXPCM_RX}, - { AFE_PORT_ID_TERTIARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TERTIARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TERT_AUXPCM_TX}, - { AFE_PORT_ID_QUATERNARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_AUXPCM_RX}, - { AFE_PORT_ID_QUATERNARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUATERNARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUAT_AUXPCM_TX}, - { AFE_PORT_ID_QUINARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_AUXPCM_RX}, - { AFE_PORT_ID_QUINARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_QUINARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_AUXPCM_TX}, - { AFE_PORT_ID_INT0_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_INT0_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT0_MI2S_RX}, - { AFE_PORT_ID_INT0_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_INT0_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT0_MI2S_TX}, - { AFE_PORT_ID_INT1_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_INT1_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT1_MI2S_RX}, - { AFE_PORT_ID_INT1_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_INT1_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT1_MI2S_TX}, - { AFE_PORT_ID_INT2_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_INT2_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT2_MI2S_RX}, - { AFE_PORT_ID_INT2_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_INT2_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT2_MI2S_TX}, - { AFE_PORT_ID_INT3_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_INT3_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT3_MI2S_RX}, - { AFE_PORT_ID_INT3_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_INT3_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT3_MI2S_TX}, - { AFE_PORT_ID_INT4_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_INT4_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT4_MI2S_RX}, - { AFE_PORT_ID_INT4_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_INT4_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT4_MI2S_TX}, - { AFE_PORT_ID_INT5_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_INT5_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT5_MI2S_RX}, - { AFE_PORT_ID_INT5_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_INT5_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT5_MI2S_TX}, - { AFE_PORT_ID_INT6_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_INT6_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT6_MI2S_RX}, - { AFE_PORT_ID_INT6_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_INT6_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT6_MI2S_TX}, - { AFE_PORT_ID_WSA_CODEC_DMA_RX_0, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_WSA_CODEC_DMA_RX_0, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_WSA_CDC_DMA_RX_0}, - { AFE_PORT_ID_WSA_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_WSA_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_WSA_CDC_DMA_TX_0}, - { AFE_PORT_ID_WSA_CODEC_DMA_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_WSA_CODEC_DMA_RX_1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_WSA_CDC_DMA_RX_1}, - { AFE_PORT_ID_WSA_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_WSA_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_WSA_CDC_DMA_TX_1}, - { AFE_PORT_ID_WSA_CODEC_DMA_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_WSA_CODEC_DMA_TX_2, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_WSA_CDC_DMA_TX_2}, - { AFE_PORT_ID_VA_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_VA_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_VA_CDC_DMA_TX_0}, - { AFE_PORT_ID_VA_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_VA_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_VA_CDC_DMA_TX_1}, - { AFE_PORT_ID_RX_CODEC_DMA_RX_0, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_RX_CODEC_DMA_RX_0, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_RX_CDC_DMA_RX_0}, - { AFE_PORT_ID_TX_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TX_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TX_CDC_DMA_TX_0}, - { AFE_PORT_ID_RX_CODEC_DMA_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_RX_CODEC_DMA_RX_1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_RX_CDC_DMA_RX_1}, - { AFE_PORT_ID_TX_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TX_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TX_CDC_DMA_TX_1}, - { AFE_PORT_ID_RX_CODEC_DMA_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_RX_CODEC_DMA_RX_2, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_RX_CDC_DMA_RX_2}, - { AFE_PORT_ID_TX_CODEC_DMA_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TX_CODEC_DMA_TX_2, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TX_CDC_DMA_TX_2}, - { AFE_PORT_ID_RX_CODEC_DMA_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_RX_CODEC_DMA_RX_3, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_RX_CDC_DMA_RX_3}, - { AFE_PORT_ID_TX_CODEC_DMA_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TX_CODEC_DMA_TX_3, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TX_CDC_DMA_TX_3}, - { AFE_PORT_ID_RX_CODEC_DMA_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_RX_CODEC_DMA_RX_4, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_RX_CDC_DMA_RX_4}, - { AFE_PORT_ID_TX_CODEC_DMA_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TX_CODEC_DMA_TX_4, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TX_CDC_DMA_TX_4}, - { AFE_PORT_ID_RX_CODEC_DMA_RX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_RX_CODEC_DMA_RX_5, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_RX_CDC_DMA_RX_5}, - { AFE_PORT_ID_TX_CODEC_DMA_TX_5, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_TX_CODEC_DMA_TX_5, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_TX_CDC_DMA_TX_5}, - { AFE_PORT_ID_RX_CODEC_DMA_RX_6, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_RX_CODEC_DMA_RX_6, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_RX_CDC_DMA_RX_6}, - { AFE_PORT_ID_RX_CODEC_DMA_RX_7, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_RX_CODEC_DMA_RX_7, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_RX_CDC_DMA_RX_7}, - { AFE_PORT_ID_PRIMARY_SPDIF_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_PRIMARY_SPDIF_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PRI_SPDIF_TX}, - { AFE_PORT_ID_SECONDARY_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_SPDIF_RX}, - { AFE_PORT_ID_SECONDARY_SPDIF_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, + { AFE_PORT_ID_SECONDARY_SPDIF_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_SPDIF_TX}, }; @@ -646,128 +646,128 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { static struct msm_pcm_routing_fdai_data fe_dai_map[MSM_FRONTEND_DAI_MAX][2] = { /* MULTIMEDIA1 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA2 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA3 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA4 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA5 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA6 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA7*/ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA8 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA9 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA10 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA11 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA12 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA13 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA14 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA15 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA16 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA17 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA18 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA19 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA20 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA21 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA28 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA29 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* VOIP */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* AFE_RX */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* AFE_TX */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* VOICE_STUB */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* DTMF_RX */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* QCHAT */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* VOLTE_STUB */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* LSM1 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* LSM2 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* LSM3 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* LSM4 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* LSM5 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* LSM6 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* LSM7 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* LSM8 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* VOICE2_STUB */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* VOICEMMODE1 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* VOICEMMODE2 */ - {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, - {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, }; static unsigned long session_copp_map[MSM_FRONTEND_DAI_MAX][2] @@ -1293,12 +1293,6 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, return -EINVAL; } - if (!route_check_fe_id_adm_support(fe_id)) { - /* ignore adm open if not supported for fe_id */ - pr_debug("%s: No ADM support for fe id %d\n", __func__, fe_id); - return 0; - } - if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) { session_type = SESSION_TYPE_RX; if (passthr_mode != LEGACY_PCM) @@ -1322,14 +1316,20 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, (fe_id <= MSM_FRONTEND_DAI_LSM8); mutex_lock(&routing_lock); - payload.num_copps = 0; /* only RX needs to use payload */ fe_dai_map[fe_id][session_type].strm_id = dspst_id; + fe_dai_map[fe_id][session_type].perf_mode = perf_mode; + fe_dai_map[fe_id][session_type].passthr_mode = passthr_mode; + if (!route_check_fe_id_adm_support(fe_id)) { + /* ignore adm open if not supported for fe_id */ + pr_debug("%s: No ADM support for fe id %d\n", __func__, fe_id); + mutex_unlock(&routing_lock); + return 0; + } + + payload.num_copps = 0; /* only RX needs to use payload */ /* re-enable EQ if active */ msm_qti_pp_send_eq_values(fe_id); for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) { - if (test_bit(fe_id, &msm_bedais[i].fe_sessions[0])) - msm_bedais[i].passthr_mode[fe_id] = passthr_mode; - if (!is_be_dai_extproc(i) && (afe_get_port_type(msm_bedais[i].port_id) == port_type) && @@ -1431,8 +1431,7 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, } if (passthr_mode != COMPRESSED_PASSTHROUGH_DSD && passthr_mode != COMPRESSED_PASSTHROUGH_GEN - && passthr_mode != - COMPRESSED_PASSTHROUGH_IEC61937) + && passthr_mode != COMPRESSED_PASSTHROUGH_IEC61937) msm_routing_send_device_pp_params( msm_bedais[i].port_id, copp_idx, fe_id); @@ -1560,6 +1559,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, payload.num_copps = 0; /* only RX needs to use payload */ fe_dai_map[fedai_id][session_type].strm_id = dspst_id; fe_dai_map[fedai_id][session_type].perf_mode = perf_mode; + fe_dai_map[fedai_id][session_type].passthr_mode = LEGACY_PCM; /* re-enable EQ if active */ msm_qti_pp_send_eq_values(fedai_id); @@ -1577,8 +1577,6 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, channels = msm_bedais[i].channel; else channels = msm_bedais[i].adm_override_ch; - msm_bedais[i].passthr_mode[fedai_id] = - LEGACY_PCM; bits_per_sample = msm_routing_get_bit_width( msm_bedais[i].format); @@ -1647,12 +1645,9 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, num_copps++; } } - if ((perf_mode == LEGACY_PCM_MODE) && - (msm_bedais[i].passthr_mode[fedai_id] == - LEGACY_PCM)) + if (perf_mode == LEGACY_PCM_MODE) msm_pcm_routing_cfg_pp(msm_bedais[i].port_id, - copp_idx, topology, - channels); + copp_idx, topology, channels); } } if (num_copps) { @@ -1737,8 +1732,7 @@ void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type) if ((topology == DOLBY_ADM_COPP_TOPOLOGY_ID || topology == DS2_ADM_COPP_TOPOLOGY_ID) && (fdai->perf_mode == LEGACY_PCM_MODE) && - (msm_bedais[i].passthr_mode[fedai_id] == - LEGACY_PCM)) + (fdai->passthr_mode == LEGACY_PCM)) msm_pcm_routing_deinit_pp(msm_bedais[i].port_id, topology); } @@ -1789,16 +1783,17 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) return; } - passthr_mode = msm_bedais[reg].passthr_mode[val]; - if (afe_get_port_type(msm_bedais[reg].port_id) == - MSM_AFE_PORT_TYPE_RX) { - session_type = SESSION_TYPE_RX; + session_type = + (afe_get_port_type(msm_bedais[reg].port_id) == MSM_AFE_PORT_TYPE_RX) ? + SESSION_TYPE_RX : SESSION_TYPE_TX; + fdai = &fe_dai_map[val][session_type]; + passthr_mode = fdai->passthr_mode; + if (session_type == SESSION_TYPE_RX) { if (passthr_mode != LEGACY_PCM) path_type = ADM_PATH_COMPRESSED_RX; else path_type = ADM_PATH_PLAYBACK; } else { - session_type = SESSION_TYPE_TX; if ((passthr_mode != LEGACY_PCM) && (passthr_mode != LISTEN)) path_type = ADM_PATH_COMPRESSED_TX; else @@ -1815,7 +1810,6 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) voc_start_playback(set, msm_bedais[reg].port_id); set_bit(val, &msm_bedais[reg].fe_sessions[0]); - fdai = &fe_dai_map[val][session_type]; if (msm_bedais[reg].active && fdai->strm_id != INVALID_SESSION) { int app_type, app_type_idx, copp_idx, acdb_dev_id; @@ -1913,7 +1907,6 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) (msm_bedais[reg].port_id == VOICE2_PLAYBACK_TX))) voc_start_playback(set, msm_bedais[reg].port_id); clear_bit(val, &msm_bedais[reg].fe_sessions[0]); - fdai = &fe_dai_map[val][session_type]; if (msm_bedais[reg].active && fdai->strm_id != INVALID_SESSION) { int idx; @@ -22405,7 +22398,7 @@ static int msm_pcm_routing_close(struct snd_pcm_substream *substream) clear_bit(idx, &session_copp_map[i][session_type][be_id]); if ((fdai->perf_mode == LEGACY_PCM_MODE) && - (bedai->passthr_mode[i] == LEGACY_PCM)) + (fdai->passthr_mode == LEGACY_PCM)) msm_pcm_routing_deinit_pp(bedai->port_id, topology); } @@ -22414,10 +22407,6 @@ static int msm_pcm_routing_close(struct snd_pcm_substream *substream) bedai->active = 0; bedai->sample_rate = 0; bedai->channel = 0; - for (i = 0; i < MSM_FRONTEND_DAI_MAX; i++) { - if (bedai->passthr_mode[i] != LISTEN) - bedai->passthr_mode[i] = LEGACY_PCM; - } mutex_unlock(&routing_lock); return 0; @@ -22463,24 +22452,24 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) route_check_fe_id_adm_support(i))) continue; + session_type = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? + SESSION_TYPE_RX : SESSION_TYPE_TX; + fdai = &fe_dai_map[i][session_type]; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (bedai->passthr_mode[i] != LEGACY_PCM) + if (fdai->passthr_mode != LEGACY_PCM) path_type = ADM_PATH_COMPRESSED_RX; else path_type = ADM_PATH_PLAYBACK; - session_type = SESSION_TYPE_RX; } else { - if ((bedai->passthr_mode[i] != LEGACY_PCM) && - (bedai->passthr_mode[i] != LISTEN)) + if ((fdai->passthr_mode != LEGACY_PCM) && + (fdai->passthr_mode != LISTEN)) path_type = ADM_PATH_COMPRESSED_TX; else path_type = ADM_PATH_LIVE_REC; - session_type = SESSION_TYPE_TX; } is_lsm = (i >= MSM_FRONTEND_DAI_LSM1) && (i <= MSM_FRONTEND_DAI_LSM8); - fdai = &fe_dai_map[i][session_type]; if (fdai->strm_id != INVALID_SESSION) { int app_type, app_type_idx, copp_idx, acdb_dev_id; @@ -22533,12 +22522,9 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) topology = msm_routing_get_adm_topology(i, session_type, be_id); - if ((bedai->passthr_mode[i] == - COMPRESSED_PASSTHROUGH_DSD) - || (bedai->passthr_mode[i] == - COMPRESSED_PASSTHROUGH_GEN) - || (bedai->passthr_mode[i] == - COMPRESSED_PASSTHROUGH_IEC61937)) + if ((fdai->passthr_mode == COMPRESSED_PASSTHROUGH_DSD) + || (fdai->passthr_mode == COMPRESSED_PASSTHROUGH_GEN) + || (fdai->passthr_mode == COMPRESSED_PASSTHROUGH_IEC61937)) topology = COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY; copp_idx = adm_open(bedai->port_id, path_type, @@ -22564,10 +22550,9 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) bedai->sample_rate); msm_pcm_routing_build_matrix(i, session_type, path_type, - fdai->perf_mode, - bedai->passthr_mode[i]); + fdai->perf_mode, fdai->passthr_mode); if ((fdai->perf_mode == LEGACY_PCM_MODE) && - (bedai->passthr_mode[i] == LEGACY_PCM)) + (fdai->passthr_mode == LEGACY_PCM)) msm_pcm_routing_cfg_pp(bedai->port_id, copp_idx, topology, channels); } @@ -22638,7 +22623,7 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx, int index, topo_id, be_idx; unsigned long pp_config = 0; bool mute_on; - int latency; + int latency, session_type; bool compr_passthr_mode = true; pr_debug("%s: port_id %d, copp_idx %d\n", __func__, port_id, copp_idx); @@ -22676,8 +22661,12 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx, return -EINVAL; } - if ((msm_bedais[be_idx].passthr_mode[fe_id] == LEGACY_PCM) || - (msm_bedais[be_idx].passthr_mode[fe_id] == LISTEN)) + session_type = + (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) ? + SESSION_TYPE_RX : SESSION_TYPE_TX; + + if ((fe_dai_map[fe_id][session_type].passthr_mode == LEGACY_PCM) || + (fe_dai_map[fe_id][session_type].passthr_mode == LISTEN)) compr_passthr_mode = false; pp_config = msm_bedais_pp_params[index].pp_params_config; @@ -22764,7 +22753,7 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol, int port_id = 0; int index, be_idx, i, topo_id, idx; bool mute; - int latency; + int latency, session_type; bool compr_passthr_mode = true; pr_debug("%s: pp_id: 0x%x\n", __func__, pp_id); @@ -22790,10 +22779,14 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol, return -EINVAL; } + session_type = + (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) ? + SESSION_TYPE_RX : SESSION_TYPE_TX; + for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0], MSM_FRONTEND_DAI_MM_SIZE) { - if ((msm_bedais[be_idx].passthr_mode[i] == LEGACY_PCM) || - (msm_bedais[be_idx].passthr_mode[i] == LISTEN)) + if ((fe_dai_map[i][session_type].passthr_mode == LEGACY_PCM) || + (fe_dai_map[i][session_type].passthr_mode == LISTEN)) compr_passthr_mode = false; for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { @@ -22808,7 +22801,7 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol, continue; pr_debug("%s: port: 0x%x, copp %ld, be active: %d, passt: %d\n", __func__, port_id, copp, msm_bedais[be_idx].active, - msm_bedais[be_idx].passthr_mode[i]); + fe_dai_map[i][session_type].passthr_mode); switch (pp_id) { case ADM_PP_PARAM_MUTE_ID: pr_debug("%s: ADM_PP_PARAM_MUTE\n", __func__); diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index b4ff50ff28ee..26a54284e6a9 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -523,7 +523,6 @@ struct msm_pcm_routing_bdai_data { unsigned int channel; unsigned int format; unsigned int adm_override_ch; - u32 passthr_mode[MSM_FRONTEND_DAI_MAX]; char *name; }; @@ -532,6 +531,7 @@ struct msm_pcm_routing_fdai_data { int strm_id; /* ASM stream ID */ int perf_mode; struct msm_pcm_routing_evt event_info; + u32 passthr_mode; }; #define MAX_APP_TYPES 16 -- GitLab From 85e9e160657530b6b416a3d710be580f91921169 Mon Sep 17 00:00:00 2001 From: Siddeswar Aluganti Date: Tue, 25 Sep 2018 19:03:00 -0700 Subject: [PATCH 0537/1645] audio-lnx: ANDROID_BUILD_TOP is deprecated. ANDROID_BUILD_TOP variable is deprecated and thus all paths are assumed to be relative to the top directory. Change-Id: Ifc1bba67bf47092a37336581990d4bcce82a72f5 --- asoc/Android.mk | 2 +- asoc/Kbuild | 2 +- asoc/codecs/Android.mk | 2 +- asoc/codecs/Kbuild | 2 +- asoc/codecs/aqt1000/Android.mk | 2 +- asoc/codecs/aqt1000/Kbuild | 2 +- asoc/codecs/bolero/Kbuild | 2 +- asoc/codecs/csra66x0/Kbuild | 2 +- asoc/codecs/msm_sdw/Android.mk | 2 +- asoc/codecs/msm_sdw/Kbuild | 2 +- asoc/codecs/sdm660_cdc/Android.mk | 2 +- asoc/codecs/sdm660_cdc/Kbuild | 2 +- asoc/codecs/wcd934x/Android.mk | 2 +- asoc/codecs/wcd934x/Kbuild | 2 +- asoc/codecs/wcd9360/Android.mk | 2 +- asoc/codecs/wcd9360/Kbuild | 2 +- dsp/Android.mk | 2 +- dsp/Kbuild | 2 +- dsp/codecs/Android.mk | 2 +- dsp/codecs/Kbuild | 2 +- ipc/Android.mk | 2 +- soc/Android.mk | 2 +- soc/Kbuild | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/asoc/Android.mk b/asoc/Android.mk index a5d1c7edad3c..8ca497c3c376 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -33,7 +33,7 @@ LOCAL_PATH := $(call my-dir) ifneq ($(findstring vendor,$(LOCAL_PATH)),) ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel endif # opensource DLKM_DIR := $(TOP)/device/qcom/common/dlkm diff --git a/asoc/Kbuild b/asoc/Kbuild index 311fbae090e9..acf8e844da5a 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -9,7 +9,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index a35a64bb7b5d..cbe1615b2b29 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -29,7 +29,7 @@ LOCAL_PATH := $(call my-dir) ifneq ($(findstring vendor,$(LOCAL_PATH)),) ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel endif # opensource DLKM_DIR := $(TOP)/device/qcom/common/dlkm diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 45018ed6700b..ade1e477a0b8 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -9,7 +9,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/aqt1000/Android.mk b/asoc/codecs/aqt1000/Android.mk index 7de1a63def8c..ac26f6d52469 100644 --- a/asoc/codecs/aqt1000/Android.mk +++ b/asoc/codecs/aqt1000/Android.mk @@ -10,7 +10,7 @@ LOCAL_PATH := $(call my-dir) ifneq ($(findstring vendor,$(LOCAL_PATH)),) ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel endif # opensource DLKM_DIR := $(TOP)/device/qcom/common/dlkm diff --git a/asoc/codecs/aqt1000/Kbuild b/asoc/codecs/aqt1000/Kbuild index 6523ce6d6b09..60ac86649e0a 100644 --- a/asoc/codecs/aqt1000/Kbuild +++ b/asoc/codecs/aqt1000/Kbuild @@ -9,7 +9,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild index dee3463a2459..d6c2eea3ec8d 100644 --- a/asoc/codecs/bolero/Kbuild +++ b/asoc/codecs/bolero/Kbuild @@ -11,7 +11,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/csra66x0/Kbuild b/asoc/codecs/csra66x0/Kbuild index c23811c23a65..bb26a384ec4f 100644 --- a/asoc/codecs/csra66x0/Kbuild +++ b/asoc/codecs/csra66x0/Kbuild @@ -10,7 +10,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/msm_sdw/Android.mk b/asoc/codecs/msm_sdw/Android.mk index 338e7f450221..7ec659200c94 100644 --- a/asoc/codecs/msm_sdw/Android.mk +++ b/asoc/codecs/msm_sdw/Android.mk @@ -13,7 +13,7 @@ LOCAL_PATH := $(call my-dir) ifneq ($(findstring vendor,$(LOCAL_PATH)),) ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel endif # opensource DLKM_DIR := $(TOP)/device/qcom/common/dlkm diff --git a/asoc/codecs/msm_sdw/Kbuild b/asoc/codecs/msm_sdw/Kbuild index f687cddf5155..46639d29f011 100644 --- a/asoc/codecs/msm_sdw/Kbuild +++ b/asoc/codecs/msm_sdw/Kbuild @@ -10,7 +10,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.9 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/sdm660_cdc/Android.mk b/asoc/codecs/sdm660_cdc/Android.mk index 43a5645fdf64..41f3cc7bc81f 100644 --- a/asoc/codecs/sdm660_cdc/Android.mk +++ b/asoc/codecs/sdm660_cdc/Android.mk @@ -12,7 +12,7 @@ LOCAL_PATH := $(call my-dir) ifneq ($(findstring vendor,$(LOCAL_PATH)),) ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel endif # opensource DLKM_DIR := $(TOP)/device/qcom/common/dlkm diff --git a/asoc/codecs/sdm660_cdc/Kbuild b/asoc/codecs/sdm660_cdc/Kbuild index 6c379e1bfc70..cbbc0c784493 100644 --- a/asoc/codecs/sdm660_cdc/Kbuild +++ b/asoc/codecs/sdm660_cdc/Kbuild @@ -10,7 +10,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.9 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/wcd934x/Android.mk b/asoc/codecs/wcd934x/Android.mk index 6b5cca55e922..90a012dbab1f 100644 --- a/asoc/codecs/wcd934x/Android.mk +++ b/asoc/codecs/wcd934x/Android.mk @@ -29,7 +29,7 @@ LOCAL_PATH := $(call my-dir) ifneq ($(findstring vendor,$(LOCAL_PATH)),) ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel endif # opensource DLKM_DIR := $(TOP)/device/qcom/common/dlkm diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index 5566ecbb26fb..26d9af61fa9e 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -11,7 +11,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.9 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/wcd9360/Android.mk b/asoc/codecs/wcd9360/Android.mk index bee0364ecd41..492061265f26 100644 --- a/asoc/codecs/wcd9360/Android.mk +++ b/asoc/codecs/wcd9360/Android.mk @@ -17,7 +17,7 @@ LOCAL_PATH := $(call my-dir) ifneq ($(findstring vendor,$(LOCAL_PATH)),) ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel endif # opensource DLKM_DIR := $(TOP)/device/qcom/common/dlkm diff --git a/asoc/codecs/wcd9360/Kbuild b/asoc/codecs/wcd9360/Kbuild index 6bba0c525599..5282b3442408 100644 --- a/asoc/codecs/wcd9360/Kbuild +++ b/asoc/codecs/wcd9360/Kbuild @@ -11,7 +11,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/dsp/Android.mk b/dsp/Android.mk index 48b068c732f5..23c0cc9669e3 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -29,7 +29,7 @@ LOCAL_PATH := $(call my-dir) ifneq ($(findstring vendor,$(LOCAL_PATH)),) ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel endif # opensource DLKM_DIR := $(TOP)/device/qcom/common/dlkm diff --git a/dsp/Kbuild b/dsp/Kbuild index ba5f82cb71ac..7081ceb0d246 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -9,7 +9,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/dsp/codecs/Android.mk b/dsp/codecs/Android.mk index 69af58eefdf5..0c969dbafc50 100644 --- a/dsp/codecs/Android.mk +++ b/dsp/codecs/Android.mk @@ -29,7 +29,7 @@ LOCAL_PATH := $(call my-dir) ifneq ($(findstring vendor,$(LOCAL_PATH)),) ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel endif # opensource DLKM_DIR := $(TOP)/device/qcom/common/dlkm diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 7d7268b694ee..0f1f519f4137 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -9,7 +9,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/ipc/Android.mk b/ipc/Android.mk index fe9ce0f54915..942a1866a0db 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -29,7 +29,7 @@ LOCAL_PATH := $(call my-dir) ifneq ($(findstring vendor,$(LOCAL_PATH)),) ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel endif # opensource DLKM_DIR := $(TOP)/device/qcom/common/dlkm diff --git a/soc/Android.mk b/soc/Android.mk index dc6a5b32f822..972b8ad261f3 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -29,7 +29,7 @@ LOCAL_PATH := $(call my-dir) ifneq ($(findstring vendor,$(LOCAL_PATH)),) ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel endif # opensource DLKM_DIR := $(TOP)/device/qcom/common/dlkm diff --git a/soc/Kbuild b/soc/Kbuild index 54ca077e4936..eedf6f1fbbda 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -9,7 +9,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif -- GitLab From 0c79439a2f7790a161f09ab22b82987fd82752cb Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 25 Sep 2018 17:41:30 -0700 Subject: [PATCH 0538/1645] dsp: codecs: check buffer size before copy check audio node buffer size if it is sufficient enough to copy the meta data before copying the meta data contents to it. Change-Id: I0bd67bddf902659ddd533a6f0d9440e873d51329 Signed-off-by: Karthikeyan Mani --- dsp/codecs/audio_utils_aio.c | 12 +++++++++--- dsp/codecs/audio_utils_aio.h | 2 +- dsp/codecs/q6audio_v2_aio.c | 19 ++++++++++++++----- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c index 298a77d0d401..445bd3f72784 100644 --- a/dsp/codecs/audio_utils_aio.c +++ b/dsp/codecs/audio_utils_aio.c @@ -1181,7 +1181,13 @@ static int audio_aio_buf_add_shared(struct q6audio_aio *audio, u32 dir, kfree(buf_node); return -EINVAL; } - extract_meta_out_info(audio, buf_node, 1); + ret = extract_meta_out_info(audio, buf_node, 1); + if (ret) { + pr_debug("%s: extract meta failed with %d\n", + __func__, ret); + kfree(buf_node); + return ret; + } /* Not a EOS buffer */ if (!(buf_node->meta_info.meta_in.nflags & AUDIO_DEC_EOS_SET)) { spin_lock_irqsave(&audio->dsp_lock, flags); @@ -1683,7 +1689,7 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, case AUDIO_SET_CONFIG: { struct msm_audio_config config; - pr_err("%s[%pK]:AUDIO_SET_CONFIG\n", __func__, audio); + pr_debug("%s[%pK]:AUDIO_SET_CONFIG\n", __func__, audio); mutex_lock(&audio->lock); if (copy_from_user(&config, (void *)arg, sizeof(config))) { pr_err( @@ -2010,7 +2016,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, mutex_unlock(&audio->lock); break; } - pr_err("%s[%pK]:AUDIO_SET_CONFIG\n", __func__, audio); + pr_debug("%s[%pK]:AUDIO_SET_CONFIG\n", __func__, audio); if (copy_from_user(&config_32, (void *)arg, sizeof(config_32))) { pr_err("%s: copy_from_user for AUDIO_SET_CONFIG_32 failed\n", diff --git a/dsp/codecs/audio_utils_aio.h b/dsp/codecs/audio_utils_aio.h index 1993f6047ef1..bd99c3680697 100644 --- a/dsp/codecs/audio_utils_aio.h +++ b/dsp/codecs/audio_utils_aio.h @@ -210,7 +210,7 @@ void audio_aio_async_read_ack(struct q6audio_aio *audio, uint32_t token, int insert_eos_buf(struct q6audio_aio *audio, struct audio_aio_buffer_node *buf_node); -void extract_meta_out_info(struct q6audio_aio *audio, +int extract_meta_out_info(struct q6audio_aio *audio, struct audio_aio_buffer_node *buf_node, int dir); int audio_aio_open(struct q6audio_aio *audio, struct file *file); diff --git a/dsp/codecs/q6audio_v2_aio.c b/dsp/codecs/q6audio_v2_aio.c index 9f764587888b..973108de9d78 100644 --- a/dsp/codecs/q6audio_v2_aio.c +++ b/dsp/codecs/q6audio_v2_aio.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -118,19 +118,26 @@ void audio_aio_cb(uint32_t opcode, uint32_t token, } } -void extract_meta_out_info(struct q6audio_aio *audio, +int extract_meta_out_info(struct q6audio_aio *audio, struct audio_aio_buffer_node *buf_node, int dir) { struct dec_meta_out *meta_data = buf_node->kvaddr; uint32_t temp; if (dir) { /* input buffer - Write */ - if (audio->buf_cfg.meta_info_enable) + if (audio->buf_cfg.meta_info_enable) { + if (buf_node->buf.buf_len < + sizeof(struct dec_meta_in)) { + pr_debug("%s: invalid buf len %d\n", + __func__, buf_node->buf.buf_len); + return -EINVAL; + } memcpy(&buf_node->meta_info.meta_in, (char *)buf_node->kvaddr, sizeof(struct dec_meta_in)); - else + } else { memset(&buf_node->meta_info.meta_in, 0, sizeof(struct dec_meta_in)); + } pr_debug("%s[%pK]:i/p: msw_ts %d lsw_ts %d nflags 0x%8x\n", __func__, audio, buf_node->meta_info.meta_in.ntimestamp.highpart, @@ -156,6 +163,7 @@ void extract_meta_out_info(struct q6audio_aio *audio, meta_out_dsp[0].nflags, ((struct dec_meta_out *)buf_node->kvaddr)->num_of_frames); } + return 0; } /* Read buffer from DSP / Handle Ack from DSP */ @@ -165,6 +173,7 @@ void audio_aio_async_read_ack(struct q6audio_aio *audio, uint32_t token, unsigned long flags; union msm_audio_event_payload event_payload; struct audio_aio_buffer_node *filled_buf; + int ret; pr_debug("%s\n", __func__); @@ -208,7 +217,7 @@ void audio_aio_async_read_ack(struct q6audio_aio *audio, uint32_t token, __func__, audio, filled_buf->meta_info.meta_out.num_of_frames, event_payload.aio_buf.data_len); - extract_meta_out_info(audio, filled_buf, 0); + ret = extract_meta_out_info(audio, filled_buf, 0); audio->eos_rsp = 0; } pr_debug("%s, posting read done to the app here\n", __func__); -- GitLab From 2ce6784865b18eda56c8dd836eefca807c5a74f0 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Tue, 25 Sep 2018 16:40:29 -0700 Subject: [PATCH 0539/1645] asoc: update log level to avoid execessive logging Excessive logging causes throttling during bootup. Update log level from error to debug in get functions to avoid excessive logging. CRs-Fixed: 2321589 Change-Id: If2a23144adf76cdd9bb2d9048a967b63186d7f6e Signed-off-by: Vignesh Kulothungan --- asoc/msm-compress-q6-v2.c | 2 +- asoc/msm-dai-q6-hdmi-v2.c | 2 +- asoc/msm-dai-q6-v2.c | 2 +- asoc/msm-pcm-loopback-v2.c | 4 ++-- asoc/msm-pcm-q6-noirq.c | 2 +- asoc/msm-pcm-q6-v2.c | 4 ++-- asoc/msm-pcm-routing-v2.c | 10 +++++----- asoc/msm-qti-pp-config.c | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 6fb61da19536..e429a5420bb6 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -3284,7 +3284,7 @@ static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol, cstream = pdata->cstream[fe_id]; audio_effects = pdata->audio_effects[fe_id]; if (!cstream || !audio_effects) { - pr_err("%s: stream or effects inactive\n", __func__); + pr_debug("%s: stream or effects inactive\n", __func__); return -EINVAL; } prtd = cstream->runtime->private_data; diff --git a/asoc/msm-dai-q6-hdmi-v2.c b/asoc/msm-dai-q6-hdmi-v2.c index bcf21b5d9b7b..4291077fcbb9 100644 --- a/asoc/msm-dai-q6-hdmi-v2.c +++ b/asoc/msm-dai-q6-hdmi-v2.c @@ -180,7 +180,7 @@ static int msm_dai_q6_ext_disp_drift_get(struct snd_kcontrol *kcontrol, struct msm_dai_q6_hdmi_dai_data *dai_data = dev_get_drvdata(dai->dev); if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { - pr_err("%s: afe port not started. status_mask = %ld\n", + pr_debug("%s: afe port not started. status_mask = %ld\n", __func__, *dai_data->status_mask); goto done; } diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 742457c1ef34..fc9e4f5263df 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -3077,7 +3077,7 @@ static int msm_dai_q6_slim_rx_drift_get(struct snd_kcontrol *kcontrol, struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { - pr_err("%s: afe port not started. dai_data->status_mask = %ld\n", + pr_debug("%s: afe port not started. dai_data->status_mask = %ld\n", __func__, *dai_data->status_mask); goto done; } diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index 1c26d1966b24..32c727aca14a 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -517,7 +517,7 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, pr_debug("%s\n", __func__); if ((!substream) || (!substream->runtime)) { - pr_err("%s substream or runtime not found\n", __func__); + pr_debug("%s substream or runtime not found\n", __func__); rc = -ENODEV; goto exit; } diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index c89efb9773bd..be34903d929d 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -670,7 +670,7 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, return -ENODEV; } if (!substream->runtime) { - pr_err("%s substream runtime not found\n", __func__); + pr_debug("%s substream runtime not found\n", __func__); return 0; } prtd = substream->runtime->private_data; diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index f40769b4b8d9..0b312fe36e91 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1301,7 +1301,7 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, return -ENODEV; } if (!substream->runtime) { - pr_err("%s substream runtime not found\n", __func__); + pr_debug("%s substream runtime not found\n", __func__); return 0; } prtd = substream->runtime->private_data; @@ -1388,7 +1388,7 @@ static int msm_pcm_compress_ctl_get(struct snd_kcontrol *kcontrol, return -EINVAL; } if (!substream->runtime) { - pr_err("%s substream runtime not found\n", __func__); + pr_debug("%s substream runtime not found\n", __func__); return 0; } prtd = substream->runtime->private_data; diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 9e445946bbf0..1d1a26709fc1 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -17017,7 +17017,7 @@ static int msm_voice_sound_focus_get(struct snd_kcontrol *kcontrol, ret = voc_get_sound_focus(&soundFocusData); if (ret) { - pr_err("%s: Error getting Sound Focus Params, err=%d\n", + pr_debug("%s: Error getting Sound Focus Params, err=%d\n", __func__, ret); ret = -EINVAL; @@ -17049,7 +17049,7 @@ static int msm_voice_source_tracking_get(struct snd_kcontrol *kcontrol, ret = voc_get_source_tracking(&sourceTrackingData); if (ret) { - pr_err("%s: Error getting Source Tracking Params, err=%d\n", + pr_debug("%s: Error getting Source Tracking Params, err=%d\n", __func__, ret); ret = -EINVAL; @@ -17105,7 +17105,7 @@ static int msm_audio_get_copp_idx_from_port_id(int port_id, int session_type, break; } if (i >= MSM_FRONTEND_DAI_MM_SIZE) { - pr_err("%s: Invalid FE, exiting\n", __func__); + pr_debug("%s: Invalid FE, exiting\n", __func__); ret = -EINVAL; goto done; @@ -17221,7 +17221,7 @@ static int msm_audio_sound_focus_get(struct snd_kcontrol *kcontrol, ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, &copp_idx); if (ret) { - pr_err("%s: Could not get copp idx for port_id=%d\n", + pr_debug("%s: Could not get copp idx for port_id=%d\n", __func__, port_id); ret = -EINVAL; @@ -17264,7 +17264,7 @@ static int msm_audio_source_tracking_get(struct snd_kcontrol *kcontrol, ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, &copp_idx); if (ret) { - pr_err("%s: Could not get copp idx for port_id=%d\n", + pr_debug("%s: Could not get copp idx for port_id=%d\n", __func__, port_id); ret = -EINVAL; diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index 7d64da66edbf..0923d0a6357d 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -1259,7 +1259,7 @@ int msm_adsp_stream_callback_get(struct snd_kcontrol *kcontrol, kctl_prtd = (struct dsp_stream_callback_prtd *) kcontrol->private_data; if (kctl_prtd == NULL) { - pr_err("%s: ASM Stream PP event queue is not initialized.\n", + pr_debug("%s: ASM Stream PP event queue is not initialized.\n", __func__); ret = -EINVAL; goto done; -- GitLab From debe893b7c6492f9e38a6548e005208faa8162da Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Tue, 25 Sep 2018 18:08:18 +0530 Subject: [PATCH 0540/1645] soc: swr-mstr: Enable required soundwire master interrupts Enable soundwire master interrupts by setting the interrupt enable bits in new CPU_n interrupt register. Change-Id: Iec2502129cd04da2c8cbc3d3f43278a2ed3ba7d6 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 7232fe83caa8..c48397a281b1 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1273,6 +1273,12 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) case SWR_ATTACHED_OK: dev_dbg(swrm->dev, "device %d got attached\n", devnum); + /* enable host irq from slave device*/ + swrm_cmd_fifo_wr_cmd(swrm, 0xFF, devnum, 0x0, + SWRS_SCP_INT_STATUS_CLEAR_1); + swrm_cmd_fifo_wr_cmd(swrm, 0x4, devnum, 0x0, + SWRS_SCP_INT_STATUS_MASK_1); + break; case SWR_ALERT: dev_dbg(swrm->dev, @@ -1409,11 +1415,6 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, dev_dbg(swrm->dev, "%s: devnum %d is assigned for dev addr %lx\n", __func__, i, swr_dev->addr); - swrm_cmd_fifo_wr_cmd(swrm, 0xFF, i, 0xF, - SWRS_SCP_INT_STATUS_CLEAR_1); - swrm_cmd_fifo_wr_cmd(swrm, 0x4, i, 0xF, - SWRS_SCP_INT_STATUS_MASK_1); - } } } @@ -1477,7 +1478,7 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) value[len++] = 0x1FFFD; reg[len] = SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN; - value[len++] = 0x1; + value[len++] = 0x1FFFD; swr_master_bulk_write(swrm, reg, value, len); -- GitLab From 7b9cdb66e6d1234f3cfe41514cd4a15de9fb06d8 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 28 Sep 2018 16:28:54 +0530 Subject: [PATCH 0541/1645] asoc: bolero: Fix slow playback on HPH After switching from native to non-native clip, observe slowness in clip playback content heard on headphones. Update mclk_mux for enable sequence based on native flag and for disable sequence use the same setting done during enable. CRs-Fixed: 2322232 Change-Id: I795e0620e0239b53cdfdadaf2d57acfb570c4c3b Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 6c936cbc014c..4c45b80bb489 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -970,11 +970,11 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, dev_dbg(rx_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", __func__, mclk_enable, dapm, rx_priv->rx_mclk_users); - if (rx_priv->is_native_on) - mclk_mux = MCLK_MUX1; mutex_lock(&rx_priv->mclk_lock); if (mclk_enable) { if (rx_priv->rx_mclk_users == 0) { + if (rx_priv->is_native_on) + mclk_mux = MCLK_MUX1; ret = bolero_request_clock(rx_priv->dev, RX_MACRO, mclk_mux, true); if (ret < 0) { @@ -1014,6 +1014,7 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, regmap_update_bits(regmap, BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x00); + mclk_mux = rx_priv->mclk_mux; bolero_request_clock(rx_priv->dev, RX_MACRO, mclk_mux, false); rx_priv->mclk_mux = MCLK_MUX0; -- GitLab From f4feb27287336f94cbee7573479d9348b6789483 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Wed, 19 Sep 2018 12:45:37 +0530 Subject: [PATCH 0542/1645] asoc: add support for TDM mics on QCS405 Add Quinary TDM for enabling TDM mics. Change-Id: I4a4c74fc38c3c44ae594399103622ffa008d9566 Signed-off-by: Mangesh Kunchamwar --- asoc/msm-dai-q6-v2.c | 83 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 742457c1ef34..1164f6f7b499 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -7140,6 +7140,9 @@ static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai, /* HW supports 1-32 slots configuration. Typical: 1, 2, 4, 8, 16, 32 */ switch (slots) { + case 1: + cap_mask = 0x01; + break; case 2: cap_mask = 0x03; break; @@ -7761,6 +7764,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "PRI_TDM_RX_0", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_PRIMARY_TDM_RX, .probe = msm_dai_q6_dai_tdm_probe, @@ -7781,6 +7785,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "PRI_TDM_RX_1", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_PRIMARY_TDM_RX_1, .probe = msm_dai_q6_dai_tdm_probe, @@ -7801,6 +7806,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "PRI_TDM_RX_2", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_PRIMARY_TDM_RX_2, .probe = msm_dai_q6_dai_tdm_probe, @@ -7821,6 +7827,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "PRI_TDM_RX_3", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_PRIMARY_TDM_RX_3, .probe = msm_dai_q6_dai_tdm_probe, @@ -7841,6 +7848,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "PRI_TDM_RX_4", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_PRIMARY_TDM_RX_4, .probe = msm_dai_q6_dai_tdm_probe, @@ -7861,6 +7869,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "PRI_TDM_RX_5", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_PRIMARY_TDM_RX_5, .probe = msm_dai_q6_dai_tdm_probe, @@ -7881,6 +7890,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "PRI_TDM_RX_6", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_PRIMARY_TDM_RX_6, .probe = msm_dai_q6_dai_tdm_probe, @@ -7901,6 +7911,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "PRI_TDM_RX_7", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_PRIMARY_TDM_RX_7, .probe = msm_dai_q6_dai_tdm_probe, @@ -7921,6 +7932,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "PRI_TDM_TX_0", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_PRIMARY_TDM_TX, .probe = msm_dai_q6_dai_tdm_probe, @@ -7941,6 +7953,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "PRI_TDM_TX_1", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_PRIMARY_TDM_TX_1, .probe = msm_dai_q6_dai_tdm_probe, @@ -7961,6 +7974,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "PRI_TDM_TX_2", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_PRIMARY_TDM_TX_2, .probe = msm_dai_q6_dai_tdm_probe, @@ -7981,6 +7995,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "PRI_TDM_TX_3", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_PRIMARY_TDM_TX_3, .probe = msm_dai_q6_dai_tdm_probe, @@ -8001,6 +8016,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "PRI_TDM_TX_4", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_PRIMARY_TDM_TX_4, .probe = msm_dai_q6_dai_tdm_probe, @@ -8021,6 +8037,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "PRI_TDM_TX_5", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_PRIMARY_TDM_TX_5, .probe = msm_dai_q6_dai_tdm_probe, @@ -8041,6 +8058,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "PRI_TDM_TX_6", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_PRIMARY_TDM_TX_6, .probe = msm_dai_q6_dai_tdm_probe, @@ -8061,6 +8079,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "PRI_TDM_TX_7", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_PRIMARY_TDM_TX_7, .probe = msm_dai_q6_dai_tdm_probe, @@ -8081,6 +8100,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "SEC_TDM_RX_0", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_SECONDARY_TDM_RX, .probe = msm_dai_q6_dai_tdm_probe, @@ -8101,6 +8121,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "SEC_TDM_RX_1", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_SECONDARY_TDM_RX_1, .probe = msm_dai_q6_dai_tdm_probe, @@ -8121,6 +8142,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "SEC_TDM_RX_2", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_SECONDARY_TDM_RX_2, .probe = msm_dai_q6_dai_tdm_probe, @@ -8141,6 +8163,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "SEC_TDM_RX_3", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_SECONDARY_TDM_RX_3, .probe = msm_dai_q6_dai_tdm_probe, @@ -8161,6 +8184,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "SEC_TDM_RX_4", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_SECONDARY_TDM_RX_4, .probe = msm_dai_q6_dai_tdm_probe, @@ -8181,6 +8205,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "SEC_TDM_RX_5", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_SECONDARY_TDM_RX_5, .probe = msm_dai_q6_dai_tdm_probe, @@ -8201,6 +8226,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "SEC_TDM_RX_6", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_SECONDARY_TDM_RX_6, .probe = msm_dai_q6_dai_tdm_probe, @@ -8221,6 +8247,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "SEC_TDM_RX_7", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_SECONDARY_TDM_RX_7, .probe = msm_dai_q6_dai_tdm_probe, @@ -8241,6 +8268,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "SEC_TDM_TX_0", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_SECONDARY_TDM_TX, .probe = msm_dai_q6_dai_tdm_probe, @@ -8261,6 +8289,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "SEC_TDM_TX_1", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_SECONDARY_TDM_TX_1, .probe = msm_dai_q6_dai_tdm_probe, @@ -8281,6 +8310,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "SEC_TDM_TX_2", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_SECONDARY_TDM_TX_2, .probe = msm_dai_q6_dai_tdm_probe, @@ -8301,6 +8331,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "SEC_TDM_TX_3", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_SECONDARY_TDM_TX_3, .probe = msm_dai_q6_dai_tdm_probe, @@ -8321,6 +8352,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "SEC_TDM_TX_4", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_SECONDARY_TDM_TX_4, .probe = msm_dai_q6_dai_tdm_probe, @@ -8341,6 +8373,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "SEC_TDM_TX_5", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_SECONDARY_TDM_TX_5, .probe = msm_dai_q6_dai_tdm_probe, @@ -8361,6 +8394,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "SEC_TDM_TX_6", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_SECONDARY_TDM_TX_6, .probe = msm_dai_q6_dai_tdm_probe, @@ -8381,6 +8415,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "SEC_TDM_TX_7", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_SECONDARY_TDM_TX_7, .probe = msm_dai_q6_dai_tdm_probe, @@ -8401,6 +8436,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "TERT_TDM_RX_0", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_TERTIARY_TDM_RX, .probe = msm_dai_q6_dai_tdm_probe, @@ -8421,6 +8457,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "TERT_TDM_RX_1", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_TERTIARY_TDM_RX_1, .probe = msm_dai_q6_dai_tdm_probe, @@ -8441,6 +8478,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "TERT_TDM_RX_2", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_TERTIARY_TDM_RX_2, .probe = msm_dai_q6_dai_tdm_probe, @@ -8461,6 +8499,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "TERT_TDM_RX_3", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_TERTIARY_TDM_RX_3, .probe = msm_dai_q6_dai_tdm_probe, @@ -8481,6 +8520,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "TERT_TDM_RX_4", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_TERTIARY_TDM_RX_4, .probe = msm_dai_q6_dai_tdm_probe, @@ -8501,6 +8541,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "TERT_TDM_RX_5", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_TERTIARY_TDM_RX_5, .probe = msm_dai_q6_dai_tdm_probe, @@ -8521,6 +8562,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "TERT_TDM_RX_6", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_TERTIARY_TDM_RX_6, .probe = msm_dai_q6_dai_tdm_probe, @@ -8541,6 +8583,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "TERT_TDM_RX_7", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_TERTIARY_TDM_RX_7, .probe = msm_dai_q6_dai_tdm_probe, @@ -8561,6 +8604,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "TERT_TDM_TX_0", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_TERTIARY_TDM_TX, .probe = msm_dai_q6_dai_tdm_probe, @@ -8581,6 +8625,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "TERT_TDM_TX_1", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_TERTIARY_TDM_TX_1, .probe = msm_dai_q6_dai_tdm_probe, @@ -8601,6 +8646,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "TERT_TDM_TX_2", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_TERTIARY_TDM_TX_2, .probe = msm_dai_q6_dai_tdm_probe, @@ -8621,6 +8667,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "TERT_TDM_TX_3", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_TERTIARY_TDM_TX_3, .probe = msm_dai_q6_dai_tdm_probe, @@ -8641,6 +8688,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "TERT_TDM_TX_4", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_TERTIARY_TDM_TX_4, .probe = msm_dai_q6_dai_tdm_probe, @@ -8661,6 +8709,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "TERT_TDM_TX_5", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_TERTIARY_TDM_TX_5, .probe = msm_dai_q6_dai_tdm_probe, @@ -8681,6 +8730,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "TERT_TDM_TX_6", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_TERTIARY_TDM_TX_6, .probe = msm_dai_q6_dai_tdm_probe, @@ -8701,6 +8751,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "TERT_TDM_TX_7", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_TERTIARY_TDM_TX_7, .probe = msm_dai_q6_dai_tdm_probe, @@ -8721,6 +8772,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUAT_TDM_RX_0", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUATERNARY_TDM_RX, .probe = msm_dai_q6_dai_tdm_probe, @@ -8741,6 +8793,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUAT_TDM_RX_1", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUATERNARY_TDM_RX_1, .probe = msm_dai_q6_dai_tdm_probe, @@ -8761,6 +8814,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUAT_TDM_RX_2", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUATERNARY_TDM_RX_2, .probe = msm_dai_q6_dai_tdm_probe, @@ -8781,6 +8835,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUAT_TDM_RX_3", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUATERNARY_TDM_RX_3, .probe = msm_dai_q6_dai_tdm_probe, @@ -8801,6 +8856,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUAT_TDM_RX_4", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUATERNARY_TDM_RX_4, .probe = msm_dai_q6_dai_tdm_probe, @@ -8821,6 +8877,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUAT_TDM_RX_5", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUATERNARY_TDM_RX_5, .probe = msm_dai_q6_dai_tdm_probe, @@ -8841,6 +8898,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUAT_TDM_RX_6", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUATERNARY_TDM_RX_6, .probe = msm_dai_q6_dai_tdm_probe, @@ -8861,6 +8919,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUAT_TDM_RX_7", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUATERNARY_TDM_RX_7, .probe = msm_dai_q6_dai_tdm_probe, @@ -8881,6 +8940,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUAT_TDM_TX_0", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUATERNARY_TDM_TX, .probe = msm_dai_q6_dai_tdm_probe, @@ -8901,6 +8961,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUAT_TDM_TX_1", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUATERNARY_TDM_TX_1, .probe = msm_dai_q6_dai_tdm_probe, @@ -8921,6 +8982,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUAT_TDM_TX_2", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUATERNARY_TDM_TX_2, .probe = msm_dai_q6_dai_tdm_probe, @@ -8941,6 +9003,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUAT_TDM_TX_3", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUATERNARY_TDM_TX_3, .probe = msm_dai_q6_dai_tdm_probe, @@ -8961,6 +9024,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUAT_TDM_TX_4", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUATERNARY_TDM_TX_4, .probe = msm_dai_q6_dai_tdm_probe, @@ -8981,6 +9045,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUAT_TDM_TX_5", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUATERNARY_TDM_TX_5, .probe = msm_dai_q6_dai_tdm_probe, @@ -9001,6 +9066,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUAT_TDM_TX_6", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUATERNARY_TDM_TX_6, .probe = msm_dai_q6_dai_tdm_probe, @@ -9021,6 +9087,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUAT_TDM_TX_7", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUATERNARY_TDM_TX_7, .probe = msm_dai_q6_dai_tdm_probe, @@ -9041,6 +9108,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUIN_TDM_RX_0", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUINARY_TDM_RX, .probe = msm_dai_q6_dai_tdm_probe, @@ -9061,6 +9129,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUIN_TDM_RX_1", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUINARY_TDM_RX_1, .probe = msm_dai_q6_dai_tdm_probe, @@ -9081,6 +9150,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUIN_TDM_RX_2", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUINARY_TDM_RX_2, .probe = msm_dai_q6_dai_tdm_probe, @@ -9101,6 +9171,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUIN_TDM_RX_3", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUINARY_TDM_RX_3, .probe = msm_dai_q6_dai_tdm_probe, @@ -9121,6 +9192,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUIN_TDM_RX_4", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUINARY_TDM_RX_4, .probe = msm_dai_q6_dai_tdm_probe, @@ -9141,6 +9213,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUIN_TDM_RX_5", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUINARY_TDM_RX_5, .probe = msm_dai_q6_dai_tdm_probe, @@ -9161,6 +9234,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUIN_TDM_RX_6", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUINARY_TDM_RX_6, .probe = msm_dai_q6_dai_tdm_probe, @@ -9181,6 +9255,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUIN_TDM_RX_7", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUINARY_TDM_RX_7, .probe = msm_dai_q6_dai_tdm_probe, @@ -9201,6 +9276,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUIN_TDM_TX_0", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUINARY_TDM_TX, .probe = msm_dai_q6_dai_tdm_probe, @@ -9221,6 +9297,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUIN_TDM_TX_1", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUINARY_TDM_TX_1, .probe = msm_dai_q6_dai_tdm_probe, @@ -9241,6 +9318,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUIN_TDM_TX_2", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUINARY_TDM_TX_2, .probe = msm_dai_q6_dai_tdm_probe, @@ -9261,6 +9339,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUIN_TDM_TX_3", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUINARY_TDM_TX_3, .probe = msm_dai_q6_dai_tdm_probe, @@ -9281,6 +9360,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUIN_TDM_TX_4", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUINARY_TDM_TX_4, .probe = msm_dai_q6_dai_tdm_probe, @@ -9301,6 +9381,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUIN_TDM_TX_5", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUINARY_TDM_TX_5, .probe = msm_dai_q6_dai_tdm_probe, @@ -9321,6 +9402,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUIN_TDM_TX_6", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUINARY_TDM_TX_6, .probe = msm_dai_q6_dai_tdm_probe, @@ -9341,6 +9423,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .rate_min = 8000, .rate_max = 352800, }, + .name = "QUIN_TDM_TX_7", .ops = &msm_dai_q6_tdm_ops, .id = AFE_PORT_ID_QUINARY_TDM_TX_7, .probe = msm_dai_q6_dai_tdm_probe, -- GitLab From 52a8c3f76fdbe8df63a716d73257a8f71e5f4154 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Wed, 19 Sep 2018 13:17:01 +0530 Subject: [PATCH 0543/1645] asoc: msm: routing: add support TDM Mics in routing driver Add Quinary TDM support to enable TDM Mics in QCS405. Change-Id: I7ce8f4e53bc37c4cf88eb0d15f8233db94ab4c63 Signed-off-by: Mangesh Kunchamwar --- asoc/msm-pcm-routing-v2.c | 89 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 1c9ad1a9d4ba..1b8404a47456 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -114,6 +114,7 @@ enum { #define VA_CDC_DMA_TX_0_TEXT "VA_CDC_DMA_TX_0" #define VA_CDC_DMA_TX_1_TEXT "VA_CDC_DMA_TX_1" #define TX_CDC_DMA_TX_3_TEXT "TX_CDC_DMA_TX_3" +#define QUIN_TDM_TX_TEXT "QUIN_TDM_TX_0" #define LSM_FUNCTION_TEXT "LSM Function" static const char * const lsm_port_text[] = { @@ -122,7 +123,7 @@ static const char * const lsm_port_text[] = { SLIMBUS_3_TX_TEXT, SLIMBUS_4_TX_TEXT, SLIMBUS_5_TX_TEXT, TERT_MI2S_TX_TEXT, QUAT_MI2S_TX_TEXT, ADM_LSM_TX_TEXT, INT3_MI2S_TX_TEXT, VA_CDC_DMA_TX_0_TEXT, VA_CDC_DMA_TX_1_TEXT, - TX_CDC_DMA_TX_3_TEXT + TX_CDC_DMA_TX_3_TEXT, QUIN_TDM_TX_TEXT }; struct msm_pcm_route_bdai_pp_params { @@ -2662,6 +2663,9 @@ static int msm_routing_lsm_port_put(struct snd_kcontrol *kcontrol, case 13: lsm_port = AFE_PORT_ID_TX_CODEC_DMA_TX_3; break; + case 14: + lsm_port = AFE_PORT_ID_QUINARY_TDM_TX; + break; default: pr_err("Default lsm port"); break; @@ -2709,6 +2713,10 @@ static int msm_routing_lsm_func_get(struct snd_kcontrol *kcontrol, strlen(lsm_port_text[13]))) port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3; + if (strnstr(kcontrol->id.name, lsm_port_text[14], + strlen(lsm_port_text[14]))) + port_id = AFE_PORT_ID_QUINARY_TDM_TX; + mad_type = afe_port_get_mad_type(port_id); pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, mad_type); @@ -2792,6 +2800,10 @@ static int msm_routing_lsm_func_put(struct snd_kcontrol *kcontrol, strlen(lsm_port_text[13]))) port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3; + if (strnstr(kcontrol->id.name, lsm_port_text[14], + strlen(lsm_port_text[14]))) + port_id = AFE_PORT_ID_QUINARY_TDM_TX; + pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, mad_type); return afe_port_set_mad_type(port_id, mad_type); @@ -16005,6 +16017,10 @@ static const struct snd_kcontrol_new lsm1_mixer_controls[] = { MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm2_mixer_controls[] = { @@ -16053,6 +16069,10 @@ static const struct snd_kcontrol_new lsm2_mixer_controls[] = { MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm3_mixer_controls[] = { @@ -16100,6 +16120,10 @@ static const struct snd_kcontrol_new lsm3_mixer_controls[] = { MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm4_mixer_controls[] = { @@ -16147,6 +16171,10 @@ static const struct snd_kcontrol_new lsm4_mixer_controls[] = { MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm5_mixer_controls[] = { @@ -16194,6 +16222,10 @@ static const struct snd_kcontrol_new lsm5_mixer_controls[] = { MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm6_mixer_controls[] = { @@ -16241,6 +16273,10 @@ static const struct snd_kcontrol_new lsm6_mixer_controls[] = { MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm7_mixer_controls[] = { @@ -16288,6 +16324,10 @@ static const struct snd_kcontrol_new lsm7_mixer_controls[] = { MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm8_mixer_controls[] = { @@ -16335,6 +16375,10 @@ static const struct snd_kcontrol_new lsm8_mixer_controls[] = { MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new slim_fm_switch_mixer_controls = @@ -16473,6 +16517,8 @@ static const struct snd_kcontrol_new lsm_controls[] = { msm_routing_lsm_func_get, msm_routing_lsm_func_put), SOC_ENUM_EXT(TX_CDC_DMA_TX_3_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(QUIN_TDM_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), /* kcontrol of lsm_port */ SOC_ENUM_EXT("LSM1 Port", lsm_port_enum, msm_routing_lsm_port_get, @@ -17137,6 +17183,9 @@ static int msm_audio_sound_focus_derive_port_id(struct snd_kcontrol *kcontrol, } else if (!strcmp(kcontrol->id.name + strlen(prefix), "TX_CDC_DMA_TX_3")) { *port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "QUIN_TDM_TX_0")) { + *port_id = AFE_PORT_ID_QUINARY_TDM_TX; } else { pr_err("%s: mixer ctl name=%s, could not derive valid port id\n", __func__, kcontrol->id.name); @@ -17431,6 +17480,36 @@ static const struct snd_kcontrol_new msm_source_tracking_controls[] = { .info = msm_source_tracking_info, .get = msm_audio_source_tracking_get, }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx QUIN_TDM_TX_0", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx QUIN_TDM_TX_0", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx QUIN_TDM_TX_0", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx QUIN_TDM_TX_0", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, }; static int spkr_prot_put_vi_lch_port(struct snd_kcontrol *kcontrol, @@ -21266,6 +21345,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"LSM1 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM1 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"LSM1_UL_HL", NULL, "LSM1 Mixer"}, {"LSM2 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -21279,6 +21359,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"LSM2 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM2 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"LSM2_UL_HL", NULL, "LSM2 Mixer"}, @@ -21293,6 +21374,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"LSM3 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM3 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"LSM3_UL_HL", NULL, "LSM3 Mixer"}, @@ -21307,6 +21389,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"LSM4 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM4 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"LSM4_UL_HL", NULL, "LSM4 Mixer"}, {"LSM5 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -21320,6 +21403,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"LSM5 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM5 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"LSM5_UL_HL", NULL, "LSM5 Mixer"}, {"LSM6 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -21331,6 +21415,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"LSM6 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM6 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"LSM6_UL_HL", NULL, "LSM6 Mixer"}, {"LSM7 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -21342,6 +21427,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM7 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM7 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"LSM7 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM7 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"LSM7_UL_HL", NULL, "LSM7 Mixer"}, {"LSM8 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -21353,6 +21439,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"LSM8 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM8 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"LSM8_UL_HL", NULL, "LSM8 Mixer"}, -- GitLab From 638b56027e5890046567680d4914d7109adfae6a Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 24 Sep 2018 13:19:52 +0530 Subject: [PATCH 0544/1645] asoc: codecs: add ignore suspend for bolero and wcd937x widgets Update ignore suspend for AIF in/out and dapm input/output widgets for bolero and wcd937x codecs to avoid suspend of codec during active usecase running even after APSS goes to suspend. CRs-Fixed: 2321226 Change-Id: I277129e8e657485c56414a385150c4da55382770 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 13 +++++++++++++ asoc/codecs/bolero/tx-macro.c | 17 +++++++++++++++++ asoc/codecs/bolero/va-macro.c | 16 ++++++++++++++++ asoc/codecs/bolero/wsa-macro.c | 11 +++++++++++ asoc/codecs/wcd937x/wcd937x.c | 21 +++++++++++++++++++++ 5 files changed, 78 insertions(+) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 6c936cbc014c..1b042cbb8433 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -3027,6 +3027,19 @@ static int rx_macro_init(struct snd_soc_codec *codec) dev_err(rx_dev, "%s: failed to add snd_ctls\n", __func__); return ret; } + snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF1 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF2 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF3 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF4 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "HPHL_OUT"); + snd_soc_dapm_ignore_suspend(dapm, "HPHR_OUT"); + snd_soc_dapm_ignore_suspend(dapm, "AUX_OUT"); + snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC0_INP"); + snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC1_INP"); + snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC2_INP"); + snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC3_INP"); + snd_soc_dapm_sync(dapm); + snd_soc_update_bits(codec, BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL, 0x01, 0x01); snd_soc_update_bits(codec, BOLERO_CDC_RX_RX1_RX_PATH_DSM_CTL, 0x01, 0x01); snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL, 0x01, 0x01); diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 44826de51f54..09dd3b097b01 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1521,6 +1521,23 @@ static int tx_macro_init(struct snd_soc_codec *codec) dev_err(tx_dev, "%s: Failed to add snd_ctls\n", __func__); return ret; } + + snd_soc_dapm_ignore_suspend(dapm, "TX_AIF1 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "TX_AIF2 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC0"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC1"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC2"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC3"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC0"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC1"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC2"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC3"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC4"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC5"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC6"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC7"); + snd_soc_dapm_sync(dapm); + for (i = 0; i < NUM_DECIMATORS; i++) { tx_priv->tx_hpf_work[i].tx_priv = tx_priv; tx_priv->tx_hpf_work[i].decimator = i; diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 1d28e411fa1a..0bbdc68be334 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -1454,6 +1454,22 @@ static int va_macro_init(struct snd_soc_codec *codec) return ret; } + snd_soc_dapm_ignore_suspend(dapm, "VA_AIF1 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "VA_AIF2 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC0"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC1"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC2"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC3"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC0"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC1"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC2"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC3"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC4"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC5"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC6"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC7"); + snd_soc_dapm_sync(dapm); + for (i = 0; i < VA_MACRO_NUM_DECIMATORS; i++) { va_priv->va_hpf_work[i].va_priv = va_priv; va_priv->va_hpf_work[i].decimator = i; diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index d5271865b2f5..9a6dff35ea17 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -2511,6 +2511,17 @@ static int wsa_macro_init(struct snd_soc_codec *codec) dev_err(wsa_dev, "%s: Failed to add snd_ctls\n", __func__); return ret; } + snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF1 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_MIX1 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_VI Capture"); + snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_ECHO Capture"); + snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK1 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK2 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_WSA"); + snd_soc_dapm_ignore_suspend(dapm, "WSA SRC0_INP"); + snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC0_INP"); + snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC1_INP"); + snd_soc_dapm_sync(dapm); wsa_priv->codec = codec; wsa_priv->spkr_gain_offset = WSA_MACRO_GAIN_OFFSET_0_DB; diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 0bdfda1a52f6..79b17d9e08c5 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1885,6 +1885,19 @@ static int wcd937x_soc_codec_probe(struct snd_soc_codec *codec) pr_err("%s: mbhc initialization failed\n", __func__); goto err_hwdep; } + snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "IN1_HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "IN2_HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "IN3_AUX"); + snd_soc_dapm_ignore_suspend(dapm, "ADC1_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "ADC2_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "EAR"); + snd_soc_dapm_ignore_suspend(dapm, "AUX"); + snd_soc_dapm_ignore_suspend(dapm, "HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "HPHR"); + snd_soc_dapm_sync(dapm); wcd937x_init_reg(codec); @@ -1903,6 +1916,14 @@ static int wcd937x_soc_codec_probe(struct snd_soc_codec *codec) __func__); goto err_hwdep; } + snd_soc_dapm_ignore_suspend(dapm, "AMIC4"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC1_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC2_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC3_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC4_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC5_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC6_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "ADC3_OUTPUT"); snd_soc_dapm_sync(dapm); } wcd937x->version = WCD937X_VERSION_1_0; -- GitLab From 62d6d76b8171ec5afc699bd0f5e2e14f74d429e1 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Thu, 20 Sep 2018 17:50:28 +0530 Subject: [PATCH 0545/1645] soc: swr-mstr: Add logic to recursively trigger slave irq handler Soundwire slave interrupt is only edge type, so any pending slave side interrupts could not cause a new slave interrupt, if they are triggered before clearing of existing interrupts. Recursively trigger slave irq until there are no pending slave interrupts to handle this issue. Change-Id: I254f2467f09172490796114b48f1f0feb604ad17 Signed-off-by: Ramprasad Katkam --- include/soc/soundwire.h | 1 + soc/swr-mstr-ctrl.c | 28 +++++++++++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/include/soc/soundwire.h b/include/soc/soundwire.h index 279642816072..3bc3332af4c1 100644 --- a/include/soc/soundwire.h +++ b/include/soc/soundwire.h @@ -208,6 +208,7 @@ struct swr_device { unsigned long addr; u8 group_id; struct irq_domain *slave_irq; + bool slave_irq_pending; }; static inline struct swr_device *to_swr_device(struct device *dev) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 7232fe83caa8..0a1c2520c397 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1237,20 +1237,26 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) spurious interrupt\n"); return ret; } - list_for_each_entry(swr_dev, &mstr->devices, dev_list) { - if (swr_dev->dev_num != devnum) - continue; - if (swr_dev->slave_irq) - handle_nested_irq( - irq_find_mapping( - swr_dev->slave_irq, 0)); - } swrm_cmd_fifo_rd_cmd(swrm, &temp, devnum, 0x0, SWRS_SCP_INT_STATUS_CLEAR_1, 1); swrm_cmd_fifo_wr_cmd(swrm, 0x4, devnum, 0x0, SWRS_SCP_INT_STATUS_CLEAR_1); swrm_cmd_fifo_wr_cmd(swrm, 0x0, devnum, 0x0, SWRS_SCP_INT_STATUS_CLEAR_1); + + + list_for_each_entry(swr_dev, &mstr->devices, dev_list) { + if (swr_dev->dev_num != devnum) + continue; + if (swr_dev->slave_irq) { + do { + handle_nested_irq( + irq_find_mapping( + swr_dev->slave_irq, 0)); + } while (swr_dev->slave_irq_pending); + } + + } break; case SWRM_INTERRUPT_STATUS_NEW_SLAVE_ATTACHED: dev_dbg(swrm->dev, "SWR new slave attached\n"); @@ -1465,9 +1471,9 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) reg[len] = SWRM_MCP_BUS_CTRL_ADDR; value[len++] = 0x2; - /* Set IRQ to PULSE */ + /* Set IRQ to LEVEL */ reg[len] = SWRM_COMP_CFG_ADDR; - value[len++] = 0x03; + value[len++] = 0x01; reg[len] = SWRM_INTERRUPT_CLEAR; value[len++] = 0xFFFFFFFF; @@ -1722,7 +1728,7 @@ static int swrm_probe(struct platform_device *pdev) ret = request_threaded_irq(swrm->irq, NULL, swr_mstr_interrupt, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "swr_master_irq", swrm); if (ret) { dev_err(swrm->dev, "%s: Failed to request irq %d\n", -- GitLab From 55ec68ca3c55be9ae5c43c7137c087eb466f84a0 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Thu, 20 Sep 2018 17:57:03 +0530 Subject: [PATCH 0546/1645] asoc: wcd937x: clear interrupts using regmap irq framework Add proper way to clear interrupts using regmap irq framework, to avoid mismatch between interrupts handled and interrupts cleared. wcd937x requires writing '1' and then '0' to clear interrupt. Set a new regmap irq flag 'clear_ack' to indicate this. Change-Id: I1346dc66735d3b5788e1cc0cfef772c9deacbfc1 Signed-off-by: Ramprasad Katkam --- asoc/codecs/wcd937x/wcd937x.c | 38 +++++++++-------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 0bdfda1a52f6..9d777427e269 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -81,6 +81,9 @@ static struct regmap_irq_chip wcd937x_regmap_irq_chip = { .num_regs = 3, .status_base = WCD937X_DIGITAL_INTR_STATUS_0, .mask_base = WCD937X_DIGITAL_INTR_MASK_0, + .ack_base = WCD937X_DIGITAL_INTR_CLEAR_0, + .use_ack = 1, + .clear_ack = 1, .type_base = WCD937X_DIGITAL_INTR_LEVEL_0, .runtime_pm = false, .handle_post_irq = wcd937x_handle_post_irq, @@ -89,35 +92,14 @@ static struct regmap_irq_chip wcd937x_regmap_irq_chip = { static int wcd937x_handle_post_irq(void *data) { struct wcd937x_priv *wcd937x = data; - int val = 0; - struct wcd937x_pdata *pdata = NULL; + u32 status1 = 0, status2 = 0, status3 = 0; + + regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_0, &status1); + regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_1, &status2); + regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_2, &status3); - pdata = dev_get_platdata(wcd937x->dev); - - regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_0, &val); - dev_dbg(wcd937x->dev, "%s Clear OCP interupts\n", __func__); - regmap_write(wcd937x->regmap, - WCD937X_DIGITAL_INTR_CLEAR_0, 0xFF); - regmap_write(wcd937x->regmap, - WCD937X_DIGITAL_INTR_CLEAR_0, 0x0); - regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_1, &val); - dev_dbg(wcd937x->dev, "%s Clear SCD interupts\n", __func__); - regmap_write(wcd937x->regmap, - WCD937X_DIGITAL_INTR_CLEAR_1, 0xFF); - regmap_write(wcd937x->regmap, - WCD937X_DIGITAL_INTR_CLEAR_1, 0x0); - - regmap_write(wcd937x->regmap, - WCD937X_DIGITAL_INTR_CLEAR_2, 0xFF); - regmap_write(wcd937x->regmap, - WCD937X_DIGITAL_INTR_CLEAR_2, 0x0); - - regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_0, &val); - regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_1, &val); - regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_STATUS_2, &val); - regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_0, &val); - regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_1, &val); - regmap_read(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_2, &val); + wcd937x->tx_swr_dev->slave_irq_pending = + ((status1 || status2 || status3) ? true : false); return IRQ_HANDLED; } -- GitLab From 2498e397f4d3ba18fa13ba1015f7377c4cfa9ebc Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 1 Sep 2018 04:33:47 +0530 Subject: [PATCH 0547/1645] ASoC: wcd934x: Avoid soundwire enable when codec is in power collapse During SSR, when the playback on speaker gets started before codec is out of digital core power collapse, results in soundwire register read/write failures. Check for codec power state before enabling the soundwire during speaker device path enablement for playback usecase to avoid soundwire register read/write failures. Change-Id: I3b45ef0c34ad4f97aad89afaf719989ffbda7485 Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd934x/wcd934x.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 2a6d829f2443..34868fa1d6b5 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -2974,6 +2974,11 @@ static int __tavil_codec_enable_swr(struct snd_soc_dapm_widget *w, int event) tavil->swr.rx_8_count++; ch_cnt = !!(tavil->swr.rx_7_count) + tavil->swr.rx_8_count; + if (wcd9xxx_get_current_power_state(tavil->wcd9xxx, + WCD9XXX_DIG_CORE_REGION_1) + != WCD_REGION_POWER_COLLAPSE_REMOVE) + goto done; + swrm_wcd_notify(tavil->swr.ctrl_data[0].swr_pdev, SWR_DEVICE_UP, NULL); swrm_wcd_notify(tavil->swr.ctrl_data[0].swr_pdev, @@ -2994,6 +2999,7 @@ static int __tavil_codec_enable_swr(struct snd_soc_dapm_widget *w, int event) break; } +done: dev_dbg(tavil->dev, "%s: %s: current swr ch cnt: %d\n", __func__, w->name, ch_cnt); -- GitLab From 6af0c159a1bb75d2aa089c66bc6493fff1446c97 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Thu, 20 Sep 2018 18:01:39 +0530 Subject: [PATCH 0548/1645] asoc: wcd-irq: Use non-sync disable irq api wcd interrupts can be disabled in the same interrupt context. So use non-sync disable irq api for disabling the interrupts to avoid a deadlock. Change-Id: I82dda8dbcd80ba18674eea00686f6a4f54a3b340 Signed-off-by: Ramprasad Katkam --- asoc/codecs/wcd-irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/wcd-irq.c b/asoc/codecs/wcd-irq.c index 12bbf36a5209..48495f553999 100644 --- a/asoc/codecs/wcd-irq.c +++ b/asoc/codecs/wcd-irq.c @@ -101,7 +101,7 @@ void wcd_disable_irq(struct wcd_irq_info *irq_info, int irq) if (!irq_info) pr_err("%s: Null IRQ handle\n", __func__); else - disable_irq(wcd_map_irq(irq_info, irq)); + disable_irq_nosync(wcd_map_irq(irq_info, irq)); } EXPORT_SYMBOL(wcd_disable_irq); -- GitLab From 8fb467f199a9a4384b9982f88c9698dc0332d692 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Tue, 2 Oct 2018 14:26:24 -0700 Subject: [PATCH 0549/1645] soc: make snd_event stub functions as static inline Modify snd_event stub functions prototype as static inline to make sure that there are no multiple definition errors in the case of static compilation. Change-Id: I0848be946b332df22c045b8e5fed4c39b7ee0fda Signed-off-by: Vidyakumar Athota --- include/soc/snd_event.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/soc/snd_event.h b/include/soc/snd_event.h index af566735343e..835941126e02 100644 --- a/include/soc/snd_event.h +++ b/include/soc/snd_event.h @@ -38,39 +38,39 @@ inline bool is_snd_event_fwk_enabled(void) return 1; } #else -int snd_event_client_register(struct device *dev, +static inline int snd_event_client_register(struct device *dev, const struct snd_event_ops *snd_ev_ops, void *data) { return 0; } -int snd_event_client_deregister(struct device *dev) +static inline int snd_event_client_deregister(struct device *dev) { return 0; } -int snd_event_master_register(struct device *dev, +static inline int snd_event_master_register(struct device *dev, const struct snd_event_ops *ops, struct snd_event_clients *clients, void *data) { return 0; } -int snd_event_master_deregister(struct device *dev) +static inline int snd_event_master_deregister(struct device *dev) { return 0; } -int snd_event_notify(struct device *dev, unsigned int state) +static inline int snd_event_notify(struct device *dev, unsigned int state) { return 0; } -void snd_event_mstr_add_client(struct snd_event_clients **snd_clients, +static inline void snd_event_mstr_add_client(struct snd_event_clients **snd_clients, int (*compare)(struct device *, void *), void *data) { return; } -inline bool is_snd_event_fwk_enabled(void) +static inline bool is_snd_event_fwk_enabled(void) { return 0; } -- GitLab From eada51564ed16e0f48918b4f95466315746c470d Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Wed, 19 Sep 2018 13:18:32 +0530 Subject: [PATCH 0550/1645] asoc: qcs405: add TDM Mics support Add Quinary TDM support in QCS405 machine driver. Change-Id: I36dcc27422124f55efb2c19bf0c73963c16c695c Signed-off-by: Mangesh Kunchamwar --- asoc/qcs405.c | 401 ++++++++++++++++++++------------------------------ 1 file changed, 161 insertions(+), 240 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index b075a21a33ed..a051f2c40f65 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -176,32 +177,20 @@ struct msm_csra66x0_dev_info { u32 index; }; -enum pinctrl_pin_state { - STATE_DISABLE = 0, /* All pins are in sleep state */ - STATE_MI2S_ACTIVE, /* I2S = active, TDM = sleep */ - STATE_TDM_ACTIVE, /* I2S = sleep, TDM = active */ -}; - -struct msm_pinctrl_info { - struct pinctrl *pinctrl; - struct pinctrl_state *mi2s_disable; - struct pinctrl_state *tdm_disable; - struct pinctrl_state *mi2s_active; - struct pinctrl_state *tdm_active; - enum pinctrl_pin_state curr_state; -}; - struct msm_asoc_mach_data { struct snd_info_entry *codec_root; - struct msm_pinctrl_info pinctrl_info; struct device_node *dmic_01_gpio_p; /* used by pinctrl API */ struct device_node *dmic_23_gpio_p; /* used by pinctrl API */ struct device_node *dmic_45_gpio_p; /* used by pinctrl API */ struct device_node *dmic_67_gpio_p; /* used by pinctrl API */ + struct device_node *mi2s_gpio_p[MI2S_MAX]; /* used by pinctrl API */ int dmic_01_gpio_cnt; int dmic_23_gpio_cnt; int dmic_45_gpio_cnt; int dmic_67_gpio_cnt; + struct regulator *tdm_micb_supply; + u32 tdm_micb_voltage; + u32 tdm_micb_current; }; struct msm_asoc_wcd93xx_codec { @@ -5074,164 +5063,6 @@ static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) return ret; } -static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, - enum pinctrl_pin_state new_state) -{ - int ret = 0; - int curr_state = 0; - - if (pinctrl_info == NULL) { - pr_err("%s: pinctrl_info is NULL\n", __func__); - ret = -EINVAL; - goto err; - } - - if (pinctrl_info->pinctrl == NULL) { - pr_err("%s: pinctrl_info->pinctrl is NULL\n", __func__); - ret = -EINVAL; - goto err; - } - - curr_state = pinctrl_info->curr_state; - pinctrl_info->curr_state = new_state; - pr_debug("%s: curr_state = %s new_state = %s\n", __func__, - pin_states[curr_state], pin_states[pinctrl_info->curr_state]); - - if (curr_state == pinctrl_info->curr_state) { - pr_debug("%s: Already in same state\n", __func__); - goto err; - } - - if (curr_state != STATE_DISABLE && - pinctrl_info->curr_state != STATE_DISABLE) { - pr_debug("%s: state already active cannot switch\n", __func__); - ret = -EIO; - goto err; - } - - switch (pinctrl_info->curr_state) { - case STATE_MI2S_ACTIVE: - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_active); - if (ret) { - pr_err("%s: MI2S state select failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - break; - case STATE_TDM_ACTIVE: - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->tdm_active); - if (ret) { - pr_err("%s: TDM state select failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - break; - case STATE_DISABLE: - if (curr_state == STATE_MI2S_ACTIVE) { - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_disable); - } else { - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->tdm_disable); - } - if (ret) { - pr_err("%s: state disable failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - break; - default: - pr_err("%s: TLMM pin state is invalid\n", __func__); - return -EINVAL; - } - -err: - return ret; -} - -static void msm_release_pinctrl(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - - if (pinctrl_info->pinctrl) { - devm_pinctrl_put(pinctrl_info->pinctrl); - pinctrl_info->pinctrl = NULL; - } -} - -static int msm_get_pinctrl(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = NULL; - struct pinctrl *pinctrl; - int ret; - - pinctrl_info = &pdata->pinctrl_info; - - if (pinctrl_info == NULL) { - pr_err("%s: pinctrl_info is NULL\n", __func__); - return -EINVAL; - } - - pinctrl = devm_pinctrl_get(&pdev->dev); - if (IS_ERR_OR_NULL(pinctrl)) { - pr_err("%s: Unable to get pinctrl handle\n", __func__); - return -EINVAL; - } - pinctrl_info->pinctrl = pinctrl; - - /* get all the states handles from Device Tree */ - pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl, - "quat-mi2s-sleep"); - if (IS_ERR(pinctrl_info->mi2s_disable)) { - pr_err("%s: could not get mi2s_disable pinstate\n", __func__); - goto err; - } - pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl, - "quat-mi2s-active"); - if (IS_ERR(pinctrl_info->mi2s_active)) { - pr_err("%s: could not get mi2s_active pinstate\n", __func__); - goto err; - } - pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl, - "quat-tdm-sleep"); - if (IS_ERR(pinctrl_info->tdm_disable)) { - pr_err("%s: could not get tdm_disable pinstate\n", __func__); - goto err; - } - pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl, - "quat-tdm-active"); - if (IS_ERR(pinctrl_info->tdm_active)) { - pr_err("%s: could not get tdm_active pinstate\n", - __func__); - goto err; - } - /* Reset the TLMM pins to a default state */ - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_disable); - if (ret != 0) { - pr_err("%s: Disable TLMM pins failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - pinctrl_info->curr_state = STATE_DISABLE; - - return 0; - -err: - devm_pinctrl_put(pinctrl); - pinctrl_info->pinctrl = NULL; - return -EINVAL; -} static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) @@ -5281,7 +5112,7 @@ static int qcs405_tdm_snd_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret = 0; int slot_width = 32; - int channels, slots; + int channels, slots = 8; unsigned int slot_mask, rate, clk_freq; unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; @@ -5290,34 +5121,34 @@ static int qcs405_tdm_snd_hw_params(struct snd_pcm_substream *substream, /* currently only supporting TDM_RX_0 and TDM_TX_0 */ switch (cpu_dai->id) { case AFE_PORT_ID_PRIMARY_TDM_RX: - slots = tdm_rx_cfg[TDM_PRI][TDM_0].channels; + channels = tdm_rx_cfg[TDM_PRI][TDM_0].channels; break; case AFE_PORT_ID_SECONDARY_TDM_RX: - slots = tdm_rx_cfg[TDM_SEC][TDM_0].channels; + channels = tdm_rx_cfg[TDM_SEC][TDM_0].channels; break; case AFE_PORT_ID_TERTIARY_TDM_RX: - slots = tdm_rx_cfg[TDM_TERT][TDM_0].channels; + channels = tdm_rx_cfg[TDM_TERT][TDM_0].channels; break; case AFE_PORT_ID_QUATERNARY_TDM_RX: - slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + channels = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; break; case AFE_PORT_ID_QUINARY_TDM_RX: - slots = tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + channels = tdm_rx_cfg[TDM_QUIN][TDM_0].channels; break; case AFE_PORT_ID_PRIMARY_TDM_TX: - slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels; + channels = tdm_tx_cfg[TDM_PRI][TDM_0].channels; break; case AFE_PORT_ID_SECONDARY_TDM_TX: - slots = tdm_tx_cfg[TDM_SEC][TDM_0].channels; + channels = tdm_tx_cfg[TDM_SEC][TDM_0].channels; break; case AFE_PORT_ID_TERTIARY_TDM_TX: - slots = tdm_tx_cfg[TDM_TERT][TDM_0].channels; + channels = tdm_tx_cfg[TDM_TERT][TDM_0].channels; break; case AFE_PORT_ID_QUATERNARY_TDM_TX: - slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + channels = tdm_tx_cfg[TDM_QUAT][TDM_0].channels; break; case AFE_PORT_ID_QUINARY_TDM_TX: - slots = tdm_tx_cfg[TDM_QUIN][TDM_0].channels; + channels = tdm_tx_cfg[TDM_QUIN][TDM_0].channels; break; default: @@ -5328,8 +5159,7 @@ static int qcs405_tdm_snd_hw_params(struct snd_pcm_substream *substream, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { /*2 slot config - bits 0 and 1 set for the first two slots */ - slot_mask = 0x0000FFFF >> (16-slots); - channels = slots; + slot_mask = 0x0000FFFF >> (16-channels); pr_debug("%s: tdm rx slot_width %d slots %d\n", __func__, slot_width, slots); @@ -5351,8 +5181,7 @@ static int qcs405_tdm_snd_hw_params(struct snd_pcm_substream *substream, } } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { /*2 slot config - bits 0 and 1 set for the first two slots */ - slot_mask = 0x0000FFFF >> (16-slots); - channels = slots; + slot_mask = 0x0000FFFF >> (16-channels); pr_debug("%s: tdm tx slot_width %d slots %d\n", __func__, slot_width, slots); @@ -5390,6 +5219,38 @@ static int qcs405_tdm_snd_hw_params(struct snd_pcm_substream *substream, return ret; } +static int msm_get_tdm_mode(u32 port_id) +{ + u32 tdm_mode; + + switch (port_id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_TX: + tdm_mode = TDM_PRI; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_TX: + tdm_mode = TDM_SEC; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_TX: + tdm_mode = TDM_TERT; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + tdm_mode = TDM_QUAT; + break; + case AFE_PORT_ID_QUINARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_TX: + tdm_mode = TDM_QUIN; + break; + default: + pr_err("%s: Invalid port id: %d\n", __func__, port_id); + tdm_mode = -EINVAL; + } + return tdm_mode; +} + static int qcs405_tdm_snd_startup(struct snd_pcm_substream *substream) { int ret = 0; @@ -5397,17 +5258,50 @@ static int qcs405_tdm_snd_startup(struct snd_pcm_substream *substream) struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + u32 tdm_mode = msm_get_tdm_mode(cpu_dai->id); - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || - (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { - ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); + if (tdm_mode >= TDM_INTERFACE_MAX) { + ret = -EINVAL; + pr_err("%s: Invalid TDM interface %d\n", + __func__, ret); + return ret; + } + + if (pdata->mi2s_gpio_p[tdm_mode]) { + ret = msm_cdc_pinctrl_select_active_state( + pdata->mi2s_gpio_p[tdm_mode]); if (ret) - pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + pr_err("%s: TDM GPIO pinctrl set active failed with %d\n", __func__, ret); } + /* Enable Mic bias for TDM Mics */ + if (cpu_dai->id == AFE_PORT_ID_QUINARY_TDM_TX) { + if (pdata->tdm_micb_supply) { + ret = regulator_set_voltage(pdata->tdm_micb_supply, + pdata->tdm_micb_voltage, + pdata->tdm_micb_voltage); + if (ret) { + pr_err("%s: Setting voltage failed, err = %d\n", + __func__, ret); + return ret; + } + ret = regulator_set_load(pdata->tdm_micb_supply, + pdata->tdm_micb_current); + if (ret) { + pr_err("%s: Setting current failed, err = %d\n", + __func__, ret); + return ret; + } + ret = regulator_enable(pdata->tdm_micb_supply); + if (ret) { + pr_err("%s: regulator enable failed, err = %d\n", + __func__, ret); + return ret; + } + } + } + return ret; } @@ -5418,14 +5312,25 @@ static void qcs405_tdm_snd_shutdown(struct snd_pcm_substream *substream) struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + u32 tdm_mode = msm_get_tdm_mode(cpu_dai->id); - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || - (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { - ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); + if (cpu_dai->id == AFE_PORT_ID_QUINARY_TDM_TX) { + if (pdata->tdm_micb_supply) { + ret = regulator_disable(pdata->tdm_micb_supply); + if (ret) + pr_err("%s: regulator disable failed, err = %d\n", + __func__, ret); + regulator_set_voltage(pdata->tdm_micb_supply, 0, + pdata->tdm_micb_voltage); + regulator_set_load(pdata->tdm_micb_supply, 0); + } + } + + if (pdata->mi2s_gpio_p[tdm_mode]) { + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->mi2s_gpio_p[tdm_mode]); if (ret) - pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + pr_err("%s: TDM GPIO pinctrl set sleep failed with %d\n", __func__, ret); } } @@ -5469,8 +5374,6 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - int ret_pinctrl = 0; dev_dbg(rtd->card->dev, "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", @@ -5510,13 +5413,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) __func__, index, ret); goto clk_off; } - if (index == QUAT_MI2S) { - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_MI2S_ACTIVE); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); - } + if (pdata->mi2s_gpio_p[index]) + msm_cdc_pinctrl_select_active_state( + pdata->mi2s_gpio_p[index]); } clk_off: if (ret < 0) @@ -5536,8 +5435,6 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) int index = rtd->cpu_dai->id; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - int ret_pinctrl = 0; pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); @@ -5548,17 +5445,14 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) mutex_lock(&mi2s_intf_conf[index].lock); if (--mi2s_intf_conf[index].ref_cnt == 0) { + if (pdata->mi2s_gpio_p[index]) + msm_cdc_pinctrl_select_sleep_state( + pdata->mi2s_gpio_p[index]); + ret = msm_mi2s_set_sclk(substream, false); if (ret < 0) pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", __func__, index, ret); - if (index == QUAT_MI2S) { - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_DISABLE); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); - } } mutex_unlock(&mi2s_intf_conf[index].lock); } @@ -8342,6 +8236,10 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) struct msm_asoc_mach_data *pdata; int ret; u32 val; + const char *micb_supply_str = "tdm-vdd-micb-supply"; + const char *micb_supply_str1 = "tdm-vdd-micb"; + const char *micb_voltage_str = "qcom,tdm-vdd-micb-voltage"; + const char *micb_current_str = "qcom,tdm-vdd-micb-current"; if (!pdev->dev.of_node) { dev_err(&pdev->dev, "No platform supplied from device tree\n"); @@ -8404,17 +8302,53 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) } pdata->dmic_01_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,cdc-dmic01-gpios", - 0); + "qcom,cdc-dmic01-gpios", 0); pdata->dmic_23_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,cdc-dmic23-gpios", - 0); + "qcom,cdc-dmic23-gpios", 0); pdata->dmic_45_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,cdc-dmic45-gpios", - 0); + "qcom,cdc-dmic45-gpios", 0); pdata->dmic_67_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,cdc-dmic67-gpios", - 0); + "qcom,cdc-dmic67-gpios", 0); + + pdata->mi2s_gpio_p[PRIM_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,pri-mi2s-gpios", 0); + pdata->mi2s_gpio_p[SEC_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,sec-mi2s-gpios", 0); + pdata->mi2s_gpio_p[TERT_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,tert-mi2s-gpios", 0); + pdata->mi2s_gpio_p[QUAT_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,quat-mi2s-gpios", 0); + pdata->mi2s_gpio_p[QUIN_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,quin-mi2s-gpios", 0); + + if (of_parse_phandle(pdev->dev.of_node, micb_supply_str, 0)) { + pdata->tdm_micb_supply = devm_regulator_get(&pdev->dev, + micb_supply_str1); + if (IS_ERR(pdata->tdm_micb_supply)) { + ret = PTR_ERR(pdata->tdm_micb_supply); + dev_err(&pdev->dev, + "%s:Failed to get micbias supply for TDM Mic %d\n", + __func__, ret); + } + ret = of_property_read_u32(pdev->dev.of_node, + micb_voltage_str, + &pdata->tdm_micb_voltage); + if (ret) { + dev_err(&pdev->dev, + "%s:Looking up %s property in node %s failed\n", + __func__, micb_voltage_str, + pdev->dev.of_node->full_name); + } + ret = of_property_read_u32(pdev->dev.of_node, + micb_current_str, + &pdata->tdm_micb_current); + if (ret) { + dev_err(&pdev->dev, + "%s:Looking up %s property in node %s failed\n", + __func__, micb_current_str, + pdev->dev.of_node->full_name); + } + } ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret == -EPROBE_DEFER) { @@ -8434,23 +8368,11 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) dev_err(&pdev->dev, "msm_mdf_mem_init failed (%d)\n", ret); - /* Parse pinctrl info from devicetree */ - ret = msm_get_pinctrl(pdev); - if (!ret) { - pr_debug("%s: pinctrl parsing successful\n", __func__); - } else { - dev_dbg(&pdev->dev, - "%s: Parsing pinctrl failed with %d. Cannot use Ports\n", - __func__, ret); - ret = 0; - } - msm_i2s_auxpcm_init(pdev); is_initial_boot = true; return 0; err: - msm_release_pinctrl(pdev); return ret; } @@ -8460,7 +8382,6 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) msm_i2s_auxpcm_deinit(); msm_mdf_mem_deinit(); - msm_release_pinctrl(pdev); return 0; } -- GitLab From cf0c63d564ab0ec5dddb27fab9d7f29c70b7ba06 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 1 Oct 2018 15:35:35 +0530 Subject: [PATCH 0551/1645] asoc: wcd937x: update access for wcd937x registers Remove page registers from access table. Update read/write access for registers as per HW spec. Change-Id: I8c32b79e4f0d4e378df5c83f3934c68f6c72385f Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd937x/wcd937x-tables.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x-tables.c b/asoc/codecs/wcd937x/wcd937x-tables.c index 70507306a5e6..5baf7733514f 100644 --- a/asoc/codecs/wcd937x/wcd937x-tables.c +++ b/asoc/codecs/wcd937x/wcd937x-tables.c @@ -178,7 +178,6 @@ const u8 wcd937x_reg_access[WCD937X_REG(WCD937X_REGISTERS_MAX_SIZE)] = { [WCD937X_REG(WCD937X_EAR_TEST_CTL)] = RD_WR_REG, [WCD937X_REG(WCD937X_EAR_STATUS_REG_1)] = RD_REG, [WCD937X_REG(WCD937X_EAR_STATUS_REG_2)] = RD_REG, - [WCD937X_REG(WCD937X_ANA_NEW_PAGE_REGISTER)] = RD_WR_REG, [WCD937X_REG(WCD937X_HPH_NEW_ANA_HPH2)] = RD_WR_REG, [WCD937X_REG(WCD937X_HPH_NEW_ANA_HPH3)] = RD_WR_REG, [WCD937X_REG(WCD937X_SLEEP_CTL)] = RD_WR_REG, @@ -195,8 +194,8 @@ const u8 wcd937x_reg_access[WCD937X_REG(WCD937X_REGISTERS_MAX_SIZE)] = { [WCD937X_REG(WCD937X_AUX_AUXPA)] = RD_WR_REG, [WCD937X_REG(WCD937X_LDORXTX_MODE)] = RD_WR_REG, [WCD937X_REG(WCD937X_LDORXTX_CONFIG)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIE_CRACK_DIE_CRK_DET_EN)] = RD_REG, - [WCD937X_REG(WCD937X_DIE_CRACK_DIE_CRK_DET_OUT)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIE_CRACK_DIE_CRK_DET_EN)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIE_CRACK_DIE_CRK_DET_OUT)] = RD_REG, [WCD937X_REG(WCD937X_HPH_NEW_INT_RDAC_GAIN_CTL)] = RD_WR_REG, [WCD937X_REG(WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L)] = RD_WR_REG, [WCD937X_REG(WCD937X_HPH_NEW_INT_RDAC_VREF_CTL)] = RD_WR_REG, @@ -241,7 +240,6 @@ const u8 wcd937x_reg_access[WCD937X_REG(WCD937X_REGISTERS_MAX_SIZE)] = { [WCD937X_REG(WCD937X_SLEEP_INT_WATCHDOG_CTL_2)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT1)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT2)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_PAGE_REGISTER)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_CHIP_ID0)] = RD_REG, [WCD937X_REG(WCD937X_DIGITAL_CHIP_ID1)] = RD_REG, [WCD937X_REG(WCD937X_DIGITAL_CHIP_ID2)] = RD_REG, @@ -282,9 +280,9 @@ const u8 wcd937x_reg_access[WCD937X_REG(WCD937X_REGISTERS_MAX_SIZE)] = { [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R2)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R3)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R4)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R4)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R4)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R4)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R5)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R6)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R7)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A1_0)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A1_1)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A2_0)] = RD_WR_REG, @@ -375,6 +373,7 @@ const u8 wcd937x_reg_access[WCD937X_REG(WCD937X_REGISTERS_MAX_SIZE)] = { [WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_RX2)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_TX)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_TX)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PAD_INP_DIS_0)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_PAD_INP_DIS_1)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_DRIVE_STRENGTH_0)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_DRIVE_STRENGTH_1)] = RD_WR_REG, -- GitLab From c1cde37a300dd662d84bd92219ba4352b8b7f6f9 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Tue, 14 Aug 2018 18:56:24 +0530 Subject: [PATCH 0552/1645] asoc: add new FE dais to support compress loopback Add new FE dais and their routings to support compress loopback usecase for HDMI and BT sink. Change-Id: I95d683ff22cda0e7d52333e7dabbb7694cb254f3 Signed-off-by: Surendar Karka Signed-off-by: Mangesh Kunchamwar --- asoc/msm-dai-fe.c | 39 ++++++ asoc/msm-pcm-routing-v2.c | 245 ++++++++++++++++++++++++++++++++++++++ asoc/msm-pcm-routing-v2.h | 2 + 3 files changed, 286 insertions(+) diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index 359ebc440159..3dc4509fc565 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -2667,6 +2667,45 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "MultiMedia21", .probe = fe_dai_probe, }, + { + .playback = { + .stream_name = "MultiMedia26 Playback", + .aif_name = "MM_DL26", + .rates = (SNDRV_PCM_RATE_8000_384000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 32, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia26", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "MultiMedia27 Capture", + .aif_name = "MM_UL27", + .rates = (SNDRV_PCM_RATE_8000_192000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE), + .channels_min = 1, + .channels_max = 32, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia27", + .probe = fe_dai_probe, + }, { .capture = { .stream_name = "MultiMedia28 Capture", diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 1b8404a47456..b431685683d3 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -707,6 +707,12 @@ static struct msm_pcm_routing_fdai_data {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA21 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, + /* MULTIMEDIA26 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, + /* MULTIMEDIA27 */ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA28 */ @@ -4192,6 +4198,10 @@ static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -4279,6 +4289,10 @@ static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -4366,6 +4380,10 @@ static const struct snd_kcontrol_new pri_spdif_rx_mixer_controls[] = { MSM_BACKEND_DAI_PRI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -4453,6 +4471,10 @@ static const struct snd_kcontrol_new sec_spdif_rx_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -4528,6 +4550,10 @@ static const struct snd_kcontrol_new slimbus_2_rx_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_2_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_2_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new slimbus_5_rx_mixer_controls[] = { @@ -4607,6 +4633,10 @@ static const struct snd_kcontrol_new slimbus_5_rx_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -4694,6 +4724,10 @@ static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -4781,6 +4815,10 @@ static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -4868,6 +4906,10 @@ static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -4955,6 +4997,10 @@ static const struct snd_kcontrol_new quinary_mi2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -5035,6 +5081,10 @@ static const struct snd_kcontrol_new tertiary_mi2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -5129,6 +5179,10 @@ static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -5216,6 +5270,10 @@ static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -5438,6 +5496,10 @@ static const struct snd_kcontrol_new hdmi_mixer_controls[] = { MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -5513,6 +5575,10 @@ static const struct snd_kcontrol_new display_port_mixer_controls[] = { MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new display_port1_mixer_controls[] = { @@ -5580,6 +5646,10 @@ static const struct snd_kcontrol_new display_port1_mixer_controls[] = { MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; /* incall music delivery mixer */ @@ -5705,6 +5775,10 @@ static const struct snd_kcontrol_new slimbus_6_rx_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_mixer_controls[] = { @@ -5772,6 +5846,10 @@ static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new wsa_cdc_dma_rx_1_mixer_controls[] = { @@ -5839,6 +5917,10 @@ static const struct snd_kcontrol_new wsa_cdc_dma_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new rx_cdc_dma_rx_0_mixer_controls[] = { @@ -5906,6 +5988,10 @@ static const struct snd_kcontrol_new rx_cdc_dma_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new rx_cdc_dma_rx_1_mixer_controls[] = { @@ -5973,6 +6059,10 @@ static const struct snd_kcontrol_new rx_cdc_dma_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new rx_cdc_dma_rx_2_mixer_controls[] = { @@ -6040,6 +6130,10 @@ static const struct snd_kcontrol_new rx_cdc_dma_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new rx_cdc_dma_rx_3_mixer_controls[] = { @@ -6107,6 +6201,10 @@ static const struct snd_kcontrol_new rx_cdc_dma_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new rx_cdc_dma_rx_4_mixer_controls[] = { @@ -6174,6 +6272,10 @@ static const struct snd_kcontrol_new rx_cdc_dma_rx_4_mixer_controls[] = { MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new rx_cdc_dma_rx_5_mixer_controls[] = { @@ -6241,6 +6343,10 @@ static const struct snd_kcontrol_new rx_cdc_dma_rx_5_mixer_controls[] = { MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new rx_cdc_dma_rx_6_mixer_controls[] = { @@ -6308,6 +6414,10 @@ static const struct snd_kcontrol_new rx_cdc_dma_rx_6_mixer_controls[] = { MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new rx_cdc_dma_rx_7_mixer_controls[] = { @@ -6375,6 +6485,10 @@ static const struct snd_kcontrol_new rx_cdc_dma_rx_7_mixer_controls[] = { MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new slimbus_7_rx_mixer_controls[] = { @@ -6442,6 +6556,10 @@ static const struct snd_kcontrol_new slimbus_7_rx_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new usb_audio_rx_mixer_controls[] = { @@ -6509,6 +6627,10 @@ static const struct snd_kcontrol_new usb_audio_rx_mixer_controls[] = { MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = { @@ -6588,6 +6710,10 @@ static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = { MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -6663,6 +6789,10 @@ static const struct snd_kcontrol_new int_bt_a2dp_rx_mixer_controls[] = { MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = { @@ -6742,6 +6872,10 @@ static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = { MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -6829,6 +6963,10 @@ static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = { MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -6920,6 +7058,10 @@ static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = { MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -7011,6 +7153,10 @@ static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = { MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -7086,6 +7232,10 @@ static const struct snd_kcontrol_new tert_auxpcm_rx_mixer_controls[] = { MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_auxpcm_rx_mixer_controls[] = { @@ -7153,6 +7303,10 @@ static const struct snd_kcontrol_new quat_auxpcm_rx_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_auxpcm_rx_mixer_controls[] = { @@ -7220,6 +7374,10 @@ static const struct snd_kcontrol_new quin_auxpcm_rx_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, @@ -11585,6 +11743,49 @@ static const struct snd_kcontrol_new mmul21_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new mmul27_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new mmul28_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, @@ -17755,6 +17956,7 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_IN("MM_DL16", "MultiMedia16 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("MM_DL20", "MultiMedia20 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("MM_DL21", "MultiMedia21 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL26", "MultiMedia26 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0), @@ -17771,6 +17973,7 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("MM_UL19", "MultiMedia19 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL20", "MultiMedia20 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL21", "MultiMedia21 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL27", "MultiMedia27 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL28", "MultiMedia28 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL29", "MultiMedia29 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0), @@ -18728,6 +18931,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { mmul20_mixer_controls, ARRAY_SIZE(mmul20_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia21 Mixer", SND_SOC_NOPM, 0, 0, mmul21_mixer_controls, ARRAY_SIZE(mmul21_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia27 Mixer", SND_SOC_NOPM, 0, 0, + mmul27_mixer_controls, ARRAY_SIZE(mmul27_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia28 Mixer", SND_SOC_NOPM, 0, 0, mmul28_mixer_controls, ARRAY_SIZE(mmul28_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia29 Mixer", SND_SOC_NOPM, 0, 0, @@ -19127,6 +19332,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"PRI_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"PRI_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"}, {"SEC_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19145,6 +19351,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"SEC_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SEC_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"SEC_I2S_RX", NULL, "SEC_RX Audio Mixer"}, {"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19163,6 +19370,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_0_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"SLIMBUS_0_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SLIMBUS_0_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"}, {"SLIMBUS_2_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19181,6 +19389,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_2_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"SLIMBUS_2_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SLIMBUS_2_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"SLIMBUS_2_RX", NULL, "SLIMBUS_2_RX Audio Mixer"}, {"SLIMBUS_5_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19199,6 +19408,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_5_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"SLIMBUS_5_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SLIMBUS_5_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"SLIMBUS_5_RX", NULL, "SLIMBUS_5_RX Audio Mixer"}, {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19217,6 +19427,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia26", "MM_DL26"}, {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0 Audio Mixer"}, {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19235,6 +19446,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia26", "MM_DL26"}, {"WSA_CDC_DMA_RX_1", NULL, "WSA_CDC_DMA_RX_1 Audio Mixer"}, {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19253,6 +19465,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia26", "MM_DL26"}, {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0 Audio Mixer"}, {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19271,6 +19484,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia26", "MM_DL26"}, {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1 Audio Mixer"}, {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19289,6 +19503,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia26", "MM_DL26"}, {"RX_CDC_DMA_RX_2", NULL, "RX_CDC_DMA_RX_2 Audio Mixer"}, {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19307,6 +19522,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia26", "MM_DL26"}, {"RX_CDC_DMA_RX_3", NULL, "RX_CDC_DMA_RX_3 Audio Mixer"}, {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19325,6 +19541,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia26", "MM_DL26"}, {"RX_CDC_DMA_RX_4", NULL, "RX_CDC_DMA_RX_4 Audio Mixer"}, {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19343,6 +19560,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia26", "MM_DL26"}, {"RX_CDC_DMA_RX_5", NULL, "RX_CDC_DMA_RX_5 Audio Mixer"}, {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19361,6 +19579,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia26", "MM_DL26"}, {"RX_CDC_DMA_RX_6", NULL, "RX_CDC_DMA_RX_6 Audio Mixer"}, {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19379,6 +19598,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia26", "MM_DL26"}, {"RX_CDC_DMA_RX_7", NULL, "RX_CDC_DMA_RX_7 Audio Mixer"}, {"HDMI Mixer", "MultiMedia1", "MM_DL1"}, @@ -19397,6 +19617,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"HDMI Mixer", "MultiMedia14", "MM_DL14"}, {"HDMI Mixer", "MultiMedia15", "MM_DL15"}, {"HDMI Mixer", "MultiMedia16", "MM_DL16"}, + {"HDMI Mixer", "MultiMedia26", "MM_DL26"}, {"HDMI", NULL, "HDMI Mixer"}, {"DISPLAY_PORT Mixer", "MultiMedia1", "MM_DL1"}, @@ -19415,6 +19636,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"DISPLAY_PORT Mixer", "MultiMedia14", "MM_DL14"}, {"DISPLAY_PORT Mixer", "MultiMedia15", "MM_DL15"}, {"DISPLAY_PORT Mixer", "MultiMedia16", "MM_DL16"}, + {"DISPLAY_PORT Mixer", "MultiMedia26", "MM_DL26"}, {"DISPLAY_PORT", NULL, "DISPLAY_PORT Mixer"}, {"DISPLAY_PORT1 Mixer", "MultiMedia1", "MM_DL1"}, @@ -19433,6 +19655,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"DISPLAY_PORT1 Mixer", "MultiMedia14", "MM_DL14"}, {"DISPLAY_PORT1 Mixer", "MultiMedia15", "MM_DL15"}, {"DISPLAY_PORT1 Mixer", "MultiMedia16", "MM_DL16"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia26", "MM_DL26"}, {"DISPLAY_PORT1", NULL, "DISPLAY_PORT1 Mixer"}, {"PRI_SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19451,6 +19674,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"PRI_SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"PRI_SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"PRI_SPDIF_RX", NULL, "PRI_SPDIF_RX Audio Mixer"}, {"SEC_SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19469,6 +19693,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"SEC_SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SEC_SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"SEC_SPDIF_RX", NULL, "SEC_SPDIF_RX Audio Mixer"}, /* incall */ @@ -19504,6 +19729,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_6_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"SLIMBUS_6_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SLIMBUS_6_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"SLIMBUS_6_RX", NULL, "SLIMBUS_6_RX Audio Mixer"}, {"SLIMBUS_7_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19522,6 +19748,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_7_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"SLIMBUS_7_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SLIMBUS_7_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"SLIMBUS_7_RX", NULL, "SLIMBUS_7_RX Audio Mixer"}, {"USB_AUDIO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19540,6 +19767,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"USB_AUDIO_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"USB_AUDIO_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"USB_AUDIO_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX Audio Mixer"}, {"MultiMedia1 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, @@ -19607,6 +19835,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"MI2S_RX", NULL, "MI2S_RX Audio Mixer"}, {"QUAT_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19624,6 +19853,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"QUAT_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"QUAT_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX Audio Mixer"}, {"TERT_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19640,6 +19870,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"TERT_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"TERT_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX Audio Mixer"}, {"SEC_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -19656,6 +19887,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"SEC_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SEC_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Audio Mixer"}, {"SEC_MI2S_RX_SD1 Audio Mixer", "MultiMedia6", "MM_DL6"}, @@ -19679,6 +19911,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"PRI_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"PRI_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Audio Mixer"}, {"INT0_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -20659,6 +20892,17 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia21 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia21 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia27 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia27 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, + {"MultiMedia27 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia27 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia27 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia27 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia27 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia27 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia27 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia27 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia4 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, @@ -20859,6 +21103,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL19", NULL, "MultiMedia19 Mixer"}, {"MM_UL20", NULL, "MultiMedia20 Mixer"}, {"MM_UL21", NULL, "MultiMedia21 Mixer"}, + {"MM_UL27", NULL, "MultiMedia27 Mixer"}, {"MM_UL28", NULL, "MultiMedia28 Mixer"}, {"MM_UL29", NULL, "MultiMedia29 Mixer"}, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 26a54284e6a9..46f913d4e510 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -240,6 +240,8 @@ enum { MSM_FRONTEND_DAI_MULTIMEDIA19, MSM_FRONTEND_DAI_MULTIMEDIA20, MSM_FRONTEND_DAI_MULTIMEDIA21, + MSM_FRONTEND_DAI_MULTIMEDIA26, + MSM_FRONTEND_DAI_MULTIMEDIA27, MSM_FRONTEND_DAI_MULTIMEDIA28, MSM_FRONTEND_DAI_MULTIMEDIA29, MSM_FRONTEND_DAI_VOIP, -- GitLab From b412979a8caa9386d7b0ab6000dd7fa56c3e009e Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Tue, 14 Aug 2018 19:05:05 +0530 Subject: [PATCH 0553/1645] asoc: qcs405: add machine driver support for compress loopback Add new dailnks in machine driver to support compress loopback usecase for HDMI and BT sink. Change-Id: Ie9658b3c06fd8d9a68b9b2317fe2689fa34a96f5 Signed-off-by: Surendar Karka Signed-off-by: Mangesh Kunchamwar --- asoc/qcs405.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index a051f2c40f65..c819bb869cea 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -6278,6 +6278,37 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA18, }, + { + .name = MSM_DAILINK_NAME(Transcode Loopback Playback), + .stream_name = "Transcode Loopback Playback", + .cpu_dai_name = "MultiMedia26", + .platform_name = "msm-transcode-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dailink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA26, + }, + { + .name = MSM_DAILINK_NAME(Transcode Loopback Capture), + .stream_name = "Transcode Loopback Capture", + .cpu_dai_name = "MultiMedia27", + .platform_name = "msm-transcode-loopback", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA27, + }, }; static struct snd_soc_dai_link msm_common_be_dai_links[] = { -- GitLab From b0dd21f1a32c4a469ac151dd414fa6e84e701f7f Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Fri, 28 Sep 2018 18:53:50 +0530 Subject: [PATCH 0554/1645] dsp: add support for Slimbus 9 port in AFE Add support for SLIMBUS_9 Rx and Tx ports in AFE driver. Change-Id: I7a21c06fd67984ef60e7d40b61a100ddc48371fc Signed-off-by: Surendar Karka Signed-off-by: Mangesh Kunchamwar --- dsp/q6afe.c | 10 ++++++++++ dsp/q6audio-v2.c | 6 ++++++ include/dsp/apr_audio-v2.h | 8 +++++++- include/dsp/q6afe-v2.h | 5 ++++- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index f5e7267f7c9e..a29011bbed10 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -839,6 +839,8 @@ int afe_sizeof_cfg_cmd(u16 port_id) case SLIMBUS_7_TX: case SLIMBUS_8_RX: case SLIMBUS_8_TX: + case SLIMBUS_9_RX: + case SLIMBUS_9_TX: ret_size = SIZEOF_CFG_CMD(afe_param_id_slimbus_cfg); break; case VOICE_PLAYBACK_TX: @@ -4041,6 +4043,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, case SLIMBUS_7_TX: case SLIMBUS_8_RX: case SLIMBUS_8_TX: + case SLIMBUS_9_RX: + case SLIMBUS_9_TX: cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG; break; case AFE_PORT_ID_USB_RX: @@ -4288,6 +4292,8 @@ int afe_get_port_index(u16 port_id) case SLIMBUS_7_TX: return IDX_SLIMBUS_7_TX; case SLIMBUS_8_RX: return IDX_SLIMBUS_8_RX; case SLIMBUS_8_TX: return IDX_SLIMBUS_8_TX; + case SLIMBUS_9_RX: return IDX_SLIMBUS_9_RX; + case SLIMBUS_9_TX: return IDX_SLIMBUS_9_TX; case AFE_PORT_ID_USB_RX: return IDX_AFE_PORT_ID_USB_RX; case AFE_PORT_ID_USB_TX: return IDX_AFE_PORT_ID_USB_TX; case AFE_PORT_ID_PRIMARY_MI2S_RX: @@ -4685,6 +4691,8 @@ int afe_open(u16 port_id, case SLIMBUS_7_TX: case SLIMBUS_8_RX: case SLIMBUS_8_TX: + case SLIMBUS_9_RX: + case SLIMBUS_9_TX: cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG; break; case AFE_PORT_ID_USB_RX: @@ -6557,6 +6565,8 @@ int afe_validate_port(u16 port_id) case SLIMBUS_7_TX: case SLIMBUS_8_RX: case SLIMBUS_8_TX: + case SLIMBUS_9_RX: + case SLIMBUS_9_TX: case AFE_PORT_ID_USB_RX: case AFE_PORT_ID_USB_TX: case AFE_PORT_ID_PRIMARY_MI2S_RX: diff --git a/dsp/q6audio-v2.c b/dsp/q6audio-v2.c index 3108c042dd02..6d14234746cd 100644 --- a/dsp/q6audio-v2.c +++ b/dsp/q6audio-v2.c @@ -79,6 +79,8 @@ int q6audio_get_port_index(u16 port_id) case SLIMBUS_7_TX: return IDX_SLIMBUS_7_TX; case SLIMBUS_8_RX: return IDX_SLIMBUS_8_RX; case SLIMBUS_8_TX: return IDX_SLIMBUS_8_TX; + case SLIMBUS_9_RX: return IDX_SLIMBUS_9_RX; + case SLIMBUS_9_TX: return IDX_SLIMBUS_9_TX; case INT_BT_SCO_RX: return IDX_INT_BT_SCO_RX; case INT_BT_SCO_TX: return IDX_INT_BT_SCO_TX; case INT_BT_A2DP_RX: return IDX_INT_BT_A2DP_RX; @@ -415,6 +417,8 @@ int q6audio_get_port_id(u16 port_id) case SLIMBUS_7_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_7_TX; case SLIMBUS_8_RX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_8_RX; case SLIMBUS_8_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_8_TX; + case SLIMBUS_9_RX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_9_RX; + case SLIMBUS_9_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_9_TX; case INT_BT_SCO_RX: return AFE_PORT_ID_INTERNAL_BT_SCO_RX; case INT_BT_SCO_TX: return AFE_PORT_ID_INTERNAL_BT_SCO_TX; case INT_BT_A2DP_RX: return AFE_PORT_ID_INTERNAL_BT_A2DP_RX; @@ -925,6 +929,8 @@ int q6audio_validate_port(u16 port_id) case SLIMBUS_7_TX: case SLIMBUS_8_RX: case SLIMBUS_8_TX: + case SLIMBUS_9_RX: + case SLIMBUS_9_TX: case INT_BT_SCO_RX: case INT_BT_SCO_TX: case INT_BT_A2DP_RX: diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 134281936992..268f7e1885c4 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1085,7 +1085,9 @@ struct adm_cmd_connect_afe_port_v5 { #define SLIMBUS_7_TX 0x400f #define SLIMBUS_8_RX 0x4010 #define SLIMBUS_8_TX 0x4011 -#define SLIMBUS_PORT_LAST SLIMBUS_8_TX +#define SLIMBUS_9_RX 0x4012 +#define SLIMBUS_9_TX 0x4013 +#define SLIMBUS_PORT_LAST SLIMBUS_9_TX #define INT_BT_SCO_RX 0x3000 #define INT_BT_SCO_TX 0x3001 #define INT_BT_A2DP_RX 0x3002 @@ -1284,6 +1286,10 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_8_RX 0x4010 /* SLIMbus Tx port on channel 8. */ #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_8_TX 0x4011 +/* SLIMbus Rx port on channel 9. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_9_RX 0x4012 +/* SLIMbus Tx port on channel 9. */ +#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_9_TX 0x4013 /* AFE Rx port for audio over Display port */ #define AFE_PORT_ID_HDMI_OVER_DP_RX 0x6020 /*USB AFE port */ diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index cf004d036eca..b7a6780e5da7 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -251,10 +251,13 @@ enum { IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_5, IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_6, IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_7, - /* IDX 182 to 185 */ + /* IDX 182 to 184 */ IDX_SECONDARY_SPDIF_RX, IDX_PRIMARY_SPDIF_TX, IDX_SECONDARY_SPDIF_TX, + /* IDX 185 to 187 */ + IDX_SLIMBUS_9_RX, + IDX_SLIMBUS_9_TX, AFE_MAX_PORTS }; -- GitLab From 3ef3d81d0a5cfefa2c43893bfcc477eaaf7a093d Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Fri, 28 Sep 2018 18:52:35 +0530 Subject: [PATCH 0555/1645] asoc: add support for Slimbus 9 port Add support for SLIMBUS_9 Rx and Tx ports for audio drivers. Change-Id: If2071983ab38cb0de76c8231ec86d5c662cce2af Signed-off-by: Surendar Karka Signed-off-by: Mangesh Kunchamwar --- asoc/msm-dai-q6-v2.c | 48 ++++++++++++ asoc/msm-pcm-routing-v2.c | 156 +++++++++++++++++++++++++++++++++++++- asoc/msm-pcm-routing-v2.h | 4 + 3 files changed, 207 insertions(+), 1 deletion(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 1164f6f7b499..c24bb65f59ac 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -2176,6 +2176,8 @@ static int msm_dai_q6_slim_bus_hw_params(struct snd_pcm_hw_params *params, case SLIMBUS_7_TX: case SLIMBUS_8_RX: case SLIMBUS_8_TX: + case SLIMBUS_9_RX: + case SLIMBUS_9_TX: dai_data->port_config.slim_sch.slimbus_dev_id = AFE_SLIMBUS_DEVICE_2; break; @@ -2350,6 +2352,7 @@ static int msm_dai_q6_hw_params(struct snd_pcm_substream *substream, case SLIMBUS_6_RX: case SLIMBUS_7_RX: case SLIMBUS_8_RX: + case SLIMBUS_9_RX: case SLIMBUS_0_TX: case SLIMBUS_1_TX: case SLIMBUS_2_TX: @@ -2359,6 +2362,7 @@ static int msm_dai_q6_hw_params(struct snd_pcm_substream *substream, case SLIMBUS_6_TX: case SLIMBUS_7_TX: case SLIMBUS_8_TX: + case SLIMBUS_9_TX: rc = msm_dai_q6_slim_bus_hw_params(params, dai, substream->stream); break; @@ -2475,6 +2479,7 @@ static int msm_dai_q6_set_channel_map(struct snd_soc_dai *dai, case SLIMBUS_6_RX: case SLIMBUS_7_RX: case SLIMBUS_8_RX: + case SLIMBUS_9_RX: /* * channel number to be between 128 and 255. * For RX port use channel numbers @@ -2512,6 +2517,7 @@ static int msm_dai_q6_set_channel_map(struct snd_soc_dai *dai, case SLIMBUS_6_TX: case SLIMBUS_7_TX: case SLIMBUS_8_TX: + case SLIMBUS_9_TX: /* * channel number to be between 128 and 255. * For TX port use channel numbers @@ -4023,6 +4029,22 @@ static struct snd_soc_dai_driver msm_dai_q6_slimbus_rx_dai[] = { .probe = msm_dai_q6_dai_probe, .remove = msm_dai_q6_dai_remove, }, + { + .playback = { + .stream_name = "Slimbus9 Playback", + .aif_name = "SLIMBUS_9_RX", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = DAI_FORMATS_S16_S24_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_9_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, }; static struct snd_soc_dai_driver msm_dai_q6_slimbus_tx_dai[] = { @@ -4202,6 +4224,26 @@ static struct snd_soc_dai_driver msm_dai_q6_slimbus_tx_dai[] = { .probe = msm_dai_q6_dai_probe, .remove = msm_dai_q6_dai_remove, }, + { + .capture = { + .stream_name = "Slimbus9 Capture", + .aif_name = "SLIMBUS_9_TX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_ops, + .id = SLIMBUS_9_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, }; static int msm_dai_q6_mi2s_format_put(struct snd_kcontrol *kcontrol, @@ -5484,6 +5526,9 @@ static int msm_dai_q6_dev_probe(struct platform_device *pdev) case SLIMBUS_8_RX: strlcpy(stream_name, "Slimbus8 Playback", sizeof(stream_name)); goto register_slim_playback; + case SLIMBUS_9_RX: + strlcpy(stream_name, "Slimbus9 Playback", sizeof(stream_name)); + goto register_slim_playback; register_slim_playback: rc = -ENODEV; len = strnlen(stream_name, 80); @@ -5529,6 +5574,9 @@ static int msm_dai_q6_dev_probe(struct platform_device *pdev) case SLIMBUS_8_TX: strlcpy(stream_name, "Slimbus8 Capture", sizeof(stream_name)); goto register_slim_capture; + case SLIMBUS_9_TX: + strlcpy(stream_name, "Slimbus9 Capture", sizeof(stream_name)); + goto register_slim_capture; register_slim_capture: rc = -ENODEV; len = strnlen(stream_name, 80); diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index b431685683d3..7292949073bf 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -639,6 +639,8 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_SEC_SPDIF_RX}, { AFE_PORT_ID_SECONDARY_SPDIF_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_SPDIF_TX}, + { SLIMBUS_9_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_9_RX}, + { SLIMBUS_9_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_9_TX}, }; /* Track ASM playback & capture sessions of DAI @@ -6562,6 +6564,76 @@ static const struct snd_kcontrol_new slimbus_7_rx_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new slimbus_9_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; static const struct snd_kcontrol_new usb_audio_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, MSM_BACKEND_DAI_USB_RX, @@ -9470,6 +9542,10 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul2_mixer_controls[] = { @@ -9661,6 +9737,10 @@ static const struct snd_kcontrol_new mmul2_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul3_mixer_controls[] = { @@ -10250,6 +10330,10 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul6_mixer_controls[] = { @@ -10636,6 +10720,10 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul16_mixer_controls[] = { @@ -10837,6 +10925,10 @@ static const struct snd_kcontrol_new mmul16_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul9_mixer_controls[] = { @@ -11137,6 +11229,10 @@ static const struct snd_kcontrol_new mmul10_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul17_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, @@ -11784,6 +11880,10 @@ static const struct snd_kcontrol_new mmul27_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul28_mixer_controls[] = { @@ -13507,6 +13607,10 @@ static const struct snd_kcontrol_new int0_mi2s_rx_port_mixer_controls[] = { MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new int4_mi2s_rx_port_mixer_controls[] = { @@ -13550,6 +13654,10 @@ static const struct snd_kcontrol_new int4_mi2s_rx_port_mixer_controls[] = { MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_port_mixer_controls[] = { @@ -13576,6 +13684,10 @@ static const struct snd_kcontrol_new rx_cdc_dma_rx_0_port_mixer_controls[] = { MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { @@ -13665,7 +13777,11 @@ static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_MI2S_RX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_RX, -MSM_BACKEND_DAI_QUINARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; @@ -13859,6 +13975,10 @@ static const struct snd_kcontrol_new sbus_6_rx_port_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new bt_sco_rx_port_mixer_controls[] = { @@ -18697,6 +18817,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("SLIMBUS_8_RX", "Slimbus8 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("SLIMBUS_8_TX", "Slimbus8 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_9_RX", "Slimbus9 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_9_TX", "Slimbus9 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("USB_AUDIO_RX", "USB Audio Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("USB_AUDIO_TX", "USB Audio Capture", 0, 0, 0, 0), @@ -18757,6 +18879,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { slimbus_5_rx_mixer_controls, ARRAY_SIZE(slimbus_5_rx_mixer_controls)), SND_SOC_DAPM_MIXER("SLIMBUS_7_RX Audio Mixer", SND_SOC_NOPM, 0, 0, slimbus_7_rx_mixer_controls, ARRAY_SIZE(slimbus_7_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_9_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_9_rx_mixer_controls, ARRAY_SIZE(slimbus_9_rx_mixer_controls)), SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0, hdmi_mixer_controls, ARRAY_SIZE(hdmi_mixer_controls)), SND_SOC_DAPM_MIXER("DISPLAY_PORT Mixer", SND_SOC_NOPM, 0, 0, @@ -19751,6 +19875,25 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_7_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"SLIMBUS_7_RX", NULL, "SLIMBUS_7_RX Audio Mixer"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SLIMBUS_9_RX", NULL, "SLIMBUS_9_RX Audio Mixer"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"USB_AUDIO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, {"USB_AUDIO_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, @@ -19780,8 +19923,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, {"MultiMedia1 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"MultiMedia1 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"MultiMedia1 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, {"MultiMedia8 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, {"MultiMedia8 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia8 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, {"MultiMedia4 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia17 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia18 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, @@ -19815,7 +19960,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia16 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia5 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"MultiMedia5 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"MultiMedia5 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, {"MultiMedia10 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia10 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, {"MultiMedia18 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia18 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, @@ -20895,6 +21042,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia27 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia27 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, {"MultiMedia27 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia27 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, {"MultiMedia27 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia27 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"MultiMedia27 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, @@ -22246,6 +22394,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"INT0_MI2S_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"INT0_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"INT0_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"INT0_MI2S_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, {"INT0_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX Port Mixer"}, @@ -22257,6 +22406,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"INT4_MI2S_RX Port Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"INT4_MI2S_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"INT4_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"INT4_MI2S_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, {"INT4_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"INT4_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX Port Mixer"}, @@ -22273,6 +22423,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_0_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"SLIMBUS_0_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"SLIMBUS_0_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, {"SLIMBUS_0_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"SLIMBUS_0_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, {"SLIMBUS_0_RX Port Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, @@ -22417,6 +22568,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_6_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"SLIMBUS_6_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"SLIMBUS_6_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, {"SLIMBUS_6_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"SLIMBUS_6_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, {"SLIMBUS_6_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, @@ -22507,6 +22659,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "SLIMBUS_6_RX"}, {"BE_OUT", NULL, "SLIMBUS_7_RX"}, {"BE_OUT", NULL, "SLIMBUS_8_RX"}, + {"BE_OUT", NULL, "SLIMBUS_9_RX"}, {"BE_OUT", NULL, "USB_AUDIO_RX"}, {"BE_OUT", NULL, "HDMI"}, {"BE_OUT", NULL, "DISPLAY_PORT"}, @@ -22594,6 +22747,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_6_TX", NULL, "BE_IN" }, {"SLIMBUS_7_TX", NULL, "BE_IN" }, {"SLIMBUS_8_TX", NULL, "BE_IN" }, + {"SLIMBUS_9_TX", NULL, "BE_IN" }, {"USB_AUDIO_TX", NULL, "BE_IN" }, {"INT_BT_SCO_TX", NULL, "BE_IN"}, {"INT_FM_TX", NULL, "BE_IN"}, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 46f913d4e510..e9a08eb8f74b 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -170,6 +170,8 @@ #define LPASS_BE_SLIMBUS_7_TX "SLIMBUS_7_TX" #define LPASS_BE_SLIMBUS_8_RX "SLIMBUS_8_RX" #define LPASS_BE_SLIMBUS_8_TX "SLIMBUS_8_TX" +#define LPASS_BE_SLIMBUS_9_RX "SLIMBUS_9_RX" +#define LPASS_BE_SLIMBUS_9_TX "SLIMBUS_9_TX" #define LPASS_BE_USB_AUDIO_RX "USB_AUDIO_RX" #define LPASS_BE_USB_AUDIO_TX "USB_AUDIO_TX" @@ -453,6 +455,8 @@ enum { MSM_BACKEND_DAI_PRI_SPDIF_TX, MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_SLIMBUS_9_TX, MSM_BACKEND_DAI_MAX, }; -- GitLab From a0a952401fc26008c52dbc05ddb7e3b38639a6b6 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Mon, 20 Aug 2018 15:23:46 +0530 Subject: [PATCH 0556/1645] asoc: update passthrough mode in transcode loopback driver Update passthrough mode to pick proper path type for compressed input data port in transcode loopback driver to support compressed input in DSP loopback. Change-Id: Ib2f66b467456787e08265a0da2bd85bb881a5d61 Signed-off-by: Siddartha Shaik Signed-off-by: Surendar Karka --- asoc/msm-transcode-loopback-q6-v2.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index 3d4f8bf3ffbc..544e1ddd342c 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -111,7 +111,8 @@ static void loopback_event_handler(uint32_t opcode, switch (opcode) { case ASM_STREAM_CMD_ENCDEC_EVENTS: case ASM_IEC_61937_MEDIA_FMT_EVENT: - pr_debug("%s: ASM_IEC_61937_MEDIA_FMT_EVENT\n", __func__); + pr_debug("%s: Handling stream event : 0X%x\n", + __func__, opcode); rtd = cstream->private_data; if (!rtd) { pr_err("%s: rtd is NULL\n", __func__); @@ -448,17 +449,17 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, trans->audio_client->perf_mode, trans->session_id, SNDRV_PCM_STREAM_CAPTURE, - true); + COMPRESSED_PASSTHROUGH_GEN); else msm_pcm_routing_reg_phy_stream( soc_pcm_tx->dai_link->id, trans->audio_client->perf_mode, trans->session_id, SNDRV_PCM_STREAM_CAPTURE); - + /* Opening Rx ADM in LOW_LATENCY mode by default */ msm_pcm_routing_reg_phy_stream( soc_pcm_rx->dai_link->id, - trans->audio_client->perf_mode, + true, trans->session_id, SNDRV_PCM_STREAM_PLAYBACK); pr_debug("%s: Successfully opened ADM sessions\n", __func__); @@ -912,10 +913,21 @@ static int msm_transcode_loopback_probe(struct snd_soc_platform *platform) return 0; } +static int msm_transcode_loopback_remove(struct snd_soc_platform *platform) +{ + struct trans_loopback_pdata *pdata = NULL; + + pdata = (struct trans_loopback_pdata *) + snd_soc_platform_get_drvdata(platform); + kfree(pdata); + return 0; +} + static struct snd_soc_platform_driver msm_soc_platform = { .probe = msm_transcode_loopback_probe, .compr_ops = &msm_transcode_loopback_ops, .pcm_new = msm_transcode_loopback_new, + .remove = msm_transcode_loopback_remove, }; static int msm_transcode_dev_probe(struct platform_device *pdev) -- GitLab From eca0432ffba47478d186946f5f8f4a2862142b8a Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Mon, 20 Aug 2018 15:31:47 +0530 Subject: [PATCH 0557/1645] asoc: mixer control queue handling in sink stream Mixer control queue handling is required only for playback. Move mixer control queue handling to be part of the playback stream in DSP transcode loopback driver. Change-Id: Ia8067237f80d509f969cf454f5afa08aaa6b0e52 Signed-off-by: Siddartha Shaik Signed-off-by: Surendar Karka --- asoc/msm-transcode-loopback-q6-v2.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index 544e1ddd342c..ffaf0fdae27d 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -99,7 +99,7 @@ static void loopback_event_handler(uint32_t opcode, return; } - cstream = trans->source.cstream; + cstream = trans->sink.cstream; ac = trans->audio_client; /* @@ -222,6 +222,7 @@ static int msm_transcode_loopback_open(struct snd_compr_stream *cstream) ret = -EINVAL; goto exit; } + msm_adsp_init_mixer_ctl_pp_event_queue(rtd); } pr_debug("%s: num stream%d, stream name %s\n", __func__, @@ -236,8 +237,7 @@ static int msm_transcode_loopback_open(struct snd_compr_stream *cstream) } runtime->private_data = trans; - if (trans->num_streams == 1) - msm_adsp_init_mixer_ctl_pp_event_queue(rtd); + exit: mutex_unlock(&trans->lock); return ret; @@ -282,14 +282,14 @@ static int msm_transcode_loopback_free(struct snd_compr_stream *cstream) trans->num_streams--; stop_transcoding(trans); - if (cstream->direction == SND_COMPRESS_PLAYBACK) + if (cstream->direction == SND_COMPRESS_PLAYBACK) { memset(&trans->sink, 0, sizeof(struct loopback_stream)); - else if (cstream->direction == SND_COMPRESS_CAPTURE) + msm_adsp_clean_mixer_ctl_pp_event_queue(rtd); + } else if (cstream->direction == SND_COMPRESS_CAPTURE) { memset(&trans->source, 0, sizeof(struct loopback_stream)); + } trans->session_state = LOOPBACK_SESSION_CLOSE; - if (trans->num_streams == 1) - msm_adsp_clean_mixer_ctl_pp_event_queue(rtd); mutex_unlock(&trans->lock); return ret; } -- GitLab From 33dc09849e5f51e02c61e5a430d46457f28d8649 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Mon, 20 Aug 2018 17:49:07 +0530 Subject: [PATCH 0558/1645] asoc: enable app type config for transcode loopback Add app type configuration support for DSP transcode loopback to enable the required PP topologies. Change-Id: I60ee50d78ba3c0edc9df042a2a86e691d62f24b7 Signed-off-by: Siddartha Shaik Signed-off-by: Surendar Karka --- asoc/msm-transcode-loopback-q6-v2.c | 123 ++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index ffaf0fdae27d..617898f385af 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -40,6 +40,11 @@ #define LOOPBACK_SESSION_MAX_NUM_STREAMS 2 +#define APP_TYPE_CONFIG_IDX_APP_TYPE 0 +#define APP_TYPE_CONFIG_IDX_ACDB_ID 1 +#define APP_TYPE_CONFIG_IDX_SAMPLE_RATE 2 +#define APP_TYPE_CONFIG_IDX_BE_ID 3 + static DEFINE_MUTEX(transcode_loopback_session_lock); struct trans_loopback_pdata { @@ -662,6 +667,67 @@ static int msm_transcode_rtic_event_ack_put(struct snd_kcontrol *kcontrol, return ret; } +static int msm_transcode_playback_app_type_cfg_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_RX; + int be_id = ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_BE_ID]; + struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000}; + int ret = 0; + + cfg_data.app_type = ucontrol->value.integer.value[ + APP_TYPE_CONFIG_IDX_APP_TYPE]; + cfg_data.acdb_dev_id = ucontrol->value.integer.value[ + APP_TYPE_CONFIG_IDX_ACDB_ID]; + if (ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_SAMPLE_RATE] != 0) + cfg_data.sample_rate = ucontrol->value.integer.value[ + APP_TYPE_CONFIG_IDX_SAMPLE_RATE]; + pr_debug("%s: fe_id %llu session_type %d be_id %d app_type %d acdb_dev_id %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, &cfg_data); + if (ret < 0) + pr_err("%s: msm_transcode_playback_stream_app_type_cfg set failed returned %d\n", + __func__, ret); + + return ret; +} + +static int msm_transcode_playback_app_type_cfg_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_RX; + int be_id = 0; + struct msm_pcm_stream_app_type_cfg cfg_data = {0}; + int ret = 0; + + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + &be_id, &cfg_data); + if (ret < 0) { + pr_err("%s: msm_transcode_playback_stream_app_type_cfg get failed returned %d\n", + __func__, ret); + goto done; + } + + ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_APP_TYPE] = + cfg_data.app_type; + ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_ACDB_ID] = + cfg_data.acdb_dev_id; + ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_SAMPLE_RATE] = + cfg_data.sample_rate; + ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_BE_ID] = be_id; + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); +done: + return ret; +} + static int msm_transcode_stream_cmd_control( struct snd_soc_pcm_runtime *rtd) { @@ -863,6 +929,58 @@ static int msm_transcode_add_event_ack_cmd_control( return ret; } +static int msm_transcode_app_type_cfg_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 5; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0xFFFFFFFF; + return 0; +} + +static int msm_transcode_add_app_type_cfg_control( + struct snd_soc_pcm_runtime *rtd) +{ + char mixer_str[32]; + struct snd_kcontrol_new fe_app_type_cfg_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_transcode_app_type_cfg_info, + .put = msm_transcode_playback_app_type_cfg_put, + .get = msm_transcode_playback_app_type_cfg_get, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s NULL rtd\n", __func__); + return -EINVAL; + } + + if (rtd->compr->direction == SND_COMPRESS_PLAYBACK) { + snprintf(mixer_str, sizeof(mixer_str), + "Audio Stream %d App Type Cfg", + rtd->pcm->device); + + fe_app_type_cfg_control[0].name = mixer_str; + fe_app_type_cfg_control[0].private_value = rtd->dai_link->id; + + fe_app_type_cfg_control[0].put = + msm_transcode_playback_app_type_cfg_put; + fe_app_type_cfg_control[0].get = + msm_transcode_playback_app_type_cfg_get; + + pr_debug("Registering new mixer ctl %s", mixer_str); + snd_soc_add_platform_controls(rtd->platform, + fe_app_type_cfg_control, + ARRAY_SIZE(fe_app_type_cfg_control)); + } + + return 0; +} + static int msm_transcode_loopback_new(struct snd_soc_pcm_runtime *rtd) { int rc; @@ -886,6 +1004,11 @@ static int msm_transcode_loopback_new(struct snd_soc_pcm_runtime *rtd) pr_err("%s: Could not add transcode event ack Control\n", __func__); + rc = msm_transcode_add_app_type_cfg_control(rtd); + if (rc) + pr_err("%s: Could not add Compr App Type Cfg Control\n", + __func__); + return 0; } -- GitLab From bcfd6862e48788d64111132652eaa4387d1ad370 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Mon, 20 Aug 2018 17:57:04 +0530 Subject: [PATCH 0559/1645] asoc: volume control support for transcode loopback FE Add stream volume control support for DSP transcode loopback to enable mute configuration requirement. Change-Id: I2003e40c9888245c1b12f0e7fbd364170d5008cf Signed-off-by: Siddartha Shaik Signed-off-by: Surendar Karka --- asoc/msm-transcode-loopback-q6-v2.c | 120 ++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index 617898f385af..14b7ac87a3a2 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -39,6 +39,8 @@ #include "msm-qti-pp-config.h" #define LOOPBACK_SESSION_MAX_NUM_STREAMS 2 +/* Max volume corresponding to 24dB */ +#define TRANSCODE_LR_VOL_MAX_DB 0xFFFF #define APP_TYPE_CONFIG_IDX_APP_TYPE 0 #define APP_TYPE_CONFIG_IDX_ACDB_ID 1 @@ -49,6 +51,7 @@ static DEFINE_MUTEX(transcode_loopback_session_lock); struct trans_loopback_pdata { struct snd_compr_stream *cstream[MSM_FRONTEND_DAI_MAX]; + uint32_t master_gain; }; struct loopback_stream { @@ -728,6 +731,80 @@ static int msm_transcode_playback_app_type_cfg_get( return ret; } +static int msm_transcode_set_volume(struct snd_compr_stream *cstream, + uint32_t master_gain) +{ + int rc = 0; + struct msm_transcode_loopback *prtd; + struct snd_soc_pcm_runtime *rtd; + + pr_debug("%s: master_gain %d\n", __func__, master_gain); + if (!cstream || !cstream->runtime) { + pr_err("%s: session not active\n", __func__); + return -EINVAL; + } + rtd = cstream->private_data; + prtd = cstream->runtime->private_data; + + if (!rtd || !rtd->platform || !prtd || !prtd->audio_client) { + pr_err("%s: invalid rtd, prtd or audio client", __func__); + return -EINVAL; + } + + rc = q6asm_set_volume(prtd->audio_client, master_gain); + if (rc < 0) + pr_err("%s: Send vol gain command failed rc=%d\n", + __func__, rc); + + return rc; +} + +static int msm_transcode_volume_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + struct trans_loopback_pdata *pdata = (struct trans_loopback_pdata *) + snd_soc_component_get_drvdata(comp); + struct snd_compr_stream *cstream = NULL; + uint32_t ret = 0; + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bounds fe_id %lu\n", + __func__, fe_id); + return -EINVAL; + } + + cstream = pdata->cstream[fe_id]; + pdata->master_gain = ucontrol->value.integer.value[0]; + + pr_debug("%s: fe_id %lu master_gain %d\n", + __func__, fe_id, pdata->master_gain); + if (cstream) + ret = msm_transcode_set_volume(cstream, pdata->master_gain); + return ret; +} + +static int msm_transcode_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + + struct trans_loopback_pdata *pdata = (struct trans_loopback_pdata *) + snd_soc_component_get_drvdata(comp); + + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bound fe_id %lu\n", __func__, fe_id); + return -EINVAL; + } + + pr_debug("%s: fe_id %lu\n", __func__, fe_id); + ucontrol->value.integer.value[0] = pdata->master_gain; + + return 0; +} + static int msm_transcode_stream_cmd_control( struct snd_soc_pcm_runtime *rtd) { @@ -980,6 +1057,44 @@ static int msm_transcode_add_app_type_cfg_control( return 0; } +static int msm_transcode_volume_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = TRANSCODE_LR_VOL_MAX_DB; + return 0; +} + +static int msm_transcode_add_volume_control(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_kcontrol_new fe_volume_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Transcode Loopback Rx Volume", + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | + SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_transcode_volume_info, + .get = msm_transcode_volume_get, + .put = msm_transcode_volume_put, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s NULL rtd\n", __func__); + return -EINVAL; + } + if (rtd->compr->direction == SND_COMPRESS_PLAYBACK) { + fe_volume_control[0].private_value = rtd->dai_link->id; + pr_debug("Registering new mixer ctl %s", + fe_volume_control[0].name); + snd_soc_add_platform_controls(rtd->platform, fe_volume_control, + ARRAY_SIZE(fe_volume_control)); + } + return 0; +} static int msm_transcode_loopback_new(struct snd_soc_pcm_runtime *rtd) { @@ -1009,6 +1124,11 @@ static int msm_transcode_loopback_new(struct snd_soc_pcm_runtime *rtd) pr_err("%s: Could not add Compr App Type Cfg Control\n", __func__); + rc = msm_transcode_add_volume_control(rtd); + if (rc) + pr_err("%s: Could not add transcode volume Control\n", + __func__); + return 0; } -- GitLab From b9caa7f4263e1f2327db4c0809653c798e7848fb Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Mon, 20 Aug 2018 18:06:16 +0530 Subject: [PATCH 0560/1645] asoc: qdsp6v2: latency mode support for transcode loopback Add metadata to configure latency mode for DSP transcode loopback to set legacy or low latency path. Userspace API introduced to configure the same. Change-Id: I914c68a9e9d8647530b72c42548e571b7508c423 Signed-off-by: Siddartha Shaik Signed-off-by: Surendar Karka --- asoc/msm-transcode-loopback-q6-v2.c | 55 +++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index 14b7ac87a3a2..fb70f6cb7aa6 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "msm-pcm-routing-v2.h" #include "msm-qti-pp-config.h" @@ -52,6 +53,7 @@ static DEFINE_MUTEX(transcode_loopback_session_lock); struct trans_loopback_pdata { struct snd_compr_stream *cstream[MSM_FRONTEND_DAI_MAX]; uint32_t master_gain; + int perf_mode; }; struct loopback_stream { @@ -344,6 +346,8 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, struct msm_transcode_loopback *trans = runtime->private_data; struct snd_soc_pcm_runtime *soc_pcm_rx; struct snd_soc_pcm_runtime *soc_pcm_tx; + struct snd_soc_pcm_runtime *rtd; + struct trans_loopback_pdata *pdata; uint32_t bit_width = 16; int ret = 0; @@ -354,6 +358,9 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, mutex_lock(&trans->lock); + rtd = snd_pcm_substream_chip(cstream); + pdata = snd_soc_platform_get_drvdata(rtd->platform); + if (cstream->direction == SND_COMPRESS_PLAYBACK) { if (codec_param->codec.id == SND_AUDIOCODEC_PCM) { trans->sink.codec_format = @@ -435,7 +442,7 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, pr_debug("%s: ASM client allocated, callback %pK\n", __func__, loopback_event_handler); trans->session_id = trans->audio_client->session; - trans->audio_client->perf_mode = false; + trans->audio_client->perf_mode = pdata->perf_mode; ret = q6asm_open_transcode_loopback(trans->audio_client, bit_width, trans->source.codec_format, @@ -454,7 +461,7 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, if (trans->source.codec_format != FORMAT_LINEAR_PCM) msm_pcm_routing_reg_phy_compr_stream( soc_pcm_tx->dai_link->id, - trans->audio_client->perf_mode, + LEGACY_PCM_MODE, trans->session_id, SNDRV_PCM_STREAM_CAPTURE, COMPRESSED_PASSTHROUGH_GEN); @@ -467,7 +474,7 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, /* Opening Rx ADM in LOW_LATENCY mode by default */ msm_pcm_routing_reg_phy_stream( soc_pcm_rx->dai_link->id, - true, + trans->audio_client->perf_mode, trans->session_id, SNDRV_PCM_STREAM_PLAYBACK); pr_debug("%s: Successfully opened ADM sessions\n", __func__); @@ -500,6 +507,46 @@ static int msm_transcode_loopback_get_caps(struct snd_compr_stream *cstream, return 0; } +static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream, + struct snd_compr_metadata *metadata) +{ + struct snd_soc_pcm_runtime *rtd; + struct trans_loopback_pdata *pdata; + + if (!metadata || !cstream) { + pr_err("%s: Invalid arguments\n", __func__); + return -EINVAL; + } + + rtd = snd_pcm_substream_chip(cstream); + pdata = snd_soc_platform_get_drvdata(rtd->platform); + + switch (metadata->key) { + case SNDRV_COMPRESS_LATENCY_MODE: + { + switch (metadata->value[0]) { + case SNDRV_COMPRESS_LEGACY_LATENCY_MODE: + pdata->perf_mode = LEGACY_PCM_MODE; + break; + case SNDRV_COMPRESS_LOW_LATENCY_MODE: + pdata->perf_mode = LOW_LATENCY_PCM_MODE; + break; + default: + pr_debug("%s: Unsupported latency mode %d, default to Legacy\n", + __func__, metadata->value[0]); + pdata->perf_mode = LEGACY_PCM_MODE; + break; + } + } + break; + default: + pr_debug("%s: Unsupported metadata %d\n", + __func__, metadata->key); + break; + } + return 0; +} + static int msm_transcode_stream_cmd_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1138,6 +1185,7 @@ static struct snd_compr_ops msm_transcode_loopback_ops = { .trigger = msm_transcode_loopback_trigger, .set_params = msm_transcode_loopback_set_params, .get_caps = msm_transcode_loopback_get_caps, + .set_metadata = msm_transcode_loopback_set_metadata, }; @@ -1152,6 +1200,7 @@ static int msm_transcode_loopback_probe(struct snd_soc_platform *platform) if (!pdata) return -ENOMEM; + pdata->perf_mode = LOW_LATENCY_PCM_MODE; snd_soc_platform_set_drvdata(platform, pdata); return 0; } -- GitLab From e1f518308fe6d6320337733b3d862debb22814fb Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Tue, 4 Sep 2018 12:10:42 +0200 Subject: [PATCH 0561/1645] asoc: codecs: Use sysfs instead of mixer_ctls for EP92 HDMI The format change event signaling for EP92 HDMI input is adapted to provide format information through sysfs nodes. Chip configuration is done through sysfs as well. Change-Id: I8c930ca5647899b4434272009699763c32fe9d04 Signed-off-by: Ralf Herz Signed-off-by: Mangesh Kunchamwar --- asoc/codecs/ep92/ep92.c | 1932 ++++++++++++++++++++++----------------- asoc/codecs/ep92/ep92.h | 18 +- 2 files changed, 1100 insertions(+), 850 deletions(-) diff --git a/asoc/codecs/ep92/ep92.c b/asoc/codecs/ep92/ep92.c index 73110da7ec04..52f5e6d0b98a 100644 --- a/asoc/codecs/ep92/ep92.c +++ b/asoc/codecs/ep92/ep92.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include #include @@ -27,9 +29,10 @@ #include #include "ep92.h" -#define EP92_POLL_INTERVAL_OFF_MSEC 2000 -#define EP92_POLL_INTERVAL_ON_MSEC 100 - +#define EP92_POLL_INTERVAL_OFF_MSEC 200 +#define EP92_POLL_INTERVAL_ON_MSEC 20 +#define EP92_SYSFS_ENTRY_MAX_LEN 64 +#define EP92_HYST_CNT 5 #define EP92_RATES (SNDRV_PCM_RATE_32000 |\ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ @@ -38,71 +41,10 @@ #define EP92_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) -#define EP92_UEVENT_CTRL_NUM_KEYS 8 -#define EP92_UEVENT_AUDIO_NUM_KEYS 9 - static const unsigned int ep92_samp_freq_table[8] = { 32000, 44100, 48000, 88200, 96000, 176400, 192000, 768000 }; -static const char hex_to_char[] = {'0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - -struct ep92_uevent_data { - struct kobject kobj; - struct kobj_type ktype; -}; - -static struct kset *ep92_uevent_kset; -static struct ep92_uevent_data *ep92_uevent_ctrl; -static struct ep92_uevent_data *ep92_uevent_audio; - -static void ep92_release_uevent_data(struct kobject *kobj) -{ - struct ep92_uevent_data *data = container_of(kobj, - struct ep92_uevent_data, kobj); - - kfree(data); -} - -static int ep92_init_uevent_data(struct ep92_uevent_data *uevent_data, - char *name) -{ - int ret = -EINVAL; - - if (!uevent_data || !name) - return ret; - - /* Set kset for kobject before initializing the kobject */ - uevent_data->kobj.kset = ep92_uevent_kset; - - /* Initialize kobject and add it to kernel */ - ret = kobject_init_and_add(&uevent_data->kobj, &uevent_data->ktype, - NULL, "%s", name); - if (ret) { - pr_err("%s: error initializing uevent kernel object: %d", - __func__, ret); - kobject_put(&uevent_data->kobj); - return ret; - } - - /* Send kobject add event to the system */ - kobject_uevent(&uevent_data->kobj, KOBJ_ADD); - - return ret; -} - -/** - * ep92_destroy_uevent_data - destroy kernel object. - * - * @uevent_data: uevent data. - */ -static void ep92_destroy_uevent_data(struct ep92_uevent_data *uevent_data) -{ - if (uevent_data) - kobject_put(&uevent_data->kobj); -} - static bool ep92_volatile_register(struct device *dev, unsigned int reg) { switch (reg) { @@ -162,10 +104,25 @@ struct ep92_pdata { struct work_struct read_status_worker; int irq; + int hyst_tx_plug; + int hyst_link_on0; + int hyst_link_on1; + int hyst_link_on2; + int filt_tx_plug; + int filt_link_on0; + int filt_link_on1; + int filt_link_on2; + struct { + u8 tx_info; + u8 video_latency; + } gi; /* General Info block */ + struct { u8 ctl; u8 rx_sel; + u8 ctl2; u8 cec_volume; + u8 link; } gc; /* General Control block */ struct { @@ -178,443 +135,145 @@ struct ep92_pdata { } ai; /* Audio Info block */ u8 old_mode; +#if IS_ENABLED(CONFIG_DEBUG_FS) + struct dentry *debugfs_dir; + struct dentry *debugfs_file_wo; + struct dentry *debugfs_file_ro; +#endif /* CONFIG_DEBUG_FS */ }; -/* - * EP92 Controls - */ - -/* enumerated controls */ -static const char * const ep92_off_on_text[] = {"Off", "On"}; -static const char * const ep92_aud_path_text[] = {"TV", "Speaker"}; -static const char * const ep92_rx_sel_text[] = {"Port 0", "Port 1", "Port 2", - "Res 3", "Res 4", "Res 5", "None", "Res 7"}; -static const char * const ep92_cec_mute_text[] = {"Normal", "Muted"}; - -static const char * const ep92_state_text[] = {"Inactive", "Active"}; -static const char * const ep92_avmute_text[] = {"Normal", "Muted"}; -static const char * const ep92_layout_text[] = {"Layout 0", "Layout 1"}; -static const char * const ep92_mode_text[] = {"LPCM", "Compr"}; - -SOC_ENUM_SINGLE_DECL(ep92_power_enum, EP92_GENERAL_CONTROL_0, - EP92_GC_POWER_SHIFT, ep92_off_on_text); -SOC_ENUM_SINGLE_DECL(ep92_audio_path_enum, EP92_GENERAL_CONTROL_0, - EP92_GC_AUDIO_PATH_SHIFT, ep92_aud_path_text); -SOC_ENUM_SINGLE_DECL(ep92_rx_sel_enum, EP92_GENERAL_CONTROL_1, - EP92_GC_RX_SEL_SHIFT, ep92_rx_sel_text); -SOC_ENUM_SINGLE_DECL(ep92_arc_en_enum, EP92_GENERAL_CONTROL_0, - EP92_GC_ARC_EN_SHIFT, ep92_off_on_text); -SOC_ENUM_SINGLE_DECL(ep92_cec_mute_enum, EP92_GENERAL_CONTROL_0, - EP92_GC_CEC_MUTE_SHIFT, ep92_cec_mute_text); - -SOC_ENUM_SINGLE_DECL(ep92_state_enum, EP92_AUDIO_INFO_SYSTEM_STATUS_0, - EP92_AI_MCLK_ON_SHIFT, ep92_state_text); -SOC_ENUM_SINGLE_DECL(ep92_avmute_enum, EP92_AUDIO_INFO_SYSTEM_STATUS_0, - EP92_AI_AVMUTE_SHIFT, ep92_avmute_text); -SOC_ENUM_SINGLE_DECL(ep92_layout_enum, EP92_AUDIO_INFO_SYSTEM_STATUS_0, - EP92_AI_LAYOUT_SHIFT, ep92_layout_text); -SOC_ENUM_SINGLE_DECL(ep92_mode_enum, EP92_AUDIO_INFO_AUDIO_STATUS, - EP92_AI_STD_ADO_SHIFT, ep92_mode_text); - -/* get/set functions */ -static int ep92_power_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - unsigned int val; - - val = snd_soc_read(codec, e->reg); - ucontrol->value.enumerated.item[0] = - (val >> e->shift_l) & EP92_2CHOICE_MASK; - - pr_debug("%s: item = %d (%s)\n", __func__, - ucontrol->value.enumerated.item[0], - ep92_off_on_text[ucontrol->value.enumerated.item[0]]); - return 0; -} - -static int ep92_power_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct ep92_pdata *ep92 = snd_soc_codec_get_drvdata(codec); - unsigned int val; - - val = snd_soc_read(codec, e->reg); - val &= ~EP92_GC_POWER_MASK; - val |= (ucontrol->value.enumerated.item[0] & EP92_2CHOICE_MASK) - << e->shift_l; - snd_soc_write(codec, e->reg, val); - ep92->gc.ctl &= ~EP92_GC_POWER_MASK; - ep92->gc.ctl |= val & EP92_GC_POWER_MASK; - - pr_debug("%s: item = %d (%s)\n", __func__, - ucontrol->value.enumerated.item[0], - ep92_off_on_text[ucontrol->value.enumerated.item[0] & - EP92_2CHOICE_MASK]); - return 0; -} - -static int ep92_audio_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - unsigned int val; - - val = snd_soc_read(codec, e->reg); - ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & - EP92_2CHOICE_MASK; - - pr_debug("%s: item = %d (%s)\n", __func__, - ucontrol->value.enumerated.item[0], - ep92_aud_path_text[ucontrol->value.enumerated.item[0]]); - return 0; -} - -static int ep92_audio_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct ep92_pdata *ep92 = snd_soc_codec_get_drvdata(codec); - unsigned int val; - - val = snd_soc_read(codec, e->reg); - val &= ~EP92_GC_AUDIO_PATH_MASK; - val |= (ucontrol->value.enumerated.item[0] & EP92_2CHOICE_MASK) - << e->shift_l; - snd_soc_write(codec, e->reg, val); - ep92->gc.ctl &= ~EP92_GC_AUDIO_PATH_MASK; - ep92->gc.ctl |= val & EP92_GC_AUDIO_PATH_MASK; - - pr_debug("%s: item = %d (%s)\n", __func__, - ucontrol->value.enumerated.item[0], - ep92_aud_path_text[ucontrol->value.enumerated.item[0] & - EP92_2CHOICE_MASK]); - return 0; -} - -static int ep92_cec_mute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - unsigned int val; - - val = snd_soc_read(codec, e->reg); - ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & - EP92_2CHOICE_MASK; - - pr_debug("%s: item = %d (%s)\n", __func__, - ucontrol->value.enumerated.item[0], - ep92_cec_mute_text[ucontrol->value.enumerated.item[0]]); - return 0; -} - -static int ep92_cec_mute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct ep92_pdata *ep92 = snd_soc_codec_get_drvdata(codec); - unsigned int val; - - val = snd_soc_read(codec, e->reg); - val &= ~EP92_GC_CEC_MUTE_MASK; - val |= (ucontrol->value.enumerated.item[0] & EP92_2CHOICE_MASK) - << e->shift_l; - snd_soc_write(codec, e->reg, val); - ep92->gc.ctl &= ~EP92_GC_CEC_MUTE_MASK; - ep92->gc.ctl |= val & EP92_GC_CEC_MUTE_MASK; - - pr_debug("%s: item = %d (%s)\n", __func__, - ucontrol->value.enumerated.item[0], - ep92_cec_mute_text[ucontrol->value.enumerated.item[0] & - EP92_2CHOICE_MASK]); - return 0; -} - -static int ep92_arc_en_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - unsigned int val; - - val = snd_soc_read(codec, e->reg); - ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & - EP92_2CHOICE_MASK; - - pr_debug("%s: item = %d (%s)\n", __func__, - ucontrol->value.enumerated.item[0], - ep92_off_on_text[ucontrol->value.enumerated.item[0]]); - return 0; -} - -static int ep92_arc_en_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct ep92_pdata *ep92 = snd_soc_codec_get_drvdata(codec); - unsigned int val; - - val = snd_soc_read(codec, e->reg); - val &= ~EP92_GC_ARC_EN_MASK; - val |= (ucontrol->value.enumerated.item[0] & EP92_2CHOICE_MASK) - << e->shift_l; - snd_soc_write(codec, e->reg, val); - ep92->gc.ctl &= ~EP92_GC_ARC_EN_MASK; - ep92->gc.ctl |= val & EP92_GC_ARC_EN_MASK; - - pr_debug("%s: item = %d (%s)\n", __func__, - ucontrol->value.enumerated.item[0], - ep92_off_on_text[ucontrol->value.enumerated.item[0] & 0x01]); - return 0; -} - -static int ep92_rx_sel_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - unsigned int val; - - val = snd_soc_read(codec, e->reg); - ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & - EP92_GC_RX_SEL_MASK; - - pr_debug("%s: item = %d (%s)\n", __func__, - ucontrol->value.enumerated.item[0], - ep92_rx_sel_text[ucontrol->value.enumerated.item[0]]); - return 0; -} - -static int ep92_rx_sel_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +#if IS_ENABLED(CONFIG_DEBUG_FS) +static int debugfs_codec_open_op(struct inode *inode, struct file *file) { - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct ep92_pdata *ep92 = snd_soc_codec_get_drvdata(codec); - unsigned int val; - - val = snd_soc_read(codec, e->reg); - val &= ~EP92_GC_RX_SEL_MASK; - val |= (ucontrol->value.enumerated.item[0] & EP92_GC_RX_SEL_MASK) - << e->shift_l; - snd_soc_write(codec, e->reg, val); - ep92->gc.rx_sel &= ~EP92_GC_RX_SEL_MASK; - ep92->gc.rx_sel |= val & EP92_GC_RX_SEL_MASK; - - pr_debug("%s: item = %d (%s)\n", __func__, - ucontrol->value.enumerated.item[0], - ep92_rx_sel_text[ucontrol->value.enumerated.item[0] & - EP92_GC_RX_SEL_MASK]); - return 0; -} - -static int ep92_cec_volume_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - unsigned int val; - - val = snd_soc_read(codec, mc->reg); - ucontrol->value.integer.value[0] = (val >> mc->shift) & - EP92_GC_CEC_VOLUME_MASK; - - pr_debug("%s: volume = %ld\n", __func__, - ucontrol->value.integer.value[0]); - return 0; -} - -static int ep92_cec_volume_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct ep92_pdata *ep92 = snd_soc_codec_get_drvdata(codec); - unsigned int val; - - val = ucontrol->value.integer.value[0] & EP92_GC_CEC_VOLUME_MASK; - if (val > EP92_GC_CEC_VOLUME_MAX) - val = EP92_GC_CEC_VOLUME_MAX; - snd_soc_write(codec, mc->reg, val); - ep92->gc.cec_volume = val; - - pr_debug("%s: volume = %ld\n", __func__, - ucontrol->value.integer.value[0]); + file->private_data = inode->i_private; return 0; } -static int ep92_state_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int debugfs_get_parameters(char *buf, u32 *param1, int num_of_par) { - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - unsigned int val; - - val = snd_soc_read(codec, e->reg); - ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & - EP92_2CHOICE_MASK; - - pr_debug("%s: item = %d (%s)\n", __func__, - ucontrol->value.enumerated.item[0], - ep92_state_text[ucontrol->value.enumerated.item[0]]); + char *token; + int base, cnt; + + token = strsep(&buf, " "); + for (cnt = 0; cnt < num_of_par; cnt++) { + if (token) { + if ((token[1] == 'x') || (token[1] == 'X')) + base = 16; + else + base = 10; + + if (kstrtou32(token, base, ¶m1[cnt]) != 0) + return -EINVAL; + + token = strsep(&buf, " "); + } else { + return -EINVAL; + } + } return 0; } -static int ep92_avmute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static ssize_t debugfs_codec_write_op(struct file *filp, + const char __user *ubuf, size_t cnt, loff_t *ppos) { - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - unsigned int val; - - val = snd_soc_read(codec, e->reg); - ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & - EP92_2CHOICE_MASK; + struct ep92_pdata *ep92 = (struct ep92_pdata *) filp->private_data; + struct snd_soc_codec *codec = ep92->codec; + char lbuf[32]; + int rc; + u32 param[2]; - pr_debug("%s: item = %d (%s)\n", __func__, - ucontrol->value.enumerated.item[0], - ep92_avmute_text[ucontrol->value.enumerated.item[0]]); - return 0; + if (!filp || !ppos || !ubuf) + return -EINVAL; + if (cnt > sizeof(lbuf) - 1) + return -EINVAL; + rc = copy_from_user(lbuf, ubuf, cnt); + if (rc) + return -EFAULT; + lbuf[cnt] = '\0'; + rc = debugfs_get_parameters(lbuf, param, 2); + if ((param[0] < EP92_ISP_MODE_ENTER_ISP) + || (param[0] > EP92_GENERAL_CONTROL_4)) { + dev_err(codec->dev, "%s: reg address 0x%02X out of range\n", + __func__, param[0]); + return -EINVAL; + } + if ((param[1] < 0) || (param[1] > 255)) { + dev_err(codec->dev, "%s: reg data 0x%02X out of range\n", + __func__, param[1]); + return -EINVAL; + } + if (rc == 0) { + rc = cnt; + dev_info(codec->dev, "%s: reg[0x%02X]=0x%02X\n", + __func__, param[0], param[1]); + snd_soc_write(codec, param[0], param[1]); + } else { + dev_err(codec->dev, "%s: write to register addr=0x%02X failed\n", + __func__, param[0]); + } + return rc; } -static int ep92_layout_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static ssize_t debugfs_ep92_reg_show(struct snd_soc_codec *codec, + char __user *ubuf, size_t count, loff_t *ppos) { - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - unsigned int val; - - val = snd_soc_read(codec, e->reg); - ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & - EP92_2CHOICE_MASK; + int i, reg_val, len; + ssize_t total = 0; + char tmp_buf[20]; - pr_debug("%s: item = %d (%s)\n", __func__, - ucontrol->value.enumerated.item[0], - ep92_layout_text[ucontrol->value.enumerated.item[0]]); - return 0; -} - -static int ep92_mode_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct ep92_pdata *ep92 = snd_soc_codec_get_drvdata(codec); - unsigned int val; + if (!ubuf || !ppos || !codec || *ppos < 0) + return -EINVAL; - val = snd_soc_read(codec, e->reg); - if (val & EP92_AI_STD_ADO_MASK) { - val = snd_soc_read(codec, EP92_AUDIO_INFO_CHANNEL_STATUS_0); - if (val & EP92_AI_NPCM_MASK) - ucontrol->value.enumerated.item[0] = 1; /* Compr */ - else - ucontrol->value.enumerated.item[0] = 0; /* LPCM */ - } else if (val & EP92_AI_HBR_ADO_MASK) { - ucontrol->value.enumerated.item[0] = 1; /* Compr */ - } else { - ucontrol->value.enumerated.item[0] = ep92->old_mode; + for (i = (int) *ppos / 11; i <= EP92_MAX_REGISTER_ADDR; i++) { + reg_val = snd_soc_read(codec, i); + len = snprintf(tmp_buf, 20, "0x%02X: 0x%02X\n", i, + (reg_val & 0xFF)); + if ((total + len) > count) + break; + if (copy_to_user((ubuf + total), tmp_buf, len)) { + dev_err(codec->dev, "%s: fail to copy reg dump\n", + __func__); + total = -EFAULT; + goto copy_err; + } + *ppos += len; + total += len; } - pr_debug("%s: item = %d (%s)\n", __func__, - ucontrol->value.enumerated.item[0], - ep92_mode_text[ucontrol->value.enumerated.item[0]]); - return 0; -} -static int ep92_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - unsigned int val; - - val = snd_soc_read(codec, mc->reg); - val &= EP92_AI_RATE_MASK; - val = ep92_samp_freq_table[val]; - ucontrol->value.integer.value[0] = val; - - pr_debug("%s: rate = %ld\n", __func__, - ucontrol->value.integer.value[0]); - return 0; +copy_err: + return total; } -static int ep92_ch_count_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static ssize_t debugfs_codec_read_op(struct file *filp, + char __user *ubuf, size_t cnt, loff_t *ppos) { - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - unsigned int val; - - val = snd_soc_read(codec, mc->reg) & EP92_AI_CH_COUNT_MASK; - /* mapping is ch_count = reg_val + 1, with exception: 0 = unknown */ - if (val > 0) - val += 1; - - ucontrol->value.integer.value[0] = val; + struct ep92_pdata *ep92 = (struct ep92_pdata *) filp->private_data; + struct snd_soc_codec *codec = ep92->codec; + ssize_t ret_cnt; - pr_debug("%s: ch_count = %ld\n", __func__, - ucontrol->value.integer.value[0]); - return 0; + if (!filp || !ppos || !ubuf || *ppos < 0) + return -EINVAL; + ret_cnt = debugfs_ep92_reg_show(codec, ubuf, cnt, ppos); + return ret_cnt; } -static int ep92_ch_alloc_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static const struct file_operations debugfs_codec_ops = { + .open = debugfs_codec_open_op, + .write = debugfs_codec_write_op, + .read = debugfs_codec_read_op, +}; +#endif /* CONFIG_DEBUG_FS */ + +static int ep92_send_uevent(struct ep92_pdata *ep92, char *event) { - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - unsigned int val; + char *env[] = { event, NULL }; - val = snd_soc_read(codec, mc->reg); - ucontrol->value.integer.value[0] = (val >> mc->shift) & - EP92_AI_CH_ALLOC_MASK; + if (!event || !ep92) + return -EINVAL; - pr_debug("%s: ch_alloc = 0x%02lx\n", __func__, - ucontrol->value.integer.value[0]); - return 0; + return kobject_uevent_env(&ep92->codec->dev->kobj, KOBJ_CHANGE, env); } -static const struct snd_kcontrol_new ep92_snd_controls[] = { - - SOC_ENUM_EXT("HDMI_IN POWER", ep92_power_enum, - ep92_power_get, ep92_power_put), - SOC_ENUM_EXT("HDMI_IN AUDIO_PATH", ep92_audio_path_enum, - ep92_audio_path_get, ep92_audio_path_put), - SOC_ENUM_EXT("HDMI_IN RX_SEL", ep92_rx_sel_enum, - ep92_rx_sel_get, ep92_rx_sel_put), - SOC_ENUM_EXT("HDMI_IN ARC_EN", ep92_arc_en_enum, - ep92_arc_en_get, ep92_arc_en_put), - SOC_ENUM_EXT("HDMI_IN CEC_MUTE", ep92_cec_mute_enum, - ep92_cec_mute_get, ep92_cec_mute_put), - SOC_SINGLE_EXT("HDMI_IN CEC_VOLUME", EP92_GENERAL_CONTROL_3, - EP92_GC_CEC_VOLUME_MIN, EP92_GC_CEC_VOLUME_MAX, - 0, ep92_cec_volume_get, ep92_cec_volume_put), - - SOC_ENUM_EXT("HDMI_IN STATE", ep92_state_enum, ep92_state_get, NULL), - SOC_ENUM_EXT("HDMI_IN AVMUTE", ep92_avmute_enum, ep92_avmute_get, NULL), - SOC_ENUM_EXT("HDMI_IN LAYOUT", ep92_layout_enum, ep92_layout_get, NULL), - SOC_ENUM_EXT("HDMI_IN MODE", ep92_mode_enum, ep92_mode_get, NULL), - SOC_SINGLE_EXT("HDMI_IN RATE", EP92_AUDIO_INFO_AUDIO_STATUS, - EP92_AI_RATE_MIN, EP92_AI_RATE_MAX, 0, ep92_rate_get, NULL), - SOC_SINGLE_EXT("HDMI_IN CH_COUNT", EP92_AUDIO_INFO_ADO_INFO_FRAME_1, - EP92_AI_CH_COUNT_MIN, EP92_AI_CH_COUNT_MAX, - 0, ep92_ch_count_get, NULL), - SOC_SINGLE_EXT("HDMI_IN CH_ALLOC", EP92_AUDIO_INFO_ADO_INFO_FRAME_4, - EP92_AI_CH_ALLOC_MIN, EP92_AI_CH_ALLOC_MAX, 0, - ep92_ch_alloc_get, NULL), -}; - static int ep92_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -669,368 +328,250 @@ static struct snd_soc_dai_driver ep92_dai[] = { }, }; -static const char * const ep92_event_power_text[] = { - "POWER=Off", - "POWER=On", -}; - -static const char * const ep92_event_arc_en_text[] = { - "ARC_EN=Off", - "ARC_EN=On", -}; - -static const char * const ep92_event_audio_path_text[] = { - "AUDIO_PATH=TV", - "AUDIO_PATH=Speaker", -}; - -static const char *const ep92_event_rx_sel_text[] = { - "RX_SEL=Port0", - "RX_SEL=Port1", - "RX_SEL=Port2", - "RX_SEL=Res3", - "RX_SEL=Res4", - "RX_SEL=Res5", - "RX_SEL=None", - "RX_SEL=Res7", -}; - -static const char *const ep92_event_cec_mute_text[] = { - "CEC_MUTE=Normal", - "CEC_MUTE=Muted", -}; - -static int ep92_send_uevent_ctrl(struct ep92_pdata *ep92) +static void ep92_read_general_control(struct snd_soc_codec *codec, + struct ep92_pdata *ep92) { - char *env[EP92_UEVENT_CTRL_NUM_KEYS]; - u8 idx = 0; - u8 cec_volume; - char cec_volume_text[] = "CEC_VOLUME=0x00"; - char *ptr; - - env[idx++] = "HDMI_CONTROL=TRUE"; - - if ((ep92->gc.ctl >> EP92_GC_POWER_SHIFT) & - EP92_2CHOICE_MASK) - env[idx++] = (char *)ep92_event_power_text[1]; - else - env[idx++] = (char *)ep92_event_power_text[0]; - - if (ep92->gc.ctl & EP92_2CHOICE_MASK) - env[idx++] = (char *)ep92_event_arc_en_text[1]; - else - env[idx++] = (char *)ep92_event_arc_en_text[0]; - - if ((ep92->gc.ctl >> EP92_GC_AUDIO_PATH_SHIFT) & - EP92_2CHOICE_MASK) - env[idx++] = (char *)ep92_event_audio_path_text[1]; - else - env[idx++] = (char *)ep92_event_audio_path_text[0]; - - switch (ep92->gc.rx_sel & EP92_GC_RX_SEL_MASK) { - case 0: - env[idx++] = (char *)ep92_event_rx_sel_text[0]; - break; - case 1: - env[idx++] = (char *)ep92_event_rx_sel_text[1]; - break; - case 2: - env[idx++] = (char *)ep92_event_rx_sel_text[2]; - break; - case 3: - env[idx++] = (char *)ep92_event_rx_sel_text[3]; - break; - case 4: - env[idx++] = (char *)ep92_event_rx_sel_text[4]; - break; - case 5: - env[idx++] = (char *)ep92_event_rx_sel_text[5]; - break; - case 6: - env[idx++] = (char *)ep92_event_rx_sel_text[6]; - break; - case 7: - env[idx++] = (char *)ep92_event_rx_sel_text[7]; - break; - default: - env[idx++] = (char *)ep92_event_rx_sel_text[0]; - } - - if ((ep92->gc.ctl >> EP92_GC_CEC_MUTE_SHIFT) & - EP92_2CHOICE_MASK) - env[idx++] = (char *)ep92_event_cec_mute_text[1]; - else - env[idx++] = (char *)ep92_event_cec_mute_text[0]; - - ptr = &cec_volume_text[strlen(cec_volume_text)-2]; - cec_volume = (ep92->ai.ca) & EP92_GC_CEC_VOLUME_MASK; - *ptr++ = hex_to_char[(cec_volume >> 4) & 0x0f]; - *ptr++ = hex_to_char[cec_volume & 0x0f]; - env[idx++] = (char *)cec_volume_text; - - env[idx++] = NULL; + u8 old, change; + int val; - if (idx != EP92_UEVENT_CTRL_NUM_KEYS) { - pr_err("ep92 wrong number of audio uevent keys (%d).\n", - idx); - return -EINVAL; + old = ep92->gi.tx_info; + ep92->gi.tx_info = snd_soc_read(codec, EP92_BI_GENERAL_INFO_0); + if (ep92->gi.tx_info == 0xff) { + pr_debug("ep92 EP92_BI_GENERAL_INFO_0 read 0xff\n"); + ep92->gi.tx_info = old; } - - return kobject_uevent_env(&ep92_uevent_ctrl->kobj, KOBJ_CHANGE, env); -} - -static const char * const ep92_event_state_text[] = { - "STATE=Inactive", - "STATE=Active", -}; - -static const char *const ep92_event_rate_text[] = { - "RATE=32000", - "RATE=44100", - "RATE=48000", - "RATE=88200", - "RATE=96000", - "RATE=176400", - "RATE=192000", - "RATE=768000", -}; - -static const char *const ep92_event_format_text[] = { - "FORMAT=LPCM", - "FORMAT=Compr", -}; - -static const char *const ep92_event_layout_text[] = { - "LAYOUT=2ch", - "LAYOUT=8ch", -}; - -static const char *const ep92_event_avmute_text[] = { - "AVMUTE=Normal", - "AVMUTE=Muted", -}; - -static const char *const ep92_event_ch_count_text[] = { - "CH_COUNT=One", - "CH_COUNT=Two", - "CH_COUNT=Three", - "CH_COUNT=Four", - "CH_COUNT=Five", - "CH_COUNT=Six", - "CH_COUNT=Seven", - "CH_COUNT=Eight", -}; - -static int ep92_send_uevent_audio(struct ep92_pdata *ep92) -{ - char *env[EP92_UEVENT_AUDIO_NUM_KEYS]; - u8 idx = 0; - u8 ch_alloc; - char ch_alloc_text[] = "CH_ALLOC=0x00"; - char *ptr; - - env[idx++] = "HDMI_FMT_UPDATE=TRUE"; - - if (((ep92->ai.system_status_0 >> EP92_AI_MCLK_ON_SHIFT) & - EP92_2CHOICE_MASK) == EP92_STATUS_AUDIO_ACTIVE) - env[idx++] = (char *)ep92_event_state_text[1]; - else - env[idx++] = (char *)ep92_event_state_text[0]; - - switch (ep92->ai.audio_status & EP92_AI_RATE_MASK) { - case 0: - env[idx++] = (char *)ep92_event_rate_text[0]; - break; - case 1: - env[idx++] = (char *)ep92_event_rate_text[1]; - break; - case 2: - env[idx++] = (char *)ep92_event_rate_text[2]; - break; - case 3: - env[idx++] = (char *)ep92_event_rate_text[3]; - break; - case 4: - env[idx++] = (char *)ep92_event_rate_text[4]; - break; - case 5: - env[idx++] = (char *)ep92_event_rate_text[5]; - break; - case 6: - env[idx++] = (char *)ep92_event_rate_text[6]; - break; - case 7: - env[idx++] = (char *)ep92_event_rate_text[7]; - break; - default: - env[idx++] = (char *)ep92_event_rate_text[2]; + /* implement hysteresis to prevent events on glitches */ + if (ep92->gi.tx_info & EP92_GI_TX_HOT_PLUG_MASK) { + if (ep92->hyst_tx_plug < EP92_HYST_CNT) { + ep92->hyst_tx_plug++; + if ((ep92->hyst_tx_plug == EP92_HYST_CNT) && + (ep92->filt_tx_plug == 0)) { + ep92->filt_tx_plug = 1; + pr_debug("ep92 out_plug changed to 1\n"); + ep92_send_uevent(ep92, + "EP92EVT_OUT_PLUG=CONNECTED"); + } + } + } else { + if (ep92->hyst_tx_plug > 0) { + ep92->hyst_tx_plug--; + if ((ep92->hyst_tx_plug == 0) && + (ep92->filt_tx_plug == 1)) { + ep92->filt_tx_plug = 0; + pr_debug("ep92 out_plug changed to 0\n"); + ep92_send_uevent(ep92, + "EP92EVT_OUT_PLUG=DISCONNECTED"); + } + } } - if (ep92->old_mode) - env[idx++] = (char *)ep92_event_format_text[1]; - else - env[idx++] = (char *)ep92_event_format_text[0]; - - if (ep92->ai.system_status_0 & EP92_2CHOICE_MASK) - env[idx++] = (char *)ep92_event_layout_text[1]; - else - env[idx++] = (char *)ep92_event_layout_text[0]; - - if ((ep92->ai.system_status_0 >> EP92_AI_AVMUTE_SHIFT) & - EP92_2CHOICE_MASK) - env[idx++] = (char *)ep92_event_avmute_text[1]; - else - env[idx++] = (char *)ep92_event_avmute_text[0]; - - /* cc==0 signals n/a and is treated as stereo */ - switch (ep92->ai.cc & EP92_AI_CH_COUNT_MASK) { - case 0: - env[idx++] = (char *)ep92_event_ch_count_text[1]; - break; - case 1: - env[idx++] = (char *)ep92_event_ch_count_text[1]; - break; - case 2: - env[idx++] = (char *)ep92_event_ch_count_text[2]; - break; - case 3: - env[idx++] = (char *)ep92_event_ch_count_text[3]; - break; - case 4: - env[idx++] = (char *)ep92_event_ch_count_text[4]; - break; - case 5: - env[idx++] = (char *)ep92_event_ch_count_text[5]; - break; - case 6: - env[idx++] = (char *)ep92_event_ch_count_text[6]; - break; - case 7: - env[idx++] = (char *)ep92_event_ch_count_text[7]; - break; - default: - env[idx++] = (char *)ep92_event_ch_count_text[1]; + old = ep92->gi.video_latency; + ep92->gi.video_latency = snd_soc_read(codec, EP92_BI_GENERAL_INFO_4); + if (ep92->gi.video_latency == 0xff) { + pr_debug("ep92 EP92_BI_GENERAL_INFO_4 read 0xff\n"); + ep92->gi.video_latency = old; } - - ptr = &ch_alloc_text[strlen(ch_alloc_text)-2]; - ch_alloc = (ep92->ai.ca) & EP92_AI_CH_ALLOC_MASK; - *ptr++ = hex_to_char[(ch_alloc >> 4) & 0x0f]; - *ptr++ = hex_to_char[ch_alloc & 0x0f]; - env[idx++] = (char *)ch_alloc_text; - - env[idx++] = NULL; - - if (idx != EP92_UEVENT_AUDIO_NUM_KEYS) { - pr_err("ep92 wrong number of audio uevent keys (%d).\n", - idx); - return -EINVAL; + change = ep92->gi.video_latency ^ old; + if (change & EP92_GI_VIDEO_LATENCY_MASK) { + val = ep92->gi.video_latency; + if (val > 0) + val = (val - 1) * 2; + pr_debug("ep92 video latency changed to %d\n", val); + ep92_send_uevent(ep92, "EP92EVT_VIDEO_LATENCY=CHANGED"); } - return kobject_uevent_env(&ep92_uevent_audio->kobj, KOBJ_CHANGE, env); -} - -static void ep92_read_general_control(struct snd_soc_codec *codec, - struct ep92_pdata *ep92) -{ - u8 old, change; - bool send_uevent = false; - old = ep92->gc.ctl; ep92->gc.ctl = snd_soc_read(codec, EP92_GENERAL_CONTROL_0); + if (ep92->gc.ctl == 0xff) { + pr_debug("ep92 EP92_GENERAL_CONTROL_0 read 0xff\n"); + ep92->gc.ctl = old; + } change = ep92->gc.ctl ^ old; if (change & EP92_GC_POWER_MASK) { - pr_debug("ep92 power changed to %d (%s)\n", - (ep92->gc.ctl >> EP92_GC_POWER_SHIFT) & - EP92_2CHOICE_MASK, - ep92_off_on_text[(ep92->gc.ctl - >> EP92_GC_POWER_SHIFT) & EP92_2CHOICE_MASK]); - send_uevent = true; + val = (ep92->gc.ctl >> EP92_GC_POWER_SHIFT) & + EP92_2CHOICE_MASK; + pr_debug("ep92 power changed to %d\n", val); + if (val) + ep92_send_uevent(ep92, "EP92EVT_POWER=ON"); + else + ep92_send_uevent(ep92, "EP92EVT_POWER=OFF"); } if (change & EP92_GC_AUDIO_PATH_MASK) { - pr_debug("ep92 audio_path changed to %d (%s)\n", - (ep92->gc.ctl >> EP92_GC_AUDIO_PATH_SHIFT) & - EP92_2CHOICE_MASK, - ep92_aud_path_text[(ep92->gc.ctl - >> EP92_GC_AUDIO_PATH_SHIFT) & EP92_2CHOICE_MASK]); - send_uevent = true; + val = (ep92->gc.ctl >> EP92_GC_AUDIO_PATH_SHIFT) & + EP92_2CHOICE_MASK; + pr_debug("ep92 audio_path changed to %d\n", val); + if (val) + ep92_send_uevent(ep92, "EP92EVT_AUDIO_PATH=TV"); + else + ep92_send_uevent(ep92, "EP92EVT_AUDIO_PATH=SPEAKER"); } if (change & EP92_GC_CEC_MUTE_MASK) { - pr_debug("ep92 cec_mute changed to %d (%s)\n", - (ep92->gc.ctl >> EP92_GC_CEC_MUTE_SHIFT) & - EP92_2CHOICE_MASK, - ep92_cec_mute_text[(ep92->gc.ctl - >> EP92_GC_CEC_MUTE_SHIFT) & EP92_2CHOICE_MASK]); - send_uevent = true; + val = (ep92->gc.ctl >> EP92_GC_CEC_MUTE_SHIFT) & + EP92_2CHOICE_MASK; + pr_debug("ep92 cec_mute changed to %d\n", val); + if (val) + ep92_send_uevent(ep92, "EP92EVT_CEC_MUTE=NORMAL"); + else + ep92_send_uevent(ep92, "EP92EVT_CEC_MUTE=MUTED"); } if (change & EP92_GC_ARC_EN_MASK) { - pr_debug("ep92 arc_en changed to %d (%s)\n", - ep92->gc.ctl & EP92_2CHOICE_MASK, - ep92_off_on_text[ep92->gc.ctl & EP92_2CHOICE_MASK]); - send_uevent = true; + val = ep92->gc.ctl & EP92_2CHOICE_MASK; + pr_debug("ep92 arc_en changed to %d\n", val); + if (val) + ep92_send_uevent(ep92, "EP92EVT_ARC_EN=ON"); + else + ep92_send_uevent(ep92, "EP92EVT_ARC_EN=OFF"); } old = ep92->gc.rx_sel; ep92->gc.rx_sel = snd_soc_read(codec, EP92_GENERAL_CONTROL_1); + if (ep92->gc.rx_sel == 0xff) { + pr_debug("ep92 EP92_GENERAL_CONTROL_1 read 0xff\n"); + ep92->gc.rx_sel = old; + } change = ep92->gc.rx_sel ^ old; if (change & EP92_GC_RX_SEL_MASK) { - pr_debug("ep92 rx_sel changed to %d (%s)\n", - ep92->gc.rx_sel & EP92_GC_RX_SEL_MASK, - ep92_rx_sel_text[ep92->gc.rx_sel & - EP92_GC_RX_SEL_MASK]); - send_uevent = true; + val = ep92->gc.rx_sel & EP92_GC_RX_SEL_MASK; + pr_debug("ep92 rx_sel changed to %d\n", val); + ep92_send_uevent(ep92, "EP92EVT_SRC_SEL=CHANGED"); } old = ep92->gc.cec_volume; ep92->gc.cec_volume = snd_soc_read(codec, EP92_GENERAL_CONTROL_3); + if (ep92->gc.cec_volume == 0xff) { + pr_debug("ep92 EP92_GENERAL_CONTROL_3 read 0xff\n"); + ep92->gc.cec_volume = old; + } change = ep92->gc.cec_volume ^ old; if (change & EP92_GC_CEC_VOLUME_MASK) { - pr_debug("ep92 cec_volume changed to %d\n", - ep92->gc.cec_volume & EP92_GC_CEC_VOLUME_MASK); - send_uevent = true; + val = ep92->gc.cec_volume & EP92_GC_CEC_VOLUME_MASK; + pr_debug("ep92 cec_volume changed to %d\n", val); + ep92_send_uevent(ep92, "EP92EVT_CEC_VOLUME=CHANGED"); } - if (send_uevent) - ep92_send_uevent_ctrl(ep92); -} + old = ep92->gc.link; + ep92->gc.link = snd_soc_read(codec, EP92_GENERAL_CONTROL_4); + if (ep92->gc.link == 0xff) { + pr_debug("ep92 EP92_GENERAL_CONTROL_4 read 0xff\n"); + ep92->gc.link = old; + } -static void ep92_read_audio_info(struct snd_soc_codec *codec, - struct ep92_pdata *ep92) -{ - u8 old, change; - u8 new_mode; - bool send_uevent = false; + /* implement hysteresis to prevent events on glitches */ + if (ep92->gc.link & EP92_GC_LINK_ON0_MASK) { + if (ep92->hyst_link_on0 < EP92_HYST_CNT) { + ep92->hyst_link_on0++; + if ((ep92->hyst_link_on0 == EP92_HYST_CNT) && + (ep92->filt_link_on0 == 0)) { + ep92->filt_link_on0 = 1; + pr_debug("ep92 link_on0 changed to 1\n"); + ep92_send_uevent(ep92, + "EP92EVT_LINK_ON0=CONNECTED"); + } + } + } else { + if (ep92->hyst_link_on0 > 0) { + ep92->hyst_link_on0--; + if ((ep92->hyst_link_on0 == 0) && + (ep92->filt_link_on0 == 1)) { + ep92->filt_link_on0 = 0; + pr_debug("ep92 link_on0 changed to 0\n"); + ep92_send_uevent(ep92, + "EP92EVT_LINK_ON0=DISCONNECTED"); + } + } + } + + /* implement hysteresis to prevent events on glitches */ + if (ep92->gc.link & EP92_GC_LINK_ON1_MASK) { + if (ep92->hyst_link_on1 < EP92_HYST_CNT) { + ep92->hyst_link_on1++; + if ((ep92->hyst_link_on1 == EP92_HYST_CNT) && + (ep92->filt_link_on1 == 0)) { + ep92->filt_link_on1 = 1; + pr_debug("ep92 link_on1 changed to 1\n"); + ep92_send_uevent(ep92, + "EP92EVT_LINK_ON1=CONNECTED"); + } + } + } else { + if (ep92->hyst_link_on1 > 0) { + ep92->hyst_link_on1--; + if ((ep92->hyst_link_on1 == 0) && + (ep92->filt_link_on1 == 1)) { + ep92->filt_link_on1 = 0; + pr_debug("ep92 link_on1 changed to 0\n"); + ep92_send_uevent(ep92, + "EP92EVT_LINK_ON1=DISCONNECTED"); + } + } + } + + /* implement hysteresis to prevent events on glitches */ + if (ep92->gc.link & EP92_GC_LINK_ON2_MASK) { + if (ep92->hyst_link_on2 < EP92_HYST_CNT) { + ep92->hyst_link_on2++; + if ((ep92->hyst_link_on2 == EP92_HYST_CNT) && + (ep92->filt_link_on2 == 0)) { + ep92->filt_link_on2 = 1; + pr_debug("ep92 link_on2 changed to 1\n"); + ep92_send_uevent(ep92, + "EP92EVT_LINK_ON2=CONNECTED"); + } + } + } else { + if (ep92->hyst_link_on2 > 0) { + ep92->hyst_link_on2--; + if ((ep92->hyst_link_on2 == 0) && + (ep92->filt_link_on2 == 1)) { + ep92->filt_link_on2 = 0; + pr_debug("ep92 link_on2 changed to 0\n"); + ep92_send_uevent(ep92, + "EP92EVT_LINK_ON2=DISCONNECTED"); + } + } + } +} + +static void ep92_read_audio_info(struct snd_soc_codec *codec, + struct ep92_pdata *ep92) +{ + u8 old, change; + u8 new_mode; + bool send_uevent = false; old = ep92->ai.system_status_0; ep92->ai.system_status_0 = snd_soc_read(codec, EP92_AUDIO_INFO_SYSTEM_STATUS_0); + if (ep92->ai.system_status_0 == 0xff) { + pr_debug("ep92 EP92_AUDIO_INFO_SYSTEM_STATUS_0 read 0xff\n"); + ep92->ai.system_status_0 = old; + } change = ep92->ai.system_status_0 ^ old; if (change & EP92_AI_MCLK_ON_MASK) { - pr_debug("ep92 status changed to %d (%s)\n", + pr_debug("ep92 status changed to %d\n", (ep92->ai.system_status_0 >> EP92_AI_MCLK_ON_SHIFT) & - EP92_2CHOICE_MASK, - ep92_state_text[(ep92->ai.system_status_0 - >> EP92_AI_MCLK_ON_SHIFT) & EP92_2CHOICE_MASK]); + EP92_2CHOICE_MASK); send_uevent = true; } if (change & EP92_AI_AVMUTE_MASK) { - pr_debug("ep92 avmute changed to %d (%s)\n", + pr_debug("ep92 avmute changed to %d\n", (ep92->ai.system_status_0 >> EP92_AI_AVMUTE_SHIFT) & - EP92_2CHOICE_MASK, - ep92_avmute_text[(ep92->ai.system_status_0 - >> EP92_AI_AVMUTE_SHIFT) & EP92_2CHOICE_MASK]); + EP92_2CHOICE_MASK); send_uevent = true; } if (change & EP92_AI_LAYOUT_MASK) { - pr_debug("ep92 layout changed to %d (%s)\n", - (ep92->ai.system_status_0) & EP92_2CHOICE_MASK, - ep92_layout_text[(ep92->ai.system_status_0) & - EP92_2CHOICE_MASK]); + pr_debug("ep92 layout changed to %d\n", + (ep92->ai.system_status_0) & EP92_2CHOICE_MASK); send_uevent = true; } old = ep92->ai.audio_status; ep92->ai.audio_status = snd_soc_read(codec, EP92_AUDIO_INFO_AUDIO_STATUS); + if (ep92->ai.audio_status == 0xff) { + pr_debug("ep92 EP92_AUDIO_INFO_AUDIO_STATUS read 0xff\n"); + ep92->ai.audio_status = old; + } change = ep92->ai.audio_status ^ old; if (change & EP92_AI_RATE_MASK) { pr_debug("ep92 rate changed to %d\n", @@ -1041,8 +582,13 @@ static void ep92_read_audio_info(struct snd_soc_codec *codec, new_mode = ep92->old_mode; if (ep92->ai.audio_status & EP92_AI_STD_ADO_MASK) { + old = ep92->ai.cs[0]; ep92->ai.cs[0] = snd_soc_read(codec, EP92_AUDIO_INFO_CHANNEL_STATUS_0); + if (ep92->ai.cs[0] == 0xff) { + pr_debug("ep92 EP92_AUDIO_INFO_CHANNEL_STATUS_0 read 0xff\n"); + ep92->ai.cs[0] = old; + } if (ep92->ai.cs[0] & EP92_AI_NPCM_MASK) new_mode = 1; /* Compr */ else @@ -1051,14 +597,17 @@ static void ep92_read_audio_info(struct snd_soc_codec *codec, new_mode = 1; /* Compr */ if (ep92->old_mode != new_mode) { - pr_debug("ep92 mode changed to %d (%s)\n", new_mode, - ep92_mode_text[new_mode]); + pr_debug("ep92 mode changed to %d\n", new_mode); send_uevent = true; } ep92->old_mode = new_mode; old = ep92->ai.cc; ep92->ai.cc = snd_soc_read(codec, EP92_AUDIO_INFO_ADO_INFO_FRAME_1); + if (ep92->ai.cc == 0xff) { + pr_debug("ep92 EP92_AUDIO_INFO_ADO_INFO_FRAME_1 read 0xff\n"); + ep92->ai.cc = old; + } change = ep92->ai.cc ^ old; if (change & EP92_AI_CH_COUNT_MASK) { pr_debug("ep92 ch_count changed to %d (%d)\n", @@ -1070,6 +619,10 @@ static void ep92_read_audio_info(struct snd_soc_codec *codec, old = ep92->ai.ca; ep92->ai.ca = snd_soc_read(codec, EP92_AUDIO_INFO_ADO_INFO_FRAME_4); + if (ep92->ai.ca == 0xff) { + pr_debug("ep92 EP92_AUDIO_INFO_ADO_INFO_FRAME_4 read 0xff\n"); + ep92->ai.ca = old; + } change = ep92->ai.ca ^ old; if (change & EP92_AI_CH_ALLOC_MASK) { pr_debug("ep92 ch_alloc changed to 0x%02x\n", @@ -1078,7 +631,7 @@ static void ep92_read_audio_info(struct snd_soc_codec *codec, } if (send_uevent) - ep92_send_uevent_audio(ep92); + ep92_send_uevent(ep92, "EP92EVT_AUDIO=MEDIA_CONFIG_CHANGE"); } static void ep92_init(struct snd_soc_codec *codec, struct ep92_pdata *ep92) @@ -1117,10 +670,6 @@ static struct snd_soc_codec_driver soc_codec_drv_ep92 = { .probe = ep92_probe, .remove = ep92_remove, .get_regmap = ep92_get_regmap, - .component_driver = { - .controls = ep92_snd_controls, - .num_controls = ARRAY_SIZE(ep92_snd_controls), - }, }; static struct regmap_config ep92_regmap_config = { @@ -1205,11 +754,712 @@ static const struct of_device_id ep92_of_match[] = { }; MODULE_DEVICE_TABLE(of, ep92_of_match); +static ssize_t ep92_sysfs_rda_audio_state(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = (ep92->ai.system_status_0 & EP92_AI_MCLK_ON_MASK) >> + EP92_AI_MCLK_ON_SHIFT; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_rda_audio_format(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = ep92->old_mode; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_rda_audio_rate(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = ep92_samp_freq_table[(ep92->ai.audio_status) & + EP92_AI_RATE_MASK]; + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_rda_audio_layout(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = (ep92->ai.system_status_0 & EP92_AI_LAYOUT_MASK) >> + EP92_AI_LAYOUT_SHIFT; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_rda_audio_ch_count(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = ep92->ai.cc & EP92_AI_CH_COUNT_MASK; + /* mapping is ch_count = reg_val + 1, with exception: 0 = unknown */ + if (val > 0) + val += 1; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_rda_audio_ch_alloc(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = ep92->ai.ca & EP92_AI_CH_ALLOC_MASK; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_rda_avmute(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + + val = (ep92->ai.system_status_0 >> EP92_AI_AVMUTE_SHIFT) & + EP92_2CHOICE_MASK; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_rda_link_on0(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = ep92->filt_link_on0; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_rda_link_on1(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = ep92->filt_link_on1; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_rda_link_on2(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = ep92->filt_link_on2; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_rda_out_plug(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = ep92->filt_tx_plug; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_rda_video_latency(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = ep92->gi.video_latency & EP92_GI_VIDEO_LATENCY_MASK; + if (val > 0) + val = (val - 1) * 2; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_rda_arc_disable(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = (ep92->gc.ctl2 >> EP92_GC_ARC_DIS_SHIFT) & + EP92_2CHOICE_MASK; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_wta_arc_disable(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int reg, val, rc; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + rc = kstrtoint(buf, 10, &val); + if (rc) { + pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + goto end; + } + if ((val < 0) || (val > 1)) { + pr_err("%s: value out of range.\n", __func__); + rc = -EINVAL; + goto end; + } + + reg = snd_soc_read(ep92->codec, EP92_GENERAL_CONTROL_2); + reg &= ~EP92_GC_ARC_DIS_MASK; + reg |= ((val << EP92_GC_ARC_DIS_SHIFT) & EP92_GC_ARC_DIS_MASK); + snd_soc_write(ep92->codec, EP92_GENERAL_CONTROL_2, reg); + ep92->gc.ctl2 &= ~EP92_GC_ARC_DIS_MASK; + ep92->gc.ctl2 |= (val << EP92_GC_ARC_DIS_SHIFT) & EP92_GC_ARC_DIS_MASK; + + rc = strnlen(buf, EP92_SYSFS_ENTRY_MAX_LEN); +end: + return rc; +} + +static ssize_t ep92_sysfs_rda_power(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = (ep92->gc.ctl >> EP92_GC_POWER_SHIFT) & EP92_2CHOICE_MASK; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_wta_power(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int reg, val, rc; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + rc = kstrtoint(buf, 10, &val); + if (rc) { + pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + goto end; + } + if ((val < 0) || (val > 1)) { + pr_err("%s: value out of range.\n", __func__); + rc = -EINVAL; + goto end; + } + + reg = snd_soc_read(ep92->codec, EP92_GENERAL_CONTROL_0); + reg &= ~EP92_GC_POWER_MASK; + reg |= (val << EP92_GC_POWER_SHIFT) & EP92_GC_POWER_MASK; + snd_soc_write(ep92->codec, EP92_GENERAL_CONTROL_0, reg); + ep92->gc.ctl &= ~EP92_GC_POWER_MASK; + ep92->gc.ctl |= (val << EP92_GC_POWER_SHIFT) & EP92_GC_POWER_MASK; + + rc = strnlen(buf, EP92_SYSFS_ENTRY_MAX_LEN); +end: + return rc; +} + +static ssize_t ep92_sysfs_rda_audio_path(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = (ep92->gc.ctl >> EP92_GC_AUDIO_PATH_SHIFT) & EP92_2CHOICE_MASK; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_wta_audio_path(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int reg, val, rc; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + rc = kstrtoint(buf, 10, &val); + if (rc) { + pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + goto end; + } + if ((val < 0) || (val > 1)) { + pr_err("%s: value out of range.\n", __func__); + rc = -EINVAL; + goto end; + } + + reg = snd_soc_read(ep92->codec, EP92_GENERAL_CONTROL_0); + reg &= ~EP92_GC_AUDIO_PATH_MASK; + reg |= (val << EP92_GC_AUDIO_PATH_SHIFT) & EP92_GC_AUDIO_PATH_MASK; + snd_soc_write(ep92->codec, EP92_GENERAL_CONTROL_0, reg); + ep92->gc.ctl &= ~EP92_GC_AUDIO_PATH_MASK; + ep92->gc.ctl |= (val << EP92_GC_AUDIO_PATH_SHIFT) & + EP92_GC_AUDIO_PATH_MASK; + + rc = strnlen(buf, EP92_SYSFS_ENTRY_MAX_LEN); +end: + return rc; +} + +static ssize_t ep92_sysfs_rda_src_sel(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = ep92->gc.rx_sel & EP92_GC_RX_SEL_MASK; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_wta_src_sel(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int reg, val, rc; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + rc = kstrtoint(buf, 10, &val); + if (rc) { + pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + goto end; + } + if ((val < 0) || (val > 7)) { + pr_err("%s: value out of range.\n", __func__); + rc = -EINVAL; + goto end; + } + + reg = snd_soc_read(ep92->codec, EP92_GENERAL_CONTROL_1); + reg &= ~EP92_GC_RX_SEL_MASK; + reg |= (val << EP92_GC_RX_SEL_SHIFT) & EP92_GC_RX_SEL_MASK; + snd_soc_write(ep92->codec, EP92_GENERAL_CONTROL_1, reg); + ep92->gc.rx_sel &= ~EP92_GC_RX_SEL_MASK; + ep92->gc.rx_sel |= (val << EP92_GC_RX_SEL_SHIFT) & EP92_GC_RX_SEL_MASK; + + rc = strnlen(buf, EP92_SYSFS_ENTRY_MAX_LEN); +end: + return rc; +} + +static ssize_t ep92_sysfs_rda_arc_enable(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = (ep92->gc.ctl >> EP92_GC_ARC_EN_SHIFT) & EP92_2CHOICE_MASK; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_wta_arc_enable(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int reg, val, rc; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + rc = kstrtoint(buf, 10, &val); + if (rc) { + pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + goto end; + } + if ((val < 0) || (val > 1)) { + pr_err("%s: value out of range.\n", __func__); + rc = -EINVAL; + goto end; + } + + reg = snd_soc_read(ep92->codec, EP92_GENERAL_CONTROL_0); + reg &= ~EP92_GC_AUDIO_PATH_MASK; + reg |= (val << EP92_GC_AUDIO_PATH_SHIFT) & EP92_GC_AUDIO_PATH_MASK; + snd_soc_write(ep92->codec, EP92_GENERAL_CONTROL_0, reg); + ep92->gc.ctl &= ~EP92_GC_AUDIO_PATH_MASK; + ep92->gc.ctl |= (val << EP92_GC_AUDIO_PATH_SHIFT) & + EP92_GC_AUDIO_PATH_MASK; + + rc = strnlen(buf, EP92_SYSFS_ENTRY_MAX_LEN); +end: + return rc; +} + +static ssize_t ep92_sysfs_rda_cec_mute(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = (ep92->gc.ctl >> EP92_GC_CEC_MUTE_SHIFT) & EP92_2CHOICE_MASK; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_wta_cec_mute(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int reg, val, rc; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + rc = kstrtoint(buf, 10, &val); + if (rc) { + pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + goto end; + } + if ((val < 0) || (val > 1)) { + pr_err("%s: value out of range.\n", __func__); + rc = -EINVAL; + goto end; + } + + reg = snd_soc_read(ep92->codec, EP92_GENERAL_CONTROL_0); + reg &= ~EP92_GC_CEC_MUTE_MASK; + reg |= (val << EP92_GC_CEC_MUTE_SHIFT) & EP92_GC_CEC_MUTE_MASK; + snd_soc_write(ep92->codec, EP92_GENERAL_CONTROL_0, reg); + ep92->gc.ctl &= ~EP92_GC_CEC_MUTE_MASK; + ep92->gc.ctl |= (val << EP92_GC_CEC_MUTE_SHIFT) & + EP92_GC_CEC_MUTE_MASK; + + rc = strnlen(buf, EP92_SYSFS_ENTRY_MAX_LEN); +end: + return rc; +} + +static ssize_t ep92_sysfs_rda_cec_volume(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + val = (ep92->gc.cec_volume >> EP92_GC_CEC_VOLUME_SHIFT) & + EP92_GC_CEC_VOLUME_MASK; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + pr_debug("%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_wta_cec_volume(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int reg, val, rc; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + rc = kstrtoint(buf, 10, &val); + if (rc) { + pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + goto end; + } + if ((val < 0) || (val > EP92_GC_CEC_VOLUME_MAX)) { + pr_err("%s: value out of range.\n", __func__); + rc = -EINVAL; + goto end; + } + + reg = val & EP92_GC_CEC_VOLUME_MASK; + snd_soc_write(ep92->codec, EP92_GENERAL_CONTROL_3, reg); + ep92->gc.cec_volume = val & EP92_GC_CEC_VOLUME_MASK; + + rc = strnlen(buf, EP92_SYSFS_ENTRY_MAX_LEN); +end: + return rc; +} + +static DEVICE_ATTR(audio_state, 0444, ep92_sysfs_rda_audio_state, NULL); +static DEVICE_ATTR(audio_format, 0444, ep92_sysfs_rda_audio_format, NULL); +static DEVICE_ATTR(audio_rate, 0444, ep92_sysfs_rda_audio_rate, NULL); +static DEVICE_ATTR(audio_layout, 0444, ep92_sysfs_rda_audio_layout, NULL); +static DEVICE_ATTR(audio_ch_count, 0444, ep92_sysfs_rda_audio_ch_count, NULL); +static DEVICE_ATTR(audio_ch_alloc, 0444, ep92_sysfs_rda_audio_ch_alloc, NULL); +static DEVICE_ATTR(audio_avmute, 0444, ep92_sysfs_rda_avmute, NULL); +static DEVICE_ATTR(link_on0, 0444, ep92_sysfs_rda_link_on0, NULL); +static DEVICE_ATTR(link_on1, 0444, ep92_sysfs_rda_link_on1, NULL); +static DEVICE_ATTR(link_on2, 0444, ep92_sysfs_rda_link_on2, NULL); +static DEVICE_ATTR(out_plug, 0444, ep92_sysfs_rda_out_plug, NULL); +static DEVICE_ATTR(video_latency, 0444, ep92_sysfs_rda_video_latency, NULL); +static DEVICE_ATTR(arc_disable, 0644, ep92_sysfs_rda_arc_disable, + ep92_sysfs_wta_arc_disable); +static DEVICE_ATTR(power_on, 0644, ep92_sysfs_rda_power, ep92_sysfs_wta_power); +static DEVICE_ATTR(audio_path, 0644, ep92_sysfs_rda_audio_path, + ep92_sysfs_wta_audio_path); +static DEVICE_ATTR(src_sel, 0644, ep92_sysfs_rda_src_sel, + ep92_sysfs_wta_src_sel); +static DEVICE_ATTR(arc_enable, 0644, ep92_sysfs_rda_arc_enable, + ep92_sysfs_wta_arc_enable); +static DEVICE_ATTR(cec_mute, 0644, ep92_sysfs_rda_cec_mute, + ep92_sysfs_wta_cec_mute); +static DEVICE_ATTR(cec_volume, 0644, ep92_sysfs_rda_cec_volume, + ep92_sysfs_wta_cec_volume); + +static struct attribute *ep92_fs_attrs[] = { + &dev_attr_audio_state.attr, + &dev_attr_audio_format.attr, + &dev_attr_audio_rate.attr, + &dev_attr_audio_layout.attr, + &dev_attr_audio_ch_count.attr, + &dev_attr_audio_ch_alloc.attr, + &dev_attr_audio_avmute.attr, + &dev_attr_link_on0.attr, + &dev_attr_link_on1.attr, + &dev_attr_link_on2.attr, + &dev_attr_out_plug.attr, + &dev_attr_video_latency.attr, + &dev_attr_arc_disable.attr, + &dev_attr_power_on.attr, + &dev_attr_audio_path.attr, + &dev_attr_src_sel.attr, + &dev_attr_arc_enable.attr, + &dev_attr_cec_mute.attr, + &dev_attr_cec_volume.attr, + NULL, +}; + +static struct attribute_group ep92_fs_attrs_group = { + .attrs = ep92_fs_attrs, +}; + +static int ep92_sysfs_create(struct i2c_client *client, + struct ep92_pdata *ep92) +{ + int rc; + + rc = sysfs_create_group(&client->dev.kobj, &ep92_fs_attrs_group); + + return rc; +} + +static void ep92_sysfs_remove(struct i2c_client *client, + struct ep92_pdata *ep92) +{ + sysfs_remove_group(&client->dev.kobj, &ep92_fs_attrs_group); +} + static int ep92_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct ep92_pdata *ep92; int ret; +#if IS_ENABLED(CONFIG_DEBUG_FS) + char debugfs_dir_name[32]; +#endif ep92 = devm_kzalloc(&client->dev, sizeof(struct ep92_pdata), GFP_KERNEL); @@ -1220,8 +1470,8 @@ static int ep92_i2c_probe(struct i2c_client *client, if (IS_ERR(ep92->regmap)) { ret = PTR_ERR(ep92->regmap); dev_err(&client->dev, - "%s %d: Failed to allocate regmap for I2C device: %d\n", - __func__, __LINE__, ret); + "%s: Failed to allocate regmap for I2C device: %d\n", + __func__, ret); return ret; } @@ -1249,6 +1499,39 @@ static int ep92_i2c_probe(struct i2c_client *client, msecs_to_jiffies(EP92_POLL_INTERVAL_OFF_MSEC)); } +#if IS_ENABLED(CONFIG_DEBUG_FS) + /* debugfs interface */ + snprintf(debugfs_dir_name, sizeof(debugfs_dir_name), "%s-%s", + client->name, dev_name(&client->dev)); + ep92->debugfs_dir = debugfs_create_dir(debugfs_dir_name, NULL); + if (!ep92->debugfs_dir) { + dev_dbg(&client->dev, + "%s: Failed to create /sys/kernel/debug/%s for debugfs\n", + __func__, debugfs_dir_name); + return -ENOMEM; + } + ep92->debugfs_file_wo = debugfs_create_file( + "write_reg_val", S_IFREG | 0444, ep92->debugfs_dir, + (void *) ep92, + &debugfs_codec_ops); + if (!ep92->debugfs_file_wo) { + dev_dbg(&client->dev, + "%s: Failed to create /sys/kernel/debug/%s/write_reg_val\n", + __func__, debugfs_dir_name); + return -ENOMEM; + } + ep92->debugfs_file_ro = debugfs_create_file( + "show_reg_dump", S_IFREG | 0444, ep92->debugfs_dir, + (void *) ep92, + &debugfs_codec_ops); + if (!ep92->debugfs_file_ro) { + dev_dbg(&client->dev, + "%s: Failed to create /sys/kernel/debug/%s/show_reg_dump\n", + __func__, debugfs_dir_name); + return -ENOMEM; + } +#endif /* CONFIG_DEBUG_FS */ + /* register codec */ ret = snd_soc_register_codec(&client->dev, &soc_codec_drv_ep92, ep92_dai, ARRAY_SIZE(ep92_dai)); @@ -1259,58 +1542,15 @@ static int ep92_i2c_probe(struct i2c_client *client, goto err_reg; } - /* Create a kset under /sys/kernel/ */ - ep92_uevent_kset = kset_create_and_add("ep92-hdmi", NULL, kernel_kobj); - if (!ep92_uevent_kset) { - pr_err("%s: error creating uevent kernel set", __func__); - ret = -EINVAL; - goto err_kset; - } - - /* uevent to signal control changes */ - ep92_uevent_ctrl = devm_kzalloc(&client->dev, - sizeof(*ep92_uevent_ctrl), GFP_KERNEL); - if (!ep92_uevent_ctrl) { - ret = -ENOMEM; - goto err_ue_ctrl; - } - - ep92_uevent_ctrl->ktype.release = ep92_release_uevent_data; - ret = ep92_init_uevent_data(ep92_uevent_ctrl, "ctrl-uevent"); + ret = ep92_sysfs_create(client, ep92); if (ret) { - dev_err(&client->dev, - "%s: Failed to init ctrl-uevent: %d\n", - __func__, ret); - goto err_ue_init_ctrl; + pr_err("%s: sysfs creation failed ret=%d\n", __func__, ret); + goto err_sysfs; } - /* uevent to signal audio format changes */ - ep92_uevent_audio = devm_kzalloc(&client->dev, - sizeof(*ep92_uevent_audio), GFP_KERNEL); - if (!ep92_uevent_audio) { - ret = -ENOMEM; - goto err_ue_audio; - } - - ep92_uevent_audio->ktype.release = ep92_release_uevent_data; - ret = ep92_init_uevent_data(ep92_uevent_audio, "audio-uevent"); - if (ret) { - dev_err(&client->dev, - "%s: Failed to init ctrl-uevent: %d\n", - __func__, ret); - goto err_ue_init_audio; - } return 0; -err_ue_init_audio: - devm_kfree(&client->dev, ep92_uevent_audio); -err_ue_audio: - ep92_destroy_uevent_data(ep92_uevent_ctrl); -err_ue_init_ctrl: - devm_kfree(&client->dev, ep92_uevent_ctrl); -err_ue_ctrl: - kset_unregister(ep92_uevent_kset); -err_kset: +err_sysfs: snd_soc_unregister_codec(&client->dev); err_reg: if (ep92->irq == 0) @@ -1324,21 +1564,17 @@ static int ep92_i2c_remove(struct i2c_client *client) struct ep92_pdata *ep92; ep92 = i2c_get_clientdata(client); - if ((ep92 != NULL) && (ep92->irq == 0)) - del_timer(&ep92->timer); + if (ep92) { + if (ep92->irq == 0) + del_timer(&ep92->timer); +#if IS_ENABLED(CONFIG_DEBUG_FS) + debugfs_remove_recursive(ep92->debugfs_dir); +#endif + } snd_soc_unregister_codec(&client->dev); - ep92_destroy_uevent_data(ep92_uevent_ctrl); - devm_kfree(&client->dev, ep92_uevent_ctrl); - - ep92_destroy_uevent_data(ep92_uevent_audio); - devm_kfree(&client->dev, ep92_uevent_audio); - - if (ep92_uevent_kset) { - kset_unregister(ep92_uevent_kset); - ep92_uevent_kset = NULL; - } + ep92_sysfs_remove(client, ep92); return 0; } diff --git a/asoc/codecs/ep92/ep92.h b/asoc/codecs/ep92/ep92.h index 237c9eac2a42..ad067ea1dc93 100644 --- a/asoc/codecs/ep92/ep92.h +++ b/asoc/codecs/ep92/ep92.h @@ -139,8 +139,13 @@ static struct reg_default ep92_reg_defaults[] = { * GC = General Control * AI = Audio Info */ -#define EP92_GI_ADO_CHF_MASK 0x01 -#define EP92_GI_CEC_ECF_MASK 0x02 +#define EP92_GI_ADO_CHF_MASK 0x01 +#define EP92_GI_CEC_ECF_MASK 0x02 +#define EP92_GI_TX_HOT_PLUG_SHIFT 7 +#define EP92_GI_TX_HOT_PLUG_MASK 0x80 +#define EP92_GI_VIDEO_LATENCY_SHIFT 0 +#define EP92_GI_VIDEO_LATENCY_MASK 0xff + #define EP92_GC_POWER_SHIFT 7 #define EP92_GC_POWER_MASK 0x80 #define EP92_GC_AUDIO_PATH_SHIFT 5 @@ -149,10 +154,19 @@ static struct reg_default ep92_reg_defaults[] = { #define EP92_GC_CEC_MUTE_MASK 0x02 #define EP92_GC_ARC_EN_SHIFT 0 #define EP92_GC_ARC_EN_MASK 0x01 +#define EP92_GC_ARC_DIS_SHIFT 6 +#define EP92_GC_ARC_DIS_MASK 0x40 #define EP92_GC_RX_SEL_SHIFT 0 #define EP92_GC_RX_SEL_MASK 0x07 #define EP92_GC_CEC_VOLUME_SHIFT 0 #define EP92_GC_CEC_VOLUME_MASK 0xff +#define EP92_GC_LINK_ON0_SHIFT 0 +#define EP92_GC_LINK_ON0_MASK 0x01 +#define EP92_GC_LINK_ON1_SHIFT 1 +#define EP92_GC_LINK_ON1_MASK 0x02 +#define EP92_GC_LINK_ON2_SHIFT 2 +#define EP92_GC_LINK_ON2_MASK 0x04 + #define EP92_AI_MCLK_ON_SHIFT 6 #define EP92_AI_MCLK_ON_MASK 0x40 #define EP92_AI_AVMUTE_SHIFT 5 -- GitLab From fa7687b233891a426767421dd0315d4035ba92af Mon Sep 17 00:00:00 2001 From: Dieter Luecking Date: Fri, 28 Sep 2018 14:21:44 +0200 Subject: [PATCH 0562/1645] dsp: Update AFE driver to support 16 ch AFE supports now MI2S interfaces with up to 16 channels. Add new APR API functions to support this. Add support for senary PCM/MI2S ports. Change-Id: I18d48eed4e9a0476363220e959a0f254aa292056 Signed-off-by: Dieter Luecking Signed-off-by: Mangesh Kunchamwar --- dsp/q6afe.c | 10 + dsp/q6audio-v2.c | 12 + include/dsp/apr_audio-v2.h | 499 ++++++++++++++++++++++++++++++++++++- include/dsp/q6afe-v2.h | 9 +- 4 files changed, 523 insertions(+), 7 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index a29011bbed10..6697208e6616 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -890,6 +890,8 @@ int afe_sizeof_cfg_cmd(u16 port_id) case AFE_PORT_ID_QUATERNARY_PCM_TX: case AFE_PORT_ID_QUINARY_PCM_RX: case AFE_PORT_ID_QUINARY_PCM_TX: + case AFE_PORT_ID_SENARY_PCM_RX: + case AFE_PORT_ID_SENARY_PCM_TX: default: pr_debug("%s: default case 0x%x\n", __func__, port_id); ret_size = SIZEOF_CFG_CMD(afe_param_id_pcm_cfg); @@ -3979,6 +3981,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, case AFE_PORT_ID_QUATERNARY_PCM_TX: case AFE_PORT_ID_QUINARY_PCM_RX: case AFE_PORT_ID_QUINARY_PCM_TX: + case AFE_PORT_ID_SENARY_PCM_RX: + case AFE_PORT_ID_SENARY_PCM_TX: cfg_type = AFE_PARAM_ID_PCM_CONFIG; break; case PRIMARY_I2S_RX: @@ -4250,6 +4254,10 @@ int afe_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_QUINARY_PCM_RX; case AFE_PORT_ID_QUINARY_PCM_TX: return IDX_AFE_PORT_ID_QUINARY_PCM_TX; + case AFE_PORT_ID_SENARY_PCM_RX: + return IDX_AFE_PORT_ID_SENARY_PCM_RX; + case AFE_PORT_ID_SENARY_PCM_TX: + return IDX_AFE_PORT_ID_SENARY_PCM_TX; case SECONDARY_I2S_RX: return IDX_SECONDARY_I2S_RX; case SECONDARY_I2S_TX: return IDX_SECONDARY_I2S_TX; case MI2S_RX: return IDX_MI2S_RX; @@ -4649,6 +4657,8 @@ int afe_open(u16 port_id, case AFE_PORT_ID_QUATERNARY_PCM_TX: case AFE_PORT_ID_QUINARY_PCM_RX: case AFE_PORT_ID_QUINARY_PCM_TX: + case AFE_PORT_ID_SENARY_PCM_RX: + case AFE_PORT_ID_SENARY_PCM_TX: cfg_type = AFE_PARAM_ID_PCM_CONFIG; break; case SECONDARY_I2S_RX: diff --git a/dsp/q6audio-v2.c b/dsp/q6audio-v2.c index 6d14234746cd..5a7fa6f62e09 100644 --- a/dsp/q6audio-v2.c +++ b/dsp/q6audio-v2.c @@ -44,6 +44,10 @@ int q6audio_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_QUINARY_PCM_RX; case AFE_PORT_ID_QUINARY_PCM_TX: return IDX_AFE_PORT_ID_QUINARY_PCM_TX; + case AFE_PORT_ID_SENARY_PCM_RX: + return IDX_AFE_PORT_ID_SENARY_PCM_RX; + case AFE_PORT_ID_SENARY_PCM_TX: + return IDX_AFE_PORT_ID_SENARY_PCM_TX; case SECONDARY_I2S_RX: return IDX_SECONDARY_I2S_RX; case SECONDARY_I2S_TX: return IDX_SECONDARY_I2S_TX; case MI2S_RX: return IDX_MI2S_RX; @@ -377,6 +381,10 @@ int q6audio_get_port_id(u16 port_id) return AFE_PORT_ID_QUINARY_PCM_RX; case AFE_PORT_ID_QUINARY_PCM_TX: return AFE_PORT_ID_QUINARY_PCM_TX; + case AFE_PORT_ID_SENARY_PCM_RX: + return AFE_PORT_ID_SENARY_PCM_RX; + case AFE_PORT_ID_SENARY_PCM_TX: + return AFE_PORT_ID_SENARY_PCM_TX; case SECONDARY_I2S_RX: return AFE_PORT_ID_SECONDARY_MI2S_RX; case SECONDARY_I2S_TX: return AFE_PORT_ID_SECONDARY_MI2S_TX; case MI2S_RX: return AFE_PORT_ID_PRIMARY_MI2S_RX; @@ -729,6 +737,8 @@ int q6audio_is_digital_pcm_interface(u16 port_id) case AFE_PORT_ID_QUATERNARY_PCM_TX: case AFE_PORT_ID_QUINARY_PCM_RX: case AFE_PORT_ID_QUINARY_PCM_TX: + case AFE_PORT_ID_SENARY_PCM_RX: + case AFE_PORT_ID_SENARY_PCM_TX: case SECONDARY_I2S_RX: case SECONDARY_I2S_TX: case MI2S_RX: @@ -898,6 +908,8 @@ int q6audio_validate_port(u16 port_id) case AFE_PORT_ID_QUATERNARY_PCM_TX: case AFE_PORT_ID_QUINARY_PCM_RX: case AFE_PORT_ID_QUINARY_PCM_TX: + case AFE_PORT_ID_SENARY_PCM_RX: + case AFE_PORT_ID_SENARY_PCM_TX: case SECONDARY_I2S_RX: case SECONDARY_I2S_TX: case MI2S_RX: diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 268f7e1885c4..87fd13b3cef4 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -212,6 +212,17 @@ struct adm_cmd_matrix_map_routings_v5 { */ #define ADM_CMD_DEVICE_OPEN_V6 0x00010356 +/* This command allows a client to open a COPP/Voice Proc the +* way as ADM_CMD_DEVICE_OPEN_V8 but supports any number channel +* of configuration. +* +* @return +* #ADM_CMDRSP_DEVICE_OPEN_V8 with the resulting status and +* COPP ID. +*/ +#define ADM_CMD_DEVICE_OPEN_V8 0x0001036A + + /* Definition for a low latency stream session. */ #define ADM_LOW_LATENCY_DEVICE_SESSION 0x2000 @@ -490,6 +501,110 @@ struct adm_cmd_device_open_v6 { */ } __packed; + +/* ADM device open endpoint payload the + * #ADM_CMD_DEVICE_OPEN_V8 command. + */ +struct adm_device_endpoint_payload { + u16 dev_num_channel; +/* Number of channels the audio COPP sends to/receives from + * the endpoint. + * Supported values: 1 to 32. + * The value is ignored for the voice processor Tx block, + * where channel + * configuration is derived from the topology ID. + */ + + u16 bit_width; +/* Bit width (in bits) that the audio COPP sends to/receives + * from the + * endpoint. The value is ignored for the voice processing + * Tx block, + * where the PCM width is 16 bits. + */ + + u32 sample_rate; +/* Sampling rate at which the audio COPP/voice processor + * Tx block + * interfaces with the endpoint. + * Supported values for voice processor Tx: 8000, 16000, + * 48000 Hz + * Supported values for audio COPP: >0 and <=192 kHz + */ + + u8 dev_channel_mapping[32]; +} __packed; + +/* ADM device open command payload of the + * #ADM_CMD_DEVICE_OPEN_V8 command. + */ +struct adm_cmd_device_open_v8 { + struct apr_hdr hdr; + u16 flags; +/* Bit width Native mode enabled : 11th bit of flag parameter +* If 11th bit of flag is set then that means matrix mixer will be +* running in native mode for bit width for this device session. +* +* Channel Native mode enabled : 12th bit of flag parameter +* If 12th bit of flag is set then that means matrix mixer will be +* running in native mode for channel configuration for this device session. +* All other bits are reserved; clients must set them to 0. +*/ + u16 mode_of_operation; +/* Specifies whether the COPP must be opened on the Tx or Rx + * path. Use the ADM_CMD_COPP_OPEN_MODE_OF_OPERATION_* macros for + * supported values and interpretation. + * Supported values: + * - 0x1 -- Rx path COPP + * - 0x2 -- Tx path live COPP + * - 0x3 -- Tx path nonlive COPP + * Live connections cause sample discarding in the Tx device + * matrix if the destination output ports do not pull them + * fast enough. Nonlive connections queue the samples + * indefinitely. + */ + u32 topology_id; +/* Audio COPP topology ID; 32-bit GUID. */ + + + u16 endpoint_id_1; +/* Logical and physical endpoint ID of the audio path. + * If the ID is a voice processor Tx block, it receives near + * samples. + * Supported values: Any pseudoport, AFE Rx port, + * or AFE Tx port For a list of valid IDs, refer to + * @xhyperref{Q4,[Q4]}. + * Q4 = Hexagon Multimedia: AFE Interface Specification + */ + + u16 endpoint_id_2; +/* Logical and physical endpoint ID 2 for a voice processor + * Tx block. + * This is not applicable to audio COPP. + * Supported values: + * - AFE Rx port + * - 0xFFFF -- Endpoint 2 is unavailable and the voice + * processor Tx + * block ignores this endpoint + * When the voice processor Tx block is created on the audio + * record path, + * it can receive far-end samples from an AFE Rx port if the + * voice call + * is active. The ID of the AFE port is provided in this + * field. + * For a list of valid IDs, refer @xhyperref{Q4,[Q4]}. + */ + + u16 endpoint_id_3; +/* + * Logical and physical endpoint ID of the audio path. + * This indicated afe rx port in ADM loopback use cases. + * In all other use cases this should be set to 0xffff + */ + + u16 reserved; +} __packed; + /* * This command allows the client to close a COPP and disconnect * the device session. @@ -620,6 +735,9 @@ struct adm_cmd_rsp_device_open_v5 { /* Returns the status and COPP ID to an #ADM_CMD_DEVICE_OPEN_V6 command. */ #define ADM_CMDRSP_DEVICE_OPEN_V6 0x00010357 +/* Returns the status and COPP ID to an #ADM_CMD_DEVICE_OPEN_V8 command. */ +#define ADM_CMDRSP_DEVICE_OPEN_V8 0x0001036B + /* Payload of the #ADM_CMDRSP_DEVICE_OPEN_V6 message, * which returns the * status and COPP ID to an #ADM_CMD_DEVICE_OPEN_V6 command @@ -804,6 +922,12 @@ struct audproc_enable_param_t { */ #define ADM_CMD_MATRIX_RAMP_GAINS_V5 0x0001032C +/* + * Allows a client to control the gains on various session-to-COPP paths. + * Maximum support 32 channels + */ +#define ADM_CMD_MATRIX_RAMP_GAINS_V7 0x0001036C + /* Indicates that the target gain in the * current adm_session_copp_gain_v5 * structure is to be applied to all @@ -916,12 +1040,97 @@ struct adm_session_copp_gain_v5 { /* Target linear gain for channel 8 in Q13 format; */ } __packed; +/* Payload of the #ADM_CMD_MATRIX_RAMP_GAINS_V7 command. + * Immediately following this structure are num_gains of the + * adm_session_copp_gain_v5structure. + */ +struct adm_cmd_matrix_ramp_gains_v7 { + struct apr_hdr hdr; + u32 matrix_id; +/* Specifies whether the matrix ID is Audio Rx (0) or Audio Tx (1). + * Use the ADM_MATRIX_ID_AUDIO_RX or ADM_MATRIX_ID_AUDIOX + * macros to set this field. +*/ + + u16 num_gains; + /* Number of gains being applied. */ + + u16 reserved_for_align; + /* Reserved. This field must be set to zero.*/ +} __packed; + +/* Session-to-COPP path gain structure, used by the + * #ADM_CMD_MATRIX_RAMP_GAINS_V7 command. + * This structure specifies the target + * gain (per channel) that must be applied + * to a particular session-to-COPP path in + * the audio matrix. The structure can + * also be used to apply the gain globally + * to all session-to-COPP paths that + * exist for the given session. + * The aDSP uses device channel mapping to + * determine which channel gains to + * use from this command. For example, + * if the device is configured as stereo, + * the aDSP uses only target_gain_ch_1 and + * target_gain_ch_2, and it ignores + * the others. + */ +struct adm_session_copp_gain_v7 { + u16 session_id; +/* Handle of the ASM session. + * Supported values: 1 to 8. + */ + + u16 copp_id; +/* Handle of the COPP. Gain will be applied on the Session ID + * COPP ID path. + */ + + u16 ramp_duration; +/* Duration (in milliseconds) of the ramp over + * which target gains are + * to be applied. Use + * #ADM_CMD_MATRIX_RAMP_GAINS_RAMP_DURATION_IMMEDIATE + * to indicate that gain must be applied immediately. + */ + + u16 step_duration; +/* Duration (in milliseconds) of each step in the ramp. + * This parameter is ignored if ramp_duration is equal to + * #ADM_CMD_MATRIX_RAMP_GAINS_RAMP_DURATION_IMMEDIATE. + * Supported value: 1 + */ + + u16 ramp_curve; +/* Type of ramping curve. + * Supported value: #ADM_CMD_MATRIX_RAMP_GAINS_RAMP_CURVE_LINEAR + */ + + u16 stream_type; +/* Type of stream_type. + * Supported value: #STREAM_TYPE_ASM STREAM_TYPE_LSM + */ + u16 num_channels; +/* Number of channels on which gain needs to be applied. + * Supported value: 1 to 32. + */ + u16 reserved_for_align; + /* Reserved. This field must be set to zero. */ +} __packed; + /* Allows to set mute/unmute on various session-to-COPP paths. * For every session-to-COPP path (stream-device interconnection), * mute/unmute can be set individually on the output channels. */ #define ADM_CMD_MATRIX_MUTE_V5 0x0001032D +/* Allows to set mute/unmute on various session-to-COPP paths. + * For every session-to-COPP path (stream-device interconnection), + * mute/unmute can be set individually on the output channels. + */ +#define ADM_CMD_MATRIX_MUTE_V7 0x0001036D + /* Indicates that mute/unmute in the * current adm_session_copp_mute_v5structure * is to be applied to all the session-to-COPP @@ -987,6 +1196,50 @@ struct adm_cmd_matrix_mute_v5 { /* Clients must set this field to zero.*/ } __packed; + +/* Payload of the #ADM_CMD_MATRIX_MUTE_V7 command*/ +struct adm_cmd_matrix_mute_v7 { + struct apr_hdr hdr; + u32 matrix_id; +/* Specifies whether the matrix ID is Audio Rx (0) or Audio Tx (1). + * Use the ADM_MATRIX_ID_AUDIO_RX or ADM_MATRIX_ID_AUDIOX + * macros to set this field. + */ + + u16 session_id; +/* Handle of the ASM session. + * Supported values: 1 to . + */ + + u16 copp_id; +/* Handle of the COPP. + * Use ADM_CMD_MATRIX_MUTE_COPP_ID_ALL_CONNECTED_COPPS + * to indicate that mute/unmute must be applied to + * all the COPPs connected to session_id. + * Supported values: + * - 0xFFFF -- Apply mute/unmute to all connected COPPs + * - Other values -- Valid COPP ID + */ + + u16 ramp_duration; +/* Duration (in milliseconds) of the ramp over + * which target gains are + * to be applied. Use + * #ADM_CMD_MATRIX_RAMP_GAINS_RAMP_DURATION_IMMEDIATE + * to indicate that gain must be applied immediately. + */ + + u16 stream_type; +/* Specify whether the stream type is connectedon the ASM or LSM + * Supported value: 1 + */ + u16 num_channels; +/* Number of channels on which gain needs to be applied + * Supported value: 1 to 32 + */ +} __packed; + + #define ASM_PARAM_ID_AAC_STEREO_MIX_COEFF_SELECTION_FLAG_V2 (0x00010DD8) struct asm_aac_stereo_mix_coeff_selection_param_v2 { @@ -1235,13 +1488,19 @@ struct adm_cmd_connect_afe_port_v5 { /* ID of the Internal 6 MI2S Tx port */ #define AFE_PORT_ID_INT6_MI2S_TX 0x103B -#define AFE_PORT_ID_QUINARY_PCM_RX 0x103C -#define AFE_PORT_ID_QUINARY_PCM_TX 0x103D +#define AFE_PORT_ID_QUINARY_PCM_RX 0x103C +#define AFE_PORT_ID_QUINARY_PCM_TX 0x103D + +/* ID of the senary auxiliary PCM Rx port. */ +#define AFE_PORT_ID_SENARY_PCM_RX 0x103E +/* ID of the senary auxiliary PCM Tx port. */ +#define AFE_PORT_ID_SENARY_PCM_TX 0x103F -#define AFE_PORT_ID_PRIMARY_SPDIF_RX 0x5000 -#define AFE_PORT_ID_PRIMARY_SPDIF_TX 0x5001 -#define AFE_PORT_ID_SECONDARY_SPDIF_RX 0x5002 -#define AFE_PORT_ID_SECONDARY_SPDIF_TX 0x5003 +#define AFE_PORT_ID_PRIMARY_SPDIF_RX 0x5000 +#define AFE_PORT_ID_PRIMARY_SPDIF_TX 0x5001 +#define AFE_PORT_ID_SECONDARY_SPDIF_RX 0x5002 +#define AFE_PORT_ID_SECONDARY_SPDIF_TX 0x5003 +#define AFE_PORT_ID_SPDIF_RX AFE_PORT_ID_PRIMARY_SPDIF_RX #define AFE_PORT_ID_RT_PROXY_PORT_001_RX 0x2000 #define AFE_PORT_ID_RT_PROXY_PORT_001_TX 0x2001 @@ -2248,6 +2507,17 @@ struct afe_port_data_cmd_rt_proxy_port_read_v2 { #define AFE_PORT_I2S_QUAD23 0x6 #define AFE_PORT_I2S_6CHS 0x7 #define AFE_PORT_I2S_8CHS 0x8 +#define AFE_PORT_I2S_10CHS 0x9 +#define AFE_PORT_I2S_12CHS 0xA +#define AFE_PORT_I2S_14CHS 0xB +#define AFE_PORT_I2S_16CHS 0xC +#define AFE_PORT_I2S_SD4 0xD +#define AFE_PORT_I2S_SD5 0xE +#define AFE_PORT_I2S_SD6 0xF +#define AFE_PORT_I2S_SD7 0x10 +#define AFE_PORT_I2S_QUAD45 0x11 +#define AFE_PORT_I2S_QUAD67 0x12 +#define AFE_PORT_I2S_8CHS_2 0x13 #define AFE_PORT_I2S_MONO 0x0 #define AFE_PORT_I2S_STEREO 0x1 #define AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL 0x0 @@ -2280,6 +2550,17 @@ struct afe_param_id_i2s_cfg { * - #AFE_PORT_I2S_QUAD23 * - #AFE_PORT_I2S_6CHS * - #AFE_PORT_I2S_8CHS + * - #AFE_PORT_I2S_10CHS + * - #AFE_PORT_I2S_12CHS + * - #AFE_PORT_I2S_14CHS + * - #AFE_PORT_I2S_16CHS + * - #AFE_PORT_I2S_SD4 + * - #AFE_PORT_I2S_SD5 + * - #AFE_PORT_I2S_SD6 + * - #AFE_PORT_I2S_SD7 + * - #AFE_PORT_I2S_QUAD45 + * - #AFE_PORT_I2S_QUAD67 + * - #AFE_PORT_I2S_8CHS_2 */ u16 mono_stereo; @@ -4949,15 +5230,80 @@ struct asm_softvolume_params { /* Rear right of center. */ #define PCM_CHANNEL_RRC 16 +/* Second low frequency channel. */ +#define PCM_CHANNEL_LFE2 17 + +/* Side left channel. */ +#define PCM_CHANNEL_SL 18 + +/* Side right channel. */ +#define PCM_CHANNEL_SR 19 + +/* Top front left channel. */ +#define PCM_CHANNEL_TFL 20 + +/* Left vertical height channel. */ +#define PCM_CHANNEL_LVH 20 + +/* Top front right channel. */ +#define PCM_CHANNEL_TFR 21 + +/* Right vertical height channel. */ +#define PCM_CHANNEL_RVH 21 + +/* Top center channel. */ +#define PCM_CHANNEL_TC 22 + +/* Top back left channel. */ +#define PCM_CHANNEL_TBL 23 + +/* Top back right channel. */ +#define PCM_CHANNEL_TBR 24 + +/* Top side left channel. */ +#define PCM_CHANNEL_TSL 25 + +/* Top side right channel. */ +#define PCM_CHANNEL_TSR 26 + +/* Top back center channel. */ +#define PCM_CHANNEL_TBC 27 + +/* Bottom front center channel. */ +#define PCM_CHANNEL_BFC 28 + +/* Bottom front left channel. */ +#define PCM_CHANNEL_BFL 29 + +/* Bottom front right channel. */ +#define PCM_CHANNEL_BFR 30 + +/* Left wide channel. */ +#define PCM_CHANNEL_LW 31 + +/* Right wide channel. */ +#define PCM_CHANNEL_RW 32 + +/* Left side direct channel. */ +#define PCM_CHANNEL_LSD 33 + +/* Right side direct channel. */ +#define PCM_CHANNEL_RSD 34 + #define PCM_FORMAT_MAX_NUM_CHANNEL 8 #define PCM_FORMAT_MAX_CHANNELS_9 9 +/* Used for ADM_CMD_DEVICE_OPEN_V8 */ +#define PCM_FORMAT_MAX_NUM_CHANNEL_V8 32 + #define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2 0x00010DA5 #define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3 0x00010DDC #define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V4 0x0001320C +#define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V5 0x00013222 + #define ASM_MEDIA_FMT_EVRCB_FS 0x00010BEF #define ASM_MEDIA_FMT_EVRCWB_FS 0x00010BF0 @@ -5172,6 +5518,56 @@ struct asm_multi_channel_pcm_fmt_blk_v4 { */ } __packed; + +struct asm_multi_channel_pcm_fmt_blk_v5 { + uint16_t num_channels; +/* + * Number of channels + * Supported values: 1 to 32 + */ + + uint16_t bits_per_sample; +/* + * Number of bits per sample per channel + * Supported values: 16, 24, 32 + */ + + uint32_t sample_rate; +/* + * Number of samples per second + * Supported values: 2000 to 48000, 96000,192000 Hz + */ + + uint16_t is_signed; +/* Flag that indicates that PCM samples are signed (1) */ + + uint16_t sample_word_size; +/* + * Size in bits of the word that holds a sample of a channel. + * Supported values: 12,24,32 + */ + uint16_t endianness; +/* + * Flag to indicate the endianness of the pcm sample + * Supported values: 0 - Little endian (all other formats) + * 1 - Big endian (AIFF) + */ + uint16_t mode; +/* + * Mode to provide additional info about the pcm input data. + * Supported values: 0 - Default QFs (Q15 for 16b, Q23 for packed 24b, + * Q31 for unpacked 24b or 32b) + * 15 - for 16 bit + * 23 - for 24b packed or 8.24 format + * 31 - for 24b unpacked or 32bit + */ + + uint8_t channel_mapping[32]; +/* + * Each element, i, in the array describes channel i inside the buffer where + * 0 <= i < num_channels. Unused channels are set to 0. + */ +} __packed; /* * Payload of the multichannel PCM configuration parameters in * the ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3 media format. @@ -5192,6 +5588,16 @@ struct asm_multi_channel_pcm_fmt_blk_param_v4 { struct asm_multi_channel_pcm_fmt_blk_v4 param; } __packed; +/* + * Payload of the multichannel PCM configuration parameters in + * the ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V5 media format. + */ +struct asm_multi_channel_pcm_fmt_blk_param_v5 { + struct apr_hdr hdr; + struct asm_data_cmd_media_fmt_update_v2 fmt_blk; + struct asm_multi_channel_pcm_fmt_blk_v5 param; +} __packed; + struct asm_stream_cmd_set_encdec_param { u32 param_id; /* ID of the parameter. */ @@ -5243,6 +5649,78 @@ struct asm_dec_ddp_endp_param_v2 { int endp_param_value; } __packed; +/* + * Payload of the multichannel PCM encoder configuration parameters in + * the ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V5 media format. + */ +struct asm_multi_channel_pcm_enc_cfg_v5 { + struct apr_hdr hdr; + struct asm_stream_cmd_set_encdec_param encdec; + struct asm_enc_cfg_blk_param_v2 encblk; + uint16_t num_channels; +/* + * Number of PCM channels. + * @values + * - 0 -- Native mode + * - 1 -- 8 channels + * Native mode indicates that encoding must be performed with the number + * of channels at the input. + */ + uint16_t bits_per_sample; +/* + * Number of bits per sample per channel. + * @values 16, 24 + */ + uint32_t sample_rate; +/* + * Number of samples per second. + * @values 0, 8000 to 48000 Hz + * A value of 0 indicates the native sampling rate. Encoding is + * performed at the input sampling rate. + */ + uint16_t is_signed; +/* + * Flag that indicates the PCM samples are signed (1). Currently, only + * signed PCM samples are supported. + */ + uint16_t sample_word_size; +/* + * The size in bits of the word that holds a sample of a channel. + * @values 16, 24, 32 + * 16-bit samples are always placed in 16-bit words: + * sample_word_size = 1. + * 24-bit samples can be placed in 32-bit words or in consecutive + * 24-bit words. + * - If sample_word_size = 32, 24-bit samples are placed in the + * most significant 24 bits of a 32-bit word. + * - If sample_word_size = 24, 24-bit samples are placed in + * 24-bit words. @tablebulletend + */ + uint16_t endianness; +/* + * Flag to indicate the endianness of the pcm sample + * Supported values: 0 - Little endian (all other formats) + * 1 - Big endian (AIFF) + */ + uint16_t mode; +/* + * Mode to provide additional info about the pcm input data. + * Supported values: 0 - Default QFs (Q15 for 16b, Q23 for packed 24b, + * Q31 for unpacked 24b or 32b) + * 15 - for 16 bit + * 23 - for 24b packed or 8.24 format + */ + uint8_t channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL_V8]; +/* + * Channel mapping array expected at the encoder output. + * Channel[i] mapping describes channel i inside the buffer, where + * 0 @le i < num_channels. All valid used channels must be present at + * the beginning of the array. + * If Native mode is set for the channels, this field is ignored. + * @values See Section @xref{dox:PcmChannelDefs} + */ +} __packed; + /* * Payload of the multichannel PCM encoder configuration parameters in * the ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V4 media format. @@ -10188,6 +10666,8 @@ struct avcs_fwk_ver_info { /* LSM Specific */ #define VW_FEAT_DIM (39) +#define APRV2_IDS_SERVICE_ID_ADSP_ASM_V (0x7) +#define APRV2_IDS_SERVICE_ID_ADSP_ADM_V (0x8) #define APRV2_IDS_SERVICE_ID_ADSP_LSM_V (0xD) #define APRV2_IDS_DOMAIN_ID_ADSP_V (0x4) #define APRV2_IDS_DOMAIN_ID_APPS_V (0x5) @@ -10505,6 +10985,10 @@ enum afe_lpass_clk_mode { #define Q6AFE_LPASS_CLK_ID_QUIN_PCM_EBIT 0x209 /* Clock ID for QUINARY PCM OSR */ #define Q6AFE_LPASS_CLK_ID_QUI_PCM_OSR 0x20A +/* Clock ID for Senary PCM IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEN_PCM_IBIT 0x20B +/* Clock ID for Senary PCM EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEN_PCM_EBIT 0x20C /** Clock ID for Primary TDM IBIT */ #define Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT 0x200 @@ -10549,6 +11033,9 @@ enum afe_lpass_clk_mode { */ #define AFE_CLOCK_SET_CLOCK_ID_SWR_NPL_CLK 0x307 +/* Clock ID for MCLK5 */ +#define Q6AFE_LPASS_CLK_ID_MCLK_5 0x308 + /* Clock ID for AHB HDMI input */ #define Q6AFE_LPASS_CLK_ID_AHB_HDMI_INPUT 0x400 diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index b7a6780e5da7..eb5fc834d96a 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -24,6 +24,10 @@ #define MSM_AFE_4CHANNELS 4 #define MSM_AFE_6CHANNELS 6 #define MSM_AFE_8CHANNELS 8 +#define MSM_AFE_10CHANNELS 10 +#define MSM_AFE_12CHANNELS 12 +#define MSM_AFE_14CHANNELS 14 +#define MSM_AFE_16CHANNELS 16 #define MSM_AFE_I2S_FORMAT_LPCM 0 #define MSM_AFE_I2S_FORMAT_COMPR 1 @@ -255,9 +259,12 @@ enum { IDX_SECONDARY_SPDIF_RX, IDX_PRIMARY_SPDIF_TX, IDX_SECONDARY_SPDIF_TX, - /* IDX 185 to 187 */ + /* IDX 185 to 186 */ IDX_SLIMBUS_9_RX, IDX_SLIMBUS_9_TX, + /* IDX 187 -> 189 */ + IDX_AFE_PORT_ID_SENARY_PCM_RX, + IDX_AFE_PORT_ID_SENARY_PCM_TX, AFE_MAX_PORTS }; -- GitLab From 50c5535991c5115a95fcfbf99298c0f43f7e0884 Mon Sep 17 00:00:00 2001 From: Dieter Luecking Date: Fri, 28 Sep 2018 14:29:17 +0200 Subject: [PATCH 0563/1645] dsp: Update ADM driver to support 32 ch ADM supports now up to 32 channels. Extend the ADM Channel map structures from 8 to 32 channels. Change-Id: I87b3e4cce850af92467b139da9df67fcdafaf0b0 Signed-off-by: Dieter Luecking Signed-off-by: Mangesh Kunchamwar --- dsp/q6adm.c | 580 ++++++++++++++++++++++++++++++++++------- include/dsp/q6adm-v2.h | 5 +- 2 files changed, 489 insertions(+), 96 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 191e668bb170..b39b44922242 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -104,24 +105,32 @@ struct adm_ctl { int num_ec_ref_rx_chans; int ec_ref_rx_bit_width; int ec_ref_rx_sampling_rate; + + int native_mode; }; static struct adm_ctl this_adm; struct adm_multi_ch_map { bool set_channel_map; - char channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL]; + char channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL_V8]; }; #define ADM_MCH_MAP_IDX_PLAYBACK 0 #define ADM_MCH_MAP_IDX_REC 1 static struct adm_multi_ch_map multi_ch_maps[2] = { - { false, - {0, 0, 0, 0, 0, 0, 0, 0} - }, - { false, - {0, 0, 0, 0, 0, 0, 0, 0} - } + { false, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0} + }, + { false, + {0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0} + } }; static int adm_get_parameters[MAX_COPPS_PER_PORT * ADM_GET_PARAMETER_LENGTH]; @@ -1303,7 +1312,7 @@ int adm_set_multi_ch_map(char *channel_map, int path) } memcpy(multi_ch_maps[idx].channel_mapping, channel_map, - PCM_FORMAT_MAX_NUM_CHANNEL); + PCM_FORMAT_MAX_NUM_CHANNEL_V8); multi_ch_maps[idx].set_channel_map = true; return 0; @@ -1334,7 +1343,7 @@ int adm_get_multi_ch_map(char *channel_map, int path) if (multi_ch_maps[idx].set_channel_map) { memcpy(channel_map, multi_ch_maps[idx].channel_mapping, - PCM_FORMAT_MAX_NUM_CHANNEL); + PCM_FORMAT_MAX_NUM_CHANNEL_V8); } return 0; @@ -1581,6 +1590,7 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) case ADM_CMD_DEVICE_OPEN_V5: case ADM_CMD_DEVICE_CLOSE_V5: case ADM_CMD_DEVICE_OPEN_V6: + case ADM_CMD_DEVICE_OPEN_V8: pr_debug("%s: Basic callback received, wake up.\n", __func__); atomic_set(&this_adm.copp.stat[port_idx] @@ -1680,7 +1690,8 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) switch (data->opcode) { case ADM_CMDRSP_DEVICE_OPEN_V5: - case ADM_CMDRSP_DEVICE_OPEN_V6: { + case ADM_CMDRSP_DEVICE_OPEN_V6: + case ADM_CMDRSP_DEVICE_OPEN_V8: { struct adm_cmd_rsp_device_open_v5 *open = (struct adm_cmd_rsp_device_open_v5 *)data->payload; @@ -2514,6 +2525,225 @@ int adm_arrange_mch_ep2_map(struct adm_cmd_device_open_v6 *open_v6, return rc; } +static int adm_arrange_mch_map_v8( + struct adm_device_endpoint_payload *ep_payload, + int path, + int channel_mode) +{ + int rc = 0, idx; + + memset(ep_payload->dev_channel_mapping, + 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8); + switch (path) { + case ADM_PATH_PLAYBACK: + idx = ADM_MCH_MAP_IDX_PLAYBACK; + break; + case ADM_PATH_LIVE_REC: + case ADM_PATH_NONLIVE_REC: + idx = ADM_MCH_MAP_IDX_REC; + break; + default: + goto non_mch_path; + }; + + if ((ep_payload->dev_num_channel > 2) && + multi_ch_maps[idx].set_channel_map) { + memcpy(ep_payload->dev_channel_mapping, + multi_ch_maps[idx].channel_mapping, + PCM_FORMAT_MAX_NUM_CHANNEL_V8); + } else { + if (channel_mode == 1) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FC; + } else if (channel_mode == 2) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + } else if (channel_mode == 3) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_FC; + } else if (channel_mode == 4) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_RS; + } else if (channel_mode == 5) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_FC; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_RS; + } else if (channel_mode == 6) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC; + ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS; + } else if (channel_mode == 7) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_FC; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_LFE; + ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LB; + ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RB; + ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_CS; + } else if (channel_mode == 8) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC; + ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS; + ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB; + ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB; + } else if (channel_mode == 10) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC; + ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LB; + ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RB; + ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RS; + ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_TFL; + ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TFR; + } else if (channel_mode == 12) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC; + ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LB; + ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RB; + ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RS; + ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_TFL; + ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TFR; + ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_TSL; + ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_TSR; + } else if (channel_mode == 16) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC; + ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LB; + ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RB; + ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RS; + ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_TFL; + ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TFR; + ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_TSL; + ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_TSR; + ep_payload->dev_channel_mapping[12] = PCM_CHANNEL_FLC; + ep_payload->dev_channel_mapping[13] = PCM_CHANNEL_FRC; + ep_payload->dev_channel_mapping[14] = PCM_CHANNEL_RLC; + ep_payload->dev_channel_mapping[15] = PCM_CHANNEL_RRC; + } else { + pr_err("%s: invalid num_chan %d\n", __func__, + channel_mode); + rc = -EINVAL; + goto inval_ch_mod; + } + } + +non_mch_path: +inval_ch_mod: + return rc; +} + +static int adm_arrange_mch_ep2_map_v8( + struct adm_device_endpoint_payload *ep_payload, + int channel_mode) +{ + int rc = 0; + + memset(ep_payload->dev_channel_mapping, 0, + PCM_FORMAT_MAX_NUM_CHANNEL_V8); + + if (channel_mode == 1) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FC; + } else if (channel_mode == 2) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + } else if (channel_mode == 3) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_FC; + } else if (channel_mode == 4) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_RS; + } else if (channel_mode == 5) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_FC; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_RS; + } else if (channel_mode == 6) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC; + ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS; + } else if (channel_mode == 8) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC; + ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS; + ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB; + ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB; + } else if (channel_mode == 10) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC; + ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS; + ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB; + ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB; + ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_CS; + ep_payload->dev_channel_mapping[9] = PCM_CHANNELS; + } else if (channel_mode == 12) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC; + ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS; + ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB; + ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB; + ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_TFL; + ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TFR; + ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_TSL; + ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_TSR; + } else if (channel_mode == 16) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC; + ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS; + ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB; + ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB; + ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_CS; + ep_payload->dev_channel_mapping[9] = PCM_CHANNELS; + ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_CVH; + ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_MS; + ep_payload->dev_channel_mapping[12] = PCM_CHANNEL_FLC; + ep_payload->dev_channel_mapping[13] = PCM_CHANNEL_FRC; + ep_payload->dev_channel_mapping[14] = PCM_CHANNEL_RLC; + ep_payload->dev_channel_mapping[15] = PCM_CHANNEL_RRC; + } else { + pr_err("%s: invalid num_chan %d\n", __func__, + channel_mode); + rc = -EINVAL; + } + + return rc; +} /** * adm_open - * command to send ADM open @@ -2535,10 +2765,17 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, { struct adm_cmd_device_open_v5 open; struct adm_cmd_device_open_v6 open_v6; + struct adm_cmd_device_open_v8 open_v8; + struct adm_device_endpoint_payload ep1_payload; + struct adm_device_endpoint_payload ep2_payload; + int ep1_payload_size = 0; + int ep2_payload_size = 0; int ret = 0; int port_idx, flags; int copp_idx = -1; int tmp_port = q6audio_get_port_id(port_id); + void *adm_params = NULL; + int param_size; pr_debug("%s:port %#x path:%d rate:%d mode:%d perf_mode:%d,topo_id %d\n", __func__, port_id, path, rate, channel_mode, perf_mode, @@ -2550,6 +2787,11 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); return -EINVAL; } + if (channel_mode < 0 || channel_mode > 32) { + pr_err("%s: Invalid channel number 0x%x\n", + __func__, channel_mode); + return -EINVAL; + } if (this_adm.apr == NULL) { this_adm.apr = apr_register("ADSP", "ADM", adm_callback, @@ -2643,109 +2885,241 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, if (atomic_read(&this_adm.copp.cnt[port_idx][copp_idx]) == 0) { pr_debug("%s: open ADM: port_idx: %d, copp_idx: %d\n", __func__, port_idx, copp_idx); - if ((topology == SRS_TRUMEDIA_TOPOLOGY_ID) && - perf_mode == LEGACY_PCM_MODE) { - int res; - - atomic_set(&this_adm.mem_map_index, ADM_SRS_TRUMEDIA); - msm_dts_srs_tm_ion_memmap(&this_adm.outband_memmap); - res = adm_memory_map_regions(&this_adm.outband_memmap.paddr, 0, - (uint32_t *)&this_adm.outband_memmap.size, 1); - if (res < 0) { - pr_err("%s: SRS adm_memory_map_regions failed ! addr = 0x%pK, size = %d\n", - __func__, (void *)this_adm.outband_memmap.paddr, - (uint32_t)this_adm.outband_memmap.size); - } - } - open.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - open.hdr.pkt_size = sizeof(open); - open.hdr.src_svc = APR_SVC_ADM; - open.hdr.src_domain = APR_DOMAIN_APPS; - open.hdr.src_port = tmp_port; - open.hdr.dest_svc = APR_SVC_ADM; - open.hdr.dest_domain = APR_DOMAIN_ADSP; - open.hdr.dest_port = tmp_port; - open.hdr.token = port_idx << 16 | copp_idx; - open.hdr.opcode = ADM_CMD_DEVICE_OPEN_V5; - open.flags = flags; - open.mode_of_operation = path; - open.endpoint_id_1 = tmp_port; - open.endpoint_id_2 = 0xFFFF; - - if (this_adm.ec_ref_rx && (path != 1)) { - open.endpoint_id_2 = this_adm.ec_ref_rx; - this_adm.ec_ref_rx = -1; + if ((topology == SRS_TRUMEDIA_TOPOLOGY_ID) && + perf_mode == LEGACY_PCM_MODE) { + int res; + + atomic_set(&this_adm.mem_map_index, ADM_SRS_TRUMEDIA); + msm_dts_srs_tm_ion_memmap(&this_adm.outband_memmap); + res = adm_memory_map_regions( + &this_adm.outband_memmap.paddr, 0, + (uint32_t *)&this_adm.outband_memmap.size, 1); + if (res < 0) { + pr_err("%s: SRS adm_memory_map_regions failed! addr = 0x%pK, size = %d\n", + __func__, + (void *)this_adm.outband_memmap.paddr, + (uint32_t)this_adm.outband_memmap.size); + } } - open.topology_id = topology; - open.dev_num_channel = channel_mode & 0x00FF; - open.bit_width = bit_width; - WARN_ON((perf_mode == ULTRA_LOW_LATENCY_PCM_MODE) && - (rate != ULL_SUPPORTED_SAMPLE_RATE)); - open.sample_rate = rate; + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_ADM_V) >= + ADSP_ADM_API_VERSION_V3) { + memset(&open_v8, 0, sizeof(open_v8)); + memset(&ep1_payload, 0, sizeof(ep1_payload)); + memset(&ep2_payload, 0, sizeof(ep2_payload)); + + open_v8.hdr.hdr_field = APR_HDR_FIELD( + APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + open_v8.hdr.src_svc = APR_SVC_ADM; + open_v8.hdr.src_domain = APR_DOMAIN_APPS; + open_v8.hdr.src_port = tmp_port; + open_v8.hdr.dest_svc = APR_SVC_ADM; + open_v8.hdr.dest_domain = APR_DOMAIN_ADSP; + open_v8.hdr.dest_port = tmp_port; + open_v8.hdr.token = port_idx << 16 | copp_idx; + open_v8.hdr.opcode = ADM_CMD_DEVICE_OPEN_V8; + + if (this_adm.native_mode != 0) { + open_v8.flags = flags | + (this_adm.native_mode << 11); + this_adm.native_mode = 0; + } else { + open_v8.flags = flags; + } + open_v8.mode_of_operation = path; + open_v8.endpoint_id_1 = tmp_port; + open_v8.endpoint_id_2 = 0xFFFF; + open_v8.endpoint_id_3 = 0xFFFF; + + if (this_adm.ec_ref_rx && (path != 1)) { + open_v8.endpoint_id_2 = this_adm.ec_ref_rx; + this_adm.ec_ref_rx = -1; + } - ret = adm_arrange_mch_map(&open, path, channel_mode); + open_v8.topology_id = topology; + open_v8.reserved = 0; - if (ret) - return ret; + /* variable endpoint payload */ + ep1_payload.dev_num_channel = channel_mode & 0x00FF; + ep1_payload.bit_width = bit_width; + ep1_payload.sample_rate = rate; + ret = adm_arrange_mch_map_v8(&ep1_payload, path, + channel_mode); + if (ret) + return ret; + + pr_debug("%s: port_id=0x%x %x %x topology_id=0x%X flags %x ref_ch %x\n", + __func__, open_v8.endpoint_id_1, + open_v8.endpoint_id_2, + open_v8.endpoint_id_3, + open_v8.topology_id, + open_v8.flags, + this_adm.num_ec_ref_rx_chans); + + ep1_payload_size = 8 + + roundup(ep1_payload.dev_num_channel, 4); + param_size = sizeof(struct adm_cmd_device_open_v8) + + ep1_payload_size; + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + + if ((this_adm.num_ec_ref_rx_chans != 0) && (path != 1) + && (open_v8.endpoint_id_2 != 0xFFFF)) { + ep2_payload.dev_num_channel = + this_adm.num_ec_ref_rx_chans; + this_adm.num_ec_ref_rx_chans = 0; + + if (this_adm.ec_ref_rx_bit_width != 0) { + ep2_payload.bit_width = + this_adm.ec_ref_rx_bit_width; + this_adm.ec_ref_rx_bit_width = 0; + } else { + ep2_payload.bit_width = bit_width; + } - pr_debug("%s: port_id=0x%x rate=%d topology_id=0x%X\n", - __func__, open.endpoint_id_1, open.sample_rate, - open.topology_id); + if (this_adm.ec_ref_rx_sampling_rate != 0) { + ep2_payload.sample_rate = + this_adm.ec_ref_rx_sampling_rate; + this_adm.ec_ref_rx_sampling_rate = 0; + } else { + ep2_payload.sample_rate = rate; + } - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + pr_debug("%s: adm open_v8 eid2_channels=%d eid2_bit_width=%d eid2_rate=%d\n", + __func__, + ep2_payload.dev_num_channel, + ep2_payload.bit_width, + ep2_payload.sample_rate); - if ((this_adm.num_ec_ref_rx_chans != 0) && (path != 1) && - (open.endpoint_id_2 != 0xFFFF)) { - memset(&open_v6, 0, - sizeof(struct adm_cmd_device_open_v6)); - memcpy(&open_v6, &open, - sizeof(struct adm_cmd_device_open_v5)); - open_v6.hdr.opcode = ADM_CMD_DEVICE_OPEN_V6; - open_v6.hdr.pkt_size = sizeof(open_v6); - open_v6.dev_num_channel_eid2 = - this_adm.num_ec_ref_rx_chans; - this_adm.num_ec_ref_rx_chans = 0; - - if (this_adm.ec_ref_rx_bit_width != 0) { - open_v6.bit_width_eid2 = - this_adm.ec_ref_rx_bit_width; - this_adm.ec_ref_rx_bit_width = 0; - } else { - open_v6.bit_width_eid2 = bit_width; + ret = adm_arrange_mch_ep2_map_v8(&ep2_payload, + ep2_payload.dev_num_channel); + + if (ret) + return ret; + ep2_payload_size = 8 + + roundup(ep2_payload.dev_num_channel, 4); + param_size += ep2_payload_size; } - if (this_adm.ec_ref_rx_sampling_rate != 0) { - open_v6.sample_rate_eid2 = - this_adm.ec_ref_rx_sampling_rate; - this_adm.ec_ref_rx_sampling_rate = 0; - } else { - open_v6.sample_rate_eid2 = rate; + adm_params = kzalloc(param_size, GFP_KERNEL); + if (!adm_params) + return -ENOMEM; + open_v8.hdr.pkt_size = param_size; + memcpy(adm_params, &open_v8, sizeof(open_v8)); + memcpy(adm_params + sizeof(open_v8), + (void *)&ep1_payload, + ep1_payload_size); + memcpy(adm_params + sizeof(open_v8) + + ep1_payload_size, + (void *)&ep2_payload, + ep2_payload_size); + + ret = apr_send_pkt(this_adm.apr, + (uint32_t *)adm_params); + if (ret < 0) { + pr_err("%s: port_id: 0x%x for[0x%x] failed %d for open_v8\n", + __func__, tmp_port, port_id, ret); + return -EINVAL; + } + kfree(adm_params); + } else { + + open.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + open.hdr.pkt_size = sizeof(open); + open.hdr.src_svc = APR_SVC_ADM; + open.hdr.src_domain = APR_DOMAIN_APPS; + open.hdr.src_port = tmp_port; + open.hdr.dest_svc = APR_SVC_ADM; + open.hdr.dest_domain = APR_DOMAIN_ADSP; + open.hdr.dest_port = tmp_port; + open.hdr.token = port_idx << 16 | copp_idx; + open.hdr.opcode = ADM_CMD_DEVICE_OPEN_V5; + open.flags = flags; + open.mode_of_operation = path; + open.endpoint_id_1 = tmp_port; + open.endpoint_id_2 = 0xFFFF; + + if (this_adm.ec_ref_rx && (path != 1)) { + open.endpoint_id_2 = this_adm.ec_ref_rx; + this_adm.ec_ref_rx = -1; } - pr_debug("%s: eid2_channels=%d eid2_bit_width=%d eid2_rate=%d\n", - __func__, open_v6.dev_num_channel_eid2, - open_v6.bit_width_eid2, - open_v6.sample_rate_eid2); + open.topology_id = topology; - ret = adm_arrange_mch_ep2_map(&open_v6, - open_v6.dev_num_channel_eid2); + open.dev_num_channel = channel_mode & 0x00FF; + open.bit_width = bit_width; + WARN_ON((perf_mode == ULTRA_LOW_LATENCY_PCM_MODE) && + (rate != ULL_SUPPORTED_SAMPLE_RATE)); + open.sample_rate = rate; + + ret = adm_arrange_mch_map(&open, path, channel_mode); if (ret) return ret; - ret = apr_send_pkt(this_adm.apr, (uint32_t *)&open_v6); - } else { - ret = apr_send_pkt(this_adm.apr, (uint32_t *)&open); - } - if (ret < 0) { - pr_err("%s: port_id: 0x%x for[0x%x] failed %d\n", - __func__, tmp_port, port_id, ret); - return -EINVAL; + pr_debug("%s: port_id=0x%x rate=%d topology_id=0x%X\n", + __func__, open.endpoint_id_1, open.sample_rate, + open.topology_id); + + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + + if ((this_adm.num_ec_ref_rx_chans != 0) && + (path != 1) && (open.endpoint_id_2 != 0xFFFF)) { + memset(&open_v6, 0, + sizeof(struct adm_cmd_device_open_v6)); + memcpy(&open_v6, &open, + sizeof(struct adm_cmd_device_open_v5)); + open_v6.hdr.opcode = ADM_CMD_DEVICE_OPEN_V6; + open_v6.hdr.pkt_size = sizeof(open_v6); + open_v6.dev_num_channel_eid2 = + this_adm.num_ec_ref_rx_chans; + this_adm.num_ec_ref_rx_chans = 0; + + if (this_adm.ec_ref_rx_bit_width != 0) { + open_v6.bit_width_eid2 = + this_adm.ec_ref_rx_bit_width; + this_adm.ec_ref_rx_bit_width = 0; + } else { + open_v6.bit_width_eid2 = bit_width; + } + + if (this_adm.ec_ref_rx_sampling_rate != 0) { + open_v6.sample_rate_eid2 = + this_adm.ec_ref_rx_sampling_rate; + this_adm.ec_ref_rx_sampling_rate = 0; + } else { + open_v6.sample_rate_eid2 = rate; + } + + pr_debug("%s: eid2_channels=%d eid2_bit_width=%d eid2_rate=%d\n", + __func__, open_v6.dev_num_channel_eid2, + open_v6.bit_width_eid2, + open_v6.sample_rate_eid2); + + ret = adm_arrange_mch_ep2_map(&open_v6, + open_v6.dev_num_channel_eid2); + + if (ret) + return ret; + + ret = apr_send_pkt(this_adm.apr, + (uint32_t *)&open_v6); + } else { + ret = apr_send_pkt(this_adm.apr, + (uint32_t *)&open); + } + if (ret < 0) { + pr_err("%s: port_id: 0x%x for[0x%x] failed %d\n", + __func__, tmp_port, port_id, ret); + return -EINVAL; + } } + /* Wait for the callback with copp id */ ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], atomic_read(&this_adm.copp.stat @@ -3080,6 +3454,22 @@ void adm_ec_ref_rx_sampling_rate(int sampling_rate) } EXPORT_SYMBOL(adm_ec_ref_rx_sampling_rate); +/** + * adm_set_native_mode - + * Set adm channel native mode. + * If enabled matrix mixer will be + * running in native mode for channel + * configuration for this device session. + * + */ +void adm_set_native_mode(int mode) +{ + this_adm.native_mode = mode; + pr_debug("%s: enable native_mode :%d\n", + __func__, this_adm.native_mode); +} +EXPORT_SYMBOL(adm_set_native_mode); + /** * adm_close - * command to close ADM copp diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index eafd2ad3b0e3..bf3d0f048205 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -57,7 +57,9 @@ enum { }; #define MAX_COPPS_PER_PORT 0x8 -#define ADM_MAX_CHANNELS 8 +#define ADM_MAX_CHANNELS 32 + +#define ADSP_ADM_API_VERSION_V3 3 /* multiple copp per stream. */ struct route_payload { @@ -208,4 +210,5 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, int channel_index); void msm_dts_srs_acquire_lock(void); void msm_dts_srs_release_lock(void); +void adm_set_native_mode(int mode); #endif /* __Q6_ADM_V2_H__ */ -- GitLab From 39b3e3cc9ea990a917e5b0a80dd05227cedb1b42 Mon Sep 17 00:00:00 2001 From: Dieter Luecking Date: Fri, 28 Sep 2018 14:32:07 +0200 Subject: [PATCH 0564/1645] dsp: Update ASM driver to support 32 ch ASM supports now up to 32 channels. Extend the ASM Channel map structures from 8 to 32 channels. Change-Id: I958d15910785cf0c5707dec432b4dd3e272c3dc1 Signed-off-by: Dieter Luecking Signed-off-by: Mangesh Kunchamwar --- dsp/q6asm.c | 472 +++++++++++++++++++++++++++++++++++++++++ include/dsp/q6asm-v2.h | 41 ++++ 2 files changed, 513 insertions(+) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 74fd1cfc6e5b..7a8b941f1024 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "adsp_err.h" #define TRUE 0x01 @@ -228,6 +229,9 @@ static inline uint32_t q6asm_get_pcm_format_id(uint32_t media_format_block_ver) uint32_t pcm_format_id; switch (media_format_block_ver) { + case PCM_MEDIA_FORMAT_V5: + pcm_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V5; + break; case PCM_MEDIA_FORMAT_V4: pcm_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V4; break; @@ -3144,6 +3148,25 @@ int q6asm_open_read_v4(struct audio_client *ac, uint32_t format, } EXPORT_SYMBOL(q6asm_open_read_v4); + +/* + * asm_open_read_v5 - Opens audio capture session + * + * @ac: Client session handle + * @format: encoder format + * @bits_per_sample: bit width of capture session + * @ts_mode: timestamp mode + */ +int q6asm_open_read_v5(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample, bool ts_mode, uint32_t enc_cfg_id) +{ + return __q6asm_open_read(ac, format, bits_per_sample, + PCM_MEDIA_FORMAT_V5 /*media fmt block ver*/, + ts_mode, enc_cfg_id); +} +EXPORT_SYMBOL(q6asm_open_read_v5); + + /** * q6asm_open_write_compressed - * command to open ASM in compressed write mode @@ -3491,6 +3514,23 @@ int q6asm_stream_open_write_v3(struct audio_client *ac, uint32_t format, } EXPORT_SYMBOL(q6asm_stream_open_write_v3); +/* + * q6asm_open_write_v5 - Opens audio playback session + * + * @ac: Client session handle + * @format: decoder format + * @bits_per_sample: bit width of playback session + */ +int q6asm_open_write_v5(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample) +{ + return __q6asm_open_write(ac, format, bits_per_sample, + ac->stream_id, false /*gapless*/, + PCM_MEDIA_FORMAT_V5 /*pcm_format_block_ver*/); +} +EXPORT_SYMBOL(q6asm_open_write_v5); + + /* * q6asm_stream_open_write_v4 - Creates audio stream for playback * @@ -3510,6 +3550,26 @@ int q6asm_stream_open_write_v4(struct audio_client *ac, uint32_t format, } EXPORT_SYMBOL(q6asm_stream_open_write_v4); +/* + * q6asm_stream_open_write_v5 - Creates audio stream for playback + * + * @ac: Client session handle + * @format: asm playback format + * @bits_per_sample: bit width of requested stream + * @stream_id: stream id of stream to be associated with this session + * @is_gapless_mode: true if gapless mode needs to be enabled + */ +int q6asm_stream_open_write_v5(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample, int32_t stream_id, + bool is_gapless_mode) +{ + return __q6asm_open_write(ac, format, bits_per_sample, + stream_id, is_gapless_mode, + PCM_MEDIA_FORMAT_V5 /*pcm_format_block_ver*/); +} +EXPORT_SYMBOL(q6asm_stream_open_write_v5); + + static int __q6asm_open_read_write(struct audio_client *ac, uint32_t rd_format, uint32_t wr_format, bool is_meta_data_mode, uint32_t bits_per_sample, @@ -4747,6 +4807,108 @@ int q6asm_set_encdec_chan_map(struct audio_client *ac, } EXPORT_SYMBOL(q6asm_set_encdec_chan_map); +/* + * q6asm_enc_cfg_blk_pcm_v5 - sends encoder configuration parameters + * + * @ac: Client session handle + * @rate: sample rate + * @channels: number of channels + * @bits_per_sample: bit width of encoder session + * @use_default_chmap: true if default channel map to be used + * @use_back_flavor: to configure back left and right channel + * @channel_map: input channel map + * @sample_word_size: Size in bits of the word that holds a sample of a channel + * @endianness: endianness of the pcm data + * @mode: Mode to provide additional info about the pcm input data + */ +static int q6asm_enc_cfg_blk_pcm_v5(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, bool use_default_chmap, + bool use_back_flavor, u8 *channel_map, + uint16_t sample_word_size, uint16_t endianness, + uint16_t mode) +{ + struct asm_multi_channel_pcm_enc_cfg_v5 enc_cfg; + struct asm_enc_cfg_blk_param_v2 enc_fg_blk; + u8 *channel_mapping; + u32 frames_per_buf = 0; + int rc; + + if (!use_default_chmap && (channel_map == NULL)) { + pr_err("%s: No valid chan map and can't use default\n", + __func__); + rc = -EINVAL; + goto fail_cmd; + } + + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, + ac->session, rate, channels, + bits_per_sample, sample_word_size); + + memset(&enc_cfg, 0, sizeof(enc_cfg)); + q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE); + atomic_set(&ac->cmd_state, -1); + enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; + enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2; + enc_cfg.encdec.param_size = sizeof(enc_cfg) - sizeof(enc_cfg.hdr) - + sizeof(enc_cfg.encdec); + enc_cfg.encblk.frames_per_buf = frames_per_buf; + enc_cfg.encblk.enc_cfg_blk_size = enc_cfg.encdec.param_size - + sizeof(enc_fg_blk); + enc_cfg.num_channels = channels; + enc_cfg.bits_per_sample = bits_per_sample; + enc_cfg.sample_rate = rate; + enc_cfg.is_signed = 1; + enc_cfg.sample_word_size = sample_word_size; + enc_cfg.endianness = endianness; + enc_cfg.mode = mode; + channel_mapping = enc_cfg.channel_mapping; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8); + + if (use_default_chmap) { + pr_debug("%s: setting default channel map for %d channels", + __func__, channels); + if (q6asm_map_channels(channel_mapping, channels, + use_back_flavor)) { + pr_err("%s: map channels failed %d\n", + __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + } else { + pr_debug("%s: Using pre-defined channel map", __func__); + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL_V8); + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg); + if (rc < 0) { + pr_err("%s: Command open failed %d\n", __func__, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout opcode[0x%x]\n", + __func__, enc_cfg.hdr.opcode); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} +EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_v5); + /* * q6asm_enc_cfg_blk_pcm_v4 - sends encoder configuration parameters * @@ -5040,6 +5202,18 @@ int q6asm_enc_cfg_blk_pcm_v2(struct audio_client *ac, } EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_v2); +static int __q6asm_enc_cfg_blk_pcm_v5(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode) +{ + return q6asm_enc_cfg_blk_pcm_v5(ac, rate, channels, + bits_per_sample, true, false, NULL, + sample_word_size, endianness, mode); +} + static int __q6asm_enc_cfg_blk_pcm_v4(struct audio_client *ac, uint32_t rate, uint32_t channels, uint16_t bits_per_sample, @@ -5137,6 +5311,31 @@ int q6asm_enc_cfg_blk_pcm_format_support_v4(struct audio_client *ac, } EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_format_support_v4); +/* + * q6asm_enc_cfg_blk_pcm_format_support_v5 - sends encoder configuration + * parameters + * + * @ac: Client session handle + * @rate: sample rate + * @channels: number of channels + * @bits_per_sample: bit width of encoder session + * @sample_word_size: Size in bits of the word that holds a sample of a channel + * @endianness: endianness of the pcm data + * @mode: Mode to provide additional info about the pcm input data + */ +int q6asm_enc_cfg_blk_pcm_format_support_v5(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode) +{ + return __q6asm_enc_cfg_blk_pcm_v5(ac, rate, channels, + bits_per_sample, sample_word_size, + endianness, mode); +} + +EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_format_support_v5); /** * q6asm_enc_cfg_blk_pcm_native - * command to set encode config block for pcm_native @@ -5274,6 +5473,44 @@ static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, lchannel_mapping[5] = PCM_CHANNEL_RB; lchannel_mapping[6] = PCM_CHANNEL_LS; lchannel_mapping[7] = PCM_CHANNEL_RS; + } else if (channels == 12) { + /* + * Configured for 7.1.4 channel mapping + * Todo: Needs to be checked + */ + lchannel_mapping[0] = PCM_CHANNEL_FL; + lchannel_mapping[1] = PCM_CHANNEL_FR; + lchannel_mapping[2] = PCM_CHANNEL_FC; + lchannel_mapping[3] = PCM_CHANNEL_LFE; + lchannel_mapping[4] = PCM_CHANNEL_LB; + lchannel_mapping[5] = PCM_CHANNEL_RB; + lchannel_mapping[6] = PCM_CHANNEL_LS; + lchannel_mapping[7] = PCM_CHANNEL_RS; + lchannel_mapping[8] = PCM_CHANNEL_TFL; + lchannel_mapping[9] = PCM_CHANNEL_TFR; + lchannel_mapping[10] = PCM_CHANNEL_TSL; + lchannel_mapping[11] = PCM_CHANNEL_TSR; + } else if (channels == 16) { + /* + * Configured for 7.1.8 channel mapping + * Todo: Needs to be checked + */ + lchannel_mapping[0] = PCM_CHANNEL_FL; + lchannel_mapping[1] = PCM_CHANNEL_FR; + lchannel_mapping[2] = PCM_CHANNEL_FC; + lchannel_mapping[3] = PCM_CHANNEL_LFE; + lchannel_mapping[4] = PCM_CHANNEL_LB; + lchannel_mapping[5] = PCM_CHANNEL_RB; + lchannel_mapping[6] = PCM_CHANNEL_LS; + lchannel_mapping[7] = PCM_CHANNEL_RS; + lchannel_mapping[8] = PCM_CHANNEL_TFL; + lchannel_mapping[9] = PCM_CHANNEL_TFR; + lchannel_mapping[10] = PCM_CHANNEL_TSL; + lchannel_mapping[11] = PCM_CHANNEL_TSR; + lchannel_mapping[12] = PCM_CHANNEL_FLC; + lchannel_mapping[13] = PCM_CHANNEL_FRC; + lchannel_mapping[14] = PCM_CHANNEL_RLC; + lchannel_mapping[15] = PCM_CHANNEL_RRC; } else { pr_err("%s: ERROR.unsupported num_ch = %u\n", __func__, channels); @@ -5953,6 +6190,92 @@ static int __q6asm_media_format_block_pcm_v4(struct audio_client *ac, return rc; } + +static int __q6asm_media_format_block_pcm_v5(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, + int stream_id, + bool use_default_chmap, + char *channel_map, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode) +{ + struct asm_multi_channel_pcm_fmt_blk_param_v5 fmt; + u8 *channel_mapping; + int rc; + + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, + ac->session, rate, channels, + bits_per_sample, sample_word_size); + + memset(&fmt, 0, sizeof(fmt)); + q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id); + atomic_set(&ac->cmd_state, -1); + /* + * Updated the token field with stream/session for compressed playback + * Platform driver must know the the stream with which the command is + * associated + */ + if (ac->io_mode & COMPRESSED_STREAM_IO) + fmt.hdr.token = ((ac->session << 8) & 0xFFFF00) | + (stream_id & 0xFF); + + pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x\n", + __func__, fmt.hdr.token, stream_id, ac->session); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmt_blk); + fmt.param.num_channels = (uint16_t) channels & 0xFFFF; + fmt.param.bits_per_sample = bits_per_sample; + fmt.param.sample_rate = rate; + fmt.param.is_signed = 1; + fmt.param.sample_word_size = sample_word_size; + fmt.param.endianness = endianness; + fmt.param.mode = mode; + channel_mapping = fmt.param.channel_mapping; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8); + + if (use_default_chmap) { + if (q6asm_map_channels(channel_mapping, fmt.param.num_channels, false)) { + pr_err("%s: map channels failed %d\n", + __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + } else { + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL_V8); + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s: Comamnd open failed %d\n", __func__, rc); + rc = -EINVAL; + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for format update\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + /** * q6asm_media_format_block_pcm - * command to set mediafmt block for PCM on ASM stream @@ -6084,6 +6407,47 @@ int q6asm_media_format_block_pcm_format_support_v4(struct audio_client *ac, EXPORT_SYMBOL(q6asm_media_format_block_pcm_format_support_v4); +/* + * q6asm_media_format_block_pcm_format_support_v5- sends pcm decoder + * configuration parameters + * + * @ac: Client session handle + * @rate: sample rate + * @channels: number of channels + * @bits_per_sample: bit width of encoder session + * @stream_id: stream id of stream to be associated with this session + * @use_default_chmap: true if default channel map to be used + * @channel_map: input channel map + * @sample_word_size: Size in bits of the word that holds a sample of a channel + * @endianness: endianness of the pcm data + * @mode: Mode to provide additional info about the pcm input data + */ +int q6asm_media_format_block_pcm_format_support_v5(struct audio_client *ac, + uint32_t rate, + uint32_t channels, + uint16_t bits_per_sample, + int stream_id, + bool use_default_chmap, + char *channel_map, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode) +{ + if (!use_default_chmap && (channel_map == NULL)) { + pr_err("%s: No valid chan map and can't use default\n", + __func__); + return -EINVAL; + } + return __q6asm_media_format_block_pcm_v5(ac, rate, + channels, bits_per_sample, stream_id, + use_default_chmap, channel_map, + sample_word_size, endianness, + mode); + +} +EXPORT_SYMBOL(q6asm_media_format_block_pcm_format_support_v5); + + static int __q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac, uint32_t rate, uint32_t channels, bool use_default_chmap, char *channel_map, @@ -6290,6 +6654,79 @@ static int __q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac, return rc; } +static int __q6asm_media_format_block_multi_ch_pcm_v5(struct audio_client *ac, + uint32_t rate, + uint32_t channels, + bool use_default_chmap, + char *channel_map, + uint16_t bits_per_sample, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode) +{ + struct asm_multi_channel_pcm_fmt_blk_param_v5 fmt; + u8 *channel_mapping; + int rc; + + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, + ac->session, rate, channels, + bits_per_sample, sample_word_size); + + memset(&fmt, 0, sizeof(fmt)); + q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE); + atomic_set(&ac->cmd_state, -1); + + fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; + fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) - + sizeof(fmt.fmt_blk); + fmt.param.num_channels = channels; + fmt.param.bits_per_sample = bits_per_sample; + fmt.param.sample_rate = rate; + fmt.param.is_signed = 1; + fmt.param.sample_word_size = sample_word_size; + fmt.param.endianness = endianness; + fmt.param.mode = mode; + channel_mapping = fmt.param.channel_mapping; + + memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8); + + if (use_default_chmap) { + if (q6asm_map_channels(channel_mapping, channels, false)) { + pr_err("%s: map channels failed %d\n", + __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + } else { + memcpy(channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL_V8); + } + + rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt); + if (rc < 0) { + pr_err("%s: Comamnd open failed %d\n", __func__, rc); + goto fail_cmd; + } + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + if (!rc) { + pr_err("%s: timeout. waited for format update\n", __func__); + rc = -ETIMEDOUT; + goto fail_cmd; + } + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + return 0; +fail_cmd: + return rc; +} + int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac, uint32_t rate, uint32_t channels, bool use_default_chmap, char *channel_map) @@ -6369,6 +6806,41 @@ int q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac, } EXPORT_SYMBOL(q6asm_media_format_block_multi_ch_pcm_v4); + +/* + * q6asm_media_format_block_multi_ch_pcm_v5 - sends pcm decoder configuration + * parameters + * + * @ac: Client session handle + * @rate: sample rate + * @channels: number of channels + * @bits_per_sample: bit width of encoder session + * @use_default_chmap: true if default channel map to be used + * @channel_map: input channel map + * @sample_word_size: Size in bits of the word that holds a sample of a channel + * @endianness: endianness of the pcm data + * @mode: Mode to provide additional info about the pcm input data + */ +int q6asm_media_format_block_multi_ch_pcm_v5(struct audio_client *ac, + uint32_t rate, uint32_t channels, + bool use_default_chmap, + char *channel_map, + uint16_t bits_per_sample, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode) +{ + return __q6asm_media_format_block_multi_ch_pcm_v5(ac, rate, channels, + use_default_chmap, + channel_map, + bits_per_sample, + sample_word_size, + endianness, + mode); +} +EXPORT_SYMBOL(q6asm_media_format_block_multi_ch_pcm_v5); + + /* * q6asm_media_format_block_gen_compr - set up generic compress format params * diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index 5fa03be456d5..2d738d6356ba 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -112,11 +112,14 @@ #define ASM_LITTLE_ENDIAN 0 #define ASM_BIG_ENDIAN 1 +#define ADSP_ASM_API_VERSION_V2 2 + /* PCM_MEDIA_FORMAT_Version */ enum { PCM_MEDIA_FORMAT_V2 = 0, PCM_MEDIA_FORMAT_V3, PCM_MEDIA_FORMAT_V4, + PCM_MEDIA_FORMAT_V5, }; /* PCM format modes in DSP */ @@ -296,6 +299,10 @@ int q6asm_open_read_v4(struct audio_client *ac, uint32_t format, uint16_t bits_per_sample, bool ts_mode, uint32_t enc_cfg_id); +int q6asm_open_read_v5(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample, bool ts_mode, + uint32_t enc_cfg_id); + int q6asm_open_write(struct audio_client *ac, uint32_t format /*, uint16_t bits_per_sample*/); @@ -312,6 +319,9 @@ int q6asm_open_write_v3(struct audio_client *ac, uint32_t format, int q6asm_open_write_v4(struct audio_client *ac, uint32_t format, uint16_t bits_per_sample); +int q6asm_open_write_v5(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample); + int q6asm_stream_open_write_v2(struct audio_client *ac, uint32_t format, uint16_t bits_per_sample, int32_t stream_id, bool is_gapless_mode); @@ -324,6 +334,10 @@ int q6asm_stream_open_write_v4(struct audio_client *ac, uint32_t format, uint16_t bits_per_sample, int32_t stream_id, bool is_gapless_mode); +int q6asm_stream_open_write_v5(struct audio_client *ac, uint32_t format, + uint16_t bits_per_sample, int32_t stream_id, + bool is_gapless_mode); + int q6asm_open_read_compressed(struct audio_client *ac, uint32_t format, uint32_t passthrough_flag); @@ -462,6 +476,13 @@ int q6asm_enc_cfg_blk_pcm_format_support_v4(struct audio_client *ac, uint16_t endianness, uint16_t mode); +int q6asm_enc_cfg_blk_pcm_format_support_v5(struct audio_client *ac, + uint32_t rate, uint32_t channels, + uint16_t bits_per_sample, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode); + int q6asm_enc_cfg_blk_custom(struct audio_client *ac, uint32_t sample_rate, uint32_t channels, uint32_t format, void *cfg); @@ -526,6 +547,17 @@ int q6asm_media_format_block_pcm_format_support_v4(struct audio_client *ac, uint16_t endianness, uint16_t mode); +int q6asm_media_format_block_pcm_format_support_v5(struct audio_client *ac, + uint32_t rate, + uint32_t channels, + uint16_t bits_per_sample, + int stream_id, + bool use_default_chmap, + char *channel_map, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode); + int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac, uint32_t rate, uint32_t channels, bool use_default_chmap, char *channel_map); @@ -561,6 +593,15 @@ int q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac, uint16_t endianness, uint16_t mode); +int q6asm_media_format_block_multi_ch_pcm_v5(struct audio_client *ac, + uint32_t rate, uint32_t channels, + bool use_default_chmap, + char *channel_map, + uint16_t bits_per_sample, + uint16_t sample_word_size, + uint16_t endianness, + uint16_t mode); + int q6asm_media_format_block_aac(struct audio_client *ac, struct asm_aac_cfg *cfg); -- GitLab From 70668fcb8d0b3610042afcbe77b0917e2f02bc38 Mon Sep 17 00:00:00 2001 From: Dieter Luecking Date: Fri, 28 Sep 2018 15:03:01 +0200 Subject: [PATCH 0565/1645] asoc: msm: Add support for 32 ch PCM streams do now support up to 32 channels. Extend Playback Channel Map mixer control to 32 channels. Use new DSP 32 channel API if DSP version supports it. If not fall back to 8 channels API. Change-Id: I74c4f91b0c9fab2a963690ba8143ebea36ad23dd Signed-off-by: Dieter Luecking Signed-off-by: Mangesh Kunchamwar --- asoc/msm-pcm-q6-v2.c | 76 ++++++++++++++++++++++++++++++--------- asoc/msm-pcm-q6-v2.h | 2 +- asoc/msm-pcm-routing-v2.c | 6 ++++ asoc/msm-pcm-routing-v2.h | 6 ++++ asoc/msm-qti-pp-config.c | 12 +++---- 5 files changed, 79 insertions(+), 23 deletions(-) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index f40769b4b8d9..714197487d53 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -35,6 +35,8 @@ #include #include #include +#include +#include #include "msm-pcm-q6-v2.h" #include "msm-pcm-routing-v2.h" @@ -384,11 +386,17 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) return -ENOMEM; } } else { - ret = q6asm_open_write_v4(prtd->audio_client, - fmt_type, bits_per_sample); + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= + ADSP_ASM_API_VERSION_V2) + ret = q6asm_open_write_v5(prtd->audio_client, + fmt_type, bits_per_sample); + else + ret = q6asm_open_write_v4(prtd->audio_client, + fmt_type, bits_per_sample); if (ret < 0) { - pr_err("%s: q6asm_open_write_v4 failed (%d)\n", + pr_err("%s: q6asm_open_write failed (%d)\n", __func__, ret); q6asm_audio_client_free(prtd->audio_client); prtd->audio_client = NULL; @@ -425,12 +433,25 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) runtime->channels, !prtd->set_channel_map, prtd->channel_map, bits_per_sample); } else { - ret = q6asm_media_format_block_multi_ch_pcm_v4( + + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= + ADSP_ASM_API_VERSION_V2) { + + ret = q6asm_media_format_block_multi_ch_pcm_v5( prtd->audio_client, runtime->rate, runtime->channels, !prtd->set_channel_map, prtd->channel_map, bits_per_sample, sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); + } else { + ret = q6asm_media_format_block_multi_ch_pcm_v4( + prtd->audio_client, runtime->rate, + runtime->channels, !prtd->set_channel_map, + prtd->channel_map, bits_per_sample, + sample_word_size, ASM_LITTLE_ENDIAN, + DEFAULT_QF); + } } if (ret < 0) pr_info("%s: CMD Format block failed\n", __func__); @@ -489,7 +510,15 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) __func__, params_channels(params), prtd->audio_client->perf_mode); - ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM, + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= + ADSP_ASM_API_VERSION_V2) + ret = q6asm_open_read_v5(prtd->audio_client, + FORMAT_LINEAR_PCM, + bits_per_sample, false, ENC_CFG_ID_NONE); + else + ret = q6asm_open_read_v4(prtd->audio_client, + FORMAT_LINEAR_PCM, bits_per_sample, false, ENC_CFG_ID_NONE); if (ret < 0) { pr_err("%s: q6asm_open_read failed\n", __func__); @@ -557,13 +586,28 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) pr_debug("%s: Samp_rate = %d Channel = %d bit width = %d, word size = %d\n", __func__, prtd->samp_rate, prtd->channel_mode, bits_per_sample, sample_word_size); - ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client, - prtd->samp_rate, - prtd->channel_mode, - bits_per_sample, - sample_word_size, - ASM_LITTLE_ENDIAN, - DEFAULT_QF); + + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= + ADSP_ASM_API_VERSION_V2) + ret = q6asm_enc_cfg_blk_pcm_format_support_v5( + prtd->audio_client, + prtd->samp_rate, + prtd->channel_mode, + bits_per_sample, + sample_word_size, + ASM_LITTLE_ENDIAN, + DEFAULT_QF); + else + ret = q6asm_enc_cfg_blk_pcm_format_support_v4( + prtd->audio_client, + prtd->samp_rate, + prtd->channel_mode, + bits_per_sample, + sample_word_size, + ASM_LITTLE_ENDIAN, + DEFAULT_QF); + if (ret < 0) pr_debug("%s: cmd cfg pcm was block failed", __func__); @@ -1508,7 +1552,7 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol, prtd = substream->runtime->private_data; if (prtd) { prtd->set_channel_map = true; - for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) prtd->channel_map[i] = (char)(ucontrol->value.integer.value[i]); } @@ -1536,11 +1580,11 @@ static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol, prtd = substream->runtime->private_data; if (prtd && prtd->set_channel_map == true) { - for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) ucontrol->value.integer.value[i] = (int)prtd->channel_map[i]; } else { - for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) ucontrol->value.integer.value[i] = 0; } @@ -1558,7 +1602,7 @@ static int msm_pcm_add_chmap_controls(struct snd_soc_pcm_runtime *rtd) pr_debug("%s, Channel map cntrl add\n", __func__); ret = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, snd_pcm_std_chmaps, - PCM_FORMAT_MAX_NUM_CHANNEL, 0, + PCM_FORMAT_MAX_NUM_CHANNEL_V8, 0, &chmap_info); if (ret < 0) { pr_err("%s, channel map cntrl add failed\n", __func__); diff --git a/asoc/msm-pcm-q6-v2.h b/asoc/msm-pcm-q6-v2.h index 21d09cde6e6e..201c7e580494 100644 --- a/asoc/msm-pcm-q6-v2.h +++ b/asoc/msm-pcm-q6-v2.h @@ -105,7 +105,7 @@ struct msm_audio { int mmap_flag; atomic_t pending_buffer; bool set_channel_map; - char channel_map[8]; + char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8]; int cmd_interrupt; bool meta_data_mode; uint32_t volume; diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 7292949073bf..06ad55f803cd 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -591,6 +591,12 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_INT6_MI2S_RX}, { AFE_PORT_ID_INT6_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT6_MI2S_TX}, + { AFE_PORT_ID_SENARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_AUXPCM_RX}, + { AFE_PORT_ID_SENARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_AUXPCM_TX}, + { AFE_PORT_ID_SENARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SENARY_MI2S_RX}, { AFE_PORT_ID_WSA_CODEC_DMA_RX_0, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_WSA_CDC_DMA_RX_0}, { AFE_PORT_ID_WSA_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index e9a08eb8f74b..f06dfc003cb9 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -43,6 +43,8 @@ #define LPASS_BE_QUAT_AUXPCM_TX "QUAT_AUX_PCM_TX" #define LPASS_BE_QUIN_AUXPCM_RX "QUIN_AUX_PCM_RX" #define LPASS_BE_QUIN_AUXPCM_TX "QUIN_AUX_PCM_TX" +#define LPASS_BE_SEN_AUXPCM_RX "SEN_AUX_PCM_RX" +#define LPASS_BE_SEN_AUXPCM_TX "SEN_AUX_PCM_TX" #define LPASS_BE_VOICE_PLAYBACK_TX "VOICE_PLAYBACK_TX" #define LPASS_BE_VOICE2_PLAYBACK_TX "VOICE2_PLAYBACK_TX" #define LPASS_BE_INCALL_RECORD_RX "INCALL_RECORD_RX" @@ -84,6 +86,7 @@ #define LPASS_BE_QUIN_MI2S_RX "QUIN_MI2S_RX" #define LPASS_BE_QUIN_MI2S_TX "QUIN_MI2S_TX" #define LPASS_BE_SENARY_MI2S_TX "SENARY_MI2S_TX" +#define LPASS_BE_SENARY_MI2S_RX "SENARY_MI2S_RX" #define LPASS_BE_PRI_TDM_RX_0 "PRI_TDM_RX_0" #define LPASS_BE_PRI_TDM_TX_0 "PRI_TDM_TX_0" @@ -431,6 +434,9 @@ enum { MSM_BACKEND_DAI_INT5_MI2S_TX, MSM_BACKEND_DAI_INT6_MI2S_RX, MSM_BACKEND_DAI_INT6_MI2S_TX, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_BACKEND_DAI_SENARY_MI2S_RX, MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index 7d64da66edbf..f2c6c746379b 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -809,11 +809,11 @@ static int msm_qti_pp_set_sec_auxpcm_lb_vol_mixer( static int msm_qti_pp_get_channel_map_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL] = {0}; + char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8] = {0}; int i; adm_get_multi_ch_map(channel_map, ADM_PATH_PLAYBACK); - for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) ucontrol->value.integer.value[i] = (unsigned int) channel_map[i]; return 0; @@ -822,10 +822,10 @@ static int msm_qti_pp_get_channel_map_mixer(struct snd_kcontrol *kcontrol, static int msm_qti_pp_put_channel_map_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL]; + char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8]; int i; - for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) channel_map[i] = (char)(ucontrol->value.integer.value[i]); adm_set_multi_ch_map(channel_map, ADM_PATH_PLAYBACK); @@ -1414,8 +1414,8 @@ static const struct snd_kcontrol_new sec_auxpcm_lb_vol_mixer_controls[] = { }; static const struct snd_kcontrol_new multi_ch_channel_map_mixer_controls[] = { - SOC_SINGLE_MULTI_EXT("Playback Device Channel Map", SND_SOC_NOPM, 0, 16, - 0, 8, msm_qti_pp_get_channel_map_mixer, + SOC_SINGLE_MULTI_EXT("Playback Device Channel Map", SND_SOC_NOPM, 0, 34, + 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, msm_qti_pp_get_channel_map_mixer, msm_qti_pp_put_channel_map_mixer), }; -- GitLab From 92c6a5fcfb41f98e68681cdd1c2beb3d7ed281ad Mon Sep 17 00:00:00 2001 From: Dieter Luecking Date: Fri, 28 Sep 2018 15:05:43 +0200 Subject: [PATCH 0566/1645] dai: Add support for 16ch MI2S AFE MI2S interfaces now support up to 8 data lines (16 channels). Add DAI support for the same. Change-Id: I7c507c0161733094c1260731c7a046561fb63200 Signed-off-by: Dieter Luecking Signed-off-by: Mangesh Kunchamwar --- asoc/msm-dai-fe.c | 6 +- asoc/msm-dai-q6-v2.c | 183 ++++++++++++++++++++++++++++++++++++++++--- asoc/msm-dai-q6-v2.h | 5 ++ 3 files changed, 181 insertions(+), 13 deletions(-) diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index 3dc4509fc565..7654e561f00d 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -99,7 +99,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 384000, }, @@ -113,7 +113,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 48000, }, @@ -311,7 +311,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 384000, }, diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index c24bb65f59ac..0c9d0b013eb7 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -2095,7 +2095,7 @@ static int msm_dai_q6_cdc_hw_params(struct snd_pcm_hw_params *params, return 0; } -static u8 num_of_bits_set(u8 sd_line_mask) +static u16 num_of_bits_set(u16 sd_line_mask) { u8 num_bits_set = 0; @@ -4644,11 +4644,68 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream, dai_data->channels = params_channels(params); switch (dai_data->channels) { + case 15: + case 16: + switch (mi2s_dai_config->pdata_mi2s_lines) { + case AFE_PORT_I2S_16CHS: + dai_data->port_config.i2s.channel_mode + = AFE_PORT_I2S_16CHS; + break; + default: + goto error_invalid_data; + }; + break; + case 13: + case 14: + switch (mi2s_dai_config->pdata_mi2s_lines) { + case AFE_PORT_I2S_14CHS: + case AFE_PORT_I2S_16CHS: + dai_data->port_config.i2s.channel_mode + = AFE_PORT_I2S_14CHS; + break; + default: + goto error_invalid_data; + }; + break; + case 11: + case 12: + switch (mi2s_dai_config->pdata_mi2s_lines) { + case AFE_PORT_I2S_12CHS: + case AFE_PORT_I2S_14CHS: + case AFE_PORT_I2S_16CHS: + dai_data->port_config.i2s.channel_mode + = AFE_PORT_I2S_12CHS; + break; + default: + goto error_invalid_data; + }; + break; + case 9: + case 10: + switch (mi2s_dai_config->pdata_mi2s_lines) { + case AFE_PORT_I2S_10CHS: + case AFE_PORT_I2S_12CHS: + case AFE_PORT_I2S_14CHS: + case AFE_PORT_I2S_16CHS: + dai_data->port_config.i2s.channel_mode + = AFE_PORT_I2S_10CHS; + break; + default: + goto error_invalid_data; + }; + break; case 8: case 7: if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_8CHS) goto error_invalid_data; - dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_8CHS; + else + if (mi2s_dai_config->pdata_mi2s_lines + == AFE_PORT_I2S_8CHS_2) + dai_data->port_config.i2s.channel_mode = + AFE_PORT_I2S_8CHS_2; + else + dai_data->port_config.i2s.channel_mode = + AFE_PORT_I2S_8CHS; break; case 6: case 5: @@ -4658,14 +4715,33 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream, break; case 4: case 3: - if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_QUAD01) + switch (mi2s_dai_config->pdata_mi2s_lines) { + case AFE_PORT_I2S_SD0: + case AFE_PORT_I2S_SD1: + case AFE_PORT_I2S_SD2: + case AFE_PORT_I2S_SD3: + case AFE_PORT_I2S_SD4: + case AFE_PORT_I2S_SD5: + case AFE_PORT_I2S_SD6: + case AFE_PORT_I2S_SD7: goto error_invalid_data; - if (mi2s_dai_config->pdata_mi2s_lines == AFE_PORT_I2S_QUAD23) + break; + case AFE_PORT_I2S_QUAD01: + case AFE_PORT_I2S_QUAD23: + case AFE_PORT_I2S_QUAD45: + case AFE_PORT_I2S_QUAD67: dai_data->port_config.i2s.channel_mode = mi2s_dai_config->pdata_mi2s_lines; - else + break; + case AFE_PORT_I2S_8CHS_2: + dai_data->port_config.i2s.channel_mode = + AFE_PORT_I2S_QUAD45; + break; + default: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_QUAD01; + break; + }; break; case 2: case 1: @@ -4676,12 +4752,20 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream, case AFE_PORT_I2S_SD1: case AFE_PORT_I2S_SD2: case AFE_PORT_I2S_SD3: + case AFE_PORT_I2S_SD4: + case AFE_PORT_I2S_SD5: + case AFE_PORT_I2S_SD6: + case AFE_PORT_I2S_SD7: dai_data->port_config.i2s.channel_mode = mi2s_dai_config->pdata_mi2s_lines; break; case AFE_PORT_I2S_QUAD01: case AFE_PORT_I2S_6CHS: case AFE_PORT_I2S_8CHS: + case AFE_PORT_I2S_10CHS: + case AFE_PORT_I2S_12CHS: + case AFE_PORT_I2S_14CHS: + case AFE_PORT_I2S_16CHS: if (dai_data->vi_feed_mono == SPKR_1) dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_SD0; @@ -4693,6 +4777,14 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream, dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_SD2; break; + case AFE_PORT_I2S_QUAD45: + dai_data->port_config.i2s.channel_mode = + AFE_PORT_I2S_SD4; + break; + case AFE_PORT_I2S_QUAD67: + dai_data->port_config.i2s.channel_mode = + AFE_PORT_I2S_SD6; + break; } if (dai_data->channels == 2) dai_data->port_config.i2s.mono_stereo = @@ -4864,15 +4956,17 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .stream_name = "Primary MI2S Playback", .aif_name = "PRI_MI2S_RX", .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | - SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | - SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_192000, + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE, .rate_min = 8000, - .rate_max = 192000, + .rate_max = 384000, }, .capture = { .stream_name = "Primary MI2S Capture", @@ -5257,6 +5351,18 @@ static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr, case MSM_MI2S_SD3: *config_ptr = AFE_PORT_I2S_SD3; break; + case MSM_MI2S_SD4: + *config_ptr = AFE_PORT_I2S_SD4; + break; + case MSM_MI2S_SD5: + *config_ptr = AFE_PORT_I2S_SD5; + break; + case MSM_MI2S_SD6: + *config_ptr = AFE_PORT_I2S_SD6; + break; + case MSM_MI2S_SD7: + *config_ptr = AFE_PORT_I2S_SD7; + break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); @@ -5271,6 +5377,12 @@ static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr, case MSM_MI2S_SD2 | MSM_MI2S_SD3: *config_ptr = AFE_PORT_I2S_QUAD23; break; + case MSM_MI2S_SD4 | MSM_MI2S_SD5: + *config_ptr = AFE_PORT_I2S_QUAD45; + break; + case MSM_MI2S_SD6 | MSM_MI2S_SD7: + *config_ptr = AFE_PORT_I2S_QUAD67; + break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); @@ -5293,6 +5405,57 @@ static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr, case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3: *config_ptr = AFE_PORT_I2S_8CHS; break; + case MSM_MI2S_SD4 | MSM_MI2S_SD5 | MSM_MI2S_SD6 | MSM_MI2S_SD7: + *config_ptr = AFE_PORT_I2S_8CHS_2; + break; + default: + pr_err("%s: invalid SD lines %d\n", + __func__, sd_lines); + goto error_invalid_data; + } + break; + case 5: + switch (sd_lines) { + case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 + | MSM_MI2S_SD3 | MSM_MI2S_SD4: + *config_ptr = AFE_PORT_I2S_10CHS; + break; + default: + pr_err("%s: invalid SD lines %d\n", + __func__, sd_lines); + goto error_invalid_data; + } + break; + case 6: + switch (sd_lines) { + case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 + | MSM_MI2S_SD3 | MSM_MI2S_SD4 | MSM_MI2S_SD5: + *config_ptr = AFE_PORT_I2S_12CHS; + break; + default: + pr_err("%s: invalid SD lines %d\n", + __func__, sd_lines); + goto error_invalid_data; + } + break; + case 7: + switch (sd_lines) { + case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3 + | MSM_MI2S_SD4 | MSM_MI2S_SD5 | MSM_MI2S_SD6: + *config_ptr = AFE_PORT_I2S_14CHS; + break; + default: + pr_err("%s: invalid SD lines %d\n", + __func__, sd_lines); + goto error_invalid_data; + } + break; + case 8: + switch (sd_lines) { + case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3 + | MSM_MI2S_SD4 | MSM_MI2S_SD5 | MSM_MI2S_SD6 | MSM_MI2S_SD7: + *config_ptr = AFE_PORT_I2S_16CHS; + break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); diff --git a/asoc/msm-dai-q6-v2.h b/asoc/msm-dai-q6-v2.h index b3f457e9e544..2327cfd72eca 100644 --- a/asoc/msm-dai-q6-v2.h +++ b/asoc/msm-dai-q6-v2.h @@ -18,6 +18,11 @@ #define MSM_MI2S_SD1 (1 << 1) #define MSM_MI2S_SD2 (1 << 2) #define MSM_MI2S_SD3 (1 << 3) +#define MSM_MI2S_SD4 (1 << 4) +#define MSM_MI2S_SD5 (1 << 5) +#define MSM_MI2S_SD6 (1 << 6) +#define MSM_MI2S_SD7 (1 << 7) + #define MSM_MI2S_CAP_RX 0 #define MSM_MI2S_CAP_TX 1 -- GitLab From 1bf7c9038ec0cc7cdbb54ba101d1a1327f391cd9 Mon Sep 17 00:00:00 2001 From: Dieter Luecking Date: Fri, 28 Sep 2018 15:07:42 +0200 Subject: [PATCH 0567/1645] asoc: qcs405: Upgrade for 16ch and senary AIFs AFE MI2S interfaces now support up to 8 data lines (16 channels). Add support for the same. Make senary PCM and MI2S ports available. Change-Id: I810dbe1c12ff091b3b4604d9e59f7015e3a55c98 Signed-off-by: Dieter Luecking Signed-off-by: Mangesh Kunchamwar --- asoc/qcs405.c | 145 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 131 insertions(+), 14 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index c819bb869cea..e7b9d7177e86 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -9,7 +9,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ - #include #include #include @@ -108,6 +107,7 @@ enum { TERT_MI2S, QUAT_MI2S, QUIN_MI2S, + SEN_MI2S, MI2S_MAX, }; @@ -117,6 +117,7 @@ enum { TERT_AUX_PCM, QUAT_AUX_PCM, QUIN_AUX_PCM, + SEN_AUX_PCM, AUX_PCM_MAX, }; @@ -158,7 +159,8 @@ static u32 mi2s_ebit_clk[MI2S_MAX] = { Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT, Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT, Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT, - Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT + Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_SEN_MI2S_EBIT }; struct dev_config { @@ -191,6 +193,7 @@ struct msm_asoc_mach_data { struct regulator *tdm_micb_supply; u32 tdm_micb_voltage; u32 tdm_micb_current; + bool codec_is_csra; }; struct msm_asoc_wcd93xx_codec { @@ -279,7 +282,6 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ } - }; /* TDM default config */ @@ -401,6 +403,7 @@ static struct dev_config mi2s_rx_cfg[] = { [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SEN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, }; /* Default configuration of SPDIF channels */ @@ -420,6 +423,7 @@ static struct dev_config mi2s_tx_cfg[] = { [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; static struct dev_config aux_pcm_rx_cfg[] = { @@ -428,6 +432,7 @@ static struct dev_config aux_pcm_rx_cfg[] = { [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; static struct dev_config aux_pcm_tx_cfg[] = { @@ -436,6 +441,7 @@ static struct dev_config aux_pcm_tx_cfg[] = { [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; static int msm_vi_feed_tx_ch = 2; @@ -472,10 +478,12 @@ static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_16", "KHZ_22P05", "KHZ_32", "KHZ_44P1", - "KHZ_48", "KHZ_96", "KHZ_192"}; -static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", - "Eight"}; + "KHZ_48", "KHZ_96", "KHZ_192", "KHZ_384"}; +static const char *const mi2s_ch_text[] = { + "One", "Two", "Three", "Four", "Five", "Six", "Seven", + "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", + "Fourteen", "Fifteen", "Sixteen" +}; static const char *const qos_text[] = {"Disable", "Enable"}; static const char *const cdc_dma_rx_ch_text[] = {"One", "Two"}; @@ -529,21 +537,25 @@ static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sen_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sen_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_rx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_tx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); @@ -554,6 +566,8 @@ static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); @@ -653,6 +667,14 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = { Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, } }; @@ -2420,6 +2442,9 @@ static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) else if (strnstr(kcontrol->id.name, "QUIN_AUX_PCM", sizeof("QUIN_AUX_PCM"))) idx = QUIN_AUX_PCM; + else if (strnstr(kcontrol->id.name, "SEN_AUX_PCM", + sizeof("SENN_AUX_PCM"))) + idx = SEN_AUX_PCM; else { pr_err("%s: unsupported port: %s", __func__, kcontrol->id.name); @@ -2520,6 +2545,9 @@ static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) else if (strnstr(kcontrol->id.name, "QUIN_MI2S_RX", sizeof("QUIN_MI2S_RX"))) idx = QUIN_MI2S; + else if (strnstr(kcontrol->id.name, "SEN_MI2S_RX", + sizeof("SEN_MI2S_RX"))) + idx = SEN_MI2S; else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", sizeof("PRIM_MI2S_TX"))) idx = PRIM_MI2S; @@ -2535,6 +2563,9 @@ static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) else if (strnstr(kcontrol->id.name, "QUIN_MI2S_TX", sizeof("QUIN_MI2S_TX"))) idx = QUIN_MI2S; + else if (strnstr(kcontrol->id.name, "SEN_MI2S_TX", + sizeof("SEN_MI2S_TX"))) + idx = SEN_MI2S; else { pr_err("%s: unsupported channel: %s", __func__, kcontrol->id.name); @@ -2576,6 +2607,9 @@ static int mi2s_get_sample_rate_val(int sample_rate) case SAMPLING_RATE_192KHZ: sample_rate_val = 8; break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 9; + break; default: sample_rate_val = 6; break; @@ -2615,6 +2649,9 @@ static int mi2s_get_sample_rate(int value) case 8: sample_rate = SAMPLING_RATE_192KHZ; break; + case 9: + sample_rate = SAMPLING_RATE_384KHZ; + break; default: sample_rate = SAMPLING_RATE_48KHZ; break; @@ -2823,17 +2860,34 @@ static int msm_mi2s_rx_format_get(struct snd_kcontrol *kcontrol, static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + + struct msm_asoc_mach_data *pdata = NULL; + struct snd_soc_component *component = NULL; + struct snd_soc_card *card = NULL; int idx = mi2s_get_port_idx(kcontrol); + component = snd_soc_kcontrol_component(kcontrol); + card = kcontrol->private_data; + pdata = snd_soc_card_get_drvdata(card); + if (idx < 0) return idx; - mi2s_rx_cfg[idx].bit_format = - mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + /* check for PRIM_MI2S and CSRAx config to allow 24bit BE config only */ + if ((PRIM_MI2S == idx) && (true==pdata->codec_is_csra)) + { + mi2s_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; + pr_debug("%s: Keeping default format idx[%d]_rx_format = %d, item = %d\n", + __func__, idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + } else { + mi2s_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); - pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, - idx, mi2s_rx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + } return 0; } @@ -3512,6 +3566,9 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("QUIN_AUX_PCM_TX SampleRate", quin_aux_pcm_tx_sample_rate, aux_pcm_tx_sample_rate_get, aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("SEN_AUX_PCM_TX SampleRate", sen_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, mi2s_rx_sample_rate_get, mi2s_rx_sample_rate_put), @@ -3527,6 +3584,9 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("QUIN_MI2S_RX SampleRate", quin_mi2s_rx_sample_rate, mi2s_rx_sample_rate_get, mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("SEN_MI2S_RX SampleRate", sen_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, mi2s_tx_sample_rate_get, mi2s_tx_sample_rate_put), @@ -3542,6 +3602,9 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("QUIN_MI2S_TX SampleRate", quin_mi2s_tx_sample_rate, mi2s_tx_sample_rate_get, mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("SEN_MI2S_TX SampleRate", sen_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, @@ -3562,6 +3625,10 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), SOC_ENUM_EXT("QUIN_MI2S_TX Channels", quin_mi2s_tx_chs, msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("SEN_MI2S_RX Channels", sen_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("SEN_MI2S_TX Channels", sen_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, @@ -3582,6 +3649,10 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), SOC_ENUM_EXT("QUIN_MI2S_TX Format", mi2s_tx_format, msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("SEN_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("SEN_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, @@ -3602,6 +3673,10 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), SOC_ENUM_EXT("QUIN_AUX_PCM_TX Format", aux_pcm_tx_format, msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("SEN_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("SEN_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), SOC_SINGLE_MULTI_EXT("VAD CFG", SND_SOC_NOPM, 0, 1000, 0, 3, NULL, msm_snd_vad_cfg_put), SOC_ENUM_EXT("PRIM_SPDIF_RX SampleRate", spdif_rx_sample_rate, @@ -4132,7 +4207,6 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = tdm_tx_cfg[TDM_QUIN][TDM_0].sample_rate; break; - case MSM_BACKEND_DAI_AUXPCM_RX: param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format); @@ -4223,6 +4297,24 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, aux_pcm_tx_cfg[QUIN_AUX_PCM].channels; break; + case MSM_BACKEND_DAI_SEN_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[SEN_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[SEN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[SEN_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEN_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[SEN_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[SEN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[SEN_AUX_PCM].channels; + break; + case MSM_BACKEND_DAI_PRI_MI2S_RX: param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, mi2s_rx_cfg[PRIM_MI2S].bit_format); @@ -4303,6 +4395,21 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, mi2s_tx_cfg[QUIN_MI2S].channels; break; + case MSM_BACKEND_DAI_SENARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[SEN_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[SEN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[SEN_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SENARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[SEN_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[SEN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[SEN_MI2S].channels; + break; case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0: case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1: idx = msm_cdc_dma_get_idx_from_beid(dai_link->id); @@ -4984,6 +5091,12 @@ static int msm_get_port_id(int be_id) case MSM_BACKEND_DAI_QUINARY_MI2S_TX: afe_port_id = AFE_PORT_ID_QUINARY_MI2S_TX; break; + case MSM_BACKEND_DAI_SENARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_SENARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_SENARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_SENARY_MI2S_TX; + break; default: pr_err("%s: Invalid BE id: %d\n", __func__, be_id); afe_port_id = -EINVAL; @@ -5150,7 +5263,6 @@ static int qcs405_tdm_snd_hw_params(struct snd_pcm_substream *substream, case AFE_PORT_ID_QUINARY_TDM_TX: channels = tdm_tx_cfg[TDM_QUIN][TDM_0].channels; break; - default: pr_err("%s: dai id 0x%x not supported\n", __func__, cpu_dai->id); @@ -5365,11 +5477,13 @@ static struct snd_soc_ops msm_fe_qos_ops = { .prepare = msm_fe_qos_prepare, }; + static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) { int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int index = cpu_dai->id; unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; struct snd_soc_card *card = rtd->card; @@ -8323,10 +8437,13 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) val = 0; } if (val) { + pdata->codec_is_csra = true; + mi2s_rx_cfg[PRIM_MI2S].bit_format = SNDRV_PCM_FORMAT_S24_LE; ret = msm_init_csra_dev(pdev, card); if (ret) goto err; } else { + pdata->codec_is_csra = false; ret = msm_init_wsa_dev(pdev, card); if (ret) goto err; -- GitLab From ceef9afb23e10dee8e55de1a37582074740b3980 Mon Sep 17 00:00:00 2001 From: Dieter Luecking Date: Fri, 28 Sep 2018 15:09:32 +0200 Subject: [PATCH 0568/1645] asoc: msm-compress: Add support for up to 32 channels Compressed streams now do support up to 32 channels. Use new ADSP API for 32 channels if ADSP supports this. If not fall back to 8 channel API. Change-Id: Ief6fe189a6a34f15cfb96bfb9cb7d97b03633b95 Signed-off-by: Dieter Luecking Signed-off-by: Mangesh Kunchamwar --- asoc/msm-compress-q6-v2.c | 59 ++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 6fb61da19536..268352bd416a 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include "msm-pcm-routing-v2.h" #include "msm-qti-pp-config.h" @@ -204,7 +205,7 @@ struct msm_compr_dec_params { struct msm_compr_ch_map { bool set_ch_map; - char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL]; + char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8]; }; static int msm_compr_send_dec_params(struct snd_compr_stream *cstream, @@ -1012,16 +1013,32 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, sample_word_size = 16; break; } - ret = q6asm_media_format_block_pcm_format_support_v4( - prtd->audio_client, - prtd->sample_rate, - prtd->num_channels, - bit_width, stream_id, - use_default_chmap, - chmap, - sample_word_size, - ASM_LITTLE_ENDIAN, - DEFAULT_QF); + + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= + ADSP_ASM_API_VERSION_V2) { + ret = q6asm_media_format_block_pcm_format_support_v5( + prtd->audio_client, + prtd->sample_rate, + prtd->num_channels, + bit_width, stream_id, + use_default_chmap, + chmap, + sample_word_size, + ASM_LITTLE_ENDIAN, + DEFAULT_QF); + } else { + ret = q6asm_media_format_block_pcm_format_support_v4( + prtd->audio_client, + prtd->sample_rate, + prtd->num_channels, + bit_width, stream_id, + use_default_chmap, + chmap, + sample_word_size, + ASM_LITTLE_ENDIAN, + DEFAULT_QF); + } if (ret < 0) pr_err("%s: CMD Format block failed\n", __func__); @@ -1336,7 +1353,16 @@ static int msm_compr_configure_dsp_for_playback } else { pr_debug("%s: stream_id %d bits_per_sample %d\n", __func__, ac->stream_id, bits_per_sample); - ret = q6asm_stream_open_write_v4(ac, + + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= + ADSP_ASM_API_VERSION_V2) + ret = q6asm_stream_open_write_v5(ac, + prtd->codec, bits_per_sample, + ac->stream_id, + prtd->gapless_state.use_dsp_gapless_mode); + else + ret = q6asm_stream_open_write_v4(ac, prtd->codec, bits_per_sample, ac->stream_id, prtd->gapless_state.use_dsp_gapless_mode); @@ -3640,7 +3666,7 @@ static int msm_compr_channel_map_put(struct snd_kcontrol *kcontrol, if (pdata->ch_map[fe_id]) { pdata->ch_map[fe_id]->set_ch_map = true; - for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) pdata->ch_map[fe_id]->channel_map[i] = (char)(ucontrol->value.integer.value[i]); } else { @@ -3669,7 +3695,7 @@ static int msm_compr_channel_map_get(struct snd_kcontrol *kcontrol, goto end; } if (pdata->ch_map[fe_id]) { - for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) ucontrol->value.integer.value[i] = pdata->ch_map[fe_id]->channel_map[i]; } @@ -3983,9 +4009,10 @@ static int msm_compr_channel_map_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 8; + uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8; uinfo->value.integer.min = 0; - uinfo->value.integer.max = 0xFFFFFFFF; + /* See PCM_CHANNEL_RSD=34 in apr_audio-v2.h */ + uinfo->value.integer.max = 34; return 0; } -- GitLab From 044e476310cf6074424506ff11f7fb255d2a96f9 Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Mon, 10 Sep 2018 11:04:16 +0200 Subject: [PATCH 0569/1645] dsp: Remove SPDIF format change detail info Remove the detailed format information from each format change event as sysfs interface is used now. Change-Id: I6abd221e87b18c1f0e84e62db8076b8198e8ad24 Signed-off-by: Ralf Herz Signed-off-by: Mangesh Kunchamwar --- dsp/q6afe.c | 143 ++++++++----------------------------------- dsp/q6core.c | 17 ----- include/dsp/q6core.h | 1 - 3 files changed, 26 insertions(+), 135 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 6697208e6616..50cd1040e45a 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -110,12 +110,9 @@ struct afe_ctl { uint32_t token, uint32_t *payload, void *priv); void *pri_spdif_tx_private_data; void *sec_spdif_tx_private_data; - struct afe_port_mod_evt_rsp_hdr pri_spdif_evt_pl; - struct afe_event_fmt_update pri_spdif_fmt_event; - struct afe_port_mod_evt_rsp_hdr sec_spdif_evt_pl; - struct afe_event_fmt_update sec_spdif_fmt_event; - struct work_struct afe_pri_spdif_work; - struct work_struct afe_sec_spdif_work; + int pri_spdif_config_change; + int sec_spdif_config_change; + struct work_struct afe_spdif_work; int topology[AFE_MAX_PORTS]; struct cal_type_data *cal_data[MAX_AFE_CAL_TYPES]; @@ -387,107 +384,26 @@ static int afe_aud_event_notify(struct notifier_block *self, return 0; } -static const char *const afe_event_port_text[] = { - "PORT=Primary", - "PORT=Secondary", -}; - -static const char * const afe_event_state_text[] = { - "STATE=Inactive", - "STATE=Active", - "STATE=EOS", -}; - -static const char *const afe_event_rate_text[] = { - "RATE=32000", - "RATE=44100", - "RATE=48000", - "RATE=88200", - "RATE=96000", - "RATE=176400", - "RATE=192000", -}; - -static const char *const afe_event_format_text[] = { - "FORMAT=LPCM", - "FORMAT=Compr", -}; - -static void afe_notify_spdif_fmt_update_common(void *payload) +static void afe_notify_spdif_fmt_update_work_fn(struct work_struct *work) { int ret = 0; - char *env[6]; - struct afe_port_mod_evt_rsp_hdr *evt_pl; - struct afe_event_fmt_update *fmt_event; - - evt_pl = (struct afe_port_mod_evt_rsp_hdr *)payload; - fmt_event = (struct afe_event_fmt_update *) - (payload + sizeof(struct afe_port_mod_evt_rsp_hdr)); + char event_pri[] = "PRI_SPDIF_TX=MEDIA_CONFIG_CHANGE"; + char event_sec[] = "SEC_SPDIF_TX=MEDIA_CONFIG_CHANGE"; - env[0] = "SPDIF_FMT_UPDATE=TRUE"; - if (evt_pl->port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) - env[1] = (char *)afe_event_port_text[0]; - else - env[1] = (char *)afe_event_port_text[1]; - - switch (fmt_event->status) { - case AFE_PORT_STATUS_AUDIO_ACTIVE: - env[2] = (char *)afe_event_state_text[1]; - break; - case AFE_PORT_STATUS_AUDIO_EOS: - env[2] = (char *)afe_event_state_text[2]; - break; - default: - env[2] = (char *)afe_event_state_text[0]; + if (this_afe.pri_spdif_config_change) { + this_afe.pri_spdif_config_change = 0; + ret = q6core_send_uevent(this_afe.uevent_data, event_pri); + if (ret) + pr_err("%s: Send UEvent %s failed :%d\n", + __func__, event_pri, ret); } - - switch (fmt_event->sample_rate) { - case 32000: - env[3] = (char *)afe_event_rate_text[0]; - break; - case 44100: - env[3] = (char *)afe_event_rate_text[1]; - break; - case 48000: - env[3] = (char *)afe_event_rate_text[2]; - break; - case 88200: - env[3] = (char *)afe_event_rate_text[3]; - break; - case 96000: - env[3] = (char *)afe_event_rate_text[4]; - break; - case 176400: - env[3] = (char *)afe_event_rate_text[5]; - break; - case 192000: - env[3] = (char *)afe_event_rate_text[6]; - break; - default: - env[3] = (char *)afe_event_rate_text[2]; + if (this_afe.sec_spdif_config_change) { + this_afe.sec_spdif_config_change = 0; + ret = q6core_send_uevent(this_afe.uevent_data, event_sec); + if (ret) + pr_err("%s: Send UEvent %s failed :%d\n", + __func__, event_sec, ret); } - - if (fmt_event->data_format == AFE_NON_LINEAR_DATA) - env[4] = (char *)afe_event_format_text[1]; - else - env[4] = (char *)afe_event_format_text[0]; - - env[5] = NULL; - - ret = q6core_send_uevent_env(this_afe.uevent_data, env); - if (ret) - pr_err("%s: Send UEvent %s failed: %d\n", __func__, - env[0], ret); -} - -static void afe_notify_pri_spdif_fmt_update_work_fn(struct work_struct *work) -{ - afe_notify_spdif_fmt_update_common(&this_afe.pri_spdif_evt_pl); -} - -static void afe_notify_sec_spdif_fmt_update_work_fn(struct work_struct *work) -{ - afe_notify_spdif_fmt_update_common(&this_afe.sec_spdif_evt_pl); } static void afe_notify_spdif_fmt_update(void *payload) @@ -495,17 +411,12 @@ static void afe_notify_spdif_fmt_update(void *payload) struct afe_port_mod_evt_rsp_hdr *evt_pl; evt_pl = (struct afe_port_mod_evt_rsp_hdr *)payload; - if (evt_pl->port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) { - memcpy(&this_afe.pri_spdif_evt_pl, payload, - sizeof(struct afe_port_mod_evt_rsp_hdr) + - sizeof(struct afe_event_fmt_update)); - schedule_work(&this_afe.afe_pri_spdif_work); - } else { - memcpy(&this_afe.sec_spdif_evt_pl, payload, - sizeof(struct afe_port_mod_evt_rsp_hdr) + - sizeof(struct afe_event_fmt_update)); - schedule_work(&this_afe.afe_sec_spdif_work); - } + if (evt_pl->port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) + this_afe.pri_spdif_config_change = 1; + else + this_afe.sec_spdif_config_change = 1; + + schedule_work(&this_afe.afe_spdif_work); } static int32_t afe_callback(struct apr_client_data *data, void *priv) @@ -8163,10 +8074,8 @@ int __init afe_init(void) q6core_init_uevent_data(this_afe.uevent_data, "q6afe_uevent"); INIT_WORK(&this_afe.afe_dc_work, afe_notify_dc_presence_work_fn); - INIT_WORK(&this_afe.afe_pri_spdif_work, - afe_notify_pri_spdif_fmt_update_work_fn); - INIT_WORK(&this_afe.afe_sec_spdif_work, - afe_notify_sec_spdif_fmt_update_work_fn); + INIT_WORK(&this_afe.afe_spdif_work, + afe_notify_spdif_fmt_update_work_fn); this_afe.event_notifier.notifier_call = afe_aud_event_notify; msm_aud_evt_blocking_register_client(&this_afe.event_notifier); diff --git a/dsp/q6core.c b/dsp/q6core.c index 5160c3dc9c1f..cf8419316b1a 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -193,23 +193,6 @@ int q6core_send_uevent(struct audio_uevent_data *uevent_data, char *event) } EXPORT_SYMBOL(q6core_send_uevent); -/** - * q6core_send_uevent_env - send uevent with list of keys to userspace. - * - * @uevent_data: uevent data. - * @event: array of event keys to send. - * - * Returns 0 on success or error otherwise. - */ -int q6core_send_uevent_env(struct audio_uevent_data *uevent_data, char *env[]) -{ - if (!env || !uevent_data) - return -EINVAL; - - return kobject_uevent_env(&uevent_data->kobj, KOBJ_CHANGE, env); -} -EXPORT_SYMBOL(q6core_send_uevent_env); - static int parse_fwk_version_info(uint32_t *payload) { size_t ver_size; diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index 4d5a973d2956..3690311d8c7f 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -35,7 +35,6 @@ struct audio_uevent_data { int q6core_init_uevent_data(struct audio_uevent_data *uevent_data, char *name); void q6core_destroy_uevent_data(struct audio_uevent_data *uevent_data); int q6core_send_uevent(struct audio_uevent_data *uevent_data, char *name); -int q6core_send_uevent_env(struct audio_uevent_data *uevent_data, char *env[]); int q6core_get_avcs_api_version_per_service(uint32_t service_id); #define ADSP_CMD_SET_DTS_EAGLE_DATA_ID 0x00012919 -- GitLab From 900bd738dd5b99bc9c04492792fc1de0d648372e Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Mon, 10 Sep 2018 11:09:02 +0200 Subject: [PATCH 0570/1645] asoc: Add sysfs attr for SPDIF interfaces The format change event signaling for SPDIF input interfaces is adapted to provide format information through sysfs nodes. Change-Id: Ifab1074a0e4b13e08813e27f8694023c2c47bfe1 Signed-off-by: Ralf Herz Signed-off-by: Mangesh Kunchamwar --- asoc/msm-dai-q6-v2.c | 182 +++++++++++++++++++++++++------------------ 1 file changed, 105 insertions(+), 77 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 0c9d0b013eb7..6242c58d3b38 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -40,6 +40,7 @@ #define CHANNEL_STATUS_MASK_INIT 0x0 #define CHANNEL_STATUS_MASK 0x4 #define AFE_API_VERSION_CLOCK_SET 1 +#define MSM_DAI_SYSFS_ENTRY_MAX_LEN 64 #define DAI_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ @@ -218,6 +219,7 @@ struct msm_dai_q6_spdif_dai_data { u16 port_id; struct afe_spdif_port_config spdif_port; struct afe_event_fmt_update fmt_event; + struct kobject *kobj; }; struct msm_dai_q6_spdif_event_msg { @@ -1459,39 +1461,6 @@ static int msm_dai_q6_spdif_source_get(struct snd_kcontrol *kcontrol, return 0; } -static int msm_dai_q6_spdif_ext_state_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; - - ucontrol->value.integer.value[0] = - dai_data->fmt_event.status & 0x3; - return 0; -} - -static int msm_dai_q6_spdif_ext_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; - - ucontrol->value.integer.value[0] = - dai_data->fmt_event.data_format & 0x1; - return 0; -} - -static int msm_dai_q6_spdif_ext_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; - - ucontrol->value.integer.value[0] = - dai_data->fmt_event.sample_rate; - return 0; -} - static const char * const spdif_format[] = { "LPCM", "Compr" @@ -1501,10 +1470,6 @@ static const char * const spdif_source[] = { "Optical", "EXT-ARC", "Coaxial", "VT-ARC" }; -static const char * const spdif_state[] = { - "Inactive", "Active", "EOS" -}; - static const struct soc_enum spdif_rx_config_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format), }; @@ -1514,11 +1479,6 @@ static const struct soc_enum spdif_tx_config_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format), }; -static const struct soc_enum spdif_tx_status_enum[] = { - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_state), spdif_state), - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format), - }; - static int msm_dai_q6_spdif_chstatus_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1609,21 +1569,6 @@ static const struct snd_kcontrol_new spdif_tx_config_controls[] = { msm_dai_q6_spdif_format_put) }; -static const struct snd_kcontrol_new spdif_tx_status_controls[] = { - SOC_ENUM_EXT("PRI SPDIF TX EXT State", spdif_tx_status_enum[0], - msm_dai_q6_spdif_ext_state_get, NULL), - SOC_ENUM_EXT("PRI SPDIF TX EXT Format", spdif_tx_status_enum[1], - msm_dai_q6_spdif_ext_format_get, NULL), - SOC_SINGLE_EXT("PRI SPDIF TX EXT Rate", 0, 0, 192000, 0, - msm_dai_q6_spdif_ext_rate_get, NULL), - SOC_ENUM_EXT("SEC SPDIF TX EXT State", spdif_tx_status_enum[0], - msm_dai_q6_spdif_ext_state_get, NULL), - SOC_ENUM_EXT("SEC SPDIF TX EXT Format", spdif_tx_status_enum[1], - msm_dai_q6_spdif_ext_format_get, NULL), - SOC_SINGLE_EXT("SEC SPDIF TX EXT Rate", 0, 0, 192000, 0, - msm_dai_q6_spdif_ext_rate_get, NULL) -}; - static void msm_dai_q6_spdif_process_event(uint32_t opcode, uint32_t token, uint32_t *payload, void *private_data) { @@ -1734,6 +1679,102 @@ static int msm_dai_q6_spdif_prepare(struct snd_pcm_substream *substream, return rc; } +static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_state(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dev); + + if (!dai_data) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + ret = snprintf(buf, MSM_DAI_SYSFS_ENTRY_MAX_LEN, "%d\n", + dai_data->fmt_event.status); + pr_debug("%s: '%d'\n", __func__, dai_data->fmt_event.status); + + return ret; +} + +static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_format(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dev); + + if (!dai_data) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + ret = snprintf(buf, MSM_DAI_SYSFS_ENTRY_MAX_LEN, "%d\n", + dai_data->fmt_event.data_format); + pr_debug("%s: '%d'\n", __func__, dai_data->fmt_event.data_format); + + return ret; +} + +static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_rate(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dev); + + if (!dai_data) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + ret = snprintf(buf, MSM_DAI_SYSFS_ENTRY_MAX_LEN, "%d\n", + dai_data->fmt_event.sample_rate); + pr_debug("%s: '%d'\n", __func__, dai_data->fmt_event.sample_rate); + + return ret; +} + +static DEVICE_ATTR(audio_state, 0444, msm_dai_q6_spdif_sysfs_rda_audio_state, + NULL); +static DEVICE_ATTR(audio_format, 0444, msm_dai_q6_spdif_sysfs_rda_audio_format, + NULL); +static DEVICE_ATTR(audio_rate, 0444, msm_dai_q6_spdif_sysfs_rda_audio_rate, + NULL); + +static struct attribute *msm_dai_q6_spdif_fs_attrs[] = { + &dev_attr_audio_state.attr, + &dev_attr_audio_format.attr, + &dev_attr_audio_rate.attr, + NULL, +}; +static struct attribute_group msm_dai_q6_spdif_fs_attrs_group = { + .attrs = msm_dai_q6_spdif_fs_attrs, +}; + +static int msm_dai_q6_spdif_sysfs_create(struct snd_soc_dai *dai, + struct msm_dai_q6_spdif_dai_data *dai_data) +{ + int rc; + + rc = sysfs_create_group(&dai->dev->kobj, + &msm_dai_q6_spdif_fs_attrs_group); + if (rc) { + pr_err("%s: failed, rc=%d\n", __func__, rc); + return rc; + } + dai_data->kobj = &dai->dev->kobj; + + return 0; +} + +static void msm_dai_q6_spdif_sysfs_remove(struct snd_soc_dai *dai, + struct msm_dai_q6_spdif_dai_data *dai_data) +{ + if (dai_data->kobj) + sysfs_remove_group(dai_data->kobj, + &msm_dai_q6_spdif_fs_attrs_group); + dai_data->kobj = NULL; +} + static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai) { struct msm_dai_q6_spdif_dai_data *dai_data; @@ -1773,40 +1814,24 @@ static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai) dai_data)); break; case AFE_PORT_ID_PRIMARY_SPDIF_TX: + rc = msm_dai_q6_spdif_sysfs_create(dai, dai_data); + rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_config_controls[0], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_config_controls[1], dai_data)); - - rc = snd_ctl_add(dai->component->card->snd_card, - snd_ctl_new1(&spdif_tx_status_controls[0], - dai_data)); - rc = snd_ctl_add(dai->component->card->snd_card, - snd_ctl_new1(&spdif_tx_status_controls[1], - dai_data)); - rc = snd_ctl_add(dai->component->card->snd_card, - snd_ctl_new1(&spdif_tx_status_controls[2], - dai_data)); break; case AFE_PORT_ID_SECONDARY_SPDIF_TX: + rc = msm_dai_q6_spdif_sysfs_create(dai, dai_data); + rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_config_controls[2], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_config_controls[3], dai_data)); - - rc = snd_ctl_add(dai->component->card->snd_card, - snd_ctl_new1(&spdif_tx_status_controls[3], - dai_data)); - rc = snd_ctl_add(dai->component->card->snd_card, - snd_ctl_new1(&spdif_tx_status_controls[4], - dai_data)); - rc = snd_ctl_add(dai->component->card->snd_card, - snd_ctl_new1(&spdif_tx_status_controls[5], - dai_data)); break; } if (rc < 0) @@ -1866,6 +1891,9 @@ static int msm_dai_q6_spdif_dai_remove(struct snd_soc_dai *dai) clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); } + + msm_dai_q6_spdif_sysfs_remove(dai, dai_data); + kfree(dai_data); return 0; -- GitLab From 3cd7e58eca1671b7144a5f70b546a1696cb60134 Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Mon, 10 Sep 2018 14:12:40 +0200 Subject: [PATCH 0571/1645] asoc: qcs405: Use changed clock for SPDIF interfaces ADSP only supports 163.84MHz for SPDIF input interface clock. Change-Id: Ib228dea0508a77d8194b348b50801624b678022f Signed-off-by: Ralf Herz Signed-off-by: Mangesh Kunchamwar --- asoc/qcs405.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index e7b9d7177e86..b5e6c0ee3edc 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -63,7 +63,7 @@ #define SAMPLING_RATE_352P8KHZ 352800 #define SAMPLING_RATE_384KHZ 384000 -#define SPDIF_TX_CORE_CLK_204_P8_MHZ 204800000 +#define SPDIF_TX_CORE_CLK_163_P84_MHZ 163840000 #define TLMM_EAST_SPARE 0x07BA0000 #define TLMM_SPDIF_HDMI_ARC_CTL 0x07BA2000 @@ -5599,11 +5599,11 @@ static int msm_spdif_set_clk(struct snd_pcm_substream *substream, bool enable) break; case AFE_PORT_ID_PRIMARY_SPDIF_TX: clk_cfg.clk_id = AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_INPUT_CORE; - clk_cfg.clk_freq_in_hz = SPDIF_TX_CORE_CLK_204_P8_MHZ; + clk_cfg.clk_freq_in_hz = SPDIF_TX_CORE_CLK_163_P84_MHZ; break; case AFE_PORT_ID_SECONDARY_SPDIF_TX: clk_cfg.clk_id = AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_INPUT_CORE; - clk_cfg.clk_freq_in_hz = SPDIF_TX_CORE_CLK_204_P8_MHZ; + clk_cfg.clk_freq_in_hz = SPDIF_TX_CORE_CLK_163_P84_MHZ; break; } -- GitLab From c49a9d541dcc55fc798841269449d7892471d776 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Thu, 4 Oct 2018 20:09:17 +0530 Subject: [PATCH 0572/1645] asoc: wcd937x: Reset mbhc detection type after ssr If headset is connected during SSR, after recovery mbhc driver expects a new detection event as the driver is reinitialized. Reset detection type to insertion to retrigger a hw interrupt for mbhc driver. Change-Id: I55705eb6b6a289deb5dc16a4b9ef6252082a3d9a Signed-off-by: Ramprasad Katkam --- asoc/codecs/wcd937x/wcd937x-mbhc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index c95de4bad700..ec38eba6def1 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -976,6 +976,8 @@ int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc, wcd937x_mbhc_hs_detect_exit(codec); wcd_mbhc_deinit(wcd_mbhc); + snd_soc_update_bits(codec, WCD937X_ANA_MBHC_MECH, + 0x20, 0x20); ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids, wcd_mbhc_registers, WCD937X_ZDET_SUPPORTED); if (ret) { -- GitLab From c9f455145261c3a84c06b04d9ddf44e8b465d669 Mon Sep 17 00:00:00 2001 From: Romed Schur Date: Mon, 24 Sep 2018 14:00:24 +0200 Subject: [PATCH 0573/1645] asoc: csra66x0: Fix interrupt in multichannel case If interrupt indicates a fault in multichannel case, reset all cluster devices in a specific order. Change-Id: I077ff65c5f2b5e656fcdf6533fde04eba426e322 Signed-off-by: Romed Schur --- asoc/codecs/csra66x0/csra66x0.c | 228 +++++++++++++++++++++----------- 1 file changed, 154 insertions(+), 74 deletions(-) diff --git a/asoc/codecs/csra66x0/csra66x0.c b/asoc/codecs/csra66x0/csra66x0.c index a6460a9237fc..2189f9bfd873 100644 --- a/asoc/codecs/csra66x0/csra66x0.c +++ b/asoc/codecs/csra66x0/csra66x0.c @@ -214,6 +214,9 @@ static bool csra66x0_volatile_register(struct device *dev, unsigned int reg) { switch (reg) { case CSRA66X0_CHIP_ID_FA: + case CSRA66X0_ROM_VER_FA: + case CSRA66X0_CHIP_REV_0_FA: + case CSRA66X0_CHIP_REV_1_FA: case CSRA66X0_TEMP_READ0_FA: case CSRA66X0_TEMP_READ1_FA: case CSRA66X0_MISC_CONTROL_STATUS_1_FA: @@ -267,6 +270,20 @@ struct csra66x0_priv { #endif /* CONFIG_DEBUG_FS */ }; +struct csra66x0_cluster_device { + struct csra66x0_priv *csra66x0_ptr; + const char *csra66x0_prefix; +}; + +struct csra66x0_cluster_device csra_clust_dev_tbl[] = { + {NULL, "CSRA_12"}, + {NULL, "CSRA_34"}, + {NULL, "CSRA_56"}, + {NULL, "CSRA_78"}, + {NULL, "CSRA_9A"}, + {NULL, "CSRA_BC"} +}; + #if IS_ENABLED(CONFIG_DEBUG_FS) static int debugfs_codec_open_op(struct inode *inode, struct file *file) { @@ -515,9 +532,12 @@ static const struct snd_soc_dapm_route csra66x0_dapm_routes[] = { {"SPKR", NULL, "POWER"}, }; -static int csra66x0_init(struct snd_soc_codec *codec, - struct csra66x0_priv *csra66x0) +static int csra66x0_init(struct csra66x0_priv *csra66x0) { + struct snd_soc_codec *codec = csra66x0->codec; + + dev_dbg(codec->dev, "%s: initialize %s\n", + __func__, codec->component.name); /* config */ snd_soc_write(codec, CSRA66X0_CHIP_STATE_CTRL_FA, CONFIG_STATE); /* settle time in HW is min. 500ms before proceeding */ @@ -565,35 +585,106 @@ static int csra66x0_init(struct snd_soc_codec *codec, return 0; } +static int csra66x0_reset(struct csra66x0_priv *csra66x0) +{ + struct snd_soc_codec *codec = csra66x0->codec; + u16 val; + + val = snd_soc_read(codec, CSRA66X0_FAULT_STATUS_FA); + if (val & FAULT_STATUS_INTERNAL) + dev_dbg(codec->dev, "%s: FAULT_STATUS_INTERNAL 0x%X\n", + __func__, val); + if (val & FAULT_STATUS_OTP_INTEGRITY) + dev_dbg(codec->dev, "%s: FAULT_STATUS_OTP_INTEGRITY 0x%X\n", + __func__, val); + if (val & FAULT_STATUS_PADS2) + dev_dbg(codec->dev, "%s: FAULT_STATUS_PADS2 0x%X\n", + __func__, val); + if (val & FAULT_STATUS_SMPS) + dev_dbg(codec->dev, "%s: FAULT_STATUS_SMPS 0x%X\n", + __func__, val); + if (val & FAULT_STATUS_TEMP) + dev_dbg(codec->dev, "%s: FAULT_STATUS_TEMP 0x%X\n", + __func__, val); + if (val & FAULT_STATUS_PROTECT) + dev_dbg(codec->dev, "%s: FAULT_STATUS_PROTECT 0x%X\n", + __func__, val); + + dev_dbg(codec->dev, "%s: reset %s\n", + __func__, codec->component.name); + /* clear fault state and re-init */ + snd_soc_write(codec, CSRA66X0_FAULT_STATUS_FA, 0x00); + snd_soc_write(codec, CSRA66X0_IRQ_OUTPUT_STATUS_FA, 0x00); + /* apply reset to CSRA66X0 */ + val = snd_soc_read(codec, CSRA66X0_MISC_CONTROL_STATUS_1_FA); + snd_soc_write(codec, CSRA66X0_MISC_CONTROL_STATUS_1_FA, val | 0x08); + /* wait 500ms after reset to recover CSRA66X0 */ + msleep(500); + return 0; +} + +static int csra66x0_msconfig(struct csra66x0_priv *csra66x0) +{ + struct snd_soc_codec *codec = csra66x0->codec; + + dev_dbg(codec->dev, "%s: configure %s\n", + __func__, codec->component.name); + /* config */ + snd_soc_write(codec, CSRA66X0_CHIP_STATE_CTRL_FA, + CONFIG_STATE); + /* settle time in HW is min. 500ms before proceeding */ + msleep(500); + snd_soc_write(codec, CSRA66X0_PIO7_SELECT, 0x04); + snd_soc_write(codec, CSRA66X0_PIO8_SELECT, 0x04); + if (csra66x0->is_master) { + /* Master specific config */ + snd_soc_write(codec, CSRA66X0_PIO_PULL_EN0, 0xFF); + snd_soc_write(codec, CSRA66X0_PIO_PULL_DIR0, 0x80); + snd_soc_write(codec, CSRA66X0_PIO_PULL_EN1, 0x01); + snd_soc_write(codec, CSRA66X0_PIO_PULL_DIR1, 0x01); + } else { + /* Slave specific config */ + snd_soc_write(codec, CSRA66X0_PIO_PULL_EN0, 0x7F); + snd_soc_write(codec, CSRA66X0_PIO_PULL_EN1, 0x00); + } + snd_soc_write(codec, CSRA66X0_DCA_CTRL, 0x05); + return 0; +} + static int csra66x0_soc_probe(struct snd_soc_codec *codec) { struct csra66x0_priv *csra66x0 = snd_soc_codec_get_drvdata(codec); struct snd_soc_dapm_context *dapm; char name[50]; + unsigned int i, max_num_cluster_devices; + csra66x0->codec = codec; if (csra66x0->in_cluster) { dapm = snd_soc_codec_get_dapm(codec); dev_dbg(codec->dev, "%s: assign prefix %s to codec device %s\n", __func__, codec->component.name_prefix, codec->component.name); - snd_soc_write(codec, CSRA66X0_CHIP_STATE_CTRL_FA, - CONFIG_STATE); - /* settle time in HW is min. 500ms before proceeding */ - msleep(500); - snd_soc_write(codec, CSRA66X0_PIO7_SELECT, 0x04); - snd_soc_write(codec, CSRA66X0_PIO8_SELECT, 0x04); - if (csra66x0->is_master) { - /* Master specific config */ - snd_soc_write(codec, CSRA66X0_PIO_PULL_EN0, 0xFF); - snd_soc_write(codec, CSRA66X0_PIO_PULL_DIR0, 0x80); - snd_soc_write(codec, CSRA66X0_PIO_PULL_EN1, 0x01); - snd_soc_write(codec, CSRA66X0_PIO_PULL_DIR1, 0x01); - } else { - /* Slave specific config */ - snd_soc_write(codec, CSRA66X0_PIO_PULL_EN0, 0x7F); - snd_soc_write(codec, CSRA66X0_PIO_PULL_EN1, 0x00); + + /* add device to cluster table */ + max_num_cluster_devices = sizeof(csra_clust_dev_tbl)/ + sizeof(csra_clust_dev_tbl[0]); + for (i = 0; i < max_num_cluster_devices; i++) { + if (!strncmp(codec->component.name_prefix, + csra_clust_dev_tbl[i].csra66x0_prefix, + strlen( + csra_clust_dev_tbl[i].csra66x0_prefix))) { + csra_clust_dev_tbl[i].csra66x0_ptr = csra66x0; + break; + } + if (i == max_num_cluster_devices-1) + dev_warn(codec->dev, + "%s: Unknown prefix %s of cluster device %s\n", + __func__, codec->component.name_prefix, + codec->component.name); } - snd_soc_write(codec, CSRA66X0_DCA_CTRL, 0x05); + + /* master slave config */ + csra66x0_msconfig(csra66x0); if (dapm->component) { strlcpy(name, dapm->component->name_prefix, sizeof(name)); @@ -606,10 +697,8 @@ static int csra66x0_soc_probe(struct snd_soc_codec *codec) } } - csra66x0->codec = codec; - - /* common configuration */ - csra66x0_init(codec, csra66x0); + /* common initialization */ + csra66x0_init(csra66x0); return 0; } @@ -679,66 +768,56 @@ static irqreturn_t csra66x0_irq(int irq, void *data) struct csra66x0_priv *csra66x0 = (struct csra66x0_priv *) data; struct snd_soc_codec *codec = csra66x0->codec; u16 val; + unsigned int i, max_num_cluster_devices; /* Treat interrupt before codec is initialized as spurious */ if (codec == NULL) return IRQ_NONE; - dev_dbg(codec->dev, "%s: csra66x0_interrupt\n", __func__); + dev_dbg(codec->dev, "%s: csra66x0_interrupt triggered by %s\n", + __func__, codec->component.name); /* fault indication */ val = snd_soc_read(codec, CSRA66X0_IRQ_OUTPUT_STATUS_FA) & 0x1; - if (val) { - val = snd_soc_read(codec, CSRA66X0_FAULT_STATUS_FA); - if (val & FAULT_STATUS_INTERNAL) - dev_dbg(codec->dev, "%s: FAULT_STATUS_INTERNAL 0x%X\n", - __func__, val); - if (val & FAULT_STATUS_OTP_INTEGRITY) - dev_dbg(codec->dev, "%s: FAULT_STATUS_OTP_INTEGRITY 0x%X\n", - __func__, val); - if (val & FAULT_STATUS_PADS2) - dev_dbg(codec->dev, "%s: FAULT_STATUS_PADS2 0x%X\n", - __func__, val); - if (val & FAULT_STATUS_SMPS) - dev_dbg(codec->dev, "%s: FAULT_STATUS_SMPS 0x%X\n", - __func__, val); - if (val & FAULT_STATUS_TEMP) - dev_dbg(codec->dev, "%s: FAULT_STATUS_TEMP 0x%X\n", - __func__, val); - if (val & FAULT_STATUS_PROTECT) - dev_dbg(codec->dev, "%s: FAULT_STATUS_PROTECT 0x%X\n", - __func__, val); - - /* clear fault state and re-init */ - snd_soc_write(codec, CSRA66X0_FAULT_STATUS_FA, 0x00); - snd_soc_write(codec, CSRA66X0_IRQ_OUTPUT_STATUS_FA, 0x00); - /* apply reset to CSRA66X0 */ - val = snd_soc_read(codec, CSRA66X0_MISC_CONTROL_STATUS_1_FA); - snd_soc_write(codec, CSRA66X0_MISC_CONTROL_STATUS_1_FA, val | 0x08); - /* wait 2s after reset to recover CSRA66X0 */ - msleep(2000); - /* re-init */ - snd_soc_write(codec, CSRA66X0_CHIP_STATE_CTRL_FA, - CONFIG_STATE); - /* settle time in HW is min. 500ms before proceeding */ - msleep(500); - snd_soc_write(codec, CSRA66X0_PIO7_SELECT, 0x04); - snd_soc_write(codec, CSRA66X0_PIO8_SELECT, 0x04); - if (csra66x0->is_master) { - /* Master specific config */ - snd_soc_write(codec, CSRA66X0_PIO_PULL_EN0, 0xFF); - snd_soc_write(codec, CSRA66X0_PIO_PULL_DIR0, 0x80); - snd_soc_write(codec, CSRA66X0_PIO_PULL_EN1, 0x01); - snd_soc_write(codec, CSRA66X0_PIO_PULL_DIR1, 0x01); - } else { - /* Slave specific config */ - snd_soc_write(codec, CSRA66X0_PIO_PULL_EN0, 0x7F); - snd_soc_write(codec, CSRA66X0_PIO_PULL_EN1, 0x00); + if (!val) + return IRQ_HANDLED; + + if (csra66x0->in_cluster) { + /* reset all slave codecs */ + max_num_cluster_devices = + sizeof(csra_clust_dev_tbl) / + sizeof(csra_clust_dev_tbl[0]); + for (i = 0; i < max_num_cluster_devices; i++) { + if (i >= codec->component.card->num_aux_devs) + break; + if (csra_clust_dev_tbl[i].csra66x0_ptr == NULL) + continue; + if (csra_clust_dev_tbl[i].csra66x0_ptr->is_master) + continue; + csra66x0_reset(csra_clust_dev_tbl[i].csra66x0_ptr); + } + /* reset all master codecs */ + for (i = 0; i < max_num_cluster_devices; i++) { + if (i >= codec->component.card->num_aux_devs) + break; + if (csra_clust_dev_tbl[i].csra66x0_ptr == NULL) + continue; + if (csra_clust_dev_tbl[i].csra66x0_ptr->is_master) + csra66x0_reset( + csra_clust_dev_tbl[i].csra66x0_ptr); + } + /* recover all codecs */ + for (i = 0; i < max_num_cluster_devices; i++) { + if (i >= codec->component.card->num_aux_devs) + break; + if (csra_clust_dev_tbl[i].csra66x0_ptr == NULL) + continue; + csra66x0_msconfig(csra_clust_dev_tbl[i].csra66x0_ptr); + csra66x0_init(csra_clust_dev_tbl[i].csra66x0_ptr); } - snd_soc_write(codec, CSRA66X0_DCA_CTRL, 0x05); - csra66x0_init(codec, csra66x0); } else { - return IRQ_NONE; + csra66x0_reset(csra66x0); + csra66x0_init(csra66x0); } return IRQ_HANDLED; }; @@ -791,7 +870,8 @@ static int csra66x0_i2c_probe(struct i2c_client *client_i2c, &csra66x0->is_master); if (ret) { dev_info(&client_i2c->dev, - "%s: qcom,csra-cluster-master property not defined in DT\n", __func__); + "%s: qcom,csra-cluster-master property not defined in DT, slave assumed\n", + __func__); csra66x0->is_master = 0; } -- GitLab From b7eba8f84a2369d26b951c46bab3d56d4ad82859 Mon Sep 17 00:00:00 2001 From: Sharad Sangle Date: Mon, 3 Sep 2018 19:39:25 +0530 Subject: [PATCH 0574/1645] dsp: afe: Add support for sending aptx adaptive encoder mode Add support for sending APTx Adaptive encoder mode, High Quality or Low latency to LPASS. CRs-Fixed: 2272343 Change-Id: Ibbe809d5ca4481d3e98931e40213dd16110f6a57 Signed-off-by: Sharad Sangle --- include/dsp/apr_audio-v2.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 4ce997384d31..c88920f3aabd 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -3547,6 +3547,7 @@ struct afe_id_aptx_adaptive_enc_init uint32_t max_sink_modeB; uint32_t min_sink_modeC; uint32_t max_sink_modeC; + uint32_t mode; } __attribute__ ((packed)); /* -- GitLab From 48b49b2117d4b3e61ef9990c72342518916a198c Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Mon, 1 Oct 2018 20:12:46 +0530 Subject: [PATCH 0575/1645] soc: swr-mstr: Avoid master reinit during clock stop-resume Avoid reinitializing master when resuming from clock stop to avoid possible slave sync lost. Change-Id: I8b2403bf10c0ec2ab7b294d64441b4d9a8afcaa0 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 7232fe83caa8..a4f99d41412a 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1235,7 +1235,7 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) if (ret) { dev_err(swrm->dev, "no slave alert found.\ spurious interrupt\n"); - return ret; + break; } list_for_each_entry(swr_dev, &mstr->devices, dev_list) { if (swr_dev->dev_num != devnum) @@ -1348,10 +1348,6 @@ static void swrm_wakeup_work(struct work_struct *work) return; } pm_runtime_get_sync(swrm->dev); - - swrm_cmd_fifo_wr_cmd(swrm, 0x4, 0xF, 0xF, - SWRS_SCP_INT_STATUS_MASK_1); - pm_runtime_mark_last_busy(swrm->dev); pm_runtime_put_autosuspend(swrm->dev); } @@ -1871,14 +1867,14 @@ static int swrm_runtime_resume(struct device *dev) goto exit; } } + swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01); + swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01); + swrm_master_init(swrm); } else { /*wake up from clock stop*/ swr_master_write(swrm, SWRM_MCP_BUS_CTRL_ADDR, 0x2); usleep_range(100, 105); } - swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01); - swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01); - swrm_master_init(swrm); } exit: pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer); -- GitLab From 6c13f05fb4f10ea95949c7837d49a9e4db2d4779 Mon Sep 17 00:00:00 2001 From: Tanya Dixit Date: Thu, 20 Sep 2018 16:16:06 +0530 Subject: [PATCH 0576/1645] asoc: wcd937x: Make vdd-buck as on-demand supply Add widget and routing support for vdd-buck supply as dynamic for all rx usecases. Change-Id: I1e67e7e950e33a0d98900ee0b20e0dc818a7936d Signed-off-by: Tanya Dixit --- asoc/codecs/wcd937x/wcd937x.c | 62 +++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index bbe9d8f87f18..c0397d54b008 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1374,6 +1374,60 @@ static int wcd937x_set_compander(struct snd_kcontrol *kcontrol, return 0; } +static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct wcd937x_pdata *pdata = NULL; + int ret = 0; + + pdata = dev_get_platdata(wcd937x->dev); + + if (!pdata) { + dev_err(codec->dev, "%s: pdata is NULL\n", __func__); + return -EINVAL; + } + + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = msm_cdc_enable_ondemand_supply(wcd937x->dev, + wcd937x->supplies, + pdata->regulator, + pdata->num_supplies, + "cdc-vdd-buck"); + if (ret == -EINVAL) { + dev_err(codec->dev, "%s: vdd buck is not enabled\n", + __func__); + return ret; + } + /* + * 200us sleep is required after LDO15 is enabled as per + * HW requirement + */ + usleep_range(200, 250); + break; + case SND_SOC_DAPM_POST_PMD: + ret = msm_cdc_disable_ondemand_supply(wcd937x->dev, + wcd937x->supplies, + pdata->regulator, + pdata->num_supplies, + "cdc-vdd-buck"); + if (ret == -EINVAL) { + dev_err(codec->dev, "%s: vdd buck is not enabled\n", + __func__); + return ret; + } + + break; + } + return 0; +} + static const char * const rx_hph_mode_mux_text[] = { "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI", "CLS_H_ULP", "CLS_AB_HIFI", @@ -1526,6 +1580,10 @@ static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("VDD_BUCK", SND_SOC_NOPM, 0, 0, + wcd937x_codec_enable_vdd_buck, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + /*rx widgets*/ SND_SOC_DAPM_PGA_E("EAR PGA", WCD937X_ANA_EAR, 7, 0, NULL, 0, wcd937x_codec_enable_ear_pa, @@ -1709,6 +1767,10 @@ static const struct snd_soc_dapm_route wcd937x_audio_map[] = { {"EAR PGA", NULL, "EAR_RDAC"}, {"EAR", NULL, "EAR PGA"}, + {"EAR", NULL, "VDD_BUCK"}, + {"HPHR", NULL, "VDD_BUCK"}, + {"HPHL", NULL, "VDD_BUCK"}, + {"AUX", NULL, "VDD_BUCK"}, }; static const struct snd_soc_dapm_route wcd9375_audio_map[] = { -- GitLab From cab8d72ab0423c1c48058f7536344c23a85f5375 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Fri, 28 Sep 2018 15:54:06 +0530 Subject: [PATCH 0577/1645] soc: swr-mstr: Ignore redundant slave path control command Slave could trigger multiple path control api multiple times after connect/disconnect port. Avoid handling the api without new connect/disconnect requests to reduce latency. Change-Id: I4db52fdebfd6b7c0fe3f388f25dfaa4981d5f61c Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 23 +++++++++++++++++++++-- soc/swr-mstr-ctrl.h | 1 + 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 7232fe83caa8..ff062b6adb55 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,11 @@ enum { MASTER_ID_RX, MASTER_ID_TX }; + +enum { + ENABLE_PENDING, + DISABLE_PENDING +}; #define TRUE 1 #define FALSE 0 @@ -955,18 +961,28 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) bank = get_inactive_bank_num(swrm); if (enable) { + if (!test_bit(ENABLE_PENDING, &swrm->port_req_pending)) { + dev_dbg(swrm->dev, "%s:No pending connect port req\n", + __func__); + goto exit; + } + clear_bit(ENABLE_PENDING, &swrm->port_req_pending); ret = swrm_get_port_config(swrm); if (ret) { /* cannot accommodate ports */ swrm_cleanup_disabled_port_reqs(master); - pm_runtime_mark_last_busy(swrm->dev); - pm_runtime_put_autosuspend(swrm->dev); mutex_unlock(&swrm->mlock); return -EINVAL; } /* apply the new port config*/ swrm_apply_port_config(master); } else { + if (!test_bit(DISABLE_PENDING, &swrm->port_req_pending)) { + dev_dbg(swrm->dev, "%s:No pending disconn port req\n", + __func__); + goto exit; + } + clear_bit(DISABLE_PENDING, &swrm->port_req_pending); swrm_disable_ports(master, bank); } dev_dbg(swrm->dev, "%s: enable: %d, cfg_devs: %d\n", @@ -1019,6 +1035,7 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) pm_runtime_mark_last_busy(swrm->dev); pm_runtime_put_autosuspend(swrm->dev); } +exit: mutex_unlock(&swrm->mlock); return 0; } @@ -1095,6 +1112,7 @@ static int swrm_connect_port(struct swr_master *master, master->port_en_mask |= (1 << mstr_port_id); } master->num_port += portinfo->num_port; + set_bit(ENABLE_PENDING, &swrm->port_req_pending); swr_port_response(master, portinfo->tid); mutex_unlock(&swrm->mlock); @@ -1155,6 +1173,7 @@ static int swrm_disconnect_port(struct swr_master *master, mport->req_ch &= ~mstr_ch_mask; } master->num_port -= portinfo->num_port; + set_bit(DISABLE_PENDING, &swrm->port_req_pending); swr_port_response(master, portinfo->tid); mutex_unlock(&swrm->mlock); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 862596651df4..b55beba993ff 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -135,6 +135,7 @@ struct swr_mstr_ctrl { int slave_status; struct swrm_mports mport_cfg[SWR_MAX_MSTR_PORT_NUM]; struct list_head port_req_list; + unsigned long port_req_pending; int state; struct platform_device *pdev; int num_rx_chs; -- GitLab From 248273c9490f3ffc1352cb324d4265e111194d86 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 3 Oct 2018 20:35:01 +0530 Subject: [PATCH 0578/1645] asoc: wcd937x: Fix pop on headphone playback start Pop is observed on HPH playback start. Enable SWR port config setup before HPH PA enable. Change-Id: I2253be1c7e4d8df2bffd7bd0396ceb72a5018637 Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd937x/wcd937x.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 0bdfda1a52f6..c6ea2efd2015 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -560,6 +560,9 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMU: snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x10, 0x10); usleep_range(100, 110); + ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, + wcd937x->rx_swr_dev->dev_num, + true); break; case SND_SOC_DAPM_POST_PMU: usleep_range(7000, 7010); @@ -567,9 +570,6 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, 0x02, 0x02); snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x02, 0x02); - ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, - wcd937x->rx_swr_dev->dev_num, - true); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -607,6 +607,9 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMU: snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x20, 0x20); usleep_range(100, 110); + ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, + wcd937x->rx_swr_dev->dev_num, + true); break; case SND_SOC_DAPM_POST_PMU: usleep_range(7000, 7010); @@ -614,9 +617,6 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, 0x02, 0x02); snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x02, 0x02); - ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, - wcd937x->rx_swr_dev->dev_num, - true); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -660,14 +660,14 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, usleep_range(500, 510); snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, 0xFF, 0x3A); usleep_range(500, 510); + ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, + wcd937x->rx_swr_dev->dev_num, + true); break; case SND_SOC_DAPM_POST_PMU: usleep_range(1000, 1010); snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x20, 0x20); - ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, - wcd937x->rx_swr_dev->dev_num, - true); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -705,14 +705,14 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, usleep_range(500, 510); snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, 0xFF, 0x3A); usleep_range(500, 510); + ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, + wcd937x->rx_swr_dev->dev_num, + true); break; case SND_SOC_DAPM_POST_PMU: usleep_range(6000, 6010); snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x02, 0x02); - ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, - wcd937x->rx_swr_dev->dev_num, - true); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, -- GitLab From cd61c6ef145cb16d5b11faacf72f42c9abce4acb Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Tue, 18 Sep 2018 13:22:58 +0530 Subject: [PATCH 0579/1645] soc: swr-mstr: Avoid handling redundant swr wakeup events It is sometimes observed that afe could send multiple wakeup events at a time. Avoid this by handling wakeup event only once per swr suspend. Change-Id: Ieb9ed1b18c8c93cb7db4b75e3411cc25838be492 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 8 ++++++-- soc/swr-mstr-ctrl.h | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 7232fe83caa8..69f9fb153ef6 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1499,8 +1499,10 @@ static int swrm_event_notify(struct notifier_block *self, schedule_work(&(swrm->dc_presence_work)); break; case SWR_WAKE_IRQ_EVENT: - if (swrm->wakeup_req) + if (swrm->wakeup_req && !swrm->wakeup_triggered) { + swrm->wakeup_triggered = true; schedule_work(&swrm->wakeup_work); + } break; default: dev_err(swrm->dev, "%s: invalid event type: %lu\n", @@ -1928,9 +1930,11 @@ static int swrm_runtime_suspend(struct device *dev) swrm_cmd_fifo_wr_cmd(swrm, 0x2, 0xF, 0xF, SWRS_SCP_CONTROL); usleep_range(100, 105); - if (swrm->wakeup_req) + if (swrm->wakeup_req) { msm_aud_evt_blocking_notifier_call_chain( SWR_WAKE_IRQ_REGISTER, (void *)swrm); + swrm->wakeup_triggered = false; + } } swrm_clk_request(swrm, false); } diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 862596651df4..1c41ffcf6629 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -150,8 +150,8 @@ struct swr_mstr_ctrl { u32 clk_stop_mode0_supp; struct work_struct wakeup_work; u32 wakeup_req; - bool dev_up; + bool wakeup_triggered; }; #endif /* _SWR_WCD_CTRL_H */ -- GitLab From 2a799b4065f0b7ef6c7b2e48814d0bf65ccfc586 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Thu, 4 Oct 2018 20:23:28 +0530 Subject: [PATCH 0580/1645] soc: swr-mstr: Add proper handling of SSR and clock stop When SSR occurs master needs to restart even though clock stop mode is supported. Add proper handling of master during SSR and suspend. Change-Id: I21c0ffd4fb741788dd12671fe4bd04cca9d7ff59 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 61 ++++++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index a4f99d41412a..47a5ecd89edc 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -232,11 +232,9 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) swrm->clk_ref_count++; if (swrm->clk_ref_count == 1) { swrm->clk(swrm->handle, true); - swrm->state = SWR_MSTR_UP; } } else if (--swrm->clk_ref_count == 0) { swrm->clk(swrm->handle, false); - swrm->state = SWR_MSTR_DOWN; } else if (swrm->clk_ref_count < 0) { pr_err("%s: swrm clk count mismatch\n", __func__); swrm->clk_ref_count = 0; @@ -1045,6 +1043,13 @@ static int swrm_connect_port(struct swr_master *master, } mutex_lock(&swrm->mlock); + mutex_lock(&swrm->devlock); + if (!swrm->dev_up) { + mutex_unlock(&swrm->devlock); + mutex_unlock(&swrm->mlock); + return -EINVAL; + } + mutex_unlock(&swrm->devlock); if (!swrm_is_port_en(master)) pm_runtime_get_sync(swrm->dev); @@ -1347,6 +1352,13 @@ static void swrm_wakeup_work(struct work_struct *work) pr_err("%s: swrm or dev is null\n", __func__); return; } + + mutex_lock(&swrm->devlock); + if (!swrm->dev_up) { + mutex_unlock(&swrm->devlock); + return; + } + mutex_unlock(&swrm->devlock); pm_runtime_get_sync(swrm->dev); pm_runtime_mark_last_busy(swrm->dev); pm_runtime_put_autosuspend(swrm->dev); @@ -1381,6 +1393,14 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, num_dev = swrm->num_dev; else num_dev = mstr->num_dev; + + mutex_lock(&swrm->devlock); + if (!swrm->dev_up) { + mutex_unlock(&swrm->devlock); + return ret; + } + mutex_unlock(&swrm->devlock); + pm_runtime_get_sync(swrm->dev); for (i = 1; i < (num_dev + 1); i++) { id = ((u64)(swr_master_read(swrm, @@ -1669,7 +1689,7 @@ static int swrm_probe(struct platform_device *pdev) swrm->clk_ref_count = 0; swrm->mclk_freq = MCLK_FREQ; swrm->dev_up = true; - swrm->state = SWR_MSTR_RESUME; + swrm->state = SWR_MSTR_UP; init_completion(&swrm->reset); init_completion(&swrm->broadcast); mutex_init(&swrm->mlock); @@ -1828,7 +1848,6 @@ static int swrm_clk_pause(struct swr_mstr_ctrl *swrm) val = swr_master_read(swrm, SWRM_MCP_CFG_ADDR); val |= SWRM_MCP_CFG_BUS_CLK_PAUSE_BMSK; swr_master_write(swrm, SWRM_MCP_CFG_ADDR, val); - swrm->state = SWR_MSTR_PAUSE; return 0; } @@ -1845,18 +1864,17 @@ static int swrm_runtime_resume(struct device *dev) dev_dbg(dev, "%s: pm_runtime: resume, state:%d\n", __func__, swrm->state); mutex_lock(&swrm->reslock); - if ((swrm->state == SWR_MSTR_PAUSE) || - (swrm->state == SWR_MSTR_DOWN)) { + + if ((swrm->state == SWR_MSTR_DOWN) || + (swrm->state == SWR_MSTR_SSR && swrm->dev_up)) { if (swrm->clk_stop_mode0_supp && swrm->wakeup_req) { msm_aud_evt_blocking_notifier_call_chain( SWR_WAKE_IRQ_DEREGISTER, (void *)swrm); } - if (swrm->state == SWR_MSTR_DOWN) { - if (swrm_clk_request(swrm, true)) - goto exit; - } - if (!swrm->clk_stop_mode0_supp) { + if (swrm_clk_request(swrm, true)) + goto exit; + if (!swrm->clk_stop_mode0_supp || swrm->state == SWR_MSTR_SSR) { list_for_each_entry(swr_dev, &mstr->devices, dev_list) { ret = swr_device_up(swr_dev); if (ret) { @@ -1870,11 +1888,15 @@ static int swrm_runtime_resume(struct device *dev) swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01); swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01); swrm_master_init(swrm); + swrm_cmd_fifo_wr_cmd(swrm, 0x4, 0xF, 0x0, + SWRS_SCP_INT_STATUS_MASK_1); + } else { /*wake up from clock stop*/ swr_master_write(swrm, SWRM_MCP_BUS_CTRL_ADDR, 0x2); usleep_range(100, 105); } + swrm->state = SWR_MSTR_UP; } exit: pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer); @@ -1897,8 +1919,7 @@ static int swrm_runtime_suspend(struct device *dev) mutex_lock(&swrm->force_down_lock); current_state = swrm->state; mutex_unlock(&swrm->force_down_lock); - if ((current_state == SWR_MSTR_RESUME) || - (current_state == SWR_MSTR_UP) || + if ((current_state == SWR_MSTR_UP) || (current_state == SWR_MSTR_SSR)) { if ((current_state != SWR_MSTR_SSR) && @@ -1907,7 +1928,7 @@ static int swrm_runtime_suspend(struct device *dev) ret = -EBUSY; goto exit; } - if (!swrm->clk_stop_mode0_supp) { + if (!swrm->clk_stop_mode0_supp || swrm->state == SWR_MSTR_SSR) { swrm_clk_pause(swrm); swr_master_write(swrm, SWRM_COMP_CFG_ADDR, 0x00); list_for_each_entry(swr_dev, &mstr->devices, dev_list) { @@ -1930,6 +1951,9 @@ static int swrm_runtime_suspend(struct device *dev) } swrm_clk_request(swrm, false); } + /* Retain SSR state until resume */ + if (current_state != SWR_MSTR_SSR) + swrm->state = SWR_MSTR_DOWN; exit: mutex_unlock(&swrm->reslock); return ret; @@ -1999,6 +2023,9 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) mutex_lock(&swrm->devlock); swrm->dev_up = false; mutex_unlock(&swrm->devlock); + mutex_lock(&swrm->reslock); + swrm->state = SWR_MSTR_SSR; + mutex_unlock(&swrm->reslock); break; case SWR_DEVICE_SSR_UP: mutex_lock(&swrm->devlock); @@ -2008,8 +2035,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) case SWR_DEVICE_DOWN: dev_dbg(swrm->dev, "%s: swr master down called\n", __func__); mutex_lock(&swrm->mlock); - if ((swrm->state == SWR_MSTR_PAUSE) || - (swrm->state == SWR_MSTR_DOWN)) + if (swrm->state == SWR_MSTR_DOWN) dev_dbg(swrm->dev, "%s:SWR master is already Down:%d\n", __func__, swrm->state); else @@ -2020,8 +2046,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) dev_dbg(swrm->dev, "%s: swr master up called\n", __func__); mutex_lock(&swrm->mlock); mutex_lock(&swrm->reslock); - if ((swrm->state == SWR_MSTR_RESUME) || - (swrm->state == SWR_MSTR_UP)) { + if (swrm->state == SWR_MSTR_UP) { dev_dbg(swrm->dev, "%s: SWR master is already UP: %d\n", __func__, swrm->state); list_for_each_entry(swr_dev, &mstr->devices, dev_list) -- GitLab From 2a0996bc17c7f67796d6c45cec92a01ea8b2432d Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Tue, 25 Sep 2018 20:13:30 +0530 Subject: [PATCH 0581/1645] soc: swr-mstr: Fix port collision during wsa playback Fix block pack mode parameter in wsa frame params to to get proper frame allocation avoiding port collision between DAC port and SMART BOOST port. Change-Id: I3e552f189a67661d63a6cd0affc1cb233b53bda7 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 9 ++++++--- soc/swrm_port_config.h | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 7232fe83caa8..6d91d26a2d1a 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -843,7 +843,8 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank) port_req->dev_num, 0x00, SWRS_DP_BLOCK_CONTROL_1(slv_id)); } - if (mport->blk_pack_mode != SWR_INVALID_PARAM) { + if (mport->blk_pack_mode != SWR_INVALID_PARAM + && swrm->master_id != MASTER_ID_WSA) { reg[len] = SWRM_CMD_FIFO_WR_CMD; val[len++] = SWR_REG_VAL_PACK(mport->blk_pack_mode, @@ -871,8 +872,10 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank) } value = ((mport->req_ch) << SWRM_DP_PORT_CTRL_EN_CHAN_SHFT); - value |= ((mport->offset2) - << SWRM_DP_PORT_CTRL_OFFSET2_SHFT); + + if (mport->offset2 != SWR_INVALID_PARAM) + value |= ((mport->offset2) + << SWRM_DP_PORT_CTRL_OFFSET2_SHFT); value |= ((mport->offset1) << SWRM_DP_PORT_CTRL_OFFSET1_SHFT); value |= mport->sinterval; diff --git a/soc/swrm_port_config.h b/soc/swrm_port_config.h index 86cc9221a1da..81bab1c90bff 100644 --- a/soc/swrm_port_config.h +++ b/soc/swrm_port_config.h @@ -24,10 +24,10 @@ struct port_params wsa_frame_superset[SWR_MSTR_PORT_LEN] = { {7, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {31, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - {63, 12, 31, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {63, 12, 31, 0xFF, 0xFF, 0xFF, 0x1, 0xFF, 0xFF}, {7, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {31, 18, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - {63, 13, 31, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {63, 13, 31, 0xFF, 0xFF, 0xFF, 0x1, 0xFF, 0xFF}, {15, 7, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {15, 10, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, }; -- GitLab From 78607e492712ac9a4e99934727e6bd4cf6abd67e Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 7 Sep 2018 09:32:54 +0530 Subject: [PATCH 0582/1645] ASoC: wcd934x: Set micbias curr to higher value when micb is enabled When micbias is enabled set curr to higher value for vreg bob bypass and when it is disabled set it to default value for sm6150. CRs-Fixed: 2315478 Change-Id: I451506002f382e666d47bc83944bdc8dbbedcad8 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd934x/wcd934x.c | 38 ++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 2a6d829f2443..5713b9e2db06 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -68,6 +68,9 @@ #define WCD934X_FORMATS_S16_LE (SNDRV_PCM_FMTBIT_S16_LE) +#define MICB_LOAD_PROP "qcom,vreg-micb" +#define MICB_LOAD_DEFAULT 30400 + /* Macros for packing register writes into a U32 */ #define WCD934X_PACKED_REG_SIZE sizeof(u32) #define WCD934X_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \ @@ -637,6 +640,9 @@ struct tavil_priv { struct platform_device *pdev_child_devices [WCD934X_CHILD_DEVICES_MAX]; int child_count; + struct regulator *micb_load; + int micb_load_low; + int micb_load_high; }; static const struct tavil_reg_mask_val tavil_spkr_default[] = { @@ -4882,6 +4888,9 @@ int tavil_micbias_control(struct snd_soc_codec *codec, case MICB_ENABLE: tavil->micb_ref[micb_index]++; if (tavil->micb_ref[micb_index] == 1) { + if (tavil->micb_load) + regulator_set_load(tavil->micb_load, + tavil->micb_load_high); snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); if (post_on_event && tavil->mbhc) blocking_notifier_call_chain( @@ -4912,6 +4921,9 @@ int tavil_micbias_control(struct snd_soc_codec *codec, &tavil->mbhc->notifier, post_off_event, &tavil->mbhc->wcd_mbhc); + if (tavil->micb_load) + regulator_set_load(tavil->micb_load, + tavil->micb_load_low); } if (is_dapm && post_dapm_off && tavil->mbhc) blocking_notifier_call_chain(&tavil->mbhc->notifier, @@ -10947,11 +10959,12 @@ static const struct snd_event_ops wcd934x_ssr_ops = { static int tavil_probe(struct platform_device *pdev) { - int ret = 0; + int ret = 0, len = 0; struct tavil_priv *tavil; struct clk *wcd_ext_clk; struct wcd9xxx_resmgr_v2 *resmgr; struct wcd9xxx_power_region *cdc_pwr; + const __be32 *micb_prop; tavil = devm_kzalloc(&pdev->dev, sizeof(struct tavil_priv), GFP_KERNEL); @@ -11078,6 +11091,26 @@ static int tavil_probe(struct platform_device *pdev) ret = 0; } + tavil->micb_load = NULL; + + if (of_get_property(tavil->wcd9xxx->dev->of_node, + "qcom,vreg-micb-supply", NULL)) { + micb_prop = of_get_property(tavil->wcd9xxx->dev->of_node, + "qcom,cdc-vdd-mic-bias-current", + &len); + if (!micb_prop || (len != (2 * sizeof(__be32)))) { + tavil->micb_load_low = MICB_LOAD_DEFAULT; + tavil->micb_load_high = MICB_LOAD_DEFAULT; + } else { + tavil->micb_load_low = be32_to_cpup(&micb_prop[0]); + tavil->micb_load_high = be32_to_cpup(&micb_prop[1]); + } + tavil->micb_load = regulator_get(&pdev->dev, MICB_LOAD_PROP); + if (IS_ERR(tavil->micb_load)) + dev_dbg(tavil->dev, "%s micb load get failed\n", + __func__); + } + return ret; err_cdc_reg: @@ -11119,6 +11152,9 @@ static int tavil_remove(struct platform_device *pdev) count < WCD934X_CHILD_DEVICES_MAX; count++) platform_device_unregister(tavil->pdev_child_devices[count]); + if (tavil->micb_load) + regulator_put(tavil->micb_load); + mutex_destroy(&tavil->micb_lock); mutex_destroy(&tavil->svs_mutex); mutex_destroy(&tavil->codec_mutex); -- GitLab From 8148b998edce0b292d2c66a20cd90f9b1463c678 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 27 Sep 2018 16:20:30 +0530 Subject: [PATCH 0583/1645] ASoC: wcd9xxx: Add gpio control for micbias-supply for SXR1120 SXR1120 has additional gpio for micbias supply to be enabled. Add control for this gpio and enable it. Change-Id: Ica4ea9765db9bd48a1f8eb010d82d2687c8abbb9 Signed-off-by: Vatsal Bucha --- asoc/codecs/pdata.h | 4 +++- asoc/codecs/wcd9xxx-core.c | 3 +++ asoc/codecs/wcd9xxx-utils.c | 13 +++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/pdata.h b/asoc/codecs/pdata.h index 6df80eb064d6..d38ae84914b7 100644 --- a/asoc/codecs/pdata.h +++ b/asoc/codecs/pdata.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -180,7 +180,9 @@ struct wcd9xxx_pdata { int num_irqs; int reset_gpio; bool has_buck_vsel_gpio; + bool has_micb_supply_en_gpio; struct device_node *buck_vsel_ctl_np; + struct device_node *micb_en_ctl; struct device_node *wcd_rst_np; struct wcd9xxx_amic amic_settings; struct slim_device slimbus_slave_device; diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index 3fe398e7cbd9..76aea1a62b69 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -1289,6 +1289,9 @@ static int wcd9xxx_slim_probe(struct slim_device *slim) if (pdata->has_buck_vsel_gpio) msm_cdc_pinctrl_select_active_state(pdata->buck_vsel_ctl_np); + if (pdata->has_micb_supply_en_gpio) + msm_cdc_pinctrl_select_active_state(pdata->micb_en_ctl); + device_id = slim_get_device_id(slim); if (!device_id) { dev_err(&slim->dev, "%s: Error, no device id\n", __func__); diff --git a/asoc/codecs/wcd9xxx-utils.c b/asoc/codecs/wcd9xxx-utils.c index bc30c9c1bd01..7dc18f68b1e9 100644 --- a/asoc/codecs/wcd9xxx-utils.c +++ b/asoc/codecs/wcd9xxx-utils.c @@ -365,6 +365,19 @@ struct wcd9xxx_pdata *wcd9xxx_populate_dt_data(struct device *dev) } } + pdata->has_micb_supply_en_gpio = of_property_read_bool(dev->of_node, + "qcom,has-micbias-supply-en-gpio"); + if (pdata->has_micb_supply_en_gpio) { + pdata->micb_en_ctl = of_parse_phandle(dev->of_node, + "qcom,micbias-supply-en-gpio-node", 0); + if (!pdata->micb_en_ctl) { + dev_err(dev, "%s No entry for %s property in node %s\n", + __func__, "qcom,micbias-supply-en-gpio-node", + dev->of_node->full_name); + goto err_parse_dt_prop; + } + } + if (!(wcd9xxx_read_of_property_u32(dev, "qcom,cdc-mclk-clk-rate", &prop_val))) pdata->mclk_rate = prop_val; -- GitLab From 493a1b3ea9ae715e0d38c7d18cfc508dc7f346db Mon Sep 17 00:00:00 2001 From: Sharad Sangle Date: Wed, 19 Sep 2018 15:52:15 +0530 Subject: [PATCH 0584/1645] asoc: sm6150: add configuration for adaptive bitrate Add mixer ctrls to independently configure TX and RX sample rates for BT RX and TX backends. Change-Id: I011d3bfb85448605717e2c1a20c19a2fc86dac3f Signed-off-by: Sharad Sangle --- asoc/sm6150.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 72181221ea1f..991245216af0 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -466,6 +466,12 @@ static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_44P1", "KHZ_48", "KHZ_88P2", "KHZ_96"}; +static char const *bt_sample_rate_rx_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; +static char const *bt_sample_rate_tx_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; @@ -531,6 +537,8 @@ static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_rx, bt_sample_rate_rx_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_tx, bt_sample_rate_tx_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, @@ -1192,7 +1200,129 @@ static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, return 0; } +static int msm_bt_sample_rate_rx_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate rx = %d", __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_rx_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rate: slim7_rx = %d, value = %d\n", + __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_bt_sample_rate_tx_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (slim_tx_cfg[SLIM_TX_7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate tx = %d", __func__, + slim_tx_cfg[SLIM_TX_7].sample_rate); + + return 0; +} +static int msm_bt_sample_rate_tx_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rate: slim7_tx = %d, value = %d\n", + __func__, + slim_tx_cfg[SLIM_TX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} static int cdc_dma_get_port_idx(struct snd_kcontrol *kcontrol) { int idx = 0; @@ -3647,6 +3777,12 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, msm_bt_sample_rate_get, msm_bt_sample_rate_put), + SOC_ENUM_EXT("BT SampleRate RX", bt_sample_rate_rx, + msm_bt_sample_rate_rx_get, + msm_bt_sample_rate_rx_put), + SOC_ENUM_EXT("BT SampleRate TX", bt_sample_rate_tx, + msm_bt_sample_rate_tx_get, + msm_bt_sample_rate_tx_put), SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), }; -- GitLab From d155fdcb2f09184d78873eba160e6228124218c0 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Thu, 11 Oct 2018 15:11:59 +0800 Subject: [PATCH 0585/1645] asoc: bolero: avoid TX distortion by runtime HPF param change Runtime HPF param change leads to TX distortion at the beginning. Unmute HPF after param change. Change-Id: I7683ca047123dd004fb2dd019365305edfc72ea5 Signed-off-by: Xiaojun Sang --- asoc/codecs/bolero/tx-macro.c | 9 +++------ asoc/codecs/bolero/va-macro.c | 9 +++------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 09dd3b097b01..a16f778de4d3 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -370,10 +370,10 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) tx_hpf_set: snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, hpf_cut_off_freq << 5); - snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); + snd_soc_update_bits(codec, hpf_gate_reg, 0x03, 0x02); /* Minimum 1 clk cycle delay is required as per HW spec */ usleep_range(1000, 1010); - snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00); + snd_soc_update_bits(codec, hpf_gate_reg, 0x03, 0x01); } static void tx_macro_mute_update_callback(struct work_struct *work) @@ -382,7 +382,7 @@ static void tx_macro_mute_update_callback(struct work_struct *work) struct snd_soc_codec *codec = NULL; struct tx_macro_priv *tx_priv = NULL; struct delayed_work *delayed_work = NULL; - u16 tx_vol_ctl_reg = 0, hpf_gate_reg = 0; + u16 tx_vol_ctl_reg = 0; u8 decimator = 0; delayed_work = to_delayed_work(work); @@ -394,9 +394,6 @@ static void tx_macro_mute_update_callback(struct work_struct *work) tx_vol_ctl_reg = BOLERO_CDC_TX0_TX_PATH_CTL + TX_MACRO_TX_PATH_OFFSET * decimator; - hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 + - TX_MACRO_TX_PATH_OFFSET * decimator; - snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x01); snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); dev_dbg(tx_priv->dev, "%s: decimator %u unmute\n", __func__, decimator); diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 0bbdc68be334..e32d9cdc9654 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -304,10 +304,10 @@ static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, hpf_cut_off_freq << 5); - snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); + snd_soc_update_bits(codec, hpf_gate_reg, 0x03, 0x02); /* Minimum 1 clk cycle delay is required as per HW spec */ usleep_range(1000, 1010); - snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00); + snd_soc_update_bits(codec, hpf_gate_reg, 0x03, 0x01); } static void va_macro_mute_update_callback(struct work_struct *work) @@ -316,7 +316,7 @@ static void va_macro_mute_update_callback(struct work_struct *work) struct snd_soc_codec *codec = NULL; struct va_macro_priv *va_priv; struct delayed_work *delayed_work; - u16 tx_vol_ctl_reg, hpf_gate_reg, decimator; + u16 tx_vol_ctl_reg, decimator; delayed_work = to_delayed_work(work); va_mute_dwork = container_of(delayed_work, struct va_mute_work, dwork); @@ -327,9 +327,6 @@ static void va_macro_mute_update_callback(struct work_struct *work) tx_vol_ctl_reg = BOLERO_CDC_VA_TX0_TX_PATH_CTL + VA_MACRO_TX_PATH_OFFSET * decimator; - hpf_gate_reg = BOLERO_CDC_VA_TX0_TX_PATH_SEC2 + - VA_MACRO_TX_PATH_OFFSET * decimator; - snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x01); snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); dev_dbg(va_priv->dev, "%s: decimator %u unmute\n", __func__, decimator); -- GitLab From fdcc0985a27186fd22648acd976df9c0b77cc5c4 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Tue, 2 Oct 2018 15:14:03 -0700 Subject: [PATCH 0586/1645] asoc: routing: add tdm loopback from tert tx7 to sec rx7 Add hostless loopback routing from TERT TDM TX 7 to SEC TDM RX 7. Change-Id: Id6737b0f292ec3ff541d988338db8ad4f8cf6ee9 Signed-off-by: Derek Chen --- asoc/msm-pcm-routing-v2.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 1c9ad1a9d4ba..d60301d88dfe 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -14654,6 +14654,14 @@ static const struct snd_kcontrol_new sec_tdm_rx_3_port_mixer_controls[] = { msm_routing_put_port_mixer), }; +static const struct snd_kcontrol_new sec_tdm_rx_7_port_mixer_controls[] = { + SOC_DOUBLE_EXT("TERT_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_7, + MSM_BACKEND_DAI_TERT_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + static const struct snd_kcontrol_new tert_tdm_rx_0_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_RX_0, @@ -18898,6 +18906,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("SEC_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0, sec_tdm_rx_3_port_mixer_controls, ARRAY_SIZE(sec_tdm_rx_3_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_7 Port Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_7_port_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_7_port_mixer_controls)), SND_SOC_DAPM_MIXER("TERT_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, tert_tdm_rx_0_port_mixer_controls, ARRAY_SIZE(tert_tdm_rx_0_port_mixer_controls)), @@ -21440,10 +21451,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1_DL_HL"}, {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2_DL_HL"}, {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3_DL_HL"}, + {"SEC_TDM_RX_7", NULL, "SEC_TDM_RX_7_DL_HL"}, {"TERT_TDM_TX_0_UL_HL", NULL, "TERT_TDM_TX_0"}, {"TERT_TDM_TX_1_UL_HL", NULL, "TERT_TDM_TX_1"}, {"TERT_TDM_TX_2_UL_HL", NULL, "TERT_TDM_TX_2"}, {"TERT_TDM_TX_3_UL_HL", NULL, "TERT_TDM_TX_3"}, + {"TERT_TDM_TX_7_UL_HL", NULL, "TERT_TDM_TX_7"}, {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0_DL_HL"}, {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1_DL_HL"}, {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2_DL_HL"}, @@ -21641,6 +21654,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Port Mixer"}, + {"SEC_TDM_RX_7 Port Mixer", "TERT_TDM_TX_7", "TERT_TDM_TX_7"}, + {"SEC_TDM_RX_7", NULL, "SEC_TDM_RX_7 Port Mixer"}, + {"TERT_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"TERT_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"TERT_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, @@ -22217,6 +22233,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "SEC_TDM_RX_1"}, {"BE_OUT", NULL, "SEC_TDM_RX_2"}, {"BE_OUT", NULL, "SEC_TDM_RX_3"}, + {"BE_OUT", NULL, "SEC_TDM_RX_7"}, {"BE_OUT", NULL, "TERT_TDM_RX_0"}, {"BE_OUT", NULL, "TERT_TDM_RX_1"}, {"BE_OUT", NULL, "TERT_TDM_RX_2"}, @@ -22304,6 +22321,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_TX_1", NULL, "BE_IN"}, {"TERT_TDM_TX_2", NULL, "BE_IN"}, {"TERT_TDM_TX_3", NULL, "BE_IN"}, + {"TERT_TDM_TX_7", NULL, "BE_IN"}, {"QUAT_TDM_TX_0", NULL, "BE_IN"}, {"QUAT_TDM_TX_1", NULL, "BE_IN"}, {"QUAT_TDM_TX_2", NULL, "BE_IN"}, -- GitLab From 077589df00b2ec7579ce61858e93b589f5b56b53 Mon Sep 17 00:00:00 2001 From: Bhalchandra Gajare Date: Tue, 27 Mar 2018 18:45:49 -0700 Subject: [PATCH 0587/1645] ASoC: wcd934x: enable MAD fs_cntr by default Currently, the fs_cntr for MAD is enabled whenever the MAD audio path is enabled. But, a new issue is reported where MAD fs_cntr is required even for some of the non-MAD paths. As per hardware requirements, enable the MAD fs_cntr always from the codec default registers. Change-Id: I6fe8f663b82e711b4194aa51a3e21150aa98cf02 Signed-off-by: Bhalchandra Gajare --- asoc/codecs/wcd934x/wcd934x.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index e268a734c199..44f741e7951b 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -3174,8 +3174,6 @@ static int __tavil_codec_enable_mad(struct snd_soc_codec *codec, bool enable) /* Undo reset for MAD */ snd_soc_update_bits(codec, WCD934X_CPE_SS_MAD_CTL, 0x02, 0x00); - snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_MCLK_CFG, - 0x04, 0x04); } else { snd_soc_update_bits(codec, WCD934X_SOC_MAD_AUDIO_CTL_2, 0x03, 0x00); @@ -3185,8 +3183,6 @@ static int __tavil_codec_enable_mad(struct snd_soc_codec *codec, bool enable) /* Turn off MAD clk */ snd_soc_update_bits(codec, WCD934X_CPE_SS_MAD_CTL, 0x01, 0x00); - snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_MCLK_CFG, - 0x04, 0x00); } done: return rc; @@ -9416,6 +9412,7 @@ static const struct tavil_reg_mask_val tavil_codec_reg_defaults[] = { {WCD934X_HPH_R_TEST, 0x01, 0x01}, {WCD934X_CPE_FLL_CONFIG_CTL_2, 0xFF, 0x20}, {WCD934X_MBHC_NEW_CTL_2, 0x0C, 0x00}, + {WCD934X_CODEC_RPM_CLK_MCLK_CFG, 0x04, 0x04}, }; static const struct tavil_reg_mask_val tavil_codec_reg_init_1_1_val[] = { -- GitLab From 7b3952d3ce7368ab4e0b1b2228bbd69bbad3b675 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Wed, 10 Oct 2018 10:44:08 -0700 Subject: [PATCH 0588/1645] asoc: msm: routing: remove WARN() log messages Replace WARN() log messages with pr_warn() to avoid exposing call stack in logs. Change-Id: I3485a28f18431ae48ad0efbe49635a8cff9f40cd Signed-off-by: Vidyakumar Athota --- asoc/msm-pcm-routing-v2.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index ab07d7ec9bc0..6776f568836f 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -2698,7 +2698,8 @@ static int msm_routing_lsm_func_get(struct snd_kcontrol *kcontrol, break; if (i-- == ARRAY_SIZE(lsm_port_text)) { - WARN(1, "Invalid id name %s\n", kcontrol->id.name); + pr_warn("%s: Invalid id name %s\n", __func__, + kcontrol->id.name); return -EINVAL; } @@ -2745,7 +2746,7 @@ static int msm_routing_lsm_func_get(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[0] = MADSWAUDIO; break; default: - WARN(1, "Unknown\n"); + pr_warn("%s: Unknown\n", __func__); return -EINVAL; } return 0; @@ -2765,7 +2766,8 @@ static int msm_routing_lsm_func_put(struct snd_kcontrol *kcontrol, break; if (i-- == ARRAY_SIZE(lsm_port_text)) { - WARN(1, "Invalid id name %s\n", kcontrol->id.name); + pr_warn("%s: Invalid id name %s\n", __func__, + kcontrol->id.name); return -EINVAL; } @@ -2787,7 +2789,7 @@ static int msm_routing_lsm_func_put(struct snd_kcontrol *kcontrol, mad_type = MAD_SW_AUDIO; break; default: - WARN(1, "Unknown\n"); + pr_warn("%s: Unknown\n", __func__); return -EINVAL; } -- GitLab From bc81e3af175079d3f4d4d2fc97c258edfb6cab62 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Tue, 9 Oct 2018 11:38:02 +0530 Subject: [PATCH 0589/1645] dsp: enable VAD support on TDM interface Send VAD configuration during TDM port start. Change-Id: I30b45b066b2ca5fdf49cd74d87d95f75566661c9 Signed-off-by: Mangesh Kunchamwar --- dsp/q6afe.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 6697208e6616..298993ca9308 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -3274,8 +3274,22 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id); } - /* Also send the topology id here: */ port_index = afe_get_port_index(port_id); + + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) { + /* send VAD configuration if enabled */ + if (this_afe.vad_cfg[port_index].is_enable) { + ret = afe_send_port_vad_cfg_params(port_id); + if (ret) { + pr_err("%s: afe send VAD config failed %d\n", + __func__, ret); + goto fail_cmd; + } + } + } + + /* Also send the topology id here: */ if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) { /* One time call: only for first time */ afe_send_custom_topology(); -- GitLab From 9850fb1429afabffd8619e90cf64c9a4eb70429b Mon Sep 17 00:00:00 2001 From: Shaikh Shadul Date: Mon, 1 Oct 2018 23:08:01 +0530 Subject: [PATCH 0590/1645] dsp: Add restart interface for adsp User space sensor daemon requires to restart the audio dsp during some of the sensors usecases. Add sysfs interface to do adsp subsystem restart from user space sensor daemon. Change-Id: I07c78892cb6e6f99ae93c04eddbc321681b52a70 Signed-off-by: Shaikh Shadul --- dsp/adsp-loader.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/dsp/adsp-loader.c b/dsp/adsp-loader.c index cc995db9069b..5afd48cd8d63 100644 --- a/dsp/adsp-loader.c +++ b/dsp/adsp-loader.c @@ -26,12 +26,17 @@ #define Q6_PIL_GET_DELAY_MS 100 #define BOOT_CMD 1 +#define SSR_RESET_CMD 1 #define IMAGE_UNLOAD_CMD 0 static ssize_t adsp_boot_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count); +static ssize_t adsp_ssr_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count); + struct adsp_loader_private { void *pil_h; struct kobject *boot_adsp_obj; @@ -41,8 +46,12 @@ struct adsp_loader_private { static struct kobj_attribute adsp_boot_attribute = __ATTR(boot, 0220, NULL, adsp_boot_store); +static struct kobj_attribute adsp_ssr_attribute = + __ATTR(ssr, 0220, NULL, adsp_ssr_store); + static struct attribute *attrs[] = { &adsp_boot_attribute.attr, + &adsp_ssr_attribute.attr, NULL, }; @@ -151,6 +160,46 @@ static void adsp_loader_do(struct platform_device *pdev) schedule_work(&adsp_ldr_work); } +static ssize_t adsp_ssr_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + int ssr_command = 0; + struct subsys_device *adsp_dev = NULL; + struct platform_device *pdev = adsp_private; + struct adsp_loader_private *priv = NULL; + int rc; + + dev_dbg(&pdev->dev, "%s: going to call adsp ssr\n ", __func__); + + if (kstrtoint(buf, 10, &ssr_command) < 0) + return -EINVAL; + + if (ssr_command != SSR_RESET_CMD) + return -EINVAL; + + priv = platform_get_drvdata(pdev); + if (!priv) + return -EINVAL; + + adsp_dev = (struct subsys_device *)priv->pil_h; + if (!adsp_dev) + return -EINVAL; + + dev_err(&pdev->dev, "requesting for ADSP restart\n"); + + /* subsystem_restart_dev has worker queue to handle */ + rc = subsystem_restart_dev(adsp_dev); + if (rc) { + dev_err(&pdev->dev, "subsystem_restart_dev failed\n"); + return rc; + } + + dev_dbg(&pdev->dev, "ADSP restarted\n"); + return count; +} + static ssize_t adsp_boot_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, -- GitLab From 9f295c71fef2e6375c2634012822389cda84d170 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Mon, 8 Oct 2018 18:20:41 +0530 Subject: [PATCH 0591/1645] msm: featurize support for 32channels from QDSP6 Add configuration flag to make use of 32channel support from QDSP6. Change-Id: I1e491b1ec870234140e914add4f177e5351b9953 Signed-off-by: Mangesh Kunchamwar --- asoc/msm-pcm-q6-v2.c | 20 ++++++++++++-------- config/qcs405auto.conf | 1 + config/qcs405autoconf.h | 1 + dsp/q6adm.c | 5 +++-- include/dsp/q6core.h | 13 +++++++++++++ 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 714197487d53..eb32f633ed55 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -386,9 +386,10 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) return -ENOMEM; } } else { - if (q6core_get_avcs_api_version_per_service( + if ((q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= - ADSP_ASM_API_VERSION_V2) + ADSP_ASM_API_VERSION_V2) && + q6core_use_Q6_32ch_support()) ret = q6asm_open_write_v5(prtd->audio_client, fmt_type, bits_per_sample); else @@ -434,9 +435,10 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) prtd->channel_map, bits_per_sample); } else { - if (q6core_get_avcs_api_version_per_service( + if ((q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= - ADSP_ASM_API_VERSION_V2) { + ADSP_ASM_API_VERSION_V2) && + q6core_use_Q6_32ch_support()) { ret = q6asm_media_format_block_multi_ch_pcm_v5( prtd->audio_client, runtime->rate, @@ -510,9 +512,10 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) __func__, params_channels(params), prtd->audio_client->perf_mode); - if (q6core_get_avcs_api_version_per_service( + if ((q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= - ADSP_ASM_API_VERSION_V2) + ADSP_ASM_API_VERSION_V2) && + q6core_use_Q6_32ch_support()) ret = q6asm_open_read_v5(prtd->audio_client, FORMAT_LINEAR_PCM, bits_per_sample, false, ENC_CFG_ID_NONE); @@ -587,9 +590,10 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) __func__, prtd->samp_rate, prtd->channel_mode, bits_per_sample, sample_word_size); - if (q6core_get_avcs_api_version_per_service( + if ((q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= - ADSP_ASM_API_VERSION_V2) + ADSP_ASM_API_VERSION_V2) && + q6core_use_Q6_32ch_support()) ret = q6asm_enc_cfg_blk_pcm_format_support_v5( prtd->audio_client, prtd->samp_rate, diff --git a/config/qcs405auto.conf b/config/qcs405auto.conf index 61620ebb6d39..afa8140b6e04 100644 --- a/config/qcs405auto.conf +++ b/config/qcs405auto.conf @@ -36,3 +36,4 @@ CONFIG_SND_SOC_MSM_STUB=m CONFIG_MSM_AVTIMER=m CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m CONFIG_SND_SOC_EP92=m +CONFIG_USE_Q6_32CH_SUPPORT=m diff --git a/config/qcs405autoconf.h b/config/qcs405autoconf.h index 98cd1660335c..fd9407bdbce3 100644 --- a/config/qcs405autoconf.h +++ b/config/qcs405autoconf.h @@ -48,3 +48,4 @@ #define CONFIG_MSM_AVTIMER 1 #define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 #define CONFIG_SND_SOC_EP92 1 +#define CONFIG_USE_Q6_32CH_SUPPORT 1 diff --git a/dsp/q6adm.c b/dsp/q6adm.c index b39b44922242..fcc1fa13184d 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2903,9 +2903,10 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, } - if (q6core_get_avcs_api_version_per_service( + if ((q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ADM_V) >= - ADSP_ADM_API_VERSION_V3) { + ADSP_ADM_API_VERSION_V3) && + q6core_use_Q6_32ch_support()) { memset(&open_v8, 0, sizeof(open_v8)); memset(&ep1_payload, 0, sizeof(ep1_payload)); memset(&ep2_payload, 0, sizeof(ep2_payload)); diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index 4d5a973d2956..eaca526f8dda 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -208,4 +208,17 @@ int32_t core_get_license_status(uint32_t module_id); int32_t q6core_load_unload_topo_modules(uint32_t topology_id, bool preload_type); + +#if IS_ENABLED(CONFIG_USE_Q6_32CH_SUPPORT) +static inline bool q6core_use_Q6_32ch_support(void) +{ + return true; +} +#else +static inline bool q6core_use_Q6_32ch_support(void) +{ + return false; +} +#endif + #endif /* __Q6CORE_H__ */ -- GitLab From 27c57727238586cfc6c2b81e33b441185e981331 Mon Sep 17 00:00:00 2001 From: Dieter Luecking Date: Fri, 5 Oct 2018 16:45:41 +0200 Subject: [PATCH 0592/1645] dsp: Fix wrong payload size in adm_open command Correcting payload length for adm_cmd_device_open_v8 usage if endpoint_id1 and endpoint_id2 are valid and this_adm.num_ec_ref_rx_chans is 0. Change-Id: I82815a2d885cdad5a9427c11eb73224289b158b3 Signed-off-by: Dieter Luecking --- dsp/q6adm.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index b39b44922242..9a6d2f888cee 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2935,10 +2935,6 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, open_v8.endpoint_id_2 = 0xFFFF; open_v8.endpoint_id_3 = 0xFFFF; - if (this_adm.ec_ref_rx && (path != 1)) { - open_v8.endpoint_id_2 = this_adm.ec_ref_rx; - this_adm.ec_ref_rx = -1; - } open_v8.topology_id = topology; open_v8.reserved = 0; @@ -2966,8 +2962,11 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, + ep1_payload_size; atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - if ((this_adm.num_ec_ref_rx_chans != 0) && (path != 1) + if ((this_adm.num_ec_ref_rx_chans != 0) + && (path != ADM_PATH_PLAYBACK) && (open_v8.endpoint_id_2 != 0xFFFF)) { + open_v8.endpoint_id_2 = this_adm.ec_ref_rx; + this_adm.ec_ref_rx = -1; ep2_payload.dev_num_channel = this_adm.num_ec_ref_rx_chans; this_adm.num_ec_ref_rx_chans = 0; @@ -3004,18 +3003,23 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, param_size += ep2_payload_size; } + open_v8.hdr.pkt_size = param_size; adm_params = kzalloc(param_size, GFP_KERNEL); if (!adm_params) return -ENOMEM; - open_v8.hdr.pkt_size = param_size; memcpy(adm_params, &open_v8, sizeof(open_v8)); memcpy(adm_params + sizeof(open_v8), (void *)&ep1_payload, ep1_payload_size); - memcpy(adm_params + sizeof(open_v8) - + ep1_payload_size, - (void *)&ep2_payload, - ep2_payload_size); + + if ((this_adm.num_ec_ref_rx_chans != 0) + && (path != ADM_PATH_PLAYBACK) + && (open_v8.endpoint_id_2 != 0xFFFF)) { + memcpy(adm_params + sizeof(open_v8) + + ep1_payload_size, + (void *)&ep2_payload, + ep2_payload_size); + } ret = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); -- GitLab From f83634eeade69158919e9b8c15ab97825b968c44 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Fri, 12 Oct 2018 22:21:07 +0530 Subject: [PATCH 0593/1645] asoc: bolero: Increase timeout for session down during ssr Sometimes observed that session is taken more time to teardown after ssr. Increase timeout to allow more time for session to be tear down. Change-Id: I3f1b4d8f583ad5b9c8f5e1b90af9c576ae6bd2b2 Signed-off-by: Ramprasad Katkam --- asoc/codecs/bolero/va-macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 0bbdc68be334..77e645f64cf7 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -46,7 +46,7 @@ #define VA_MACRO_TX_DMIC_CLK_DIV_SHFT 0x01 #define BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS 40 -#define MAX_RETRY_ATTEMPTS 50 +#define MAX_RETRY_ATTEMPTS 250 static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); static int va_tx_unmute_delay = BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS; -- GitLab From 85599d7787bfcbfbcc664f25f578b9e0b1687aa7 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Tue, 2 Oct 2018 15:17:11 -0700 Subject: [PATCH 0594/1645] ASoC: add dai links for tert tdm tx7 and sec rx7 Add hostless FE and TDM BE DAI links for TERT TDM TX7 and SEC TDM RX7 ports. Change-Id: I57fed1162c5dc175475e7990f57d4a010a9057f2 Signed-off-by: Derek Chen --- asoc/sa8155.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 5 deletions(-) diff --git a/asoc/sa8155.c b/asoc/sa8155.c index 5e51f0969e39..a477a85a7592 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -397,7 +397,7 @@ static unsigned int tdm_rx_slot_offset {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {28, 0xFFFF}, }, {/* TERT TDM */ {0, 4, 8, 12, 16, 20, 0xFFFF}, @@ -461,7 +461,7 @@ static unsigned int tdm_tx_slot_offset {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {28, 0xFFFF}, }, {/* QUAT TDM */ {0xFFFF}, /* not used */ @@ -512,7 +512,7 @@ static unsigned int tdm_rx_slot_offset_custom {10, 0xFFFF}, {12, 14, 16, 18, 20, 22, 24, 26, 0xFFFF}, {28, 30, 0xFFFF}, - {0xFFFF}, /* not used */ + {30, 0xFFFF}, }, {/* TERT TDM */ {0, 2, 0xFFFF}, @@ -576,7 +576,7 @@ static unsigned int tdm_tx_slot_offset_custom {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {30, 0xFFFF}, }, {/* QUAT TDM */ {0xFFFF}, /* not used */ @@ -4018,6 +4018,14 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_3].sample_rate; break; + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_7].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_7].sample_rate; + break; case AFE_PORT_ID_SECONDARY_TDM_TX: channels->min = channels->max = tdm_tx_cfg[TDM_SEC][TDM_0].channels; @@ -4122,6 +4130,14 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_3].sample_rate; break; + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_7].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_7].sample_rate; + break; case AFE_PORT_ID_QUATERNARY_TDM_RX: channels->min = channels->max = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; @@ -4375,6 +4391,11 @@ static int sa8155_tdm_snd_hw_params(struct snd_pcm_substream *substream, slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_3]; break; + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_7]; + break; case AFE_PORT_ID_SECONDARY_TDM_TX: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; @@ -4440,6 +4461,11 @@ static int sa8155_tdm_snd_hw_params(struct snd_pcm_substream *substream, slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_3]; break; + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_7]; + break; case AFE_PORT_ID_QUATERNARY_TDM_RX: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; @@ -5565,7 +5591,37 @@ static struct snd_soc_dai_link msm_auto_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_DTMF_RX, - } + }, + { + .name = "Secondary TDM RX 7 Hostless", + .stream_name = "Secondary TDM RX 7 Hostless", + .cpu_dai_name = "SEC_TDM_RX_7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Tertiary TDM TX 7 Hostless", + .stream_name = "Tertiary TDM TX 7 Hostless", + .cpu_dai_name = "TERT_TDM_TX_7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, }; static struct snd_soc_dai_link msm_custom_fe_dai_links[] = { @@ -6118,6 +6174,20 @@ static struct snd_soc_dai_link msm_auto_be_dai_links[] = { .ops = &sa8155_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_SEC_TDM_RX_7, + .stream_name = "Secondary TDM7 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36894", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_7, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, { .name = LPASS_BE_SEC_TDM_TX_1, .stream_name = "Secondary TDM1 Capture", @@ -6258,6 +6328,20 @@ static struct snd_soc_dai_link msm_auto_be_dai_links[] = { .ops = &sa8155_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_TERT_TDM_TX_7, + .stream_name = "Tertiary TDM7 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36911", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_7, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, { .name = LPASS_BE_QUAT_TDM_RX_1, .stream_name = "Quaternary TDM1 Playback", -- GitLab From 6cb17a0a3fe4f4e47c5bbad08dc8f2d84f489f72 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 7 Aug 2018 11:07:04 +0530 Subject: [PATCH 0595/1645] ASoC: sm6150: Use FSA for USBC gnd-mic swap USBC gnd mic swap is taken care of by FSA4480. Gpio does not need to be swapped for this purpose. CRs-Fixed: 2323772 Change-Id: Ida490995761ec5361ff2302b990d3c6fe1f32f85 Signed-off-by: Vatsal Bucha --- asoc/sm6150.c | 96 ++++++++++----------------------------------------- 1 file changed, 18 insertions(+), 78 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 184960582be6..0508f063c751 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -202,6 +203,7 @@ struct msm_asoc_mach_data { struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ bool is_afe_config_done; + struct device_node *fsa_handle; }; struct msm_asoc_wcd93xx_codec { @@ -4465,88 +4467,14 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, static bool msm_usbc_swap_gnd_mic(struct snd_soc_codec *codec, bool active) { - int value = 0; - bool ret = 0; struct snd_soc_card *card = codec->component.card; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct pinctrl_state *en2_pinctrl_active; - struct pinctrl_state *en2_pinctrl_sleep; - - if (!pdata->usbc_en2_gpio_p) { - if (active) { - /* if active and usbc_en2_gpio undefined, get pin */ - pdata->usbc_en2_gpio_p = devm_pinctrl_get(card->dev); - if (IS_ERR_OR_NULL(pdata->usbc_en2_gpio_p)) { - dev_err(card->dev, - "%s: Can't get EN2 gpio pinctrl:%ld\n", - __func__, - PTR_ERR(pdata->usbc_en2_gpio_p)); - pdata->usbc_en2_gpio_p = NULL; - return false; - } - } else { - /* if not active and usbc_en2_gpio undefined, return */ - return false; - } - } + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); - pdata->usbc_en2_gpio = of_get_named_gpio(card->dev->of_node, - "qcom,usbc-analog-en2-gpio", 0); - if (!gpio_is_valid(pdata->usbc_en2_gpio)) { - dev_err(card->dev, "%s, property %s not in node %s", - __func__, "qcom,usbc-analog-en2-gpio", - card->dev->of_node->full_name); + if (!pdata->fsa_handle) return false; - } - - en2_pinctrl_active = pinctrl_lookup_state( - pdata->usbc_en2_gpio_p, "aud_active"); - if (IS_ERR_OR_NULL(en2_pinctrl_active)) { - dev_err(card->dev, - "%s: Cannot get aud_active pinctrl state:%ld\n", - __func__, PTR_ERR(en2_pinctrl_active)); - ret = false; - goto err_lookup_state; - } - en2_pinctrl_sleep = pinctrl_lookup_state( - pdata->usbc_en2_gpio_p, "aud_sleep"); - if (IS_ERR_OR_NULL(en2_pinctrl_sleep)) { - dev_err(card->dev, - "%s: Cannot get aud_sleep pinctrl state:%ld\n", - __func__, PTR_ERR(en2_pinctrl_sleep)); - ret = false; - goto err_lookup_state; - } - - /* if active and usbc_en2_gpio_p defined, swap using usbc_en2_gpio_p */ - if (active) { - dev_dbg(codec->dev, "%s: enter\n", __func__); - if (pdata->usbc_en2_gpio_p) { - value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); - if (value) - pinctrl_select_state(pdata->usbc_en2_gpio_p, - en2_pinctrl_sleep); - else - pinctrl_select_state(pdata->usbc_en2_gpio_p, - en2_pinctrl_active); - } else if (pdata->usbc_en2_gpio >= 0) { - value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); - gpio_set_value_cansleep(pdata->usbc_en2_gpio, !value); - } - pr_debug("%s: swap select switch %d to %d\n", __func__, - value, !value); - ret = true; - } else { - /* if not active, release usbc_en2_gpio_p pin */ - pinctrl_select_state(pdata->usbc_en2_gpio_p, - en2_pinctrl_sleep); - } - -err_lookup_state: - devm_pinctrl_put(pdata->usbc_en2_gpio_p); - pdata->usbc_en2_gpio_p = NULL; - return ret; + return fsa4480_switch_event(pdata->fsa_handle, FSA_MIC_GND_SWAP); } static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) @@ -8459,6 +8387,18 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) "qcom,us-euro-gpios"); wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; } + + if (wcd_mbhc_cfg.enable_usbc_analog) { + wcd_mbhc_cfg.swap_gnd_mic = msm_usbc_swap_gnd_mic; + + pdata->fsa_handle = of_parse_phandle(pdev->dev.of_node, + "fsa4480-i2c-handle", 0); + if (!pdata->fsa_handle) + dev_err(&pdev->dev, + "property %s not detected in node %s\n", + "fsa4480-i2c-handle", + pdev->dev.of_node->full_name); + } /* Parse pinctrl info from devicetree */ ret = msm_get_pinctrl(pdev); if (!ret) { -- GitLab From 1c9ae8ff7638cf213507c8ca3c73726dc419a449 Mon Sep 17 00:00:00 2001 From: Aniket Kumar Lata Date: Wed, 10 Oct 2018 18:22:04 -0700 Subject: [PATCH 0596/1645] dsp: Fix port media type sample rate for APTX AD Send sample rate for port media type from APTX AD config before AFE port start. Change-Id: I3410428661ad4162539f437bb391c33a60ea1852 Signed-off-by: Aniket Kumar Lata --- dsp/q6afe.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 6697208e6616..57376cbcaf40 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -3790,6 +3790,9 @@ static int q6afe_send_enc_config(u16 port_id, if (format == ASM_MEDIA_FMT_LDAC) media_type.sample_rate = cfg->ldac_config.custom_config.sample_rate; + else if (format == ASM_MEDIA_FMT_APTX_ADAPTIVE) + media_type.sample_rate = + cfg->aptx_ad_config.custom_cfg.sample_rate; else media_type.sample_rate = afe_config.slim_sch.sample_rate; -- GitLab From e59d3158a0f24e08a7f6b5bc820479b7676dddab Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Wed, 10 Oct 2018 14:19:59 -0700 Subject: [PATCH 0597/1645] asoc: add limit checks for copp index Check the validity of copp index before calling adm_close. This avoids redundant error logs in adm_close. CRs-Fixed: 2330388 Change-Id: I0b1cef5a45298fe9cbc84d9b944f6f10cec562df Signed-off-by: Vignesh Kulothungan --- asoc/msm-pcm-routing-v2.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index ab07d7ec9bc0..66d6c9b36076 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1926,6 +1926,12 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) if (test_bit(idx, &copp)) break; + if (idx >= MAX_COPPS_PER_PORT) { + pr_debug("%s: copp idx is invalid, exiting\n", + __func__); + mutex_unlock(&routing_lock); + return; + } port_id = msm_bedais[reg].port_id; topology = adm_get_topology_for_port_copp_idx(port_id, idx); @@ -22872,6 +22878,12 @@ static int msm_pcm_routing_close(struct snd_pcm_substream *substream) for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) if (test_bit(idx, &copp)) break; + + if (idx >= MAX_COPPS_PER_PORT) { + pr_debug("%s: copp idx is invalid, exiting\n", + __func__); + continue; + } fdai->be_srate = bedai->sample_rate; port_id = bedai->port_id; topology = adm_get_topology_for_port_copp_idx(port_id, -- GitLab From 9c69ccfce6fb34d7fb02e443990ab2b82fa2953f Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 15 Oct 2018 12:21:06 -0700 Subject: [PATCH 0598/1645] dsp: msm_audio_ion: unmap dma only if unmap kernel succeeds If buf unmap is executed without successful kernel unmap the vmap counter mismatches. Check for error scenarios in kernel unmap function and ignore buf unmap if not necessary. Change-Id: I3c5835dcdfe05db4baaa5cf904995ed8f89e9cfe Signed-off-by: Karthikeyan Mani --- dsp/msm_audio_ion.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index 5a80916c1f84..bf3ef1250ed4 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -279,7 +279,7 @@ static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf) return addr; } -static void msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf) +static int msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf) { int rc = 0; void *vaddr = NULL; @@ -304,6 +304,7 @@ static void msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf) dev_err(cb_dev, "%s: cannot find allocation for dma_buf %pK", __func__, dma_buf); + rc = -EINVAL; goto err; } @@ -317,7 +318,7 @@ static void msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf) } err: - return; + return rc; } static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr, @@ -489,12 +490,16 @@ EXPORT_SYMBOL(msm_audio_ion_import); */ int msm_audio_ion_free(struct dma_buf *dma_buf) { + int ret = 0; + if (!dma_buf) { pr_err("%s: dma_buf invalid\n", __func__); return -EINVAL; } - msm_audio_ion_unmap_kernel(dma_buf); + ret = msm_audio_ion_unmap_kernel(dma_buf); + if (ret) + return ret; msm_audio_dma_buf_unmap(dma_buf); -- GitLab From e71ecf6efedd671fdeff8034ae1a34a69d73bdfd Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Fri, 28 Sep 2018 18:44:48 -0700 Subject: [PATCH 0599/1645] ASoC: msm: add tdm clk ref count Add TDM clock reference count as LPASS CLK API should only be controlled once per TDM interface. Change-Id: I025dc7cce3f1ccfe3b9d0ed652b71773f90d5c6f Signed-off-by: Derek Chen --- asoc/msm-dai-q6-v2.c | 52 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index fccac2802a2f..74a4057b8f74 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -368,6 +368,33 @@ static struct afe_clk_set tdm_clk_set = { 0, }; +static int msm_dai_q6_get_tdm_clk_ref(u16 id) +{ + switch (id) { + case IDX_GROUP_PRIMARY_TDM_RX: + case IDX_GROUP_PRIMARY_TDM_TX: + return atomic_read(&tdm_group_ref[IDX_GROUP_PRIMARY_TDM_RX]) + + atomic_read(&tdm_group_ref[IDX_GROUP_PRIMARY_TDM_TX]); + case IDX_GROUP_SECONDARY_TDM_RX: + case IDX_GROUP_SECONDARY_TDM_TX: + return atomic_read(&tdm_group_ref[IDX_GROUP_SECONDARY_TDM_RX]) + + atomic_read(&tdm_group_ref[IDX_GROUP_SECONDARY_TDM_TX]); + case IDX_GROUP_TERTIARY_TDM_RX: + case IDX_GROUP_TERTIARY_TDM_TX: + return atomic_read(&tdm_group_ref[IDX_GROUP_TERTIARY_TDM_RX]) + + atomic_read(&tdm_group_ref[IDX_GROUP_TERTIARY_TDM_TX]); + case IDX_GROUP_QUATERNARY_TDM_RX: + case IDX_GROUP_QUATERNARY_TDM_TX: + return atomic_read(&tdm_group_ref[IDX_GROUP_QUATERNARY_TDM_RX]) + + atomic_read(&tdm_group_ref[IDX_GROUP_QUATERNARY_TDM_TX]); + case IDX_GROUP_QUINARY_TDM_RX: + case IDX_GROUP_QUINARY_TDM_TX: + return atomic_read(&tdm_group_ref[IDX_GROUP_QUINARY_TDM_RX]) + + atomic_read(&tdm_group_ref[IDX_GROUP_QUINARY_TDM_TX]); + default: return -EINVAL; + } +} + int msm_dai_q6_get_group_idx(u16 id) { switch (id) { @@ -7344,6 +7371,9 @@ static int msm_dai_q6_dai_tdm_remove(struct snd_soc_dai *dai) dev_err(dai->dev, "fail to disable AFE group 0x%x\n", group_id); } + } + + if (msm_dai_q6_get_tdm_clk_ref(group_idx) == 0) { rc = msm_dai_q6_tdm_set_clk(tdm_dai_data, dai->id, false); if (rc < 0) { @@ -7862,17 +7892,11 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream, if (rc) dev_err(dai->dev, "%s: afe send island mode failed %d\n", __func__, rc); - } - /* PORT START should be set if prepare called - * in active state. - */ - if (atomic_read(group_ref) == 0) { - /* TX and RX share the same clk. - * AFE clk is enabled per group to simplify the logic. - * DSP will monitor the clk count. - */ + if (msm_dai_q6_get_tdm_clk_ref(group_idx) == 0) { + /* TX and RX share the same clk. So enable the clk + * per TDM interface. */ rc = msm_dai_q6_tdm_set_clk(dai_data, dai->id, true); if (rc < 0) { @@ -7880,7 +7904,12 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream, __func__, dai->id); goto rtn; } + } + /* PORT START should be set if prepare called + * in active state. + */ + if (atomic_read(group_ref) == 0) { /* * if only one port, don't do group enable as there * is no group need for only one port @@ -7903,6 +7932,8 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream, if (atomic_read(group_ref) == 0) { afe_port_group_enable(group_id, NULL, false); + } + if (msm_dai_q6_get_tdm_clk_ref(group_idx) == 0) { msm_dai_q6_tdm_set_clk(dai_data, dai->id, false); } @@ -7962,6 +7993,9 @@ static void msm_dai_q6_tdm_shutdown(struct snd_pcm_substream *substream, dev_err(dai->dev, "%s: fail to disable AFE group 0x%x\n", __func__, group_id); } + } + + if (msm_dai_q6_get_tdm_clk_ref(group_idx) == 0) { rc = msm_dai_q6_tdm_set_clk(dai_data, dai->id, false); if (rc < 0) { -- GitLab From 71699fd35fe98da49ae45fd812145206a457b4ca Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Tue, 16 Oct 2018 11:32:47 -0700 Subject: [PATCH 0600/1645] ipc: wcd-dsp-glink: increase timeout to 2 seconds There seems to be a delay in processing WDSP open commands on APPS side. Sometimes it is taking more than 1 second, results error in wdsp channels initialization. Increase the timeout value to avoid channel connect failures. Change-Id: If46251f07763080729858dc612679ee10149f57b Signed-off-by: Vidyakumar Athota --- ipc/wcd-dsp-glink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipc/wcd-dsp-glink.c b/ipc/wcd-dsp-glink.c index 8c89418cc90a..79ff26aef65a 100644 --- a/ipc/wcd-dsp-glink.c +++ b/ipc/wcd-dsp-glink.c @@ -33,7 +33,7 @@ #define MINOR_NUMBER_COUNT 1 #define RESP_QUEUE_SIZE 3 -#define TIMEOUT_MS 1000 +#define TIMEOUT_MS 2000 enum wdsp_ch_state { WDSP_CH_DISCONNECTED, -- GitLab From e23066df2a61036c5a9fe0b7ebbf00108f2162a5 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Mon, 15 Oct 2018 17:52:48 +0530 Subject: [PATCH 0601/1645] asoc: wcd937x: initialize micb lock mutex Micb lock which is used to synchronize micbias control api is not initialized causing spin lock errors. Initialize the mutex to avoid the issue. Change-Id: I580e52e1bd225c2d99bfba4657d80670296709a0 Signed-off-by: Ramprasad Katkam --- asoc/codecs/wcd937x/wcd937x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index db9f2be4876b..864aedab94ff 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -2324,6 +2324,7 @@ static int wcd937x_bind(struct device *dev) } wcd937x->tx_swr_dev->slave_irq = wcd937x->virq; + mutex_init(&wcd937x->micb_lock); ret = snd_soc_register_codec(dev, &soc_codec_dev_wcd937x, NULL, 0); if (ret) { @@ -2347,6 +2348,7 @@ static void wcd937x_unbind(struct device *dev) wcd_irq_exit(&wcd937x->irq_info, wcd937x->virq); snd_soc_unregister_codec(dev); component_unbind_all(dev, wcd937x); + mutex_destroy(&wcd937x->micb_lock); } static const struct of_device_id wcd937x_dt_match[] = { -- GitLab From d7a6390344ad7f0f2aad1f5d6b7b55accf5761ff Mon Sep 17 00:00:00 2001 From: Tanya Dixit Date: Wed, 17 Oct 2018 17:20:04 +0530 Subject: [PATCH 0602/1645] soc: Add proper null check for client array pointer Check if snd event client array is null before dereferencing. CRs-Fixed: 2328286 Change-Id: I4f7c2a1288ee27df51609e090cb2da2d33624a07 Signed-off-by: Tanya Dixit --- soc/snd_event.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/soc/snd_event.c b/soc/snd_event.c index 32407742b2a2..f8bffb81c2e4 100644 --- a/soc/snd_event.c +++ b/soc/snd_event.c @@ -301,6 +301,10 @@ void snd_event_mstr_add_client(struct snd_event_clients **snd_clients, } client->cl_arr = kzalloc(sizeof(struct snd_event_client_array), GFP_KERNEL); + if (!client->cl_arr) { + *snd_clients = ERR_PTR(-ENOMEM); + return; + } *snd_clients = client; } else { struct snd_event_client_array *new; -- GitLab From 6bce2e73746852f2e55cb46aed830f747fa98c45 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 10 Oct 2018 19:20:13 +0530 Subject: [PATCH 0603/1645] soc: swr-mstr: synchronize swr clock requests synchronize swr clock request using mutex and ensure count becomes zero during ssr. Change-Id: I3aa933a137d9439742d84fc23b37653da86f3b42 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 34 +++++++++++++++++++++++++++++++--- soc/swr-mstr-ctrl.h | 2 ++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 0cda6e8c8dc1..fa31bbfc693d 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -231,21 +231,37 @@ static const struct file_operations swrm_debug_ops = { static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) { + int ret = 0; + if (!swrm->clk || !swrm->handle) return -EINVAL; + mutex_lock(&swrm->clklock); if (enable) { + if (!swrm->dev_up) + goto exit; swrm->clk_ref_count++; if (swrm->clk_ref_count == 1) { - swrm->clk(swrm->handle, true); + ret = swrm->clk(swrm->handle, true); + if (ret) { + dev_err(swrm->dev, + "%s: clock enable req failed", + __func__); + --swrm->clk_ref_count; + } } } else if (--swrm->clk_ref_count == 0) { swrm->clk(swrm->handle, false); - } else if (swrm->clk_ref_count < 0) { + complete(&swrm->clk_off_complete); + } + if (swrm->clk_ref_count < 0) { pr_err("%s: swrm clk count mismatch\n", __func__); swrm->clk_ref_count = 0; } - return 0; + +exit: + mutex_unlock(&swrm->clklock); + return ret; } static int swrm_ahb_write(struct swr_mstr_ctrl *swrm, @@ -1723,10 +1739,12 @@ static int swrm_probe(struct platform_device *pdev) swrm->state = SWR_MSTR_UP; init_completion(&swrm->reset); init_completion(&swrm->broadcast); + init_completion(&swrm->clk_off_complete); mutex_init(&swrm->mlock); mutex_init(&swrm->reslock); mutex_init(&swrm->force_down_lock); mutex_init(&swrm->iolock); + mutex_init(&swrm->clklock); mutex_init(&swrm->devlock); for (i = 0 ; i < SWR_MSTR_PORT_LEN; i++) @@ -1845,6 +1863,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_destroy(&swrm->reslock); mutex_destroy(&swrm->force_down_lock); mutex_destroy(&swrm->iolock); + mutex_destroy(&swrm->clklock); err_pdata_fail: err_memory_fail: return ret; @@ -1865,6 +1884,8 @@ static int swrm_remove(struct platform_device *pdev) msm_aud_evt_unregister_client(&swrm->event_notifier); mutex_destroy(&swrm->mlock); mutex_destroy(&swrm->reslock); + mutex_destroy(&swrm->iolock); + mutex_destroy(&swrm->clklock); mutex_destroy(&swrm->force_down_lock); devm_kfree(&pdev->dev, swrm); return 0; @@ -2061,6 +2082,13 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) mutex_unlock(&swrm->reslock); break; case SWR_DEVICE_SSR_UP: + /* wait for clk voting to be zero */ + if (swrm->clk_ref_count && + !wait_for_completion_timeout(&swrm->clk_off_complete, + (1 * HZ/100))) + dev_err(swrm->dev, "%s: clock voting not zero\n", + __func__); + mutex_lock(&swrm->devlock); swrm->dev_up = true; mutex_unlock(&swrm->devlock); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index f9faed54ce50..4a40fa339e7e 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -110,8 +110,10 @@ struct swr_mstr_ctrl { struct resource *supplies; struct clk *mclk; int clk_ref_count; + struct completion clk_off_complete; struct completion reset; struct completion broadcast; + struct mutex clklock; struct mutex iolock; struct mutex devlock; struct mutex mlock; -- GitLab From 13e051c9abceae9efb86022690120af1f8abc82a Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Mon, 8 Oct 2018 16:38:06 +0530 Subject: [PATCH 0604/1645] soc: swr-mstr: Mask swrm debug interrupts Mask swrm debug interrupts as workaround for interrupt storm issue. Change-Id: Ic623a3a161d7d04812c4dd4b2e07a3331f5ed7ec Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 0cda6e8c8dc1..db8aec1b9fe6 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1522,7 +1522,7 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) value[len++] = 0x1FFFD; reg[len] = SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN; - value[len++] = 0x1FFFD; + value[len++] = 0x1FDFD; swr_master_bulk_write(swrm, reg, value, len); -- GitLab From 6a3050d838273760ed2c8bef06ac1d15f1f41a3e Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 10 Oct 2018 02:08:00 +0530 Subject: [PATCH 0605/1645] soc: swr-mstr: Register for wakeup irq after disabling clk During clock stop, Register for lpass wakeup only after disabling the clock to avoid flooding of interrupts when master is turned on for pending slave irq. Change-Id: Ifbf604048d4972beb22b6286930193b83a2249e8 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 0cda6e8c8dc1..c7fe7d25861b 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1976,13 +1976,15 @@ static int swrm_runtime_suspend(struct device *dev) swrm_cmd_fifo_wr_cmd(swrm, 0x2, 0xF, 0xF, SWRS_SCP_CONTROL); usleep_range(100, 105); - if (swrm->wakeup_req) { - msm_aud_evt_blocking_notifier_call_chain( - SWR_WAKE_IRQ_REGISTER, (void *)swrm); - swrm->wakeup_triggered = false; - } } swrm_clk_request(swrm, false); + + if (swrm->clk_stop_mode0_supp && swrm->wakeup_req) { + msm_aud_evt_blocking_notifier_call_chain( + SWR_WAKE_IRQ_REGISTER, (void *)swrm); + swrm->wakeup_triggered = false; + } + } /* Retain SSR state until resume */ if (current_state != SWR_MSTR_SSR) -- GitLab From ab8eba871129d5434a0dea401b8eb6ed046b5d6f Mon Sep 17 00:00:00 2001 From: Tanya Dixit Date: Fri, 5 Oct 2018 15:07:37 +0530 Subject: [PATCH 0606/1645] asoc: codecs: Add proper NULL checks and initialize variables Add null checks and initialize unintialized variables in wsa macro, wcd937x and wcd937x_slave drivers. CRs-Fixed: 2328286 Change-Id: I76b8d262e42d2b06ece3a6ecba28ed26b13d4447 Signed-off-by: Tanya Dixit --- asoc/codecs/bolero/wsa-macro.c | 10 ++++++++++ asoc/codecs/wcd937x/wcd937x.c | 11 +++++++---- asoc/codecs/wcd937x/wcd937x_slave.c | 10 ++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 9a6dff35ea17..ec870add94b5 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -756,6 +756,11 @@ static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv, struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL); int ret = 0; + if (regmap == NULL) { + dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__); + return -EINVAL; + } + dev_dbg(wsa_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", __func__, mclk_enable, dapm, wsa_priv->wsa_mclk_users); @@ -2431,6 +2436,11 @@ static int wsa_swrm_clock(void *handle, bool enable) struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle; struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL); + if (regmap == NULL) { + dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__); + return -EINVAL; + } + mutex_lock(&wsa_priv->swr_clk_lock); dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n", diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index db9f2be4876b..b9ef7133ab4d 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -166,7 +166,7 @@ static int wcd937x_parse_port_mapping(struct device *dev, char *prop, u8 path) { u32 *dt_array, map_size, map_length; - u32 port_num, ch_mask, ch_rate, old_port_num = 0; + u32 port_num = 0, ch_mask, ch_rate, old_port_num = 0; u32 slave_port_type, master_port_type; u32 i, ch_iter = 0; int ret = 0; @@ -188,7 +188,8 @@ static int wcd937x_parse_port_mapping(struct device *dev, if (!of_find_property(dev->of_node, prop, &map_size)) { dev_err(dev, "missing port mapping prop %s\n", prop); - goto err_pdata_fail; + ret = -EINVAL; + goto err; } map_length = map_size / (NUM_SWRS_DT_PARAMS * sizeof(u32)); @@ -197,13 +198,14 @@ static int wcd937x_parse_port_mapping(struct device *dev, if (!dt_array) { ret = -ENOMEM; - goto err_pdata_fail; + goto err; } ret = of_property_read_u32_array(dev->of_node, prop, dt_array, NUM_SWRS_DT_PARAMS * map_length); if (ret) { dev_err(dev, "%s: Failed to read port mapping from prop %s\n", __func__, prop); + ret = -EINVAL; goto err_pdata_fail; } @@ -230,7 +232,8 @@ static int wcd937x_parse_port_mapping(struct device *dev, err_pdata_fail: kfree(dt_array); - return -EINVAL; +err: + return ret; } static int wcd937x_tx_connect_port(struct snd_soc_codec *codec, diff --git a/asoc/codecs/wcd937x/wcd937x_slave.c b/asoc/codecs/wcd937x/wcd937x_slave.c index 252504fe0f08..baab26fe6de3 100644 --- a/asoc/codecs/wcd937x/wcd937x_slave.c +++ b/asoc/codecs/wcd937x/wcd937x_slave.c @@ -31,6 +31,11 @@ static int wcd937x_slave_bind(struct device *dev, uint8_t devnum = 0; struct swr_device *pdev = to_swr_device(dev); + if (pdev == NULL) { + dev_err(dev, "%s: pdev is NULL\n", __func__); + return -EINVAL; + } + wcd937x_slave = devm_kzalloc(&pdev->dev, sizeof(struct wcd937x_slave_priv), GFP_KERNEL); if (!wcd937x_slave) @@ -59,6 +64,11 @@ static void wcd937x_slave_unbind(struct device *dev, struct wcd937x_slave_priv *wcd937x_slave = NULL; struct swr_device *pdev = to_swr_device(dev); + if (pdev == NULL) { + dev_err(dev, "%s: pdev is NULL\n", __func__); + return; + } + wcd937x_slave = swr_get_dev_data(pdev); if (!wcd937x_slave) { dev_err(&pdev->dev, "%s: wcd937x_slave is NULL\n", __func__); -- GitLab From c0cd19e0b60d6b984b8593a410c3e3caf1be46ab Mon Sep 17 00:00:00 2001 From: kunleiz Date: Thu, 18 Oct 2018 17:11:35 +0800 Subject: [PATCH 0607/1645] dsp: adm: change channel number for SMECNS_V2 module SMECNS_V2 module in COPreP topology doesn't support stereo input. Update channel number to mono for VPM_TX_VOICE_SMECNS_V2_COPP_TOPOLOGY, which contains SMECNS_V2 module. Change-Id: I04b971b41328f6a32bf0ff42b21496b49bb4140b Signed-off-by: Kunlei Zhang --- dsp/q6adm.c | 3 +++ include/dsp/apr_audio-v2.h | 1 + 2 files changed, 4 insertions(+) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 4e621a9d3915..b9c11ac6b4c3 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2833,6 +2833,9 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, (topology == VPM_TX_DM_RFECNS_COPP_TOPOLOGY)) rate = 16000; + if (topology == VPM_TX_VOICE_SMECNS_V2_COPP_TOPOLOGY) + channel_mode = 1; + /* * Routing driver reuses the same adm for streams with the same * app_type, sample_rate etc. diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index fe55341796df..ddcc101a3215 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -4892,6 +4892,7 @@ struct afe_param_id_lpass_core_shared_clk_cfg { #define COMPRESSED_PASSTHROUGH_DEFAULT_TOPOLOGY 0x0001076B #define COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY 0x00010774 #define VPM_TX_SM_ECNS_V2_COPP_TOPOLOGY 0x00010F89 +#define VPM_TX_VOICE_SMECNS_V2_COPP_TOPOLOGY 0x10000003 #define VPM_TX_DM_FLUENCE_COPP_TOPOLOGY 0x00010F72 #define VPM_TX_QMIC_FLUENCE_COPP_TOPOLOGY 0x00010F75 #define VPM_TX_DM_RFECNS_COPP_TOPOLOGY 0x00010F86 -- GitLab From 701e358482c58d2155a434a495bea4cf9c09cf14 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 15 Oct 2018 20:06:09 +0530 Subject: [PATCH 0608/1645] asoc: bolero: Fix gfmux access during SSR Avoid access of gfmux register during SSR/PDR. Reset the gfmux state to MCLK_MUX0 after SSR up event in rx macro. Change-Id: I2ac611049efd3ce9d03bc9dcd912f64887a23679 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc.c | 24 ++++++++++++++++-------- asoc/codecs/bolero/rx-macro.c | 21 +++++++++++++++++---- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 5001b7f26be3..d6a196b6c830 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -428,7 +428,7 @@ int bolero_request_clock(struct device *dev, u16 macro_id, { struct bolero_priv *priv; u16 mclk_mux0_macro, mclk_mux1_macro; - int ret = 0; + int ret = 0, ret1 = 0; if (!dev) { pr_err("%s: dev is null\n", __func__); @@ -468,24 +468,32 @@ int bolero_request_clock(struct device *dev, u16 macro_id, dev_err(dev, "%s: MCLK_MUX0 en failed for macro:%d mclk_mux0_macro:%d\n", __func__, macro_id, mclk_mux0_macro); - goto err; + /* + * for disable case, need to proceed still for mclk_mux1 + * counter to decrement + */ + if (enable) + goto err; } - ret = priv->macro_params[mclk_mux1_macro].mclk_fn( + /* + * need different return value as ret variable + * is used to track mclk_mux0 enable success or fail + */ + ret1 = priv->macro_params[mclk_mux1_macro].mclk_fn( priv->macro_params[mclk_mux1_macro].dev, enable); - if (ret < 0) { + if (ret1 < 0) dev_err(dev, "%s: MCLK_MUX1 %s failed for macro:%d, mclk_mux1_macro:%d\n", __func__, enable ? "enable" : "disable", macro_id, mclk_mux1_macro); + /* disable mclk_mux0 only if ret is success(0) */ + if (!ret) priv->macro_params[mclk_mux0_macro].mclk_fn( priv->macro_params[mclk_mux0_macro].dev, false); + if (enable && ret1) goto err; - } - priv->macro_params[mclk_mux0_macro].mclk_fn( - priv->macro_params[mclk_mux0_macro].dev, - false); break; case MCLK_MUX_MAX: default: diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 37cfefeea759..986375dec738 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -343,6 +343,7 @@ struct rx_macro_priv { int rx_mclk_cnt; bool is_native_on; bool is_ear_mode_on; + bool dev_up; u16 mclk_mux; struct mutex mclk_lock; struct mutex swr_clk_lock; @@ -1087,16 +1088,20 @@ static int rx_macro_mclk_ctrl(struct device *dev, bool enable) __func__); return ret; } - if (rx_priv->rx_mclk_cnt++ == 0) - iowrite32(0x1, rx_priv->rx_mclk_mode_muxsel); + if (rx_priv->rx_mclk_cnt++ == 0) { + if (rx_priv->dev_up) + iowrite32(0x1, rx_priv->rx_mclk_mode_muxsel); + } } else { if (rx_priv->rx_mclk_cnt <= 0) { dev_dbg(dev, "%s:rx mclk already disabled\n", __func__); rx_priv->rx_mclk_cnt = 0; return 0; } - if (--rx_priv->rx_mclk_cnt == 0) - iowrite32(0x0, rx_priv->rx_mclk_mode_muxsel); + if (--rx_priv->rx_mclk_cnt == 0) { + if (rx_priv->dev_up) + iowrite32(0x0, rx_priv->rx_mclk_mode_muxsel); + } clk_disable_unprepare(rx_priv->rx_npl_clk); clk_disable_unprepare(rx_priv->rx_core_clk); } @@ -1132,6 +1137,7 @@ static int rx_macro_event_handler(struct snd_soc_codec *codec, u16 event, rx_macro_wcd_clsh_imped_config(codec, data, false); break; case BOLERO_MACRO_EVT_SSR_DOWN: + rx_priv->dev_up = false; swrm_wcd_notify( rx_priv->swr_ctrl_data[0].rx_swr_pdev, SWR_DEVICE_SSR_DOWN, NULL); @@ -1140,6 +1146,12 @@ static int rx_macro_event_handler(struct snd_soc_codec *codec, u16 event, SWR_DEVICE_DOWN, NULL); break; case BOLERO_MACRO_EVT_SSR_UP: + rx_priv->dev_up = true; + /* enable&disable MCLK_MUX1 to reset GFMUX reg */ + bolero_request_clock(rx_priv->dev, + RX_MACRO, MCLK_MUX1, true); + bolero_request_clock(rx_priv->dev, + RX_MACRO, MCLK_MUX1, false); swrm_wcd_notify( rx_priv->swr_ctrl_data[0].rx_swr_pdev, SWR_DEVICE_SSR_UP, NULL); @@ -3028,6 +3040,7 @@ static int rx_macro_init(struct snd_soc_codec *codec) dev_err(rx_dev, "%s: failed to add snd_ctls\n", __func__); return ret; } + rx_priv->dev_up = true; snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF1 Playback"); snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF2 Playback"); snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF3 Playback"); -- GitLab From 86c45e0761e895ae622c22d5a0e619ae23c22f36 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Tue, 16 Oct 2018 19:31:51 +0530 Subject: [PATCH 0609/1645] soc: swr-mstr: Avoid race condition during device up During device up call from platform driver, if master is already up pm get_sync is currently skipped. However pm suspend can get called after this check. Hence do a pm get_sync even if master is already up to avoid race condition. Change-Id: I1779db3d65f58bda220d1ec07706e91745814c1f Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 3d1b080b6691..af5adac4992e 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1191,6 +1191,7 @@ static int swrm_disconnect_port(struct swr_master *master, if (!port_req) { dev_err(&master->dev, "%s:port not enabled : port %d\n", __func__, portinfo->port_id[i]); + mutex_unlock(&swrm->mlock); return -EINVAL; } port_req->req_ch &= ~portinfo->ch_en[i]; @@ -2108,29 +2109,20 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) case SWR_DEVICE_UP: dev_dbg(swrm->dev, "%s: swr master up called\n", __func__); mutex_lock(&swrm->mlock); + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); mutex_lock(&swrm->reslock); - if (swrm->state == SWR_MSTR_UP) { - dev_dbg(swrm->dev, "%s: SWR master is already UP: %d\n", - __func__, swrm->state); - list_for_each_entry(swr_dev, &mstr->devices, dev_list) - swr_reset_device(swr_dev); - } else { - pm_runtime_mark_last_busy(&pdev->dev); - mutex_unlock(&swrm->reslock); - pm_runtime_get_sync(&pdev->dev); - mutex_lock(&swrm->reslock); - list_for_each_entry(swr_dev, &mstr->devices, dev_list) { - ret = swr_reset_device(swr_dev); - if (ret) { - dev_err(swrm->dev, - "%s: failed to reset swr device %d\n", - __func__, swr_dev->dev_num); - swrm_clk_request(swrm, false); - } + list_for_each_entry(swr_dev, &mstr->devices, dev_list) { + ret = swr_reset_device(swr_dev); + if (ret) { + dev_err(swrm->dev, + "%s: failed to reset swr device %d\n", + __func__, swr_dev->dev_num); + swrm_clk_request(swrm, false); } - pm_runtime_mark_last_busy(&pdev->dev); - pm_runtime_put_autosuspend(&pdev->dev); } + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_put_autosuspend(&pdev->dev); mutex_unlock(&swrm->reslock); mutex_unlock(&swrm->mlock); break; -- GitLab From 833035127f91ae9e68b6c3b515acc316721f1035 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Thu, 11 Oct 2018 17:34:22 +0530 Subject: [PATCH 0610/1645] soc: swr-mstr: Change master interrupt to edge type Change master interrupt to edge type handling to avoid recurring interrupts during ssr. Add loop logic to handle concurrent edge type interrupts. Change-Id: I3c789a24c035a6a00b1a2f515aa5328546ad80a9 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index af5adac4992e..7747b3c3fc8e 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -42,6 +42,7 @@ #define SWR_INVALID_PARAM 0xFF +#define SWRM_INTERRUPT_STATUS_MASK 0x1FDFD /* pm runtime auto suspend timer in msecs */ static int auto_suspend_timer = SWR_AUTO_SUSPEND_DELAY * 1000; module_param(auto_suspend_timer, int, 0664); @@ -68,7 +69,7 @@ enum { #define FALSE 0 #define SWRM_MAX_PORT_REG 120 -#define SWRM_MAX_INIT_REG 10 +#define SWRM_MAX_INIT_REG 11 #define SWR_MSTR_MAX_REG_ADDR 0x1740 #define SWR_MSTR_START_REG_ADDR 0x00 @@ -1265,7 +1266,8 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) mutex_unlock(&swrm->reslock); intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); - intr_sts &= SWRM_INTERRUPT_STATUS_RMSK; + intr_sts &= SWRM_INTERRUPT_STATUS_MASK; +handle_irq: for (i = 0; i < SWRM_INTERRUPT_MAX; i++) { value = intr_sts & (1 << i); if (!value) @@ -1387,6 +1389,15 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) } swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, intr_sts); swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, 0x0); + + intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); + intr_sts &= SWRM_INTERRUPT_STATUS_MASK; + + if (intr_sts) { + dev_dbg(swrm->dev, "%s: new interrupt received\n", __func__); + goto handle_irq; + } + mutex_lock(&swrm->reslock); swrm_clk_request(swrm, false); mutex_unlock(&swrm->reslock); @@ -1527,9 +1538,12 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) reg[len] = SWRM_MCP_BUS_CTRL_ADDR; value[len++] = 0x2; - /* Set IRQ to LEVEL */ + /* Set IRQ to PULSE */ + reg[len] = SWRM_COMP_CFG_ADDR; + value[len++] = 0x02; + reg[len] = SWRM_COMP_CFG_ADDR; - value[len++] = 0x01; + value[len++] = 0x03; reg[len] = SWRM_INTERRUPT_CLEAR; value[len++] = 0xFFFFFFFF; @@ -1539,7 +1553,7 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) value[len++] = 0x1FFFD; reg[len] = SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN; - value[len++] = 0x1FDFD; + value[len++] = SWRM_INTERRUPT_STATUS_MASK; swr_master_bulk_write(swrm, reg, value, len); @@ -1788,7 +1802,7 @@ static int swrm_probe(struct platform_device *pdev) ret = request_threaded_irq(swrm->irq, NULL, swr_mstr_interrupt, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, "swr_master_irq", swrm); if (ret) { dev_err(swrm->dev, "%s: Failed to request irq %d\n", -- GitLab From d49fecb934723626f51aa576a4ed5ed4d5fbd99e Mon Sep 17 00:00:00 2001 From: Trinath Thammishetty Date: Fri, 17 Aug 2018 16:53:56 +0530 Subject: [PATCH 0611/1645] asoc: Add effects controls in loopback driver Add audio effects related controls in transcode loopback driver to support audio effects in hardware loopback usecase. Update transcode loopback driver to support configuration of DSP render window. Render window is used by DSP to take rendering decision. i.e whether input frame should be rendered, dropped or repeated. Change-Id: I09bb725d980b8051eae3a245584e2b66cd2af7ff Signed-off-by: Trinath Thammishetty --- asoc/msm-transcode-loopback-q6-v2.c | 282 +++++++++++++++++++++++++++- 1 file changed, 281 insertions(+), 1 deletion(-) diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index fb70f6cb7aa6..f44e87d44d57 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,7 @@ #include #include #include +#include #include "msm-pcm-routing-v2.h" #include "msm-qti-pp-config.h" @@ -50,10 +52,20 @@ static DEFINE_MUTEX(transcode_loopback_session_lock); +struct msm_transcode_audio_effects { + struct bass_boost_params bass_boost; + struct pbe_params pbe; + struct virtualizer_params virtualizer; + struct reverb_params reverb; + struct eq_params equalizer; + struct soft_volume_params volume; +}; + struct trans_loopback_pdata { struct snd_compr_stream *cstream[MSM_FRONTEND_DAI_MAX]; uint32_t master_gain; int perf_mode; + struct msm_transcode_audio_effects *audio_effects[MSM_FRONTEND_DAI_MAX]; }; struct loopback_stream { @@ -204,6 +216,13 @@ static int msm_transcode_loopback_open(struct snd_compr_stream *cstream) rtd = snd_pcm_substream_chip(cstream); pdata = snd_soc_platform_get_drvdata(rtd->platform); pdata->cstream[rtd->dai_link->id] = cstream; + pdata->audio_effects[rtd->dai_link->id] = + kzalloc(sizeof(struct msm_transcode_audio_effects), GFP_KERNEL); + + if (pdata->audio_effects[rtd->dai_link->id] == NULL) { + ret = -ENOMEM; + goto effect_error; + } mutex_lock(&trans->lock); if (trans->num_streams > LOOPBACK_SESSION_MAX_NUM_STREAMS) { @@ -250,6 +269,11 @@ static int msm_transcode_loopback_open(struct snd_compr_stream *cstream) exit: mutex_unlock(&trans->lock); + if ((pdata->audio_effects[rtd->dai_link->id] != NULL) && (ret < 0)) { + kfree(pdata->audio_effects[rtd->dai_link->id]); + pdata->audio_effects[rtd->dai_link->id] = NULL; + } +effect_error: return ret; } @@ -283,10 +307,18 @@ static int msm_transcode_loopback_free(struct snd_compr_stream *cstream) struct snd_compr_runtime *runtime = cstream->runtime; struct msm_transcode_loopback *trans = runtime->private_data; struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(cstream); + struct trans_loopback_pdata *pdata; int ret = 0; + pdata = snd_soc_platform_get_drvdata(rtd->platform); + mutex_lock(&trans->lock); + if (pdata->audio_effects[rtd->dai_link->id] != NULL) { + kfree(pdata->audio_effects[rtd->dai_link->id]); + pdata->audio_effects[rtd->dai_link->id] = NULL; + } + pr_debug("%s: Transcode loopback end:%d, streams %d\n", __func__, cstream->direction, trans->num_streams); trans->num_streams--; @@ -338,6 +370,39 @@ static int msm_transcode_loopback_trigger(struct snd_compr_stream *cstream, return 0; } +static int msm_transcode_set_render_window(struct audio_client *ac, + uint32_t ws_lsw, uint32_t ws_msw, + uint32_t we_lsw, uint32_t we_msw) +{ + int ret = -EINVAL; + struct asm_session_mtmx_strtr_param_window_v2_t asm_mtmx_strtr_window; + uint32_t param_id; + + pr_debug("%s, ws_lsw 0x%x ws_msw 0x%x we_lsw 0x%x we_msw 0x%x\n", + __func__, ws_lsw, ws_msw, we_lsw, we_msw); + + memset(&asm_mtmx_strtr_window, 0, + sizeof(struct asm_session_mtmx_strtr_param_window_v2_t)); + asm_mtmx_strtr_window.window_lsw = ws_lsw; + asm_mtmx_strtr_window.window_msw = ws_msw; + param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_START_V2; + ret = q6asm_send_mtmx_strtr_window(ac, &asm_mtmx_strtr_window, param_id); + if (ret) { + pr_err("%s, start window can't be set error %d\n", __func__, ret); + goto exit; + } + + asm_mtmx_strtr_window.window_lsw = we_lsw; + asm_mtmx_strtr_window.window_msw = we_msw; + param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_END_V2; + ret = q6asm_send_mtmx_strtr_window(ac, &asm_mtmx_strtr_window, param_id); + if (ret) + pr_err("%s, end window can't be set error %d\n", __func__, ret); + +exit: + return ret; +} + static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, struct snd_compr_params *codec_param) { @@ -512,6 +577,8 @@ static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream, { struct snd_soc_pcm_runtime *rtd; struct trans_loopback_pdata *pdata; + struct msm_transcode_loopback *prtd = NULL; + struct audio_client *ac = NULL; if (!metadata || !cstream) { pr_err("%s: Invalid arguments\n", __func__); @@ -521,6 +588,15 @@ static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream, rtd = snd_pcm_substream_chip(cstream); pdata = snd_soc_platform_get_drvdata(rtd->platform); + prtd = cstream->runtime->private_data; + + if (!prtd || !prtd->audio_client) { + pr_err("%s: prtd or audio client is NULL\n", __func__); + return -EINVAL; + } + + ac = prtd->audio_client; + switch (metadata->key) { case SNDRV_COMPRESS_LATENCY_MODE: { @@ -537,8 +613,17 @@ static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream, pdata->perf_mode = LEGACY_PCM_MODE; break; } - } break; + } + case SNDRV_COMPRESS_RENDER_WINDOW: + { + return msm_transcode_set_render_window( + ac, + metadata->value[0], + metadata->value[1], + metadata->value[2], + metadata->value[3]); + } default: pr_debug("%s: Unsupported metadata %d\n", __func__, metadata->key); @@ -852,6 +937,192 @@ static int msm_transcode_volume_get(struct snd_kcontrol *kcontrol, return 0; } +static int msm_transcode_audio_effects_config_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = MAX_PP_PARAMS_SZ; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0xFFFFFFFF; + return 0; +} + +static int msm_transcode_audio_effects_config_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + struct trans_loopback_pdata *pdata = (struct trans_loopback_pdata *) + snd_soc_component_get_drvdata(comp); + struct msm_transcode_audio_effects *audio_effects = NULL; + struct snd_compr_stream *cstream = NULL; + + pr_debug("%s: fe_id: %lu\n", __func__, fe_id); + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bounds fe_id %lu\n", + __func__, fe_id); + return -EINVAL; + } + cstream = pdata->cstream[fe_id]; + audio_effects = pdata->audio_effects[fe_id]; + if (!cstream || !audio_effects) { + pr_err("%s: stream or effects inactive\n", __func__); + return -EINVAL; + } + + return 0; +} + +static int msm_transcode_audio_effects_config_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + unsigned long fe_id = kcontrol->private_value; + struct trans_loopback_pdata *pdata = (struct trans_loopback_pdata *) + snd_soc_component_get_drvdata(comp); + struct msm_transcode_audio_effects *audio_effects = NULL; + struct snd_compr_stream *cstream = NULL; + struct msm_transcode_loopback *prtd = NULL; + long *values = &(ucontrol->value.integer.value[0]); + int effects_module; + int ret = 0; + + pr_debug("%s: fe_id: %lu\n", __func__, fe_id); + if (fe_id >= MSM_FRONTEND_DAI_MAX) { + pr_err("%s Received out of bounds fe_id %lu\n", + __func__, fe_id); + ret = -EINVAL; + goto exit; + } + cstream = pdata->cstream[fe_id]; + audio_effects = pdata->audio_effects[fe_id]; + if (!cstream || !audio_effects) { + pr_err("%s: stream or effects inactive\n", __func__); + ret = -EINVAL; + goto exit; + } + prtd = cstream->runtime->private_data; + if (!prtd) { + pr_err("%s: cannot set audio effects\n", __func__); + ret = -EINVAL; + goto exit; + } + + effects_module = *values++; + switch (effects_module) { + case VIRTUALIZER_MODULE: + pr_debug("%s: VIRTUALIZER_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top(effects_module, + prtd->audio_client->topology)) + ret = msm_audio_effects_virtualizer_handler( + prtd->audio_client, + &(audio_effects->virtualizer), + values); + break; + case REVERB_MODULE: + pr_debug("%s: REVERB_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top(effects_module, + prtd->audio_client->topology)) + ret = msm_audio_effects_reverb_handler(prtd->audio_client, + &(audio_effects->reverb), + values); + break; + case BASS_BOOST_MODULE: + pr_debug("%s: BASS_BOOST_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top(effects_module, + prtd->audio_client->topology)) + ret = msm_audio_effects_bass_boost_handler(prtd->audio_client, + &(audio_effects->bass_boost), + values); + break; + case PBE_MODULE: + pr_debug("%s: PBE_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top(effects_module, + prtd->audio_client->topology)) + ret = msm_audio_effects_pbe_handler(prtd->audio_client, + &(audio_effects->pbe), + values); + break; + case EQ_MODULE: + pr_debug("%s: EQ_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top(effects_module, + prtd->audio_client->topology)) + ret = msm_audio_effects_popless_eq_handler(prtd->audio_client, + &(audio_effects->equalizer), + values); + break; + case SOFT_VOLUME_MODULE: + pr_debug("%s: SOFT_VOLUME_MODULE\n", __func__); + break; + case SOFT_VOLUME2_MODULE: + pr_debug("%s: SOFT_VOLUME2_MODULE\n", __func__); + if (msm_audio_effects_is_effmodule_supp_in_top(effects_module, + prtd->audio_client->topology)) + ret = msm_audio_effects_volume_handler_v2(prtd->audio_client, + &(audio_effects->volume), + values, SOFT_VOLUME_INSTANCE_2); + break; + default: + pr_err("%s Invalid effects config module\n", __func__); + ret = -EINVAL; + } + +exit: + return ret; +} + +static int msm_transcode_add_audio_effects_control(struct snd_soc_pcm_runtime *rtd) +{ + const char *mixer_ctl_name = "Audio Effects Config"; + const char *deviceNo = "NN"; + char *mixer_str = NULL; + int ctl_len = 0; + int ret = 0; + struct snd_kcontrol_new fe_audio_effects_config_control[1] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_transcode_audio_effects_config_info, + .get = msm_transcode_audio_effects_config_get, + .put = msm_transcode_audio_effects_config_put, + .private_value = 0, + } + }; + + if (!rtd) { + pr_err("%s NULL rtd\n", __func__); + ret = -EINVAL; + goto done; + } + + pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n", __func__, + rtd->dai_link->name, rtd->dai_link->id, + rtd->dai_link->cpu_dai_name, rtd->pcm->device); + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; + mixer_str = kzalloc(ctl_len, GFP_KERNEL); + + if (!mixer_str) { + ret = -ENOMEM; + goto done; + } + + snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device); + + fe_audio_effects_config_control[0].name = mixer_str; + fe_audio_effects_config_control[0].private_value = rtd->dai_link->id; + ret = snd_soc_add_platform_controls(rtd->platform, + fe_audio_effects_config_control, + ARRAY_SIZE(fe_audio_effects_config_control)); + if (ret < 0) + pr_err("%s: failed to add ctl %s. err = %d\n", __func__, mixer_str, ret); + + kfree(mixer_str); +done: + return ret; +} + static int msm_transcode_stream_cmd_control( struct snd_soc_pcm_runtime *rtd) { @@ -1147,6 +1418,11 @@ static int msm_transcode_loopback_new(struct snd_soc_pcm_runtime *rtd) { int rc; + rc = msm_transcode_add_audio_effects_control(rtd); + if (rc) + pr_err("%s: Could not add Compr Audio Effects Control\n", + __func__); + rc = msm_transcode_stream_cmd_control(rtd); if (rc) pr_err("%s: ADSP Stream Cmd Control open failed\n", __func__); @@ -1192,6 +1468,7 @@ static struct snd_compr_ops msm_transcode_loopback_ops = { static int msm_transcode_loopback_probe(struct snd_soc_platform *platform) { struct trans_loopback_pdata *pdata = NULL; + int i; pr_debug("%s\n", __func__); pdata = (struct trans_loopback_pdata *) @@ -1201,6 +1478,9 @@ static int msm_transcode_loopback_probe(struct snd_soc_platform *platform) return -ENOMEM; pdata->perf_mode = LOW_LATENCY_PCM_MODE; + for (i = 0; i < MSM_FRONTEND_DAI_MAX; i++) + pdata->audio_effects[i] = NULL; + snd_soc_platform_set_drvdata(platform, pdata); return 0; } -- GitLab From dcab67c50473c2bc1c53c2d7b55b1c2ec94e15cc Mon Sep 17 00:00:00 2001 From: Hari Veerubhotla Date: Sun, 14 Oct 2018 17:08:35 +0530 Subject: [PATCH 0612/1645] Initial Android target definition for trinket. Change-Id: Ib55a9013b0fa5bcda0e5d2d17d1741e607a9c9b5 --- Android.mk | 4 ++-- asoc/Android.mk | 7 ++++++- asoc/Kbuild | 5 +++++ asoc/codecs/Android.mk | 6 +++++- asoc/codecs/Kbuild | 5 +++++ asoc/codecs/bolero/Android.mk | 4 ++-- asoc/codecs/bolero/Kbuild | 5 +++++ asoc/codecs/wcd934x/Android.mk | 4 ++-- asoc/codecs/wcd934x/Kbuild | 5 +++++ asoc/codecs/wcd937x/Android.mk | 4 ++-- asoc/codecs/wcd937x/Kbuild | 5 +++++ dsp/Android.mk | 4 ++-- dsp/Kbuild | 5 +++++ dsp/codecs/Android.mk | 4 ++-- dsp/codecs/Kbuild | 5 +++++ ipc/Android.mk | 4 ++-- ipc/Kbuild | 5 +++++ soc/Android.mk | 6 +++--- soc/Kbuild | 5 +++++ 19 files changed, 73 insertions(+), 19 deletions(-) diff --git a/Android.mk b/Android.mk index c515dc5ea006..d5be7c8da943 100644 --- a/Android.mk +++ b/Android.mk @@ -3,7 +3,7 @@ MY_LOCAL_PATH := $(call my-dir) UAPI_OUT := $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/include -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) $(shell mkdir -p $(UAPI_OUT)/linux;) $(shell mkdir -p $(UAPI_OUT)/sound;) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers) @@ -29,7 +29,7 @@ $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codec include $(MY_LOCAL_PATH)/asoc/codecs/aqt1000/Android.mk endif -ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE)),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/bolero/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/bolero/Android.mk $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd937x/Module.symvers) diff --git a/asoc/Android.mk b/asoc/Android.mk index 8ca497c3c376..ae00ed72ae3d 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -23,9 +23,14 @@ TARGET := talos AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif +ifeq ($(call is-board-platform,$(TRINKET)),true) +TARGET := trinket +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/Kbuild b/asoc/Kbuild index d0cbef55ba2e..2481e5b922eb 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -39,6 +39,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_TRINKET), y) + include $(AUDIO_ROOT)/config/sm6150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index cbe1615b2b29..c6c8a443a39b 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -19,9 +19,13 @@ ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif +ifeq ($(call is-board-platform,$(TRINKET)),true) +AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index ade1e477a0b8..3e5fc12e71e6 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -39,6 +39,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_TRINKET), y) + include $(AUDIO_ROOT)/config/sm6150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/asoc/codecs/bolero/Android.mk b/asoc/codecs/bolero/Android.mk index 7b28789535c0..e858207320f9 100644 --- a/asoc/codecs/bolero/Android.mk +++ b/asoc/codecs/bolero/Android.mk @@ -3,13 +3,13 @@ # Assume no targets will be supported # Check if this driver needs be built for current target -ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE)),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild index d6c2eea3ec8d..dfb7596a35d0 100644 --- a/asoc/codecs/bolero/Kbuild +++ b/asoc/codecs/bolero/Kbuild @@ -21,6 +21,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_TRINKET), y) + include $(AUDIO_ROOT)/config/sm6150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + endif ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf export diff --git a/asoc/codecs/wcd934x/Android.mk b/asoc/codecs/wcd934x/Android.mk index 90a012dbab1f..3b5ef2fa175d 100644 --- a/asoc/codecs/wcd934x/Android.mk +++ b/asoc/codecs/wcd934x/Android.mk @@ -11,7 +11,7 @@ ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif -ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif @@ -21,7 +21,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index 26d9af61fa9e..e6427cfba4c7 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -36,6 +36,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_TRINKET), y) + include $(AUDIO_ROOT)/config/sm6150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/asoc/codecs/wcd937x/Android.mk b/asoc/codecs/wcd937x/Android.mk index 51c4bc00f0b1..fa544664a418 100644 --- a/asoc/codecs/wcd937x/Android.mk +++ b/asoc/codecs/wcd937x/Android.mk @@ -3,13 +3,13 @@ # Assume no targets will be supported # Check if this driver needs be built for current target -ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wcd937x/Kbuild b/asoc/codecs/wcd937x/Kbuild index c3d8e38c3844..48d333035b20 100644 --- a/asoc/codecs/wcd937x/Kbuild +++ b/asoc/codecs/wcd937x/Kbuild @@ -21,6 +21,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_TRINKET), y) + include $(AUDIO_ROOT)/config/sm6150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/dsp/Android.mk b/dsp/Android.mk index 23c0cc9669e3..310bd01f104f 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -15,13 +15,13 @@ ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif -ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/Kbuild b/dsp/Kbuild index 7081ceb0d246..11db9d57b061 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -34,6 +34,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_TRINKET), y) + include $(AUDIO_ROOT)/config/sm6150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/dsp/codecs/Android.mk b/dsp/codecs/Android.mk index 0c969dbafc50..0e22e03a8cd8 100644 --- a/dsp/codecs/Android.mk +++ b/dsp/codecs/Android.mk @@ -15,13 +15,13 @@ ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif -ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 0f1f519f4137..34e3b720baf1 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -35,6 +35,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_TRINKET), y) + include $(AUDIO_ROOT)/config/sm6150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/ipc/Android.mk b/ipc/Android.mk index 942a1866a0db..18dbedf7b60a 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -15,13 +15,13 @@ ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif -ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) diff --git a/ipc/Kbuild b/ipc/Kbuild index 0c77ed8c95aa..4e2d54bd7183 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -35,6 +35,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_TRINKET), y) + include $(AUDIO_ROOT)/config/sm6150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/soc/Android.mk b/soc/Android.mk index 3b43dc19cdd0..65770ba66d8b 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -15,13 +15,13 @@ ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif -ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE)),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) @@ -48,7 +48,7 @@ KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) KBUILD_OPTIONS += $(AUDIO_SELECT) ########################################################### -ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605 $(MSMSTEPPE)),true) +ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605 $(MSMSTEPPE) $(TRINKET)),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_lpi.ko LOCAL_MODULE_KBUILD_NAME := pinctrl_lpi_dlkm.ko diff --git a/soc/Kbuild b/soc/Kbuild index 933bf20cf0cb..29306ceaac24 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -39,6 +39,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_TRINKET), y) + include $(AUDIO_ROOT)/config/sm6150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export -- GitLab From 18bc8e228a613cb0991687b6f1b6f7f8fe4e0025 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Thu, 25 Oct 2018 15:04:24 +0530 Subject: [PATCH 0613/1645] soc: swr-mstr: suppress continuous warning interrupts Some warning interrupts keep flooding as long as data path is enabled. Disable the interrupt after the first interrupt to avoid flooding, and reenable for new data path. Change-Id: Ie4cd447be908ab40568fa24d6111d8a1f0483ee4 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 7747b3c3fc8e..80dd5e8d3f76 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -992,6 +992,8 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) mutex_unlock(&swrm->mlock); return -EINVAL; } + swr_master_write(swrm, SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN, + SWRM_INTERRUPT_STATUS_MASK); /* apply the new port config*/ swrm_apply_port_config(master); } else { @@ -1252,7 +1254,7 @@ static int swrm_check_slave_change_status(struct swr_mstr_ctrl *swrm, static irqreturn_t swr_mstr_interrupt(int irq, void *dev) { struct swr_mstr_ctrl *swrm = dev; - u32 value, intr_sts; + u32 value, intr_sts, intr_mask; u32 temp = 0; u32 status, chg_sts, i; u8 devnum = 0; @@ -1266,7 +1268,8 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) mutex_unlock(&swrm->reslock); intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); - intr_sts &= SWRM_INTERRUPT_STATUS_MASK; + intr_mask = swr_master_read(swrm, SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN); + intr_sts &= intr_mask; handle_irq: for (i = 0; i < SWRM_INTERRUPT_MAX; i++) { value = intr_sts & (1 << i); @@ -1279,8 +1282,8 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) status = swr_master_read(swrm, SWRM_MCP_SLV_STATUS); ret = swrm_find_alert_slave(swrm, status, &devnum); if (ret) { - dev_err(swrm->dev, "no slave alert found.\ - spurious interrupt\n"); + dev_err_ratelimited(swrm->dev, + "no slave alert found.spurious interrupt\n"); break; } swrm_cmd_fifo_rd_cmd(swrm, &temp, devnum, 0x0, @@ -1360,10 +1363,17 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) swr_master_write(swrm, SWRM_CMD_FIFO_CMD, 0x1); break; case SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION: - dev_dbg(swrm->dev, "SWR Port collision detected\n"); + dev_err_ratelimited(swrm->dev, "SWR Port collision detected\n"); + intr_mask &= ~SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION; + swr_master_write(swrm, + SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN, intr_mask); break; case SWRM_INTERRUPT_STATUS_READ_EN_RD_VALID_MISMATCH: dev_dbg(swrm->dev, "SWR read enable valid mismatch\n"); + intr_mask &= + ~SWRM_INTERRUPT_STATUS_READ_EN_RD_VALID_MISMATCH; + swr_master_write(swrm, + SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN, intr_mask); break; case SWRM_INTERRUPT_STATUS_SPECIAL_CMD_ID_FINISHED: complete(&swrm->broadcast); @@ -1391,7 +1401,7 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, 0x0); intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); - intr_sts &= SWRM_INTERRUPT_STATUS_MASK; + intr_sts &= intr_mask; if (intr_sts) { dev_dbg(swrm->dev, "%s: new interrupt received\n", __func__); -- GitLab From 41de9e1640c2921dd656a77ac10093e0540eccb0 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Tue, 16 Oct 2018 15:12:47 +0800 Subject: [PATCH 0614/1645] dsp: afe: change lock sequence to avoid deadlock Lock sequence for afe_alloc_cal does not comply with others. To avoid deadlock, move afe_cmd_lock to the top caller in AFE. Change-Id: I4ce03034c642c8b5e7e9e5e2ff4c73644980484b Signed-off-by: Xiaojun Sang --- dsp/q6afe.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index da8dc5a8033a..f71d72b810b0 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -7408,14 +7408,17 @@ int afe_alloc_cal(int32_t cal_type, size_t data_size, goto done; } + mutex_lock(&this_afe.afe_cmd_lock); ret = cal_utils_alloc_cal(data_size, data, this_afe.cal_data[cal_index], 0, NULL); if (ret < 0) { pr_err("%s: cal_utils_alloc_block failed, ret = %d, cal type = %d!\n", __func__, ret, cal_type); ret = -EINVAL; + mutex_unlock(&this_afe.afe_cmd_lock); goto done; } + mutex_unlock(&this_afe.afe_cmd_lock); done: return ret; } @@ -7799,8 +7802,6 @@ static int afe_map_cal_data(int32_t cal_type, goto done; } - - mutex_lock(&this_afe.afe_cmd_lock); atomic_set(&this_afe.mem_map_cal_index, cal_index); ret = afe_cmd_memory_map(cal_block->cal_data.paddr, cal_block->map_data.map_size); @@ -7813,12 +7814,10 @@ static int afe_map_cal_data(int32_t cal_type, __func__, &cal_block->cal_data.paddr, cal_block->map_data.map_size); - mutex_unlock(&this_afe.afe_cmd_lock); goto done; } cal_block->map_data.q6map_handle = atomic_read(&this_afe. mem_map_cal_handles[cal_index]); - mutex_unlock(&this_afe.afe_cmd_lock); done: return ret; } -- GitLab From 4e6bb44f611bb81201be4b10b4bc18115fdd2c33 Mon Sep 17 00:00:00 2001 From: Weiyin Jiang Date: Mon, 22 Oct 2018 16:40:10 +0800 Subject: [PATCH 0615/1645] ASoC: correct read size return value for erroneous conditions Wrong return value of in_read() causes integer overflow in omx, which aborts the process. Correct the return value for erroneous conditions. CRs-Fixed: 2336645 Change-Id: Ib01827adc92700876f3b11816857f0086b1b5f94 Signed-off-by: Weiyin Jiang --- dsp/codecs/audio_utils.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dsp/codecs/audio_utils.c b/dsp/codecs/audio_utils.c index 15ee9f51a7d8..e55967841fa6 100644 --- a/dsp/codecs/audio_utils.c +++ b/dsp/codecs/audio_utils.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -760,6 +760,10 @@ ssize_t audio_in_read(struct file *file, } bytes_to_copy = (size + audio->out_frame_info[idx][1]); + if (bytes_to_copy == 0) { + rc = 0; + break; + } /* Number of frames information copied */ buf += sizeof(unsigned char); count -= sizeof(unsigned char); @@ -793,8 +797,10 @@ ssize_t audio_in_read(struct file *file, pr_debug("%s:session id %d: read: %zd bytes\n", __func__, audio->ac->session, (buf-start)); - if (buf > start) - return buf - start; + if (!rc) { + if (buf > start) + return buf - start; + } return rc; } -- GitLab From f1b8d5bdea651cc8a633b67845d5565bd8608d4d Mon Sep 17 00:00:00 2001 From: Florian Pfister Date: Wed, 26 Sep 2018 15:45:18 +0200 Subject: [PATCH 0616/1645] dsp: add BT sink support in AFE driver Add different media format support in AFE decoder. Change-Id: Icdc3884882c34236f5ab02355dfbabdd2a1becd2 Signed-off-by: Florian Pfister Signed-off-by: Surendar Karka --- dsp/q6afe.c | 147 +++++++++++++++++++++++++++++++------ include/dsp/apr_audio-v2.h | 145 +++++++++++++++++++++++++++++++++++- 2 files changed, 268 insertions(+), 24 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index da8dc5a8033a..cbd87863f86b 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -3442,15 +3442,21 @@ int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) static int q6afe_send_dec_config(u16 port_id, union afe_port_config afe_config, - struct afe_dec_config *cfg) + struct afe_dec_config *cfg, + u32 format, + u16 afe_in_channels, u16 afe_in_bit_width) { + struct afe_dec_media_fmt_t dec_media_fmt; struct avs_dec_depacketizer_id_param_t dec_depkt_id_param; + struct avs_dec_congestion_buffer_param_t dec_buffer_id_param; struct afe_enc_dec_imc_info_param_t imc_info_param; struct afe_port_media_type_t media_type; struct param_hdr_v3 param_hdr; int ret; + u32 dec_fmt; memset(&dec_depkt_id_param, 0, sizeof(dec_depkt_id_param)); + memset(&dec_media_fmt, 0, sizeof(dec_media_fmt)); memset(&imc_info_param, 0, sizeof(imc_info_param)); memset(&media_type, 0, sizeof(media_type)); memset(¶m_hdr, 0, sizeof(param_hdr)); @@ -3463,10 +3469,10 @@ static int q6afe_send_dec_config(u16 port_id, param_hdr.param_id = AFE_DECODER_PARAM_ID_DEPACKETIZER_ID; param_hdr.param_size = sizeof(struct avs_dec_depacketizer_id_param_t); dec_depkt_id_param.dec_depacketizer_id = - AFE_MODULE_ID_DEPACKETIZER_COP; - if (cfg->format == ASM_MEDIA_FMT_APTX_ADAPTIVE) - dec_depkt_id_param.dec_depacketizer_id = AFE_MODULE_ID_DEPACKETIZER_COP_V1; + if (cfg->format == ENC_CODEC_TYPE_LDAC) + dec_depkt_id_param.dec_depacketizer_id = + AFE_MODULE_ID_DEPACKETIZER_COP; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, @@ -3477,19 +3483,52 @@ static int q6afe_send_dec_config(u16 port_id, goto exit; } - pr_debug("%s:sending AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION to DSP payload\n", - __func__); - param_hdr.param_id = AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION; - param_hdr.param_size = sizeof(struct afe_enc_dec_imc_info_param_t); - imc_info_param.imc_info = cfg->abr_dec_cfg.imc_info; - ret = q6afe_pack_and_set_param_in_band(port_id, - q6audio_get_port_index(port_id), - param_hdr, - (u8 *) &imc_info_param); - if (ret) { - pr_err("%s: AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION for port 0x%x failed %d\n", - __func__, port_id, ret); - goto exit; + switch (cfg->format) { + case ASM_MEDIA_FMT_SBC: + case ASM_MEDIA_FMT_AAC_V2: + case ASM_MEDIA_FMT_MP3: + if (port_id == SLIMBUS_9_TX) { + dec_buffer_id_param.max_nr_buffers = 200; + dec_buffer_id_param.pre_buffer_size = 200; + } else { + dec_buffer_id_param.max_nr_buffers = 0; + dec_buffer_id_param.pre_buffer_size = 0; + } + pr_debug("%s: sending AFE_DECODER_PARAM_ID_CONGESTION_BUFFER_SIZE to DSP payload\n", + __func__); + param_hdr.param_id = + AFE_DECODER_PARAM_ID_CONGESTION_BUFFER_SIZE; + param_hdr.param_size = + sizeof(struct avs_dec_congestion_buffer_param_t); + dec_buffer_id_param.version = 0; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &dec_buffer_id_param); + if (ret) { + pr_err("%s: AFE_DECODER_PARAM_ID_CONGESTION_BUFFER_SIZE for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + break; + default: + pr_debug("%s:sending AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION to DSP payload\n", + __func__); + param_hdr.param_id = + AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION; + param_hdr.param_size = + sizeof(struct afe_enc_dec_imc_info_param_t); + imc_info_param.imc_info = cfg->abr_dec_cfg.imc_info; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &imc_info_param); + if (ret) { + pr_err("%s: AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + break; } pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __func__); @@ -3497,9 +3536,24 @@ static int q6afe_send_dec_config(u16 port_id, param_hdr.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE; param_hdr.param_size = sizeof(struct afe_port_media_type_t); media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE; - media_type.sample_rate = afe_config.slim_sch.sample_rate; - media_type.bit_width = afe_config.slim_sch.bit_width; - media_type.num_channels = afe_config.slim_sch.num_channels; + switch (cfg->format) { + case ASM_MEDIA_FMT_AAC_V2: + media_type.sample_rate = + cfg->data.aac_config.sample_rate; + break; + default: + media_type.sample_rate = + afe_config.slim_sch.sample_rate; + } + if (afe_in_bit_width) + media_type.bit_width = afe_in_bit_width; + else + media_type.bit_width = afe_config.slim_sch.bit_width; + + if (afe_in_channels) + media_type.num_channels = afe_in_channels; + else + media_type.num_channels = afe_config.slim_sch.num_channels; media_type.data_format = AFE_PORT_DATA_FORMAT_PCM; media_type.reserved = 0; @@ -3512,6 +3566,50 @@ static int q6afe_send_dec_config(u16 port_id, goto exit; } + if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2) { + pr_debug("%s:Unsuppported dec format. Ignore AFE config %u\n", + __func__, format); + goto exit; + } + pr_debug("%s: sending AFE_DECODER_PARAM_ID_DEC_MEDIA_FMT to DSP payload\n", + __func__); + param_hdr.module_id = AFE_MODULE_ID_DECODER; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_DECODER_PARAM_ID_DEC_FMT_ID; + param_hdr.param_size = sizeof(dec_fmt); + dec_fmt = format; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &dec_fmt); + if (ret) { + pr_err("%s: AFE_DECODER_PARAM_ID_DEC_MEDIA_FMT for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + + switch (cfg->format) { + case ASM_MEDIA_FMT_AAC_V2: + param_hdr.param_size = sizeof(struct afe_dec_media_fmt_t); + + pr_debug("%s:send AFE_DECODER_PARAM_ID DEC_MEDIA_FMT to DSP payload\n", + __func__); + param_hdr.param_id = AVS_DECODER_PARAM_ID_DEC_MEDIA_FMT; + dec_media_fmt.dec_media_config = cfg->data; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &dec_media_fmt); + if (ret) { + pr_err("%s: AFE_DECODER_PARAM_ID DEC_MEDIA_FMT for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + break; + default: + pr_debug("%s:No need to send DEC_MEDIA_FMT to DSP payload\n", + __func__); + } + exit: return ret; } @@ -3550,7 +3648,8 @@ static int q6afe_send_enc_config(u16 port_id, format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD && format != ASM_MEDIA_FMT_CELT && format != ASM_MEDIA_FMT_LDAC && format != ASM_MEDIA_FMT_APTX_ADAPTIVE) { - pr_err("%s:Unsuppported format Ignore AFE config\n", __func__); + pr_err("%s:Unsuppported enc format. Ignore AFE config\n", + __func__); return 0; } @@ -3582,7 +3681,7 @@ static int q6afe_send_enc_config(u16 port_id, enc_blk_param.enc_cfg_blk_size = sizeof(union afe_enc_config_data); } - pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payloadn", + pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payload\n", __func__); param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK; enc_blk_param.enc_blk_config = *cfg; @@ -4064,7 +4163,9 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, pr_debug("%s: Found AFE decoder support for SLIMBUS format = %d\n", __func__, codec_format); ret = q6afe_send_dec_config(port_id, *afe_config, - dec_cfg); + dec_cfg, codec_format, + afe_in_channels, + afe_in_bit_width); if (ret) { pr_err("%s: AFE decoder config for port 0x%x failed %d\n", __func__, port_id, ret); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index ddcc101a3215..eb529dc1e8e6 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -3875,6 +3875,12 @@ struct afe_id_aptx_adaptive_enc_init */ #define AFE_ENCODER_PARAM_ID_ENC_FMT_ID 0x0001322B +/* + * Decoder format ID parameter for the #AVS_MODULE_ID_DECODER module. + * This parameter cannot be set runtime. + */ +#define AFE_DECODER_PARAM_ID_DEC_FMT_ID 0x00013234 + /* * Encoder scrambler parameter for the #AVS_MODULE_ID_ENCODER module. * This parameter cannot be set runtime. @@ -3915,6 +3921,12 @@ struct afe_id_aptx_adaptive_enc_init */ #define AFE_DECODER_PARAM_ID_DEPACKETIZER_ID 0x00013235 +/* + * Decoder buffer ID parameter for the #AVS_MODULE_ID_DECODER module. + * This parameter cannot be set runtime. + */ +#define AFE_DECODER_PARAM_ID_CONGESTION_BUFFER_SIZE 0x000132ec + /* * Data format to send compressed data * is transmitted/received over Slimbus lines. @@ -4185,6 +4197,7 @@ struct asm_celt_enc_cfg_t { } __packed; #define ASM_MEDIA_FMT_LDAC 0x00013224 +#define ENC_CODEC_TYPE_LDAC 0x23000000 struct asm_ldac_specific_enc_cfg_t { /* * This is used to calculate the encoder output @@ -4293,6 +4306,98 @@ struct afe_port_media_type_t { uint16_t reserved; } __packed; +/* + * Payload of the SBC decoder configuration parameters in the + * #ASM_MEDIA_FMT_SBC media format. + */ +struct asm_sbc_dec_cfg_t { + /* All configuration is extracted from the stream */ +} __packed; + +/* + * Payload of the MP3 decoder configuration parameters in the + * #ASM_MEDIA_FMT_MP3 media format. + */ +struct asm_mp3_dec_cfg_t { + /* All configuration is extracted from the stream */ +} __packed; + +struct asm_aac_dec_cfg_v2_t { + uint16_t aac_fmt_flag; + /* + * Bit stream format option. + * + * @values + * - #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_ADTS + * - #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_LOAS + * - #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_ADIF + * - #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_RAW + * - #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_LATM + */ + + uint16_t audio_obj_type; + /* + * Audio Object Type (AOT) present in the AAC stream. + * + * @values + * - #ASM_MEDIA_FMT_AAC_AOT_LC + * - #ASM_MEDIA_FMT_AAC_AOT_SBR + * - #ASM_MEDIA_FMT_AAC_AOT_BSAC + * - #ASM_MEDIA_FMT_AAC_AOT_PS + * + * Other values are not supported. + */ + + uint16_t channel_config; + /* + * Number of channels present in the AAC stream. + * + * @values + * - 0 -- PCE + * - 1 -- Mono + * - 2 -- Stereo + * - 6 -- 5.1 content + */ + + uint16_t total_size_of_PCE_bits; + /* + * For RAW formats and if channel_config=0 (PCE), + * the client can send the bit stream containing PCE + * immediately following this structure (in band). + * + * @values @ge 0 (does not include the bits required + * for 32-bit alignment) + * + * If this field is set to 0, the PCE information is + * assumed to be available in the audio bit stream + * and not in band. + * + * If this field is greater than 0, the PCE information + * follows this structure. Additional bits might + * be required for 32-bit alignment. + */ + + uint32_t sample_rate; + /* + * Number of samples per second. + * + * @values 8000, 11025, 12000, 16000, 22050, 24000, 32000, + * 44100, 48000, 64000, 88200, 96000 Hz + * + * This field must be equal to the sample rate of the + * AAC-LC decoder output. + * - For MP4 or 3GP containers, this sample rate + * is indicated by the + * samplingFrequencyIndex field in the + * AudioSpecificConfig element. + * - For ADTS format, this sample rate is indicated by the + * samplingFrequencyIndex in the ADTS fixed header. + * - For ADIF format, this sample rate is indicated by the + * samplingFrequencyIndex in the program_config_element + * present in the ADIF header. + */ +} __packed; + union afe_enc_config_data { struct asm_sbc_enc_cfg_t sbc_config; struct asm_aac_enc_cfg_v2_t aac_config; @@ -4309,9 +4414,16 @@ struct afe_enc_config { union afe_enc_config_data data; }; +union afe_dec_config_data { + struct asm_sbc_dec_cfg_t sbc_config; + struct asm_aac_dec_cfg_v2_t aac_config; + struct asm_mp3_dec_cfg_t mp3_config; +}; + struct afe_dec_config { u32 format; struct afe_abr_dec_cfg_t abr_dec_cfg; + union afe_dec_config_data data; }; struct afe_enc_cfg_blk_param_t { @@ -4322,6 +4434,14 @@ struct afe_enc_cfg_blk_param_t { union afe_enc_config_data enc_blk_config; }; +/* + * Payload of the AVS_DECODER_PARAM_ID_DEC_MEDIA_FMT parameter used by + * AVS_MODULE_ID_DECODER. + */ +struct afe_dec_media_fmt_t { + union afe_dec_config_data dec_media_config; +} __packed; + /* * Payload of the AVS_ENCODER_PARAM_ID_PACKETIZER_ID parameter. */ @@ -4373,12 +4493,34 @@ struct afe_enc_dec_imc_info_param_t { struct avs_dec_depacketizer_id_param_t { /* * Supported values: - * #AVS_MODULE_ID_DEPACKETIZER_COP + * #AFE_MODULE_ID_DEPACKETIZER_COP + * #AFE_MODULE_ID_DEPACKETIZER_COP_V1 * Any OpenDSP supported values */ uint32_t dec_depacketizer_id; }; +struct avs_dec_congestion_buffer_param_t { + uint32_t version; + uint16_t max_nr_buffers; + /* + * Maximum number of 1ms buffers: + * 0 - 256 + */ + uint16_t pre_buffer_size; + /* + * Pre-buffering size in 1ms: + * 1 - 128 + */ +}; + +/* + * ID of the parameter used by #AVS_MODULE_ID_DECODER to configure + * the decoder mode for the AFE module. + * This parameter cannot be set at runtime. + */ +#define AVS_DECODER_PARAM_ID_DEC_MEDIA_FMT 0x00013232 + /* ID of the parameter used by #AFE_MODULE_AUDIO_DEV_INTERFACE to configure * the island mode for a given AFE port. */ @@ -4492,6 +4634,7 @@ union afe_port_config { struct avs_enc_packetizer_id_param_t enc_pkt_id_param; struct avs_enc_set_scrambler_param_t enc_set_scrambler_param; struct avs_dec_depacketizer_id_param_t dec_depkt_id_param; + struct afe_dec_media_fmt_t dec_media_fmt; struct afe_enc_level_to_bitrate_map_param_t map_param; struct afe_enc_dec_imc_info_param_t imc_info_param; struct afe_param_id_cdc_dma_cfg_t cdc_dma; -- GitLab From 522073c3709741f227dcbe59ee131145bce3cc71 Mon Sep 17 00:00:00 2001 From: Florian Pfister Date: Wed, 26 Sep 2018 15:39:15 +0200 Subject: [PATCH 0617/1645] asoc: add A2DP sink support in dai-driver Add decoder config support for split A2DP sink. Change-Id: If71a2b2ae7f0f0500f196b0552ab185c9f37b778 Signed-off-by: Florian Pfister Signed-off-by: Surendar Karka --- asoc/msm-dai-q6-v2.c | 246 +++++++++++++++++++++++++++++++------- asoc/msm-pcm-routing-v2.c | 4 +- 2 files changed, 207 insertions(+), 43 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 74a4057b8f74..171337a613bb 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -52,12 +52,16 @@ enum { ENC_FMT_NONE, DEC_FMT_NONE = ENC_FMT_NONE, ENC_FMT_SBC = ASM_MEDIA_FMT_SBC, + DEC_FMT_SBC = ASM_MEDIA_FMT_SBC, ENC_FMT_AAC_V2 = ASM_MEDIA_FMT_AAC_V2, + DEC_FMT_AAC_V2 = ASM_MEDIA_FMT_AAC_V2, ENC_FMT_APTX = ASM_MEDIA_FMT_APTX, ENC_FMT_APTX_HD = ASM_MEDIA_FMT_APTX_HD, ENC_FMT_CELT = ASM_MEDIA_FMT_CELT, ENC_FMT_LDAC = ASM_MEDIA_FMT_LDAC, ENC_FMT_APTX_ADAPTIVE = ASM_MEDIA_FMT_APTX_ADAPTIVE, + DEC_FMT_APTX_ADAPTIVE = ASM_MEDIA_FMT_APTX_ADAPTIVE, + DEC_FMT_MP3 = ASM_MEDIA_FMT_MP3, }; enum { @@ -203,8 +207,10 @@ struct msm_dai_q6_dai_data { u32 channels; u32 bitwidth; u32 cal_mode; - u32 afe_in_channels; - u16 afe_in_bitformat; + u32 afe_rx_in_channels; + u16 afe_rx_in_bitformat; + u32 afe_tx_out_channels; + u16 afe_tx_out_bitformat; struct afe_enc_config enc_config; struct afe_dec_config dec_config; union afe_port_config port_config; @@ -2049,7 +2055,7 @@ static int msm_dai_q6_prepare(struct snd_pcm_substream *substream, if (dai_data->enc_config.format != ENC_FMT_NONE) { int bitwidth = 0; - switch (dai_data->afe_in_bitformat) { + switch (dai_data->afe_rx_in_bitformat) { case SNDRV_PCM_FORMAT_S32_LE: bitwidth = 32; break; @@ -2065,26 +2071,41 @@ static int msm_dai_q6_prepare(struct snd_pcm_substream *substream, __func__, dai_data->enc_config.format); rc = afe_port_start_v2(dai->id, &dai_data->port_config, dai_data->rate, - dai_data->afe_in_channels, + dai_data->afe_rx_in_channels, bitwidth, &dai_data->enc_config, NULL); if (rc < 0) pr_err("%s: afe_port_start_v2 failed error: %d\n", __func__, rc); } else if (dai_data->dec_config.format != DEC_FMT_NONE) { + int bitwidth = 0; + /* - * A dummy Tx session is established in LPASS to - * get the link statistics from BTSoC. - * Depacketizer extracts the bit rate levels and - * transmits them to the encoder on the Rx path. - * Since this is a dummy decoder - channels, bit - * width are sent as 0 and encoder config is NULL. - * This could be updated in the future if there is - * a complete Tx path set up that uses this decoder. + * If bitwidth is not configured set default value to + * zero, so that decoder port config uses slim device + * bit width value in afe decoder config. */ + switch (dai_data->afe_tx_out_bitformat) { + case SNDRV_PCM_FORMAT_S32_LE: + bitwidth = 32; + break; + case SNDRV_PCM_FORMAT_S24_LE: + bitwidth = 24; + break; + case SNDRV_PCM_FORMAT_S16_LE: + bitwidth = 16; + break; + default: + bitwidth = 0; + break; + } + pr_debug("%s: calling AFE_PORT_START_V2 with dec format: %d\n", + __func__, dai_data->dec_config.format); rc = afe_port_start_v2(dai->id, &dai_data->port_config, - dai_data->rate, 0, 0, NULL, - &dai_data->dec_config); + dai_data->rate, + dai_data->afe_tx_out_channels, + bitwidth, + NULL, &dai_data->dec_config); if (rc < 0) { pr_err("%s: fail to open AFE port 0x%x\n", __func__, dai->id); @@ -2902,17 +2923,17 @@ static int msm_dai_q6_afe_enc_cfg_put(struct snd_kcontrol *kcontrol, return ret; } -static const char *const afe_input_chs_text[] = {"Zero", "One", "Two"}; +static const char *const afe_chs_text[] = {"Zero", "One", "Two"}; -static const struct soc_enum afe_input_chs_enum[] = { - SOC_ENUM_SINGLE_EXT(3, afe_input_chs_text), +static const struct soc_enum afe_chs_enum[] = { + SOC_ENUM_SINGLE_EXT(3, afe_chs_text), }; -static const char *const afe_input_bit_format_text[] = {"S16_LE", "S24_LE", +static const char *const afe_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; -static const struct soc_enum afe_input_bit_format_enum[] = { - SOC_ENUM_SINGLE_EXT(3, afe_input_bit_format_text), +static const struct soc_enum afe_bit_format_enum[] = { + SOC_ENUM_SINGLE_EXT(3, afe_bit_format_text), }; static int msm_dai_q6_afe_input_channel_get(struct snd_kcontrol *kcontrol, @@ -2921,9 +2942,9 @@ static int msm_dai_q6_afe_input_channel_get(struct snd_kcontrol *kcontrol, struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; if (dai_data) { - ucontrol->value.integer.value[0] = dai_data->afe_in_channels; + ucontrol->value.integer.value[0] = dai_data->afe_rx_in_channels; pr_debug("%s:afe input channel = %d\n", - __func__, dai_data->afe_in_channels); + __func__, dai_data->afe_rx_in_channels); } return 0; @@ -2935,9 +2956,9 @@ static int msm_dai_q6_afe_input_channel_put(struct snd_kcontrol *kcontrol, struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; if (dai_data) { - dai_data->afe_in_channels = ucontrol->value.integer.value[0]; + dai_data->afe_rx_in_channels = ucontrol->value.integer.value[0]; pr_debug("%s: updating afe input channel : %d\n", - __func__, dai_data->afe_in_channels); + __func__, dai_data->afe_rx_in_channels); } return 0; @@ -2954,7 +2975,7 @@ static int msm_dai_q6_afe_input_bit_format_get( return -EINVAL; } - switch (dai_data->afe_in_bitformat) { + switch (dai_data->afe_rx_in_bitformat) { case SNDRV_PCM_FORMAT_S32_LE: ucontrol->value.integer.value[0] = 2; break; @@ -2984,22 +3005,107 @@ static int msm_dai_q6_afe_input_bit_format_put( } switch (ucontrol->value.integer.value[0]) { case 2: - dai_data->afe_in_bitformat = SNDRV_PCM_FORMAT_S32_LE; + dai_data->afe_rx_in_bitformat = SNDRV_PCM_FORMAT_S32_LE; break; case 1: - dai_data->afe_in_bitformat = SNDRV_PCM_FORMAT_S24_LE; + dai_data->afe_rx_in_bitformat = SNDRV_PCM_FORMAT_S24_LE; break; case 0: default: - dai_data->afe_in_bitformat = SNDRV_PCM_FORMAT_S16_LE; + dai_data->afe_rx_in_bitformat = SNDRV_PCM_FORMAT_S16_LE; break; } pr_debug("%s: updating afe input bit format : %d\n", - __func__, dai_data->afe_in_bitformat); + __func__, dai_data->afe_rx_in_bitformat); + + return 0; +} + +static int msm_dai_q6_afe_output_bit_format_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (!dai_data) { + pr_err("%s: Invalid dai data\n", __func__); + return -EINVAL; + } + + switch (dai_data->afe_tx_out_bitformat) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: afe output bit format : %ld\n", + __func__, ucontrol->value.integer.value[0]); return 0; } +static int msm_dai_q6_afe_output_bit_format_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (!dai_data) { + pr_err("%s: Invalid dai data\n", __func__); + return -EINVAL; + } + switch (ucontrol->value.integer.value[0]) { + case 2: + dai_data->afe_tx_out_bitformat = SNDRV_PCM_FORMAT_S32_LE; + break; + case 1: + dai_data->afe_tx_out_bitformat = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + dai_data->afe_tx_out_bitformat = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: updating afe output bit format : %d\n", + __func__, dai_data->afe_tx_out_bitformat); + + return 0; +} + +static int msm_dai_q6_afe_output_channel_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (dai_data) { + ucontrol->value.integer.value[0] = + dai_data->afe_tx_out_channels; + pr_debug("%s:afe output channel = %d\n", + __func__, dai_data->afe_tx_out_channels); + } + return 0; +} + +static int msm_dai_q6_afe_output_channel_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (dai_data) { + dai_data->afe_tx_out_channels = + ucontrol->value.integer.value[0]; + pr_debug("%s: updating afe output channel : %d\n", + __func__, dai_data->afe_tx_out_channels); + } + return 0; +} + static int msm_dai_q6_afe_scrambler_mode_get( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -3041,10 +3147,10 @@ static const struct snd_kcontrol_new afe_enc_config_controls[] = { .get = msm_dai_q6_afe_enc_cfg_get, .put = msm_dai_q6_afe_enc_cfg_put, }, - SOC_ENUM_EXT("AFE Input Channels", afe_input_chs_enum[0], + SOC_ENUM_EXT("AFE Input Channels", afe_chs_enum[0], msm_dai_q6_afe_input_channel_get, msm_dai_q6_afe_input_channel_put), - SOC_ENUM_EXT("AFE Input Bit Format", afe_input_bit_format_enum[0], + SOC_ENUM_EXT("AFE Input Bit Format", afe_bit_format_enum[0], msm_dai_q6_afe_input_bit_format_get, msm_dai_q6_afe_input_bit_format_put), SOC_SINGLE_EXT("AFE Scrambler Mode", @@ -3066,7 +3172,7 @@ static int msm_dai_q6_afe_dec_cfg_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; - int format_size = 0; + u32 format_size = 0; if (!dai_data) { pr_err("%s: Invalid dai data\n", __func__); @@ -3077,10 +3183,25 @@ static int msm_dai_q6_afe_dec_cfg_get(struct snd_kcontrol *kcontrol, memcpy(ucontrol->value.bytes.data, &dai_data->dec_config.format, format_size); - memcpy(ucontrol->value.bytes.data + format_size, - &dai_data->dec_config.abr_dec_cfg, - sizeof(struct afe_abr_dec_cfg_t)); + switch (dai_data->dec_config.format) { + case DEC_FMT_AAC_V2: + memcpy(ucontrol->value.bytes.data + format_size, + &dai_data->dec_config.data, + sizeof(struct asm_aac_dec_cfg_v2_t)); + break; + case DEC_FMT_SBC: + case DEC_FMT_MP3: + /* No decoder specific data available */ + break; + default: + pr_debug("%s: Default decoder config for %d format: Expect abr_dec_cfg\n", + __func__, dai_data->dec_config.format); + memcpy(ucontrol->value.bytes.data + format_size, + &dai_data->dec_config.abr_dec_cfg, + sizeof(struct afe_abr_dec_cfg_t)); + break; + } return 0; } @@ -3088,7 +3209,7 @@ static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; - int format_size = 0; + u32 format_size = 0; if (!dai_data) { pr_err("%s: Invalid dai data\n", __func__); @@ -3101,10 +3222,26 @@ static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol, memcpy(&dai_data->dec_config.format, ucontrol->value.bytes.data, format_size); - memcpy(&dai_data->dec_config.abr_dec_cfg, - ucontrol->value.bytes.data + format_size, - sizeof(struct afe_abr_dec_cfg_t)); - + pr_debug("%s: Received decoder config for %d format\n", + __func__, dai_data->dec_config.format); + switch (dai_data->dec_config.format) { + case DEC_FMT_AAC_V2: + memcpy(&dai_data->dec_config.data, + ucontrol->value.bytes.data + format_size, + sizeof(struct asm_aac_dec_cfg_v2_t)); + break; + case DEC_FMT_SBC: + case DEC_FMT_MP3: + /* No decoder specific data available */ + break; + default: + pr_debug("%s: Default decoder config for %d format: Expect abr_dec_cfg\n", + __func__, dai_data->dec_config.format); + memcpy(&dai_data->dec_config.abr_dec_cfg, + ucontrol->value.bytes.data + format_size, + sizeof(struct afe_abr_dec_cfg_t)); + break; + } return 0; } @@ -3118,6 +3255,21 @@ static const struct snd_kcontrol_new afe_dec_config_controls[] = { .get = msm_dai_q6_afe_dec_cfg_get, .put = msm_dai_q6_afe_dec_cfg_put, }, + { + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_INACTIVE), + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "SLIM_9_TX Decoder Config", + .info = msm_dai_q6_afe_dec_cfg_info, + .get = msm_dai_q6_afe_dec_cfg_get, + .put = msm_dai_q6_afe_dec_cfg_put, + }, + SOC_ENUM_EXT("AFE Output Channels", afe_chs_enum[0], + msm_dai_q6_afe_output_channel_get, + msm_dai_q6_afe_output_channel_put), + SOC_ENUM_EXT("AFE Output Bit Format", afe_bit_format_enum[0], + msm_dai_q6_afe_output_bit_format_get, + msm_dai_q6_afe_output_bit_format_put), }; static int msm_dai_q6_slim_rx_drift_info(struct snd_kcontrol *kcontrol, @@ -3296,6 +3448,17 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) snd_ctl_new1(&afe_dec_config_controls[0], dai_data)); break; + case SLIMBUS_9_TX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&afe_dec_config_controls[1], + dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&afe_dec_config_controls[2], + dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&afe_dec_config_controls[3], + dai_data)); + break; case RT_PROXY_DAI_001_RX: rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&rt_proxy_config_controls[0], @@ -4284,7 +4447,8 @@ static struct snd_soc_dai_driver msm_dai_q6_slimbus_tx_dai[] = { .stream_name = "Slimbus9 Capture", .aif_name = "SLIMBUS_9_TX", .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 516b83f237e0..2639f9cedb98 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -794,7 +794,7 @@ static struct msm_pcm_stream_app_type_cfg static int last_be_id_configured[MSM_FRONTEND_DAI_MAX][MAX_SESSION_TYPES]; -/* The caller of this should aqcuire routing lock */ +/* The caller of this should acquire routing lock */ void msm_pcm_routing_get_bedai_info(int be_idx, struct msm_pcm_routing_bdai_data *be_dai) { @@ -803,7 +803,7 @@ void msm_pcm_routing_get_bedai_info(int be_idx, sizeof(struct msm_pcm_routing_bdai_data)); } -/* The caller of this should aqcuire routing lock */ +/* The caller of this should acquire routing lock */ void msm_pcm_routing_get_fedai_info(int fe_idx, int sess_type, struct msm_pcm_routing_fdai_data *fe_dai) { -- GitLab From cc99c35118ddb23d97110c019071453f807b9e69 Mon Sep 17 00:00:00 2001 From: Florian Pfister Date: Wed, 26 Sep 2018 16:17:21 +0200 Subject: [PATCH 0618/1645] asoc: qcs405: add A2DP sink support in machine driver Add support to configure sample rate for SLIM_9_TX. Change-Id: Icea2b7c707840be60a23707947c9811e83e4789d Signed-off-by: Florian Pfister Signed-off-by: Surendar Karka --- asoc/qcs405.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 7 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index b5e6c0ee3edc..f08645797f13 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -70,8 +70,9 @@ #define WSA8810_NAME_1 "wsa881x.20170211" #define WSA8810_NAME_2 "wsa881x.20170212" #define WCN_CDC_SLIM_RX_CH_MAX 2 -#define WCN_CDC_SLIM_TX_CH_MAX 3 +#define WCN_CDC_SLIM_TX_CH_MAX 4 #define TDM_CHANNEL_MAX 8 +#define BT_SLIM_TX SLIM_TX_9 #define ADSP_STATE_READY_TIMEOUT_MS 3000 #define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ @@ -98,6 +99,7 @@ enum { SLIM_TX_6, SLIM_TX_7, SLIM_TX_8, + SLIM_TX_9, SLIM_TX_MAX, }; @@ -361,6 +363,7 @@ static struct dev_config slim_tx_cfg[] = { [SLIM_TX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SLIM_TX_9] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; /* Default configuration of Codec DMA Interface Tx */ @@ -524,6 +527,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_sink, bt_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); @@ -1149,6 +1153,68 @@ static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, return 0; } +static int msm_bt_sample_rate_sink_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (slim_tx_cfg[BT_SLIM_TX].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate = %d", __func__, + slim_tx_cfg[BT_SLIM_TX].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_sink_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_tx_cfg[BT_SLIM_TX].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_tx_cfg[BT_SLIM_TX].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + slim_tx_cfg[BT_SLIM_TX].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + slim_tx_cfg[BT_SLIM_TX].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_tx_cfg[BT_SLIM_TX].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim_tx_cfg[BT_SLIM_TX].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rate = %d, value = %d\n", + __func__, + slim_tx_cfg[BT_SLIM_TX].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + static int cdc_dma_get_port_idx(struct snd_kcontrol *kcontrol) { int idx = 0; @@ -3427,19 +3493,25 @@ static const struct snd_kcontrol_new msm_snd_wsa_controls[] = { }; static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("BT_TX SampleRate", bt_sample_rate_sink, + msm_bt_sample_rate_sink_get, + msm_bt_sample_rate_sink_put), + SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), + SOC_ENUM_EXT("BT_RX SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), + SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, + proxy_rx_ch_get, proxy_rx_ch_put), SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, usb_audio_rx_ch_get, usb_audio_rx_ch_put), SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, usb_audio_tx_ch_get, usb_audio_tx_ch_put), - SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, - proxy_rx_ch_get, proxy_rx_ch_put), SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, usb_audio_rx_format_get, usb_audio_rx_format_put), SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, usb_audio_tx_format_get, usb_audio_tx_format_put), - SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, - msm_bt_sample_rate_get, - msm_bt_sample_rate_put), SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, usb_audio_rx_sample_rate_get, usb_audio_rx_sample_rate_put), @@ -4108,6 +4180,14 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, slim_tx_cfg[SLIM_TX_8].channels; break; + case MSM_BACKEND_DAI_SLIMBUS_9_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[SLIM_TX_9].bit_format); + rate->min = rate->max = slim_tx_cfg[SLIM_TX_9].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_9].channels; + break; + case MSM_BACKEND_DAI_USB_RX: param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, usb_rx_cfg.bit_format); @@ -4853,7 +4933,7 @@ static int msm_wsa_cdc_dma_init(struct snd_soc_pcm_runtime *rtd) static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) { unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; - unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; + unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161, 162}; struct snd_soc_dai *codec_dai = rtd->codec_dai; return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), -- GitLab From 05392ab0da20a6248948bd49e201c38689525a3f Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Mon, 3 Sep 2018 18:23:19 +0530 Subject: [PATCH 0619/1645] asoc: qcs405: add machine driver support for SLIMBUS_9_TX Add machine driver code to support SLIMBUS_9_TX port. SLIMBUS_9_TX BE port is used for split A2DP sink usecase. Change-Id: I9628a46c4b2b2fe0f5fb8c9861975fd4630bdcdb --- asoc/qcs405.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index f08645797f13..a0f54600e0bb 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -6990,6 +6990,20 @@ static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { .ops = &msm_wcn_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_SLIMBUS_9_TX, + .stream_name = "Slimbus9 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16403", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_bt_split_a2dp_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_9_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { -- GitLab From 2bb55777d4a238735e5f64c46e820283040ba9af Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Wed, 24 Oct 2018 00:17:15 -0700 Subject: [PATCH 0620/1645] ASoC: msm: routing: add ec ref for sec and tert tdm Add ec reference support for SEC_TDM_TX_0 and TERT_TDM_RX_2 ports. Change-Id: I3116b942fbd3c6c7bea14a77fdcd840dcab059aa Signed-off-by: Derek Chen --- asoc/msm-pcm-routing-v2.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 516b83f237e0..3e4ba50c2e23 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -3941,6 +3941,14 @@ static int msm_routing_ec_ref_rx_put(struct snd_kcontrol *kcontrol, msm_route_ec_ref_rx = 34; ec_ref_port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_0; break; + case 35: + msm_route_ec_ref_rx = 35; + ec_ref_port_id = AFE_PORT_ID_TERTIARY_TDM_RX_2; + break; + case 36: + msm_route_ec_ref_rx = 36; + ec_ref_port_id = AFE_PORT_ID_SECONDARY_TDM_TX; + break; default: msm_route_ec_ref_rx = 0; /* NONE */ pr_err("%s EC ref rx %ld not valid\n", @@ -3967,7 +3975,7 @@ static const char *const ec_ref_rx[] = { "None", "SLIM_RX", "I2S_RX", "WSA_CDC_DMA_RX_0", "WSA_CDC_DMA_RX_1", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_2", "SLIM_7_RX", "RX_CDC_DMA_RX_0", "RX_CDC_DMA_RX_1", "RX_CDC_DMA_RX_2", - "RX_CDC_DMA_RX_3", "TX_CDC_DMA_TX_0", + "RX_CDC_DMA_RX_3", "TX_CDC_DMA_TX_0", "TERT_TDM_RX_2", "SEC_TDM_TX_0", }; static const struct soc_enum msm_route_ec_ref_rx_enum[] = { @@ -21562,6 +21570,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_1", "QUAT_TDM_RX_1"}, {"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_2", "QUAT_TDM_RX_2"}, {"AUDIO_REF_EC_UL1 MUX", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"AUDIO_REF_EC_UL1 MUX", "TERT_TDM_RX_2", "TERT_TDM_RX_2"}, + {"AUDIO_REF_EC_UL1 MUX", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, {"AUDIO_REF_EC_UL2 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"AUDIO_REF_EC_UL2 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, @@ -21608,6 +21618,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_1", "QUAT_TDM_RX_1"}, {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_2", "QUAT_TDM_RX_2"}, {"AUDIO_REF_EC_UL10 MUX", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"AUDIO_REF_EC_UL10 MUX", "TERT_TDM_RX_2", "TERT_TDM_RX_2"}, + {"AUDIO_REF_EC_UL10 MUX", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, {"AUDIO_REF_EC_UL16 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"AUDIO_REF_EC_UL16 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, -- GitLab From 68a4a15c787b5f3c43ca20b2c316f9c8c4203c3b Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Tue, 23 Oct 2018 20:51:37 +0530 Subject: [PATCH 0621/1645] dsp: fix issue with MDF shared memory access in QCS403 MDF shared memory uses different SID from other use cases. Existing memory map function hard codes SID from audio ion. Use separate map function for MDF to make use of proper SID for MDF shared memory in 32bit build. Change-Id: I0e854054ad6f58344644f3386618986eab238549 Signed-off-by: Mangesh Kunchamwar --- dsp/msm_mdf.c | 16 +++--- dsp/q6core.c | 117 +++++++++++++++++++++++++++++++++++++++++-- include/dsp/q6core.h | 6 ++- 3 files changed, 128 insertions(+), 11 deletions(-) diff --git a/dsp/msm_mdf.c b/dsp/msm_mdf.c index 9c73e55f12dd..fcc8a5ceedd3 100644 --- a/dsp/msm_mdf.c +++ b/dsp/msm_mdf.c @@ -112,7 +112,7 @@ struct msm_mdf_smmu { uint8_t device_status; uint64_t sid; struct dma_iommu_mapping *mapping; - dma_addr_t pa; + u64 pa; size_t pa_len; }; @@ -183,6 +183,9 @@ static int msm_mdf_dma_buf_map(struct msm_mdf_mem *mem, struct msm_mdf_smmu *smmu) { int rc = 0; + dma_addr_t pa = 0; + + smmu->pa = 0; if (!smmu) return -EINVAL; @@ -207,7 +210,7 @@ static int msm_mdf_dma_buf_map(struct msm_mdf_mem *mem, return -ENODEV; } - smmu->pa = dma_map_single_attrs(smmu->cb_dev, mem->va, + pa = dma_map_single_attrs(smmu->cb_dev, mem->va, mem->size, DMA_BIDIRECTIONAL, DMA_ATTR_SKIP_CPU_SYNC); if (dma_mapping_error(smmu->cb_dev, smmu->pa)) { rc = -ENOMEM; @@ -215,13 +218,14 @@ static int msm_mdf_dma_buf_map(struct msm_mdf_mem *mem, __func__, rc); goto err; } + smmu->pa |= pa; smmu->pa_len = mem->size; /* Append the SMMU SID information to the IOVA address */ if (smmu->sid) smmu->pa |= smmu->sid; } else { - smmu->pa = mem->dma_addr; + smmu->pa |= mem->dma_addr; smmu->pa_len = mem->size; } pr_err("%s: pa=%pa, pa_len=%zd\n", __func__, @@ -312,7 +316,7 @@ static int msm_mdf_map_memory_to_subsys(struct msm_mdf_mem *mem, /* Map mdf shared memory to ADSP */ if (!strcmp("adsp", smmu->subsys)) { - rc = q6core_map_memory_regions((phys_addr_t *)&smmu->pa, + rc = q6core_map_mdf_memory_regions((uint64_t *)&smmu->pa, ADSP_MEMORY_MAP_MDF_SHMEM_4K_POOL, (uint32_t *)&smmu->pa_len, 1, &mem->map_handle); if (rc) { @@ -323,7 +327,7 @@ static int msm_mdf_map_memory_to_subsys(struct msm_mdf_mem *mem, if (mem->map_handle) { /* Map mdf shared memory to remote DSPs */ rc = q6core_map_mdf_shared_memory(mem->map_handle, - (phys_addr_t *)&smmu->pa, smmu->proc_id, + (uint64_t *)&smmu->pa, smmu->proc_id, (uint32_t *)&smmu->pa_len, 1); if (rc) { pr_err("%s: q6core_map_mdf_shared_memory failed, rc = %d\n", @@ -601,7 +605,7 @@ static int msm_mdf_cb_probe(struct device *dev) dev_err(dev, "%s: qcom,smmu-sid-mask missing in DT node, using default\n", __func__); - smmu_sid_mask = 0xFFFFFFFFFFFFFFFF; + smmu_sid_mask = 0xF; } rc = of_parse_phandle_with_args(dev->of_node, "iommus", diff --git a/dsp/q6core.c b/dsp/q6core.c index cf8419316b1a..4888f7110efa 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -41,6 +41,8 @@ #define ADSP_STATE_READY_TIMEOUT_MS 3000 #define APR_ENOTREADY 10 +#define MEMPOOL_ID_MASK 0xFF +#define MDF_MAP_TOKEN 0xF000 enum { META_CAL, @@ -62,9 +64,11 @@ struct q6core_avcs_ver_info { struct q6core_str { struct apr_svc *core_handle_q; wait_queue_head_t bus_bw_req_wait; + wait_queue_head_t mdf_map_resp_wait; wait_queue_head_t cmd_req_wait; wait_queue_head_t avcs_fwk_ver_req_wait; u32 bus_bw_resp_received; + u32 mdf_map_resp_received; enum cmd_flags { FLAG_NONE, FLAG_CMDRSP_LICENSE_RESULT @@ -79,6 +83,7 @@ struct q6core_str { u32 param; struct cal_type_data *cal_data[CORE_MAX_CAL]; uint32_t mem_map_cal_handle; + uint32_t mdf_mem_map_cal_handle; int32_t adsp_status; int32_t avs_state; struct q6core_avcs_ver_info q6core_avcs_ver_info; @@ -340,9 +345,15 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) payload1 = data->payload; pr_debug("%s: AVCS_CMDRSP_SHARED_MEM_MAP_REGIONS handle %d\n", __func__, payload1[0]); - q6core_lcl.mem_map_cal_handle = payload1[0]; - q6core_lcl.bus_bw_resp_received = 1; - wake_up(&q6core_lcl.bus_bw_req_wait); + if (data->token == MDF_MAP_TOKEN) { + q6core_lcl.mdf_mem_map_cal_handle = payload1[0]; + q6core_lcl.mdf_map_resp_received = 1; + wake_up(&q6core_lcl.mdf_map_resp_wait); + } else { + q6core_lcl.mem_map_cal_handle = payload1[0]; + q6core_lcl.bus_bw_resp_received = 1; + wake_up(&q6core_lcl.bus_bw_req_wait); + } break; case AVCS_CMDRSP_ADSP_EVENT_GET_STATE: payload1 = data->payload; @@ -1006,6 +1017,103 @@ int q6core_map_memory_regions(phys_addr_t *buf_add, uint32_t mempool_id, return ret; } +/** + * q6core_map_mdf_memory_regions - for sending MDF shared memory map information + * to ADSP. + * + * @buf_add: array of buffers. + * @mempool_id: memory pool ID + * @bufsz: size of the buffer + * @bufcnt: buffers count + * @map_handle: map handle received from ADSP + */ +int q6core_map_mdf_memory_regions(uint64_t *buf_add, uint32_t mempool_id, + uint32_t *bufsz, uint32_t bufcnt, uint32_t *map_handle) +{ + struct avs_cmd_shared_mem_map_regions *mmap_regions = NULL; + struct avs_shared_map_region_payload *mregions = NULL; + void *mmap_region_cmd = NULL; + void *payload = NULL; + int ret = 0; + int i = 0; + int cmd_size = 0; + + mutex_lock(&q6core_lcl.cmd_lock); + + cmd_size = sizeof(struct avs_cmd_shared_mem_map_regions) + + sizeof(struct avs_shared_map_region_payload) + * bufcnt; + + mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL); + if (mmap_region_cmd == NULL) + return -ENOMEM; + + mmap_regions = (struct avs_cmd_shared_mem_map_regions *)mmap_region_cmd; + mmap_regions->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mmap_regions->hdr.pkt_size = cmd_size; + mmap_regions->hdr.src_port = 0; + mmap_regions->hdr.dest_port = 0; + mmap_regions->hdr.token = MDF_MAP_TOKEN; + mmap_regions->hdr.opcode = AVCS_CMD_SHARED_MEM_MAP_REGIONS; + mmap_regions->mem_pool_id = mempool_id & MEMPOOL_ID_MASK; + mmap_regions->num_regions = bufcnt & 0x00ff; + mmap_regions->property_flag = 0x00; + + payload = ((u8 *) mmap_region_cmd + + sizeof(struct avs_cmd_shared_mem_map_regions)); + mregions = (struct avs_shared_map_region_payload *)payload; + + for (i = 0; i < bufcnt; i++) { + mregions->shm_addr_lsw = lower_32_bits(buf_add[i]); + mregions->shm_addr_msw = upper_32_bits(buf_add[i]); + mregions->mem_size_bytes = bufsz[i]; + ++mregions; + } + + pr_debug("%s: sending MDF memory map, addr %pK, size %d, bufcnt = %d\n", + __func__, buf_add, bufsz[0], mmap_regions->num_regions); + + *map_handle = 0; + q6core_lcl.adsp_status = 0; + q6core_lcl.mdf_map_resp_received = 0; + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) + mmap_regions); + if (ret < 0) { + pr_err("%s: mmap regions failed %d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(q6core_lcl.mdf_map_resp_wait, + (q6core_lcl.mdf_map_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: timeout. waited for memory map\n", __func__); + ret = -ETIMEDOUT; + goto done; + } else { + /* set ret to 0 as no timeout happened */ + ret = 0; + } + + if (q6core_lcl.adsp_status < 0) { + pr_err("%s: DSP returned error %d\n", + __func__, q6core_lcl.adsp_status); + ret = q6core_lcl.adsp_status; + goto done; + } + + *map_handle = q6core_lcl.mdf_mem_map_cal_handle; +done: + kfree(mmap_region_cmd); + mutex_unlock(&q6core_lcl.cmd_lock); + return ret; +} +EXPORT_SYMBOL(q6core_map_mdf_memory_regions); + int q6core_memory_unmap_regions(uint32_t mem_map_handle) { struct avs_cmd_shared_mem_unmap_regions unmap_regions; @@ -1063,7 +1171,7 @@ int q6core_memory_unmap_regions(uint32_t mem_map_handle) } -int q6core_map_mdf_shared_memory(uint32_t map_handle, phys_addr_t *buf_add, +int q6core_map_mdf_shared_memory(uint32_t map_handle, uint64_t *buf_add, uint32_t proc_id, uint32_t *bufsz, uint32_t bufcnt) { struct avs_cmd_map_mdf_shared_memory *mmap_regions = NULL; @@ -1563,6 +1671,7 @@ int __init core_init(void) init_waitqueue_head(&q6core_lcl.bus_bw_req_wait); init_waitqueue_head(&q6core_lcl.cmd_req_wait); init_waitqueue_head(&q6core_lcl.avcs_fwk_ver_req_wait); + init_waitqueue_head(&q6core_lcl.mdf_map_resp_wait); q6core_lcl.cmd_resp_received_flag = FLAG_NONE; mutex_init(&q6core_lcl.cmd_lock); mutex_init(&q6core_lcl.ver_lock); diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index 55d7dbc6c564..1fa0d1e98a9f 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -199,7 +199,11 @@ struct avcs_cmd_load_unload_topo_modules { int q6core_map_memory_regions(phys_addr_t *buf_add, uint32_t mempool_id, uint32_t *bufsz, uint32_t bufcnt, uint32_t *map_handle); int q6core_memory_unmap_regions(uint32_t mem_map_handle); -int q6core_map_mdf_shared_memory(uint32_t map_handle, phys_addr_t *buf_add, + +int q6core_map_mdf_memory_regions(uint64_t *buf_add, uint32_t mempool_id, + uint32_t *bufsz, uint32_t bufcnt, uint32_t *map_handle); + +int q6core_map_mdf_shared_memory(uint32_t map_handle, uint64_t *buf_add, uint32_t proc_id, uint32_t *bufsz, uint32_t bufcnt); int32_t core_set_license(uint32_t key, uint32_t module_id); -- GitLab From aade87e1f2400f0159d6b1706864e0c785522606 Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Fri, 26 Oct 2018 17:28:46 -0700 Subject: [PATCH 0622/1645] dsp: increase afe apr_send_pkt timeout to 2 seconds Some USB headsets take more than 1 second to respond for afe port start command so increase the timeout value to support playback on slow responsive USB headsets. Change-Id: I76c43bafe3c9e1e2d8a4a23059053db6bfc0188b Signed-off-by: Vidyakumar Athota --- dsp/q6afe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index da8dc5a8033a..49c7b026eb5b 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -851,7 +851,7 @@ static int afe_apr_send_pkt(void *data, wait_queue_head_t *wait) if (wait) { ret = wait_event_timeout(*wait, (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); + msecs_to_jiffies(2 * TIMEOUT_MS)); if (!ret) { ret = -ETIMEDOUT; } else if (atomic_read(&this_afe.status) > 0) { -- GitLab From 80eb5ddfdd3c4477c37f44fb4d4d7ce38399013c Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Fri, 2 Nov 2018 12:42:05 +0800 Subject: [PATCH 0623/1645] asoc: wcd937x: disable TX CH2 after power down TX channel2 is not disabled after power down. It leads to noise at the beginning of next recording on CH2. Disable it after power down. Change-Id: If12a84df52b9c8cd55de2bdcb91f950b054898b8 Signed-off-by: Xiaojun Sang --- asoc/codecs/wcd937x/wcd937x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 8436605c1683..78cdfa13cf7e 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1086,6 +1086,7 @@ static int wcd937x_enable_req(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, WCD937X_ANA_TX_CH1, 0x80, 0x00); + snd_soc_update_bits(codec, WCD937X_ANA_TX_CH2, 0x80, 0x00); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x10, 0x00); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, -- GitLab From 4867dc18a847f2735e2d30ca7cb60b36893681ad Mon Sep 17 00:00:00 2001 From: Dhananjay Kumar Date: Mon, 15 Oct 2018 18:39:47 +0530 Subject: [PATCH 0624/1645] asoc: msm-lsm-client: Update lsm client driver to prevent buffer overrun ADSP, userspace and LSM client driver, all these three layer are maintaining independent buffers and rewrite them irrespective of the buffer being read successfully by their client or not. Before switching to real-time capture, history buffers cached can be returned with minimal delay and may lead to overrun in a module if buffering in the module is not sufficient to store all those data generated almost instantaneously. LSM driver having buffer size smaller than history buffer duration is hitting this issue and resulting in buffer overrun for even a small delay from userspace in start of capture processing thread. Prevent this issue by synchronising read and write in LSM driver to make sure the driver waits for read from userspace before writing the same buffer again. Change-Id: I2710b484a7ef03e8314c7ba05bf729893aecb890 Signed-off-by: Dhananjay Kumar --- asoc/msm-lsm-client.c | 54 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index e9ec63f0fc49..391d71946957 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -93,6 +93,9 @@ struct lsm_priv { struct mutex lsm_api_lock; int appl_cnt; int dma_write; + int xrun_count; + int xrun_index; + spinlock_t xrun_lock; }; enum { /* lsm session states */ @@ -224,6 +227,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, int rc; struct lsm_cmd_read_done *read_done = (struct lsm_cmd_read_done *)payload; int buf_index = 0; + unsigned long flags = 0; if (prtd->lsm_client->session != token || !read_done) { @@ -250,18 +254,30 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, prtd->lsm_client->out_hw_params.period_count); return; } + spin_lock_irqsave(&prtd->xrun_lock, flags); prtd->dma_write += read_done->total_size; atomic_inc(&prtd->buf_count); snd_pcm_period_elapsed(substream); wake_up(&prtd->period_wait); - /* queue the next period buffer */ - buf_index = (buf_index + 1) % - prtd->lsm_client->out_hw_params.period_count; - rc = msm_lsm_queue_lab_buffer(prtd, buf_index); - if (rc) - dev_err(rtd->dev, - "%s: error in queuing the lab buffer rc %d\n", - __func__, rc); + if (atomic_read(&prtd->buf_count) < + prtd->lsm_client->out_hw_params.period_count) { + /* queue the next period buffer */ + buf_index = (buf_index + 1) % + prtd->lsm_client->out_hw_params.period_count; + rc = msm_lsm_queue_lab_buffer(prtd, buf_index); + if (rc) + dev_err(rtd->dev, + "%s: error in queuing the lab buffer rc %d\n", + __func__, rc); + } else { + dev_dbg(rtd->dev, + "%s: xrun: further lab to be queued after read from user\n", + __func__); + if (!prtd->xrun_count) + prtd->xrun_index = buf_index; + (prtd->xrun_count)++; + } + spin_unlock_irqrestore(&prtd->xrun_lock, flags); } else dev_err(rtd->dev, "%s: Invalid lab buffer returned by dsp\n", __func__); @@ -970,6 +986,8 @@ static int msm_lsm_start_lab_buffer(struct lsm_priv *prtd, uint16_t status) atomic_set(&prtd->buf_count, 0); prtd->appl_cnt = 0; prtd->dma_write = 0; + prtd->xrun_count = 0; + prtd->xrun_index = 0; rc = msm_lsm_queue_lab_buffer(prtd, 0); if (rc) @@ -2377,6 +2395,7 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) } mutex_init(&prtd->lsm_api_lock); spin_lock_init(&prtd->event_lock); + spin_lock_init(&prtd->xrun_lock); init_waitqueue_head(&prtd->event_wait); init_waitqueue_head(&prtd->period_wait); prtd->substream = substream; @@ -2721,7 +2740,8 @@ static int msm_lsm_pcm_copy(struct snd_pcm_substream *substream, int ch, struct snd_pcm_runtime *runtime = substream->runtime; struct lsm_priv *prtd = runtime->private_data; char *pcm_buf = NULL; - int rc = 0; + int rc = 0, buf_index = 0; + unsigned long flags = 0; struct snd_soc_pcm_runtime *rtd; if (!substream->private_data) { @@ -2776,7 +2796,23 @@ static int msm_lsm_pcm_copy(struct snd_pcm_substream *substream, int ch, } prtd->appl_cnt = (prtd->appl_cnt + 1) % prtd->lsm_client->out_hw_params.period_count; + + spin_lock_irqsave(&prtd->xrun_lock, flags); + /* Queue lab buffer here if in xrun */ + if (prtd->xrun_count > 0) { + (prtd->xrun_count)--; + buf_index = (prtd->xrun_index + 1) % + prtd->lsm_client->out_hw_params.period_count; + rc = msm_lsm_queue_lab_buffer(prtd, buf_index); + if (rc) + dev_err(rtd->dev, + "%s: error in queuing the lab buffer rc %d\n", + __func__, rc); + prtd->xrun_index = buf_index; + } atomic_dec(&prtd->buf_count); + spin_unlock_irqrestore(&prtd->xrun_lock, flags); + return 0; } -- GitLab From 1face6aa6d462e5429d57f086720e2017f79a896 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Tue, 6 Nov 2018 18:03:24 +0530 Subject: [PATCH 0625/1645] dsp: fix issue with MDF shared memory access in CDSP for QCS403 SMMU is not enabled on CDSP and shared memory to CDSP doesn't need SID. Default SID from audio ION was being added in 32bit builds. Avoid adding default SID for MDF shared memory for CDSP. Change-Id: I5e35396fc90071f96e1042c5e08eafe4226c240b Signed-off-by: Mangesh Kunchamwar --- dsp/q6core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dsp/q6core.c b/dsp/q6core.c index 4888f7110efa..f66fc842b52c 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -1209,8 +1209,7 @@ int q6core_map_mdf_shared_memory(uint32_t map_handle, uint64_t *buf_add, for (i = 0; i < bufcnt; i++) { mregions->shm_addr_lsw = lower_32_bits(buf_add[i]); - mregions->shm_addr_msw = - msm_audio_populate_upper_32_bits(buf_add[i]); + mregions->shm_addr_msw = upper_32_bits(buf_add[i]); mregions->mem_size_bytes = bufsz[i]; ++mregions; } -- GitLab From 52b9a67618955c4eeeecb447648dcc7600014cac Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Thu, 30 Nov 2017 15:42:11 -0800 Subject: [PATCH 0626/1645] asoc: sdm845: set flag ignore_pmdown_time for ultrasound RX DAI During PCM closing, the AIF power down will be delayed due to flag ignore_pmdown_time is not set. Set this flag for ultrasound RX DAI to avoid delay in PCM close which causes slimbus overflow. Change-Id: I5eeaceaacc5be0c200b50d1a7d0f211fa0d41f2b Signed-off-by: Xiaoyu Ye --- asoc/sdm845.c | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/sdm845.c b/asoc/sdm845.c index 392ac85b9d78..e2ab1f0167da 100644 --- a/asoc/sdm845.c +++ b/asoc/sdm845.c @@ -5412,6 +5412,7 @@ static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = { .codec_name = "tavil_codec", .codec_dai_name = "tavil_rx2", .ignore_suspend = 1, + .ignore_pmdown_time = 1, .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ops = &msm_slimbus_2_be_ops, }, -- GitLab From e30eef71d414a7fd0efdd6867de6ae1fb8c68c3b Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 5 Nov 2018 17:40:09 +0530 Subject: [PATCH 0627/1645] soc: swr-mstr: Update class-H port params Update sampling interval for class-H as per HW spec and hstart/hstop bit fields in swr master register since master fields are not same as slave fields for this setting as defined in HW register document. Change-Id: Iefb5bb83bb8984ee964f405f53ab6f8f0ba47f75 Signed-off-by: Laxminath Kasam --- soc/swr-mstr-ctrl.c | 2 +- soc/swrm_port_config.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 80dd5e8d3f76..df373abcc4db 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -924,7 +924,7 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank) if (mport->hstart != SWR_INVALID_PARAM && mport->hstop != SWR_INVALID_PARAM) { reg[len] = SWRM_DP_PORT_HCTRL_BANK(i + 1, bank); - hparams = (mport->hstart << 4) | mport->hstop; + hparams = (mport->hstop << 4) | mport->hstart; val[len++] = hparams; } if (mport->blk_pack_mode != SWR_INVALID_PARAM) { diff --git a/soc/swrm_port_config.h b/soc/swrm_port_config.h index 81bab1c90bff..6dbd1de41586 100644 --- a/soc/swrm_port_config.h +++ b/soc/swrm_port_config.h @@ -34,7 +34,7 @@ struct port_params wsa_frame_superset[SWR_MSTR_PORT_LEN] = { struct port_params rx_frame_params[SWR_MSTR_PORT_LEN] = { {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1}, - {31, 0, 0, 3, 6, 7, 0, 0xFF, 0}, + {63, 0, 0, 3, 6, 7, 0, 0xFF, 0}, {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0}, {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0}, {0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0}, @@ -42,7 +42,7 @@ struct port_params rx_frame_params[SWR_MSTR_PORT_LEN] = { struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = { {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1}, - {31, 0, 0, 3, 6, 7, 0, 0xFF, 0}, + {63, 0, 0, 3, 6, 7, 0, 0xFF, 0}, {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0}, {7, 9, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0}, {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 3, 0}, -- GitLab From 94aca37c6ebbf4c84cfe17dc9d0ac42d8ee78aef Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 9 Nov 2018 14:53:48 -0800 Subject: [PATCH 0628/1645] asoc: msm: update max eq sessions based on fe dai max Maintain eq data size to be equal to the max fe dais present to not step over bound in accessing. Change-Id: Ice0b7675b39a9fe2516a56d4e0b739ce34277958 Signed-off-by: Karthikeyan Mani --- asoc/msm-qti-pp-config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index 1a3bd9c01c64..a8e20bc69ba6 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -28,7 +28,7 @@ /* EQUALIZER */ /* Equal to Frontend after last of the MULTIMEDIA SESSIONS */ -#define MAX_EQ_SESSIONS (MSM_FRONTEND_DAI_MULTIMEDIA20 + 1) +#define MAX_EQ_SESSIONS (MSM_FRONTEND_DAI_MAX + 1) #define CHMIX_CFG_CONST_PARAM_SIZE 4 enum { -- GitLab From 95be5b145e83542e902ac8d556b4297d6ae04bcc Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 9 Nov 2018 14:57:32 -0800 Subject: [PATCH 0629/1645] dsp: q6adm: fix boundary check for copp idx Check for maximum boundary limit for adm parameters before using the parameter array. Change-Id: Idf4961c547cd38e3525c255cca849e5e4280ac29 Signed-off-by: Karthikeyan Mani --- dsp/q6adm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index b9c11ac6b4c3..b4b5b20d87d8 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -1389,7 +1389,7 @@ static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload, */ if ((payload_size >= struct_size + data_size) && (ARRAY_SIZE(adm_get_parameters) > idx) && - (ARRAY_SIZE(adm_get_parameters) >= idx + 1 + data_size)) { + (ARRAY_SIZE(adm_get_parameters) > idx + 1 + data_size)) { pr_debug("%s: Received parameter data in band\n", __func__); /* -- GitLab From 4183e32a46da04036b76ef5819a0af89108a5898 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 9 Nov 2018 17:48:17 -0800 Subject: [PATCH 0630/1645] asoc: msm-audio-effects: initialize struct before use Memset the param header struct to null values before using or passing it to other functions. Change-Id: I09ae686e62c8812ea267d4f809529b324fb7106d Signed-off-by: Karthikeyan Mani --- asoc/msm-audio-effects-q6-v2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/msm-audio-effects-q6-v2.c b/asoc/msm-audio-effects-q6-v2.c index 8b2ca3168bcf..b4dc30ab5948 100644 --- a/asoc/msm-audio-effects-q6-v2.c +++ b/asoc/msm-audio-effects-q6-v2.c @@ -141,6 +141,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, pr_debug("%s: device: %d\n", __func__, devices); updt_params = (u8 *) params; /* Set MID and IID once at top and only update param specific fields*/ + memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AUDPROC_MODULE_ID_VIRTUALIZER; param_hdr.instance_id = INSTANCE_ID_0; for (i = 0; i < num_commands; i++) { -- GitLab From de09dfb30145bd2a49b0f0e7f04fc224c18eb38b Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 9 Nov 2018 13:00:30 +0530 Subject: [PATCH 0631/1645] asoc: codecs: bolero: Add HPH power modes on bolero Two power modes are supported on bolero digital. Add support to set required power mode using mixer control and enable runtime during powerup sequence. Change-Id: I4c5a7560984d60745ac98848f1eec1d1f8485323 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 40 ++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 986375dec738..4624eae8a9e9 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -344,6 +344,7 @@ struct rx_macro_priv { bool is_native_on; bool is_ear_mode_on; bool dev_up; + bool hph_pwr_mode; u16 mclk_mux; struct mutex mclk_lock; struct mutex swr_clk_lock; @@ -432,6 +433,10 @@ static const char *const rx_macro_ear_mode_text[] = {"OFF", "ON"}; static const struct soc_enum rx_macro_ear_mode_enum = SOC_ENUM_SINGLE_EXT(2, rx_macro_ear_mode_text); +static const char *const rx_macro_hph_pwr_mode_text[] = {"ULP", "LoHIFI"}; +static const struct soc_enum rx_macro_hph_pwr_mode_enum = + SOC_ENUM_SINGLE_EXT(2, rx_macro_hph_pwr_mode_text); + static const char * const rx_macro_vbat_bcl_gsm_mode_text[] = {"OFF", "ON"}; static const struct soc_enum rx_macro_vbat_bcl_gsm_mode_enum = SOC_ENUM_SINGLE_EXT(2, rx_macro_vbat_bcl_gsm_mode_text); @@ -1689,6 +1694,34 @@ static int rx_macro_put_ear_mode(struct snd_kcontrol *kcontrol, return 0; } +static int rx_macro_get_hph_pwr_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = rx_priv->hph_pwr_mode; + return 0; +} + +static int rx_macro_put_hph_pwr_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + rx_priv->hph_pwr_mode = ucontrol->value.integer.value[0]; + return 0; +} + static int rx_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1944,6 +1977,8 @@ static void rx_macro_hphdelay_lutbypass(struct snd_soc_codec *codec, hph_lut_bypass_reg, 0x80, 0x80); } + if (rx_priv->hph_pwr_mode) + snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x00); } if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) { @@ -1952,7 +1987,7 @@ static void rx_macro_hphdelay_lutbypass(struct snd_soc_codec *codec, snd_soc_update_bits(codec, BOLERO_CDC_RX_RX0_RX_PATH_CFG1, 0x02, 0x00); snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x00); - snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x0); + snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x20); } } @@ -2375,6 +2410,9 @@ static const struct snd_kcontrol_new rx_macro_snd_controls[] = { SOC_ENUM_EXT("RX_EAR Mode", rx_macro_ear_mode_enum, rx_macro_get_ear_mode, rx_macro_put_ear_mode), + SOC_ENUM_EXT("RX_HPH_PWR_MODE", rx_macro_hph_pwr_mode_enum, + rx_macro_get_hph_pwr_mode, rx_macro_put_hph_pwr_mode), + SOC_ENUM_EXT("RX_GSM mode Enable", rx_macro_vbat_bcl_gsm_mode_enum, rx_macro_vbat_bcl_gsm_mode_func_get, rx_macro_vbat_bcl_gsm_mode_func_put), -- GitLab From 7f6462ebd7fea03edcd5f4ca4f92523de7f8766f Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Tue, 6 Nov 2018 11:51:22 +0530 Subject: [PATCH 0632/1645] soc: swr-mstr: Reinit clk off signal before waiting Reinit clk off signal before waiting to avoid false positives because of the signal complete that happened prior to the waiting. Change-Id: I678fdc8589039d9f59e6590a4899309dad479181 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 80dd5e8d3f76..4e2b261a076a 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2110,9 +2110,10 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) break; case SWR_DEVICE_SSR_UP: /* wait for clk voting to be zero */ + reinit_completion(&swrm->clk_off_complete); if (swrm->clk_ref_count && !wait_for_completion_timeout(&swrm->clk_off_complete, - (1 * HZ/100))) + msecs_to_jiffies(200))) dev_err(swrm->dev, "%s: clock voting not zero\n", __func__); -- GitLab From 0fed92f4777e632667dfac9ee99dbbc1484f807e Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Thu, 8 Nov 2018 14:22:22 +0530 Subject: [PATCH 0633/1645] soc: swr-mstr: Ignore device up during SSR New audio session may be opened just before SSR has occured. Ignore device up notification due to new session during SSR as soundwire hardware is not ready. Change-Id: I06a558d0fa9e31ed6bbdfab80402ba7b337e7ad8 signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 80dd5e8d3f76..babf8035b9b3 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2132,6 +2132,13 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) break; case SWR_DEVICE_UP: dev_dbg(swrm->dev, "%s: swr master up called\n", __func__); + mutex_lock(&swrm->devlock); + if (!swrm->dev_up) { + dev_dbg(swrm->dev, "SSR not complete yet\n"); + mutex_unlock(&swrm->devlock); + return -EBUSY; + } + mutex_unlock(&swrm->devlock); mutex_lock(&swrm->mlock); pm_runtime_mark_last_busy(&pdev->dev); pm_runtime_get_sync(&pdev->dev); -- GitLab From 838f0b885f40ea72fc661e56002cb7ee39347969 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 23 Oct 2018 20:20:18 +0530 Subject: [PATCH 0634/1645] asoc: wcd937x: move export functions to new header For export functions from wcd937x use separate header as internal header is only supposed to be used within wcd937x driver logic. Change-Id: Ice373ff95f7166a2f968458b25223c582edc7fba Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd937x/internal.h | 2 -- asoc/codecs/wcd937x/wcd937x.c | 1 + asoc/codecs/wcd937x/wcd937x.h | 27 +++++++++++++++++++++++++++ asoc/sm6150.c | 2 +- 4 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 asoc/codecs/wcd937x/wcd937x.h diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index 4ca82726a5ce..eb2de9d69efb 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -168,6 +168,4 @@ extern int wcd937x_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, extern int wcd937x_get_micb_vout_ctl_val(u32 micb_mv); extern int wcd937x_micbias_control(struct snd_soc_codec *codec, int micb_num, int req, bool is_dapm); -extern int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root, - struct snd_soc_codec *codec); #endif diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 78cdfa13cf7e..485d328389d3 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -25,6 +25,7 @@ #include #include #include "internal.h" +#include "wcd937x.h" #include "../wcdcal-hwdep.h" #include "wcd937x-registers.h" #include "../msm-cdc-pinctrl.h" diff --git a/asoc/codecs/wcd937x/wcd937x.h b/asoc/codecs/wcd937x/wcd937x.h new file mode 100644 index 000000000000..49905d77f54c --- /dev/null +++ b/asoc/codecs/wcd937x/wcd937x.h @@ -0,0 +1,27 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _WCD937X_H +#define _WCD937X_H + +#ifdef CONFIG_SND_SOC_WCD937X +extern int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_codec *codec); +#else +extern int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + return 0; +} +#endif /* CONFIG_SND_SOC_WCD937X */ + +#endif diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 8bd1d6f32086..307ef0c6321d 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -42,7 +42,7 @@ #include "codecs/bolero/bolero-cdc.h" #include #include "codecs/bolero/wsa-macro.h" -#include "codecs/wcd937x/internal.h" +#include "codecs/wcd937x/wcd937x.h" #define DRV_NAME "sm6150-asoc-snd" -- GitLab From 7adc34e496464cdd2847bb9f22476a4d16239552 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 9 Nov 2018 11:24:38 +0530 Subject: [PATCH 0635/1645] asoc: codecs: Add new class-H driver for wcd937x Add new class-H driver with sequences to support both class-H and class-AB modes on wcd937x variants. Change-Id: Ie109f3d951af1e8a0079dd39ab2fe1e9883bd6c2 Signed-off-by: Laxminath Kasam --- asoc/codecs/Kbuild | 1 + asoc/codecs/bolero/rx-macro.c | 15 +- asoc/codecs/wcd-clsh.c | 575 +++++++++++++++++++++++++++++++ asoc/codecs/wcd-clsh.h | 104 ++++++ asoc/codecs/wcd937x/internal.h | 3 + asoc/codecs/wcd937x/wcd937x.c | 203 +++++++---- include/asoc/wcd9xxx_registers.h | 30 ++ 7 files changed, 846 insertions(+), 85 deletions(-) create mode 100644 asoc/codecs/wcd-clsh.c create mode 100644 asoc/codecs/wcd-clsh.h create mode 100644 include/asoc/wcd9xxx_registers.h diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 3e5fc12e71e6..48e043119bec 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -98,6 +98,7 @@ ifdef CONFIG_WCD9XXX_CODEC_CORE endif ifdef CONFIG_SND_SOC_WCD9XXX_V2 + WCD9XXX_OBJS += wcd-clsh.o WCD9XXX_OBJS += wcd9xxx-common-v2.o WCD9XXX_OBJS += wcd9xxx-resmgr-v2.o WCD9XXX_OBJS += wcdcal-hwdep.o diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 986375dec738..0b8256b6a8dc 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1535,12 +1535,12 @@ static void rx_macro_hd2_control(struct snd_soc_codec *codec, switch (interp_idx) { case INTERP_HPHL: - hd2_scale_reg = BOLERO_CDC_RX_RX1_RX_PATH_SEC3; - hd2_enable_reg = BOLERO_CDC_RX_RX1_RX_PATH_CFG0; + hd2_scale_reg = BOLERO_CDC_RX_RX0_RX_PATH_SEC3; + hd2_enable_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0; break; case INTERP_HPHR: - hd2_scale_reg = BOLERO_CDC_RX_RX2_RX_PATH_SEC3; - hd2_enable_reg = BOLERO_CDC_RX_RX2_RX_PATH_CFG0; + hd2_scale_reg = BOLERO_CDC_RX_RX1_RX_PATH_SEC3; + hd2_enable_reg = BOLERO_CDC_RX_RX1_RX_PATH_CFG0; break; } @@ -1908,18 +1908,15 @@ static void rx_macro_hphdelay_lutbypass(struct snd_soc_codec *codec, struct rx_macro_priv *rx_priv, u16 interp_idx, int event) { - u8 hph_dly_mask = 0; u16 hph_lut_bypass_reg = 0; u16 hph_comp_ctrl7 = 0; switch (interp_idx) { case INTERP_HPHL: - hph_dly_mask = 1; hph_lut_bypass_reg = BOLERO_CDC_RX_TOP_HPHL_COMP_LUT; hph_comp_ctrl7 = BOLERO_CDC_RX_COMPANDER0_CTL7; break; case INTERP_HPHR: - hph_dly_mask = 2; hph_lut_bypass_reg = BOLERO_CDC_RX_TOP_HPHR_COMP_LUT; hph_comp_ctrl7 = BOLERO_CDC_RX_COMPANDER1_CTL7; break; @@ -1928,8 +1925,6 @@ static void rx_macro_hphdelay_lutbypass(struct snd_soc_codec *codec, } if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) { - snd_soc_update_bits(codec, BOLERO_CDC_RX_CLSH_TEST0, - hph_dly_mask, 0x0); if (interp_idx == INTERP_HPHL) { if (rx_priv->is_ear_mode_on) snd_soc_update_bits(codec, @@ -1947,8 +1942,6 @@ static void rx_macro_hphdelay_lutbypass(struct snd_soc_codec *codec, } if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, BOLERO_CDC_RX_CLSH_TEST0, - hph_dly_mask, hph_dly_mask); snd_soc_update_bits(codec, BOLERO_CDC_RX_RX0_RX_PATH_CFG1, 0x02, 0x00); snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x00); diff --git a/asoc/codecs/wcd-clsh.c b/asoc/codecs/wcd-clsh.c new file mode 100644 index 000000000000..d119b837c3f2 --- /dev/null +++ b/asoc/codecs/wcd-clsh.c @@ -0,0 +1,575 @@ +/* + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include "wcd-clsh.h" + +#define WCD_USLEEP_RANGE 50 + +static void (*clsh_state_fp[NUM_CLSH_STATES])(struct snd_soc_codec *, + struct wcd_clsh_cdc_info *, + u8 req_state, bool en, int mode); + +static const char *mode_to_str(int mode) +{ + switch (mode) { + case CLS_H_NORMAL: + return WCD_CLSH_STRINGIFY(CLS_H_NORMAL); + case CLS_H_HIFI: + return WCD_CLSH_STRINGIFY(CLS_H_HIFI); + case CLS_H_LOHIFI: + return WCD_CLSH_STRINGIFY(CLS_H_LOHIFI); + case CLS_H_LP: + return WCD_CLSH_STRINGIFY(CLS_H_LP); + case CLS_H_ULP: + return WCD_CLSH_STRINGIFY(CLS_H_ULP); + case CLS_AB: + return WCD_CLSH_STRINGIFY(CLS_AB); + case CLS_AB_HIFI: + return WCD_CLSH_STRINGIFY(CLS_AB_HIFI); + default: + return WCD_CLSH_STRINGIFY(CLS_H_INVALID); + }; +} + +static const char *state_to_str(u8 state, char *buf, size_t buflen) +{ + int i; + int cnt = 0; + /* + * This array of strings should match with enum wcd_clsh_state_bit. + */ + static const char *const states[] = { + "STATE_EAR", + "STATE_HPH_L", + "STATE_HPH_R", + "STATE_AUX", + }; + + if (state == WCD_CLSH_STATE_IDLE) { + snprintf(buf, buflen, "[STATE_IDLE]"); + goto done; + } + + buf[0] = '\0'; + for (i = 0; i < ARRAY_SIZE(states); i++) { + if (!(state & (1 << i))) + continue; + cnt = snprintf(buf, buflen - cnt - 1, "%s%s%s", buf, + buf[0] == '\0' ? "[" : "|", + states[i]); + } + if (cnt > 0) + strlcat(buf + cnt, "]", buflen); + +done: + if (buf[0] == '\0') + snprintf(buf, buflen, "[STATE_UNKNOWN]"); + return buf; +} + +static inline int wcd_clsh_get_int_mode(struct wcd_clsh_cdc_info *clsh_d, + int clsh_state) +{ + int mode; + + if ((clsh_state != WCD_CLSH_STATE_EAR) && + (clsh_state != WCD_CLSH_STATE_HPHL) && + (clsh_state != WCD_CLSH_STATE_HPHR) && + (clsh_state != WCD_CLSH_STATE_AUX)) + mode = CLS_NONE; + else + mode = clsh_d->interpolator_modes[ffs(clsh_state)]; + + return mode; +} + +static inline void wcd_clsh_set_int_mode(struct wcd_clsh_cdc_info *clsh_d, + int clsh_state, int mode) +{ + if ((clsh_state != WCD_CLSH_STATE_EAR) && + (clsh_state != WCD_CLSH_STATE_HPHL) && + (clsh_state != WCD_CLSH_STATE_HPHR) && + (clsh_state != WCD_CLSH_STATE_AUX)) + return; + + clsh_d->interpolator_modes[ffs(clsh_state)] = mode; +} + +static inline void wcd_clsh_set_buck_mode(struct snd_soc_codec *codec, + int mode) +{ + if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || + mode == CLS_AB_HIFI) + snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES, + 0x08, 0x08); /* set to HIFI */ + else + snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES, + 0x08, 0x00); /* set to default */ +} + +static inline void wcd_clsh_set_flyback_mode(struct snd_soc_codec *codec, + int mode) +{ + if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || + mode == CLS_AB_HIFI) { + snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES, + 0x04, 0x04); + snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEG_CTRL_4, + 0xF0, 0x80); + } else { + snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES, + 0x04, 0x00); /* set to Default */ + snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEG_CTRL_4, + 0xF0, 0x70); + } +} + +static inline void wcd_clsh_force_iq_ctl(struct snd_soc_codec *codec, + int mode, bool enable) +{ + if (enable) { + snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEGDAC_CTRL_2, + 0xE0, 0xA0); + /* 100usec delay is needed as per HW requirement */ + usleep_range(100, 110); + snd_soc_update_bits(codec, WCD9XXX_CLASSH_MODE_3, + 0x02, 0x02); + snd_soc_update_bits(codec, WCD9XXX_CLASSH_MODE_2, + 0xFF, 0x1C); + if (mode == CLS_H_LOHIFI) { + snd_soc_update_bits(codec, WCD9XXX_HPH_NEW_INT_PA_MISC2, + 0x20, 0x20); + snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_HPH_LOWPOWER, + 0xF0, 0xC0); + snd_soc_update_bits(codec, WCD9XXX_HPH_PA_CTL1, + 0x0E, 0x02); + } + } else { + snd_soc_update_bits(codec, WCD9XXX_HPH_NEW_INT_PA_MISC2, + 0x20, 0x00); + snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_HPH_LOWPOWER, + 0xF0, 0x80); + snd_soc_update_bits(codec, WCD9XXX_HPH_PA_CTL1, + 0x0E, 0x06); + } +} + +static void wcd_clsh_buck_ctrl(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_info *clsh_d, + int mode, + bool enable) +{ + /* enable/disable buck */ + if ((enable && (++clsh_d->buck_users == 1)) || + (!enable && (--clsh_d->buck_users == 0))) { + snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES, + (1 << 7), (enable << 7)); + /* + * 500us sleep is required after buck enable/disable + * as per HW requirement + */ + usleep_range(500, 510); + if (mode == CLS_H_LOHIFI || mode == CLS_H_ULP || + mode == CLS_H_HIFI || mode == CLS_H_LP) + snd_soc_update_bits(codec, WCD9XXX_CLASSH_MODE_3, + 0x02, 0x00); + + snd_soc_update_bits(codec, WCD9XXX_CLASSH_MODE_2, 0xFF, 0x3A); + /* 500usec delay is needed as per HW requirement */ + usleep_range(500, 500 + WCD_USLEEP_RANGE); + } + dev_dbg(codec->dev, "%s: buck_users %d, enable %d, mode: %s\n", + __func__, clsh_d->buck_users, enable, mode_to_str(mode)); +} + +static void wcd_clsh_flyback_ctrl(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_info *clsh_d, + int mode, + bool enable) +{ + /* enable/disable flyback */ + if ((enable && (++clsh_d->flyback_users == 1)) || + (!enable && (--clsh_d->flyback_users == 0))) { + snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES, + (1 << 6), (enable << 6)); + /* + * 100us sleep is required after flyback enable/disable + * as per HW requirement + */ + usleep_range(100, 110); + snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEGDAC_CTRL_2, + 0xE0, 0xE0); + /* 500usec delay is needed as per HW requirement */ + usleep_range(500, 500 + WCD_USLEEP_RANGE); + } + dev_dbg(codec->dev, "%s: flyback_users %d, enable %d, mode: %s\n", + __func__, clsh_d->flyback_users, enable, mode_to_str(mode)); +} + +static void wcd_clsh_set_hph_mode(struct snd_soc_codec *codec, + int mode) +{ + u8 val = 0; + + switch (mode) { + case CLS_H_NORMAL: + case CLS_H_LOHIFI: + val = 0x00; + break; + case CLS_AB: + case CLS_H_ULP: + val = 0x0C; + break; + case CLS_AB_HIFI: + case CLS_H_HIFI: + val = 0x08; + break; + case CLS_H_LP: + val = 0x04; + break; + default: + dev_err(codec->dev, "%s:Invalid mode %d\n", __func__, mode); + return; + }; + + snd_soc_update_bits(codec, WCD9XXX_ANA_HPH, 0x0C, val); +} + +static void wcd_clsh_set_flyback_current(struct snd_soc_codec *codec, int mode) +{ + + snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_FLYB_BUFF, 0x0F, 0x0A); + snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_FLYB_BUFF, 0xF0, 0xA0); + /* Sleep needed to avoid click and pop as per HW requirement */ + usleep_range(100, 110); +} + +static void wcd_clsh_set_buck_regulator_mode(struct snd_soc_codec *codec, + int mode) +{ + snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES, + 0x02, 0x00); +} + +static void wcd_clsh_state_ear_aux(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_info *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); +} + +static void wcd_clsh_state_hph_aux(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_info *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); +} + +static void wcd_clsh_state_hph_ear(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_info *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); +} + +static void wcd_clsh_state_hph_st(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_info *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); +} + +static void wcd_clsh_state_hph_r(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_info *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (mode == CLS_H_NORMAL) { + dev_dbg(codec->dev, "%s: Normal mode not applicable for hph_r\n", + __func__); + return; + } + + if (is_enable) { + wcd_clsh_set_buck_regulator_mode(codec, mode); + wcd_clsh_set_flyback_mode(codec, mode); + wcd_clsh_force_iq_ctl(codec, mode, true); + wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true); + wcd_clsh_set_flyback_current(codec, mode); + wcd_clsh_set_buck_mode(codec, mode); + wcd_clsh_buck_ctrl(codec, clsh_d, mode, true); + wcd_clsh_set_hph_mode(codec, mode); + } else { + wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL); + + /* buck and flyback set to default mode and disable */ + wcd_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_force_iq_ctl(codec, CLS_H_NORMAL, false); + wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + } +} + +static void wcd_clsh_state_hph_l(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_info *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (mode == CLS_H_NORMAL) { + dev_dbg(codec->dev, "%s: Normal mode not applicable for hph_l\n", + __func__); + return; + } + + if (is_enable) { + wcd_clsh_set_buck_regulator_mode(codec, mode); + wcd_clsh_set_flyback_mode(codec, mode); + wcd_clsh_force_iq_ctl(codec, mode, true); + wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true); + wcd_clsh_set_flyback_current(codec, mode); + wcd_clsh_set_buck_mode(codec, mode); + wcd_clsh_buck_ctrl(codec, clsh_d, mode, true); + wcd_clsh_set_hph_mode(codec, mode); + } else { + wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL); + + /* set buck and flyback to Default Mode */ + wcd_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_force_iq_ctl(codec, CLS_H_NORMAL, false); + wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + } +} + +static void wcd_clsh_state_aux(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_info *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (is_enable) { + wcd_clsh_set_buck_mode(codec, mode); + wcd_clsh_set_flyback_mode(codec, mode); + wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true); + wcd_clsh_set_flyback_current(codec, mode); + wcd_clsh_buck_ctrl(codec, clsh_d, mode, true); + } else { + wcd_clsh_buck_ctrl(codec, clsh_d, mode, false); + wcd_clsh_flyback_ctrl(codec, clsh_d, mode, false); + wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + } +} + +static void wcd_clsh_state_ear(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_info *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + is_enable ? "enable" : "disable"); + + if (is_enable) { + wcd_clsh_set_buck_regulator_mode(codec, mode); + wcd_clsh_set_flyback_mode(codec, mode); + wcd_clsh_force_iq_ctl(codec, mode, true); + wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true); + wcd_clsh_set_flyback_current(codec, mode); + wcd_clsh_set_buck_mode(codec, mode); + wcd_clsh_buck_ctrl(codec, clsh_d, mode, true); + wcd_clsh_set_hph_mode(codec, mode); + } else { + wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL); + + /* set buck and flyback to Default Mode */ + wcd_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_force_iq_ctl(codec, CLS_H_NORMAL, false); + wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + } +} + +static void wcd_clsh_state_err(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_info *clsh_d, + u8 req_state, bool is_enable, int mode) +{ + char msg[128]; + + dev_err(codec->dev, + "%s Wrong request for class H state machine requested to %s %s\n", + __func__, is_enable ? "enable" : "disable", + state_to_str(req_state, msg, sizeof(msg))); +} + +/* + * Function: wcd_clsh_is_state_valid + * Params: state + * Description: + * Provides information on valid states of Class H configuration + */ +static bool wcd_clsh_is_state_valid(u8 state) +{ + switch (state) { + case WCD_CLSH_STATE_IDLE: + case WCD_CLSH_STATE_EAR: + case WCD_CLSH_STATE_HPHL: + case WCD_CLSH_STATE_HPHR: + case WCD_CLSH_STATE_HPH_ST: + case WCD_CLSH_STATE_AUX: + case WCD_CLSH_STATE_HPHL_AUX: + case WCD_CLSH_STATE_HPHR_AUX: + case WCD_CLSH_STATE_HPH_ST_AUX: + case WCD_CLSH_STATE_EAR_AUX: + return true; + default: + return false; + }; +} + +/* + * Function: wcd_cls_h_fsm + * Params: codec, cdc_clsh_d, req_state, req_type, clsh_event + * Description: + * This function handles PRE DAC and POST DAC conditions of different devices + * and updates class H configuration of different combination of devices + * based on validity of their states. cdc_clsh_d will contain current + * class h state information + */ +void wcd_cls_h_fsm(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_info *cdc_clsh_d, + u8 clsh_event, u8 req_state, + int int_mode) +{ + u8 old_state, new_state; + char msg0[128], msg1[128]; + + switch (clsh_event) { + case WCD_CLSH_EVENT_PRE_DAC: + old_state = cdc_clsh_d->state; + new_state = old_state | req_state; + + if (!wcd_clsh_is_state_valid(new_state)) { + dev_err(codec->dev, + "%s: Class-H not a valid new state: %s\n", + __func__, + state_to_str(new_state, msg0, sizeof(msg0))); + return; + } + if (new_state == old_state) { + dev_err(codec->dev, + "%s: Class-H already in requested state: %s\n", + __func__, + state_to_str(new_state, msg0, sizeof(msg0))); + return; + } + cdc_clsh_d->state = new_state; + wcd_clsh_set_int_mode(cdc_clsh_d, req_state, int_mode); + (*clsh_state_fp[new_state]) (codec, cdc_clsh_d, req_state, + CLSH_REQ_ENABLE, int_mode); + dev_dbg(codec->dev, + "%s: ClassH state transition from %s to %s\n", + __func__, state_to_str(old_state, msg0, sizeof(msg0)), + state_to_str(cdc_clsh_d->state, msg1, sizeof(msg1))); + break; + case WCD_CLSH_EVENT_POST_PA: + old_state = cdc_clsh_d->state; + new_state = old_state & (~req_state); + if (new_state < NUM_CLSH_STATES) { + if (!wcd_clsh_is_state_valid(old_state)) { + dev_err(codec->dev, + "%s:Invalid old state:%s\n", + __func__, + state_to_str(old_state, msg0, + sizeof(msg0))); + return; + } + if (new_state == old_state) { + dev_err(codec->dev, + "%s: Class-H already in requested state: %s\n", + __func__, + state_to_str(new_state, msg0, + sizeof(msg0))); + return; + } + (*clsh_state_fp[old_state]) (codec, cdc_clsh_d, + req_state, CLSH_REQ_DISABLE, + int_mode); + cdc_clsh_d->state = new_state; + wcd_clsh_set_int_mode(cdc_clsh_d, req_state, CLS_NONE); + dev_dbg(codec->dev, "%s: ClassH state transition from %s to %s\n", + __func__, state_to_str(old_state, msg0, + sizeof(msg0)), + state_to_str(cdc_clsh_d->state, msg1, + sizeof(msg1))); + } + break; + }; +} +EXPORT_SYMBOL(wcd_cls_h_fsm); + +/* + * wcd_cls_h_init: Called to init clsh info + * + * @clsh: pointer for clsh state information. + */ +void wcd_cls_h_init(struct wcd_clsh_cdc_info *clsh) +{ + int i; + + clsh->state = WCD_CLSH_STATE_IDLE; + + for (i = 0; i < NUM_CLSH_STATES; i++) + clsh_state_fp[i] = wcd_clsh_state_err; + + clsh_state_fp[WCD_CLSH_STATE_EAR] = wcd_clsh_state_ear; + clsh_state_fp[WCD_CLSH_STATE_HPHL] = wcd_clsh_state_hph_l; + clsh_state_fp[WCD_CLSH_STATE_HPHR] = wcd_clsh_state_hph_r; + clsh_state_fp[WCD_CLSH_STATE_HPH_ST] = wcd_clsh_state_hph_st; + clsh_state_fp[WCD_CLSH_STATE_AUX] = wcd_clsh_state_aux; + clsh_state_fp[WCD_CLSH_STATE_HPHL_AUX] = wcd_clsh_state_hph_aux; + clsh_state_fp[WCD_CLSH_STATE_HPHR_AUX] = wcd_clsh_state_hph_aux; + clsh_state_fp[WCD_CLSH_STATE_HPH_ST_AUX] = + wcd_clsh_state_hph_aux; + clsh_state_fp[WCD_CLSH_STATE_EAR_AUX] = wcd_clsh_state_ear_aux; + clsh_state_fp[WCD_CLSH_STATE_HPHL_EAR] = wcd_clsh_state_hph_ear; + clsh_state_fp[WCD_CLSH_STATE_HPHR_EAR] = wcd_clsh_state_hph_ear; + clsh_state_fp[WCD_CLSH_STATE_HPH_ST_EAR] = wcd_clsh_state_hph_ear; + /* Set interpolaotr modes to NONE */ + wcd_clsh_set_int_mode(clsh, WCD_CLSH_STATE_EAR, CLS_NONE); + wcd_clsh_set_int_mode(clsh, WCD_CLSH_STATE_HPHL, CLS_NONE); + wcd_clsh_set_int_mode(clsh, WCD_CLSH_STATE_HPHR, CLS_NONE); + wcd_clsh_set_int_mode(clsh, WCD_CLSH_STATE_AUX, CLS_NONE); + clsh->flyback_users = 0; + clsh->buck_users = 0; +} +EXPORT_SYMBOL(wcd_cls_h_init); + +MODULE_DESCRIPTION("WCD Class-H Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/wcd-clsh.h b/asoc/codecs/wcd-clsh.h new file mode 100644 index 000000000000..df305bcf7aa1 --- /dev/null +++ b/asoc/codecs/wcd-clsh.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _WCD_CLSH +#define _WCD_CLSH + +#include + +#define WCD_CLSH_STRINGIFY(s) __stringify(s) +#define CLSH_REQ_ENABLE true +#define CLSH_REQ_DISABLE false + +#define WCD_CLSH_EVENT_PRE_DAC 0x01 +#define WCD_CLSH_EVENT_POST_PA 0x02 +/* + * Basic states for Class H state machine. + * represented as a bit mask within a u8 data type + * bit 0: EAR mode + * bit 1: HPH Left mode + * bit 2: HPH Right mode + * bit 3: AUX mode + */ +#define WCD_CLSH_STATE_IDLE 0x00 +#define WCD_CLSH_STATE_EAR (0x01 << 0) +#define WCD_CLSH_STATE_HPHL (0x01 << 1) +#define WCD_CLSH_STATE_HPHR (0x01 << 2) +#define WCD_CLSH_STATE_AUX (0x01 << 3) + +/* + * Though number of CLSH states is 4, max state should be 5 + * because state array index starts from 1. + */ +#define WCD_CLSH_STATE_MAX 5 +#define NUM_CLSH_STATES (0x01 << WCD_CLSH_STATE_MAX) + +/* Derived State: Bits 1 and 2 should be set for Headphone stereo */ +#define WCD_CLSH_STATE_HPH_ST (WCD_CLSH_STATE_HPHL | \ + WCD_CLSH_STATE_HPHR) + +#define WCD_CLSH_STATE_HPHL_AUX (WCD_CLSH_STATE_HPHL | \ + WCD_CLSH_STATE_AUX) +#define WCD_CLSH_STATE_HPHR_AUX (WCD_CLSH_STATE_HPHR | \ + WCD_CLSH_STATE_AUX) +#define WCD_CLSH_STATE_HPH_ST_AUX (WCD_CLSH_STATE_HPH_ST | \ + WCD_CLSH_STATE_AUX) +#define WCD_CLSH_STATE_EAR_AUX (WCD_CLSH_STATE_EAR | \ + WCD_CLSH_STATE_AUX) +#define WCD_CLSH_STATE_HPHL_EAR (WCD_CLSH_STATE_HPHL | \ + WCD_CLSH_STATE_EAR) +#define WCD_CLSH_STATE_HPHR_EAR (WCD_CLSH_STATE_HPHR | \ + WCD_CLSH_STATE_EAR) +#define WCD_CLSH_STATE_HPH_ST_EAR (WCD_CLSH_STATE_HPH_ST | \ + WCD_CLSH_STATE_EAR) + +enum { + CLS_H_NORMAL = 0, /* Class-H Default */ + CLS_H_HIFI, /* Class-H HiFi */ + CLS_H_LP, /* Class-H Low Power */ + CLS_AB, /* Class-AB Low HIFI*/ + CLS_H_LOHIFI, /* LoHIFI */ + CLS_H_ULP, /* Ultra Low power */ + CLS_AB_HIFI, /* Class-AB */ + CLS_NONE, /* None of the above modes */ +}; + +/* Class H data that the codec driver will maintain */ +struct wcd_clsh_cdc_info { + u8 state; + int flyback_users; + int buck_users; + int interpolator_modes[WCD_CLSH_STATE_MAX]; +}; + +#ifdef CONFIG_SND_SOC_WCD9XXX_V2 +extern void wcd_cls_h_fsm(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_info *cdc_clsh_d, + u8 clsh_event, u8 req_state, + int int_mode); + +extern void wcd_cls_h_init(struct wcd_clsh_cdc_info *clsh); +#else +extern void wcd_cls_h_fsm(struct snd_soc_codec *codec, + struct wcd_clsh_cdc_info *cdc_clsh_d, + u8 clsh_event, u8 req_state, + int int_mode) +{ +} + +extern void wcd_cls_h_init(struct wcd_clsh_cdc_info *clsh) +{ +} +#endif /* CONFIG_SND_SOC_WCD9XXX_V2 */ + +#endif diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index eb2de9d69efb..c11baa9abdfe 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -13,6 +13,7 @@ #ifndef _WCD937X_INTERNAL_H #define _WCD937X_INTERNAL_H +#include "../wcd-clsh.h" #include "../wcd-mbhc-v2.h" #include "asoc/wcd-irq.h" #include "wcd937x-mbhc.h" @@ -54,6 +55,8 @@ struct wcd937x_priv { s32 dmic_0_1_clk_cnt; s32 dmic_2_3_clk_cnt; s32 dmic_4_5_clk_cnt; + /* class h specific info */ + struct wcd_clsh_cdc_info clsh_info; /* mbhc module */ struct wcd937x_mbhc *mbhc; diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 485d328389d3..02c952b756f2 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -297,7 +297,6 @@ static int wcd937x_rx_connect_port(struct snd_soc_codec *codec, static int wcd937x_rx_clk_enable(struct snd_soc_codec *codec) { - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); if (wcd937x->rx_clk_cnt == 0) { @@ -324,10 +323,12 @@ static int wcd937x_rx_clk_disable(struct snd_soc_codec *codec) { struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + if (wcd937x->rx_clk_cnt == 0) { + dev_dbg(wcd937x->dev, "%s:clk already disabled\n", __func__); + return 0; + } wcd937x->rx_clk_cnt--; if (wcd937x->rx_clk_cnt == 0) { - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x40, 0x00); - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x80, 0x00); snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x01, 0x00); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x00); @@ -368,6 +369,7 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int hph_mode = wcd937x->hph_mode; int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, @@ -384,8 +386,14 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, 0x80, 0x00); break; case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, - 0x0F, 0x02); + if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI) + snd_soc_update_bits(codec, + WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, + 0x0F, 0x02); + else if (hph_mode == CLS_H_LOHIFI) + snd_soc_update_bits(codec, + WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, + 0x0F, 0x06); if (wcd937x->comp1_enable) { snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, @@ -402,8 +410,15 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, usleep_range(5000, 5010); snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); + wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_HPHL, + hph_mode); break; case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, + WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, + 0x0F, 0x01); ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, false); @@ -419,6 +434,7 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int hph_mode = wcd937x->hph_mode; int ret = 0; @@ -436,8 +452,14 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, 0x80, 0x00); break; case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, - 0x0F, 0x02); + if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI) + snd_soc_update_bits(codec, + WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, + 0x0F, 0x02); + else if (hph_mode == CLS_H_LOHIFI) + snd_soc_update_bits(codec, + WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, + 0x0F, 0x06); if (wcd937x->comp2_enable) { snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, @@ -454,8 +476,15 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, usleep_range(5000, 5010); snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); + wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_HPHR, + hph_mode); break; case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, + WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, + 0x0F, 0x01); ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, false); @@ -471,6 +500,7 @@ static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int hph_mode = wcd937x->hph_mode; int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, @@ -483,11 +513,29 @@ static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, 0x04, 0x04); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x01); + if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI) + snd_soc_update_bits(codec, + WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, + 0x0F, 0x02); + else if (hph_mode == CLS_H_LOHIFI) + snd_soc_update_bits(codec, + WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, + 0x0F, 0x06); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x02); usleep_range(5000, 5010); + wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_EAR, + hph_mode); + break; case SND_SOC_DAPM_POST_PMD: + if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_LOHIFI || + hph_mode == CLS_H_HIFI) + snd_soc_update_bits(codec, + WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, + 0x0F, 0x01); ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, false); @@ -503,6 +551,7 @@ static int wcd937x_codec_aux_dac_event(struct snd_soc_dapm_widget *w, { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int hph_mode = wcd937x->hph_mode; int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, @@ -517,6 +566,11 @@ static int wcd937x_codec_aux_dac_event(struct snd_soc_dapm_widget *w, 0x04, 0x04); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_AUX_GAIN_CTL, 0x01, 0x01); + wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_AUX, + hph_mode); + break; case SND_SOC_DAPM_POST_PMD: ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, @@ -538,6 +592,7 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); int ret = 0; + int hph_mode = wcd937x->hph_mode; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -554,8 +609,9 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, usleep_range(7000, 7010); snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02); - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, - 0x02, 0x02); + if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, + 0x02, 0x02); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -576,6 +632,10 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, WCD_EVENT_POST_HPHR_PA_OFF, &wcd937x->mbhc->wcd_mbhc); snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x10, 0x00); + wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + WCD_CLSH_EVENT_POST_PA, + WCD_CLSH_STATE_HPHR, + hph_mode); break; }; return ret; @@ -588,6 +648,7 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); int ret = 0; + int hph_mode = wcd937x->hph_mode; switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -601,8 +662,9 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, usleep_range(7000, 7010); snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02); - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, - 0x02, 0x02); + if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, + 0x02, 0x02); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -623,6 +685,10 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, WCD_EVENT_POST_HPHL_PA_OFF, &wcd937x->mbhc->wcd_mbhc); snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x20, 0x00); + wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + WCD_CLSH_EVENT_POST_PA, + WCD_CLSH_STATE_HPHL, + hph_mode); break; }; return ret; @@ -634,6 +700,7 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int hph_mode = wcd937x->hph_mode; int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, @@ -641,19 +708,15 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, - 0x80, 0x80); - usleep_range(500, 510); - snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, 0xFF, 0x3A); - usleep_range(500, 510); ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, true); break; case SND_SOC_DAPM_POST_PMU: usleep_range(1000, 1010); - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, - 0x20, 0x20); + if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, + 0x02, 0x02); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -668,6 +731,10 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMD: usleep_range(1000, 1010); usleep_range(1000, 1010); + wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + WCD_CLSH_EVENT_POST_PA, + WCD_CLSH_STATE_AUX, + hph_mode); break; }; return ret; @@ -679,6 +746,7 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int hph_mode = wcd937x->hph_mode; int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, @@ -686,19 +754,15 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, - 0x08, 0x08); - usleep_range(500, 510); - snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, 0xFF, 0x3A); - usleep_range(500, 510); ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, true); break; case SND_SOC_DAPM_POST_PMU: usleep_range(6000, 6010); - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, - 0x02, 0x02); + if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) + snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, + 0x02, 0x02); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -712,16 +776,44 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: usleep_range(7000, 7010); + wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + WCD_CLSH_EVENT_POST_PA, + WCD_CLSH_STATE_EAR, + hph_mode); break; }; return ret; } +static int wcd937x_enable_clsh(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + int mode = wcd937x->hph_mode; + int ret = 0; + + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + if (mode == CLS_H_LOHIFI || mode == CLS_H_ULP || + mode == CLS_H_HIFI || mode == CLS_H_LP) { + wcd937x_rx_connect_port(codec, CLSH, + SND_SOC_DAPM_EVENT_ON(event)); + if (SND_SOC_DAPM_EVENT_OFF(event)) + ret = swr_slvdev_datapath_control( + wcd937x->rx_swr_dev, + wcd937x->rx_swr_dev->dev_num, + false); + } + return ret; +} + static int wcd937x_enable_rx1(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); @@ -730,26 +822,6 @@ static int wcd937x_enable_rx1(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEG_CTRL_4, - 0xF0, 0x80); - snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEGDAC_CTRL_2, - 0xE0, 0xA0); - snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_3, - 0x02, 0x02); - snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, - 0xFF, 0x1C); - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, - 0x40, 0x40); - usleep_range(100, 110); - snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEGDAC_CTRL_2, - 0xE0, 0xE0); - usleep_range(100, 110); - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, - 0x80, 0x80); - usleep_range(500, 510); - snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, 0xFF, 0x3A); - usleep_range(500, 510); - wcd937x_rx_connect_port(codec, HPH_L, true); if (wcd937x->comp1_enable) wcd937x_rx_connect_port(codec, COMP_L, true); @@ -765,6 +837,7 @@ static int wcd937x_enable_rx1(struct snd_soc_dapm_widget *w, }; return 0; } + static int wcd937x_enable_rx2(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -776,24 +849,6 @@ static int wcd937x_enable_rx2(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEG_CTRL_4, - 0xF0, 0x80); - snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEGDAC_CTRL_2, - 0xE0, 0xA0); - snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_3, 0x02, 0x02); - snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, 0xFF, 0x1C); - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, - 0x40, 0x40); - usleep_range(100, 110); - snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEGDAC_CTRL_2, - 0xE0, 0xE0); - usleep_range(100, 110); - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, - 0x80, 0x80); - usleep_range(500, 510); - snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, 0xFF, 0x3A); - usleep_range(500, 510); - wcd937x_rx_connect_port(codec, HPH_R, true); if (wcd937x->comp2_enable) wcd937x_rx_connect_port(codec, COMP_R, true); @@ -823,16 +878,6 @@ static int wcd937x_enable_rx3(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEG_CTRL_2, - 0xE0, 0xA0); - snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_3, 0x02, 0x02); - snd_soc_update_bits(codec, WCD937X_CLASSH_MODE_2, 0xFF, 0x1C); - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, - 0x40, 0x40); - usleep_range(100, 110); - snd_soc_update_bits(codec, WCD937X_FLYBACK_VNEG_CTRL_2, - 0xE0, 0xE0); - usleep_range(100, 110); wcd937x_rx_connect_port(codec, LO, true); break; case SND_SOC_DAPM_POST_PMD: @@ -1589,6 +1634,10 @@ static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = { wcd937x_codec_enable_vdd_buck, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("CLS_H_PORT", SND_SOC_NOPM, 0, 0, + wcd937x_enable_clsh, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + /*rx widgets*/ SND_SOC_DAPM_PGA_E("EAR PGA", WCD937X_ANA_EAR, 7, 0, NULL, 0, wcd937x_codec_enable_ear_pa, @@ -1776,6 +1825,11 @@ static const struct snd_soc_dapm_route wcd937x_audio_map[] = { {"HPHR", NULL, "VDD_BUCK"}, {"HPHL", NULL, "VDD_BUCK"}, {"AUX", NULL, "VDD_BUCK"}, + + {"EAR", NULL, "CLS_H_PORT"}, + {"HPHR", NULL, "CLS_H_PORT"}, + {"HPHL", NULL, "CLS_H_PORT"}, + {"AUX", NULL, "CLS_H_PORT"}, }; static const struct snd_soc_dapm_route wcd9375_audio_map[] = { @@ -1948,6 +2002,7 @@ static int wcd937x_soc_codec_probe(struct snd_soc_codec *codec) snd_soc_dapm_ignore_suspend(dapm, "HPHR"); snd_soc_dapm_sync(dapm); + wcd_cls_h_init(&wcd937x->clsh_info); wcd937x_init_reg(codec); if (wcd937x->variant == WCD9375_VARIANT) { diff --git a/include/asoc/wcd9xxx_registers.h b/include/asoc/wcd9xxx_registers.h new file mode 100644 index 000000000000..928dfcc56d56 --- /dev/null +++ b/include/asoc/wcd9xxx_registers.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _WCD9XXX_REGISTERS_H +#define _WCD9XXX_REGISTERS_H + +#define WCD9XXX_BASE_ADDRESS 0x3000 + +#define WCD9XXX_ANA_RX_SUPPLIES (WCD9XXX_BASE_ADDRESS+0x008) +#define WCD9XXX_ANA_HPH (WCD9XXX_BASE_ADDRESS+0x009) +#define WCD9XXX_CLASSH_MODE_2 (WCD9XXX_BASE_ADDRESS+0x098) +#define WCD9XXX_CLASSH_MODE_3 (WCD9XXX_BASE_ADDRESS+0x099) +#define WCD9XXX_FLYBACK_VNEG_CTRL_4 (WCD9XXX_BASE_ADDRESS+0x0A8) +#define WCD9XXX_FLYBACK_VNEGDAC_CTRL_2 (WCD9XXX_BASE_ADDRESS+0x0AF) +#define WCD9XXX_RX_BIAS_HPH_LOWPOWER (WCD9XXX_BASE_ADDRESS+0x0BF) +#define WCD9XXX_RX_BIAS_FLYB_BUFF (WCD9XXX_BASE_ADDRESS+0x0C7) +#define WCD9XXX_HPH_PA_CTL1 (WCD9XXX_BASE_ADDRESS+0x0D1) +#define WCD9XXX_HPH_NEW_INT_PA_MISC2 (WCD9XXX_BASE_ADDRESS+0x138) + +#endif -- GitLab From 990c70b0049de363bb33c5d30c852221c2dedae3 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 9 Nov 2018 23:15:09 +0530 Subject: [PATCH 0636/1645] soc: swr-mstr: Update hparams for all swr master ports Need to specify hstart and hstop bit fields even if those are not used in frameshape for given port. Soundwire master register config needs to set as 0x0, 0xF for hstart and hstop for those ports. CRs-Fixed: 2333434 Change-Id: I78e103a3d4c9085ea14884691d5df3f35fa7a754 Signed-off-by: Laxminath Kasam --- soc/swr-mstr-ctrl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 80dd5e8d3f76..dc105f20d3ac 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -41,6 +41,8 @@ ((reg) | ((id) << 16) | ((dev) << 20) | ((data) << 24)) #define SWR_INVALID_PARAM 0xFF +#define SWR_HSTOP_MAX_VAL 0xF +#define SWR_HSTART_MIN_VAL 0x0 #define SWRM_INTERRUPT_STATUS_MASK 0x1FDFD /* pm runtime auto suspend timer in msecs */ @@ -926,6 +928,10 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank) reg[len] = SWRM_DP_PORT_HCTRL_BANK(i + 1, bank); hparams = (mport->hstart << 4) | mport->hstop; val[len++] = hparams; + } else { + reg[len] = SWRM_DP_PORT_HCTRL_BANK(i + 1, bank); + hparams = (SWR_HSTOP_MAX_VAL << 4) | SWR_HSTART_MIN_VAL; + val[len++] = hparams; } if (mport->blk_pack_mode != SWR_INVALID_PARAM) { reg[len] = SWRM_DP_BLOCK_CTRL3_BANK(i + 1, bank); -- GitLab From 0db4801f4dcaeb65a7b2ec0e8723f94221625611 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Fri, 9 Nov 2018 11:01:23 +0530 Subject: [PATCH 0637/1645] soc: swr-mstr: Remove master access from slave api The read/write api exposed by soundwire master is intended to be used only for accessing soundwire slave registers. Remove master access from the api, to avoid invalid access due to slaves sending devnum as zero incorrectly. Change-Id: Ia00179f87908f95f03ef027630d178016affdb18 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index df373abcc4db..d6ebafd76bc1 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -534,6 +534,10 @@ static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr, dev_err(&master->dev, "%s: swrm is NULL\n", __func__); return -EINVAL; } + if (!dev_num) { + dev_err(&master->dev, "%s: invalid slave dev num\n", __func__); + return -EINVAL; + } mutex_lock(&swrm->devlock); if (!swrm->dev_up) { mutex_unlock(&swrm->devlock); @@ -542,11 +546,7 @@ static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr, mutex_unlock(&swrm->devlock); pm_runtime_get_sync(swrm->dev); - if (dev_num) - ret = swrm_cmd_fifo_rd_cmd(swrm, &val, dev_num, 0, reg_addr, - len); - else - val = swr_master_read(swrm, reg_addr); + ret = swrm_cmd_fifo_rd_cmd(swrm, &val, dev_num, 0, reg_addr, len); if (!ret) *reg_val = (u8)val; @@ -567,6 +567,10 @@ static int swrm_write(struct swr_master *master, u8 dev_num, u16 reg_addr, dev_err(&master->dev, "%s: swrm is NULL\n", __func__); return -EINVAL; } + if (!dev_num) { + dev_err(&master->dev, "%s: invalid slave dev num\n", __func__); + return -EINVAL; + } mutex_lock(&swrm->devlock); if (!swrm->dev_up) { mutex_unlock(&swrm->devlock); @@ -575,10 +579,7 @@ static int swrm_write(struct swr_master *master, u8 dev_num, u16 reg_addr, mutex_unlock(&swrm->devlock); pm_runtime_get_sync(swrm->dev); - if (dev_num) - ret = swrm_cmd_fifo_wr_cmd(swrm, reg_val, dev_num, 0, reg_addr); - else - swr_master_write(swrm, reg_addr, reg_val); + ret = swrm_cmd_fifo_wr_cmd(swrm, reg_val, dev_num, 0, reg_addr); pm_runtime_put_autosuspend(swrm->dev); pm_runtime_mark_last_busy(swrm->dev); -- GitLab From 0730ecfaa0bb1151b63bbc6a713afa432d5c73be Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Mon, 12 Nov 2018 20:18:50 +0530 Subject: [PATCH 0638/1645] asoc: wcd937x: Handle button press before release interrupt If button press and release interrupts occur at same time processing button release first would treat the button event as fake, as it is not preceeded with press event. Hence process button press before button release in irq driver. Change-Id: I9413def87537502c470236a3948a21be47c479bc Signed-off-by: Ramprasad Katkam --- asoc/codecs/wcd937x/internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index eb2de9d69efb..2f222777d34e 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -135,8 +135,8 @@ enum { enum { /* INTR_CTRL_INT_MASK_0 */ - WCD937X_IRQ_MBHC_BUTTON_RELEASE_DET = 0, - WCD937X_IRQ_MBHC_BUTTON_PRESS_DET, + WCD937X_IRQ_MBHC_BUTTON_PRESS_DET = 0, + WCD937X_IRQ_MBHC_BUTTON_RELEASE_DET, WCD937X_IRQ_MBHC_ELECT_INS_REM_DET, WCD937X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, WCD937X_IRQ_MBHC_SW_DET, -- GitLab From c034fadb2c637fdfa0a50186a0802c5394b335f2 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 12 Nov 2018 22:55:11 +0530 Subject: [PATCH 0639/1645] soc: swr-mstr: add support for hardware wakeup interrupt Add changes to register hardware wake up interrupt from soundwire data line or ipc wake up interrupt from LPASS. Change-Id: Ibe4277db79aa62f34e9b325ae656b3f3fa7a2bcb Signed-off-by: Aditya Bavanari --- include/soc/swr-wcd.h | 1 + soc/swr-mstr-ctrl.c | 103 ++++++++++++++++++++++++++++++++++++------ soc/swr-mstr-ctrl.h | 5 +- 3 files changed, 93 insertions(+), 16 deletions(-) diff --git a/include/soc/swr-wcd.h b/include/soc/swr-wcd.h index 8ea8616572a4..7eaad27562d2 100644 --- a/include/soc/swr-wcd.h +++ b/include/soc/swr-wcd.h @@ -26,6 +26,7 @@ enum { SWR_CLK_FREQ, SWR_DEVICE_SSR_DOWN, SWR_DEVICE_SSR_UP, + SWR_REGISTER_WAKE_IRQ, }; struct swr_mstr_port { diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index df373abcc4db..64da45700409 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1414,6 +1414,32 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) return ret; } +static irqreturn_t swrm_wakeup_interrupt(int irq, void *dev) +{ + struct swr_mstr_ctrl *swrm = dev; + int ret = IRQ_HANDLED; + + if (!swrm || !(swrm->dev)) { + pr_err("%s: swrm or dev is null\n", __func__); + return IRQ_NONE; + } + mutex_lock(&swrm->devlock); + if (!swrm->dev_up) { + if (swrm->wake_irq > 0) + disable_irq_nosync(swrm->wake_irq); + mutex_unlock(&swrm->devlock); + return ret; + } + mutex_unlock(&swrm->devlock); + if (swrm->wake_irq > 0) + disable_irq_nosync(swrm->wake_irq); + pm_runtime_get_sync(swrm->dev); + pm_runtime_mark_last_busy(swrm->dev); + pm_runtime_put_autosuspend(swrm->dev); + + return ret; +} + static void swrm_wakeup_work(struct work_struct *work) { struct swr_mstr_ctrl *swrm; @@ -1585,8 +1611,8 @@ static int swrm_event_notify(struct notifier_block *self, schedule_work(&(swrm->dc_presence_work)); break; case SWR_WAKE_IRQ_EVENT: - if (swrm->wakeup_req && !swrm->wakeup_triggered) { - swrm->wakeup_triggered = true; + if (swrm->ipc_wakeup && !swrm->ipc_wakeup_triggered) { + swrm->ipc_wakeup_triggered = true; schedule_work(&swrm->wakeup_work); } break; @@ -1762,6 +1788,8 @@ static int swrm_probe(struct platform_device *pdev) swrm->mclk_freq = MCLK_FREQ; swrm->dev_up = true; swrm->state = SWR_MSTR_UP; + swrm->ipc_wakeup = false; + swrm->ipc_wakeup_triggered = false; init_completion(&swrm->reset); init_completion(&swrm->broadcast); init_completion(&swrm->clk_off_complete); @@ -1789,11 +1817,6 @@ static int swrm_probe(struct platform_device *pdev) } } - if (of_property_read_u32(swrm->dev->of_node, - "qcom,swr-wakeup-required", &swrm->wakeup_req)) { - swrm->wakeup_req = false; - } - if (swrm->reg_irq) { ret = swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, SWR_IRQ_REGISTER); @@ -1903,6 +1926,9 @@ static int swrm_remove(struct platform_device *pdev) swrm, SWR_IRQ_FREE); else if (swrm->irq) free_irq(swrm->irq, swrm); + else if (swrm->wake_irq > 0) + free_irq(swrm->wake_irq, swrm); + pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); swr_unregister_master(&swrm->master); @@ -1944,9 +1970,10 @@ static int swrm_runtime_resume(struct device *dev) if ((swrm->state == SWR_MSTR_DOWN) || (swrm->state == SWR_MSTR_SSR && swrm->dev_up)) { - if (swrm->clk_stop_mode0_supp && swrm->wakeup_req) { - msm_aud_evt_blocking_notifier_call_chain( - SWR_WAKE_IRQ_DEREGISTER, (void *)swrm); + if (swrm->clk_stop_mode0_supp) { + if (swrm->ipc_wakeup) + msm_aud_evt_blocking_notifier_call_chain( + SWR_WAKE_IRQ_DEREGISTER, (void *)swrm); } if (swrm_clk_request(swrm, true)) @@ -2025,10 +2052,14 @@ static int swrm_runtime_suspend(struct device *dev) } swrm_clk_request(swrm, false); - if (swrm->clk_stop_mode0_supp && swrm->wakeup_req) { - msm_aud_evt_blocking_notifier_call_chain( - SWR_WAKE_IRQ_REGISTER, (void *)swrm); - swrm->wakeup_triggered = false; + if (swrm->clk_stop_mode0_supp) { + if (swrm->wake_irq > 0) { + enable_irq(swrm->wake_irq); + } else if (swrm->ipc_wakeup) { + msm_aud_evt_blocking_notifier_call_chain( + SWR_WAKE_IRQ_REGISTER, (void *)swrm); + swrm->ipc_wakeup_triggered = false; + } } } @@ -2064,6 +2095,35 @@ static int swrm_device_down(struct device *dev) return 0; } +int swrm_register_wake_irq(struct swr_mstr_ctrl *swrm) +{ + int ret = 0; + + if (!swrm->ipc_wakeup) { + swrm->wake_irq = platform_get_irq_byname(swrm->pdev, + "swr_wake_irq"); + if (swrm->wake_irq < 0) { + dev_err(swrm->dev, + "%s() error getting wake irq handle: %d\n", + __func__, swrm->wake_irq); + return -EINVAL; + } + + ret = request_threaded_irq(swrm->wake_irq, NULL, + swrm_wakeup_interrupt, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "swr_wake_irq", swrm); + if (ret) { + dev_err(swrm->dev, "%s: Failed to request irq %d\n", + __func__, ret); + return -EINVAL; + } + /* Disable wake irq - enable it after clock stop */ + disable_irq(swrm->wake_irq); + } + return ret; +} + /** * swrm_wcd_notify - parent device can notify to soundwire master through * this function @@ -2181,6 +2241,21 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) mutex_unlock(&swrm->mlock); } break; + case SWR_REGISTER_WAKE_IRQ: + if (!data) { + dev_err(swrm->dev, "%s: reg wake irq data is NULL\n", + __func__); + ret = -EINVAL; + } else { + mutex_lock(&swrm->mlock); + swrm->ipc_wakeup = *(u32 *)data; + ret = swrm_register_wake_irq(swrm); + if (ret) + dev_err(swrm->dev, "%s: register wake_irq failed\n", + __func__); + mutex_unlock(&swrm->mlock); + } + break; default: dev_err(swrm->dev, "%s: swr master unknown id %d\n", __func__, id); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 4a40fa339e7e..b3e358a0d944 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -131,6 +131,7 @@ struct swr_mstr_ctrl { int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq, void *data), void *swr_handle, int type); int irq; + int wake_irq; int version; int mclk_freq; u32 num_dev; @@ -152,9 +153,9 @@ struct swr_mstr_ctrl { int swr_irq; u32 clk_stop_mode0_supp; struct work_struct wakeup_work; - u32 wakeup_req; + u32 ipc_wakeup; bool dev_up; - bool wakeup_triggered; + bool ipc_wakeup_triggered; }; #endif /* _SWR_WCD_CTRL_H */ -- GitLab From c4e96121c5c917b8d44c037f46ce597208853369 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 14 Nov 2018 14:46:38 +0530 Subject: [PATCH 0640/1645] asoc: bolero: Add support to register wake irq Add reg_wake_irq macro callback and issue an event from Tx macro to Tx sound wire master instance in order to register for wake irq and to handle the ipc wake up interrupt. Change-Id: Iefddc1f85173ce267c0b00c9d06be3a4a2fe29fe Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/bolero-cdc.c | 37 +++++++++++++++++++++++++++++++++ asoc/codecs/bolero/bolero-cdc.h | 11 +++++++++- asoc/codecs/bolero/tx-macro.c | 19 +++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index d6a196b6c830..a0822ebdec0c 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -344,6 +344,9 @@ int bolero_register_macro(struct device *dev, u16 macro_id, priv->macro_params[macro_id].dev = dev; priv->current_mclk_mux_macro[macro_id] = bolero_mclk_mux_tbl[macro_id][MCLK_MUX0]; + if (macro_id == TX_MACRO) + priv->macro_params[macro_id].reg_wake_irq = ops->reg_wake_irq; + priv->num_dais += ops->num_dais; priv->num_macros_registered++; priv->macros_supported[macro_id] = true; @@ -403,6 +406,9 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) priv->macro_params[macro_id].mclk_fn = NULL; priv->macro_params[macro_id].event_handler = NULL; priv->macro_params[macro_id].dev = NULL; + if (macro_id == TX_MACRO) + priv->macro_params[macro_id].reg_wake_irq = NULL; + priv->num_dais -= priv->macro_params[macro_id].num_dais; priv->num_macros_registered--; @@ -663,6 +669,37 @@ int bolero_info_create_codec_entry(struct snd_info_entry *codec_root, } EXPORT_SYMBOL(bolero_info_create_codec_entry); +/** + * bolero_register_wake_irq - Register wake irq of Tx macro + * + * @codec: codec ptr. + * @ipc_wakeup: bool to identify ipc_wakeup to be used or HW interrupt line. + * + * Return: 0 on success or negative error code on failure. + */ +int bolero_register_wake_irq(struct snd_soc_codec *codec, u32 ipc_wakeup) +{ + struct bolero_priv *priv = NULL; + + if (!codec) + return -EINVAL; + + priv = snd_soc_codec_get_drvdata(codec); + if (!priv) + return -EINVAL; + + if (!bolero_is_valid_codec_dev(priv->dev)) { + dev_err(codec->dev, "%s: invalid codec\n", __func__); + return -EINVAL; + } + + if (priv->macro_params[TX_MACRO].reg_wake_irq) + priv->macro_params[TX_MACRO].reg_wake_irq(codec, ipc_wakeup); + + return 0; +} +EXPORT_SYMBOL(bolero_register_wake_irq); + static int bolero_soc_codec_probe(struct snd_soc_codec *codec) { struct bolero_priv *priv = dev_get_drvdata(codec->dev); diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index aa524918e64f..36d17f5ab521 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -45,7 +45,8 @@ enum { BOLERO_MACRO_EVT_IMPED_FALSE, /* for imped false */ BOLERO_MACRO_EVT_SSR_DOWN, BOLERO_MACRO_EVT_SSR_UP, - BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET + BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET, + BOLERO_MACRO_EVT_REG_WAKE_IRQ }; struct macro_ops { @@ -57,6 +58,7 @@ struct macro_ops { int (*mclk_fn)(struct device *dev, bool enable); int (*event_handler)(struct snd_soc_codec *codec, u16 event, u32 data); + int (*reg_wake_irq)(struct snd_soc_codec *codec, u32 data); char __iomem *io_base; }; @@ -71,6 +73,7 @@ int bolero_request_clock(struct device *dev, u16 macro_id, int bolero_info_create_codec_entry( struct snd_info_entry *codec_root, struct snd_soc_codec *codec); +int bolero_register_wake_irq(struct snd_soc_codec *codec, u32 data); void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n); #else static inline int bolero_register_macro(struct device *dev, @@ -107,5 +110,11 @@ static int bolero_info_create_codec_entry( static inline void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n) { } + +static inline int bolero_register_wake_irq(struct snd_soc_codec *codec, + u32 data) +{ + return 0; +} #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index a16f778de4d3..e58cbd5c989e 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -331,6 +331,24 @@ static int tx_macro_event_handler(struct snd_soc_codec *codec, u16 event, return 0; } +static int tx_macro_reg_wake_irq(struct snd_soc_codec *codec, + u32 data) +{ + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + u32 ipc_wakeup = data; + int ret = 0; + + if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + ret = swrm_wcd_notify( + tx_priv->swr_ctrl_data[0].tx_swr_pdev, + SWR_REGISTER_WAKE_IRQ, &ipc_wakeup); + + return ret; +} + static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) { struct delayed_work *hpf_delayed_work = NULL; @@ -1683,6 +1701,7 @@ static void tx_macro_init_ops(struct macro_ops *ops, ops->num_dais = ARRAY_SIZE(tx_macro_dai); ops->mclk_fn = tx_macro_mclk_ctrl; ops->event_handler = tx_macro_event_handler; + ops->reg_wake_irq = tx_macro_reg_wake_irq; } static int tx_macro_probe(struct platform_device *pdev) -- GitLab From 3e19f3c0076f0e52bc48ffc17b508189b951840c Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 12 Nov 2018 19:29:50 +0530 Subject: [PATCH 0641/1645] asoc: sm6150: Add changes to send wake_irq mechanism SM6150 V1.0 target uses ipc wake up mechanism. Based on version info of sm6150 chipset, register for wake up interrupt either by ipc_wakeup or hardware interrupt line machanism. Change-Id: I7f12d919418b284f310c8b7bb5cd24e47f2099ec Signed-off-by: Aditya Bavanari --- asoc/sm6150.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 307ef0c6321d..65aaa9b84a30 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include "device_event.h" @@ -79,6 +80,9 @@ #define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ #define MSM_HIFI_ON 1 +#define SM6150_SOC_VERSION_1_0 0x00010000 +#define SM6150_SOC_MSM_ID 0x163 + enum { SLIM_RX_0 = 0, SLIM_RX_1, @@ -4925,6 +4929,19 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) pdata->codec_root = entry; } bolero_info_create_codec_entry(pdata->codec_root, codec); + /* + * SM6150 MSM 1.0 doesn't have hardware wake up interrupt line + * from AOSS to APSS. So, it uses SW workaround and listens to + * interrupt from AFE over IPC. + * Check for MSM version and MSM ID and register wake irq + * accordingly to provide compatibility to all chipsets. + */ + if (socinfo_get_id() == SM6150_SOC_MSM_ID && + socinfo_get_version() == SM6150_SOC_VERSION_1_0) + bolero_register_wake_irq(codec, true); + else + bolero_register_wake_irq(codec, false); + codec_reg_done = true; return 0; err: -- GitLab From 70c29ec0dcb528e2e1b80bd783e46ae8b36d15f7 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Tue, 13 Nov 2018 15:58:13 +0530 Subject: [PATCH 0642/1645] dsp: update q6core driver to vote for LPASS island NPA resource Add interface functions to vote for LPASS island NPA resource from clients. Change-Id: I532dd697f986aca48c3125b1bab3435b890d4039 Signed-off-by: Mangesh Kunchamwar --- dsp/q6core.c | 219 ++++++++++++++++++++++++++++++++++++++++++- include/dsp/q6core.h | 103 +++++++++++++++++++- 2 files changed, 320 insertions(+), 2 deletions(-) diff --git a/dsp/q6core.c b/dsp/q6core.c index f66fc842b52c..d4ea98466308 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -32,7 +32,7 @@ #define TIMEOUT_MS 1000 /* - * AVS bring up in the modem is optimitized for the new + * AVS bring up in the modem is optimized for the new * Sub System Restart design and 100 milliseconds timeout * is sufficient to make sure the Q6 will be ready. */ @@ -67,6 +67,8 @@ struct q6core_str { wait_queue_head_t mdf_map_resp_wait; wait_queue_head_t cmd_req_wait; wait_queue_head_t avcs_fwk_ver_req_wait; + wait_queue_head_t lpass_npa_rsc_wait; + u32 lpass_npa_rsc_rsp_rcvd; u32 bus_bw_resp_received; u32 mdf_map_resp_received; enum cmd_flags { @@ -84,6 +86,7 @@ struct q6core_str { struct cal_type_data *cal_data[CORE_MAX_CAL]; uint32_t mem_map_cal_handle; uint32_t mdf_mem_map_cal_handle; + uint32_t npa_client_handle; int32_t adsp_status; int32_t avs_state; struct q6core_avcs_ver_info q6core_avcs_ver_info; @@ -321,6 +324,15 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) "AVCS_CMD_UNLOAD_TOPO_MODULES", adsp_err_get_err_str(payload1[1])); break; + case AVCS_CMD_DESTROY_LPASS_NPA_CLIENT: + case AVCS_CMD_REQUEST_LPASS_NPA_RESOURCES: + pr_debug("%s: Cmd = AVCS_CMD_CREATE_LPASS_NPA_CLIENT/AVCS_CMD_DESTROY_LPASS_NPA_CLIENT status[%s]\n", + __func__, adsp_err_get_err_str(payload1[1])); + /* ADSP status to match Linux error standard */ + q6core_lcl.adsp_status = -payload1[1]; + q6core_lcl.lpass_npa_rsc_rsp_rcvd = 1; + wake_up(&q6core_lcl.lpass_npa_rsc_wait); + break; default: pr_err("%s: Invalid cmd rsp[0x%x][0x%x] opcode %d\n", __func__, @@ -355,6 +367,15 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) wake_up(&q6core_lcl.bus_bw_req_wait); } break; + case AVCS_CMDRSP_CREATE_LPASS_NPA_CLIENT: + payload1 = data->payload; + pr_debug("%s: AVCS_CMDRSP_CREATE_LPASS_NPA_CLIENT handle %d\n", + __func__, payload1[1]); + q6core_lcl.adsp_status = payload1[0]; + q6core_lcl.npa_client_handle = payload1[1]; + q6core_lcl.lpass_npa_rsc_rsp_rcvd = 1; + wake_up(&q6core_lcl.lpass_npa_rsc_wait); + break; case AVCS_CMDRSP_ADSP_EVENT_GET_STATE: payload1 = data->payload; q6core_lcl.param = payload1[0]; @@ -933,6 +954,201 @@ bool q6core_is_adsp_ready(void) } EXPORT_SYMBOL(q6core_is_adsp_ready); +int q6core_create_lpass_npa_client(uint32_t node_id, char *client_name, + uint32_t *client_handle) +{ + struct avcs_cmd_create_lpass_npa_client_t create_lpass_npa_client; + struct avcs_cmd_create_lpass_npa_client_t *cmd_ptr = + &create_lpass_npa_client; + int ret = 0; + + if (!client_name) { + pr_err("%s: Invalid params\n", __func__); + return -EINVAL; + } + + mutex_lock(&(q6core_lcl.cmd_lock)); + + memset(cmd_ptr, 0, sizeof(create_lpass_npa_client)); + + cmd_ptr->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cmd_ptr->hdr.pkt_size = sizeof(create_lpass_npa_client); + cmd_ptr->hdr.src_port = 0; + cmd_ptr->hdr.dest_port = 0; + cmd_ptr->hdr.token = 0; + cmd_ptr->hdr.opcode = AVCS_CMD_CREATE_LPASS_NPA_CLIENT; + cmd_ptr->node_id = AVCS_SLEEP_ISLAND_CORE_DRIVER_NODE_ID; + strlcpy(cmd_ptr->client_name, client_name, + sizeof(cmd_ptr->client_name)); + + pr_debug("%s: create lpass npa client opcode[0x%x] node id[0x%x]\n", + __func__, cmd_ptr->hdr.opcode, cmd_ptr->node_id); + + *client_handle = 0; + q6core_lcl.adsp_status = 0; + q6core_lcl.lpass_npa_rsc_rsp_rcvd = 0; + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) cmd_ptr); + if (ret < 0) { + pr_err("%s: create lpass npa client failed %d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(q6core_lcl.lpass_npa_rsc_wait, + (q6core_lcl.lpass_npa_rsc_rsp_rcvd == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: timeout. waited for create lpass npa rsc client\n", + __func__); + ret = -ETIMEDOUT; + goto done; + } else { + /* set ret to 0 as no timeout happened */ + ret = 0; + } + + if (q6core_lcl.adsp_status < 0) { + pr_err("%s: DSP returned error %d\n", + __func__, q6core_lcl.adsp_status); + ret = q6core_lcl.adsp_status; + goto done; + } + + *client_handle = q6core_lcl.npa_client_handle; + pr_debug("%s: q6core_lcl.npa_client_handle %d\n", __func__, + q6core_lcl.npa_client_handle); +done: + mutex_unlock(&q6core_lcl.cmd_lock); + return ret; +} +EXPORT_SYMBOL(q6core_create_lpass_npa_client); + +int q6core_destroy_lpass_npa_client(uint32_t client_handle) +{ + struct avcs_cmd_destroy_lpass_npa_client_t destroy_lpass_npa_client; + struct avcs_cmd_destroy_lpass_npa_client_t *cmd_ptr = + &destroy_lpass_npa_client; + int ret = 0; + + mutex_lock(&(q6core_lcl.cmd_lock)); + + memset(cmd_ptr, 0, sizeof(destroy_lpass_npa_client)); + + cmd_ptr->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cmd_ptr->hdr.pkt_size = sizeof(destroy_lpass_npa_client); + cmd_ptr->hdr.src_port = 0; + cmd_ptr->hdr.dest_port = 0; + cmd_ptr->hdr.token = 0; + cmd_ptr->hdr.opcode = AVCS_CMD_DESTROY_LPASS_NPA_CLIENT; + cmd_ptr->client_handle = client_handle; + + pr_debug("%s: dstry lpass npa client opcode[0x%x] client hdl[0x%x]\n", + __func__, cmd_ptr->hdr.opcode, cmd_ptr->client_handle); + + q6core_lcl.adsp_status = 0; + q6core_lcl.lpass_npa_rsc_rsp_rcvd = 0; + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) cmd_ptr); + if (ret < 0) { + pr_err("%s: destroy lpass npa client failed %d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(q6core_lcl.lpass_npa_rsc_wait, + (q6core_lcl.lpass_npa_rsc_rsp_rcvd == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: timeout. waited for destroy lpass npa rsc client\n", + __func__); + ret = -ETIMEDOUT; + goto done; + } else { + /* set ret to 0 as no timeout happened */ + ret = 0; + } + + if (q6core_lcl.adsp_status < 0) { + pr_err("%s: DSP returned error %d\n", + __func__, q6core_lcl.adsp_status); + ret = q6core_lcl.adsp_status; + } +done: + mutex_unlock(&q6core_lcl.cmd_lock); + return ret; +} +EXPORT_SYMBOL(q6core_destroy_lpass_npa_client); + +int q6core_request_island_transition(uint32_t client_handle, + uint32_t island_allow_mode) +{ + struct avcs_sleep_node_island_transition_config_t island_tsn_cfg; + struct avcs_sleep_node_island_transition_config_t *cmd_ptr = + &island_tsn_cfg; + int ret = 0; + + mutex_lock(&(q6core_lcl.cmd_lock)); + + memset(cmd_ptr, 0, sizeof(island_tsn_cfg)); + + cmd_ptr->req_lpass_npa_rsc.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cmd_ptr->req_lpass_npa_rsc.hdr.pkt_size = sizeof(island_tsn_cfg); + cmd_ptr->req_lpass_npa_rsc.hdr.src_port = 0; + cmd_ptr->req_lpass_npa_rsc.hdr.dest_port = 0; + cmd_ptr->req_lpass_npa_rsc.hdr.token = 0; + cmd_ptr->req_lpass_npa_rsc.hdr.opcode = + AVCS_CMD_REQUEST_LPASS_NPA_RESOURCES; + cmd_ptr->req_lpass_npa_rsc.client_handle = client_handle; + cmd_ptr->req_lpass_npa_rsc.resource_id = + AVCS_SLEEP_NODE_ISLAND_TRANSITION_RESOURCE_ID; + cmd_ptr->island_allow_mode = island_allow_mode; + + pr_debug("%s: req islnd tnsn opcode[0x%x] island_allow_mode[0x%x]\n", + __func__, cmd_ptr->req_lpass_npa_rsc.hdr.opcode, + cmd_ptr->island_allow_mode); + + q6core_lcl.adsp_status = 0; + q6core_lcl.lpass_npa_rsc_rsp_rcvd = 0; + ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) cmd_ptr); + if (ret < 0) { + pr_err("%s: island tnsn cmd send failed %d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(q6core_lcl.lpass_npa_rsc_wait, + (q6core_lcl.lpass_npa_rsc_rsp_rcvd == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: timeout. waited for island lpass npa rsc req\n", + __func__); + ret = -ETIMEDOUT; + goto done; + } else { + /* set ret to 0 as no timeout happened */ + ret = 0; + } + + if (q6core_lcl.adsp_status < 0) { + pr_err("%s: DSP returned error %d\n", + __func__, q6core_lcl.adsp_status); + ret = q6core_lcl.adsp_status; + } +done: + mutex_unlock(&q6core_lcl.cmd_lock); + return ret; +} +EXPORT_SYMBOL(q6core_request_island_transition); + int q6core_map_memory_regions(phys_addr_t *buf_add, uint32_t mempool_id, uint32_t *bufsz, uint32_t bufcnt, uint32_t *map_handle) { @@ -1671,6 +1887,7 @@ int __init core_init(void) init_waitqueue_head(&q6core_lcl.cmd_req_wait); init_waitqueue_head(&q6core_lcl.avcs_fwk_ver_req_wait); init_waitqueue_head(&q6core_lcl.mdf_map_resp_wait); + init_waitqueue_head(&q6core_lcl.lpass_npa_rsc_wait); q6core_lcl.cmd_resp_received_flag = FLAG_NONE; mutex_init(&q6core_lcl.cmd_lock); mutex_init(&q6core_lcl.ver_lock); diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index 1fa0d1e98a9f..e1f8b97dbb90 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -19,6 +19,8 @@ #define AVCS_CMD_ADSP_EVENT_GET_STATE 0x0001290C #define AVCS_CMDRSP_ADSP_EVENT_GET_STATE 0x0001290D +#define AVCS_API_VERSION_V4 4 +#define APRV2_IDS_SERVICE_ID_ADSP_CORE_V (0x3) bool q6core_is_adsp_ready(void); @@ -150,7 +152,7 @@ struct avcs_cmd_register_topologies { } __packed; -#define AVCS_CMD_DEREGISTER_TOPOLOGIES 0x0001292a +#define AVCS_CMD_DEREGISTER_TOPOLOGIES 0x0001292a /* The payload for the AVCS_CMD_DEREGISTER_TOPOLOGIES command */ struct avcs_cmd_deregister_topologies { @@ -195,6 +197,99 @@ struct avcs_cmd_load_unload_topo_modules { uint32_t topology_id; } __packed; +/* This command allows a remote client(HLOS) creates a client to LPASS NPA + * resource node. Currently, this command supports only the NPA Sleep resource + * "/island/core/drivers" node ID. + */ +#define AVCS_CMD_CREATE_LPASS_NPA_CLIENT 0x00012985 + +#define AVCS_SLEEP_ISLAND_CORE_DRIVER_NODE_ID 0x00000001 + +struct avcs_cmd_create_lpass_npa_client_t { + struct apr_hdr hdr; + uint32_t node_id; + /* Unique ID of the NPA node. + * @values + * - #AVCS_SLEEP_ISLAND_CORE_DRIVER_NODE_ID + */ + + char client_name[16]; + /* Client name, up to a maximum of sixteen characters.*/ +}; + +/* In response to the #AVCS_CMD_CREATE_LPASS_NPA_CLIENT command, the AVCS + * returns the handle to remote HLOS client. + */ +#define AVCS_CMDRSP_CREATE_LPASS_NPA_CLIENT 0x00012986 + +struct avcs_cmdrsp_create_lpass_npa_client_t { + uint32_t status; + /* Status message (error code). + * @values + * - ADSP_EOK -- Create was successful + * - ADSP_EFAILED -- Create failed + */ + + uint32_t client_handle; + /* Handle of the client.*/ +}; + +/* The remote HLOS client use this command to issue the request to the npa + * resource. Remote client(HLOS) must send the valid npa client handle and + * resource id info. + */ +#define AVCS_CMD_REQUEST_LPASS_NPA_RESOURCES 0x00012987 + +#define AVCS_SLEEP_NODE_ISLAND_TRANSITION_RESOURCE_ID 0x00000001 + +#define SLEEP_RESTRICT_ISLAND 0x0 +#define SLEEP_ALLOW_ISLAND 0x1 + +/* Immediately following this structure is the resource request configuration + * data payload. Payload varies depend on the resource_id requested. + * Currently supported only island transition payload. + */ +struct avcs_cmd_request_lpass_npa_resources_t { + struct apr_hdr hdr; + uint32_t client_handle; + /* Handle of the client. + * @values + * - Valid uint32 number + */ + + uint32_t resource_id; + /* Unique ID of the NPA resource ID. + * @values + * - #AVCS_SLEEP_NODE_ISLAND_TRANSITION_RESOURCE_ID + */ +}; + +/* This structure contains the sleep node resource payload data. + */ +struct avcs_sleep_node_island_transition_config_t { + struct avcs_cmd_request_lpass_npa_resources_t req_lpass_npa_rsc; + uint32_t island_allow_mode; + /* Specifies the island state. + * @values + * - #SLEEP_RESTRICT_ISLAND + * - #SLEEP_ALLOW_ISLAND + */ +}; + +/* This command allows remote client(HLOS) to destroy the npa node client + * handle, which is created using the #AVCS_CMD_CREATE_LPASS_NPA_CLIENT command. + * Remote client(HLOS) must send the valid npa client handle. + */ +#define AVCS_CMD_DESTROY_LPASS_NPA_CLIENT 0x00012988 + +struct avcs_cmd_destroy_lpass_npa_client_t { + struct apr_hdr hdr; + uint32_t client_handle; + /* Handle of the client. + * @values + * - Valid uint32 number + */ +}; int q6core_map_memory_regions(phys_addr_t *buf_add, uint32_t mempool_id, uint32_t *bufsz, uint32_t bufcnt, uint32_t *map_handle); @@ -212,6 +307,12 @@ int32_t core_get_license_status(uint32_t module_id); int32_t q6core_load_unload_topo_modules(uint32_t topology_id, bool preload_type); +int q6core_create_lpass_npa_client(uint32_t node_id, char *client_name, + uint32_t *client_handle); +int q6core_destroy_lpass_npa_client(uint32_t client_handle); +int q6core_request_island_transition(uint32_t client_handle, + uint32_t island_allow_mode); + #if IS_ENABLED(CONFIG_USE_Q6_32CH_SUPPORT) static inline bool q6core_use_Q6_32ch_support(void) { -- GitLab From 912a96accb6439da49b681d6228d664c3532617b Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Tue, 13 Nov 2018 16:04:53 +0530 Subject: [PATCH 0643/1645] asoc: codecs: update audio clock driver for LPASS NPA resource Add new clock node for LPASS NPA resource for clients to enable or disable the resource. Change-Id: I8aa587771618d301ace72d6df1045078cdf39c9c Signed-off-by: Mangesh Kunchamwar --- asoc/codecs/audio-ext-clk-up.c | 81 ++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index b6cb2f6b4c5a..ba72fd8f6107 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "audio-ext-clk-up.h" enum { @@ -33,6 +34,7 @@ enum { AUDIO_EXT_CLK_LPASS5, AUDIO_EXT_CLK_LPASS6, AUDIO_EXT_CLK_LPASS7, + AUDIO_EXT_CLK_LPASS_NPA_RSC_ISLAND, AUDIO_EXT_CLK_LPASS_MAX, AUDIO_EXT_CLK_MAX = AUDIO_EXT_CLK_LPASS_MAX, }; @@ -55,6 +57,7 @@ struct audio_ext_clk_priv { struct afe_clk_set clk_cfg; struct audio_ext_clk audio_clk; const char *clk_name; + uint32_t npa_rsc_client_handle; }; static inline struct audio_ext_clk_priv *to_audio_clk(struct clk_hw *hw) @@ -141,12 +144,58 @@ static u8 audio_ext_clk_get_parent(struct clk_hw *hw) return 0; } +static int lpass_npa_rsc_prepare(struct clk_hw *hw) +{ + struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw); + int ret; + + if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS_NPA_RSC_ISLAND) && + (clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX)) { + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= AVCS_API_VERSION_V4) { + ret = q6core_request_island_transition( + clk_priv->npa_rsc_client_handle, false); + if (ret < 0) { + pr_err("%s q6core_request_island_transition failed %d\n", + __func__, ret); + return ret; + } + } + } + + return 0; +} + +static void lpass_npa_rsc_unprepare(struct clk_hw *hw) +{ + struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw); + int ret = 0; + + if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS_NPA_RSC_ISLAND) && + (clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX)) { + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= AVCS_API_VERSION_V4) { + ret = q6core_request_island_transition( + clk_priv->npa_rsc_client_handle, true); + if (ret < 0) { + pr_err("%s q6core_request_island_transition failed %d\n", + __func__, ret); + } + } + } +} + static const struct clk_ops audio_ext_clk_ops = { .prepare = audio_ext_clk_prepare, .unprepare = audio_ext_clk_unprepare, .get_parent = audio_ext_clk_get_parent, }; +static const struct clk_ops lpass_npa_rsc_ops = { + .prepare = lpass_npa_rsc_prepare, + .unprepare = lpass_npa_rsc_unprepare, +}; + static const char * const audio_ext_pmi_div_clk[] = { "qpnp_clkdiv_1", "pms405_div_clk1", @@ -274,6 +323,15 @@ static struct audio_ext_clk audio_clk_array[] = { }, }, }, + { + .pnctrl_info = {NULL}, + .fact = { + .hw.init = &(struct clk_init_data){ + .name = "lpass_npa_rsc_island_clk", + .ops = &lpass_npa_rsc_ops, + }, + }, + }, }; static int audio_get_pinctrl(struct platform_device *pdev) @@ -476,11 +534,34 @@ static int audio_ref_clk_probe(struct platform_device *pdev) return ret; } + if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_NPA_RSC_ISLAND) { + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= AVCS_API_VERSION_V4) { + ret = q6core_create_lpass_npa_client( + AVCS_SLEEP_NODE_ISLAND_TRANSITION_RESOURCE_ID, + "lpass_npa_rsc_mgr", + &clk_priv->npa_rsc_client_handle); + if (ret) { + dev_err(&pdev->dev, "%s: q6core_create_lpass_npa_client is failed %d\n", + __func__, ret); + audio_put_pinctrl(pdev); + return ret; + } + } + } return 0; } static int audio_ref_clk_remove(struct platform_device *pdev) { + struct audio_ext_clk_priv *clk_priv = platform_get_drvdata(pdev); + + if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_NPA_RSC_ISLAND) { + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= AVCS_API_VERSION_V4) + q6core_destroy_lpass_npa_client( + clk_priv->npa_rsc_client_handle); + } audio_put_pinctrl(pdev); return 0; -- GitLab From 53b4e14f9480f4479dc281d35ba4c7dfbc2cbfa4 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 13 Nov 2018 19:36:25 +0530 Subject: [PATCH 0644/1645] ASoC: bolero: Add callback to tanggu in SSR Disable Add callback event in ssr_disable to disable tanggu PA before regcache_cache_only to avoid pop after PDR. Also update proper bit while RX Mute. Change-Id: I06402269d393ca74c11611482cafbde03f4c62b9 Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/bolero-cdc.c | 1 + asoc/codecs/bolero/internal.h | 1 + asoc/codecs/bolero/rx-macro.c | 7 ++++--- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index d6a196b6c830..dcf688ef6c99 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -581,6 +581,7 @@ static void bolero_ssr_disable(struct device *dev, void *data) struct bolero_priv *priv = data; int macro_idx; + bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_PA_OFF_PRE_SSR); regcache_cache_only(priv->regmap, true); mutex_lock(&priv->clk_lock); diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 0129c395f1b9..89d3cadb7f3b 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -20,6 +20,7 @@ /* from bolero to WCD events */ enum { BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1, + BOLERO_WCD_EVT_PA_OFF_PRE_SSR, BOLERO_WCD_EVT_SSR_DOWN, BOLERO_WCD_EVT_SSR_UP, }; diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 4624eae8a9e9..f5ad8d225d8e 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1117,7 +1117,7 @@ static int rx_macro_mclk_ctrl(struct device *dev, bool enable) static int rx_macro_event_handler(struct snd_soc_codec *codec, u16 event, u32 data) { - u16 reg = 0, reg_mix = 0, rx_idx = 0, mute = 0x0; + u16 reg = 0, reg_mix = 0, rx_idx = 0, mute = 0x0, val = 0; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; @@ -1128,12 +1128,13 @@ static int rx_macro_event_handler(struct snd_soc_codec *codec, u16 event, case BOLERO_MACRO_EVT_RX_MUTE: rx_idx = data >> 0x10; mute = data & 0xffff; + val = mute ? 0x10 : 0x00; reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + (rx_idx * RX_MACRO_RX_PATH_OFFSET); reg_mix = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL + (rx_idx * RX_MACRO_RX_PATH_OFFSET); - snd_soc_update_bits(codec, reg, 0x10, mute << 0x10); - snd_soc_update_bits(codec, reg_mix, 0x10, mute << 0x10); + snd_soc_update_bits(codec, reg, 0x10, val); + snd_soc_update_bits(codec, reg_mix, 0x10, val); break; case BOLERO_MACRO_EVT_IMPED_TRUE: rx_macro_wcd_clsh_imped_config(codec, data, true); -- GitLab From 920015ceb80192ba0e692a7e8e86840717c61fea Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Tue, 13 Nov 2018 16:16:35 +0530 Subject: [PATCH 0645/1645] asoc: codecs: bolero: vote for LPASS NPA resource Updates for voting for LPASS island NPA resource while access any LPASS registers. Change-Id: Ibcebd2d6ef368f309594689335bc07a36eafeaf0 Signed-off-by: Mangesh Kunchamwar --- asoc/codecs/bolero/bolero-cdc.c | 59 +++++++++++++++++++++++++++++++++ asoc/codecs/bolero/bolero-cdc.h | 7 ++++ asoc/codecs/bolero/internal.h | 1 + asoc/codecs/bolero/va-macro.c | 19 ++++++++++- 4 files changed, 85 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index a0822ebdec0c..07918a89aa51 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -18,7 +18,9 @@ #include #include #include +#include #include +#include #include "bolero-cdc.h" #include "internal.h" @@ -30,6 +32,9 @@ static struct snd_soc_codec_driver bolero; +/* pm runtime auto suspend timer in msecs */ +#define BOLERO_AUTO_SUSPEND_DELAY 1500 /* delay in msec */ + /* MCLK_MUX table for all macros */ static u16 bolero_mclk_mux_tbl[MAX_MACRO][MCLK_MUX_MAX] = { {TX_MACRO, VA_MACRO}, @@ -67,6 +72,8 @@ static int __bolero_reg_read(struct bolero_priv *priv, "%s: SSR in progress, exit\n", __func__); goto err; } + + pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev); current_mclk_mux_macro = priv->current_mclk_mux_macro[macro_id]; if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) { @@ -88,6 +95,8 @@ static int __bolero_reg_read(struct bolero_priv *priv, priv->macro_params[current_mclk_mux_macro].mclk_fn( priv->macro_params[current_mclk_mux_macro].dev, false); err: + pm_runtime_mark_last_busy(priv->macro_params[VA_MACRO].dev); + pm_runtime_put_autosuspend(priv->macro_params[VA_MACRO].dev); mutex_unlock(&priv->clk_lock); return ret; } @@ -104,6 +113,7 @@ static int __bolero_reg_write(struct bolero_priv *priv, "%s: SSR in progress, exit\n", __func__); goto err; } + ret = pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev); current_mclk_mux_macro = priv->current_mclk_mux_macro[macro_id]; if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) { @@ -125,6 +135,8 @@ static int __bolero_reg_write(struct bolero_priv *priv, priv->macro_params[current_mclk_mux_macro].mclk_fn( priv->macro_params[current_mclk_mux_macro].dev, false); err: + pm_runtime_mark_last_busy(priv->macro_params[VA_MACRO].dev); + pm_runtime_put_autosuspend(priv->macro_params[VA_MACRO].dev); mutex_unlock(&priv->clk_lock); return ret; } @@ -850,6 +862,7 @@ static int bolero_probe(struct platform_device *pdev) struct bolero_priv *priv; u32 num_macros = 0; int ret; + struct clk *lpass_npa_rsc_island = NULL; priv = devm_kzalloc(&pdev->dev, sizeof(struct bolero_priv), GFP_KERNEL); @@ -898,6 +911,17 @@ static int bolero_probe(struct platform_device *pdev) bolero_add_child_devices); schedule_work(&priv->bolero_add_child_devices_work); + /* Register LPASS NPA resource */ + lpass_npa_rsc_island = devm_clk_get(&pdev->dev, "island_lpass_npa_rsc"); + if (IS_ERR(lpass_npa_rsc_island)) { + ret = PTR_ERR(lpass_npa_rsc_island); + dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", + __func__, "island_lpass_npa_rsc", ret); + lpass_npa_rsc_island = NULL; + ret = 0; + } + priv->lpass_npa_rsc_island = lpass_npa_rsc_island; + return 0; } @@ -914,6 +938,41 @@ static int bolero_remove(struct platform_device *pdev) return 0; } +int bolero_runtime_resume(struct device *dev) +{ + struct bolero_priv *priv = dev_get_drvdata(dev->parent); + int ret = 0; + + if (priv->lpass_npa_rsc_island == NULL) { + dev_dbg(dev, "%s: Invalid lpass npa rsc node\n", __func__); + return 0; + } + + ret = clk_prepare_enable(priv->lpass_npa_rsc_island); + if (ret < 0) + dev_err(dev, "%s:lpass npa rsc island enable failed\n", + __func__); + + pm_runtime_set_autosuspend_delay(priv->dev, BOLERO_AUTO_SUSPEND_DELAY); + return 0; +} +EXPORT_SYMBOL(bolero_runtime_resume); + +int bolero_runtime_suspend(struct device *dev) +{ + struct bolero_priv *priv = dev_get_drvdata(dev->parent); + + mutex_lock(&priv->clk_lock); + if (priv->lpass_npa_rsc_island != NULL) + clk_disable_unprepare(priv->lpass_npa_rsc_island); + else + dev_dbg(dev, "%s: Invalid lpass npa rsc node\n", + __func__); + mutex_unlock(&priv->clk_lock); + return 0; +} +EXPORT_SYMBOL(bolero_runtime_suspend); + static const struct of_device_id bolero_dt_match[] = { {.compatible = "qcom,bolero-codec"}, {} diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 36d17f5ab521..a00c06530c2e 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -75,6 +75,8 @@ int bolero_info_create_codec_entry( struct snd_soc_codec *codec); int bolero_register_wake_irq(struct snd_soc_codec *codec, u32 data); void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n); +int bolero_runtime_resume(struct device *dev); +int bolero_runtime_suspend(struct device *dev); #else static inline int bolero_register_macro(struct device *dev, u16 macro_id, @@ -113,6 +115,11 @@ static inline void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n) static inline int bolero_register_wake_irq(struct snd_soc_codec *codec, u32 data) +static inline int bolero_runtime_resume(struct device *dev) +{ + return 0; +} +static int bolero_runtime_suspend(struct device *dev) { return 0; } diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 0129c395f1b9..947dd546b028 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -64,6 +64,7 @@ struct bolero_priv { u16 current_mclk_mux_macro[MAX_MACRO]; struct work_struct bolero_add_child_devices_work; u32 version; + struct clk *lpass_npa_rsc_island; /* Entry for version info */ struct snd_info_entry *entry; diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 199f75c19075..820c4dfd857b 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -20,9 +20,12 @@ #include #include #include +#include #include "bolero-cdc.h" #include "bolero-cdc-registers.h" +/* pm runtime auto suspend timer in msecs */ +#define VA_AUTO_SUSPEND_DELAY 1500 /* delay in msec */ #define VA_MACRO_MAX_OFFSET 0x1000 #define VA_MACRO_NUM_DECIMATORS 8 @@ -1617,6 +1620,10 @@ static int va_macro_probe(struct platform_device *pdev) dev_err(&pdev->dev, "%s: register macro failed\n", __func__); goto reg_macro_fail; } + pm_runtime_set_autosuspend_delay(&pdev->dev, VA_AUTO_SUSPEND_DELAY); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_enable(&pdev->dev); return ret; reg_macro_fail: @@ -1632,7 +1639,8 @@ static int va_macro_remove(struct platform_device *pdev) if (!va_priv) return -EINVAL; - + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); bolero_unregister_macro(&pdev->dev, VA_MACRO); mutex_destroy(&va_priv->mclk_lock); return 0; @@ -1644,10 +1652,19 @@ static const struct of_device_id va_macro_dt_match[] = { {} }; +static const struct dev_pm_ops bolero_dev_pm_ops = { + SET_RUNTIME_PM_OPS( + bolero_runtime_suspend, + bolero_runtime_resume, + NULL + ) +}; + static struct platform_driver va_macro_driver = { .driver = { .name = "va_macro", .owner = THIS_MODULE, + .pm = &bolero_dev_pm_ops, .of_match_table = va_macro_dt_match, }, .probe = va_macro_probe, -- GitLab From d3ffb3368b14dfd5b3f5b172f5ace0f1a332b083 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 14 Nov 2018 19:59:21 +0530 Subject: [PATCH 0646/1645] asoc: codecs: bolero: Disable HD2 on RX macro HD2 canceller on analog codec is performing better and enabling HD2 block on rx macro side as well impacting THD+N spec. As per HW recommendation, disable HD2 on digital bolero rx macro by default. Mixer control option is provided if required to enable it in future for any requirements. CRs-Fixed: 2343436 Change-Id: Ic1696ff9a6dea22a3c2a6071708267e2a024a4c7 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 42 +++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 10fb7eeca348..29d7fca6fb4a 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -345,6 +345,7 @@ struct rx_macro_priv { bool is_ear_mode_on; bool dev_up; bool hph_pwr_mode; + bool hph_hd2_mode; u16 mclk_mux; struct mutex mclk_lock; struct mutex swr_clk_lock; @@ -433,6 +434,10 @@ static const char *const rx_macro_ear_mode_text[] = {"OFF", "ON"}; static const struct soc_enum rx_macro_ear_mode_enum = SOC_ENUM_SINGLE_EXT(2, rx_macro_ear_mode_text); +static const char *const rx_macro_hph_hd2_mode_text[] = {"OFF", "ON"}; +static const struct soc_enum rx_macro_hph_hd2_mode_enum = + SOC_ENUM_SINGLE_EXT(2, rx_macro_hph_hd2_mode_text); + static const char *const rx_macro_hph_pwr_mode_text[] = {"ULP", "LoHIFI"}; static const struct soc_enum rx_macro_hph_pwr_mode_enum = SOC_ENUM_SINGLE_EXT(2, rx_macro_hph_pwr_mode_text); @@ -1694,6 +1699,34 @@ static int rx_macro_put_ear_mode(struct snd_kcontrol *kcontrol, return 0; } +static int rx_macro_get_hph_hd2_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = rx_priv->hph_hd2_mode; + return 0; +} + +static int rx_macro_put_hph_hd2_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + rx_priv->hph_hd2_mode = ucontrol->value.integer.value[0]; + return 0; +} + static int rx_macro_get_hph_pwr_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2010,7 +2043,8 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, snd_soc_update_bits(codec, main_reg, 0x20, 0x20); rx_macro_idle_detect_control(codec, rx_priv, interp_idx, event); - rx_macro_hd2_control(codec, interp_idx, event); + if (rx_priv->hph_hd2_mode) + rx_macro_hd2_control(codec, interp_idx, event); rx_macro_hphdelay_lutbypass(codec, rx_priv, interp_idx, event); rx_macro_config_compander(codec, rx_priv, @@ -2037,7 +2071,8 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, event); rx_macro_hphdelay_lutbypass(codec, rx_priv, interp_idx, event); - rx_macro_hd2_control(codec, interp_idx, event); + if (rx_priv->hph_hd2_mode) + rx_macro_hd2_control(codec, interp_idx, event); rx_macro_idle_detect_control(codec, rx_priv, interp_idx, event); /* Clk Disable */ @@ -2403,6 +2438,9 @@ static const struct snd_kcontrol_new rx_macro_snd_controls[] = { SOC_ENUM_EXT("RX_EAR Mode", rx_macro_ear_mode_enum, rx_macro_get_ear_mode, rx_macro_put_ear_mode), + SOC_ENUM_EXT("RX_HPH HD2 Mode", rx_macro_hph_hd2_mode_enum, + rx_macro_get_hph_hd2_mode, rx_macro_put_hph_hd2_mode), + SOC_ENUM_EXT("RX_HPH_PWR_MODE", rx_macro_hph_pwr_mode_enum, rx_macro_get_hph_pwr_mode, rx_macro_put_hph_pwr_mode), -- GitLab From f4fd5f33d1f68ad81da778cdad1478bfc755d8ae Mon Sep 17 00:00:00 2001 From: Florian Pfister Date: Mon, 5 Nov 2018 15:32:13 +0100 Subject: [PATCH 0647/1645] dsp: add SBC support for BT sink mode Update SBC sample frequency and number of channels from IPC library to set AFE port accordingly. Change-Id: Ibca385b0fc0ba4c3122053559b1116bd4c31336d Signed-off-by: Florian Pfister --- dsp/q6afe.c | 4 ++++ include/dsp/apr_audio-v2.h | 18 ++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 0d5721e5305d..2810bebd9829 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -3541,6 +3541,10 @@ static int q6afe_send_dec_config(u16 port_id, media_type.sample_rate = cfg->data.aac_config.sample_rate; break; + case ASM_MEDIA_FMT_SBC: + media_type.sample_rate = + cfg->data.sbc_config.sample_rate; + break; default: media_type.sample_rate = afe_config.slim_sch.sample_rate; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index eb529dc1e8e6..9ac728185953 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -4311,9 +4311,23 @@ struct afe_port_media_type_t { * #ASM_MEDIA_FMT_SBC media format. */ struct asm_sbc_dec_cfg_t { - /* All configuration is extracted from the stream */ -} __packed; + uint16_t channels; + /* + * Number of channels present in the SBC stream. + * + * @values + * - 1 -- Mono + * - 2 -- Stereo + */ + uint32_t sample_rate; + /* + * Number of samples per second. + * + * @values 8000, 11025, 12000, 16000, 22050, 24000, 32000, + * 44100, 48000, 64000, 88200, 96000 Hz + */ +} __packed; /* * Payload of the MP3 decoder configuration parameters in the * #ASM_MEDIA_FMT_MP3 media format. -- GitLab From 8ab099ad8cf481e499ceb641597b76e2567b2dc1 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Tue, 13 Nov 2018 16:20:16 +0530 Subject: [PATCH 0648/1645] soc: vote for LPASS NPA resource from LPI TLMM driver Vote for LPASS island NPA resource before accessing any LPASS register from LPI TLMM driver. Change-Id: I9987b2ac60b055a7d33b3adce2b36a2fbbe2dea1 Signed-off-by: Mangesh Kunchamwar --- soc/pinctrl-lpi.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index 21d51fb0ee22..f6628bb860e4 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -21,12 +21,16 @@ #include #include #include +#include #include +#include #include #include "core.h" #include "pinctrl-utils.h" +#define LPI_AUTO_SUSPEND_DELAY 1500 /* delay in msec */ + #define LPI_ADDRESS_SIZE 0x20000 #define LPI_GPIO_REG_VAL_CTL 0x00 @@ -97,6 +101,7 @@ struct lpi_gpio_state { struct pinctrl_dev *ctrl; struct gpio_chip chip; char __iomem *base; + struct clk *lpass_npa_rsc_island; }; static const char *const lpi_gpio_groups[] = { @@ -128,11 +133,14 @@ static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr) __func__); return 0; } + pm_runtime_get_sync(lpi_dev); ret = ioread32(pad->base + pad->offset + addr); if (ret < 0) pr_err("%s: read 0x%x failed\n", __func__, addr); + pm_runtime_mark_last_busy(lpi_dev); + pm_runtime_put_autosuspend(lpi_dev); return ret; } @@ -144,8 +152,12 @@ static int lpi_gpio_write(struct lpi_gpio_pad *pad, unsigned int addr, __func__); return 0; } + pm_runtime_get_sync(lpi_dev); iowrite32(val, pad->base + pad->offset + addr); + + pm_runtime_mark_last_busy(lpi_dev); + pm_runtime_put_autosuspend(lpi_dev); return 0; } @@ -499,6 +511,7 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) int ret, npins, i; char __iomem *lpi_base; u32 reg; + struct clk *lpass_npa_rsc_island = NULL; ret = of_property_read_u32(dev->of_node, "reg", ®); if (ret < 0) { @@ -608,6 +621,22 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) goto err_snd_evt; } + /* Register LPASS NPA resource */ + lpass_npa_rsc_island = devm_clk_get(&pdev->dev, "island_lpass_npa_rsc"); + if (IS_ERR(lpass_npa_rsc_island)) { + ret = PTR_ERR(lpass_npa_rsc_island); + dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", + __func__, "island_lpass_npa_rsc", ret); + lpass_npa_rsc_island = NULL; + ret = 0; + } + state->lpass_npa_rsc_island = lpass_npa_rsc_island; + + pm_runtime_set_autosuspend_delay(&pdev->dev, LPI_AUTO_SUSPEND_DELAY); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_enable(&pdev->dev); + return 0; err_snd_evt: @@ -621,6 +650,8 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) static int lpi_pinctrl_remove(struct platform_device *pdev) { struct lpi_gpio_state *state = platform_get_drvdata(pdev); + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); snd_event_client_deregister(&pdev->dev); audio_notifier_deregister("lpi_tlmm"); @@ -635,9 +666,49 @@ static const struct of_device_id lpi_pinctrl_of_match[] = { MODULE_DEVICE_TABLE(of, lpi_pinctrl_of_match); +int lpi_pinctrl_runtime_resume(struct device *dev) +{ + struct lpi_gpio_state *state = dev_get_drvdata(dev); + int ret = 0; + + if (state->lpass_npa_rsc_island == NULL) { + dev_dbg(dev, "%s: Invalid lpass npa rsc node\n", __func__); + return 0; + } + + ret = clk_prepare_enable(state->lpass_npa_rsc_island); + if (ret < 0) { + dev_err(dev, "%s:lpass npa rsc island enable failed\n", + __func__); + } + pm_runtime_set_autosuspend_delay(dev, LPI_AUTO_SUSPEND_DELAY); + return 0; +} + +int lpi_pinctrl_runtime_suspend(struct device *dev) +{ + struct lpi_gpio_state *state = dev_get_drvdata(dev); + + if (state->lpass_npa_rsc_island == NULL) { + dev_dbg(dev, "%s: Invalid lpass npa rsc node\n", __func__); + return 0; + } + clk_disable_unprepare(state->lpass_npa_rsc_island); + return 0; +} + +static const struct dev_pm_ops lpi_pinctrl_dev_pm_ops = { + SET_RUNTIME_PM_OPS( + lpi_pinctrl_runtime_suspend, + lpi_pinctrl_runtime_resume, + NULL + ) +}; + static struct platform_driver lpi_pinctrl_driver = { .driver = { .name = "qcom-lpi-pinctrl", + .pm = &lpi_pinctrl_dev_pm_ops, .of_match_table = lpi_pinctrl_of_match, }, .probe = lpi_pinctrl_probe, -- GitLab From 204f59cd14b39da62cdd5f908029e2f33c48ce04 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 25 Sep 2018 16:13:10 +0530 Subject: [PATCH 0649/1645] ASoC: wcd937x: Enable hph OCP Update registers to enable OCP for HPHL and HPHR. CRs-Fixed: 2321013 Change-Id: I51a872981ee2dc435757152b9122067944d13924 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 02c952b756f2..e78bbf971326 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -118,6 +118,10 @@ static int wcd937x_init_reg(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WCD937X_ANA_BIAS, 0x40, 0x40); usleep_range(10000, 10010); snd_soc_update_bits(codec, WCD937X_ANA_BIAS, 0x40, 0x00); + snd_soc_update_bits(codec, WCD937X_HPH_OCP_CTL, 0xFF, 0x3A); + snd_soc_update_bits(codec, WCD937X_RX_OCP_CTL, 0x0F, 0x02); + snd_soc_update_bits(codec, WCD937X_HPH_R_TEST, 0x01, 0x01); + snd_soc_update_bits(codec, WCD937X_HPH_L_TEST, 0x01, 0x01); return 0; } -- GitLab From 4b3b0c840160bdf450ad65b09e09adaf5c3ef29b Mon Sep 17 00:00:00 2001 From: Florian Pfister Date: Mon, 5 Nov 2018 15:36:44 +0100 Subject: [PATCH 0650/1645] asoc: add SBC support for BT Sink in dai-driver Receive SBC stream parameters from IPC library. Change-Id: I59e938589c912c85aa3b84203ff20c469b978671 Signed-off-by: Florian Pfister --- asoc/msm-dai-q6-v2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 171337a613bb..9516867c1aae 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -3231,8 +3231,9 @@ static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol, sizeof(struct asm_aac_dec_cfg_v2_t)); break; case DEC_FMT_SBC: - case DEC_FMT_MP3: - /* No decoder specific data available */ + memcpy(&dai_data->dec_config.data, + ucontrol->value.bytes.data + format_size, + sizeof(struct asm_sbc_dec_cfg_t)); break; default: pr_debug("%s: Default decoder config for %d format: Expect abr_dec_cfg\n", -- GitLab From 2eb2e613dfc8b4a9a2dca485c047297989221fbc Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 1 Jun 2018 12:05:25 +0530 Subject: [PATCH 0651/1645] ASoC: Fix null pointer dereference for prtd pointer Private data pointer may not be initialized before access it in adsp_stream_cmd_put. NULL check for prtd avoids the issue. CRs-Fixed: 2250112 Change-Id: I0a033d7e867b183c329941b57b49232729191f1b Signed-off-by: Vatsal Bucha --- asoc/msm-pcm-q6-v2.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 1dccecdaed88..5da97952c8f5 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -686,6 +686,7 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) if (!prtd->audio_client) { pr_info("%s: Could not allocate memory\n", __func__); kfree(prtd); + prtd = NULL; return -ENOMEM; } @@ -1174,6 +1175,12 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, } prtd = substream->runtime->private_data; + if (prtd == NULL) { + pr_err("%s prtd is null.\n", __func__); + ret = -EINVAL; + goto done; + } + if (prtd->audio_client == NULL) { pr_err("%s prtd is null.\n", __func__); ret = -EINVAL; -- GitLab From 8d8602219bfb914bc8060a845c946a09d20c1723 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 3 Jul 2018 14:05:53 +0530 Subject: [PATCH 0652/1645] wcd934x: Fix NULL pointer dereference for wcd9xxx pointer During bind/unbind of ngd_msm_ctrl power_gate_digital_core is called. Simultaneously tavil_remove is also called making tavil pointer as NULL. Check for tavil as not NULL at the start of function to avoid NULL pointer dereference. CRs-Fixed: 2267796 Change-Id: I6fc476cc8b706b556836f30838983de0f34d4fc1 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd934x/wcd934x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 44f741e7951b..2dde1de26916 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -8939,6 +8939,8 @@ static struct snd_soc_dai_driver tavil_i2s_dai[] = { static void tavil_codec_power_gate_digital_core(struct tavil_priv *tavil) { + if (!tavil) + return; mutex_lock(&tavil->power_lock); dev_dbg(tavil->dev, "%s: Entering power gating function, %d\n", __func__, tavil->power_active_ref); -- GitLab From 61cd502c9d96ed332a7c35f01696abbec66d507a Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 16 Nov 2018 16:57:11 +0530 Subject: [PATCH 0653/1645] dsp: audio_ion: Update IOVA start address from dt entry In sm6150, LPASS has Agg NOC before SMMU transactions. Agg NOC has HW limitation which considers IOVA as physical DDR address and resulting in failure for particular memory range. Update IOVA address start address for audio to use different range. CRs-Fixed: 2346788 Change-Id: Ieac3b8bdd6295a56039d9bca422d2f41e0d94944 Signed-off-by: Laxminath Kasam --- dsp/msm_audio_ion.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index bf3ef1250ed4..8bfcdc4493c8 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -49,6 +49,7 @@ struct msm_audio_ion_private { struct mutex list_mutex; u64 smmu_sid_bits; u32 smmu_version; + u32 iova_start_addr; }; struct msm_audio_alloc_data { @@ -665,7 +666,7 @@ static int msm_audio_smmu_init(struct device *dev) int ret; mapping = arm_iommu_create_mapping(&platform_bus_type, - MSM_AUDIO_ION_VA_START, + msm_audio_ion_data.iova_start_addr, MSM_AUDIO_ION_VA_LEN); if (IS_ERR(mapping)) return PTR_ERR(mapping); @@ -701,6 +702,7 @@ static int msm_audio_ion_probe(struct platform_device *pdev) u64 smmu_sid_mask = 0; const char *msm_audio_ion_dt = "qcom,smmu-enabled"; const char *msm_audio_ion_smmu = "qcom,smmu-version"; + const char *msm_audio_ion_iova_start_addr = "qcom,iova-start-addr"; const char *msm_audio_ion_smmu_sid_mask = "qcom,smmu-sid-mask"; bool smmu_enabled; enum apr_subsys_state q6_state; @@ -746,6 +748,18 @@ static int msm_audio_ion_probe(struct platform_device *pdev) dev_dbg(dev, "%s: SMMU is Enabled. SMMU version is (%d)", __func__, msm_audio_ion_data.smmu_version); + rc = of_property_read_u32(dev->of_node, + msm_audio_ion_iova_start_addr, + &msm_audio_ion_data.iova_start_addr); + if (rc) { + dev_dbg(dev, + "%s: qcom,iova_start_addr missing in DT node, initialize with default val\n", + __func__); + msm_audio_ion_data.iova_start_addr = MSM_AUDIO_ION_VA_START; + } else { + dev_dbg(dev, "%s:IOVA start addr: 0x%x\n", + __func__, msm_audio_ion_data.iova_start_addr); + } /* Get SMMU SID information from Devicetree */ rc = of_property_read_u64(dev->of_node, msm_audio_ion_smmu_sid_mask, -- GitLab From d9fa69c9e7900a5767bd68f2c360113a46b8a0f5 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 23 Jan 2018 12:42:52 +0800 Subject: [PATCH 0654/1645] ASoC: dsp: correct return value check When the return value of adm_populate_channel_weight is 0, it should keep running, not return error. Change-Id: I447b81d6edfc89db6cb3742c1719e745c6071c12 Signed-off-by: Meng Wang --- dsp/q6adm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index b9c11ac6b4c3..c6dc1784faf1 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -644,7 +644,7 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, index = index + ch_mixer->input_channels[channel_index]; ret = adm_populate_channel_weight(&adm_pspd_params[index], ch_mixer, channel_index); - if (!ret) { + if (ret) { pr_err("%s: fail to get channel weight with error %d\n", __func__, ret); goto fail_cmd; -- GitLab From 9ae91fb765ba32478c6aeb67f978cf821ee57238 Mon Sep 17 00:00:00 2001 From: Bhalchandra Gajare Date: Wed, 14 Feb 2018 18:12:43 -0800 Subject: [PATCH 0655/1645] ASoC: wcd934x: mark wdma3 output widget as ignore_suspend Paths using WDMA3_OUT widget are currently not marked to be ignored during suspend, which results in the path teardown during suspend. Due to this the audio use-case is broken. Fix this by marking WDMA3_OUT widget as ignore_suspend. CRs-fixed: 2176596 Change-Id: I72a2dda21aabfe9b13ea8660d4e3a51b3185d9ea Signed-off-by: Bhalchandra Gajare --- asoc/codecs/wcd934x/wcd934x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 44f741e7951b..dfa40de8d6b0 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -10298,6 +10298,8 @@ static int tavil_soc_codec_probe(struct snd_soc_codec *codec) snd_soc_dapm_ignore_suspend(dapm, "AIF2 Capture"); snd_soc_dapm_ignore_suspend(dapm, "AIF3 Playback"); snd_soc_dapm_ignore_suspend(dapm, "AIF3 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "WDMA3_OUT"); + if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) { snd_soc_dapm_ignore_suspend(dapm, "AIF4 Playback"); snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX"); -- GitLab From 49e9a4081bbcefcd5c2ed2f096d8cd01130ac6d4 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 11 Apr 2018 17:33:55 +0800 Subject: [PATCH 0656/1645] ASoC: msm: remove pcm_i2S_sel_vt_address from machine driver lpaif_muxsel_virt_addr to select AUXPCM or I2S is not needed in machine driver. ADSP would select AUXPCM or I2S according to afe port. Remove related change in machine driver. Change-Id: I55520a56bab2134a08e86909b98eb15d588c53ba Signed-off-by: Meng Wang --- asoc/sdm845.c | 164 +------------------------------------------------- 1 file changed, 1 insertion(+), 163 deletions(-) diff --git a/asoc/sdm845.c b/asoc/sdm845.c index e2ab1f0167da..3fe402329485 100644 --- a/asoc/sdm845.c +++ b/asoc/sdm845.c @@ -116,19 +116,6 @@ enum { AUX_PCM_MAX, }; -enum { - PCM_I2S_SEL_PRIM = 0, - PCM_I2S_SEL_SEC, - PCM_I2S_SEL_TERT, - PCM_I2S_SEL_QUAT, - PCM_I2S_SEL_MAX, -}; - -struct mi2s_aux_pcm_common_conf { - struct mutex lock; - void *pcm_i2s_sel_vt_addr; -}; - struct mi2s_conf { struct mutex lock; u32 ref_cnt; @@ -142,11 +129,6 @@ static u32 mi2s_ebit_clk[MI2S_MAX] = { Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT }; -struct auxpcm_conf { - struct mutex lock; - u32 ref_cnt; -}; - struct dev_config { u32 sample_rate; u32 bit_format; @@ -584,9 +566,7 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = { } }; -static struct mi2s_aux_pcm_common_conf mi2s_auxpcm_conf[PCM_I2S_SEL_MAX]; static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; -static struct auxpcm_conf auxpcm_intf_conf[AUX_PCM_MAX]; static int slim_get_sample_rate_val(int sample_rate) { @@ -4116,83 +4096,6 @@ static int msm_wcn_hw_params(struct snd_pcm_substream *substream, return ret; } -static int msm_aux_pcm_snd_startup(struct snd_pcm_substream *substream) -{ - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int index = cpu_dai->id - 1; - - dev_dbg(rtd->card->dev, - "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", - __func__, substream->name, substream->stream, - cpu_dai->name, cpu_dai->id); - - if (index < PRIM_AUX_PCM || index > QUAT_AUX_PCM) { - ret = -EINVAL; - dev_err(rtd->card->dev, - "%s: CPU DAI id (%d) out of range\n", - __func__, cpu_dai->id); - goto err; - } - - mutex_lock(&auxpcm_intf_conf[index].lock); - if (++auxpcm_intf_conf[index].ref_cnt == 1) { - if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) { - mutex_lock(&mi2s_auxpcm_conf[index].lock); - iowrite32(1, - mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr); - mutex_unlock(&mi2s_auxpcm_conf[index].lock); - } else { - dev_err(rtd->card->dev, - "%s lpaif_tert_muxsel_virt_addr is NULL\n", - __func__); - ret = -EINVAL; - } - } - if (ret < 0) - auxpcm_intf_conf[index].ref_cnt--; - - mutex_unlock(&auxpcm_intf_conf[index].lock); - -err: - return ret; -} - -static void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - int index = rtd->cpu_dai->id - 1; - - dev_dbg(rtd->card->dev, - "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", - __func__, - substream->name, substream->stream, - rtd->cpu_dai->name, rtd->cpu_dai->id); - - if (index < PRIM_AUX_PCM || index > QUAT_AUX_PCM) { - dev_err(rtd->card->dev, - "%s: CPU DAI id (%d) out of range\n", - __func__, rtd->cpu_dai->id); - return; - } - - mutex_lock(&auxpcm_intf_conf[index].lock); - if (--auxpcm_intf_conf[index].ref_cnt == 0) { - if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) { - mutex_lock(&mi2s_auxpcm_conf[index].lock); - iowrite32(0, - mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr); - mutex_unlock(&mi2s_auxpcm_conf[index].lock); - } else { - dev_err(rtd->card->dev, - "%s lpaif_tert_muxsel_virt_addr is NULL\n", - __func__); - } - } - mutex_unlock(&auxpcm_intf_conf[index].lock); -} - static int msm_get_port_id(int be_id) { int afe_port_id; @@ -4723,18 +4626,7 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) __func__, ret); goto clean_up; } - if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) { - mutex_lock(&mi2s_auxpcm_conf[index].lock); - iowrite32(0, - mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr); - mutex_unlock(&mi2s_auxpcm_conf[index].lock); - } else { - dev_err(rtd->card->dev, - "%s lpaif_muxsel_virt_addr is NULL for dai %d\n", - __func__, index); - ret = -EINVAL; - goto clk_off; - } + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); if (ret < 0) { pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n", @@ -4792,11 +4684,6 @@ static struct snd_soc_ops msm_mi2s_be_ops = { .shutdown = msm_mi2s_snd_shutdown, }; -static struct snd_soc_ops msm_aux_pcm_be_ops = { - .startup = msm_aux_pcm_snd_startup, - .shutdown = msm_aux_pcm_snd_shutdown, -}; - static struct snd_soc_ops msm_be_ops = { .hw_params = msm_snd_hw_params, }; @@ -6085,7 +5972,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, }, { .name = LPASS_BE_AUXPCM_TX, @@ -6100,7 +5986,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, }, /* Secondary AUX PCM Backend DAI Links */ { @@ -6116,7 +6001,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, }, { .name = LPASS_BE_SEC_AUXPCM_TX, @@ -6131,7 +6015,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_suspend = 1, .ignore_pmdown_time = 1, - .ops = &msm_aux_pcm_be_ops, }, /* Tertiary AUX PCM Backend DAI Links */ { @@ -6147,7 +6030,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, }, { .name = LPASS_BE_TERT_AUXPCM_TX, @@ -6162,7 +6044,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_suspend = 1, .ignore_pmdown_time = 1, - .ops = &msm_aux_pcm_be_ops, }, /* Quaternary AUX PCM Backend DAI Links */ { @@ -6178,7 +6059,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, }, { .name = LPASS_BE_QUAT_AUXPCM_TX, @@ -6193,7 +6073,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_suspend = 1, .ignore_pmdown_time = 1, - .ops = &msm_aux_pcm_be_ops, }, }; @@ -6823,41 +6702,15 @@ static int msm_init_wsa_dev(struct platform_device *pdev, static void msm_i2s_auxpcm_init(struct platform_device *pdev) { - struct resource *muxsel; int count; u32 mi2s_master_slave[MI2S_MAX]; int ret; - char *str[PCM_I2S_SEL_MAX] = { - "lpaif_pri_mode_muxsel", - "lpaif_sec_mode_muxsel", - "lpaif_tert_mode_muxsel", - "lpaif_quat_mode_muxsel" - }; for (count = 0; count < MI2S_MAX; count++) { mutex_init(&mi2s_intf_conf[count].lock); mi2s_intf_conf[count].ref_cnt = 0; } - for (count = 0; count < AUX_PCM_MAX; count++) { - mutex_init(&auxpcm_intf_conf[count].lock); - auxpcm_intf_conf[count].ref_cnt = 0; - } - - for (count = 0; count < PCM_I2S_SEL_MAX; count++) { - mutex_init(&mi2s_auxpcm_conf[count].lock); - mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr = NULL; - } - - for (count = 0; count < PCM_I2S_SEL_MAX; count++) { - muxsel = platform_get_resource_byname(pdev, IORESOURCE_MEM, - str[count]); - if (muxsel) { - mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr - = ioremap(muxsel->start, resource_size(muxsel)); - } - } - ret = of_property_read_u32_array(pdev->dev.of_node, "qcom,msm-mi2s-master", mi2s_master_slave, MI2S_MAX); @@ -6876,21 +6729,6 @@ static void msm_i2s_auxpcm_deinit(void) { int count; - for (count = 0; count < PCM_I2S_SEL_MAX; count++) { - if (mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr != - NULL) { - iounmap( - mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr); - mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr = NULL; - } - mutex_destroy(&mi2s_auxpcm_conf[count].lock); - } - - for (count = 0; count < AUX_PCM_MAX; count++) { - mutex_destroy(&auxpcm_intf_conf[count].lock); - auxpcm_intf_conf[count].ref_cnt = 0; - } - for (count = 0; count < MI2S_MAX; count++) { mutex_destroy(&mi2s_intf_conf[count].lock); mi2s_intf_conf[count].ref_cnt = 0; -- GitLab From 79da9fb84a19d288cf3faef8b663d13ed8ed6dac Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 13 Nov 2018 19:49:34 +0530 Subject: [PATCH 0657/1645] ASoC: wcd937x: Fix pop after PDR Pop is heard after PDR is triggered. This is because while device down PA is still on. Disable PA before SSR device down to prevent pop. Change-Id: I6bfe3e731bdf60fba8fee90ab39c03a0512006ce Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/internal.h | 1 + asoc/codecs/wcd937x/wcd937x.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index eb2de9d69efb..c0f96f124ff9 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -123,6 +123,7 @@ enum { enum { BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1, + BOLERO_WCD_EVT_PA_OFF_PRE_SSR, BOLERO_WCD_EVT_SSR_DOWN, BOLERO_WCD_EVT_SSR_UP, }; diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 485d328389d3..34e4b1b811aa 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1246,6 +1246,11 @@ static int wcd937x_event_notify(struct notifier_block *block, mask = 0x20; snd_soc_update_bits(codec, reg, mask, 0x00); break; + case BOLERO_WCD_EVT_PA_OFF_PRE_SSR: + snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0xC0, 0x00); + snd_soc_update_bits(codec, WCD937X_ANA_EAR, 0x80, 0x00); + snd_soc_update_bits(codec, WCD937X_AUX_AUXPA, 0x80, 0x00); + break; case BOLERO_WCD_EVT_SSR_DOWN: wcd937x_reset_low(wcd937x->dev); break; -- GitLab From eb1fdd1afcc1b22974069c22a04fbef53222c1bd Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Mon, 19 Nov 2018 16:17:28 +0530 Subject: [PATCH 0658/1645] msm: update auto suspend delay for voting LPASS NPA resource Reduce auto suspend delay to 100ms from 1500ms for voting LPASS NPA resource to reduce delay in entering LPASS into island mode. Change-Id: Ic38f7b9e8d794963e51c30dfd03da586bca84bd2 Signed-off-by: Mangesh Kunchamwar --- asoc/codecs/bolero/bolero-cdc.c | 2 +- asoc/codecs/bolero/va-macro.c | 2 +- soc/pinctrl-lpi.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 07918a89aa51..da6cb2fa96a6 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -33,7 +33,7 @@ static struct snd_soc_codec_driver bolero; /* pm runtime auto suspend timer in msecs */ -#define BOLERO_AUTO_SUSPEND_DELAY 1500 /* delay in msec */ +#define BOLERO_AUTO_SUSPEND_DELAY 100 /* delay in msec */ /* MCLK_MUX table for all macros */ static u16 bolero_mclk_mux_tbl[MAX_MACRO][MCLK_MUX_MAX] = { diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 820c4dfd857b..99b87396ec5d 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -25,7 +25,7 @@ #include "bolero-cdc-registers.h" /* pm runtime auto suspend timer in msecs */ -#define VA_AUTO_SUSPEND_DELAY 1500 /* delay in msec */ +#define VA_AUTO_SUSPEND_DELAY 100 /* delay in msec */ #define VA_MACRO_MAX_OFFSET 0x1000 #define VA_MACRO_NUM_DECIMATORS 8 diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index f6628bb860e4..279ec0000084 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -29,7 +29,7 @@ #include "core.h" #include "pinctrl-utils.h" -#define LPI_AUTO_SUSPEND_DELAY 1500 /* delay in msec */ +#define LPI_AUTO_SUSPEND_DELAY 100 /* delay in msec */ #define LPI_ADDRESS_SIZE 0x20000 -- GitLab From 2382aaad1a62a1d8b95a32cf5edd04bce745e1bd Mon Sep 17 00:00:00 2001 From: Md Mansoor Ahmed Date: Tue, 20 Nov 2018 11:06:32 +0530 Subject: [PATCH 0659/1645] Asoc: Enable audio-dlkm compilation for sdmsteppe target Enable compilation for sdmsteppe target and also fix compilation errors. Change-Id: I18a13764415ae955843706943e338bb575c11853 Signed-off-by: Md Mansoor Ahmed --- Makefile.am | 9 ++++++++- asoc/sm6150.c | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index bd60e53769a6..4a9f96ed5cbf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,6 +23,9 @@ endif ifeq ($(TARGET_SUPPORT),qcs40x) KBUILD_OPTIONS += CONFIG_ARCH_QCS405=y endif +ifeq ($(TARGET_SUPPORT), sdmsteppe)) +KBUILD_OPTIONS += CONFIG_ARCH_SM6150=y +endif obj-m := ipc/ obj-m += dsp/ @@ -30,7 +33,7 @@ obj-m += dsp/codecs/ obj-m += soc/ obj-m += asoc/ obj-m += asoc/codecs/ -ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sdm670 qcs605)) +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sdm670 qcs605 sdmsteppe)) obj-m += asoc/codecs/wcd934x/ endif ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), apq8053 sdm670 qcs605)) @@ -44,6 +47,10 @@ obj-m += asoc/codecs/bolero/ obj-m += asoc/codecs/csra66x0/ obj-m += asoc/codecs/ep92/ endif +ifeq ($(TARGET_SUPPORT), sdmsteppe)) +obj-m += asoc/codecs/bolero/ +obj-m += asoc/codecs/wcd937x/ +endif all: $(shell rm -fr $(shell pwd)/soc/core.h) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 65aaa9b84a30..59bbf69664be 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -8035,8 +8035,8 @@ static int msm_init_aux_dev(struct platform_device *pdev, u32 wsa_dev_cnt; u32 codec_aux_dev_cnt = 0; int i; - struct msm_wsa881x_dev_info *wsa881x_dev_info; - struct aux_codec_dev_info *aux_cdc_dev_info; + struct msm_wsa881x_dev_info *wsa881x_dev_info = NULL; + struct aux_codec_dev_info *aux_cdc_dev_info = NULL; const char *auxdev_name_prefix[1]; char *dev_name_str = NULL; int found = 0; -- GitLab From 26d8bddff460055d6baf315b0744fe419907d243 Mon Sep 17 00:00:00 2001 From: Md Mansoor Ahmed Date: Tue, 20 Nov 2018 10:56:01 +0530 Subject: [PATCH 0660/1645] Asoc: codec: Fix compilation errors for sdmsteppe target Fix compilation errors for sdmsteppe target. Change-Id: I511bfd5271d04b455e46a101c47ea1535681dcca Signed-off-by: Md Mansoor Ahmed --- asoc/codecs/bolero/rx-macro.c | 2 +- asoc/codecs/wcd-mbhc-v2.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 10fb7eeca348..f537fc19c6be 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -3022,7 +3022,7 @@ static void rx_macro_init_bcl_pmic_reg(struct snd_soc_codec *codec) rx_priv->bcl_pmic_params.ppid); break; default: - dev_err(rx_dev, "%s: PMIC ID is invalid\n", + dev_err(rx_dev, "%s: PMIC ID is invalid %d\n", __func__, rx_priv->bcl_pmic_params.id); break; } diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 363b90b1d5f5..ed39b6657047 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -777,7 +777,7 @@ void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc, enum snd_jack_types jack_type; if (mbhc->deinit_in_progress) { - pr_info("%s: mbhc deinit in progess: ignore report\n"); + pr_info("%s: mbhc deinit in progess: ignore report\n", __func__); return; } -- GitLab From 2a7cbe473af17478eaa6d17ef24b5a6b871f4329 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 13 Nov 2018 12:35:00 +0530 Subject: [PATCH 0661/1645] wcd937x: Use MICBIAS2 instead of MICBIAS1 for MICB2_VOUT MICBIAS1 is mapped to MICB2_VOUT. Replace it with MICBIAS2 as MICBIAS2 is used for mbhc detect. Change-Id: I23bade728f0c5b9de75d78ccb70e57d74f01adbb Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x-mbhc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index ec38eba6def1..96343b8ce391 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -137,7 +137,7 @@ static struct wcd_mbhc_register 0x80, 7, 0), WCD_MBHC_REGISTER("WCD_MBHC_ADC_RESULT", WCD937X_MBHC_NEW_ADC_RESULT, 0xFF, 0, 0), - WCD_MBHC_REGISTER("WCD_MBHC_MICB2_VOUT", WCD937X_ANA_MICB1, 0x3F, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB2_VOUT", WCD937X_ANA_MICB2, 0x3F, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_ADC_MODE", WCD937X_MBHC_NEW_CTL_1, 0x10, 4, 0), WCD_MBHC_REGISTER("WCD_MBHC_DETECTION_DONE", -- GitLab From 773b1d1ad013b4075013995056a7eebabcd27be4 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 29 Oct 2018 17:49:34 -0700 Subject: [PATCH 0662/1645] asoc: sm8150: use locked version of soc_find_component Use soc_find_component locked version to ensure proper access of component list while trying to find wsa components from the list. Change-Id: I1960d5b023c3d59f5c97ca0f616b4d9e39c15c50 Signed-off-by: Karthikeyan Mani --- asoc/sm8150.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/sm8150.c b/asoc/sm8150.c index 7eb95e550046..30f3b130a5f1 100644 --- a/asoc/sm8150.c +++ b/asoc/sm8150.c @@ -7268,7 +7268,7 @@ static int msm_init_wsa_dev(struct platform_device *pdev, ret = -EINVAL; goto err_free_dev_info; } - if (soc_find_component(wsa_of_node, NULL)) { + if (soc_find_component_locked(wsa_of_node, NULL)) { /* WSA device registered with ALSA core */ wsa881x_dev_info[found].of_node = wsa_of_node; wsa881x_dev_info[found].index = i; -- GitLab From 356b68c1e208bb5be15c0489a2284519c61dcb81 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 5 Mar 2018 15:56:29 +0530 Subject: [PATCH 0663/1645] dsp: avtimer: Update function pointers for camera isp to use avtimer After DLKM, avtimer functions cannot be invoked directly from kernel driver. Camera driver exposes API to get the function pointers to use avtimer. Update the function pointers by calling respective camera set API. AVTIMER_LEGACY config should be enabled in audio conf to enable this support. CRs-Fixed: 2201340 Change-Id: I165e7ea0226e174288f3e8b81ef01fce137e2e35 Signed-off-by: Laxminath Kasam --- dsp/avtimer.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/dsp/avtimer.c b/dsp/avtimer.c index c9ef9f4a8ac9..41718ef6720b 100644 --- a/dsp/avtimer.c +++ b/dsp/avtimer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2015, 2017-2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -25,6 +25,9 @@ #include #include #include +#if IS_ENABLED(CONFIG_AVTIMER_LEGACY) +#include +#endif #include #include @@ -70,6 +73,7 @@ struct avtimer_t { }; static struct avtimer_t avtimer; +static void avcs_set_isp_fptr(bool enable); static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) { @@ -313,6 +317,29 @@ int avcs_core_query_timer(uint64_t *avtimer_tick) } EXPORT_SYMBOL(avcs_core_query_timer); +#if IS_ENABLED(CONFIG_AVTIMER_LEGACY) +static void avcs_set_isp_fptr(bool enable) +{ + struct avtimer_fptr_t av_fptr; + + if (enable) { + av_fptr.fptr_avtimer_open = avcs_core_open; + av_fptr.fptr_avtimer_enable = avcs_core_disable_power_collapse; + av_fptr.fptr_avtimer_get_time = avcs_core_query_timer; + msm_isp_set_avtimer_fptr(av_fptr); + } else { + av_fptr.fptr_avtimer_open = NULL; + av_fptr.fptr_avtimer_enable = NULL; + av_fptr.fptr_avtimer_get_time = NULL; + msm_isp_set_avtimer_fptr(av_fptr); + } +} +#else +static void avcs_set_isp_fptr(bool enable) +{ +} +#endif + static int avtimer_open(struct inode *inode, struct file *file) { return avcs_core_disable_power_collapse(1); @@ -469,6 +496,8 @@ static int dev_avtimer_probe(struct platform_device *pdev) else avtimer.clk_mult = clk_mult_val; + avcs_set_isp_fptr(true); + pr_debug("%s: avtimer.clk_div = %d, avtimer.clk_mult = %d\n", __func__, avtimer.clk_div, avtimer.clk_mult); return 0; @@ -500,6 +529,7 @@ static int dev_avtimer_remove(struct platform_device *pdev) cdev_del(&avtimer.myc); class_destroy(avtimer.avtimer_class); unregister_chrdev_region(MKDEV(major, 0), 1); + avcs_set_isp_fptr(false); return 0; } -- GitLab From f008d22120a50066c52c7ef24acf23bc3c47e6c8 Mon Sep 17 00:00:00 2001 From: Raja Mallik Date: Fri, 1 Jun 2018 07:48:38 +0530 Subject: [PATCH 0664/1645] ASoC: wcd9335: Add support for Microphone Activity Detection Microphone Activity Detection (MAD) hardware in the codec is used to perform detection of audio/beacon/ultrasound audio activity on the microphone. Add routing controls and configuration to enable the capture support for MAD in WCD9335 codec. Change-Id: I48359c6069bbebfc7f58efc24654544309912b69 Signed-off-by: Bhalchandra Gajare Signed-off-by: Raja Mallik --- asoc/codecs/wcd9335.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 854fb92878c1..d7db8ee1fa50 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -11928,6 +11928,21 @@ static struct snd_soc_dai_driver tasha_i2s_dai[] = { }, .ops = &tasha_dai_ops, }, + { + .name = "tasha_mad1", + .id = AIF4_MAD_TX, + .capture = { + .stream_name = "AIF4 MAD TX", + .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_384000, + .formats = TASHA_FORMATS_S16_S24_S32_LE, + .rate_min = 16000, + .rate_max = 384000, + .channels_min = 1, + .channels_max = 1, + }, + .ops = &tasha_dai_ops, + }, }; static void tasha_codec_power_gate_digital_core(struct tasha_priv *tasha) -- GitLab From 4162083535585342b2c2ed688833cf2a1b824ac6 Mon Sep 17 00:00:00 2001 From: Dieter Luecking Date: Wed, 14 Nov 2018 15:11:47 +0100 Subject: [PATCH 0665/1645] dsp: fix configuration of EC reference The check open_v8.endpoint_id_2 != 0xFFFF can only be true if changed after initializing open_v8.endpoint_id_2 to 0xFFFF. If not, EC reference will never be configured correctly. Fixing code to account for that. Change-Id: I8d2aba19ae1f60ace118c828a98d5fecb149be18 Signed-off-by: Dieter Luecking --- dsp/q6adm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index b9c11ac6b4c3..265ae939b0d8 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2939,6 +2939,10 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, open_v8.endpoint_id_2 = 0xFFFF; open_v8.endpoint_id_3 = 0xFFFF; + if (this_adm.ec_ref_rx && (path != ADM_PATH_PLAYBACK)) { + open_v8.endpoint_id_2 = this_adm.ec_ref_rx; + this_adm.ec_ref_rx = -1; + } open_v8.topology_id = topology; open_v8.reserved = 0; @@ -2969,11 +2973,8 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, if ((this_adm.num_ec_ref_rx_chans != 0) && (path != ADM_PATH_PLAYBACK) && (open_v8.endpoint_id_2 != 0xFFFF)) { - open_v8.endpoint_id_2 = this_adm.ec_ref_rx; - this_adm.ec_ref_rx = -1; ep2_payload.dev_num_channel = this_adm.num_ec_ref_rx_chans; - this_adm.num_ec_ref_rx_chans = 0; if (this_adm.ec_ref_rx_bit_width != 0) { ep2_payload.bit_width = @@ -3019,6 +3020,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, if ((this_adm.num_ec_ref_rx_chans != 0) && (path != ADM_PATH_PLAYBACK) && (open_v8.endpoint_id_2 != 0xFFFF)) { + this_adm.num_ec_ref_rx_chans = 0; memcpy(adm_params + sizeof(open_v8) + ep1_payload_size, (void *)&ep2_payload, -- GitLab From 35849ccf241182ec615951a23dcbfd37ed0a7c0b Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 14 Nov 2018 20:36:08 +0530 Subject: [PATCH 0666/1645] asoc: codecs: Fix CnP on HPH turnon and turnoff On headphone(HPH) path, CnP spec is not met. Handle sequences for bolero and tanggu codecs as per HW sequences. Disable vdd_buck during system suspend when no usecase is active. CRs-Fixed: 2343436 Change-Id: I62f89d829715f07885a97531fdcb2cc3ca0822ef Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 26 ++++-- asoc/codecs/wcd937x/internal.h | 2 + asoc/codecs/wcd937x/wcd937x.c | 164 ++++++++++++++++++++------------- 3 files changed, 119 insertions(+), 73 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 10fb7eeca348..161408336f7d 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1407,8 +1407,6 @@ static int rx_macro_config_compander(struct snd_soc_codec *codec, if (SND_SOC_DAPM_EVENT_OFF(event)) { snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); } @@ -1987,7 +1985,7 @@ static void rx_macro_hphdelay_lutbypass(struct snd_soc_codec *codec, static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, int event, int interp_idx) { - u16 main_reg = 0; + u16 main_reg = 0, dsm_reg = 0, rx_cfg2_reg = 0; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; @@ -2001,13 +1999,19 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, main_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + (interp_idx * RX_MACRO_RX_PATH_OFFSET); + dsm_reg = BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL + + (interp_idx * RX_MACRO_RX_PATH_OFFSET); + rx_cfg2_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG2 + + (interp_idx * RX_MACRO_RX_PATH_OFFSET); if (SND_SOC_DAPM_EVENT_ON(event)) { if (rx_priv->main_clk_users[interp_idx] == 0) { + snd_soc_update_bits(codec, dsm_reg, 0x01, 0x01); /* Main path PGA mute enable */ snd_soc_update_bits(codec, main_reg, 0x10, 0x10); /* Clk enable */ snd_soc_update_bits(codec, main_reg, 0x20, 0x20); + snd_soc_update_bits(codec, rx_cfg2_reg, 0x03, 0x03); rx_macro_idle_detect_control(codec, rx_priv, interp_idx, event); rx_macro_hd2_control(codec, interp_idx, event); @@ -2028,6 +2032,15 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, rx_priv->main_clk_users[interp_idx]--; if (rx_priv->main_clk_users[interp_idx] <= 0) { rx_priv->main_clk_users[interp_idx] = 0; + /* Clk Disable */ + snd_soc_update_bits(codec, dsm_reg, 0x01, 0x00); + snd_soc_update_bits(codec, main_reg, 0x20, 0x00); + /* Reset enable and disable */ + snd_soc_update_bits(codec, main_reg, 0x40, 0x40); + snd_soc_update_bits(codec, main_reg, 0x40, 0x00); + /* Reset rate to 48K*/ + snd_soc_update_bits(codec, main_reg, 0x0F, 0x04); + snd_soc_update_bits(codec, rx_cfg2_reg, 0x03, 0x00); rx_macro_config_classh(codec, rx_priv, interp_idx, event); rx_macro_config_compander(codec, rx_priv, @@ -2040,13 +2053,6 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, rx_macro_hd2_control(codec, interp_idx, event); rx_macro_idle_detect_control(codec, rx_priv, interp_idx, event); - /* Clk Disable */ - snd_soc_update_bits(codec, main_reg, 0x20, 0x00); - /* Reset enable and disable */ - snd_soc_update_bits(codec, main_reg, 0x40, 0x40); - snd_soc_update_bits(codec, main_reg, 0x40, 0x00); - /* Reset rate to 48K*/ - snd_soc_update_bits(codec, main_reg, 0x0F, 0x04); } } diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index c11baa9abdfe..247a046eaa92 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -68,6 +68,8 @@ struct wcd937x_priv { struct wcd_irq_info irq_info; u32 rx_clk_cnt; int num_irq_regs; + /* to track the status */ + unsigned long status_mask; u8 num_tx_ports; u8 num_rx_ports; diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index e78bbf971326..8d9cd24f98e0 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -18,10 +18,11 @@ #include #include #include +#include +#include #include #include #include -#include #include #include #include "internal.h" @@ -45,6 +46,10 @@ enum { CODEC_RX, }; +enum { + ALLOW_BUCK_DISABLE, +}; + static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); @@ -374,7 +379,6 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); int hph_mode = wcd937x->hph_mode; - int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -414,22 +418,15 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, usleep_range(5000, 5010); snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); - wcd_cls_h_fsm(codec, &wcd937x->clsh_info, - WCD_CLSH_EVENT_PRE_DAC, - WCD_CLSH_STATE_HPHL, - hph_mode); break; case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x01); - ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, - wcd937x->rx_swr_dev->dev_num, - false); break; } - return ret; + return 0; } static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, @@ -439,8 +436,6 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); int hph_mode = wcd937x->hph_mode; - int ret = 0; - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -480,22 +475,15 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, usleep_range(5000, 5010); snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); - wcd_cls_h_fsm(codec, &wcd937x->clsh_info, - WCD_CLSH_EVENT_PRE_DAC, - WCD_CLSH_STATE_HPHR, - hph_mode); break; case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x0F, 0x01); - ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, - wcd937x->rx_swr_dev->dev_num, - false); break; } - return ret; + return 0; } static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, @@ -505,7 +493,6 @@ static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); int hph_mode = wcd937x->hph_mode; - int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -540,12 +527,9 @@ static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x01); - ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, - wcd937x->rx_swr_dev->dev_num, - false); break; }; - return ret; + return 0; } @@ -556,7 +540,6 @@ static int wcd937x_codec_aux_dac_event(struct snd_soc_dapm_widget *w, struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); int hph_mode = wcd937x->hph_mode; - int ret = 0; dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -577,15 +560,12 @@ static int wcd937x_codec_aux_dac_event(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: - ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, - wcd937x->rx_swr_dev->dev_num, - false); wcd937x_rx_clk_disable(codec); snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x04, 0x00); break; }; - return ret; + return 0; } @@ -603,11 +583,15 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, + wcd937x->rx_swr_dev->dev_num, + true); + wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_HPHR, + hph_mode); snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x10, 0x10); usleep_range(100, 110); - ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, - wcd937x->rx_swr_dev->dev_num, - true); break; case SND_SOC_DAPM_POST_PMU: usleep_range(7000, 7010); @@ -654,13 +638,20 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, int ret = 0; int hph_mode = wcd937x->hph_mode; + dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x20, 0x20); - usleep_range(100, 110); ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, true); + wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_HPHL, + hph_mode); + snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x20, 0x20); + usleep_range(100, 110); break; case SND_SOC_DAPM_POST_PMU: usleep_range(7000, 7010); @@ -805,12 +796,12 @@ static int wcd937x_enable_clsh(struct snd_soc_dapm_widget *w, mode == CLS_H_HIFI || mode == CLS_H_LP) { wcd937x_rx_connect_port(codec, CLSH, SND_SOC_DAPM_EVENT_ON(event)); - if (SND_SOC_DAPM_EVENT_OFF(event)) - ret = swr_slvdev_datapath_control( - wcd937x->rx_swr_dev, - wcd937x->rx_swr_dev->dev_num, - false); } + if (SND_SOC_DAPM_EVENT_OFF(event)) + ret = swr_slvdev_datapath_control( + wcd937x->rx_swr_dev, + wcd937x->rx_swr_dev->dev_num, + false); return ret; } @@ -1449,6 +1440,12 @@ static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + if (test_bit(ALLOW_BUCK_DISABLE, &wcd937x->status_mask)) { + dev_dbg(codec->dev, + "%s: buck already in enabled state\n", + __func__); + return 0; + } ret = msm_cdc_enable_ondemand_supply(wcd937x->dev, wcd937x->supplies, pdata->regulator, @@ -1459,6 +1456,7 @@ static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, __func__); return ret; } + clear_bit(ALLOW_BUCK_DISABLE, &wcd937x->status_mask); /* * 200us sleep is required after LDO15 is enabled as per * HW requirement @@ -1466,17 +1464,7 @@ static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, usleep_range(200, 250); break; case SND_SOC_DAPM_POST_PMD: - ret = msm_cdc_disable_ondemand_supply(wcd937x->dev, - wcd937x->supplies, - pdata->regulator, - pdata->num_supplies, - "cdc-vdd-buck"); - if (ret == -EINVAL) { - dev_err(codec->dev, "%s: vdd buck is not enabled\n", - __func__); - return ret; - } - + set_bit(ALLOW_BUCK_DISABLE, &wcd937x->status_mask); break; } return 0; @@ -1638,7 +1626,7 @@ static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = { wcd937x_codec_enable_vdd_buck, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY("CLS_H_PORT", SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_SUPPLY_S("CLS_H_PORT", 1, SND_SOC_NOPM, 0, 0, wcd937x_enable_clsh, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -1787,7 +1775,6 @@ static const struct snd_soc_dapm_widget wcd9375_dapm_widgets[] = { }; static const struct snd_soc_dapm_route wcd937x_audio_map[] = { - {"ADC1_OUTPUT", NULL, "ADC1_MIXER"}, {"ADC1_MIXER", "Switch", "ADC1 REQ"}, {"ADC1 REQ", NULL, "ADC1"}, @@ -1800,18 +1787,24 @@ static const struct snd_soc_dapm_route wcd937x_audio_map[] = { {"ADC2 MUX", "INP3", "AMIC3"}, {"ADC2 MUX", "INP2", "AMIC2"}, + {"IN1_HPHL", NULL, "VDD_BUCK"}, + {"IN1_HPHL", NULL, "CLS_H_PORT"}, {"RX1", NULL, "IN1_HPHL"}, {"RDAC1", NULL, "RX1"}, {"HPHL_RDAC", "Switch", "RDAC1"}, {"HPHL PGA", NULL, "HPHL_RDAC"}, {"HPHL", NULL, "HPHL PGA"}, + {"IN2_HPHR", NULL, "VDD_BUCK"}, + {"IN2_HPHR", NULL, "CLS_H_PORT"}, {"RX2", NULL, "IN2_HPHR"}, {"RDAC2", NULL, "RX2"}, {"HPHR_RDAC", "Switch", "RDAC2"}, {"HPHR PGA", NULL, "HPHR_RDAC"}, {"HPHR", NULL, "HPHR PGA"}, + {"IN3_AUX", NULL, "VDD_BUCK"}, + {"IN3_AUX", NULL, "CLS_H_PORT"}, {"RX3", NULL, "IN3_AUX"}, {"RDAC4", NULL, "RX3"}, {"AUX_RDAC", "Switch", "RDAC4"}, @@ -1824,16 +1817,6 @@ static const struct snd_soc_dapm_route wcd937x_audio_map[] = { {"EAR_RDAC", "Switch", "RDAC3"}, {"EAR PGA", NULL, "EAR_RDAC"}, {"EAR", NULL, "EAR PGA"}, - - {"EAR", NULL, "VDD_BUCK"}, - {"HPHR", NULL, "VDD_BUCK"}, - {"HPHL", NULL, "VDD_BUCK"}, - {"AUX", NULL, "VDD_BUCK"}, - - {"EAR", NULL, "CLS_H_PORT"}, - {"HPHR", NULL, "CLS_H_PORT"}, - {"HPHL", NULL, "CLS_H_PORT"}, - {"AUX", NULL, "CLS_H_PORT"}, }; static const struct snd_soc_dapm_route wcd9375_audio_map[] = { @@ -2092,6 +2075,49 @@ static struct snd_soc_codec_driver soc_codec_dev_wcd937x = { }, }; +#ifdef CONFIG_PM_SLEEP +static int wcd937x_suspend(struct device *dev) +{ + struct wcd937x_priv *wcd937x = NULL; + int ret = 0; + struct wcd937x_pdata *pdata = NULL; + + if (!dev) + return -ENODEV; + + wcd937x = dev_get_drvdata(dev); + if (!wcd937x) + return -EINVAL; + + pdata = dev_get_platdata(wcd937x->dev); + + if (!pdata) { + dev_err(dev, "%s: pdata is NULL\n", __func__); + return -EINVAL; + } + + if (test_bit(ALLOW_BUCK_DISABLE, &wcd937x->status_mask)) { + ret = msm_cdc_disable_ondemand_supply(wcd937x->dev, + wcd937x->supplies, + pdata->regulator, + pdata->num_supplies, + "cdc-vdd-buck"); + if (ret == -EINVAL) { + dev_err(dev, "%s: vdd buck is not disabled\n", + __func__); + return 0; + } + clear_bit(ALLOW_BUCK_DISABLE, &wcd937x->status_mask); + } + return 0; +} + +static int wcd937x_resume(struct device *dev) +{ + return 0; +} +#endif + static int wcd937x_reset(struct device *dev) { struct wcd937x_priv *wcd937x = NULL; @@ -2485,6 +2511,15 @@ static int wcd937x_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP +static const struct dev_pm_ops wcd937x_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS( + wcd937x_suspend, + wcd937x_resume + ) +}; +#endif + static struct platform_driver wcd937x_codec_driver = { .probe = wcd937x_probe, .remove = wcd937x_remove, @@ -2492,6 +2527,9 @@ static struct platform_driver wcd937x_codec_driver = { .name = "wcd937x_codec", .owner = THIS_MODULE, .of_match_table = of_match_ptr(wcd937x_dt_match), +#ifdef CONFIG_PM_SLEEP + .pm = &wcd937x_dev_pm_ops, +#endif }, }; -- GitLab From 7c8ff05871aa1dca40bbc9d60256c236892342c0 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 19 Nov 2018 20:11:10 +0530 Subject: [PATCH 0667/1645] asoc: codecs: wcd937x: Optimize HPH PA delays On headphone path, cold start output latency is not met. Optimize delays during HPH DAC and PA paths. CRs-Fixed: 2338278 Change-Id: If96975d664fc655a4ac38a9d6ed88b6af61adfdf Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd937x/wcd937x.c | 68 ++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 8d9cd24f98e0..3c79a79b7c23 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -48,6 +48,8 @@ enum { enum { ALLOW_BUCK_DISABLE, + HPH_COMP_DELAY, + HPH_PA_DELAY, }; static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); @@ -392,6 +394,7 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, 0x04, 0x04); snd_soc_update_bits(codec, WCD937X_HPH_RDAC_CLK_CTL1, 0x80, 0x00); + set_bit(HPH_COMP_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI) @@ -408,6 +411,22 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, 0x02, 0x02); snd_soc_update_bits(codec, WCD937X_HPH_L_EN, 0x20, 0x00); + if (wcd937x->comp2_enable) { + snd_soc_update_bits(codec, + WCD937X_DIGITAL_CDC_COMP_CTL_0, + 0x01, 0x01); + snd_soc_update_bits(codec, + WCD937X_HPH_R_EN, 0x20, 0x00); + } + /* + * 5ms sleep is required after COMP is enabled as per + * HW requirement + */ + if (test_bit(HPH_COMP_DELAY, &wcd937x->status_mask)) { + usleep_range(5000, 5100); + clear_bit(HPH_COMP_DELAY, + &wcd937x->status_mask); + } } else { snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, @@ -415,7 +434,6 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD937X_HPH_L_EN, 0x20, 0x20); } - usleep_range(5000, 5010); snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); break; @@ -449,6 +467,7 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, 0x08, 0x08); snd_soc_update_bits(codec, WCD937X_HPH_RDAC_CLK_CTL1, 0x80, 0x00); + set_bit(HPH_COMP_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI) @@ -465,6 +484,22 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, 0x01, 0x01); snd_soc_update_bits(codec, WCD937X_HPH_R_EN, 0x20, 0x00); + if (wcd937x->comp1_enable) { + snd_soc_update_bits(codec, + WCD937X_DIGITAL_CDC_COMP_CTL_0, + 0x02, 0x02); + snd_soc_update_bits(codec, + WCD937X_HPH_L_EN, 0x20, 0x00); + } + /* + * 5ms sleep is required after COMP is enabled as per + * HW requirement + */ + if (test_bit(HPH_COMP_DELAY, &wcd937x->status_mask)) { + usleep_range(5000, 5100); + clear_bit(HPH_COMP_DELAY, + &wcd937x->status_mask); + } } else { snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, @@ -472,7 +507,6 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD937X_HPH_R_EN, 0x20, 0x20); } - usleep_range(5000, 5010); snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); break; @@ -592,9 +626,22 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, hph_mode); snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x10, 0x10); usleep_range(100, 110); + set_bit(HPH_PA_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: - usleep_range(7000, 7010); + /* + * 7ms sleep is required after PA is enabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is required. + */ + if (test_bit(HPH_PA_DELAY, &wcd937x->status_mask)) { + if (!wcd937x->comp2_enable) + usleep_range(20000, 20100); + else + usleep_range(7000, 7100); + clear_bit(HPH_PA_DELAY, &wcd937x->status_mask); + } + snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02); if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) @@ -652,9 +699,22 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, hph_mode); snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x20, 0x20); usleep_range(100, 110); + set_bit(HPH_PA_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: - usleep_range(7000, 7010); + /* + * 7ms sleep is required after PA is enabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is required. + */ + if (test_bit(HPH_PA_DELAY, &wcd937x->status_mask)) { + if (!wcd937x->comp1_enable) + usleep_range(20000, 20100); + else + usleep_range(7000, 7100); + clear_bit(HPH_PA_DELAY, &wcd937x->status_mask); + } + snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02); if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) -- GitLab From c496ed25a9c110f28c6fa72c07b13969b7f408b2 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 16 Nov 2018 15:50:40 +0530 Subject: [PATCH 0668/1645] asoc: codecs: Correct the clk users increment/decrement logic The clk users count goes out of sync with the actual clk requests from clients during SSR/PDR. Increment the clk users only after the clk request is successful. Change-Id: I512f037a118f4763a64e7a64f7f559bcfa37a37f Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/va-macro.c | 14 ++++++++++---- asoc/codecs/bolero/wsa-macro.c | 32 ++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 820c4dfd857b..a144583fde73 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -157,8 +157,7 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, mutex_lock(&va_priv->mclk_lock); if (mclk_enable) { - va_priv->va_mclk_users++; - if (va_priv->va_mclk_users == 1) { + if (va_priv->va_mclk_users == 0) { ret = bolero_request_clock(va_priv->dev, VA_MACRO, MCLK_MUX0, true); if (ret < 0) { @@ -181,8 +180,16 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, BOLERO_CDC_VA_TOP_CSR_TOP_CFG0, 0x02, 0x02); } + va_priv->va_mclk_users++; } else { - if (va_priv->va_mclk_users == 1) { + if (va_priv->va_mclk_users <= 0) { + dev_err(va_priv->dev, "%s: clock already disabled\n", + __func__); + va_priv->va_mclk_users = 0; + goto exit; + } + va_priv->va_mclk_users--; + if (va_priv->va_mclk_users == 0) { regmap_update_bits(regmap, BOLERO_CDC_VA_TOP_CSR_TOP_CFG0, 0x02, 0x00); @@ -195,7 +202,6 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, bolero_request_clock(va_priv->dev, VA_MACRO, MCLK_MUX0, false); } - va_priv->va_mclk_users--; } exit: mutex_unlock(&va_priv->mclk_lock); diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index ec870add94b5..2cd1b4360e46 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -766,8 +766,7 @@ static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv, mutex_lock(&wsa_priv->mclk_lock); if (mclk_enable) { - wsa_priv->wsa_mclk_users++; - if (wsa_priv->wsa_mclk_users == 1) { + if (wsa_priv->wsa_mclk_users == 0) { ret = bolero_request_clock(wsa_priv->dev, WSA_MACRO, MCLK_MUX0, true); if (ret < 0) { @@ -790,7 +789,14 @@ static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv, BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x01); } + wsa_priv->wsa_mclk_users++; } else { + if (wsa_priv->wsa_mclk_users <= 0) { + dev_err(wsa_priv->dev, "%s: clock already disabled\n", + __func__); + wsa_priv->wsa_mclk_users = 0; + goto exit; + } wsa_priv->wsa_mclk_users--; if (wsa_priv->wsa_mclk_users == 0) { regmap_update_bits(regmap, @@ -2435,6 +2441,7 @@ static int wsa_swrm_clock(void *handle, bool enable) { struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle; struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL); + int ret = 0; if (regmap == NULL) { dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__); @@ -2446,9 +2453,14 @@ static int wsa_swrm_clock(void *handle, bool enable) dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n", __func__, (enable ? "enable" : "disable")); if (enable) { - wsa_priv->swr_clk_users++; - if (wsa_priv->swr_clk_users == 1) { - wsa_macro_mclk_enable(wsa_priv, 1, true); + if (wsa_priv->swr_clk_users == 0) { + ret = wsa_macro_mclk_enable(wsa_priv, 1, true); + if (ret < 0) { + dev_err(wsa_priv->dev, + "%s: wsa request clock enable failed\n", + __func__); + goto exit; + } regmap_update_bits(regmap, BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x01); @@ -2458,7 +2470,14 @@ static int wsa_swrm_clock(void *handle, bool enable) msm_cdc_pinctrl_select_active_state( wsa_priv->wsa_swr_gpio_p); } + wsa_priv->swr_clk_users++; } else { + if (wsa_priv->swr_clk_users <= 0) { + dev_err(wsa_priv->dev, "%s: clock already disabled\n", + __func__); + wsa_priv->swr_clk_users = 0; + goto exit; + } wsa_priv->swr_clk_users--; if (wsa_priv->swr_clk_users == 0) { regmap_update_bits(regmap, @@ -2471,8 +2490,9 @@ static int wsa_swrm_clock(void *handle, bool enable) } dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n", __func__, wsa_priv->swr_clk_users); +exit: mutex_unlock(&wsa_priv->swr_clk_lock); - return 0; + return ret; } static int wsa_macro_init(struct snd_soc_codec *codec) -- GitLab From 4b8884a7ae28440432a25d081ae40f67b90aba1f Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 10 May 2018 14:20:18 +0530 Subject: [PATCH 0669/1645] ASoC: wcd: Remove non-essential current source votings from adc Zdet current source is enabled for 4 pole aux cable and kept even after plug removal. This increases voltage for both hph left and right which causes error in cross-connection detection for subsequent plug detections. Remove current source enablement from unrequired places. CRs-Fixed: 2234559 Change-Id: Icffbca88f7a6873c509c91e31b494dd6d5d21cb9 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd-mbhc-v2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index ed39b6657047..12057654510d 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -982,6 +982,8 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) jack_type = SND_JACK_HEADSET; break; case MBHC_PLUG_TYPE_HIGH_HPH: + if (mbhc->mbhc_detection_logic == WCD_DETECTION_ADC) + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_ISRC_EN, 0); mbhc->is_extn_cable = false; jack_type = SND_JACK_LINEOUT; break; -- GitLab From 1b52b57ad2944d1ff08c60133d12c3c742f40225 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 7 Aug 2018 16:28:06 +0800 Subject: [PATCH 0670/1645] asoc: add snd_dec_ddp struct for AC3 and EC3 playback Move struct snd_dec_ddp from uapi folder to msm-compress-q6-v2.c to avoid code check warning. Change-Id: Id33eee6da8f42841c80e7e5795bb19e71ab6e784 Signed-off-by: Meng Wang --- asoc/msm-compress-q6-v2.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index d35ed890d66f..97cd85b47507 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -79,6 +79,8 @@ const DECLARE_TLV_DB_LINEAR(msm_compr_vol_gain, 0, #define MAX_NUMBER_OF_STREAMS 2 +#define SND_DEC_DDP_MAX_PARAMS 18 + struct msm_compr_gapless_state { bool set_next_stream_id; int32_t stream_opened[MAX_NUMBER_OF_STREAMS]; @@ -199,6 +201,12 @@ struct msm_compr_audio_effects { struct query_audio_effect query; }; +struct snd_dec_ddp { + __u32 params_length; + __u32 params_id[SND_DEC_DDP_MAX_PARAMS]; + __u32 params_value[SND_DEC_DDP_MAX_PARAMS]; +} __attribute__((packed, aligned(4))); + struct msm_compr_dec_params { struct snd_dec_ddp ddp_params; }; -- GitLab From adbca4f654f6217c26981891b9b2589ee1180306 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 29 Oct 2018 14:30:13 +0800 Subject: [PATCH 0671/1645] asoc: routing: update app type config get function Update app type config get function and userspace can get the app type config with mixer control. Change-Id: I78eda2963161936ae1dbf90dad1bfb64cb079e8d Signed-off-by: Meng Wang --- asoc/msm-pcm-routing-v2.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 0d07dd4773af..41dd7cdac671 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -84,6 +84,7 @@ static bool is_custom_stereo_on; static bool is_ds2_on; static bool swap_ch; static int aanc_level; +static int num_app_cfg_types; #define WEIGHT_0_DB 0x4000 /* all the FEs which can support channel mixer */ @@ -17238,6 +17239,23 @@ static int msm_routing_get_lsm_app_type_cfg_control( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + int shift = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int i = 0, j = 0; + + ucontrol->value.integer.value[i] = num_app_cfg_types; + + for (j = 0; j < num_app_cfg_types; ++j) { + ucontrol->value.integer.value[++i] = + lsm_app_type_cfg[j].app_type; + ucontrol->value.integer.value[++i] = + lsm_app_type_cfg[j].sample_rate; + ucontrol->value.integer.value[++i] = + lsm_app_type_cfg[j].bit_width; + if (shift == 1) + ucontrol->value.integer.value[++i] = + lsm_app_type_cfg[j].num_out_channels; + } return 0; } @@ -17248,18 +17266,18 @@ static int msm_routing_put_lsm_app_type_cfg_control( int shift = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; int i = 0, j; - int num_app_types = ucontrol->value.integer.value[i++]; + num_app_cfg_types = ucontrol->value.integer.value[i++]; memset(lsm_app_type_cfg, 0, MAX_APP_TYPES* sizeof(struct msm_pcm_routing_app_type_data)); - if (num_app_types > MAX_APP_TYPES) { + if (num_app_cfg_types > MAX_APP_TYPES) { pr_err("%s: number of app types exceed the max supported\n", __func__); return -EINVAL; } - for (j = 0; j < num_app_types; j++) { + for (j = 0; j < num_app_cfg_types; j++) { lsm_app_type_cfg[j].app_type = ucontrol->value.integer.value[i++]; lsm_app_type_cfg[j].sample_rate = -- GitLab From d6107d0bbe331c35a506d954826095ed91135f2b Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Fri, 16 Nov 2018 13:06:16 +0800 Subject: [PATCH 0672/1645] asoc: clean up audio drivers and remove unused files Clean up audio drivers and remove unused files. Change-Id: I50559ac3c5f4a1f4336e4480cd3ff235d015441e Signed-off-by: Meng Wang --- Android.mk | 16 +- Makefile | 16 - Makefile.am | 17 +- asoc/Android.mk | 14 +- asoc/Kbuild | 48 - asoc/codecs/Android.mk | 14 +- asoc/codecs/Kbuild | 19 - asoc/codecs/core.h | 4 - asoc/codecs/msm_sdw/Android.mk | 46 - asoc/codecs/msm_sdw/Kbuild | 115 - asoc/codecs/msm_sdw/msm-sdw-tables.c | 319 - asoc/codecs/msm_sdw/msm_sdw.h | 203 - asoc/codecs/msm_sdw/msm_sdw_cdc.c | 2097 ----- asoc/codecs/msm_sdw/msm_sdw_cdc_utils.c | 211 - asoc/codecs/msm_sdw/msm_sdw_registers.h | 126 - asoc/codecs/msm_sdw/msm_sdw_regmap.c | 161 - asoc/codecs/sdm660_cdc/Android.mk | 53 - asoc/codecs/sdm660_cdc/Kbuild | 121 - .../codecs/sdm660_cdc/msm-analog-cdc-regmap.h | 186 - asoc/codecs/sdm660_cdc/msm-analog-cdc.c | 4665 ---------- asoc/codecs/sdm660_cdc/msm-analog-cdc.h | 273 - asoc/codecs/sdm660_cdc/msm-cdc-common.h | 67 - .../sdm660_cdc/msm-digital-cdc-regmap.c | 452 - asoc/codecs/sdm660_cdc/msm-digital-cdc.c | 2213 ----- asoc/codecs/sdm660_cdc/msm-digital-cdc.h | 116 - asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c | 418 - asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h | 35 - asoc/codecs/sdm660_cdc/sdm660-cdc-registers.h | 603 -- asoc/codecs/wcd934x/Android.mk | 10 +- asoc/codecs/wcd934x/Kbuild | 15 - asoc/codecs/wcd9360/Android.mk | 50 - asoc/codecs/wcd9360/Kbuild | 110 - asoc/codecs/wcd9360/wcd9360-defaults.h | 2231 ----- asoc/codecs/wcd9360/wcd9360-dsp-cntl.c | 1357 --- asoc/codecs/wcd9360/wcd9360-dsp-cntl.h | 120 - asoc/codecs/wcd9360/wcd9360-irq.h | 56 - asoc/codecs/wcd9360/wcd9360-regmap.c | 110 - asoc/codecs/wcd9360/wcd9360-routing.h | 882 -- asoc/codecs/wcd9360/wcd9360.c | 8101 ----------------- asoc/codecs/wcd9360/wcd9360.h | 180 - asoc/codecs/wcd937x/Android.mk | 2 +- asoc/codecs/wcd9xxx-core.c | 8 +- asoc/codecs/wcd9xxx-regmap.h | 5 - asoc/codecs/wcd9xxx-rst.c | 159 - asoc/codecs/wcd9xxx-utils.c | 17 +- asoc/msm8998.c | 7483 --------------- asoc/sdm660-common.c | 3551 -------- asoc/sdm660-common.h | 133 - asoc/sdm660-ext-dai-links.c | 2162 ----- asoc/sdm660-external.c | 1882 ---- asoc/sdm660-external.h | 52 - asoc/sdm660-internal.c | 3354 ------- asoc/sdm660-internal.h | 32 - asoc/sdm845.c | 6963 -------------- config/sdm670auto.conf | 50 - config/sdm670auto_static.conf | 50 - config/sdm670autoconf.h | 63 - config/sdm845auto.conf | 37 - config/sdm845autoconf.h | 50 - dsp/Android.mk | 10 +- dsp/Kbuild | 15 - dsp/codecs/Android.mk | 10 +- dsp/codecs/Kbuild | 16 - include/asoc/wcd9360-registers.h | 1158 --- ipc/Android.mk | 10 +- ipc/Kbuild | 15 - soc/Android.mk | 12 +- soc/Kbuild | 15 - 68 files changed, 18 insertions(+), 53146 deletions(-) delete mode 100644 asoc/codecs/msm_sdw/Android.mk delete mode 100644 asoc/codecs/msm_sdw/Kbuild delete mode 100644 asoc/codecs/msm_sdw/msm-sdw-tables.c delete mode 100644 asoc/codecs/msm_sdw/msm_sdw.h delete mode 100644 asoc/codecs/msm_sdw/msm_sdw_cdc.c delete mode 100644 asoc/codecs/msm_sdw/msm_sdw_cdc_utils.c delete mode 100644 asoc/codecs/msm_sdw/msm_sdw_registers.h delete mode 100644 asoc/codecs/msm_sdw/msm_sdw_regmap.c delete mode 100644 asoc/codecs/sdm660_cdc/Android.mk delete mode 100644 asoc/codecs/sdm660_cdc/Kbuild delete mode 100644 asoc/codecs/sdm660_cdc/msm-analog-cdc-regmap.h delete mode 100644 asoc/codecs/sdm660_cdc/msm-analog-cdc.c delete mode 100644 asoc/codecs/sdm660_cdc/msm-analog-cdc.h delete mode 100644 asoc/codecs/sdm660_cdc/msm-cdc-common.h delete mode 100644 asoc/codecs/sdm660_cdc/msm-digital-cdc-regmap.c delete mode 100644 asoc/codecs/sdm660_cdc/msm-digital-cdc.c delete mode 100644 asoc/codecs/sdm660_cdc/msm-digital-cdc.h delete mode 100644 asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c delete mode 100644 asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h delete mode 100644 asoc/codecs/sdm660_cdc/sdm660-cdc-registers.h delete mode 100644 asoc/codecs/wcd9360/Android.mk delete mode 100644 asoc/codecs/wcd9360/Kbuild delete mode 100644 asoc/codecs/wcd9360/wcd9360-defaults.h delete mode 100644 asoc/codecs/wcd9360/wcd9360-dsp-cntl.c delete mode 100644 asoc/codecs/wcd9360/wcd9360-dsp-cntl.h delete mode 100644 asoc/codecs/wcd9360/wcd9360-irq.h delete mode 100644 asoc/codecs/wcd9360/wcd9360-regmap.c delete mode 100644 asoc/codecs/wcd9360/wcd9360-routing.h delete mode 100644 asoc/codecs/wcd9360/wcd9360.c delete mode 100644 asoc/codecs/wcd9360/wcd9360.h delete mode 100644 asoc/msm8998.c delete mode 100644 asoc/sdm660-common.c delete mode 100644 asoc/sdm660-common.h delete mode 100644 asoc/sdm660-ext-dai-links.c delete mode 100644 asoc/sdm660-external.c delete mode 100644 asoc/sdm660-external.h delete mode 100644 asoc/sdm660-internal.c delete mode 100644 asoc/sdm660-internal.h delete mode 100644 asoc/sdm845.c delete mode 100644 config/sdm670auto.conf delete mode 100644 config/sdm670auto_static.conf delete mode 100644 config/sdm670autoconf.h delete mode 100644 config/sdm845auto.conf delete mode 100644 config/sdm845autoconf.h delete mode 100644 include/asoc/wcd9360-registers.h diff --git a/Android.mk b/Android.mk index d5be7c8da943..e3a969652da3 100644 --- a/Android.mk +++ b/Android.mk @@ -3,7 +3,7 @@ MY_LOCAL_PATH := $(call my-dir) UAPI_OUT := $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/include -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) $(shell mkdir -p $(UAPI_OUT)/linux;) $(shell mkdir -p $(UAPI_OUT)/sound;) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers) @@ -24,7 +24,7 @@ include $(MY_LOCAL_PATH)/asoc/codecs/Android.mk include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk endif -ifeq ($(call is-board-platform-in-list,sdm670 msmnile),true) +ifeq ($(call is-board-platform-in-list,msmnile),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/aqt1000/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/aqt1000/Android.mk endif @@ -35,15 +35,3 @@ include $(MY_LOCAL_PATH)/asoc/codecs/bolero/Android.mk $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd937x/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wcd937x/Android.mk endif - -ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) -$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers) -$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers) -include $(MY_LOCAL_PATH)/asoc/codecs/sdm660_cdc/Android.mk -include $(MY_LOCAL_PATH)/asoc/codecs/msm_sdw/Android.mk -endif - -ifeq ($(call is-board-platform-in-list,msmnile),true) -$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd9360/Module.symvers) -include $(MY_LOCAL_PATH)/asoc/codecs/wcd9360/Android.mk -endif diff --git a/Makefile b/Makefile index 159b68cd0e14..d9d093bde49d 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,4 @@ # auto-detect subdirs -ifeq ($(CONFIG_ARCH_SDM845), y) -include $(srctree)/techpack/audio/config/sdm845auto.conf -export -endif -ifeq ($(CONFIG_ARCH_SDM670), y) -include $(srctree)/techpack/audio/config/sdm670auto_static.conf -export -endif ifeq ($(CONFIG_ARCH_SDXPOORWILLS), y) include $(srctree)/techpack/audio/config/sdxpoorwillsauto.conf export @@ -30,14 +22,6 @@ LINUXINCLUDE += \ -I$(srctree)/techpack/audio/include/uapi \ -I$(srctree)/techpack/audio/include -ifeq ($(CONFIG_ARCH_SDM845), y) -LINUXINCLUDE += \ - -include $(srctree)/techpack/audio/config/sdm845autoconf.h -endif -ifeq ($(CONFIG_ARCH_SDM670), y) -LINUXINCLUDE += \ - -include $(srctree)/techpack/audio/config/sdm670autoconf.h -endif ifeq ($(CONFIG_ARCH_SDXPOORWILLS), y) LINUXINCLUDE += \ -include $(srctree)/techpack/audio/config/sdxpoorwillsautoconf.h diff --git a/Makefile.am b/Makefile.am index 4a9f96ed5cbf..7ee55c0d236c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,15 +11,6 @@ AUDIO_KERNEL_HEADERS_PATH1 = $(shell ls ./include/uapi/linux/*.h) AUDIO_KERNEL_HEADERS_PATH2 = $(shell ls ./include/uapi/linux/mfd/wcd9xxx/*.h) AUDIO_KERNEL_HEADERS_PATH3 = $(shell ls ./include/uapi/sound/*.h) -ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sdm670 qcs605)) -KBUILD_OPTIONS += CONFIG_ARCH_SDM670=y -endif -ifeq ($(TARGET_SUPPORT),sdm845) -KBUILD_OPTIONS += CONFIG_ARCH_SDM845=y -endif -ifeq ($(TARGET_SUPPORT),apq8053) -KBUILD_OPTIONS += CONFIG_ARCH_SDM450=y -endif ifeq ($(TARGET_SUPPORT),qcs40x) KBUILD_OPTIONS += CONFIG_ARCH_QCS405=y endif @@ -33,15 +24,9 @@ obj-m += dsp/codecs/ obj-m += soc/ obj-m += asoc/ obj-m += asoc/codecs/ -ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sdm670 qcs605 sdmsteppe)) +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sdmsteppe)) obj-m += asoc/codecs/wcd934x/ endif -ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), apq8053 sdm670 qcs605)) -obj-m += asoc/codecs/sdm660_cdc/ -endif -ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sdm670 qcs605)) -obj-m += asoc/codecs/msm_sdw/ -endif ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), qcs40x)) obj-m += asoc/codecs/bolero/ obj-m += asoc/codecs/csra66x0/ diff --git a/asoc/Android.mk b/asoc/Android.mk index ae00ed72ae3d..793712008402 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -3,16 +3,6 @@ # Assume no targets will be supported # Check if this driver needs be built for current target -ifeq ($(call is-board-platform,sdm845),true) -TARGET := sdm845 -AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m -endif - -ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) -TARGET := sdm670 -AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m -endif - ifeq ($(call is-board-platform,msmnile),true) TARGET := msmnile AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m @@ -30,7 +20,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) @@ -65,7 +55,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### -ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list, ),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_cpe_lsm.ko LOCAL_MODULE_KBUILD_NAME := cpe_lsm_dlkm.ko diff --git a/asoc/Kbuild b/asoc/Kbuild index 2481e5b922eb..17d4d211d97a 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -14,21 +14,6 @@ ifeq ($(KERNEL_BUILD), 1) endif ifeq ($(KERNEL_BUILD), 0) - ifeq ($(CONFIG_ARCH_SDM845), y) - include $(AUDIO_ROOT)/config/sdm845auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM670), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM450), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export @@ -82,28 +67,6 @@ COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) ############ ASoC Drivers ############ - -# for SDM6xx sound card driver -ifdef CONFIG_SND_SOC_SDM670 - MACHINE_OBJS += sdm660-common.o -endif - -# for SDM6xx sound card driver -ifdef CONFIG_SND_SOC_INT_CODEC - MACHINE_OBJS += sdm660-internal.o -endif - -# for SDM6xx sound card driver -ifdef CONFIG_SND_SOC_EXT_CODEC - MACHINE_OBJS += sdm660-external.o - MACHINE_OBJS += sdm660-ext-dai-links.o -endif - -# for SDM845 sound card driver -ifdef CONFIG_SND_SOC_MACHINE_SDM845 - MACHINE_OBJS += sdm845.o -endif - # for SM8150 sound card driver ifdef CONFIG_SND_SOC_SM8150 MACHINE_OBJS += sa8155.o @@ -197,8 +160,6 @@ KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd937x/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers endif ifeq ($(KERNEL_BUILD), 1) obj-y += codecs/ @@ -207,9 +168,6 @@ endif obj-$(CONFIG_SND_SOC_QDSP6V2) += platform_dlkm.o platform_dlkm-y := $(PLATFORM_OBJS) -obj-$(CONFIG_SND_SOC_MACHINE_SDM845) += machine_dlkm.o -machine_dlkm-y := $(MACHINE_OBJS) - obj-$(CONFIG_SND_SOC_SM8150) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) @@ -219,12 +177,6 @@ machine_dlkm-y := $(MACHINE_OBJS) obj-$(CONFIG_SND_SOC_QCS405) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) -obj-$(CONFIG_SND_SOC_EXT_CODEC) += machine_dlkm.o -machine_dlkm-y := $(MACHINE_OBJS) - -obj-$(CONFIG_SND_SOC_INT_CODEC) += machine_dlkm.o -machine_dlkm-y := $(MACHINE_OBJS) - obj-$(CONFIG_SND_SOC_CPE) += cpe_lsm_dlkm.o cpe_lsm_dlkm-y := $(CPE_LSM_OBJS) diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index c6c8a443a39b..8eb61c1d01fe 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -3,14 +3,6 @@ # Assume no targets will be supported # Check if this driver needs be built for current target -ifeq ($(call is-board-platform,sdm845),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m -endif - -ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m -endif - ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif @@ -25,7 +17,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) @@ -68,7 +60,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### -ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list, ),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd_cpe.ko LOCAL_MODULE_KBUILD_NAME := wcd_cpe_dlkm.ko @@ -86,7 +78,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### -ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) +ifeq ($(call is-board-platform-in-list, ),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd9335.ko LOCAL_MODULE_KBUILD_NAME := wcd9335_dlkm.ko diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 48e043119bec..6f04844027d5 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -14,21 +14,6 @@ ifeq ($(KERNEL_BUILD), 1) endif ifeq ($(KERNEL_BUILD), 0) - ifeq ($(CONFIG_ARCH_SDM845), y) - include $(AUDIO_ROOT)/config/sdm845auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM670), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM450), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export @@ -94,7 +79,6 @@ ifdef CONFIG_WCD9XXX_CODEC_CORE CORE_OBJS += msm-cdc-supply.o CORE_OBJS += wcd934x/wcd934x-regmap.o CORE_OBJS += wcd934x/wcd934x-tables.o - CORE_OBJS += wcd9360/wcd9360-regmap.o endif ifdef CONFIG_SND_SOC_WCD9XXX_V2 @@ -193,9 +177,6 @@ endif ifeq ($(KERNEL_BUILD), 1) obj-y += wcd934x/ - obj-y += sdm660_cdc/ - obj-y += msm_sdw/ - obj-y += wcd9360/ obj-y += wcd937x/ endif # Module information used by KBuild framework diff --git a/asoc/codecs/core.h b/asoc/codecs/core.h index 7d9fcd2db268..c102a55e24c0 100644 --- a/asoc/codecs/core.h +++ b/asoc/codecs/core.h @@ -105,8 +105,6 @@ #define IS_CODEC_VERSION(wcd, wcdversion) \ ((wcd->version == wcdversion) ? true : false) -#define PAHU_VERSION_1_0 0 - enum { CDC_V_1_0, CDC_V_1_1, @@ -119,7 +117,6 @@ enum codec_variant { WCD9335, WCD9326, WCD934X, - WCD9360, }; enum wcd9xxx_slim_slave_addr_type { @@ -298,7 +295,6 @@ enum wcd9xxx_chipid_major { TASHA_MAJOR = cpu_to_le16(0x0), TASHA2P0_MAJOR = cpu_to_le16(0x107), TAVIL_MAJOR = cpu_to_le16(0x108), - PAHU_MAJOR = cpu_to_le16(0x109), }; enum codec_power_states { diff --git a/asoc/codecs/msm_sdw/Android.mk b/asoc/codecs/msm_sdw/Android.mk deleted file mode 100644 index 7ec659200c94..000000000000 --- a/asoc/codecs/msm_sdw/Android.mk +++ /dev/null @@ -1,46 +0,0 @@ -# Android makefile for audio kernel modules - -# Assume no targets will be supported - -AUDIO_CHIPSET := audio -# Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m - -LOCAL_PATH := $(call my-dir) - -# This makefile is only for DLKM -ifneq ($(findstring vendor,$(LOCAL_PATH)),) - -ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel -endif # opensource - -DLKM_DIR := $(TOP)/device/qcom/common/dlkm - -# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko -########################################################### -# This is set once per LOCAL_PATH, not per (kernel) module -KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) - -# We are actually building audio.ko here, as per the -# requirement we are specifying _audio.ko as LOCAL_MODULE. -# This means we need to rename the module to _audio.ko -# after audio.ko is built. -KBUILD_OPTIONS += MODNAME=msm_sdw_dlkm -KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) -KBUILD_OPTIONS += $(AUDIO_SELECT) - -########################################################### -include $(CLEAR_VARS) -LOCAL_MODULE := $(AUDIO_CHIPSET)_msm_sdw.ko -LOCAL_MODULE_KBUILD_NAME := msm_sdw_dlkm.ko -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE_DEBUG_ENABLE := true -LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) -include $(DLKM_DIR)/AndroidKernelModule.mk -########################################################### -########################################################### - -endif # DLKM check -endif # supported target check diff --git a/asoc/codecs/msm_sdw/Kbuild b/asoc/codecs/msm_sdw/Kbuild deleted file mode 100644 index 46639d29f011..000000000000 --- a/asoc/codecs/msm_sdw/Kbuild +++ /dev/null @@ -1,115 +0,0 @@ -# We can build either as part of a standalone Kernel build or as -# an external module. Determine which mechanism is being used -ifeq ($(MODNAME),) - KERNEL_BUILD := 1 -else - KERNEL_BUILD := 0 -endif - - -ifeq ($(KERNEL_BUILD), 1) - # These are configurable via Kconfig for kernel-based builds - # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.9 - AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio -endif - -ifeq ($(KERNEL_BUILD), 0) - ifeq ($(CONFIG_ARCH_SDM845), y) - include $(AUDIO_ROOT)/config/sdm845auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM670), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM450), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif -endif - -# As per target team, build is done as follows: -# Defconfig : build with default flags -# Slub : defconfig + CONFIG_SLUB_DEBUG := y + -# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y -# Perf : Using appropriate msmXXXX-perf_defconfig -# -# Shipment builds (user variants) should not have any debug feature -# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds -# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since -# there is no other way to identify defconfig builds, QTI internal -# representation of perf builds (identified using the string 'perf'), -# is used to identify if the build is a slub or defconfig one. This -# way no critical debug feature will be enabled for perf and shipment -# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT -# config. - -############ UAPI ############ -UAPI_DIR := uapi -UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) - -############ COMMON ############ -COMMON_DIR := include -COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) - -############ MSM Soundwire ############ - -# for MSM Soundwire Codec -ifdef CONFIG_SND_SOC_MSM_SDW - MSM_SDW_OBJS += msm_sdw_cdc.o - MSM_SDW_OBJS += msm_sdw_regmap.o - MSM_SDW_OBJS += msm-sdw-tables.o - MSM_SDW_OBJS += msm_sdw_cdc_utils.o -endif - -LINUX_INC += -Iinclude/linux - -INCS += $(COMMON_INC) \ - $(UAPI_INC) - -EXTRA_CFLAGS += $(INCS) - - -CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ - -DANI_LITTLE_BIT_ENDIAN \ - -DDOT11F_LITTLE_ENDIAN_HOST \ - -DANI_COMPILER_TYPE_GCC \ - -DANI_OS_TYPE_ANDROID=6 \ - -DPTT_SOCK_SVC_ENABLE \ - -Wall\ - -Werror\ - -D__linux__ - -KBUILD_CPPFLAGS += $(CDEFINES) - -# Currently, for versions of gcc which support it, the kernel Makefile -# is disabling the maybe-uninitialized warning. Re-enable it for the -# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it -# will override the kernel settings. -ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) -EXTRA_CFLAGS += -Wmaybe-uninitialized -endif -#EXTRA_CFLAGS += -Wmissing-prototypes - -ifeq ($(call cc-option-yn, -Wheader-guard),y) -EXTRA_CFLAGS += -Wheader-guard -endif - -ifeq ($(KERNEL_BUILD), 0) -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers -endif - -# Module information used by KBuild framework -obj-$(CONFIG_SND_SOC_MSM_SDW) += msm_sdw_dlkm.o -msm_sdw_dlkm-y := $(MSM_SDW_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/msm_sdw/msm-sdw-tables.c b/asoc/codecs/msm_sdw/msm-sdw-tables.c deleted file mode 100644 index 1b51805bb92e..000000000000 --- a/asoc/codecs/msm_sdw/msm-sdw-tables.c +++ /dev/null @@ -1,319 +0,0 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include "msm_sdw.h" - -const u8 msm_sdw_page_map[MSM_SDW_MAX_REGISTER] = { - [MSM_SDW_TX9_SPKR_PROT_PATH_CTL] = 0xa, - [MSM_SDW_TX9_SPKR_PROT_PATH_CFG0] = 0xa, - [MSM_SDW_TX10_SPKR_PROT_PATH_CTL] = 0xa, - [MSM_SDW_TX10_SPKR_PROT_PATH_CFG0] = 0xa, - [MSM_SDW_TX11_SPKR_PROT_PATH_CTL] = 0xa, - [MSM_SDW_TX11_SPKR_PROT_PATH_CFG0] = 0xa, - [MSM_SDW_TX12_SPKR_PROT_PATH_CTL] = 0xa, - [MSM_SDW_TX12_SPKR_PROT_PATH_CFG0] = 0xa, - [MSM_SDW_COMPANDER7_CTL0] = 0xb, - [MSM_SDW_COMPANDER7_CTL1] = 0xb, - [MSM_SDW_COMPANDER7_CTL2] = 0xb, - [MSM_SDW_COMPANDER7_CTL3] = 0xb, - [MSM_SDW_COMPANDER7_CTL4] = 0xb, - [MSM_SDW_COMPANDER7_CTL5] = 0xb, - [MSM_SDW_COMPANDER7_CTL6] = 0xb, - [MSM_SDW_COMPANDER7_CTL7] = 0xb, - [MSM_SDW_COMPANDER8_CTL0] = 0xb, - [MSM_SDW_COMPANDER8_CTL1] = 0xb, - [MSM_SDW_COMPANDER8_CTL2] = 0xb, - [MSM_SDW_COMPANDER8_CTL3] = 0xb, - [MSM_SDW_COMPANDER8_CTL4] = 0xb, - [MSM_SDW_COMPANDER8_CTL5] = 0xb, - [MSM_SDW_COMPANDER8_CTL6] = 0xb, - [MSM_SDW_COMPANDER8_CTL7] = 0xb, - [MSM_SDW_RX7_RX_PATH_CTL] = 0xb, - [MSM_SDW_RX7_RX_PATH_CFG0] = 0xb, - [MSM_SDW_RX7_RX_PATH_CFG1] = 0xb, - [MSM_SDW_RX7_RX_PATH_CFG2] = 0xb, - [MSM_SDW_RX7_RX_VOL_CTL] = 0xb, - [MSM_SDW_RX7_RX_PATH_MIX_CTL] = 0xb, - [MSM_SDW_RX7_RX_PATH_MIX_CFG] = 0xb, - [MSM_SDW_RX7_RX_VOL_MIX_CTL] = 0xb, - [MSM_SDW_RX7_RX_PATH_SEC0] = 0xb, - [MSM_SDW_RX7_RX_PATH_SEC1] = 0xb, - [MSM_SDW_RX7_RX_PATH_SEC2] = 0xb, - [MSM_SDW_RX7_RX_PATH_SEC3] = 0xb, - [MSM_SDW_RX7_RX_PATH_SEC5] = 0xb, - [MSM_SDW_RX7_RX_PATH_SEC6] = 0xb, - [MSM_SDW_RX7_RX_PATH_SEC7] = 0xb, - [MSM_SDW_RX7_RX_PATH_MIX_SEC0] = 0xb, - [MSM_SDW_RX7_RX_PATH_MIX_SEC1] = 0xb, - [MSM_SDW_RX8_RX_PATH_CTL] = 0xb, - [MSM_SDW_RX8_RX_PATH_CFG0] = 0xb, - [MSM_SDW_RX8_RX_PATH_CFG1] = 0xb, - [MSM_SDW_RX8_RX_PATH_CFG2] = 0xb, - [MSM_SDW_RX8_RX_VOL_CTL] = 0xb, - [MSM_SDW_RX8_RX_PATH_MIX_CTL] = 0xb, - [MSM_SDW_RX8_RX_PATH_MIX_CFG] = 0xb, - [MSM_SDW_RX8_RX_VOL_MIX_CTL] = 0xb, - [MSM_SDW_RX8_RX_PATH_SEC0] = 0xb, - [MSM_SDW_RX8_RX_PATH_SEC1] = 0xb, - [MSM_SDW_RX8_RX_PATH_SEC2] = 0xb, - [MSM_SDW_RX8_RX_PATH_SEC3] = 0xb, - [MSM_SDW_RX8_RX_PATH_SEC5] = 0xb, - [MSM_SDW_RX8_RX_PATH_SEC6] = 0xb, - [MSM_SDW_RX8_RX_PATH_SEC7] = 0xb, - [MSM_SDW_RX8_RX_PATH_MIX_SEC0] = 0xb, - [MSM_SDW_RX8_RX_PATH_MIX_SEC1] = 0xb, - [MSM_SDW_BOOST0_BOOST_PATH_CTL] = 0xc, - [MSM_SDW_BOOST0_BOOST_CTL] = 0xc, - [MSM_SDW_BOOST0_BOOST_CFG1] = 0xc, - [MSM_SDW_BOOST0_BOOST_CFG2] = 0xc, - [MSM_SDW_BOOST1_BOOST_PATH_CTL] = 0xc, - [MSM_SDW_BOOST1_BOOST_CTL] = 0xc, - [MSM_SDW_BOOST1_BOOST_CFG1] = 0xc, - [MSM_SDW_BOOST1_BOOST_CFG2] = 0xc, - [MSM_SDW_AHB_BRIDGE_WR_DATA_0] = 0xc, - [MSM_SDW_AHB_BRIDGE_WR_DATA_1] = 0xc, - [MSM_SDW_AHB_BRIDGE_WR_DATA_2] = 0xc, - [MSM_SDW_AHB_BRIDGE_WR_DATA_3] = 0xc, - [MSM_SDW_AHB_BRIDGE_WR_ADDR_0] = 0xc, - [MSM_SDW_AHB_BRIDGE_WR_ADDR_1] = 0xc, - [MSM_SDW_AHB_BRIDGE_WR_ADDR_2] = 0xc, - [MSM_SDW_AHB_BRIDGE_WR_ADDR_3] = 0xc, - [MSM_SDW_AHB_BRIDGE_RD_ADDR_0] = 0xc, - [MSM_SDW_AHB_BRIDGE_RD_ADDR_1] = 0xc, - [MSM_SDW_AHB_BRIDGE_RD_ADDR_2] = 0xc, - [MSM_SDW_AHB_BRIDGE_RD_ADDR_3] = 0xc, - [MSM_SDW_AHB_BRIDGE_RD_DATA_0] = 0xc, - [MSM_SDW_AHB_BRIDGE_RD_DATA_1] = 0xc, - [MSM_SDW_AHB_BRIDGE_RD_DATA_2] = 0xc, - [MSM_SDW_AHB_BRIDGE_RD_DATA_3] = 0xc, - [MSM_SDW_AHB_BRIDGE_ACCESS_CFG] = 0xc, - [MSM_SDW_AHB_BRIDGE_ACCESS_STATUS] = 0xc, - [MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL] = 0xd, - [MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL] = 0xd, - [MSM_SDW_CLK_RST_CTRL_SWR_CONTROL] = 0xd, - [MSM_SDW_TOP_TOP_CFG0] = 0xd, - [MSM_SDW_TOP_TOP_CFG1] = 0xd, - [MSM_SDW_TOP_RX_I2S_CTL] = 0xd, - [MSM_SDW_TOP_TX_I2S_CTL] = 0xd, - [MSM_SDW_TOP_I2S_CLK] = 0xd, - [MSM_SDW_TOP_RX7_PATH_INPUT0_MUX] = 0xd, - [MSM_SDW_TOP_RX7_PATH_INPUT1_MUX] = 0xd, - [MSM_SDW_TOP_RX8_PATH_INPUT0_MUX] = 0xd, - [MSM_SDW_TOP_RX8_PATH_INPUT1_MUX] = 0xd, - [MSM_SDW_TOP_FREQ_MCLK] = 0xd, - [MSM_SDW_TOP_DEBUG_BUS_SEL] = 0xd, - [MSM_SDW_TOP_DEBUG_EN] = 0xd, - [MSM_SDW_TOP_I2S_RESET] = 0xd, - [MSM_SDW_TOP_BLOCKS_RESET] = 0xd, -}; - -const u8 msm_sdw_reg_readable[MSM_SDW_MAX_REGISTER] = { - [MSM_SDW_PAGE_REGISTER] = 1, - [MSM_SDW_TX9_SPKR_PROT_PATH_CTL] = 1, - [MSM_SDW_TX9_SPKR_PROT_PATH_CFG0] = 1, - [MSM_SDW_TX10_SPKR_PROT_PATH_CTL] = 1, - [MSM_SDW_TX10_SPKR_PROT_PATH_CFG0] = 1, - [MSM_SDW_TX11_SPKR_PROT_PATH_CTL] = 1, - [MSM_SDW_TX11_SPKR_PROT_PATH_CFG0] = 1, - [MSM_SDW_TX12_SPKR_PROT_PATH_CTL] = 1, - [MSM_SDW_TX12_SPKR_PROT_PATH_CFG0] = 1, - [MSM_SDW_COMPANDER7_CTL0] = 1, - [MSM_SDW_COMPANDER7_CTL1] = 1, - [MSM_SDW_COMPANDER7_CTL2] = 1, - [MSM_SDW_COMPANDER7_CTL3] = 1, - [MSM_SDW_COMPANDER7_CTL4] = 1, - [MSM_SDW_COMPANDER7_CTL5] = 1, - [MSM_SDW_COMPANDER7_CTL6] = 1, - [MSM_SDW_COMPANDER7_CTL7] = 1, - [MSM_SDW_COMPANDER8_CTL0] = 1, - [MSM_SDW_COMPANDER8_CTL1] = 1, - [MSM_SDW_COMPANDER8_CTL2] = 1, - [MSM_SDW_COMPANDER8_CTL3] = 1, - [MSM_SDW_COMPANDER8_CTL4] = 1, - [MSM_SDW_COMPANDER8_CTL5] = 1, - [MSM_SDW_COMPANDER8_CTL6] = 1, - [MSM_SDW_COMPANDER8_CTL7] = 1, - [MSM_SDW_RX7_RX_PATH_CTL] = 1, - [MSM_SDW_RX7_RX_PATH_CFG0] = 1, - [MSM_SDW_RX7_RX_PATH_CFG1] = 1, - [MSM_SDW_RX7_RX_PATH_CFG2] = 1, - [MSM_SDW_RX7_RX_VOL_CTL] = 1, - [MSM_SDW_RX7_RX_PATH_MIX_CTL] = 1, - [MSM_SDW_RX7_RX_PATH_MIX_CFG] = 1, - [MSM_SDW_RX7_RX_VOL_MIX_CTL] = 1, - [MSM_SDW_RX7_RX_PATH_SEC0] = 1, - [MSM_SDW_RX7_RX_PATH_SEC1] = 1, - [MSM_SDW_RX7_RX_PATH_SEC2] = 1, - [MSM_SDW_RX7_RX_PATH_SEC3] = 1, - [MSM_SDW_RX7_RX_PATH_SEC5] = 1, - [MSM_SDW_RX7_RX_PATH_SEC6] = 1, - [MSM_SDW_RX7_RX_PATH_SEC7] = 1, - [MSM_SDW_RX7_RX_PATH_MIX_SEC0] = 1, - [MSM_SDW_RX7_RX_PATH_MIX_SEC1] = 1, - [MSM_SDW_RX8_RX_PATH_CTL] = 1, - [MSM_SDW_RX8_RX_PATH_CFG0] = 1, - [MSM_SDW_RX8_RX_PATH_CFG1] = 1, - [MSM_SDW_RX8_RX_PATH_CFG2] = 1, - [MSM_SDW_RX8_RX_VOL_CTL] = 1, - [MSM_SDW_RX8_RX_PATH_MIX_CTL] = 1, - [MSM_SDW_RX8_RX_PATH_MIX_CFG] = 1, - [MSM_SDW_RX8_RX_VOL_MIX_CTL] = 1, - [MSM_SDW_RX8_RX_PATH_SEC0] = 1, - [MSM_SDW_RX8_RX_PATH_SEC1] = 1, - [MSM_SDW_RX8_RX_PATH_SEC2] = 1, - [MSM_SDW_RX8_RX_PATH_SEC3] = 1, - [MSM_SDW_RX8_RX_PATH_SEC5] = 1, - [MSM_SDW_RX8_RX_PATH_SEC6] = 1, - [MSM_SDW_RX8_RX_PATH_SEC7] = 1, - [MSM_SDW_RX8_RX_PATH_MIX_SEC0] = 1, - [MSM_SDW_RX8_RX_PATH_MIX_SEC1] = 1, - [MSM_SDW_BOOST0_BOOST_PATH_CTL] = 1, - [MSM_SDW_BOOST0_BOOST_CTL] = 1, - [MSM_SDW_BOOST0_BOOST_CFG1] = 1, - [MSM_SDW_BOOST0_BOOST_CFG2] = 1, - [MSM_SDW_BOOST1_BOOST_PATH_CTL] = 1, - [MSM_SDW_BOOST1_BOOST_CTL] = 1, - [MSM_SDW_BOOST1_BOOST_CFG1] = 1, - [MSM_SDW_BOOST1_BOOST_CFG2] = 1, - [MSM_SDW_AHB_BRIDGE_WR_DATA_0] = 1, - [MSM_SDW_AHB_BRIDGE_WR_DATA_1] = 1, - [MSM_SDW_AHB_BRIDGE_WR_DATA_2] = 1, - [MSM_SDW_AHB_BRIDGE_WR_DATA_3] = 1, - [MSM_SDW_AHB_BRIDGE_WR_ADDR_0] = 1, - [MSM_SDW_AHB_BRIDGE_WR_ADDR_1] = 1, - [MSM_SDW_AHB_BRIDGE_WR_ADDR_2] = 1, - [MSM_SDW_AHB_BRIDGE_WR_ADDR_3] = 1, - [MSM_SDW_AHB_BRIDGE_RD_ADDR_0] = 1, - [MSM_SDW_AHB_BRIDGE_RD_ADDR_1] = 1, - [MSM_SDW_AHB_BRIDGE_RD_ADDR_2] = 1, - [MSM_SDW_AHB_BRIDGE_RD_ADDR_3] = 1, - [MSM_SDW_AHB_BRIDGE_RD_DATA_0] = 1, - [MSM_SDW_AHB_BRIDGE_RD_DATA_1] = 1, - [MSM_SDW_AHB_BRIDGE_RD_DATA_2] = 1, - [MSM_SDW_AHB_BRIDGE_RD_DATA_3] = 1, - [MSM_SDW_AHB_BRIDGE_ACCESS_CFG] = 1, - [MSM_SDW_AHB_BRIDGE_ACCESS_STATUS] = 1, - [MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL] = 1, - [MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL] = 1, - [MSM_SDW_CLK_RST_CTRL_SWR_CONTROL] = 1, - [MSM_SDW_TOP_TOP_CFG0] = 1, - [MSM_SDW_TOP_TOP_CFG1] = 1, - [MSM_SDW_TOP_RX_I2S_CTL] = 1, - [MSM_SDW_TOP_TX_I2S_CTL] = 1, - [MSM_SDW_TOP_RX7_PATH_INPUT0_MUX] = 1, - [MSM_SDW_TOP_RX7_PATH_INPUT1_MUX] = 1, - [MSM_SDW_TOP_RX8_PATH_INPUT0_MUX] = 1, - [MSM_SDW_TOP_RX8_PATH_INPUT1_MUX] = 1, - [MSM_SDW_TOP_FREQ_MCLK] = 1, - [MSM_SDW_TOP_DEBUG_BUS_SEL] = 1, - [MSM_SDW_TOP_DEBUG_EN] = 1, - [MSM_SDW_TOP_I2S_RESET] = 1, - [MSM_SDW_TOP_BLOCKS_RESET] = 1, -}; - -const u8 msm_sdw_reg_writeable[MSM_SDW_MAX_REGISTER] = { - [MSM_SDW_PAGE_REGISTER] = 1, - [MSM_SDW_TX9_SPKR_PROT_PATH_CTL] = 1, - [MSM_SDW_TX9_SPKR_PROT_PATH_CFG0] = 1, - [MSM_SDW_TX10_SPKR_PROT_PATH_CTL] = 1, - [MSM_SDW_TX10_SPKR_PROT_PATH_CFG0] = 1, - [MSM_SDW_TX11_SPKR_PROT_PATH_CTL] = 1, - [MSM_SDW_TX11_SPKR_PROT_PATH_CFG0] = 1, - [MSM_SDW_TX12_SPKR_PROT_PATH_CTL] = 1, - [MSM_SDW_TX12_SPKR_PROT_PATH_CFG0] = 1, - [MSM_SDW_COMPANDER7_CTL0] = 1, - [MSM_SDW_COMPANDER7_CTL1] = 1, - [MSM_SDW_COMPANDER7_CTL2] = 1, - [MSM_SDW_COMPANDER7_CTL3] = 1, - [MSM_SDW_COMPANDER7_CTL4] = 1, - [MSM_SDW_COMPANDER7_CTL5] = 1, - [MSM_SDW_COMPANDER7_CTL7] = 1, - [MSM_SDW_COMPANDER8_CTL0] = 1, - [MSM_SDW_COMPANDER8_CTL1] = 1, - [MSM_SDW_COMPANDER8_CTL2] = 1, - [MSM_SDW_COMPANDER8_CTL3] = 1, - [MSM_SDW_COMPANDER8_CTL4] = 1, - [MSM_SDW_COMPANDER8_CTL5] = 1, - [MSM_SDW_COMPANDER8_CTL7] = 1, - [MSM_SDW_RX7_RX_PATH_CTL] = 1, - [MSM_SDW_RX7_RX_PATH_CFG0] = 1, - [MSM_SDW_RX7_RX_PATH_CFG1] = 1, - [MSM_SDW_RX7_RX_PATH_CFG2] = 1, - [MSM_SDW_RX7_RX_VOL_CTL] = 1, - [MSM_SDW_RX7_RX_PATH_MIX_CTL] = 1, - [MSM_SDW_RX7_RX_PATH_MIX_CFG] = 1, - [MSM_SDW_RX7_RX_VOL_MIX_CTL] = 1, - [MSM_SDW_RX7_RX_PATH_SEC0] = 1, - [MSM_SDW_RX7_RX_PATH_SEC1] = 1, - [MSM_SDW_RX7_RX_PATH_SEC2] = 1, - [MSM_SDW_RX7_RX_PATH_SEC3] = 1, - [MSM_SDW_RX7_RX_PATH_SEC5] = 1, - [MSM_SDW_RX7_RX_PATH_SEC6] = 1, - [MSM_SDW_RX7_RX_PATH_SEC7] = 1, - [MSM_SDW_RX7_RX_PATH_MIX_SEC0] = 1, - [MSM_SDW_RX7_RX_PATH_MIX_SEC1] = 1, - [MSM_SDW_RX8_RX_PATH_CTL] = 1, - [MSM_SDW_RX8_RX_PATH_CFG0] = 1, - [MSM_SDW_RX8_RX_PATH_CFG1] = 1, - [MSM_SDW_RX8_RX_PATH_CFG2] = 1, - [MSM_SDW_RX8_RX_VOL_CTL] = 1, - [MSM_SDW_RX8_RX_PATH_MIX_CTL] = 1, - [MSM_SDW_RX8_RX_PATH_MIX_CFG] = 1, - [MSM_SDW_RX8_RX_VOL_MIX_CTL] = 1, - [MSM_SDW_RX8_RX_PATH_SEC0] = 1, - [MSM_SDW_RX8_RX_PATH_SEC1] = 1, - [MSM_SDW_RX8_RX_PATH_SEC2] = 1, - [MSM_SDW_RX8_RX_PATH_SEC3] = 1, - [MSM_SDW_RX8_RX_PATH_SEC5] = 1, - [MSM_SDW_RX8_RX_PATH_SEC6] = 1, - [MSM_SDW_RX8_RX_PATH_SEC7] = 1, - [MSM_SDW_RX8_RX_PATH_MIX_SEC0] = 1, - [MSM_SDW_RX8_RX_PATH_MIX_SEC1] = 1, - [MSM_SDW_BOOST0_BOOST_PATH_CTL] = 1, - [MSM_SDW_BOOST0_BOOST_CTL] = 1, - [MSM_SDW_BOOST0_BOOST_CFG1] = 1, - [MSM_SDW_BOOST0_BOOST_CFG2] = 1, - [MSM_SDW_BOOST1_BOOST_PATH_CTL] = 1, - [MSM_SDW_BOOST1_BOOST_CTL] = 1, - [MSM_SDW_BOOST1_BOOST_CFG1] = 1, - [MSM_SDW_BOOST1_BOOST_CFG2] = 1, - [MSM_SDW_AHB_BRIDGE_WR_DATA_0] = 1, - [MSM_SDW_AHB_BRIDGE_WR_DATA_1] = 1, - [MSM_SDW_AHB_BRIDGE_WR_DATA_2] = 1, - [MSM_SDW_AHB_BRIDGE_WR_DATA_3] = 1, - [MSM_SDW_AHB_BRIDGE_WR_ADDR_0] = 1, - [MSM_SDW_AHB_BRIDGE_WR_ADDR_1] = 1, - [MSM_SDW_AHB_BRIDGE_WR_ADDR_2] = 1, - [MSM_SDW_AHB_BRIDGE_WR_ADDR_3] = 1, - [MSM_SDW_AHB_BRIDGE_RD_ADDR_0] = 1, - [MSM_SDW_AHB_BRIDGE_RD_ADDR_1] = 1, - [MSM_SDW_AHB_BRIDGE_RD_ADDR_2] = 1, - [MSM_SDW_AHB_BRIDGE_RD_ADDR_3] = 1, - [MSM_SDW_AHB_BRIDGE_ACCESS_CFG] = 1, - [MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL] = 1, - [MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL] = 1, - [MSM_SDW_CLK_RST_CTRL_SWR_CONTROL] = 1, - [MSM_SDW_TOP_TOP_CFG0] = 1, - [MSM_SDW_TOP_TOP_CFG1] = 1, - [MSM_SDW_TOP_RX_I2S_CTL] = 1, - [MSM_SDW_TOP_TX_I2S_CTL] = 1, - [MSM_SDW_TOP_RX7_PATH_INPUT0_MUX] = 1, - [MSM_SDW_TOP_RX7_PATH_INPUT1_MUX] = 1, - [MSM_SDW_TOP_RX8_PATH_INPUT0_MUX] = 1, - [MSM_SDW_TOP_RX8_PATH_INPUT1_MUX] = 1, - [MSM_SDW_TOP_FREQ_MCLK] = 1, - [MSM_SDW_TOP_DEBUG_BUS_SEL] = 1, - [MSM_SDW_TOP_DEBUG_EN] = 1, - [MSM_SDW_TOP_I2S_RESET] = 1, - [MSM_SDW_TOP_BLOCKS_RESET] = 1, -}; diff --git a/asoc/codecs/msm_sdw/msm_sdw.h b/asoc/codecs/msm_sdw/msm_sdw.h deleted file mode 100644 index 3c7a07dca673..000000000000 --- a/asoc/codecs/msm_sdw/msm_sdw.h +++ /dev/null @@ -1,203 +0,0 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef MSM_SDW_H -#define MSM_SDW_H - -#include -#include -#include "msm_sdw_registers.h" - -#define MSM_SDW_MAX_REGISTER 0x400 -#define MSM_SDW_CHILD_DEVICES_MAX 1 - -extern const struct regmap_config msm_sdw_regmap_config; -extern const u8 msm_sdw_page_map[MSM_SDW_MAX_REGISTER]; -extern const u8 msm_sdw_reg_readable[MSM_SDW_MAX_REGISTER]; -extern const u8 msm_sdw_reg_writeable[MSM_SDW_MAX_REGISTER]; - -enum { - MSM_SDW_RX4 = 0, - MSM_SDW_RX5, - MSM_SDW_RX_MAX, -}; - -enum { - MSM_SDW_TX0 = 0, - MSM_SDW_TX1, - MSM_SDW_TX_MAX, -}; - -enum { - COMP1, /* SPK_L */ - COMP2, /* SPK_R */ - COMP_MAX -}; - -/* - * Structure used to update codec - * register defaults after reset - */ -struct msm_sdw_reg_mask_val { - u16 reg; - u8 mask; - u8 val; -}; - -/* - * Selects compander and smart boost settings - * for a given speaker mode - */ -enum { - SPKR_MODE_DEFAULT, - SPKR_MODE_1, /* COMP Gain = 12dB, Smartboost Max = 5.5V */ -}; - -/* Rx path gain offsets */ -enum { - RX_GAIN_OFFSET_M1P5_DB, - RX_GAIN_OFFSET_0_DB, -}; - -struct msm_sdw_reg_val { - unsigned short reg; /* register address */ - u8 *buf; /* buffer to be written to reg. addr */ - int bytes; /* number of bytes to be written */ -}; - -/* Hold instance to soundwire platform device */ -struct msm_sdw_ctrl_data { - struct platform_device *sdw_pdev; -}; - -struct wcd_sdw_ctrl_platform_data { - void *handle; /* holds codec private data */ - int (*read)(void *handle, int reg); - int (*write)(void *handle, int reg, int val); - int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); - int (*clk)(void *handle, bool enable); - int (*handle_irq)(void *handle, - irqreturn_t (*swrm_irq_handler)(int irq, - void *data), - void *swrm_handle, - int action); -}; - -struct msm_sdw_priv { - struct device *dev; - struct mutex io_lock; - - int (*read_dev)(struct msm_sdw_priv *msm_sdw, unsigned short reg, - int bytes, void *dest); - int (*write_dev)(struct msm_sdw_priv *msm_sdw, unsigned short reg, - int bytes, void *src); - int (*multi_reg_write)(struct msm_sdw_priv *msm_sdw, const void *data, - size_t count); - struct snd_soc_codec *codec; - struct device_node *sdw_gpio_p; /* used by pinctrl API */ - /* SoundWire data structure */ - struct msm_sdw_ctrl_data *sdw_ctrl_data; - int nr; - - /* compander */ - int comp_enabled[COMP_MAX]; - int ear_spkr_gain; - - /* to track the status */ - unsigned long status_mask; - - struct work_struct msm_sdw_add_child_devices_work; - struct wcd_sdw_ctrl_platform_data sdw_plat_data; - - unsigned int vi_feed_value; - - struct mutex sdw_read_lock; - struct mutex sdw_write_lock; - struct mutex sdw_clk_lock; - int sdw_clk_users; - int sdw_mclk_users; - - int sdw_irq; - int int_mclk1_rsc_ref; - bool int_mclk1_enabled; - bool sdw_npl_clk_enabled; - struct mutex cdc_int_mclk1_mutex; - struct mutex sdw_npl_clk_mutex; - struct delayed_work disable_int_mclk1_work; - struct afe_clk_set sdw_cdc_core_clk; - struct afe_clk_set sdw_npl_clk; - struct notifier_block service_nb; - int (*sdw_cdc_gpio_fn)(bool enable, struct snd_soc_codec *codec); - bool dev_up; - - int spkr_gain_offset; - int spkr_mode; - struct mutex codec_mutex; - int rx_4_count; - int rx_5_count; - u32 mclk_rate; - struct regmap *regmap; - - bool prev_pg_valid; - u8 prev_pg; - u32 sdw_base_addr; - char __iomem *sdw_base; - u32 version; - - /* Entry for version info */ - struct snd_info_entry *entry; - struct snd_info_entry *version_entry; - struct platform_device *pdev_child_devices - [MSM_SDW_CHILD_DEVICES_MAX]; - int child_count; -}; - -#if IS_ENABLED(CONFIG_SND_SOC_MSM_SDW) -extern int msm_sdw_set_spkr_mode(struct snd_soc_codec *codec, int mode); -extern int msm_sdw_set_spkr_gain_offset(struct snd_soc_codec *codec, - int offset); -extern void msm_sdw_gpio_cb( - int (*sdw_cdc_gpio_fn)(bool enable, struct snd_soc_codec *codec), - struct snd_soc_codec *codec); -extern struct regmap *msm_sdw_regmap_init(struct device *dev, - const struct regmap_config *config); -extern int msm_sdw_codec_info_create_codec_entry( - struct snd_info_entry *codec_root, - struct snd_soc_codec *codec); -#else /* CONFIG_SND_SOC_MSM_SDW */ -static inline int msm_sdw_set_spkr_mode(struct snd_soc_codec *codec, int mode) -{ - return 0; -} -static inline int msm_sdw_set_spkr_gain_offset(struct snd_soc_codec *codec, - int offset); -{ - return 0; -} -static inline void msm_sdw_gpio_cb( - int (*sdw_cdc_gpio_fn)(bool enable, struct snd_soc_codec *codec), - struct snd_soc_codec *codec); -{ - -} -static inline struct regmap *msm_sdw_regmap_init(struct device *dev, - const struct regmap_config *config); -{ - return NULL; -} -static inline int msm_sdw_codec_info_create_codec_entry( - struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) -{ - return 0; -} -#endif /* CONFIG_SND_SOC_MSM_SDW */ -#endif diff --git a/asoc/codecs/msm_sdw/msm_sdw_cdc.c b/asoc/codecs/msm_sdw/msm_sdw_cdc.c deleted file mode 100644 index 69e340736ad9..000000000000 --- a/asoc/codecs/msm_sdw/msm_sdw_cdc.c +++ /dev/null @@ -1,2097 +0,0 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "msm_sdw.h" -#include "msm_sdw_registers.h" -#include "../msm-cdc-pinctrl.h" - -#define MSM_SDW_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ - SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000) -#define MSM_SDW_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S24_LE |\ - SNDRV_PCM_FMTBIT_S24_3LE) - -#define MSM_SDW_STRING_LEN 80 - -#define INT_MCLK1_FREQ 9600000 -#define SDW_NPL_FREQ 153600000 - -#define MSM_SDW_VERSION_1_0 0x0001 -#define MSM_SDW_VERSION_ENTRY_SIZE 32 - -/* - * 200 Milliseconds sufficient for DSP bring up in the modem - * after Sub System Restart - */ -#define ADSP_STATE_READY_TIMEOUT_MS 200 - -static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); -static struct snd_soc_dai_driver msm_sdw_dai[]; -static bool skip_irq = true; - -static int msm_sdw_config_ear_spkr_gain(struct snd_soc_codec *codec, - int event, int gain_reg); -static int msm_sdw_config_compander(struct snd_soc_codec *, int, int); -static int msm_sdw_mclk_enable(struct msm_sdw_priv *msm_sdw, - int mclk_enable, bool dapm); -static int msm_int_enable_sdw_cdc_clk(struct msm_sdw_priv *msm_sdw, - int enable, bool dapm); - -enum { - VI_SENSE_1, - VI_SENSE_2, -}; - -enum { - AIF1_SDW_PB = 0, - AIF1_SDW_VIFEED, - NUM_CODEC_DAIS, -}; - -static const struct msm_sdw_reg_mask_val msm_sdw_spkr_default[] = { - {MSM_SDW_COMPANDER7_CTL3, 0x80, 0x80}, - {MSM_SDW_COMPANDER8_CTL3, 0x80, 0x80}, - {MSM_SDW_COMPANDER7_CTL7, 0x01, 0x01}, - {MSM_SDW_COMPANDER8_CTL7, 0x01, 0x01}, - {MSM_SDW_BOOST0_BOOST_CTL, 0x7C, 0x58}, - {MSM_SDW_BOOST1_BOOST_CTL, 0x7C, 0x58}, -}; - -static const struct msm_sdw_reg_mask_val msm_sdw_spkr_mode1[] = { - {MSM_SDW_COMPANDER7_CTL3, 0x80, 0x00}, - {MSM_SDW_COMPANDER8_CTL3, 0x80, 0x00}, - {MSM_SDW_COMPANDER7_CTL7, 0x01, 0x00}, - {MSM_SDW_COMPANDER8_CTL7, 0x01, 0x00}, - {MSM_SDW_BOOST0_BOOST_CTL, 0x7C, 0x44}, - {MSM_SDW_BOOST1_BOOST_CTL, 0x7C, 0x44}, -}; - -/** - * msm_sdw_set_spkr_gain_offset - offset the speaker path - * gain with the given offset value. - * - * @codec: codec instance - * @offset: Indicates speaker path gain offset value. - * - * Returns 0 on success or -EINVAL on error. - */ -int msm_sdw_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset) -{ - struct msm_sdw_priv *priv; - - if (!codec) { - pr_err("%s: NULL codec pointer!\n", __func__); - return -EINVAL; - } - - priv = snd_soc_codec_get_drvdata(codec); - if (!priv) - return -EINVAL; - - priv->spkr_gain_offset = offset; - return 0; -} -EXPORT_SYMBOL(msm_sdw_set_spkr_gain_offset); - -/** - * msm_sdw_set_spkr_mode - Configures speaker compander and smartboost - * settings based on speaker mode. - * - * @codec: codec instance - * @mode: Indicates speaker configuration mode. - * - * Returns 0 on success or -EINVAL on error. - */ -int msm_sdw_set_spkr_mode(struct snd_soc_codec *codec, int mode) -{ - struct msm_sdw_priv *priv; - int i; - const struct msm_sdw_reg_mask_val *regs; - int size; - - if (!codec) { - pr_err("%s: NULL codec pointer!\n", __func__); - return -EINVAL; - } - - priv = snd_soc_codec_get_drvdata(codec); - if (!priv) - return -EINVAL; - - switch (mode) { - case SPKR_MODE_1: - regs = msm_sdw_spkr_mode1; - size = ARRAY_SIZE(msm_sdw_spkr_mode1); - break; - default: - regs = msm_sdw_spkr_default; - size = ARRAY_SIZE(msm_sdw_spkr_default); - break; - } - - priv->spkr_mode = mode; - for (i = 0; i < size; i++) - snd_soc_update_bits(codec, regs[i].reg, - regs[i].mask, regs[i].val); - return 0; -} -EXPORT_SYMBOL(msm_sdw_set_spkr_mode); - -static int msm_enable_sdw_npl_clk(struct msm_sdw_priv *msm_sdw, int enable) -{ - int ret = 0; - - dev_dbg(msm_sdw->dev, "%s: enable %d\n", __func__, enable); - - mutex_lock(&msm_sdw->sdw_npl_clk_mutex); - if (enable) { - if (msm_sdw->sdw_npl_clk_enabled == false) { - msm_sdw->sdw_npl_clk.enable = 1; - ret = afe_set_lpass_clock_v2( - AFE_PORT_ID_INT4_MI2S_RX, - &msm_sdw->sdw_npl_clk); - if (ret < 0) { - dev_err(msm_sdw->dev, - "%s: failed to enable SDW NPL CLK\n", - __func__); - mutex_unlock(&msm_sdw->sdw_npl_clk_mutex); - return ret; - } - dev_dbg(msm_sdw->dev, "enabled sdw npl clk\n"); - msm_sdw->sdw_npl_clk_enabled = true; - } - } else { - if (msm_sdw->sdw_npl_clk_enabled == true) { - msm_sdw->sdw_npl_clk.enable = 0; - ret = afe_set_lpass_clock_v2( - AFE_PORT_ID_INT4_MI2S_RX, - &msm_sdw->sdw_npl_clk); - if (ret < 0) - dev_err(msm_sdw->dev, - "%s: failed to disable SDW NPL CLK\n", - __func__); - msm_sdw->sdw_npl_clk_enabled = false; - } - } - mutex_unlock(&msm_sdw->sdw_npl_clk_mutex); - return ret; -} - -static int msm_int_enable_sdw_cdc_clk(struct msm_sdw_priv *msm_sdw, - int enable, bool dapm) -{ - int ret = 0; - - mutex_lock(&msm_sdw->cdc_int_mclk1_mutex); - dev_dbg(msm_sdw->dev, "%s: enable %d mclk1 ref counter %d\n", - __func__, enable, msm_sdw->int_mclk1_rsc_ref); - if (enable) { - if (msm_sdw->int_mclk1_rsc_ref == 0) { - cancel_delayed_work_sync( - &msm_sdw->disable_int_mclk1_work); - if (msm_sdw->int_mclk1_enabled == false) { - msm_sdw->sdw_cdc_core_clk.enable = 1; - ret = afe_set_lpass_clock_v2( - AFE_PORT_ID_INT4_MI2S_RX, - &msm_sdw->sdw_cdc_core_clk); - if (ret < 0) { - dev_err(msm_sdw->dev, - "%s: failed to enable SDW MCLK\n", - __func__); - goto rtn; - } - dev_dbg(msm_sdw->dev, - "enabled sdw codec core mclk\n"); - msm_sdw->int_mclk1_enabled = true; - } - } - msm_sdw->int_mclk1_rsc_ref++; - } else { - cancel_delayed_work_sync(&msm_sdw->disable_int_mclk1_work); - if (msm_sdw->int_mclk1_rsc_ref > 0) { - msm_sdw->int_mclk1_rsc_ref--; - dev_dbg(msm_sdw->dev, - "%s: decrementing mclk_res_ref %d\n", - __func__, msm_sdw->int_mclk1_rsc_ref); - } - if (msm_sdw->int_mclk1_enabled == true && - msm_sdw->int_mclk1_rsc_ref == 0) { - msm_sdw->sdw_cdc_core_clk.enable = 0; - ret = afe_set_lpass_clock_v2( - AFE_PORT_ID_INT4_MI2S_RX, - &msm_sdw->sdw_cdc_core_clk); - if (ret < 0) - dev_err(msm_sdw->dev, - "%s: failed to disable SDW MCLK\n", - __func__); - msm_sdw->int_mclk1_enabled = false; - } - } -rtn: - mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); - return ret; -} -EXPORT_SYMBOL(msm_int_enable_sdw_cdc_clk); - -static void msm_disable_int_mclk1(struct work_struct *work) -{ - struct msm_sdw_priv *msm_sdw = NULL; - struct delayed_work *dwork; - int ret = 0; - - dwork = to_delayed_work(work); - msm_sdw = container_of(dwork, struct msm_sdw_priv, - disable_int_mclk1_work); - mutex_lock(&msm_sdw->cdc_int_mclk1_mutex); - dev_dbg(msm_sdw->dev, "%s: mclk1_enabled %d mclk1_rsc_ref %d\n", - __func__, msm_sdw->int_mclk1_enabled, - msm_sdw->int_mclk1_rsc_ref); - if (msm_sdw->int_mclk1_enabled == true - && msm_sdw->int_mclk1_rsc_ref == 0) { - dev_dbg(msm_sdw->dev, "Disable the mclk1\n"); - msm_sdw->sdw_cdc_core_clk.enable = 0; - ret = afe_set_lpass_clock_v2( - AFE_PORT_ID_INT4_MI2S_RX, - &msm_sdw->sdw_cdc_core_clk); - if (ret < 0) - dev_err(msm_sdw->dev, - "%s failed to disable the MCLK1\n", - __func__); - msm_sdw->int_mclk1_enabled = false; - } - mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); -} - -static int msm_int_mclk1_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); - int ret = 0; - - dev_dbg(msm_sdw->dev, "%s: event = %d\n", __func__, event); - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - /* enable the codec mclk config */ - msm_int_enable_sdw_cdc_clk(msm_sdw, 1, true); - msm_sdw_mclk_enable(msm_sdw, 1, true); - break; - case SND_SOC_DAPM_POST_PMD: - /* disable the codec mclk config */ - msm_sdw_mclk_enable(msm_sdw, 0, true); - msm_int_enable_sdw_cdc_clk(msm_sdw, 0, true); - break; - default: - dev_err(msm_sdw->dev, - "%s: invalid DAPM event %d\n", __func__, event); - ret = -EINVAL; - } - return ret; -} - -static int msm_sdw_ahb_write_device(struct msm_sdw_priv *msm_sdw, - u16 reg, u8 *value) -{ - u32 temp = (u32)(*value) & 0x000000FF; - - if (!msm_sdw->dev_up) { - dev_err_ratelimited(msm_sdw->dev, "%s: q6 not ready\n", - __func__); - return 0; - } - - iowrite32(temp, msm_sdw->sdw_base + reg); - return 0; -} - -static int msm_sdw_ahb_read_device(struct msm_sdw_priv *msm_sdw, - u16 reg, u8 *value) -{ - u32 temp; - - if (!msm_sdw->dev_up) { - dev_err_ratelimited(msm_sdw->dev, "%s: q6 not ready\n", - __func__); - return 0; - } - - temp = ioread32(msm_sdw->sdw_base + reg); - *value = (u8)temp; - return 0; -} - -static int __msm_sdw_reg_read(struct msm_sdw_priv *msm_sdw, unsigned short reg, - int bytes, void *dest) -{ - int ret = -EINVAL, i; - u8 temp = 0; - - dev_dbg(msm_sdw->dev, "%s reg = %x\n", __func__, reg); - mutex_lock(&msm_sdw->cdc_int_mclk1_mutex); - if (msm_sdw->int_mclk1_enabled == false) { - msm_sdw->sdw_cdc_core_clk.enable = 1; - ret = afe_set_lpass_clock_v2( - AFE_PORT_ID_INT4_MI2S_RX, - &msm_sdw->sdw_cdc_core_clk); - if (ret < 0) { - dev_err(msm_sdw->dev, - "%s:failed to enable the INT_MCLK1\n", - __func__); - goto unlock_exit; - } - dev_dbg(msm_sdw->dev, "%s:enabled sdw codec core clk\n", - __func__); - for (i = 0; i < bytes; i++) { - ret = msm_sdw_ahb_read_device( - msm_sdw, reg + (4 * i), &temp); - ((u8 *)dest)[i] = temp; - } - msm_sdw->int_mclk1_enabled = true; - schedule_delayed_work(&msm_sdw->disable_int_mclk1_work, 50); - goto unlock_exit; - } - for (i = 0; i < bytes; i++) { - ret = msm_sdw_ahb_read_device( - msm_sdw, reg + (4 * i), &temp); - ((u8 *)dest)[i] = temp; - } -unlock_exit: - mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); - if (ret < 0) { - dev_err_ratelimited(msm_sdw->dev, - "%s: codec read failed for reg 0x%x\n", - __func__, reg); - return ret; - } - dev_dbg(msm_sdw->dev, "Read 0x%02x from 0x%x\n", temp, reg); - - return 0; -} - -static int __msm_sdw_reg_write(struct msm_sdw_priv *msm_sdw, unsigned short reg, - int bytes, void *src) -{ - int ret = -EINVAL, i; - - mutex_lock(&msm_sdw->cdc_int_mclk1_mutex); - if (msm_sdw->int_mclk1_enabled == false) { - msm_sdw->sdw_cdc_core_clk.enable = 1; - ret = afe_set_lpass_clock_v2(AFE_PORT_ID_INT4_MI2S_RX, - &msm_sdw->sdw_cdc_core_clk); - if (ret < 0) { - dev_err(msm_sdw->dev, - "%s: failed to enable the INT_MCLK1\n", - __func__); - ret = 0; - goto unlock_exit; - } - dev_dbg(msm_sdw->dev, "%s: enabled INT_MCLK1\n", __func__); - for (i = 0; i < bytes; i++) - ret = msm_sdw_ahb_write_device(msm_sdw, reg + (4 * i), - &((u8 *)src)[i]); - msm_sdw->int_mclk1_enabled = true; - schedule_delayed_work(&msm_sdw->disable_int_mclk1_work, 50); - goto unlock_exit; - } - for (i = 0; i < bytes; i++) - ret = msm_sdw_ahb_write_device(msm_sdw, reg + (4 * i), - &((u8 *)src)[i]); -unlock_exit: - mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); - dev_dbg(msm_sdw->dev, "Write 0x%x val 0x%02x\n", - reg, (u32)(*(u32 *)src)); - - return ret; -} - -static int msm_sdw_codec_enable_vi_feedback(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = NULL; - struct msm_sdw_priv *msm_sdw_p = NULL; - int ret = 0; - - if (!w) { - pr_err("%s invalid params\n", __func__); - return -EINVAL; - } - codec = snd_soc_dapm_to_codec(w->dapm); - msm_sdw_p = snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: num_dai %d stream name %s\n", - __func__, codec->component.num_dai, w->sname); - - dev_dbg(codec->dev, "%s(): w->name %s event %d w->shift %d\n", - __func__, w->name, event, w->shift); - if (w->shift != AIF1_SDW_VIFEED) { - dev_err(codec->dev, - "%s:Error in enabling the vi feedback path\n", - __func__); - ret = -EINVAL; - goto out_vi; - } - switch (event) { - case SND_SOC_DAPM_POST_PMU: - if (test_bit(VI_SENSE_1, &msm_sdw_p->status_mask)) { - dev_dbg(codec->dev, "%s: spkr1 enabled\n", __func__); - /* Enable V&I sensing */ - snd_soc_update_bits(codec, - MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, - MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x20, - 0x20); - snd_soc_update_bits(codec, - MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x0F, 0x04); - snd_soc_update_bits(codec, - MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x0F, 0x04); - snd_soc_update_bits(codec, - MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, - MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x10, - 0x10); - snd_soc_update_bits(codec, - MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x00); - snd_soc_update_bits(codec, - MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x20, - 0x00); - } - if (test_bit(VI_SENSE_2, &msm_sdw_p->status_mask)) { - dev_dbg(codec->dev, "%s: spkr2 enabled\n", __func__); - /* Enable V&I sensing */ - snd_soc_update_bits(codec, - MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x20, - 0x20); - snd_soc_update_bits(codec, - MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x20, - 0x20); - snd_soc_update_bits(codec, - MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x0F, - 0x04); - snd_soc_update_bits(codec, - MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x0F, - 0x04); - snd_soc_update_bits(codec, - MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x10, - 0x10); - snd_soc_update_bits(codec, - MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x10, - 0x10); - snd_soc_update_bits(codec, - MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x20, - 0x00); - snd_soc_update_bits(codec, - MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x20, - 0x00); - } - break; - case SND_SOC_DAPM_POST_PMD: - if (test_bit(VI_SENSE_1, &msm_sdw_p->status_mask)) { - /* Disable V&I sensing */ - dev_dbg(codec->dev, "%s: spkr1 disabled\n", __func__); - snd_soc_update_bits(codec, - MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, - MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x20, - 0x20); - snd_soc_update_bits(codec, - MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x00); - snd_soc_update_bits(codec, - MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x10, - 0x00); - } - if (test_bit(VI_SENSE_2, &msm_sdw_p->status_mask)) { - /* Disable V&I sensing */ - dev_dbg(codec->dev, "%s: spkr2 disabled\n", __func__); - snd_soc_update_bits(codec, - MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x20, - 0x20); - snd_soc_update_bits(codec, - MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x20, - 0x20); - snd_soc_update_bits(codec, - MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x10, - 0x00); - snd_soc_update_bits(codec, - MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x10, - 0x00); - } - break; - } -out_vi: - return ret; -} - -static int msm_sdwm_handle_irq(void *handle, - irqreturn_t (*swrm_irq_handler)(int irq, - void *data), - void *swrm_handle, - int action) -{ - struct msm_sdw_priv *msm_sdw; - int ret = 0; - - if (!handle) { - pr_err("%s: null handle received\n", __func__); - return -EINVAL; - } - msm_sdw = (struct msm_sdw_priv *) handle; - - if (skip_irq) - return ret; - - if (action) { - ret = request_threaded_irq(msm_sdw->sdw_irq, NULL, - swrm_irq_handler, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, - "swr_master_irq", swrm_handle); - if (ret) - dev_err(msm_sdw->dev, "%s: Failed to request irq %d\n", - __func__, ret); - } else - free_irq(msm_sdw->sdw_irq, swrm_handle); - - return ret; -} - -static void msm_sdw_codec_hd2_control(struct snd_soc_codec *codec, - u16 reg, int event) -{ - u16 hd2_scale_reg; - u16 hd2_enable_reg = 0; - - if (reg == MSM_SDW_RX7_RX_PATH_CTL) { - hd2_scale_reg = MSM_SDW_RX7_RX_PATH_SEC3; - hd2_enable_reg = MSM_SDW_RX7_RX_PATH_CFG0; - } - if (reg == MSM_SDW_RX8_RX_PATH_CTL) { - hd2_scale_reg = MSM_SDW_RX8_RX_PATH_SEC3; - hd2_enable_reg = MSM_SDW_RX8_RX_PATH_CFG0; - } - - if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { - snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x10); - snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x01); - snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x04); - } - - if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x00); - snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x00); - snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x00); - } -} - -static int msm_sdw_enable_swr(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct msm_sdw_priv *msm_sdw; - int i, ch_cnt; - - msm_sdw = snd_soc_codec_get_drvdata(codec); - - if (!msm_sdw->nr) - return 0; - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (!(strnstr(w->name, "RX4", sizeof("RX4 MIX"))) && - !msm_sdw->rx_4_count) - msm_sdw->rx_4_count++; - if (!(strnstr(w->name, "RX5", sizeof("RX5 MIX"))) && - !msm_sdw->rx_5_count) - msm_sdw->rx_5_count++; - ch_cnt = msm_sdw->rx_4_count + msm_sdw->rx_5_count; - - for (i = 0; i < msm_sdw->nr; i++) { - swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, - SWR_DEVICE_UP, NULL); - swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, - SWR_SET_NUM_RX_CH, &ch_cnt); - } - break; - case SND_SOC_DAPM_POST_PMD: - if (!(strnstr(w->name, "RX4", sizeof("RX4 MIX"))) && - msm_sdw->rx_4_count) - msm_sdw->rx_4_count--; - if (!(strnstr(w->name, "RX5", sizeof("RX5 MIX"))) && - msm_sdw->rx_5_count) - msm_sdw->rx_5_count--; - ch_cnt = msm_sdw->rx_4_count + msm_sdw->rx_5_count; - - for (i = 0; i < msm_sdw->nr; i++) - swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, - SWR_SET_NUM_RX_CH, &ch_cnt); - break; - } - dev_dbg(msm_sdw->dev, "%s: current swr ch cnt: %d\n", - __func__, msm_sdw->rx_4_count + msm_sdw->rx_5_count); - - return 0; -} - -static int msm_sdw_codec_enable_interpolator(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); - u16 gain_reg; - u16 reg; - int val; - int offset_val = 0; - - dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); - - if (!(strcmp(w->name, "RX INT4 INTERP"))) { - reg = MSM_SDW_RX7_RX_PATH_CTL; - gain_reg = MSM_SDW_RX7_RX_VOL_CTL; - } else if (!(strcmp(w->name, "RX INT5 INTERP"))) { - reg = MSM_SDW_RX8_RX_PATH_CTL; - gain_reg = MSM_SDW_RX8_RX_VOL_CTL; - } else { - dev_err(codec->dev, "%s: Interpolator reg not found\n", - __func__); - return -EINVAL; - } - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, reg, 0x10, 0x10); - msm_sdw_codec_hd2_control(codec, reg, event); - snd_soc_update_bits(codec, reg, 1 << 0x5, 1 << 0x5); - break; - case SND_SOC_DAPM_POST_PMU: - msm_sdw_config_compander(codec, w->shift, event); - /* apply gain after int clk is enabled */ - if ((msm_sdw->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && - (msm_sdw->comp_enabled[COMP1] || - msm_sdw->comp_enabled[COMP2]) && - (gain_reg == MSM_SDW_RX7_RX_VOL_CTL || - gain_reg == MSM_SDW_RX8_RX_VOL_CTL)) { - snd_soc_update_bits(codec, MSM_SDW_RX7_RX_PATH_SEC1, - 0x01, 0x01); - snd_soc_update_bits(codec, - MSM_SDW_RX7_RX_PATH_MIX_SEC0, - 0x01, 0x01); - snd_soc_update_bits(codec, MSM_SDW_RX8_RX_PATH_SEC1, - 0x01, 0x01); - snd_soc_update_bits(codec, - MSM_SDW_RX8_RX_PATH_MIX_SEC0, - 0x01, 0x01); - offset_val = -2; - } - val = snd_soc_read(codec, gain_reg); - val += offset_val; - snd_soc_write(codec, gain_reg, val); - msm_sdw_config_ear_spkr_gain(codec, event, gain_reg); - snd_soc_update_bits(codec, reg, 0x10, 0x00); - break; - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, reg, 1 << 0x5, 0 << 0x5); - snd_soc_update_bits(codec, reg, 0x40, 0x40); - snd_soc_update_bits(codec, reg, 0x40, 0x00); - msm_sdw_codec_hd2_control(codec, reg, event); - msm_sdw_config_compander(codec, w->shift, event); - if ((msm_sdw->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && - (msm_sdw->comp_enabled[COMP1] || - msm_sdw->comp_enabled[COMP2]) && - (gain_reg == MSM_SDW_RX7_RX_VOL_CTL || - gain_reg == MSM_SDW_RX8_RX_VOL_CTL)) { - snd_soc_update_bits(codec, MSM_SDW_RX7_RX_PATH_SEC1, - 0x01, 0x00); - snd_soc_update_bits(codec, - MSM_SDW_RX7_RX_PATH_MIX_SEC0, - 0x01, 0x00); - snd_soc_update_bits(codec, MSM_SDW_RX8_RX_PATH_SEC1, - 0x01, 0x00); - snd_soc_update_bits(codec, - MSM_SDW_RX8_RX_PATH_MIX_SEC0, - 0x01, 0x00); - offset_val = 2; - val = snd_soc_read(codec, gain_reg); - val += offset_val; - snd_soc_write(codec, gain_reg, val); - } - msm_sdw_config_ear_spkr_gain(codec, event, gain_reg); - break; - }; - - return 0; -} - -static int msm_sdw_config_ear_spkr_gain(struct snd_soc_codec *codec, - int event, int gain_reg) -{ - int comp_gain_offset, val; - struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); - - switch (msm_sdw->spkr_mode) { - /* Compander gain in SPKR_MODE1 case is 12 dB */ - case SPKR_MODE_1: - comp_gain_offset = -12; - break; - /* Default case compander gain is 15 dB */ - default: - comp_gain_offset = -15; - break; - } - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - /* Apply ear spkr gain only if compander is enabled */ - if (msm_sdw->comp_enabled[COMP1] && - (gain_reg == MSM_SDW_RX7_RX_VOL_CTL) && - (msm_sdw->ear_spkr_gain != 0)) { - /* For example, val is -8(-12+5-1) for 4dB of gain */ - val = comp_gain_offset + msm_sdw->ear_spkr_gain - 1; - snd_soc_write(codec, gain_reg, val); - - dev_dbg(codec->dev, "%s: RX4 Volume %d dB\n", - __func__, val); - } - break; - case SND_SOC_DAPM_POST_PMD: - /* - * Reset RX4 volume to 0 dB if compander is enabled and - * ear_spkr_gain is non-zero. - */ - if (msm_sdw->comp_enabled[COMP1] && - (gain_reg == MSM_SDW_RX7_RX_VOL_CTL) && - (msm_sdw->ear_spkr_gain != 0)) { - snd_soc_write(codec, gain_reg, 0x0); - - dev_dbg(codec->dev, "%s: Reset RX4 Volume to 0 dB\n", - __func__); - } - break; - } - - return 0; -} - -static int msm_sdw_codec_spk_boost_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - u16 boost_path_ctl, boost_path_cfg1; - u16 reg; - - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); - - if (!strcmp(w->name, "RX INT4 CHAIN")) { - boost_path_ctl = MSM_SDW_BOOST0_BOOST_PATH_CTL; - boost_path_cfg1 = MSM_SDW_RX7_RX_PATH_CFG1; - reg = MSM_SDW_RX7_RX_PATH_CTL; - } else if (!strcmp(w->name, "RX INT5 CHAIN")) { - boost_path_ctl = MSM_SDW_BOOST1_BOOST_PATH_CTL; - boost_path_cfg1 = MSM_SDW_RX8_RX_PATH_CFG1; - reg = MSM_SDW_RX8_RX_PATH_CTL; - } else { - dev_err(codec->dev, "%s: boost reg not found\n", - __func__); - return -EINVAL; - } - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x10); - snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x01); - snd_soc_update_bits(codec, reg, 0x10, 0x00); - break; - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x00); - snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x00); - break; - }; - - return 0; -} - -static int msm_sdw_config_compander(struct snd_soc_codec *codec, int comp, - int event) -{ - struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); - u16 comp_ctl0_reg, rx_path_cfg0_reg; - - if (comp < COMP1 || comp >= COMP_MAX) - return 0; - - dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n", - __func__, event, comp + 1, msm_sdw->comp_enabled[comp]); - - if (!msm_sdw->comp_enabled[comp]) - return 0; - - comp_ctl0_reg = MSM_SDW_COMPANDER7_CTL0 + (comp * 0x20); - rx_path_cfg0_reg = MSM_SDW_RX7_RX_PATH_CFG0 + (comp * 0x1E0); - - if (SND_SOC_DAPM_EVENT_ON(event)) { - /* Enable Compander Clock */ - snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02); - } - - if (SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); - snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); - } - - return 0; -} - -static int msm_sdw_get_compander(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - int comp = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = msm_sdw->comp_enabled[comp]; - return 0; -} - -static int msm_sdw_set_compander(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); - int comp = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - int value = ucontrol->value.integer.value[0]; - - dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n", - __func__, comp + 1, msm_sdw->comp_enabled[comp], value); - msm_sdw->comp_enabled[comp] = value; - - return 0; -} - -static int msm_sdw_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = msm_sdw->ear_spkr_gain; - - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - return 0; -} - -static int msm_sdw_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct msm_sdw_priv *msm_sdw = snd_soc_codec_get_drvdata(codec); - - msm_sdw->ear_spkr_gain = ucontrol->value.integer.value[0]; - - dev_dbg(codec->dev, "%s: gain = %d\n", __func__, - msm_sdw->ear_spkr_gain); - - return 0; -} - -static int msm_sdw_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - u8 bst_state_max = 0; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - - bst_state_max = snd_soc_read(codec, MSM_SDW_BOOST0_BOOST_CTL); - bst_state_max = (bst_state_max & 0x0c) >> 2; - ucontrol->value.integer.value[0] = bst_state_max; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - return 0; -} - -static int msm_sdw_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - u8 bst_state_max; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - bst_state_max = ucontrol->value.integer.value[0] << 2; - snd_soc_update_bits(codec, MSM_SDW_BOOST0_BOOST_CTL, - 0x0c, bst_state_max); - - return 0; -} - -static int msm_sdw_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - u8 bst_state_max = 0; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - - bst_state_max = snd_soc_read(codec, MSM_SDW_BOOST1_BOOST_CTL); - bst_state_max = (bst_state_max & 0x0c) >> 2; - ucontrol->value.integer.value[0] = bst_state_max; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - return 0; -} - -static int msm_sdw_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - u8 bst_state_max; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - bst_state_max = ucontrol->value.integer.value[0] << 2; - snd_soc_update_bits(codec, MSM_SDW_BOOST1_BOOST_CTL, - 0x0c, bst_state_max); - - return 0; -} - -static int msm_sdw_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct msm_sdw_priv *msm_sdw_p = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = msm_sdw_p->vi_feed_value; - - return 0; -} - -static int msm_sdw_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct msm_sdw_priv *msm_sdw_p = snd_soc_codec_get_drvdata(codec); - struct soc_multi_mixer_control *mixer = - ((struct soc_multi_mixer_control *)kcontrol->private_value); - u32 dai_id = widget->shift; - u32 port_id = mixer->shift; - u32 enable = ucontrol->value.integer.value[0]; - - dev_dbg(codec->dev, "%s: enable: %d, port_id:%d, dai_id: %d\n", - __func__, enable, port_id, dai_id); - - msm_sdw_p->vi_feed_value = ucontrol->value.integer.value[0]; - - mutex_lock(&msm_sdw_p->codec_mutex); - if (enable) { - if (port_id == MSM_SDW_TX0 && !test_bit(VI_SENSE_1, - &msm_sdw_p->status_mask)) - set_bit(VI_SENSE_1, &msm_sdw_p->status_mask); - if (port_id == MSM_SDW_TX1 && !test_bit(VI_SENSE_2, - &msm_sdw_p->status_mask)) - set_bit(VI_SENSE_2, &msm_sdw_p->status_mask); - } else { - if (port_id == MSM_SDW_TX0 && test_bit(VI_SENSE_1, - &msm_sdw_p->status_mask)) - clear_bit(VI_SENSE_1, &msm_sdw_p->status_mask); - if (port_id == MSM_SDW_TX1 && test_bit(VI_SENSE_2, - &msm_sdw_p->status_mask)) - clear_bit(VI_SENSE_2, &msm_sdw_p->status_mask); - } - mutex_unlock(&msm_sdw_p->codec_mutex); - snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL); - - return 0; -} - -static int msm_sdw_mclk_enable(struct msm_sdw_priv *msm_sdw, - int mclk_enable, bool dapm) -{ - dev_dbg(msm_sdw->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", - __func__, mclk_enable, dapm, msm_sdw->sdw_mclk_users); - if (mclk_enable) { - msm_sdw->sdw_mclk_users++; - if (msm_sdw->sdw_mclk_users == 1) { - regmap_update_bits(msm_sdw->regmap, - MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL, - 0x01, 0x01); - regmap_update_bits(msm_sdw->regmap, - MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL, - 0x01, 0x01); - /* 9.6MHz MCLK, set value 0x00 if other frequency */ - regmap_update_bits(msm_sdw->regmap, - MSM_SDW_TOP_FREQ_MCLK, 0x01, 0x01); - } - } else { - msm_sdw->sdw_mclk_users--; - if (msm_sdw->sdw_mclk_users == 0) { - regmap_update_bits(msm_sdw->regmap, - MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL, - 0x01, 0x00); - regmap_update_bits(msm_sdw->regmap, - MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL, - 0x01, 0x00); - } - } - return 0; -} -EXPORT_SYMBOL(msm_sdw_mclk_enable); - -static int msm_sdw_swrm_read(void *handle, int reg) -{ - struct msm_sdw_priv *msm_sdw; - unsigned short sdw_rd_addr_base; - unsigned short sdw_rd_data_base; - int val, ret; - - if (!handle) { - pr_err("%s: NULL handle\n", __func__); - return -EINVAL; - } - msm_sdw = (struct msm_sdw_priv *)handle; - - dev_dbg(msm_sdw->dev, "%s: Reading soundwire register, 0x%x\n", - __func__, reg); - sdw_rd_addr_base = MSM_SDW_AHB_BRIDGE_RD_ADDR_0; - sdw_rd_data_base = MSM_SDW_AHB_BRIDGE_RD_DATA_0; - /* - * Add sleep as SWR slave access read takes time. - * Allow for RD_DONE to complete for previous register if any. - */ - usleep_range(100, 105); - - /* read_lock */ - mutex_lock(&msm_sdw->sdw_read_lock); - ret = regmap_bulk_write(msm_sdw->regmap, sdw_rd_addr_base, - (u8 *)®, 4); - if (ret < 0) { - dev_err(msm_sdw->dev, "%s: RD Addr Failure\n", __func__); - goto err; - } - /* Add sleep for SWR register read value to get updated. */ - usleep_range(100, 105); - /* Check for RD value */ - ret = regmap_bulk_read(msm_sdw->regmap, sdw_rd_data_base, - (u8 *)&val, 4); - if (ret < 0) { - dev_err(msm_sdw->dev, "%s: RD Data Failure\n", __func__); - goto err; - } - ret = val; -err: - /* read_unlock */ - mutex_unlock(&msm_sdw->sdw_read_lock); - return ret; -} - -static int msm_sdw_bulk_write(struct msm_sdw_priv *msm_sdw, - struct msm_sdw_reg_val *bulk_reg, - size_t len) -{ - int i, ret = 0; - unsigned short sdw_wr_addr_base; - unsigned short sdw_wr_data_base; - - sdw_wr_addr_base = MSM_SDW_AHB_BRIDGE_WR_ADDR_0; - sdw_wr_data_base = MSM_SDW_AHB_BRIDGE_WR_DATA_0; - - for (i = 0; i < len; i += 2) { - /* - * Add sleep as SWR slave write takes time. - * Allow for any previous pending write to complete. - */ - usleep_range(100, 105); - /* First Write the Data to register */ - ret = regmap_bulk_write(msm_sdw->regmap, - sdw_wr_data_base, bulk_reg[i].buf, 4); - if (ret < 0) { - dev_err(msm_sdw->dev, "%s: WR Data Failure\n", - __func__); - break; - } - /* Next Write Address */ - ret = regmap_bulk_write(msm_sdw->regmap, - sdw_wr_addr_base, bulk_reg[i+1].buf, 4); - if (ret < 0) { - dev_err(msm_sdw->dev, - "%s: WR Addr Failure: 0x%x\n", - __func__, (u32)(bulk_reg[i+1].buf[0])); - break; - } - } - return ret; -} - -static int msm_sdw_swrm_bulk_write(void *handle, u32 *reg, u32 *val, size_t len) -{ - struct msm_sdw_priv *msm_sdw; - struct msm_sdw_reg_val *bulk_reg; - unsigned short sdw_wr_addr_base; - unsigned short sdw_wr_data_base; - int i, j, ret; - - if (!handle) { - pr_err("%s: NULL handle\n", __func__); - return -EINVAL; - } - - msm_sdw = (struct msm_sdw_priv *)handle; - if (len <= 0) { - dev_err(msm_sdw->dev, - "%s: Invalid size: %zu\n", __func__, len); - return -EINVAL; - } - - sdw_wr_addr_base = MSM_SDW_AHB_BRIDGE_WR_ADDR_0; - sdw_wr_data_base = MSM_SDW_AHB_BRIDGE_WR_DATA_0; - - bulk_reg = kzalloc((2 * len * sizeof(struct msm_sdw_reg_val)), - GFP_KERNEL); - if (!bulk_reg) - return -ENOMEM; - - for (i = 0, j = 0; i < (len * 2); i += 2, j++) { - bulk_reg[i].reg = sdw_wr_data_base; - bulk_reg[i].buf = (u8 *)(&val[j]); - bulk_reg[i].bytes = 4; - bulk_reg[i+1].reg = sdw_wr_addr_base; - bulk_reg[i+1].buf = (u8 *)(®[j]); - bulk_reg[i+1].bytes = 4; - } - mutex_lock(&msm_sdw->sdw_write_lock); - - ret = msm_sdw_bulk_write(msm_sdw, bulk_reg, (len * 2)); - if (ret) - dev_err(msm_sdw->dev, "%s: swrm bulk write failed, ret: %d\n", - __func__, ret); - - mutex_unlock(&msm_sdw->sdw_write_lock); - kfree(bulk_reg); - - return ret; -} - -static int msm_sdw_swrm_write(void *handle, int reg, int val) -{ - struct msm_sdw_priv *msm_sdw; - unsigned short sdw_wr_addr_base; - unsigned short sdw_wr_data_base; - struct msm_sdw_reg_val bulk_reg[2]; - int ret; - - if (!handle) { - pr_err("%s: NULL handle\n", __func__); - return -EINVAL; - } - msm_sdw = (struct msm_sdw_priv *)handle; - - sdw_wr_addr_base = MSM_SDW_AHB_BRIDGE_WR_ADDR_0; - sdw_wr_data_base = MSM_SDW_AHB_BRIDGE_WR_DATA_0; - - /* First Write the Data to register */ - bulk_reg[0].reg = sdw_wr_data_base; - bulk_reg[0].buf = (u8 *)(&val); - bulk_reg[0].bytes = 4; - bulk_reg[1].reg = sdw_wr_addr_base; - bulk_reg[1].buf = (u8 *)(®); - bulk_reg[1].bytes = 4; - - mutex_lock(&msm_sdw->sdw_write_lock); - - ret = msm_sdw_bulk_write(msm_sdw, bulk_reg, 2); - if (ret < 0) - dev_err(msm_sdw->dev, "%s: WR Data Failure\n", __func__); - - mutex_unlock(&msm_sdw->sdw_write_lock); - return ret; -} - -static int msm_sdw_swrm_clock(void *handle, bool enable) -{ - struct msm_sdw_priv *msm_sdw; - - if (!handle) { - pr_err("%s: NULL handle\n", __func__); - return -EINVAL; - } - msm_sdw = (struct msm_sdw_priv *)handle; - - mutex_lock(&msm_sdw->sdw_clk_lock); - - dev_dbg(msm_sdw->dev, "%s: swrm clock %s\n", - __func__, (enable ? "enable" : "disable")); - if (enable) { - msm_sdw->sdw_clk_users++; - if (msm_sdw->sdw_clk_users == 1) { - msm_int_enable_sdw_cdc_clk(msm_sdw, 1, true); - msm_sdw_mclk_enable(msm_sdw, 1, true); - regmap_update_bits(msm_sdw->regmap, - MSM_SDW_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x01); - msm_enable_sdw_npl_clk(msm_sdw, true); - msm_cdc_pinctrl_select_active_state( - msm_sdw->sdw_gpio_p); - } - } else { - msm_sdw->sdw_clk_users--; - if (msm_sdw->sdw_clk_users == 0) { - regmap_update_bits(msm_sdw->regmap, - MSM_SDW_CLK_RST_CTRL_SWR_CONTROL, - 0x01, 0x00); - msm_sdw_mclk_enable(msm_sdw, 0, true); - msm_int_enable_sdw_cdc_clk(msm_sdw, 0, true); - msm_enable_sdw_npl_clk(msm_sdw, false); - msm_cdc_pinctrl_select_sleep_state(msm_sdw->sdw_gpio_p); - } - } - dev_dbg(msm_sdw->dev, "%s: swrm clock users %d\n", - __func__, msm_sdw->sdw_clk_users); - mutex_unlock(&msm_sdw->sdw_clk_lock); - return 0; -} - -static int msm_sdw_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - dev_dbg(dai->codec->dev, "%s(): substream = %s stream = %d\n", - __func__, - substream->name, substream->stream); - return 0; -} - -static int msm_sdw_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - u8 clk_fs_rate, fs_rate; - - dev_dbg(dai->codec->dev, - "%s: dai_name = %s DAI-ID %x rate %d num_ch %d format %d\n", - __func__, dai->name, dai->id, params_rate(params), - params_channels(params), params_format(params)); - - switch (params_rate(params)) { - case 8000: - clk_fs_rate = 0x00; - fs_rate = 0x00; - break; - case 16000: - clk_fs_rate = 0x01; - fs_rate = 0x01; - break; - case 32000: - clk_fs_rate = 0x02; - fs_rate = 0x03; - break; - case 48000: - clk_fs_rate = 0x03; - fs_rate = 0x04; - break; - case 96000: - clk_fs_rate = 0x04; - fs_rate = 0x05; - break; - case 192000: - clk_fs_rate = 0x05; - fs_rate = 0x06; - break; - default: - dev_err(dai->codec->dev, - "%s: Invalid sampling rate %d\n", __func__, - params_rate(params)); - return -EINVAL; - } - - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - snd_soc_update_bits(dai->codec, - MSM_SDW_TOP_TX_I2S_CTL, 0x1C, - (clk_fs_rate << 2)); - } else { - snd_soc_update_bits(dai->codec, - MSM_SDW_TOP_RX_I2S_CTL, 0x1C, - (clk_fs_rate << 2)); - snd_soc_update_bits(dai->codec, - MSM_SDW_RX7_RX_PATH_CTL, 0x0F, - fs_rate); - snd_soc_update_bits(dai->codec, - MSM_SDW_RX8_RX_PATH_CTL, 0x0F, - fs_rate); - } - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - snd_soc_update_bits(dai->codec, - MSM_SDW_TOP_TX_I2S_CTL, 0x20, 0x20); - else - snd_soc_update_bits(dai->codec, - MSM_SDW_TOP_RX_I2S_CTL, 0x20, 0x20); - break; - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S24_3LE: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - snd_soc_update_bits(dai->codec, - MSM_SDW_TOP_TX_I2S_CTL, 0x20, 0x00); - else - snd_soc_update_bits(dai->codec, - MSM_SDW_TOP_RX_I2S_CTL, 0x20, 0x00); - break; - default: - dev_err(dai->codec->dev, "%s: wrong format selected\n", - __func__); - return -EINVAL; - } - - return 0; -} - -static void msm_sdw_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - dev_dbg(dai->codec->dev, - "%s(): substream = %s stream = %d\n", __func__, - substream->name, substream->stream); -} - -static ssize_t msm_sdw_codec_version_read(struct snd_info_entry *entry, - void *file_private_data, - struct file *file, - char __user *buf, size_t count, - loff_t pos) -{ - struct msm_sdw_priv *msm_sdw; - char buffer[MSM_SDW_VERSION_ENTRY_SIZE]; - int len = 0; - - msm_sdw = (struct msm_sdw_priv *) entry->private_data; - if (!msm_sdw) { - pr_err("%s: msm_sdw priv is null\n", __func__); - return -EINVAL; - } - - switch (msm_sdw->version) { - case MSM_SDW_VERSION_1_0: - len = snprintf(buffer, sizeof(buffer), "SDW-CDC_1_0\n"); - break; - default: - len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); - } - - return simple_read_from_buffer(buf, count, &pos, buffer, len); -} - -static struct snd_info_entry_ops msm_sdw_codec_info_ops = { - .read = msm_sdw_codec_version_read, -}; - -/* - * msm_sdw_codec_info_create_codec_entry - creates msm_sdw module - * @codec_root: The parent directory - * @codec: Codec instance - * - * Creates msm_sdw module and version entry under the given - * parent directory. - * - * Return: 0 on success or negative error code on failure. - */ -int msm_sdw_codec_info_create_codec_entry(struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) -{ - struct snd_info_entry *version_entry; - struct msm_sdw_priv *msm_sdw; - struct snd_soc_card *card; - char name[80]; - - if (!codec_root || !codec) - return -EINVAL; - - msm_sdw = snd_soc_codec_get_drvdata(codec); - card = codec->component.card; - - snprintf(name, sizeof(name), "%x.%s", (u32)msm_sdw->sdw_base_addr, - "msm-sdw-codec"); - msm_sdw->entry = snd_info_create_subdir(codec_root->module, - (const char *)name, - codec_root); - if (!msm_sdw->entry) { - dev_err(codec->dev, "%s: failed to create msm_sdw entry\n", - __func__); - return -ENOMEM; - } - - version_entry = snd_info_create_card_entry(card->snd_card, - "version", - msm_sdw->entry); - if (!version_entry) { - dev_err(codec->dev, "%s: failed to create msm_sdw version entry\n", - __func__); - return -ENOMEM; - } - - version_entry->private_data = msm_sdw; - version_entry->size = MSM_SDW_VERSION_ENTRY_SIZE; - version_entry->content = SNDRV_INFO_CONTENT_DATA; - version_entry->c.ops = &msm_sdw_codec_info_ops; - - if (snd_info_register(version_entry) < 0) { - snd_info_free_entry(version_entry); - return -ENOMEM; - } - msm_sdw->version_entry = version_entry; - - return 0; -} -EXPORT_SYMBOL(msm_sdw_codec_info_create_codec_entry); - -static struct snd_soc_dai_ops msm_sdw_dai_ops = { - .startup = msm_sdw_startup, - .shutdown = msm_sdw_shutdown, - .hw_params = msm_sdw_hw_params, -}; - -static struct snd_soc_dai_driver msm_sdw_dai[] = { - { - .name = "msm_sdw_i2s_rx1", - .id = AIF1_SDW_PB, - .playback = { - .stream_name = "AIF1_SDW Playback", - .rates = MSM_SDW_RATES, - .formats = MSM_SDW_FORMATS, - .rate_max = 192000, - .rate_min = 8000, - .channels_min = 1, - .channels_max = 4, - }, - .ops = &msm_sdw_dai_ops, - }, - { - .name = "msm_sdw_vifeedback", - .id = AIF1_SDW_VIFEED, - .capture = { - .stream_name = "VIfeed_SDW", - .rates = MSM_SDW_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rate_max = 48000, - .rate_min = 8000, - .channels_min = 2, - .channels_max = 4, - }, - .ops = &msm_sdw_dai_ops, - }, -}; - -static const char * const rx_mix1_text[] = { - "ZERO", "RX4", "RX5" -}; - -static const char * const msm_sdw_ear_spkr_pa_gain_text[] = { - "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB", - "G_4_DB", "G_5_DB", "G_6_DB" -}; - -static const char * const msm_sdw_speaker_boost_stage_text[] = { - "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2" -}; - -static SOC_ENUM_SINGLE_EXT_DECL(msm_sdw_ear_spkr_pa_gain_enum, - msm_sdw_ear_spkr_pa_gain_text); -static SOC_ENUM_SINGLE_EXT_DECL(msm_sdw_spkr_boost_stage_enum, - msm_sdw_speaker_boost_stage_text); - -/* RX4 MIX1 */ -static const struct soc_enum rx4_mix1_inp1_chain_enum = - SOC_ENUM_SINGLE(MSM_SDW_TOP_RX7_PATH_INPUT0_MUX, - 0, 3, rx_mix1_text); - -static const struct soc_enum rx4_mix1_inp2_chain_enum = - SOC_ENUM_SINGLE(MSM_SDW_TOP_RX7_PATH_INPUT1_MUX, - 0, 3, rx_mix1_text); - -/* RX5 MIX1 */ -static const struct soc_enum rx5_mix1_inp1_chain_enum = - SOC_ENUM_SINGLE(MSM_SDW_TOP_RX8_PATH_INPUT0_MUX, - 0, 3, rx_mix1_text); - -static const struct soc_enum rx5_mix1_inp2_chain_enum = - SOC_ENUM_SINGLE(MSM_SDW_TOP_RX8_PATH_INPUT1_MUX, - 0, 3, rx_mix1_text); - -static const struct snd_kcontrol_new rx4_mix1_inp1_mux = - SOC_DAPM_ENUM("RX4 MIX1 INP1 Mux", rx4_mix1_inp1_chain_enum); - -static const struct snd_kcontrol_new rx4_mix1_inp2_mux = - SOC_DAPM_ENUM("RX4 MIX1 INP2 Mux", rx4_mix1_inp2_chain_enum); - -static const struct snd_kcontrol_new rx5_mix1_inp1_mux = - SOC_DAPM_ENUM("RX5 MIX1 INP1 Mux", rx5_mix1_inp1_chain_enum); - -static const struct snd_kcontrol_new rx5_mix1_inp2_mux = - SOC_DAPM_ENUM("RX5 MIX1 INP2 Mux", rx5_mix1_inp2_chain_enum); - -static const struct snd_kcontrol_new aif1_vi_mixer[] = { - SOC_SINGLE_EXT("SPKR_VI_1", SND_SOC_NOPM, MSM_SDW_TX0, 1, 0, - msm_sdw_vi_feed_mixer_get, msm_sdw_vi_feed_mixer_put), - SOC_SINGLE_EXT("SPKR_VI_2", SND_SOC_NOPM, MSM_SDW_TX1, 1, 0, - msm_sdw_vi_feed_mixer_get, msm_sdw_vi_feed_mixer_put), -}; - -static const struct snd_soc_dapm_widget msm_sdw_dapm_widgets[] = { - SND_SOC_DAPM_AIF_IN("I2S RX4", "AIF1_SDW Playback", 0, - SND_SOC_NOPM, 0, 0), - - SND_SOC_DAPM_AIF_IN("I2S RX5", "AIF1_SDW Playback", 0, - SND_SOC_NOPM, 0, 0), - - SND_SOC_DAPM_AIF_OUT_E("AIF1_SDW VI", "VIfeed_SDW", 0, SND_SOC_NOPM, - AIF1_SDW_VIFEED, 0, msm_sdw_codec_enable_vi_feedback, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER("AIF1_VI_SDW Mixer", SND_SOC_NOPM, AIF1_SDW_VIFEED, - 0, aif1_vi_mixer, ARRAY_SIZE(aif1_vi_mixer)), - - SND_SOC_DAPM_MUX_E("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0, - &rx4_mix1_inp1_mux, msm_sdw_enable_swr, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0, - &rx4_mix1_inp2_mux, msm_sdw_enable_swr, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("RX5 MIX1 INP1", SND_SOC_NOPM, 0, 0, - &rx5_mix1_inp1_mux, msm_sdw_enable_swr, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("RX5 MIX1 INP2", SND_SOC_NOPM, 0, 0, - &rx5_mix1_inp2_mux, msm_sdw_enable_swr, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER("RX4 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("RX5 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), - - SND_SOC_DAPM_MIXER_E("RX INT4 INTERP", SND_SOC_NOPM, - COMP1, 0, NULL, 0, msm_sdw_codec_enable_interpolator, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER_E("RX INT5 INTERP", SND_SOC_NOPM, - COMP2, 0, NULL, 0, msm_sdw_codec_enable_interpolator, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MIXER_E("RX INT4 CHAIN", SND_SOC_NOPM, 0, 0, - NULL, 0, msm_sdw_codec_spk_boost_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER_E("RX INT5 CHAIN", SND_SOC_NOPM, 0, 0, - NULL, 0, msm_sdw_codec_spk_boost_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_INPUT("VIINPUT_SDW"), - - SND_SOC_DAPM_OUTPUT("SPK1 OUT"), - SND_SOC_DAPM_OUTPUT("SPK2 OUT"), - - SND_SOC_DAPM_SUPPLY_S("SDW_CONN", -1, MSM_SDW_TOP_I2S_CLK, - 0, 0, NULL, 0), - - SND_SOC_DAPM_SUPPLY_S("INT_MCLK1", -2, SND_SOC_NOPM, 0, 0, - msm_int_mclk1_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY("SDW_RX_I2S_CLK", - MSM_SDW_TOP_RX_I2S_CTL, 0, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("SDW_TX_I2S_CLK", - MSM_SDW_TOP_TX_I2S_CTL, 0, 0, NULL, 0), -}; - -static const struct snd_kcontrol_new msm_sdw_snd_controls[] = { - SOC_ENUM_EXT("EAR SPKR PA Gain", msm_sdw_ear_spkr_pa_gain_enum, - msm_sdw_ear_spkr_pa_gain_get, - msm_sdw_ear_spkr_pa_gain_put), - SOC_ENUM_EXT("SPKR Left Boost Max State", - msm_sdw_spkr_boost_stage_enum, - msm_sdw_spkr_left_boost_stage_get, - msm_sdw_spkr_left_boost_stage_put), - SOC_ENUM_EXT("SPKR Right Boost Max State", - msm_sdw_spkr_boost_stage_enum, - msm_sdw_spkr_right_boost_stage_get, - msm_sdw_spkr_right_boost_stage_put), - SOC_SINGLE_SX_TLV("RX4 Digital Volume", MSM_SDW_RX7_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX5 Digital Volume", MSM_SDW_RX8_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMP1, 1, 0, - msm_sdw_get_compander, msm_sdw_set_compander), - SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMP2, 1, 0, - msm_sdw_get_compander, msm_sdw_set_compander), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - - {"AIF1_SDW VI", NULL, "SDW_TX_I2S_CLK"}, - {"SDW_TX_I2S_CLK", NULL, "INT_MCLK1"}, - {"SDW_TX_I2S_CLK", NULL, "SDW_CONN"}, - - /* VI Feedback */ - {"AIF1_VI_SDW Mixer", "SPKR_VI_1", "VIINPUT_SDW"}, - {"AIF1_VI_SDW Mixer", "SPKR_VI_2", "VIINPUT_SDW"}, - {"AIF1_SDW VI", NULL, "AIF1_VI_SDW Mixer"}, - - {"SDW_RX_I2S_CLK", NULL, "INT_MCLK1"}, - {"SDW_RX_I2S_CLK", NULL, "SDW_CONN"}, - {"I2S RX4", NULL, "SDW_RX_I2S_CLK"}, - {"I2S RX5", NULL, "SDW_RX_I2S_CLK"}, - - {"RX4 MIX1 INP1", "RX4", "I2S RX4"}, - {"RX4 MIX1 INP1", "RX5", "I2S RX5"}, - {"RX4 MIX1 INP2", "RX4", "I2S RX4"}, - {"RX4 MIX1 INP2", "RX5", "I2S RX5"}, - {"RX5 MIX1 INP1", "RX4", "I2S RX4"}, - {"RX5 MIX1 INP1", "RX5", "I2S RX5"}, - {"RX5 MIX1 INP2", "RX4", "I2S RX4"}, - {"RX5 MIX1 INP2", "RX5", "I2S RX5"}, - - {"RX4 MIX1", NULL, "RX4 MIX1 INP1"}, - {"RX4 MIX1", NULL, "RX4 MIX1 INP2"}, - {"RX5 MIX1", NULL, "RX5 MIX1 INP1"}, - {"RX5 MIX1", NULL, "RX5 MIX1 INP2"}, - - {"RX INT4 INTERP", NULL, "RX4 MIX1"}, - {"RX INT4 CHAIN", NULL, "RX INT4 INTERP"}, - {"SPK1 OUT", NULL, "RX INT4 CHAIN"}, - - {"RX INT5 INTERP", NULL, "RX5 MIX1"}, - {"RX INT5 CHAIN", NULL, "RX INT5 INTERP"}, - {"SPK2 OUT", NULL, "RX INT5 CHAIN"}, -}; - -static const struct msm_sdw_reg_mask_val msm_sdw_reg_init[] = { - {MSM_SDW_BOOST0_BOOST_CFG1, 0x3F, 0x12}, - {MSM_SDW_BOOST0_BOOST_CFG2, 0x1C, 0x08}, - {MSM_SDW_COMPANDER7_CTL7, 0x1E, 0x18}, - {MSM_SDW_BOOST1_BOOST_CFG1, 0x3F, 0x12}, - {MSM_SDW_BOOST1_BOOST_CFG2, 0x1C, 0x08}, - {MSM_SDW_COMPANDER8_CTL7, 0x1E, 0x18}, - {MSM_SDW_BOOST0_BOOST_CTL, 0x7C, 0x58}, - {MSM_SDW_BOOST1_BOOST_CTL, 0x7C, 0x58}, - {MSM_SDW_RX7_RX_PATH_CFG1, 0x08, 0x08}, - {MSM_SDW_RX8_RX_PATH_CFG1, 0x08, 0x08}, - {MSM_SDW_TOP_TOP_CFG1, 0x02, 0x02}, - {MSM_SDW_TOP_TOP_CFG1, 0x01, 0x01}, - {MSM_SDW_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, - {MSM_SDW_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, - {MSM_SDW_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, - {MSM_SDW_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, - {MSM_SDW_COMPANDER7_CTL3, 0x80, 0x80}, - {MSM_SDW_COMPANDER8_CTL3, 0x80, 0x80}, - {MSM_SDW_COMPANDER7_CTL7, 0x01, 0x01}, - {MSM_SDW_COMPANDER8_CTL7, 0x01, 0x01}, - {MSM_SDW_RX7_RX_PATH_CFG0, 0x01, 0x01}, - {MSM_SDW_RX8_RX_PATH_CFG0, 0x01, 0x01}, - {MSM_SDW_RX7_RX_PATH_MIX_CFG, 0x01, 0x01}, - {MSM_SDW_RX8_RX_PATH_MIX_CFG, 0x01, 0x01}, -}; - -static void msm_sdw_init_reg(struct snd_soc_codec *codec) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(msm_sdw_reg_init); i++) - snd_soc_update_bits(codec, - msm_sdw_reg_init[i].reg, - msm_sdw_reg_init[i].mask, - msm_sdw_reg_init[i].val); -} - -static int msm_sdw_notifier_service_cb(struct notifier_block *nb, - unsigned long opcode, void *ptr) -{ - int i; - struct msm_sdw_priv *msm_sdw = container_of(nb, - struct msm_sdw_priv, - service_nb); - bool adsp_ready = false; - unsigned long timeout; - static bool initial_boot = true; - - pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); - - mutex_lock(&msm_sdw->codec_mutex); - switch (opcode) { - case AUDIO_NOTIFIER_SERVICE_DOWN: - if (initial_boot) { - initial_boot = false; - break; - } - msm_sdw->int_mclk1_enabled = false; - msm_sdw->dev_up = false; - for (i = 0; i < msm_sdw->nr; i++) - swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, - SWR_DEVICE_DOWN, NULL); - break; - case AUDIO_NOTIFIER_SERVICE_UP: - if (initial_boot) - initial_boot = false; - if (!q6core_is_adsp_ready()) { - dev_dbg(msm_sdw->dev, "ADSP isn't ready\n"); - timeout = jiffies + - msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); - while (!time_after(jiffies, timeout)) { - if (!q6core_is_adsp_ready()) { - dev_dbg(msm_sdw->dev, - "ADSP isn't ready\n"); - } else { - dev_dbg(msm_sdw->dev, - "ADSP is ready\n"); - adsp_ready = true; - goto powerup; - } - } - } else { - adsp_ready = true; - dev_dbg(msm_sdw->dev, "%s: DSP is ready\n", __func__); - } -powerup: - if (adsp_ready) { - msm_sdw->dev_up = true; - msm_sdw_init_reg(msm_sdw->codec); - regcache_mark_dirty(msm_sdw->regmap); - regcache_sync(msm_sdw->regmap); - msm_sdw_set_spkr_mode(msm_sdw->codec, - msm_sdw->spkr_mode); - } - break; - default: - break; - } - mutex_unlock(&msm_sdw->codec_mutex); - return NOTIFY_OK; -} - -static int msm_sdw_codec_probe(struct snd_soc_codec *codec) -{ - struct msm_sdw_priv *msm_sdw; - int i, ret; - - msm_sdw = snd_soc_codec_get_drvdata(codec); - if (!msm_sdw) { - pr_err("%s:SDW priv data null\n", __func__); - return -EINVAL; - } - msm_sdw->codec = codec; - for (i = 0; i < COMP_MAX; i++) - msm_sdw->comp_enabled[i] = 0; - - msm_sdw->spkr_gain_offset = RX_GAIN_OFFSET_0_DB; - msm_sdw_init_reg(codec); - msm_sdw->version = MSM_SDW_VERSION_1_0; - - msm_sdw->service_nb.notifier_call = msm_sdw_notifier_service_cb; - ret = audio_notifier_register("msm_sdw", - AUDIO_NOTIFIER_ADSP_DOMAIN, - &msm_sdw->service_nb); - if (ret < 0) - dev_err(msm_sdw->dev, - "%s: Audio notifier register failed ret = %d\n", - __func__, ret); - return 0; -} - -static int msm_sdw_codec_remove(struct snd_soc_codec *codec) -{ - return 0; -} - -static struct regmap *msm_sdw_get_regmap(struct device *dev) -{ - struct msm_sdw_priv *msm_sdw = dev_get_drvdata(dev); - - return msm_sdw->regmap; -} - -static struct snd_soc_codec_driver soc_codec_dev_msm_sdw = { - .probe = msm_sdw_codec_probe, - .remove = msm_sdw_codec_remove, - .get_regmap = msm_sdw_get_regmap, - .component_driver = { - .controls = msm_sdw_snd_controls, - .num_controls = ARRAY_SIZE(msm_sdw_snd_controls), - .dapm_widgets = msm_sdw_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(msm_sdw_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), - }, -}; - -static void msm_sdw_add_child_devices(struct work_struct *work) -{ - struct msm_sdw_priv *msm_sdw; - struct platform_device *pdev; - struct device_node *node; - struct msm_sdw_ctrl_data *sdw_ctrl_data = NULL, *temp; - int ret, ctrl_num = 0; - struct wcd_sdw_ctrl_platform_data *platdata; - char plat_dev_name[MSM_SDW_STRING_LEN]; - - msm_sdw = container_of(work, struct msm_sdw_priv, - msm_sdw_add_child_devices_work); - if (!msm_sdw) { - pr_err("%s: Memory for msm_sdw does not exist\n", - __func__); - return; - } - if (!msm_sdw->dev->of_node) { - dev_err(msm_sdw->dev, - "%s: DT node for msm_sdw does not exist\n", __func__); - return; - } - - platdata = &msm_sdw->sdw_plat_data; - - for_each_available_child_of_node(msm_sdw->dev->of_node, node) { - if (!strcmp(node->name, "swr_master")) - strlcpy(plat_dev_name, "msm_sdw_swr_ctrl", - (MSM_SDW_STRING_LEN - 1)); - else if (strnstr(node->name, "msm_cdc_pinctrl", - strlen("msm_cdc_pinctrl")) != NULL) - strlcpy(plat_dev_name, node->name, - (MSM_SDW_STRING_LEN - 1)); - else - continue; - - pdev = platform_device_alloc(plat_dev_name, -1); - if (!pdev) { - dev_err(msm_sdw->dev, "%s: pdev memory alloc failed\n", - __func__); - ret = -ENOMEM; - goto err; - } - pdev->dev.parent = msm_sdw->dev; - pdev->dev.of_node = node; - - if (!strcmp(node->name, "swr_master")) { - ret = platform_device_add_data(pdev, platdata, - sizeof(*platdata)); - if (ret) { - dev_err(&pdev->dev, - "%s: cannot add plat data ctrl:%d\n", - __func__, ctrl_num); - goto fail_pdev_add; - } - } - - ret = platform_device_add(pdev); - if (ret) { - dev_err(&pdev->dev, - "%s: Cannot add platform device\n", - __func__); - goto fail_pdev_add; - } - - if (!strcmp(node->name, "swr_master")) { - temp = krealloc(sdw_ctrl_data, - (ctrl_num + 1) * sizeof( - struct msm_sdw_ctrl_data), - GFP_KERNEL); - if (!temp) { - dev_err(&pdev->dev, "out of memory\n"); - ret = -ENOMEM; - goto err; - } - sdw_ctrl_data = temp; - sdw_ctrl_data[ctrl_num].sdw_pdev = pdev; - ctrl_num++; - dev_dbg(&pdev->dev, - "%s: Added soundwire ctrl device(s)\n", - __func__); - msm_sdw->nr = ctrl_num; - msm_sdw->sdw_ctrl_data = sdw_ctrl_data; - } - msm_sdw->pdev_child_devices[msm_sdw->child_count++] = pdev; - } - - return; -fail_pdev_add: - platform_device_put(pdev); -err: - return; -} - -static int msm_sdw_probe(struct platform_device *pdev) -{ - int ret = 0; - struct msm_sdw_priv *msm_sdw; - int adsp_state; - - adsp_state = apr_get_subsys_state(); - if (adsp_state != APR_SUBSYS_LOADED) { - dev_err(&pdev->dev, "Adsp is not loaded yet %d\n", - adsp_state); - return -EPROBE_DEFER; - } - - msm_sdw = devm_kzalloc(&pdev->dev, sizeof(struct msm_sdw_priv), - GFP_KERNEL); - if (!msm_sdw) - return -ENOMEM; - dev_set_drvdata(&pdev->dev, msm_sdw); - msm_sdw->dev_up = true; - - msm_sdw->dev = &pdev->dev; - INIT_WORK(&msm_sdw->msm_sdw_add_child_devices_work, - msm_sdw_add_child_devices); - msm_sdw->sdw_plat_data.handle = (void *) msm_sdw; - msm_sdw->sdw_plat_data.read = msm_sdw_swrm_read; - msm_sdw->sdw_plat_data.write = msm_sdw_swrm_write; - msm_sdw->sdw_plat_data.bulk_write = msm_sdw_swrm_bulk_write; - msm_sdw->sdw_plat_data.clk = msm_sdw_swrm_clock; - msm_sdw->sdw_plat_data.handle_irq = msm_sdwm_handle_irq; - ret = of_property_read_u32(pdev->dev.of_node, "reg", - &msm_sdw->sdw_base_addr); - if (ret) { - dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", - __func__, "reg"); - goto err_sdw_cdc; - } - - msm_sdw->sdw_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,cdc-sdw-gpios", 0); - msm_sdw->sdw_base = ioremap(msm_sdw->sdw_base_addr, - MSM_SDW_MAX_REGISTER); - msm_sdw->read_dev = __msm_sdw_reg_read; - msm_sdw->write_dev = __msm_sdw_reg_write; - - msm_sdw->regmap = msm_sdw_regmap_init(msm_sdw->dev, - &msm_sdw_regmap_config); - msm_sdw->sdw_irq = platform_get_irq_byname(pdev, "swr_master_irq"); - if (msm_sdw->sdw_irq < 0) { - dev_err(msm_sdw->dev, "%s() error getting irq handle: %d\n", - __func__, msm_sdw->sdw_irq); - ret = -ENODEV; - goto err_sdw_cdc; - } - ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_msm_sdw, - msm_sdw_dai, ARRAY_SIZE(msm_sdw_dai)); - if (ret) { - dev_err(&pdev->dev, "%s: Codec registration failed, ret = %d\n", - __func__, ret); - goto err_sdw_cdc; - } - /* initialize the int_mclk1 */ - msm_sdw->sdw_cdc_core_clk.clk_set_minor_version = - AFE_API_VERSION_I2S_CONFIG; - msm_sdw->sdw_cdc_core_clk.clk_id = - Q6AFE_LPASS_CLK_ID_INT_MCLK_1; - msm_sdw->sdw_cdc_core_clk.clk_freq_in_hz = - INT_MCLK1_FREQ; - msm_sdw->sdw_cdc_core_clk.clk_attri = - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO; - msm_sdw->sdw_cdc_core_clk.clk_root = - Q6AFE_LPASS_CLK_ROOT_DEFAULT; - msm_sdw->sdw_cdc_core_clk.enable = 0; - - /* initialize the sdw_npl_clk */ - msm_sdw->sdw_npl_clk.clk_set_minor_version = - AFE_API_VERSION_I2S_CONFIG; - msm_sdw->sdw_npl_clk.clk_id = - AFE_CLOCK_SET_CLOCK_ID_SWR_NPL_CLK; - msm_sdw->sdw_npl_clk.clk_freq_in_hz = SDW_NPL_FREQ; - msm_sdw->sdw_npl_clk.clk_attri = - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO; - msm_sdw->sdw_npl_clk.clk_root = - Q6AFE_LPASS_CLK_ROOT_DEFAULT; - msm_sdw->sdw_npl_clk.enable = 0; - - INIT_DELAYED_WORK(&msm_sdw->disable_int_mclk1_work, - msm_disable_int_mclk1); - mutex_init(&msm_sdw->cdc_int_mclk1_mutex); - mutex_init(&msm_sdw->sdw_npl_clk_mutex); - mutex_init(&msm_sdw->io_lock); - mutex_init(&msm_sdw->sdw_read_lock); - mutex_init(&msm_sdw->sdw_write_lock); - mutex_init(&msm_sdw->sdw_clk_lock); - mutex_init(&msm_sdw->codec_mutex); - schedule_work(&msm_sdw->msm_sdw_add_child_devices_work); - - dev_dbg(&pdev->dev, "%s: msm_sdw driver probe done\n", __func__); - return ret; - -err_sdw_cdc: - devm_kfree(&pdev->dev, msm_sdw); - return ret; -} - -static int msm_sdw_remove(struct platform_device *pdev) -{ - struct msm_sdw_priv *msm_sdw; - int count; - - msm_sdw = dev_get_drvdata(&pdev->dev); - - for (count = 0; count < msm_sdw->child_count && - count < MSM_SDW_CHILD_DEVICES_MAX; count++) - platform_device_unregister(msm_sdw->pdev_child_devices[count]); - - mutex_destroy(&msm_sdw->io_lock); - mutex_destroy(&msm_sdw->sdw_read_lock); - mutex_destroy(&msm_sdw->sdw_write_lock); - mutex_destroy(&msm_sdw->sdw_clk_lock); - mutex_destroy(&msm_sdw->codec_mutex); - mutex_destroy(&msm_sdw->cdc_int_mclk1_mutex); - - devm_kfree(&pdev->dev, msm_sdw); - snd_soc_unregister_codec(&pdev->dev); - return 0; -} - -static const struct of_device_id msm_sdw_codec_dt_match[] = { - { .compatible = "qcom,msm-sdw-codec", }, - {} -}; - -static struct platform_driver msm_sdw_codec_driver = { - .probe = msm_sdw_probe, - .remove = msm_sdw_remove, - .driver = { - .name = "msm_sdw_codec", - .owner = THIS_MODULE, - .of_match_table = msm_sdw_codec_dt_match, - }, -}; -module_platform_driver(msm_sdw_codec_driver); - -MODULE_DESCRIPTION("MSM Soundwire Codec driver"); -MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/msm_sdw/msm_sdw_cdc_utils.c b/asoc/codecs/msm_sdw/msm_sdw_cdc_utils.c deleted file mode 100644 index 9a5c85bf0c6c..000000000000 --- a/asoc/codecs/msm_sdw/msm_sdw_cdc_utils.c +++ /dev/null @@ -1,211 +0,0 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include "msm_sdw.h" - -#define REG_BYTES 2 -#define VAL_BYTES 1 -/* - * Page Register Address that APP Proc uses to - * access WCD9335 Codec registers is identified - * as 0x00 - */ -#define PAGE_REG_ADDR 0x00 - -/* - * msm_sdw_page_write: - * Retrieve page number from register and - * write that page number to the page address. - * Called under io_lock acquisition. - * - * @msm_sdw: pointer to msm_sdw - * @reg: Register address from which page number is retrieved - * - * Returns 0 for success and negative error code for failure. - */ -int msm_sdw_page_write(struct msm_sdw_priv *msm_sdw, unsigned short reg) -{ - int ret = 0; - u8 pg_num, prev_pg_num; - - pg_num = msm_sdw_page_map[reg]; - if (msm_sdw->prev_pg_valid) { - prev_pg_num = msm_sdw->prev_pg; - if (prev_pg_num != pg_num) { - ret = msm_sdw->write_dev(msm_sdw, PAGE_REG_ADDR, 1, - (void *) &pg_num); - if (ret < 0) { - dev_err(msm_sdw->dev, - "page write error, pg_num: 0x%x\n", - pg_num); - } else { - msm_sdw->prev_pg = pg_num; - dev_dbg(msm_sdw->dev, - "%s: Page 0x%x Write to 0x00\n", - __func__, pg_num); - } - } - } else { - ret = msm_sdw->write_dev(msm_sdw, PAGE_REG_ADDR, 1, - (void *) &pg_num); - if (ret < 0) { - dev_err(msm_sdw->dev, - "page write error, pg_num: 0x%x\n", pg_num); - } else { - msm_sdw->prev_pg = pg_num; - msm_sdw->prev_pg_valid = true; - dev_dbg(msm_sdw->dev, "%s: Page 0x%x Write to 0x00\n", - __func__, pg_num); - } - } - return ret; -} -EXPORT_SYMBOL(msm_sdw_page_write); - -static int regmap_bus_read(void *context, const void *reg, size_t reg_size, - void *val, size_t val_size) -{ - struct device *dev = context; - struct msm_sdw_priv *msm_sdw = dev_get_drvdata(dev); - unsigned short c_reg; - int ret, i; - - if (!msm_sdw) { - dev_err(dev, "%s: msm_sdw is NULL\n", __func__); - return -EINVAL; - } - if (!reg || !val) { - dev_err(dev, "%s: reg or val is NULL\n", __func__); - return -EINVAL; - } - if (reg_size != REG_BYTES) { - dev_err(dev, "%s: register size %zd bytes, not supported\n", - __func__, reg_size); - return -EINVAL; - } - if (!msm_sdw->dev_up) { - dev_dbg_ratelimited(dev, "%s: No read allowed. dev_up = %d\n", - __func__, msm_sdw->dev_up); - return 0; - } - - mutex_lock(&msm_sdw->io_lock); - c_reg = *(u16 *)reg; - ret = msm_sdw_page_write(msm_sdw, c_reg); - if (ret) - goto err; - ret = msm_sdw->read_dev(msm_sdw, c_reg, val_size, val); - if (ret < 0) - dev_err(dev, "%s: Codec read failed (%d), reg: 0x%x, size:%zd\n", - __func__, ret, c_reg, val_size); - else { - for (i = 0; i < val_size; i++) - dev_dbg(dev, "%s: Read 0x%02x from 0x%x\n", - __func__, ((u8 *)val)[i], c_reg + i); - } -err: - mutex_unlock(&msm_sdw->io_lock); - - return ret; -} - -static int regmap_bus_gather_write(void *context, - const void *reg, size_t reg_size, - const void *val, size_t val_size) -{ - struct device *dev = context; - struct msm_sdw_priv *msm_sdw = dev_get_drvdata(dev); - unsigned short c_reg; - int ret, i; - - if (!msm_sdw) { - dev_err(dev, "%s: msm_sdw is NULL\n", __func__); - return -EINVAL; - } - if (!reg || !val) { - dev_err(dev, "%s: reg or val is NULL\n", __func__); - return -EINVAL; - } - if (reg_size != REG_BYTES) { - dev_err(dev, "%s: register size %zd bytes, not supported\n", - __func__, reg_size); - return -EINVAL; - } - if (!msm_sdw->dev_up) { - dev_dbg_ratelimited(dev, "%s: No write allowed. dev_up = %d\n", - __func__, msm_sdw->dev_up); - return 0; - } - - mutex_lock(&msm_sdw->io_lock); - c_reg = *(u16 *)reg; - ret = msm_sdw_page_write(msm_sdw, c_reg); - if (ret) - goto err; - - for (i = 0; i < val_size; i++) - dev_dbg(dev, "Write %02x to 0x%x\n", ((u8 *)val)[i], - c_reg + i*4); - - ret = msm_sdw->write_dev(msm_sdw, c_reg, val_size, (void *) val); - if (ret < 0) - dev_err(dev, - "%s: Codec write failed (%d), reg:0x%x, size:%zd\n", - __func__, ret, c_reg, val_size); - -err: - mutex_unlock(&msm_sdw->io_lock); - return ret; -} - -static int regmap_bus_write(void *context, const void *data, size_t count) -{ - struct device *dev = context; - struct msm_sdw_priv *msm_sdw = dev_get_drvdata(dev); - - if (!msm_sdw) - return -EINVAL; - - WARN_ON(count < REG_BYTES); - - return regmap_bus_gather_write(context, data, REG_BYTES, - data + REG_BYTES, - count - REG_BYTES); - -} - -static struct regmap_bus regmap_bus_config = { - .write = regmap_bus_write, - .gather_write = regmap_bus_gather_write, - .read = regmap_bus_read, - .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, - .val_format_endian_default = REGMAP_ENDIAN_NATIVE, -}; - -/* - * msm_sdw_regmap_init: - * Initialize msm_sdw register map - * - * @dev: pointer to wcd device - * @config: pointer to register map config - * - * Returns pointer to regmap structure for success - * or NULL in case of failure. - */ -struct regmap *msm_sdw_regmap_init(struct device *dev, - const struct regmap_config *config) -{ - return devm_regmap_init(dev, ®map_bus_config, dev, config); -} -EXPORT_SYMBOL(msm_sdw_regmap_init); diff --git a/asoc/codecs/msm_sdw/msm_sdw_registers.h b/asoc/codecs/msm_sdw/msm_sdw_registers.h deleted file mode 100644 index 1b7b0b01a6b2..000000000000 --- a/asoc/codecs/msm_sdw/msm_sdw_registers.h +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef MSM_SDW_REGISTERS_H -#define MSM_SDW_REGISTERS_H - -#define MSM_SDW_PAGE_REGISTER 0x0000 - -/* Page-A Registers */ -#define MSM_SDW_TX9_SPKR_PROT_PATH_CTL 0x0308 -#define MSM_SDW_TX9_SPKR_PROT_PATH_CFG0 0x030c -#define MSM_SDW_TX10_SPKR_PROT_PATH_CTL 0x0318 -#define MSM_SDW_TX10_SPKR_PROT_PATH_CFG0 0x031c -#define MSM_SDW_TX11_SPKR_PROT_PATH_CTL 0x0328 -#define MSM_SDW_TX11_SPKR_PROT_PATH_CFG0 0x032c -#define MSM_SDW_TX12_SPKR_PROT_PATH_CTL 0x0338 -#define MSM_SDW_TX12_SPKR_PROT_PATH_CFG0 0x033c - -/* Page-B Registers */ -#define MSM_SDW_COMPANDER7_CTL0 0x0024 -#define MSM_SDW_COMPANDER7_CTL1 0x0028 -#define MSM_SDW_COMPANDER7_CTL2 0x002c -#define MSM_SDW_COMPANDER7_CTL3 0x0030 -#define MSM_SDW_COMPANDER7_CTL4 0x0034 -#define MSM_SDW_COMPANDER7_CTL5 0x0038 -#define MSM_SDW_COMPANDER7_CTL6 0x003c -#define MSM_SDW_COMPANDER7_CTL7 0x0040 -#define MSM_SDW_COMPANDER8_CTL0 0x0044 -#define MSM_SDW_COMPANDER8_CTL1 0x0048 -#define MSM_SDW_COMPANDER8_CTL2 0x004c -#define MSM_SDW_COMPANDER8_CTL3 0x0050 -#define MSM_SDW_COMPANDER8_CTL4 0x0054 -#define MSM_SDW_COMPANDER8_CTL5 0x0058 -#define MSM_SDW_COMPANDER8_CTL6 0x005c -#define MSM_SDW_COMPANDER8_CTL7 0x0060 -#define MSM_SDW_RX7_RX_PATH_CTL 0x01a4 -#define MSM_SDW_RX7_RX_PATH_CFG0 0x01a8 -#define MSM_SDW_RX7_RX_PATH_CFG1 0x01ac -#define MSM_SDW_RX7_RX_PATH_CFG2 0x01b0 -#define MSM_SDW_RX7_RX_VOL_CTL 0x01b4 -#define MSM_SDW_RX7_RX_PATH_MIX_CTL 0x01b8 -#define MSM_SDW_RX7_RX_PATH_MIX_CFG 0x01bc -#define MSM_SDW_RX7_RX_VOL_MIX_CTL 0x01c0 -#define MSM_SDW_RX7_RX_PATH_SEC0 0x01c4 -#define MSM_SDW_RX7_RX_PATH_SEC1 0x01c8 -#define MSM_SDW_RX7_RX_PATH_SEC2 0x01cc -#define MSM_SDW_RX7_RX_PATH_SEC3 0x01d0 -#define MSM_SDW_RX7_RX_PATH_SEC5 0x01d8 -#define MSM_SDW_RX7_RX_PATH_SEC6 0x01dc -#define MSM_SDW_RX7_RX_PATH_SEC7 0x01e0 -#define MSM_SDW_RX7_RX_PATH_MIX_SEC0 0x01e4 -#define MSM_SDW_RX7_RX_PATH_MIX_SEC1 0x01e8 -#define MSM_SDW_RX8_RX_PATH_CTL 0x0384 -#define MSM_SDW_RX8_RX_PATH_CFG0 0x0388 -#define MSM_SDW_RX8_RX_PATH_CFG1 0x038c -#define MSM_SDW_RX8_RX_PATH_CFG2 0x0390 -#define MSM_SDW_RX8_RX_VOL_CTL 0x0394 -#define MSM_SDW_RX8_RX_PATH_MIX_CTL 0x0398 -#define MSM_SDW_RX8_RX_PATH_MIX_CFG 0x039c -#define MSM_SDW_RX8_RX_VOL_MIX_CTL 0x03a0 -#define MSM_SDW_RX8_RX_PATH_SEC0 0x03a4 -#define MSM_SDW_RX8_RX_PATH_SEC1 0x03a8 -#define MSM_SDW_RX8_RX_PATH_SEC2 0x03ac -#define MSM_SDW_RX8_RX_PATH_SEC3 0x03b0 -#define MSM_SDW_RX8_RX_PATH_SEC5 0x03b8 -#define MSM_SDW_RX8_RX_PATH_SEC6 0x03bc -#define MSM_SDW_RX8_RX_PATH_SEC7 0x03c0 -#define MSM_SDW_RX8_RX_PATH_MIX_SEC0 0x03c4 -#define MSM_SDW_RX8_RX_PATH_MIX_SEC1 0x03c8 - -/* Page-C Registers */ -#define MSM_SDW_BOOST0_BOOST_PATH_CTL 0x0064 -#define MSM_SDW_BOOST0_BOOST_CTL 0x0068 -#define MSM_SDW_BOOST0_BOOST_CFG1 0x006c -#define MSM_SDW_BOOST0_BOOST_CFG2 0x0070 -#define MSM_SDW_BOOST1_BOOST_PATH_CTL 0x0084 -#define MSM_SDW_BOOST1_BOOST_CTL 0x0088 -#define MSM_SDW_BOOST1_BOOST_CFG1 0x008c -#define MSM_SDW_BOOST1_BOOST_CFG2 0x0090 -#define MSM_SDW_AHB_BRIDGE_WR_DATA_0 0x00a4 -#define MSM_SDW_AHB_BRIDGE_WR_DATA_1 0x00a8 -#define MSM_SDW_AHB_BRIDGE_WR_DATA_2 0x00ac -#define MSM_SDW_AHB_BRIDGE_WR_DATA_3 0x00b0 -#define MSM_SDW_AHB_BRIDGE_WR_ADDR_0 0x00b4 -#define MSM_SDW_AHB_BRIDGE_WR_ADDR_1 0x00b8 -#define MSM_SDW_AHB_BRIDGE_WR_ADDR_2 0x00bc -#define MSM_SDW_AHB_BRIDGE_WR_ADDR_3 0x00c0 -#define MSM_SDW_AHB_BRIDGE_RD_ADDR_0 0x00c4 -#define MSM_SDW_AHB_BRIDGE_RD_ADDR_1 0x00c8 -#define MSM_SDW_AHB_BRIDGE_RD_ADDR_2 0x00cc -#define MSM_SDW_AHB_BRIDGE_RD_ADDR_3 0x00d0 -#define MSM_SDW_AHB_BRIDGE_RD_DATA_0 0x00d4 -#define MSM_SDW_AHB_BRIDGE_RD_DATA_1 0x00d8 -#define MSM_SDW_AHB_BRIDGE_RD_DATA_2 0x00dc -#define MSM_SDW_AHB_BRIDGE_RD_DATA_3 0x00e0 -#define MSM_SDW_AHB_BRIDGE_ACCESS_CFG 0x00e4 -#define MSM_SDW_AHB_BRIDGE_ACCESS_STATUS 0x00e8 - -/* Page-D Registers */ -#define MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL 0x0104 -#define MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL 0x0108 -#define MSM_SDW_CLK_RST_CTRL_SWR_CONTROL 0x010c -#define MSM_SDW_TOP_TOP_CFG0 0x0204 -#define MSM_SDW_TOP_TOP_CFG1 0x0208 -#define MSM_SDW_TOP_RX_I2S_CTL 0x020c -#define MSM_SDW_TOP_TX_I2S_CTL 0x0210 -#define MSM_SDW_TOP_I2S_CLK 0x0214 -#define MSM_SDW_TOP_RX7_PATH_INPUT0_MUX 0x0218 -#define MSM_SDW_TOP_RX7_PATH_INPUT1_MUX 0x021c -#define MSM_SDW_TOP_RX8_PATH_INPUT0_MUX 0x0220 -#define MSM_SDW_TOP_RX8_PATH_INPUT1_MUX 0x0224 -#define MSM_SDW_TOP_FREQ_MCLK 0x0228 -#define MSM_SDW_TOP_DEBUG_BUS_SEL 0x022c -#define MSM_SDW_TOP_DEBUG_EN 0x0230 -#define MSM_SDW_TOP_I2S_RESET 0x0234 -#define MSM_SDW_TOP_BLOCKS_RESET 0x0238 - -#endif diff --git a/asoc/codecs/msm_sdw/msm_sdw_regmap.c b/asoc/codecs/msm_sdw/msm_sdw_regmap.c deleted file mode 100644 index 7613e65d2c19..000000000000 --- a/asoc/codecs/msm_sdw/msm_sdw_regmap.c +++ /dev/null @@ -1,161 +0,0 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include "msm_sdw.h" - -static const struct reg_default msm_sdw_defaults[] = { - /* Page #10 registers */ - { MSM_SDW_PAGE_REGISTER, 0x00 }, - { MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x02 }, - { MSM_SDW_TX9_SPKR_PROT_PATH_CFG0, 0x00 }, - { MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x02 }, - { MSM_SDW_TX10_SPKR_PROT_PATH_CFG0, 0x00 }, - { MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x02 }, - { MSM_SDW_TX11_SPKR_PROT_PATH_CFG0, 0x00 }, - { MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x02 }, - { MSM_SDW_TX12_SPKR_PROT_PATH_CFG0, 0x00 }, - /* Page #11 registers */ - { MSM_SDW_COMPANDER7_CTL0, 0x60 }, - { MSM_SDW_COMPANDER7_CTL1, 0xdb }, - { MSM_SDW_COMPANDER7_CTL2, 0xff }, - { MSM_SDW_COMPANDER7_CTL3, 0x35 }, - { MSM_SDW_COMPANDER7_CTL4, 0xff }, - { MSM_SDW_COMPANDER7_CTL5, 0x00 }, - { MSM_SDW_COMPANDER7_CTL6, 0x01 }, - { MSM_SDW_COMPANDER8_CTL0, 0x60 }, - { MSM_SDW_COMPANDER8_CTL1, 0xdb }, - { MSM_SDW_COMPANDER8_CTL2, 0xff }, - { MSM_SDW_COMPANDER8_CTL3, 0x35 }, - { MSM_SDW_COMPANDER8_CTL4, 0xff }, - { MSM_SDW_COMPANDER8_CTL5, 0x00 }, - { MSM_SDW_COMPANDER8_CTL6, 0x01 }, - { MSM_SDW_RX7_RX_PATH_CTL, 0x04 }, - { MSM_SDW_RX7_RX_PATH_CFG0, 0x00 }, - { MSM_SDW_RX7_RX_PATH_CFG2, 0x8f }, - { MSM_SDW_RX7_RX_VOL_CTL, 0x00 }, - { MSM_SDW_RX7_RX_PATH_MIX_CTL, 0x04 }, - { MSM_SDW_RX7_RX_VOL_MIX_CTL, 0x00 }, - { MSM_SDW_RX7_RX_PATH_SEC2, 0x00 }, - { MSM_SDW_RX7_RX_PATH_SEC3, 0x00 }, - { MSM_SDW_RX7_RX_PATH_SEC5, 0x00 }, - { MSM_SDW_RX7_RX_PATH_SEC6, 0x00 }, - { MSM_SDW_RX7_RX_PATH_SEC7, 0x00 }, - { MSM_SDW_RX7_RX_PATH_MIX_SEC1, 0x00 }, - { MSM_SDW_RX8_RX_PATH_CTL, 0x04 }, - { MSM_SDW_RX8_RX_PATH_CFG0, 0x00 }, - { MSM_SDW_RX8_RX_PATH_CFG2, 0x8f }, - { MSM_SDW_RX8_RX_VOL_CTL, 0x00 }, - { MSM_SDW_RX8_RX_PATH_MIX_CTL, 0x04 }, - { MSM_SDW_RX8_RX_VOL_MIX_CTL, 0x00 }, - { MSM_SDW_RX8_RX_PATH_SEC2, 0x00 }, - { MSM_SDW_RX8_RX_PATH_SEC3, 0x00 }, - { MSM_SDW_RX8_RX_PATH_SEC5, 0x00 }, - { MSM_SDW_RX8_RX_PATH_SEC6, 0x00 }, - { MSM_SDW_RX8_RX_PATH_SEC7, 0x00 }, - { MSM_SDW_RX8_RX_PATH_MIX_SEC1, 0x00 }, - /* Page #12 registers */ - { MSM_SDW_BOOST0_BOOST_PATH_CTL, 0x00 }, - { MSM_SDW_BOOST0_BOOST_CTL, 0xb2 }, - { MSM_SDW_BOOST0_BOOST_CFG1, 0x00 }, - { MSM_SDW_BOOST0_BOOST_CFG2, 0x00 }, - { MSM_SDW_BOOST1_BOOST_PATH_CTL, 0x00 }, - { MSM_SDW_BOOST1_BOOST_CTL, 0xb2 }, - { MSM_SDW_BOOST1_BOOST_CFG1, 0x00 }, - { MSM_SDW_BOOST1_BOOST_CFG2, 0x00 }, - { MSM_SDW_AHB_BRIDGE_WR_DATA_0, 0x00 }, - { MSM_SDW_AHB_BRIDGE_WR_DATA_1, 0x00 }, - { MSM_SDW_AHB_BRIDGE_WR_DATA_2, 0x00 }, - { MSM_SDW_AHB_BRIDGE_WR_DATA_3, 0x00 }, - { MSM_SDW_AHB_BRIDGE_WR_ADDR_0, 0x00 }, - { MSM_SDW_AHB_BRIDGE_WR_ADDR_1, 0x00 }, - { MSM_SDW_AHB_BRIDGE_WR_ADDR_2, 0x00 }, - { MSM_SDW_AHB_BRIDGE_WR_ADDR_3, 0x00 }, - { MSM_SDW_AHB_BRIDGE_RD_ADDR_0, 0x00 }, - { MSM_SDW_AHB_BRIDGE_RD_ADDR_1, 0x00 }, - { MSM_SDW_AHB_BRIDGE_RD_ADDR_2, 0x00 }, - { MSM_SDW_AHB_BRIDGE_RD_ADDR_3, 0x00 }, - { MSM_SDW_AHB_BRIDGE_RD_DATA_0, 0x00 }, - { MSM_SDW_AHB_BRIDGE_RD_DATA_1, 0x00 }, - { MSM_SDW_AHB_BRIDGE_RD_DATA_2, 0x00 }, - { MSM_SDW_AHB_BRIDGE_RD_DATA_3, 0x00 }, - { MSM_SDW_AHB_BRIDGE_ACCESS_CFG, 0x0f }, - { MSM_SDW_AHB_BRIDGE_ACCESS_STATUS, 0x03 }, - /* Page #13 registers */ - { MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL, 0x00 }, - { MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00 }, - { MSM_SDW_CLK_RST_CTRL_SWR_CONTROL, 0x00 }, - { MSM_SDW_TOP_TOP_CFG0, 0x00 }, - { MSM_SDW_TOP_TOP_CFG1, 0x00 }, - { MSM_SDW_TOP_RX_I2S_CTL, 0x0C }, - { MSM_SDW_TOP_TX_I2S_CTL, 0x00 }, - { MSM_SDW_TOP_I2S_CLK, 0x00 }, - { MSM_SDW_TOP_RX7_PATH_INPUT0_MUX, 0x00 }, - { MSM_SDW_TOP_RX7_PATH_INPUT1_MUX, 0x00 }, - { MSM_SDW_TOP_RX8_PATH_INPUT0_MUX, 0x00 }, - { MSM_SDW_TOP_RX8_PATH_INPUT1_MUX, 0x00 }, - { MSM_SDW_TOP_FREQ_MCLK, 0x00 }, - { MSM_SDW_TOP_DEBUG_BUS_SEL, 0x00 }, - { MSM_SDW_TOP_DEBUG_EN, 0x00 }, - { MSM_SDW_TOP_I2S_RESET, 0x00 }, - { MSM_SDW_TOP_BLOCKS_RESET, 0x00 }, -}; - -static bool msm_sdw_is_readable_register(struct device *dev, unsigned int reg) -{ - return msm_sdw_reg_readable[reg]; -} - -static bool msm_sdw_is_writeable_register(struct device *dev, unsigned int reg) -{ - return msm_sdw_reg_writeable[reg]; -} - -static bool msm_sdw_is_volatile_register(struct device *dev, unsigned int reg) -{ - switch (reg) { - case MSM_SDW_AHB_BRIDGE_WR_DATA_0: - case MSM_SDW_AHB_BRIDGE_WR_DATA_1: - case MSM_SDW_AHB_BRIDGE_WR_DATA_2: - case MSM_SDW_AHB_BRIDGE_WR_DATA_3: - case MSM_SDW_AHB_BRIDGE_WR_ADDR_0: - case MSM_SDW_AHB_BRIDGE_WR_ADDR_1: - case MSM_SDW_AHB_BRIDGE_WR_ADDR_2: - case MSM_SDW_AHB_BRIDGE_WR_ADDR_3: - case MSM_SDW_AHB_BRIDGE_RD_DATA_0: - case MSM_SDW_AHB_BRIDGE_RD_DATA_1: - case MSM_SDW_AHB_BRIDGE_RD_DATA_2: - case MSM_SDW_AHB_BRIDGE_RD_DATA_3: - case MSM_SDW_AHB_BRIDGE_RD_ADDR_0: - case MSM_SDW_AHB_BRIDGE_RD_ADDR_1: - case MSM_SDW_AHB_BRIDGE_RD_ADDR_2: - case MSM_SDW_AHB_BRIDGE_RD_ADDR_3: - case MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL: - case MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL: - return true; - default: - return false; - } -} - -const struct regmap_config msm_sdw_regmap_config = { - .reg_bits = 16, - .val_bits = 8, - .reg_stride = 4, - .cache_type = REGCACHE_RBTREE, - .reg_defaults = msm_sdw_defaults, - .num_reg_defaults = ARRAY_SIZE(msm_sdw_defaults), - .max_register = MSM_SDW_MAX_REGISTER, - .writeable_reg = msm_sdw_is_writeable_register, - .volatile_reg = msm_sdw_is_volatile_register, - .readable_reg = msm_sdw_is_readable_register, -}; diff --git a/asoc/codecs/sdm660_cdc/Android.mk b/asoc/codecs/sdm660_cdc/Android.mk deleted file mode 100644 index 41f3cc7bc81f..000000000000 --- a/asoc/codecs/sdm660_cdc/Android.mk +++ /dev/null @@ -1,53 +0,0 @@ -# Android makefile for audio kernel modules - -# Assume no targets will be supported - -AUDIO_CHIPSET := audio -# Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) - -LOCAL_PATH := $(call my-dir) - -# This makefile is only for DLKM -ifneq ($(findstring vendor,$(LOCAL_PATH)),) - -ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel -endif # opensource - -DLKM_DIR := $(TOP)/device/qcom/common/dlkm - -# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko -########################################################### -# This is set once per LOCAL_PATH, not per (kernel) module -KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) - -# We are actually building audio.ko here, as per the -# requirement we are specifying _audio.ko as LOCAL_MODULE. -# This means we need to rename the module to _audio.ko -# after audio.ko is built. -KBUILD_OPTIONS += MODNAME=analog_cdc_dlkm -KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) -KBUILD_OPTIONS += $(AUDIO_SELECT) - -########################################################### -include $(CLEAR_VARS) -LOCAL_MODULE := $(AUDIO_CHIPSET)_analog_cdc.ko -LOCAL_MODULE_KBUILD_NAME := analog_cdc_dlkm.ko -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE_DEBUG_ENABLE := true -LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) -include $(DLKM_DIR)/AndroidKernelModule.mk -########################################################### -include $(CLEAR_VARS) -LOCAL_MODULE := $(AUDIO_CHIPSET)_digital_cdc.ko -LOCAL_MODULE_KBUILD_NAME := digital_cdc_dlkm.ko -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE_DEBUG_ENABLE := true -LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) -include $(DLKM_DIR)/AndroidKernelModule.mk -########################################################### -########################################################### - -endif # DLKM check -endif # supported target check diff --git a/asoc/codecs/sdm660_cdc/Kbuild b/asoc/codecs/sdm660_cdc/Kbuild deleted file mode 100644 index cbbc0c784493..000000000000 --- a/asoc/codecs/sdm660_cdc/Kbuild +++ /dev/null @@ -1,121 +0,0 @@ -# We can build either as part of a standalone Kernel build or as -# an external module. Determine which mechanism is being used -ifeq ($(MODNAME),) - KERNEL_BUILD := 1 -else - KERNEL_BUILD := 0 -endif - - -ifeq ($(KERNEL_BUILD), 1) - # These are configurable via Kconfig for kernel-based builds - # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.9 - AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio -endif - -ifeq ($(KERNEL_BUILD), 0) - ifeq ($(CONFIG_ARCH_SDM845), y) - include $(AUDIO_ROOT)/config/sdm845auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM670), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM450), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif -endif - -# As per target team, build is done as follows: -# Defconfig : build with default flags -# Slub : defconfig + CONFIG_SLUB_DEBUG := y + -# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y -# Perf : Using appropriate msmXXXX-perf_defconfig -# -# Shipment builds (user variants) should not have any debug feature -# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds -# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since -# there is no other way to identify defconfig builds, QTI internal -# representation of perf builds (identified using the string 'perf'), -# is used to identify if the build is a slub or defconfig one. This -# way no critical debug feature will be enabled for perf and shipment -# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT -# config. - -############ UAPI ############ -UAPI_DIR := uapi -UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) - -############ COMMON ############ -COMMON_DIR := include -COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) - -############ SDM660_CDC ############ - -# for SDM660_CDC Codec -ifdef CONFIG_SND_SOC_ANALOG_CDC - ANALOG_CDC_OBJS += msm-analog-cdc.o - ANALOG_CDC_OBJS += sdm660-cdc-irq.o -endif - -ifdef CONFIG_SND_SOC_DIGITAL_CDC - DIGITAL_CDC_OBJS += msm-digital-cdc.o - DIGITAL_CDC_OBJS += msm-digital-cdc-regmap.o -endif -LINUX_INC += -Iinclude/linux - -INCS += $(COMMON_INC) \ - $(UAPI_INC) - -EXTRA_CFLAGS += $(INCS) - - -CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ - -DANI_LITTLE_BIT_ENDIAN \ - -DDOT11F_LITTLE_ENDIAN_HOST \ - -DANI_COMPILER_TYPE_GCC \ - -DANI_OS_TYPE_ANDROID=6 \ - -DPTT_SOCK_SVC_ENABLE \ - -Wall\ - -Werror\ - -D__linux__ - -KBUILD_CPPFLAGS += $(CDEFINES) - -# Currently, for versions of gcc which support it, the kernel Makefile -# is disabling the maybe-uninitialized warning. Re-enable it for the -# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it -# will override the kernel settings. -ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) -EXTRA_CFLAGS += -Wmaybe-uninitialized -endif -#EXTRA_CFLAGS += -Wmissing-prototypes - -ifeq ($(call cc-option-yn, -Wheader-guard),y) -EXTRA_CFLAGS += -Wheader-guard -endif - - -ifeq ($(KERNEL_BUILD), 0) -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers -endif - -# Module information used by KBuild framework -obj-$(CONFIG_SND_SOC_ANALOG_CDC) += analog_cdc_dlkm.o -analog_cdc_dlkm-y := $(ANALOG_CDC_OBJS) - -obj-$(CONFIG_SND_SOC_DIGITAL_CDC) += digital_cdc_dlkm.o -digital_cdc_dlkm-y := $(DIGITAL_CDC_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc-regmap.h b/asoc/codecs/sdm660_cdc/msm-analog-cdc-regmap.h deleted file mode 100644 index 55846a1a20ca..000000000000 --- a/asoc/codecs/sdm660_cdc/msm-analog-cdc-regmap.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef ANALOG_CDC_REGMAP_H -#define ANALOG_CDC_REGMAP_H - -#include -#include "sdm660-cdc-registers.h" - -/* - * Default register reset values that are common across different versions - * are defined here. If a register reset value is changed based on version - * then remove it from this structure and add it in version specific - * structures. - */ - -struct reg_default - msm89xx_pmic_cdc_defaults[MSM89XX_PMIC_CDC_CACHE_SIZE] = { - {MSM89XX_PMIC_DIGITAL_REVISION1, 0x00}, - {MSM89XX_PMIC_DIGITAL_REVISION2, 0x00}, - {MSM89XX_PMIC_DIGITAL_PERPH_TYPE, 0x23}, - {MSM89XX_PMIC_DIGITAL_PERPH_SUBTYPE, 0x01}, - {MSM89XX_PMIC_DIGITAL_INT_RT_STS, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_SET_TYPE, 0xFF}, - {MSM89XX_PMIC_DIGITAL_INT_POLARITY_HIGH, 0xFF}, - {MSM89XX_PMIC_DIGITAL_INT_POLARITY_LOW, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_LATCHED_CLR, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_EN_SET, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_EN_CLR, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_LATCHED_STS, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_PENDING_STS, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_MID_SEL, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_PRIORITY, 0x00}, - {MSM89XX_PMIC_DIGITAL_GPIO_MODE, 0x00}, - {MSM89XX_PMIC_DIGITAL_PIN_CTL_OE, 0x01}, - {MSM89XX_PMIC_DIGITAL_PIN_CTL_DATA, 0x00}, - {MSM89XX_PMIC_DIGITAL_PIN_STATUS, 0x00}, - {MSM89XX_PMIC_DIGITAL_HDRIVE_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL, 0x02}, - {MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL, 0x02}, - {MSM89XX_PMIC_DIGITAL_CDC_CONN_HPHR_DAC_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX1_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX2_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX3_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX_LB_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_CDC_RX_CTL1, 0x7C}, - {MSM89XX_PMIC_DIGITAL_CDC_RX_CTL2, 0x7C}, - {MSM89XX_PMIC_DIGITAL_CDC_RX_CTL3, 0x7C}, - {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA0, 0x00}, - {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA1, 0x00}, - {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA2, 0x00}, - {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA3, 0x00}, - {MSM89XX_PMIC_DIGITAL_DIG_DEBUG_CTL, 0x00}, - {MSM89XX_PMIC_DIGITAL_DIG_DEBUG_EN, 0x00}, - {MSM89XX_PMIC_DIGITAL_SPARE_0, 0x00}, - {MSM89XX_PMIC_DIGITAL_SPARE_1, 0x00}, - {MSM89XX_PMIC_DIGITAL_SPARE_2, 0x00}, - {MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0x00}, - {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL1, 0x00}, - {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL2, 0x02}, - {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x05}, - {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_TEST1, 0x00}, - {MSM89XX_PMIC_DIGITAL_INT_TEST_VAL, 0x00}, - {MSM89XX_PMIC_DIGITAL_TRIM_NUM, 0x00}, - {MSM89XX_PMIC_DIGITAL_TRIM_CTRL, 0x00}, - {MSM89XX_PMIC_ANALOG_REVISION1, 0x00}, - {MSM89XX_PMIC_ANALOG_REVISION2, 0x00}, - {MSM89XX_PMIC_ANALOG_REVISION3, 0x00}, - {MSM89XX_PMIC_ANALOG_REVISION4, 0x00}, - {MSM89XX_PMIC_ANALOG_PERPH_TYPE, 0x23}, - {MSM89XX_PMIC_ANALOG_PERPH_SUBTYPE, 0x09}, - {MSM89XX_PMIC_ANALOG_INT_RT_STS, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_SET_TYPE, 0x3F}, - {MSM89XX_PMIC_ANALOG_INT_POLARITY_HIGH, 0x3F}, - {MSM89XX_PMIC_ANALOG_INT_POLARITY_LOW, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_LATCHED_CLR, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_EN_SET, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_EN_CLR, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_LATCHED_STS, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_PENDING_STS, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_MID_SEL, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_PRIORITY, 0x00}, - {MSM89XX_PMIC_ANALOG_MICB_1_EN, 0x00}, - {MSM89XX_PMIC_ANALOG_MICB_1_VAL, 0x20}, - {MSM89XX_PMIC_ANALOG_MICB_1_CTL, 0x00}, - {MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS, 0x49}, - {MSM89XX_PMIC_ANALOG_MICB_2_EN, 0x20}, - {MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2, 0x00}, - {MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, 0x00}, - {MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x35}, - {MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x08}, - {MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, 0x00}, - {MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, 0x98}, - {MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, 0x00}, - {MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL, 0x20}, - {MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL, 0x40}, - {MSM89XX_PMIC_ANALOG_MBHC_BTN3_CTL, 0x61}, - {MSM89XX_PMIC_ANALOG_MBHC_BTN4_CTL, 0x80}, - {MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT, 0x00}, - {MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x00}, - {MSM89XX_PMIC_ANALOG_TX_1_EN, 0x03}, - {MSM89XX_PMIC_ANALOG_TX_2_EN, 0x03}, - {MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_1, 0xBF}, - {MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_2, 0x8C}, - {MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL, 0x00}, - {MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x6B}, - {MSM89XX_PMIC_ANALOG_TX_1_2_TXFE_CLKDIV, 0x51}, - {MSM89XX_PMIC_ANALOG_TX_3_EN, 0x02}, - {MSM89XX_PMIC_ANALOG_NCP_EN, 0x26}, - {MSM89XX_PMIC_ANALOG_NCP_CLK, 0x23}, - {MSM89XX_PMIC_ANALOG_NCP_DEGLITCH, 0x5B}, - {MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0x08}, - {MSM89XX_PMIC_ANALOG_NCP_BIAS, 0x29}, - {MSM89XX_PMIC_ANALOG_NCP_VCTRL, 0x24}, - {MSM89XX_PMIC_ANALOG_NCP_TEST, 0x00}, - {MSM89XX_PMIC_ANALOG_NCP_CLIM_ADDR, 0xD5}, - {MSM89XX_PMIC_ANALOG_RX_CLOCK_DIVIDER, 0xE8}, - {MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL, 0xCF}, - {MSM89XX_PMIC_ANALOG_RX_COM_OCP_COUNT, 0x6E}, - {MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, 0x18}, - {MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA, 0x5A}, - {MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_LDO_OCP, 0x69}, - {MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_CNP, 0x29}, - {MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, 0x80}, - {MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_CTL, 0xDA}, - {MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME, 0x16}, - {MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x00}, - {MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x20}, - {MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x00}, - {MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x20}, - {MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x12}, - {MSM89XX_PMIC_ANALOG_RX_ATEST, 0x00}, - {MSM89XX_PMIC_ANALOG_RX_HPH_STATUS, 0x0C}, - {MSM89XX_PMIC_ANALOG_RX_EAR_STATUS, 0x00}, - {MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x00}, - {MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x00}, - {MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x83}, - {MSM89XX_PMIC_ANALOG_SPKR_DRV_CLIP_DET, 0x91}, - {MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x29}, - {MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET, 0x4D}, - {MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1}, - {MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0x1E}, - {MSM89XX_PMIC_ANALOG_SPKR_DRV_MISC, 0xCB}, - {MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x00}, - {MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x02}, - {MSM89XX_PMIC_ANALOG_OUTPUT_VOLTAGE, 0x14}, - {MSM89XX_PMIC_ANALOG_BYPASS_MODE, 0x00}, - {MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, 0x1F}, - {MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO, 0x8C}, - {MSM89XX_PMIC_ANALOG_RDSON_MAX_DUTY_CYCLE, 0xC0}, - {MSM89XX_PMIC_ANALOG_BOOST_TEST1_1, 0x00}, - {MSM89XX_PMIC_ANALOG_BOOST_TEST_2, 0x00}, - {MSM89XX_PMIC_ANALOG_SPKR_SAR_STATUS, 0x00}, - {MSM89XX_PMIC_ANALOG_SPKR_DRV_STATUS, 0x00}, - {MSM89XX_PMIC_ANALOG_PBUS_ADD_CSR, 0x00}, - {MSM89XX_PMIC_ANALOG_PBUS_ADD_SEL, 0x00}, - {MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0x00}, - {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL1, 0x00}, - {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL2, 0x01}, - {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x05}, - {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_TEST1, 0x00}, - {MSM89XX_PMIC_ANALOG_INT_TEST_VAL, 0x00}, - {MSM89XX_PMIC_ANALOG_TRIM_NUM, 0x04}, - {MSM89XX_PMIC_ANALOG_TRIM_CTRL1, 0x00}, - {MSM89XX_PMIC_ANALOG_TRIM_CTRL2, 0x00}, - {MSM89XX_PMIC_ANALOG_TRIM_CTRL3, 0x00}, - {MSM89XX_PMIC_ANALOG_TRIM_CTRL4, 0x00}, -}; - -#endif diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c deleted file mode 100644 index 64b99561b522..000000000000 --- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c +++ /dev/null @@ -1,4665 +0,0 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "msm-analog-cdc.h" -#include "msm-cdc-common.h" -#include "sdm660-cdc-irq.h" -#include "msm-analog-cdc-regmap.h" -#include "../../sdm660-common.h" -#include "../wcd-mbhc-v2-api.h" - -#define DRV_NAME "pmic_analog_codec" -#define SDM660_CDC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ - SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\ - SNDRV_PCM_RATE_192000) -#define SDM660_CDC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE) -#define MSM_DIG_CDC_STRING_LEN 80 -#define MSM_ANLG_CDC_VERSION_ENTRY_SIZE 32 - -#define CODEC_DT_MAX_PROP_SIZE 40 -#define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64 -#define BUS_DOWN 1 - -/* - * 200 Milliseconds sufficient for DSP bring up in the lpass - * after Sub System Restart - */ -#define ADSP_STATE_READY_TIMEOUT_MS 200 - -#define EAR_PMD 0 -#define EAR_PMU 1 -#define SPK_PMD 2 -#define SPK_PMU 3 - -#define MICBIAS_DEFAULT_VAL 1800000 -#define MICBIAS_MIN_VAL 1600000 -#define MICBIAS_STEP_SIZE 50000 - -#define DEFAULT_BOOST_VOLTAGE 5000 -#define MIN_BOOST_VOLTAGE 4000 -#define MAX_BOOST_VOLTAGE 5550 -#define BOOST_VOLTAGE_STEP 50 - -#define SDM660_CDC_MBHC_BTN_COARSE_ADJ 100 /* in mV */ -#define SDM660_CDC_MBHC_BTN_FINE_ADJ 12 /* in mV */ - -#define VOLTAGE_CONVERTER(value, min_value, step_size)\ - ((value - min_value)/step_size) - -enum { - BOOST_SWITCH = 0, - BOOST_ALWAYS, - BYPASS_ALWAYS, - BOOST_ON_FOREVER, -}; - -static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); -static struct snd_soc_dai_driver msm_anlg_cdc_i2s_dai[]; -/* By default enable the internal speaker boost */ -static bool spkr_boost_en = true; - -static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = { - "cdc-vdd-mic-bias", -}; - -static struct wcd_mbhc_register - wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = { - WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN", - MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x80, 7, 0), - WCD_MBHC_REGISTER("WCD_MBHC_GND_DET_EN", - MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x40, 6, 0), - WCD_MBHC_REGISTER("WCD_MBHC_MECH_DETECTION_TYPE", - MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x20, 5, 0), - WCD_MBHC_REGISTER("WCD_MBHC_MIC_CLAMP_CTL", - MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x18, 3, 0), - WCD_MBHC_REGISTER("WCD_MBHC_ELECT_DETECTION_TYPE", - MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x01, 0, 0), - WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_CTRL", - MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0xC0, 6, 0), - WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL", - MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x20, 5, 0), - WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PLUG_TYPE", - MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x10, 4, 0), - WCD_MBHC_REGISTER("WCD_MBHC_GND_PLUG_TYPE", - MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x08, 3, 0), - WCD_MBHC_REGISTER("WCD_MBHC_SW_HPH_LP_100K_TO_GND", - MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x01, 0, 0), - WCD_MBHC_REGISTER("WCD_MBHC_ELECT_SCHMT_ISRC", - MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x06, 1, 0), - WCD_MBHC_REGISTER("WCD_MBHC_FSM_EN", - MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, 0x80, 7, 0), - WCD_MBHC_REGISTER("WCD_MBHC_INSREM_DBNC", - MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, 0xF0, 4, 0), - WCD_MBHC_REGISTER("WCD_MBHC_BTN_DBNC", - MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, 0x0C, 2, 0), - WCD_MBHC_REGISTER("WCD_MBHC_HS_VREF", - MSM89XX_PMIC_ANALOG_MBHC_BTN3_CTL, 0x03, 0, 0), - WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT", - MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x01, - 0, 0), - WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT", - MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x02, - 1, 0), - WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT", - MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x08, - 3, 0), - WCD_MBHC_REGISTER("WCD_MBHC_HPHR_SCHMT_RESULT", - MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x04, - 2, 0), - WCD_MBHC_REGISTER("WCD_MBHC_OCP_FSM_EN", - MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL, 0x10, 4, 0), - WCD_MBHC_REGISTER("WCD_MBHC_BTN_RESULT", - MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT, 0xFF, 0, 0), - WCD_MBHC_REGISTER("WCD_MBHC_BTN_ISRC_CTL", - MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, 0x70, 4, 0), - WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT", - MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0xFF, - 0, 0), - WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL", - MSM89XX_PMIC_ANALOG_MICB_2_EN, 0xC0, 6, 0), - WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME", - MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME, 0xFC, 2, 0), - WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN", - MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, 0x10, 4, 0), - WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PA_EN", - MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, 0x20, 5, 0), - WCD_MBHC_REGISTER("WCD_MBHC_HPH_PA_EN", - MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, 0x30, 4, 0), - WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE", - MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, - 0x10, 4, 0), - WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL", - MSM89XX_PMIC_ANALOG_MICB_2_EN, 0x20, 5, 0), - WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN", 0, 0, 0, 0), - WCD_MBHC_REGISTER("WCD_MBHC_FSM_STATUS", 0, 0, 0, 0), - WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL", 0, 0, 0, 0), -}; - -/* Multiply gain_adj and offset by 1000 and 100 to avoid float arithmetic */ -static const struct wcd_imped_i_ref imped_i_ref[] = { - {I_h4_UA, 8, 800, 9000, 10000}, - {I_pt5_UA, 10, 100, 990, 4600}, - {I_14_UA, 17, 14, 1050, 700}, - {I_l4_UA, 10, 4, 1165, 110}, - {I_1_UA, 0, 1, 1200, 65}, -}; - -static const struct wcd_mbhc_intr intr_ids = { - .mbhc_sw_intr = MSM89XX_IRQ_MBHC_HS_DET, - .mbhc_btn_press_intr = MSM89XX_IRQ_MBHC_PRESS, - .mbhc_btn_release_intr = MSM89XX_IRQ_MBHC_RELEASE, - .mbhc_hs_ins_intr = MSM89XX_IRQ_MBHC_INSREM_DET1, - .mbhc_hs_rem_intr = MSM89XX_IRQ_MBHC_INSREM_DET, - .hph_left_ocp = MSM89XX_IRQ_HPHL_OCP, - .hph_right_ocp = MSM89XX_IRQ_HPHR_OCP, -}; - -static int msm_anlg_cdc_dt_parse_vreg_info(struct device *dev, - struct sdm660_cdc_regulator *vreg, - const char *vreg_name, - bool ondemand); -static struct sdm660_cdc_pdata *msm_anlg_cdc_populate_dt_pdata( - struct device *dev); -static int msm_anlg_cdc_enable_ext_mb_source(struct wcd_mbhc *wcd_mbhc, - bool turn_on); -static void msm_anlg_cdc_trim_btn_reg(struct snd_soc_codec *codec); -static void msm_anlg_cdc_set_micb_v(struct snd_soc_codec *codec); -static void msm_anlg_cdc_set_boost_v(struct snd_soc_codec *codec); -static void msm_anlg_cdc_set_auto_zeroing(struct snd_soc_codec *codec, - bool enable); -static void msm_anlg_cdc_configure_cap(struct snd_soc_codec *codec, - bool micbias1, bool micbias2); -static bool msm_anlg_cdc_use_mb(struct snd_soc_codec *codec); - -static int get_codec_version(struct sdm660_cdc_priv *sdm660_cdc) -{ - if (sdm660_cdc->codec_version == DRAX_CDC) - return DRAX_CDC; - else if (sdm660_cdc->codec_version == DIANGU) - return DIANGU; - else if (sdm660_cdc->codec_version == CAJON_2_0) - return CAJON_2_0; - else if (sdm660_cdc->codec_version == CAJON) - return CAJON; - else if (sdm660_cdc->codec_version == CONGA) - return CONGA; - else if (sdm660_cdc->pmic_rev == TOMBAK_2_0) - return TOMBAK_2_0; - else if (sdm660_cdc->pmic_rev == TOMBAK_1_0) - return TOMBAK_1_0; - - pr_err("%s: unsupported codec version\n", __func__); - return UNSUPPORTED; -} - -static void wcd_mbhc_meas_imped(struct snd_soc_codec *codec, - s16 *impedance_l, s16 *impedance_r) -{ - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - if ((sdm660_cdc->imped_det_pin == WCD_MBHC_DET_BOTH) || - (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHL)) { - /* Enable ZDET_L_MEAS_EN */ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, - 0x08, 0x08); - /* Wait for 2ms for measurement to complete */ - usleep_range(2000, 2100); - /* Read Left impedance value from Result1 */ - *impedance_l = snd_soc_read(codec, - MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT); - /* Enable ZDET_R_MEAS_EN */ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, - 0x08, 0x00); - } - if ((sdm660_cdc->imped_det_pin == WCD_MBHC_DET_BOTH) || - (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHR)) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, - 0x04, 0x04); - /* Wait for 2ms for measurement to complete */ - usleep_range(2000, 2100); - /* Read Right impedance value from Result1 */ - *impedance_r = snd_soc_read(codec, - MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, - 0x04, 0x00); - } -} - -static void msm_anlg_cdc_set_ref_current(struct snd_soc_codec *codec, - enum wcd_curr_ref curr_ref) -{ - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: curr_ref: %d\n", __func__, curr_ref); - - if (get_codec_version(sdm660_cdc) < CAJON) - dev_dbg(codec->dev, "%s: Setting ref current not required\n", - __func__); - - sdm660_cdc->imped_i_ref = imped_i_ref[curr_ref]; - - switch (curr_ref) { - case I_h4_UA: - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MICB_2_EN, - 0x07, 0x01); - break; - case I_pt5_UA: - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MICB_2_EN, - 0x07, 0x04); - break; - case I_14_UA: - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MICB_2_EN, - 0x07, 0x03); - break; - case I_l4_UA: - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MICB_2_EN, - 0x07, 0x01); - break; - case I_1_UA: - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MICB_2_EN, - 0x07, 0x00); - break; - default: - pr_debug("%s: No ref current set\n", __func__); - break; - } -} - -static bool msm_anlg_cdc_adj_ref_current(struct snd_soc_codec *codec, - s16 *impedance_l, s16 *impedance_r) -{ - int i = 2; - s16 compare_imp = 0; - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHR) - compare_imp = *impedance_r; - else - compare_imp = *impedance_l; - - if (get_codec_version(sdm660_cdc) < CAJON) { - dev_dbg(codec->dev, - "%s: Reference current adjustment not required\n", - __func__); - return false; - } - - while (compare_imp < imped_i_ref[i].min_val) { - msm_anlg_cdc_set_ref_current(codec, imped_i_ref[++i].curr_ref); - wcd_mbhc_meas_imped(codec, impedance_l, impedance_r); - compare_imp = (sdm660_cdc->imped_det_pin == - WCD_MBHC_DET_HPHR) ? *impedance_r : *impedance_l; - if (i >= I_1_UA) - break; - } - return true; -} - -void msm_anlg_cdc_spk_ext_pa_cb( - int (*codec_spk_ext_pa)(struct snd_soc_codec *codec, - int enable), struct snd_soc_codec *codec) -{ - struct sdm660_cdc_priv *sdm660_cdc; - - if (!codec) { - pr_err("%s: NULL codec pointer!\n", __func__); - return; - } - - sdm660_cdc = snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: Enter\n", __func__); - sdm660_cdc->codec_spk_ext_pa_cb = codec_spk_ext_pa; -} -EXPORT_SYMBOL(msm_anlg_cdc_spk_ext_pa_cb); - -static void msm_anlg_cdc_compute_impedance(struct snd_soc_codec *codec, s16 l, - s16 r, uint32_t *zl, uint32_t *zr, - bool high) -{ - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - uint32_t rl = 0, rr = 0; - struct wcd_imped_i_ref R = sdm660_cdc->imped_i_ref; - int codec_ver = get_codec_version(sdm660_cdc); - - switch (codec_ver) { - case TOMBAK_1_0: - case TOMBAK_2_0: - case CONGA: - if (high) { - dev_dbg(codec->dev, - "%s: This plug has high range impedance\n", - __func__); - rl = (uint32_t)(((100 * (l * 400 - 200))/96) - 230); - rr = (uint32_t)(((100 * (r * 400 - 200))/96) - 230); - } else { - dev_dbg(codec->dev, - "%s: This plug has low range impedance\n", - __func__); - rl = (uint32_t)(((1000 * (l * 2 - 1))/1165) - (13/10)); - rr = (uint32_t)(((1000 * (r * 2 - 1))/1165) - (13/10)); - } - break; - case CAJON: - case CAJON_2_0: - case DIANGU: - case DRAX_CDC: - if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHL) { - rr = (uint32_t)(((DEFAULT_MULTIPLIER * (10 * r - 5)) - - (DEFAULT_OFFSET * DEFAULT_GAIN))/DEFAULT_GAIN); - rl = (uint32_t)(((10000 * (R.multiplier * (10 * l - 5))) - - R.offset * R.gain_adj)/(R.gain_adj * 100)); - } else if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHR) { - rr = (uint32_t)(((10000 * (R.multiplier * (10 * r - 5))) - - R.offset * R.gain_adj)/(R.gain_adj * 100)); - rl = (uint32_t)(((DEFAULT_MULTIPLIER * (10 * l - 5))- - (DEFAULT_OFFSET * DEFAULT_GAIN))/DEFAULT_GAIN); - } else if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_NONE) { - rr = (uint32_t)(((DEFAULT_MULTIPLIER * (10 * r - 5)) - - (DEFAULT_OFFSET * DEFAULT_GAIN))/DEFAULT_GAIN); - rl = (uint32_t)(((DEFAULT_MULTIPLIER * (10 * l - 5))- - (DEFAULT_OFFSET * DEFAULT_GAIN))/DEFAULT_GAIN); - } else { - rr = (uint32_t)(((10000 * (R.multiplier * (10 * r - 5))) - - R.offset * R.gain_adj)/(R.gain_adj * 100)); - rl = (uint32_t)(((10000 * (R.multiplier * (10 * l - 5))) - - R.offset * R.gain_adj)/(R.gain_adj * 100)); - } - break; - default: - dev_dbg(codec->dev, "%s: No codec mentioned\n", __func__); - break; - } - *zl = rl; - *zr = rr; -} - -static struct firmware_cal *msm_anlg_cdc_get_hwdep_fw_cal( - struct wcd_mbhc *wcd_mbhc, - enum wcd_cal_type type) -{ - struct sdm660_cdc_priv *sdm660_cdc; - struct firmware_cal *hwdep_cal; - struct snd_soc_codec *codec = wcd_mbhc->codec; - - if (!codec) { - pr_err("%s: NULL codec pointer\n", __func__); - return NULL; - } - sdm660_cdc = snd_soc_codec_get_drvdata(codec); - hwdep_cal = wcdcal_get_fw_cal(sdm660_cdc->fw_data, type); - if (!hwdep_cal) { - dev_err(codec->dev, "%s: cal not sent by %d\n", - __func__, type); - return NULL; - } - return hwdep_cal; -} - -static void wcd9xxx_spmi_irq_control(struct snd_soc_codec *codec, - int irq, bool enable) -{ - if (enable) - wcd9xxx_spmi_enable_irq(irq); - else - wcd9xxx_spmi_disable_irq(irq); -} - -static void msm_anlg_cdc_mbhc_clk_setup(struct snd_soc_codec *codec, - bool enable) -{ - if (enable) - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0x08, 0x08); - else - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0x08, 0x00); -} - -static int msm_anlg_cdc_mbhc_map_btn_code_to_num(struct snd_soc_codec *codec) -{ - int btn_code; - int btn; - - btn_code = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT); - - switch (btn_code) { - case 0: - btn = 0; - break; - case 1: - btn = 1; - break; - case 3: - btn = 2; - break; - case 7: - btn = 3; - break; - case 15: - btn = 4; - break; - default: - btn = -EINVAL; - break; - }; - - return btn; -} - -static bool msm_anlg_cdc_spmi_lock_sleep(struct wcd_mbhc *mbhc, bool lock) -{ - if (lock) - return wcd9xxx_spmi_lock_sleep(); - wcd9xxx_spmi_unlock_sleep(); - return 0; -} - -static bool msm_anlg_cdc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) -{ - if (micb_num == MIC_BIAS_1) - return (snd_soc_read(mbhc->codec, - MSM89XX_PMIC_ANALOG_MICB_1_EN) & - 0x80); - if (micb_num == MIC_BIAS_2) - return (snd_soc_read(mbhc->codec, - MSM89XX_PMIC_ANALOG_MICB_2_EN) & - 0x80); - return false; -} - -static void msm_anlg_cdc_enable_master_bias(struct snd_soc_codec *codec, - bool enable) -{ - if (enable) - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, - 0x30, 0x30); - else - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, - 0x30, 0x00); -} - -static void msm_anlg_cdc_mbhc_common_micb_ctrl(struct snd_soc_codec *codec, - int event, bool enable) -{ - u16 reg; - u8 mask; - u8 val; - - switch (event) { - case MBHC_COMMON_MICB_PRECHARGE: - reg = MSM89XX_PMIC_ANALOG_MICB_1_CTL; - mask = 0x60; - val = (enable ? 0x60 : 0x00); - break; - case MBHC_COMMON_MICB_SET_VAL: - reg = MSM89XX_PMIC_ANALOG_MICB_1_VAL; - mask = 0xFF; - val = (enable ? 0xC0 : 0x00); - break; - case MBHC_COMMON_MICB_TAIL_CURR: - reg = MSM89XX_PMIC_ANALOG_MICB_1_EN; - mask = 0x04; - val = (enable ? 0x04 : 0x00); - break; - default: - dev_err(codec->dev, - "%s: Invalid event received\n", __func__); - return; - }; - snd_soc_update_bits(codec, reg, mask, val); -} - -static void msm_anlg_cdc_mbhc_internal_micbias_ctrl(struct snd_soc_codec *codec, - int micbias_num, - bool enable) -{ - if (micbias_num == 1) { - if (enable) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS, - 0x10, 0x10); - else - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS, - 0x10, 0x00); - } -} - -static bool msm_anlg_cdc_mbhc_hph_pa_on_status(struct snd_soc_codec *codec) -{ - return (snd_soc_read(codec, MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN) & - 0x30) ? true : false; -} - -static void msm_anlg_cdc_mbhc_program_btn_thr(struct snd_soc_codec *codec, - s16 *btn_low, s16 *btn_high, - int num_btn, bool is_micbias) -{ - int i; - u32 course, fine, reg_val; - u16 reg_addr = MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL; - s16 *btn_voltage; - - btn_voltage = ((is_micbias) ? btn_high : btn_low); - - for (i = 0; i < num_btn; i++) { - course = (btn_voltage[i] / SDM660_CDC_MBHC_BTN_COARSE_ADJ); - fine = ((btn_voltage[i] % SDM660_CDC_MBHC_BTN_COARSE_ADJ) / - SDM660_CDC_MBHC_BTN_FINE_ADJ); - - reg_val = (course << 5) | (fine << 2); - snd_soc_update_bits(codec, reg_addr, 0xFC, reg_val); - dev_dbg(codec->dev, - "%s: course: %d fine: %d reg_addr: %x reg_val: %x\n", - __func__, course, fine, reg_addr, reg_val); - reg_addr++; - } -} - -static void msm_anlg_cdc_mbhc_calc_impedance(struct wcd_mbhc *mbhc, - uint32_t *zl, uint32_t *zr) -{ - struct snd_soc_codec *codec = mbhc->codec; - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - s16 impedance_l, impedance_r; - s16 impedance_l_fixed; - s16 reg0, reg1, reg2, reg3, reg4; - bool high = false; - bool min_range_used = false; - - WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); - reg0 = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER); - reg1 = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL); - reg2 = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2); - reg3 = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MICB_2_EN); - reg4 = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL); - - sdm660_cdc->imped_det_pin = WCD_MBHC_DET_BOTH; - mbhc->hph_type = WCD_MBHC_HPH_NONE; - - /* disable FSM and micbias and enable pullup*/ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, - 0x80, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MICB_2_EN, - 0xA5, 0x25); - /* - * Enable legacy electrical detection current sources - * and disable fast ramp and enable manual switching - * of extra capacitance - */ - dev_dbg(codec->dev, "%s: Setup for impedance det\n", __func__); - - msm_anlg_cdc_set_ref_current(codec, I_h4_UA); - - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, - 0x06, 0x02); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, - 0x02, 0x02); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL, - 0x02, 0x00); - - dev_dbg(codec->dev, "%s: Start performing impedance detection\n", - __func__); - - wcd_mbhc_meas_imped(codec, &impedance_l, &impedance_r); - - if (impedance_l > 2 || impedance_r > 2) { - high = true; - if (!mbhc->mbhc_cfg->mono_stero_detection) { - /* Set ZDET_CHG to 0 to discharge ramp */ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, - 0x02, 0x00); - /* wait 40ms for the discharge ramp to complete */ - usleep_range(40000, 40100); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, - 0x03, 0x00); - sdm660_cdc->imped_det_pin = (impedance_l > 2 && - impedance_r > 2) ? - WCD_MBHC_DET_NONE : - ((impedance_l > 2) ? - WCD_MBHC_DET_HPHR : - WCD_MBHC_DET_HPHL); - if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_NONE) - goto exit; - } else { - if (get_codec_version(sdm660_cdc) >= CAJON) { - if (impedance_l == 63 && impedance_r == 63) { - dev_dbg(codec->dev, - "%s: HPHL and HPHR are floating\n", - __func__); - sdm660_cdc->imped_det_pin = - WCD_MBHC_DET_NONE; - mbhc->hph_type = WCD_MBHC_HPH_NONE; - } else if (impedance_l == 63 - && impedance_r < 63) { - dev_dbg(codec->dev, - "%s: Mono HS with HPHL floating\n", - __func__); - sdm660_cdc->imped_det_pin = - WCD_MBHC_DET_HPHR; - mbhc->hph_type = WCD_MBHC_HPH_MONO; - } else if (impedance_r == 63 && - impedance_l < 63) { - dev_dbg(codec->dev, - "%s: Mono HS with HPHR floating\n", - __func__); - sdm660_cdc->imped_det_pin = - WCD_MBHC_DET_HPHL; - mbhc->hph_type = WCD_MBHC_HPH_MONO; - } else if (impedance_l > 3 && impedance_r > 3 && - (impedance_l == impedance_r)) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, - 0x06, 0x06); - wcd_mbhc_meas_imped(codec, &impedance_l, - &impedance_r); - if (impedance_r == impedance_l) - dev_dbg(codec->dev, - "%s: Mono Headset\n", - __func__); - sdm660_cdc->imped_det_pin = - WCD_MBHC_DET_NONE; - mbhc->hph_type = - WCD_MBHC_HPH_MONO; - } else { - dev_dbg(codec->dev, - "%s: STEREO headset is found\n", - __func__); - sdm660_cdc->imped_det_pin = - WCD_MBHC_DET_BOTH; - mbhc->hph_type = WCD_MBHC_HPH_STEREO; - } - } - } - } - - msm_anlg_cdc_set_ref_current(codec, I_pt5_UA); - msm_anlg_cdc_set_ref_current(codec, I_14_UA); - - /* Enable RAMP_L , RAMP_R & ZDET_CHG*/ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, - 0x03, 0x03); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, - 0x02, 0x02); - /* wait for 50msec for the HW to apply ramp on HPHL and HPHR */ - usleep_range(50000, 50100); - /* Enable ZDET_DISCHG_CAP_CTL to add extra capacitance */ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, - 0x01, 0x01); - /* wait for 5msec for the voltage to get stable */ - usleep_range(5000, 5100); - - wcd_mbhc_meas_imped(codec, &impedance_l, &impedance_r); - - min_range_used = msm_anlg_cdc_adj_ref_current(codec, - &impedance_l, &impedance_r); - if (!mbhc->mbhc_cfg->mono_stero_detection) { - /* Set ZDET_CHG to 0 to discharge ramp */ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, - 0x02, 0x00); - /* wait for 40msec for the capacitor to discharge */ - usleep_range(40000, 40100); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, - 0x03, 0x00); - goto exit; - } - - /* we are setting ref current to the minimun range or the measured - * value larger than the minimum value, so min_range_used is true. - * If the headset is mono headset with either HPHL or HPHR floating - * then we have already done the mono stereo detection and do not - * need to continue further. - */ - - if (!min_range_used || - sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHL || - sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHR) - goto exit; - - - /* Disable Set ZDET_CONN_RAMP_L and enable ZDET_CONN_FIXED_L */ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, - 0x02, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL, - 0x02, 0x02); - /* Set ZDET_CHG to 0 */ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, - 0x02, 0x00); - /* wait for 40msec for the capacitor to discharge */ - usleep_range(40000, 40100); - - /* Set ZDET_CONN_RAMP_R to 0 */ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, - 0x01, 0x00); - /* Enable ZDET_L_MEAS_EN */ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, - 0x08, 0x08); - /* wait for 2msec for the HW to compute left inpedance value */ - usleep_range(2000, 2100); - /* Read Left impedance value from Result1 */ - impedance_l_fixed = snd_soc_read(codec, - MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT); - /* Disable ZDET_L_MEAS_EN */ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, - 0x08, 0x00); - /* - * Assume impedance_l is L1, impedance_l_fixed is L2. - * If the following condition is met, we can take this - * headset as mono one with impedance of L2. - * Otherwise, take it as stereo with impedance of L1. - * Condition: - * abs[(L2-0.5L1)/(L2+0.5L1)] < abs [(L2-L1)/(L2+L1)] - */ - if ((abs(impedance_l_fixed - impedance_l/2) * - (impedance_l_fixed + impedance_l)) >= - (abs(impedance_l_fixed - impedance_l) * - (impedance_l_fixed + impedance_l/2))) { - dev_dbg(codec->dev, - "%s: STEREO plug type detected\n", - __func__); - mbhc->hph_type = WCD_MBHC_HPH_STEREO; - } else { - dev_dbg(codec->dev, - "%s: MONO plug type detected\n", - __func__); - mbhc->hph_type = WCD_MBHC_HPH_MONO; - impedance_l = impedance_l_fixed; - } - /* Enable ZDET_CHG */ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, - 0x02, 0x02); - /* wait for 10msec for the capacitor to charge */ - usleep_range(10000, 10100); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, - 0x02, 0x02); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL, - 0x02, 0x00); - /* Set ZDET_CHG to 0 to discharge HPHL */ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, - 0x02, 0x00); - /* wait for 40msec for the capacitor to discharge */ - usleep_range(40000, 40100); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, - 0x02, 0x00); - -exit: - snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, reg4); - snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MICB_2_EN, reg3); - snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL, reg1); - snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, reg0); - snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, reg2); - msm_anlg_cdc_compute_impedance(codec, impedance_l, impedance_r, - zl, zr, high); - - dev_dbg(codec->dev, "%s: RL %d ohm, RR %d ohm\n", __func__, *zl, *zr); - dev_dbg(codec->dev, "%s: Impedance detection completed\n", __func__); -} - -static int msm_anlg_cdc_dig_register_notifier(void *handle, - struct notifier_block *nblock, - bool enable) -{ - struct sdm660_cdc_priv *handle_cdc = handle; - - if (enable) - return blocking_notifier_chain_register(&handle_cdc->notifier, - nblock); - - return blocking_notifier_chain_unregister(&handle_cdc->notifier, - nblock); -} - -static int msm_anlg_cdc_mbhc_register_notifier(struct wcd_mbhc *wcd_mbhc, - struct notifier_block *nblock, - bool enable) -{ - struct snd_soc_codec *codec = wcd_mbhc->codec; - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - if (enable) - return blocking_notifier_chain_register( - &sdm660_cdc->notifier_mbhc, - nblock); - - return blocking_notifier_chain_unregister(&sdm660_cdc->notifier_mbhc, - nblock); -} - -static int msm_anlg_cdc_request_irq(struct snd_soc_codec *codec, - int irq, irq_handler_t handler, - const char *name, void *data) -{ - return wcd9xxx_spmi_request_irq(irq, handler, name, data); -} - -static int msm_anlg_cdc_free_irq(struct snd_soc_codec *codec, - int irq, void *data) -{ - return wcd9xxx_spmi_free_irq(irq, data); -} - -static const struct wcd_mbhc_cb mbhc_cb = { - .enable_mb_source = msm_anlg_cdc_enable_ext_mb_source, - .trim_btn_reg = msm_anlg_cdc_trim_btn_reg, - .compute_impedance = msm_anlg_cdc_mbhc_calc_impedance, - .set_micbias_value = msm_anlg_cdc_set_micb_v, - .set_auto_zeroing = msm_anlg_cdc_set_auto_zeroing, - .get_hwdep_fw_cal = msm_anlg_cdc_get_hwdep_fw_cal, - .set_cap_mode = msm_anlg_cdc_configure_cap, - .register_notifier = msm_anlg_cdc_mbhc_register_notifier, - .request_irq = msm_anlg_cdc_request_irq, - .irq_control = wcd9xxx_spmi_irq_control, - .free_irq = msm_anlg_cdc_free_irq, - .clk_setup = msm_anlg_cdc_mbhc_clk_setup, - .map_btn_code_to_num = msm_anlg_cdc_mbhc_map_btn_code_to_num, - .lock_sleep = msm_anlg_cdc_spmi_lock_sleep, - .micbias_enable_status = msm_anlg_cdc_micb_en_status, - .mbhc_bias = msm_anlg_cdc_enable_master_bias, - .mbhc_common_micb_ctrl = msm_anlg_cdc_mbhc_common_micb_ctrl, - .micb_internal = msm_anlg_cdc_mbhc_internal_micbias_ctrl, - .hph_pa_on_status = msm_anlg_cdc_mbhc_hph_pa_on_status, - .set_btn_thr = msm_anlg_cdc_mbhc_program_btn_thr, - .extn_use_mb = msm_anlg_cdc_use_mb, -}; - -static const uint32_t wcd_imped_val[] = {4, 8, 12, 13, 16, - 20, 24, 28, 32, - 36, 40, 44, 48}; - -static void msm_anlg_cdc_dig_notifier_call(struct snd_soc_codec *codec, - const enum dig_cdc_notify_event event) -{ - struct sdm660_cdc_priv *sdm660_cdc = snd_soc_codec_get_drvdata(codec); - - pr_debug("%s: notifier call event %d\n", __func__, event); - blocking_notifier_call_chain(&sdm660_cdc->notifier, - event, NULL); -} - -static void msm_anlg_cdc_notifier_call(struct snd_soc_codec *codec, - const enum wcd_notify_event event) -{ - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: notifier call event %d\n", __func__, event); - blocking_notifier_call_chain(&sdm660_cdc->notifier_mbhc, event, - &sdm660_cdc->mbhc); -} - -static void msm_anlg_cdc_boost_on(struct snd_soc_codec *codec) -{ - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x0F, 0x0F); - snd_soc_write(codec, MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0xA5); - snd_soc_write(codec, MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x0F); - snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, 0x30); - if (get_codec_version(sdm660_cdc) < CAJON_2_0) - snd_soc_write(codec, MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x82); - else - snd_soc_write(codec, MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0xA2); - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, - 0x69, 0x69); - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, - 0x01, 0x01); - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO, - 0x88, 0x88); - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, - 0x03, 0x03); - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, - 0xE1, 0xE1); - if (get_codec_version(sdm660_cdc) < CAJON_2_0) { - snd_soc_update_bits(codec, MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0x20, 0x20); - /* Wait for 1ms after clock ctl enable */ - usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, - 0xDF, 0xDF); - usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); - } else { - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, - 0x40, 0x00); - snd_soc_update_bits(codec, MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0x20, 0x20); - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, - 0x80, 0x80); - /* Wait for 500us after BOOST_EN to happen */ - usleep_range(500, 510); - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, - 0x40, 0x40); - /* Wait for 500us after BOOST pulse_skip */ - usleep_range(500, 510); - } -} - -static void msm_anlg_cdc_boost_off(struct snd_soc_codec *codec) -{ - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, - 0xDF, 0x5F); - snd_soc_update_bits(codec, MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0x20, 0x00); -} - -static void msm_anlg_cdc_bypass_on(struct snd_soc_codec *codec) -{ - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - if (get_codec_version(sdm660_cdc) < CAJON_2_0) { - snd_soc_write(codec, - MSM89XX_PMIC_ANALOG_SEC_ACCESS, - 0xA5); - snd_soc_write(codec, - MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, - 0x07); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_BYPASS_MODE, - 0x02, 0x02); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_BYPASS_MODE, - 0x01, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_BYPASS_MODE, - 0x40, 0x40); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_BYPASS_MODE, - 0x80, 0x80); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, - 0xDF, 0xDF); - } else { - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0x20, 0x20); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_BYPASS_MODE, - 0x20, 0x20); - } -} - -static void msm_anlg_cdc_bypass_off(struct snd_soc_codec *codec) -{ - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - if (get_codec_version(sdm660_cdc) < CAJON_2_0) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, - 0x80, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_BYPASS_MODE, - 0x80, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_BYPASS_MODE, - 0x02, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_BYPASS_MODE, - 0x40, 0x00); - } else { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_BYPASS_MODE, - 0x20, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0x20, 0x00); - } -} - -static void msm_anlg_cdc_boost_mode_sequence(struct snd_soc_codec *codec, - int flag) -{ - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - if (flag == EAR_PMU) { - switch (sdm660_cdc->boost_option) { - case BOOST_SWITCH: - if (sdm660_cdc->ear_pa_boost_set) { - msm_anlg_cdc_boost_off(codec); - msm_anlg_cdc_bypass_on(codec); - } - break; - case BOOST_ALWAYS: - msm_anlg_cdc_boost_on(codec); - break; - case BYPASS_ALWAYS: - msm_anlg_cdc_bypass_on(codec); - break; - case BOOST_ON_FOREVER: - msm_anlg_cdc_boost_on(codec); - break; - default: - dev_err(codec->dev, - "%s: invalid boost option: %d\n", __func__, - sdm660_cdc->boost_option); - break; - } - } else if (flag == EAR_PMD) { - switch (sdm660_cdc->boost_option) { - case BOOST_SWITCH: - if (sdm660_cdc->ear_pa_boost_set) - msm_anlg_cdc_bypass_off(codec); - break; - case BOOST_ALWAYS: - msm_anlg_cdc_boost_off(codec); - /* 80ms for EAR boost to settle down */ - msleep(80); - break; - case BYPASS_ALWAYS: - /* nothing to do as bypass on always */ - break; - case BOOST_ON_FOREVER: - /* nothing to do as boost on forever */ - break; - default: - dev_err(codec->dev, - "%s: invalid boost option: %d\n", __func__, - sdm660_cdc->boost_option); - break; - } - } else if (flag == SPK_PMU) { - switch (sdm660_cdc->boost_option) { - case BOOST_SWITCH: - if (sdm660_cdc->spk_boost_set) { - msm_anlg_cdc_bypass_off(codec); - msm_anlg_cdc_boost_on(codec); - } - break; - case BOOST_ALWAYS: - msm_anlg_cdc_boost_on(codec); - break; - case BYPASS_ALWAYS: - msm_anlg_cdc_bypass_on(codec); - break; - case BOOST_ON_FOREVER: - msm_anlg_cdc_boost_on(codec); - break; - default: - dev_err(codec->dev, - "%s: invalid boost option: %d\n", __func__, - sdm660_cdc->boost_option); - break; - } - } else if (flag == SPK_PMD) { - switch (sdm660_cdc->boost_option) { - case BOOST_SWITCH: - if (sdm660_cdc->spk_boost_set) { - msm_anlg_cdc_boost_off(codec); - /* - * Add 40 ms sleep for the spk - * boost to settle down - */ - msleep(40); - } - break; - case BOOST_ALWAYS: - msm_anlg_cdc_boost_off(codec); - /* - * Add 40 ms sleep for the spk - * boost to settle down - */ - msleep(40); - break; - case BYPASS_ALWAYS: - /* nothing to do as bypass on always */ - break; - case BOOST_ON_FOREVER: - /* nothing to do as boost on forever */ - break; - default: - dev_err(codec->dev, - "%s: invalid boost option: %d\n", __func__, - sdm660_cdc->boost_option); - break; - } - } -} - -static int msm_anlg_cdc_dt_parse_vreg_info(struct device *dev, - struct sdm660_cdc_regulator *vreg, const char *vreg_name, - bool ondemand) -{ - int len, ret = 0; - const __be32 *prop; - char prop_name[CODEC_DT_MAX_PROP_SIZE]; - struct device_node *regnode = NULL; - u32 prop_val; - - snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "%s-supply", - vreg_name); - regnode = of_parse_phandle(dev->of_node, prop_name, 0); - - if (!regnode) { - dev_err(dev, "Looking up %s property in node %s failed\n", - prop_name, dev->of_node->full_name); - return -ENODEV; - } - - dev_dbg(dev, "Looking up %s property in node %s\n", - prop_name, dev->of_node->full_name); - - vreg->name = vreg_name; - vreg->ondemand = ondemand; - - snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, - "qcom,%s-voltage", vreg_name); - prop = of_get_property(dev->of_node, prop_name, &len); - - if (!prop || (len != (2 * sizeof(__be32)))) { - dev_err(dev, "%s %s property\n", - prop ? "invalid format" : "no", prop_name); - return -EINVAL; - } - vreg->min_uv = be32_to_cpup(&prop[0]); - vreg->max_uv = be32_to_cpup(&prop[1]); - - snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, - "qcom,%s-current", vreg_name); - - ret = of_property_read_u32(dev->of_node, prop_name, &prop_val); - if (ret) { - dev_err(dev, "Looking up %s property in node %s failed", - prop_name, dev->of_node->full_name); - return -EFAULT; - } - vreg->optimum_ua = prop_val; - - dev_dbg(dev, "%s: vol=[%d %d]uV, curr=[%d]uA, ond %d\n\n", vreg->name, - vreg->min_uv, vreg->max_uv, vreg->optimum_ua, vreg->ondemand); - return 0; -} - -static void msm_anlg_cdc_dt_parse_boost_info(struct snd_soc_codec *codec) -{ - struct sdm660_cdc_priv *sdm660_cdc_priv = - snd_soc_codec_get_drvdata(codec); - const char *prop_name = "qcom,cdc-boost-voltage"; - int boost_voltage, ret; - - ret = of_property_read_u32(codec->dev->of_node, prop_name, - &boost_voltage); - if (ret) { - dev_dbg(codec->dev, "Looking up %s property in node %s failed\n", - prop_name, codec->dev->of_node->full_name); - boost_voltage = DEFAULT_BOOST_VOLTAGE; - } - if (boost_voltage < MIN_BOOST_VOLTAGE || - boost_voltage > MAX_BOOST_VOLTAGE) { - dev_err(codec->dev, - "Incorrect boost voltage. Reverting to default\n"); - boost_voltage = DEFAULT_BOOST_VOLTAGE; - } - - sdm660_cdc_priv->boost_voltage = - VOLTAGE_CONVERTER(boost_voltage, MIN_BOOST_VOLTAGE, - BOOST_VOLTAGE_STEP); - dev_dbg(codec->dev, "Boost voltage value is: %d\n", - boost_voltage); -} - -static void msm_anlg_cdc_dt_parse_micbias_info(struct device *dev, - struct wcd_micbias_setting *micbias) -{ - const char *prop_name = "qcom,cdc-micbias-cfilt-mv"; - int ret; - - ret = of_property_read_u32(dev->of_node, prop_name, - &micbias->cfilt1_mv); - if (ret) { - dev_dbg(dev, "Looking up %s property in node %s failed", - prop_name, dev->of_node->full_name); - micbias->cfilt1_mv = MICBIAS_DEFAULT_VAL; - } -} - -static struct sdm660_cdc_pdata *msm_anlg_cdc_populate_dt_pdata( - struct device *dev) -{ - struct sdm660_cdc_pdata *pdata; - int ret, static_cnt, ond_cnt, idx, i; - const char *name = NULL; - const char *static_prop_name = "qcom,cdc-static-supplies"; - const char *ond_prop_name = "qcom,cdc-on-demand-supplies"; - - pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return NULL; - - static_cnt = of_property_count_strings(dev->of_node, static_prop_name); - if (static_cnt < 0) { - dev_err(dev, "%s: Failed to get static supplies %d\n", __func__, - static_cnt); - ret = -EINVAL; - goto err; - } - - /* On-demand supply list is an optional property */ - ond_cnt = of_property_count_strings(dev->of_node, ond_prop_name); - if (ond_cnt < 0) - ond_cnt = 0; - - WARN_ON(static_cnt <= 0 || ond_cnt < 0); - if ((static_cnt + ond_cnt) > ARRAY_SIZE(pdata->regulator)) { - dev_err(dev, "%s: Num of supplies %u > max supported %zd\n", - __func__, (static_cnt + ond_cnt), - ARRAY_SIZE(pdata->regulator)); - ret = -EINVAL; - goto err; - } - - for (idx = 0; idx < static_cnt; idx++) { - ret = of_property_read_string_index(dev->of_node, - static_prop_name, idx, - &name); - if (ret) { - dev_err(dev, "%s: of read string %s idx %d error %d\n", - __func__, static_prop_name, idx, ret); - goto err; - } - - dev_dbg(dev, "%s: Found static cdc supply %s\n", __func__, - name); - ret = msm_anlg_cdc_dt_parse_vreg_info(dev, - &pdata->regulator[idx], - name, false); - if (ret) { - dev_err(dev, "%s:err parsing vreg for %s idx %d\n", - __func__, name, idx); - goto err; - } - } - - for (i = 0; i < ond_cnt; i++, idx++) { - ret = of_property_read_string_index(dev->of_node, ond_prop_name, - i, &name); - if (ret) { - dev_err(dev, "%s: err parsing on_demand for %s idx %d\n", - __func__, ond_prop_name, i); - goto err; - } - - dev_dbg(dev, "%s: Found on-demand cdc supply %s\n", __func__, - name); - ret = msm_anlg_cdc_dt_parse_vreg_info(dev, - &pdata->regulator[idx], - name, true); - if (ret) { - dev_err(dev, "%s: err parsing vreg on_demand for %s idx %d\n", - __func__, name, idx); - goto err; - } - } - msm_anlg_cdc_dt_parse_micbias_info(dev, &pdata->micbias); - - return pdata; -err: - devm_kfree(dev, pdata); - dev_err(dev, "%s: Failed to populate DT data ret = %d\n", - __func__, ret); - return NULL; -} - -static int msm_anlg_cdc_codec_enable_on_demand_supply( - struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - int ret = 0; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - struct on_demand_supply *supply; - - if (w->shift >= ON_DEMAND_SUPPLIES_MAX) { - dev_err(codec->dev, "%s: error index > MAX Demand supplies", - __func__); - ret = -EINVAL; - goto out; - } - dev_dbg(codec->dev, "%s: supply: %s event: %d ref: %d\n", - __func__, on_demand_supply_name[w->shift], event, - atomic_read(&sdm660_cdc->on_demand_list[w->shift].ref)); - - supply = &sdm660_cdc->on_demand_list[w->shift]; - WARN_ONCE(!supply->supply, "%s isn't defined\n", - on_demand_supply_name[w->shift]); - if (!supply->supply) { - dev_err(codec->dev, "%s: err supply not present ond for %d", - __func__, w->shift); - goto out; - } - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (atomic_inc_return(&supply->ref) == 1) { - ret = regulator_set_voltage(supply->supply, - supply->min_uv, - supply->max_uv); - if (ret) { - dev_err(codec->dev, - "Setting regulator voltage(en) for micbias with err = %d\n", - ret); - goto out; - } - ret = regulator_set_load(supply->supply, - supply->optimum_ua); - if (ret < 0) { - dev_err(codec->dev, - "Setting regulator optimum mode(en) failed for micbias with err = %d\n", - ret); - goto out; - } - ret = regulator_enable(supply->supply); - } - if (ret) - dev_err(codec->dev, "%s: Failed to enable %s\n", - __func__, - on_demand_supply_name[w->shift]); - break; - case SND_SOC_DAPM_POST_PMD: - if (atomic_read(&supply->ref) == 0) { - dev_dbg(codec->dev, "%s: %s supply has been disabled.\n", - __func__, on_demand_supply_name[w->shift]); - goto out; - } - if (atomic_dec_return(&supply->ref) == 0) { - ret = regulator_disable(supply->supply); - if (ret) - dev_err(codec->dev, "%s: Failed to disable %s\n", - __func__, - on_demand_supply_name[w->shift]); - ret = regulator_set_voltage(supply->supply, - 0, - supply->max_uv); - if (ret) { - dev_err(codec->dev, - "Setting regulator voltage(dis) failed for micbias with err = %d\n", - ret); - goto out; - } - ret = regulator_set_load(supply->supply, 0); - if (ret < 0) - dev_err(codec->dev, - "Setting regulator optimum mode(dis) failed for micbias with err = %d\n", - ret); - } - break; - default: - break; - } -out: - return ret; -} - -static int msm_anlg_cdc_codec_enable_clock_block(struct snd_soc_codec *codec, - int enable) -{ - struct msm_asoc_mach_data *pdata = NULL; - - pdata = snd_soc_card_get_drvdata(codec->component.card); - if (enable) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, 0x30, 0x30); - msm_anlg_cdc_dig_notifier_call(codec, DIG_CDC_EVENT_CLK_ON); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80, 0x80); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL, 0x0C, 0x0C); - } else { - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL, 0x0C, 0x00); - } - return 0; -} - -static int msm_anlg_cdc_codec_enable_charge_pump(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: event = %d\n", __func__, event); - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - msm_anlg_cdc_codec_enable_clock_block(codec, 1); - if (!(strcmp(w->name, "EAR CP"))) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0x80, 0x80); - msm_anlg_cdc_boost_mode_sequence(codec, EAR_PMU); - } else if (get_codec_version(sdm660_cdc) >= DIANGU) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0x80, 0x80); - } else { - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0xC0, 0xC0); - } - break; - case SND_SOC_DAPM_POST_PMU: - /* Wait for 1ms post powerup of chargepump */ - usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); - break; - case SND_SOC_DAPM_POST_PMD: - /* Wait for 1ms post powerdown of chargepump */ - usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); - if (!(strcmp(w->name, "EAR CP"))) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0x80, 0x00); - if (sdm660_cdc->boost_option != BOOST_ALWAYS) { - dev_dbg(codec->dev, - "%s: boost_option:%d, tear down ear\n", - __func__, sdm660_cdc->boost_option); - msm_anlg_cdc_boost_mode_sequence(codec, - EAR_PMD); - } - /* - * Reset pa select bit from ear to hph after ear pa - * is disabled and HPH DAC disable to reduce ear - * turn off pop and avoid HPH pop in concurrency - */ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x80, 0x00); - } else { - if (get_codec_version(sdm660_cdc) < DIANGU) - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0x40, 0x00); - if (sdm660_cdc->rx_bias_count == 0) - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0x80, 0x00); - dev_dbg(codec->dev, "%s: rx_bias_count = %d\n", - __func__, sdm660_cdc->rx_bias_count); - } - break; - } - return 0; -} - -static int msm_anlg_cdc_ear_pa_boost_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = - (sdm660_cdc->ear_pa_boost_set ? 1 : 0); - dev_dbg(codec->dev, "%s: sdm660_cdc->ear_pa_boost_set = %d\n", - __func__, sdm660_cdc->ear_pa_boost_set); - return 0; -} - -static int msm_anlg_cdc_ear_pa_boost_set(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - sdm660_cdc->ear_pa_boost_set = - (ucontrol->value.integer.value[0] ? true : false); - return 0; -} - -static int msm_anlg_cdc_pa_gain_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - u8 ear_pa_gain; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - if (get_codec_version(sdm660_cdc) >= DIANGU) { - ear_pa_gain = snd_soc_read(codec, - MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC); - ear_pa_gain = (ear_pa_gain >> 1) & 0x3; - - if (ear_pa_gain == 0x00) { - ucontrol->value.integer.value[0] = 3; - } else if (ear_pa_gain == 0x01) { - ucontrol->value.integer.value[0] = 2; - } else if (ear_pa_gain == 0x02) { - ucontrol->value.integer.value[0] = 1; - } else if (ear_pa_gain == 0x03) { - ucontrol->value.integer.value[0] = 0; - } else { - dev_err(codec->dev, - "%s: ERROR: Unsupported Ear Gain = 0x%x\n", - __func__, ear_pa_gain); - return -EINVAL; - } - } else { - ear_pa_gain = snd_soc_read(codec, - MSM89XX_PMIC_ANALOG_RX_EAR_CTL); - ear_pa_gain = (ear_pa_gain >> 5) & 0x1; - if (ear_pa_gain == 0x00) { - ucontrol->value.integer.value[0] = 0; - } else if (ear_pa_gain == 0x01) { - ucontrol->value.integer.value[0] = 3; - } else { - dev_err(codec->dev, - "%s: ERROR: Unsupported Ear Gain = 0x%x\n", - __func__, ear_pa_gain); - return -EINVAL; - } - } - dev_dbg(codec->dev, "%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain); - return 0; -} - -static int msm_anlg_cdc_pa_gain_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - u8 ear_pa_gain; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - if (get_codec_version(sdm660_cdc) >= DIANGU) { - switch (ucontrol->value.integer.value[0]) { - case 0: - ear_pa_gain = 0x06; - break; - case 1: - ear_pa_gain = 0x04; - break; - case 2: - ear_pa_gain = 0x02; - break; - case 3: - ear_pa_gain = 0x00; - break; - default: - return -EINVAL; - } - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, - 0x06, ear_pa_gain); - } else { - switch (ucontrol->value.integer.value[0]) { - case 0: - ear_pa_gain = 0x00; - break; - case 3: - ear_pa_gain = 0x20; - break; - case 1: - case 2: - default: - return -EINVAL; - } - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_RX_EAR_CTL, - 0x20, ear_pa_gain); - } - return 0; -} - -static int msm_anlg_cdc_hph_mode_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - if (sdm660_cdc->hph_mode == NORMAL_MODE) { - ucontrol->value.integer.value[0] = 0; - } else if (sdm660_cdc->hph_mode == HD2_MODE) { - ucontrol->value.integer.value[0] = 1; - } else { - dev_err(codec->dev, "%s: ERROR: Default HPH Mode= %d\n", - __func__, sdm660_cdc->hph_mode); - } - - dev_dbg(codec->dev, "%s: sdm660_cdc->hph_mode = %d\n", __func__, - sdm660_cdc->hph_mode); - return 0; -} - -static int msm_anlg_cdc_hph_mode_set(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - switch (ucontrol->value.integer.value[0]) { - case 0: - sdm660_cdc->hph_mode = NORMAL_MODE; - break; - case 1: - if (get_codec_version(sdm660_cdc) >= DIANGU) - sdm660_cdc->hph_mode = HD2_MODE; - break; - default: - sdm660_cdc->hph_mode = NORMAL_MODE; - break; - } - dev_dbg(codec->dev, "%s: sdm660_cdc->hph_mode_set = %d\n", - __func__, sdm660_cdc->hph_mode); - return 0; -} - -static int msm_anlg_cdc_boost_option_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - if (sdm660_cdc->boost_option == BOOST_SWITCH) { - ucontrol->value.integer.value[0] = 0; - } else if (sdm660_cdc->boost_option == BOOST_ALWAYS) { - ucontrol->value.integer.value[0] = 1; - } else if (sdm660_cdc->boost_option == BYPASS_ALWAYS) { - ucontrol->value.integer.value[0] = 2; - } else if (sdm660_cdc->boost_option == BOOST_ON_FOREVER) { - ucontrol->value.integer.value[0] = 3; - } else { - dev_err(codec->dev, "%s: ERROR: Unsupported Boost option= %d\n", - __func__, sdm660_cdc->boost_option); - return -EINVAL; - } - - dev_dbg(codec->dev, "%s: sdm660_cdc->boost_option = %d\n", __func__, - sdm660_cdc->boost_option); - return 0; -} - -static int msm_anlg_cdc_boost_option_set(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - switch (ucontrol->value.integer.value[0]) { - case 0: - sdm660_cdc->boost_option = BOOST_SWITCH; - break; - case 1: - sdm660_cdc->boost_option = BOOST_ALWAYS; - break; - case 2: - sdm660_cdc->boost_option = BYPASS_ALWAYS; - msm_anlg_cdc_bypass_on(codec); - break; - case 3: - sdm660_cdc->boost_option = BOOST_ON_FOREVER; - msm_anlg_cdc_boost_on(codec); - break; - default: - pr_err("%s: invalid boost option: %d\n", __func__, - sdm660_cdc->boost_option); - return -EINVAL; - } - dev_dbg(codec->dev, "%s: sdm660_cdc->boost_option_set = %d\n", - __func__, sdm660_cdc->boost_option); - return 0; -} - -static int msm_anlg_cdc_spk_boost_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - if (sdm660_cdc->spk_boost_set == false) { - ucontrol->value.integer.value[0] = 0; - } else if (sdm660_cdc->spk_boost_set == true) { - ucontrol->value.integer.value[0] = 1; - } else { - dev_err(codec->dev, "%s: ERROR: Unsupported Speaker Boost = %d\n", - __func__, sdm660_cdc->spk_boost_set); - return -EINVAL; - } - - dev_dbg(codec->dev, "%s: sdm660_cdc->spk_boost_set = %d\n", __func__, - sdm660_cdc->spk_boost_set); - return 0; -} - -static int msm_anlg_cdc_spk_boost_set(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - switch (ucontrol->value.integer.value[0]) { - case 0: - sdm660_cdc->spk_boost_set = false; - break; - case 1: - sdm660_cdc->spk_boost_set = true; - break; - default: - return -EINVAL; - } - dev_dbg(codec->dev, "%s: sdm660_cdc->spk_boost_set = %d\n", - __func__, sdm660_cdc->spk_boost_set); - return 0; -} - -static int msm_anlg_cdc_ext_spk_boost_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - if (sdm660_cdc->ext_spk_boost_set == false) - ucontrol->value.integer.value[0] = 0; - else - ucontrol->value.integer.value[0] = 1; - - dev_dbg(codec->dev, "%s: sdm660_cdc->ext_spk_boost_set = %d\n", - __func__, sdm660_cdc->ext_spk_boost_set); - return 0; -} - -static int msm_anlg_cdc_ext_spk_boost_set(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - switch (ucontrol->value.integer.value[0]) { - case 0: - sdm660_cdc->ext_spk_boost_set = false; - break; - case 1: - sdm660_cdc->ext_spk_boost_set = true; - break; - default: - return -EINVAL; - } - dev_dbg(codec->dev, "%s: sdm660_cdc->spk_boost_set = %d\n", - __func__, sdm660_cdc->spk_boost_set); - return 0; -} - -static const char * const msm_anlg_cdc_ear_pa_boost_ctrl_text[] = { - "DISABLE", "ENABLE"}; -static const struct soc_enum msm_anlg_cdc_ear_pa_boost_ctl_enum[] = { - SOC_ENUM_SINGLE_EXT(2, msm_anlg_cdc_ear_pa_boost_ctrl_text), -}; - -static const char * const msm_anlg_cdc_ear_pa_gain_text[] = { - "POS_1P5_DB", "POS_3_DB", "POS_4P5_DB", "POS_6_DB"}; -static const struct soc_enum msm_anlg_cdc_ear_pa_gain_enum[] = { - SOC_ENUM_SINGLE_EXT(4, msm_anlg_cdc_ear_pa_gain_text), -}; - -static const char * const msm_anlg_cdc_boost_option_ctrl_text[] = { - "BOOST_SWITCH", "BOOST_ALWAYS", "BYPASS_ALWAYS", - "BOOST_ON_FOREVER"}; -static const struct soc_enum msm_anlg_cdc_boost_option_ctl_enum[] = { - SOC_ENUM_SINGLE_EXT(4, msm_anlg_cdc_boost_option_ctrl_text), -}; -static const char * const msm_anlg_cdc_spk_boost_ctrl_text[] = { - "DISABLE", "ENABLE"}; -static const struct soc_enum msm_anlg_cdc_spk_boost_ctl_enum[] = { - SOC_ENUM_SINGLE_EXT(2, msm_anlg_cdc_spk_boost_ctrl_text), -}; - -static const char * const msm_anlg_cdc_ext_spk_boost_ctrl_text[] = { - "DISABLE", "ENABLE"}; -static const struct soc_enum msm_anlg_cdc_ext_spk_boost_ctl_enum[] = { - SOC_ENUM_SINGLE_EXT(2, msm_anlg_cdc_ext_spk_boost_ctrl_text), -}; - -static const char * const msm_anlg_cdc_hph_mode_ctrl_text[] = { - "NORMAL", "HD2"}; -static const struct soc_enum msm_anlg_cdc_hph_mode_ctl_enum[] = { - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(msm_anlg_cdc_hph_mode_ctrl_text), - msm_anlg_cdc_hph_mode_ctrl_text), -}; - -/*cut of frequency for high pass filter*/ -static const char * const cf_text[] = { - "MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz" -}; - - -static const struct snd_kcontrol_new msm_anlg_cdc_snd_controls[] = { - - SOC_ENUM_EXT("RX HPH Mode", msm_anlg_cdc_hph_mode_ctl_enum[0], - msm_anlg_cdc_hph_mode_get, msm_anlg_cdc_hph_mode_set), - - SOC_ENUM_EXT("Boost Option", msm_anlg_cdc_boost_option_ctl_enum[0], - msm_anlg_cdc_boost_option_get, msm_anlg_cdc_boost_option_set), - - SOC_ENUM_EXT("EAR PA Boost", msm_anlg_cdc_ear_pa_boost_ctl_enum[0], - msm_anlg_cdc_ear_pa_boost_get, msm_anlg_cdc_ear_pa_boost_set), - - SOC_ENUM_EXT("EAR PA Gain", msm_anlg_cdc_ear_pa_gain_enum[0], - msm_anlg_cdc_pa_gain_get, msm_anlg_cdc_pa_gain_put), - - SOC_ENUM_EXT("Speaker Boost", msm_anlg_cdc_spk_boost_ctl_enum[0], - msm_anlg_cdc_spk_boost_get, msm_anlg_cdc_spk_boost_set), - - SOC_ENUM_EXT("Ext Spk Boost", msm_anlg_cdc_ext_spk_boost_ctl_enum[0], - msm_anlg_cdc_ext_spk_boost_get, msm_anlg_cdc_ext_spk_boost_set), - - SOC_SINGLE_TLV("ADC1 Volume", MSM89XX_PMIC_ANALOG_TX_1_EN, 3, - 8, 0, analog_gain), - SOC_SINGLE_TLV("ADC2 Volume", MSM89XX_PMIC_ANALOG_TX_2_EN, 3, - 8, 0, analog_gain), - SOC_SINGLE_TLV("ADC3 Volume", MSM89XX_PMIC_ANALOG_TX_3_EN, 3, - 8, 0, analog_gain), - - -}; - -static int tombak_hph_impedance_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret; - uint32_t zl, zr; - bool hphr; - struct soc_multi_mixer_control *mc; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct sdm660_cdc_priv *priv = snd_soc_codec_get_drvdata(codec); - - mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); - - hphr = mc->shift; - ret = wcd_mbhc_get_impedance(&priv->mbhc, &zl, &zr); - if (ret) - dev_dbg(codec->dev, "%s: Failed to get mbhc imped", __func__); - dev_dbg(codec->dev, "%s: zl %u, zr %u\n", __func__, zl, zr); - ucontrol->value.integer.value[0] = hphr ? zr : zl; - - return 0; -} - -static const struct snd_kcontrol_new impedance_detect_controls[] = { - SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0, - tombak_hph_impedance_get, NULL), - SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0, - tombak_hph_impedance_get, NULL), -}; - -static int tombak_get_hph_type(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct sdm660_cdc_priv *priv = snd_soc_codec_get_drvdata(codec); - struct wcd_mbhc *mbhc; - - if (!priv) { - dev_err(codec->dev, - "%s: sdm660_cdc-wcd private data is NULL\n", - __func__); - return -EINVAL; - } - - mbhc = &priv->mbhc; - if (!mbhc) { - dev_err(codec->dev, "%s: mbhc not initialized\n", __func__); - return -EINVAL; - } - - ucontrol->value.integer.value[0] = (u32) mbhc->hph_type; - dev_dbg(codec->dev, "%s: hph_type = %u\n", __func__, mbhc->hph_type); - - return 0; -} - -static const struct snd_kcontrol_new hph_type_detect_controls[] = { - SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0, - tombak_get_hph_type, NULL), -}; - -static const char * const rdac2_mux_text[] = { - "ZERO", "RX2", "RX1" -}; - -static const struct snd_kcontrol_new adc1_switch = - SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); - -static const struct soc_enum rdac2_mux_enum = - SOC_ENUM_SINGLE(MSM89XX_PMIC_DIGITAL_CDC_CONN_HPHR_DAC_CTL, - 0, 3, rdac2_mux_text); - -static const char * const adc2_mux_text[] = { - "ZERO", "INP2", "INP3" -}; - -static const char * const ext_spk_text[] = { - "Off", "On" -}; - -static const char * const wsa_spk_text[] = { - "ZERO", "WSA" -}; - -static const struct soc_enum adc2_enum = - SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, - ARRAY_SIZE(adc2_mux_text), adc2_mux_text); - -static const struct soc_enum ext_spk_enum = - SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, - ARRAY_SIZE(ext_spk_text), ext_spk_text); - -static const struct soc_enum wsa_spk_enum = - SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, - ARRAY_SIZE(wsa_spk_text), wsa_spk_text); - - - -static const struct snd_kcontrol_new ext_spk_mux = - SOC_DAPM_ENUM("Ext Spk Switch Mux", ext_spk_enum); - - - -static const struct snd_kcontrol_new tx_adc2_mux = - SOC_DAPM_ENUM("ADC2 MUX Mux", adc2_enum); - - -static const struct snd_kcontrol_new rdac2_mux = - SOC_DAPM_ENUM("RDAC2 MUX Mux", rdac2_mux_enum); - -static const char * const ear_text[] = { - "ZERO", "Switch", -}; - -static const struct soc_enum ear_enum = - SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(ear_text), ear_text); - -static const struct snd_kcontrol_new ear_pa_mux[] = { - SOC_DAPM_ENUM("EAR_S", ear_enum) -}; - -static const struct snd_kcontrol_new wsa_spk_mux[] = { - SOC_DAPM_ENUM("WSA Spk Switch", wsa_spk_enum) -}; - - - -static const char * const hph_text[] = { - "ZERO", "Switch", -}; - -static const struct soc_enum hph_enum = - SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hph_text), hph_text); - -static const struct snd_kcontrol_new hphl_mux[] = { - SOC_DAPM_ENUM("HPHL", hph_enum) -}; - -static const struct snd_kcontrol_new hphr_mux[] = { - SOC_DAPM_ENUM("HPHR", hph_enum) -}; - -static const struct snd_kcontrol_new spkr_mux[] = { - SOC_DAPM_ENUM("SPK", hph_enum) -}; - -static const char * const lo_text[] = { - "ZERO", "Switch", -}; - -static const struct soc_enum lo_enum = - SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hph_text), hph_text); - -static const struct snd_kcontrol_new lo_mux[] = { - SOC_DAPM_ENUM("LINE_OUT", lo_enum) -}; - -static void msm_anlg_cdc_codec_enable_adc_block(struct snd_soc_codec *codec, - int enable) -{ - struct sdm660_cdc_priv *wcd8x16 = snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s %d\n", __func__, enable); - - if (enable) { - wcd8x16->adc_count++; - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, - 0x20, 0x20); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0x10, 0x10); - } else { - wcd8x16->adc_count--; - if (!wcd8x16->adc_count) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0x10, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, - 0x20, 0x0); - } - } -} - -static int msm_anlg_cdc_codec_enable_adc(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - u16 adc_reg; - u8 init_bit_shift; - - dev_dbg(codec->dev, "%s %d\n", __func__, event); - - adc_reg = MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_2; - - if (w->reg == MSM89XX_PMIC_ANALOG_TX_1_EN) - init_bit_shift = 5; - else if ((w->reg == MSM89XX_PMIC_ANALOG_TX_2_EN) || - (w->reg == MSM89XX_PMIC_ANALOG_TX_3_EN)) - init_bit_shift = 4; - else { - dev_err(codec->dev, "%s: Error, invalid adc register\n", - __func__); - return -EINVAL; - } - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - msm_anlg_cdc_codec_enable_adc_block(codec, 1); - if (w->reg == MSM89XX_PMIC_ANALOG_TX_2_EN) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MICB_1_CTL, 0x02, 0x02); - /* - * Add delay of 10 ms to give sufficient time for the voltage - * to shoot up and settle so that the txfe init does not - * happen when the input voltage is changing too much. - */ - usleep_range(10000, 10010); - snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, - 1 << init_bit_shift); - if (w->reg == MSM89XX_PMIC_ANALOG_TX_1_EN) - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL, - 0x03, 0x00); - else if ((w->reg == MSM89XX_PMIC_ANALOG_TX_2_EN) || - (w->reg == MSM89XX_PMIC_ANALOG_TX_3_EN)) - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL, - 0x03, 0x00); - /* Wait for 1ms to allow txfe settling time */ - usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); - break; - case SND_SOC_DAPM_POST_PMU: - /* - * Add delay of 12 ms before deasserting the init - * to reduce the tx pop - */ - usleep_range(12000, 12010); - snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, 0x00); - /* Wait for 1ms to allow txfe settling time post powerup */ - usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); - break; - case SND_SOC_DAPM_POST_PMD: - msm_anlg_cdc_codec_enable_adc_block(codec, 0); - if (w->reg == MSM89XX_PMIC_ANALOG_TX_2_EN) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MICB_1_CTL, 0x02, 0x00); - if (w->reg == MSM89XX_PMIC_ANALOG_TX_1_EN) - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL, - 0x03, 0x02); - else if ((w->reg == MSM89XX_PMIC_ANALOG_TX_2_EN) || - (w->reg == MSM89XX_PMIC_ANALOG_TX_3_EN)) - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL, - 0x03, 0x02); - - break; - } - return 0; -} - -static int msm_anlg_cdc_codec_enable_spk_pa(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0x01, 0x01); - switch (sdm660_cdc->boost_option) { - case BOOST_SWITCH: - if (!sdm660_cdc->spk_boost_set) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, - 0x10, 0x10); - break; - case BOOST_ALWAYS: - case BOOST_ON_FOREVER: - break; - case BYPASS_ALWAYS: - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, - 0x10, 0x10); - break; - default: - dev_err(codec->dev, - "%s: invalid boost option: %d\n", __func__, - sdm660_cdc->boost_option); - break; - } - /* Wait for 1ms after SPK_DAC CTL setting */ - usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0xE0, 0xE0); - if (get_codec_version(sdm660_cdc) != TOMBAK_1_0) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x01, 0x01); - break; - case SND_SOC_DAPM_POST_PMU: - /* Wait for 1ms after SPK_VBAT_LDO Enable */ - usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); - switch (sdm660_cdc->boost_option) { - case BOOST_SWITCH: - if (sdm660_cdc->spk_boost_set) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, - 0xEF, 0xEF); - else - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, - 0x10, 0x00); - break; - case BOOST_ALWAYS: - case BOOST_ON_FOREVER: - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, - 0xEF, 0xEF); - break; - case BYPASS_ALWAYS: - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x10, 0x00); - break; - default: - dev_err(codec->dev, - "%s: invalid boost option: %d\n", __func__, - sdm660_cdc->boost_option); - break; - } - msm_anlg_cdc_dig_notifier_call(codec, - DIG_CDC_EVENT_RX3_MUTE_OFF); - snd_soc_update_bits(codec, w->reg, 0x80, 0x80); - break; - case SND_SOC_DAPM_PRE_PMD: - msm_anlg_cdc_dig_notifier_call(codec, - DIG_CDC_EVENT_RX3_MUTE_ON); - /* - * Add 1 ms sleep for the mute to take effect - */ - usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x10, 0x10); - if (get_codec_version(sdm660_cdc) < CAJON_2_0) - msm_anlg_cdc_boost_mode_sequence(codec, SPK_PMD); - snd_soc_update_bits(codec, w->reg, 0x80, 0x00); - switch (sdm660_cdc->boost_option) { - case BOOST_SWITCH: - if (sdm660_cdc->spk_boost_set) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, - 0xEF, 0x69); - break; - case BOOST_ALWAYS: - case BOOST_ON_FOREVER: - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, - 0xEF, 0x69); - break; - case BYPASS_ALWAYS: - break; - default: - dev_err(codec->dev, - "%s: invalid boost option: %d\n", __func__, - sdm660_cdc->boost_option); - break; - } - break; - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0xE0, 0x00); - /* Wait for 1ms to allow setting time for spkr path disable */ - usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0x01, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x10, 0x00); - if (get_codec_version(sdm660_cdc) != TOMBAK_1_0) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x01, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00); - if (get_codec_version(sdm660_cdc) >= CAJON_2_0) - msm_anlg_cdc_boost_mode_sequence(codec, SPK_PMD); - break; - } - return 0; -} - -static int msm_anlg_cdc_codec_enable_dig_clk(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - struct msm_asoc_mach_data *pdata = NULL; - - pdata = snd_soc_card_get_drvdata(codec->component.card); - - dev_dbg(codec->dev, "%s event %d w->name %s\n", __func__, - event, w->name); - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - msm_anlg_cdc_codec_enable_clock_block(codec, 1); - snd_soc_update_bits(codec, w->reg, 0x80, 0x80); - msm_anlg_cdc_boost_mode_sequence(codec, SPK_PMU); - break; - case SND_SOC_DAPM_POST_PMD: - if (sdm660_cdc->rx_bias_count == 0) - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0x80, 0x00); - } - return 0; -} - - - -static bool msm_anlg_cdc_use_mb(struct snd_soc_codec *codec) -{ - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - if (get_codec_version(sdm660_cdc) < CAJON) - return true; - else - return false; -} - -static void msm_anlg_cdc_set_auto_zeroing(struct snd_soc_codec *codec, - bool enable) -{ - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - if (get_codec_version(sdm660_cdc) < CONGA) { - if (enable) - /* - * Set autozeroing for special headset detection and - * buttons to work. - */ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MICB_2_EN, - 0x18, 0x10); - else - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MICB_2_EN, - 0x18, 0x00); - - } else { - dev_dbg(codec->dev, - "%s: Auto Zeroing is not required from CONGA\n", - __func__); - } -} - -static void msm_anlg_cdc_trim_btn_reg(struct snd_soc_codec *codec) -{ - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - if (get_codec_version(sdm660_cdc) == TOMBAK_1_0) { - pr_debug("%s: This device needs to be trimmed\n", __func__); - /* - * Calculate the trim value for each device used - * till is comes in production by hardware team - */ - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SEC_ACCESS, - 0xA5, 0xA5); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_TRIM_CTRL2, - 0xFF, 0x30); - } else { - dev_dbg(codec->dev, "%s: This device is trimmed at ATE\n", - __func__); - } -} - -static int msm_anlg_cdc_enable_ext_mb_source(struct wcd_mbhc *wcd_mbhc, - bool turn_on) -{ - int ret = 0; - static int count; - struct snd_soc_codec *codec = wcd_mbhc->codec; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - - dev_dbg(codec->dev, "%s turn_on: %d count: %d\n", __func__, turn_on, - count); - if (turn_on) { - if (!count) { - ret = snd_soc_dapm_force_enable_pin(dapm, - "MICBIAS_REGULATOR"); - snd_soc_dapm_sync(dapm); - } - count++; - } else { - if (count > 0) - count--; - if (!count) { - ret = snd_soc_dapm_disable_pin(dapm, - "MICBIAS_REGULATOR"); - snd_soc_dapm_sync(dapm); - } - } - - if (ret) - dev_err(codec->dev, "%s: Failed to %s external micbias source\n", - __func__, turn_on ? "enable" : "disabled"); - else - dev_dbg(codec->dev, "%s: %s external micbias source\n", - __func__, turn_on ? "Enabled" : "Disabled"); - - return ret; -} - -static int msm_anlg_cdc_codec_enable_micbias(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - u16 micb_int_reg; - char *internal1_text = "Internal1"; - char *internal2_text = "Internal2"; - char *internal3_text = "Internal3"; - char *external2_text = "External2"; - char *external_text = "External"; - bool micbias2; - - dev_dbg(codec->dev, "%s %d\n", __func__, event); - switch (w->reg) { - case MSM89XX_PMIC_ANALOG_MICB_1_EN: - case MSM89XX_PMIC_ANALOG_MICB_2_EN: - micb_int_reg = MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS; - break; - default: - dev_err(codec->dev, - "%s: Error, invalid micbias register 0x%x\n", - __func__, w->reg); - return -EINVAL; - } - - micbias2 = (snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MICB_2_EN) & 0x80); - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (strnstr(w->name, internal1_text, strlen(w->name))) { - if (get_codec_version(sdm660_cdc) >= CAJON) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2, - 0x02, 0x02); - snd_soc_update_bits(codec, micb_int_reg, 0x80, 0x80); - } else if (strnstr(w->name, internal2_text, strlen(w->name))) { - snd_soc_update_bits(codec, micb_int_reg, 0x10, 0x10); - snd_soc_update_bits(codec, w->reg, 0x60, 0x00); - } else if (strnstr(w->name, internal3_text, strlen(w->name))) { - snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x2); - /* - * update MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2 - * for external bias only, not for external2. - */ - } else if (!strnstr(w->name, external2_text, strlen(w->name)) && - strnstr(w->name, external_text, - strlen(w->name))) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2, - 0x02, 0x02); - } - if (!strnstr(w->name, external_text, strlen(w->name))) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MICB_1_EN, 0x05, 0x04); - if (w->reg == MSM89XX_PMIC_ANALOG_MICB_1_EN) - msm_anlg_cdc_configure_cap(codec, true, micbias2); - - break; - case SND_SOC_DAPM_POST_PMU: - if (get_codec_version(sdm660_cdc) <= TOMBAK_2_0) - /* - * Wait for 20ms post micbias enable - * for version < tombak 2.0. - */ - usleep_range(20000, 20100); - if (strnstr(w->name, internal1_text, strlen(w->name))) { - snd_soc_update_bits(codec, micb_int_reg, 0x40, 0x40); - } else if (strnstr(w->name, internal2_text, strlen(w->name))) { - snd_soc_update_bits(codec, micb_int_reg, 0x08, 0x08); - msm_anlg_cdc_notifier_call(codec, - WCD_EVENT_POST_MICBIAS_2_ON); - } else if (strnstr(w->name, internal3_text, 30)) { - snd_soc_update_bits(codec, micb_int_reg, 0x01, 0x01); - } else if (strnstr(w->name, external2_text, strlen(w->name))) { - msm_anlg_cdc_notifier_call(codec, - WCD_EVENT_POST_MICBIAS_2_ON); - } - break; - case SND_SOC_DAPM_POST_PMD: - if (strnstr(w->name, internal1_text, strlen(w->name))) { - snd_soc_update_bits(codec, micb_int_reg, 0xC0, 0x40); - } else if (strnstr(w->name, internal2_text, strlen(w->name))) { - msm_anlg_cdc_notifier_call(codec, - WCD_EVENT_POST_MICBIAS_2_OFF); - } else if (strnstr(w->name, internal3_text, 30)) { - snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x0); - } else if (strnstr(w->name, external2_text, strlen(w->name))) { - /* - * send micbias turn off event to mbhc driver and then - * break, as no need to set MICB_1_EN register. - */ - msm_anlg_cdc_notifier_call(codec, - WCD_EVENT_POST_MICBIAS_2_OFF); - break; - } - if (w->reg == MSM89XX_PMIC_ANALOG_MICB_1_EN) - msm_anlg_cdc_configure_cap(codec, false, micbias2); - break; - } - return 0; -} - -static void set_compander_mode(void *handle, int val) -{ - struct sdm660_cdc_priv *handle_cdc = handle; - struct snd_soc_codec *codec = handle_cdc->codec; - - if (get_codec_version(handle_cdc) >= DIANGU) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, - 0x08, val); - }; -} - -static void update_clkdiv(void *handle, int val) -{ - struct sdm660_cdc_priv *handle_cdc = handle; - struct snd_soc_codec *codec = handle_cdc->codec; - - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_TX_1_2_TXFE_CLKDIV, - 0xFF, val); -} - -static int get_cdc_version(void *handle) -{ - struct sdm660_cdc_priv *sdm660_cdc = handle; - - return get_codec_version(sdm660_cdc); -} - -static int sdm660_wcd_codec_enable_vdd_spkr(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - int ret = 0; - - if (!sdm660_cdc->ext_spk_boost_set) { - dev_dbg(codec->dev, "%s: ext_boost not supported/disabled\n", - __func__); - return 0; - } - dev_dbg(codec->dev, "%s: %s %d\n", __func__, w->name, event); - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (sdm660_cdc->spkdrv_reg) { - ret = regulator_enable(sdm660_cdc->spkdrv_reg); - if (ret) - dev_err(codec->dev, - "%s Failed to enable spkdrv reg %s\n", - __func__, MSM89XX_VDD_SPKDRV_NAME); - } - break; - case SND_SOC_DAPM_POST_PMD: - if (sdm660_cdc->spkdrv_reg) { - ret = regulator_disable(sdm660_cdc->spkdrv_reg); - if (ret) - dev_err(codec->dev, - "%s: Failed to disable spkdrv_reg %s\n", - __func__, MSM89XX_VDD_SPKDRV_NAME); - } - break; - } - return 0; -} - - -/* The register address is the same as other codec so it can use resmgr */ -static int msm_anlg_cdc_codec_enable_rx_bias(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s %d\n", __func__, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - sdm660_cdc->rx_bias_count++; - if (sdm660_cdc->rx_bias_count == 1) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, - 0x80, 0x80); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, - 0x01, 0x01); - } - break; - case SND_SOC_DAPM_POST_PMD: - sdm660_cdc->rx_bias_count--; - if (sdm660_cdc->rx_bias_count == 0) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, - 0x01, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, - 0x80, 0x00); - } - break; - } - dev_dbg(codec->dev, "%s rx_bias_count = %d\n", - __func__, sdm660_cdc->rx_bias_count); - return 0; -} - -static uint32_t wcd_get_impedance_value(uint32_t imped) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(wcd_imped_val) - 1; i++) { - if (imped >= wcd_imped_val[i] && - imped < wcd_imped_val[i + 1]) - break; - } - - pr_debug("%s: selected impedance value = %d\n", - __func__, wcd_imped_val[i]); - return wcd_imped_val[i]; -} - -static void wcd_imped_config(struct snd_soc_codec *codec, - uint32_t imped, bool set_gain) -{ - uint32_t value; - int codec_version; - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - value = wcd_get_impedance_value(imped); - - if (value < wcd_imped_val[0]) { - dev_dbg(codec->dev, - "%s, detected impedance is less than 4 Ohm\n", - __func__); - return; - } - - codec_version = get_codec_version(sdm660_cdc); - - if (set_gain) { - switch (codec_version) { - case TOMBAK_1_0: - case TOMBAK_2_0: - case CONGA: - /* - * For 32Ohm load and higher loads, Set 0x19E - * bit 5 to 1 (POS_0_DB_DI). For loads lower - * than 32Ohm (such as 16Ohm load), Set 0x19E - * bit 5 to 0 (POS_M4P5_DB_DI) - */ - if (value >= 32) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_EAR_CTL, - 0x20, 0x20); - else - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_EAR_CTL, - 0x20, 0x00); - break; - case CAJON: - case CAJON_2_0: - case DIANGU: - case DRAX_CDC: - if (value >= 13) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_EAR_CTL, - 0x20, 0x20); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_NCP_VCTRL, - 0x07, 0x07); - } else { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_EAR_CTL, - 0x20, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_NCP_VCTRL, - 0x07, 0x04); - } - break; - } - } else { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_EAR_CTL, - 0x20, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_NCP_VCTRL, - 0x07, 0x04); - } - - dev_dbg(codec->dev, "%s: Exit\n", __func__); -} - -static int msm_anlg_cdc_hphl_dac_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - uint32_t impedl, impedr; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - int ret; - - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); - ret = wcd_mbhc_get_impedance(&sdm660_cdc->mbhc, - &impedl, &impedr); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (get_codec_version(sdm660_cdc) > CAJON) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, - 0x08, 0x08); - if (get_codec_version(sdm660_cdc) == CAJON || - get_codec_version(sdm660_cdc) == CAJON_2_0) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, - 0x80, 0x80); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, - 0x80, 0x80); - } - if (get_codec_version(sdm660_cdc) > CAJON) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, - 0x08, 0x00); - if (sdm660_cdc->hph_mode == HD2_MODE) - msm_anlg_cdc_dig_notifier_call(codec, - DIG_CDC_EVENT_PRE_RX1_INT_ON); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x02, 0x02); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x01); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x02); - if (!ret) - wcd_imped_config(codec, impedl, true); - else - dev_dbg(codec->dev, "Failed to get mbhc impedance %d\n", - ret); - break; - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x02, 0x00); - break; - case SND_SOC_DAPM_POST_PMD: - wcd_imped_config(codec, impedl, false); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x00); - if (sdm660_cdc->hph_mode == HD2_MODE) - msm_anlg_cdc_dig_notifier_call(codec, - DIG_CDC_EVENT_POST_RX1_INT_OFF); - break; - } - return 0; -} - -static int msm_anlg_cdc_lo_dac_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x80, 0x80); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x08, 0x08); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x40, 0x40); - break; - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x80, 0x80); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x08, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x40, 0x40); - break; - case SND_SOC_DAPM_POST_PMD: - /* Wait for 20ms before powerdown of lineout_dac */ - usleep_range(20000, 20100); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x80, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x40, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x08, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x80, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x40, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x20, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00); - break; - } - return 0; -} - -static int msm_anlg_cdc_hphr_dac_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (sdm660_cdc->hph_mode == HD2_MODE) - msm_anlg_cdc_dig_notifier_call(codec, - DIG_CDC_EVENT_PRE_RX2_INT_ON); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x02, 0x02); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x02, 0x02); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x01, 0x01); - break; - case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x02, 0x00); - break; - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x01, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x02, 0x00); - if (sdm660_cdc->hph_mode == HD2_MODE) - msm_anlg_cdc_dig_notifier_call(codec, - DIG_CDC_EVENT_POST_RX2_INT_OFF); - break; - } - return 0; -} - -static int msm_anlg_cdc_hph_pa_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: %s event = %d\n", __func__, w->name, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (w->shift == 5) - msm_anlg_cdc_notifier_call(codec, - WCD_EVENT_PRE_HPHL_PA_ON); - else if (w->shift == 4) - msm_anlg_cdc_notifier_call(codec, - WCD_EVENT_PRE_HPHR_PA_ON); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0x20, 0x20); - break; - - case SND_SOC_DAPM_POST_PMU: - /* Wait for 7ms to allow setting time for HPH_PA Enable */ - usleep_range(7000, 7100); - if (w->shift == 5) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x04, 0x04); - msm_anlg_cdc_dig_notifier_call(codec, - DIG_CDC_EVENT_RX1_MUTE_OFF); - } else if (w->shift == 4) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x04, 0x04); - msm_anlg_cdc_dig_notifier_call(codec, - DIG_CDC_EVENT_RX2_MUTE_OFF); - } - break; - - case SND_SOC_DAPM_PRE_PMD: - if (w->shift == 5) { - msm_anlg_cdc_dig_notifier_call(codec, - DIG_CDC_EVENT_RX1_MUTE_ON); - /* Wait for 20ms after HPHL RX digital mute */ - msleep(20); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x04, 0x00); - msm_anlg_cdc_notifier_call(codec, - WCD_EVENT_PRE_HPHL_PA_OFF); - } else if (w->shift == 4) { - msm_anlg_cdc_dig_notifier_call(codec, - DIG_CDC_EVENT_RX2_MUTE_ON); - /* Wait for 20ms after HPHR RX digital mute */ - msleep(20); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x04, 0x00); - msm_anlg_cdc_notifier_call(codec, - WCD_EVENT_PRE_HPHR_PA_OFF); - } - if (get_codec_version(sdm660_cdc) >= CAJON) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_CNP, - 0xF0, 0x30); - } - break; - case SND_SOC_DAPM_POST_PMD: - if (w->shift == 5) { - clear_bit(WCD_MBHC_HPHL_PA_OFF_ACK, - &sdm660_cdc->mbhc.hph_pa_dac_state); - msm_anlg_cdc_notifier_call(codec, - WCD_EVENT_POST_HPHL_PA_OFF); - } else if (w->shift == 4) { - clear_bit(WCD_MBHC_HPHR_PA_OFF_ACK, - &sdm660_cdc->mbhc.hph_pa_dac_state); - msm_anlg_cdc_notifier_call(codec, - WCD_EVENT_POST_HPHR_PA_OFF); - } - /* Wait for 15ms after HPH RX teardown */ - usleep_range(15000, 15100); - break; - } - return 0; -} - -static const struct snd_soc_dapm_route audio_map[] = { - /* RDAC Connections */ - {"HPHR DAC", NULL, "RDAC2 MUX"}, - {"RDAC2 MUX", "RX1", "PDM_IN_RX1"}, - {"RDAC2 MUX", "RX2", "PDM_IN_RX2"}, - - /* WSA */ - {"WSA_SPK OUT", NULL, "WSA Spk Switch"}, - {"WSA Spk Switch", "WSA", "EAR PA"}, - - /* Earpiece (RX MIX1) */ - {"EAR", NULL, "EAR_S"}, - {"EAR_S", "Switch", "EAR PA"}, - {"EAR PA", NULL, "RX_BIAS"}, - {"EAR PA", NULL, "HPHL DAC"}, - {"EAR PA", NULL, "HPHR DAC"}, - {"EAR PA", NULL, "EAR CP"}, - - /* Headset (RX MIX1 and RX MIX2) */ - {"HEADPHONE", NULL, "HPHL PA"}, - {"HEADPHONE", NULL, "HPHR PA"}, - - {"Ext Spk", NULL, "Ext Spk Switch"}, - {"Ext Spk Switch", "On", "HPHL PA"}, - {"Ext Spk Switch", "On", "HPHR PA"}, - - {"HPHL PA", NULL, "HPHL"}, - {"HPHR PA", NULL, "HPHR"}, - {"HPHL", "Switch", "HPHL DAC"}, - {"HPHR", "Switch", "HPHR DAC"}, - {"HPHL PA", NULL, "CP"}, - {"HPHL PA", NULL, "RX_BIAS"}, - {"HPHR PA", NULL, "CP"}, - {"HPHR PA", NULL, "RX_BIAS"}, - {"HPHL DAC", NULL, "PDM_IN_RX1"}, - - {"SPK_OUT", NULL, "SPK PA"}, - {"SPK PA", NULL, "SPK_RX_BIAS"}, - {"SPK PA", NULL, "SPK"}, - {"SPK", "Switch", "SPK DAC"}, - {"SPK DAC", NULL, "PDM_IN_RX3"}, - {"SPK DAC", NULL, "VDD_SPKDRV"}, - - /* lineout */ - {"LINEOUT", NULL, "LINEOUT PA"}, - {"LINEOUT PA", NULL, "SPK_RX_BIAS"}, - {"LINEOUT PA", NULL, "LINE_OUT"}, - {"LINE_OUT", "Switch", "LINEOUT DAC"}, - {"LINEOUT DAC", NULL, "PDM_IN_RX3"}, - - /* lineout to WSA */ - {"WSA_SPK OUT", NULL, "LINEOUT PA"}, - - {"PDM_IN_RX1", NULL, "RX1 CLK"}, - {"PDM_IN_RX2", NULL, "RX2 CLK"}, - {"PDM_IN_RX3", NULL, "RX3 CLK"}, - - {"ADC1_OUT", NULL, "ADC1"}, - {"ADC2_OUT", NULL, "ADC2"}, - {"ADC3_OUT", NULL, "ADC3"}, - - /* ADC Connections */ - {"ADC2", NULL, "ADC2 MUX"}, - {"ADC3", NULL, "ADC2 MUX"}, - {"ADC2 MUX", "INP2", "ADC2_INP2"}, - {"ADC2 MUX", "INP3", "ADC2_INP3"}, - - {"ADC1", NULL, "ADC1_INP1"}, - {"ADC1_INP1", "Switch", "AMIC1"}, - {"ADC2_INP2", NULL, "AMIC2"}, - {"ADC2_INP3", NULL, "AMIC3"}, - - {"MIC BIAS Internal1", NULL, "INT_LDO_H"}, - {"MIC BIAS Internal2", NULL, "INT_LDO_H"}, - {"MIC BIAS External", NULL, "INT_LDO_H"}, - {"MIC BIAS External2", NULL, "INT_LDO_H"}, - {"MIC BIAS Internal1", NULL, "MICBIAS_REGULATOR"}, - {"MIC BIAS Internal2", NULL, "MICBIAS_REGULATOR"}, - {"MIC BIAS External", NULL, "MICBIAS_REGULATOR"}, - {"MIC BIAS External2", NULL, "MICBIAS_REGULATOR"}, -}; - -static int msm_anlg_cdc_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(dai->codec); - - dev_dbg(dai->codec->dev, "%s(): substream = %s stream = %d\n", - __func__, - substream->name, substream->stream); - /* - * If status_mask is BUS_DOWN it means SSR is not complete. - * So return error. - */ - if (test_bit(BUS_DOWN, &sdm660_cdc->status_mask)) { - dev_err(dai->codec->dev, "Error, Device is not up post SSR\n"); - return -EINVAL; - } - return 0; -} - -static void msm_anlg_cdc_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - dev_dbg(dai->codec->dev, - "%s(): substream = %s stream = %d\n", __func__, - substream->name, substream->stream); -} - -int msm_anlg_cdc_mclk_enable(struct snd_soc_codec *codec, - int mclk_enable, bool dapm) -{ - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: mclk_enable = %u, dapm = %d\n", - __func__, mclk_enable, dapm); - if (mclk_enable) { - sdm660_cdc->int_mclk0_enabled = true; - msm_anlg_cdc_codec_enable_clock_block(codec, 1); - } else { - if (!sdm660_cdc->int_mclk0_enabled) { - dev_err(codec->dev, "Error, MCLK already diabled\n"); - return -EINVAL; - } - sdm660_cdc->int_mclk0_enabled = false; - msm_anlg_cdc_codec_enable_clock_block(codec, 0); - } - return 0; -} -EXPORT_SYMBOL(msm_anlg_cdc_mclk_enable); - -static int msm_anlg_cdc_set_dai_sysclk(struct snd_soc_dai *dai, - int clk_id, unsigned int freq, int dir) -{ - dev_dbg(dai->codec->dev, "%s\n", __func__); - return 0; -} - -static int msm_anlg_cdc_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) -{ - dev_dbg(dai->codec->dev, "%s\n", __func__); - return 0; -} - -static int msm_anlg_cdc_set_channel_map(struct snd_soc_dai *dai, - unsigned int tx_num, unsigned int *tx_slot, - unsigned int rx_num, unsigned int *rx_slot) - -{ - dev_dbg(dai->codec->dev, "%s\n", __func__); - return 0; -} - -static int msm_anlg_cdc_get_channel_map(struct snd_soc_dai *dai, - unsigned int *tx_num, unsigned int *tx_slot, - unsigned int *rx_num, unsigned int *rx_slot) - -{ - dev_dbg(dai->codec->dev, "%s\n", __func__); - return 0; -} - -static struct snd_soc_dai_ops msm_anlg_cdc_dai_ops = { - .startup = msm_anlg_cdc_startup, - .shutdown = msm_anlg_cdc_shutdown, - .set_sysclk = msm_anlg_cdc_set_dai_sysclk, - .set_fmt = msm_anlg_cdc_set_dai_fmt, - .set_channel_map = msm_anlg_cdc_set_channel_map, - .get_channel_map = msm_anlg_cdc_get_channel_map, -}; - -static struct snd_soc_dai_driver msm_anlg_cdc_i2s_dai[] = { - { - .name = "msm_anlg_cdc_i2s_rx1", - .id = AIF1_PB, - .playback = { - .stream_name = "PDM Playback", - .rates = SDM660_CDC_RATES, - .formats = SDM660_CDC_FORMATS, - .rate_max = 192000, - .rate_min = 8000, - .channels_min = 1, - .channels_max = 3, - }, - .ops = &msm_anlg_cdc_dai_ops, - }, - { - .name = "msm_anlg_cdc_i2s_tx1", - .id = AIF1_CAP, - .capture = { - .stream_name = "PDM Capture", - .rates = SDM660_CDC_RATES, - .formats = SDM660_CDC_FORMATS, - .rate_max = 48000, - .rate_min = 8000, - .channels_min = 1, - .channels_max = 4, - }, - .ops = &msm_anlg_cdc_dai_ops, - }, - { - .name = "msm_anlg_cdc_i2s_tx2", - .id = AIF3_SVA, - .capture = { - .stream_name = "RecordSVA", - .rates = SDM660_CDC_RATES, - .formats = SDM660_CDC_FORMATS, - .rate_max = 48000, - .rate_min = 8000, - .channels_min = 1, - .channels_max = 2, - }, - .ops = &msm_anlg_cdc_dai_ops, - }, - { - .name = "msm_anlg_vifeedback", - .id = AIF2_VIFEED, - .capture = { - .stream_name = "VIfeed", - .rates = SDM660_CDC_RATES, - .formats = SDM660_CDC_FORMATS, - .rate_max = 48000, - .rate_min = 48000, - .channels_min = 2, - .channels_max = 2, - }, - .ops = &msm_anlg_cdc_dai_ops, - }, -}; - - -static int msm_anlg_cdc_codec_enable_lo_pa(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - dev_dbg(codec->dev, "%s: %d %s\n", __func__, event, w->name); - switch (event) { - case SND_SOC_DAPM_POST_PMU: - msm_anlg_cdc_dig_notifier_call(codec, - DIG_CDC_EVENT_RX3_MUTE_OFF); - break; - case SND_SOC_DAPM_POST_PMD: - msm_anlg_cdc_dig_notifier_call(codec, - DIG_CDC_EVENT_RX3_MUTE_ON); - break; - } - - return 0; -} - -static int msm_anlg_cdc_codec_enable_spk_ext_pa(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: %s event = %d\n", __func__, w->name, event); - switch (event) { - case SND_SOC_DAPM_POST_PMU: - dev_dbg(codec->dev, - "%s: enable external speaker PA\n", __func__); - if (sdm660_cdc->codec_spk_ext_pa_cb) - sdm660_cdc->codec_spk_ext_pa_cb(codec, 1); - break; - case SND_SOC_DAPM_PRE_PMD: - dev_dbg(codec->dev, - "%s: enable external speaker PA\n", __func__); - if (sdm660_cdc->codec_spk_ext_pa_cb) - sdm660_cdc->codec_spk_ext_pa_cb(codec, 0); - break; - } - return 0; -} - -static int msm_anlg_cdc_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - dev_dbg(codec->dev, - "%s: Sleeping 20ms after select EAR PA\n", - __func__); - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_RX_EAR_CTL, - 0x80, 0x80); - if (get_codec_version(sdm660_cdc) < CONGA) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME, 0xFF, 0x2A); - if (get_codec_version(sdm660_cdc) >= DIANGU) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, 0x08, 0x00); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x04, 0x04); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x04, 0x04); - } - break; - case SND_SOC_DAPM_POST_PMU: - dev_dbg(codec->dev, - "%s: Sleeping 20ms after enabling EAR PA\n", - __func__); - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_RX_EAR_CTL, - 0x40, 0x40); - /* Wait for 7ms after EAR PA enable */ - usleep_range(7000, 7100); - msm_anlg_cdc_dig_notifier_call(codec, - DIG_CDC_EVENT_RX1_MUTE_OFF); - break; - case SND_SOC_DAPM_PRE_PMD: - msm_anlg_cdc_dig_notifier_call(codec, - DIG_CDC_EVENT_RX1_MUTE_ON); - /* Wait for 20ms for RX digital mute to take effect */ - msleep(20); - if (sdm660_cdc->boost_option == BOOST_ALWAYS) { - dev_dbg(codec->dev, - "%s: boost_option:%d, tear down ear\n", - __func__, sdm660_cdc->boost_option); - msm_anlg_cdc_boost_mode_sequence(codec, EAR_PMD); - } - if (get_codec_version(sdm660_cdc) >= DIANGU) { - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x04, 0x0); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x04, 0x0); - } - break; - case SND_SOC_DAPM_POST_PMD: - dev_dbg(codec->dev, - "%s: Sleeping 7ms after disabling EAR PA\n", - __func__); - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_RX_EAR_CTL, - 0x40, 0x00); - /* Wait for 7ms after EAR PA teardown */ - usleep_range(7000, 7100); - if (get_codec_version(sdm660_cdc) < CONGA) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME, 0xFF, 0x16); - if (get_codec_version(sdm660_cdc) >= DIANGU) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, 0x08, 0x08); - break; - } - return 0; -} - -static const struct snd_soc_dapm_widget msm_anlg_cdc_dapm_widgets[] = { - SND_SOC_DAPM_PGA_E("EAR PA", SND_SOC_NOPM, - 0, 0, NULL, 0, msm_anlg_cdc_codec_enable_ear_pa, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("HPHL PA", MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, - 5, 0, NULL, 0, - msm_anlg_cdc_hph_pa_event, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("HPHR PA", MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, - 4, 0, NULL, 0, - msm_anlg_cdc_hph_pa_event, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("SPK PA", SND_SOC_NOPM, - 0, 0, NULL, 0, msm_anlg_cdc_codec_enable_spk_pa, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("LINEOUT PA", MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, - 5, 0, NULL, 0, msm_anlg_cdc_codec_enable_lo_pa, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX("EAR_S", SND_SOC_NOPM, 0, 0, ear_pa_mux), - SND_SOC_DAPM_MUX("SPK", SND_SOC_NOPM, 0, 0, spkr_mux), - SND_SOC_DAPM_MUX("HPHL", SND_SOC_NOPM, 0, 0, hphl_mux), - SND_SOC_DAPM_MUX("HPHR", SND_SOC_NOPM, 0, 0, hphr_mux), - SND_SOC_DAPM_MUX("RDAC2 MUX", SND_SOC_NOPM, 0, 0, &rdac2_mux), - SND_SOC_DAPM_MUX("WSA Spk Switch", SND_SOC_NOPM, 0, 0, wsa_spk_mux), - SND_SOC_DAPM_MUX("Ext Spk Switch", SND_SOC_NOPM, 0, 0, &ext_spk_mux), - SND_SOC_DAPM_MUX("LINE_OUT", SND_SOC_NOPM, 0, 0, lo_mux), - SND_SOC_DAPM_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, &tx_adc2_mux), - - SND_SOC_DAPM_MIXER_E("HPHL DAC", - MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 3, 0, NULL, - 0, msm_anlg_cdc_hphl_dac_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER_E("HPHR DAC", - MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 3, 0, NULL, - 0, msm_anlg_cdc_hphr_dac_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER("ADC2", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("ADC3", SND_SOC_NOPM, 0, 0, NULL, 0), - - SND_SOC_DAPM_DAC("SPK DAC", NULL, MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, - 7, 0), - SND_SOC_DAPM_DAC_E("LINEOUT DAC", NULL, - SND_SOC_NOPM, 0, 0, msm_anlg_cdc_lo_dac_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SPK("Ext Spk", msm_anlg_cdc_codec_enable_spk_ext_pa), - - SND_SOC_DAPM_SWITCH("ADC1_INP1", SND_SOC_NOPM, 0, 0, - &adc1_switch), - SND_SOC_DAPM_SUPPLY("RX1 CLK", MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("RX2 CLK", MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 1, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("RX3 CLK", MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 2, 0, msm_anlg_cdc_codec_enable_dig_clk, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY("CP", MSM89XX_PMIC_ANALOG_NCP_EN, 0, 0, - msm_anlg_cdc_codec_enable_charge_pump, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY("EAR CP", MSM89XX_PMIC_ANALOG_NCP_EN, 4, 0, - msm_anlg_cdc_codec_enable_charge_pump, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY_S("RX_BIAS", 1, SND_SOC_NOPM, - 0, 0, msm_anlg_cdc_codec_enable_rx_bias, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY_S("SPK_RX_BIAS", 1, SND_SOC_NOPM, 0, 0, - msm_anlg_cdc_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY("VDD_SPKDRV", SND_SOC_NOPM, 0, 0, - sdm660_wcd_codec_enable_vdd_spkr, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY("INT_LDO_H", SND_SOC_NOPM, 1, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("MICBIAS_REGULATOR", SND_SOC_NOPM, - ON_DEMAND_MICBIAS, 0, - msm_anlg_cdc_codec_enable_on_demand_supply, - SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MICBIAS_E("MIC BIAS Internal1", - MSM89XX_PMIC_ANALOG_MICB_1_EN, 7, 0, - msm_anlg_cdc_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MICBIAS_E("MIC BIAS Internal2", - MSM89XX_PMIC_ANALOG_MICB_2_EN, 7, 0, - msm_anlg_cdc_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MICBIAS_E("MIC BIAS Internal3", - MSM89XX_PMIC_ANALOG_MICB_1_EN, 7, 0, - msm_anlg_cdc_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_ADC_E("ADC1", NULL, MSM89XX_PMIC_ANALOG_TX_1_EN, 7, 0, - msm_anlg_cdc_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("ADC2_INP2", - NULL, MSM89XX_PMIC_ANALOG_TX_2_EN, 7, 0, - msm_anlg_cdc_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("ADC2_INP3", - NULL, MSM89XX_PMIC_ANALOG_TX_3_EN, 7, 0, - msm_anlg_cdc_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MICBIAS_E("MIC BIAS External", - MSM89XX_PMIC_ANALOG_MICB_1_EN, 7, 0, - msm_anlg_cdc_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MICBIAS_E("MIC BIAS External2", - MSM89XX_PMIC_ANALOG_MICB_2_EN, 7, 0, - msm_anlg_cdc_codec_enable_micbias, SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_INPUT("AMIC1"), - SND_SOC_DAPM_INPUT("AMIC2"), - SND_SOC_DAPM_INPUT("AMIC3"), - SND_SOC_DAPM_AIF_IN("PDM_IN_RX1", "PDM Playback", - 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_IN("PDM_IN_RX2", "PDM Playback", - 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_IN("PDM_IN_RX3", "PDM Playback", - 0, SND_SOC_NOPM, 0, 0), - - SND_SOC_DAPM_OUTPUT("EAR"), - SND_SOC_DAPM_OUTPUT("WSA_SPK OUT"), - SND_SOC_DAPM_OUTPUT("HEADPHONE"), - SND_SOC_DAPM_OUTPUT("SPK_OUT"), - SND_SOC_DAPM_OUTPUT("LINEOUT"), - SND_SOC_DAPM_AIF_OUT("ADC1_OUT", "PDM Capture", - 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("ADC2_OUT", "PDM Capture", - 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("ADC3_OUT", "PDM Capture", - 0, SND_SOC_NOPM, 0, 0), -}; - -static const struct sdm660_cdc_reg_mask_val msm_anlg_cdc_reg_defaults[] = { - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x03), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x82), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1), -}; - -static const struct sdm660_cdc_reg_mask_val - msm_anlg_cdc_reg_defaults_2_0[] = { - MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0xA5), - MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x0F), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x4F), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0x28), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x69), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x01), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, 0x5F), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO, 0x88), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0xA5), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x0F), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x82), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x03), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1), - MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80), -}; - -static const struct sdm660_cdc_reg_mask_val conga_wcd_reg_defaults[] = { - MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0xA5), - MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x0F), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0xA5), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x0F), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x4C), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0x28), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x69), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x01), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_PERPH_SUBTYPE, 0x0A), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x03), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1), - MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80), -}; - -static const struct sdm660_cdc_reg_mask_val cajon_wcd_reg_defaults[] = { - MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0xA5), - MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x0F), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0xA5), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x0F), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x4C), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x82), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0xA8), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_VCTRL, 0xA4), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET, 0x41), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x69), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x01), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x03), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA, 0xFA), - MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80), -}; - -static const struct sdm660_cdc_reg_mask_val cajon2p0_wcd_reg_defaults[] = { - MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0xA5), - MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x0F), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0xA5), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x0F), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x4C), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0xA2), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0xA8), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_VCTRL, 0xA4), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET, 0x41), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x69), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x01), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x03), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_RX_EAR_STATUS, 0x10), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_BYPASS_MODE, 0x18), - MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA, 0xFA), - MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80), -}; - -static void msm_anlg_cdc_update_reg_defaults(struct snd_soc_codec *codec) -{ - u32 i, version; - struct sdm660_cdc_priv *sdm660_cdc = - snd_soc_codec_get_drvdata(codec); - - version = get_codec_version(sdm660_cdc); - if (version == TOMBAK_1_0) { - for (i = 0; i < ARRAY_SIZE(msm_anlg_cdc_reg_defaults); i++) - snd_soc_write(codec, msm_anlg_cdc_reg_defaults[i].reg, - msm_anlg_cdc_reg_defaults[i].val); - } else if (version == TOMBAK_2_0) { - for (i = 0; i < ARRAY_SIZE(msm_anlg_cdc_reg_defaults_2_0); i++) - snd_soc_write(codec, - msm_anlg_cdc_reg_defaults_2_0[i].reg, - msm_anlg_cdc_reg_defaults_2_0[i].val); - } else if (version == CONGA) { - for (i = 0; i < ARRAY_SIZE(conga_wcd_reg_defaults); i++) - snd_soc_write(codec, - conga_wcd_reg_defaults[i].reg, - conga_wcd_reg_defaults[i].val); - } else if (version == CAJON) { - for (i = 0; i < ARRAY_SIZE(cajon_wcd_reg_defaults); i++) - snd_soc_write(codec, - cajon_wcd_reg_defaults[i].reg, - cajon_wcd_reg_defaults[i].val); - } else if (version == CAJON_2_0 || version == DIANGU - || version == DRAX_CDC) { - for (i = 0; i < ARRAY_SIZE(cajon2p0_wcd_reg_defaults); i++) - snd_soc_write(codec, - cajon2p0_wcd_reg_defaults[i].reg, - cajon2p0_wcd_reg_defaults[i].val); - } -} - -static const struct sdm660_cdc_reg_mask_val - msm_anlg_cdc_codec_reg_init_val[] = { - - /* Initialize current threshold to 350MA - * number of wait and run cycles to 4096 - */ - {MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL, 0xFF, 0x12}, - {MSM89XX_PMIC_ANALOG_RX_COM_OCP_COUNT, 0xFF, 0xFF}, -}; - -static void msm_anlg_cdc_codec_init_reg(struct snd_soc_codec *codec) -{ - u32 i; - - for (i = 0; i < ARRAY_SIZE(msm_anlg_cdc_codec_reg_init_val); i++) - snd_soc_update_bits(codec, - msm_anlg_cdc_codec_reg_init_val[i].reg, - msm_anlg_cdc_codec_reg_init_val[i].mask, - msm_anlg_cdc_codec_reg_init_val[i].val); -} - -static int msm_anlg_cdc_bringup(struct snd_soc_codec *codec) -{ - snd_soc_write(codec, - MSM89XX_PMIC_DIGITAL_SEC_ACCESS, - 0xA5); - snd_soc_write(codec, MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4, 0x01); - snd_soc_write(codec, - MSM89XX_PMIC_ANALOG_SEC_ACCESS, - 0xA5); - snd_soc_write(codec, MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4, 0x01); - snd_soc_write(codec, - MSM89XX_PMIC_DIGITAL_SEC_ACCESS, - 0xA5); - snd_soc_write(codec, MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4, 0x00); - snd_soc_write(codec, - MSM89XX_PMIC_ANALOG_SEC_ACCESS, - 0xA5); - snd_soc_write(codec, MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4, 0x00); - - return 0; -} - -static struct regulator *msm_anlg_cdc_find_regulator( - const struct sdm660_cdc_priv *sdm660_cdc, - const char *name) -{ - int i; - - for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { - if (sdm660_cdc->supplies[i].supply && - !strcmp(sdm660_cdc->supplies[i].supply, name)) - return sdm660_cdc->supplies[i].consumer; - } - - dev_dbg(sdm660_cdc->dev, "Error: regulator not found:%s\n" - , name); - return NULL; -} - -static void msm_anlg_cdc_update_micbias_regulator( - const struct sdm660_cdc_priv *sdm660_cdc, - const char *name, - struct on_demand_supply *micbias_supply) -{ - int i; - struct sdm660_cdc_pdata *pdata = sdm660_cdc->dev->platform_data; - - for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { - if (sdm660_cdc->supplies[i].supply && - !strcmp(sdm660_cdc->supplies[i].supply, name)) { - micbias_supply->supply = - sdm660_cdc->supplies[i].consumer; - micbias_supply->min_uv = pdata->regulator[i].min_uv; - micbias_supply->max_uv = pdata->regulator[i].max_uv; - micbias_supply->optimum_ua = - pdata->regulator[i].optimum_ua; - return; - } - } - - dev_err(sdm660_cdc->dev, "Error: regulator not found:%s\n", name); -} - -static int msm_anlg_cdc_device_down(struct snd_soc_codec *codec) -{ - struct msm_asoc_mach_data *pdata = NULL; - struct sdm660_cdc_priv *sdm660_cdc_priv = - snd_soc_codec_get_drvdata(codec); - unsigned int tx_1_en; - unsigned int tx_2_en; - - pdata = snd_soc_card_get_drvdata(codec->component.card); - dev_dbg(codec->dev, "%s: device down!\n", __func__); - - tx_1_en = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_TX_1_EN); - tx_2_en = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_TX_2_EN); - tx_1_en = tx_1_en & 0x7f; - tx_2_en = tx_2_en & 0x7f; - snd_soc_write(codec, - MSM89XX_PMIC_ANALOG_TX_1_EN, tx_1_en); - snd_soc_write(codec, - MSM89XX_PMIC_ANALOG_TX_2_EN, tx_2_en); - if (sdm660_cdc_priv->boost_option == BOOST_ON_FOREVER) { - if ((snd_soc_read(codec, MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL) - & 0x80) == 0) { - msm_anlg_cdc_dig_notifier_call(codec, - DIG_CDC_EVENT_CLK_ON); - snd_soc_write(codec, - MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, 0x30); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80, 0x80); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL, - 0x0C, 0x0C); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, - 0x84, 0x84); - snd_soc_update_bits(codec, - MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, - 0x10, 0x10); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, - 0x1F, 0x1F); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, - 0x90, 0x90); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_RX_EAR_CTL, - 0xFF, 0xFF); - /* Wait for 20us for boost settings to take effect */ - usleep_range(20, 21); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, - 0xFF, 0xFF); - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, - 0xE9, 0xE9); - } - } - msm_anlg_cdc_boost_off(codec); - sdm660_cdc_priv->hph_mode = NORMAL_MODE; - - /* 40ms to allow boost to discharge */ - msleep(40); - /* Disable PA to avoid pop during codec bring up */ - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, - 0x30, 0x00); - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, - 0x80, 0x00); - snd_soc_write(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x20); - snd_soc_write(codec, - MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x20); - snd_soc_write(codec, - MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x12); - snd_soc_write(codec, - MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x93); - - msm_anlg_cdc_dig_notifier_call(codec, DIG_CDC_EVENT_SSR_DOWN); - atomic_set(&pdata->int_mclk0_enabled, false); - set_bit(BUS_DOWN, &sdm660_cdc_priv->status_mask); - snd_soc_card_change_online_state(codec->component.card, 0); - - return 0; -} - -static int msm_anlg_cdc_device_up(struct snd_soc_codec *codec) -{ - struct sdm660_cdc_priv *sdm660_cdc_priv = - snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s: device up!\n", __func__); - - msm_anlg_cdc_dig_notifier_call(codec, DIG_CDC_EVENT_SSR_UP); - clear_bit(BUS_DOWN, &sdm660_cdc_priv->status_mask); - snd_soc_card_change_online_state(codec->component.card, 1); - /* delay is required to make sure sound card state updated */ - usleep_range(5000, 5100); - - snd_soc_write(codec, MSM89XX_PMIC_DIGITAL_INT_EN_SET, - MSM89XX_PMIC_DIGITAL_INT_EN_SET__POR); - snd_soc_write(codec, MSM89XX_PMIC_DIGITAL_INT_EN_CLR, - MSM89XX_PMIC_DIGITAL_INT_EN_CLR__POR); - - msm_anlg_cdc_set_boost_v(codec); - msm_anlg_cdc_set_micb_v(codec); - if (sdm660_cdc_priv->boost_option == BOOST_ON_FOREVER) - msm_anlg_cdc_boost_on(codec); - else if (sdm660_cdc_priv->boost_option == BYPASS_ALWAYS) - msm_anlg_cdc_bypass_on(codec); - - return 0; -} - -static int sdm660_cdc_notifier_service_cb(struct notifier_block *nb, - unsigned long opcode, void *ptr) -{ - struct snd_soc_codec *codec; - struct sdm660_cdc_priv *sdm660_cdc_priv = - container_of(nb, struct sdm660_cdc_priv, - audio_ssr_nb); - bool adsp_ready = false; - bool timedout; - unsigned long timeout; - static bool initial_boot = true; - - codec = sdm660_cdc_priv->codec; - dev_dbg(codec->dev, "%s: Service opcode 0x%lx\n", __func__, opcode); - - switch (opcode) { - case AUDIO_NOTIFIER_SERVICE_DOWN: - if (initial_boot) { - initial_boot = false; - break; - } - dev_dbg(codec->dev, - "ADSP is about to power down. teardown/reset codec\n"); - msm_anlg_cdc_device_down(codec); - break; - case AUDIO_NOTIFIER_SERVICE_UP: - if (initial_boot) - initial_boot = false; - dev_dbg(codec->dev, - "ADSP is about to power up. bring up codec\n"); - - if (!q6core_is_adsp_ready()) { - dev_dbg(codec->dev, - "ADSP isn't ready\n"); - timeout = jiffies + - msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); - while (!(timedout = time_after(jiffies, timeout))) { - if (!q6core_is_adsp_ready()) { - dev_dbg(codec->dev, - "ADSP isn't ready\n"); - } else { - dev_dbg(codec->dev, - "ADSP is ready\n"); - adsp_ready = true; - goto powerup; - } - } - } else { - adsp_ready = true; - dev_dbg(codec->dev, "%s: DSP is ready\n", __func__); - } -powerup: - if (adsp_ready) - msm_anlg_cdc_device_up(codec); - break; - default: - break; - } - return NOTIFY_OK; -} - -int msm_anlg_cdc_hs_detect(struct snd_soc_codec *codec, - struct wcd_mbhc_config *mbhc_cfg) -{ - struct sdm660_cdc_priv *sdm660_cdc_priv = - snd_soc_codec_get_drvdata(codec); - - return wcd_mbhc_start(&sdm660_cdc_priv->mbhc, mbhc_cfg); -} -EXPORT_SYMBOL(msm_anlg_cdc_hs_detect); - -void msm_anlg_cdc_hs_detect_exit(struct snd_soc_codec *codec) -{ - struct sdm660_cdc_priv *sdm660_cdc_priv = - snd_soc_codec_get_drvdata(codec); - - wcd_mbhc_stop(&sdm660_cdc_priv->mbhc); -} -EXPORT_SYMBOL(msm_anlg_cdc_hs_detect_exit); - -void msm_anlg_cdc_update_int_spk_boost(bool enable) -{ - pr_debug("%s: enable = %d\n", __func__, enable); - spkr_boost_en = enable; -} -EXPORT_SYMBOL(msm_anlg_cdc_update_int_spk_boost); - -static void msm_anlg_cdc_set_micb_v(struct snd_soc_codec *codec) -{ - - struct sdm660_cdc_priv *sdm660_cdc = snd_soc_codec_get_drvdata(codec); - struct sdm660_cdc_pdata *pdata = sdm660_cdc->dev->platform_data; - u8 reg_val; - - reg_val = VOLTAGE_CONVERTER(pdata->micbias.cfilt1_mv, MICBIAS_MIN_VAL, - MICBIAS_STEP_SIZE); - dev_dbg(codec->dev, "cfilt1_mv %d reg_val %x\n", - (u32)pdata->micbias.cfilt1_mv, reg_val); - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_MICB_1_VAL, - 0xF8, (reg_val << 3)); -} - -static void msm_anlg_cdc_set_boost_v(struct snd_soc_codec *codec) -{ - struct sdm660_cdc_priv *sdm660_cdc_priv = - snd_soc_codec_get_drvdata(codec); - - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_OUTPUT_VOLTAGE, - 0x1F, sdm660_cdc_priv->boost_voltage); -} - -static void msm_anlg_cdc_configure_cap(struct snd_soc_codec *codec, - bool micbias1, bool micbias2) -{ - - struct msm_asoc_mach_data *pdata = NULL; - - pdata = snd_soc_card_get_drvdata(codec->component.card); - - pr_debug("\n %s: micbias1 %x micbias2 = %d\n", __func__, micbias1, - micbias2); - if (micbias1 && micbias2) { - if ((pdata->micbias1_cap_mode - == MICBIAS_EXT_BYP_CAP) || - (pdata->micbias2_cap_mode - == MICBIAS_EXT_BYP_CAP)) - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MICB_1_EN, - 0x40, (MICBIAS_EXT_BYP_CAP << 6)); - else - snd_soc_update_bits(codec, - MSM89XX_PMIC_ANALOG_MICB_1_EN, - 0x40, (MICBIAS_NO_EXT_BYP_CAP << 6)); - } else if (micbias2) { - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_MICB_1_EN, - 0x40, (pdata->micbias2_cap_mode << 6)); - } else if (micbias1) { - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_MICB_1_EN, - 0x40, (pdata->micbias1_cap_mode << 6)); - } else { - snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_MICB_1_EN, - 0x40, 0x00); - } -} - -static ssize_t msm_anlg_codec_version_read(struct snd_info_entry *entry, - void *file_private_data, - struct file *file, - char __user *buf, size_t count, - loff_t pos) -{ - struct sdm660_cdc_priv *sdm660_cdc_priv; - char buffer[MSM_ANLG_CDC_VERSION_ENTRY_SIZE]; - int len = 0; - - sdm660_cdc_priv = (struct sdm660_cdc_priv *) entry->private_data; - if (!sdm660_cdc_priv) { - pr_err("%s: sdm660_cdc_priv is null\n", __func__); - return -EINVAL; - } - - switch (get_codec_version(sdm660_cdc_priv)) { - case DRAX_CDC: - len = snprintf(buffer, sizeof(buffer), "DRAX-CDC_1_0\n"); - break; - default: - len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); - } - - return simple_read_from_buffer(buf, count, &pos, buffer, len); -} - -static struct snd_info_entry_ops msm_anlg_codec_info_ops = { - .read = msm_anlg_codec_version_read, -}; - -/* - * msm_anlg_codec_info_create_codec_entry - creates pmic_analog module - * @codec_root: The parent directory - * @codec: Codec instance - * - * Creates pmic_analog module and version entry under the given - * parent directory. - * - * Return: 0 on success or negative error code on failure. - */ -int msm_anlg_codec_info_create_codec_entry(struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) -{ - struct snd_info_entry *version_entry; - struct sdm660_cdc_priv *sdm660_cdc_priv; - struct snd_soc_card *card; - int ret; - - if (!codec_root || !codec) - return -EINVAL; - - sdm660_cdc_priv = snd_soc_codec_get_drvdata(codec); - card = codec->component.card; - sdm660_cdc_priv->entry = snd_info_create_subdir(codec_root->module, - "spmi0-03", - codec_root); - if (!sdm660_cdc_priv->entry) { - dev_dbg(codec->dev, "%s: failed to create pmic_analog entry\n", - __func__); - return -ENOMEM; - } - - version_entry = snd_info_create_card_entry(card->snd_card, - "version", - sdm660_cdc_priv->entry); - if (!version_entry) { - dev_dbg(codec->dev, "%s: failed to create pmic_analog version entry\n", - __func__); - return -ENOMEM; - } - - version_entry->private_data = sdm660_cdc_priv; - version_entry->size = MSM_ANLG_CDC_VERSION_ENTRY_SIZE; - version_entry->content = SNDRV_INFO_CONTENT_DATA; - version_entry->c.ops = &msm_anlg_codec_info_ops; - - if (snd_info_register(version_entry) < 0) { - snd_info_free_entry(version_entry); - return -ENOMEM; - } - sdm660_cdc_priv->version_entry = version_entry; - - sdm660_cdc_priv->audio_ssr_nb.notifier_call = - sdm660_cdc_notifier_service_cb; - ret = audio_notifier_register("pmic_analog_cdc", - AUDIO_NOTIFIER_ADSP_DOMAIN, - &sdm660_cdc_priv->audio_ssr_nb); - if (ret < 0) { - pr_err("%s: Audio notifier register failed ret = %d\n", - __func__, ret); - return ret; - } - return 0; -} -EXPORT_SYMBOL(msm_anlg_codec_info_create_codec_entry); - -static int msm_anlg_cdc_soc_probe(struct snd_soc_codec *codec) -{ - struct sdm660_cdc_priv *sdm660_cdc; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - int ret; - - sdm660_cdc = dev_get_drvdata(codec->dev); - sdm660_cdc->codec = codec; - - /* codec resmgr module init */ - sdm660_cdc->spkdrv_reg = - msm_anlg_cdc_find_regulator(sdm660_cdc, - MSM89XX_VDD_SPKDRV_NAME); - sdm660_cdc->pmic_rev = - snd_soc_read(codec, - MSM89XX_PMIC_DIGITAL_REVISION1); - sdm660_cdc->codec_version = - snd_soc_read(codec, - MSM89XX_PMIC_DIGITAL_PERPH_SUBTYPE); - sdm660_cdc->analog_major_rev = - snd_soc_read(codec, - MSM89XX_PMIC_ANALOG_REVISION4); - - if (sdm660_cdc->codec_version == CONGA) { - dev_dbg(codec->dev, "%s :Conga REV: %d\n", __func__, - sdm660_cdc->codec_version); - sdm660_cdc->ext_spk_boost_set = true; - } else { - dev_dbg(codec->dev, "%s :PMIC REV: %d\n", __func__, - sdm660_cdc->pmic_rev); - if (sdm660_cdc->pmic_rev == TOMBAK_1_0 && - sdm660_cdc->codec_version == CAJON_2_0) { - if (sdm660_cdc->analog_major_rev == 0x02) { - sdm660_cdc->codec_version = DRAX_CDC; - dev_dbg(codec->dev, - "%s : Drax codec detected\n", __func__); - } else { - sdm660_cdc->codec_version = DIANGU; - dev_dbg(codec->dev, "%s : Diangu detected\n", - __func__); - } - } else if (sdm660_cdc->pmic_rev == TOMBAK_1_0 && - (snd_soc_read(codec, MSM89XX_PMIC_ANALOG_NCP_FBCTRL) - & 0x80)) { - sdm660_cdc->codec_version = CAJON; - dev_dbg(codec->dev, "%s : Cajon detected\n", __func__); - } else if (sdm660_cdc->pmic_rev == TOMBAK_2_0 && - (snd_soc_read(codec, MSM89XX_PMIC_ANALOG_NCP_FBCTRL) - & 0x80)) { - sdm660_cdc->codec_version = CAJON_2_0; - dev_dbg(codec->dev, "%s : Cajon 2.0 detected\n", - __func__); - } - } - /* - * set to default boost option BOOST_SWITCH, user mixer path can change - * it to BOOST_ALWAYS or BOOST_BYPASS based on solution chosen. - */ - sdm660_cdc->boost_option = BOOST_SWITCH; - sdm660_cdc->hph_mode = NORMAL_MODE; - - msm_anlg_cdc_dt_parse_boost_info(codec); - msm_anlg_cdc_set_boost_v(codec); - - snd_soc_add_codec_controls(codec, impedance_detect_controls, - ARRAY_SIZE(impedance_detect_controls)); - snd_soc_add_codec_controls(codec, hph_type_detect_controls, - ARRAY_SIZE(hph_type_detect_controls)); - - msm_anlg_cdc_bringup(codec); - msm_anlg_cdc_codec_init_reg(codec); - msm_anlg_cdc_update_reg_defaults(codec); - - wcd9xxx_spmi_set_codec(codec); - - msm_anlg_cdc_update_micbias_regulator( - sdm660_cdc, - on_demand_supply_name[ON_DEMAND_MICBIAS], - &sdm660_cdc->on_demand_list[ON_DEMAND_MICBIAS]); - atomic_set(&sdm660_cdc->on_demand_list[ON_DEMAND_MICBIAS].ref, - 0); - - sdm660_cdc->fw_data = devm_kzalloc(codec->dev, - sizeof(*(sdm660_cdc->fw_data)), - GFP_KERNEL); - if (!sdm660_cdc->fw_data) - return -ENOMEM; - - set_bit(WCD9XXX_MBHC_CAL, sdm660_cdc->fw_data->cal_bit); - ret = wcd_cal_create_hwdep(sdm660_cdc->fw_data, - WCD9XXX_CODEC_HWDEP_NODE, codec); - if (ret < 0) { - dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret); - return ret; - } - - wcd_mbhc_init(&sdm660_cdc->mbhc, codec, &mbhc_cb, &intr_ids, - wcd_mbhc_registers, true); - - sdm660_cdc->int_mclk0_enabled = false; - /*Update speaker boost configuration*/ - sdm660_cdc->spk_boost_set = spkr_boost_en; - pr_debug("%s: speaker boost configured = %d\n", - __func__, sdm660_cdc->spk_boost_set); - - /* Set initial MICBIAS voltage level */ - msm_anlg_cdc_set_micb_v(codec); - - /* Set initial cap mode */ - msm_anlg_cdc_configure_cap(codec, false, false); - - snd_soc_dapm_ignore_suspend(dapm, "PDM Playback"); - snd_soc_dapm_ignore_suspend(dapm, "PDM Capture"); - - snd_soc_dapm_sync(dapm); - - return 0; -} - -static int msm_anlg_cdc_soc_remove(struct snd_soc_codec *codec) -{ - struct sdm660_cdc_priv *sdm660_cdc_priv = - dev_get_drvdata(codec->dev); - - sdm660_cdc_priv->spkdrv_reg = NULL; - sdm660_cdc_priv->on_demand_list[ON_DEMAND_MICBIAS].supply = NULL; - atomic_set(&sdm660_cdc_priv->on_demand_list[ON_DEMAND_MICBIAS].ref, - 0); - wcd_mbhc_deinit(&sdm660_cdc_priv->mbhc); - - return 0; -} - -static int msm_anlg_cdc_enable_static_supplies_to_optimum( - struct sdm660_cdc_priv *sdm660_cdc, - struct sdm660_cdc_pdata *pdata) -{ - int i; - int ret = 0, rc = 0; - - for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { - if (pdata->regulator[i].ondemand) - continue; - if (regulator_count_voltages( - sdm660_cdc->supplies[i].consumer) <= 0) - continue; - - rc = regulator_enable(sdm660_cdc->supplies[i].consumer); - if (rc) { - dev_err(sdm660_cdc->dev, "Failed to enable %s: %d\n", - sdm660_cdc->supplies[i].supply, rc); - break; - } - ret = regulator_set_voltage( - sdm660_cdc->supplies[i].consumer, - pdata->regulator[i].min_uv, - pdata->regulator[i].max_uv); - if (ret) { - dev_err(sdm660_cdc->dev, - "Setting volt failed for regulator %s err %d\n", - sdm660_cdc->supplies[i].supply, ret); - } - - ret = regulator_set_load(sdm660_cdc->supplies[i].consumer, - pdata->regulator[i].optimum_ua); - dev_dbg(sdm660_cdc->dev, "Regulator %s set optimum mode\n", - sdm660_cdc->supplies[i].supply); - } - - while (rc && i--) - if (!pdata->regulator[i].ondemand) - regulator_disable(sdm660_cdc->supplies[i].consumer); - return rc; -} - -static int msm_anlg_cdc_disable_static_supplies_to_optimum( - struct sdm660_cdc_priv *sdm660_cdc, - struct sdm660_cdc_pdata *pdata) -{ - int i; - int ret = 0; - - for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { - if (pdata->regulator[i].ondemand) - continue; - if (regulator_count_voltages( - sdm660_cdc->supplies[i].consumer) <= 0) - continue; - regulator_set_voltage(sdm660_cdc->supplies[i].consumer, 0, - pdata->regulator[i].max_uv); - regulator_set_load(sdm660_cdc->supplies[i].consumer, 0); - ret = regulator_disable(sdm660_cdc->supplies[i].consumer); - if (ret) - dev_err(sdm660_cdc->dev, "Failed to disable %s: %d\n", - sdm660_cdc->supplies[i].supply, ret); - - dev_dbg(sdm660_cdc->dev, "Regulator %s disable\n", - sdm660_cdc->supplies[i].supply); - } - - return ret; -} - -static int msm_anlg_cdc_suspend(struct snd_soc_codec *codec) -{ - struct sdm660_cdc_priv *sdm660_cdc = snd_soc_codec_get_drvdata(codec); - struct sdm660_cdc_pdata *sdm660_cdc_pdata = - sdm660_cdc->dev->platform_data; - - msm_anlg_cdc_disable_static_supplies_to_optimum(sdm660_cdc, - sdm660_cdc_pdata); - return 0; -} - -static int msm_anlg_cdc_resume(struct snd_soc_codec *codec) -{ - struct msm_asoc_mach_data *pdata = NULL; - struct sdm660_cdc_priv *sdm660_cdc = snd_soc_codec_get_drvdata(codec); - struct sdm660_cdc_pdata *sdm660_cdc_pdata = - sdm660_cdc->dev->platform_data; - - pdata = snd_soc_card_get_drvdata(codec->component.card); - msm_anlg_cdc_enable_static_supplies_to_optimum(sdm660_cdc, - sdm660_cdc_pdata); - return 0; -} - -static struct regmap *msm_anlg_get_regmap(struct device *dev) -{ - return dev_get_regmap(dev->parent, NULL); -} - -static struct snd_soc_codec_driver soc_codec_dev_sdm660_cdc = { - .probe = msm_anlg_cdc_soc_probe, - .remove = msm_anlg_cdc_soc_remove, - .suspend = msm_anlg_cdc_suspend, - .resume = msm_anlg_cdc_resume, - .reg_word_size = 1, - .get_regmap = msm_anlg_get_regmap, - .component_driver = { - .controls = msm_anlg_cdc_snd_controls, - .num_controls = ARRAY_SIZE(msm_anlg_cdc_snd_controls), - .dapm_widgets = msm_anlg_cdc_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(msm_anlg_cdc_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), - }, -}; - -static int msm_anlg_cdc_init_supplies(struct sdm660_cdc_priv *sdm660_cdc, - struct sdm660_cdc_pdata *pdata) -{ - int ret; - int i; - - sdm660_cdc->supplies = devm_kzalloc(sdm660_cdc->dev, - sizeof(struct regulator_bulk_data) * - ARRAY_SIZE(pdata->regulator), - GFP_KERNEL); - if (!sdm660_cdc->supplies) { - ret = -ENOMEM; - goto err; - } - - sdm660_cdc->num_of_supplies = 0; - if (ARRAY_SIZE(pdata->regulator) > MAX_REGULATOR) { - dev_err(sdm660_cdc->dev, "%s: Array Size out of bound\n", - __func__); - ret = -EINVAL; - goto err; - } - - for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) { - if (pdata->regulator[i].name) { - sdm660_cdc->supplies[i].supply = - pdata->regulator[i].name; - sdm660_cdc->num_of_supplies++; - } - } - - ret = devm_regulator_bulk_get(sdm660_cdc->dev, - sdm660_cdc->num_of_supplies, - sdm660_cdc->supplies); - if (ret != 0) { - dev_err(sdm660_cdc->dev, - "Failed to get supplies: err = %d\n", - ret); - goto err_supplies; - } - - for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { - if (regulator_count_voltages( - sdm660_cdc->supplies[i].consumer) <= 0) - continue; - if (pdata->regulator[i].ondemand) { - ret = regulator_set_voltage( - sdm660_cdc->supplies[i].consumer, - 0, pdata->regulator[i].max_uv); - if (ret) { - dev_err(sdm660_cdc->dev, - "Setting regulator voltage failed for regulator %s err = %d\n", - sdm660_cdc->supplies[i].supply, ret); - goto err_supplies; - } - ret = regulator_set_load( - sdm660_cdc->supplies[i].consumer, 0); - if (ret < 0) { - dev_err(sdm660_cdc->dev, - "Setting regulator optimum mode failed for regulator %s err = %d\n", - sdm660_cdc->supplies[i].supply, ret); - goto err_supplies; - } else { - ret = 0; - continue; - } - } - ret = regulator_set_voltage(sdm660_cdc->supplies[i].consumer, - pdata->regulator[i].min_uv, - pdata->regulator[i].max_uv); - if (ret) { - dev_err(sdm660_cdc->dev, - "Setting regulator voltage failed for regulator %s err = %d\n", - sdm660_cdc->supplies[i].supply, ret); - goto err_supplies; - } - ret = regulator_set_load(sdm660_cdc->supplies[i].consumer, - pdata->regulator[i].optimum_ua); - if (ret < 0) { - dev_err(sdm660_cdc->dev, - "Setting regulator optimum mode failed for regulator %s err = %d\n", - sdm660_cdc->supplies[i].supply, ret); - goto err_supplies; - } else { - ret = 0; - } - } - - return ret; - -err_supplies: - devm_kfree(sdm660_cdc->dev, sdm660_cdc->supplies); -err: - return ret; -} - -static int msm_anlg_cdc_enable_static_supplies( - struct sdm660_cdc_priv *sdm660_cdc, - struct sdm660_cdc_pdata *pdata) -{ - int i; - int ret = 0; - - for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { - if (pdata->regulator[i].ondemand) - continue; - ret = regulator_enable(sdm660_cdc->supplies[i].consumer); - if (ret) { - dev_err(sdm660_cdc->dev, "Failed to enable %s\n", - sdm660_cdc->supplies[i].supply); - break; - } - dev_dbg(sdm660_cdc->dev, "Enabled regulator %s\n", - sdm660_cdc->supplies[i].supply); - } - - while (ret && i--) - if (!pdata->regulator[i].ondemand) - regulator_disable(sdm660_cdc->supplies[i].consumer); - return ret; -} - -static void msm_anlg_cdc_disable_supplies(struct sdm660_cdc_priv *sdm660_cdc, - struct sdm660_cdc_pdata *pdata) -{ - int i; - - regulator_bulk_disable(sdm660_cdc->num_of_supplies, - sdm660_cdc->supplies); - for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { - if (regulator_count_voltages( - sdm660_cdc->supplies[i].consumer) <= 0) - continue; - regulator_set_voltage(sdm660_cdc->supplies[i].consumer, 0, - pdata->regulator[i].max_uv); - regulator_set_load(sdm660_cdc->supplies[i].consumer, 0); - } -} - -static const struct of_device_id sdm660_codec_of_match[] = { - { .compatible = "qcom,pmic-analog-codec", }, - {}, -}; - -static void msm_anlg_add_child_devices(struct work_struct *work) -{ - struct sdm660_cdc_priv *pdata; - struct platform_device *pdev; - struct device_node *node; - struct msm_dig_ctrl_data *dig_ctrl_data = NULL, *temp; - int ret, ctrl_num = 0; - struct msm_dig_ctrl_platform_data *platdata; - char plat_dev_name[MSM_DIG_CDC_STRING_LEN]; - - pdata = container_of(work, struct sdm660_cdc_priv, - msm_anlg_add_child_devices_work); - if (!pdata) { - pr_err("%s: Memory for pdata does not exist\n", - __func__); - return; - } - if (!pdata->dev->of_node) { - dev_err(pdata->dev, - "%s: DT node for pdata does not exist\n", __func__); - return; - } - - platdata = &pdata->dig_plat_data; - - for_each_child_of_node(pdata->dev->of_node, node) { - if (!strcmp(node->name, "msm-dig-codec")) - strlcpy(plat_dev_name, "msm_digital_codec", - (MSM_DIG_CDC_STRING_LEN - 1)); - else - continue; - - pdev = platform_device_alloc(plat_dev_name, -1); - if (!pdev) { - dev_err(pdata->dev, "%s: pdev memory alloc failed\n", - __func__); - ret = -ENOMEM; - goto err; - } - pdev->dev.parent = pdata->dev; - pdev->dev.of_node = node; - - if (!strcmp(node->name, "msm-dig-codec")) { - ret = platform_device_add_data(pdev, platdata, - sizeof(*platdata)); - if (ret) { - dev_err(&pdev->dev, - "%s: cannot add plat data ctrl:%d\n", - __func__, ctrl_num); - goto fail_pdev_add; - } - } - - ret = platform_device_add(pdev); - if (ret) { - dev_err(&pdev->dev, - "%s: Cannot add platform device\n", - __func__); - goto fail_pdev_add; - } - - if (!strcmp(node->name, "msm-dig-codec")) { - temp = krealloc(dig_ctrl_data, - (ctrl_num + 1) * sizeof( - struct msm_dig_ctrl_data), - GFP_KERNEL); - if (!temp) { - dev_err(&pdev->dev, "out of memory\n"); - ret = -ENOMEM; - goto err; - } - dig_ctrl_data = temp; - dig_ctrl_data[ctrl_num].dig_pdev = pdev; - ctrl_num++; - dev_dbg(&pdev->dev, - "%s: Added digital codec device(s)\n", - __func__); - pdata->dig_ctrl_data = dig_ctrl_data; - } - pdata->pdev_child_devices[pdata->child_count++] = pdev; - } - - return; -fail_pdev_add: - platform_device_put(pdev); -err: - return; -} - -static int msm_anlg_cdc_probe(struct platform_device *pdev) -{ - int ret = 0; - struct sdm660_cdc_priv *sdm660_cdc = NULL; - struct sdm660_cdc_pdata *pdata; - int adsp_state; - - adsp_state = apr_get_subsys_state(); - if (adsp_state != APR_SUBSYS_LOADED) { - dev_err(&pdev->dev, "Adsp is not loaded yet %d\n", - adsp_state); - return -EPROBE_DEFER; - } - device_init_wakeup(&pdev->dev, true); - - if (pdev->dev.of_node) { - dev_dbg(&pdev->dev, "%s:Platform data from device tree\n", - __func__); - pdata = msm_anlg_cdc_populate_dt_pdata(&pdev->dev); - pdev->dev.platform_data = pdata; - } else { - dev_dbg(&pdev->dev, "%s:Platform data from board file\n", - __func__); - pdata = pdev->dev.platform_data; - } - if (pdata == NULL) { - dev_err(&pdev->dev, "%s:Platform data failed to populate\n", - __func__); - goto rtn; - } - sdm660_cdc = devm_kzalloc(&pdev->dev, sizeof(struct sdm660_cdc_priv), - GFP_KERNEL); - if (sdm660_cdc == NULL) { - ret = -ENOMEM; - goto rtn; - } - - sdm660_cdc->dev = &pdev->dev; - ret = msm_anlg_cdc_init_supplies(sdm660_cdc, pdata); - if (ret) { - dev_err(&pdev->dev, "%s: Fail to enable Codec supplies\n", - __func__); - goto rtn; - } - ret = msm_anlg_cdc_enable_static_supplies(sdm660_cdc, pdata); - if (ret) { - dev_err(&pdev->dev, - "%s: Fail to enable Codec pre-reset supplies\n", - __func__); - goto rtn; - } - /* Allow supplies to be ready */ - usleep_range(5, 6); - - wcd9xxx_spmi_set_dev(pdev, 0); - wcd9xxx_spmi_set_dev(pdev, 1); - if (wcd9xxx_spmi_irq_init()) { - dev_err(&pdev->dev, - "%s: irq initialization failed\n", __func__); - } else { - dev_dbg(&pdev->dev, - "%s: irq initialization passed\n", __func__); - } - dev_set_drvdata(&pdev->dev, sdm660_cdc); - - ret = snd_soc_register_codec(&pdev->dev, - &soc_codec_dev_sdm660_cdc, - msm_anlg_cdc_i2s_dai, - ARRAY_SIZE(msm_anlg_cdc_i2s_dai)); - if (ret) { - dev_err(&pdev->dev, - "%s:snd_soc_register_codec failed with error %d\n", - __func__, ret); - goto err_supplies; - } - BLOCKING_INIT_NOTIFIER_HEAD(&sdm660_cdc->notifier); - BLOCKING_INIT_NOTIFIER_HEAD(&sdm660_cdc->notifier_mbhc); - - sdm660_cdc->dig_plat_data.handle = (void *) sdm660_cdc; - sdm660_cdc->dig_plat_data.set_compander_mode = set_compander_mode; - sdm660_cdc->dig_plat_data.update_clkdiv = update_clkdiv; - sdm660_cdc->dig_plat_data.get_cdc_version = get_cdc_version; - sdm660_cdc->dig_plat_data.register_notifier = - msm_anlg_cdc_dig_register_notifier; - INIT_WORK(&sdm660_cdc->msm_anlg_add_child_devices_work, - msm_anlg_add_child_devices); - schedule_work(&sdm660_cdc->msm_anlg_add_child_devices_work); - - return ret; -err_supplies: - msm_anlg_cdc_disable_supplies(sdm660_cdc, pdata); -rtn: - return ret; -} - -static int msm_anlg_cdc_remove(struct platform_device *pdev) -{ - struct sdm660_cdc_priv *sdm660_cdc = dev_get_drvdata(&pdev->dev); - struct sdm660_cdc_pdata *pdata = sdm660_cdc->dev->platform_data; - int count; - - for (count = 0; count < sdm660_cdc->child_count && - count < ANLG_CDC_CHILD_DEVICES_MAX; count++) - platform_device_unregister( - sdm660_cdc->pdev_child_devices[count]); - snd_soc_unregister_codec(&pdev->dev); - msm_anlg_cdc_disable_supplies(sdm660_cdc, pdata); - wcd9xxx_spmi_irq_exit(); - devm_kfree(&pdev->dev, sdm660_cdc); - return 0; -} - -static struct platform_driver msm_anlg_codec_driver = { - .driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, - .of_match_table = of_match_ptr(sdm660_codec_of_match) - }, - .probe = msm_anlg_cdc_probe, - .remove = msm_anlg_cdc_remove, -}; -module_platform_driver(msm_anlg_codec_driver); - -MODULE_DESCRIPTION("MSM Audio Analog codec driver"); -MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.h b/asoc/codecs/sdm660_cdc/msm-analog-cdc.h deleted file mode 100644 index 71d555f38846..000000000000 --- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.h +++ /dev/null @@ -1,273 +0,0 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef MSM_ANALOG_CDC_H -#define MSM_ANALOG_CDC_H - -#include -#include -#include -#include "../wcd-mbhc-v2.h" -#include "../wcdcal-hwdep.h" -#include "sdm660-cdc-registers.h" - -#define MICBIAS_EXT_BYP_CAP 0x00 -#define MICBIAS_NO_EXT_BYP_CAP 0x01 -#define ANLG_CDC_CHILD_DEVICES_MAX 1 - -#define MSM89XX_NUM_IRQ_REGS 2 -#define MAX_REGULATOR 7 -#define MSM89XX_REG_VAL(reg, val) {reg, 0, val} - -#define MSM89XX_VDD_SPKDRV_NAME "cdc-vdd-spkdrv" - -#define DEFAULT_MULTIPLIER 800 -#define DEFAULT_GAIN 9 -#define DEFAULT_OFFSET 100 - -extern const u8 msm89xx_pmic_cdc_reg_readable[MSM89XX_PMIC_CDC_CACHE_SIZE]; -extern const u8 msm89xx_cdc_core_reg_readable[MSM89XX_CDC_CORE_CACHE_SIZE]; -extern struct regmap_config msm89xx_cdc_core_regmap_config; -extern struct regmap_config msm89xx_pmic_cdc_regmap_config; - -enum wcd_curr_ref { - I_h4_UA = 0, - I_pt5_UA, - I_14_UA, - I_l4_UA, - I_1_UA, -}; - -enum wcd_mbhc_imp_det_pin { - WCD_MBHC_DET_NONE = 0, - WCD_MBHC_DET_HPHL, - WCD_MBHC_DET_HPHR, - WCD_MBHC_DET_BOTH, -}; - - -/* Each micbias can be assigned to one of three cfilters - * Vbatt_min >= .15V + ldoh_v - * ldoh_v >= .15v + cfiltx_mv - * If ldoh_v = 1.95 160 mv < cfiltx_mv < 1800 mv - * If ldoh_v = 2.35 200 mv < cfiltx_mv < 2200 mv - * If ldoh_v = 2.75 240 mv < cfiltx_mv < 2600 mv - * If ldoh_v = 2.85 250 mv < cfiltx_mv < 2700 mv - */ - -struct wcd_micbias_setting { - u8 ldoh_v; - u32 cfilt1_mv; /* in mv */ - u32 cfilt2_mv; /* in mv */ - u32 cfilt3_mv; /* in mv */ - /* Different WCD9xxx series codecs may not - * have 4 mic biases. If a codec has fewer - * mic biases, some of these properties will - * not be used. - */ - u8 bias1_cfilt_sel; - u8 bias2_cfilt_sel; - u8 bias3_cfilt_sel; - u8 bias4_cfilt_sel; - u8 bias1_cap_mode; - u8 bias2_cap_mode; - u8 bias3_cap_mode; - u8 bias4_cap_mode; - bool bias2_is_headset_only; -}; - -enum sdm660_cdc_pid_current { - MSM89XX_PID_MIC_2P5_UA, - MSM89XX_PID_MIC_5_UA, - MSM89XX_PID_MIC_10_UA, - MSM89XX_PID_MIC_20_UA, -}; - -struct sdm660_cdc_reg_mask_val { - u16 reg; - u8 mask; - u8 val; -}; - -enum { - /* INTR_REG 0 - Digital Periph */ - MSM89XX_IRQ_SPKR_CNP = 0, - MSM89XX_IRQ_SPKR_CLIP, - MSM89XX_IRQ_SPKR_OCP, - MSM89XX_IRQ_MBHC_INSREM_DET1, - MSM89XX_IRQ_MBHC_RELEASE, - MSM89XX_IRQ_MBHC_PRESS, - MSM89XX_IRQ_MBHC_INSREM_DET, - MSM89XX_IRQ_MBHC_HS_DET, - /* INTR_REG 1 - Analog Periph */ - MSM89XX_IRQ_EAR_OCP, - MSM89XX_IRQ_HPHR_OCP, - MSM89XX_IRQ_HPHL_OCP, - MSM89XX_IRQ_EAR_CNP, - MSM89XX_IRQ_HPHR_CNP, - MSM89XX_IRQ_HPHL_CNP, - MSM89XX_NUM_IRQS, -}; - -enum { - ON_DEMAND_MICBIAS = 0, - ON_DEMAND_SPKDRV, - ON_DEMAND_SUPPLIES_MAX, -}; - -/* - * The delay list is per codec HW specification. - * Please add delay in the list in the future instead - * of magic number - */ -enum { - CODEC_DELAY_1_MS = 1000, - CODEC_DELAY_1_1_MS = 1100, -}; - -struct sdm660_cdc_regulator { - const char *name; - int min_uv; - int max_uv; - int optimum_ua; - bool ondemand; - struct regulator *regulator; -}; - -struct on_demand_supply { - struct regulator *supply; - atomic_t ref; - int min_uv; - int max_uv; - int optimum_ua; -}; - -struct wcd_imped_i_ref { - enum wcd_curr_ref curr_ref; - int min_val; - int multiplier; - int gain_adj; - int offset; -}; - -enum sdm660_cdc_micbias_num { - MSM89XX_MICBIAS1 = 0, -}; - -/* Hold instance to digital codec platform device */ -struct msm_dig_ctrl_data { - struct platform_device *dig_pdev; -}; - -struct msm_dig_ctrl_platform_data { - void *handle; - void (*set_compander_mode)(void *handle, int val); - void (*update_clkdiv)(void *handle, int val); - int (*get_cdc_version)(void *handle); - int (*register_notifier)(void *handle, - struct notifier_block *nblock, - bool enable); -}; - -struct sdm660_cdc_priv { - struct device *dev; - u32 num_of_supplies; - struct regulator_bulk_data *supplies; - struct snd_soc_codec *codec; - struct work_struct msm_anlg_add_child_devices_work; - struct msm_dig_ctrl_platform_data dig_plat_data; - /* digital codec data structure */ - struct msm_dig_ctrl_data *dig_ctrl_data; - struct blocking_notifier_head notifier; - u16 pmic_rev; - u16 codec_version; - u16 analog_major_rev; - u32 boost_voltage; - u32 adc_count; - u32 rx_bias_count; - bool int_mclk0_enabled; - u16 boost_option; - /* mode to select hd2 */ - u32 hph_mode; - /* compander used for each rx chain */ - bool spk_boost_set; - bool ear_pa_boost_set; - bool ext_spk_boost_set; - struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX]; - struct regulator *spkdrv_reg; - struct blocking_notifier_head notifier_mbhc; - /* mbhc module */ - struct wcd_mbhc mbhc; - /* cal info for codec */ - struct fw_info *fw_data; - struct notifier_block audio_ssr_nb; - int (*codec_spk_ext_pa_cb)(struct snd_soc_codec *codec, int enable); - unsigned long status_mask; - struct wcd_imped_i_ref imped_i_ref; - enum wcd_mbhc_imp_det_pin imped_det_pin; - /* Entry for version info */ - struct snd_info_entry *entry; - struct snd_info_entry *version_entry; - struct platform_device *pdev_child_devices - [ANLG_CDC_CHILD_DEVICES_MAX]; - int child_count; -}; - -struct sdm660_cdc_pdata { - struct wcd_micbias_setting micbias; - struct sdm660_cdc_regulator regulator[MAX_REGULATOR]; -}; - -#if IS_ENABLED(CONFIG_SND_SOC_ANALOG_CDC) -extern int msm_anlg_cdc_mclk_enable(struct snd_soc_codec *codec, - int mclk_enable, bool dapm); -extern int msm_anlg_cdc_hs_detect(struct snd_soc_codec *codec, - struct wcd_mbhc_config *mbhc_cfg); -extern void msm_anlg_cdc_hs_detect_exit(struct snd_soc_codec *codec); -extern void sdm660_cdc_update_int_spk_boost(bool enable); -extern void msm_anlg_cdc_spk_ext_pa_cb( - int (*codec_spk_ext_pa)(struct snd_soc_codec *codec, - int enable), struct snd_soc_codec *codec); -int msm_anlg_codec_info_create_codec_entry(struct snd_info_entry *codec_root, - struct snd_soc_codec *codec); -#else /* CONFIG_SND_SOC_ANALOG_CDC */ -static inline int msm_anlg_cdc_mclk_enable(struct snd_soc_codec *codec, - int mclk_enable, bool dapm) -{ - return 0; -} -static inline int msm_anlg_cdc_hs_detect(struct snd_soc_codec *codec, - struct wcd_mbhc_config *mbhc_cfg) -{ - return 0; -} -static inline void msm_anlg_cdc_hs_detect_exit(struct snd_soc_codec *codec) -{ - -} -static inline void sdm660_cdc_update_int_spk_boost(bool enable) -{ - -} -static inline void msm_anlg_cdc_spk_ext_pa_cb( - int (*codec_spk_ext_pa)(struct snd_soc_codec *codec, - int enable), struct snd_soc_codec *codec) -{ - -} -static inline int msm_anlg_codec_info_create_codec_entry( - struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) -{ - return 0; -} -#endif /* CONFIG_SND_SOC_ANALOG_CDC */ -#endif diff --git a/asoc/codecs/sdm660_cdc/msm-cdc-common.h b/asoc/codecs/sdm660_cdc/msm-cdc-common.h deleted file mode 100644 index 1a490a492b45..000000000000 --- a/asoc/codecs/sdm660_cdc/msm-cdc-common.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include "sdm660-cdc-registers.h" - -extern struct reg_default - msm89xx_cdc_core_defaults[MSM89XX_CDC_CORE_CACHE_SIZE]; -extern struct reg_default - msm89xx_pmic_cdc_defaults[MSM89XX_PMIC_CDC_CACHE_SIZE]; - -bool msm89xx_cdc_core_readable_reg(struct device *dev, unsigned int reg); -bool msm89xx_cdc_core_writeable_reg(struct device *dev, unsigned int reg); -bool msm89xx_cdc_core_volatile_reg(struct device *dev, unsigned int reg); - -enum { - AIF1_PB = 0, - AIF1_CAP, - AIF2_VIFEED, - AIF3_SVA, - NUM_CODEC_DAIS, -}; - -enum codec_versions { - TOMBAK_1_0, - TOMBAK_2_0, - CONGA, - CAJON, - CAJON_2_0, - DIANGU, - DRAX_CDC, - UNSUPPORTED, -}; - -/* Support different hph modes */ -enum { - NORMAL_MODE = 0, - HD2_MODE, -}; - -enum dig_cdc_notify_event { - DIG_CDC_EVENT_INVALID, - DIG_CDC_EVENT_CLK_ON, - DIG_CDC_EVENT_CLK_OFF, - DIG_CDC_EVENT_RX1_MUTE_ON, - DIG_CDC_EVENT_RX1_MUTE_OFF, - DIG_CDC_EVENT_RX2_MUTE_ON, - DIG_CDC_EVENT_RX2_MUTE_OFF, - DIG_CDC_EVENT_RX3_MUTE_ON, - DIG_CDC_EVENT_RX3_MUTE_OFF, - DIG_CDC_EVENT_PRE_RX1_INT_ON, - DIG_CDC_EVENT_PRE_RX2_INT_ON, - DIG_CDC_EVENT_POST_RX1_INT_OFF, - DIG_CDC_EVENT_POST_RX2_INT_OFF, - DIG_CDC_EVENT_SSR_DOWN, - DIG_CDC_EVENT_SSR_UP, - DIG_CDC_EVENT_LAST, -}; diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc-regmap.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc-regmap.c deleted file mode 100644 index a62679174567..000000000000 --- a/asoc/codecs/sdm660_cdc/msm-digital-cdc-regmap.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include "msm-cdc-common.h" -#include "sdm660-cdc-registers.h" - -/* - * Default register reset values that are common across different versions - * are defined here. If a register reset value is changed based on version - * then remove it from this structure and add it in version specific - * structures. - */ -struct reg_default - msm89xx_cdc_core_defaults[MSM89XX_CDC_CORE_CACHE_SIZE] = { - {MSM89XX_CDC_CORE_CLK_RX_RESET_CTL, 0x00}, - {MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x13}, - {MSM89XX_CDC_CORE_CLK_TX_I2S_CTL, 0x13}, - {MSM89XX_CDC_CORE_CLK_OTHR_RESET_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_CLK_OTHR_CTL, 0x04}, - {MSM89XX_CDC_CORE_CLK_RX_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_CLK_MCLK_CTL, 0x00}, - {MSM89XX_CDC_CORE_CLK_PDM_CTL, 0x00}, - {MSM89XX_CDC_CORE_CLK_SD_CTL, 0x00}, - {MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_CLK_TX2_I2S_CTL, 0x13}, - {MSM89XX_CDC_CORE_RX1_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX2_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX3_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX1_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX2_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX3_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX1_B3_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX2_B3_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX3_B3_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX1_B4_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX2_B4_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX3_B4_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX1_B5_CTL, 0x68}, - {MSM89XX_CDC_CORE_RX2_B5_CTL, 0x68}, - {MSM89XX_CDC_CORE_RX3_B5_CTL, 0x68}, - {MSM89XX_CDC_CORE_RX1_B6_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX2_B6_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX3_B6_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX1_VOL_CTL_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX2_VOL_CTL_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX3_VOL_CTL_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_TOP_GAIN_UPDATE, 0x00}, - {MSM89XX_CDC_CORE_TOP_CTL, 0x01}, - {MSM89XX_CDC_CORE_COMP0_B1_CTL, 0x30}, - {MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xB5}, - {MSM89XX_CDC_CORE_COMP0_B3_CTL, 0x28}, - {MSM89XX_CDC_CORE_COMP0_B4_CTL, 0x37}, - {MSM89XX_CDC_CORE_COMP0_B5_CTL, 0x7F}, - {MSM89XX_CDC_CORE_COMP0_B6_CTL, 0x00}, - {MSM89XX_CDC_CORE_COMP0_SHUT_DOWN_STATUS, 0x03}, - {MSM89XX_CDC_CORE_COMP0_FS_CFG, 0x03}, - {MSM89XX_CDC_CORE_COMP0_DELAY_BUF_CTL, 0x02}, - {MSM89XX_CDC_CORE_DEBUG_DESER1_CTL, 0x00}, - {MSM89XX_CDC_CORE_DEBUG_DESER2_CTL, 0x00}, - {MSM89XX_CDC_CORE_DEBUG_B1_CTL_CFG, 0x00}, - {MSM89XX_CDC_CORE_DEBUG_B2_CTL_CFG, 0x00}, - {MSM89XX_CDC_CORE_DEBUG_B3_CTL_CFG, 0x00}, - {MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR2_GAIN_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR2_GAIN_B3_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR2_GAIN_B4_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR1_GAIN_B5_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR2_GAIN_B5_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR1_GAIN_B6_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR2_GAIN_B6_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR1_GAIN_B7_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR2_GAIN_B7_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR1_GAIN_B8_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR2_GAIN_B8_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR1_CTL, 0x40}, - {MSM89XX_CDC_CORE_IIR2_CTL, 0x40}, - {MSM89XX_CDC_CORE_IIR1_GAIN_TIMER_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR2_GAIN_TIMER_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_IIR2_COEF_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_RX1_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_RX1_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_RX1_B3_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_RX2_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_RX2_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_RX2_B3_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_RX3_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_RX3_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_TX_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_TX_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_EQ1_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_EQ1_B3_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_EQ1_B4_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_EQ2_B2_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_EQ2_B3_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_EQ2_B4_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL, 0x00}, - {MSM89XX_CDC_CORE_CONN_TX_B3_CTL, 0x00}, - {MSM89XX_CDC_CORE_TX5_VOL_CTL_TIMER, 0x00}, - {MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN, 0x00}, - {MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG, 0x00}, - {MSM89XX_CDC_CORE_TX5_MUX_CTL, 0x00}, - {MSM89XX_CDC_CORE_TX5_CLK_FS_CTL, 0x03}, - {MSM89XX_CDC_CORE_TX5_DMIC_CTL, 0x00}, - {MSM89XX_CDC_CORE_TX1_VOL_CTL_TIMER, 0x00}, - {MSM89XX_CDC_CORE_TX2_VOL_CTL_TIMER, 0x00}, - {MSM89XX_CDC_CORE_TX3_VOL_CTL_TIMER, 0x00}, - {MSM89XX_CDC_CORE_TX4_VOL_CTL_TIMER, 0x00}, - {MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN, 0x00}, - {MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN, 0x00}, - {MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN, 0x00}, - {MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN, 0x00}, - {MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG, 0x00}, - {MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG, 0x00}, - {MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG, 0x00}, - {MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG, 0x00}, - {MSM89XX_CDC_CORE_TX1_MUX_CTL, 0x00}, - {MSM89XX_CDC_CORE_TX2_MUX_CTL, 0x00}, - {MSM89XX_CDC_CORE_TX3_MUX_CTL, 0x00}, - {MSM89XX_CDC_CORE_TX4_MUX_CTL, 0x00}, - {MSM89XX_CDC_CORE_TX1_CLK_FS_CTL, 0x03}, - {MSM89XX_CDC_CORE_TX2_CLK_FS_CTL, 0x03}, - {MSM89XX_CDC_CORE_TX3_CLK_FS_CTL, 0x03}, - {MSM89XX_CDC_CORE_TX4_CLK_FS_CTL, 0x03}, - {MSM89XX_CDC_CORE_TX1_DMIC_CTL, 0x00}, - {MSM89XX_CDC_CORE_TX2_DMIC_CTL, 0x00}, - {MSM89XX_CDC_CORE_TX3_DMIC_CTL, 0x00}, - {MSM89XX_CDC_CORE_TX4_DMIC_CTL, 0x00}, -}; - -static const u8 msm89xx_cdc_core_reg_readable[MSM89XX_CDC_CORE_CACHE_SIZE] = { - [MSM89XX_CDC_CORE_CLK_RX_RESET_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_RX_I2S_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_TX_I2S_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_OTHR_RESET_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_OTHR_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_RX_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_MCLK_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_PDM_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_SD_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_RX_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_TX2_I2S_CTL] = 1, - [MSM89XX_CDC_CORE_RX1_B1_CTL] = 1, - [MSM89XX_CDC_CORE_RX2_B1_CTL] = 1, - [MSM89XX_CDC_CORE_RX3_B1_CTL] = 1, - [MSM89XX_CDC_CORE_RX1_B2_CTL] = 1, - [MSM89XX_CDC_CORE_RX2_B2_CTL] = 1, - [MSM89XX_CDC_CORE_RX3_B2_CTL] = 1, - [MSM89XX_CDC_CORE_RX1_B3_CTL] = 1, - [MSM89XX_CDC_CORE_RX2_B3_CTL] = 1, - [MSM89XX_CDC_CORE_RX3_B3_CTL] = 1, - [MSM89XX_CDC_CORE_RX1_B4_CTL] = 1, - [MSM89XX_CDC_CORE_RX2_B4_CTL] = 1, - [MSM89XX_CDC_CORE_RX3_B4_CTL] = 1, - [MSM89XX_CDC_CORE_RX1_B5_CTL] = 1, - [MSM89XX_CDC_CORE_RX2_B5_CTL] = 1, - [MSM89XX_CDC_CORE_RX3_B5_CTL] = 1, - [MSM89XX_CDC_CORE_RX1_B6_CTL] = 1, - [MSM89XX_CDC_CORE_RX2_B6_CTL] = 1, - [MSM89XX_CDC_CORE_RX3_B6_CTL] = 1, - [MSM89XX_CDC_CORE_RX1_VOL_CTL_B1_CTL] = 1, - [MSM89XX_CDC_CORE_RX2_VOL_CTL_B1_CTL] = 1, - [MSM89XX_CDC_CORE_RX3_VOL_CTL_B1_CTL] = 1, - [MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL] = 1, - [MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL] = 1, - [MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL] = 1, - [MSM89XX_CDC_CORE_TOP_GAIN_UPDATE] = 1, - [MSM89XX_CDC_CORE_TOP_CTL] = 1, - [MSM89XX_CDC_CORE_COMP0_B1_CTL] = 1, - [MSM89XX_CDC_CORE_COMP0_B2_CTL] = 1, - [MSM89XX_CDC_CORE_COMP0_B3_CTL] = 1, - [MSM89XX_CDC_CORE_COMP0_B4_CTL] = 1, - [MSM89XX_CDC_CORE_COMP0_B5_CTL] = 1, - [MSM89XX_CDC_CORE_COMP0_B6_CTL] = 1, - [MSM89XX_CDC_CORE_COMP0_SHUT_DOWN_STATUS] = 1, - [MSM89XX_CDC_CORE_COMP0_FS_CFG] = 1, - [MSM89XX_CDC_CORE_COMP0_DELAY_BUF_CTL] = 1, - [MSM89XX_CDC_CORE_DEBUG_DESER1_CTL] = 1, - [MSM89XX_CDC_CORE_DEBUG_DESER2_CTL] = 1, - [MSM89XX_CDC_CORE_DEBUG_B1_CTL_CFG] = 1, - [MSM89XX_CDC_CORE_DEBUG_B2_CTL_CFG] = 1, - [MSM89XX_CDC_CORE_DEBUG_B3_CTL_CFG] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_B2_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_B3_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_B4_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_B5_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_B5_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_B6_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_B6_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_B7_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_B7_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_B8_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_B8_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_TIMER_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_TIMER_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_COEF_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_RX1_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_RX1_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_RX1_B3_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_RX2_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_RX2_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_RX2_B3_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_RX3_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_RX3_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_TX_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_TX_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_EQ1_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_EQ1_B3_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_EQ1_B4_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_EQ2_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_EQ2_B3_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_EQ2_B4_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_TX_B3_CTL] = 1, - [MSM89XX_CDC_CORE_TX1_VOL_CTL_TIMER] = 1, - [MSM89XX_CDC_CORE_TX2_VOL_CTL_TIMER] = 1, - [MSM89XX_CDC_CORE_TX3_VOL_CTL_TIMER] = 1, - [MSM89XX_CDC_CORE_TX4_VOL_CTL_TIMER] = 1, - [MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN] = 1, - [MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN] = 1, - [MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN] = 1, - [MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN] = 1, - [MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG] = 1, - [MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG] = 1, - [MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG] = 1, - [MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG] = 1, - [MSM89XX_CDC_CORE_TX1_MUX_CTL] = 1, - [MSM89XX_CDC_CORE_TX2_MUX_CTL] = 1, - [MSM89XX_CDC_CORE_TX3_MUX_CTL] = 1, - [MSM89XX_CDC_CORE_TX4_MUX_CTL] = 1, - [MSM89XX_CDC_CORE_TX1_CLK_FS_CTL] = 1, - [MSM89XX_CDC_CORE_TX2_CLK_FS_CTL] = 1, - [MSM89XX_CDC_CORE_TX3_CLK_FS_CTL] = 1, - [MSM89XX_CDC_CORE_TX4_CLK_FS_CTL] = 1, - [MSM89XX_CDC_CORE_TX5_VOL_CTL_TIMER] = 1, - [MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN] = 1, - [MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG] = 1, - [MSM89XX_CDC_CORE_TX5_MUX_CTL] = 1, - [MSM89XX_CDC_CORE_TX5_CLK_FS_CTL] = 1, - [MSM89XX_CDC_CORE_TX5_DMIC_CTL] = 1, - [MSM89XX_CDC_CORE_TX1_DMIC_CTL] = 1, - [MSM89XX_CDC_CORE_TX2_DMIC_CTL] = 1, - [MSM89XX_CDC_CORE_TX3_DMIC_CTL] = 1, - [MSM89XX_CDC_CORE_TX4_DMIC_CTL] = 1, -}; - -static const u8 msm89xx_cdc_core_reg_writeable[MSM89XX_CDC_CORE_CACHE_SIZE] = { - [MSM89XX_CDC_CORE_CLK_RX_RESET_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_RX_I2S_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_TX_I2S_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_OTHR_RESET_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_OTHR_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_RX_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_MCLK_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_PDM_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_SD_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_RX_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CLK_TX2_I2S_CTL] = 1, - [MSM89XX_CDC_CORE_RX1_B1_CTL] = 1, - [MSM89XX_CDC_CORE_RX2_B1_CTL] = 1, - [MSM89XX_CDC_CORE_RX3_B1_CTL] = 1, - [MSM89XX_CDC_CORE_RX1_B2_CTL] = 1, - [MSM89XX_CDC_CORE_RX2_B2_CTL] = 1, - [MSM89XX_CDC_CORE_RX3_B2_CTL] = 1, - [MSM89XX_CDC_CORE_RX1_B3_CTL] = 1, - [MSM89XX_CDC_CORE_RX2_B3_CTL] = 1, - [MSM89XX_CDC_CORE_RX3_B3_CTL] = 1, - [MSM89XX_CDC_CORE_RX1_B4_CTL] = 1, - [MSM89XX_CDC_CORE_RX2_B4_CTL] = 1, - [MSM89XX_CDC_CORE_RX3_B4_CTL] = 1, - [MSM89XX_CDC_CORE_RX1_B5_CTL] = 1, - [MSM89XX_CDC_CORE_RX2_B5_CTL] = 1, - [MSM89XX_CDC_CORE_RX3_B5_CTL] = 1, - [MSM89XX_CDC_CORE_RX1_B6_CTL] = 1, - [MSM89XX_CDC_CORE_RX2_B6_CTL] = 1, - [MSM89XX_CDC_CORE_RX3_B6_CTL] = 1, - [MSM89XX_CDC_CORE_RX1_VOL_CTL_B1_CTL] = 1, - [MSM89XX_CDC_CORE_RX2_VOL_CTL_B1_CTL] = 1, - [MSM89XX_CDC_CORE_RX3_VOL_CTL_B1_CTL] = 1, - [MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL] = 1, - [MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL] = 1, - [MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL] = 1, - [MSM89XX_CDC_CORE_TOP_GAIN_UPDATE] = 1, - [MSM89XX_CDC_CORE_TOP_CTL] = 1, - [MSM89XX_CDC_CORE_COMP0_B1_CTL] = 1, - [MSM89XX_CDC_CORE_COMP0_B2_CTL] = 1, - [MSM89XX_CDC_CORE_COMP0_B3_CTL] = 1, - [MSM89XX_CDC_CORE_COMP0_B4_CTL] = 1, - [MSM89XX_CDC_CORE_COMP0_B5_CTL] = 1, - [MSM89XX_CDC_CORE_COMP0_B6_CTL] = 1, - [MSM89XX_CDC_CORE_COMP0_FS_CFG] = 1, - [MSM89XX_CDC_CORE_COMP0_DELAY_BUF_CTL] = 1, - [MSM89XX_CDC_CORE_DEBUG_DESER1_CTL] = 1, - [MSM89XX_CDC_CORE_DEBUG_DESER2_CTL] = 1, - [MSM89XX_CDC_CORE_DEBUG_B1_CTL_CFG] = 1, - [MSM89XX_CDC_CORE_DEBUG_B2_CTL_CFG] = 1, - [MSM89XX_CDC_CORE_DEBUG_B3_CTL_CFG] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_B2_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_B3_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_B4_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_B5_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_B5_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_B6_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_B6_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_B7_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_B7_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_B8_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_B8_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_GAIN_TIMER_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_GAIN_TIMER_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL] = 1, - [MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL] = 1, - [MSM89XX_CDC_CORE_IIR2_COEF_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_RX1_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_RX1_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_RX1_B3_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_RX2_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_RX2_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_RX2_B3_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_RX3_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_RX3_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_TX_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_TX_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_EQ1_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_EQ1_B3_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_EQ1_B4_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_EQ2_B2_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_EQ2_B3_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_EQ2_B4_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL] = 1, - [MSM89XX_CDC_CORE_CONN_TX_B3_CTL] = 1, - [MSM89XX_CDC_CORE_TX1_VOL_CTL_TIMER] = 1, - [MSM89XX_CDC_CORE_TX2_VOL_CTL_TIMER] = 1, - [MSM89XX_CDC_CORE_TX3_VOL_CTL_TIMER] = 1, - [MSM89XX_CDC_CORE_TX4_VOL_CTL_TIMER] = 1, - [MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN] = 1, - [MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN] = 1, - [MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN] = 1, - [MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN] = 1, - [MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG] = 1, - [MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG] = 1, - [MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG] = 1, - [MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG] = 1, - [MSM89XX_CDC_CORE_TX1_MUX_CTL] = 1, - [MSM89XX_CDC_CORE_TX2_MUX_CTL] = 1, - [MSM89XX_CDC_CORE_TX3_MUX_CTL] = 1, - [MSM89XX_CDC_CORE_TX4_MUX_CTL] = 1, - [MSM89XX_CDC_CORE_TX1_CLK_FS_CTL] = 1, - [MSM89XX_CDC_CORE_TX2_CLK_FS_CTL] = 1, - [MSM89XX_CDC_CORE_TX3_CLK_FS_CTL] = 1, - [MSM89XX_CDC_CORE_TX4_CLK_FS_CTL] = 1, - [MSM89XX_CDC_CORE_TX5_VOL_CTL_TIMER] = 1, - [MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN] = 1, - [MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG] = 1, - [MSM89XX_CDC_CORE_TX5_MUX_CTL] = 1, - [MSM89XX_CDC_CORE_TX5_CLK_FS_CTL] = 1, - [MSM89XX_CDC_CORE_TX5_DMIC_CTL] = 1, - [MSM89XX_CDC_CORE_TX1_DMIC_CTL] = 1, - [MSM89XX_CDC_CORE_TX2_DMIC_CTL] = 1, - [MSM89XX_CDC_CORE_TX3_DMIC_CTL] = 1, - [MSM89XX_CDC_CORE_TX4_DMIC_CTL] = 1, -}; - -bool msm89xx_cdc_core_readable_reg(struct device *dev, unsigned int reg) -{ - return msm89xx_cdc_core_reg_readable[reg]; -} - -bool msm89xx_cdc_core_writeable_reg(struct device *dev, unsigned int reg) -{ - return msm89xx_cdc_core_reg_writeable[reg]; -} - -bool msm89xx_cdc_core_volatile_reg(struct device *dev, unsigned int reg) -{ - switch (reg) { - case MSM89XX_CDC_CORE_RX1_B1_CTL: - case MSM89XX_CDC_CORE_RX2_B1_CTL: - case MSM89XX_CDC_CORE_RX3_B1_CTL: - case MSM89XX_CDC_CORE_RX1_B6_CTL: - case MSM89XX_CDC_CORE_RX2_B6_CTL: - case MSM89XX_CDC_CORE_RX3_B6_CTL: - case MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG: - case MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG: - case MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG: - case MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG: - case MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG: - case MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL: - case MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL: - case MSM89XX_CDC_CORE_CLK_MCLK_CTL: - case MSM89XX_CDC_CORE_CLK_PDM_CTL: - return true; - default: - return false; - } -} diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c deleted file mode 100644 index 2c3d0d66afca..000000000000 --- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c +++ /dev/null @@ -1,2213 +0,0 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "sdm660-cdc-registers.h" -#include "msm-digital-cdc.h" -#include "msm-cdc-common.h" -#include "../../sdm660-common.h" - -#define DRV_NAME "msm_digital_codec" -#define MCLK_RATE_9P6MHZ 9600000 -#define MCLK_RATE_12P288MHZ 12288000 -#define TX_MUX_CTL_CUT_OFF_FREQ_MASK 0x30 -#define CF_MIN_3DB_4HZ 0x0 -#define CF_MIN_3DB_75HZ 0x1 -#define CF_MIN_3DB_150HZ 0x2 - -#define MSM_DIG_CDC_VERSION_ENTRY_SIZE 32 - -static unsigned long rx_digital_gain_reg[] = { - MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL, - MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL, - MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL, -}; - -static unsigned long tx_digital_gain_reg[] = { - MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN, - MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN, - MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN, - MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN, - MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN, -}; - -#define SDM660_TX_UNMUTE_DELAY_MS 40 -static int tx_unmute_delay = SDM660_TX_UNMUTE_DELAY_MS; -module_param(tx_unmute_delay, int, 0664); -MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path"); - -static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); - -struct snd_soc_codec *registered_digcodec; -struct hpf_work tx_hpf_work[NUM_DECIMATORS]; - -/* Codec supports 2 IIR filters */ -enum { - IIR1 = 0, - IIR2, - IIR_MAX, -}; - -static int msm_digcdc_clock_control(bool flag) -{ - int ret = -EINVAL; - struct msm_asoc_mach_data *pdata = NULL; - struct msm_dig_priv *msm_dig_cdc = - snd_soc_codec_get_drvdata(registered_digcodec); - - pdata = snd_soc_card_get_drvdata(registered_digcodec->component.card); - - if (flag) { - mutex_lock(&pdata->cdc_int_mclk0_mutex); - if (atomic_read(&pdata->int_mclk0_enabled) == false) { - if (pdata->native_clk_set) - pdata->digital_cdc_core_clk.clk_freq_in_hz = - NATIVE_MCLK_RATE; - else - pdata->digital_cdc_core_clk.clk_freq_in_hz = - DEFAULT_MCLK_RATE; - pdata->digital_cdc_core_clk.enable = 1; - ret = afe_set_lpass_clock_v2( - AFE_PORT_ID_INT0_MI2S_RX, - &pdata->digital_cdc_core_clk); - if (ret < 0) { - pr_err("%s:failed to enable the MCLK\n", - __func__); - /* - * Avoid access to lpass register - * as clock enable failed during SSR. - */ - if (ret == -ENODEV) - msm_dig_cdc->regmap->cache_only = true; - return ret; - } - pr_debug("enabled digital codec core clk\n"); - atomic_set(&pdata->int_mclk0_enabled, true); - schedule_delayed_work(&pdata->disable_int_mclk0_work, - 50); - } - } else { - mutex_unlock(&pdata->cdc_int_mclk0_mutex); - dev_dbg(registered_digcodec->dev, - "disable MCLK, workq to disable set already\n"); - } - return 0; -} - -static void enable_digital_callback(void *flag) -{ - msm_digcdc_clock_control(true); -} - -static void disable_digital_callback(void *flag) -{ - msm_digcdc_clock_control(false); - pr_debug("disable mclk happens in workq\n"); -} - -static int msm_dig_cdc_put_dec_enum(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int dec_mux, decimator; - char *dec_name = NULL; - char *widget_name = NULL; - char *temp; - u16 tx_mux_ctl_reg; - u8 adc_dmic_sel = 0x0; - int ret = 0; - char *dec_num; - - if (ucontrol->value.enumerated.item[0] > e->items) { - dev_err(codec->dev, "%s: Invalid enum value: %d\n", - __func__, ucontrol->value.enumerated.item[0]); - return -EINVAL; - } - dec_mux = ucontrol->value.enumerated.item[0]; - - widget_name = kstrndup(w->name, 15, GFP_KERNEL); - if (!widget_name) { - dev_err(codec->dev, "%s: failed to copy string\n", - __func__); - return -ENOMEM; - } - temp = widget_name; - - dec_name = strsep(&widget_name, " "); - widget_name = temp; - if (!dec_name) { - dev_err(codec->dev, "%s: Invalid decimator = %s\n", - __func__, w->name); - ret = -EINVAL; - goto out; - } - - dec_num = strpbrk(dec_name, "12345"); - if (dec_num == NULL) { - dev_err(codec->dev, "%s: Invalid DEC selected\n", __func__); - ret = -EINVAL; - goto out; - } - - ret = kstrtouint(dec_num, 10, &decimator); - if (ret < 0) { - dev_err(codec->dev, "%s: Invalid decimator = %s\n", - __func__, dec_name); - ret = -EINVAL; - goto out; - } - - dev_dbg(w->dapm->dev, "%s(): widget = %s decimator = %u dec_mux = %u\n" - , __func__, w->name, decimator, dec_mux); - - switch (decimator) { - case 1: - case 2: - case 3: - case 4: - case 5: - if ((dec_mux == 4) || (dec_mux == 5) || - (dec_mux == 6) || (dec_mux == 7)) - adc_dmic_sel = 0x1; - else - adc_dmic_sel = 0x0; - break; - default: - dev_err(codec->dev, "%s: Invalid Decimator = %u\n", - __func__, decimator); - ret = -EINVAL; - goto out; - } - - tx_mux_ctl_reg = - MSM89XX_CDC_CORE_TX1_MUX_CTL + 32 * (decimator - 1); - - snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x1, adc_dmic_sel); - - ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol); - -out: - kfree(widget_name); - return ret; -} - - -static int msm_dig_cdc_codec_config_compander(struct snd_soc_codec *codec, - int interp_n, int event) -{ - struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec); - int comp_ch_bits_set = 0x03; - int comp_ch_value; - - dev_dbg(codec->dev, "%s: event %d shift %d, enabled %d\n", - __func__, event, interp_n, - dig_cdc->comp_enabled[interp_n]); - - /* compander is invalid */ - if (dig_cdc->comp_enabled[interp_n] != COMPANDER_1 && - dig_cdc->comp_enabled[interp_n]) { - dev_dbg(codec->dev, "%s: Invalid compander %d\n", __func__, - dig_cdc->comp_enabled[interp_n]); - return 0; - } - - if (SND_SOC_DAPM_EVENT_ON(event)) { - /* compander is not enabled */ - if (!dig_cdc->comp_enabled[interp_n]) { - dig_cdc->set_compander_mode(dig_cdc->handle, 0x00); - return 0; - }; - comp_ch_value = snd_soc_read(codec, - MSM89XX_CDC_CORE_COMP0_B1_CTL); - if (interp_n == 0) { - if (comp_ch_value & 0x02) { - dev_dbg(codec->dev, - "%s comp ch 1 already enabled\n", - __func__); - return 0; - } - } - if (interp_n == 1) { - if (comp_ch_value & 0x01) { - dev_dbg(codec->dev, - "%s comp ch 0 already enabled\n", - __func__); - return 0; - } - } - dig_cdc->set_compander_mode(dig_cdc->handle, 0x08); - /* Enable Compander Clock */ - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B2_CTL, 0x0F, 0x09); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x01, 0x01); - if (dig_cdc->comp_enabled[MSM89XX_RX1]) { - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B1_CTL, - 0x02, 0x02); - } - if (dig_cdc->comp_enabled[MSM89XX_RX2]) { - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B1_CTL, - 0x01, 0x01); - } - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x01); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xF0, 0x50); - /* add sleep for compander to settle */ - usleep_range(1000, 1100); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x28); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xF0, 0xB0); - - /* Enable Compander GPIO */ - if (dig_cdc->codec_hph_comp_gpio) - dig_cdc->codec_hph_comp_gpio(1, codec); - } else if (SND_SOC_DAPM_EVENT_OFF(event)) { - /* Disable Compander GPIO */ - if (dig_cdc->codec_hph_comp_gpio) - dig_cdc->codec_hph_comp_gpio(0, codec); - - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B1_CTL, - 1 << interp_n, 0); - comp_ch_bits_set = snd_soc_read(codec, - MSM89XX_CDC_CORE_COMP0_B1_CTL); - if ((comp_ch_bits_set & 0x03) == 0x00) { - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_COMP0_B2_CTL, 0x0F, 0x05); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x01, 0x00); - } - } - return 0; -} - -/** - * msm_dig_cdc_hph_comp_cb - registers callback to codec by machine driver. - * - * @codec_hph_comp_gpio: function pointer to set comp gpio at machine driver - * @codec: codec pointer - * - */ -void msm_dig_cdc_hph_comp_cb( - int (*codec_hph_comp_gpio)(bool enable, struct snd_soc_codec *codec), - struct snd_soc_codec *codec) -{ - struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec); - - pr_debug("%s: Enter\n", __func__); - dig_cdc->codec_hph_comp_gpio = codec_hph_comp_gpio; -} -EXPORT_SYMBOL(msm_dig_cdc_hph_comp_cb); - -static int msm_dig_cdc_codec_enable_interpolator(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct msm_dig_priv *msm_dig_cdc = snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); - - if (w->shift >= MSM89XX_RX_MAX || w->shift < 0) { - dev_err(codec->dev, "%s: wrong RX index: %d\n", - __func__, w->shift); - return -EINVAL; - } - switch (event) { - case SND_SOC_DAPM_POST_PMU: - msm_dig_cdc_codec_config_compander(codec, w->shift, event); - /* apply the digital gain after the interpolator is enabled*/ - if ((w->shift) < ARRAY_SIZE(rx_digital_gain_reg)) - snd_soc_write(codec, - rx_digital_gain_reg[w->shift], - snd_soc_read(codec, - rx_digital_gain_reg[w->shift]) - ); - break; - case SND_SOC_DAPM_POST_PMD: - msm_dig_cdc_codec_config_compander(codec, w->shift, event); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_CLK_RX_RESET_CTL, - 1 << w->shift, 1 << w->shift); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_CLK_RX_RESET_CTL, - 1 << w->shift, 0x0); - /* - * disable the mute enabled during the PMD of this device - */ - if ((w->shift == 0) && - (msm_dig_cdc->mute_mask & HPHL_PA_DISABLE)) { - pr_debug("disabling HPHL mute\n"); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX1_B6_CTL, 0x01, 0x00); - msm_dig_cdc->mute_mask &= ~(HPHL_PA_DISABLE); - } else if ((w->shift == 1) && - (msm_dig_cdc->mute_mask & HPHR_PA_DISABLE)) { - pr_debug("disabling HPHR mute\n"); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX2_B6_CTL, 0x01, 0x00); - msm_dig_cdc->mute_mask &= ~(HPHR_PA_DISABLE); - } else if ((w->shift == 2) && - (msm_dig_cdc->mute_mask & SPKR_PA_DISABLE)) { - pr_debug("disabling SPKR mute\n"); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX3_B6_CTL, 0x01, 0x00); - msm_dig_cdc->mute_mask &= ~(SPKR_PA_DISABLE); - } - } - return 0; -} - -static int msm_dig_cdc_get_iir_enable_audio_mixer( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - int iir_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->reg; - int band_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - - ucontrol->value.integer.value[0] = - (snd_soc_read(codec, - (MSM89XX_CDC_CORE_IIR1_CTL + 64 * iir_idx)) & - (1 << band_idx)) != 0; - - dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, - iir_idx, band_idx, - (uint32_t)ucontrol->value.integer.value[0]); - return 0; -} - -static int msm_dig_cdc_put_iir_enable_audio_mixer( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - int iir_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->reg; - int band_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - int value = ucontrol->value.integer.value[0]; - - /* Mask first 5 bits, 6-8 are reserved */ - snd_soc_update_bits(codec, - (MSM89XX_CDC_CORE_IIR1_CTL + 64 * iir_idx), - (1 << band_idx), (value << band_idx)); - - dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, - iir_idx, band_idx, - ((snd_soc_read(codec, - (MSM89XX_CDC_CORE_IIR1_CTL + 64 * iir_idx)) & - (1 << band_idx)) != 0)); - - return 0; -} - -static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec, - int iir_idx, int band_idx, - int coeff_idx) -{ - uint32_t value = 0; - - /* Address does not automatically update if reading */ - snd_soc_write(codec, - (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx), - ((band_idx * BAND_MAX + coeff_idx) - * sizeof(uint32_t)) & 0x7F); - - value |= snd_soc_read(codec, - (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx)); - - snd_soc_write(codec, - (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx), - ((band_idx * BAND_MAX + coeff_idx) - * sizeof(uint32_t) + 1) & 0x7F); - - value |= (snd_soc_read(codec, - (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 8); - - snd_soc_write(codec, - (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx), - ((band_idx * BAND_MAX + coeff_idx) - * sizeof(uint32_t) + 2) & 0x7F); - - value |= (snd_soc_read(codec, - (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 16); - - snd_soc_write(codec, - (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx), - ((band_idx * BAND_MAX + coeff_idx) - * sizeof(uint32_t) + 3) & 0x7F); - - /* Mask bits top 2 bits since they are reserved */ - value |= ((snd_soc_read(codec, (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL - + 64 * iir_idx)) & 0x3f) << 24); - - return value; - -} - -static void set_iir_band_coeff(struct snd_soc_codec *codec, - int iir_idx, int band_idx, - uint32_t value) -{ - snd_soc_write(codec, - (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx), - (value & 0xFF)); - - snd_soc_write(codec, - (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx), - (value >> 8) & 0xFF); - - snd_soc_write(codec, - (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx), - (value >> 16) & 0xFF); - - /* Mask top 2 bits, 7-8 are reserved */ - snd_soc_write(codec, - (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx), - (value >> 24) & 0x3F); - -} - -static int msm_dig_cdc_get_iir_band_audio_mixer( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - int iir_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->reg; - int band_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - - ucontrol->value.integer.value[0] = - get_iir_band_coeff(codec, iir_idx, band_idx, 0); - ucontrol->value.integer.value[1] = - get_iir_band_coeff(codec, iir_idx, band_idx, 1); - ucontrol->value.integer.value[2] = - get_iir_band_coeff(codec, iir_idx, band_idx, 2); - ucontrol->value.integer.value[3] = - get_iir_band_coeff(codec, iir_idx, band_idx, 3); - ucontrol->value.integer.value[4] = - get_iir_band_coeff(codec, iir_idx, band_idx, 4); - - dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n" - "%s: IIR #%d band #%d b1 = 0x%x\n" - "%s: IIR #%d band #%d b2 = 0x%x\n" - "%s: IIR #%d band #%d a1 = 0x%x\n" - "%s: IIR #%d band #%d a2 = 0x%x\n", - __func__, iir_idx, band_idx, - (uint32_t)ucontrol->value.integer.value[0], - __func__, iir_idx, band_idx, - (uint32_t)ucontrol->value.integer.value[1], - __func__, iir_idx, band_idx, - (uint32_t)ucontrol->value.integer.value[2], - __func__, iir_idx, band_idx, - (uint32_t)ucontrol->value.integer.value[3], - __func__, iir_idx, band_idx, - (uint32_t)ucontrol->value.integer.value[4]); - return 0; -} - -static int msm_dig_cdc_put_iir_band_audio_mixer( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - int iir_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->reg; - int band_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - - /* Mask top bit it is reserved */ - /* Updates addr automatically for each B2 write */ - snd_soc_write(codec, - (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx), - (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); - - - set_iir_band_coeff(codec, iir_idx, band_idx, - ucontrol->value.integer.value[0]); - set_iir_band_coeff(codec, iir_idx, band_idx, - ucontrol->value.integer.value[1]); - set_iir_band_coeff(codec, iir_idx, band_idx, - ucontrol->value.integer.value[2]); - set_iir_band_coeff(codec, iir_idx, band_idx, - ucontrol->value.integer.value[3]); - set_iir_band_coeff(codec, iir_idx, band_idx, - ucontrol->value.integer.value[4]); - - dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n" - "%s: IIR #%d band #%d b1 = 0x%x\n" - "%s: IIR #%d band #%d b2 = 0x%x\n" - "%s: IIR #%d band #%d a1 = 0x%x\n" - "%s: IIR #%d band #%d a2 = 0x%x\n", - __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 0), - __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 1), - __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 2), - __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 3), - __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 4)); - return 0; -} - -static void tx_hpf_corner_freq_callback(struct work_struct *work) -{ - struct delayed_work *hpf_delayed_work; - struct hpf_work *hpf_work; - struct snd_soc_codec *codec; - struct msm_dig_priv *msm_dig_cdc; - u16 tx_mux_ctl_reg; - u8 hpf_cut_of_freq; - - hpf_delayed_work = to_delayed_work(work); - hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); - codec = hpf_work->dig_cdc->codec; - msm_dig_cdc = hpf_work->dig_cdc; - hpf_cut_of_freq = hpf_work->tx_hpf_cut_of_freq; - - tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX1_MUX_CTL + - (hpf_work->decimator - 1) * 32; - - dev_dbg(codec->dev, "%s(): decimator %u hpf_cut_of_freq 0x%x\n", - __func__, hpf_work->decimator, (unsigned int)hpf_cut_of_freq); - msm_dig_cdc->update_clkdiv(msm_dig_cdc->handle, 0x51); - - snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, hpf_cut_of_freq << 4); -} - -static int msm_dig_cdc_codec_set_iir_gain(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - int value = 0, reg; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - if (w->shift == 0) - reg = MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL; - else if (w->shift == 1) - reg = MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL; - else - goto ret; - value = snd_soc_read(codec, reg); - snd_soc_write(codec, reg, value); - break; - default: - pr_err("%s: event = %d not expected\n", __func__, event); - } -ret: - return 0; -} - -static int msm_dig_cdc_compander_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec); - int comp_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->reg; - int rx_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - - dev_dbg(codec->dev, "%s: msm_dig_cdc->comp[%d]_enabled[%d] = %d\n", - __func__, comp_idx, rx_idx, - dig_cdc->comp_enabled[rx_idx]); - - ucontrol->value.integer.value[0] = dig_cdc->comp_enabled[rx_idx]; - - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - return 0; -} - -static int msm_dig_cdc_compander_set(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec); - int comp_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->reg; - int rx_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - int value = ucontrol->value.integer.value[0]; - - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - if (dig_cdc->version >= DIANGU) { - if (!value) - dig_cdc->comp_enabled[rx_idx] = 0; - else - dig_cdc->comp_enabled[rx_idx] = comp_idx; - } - - dev_dbg(codec->dev, "%s: msm_dig_cdc->comp[%d]_enabled[%d] = %d\n", - __func__, comp_idx, rx_idx, - dig_cdc->comp_enabled[rx_idx]); - - return 0; -} - -static const struct snd_kcontrol_new compander_kcontrols[] = { - SOC_SINGLE_EXT("COMP0 RX1", COMPANDER_1, MSM89XX_RX1, 1, 0, - msm_dig_cdc_compander_get, msm_dig_cdc_compander_set), - - SOC_SINGLE_EXT("COMP0 RX2", COMPANDER_1, MSM89XX_RX2, 1, 0, - msm_dig_cdc_compander_get, msm_dig_cdc_compander_set), - -}; - -static int msm_dig_cdc_set_interpolator_rate(struct snd_soc_dai *dai, - u8 rx_fs_rate_reg_val, - u32 sample_rate) -{ - snd_soc_update_bits(dai->codec, - MSM89XX_CDC_CORE_RX1_B5_CTL, 0xF0, rx_fs_rate_reg_val); - snd_soc_update_bits(dai->codec, - MSM89XX_CDC_CORE_RX2_B5_CTL, 0xF0, rx_fs_rate_reg_val); - return 0; -} - -static int msm_dig_cdc_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - u8 tx_fs_rate, rx_fs_rate, rx_clk_fs_rate; - int ret; - - dev_dbg(dai->codec->dev, - "%s: dai_name = %s DAI-ID %x rate %d num_ch %d format %d\n", - __func__, dai->name, dai->id, params_rate(params), - params_channels(params), params_format(params)); - - switch (params_rate(params)) { - case 8000: - tx_fs_rate = 0x00; - rx_fs_rate = 0x00; - rx_clk_fs_rate = 0x00; - break; - case 16000: - tx_fs_rate = 0x20; - rx_fs_rate = 0x20; - rx_clk_fs_rate = 0x01; - break; - case 32000: - tx_fs_rate = 0x40; - rx_fs_rate = 0x40; - rx_clk_fs_rate = 0x02; - break; - case 44100: - case 48000: - tx_fs_rate = 0x60; - rx_fs_rate = 0x60; - rx_clk_fs_rate = 0x03; - break; - case 96000: - tx_fs_rate = 0x80; - rx_fs_rate = 0x80; - rx_clk_fs_rate = 0x04; - break; - case 192000: - tx_fs_rate = 0xA0; - rx_fs_rate = 0xA0; - rx_clk_fs_rate = 0x05; - break; - default: - dev_err(dai->codec->dev, - "%s: Invalid sampling rate %d\n", __func__, - params_rate(params)); - return -EINVAL; - } - - snd_soc_update_bits(dai->codec, - MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x0F, rx_clk_fs_rate); - - switch (substream->stream) { - case SNDRV_PCM_STREAM_CAPTURE: - break; - case SNDRV_PCM_STREAM_PLAYBACK: - ret = msm_dig_cdc_set_interpolator_rate(dai, rx_fs_rate, - params_rate(params)); - if (ret < 0) { - dev_err(dai->codec->dev, - "%s: set decimator rate failed %d\n", __func__, - ret); - return ret; - } - break; - default: - dev_err(dai->codec->dev, - "%s: Invalid stream type %d\n", __func__, - substream->stream); - return -EINVAL; - } - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - snd_soc_update_bits(dai->codec, - MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x20, 0x20); - break; - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S24_3LE: - snd_soc_update_bits(dai->codec, - MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x20, 0x00); - break; - default: - dev_err(dai->codec->dev, "%s: wrong format selected\n", - __func__); - return -EINVAL; - } - return 0; -} - -static int msm_dig_cdc_codec_enable_dmic(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec); - u8 dmic_clk_en; - u16 dmic_clk_reg; - s32 *dmic_clk_cnt; - unsigned int dmic; - int ret; - char *dmic_num = strpbrk(w->name, "1234"); - - if (dmic_num == NULL) { - dev_err(codec->dev, "%s: Invalid DMIC\n", __func__); - return -EINVAL; - } - - ret = kstrtouint(dmic_num, 10, &dmic); - if (ret < 0) { - dev_err(codec->dev, - "%s: Invalid DMIC line on the codec\n", __func__); - return -EINVAL; - } - - switch (dmic) { - case 1: - case 2: - dmic_clk_en = 0x01; - dmic_clk_cnt = &(dig_cdc->dmic_1_2_clk_cnt); - dmic_clk_reg = MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL; - dev_dbg(codec->dev, - "%s() event %d DMIC%d dmic_1_2_clk_cnt %d\n", - __func__, event, dmic, *dmic_clk_cnt); - break; - case 3: - case 4: - dmic_clk_en = 0x01; - dmic_clk_cnt = &(dig_cdc->dmic_3_4_clk_cnt); - dmic_clk_reg = MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL; - dev_dbg(codec->dev, - "%s() event %d DMIC%d dmic_3_4_clk_cnt %d\n", - __func__, event, dmic, *dmic_clk_cnt); - break; - default: - dev_err(codec->dev, "%s: Invalid DMIC Selection\n", __func__); - return -EINVAL; - } - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - (*dmic_clk_cnt)++; - if (*dmic_clk_cnt == 1) { - snd_soc_update_bits(codec, dmic_clk_reg, - 0x0E, 0x04); - snd_soc_update_bits(codec, dmic_clk_reg, - dmic_clk_en, dmic_clk_en); - } - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_TX1_DMIC_CTL + (dmic - 1) * 0x20, - 0x07, 0x02); - break; - case SND_SOC_DAPM_POST_PMD: - (*dmic_clk_cnt)--; - if (*dmic_clk_cnt == 0) - snd_soc_update_bits(codec, dmic_clk_reg, - dmic_clk_en, 0); - break; - } - return 0; -} - -static int msm_dig_cdc_codec_enable_dec(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct msm_asoc_mach_data *pdata = NULL; - unsigned int decimator; - struct msm_dig_priv *msm_dig_cdc = snd_soc_codec_get_drvdata(codec); - char *dec_name = NULL; - char *widget_name = NULL; - char *temp; - int ret = 0, i; - u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg; - u8 dec_hpf_cut_of_freq; - int offset; - char *dec_num; - - pdata = snd_soc_card_get_drvdata(codec->component.card); - dev_dbg(codec->dev, "%s %d\n", __func__, event); - - widget_name = kstrndup(w->name, 15, GFP_KERNEL); - if (!widget_name) - return -ENOMEM; - temp = widget_name; - - dec_name = strsep(&widget_name, " "); - widget_name = temp; - if (!dec_name) { - dev_err(codec->dev, - "%s: Invalid decimator = %s\n", __func__, w->name); - ret = -EINVAL; - goto out; - } - - dec_num = strpbrk(dec_name, "12345"); - if (dec_num == NULL) { - dev_err(codec->dev, "%s: Invalid Decimator\n", __func__); - ret = -EINVAL; - goto out; - } - - ret = kstrtouint(dec_num, 10, &decimator); - if (ret < 0) { - dev_err(codec->dev, - "%s: Invalid decimator = %s\n", __func__, dec_name); - ret = -EINVAL; - goto out; - } - - dev_dbg(codec->dev, - "%s(): widget = %s dec_name = %s decimator = %u\n", __func__, - w->name, dec_name, decimator); - - if (w->reg == MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL) { - dec_reset_reg = MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL; - offset = 0; - } else { - dev_err(codec->dev, "%s: Error, incorrect dec\n", __func__); - ret = -EINVAL; - goto out; - } - - tx_vol_ctl_reg = MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG + - 32 * (decimator - 1); - tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX1_MUX_CTL + - 32 * (decimator - 1); - if (decimator == 5) { - tx_vol_ctl_reg = MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG; - tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX5_MUX_CTL; - } - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - /* Enableable TX digital mute */ - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01); - for (i = 0; i < NUM_DECIMATORS; i++) { - if (decimator == i + 1) - msm_dig_cdc->dec_active[i] = true; - } - - dec_hpf_cut_of_freq = snd_soc_read(codec, tx_mux_ctl_reg); - - dec_hpf_cut_of_freq = (dec_hpf_cut_of_freq & 0x30) >> 4; - - tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq = - dec_hpf_cut_of_freq; - - if (dec_hpf_cut_of_freq != CF_MIN_3DB_150HZ) { - - /* set cut of freq to CF_MIN_3DB_150HZ (0x1); */ - snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, - CF_MIN_3DB_150HZ << 4); - } - msm_dig_cdc->update_clkdiv(msm_dig_cdc->handle, 0x42); - break; - case SND_SOC_DAPM_POST_PMU: - /* enable HPF */ - snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x00); - - schedule_delayed_work( - &msm_dig_cdc->tx_mute_dwork[decimator - 1].dwork, - msecs_to_jiffies(tx_unmute_delay)); - if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq != - CF_MIN_3DB_150HZ) { - - schedule_delayed_work(&tx_hpf_work[decimator - 1].dwork, - msecs_to_jiffies(300)); - } - /* apply the digital gain after the decimator is enabled*/ - if ((w->shift) < ARRAY_SIZE(tx_digital_gain_reg)) - snd_soc_write(codec, - tx_digital_gain_reg[w->shift + offset], - snd_soc_read(codec, - tx_digital_gain_reg[w->shift + offset]) - ); - break; - case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01); - msleep(20); - snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08); - cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork); - cancel_delayed_work_sync( - &msm_dig_cdc->tx_mute_dwork[decimator - 1].dwork); - break; - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, - 1 << w->shift); - snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, 0x0); - snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08); - snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, - (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq) << 4); - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00); - for (i = 0; i < NUM_DECIMATORS; i++) { - if (decimator == i + 1) - msm_dig_cdc->dec_active[i] = false; - } - break; - } -out: - kfree(widget_name); - return ret; -} - -static int msm_dig_cdc_event_notify(struct notifier_block *block, - unsigned long val, - void *data) -{ - enum dig_cdc_notify_event event = (enum dig_cdc_notify_event)val; - struct snd_soc_codec *codec = registered_digcodec; - struct msm_dig_priv *msm_dig_cdc = snd_soc_codec_get_drvdata(codec); - struct msm_asoc_mach_data *pdata = NULL; - int ret = -EINVAL; - - pdata = snd_soc_card_get_drvdata(codec->component.card); - - switch (event) { - case DIG_CDC_EVENT_CLK_ON: - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_CLK_PDM_CTL, 0x03, 0x03); - if (pdata->mclk_freq == MCLK_RATE_12P288MHZ || - pdata->native_clk_set) - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_TOP_CTL, 0x01, 0x00); - else if (pdata->mclk_freq == MCLK_RATE_9P6MHZ) - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_TOP_CTL, 0x01, 0x01); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_CLK_MCLK_CTL, 0x01, 0x01); - break; - case DIG_CDC_EVENT_CLK_OFF: - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_CLK_PDM_CTL, 0x03, 0x00); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_CLK_MCLK_CTL, 0x01, 0x00); - break; - case DIG_CDC_EVENT_RX1_MUTE_ON: - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX1_B6_CTL, 0x01, 0x01); - msm_dig_cdc->mute_mask |= HPHL_PA_DISABLE; - break; - case DIG_CDC_EVENT_RX1_MUTE_OFF: - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX1_B6_CTL, 0x01, 0x00); - msm_dig_cdc->mute_mask &= (~HPHL_PA_DISABLE); - break; - case DIG_CDC_EVENT_RX2_MUTE_ON: - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX2_B6_CTL, 0x01, 0x01); - msm_dig_cdc->mute_mask |= HPHR_PA_DISABLE; - break; - case DIG_CDC_EVENT_RX2_MUTE_OFF: - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX2_B6_CTL, 0x01, 0x00); - msm_dig_cdc->mute_mask &= (~HPHR_PA_DISABLE); - break; - case DIG_CDC_EVENT_RX3_MUTE_ON: - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX3_B6_CTL, 0x01, 0x01); - msm_dig_cdc->mute_mask |= SPKR_PA_DISABLE; - break; - case DIG_CDC_EVENT_RX3_MUTE_OFF: - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX3_B6_CTL, 0x01, 0x00); - msm_dig_cdc->mute_mask &= (~SPKR_PA_DISABLE); - break; - case DIG_CDC_EVENT_PRE_RX1_INT_ON: - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX1_B3_CTL, 0x3C, 0x28); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX1_B4_CTL, 0x18, 0x10); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX1_B3_CTL, 0x80, 0x80); - break; - case DIG_CDC_EVENT_PRE_RX2_INT_ON: - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX2_B3_CTL, 0x3C, 0x28); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX2_B4_CTL, 0x18, 0x10); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX2_B3_CTL, 0x80, 0x80); - break; - case DIG_CDC_EVENT_POST_RX1_INT_OFF: - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX1_B3_CTL, 0x3C, 0x00); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX1_B4_CTL, 0x18, 0xFF); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX1_B3_CTL, 0x80, 0x00); - break; - case DIG_CDC_EVENT_POST_RX2_INT_OFF: - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX2_B3_CTL, 0x3C, 0x00); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX2_B4_CTL, 0x18, 0xFF); - snd_soc_update_bits(codec, - MSM89XX_CDC_CORE_RX2_B3_CTL, 0x80, 0x00); - break; - case DIG_CDC_EVENT_SSR_DOWN: - regcache_cache_only(msm_dig_cdc->regmap, true); - break; - case DIG_CDC_EVENT_SSR_UP: - regcache_cache_only(msm_dig_cdc->regmap, false); - regcache_mark_dirty(msm_dig_cdc->regmap); - - mutex_lock(&pdata->cdc_int_mclk0_mutex); - pdata->digital_cdc_core_clk.enable = 1; - ret = afe_set_lpass_clock_v2( - AFE_PORT_ID_INT0_MI2S_RX, - &pdata->digital_cdc_core_clk); - if (ret < 0) { - pr_err("%s:failed to enable the MCLK\n", - __func__); - mutex_unlock(&pdata->cdc_int_mclk0_mutex); - break; - } - mutex_unlock(&pdata->cdc_int_mclk0_mutex); - - regcache_sync(msm_dig_cdc->regmap); - - mutex_lock(&pdata->cdc_int_mclk0_mutex); - pdata->digital_cdc_core_clk.enable = 0; - afe_set_lpass_clock_v2( - AFE_PORT_ID_INT0_MI2S_RX, - &pdata->digital_cdc_core_clk); - mutex_unlock(&pdata->cdc_int_mclk0_mutex); - break; - case DIG_CDC_EVENT_INVALID: - default: - break; - } - return 0; -} - -static ssize_t msm_dig_codec_version_read(struct snd_info_entry *entry, - void *file_private_data, - struct file *file, - char __user *buf, size_t count, - loff_t pos) -{ - struct msm_dig_priv *msm_dig; - char buffer[MSM_DIG_CDC_VERSION_ENTRY_SIZE]; - int len = 0; - - msm_dig = (struct msm_dig_priv *) entry->private_data; - if (!msm_dig) { - pr_err("%s: msm_dig priv is null\n", __func__); - return -EINVAL; - } - - switch (msm_dig->version) { - case DRAX_CDC: - len = snprintf(buffer, sizeof(buffer), "SDM660-CDC_1_0\n"); - break; - default: - len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); - } - - return simple_read_from_buffer(buf, count, &pos, buffer, len); -} - -static struct snd_info_entry_ops msm_dig_codec_info_ops = { - .read = msm_dig_codec_version_read, -}; - -/* - * msm_dig_codec_info_create_codec_entry - creates msm_dig module - * @codec_root: The parent directory - * @codec: Codec instance - * - * Creates msm_dig module and version entry under the given - * parent directory. - * - * Return: 0 on success or negative error code on failure. - */ -int msm_dig_codec_info_create_codec_entry(struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) -{ - struct snd_info_entry *version_entry; - struct msm_dig_priv *msm_dig; - struct snd_soc_card *card; - - if (!codec_root || !codec) - return -EINVAL; - - msm_dig = snd_soc_codec_get_drvdata(codec); - card = codec->component.card; - msm_dig->entry = snd_info_create_subdir(codec_root->module, - "msm_digital_codec", - codec_root); - if (!msm_dig->entry) { - dev_dbg(codec->dev, "%s: failed to create msm_digital entry\n", - __func__); - return -ENOMEM; - } - - version_entry = snd_info_create_card_entry(card->snd_card, - "version", - msm_dig->entry); - if (!version_entry) { - dev_dbg(codec->dev, "%s: failed to create msm_digital version entry\n", - __func__); - return -ENOMEM; - } - - version_entry->private_data = msm_dig; - version_entry->size = MSM_DIG_CDC_VERSION_ENTRY_SIZE; - version_entry->content = SNDRV_INFO_CONTENT_DATA; - version_entry->c.ops = &msm_dig_codec_info_ops; - - if (snd_info_register(version_entry) < 0) { - snd_info_free_entry(version_entry); - return -ENOMEM; - } - msm_dig->version_entry = version_entry; - if (msm_dig->get_cdc_version) - msm_dig->version = msm_dig->get_cdc_version(msm_dig->handle); - else - msm_dig->version = DRAX_CDC; - - return 0; -} -EXPORT_SYMBOL(msm_dig_codec_info_create_codec_entry); - -static void sdm660_tx_mute_update_callback(struct work_struct *work) -{ - struct tx_mute_work *tx_mute_dwork; - struct snd_soc_codec *codec = NULL; - struct msm_dig_priv *dig_cdc; - struct delayed_work *delayed_work; - u16 tx_vol_ctl_reg = 0; - u8 decimator = 0, i; - - delayed_work = to_delayed_work(work); - tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); - dig_cdc = tx_mute_dwork->dig_cdc; - codec = dig_cdc->codec; - - for (i = 0; i < (NUM_DECIMATORS - 1); i++) { - if (dig_cdc->dec_active[i]) - decimator = i + 1; - if (decimator && decimator < NUM_DECIMATORS) { - /* unmute decimators corresponding to Tx DAI's*/ - tx_vol_ctl_reg = - MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG + - 32 * (decimator - 1); - snd_soc_update_bits(codec, tx_vol_ctl_reg, - 0x01, 0x00); - } - decimator = 0; - } -} - -static int msm_dig_cdc_soc_probe(struct snd_soc_codec *codec) -{ - struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev); - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - int i, ret; - - msm_dig_cdc->codec = codec; - - snd_soc_add_codec_controls(codec, compander_kcontrols, - ARRAY_SIZE(compander_kcontrols)); - - for (i = 0; i < NUM_DECIMATORS; i++) { - tx_hpf_work[i].dig_cdc = msm_dig_cdc; - tx_hpf_work[i].decimator = i + 1; - INIT_DELAYED_WORK(&tx_hpf_work[i].dwork, - tx_hpf_corner_freq_callback); - msm_dig_cdc->tx_mute_dwork[i].dig_cdc = msm_dig_cdc; - msm_dig_cdc->tx_mute_dwork[i].decimator = i + 1; - INIT_DELAYED_WORK(&msm_dig_cdc->tx_mute_dwork[i].dwork, - sdm660_tx_mute_update_callback); - } - - for (i = 0; i < MSM89XX_RX_MAX; i++) - msm_dig_cdc->comp_enabled[i] = COMPANDER_NONE; - - /* Register event notifier */ - msm_dig_cdc->nblock.notifier_call = msm_dig_cdc_event_notify; - if (msm_dig_cdc->register_notifier) { - ret = msm_dig_cdc->register_notifier(msm_dig_cdc->handle, - &msm_dig_cdc->nblock, - true); - if (ret) { - pr_err("%s: Failed to register notifier %d\n", - __func__, ret); - return ret; - } - } - registered_digcodec = codec; - - snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback"); - snd_soc_dapm_ignore_suspend(dapm, "AIF1 Capture"); - snd_soc_dapm_ignore_suspend(dapm, "ADC1_IN"); - snd_soc_dapm_ignore_suspend(dapm, "ADC2_IN"); - snd_soc_dapm_ignore_suspend(dapm, "ADC3_IN"); - snd_soc_dapm_ignore_suspend(dapm, "PDM_OUT_RX1"); - snd_soc_dapm_ignore_suspend(dapm, "PDM_OUT_RX2"); - snd_soc_dapm_ignore_suspend(dapm, "PDM_OUT_RX3"); - - snd_soc_dapm_sync(dapm); - - return 0; -} - -static int msm_dig_cdc_soc_remove(struct snd_soc_codec *codec) -{ - struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev); - - if (msm_dig_cdc->register_notifier) - msm_dig_cdc->register_notifier(msm_dig_cdc->handle, - &msm_dig_cdc->nblock, - false); - iounmap(msm_dig_cdc->dig_base); - return 0; -} - -static const struct snd_soc_dapm_route audio_dig_map[] = { - {"RX_I2S_CLK", NULL, "CDC_CONN"}, - {"I2S RX1", NULL, "RX_I2S_CLK"}, - {"I2S RX2", NULL, "RX_I2S_CLK"}, - {"I2S RX3", NULL, "RX_I2S_CLK"}, - - {"I2S TX1", NULL, "TX_I2S_CLK"}, - {"I2S TX2", NULL, "TX_I2S_CLK"}, - {"I2S TX3", NULL, "TX_I2S_CLK"}, - {"I2S TX4", NULL, "TX_I2S_CLK"}, - {"I2S TX5", NULL, "TX_I2S_CLK"}, - {"I2S TX6", NULL, "TX_I2S_CLK"}, - - {"I2S TX1", NULL, "DEC1 MUX"}, - {"I2S TX2", NULL, "DEC2 MUX"}, - {"I2S TX3", NULL, "I2S TX2 INP1"}, - {"I2S TX4", NULL, "I2S TX2 INP2"}, - {"I2S TX5", NULL, "DEC3 MUX"}, - {"I2S TX6", NULL, "I2S TX3 INP2"}, - - {"I2S TX2 INP1", "RX_MIX1", "RX1 MIX2"}, - {"I2S TX2 INP1", "DEC3", "DEC3 MUX"}, - {"I2S TX2 INP2", "RX_MIX2", "RX2 MIX2"}, - {"I2S TX2 INP2", "RX_MIX3", "RX3 MIX1"}, - {"I2S TX2 INP2", "DEC4", "DEC4 MUX"}, - {"I2S TX3 INP2", "DEC4", "DEC4 MUX"}, - {"I2S TX3 INP2", "DEC5", "DEC5 MUX"}, - - {"PDM_OUT_RX1", NULL, "RX1 CHAIN"}, - {"PDM_OUT_RX2", NULL, "RX2 CHAIN"}, - {"PDM_OUT_RX3", NULL, "RX3 CHAIN"}, - - {"RX1 CHAIN", NULL, "RX1 MIX2"}, - {"RX2 CHAIN", NULL, "RX2 MIX2"}, - {"RX3 CHAIN", NULL, "RX3 MIX1"}, - - {"RX1 MIX1", NULL, "RX1 MIX1 INP1"}, - {"RX1 MIX1", NULL, "RX1 MIX1 INP2"}, - {"RX1 MIX1", NULL, "RX1 MIX1 INP3"}, - {"RX2 MIX1", NULL, "RX2 MIX1 INP1"}, - {"RX2 MIX1", NULL, "RX2 MIX1 INP2"}, - {"RX3 MIX1", NULL, "RX3 MIX1 INP1"}, - {"RX3 MIX1", NULL, "RX3 MIX1 INP2"}, - {"RX1 MIX2", NULL, "RX1 MIX1"}, - {"RX1 MIX2", NULL, "RX1 MIX2 INP1"}, - {"RX2 MIX2", NULL, "RX2 MIX1"}, - {"RX2 MIX2", NULL, "RX2 MIX2 INP1"}, - - {"RX1 MIX1 INP1", "RX1", "I2S RX1"}, - {"RX1 MIX1 INP1", "RX2", "I2S RX2"}, - {"RX1 MIX1 INP1", "RX3", "I2S RX3"}, - {"RX1 MIX1 INP1", "IIR1", "IIR1"}, - {"RX1 MIX1 INP1", "IIR2", "IIR2"}, - {"RX1 MIX1 INP2", "RX1", "I2S RX1"}, - {"RX1 MIX1 INP2", "RX2", "I2S RX2"}, - {"RX1 MIX1 INP2", "RX3", "I2S RX3"}, - {"RX1 MIX1 INP2", "IIR1", "IIR1"}, - {"RX1 MIX1 INP2", "IIR2", "IIR2"}, - {"RX1 MIX1 INP3", "RX1", "I2S RX1"}, - {"RX1 MIX1 INP3", "RX2", "I2S RX2"}, - {"RX1 MIX1 INP3", "RX3", "I2S RX3"}, - - {"RX2 MIX1 INP1", "RX1", "I2S RX1"}, - {"RX2 MIX1 INP1", "RX2", "I2S RX2"}, - {"RX2 MIX1 INP1", "RX3", "I2S RX3"}, - {"RX2 MIX1 INP1", "IIR1", "IIR1"}, - {"RX2 MIX1 INP1", "IIR2", "IIR2"}, - {"RX2 MIX1 INP2", "RX1", "I2S RX1"}, - {"RX2 MIX1 INP2", "RX2", "I2S RX2"}, - {"RX2 MIX1 INP2", "RX3", "I2S RX3"}, - {"RX2 MIX1 INP2", "IIR1", "IIR1"}, - {"RX2 MIX1 INP2", "IIR2", "IIR2"}, - {"RX2 MIX1 INP3", "RX1", "I2S RX1"}, - {"RX2 MIX1 INP3", "RX2", "I2S RX2"}, - {"RX2 MIX1 INP3", "RX3", "I2S RX3"}, - - {"RX3 MIX1 INP1", "RX1", "I2S RX1"}, - {"RX3 MIX1 INP1", "RX2", "I2S RX2"}, - {"RX3 MIX1 INP1", "RX3", "I2S RX3"}, - {"RX3 MIX1 INP1", "IIR1", "IIR1"}, - {"RX3 MIX1 INP1", "IIR2", "IIR2"}, - {"RX3 MIX1 INP2", "RX1", "I2S RX1"}, - {"RX3 MIX1 INP2", "RX2", "I2S RX2"}, - {"RX3 MIX1 INP2", "RX3", "I2S RX3"}, - {"RX3 MIX1 INP2", "IIR1", "IIR1"}, - {"RX3 MIX1 INP2", "IIR2", "IIR2"}, - {"RX3 MIX1 INP3", "RX1", "I2S RX1"}, - {"RX3 MIX1 INP3", "RX2", "I2S RX2"}, - {"RX3 MIX1 INP3", "RX3", "I2S RX3"}, - - {"RX1 MIX2 INP1", "IIR1", "IIR1"}, - {"RX2 MIX2 INP1", "IIR1", "IIR1"}, - {"RX1 MIX2 INP1", "IIR2", "IIR2"}, - {"RX2 MIX2 INP1", "IIR2", "IIR2"}, - - /* Decimator Inputs */ - {"DEC1 MUX", "DMIC1", "DMIC1"}, - {"DEC1 MUX", "DMIC2", "DMIC2"}, - {"DEC1 MUX", "DMIC3", "DMIC3"}, - {"DEC1 MUX", "DMIC4", "DMIC4"}, - {"DEC1 MUX", "ADC1", "ADC1_IN"}, - {"DEC1 MUX", "ADC2", "ADC2_IN"}, - {"DEC1 MUX", "ADC3", "ADC3_IN"}, - {"DEC1 MUX", NULL, "CDC_CONN"}, - - {"DEC2 MUX", "DMIC1", "DMIC1"}, - {"DEC2 MUX", "DMIC2", "DMIC2"}, - {"DEC2 MUX", "DMIC3", "DMIC3"}, - {"DEC2 MUX", "DMIC4", "DMIC4"}, - {"DEC2 MUX", "ADC1", "ADC1_IN"}, - {"DEC2 MUX", "ADC2", "ADC2_IN"}, - {"DEC2 MUX", "ADC3", "ADC3_IN"}, - {"DEC2 MUX", NULL, "CDC_CONN"}, - - {"DEC3 MUX", "DMIC1", "DMIC1"}, - {"DEC3 MUX", "DMIC2", "DMIC2"}, - {"DEC3 MUX", "DMIC3", "DMIC3"}, - {"DEC3 MUX", "DMIC4", "DMIC4"}, - {"DEC3 MUX", "ADC1", "ADC1_IN"}, - {"DEC3 MUX", "ADC2", "ADC2_IN"}, - {"DEC3 MUX", "ADC3", "ADC3_IN"}, - {"DEC3 MUX", NULL, "CDC_CONN"}, - - {"DEC4 MUX", "DMIC1", "DMIC1"}, - {"DEC4 MUX", "DMIC2", "DMIC2"}, - {"DEC4 MUX", "DMIC3", "DMIC3"}, - {"DEC4 MUX", "DMIC4", "DMIC4"}, - {"DEC4 MUX", "ADC1", "ADC1_IN"}, - {"DEC4 MUX", "ADC2", "ADC2_IN"}, - {"DEC4 MUX", "ADC3", "ADC3_IN"}, - {"DEC4 MUX", NULL, "CDC_CONN"}, - - {"DEC5 MUX", "DMIC1", "DMIC1"}, - {"DEC5 MUX", "DMIC2", "DMIC2"}, - {"DEC5 MUX", "DMIC3", "DMIC3"}, - {"DEC5 MUX", "DMIC4", "DMIC4"}, - {"DEC5 MUX", "ADC1", "ADC1_IN"}, - {"DEC5 MUX", "ADC2", "ADC2_IN"}, - {"DEC5 MUX", "ADC3", "ADC3_IN"}, - {"DEC5 MUX", NULL, "CDC_CONN"}, - - {"IIR1", NULL, "IIR1 INP1 MUX"}, - {"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"}, - {"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"}, - {"IIR1 INP1 MUX", "DEC3", "DEC3 MUX"}, - {"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"}, - {"IIR2", NULL, "IIR2 INP1 MUX"}, - {"IIR2 INP1 MUX", "DEC1", "DEC1 MUX"}, - {"IIR2 INP1 MUX", "DEC2", "DEC2 MUX"}, - {"IIR1 INP1 MUX", "DEC3", "DEC3 MUX"}, - {"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"}, -}; - - -static const char * const i2s_tx2_inp1_text[] = { - "ZERO", "RX_MIX1", "DEC3" -}; - -static const char * const i2s_tx2_inp2_text[] = { - "ZERO", "RX_MIX2", "RX_MIX3", "DEC4" -}; - -static const char * const i2s_tx3_inp2_text[] = { - "DEC4", "DEC5" -}; - -static const char * const rx_mix1_text[] = { - "ZERO", "IIR1", "IIR2", "RX1", "RX2", "RX3" -}; - -static const char * const rx_mix2_text[] = { - "ZERO", "IIR1", "IIR2" -}; - -static const char * const dec_mux_text[] = { - "ZERO", "ADC1", "ADC2", "ADC3", "DMIC1", "DMIC2", "DMIC3", "DMIC4" -}; - -static const char * const iir_inp1_text[] = { - "ZERO", "DEC1", "DEC2", "RX1", "RX2", "RX3", "DEC3", "DEC4" -}; - -/* I2S TX MUXes */ -static const struct soc_enum i2s_tx2_inp1_chain_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL, - 2, 3, i2s_tx2_inp1_text); - -static const struct soc_enum i2s_tx2_inp2_chain_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL, - 0, 4, i2s_tx2_inp2_text); - -static const struct soc_enum i2s_tx3_inp2_chain_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL, - 4, 2, i2s_tx3_inp2_text); - -/* RX1 MIX1 */ -static const struct soc_enum rx_mix1_inp1_chain_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B1_CTL, - 0, 6, rx_mix1_text); - -static const struct soc_enum rx_mix1_inp2_chain_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B1_CTL, - 3, 6, rx_mix1_text); - -static const struct soc_enum rx_mix1_inp3_chain_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B2_CTL, - 0, 6, rx_mix1_text); - -/* RX1 MIX2 */ -static const struct soc_enum rx_mix2_inp1_chain_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B3_CTL, - 0, 3, rx_mix2_text); - -/* RX2 MIX1 */ -static const struct soc_enum rx2_mix1_inp1_chain_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX2_B1_CTL, - 0, 6, rx_mix1_text); - -static const struct soc_enum rx2_mix1_inp2_chain_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX2_B1_CTL, - 3, 6, rx_mix1_text); - -static const struct soc_enum rx2_mix1_inp3_chain_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX2_B1_CTL, - 0, 6, rx_mix1_text); - -/* RX2 MIX2 */ -static const struct soc_enum rx2_mix2_inp1_chain_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX2_B3_CTL, - 0, 3, rx_mix2_text); - -/* RX3 MIX1 */ -static const struct soc_enum rx3_mix1_inp1_chain_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX3_B1_CTL, - 0, 6, rx_mix1_text); - -static const struct soc_enum rx3_mix1_inp2_chain_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX3_B1_CTL, - 3, 6, rx_mix1_text); - -static const struct soc_enum rx3_mix1_inp3_chain_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX3_B1_CTL, - 0, 6, rx_mix1_text); - -/* DEC */ -static const struct soc_enum dec1_mux_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B1_CTL, - 0, 8, dec_mux_text); - -static const struct soc_enum dec2_mux_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B1_CTL, - 3, 8, dec_mux_text); - -static const struct soc_enum dec3_mux_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B2_CTL, - 0, 8, dec_mux_text); - -static const struct soc_enum dec4_mux_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B2_CTL, - 3, 8, dec_mux_text); - -static const struct soc_enum decsva_mux_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B3_CTL, - 0, 8, dec_mux_text); - -static const struct soc_enum iir1_inp1_mux_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL, - 0, 8, iir_inp1_text); - -static const struct soc_enum iir2_inp1_mux_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL, - 0, 8, iir_inp1_text); - -/*cut of frequency for high pass filter*/ -static const char * const cf_text[] = { - "MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz" -}; - -static const struct soc_enum cf_rxmix1_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_RX1_B4_CTL, 0, 3, cf_text); - -static const struct soc_enum cf_rxmix2_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_RX2_B4_CTL, 0, 3, cf_text); - -static const struct soc_enum cf_rxmix3_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_RX3_B4_CTL, 0, 3, cf_text); - -static const struct snd_kcontrol_new rx3_mix1_inp1_mux = - SOC_DAPM_ENUM("RX3 MIX1 INP1 Mux", rx3_mix1_inp1_chain_enum); - -#define MSM89XX_DEC_ENUM(xname, xenum) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_enum_double, \ - .get = snd_soc_dapm_get_enum_double, \ - .put = msm_dig_cdc_put_dec_enum, \ - .private_value = (unsigned long)&xenum } - -static const struct snd_kcontrol_new dec1_mux = - MSM89XX_DEC_ENUM("DEC1 MUX Mux", dec1_mux_enum); - -static const struct snd_kcontrol_new dec2_mux = - MSM89XX_DEC_ENUM("DEC2 MUX Mux", dec2_mux_enum); - -static const struct snd_kcontrol_new dec3_mux = - MSM89XX_DEC_ENUM("DEC3 MUX Mux", dec3_mux_enum); - -static const struct snd_kcontrol_new dec4_mux = - MSM89XX_DEC_ENUM("DEC4 MUX Mux", dec4_mux_enum); - -static const struct snd_kcontrol_new decsva_mux = - MSM89XX_DEC_ENUM("DEC5 MUX Mux", decsva_mux_enum); - -static const struct snd_kcontrol_new i2s_tx2_inp1_mux = - SOC_DAPM_ENUM("I2S TX2 INP1 Mux", i2s_tx2_inp1_chain_enum); - -static const struct snd_kcontrol_new i2s_tx2_inp2_mux = - SOC_DAPM_ENUM("I2S TX2 INP2 Mux", i2s_tx2_inp2_chain_enum); - -static const struct snd_kcontrol_new i2s_tx3_inp2_mux = - SOC_DAPM_ENUM("I2S TX3 INP2 Mux", i2s_tx3_inp2_chain_enum); - -static const struct snd_kcontrol_new iir1_inp1_mux = - SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum); - -static const struct snd_kcontrol_new iir2_inp1_mux = - SOC_DAPM_ENUM("IIR2 INP1 Mux", iir2_inp1_mux_enum); - -static const struct snd_kcontrol_new rx_mix1_inp1_mux = - SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum); - -static const struct snd_kcontrol_new rx_mix1_inp2_mux = - SOC_DAPM_ENUM("RX1 MIX1 INP2 Mux", rx_mix1_inp2_chain_enum); - -static const struct snd_kcontrol_new rx_mix1_inp3_mux = - SOC_DAPM_ENUM("RX1 MIX1 INP3 Mux", rx_mix1_inp3_chain_enum); - -static const struct snd_kcontrol_new rx2_mix1_inp1_mux = - SOC_DAPM_ENUM("RX2 MIX1 INP1 Mux", rx2_mix1_inp1_chain_enum); - -static const struct snd_kcontrol_new rx2_mix1_inp2_mux = - SOC_DAPM_ENUM("RX2 MIX1 INP2 Mux", rx2_mix1_inp2_chain_enum); - -static const struct snd_kcontrol_new rx2_mix1_inp3_mux = - SOC_DAPM_ENUM("RX2 MIX1 INP3 Mux", rx2_mix1_inp3_chain_enum); - -static const struct snd_kcontrol_new rx3_mix1_inp2_mux = - SOC_DAPM_ENUM("RX3 MIX1 INP2 Mux", rx3_mix1_inp2_chain_enum); - -static const struct snd_kcontrol_new rx3_mix1_inp3_mux = - SOC_DAPM_ENUM("RX3 MIX1 INP3 Mux", rx3_mix1_inp3_chain_enum); - -static const struct snd_kcontrol_new rx1_mix2_inp1_mux = - SOC_DAPM_ENUM("RX1 MIX2 INP1 Mux", rx_mix2_inp1_chain_enum); - -static const struct snd_kcontrol_new rx2_mix2_inp1_mux = - SOC_DAPM_ENUM("RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum); - -static const struct snd_soc_dapm_widget msm_dig_dapm_widgets[] = { - SND_SOC_DAPM_AIF_IN("I2S RX1", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_IN("I2S RX2", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_IN("I2S RX3", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), - - SND_SOC_DAPM_AIF_OUT("I2S TX1", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("I2S TX2", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("I2S TX3", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("I2S TX4", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("I2S TX5", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("I2S TX6", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), - - SND_SOC_DAPM_MIXER_E("RX1 MIX2", MSM89XX_CDC_CORE_CLK_RX_B1_CTL, - MSM89XX_RX1, 0, NULL, 0, - msm_dig_cdc_codec_enable_interpolator, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER_E("RX2 MIX2", MSM89XX_CDC_CORE_CLK_RX_B1_CTL, - MSM89XX_RX2, 0, NULL, 0, - msm_dig_cdc_codec_enable_interpolator, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER_E("RX3 MIX1", MSM89XX_CDC_CORE_CLK_RX_B1_CTL, - MSM89XX_RX3, 0, NULL, 0, - msm_dig_cdc_codec_enable_interpolator, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), - - SND_SOC_DAPM_MIXER("RX1 CHAIN", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("RX2 CHAIN", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("RX3 CHAIN", SND_SOC_NOPM, 0, 0, NULL, 0), - - SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0, - &rx_mix1_inp1_mux), - SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0, - &rx_mix1_inp2_mux), - SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0, - &rx_mix1_inp3_mux), - - SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0, - &rx2_mix1_inp1_mux), - SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0, - &rx2_mix1_inp2_mux), - SND_SOC_DAPM_MUX("RX2 MIX1 INP3", SND_SOC_NOPM, 0, 0, - &rx2_mix1_inp3_mux), - - SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0, - &rx3_mix1_inp1_mux), - SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0, - &rx3_mix1_inp2_mux), - SND_SOC_DAPM_MUX("RX3 MIX1 INP3", SND_SOC_NOPM, 0, 0, - &rx3_mix1_inp3_mux), - - SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0, - &rx1_mix2_inp1_mux), - SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0, - &rx2_mix2_inp1_mux), - - SND_SOC_DAPM_SUPPLY_S("CDC_CONN", -2, MSM89XX_CDC_CORE_CLK_OTHR_CTL, - 2, 0, NULL, 0), - - SND_SOC_DAPM_MUX_E("DEC1 MUX", - MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 0, 0, - &dec1_mux, msm_dig_cdc_codec_enable_dec, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX_E("DEC2 MUX", - MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 1, 0, - &dec2_mux, msm_dig_cdc_codec_enable_dec, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX_E("DEC3 MUX", - MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 2, 0, - &dec3_mux, msm_dig_cdc_codec_enable_dec, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX_E("DEC4 MUX", - MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 3, 0, - &dec4_mux, msm_dig_cdc_codec_enable_dec, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX_E("DEC5 MUX", - MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 4, 0, - &decsva_mux, msm_dig_cdc_codec_enable_dec, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - - /* Sidetone */ - SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux), - SND_SOC_DAPM_PGA_E("IIR1", MSM89XX_CDC_CORE_CLK_SD_CTL, 0, 0, NULL, 0, - msm_dig_cdc_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU), - - SND_SOC_DAPM_MUX("IIR2 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir2_inp1_mux), - SND_SOC_DAPM_PGA_E("IIR2", MSM89XX_CDC_CORE_CLK_SD_CTL, 1, 0, NULL, 0, - msm_dig_cdc_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU), - - SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", - MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 4, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("TX_I2S_CLK", - MSM89XX_CDC_CORE_CLK_TX_I2S_CTL, 4, 0, NULL, 0), - - - SND_SOC_DAPM_MUX("I2S TX2 INP1", SND_SOC_NOPM, 0, 0, - &i2s_tx2_inp1_mux), - SND_SOC_DAPM_MUX("I2S TX2 INP2", SND_SOC_NOPM, 0, 0, - &i2s_tx2_inp2_mux), - SND_SOC_DAPM_MUX("I2S TX3 INP2", SND_SOC_NOPM, 0, 0, - &i2s_tx3_inp2_mux), - - /* Digital Mic Inputs */ - SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0, - msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0, - msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0, - msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0, - msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_INPUT("ADC1_IN"), - SND_SOC_DAPM_INPUT("ADC2_IN"), - SND_SOC_DAPM_INPUT("ADC3_IN"), - SND_SOC_DAPM_OUTPUT("PDM_OUT_RX1"), - SND_SOC_DAPM_OUTPUT("PDM_OUT_RX2"), - SND_SOC_DAPM_OUTPUT("PDM_OUT_RX3"), -}; - -static const struct soc_enum cf_dec1_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX1_MUX_CTL, 4, 3, cf_text); - -static const struct soc_enum cf_dec2_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX2_MUX_CTL, 4, 3, cf_text); - -static const struct soc_enum cf_dec3_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX3_MUX_CTL, 4, 3, cf_text); - -static const struct soc_enum cf_dec4_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX4_MUX_CTL, 4, 3, cf_text); - -static const struct soc_enum cf_decsva_enum = - SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX5_MUX_CTL, 4, 3, cf_text); - -static const struct snd_kcontrol_new msm_dig_snd_controls[] = { - SOC_SINGLE_SX_TLV("DEC1 Volume", - MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("DEC2 Volume", - MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("DEC3 Volume", - MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("DEC4 Volume", - MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("DEC5 Volume", - MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN, - 0, -84, 40, digital_gain), - - SOC_SINGLE_SX_TLV("IIR1 INP1 Volume", - MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR1 INP2 Volume", - MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR1 INP3 Volume", - MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR1 INP4 Volume", - MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP1 Volume", - MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL, - 0, -84, 40, digital_gain), - - SOC_SINGLE_SX_TLV("RX1 Digital Volume", - MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX2 Digital Volume", - MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX3 Digital Volume", - MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL, - 0, -84, 40, digital_gain), - - SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0, - msm_dig_cdc_get_iir_enable_audio_mixer, - msm_dig_cdc_put_iir_enable_audio_mixer), - SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0, - msm_dig_cdc_get_iir_enable_audio_mixer, - msm_dig_cdc_put_iir_enable_audio_mixer), - SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0, - msm_dig_cdc_get_iir_enable_audio_mixer, - msm_dig_cdc_put_iir_enable_audio_mixer), - SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0, - msm_dig_cdc_get_iir_enable_audio_mixer, - msm_dig_cdc_put_iir_enable_audio_mixer), - SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0, - msm_dig_cdc_get_iir_enable_audio_mixer, - msm_dig_cdc_put_iir_enable_audio_mixer), - - SOC_SINGLE_EXT("IIR2 Enable Band1", IIR2, BAND1, 1, 0, - msm_dig_cdc_get_iir_enable_audio_mixer, - msm_dig_cdc_put_iir_enable_audio_mixer), - SOC_SINGLE_EXT("IIR2 Enable Band2", IIR2, BAND2, 1, 0, - msm_dig_cdc_get_iir_enable_audio_mixer, - msm_dig_cdc_put_iir_enable_audio_mixer), - SOC_SINGLE_EXT("IIR2 Enable Band3", IIR2, BAND3, 1, 0, - msm_dig_cdc_get_iir_enable_audio_mixer, - msm_dig_cdc_put_iir_enable_audio_mixer), - SOC_SINGLE_EXT("IIR2 Enable Band4", IIR2, BAND4, 1, 0, - msm_dig_cdc_get_iir_enable_audio_mixer, - msm_dig_cdc_put_iir_enable_audio_mixer), - SOC_SINGLE_EXT("IIR2 Enable Band5", IIR2, BAND5, 1, 0, - msm_dig_cdc_get_iir_enable_audio_mixer, - msm_dig_cdc_put_iir_enable_audio_mixer), - - SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5, - msm_dig_cdc_get_iir_band_audio_mixer, - msm_dig_cdc_put_iir_band_audio_mixer), - SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5, - msm_dig_cdc_get_iir_band_audio_mixer, - msm_dig_cdc_put_iir_band_audio_mixer), - SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5, - msm_dig_cdc_get_iir_band_audio_mixer, - msm_dig_cdc_put_iir_band_audio_mixer), - SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5, - msm_dig_cdc_get_iir_band_audio_mixer, - msm_dig_cdc_put_iir_band_audio_mixer), - SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5, - msm_dig_cdc_get_iir_band_audio_mixer, - msm_dig_cdc_put_iir_band_audio_mixer), - - SOC_SINGLE_MULTI_EXT("IIR2 Band1", IIR2, BAND1, 255, 0, 5, - msm_dig_cdc_get_iir_band_audio_mixer, - msm_dig_cdc_put_iir_band_audio_mixer), - SOC_SINGLE_MULTI_EXT("IIR2 Band2", IIR2, BAND2, 255, 0, 5, - msm_dig_cdc_get_iir_band_audio_mixer, - msm_dig_cdc_put_iir_band_audio_mixer), - SOC_SINGLE_MULTI_EXT("IIR2 Band3", IIR2, BAND3, 255, 0, 5, - msm_dig_cdc_get_iir_band_audio_mixer, - msm_dig_cdc_put_iir_band_audio_mixer), - SOC_SINGLE_MULTI_EXT("IIR2 Band4", IIR2, BAND4, 255, 0, 5, - msm_dig_cdc_get_iir_band_audio_mixer, - msm_dig_cdc_put_iir_band_audio_mixer), - SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5, - msm_dig_cdc_get_iir_band_audio_mixer, - msm_dig_cdc_put_iir_band_audio_mixer), - - SOC_SINGLE("RX1 HPF Switch", - MSM89XX_CDC_CORE_RX1_B5_CTL, 2, 1, 0), - SOC_SINGLE("RX2 HPF Switch", - MSM89XX_CDC_CORE_RX2_B5_CTL, 2, 1, 0), - SOC_SINGLE("RX3 HPF Switch", - MSM89XX_CDC_CORE_RX3_B5_CTL, 2, 1, 0), - - SOC_ENUM("RX1 HPF cut off", cf_rxmix1_enum), - SOC_ENUM("RX2 HPF cut off", cf_rxmix2_enum), - SOC_ENUM("RX3 HPF cut off", cf_rxmix3_enum), - - SOC_ENUM("TX1 HPF cut off", cf_dec1_enum), - SOC_ENUM("TX2 HPF cut off", cf_dec2_enum), - SOC_ENUM("TX3 HPF cut off", cf_dec3_enum), - SOC_ENUM("TX4 HPF cut off", cf_dec4_enum), - SOC_ENUM("TX5 HPF cut off", cf_decsva_enum), - SOC_SINGLE("TX1 HPF Switch", - MSM89XX_CDC_CORE_TX1_MUX_CTL, 3, 1, 0), - SOC_SINGLE("TX2 HPF Switch", - MSM89XX_CDC_CORE_TX2_MUX_CTL, 3, 1, 0), - SOC_SINGLE("TX3 HPF Switch", - MSM89XX_CDC_CORE_TX3_MUX_CTL, 3, 1, 0), - SOC_SINGLE("TX4 HPF Switch", - MSM89XX_CDC_CORE_TX4_MUX_CTL, 3, 1, 0), - SOC_SINGLE("TX5 HPF Switch", - MSM89XX_CDC_CORE_TX5_MUX_CTL, 3, 1, 0), -}; - -static struct snd_soc_dai_ops msm_dig_dai_ops = { - .hw_params = msm_dig_cdc_hw_params, -}; - - -static struct snd_soc_dai_driver msm_codec_dais[] = { - { - .name = "msm_dig_cdc_dai_rx1", - .id = AIF1_PB, - .playback = { /* Support maximum range */ - .stream_name = "AIF1 Playback", - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_192000, - .rate_max = 192000, - .rate_min = 8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S24_3LE, - }, - .ops = &msm_dig_dai_ops, - }, - { - .name = "msm_dig_cdc_dai_tx1", - .id = AIF1_CAP, - .capture = { /* Support maximum range */ - .stream_name = "AIF1 Capture", - .channels_min = 1, - .channels_max = 4, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .ops = &msm_dig_dai_ops, - }, - { - .name = "msm_dig_cdc_dai_tx2", - .id = AIF3_SVA, - .capture = { /* Support maximum range */ - .stream_name = "AIF2 Capture", - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .ops = &msm_dig_dai_ops, - }, - { - .name = "msm_dig_cdc_dai_vifeed", - .id = AIF2_VIFEED, - .capture = { /* Support maximum range */ - .stream_name = "AIF2 Capture", - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .ops = &msm_dig_dai_ops, - }, -}; - -static struct regmap *msm_digital_get_regmap(struct device *dev) -{ - struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(dev); - - return msm_dig_cdc->regmap; -} - -static int msm_dig_cdc_suspend(struct snd_soc_codec *codec) -{ - struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev); - - msm_dig_cdc->dapm_bias_off = 1; - return 0; -} - -static int msm_dig_cdc_resume(struct snd_soc_codec *codec) -{ - struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev); - - msm_dig_cdc->dapm_bias_off = 0; - return 0; -} - -static struct snd_soc_codec_driver soc_msm_dig_codec = { - .probe = msm_dig_cdc_soc_probe, - .remove = msm_dig_cdc_soc_remove, - .suspend = msm_dig_cdc_suspend, - .resume = msm_dig_cdc_resume, - .get_regmap = msm_digital_get_regmap, - .component_driver = { - .controls = msm_dig_snd_controls, - .num_controls = ARRAY_SIZE(msm_dig_snd_controls), - .dapm_widgets = msm_dig_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(msm_dig_dapm_widgets), - .dapm_routes = audio_dig_map, - .num_dapm_routes = ARRAY_SIZE(audio_dig_map), - }, -}; - -const struct regmap_config msm_digital_regmap_config = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 8, - .lock = enable_digital_callback, - .unlock = disable_digital_callback, - .cache_type = REGCACHE_FLAT, - .reg_defaults = msm89xx_cdc_core_defaults, - .num_reg_defaults = MSM89XX_CDC_CORE_MAX_REGISTER, - .writeable_reg = msm89xx_cdc_core_writeable_reg, - .readable_reg = msm89xx_cdc_core_readable_reg, - .volatile_reg = msm89xx_cdc_core_volatile_reg, - .reg_format_endian = REGMAP_ENDIAN_NATIVE, - .val_format_endian = REGMAP_ENDIAN_NATIVE, - .max_register = MSM89XX_CDC_CORE_MAX_REGISTER, -}; - -static int msm_dig_cdc_probe(struct platform_device *pdev) -{ - int ret; - u32 dig_cdc_addr; - struct msm_dig_priv *msm_dig_cdc; - struct dig_ctrl_platform_data *pdata; - - msm_dig_cdc = devm_kzalloc(&pdev->dev, sizeof(struct msm_dig_priv), - GFP_KERNEL); - if (!msm_dig_cdc) - return -ENOMEM; - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) { - dev_err(&pdev->dev, "%s: pdata from parent is NULL\n", - __func__); - ret = -EINVAL; - goto rtn; - } - - ret = of_property_read_u32(pdev->dev.of_node, "reg", - &dig_cdc_addr); - if (ret) { - dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", - __func__, "reg"); - return ret; - } - - msm_dig_cdc->dig_base = ioremap(dig_cdc_addr, - MSM89XX_CDC_CORE_MAX_REGISTER); - if (msm_dig_cdc->dig_base == NULL) { - dev_err(&pdev->dev, "%s ioremap failed\n", __func__); - return -ENOMEM; - } - msm_dig_cdc->regmap = - devm_regmap_init_mmio_clk(&pdev->dev, NULL, - msm_dig_cdc->dig_base, &msm_digital_regmap_config); - - msm_dig_cdc->update_clkdiv = pdata->update_clkdiv; - msm_dig_cdc->set_compander_mode = pdata->set_compander_mode; - msm_dig_cdc->get_cdc_version = pdata->get_cdc_version; - msm_dig_cdc->handle = pdata->handle; - msm_dig_cdc->register_notifier = pdata->register_notifier; - - dev_set_drvdata(&pdev->dev, msm_dig_cdc); - snd_soc_register_codec(&pdev->dev, &soc_msm_dig_codec, - msm_codec_dais, ARRAY_SIZE(msm_codec_dais)); - dev_dbg(&pdev->dev, "%s: registered DIG CODEC 0x%x\n", - __func__, dig_cdc_addr); -rtn: - return ret; -} - -static int msm_dig_cdc_remove(struct platform_device *pdev) -{ - snd_soc_unregister_codec(&pdev->dev); - return 0; -} - -#ifdef CONFIG_PM -static int msm_dig_suspend(struct device *dev) -{ - struct msm_asoc_mach_data *pdata; - struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(dev); - - if (!registered_digcodec || !msm_dig_cdc) { - pr_debug("%s:digcodec not initialized, return\n", __func__); - return 0; - } - pdata = snd_soc_card_get_drvdata(registered_digcodec->component.card); - if (!pdata) { - pr_debug("%s:card not initialized, return\n", __func__); - return 0; - } - if (msm_dig_cdc->dapm_bias_off) { - pr_debug("%s: mclk cnt = %d, mclk_enabled = %d\n", - __func__, atomic_read(&pdata->int_mclk0_rsc_ref), - atomic_read(&pdata->int_mclk0_enabled)); - - if (atomic_read(&pdata->int_mclk0_enabled) == true) { - cancel_delayed_work_sync( - &pdata->disable_int_mclk0_work); - mutex_lock(&pdata->cdc_int_mclk0_mutex); - pdata->digital_cdc_core_clk.enable = 0; - afe_set_lpass_clock_v2(AFE_PORT_ID_INT0_MI2S_RX, - &pdata->digital_cdc_core_clk); - atomic_set(&pdata->int_mclk0_enabled, false); - mutex_unlock(&pdata->cdc_int_mclk0_mutex); - } - } - - return 0; -} - -static int msm_dig_resume(struct device *dev) -{ - return 0; -} - -static const struct dev_pm_ops msm_dig_pm_ops = { - .suspend_late = msm_dig_suspend, - .resume_early = msm_dig_resume, -}; -#endif - -static const struct of_device_id msm_dig_cdc_of_match[] = { - {.compatible = "qcom,msm-digital-codec"}, - {}, -}; - -static struct platform_driver msm_digcodec_driver = { - .driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, - .of_match_table = msm_dig_cdc_of_match, -#ifdef CONFIG_PM - .pm = &msm_dig_pm_ops, -#endif - }, - .probe = msm_dig_cdc_probe, - .remove = msm_dig_cdc_remove, -}; -module_platform_driver(msm_digcodec_driver); - -MODULE_DESCRIPTION("MSM Audio Digital codec driver"); -MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.h b/asoc/codecs/sdm660_cdc/msm-digital-cdc.h deleted file mode 100644 index 7abb2045b79c..000000000000 --- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.h +++ /dev/null @@ -1,116 +0,0 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef MSM_DIGITAL_CDC_H -#define MSM_DIGITAL_CDC_H - -#define HPHL_PA_DISABLE (0x01 << 1) -#define HPHR_PA_DISABLE (0x01 << 2) -#define SPKR_PA_DISABLE (0x01 << 3) - -#define NUM_DECIMATORS 5 -/* Codec supports 1 compander */ -enum { - COMPANDER_NONE = 0, - COMPANDER_1, /* HPHL/R */ - COMPANDER_MAX, -}; - -/* Number of output I2S port */ -enum { - MSM89XX_RX1 = 0, - MSM89XX_RX2, - MSM89XX_RX3, - MSM89XX_RX_MAX, -}; - -struct tx_mute_work { - struct msm_dig_priv *dig_cdc; - u32 decimator; - struct delayed_work dwork; -}; - -struct msm_dig_priv { - struct snd_soc_codec *codec; - u32 comp_enabled[MSM89XX_RX_MAX]; - int (*codec_hph_comp_gpio)(bool enable, struct snd_soc_codec *codec); - s32 dmic_1_2_clk_cnt; - s32 dmic_3_4_clk_cnt; - bool dec_active[NUM_DECIMATORS]; - int version; - /* Entry for version info */ - struct snd_info_entry *entry; - struct snd_info_entry *version_entry; - char __iomem *dig_base; - struct regmap *regmap; - struct notifier_block nblock; - u32 mute_mask; - int dapm_bias_off; - void *handle; - void (*set_compander_mode)(void *handle, int val); - void (*update_clkdiv)(void *handle, int val); - int (*get_cdc_version)(void *handle); - int (*register_notifier)(void *handle, - struct notifier_block *nblock, - bool enable); - struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS]; -}; - -struct dig_ctrl_platform_data { - void *handle; - void (*set_compander_mode)(void *handle, int val); - void (*update_clkdiv)(void *handle, int val); - int (*get_cdc_version)(void *handle); - int (*register_notifier)(void *handle, - struct notifier_block *nblock, - bool enable); -}; - -struct hpf_work { - struct msm_dig_priv *dig_cdc; - u32 decimator; - u8 tx_hpf_cut_of_freq; - struct delayed_work dwork; -}; - -/* Codec supports 5 bands */ -enum { - BAND1 = 0, - BAND2, - BAND3, - BAND4, - BAND5, - BAND_MAX, -}; - -#if IS_ENABLED(CONFIG_SND_SOC_DIGITAL_CDC) -extern void msm_dig_cdc_hph_comp_cb( - int (*codec_hph_comp_gpio)( - bool enable, struct snd_soc_codec *codec), - struct snd_soc_codec *codec); -int msm_dig_codec_info_create_codec_entry(struct snd_info_entry *codec_root, - struct snd_soc_codec *codec); -#else /* CONFIG_SND_SOC_DIGITAL_CDC */ -static inline void msm_dig_cdc_hph_comp_cb( - int (*codec_hph_comp_gpio)( - bool enable, struct snd_soc_codec *codec), - struct snd_soc_codec *codec) -{ - -} -static inline int msm_dig_codec_info_create_codec_entry( - struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) -{ - return 0; -} -#endif /* CONFIG_SND_SOC_DIGITAL_CDC */ -#endif diff --git a/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c b/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c deleted file mode 100644 index 673b738b4eac..000000000000 --- a/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c +++ /dev/null @@ -1,418 +0,0 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "msm-analog-cdc.h" -#include "sdm660-cdc-irq.h" -#include "sdm660-cdc-registers.h" - -#define MAX_NUM_IRQS 14 -#define NUM_IRQ_REGS 2 -#define WCD9XXX_SYSTEM_RESUME_TIMEOUT_MS 700 - -#define BYTE_BIT_MASK(nr) (1UL << ((nr) % BITS_PER_BYTE)) -#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE) - -static irqreturn_t wcd9xxx_spmi_irq_handler(int linux_irq, void *data); - -char *irq_names[MAX_NUM_IRQS] = { - "spk_cnp_int", - "spk_clip_int", - "spk_ocp_int", - "ins_rem_det1", - "but_rel_det", - "but_press_det", - "ins_rem_det", - "mbhc_int", - "ear_ocp_int", - "hphr_ocp_int", - "hphl_ocp_det", - "ear_cnp_int", - "hphr_cnp_int", - "hphl_cnp_int" -}; - -int order[MAX_NUM_IRQS] = { - MSM89XX_IRQ_SPKR_CNP, - MSM89XX_IRQ_SPKR_CLIP, - MSM89XX_IRQ_SPKR_OCP, - MSM89XX_IRQ_MBHC_INSREM_DET1, - MSM89XX_IRQ_MBHC_RELEASE, - MSM89XX_IRQ_MBHC_PRESS, - MSM89XX_IRQ_MBHC_INSREM_DET, - MSM89XX_IRQ_MBHC_HS_DET, - MSM89XX_IRQ_EAR_OCP, - MSM89XX_IRQ_HPHR_OCP, - MSM89XX_IRQ_HPHL_OCP, - MSM89XX_IRQ_EAR_CNP, - MSM89XX_IRQ_HPHR_CNP, - MSM89XX_IRQ_HPHL_CNP, -}; - -enum wcd9xxx_spmi_pm_state { - WCD9XXX_PM_SLEEPABLE, - WCD9XXX_PM_AWAKE, - WCD9XXX_PM_ASLEEP, -}; - -struct wcd9xxx_spmi_map { - uint8_t handled[NUM_IRQ_REGS]; - uint8_t mask[NUM_IRQ_REGS]; - int linuxirq[MAX_NUM_IRQS]; - irq_handler_t handler[MAX_NUM_IRQS]; - struct platform_device *spmi[NUM_IRQ_REGS]; - struct snd_soc_codec *codec; - - enum wcd9xxx_spmi_pm_state pm_state; - struct mutex pm_lock; - /* pm_wq notifies change of pm_state */ - wait_queue_head_t pm_wq; - struct pm_qos_request pm_qos_req; - int wlock_holders; -}; - -struct wcd9xxx_spmi_map map; - -void wcd9xxx_spmi_enable_irq(int irq) -{ - pr_debug("%s: irqno =%d\n", __func__, irq); - - if (!(map.mask[BIT_BYTE(irq)] & (BYTE_BIT_MASK(irq)))) - return; - - map.mask[BIT_BYTE(irq)] &= - ~(BYTE_BIT_MASK(irq)); - - enable_irq(map.linuxirq[irq]); -} - -void wcd9xxx_spmi_disable_irq(int irq) -{ - pr_debug("%s: irqno =%d\n", __func__, irq); - - if (map.mask[BIT_BYTE(irq)] & (BYTE_BIT_MASK(irq))) - return; - - map.mask[BIT_BYTE(irq)] |= - (BYTE_BIT_MASK(irq)); - - disable_irq_nosync(map.linuxirq[irq]); -} - -int wcd9xxx_spmi_request_irq(int irq, irq_handler_t handler, - const char *name, void *priv) -{ - int rc; - unsigned long irq_flags; - - map.linuxirq[irq] = - platform_get_irq_byname(map.spmi[BIT_BYTE(irq)], - irq_names[irq]); - - if (strcmp(name, "mbhc sw intr")) - irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | - IRQF_ONESHOT; - else - irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | - IRQF_ONESHOT | IRQF_NO_SUSPEND; - pr_debug("%s: name:%s irq_flags = %lx\n", __func__, name, irq_flags); - - rc = devm_request_threaded_irq(&map.spmi[BIT_BYTE(irq)]->dev, - map.linuxirq[irq], NULL, - wcd9xxx_spmi_irq_handler, - irq_flags, - name, priv); - if (rc < 0) { - dev_err(&map.spmi[BIT_BYTE(irq)]->dev, - "Can't request %d IRQ\n", irq); - return rc; - } - - dev_dbg(&map.spmi[BIT_BYTE(irq)]->dev, - "irq %d linuxIRQ: %d\n", irq, map.linuxirq[irq]); - map.mask[BIT_BYTE(irq)] &= ~BYTE_BIT_MASK(irq); - map.handler[irq] = handler; - enable_irq_wake(map.linuxirq[irq]); - return 0; -} - -int wcd9xxx_spmi_free_irq(int irq, void *priv) -{ - devm_free_irq(&map.spmi[BIT_BYTE(irq)]->dev, map.linuxirq[irq], - priv); - map.mask[BIT_BYTE(irq)] |= BYTE_BIT_MASK(irq); - return 0; -} - -static int get_irq_bit(int linux_irq) -{ - int i = 0; - - for (; i < MAX_NUM_IRQS; i++) - if (map.linuxirq[i] == linux_irq) - return i; - - return i; -} - -static int get_order_irq(int i) -{ - return order[i]; -} - -static irqreturn_t wcd9xxx_spmi_irq_handler(int linux_irq, void *data) -{ - int irq, i, j; - unsigned long status[NUM_IRQ_REGS] = {0}; - - if (unlikely(wcd9xxx_spmi_lock_sleep() == false)) { - pr_err("Failed to hold suspend\n"); - return IRQ_NONE; - } - - irq = get_irq_bit(linux_irq); - if (irq == MAX_NUM_IRQS) - return IRQ_HANDLED; - - status[BIT_BYTE(irq)] |= BYTE_BIT_MASK(irq); - for (i = 0; i < NUM_IRQ_REGS; i++) { - status[i] |= snd_soc_read(map.codec, - BIT_BYTE(irq) * 0x100 + - MSM89XX_PMIC_DIGITAL_INT_LATCHED_STS); - status[i] &= ~map.mask[i]; - } - for (i = 0; i < MAX_NUM_IRQS; i++) { - j = get_order_irq(i); - if ((status[BIT_BYTE(j)] & BYTE_BIT_MASK(j)) && - ((map.handled[BIT_BYTE(j)] & - BYTE_BIT_MASK(j)) == 0)) { - map.handler[j](irq, data); - map.handled[BIT_BYTE(j)] |= - BYTE_BIT_MASK(j); - } - } - map.handled[BIT_BYTE(irq)] &= ~BYTE_BIT_MASK(irq); - wcd9xxx_spmi_unlock_sleep(); - - return IRQ_HANDLED; -} - -enum wcd9xxx_spmi_pm_state wcd9xxx_spmi_pm_cmpxchg( - enum wcd9xxx_spmi_pm_state o, - enum wcd9xxx_spmi_pm_state n) -{ - enum wcd9xxx_spmi_pm_state old; - - mutex_lock(&map.pm_lock); - old = map.pm_state; - if (old == o) - map.pm_state = n; - pr_debug("%s: map.pm_state = %d\n", __func__, map.pm_state); - mutex_unlock(&map.pm_lock); - return old; -} -EXPORT_SYMBOL(wcd9xxx_spmi_pm_cmpxchg); - -int wcd9xxx_spmi_suspend(pm_message_t pmesg) -{ - int ret = 0; - - pr_debug("%s: enter\n", __func__); - /* - * pm_qos_update_request() can be called after this suspend chain call - * started. thus suspend can be called while lock is being held - */ - mutex_lock(&map.pm_lock); - if (map.pm_state == WCD9XXX_PM_SLEEPABLE) { - pr_debug("%s: suspending system, state %d, wlock %d\n", - __func__, map.pm_state, - map.wlock_holders); - map.pm_state = WCD9XXX_PM_ASLEEP; - } else if (map.pm_state == WCD9XXX_PM_AWAKE) { - /* - * unlock to wait for pm_state == WCD9XXX_PM_SLEEPABLE - * then set to WCD9XXX_PM_ASLEEP - */ - pr_debug("%s: waiting to suspend system, state %d, wlock %d\n", - __func__, map.pm_state, - map.wlock_holders); - mutex_unlock(&map.pm_lock); - if (!(wait_event_timeout(map.pm_wq, - wcd9xxx_spmi_pm_cmpxchg( - WCD9XXX_PM_SLEEPABLE, - WCD9XXX_PM_ASLEEP) == - WCD9XXX_PM_SLEEPABLE, - HZ))) { - pr_debug("%s: suspend failed state %d, wlock %d\n", - __func__, map.pm_state, - map.wlock_holders); - ret = -EBUSY; - } else { - pr_debug("%s: done, state %d, wlock %d\n", __func__, - map.pm_state, - map.wlock_holders); - } - mutex_lock(&map.pm_lock); - } else if (map.pm_state == WCD9XXX_PM_ASLEEP) { - pr_warn("%s: system is already suspended, state %d, wlock %dn", - __func__, map.pm_state, - map.wlock_holders); - } - mutex_unlock(&map.pm_lock); - - return ret; -} -EXPORT_SYMBOL(wcd9xxx_spmi_suspend); - -int wcd9xxx_spmi_resume(void) -{ - int ret = 0; - - pr_debug("%s: enter\n", __func__); - mutex_lock(&map.pm_lock); - if (map.pm_state == WCD9XXX_PM_ASLEEP) { - pr_debug("%s: resuming system, state %d, wlock %d\n", __func__, - map.pm_state, - map.wlock_holders); - map.pm_state = WCD9XXX_PM_SLEEPABLE; - } else { - pr_warn("%s: system is already awake, state %d wlock %d\n", - __func__, map.pm_state, - map.wlock_holders); - } - mutex_unlock(&map.pm_lock); - wake_up_all(&map.pm_wq); - - return ret; -} -EXPORT_SYMBOL(wcd9xxx_spmi_resume); - -bool wcd9xxx_spmi_lock_sleep(void) -{ - /* - * wcd9xxx_spmi_{lock/unlock}_sleep will be called by - * wcd9xxx_spmi_irq_thread - * and its subroutines only motly. - * but btn0_lpress_fn is not wcd9xxx_spmi_irq_thread's subroutine and - * It can race with wcd9xxx_spmi_irq_thread. - * So need to embrace wlock_holders with mutex. - */ - mutex_lock(&map.pm_lock); - if (map.wlock_holders++ == 0) { - pr_debug("%s: holding wake lock\n", __func__); - pm_qos_update_request(&map.pm_qos_req, - msm_cpuidle_get_deep_idle_latency()); - pm_stay_awake(&map.spmi[0]->dev); - } - mutex_unlock(&map.pm_lock); - pr_debug("%s: wake lock counter %d\n", __func__, - map.wlock_holders); - pr_debug("%s: map.pm_state = %d\n", __func__, map.pm_state); - - if (!wait_event_timeout(map.pm_wq, - ((wcd9xxx_spmi_pm_cmpxchg( - WCD9XXX_PM_SLEEPABLE, - WCD9XXX_PM_AWAKE)) == - WCD9XXX_PM_SLEEPABLE || - (wcd9xxx_spmi_pm_cmpxchg( - WCD9XXX_PM_SLEEPABLE, - WCD9XXX_PM_AWAKE) == - WCD9XXX_PM_AWAKE)), - msecs_to_jiffies( - WCD9XXX_SYSTEM_RESUME_TIMEOUT_MS))) { - pr_warn("%s: system didn't resume within %dms, s %d, w %d\n", - __func__, - WCD9XXX_SYSTEM_RESUME_TIMEOUT_MS, map.pm_state, - map.wlock_holders); - wcd9xxx_spmi_unlock_sleep(); - return false; - } - wake_up_all(&map.pm_wq); - pr_debug("%s: leaving pm_state = %d\n", __func__, map.pm_state); - return true; -} -EXPORT_SYMBOL(wcd9xxx_spmi_lock_sleep); - -void wcd9xxx_spmi_unlock_sleep(void) -{ - mutex_lock(&map.pm_lock); - if (--map.wlock_holders == 0) { - pr_debug("%s: releasing wake lock pm_state %d -> %d\n", - __func__, map.pm_state, WCD9XXX_PM_SLEEPABLE); - /* - * if wcd9xxx_spmi_lock_sleep failed, pm_state would be still - * WCD9XXX_PM_ASLEEP, don't overwrite - */ - if (likely(map.pm_state == WCD9XXX_PM_AWAKE)) - map.pm_state = WCD9XXX_PM_SLEEPABLE; - pm_qos_update_request(&map.pm_qos_req, - PM_QOS_DEFAULT_VALUE); - pm_relax(&map.spmi[0]->dev); - } - mutex_unlock(&map.pm_lock); - pr_debug("%s: wake lock counter %d\n", __func__, - map.wlock_holders); - pr_debug("%s: map.pm_state = %d\n", __func__, map.pm_state); - wake_up_all(&map.pm_wq); -} -EXPORT_SYMBOL(wcd9xxx_spmi_unlock_sleep); - -void wcd9xxx_spmi_set_codec(struct snd_soc_codec *codec) -{ - map.codec = codec; -} - -void wcd9xxx_spmi_set_dev(struct platform_device *spmi, int i) -{ - if (i < NUM_IRQ_REGS) - map.spmi[i] = spmi; -} - -int wcd9xxx_spmi_irq_init(void) -{ - int i = 0; - - for (; i < MAX_NUM_IRQS; i++) - map.mask[BIT_BYTE(i)] |= BYTE_BIT_MASK(i); - mutex_init(&map.pm_lock); - map.wlock_holders = 0; - map.pm_state = WCD9XXX_PM_SLEEPABLE; - init_waitqueue_head(&map.pm_wq); - pm_qos_add_request(&map.pm_qos_req, - PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); - - return 0; -} - -void wcd9xxx_spmi_irq_exit(void) -{ - pm_qos_remove_request(&map.pm_qos_req); - mutex_destroy(&map.pm_lock); -} -MODULE_DESCRIPTION("MSM8x16 SPMI IRQ driver"); -MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h b/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h deleted file mode 100644 index 0b9b56e12b8a..000000000000 --- a/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef __WCD9XXX_SPMI_IRQ_H__ -#define __WCD9XXX_SPMI_IRQ_H__ - -#include -#include -#include -#include -#include - -extern void wcd9xxx_spmi_enable_irq(int irq); -extern void wcd9xxx_spmi_disable_irq(int irq); -extern int wcd9xxx_spmi_request_irq(int irq, irq_handler_t handler, - const char *name, void *priv); -extern int wcd9xxx_spmi_free_irq(int irq, void *priv); -extern void wcd9xxx_spmi_set_codec(struct snd_soc_codec *codec); -extern void wcd9xxx_spmi_set_dev(struct platform_device *spmi, int i); -extern int wcd9xxx_spmi_irq_init(void); -extern void wcd9xxx_spmi_irq_exit(void); -extern int wcd9xxx_spmi_suspend(pm_message_t pmesg); -extern int wcd9xxx_spmi_resume(void); -bool wcd9xxx_spmi_lock_sleep(void); -void wcd9xxx_spmi_unlock_sleep(void); - -#endif diff --git a/asoc/codecs/sdm660_cdc/sdm660-cdc-registers.h b/asoc/codecs/sdm660_cdc/sdm660-cdc-registers.h deleted file mode 100644 index 1317ce169755..000000000000 --- a/asoc/codecs/sdm660_cdc/sdm660-cdc-registers.h +++ /dev/null @@ -1,603 +0,0 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef SDM660_WCD_REGISTERS_H -#define SDM660_WCD_REGISTERS_H - -#define CDC_DIG_BASE 0xF000 -#define CDC_ANA_BASE 0xF100 - -#define MSM89XX_PMIC_DIGITAL_REVISION1 (CDC_DIG_BASE+0x000) -#define MSM89XX_PMIC_DIGITAL_REVISION1__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_REVISION2 (CDC_DIG_BASE+0x001) -#define MSM89XX_PMIC_DIGITAL_REVISION2__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_PERPH_TYPE (CDC_DIG_BASE+0x004) -#define MSM89XX_PMIC_DIGITAL_PERPH_TYPE__POR (0x23) -#define MSM89XX_PMIC_DIGITAL_PERPH_SUBTYPE (CDC_DIG_BASE+0x005) -#define MSM89XX_PMIC_DIGITAL_PERPH_SUBTYPE__POR (0x01) -#define MSM89XX_PMIC_DIGITAL_INT_RT_STS (CDC_DIG_BASE+0x010) -#define MSM89XX_PMIC_DIGITAL_INT_RT_STS__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_INT_SET_TYPE (CDC_DIG_BASE+0x011) -#define MSM89XX_PMIC_DIGITAL_INT_SET_TYPE__POR (0xFF) -#define MSM89XX_PMIC_DIGITAL_INT_POLARITY_HIGH (CDC_DIG_BASE+0x012) -#define MSM89XX_PMIC_DIGITAL_INT_POLARITY_HIGH__POR (0xFF) -#define MSM89XX_PMIC_DIGITAL_INT_POLARITY_LOW (CDC_DIG_BASE+0x013) -#define MSM89XX_PMIC_DIGITAL_INT_POLARITY_LOW__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_INT_LATCHED_CLR (CDC_DIG_BASE+0x014) -#define MSM89XX_PMIC_DIGITAL_INT_LATCHED_CLR__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_INT_EN_SET (CDC_DIG_BASE+0x015) -#define MSM89XX_PMIC_DIGITAL_INT_EN_SET__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_INT_EN_CLR (CDC_DIG_BASE+0x016) -#define MSM89XX_PMIC_DIGITAL_INT_EN_CLR__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_INT_LATCHED_STS (CDC_DIG_BASE+0x018) -#define MSM89XX_PMIC_DIGITAL_INT_LATCHED_STS__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_INT_PENDING_STS (CDC_DIG_BASE+0x019) -#define MSM89XX_PMIC_DIGITAL_INT_PENDING_STS__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_INT_MID_SEL (CDC_DIG_BASE+0x01A) -#define MSM89XX_PMIC_DIGITAL_INT_MID_SEL__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_INT_PRIORITY (CDC_DIG_BASE+0x01B) -#define MSM89XX_PMIC_DIGITAL_INT_PRIORITY__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_GPIO_MODE (CDC_DIG_BASE+0x040) -#define MSM89XX_PMIC_DIGITAL_GPIO_MODE__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_PIN_CTL_OE (CDC_DIG_BASE+0x041) -#define MSM89XX_PMIC_DIGITAL_PIN_CTL_OE__POR (0x01) -#define MSM89XX_PMIC_DIGITAL_PIN_CTL_DATA (CDC_DIG_BASE+0x042) -#define MSM89XX_PMIC_DIGITAL_PIN_CTL_DATA__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_PIN_STATUS (CDC_DIG_BASE+0x043) -#define MSM89XX_PMIC_DIGITAL_PIN_STATUS__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_HDRIVE_CTL (CDC_DIG_BASE+0x044) -#define MSM89XX_PMIC_DIGITAL_HDRIVE_CTL__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_CDC_RST_CTL (CDC_DIG_BASE+0x046) -#define MSM89XX_PMIC_DIGITAL_CDC_RST_CTL__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL (CDC_DIG_BASE+0x048) -#define MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL (CDC_DIG_BASE+0x049) -#define MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL (CDC_DIG_BASE+0x04A) -#define MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL (CDC_DIG_BASE+0x050) -#define MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL__POR (0x02) -#define MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL (CDC_DIG_BASE+0x051) -#define MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL__POR (0x02) -#define MSM89XX_PMIC_DIGITAL_CDC_CONN_HPHR_DAC_CTL (CDC_DIG_BASE+0x052) -#define MSM89XX_PMIC_DIGITAL_CDC_CONN_HPHR_DAC_CTL__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX1_CTL (CDC_DIG_BASE+0x053) -#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX1_CTL__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX2_CTL (CDC_DIG_BASE+0x054) -#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX2_CTL__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX3_CTL (CDC_DIG_BASE+0x055) -#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX3_CTL__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX_LB_CTL (CDC_DIG_BASE+0x056) -#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX_LB_CTL__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL1 (CDC_DIG_BASE+0x058) -#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL1__POR (0x7C) -#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL2 (CDC_DIG_BASE+0x059) -#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL2__POR (0x7C) -#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL3 (CDC_DIG_BASE+0x05A) -#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL3__POR (0x7C) -#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA0 (CDC_DIG_BASE+0x05B) -#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA0__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA1 (CDC_DIG_BASE+0x05C) -#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA1__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA2 (CDC_DIG_BASE+0x05D) -#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA2__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA3 (CDC_DIG_BASE+0x05E) -#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA3__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_DIG_DEBUG_CTL (CDC_DIG_BASE+0x068) -#define MSM89XX_PMIC_DIGITAL_DIG_DEBUG_CTL__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_DIG_DEBUG_EN (CDC_DIG_BASE+0x069) -#define MSM89XX_PMIC_DIGITAL_DIG_DEBUG_EN__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_SPARE_0 (CDC_DIG_BASE+0x070) -#define MSM89XX_PMIC_DIGITAL_SPARE_0__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_SPARE_1 (CDC_DIG_BASE+0x071) -#define MSM89XX_PMIC_DIGITAL_SPARE_1__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_SPARE_2 (CDC_DIG_BASE+0x072) -#define MSM89XX_PMIC_DIGITAL_SPARE_2__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_SEC_ACCESS (CDC_DIG_BASE+0x0D0) -#define MSM89XX_PMIC_DIGITAL_SEC_ACCESS__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL1 (CDC_DIG_BASE+0x0D8) -#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL1__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL2 (CDC_DIG_BASE+0x0D9) -#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL2__POR (0x01) -#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3 (CDC_DIG_BASE+0x0DA) -#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3__POR (0x05) -#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4 (CDC_DIG_BASE+0x0DB) -#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_INT_TEST1 (CDC_DIG_BASE+0x0E0) -#define MSM89XX_PMIC_DIGITAL_INT_TEST1__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_INT_TEST_VAL (CDC_DIG_BASE+0x0E1) -#define MSM89XX_PMIC_DIGITAL_INT_TEST_VAL__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_TRIM_NUM (CDC_DIG_BASE+0x0F0) -#define MSM89XX_PMIC_DIGITAL_TRIM_NUM__POR (0x00) -#define MSM89XX_PMIC_DIGITAL_TRIM_CTRL (CDC_DIG_BASE+0x0F1) -#define MSM89XX_PMIC_DIGITAL_TRIM_CTRL__POR (0x00) - -#define MSM89XX_PMIC_ANALOG_REVISION1 (CDC_ANA_BASE+0x00) -#define MSM89XX_PMIC_ANALOG_REVISION1__POR (0x00) -#define MSM89XX_PMIC_ANALOG_REVISION2 (CDC_ANA_BASE+0x01) -#define MSM89XX_PMIC_ANALOG_REVISION2__POR (0x00) -#define MSM89XX_PMIC_ANALOG_REVISION3 (CDC_ANA_BASE+0x02) -#define MSM89XX_PMIC_ANALOG_REVISION3__POR (0x00) -#define MSM89XX_PMIC_ANALOG_REVISION4 (CDC_ANA_BASE+0x03) -#define MSM89XX_PMIC_ANALOG_REVISION4__POR (0x00) -#define MSM89XX_PMIC_ANALOG_PERPH_TYPE (CDC_ANA_BASE+0x04) -#define MSM89XX_PMIC_ANALOG_PERPH_TYPE__POR (0x23) -#define MSM89XX_PMIC_ANALOG_PERPH_SUBTYPE (CDC_ANA_BASE+0x05) -#define MSM89XX_PMIC_ANALOG_PERPH_SUBTYPE__POR (0x09) -#define MSM89XX_PMIC_ANALOG_INT_RT_STS (CDC_ANA_BASE+0x10) -#define MSM89XX_PMIC_ANALOG_INT_RT_STS__POR (0x00) -#define MSM89XX_PMIC_ANALOG_INT_SET_TYPE (CDC_ANA_BASE+0x11) -#define MSM89XX_PMIC_ANALOG_INT_SET_TYPE__POR (0x3F) -#define MSM89XX_PMIC_ANALOG_INT_POLARITY_HIGH (CDC_ANA_BASE+0x12) -#define MSM89XX_PMIC_ANALOG_INT_POLARITY_HIGH__POR (0x3F) -#define MSM89XX_PMIC_ANALOG_INT_POLARITY_LOW (CDC_ANA_BASE+0x13) -#define MSM89XX_PMIC_ANALOG_INT_POLARITY_LOW__POR (0x00) -#define MSM89XX_PMIC_ANALOG_INT_LATCHED_CLR (CDC_ANA_BASE+0x14) -#define MSM89XX_PMIC_ANALOG_INT_LATCHED_CLR__POR (0x00) -#define MSM89XX_PMIC_ANALOG_INT_EN_SET (CDC_ANA_BASE+0x15) -#define MSM89XX_PMIC_ANALOG_INT_EN_SET__POR (0x00) -#define MSM89XX_PMIC_ANALOG_INT_EN_CLR (CDC_ANA_BASE+0x16) -#define MSM89XX_PMIC_ANALOG_INT_EN_CLR__POR (0x00) -#define MSM89XX_PMIC_ANALOG_INT_LATCHED_STS (CDC_ANA_BASE+0x18) -#define MSM89XX_PMIC_ANALOG_INT_LATCHED_STS__POR (0x00) -#define MSM89XX_PMIC_ANALOG_INT_PENDING_STS (CDC_ANA_BASE+0x19) -#define MSM89XX_PMIC_ANALOG_INT_PENDING_STS__POR (0x00) -#define MSM89XX_PMIC_ANALOG_INT_MID_SEL (CDC_ANA_BASE+0x1A) -#define MSM89XX_PMIC_ANALOG_INT_MID_SEL__POR (0x00) -#define MSM89XX_PMIC_ANALOG_INT_PRIORITY (CDC_ANA_BASE+0x1B) -#define MSM89XX_PMIC_ANALOG_INT_PRIORITY__POR (0x00) -#define MSM89XX_PMIC_ANALOG_MICB_1_EN (CDC_ANA_BASE+0x40) -#define MSM89XX_PMIC_ANALOG_MICB_1_EN__POR (0x00) -#define MSM89XX_PMIC_ANALOG_MICB_1_VAL (CDC_ANA_BASE+0x41) -#define MSM89XX_PMIC_ANALOG_MICB_1_VAL__POR (0x20) -#define MSM89XX_PMIC_ANALOG_MICB_1_CTL (CDC_ANA_BASE+0x42) -#define MSM89XX_PMIC_ANALOG_MICB_1_CTL__POR (0x00) -#define MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS (CDC_ANA_BASE+0x43) -#define MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS__POR (0x49) -#define MSM89XX_PMIC_ANALOG_MICB_2_EN (CDC_ANA_BASE+0x44) -#define MSM89XX_PMIC_ANALOG_MICB_2_EN__POR (0x20) -#define MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2 (CDC_ANA_BASE+0x45) -#define MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2__POR (0x00) -#define MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL (CDC_ANA_BASE+0x46) -#define MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL__POR (0x00) -#define MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1 (CDC_ANA_BASE+0x47) -#define MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1__POR (0x35) -#define MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2 (CDC_ANA_BASE+0x50) -#define MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2__POR (0x08) -#define MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL (CDC_ANA_BASE+0x51) -#define MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL__POR (0x00) -#define MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER (CDC_ANA_BASE+0x52) -#define MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER__POR (0x98) -#define MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL (CDC_ANA_BASE+0x53) -#define MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL__POR (0x00) -#define MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL (CDC_ANA_BASE+0x54) -#define MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL__POR (0x20) -#define MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL (CDC_ANA_BASE+0x55) -#define MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL__POR (0x40) -#define MSM89XX_PMIC_ANALOG_MBHC_BTN3_CTL (CDC_ANA_BASE+0x56) -#define MSM89XX_PMIC_ANALOG_MBHC_BTN3_CTL__POR (0x61) -#define MSM89XX_PMIC_ANALOG_MBHC_BTN4_CTL (CDC_ANA_BASE+0x57) -#define MSM89XX_PMIC_ANALOG_MBHC_BTN4_CTL__POR (0x80) -#define MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT (CDC_ANA_BASE+0x58) -#define MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT__POR (0x00) -#define MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT (CDC_ANA_BASE+0x59) -#define MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT__POR (0x00) -#define MSM89XX_PMIC_ANALOG_TX_1_EN (CDC_ANA_BASE+0x60) -#define MSM89XX_PMIC_ANALOG_TX_1_EN__POR (0x03) -#define MSM89XX_PMIC_ANALOG_TX_2_EN (CDC_ANA_BASE+0x61) -#define MSM89XX_PMIC_ANALOG_TX_2_EN__POR (0x03) -#define MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_1 (CDC_ANA_BASE+0x62) -#define MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_1__POR (0xBF) -#define MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_2 (CDC_ANA_BASE+0x63) -#define MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_2__POR (0x8C) -#define MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL (CDC_ANA_BASE+0x64) -#define MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL__POR (0x00) -#define MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS (CDC_ANA_BASE+0x65) -#define MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS__POR (0x6B) -#define MSM89XX_PMIC_ANALOG_TX_1_2_TXFE_CLKDIV (CDC_ANA_BASE+0x66) -#define MSM89XX_PMIC_ANALOG_TX_1_2_TXFE_CLKDIV__POR (0x51) -#define MSM89XX_PMIC_ANALOG_TX_3_EN (CDC_ANA_BASE+0x67) -#define MSM89XX_PMIC_ANALOG_TX_3_EN__POR (0x02) -#define MSM89XX_PMIC_ANALOG_NCP_EN (CDC_ANA_BASE+0x80) -#define MSM89XX_PMIC_ANALOG_NCP_EN__POR (0x26) -#define MSM89XX_PMIC_ANALOG_NCP_CLK (CDC_ANA_BASE+0x81) -#define MSM89XX_PMIC_ANALOG_NCP_CLK__POR (0x23) -#define MSM89XX_PMIC_ANALOG_NCP_DEGLITCH (CDC_ANA_BASE+0x82) -#define MSM89XX_PMIC_ANALOG_NCP_DEGLITCH__POR (0x5B) -#define MSM89XX_PMIC_ANALOG_NCP_FBCTRL (CDC_ANA_BASE+0x83) -#define MSM89XX_PMIC_ANALOG_NCP_FBCTRL__POR (0x08) -#define MSM89XX_PMIC_ANALOG_NCP_BIAS (CDC_ANA_BASE+0x84) -#define MSM89XX_PMIC_ANALOG_NCP_BIAS__POR (0x29) -#define MSM89XX_PMIC_ANALOG_NCP_VCTRL (CDC_ANA_BASE+0x85) -#define MSM89XX_PMIC_ANALOG_NCP_VCTRL__POR (0x24) -#define MSM89XX_PMIC_ANALOG_NCP_TEST (CDC_ANA_BASE+0x86) -#define MSM89XX_PMIC_ANALOG_NCP_TEST__POR (0x00) -#define MSM89XX_PMIC_ANALOG_NCP_CLIM_ADDR (CDC_ANA_BASE+0x87) -#define MSM89XX_PMIC_ANALOG_NCP_CLIM_ADDR__POR (0xD5) -#define MSM89XX_PMIC_ANALOG_RX_CLOCK_DIVIDER (CDC_ANA_BASE+0x90) -#define MSM89XX_PMIC_ANALOG_RX_CLOCK_DIVIDER__POR (0xE8) -#define MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL (CDC_ANA_BASE+0x91) -#define MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL__POR (0xCF) -#define MSM89XX_PMIC_ANALOG_RX_COM_OCP_COUNT (CDC_ANA_BASE+0x92) -#define MSM89XX_PMIC_ANALOG_RX_COM_OCP_COUNT__POR (0x6E) -#define MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC (CDC_ANA_BASE+0x93) -#define MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC__POR (0x18) -#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA (CDC_ANA_BASE+0x94) -#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA__POR (0x5A) -#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_LDO_OCP (CDC_ANA_BASE+0x95) -#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_LDO_OCP__POR (0x69) -#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_CNP (CDC_ANA_BASE+0x96) -#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_CNP__POR (0x29) -#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN (CDC_ANA_BASE+0x97) -#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN__POR (0x80) -#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_CTL (CDC_ANA_BASE+0x98) -#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_CTL__POR (0xDA) -#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME (CDC_ANA_BASE+0x99) -#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME__POR (0x16) -#define MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST (CDC_ANA_BASE+0x9A) -#define MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST__POR (0x00) -#define MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL (CDC_ANA_BASE+0x9B) -#define MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL__POR (0x20) -#define MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST (CDC_ANA_BASE+0x9C) -#define MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST__POR (0x00) -#define MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL (CDC_ANA_BASE+0x9D) -#define MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL__POR (0x20) -#define MSM89XX_PMIC_ANALOG_RX_EAR_CTL (CDC_ANA_BASE+0x9E) -#define MSM89XX_PMIC_ANALOG_RX_EAR_CTL___POR (0x12) -#define MSM89XX_PMIC_ANALOG_RX_ATEST (CDC_ANA_BASE+0x9F) -#define MSM89XX_PMIC_ANALOG_RX_ATEST__POR (0x00) -#define MSM89XX_PMIC_ANALOG_RX_HPH_STATUS (CDC_ANA_BASE+0xA0) -#define MSM89XX_PMIC_ANALOG_RX_HPH_STATUS__POR (0x0C) -#define MSM89XX_PMIC_ANALOG_RX_EAR_STATUS (CDC_ANA_BASE+0xA1) -#define MSM89XX_PMIC_ANALOG_RX_EAR_STATUS__POR (0x00) -#define MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL (CDC_ANA_BASE+0xAC) -#define MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL__POR (0x00) -#define MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL (CDC_ANA_BASE+0xAD) -#define MSM89XX_PMIC_ANALOG_RX_RX_LO_EN_CTL__POR (0x00) -#define MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL (CDC_ANA_BASE+0xB0) -#define MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL__POR (0x83) -#define MSM89XX_PMIC_ANALOG_SPKR_DRV_CLIP_DET (CDC_ANA_BASE+0xB1) -#define MSM89XX_PMIC_ANALOG_SPKR_DRV_CLIP_DET__POR (0x91) -#define MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL (CDC_ANA_BASE+0xB2) -#define MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL__POR (0x29) -#define MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET (CDC_ANA_BASE+0xB3) -#define MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET__POR (0x4D) -#define MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL (CDC_ANA_BASE+0xB4) -#define MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL__POR (0xE1) -#define MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL (CDC_ANA_BASE+0xB5) -#define MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL__POR (0x1E) -#define MSM89XX_PMIC_ANALOG_SPKR_DRV_MISC (CDC_ANA_BASE+0xB6) -#define MSM89XX_PMIC_ANALOG_SPKR_DRV_MISC__POR (0xCB) -#define MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG (CDC_ANA_BASE+0xB7) -#define MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG__POR (0x00) -#define MSM89XX_PMIC_ANALOG_CURRENT_LIMIT (CDC_ANA_BASE+0xC0) -#define MSM89XX_PMIC_ANALOG_CURRENT_LIMIT__POR (0x02) -#define MSM89XX_PMIC_ANALOG_OUTPUT_VOLTAGE (CDC_ANA_BASE+0xC1) -#define MSM89XX_PMIC_ANALOG_OUTPUT_VOLTAGE__POR (0x14) -#define MSM89XX_PMIC_ANALOG_BYPASS_MODE (CDC_ANA_BASE+0xC2) -#define MSM89XX_PMIC_ANALOG_BYPASS_MODE__POR (0x00) -#define MSM89XX_PMIC_ANALOG_BOOST_EN_CTL (CDC_ANA_BASE+0xC3) -#define MSM89XX_PMIC_ANALOG_BOOST_EN_CTL__POR (0x1F) -#define MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO (CDC_ANA_BASE+0xC4) -#define MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO__POR (0x8C) -#define MSM89XX_PMIC_ANALOG_RDSON_MAX_DUTY_CYCLE (CDC_ANA_BASE+0xC5) -#define MSM89XX_PMIC_ANALOG_RDSON_MAX_DUTY_CYCLE__POR (0xC0) -#define MSM89XX_PMIC_ANALOG_BOOST_TEST1_1 (CDC_ANA_BASE+0xC6) -#define MSM89XX_PMIC_ANALOG_BOOST_TEST1_1__POR (0x00) -#define MSM89XX_PMIC_ANALOG_BOOST_TEST_2 (CDC_ANA_BASE+0xC7) -#define MSM89XX_PMIC_ANALOG_BOOST_TEST_2__POR (0x00) -#define MSM89XX_PMIC_ANALOG_SPKR_SAR_STATUS (CDC_ANA_BASE+0xC8) -#define MSM89XX_PMIC_ANALOG_SPKR_SAR_STATUS__POR (0x00) -#define MSM89XX_PMIC_ANALOG_SPKR_DRV_STATUS (CDC_ANA_BASE+0xC9) -#define MSM89XX_PMIC_ANALOG_SPKR_DRV_STATUS__POR (0x00) -#define MSM89XX_PMIC_ANALOG_PBUS_ADD_CSR (CDC_ANA_BASE+0xCE) -#define MSM89XX_PMIC_ANALOG_PBUS_ADD_CSR__POR (0x00) -#define MSM89XX_PMIC_ANALOG_PBUS_ADD_SEL (CDC_ANA_BASE+0xCF) -#define MSM89XX_PMIC_ANALOG_PBUS_ADD_SEL__POR (0x00) -#define MSM89XX_PMIC_ANALOG_SEC_ACCESS (CDC_ANA_BASE+0xD0) -#define MSM89XX_PMIC_ANALOG_SEC_ACCESS__POR (0x00) -#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL1 (CDC_ANA_BASE+0xD8) -#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL1__POR (0x00) -#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL2 (CDC_ANA_BASE+0xD9) -#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL2__POR (0x01) -#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3 (CDC_ANA_BASE+0xDA) -#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3__POR (0x05) -#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4 (CDC_ANA_BASE+0xDB) -#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4__POR (0x00) -#define MSM89XX_PMIC_ANALOG_INT_TEST1 (CDC_ANA_BASE+0xE0) -#define MSM89XX_PMIC_ANALOG_INT_TEST1__POR (0x00) -#define MSM89XX_PMIC_ANALOG_INT_TEST_VAL (CDC_ANA_BASE+0xE1) -#define MSM89XX_PMIC_ANALOG_INT_TEST_VAL__POR (0x00) -#define MSM89XX_PMIC_ANALOG_TRIM_NUM (CDC_ANA_BASE+0xF0) -#define MSM89XX_PMIC_ANALOG_TRIM_NUM__POR (0x04) -#define MSM89XX_PMIC_ANALOG_TRIM_CTRL1 (CDC_ANA_BASE+0xF1) -#define MSM89XX_PMIC_ANALOG_TRIM_CTRL1__POR (0x00) -#define MSM89XX_PMIC_ANALOG_TRIM_CTRL2 (CDC_ANA_BASE+0xF2) -#define MSM89XX_PMIC_ANALOG_TRIM_CTRL2__POR (0x00) -#define MSM89XX_PMIC_ANALOG_TRIM_CTRL3 (CDC_ANA_BASE+0xF3) -#define MSM89XX_PMIC_ANALOG_TRIM_CTRL3__POR (0x00) -#define MSM89XX_PMIC_ANALOG_TRIM_CTRL4 (CDC_ANA_BASE+0xF4) -#define MSM89XX_PMIC_ANALOG_TRIM_CTRL4__POR (0x00) - -#define MSM89XX_PMIC_CDC_NUM_REGISTERS \ - (MSM89XX_PMIC_ANALOG_TRIM_CTRL4+1) -#define MSM89XX_PMIC_CDC_MAX_REGISTER \ - (MSM89XX_PMIC_CDC_NUM_REGISTERS-1) -#define MSM89XX_PMIC_CDC_CACHE_SIZE \ - MSM89XX_PMIC_CDC_NUM_REGISTERS - - -#define MSM89XX_CDC_CORE_CLK_RX_RESET_CTL (0x00) -#define MSM89XX_CDC_CORE_CLK_RX_RESET_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL (0x04) -#define MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL (0x08) -#define MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CLK_RX_I2S_CTL (0x0C) -#define MSM89XX_CDC_CORE_CLK_RX_I2S_CTL__POR (0x13) -#define MSM89XX_CDC_CORE_CLK_TX_I2S_CTL (0x10) -#define MSM89XX_CDC_CORE_CLK_TX_I2S_CTL__POR (0x13) -#define MSM89XX_CDC_CORE_CLK_OTHR_RESET_B1_CTL (0x14) -#define MSM89XX_CDC_CORE_CLK_OTHR_RESET_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL (0x18) -#define MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CLK_OTHR_CTL (0x1C) -#define MSM89XX_CDC_CORE_CLK_OTHR_CTL__POR (0x04) -#define MSM89XX_CDC_CORE_CLK_RX_B1_CTL (0x20) -#define MSM89XX_CDC_CORE_CLK_RX_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CLK_MCLK_CTL (0x24) -#define MSM89XX_CDC_CORE_CLK_MCLK_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CLK_PDM_CTL (0x28) -#define MSM89XX_CDC_CORE_CLK_PDM_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CLK_SD_CTL (0x2C) -#define MSM89XX_CDC_CORE_CLK_SD_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL (0x30) -#define MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CLK_RX_B2_CTL (0x34) -#define MSM89XX_CDC_CORE_CLK_RX_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CLK_TX2_I2S_CTL (0x38) -#define MSM89XX_CDC_CORE_CLK_TX2_I2S_CTL__POR (0x13) -#define MSM89XX_CDC_CORE_RX1_B1_CTL (0x40) -#define MSM89XX_CDC_CORE_RX1_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX2_B1_CTL (0x60) -#define MSM89XX_CDC_CORE_RX2_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX3_B1_CTL (0x80) -#define MSM89XX_CDC_CORE_RX3_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX1_B2_CTL (0x44) -#define MSM89XX_CDC_CORE_RX1_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX2_B2_CTL (0x64) -#define MSM89XX_CDC_CORE_RX2_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX3_B2_CTL (0x84) -#define MSM89XX_CDC_CORE_RX3_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX1_B3_CTL (0x48) -#define MSM89XX_CDC_CORE_RX1_B3_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX2_B3_CTL (0x68) -#define MSM89XX_CDC_CORE_RX2_B3_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX3_B3_CTL (0x88) -#define MSM89XX_CDC_CORE_RX3_B3_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX1_B4_CTL (0x4C) -#define MSM89XX_CDC_CORE_RX1_B4_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX2_B4_CTL (0x6C) -#define MSM89XX_CDC_CORE_RX2_B4_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX3_B4_CTL (0x8C) -#define MSM89XX_CDC_CORE_RX3_B4_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX1_B5_CTL (0x50) -#define MSM89XX_CDC_CORE_RX1_B5_CTL__POR (0x68) -#define MSM89XX_CDC_CORE_RX2_B5_CTL (0x70) -#define MSM89XX_CDC_CORE_RX2_B5_CTL__POR (0x68) -#define MSM89XX_CDC_CORE_RX3_B5_CTL (0x90) -#define MSM89XX_CDC_CORE_RX3_B5_CTL__POR (0x68) -#define MSM89XX_CDC_CORE_RX1_B6_CTL (0x54) -#define MSM89XX_CDC_CORE_RX1_B6_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX2_B6_CTL (0x74) -#define MSM89XX_CDC_CORE_RX2_B6_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX3_B6_CTL (0x94) -#define MSM89XX_CDC_CORE_RX3_B6_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX1_VOL_CTL_B1_CTL (0x58) -#define MSM89XX_CDC_CORE_RX1_VOL_CTL_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX2_VOL_CTL_B1_CTL (0x78) -#define MSM89XX_CDC_CORE_RX2_VOL_CTL_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX3_VOL_CTL_B1_CTL (0x98) -#define MSM89XX_CDC_CORE_RX3_VOL_CTL_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL (0x5C) -#define MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL (0x7C) -#define MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL (0x9C) -#define MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_TOP_GAIN_UPDATE (0xA0) -#define MSM89XX_CDC_CORE_TOP_GAIN_UPDATE__POR (0x00) -#define MSM89XX_CDC_CORE_TOP_CTL (0xA4) -#define MSM89XX_CDC_CORE_TOP_CTL__POR (0x01) -#define MSM89XX_CDC_CORE_COMP0_B1_CTL (0xB0) -#define MSM89XX_CDC_CORE_COMP0_B1_CTL__POR (0x30) -#define MSM89XX_CDC_CORE_COMP0_B2_CTL (0xB4) -#define MSM89XX_CDC_CORE_COMP0_B2_CTL__POR (0xB5) -#define MSM89XX_CDC_CORE_COMP0_B3_CTL (0xB8) -#define MSM89XX_CDC_CORE_COMP0_B3_CTL__POR (0x28) -#define MSM89XX_CDC_CORE_COMP0_B4_CTL (0xBC) -#define MSM89XX_CDC_CORE_COMP0_B4_CTL__POR (0x37) -#define MSM89XX_CDC_CORE_COMP0_B5_CTL (0xC0) -#define MSM89XX_CDC_CORE_COMP0_B5_CTL__POR (0x7F) -#define MSM89XX_CDC_CORE_COMP0_B6_CTL (0xC4) -#define MSM89XX_CDC_CORE_COMP0_B6_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_COMP0_SHUT_DOWN_STATUS (0xC8) -#define MSM89XX_CDC_CORE_COMP0_SHUT_DOWN_STATUS__POR (0x03) -#define MSM89XX_CDC_CORE_COMP0_FS_CFG (0xCC) -#define MSM89XX_CDC_CORE_COMP0_FS_CFG__POR (0x03) -#define MSM89XX_CDC_CORE_COMP0_DELAY_BUF_CTL (0xD0) -#define MSM89XX_CDC_CORE_COMP0_DELAY_BUF_CTL__POR (0x02) -#define MSM89XX_CDC_CORE_DEBUG_DESER1_CTL (0xE0) -#define MSM89XX_CDC_CORE_DEBUG_DESER1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_DEBUG_DESER2_CTL (0xE4) -#define MSM89XX_CDC_CORE_DEBUG_DESER2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_DEBUG_B1_CTL_CFG (0xE8) -#define MSM89XX_CDC_CORE_DEBUG_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_DEBUG_B2_CTL_CFG (0xEC) -#define MSM89XX_CDC_CORE_DEBUG_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_DEBUG_B3_CTL_CFG (0xF0) -#define MSM89XX_CDC_CORE_DEBUG_B3_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL (0x100) -#define MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL (0x140) -#define MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL (0x104) -#define MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR2_GAIN_B2_CTL (0x144) -#define MSM89XX_CDC_CORE_IIR2_GAIN_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL (0x108) -#define MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR2_GAIN_B3_CTL (0x148) -#define MSM89XX_CDC_CORE_IIR2_GAIN_B3_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL (0x10C) -#define MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR2_GAIN_B4_CTL (0x14C) -#define MSM89XX_CDC_CORE_IIR2_GAIN_B4_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR1_GAIN_B5_CTL (0x110) -#define MSM89XX_CDC_CORE_IIR1_GAIN_B5_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR2_GAIN_B5_CTL (0x150) -#define MSM89XX_CDC_CORE_IIR2_GAIN_B5_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR1_GAIN_B6_CTL (0x114) -#define MSM89XX_CDC_CORE_IIR1_GAIN_B6_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR2_GAIN_B6_CTL (0x154) -#define MSM89XX_CDC_CORE_IIR2_GAIN_B6_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR1_GAIN_B7_CTL (0x118) -#define MSM89XX_CDC_CORE_IIR1_GAIN_B7_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR2_GAIN_B7_CTL (0x158) -#define MSM89XX_CDC_CORE_IIR2_GAIN_B7_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR1_GAIN_B8_CTL (0x11C) -#define MSM89XX_CDC_CORE_IIR1_GAIN_B8_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR2_GAIN_B8_CTL (0x15C) -#define MSM89XX_CDC_CORE_IIR2_GAIN_B8_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR1_CTL (0x120) -#define MSM89XX_CDC_CORE_IIR1_CTL__POR (0x40) -#define MSM89XX_CDC_CORE_IIR2_CTL (0x160) -#define MSM89XX_CDC_CORE_IIR2_CTL__POR (0x40) -#define MSM89XX_CDC_CORE_IIR1_GAIN_TIMER_CTL (0x124) -#define MSM89XX_CDC_CORE_IIR1_GAIN_TIMER_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR2_GAIN_TIMER_CTL (0x164) -#define MSM89XX_CDC_CORE_IIR2_GAIN_TIMER_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL (0x128) -#define MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL (0x168) -#define MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL (0x12C) -#define MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_IIR2_COEF_B2_CTL (0x16C) -#define MSM89XX_CDC_CORE_IIR2_COEF_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_RX1_B1_CTL (0x180) -#define MSM89XX_CDC_CORE_CONN_RX1_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_RX1_B2_CTL (0x184) -#define MSM89XX_CDC_CORE_CONN_RX1_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_RX1_B3_CTL (0x188) -#define MSM89XX_CDC_CORE_CONN_RX1_B3_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_RX2_B1_CTL (0x18C) -#define MSM89XX_CDC_CORE_CONN_RX2_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_RX2_B2_CTL (0x190) -#define MSM89XX_CDC_CORE_CONN_RX2_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_RX2_B3_CTL (0x194) -#define MSM89XX_CDC_CORE_CONN_RX2_B3_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_RX3_B1_CTL (0x198) -#define MSM89XX_CDC_CORE_CONN_RX3_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_RX3_B2_CTL (0x19C) -#define MSM89XX_CDC_CORE_CONN_RX3_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_TX_B1_CTL (0x1A0) -#define MSM89XX_CDC_CORE_CONN_TX_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_TX_B2_CTL (0x1A4) -#define MSM89XX_CDC_CORE_CONN_TX_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL (0x1A8) -#define MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_EQ1_B2_CTL (0x1AC) -#define MSM89XX_CDC_CORE_CONN_EQ1_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_EQ1_B3_CTL (0x1B0) -#define MSM89XX_CDC_CORE_CONN_EQ1_B3_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_EQ1_B4_CTL (0x1B4) -#define MSM89XX_CDC_CORE_CONN_EQ1_B4_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL (0x1B8) -#define MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_EQ2_B2_CTL (0x1BC) -#define MSM89XX_CDC_CORE_CONN_EQ2_B2_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_EQ2_B3_CTL (0x1C0) -#define MSM89XX_CDC_CORE_CONN_EQ2_B3_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_EQ2_B4_CTL (0x1C4) -#define MSM89XX_CDC_CORE_CONN_EQ2_B4_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL (0x1C8) -#define MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_CONN_TX_B3_CTL (0x1CC) -#define MSM89XX_CDC_CORE_CONN_TX_B3_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_TX5_VOL_CTL_TIMER (0x1E0) -#define MSM89XX_CDC_CORE_TX5_VOL_CTL_TIMER__POR (0x00) -#define MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN (0x1E4) -#define MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN__POR (0x00) -#define MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG (0x1E8) -#define MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG__POR (0x00) -#define MSM89XX_CDC_CORE_TX5_MUX_CTL (0x1EC) -#define MSM89XX_CDC_CORE_TX5_MUX_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_TX5_CLK_FS_CTL (0x1F0) -#define MSM89XX_CDC_CORE_TX5_CLK_FS_CTL__POR (0x03) -#define MSM89XX_CDC_CORE_TX5_DMIC_CTL (0x1F4) -#define MSM89XX_CDC_CORE_TX5_DMIC_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_TX1_VOL_CTL_TIMER (0x280) -#define MSM89XX_CDC_CORE_TX1_VOL_CTL_TIMER__POR (0x00) -#define MSM89XX_CDC_CORE_TX2_VOL_CTL_TIMER (0x2A0) -#define MSM89XX_CDC_CORE_TX2_VOL_CTL_TIMER__POR (0x00) -#define MSM89XX_CDC_CORE_TX3_VOL_CTL_TIMER (0x2C0) -#define MSM89XX_CDC_CORE_TX3_VOL_CTL_TIMER__POR (0x00) -#define MSM89XX_CDC_CORE_TX4_VOL_CTL_TIMER (0x2E0) -#define MSM89XX_CDC_CORE_TX4_VOL_CTL_TIMER__POR (0x00) -#define MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN (0x284) -#define MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN__POR (0x00) -#define MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN (0x2A4) -#define MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN__POR (0x00) -#define MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN (0x2C4) -#define MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN__POR (0x00) -#define MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN (0x2E4) -#define MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN__POR (0x00) -#define MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG (0x288) -#define MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG__POR (0x00) -#define MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG (0x2A8) -#define MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG__POR (0x00) -#define MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG (0x2C8) -#define MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG__POR (0x00) -#define MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG (0x2E8) -#define MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG__POR (0x00) -#define MSM89XX_CDC_CORE_TX1_MUX_CTL (0x28C) -#define MSM89XX_CDC_CORE_TX1_MUX_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_TX2_MUX_CTL (0x2AC) -#define MSM89XX_CDC_CORE_TX2_MUX_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_TX3_MUX_CTL (0x2CC) -#define MSM89XX_CDC_CORE_TX3_MUX_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_TX4_MUX_CTL (0x2EC) -#define MSM89XX_CDC_CORE_TX4_MUX_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_TX1_CLK_FS_CTL (0x290) -#define MSM89XX_CDC_CORE_TX1_CLK_FS_CTL__POR (0x03) -#define MSM89XX_CDC_CORE_TX2_CLK_FS_CTL (0x2B0) -#define MSM89XX_CDC_CORE_TX2_CLK_FS_CTL__POR (0x03) -#define MSM89XX_CDC_CORE_TX3_CLK_FS_CTL (0x2D0) -#define MSM89XX_CDC_CORE_TX3_CLK_FS_CTL__POR (0x03) -#define MSM89XX_CDC_CORE_TX4_CLK_FS_CTL (0x2F0) -#define MSM89XX_CDC_CORE_TX4_CLK_FS_CTL__POR (0x03) -#define MSM89XX_CDC_CORE_TX1_DMIC_CTL (0x294) -#define MSM89XX_CDC_CORE_TX1_DMIC_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_TX2_DMIC_CTL (0x2B4) -#define MSM89XX_CDC_CORE_TX2_DMIC_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_TX3_DMIC_CTL (0x2D4) -#define MSM89XX_CDC_CORE_TX3_DMIC_CTL__POR (0x00) -#define MSM89XX_CDC_CORE_TX4_DMIC_CTL (0x2F4) -#define MSM89XX_CDC_CORE_TX4_DMIC_CTL__POR (0x00) - -#define MSM89XX_CDC_CORE_NUM_REGISTERS \ - (MSM89XX_CDC_CORE_TX4_DMIC_CTL+1) -#define MSM89XX_CDC_CORE_MAX_REGISTER \ - (MSM89XX_CDC_CORE_NUM_REGISTERS-1) -#define MSM89XX_CDC_CORE_CACHE_SIZE \ - MSM89XX_CDC_CORE_NUM_REGISTERS -#endif diff --git a/asoc/codecs/wcd934x/Android.mk b/asoc/codecs/wcd934x/Android.mk index 3b5ef2fa175d..f4fe33c27122 100644 --- a/asoc/codecs/wcd934x/Android.mk +++ b/asoc/codecs/wcd934x/Android.mk @@ -3,10 +3,6 @@ # Assume no targets will be supported # Check if this driver needs be built for current target -ifeq ($(call is-board-platform,sdm845),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m -endif - ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif @@ -15,13 +11,9 @@ ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif -ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m -endif - AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index e6427cfba4c7..d81618f6054c 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -16,21 +16,6 @@ ifeq ($(KERNEL_BUILD), 1) endif ifeq ($(KERNEL_BUILD), 0) - ifeq ($(CONFIG_ARCH_SDM845), y) - include $(AUDIO_ROOT)/config/sdm845auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM670), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM450), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm6150auto.conf export diff --git a/asoc/codecs/wcd9360/Android.mk b/asoc/codecs/wcd9360/Android.mk deleted file mode 100644 index 492061265f26..000000000000 --- a/asoc/codecs/wcd9360/Android.mk +++ /dev/null @@ -1,50 +0,0 @@ -# Android makefile for audio kernel modules - -# Assume no targets will be supported - -# Check if this driver needs be built for current target -ifeq ($(call is-board-platform,msmnile),true) -AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m -endif - -AUDIO_CHIPSET := audio -# Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile),true) - -LOCAL_PATH := $(call my-dir) - -# This makefile is only for DLKM -ifneq ($(findstring vendor,$(LOCAL_PATH)),) - -ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel -endif # opensource - -DLKM_DIR := $(TOP)/device/qcom/common/dlkm - -# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko -########################################################### -# This is set once per LOCAL_PATH, not per (kernel) module -KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) - -# We are actually building audio.ko here, as per the -# requirement we are specifying _audio.ko as LOCAL_MODULE. -# This means we need to rename the module to _audio.ko -# after audio.ko is built. -KBUILD_OPTIONS += MODNAME=wcd9360_dlkm -KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) -KBUILD_OPTIONS += $(AUDIO_SELECT) - -########################################################### -include $(CLEAR_VARS) -LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd9360.ko -LOCAL_MODULE_KBUILD_NAME := wcd9360_dlkm.ko -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE_DEBUG_ENABLE := true -LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) -include $(DLKM_DIR)/AndroidKernelModule.mk -########################################################### -########################################################### - -endif # DLKM check -endif # supported target check diff --git a/asoc/codecs/wcd9360/Kbuild b/asoc/codecs/wcd9360/Kbuild deleted file mode 100644 index 5282b3442408..000000000000 --- a/asoc/codecs/wcd9360/Kbuild +++ /dev/null @@ -1,110 +0,0 @@ -# We can build either as part of a standalone Kernel build or as -# an external module. Determine which mechanism is being used -ifeq ($(MODNAME),) - KERNEL_BUILD := 1 -else - KERNEL_BUILD := 0 -endif - - - -ifeq ($(KERNEL_BUILD), 1) - # These are configurable via Kconfig for kernel-based builds - # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 - AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio -endif - -ifeq ($(KERNEL_BUILD), 0) - ifeq ($(CONFIG_ARCH_SM8150), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h - endif - - ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h - endif -endif - -# As per target team, build is done as follows: -# Defconfig : build with default flags -# Slub : defconfig + CONFIG_SLUB_DEBUG := y + -# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y -# Perf : Using appropriate msmXXXX-perf_defconfig -# -# Shipment builds (user variants) should not have any debug feature -# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds -# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since -# there is no other way to identify defconfig builds, QTI internal -# representation of perf builds (identified using the string 'perf'), -# is used to identify if the build is a slub or defconfig one. This -# way no critical debug feature will be enabled for perf and shipment -# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT -# config. - -############ UAPI ############ -UAPI_DIR := uapi -UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) - -############ COMMON ############ -COMMON_DIR := include -COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) - -############ WCD934X ############ - -# for WCD9360 Codec -ifdef CONFIG_SND_SOC_WCD9360 - WCD9360_OBJS += wcd9360.o - WCD9360_OBJS += wcd9360-dsp-cntl.o -endif - -LINUX_INC += -Iinclude/linux - -INCS += $(COMMON_INC) \ - $(UAPI_INC) - -EXTRA_CFLAGS += $(INCS) - - -CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ - -DANI_LITTLE_BIT_ENDIAN \ - -DDOT11F_LITTLE_ENDIAN_HOST \ - -DANI_COMPILER_TYPE_GCC \ - -DANI_OS_TYPE_ANDROID=6 \ - -DPTT_SOCK_SVC_ENABLE \ - -Wall\ - -Werror\ - -D__linux__ - -KBUILD_CPPFLAGS += $(CDEFINES) - -# Currently, for versions of gcc which support it, the kernel Makefile -# is disabling the maybe-uninitialized warning. Re-enable it for the -# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it -# will override the kernel settings. -ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) -EXTRA_CFLAGS += -Wmaybe-uninitialized -endif -#EXTRA_CFLAGS += -Wmissing-prototypes - -ifeq ($(call cc-option-yn, -Wheader-guard),y) -EXTRA_CFLAGS += -Wheader-guard -endif - -ifeq ($(KERNEL_BUILD), 0) -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers -KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers -endif - -# Module information used by KBuild framework -obj-$(CONFIG_SND_SOC_WCD9360) += wcd9360_dlkm.o -wcd9360_dlkm-y := $(WCD9360_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/wcd9360/wcd9360-defaults.h b/asoc/codecs/wcd9360/wcd9360-defaults.h deleted file mode 100644 index 5557ddafa865..000000000000 --- a/asoc/codecs/wcd9360/wcd9360-defaults.h +++ /dev/null @@ -1,2231 +0,0 @@ -/* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __WCD9360_DEFAULTS_H__ -#define __WCD9360_DEFAULTS_H__ - -#include -#include - -#define WCD9360_REG(reg) ((reg) & 0xFF) - -static const struct reg_default wcd9360_defaults[] = { -{WCD9360_PAGE0_PAGE_REGISTER, 0x00}, -{WCD9360_CODEC_RPM_CLK_BYPASS, 0x00}, -{WCD9360_CODEC_RPM_CLK_GATE, 0x1F}, -{WCD9360_CODEC_RPM_CLK_MCLK_CFG, 0x00}, -{WCD9360_CODEC_RPM_CLK_MCLK2_CFG, 0x02}, -{WCD9360_CODEC_RPM_I2S_DSD_CLK_SEL, 0x00}, -{WCD9360_CODEC_RPM_RST_CTL, 0x00}, -{WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x04}, -{WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE0, 0x10}, -{WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE1, 0x60}, -{WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE2, 0x93}, -{WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE3, 0x01}, -{WCD9360_CHIP_TIER_CTRL_EFUSE_CTL, 0x10}, -{WCD9360_CHIP_TIER_CTRL_EFUSE_TEST0, 0x00}, -{WCD9360_CHIP_TIER_CTRL_EFUSE_TEST1, 0x00}, -{WCD9360_CHIP_TIER_CTRL_EFUSE_STATUS, 0x00}, -{WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO, 0x0D}, -{WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_1, 0x00}, -{WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_2, 0x00}, -{WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_3, 0x00}, -{WCD9360_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL, 0x44}, -{WCD9360_CHIP_TIER_CTRL_I2C_ACTIVE, 0x00}, -{WCD9360_CHIP_TIER_CTRL_ALT_FUNC_EN, 0x00}, -{WCD9360_CHIP_TIER_CTRL_GPIO_CTL_OE, 0x00}, -{WCD9360_CHIP_TIER_CTRL_GPIO_CTL_DATA, 0x00}, -{WCD9360_DATA_HUB_RX0_CFG, 0x00}, -{WCD9360_DATA_HUB_RX1_CFG, 0x00}, -{WCD9360_DATA_HUB_RX2_CFG, 0x00}, -{WCD9360_DATA_HUB_RX3_CFG, 0x00}, -{WCD9360_DATA_HUB_RX4_CFG, 0x00}, -{WCD9360_DATA_HUB_RX5_CFG, 0x00}, -{WCD9360_DATA_HUB_RX6_CFG, 0x00}, -{WCD9360_DATA_HUB_RX7_CFG, 0x00}, -{WCD9360_DATA_HUB_SB_TX0_INP_CFG, 0x00}, -{WCD9360_DATA_HUB_SB_TX1_INP_CFG, 0x00}, -{WCD9360_DATA_HUB_SB_TX2_INP_CFG, 0x00}, -{WCD9360_DATA_HUB_SB_TX3_INP_CFG, 0x00}, -{WCD9360_DATA_HUB_SB_TX4_INP_CFG, 0x00}, -{WCD9360_DATA_HUB_SB_TX5_INP_CFG, 0x00}, -{WCD9360_DATA_HUB_SB_TX6_INP_CFG, 0x00}, -{WCD9360_DATA_HUB_SB_TX7_INP_CFG, 0x00}, -{WCD9360_DATA_HUB_SB_TX8_INP_CFG, 0x00}, -{WCD9360_DATA_HUB_SB_TX9_INP_CFG, 0x00}, -{WCD9360_DATA_HUB_SB_TX10_INP_CFG, 0x00}, -{WCD9360_DATA_HUB_SB_TX11_INP_CFG, 0x00}, -{WCD9360_DATA_HUB_SB_TX12_INP_CFG, 0x00}, -{WCD9360_DATA_HUB_SB_TX13_INP_CFG, 0x00}, -{WCD9360_DATA_HUB_SB_TX14_INP_CFG, 0x00}, -{WCD9360_DATA_HUB_SB_TX15_INP_CFG, 0x00}, -{WCD9360_DATA_HUB_I2S_TX0_CFG, 0x00}, -{WCD9360_DATA_HUB_I2S_TX0_CFG2, 0x00}, -{WCD9360_DATA_HUB_I2S_TX1_0_CFG, 0x00}, -{WCD9360_DATA_HUB_I2S_TX1_1_CFG, 0x00}, -{WCD9360_DATA_HUB_DATA_HUB_CFG, 0x03}, -{WCD9360_DATA_HUB_I2S_0_CTL, 0x0C}, -{WCD9360_DATA_HUB_I2S_1_CTL, 0x0C}, -{WCD9360_DATA_HUB_I2S_0_CTL2, 0x01}, -{WCD9360_DATA_HUB_I2S_1_CTL2, 0x01}, -{WCD9360_DATA_HUB_I2S_CLKSRC_CTL, 0x00}, -{WCD9360_DATA_HUB_I2S_COMMON_CTL, 0x00}, -{WCD9360_DATA_HUB_I2S_0_TDM_CTL, 0x00}, -{WCD9360_DATA_HUB_I2S_0_TDM_CTL2, 0x05}, -{WCD9360_DATA_HUB_I2S_0_TDM_CH_RX, 0x00}, -{WCD9360_DATA_HUB_I2S_0_TDM_CH_TX, 0x00}, -{WCD9360_DATA_HUB_I2S_0_TDM_CFG, 0x00}, -{WCD9360_DATA_HUB_I2S_0_TDM_STRETCH, 0x00}, -{WCD9360_DATA_HUB_I2S_RESET_CTL, 0x00}, -{WCD9360_DMA_RDMA_CTL_0, 0x00}, -{WCD9360_DMA_RDMA_CTL_1, 0x00}, -{WCD9360_DMA_RDMA_CTL_2, 0x00}, -{WCD9360_DMA_RDMA_CTL_3, 0x00}, -{WCD9360_DMA_RDMA_CTL_4, 0x00}, -{WCD9360_DMA_CH_2_3_CFG_RDMA_0, 0xFF}, -{WCD9360_DMA_CH_2_3_CFG_RDMA_1, 0xFF}, -{WCD9360_DMA_CH_2_3_CFG_RDMA_2, 0xFF}, -{WCD9360_DMA_CH_2_3_CFG_RDMA_3, 0xFF}, -{WCD9360_DMA_CH_2_3_CFG_RDMA_4, 0xFF}, -{WCD9360_DMA_CH_0_1_CFG_RDMA_0, 0xFF}, -{WCD9360_DMA_CH_0_1_CFG_RDMA_1, 0xFF}, -{WCD9360_DMA_CH_0_1_CFG_RDMA_2, 0xFF}, -{WCD9360_DMA_CH_0_1_CFG_RDMA_3, 0xFF}, -{WCD9360_DMA_CH_0_1_CFG_RDMA_4, 0xFF}, -{WCD9360_DMA_RDMA4_PRT_CFG, 0x00}, -{WCD9360_DMA_RDMA_SBTX0_7_CFG, 0x00}, -{WCD9360_DMA_RDMA_SBTX8_10_CFG, 0x00}, -{WCD9360_DMA_WDMA_CTL_0, 0x00}, -{WCD9360_DMA_WDMA_CTL_1, 0x00}, -{WCD9360_DMA_WDMA_CTL_2, 0x00}, -{WCD9360_DMA_WDMA_CTL_3, 0x00}, -{WCD9360_DMA_WDMA_CTL_4, 0x00}, -{WCD9360_DMA_CH_4_5_CFG_WDMA_0, 0x00}, -{WCD9360_DMA_CH_4_5_CFG_WDMA_1, 0x00}, -{WCD9360_DMA_CH_4_5_CFG_WDMA_2, 0x00}, -{WCD9360_DMA_CH_4_5_CFG_WDMA_3, 0x00}, -{WCD9360_DMA_CH_4_5_CFG_WDMA_4, 0x00}, -{WCD9360_DMA_CH_2_3_CFG_WDMA_0, 0x00}, -{WCD9360_DMA_CH_2_3_CFG_WDMA_1, 0x00}, -{WCD9360_DMA_CH_2_3_CFG_WDMA_2, 0x00}, -{WCD9360_DMA_CH_2_3_CFG_WDMA_3, 0x00}, -{WCD9360_DMA_CH_2_3_CFG_WDMA_4, 0x00}, -{WCD9360_DMA_CH_0_1_CFG_WDMA_0, 0x00}, -{WCD9360_DMA_CH_0_1_CFG_WDMA_1, 0x00}, -{WCD9360_DMA_CH_0_1_CFG_WDMA_2, 0x00}, -{WCD9360_DMA_CH_0_1_CFG_WDMA_3, 0x00}, -{WCD9360_DMA_CH_0_1_CFG_WDMA_4, 0x00}, -{WCD9360_DMA_WDMA0_PRT_CFG, 0x00}, -{WCD9360_DMA_WDMA3_PRT_CFG, 0x00}, -{WCD9360_DMA_WDMA4_PRT0_3_CFG, 0x00}, -{WCD9360_DMA_WDMA4_PRT4_7_CFG, 0x00}, -{WCD9360_PAGE1_PAGE_REGISTER, 0x00}, -{WCD9360_CPE_FLL_USER_CTL_0, 0x71}, -{WCD9360_CPE_FLL_USER_CTL_1, 0x34}, -{WCD9360_CPE_FLL_USER_CTL_2, 0x0B}, -{WCD9360_CPE_FLL_USER_CTL_3, 0x02}, -{WCD9360_CPE_FLL_USER_CTL_4, 0x04}, -{WCD9360_CPE_FLL_USER_CTL_5, 0x02}, -{WCD9360_CPE_FLL_USER_CTL_6, 0x6E}, -{WCD9360_CPE_FLL_USER_CTL_7, 0x00}, -{WCD9360_CPE_FLL_USER_CTL_8, 0x94}, -{WCD9360_CPE_FLL_USER_CTL_9, 0x50}, -{WCD9360_CPE_FLL_L_VAL_CTL_0, 0x53}, -{WCD9360_CPE_FLL_L_VAL_CTL_1, 0x00}, -{WCD9360_CPE_FLL_DSM_FRAC_CTL_0, 0x00}, -{WCD9360_CPE_FLL_DSM_FRAC_CTL_1, 0xFF}, -{WCD9360_CPE_FLL_CONFIG_CTL_0, 0x6B}, -{WCD9360_CPE_FLL_CONFIG_CTL_1, 0x05}, -{WCD9360_CPE_FLL_CONFIG_CTL_2, 0x20}, -{WCD9360_CPE_FLL_CONFIG_CTL_3, 0x00}, -{WCD9360_CPE_FLL_CONFIG_CTL_4, 0x10}, -{WCD9360_CPE_FLL_TEST_CTL_0, 0x80}, -{WCD9360_CPE_FLL_TEST_CTL_1, 0x00}, -{WCD9360_CPE_FLL_TEST_CTL_2, 0x00}, -{WCD9360_CPE_FLL_TEST_CTL_3, 0x00}, -{WCD9360_CPE_FLL_TEST_CTL_4, 0x00}, -{WCD9360_CPE_FLL_TEST_CTL_5, 0x00}, -{WCD9360_CPE_FLL_TEST_CTL_6, 0x04}, -{WCD9360_CPE_FLL_TEST_CTL_7, 0x33}, -{WCD9360_CPE_FLL_FREQ_CTL_0, 0x00}, -{WCD9360_CPE_FLL_FREQ_CTL_1, 0x00}, -{WCD9360_CPE_FLL_FREQ_CTL_2, 0x00}, -{WCD9360_CPE_FLL_FREQ_CTL_3, 0x00}, -{WCD9360_CPE_FLL_SSC_CTL_0, 0x00}, -{WCD9360_CPE_FLL_SSC_CTL_1, 0x00}, -{WCD9360_CPE_FLL_SSC_CTL_2, 0x00}, -{WCD9360_CPE_FLL_SSC_CTL_3, 0x00}, -{WCD9360_CPE_FLL_FLL_MODE, 0x20}, -{WCD9360_CPE_FLL_STATUS_0, 0x00}, -{WCD9360_CPE_FLL_STATUS_1, 0x00}, -{WCD9360_CPE_FLL_STATUS_2, 0x00}, -{WCD9360_CPE_FLL_STATUS_3, 0x00}, -{WCD9360_I2S_FLL_USER_CTL_0, 0x41}, -{WCD9360_I2S_FLL_USER_CTL_1, 0x94}, -{WCD9360_I2S_FLL_USER_CTL_2, 0x08}, -{WCD9360_I2S_FLL_USER_CTL_3, 0x02}, -{WCD9360_I2S_FLL_USER_CTL_4, 0x04}, -{WCD9360_I2S_FLL_USER_CTL_5, 0x02}, -{WCD9360_I2S_FLL_USER_CTL_6, 0x40}, -{WCD9360_I2S_FLL_USER_CTL_7, 0x00}, -{WCD9360_I2S_FLL_USER_CTL_8, 0x5F}, -{WCD9360_I2S_FLL_USER_CTL_9, 0x02}, -{WCD9360_I2S_FLL_L_VAL_CTL_0, 0x40}, -{WCD9360_I2S_FLL_L_VAL_CTL_1, 0x00}, -{WCD9360_I2S_FLL_DSM_FRAC_CTL_0, 0x00}, -{WCD9360_I2S_FLL_DSM_FRAC_CTL_1, 0xFF}, -{WCD9360_I2S_FLL_CONFIG_CTL_0, 0x6B}, -{WCD9360_I2S_FLL_CONFIG_CTL_1, 0x05}, -{WCD9360_I2S_FLL_CONFIG_CTL_2, 0x20}, -{WCD9360_I2S_FLL_CONFIG_CTL_3, 0x00}, -{WCD9360_I2S_FLL_CONFIG_CTL_4, 0x30}, -{WCD9360_I2S_FLL_TEST_CTL_0, 0x80}, -{WCD9360_I2S_FLL_TEST_CTL_1, 0x00}, -{WCD9360_I2S_FLL_TEST_CTL_2, 0x00}, -{WCD9360_I2S_FLL_TEST_CTL_3, 0x00}, -{WCD9360_I2S_FLL_TEST_CTL_4, 0x00}, -{WCD9360_I2S_FLL_TEST_CTL_5, 0x00}, -{WCD9360_I2S_FLL_TEST_CTL_6, 0x04}, -{WCD9360_I2S_FLL_TEST_CTL_7, 0xFF}, -{WCD9360_I2S_FLL_FREQ_CTL_0, 0x00}, -{WCD9360_I2S_FLL_FREQ_CTL_1, 0x00}, -{WCD9360_I2S_FLL_FREQ_CTL_2, 0x00}, -{WCD9360_I2S_FLL_FREQ_CTL_3, 0x00}, -{WCD9360_I2S_FLL_SSC_CTL_0, 0x00}, -{WCD9360_I2S_FLL_SSC_CTL_1, 0x00}, -{WCD9360_I2S_FLL_SSC_CTL_2, 0x00}, -{WCD9360_I2S_FLL_SSC_CTL_3, 0x00}, -{WCD9360_I2S_FLL_FLL_MODE, 0x00}, -{WCD9360_I2S_FLL_STATUS_0, 0x00}, -{WCD9360_I2S_FLL_STATUS_1, 0x00}, -{WCD9360_I2S_FLL_STATUS_2, 0x00}, -{WCD9360_I2S_FLL_STATUS_3, 0x00}, -{WCD9360_PAGE2_PAGE_REGISTER, 0x00}, -{WCD9360_CPE_SS_CPE_CTL, 0x05}, -{WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_0, 0x01}, -{WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_1, 0x00}, -{WCD9360_CPE_SS_PWR_CPEFLL_CTL, 0x02}, -{WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, 0xFF}, -{WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, 0x03}, -{WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0, 0xFF}, -{WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1, 0xFF}, -{WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2, 0xFF}, -{WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3, 0xFF}, -{WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_4, 0xFF}, -{WCD9360_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN, 0x07}, -{WCD9360_CPE_SS_US_BUF_INT_PERIOD, 0x5F}, -{WCD9360_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD, 0x13}, -{WCD9360_CPE_SS_SVA_CFG, 0x41}, -{WCD9360_CPE_SS_US_CFG, 0x00}, -{WCD9360_CPE_SS_MAD_CTL, 0x00}, -{WCD9360_CPE_SS_CPAR_CTL, 0x00}, -{WCD9360_CPE_SS_DMIC0_CTL, 0x00}, -{WCD9360_CPE_SS_DMIC1_CTL, 0x00}, -{WCD9360_CPE_SS_DMIC2_CTL, 0x00}, -{WCD9360_CPE_SS_DMIC_CFG, 0x80}, -{WCD9360_CPE_SS_CPAR_CFG, 0x00}, -{WCD9360_CPE_SS_WDOG_CFG, 0x01}, -{WCD9360_CPE_SS_BACKUP_INT, 0x00}, -{WCD9360_CPE_SS_STATUS, 0x00}, -{WCD9360_CPE_SS_CPE_OCD_CFG, 0x00}, -{WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A, 0xFF}, -{WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B, 0x3F}, -{WCD9360_CPE_SS_SS_ERROR_INT_MASK_1A, 0xFF}, -{WCD9360_CPE_SS_SS_ERROR_INT_MASK_1B, 0x3F}, -{WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0A, 0x00}, -{WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0B, 0x00}, -{WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1A, 0x00}, -{WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1B, 0x00}, -{WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0A, 0x00}, -{WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0B, 0x00}, -{WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1A, 0x00}, -{WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1B, 0x00}, -{WCD9360_CPE_SS_DMIC3_CTL, 0x00}, -{WCD9360_CPE_SS_WDOG_RESET, 0x00}, -{WCD9360_CPE_SS_LPASS_MCLK_PRG, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_IN_0, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_IN_1, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_IN_2, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_IN_3, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_IN_4, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_IN_5, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_IN_6, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_IN_7, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_IN_8, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_IN_9, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_IN_10, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_IN_11, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_IN_12, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_IN_13, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_IN_14, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_IN_15, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_OUT_0, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_OUT_1, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_OUT_2, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_OUT_3, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_OUT_4, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_OUT_5, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_OUT_6, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_OUT_7, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_OUT_8, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_OUT_9, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_OUT_10, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_OUT_11, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_OUT_12, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_OUT_13, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_OUT_14, 0x00}, -{WCD9360_CPE_SS_LPASS_IPC_OUT_15, 0x00}, -{WCD9360_CPE_SS_LPASS_ARB_CTL, 0x00}, -{WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_0, 0x00}, -{WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_1, 0x00}, -{WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_0, 0x00}, -{WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_1, 0x00}, -{WCD9360_SOC_MAD_MAIN_CTL_1, 0x00}, -{WCD9360_SOC_MAD_MAIN_CTL_2, 0x00}, -{WCD9360_SOC_MAD_AUDIO_CTL_1, 0x00}, -{WCD9360_SOC_MAD_AUDIO_CTL_2, 0x00}, -{WCD9360_SOC_MAD_AUDIO_CTL_3, 0x00}, -{WCD9360_SOC_MAD_AUDIO_CTL_4, 0x00}, -{WCD9360_SOC_MAD_AUDIO_CTL_5, 0x00}, -{WCD9360_SOC_MAD_AUDIO_CTL_6, 0x00}, -{WCD9360_SOC_MAD_AUDIO_CTL_7, 0x00}, -{WCD9360_SOC_MAD_AUDIO_CTL_8, 0x00}, -{WCD9360_SOC_MAD_AUDIO_IIR_CTL_PTR, 0x00}, -{WCD9360_SOC_MAD_AUDIO_IIR_CTL_VAL, 0x40}, -{WCD9360_SOC_MAD_ULTR_CTL_1, 0x00}, -{WCD9360_SOC_MAD_ULTR_CTL_2, 0x00}, -{WCD9360_SOC_MAD_ULTR_CTL_3, 0x00}, -{WCD9360_SOC_MAD_ULTR_CTL_4, 0x00}, -{WCD9360_SOC_MAD_ULTR_CTL_5, 0x00}, -{WCD9360_SOC_MAD_ULTR_CTL_6, 0x00}, -{WCD9360_SOC_MAD_ULTR_CTL_7, 0x00}, -{WCD9360_SOC_MAD_BEACON_CTL_1, 0x00}, -{WCD9360_SOC_MAD_BEACON_CTL_2, 0x00}, -{WCD9360_SOC_MAD_BEACON_CTL_3, 0x00}, -{WCD9360_SOC_MAD_BEACON_CTL_4, 0x00}, -{WCD9360_SOC_MAD_BEACON_CTL_5, 0x00}, -{WCD9360_SOC_MAD_BEACON_CTL_6, 0x00}, -{WCD9360_SOC_MAD_BEACON_CTL_7, 0x00}, -{WCD9360_SOC_MAD_BEACON_CTL_8, 0x00}, -{WCD9360_SOC_MAD_BEACON_IIR_CTL_PTR, 0x00}, -{WCD9360_SOC_MAD_BEACON_IIR_CTL_VAL, 0x00}, -{WCD9360_SOC_MAD_INP_SEL, 0x00}, -{WCD9360_SOC_MAD_MAD2_INP_SEL, 0x00}, -{WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_CTRL, 0x00}, -{WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_STATUS, 0x00}, -{WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_FS, 0x00}, -{WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_IN_SEL, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT0, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT1, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT2, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT3, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT4, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT5, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT6, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT7, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT8, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT9, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT10, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT11, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT12, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT13, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT14, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT15, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT0, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT1, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT2, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT3, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT4, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT5, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT6, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT7, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT8, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT9, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT10, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT11, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT12, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT13, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT14, 0x00}, -{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT15, 0x00}, -{WCD9360_PAGE4_PAGE_REGISTER, 0x00}, -{WCD9360_INTR_CFG, 0x00}, -{WCD9360_INTR_CLR_COMMIT, 0x00}, -{WCD9360_INTR_PIN1_MASK0, 0xFF}, -{WCD9360_INTR_PIN1_MASK1, 0xFF}, -{WCD9360_INTR_PIN1_MASK2, 0xFF}, -{WCD9360_INTR_PIN1_MASK3, 0xFF}, -{WCD9360_INTR_PIN1_STATUS0, 0x00}, -{WCD9360_INTR_PIN1_STATUS1, 0x00}, -{WCD9360_INTR_PIN1_STATUS2, 0x00}, -{WCD9360_INTR_PIN1_STATUS3, 0x00}, -{WCD9360_INTR_PIN1_CLEAR0, 0x00}, -{WCD9360_INTR_PIN1_CLEAR1, 0x00}, -{WCD9360_INTR_PIN1_CLEAR2, 0x00}, -{WCD9360_INTR_PIN1_CLEAR3, 0x00}, -{WCD9360_INTR_PIN2_MASK3, 0xFF}, -{WCD9360_INTR_PIN2_STATUS3, 0x00}, -{WCD9360_INTR_PIN2_CLEAR3, 0x00}, -{WCD9360_INTR_CPESS_SUMRY_MASK2, 0xFF}, -{WCD9360_INTR_CPESS_SUMRY_MASK3, 0xFF}, -{WCD9360_INTR_CPESS_SUMRY_STATUS2, 0x00}, -{WCD9360_INTR_CPESS_SUMRY_STATUS3, 0x00}, -{WCD9360_INTR_CPESS_SUMRY_CLEAR2, 0x00}, -{WCD9360_INTR_CPESS_SUMRY_CLEAR3, 0x00}, -{WCD9360_INTR_LEVEL0, 0x3B}, -{WCD9360_INTR_LEVEL1, 0x00}, -{WCD9360_INTR_LEVEL2, 0xD0}, -{WCD9360_INTR_LEVEL3, 0x00}, -{WCD9360_INTR_BYPASS0, 0x00}, -{WCD9360_INTR_BYPASS1, 0x00}, -{WCD9360_INTR_BYPASS2, 0x00}, -{WCD9360_INTR_BYPASS3, 0x00}, -{WCD9360_INTR_SET0, 0x00}, -{WCD9360_INTR_SET1, 0x00}, -{WCD9360_INTR_SET2, 0x00}, -{WCD9360_INTR_SET3, 0x00}, -{WCD9360_INTR_CODEC_MISC_MASK, 0x73}, -{WCD9360_INTR_CODEC_MISC_STATUS, 0x00}, -{WCD9360_INTR_CODEC_MISC_CLEAR, 0x00}, -{WCD9360_ANA_PAGE_REGISTER, 0x00}, -{WCD9360_ANA_BIAS, 0x00}, -{WCD9360_ANA_RCO, 0x00}, -{WCD9360_ANA_BUCK_CTL, 0x00}, -{WCD9360_ANA_BUCK_STATUS, 0x00}, -{WCD9360_ANA_EAR, 0x00}, -{WCD9360_ANA_MAD_SETUP, 0x01}, -{WCD9360_ANA_AMIC1, 0x20}, -{WCD9360_ANA_AMIC2, 0x00}, -{WCD9360_ANA_AMIC3, 0x20}, -{WCD9360_ANA_AMIC4, 0x00}, -{WCD9360_ANA_MICB1, 0x10}, -{WCD9360_ANA_MICB2, 0x10}, -{WCD9360_ANA_MICB3, 0x10}, -{WCD9360_ANA_MICB4, 0x10}, -{WCD9360_BIAS_CTL, 0x2A}, -{WCD9360_BIAS_VBG_FINE_ADJ, 0x55}, -{WCD9360_RCO_CTRL_1, 0x44}, -{WCD9360_RCO_CTRL_2, 0x48}, -{WCD9360_RCO_CAL, 0x00}, -{WCD9360_RCO_CAL_1, 0x00}, -{WCD9360_RCO_CAL_2, 0x00}, -{WCD9360_RCO_TEST_CTRL, 0x00}, -{WCD9360_RCO_CAL_OUT_1, 0x00}, -{WCD9360_RCO_CAL_OUT_2, 0x00}, -{WCD9360_RCO_CAL_OUT_3, 0x00}, -{WCD9360_RCO_CAL_OUT_4, 0x00}, -{WCD9360_RCO_CAL_OUT_5, 0x00}, -{WCD9360_SIDO_MODE_1, 0x84}, -{WCD9360_SIDO_MODE_2, 0xFE}, -{WCD9360_SIDO_MODE_3, 0xF6}, -{WCD9360_SIDO_MODE_4, 0x56}, -{WCD9360_SIDO_VCL_1, 0x00}, -{WCD9360_SIDO_VCL_2, 0x6C}, -{WCD9360_SIDO_VCL_3, 0x44}, -{WCD9360_SIDO_CCL_1, 0x57}, -{WCD9360_SIDO_CCL_2, 0x92}, -{WCD9360_SIDO_CCL_3, 0x35}, -{WCD9360_SIDO_CCL_4, 0x61}, -{WCD9360_SIDO_CCL_5, 0x6D}, -{WCD9360_SIDO_CCL_6, 0x60}, -{WCD9360_SIDO_CCL_7, 0x6F}, -{WCD9360_SIDO_CCL_8, 0x6F}, -{WCD9360_SIDO_CCL_9, 0x6E}, -{WCD9360_SIDO_CCL_10, 0x26}, -{WCD9360_SIDO_FILTER_1, 0x92}, -{WCD9360_SIDO_FILTER_2, 0x54}, -{WCD9360_SIDO_DRIVER_1, 0x77}, -{WCD9360_SIDO_DRIVER_2, 0x55}, -{WCD9360_SIDO_DRIVER_3, 0x55}, -{WCD9360_SIDO_CAL_CODE_EXT_1, 0x9C}, -{WCD9360_SIDO_CAL_CODE_EXT_2, 0x82}, -{WCD9360_SIDO_CAL_CODE_OUT_1, 0x00}, -{WCD9360_SIDO_CAL_CODE_OUT_2, 0x00}, -{WCD9360_SIDO_TEST_1, 0x00}, -{WCD9360_SIDO_TEST_2, 0x00}, -{WCD9360_LDOH_MODE, 0x2B}, -{WCD9360_LDOH_BIAS, 0x68}, -{WCD9360_LDOH_STB_LOADS, 0x00}, -{WCD9360_LDOH_SLOWRAMP, 0x50}, -{WCD9360_MICB1_TEST_CTL_1, 0x1A}, -{WCD9360_MICB1_TEST_CTL_2, 0x18}, -{WCD9360_MICB1_TEST_CTL_3, 0xA4}, -{WCD9360_MICB2_TEST_CTL_1, 0x1A}, -{WCD9360_MICB2_TEST_CTL_2, 0x18}, -{WCD9360_MICB2_TEST_CTL_3, 0xA4}, -{WCD9360_MICB3_TEST_CTL_1, 0x1A}, -{WCD9360_MICB3_TEST_CTL_2, 0x18}, -{WCD9360_MICB3_TEST_CTL_3, 0xA4}, -{WCD9360_MICB4_TEST_CTL_1, 0x1A}, -{WCD9360_MICB4_TEST_CTL_2, 0x18}, -{WCD9360_MICB4_TEST_CTL_3, 0xA4}, -{WCD9360_TX_COM_ADC_VCM, 0x39}, -{WCD9360_TX_COM_BIAS_ATEST, 0xC0}, -{WCD9360_TX_COM_ADC_INT1_IB, 0x6F}, -{WCD9360_TX_COM_ADC_INT2_IB, 0x4F}, -{WCD9360_TX_COM_TXFE_DIV_CTL, 0x2E}, -{WCD9360_TX_COM_TXFE_DIV_START, 0x00}, -{WCD9360_TX_COM_TXFE_DIV_STOP_9P6M, 0xC7}, -{WCD9360_TX_COM_TXFE_DIV_STOP_12P288M, 0xFF}, -{WCD9360_TX_1_2_TEST_EN, 0xCC}, -{WCD9360_TX_1_2_ADC_IB, 0x09}, -{WCD9360_TX_1_2_ATEST_REFCTL, 0x0A}, -{WCD9360_TX_1_2_TEST_CTL, 0x38}, -{WCD9360_TX_1_2_TEST_BLK_EN, 0xFF}, -{WCD9360_TX_1_2_TXFE_CLKDIV, 0x00}, -{WCD9360_TX_1_2_SAR1_ERR, 0x00}, -{WCD9360_TX_1_2_SAR2_ERR, 0x00}, -{WCD9360_TX_3_4_TEST_EN, 0xCC}, -{WCD9360_TX_3_4_ADC_IB, 0x09}, -{WCD9360_TX_3_4_ATEST_REFCTL, 0x0A}, -{WCD9360_TX_3_4_TEST_CTL, 0x38}, -{WCD9360_TX_3_4_TEST_BLK_EN, 0xFF}, -{WCD9360_TX_3_4_TXFE_CLKDIV, 0x00}, -{WCD9360_TX_3_4_SAR1_ERR, 0x00}, -{WCD9360_TX_3_4_SAR2_ERR, 0x00}, -{WCD9360_RX_RX_EAR_BIAS_CON_1, 0x2A}, -{WCD9360_RX_RX_EAR_BIAS_CON_2, 0x8A}, -{WCD9360_RX_RX_AUX_BIAS_CON_1, 0x2A}, -{WCD9360_RX_RX_AUX_BIAS_CON_2, 0x8A}, -{WCD9360_RX_RX_BIAS_ATEST, 0x0C}, -{WCD9360_RX_RXTOP_RESERVED, 0x00}, -{WCD9360_EAR_EAR_EN_REG, 0x22}, -{WCD9360_EAR_EAR_PA_CON, 0x44}, -{WCD9360_EAR_EAR_SP_CON, 0xDB}, -{WCD9360_EAR_EAR_DAC_CON, 0x00}, -{WCD9360_EAR_EAR_CNP_FSM_CON, 0xB6}, -{WCD9360_EAR_DAC_CTL_TEST, 0x00}, -{WCD9360_EAR_STATUS_REG, 0x00}, -{WCD9360_EAR_EAR_COMPANDER_CON, 0x02}, -{WCD9360_ANA_NEW_PAGE_REGISTER, 0x00}, -{WCD9360_CLK_SYS_PLL_ENABLES, 0x00}, -{WCD9360_CLK_SYS_PLL_PRESET, 0x00}, -{WCD9360_CLK_SYS_PLL_STATUS, 0x00}, -{WCD9360_CLK_SYS_MCLK_PRG, 0x10}, -{WCD9360_CLK_SYS_MCLK2_PRG1, 0x00}, -{WCD9360_CLK_SYS_MCLK_MISC, 0x00}, -{WCD9360_SIDO_NEW_VOUT_A_STARTUP, 0x17}, -{WCD9360_SIDO_NEW_VOUT_D_STARTUP, 0x0D}, -{WCD9360_SIDO_NEW_VOUT_D_FREQ1, 0x07}, -{WCD9360_SIDO_NEW_VOUT_D_FREQ2, 0x00}, -{WCD9360_AUX_ANA_EAR, 0x00}, -{WCD9360_LDORXTX_LDORXTX, 0x10}, -{WCD9360_DIE_CRACK_CTL, 0x00}, -{WCD9360_DIE_CRACK_OUT, 0x00}, -{WCD9360_LOOP_BACK_EN, 0x00}, -{WCD9360_CLK_SYS_INT_POST_DIV_REG0, 0x00}, -{WCD9360_CLK_SYS_INT_POST_DIV_REG1, 0x00}, -{WCD9360_CLK_SYS_INT_REF_DIV_REG0, 0x00}, -{WCD9360_CLK_SYS_INT_REF_DIV_REG1, 0x00}, -{WCD9360_CLK_SYS_INT_FILTER_REG0, 0x00}, -{WCD9360_CLK_SYS_INT_FILTER_REG1, 0x00}, -{WCD9360_CLK_SYS_INT_PLL_L_VAL, 0x00}, -{WCD9360_CLK_SYS_INT_PLL_M_VAL, 0x00}, -{WCD9360_CLK_SYS_INT_PLL_N_VAL, 0x00}, -{WCD9360_CLK_SYS_INT_TEST_REG0, 0x00}, -{WCD9360_CLK_SYS_INT_PFD_CP_DSM_PROG, 0x00}, -{WCD9360_CLK_SYS_INT_VCO_PROG, 0x00}, -{WCD9360_CLK_SYS_INT_TEST_REG1, 0x00}, -{WCD9360_CLK_SYS_INT_LDO_LOCK_CFG, 0x00}, -{WCD9360_CLK_SYS_INT_DIG_LOCK_DET_CFG, 0x00}, -{WCD9360_CLK_SYS_INT_CLK_TEST1, 0x00}, -{WCD9360_CLK_SYS_INT_CLK_TEST2, 0x00}, -{WCD9360_CLK_SYS_INT_CLK_TEST3, 0x00}, -{WCD9360_SIDO_NEW_INT_RAMP_STATUS, 0x00}, -{WCD9360_SIDO_NEW_INT_SPARE_1, 0x00}, -{WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_A, 0x64}, -{WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_D, 0x40}, -{WCD9360_SIDO_NEW_INT_RAMP_INC_WAIT, 0x24}, -{WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_CTL, 0x09}, -{WCD9360_SIDO_NEW_INT_RAMP_IBLEED_CTL, 0x7D}, -{WCD9360_SIDO_NEW_INT_DEBUG_CPROVR_TEST, 0x00}, -{WCD9360_SIDO_NEW_INT_RAMP_CTL_A, 0x14}, -{WCD9360_SIDO_NEW_INT_RAMP_CTL_D, 0x14}, -{WCD9360_SIDO_NEW_INT_RAMP_TIMEOUT_PERIOD, 0x33}, -{WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING1, 0x3F}, -{WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING2, 0x74}, -{WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING3, 0x33}, -{WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL1, 0x1D}, -{WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL2, 0x0A}, -{WCD9360_EAR_INT_NEW_EAR_CHOPPER_CON, 0xA8}, -{WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON1, 0x42}, -{WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON2, 0x22}, -{WCD9360_EAR_INT_NEW_EAR_DYNAMIC_BIAS, 0x00}, -{WCD9360_AUX_INT_AUX_EN_REG, 0x22}, -{WCD9360_AUX_INT_AUX_PA_CON, 0x46}, -{WCD9360_AUX_INT_AUX_SP_CON, 0xD2}, -{WCD9360_AUX_INT_AUX_DAC_CON, 0x00}, -{WCD9360_AUX_INT_AUX_CNP_FSM_CON, 0xB6}, -{WCD9360_AUX_INT_AUX_TEST, 0x00}, -{WCD9360_AUX_INT_STATUS_REG, 0x00}, -{WCD9360_AUX_INT_AUX_MISC, 0x00}, -{WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL1, 0xFF}, -{WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL2, 0xD8}, -{WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL3, 0x80}, -{WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL4, 0xFF}, -{WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL5, 0x09}, -{WCD9360_LDORXTX_INT_ANA_LDORXTX_STATUS, 0x00}, -{WCD9360_DIE_CRACK_INT_INT1, 0x02}, -{WCD9360_DIE_CRACK_INT_INT2, 0x60}, -{WCD9360_LOOP_BACK_INT_SPARE, 0x00}, -{WCD9360_PAGE10_PAGE_REGISTER, 0x00}, -{WCD9360_CDC_ANC0_CLK_RESET_CTL, 0x00}, -{WCD9360_CDC_ANC0_MODE_1_CTL, 0x00}, -{WCD9360_CDC_ANC0_MODE_2_CTL, 0x00}, -{WCD9360_CDC_ANC0_FF_SHIFT, 0x00}, -{WCD9360_CDC_ANC0_FB_SHIFT, 0x00}, -{WCD9360_CDC_ANC0_LPF_FF_A_CTL, 0x00}, -{WCD9360_CDC_ANC0_LPF_FF_B_CTL, 0x00}, -{WCD9360_CDC_ANC0_LPF_FB_CTL, 0x00}, -{WCD9360_CDC_ANC0_SMLPF_CTL, 0x00}, -{WCD9360_CDC_ANC0_DCFLT_SHIFT_CTL, 0x00}, -{WCD9360_CDC_ANC0_IIR_ADAPT_CTL, 0x00}, -{WCD9360_CDC_ANC0_IIR_COEFF_1_CTL, 0x00}, -{WCD9360_CDC_ANC0_IIR_COEFF_2_CTL, 0x00}, -{WCD9360_CDC_ANC0_FF_A_GAIN_CTL, 0x00}, -{WCD9360_CDC_ANC0_FF_B_GAIN_CTL, 0x00}, -{WCD9360_CDC_ANC0_FB_GAIN_CTL, 0x00}, -{WCD9360_CDC_TX0_TX_PATH_CTL, 0x04}, -{WCD9360_CDC_TX0_TX_PATH_CFG0, 0x10}, -{WCD9360_CDC_TX0_TX_PATH_CFG1, 0x03}, -{WCD9360_CDC_TX0_TX_VOL_CTL, 0x00}, -{WCD9360_CDC_TX0_TX_PATH_192_CTL, 0x00}, -{WCD9360_CDC_TX0_TX_PATH_192_CFG, 0x00}, -{WCD9360_CDC_TX0_TX_PATH_SEC0, 0x00}, -{WCD9360_CDC_TX0_TX_PATH_SEC1, 0x00}, -{WCD9360_CDC_TX0_TX_PATH_SEC2, 0x01}, -{WCD9360_CDC_TX0_TX_PATH_SEC3, 0x3C}, -{WCD9360_CDC_TX0_TX_PATH_SEC4, 0x20}, -{WCD9360_CDC_TX0_TX_PATH_SEC5, 0x00}, -{WCD9360_CDC_TX0_TX_PATH_SEC6, 0x00}, -{WCD9360_CDC_TX1_TX_PATH_CTL, 0x04}, -{WCD9360_CDC_TX1_TX_PATH_CFG0, 0x10}, -{WCD9360_CDC_TX1_TX_PATH_CFG1, 0x03}, -{WCD9360_CDC_TX1_TX_VOL_CTL, 0x00}, -{WCD9360_CDC_TX1_TX_PATH_192_CTL, 0x00}, -{WCD9360_CDC_TX1_TX_PATH_192_CFG, 0x00}, -{WCD9360_CDC_TX1_TX_PATH_SEC0, 0x00}, -{WCD9360_CDC_TX1_TX_PATH_SEC1, 0x00}, -{WCD9360_CDC_TX1_TX_PATH_SEC2, 0x01}, -{WCD9360_CDC_TX1_TX_PATH_SEC3, 0x3C}, -{WCD9360_CDC_TX1_TX_PATH_SEC4, 0x20}, -{WCD9360_CDC_TX1_TX_PATH_SEC5, 0x00}, -{WCD9360_CDC_TX1_TX_PATH_SEC6, 0x00}, -{WCD9360_CDC_TX2_TX_PATH_CTL, 0x04}, -{WCD9360_CDC_TX2_TX_PATH_CFG0, 0x10}, -{WCD9360_CDC_TX2_TX_PATH_CFG1, 0x03}, -{WCD9360_CDC_TX2_TX_VOL_CTL, 0x00}, -{WCD9360_CDC_TX2_TX_PATH_192_CTL, 0x00}, -{WCD9360_CDC_TX2_TX_PATH_192_CFG, 0x00}, -{WCD9360_CDC_TX2_TX_PATH_SEC0, 0x00}, -{WCD9360_CDC_TX2_TX_PATH_SEC1, 0x00}, -{WCD9360_CDC_TX2_TX_PATH_SEC2, 0x01}, -{WCD9360_CDC_TX2_TX_PATH_SEC3, 0x3C}, -{WCD9360_CDC_TX2_TX_PATH_SEC4, 0x20}, -{WCD9360_CDC_TX2_TX_PATH_SEC5, 0x00}, -{WCD9360_CDC_TX2_TX_PATH_SEC6, 0x00}, -{WCD9360_CDC_TX3_TX_PATH_CTL, 0x04}, -{WCD9360_CDC_TX3_TX_PATH_CFG0, 0x10}, -{WCD9360_CDC_TX3_TX_PATH_CFG1, 0x03}, -{WCD9360_CDC_TX3_TX_VOL_CTL, 0x00}, -{WCD9360_CDC_TX3_TX_PATH_192_CTL, 0x00}, -{WCD9360_CDC_TX3_TX_PATH_192_CFG, 0x00}, -{WCD9360_CDC_TX3_TX_PATH_SEC0, 0x00}, -{WCD9360_CDC_TX3_TX_PATH_SEC1, 0x00}, -{WCD9360_CDC_TX3_TX_PATH_SEC2, 0x01}, -{WCD9360_CDC_TX3_TX_PATH_SEC3, 0x3C}, -{WCD9360_CDC_TX3_TX_PATH_SEC4, 0x20}, -{WCD9360_CDC_TX3_TX_PATH_SEC5, 0x00}, -{WCD9360_CDC_TX3_TX_PATH_SEC6, 0x00}, -{WCD9360_CDC_TX4_TX_PATH_CTL, 0x04}, -{WCD9360_CDC_TX4_TX_PATH_CFG0, 0x10}, -{WCD9360_CDC_TX4_TX_PATH_CFG1, 0x03}, -{WCD9360_CDC_TX4_TX_VOL_CTL, 0x00}, -{WCD9360_CDC_TX4_TX_PATH_192_CTL, 0x00}, -{WCD9360_CDC_TX4_TX_PATH_192_CFG, 0x00}, -{WCD9360_CDC_TX4_TX_PATH_SEC0, 0x00}, -{WCD9360_CDC_TX4_TX_PATH_SEC1, 0x00}, -{WCD9360_CDC_TX4_TX_PATH_SEC2, 0x01}, -{WCD9360_CDC_TX4_TX_PATH_SEC3, 0x3C}, -{WCD9360_CDC_TX4_TX_PATH_SEC4, 0x20}, -{WCD9360_CDC_TX4_TX_PATH_SEC5, 0x00}, -{WCD9360_CDC_TX4_TX_PATH_SEC6, 0x00}, -{WCD9360_CDC_TX5_TX_PATH_CTL, 0x04}, -{WCD9360_CDC_TX5_TX_PATH_CFG0, 0x10}, -{WCD9360_CDC_TX5_TX_PATH_CFG1, 0x03}, -{WCD9360_CDC_TX5_TX_VOL_CTL, 0x00}, -{WCD9360_CDC_TX5_TX_PATH_192_CTL, 0x00}, -{WCD9360_CDC_TX5_TX_PATH_192_CFG, 0x00}, -{WCD9360_CDC_TX5_TX_PATH_SEC0, 0x00}, -{WCD9360_CDC_TX5_TX_PATH_SEC1, 0x00}, -{WCD9360_CDC_TX5_TX_PATH_SEC2, 0x01}, -{WCD9360_CDC_TX5_TX_PATH_SEC3, 0x3C}, -{WCD9360_CDC_TX5_TX_PATH_SEC4, 0x20}, -{WCD9360_CDC_TX5_TX_PATH_SEC5, 0x00}, -{WCD9360_CDC_TX5_TX_PATH_SEC6, 0x00}, -{WCD9360_CDC_TX6_TX_PATH_CTL, 0x04}, -{WCD9360_CDC_TX6_TX_PATH_CFG0, 0x10}, -{WCD9360_CDC_TX6_TX_PATH_CFG1, 0x03}, -{WCD9360_CDC_TX6_TX_VOL_CTL, 0x00}, -{WCD9360_CDC_TX6_TX_PATH_192_CTL, 0x00}, -{WCD9360_CDC_TX6_TX_PATH_192_CFG, 0x00}, -{WCD9360_CDC_TX6_TX_PATH_SEC0, 0x00}, -{WCD9360_CDC_TX6_TX_PATH_SEC1, 0x00}, -{WCD9360_CDC_TX6_TX_PATH_SEC2, 0x01}, -{WCD9360_CDC_TX6_TX_PATH_SEC3, 0x3C}, -{WCD9360_CDC_TX6_TX_PATH_SEC4, 0x20}, -{WCD9360_CDC_TX6_TX_PATH_SEC5, 0x00}, -{WCD9360_CDC_TX6_TX_PATH_SEC6, 0x00}, -{WCD9360_CDC_TX7_TX_PATH_CTL, 0x04}, -{WCD9360_CDC_TX7_TX_PATH_CFG0, 0x10}, -{WCD9360_CDC_TX7_TX_PATH_CFG1, 0x03}, -{WCD9360_CDC_TX7_TX_VOL_CTL, 0x00}, -{WCD9360_CDC_TX7_TX_PATH_192_CTL, 0x00}, -{WCD9360_CDC_TX7_TX_PATH_192_CFG, 0x00}, -{WCD9360_CDC_TX7_TX_PATH_SEC0, 0x00}, -{WCD9360_CDC_TX7_TX_PATH_SEC1, 0x00}, -{WCD9360_CDC_TX7_TX_PATH_SEC2, 0x01}, -{WCD9360_CDC_TX7_TX_PATH_SEC3, 0x3C}, -{WCD9360_CDC_TX7_TX_PATH_SEC4, 0x20}, -{WCD9360_CDC_TX7_TX_PATH_SEC5, 0x00}, -{WCD9360_CDC_TX7_TX_PATH_SEC6, 0x00}, -{WCD9360_CDC_TX8_TX_PATH_CTL, 0x04}, -{WCD9360_CDC_TX8_TX_PATH_CFG0, 0x10}, -{WCD9360_CDC_TX8_TX_PATH_CFG1, 0x03}, -{WCD9360_CDC_TX8_TX_VOL_CTL, 0x00}, -{WCD9360_CDC_TX8_TX_PATH_192_CTL, 0x00}, -{WCD9360_CDC_TX8_TX_PATH_192_CFG, 0x00}, -{WCD9360_CDC_TX8_TX_PATH_SEC0, 0x00}, -{WCD9360_CDC_TX8_TX_PATH_SEC1, 0x00}, -{WCD9360_CDC_TX8_TX_PATH_SEC2, 0x01}, -{WCD9360_CDC_TX8_TX_PATH_SEC3, 0x3C}, -{WCD9360_CDC_TX8_TX_PATH_SEC4, 0x20}, -{WCD9360_CDC_TX8_TX_PATH_SEC5, 0x00}, -{WCD9360_CDC_TX8_TX_PATH_SEC6, 0x00}, -{WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x02}, -{WCD9360_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x00}, -{WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x02}, -{WCD9360_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x00}, -{WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x02}, -{WCD9360_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x00}, -{WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x02}, -{WCD9360_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x00}, -{WCD9360_PAGE11_PAGE_REGISTER, 0x00}, -{WCD9360_CDC_COMPANDER0_CTL0, 0x60}, -{WCD9360_CDC_COMPANDER0_CTL1, 0xDB}, -{WCD9360_CDC_COMPANDER0_CTL2, 0xFF}, -{WCD9360_CDC_COMPANDER0_CTL3, 0x35}, -{WCD9360_CDC_COMPANDER0_CTL4, 0xFF}, -{WCD9360_CDC_COMPANDER0_CTL5, 0x00}, -{WCD9360_CDC_COMPANDER0_CTL6, 0x01}, -{WCD9360_CDC_COMPANDER0_CTL7, 0x06}, -{WCD9360_CDC_COMPANDER7_CTL0, 0x60}, -{WCD9360_CDC_COMPANDER7_CTL1, 0xDB}, -{WCD9360_CDC_COMPANDER7_CTL2, 0xFF}, -{WCD9360_CDC_COMPANDER7_CTL3, 0x35}, -{WCD9360_CDC_COMPANDER7_CTL4, 0xFF}, -{WCD9360_CDC_COMPANDER7_CTL5, 0x00}, -{WCD9360_CDC_COMPANDER7_CTL6, 0x01}, -{WCD9360_CDC_COMPANDER7_CTL7, 0x06}, -{WCD9360_CDC_COMPANDER8_CTL0, 0x60}, -{WCD9360_CDC_COMPANDER8_CTL1, 0xDB}, -{WCD9360_CDC_COMPANDER8_CTL2, 0xFF}, -{WCD9360_CDC_COMPANDER8_CTL3, 0x35}, -{WCD9360_CDC_COMPANDER8_CTL4, 0xFF}, -{WCD9360_CDC_COMPANDER8_CTL5, 0x00}, -{WCD9360_CDC_COMPANDER8_CTL6, 0x01}, -{WCD9360_CDC_COMPANDER8_CTL7, 0x06}, -{WCD9360_CDC_RX0_RX_PATH_CTL, 0x04}, -{WCD9360_CDC_RX0_RX_PATH_CFG0, 0x00}, -{WCD9360_CDC_RX0_RX_PATH_CFG1, 0x64}, -{WCD9360_CDC_RX0_RX_PATH_CFG2, 0x80}, -{WCD9360_CDC_RX0_RX_VOL_CTL, 0x00}, -{WCD9360_CDC_RX0_RX_PATH_MIX_CTL, 0x04}, -{WCD9360_CDC_RX0_RX_PATH_MIX_CFG, 0x12}, -{WCD9360_CDC_RX0_RX_VOL_MIX_CTL, 0x00}, -{WCD9360_CDC_RX0_RX_PATH_SEC0, 0xFC}, -{WCD9360_CDC_RX0_RX_PATH_SEC1, 0x08}, -{WCD9360_CDC_RX0_RX_PATH_SEC2, 0x00}, -{WCD9360_CDC_RX0_RX_PATH_SEC3, 0x00}, -{WCD9360_CDC_RX0_RX_PATH_SEC5, 0x00}, -{WCD9360_CDC_RX0_RX_PATH_SEC6, 0x00}, -{WCD9360_CDC_RX0_RX_PATH_SEC7, 0x00}, -{WCD9360_CDC_RX0_RX_PATH_MIX_SEC0, 0x08}, -{WCD9360_CDC_RX0_RX_PATH_MIX_SEC1, 0x00}, -{WCD9360_CDC_RX0_RX_PATH_DSMDEM_CTL, 0x00}, -{WCD9360_CDC_RX9_RX_PATH_CTL, 0x04}, -{WCD9360_CDC_RX9_RX_PATH_CFG0, 0x00}, -{WCD9360_CDC_RX9_RX_PATH_CFG1, 0x64}, -{WCD9360_CDC_RX9_RX_PATH_CFG2, 0x80}, -{WCD9360_CDC_RX9_RX_VOL_CTL, 0x00}, -{WCD9360_CDC_RX9_RX_PATH_MIX_CTL, 0x04}, -{WCD9360_CDC_RX9_RX_PATH_MIX_CFG, 0x12}, -{WCD9360_CDC_RX9_RX_VOL_MIX_CTL, 0x00}, -{WCD9360_CDC_RX9_RX_PATH_SEC0, 0xFC}, -{WCD9360_CDC_RX9_RX_PATH_SEC1, 0x08}, -{WCD9360_CDC_RX9_RX_PATH_SEC2, 0x00}, -{WCD9360_CDC_RX9_RX_PATH_SEC3, 0x00}, -{WCD9360_CDC_RX9_RX_PATH_SEC5, 0x00}, -{WCD9360_CDC_RX9_RX_PATH_SEC6, 0x00}, -{WCD9360_CDC_RX9_RX_PATH_SEC7, 0x00}, -{WCD9360_CDC_RX9_RX_PATH_MIX_SEC0, 0x08}, -{WCD9360_CDC_RX9_RX_PATH_MIX_SEC1, 0x00}, -{WCD9360_CDC_RX9_RX_PATH_DSMDEM_CTL, 0x00}, -{WCD9360_CDC_RX7_RX_PATH_CTL, 0x04}, -{WCD9360_CDC_RX7_RX_PATH_CFG0, 0x00}, -{WCD9360_CDC_RX7_RX_PATH_CFG1, 0x64}, -{WCD9360_CDC_RX7_RX_PATH_CFG2, 0x80}, -{WCD9360_CDC_RX7_RX_VOL_CTL, 0x00}, -{WCD9360_CDC_RX7_RX_PATH_MIX_CTL, 0x04}, -{WCD9360_CDC_RX7_RX_PATH_MIX_CFG, 0x12}, -{WCD9360_CDC_RX7_RX_VOL_MIX_CTL, 0x00}, -{WCD9360_CDC_RX7_RX_PATH_SEC0, 0x04}, -{WCD9360_CDC_RX7_RX_PATH_SEC1, 0x08}, -{WCD9360_CDC_RX7_RX_PATH_SEC2, 0x00}, -{WCD9360_CDC_RX7_RX_PATH_SEC3, 0x00}, -{WCD9360_CDC_RX7_RX_PATH_SEC5, 0x00}, -{WCD9360_CDC_RX7_RX_PATH_SEC6, 0x00}, -{WCD9360_CDC_RX7_RX_PATH_SEC7, 0x00}, -{WCD9360_CDC_RX7_RX_PATH_MIX_SEC0, 0x08}, -{WCD9360_CDC_RX7_RX_PATH_MIX_SEC1, 0x00}, -{WCD9360_CDC_RX7_RX_PATH_DSMDEM_CTL, 0x00}, -{WCD9360_CDC_RX8_RX_PATH_CTL, 0x04}, -{WCD9360_CDC_RX8_RX_PATH_CFG0, 0x00}, -{WCD9360_CDC_RX8_RX_PATH_CFG1, 0x64}, -{WCD9360_CDC_RX8_RX_PATH_CFG2, 0x80}, -{WCD9360_CDC_RX8_RX_VOL_CTL, 0x00}, -{WCD9360_CDC_RX8_RX_PATH_MIX_CTL, 0x04}, -{WCD9360_CDC_RX8_RX_PATH_MIX_CFG, 0x12}, -{WCD9360_CDC_RX8_RX_VOL_MIX_CTL, 0x00}, -{WCD9360_CDC_RX8_RX_PATH_SEC0, 0x04}, -{WCD9360_CDC_RX8_RX_PATH_SEC1, 0x08}, -{WCD9360_CDC_RX8_RX_PATH_SEC2, 0x00}, -{WCD9360_CDC_RX8_RX_PATH_SEC3, 0x00}, -{WCD9360_CDC_RX8_RX_PATH_SEC5, 0x00}, -{WCD9360_CDC_RX8_RX_PATH_SEC6, 0x00}, -{WCD9360_CDC_RX8_RX_PATH_SEC7, 0x00}, -{WCD9360_CDC_RX8_RX_PATH_MIX_SEC0, 0x08}, -{WCD9360_CDC_RX8_RX_PATH_MIX_SEC1, 0x00}, -{WCD9360_CDC_RX8_RX_PATH_DSMDEM_CTL, 0x00}, -{WCD9360_PAGE12_PAGE_REGISTER, 0x00}, -{WCD9360_CDC_BOOST0_BOOST_PATH_CTL, 0x00}, -{WCD9360_CDC_BOOST0_BOOST_CTL, 0xD0}, -{WCD9360_CDC_BOOST0_BOOST_CFG1, 0x89}, -{WCD9360_CDC_BOOST0_BOOST_CFG2, 0x04}, -{WCD9360_CDC_BOOST1_BOOST_PATH_CTL, 0x00}, -{WCD9360_CDC_BOOST1_BOOST_CTL, 0xD0}, -{WCD9360_CDC_BOOST1_BOOST_CFG1, 0x89}, -{WCD9360_CDC_BOOST1_BOOST_CFG2, 0x04}, -{WCD9360_MIXING_ASRC2_CLK_RST_CTL, 0x00}, -{WCD9360_MIXING_ASRC2_CTL0, 0x00}, -{WCD9360_MIXING_ASRC2_CTL1, 0x00}, -{WCD9360_MIXING_ASRC2_FIFO_CTL, 0xA8}, -{WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_LSB, 0x00}, -{WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_MSB, 0x00}, -{WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_LSB, 0x00}, -{WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_MSB, 0x00}, -{WCD9360_MIXING_ASRC2_STATUS_FIFO, 0x00}, -{WCD9360_MIXING_ASRC3_CLK_RST_CTL, 0x00}, -{WCD9360_MIXING_ASRC3_CTL0, 0x00}, -{WCD9360_MIXING_ASRC3_CTL1, 0x00}, -{WCD9360_MIXING_ASRC3_FIFO_CTL, 0xA8}, -{WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_LSB, 0x00}, -{WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_MSB, 0x00}, -{WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_LSB, 0x00}, -{WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_MSB, 0x00}, -{WCD9360_MIXING_ASRC3_STATUS_FIFO, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_WR_DATA_0, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_WR_DATA_1, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_WR_DATA_2, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_WR_DATA_3, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_WR_ADDR_0, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_WR_ADDR_1, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_WR_ADDR_2, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_WR_ADDR_3, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_RD_ADDR_0, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_RD_ADDR_1, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_RD_ADDR_2, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_RD_ADDR_3, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_RD_DATA_0, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_RD_DATA_1, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_RD_DATA_2, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_RD_DATA_3, 0x00}, -{WCD9360_SWR_AHB_BRIDGE_ACCESS_CFG, 0x0F}, -{WCD9360_SWR_AHB_BRIDGE_ACCESS_STATUS, 0x03}, -{WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL, 0x04}, -{WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1, 0x00}, -{WCD9360_SIDETONE_ASRC0_CLK_RST_CTL, 0x00}, -{WCD9360_SIDETONE_ASRC0_CTL0, 0x00}, -{WCD9360_SIDETONE_ASRC0_CTL1, 0x00}, -{WCD9360_SIDETONE_ASRC0_FIFO_CTL, 0xA8}, -{WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00}, -{WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00}, -{WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00}, -{WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00}, -{WCD9360_SIDETONE_ASRC0_STATUS_FIFO, 0x00}, -{WCD9360_EC_REF_HQ0_EC_REF_HQ_PATH_CTL, 0x00}, -{WCD9360_EC_REF_HQ0_EC_REF_HQ_CFG0, 0x01}, -{WCD9360_EC_REF_HQ1_EC_REF_HQ_PATH_CTL, 0x00}, -{WCD9360_EC_REF_HQ1_EC_REF_HQ_CFG0, 0x01}, -{WCD9360_EC_ASRC0_CLK_RST_CTL, 0x00}, -{WCD9360_EC_ASRC0_CTL0, 0x00}, -{WCD9360_EC_ASRC0_CTL1, 0x00}, -{WCD9360_EC_ASRC0_FIFO_CTL, 0xA8}, -{WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00}, -{WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00}, -{WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00}, -{WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00}, -{WCD9360_EC_ASRC0_STATUS_FIFO, 0x00}, -{WCD9360_EC_ASRC1_CLK_RST_CTL, 0x00}, -{WCD9360_EC_ASRC1_CTL0, 0x00}, -{WCD9360_EC_ASRC1_CTL1, 0x00}, -{WCD9360_EC_ASRC1_FIFO_CTL, 0xA8}, -{WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00}, -{WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00}, -{WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00}, -{WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00}, -{WCD9360_EC_ASRC1_STATUS_FIFO, 0x00}, -{WCD9360_PAGE13_PAGE_REGISTER, 0x00}, -{WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0, 0x00}, -{WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1, 0x00}, -{WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0, 0x00}, -{WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1, 0x00}, -{WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0, 0x00}, -{WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1, 0x00}, -{WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0, 0x00}, -{WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1, 0x00}, -{WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG0, 0x00}, -{WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG1, 0x00}, -{WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG2, 0x00}, -{WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG3, 0x00}, -{WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG4, 0x00}, -{WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0x00}, -{WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 0x00}, -{WCD9360_CDC_RX_INP_MUX_ANC_CFG0, 0x00}, -{WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 0x00}, -{WCD9360_CDC_RX_INP_MUX_EC_REF_HQ_CFG0, 0x00}, -{WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0x00}, -{WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0x00}, -{WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0x00}, -{WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0x00}, -{WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0x00}, -{WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0x00}, -{WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0x00}, -{WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0x00}, -{WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0x00}, -{WCD9360_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0x00}, -{WCD9360_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0x00}, -{WCD9360_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0x00}, -{WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0x00}, -{WCD9360_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0x00}, -{WCD9360_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0x00}, -{WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0x00}, -{WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1, 0x00}, -{WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2, 0x00}, -{WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3, 0x00}, -{WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0, 0x00}, -{WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1, 0x00}, -{WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2, 0x00}, -{WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3, 0x00}, -{WCD9360_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x00}, -{WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00}, -{WCD9360_CDC_CLK_RST_CTRL_SWR_CONTROL, 0x00}, -{WCD9360_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL, 0x0A}, -{WCD9360_CDC_PROX_DETECT_PROX_CTL, 0x08}, -{WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD0, 0x00}, -{WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD1, 0x4B}, -{WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB, 0x00}, -{WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB, 0x00}, -{WCD9360_CDC_PROX_DETECT_PROX_STATUS, 0x00}, -{WCD9360_CDC_PROX_DETECT_PROX_TEST_CTRL, 0x00}, -{WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB, 0x00}, -{WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB, 0x00}, -{WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD, 0x00}, -{WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD, 0x00}, -{WCD9360_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT, 0x00}, -{WCD9360_CDC_SIDETONE_IIR0_IIR_PATH_CTL, 0x00}, -{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0x00}, -{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0x00}, -{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0x00}, -{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0x00}, -{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL, 0x00}, -{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL, 0x00}, -{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL, 0x00}, -{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL, 0x00}, -{WCD9360_CDC_SIDETONE_IIR0_IIR_CTL, 0x40}, -{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL, 0x00}, -{WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, 0x00}, -{WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL, 0x00}, -{WCD9360_CDC_TOP_TOP_CFG0, 0x00}, -{WCD9360_CDC_TOP_TOP_CFG1, 0x00}, -{WCD9360_CDC_TOP_TOP_CFG7, 0x00}, -{WCD9360_CDC_TOP_EAR_COMP_WR_LSB, 0x00}, -{WCD9360_CDC_TOP_EAR_COMP_WR_MSB, 0x00}, -{WCD9360_CDC_TOP_EAR_COMP_LUT, 0x00}, -{WCD9360_CDC_TOP_EAR_COMP_RD_LSB, 0x00}, -{WCD9360_CDC_TOP_EAR_COMP_RD_MSB, 0x00}, -{WCD9360_CDC_TOP_TOP_DEBUG, 0x00}, -{WCD9360_PAGE80_PAGE_REGISTER, 0x00}, -{WCD9360_CODEC_CPR_WR_DATA_0, 0x00}, -{WCD9360_CODEC_CPR_WR_DATA_1, 0x00}, -{WCD9360_CODEC_CPR_WR_DATA_2, 0x00}, -{WCD9360_CODEC_CPR_WR_DATA_3, 0x00}, -{WCD9360_CODEC_CPR_WR_ADDR_0, 0x00}, -{WCD9360_CODEC_CPR_WR_ADDR_1, 0x00}, -{WCD9360_CODEC_CPR_WR_ADDR_2, 0x00}, -{WCD9360_CODEC_CPR_WR_ADDR_3, 0x00}, -{WCD9360_CODEC_CPR_RD_ADDR_0, 0x00}, -{WCD9360_CODEC_CPR_RD_ADDR_1, 0x00}, -{WCD9360_CODEC_CPR_RD_ADDR_2, 0x00}, -{WCD9360_CODEC_CPR_RD_ADDR_3, 0x00}, -{WCD9360_CODEC_CPR_RD_DATA_0, 0x00}, -{WCD9360_CODEC_CPR_RD_DATA_1, 0x00}, -{WCD9360_CODEC_CPR_RD_DATA_2, 0x00}, -{WCD9360_CODEC_CPR_RD_DATA_3, 0x00}, -{WCD9360_CODEC_CPR_ACCESS_CFG, 0x0F}, -{WCD9360_CODEC_CPR_ACCESS_STATUS, 0x03}, -{WCD9360_CODEC_CPR_NOM_CX_VDD, 0xB4}, -{WCD9360_CODEC_CPR_SVS_CX_VDD, 0x7C}, -{WCD9360_CODEC_CPR_SVS2_CX_VDD, 0x58}, -{WCD9360_CODEC_CPR_NOM_MX_VDD, 0xB4}, -{WCD9360_CODEC_CPR_SVS_MX_VDD, 0xB4}, -{WCD9360_CODEC_CPR_SVS2_MX_VDD, 0xA0}, -{WCD9360_CODEC_CPR_SVS2_MIN_CX_VDD, 0x2C}, -{WCD9360_CODEC_CPR_MAX_SVS2_STEP, 0x08}, -{WCD9360_CODEC_CPR_CTL, 0x00}, -{WCD9360_CODEC_CPR_SW_MODECHNG_STATUS, 0x00}, -{WCD9360_CODEC_CPR_SW_MODECHNG_START, 0x00}, -{WCD9360_CODEC_CPR_CPR_STATUS, 0x00}, -{WCD9360_PAGE128_PAGE_REGISTER, 0x00}, -{WCD9360_TLMM_JTCK_PINCFG, 0x00}, -{WCD9360_TLMM_INTR1_PINCFG, 0x00}, -{WCD9360_TLMM_INTR2_PINCFG, 0x00}, -{WCD9360_TLMM_SWR_DATA_PINCFG, 0x00}, -{WCD9360_TLMM_SWR_CLK_PINCFG, 0x00}, -{WCD9360_TLMM_SLIMBUS_DATA1_PINCFG, 0x00}, -{WCD9360_TLMM_SLIMBUS_DATA2_PINCFG, 0x00}, -{WCD9360_TLMM_SLIMBUS_CLK_PINCFG, 0x00}, -{WCD9360_TLMM_I2C_CLK_PINCFG, 0x00}, -{WCD9360_TLMM_I2C_DATA_PINCFG, 0x00}, -{WCD9360_TLMM_I2S_0_RX_PINCFG, 0x00}, -{WCD9360_TLMM_I2S_0_TX_PINCFG, 0x00}, -{WCD9360_TLMM_I2S_0_SCK_PINCFG, 0x00}, -{WCD9360_TLMM_I2S_0_WS_PINCFG, 0x00}, -{WCD9360_TLMM_I2S_1_RX_PINCFG, 0x00}, -{WCD9360_TLMM_I2S_1_TX_PINCFG, 0x00}, -{WCD9360_TLMM_I2S_1_SCK_PINCFG, 0x00}, -{WCD9360_TLMM_I2S_1_WS_PINCFG, 0x00}, -{WCD9360_TLMM_DMIC1_CLK_PINCFG, 0x00}, -{WCD9360_TLMM_DMIC1_DATA_PINCFG, 0x00}, -{WCD9360_TLMM_DMIC2_CLK_PINCFG, 0x00}, -{WCD9360_TLMM_DMIC2_DATA_PINCFG, 0x00}, -{WCD9360_TLMM_GPIO1_PINCFG, 0x00}, -{WCD9360_TLMM_GPIO2_PINCFG, 0x00}, -{WCD9360_TLMM_GPIO3_PINCFG, 0x00}, -{WCD9360_TLMM_GPIO4_PINCFG, 0x00}, -{WCD9360_TLMM_SPI_S_CSN_PINCFG, 0x00}, -{WCD9360_TLMM_SPI_S_CLK_PINCFG, 0x00}, -{WCD9360_TLMM_SPI_S_DOUT_PINCFG, 0x00}, -{WCD9360_TLMM_SPI_S_DIN_PINCFG, 0x00}, -{WCD9360_TLMM_GPIO0_PINCFG, 0x00}, -{WCD9360_TLMM_DMIC3_CLK_PINCFG, 0x00}, -{WCD9360_TLMM_DMIC3_DATA_PINCFG, 0x00}, -{WCD9360_TLMM_DMIC4_CLK_PINCFG, 0x00}, -{WCD9360_TLMM_DMIC4_DATA_PINCFG, 0x00}, -{WCD9360_TEST_DEBUG_PIN_CTL_OE_0, 0x00}, -{WCD9360_TEST_DEBUG_PIN_CTL_OE_1, 0x00}, -{WCD9360_TEST_DEBUG_PIN_CTL_OE_2, 0x00}, -{WCD9360_TEST_DEBUG_PIN_CTL_OE_3, 0x00}, -{WCD9360_TEST_DEBUG_PIN_CTL_OE_4, 0x00}, -{WCD9360_TEST_DEBUG_PIN_CTL_DATA_0, 0x00}, -{WCD9360_TEST_DEBUG_PIN_CTL_DATA_1, 0x00}, -{WCD9360_TEST_DEBUG_PIN_CTL_DATA_2, 0x00}, -{WCD9360_TEST_DEBUG_PIN_CTL_DATA_3, 0x00}, -{WCD9360_TEST_DEBUG_PIN_CTL_DATA_4, 0x00}, -{WCD9360_TEST_DEBUG_PAD_DRVCTL_0, 0x00}, -{WCD9360_TEST_DEBUG_PAD_DRVCTL_1, 0x00}, -{WCD9360_TEST_DEBUG_PIN_STATUS, 0x00}, -{WCD9360_TEST_DEBUG_NPL_DLY_TEST_1, 0x10}, -{WCD9360_TEST_DEBUG_NPL_DLY_TEST_2, 0x60}, -{WCD9360_TEST_DEBUG_MEM_CTRL, 0x00}, -{WCD9360_TEST_DEBUG_DEBUG_BUS_SEL, 0x00}, -{WCD9360_TEST_DEBUG_DEBUG_JTAG, 0x00}, -{WCD9360_TEST_DEBUG_DEBUG_EN_1, 0x00}, -{WCD9360_TEST_DEBUG_DEBUG_EN_2, 0x00}, -{WCD9360_TEST_DEBUG_DEBUG_EN_3, 0x00}, -{WCD9360_TEST_DEBUG_DEBUG_EN_4, 0x00}, -{WCD9360_TEST_DEBUG_DEBUG_EN_5, 0x00}, -{WCD9360_TEST_DEBUG_ANA_DTEST_DIR, 0x00}, -{WCD9360_TEST_DEBUG_PAD_INP_DISABLE_0, 0x00}, -{WCD9360_TEST_DEBUG_PAD_INP_DISABLE_1, 0x00}, -{WCD9360_TEST_DEBUG_PAD_INP_DISABLE_2, 0x00}, -{WCD9360_TEST_DEBUG_PAD_INP_DISABLE_3, 0x00}, -{WCD9360_TEST_DEBUG_PAD_INP_DISABLE_4, 0x00}, -{WCD9360_TEST_DEBUG_SYSMEM_CTRL, 0x00}, -{WCD9360_TEST_DEBUG_LVAL_NOM_LOW, 0x96}, -{WCD9360_TEST_DEBUG_LVAL_NOM_HIGH, 0x00}, -{WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_LOW, 0x53}, -{WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_HIGH, 0x00}, -{WCD9360_TEST_DEBUG_SPI_SLAVE_CHAR, 0x00}, -{WCD9360_TEST_DEBUG_CODEC_DIAGS, 0x00}, -}; - - -const u8 wcd9360_page0_reg_access[WCD9360_PAGE_SIZE] = { -[WCD9360_REG(WCD9360_PAGE0_PAGE_REGISTER)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_RPM_CLK_BYPASS)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_RPM_CLK_GATE)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_RPM_CLK_MCLK_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_RPM_CLK_MCLK2_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_RPM_I2S_DSD_CLK_SEL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_RPM_RST_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE0)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE1)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE2)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE3)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_EFUSE_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_EFUSE_TEST0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_EFUSE_TEST1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_EFUSE_STATUS)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_I2C_ACTIVE)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_ALT_FUNC_EN)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_GPIO_CTL_OE)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_GPIO_CTL_DATA)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_RX0_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_RX1_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_RX2_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_RX3_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_RX4_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_RX5_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_RX6_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_RX7_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_SB_TX0_INP_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_SB_TX1_INP_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_SB_TX2_INP_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_SB_TX3_INP_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_SB_TX4_INP_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_SB_TX5_INP_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_SB_TX6_INP_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_SB_TX7_INP_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_SB_TX8_INP_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_SB_TX9_INP_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_SB_TX10_INP_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_SB_TX11_INP_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_SB_TX12_INP_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_SB_TX13_INP_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_SB_TX14_INP_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_SB_TX15_INP_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_TX0_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_TX0_CFG2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_TX1_0_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_TX1_1_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_DATA_HUB_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_1_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_CTL2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_1_CTL2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_CLKSRC_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_COMMON_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_CTL2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_CH_RX)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_CH_TX)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_STRETCH)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DATA_HUB_I2S_RESET_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_RDMA_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_RDMA_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_RDMA_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_RDMA_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_RDMA_CTL_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_RDMA_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_RDMA_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_RDMA_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_RDMA_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_RDMA_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_RDMA_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_RDMA_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_RDMA_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_RDMA_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_RDMA_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_RDMA4_PRT_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_RDMA_SBTX0_7_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_RDMA_SBTX8_10_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_WDMA_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_WDMA_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_WDMA_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_WDMA_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_WDMA_CTL_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_4_5_CFG_WDMA_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_4_5_CFG_WDMA_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_4_5_CFG_WDMA_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_4_5_CFG_WDMA_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_4_5_CFG_WDMA_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_WDMA_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_WDMA_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_WDMA_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_WDMA_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_WDMA_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_WDMA_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_WDMA_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_WDMA_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_WDMA_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_WDMA_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_WDMA0_PRT_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_WDMA3_PRT_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_WDMA4_PRT0_3_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DMA_WDMA4_PRT4_7_CFG)] = WCD9360_RW, -}; - -const u8 wcd9360_page1_reg_access[WCD9360_PAGE_SIZE] = { -[WCD9360_REG(WCD9360_PAGE1_PAGE_REGISTER)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_8)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_9)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_L_VAL_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_L_VAL_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_DSM_FRAC_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_DSM_FRAC_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_CONFIG_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_CONFIG_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_CONFIG_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_CONFIG_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_CONFIG_CTL_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_FREQ_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_FREQ_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_FREQ_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_FREQ_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_SSC_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_SSC_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_SSC_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_SSC_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_FLL_MODE)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_FLL_STATUS_0)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_FLL_STATUS_1)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_FLL_STATUS_2)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_FLL_STATUS_3)] = WCD9360_RO, -[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_8)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_9)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_L_VAL_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_L_VAL_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_DSM_FRAC_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_DSM_FRAC_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_CONFIG_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_CONFIG_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_CONFIG_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_CONFIG_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_CONFIG_CTL_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_FREQ_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_FREQ_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_FREQ_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_FREQ_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_SSC_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_SSC_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_SSC_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_SSC_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_FLL_MODE)] = WCD9360_RW, -[WCD9360_REG(WCD9360_I2S_FLL_STATUS_0)] = WCD9360_RO, -[WCD9360_REG(WCD9360_I2S_FLL_STATUS_1)] = WCD9360_RO, -[WCD9360_REG(WCD9360_I2S_FLL_STATUS_2)] = WCD9360_RO, -[WCD9360_REG(WCD9360_I2S_FLL_STATUS_3)] = WCD9360_RO, -}; - -const u8 wcd9360_page2_reg_access[WCD9360_PAGE_SIZE] = { -[WCD9360_REG(WCD9360_PAGE2_PAGE_REGISTER)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_CPE_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_PWR_CPEFLL_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_US_BUF_INT_PERIOD)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_SVA_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_US_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_MAD_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_CPAR_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_DMIC0_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_DMIC1_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_DMIC2_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_DMIC_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_CPAR_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_WDOG_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_BACKUP_INT)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_STATUS)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_CPE_OCD_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_MASK_1A)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_MASK_1B)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0A)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0B)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1A)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1B)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0A)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0B)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1A)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1B)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_DMIC3_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_WDOG_RESET)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_MCLK_PRG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_0)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_1)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_2)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_3)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_4)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_5)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_6)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_7)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_8)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_9)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_10)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_11)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_12)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_13)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_14)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_15)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_0)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_1)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_2)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_3)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_4)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_5)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_6)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_7)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_8)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_9)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_10)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_11)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_12)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_13)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_14)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_15)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_LPASS_ARB_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_0)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_1)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_MAIN_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_MAIN_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_8)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_IIR_CTL_PTR)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_IIR_CTL_VAL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_8)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_BEACON_IIR_CTL_PTR)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_BEACON_IIR_CTL_VAL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_INP_SEL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SOC_MAD_MAD2_INP_SEL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_CTRL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_STATUS)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_FS)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_IN_SEL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT0)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT1)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT2)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT3)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT4)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT5)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT6)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT7)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT8)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT9)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT10)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT11)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT12)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT13)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT14)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT15)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT0)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT1)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT2)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT3)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT4)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT5)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT6)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT7)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT8)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT9)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT10)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT11)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT12)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT13)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT14)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT15)] = WCD9360_RO, -}; - -const u8 wcd9360_page4_reg_access[WCD9360_PAGE_SIZE] = { -[WCD9360_REG(WCD9360_PAGE4_PAGE_REGISTER)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_CLR_COMMIT)] = WCD9360_WO, -[WCD9360_REG(WCD9360_INTR_PIN1_MASK0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_PIN1_MASK1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_PIN1_MASK2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_PIN1_MASK3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_PIN1_STATUS0)] = WCD9360_RO, -[WCD9360_REG(WCD9360_INTR_PIN1_STATUS1)] = WCD9360_RO, -[WCD9360_REG(WCD9360_INTR_PIN1_STATUS2)] = WCD9360_RO, -[WCD9360_REG(WCD9360_INTR_PIN1_STATUS3)] = WCD9360_RO, -[WCD9360_REG(WCD9360_INTR_PIN1_CLEAR0)] = WCD9360_WO, -[WCD9360_REG(WCD9360_INTR_PIN1_CLEAR1)] = WCD9360_WO, -[WCD9360_REG(WCD9360_INTR_PIN1_CLEAR2)] = WCD9360_WO, -[WCD9360_REG(WCD9360_INTR_PIN1_CLEAR3)] = WCD9360_WO, -[WCD9360_REG(WCD9360_INTR_PIN2_MASK3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_PIN2_STATUS3)] = WCD9360_RO, -[WCD9360_REG(WCD9360_INTR_PIN2_CLEAR3)] = WCD9360_WO, -[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_MASK2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_MASK3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_STATUS2)] = WCD9360_RO, -[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_STATUS3)] = WCD9360_RO, -[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_CLEAR2)] = WCD9360_WO, -[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_CLEAR3)] = WCD9360_WO, -[WCD9360_REG(WCD9360_INTR_LEVEL0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_LEVEL1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_LEVEL2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_LEVEL3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_BYPASS0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_BYPASS1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_BYPASS2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_BYPASS3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_SET0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_SET1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_SET2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_SET3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_CODEC_MISC_MASK)] = WCD9360_RW, -[WCD9360_REG(WCD9360_INTR_CODEC_MISC_STATUS)] = WCD9360_RO, -[WCD9360_REG(WCD9360_INTR_CODEC_MISC_CLEAR)] = WCD9360_WO, -}; - -const u8 wcd9360_page6_reg_access[WCD9360_PAGE_SIZE] = { -[WCD9360_REG(WCD9360_ANA_PAGE_REGISTER)] = WCD9360_RW, -[WCD9360_REG(WCD9360_ANA_BIAS)] = WCD9360_RW, -[WCD9360_REG(WCD9360_ANA_AMIC_INPUT_SWITCH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_ANA_RCO)] = WCD9360_RW, -[WCD9360_REG(WCD9360_ANA_BUCK_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_ANA_BUCK_STATUS)] = WCD9360_RO, -[WCD9360_REG(WCD9360_ANA_EAR)] = WCD9360_RW, -[WCD9360_REG(WCD9360_ANA_MAD_SETUP)] = WCD9360_RW, -[WCD9360_REG(WCD9360_ANA_AMIC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_ANA_AMIC2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_ANA_AMIC3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_ANA_AMIC4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_ANA_MICB1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_ANA_MICB2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_ANA_MICB3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_ANA_MICB4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_BIAS_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_BIAS_VBG_FINE_ADJ)] = WCD9360_RW, -[WCD9360_REG(WCD9360_RCO_CTRL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_RCO_CTRL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_RCO_CAL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_RCO_CAL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_RCO_CAL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_RCO_TEST_CTRL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_RCO_CAL_OUT_1)] = WCD9360_RO, -[WCD9360_REG(WCD9360_RCO_CAL_OUT_2)] = WCD9360_RO, -[WCD9360_REG(WCD9360_RCO_CAL_OUT_3)] = WCD9360_RO, -[WCD9360_REG(WCD9360_RCO_CAL_OUT_4)] = WCD9360_RO, -[WCD9360_REG(WCD9360_RCO_CAL_OUT_5)] = WCD9360_RO, -[WCD9360_REG(WCD9360_SIDO_MODE_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_MODE_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_MODE_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_MODE_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_VCL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_VCL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_VCL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_CCL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_CCL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_CCL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_CCL_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_CCL_5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_CCL_6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_CCL_7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_CCL_8)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_CCL_9)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_CCL_10)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_FILTER_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_FILTER_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_DRIVER_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_DRIVER_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_DRIVER_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_CAL_CODE_EXT_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_CAL_CODE_EXT_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_CAL_CODE_OUT_1)] = WCD9360_RO, -[WCD9360_REG(WCD9360_SIDO_CAL_CODE_OUT_2)] = WCD9360_RO, -[WCD9360_REG(WCD9360_SIDO_TEST_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_TEST_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_LDOH_MODE)] = WCD9360_RW, -[WCD9360_REG(WCD9360_LDOH_BIAS)] = WCD9360_RW, -[WCD9360_REG(WCD9360_LDOH_STB_LOADS)] = WCD9360_RW, -[WCD9360_REG(WCD9360_LDOH_SLOWRAMP)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MICB1_TEST_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MICB1_TEST_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MICB1_TEST_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MICB2_TEST_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MICB2_TEST_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MICB2_TEST_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MICB3_TEST_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MICB3_TEST_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MICB3_TEST_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MICB4_TEST_CTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MICB4_TEST_CTL_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MICB4_TEST_CTL_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_COM_ADC_VCM)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_COM_BIAS_ATEST)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_COM_ADC_INT1_IB)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_COM_ADC_INT2_IB)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_COM_TXFE_DIV_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_COM_TXFE_DIV_START)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_COM_TXFE_DIV_STOP_9P6M)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_COM_TXFE_DIV_STOP_12P288M)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_1_2_TEST_EN)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_1_2_ADC_IB)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_1_2_ATEST_REFCTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_1_2_TEST_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_1_2_TEST_BLK_EN)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_1_2_TXFE_CLKDIV)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_1_2_SAR1_ERR)] = WCD9360_RO, -[WCD9360_REG(WCD9360_TX_1_2_SAR2_ERR)] = WCD9360_RO, -[WCD9360_REG(WCD9360_TX_3_4_TEST_EN)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_3_4_ADC_IB)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_3_4_ATEST_REFCTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_3_4_TEST_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_3_4_TEST_BLK_EN)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_3_4_TXFE_CLKDIV)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TX_3_4_SAR1_ERR)] = WCD9360_RO, -[WCD9360_REG(WCD9360_TX_3_4_SAR2_ERR)] = WCD9360_RO, -[WCD9360_REG(WCD9360_RX_RX_EAR_BIAS_CON_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_RX_RX_EAR_BIAS_CON_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_RX_RX_AUX_BIAS_CON_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_RX_RX_AUX_BIAS_CON_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_RX_RX_BIAS_ATEST)] = WCD9360_RW, -[WCD9360_REG(WCD9360_RX_RXTOP_RESERVED)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EAR_EAR_EN_REG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EAR_EAR_PA_CON)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EAR_EAR_SP_CON)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EAR_EAR_DAC_CON)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EAR_EAR_CNP_FSM_CON)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EAR_DAC_CTL_TEST)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EAR_STATUS_REG)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EAR_EAR_COMPANDER_CON)] = WCD9360_RW, -}; - -const u8 wcd9360_page7_reg_access[WCD9360_PAGE_SIZE] = { -[WCD9360_REG(WCD9360_ANA_NEW_PAGE_REGISTER)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_PLL_ENABLES)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_PLL_PRESET)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_PLL_STATUS)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CLK_SYS_MCLK_PRG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_MCLK2_PRG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_MCLK_MISC)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_VOUT_A_STARTUP)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_VOUT_D_STARTUP)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_VOUT_D_FREQ1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_VOUT_D_FREQ2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_AUX_ANA_EAR)] = WCD9360_RW, -[WCD9360_REG(WCD9360_LDORXTX_LDORXTX)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DIE_CRACK_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DIE_CRACK_OUT)] = WCD9360_RO, -[WCD9360_REG(WCD9360_LOOP_BACK_EN)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_POST_DIV_REG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_POST_DIV_REG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_REF_DIV_REG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_REF_DIV_REG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_FILTER_REG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_FILTER_REG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_PLL_L_VAL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_PLL_M_VAL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_PLL_N_VAL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_TEST_REG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_PFD_CP_DSM_PROG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_VCO_PROG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_TEST_REG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_LDO_LOCK_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_DIG_LOCK_DET_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_CLK_TEST1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_CLK_TEST2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CLK_SYS_INT_CLK_TEST3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_STATUS)] = WCD9360_RO, -[WCD9360_REG(WCD9360_SIDO_NEW_INT_SPARE_1)] = WCD9360_RO, -[WCD9360_REG(WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_A)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_D)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_INC_WAIT)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_IBLEED_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_INT_DEBUG_CPROVR_TEST)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_CTL_A)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_CTL_D)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_TIMEOUT_PERIOD)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EAR_INT_NEW_EAR_CHOPPER_CON)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EAR_INT_NEW_EAR_DYNAMIC_BIAS)] = WCD9360_RW, -[WCD9360_REG(WCD9360_AUX_INT_AUX_EN_REG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_AUX_INT_AUX_PA_CON)] = WCD9360_RW, -[WCD9360_REG(WCD9360_AUX_INT_AUX_SP_CON)] = WCD9360_RW, -[WCD9360_REG(WCD9360_AUX_INT_AUX_DAC_CON)] = WCD9360_RW, -[WCD9360_REG(WCD9360_AUX_INT_AUX_CNP_FSM_CON)] = WCD9360_RW, -[WCD9360_REG(WCD9360_AUX_INT_AUX_TEST)] = WCD9360_RW, -[WCD9360_REG(WCD9360_AUX_INT_STATUS_REG)] = WCD9360_RO, -[WCD9360_REG(WCD9360_AUX_INT_AUX_MISC)] = WCD9360_RW, -[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_STATUS)] = WCD9360_RO, -[WCD9360_REG(WCD9360_DIE_CRACK_INT_INT1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_DIE_CRACK_INT_INT2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_LOOP_BACK_INT_SPARE)] = WCD9360_RW, -}; - -const u8 wcd9360_page10_reg_access[WCD9360_PAGE_SIZE] = { -[WCD9360_REG(WCD9360_PAGE10_PAGE_REGISTER)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_ANC0_CLK_RESET_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_ANC0_MODE_1_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_ANC0_MODE_2_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_ANC0_FF_SHIFT)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_ANC0_FB_SHIFT)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_ANC0_LPF_FF_A_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_ANC0_LPF_FF_B_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_ANC0_LPF_FB_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_ANC0_SMLPF_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_ANC0_DCFLT_SHIFT_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_ANC0_IIR_ADAPT_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_ANC0_IIR_COEFF_1_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_ANC0_IIR_COEFF_2_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_ANC0_FF_A_GAIN_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_ANC0_FF_B_GAIN_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_ANC0_FB_GAIN_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX0_TX_VOL_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_192_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_192_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX1_TX_VOL_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_192_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_192_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX2_TX_VOL_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_192_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_192_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX3_TX_VOL_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_192_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_192_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX4_TX_VOL_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_192_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_192_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX5_TX_VOL_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_192_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_192_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX6_TX_VOL_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_192_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_192_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX7_TX_VOL_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_192_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_192_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX8_TX_VOL_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_192_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_192_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX9_SPKR_PROT_PATH_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX10_SPKR_PROT_PATH_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX11_SPKR_PROT_PATH_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX12_SPKR_PROT_PATH_CFG0)] = WCD9360_RW, -}; - -const u8 wcd9360_page11_reg_access[WCD9360_PAGE_SIZE] = { -[WCD9360_REG(WCD9360_PAGE11_PAGE_REGISTER)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL6)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL6)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL6)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_CFG2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_VOL_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_MIX_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_MIX_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_VOL_MIX_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_MIX_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_MIX_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_DSMDEM_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_CFG2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_VOL_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_MIX_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_MIX_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_VOL_MIX_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_MIX_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_MIX_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_DSMDEM_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_CFG2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_VOL_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_MIX_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_MIX_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_VOL_MIX_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_MIX_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_MIX_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_DSMDEM_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_CFG2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_VOL_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_MIX_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_MIX_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_VOL_MIX_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_MIX_SEC0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_MIX_SEC1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_DSMDEM_CTL)] = WCD9360_RW, -}; - -const u8 wcd9360_page12_reg_access[WCD9360_PAGE_SIZE] = { -[WCD9360_REG(WCD9360_PAGE12_PAGE_REGISTER)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_BOOST0_BOOST_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_BOOST0_BOOST_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_BOOST0_BOOST_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_BOOST0_BOOST_CFG2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_BOOST1_BOOST_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_BOOST1_BOOST_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_BOOST1_BOOST_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_BOOST1_BOOST_CFG2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MIXING_ASRC2_CLK_RST_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MIXING_ASRC2_CTL0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MIXING_ASRC2_CTL1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MIXING_ASRC2_FIFO_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_LSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_MSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_LSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_MSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_MIXING_ASRC2_STATUS_FIFO)] = WCD9360_RO, -[WCD9360_REG(WCD9360_MIXING_ASRC3_CLK_RST_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MIXING_ASRC3_CTL0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MIXING_ASRC3_CTL1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MIXING_ASRC3_FIFO_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_LSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_MSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_LSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_MSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_MIXING_ASRC3_STATUS_FIFO)] = WCD9360_RO, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_DATA_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_DATA_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_DATA_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_DATA_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_ADDR_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_ADDR_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_ADDR_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_ADDR_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_ADDR_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_ADDR_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_ADDR_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_ADDR_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_DATA_0)] = WCD9360_RO, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_DATA_1)] = WCD9360_RO, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_DATA_2)] = WCD9360_RO, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_DATA_3)] = WCD9360_RO, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_ACCESS_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_ACCESS_STATUS)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDETONE_ASRC0_CLK_RST_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDETONE_ASRC0_CTL0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDETONE_ASRC0_CTL1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDETONE_ASRC0_FIFO_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_SIDETONE_ASRC0_STATUS_FIFO)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EC_REF_HQ0_EC_REF_HQ_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EC_REF_HQ0_EC_REF_HQ_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EC_REF_HQ1_EC_REF_HQ_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EC_REF_HQ1_EC_REF_HQ_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EC_ASRC0_CLK_RST_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EC_ASRC0_CTL0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EC_ASRC0_CTL1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EC_ASRC0_FIFO_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_LSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_MSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_LSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_MSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EC_ASRC0_STATUS_FIFO)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EC_ASRC1_CLK_RST_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EC_ASRC1_CTL0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EC_ASRC1_CTL1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EC_ASRC1_FIFO_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_LSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_MSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_LSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_MSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_EC_ASRC1_STATUS_FIFO)] = WCD9360_RO, -}; - -const u8 wcd9360_page13_reg_access[WCD9360_PAGE_SIZE] = { -[WCD9360_REG(WCD9360_PAGE13_PAGE_REGISTER)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_ANC_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_EC_REF_HQ_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX5_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX6_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX7_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX10_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX11_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_CLK_RST_CTRL_MCLK_CONTROL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_CLK_RST_CTRL_SWR_CONTROL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_STATUS)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_TEST_CTRL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_PATH_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TOP_TOP_CFG0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TOP_TOP_CFG1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TOP_TOP_CFG7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TOP_EAR_COMP_WR_LSB)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TOP_EAR_COMP_WR_MSB)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TOP_EAR_COMP_LUT)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CDC_TOP_EAR_COMP_RD_LSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CDC_TOP_EAR_COMP_RD_MSB)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CDC_TOP_TOP_DEBUG)] = WCD9360_RW, -}; - -const u8 wcd9360_page80_reg_access[WCD9360_PAGE_SIZE] = { -[WCD9360_REG(WCD9360_PAGE80_PAGE_REGISTER)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_WR_DATA_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_WR_DATA_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_WR_DATA_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_WR_DATA_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_WR_ADDR_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_WR_ADDR_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_WR_ADDR_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_WR_ADDR_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_RD_ADDR_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_RD_ADDR_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_RD_ADDR_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_RD_ADDR_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_RD_DATA_0)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CODEC_CPR_RD_DATA_1)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CODEC_CPR_RD_DATA_2)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CODEC_CPR_RD_DATA_3)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CODEC_CPR_ACCESS_CFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_ACCESS_STATUS)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CODEC_CPR_NOM_CX_VDD)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_SVS_CX_VDD)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_SVS2_CX_VDD)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_NOM_MX_VDD)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_SVS_MX_VDD)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_SVS2_MX_VDD)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_SVS2_MIN_CX_VDD)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_MAX_SVS2_STEP)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_CTL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_CODEC_CPR_SW_MODECHNG_STATUS)] = WCD9360_RO, -[WCD9360_REG(WCD9360_CODEC_CPR_SW_MODECHNG_START)] = WCD9360_WO, -[WCD9360_REG(WCD9360_CODEC_CPR_CPR_STATUS)] = WCD9360_RW, -}; - -const u8 wcd9360_page128_reg_access[WCD9360_PAGE_SIZE] = { -[WCD9360_REG(WCD9360_PAGE128_PAGE_REGISTER)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_JTCK_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_INTR1_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_INTR2_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_SWR_DATA_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_SWR_CLK_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_SLIMBUS_DATA1_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_SLIMBUS_DATA2_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_SLIMBUS_CLK_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_I2C_CLK_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_I2C_DATA_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_I2S_0_RX_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_I2S_0_TX_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_I2S_0_SCK_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_I2S_0_WS_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_I2S_1_RX_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_I2S_1_TX_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_I2S_1_SCK_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_I2S_1_WS_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_DMIC1_CLK_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_DMIC1_DATA_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_DMIC2_CLK_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_DMIC2_DATA_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_GPIO1_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_GPIO2_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_GPIO3_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_GPIO4_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_SPI_S_CSN_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_SPI_S_CLK_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_SPI_S_DOUT_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_SPI_S_DIN_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_GPIO0_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_DMIC3_CLK_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_DMIC3_DATA_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_DMIC4_CLK_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TLMM_DMIC4_DATA_PINCFG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_OE_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_OE_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_OE_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_OE_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_OE_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_DATA_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_DATA_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_DATA_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_DATA_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_DATA_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_DRVCTL_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_DRVCTL_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_STATUS)] = WCD9360_RO, -[WCD9360_REG(WCD9360_TEST_DEBUG_NPL_DLY_TEST_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_NPL_DLY_TEST_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_MEM_CTRL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_BUS_SEL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_JTAG)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_EN_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_EN_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_EN_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_EN_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_EN_5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_ANA_DTEST_DIR)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_INP_DISABLE_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_INP_DISABLE_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_INP_DISABLE_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_INP_DISABLE_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_INP_DISABLE_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_SYSMEM_CTRL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_LVAL_NOM_LOW)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_LVAL_NOM_HIGH)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_LOW)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_HIGH)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_SPI_SLAVE_CHAR)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_CODEC_DIAGS)] = WCD9360_RO, -[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_TEST)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_0)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_1)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_2)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_3)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_4)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_5)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_6)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_7)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_8)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_9)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_10)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_11)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_12)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_13)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_14)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_15)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_16)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_17)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_18)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_19)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_20)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_21)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_22)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_23)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_24)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_25)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_26)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_27)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_28)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_29)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_30)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_31)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_RD_CTRL)] = WCD9360_RW, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_RD_7_0)] = WCD9360_RO, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_RD_15_8)] = WCD9360_RO, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_RD_23_16)] = WCD9360_RO, -[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_RD_31_24)] = WCD9360_RO, - -}; - -const u8 * const wcd9360_reg[WCD9360_PAGE_MAX] = { -[WCD9360_PAGE_0] = wcd9360_page0_reg_access, -[WCD9360_PAGE_1] = wcd9360_page1_reg_access, -[WCD9360_PAGE_2] = wcd9360_page2_reg_access, -[WCD9360_PAGE_4] = wcd9360_page4_reg_access, -[WCD9360_PAGE_6] = wcd9360_page6_reg_access, -[WCD9360_PAGE_7] = wcd9360_page7_reg_access, -[WCD9360_PAGE_10] = wcd9360_page10_reg_access, -[WCD9360_PAGE_11] = wcd9360_page11_reg_access, -[WCD9360_PAGE_12] = wcd9360_page12_reg_access, -[WCD9360_PAGE_13] = wcd9360_page13_reg_access, -[WCD9360_PAGE_80] = wcd9360_page80_reg_access, -[WCD9360_PAGE_128] = wcd9360_page128_reg_access, -}; - -#endif diff --git a/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c b/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c deleted file mode 100644 index 37536f86c54c..000000000000 --- a/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c +++ /dev/null @@ -1,1357 +0,0 @@ -/* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "wcd9360.h" -#include "wcd9360-dsp-cntl.h" -#include "../wcd9xxx-irq.h" -#include "../core.h" - -#define WCD_CNTL_DIR_NAME_LEN_MAX 32 -#define WCD_CPE_FLL_MAX_RETRIES 5 -#define WCD_MEM_ENABLE_MAX_RETRIES 20 -#define WCD_DSP_BOOT_TIMEOUT_MS 3000 -#define WCD_SYSFS_ENTRY_MAX_LEN 8 -#define WCD_PROCFS_ENTRY_MAX_LEN 16 -#define WCD_9360_RAMDUMP_START_ADDR 0x20100000 -#define WCD_9360_RAMDUMP_SIZE ((1024 * 1024) - 128) -#define WCD_MISCDEV_CMD_MAX_LEN 2 - -#define WCD_CNTL_MUTEX_LOCK(codec, lock) \ -{ \ - dev_dbg(codec->dev, "%s: mutex_lock(%s)\n", \ - __func__, __stringify_1(lock)); \ - mutex_lock(&lock); \ -} - -#define WCD_CNTL_MUTEX_UNLOCK(codec, lock) \ -{ \ - dev_dbg(codec->dev, "%s: mutex_unlock(%s)\n", \ - __func__, __stringify_1(lock)); \ - mutex_unlock(&lock); \ -} - -enum wcd_mem_type { - WCD_MEM_TYPE_ALWAYS_ON, - WCD_MEM_TYPE_SWITCHABLE, -}; - -struct wcd_cntl_attribute { - struct attribute attr; - ssize_t (*show)(struct wcd_dsp_cntl *cntl, char *buf); - ssize_t (*store)(struct wcd_dsp_cntl *cntl, const char *buf, - ssize_t count); -}; - -#define WCD_CNTL_ATTR(_name, _mode, _show, _store) \ -static struct wcd_cntl_attribute cntl_attr_##_name = { \ - .attr = {.name = __stringify(_name), .mode = _mode}, \ - .show = _show, \ - .store = _store, \ -} - -#define to_wcd_cntl_attr(a) \ - container_of((a), struct wcd_cntl_attribute, attr) - -#define to_wcd_cntl(kobj) \ - container_of((kobj), struct wcd_dsp_cntl, wcd_kobj) - -static u8 mem_enable_values[] = { - 0xFE, 0xFC, 0xF8, 0xF0, - 0xE0, 0xC0, 0x80, 0x00, -}; - -static ssize_t wdsp_boot_show(struct wcd_dsp_cntl *cntl, char *buf) -{ - return snprintf(buf, WCD_SYSFS_ENTRY_MAX_LEN, - "%u", cntl->boot_reqs); -} - -static ssize_t wdsp_boot_store(struct wcd_dsp_cntl *cntl, - const char *buf, ssize_t count) -{ - u32 val; - bool vote; - int ret; - - ret = kstrtou32(buf, 10, &val); - if (ret) { - dev_err(cntl->codec->dev, - "%s: Invalid entry, ret = %d\n", __func__, ret); - return -EINVAL; - } - - if (val > 0) { - cntl->boot_reqs++; - vote = true; - } else { - cntl->boot_reqs--; - vote = false; - } - - if (cntl->m_dev && cntl->m_ops && - cntl->m_ops->vote_for_dsp) - ret = cntl->m_ops->vote_for_dsp(cntl->m_dev, vote); - else - ret = -EINVAL; - - if (ret < 0) - dev_err(cntl->codec->dev, - "%s: failed to %s dsp\n", __func__, - vote ? "enable" : "disable"); - return count; -} - -WCD_CNTL_ATTR(boot, 0660, wdsp_boot_show, wdsp_boot_store); - -static ssize_t wcd_cntl_sysfs_show(struct kobject *kobj, - struct attribute *attr, char *buf) -{ - struct wcd_cntl_attribute *wcd_attr = to_wcd_cntl_attr(attr); - struct wcd_dsp_cntl *cntl = to_wcd_cntl(kobj); - ssize_t ret = -EINVAL; - - if (cntl && wcd_attr->show) - ret = wcd_attr->show(cntl, buf); - - return ret; -} - -static ssize_t wcd_cntl_sysfs_store(struct kobject *kobj, - struct attribute *attr, const char *buf, - size_t count) -{ - struct wcd_cntl_attribute *wcd_attr = to_wcd_cntl_attr(attr); - struct wcd_dsp_cntl *cntl = to_wcd_cntl(kobj); - ssize_t ret = -EINVAL; - - if (cntl && wcd_attr->store) - ret = wcd_attr->store(cntl, buf, count); - - return ret; -} - -static const struct sysfs_ops wcd_cntl_sysfs_ops = { - .show = wcd_cntl_sysfs_show, - .store = wcd_cntl_sysfs_store, -}; - -static struct kobj_type wcd_cntl_ktype = { - .sysfs_ops = &wcd_cntl_sysfs_ops, -}; - -static void wcd_cntl_change_online_state(struct wcd_dsp_cntl *cntl, - u8 online) -{ - struct wdsp_ssr_entry *ssr_entry = &cntl->ssr_entry; - unsigned long ret; - - WCD_CNTL_MUTEX_LOCK(cntl->codec, cntl->ssr_mutex); - ssr_entry->offline = !online; - /* Make sure the write is complete */ - wmb(); - ret = xchg(&ssr_entry->offline_change, 1); - wake_up_interruptible(&ssr_entry->offline_poll_wait); - dev_dbg(cntl->codec->dev, - "%s: requested %u, offline %u offline_change %u, ret = %ldn", - __func__, online, ssr_entry->offline, - ssr_entry->offline_change, ret); - WCD_CNTL_MUTEX_UNLOCK(cntl->codec, cntl->ssr_mutex); -} - -static ssize_t wdsp_ssr_entry_read(struct snd_info_entry *entry, - void *file_priv_data, struct file *file, - char __user *buf, size_t count, loff_t pos) -{ - int len = 0; - char buffer[WCD_PROCFS_ENTRY_MAX_LEN]; - struct wcd_dsp_cntl *cntl; - struct wdsp_ssr_entry *ssr_entry; - ssize_t ret; - u8 offline; - - cntl = (struct wcd_dsp_cntl *) entry->private_data; - if (!cntl) { - pr_err("%s: Invalid private data for SSR procfs entry\n", - __func__); - return -EINVAL; - } - - ssr_entry = &cntl->ssr_entry; - - WCD_CNTL_MUTEX_LOCK(cntl->codec, cntl->ssr_mutex); - offline = ssr_entry->offline; - /* Make sure the read is complete */ - rmb(); - dev_dbg(cntl->codec->dev, "%s: offline = %s\n", __func__, - offline ? "true" : "false"); - len = snprintf(buffer, sizeof(buffer), "%s\n", - offline ? "OFFLINE" : "ONLINE"); - ret = simple_read_from_buffer(buf, count, &pos, buffer, len); - WCD_CNTL_MUTEX_UNLOCK(cntl->codec, cntl->ssr_mutex); - - return ret; -} - -static unsigned int wdsp_ssr_entry_poll(struct snd_info_entry *entry, - void *private_data, struct file *file, - poll_table *wait) -{ - struct wcd_dsp_cntl *cntl; - struct wdsp_ssr_entry *ssr_entry; - unsigned int ret = 0; - - if (!entry || !entry->private_data) { - pr_err("%s: %s is NULL\n", __func__, - (!entry) ? "entry" : "private_data"); - return -EINVAL; - } - - cntl = (struct wcd_dsp_cntl *) entry->private_data; - ssr_entry = &cntl->ssr_entry; - - dev_dbg(cntl->codec->dev, "%s: Poll wait, offline = %u\n", - __func__, ssr_entry->offline); - poll_wait(file, &ssr_entry->offline_poll_wait, wait); - dev_dbg(cntl->codec->dev, "%s: Woken up Poll wait, offline = %u\n", - __func__, ssr_entry->offline); - - WCD_CNTL_MUTEX_LOCK(cntl->codec, cntl->ssr_mutex); - if (xchg(&ssr_entry->offline_change, 0)) - ret = POLLIN | POLLPRI | POLLRDNORM; - dev_dbg(cntl->codec->dev, "%s: ret (%d) from poll_wait\n", - __func__, ret); - WCD_CNTL_MUTEX_UNLOCK(cntl->codec, cntl->ssr_mutex); - - return ret; -} - -static struct snd_info_entry_ops wdsp_ssr_entry_ops = { - .read = wdsp_ssr_entry_read, - .poll = wdsp_ssr_entry_poll, -}; - -static int wcd_cntl_cpe_fll_calibrate(struct wcd_dsp_cntl *cntl) -{ - struct snd_soc_codec *codec = cntl->codec; - int ret = 0, retry = 0; - u8 cal_lsb, cal_msb; - u8 lock_det; - - /* Make sure clocks are gated */ - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPE_CTL, - 0x05, 0x00); - - /* Enable CPE FLL reference clock */ - snd_soc_update_bits(codec, WCD9360_CLK_SYS_MCLK2_PRG1, - 0x80, 0x80); - - snd_soc_update_bits(codec, WCD9360_CPE_FLL_USER_CTL_5, - 0xF3, 0x13); - snd_soc_write(codec, WCD9360_CPE_FLL_L_VAL_CTL_0, 0x50); - - /* Disable CPAR reset and Enable CPAR clk */ - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, - 0x02, 0x02); - - /* Write calibration l-value based on cdc clk rate */ - if (cntl->clk_rate == 9600000) { - cal_lsb = 0x6d; - cal_msb = 0x00; - } else { - cal_lsb = 0x56; - cal_msb = 0x00; - } - snd_soc_write(codec, WCD9360_CPE_FLL_USER_CTL_6, cal_lsb); - snd_soc_write(codec, WCD9360_CPE_FLL_USER_CTL_7, cal_msb); - - /* FLL mode to follow power up sequence */ - snd_soc_update_bits(codec, WCD9360_CPE_FLL_FLL_MODE, - 0x60, 0x00); - - /* HW controlled CPE FLL */ - snd_soc_update_bits(codec, WCD9360_CPE_FLL_FLL_MODE, - 0x80, 0x80); - - /* Force on CPE FLL */ - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CFG, - 0x04, 0x04); - - do { - /* Time for FLL calibration to complete */ - usleep_range(1000, 1100); - lock_det = snd_soc_read(codec, WCD9360_CPE_FLL_STATUS_3); - retry++; - } while (!(lock_det & 0x01) && - retry <= WCD_CPE_FLL_MAX_RETRIES); - - if (!(lock_det & 0x01)) { - dev_err(codec->dev, "%s: lock detect not set, 0x%02x\n", - __func__, lock_det); - ret = -EIO; - goto err_lock_det; - } - - snd_soc_update_bits(codec, WCD9360_CPE_FLL_FLL_MODE, - 0x60, 0x20); - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CFG, - 0x04, 0x00); - return ret; - -err_lock_det: - /* Undo the register settings */ - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CFG, - 0x04, 0x00); - snd_soc_update_bits(codec, WCD9360_CPE_FLL_FLL_MODE, - 0x80, 0x00); - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, - 0x02, 0x00); - return ret; -} - -static void wcd_cntl_config_cpar(struct wcd_dsp_cntl *cntl) -{ - struct snd_soc_codec *codec = cntl->codec; - u8 nom_lo, nom_hi, svs2_lo, svs2_hi; - - /* Configure CPAR */ - nom_hi = svs2_hi = 0; - if (cntl->clk_rate == 9600000) { - nom_lo = 0x90; - svs2_lo = 0x50; - } else { - nom_lo = 0x70; - svs2_lo = 0x3e; - } - - snd_soc_write(codec, WCD9360_TEST_DEBUG_LVAL_NOM_LOW, nom_lo); - snd_soc_write(codec, WCD9360_TEST_DEBUG_LVAL_NOM_HIGH, nom_hi); - snd_soc_write(codec, WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_LOW, svs2_lo); - snd_soc_write(codec, WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_HIGH, svs2_hi); - - snd_soc_update_bits(codec, WCD9360_CPE_SS_PWR_CPEFLL_CTL, - 0x03, 0x03); -} - -static int wcd_cntl_cpe_fll_ctrl(struct wcd_dsp_cntl *cntl, - bool enable) -{ - struct snd_soc_codec *codec = cntl->codec; - int ret = 0; - - if (enable) { - ret = wcd_cntl_cpe_fll_calibrate(cntl); - if (ret < 0) { - dev_err(codec->dev, - "%s: cpe_fll_cal failed, err = %d\n", - __func__, ret); - goto done; - } - - wcd_cntl_config_cpar(cntl); - - /* Enable AHB CLK and CPE CLK*/ - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPE_CTL, - 0x05, 0x05); - } else { - /* Disable AHB CLK and CPE CLK */ - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPE_CTL, - 0x05, 0x00); - /* Reset the CPAR mode for CPE FLL */ - snd_soc_write(codec, WCD9360_CPE_FLL_FLL_MODE, 0x20); - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CFG, - 0x04, 0x00); - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, - 0x02, 0x00); - } -done: - return ret; -} - -static int wcd_cntl_clocks_enable(struct wcd_dsp_cntl *cntl) -{ - struct snd_soc_codec *codec = cntl->codec; - int ret; - - WCD_CNTL_MUTEX_LOCK(codec, cntl->clk_mutex); - /* Enable codec clock */ - if (cntl->cdc_cb && cntl->cdc_cb->cdc_clk_en) - ret = cntl->cdc_cb->cdc_clk_en(codec, true); - else - ret = -EINVAL; - - if (ret < 0) { - dev_err(codec->dev, - "%s: Failed to enable cdc clk, err = %d\n", - __func__, ret); - goto done; - } - /* Pull CPAR out of reset */ - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, 0x04, 0x00); - - /* Configure and Enable CPE FLL clock */ - ret = wcd_cntl_cpe_fll_ctrl(cntl, true); - if (ret < 0) { - dev_err(codec->dev, - "%s: Failed to enable cpe clk, err = %d\n", - __func__, ret); - goto err_cpe_clk; - } - cntl->is_clk_enabled = true; - - /* Ungate the CPR clock */ - snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_GATE, 0x10, 0x00); -done: - WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex); - return ret; - -err_cpe_clk: - if (cntl->cdc_cb && cntl->cdc_cb->cdc_clk_en) - cntl->cdc_cb->cdc_clk_en(codec, false); - - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, 0x04, 0x04); - WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex); - return ret; -} - -static int wcd_cntl_clocks_disable(struct wcd_dsp_cntl *cntl) -{ - struct snd_soc_codec *codec = cntl->codec; - int ret = 0; - - WCD_CNTL_MUTEX_LOCK(codec, cntl->clk_mutex); - if (!cntl->is_clk_enabled) { - dev_info(codec->dev, "%s: clocks already disabled\n", - __func__); - goto done; - } - - /* Gate the CPR clock */ - snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_GATE, 0x10, 0x10); - - /* Disable CPE FLL clock */ - ret = wcd_cntl_cpe_fll_ctrl(cntl, false); - if (ret < 0) - dev_err(codec->dev, - "%s: Failed to disable cpe clk, err = %d\n", - __func__, ret); - - /* - * Even if CPE FLL disable failed, go ahead and disable - * the codec clock - */ - if (cntl->cdc_cb && cntl->cdc_cb->cdc_clk_en) - ret = cntl->cdc_cb->cdc_clk_en(codec, false); - else - ret = -EINVAL; - - cntl->is_clk_enabled = false; - - /* Put CPAR in reset */ - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, 0x04, 0x04); -done: - WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex); - return ret; -} - -static void wcd_cntl_cpar_ctrl(struct wcd_dsp_cntl *cntl, - bool enable) -{ - struct snd_soc_codec *codec = cntl->codec; - - if (enable) - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, 0x03, 0x03); - else - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, 0x03, 0x00); -} - -static int wcd_cntl_enable_memory(struct wcd_dsp_cntl *cntl, - enum wcd_mem_type mem_type) -{ - struct snd_soc_codec *codec = cntl->codec; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); - int loop_cnt = 0; - u8 status = 0; - int ret = 0; - - - switch (mem_type) { - - case WCD_MEM_TYPE_ALWAYS_ON: - - /* 512KB of always on region */ - wcd9xxx_slim_write_repeat(wcd9xxx, - WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0, - ARRAY_SIZE(mem_enable_values), - mem_enable_values); - wcd9xxx_slim_write_repeat(wcd9xxx, - WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1, - ARRAY_SIZE(mem_enable_values), - mem_enable_values); - break; - - case WCD_MEM_TYPE_SWITCHABLE: - - snd_soc_update_bits(codec, WCD9360_TEST_DEBUG_MEM_CTRL, - 0x80, 0x80); - do { - loop_cnt++; - /* Time to enable the power domain for memory */ - usleep_range(100, 150); - } while ((status & 0x02) != 0x02 && - loop_cnt != WCD_MEM_ENABLE_MAX_RETRIES); - - if ((status & 0x02) != 0x02) { - dev_err(cntl->codec->dev, - "%s: power domain not enabled, status = 0x%02x\n", - __func__, status); - ret = -EIO; - goto done; - } - - /* Rest of the memory */ - wcd9xxx_slim_write_repeat(wcd9xxx, - WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2, - ARRAY_SIZE(mem_enable_values), - mem_enable_values); - wcd9xxx_slim_write_repeat(wcd9xxx, - WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3, - ARRAY_SIZE(mem_enable_values), - mem_enable_values); - - snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN, - 0x05); - break; - - default: - dev_err(cntl->codec->dev, "%s: Invalid mem_type %d\n", - __func__, mem_type); - ret = -EINVAL; - break; - } -done: - /* Make sure Deep sleep of memories is enabled for all banks */ - snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, 0xFF); - snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, 0x0F); - - return ret; -} - -static void wcd_cntl_disable_memory(struct wcd_dsp_cntl *cntl, - enum wcd_mem_type mem_type) -{ - struct snd_soc_codec *codec = cntl->codec; - - switch (mem_type) { - case WCD_MEM_TYPE_ALWAYS_ON: - snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1, - 0xFF); - snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0, - 0xFF); - break; - case WCD_MEM_TYPE_SWITCHABLE: - snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3, - 0xFF); - snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2, - 0xFF); - snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN, - 0x07); - - snd_soc_update_bits(codec, WCD9360_TEST_DEBUG_MEM_CTRL, - 0x80, 0x00); - break; - default: - dev_err(cntl->codec->dev, "%s: Invalid mem_type %d\n", - __func__, mem_type); - break; - } - - snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, 0xFF); - snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, 0x0F); -} - -static void wcd_cntl_do_shutdown(struct wcd_dsp_cntl *cntl) -{ - struct snd_soc_codec *codec = cntl->codec; - - /* Disable WDOG */ - snd_soc_update_bits(codec, WCD9360_CPE_SS_WDOG_CFG, - 0x3F, 0x01); - - /* Put WDSP in reset state */ - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPE_CTL, - 0x02, 0x00); - - /* If DSP transitions from boot to shutdown, then vote for SVS */ - if (cntl->is_wdsp_booted) - cntl->cdc_cb->cdc_vote_svs(codec, true); - cntl->is_wdsp_booted = false; -} - -static int wcd_cntl_do_boot(struct wcd_dsp_cntl *cntl) -{ - struct snd_soc_codec *codec = cntl->codec; - int ret = 0; - - /* - * Debug mode is set from debugfs file node. If debug_mode - * is set, then do not configure the watchdog timer. This - * will be required for debugging the DSP firmware. - */ - if (cntl->debug_mode) { - snd_soc_update_bits(codec, WCD9360_CPE_SS_WDOG_CFG, - 0x3F, 0x01); - } else { - snd_soc_update_bits(codec, WCD9360_CPE_SS_WDOG_CFG, - 0x3F, 0x21); - } - - /* Make sure all the error interrupts are cleared */ - snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0A, 0xFF); - snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0B, 0xFF); - - reinit_completion(&cntl->boot_complete); - - /* Remove WDSP out of reset */ - snd_soc_update_bits(codec, WCD9360_CPE_SS_CPE_CTL, - 0x02, 0x02); - - /* - * In debug mode, DSP may not boot up normally, - * wait indefinitely for DSP to boot. - */ - if (cntl->debug_mode) { - wait_for_completion(&cntl->boot_complete); - dev_dbg(codec->dev, "%s: WDSP booted in dbg mode\n", __func__); - cntl->is_wdsp_booted = true; - goto done; - } - - /* Boot in normal mode */ - ret = wait_for_completion_timeout(&cntl->boot_complete, - msecs_to_jiffies(WCD_DSP_BOOT_TIMEOUT_MS)); - if (!ret) { - dev_err(codec->dev, "%s: WDSP boot timed out\n", - __func__); - ret = -ETIMEDOUT; - goto err_boot; - } else { - /* - * Re-initialize the return code to 0, as in success case, - * it will hold the remaining time for completion timeout - */ - ret = 0; - } - - dev_dbg(codec->dev, "%s: WDSP booted in normal mode\n", __func__); - cntl->is_wdsp_booted = true; - - /* Enable WDOG */ - snd_soc_update_bits(codec, WCD9360_CPE_SS_WDOG_CFG, - 0x10, 0x10); -done: - /* If dsp booted up, then remove vote on SVS */ - if (cntl->is_wdsp_booted) - cntl->cdc_cb->cdc_vote_svs(codec, false); - - return ret; -err_boot: - /* call shutdown to perform cleanup */ - wcd_cntl_do_shutdown(cntl); - return ret; -} - -static irqreturn_t wcd_cntl_ipc_irq(int irq, void *data) -{ - struct wcd_dsp_cntl *cntl = data; - int ret; - - complete(&cntl->boot_complete); - - if (cntl->m_dev && cntl->m_ops && - cntl->m_ops->signal_handler) - ret = cntl->m_ops->signal_handler(cntl->m_dev, WDSP_IPC1_INTR, - NULL); - else - ret = -EINVAL; - - if (ret < 0) - dev_err(cntl->codec->dev, - "%s: Failed to handle irq %d\n", __func__, irq); - - return IRQ_HANDLED; -} - -static irqreturn_t wcd_cntl_err_irq(int irq, void *data) -{ - struct wcd_dsp_cntl *cntl = data; - struct snd_soc_codec *codec = cntl->codec; - struct wdsp_err_signal_arg arg; - u16 status = 0; - u8 reg_val; - int ret = 0; - - reg_val = snd_soc_read(codec, WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0A); - status = status | reg_val; - - reg_val = snd_soc_read(codec, WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0B); - status = status | (reg_val << 8); - - dev_info(codec->dev, "%s: error interrupt status = 0x%x\n", - __func__, status); - - if ((status & cntl->irqs.fatal_irqs) && - (cntl->m_dev && cntl->m_ops && cntl->m_ops->signal_handler)) { - arg.mem_dumps_enabled = cntl->ramdump_enable; - arg.remote_start_addr = WCD_9360_RAMDUMP_START_ADDR; - arg.dump_size = WCD_9360_RAMDUMP_SIZE; - ret = cntl->m_ops->signal_handler(cntl->m_dev, WDSP_ERR_INTR, - &arg); - if (ret < 0) - dev_err(cntl->codec->dev, - "%s: Failed to handle fatal irq 0x%x\n", - __func__, status & cntl->irqs.fatal_irqs); - wcd_cntl_change_online_state(cntl, 0); - } else { - dev_err(cntl->codec->dev, "%s: Invalid signal_handler\n", - __func__); - } - - return IRQ_HANDLED; -} - -static int wcd_control_handler(struct device *dev, void *priv_data, - enum wdsp_event_type event, void *data) -{ - struct wcd_dsp_cntl *cntl = priv_data; - struct snd_soc_codec *codec = cntl->codec; - int ret = 0; - - switch (event) { - case WDSP_EVENT_POST_INIT: - case WDSP_EVENT_POST_DLOAD_CODE: - case WDSP_EVENT_DLOAD_FAILED: - case WDSP_EVENT_POST_SHUTDOWN: - - /* Disable CPAR */ - wcd_cntl_cpar_ctrl(cntl, false); - /* Disable all the clocks */ - ret = wcd_cntl_clocks_disable(cntl); - if (ret < 0) - dev_err(codec->dev, - "%s: Failed to disable clocks, err = %d\n", - __func__, ret); - - if (event == WDSP_EVENT_POST_DLOAD_CODE) - /* Mark DSP online since code download is complete */ - wcd_cntl_change_online_state(cntl, 1); - break; - - case WDSP_EVENT_PRE_DLOAD_DATA: - case WDSP_EVENT_PRE_DLOAD_CODE: - - /* Enable all the clocks */ - ret = wcd_cntl_clocks_enable(cntl); - if (ret < 0) { - dev_err(codec->dev, - "%s: Failed to enable clocks, err = %d\n", - __func__, ret); - goto done; - } - - /* Enable CPAR */ - wcd_cntl_cpar_ctrl(cntl, true); - - if (event == WDSP_EVENT_PRE_DLOAD_CODE) - wcd_cntl_enable_memory(cntl, WCD_MEM_TYPE_ALWAYS_ON); - else if (event == WDSP_EVENT_PRE_DLOAD_DATA) - wcd_cntl_enable_memory(cntl, WCD_MEM_TYPE_SWITCHABLE); - break; - - case WDSP_EVENT_DO_BOOT: - - ret = wcd_cntl_do_boot(cntl); - if (ret < 0) - dev_err(codec->dev, - "%s: WDSP boot failed, err = %d\n", - __func__, ret); - break; - - case WDSP_EVENT_DO_SHUTDOWN: - - wcd_cntl_do_shutdown(cntl); - wcd_cntl_disable_memory(cntl, WCD_MEM_TYPE_SWITCHABLE); - break; - - default: - dev_dbg(codec->dev, "%s: unhandled event %d\n", - __func__, event); - } - -done: - return ret; -} - -static int wcd_cntl_sysfs_init(char *dir, struct wcd_dsp_cntl *cntl) -{ - struct snd_soc_codec *codec = cntl->codec; - int ret = 0; - - ret = kobject_init_and_add(&cntl->wcd_kobj, &wcd_cntl_ktype, - kernel_kobj, dir); - if (ret < 0) { - dev_err(codec->dev, - "%s: Failed to add kobject %s, err = %d\n", - __func__, dir, ret); - goto done; - } - - ret = sysfs_create_file(&cntl->wcd_kobj, &cntl_attr_boot.attr); - if (ret < 0) { - dev_err(codec->dev, - "%s: Failed to add wdsp_boot sysfs entry to %s\n", - __func__, dir); - goto fail_create_file; - } - - return ret; - -fail_create_file: - kobject_put(&cntl->wcd_kobj); -done: - return ret; -} - -static void wcd_cntl_sysfs_remove(struct wcd_dsp_cntl *cntl) -{ - sysfs_remove_file(&cntl->wcd_kobj, &cntl_attr_boot.attr); - kobject_put(&cntl->wcd_kobj); -} - -static void wcd_cntl_debugfs_init(char *dir, struct wcd_dsp_cntl *cntl) -{ - struct snd_soc_codec *codec = cntl->codec; - - cntl->entry = debugfs_create_dir(dir, NULL); - if (IS_ERR_OR_NULL(dir)) { - dev_err(codec->dev, "%s debugfs_create_dir failed for %s\n", - __func__, dir); - goto done; - } - - debugfs_create_u32("debug_mode", 0644, - cntl->entry, &cntl->debug_mode); - debugfs_create_bool("ramdump_enable", 0644, - cntl->entry, &cntl->ramdump_enable); -done: - return; -} - -static void wcd_cntl_debugfs_remove(struct wcd_dsp_cntl *cntl) -{ - if (cntl) - debugfs_remove(cntl->entry); -} - -static int wcd_miscdev_release(struct inode *inode, struct file *filep) -{ - struct wcd_dsp_cntl *cntl = container_of(filep->private_data, - struct wcd_dsp_cntl, miscdev); - if (!cntl->m_dev || !cntl->m_ops || - !cntl->m_ops->vote_for_dsp) { - dev_err(cntl->codec->dev, - "%s: DSP not ready to boot\n", __func__); - return -EINVAL; - } - - /* Make sure the DSP users goes to zero upon closing dev node */ - while (cntl->boot_reqs > 0) { - cntl->m_ops->vote_for_dsp(cntl->m_dev, false); - cntl->boot_reqs--; - } - - return 0; -} - -static ssize_t wcd_miscdev_write(struct file *filep, const char __user *ubuf, - size_t count, loff_t *pos) -{ - struct wcd_dsp_cntl *cntl = container_of(filep->private_data, - struct wcd_dsp_cntl, miscdev); - char val[WCD_MISCDEV_CMD_MAX_LEN + 1]; - bool vote; - int ret = 0; - - memset(val, 0, WCD_MISCDEV_CMD_MAX_LEN + 1); - - if (count == 0 || count > WCD_MISCDEV_CMD_MAX_LEN) { - pr_err("%s: Invalid count = %zd\n", __func__, count); - ret = -EINVAL; - goto done; - } - - ret = copy_from_user(val, ubuf, count); - if (ret < 0) { - dev_err(cntl->codec->dev, - "%s: copy_from_user failed, err = %d\n", - __func__, ret); - ret = -EFAULT; - goto done; - } - - if (val[0] == '1') { - cntl->boot_reqs++; - vote = true; - } else if (val[0] == '0') { - if (cntl->boot_reqs == 0) { - dev_err(cntl->codec->dev, - "%s: WDSP already disabled\n", __func__); - ret = -EINVAL; - goto done; - } - cntl->boot_reqs--; - vote = false; - } else { - dev_err(cntl->codec->dev, "%s: Invalid value %s\n", - __func__, val); - ret = -EINVAL; - goto done; - } - - dev_dbg(cntl->codec->dev, - "%s: booted = %s, ref_cnt = %d, vote = %s\n", - __func__, cntl->is_wdsp_booted ? "true" : "false", - cntl->boot_reqs, vote ? "true" : "false"); - - if (cntl->m_dev && cntl->m_ops && - cntl->m_ops->vote_for_dsp) - ret = cntl->m_ops->vote_for_dsp(cntl->m_dev, vote); - else - ret = -EINVAL; -done: - if (ret) - return ret; - else - return count; -} - -static const struct file_operations wcd_miscdev_fops = { - .write = wcd_miscdev_write, - .release = wcd_miscdev_release, -}; - -static int wcd_cntl_miscdev_create(struct wcd_dsp_cntl *cntl) -{ - snprintf(cntl->miscdev_name, ARRAY_SIZE(cntl->miscdev_name), - "wcd_dsp%u_control", cntl->dsp_instance); - cntl->miscdev.minor = MISC_DYNAMIC_MINOR; - cntl->miscdev.name = cntl->miscdev_name; - cntl->miscdev.fops = &wcd_miscdev_fops; - cntl->miscdev.parent = cntl->codec->dev; - - return misc_register(&cntl->miscdev); -} - -static void wcd_cntl_miscdev_destroy(struct wcd_dsp_cntl *cntl) -{ - misc_deregister(&cntl->miscdev); -} - -static int wcd_control_init(struct device *dev, void *priv_data) -{ - struct wcd_dsp_cntl *cntl = priv_data; - struct snd_soc_codec *codec = cntl->codec; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); - struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; - int ret; - bool err_irq_requested = false; - - ret = wcd9xxx_request_irq(core_res, - cntl->irqs.cpe_ipc1_irq, - wcd_cntl_ipc_irq, "CPE IPC1", - cntl); - if (ret < 0) { - dev_err(codec->dev, - "%s: Failed to request cpe ipc irq, err = %d\n", - __func__, ret); - goto done; - } - - /* Unmask the fatal irqs */ - snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A, - ~(cntl->irqs.fatal_irqs & 0xFF)); - snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B, - ~((cntl->irqs.fatal_irqs >> 8) & 0xFF)); - - /* - * CPE ERR irq is used only for error reporting from WCD DSP, - * even if this request fails, DSP can be function normally. - * Continuing with init even if the CPE ERR irq request fails. - */ - if (wcd9xxx_request_irq(core_res, cntl->irqs.cpe_err_irq, - wcd_cntl_err_irq, "CPE ERR", cntl)) - dev_info(codec->dev, "%s: Failed request_irq(cpe_err_irq)", - __func__); - else - err_irq_requested = true; - - - /* Enable all the clocks */ - ret = wcd_cntl_clocks_enable(cntl); - if (ret < 0) { - dev_err(codec->dev, "%s: Failed to enable clocks, err = %d\n", - __func__, ret); - goto err_clk_enable; - } - wcd_cntl_cpar_ctrl(cntl, true); - - return 0; - -err_clk_enable: - /* Mask all error interrupts */ - snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A, 0xFF); - snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B, 0xFF); - - /* Free the irq's requested */ - wcd9xxx_free_irq(core_res, cntl->irqs.cpe_ipc1_irq, cntl); - - if (err_irq_requested) - wcd9xxx_free_irq(core_res, cntl->irqs.cpe_err_irq, cntl); -done: - return ret; -} - -static int wcd_control_deinit(struct device *dev, void *priv_data) -{ - struct wcd_dsp_cntl *cntl = priv_data; - struct snd_soc_codec *codec = cntl->codec; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); - struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; - - wcd_cntl_clocks_disable(cntl); - wcd_cntl_cpar_ctrl(cntl, false); - - /* Mask all error interrupts */ - snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A, 0xFF); - snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B, 0xFF); - - /* Free the irq's requested */ - wcd9xxx_free_irq(core_res, cntl->irqs.cpe_err_irq, cntl); - wcd9xxx_free_irq(core_res, cntl->irqs.cpe_ipc1_irq, cntl); - - return 0; -} - -static struct wdsp_cmpnt_ops control_ops = { - .init = wcd_control_init, - .deinit = wcd_control_deinit, - .event_handler = wcd_control_handler, -}; - -static int wcd_ctrl_component_bind(struct device *dev, - struct device *master, - void *data) -{ - struct wcd_dsp_cntl *cntl; - struct snd_soc_codec *codec; - struct snd_card *card; - struct snd_info_entry *entry; - char proc_name[WCD_PROCFS_ENTRY_MAX_LEN]; - char wcd_cntl_dir_name[WCD_CNTL_DIR_NAME_LEN_MAX]; - int ret = 0; - - if (!dev || !master || !data) { - pr_err("%s: Invalid parameters\n", __func__); - return -EINVAL; - } - - cntl = (struct wcd_dsp_cntl *) pahu_get_wcd_dsp_cntl(dev); - if (!cntl) { - dev_err(dev, "%s: Failed to get cntl reference\n", - __func__); - return -EINVAL; - } - - cntl->m_dev = master; - cntl->m_ops = data; - - if (!cntl->m_ops->register_cmpnt_ops) { - dev_err(dev, "%s: invalid master callback register_cmpnt_ops\n", - __func__); - ret = -EINVAL; - goto done; - } - - ret = cntl->m_ops->register_cmpnt_ops(master, dev, cntl, &control_ops); - if (ret) { - dev_err(dev, "%s: register_cmpnt_ops failed, err = %d\n", - __func__, ret); - goto done; - } - - ret = wcd_cntl_miscdev_create(cntl); - if (ret < 0) { - dev_err(dev, "%s: misc dev register failed, err = %d\n", - __func__, ret); - goto done; - } - - snprintf(wcd_cntl_dir_name, WCD_CNTL_DIR_NAME_LEN_MAX, - "%s%d", "wdsp", cntl->dsp_instance); - ret = wcd_cntl_sysfs_init(wcd_cntl_dir_name, cntl); - if (ret < 0) { - dev_err(dev, "%s: sysfs_init failed, err = %d\n", - __func__, ret); - goto err_sysfs_init; - } - - wcd_cntl_debugfs_init(wcd_cntl_dir_name, cntl); - - codec = cntl->codec; - card = codec->component.card->snd_card; - snprintf(proc_name, WCD_PROCFS_ENTRY_MAX_LEN, "%s%d%s", "cpe", - cntl->dsp_instance, "_state"); - entry = snd_info_create_card_entry(card, proc_name, card->proc_root); - if (!entry) { - /* Do not treat this as Fatal error */ - dev_err(dev, "%s: Failed to create procfs entry %s\n", - __func__, proc_name); - goto err_sysfs_init; - } - - cntl->ssr_entry.entry = entry; - cntl->ssr_entry.offline = 1; - entry->size = WCD_PROCFS_ENTRY_MAX_LEN; - entry->content = SNDRV_INFO_CONTENT_DATA; - entry->c.ops = &wdsp_ssr_entry_ops; - entry->private_data = cntl; - ret = snd_info_register(entry); - if (ret < 0) { - dev_err(dev, "%s: Failed to register entry %s, err = %d\n", - __func__, proc_name, ret); - snd_info_free_entry(entry); - /* Let bind still happen even if creating the entry failed */ - ret = 0; - } -done: - return ret; - -err_sysfs_init: - wcd_cntl_miscdev_destroy(cntl); - return ret; -} - -static void wcd_ctrl_component_unbind(struct device *dev, - struct device *master, - void *data) -{ - struct wcd_dsp_cntl *cntl; - - if (!dev) { - pr_err("%s: Invalid device\n", __func__); - return; - } - - cntl = (struct wcd_dsp_cntl *) pahu_get_wcd_dsp_cntl(dev); - if (!cntl) { - dev_err(dev, "%s: Failed to get cntl reference\n", - __func__); - return; - } - - cntl->m_dev = NULL; - cntl->m_ops = NULL; - - /* Remove the sysfs entries */ - wcd_cntl_sysfs_remove(cntl); - - /* Remove the debugfs entries */ - wcd_cntl_debugfs_remove(cntl); - - /* Remove the misc device */ - wcd_cntl_miscdev_destroy(cntl); -} - -static const struct component_ops wcd_ctrl_component_ops = { - .bind = wcd_ctrl_component_bind, - .unbind = wcd_ctrl_component_unbind, -}; - -/* - * wcd9360_dsp_ssr_event: handle the SSR event raised by caller. - * @cntl: Handle to the wcd_dsp_cntl structure - * @event: The SSR event to be handled - * - * Notifies the manager driver about the SSR event. - * Returns 0 on success and negative error code on error. - */ -int wcd9360_dsp_ssr_event(struct wcd_dsp_cntl *cntl, enum cdc_ssr_event event) -{ - int ret = 0; - - if (!cntl) { - pr_err("%s: Invalid handle to control\n", __func__); - return -EINVAL; - } - - if (!cntl->m_dev || !cntl->m_ops || !cntl->m_ops->signal_handler) { - dev_err(cntl->codec->dev, - "%s: Invalid signal_handler callback\n", __func__); - return -EINVAL; - } - - switch (event) { - case WCD_CDC_DOWN_EVENT: - ret = cntl->m_ops->signal_handler(cntl->m_dev, - WDSP_CDC_DOWN_SIGNAL, - NULL); - if (ret < 0) - dev_err(cntl->codec->dev, - "%s: WDSP_CDC_DOWN_SIGNAL failed, err = %d\n", - __func__, ret); - wcd_cntl_change_online_state(cntl, 0); - break; - case WCD_CDC_UP_EVENT: - ret = cntl->m_ops->signal_handler(cntl->m_dev, - WDSP_CDC_UP_SIGNAL, - NULL); - if (ret < 0) - dev_err(cntl->codec->dev, - "%s: WDSP_CDC_UP_SIGNAL failed, err = %d\n", - __func__, ret); - break; - default: - dev_err(cntl->codec->dev, "%s: Invalid event %d\n", - __func__, event); - ret = -EINVAL; - break; - } - - return ret; -} -EXPORT_SYMBOL(wcd9360_dsp_ssr_event); - -/* - * wcd9360_dsp_cntl_init: Initialize the wcd-dsp control - * @codec: pointer to the codec handle - * @params: Parameters required to initialize wcd-dsp control - * - * This API is expected to be invoked by the codec driver and - * provide information essential for the wcd dsp control to - * configure and initialize the dsp - */ -void wcd9360_dsp_cntl_init(struct snd_soc_codec *codec, - struct wcd_dsp_params *params, - struct wcd_dsp_cntl **cntl) -{ - struct wcd_dsp_cntl *control; - int ret; - - if (!codec || !params) { - pr_err("%s: Invalid handle to %s\n", __func__, - (!codec) ? "codec" : "params"); - *cntl = NULL; - return; - } - - if (*cntl) { - pr_err("%s: cntl is non NULL, maybe already initialized ?\n", - __func__); - return; - } - - if (!params->cb || !params->cb->cdc_clk_en || - !params->cb->cdc_vote_svs) { - dev_err(codec->dev, - "%s: clk_en and vote_svs callbacks must be provided\n", - __func__); - return; - } - - control = kzalloc(sizeof(*control), GFP_KERNEL); - if (!(control)) - return; - - control->codec = codec; - control->clk_rate = params->clk_rate; - control->cdc_cb = params->cb; - control->dsp_instance = params->dsp_instance; - memcpy(&control->irqs, ¶ms->irqs, sizeof(control->irqs)); - init_completion(&control->boot_complete); - mutex_init(&control->clk_mutex); - mutex_init(&control->ssr_mutex); - init_waitqueue_head(&control->ssr_entry.offline_poll_wait); - - /* - * The default state of WDSP is in SVS mode. - * Vote for SVS now, the vote will be removed only - * after DSP is booted up. - */ - control->cdc_cb->cdc_vote_svs(codec, true); - - /* - * If this is the last component needed by master to be ready, - * then component_bind will be called within the component_add. - * Hence, the data pointer should be assigned before component_add, - * so that we can access it during this component's bind call. - */ - *cntl = control; - ret = component_add(codec->dev, &wcd_ctrl_component_ops); - if (ret) { - dev_err(codec->dev, "%s: component_add failed, err = %d\n", - __func__, ret); - kfree(*cntl); - *cntl = NULL; - } -} -EXPORT_SYMBOL(wcd9360_dsp_cntl_init); - -/* - * wcd9360_dsp_cntl_deinit: De-initialize the wcd-dsp control - * @cntl: The struct wcd_dsp_cntl to de-initialize - * - * This API is intended to be invoked by the codec driver - * to de-initialize the wcd dsp control - */ -void wcd9360_dsp_cntl_deinit(struct wcd_dsp_cntl **cntl) -{ - struct wcd_dsp_cntl *control = *cntl; - struct snd_soc_codec *codec; - - /* If control is NULL, there is nothing to de-initialize */ - if (!control) - return; - codec = control->codec; - - /* - * Calling shutdown will cleanup all register states, - * irrespective of DSP was booted up or not. - */ - wcd_cntl_do_shutdown(control); - wcd_cntl_disable_memory(control, WCD_MEM_TYPE_SWITCHABLE); - wcd_cntl_disable_memory(control, WCD_MEM_TYPE_ALWAYS_ON); - - component_del(codec->dev, &wcd_ctrl_component_ops); - - mutex_destroy(&control->clk_mutex); - mutex_destroy(&control->ssr_mutex); - kfree(*cntl); - *cntl = NULL; -} -EXPORT_SYMBOL(wcd9360_dsp_cntl_deinit); diff --git a/asoc/codecs/wcd9360/wcd9360-dsp-cntl.h b/asoc/codecs/wcd9360/wcd9360-dsp-cntl.h deleted file mode 100644 index db8b4310552b..000000000000 --- a/asoc/codecs/wcd9360/wcd9360-dsp-cntl.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __WCD9360_DSP_CNTL_H__ -#define __WCD9360_DSP_CNTL_H__ - -#include -#include -#include - -enum cdc_ssr_event { - WCD_CDC_DOWN_EVENT, - WCD_CDC_UP_EVENT, -}; - -struct wcd_dsp_cdc_cb { - /* Callback to enable codec clock */ - int (*cdc_clk_en)(struct snd_soc_codec *, bool); - /* Callback to vote and unvote for SVS2 mode */ - void (*cdc_vote_svs)(struct snd_soc_codec *, bool); -}; - -struct wcd_dsp_irq_info { - /* IPC interrupt */ - int cpe_ipc1_irq; - - /* CPE error summary interrupt */ - int cpe_err_irq; - - /* - * Bit mask to indicate which of the - * error interrupts are to be considered - * as fatal. - */ - u16 fatal_irqs; -}; - -struct wcd_dsp_params { - struct wcd_dsp_cdc_cb *cb; - struct wcd_dsp_irq_info irqs; - - /* Rate at which the codec clock operates */ - u32 clk_rate; - - /* - * Represents the dsp instance, will be used - * to create sysfs and debugfs entries with - * directory wdsp - */ - u32 dsp_instance; -}; - -struct wdsp_ssr_entry { - u8 offline; - u8 offline_change; - wait_queue_head_t offline_poll_wait; - struct snd_info_entry *entry; -}; - -struct wcd_dsp_cntl { - /* Handle to codec */ - struct snd_soc_codec *codec; - - /* Clk rate of the codec clock */ - u32 clk_rate; - - /* Callbacks to codec driver */ - const struct wcd_dsp_cdc_cb *cdc_cb; - - /* Completion to indicate WDSP boot done */ - struct completion boot_complete; - - struct wcd_dsp_irq_info irqs; - u32 dsp_instance; - - /* Sysfs entries related */ - int boot_reqs; - struct kobject wcd_kobj; - - /* Debugfs related */ - struct dentry *entry; - u32 debug_mode; - bool ramdump_enable; - - /* WDSP manager drivers data */ - struct device *m_dev; - struct wdsp_mgr_ops *m_ops; - - /* clk related */ - struct mutex clk_mutex; - bool is_clk_enabled; - - /* Keep track of WDSP boot status */ - bool is_wdsp_booted; - - /* SSR related */ - struct wdsp_ssr_entry ssr_entry; - struct mutex ssr_mutex; - - /* Misc device related */ - char miscdev_name[256]; - struct miscdevice miscdev; -}; - -void wcd9360_dsp_cntl_init(struct snd_soc_codec *codec, - struct wcd_dsp_params *params, - struct wcd_dsp_cntl **cntl); -void wcd9360_dsp_cntl_deinit(struct wcd_dsp_cntl **cntl); -int wcd9360_dsp_ssr_event(struct wcd_dsp_cntl *cntl, enum cdc_ssr_event event); -#endif /* end __WCD_DSP_CONTROL_H__ */ diff --git a/asoc/codecs/wcd9360/wcd9360-irq.h b/asoc/codecs/wcd9360/wcd9360-irq.h deleted file mode 100644 index fa79447709b3..000000000000 --- a/asoc/codecs/wcd9360/wcd9360-irq.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __WCD9360_IRQ_H_ -#define __WCD9360_IRQ_H_ - -enum { - /* INTR_REG 0 */ - WCD9360_IRQ_MISC = 1, - WCD9360_IRQ_RESERVED_0, - WCD9360_IRQ_LDO_RXTX_SCD, - WCD9360_IRQ_EAR_PA_SCD, - WCD9360_IRQ_AUX_PA_SCD, - WCD9360_IRQ_AUX_PA_CNP_COMPLETE, - WCD9360_IRQ_EAR_PA_CNP_COMPLETE, - /* INTR_REG 1 */ - WCD9360_IRQ_RESERVED_1, - WCD9360_IRQ_RESERVED_2, - WCD9360_IRQ_RESERVED_3, - WCD9360_IRQ_RESERVED_4, - WCD9360_IRQ_RESERVED_5, - WCD9360_IRQ_RESERVED_6, - WCD9360_IRQ_RESERVED_7, - WCD9360_IRQ_RESERVED_8, - /* INTR_REG 2 */ - WCD9360_IRQ_RESERVED_9, - WCD9360_IRQ_RESERVED_10, - WCD9360_IRQ_RESERVED_11, - WCD9360_IRQ_RESERVED_12, - WCD9360_IRQ_SOUNDWIRE, - WCD9360_IRQ_RESERVED_13, - WCD9360_IRQ_RCO_ERROR, - WCD9360_IRQ_CPE_ERROR, - /* INTR_REG 3 */ - WCD9360_IRQ_MAD_AUDIO, - WCD9360_IRQ_MAD_BEACON, - WCD9360_IRQ_MAD_ULTRASOUND, - WCD9360_IRQ_RESERVED_14, - WCD9360_IRQ_RESERVED_15, - WCD9360_IRQ_CPE1_INTR, - WCD9360_IRQ_CPE2_INTR, - WCD9360_IRQ_CPE_LPASS_ACK, - WCD9360_NUM_IRQS, -}; - -#endif diff --git a/asoc/codecs/wcd9360/wcd9360-regmap.c b/asoc/codecs/wcd9360/wcd9360-regmap.c deleted file mode 100644 index b74c1fb5c608..000000000000 --- a/asoc/codecs/wcd9360/wcd9360-regmap.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include "../core.h" -#include "../wcd9xxx-regmap.h" -#include "wcd9360-defaults.h" - -static bool wcd9360_is_readable_register(struct device *dev, unsigned int reg) -{ - u8 pg_num, reg_offset; - const u8 *reg_tbl = NULL; - - /* - * Get the page number from MSB of codec register. If its 0x80, assign - * the corresponding page index PAGE_0x80. - */ - pg_num = reg >> 8; - if (pg_num == 128) - pg_num = WCD9360_PAGE_128; - else if (pg_num == 80) - pg_num = WCD9360_PAGE_80; - else if (pg_num > 15) - return false; - - reg_tbl = wcd9360_reg[pg_num]; - reg_offset = reg & 0xFF; - - if (reg_tbl && reg_tbl[reg_offset]) - return true; - else - return false; -} - -static bool wcd9360_is_volatile_register(struct device *dev, unsigned int reg) -{ - u8 pg_num, reg_offset; - const u8 *reg_tbl = NULL; - - pg_num = reg >> 8; - - if (pg_num == 1 || pg_num == 2 || - pg_num == 6 || pg_num == 7) - return true; - else if (pg_num == 128) - pg_num = WCD9360_PAGE_128; - else if (pg_num == 80) - pg_num = WCD9360_PAGE_80; - else if (pg_num > 15) - return false; - - reg_tbl = wcd9360_reg[pg_num]; - reg_offset = reg & 0xFF; - - if (reg_tbl && reg_tbl[reg_offset] == WCD9360_RO) - return true; - - if ((reg >= WCD9360_CODEC_RPM_RST_CTL) && - (reg <= WCD9360_CHIP_TIER_CTRL_ALT_FUNC_EN)) - return true; - - if ((reg >= WCD9360_CDC_ANC0_IIR_COEFF_1_CTL) && - (reg <= WCD9360_CDC_ANC0_FB_GAIN_CTL)) - return true; - - if ((reg >= WCD9360_CODEC_CPR_WR_DATA_0) && - (reg <= WCD9360_CODEC_CPR_RD_DATA_3)) - return true; - - /* - * Need to mark volatile for registers that are writable but - * only few bits are read-only - */ - switch (reg) { - case WCD9360_CODEC_RPM_CLK_BYPASS: - case WCD9360_CODEC_RPM_CLK_GATE: - case WCD9360_CODEC_RPM_CLK_MCLK_CFG: - case WCD9360_CODEC_CPR_SVS_CX_VDD: - case WCD9360_CODEC_CPR_SVS2_CX_VDD: - case WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL: - case WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL: - return true; - } - - return false; -} - -struct regmap_config wcd9360_regmap_config = { - .reg_bits = 16, - .val_bits = 8, - .cache_type = REGCACHE_RBTREE, - .reg_defaults = wcd9360_defaults, - .num_reg_defaults = ARRAY_SIZE(wcd9360_defaults), - .max_register = WCD9360_MAX_REGISTER, - .volatile_reg = wcd9360_is_volatile_register, - .readable_reg = wcd9360_is_readable_register, - .can_multi_write = true, -}; diff --git a/asoc/codecs/wcd9360/wcd9360-routing.h b/asoc/codecs/wcd9360/wcd9360-routing.h deleted file mode 100644 index c305d2e23bf7..000000000000 --- a/asoc/codecs/wcd9360/wcd9360-routing.h +++ /dev/null @@ -1,882 +0,0 @@ -/* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef __WCD9360_ROUTING_H__ -#define __WCD9360_ROUTING_H__ - -#include - -const struct snd_soc_dapm_route pahu_slim_audio_map[] = { - - {"AIF4 MAD", NULL, "AIF4_MAD Mixer"}, - - /* Virtual input widget Mixer SLIMBUS */ - {"AIF1_CAP Mixer", "SLIM TX0", "SLIM TX0"}, - {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1"}, - {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2"}, - {"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3"}, - {"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4"}, - {"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5"}, - {"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6"}, - {"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7"}, - {"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8"}, - {"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9"}, - {"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10"}, - {"AIF1_CAP Mixer", "SLIM TX11", "SLIM TX11"}, - {"AIF1_CAP Mixer", "SLIM TX13", "SLIM TX13"}, - - {"AIF2_CAP Mixer", "SLIM TX0", "SLIM TX0"}, - {"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1"}, - {"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2"}, - {"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3"}, - {"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4"}, - {"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5"}, - {"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6"}, - {"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7"}, - {"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8"}, - {"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9"}, - {"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10"}, - {"AIF2_CAP Mixer", "SLIM TX11", "SLIM TX11"}, - {"AIF2_CAP Mixer", "SLIM TX13", "SLIM TX13"}, - - {"AIF3_CAP Mixer", "SLIM TX0", "SLIM TX0"}, - {"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1"}, - {"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2"}, - {"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3"}, - {"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4"}, - {"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5"}, - {"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6"}, - {"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7"}, - {"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8"}, - {"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9"}, - {"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10"}, - {"AIF3_CAP Mixer", "SLIM TX11", "SLIM TX11"}, - {"AIF3_CAP Mixer", "SLIM TX13", "SLIM TX13"}, - - {"AIF4_MAD Mixer", "SLIM TX13", "SLIM TX13"}, - - /* CDC Tx interface with SLIMBUS */ - {"SLIM TX0", NULL, "CDC_IF TX0 MUX"}, - {"SLIM TX1", NULL, "CDC_IF TX1 MUX"}, - {"SLIM TX2", NULL, "CDC_IF TX2 MUX"}, - {"SLIM TX3", NULL, "CDC_IF TX3 MUX"}, - {"SLIM TX4", NULL, "CDC_IF TX4 MUX"}, - {"SLIM TX5", NULL, "CDC_IF TX5 MUX"}, - {"SLIM TX6", NULL, "CDC_IF TX6 MUX"}, - {"SLIM TX7", NULL, "CDC_IF TX7 MUX"}, - {"SLIM TX8", NULL, "CDC_IF TX8 MUX"}, - {"SLIM TX9", NULL, "CDC_IF TX9 MUX"}, - {"SLIM TX10", NULL, "CDC_IF TX10 MUX2"}, - {"SLIM TX11", NULL, "CDC_IF TX11 MUX2"}, - {"SLIM TX13", NULL, "CDC_IF TX13 MUX"}, - - {"SLIM RX0 MUX", "AIF1_PB", "AIF1 PB"}, - {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"}, - {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"}, - {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"}, - {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"}, - {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"}, - {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"}, - {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"}, - - {"SLIM RX0 MUX", "AIF2_PB", "AIF2 PB"}, - {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"}, - {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"}, - {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"}, - {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"}, - {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"}, - {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"}, - {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"}, - - {"SLIM RX0 MUX", "AIF3_PB", "AIF3 PB"}, - {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"}, - {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"}, - {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"}, - {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"}, - {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"}, - {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"}, - {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"}, - - {"SLIM RX0 MUX", "AIF4_PB", "AIF4 PB"}, - {"SLIM RX1 MUX", "AIF4_PB", "AIF4 PB"}, - {"SLIM RX2 MUX", "AIF4_PB", "AIF4 PB"}, - {"SLIM RX3 MUX", "AIF4_PB", "AIF4 PB"}, - {"SLIM RX4 MUX", "AIF4_PB", "AIF4 PB"}, - {"SLIM RX5 MUX", "AIF4_PB", "AIF4 PB"}, - {"SLIM RX6 MUX", "AIF4_PB", "AIF4 PB"}, - {"SLIM RX7 MUX", "AIF4_PB", "AIF4 PB"}, - - {"SLIM RX0", NULL, "SLIM RX0 MUX"}, - {"SLIM RX1", NULL, "SLIM RX1 MUX"}, - {"SLIM RX2", NULL, "SLIM RX2 MUX"}, - {"SLIM RX3", NULL, "SLIM RX3 MUX"}, - {"SLIM RX4", NULL, "SLIM RX4 MUX"}, - {"SLIM RX5", NULL, "SLIM RX5 MUX"}, - {"SLIM RX6", NULL, "SLIM RX6 MUX"}, - {"SLIM RX7", NULL, "SLIM RX7 MUX"}, - - /* CDC Rx interface with SLIMBUS */ - {"CDC_IF RX0 MUX", "SLIM RX0", "SLIM RX0"}, - {"CDC_IF RX1 MUX", "SLIM RX1", "SLIM RX1"}, - {"CDC_IF RX2 MUX", "SLIM RX2", "SLIM RX2"}, - {"CDC_IF RX3 MUX", "SLIM RX3", "SLIM RX3"}, - {"CDC_IF RX4 MUX", "SLIM RX4", "SLIM RX4"}, - {"CDC_IF RX5 MUX", "SLIM RX5", "SLIM RX5"}, - {"CDC_IF RX6 MUX", "SLIM RX6", "SLIM RX6"}, - {"CDC_IF RX7 MUX", "SLIM RX7", "SLIM RX7"}, - - /* VI Feedback */ - {"AIF4_VI Mixer", "SPKR_VI_1", "VIINPUT"}, - {"AIF4_VI Mixer", "SPKR_VI_2", "VIINPUT"}, - {"AIF4 VI", NULL, "AIF4_VI Mixer"}, -}; - -const struct snd_soc_dapm_route pahu_audio_map[] = { - - /* Virtual input widgets */ - {"AIF1 CAP", NULL, "AIF1_CAP Mixer"}, - {"AIF2 CAP", NULL, "AIF2_CAP Mixer"}, - {"AIF3 CAP", NULL, "AIF3_CAP Mixer"}, - - /* WDMA3 */ - {"WDMA3 PORT0 MUX", "DEC0", "ADC MUX0"}, - {"WDMA3 PORT0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"}, - {"WDMA3 PORT1 MUX", "DEC1", "ADC MUX1"}, - {"WDMA3 PORT1 MUX", "RX_MIX_TX1", "RX MIX TX1 MUX"}, - {"WDMA3 PORT2 MUX", "DEC2", "ADC MUX2"}, - {"WDMA3 PORT2 MUX", "RX_MIX_TX2", "RX MIX TX2 MUX"}, - {"WDMA3 PORT3 MUX", "DEC3", "ADC MUX3"}, - {"WDMA3 PORT3 MUX", "RX_MIX_TX3", "RX MIX TX3 MUX"}, - {"WDMA3 PORT4 MUX", "DEC4", "ADC MUX4"}, - {"WDMA3 PORT4 MUX", "RX_MIX_TX4", "RX MIX TX4 MUX"}, - {"WDMA3 PORT5 MUX", "DEC5", "ADC MUX5"}, - {"WDMA3 PORT5 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"}, - {"WDMA3 PORT6 MUX", "DEC6", "ADC MUX6"}, - {"WDMA3 PORT6 MUX", "RX_MIX_TX6", "RX MIX TX6 MUX"}, - - {"WDMA3 CH0 MUX", "PORT_0", "WDMA3 PORT0 MUX"}, - {"WDMA3 CH0 MUX", "PORT_1", "WDMA3 PORT1 MUX"}, - {"WDMA3 CH0 MUX", "PORT_2", "WDMA3 PORT2 MUX"}, - {"WDMA3 CH0 MUX", "PORT_3", "WDMA3 PORT3 MUX"}, - {"WDMA3 CH0 MUX", "PORT_4", "WDMA3 PORT4 MUX"}, - {"WDMA3 CH0 MUX", "PORT_5", "WDMA3 PORT5 MUX"}, - {"WDMA3 CH0 MUX", "PORT_6", "WDMA3 PORT6 MUX"}, - {"WDMA3 CH0 MUX", "PORT_7", "ADC MUX7"}, - {"WDMA3 CH0 MUX", "PORT_8", "ADC MUX8"}, - - {"WDMA3 CH1 MUX", "PORT_0", "WDMA3 PORT0 MUX"}, - {"WDMA3 CH1 MUX", "PORT_1", "WDMA3 PORT1 MUX"}, - {"WDMA3 CH1 MUX", "PORT_2", "WDMA3 PORT2 MUX"}, - {"WDMA3 CH1 MUX", "PORT_3", "WDMA3 PORT3 MUX"}, - {"WDMA3 CH1 MUX", "PORT_4", "WDMA3 PORT4 MUX"}, - {"WDMA3 CH1 MUX", "PORT_5", "WDMA3 PORT5 MUX"}, - {"WDMA3 CH1 MUX", "PORT_6", "WDMA3 PORT6 MUX"}, - {"WDMA3 CH1 MUX", "PORT_7", "ADC MUX7"}, - {"WDMA3 CH1 MUX", "PORT_8", "ADC MUX8"}, - - {"WDMA3 CH2 MUX", "PORT_0", "WDMA3 PORT0 MUX"}, - {"WDMA3 CH2 MUX", "PORT_1", "WDMA3 PORT1 MUX"}, - {"WDMA3 CH2 MUX", "PORT_2", "WDMA3 PORT2 MUX"}, - {"WDMA3 CH2 MUX", "PORT_3", "WDMA3 PORT3 MUX"}, - {"WDMA3 CH2 MUX", "PORT_4", "WDMA3 PORT4 MUX"}, - {"WDMA3 CH2 MUX", "PORT_5", "WDMA3 PORT5 MUX"}, - {"WDMA3 CH2 MUX", "PORT_6", "WDMA3 PORT6 MUX"}, - {"WDMA3 CH2 MUX", "PORT_7", "ADC MUX7"}, - {"WDMA3 CH2 MUX", "PORT_8", "ADC MUX8"}, - - {"WDMA3 CH3 MUX", "PORT_0", "WDMA3 PORT0 MUX"}, - {"WDMA3 CH3 MUX", "PORT_1", "WDMA3 PORT1 MUX"}, - {"WDMA3 CH3 MUX", "PORT_2", "WDMA3 PORT2 MUX"}, - {"WDMA3 CH3 MUX", "PORT_3", "WDMA3 PORT3 MUX"}, - {"WDMA3 CH3 MUX", "PORT_4", "WDMA3 PORT4 MUX"}, - {"WDMA3 CH3 MUX", "PORT_5", "WDMA3 PORT5 MUX"}, - {"WDMA3 CH3 MUX", "PORT_6", "WDMA3 PORT6 MUX"}, - {"WDMA3 CH3 MUX", "PORT_7", "ADC MUX7"}, - {"WDMA3 CH3 MUX", "PORT_8", "ADC MUX8"}, - - {"WDMA3_CH_MIXER", NULL, "WDMA3 CH0 MUX"}, - {"WDMA3_CH_MIXER", NULL, "WDMA3 CH1 MUX"}, - {"WDMA3_CH_MIXER", NULL, "WDMA3 CH2 MUX"}, - {"WDMA3_CH_MIXER", NULL, "WDMA3 CH3 MUX"}, - - {"WDMA3_ON_OFF", "Switch", "WDMA3_CH_MIXER"}, - {"WDMA3_OUT", NULL, "WDMA3_ON_OFF"}, - - /* MAD */ - {"MAD_SEL MUX", "SPE", "MAD_CPE_INPUT"}, - {"MAD_SEL MUX", "MSM", "MADINPUT"}, - - {"MAD_INP MUX", "MAD", "MAD_SEL MUX"}, - {"MAD_INP MUX", "DEC1", "ADC MUX1"}, - - {"MAD_BROADCAST", "Switch", "MAD_INP MUX"}, - {"MAD_CPE1", "Switch", "MAD_INP MUX"}, - {"MAD_CPE2", "Switch", "MAD_INP MUX"}, - - {"MAD_CPE_OUT1", NULL, "MAD_CPE1"}, - {"MAD_CPE_OUT2", NULL, "MAD_CPE2"}, - - {"CDC_IF TX0 MUX", "DEC0", "ADC MUX0"}, - {"CDC_IF TX0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"}, - {"CDC_IF TX0 MUX", "DEC0_192", "ADC US MUX0"}, - - {"CDC_IF TX1 MUX", "DEC1", "ADC MUX1"}, - {"CDC_IF TX1 MUX", "RX_MIX_TX1", "RX MIX TX1 MUX"}, - {"CDC_IF TX1 MUX", "DEC1_192", "ADC US MUX1"}, - - {"CDC_IF TX2 MUX", "DEC2", "ADC MUX2"}, - {"CDC_IF TX2 MUX", "RX_MIX_TX2", "RX MIX TX2 MUX"}, - {"CDC_IF TX2 MUX", "DEC2_192", "ADC US MUX2"}, - - {"CDC_IF TX3 MUX", "DEC3", "ADC MUX3"}, - {"CDC_IF TX3 MUX", "RX_MIX_TX3", "RX MIX TX3 MUX"}, - {"CDC_IF TX3 MUX", "DEC3_192", "ADC US MUX3"}, - - {"CDC_IF TX4 MUX", "DEC4", "ADC MUX4"}, - {"CDC_IF TX4 MUX", "RX_MIX_TX4", "RX MIX TX4 MUX"}, - {"CDC_IF TX4 MUX", "DEC4_192", "ADC US MUX4"}, - - {"CDC_IF TX5 MUX", "DEC5", "ADC MUX5"}, - {"CDC_IF TX5 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"}, - {"CDC_IF TX5 MUX", "DEC5_192", "ADC US MUX5"}, - - {"CDC_IF TX6 MUX", "DEC6", "ADC MUX6"}, - {"CDC_IF TX6 MUX", "RX_MIX_TX6", "RX MIX TX6 MUX"}, - {"CDC_IF TX6 MUX", "DEC6_192", "ADC US MUX6"}, - - {"CDC_IF TX7 MUX", "DEC7", "ADC MUX7"}, - {"CDC_IF TX7 MUX", "RX_MIX_TX7", "RX MIX TX7 MUX"}, - {"CDC_IF TX7 MUX", "DEC7_192", "ADC US MUX7"}, - - {"CDC_IF TX8 MUX", "DEC8", "ADC MUX8"}, - {"CDC_IF TX8 MUX", "RX_MIX_TX8", "RX MIX TX8 MUX"}, - {"CDC_IF TX8 MUX", "DEC8_192", "ADC US MUX8"}, - - {"CDC_IF TX9 MUX", "DEC7", "ADC MUX7"}, - {"CDC_IF TX9 MUX", "DEC7_192", "ADC US MUX7"}, - {"CDC_IF TX10 MUX", "DEC6", "ADC MUX6"}, - {"CDC_IF TX10 MUX", "DEC6_192", "ADC US MUX6"}, - {"CDC_IF TX10 MUX2", "TX10_MUX1", "CDC_IF TX10 MUX"}, - - {"CDC_IF TX11 MUX2", "TX11_MUX1", "CDC_IF TX11 MUX"}, - {"CDC_IF TX11 MUX", "DEC_0_5", "CDC_IF TX11 INP1 MUX"}, - {"CDC_IF TX11 MUX", "DEC_9_12", "CDC_IF TX11 INP1 MUX"}, - {"CDC_IF TX11 INP1 MUX", "DEC0", "ADC MUX0"}, - {"CDC_IF TX11 INP1 MUX", "DEC1", "ADC MUX1"}, - {"CDC_IF TX11 INP1 MUX", "DEC2", "ADC MUX2"}, - {"CDC_IF TX11 INP1 MUX", "DEC3", "ADC MUX3"}, - {"CDC_IF TX11 INP1 MUX", "DEC4", "ADC MUX4"}, - {"CDC_IF TX11 INP1 MUX", "DEC5", "ADC MUX5"}, - {"CDC_IF TX11 INP1 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"}, - - {"CDC_IF TX13 MUX", "MAD_BRDCST", "MAD_BROADCAST"}, - {"CDC_IF TX13 MUX", "CDC_DEC_5", "CDC_IF TX13 INP1 MUX"}, - {"CDC_IF TX13 INP1 MUX", "DEC5", "ADC MUX5"}, - {"CDC_IF TX13 INP1 MUX", "DEC5_192", "ADC US MUX5"}, - - {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, - {"RX MIX TX0 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, - {"RX MIX TX0 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, - {"RX MIX TX0 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, - - {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, - {"RX MIX TX1 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, - {"RX MIX TX1 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, - {"RX MIX TX1 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, - - {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, - {"RX MIX TX2 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, - {"RX MIX TX2 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, - {"RX MIX TX2 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, - - {"RX MIX TX3 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, - {"RX MIX TX3 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, - {"RX MIX TX3 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, - {"RX MIX TX3 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, - - {"RX MIX TX4 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, - {"RX MIX TX4 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, - {"RX MIX TX4 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, - {"RX MIX TX4 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, - - {"RX MIX TX5 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, - {"RX MIX TX5 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, - {"RX MIX TX5 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, - {"RX MIX TX5 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, - - {"RX MIX TX6 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, - {"RX MIX TX6 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, - {"RX MIX TX6 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, - {"RX MIX TX6 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, - - {"RX MIX TX7 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, - {"RX MIX TX7 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, - {"RX MIX TX7 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, - {"RX MIX TX7 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, - - {"RX MIX TX8 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, - {"RX MIX TX8 MUX", "RX_MIX7", "RX INT7 SEC MIX"}, - {"RX MIX TX8 MUX", "RX_MIX8", "RX INT8 SEC MIX"}, - {"RX MIX TX8 MUX", "RX_MIX9", "RX INT9 SEC MIX"}, - - {"ADC US MUX0", "US_Switch", "ADC MUX0"}, - {"ADC US MUX1", "US_Switch", "ADC MUX1"}, - {"ADC US MUX2", "US_Switch", "ADC MUX2"}, - {"ADC US MUX3", "US_Switch", "ADC MUX3"}, - {"ADC US MUX4", "US_Switch", "ADC MUX4"}, - {"ADC US MUX5", "US_Switch", "ADC MUX5"}, - {"ADC US MUX6", "US_Switch", "ADC MUX6"}, - {"ADC US MUX7", "US_Switch", "ADC MUX7"}, - {"ADC US MUX8", "US_Switch", "ADC MUX8"}, - - {"ADC MUX0", "DMIC", "DMIC MUX0"}, - {"ADC MUX0", "AMIC", "AMIC MUX0"}, - {"ADC MUX1", "DMIC", "DMIC MUX1"}, - {"ADC MUX1", "AMIC", "AMIC MUX1"}, - {"ADC MUX2", "DMIC", "DMIC MUX2"}, - {"ADC MUX2", "AMIC", "AMIC MUX2"}, - {"ADC MUX3", "DMIC", "DMIC MUX3"}, - {"ADC MUX3", "AMIC", "AMIC MUX3"}, - {"ADC MUX4", "DMIC", "DMIC MUX4"}, - {"ADC MUX4", "AMIC", "AMIC MUX4"}, - {"ADC MUX5", "DMIC", "DMIC MUX5"}, - {"ADC MUX5", "AMIC", "AMIC MUX5"}, - {"ADC MUX6", "DMIC", "DMIC MUX6"}, - {"ADC MUX6", "AMIC", "AMIC MUX6"}, - {"ADC MUX7", "DMIC", "DMIC MUX7"}, - {"ADC MUX7", "AMIC", "AMIC MUX7"}, - {"ADC MUX8", "DMIC", "DMIC MUX8"}, - {"ADC MUX8", "AMIC", "AMIC MUX8"}, - {"ADC MUX10", "DMIC", "DMIC MUX10"}, - {"ADC MUX10", "AMIC", "AMIC MUX10"}, - {"ADC MUX11", "DMIC", "DMIC MUX11"}, - {"ADC MUX11", "AMIC", "AMIC MUX11"}, - - {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX10"}, - {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX11"}, - {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX10"}, - {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX11"}, - {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX10"}, - {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX11"}, - {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX10"}, - {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX11"}, - {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX10"}, - {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX11"}, - {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX10"}, - {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX11"}, - {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX10"}, - {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX11"}, - {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX10"}, - {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX11"}, - {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX10"}, - {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX11"}, - - {"DMIC MUX0", "DMIC0", "DMIC0"}, - {"DMIC MUX0", "DMIC1", "DMIC1"}, - {"DMIC MUX0", "DMIC2", "DMIC2"}, - {"DMIC MUX0", "DMIC3", "DMIC3"}, - {"DMIC MUX0", "DMIC4", "DMIC4"}, - {"DMIC MUX0", "DMIC5", "DMIC5"}, - {"DMIC MUX0", "DMIC6", "DMIC6"}, - {"DMIC MUX0", "DMIC7", "DMIC7"}, - {"AMIC MUX0", "ADC1", "ADC1"}, - {"AMIC MUX0", "ADC2", "ADC2"}, - {"AMIC MUX0", "ADC3", "ADC3"}, - {"AMIC MUX0", "ADC4", "ADC4"}, - - {"DMIC MUX1", "DMIC0", "DMIC0"}, - {"DMIC MUX1", "DMIC1", "DMIC1"}, - {"DMIC MUX1", "DMIC2", "DMIC2"}, - {"DMIC MUX1", "DMIC3", "DMIC3"}, - {"DMIC MUX1", "DMIC4", "DMIC4"}, - {"DMIC MUX1", "DMIC5", "DMIC5"}, - {"DMIC MUX1", "DMIC6", "DMIC6"}, - {"DMIC MUX1", "DMIC7", "DMIC7"}, - {"AMIC MUX1", "ADC1", "ADC1"}, - {"AMIC MUX1", "ADC2", "ADC2"}, - {"AMIC MUX1", "ADC3", "ADC3"}, - {"AMIC MUX1", "ADC4", "ADC4"}, - - {"DMIC MUX2", "DMIC0", "DMIC0"}, - {"DMIC MUX2", "DMIC1", "DMIC1"}, - {"DMIC MUX2", "DMIC2", "DMIC2"}, - {"DMIC MUX2", "DMIC3", "DMIC3"}, - {"DMIC MUX2", "DMIC4", "DMIC4"}, - {"DMIC MUX2", "DMIC5", "DMIC5"}, - {"DMIC MUX2", "DMIC6", "DMIC6"}, - {"DMIC MUX2", "DMIC7", "DMIC7"}, - {"AMIC MUX2", "ADC1", "ADC1"}, - {"AMIC MUX2", "ADC2", "ADC2"}, - {"AMIC MUX2", "ADC3", "ADC3"}, - {"AMIC MUX2", "ADC4", "ADC4"}, - - {"DMIC MUX3", "DMIC0", "DMIC0"}, - {"DMIC MUX3", "DMIC1", "DMIC1"}, - {"DMIC MUX3", "DMIC2", "DMIC2"}, - {"DMIC MUX3", "DMIC3", "DMIC3"}, - {"DMIC MUX3", "DMIC4", "DMIC4"}, - {"DMIC MUX3", "DMIC5", "DMIC5"}, - {"DMIC MUX3", "DMIC6", "DMIC6"}, - {"DMIC MUX3", "DMIC7", "DMIC7"}, - {"AMIC MUX3", "ADC1", "ADC1"}, - {"AMIC MUX3", "ADC2", "ADC2"}, - {"AMIC MUX3", "ADC3", "ADC3"}, - {"AMIC MUX3", "ADC4", "ADC4"}, - - {"DMIC MUX4", "DMIC0", "DMIC0"}, - {"DMIC MUX4", "DMIC1", "DMIC1"}, - {"DMIC MUX4", "DMIC2", "DMIC2"}, - {"DMIC MUX4", "DMIC3", "DMIC3"}, - {"DMIC MUX4", "DMIC4", "DMIC4"}, - {"DMIC MUX4", "DMIC5", "DMIC5"}, - {"DMIC MUX4", "DMIC6", "DMIC6"}, - {"DMIC MUX4", "DMIC7", "DMIC7"}, - {"AMIC MUX4", "ADC1", "ADC1"}, - {"AMIC MUX4", "ADC2", "ADC2"}, - {"AMIC MUX4", "ADC3", "ADC3"}, - {"AMIC MUX4", "ADC4", "ADC4"}, - - {"DMIC MUX5", "DMIC0", "DMIC0"}, - {"DMIC MUX5", "DMIC1", "DMIC1"}, - {"DMIC MUX5", "DMIC2", "DMIC2"}, - {"DMIC MUX5", "DMIC3", "DMIC3"}, - {"DMIC MUX5", "DMIC4", "DMIC4"}, - {"DMIC MUX5", "DMIC5", "DMIC5"}, - {"DMIC MUX5", "DMIC6", "DMIC6"}, - {"DMIC MUX5", "DMIC7", "DMIC7"}, - {"AMIC MUX5", "ADC1", "ADC1"}, - {"AMIC MUX5", "ADC2", "ADC2"}, - {"AMIC MUX5", "ADC3", "ADC3"}, - {"AMIC MUX5", "ADC4", "ADC4"}, - - {"DMIC MUX6", "DMIC0", "DMIC0"}, - {"DMIC MUX6", "DMIC1", "DMIC1"}, - {"DMIC MUX6", "DMIC2", "DMIC2"}, - {"DMIC MUX6", "DMIC3", "DMIC3"}, - {"DMIC MUX6", "DMIC4", "DMIC4"}, - {"DMIC MUX6", "DMIC5", "DMIC5"}, - {"DMIC MUX6", "DMIC6", "DMIC6"}, - {"DMIC MUX6", "DMIC7", "DMIC7"}, - {"AMIC MUX6", "ADC1", "ADC1"}, - {"AMIC MUX6", "ADC2", "ADC2"}, - {"AMIC MUX6", "ADC3", "ADC3"}, - {"AMIC MUX6", "ADC4", "ADC4"}, - - {"DMIC MUX7", "DMIC0", "DMIC0"}, - {"DMIC MUX7", "DMIC1", "DMIC1"}, - {"DMIC MUX7", "DMIC2", "DMIC2"}, - {"DMIC MUX7", "DMIC3", "DMIC3"}, - {"DMIC MUX7", "DMIC4", "DMIC4"}, - {"DMIC MUX7", "DMIC5", "DMIC5"}, - {"DMIC MUX7", "DMIC6", "DMIC6"}, - {"DMIC MUX7", "DMIC7", "DMIC7"}, - {"AMIC MUX7", "ADC1", "ADC1"}, - {"AMIC MUX7", "ADC2", "ADC2"}, - {"AMIC MUX7", "ADC3", "ADC3"}, - {"AMIC MUX7", "ADC4", "ADC4"}, - - {"DMIC MUX8", "DMIC0", "DMIC0"}, - {"DMIC MUX8", "DMIC1", "DMIC1"}, - {"DMIC MUX8", "DMIC2", "DMIC2"}, - {"DMIC MUX8", "DMIC3", "DMIC3"}, - {"DMIC MUX8", "DMIC4", "DMIC4"}, - {"DMIC MUX8", "DMIC5", "DMIC5"}, - {"DMIC MUX8", "DMIC6", "DMIC6"}, - {"DMIC MUX8", "DMIC7", "DMIC7"}, - {"AMIC MUX8", "ADC1", "ADC1"}, - {"AMIC MUX8", "ADC2", "ADC2"}, - {"AMIC MUX8", "ADC3", "ADC3"}, - {"AMIC MUX8", "ADC4", "ADC4"}, - - {"DMIC MUX10", "DMIC0", "DMIC0"}, - {"DMIC MUX10", "DMIC1", "DMIC1"}, - {"DMIC MUX10", "DMIC2", "DMIC2"}, - {"DMIC MUX10", "DMIC3", "DMIC3"}, - {"DMIC MUX10", "DMIC4", "DMIC4"}, - {"DMIC MUX10", "DMIC5", "DMIC5"}, - {"DMIC MUX10", "DMIC6", "DMIC6"}, - {"DMIC MUX10", "DMIC7", "DMIC7"}, - {"AMIC MUX10", "ADC1", "ADC1"}, - {"AMIC MUX10", "ADC2", "ADC2"}, - {"AMIC MUX10", "ADC3", "ADC3"}, - {"AMIC MUX10", "ADC4", "ADC4"}, - - {"DMIC MUX11", "DMIC0", "DMIC0"}, - {"DMIC MUX11", "DMIC1", "DMIC1"}, - {"DMIC MUX11", "DMIC2", "DMIC2"}, - {"DMIC MUX11", "DMIC3", "DMIC3"}, - {"DMIC MUX11", "DMIC4", "DMIC4"}, - {"DMIC MUX11", "DMIC5", "DMIC5"}, - {"DMIC MUX11", "DMIC6", "DMIC6"}, - {"DMIC MUX11", "DMIC7", "DMIC7"}, - {"AMIC MUX11", "ADC1", "ADC1"}, - {"AMIC MUX11", "ADC2", "ADC2"}, - {"AMIC MUX11", "ADC3", "ADC3"}, - {"AMIC MUX11", "ADC4", "ADC4"}, - - {"ADC2_IN", "AMIC1", "AMIC1"}, - {"ADC2_IN", "AMIC2", "AMIC2"}, - {"ADC4_IN", "AMIC3", "AMIC3"}, - {"ADC4_IN", "AMIC4", "AMIC4"}, - - {"ADC1", NULL, "AMIC1"}, - {"ADC2", NULL, "ADC2_IN"}, - {"ADC3", NULL, "AMIC3"}, - {"ADC4", NULL, "ADC4_IN"}, - - {"ADC1", NULL, "LDO_RXTX"}, - {"ADC2", NULL, "LDO_RXTX"}, - {"ADC3", NULL, "LDO_RXTX"}, - {"ADC4", NULL, "LDO_RXTX"}, - - {"RX INT0_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"}, - {"RX INT0_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"}, - {"RX INT0_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"}, - {"RX INT0_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"}, - {"RX INT0_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"}, - {"RX INT0_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"}, - {"RX INT0_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"}, - {"RX INT0_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"}, - {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"}, - {"RX INT0_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"}, - {"RX INT0_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"}, - {"RX INT0_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"}, - {"RX INT0_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"}, - {"RX INT0_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"}, - {"RX INT0_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"}, - {"RX INT0_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"}, - {"RX INT0_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"}, - {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"}, - {"RX INT0_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"}, - {"RX INT0_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"}, - {"RX INT0_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"}, - {"RX INT0_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"}, - {"RX INT0_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"}, - {"RX INT0_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"}, - {"RX INT0_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"}, - {"RX INT0_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"}, - {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"}, - - {"RX INT7_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"}, - {"RX INT7_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"}, - {"RX INT7_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"}, - {"RX INT7_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"}, - {"RX INT7_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"}, - {"RX INT7_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"}, - {"RX INT7_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"}, - {"RX INT7_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"}, - {"RX INT7_1 MIX1 INP0", "IIR0", "IIR0"}, - {"RX INT7_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"}, - {"RX INT7_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"}, - {"RX INT7_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"}, - {"RX INT7_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"}, - {"RX INT7_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"}, - {"RX INT7_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"}, - {"RX INT7_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"}, - {"RX INT7_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"}, - {"RX INT7_1 MIX1 INP1", "IIR0", "IIR0"}, - {"RX INT7_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"}, - {"RX INT7_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"}, - {"RX INT7_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"}, - {"RX INT7_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"}, - {"RX INT7_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"}, - {"RX INT7_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"}, - {"RX INT7_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"}, - {"RX INT7_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"}, - {"RX INT7_1 MIX1 INP2", "IIR0", "IIR0"}, - - {"RX INT8_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"}, - {"RX INT8_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"}, - {"RX INT8_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"}, - {"RX INT8_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"}, - {"RX INT8_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"}, - {"RX INT8_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"}, - {"RX INT8_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"}, - {"RX INT8_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"}, - {"RX INT8_1 MIX1 INP0", "IIR0", "IIR0"}, - {"RX INT8_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"}, - {"RX INT8_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"}, - {"RX INT8_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"}, - {"RX INT8_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"}, - {"RX INT8_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"}, - {"RX INT8_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"}, - {"RX INT8_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"}, - {"RX INT8_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"}, - {"RX INT8_1 MIX1 INP1", "IIR0", "IIR0"}, - {"RX INT8_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"}, - {"RX INT8_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"}, - {"RX INT8_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"}, - {"RX INT8_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"}, - {"RX INT8_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"}, - {"RX INT8_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"}, - {"RX INT8_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"}, - {"RX INT8_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"}, - {"RX INT8_1 MIX1 INP2", "IIR0", "IIR0"}, - - {"RX INT9_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"}, - {"RX INT9_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"}, - {"RX INT9_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"}, - {"RX INT9_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"}, - {"RX INT9_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"}, - {"RX INT9_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"}, - {"RX INT9_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"}, - {"RX INT9_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"}, - {"RX INT9_1 MIX1 INP0", "IIR0", "IIR0"}, - {"RX INT9_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"}, - {"RX INT9_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"}, - {"RX INT9_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"}, - {"RX INT9_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"}, - {"RX INT9_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"}, - {"RX INT9_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"}, - {"RX INT9_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"}, - {"RX INT9_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"}, - {"RX INT9_1 MIX1 INP1", "IIR0", "IIR0"}, - {"RX INT9_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"}, - {"RX INT9_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"}, - {"RX INT9_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"}, - {"RX INT9_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"}, - {"RX INT9_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"}, - {"RX INT9_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"}, - {"RX INT9_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"}, - {"RX INT9_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"}, - {"RX INT9_1 MIX1 INP2", "IIR0", "IIR0"}, - - {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"}, - {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"}, - {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"}, - {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP0"}, - {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP1"}, - {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP2"}, - {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP0"}, - {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP1"}, - {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP2"}, - {"RX INT9_1 MIX1", NULL, "RX INT9_1 MIX1 INP0"}, - {"RX INT9_1 MIX1", NULL, "RX INT9_1 MIX1 INP1"}, - {"RX INT9_1 MIX1", NULL, "RX INT9_1 MIX1 INP2"}, - - /* Mixing path INT0 */ - {"RX INT0_2 MUX", "RX0", "CDC_IF RX0 MUX"}, - {"RX INT0_2 MUX", "RX1", "CDC_IF RX1 MUX"}, - {"RX INT0_2 MUX", "RX2", "CDC_IF RX2 MUX"}, - {"RX INT0_2 MUX", "RX3", "CDC_IF RX3 MUX"}, - {"RX INT0_2 MUX", "RX4", "CDC_IF RX4 MUX"}, - {"RX INT0_2 MUX", "RX5", "CDC_IF RX5 MUX"}, - {"RX INT0_2 MUX", "RX6", "CDC_IF RX6 MUX"}, - {"RX INT0_2 MUX", "RX7", "CDC_IF RX7 MUX"}, - {"RX INT0_2 INTERP", NULL, "RX INT0_2 MUX"}, - {"RX INT0 SEC MIX", NULL, "RX INT0_2 INTERP"}, - - /* Mixing path INT7 */ - {"RX INT7_2 MUX", "RX0", "CDC_IF RX0 MUX"}, - {"RX INT7_2 MUX", "RX1", "CDC_IF RX1 MUX"}, - {"RX INT7_2 MUX", "RX2", "CDC_IF RX2 MUX"}, - {"RX INT7_2 MUX", "RX3", "CDC_IF RX3 MUX"}, - {"RX INT7_2 MUX", "RX4", "CDC_IF RX4 MUX"}, - {"RX INT7_2 MUX", "RX5", "CDC_IF RX5 MUX"}, - {"RX INT7_2 MUX", "RX6", "CDC_IF RX6 MUX"}, - {"RX INT7_2 MUX", "RX7", "CDC_IF RX7 MUX"}, - {"RX INT7_2 INTERP", NULL, "RX INT7_2 MUX"}, - {"RX INT7 SEC MIX", NULL, "RX INT7_2 INTERP"}, - - /* Mixing path INT8 */ - {"RX INT8_2 MUX", "RX0", "CDC_IF RX0 MUX"}, - {"RX INT8_2 MUX", "RX1", "CDC_IF RX1 MUX"}, - {"RX INT8_2 MUX", "RX2", "CDC_IF RX2 MUX"}, - {"RX INT8_2 MUX", "RX3", "CDC_IF RX3 MUX"}, - {"RX INT8_2 MUX", "RX4", "CDC_IF RX4 MUX"}, - {"RX INT8_2 MUX", "RX5", "CDC_IF RX5 MUX"}, - {"RX INT8_2 MUX", "RX6", "CDC_IF RX6 MUX"}, - {"RX INT8_2 MUX", "RX7", "CDC_IF RX7 MUX"}, - {"RX INT8_2 INTERP", NULL, "RX INT8_2 MUX"}, - {"RX INT8 SEC MIX", NULL, "RX INT8_2 INTERP"}, - - /* Mixing path INT9 */ - {"RX INT9_2 MUX", "RX0", "CDC_IF RX0 MUX"}, - {"RX INT9_2 MUX", "RX1", "CDC_IF RX1 MUX"}, - {"RX INT9_2 MUX", "RX2", "CDC_IF RX2 MUX"}, - {"RX INT9_2 MUX", "RX3", "CDC_IF RX3 MUX"}, - {"RX INT9_2 MUX", "RX4", "CDC_IF RX4 MUX"}, - {"RX INT9_2 MUX", "RX5", "CDC_IF RX5 MUX"}, - {"RX INT9_2 MUX", "RX6", "CDC_IF RX6 MUX"}, - {"RX INT9_2 MUX", "RX7", "CDC_IF RX7 MUX"}, - {"RX INT9_2 INTERP", NULL, "RX INT9_2 MUX"}, - {"RX INT9 SEC MIX", NULL, "RX INT9_2 INTERP"}, - - {"RX INT0_1 INTERP", NULL, "RX INT0_1 MIX1"}, - {"RX INT0 SEC MIX", NULL, "RX INT0_1 INTERP"}, - {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"}, - {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"}, - {"RX INT0 DEM MUX", NULL, "RX INT0 MIX2"}, - {"RX INT0 DAC", NULL, "RX INT0 DEM MUX"}, - {"RX INT0 DAC", NULL, "LDO_RXTX"}, - {"EAR PA", NULL, "RX INT0 DAC"}, - {"EAR", NULL, "EAR PA"}, - - {"RX INT7_1 INTERP", NULL, "RX INT7_1 MIX1"}, - {"RX INT7 SEC MIX", NULL, "RX INT7_1 INTERP"}, - {"RX INT7 MIX2", NULL, "RX INT7 SEC MIX"}, - {"RX INT7 MIX2", NULL, "RX INT7 MIX2 INP"}, - {"RX INT7 CHAIN", NULL, "RX INT7 MIX2"}, - {"SPK1 OUT", NULL, "RX INT7 CHAIN"}, - - {"RX INT8_1 INTERP", NULL, "RX INT8_1 MIX1"}, - {"RX INT8 SEC MIX", NULL, "RX INT8_1 INTERP"}, - {"RX INT8 SEC MIX", NULL, "RX INT8_1 MIX1"}, - {"RX INT8 CHAIN", NULL, "RX INT8 SEC MIX"}, - {"SPK2 OUT", NULL, "RX INT8 CHAIN"}, - - {"RX INT9_1 INTERP", NULL, "RX INT9_1 MIX1"}, - {"RX INT9 SEC MIX", NULL, "RX INT9_1 INTERP"}, - {"RX INT9 MIX2", NULL, "RX INT9 SEC MIX"}, - {"RX INT9 MIX2", NULL, "RX INT9 MIX2 INP"}, - {"RX INT9 DEM MUX", NULL, "RX INT9 MIX2"}, - {"RX INT9 DAC", NULL, "RX INT9 DEM MUX"}, - {"RX INT9 DAC", NULL, "LDO_RXTX"}, - {"AUX PA", NULL, "RX INT9 DAC"}, - {"AUX", NULL, "AUX PA"}, - - /* ANC Routing */ - {"ANC0 FB MUX", "ANC_IN_EAR", "RX INT0 MIX2"}, - {"ANC0 FB MUX", "ANC_IN_EAR_SPKR", "RX INT7 MIX2"}, - - {"ANC OUT EAR Enable", "Switch", "ADC MUX10"}, - {"ANC OUT EAR Enable", "Switch", "ADC MUX11"}, - {"RX INT0 MIX2", NULL, "ANC OUT EAR Enable"}, - - {"ANC EAR PA", NULL, "RX INT0 DAC"}, - {"ANC EAR", NULL, "ANC EAR PA"}, - - {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX10"}, - {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX11"}, - {"RX INT7 MIX2", NULL, "ANC OUT EAR SPKR Enable"}, - - {"ANC SPKR PA Enable", "Switch", "RX INT7 CHAIN"}, - {"ANC SPK1 PA", NULL, "ANC SPKR PA Enable"}, - {"SPK1 OUT", NULL, "ANC SPK1 PA"}, - - /* - * SRC0 input to Sidetone RX Mixer - * on RX0, RX1, RX2, RX3, RX4 and RX7 chains - */ - {"IIR0", NULL, "IIR0 INP0 MUX"}, - {"IIR0 INP0 MUX", "DEC0", "ADC MUX0"}, - {"IIR0 INP0 MUX", "DEC1", "ADC MUX1"}, - {"IIR0 INP0 MUX", "DEC2", "ADC MUX2"}, - {"IIR0 INP0 MUX", "DEC3", "ADC MUX3"}, - {"IIR0 INP0 MUX", "DEC4", "ADC MUX4"}, - {"IIR0 INP0 MUX", "DEC5", "ADC MUX5"}, - {"IIR0 INP0 MUX", "DEC6", "ADC MUX6"}, - {"IIR0 INP0 MUX", "DEC7", "ADC MUX7"}, - {"IIR0 INP0 MUX", "DEC8", "ADC MUX8"}, - {"IIR0 INP0 MUX", "RX0", "CDC_IF RX0 MUX"}, - {"IIR0 INP0 MUX", "RX1", "CDC_IF RX1 MUX"}, - {"IIR0 INP0 MUX", "RX2", "CDC_IF RX2 MUX"}, - {"IIR0 INP0 MUX", "RX3", "CDC_IF RX3 MUX"}, - {"IIR0 INP0 MUX", "RX4", "CDC_IF RX4 MUX"}, - {"IIR0 INP0 MUX", "RX5", "CDC_IF RX5 MUX"}, - {"IIR0 INP0 MUX", "RX6", "CDC_IF RX6 MUX"}, - {"IIR0 INP0 MUX", "RX7", "CDC_IF RX7 MUX"}, - {"IIR0", NULL, "IIR0 INP1 MUX"}, - {"IIR0 INP1 MUX", "DEC0", "ADC MUX0"}, - {"IIR0 INP1 MUX", "DEC1", "ADC MUX1"}, - {"IIR0 INP1 MUX", "DEC2", "ADC MUX2"}, - {"IIR0 INP1 MUX", "DEC3", "ADC MUX3"}, - {"IIR0 INP1 MUX", "DEC4", "ADC MUX4"}, - {"IIR0 INP1 MUX", "DEC5", "ADC MUX5"}, - {"IIR0 INP1 MUX", "DEC6", "ADC MUX6"}, - {"IIR0 INP1 MUX", "DEC7", "ADC MUX7"}, - {"IIR0 INP1 MUX", "DEC8", "ADC MUX8"}, - {"IIR0 INP1 MUX", "RX0", "CDC_IF RX0 MUX"}, - {"IIR0 INP1 MUX", "RX1", "CDC_IF RX1 MUX"}, - {"IIR0 INP1 MUX", "RX2", "CDC_IF RX2 MUX"}, - {"IIR0 INP1 MUX", "RX3", "CDC_IF RX3 MUX"}, - {"IIR0 INP1 MUX", "RX4", "CDC_IF RX4 MUX"}, - {"IIR0 INP1 MUX", "RX5", "CDC_IF RX5 MUX"}, - {"IIR0 INP1 MUX", "RX6", "CDC_IF RX6 MUX"}, - {"IIR0 INP1 MUX", "RX7", "CDC_IF RX7 MUX"}, - {"IIR0", NULL, "IIR0 INP2 MUX"}, - {"IIR0 INP2 MUX", "DEC0", "ADC MUX0"}, - {"IIR0 INP2 MUX", "DEC1", "ADC MUX1"}, - {"IIR0 INP2 MUX", "DEC2", "ADC MUX2"}, - {"IIR0 INP2 MUX", "DEC3", "ADC MUX3"}, - {"IIR0 INP2 MUX", "DEC4", "ADC MUX4"}, - {"IIR0 INP2 MUX", "DEC5", "ADC MUX5"}, - {"IIR0 INP2 MUX", "DEC6", "ADC MUX6"}, - {"IIR0 INP2 MUX", "DEC7", "ADC MUX7"}, - {"IIR0 INP2 MUX", "DEC8", "ADC MUX8"}, - {"IIR0 INP2 MUX", "RX0", "CDC_IF RX0 MUX"}, - {"IIR0 INP2 MUX", "RX1", "CDC_IF RX1 MUX"}, - {"IIR0 INP2 MUX", "RX2", "CDC_IF RX2 MUX"}, - {"IIR0 INP2 MUX", "RX3", "CDC_IF RX3 MUX"}, - {"IIR0 INP2 MUX", "RX4", "CDC_IF RX4 MUX"}, - {"IIR0 INP2 MUX", "RX5", "CDC_IF RX5 MUX"}, - {"IIR0 INP2 MUX", "RX6", "CDC_IF RX6 MUX"}, - {"IIR0 INP2 MUX", "RX7", "CDC_IF RX7 MUX"}, - {"IIR0", NULL, "IIR0 INP3 MUX"}, - {"IIR0 INP3 MUX", "DEC0", "ADC MUX0"}, - {"IIR0 INP3 MUX", "DEC1", "ADC MUX1"}, - {"IIR0 INP3 MUX", "DEC2", "ADC MUX2"}, - {"IIR0 INP3 MUX", "DEC3", "ADC MUX3"}, - {"IIR0 INP3 MUX", "DEC4", "ADC MUX4"}, - {"IIR0 INP3 MUX", "DEC5", "ADC MUX5"}, - {"IIR0 INP3 MUX", "DEC6", "ADC MUX6"}, - {"IIR0 INP3 MUX", "DEC7", "ADC MUX7"}, - {"IIR0 INP3 MUX", "DEC8", "ADC MUX8"}, - {"IIR0 INP3 MUX", "RX0", "CDC_IF RX0 MUX"}, - {"IIR0 INP3 MUX", "RX1", "CDC_IF RX1 MUX"}, - {"IIR0 INP3 MUX", "RX2", "CDC_IF RX2 MUX"}, - {"IIR0 INP3 MUX", "RX3", "CDC_IF RX3 MUX"}, - {"IIR0 INP3 MUX", "RX4", "CDC_IF RX4 MUX"}, - {"IIR0 INP3 MUX", "RX5", "CDC_IF RX5 MUX"}, - {"IIR0 INP3 MUX", "RX6", "CDC_IF RX6 MUX"}, - {"IIR0 INP3 MUX", "RX7", "CDC_IF RX7 MUX"}, - - {"SRC0", NULL, "IIR0"}, - {"RX INT0 MIX2 INP", "SRC0", "SRC0"}, - {"RX INT7 MIX2 INP", "SRC0", "SRC0"}, - {"RX INT9 MIX2 INP", "SRC0", "SRC0"}, - - /* Native clk mix path routing */ - {"RX INT7_2 NATIVE MUX", "ON", "RX INT7_2 MUX"}, - {"RX INT7_2 INTERP", NULL, "RX INT7_2 NATIVE MUX"}, - {"RX INT7_2 NATIVE MUX", NULL, "RX INT7 NATIVE SUPPLY"}, - - {"RX INT8_2 NATIVE MUX", "ON", "RX INT8_2 MUX"}, - {"RX INT8_2 INTERP", NULL, "RX INT8_2 NATIVE MUX"}, - {"RX INT8_2 NATIVE MUX", NULL, "RX INT8 NATIVE SUPPLY"}, - - /* ASRC Routing */ - {"ASRC2 MUX", "ASRC_IN_SPKR1", "RX INT7_2 INTERP"}, - {"RX INT7 SEC MIX", NULL, "ASRC2 MUX"}, - - {"ASRC3 MUX", "ASRC_IN_SPKR2", "RX INT8_2 INTERP"}, - {"RX INT8 SEC MIX", NULL, "ASRC3 MUX"}, - - /* SLIMBUS-I2S Bridge interface */ - {"I2S TX1_0 MUX", "SB_RX2", "SLIM RX2"}, - - {"I2S TX1_1 MUX", "SB_RX0", "SLIM RX0"}, - {"I2S TX1_1 MUX", "SB_RX1", "SLIM RX1"}, - {"I2S TX1_1 MUX", "SB_RX2", "SLIM RX2"}, - {"I2S TX1_1 MUX", "SB_RX3", "SLIM RX3"}, - - {"I2S TX1 MIXER", NULL, "I2S TX1_0 MUX"}, - {"I2S TX1 MIXER", NULL, "I2S TX1_1 MUX"}, - {"I2S1 CAP", NULL, "I2S TX1 MIXER"}, - - {"CDC_IF TX10 MUX2", "I2SRX1_0_BRDG", "CDC_IF RX2 MUX"}, - {"CDC_IF TX11 MUX2", "I2SRX1_1_BRDG", "CDC_IF RX3 MUX"}, - {"CDC_IF RX2 MUX", "I2SRX1_0", "I2S1 PB"}, - {"CDC_IF RX3 MUX", "I2SRX1_1", "I2S1 PB"}, -}; - -#endif diff --git a/asoc/codecs/wcd9360/wcd9360.c b/asoc/codecs/wcd9360/wcd9360.c deleted file mode 100644 index 075a77fb60ca..000000000000 --- a/asoc/codecs/wcd9360/wcd9360.c +++ /dev/null @@ -1,8101 +0,0 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "wcd9360.h" -#include "wcd9360-routing.h" -#include "wcd9360-dsp-cntl.h" -#include "wcd9360-irq.h" -#include "../core.h" -#include "../pdata.h" -#include "../wcd9xxx-irq.h" -#include "../wcd9xxx-common-v2.h" -#include "../wcd9xxx-resmgr-v2.h" -#include "../wcdcal-hwdep.h" -#include "../msm-cdc-supply.h" - - -#define WCD9360_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ - SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ - SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\ - SNDRV_PCM_RATE_384000) -/* Fractional Rates */ -#define WCD9360_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\ - SNDRV_PCM_RATE_176400) - -#define WCD9360_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \ - SNDRV_PCM_FMTBIT_S24_LE) - -#define WCD9360_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \ - SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S32_LE) - -#define WCD9360_FORMATS_S16_LE (SNDRV_PCM_FMTBIT_S16_LE) - -/* Macros for packing register writes into a U32 */ -#define WCD9360_PACKED_REG_SIZE sizeof(u32) -#define WCD9360_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \ - do { \ - ((reg) = ((packed >> 16) & (0xffff))); \ - ((mask) = ((packed >> 8) & (0xff))); \ - ((val) = ((packed) & (0xff))); \ - } while (0) - -#define STRING(name) #name -#define WCD_DAPM_ENUM(name, reg, offset, text) \ -static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ -static const struct snd_kcontrol_new name##_mux = \ - SOC_DAPM_ENUM(STRING(name), name##_enum) - -#define WCD_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \ -static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ -static const struct snd_kcontrol_new name##_mux = \ - SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname) - -#define WCD_DAPM_MUX(name, shift, kctl) \ - SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux) - -/* - * Timeout in milli seconds and it is the wait time for - * slim channel removal interrupt to receive. - */ -#define WCD9360_SLIM_CLOSE_TIMEOUT 1000 -#define WCD9360_SLIM_IRQ_OVERFLOW (1 << 0) -#define WCD9360_SLIM_IRQ_UNDERFLOW (1 << 1) -#define WCD9360_SLIM_IRQ_PORT_CLOSED (1 << 2) - -#define WCD9360_MCLK_CLK_9P6MHZ 9600000 - -#define WCD9360_INTERP_MUX_NUM_INPUTS 3 -#define WCD9360_NUM_INTERPOLATORS 10 -#define WCD9360_NUM_DECIMATORS 9 -#define WCD9360_RX_PATH_CTL_OFFSET 20 -#define WCD9360_TLMM_DMIC_PINCFG_OFFSET 15 - -#define BYTE_BIT_MASK(nr) (1 << ((nr) % BITS_PER_BYTE)) - -#define WCD9360_REG_BITS 8 -#define WCD9360_MAX_VALID_ADC_MUX 11 -#define WCD9360_INVALID_ADC_MUX 9 - -#define WCD9360_AMIC_PWR_LEVEL_LP 0 -#define WCD9360_AMIC_PWR_LEVEL_DEFAULT 1 -#define WCD9360_AMIC_PWR_LEVEL_HP 2 -#define WCD9360_AMIC_PWR_LVL_MASK 0x60 -#define WCD9360_AMIC_PWR_LVL_SHIFT 0x5 - -#define WCD9360_DEC_PWR_LVL_MASK 0x06 -#define WCD9360_DEC_PWR_LVL_LP 0x02 -#define WCD9360_DEC_PWR_LVL_HP 0x04 -#define WCD9360_DEC_PWR_LVL_DF 0x00 -#define WCD9360_STRING_LEN 100 - -#define WCD9360_CDC_SIDETONE_IIR_COEFF_MAX 5 -#define WCD9360_CDC_REPEAT_WRITES_MAX 16 -#define WCD9360_DIG_CORE_REG_MIN WCD9360_CDC_ANC0_CLK_RESET_CTL -#define WCD9360_DIG_CORE_REG_MAX 0xFFF - -#define WCD9360_CHILD_DEVICES_MAX 6 - -#define WCD9360_MAX_MICBIAS 4 -#define DAPM_MICBIAS1_STANDALONE "MIC BIAS1 Standalone" -#define DAPM_MICBIAS2_STANDALONE "MIC BIAS2 Standalone" -#define DAPM_MICBIAS3_STANDALONE "MIC BIAS3 Standalone" -#define DAPM_MICBIAS4_STANDALONE "MIC BIAS4 Standalone" - -#define WCD9360_LDO_RXTX_SUPPLY_NAME "cdc-vdd-ldo-rxtx" - -#define TX_HPF_CUT_OFF_FREQ_MASK 0x60 -#define CF_MIN_3DB_4HZ 0x0 -#define CF_MIN_3DB_75HZ 0x1 -#define CF_MIN_3DB_150HZ 0x2 - -#define CPE_ERR_WDOG_BITE BIT(0) -#define CPE_FATAL_IRQS CPE_ERR_WDOG_BITE - -#define WCD9360_MAD_AUDIO_FIRMWARE_PATH "wcd9360/wcd9360_mad_audio.bin" - -#define PAHU_VERSION_ENTRY_SIZE 17 - -#define WCD9360_DIG_CORE_COLLAPSE_TIMER_MS (5 * 1000) - -enum { - INTERP_EAR = 0, - /* Headset and Lineout are not avalible in pahu */ - INTERP_HPHL_NA, - INTERP_HPHR_NA, - INTERP_LO1_NA, - INTERP_LO2_NA, - INTERP_LO3_NA, - INTERP_LO4_NA, - INTERP_SPKR1, - INTERP_SPKR2, - INTERP_AUX, - INTERP_MAX, -}; - -enum { - POWER_COLLAPSE, - POWER_RESUME, -}; - -static int dig_core_collapse_enable = 1; -module_param(dig_core_collapse_enable, int, 0664); -MODULE_PARM_DESC(dig_core_collapse_enable, "enable/disable power gating"); - -/* dig_core_collapse timer in seconds */ -static int dig_core_collapse_timer = (WCD9360_DIG_CORE_COLLAPSE_TIMER_MS/1000); -module_param(dig_core_collapse_timer, int, 0664); -MODULE_PARM_DESC(dig_core_collapse_timer, "timer for power gating"); - -enum { - VI_SENSE_1, - VI_SENSE_2, - CLK_INTERNAL, - CLK_MODE, -}; - -enum { - AIF1_PB = 0, - AIF1_CAP, - AIF2_PB, - AIF2_CAP, - AIF3_PB, - AIF3_CAP, - AIF4_PB, - AIF4_VIFEED, - AIF4_MAD_TX, - I2S1_PB, - I2S1_CAP, - NUM_CODEC_DAIS, -}; - -enum { - INTn_1_INP_SEL_ZERO = 0, - INTn_1_INP_SEL_DEC0, - INTn_1_INP_SEL_DEC1, - INTn_1_INP_SEL_IIR0, - INTn_1_INP_SEL_NA, - INTn_1_INP_SEL_RX0, - INTn_1_INP_SEL_RX1, - INTn_1_INP_SEL_RX2, - INTn_1_INP_SEL_RX3, - INTn_1_INP_SEL_RX4, - INTn_1_INP_SEL_RX5, - INTn_1_INP_SEL_RX6, - INTn_1_INP_SEL_RX7, -}; - -enum { - INTn_2_INP_SEL_ZERO = 0, - INTn_2_INP_SEL_RX0, - INTn_2_INP_SEL_RX1, - INTn_2_INP_SEL_RX2, - INTn_2_INP_SEL_RX3, - INTn_2_INP_SEL_RX4, - INTn_2_INP_SEL_RX5, - INTn_2_INP_SEL_RX6, - INTn_2_INP_SEL_RX7, - INTn_2_INP_SEL_PROXIMITY, -}; - -enum { - INTERP_MAIN_PATH, - INTERP_MIX_PATH, -}; - -struct pahu_cpr_reg_defaults { - int wr_data; - int wr_addr; -}; - -struct interp_sample_rate { - int sample_rate; - int rate_val; -}; - -static struct interp_sample_rate sr_val_tbl[] = { - {8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5}, - {192000, 0x6}, {384000, 0x7}, {44100, 0x9}, {88200, 0xA}, - {176400, 0xB}, {352800, 0xC}, -}; - -static const struct wcd9xxx_ch pahu_rx_chs[WCD9360_RX_MAX] = { - WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER, 0), - WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 1, 1), - WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 2, 2), - WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 3, 3), - WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 4, 4), - WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 5, 5), - WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 6, 6), - WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 7, 7), -}; - -static const struct wcd9xxx_ch pahu_tx_chs[WCD9360_TX_MAX] = { - WCD9XXX_CH(0, 0), - WCD9XXX_CH(1, 1), - WCD9XXX_CH(2, 2), - WCD9XXX_CH(3, 3), - WCD9XXX_CH(4, 4), - WCD9XXX_CH(5, 5), - WCD9XXX_CH(6, 6), - WCD9XXX_CH(7, 7), - WCD9XXX_CH(8, 8), - WCD9XXX_CH(9, 9), - WCD9XXX_CH(10, 10), - WCD9XXX_CH(11, 11), - WCD9XXX_CH(12, 12), - WCD9XXX_CH(13, 13), - WCD9XXX_CH(14, 14), - WCD9XXX_CH(15, 15), -}; - -static const u32 vport_slim_check_table[NUM_CODEC_DAIS] = { - 0, /* AIF1_PB */ - BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX), /* AIF1_CAP */ - 0, /* AIF2_PB */ - BIT(AIF1_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX), /* AIF2_CAP */ - 0, /* AIF3_PB */ - BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF4_MAD_TX), /* AIF3_CAP */ - 0, /* AIF4_PB */ -}; - -/* Codec supports 2 IIR filters */ -enum { - IIR0 = 0, - IIR_MAX, -}; - -/* Each IIR has 5 Filter Stages */ -enum { - BAND1 = 0, - BAND2, - BAND3, - BAND4, - BAND5, - BAND_MAX, -}; - -enum { - COMPANDER_0, /* EAR */ - COMPANDER_1, /* HPH_L */ - COMPANDER_2, /* HPH_R */ - COMPANDER_3, /* LO1_DIFF */ - COMPANDER_4, /* LO2_DIFF */ - COMPANDER_5, /* LO3_SE */ - COMPANDER_6, /* LO4_SE */ - COMPANDER_7, /* SWR SPK CH1 */ - COMPANDER_8, /* SWR SPK CH2 */ - COMPANDER_9, /* AUX */ - COMPANDER_MAX, -}; - -enum { - ASRC_IN_SPKR1, - ASRC_IN_SPKR2, - ASRC_INVALID, -}; - -enum { - ASRC2, - ASRC3, - ASRC_MAX, -}; - -enum { - CONV_88P2K_TO_384K, - CONV_96K_TO_352P8K, - CONV_352P8K_TO_384K, - CONV_384K_TO_352P8K, - CONV_384K_TO_384K, - CONV_96K_TO_384K, -}; - -static struct afe_param_slimbus_slave_port_cfg pahu_slimbus_slave_port_cfg = { - .minor_version = 1, - .slimbus_dev_id = AFE_SLIMBUS_DEVICE_1, - .slave_dev_pgd_la = 0, - .slave_dev_intfdev_la = 0, - .bit_width = 16, - .data_format = 0, - .num_channels = 1 -}; - -static struct afe_param_cdc_reg_page_cfg pahu_cdc_reg_page_cfg = { - .minor_version = AFE_API_VERSION_CDC_REG_PAGE_CFG, - .enable = 1, - .proc_id = AFE_CDC_REG_PAGE_ASSIGN_PROC_ID_1, -}; - -static struct afe_param_cdc_reg_cfg audio_reg_cfg[] = { - { - 1, - (WCD9360_REGISTER_START_OFFSET + WCD9360_SOC_MAD_MAIN_CTL_1), - HW_MAD_AUDIO_ENABLE, 0x1, WCD9360_REG_BITS, 0 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + WCD9360_SOC_MAD_AUDIO_CTL_3), - HW_MAD_AUDIO_SLEEP_TIME, 0xF, WCD9360_REG_BITS, 0 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + WCD9360_SOC_MAD_AUDIO_CTL_4), - HW_MAD_TX_AUDIO_SWITCH_OFF, 0x1, WCD9360_REG_BITS, 0 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + WCD9360_INTR_CFG), - MAD_AUDIO_INT_DEST_SELECT_REG, 0x2, WCD9360_REG_BITS, 0 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + WCD9360_INTR_PIN2_MASK3), - MAD_AUDIO_INT_MASK_REG, 0x1, WCD9360_REG_BITS, 0 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + WCD9360_INTR_PIN2_STATUS3), - MAD_AUDIO_INT_STATUS_REG, 0x1, WCD9360_REG_BITS, 0 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + WCD9360_INTR_PIN2_CLEAR3), - MAD_AUDIO_INT_CLEAR_REG, 0x1, WCD9360_REG_BITS, 0 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + WCD9360_SB_PGD_PORT_TX_BASE), - SB_PGD_PORT_TX_WATERMARK_N, 0x1E, WCD9360_REG_BITS, 0x1 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + WCD9360_SB_PGD_PORT_TX_BASE), - SB_PGD_PORT_TX_ENABLE_N, 0x1, WCD9360_REG_BITS, 0x1 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + WCD9360_SB_PGD_PORT_RX_BASE), - SB_PGD_PORT_RX_WATERMARK_N, 0x1E, WCD9360_REG_BITS, 0x1 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + WCD9360_SB_PGD_PORT_RX_BASE), - SB_PGD_PORT_RX_ENABLE_N, 0x1, WCD9360_REG_BITS, 0x1 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + - WCD9360_CDC_ANC0_IIR_ADAPT_CTL), - AANC_FF_GAIN_ADAPTIVE, 0x4, WCD9360_REG_BITS, 0 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + - WCD9360_CDC_ANC0_IIR_ADAPT_CTL), - AANC_FFGAIN_ADAPTIVE_EN, 0x8, WCD9360_REG_BITS, 0 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + - WCD9360_CDC_ANC0_FF_A_GAIN_CTL), - AANC_GAIN_CONTROL, 0xFF, WCD9360_REG_BITS, 0 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + - SB_PGD_TX_PORT_MULTI_CHANNEL_0(0)), - SB_PGD_TX_PORTn_MULTI_CHNL_0, 0xFF, WCD9360_REG_BITS, 0x4 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + - SB_PGD_TX_PORT_MULTI_CHANNEL_1(0)), - SB_PGD_TX_PORTn_MULTI_CHNL_1, 0xFF, WCD9360_REG_BITS, 0x4 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + - SB_PGD_RX_PORT_MULTI_CHANNEL_0(0x180, 0)), - SB_PGD_RX_PORTn_MULTI_CHNL_0, 0xFF, WCD9360_REG_BITS, 0x4 - }, - { - 1, - (WCD9360_REGISTER_START_OFFSET + - SB_PGD_RX_PORT_MULTI_CHANNEL_0(0x181, 0)), - SB_PGD_RX_PORTn_MULTI_CHNL_1, 0xFF, WCD9360_REG_BITS, 0x4 - }, -}; - -static struct afe_param_cdc_reg_cfg_data pahu_audio_reg_cfg = { - .num_registers = ARRAY_SIZE(audio_reg_cfg), - .reg_data = audio_reg_cfg, -}; - -static struct afe_param_id_cdc_aanc_version pahu_cdc_aanc_version = { - .cdc_aanc_minor_version = AFE_API_VERSION_CDC_AANC_VERSION, - .aanc_hw_version = AANC_HW_BLOCK_VERSION_2, -}; - -static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); -static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); - -#define WCD9360_TX_UNMUTE_DELAY_MS 40 - -static int tx_unmute_delay = WCD9360_TX_UNMUTE_DELAY_MS; -module_param(tx_unmute_delay, int, 0664); -MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path"); - -static void pahu_codec_set_tx_hold(struct snd_soc_codec *, u16, bool); - -/* Hold instance to soundwire platform device */ -struct pahu_swr_ctrl_data { - struct platform_device *swr_pdev; -}; - -struct wcd_swr_ctrl_platform_data { - void *handle; /* holds codec private data */ - int (*read)(void *handle, int reg); - int (*write)(void *handle, int reg, int val); - int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); - int (*clk)(void *handle, bool enable); - int (*handle_irq)(void *handle, - irqreturn_t (*swrm_irq_handler)(int irq, void *data), - void *swrm_handle, int action); -}; - -/* Holds all Soundwire and speaker related information */ -struct wcd9360_swr { - struct pahu_swr_ctrl_data *ctrl_data; - struct wcd_swr_ctrl_platform_data plat_data; - struct mutex read_mutex; - struct mutex write_mutex; - struct mutex clk_mutex; - int spkr_gain_offset; - int spkr_mode; - int clk_users; - int rx_7_count; - int rx_8_count; -}; - -struct tx_mute_work { - struct pahu_priv *pahu; - u8 decimator; - struct delayed_work dwork; -}; - -#define WCD9360_SPK_ANC_EN_DELAY_MS 550 -static int spk_anc_en_delay = WCD9360_SPK_ANC_EN_DELAY_MS; -module_param(spk_anc_en_delay, int, 0664); -MODULE_PARM_DESC(spk_anc_en_delay, "delay to enable anc in speaker path"); - -struct spk_anc_work { - struct pahu_priv *pahu; - struct delayed_work dwork; -}; - -struct hpf_work { - struct pahu_priv *pahu; - u8 decimator; - u8 hpf_cut_off_freq; - struct delayed_work dwork; -}; - -struct pahu_priv { - struct device *dev; - struct wcd9xxx *wcd9xxx; - struct snd_soc_codec *codec; - s32 ldo_rxtx_cnt; - s32 dmic_0_1_clk_cnt; - s32 dmic_2_3_clk_cnt; - s32 dmic_4_5_clk_cnt; - s32 dmic_6_7_clk_cnt; - s32 micb_ref[PAHU_MAX_MICBIAS]; - s32 pullup_ref[PAHU_MAX_MICBIAS]; - - /* ANC related */ - u32 anc_slot; - bool anc_func; - - /* compander */ - int comp_enabled[COMPANDER_MAX]; - int ear_spkr_gain; - - /* Mad switch reference count */ - int mad_switch_cnt; - - /* track pahu interface type */ - u8 intf_type; - - /* to track the status */ - unsigned long status_mask; - - struct afe_param_cdc_slimbus_slave_cfg slimbus_slave_cfg; - - /* num of slim ports required */ - struct wcd9xxx_codec_dai_data dai[NUM_CODEC_DAIS]; - /* Port values for Rx and Tx codec_dai */ - unsigned int rx_port_value[WCD9360_RX_MAX]; - unsigned int tx_port_value; - - struct wcd9xxx_resmgr_v2 *resmgr; - struct wcd9360_swr swr; - struct mutex micb_lock; - - struct delayed_work power_gate_work; - struct mutex power_lock; - - struct clk *wcd_ext_clk; - - struct mutex codec_mutex; - struct work_struct pahu_add_child_devices_work; - struct hpf_work tx_hpf_work[WCD9360_NUM_DECIMATORS]; - struct tx_mute_work tx_mute_dwork[WCD9360_NUM_DECIMATORS]; - struct spk_anc_work spk_anc_dwork; - - unsigned int vi_feed_value; - - /* DSP control */ - struct wcd_dsp_cntl *wdsp_cntl; - - /* cal info for codec */ - struct fw_info *fw_data; - - /* Entry for version info */ - struct snd_info_entry *entry; - struct snd_info_entry *version_entry; - - /* SVS voting related */ - struct mutex svs_mutex; - int svs_ref_cnt; - - int native_clk_users; - /* ASRC users count */ - int asrc_users[ASRC_MAX]; - int asrc_output_mode[ASRC_MAX]; - /* Main path clock users count */ - int main_clk_users[WCD9360_NUM_INTERPOLATORS]; - - int power_active_ref; - u8 sidetone_coeff_array[IIR_MAX][BAND_MAX] - [WCD9360_CDC_SIDETONE_IIR_COEFF_MAX * 4]; - - struct spi_device *spi; - struct platform_device *pdev_child_devices - [WCD9360_CHILD_DEVICES_MAX]; - int child_count; - int i2s_ref_cnt; -}; - -static const struct pahu_reg_mask_val pahu_spkr_default[] = { - {WCD9360_CDC_COMPANDER7_CTL3, 0x80, 0x80}, - {WCD9360_CDC_COMPANDER8_CTL3, 0x80, 0x80}, - {WCD9360_CDC_COMPANDER7_CTL7, 0x01, 0x01}, - {WCD9360_CDC_COMPANDER8_CTL7, 0x01, 0x01}, - {WCD9360_CDC_BOOST0_BOOST_CTL, 0x7C, 0x50}, - {WCD9360_CDC_BOOST1_BOOST_CTL, 0x7C, 0x50}, -}; - -static const struct pahu_reg_mask_val pahu_spkr_mode1[] = { - {WCD9360_CDC_COMPANDER7_CTL3, 0x80, 0x00}, - {WCD9360_CDC_COMPANDER8_CTL3, 0x80, 0x00}, - {WCD9360_CDC_COMPANDER7_CTL7, 0x01, 0x00}, - {WCD9360_CDC_COMPANDER8_CTL7, 0x01, 0x00}, - {WCD9360_CDC_BOOST0_BOOST_CTL, 0x7C, 0x44}, - {WCD9360_CDC_BOOST1_BOOST_CTL, 0x7C, 0x44}, -}; - -static int __pahu_enable_efuse_sensing(struct pahu_priv *pahu); - -/** - * pahu_set_spkr_gain_offset - offset the speaker path - * gain with the given offset value. - * - * @codec: codec instance - * @offset: Indicates speaker path gain offset value. - * - * Returns 0 on success or -EINVAL on error. - */ -int pahu_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset) -{ - struct pahu_priv *priv = snd_soc_codec_get_drvdata(codec); - - if (!priv) - return -EINVAL; - - priv->swr.spkr_gain_offset = offset; - return 0; -} -EXPORT_SYMBOL(pahu_set_spkr_gain_offset); - -/** - * pahu_set_spkr_mode - Configures speaker compander and smartboost - * settings based on speaker mode. - * - * @codec: codec instance - * @mode: Indicates speaker configuration mode. - * - * Returns 0 on success or -EINVAL on error. - */ -int pahu_set_spkr_mode(struct snd_soc_codec *codec, int mode) -{ - struct pahu_priv *priv = snd_soc_codec_get_drvdata(codec); - int i; - const struct pahu_reg_mask_val *regs; - int size; - - if (!priv) - return -EINVAL; - - switch (mode) { - case WCD9360_SPKR_MODE_1: - regs = pahu_spkr_mode1; - size = ARRAY_SIZE(pahu_spkr_mode1); - break; - default: - regs = pahu_spkr_default; - size = ARRAY_SIZE(pahu_spkr_default); - break; - } - - priv->swr.spkr_mode = mode; - for (i = 0; i < size; i++) - snd_soc_update_bits(codec, regs[i].reg, - regs[i].mask, regs[i].val); - return 0; -} -EXPORT_SYMBOL(pahu_set_spkr_mode); - -/** - * pahu_get_afe_config - returns specific codec configuration to afe to write - * - * @codec: codec instance - * @config_type: Indicates type of configuration to write. - */ -void *pahu_get_afe_config(struct snd_soc_codec *codec, - enum afe_config_type config_type) -{ - struct pahu_priv *priv = snd_soc_codec_get_drvdata(codec); - - switch (config_type) { - case AFE_SLIMBUS_SLAVE_CONFIG: - return &priv->slimbus_slave_cfg; - case AFE_CDC_REGISTERS_CONFIG: - return &pahu_audio_reg_cfg; - case AFE_SLIMBUS_SLAVE_PORT_CONFIG: - return &pahu_slimbus_slave_port_cfg; - case AFE_AANC_VERSION: - return &pahu_cdc_aanc_version; - case AFE_CDC_REGISTER_PAGE_CONFIG: - return &pahu_cdc_reg_page_cfg; - default: - dev_info(codec->dev, "%s: Unknown config_type 0x%x\n", - __func__, config_type); - return NULL; - } -} -EXPORT_SYMBOL(pahu_get_afe_config); - -static void pahu_vote_svs(struct pahu_priv *pahu, bool vote) -{ - struct wcd9xxx *wcd9xxx; - - wcd9xxx = pahu->wcd9xxx; - - mutex_lock(&pahu->svs_mutex); - if (vote) { - pahu->svs_ref_cnt++; - if (pahu->svs_ref_cnt == 1) - regmap_update_bits(wcd9xxx->regmap, - WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_0, - 0x01, 0x01); - } else { - /* Do not decrement ref count if it is already 0 */ - if (pahu->svs_ref_cnt == 0) - goto done; - - pahu->svs_ref_cnt--; - if (pahu->svs_ref_cnt == 0) - regmap_update_bits(wcd9xxx->regmap, - WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_0, - 0x01, 0x00); - } -done: - dev_dbg(pahu->dev, "%s: vote = %s, updated ref cnt = %u\n", __func__, - vote ? "vote" : "Unvote", pahu->svs_ref_cnt); - mutex_unlock(&pahu->svs_mutex); -} - -static int pahu_get_anc_slot(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = pahu->anc_slot; - return 0; -} - -static int pahu_put_anc_slot(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - pahu->anc_slot = ucontrol->value.integer.value[0]; - return 0; -} - -static int pahu_get_anc_func(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = (pahu->anc_func == true ? 1 : 0); - return 0; -} - -static int pahu_put_anc_func(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - - mutex_lock(&pahu->codec_mutex); - pahu->anc_func = (!ucontrol->value.integer.value[0] ? false : true); - dev_dbg(codec->dev, "%s: anc_func %x", __func__, pahu->anc_func); - - if (pahu->anc_func == true) { - snd_soc_dapm_enable_pin(dapm, "ANC EAR PA"); - snd_soc_dapm_enable_pin(dapm, "ANC EAR"); - snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA"); - snd_soc_dapm_disable_pin(dapm, "EAR PA"); - snd_soc_dapm_disable_pin(dapm, "EAR"); - } else { - snd_soc_dapm_disable_pin(dapm, "ANC EAR PA"); - snd_soc_dapm_disable_pin(dapm, "ANC EAR"); - snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA"); - snd_soc_dapm_enable_pin(dapm, "EAR PA"); - snd_soc_dapm_enable_pin(dapm, "EAR"); - } - mutex_unlock(&pahu->codec_mutex); - - snd_soc_dapm_sync(dapm); - return 0; -} - -static int pahu_codec_enable_anc(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - const char *filename; - const struct firmware *fw; - int i; - int ret = 0; - int num_anc_slots; - struct wcd9xxx_anc_header *anc_head; - struct firmware_cal *hwdep_cal = NULL; - u32 anc_writes_size = 0; - int anc_size_remaining; - u32 *anc_ptr; - u16 reg; - u8 mask, val; - size_t cal_size; - const void *data; - - if (!pahu->anc_func) - return 0; - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - hwdep_cal = wcdcal_get_fw_cal(pahu->fw_data, WCD9XXX_ANC_CAL); - if (hwdep_cal) { - data = hwdep_cal->data; - cal_size = hwdep_cal->size; - dev_dbg(codec->dev, "%s: using hwdep calibration, cal_size %zd", - __func__, cal_size); - } else { - filename = "wcd9360/WCD9360_anc.bin"; - ret = request_firmware(&fw, filename, codec->dev); - if (ret < 0) { - dev_err(codec->dev, "%s: Failed to acquire ANC data: %d\n", - __func__, ret); - return ret; - } - if (!fw) { - dev_err(codec->dev, "%s: Failed to get anc fw\n", - __func__); - return -ENODEV; - } - data = fw->data; - cal_size = fw->size; - dev_dbg(codec->dev, "%s: using request_firmware calibration\n", - __func__); - } - if (cal_size < sizeof(struct wcd9xxx_anc_header)) { - dev_err(codec->dev, "%s: Invalid cal_size %zd\n", - __func__, cal_size); - ret = -EINVAL; - goto err; - } - /* First number is the number of register writes */ - anc_head = (struct wcd9xxx_anc_header *)(data); - anc_ptr = (u32 *)(data + sizeof(struct wcd9xxx_anc_header)); - anc_size_remaining = cal_size - - sizeof(struct wcd9xxx_anc_header); - num_anc_slots = anc_head->num_anc_slots; - - if (pahu->anc_slot >= num_anc_slots) { - dev_err(codec->dev, "%s: Invalid ANC slot selected\n", - __func__); - ret = -EINVAL; - goto err; - } - for (i = 0; i < num_anc_slots; i++) { - if (anc_size_remaining < WCD9360_PACKED_REG_SIZE) { - dev_err(codec->dev, "%s: Invalid register format\n", - __func__); - ret = -EINVAL; - goto err; - } - anc_writes_size = (u32)(*anc_ptr); - anc_size_remaining -= sizeof(u32); - anc_ptr += 1; - - if ((anc_writes_size * WCD9360_PACKED_REG_SIZE) > - anc_size_remaining) { - dev_err(codec->dev, "%s: Invalid register format\n", - __func__); - ret = -EINVAL; - goto err; - } - - if (pahu->anc_slot == i) - break; - - anc_size_remaining -= (anc_writes_size * - WCD9360_PACKED_REG_SIZE); - anc_ptr += anc_writes_size; - } - if (i == num_anc_slots) { - dev_err(codec->dev, "%s: Selected ANC slot not present\n", - __func__); - ret = -EINVAL; - goto err; - } - - for (i = 0; i < anc_writes_size; i++) { - WCD9360_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val); - snd_soc_write(codec, reg, (val & mask)); - } - - if (!hwdep_cal) - release_firmware(fw); - break; - - case SND_SOC_DAPM_POST_PMU: - break; - - case SND_SOC_DAPM_POST_PMD: - if (!strcmp(w->name, "ANC EAR PA") || - !strcmp(w->name, "ANC SPK1 PA")) { - snd_soc_update_bits(codec, WCD9360_CDC_ANC0_MODE_1_CTL, - 0x30, 0x00); - msleep(50); - snd_soc_update_bits(codec, WCD9360_CDC_ANC0_MODE_1_CTL, - 0x01, 0x00); - snd_soc_update_bits(codec, - WCD9360_CDC_ANC0_CLK_RESET_CTL, - 0x38, 0x38); - snd_soc_update_bits(codec, - WCD9360_CDC_ANC0_CLK_RESET_CTL, - 0x07, 0x00); - snd_soc_update_bits(codec, - WCD9360_CDC_ANC0_CLK_RESET_CTL, - 0x38, 0x00); - } - break; - } - - return 0; -err: - if (!hwdep_cal) - release_firmware(fw); - return ret; -} - -static int pahu_get_clkmode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); - - if (test_bit(CLK_MODE, &pahu_p->status_mask)) - ucontrol->value.enumerated.item[0] = 1; - else - ucontrol->value.enumerated.item[0] = 0; - - dev_dbg(codec->dev, "%s: is_low_power_clock: %s\n", __func__, - test_bit(CLK_MODE, &pahu_p->status_mask) ? "true" : "false"); - - return 0; -} - -static int pahu_put_clkmode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); - - if (ucontrol->value.enumerated.item[0]) - set_bit(CLK_MODE, &pahu_p->status_mask); - else - clear_bit(CLK_MODE, &pahu_p->status_mask); - - dev_dbg(codec->dev, "%s: is_low_power_clock: %s\n", __func__, - test_bit(CLK_MODE, &pahu_p->status_mask) ? "true" : "false"); - - return 0; -} - -static int pahu_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = pahu_p->vi_feed_value; - - return 0; -} - -static int pahu_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); - struct soc_multi_mixer_control *mixer = - ((struct soc_multi_mixer_control *)kcontrol->private_value); - u32 dai_id = widget->shift; - u32 port_id = mixer->shift; - u32 enable = ucontrol->value.integer.value[0]; - - dev_dbg(codec->dev, "%s: enable: %d, port_id:%d, dai_id: %d\n", - __func__, enable, port_id, dai_id); - - pahu_p->vi_feed_value = ucontrol->value.integer.value[0]; - - mutex_lock(&pahu_p->codec_mutex); - if (enable) { - if (port_id == WCD9360_TX14 && !test_bit(VI_SENSE_1, - &pahu_p->status_mask)) { - list_add_tail(&core->tx_chs[WCD9360_TX14].list, - &pahu_p->dai[dai_id].wcd9xxx_ch_list); - set_bit(VI_SENSE_1, &pahu_p->status_mask); - } - if (port_id == WCD9360_TX15 && !test_bit(VI_SENSE_2, - &pahu_p->status_mask)) { - list_add_tail(&core->tx_chs[WCD9360_TX15].list, - &pahu_p->dai[dai_id].wcd9xxx_ch_list); - set_bit(VI_SENSE_2, &pahu_p->status_mask); - } - } else { - if (port_id == WCD9360_TX14 && test_bit(VI_SENSE_1, - &pahu_p->status_mask)) { - list_del_init(&core->tx_chs[WCD9360_TX14].list); - clear_bit(VI_SENSE_1, &pahu_p->status_mask); - } - if (port_id == WCD9360_TX15 && test_bit(VI_SENSE_2, - &pahu_p->status_mask)) { - list_del_init(&core->tx_chs[WCD9360_TX15].list); - clear_bit(VI_SENSE_2, &pahu_p->status_mask); - } - } - mutex_unlock(&pahu_p->codec_mutex); - snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL); - - return 0; -} - -static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = pahu_p->tx_port_value; - return 0; -} - -static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); - struct snd_soc_dapm_update *update = NULL; - struct soc_multi_mixer_control *mixer = - ((struct soc_multi_mixer_control *)kcontrol->private_value); - u32 dai_id = widget->shift; - u32 port_id = mixer->shift; - u32 enable = ucontrol->value.integer.value[0]; - u32 vtable; - - dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", - __func__, - widget->name, ucontrol->id.name, pahu_p->tx_port_value, - widget->shift, ucontrol->value.integer.value[0]); - - mutex_lock(&pahu_p->codec_mutex); - if (dai_id >= ARRAY_SIZE(vport_slim_check_table)) { - dev_err(codec->dev, "%s: dai_id: %d, out of bounds\n", - __func__, dai_id); - mutex_unlock(&pahu_p->codec_mutex); - return -EINVAL; - } - vtable = vport_slim_check_table[dai_id]; - - switch (dai_id) { - case AIF1_CAP: - case AIF2_CAP: - case AIF3_CAP: - /* only add to the list if value not set */ - if (enable && !(pahu_p->tx_port_value & 1 << port_id)) { - if (wcd9xxx_tx_vport_validation(vtable, port_id, - pahu_p->dai, NUM_CODEC_DAIS)) { - dev_dbg(codec->dev, "%s: TX%u is used by other virtual port\n", - __func__, port_id); - mutex_unlock(&pahu_p->codec_mutex); - return 0; - } - pahu_p->tx_port_value |= 1 << port_id; - list_add_tail(&core->tx_chs[port_id].list, - &pahu_p->dai[dai_id].wcd9xxx_ch_list); - } else if (!enable && (pahu_p->tx_port_value & - 1 << port_id)) { - pahu_p->tx_port_value &= ~(1 << port_id); - list_del_init(&core->tx_chs[port_id].list); - } else { - if (enable) - dev_dbg(codec->dev, "%s: TX%u port is used by\n" - "this virtual port\n", - __func__, port_id); - else - dev_dbg(codec->dev, "%s: TX%u port is not used by\n" - "this virtual port\n", - __func__, port_id); - /* avoid update power function */ - mutex_unlock(&pahu_p->codec_mutex); - return 0; - } - break; - case AIF4_MAD_TX: - break; - default: - dev_err(codec->dev, "Unknown AIF %d\n", dai_id); - mutex_unlock(&pahu_p->codec_mutex); - return -EINVAL; - } - dev_dbg(codec->dev, "%s: name %s sname %s updated value %u shift %d\n", - __func__, widget->name, widget->sname, pahu_p->tx_port_value, - widget->shift); - - mutex_unlock(&pahu_p->codec_mutex); - snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update); - - return 0; -} - -static int slim_rx_mux_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.enumerated.item[0] = - pahu_p->rx_port_value[widget->shift]; - return 0; -} - -static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_dapm_update *update = NULL; - unsigned int rx_port_value; - u32 port_id = widget->shift; - - pahu_p->rx_port_value[port_id] = ucontrol->value.enumerated.item[0]; - rx_port_value = pahu_p->rx_port_value[port_id]; - - mutex_lock(&pahu_p->codec_mutex); - dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", - __func__, widget->name, ucontrol->id.name, - rx_port_value, widget->shift, - ucontrol->value.integer.value[0]); - - /* value need to match the Virtual port and AIF number */ - switch (rx_port_value) { - case 0: - list_del_init(&core->rx_chs[port_id].list); - break; - case 1: - if (wcd9xxx_rx_vport_validation(port_id + - WCD9360_RX_PORT_START_NUMBER, - &pahu_p->dai[AIF1_PB].wcd9xxx_ch_list)) { - dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", - __func__, port_id); - goto rtn; - } - list_add_tail(&core->rx_chs[port_id].list, - &pahu_p->dai[AIF1_PB].wcd9xxx_ch_list); - break; - case 2: - if (wcd9xxx_rx_vport_validation(port_id + - WCD9360_RX_PORT_START_NUMBER, - &pahu_p->dai[AIF2_PB].wcd9xxx_ch_list)) { - dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", - __func__, port_id); - goto rtn; - } - list_add_tail(&core->rx_chs[port_id].list, - &pahu_p->dai[AIF2_PB].wcd9xxx_ch_list); - break; - case 3: - if (wcd9xxx_rx_vport_validation(port_id + - WCD9360_RX_PORT_START_NUMBER, - &pahu_p->dai[AIF3_PB].wcd9xxx_ch_list)) { - dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", - __func__, port_id); - goto rtn; - } - list_add_tail(&core->rx_chs[port_id].list, - &pahu_p->dai[AIF3_PB].wcd9xxx_ch_list); - break; - case 4: - if (wcd9xxx_rx_vport_validation(port_id + - WCD9360_RX_PORT_START_NUMBER, - &pahu_p->dai[AIF4_PB].wcd9xxx_ch_list)) { - dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", - __func__, port_id); - goto rtn; - } - list_add_tail(&core->rx_chs[port_id].list, - &pahu_p->dai[AIF4_PB].wcd9xxx_ch_list); - break; - default: - dev_err(codec->dev, "Unknown AIF %d\n", rx_port_value); - goto err; - } -rtn: - mutex_unlock(&pahu_p->codec_mutex); - snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, - rx_port_value, e, update); - - return 0; -err: - mutex_unlock(&pahu_p->codec_mutex); - return -EINVAL; -} - -static void pahu_codec_enable_slim_port_intr( - struct wcd9xxx_codec_dai_data *dai, - struct snd_soc_codec *codec) -{ - struct wcd9xxx_ch *ch; - int port_num = 0; - unsigned short reg = 0; - u8 val = 0; - struct pahu_priv *pahu_p; - - if (!dai || !codec) { - pr_err("%s: Invalid params\n", __func__); - return; - } - - pahu_p = snd_soc_codec_get_drvdata(codec); - list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) { - if (ch->port >= WCD9360_RX_PORT_START_NUMBER) { - port_num = ch->port - WCD9360_RX_PORT_START_NUMBER; - reg = WCD9360_SLIM_PGD_PORT_INT_RX_EN0 + (port_num / 8); - val = wcd9xxx_interface_reg_read(pahu_p->wcd9xxx, - reg); - if (!(val & BYTE_BIT_MASK(port_num))) { - val |= BYTE_BIT_MASK(port_num); - wcd9xxx_interface_reg_write( - pahu_p->wcd9xxx, reg, val); - val = wcd9xxx_interface_reg_read( - pahu_p->wcd9xxx, reg); - } - } else { - port_num = ch->port; - reg = WCD9360_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8); - val = wcd9xxx_interface_reg_read(pahu_p->wcd9xxx, - reg); - if (!(val & BYTE_BIT_MASK(port_num))) { - val |= BYTE_BIT_MASK(port_num); - wcd9xxx_interface_reg_write(pahu_p->wcd9xxx, - reg, val); - val = wcd9xxx_interface_reg_read( - pahu_p->wcd9xxx, reg); - } - } - } -} - -static int pahu_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai, - bool up) -{ - int ret = 0; - struct wcd9xxx_ch *ch; - - if (up) { - list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) { - ret = wcd9xxx_get_slave_port(ch->ch_num); - if (ret < 0) { - pr_err("%s: Invalid slave port ID: %d\n", - __func__, ret); - ret = -EINVAL; - } else { - set_bit(ret, &dai->ch_mask); - } - } - } else { - ret = wait_event_timeout(dai->dai_wait, (dai->ch_mask == 0), - msecs_to_jiffies( - WCD9360_SLIM_CLOSE_TIMEOUT)); - if (!ret) { - pr_err("%s: Slim close tx/rx wait timeout, ch_mask:0x%lx\n", - __func__, dai->ch_mask); - ret = -ETIMEDOUT; - } else { - ret = 0; - } - } - return ret; -} - -static int pahu_codec_enable_slimrx(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct wcd9xxx *core; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); - int ret = 0; - struct wcd9xxx_codec_dai_data *dai; - - core = dev_get_drvdata(codec->dev->parent); - - dev_dbg(codec->dev, "%s: event called! codec name %s num_dai %d\n" - "stream name %s event %d\n", - __func__, codec->component.name, - codec->component.num_dai, w->sname, event); - - dai = &pahu_p->dai[w->shift]; - dev_dbg(codec->dev, "%s: w->name %s w->shift %d event %d\n", - __func__, w->name, w->shift, event); - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - dai->bus_down_in_recovery = false; - pahu_codec_enable_slim_port_intr(dai, codec); - (void) pahu_codec_enable_slim_chmask(dai, true); - ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list, - dai->rate, dai->bit_width, - &dai->grph); - break; - case SND_SOC_DAPM_POST_PMD: - ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list, - dai->grph); - dev_dbg(codec->dev, "%s: Disconnect RX port, ret = %d\n", - __func__, ret); - - if (!dai->bus_down_in_recovery) - ret = pahu_codec_enable_slim_chmask(dai, false); - else - dev_dbg(codec->dev, - "%s: bus in recovery skip enable slim_chmask", - __func__); - ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list, - dai->grph); - break; - } - return ret; -} - -static int pahu_codec_enable_slimtx(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx_codec_dai_data *dai; - struct wcd9xxx *core; - int ret = 0; - - dev_dbg(codec->dev, - "%s: w->name %s, w->shift = %d, num_dai %d stream name %s\n", - __func__, w->name, w->shift, - codec->component.num_dai, w->sname); - - dai = &pahu_p->dai[w->shift]; - core = dev_get_drvdata(codec->dev->parent); - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - dai->bus_down_in_recovery = false; - pahu_codec_enable_slim_port_intr(dai, codec); - (void) pahu_codec_enable_slim_chmask(dai, true); - ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list, - dai->rate, dai->bit_width, - &dai->grph); - break; - case SND_SOC_DAPM_POST_PMD: - ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list, - dai->grph); - if (!dai->bus_down_in_recovery) - ret = pahu_codec_enable_slim_chmask(dai, false); - if (ret < 0) { - ret = wcd9xxx_disconnect_port(core, - &dai->wcd9xxx_ch_list, - dai->grph); - dev_dbg(codec->dev, "%s: Disconnect RX port, ret = %d\n", - __func__, ret); - } - break; - } - return ret; -} - -static int pahu_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct wcd9xxx *core = NULL; - struct snd_soc_codec *codec = NULL; - struct pahu_priv *pahu_p = NULL; - int ret = 0; - struct wcd9xxx_codec_dai_data *dai = NULL; - - codec = snd_soc_dapm_to_codec(w->dapm); - pahu_p = snd_soc_codec_get_drvdata(codec); - core = dev_get_drvdata(codec->dev->parent); - - dev_dbg(codec->dev, - "%s: num_dai %d stream name %s w->name %s event %d shift %d\n", - __func__, codec->component.num_dai, w->sname, - w->name, event, w->shift); - - if (w->shift != AIF4_VIFEED) { - pr_err("%s Error in enabling the tx path\n", __func__); - ret = -EINVAL; - goto done; - } - dai = &pahu_p->dai[w->shift]; - switch (event) { - case SND_SOC_DAPM_POST_PMU: - if (test_bit(VI_SENSE_1, &pahu_p->status_mask)) { - dev_dbg(codec->dev, "%s: spkr1 enabled\n", __func__); - /* Enable V&I sensing */ - snd_soc_update_bits(codec, - WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, - WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, - 0x20); - snd_soc_update_bits(codec, - WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x0F, 0x00); - snd_soc_update_bits(codec, - WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x0F, - 0x00); - snd_soc_update_bits(codec, - WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, - WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10, - 0x10); - snd_soc_update_bits(codec, - WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x00); - snd_soc_update_bits(codec, - WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, - 0x00); - } - if (test_bit(VI_SENSE_2, &pahu_p->status_mask)) { - pr_debug("%s: spkr2 enabled\n", __func__); - /* Enable V&I sensing */ - snd_soc_update_bits(codec, - WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, - 0x20); - snd_soc_update_bits(codec, - WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, - 0x20); - snd_soc_update_bits(codec, - WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x0F, - 0x00); - snd_soc_update_bits(codec, - WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x0F, - 0x00); - snd_soc_update_bits(codec, - WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10, - 0x10); - snd_soc_update_bits(codec, - WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10, - 0x10); - snd_soc_update_bits(codec, - WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, - 0x00); - snd_soc_update_bits(codec, - WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, - 0x00); - } - dai->bus_down_in_recovery = false; - pahu_codec_enable_slim_port_intr(dai, codec); - (void) pahu_codec_enable_slim_chmask(dai, true); - ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list, - dai->rate, dai->bit_width, - &dai->grph); - break; - case SND_SOC_DAPM_POST_PMD: - ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list, - dai->grph); - if (ret) - dev_err(codec->dev, "%s error in close_slim_sch_tx %d\n", - __func__, ret); - if (!dai->bus_down_in_recovery) - ret = pahu_codec_enable_slim_chmask(dai, false); - if (ret < 0) { - ret = wcd9xxx_disconnect_port(core, - &dai->wcd9xxx_ch_list, - dai->grph); - dev_dbg(codec->dev, "%s: Disconnect TX port, ret = %d\n", - __func__, ret); - } - if (test_bit(VI_SENSE_1, &pahu_p->status_mask)) { - /* Disable V&I sensing */ - dev_dbg(codec->dev, "%s: spkr1 disabled\n", __func__); - snd_soc_update_bits(codec, - WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, - WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, - 0x20); - snd_soc_update_bits(codec, - WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x00); - snd_soc_update_bits(codec, - WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10, - 0x00); - } - if (test_bit(VI_SENSE_2, &pahu_p->status_mask)) { - /* Disable V&I sensing */ - dev_dbg(codec->dev, "%s: spkr2 disabled\n", __func__); - snd_soc_update_bits(codec, - WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, - 0x20); - snd_soc_update_bits(codec, - WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, - 0x20); - snd_soc_update_bits(codec, - WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10, - 0x00); - snd_soc_update_bits(codec, - WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10, - 0x00); - } - break; - } -done: - return ret; -} - -static void pahu_codec_enable_i2s(struct snd_soc_codec *codec, bool enable) -{ - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - if (enable) { - if (++pahu->i2s_ref_cnt == 1) - snd_soc_update_bits(codec, WCD9360_DATA_HUB_I2S_1_CTL, - 0x01, 0x01); - } else { - if (--pahu->i2s_ref_cnt == 0) - snd_soc_update_bits(codec, WCD9360_DATA_HUB_I2S_1_CTL, - 0x01, 0x00); - } -} - -static int pahu_i2s_aif_rx_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); - switch(event) { - case SND_SOC_DAPM_PRE_PMU: - pahu_cdc_mclk_enable(codec, true); - break; - case SND_SOC_DAPM_POST_PMU: - pahu_codec_enable_i2s(codec, true); - break; - case SND_SOC_DAPM_PRE_PMD: - pahu_codec_enable_i2s(codec, false); - break; - case SND_SOC_DAPM_POST_PMD: - pahu_cdc_mclk_enable(codec, false); - break; - } - - return 0; -} - -static int pahu_i2s_aif_tx_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); - switch(event) { - case SND_SOC_DAPM_PRE_PMU: - pahu_cdc_mclk_enable(codec, true); - break; - case SND_SOC_DAPM_POST_PMU: - pahu_codec_enable_i2s(codec, true); - break; - case SND_SOC_DAPM_PRE_PMD: - pahu_codec_enable_i2s(codec, false); - break; - case SND_SOC_DAPM_POST_PMD: - pahu_cdc_mclk_enable(codec, false); - break; - } - - return 0; -} - -static int pahu_codec_enable_ldo_rxtx(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); - - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - pahu->ldo_rxtx_cnt++; - if (pahu->ldo_rxtx_cnt == 1) { - /* Enable VDD_LDO_RxTx regulator */ - msm_cdc_enable_ondemand_supply(pahu->wcd9xxx->dev, - pahu->wcd9xxx->supplies, - pdata->regulator, - pdata->num_supplies, - WCD9360_LDO_RXTX_SUPPLY_NAME); - - snd_soc_update_bits(codec, WCD9360_LDORXTX_LDORXTX, - 0x80, 0x80); - /* - * 200us sleep is required after LDO_RXTX is enabled as per - * HW requirement - */ - usleep_range(200, 250); - } - break; - case SND_SOC_DAPM_POST_PMD: - pahu->ldo_rxtx_cnt--; - if (pahu->ldo_rxtx_cnt < 0) - pahu->ldo_rxtx_cnt = 0; - - if (!pahu->ldo_rxtx_cnt) { - snd_soc_update_bits(codec, WCD9360_LDORXTX_LDORXTX, - 0x80, 0x00); - /* Disable VDD_LDO_RxTx regulator */ - msm_cdc_disable_ondemand_supply(pahu->wcd9xxx->dev, - pahu->wcd9xxx->supplies, - pdata->regulator, - pdata->num_supplies, - WCD9360_LDO_RXTX_SUPPLY_NAME); - } - break; - }; - dev_dbg(codec->dev, "%s: Current LDO RXTX user count: %d\n", __func__, - pahu->ldo_rxtx_cnt); - - return 0; -} - -static void pahu_spk_anc_update_callback(struct work_struct *work) -{ - struct spk_anc_work *spk_anc_dwork; - struct pahu_priv *pahu; - struct delayed_work *delayed_work; - struct snd_soc_codec *codec; - - delayed_work = to_delayed_work(work); - spk_anc_dwork = container_of(delayed_work, struct spk_anc_work, dwork); - pahu = spk_anc_dwork->pahu; - codec = pahu->codec; - - snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_CFG0, 0x10, 0x10); -} - -static int pahu_codec_enable_spkr_anc(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - int ret = 0; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - if (!pahu->anc_func) - return 0; - - dev_dbg(codec->dev, "%s: w: %s event: %d anc: %d\n", __func__, - w->name, event, pahu->anc_func); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - ret = pahu_codec_enable_anc(w, kcontrol, event); - schedule_delayed_work(&pahu->spk_anc_dwork.dwork, - msecs_to_jiffies(spk_anc_en_delay)); - break; - case SND_SOC_DAPM_POST_PMD: - cancel_delayed_work_sync(&pahu->spk_anc_dwork.dwork); - snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_CFG0, - 0x10, 0x00); - ret = pahu_codec_enable_anc(w, kcontrol, event); - break; - } - return ret; -} - -static int pahu_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - int ret = 0; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - /* - * 5ms sleep is required after PA is enabled as per - * HW requirement - */ - usleep_range(5000, 5500); - snd_soc_update_bits(codec, WCD9360_CDC_RX9_RX_PATH_CTL, - 0x10, 0x00); - /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, WCD9360_CDC_RX9_RX_PATH_MIX_CTL)) & - 0x10) - snd_soc_update_bits(codec, - WCD9360_CDC_RX9_RX_PATH_MIX_CTL, - 0x10, 0x00); - break; - default: - break; - }; - - return ret; -} - -static int pahu_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - int ret = 0; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - /* - * 5ms sleep is required after PA is enabled as per - * HW requirement - */ - usleep_range(5000, 5500); - snd_soc_update_bits(codec, WCD9360_CDC_RX0_RX_PATH_CTL, - 0x10, 0x00); - /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, WCD9360_CDC_RX0_RX_PATH_MIX_CTL)) & - 0x10) - snd_soc_update_bits(codec, - WCD9360_CDC_RX0_RX_PATH_MIX_CTL, - 0x10, 0x00); - break; - case SND_SOC_DAPM_POST_PMD: - /* - * 5ms sleep is required after PA is disabled as per - * HW requirement - */ - usleep_range(5000, 5500); - - if (!(strcmp(w->name, "ANC EAR PA"))) { - ret = pahu_codec_enable_anc(w, kcontrol, event); - snd_soc_update_bits(codec, WCD9360_CDC_RX0_RX_PATH_CFG0, - 0x10, 0x00); - } - break; - }; - - return ret; -} - -static int pahu_codec_ear_dac_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - int ret = 0; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (pahu->anc_func) { - ret = pahu_codec_enable_anc(w, kcontrol, event); - snd_soc_update_bits(codec, WCD9360_CDC_RX0_RX_PATH_CFG0, - 0x10, 0x10); - } - break; - default: - break; - }; - - return ret; -} - -static int pahu_codec_spk_boost_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - u16 boost_path_ctl, boost_path_cfg1; - u16 reg, reg_mix; - - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); - - if (!strcmp(w->name, "RX INT7 CHAIN")) { - boost_path_ctl = WCD9360_CDC_BOOST0_BOOST_PATH_CTL; - boost_path_cfg1 = WCD9360_CDC_RX7_RX_PATH_CFG1; - reg = WCD9360_CDC_RX7_RX_PATH_CTL; - reg_mix = WCD9360_CDC_RX7_RX_PATH_MIX_CTL; - } else if (!strcmp(w->name, "RX INT8 CHAIN")) { - boost_path_ctl = WCD9360_CDC_BOOST1_BOOST_PATH_CTL; - boost_path_cfg1 = WCD9360_CDC_RX8_RX_PATH_CFG1; - reg = WCD9360_CDC_RX8_RX_PATH_CTL; - reg_mix = WCD9360_CDC_RX8_RX_PATH_MIX_CTL; - } else { - dev_err(codec->dev, "%s: unknown widget: %s\n", - __func__, w->name); - return -EINVAL; - } - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x01); - snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x10); - snd_soc_update_bits(codec, reg, 0x10, 0x00); - if ((snd_soc_read(codec, reg_mix)) & 0x10) - snd_soc_update_bits(codec, reg_mix, 0x10, 0x00); - break; - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x00); - snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x00); - break; - }; - - return 0; -} - -static int __pahu_codec_enable_swr(struct snd_soc_dapm_widget *w, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct pahu_priv *pahu; - int ch_cnt = 0; - - pahu = snd_soc_codec_get_drvdata(codec); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) || - (strnstr(w->name, "INT7 MIX2", - sizeof("RX INT7 MIX2"))))) - pahu->swr.rx_7_count++; - if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) && - !pahu->swr.rx_8_count) - pahu->swr.rx_8_count++; - ch_cnt = !!(pahu->swr.rx_7_count) + pahu->swr.rx_8_count; - - swrm_wcd_notify(pahu->swr.ctrl_data[0].swr_pdev, - SWR_DEVICE_UP, NULL); - swrm_wcd_notify(pahu->swr.ctrl_data[0].swr_pdev, - SWR_SET_NUM_RX_CH, &ch_cnt); - break; - case SND_SOC_DAPM_POST_PMD: - if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) || - (strnstr(w->name, "INT7 MIX2", - sizeof("RX INT7 MIX2")))) - pahu->swr.rx_7_count--; - if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) && - pahu->swr.rx_8_count) - pahu->swr.rx_8_count--; - ch_cnt = !!(pahu->swr.rx_7_count) + pahu->swr.rx_8_count; - - swrm_wcd_notify(pahu->swr.ctrl_data[0].swr_pdev, - SWR_SET_NUM_RX_CH, &ch_cnt); - - break; - } - dev_dbg(pahu->dev, "%s: %s: current swr ch cnt: %d\n", - __func__, w->name, ch_cnt); - - return 0; -} - -static int pahu_codec_enable_swr(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - return __pahu_codec_enable_swr(w, event); -} - -static int pahu_codec_config_mad(struct snd_soc_codec *codec) -{ - int ret = 0; - int idx; - const struct firmware *fw; - struct firmware_cal *hwdep_cal = NULL; - struct wcd_mad_audio_cal *mad_cal = NULL; - const void *data; - const char *filename = WCD9360_MAD_AUDIO_FIRMWARE_PATH; - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - size_t cal_size; - - hwdep_cal = wcdcal_get_fw_cal(pahu->fw_data, WCD9XXX_MAD_CAL); - if (hwdep_cal) { - data = hwdep_cal->data; - cal_size = hwdep_cal->size; - dev_dbg(codec->dev, "%s: using hwdep calibration\n", - __func__); - } else { - ret = request_firmware(&fw, filename, codec->dev); - if (ret || !fw) { - dev_err(codec->dev, - "%s: MAD firmware acquire failed, err = %d\n", - __func__, ret); - return -ENODEV; - } - data = fw->data; - cal_size = fw->size; - dev_dbg(codec->dev, "%s: using request_firmware calibration\n", - __func__); - } - - if (cal_size < sizeof(*mad_cal)) { - dev_err(codec->dev, - "%s: Incorrect size %zd for MAD Cal, expected %zd\n", - __func__, cal_size, sizeof(*mad_cal)); - ret = -ENOMEM; - goto done; - } - - mad_cal = (struct wcd_mad_audio_cal *) (data); - if (!mad_cal) { - dev_err(codec->dev, - "%s: Invalid calibration data\n", - __func__); - ret = -EINVAL; - goto done; - } - - snd_soc_write(codec, WCD9360_SOC_MAD_MAIN_CTL_2, - mad_cal->microphone_info.cycle_time); - snd_soc_update_bits(codec, WCD9360_SOC_MAD_MAIN_CTL_1, 0xFF << 3, - ((uint16_t)mad_cal->microphone_info.settle_time) - << 3); - - /* Audio */ - snd_soc_write(codec, WCD9360_SOC_MAD_AUDIO_CTL_8, - mad_cal->audio_info.rms_omit_samples); - snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_CTL_1, - 0x07 << 4, mad_cal->audio_info.rms_comp_time << 4); - snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_CTL_2, 0x03 << 2, - mad_cal->audio_info.detection_mechanism << 2); - snd_soc_write(codec, WCD9360_SOC_MAD_AUDIO_CTL_7, - mad_cal->audio_info.rms_diff_threshold & 0x3F); - snd_soc_write(codec, WCD9360_SOC_MAD_AUDIO_CTL_5, - mad_cal->audio_info.rms_threshold_lsb); - snd_soc_write(codec, WCD9360_SOC_MAD_AUDIO_CTL_6, - mad_cal->audio_info.rms_threshold_msb); - - for (idx = 0; idx < ARRAY_SIZE(mad_cal->audio_info.iir_coefficients); - idx++) { - snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_IIR_CTL_PTR, - 0x3F, idx); - snd_soc_write(codec, WCD9360_SOC_MAD_AUDIO_IIR_CTL_VAL, - mad_cal->audio_info.iir_coefficients[idx]); - dev_dbg(codec->dev, "%s:MAD Audio IIR Coef[%d] = 0X%x", - __func__, idx, - mad_cal->audio_info.iir_coefficients[idx]); - } - - /* Beacon */ - snd_soc_write(codec, WCD9360_SOC_MAD_BEACON_CTL_8, - mad_cal->beacon_info.rms_omit_samples); - snd_soc_update_bits(codec, WCD9360_SOC_MAD_BEACON_CTL_1, - 0x07 << 4, mad_cal->beacon_info.rms_comp_time << 4); - snd_soc_update_bits(codec, WCD9360_SOC_MAD_BEACON_CTL_2, 0x03 << 2, - mad_cal->beacon_info.detection_mechanism << 2); - snd_soc_write(codec, WCD9360_SOC_MAD_BEACON_CTL_7, - mad_cal->beacon_info.rms_diff_threshold & 0x1F); - snd_soc_write(codec, WCD9360_SOC_MAD_BEACON_CTL_5, - mad_cal->beacon_info.rms_threshold_lsb); - snd_soc_write(codec, WCD9360_SOC_MAD_BEACON_CTL_6, - mad_cal->beacon_info.rms_threshold_msb); - - for (idx = 0; idx < ARRAY_SIZE(mad_cal->beacon_info.iir_coefficients); - idx++) { - snd_soc_update_bits(codec, WCD9360_SOC_MAD_BEACON_IIR_CTL_PTR, - 0x3F, idx); - snd_soc_write(codec, WCD9360_SOC_MAD_BEACON_IIR_CTL_VAL, - mad_cal->beacon_info.iir_coefficients[idx]); - dev_dbg(codec->dev, "%s:MAD Beacon IIR Coef[%d] = 0X%x", - __func__, idx, - mad_cal->beacon_info.iir_coefficients[idx]); - } - - /* Ultrasound */ - snd_soc_update_bits(codec, WCD9360_SOC_MAD_ULTR_CTL_1, - 0x07 << 4, - mad_cal->ultrasound_info.rms_comp_time << 4); - snd_soc_update_bits(codec, WCD9360_SOC_MAD_ULTR_CTL_2, 0x03 << 2, - mad_cal->ultrasound_info.detection_mechanism << 2); - snd_soc_write(codec, WCD9360_SOC_MAD_ULTR_CTL_7, - mad_cal->ultrasound_info.rms_diff_threshold & 0x1F); - snd_soc_write(codec, WCD9360_SOC_MAD_ULTR_CTL_5, - mad_cal->ultrasound_info.rms_threshold_lsb); - snd_soc_write(codec, WCD9360_SOC_MAD_ULTR_CTL_6, - mad_cal->ultrasound_info.rms_threshold_msb); - -done: - if (!hwdep_cal) - release_firmware(fw); - - return ret; -} - -static int __pahu_codec_enable_mad(struct snd_soc_codec *codec, bool enable) -{ - int rc = 0; - - /* Return if CPE INPUT is DEC1 */ - if (snd_soc_read(codec, WCD9360_CPE_SS_SVA_CFG) & 0x04) { - dev_dbg(codec->dev, "%s: MAD is bypassed, skip mad %s\n", - __func__, enable ? "enable" : "disable"); - return rc; - } - - dev_dbg(codec->dev, "%s: enable = %s\n", __func__, - enable ? "enable" : "disable"); - - if (enable) { - snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_CTL_2, - 0x03, 0x03); - rc = pahu_codec_config_mad(codec); - if (rc < 0) { - snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_CTL_2, - 0x03, 0x00); - goto done; - } - - /* Turn on MAD clk */ - snd_soc_update_bits(codec, WCD9360_CPE_SS_MAD_CTL, - 0x01, 0x01); - - /* Undo reset for MAD */ - snd_soc_update_bits(codec, WCD9360_CPE_SS_MAD_CTL, - 0x02, 0x00); - snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_MCLK_CFG, - 0x04, 0x04); - } else { - snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_CTL_2, - 0x03, 0x00); - /* Reset the MAD block */ - snd_soc_update_bits(codec, WCD9360_CPE_SS_MAD_CTL, - 0x02, 0x02); - /* Turn off MAD clk */ - snd_soc_update_bits(codec, WCD9360_CPE_SS_MAD_CTL, - 0x01, 0x00); - snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_MCLK_CFG, - 0x04, 0x00); - } -done: - return rc; -} - -static int pahu_codec_ape_enable_mad(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - int rc = 0; - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, WCD9360_CPE_SS_SVA_CFG, 0x40, 0x40); - rc = __pahu_codec_enable_mad(codec, true); - break; - case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, WCD9360_CPE_SS_SVA_CFG, 0x40, 0x00); - __pahu_codec_enable_mad(codec, false); - break; - } - - dev_dbg(pahu->dev, "%s: event = %d\n", __func__, event); - return rc; -} - -static int pahu_codec_cpe_mad_ctl(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - int rc = 0; - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - pahu->mad_switch_cnt++; - if (pahu->mad_switch_cnt != 1) - goto done; - - snd_soc_update_bits(codec, WCD9360_CPE_SS_SVA_CFG, 0x20, 0x20); - rc = __pahu_codec_enable_mad(codec, true); - if (rc < 0) { - pahu->mad_switch_cnt--; - goto done; - } - - break; - case SND_SOC_DAPM_PRE_PMD: - pahu->mad_switch_cnt--; - if (pahu->mad_switch_cnt != 0) - goto done; - - snd_soc_update_bits(codec, WCD9360_CPE_SS_SVA_CFG, 0x20, 0x00); - __pahu_codec_enable_mad(codec, false); - break; - } -done: - dev_dbg(pahu->dev, "%s: event = %d, mad_switch_cnt = %d\n", - __func__, event, pahu->mad_switch_cnt); - return rc; -} - -static int pahu_get_asrc_mode(struct pahu_priv *pahu, int asrc, - u8 main_sr, u8 mix_sr) -{ - u8 asrc_output_mode; - int asrc_mode = CONV_88P2K_TO_384K; - - if ((asrc < 0) || (asrc >= ASRC_MAX)) - return 0; - - asrc_output_mode = pahu->asrc_output_mode[asrc]; - - if (asrc_output_mode) { - /* - * If Mix sample rate is < 96KHz, use 96K to 352.8K - * conversion, or else use 384K to 352.8K conversion - */ - if (mix_sr < 5) - asrc_mode = CONV_96K_TO_352P8K; - else - asrc_mode = CONV_384K_TO_352P8K; - } else { - /* Integer main and Fractional mix path */ - if (main_sr < 8 && mix_sr > 9) { - asrc_mode = CONV_352P8K_TO_384K; - } else if (main_sr > 8 && mix_sr < 8) { - /* Fractional main and Integer mix path */ - if (mix_sr < 5) - asrc_mode = CONV_96K_TO_352P8K; - else - asrc_mode = CONV_384K_TO_352P8K; - } else if (main_sr < 8 && mix_sr < 8) { - /* Integer main and Integer mix path */ - asrc_mode = CONV_96K_TO_384K; - } - } - - return asrc_mode; -} - -static int pahu_codec_wdma3_ctl(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - /* Fix to 16KHz */ - snd_soc_update_bits(codec, WCD9360_DMA_WDMA_CTL_3, - 0xF0, 0x10); - /* Select mclk_1 */ - snd_soc_update_bits(codec, WCD9360_DMA_WDMA_CTL_3, - 0x02, 0x00); - /* Enable DMA */ - snd_soc_update_bits(codec, WCD9360_DMA_WDMA_CTL_3, - 0x01, 0x01); - break; - - case SND_SOC_DAPM_POST_PMD: - /* Disable DMA */ - snd_soc_update_bits(codec, WCD9360_DMA_WDMA_CTL_3, - 0x01, 0x00); - break; - - }; - - return 0; -} -static int pahu_codec_enable_asrc(struct snd_soc_codec *codec, - int asrc_in, int event) -{ - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - u16 cfg_reg, ctl_reg, clk_reg, asrc_ctl, mix_ctl_reg, paired_reg; - int asrc, ret = 0; - u8 main_sr, mix_sr, asrc_mode = 0; - - switch (asrc_in) { - case ASRC_IN_SPKR1: - cfg_reg = WCD9360_CDC_RX7_RX_PATH_CFG0; - ctl_reg = WCD9360_CDC_RX7_RX_PATH_CTL; - clk_reg = WCD9360_MIXING_ASRC2_CLK_RST_CTL; - paired_reg = WCD9360_MIXING_ASRC2_CLK_RST_CTL; - asrc_ctl = WCD9360_MIXING_ASRC2_CTL1; - asrc = ASRC2; - break; - case ASRC_IN_SPKR2: - cfg_reg = WCD9360_CDC_RX8_RX_PATH_CFG0; - ctl_reg = WCD9360_CDC_RX8_RX_PATH_CTL; - clk_reg = WCD9360_MIXING_ASRC3_CLK_RST_CTL; - paired_reg = WCD9360_MIXING_ASRC3_CLK_RST_CTL; - asrc_ctl = WCD9360_MIXING_ASRC3_CTL1; - asrc = ASRC3; - break; - default: - dev_err(codec->dev, "%s: Invalid asrc input :%d\n", __func__, - asrc_in); - ret = -EINVAL; - goto done; - }; - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (pahu->asrc_users[asrc] == 0) { - if ((snd_soc_read(codec, clk_reg) & 0x02) || - (snd_soc_read(codec, paired_reg) & 0x02)) { - snd_soc_update_bits(codec, clk_reg, - 0x02, 0x00); - snd_soc_update_bits(codec, paired_reg, - 0x02, 0x00); - } - snd_soc_update_bits(codec, cfg_reg, 0x80, 0x80); - snd_soc_update_bits(codec, clk_reg, 0x01, 0x01); - main_sr = snd_soc_read(codec, ctl_reg) & 0x0F; - mix_ctl_reg = ctl_reg + 5; - mix_sr = snd_soc_read(codec, mix_ctl_reg) & 0x0F; - asrc_mode = pahu_get_asrc_mode(pahu, asrc, - main_sr, mix_sr); - dev_dbg(codec->dev, "%s: main_sr:%d mix_sr:%d asrc_mode %d\n", - __func__, main_sr, mix_sr, asrc_mode); - snd_soc_update_bits(codec, asrc_ctl, 0x07, asrc_mode); - } - pahu->asrc_users[asrc]++; - break; - case SND_SOC_DAPM_POST_PMD: - pahu->asrc_users[asrc]--; - if (pahu->asrc_users[asrc] <= 0) { - pahu->asrc_users[asrc] = 0; - snd_soc_update_bits(codec, asrc_ctl, 0x07, 0x00); - snd_soc_update_bits(codec, cfg_reg, 0x80, 0x00); - snd_soc_update_bits(codec, clk_reg, 0x03, 0x02); - } - break; - }; - - dev_dbg(codec->dev, "%s: ASRC%d, users: %d\n", - __func__, asrc, pahu->asrc_users[asrc]); - -done: - return ret; -} - -static int pahu_codec_enable_asrc_resampler(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - int ret = 0; - u8 cfg, asrc_in; - - cfg = snd_soc_read(codec, WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0); - if (!(cfg & 0xFF)) { - dev_err(codec->dev, "%s: ASRC%u input not selected\n", - __func__, w->shift); - return -EINVAL; - } - - switch (w->shift) { - case ASRC2: - asrc_in = ((cfg & 0x30) == 0x20) ? ASRC_IN_SPKR1 : ASRC_INVALID; - ret = pahu_codec_enable_asrc(codec, asrc_in, event); - break; - case ASRC3: - asrc_in = ((cfg & 0xC0) == 0x80) ? ASRC_IN_SPKR2 : ASRC_INVALID; - ret = pahu_codec_enable_asrc(codec, asrc_in, event); - break; - default: - dev_err(codec->dev, "%s: Invalid asrc:%u\n", __func__, - w->shift); - ret = -EINVAL; - break; - }; - - return ret; -} - -static int pahu_enable_native_supply(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (++pahu->native_clk_users == 1) { - snd_soc_update_bits(codec, WCD9360_CLK_SYS_PLL_ENABLES, - 0x01, 0x01); - usleep_range(100, 120); - snd_soc_update_bits(codec, WCD9360_CLK_SYS_MCLK2_PRG1, - 0x06, 0x02); - snd_soc_update_bits(codec, WCD9360_CLK_SYS_MCLK2_PRG1, - 0x01, 0x01); - snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_GATE, - 0x04, 0x00); - /* Add sleep as per HW register sequence */ - usleep_range(30, 50); - snd_soc_update_bits(codec, - WCD9360_CDC_CLK_RST_CTRL_MCLK_CONTROL, - 0x02, 0x02); - snd_soc_update_bits(codec, - WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, - 0x10, 0x10); - } - break; - case SND_SOC_DAPM_PRE_PMD: - if (pahu->native_clk_users && - (--pahu->native_clk_users == 0)) { - snd_soc_update_bits(codec, - WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, - 0x10, 0x00); - snd_soc_update_bits(codec, - WCD9360_CDC_CLK_RST_CTRL_MCLK_CONTROL, - 0x02, 0x00); - snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_GATE, - 0x04, 0x04); - snd_soc_update_bits(codec, WCD9360_CLK_SYS_MCLK2_PRG1, - 0x01, 0x00); - snd_soc_update_bits(codec, WCD9360_CLK_SYS_MCLK2_PRG1, - 0x06, 0x00); - snd_soc_update_bits(codec, WCD9360_CLK_SYS_PLL_ENABLES, - 0x01, 0x00); - } - break; - } - - dev_dbg(codec->dev, "%s: native_clk_users: %d, event: %d\n", - __func__, pahu->native_clk_users, event); - - return 0; -} - -static int pahu_codec_config_ear_spkr_gain(struct snd_soc_codec *codec, - int event, int gain_reg) -{ - int comp_gain_offset, val; - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - switch (pahu->swr.spkr_mode) { - /* Compander gain in SPKR_MODE1 case is 12 dB */ - case WCD9360_SPKR_MODE_1: - comp_gain_offset = -12; - break; - /* Default case compander gain is 15 dB */ - default: - comp_gain_offset = -15; - break; - } - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - /* Apply ear spkr gain only if compander is enabled */ - if (pahu->comp_enabled[COMPANDER_7] && - (gain_reg == WCD9360_CDC_RX7_RX_VOL_CTL || - gain_reg == WCD9360_CDC_RX7_RX_VOL_MIX_CTL) && - (pahu->ear_spkr_gain != 0)) { - /* For example, val is -8(-12+5-1) for 4dB of gain */ - val = comp_gain_offset + pahu->ear_spkr_gain - 1; - snd_soc_write(codec, gain_reg, val); - - dev_dbg(codec->dev, "%s: RX7 Volume %d dB\n", - __func__, val); - } - break; - case SND_SOC_DAPM_POST_PMD: - /* - * Reset RX7 volume to 0 dB if compander is enabled and - * ear_spkr_gain is non-zero. - */ - if (pahu->comp_enabled[COMPANDER_7] && - (gain_reg == WCD9360_CDC_RX7_RX_VOL_CTL || - gain_reg == WCD9360_CDC_RX7_RX_VOL_MIX_CTL) && - (pahu->ear_spkr_gain != 0)) { - snd_soc_write(codec, gain_reg, 0x0); - - dev_dbg(codec->dev, "%s: Reset RX7 Volume to 0 dB\n", - __func__); - } - break; - } - - return 0; -} - -static int pahu_config_compander(struct snd_soc_codec *codec, int interp_n, - int event) -{ - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - int comp; - u16 comp_ctl0_reg, rx_path_cfg0_reg; - - /* HPH, LO are not valid and AUX does not have compander */ - if (((interp_n >= INTERP_HPHL_NA) && (interp_n <= INTERP_LO4_NA)) || - (interp_n == INTERP_AUX)) - return 0; - - comp = interp_n; - dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n", - __func__, event, comp, pahu->comp_enabled[comp]); - - if (!pahu->comp_enabled[comp]) - return 0; - - comp_ctl0_reg = WCD9360_CDC_COMPANDER0_CTL0 + (comp * 8); - rx_path_cfg0_reg = WCD9360_CDC_RX0_RX_PATH_CFG0 + (comp * 20); - - if (SND_SOC_DAPM_EVENT_ON(event)) { - /* Enable Compander Clock */ - snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01); - /* Soft reset */ - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); - /* Compander enable */ - snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02); - } - - if (SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); - } - - return 0; -} - -/** - * pahu_codec_enable_interp_clk - Enable main path Interpolator - * clock. - * - * @codec: Codec instance - * @event: Indicates speaker path gain offset value - * @intp_idx: Interpolator index - * Returns number of main clock users - */ -int pahu_codec_enable_interp_clk(struct snd_soc_codec *codec, - int event, int interp_idx) -{ - struct pahu_priv *pahu; - u16 main_reg; - - if (!codec) { - pr_err("%s: codec is NULL\n", __func__); - return -EINVAL; - } - - pahu = snd_soc_codec_get_drvdata(codec); - - main_reg = WCD9360_CDC_RX0_RX_PATH_CTL + - (interp_idx * WCD9360_RX_PATH_CTL_OFFSET); - - if (interp_idx == INTERP_AUX) - main_reg = WCD9360_CDC_RX9_RX_PATH_CTL; - - if (SND_SOC_DAPM_EVENT_ON(event)) { - if (pahu->main_clk_users[interp_idx] == 0) { - /* Main path PGA mute enable */ - snd_soc_update_bits(codec, main_reg, 0x10, 0x10); - /* Clk enable */ - snd_soc_update_bits(codec, main_reg, 0x20, 0x20); - pahu_config_compander(codec, interp_idx, event); - } - pahu->main_clk_users[interp_idx]++; - } - - if (SND_SOC_DAPM_EVENT_OFF(event)) { - pahu->main_clk_users[interp_idx]--; - if (pahu->main_clk_users[interp_idx] <= 0) { - pahu->main_clk_users[interp_idx] = 0; - pahu_config_compander(codec, interp_idx, event); - /* Clk Disable */ - snd_soc_update_bits(codec, main_reg, 0x20, 0x00); - /* Reset enable and disable */ - snd_soc_update_bits(codec, main_reg, 0x40, 0x40); - snd_soc_update_bits(codec, main_reg, 0x40, 0x00); - /* Reset rate to 48K*/ - snd_soc_update_bits(codec, main_reg, 0x0F, 0x04); - } - } - - dev_dbg(codec->dev, "%s event %d main_clk_users %d\n", - __func__, event, pahu->main_clk_users[interp_idx]); - - return pahu->main_clk_users[interp_idx]; -} -EXPORT_SYMBOL(pahu_codec_enable_interp_clk); - -static int pahu_codec_enable_mix_path(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - u16 gain_reg, mix_reg; - int offset_val = 0; - int val = 0; - - if (w->shift >= WCD9360_NUM_INTERPOLATORS || - ((w->shift >= INTERP_HPHL_NA) && (w->shift <= INTERP_LO4_NA))) { - dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", - __func__, w->shift, w->name); - return -EINVAL; - }; - - gain_reg = WCD9360_CDC_RX0_RX_VOL_MIX_CTL + - (w->shift * WCD9360_RX_PATH_CTL_OFFSET); - mix_reg = WCD9360_CDC_RX0_RX_PATH_MIX_CTL + - (w->shift * WCD9360_RX_PATH_CTL_OFFSET); - - if (w->shift == INTERP_AUX) { - gain_reg = WCD9360_CDC_RX9_RX_VOL_MIX_CTL; - mix_reg = WCD9360_CDC_RX9_RX_PATH_MIX_CTL; - } - - if (w->shift == INTERP_SPKR1 || w->shift == INTERP_SPKR2) - __pahu_codec_enable_swr(w, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - pahu_codec_enable_interp_clk(codec, event, w->shift); - /* Clk enable */ - snd_soc_update_bits(codec, mix_reg, 0x20, 0x20); - break; - case SND_SOC_DAPM_POST_PMU: - if ((pahu->swr.spkr_gain_offset == - WCD9360_RX_GAIN_OFFSET_M1P5_DB) && - (pahu->comp_enabled[COMPANDER_7] || - pahu->comp_enabled[COMPANDER_8]) && - (gain_reg == WCD9360_CDC_RX7_RX_VOL_MIX_CTL || - gain_reg == WCD9360_CDC_RX8_RX_VOL_MIX_CTL)) { - snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_SEC1, - 0x01, 0x01); - snd_soc_update_bits(codec, - WCD9360_CDC_RX7_RX_PATH_MIX_SEC0, - 0x01, 0x01); - snd_soc_update_bits(codec, WCD9360_CDC_RX8_RX_PATH_SEC1, - 0x01, 0x01); - snd_soc_update_bits(codec, - WCD9360_CDC_RX8_RX_PATH_MIX_SEC0, - 0x01, 0x01); - offset_val = -2; - } - val = snd_soc_read(codec, gain_reg); - val += offset_val; - snd_soc_write(codec, gain_reg, val); - pahu_codec_config_ear_spkr_gain(codec, event, gain_reg); - break; - case SND_SOC_DAPM_POST_PMD: - /* Clk Disable */ - snd_soc_update_bits(codec, mix_reg, 0x20, 0x00); - pahu_codec_enable_interp_clk(codec, event, w->shift); - /* Reset enable and disable */ - snd_soc_update_bits(codec, mix_reg, 0x40, 0x40); - snd_soc_update_bits(codec, mix_reg, 0x40, 0x00); - - if ((pahu->swr.spkr_gain_offset == - WCD9360_RX_GAIN_OFFSET_M1P5_DB) && - (pahu->comp_enabled[COMPANDER_7] || - pahu->comp_enabled[COMPANDER_8]) && - (gain_reg == WCD9360_CDC_RX7_RX_VOL_MIX_CTL || - gain_reg == WCD9360_CDC_RX8_RX_VOL_MIX_CTL)) { - snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_SEC1, - 0x01, 0x00); - snd_soc_update_bits(codec, - WCD9360_CDC_RX7_RX_PATH_MIX_SEC0, - 0x01, 0x00); - snd_soc_update_bits(codec, WCD9360_CDC_RX8_RX_PATH_SEC1, - 0x01, 0x00); - snd_soc_update_bits(codec, - WCD9360_CDC_RX8_RX_PATH_MIX_SEC0, - 0x01, 0x00); - offset_val = 2; - val = snd_soc_read(codec, gain_reg); - val += offset_val; - snd_soc_write(codec, gain_reg, val); - } - pahu_codec_config_ear_spkr_gain(codec, event, gain_reg); - break; - }; - dev_dbg(codec->dev, "%s event %d name %s\n", __func__, event, w->name); - - return 0; -} - -static int pahu_codec_enable_main_path(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - u16 gain_reg; - u16 reg; - int val; - int offset_val = 0; - - dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); - - if (w->shift >= WCD9360_NUM_INTERPOLATORS || - ((w->shift >= INTERP_HPHL_NA) && (w->shift <= INTERP_LO4_NA))) { - dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", - __func__, w->shift, w->name); - return -EINVAL; - }; - - reg = WCD9360_CDC_RX0_RX_PATH_CTL + (w->shift * - WCD9360_RX_PATH_CTL_OFFSET); - gain_reg = WCD9360_CDC_RX0_RX_VOL_CTL + (w->shift * - WCD9360_RX_PATH_CTL_OFFSET); - - if (w->shift == INTERP_AUX) { - reg = WCD9360_CDC_RX9_RX_PATH_CTL; - gain_reg = WCD9360_CDC_RX9_RX_VOL_CTL; - } - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - pahu_codec_enable_interp_clk(codec, event, w->shift); - break; - case SND_SOC_DAPM_POST_PMU: - /* apply gain after int clk is enabled */ - if ((pahu->swr.spkr_gain_offset == - WCD9360_RX_GAIN_OFFSET_M1P5_DB) && - (pahu->comp_enabled[COMPANDER_7] || - pahu->comp_enabled[COMPANDER_8]) && - (gain_reg == WCD9360_CDC_RX7_RX_VOL_CTL || - gain_reg == WCD9360_CDC_RX8_RX_VOL_CTL)) { - snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_SEC1, - 0x01, 0x01); - snd_soc_update_bits(codec, - WCD9360_CDC_RX7_RX_PATH_MIX_SEC0, - 0x01, 0x01); - snd_soc_update_bits(codec, WCD9360_CDC_RX8_RX_PATH_SEC1, - 0x01, 0x01); - snd_soc_update_bits(codec, - WCD9360_CDC_RX8_RX_PATH_MIX_SEC0, - 0x01, 0x01); - offset_val = -2; - } - val = snd_soc_read(codec, gain_reg); - val += offset_val; - snd_soc_write(codec, gain_reg, val); - pahu_codec_config_ear_spkr_gain(codec, event, gain_reg); - break; - case SND_SOC_DAPM_POST_PMD: - pahu_codec_enable_interp_clk(codec, event, w->shift); - - if ((pahu->swr.spkr_gain_offset == - WCD9360_RX_GAIN_OFFSET_M1P5_DB) && - (pahu->comp_enabled[COMPANDER_7] || - pahu->comp_enabled[COMPANDER_8]) && - (gain_reg == WCD9360_CDC_RX7_RX_VOL_CTL || - gain_reg == WCD9360_CDC_RX8_RX_VOL_CTL)) { - snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_SEC1, - 0x01, 0x00); - snd_soc_update_bits(codec, - WCD9360_CDC_RX7_RX_PATH_MIX_SEC0, - 0x01, 0x00); - snd_soc_update_bits(codec, WCD9360_CDC_RX8_RX_PATH_SEC1, - 0x01, 0x00); - snd_soc_update_bits(codec, - WCD9360_CDC_RX8_RX_PATH_MIX_SEC0, - 0x01, 0x00); - offset_val = 2; - val = snd_soc_read(codec, gain_reg); - val += offset_val; - snd_soc_write(codec, gain_reg, val); - } - pahu_codec_config_ear_spkr_gain(codec, event, gain_reg); - break; - }; - - return 0; -} - -static int pahu_codec_set_iir_gain(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - dev_dbg(codec->dev, "%s: event = %d\n", __func__, event); - - switch (event) { - case SND_SOC_DAPM_POST_PMU: /* fall through */ - case SND_SOC_DAPM_PRE_PMD: - if (strnstr(w->name, "IIR0", sizeof("IIR0"))) { - snd_soc_write(codec, - WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, - snd_soc_read(codec, - WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)); - snd_soc_write(codec, - WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, - snd_soc_read(codec, - WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)); - snd_soc_write(codec, - WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, - snd_soc_read(codec, - WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)); - snd_soc_write(codec, - WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, - snd_soc_read(codec, - WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)); - } - break; - } - return 0; -} - -static int pahu_codec_find_amic_input(struct snd_soc_codec *codec, - int adc_mux_n) -{ - u16 mask, shift, adc_mux_in_reg; - u16 amic_mux_sel_reg; - bool is_amic; - - if (adc_mux_n < 0 || adc_mux_n > WCD9360_MAX_VALID_ADC_MUX || - adc_mux_n == WCD9360_INVALID_ADC_MUX) - return 0; - - if (adc_mux_n < 3) { - adc_mux_in_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + - 2 * adc_mux_n; - mask = 0x03; - shift = 0; - amic_mux_sel_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + - 2 * adc_mux_n; - } else if (adc_mux_n < 4) { - adc_mux_in_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1; - mask = 0x03; - shift = 0; - amic_mux_sel_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + - 2 * adc_mux_n; - } else if (adc_mux_n < 7) { - adc_mux_in_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + - 2 * (adc_mux_n - 4); - mask = 0x0C; - shift = 2; - amic_mux_sel_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + - adc_mux_n - 4; - } else if (adc_mux_n < 8) { - adc_mux_in_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1; - mask = 0x0C; - shift = 2; - amic_mux_sel_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + - adc_mux_n - 4; - } else if (adc_mux_n < 12) { - adc_mux_in_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + - 2 * (((adc_mux_n == 8) ? (adc_mux_n - 8) : - (adc_mux_n - 9))); - mask = 0x30; - shift = 4; - amic_mux_sel_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0 + - ((adc_mux_n == 8) ? (adc_mux_n - 8) : - (adc_mux_n - 9)); - } - - is_amic = (((snd_soc_read(codec, adc_mux_in_reg) & mask) >> shift) - == 1); - if (!is_amic) - return 0; - - return snd_soc_read(codec, amic_mux_sel_reg) & 0x07; -} - -static void pahu_codec_set_tx_hold(struct snd_soc_codec *codec, - u16 amic_reg, bool set) -{ - u8 mask = 0x20; - u8 val; - - if (amic_reg == WCD9360_ANA_AMIC1 || - amic_reg == WCD9360_ANA_AMIC3) - mask = 0x40; - - val = set ? mask : 0x00; - - switch (amic_reg) { - case WCD9360_ANA_AMIC1: - case WCD9360_ANA_AMIC2: - snd_soc_update_bits(codec, WCD9360_ANA_AMIC2, mask, val); - break; - case WCD9360_ANA_AMIC3: - case WCD9360_ANA_AMIC4: - snd_soc_update_bits(codec, WCD9360_ANA_AMIC4, mask, val); - break; - default: - dev_dbg(codec->dev, "%s: invalid amic: %d\n", - __func__, amic_reg); - break; - } -} - -static int pahu_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - int adc_mux_n = w->shift; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - int amic_n; - - dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - amic_n = pahu_codec_find_amic_input(codec, adc_mux_n); - break; - default: - break; - } - - return 0; -} - -static u16 pahu_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic) -{ - u16 pwr_level_reg = 0; - - switch (amic) { - case 1: - case 2: - pwr_level_reg = WCD9360_ANA_AMIC1; - break; - - case 3: - case 4: - pwr_level_reg = WCD9360_ANA_AMIC3; - break; - default: - dev_dbg(codec->dev, "%s: invalid amic: %d\n", - __func__, amic); - break; - } - - return pwr_level_reg; -} - -#define TX_HPF_CUT_OFF_FREQ_MASK 0x60 -#define CF_MIN_3DB_4HZ 0x0 -#define CF_MIN_3DB_75HZ 0x1 -#define CF_MIN_3DB_150HZ 0x2 - -static void pahu_tx_hpf_corner_freq_callback(struct work_struct *work) -{ - struct delayed_work *hpf_delayed_work; - struct hpf_work *hpf_work; - struct pahu_priv *pahu; - struct snd_soc_codec *codec; - u16 dec_cfg_reg, amic_reg, go_bit_reg; - u8 hpf_cut_off_freq; - int amic_n; - - hpf_delayed_work = to_delayed_work(work); - hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); - pahu = hpf_work->pahu; - codec = pahu->codec; - hpf_cut_off_freq = hpf_work->hpf_cut_off_freq; - - dec_cfg_reg = WCD9360_CDC_TX0_TX_PATH_CFG0 + 16 * hpf_work->decimator; - go_bit_reg = dec_cfg_reg + 7; - - dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", - __func__, hpf_work->decimator, hpf_cut_off_freq); - - amic_n = pahu_codec_find_amic_input(codec, hpf_work->decimator); - if (amic_n) { - amic_reg = WCD9360_ANA_AMIC1 + amic_n - 1; - pahu_codec_set_tx_hold(codec, amic_reg, false); - } - snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, - hpf_cut_off_freq << 5); - snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x02); - /* Minimum 1 clk cycle delay is required as per HW spec */ - usleep_range(1000, 1010); - snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x00); -} - -static void pahu_tx_mute_update_callback(struct work_struct *work) -{ - struct tx_mute_work *tx_mute_dwork; - struct pahu_priv *pahu; - struct delayed_work *delayed_work; - struct snd_soc_codec *codec; - u16 tx_vol_ctl_reg; - - delayed_work = to_delayed_work(work); - tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); - pahu = tx_mute_dwork->pahu; - codec = pahu->codec; - - tx_vol_ctl_reg = WCD9360_CDC_TX0_TX_PATH_CTL + - 16 * tx_mute_dwork->decimator; - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); -} - -static int pahu_codec_enable_rx_path_clk(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - u16 sidetone_reg; - - dev_dbg(codec->dev, "%s %d %d\n", __func__, event, w->shift); - sidetone_reg = WCD9360_CDC_RX0_RX_PATH_CFG1 + 0x14*(w->shift); - - if (w->shift == INTERP_AUX) - sidetone_reg = WCD9360_CDC_RX9_RX_PATH_CFG1; - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (!strcmp(w->name, "RX INT7 MIX2 INP")) - __pahu_codec_enable_swr(w, event); - pahu_codec_enable_interp_clk(codec, event, w->shift); - snd_soc_update_bits(codec, sidetone_reg, 0x10, 0x10); - break; - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, sidetone_reg, 0x10, 0x00); - pahu_codec_enable_interp_clk(codec, event, w->shift); - if (!strcmp(w->name, "RX INT7 MIX2 INP")) - __pahu_codec_enable_swr(w, event); - break; - default: - break; - }; - return 0; -} - -static int pahu_codec_enable_dec(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - unsigned int decimator; - char *dec_adc_mux_name = NULL; - char *widget_name = NULL; - char *wname; - int ret = 0, amic_n; - u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg; - u16 tx_gain_ctl_reg; - char *dec; - u8 hpf_cut_off_freq; - - dev_dbg(codec->dev, "%s %d\n", __func__, event); - - widget_name = kstrndup(w->name, 15, GFP_KERNEL); - if (!widget_name) - return -ENOMEM; - - wname = widget_name; - dec_adc_mux_name = strsep(&widget_name, " "); - if (!dec_adc_mux_name) { - dev_err(codec->dev, "%s: Invalid decimator = %s\n", - __func__, w->name); - ret = -EINVAL; - goto out; - } - dec_adc_mux_name = widget_name; - - dec = strpbrk(dec_adc_mux_name, "012345678"); - if (!dec) { - dev_err(codec->dev, "%s: decimator index not found\n", - __func__); - ret = -EINVAL; - goto out; - } - - ret = kstrtouint(dec, 10, &decimator); - if (ret < 0) { - dev_err(codec->dev, "%s: Invalid decimator = %s\n", - __func__, wname); - ret = -EINVAL; - goto out; - } - - dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__, - w->name, decimator); - - tx_vol_ctl_reg = WCD9360_CDC_TX0_TX_PATH_CTL + 16 * decimator; - hpf_gate_reg = WCD9360_CDC_TX0_TX_PATH_SEC2 + 16 * decimator; - dec_cfg_reg = WCD9360_CDC_TX0_TX_PATH_CFG0 + 16 * decimator; - tx_gain_ctl_reg = WCD9360_CDC_TX0_TX_VOL_CTL + 16 * decimator; - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - amic_n = pahu_codec_find_amic_input(codec, decimator); - if (amic_n) - pwr_level_reg = pahu_codec_get_amic_pwlvl_reg(codec, - amic_n); - - if (pwr_level_reg) { - switch ((snd_soc_read(codec, pwr_level_reg) & - WCD9360_AMIC_PWR_LVL_MASK) >> - WCD9360_AMIC_PWR_LVL_SHIFT) { - case WCD9360_AMIC_PWR_LEVEL_LP: - snd_soc_update_bits(codec, dec_cfg_reg, - WCD9360_DEC_PWR_LVL_MASK, - WCD9360_DEC_PWR_LVL_LP); - break; - - case WCD9360_AMIC_PWR_LEVEL_HP: - snd_soc_update_bits(codec, dec_cfg_reg, - WCD9360_DEC_PWR_LVL_MASK, - WCD9360_DEC_PWR_LVL_HP); - break; - case WCD9360_AMIC_PWR_LEVEL_DEFAULT: - default: - snd_soc_update_bits(codec, dec_cfg_reg, - WCD9360_DEC_PWR_LVL_MASK, - WCD9360_DEC_PWR_LVL_DF); - break; - } - } - /* Enable TX PGA Mute */ - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); - break; - case SND_SOC_DAPM_POST_PMU: - hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) & - TX_HPF_CUT_OFF_FREQ_MASK) >> 5; - - pahu->tx_hpf_work[decimator].hpf_cut_off_freq = - hpf_cut_off_freq; - if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { - snd_soc_update_bits(codec, dec_cfg_reg, - TX_HPF_CUT_OFF_FREQ_MASK, - CF_MIN_3DB_150HZ << 5); - snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); - /* - * Minimum 1 clk cycle delay is required as per - * HW spec. - */ - usleep_range(1000, 1010); - snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00); - } - /* schedule work queue to Remove Mute */ - schedule_delayed_work(&pahu->tx_mute_dwork[decimator].dwork, - msecs_to_jiffies(tx_unmute_delay)); - if (pahu->tx_hpf_work[decimator].hpf_cut_off_freq != - CF_MIN_3DB_150HZ) - schedule_delayed_work( - &pahu->tx_hpf_work[decimator].dwork, - msecs_to_jiffies(300)); - /* apply gain after decimator is enabled */ - snd_soc_write(codec, tx_gain_ctl_reg, - snd_soc_read(codec, tx_gain_ctl_reg)); - break; - case SND_SOC_DAPM_PRE_PMD: - hpf_cut_off_freq = - pahu->tx_hpf_work[decimator].hpf_cut_off_freq; - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); - if (cancel_delayed_work_sync( - &pahu->tx_hpf_work[decimator].dwork)) { - if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { - snd_soc_update_bits(codec, dec_cfg_reg, - TX_HPF_CUT_OFF_FREQ_MASK, - hpf_cut_off_freq << 5); - snd_soc_update_bits(codec, hpf_gate_reg, - 0x02, 0x02); - /* - * Minimum 1 clk cycle delay is required as per - * HW spec. - */ - usleep_range(1000, 1010); - snd_soc_update_bits(codec, hpf_gate_reg, - 0x02, 0x00); - } - } - cancel_delayed_work_sync( - &pahu->tx_mute_dwork[decimator].dwork); - break; - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); - snd_soc_update_bits(codec, dec_cfg_reg, - WCD9360_DEC_PWR_LVL_MASK, - WCD9360_DEC_PWR_LVL_DF); - break; - }; -out: - kfree(wname); - return ret; -} - -static u32 pahu_get_dmic_sample_rate(struct snd_soc_codec *codec, - unsigned int dmic, - struct wcd9xxx_pdata *pdata) -{ - u8 tx_stream_fs; - u8 adc_mux_index = 0, adc_mux_sel = 0; - bool dec_found = false; - u16 adc_mux_ctl_reg, tx_fs_reg; - u32 dmic_fs; - - while (dec_found == 0 && adc_mux_index < WCD9360_MAX_VALID_ADC_MUX) { - if (adc_mux_index < 4) { - adc_mux_ctl_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + - (adc_mux_index * 2); - } else if (adc_mux_index < WCD9360_INVALID_ADC_MUX) { - adc_mux_ctl_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + - adc_mux_index - 4; - } else if (adc_mux_index == WCD9360_INVALID_ADC_MUX) { - ++adc_mux_index; - continue; - } - adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) & - 0xF8) >> 3) - 1; - - if (adc_mux_sel == dmic) { - dec_found = true; - break; - } - - ++adc_mux_index; - } - - if (dec_found && adc_mux_index <= 8) { - tx_fs_reg = WCD9360_CDC_TX0_TX_PATH_CTL + (16 * adc_mux_index); - tx_stream_fs = snd_soc_read(codec, tx_fs_reg) & 0x0F; - if (tx_stream_fs <= 4) { - if (pdata->dmic_sample_rate <= - WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ) - dmic_fs = pdata->dmic_sample_rate; - else - dmic_fs = WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ; - } else - dmic_fs = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ; - } else { - dmic_fs = pdata->dmic_sample_rate; - } - - return dmic_fs; -} - -static u8 pahu_get_dmic_clk_val(struct snd_soc_codec *codec, - u32 dmic_clk_rate) -{ - u32 div_factor; - u8 dmic_ctl_val = WCD9360_DMIC_CLK_DIV_2; - - dev_dbg(codec->dev, "%s: dmic_sample_rate = %d\n", - __func__, dmic_clk_rate); - - if (dmic_clk_rate == 0) { - dev_err(codec->dev, "%s: dmic_sample_rate cannot be 0\n", - __func__); - goto done; - } - - div_factor = WCD9360_MCLK_CLK_9P6MHZ / dmic_clk_rate; - switch (div_factor) { - case 2: - dmic_ctl_val = WCD9360_DMIC_CLK_DIV_2; - break; - case 3: - dmic_ctl_val = WCD9360_DMIC_CLK_DIV_3; - break; - case 4: - dmic_ctl_val = WCD9360_DMIC_CLK_DIV_4; - break; - case 6: - dmic_ctl_val = WCD9360_DMIC_CLK_DIV_6; - break; - case 8: - dmic_ctl_val = WCD9360_DMIC_CLK_DIV_8; - break; - case 16: - dmic_ctl_val = WCD9360_DMIC_CLK_DIV_16; - break; - default: - dev_err(codec->dev, - "%s: Invalid div_factor %u, dmic_rate(%u)\n", - __func__, div_factor, dmic_clk_rate); - break; - } - -done: - return dmic_ctl_val; -} - -static int pahu_codec_enable_adc(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - dev_dbg(codec->dev, "%s: event:%d\n", __func__, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - pahu_codec_set_tx_hold(codec, w->reg, true); - break; - default: - break; - } - - return 0; -} - -static int pahu_codec_enable_dmic(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); - u8 dmic_clk_en = 0x01; - u16 dmic_clk_reg; - s32 *dmic_clk_cnt; - u8 dmic_rate_val, dmic_rate_shift = 1; - unsigned int dmic; - u32 dmic_sample_rate; - - dmic = w->shift; - switch (dmic) { - case 0: - case 1: - dmic_clk_cnt = &(pahu->dmic_0_1_clk_cnt); - dmic_clk_reg = WCD9360_CPE_SS_DMIC0_CTL; - break; - case 2: - case 3: - dmic_clk_cnt = &(pahu->dmic_2_3_clk_cnt); - dmic_clk_reg = WCD9360_CPE_SS_DMIC1_CTL; - break; - case 4: - case 5: - dmic_clk_cnt = &(pahu->dmic_4_5_clk_cnt); - dmic_clk_reg = WCD9360_CPE_SS_DMIC2_CTL; - break; - case 6: - case 7: - dmic_clk_cnt = &(pahu->dmic_6_7_clk_cnt); - dmic_clk_reg = WCD9360_CPE_SS_DMIC3_CTL; - break; - default: - dev_err(codec->dev, "%s: Invalid DMIC Selection\n", - __func__); - return -EINVAL; - }; - dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", - __func__, event, dmic, *dmic_clk_cnt); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - dmic_sample_rate = pahu_get_dmic_sample_rate(codec, dmic, - pdata); - dmic_rate_val = - pahu_get_dmic_clk_val(codec, - dmic_sample_rate); - - (*dmic_clk_cnt)++; - if (*dmic_clk_cnt == 1) { - snd_soc_update_bits(codec, dmic_clk_reg, - 0x07 << dmic_rate_shift, - dmic_rate_val << dmic_rate_shift); - snd_soc_update_bits(codec, dmic_clk_reg, - dmic_clk_en, dmic_clk_en); - } - - break; - case SND_SOC_DAPM_POST_PMD: - dmic_rate_val = - pahu_get_dmic_clk_val(codec, - pdata->mad_dmic_sample_rate); - (*dmic_clk_cnt)--; - if (*dmic_clk_cnt == 0) { - snd_soc_update_bits(codec, dmic_clk_reg, - dmic_clk_en, 0); - snd_soc_update_bits(codec, dmic_clk_reg, - 0x07 << dmic_rate_shift, - dmic_rate_val << dmic_rate_shift); - } - break; - }; - - return 0; -} - -/* - * pahu_micbias_control: enable/disable micbias - * @codec: handle to snd_soc_codec * - * @micb_num: micbias to be enabled/disabled, e.g. micbias1 or micbias2 - * @req: control requested, enable/disable or pullup enable/disable - * @is_dapm: triggered by dapm or not - * - * return 0 if control is success or error code in case of failure - */ -int pahu_micbias_control(struct snd_soc_codec *codec, - int micb_num, int req, bool is_dapm) -{ - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - int micb_index = micb_num - 1; - u16 micb_reg; - - if ((micb_index < 0) || (micb_index > PAHU_MAX_MICBIAS - 1)) { - dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n", - __func__, micb_index); - return -EINVAL; - } - - switch (micb_num) { - case WCD9360_MIC_BIAS_1: - micb_reg = WCD9360_ANA_MICB1; - break; - case WCD9360_MIC_BIAS_2: - micb_reg = WCD9360_ANA_MICB2; - break; - case WCD9360_MIC_BIAS_3: - micb_reg = WCD9360_ANA_MICB3; - break; - case WCD9360_MIC_BIAS_4: - micb_reg = WCD9360_ANA_MICB4; - break; - default: - dev_err(codec->dev, "%s: Invalid micbias number: %d\n", - __func__, micb_num); - return -EINVAL; - } - mutex_lock(&pahu->micb_lock); - - switch (req) { - case WCD9360_MICB_PULLUP_ENABLE: - pahu->pullup_ref[micb_index]++; - if ((pahu->pullup_ref[micb_index] == 1) && - (pahu->micb_ref[micb_index] == 0)) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); - break; - case WCD9360_MICB_PULLUP_DISABLE: - if (pahu->pullup_ref[micb_index] > 0) - pahu->pullup_ref[micb_index]--; - if ((pahu->pullup_ref[micb_index] == 0) && - (pahu->micb_ref[micb_index] == 0)) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); - break; - case WCD9360_MICB_ENABLE: - pahu->micb_ref[micb_index]++; - if (pahu->micb_ref[micb_index] == 1) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); - break; - case WCD9360_MICB_DISABLE: - if (pahu->micb_ref[micb_index] > 0) - pahu->micb_ref[micb_index]--; - if ((pahu->micb_ref[micb_index] == 0) && - (pahu->pullup_ref[micb_index] > 0)) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); - else if ((pahu->micb_ref[micb_index] == 0) && - (pahu->pullup_ref[micb_index] == 0)) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); - break; - } - - dev_dbg(codec->dev, "%s: micb_num:%d, micb_ref: %d\n", - __func__, micb_num, pahu->micb_ref[micb_index]); - - mutex_unlock(&pahu->micb_lock); - - return 0; -} -EXPORT_SYMBOL(pahu_micbias_control); - -static int __pahu_codec_enable_micbias(struct snd_soc_dapm_widget *w, - int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - int micb_num; - - dev_dbg(codec->dev, "%s: wname: %s, event: %d\n", - __func__, w->name, event); - - if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) - micb_num = WCD9360_MIC_BIAS_1; - else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2"))) - micb_num = WCD9360_MIC_BIAS_2; - else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3"))) - micb_num = WCD9360_MIC_BIAS_3; - else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4"))) - micb_num = WCD9360_MIC_BIAS_4; - else - return -EINVAL; - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - /* - * Use ref count to handle micbias pullup - * and enable requests - */ - pahu_micbias_control(codec, micb_num, WCD9360_MICB_ENABLE, - true); - break; - case SND_SOC_DAPM_POST_PMU: - /* wait for cnp time */ - usleep_range(1000, 1100); - break; - case SND_SOC_DAPM_POST_PMD: - pahu_micbias_control(codec, micb_num, WCD9360_MICB_DISABLE, - true); - break; - }; - - return 0; -} - -/* - * pahu_codec_enable_standalone_micbias - enable micbias standalone - * @codec: pointer to codec instance - * @micb_num: number of micbias to be enabled - * @enable: true to enable micbias or false to disable - * - * This function is used to enable micbias (1, 2, 3 or 4) during - * standalone independent of whether TX use-case is running or not - * - * Return: error code in case of failure or 0 for success - */ -int pahu_codec_enable_standalone_micbias(struct snd_soc_codec *codec, - int micb_num, - bool enable) -{ - const char * const micb_names[] = { - DAPM_MICBIAS1_STANDALONE, DAPM_MICBIAS2_STANDALONE, - DAPM_MICBIAS3_STANDALONE, DAPM_MICBIAS4_STANDALONE - }; - int micb_index = micb_num - 1; - int rc; - - if (!codec) { - pr_err("%s: Codec memory is NULL\n", __func__); - return -EINVAL; - } - - if ((micb_index < 0) || (micb_index > PAHU_MAX_MICBIAS - 1)) { - dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n", - __func__, micb_index); - return -EINVAL; - } - - if (enable) - rc = snd_soc_dapm_force_enable_pin( - snd_soc_codec_get_dapm(codec), - micb_names[micb_index]); - else - rc = snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(codec), - micb_names[micb_index]); - - if (!rc) - snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); - else - dev_err(codec->dev, "%s: micbias%d force %s pin failed\n", - __func__, micb_num, (enable ? "enable" : "disable")); - - return rc; -} -EXPORT_SYMBOL(pahu_codec_enable_standalone_micbias); - -static int pahu_codec_force_enable_micbias(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - int ret = 0; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - wcd_resmgr_enable_master_bias(pahu->resmgr); - pahu_cdc_mclk_enable(codec, true); - ret = __pahu_codec_enable_micbias(w, SND_SOC_DAPM_PRE_PMU); - /* Wait for 1ms for better cnp */ - usleep_range(1000, 1100); - pahu_cdc_mclk_enable(codec, false); - break; - case SND_SOC_DAPM_POST_PMD: - ret = __pahu_codec_enable_micbias(w, SND_SOC_DAPM_POST_PMD); - wcd_resmgr_disable_master_bias(pahu->resmgr); - break; - } - - return ret; -} - -static int pahu_codec_enable_micbias(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - return __pahu_codec_enable_micbias(w, event); -} - -static void pahu_restore_iir_coeff(struct pahu_priv *pahu, int iir_idx, - int band_idx) -{ - u16 reg_add; - int no_of_reg = 0; - - regmap_write(pahu->wcd9xxx->regmap, - (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), - (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); - reg_add = WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx; - - if (pahu->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) - return; - /* - * Since wcd9xxx_slim_write_repeat() supports only maximum of 16 - * registers at a time, split total 20 writes(5 coefficients per - * band and 4 writes per coefficient) into 16 and 4. - */ - no_of_reg = WCD9360_CDC_REPEAT_WRITES_MAX; - wcd9xxx_slim_write_repeat(pahu->wcd9xxx, reg_add, no_of_reg, - &pahu->sidetone_coeff_array[iir_idx][band_idx][0]); - - no_of_reg = (WCD9360_CDC_SIDETONE_IIR_COEFF_MAX * 4) - - WCD9360_CDC_REPEAT_WRITES_MAX; - wcd9xxx_slim_write_repeat(pahu->wcd9xxx, reg_add, no_of_reg, - &pahu->sidetone_coeff_array[iir_idx][band_idx] - [WCD9360_CDC_REPEAT_WRITES_MAX]); -} - -static int pahu_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - int iir_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->reg; - int band_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - /* IIR filter band registers are at integer multiples of 16 */ - u16 iir_reg = WCD9360_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx; - - ucontrol->value.integer.value[0] = (snd_soc_read(codec, iir_reg) & - (1 << band_idx)) != 0; - - dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, - iir_idx, band_idx, - (uint32_t)ucontrol->value.integer.value[0]); - return 0; -} - -static int pahu_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - int iir_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->reg; - int band_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - bool iir_band_en_status; - int value = ucontrol->value.integer.value[0]; - u16 iir_reg = WCD9360_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx; - - pahu_restore_iir_coeff(pahu, iir_idx, band_idx); - - /* Mask first 5 bits, 6-8 are reserved */ - snd_soc_update_bits(codec, iir_reg, (1 << band_idx), - (value << band_idx)); - - iir_band_en_status = ((snd_soc_read(codec, iir_reg) & - (1 << band_idx)) != 0); - dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, - iir_idx, band_idx, iir_band_en_status); - return 0; -} - -static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec, - int iir_idx, int band_idx, - int coeff_idx) -{ - uint32_t value = 0; - - /* Address does not automatically update if reading */ - snd_soc_write(codec, - (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), - ((band_idx * BAND_MAX + coeff_idx) - * sizeof(uint32_t)) & 0x7F); - - value |= snd_soc_read(codec, - (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx)); - - snd_soc_write(codec, - (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), - ((band_idx * BAND_MAX + coeff_idx) - * sizeof(uint32_t) + 1) & 0x7F); - - value |= (snd_soc_read(codec, - (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + - 16 * iir_idx)) << 8); - - snd_soc_write(codec, - (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), - ((band_idx * BAND_MAX + coeff_idx) - * sizeof(uint32_t) + 2) & 0x7F); - - value |= (snd_soc_read(codec, - (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + - 16 * iir_idx)) << 16); - - snd_soc_write(codec, - (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), - ((band_idx * BAND_MAX + coeff_idx) - * sizeof(uint32_t) + 3) & 0x7F); - - /* Mask bits top 2 bits since they are reserved */ - value |= ((snd_soc_read(codec, - (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + - 16 * iir_idx)) & 0x3F) << 24); - - return value; -} - -static int pahu_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - int iir_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->reg; - int band_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - - ucontrol->value.integer.value[0] = - get_iir_band_coeff(codec, iir_idx, band_idx, 0); - ucontrol->value.integer.value[1] = - get_iir_band_coeff(codec, iir_idx, band_idx, 1); - ucontrol->value.integer.value[2] = - get_iir_band_coeff(codec, iir_idx, band_idx, 2); - ucontrol->value.integer.value[3] = - get_iir_band_coeff(codec, iir_idx, band_idx, 3); - ucontrol->value.integer.value[4] = - get_iir_band_coeff(codec, iir_idx, band_idx, 4); - - dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n" - "%s: IIR #%d band #%d b1 = 0x%x\n" - "%s: IIR #%d band #%d b2 = 0x%x\n" - "%s: IIR #%d band #%d a1 = 0x%x\n" - "%s: IIR #%d band #%d a2 = 0x%x\n", - __func__, iir_idx, band_idx, - (uint32_t)ucontrol->value.integer.value[0], - __func__, iir_idx, band_idx, - (uint32_t)ucontrol->value.integer.value[1], - __func__, iir_idx, band_idx, - (uint32_t)ucontrol->value.integer.value[2], - __func__, iir_idx, band_idx, - (uint32_t)ucontrol->value.integer.value[3], - __func__, iir_idx, band_idx, - (uint32_t)ucontrol->value.integer.value[4]); - return 0; -} - -static void set_iir_band_coeff(struct snd_soc_codec *codec, - int iir_idx, int band_idx, - uint32_t value) -{ - snd_soc_write(codec, - (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), - (value & 0xFF)); - - snd_soc_write(codec, - (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), - (value >> 8) & 0xFF); - - snd_soc_write(codec, - (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), - (value >> 16) & 0xFF); - - /* Mask top 2 bits, 7-8 are reserved */ - snd_soc_write(codec, - (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), - (value >> 24) & 0x3F); -} - -static int pahu_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - int iir_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->reg; - int band_idx = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - int coeff_idx, idx = 0; - - /* - * Mask top bit it is reserved - * Updates addr automatically for each B2 write - */ - snd_soc_write(codec, - (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), - (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); - - /* Store the coefficients in sidetone coeff array */ - for (coeff_idx = 0; coeff_idx < WCD9360_CDC_SIDETONE_IIR_COEFF_MAX; - coeff_idx++) { - uint32_t value = ucontrol->value.integer.value[coeff_idx]; - - set_iir_band_coeff(codec, iir_idx, band_idx, value); - - /* Four 8 bit values(one 32 bit) per coefficient */ - pahu->sidetone_coeff_array[iir_idx][band_idx][idx++] = - (value & 0xFF); - pahu->sidetone_coeff_array[iir_idx][band_idx][idx++] = - ((value >> 8) & 0xFF); - pahu->sidetone_coeff_array[iir_idx][band_idx][idx++] = - ((value >> 16) & 0xFF); - pahu->sidetone_coeff_array[iir_idx][band_idx][idx++] = - ((value >> 24) & 0xFF); - } - - pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n" - "%s: IIR #%d band #%d b1 = 0x%x\n" - "%s: IIR #%d band #%d b2 = 0x%x\n" - "%s: IIR #%d band #%d a1 = 0x%x\n" - "%s: IIR #%d band #%d a2 = 0x%x\n", - __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 0), - __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 1), - __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 2), - __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 3), - __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 4)); - return 0; -} - -static int pahu_compander_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - int comp = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = pahu->comp_enabled[comp]; - return 0; -} - -static int pahu_compander_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - int comp = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - int value = ucontrol->value.integer.value[0]; - - dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n", - __func__, comp + 1, pahu->comp_enabled[comp], value); - pahu->comp_enabled[comp] = value; - - return 0; -} - -static int pahu_dmic_pin_mode_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - u16 offset; - u8 reg_val, pinctl_position; - - pinctl_position = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - - offset = pinctl_position - WCD9360_TLMM_DMIC_PINCFG_OFFSET; - reg_val = snd_soc_read(codec, - WCD9360_TLMM_DMIC1_CLK_PINCFG + offset); - - ucontrol->value.integer.value[0] = !!reg_val; - - return 0; -} - -static int pahu_dmic_pin_mode_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - u16 ctl_reg, cfg_reg, offset; - u8 ctl_val, cfg_val, pinctl_position, pinctl_mode, mask; - - /* 0- high or low; 1- high Z */ - pinctl_mode = ucontrol->value.integer.value[0]; - pinctl_position = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - - switch (pinctl_position >> 3) { - case 0: - ctl_reg = WCD9360_TEST_DEBUG_PIN_CTL_OE_0; - break; - case 1: - ctl_reg = WCD9360_TEST_DEBUG_PIN_CTL_OE_1; - break; - case 2: - ctl_reg = WCD9360_TEST_DEBUG_PIN_CTL_OE_2; - break; - case 3: - ctl_reg = WCD9360_TEST_DEBUG_PIN_CTL_OE_3; - break; - default: - dev_err(codec->dev, "%s: Invalid pinctl position = %d\n", - __func__, pinctl_position); - return -EINVAL; - } - - ctl_val = ~(pinctl_mode << (pinctl_position & 0x07)); - mask = 1 << (pinctl_position & 0x07); - snd_soc_update_bits(codec, ctl_reg, mask, ctl_val); - - offset = pinctl_position - WCD9360_TLMM_DMIC_PINCFG_OFFSET; - cfg_reg = WCD9360_TLMM_DMIC1_CLK_PINCFG + offset; - if (pinctl_mode) { - if (pahu->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) - cfg_val = 0x5; - else - cfg_val = 0xD; - } else - cfg_val = 0; - snd_soc_update_bits(codec, cfg_reg, 0x1F, cfg_val); - - dev_dbg(codec->dev, "%s: reg=0x%x mask=0x%x val=%d reg=0x%x val=%d\n", - __func__, ctl_reg, mask, ctl_val, cfg_reg, cfg_val); - - return 0; -} - -static int pahu_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - u16 amic_reg = 0; - - if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE")) - amic_reg = WCD9360_ANA_AMIC1; - if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE")) - amic_reg = WCD9360_ANA_AMIC3; - - if (amic_reg) - ucontrol->value.integer.value[0] = - (snd_soc_read(codec, amic_reg) & - WCD9360_AMIC_PWR_LVL_MASK) >> - WCD9360_AMIC_PWR_LVL_SHIFT; - return 0; -} - -static int pahu_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - u32 mode_val; - u16 amic_reg = 0; - - mode_val = ucontrol->value.enumerated.item[0]; - - dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val); - - if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE")) - amic_reg = WCD9360_ANA_AMIC1; - if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE")) - amic_reg = WCD9360_ANA_AMIC3; - - if (amic_reg) - snd_soc_update_bits(codec, amic_reg, WCD9360_AMIC_PWR_LVL_MASK, - mode_val << WCD9360_AMIC_PWR_LVL_SHIFT); - return 0; -} - -static const char *const pahu_conn_mad_text[] = { - "NOTUSED1", "ADC1", "ADC2", "ADC3", "ADC4", "NOTUSED5", - "NOTUSED6", "NOTUSED2", "DMIC0", "DMIC1", "DMIC2", "DMIC3", - "DMIC4", "DMIC5", "DMIC6", "DMIC7" -}; - -static const struct soc_enum pahu_conn_mad_enum = - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(pahu_conn_mad_text), - pahu_conn_mad_text); - -static int pahu_mad_input_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - u8 pahu_mad_input; - - pahu_mad_input = snd_soc_read(codec, WCD9360_SOC_MAD_INP_SEL) & 0x0F; - ucontrol->value.integer.value[0] = pahu_mad_input; - - dev_dbg(codec->dev, "%s: pahu_mad_input = %s\n", __func__, - pahu_conn_mad_text[pahu_mad_input]); - - return 0; -} - -static int pahu_mad_input_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct snd_soc_card *card = codec->component.card; - u8 pahu_mad_input; - char mad_amic_input_widget[6]; - const char *mad_input_widget; - const char *source_widget = NULL; - u32 adc, i, mic_bias_found = 0; - int ret = 0; - char *mad_input; - bool is_adc_input = false; - - pahu_mad_input = ucontrol->value.integer.value[0]; - - if (pahu_mad_input >= sizeof(pahu_conn_mad_text)/ - sizeof(pahu_conn_mad_text[0])) { - dev_err(codec->dev, - "%s: pahu_mad_input = %d out of bounds\n", - __func__, pahu_mad_input); - return -EINVAL; - } - - if (strnstr(pahu_conn_mad_text[pahu_mad_input], "NOTUSED", - sizeof("NOTUSED"))) { - dev_dbg(codec->dev, - "%s: Unsupported pahu_mad_input = %s\n", - __func__, pahu_conn_mad_text[pahu_mad_input]); - /* Make sure the MAD register is updated */ - snd_soc_update_bits(codec, WCD9360_ANA_MAD_SETUP, - 0x88, 0x00); - return -EINVAL; - } - - if (strnstr(pahu_conn_mad_text[pahu_mad_input], - "ADC", sizeof("ADC"))) { - mad_input = strpbrk(pahu_conn_mad_text[pahu_mad_input], - "1234"); - if (!mad_input) { - dev_err(codec->dev, "%s: Invalid MAD input %s\n", - __func__, pahu_conn_mad_text[pahu_mad_input]); - return -EINVAL; - } - - ret = kstrtouint(mad_input, 10, &adc); - if ((ret < 0) || (adc > 4)) { - dev_err(codec->dev, "%s: Invalid ADC = %s\n", __func__, - pahu_conn_mad_text[pahu_mad_input]); - return -EINVAL; - } - - snprintf(mad_amic_input_widget, 6, "%s%u", "AMIC", adc); - - mad_input_widget = mad_amic_input_widget; - is_adc_input = true; - } else { - /* DMIC type input widget*/ - mad_input_widget = pahu_conn_mad_text[pahu_mad_input]; - } - - dev_dbg(codec->dev, - "%s: pahu input widget = %s, adc_input = %s\n", __func__, - mad_input_widget, is_adc_input ? "true" : "false"); - - for (i = 0; i < card->num_of_dapm_routes; i++) { - if (!strcmp(card->of_dapm_routes[i].sink, mad_input_widget)) { - source_widget = card->of_dapm_routes[i].source; - if (!source_widget) { - dev_err(codec->dev, - "%s: invalid source widget\n", - __func__); - return -EINVAL; - } - - if (strnstr(source_widget, - "MIC BIAS1", sizeof("MIC BIAS1"))) { - mic_bias_found = 1; - break; - } else if (strnstr(source_widget, - "MIC BIAS2", sizeof("MIC BIAS2"))) { - mic_bias_found = 2; - break; - } else if (strnstr(source_widget, - "MIC BIAS3", sizeof("MIC BIAS3"))) { - mic_bias_found = 3; - break; - } else if (strnstr(source_widget, - "MIC BIAS4", sizeof("MIC BIAS4"))) { - mic_bias_found = 4; - break; - } - } - } - - if (!mic_bias_found) { - dev_err(codec->dev, "%s: mic bias not found for input %s\n", - __func__, mad_input_widget); - return -EINVAL; - } - - dev_dbg(codec->dev, "%s: mic_bias found = %d\n", __func__, - mic_bias_found); - - snd_soc_update_bits(codec, WCD9360_SOC_MAD_INP_SEL, - 0x0F, pahu_mad_input); - snd_soc_update_bits(codec, WCD9360_ANA_MAD_SETUP, - 0x07, mic_bias_found); - /* for all adc inputs, mad should be in micbias mode with BG enabled */ - if (is_adc_input) - snd_soc_update_bits(codec, WCD9360_ANA_MAD_SETUP, - 0x88, 0x88); - else - snd_soc_update_bits(codec, WCD9360_ANA_MAD_SETUP, - 0x88, 0x00); - return 0; -} - -static int pahu_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = pahu->ear_spkr_gain; - - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - return 0; -} - -static int pahu_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - pahu->ear_spkr_gain = ucontrol->value.integer.value[0]; - - dev_dbg(codec->dev, "%s: gain = %d\n", __func__, pahu->ear_spkr_gain); - - return 0; -} - -static int pahu_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - u8 bst_state_max = 0; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - - bst_state_max = snd_soc_read(codec, WCD9360_CDC_BOOST0_BOOST_CTL); - bst_state_max = (bst_state_max & 0x0c) >> 2; - ucontrol->value.integer.value[0] = bst_state_max; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - return 0; -} - -static int pahu_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - u8 bst_state_max; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - bst_state_max = ucontrol->value.integer.value[0] << 2; - snd_soc_update_bits(codec, WCD9360_CDC_BOOST0_BOOST_CTL, - 0x0c, bst_state_max); - - return 0; -} - -static int pahu_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - u8 bst_state_max = 0; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - - bst_state_max = snd_soc_read(codec, WCD9360_CDC_BOOST1_BOOST_CTL); - bst_state_max = (bst_state_max & 0x0c) >> 2; - ucontrol->value.integer.value[0] = bst_state_max; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - return 0; -} - -static int pahu_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - u8 bst_state_max; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - bst_state_max = ucontrol->value.integer.value[0] << 2; - snd_soc_update_bits(codec, WCD9360_CDC_BOOST1_BOOST_CTL, - 0x0c, bst_state_max); - - return 0; -} - -static const char *const pahu_anc_func_text[] = {"OFF", "ON"}; -static const struct soc_enum pahu_anc_func_enum = - SOC_ENUM_SINGLE_EXT(2, pahu_anc_func_text); - -static const char *const pahu_clkmode_text[] = {"EXTERNAL", "INTERNAL"}; -static SOC_ENUM_SINGLE_EXT_DECL(pahu_clkmode_enum, pahu_clkmode_text); - -/* Cutoff frequency for high pass filter */ -static const char * const cf_text[] = { - "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ" -}; - -static const char * const rx_cf_text[] = { - "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ", - "CF_NEG_3DB_0P48HZ" -}; - -static const char * const amic_pwr_lvl_text[] = { - "LOW_PWR", "DEFAULT", "HIGH_PERF", "HYBRID" -}; - -static const char * const pahu_ear_pa_gain_text[] = { - "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB", - "G_0_DB", "G_M2P5_DB", "UNDEFINED", "G_M12_DB" -}; - -static const char * const pahu_ear_spkr_pa_gain_text[] = { - "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB", - "G_4_DB", "G_5_DB", "G_6_DB" -}; - -static const char * const pahu_speaker_boost_stage_text[] = { - "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2" -}; - -static SOC_ENUM_SINGLE_EXT_DECL(pahu_ear_pa_gain_enum, pahu_ear_pa_gain_text); -static SOC_ENUM_SINGLE_EXT_DECL(pahu_ear_spkr_pa_gain_enum, - pahu_ear_spkr_pa_gain_text); -static SOC_ENUM_SINGLE_EXT_DECL(pahu_spkr_boost_stage_enum, - pahu_speaker_boost_stage_text); -static SOC_ENUM_SINGLE_EXT_DECL(amic_pwr_lvl_enum, amic_pwr_lvl_text); -static SOC_ENUM_SINGLE_DECL(cf_dec0_enum, WCD9360_CDC_TX0_TX_PATH_CFG0, 5, - cf_text); -static SOC_ENUM_SINGLE_DECL(cf_dec1_enum, WCD9360_CDC_TX1_TX_PATH_CFG0, 5, - cf_text); -static SOC_ENUM_SINGLE_DECL(cf_dec2_enum, WCD9360_CDC_TX2_TX_PATH_CFG0, 5, - cf_text); -static SOC_ENUM_SINGLE_DECL(cf_dec3_enum, WCD9360_CDC_TX3_TX_PATH_CFG0, 5, - cf_text); -static SOC_ENUM_SINGLE_DECL(cf_dec4_enum, WCD9360_CDC_TX4_TX_PATH_CFG0, 5, - cf_text); -static SOC_ENUM_SINGLE_DECL(cf_dec5_enum, WCD9360_CDC_TX5_TX_PATH_CFG0, 5, - cf_text); -static SOC_ENUM_SINGLE_DECL(cf_dec6_enum, WCD9360_CDC_TX6_TX_PATH_CFG0, 5, - cf_text); -static SOC_ENUM_SINGLE_DECL(cf_dec7_enum, WCD9360_CDC_TX7_TX_PATH_CFG0, 5, - cf_text); -static SOC_ENUM_SINGLE_DECL(cf_dec8_enum, WCD9360_CDC_TX8_TX_PATH_CFG0, 5, - cf_text); -static SOC_ENUM_SINGLE_DECL(cf_int0_1_enum, WCD9360_CDC_RX0_RX_PATH_CFG2, 0, - rx_cf_text); -static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD9360_CDC_RX0_RX_PATH_MIX_CFG, 2, - rx_cf_text); -static SOC_ENUM_SINGLE_DECL(cf_int7_1_enum, WCD9360_CDC_RX7_RX_PATH_CFG2, 0, - rx_cf_text); -static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD9360_CDC_RX7_RX_PATH_MIX_CFG, 2, - rx_cf_text); -static SOC_ENUM_SINGLE_DECL(cf_int8_1_enum, WCD9360_CDC_RX8_RX_PATH_CFG2, 0, - rx_cf_text); -static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD9360_CDC_RX8_RX_PATH_MIX_CFG, 2, - rx_cf_text); -static SOC_ENUM_SINGLE_DECL(cf_int9_1_enum, WCD9360_CDC_RX9_RX_PATH_CFG2, 0, - rx_cf_text); -static SOC_ENUM_SINGLE_DECL(cf_int9_2_enum, WCD9360_CDC_RX9_RX_PATH_MIX_CFG, 2, - rx_cf_text); - -static const struct snd_kcontrol_new pahu_snd_controls[] = { - SOC_ENUM_EXT("EAR SPKR PA Gain", pahu_ear_spkr_pa_gain_enum, - pahu_ear_spkr_pa_gain_get, pahu_ear_spkr_pa_gain_put), - SOC_ENUM_EXT("SPKR Left Boost Max State", pahu_spkr_boost_stage_enum, - pahu_spkr_left_boost_stage_get, - pahu_spkr_left_boost_stage_put), - SOC_ENUM_EXT("SPKR Right Boost Max State", pahu_spkr_boost_stage_enum, - pahu_spkr_right_boost_stage_get, - pahu_spkr_right_boost_stage_put), - SOC_SINGLE_TLV("ADC1 Volume", WCD9360_ANA_AMIC1, 0, 20, 0, analog_gain), - SOC_SINGLE_TLV("ADC2 Volume", WCD9360_ANA_AMIC2, 0, 20, 0, analog_gain), - SOC_SINGLE_TLV("ADC3 Volume", WCD9360_ANA_AMIC3, 0, 20, 0, analog_gain), - SOC_SINGLE_TLV("ADC4 Volume", WCD9360_ANA_AMIC4, 0, 20, 0, analog_gain), - - SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9360_CDC_RX0_RX_VOL_CTL, - 0, -84, 40, digital_gain), /* -84dB min - 40dB max */ - SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9360_CDC_RX7_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9360_CDC_RX8_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX9 Digital Volume", WCD9360_CDC_RX9_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume", - WCD9360_CDC_RX0_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume", - WCD9360_CDC_RX7_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume", - WCD9360_CDC_RX8_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX9 Mix Digital Volume", - WCD9360_CDC_RX9_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain), - - SOC_SINGLE_SX_TLV("DEC0 Volume", WCD9360_CDC_TX0_TX_VOL_CTL, 0, - -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("DEC1 Volume", WCD9360_CDC_TX1_TX_VOL_CTL, 0, - -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("DEC2 Volume", WCD9360_CDC_TX2_TX_VOL_CTL, 0, - -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("DEC3 Volume", WCD9360_CDC_TX3_TX_VOL_CTL, 0, - -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("DEC4 Volume", WCD9360_CDC_TX4_TX_VOL_CTL, 0, - -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("DEC5 Volume", WCD9360_CDC_TX5_TX_VOL_CTL, 0, - -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("DEC6 Volume", WCD9360_CDC_TX6_TX_VOL_CTL, 0, - -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("DEC7 Volume", WCD9360_CDC_TX7_TX_VOL_CTL, 0, - -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("DEC8 Volume", WCD9360_CDC_TX8_TX_VOL_CTL, 0, - -84, 40, digital_gain), - - SOC_SINGLE_SX_TLV("IIR0 INP0 Volume", - WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40, - digital_gain), - SOC_SINGLE_SX_TLV("IIR0 INP1 Volume", - WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84, 40, - digital_gain), - SOC_SINGLE_SX_TLV("IIR0 INP2 Volume", - WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84, 40, - digital_gain), - SOC_SINGLE_SX_TLV("IIR0 INP3 Volume", - WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84, 40, - digital_gain), - - SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, pahu_get_anc_slot, - pahu_put_anc_slot), - SOC_ENUM_EXT("ANC Function", pahu_anc_func_enum, pahu_get_anc_func, - pahu_put_anc_func), - - SOC_ENUM_EXT("CLK MODE", pahu_clkmode_enum, pahu_get_clkmode, - pahu_put_clkmode), - - SOC_ENUM("TX0 HPF cut off", cf_dec0_enum), - SOC_ENUM("TX1 HPF cut off", cf_dec1_enum), - SOC_ENUM("TX2 HPF cut off", cf_dec2_enum), - SOC_ENUM("TX3 HPF cut off", cf_dec3_enum), - SOC_ENUM("TX4 HPF cut off", cf_dec4_enum), - SOC_ENUM("TX5 HPF cut off", cf_dec5_enum), - SOC_ENUM("TX6 HPF cut off", cf_dec6_enum), - SOC_ENUM("TX7 HPF cut off", cf_dec7_enum), - SOC_ENUM("TX8 HPF cut off", cf_dec8_enum), - - SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum), - SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum), - SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum), - SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum), - SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum), - SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum), - SOC_ENUM("RX INT9_1 HPF cut off", cf_int9_1_enum), - SOC_ENUM("RX INT9_2 HPF cut off", cf_int9_2_enum), - - SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0, - pahu_iir_enable_audio_mixer_get, - pahu_iir_enable_audio_mixer_put), - SOC_SINGLE_EXT("IIR0 Enable Band2", IIR0, BAND2, 1, 0, - pahu_iir_enable_audio_mixer_get, - pahu_iir_enable_audio_mixer_put), - SOC_SINGLE_EXT("IIR0 Enable Band3", IIR0, BAND3, 1, 0, - pahu_iir_enable_audio_mixer_get, - pahu_iir_enable_audio_mixer_put), - SOC_SINGLE_EXT("IIR0 Enable Band4", IIR0, BAND4, 1, 0, - pahu_iir_enable_audio_mixer_get, - pahu_iir_enable_audio_mixer_put), - SOC_SINGLE_EXT("IIR0 Enable Band5", IIR0, BAND5, 1, 0, - pahu_iir_enable_audio_mixer_get, - pahu_iir_enable_audio_mixer_put), - - SOC_SINGLE_MULTI_EXT("IIR0 Band1", IIR0, BAND1, 255, 0, 5, - pahu_iir_band_audio_mixer_get, pahu_iir_band_audio_mixer_put), - SOC_SINGLE_MULTI_EXT("IIR0 Band2", IIR0, BAND2, 255, 0, 5, - pahu_iir_band_audio_mixer_get, pahu_iir_band_audio_mixer_put), - SOC_SINGLE_MULTI_EXT("IIR0 Band3", IIR0, BAND3, 255, 0, 5, - pahu_iir_band_audio_mixer_get, pahu_iir_band_audio_mixer_put), - SOC_SINGLE_MULTI_EXT("IIR0 Band4", IIR0, BAND4, 255, 0, 5, - pahu_iir_band_audio_mixer_get, pahu_iir_band_audio_mixer_put), - SOC_SINGLE_MULTI_EXT("IIR0 Band5", IIR0, BAND5, 255, 0, 5, - pahu_iir_band_audio_mixer_get, pahu_iir_band_audio_mixer_put), - - SOC_SINGLE_EXT("COMP0 Switch", SND_SOC_NOPM, COMPANDER_0, 1, 0, - pahu_compander_get, pahu_compander_put), - SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0, - pahu_compander_get, pahu_compander_put), - SOC_SINGLE_EXT("COMP8 Switch", SND_SOC_NOPM, COMPANDER_8, 1, 0, - pahu_compander_get, pahu_compander_put), - - SOC_ENUM_EXT("MAD Input", pahu_conn_mad_enum, - pahu_mad_input_get, pahu_mad_input_put), - - SOC_SINGLE_EXT("DMIC1_CLK_PIN_MODE", SND_SOC_NOPM, 15, 1, 0, - pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put), - - SOC_SINGLE_EXT("DMIC1_DATA_PIN_MODE", SND_SOC_NOPM, 16, 1, 0, - pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put), - - SOC_SINGLE_EXT("DMIC2_CLK_PIN_MODE", SND_SOC_NOPM, 17, 1, 0, - pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put), - - SOC_SINGLE_EXT("DMIC2_DATA_PIN_MODE", SND_SOC_NOPM, 18, 1, 0, - pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put), - - SOC_SINGLE_EXT("DMIC3_CLK_PIN_MODE", SND_SOC_NOPM, 28, 1, 0, - pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put), - - SOC_SINGLE_EXT("DMIC3_DATA_PIN_MODE", SND_SOC_NOPM, 29, 1, 0, - pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put), - - SOC_SINGLE_EXT("DMIC4_CLK_PIN_MODE", SND_SOC_NOPM, 30, 1, 0, - pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put), - - SOC_SINGLE_EXT("DMIC4_DATA_PIN_MODE", SND_SOC_NOPM, 31, 1, 0, - pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put), - - SOC_ENUM_EXT("AMIC_1_2 PWR MODE", amic_pwr_lvl_enum, - pahu_amic_pwr_lvl_get, pahu_amic_pwr_lvl_put), - SOC_ENUM_EXT("AMIC_3_4 PWR MODE", amic_pwr_lvl_enum, - pahu_amic_pwr_lvl_get, pahu_amic_pwr_lvl_put), -}; - -static int pahu_dec_enum_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int val; - u16 mic_sel_reg = 0; - u8 mic_sel; - - val = ucontrol->value.enumerated.item[0]; - if (val > e->items - 1) - return -EINVAL; - - dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, - widget->name, val); - - switch (e->reg) { - case WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1: - if (e->shift_l == 0) - mic_sel_reg = WCD9360_CDC_TX0_TX_PATH_CFG0; - else if (e->shift_l == 2) - mic_sel_reg = WCD9360_CDC_TX4_TX_PATH_CFG0; - else if (e->shift_l == 4) - mic_sel_reg = WCD9360_CDC_TX8_TX_PATH_CFG0; - break; - case WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1: - if (e->shift_l == 0) - mic_sel_reg = WCD9360_CDC_TX1_TX_PATH_CFG0; - else if (e->shift_l == 2) - mic_sel_reg = WCD9360_CDC_TX5_TX_PATH_CFG0; - break; - case WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1: - if (e->shift_l == 0) - mic_sel_reg = WCD9360_CDC_TX2_TX_PATH_CFG0; - else if (e->shift_l == 2) - mic_sel_reg = WCD9360_CDC_TX6_TX_PATH_CFG0; - break; - case WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1: - if (e->shift_l == 0) - mic_sel_reg = WCD9360_CDC_TX3_TX_PATH_CFG0; - else if (e->shift_l == 2) - mic_sel_reg = WCD9360_CDC_TX7_TX_PATH_CFG0; - break; - default: - dev_err(codec->dev, "%s: e->reg: 0x%x not expected\n", - __func__, e->reg); - return -EINVAL; - } - - /* ADC: 0, DMIC: 1 */ - mic_sel = val ? 0x0 : 0x1; - if (mic_sel_reg) - snd_soc_update_bits(codec, mic_sel_reg, 1 << 7, mic_sel << 7); - - return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); -} - -static int pahu_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int val; - unsigned short look_ahead_dly_reg = WCD9360_CDC_RX0_RX_PATH_CFG0; - - val = ucontrol->value.enumerated.item[0]; - if (val >= e->items) - return -EINVAL; - - dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, - widget->name, val); - - if (e->reg == WCD9360_CDC_RX0_RX_PATH_SEC0) - look_ahead_dly_reg = WCD9360_CDC_RX0_RX_PATH_CFG0; - else if (e->reg == WCD9360_CDC_RX9_RX_PATH_SEC0) - look_ahead_dly_reg = WCD9360_CDC_RX9_RX_PATH_CFG0; - - /* Set Look Ahead Delay */ - snd_soc_update_bits(codec, look_ahead_dly_reg, - 0x08, (val ? 0x08 : 0x00)); - /* Set DEM INP Select */ - return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); -} - -static const char * const rx_int0_7_mix_mux_text[] = { - "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", - "RX6", "RX7", "PROXIMITY", "IIR0" -}; - -static const char * const rx_int_mix_mux_text[] = { - "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", - "RX6", "RX7", "NA", "IIR0" -}; - -static const char * const rx_prim_mix_text[] = { - "ZERO", "DEC0", "DEC1", "IIR0", "INVALID", "RX0", "RX1", "RX2", - "RX3", "RX4", "RX5", "RX6", "RX7" -}; - -static const char * const rx_sidetone_mix_text[] = { - "ZERO", "SRC0" -}; - -static const char * const cdc_if_tx0_mux_text[] = { - "ZERO", "RX_MIX_TX0", "DEC0", "DEC0_192" -}; -static const char * const cdc_if_tx1_mux_text[] = { - "ZERO", "RX_MIX_TX1", "DEC1", "DEC1_192" -}; -static const char * const cdc_if_tx2_mux_text[] = { - "ZERO", "RX_MIX_TX2", "DEC2", "DEC2_192" -}; -static const char * const cdc_if_tx3_mux_text[] = { - "ZERO", "RX_MIX_TX3", "DEC3", "DEC3_192" -}; -static const char * const cdc_if_tx4_mux_text[] = { - "ZERO", "RX_MIX_TX4", "DEC4", "DEC4_192" -}; -static const char * const cdc_if_tx5_mux_text[] = { - "ZERO", "RX_MIX_TX5", "DEC5", "DEC5_192" -}; -static const char * const cdc_if_tx6_mux_text[] = { - "ZERO", "RX_MIX_TX6", "DEC6", "DEC6_192" -}; -static const char * const cdc_if_tx7_mux_text[] = { - "ZERO", "RX_MIX_TX7", "DEC7", "DEC7_192" -}; -static const char * const cdc_if_tx8_mux_text[] = { - "ZERO", "RX_MIX_TX8", "DEC8", "DEC8_192" -}; -static const char * const cdc_if_tx9_mux_text[] = { - "ZERO", "DEC7", "DEC7_192" -}; -static const char * const cdc_if_tx10_mux_text[] = { - "ZERO", "DEC6", "DEC6_192" -}; -static const char * const cdc_if_tx10_mux2_text[] = { - "TX10_MUX1", "I2SRX1_0_BRDG" -}; -static const char * const cdc_if_tx11_mux2_text[] = { - "TX11_MUX1", "I2SRX1_1_BRDG", "SWR_PACKED_PDM" -}; -static const char * const cdc_if_tx11_mux_text[] = { - "RDMA_TX11", "DEC_0_5", "DEC_9_12", "MAD_AUDIO", "MAD_BRDCST" -}; -static const char * const cdc_if_tx11_inp1_mux_text[] = { - "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", - "DEC5", "RX_MIX_TX5", "DEC9_10", "DEC11_12" -}; -static const char * const cdc_if_tx13_mux_text[] = { - "CDC_DEC_5", "MAD_BRDCST" -}; -static const char * const cdc_if_tx13_inp1_mux_text[] = { - "ZERO", "DEC5", "DEC5_192" -}; - -static const char * const iir_inp_mux_text[] = { - "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", - "DEC7", "DEC8", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7" -}; - -static const char * const rx_int_dem_inp_mux_text[] = { - "NORMAL_DSM_OUT", "NOT_VALID", "ADC_LOOPBACK" -}; - -static const char * const rx_int0_1_interp_mux_text[] = { - "ZERO", "RX INT0_1 MIX1", -}; - -static const char * const rx_int7_1_interp_mux_text[] = { - "ZERO", "RX INT7_1 MIX1", -}; - -static const char * const rx_int8_1_interp_mux_text[] = { - "ZERO", "RX INT8_1 MIX1", -}; - -static const char * const rx_int9_1_interp_mux_text[] = { - "ZERO", "RX INT9_1 MIX1", -}; - -static const char * const rx_int0_2_interp_mux_text[] = { - "ZERO", "RX INT0_2 MUX", -}; - -static const char * const rx_int7_2_interp_mux_text[] = { - "ZERO", "RX INT7_2 MUX", -}; - -static const char * const rx_int8_2_interp_mux_text[] = { - "ZERO", "RX INT8_2 MUX", -}; - -static const char * const rx_int9_2_interp_mux_text[] = { - "ZERO", "RX INT9_2 MUX", -}; - -static const char * const mad_sel_txt[] = { - "SPE", "MSM" -}; - -static const char * const mad_inp_mux_txt[] = { - "MAD", "DEC1" -}; - -static const char * const adc_mux_text[] = { - "DMIC", "AMIC", "ANC_FB_TUNE1" -}; - -static const char * const dmic_mux_text[] = { - "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", - "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "DMIC6", - "DMIC7" -}; - -static const char * const amic_mux_text[] = { - "ZERO", "ADC1", "ADC2", "ADC3", "ADC4" -}; - -static const char * const adc2_in_text[] = { - "AMIC2", "AMIC1" -}; - -static const char * const adc4_in_text[] = { - "AMIC4", "AMIC3" -}; - -static const char * const anc0_fb_mux_text[] = { - "ZERO", "INVALID", "ANC_IN_EAR", "ANC_IN_EAR_SPKR", -}; - -static const char * const rx_echo_mux_text[] = { - "ZERO", "RX_MIX0", "NA", "NA", "NA", "NA", "NA", "NA", - "RX_MIX7", "RX_MIX8", "NA", "NA", "NA", "NA", "RX_MIX9" -}; - -static const char *const slim_rx_mux_text[] = { - "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB" -}; - -static const char *const cdc_if_rx0_mux_text[] = { - "SLIM RX0", "I2S RX0" -}; -static const char *const cdc_if_rx1_mux_text[] = { - "SLIM RX1", "I2S RX1" -}; -static const char *const cdc_if_rx2_mux_text[] = { - "SLIM RX2", "I2SRX1_0", "I2SRX0_2" -}; -static const char *const cdc_if_rx3_mux_text[] = { - "SLIM RX3", "I2SRX1_1", "I2SRX0_3" -}; -static const char *const cdc_if_rx4_mux_text[] = { - "SLIM RX4", "I2S RX4" -}; -static const char *const cdc_if_rx5_mux_text[] = { - "SLIM RX5", "I2S RX5" -}; -static const char *const cdc_if_rx6_mux_text[] = { - "SLIM RX6", "I2S RX6" -}; -static const char *const cdc_if_rx7_mux_text[] = { - "SLIM RX7", "I2S RX7" -}; - -static const char * const asrc2_mux_text[] = { - "ZERO", "ASRC_IN_SPKR1", -}; - -static const char * const asrc3_mux_text[] = { - "ZERO", "ASRC_IN_SPKR2", -}; - -static const char * const native_mux_text[] = { - "OFF", "ON", -}; - -static const char *const wdma3_port0_text[] = { - "RX_MIX_TX0", "DEC0" -}; - -static const char *const wdma3_port1_text[] = { - "RX_MIX_TX1", "DEC1" -}; - -static const char *const wdma3_port2_text[] = { - "RX_MIX_TX2", "DEC2" -}; - -static const char *const wdma3_port3_text[] = { - "RX_MIX_TX3", "DEC3" -}; - -static const char *const wdma3_port4_text[] = { - "RX_MIX_TX4", "DEC4" -}; - -static const char *const wdma3_port5_text[] = { - "RX_MIX_TX5", "DEC5" -}; - -static const char *const wdma3_port6_text[] = { - "RX_MIX_TX6", "DEC6" -}; - -static const char *const wdma3_ch_text[] = { - "PORT_0", "PORT_1", "PORT_2", "PORT_3", "PORT_4", - "PORT_5", "PORT_6", "PORT_7", "PORT_8", -}; - -static const struct snd_kcontrol_new aif4_vi_mixer[] = { - SOC_SINGLE_EXT("SPKR_VI_1", SND_SOC_NOPM, WCD9360_TX14, 1, 0, - pahu_vi_feed_mixer_get, pahu_vi_feed_mixer_put), - SOC_SINGLE_EXT("SPKR_VI_2", SND_SOC_NOPM, WCD9360_TX15, 1, 0, - pahu_vi_feed_mixer_get, pahu_vi_feed_mixer_put), -}; - -static const struct snd_kcontrol_new aif1_cap_mixer[] = { - SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9360_TX0, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9360_TX1, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9360_TX2, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9360_TX3, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9360_TX4, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9360_TX5, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9360_TX6, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9360_TX7, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9360_TX8, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD9360_TX9, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD9360_TX10, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD9360_TX11, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9360_TX13, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), -}; - -static const struct snd_kcontrol_new aif2_cap_mixer[] = { - SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9360_TX0, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9360_TX1, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9360_TX2, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9360_TX3, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9360_TX4, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9360_TX5, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9360_TX6, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9360_TX7, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9360_TX8, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD9360_TX9, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD9360_TX10, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD9360_TX11, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9360_TX13, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), -}; - -static const struct snd_kcontrol_new aif3_cap_mixer[] = { - SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9360_TX0, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9360_TX1, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9360_TX2, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9360_TX3, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9360_TX4, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9360_TX5, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9360_TX6, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9360_TX7, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9360_TX8, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD9360_TX9, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD9360_TX10, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD9360_TX11, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), - SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9360_TX13, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), -}; - -static const struct snd_kcontrol_new aif4_mad_mixer[] = { - SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9360_TX13, 1, 0, - slim_tx_mixer_get, slim_tx_mixer_put), -}; - -WCD_DAPM_ENUM_EXT(slim_rx0, SND_SOC_NOPM, 0, slim_rx_mux_text, - slim_rx_mux_get, slim_rx_mux_put); -WCD_DAPM_ENUM_EXT(slim_rx1, SND_SOC_NOPM, 0, slim_rx_mux_text, - slim_rx_mux_get, slim_rx_mux_put); -WCD_DAPM_ENUM_EXT(slim_rx2, SND_SOC_NOPM, 0, slim_rx_mux_text, - slim_rx_mux_get, slim_rx_mux_put); -WCD_DAPM_ENUM_EXT(slim_rx3, SND_SOC_NOPM, 0, slim_rx_mux_text, - slim_rx_mux_get, slim_rx_mux_put); -WCD_DAPM_ENUM_EXT(slim_rx4, SND_SOC_NOPM, 0, slim_rx_mux_text, - slim_rx_mux_get, slim_rx_mux_put); -WCD_DAPM_ENUM_EXT(slim_rx5, SND_SOC_NOPM, 0, slim_rx_mux_text, - slim_rx_mux_get, slim_rx_mux_put); -WCD_DAPM_ENUM_EXT(slim_rx6, SND_SOC_NOPM, 0, slim_rx_mux_text, - slim_rx_mux_get, slim_rx_mux_put); -WCD_DAPM_ENUM_EXT(slim_rx7, SND_SOC_NOPM, 0, slim_rx_mux_text, - slim_rx_mux_get, slim_rx_mux_put); - -WCD_DAPM_ENUM(cdc_if_rx0, SND_SOC_NOPM, 0, cdc_if_rx0_mux_text); -WCD_DAPM_ENUM(cdc_if_rx1, SND_SOC_NOPM, 0, cdc_if_rx1_mux_text); -WCD_DAPM_ENUM(cdc_if_rx2, SND_SOC_NOPM, 0, cdc_if_rx2_mux_text); -WCD_DAPM_ENUM(cdc_if_rx3, SND_SOC_NOPM, 0, cdc_if_rx3_mux_text); -WCD_DAPM_ENUM(cdc_if_rx4, SND_SOC_NOPM, 0, cdc_if_rx4_mux_text); -WCD_DAPM_ENUM(cdc_if_rx5, SND_SOC_NOPM, 0, cdc_if_rx5_mux_text); -WCD_DAPM_ENUM(cdc_if_rx6, SND_SOC_NOPM, 0, cdc_if_rx6_mux_text); -WCD_DAPM_ENUM(cdc_if_rx7, SND_SOC_NOPM, 0, cdc_if_rx7_mux_text); - -WCD_DAPM_ENUM(rx_int0_2, WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, - rx_int0_7_mix_mux_text); -WCD_DAPM_ENUM(rx_int7_2, WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1, 0, - rx_int0_7_mix_mux_text); -WCD_DAPM_ENUM(rx_int8_2, WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1, 0, - rx_int_mix_mux_text); -WCD_DAPM_ENUM(rx_int9_2, WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1, 0, - rx_int0_7_mix_mux_text); - -WCD_DAPM_ENUM(rx_int0_1_mix_inp0, WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0, 0, - rx_prim_mix_text); -WCD_DAPM_ENUM(rx_int0_1_mix_inp1, WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0, 4, - rx_prim_mix_text); -WCD_DAPM_ENUM(rx_int0_1_mix_inp2, WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1, 4, - rx_prim_mix_text); -WCD_DAPM_ENUM(rx_int7_1_mix_inp0, WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0, 0, - rx_prim_mix_text); -WCD_DAPM_ENUM(rx_int7_1_mix_inp1, WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0, 4, - rx_prim_mix_text); -WCD_DAPM_ENUM(rx_int7_1_mix_inp2, WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1, 4, - rx_prim_mix_text); -WCD_DAPM_ENUM(rx_int8_1_mix_inp0, WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0, 0, - rx_prim_mix_text); -WCD_DAPM_ENUM(rx_int8_1_mix_inp1, WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0, 4, - rx_prim_mix_text); -WCD_DAPM_ENUM(rx_int8_1_mix_inp2, WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1, 4, - rx_prim_mix_text); -WCD_DAPM_ENUM(rx_int9_1_mix_inp0, WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0, 0, - rx_prim_mix_text); -WCD_DAPM_ENUM(rx_int9_1_mix_inp1, WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0, 4, - rx_prim_mix_text); -WCD_DAPM_ENUM(rx_int9_1_mix_inp2, WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1, 4, - rx_prim_mix_text); - -WCD_DAPM_ENUM(rx_int0_mix2_inp, WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0, - rx_sidetone_mix_text); -WCD_DAPM_ENUM(rx_int7_mix2_inp, WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 2, - rx_sidetone_mix_text); -WCD_DAPM_ENUM(rx_int9_mix2_inp, WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 4, - rx_sidetone_mix_text); - -WCD_DAPM_ENUM(tx_adc_mux10, WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 4, - adc_mux_text); -WCD_DAPM_ENUM(tx_adc_mux11, WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 4, - adc_mux_text); - -WCD_DAPM_ENUM(tx_dmic_mux0, WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 3, - dmic_mux_text); -WCD_DAPM_ENUM(tx_dmic_mux1, WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 3, - dmic_mux_text); -WCD_DAPM_ENUM(tx_dmic_mux2, WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 3, - dmic_mux_text); -WCD_DAPM_ENUM(tx_dmic_mux3, WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 3, - dmic_mux_text); -WCD_DAPM_ENUM(tx_dmic_mux4, WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 3, - dmic_mux_text); -WCD_DAPM_ENUM(tx_dmic_mux5, WCD9360_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 3, - dmic_mux_text); -WCD_DAPM_ENUM(tx_dmic_mux6, WCD9360_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 3, - dmic_mux_text); -WCD_DAPM_ENUM(tx_dmic_mux7, WCD9360_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 3, - dmic_mux_text); -WCD_DAPM_ENUM(tx_dmic_mux8, WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 3, - dmic_mux_text); -WCD_DAPM_ENUM(tx_dmic_mux10, WCD9360_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 3, - dmic_mux_text); -WCD_DAPM_ENUM(tx_dmic_mux11, WCD9360_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 3, - dmic_mux_text); - -WCD_DAPM_ENUM(tx_amic_mux0, WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0, - amic_mux_text); -WCD_DAPM_ENUM(tx_amic_mux1, WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0, - amic_mux_text); -WCD_DAPM_ENUM(tx_amic_mux2, WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0, - amic_mux_text); -WCD_DAPM_ENUM(tx_amic_mux3, WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0, - amic_mux_text); -WCD_DAPM_ENUM(tx_amic_mux4, WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0, - amic_mux_text); -WCD_DAPM_ENUM(tx_amic_mux5, WCD9360_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0, - amic_mux_text); -WCD_DAPM_ENUM(tx_amic_mux6, WCD9360_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0, - amic_mux_text); -WCD_DAPM_ENUM(tx_amic_mux7, WCD9360_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0, - amic_mux_text); -WCD_DAPM_ENUM(tx_amic_mux8, WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0, - amic_mux_text); -WCD_DAPM_ENUM(tx_amic_mux10, WCD9360_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0, - amic_mux_text); -WCD_DAPM_ENUM(tx_amic_mux11, WCD9360_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0, - amic_mux_text); - -WCD_DAPM_ENUM(tx_adc2_in, WCD9360_ANA_AMIC_INPUT_SWITCH_CTL, 7, adc2_in_text); -WCD_DAPM_ENUM(tx_adc4_in, WCD9360_ANA_AMIC_INPUT_SWITCH_CTL, 6, adc4_in_text); - -WCD_DAPM_ENUM(cdc_if_tx0, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0, 0, - cdc_if_tx0_mux_text); -WCD_DAPM_ENUM(cdc_if_tx1, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0, 2, - cdc_if_tx1_mux_text); -WCD_DAPM_ENUM(cdc_if_tx2, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0, 4, - cdc_if_tx2_mux_text); -WCD_DAPM_ENUM(cdc_if_tx3, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0, 6, - cdc_if_tx3_mux_text); -WCD_DAPM_ENUM(cdc_if_tx4, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1, 0, - cdc_if_tx4_mux_text); -WCD_DAPM_ENUM(cdc_if_tx5, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1, 2, - cdc_if_tx5_mux_text); -WCD_DAPM_ENUM(cdc_if_tx6, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1, 4, - cdc_if_tx6_mux_text); -WCD_DAPM_ENUM(cdc_if_tx7, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1, 6, - cdc_if_tx7_mux_text); -WCD_DAPM_ENUM(cdc_if_tx8, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2, 0, - cdc_if_tx8_mux_text); -WCD_DAPM_ENUM(cdc_if_tx9, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2, 2, - cdc_if_tx9_mux_text); -WCD_DAPM_ENUM(cdc_if_tx10, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2, 4, - cdc_if_tx10_mux_text); -WCD_DAPM_ENUM(cdc_if_tx10_inp2, WCD9360_DATA_HUB_SB_TX10_INP_CFG, 3, - cdc_if_tx10_mux2_text); -WCD_DAPM_ENUM(cdc_if_tx11_inp1, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3, 0, - cdc_if_tx11_inp1_mux_text); -WCD_DAPM_ENUM(cdc_if_tx11, WCD9360_DATA_HUB_SB_TX11_INP_CFG, 0, - cdc_if_tx11_mux_text); -WCD_DAPM_ENUM(cdc_if_tx11_inp2, WCD9360_DATA_HUB_SB_TX11_INP_CFG, 3, - cdc_if_tx11_mux2_text); -WCD_DAPM_ENUM(cdc_if_tx13_inp1, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3, 4, - cdc_if_tx13_inp1_mux_text); -WCD_DAPM_ENUM(cdc_if_tx13, WCD9360_DATA_HUB_SB_TX13_INP_CFG, 0, - cdc_if_tx13_mux_text); - -WCD_DAPM_ENUM(rx_mix_tx0, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG0, 0, - rx_echo_mux_text); -WCD_DAPM_ENUM(rx_mix_tx1, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG0, 4, - rx_echo_mux_text); -WCD_DAPM_ENUM(rx_mix_tx2, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG1, 0, - rx_echo_mux_text); -WCD_DAPM_ENUM(rx_mix_tx3, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG1, 4, - rx_echo_mux_text); -WCD_DAPM_ENUM(rx_mix_tx4, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG2, 0, - rx_echo_mux_text); -WCD_DAPM_ENUM(rx_mix_tx5, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG2, 4, - rx_echo_mux_text); -WCD_DAPM_ENUM(rx_mix_tx6, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG3, 0, - rx_echo_mux_text); -WCD_DAPM_ENUM(rx_mix_tx7, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG3, 4, - rx_echo_mux_text); -WCD_DAPM_ENUM(rx_mix_tx8, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, - rx_echo_mux_text); - -WCD_DAPM_ENUM(iir0_inp0, WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0, - iir_inp_mux_text); -WCD_DAPM_ENUM(iir0_inp1, WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1, 0, - iir_inp_mux_text); -WCD_DAPM_ENUM(iir0_inp2, WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2, 0, - iir_inp_mux_text); -WCD_DAPM_ENUM(iir0_inp3, WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3, 0, - iir_inp_mux_text); - -WCD_DAPM_ENUM(rx_int0_1_interp, SND_SOC_NOPM, 0, rx_int0_1_interp_mux_text); -WCD_DAPM_ENUM(rx_int7_1_interp, SND_SOC_NOPM, 0, rx_int7_1_interp_mux_text); -WCD_DAPM_ENUM(rx_int8_1_interp, SND_SOC_NOPM, 0, rx_int8_1_interp_mux_text); -WCD_DAPM_ENUM(rx_int9_1_interp, SND_SOC_NOPM, 0, rx_int9_1_interp_mux_text); - -WCD_DAPM_ENUM(rx_int0_2_interp, SND_SOC_NOPM, 0, rx_int0_2_interp_mux_text); -WCD_DAPM_ENUM(rx_int7_2_interp, SND_SOC_NOPM, 0, rx_int7_2_interp_mux_text); -WCD_DAPM_ENUM(rx_int8_2_interp, SND_SOC_NOPM, 0, rx_int8_2_interp_mux_text); -WCD_DAPM_ENUM(rx_int9_2_interp, SND_SOC_NOPM, 0, rx_int9_2_interp_mux_text); - -WCD_DAPM_ENUM(mad_sel, WCD9360_CPE_SS_SVA_CFG, 0, - mad_sel_txt); - -WCD_DAPM_ENUM(mad_inp_mux, WCD9360_CPE_SS_SVA_CFG, 2, - mad_inp_mux_txt); - -WCD_DAPM_ENUM_EXT(rx_int0_dem_inp, WCD9360_CDC_RX0_RX_PATH_SEC0, 0, - rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double, - pahu_int_dem_inp_mux_put); - -WCD_DAPM_ENUM_EXT(rx_int9_dem_inp, WCD9360_CDC_RX9_RX_PATH_SEC0, 0, - rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double, - pahu_int_dem_inp_mux_put); - -WCD_DAPM_ENUM_EXT(tx_adc_mux0, WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0, - adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); -WCD_DAPM_ENUM_EXT(tx_adc_mux1, WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0, - adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); -WCD_DAPM_ENUM_EXT(tx_adc_mux2, WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0, - adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); -WCD_DAPM_ENUM_EXT(tx_adc_mux3, WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0, - adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); -WCD_DAPM_ENUM_EXT(tx_adc_mux4, WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 2, - adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); -WCD_DAPM_ENUM_EXT(tx_adc_mux5, WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 2, - adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); -WCD_DAPM_ENUM_EXT(tx_adc_mux6, WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 2, - adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); -WCD_DAPM_ENUM_EXT(tx_adc_mux7, WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 2, - adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); -WCD_DAPM_ENUM_EXT(tx_adc_mux8, WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 4, - adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put); - -WCD_DAPM_ENUM(asrc2, WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 4, - asrc2_mux_text); -WCD_DAPM_ENUM(asrc3, WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 6, - asrc3_mux_text); - -WCD_DAPM_ENUM(int7_2_native, SND_SOC_NOPM, 0, native_mux_text); -WCD_DAPM_ENUM(int8_2_native, SND_SOC_NOPM, 0, native_mux_text); - -WCD_DAPM_ENUM(anc0_fb, WCD9360_CDC_RX_INP_MUX_ANC_CFG0, 0, anc0_fb_mux_text); - -WCD_DAPM_ENUM(wdma3_port0, WCD9360_DMA_WDMA3_PRT_CFG, 0, wdma3_port0_text); -WCD_DAPM_ENUM(wdma3_port1, WCD9360_DMA_WDMA3_PRT_CFG, 1, wdma3_port1_text); -WCD_DAPM_ENUM(wdma3_port2, WCD9360_DMA_WDMA3_PRT_CFG, 2, wdma3_port2_text); -WCD_DAPM_ENUM(wdma3_port3, WCD9360_DMA_WDMA3_PRT_CFG, 3, wdma3_port3_text); -WCD_DAPM_ENUM(wdma3_port4, WCD9360_DMA_WDMA3_PRT_CFG, 4, wdma3_port4_text); -WCD_DAPM_ENUM(wdma3_port5, WCD9360_DMA_WDMA3_PRT_CFG, 5, wdma3_port5_text); -WCD_DAPM_ENUM(wdma3_port6, WCD9360_DMA_WDMA3_PRT_CFG, 6, wdma3_port6_text); - -WCD_DAPM_ENUM(wdma3_ch0, WCD9360_DMA_CH_0_1_CFG_WDMA_3, 0, wdma3_ch_text); -WCD_DAPM_ENUM(wdma3_ch1, WCD9360_DMA_CH_0_1_CFG_WDMA_3, 4, wdma3_ch_text); -WCD_DAPM_ENUM(wdma3_ch2, WCD9360_DMA_CH_2_3_CFG_WDMA_3, 0, wdma3_ch_text); -WCD_DAPM_ENUM(wdma3_ch3, WCD9360_DMA_CH_2_3_CFG_WDMA_3, 4, wdma3_ch_text); - -static const struct snd_kcontrol_new anc_ear_switch = - SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); - -static const struct snd_kcontrol_new anc_ear_spkr_switch = - SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); - -static const struct snd_kcontrol_new anc_spkr_pa_switch = - SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); - -static const struct snd_kcontrol_new mad_cpe1_switch = - SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); - -static const struct snd_kcontrol_new mad_cpe2_switch = - SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); - -static const struct snd_kcontrol_new mad_brdcst_switch = - SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); - -static const struct snd_kcontrol_new adc_us_mux0_switch = - SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); - -static const struct snd_kcontrol_new adc_us_mux1_switch = - SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); - -static const struct snd_kcontrol_new adc_us_mux2_switch = - SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); - -static const struct snd_kcontrol_new adc_us_mux3_switch = - SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); - -static const struct snd_kcontrol_new adc_us_mux4_switch = - SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); - -static const struct snd_kcontrol_new adc_us_mux5_switch = - SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); - -static const struct snd_kcontrol_new adc_us_mux6_switch = - SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); - -static const struct snd_kcontrol_new adc_us_mux7_switch = - SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); - -static const struct snd_kcontrol_new adc_us_mux8_switch = - SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0); - -static const struct snd_kcontrol_new wdma3_onoff_switch = - SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); - -static const char *const i2s_tx1_0_txt[] = { - "ZERO", "SB_TX8", "SB_RX2", "SB_TX12" -}; - -static const char *const i2s_tx1_1_txt[] = { - "ZERO", "SB_RX0", "SB_RX1", "SB_RX2", "SB_RX3", "SB_TX11" -}; - -WCD_DAPM_ENUM(i2s_tx1_0_inp, WCD9360_DATA_HUB_I2S_TX1_0_CFG, 0, i2s_tx1_0_txt); -WCD_DAPM_ENUM(i2s_tx1_1_inp, WCD9360_DATA_HUB_I2S_TX1_1_CFG, 0, i2s_tx1_1_txt); - -static const struct snd_soc_dapm_widget pahu_dapm_widgets[] = { - SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM, - AIF1_PB, 0, pahu_codec_enable_slimrx, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM, - AIF2_PB, 0, pahu_codec_enable_slimrx, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM, - AIF3_PB, 0, pahu_codec_enable_slimrx, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM, - AIF4_PB, 0, pahu_codec_enable_slimrx, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_AIF_IN_E("I2S1 PB", "I2S1 Playback", 0, SND_SOC_NOPM, - I2S1_PB, 0, pahu_i2s_aif_rx_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - - WCD_DAPM_MUX("SLIM RX0 MUX", WCD9360_RX0, slim_rx0), - WCD_DAPM_MUX("SLIM RX1 MUX", WCD9360_RX1, slim_rx1), - WCD_DAPM_MUX("SLIM RX2 MUX", WCD9360_RX2, slim_rx2), - WCD_DAPM_MUX("SLIM RX3 MUX", WCD9360_RX3, slim_rx3), - WCD_DAPM_MUX("SLIM RX4 MUX", WCD9360_RX4, slim_rx4), - WCD_DAPM_MUX("SLIM RX5 MUX", WCD9360_RX5, slim_rx5), - WCD_DAPM_MUX("SLIM RX6 MUX", WCD9360_RX6, slim_rx6), - WCD_DAPM_MUX("SLIM RX7 MUX", WCD9360_RX7, slim_rx7), - - SND_SOC_DAPM_MIXER("SLIM RX0", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0), - - WCD_DAPM_MUX("CDC_IF RX0 MUX", WCD9360_RX0, cdc_if_rx0), - WCD_DAPM_MUX("CDC_IF RX1 MUX", WCD9360_RX1, cdc_if_rx1), - WCD_DAPM_MUX("CDC_IF RX2 MUX", WCD9360_RX2, cdc_if_rx2), - WCD_DAPM_MUX("CDC_IF RX3 MUX", WCD9360_RX3, cdc_if_rx3), - WCD_DAPM_MUX("CDC_IF RX4 MUX", WCD9360_RX4, cdc_if_rx4), - WCD_DAPM_MUX("CDC_IF RX5 MUX", WCD9360_RX5, cdc_if_rx5), - WCD_DAPM_MUX("CDC_IF RX6 MUX", WCD9360_RX6, cdc_if_rx6), - WCD_DAPM_MUX("CDC_IF RX7 MUX", WCD9360_RX7, cdc_if_rx7), - - SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", SND_SOC_NOPM, INTERP_EAR, 0, - &rx_int0_2_mux, pahu_codec_enable_mix_path, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("RX INT7_2 MUX", SND_SOC_NOPM, INTERP_SPKR1, 0, - &rx_int7_2_mux, pahu_codec_enable_mix_path, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("RX INT8_2 MUX", SND_SOC_NOPM, INTERP_SPKR2, 0, - &rx_int8_2_mux, pahu_codec_enable_mix_path, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("RX INT9_2 MUX", SND_SOC_NOPM, INTERP_AUX, 0, - &rx_int9_2_mux, pahu_codec_enable_mix_path, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), - - WCD_DAPM_MUX("RX INT0_1 MIX1 INP0", 0, rx_int0_1_mix_inp0), - WCD_DAPM_MUX("RX INT0_1 MIX1 INP1", 0, rx_int0_1_mix_inp1), - WCD_DAPM_MUX("RX INT0_1 MIX1 INP2", 0, rx_int0_1_mix_inp2), - - SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, - &rx_int7_1_mix_inp0_mux, pahu_codec_enable_swr, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, - &rx_int7_1_mix_inp1_mux, pahu_codec_enable_swr, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, - &rx_int7_1_mix_inp2_mux, pahu_codec_enable_swr, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, - &rx_int8_1_mix_inp0_mux, pahu_codec_enable_swr, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, - &rx_int8_1_mix_inp1_mux, pahu_codec_enable_swr, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, - &rx_int8_1_mix_inp2_mux, pahu_codec_enable_swr, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - WCD_DAPM_MUX("RX INT9_1 MIX1 INP0", 0, rx_int9_1_mix_inp0), - WCD_DAPM_MUX("RX INT9_1 MIX1 INP1", 0, rx_int9_1_mix_inp1), - WCD_DAPM_MUX("RX INT9_1 MIX1 INP2", 0, rx_int9_1_mix_inp2), - - SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("RX INT7_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("RX INT7 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("RX INT8_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("RX INT8 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("RX INT9_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("RX INT9 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), - - SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("RX INT7 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("RX INT9 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), - - SND_SOC_DAPM_MIXER_E("RX INT7 CHAIN", SND_SOC_NOPM, 0, 0, - NULL, 0, pahu_codec_spk_boost_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER_E("RX INT8 CHAIN", SND_SOC_NOPM, 0, 0, - NULL, 0, pahu_codec_spk_boost_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX_E("RX INT0 MIX2 INP", SND_SOC_NOPM, INTERP_EAR, - 0, &rx_int0_mix2_inp_mux, pahu_codec_enable_rx_path_clk, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("RX INT7 MIX2 INP", SND_SOC_NOPM, INTERP_SPKR1, - 0, &rx_int7_mix2_inp_mux, pahu_codec_enable_rx_path_clk, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("RX INT9 MIX2 INP", SND_SOC_NOPM, INTERP_AUX, - 0, &rx_int9_mix2_inp_mux, pahu_codec_enable_rx_path_clk, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - WCD_DAPM_MUX("CDC_IF TX0 MUX", WCD9360_TX0, cdc_if_tx0), - WCD_DAPM_MUX("CDC_IF TX1 MUX", WCD9360_TX1, cdc_if_tx1), - WCD_DAPM_MUX("CDC_IF TX2 MUX", WCD9360_TX2, cdc_if_tx2), - WCD_DAPM_MUX("CDC_IF TX3 MUX", WCD9360_TX3, cdc_if_tx3), - WCD_DAPM_MUX("CDC_IF TX4 MUX", WCD9360_TX4, cdc_if_tx4), - WCD_DAPM_MUX("CDC_IF TX5 MUX", WCD9360_TX5, cdc_if_tx5), - WCD_DAPM_MUX("CDC_IF TX6 MUX", WCD9360_TX6, cdc_if_tx6), - WCD_DAPM_MUX("CDC_IF TX7 MUX", WCD9360_TX7, cdc_if_tx7), - WCD_DAPM_MUX("CDC_IF TX8 MUX", WCD9360_TX8, cdc_if_tx8), - WCD_DAPM_MUX("CDC_IF TX9 MUX", WCD9360_TX9, cdc_if_tx9), - WCD_DAPM_MUX("CDC_IF TX10 MUX", WCD9360_TX10, cdc_if_tx10), - WCD_DAPM_MUX("CDC_IF TX11 MUX", WCD9360_TX11, cdc_if_tx11), - WCD_DAPM_MUX("CDC_IF TX11 INP1 MUX", WCD9360_TX11, cdc_if_tx11_inp1), - WCD_DAPM_MUX("CDC_IF TX13 MUX", WCD9360_TX13, cdc_if_tx13), - WCD_DAPM_MUX("CDC_IF TX13 INP1 MUX", WCD9360_TX13, cdc_if_tx13_inp1), - WCD_DAPM_MUX("CDC_IF TX10 MUX2", WCD9360_TX10, cdc_if_tx10_inp2), - WCD_DAPM_MUX("CDC_IF TX11 MUX2", WCD9360_TX11, cdc_if_tx11_inp2), - - SND_SOC_DAPM_MUX_E("ADC MUX0", WCD9360_CDC_TX0_TX_PATH_CTL, 5, 0, - &tx_adc_mux0_mux, pahu_codec_enable_dec, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX_E("ADC MUX1", WCD9360_CDC_TX1_TX_PATH_CTL, 5, 0, - &tx_adc_mux1_mux, pahu_codec_enable_dec, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX_E("ADC MUX2", WCD9360_CDC_TX2_TX_PATH_CTL, 5, 0, - &tx_adc_mux2_mux, pahu_codec_enable_dec, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX_E("ADC MUX3", WCD9360_CDC_TX3_TX_PATH_CTL, 5, 0, - &tx_adc_mux3_mux, pahu_codec_enable_dec, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX_E("ADC MUX4", WCD9360_CDC_TX4_TX_PATH_CTL, 5, 0, - &tx_adc_mux4_mux, pahu_codec_enable_dec, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX_E("ADC MUX5", WCD9360_CDC_TX5_TX_PATH_CTL, 5, 0, - &tx_adc_mux5_mux, pahu_codec_enable_dec, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX_E("ADC MUX6", WCD9360_CDC_TX6_TX_PATH_CTL, 5, 0, - &tx_adc_mux6_mux, pahu_codec_enable_dec, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX_E("ADC MUX7", WCD9360_CDC_TX7_TX_PATH_CTL, 5, 0, - &tx_adc_mux7_mux, pahu_codec_enable_dec, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX_E("ADC MUX8", WCD9360_CDC_TX8_TX_PATH_CTL, 5, 0, - &tx_adc_mux8_mux, pahu_codec_enable_dec, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX_E("ADC MUX10", SND_SOC_NOPM, 10, 0, &tx_adc_mux10_mux, - pahu_codec_tx_adc_cfg, SND_SOC_DAPM_POST_PMU), - - SND_SOC_DAPM_MUX_E("ADC MUX11", SND_SOC_NOPM, 11, 0, &tx_adc_mux11_mux, - pahu_codec_tx_adc_cfg, SND_SOC_DAPM_POST_PMU), - - WCD_DAPM_MUX("DMIC MUX0", 0, tx_dmic_mux0), - WCD_DAPM_MUX("DMIC MUX1", 0, tx_dmic_mux1), - WCD_DAPM_MUX("DMIC MUX2", 0, tx_dmic_mux2), - WCD_DAPM_MUX("DMIC MUX3", 0, tx_dmic_mux3), - WCD_DAPM_MUX("DMIC MUX4", 0, tx_dmic_mux4), - WCD_DAPM_MUX("DMIC MUX5", 0, tx_dmic_mux5), - WCD_DAPM_MUX("DMIC MUX6", 0, tx_dmic_mux6), - WCD_DAPM_MUX("DMIC MUX7", 0, tx_dmic_mux7), - WCD_DAPM_MUX("DMIC MUX8", 0, tx_dmic_mux8), - WCD_DAPM_MUX("DMIC MUX10", 0, tx_dmic_mux10), - WCD_DAPM_MUX("DMIC MUX11", 0, tx_dmic_mux11), - - WCD_DAPM_MUX("AMIC MUX0", 0, tx_amic_mux0), - WCD_DAPM_MUX("AMIC MUX1", 0, tx_amic_mux1), - WCD_DAPM_MUX("AMIC MUX2", 0, tx_amic_mux2), - WCD_DAPM_MUX("AMIC MUX3", 0, tx_amic_mux3), - WCD_DAPM_MUX("AMIC MUX4", 0, tx_amic_mux4), - WCD_DAPM_MUX("AMIC MUX5", 0, tx_amic_mux5), - WCD_DAPM_MUX("AMIC MUX6", 0, tx_amic_mux6), - WCD_DAPM_MUX("AMIC MUX7", 0, tx_amic_mux7), - WCD_DAPM_MUX("AMIC MUX8", 0, tx_amic_mux8), - WCD_DAPM_MUX("AMIC MUX10", 0, tx_amic_mux10), - WCD_DAPM_MUX("AMIC MUX11", 0, tx_amic_mux11), - - SND_SOC_DAPM_ADC_E("ADC1", NULL, WCD9360_ANA_AMIC1, 7, 0, - pahu_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), - SND_SOC_DAPM_ADC_E("ADC2", NULL, WCD9360_ANA_AMIC2, 7, 0, - pahu_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), - SND_SOC_DAPM_ADC_E("ADC3", NULL, WCD9360_ANA_AMIC3, 7, 0, - pahu_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), - SND_SOC_DAPM_ADC_E("ADC4", NULL, WCD9360_ANA_AMIC4, 7, 0, - pahu_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), - - WCD_DAPM_MUX("ANC0 FB MUX", 0, anc0_fb), - - WCD_DAPM_MUX("ADC2_IN", 0, tx_adc2_in), - WCD_DAPM_MUX("ADC4_IN", 0, tx_adc4_in), - - SND_SOC_DAPM_INPUT("AMIC1"), - SND_SOC_DAPM_INPUT("AMIC2"), - SND_SOC_DAPM_INPUT("AMIC3"), - SND_SOC_DAPM_INPUT("AMIC4"), - - SND_SOC_DAPM_MICBIAS_E("MIC BIAS1", SND_SOC_NOPM, 0, 0, - pahu_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MICBIAS_E("MIC BIAS2", SND_SOC_NOPM, 0, 0, - pahu_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MICBIAS_E("MIC BIAS3", SND_SOC_NOPM, 0, 0, - pahu_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MICBIAS_E("MIC BIAS4", SND_SOC_NOPM, 0, 0, - pahu_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS1_STANDALONE, SND_SOC_NOPM, 0, 0, - pahu_codec_force_enable_micbias, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS2_STANDALONE, SND_SOC_NOPM, 0, 0, - pahu_codec_force_enable_micbias, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS3_STANDALONE, SND_SOC_NOPM, 0, 0, - pahu_codec_force_enable_micbias, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS4_STANDALONE, SND_SOC_NOPM, 0, 0, - pahu_codec_force_enable_micbias, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM, - AIF1_CAP, 0, pahu_codec_enable_slimtx, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM, - AIF2_CAP, 0, pahu_codec_enable_slimtx, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM, - AIF3_CAP, 0, pahu_codec_enable_slimtx, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - - WCD_DAPM_MUX("I2S TX1_0 MUX", 0, i2s_tx1_0_inp), - WCD_DAPM_MUX("I2S TX1_1 MUX", 0, i2s_tx1_1_inp), - SND_SOC_DAPM_MIXER("I2S TX1 MIXER", SND_SOC_NOPM, 0, 0, NULL, 0), - - SND_SOC_DAPM_AIF_OUT_E("I2S1 CAP", "I2S1 Capture", 0, - SND_SOC_NOPM, I2S1_CAP, 0, pahu_i2s_aif_tx_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0, - aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)), - SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0, - aif2_cap_mixer, ARRAY_SIZE(aif2_cap_mixer)), - SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0, - aif3_cap_mixer, ARRAY_SIZE(aif3_cap_mixer)), - SND_SOC_DAPM_MIXER("AIF4_MAD Mixer", SND_SOC_NOPM, AIF4_MAD_TX, 0, - aif4_mad_mixer, ARRAY_SIZE(aif4_mad_mixer)), - - SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM, - AIF4_VIFEED, 0, pahu_codec_enable_slimvi_feedback, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_AIF_OUT("AIF4 MAD", "AIF4 MAD TX", 0, - SND_SOC_NOPM, 0, 0), - - SND_SOC_DAPM_MIXER("AIF4_VI Mixer", SND_SOC_NOPM, AIF4_VIFEED, 0, - aif4_vi_mixer, ARRAY_SIZE(aif4_vi_mixer)), - SND_SOC_DAPM_INPUT("VIINPUT"), - - SND_SOC_DAPM_MIXER("SLIM TX0", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM TX1", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM TX2", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM TX3", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM TX4", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM TX5", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM TX6", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM TX7", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM TX8", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM TX9", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM TX10", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM TX11", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("SLIM TX13", SND_SOC_NOPM, 0, 0, NULL, 0), - - /* Digital Mic Inputs */ - SND_SOC_DAPM_ADC_E("DMIC0", NULL, SND_SOC_NOPM, 0, 0, - pahu_codec_enable_dmic, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 1, 0, - pahu_codec_enable_dmic, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 2, 0, - pahu_codec_enable_dmic, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 3, 0, - pahu_codec_enable_dmic, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 4, 0, - pahu_codec_enable_dmic, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 5, 0, - pahu_codec_enable_dmic, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 6, 0, - pahu_codec_enable_dmic, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC7", NULL, SND_SOC_NOPM, 7, 0, - pahu_codec_enable_dmic, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - WCD_DAPM_MUX("IIR0 INP0 MUX", 0, iir0_inp0), - WCD_DAPM_MUX("IIR0 INP1 MUX", 0, iir0_inp1), - WCD_DAPM_MUX("IIR0 INP2 MUX", 0, iir0_inp2), - WCD_DAPM_MUX("IIR0 INP3 MUX", 0, iir0_inp3), - - SND_SOC_DAPM_MIXER_E("IIR0", WCD9360_CDC_SIDETONE_IIR0_IIR_PATH_CTL, - 4, 0, NULL, 0, pahu_codec_set_iir_gain, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_MIXER("SRC0", WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL, - 4, 0, NULL, 0), - - WCD_DAPM_MUX("RX MIX TX0 MUX", 0, rx_mix_tx0), - WCD_DAPM_MUX("RX MIX TX1 MUX", 0, rx_mix_tx1), - WCD_DAPM_MUX("RX MIX TX2 MUX", 0, rx_mix_tx2), - WCD_DAPM_MUX("RX MIX TX3 MUX", 0, rx_mix_tx3), - WCD_DAPM_MUX("RX MIX TX4 MUX", 0, rx_mix_tx4), - WCD_DAPM_MUX("RX MIX TX5 MUX", 0, rx_mix_tx5), - WCD_DAPM_MUX("RX MIX TX6 MUX", 0, rx_mix_tx6), - WCD_DAPM_MUX("RX MIX TX7 MUX", 0, rx_mix_tx7), - WCD_DAPM_MUX("RX MIX TX8 MUX", 0, rx_mix_tx8), - WCD_DAPM_MUX("RX INT0 DEM MUX", 0, rx_int0_dem_inp), - WCD_DAPM_MUX("RX INT9 DEM MUX", 0, rx_int9_dem_inp), - - SND_SOC_DAPM_MUX_E("RX INT0_1 INTERP", SND_SOC_NOPM, INTERP_EAR, 0, - &rx_int0_1_interp_mux, pahu_codec_enable_main_path, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("RX INT7_1 INTERP", SND_SOC_NOPM, INTERP_SPKR1, 0, - &rx_int7_1_interp_mux, pahu_codec_enable_main_path, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("RX INT8_1 INTERP", SND_SOC_NOPM, INTERP_SPKR2, 0, - &rx_int8_1_interp_mux, pahu_codec_enable_main_path, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("RX INT9_1 INTERP", SND_SOC_NOPM, INTERP_AUX, 0, - &rx_int9_1_interp_mux, pahu_codec_enable_main_path, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_POST_PMD), - - WCD_DAPM_MUX("RX INT0_2 INTERP", 0, rx_int0_2_interp), - WCD_DAPM_MUX("RX INT7_2 INTERP", 0, rx_int7_2_interp), - WCD_DAPM_MUX("RX INT8_2 INTERP", 0, rx_int8_2_interp), - WCD_DAPM_MUX("RX INT9_2 INTERP", 0, rx_int9_2_interp), - - SND_SOC_DAPM_SWITCH("ADC US MUX0", WCD9360_CDC_TX0_TX_PATH_192_CTL, 0, - 0, &adc_us_mux0_switch), - SND_SOC_DAPM_SWITCH("ADC US MUX1", WCD9360_CDC_TX1_TX_PATH_192_CTL, 0, - 0, &adc_us_mux1_switch), - SND_SOC_DAPM_SWITCH("ADC US MUX2", WCD9360_CDC_TX2_TX_PATH_192_CTL, 0, - 0, &adc_us_mux2_switch), - SND_SOC_DAPM_SWITCH("ADC US MUX3", WCD9360_CDC_TX3_TX_PATH_192_CTL, 0, - 0, &adc_us_mux3_switch), - SND_SOC_DAPM_SWITCH("ADC US MUX4", WCD9360_CDC_TX4_TX_PATH_192_CTL, 0, - 0, &adc_us_mux4_switch), - SND_SOC_DAPM_SWITCH("ADC US MUX5", WCD9360_CDC_TX5_TX_PATH_192_CTL, 0, - 0, &adc_us_mux5_switch), - SND_SOC_DAPM_SWITCH("ADC US MUX6", WCD9360_CDC_TX6_TX_PATH_192_CTL, 0, - 0, &adc_us_mux6_switch), - SND_SOC_DAPM_SWITCH("ADC US MUX7", WCD9360_CDC_TX7_TX_PATH_192_CTL, 0, - 0, &adc_us_mux7_switch), - SND_SOC_DAPM_SWITCH("ADC US MUX8", WCD9360_CDC_TX8_TX_PATH_192_CTL, 0, - 0, &adc_us_mux8_switch), - - /* MAD related widgets */ - SND_SOC_DAPM_INPUT("MAD_CPE_INPUT"), - SND_SOC_DAPM_INPUT("MADINPUT"), - - WCD_DAPM_MUX("MAD_SEL MUX", 0, mad_sel), - WCD_DAPM_MUX("MAD_INP MUX", 0, mad_inp_mux), - - SND_SOC_DAPM_SWITCH_E("MAD_BROADCAST", SND_SOC_NOPM, 0, 0, - &mad_brdcst_switch, pahu_codec_ape_enable_mad, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), - - SND_SOC_DAPM_SWITCH_E("MAD_CPE1", SND_SOC_NOPM, 0, 0, - &mad_cpe1_switch, pahu_codec_cpe_mad_ctl, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_SWITCH_E("MAD_CPE2", SND_SOC_NOPM, 0, 0, - &mad_cpe2_switch, pahu_codec_cpe_mad_ctl, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), - - SND_SOC_DAPM_OUTPUT("MAD_CPE_OUT1"), - SND_SOC_DAPM_OUTPUT("MAD_CPE_OUT2"), - - SND_SOC_DAPM_DAC_E("RX INT0 DAC", NULL, SND_SOC_NOPM, - 0, 0, pahu_codec_ear_dac_event, SND_SOC_DAPM_PRE_PMU), - - SND_SOC_DAPM_PGA_E("EAR PA", WCD9360_ANA_EAR, 7, 0, NULL, 0, - pahu_codec_enable_ear_pa, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("ANC EAR PA", WCD9360_ANA_EAR, 7, 0, NULL, 0, - pahu_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("ANC SPK1 PA", SND_SOC_NOPM, 0, 0, NULL, 0, - pahu_codec_enable_spkr_anc, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_OUTPUT("EAR"), - SND_SOC_DAPM_OUTPUT("SPK1 OUT"), - SND_SOC_DAPM_OUTPUT("SPK2 OUT"), - SND_SOC_DAPM_OUTPUT("ANC EAR"), - - SND_SOC_DAPM_SWITCH("ANC OUT EAR Enable", SND_SOC_NOPM, 0, 0, - &anc_ear_switch), - SND_SOC_DAPM_SWITCH("ANC OUT EAR SPKR Enable", SND_SOC_NOPM, 0, 0, - &anc_ear_spkr_switch), - SND_SOC_DAPM_SWITCH("ANC SPKR PA Enable", SND_SOC_NOPM, 0, 0, - &anc_spkr_pa_switch), - - SND_SOC_DAPM_DAC("RX INT9 DAC", NULL, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_PGA_E("AUX PA", WCD9360_AUX_ANA_EAR, 7, 0, NULL, 0, - pahu_codec_enable_aux_pa, SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_OUTPUT("AUX"), - - - SND_SOC_DAPM_SUPPLY("LDO_RXTX", SND_SOC_NOPM, 0, 0, - pahu_codec_enable_ldo_rxtx, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SUPPLY("RX INT7 NATIVE SUPPLY", SND_SOC_NOPM, - INTERP_SPKR1, 0, pahu_enable_native_supply, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_SUPPLY("RX INT8 NATIVE SUPPLY", SND_SOC_NOPM, - INTERP_SPKR2, 0, pahu_enable_native_supply, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), - - WCD_DAPM_MUX("RX INT7_2 NATIVE MUX", 0, int7_2_native), - WCD_DAPM_MUX("RX INT8_2 NATIVE MUX", 0, int8_2_native), - - SND_SOC_DAPM_MUX_E("ASRC2 MUX", SND_SOC_NOPM, ASRC2, 0, - &asrc2_mux, pahu_codec_enable_asrc_resampler, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("ASRC3 MUX", SND_SOC_NOPM, ASRC3, 0, - &asrc3_mux, pahu_codec_enable_asrc_resampler, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - /* WDMA3 widgets */ - WCD_DAPM_MUX("WDMA3 PORT0 MUX", 0, wdma3_port0), - WCD_DAPM_MUX("WDMA3 PORT1 MUX", 1, wdma3_port1), - WCD_DAPM_MUX("WDMA3 PORT2 MUX", 2, wdma3_port2), - WCD_DAPM_MUX("WDMA3 PORT3 MUX", 3, wdma3_port3), - WCD_DAPM_MUX("WDMA3 PORT4 MUX", 4, wdma3_port4), - WCD_DAPM_MUX("WDMA3 PORT5 MUX", 5, wdma3_port5), - WCD_DAPM_MUX("WDMA3 PORT6 MUX", 6, wdma3_port6), - - WCD_DAPM_MUX("WDMA3 CH0 MUX", 0, wdma3_ch0), - WCD_DAPM_MUX("WDMA3 CH1 MUX", 4, wdma3_ch1), - WCD_DAPM_MUX("WDMA3 CH2 MUX", 0, wdma3_ch2), - WCD_DAPM_MUX("WDMA3 CH3 MUX", 4, wdma3_ch3), - - SND_SOC_DAPM_MIXER("WDMA3_CH_MIXER", SND_SOC_NOPM, 0, 0, NULL, 0), - - SND_SOC_DAPM_SWITCH_E("WDMA3_ON_OFF", SND_SOC_NOPM, 0, 0, - &wdma3_onoff_switch, pahu_codec_wdma3_ctl, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_OUTPUT("WDMA3_OUT"), -}; - -static int pahu_get_channel_map(struct snd_soc_dai *dai, - unsigned int *tx_num, unsigned int *tx_slot, - unsigned int *rx_num, unsigned int *rx_slot) -{ - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(dai->codec); - u32 i = 0; - struct wcd9xxx_ch *ch; - int ret = 0; - - switch (dai->id) { - case AIF1_PB: - case AIF2_PB: - case AIF3_PB: - case AIF4_PB: - if (!rx_slot || !rx_num) { - dev_err(pahu->dev, "%s: Invalid rx_slot 0x%pK or rx_num 0x%pK\n", - __func__, rx_slot, rx_num); - ret = -EINVAL; - break; - } - list_for_each_entry(ch, &pahu->dai[dai->id].wcd9xxx_ch_list, - list) { - dev_dbg(pahu->dev, "%s: slot_num %u ch->ch_num %d\n", - __func__, i, ch->ch_num); - rx_slot[i++] = ch->ch_num; - } - *rx_num = i; - dev_dbg(pahu->dev, "%s: dai_name = %s dai_id = %x rx_num = %d\n", - __func__, dai->name, dai->id, i); - if (*rx_num == 0) { - dev_err(pahu->dev, "%s: Channel list empty for dai_name = %s dai_id = %x\n", - __func__, dai->name, dai->id); - ret = -EINVAL; - } - break; - case AIF1_CAP: - case AIF2_CAP: - case AIF3_CAP: - case AIF4_MAD_TX: - case AIF4_VIFEED: - if (!tx_slot || !tx_num) { - dev_err(pahu->dev, "%s: Invalid tx_slot 0x%pK or tx_num 0x%pK\n", - __func__, tx_slot, tx_num); - ret = -EINVAL; - break; - } - list_for_each_entry(ch, &pahu->dai[dai->id].wcd9xxx_ch_list, - list) { - dev_dbg(pahu->dev, "%s: slot_num %u ch->ch_num %d\n", - __func__, i, ch->ch_num); - tx_slot[i++] = ch->ch_num; - } - *tx_num = i; - dev_dbg(pahu->dev, "%s: dai_name = %s dai_id = %x tx_num = %d\n", - __func__, dai->name, dai->id, i); - if (*tx_num == 0) { - dev_err(pahu->dev, "%s: Channel list empty for dai_name = %s dai_id = %x\n", - __func__, dai->name, dai->id); - ret = -EINVAL; - } - break; - default: - dev_err(pahu->dev, "%s: Invalid DAI ID %x\n", - __func__, dai->id); - ret = -EINVAL; - break; - } - - return ret; -} - -static int pahu_set_channel_map(struct snd_soc_dai *dai, - unsigned int tx_num, unsigned int *tx_slot, - unsigned int rx_num, unsigned int *rx_slot) -{ - struct pahu_priv *pahu; - struct wcd9xxx *core; - struct wcd9xxx_codec_dai_data *dai_data = NULL; - - pahu = snd_soc_codec_get_drvdata(dai->codec); - core = dev_get_drvdata(dai->codec->dev->parent); - - if (!tx_slot || !rx_slot) { - dev_err(pahu->dev, "%s: Invalid tx_slot 0x%pK, rx_slot 0x%pK\n", - __func__, tx_slot, rx_slot); - return -EINVAL; - } - dev_dbg(pahu->dev, "%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n", - __func__, dai->name, dai->id, tx_num, rx_num); - - wcd9xxx_init_slimslave(core, core->slim->laddr, - tx_num, tx_slot, rx_num, rx_slot); - /* Reserve TX13 for MAD data channel */ - dai_data = &pahu->dai[AIF4_MAD_TX]; - if (dai_data) - list_add_tail(&core->tx_chs[WCD9360_TX13].list, - &dai_data->wcd9xxx_ch_list); - - return 0; -} - -static int pahu_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - pr_debug("%s(): substream = %s stream = %d\n", __func__, - substream->name, substream->stream); - - return 0; -} - -static void pahu_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - pr_debug("%s(): substream = %s stream = %d\n", __func__, - substream->name, substream->stream); -} - -static int pahu_set_decimator_rate(struct snd_soc_dai *dai, - u32 sample_rate) -{ - struct snd_soc_codec *codec = dai->codec; - struct wcd9xxx_ch *ch; - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - u32 tx_port = 0, tx_fs_rate = 0; - u8 shift = 0, shift_val = 0, tx_mux_sel = 0; - int decimator = -1; - u16 tx_port_reg = 0, tx_fs_reg = 0; - - switch (sample_rate) { - case 8000: - tx_fs_rate = 0; - break; - case 16000: - tx_fs_rate = 1; - break; - case 32000: - tx_fs_rate = 3; - break; - case 48000: - tx_fs_rate = 4; - break; - case 96000: - tx_fs_rate = 5; - break; - case 192000: - tx_fs_rate = 6; - break; - default: - dev_err(pahu->dev, "%s: Invalid TX sample rate: %d\n", - __func__, sample_rate); - return -EINVAL; - - }; - - list_for_each_entry(ch, &pahu->dai[dai->id].wcd9xxx_ch_list, list) { - tx_port = ch->port; - dev_dbg(codec->dev, "%s: dai->id = %d, tx_port = %d", - __func__, dai->id, tx_port); - - if ((tx_port < 0) || (tx_port == 12) || (tx_port >= 14)) { - dev_err(codec->dev, "%s: Invalid SLIM TX%u port. DAI ID: %d\n", - __func__, tx_port, dai->id); - return -EINVAL; - } - /* Find the SB TX MUX input - which decimator is connected */ - if (tx_port < 4) { - tx_port_reg = WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0; - shift = (tx_port << 1); - shift_val = 0x03; - } else if ((tx_port >= 4) && (tx_port < 8)) { - tx_port_reg = WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1; - shift = ((tx_port - 4) << 1); - shift_val = 0x03; - } else if ((tx_port >= 8) && (tx_port < 11)) { - tx_port_reg = WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2; - shift = ((tx_port - 8) << 1); - shift_val = 0x03; - } else if (tx_port == 11) { - tx_port_reg = WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3; - shift = 0; - shift_val = 0x0F; - } else if (tx_port == 13) { - tx_port_reg = WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3; - shift = 4; - shift_val = 0x03; - } - tx_mux_sel = snd_soc_read(codec, tx_port_reg) & - (shift_val << shift); - tx_mux_sel = tx_mux_sel >> shift; - - if (tx_port <= 8) { - if ((tx_mux_sel == 0x2) || (tx_mux_sel == 0x3)) - decimator = tx_port; - } else if (tx_port <= 10) { - if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2)) - decimator = ((tx_port == 9) ? 7 : 6); - } else if (tx_port == 11) { - if ((tx_mux_sel >= 1) && (tx_mux_sel < 7)) - decimator = tx_mux_sel - 1; - } else if (tx_port == 13) { - if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2)) - decimator = 5; - } - - if (decimator >= 0) { - tx_fs_reg = WCD9360_CDC_TX0_TX_PATH_CTL + - 16 * decimator; - dev_dbg(codec->dev, "%s: set DEC%u (-> SLIM_TX%u) rate to %u\n", - __func__, decimator, tx_port, sample_rate); - snd_soc_update_bits(codec, tx_fs_reg, 0x0F, tx_fs_rate); - } else if ((tx_port <= 8) && (tx_mux_sel == 0x01)) { - /* Check if the TX Mux input is RX MIX TXn */ - dev_dbg(codec->dev, "%s: RX_MIX_TX%u going to CDC_IF TX%u\n", - __func__, tx_port, tx_port); - } else { - dev_err(codec->dev, "%s: ERROR: Invalid decimator: %d\n", - __func__, decimator); - return -EINVAL; - } - } - return 0; -} - -static int pahu_set_mix_interpolator_rate(struct snd_soc_dai *dai, - u8 rate_reg_val, - u32 sample_rate) -{ - u8 int_2_inp; - u32 j; - u16 int_mux_cfg1, int_fs_reg; - u8 int_mux_cfg1_val; - struct snd_soc_codec *codec = dai->codec; - struct wcd9xxx_ch *ch; - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - list_for_each_entry(ch, &pahu->dai[dai->id].wcd9xxx_ch_list, list) { - int_2_inp = INTn_2_INP_SEL_RX0 + ch->port - - WCD9360_RX_PORT_START_NUMBER; - if ((int_2_inp < INTn_2_INP_SEL_RX0) || - (int_2_inp > INTn_2_INP_SEL_RX7)) { - dev_err(codec->dev, "%s: Invalid RX%u port, Dai ID is %d\n", - __func__, - (ch->port - WCD9360_RX_PORT_START_NUMBER), - dai->id); - return -EINVAL; - } - - for (j = 0; j < WCD9360_NUM_INTERPOLATORS; j++) { - if (j == INTERP_EAR) { - int_mux_cfg1 = - WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1; - int_fs_reg = WCD9360_CDC_RX0_RX_PATH_MIX_CTL; - } else if (j == INTERP_SPKR1) { - int_mux_cfg1 = - WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1; - int_fs_reg = WCD9360_CDC_RX7_RX_PATH_MIX_CTL; - } else if (j == INTERP_SPKR2) { - int_mux_cfg1 = - WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1; - int_fs_reg = WCD9360_CDC_RX8_RX_PATH_MIX_CTL; - } else if (j == INTERP_AUX) { - int_mux_cfg1 = - WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1; - int_fs_reg = WCD9360_CDC_RX9_RX_PATH_MIX_CTL; - } else { - continue; - } - - int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1) & - 0x0F; - if (int_mux_cfg1_val == int_2_inp) { - /* - * Ear mix path supports only 48, 96, 192, - * 384KHz only - */ - if ((j == INTERP_EAR || j == INTERP_AUX) && - (rate_reg_val < 0x4 || rate_reg_val > 0x7)) { - dev_err_ratelimited(codec->dev, - "%s: Invalid rate for AIF_PB DAI(%d)\n", - __func__, dai->id); - return -EINVAL; - } - - dev_dbg(codec->dev, "%s: AIF_PB DAI(%d) connected to INT%u_2\n", - __func__, dai->id, j); - dev_dbg(codec->dev, "%s: set INT%u_2 sample rate to %u\n", - __func__, j, sample_rate); - snd_soc_update_bits(codec, int_fs_reg, 0x0F, - rate_reg_val); - } - } - } - return 0; -} - -static int pahu_set_prim_interpolator_rate(struct snd_soc_dai *dai, - u8 rate_reg_val, - u32 sample_rate) -{ - u8 int_1_mix1_inp; - u32 j; - u16 int_mux_cfg0, int_mux_cfg1; - u16 int_fs_reg; - u8 int_mux_cfg0_val, int_mux_cfg1_val; - u8 inp0_sel, inp1_sel, inp2_sel; - struct snd_soc_codec *codec = dai->codec; - struct wcd9xxx_ch *ch; - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - list_for_each_entry(ch, &pahu->dai[dai->id].wcd9xxx_ch_list, list) { - int_1_mix1_inp = INTn_1_INP_SEL_RX0 + ch->port - - WCD9360_RX_PORT_START_NUMBER; - if ((int_1_mix1_inp < INTn_1_INP_SEL_RX0) || - (int_1_mix1_inp > INTn_1_INP_SEL_RX7)) { - dev_err(codec->dev, "%s: Invalid RX%u port, Dai ID is %d\n", - __func__, - (ch->port - WCD9360_RX_PORT_START_NUMBER), - dai->id); - return -EINVAL; - } - - /* - * Loop through all interpolator MUX inputs and find out - * to which interpolator input, the slim rx port - * is connected - */ - for (j = 0; j < WCD9360_NUM_INTERPOLATORS; j++) { - if (j == INTERP_EAR) { - int_mux_cfg0 = - WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0; - int_fs_reg = WCD9360_CDC_RX0_RX_PATH_CTL; - } else if (j == INTERP_SPKR1) { - int_mux_cfg0 = - WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0; - int_fs_reg = WCD9360_CDC_RX7_RX_PATH_CTL; - } else if (j == INTERP_SPKR2) { - int_mux_cfg0 = - WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0; - int_fs_reg = WCD9360_CDC_RX8_RX_PATH_CTL; - } else if (j == INTERP_AUX) { - int_mux_cfg0 = - WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0; - int_fs_reg = WCD9360_CDC_RX9_RX_PATH_CTL; - } else { - continue; - } - int_mux_cfg1 = int_mux_cfg0 + 1; - - int_mux_cfg0_val = snd_soc_read(codec, int_mux_cfg0); - int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1); - inp0_sel = int_mux_cfg0_val & 0x0F; - inp1_sel = (int_mux_cfg0_val >> 4) & 0x0F; - inp2_sel = (int_mux_cfg1_val >> 4) & 0x0F; - if ((inp0_sel == int_1_mix1_inp) || - (inp1_sel == int_1_mix1_inp) || - (inp2_sel == int_1_mix1_inp)) { - /* - * Primary path does not support - * native sample rates - */ - if (rate_reg_val > 0x7) { - dev_err_ratelimited(codec->dev, - "%s: Invalid rate for AIF_PB DAI(%d)\n", - __func__, dai->id); - return -EINVAL; - } - dev_dbg(codec->dev, - "%s: AIF_PB DAI(%d) connected to INT%u_1\n", - __func__, dai->id, j); - dev_dbg(codec->dev, - "%s: set INT%u_1 sample rate to %u\n", - __func__, j, sample_rate); - snd_soc_update_bits(codec, int_fs_reg, 0x0F, - rate_reg_val); - } - int_mux_cfg0 += 2; - } - } - - return 0; -} - - -static int pahu_set_interpolator_rate(struct snd_soc_dai *dai, - u32 sample_rate) -{ - struct snd_soc_codec *codec = dai->codec; - int rate_val = 0; - int i, ret; - - for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) { - if (sample_rate == sr_val_tbl[i].sample_rate) { - rate_val = sr_val_tbl[i].rate_val; - break; - } - } - if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) { - dev_err(codec->dev, "%s: Unsupported sample rate: %d\n", - __func__, sample_rate); - return -EINVAL; - } - - ret = pahu_set_prim_interpolator_rate(dai, (u8)rate_val, sample_rate); - if (ret) - return ret; - ret = pahu_set_mix_interpolator_rate(dai, (u8)rate_val, sample_rate); - if (ret) - return ret; - - return ret; -} - -static int pahu_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - pr_debug("%s(): substream = %s stream = %d\n", __func__, - substream->name, substream->stream); - return 0; -} - -static int pahu_vi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(dai->codec); - - dev_dbg(pahu->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", - __func__, dai->name, dai->id, params_rate(params), - params_channels(params)); - - pahu->dai[dai->id].rate = params_rate(params); - pahu->dai[dai->id].bit_width = 32; - - return 0; -} - -static int pahu_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(dai->codec); - int ret = 0; - - dev_dbg(pahu->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", - __func__, dai->name, dai->id, params_rate(params), - params_channels(params)); - - switch (substream->stream) { - case SNDRV_PCM_STREAM_PLAYBACK: - ret = pahu_set_interpolator_rate(dai, params_rate(params)); - if (ret) { - dev_err(pahu->dev, "%s: cannot set sample rate: %u\n", - __func__, params_rate(params)); - return ret; - } - switch (params_width(params)) { - case 16: - pahu->dai[dai->id].bit_width = 16; - break; - case 24: - pahu->dai[dai->id].bit_width = 24; - break; - case 32: - pahu->dai[dai->id].bit_width = 32; - break; - default: - return -EINVAL; - } - pahu->dai[dai->id].rate = params_rate(params); - break; - case SNDRV_PCM_STREAM_CAPTURE: - if (dai->id != AIF4_MAD_TX) - ret = pahu_set_decimator_rate(dai, - params_rate(params)); - if (ret) { - dev_err(pahu->dev, "%s: cannot set TX Decimator rate: %d\n", - __func__, ret); - return ret; - } - switch (params_width(params)) { - case 16: - pahu->dai[dai->id].bit_width = 16; - break; - case 24: - pahu->dai[dai->id].bit_width = 24; - break; - default: - dev_err(pahu->dev, "%s: Invalid format 0x%x\n", - __func__, params_width(params)); - return -EINVAL; - }; - pahu->dai[dai->id].rate = params_rate(params); - break; - default: - dev_err(pahu->dev, "%s: Invalid stream type %d\n", __func__, - substream->stream); - return -EINVAL; - }; - - return 0; -} - -static int pahu_i2s_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(dai->codec); - - dev_dbg(dai->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", - __func__, dai->name, dai->id, params_rate(params), - params_channels(params)); - - pahu->dai[dai->id].rate = params_rate(params); - pahu->dai[dai->id].bit_width = params_width(params); - - return 0; -} - -static struct snd_soc_dai_ops pahu_dai_ops = { - .startup = pahu_startup, - .shutdown = pahu_shutdown, - .hw_params = pahu_hw_params, - .prepare = pahu_prepare, - .set_channel_map = pahu_set_channel_map, - .get_channel_map = pahu_get_channel_map, -}; - -static struct snd_soc_dai_ops pahu_vi_dai_ops = { - .hw_params = pahu_vi_hw_params, - .set_channel_map = pahu_set_channel_map, - .get_channel_map = pahu_get_channel_map, -}; - -static struct snd_soc_dai_ops pahu_i2s_dai_ops = { - .hw_params = pahu_i2s_hw_params, -}; - -static struct snd_soc_dai_driver pahu_dai[] = { - { - .name = "pahu_rx1", - .id = AIF1_PB, - .playback = { - .stream_name = "AIF1 Playback", - .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK, - .formats = WCD9360_FORMATS_S16_S24_S32_LE, - .rate_min = 8000, - .rate_max = 384000, - .channels_min = 1, - .channels_max = 2, - }, - .ops = &pahu_dai_ops, - }, - { - .name = "pahu_tx1", - .id = AIF1_CAP, - .capture = { - .stream_name = "AIF1 Capture", - .rates = WCD9360_RATES_MASK, - .formats = WCD9360_FORMATS_S16_S24_LE, - .rate_min = 8000, - .rate_max = 192000, - .channels_min = 1, - .channels_max = 8, - }, - .ops = &pahu_dai_ops, - }, - { - .name = "pahu_rx2", - .id = AIF2_PB, - .playback = { - .stream_name = "AIF2 Playback", - .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK, - .formats = WCD9360_FORMATS_S16_S24_S32_LE, - .rate_min = 8000, - .rate_max = 384000, - .channels_min = 1, - .channels_max = 2, - }, - .ops = &pahu_dai_ops, - }, - { - .name = "pahu_tx2", - .id = AIF2_CAP, - .capture = { - .stream_name = "AIF2 Capture", - .rates = WCD9360_RATES_MASK, - .formats = WCD9360_FORMATS_S16_S24_LE, - .rate_min = 8000, - .rate_max = 192000, - .channels_min = 1, - .channels_max = 8, - }, - .ops = &pahu_dai_ops, - }, - { - .name = "pahu_rx3", - .id = AIF3_PB, - .playback = { - .stream_name = "AIF3 Playback", - .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK, - .formats = WCD9360_FORMATS_S16_S24_S32_LE, - .rate_min = 8000, - .rate_max = 384000, - .channels_min = 1, - .channels_max = 2, - }, - .ops = &pahu_dai_ops, - }, - { - .name = "pahu_tx3", - .id = AIF3_CAP, - .capture = { - .stream_name = "AIF3 Capture", - .rates = WCD9360_RATES_MASK, - .formats = WCD9360_FORMATS_S16_S24_LE, - .rate_min = 8000, - .rate_max = 192000, - .channels_min = 1, - .channels_max = 8, - }, - .ops = &pahu_dai_ops, - }, - { - .name = "pahu_rx4", - .id = AIF4_PB, - .playback = { - .stream_name = "AIF4 Playback", - .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK, - .formats = WCD9360_FORMATS_S16_S24_S32_LE, - .rate_min = 8000, - .rate_max = 384000, - .channels_min = 1, - .channels_max = 2, - }, - .ops = &pahu_dai_ops, - }, - { - .name = "pahu_vifeedback", - .id = AIF4_VIFEED, - .capture = { - .stream_name = "VIfeed", - .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, - .formats = WCD9360_FORMATS_S16_S24_S32_LE, - .rate_min = 8000, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 4, - }, - .ops = &pahu_vi_dai_ops, - }, - { - .name = "pahu_mad1", - .id = AIF4_MAD_TX, - .capture = { - .stream_name = "AIF4 MAD TX", - .rates = SNDRV_PCM_RATE_16000, - .formats = WCD9360_FORMATS_S16_LE, - .rate_min = 16000, - .rate_max = 16000, - .channels_min = 1, - .channels_max = 1, - }, - .ops = &pahu_dai_ops, - }, - { - .name = "pahu_i2s1_rx", - .id = I2S1_PB, - .playback = { - .stream_name = "I2S1 Playback", - .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK, - .formats = WCD9360_FORMATS_S16_S24_S32_LE, - .rate_min = 8000, - .rate_max = 384000, - .channels_min = 1, - .channels_max = 2, - }, - .ops = &pahu_i2s_dai_ops, - }, - { - .name = "pahu_i2s1_tx", - .id = I2S1_CAP, - .capture = { - .stream_name = "I2S1 Capture", - .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK, - .formats = WCD9360_FORMATS_S16_S24_S32_LE, - .rate_min = 8000, - .rate_max = 192000, - .channels_min = 1, - .channels_max = 2, - }, - .ops = &pahu_i2s_dai_ops, - }, -}; - -static void pahu_codec_power_gate_digital_core(struct pahu_priv *pahu) -{ - mutex_lock(&pahu->power_lock); - dev_dbg(pahu->dev, "%s: Entering power gating function, %d\n", - __func__, pahu->power_active_ref); - - if (pahu->power_active_ref > 0) - goto exit; - - wcd9xxx_set_power_state(pahu->wcd9xxx, - WCD_REGION_POWER_COLLAPSE_BEGIN, - WCD9XXX_DIG_CORE_REGION_1); - regmap_update_bits(pahu->wcd9xxx->regmap, - WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x04, 0x04); - regmap_update_bits(pahu->wcd9xxx->regmap, - WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x01, 0x00); - regmap_update_bits(pahu->wcd9xxx->regmap, - WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x02, 0x00); - wcd9xxx_set_power_state(pahu->wcd9xxx, WCD_REGION_POWER_DOWN, - WCD9XXX_DIG_CORE_REGION_1); -exit: - dev_dbg(pahu->dev, "%s: Exiting power gating function, %d\n", - __func__, pahu->power_active_ref); - mutex_unlock(&pahu->power_lock); -} - -static void pahu_codec_power_gate_work(struct work_struct *work) -{ - struct pahu_priv *pahu; - struct delayed_work *dwork; - - dwork = to_delayed_work(work); - pahu = container_of(dwork, struct pahu_priv, power_gate_work); - - pahu_codec_power_gate_digital_core(pahu); -} - -/* called under power_lock acquisition */ -static int pahu_dig_core_remove_power_collapse(struct pahu_priv *pahu) -{ - regmap_write(pahu->wcd9xxx->regmap, - WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x05); - regmap_write(pahu->wcd9xxx->regmap, - WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x07); - regmap_update_bits(pahu->wcd9xxx->regmap, - WCD9360_CODEC_RPM_RST_CTL, 0x02, 0x00); - regmap_update_bits(pahu->wcd9xxx->regmap, - WCD9360_CODEC_RPM_RST_CTL, 0x02, 0x02); - regmap_write(pahu->wcd9xxx->regmap, - WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x03); - - wcd9xxx_set_power_state(pahu->wcd9xxx, - WCD_REGION_POWER_COLLAPSE_REMOVE, - WCD9XXX_DIG_CORE_REGION_1); - regcache_mark_dirty(pahu->wcd9xxx->regmap); - regcache_sync_region(pahu->wcd9xxx->regmap, - WCD9360_DIG_CORE_REG_MIN, - WCD9360_DIG_CORE_REG_MAX); - return 0; -} - -static int pahu_dig_core_power_collapse(struct pahu_priv *pahu, - int req_state) -{ - int cur_state; - - /* Exit if feature is disabled */ - if (!dig_core_collapse_enable) - return 0; - - mutex_lock(&pahu->power_lock); - if (req_state == POWER_COLLAPSE) - pahu->power_active_ref--; - else if (req_state == POWER_RESUME) - pahu->power_active_ref++; - else - goto unlock_mutex; - - if (pahu->power_active_ref < 0) { - dev_dbg(pahu->dev, "%s: power_active_ref is negative\n", - __func__); - goto unlock_mutex; - } - - if (req_state == POWER_COLLAPSE) { - if (pahu->power_active_ref == 0) { - schedule_delayed_work(&pahu->power_gate_work, - msecs_to_jiffies(dig_core_collapse_timer * 1000)); - } - } else if (req_state == POWER_RESUME) { - if (pahu->power_active_ref == 1) { - /* - * At this point, there can be two cases: - * 1. Core already in power collapse state - * 2. Timer kicked in and still did not expire or - * waiting for the power_lock - */ - cur_state = wcd9xxx_get_current_power_state( - pahu->wcd9xxx, - WCD9XXX_DIG_CORE_REGION_1); - if (cur_state == WCD_REGION_POWER_DOWN) { - pahu_dig_core_remove_power_collapse(pahu); - } else { - mutex_unlock(&pahu->power_lock); - cancel_delayed_work_sync( - &pahu->power_gate_work); - mutex_lock(&pahu->power_lock); - } - } - } - -unlock_mutex: - mutex_unlock(&pahu->power_lock); - - return 0; -} - -static int pahu_cdc_req_mclk_enable(struct pahu_priv *pahu, - bool enable) -{ - int ret = 0; - - if (enable) { - ret = clk_prepare_enable(pahu->wcd_ext_clk); - if (ret) { - dev_err(pahu->dev, "%s: ext clk enable failed\n", - __func__); - goto done; - } - /* get BG */ - wcd_resmgr_enable_master_bias(pahu->resmgr); - /* get MCLK */ - wcd_resmgr_enable_clk_block(pahu->resmgr, WCD_CLK_MCLK); - } else { - /* put MCLK */ - wcd_resmgr_disable_clk_block(pahu->resmgr, WCD_CLK_MCLK); - /* put BG */ - wcd_resmgr_disable_master_bias(pahu->resmgr); - clk_disable_unprepare(pahu->wcd_ext_clk); - } - -done: - return ret; -} - -static int __pahu_cdc_mclk_enable_locked(struct pahu_priv *pahu, - bool enable) -{ - int ret = 0; - - if (!pahu->wcd_ext_clk) { - dev_err(pahu->dev, "%s: wcd ext clock is NULL\n", __func__); - return -EINVAL; - } - - dev_dbg(pahu->dev, "%s: mclk_enable = %u\n", __func__, enable); - - if (enable) { - pahu_dig_core_power_collapse(pahu, POWER_RESUME); - pahu_vote_svs(pahu, true); - ret = pahu_cdc_req_mclk_enable(pahu, true); - if (ret) - goto done; - } else { - pahu_cdc_req_mclk_enable(pahu, false); - pahu_vote_svs(pahu, false); - pahu_dig_core_power_collapse(pahu, POWER_COLLAPSE); - } - -done: - return ret; -} - -static int __pahu_cdc_mclk_enable(struct pahu_priv *pahu, - bool enable) -{ - int ret; - - WCD9XXX_V2_BG_CLK_LOCK(pahu->resmgr); - ret = __pahu_cdc_mclk_enable_locked(pahu, enable); - if (enable) - wcd_resmgr_set_sido_input_src(pahu->resmgr, - SIDO_SOURCE_RCO_BG); - WCD9XXX_V2_BG_CLK_UNLOCK(pahu->resmgr); - - return ret; -} - -static ssize_t pahu_codec_version_read(struct snd_info_entry *entry, - void *file_private_data, - struct file *file, - char __user *buf, size_t count, - loff_t pos) -{ - struct pahu_priv *pahu; - struct wcd9xxx *wcd9xxx; - char buffer[PAHU_VERSION_ENTRY_SIZE]; - int len = 0; - - pahu = (struct pahu_priv *) entry->private_data; - if (!pahu) { - pr_err("%s: pahu priv is null\n", __func__); - return -EINVAL; - } - - wcd9xxx = pahu->wcd9xxx; - - switch (wcd9xxx->version) { - case PAHU_VERSION_1_0: - len = snprintf(buffer, sizeof(buffer), "WCD9360_1_0\n"); - break; - default: - len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); - } - - return simple_read_from_buffer(buf, count, &pos, buffer, len); -} - -static struct snd_info_entry_ops pahu_codec_info_ops = { - .read = pahu_codec_version_read, -}; - -/* - * pahu_codec_info_create_codec_entry - creates wcd9360 module - * @codec_root: The parent directory - * @codec: Codec instance - * - * Creates wcd9360 module and version entry under the given - * parent directory. - * - * Return: 0 on success or negative error code on failure. - */ -int pahu_codec_info_create_codec_entry(struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) -{ - struct snd_info_entry *version_entry; - struct pahu_priv *pahu; - struct snd_soc_card *card; - - if (!codec_root || !codec) - return -EINVAL; - - pahu = snd_soc_codec_get_drvdata(codec); - card = codec->component.card; - pahu->entry = snd_info_create_subdir(codec_root->module, - "pahu", codec_root); - if (!pahu->entry) { - dev_dbg(codec->dev, "%s: failed to create wcd9360 entry\n", - __func__); - return -ENOMEM; - } - - version_entry = snd_info_create_card_entry(card->snd_card, - "version", - pahu->entry); - if (!version_entry) { - dev_dbg(codec->dev, "%s: failed to create wcd9360 version entry\n", - __func__); - return -ENOMEM; - } - - version_entry->private_data = pahu; - version_entry->size = PAHU_VERSION_ENTRY_SIZE; - version_entry->content = SNDRV_INFO_CONTENT_DATA; - version_entry->c.ops = &pahu_codec_info_ops; - - if (snd_info_register(version_entry) < 0) { - snd_info_free_entry(version_entry); - return -ENOMEM; - } - pahu->version_entry = version_entry; - - return 0; -} -EXPORT_SYMBOL(pahu_codec_info_create_codec_entry); - -/** - * pahu_cdc_mclk_enable - Enable/disable codec mclk - * - * @codec: codec instance - * @enable: Indicates clk enable or disable - * - * Returns 0 on Success and error on failure - */ -int pahu_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable) -{ - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - return __pahu_cdc_mclk_enable(pahu, enable); -} -EXPORT_SYMBOL(pahu_cdc_mclk_enable); - -static int __pahu_codec_internal_rco_ctrl(struct snd_soc_codec *codec, - bool enable) -{ - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - int ret = 0; - - if (enable) { - if (wcd_resmgr_get_clk_type(pahu->resmgr) == - WCD_CLK_RCO) { - ret = wcd_resmgr_enable_clk_block(pahu->resmgr, - WCD_CLK_RCO); - } else { - ret = pahu_cdc_req_mclk_enable(pahu, true); - if (ret) { - dev_err(codec->dev, - "%s: mclk_enable failed, err = %d\n", - __func__, ret); - goto done; - } - wcd_resmgr_set_sido_input_src(pahu->resmgr, - SIDO_SOURCE_RCO_BG); - ret = wcd_resmgr_enable_clk_block(pahu->resmgr, - WCD_CLK_RCO); - ret |= pahu_cdc_req_mclk_enable(pahu, false); - } - - } else { - ret = wcd_resmgr_disable_clk_block(pahu->resmgr, - WCD_CLK_RCO); - } - - if (ret) { - dev_err(codec->dev, "%s: Error in %s RCO\n", - __func__, (enable ? "enabling" : "disabling")); - ret = -EINVAL; - } - -done: - return ret; -} - -/* - * pahu_codec_internal_rco_ctrl: Enable/Disable codec's RCO clock - * @codec: Handle to the codec - * @enable: Indicates whether clock should be enabled or disabled - */ -static int pahu_codec_internal_rco_ctrl(struct snd_soc_codec *codec, - bool enable) -{ - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - int ret = 0; - - WCD9XXX_V2_BG_CLK_LOCK(pahu->resmgr); - ret = __pahu_codec_internal_rco_ctrl(codec, enable); - WCD9XXX_V2_BG_CLK_UNLOCK(pahu->resmgr); - return ret; -} - -/* - * pahu_cdc_mclk_tx_enable: Enable/Disable codec's clock for TX path - * @codec: Handle to codec - * @enable: Indicates whether clock should be enabled or disabled - */ -int pahu_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable) -{ - struct pahu_priv *pahu_p; - int ret = 0; - bool clk_mode; - bool clk_internal; - - if (!codec) - return -EINVAL; - - pahu_p = snd_soc_codec_get_drvdata(codec); - clk_mode = test_bit(CLK_MODE, &pahu_p->status_mask); - clk_internal = test_bit(CLK_INTERNAL, &pahu_p->status_mask); - - dev_dbg(codec->dev, "%s: clkmode: %d, enable: %d, clk_internal: %d\n", - __func__, clk_mode, enable, clk_internal); - - if (clk_mode || clk_internal) { - if (enable) { - wcd_resmgr_enable_master_bias(pahu_p->resmgr); - pahu_dig_core_power_collapse(pahu_p, POWER_RESUME); - pahu_vote_svs(pahu_p, true); - ret = pahu_codec_internal_rco_ctrl(codec, enable); - set_bit(CLK_INTERNAL, &pahu_p->status_mask); - } else { - clear_bit(CLK_INTERNAL, &pahu_p->status_mask); - pahu_codec_internal_rco_ctrl(codec, enable); - pahu_vote_svs(pahu_p, false); - pahu_dig_core_power_collapse(pahu_p, POWER_COLLAPSE); - wcd_resmgr_disable_master_bias(pahu_p->resmgr); - } - } else { - ret = __pahu_cdc_mclk_enable(pahu_p, enable); - } - - return ret; -} -EXPORT_SYMBOL(pahu_cdc_mclk_tx_enable); - -static const struct wcd_resmgr_cb pahu_resmgr_cb = { - .cdc_rco_ctrl = __pahu_codec_internal_rco_ctrl, -}; - -static const struct pahu_reg_mask_val pahu_codec_mclk2_1_0_defaults[] = { - /* - * PLL Settings: - * Clock Root: MCLK2, - * Clock Source: EXT_CLK, - * Clock Destination: MCLK2 - * Clock Freq In: 19.2MHz, - * Clock Freq Out: 11.2896MHz - */ - {WCD9360_CLK_SYS_MCLK2_PRG1, 0x60, 0x20}, - {WCD9360_CLK_SYS_INT_POST_DIV_REG0, 0xFF, 0x5E}, - {WCD9360_CLK_SYS_INT_POST_DIV_REG1, 0x1F, 0x1F}, - {WCD9360_CLK_SYS_INT_REF_DIV_REG0, 0xFF, 0x54}, - {WCD9360_CLK_SYS_INT_REF_DIV_REG1, 0xFF, 0x01}, - {WCD9360_CLK_SYS_INT_FILTER_REG1, 0x07, 0x04}, - {WCD9360_CLK_SYS_INT_PLL_L_VAL, 0xFF, 0x93}, - {WCD9360_CLK_SYS_INT_PLL_N_VAL, 0xFF, 0xFA}, - {WCD9360_CLK_SYS_INT_TEST_REG0, 0xFF, 0x90}, - {WCD9360_CLK_SYS_INT_PFD_CP_DSM_PROG, 0xFF, 0x7E}, - {WCD9360_CLK_SYS_INT_VCO_PROG, 0xFF, 0xF8}, - {WCD9360_CLK_SYS_INT_TEST_REG1, 0xFF, 0x68}, - {WCD9360_CLK_SYS_INT_LDO_LOCK_CFG, 0xFF, 0x40}, - {WCD9360_CLK_SYS_INT_DIG_LOCK_DET_CFG, 0xFF, 0x32}, -}; - -static const struct pahu_reg_mask_val pahu_codec_reg_defaults[] = { - {WCD9360_BIAS_VBG_FINE_ADJ, 0xFF, 0x75}, - {WCD9360_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x01}, - {WCD9360_CODEC_CPR_SVS_CX_VDD, 0xFF, 0x7C}, /* value in svs mode */ - {WCD9360_CODEC_CPR_SVS2_CX_VDD, 0xFF, 0x58}, /* value in svs2 mode */ - {WCD9360_CDC_RX0_RX_PATH_DSMDEM_CTL, 0x01, 0x01}, - {WCD9360_CDC_RX7_RX_PATH_DSMDEM_CTL, 0x01, 0x01}, - {WCD9360_CDC_RX8_RX_PATH_DSMDEM_CTL, 0x01, 0x01}, - {WCD9360_CDC_RX9_RX_PATH_DSMDEM_CTL, 0x01, 0x01}, - {WCD9360_CDC_COMPANDER8_CTL7, 0x1E, 0x18}, - {WCD9360_CDC_COMPANDER7_CTL7, 0x1E, 0x18}, - {WCD9360_CDC_RX0_RX_PATH_SEC0, 0x08, 0x00}, - {WCD9360_CDC_RX9_RX_PATH_SEC0, 0x08, 0x00}, - {WCD9360_MICB1_TEST_CTL_2, 0x07, 0x01}, - {WCD9360_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12}, - {WCD9360_CDC_BOOST0_BOOST_CFG2, 0x1C, 0x08}, - {WCD9360_CDC_BOOST1_BOOST_CFG1, 0x3F, 0x12}, - {WCD9360_CDC_BOOST1_BOOST_CFG2, 0x1C, 0x08}, - {WCD9360_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD, 0x1F, 0x09}, - {WCD9360_CDC_TX0_TX_PATH_CFG1, 0x01, 0x00}, - {WCD9360_CDC_TX1_TX_PATH_CFG1, 0x01, 0x00}, - {WCD9360_CDC_TX2_TX_PATH_CFG1, 0x01, 0x00}, - {WCD9360_CDC_TX3_TX_PATH_CFG1, 0x01, 0x00}, - {WCD9360_CDC_TX4_TX_PATH_CFG1, 0x01, 0x00}, - {WCD9360_CDC_TX5_TX_PATH_CFG1, 0x01, 0x00}, - {WCD9360_CDC_TX6_TX_PATH_CFG1, 0x01, 0x00}, - {WCD9360_CDC_TX7_TX_PATH_CFG1, 0x01, 0x00}, - {WCD9360_CDC_TX8_TX_PATH_CFG1, 0x01, 0x00}, - {WCD9360_CPE_FLL_CONFIG_CTL_2, 0xFF, 0x20}, - {WCD9360_CPE_SS_DMIC_CFG, 0x80, 0x00}, - {WCD9360_CDC_BOOST0_BOOST_CTL, 0x70, 0x50}, - {WCD9360_CDC_BOOST1_BOOST_CTL, 0x70, 0x50}, - {WCD9360_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08}, - {WCD9360_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08}, - {WCD9360_CDC_TOP_TOP_CFG1, 0x02, 0x02}, - {WCD9360_CDC_TOP_TOP_CFG1, 0x01, 0x01}, - {WCD9360_CDC_TOP_EAR_COMP_LUT, 0x80, 0x80}, - {WCD9360_EAR_EAR_DAC_CON, 0x06, 0x02}, - {WCD9360_AUX_INT_AUX_DAC_CON, 0x06, 0x02}, - {WCD9360_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, - {WCD9360_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, - {WCD9360_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, - {WCD9360_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, - {WCD9360_DATA_HUB_SB_TX11_INP_CFG, 0x01, 0x01}, - {WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x01}, - {WCD9360_CDC_COMPANDER7_CTL3, 0x80, 0x80}, - {WCD9360_CDC_COMPANDER8_CTL3, 0x80, 0x80}, - {WCD9360_CDC_COMPANDER7_CTL7, 0x01, 0x01}, - {WCD9360_CDC_COMPANDER8_CTL7, 0x01, 0x01}, - {WCD9360_CODEC_RPM_CLK_GATE, 0x08, 0x00}, - {WCD9360_CPE_SS_SVA_CFG, 0x60, 0x00}, - {WCD9360_CPE_SS_CPAR_CFG, 0x10, 0x10}, -}; - -static const struct pahu_cpr_reg_defaults cpr_defaults[] = { - { 0x00000820, 0x00000094 }, - { 0x00000fC0, 0x00000048 }, - { 0x0000f000, 0x00000044 }, - { 0x0000bb80, 0xC0000178 }, - { 0x00000000, 0x00000160 }, - { 0x10854522, 0x00000060 }, - { 0x10854509, 0x00000064 }, - { 0x108544dd, 0x00000068 }, - { 0x108544ad, 0x0000006C }, - { 0x0000077E, 0x00000070 }, - { 0x000007da, 0x00000074 }, - { 0x00000000, 0x00000078 }, - { 0x00000000, 0x0000007C }, - { 0x00042029, 0x00000080 }, - { 0x4002002A, 0x00000090 }, - { 0x4002002B, 0x00000090 }, -}; - -static void pahu_update_reg_defaults(struct pahu_priv *pahu) -{ - u32 i; - struct wcd9xxx *wcd9xxx; - - wcd9xxx = pahu->wcd9xxx; - for (i = 0; i < ARRAY_SIZE(pahu_codec_reg_defaults); i++) - regmap_update_bits(wcd9xxx->regmap, - pahu_codec_reg_defaults[i].reg, - pahu_codec_reg_defaults[i].mask, - pahu_codec_reg_defaults[i].val); -} - -static void pahu_update_cpr_defaults(struct pahu_priv *pahu) -{ - int i; - struct wcd9xxx *wcd9xxx; - - wcd9xxx = pahu->wcd9xxx; - - __pahu_cdc_mclk_enable(pahu, true); - - regmap_update_bits(wcd9xxx->regmap, WCD9360_CODEC_RPM_CLK_GATE, - 0x10, 0x00); - - for (i = 0; i < ARRAY_SIZE(cpr_defaults); i++) { - regmap_bulk_write(wcd9xxx->regmap, - WCD9360_CODEC_CPR_WR_DATA_0, - (u8 *)&cpr_defaults[i].wr_data, 4); - regmap_bulk_write(wcd9xxx->regmap, - WCD9360_CODEC_CPR_WR_ADDR_0, - (u8 *)&cpr_defaults[i].wr_addr, 4); - } - - __pahu_cdc_mclk_enable(pahu, false); -} - -static void pahu_slim_interface_init_reg(struct snd_soc_codec *codec) -{ - int i; - struct pahu_priv *priv = snd_soc_codec_get_drvdata(codec); - - for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++) - wcd9xxx_interface_reg_write(priv->wcd9xxx, - WCD9360_SLIM_PGD_PORT_INT_RX_EN0 + i, - 0xFF); -} - -static irqreturn_t pahu_misc_irq(int irq, void *data) -{ - struct pahu_priv *pahu = data; - int misc_val; - - /* Find source of interrupt */ - regmap_read(pahu->wcd9xxx->regmap, WCD9360_INTR_CODEC_MISC_STATUS, - &misc_val); - - dev_dbg(pahu->dev, "%s: Codec misc irq: %d, val: 0x%x\n", - __func__, irq, misc_val); - - /* Clear interrupt status */ - regmap_update_bits(pahu->wcd9xxx->regmap, - WCD9360_INTR_CODEC_MISC_CLEAR, misc_val, 0x00); - - return IRQ_HANDLED; -} - -static irqreturn_t pahu_slimbus_irq(int irq, void *data) -{ - struct pahu_priv *pahu = data; - unsigned long status = 0; - int i, j, port_id, k; - u32 bit; - u8 val, int_val = 0; - bool tx, cleared; - unsigned short reg = 0; - - for (i = WCD9360_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0; - i <= WCD9360_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) { - val = wcd9xxx_interface_reg_read(pahu->wcd9xxx, i); - status |= ((u32)val << (8 * j)); - } - - for_each_set_bit(j, &status, 32) { - tx = (j >= 16 ? true : false); - port_id = (tx ? j - 16 : j); - val = wcd9xxx_interface_reg_read(pahu->wcd9xxx, - WCD9360_SLIM_PGD_PORT_INT_RX_SOURCE0 + j); - if (val) { - if (!tx) - reg = WCD9360_SLIM_PGD_PORT_INT_RX_EN0 + - (port_id / 8); - else - reg = WCD9360_SLIM_PGD_PORT_INT_TX_EN0 + - (port_id / 8); - int_val = wcd9xxx_interface_reg_read( - pahu->wcd9xxx, reg); - /* - * Ignore interrupts for ports for which the - * interrupts are not specifically enabled. - */ - if (!(int_val & (1 << (port_id % 8)))) - continue; - } - if (val & WCD9360_SLIM_IRQ_OVERFLOW) - dev_err_ratelimited(pahu->dev, "%s: overflow error on %s port %d, value %x\n", - __func__, (tx ? "TX" : "RX"), port_id, val); - if (val & WCD9360_SLIM_IRQ_UNDERFLOW) - dev_err_ratelimited(pahu->dev, "%s: underflow error on %s port %d, value %x\n", - __func__, (tx ? "TX" : "RX"), port_id, val); - if ((val & WCD9360_SLIM_IRQ_OVERFLOW) || - (val & WCD9360_SLIM_IRQ_UNDERFLOW)) { - if (!tx) - reg = WCD9360_SLIM_PGD_PORT_INT_RX_EN0 + - (port_id / 8); - else - reg = WCD9360_SLIM_PGD_PORT_INT_TX_EN0 + - (port_id / 8); - int_val = wcd9xxx_interface_reg_read( - pahu->wcd9xxx, reg); - if (int_val & (1 << (port_id % 8))) { - int_val = int_val ^ (1 << (port_id % 8)); - wcd9xxx_interface_reg_write(pahu->wcd9xxx, - reg, int_val); - } - } - if (val & WCD9360_SLIM_IRQ_PORT_CLOSED) { - /* - * INT SOURCE register starts from RX to TX - * but port number in the ch_mask is in opposite way - */ - bit = (tx ? j - 16 : j + 16); - dev_dbg(pahu->dev, "%s: %s port %d closed value %x, bit %u\n", - __func__, (tx ? "TX" : "RX"), port_id, val, - bit); - for (k = 0, cleared = false; k < NUM_CODEC_DAIS; k++) { - dev_dbg(pahu->dev, "%s: pahu->dai[%d].ch_mask = 0x%lx\n", - __func__, k, pahu->dai[k].ch_mask); - if (test_and_clear_bit(bit, - &pahu->dai[k].ch_mask)) { - cleared = true; - if (!pahu->dai[k].ch_mask) - wake_up( - &pahu->dai[k].dai_wait); - /* - * There are cases when multiple DAIs - * might be using the same slimbus - * channel. Hence don't break here. - */ - } - } - } - wcd9xxx_interface_reg_write(pahu->wcd9xxx, - WCD9360_SLIM_PGD_PORT_INT_CLR_RX_0 + - (j / 8), - 1 << (j % 8)); - } - - return IRQ_HANDLED; -} - -static int pahu_setup_irqs(struct pahu_priv *pahu) -{ - int ret = 0; - struct snd_soc_codec *codec = pahu->codec; - struct wcd9xxx *wcd9xxx = pahu->wcd9xxx; - struct wcd9xxx_core_resource *core_res = - &wcd9xxx->core_res; - - ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_SLIMBUS, - pahu_slimbus_irq, "SLIMBUS Slave", pahu); - if (ret) - dev_err(codec->dev, "%s: Failed to request irq %d\n", __func__, - WCD9XXX_IRQ_SLIMBUS); - else - pahu_slim_interface_init_reg(codec); - - /* Register for misc interrupts as well */ - ret = wcd9xxx_request_irq(core_res, WCD9360_IRQ_MISC, - pahu_misc_irq, "CDC MISC Irq", pahu); - if (ret) - dev_err(codec->dev, "%s: Failed to request cdc misc irq\n", - __func__); - - return ret; -} - -static void pahu_init_slim_slave_cfg(struct snd_soc_codec *codec) -{ - struct pahu_priv *priv = snd_soc_codec_get_drvdata(codec); - struct afe_param_cdc_slimbus_slave_cfg *cfg; - struct wcd9xxx *wcd9xxx = priv->wcd9xxx; - uint64_t eaddr = 0; - - cfg = &priv->slimbus_slave_cfg; - cfg->minor_version = 1; - cfg->tx_slave_port_offset = 0; - cfg->rx_slave_port_offset = 16; - - memcpy(&eaddr, &wcd9xxx->slim->e_addr, sizeof(wcd9xxx->slim->e_addr)); - WARN_ON(sizeof(wcd9xxx->slim->e_addr) != 6); - cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF; - cfg->device_enum_addr_msw = eaddr >> 32; - - dev_dbg(codec->dev, "%s: slimbus logical address 0x%llx\n", - __func__, eaddr); -} - -static void pahu_cleanup_irqs(struct pahu_priv *pahu) -{ - struct wcd9xxx *wcd9xxx = pahu->wcd9xxx; - struct wcd9xxx_core_resource *core_res = - &wcd9xxx->core_res; - - wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_SLIMBUS, pahu); - wcd9xxx_free_irq(core_res, WCD9360_IRQ_MISC, pahu); -} - -/* - * wcd9360_get_micb_vout_ctl_val: converts micbias from volts to register value - * @micb_mv: micbias in mv - * - * return register value converted - */ -int wcd9360_get_micb_vout_ctl_val(u32 micb_mv) -{ - /* min micbias voltage is 1V and maximum is 2.85V */ - if (micb_mv < 1000 || micb_mv > 2850) { - pr_err("%s: unsupported micbias voltage\n", __func__); - return -EINVAL; - } - - return (micb_mv - 1000) / 50; -} -EXPORT_SYMBOL(wcd9360_get_micb_vout_ctl_val); - -static int pahu_handle_pdata(struct pahu_priv *pahu, - struct wcd9xxx_pdata *pdata) -{ - struct snd_soc_codec *codec = pahu->codec; - u8 mad_dmic_ctl_val; - u8 anc_ctl_value; - u32 dmic_clk_drv; - int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4; - int rc = 0; - - if (!pdata) { - dev_err(codec->dev, "%s: NULL pdata\n", __func__); - return -ENODEV; - } - - /* set micbias voltage */ - vout_ctl_1 = wcd9360_get_micb_vout_ctl_val(pdata->micbias.micb1_mv); - vout_ctl_2 = wcd9360_get_micb_vout_ctl_val(pdata->micbias.micb2_mv); - vout_ctl_3 = wcd9360_get_micb_vout_ctl_val(pdata->micbias.micb3_mv); - vout_ctl_4 = wcd9360_get_micb_vout_ctl_val(pdata->micbias.micb4_mv); - if (vout_ctl_1 < 0 || vout_ctl_2 < 0 || - vout_ctl_3 < 0 || vout_ctl_4 < 0) { - rc = -EINVAL; - goto done; - } - snd_soc_update_bits(codec, WCD9360_ANA_MICB1, 0x3F, vout_ctl_1); - snd_soc_update_bits(codec, WCD9360_ANA_MICB2, 0x3F, vout_ctl_2); - snd_soc_update_bits(codec, WCD9360_ANA_MICB3, 0x3F, vout_ctl_3); - snd_soc_update_bits(codec, WCD9360_ANA_MICB4, 0x3F, vout_ctl_4); - - if (pdata->dmic_sample_rate == - WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) { - dev_info(codec->dev, "%s: dmic_rate invalid default = %d\n", - __func__, WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ); - pdata->dmic_sample_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ; - } - if (pdata->mad_dmic_sample_rate == - WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) { - dev_info(codec->dev, "%s: mad_dmic_rate invalid default = %d\n", - __func__, WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ); - /* - * use dmic_sample_rate as the default for MAD - * if mad dmic sample rate is undefined - */ - pdata->mad_dmic_sample_rate = pdata->dmic_sample_rate; - } - - if (pdata->dmic_clk_drv == - WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED) { - pdata->dmic_clk_drv = WCD9360_DMIC_CLK_DRIVE_DEFAULT; - dev_dbg(codec->dev, - "%s: dmic_clk_strength invalid, default = %d\n", - __func__, pdata->dmic_clk_drv); - } - - switch (pdata->dmic_clk_drv) { - case 2: - dmic_clk_drv = 0; - break; - case 4: - dmic_clk_drv = 1; - break; - case 8: - dmic_clk_drv = 2; - break; - case 16: - dmic_clk_drv = 3; - break; - default: - dev_err(codec->dev, - "%s: invalid dmic_clk_drv %d, using default\n", - __func__, pdata->dmic_clk_drv); - dmic_clk_drv = 0; - break; - } - - snd_soc_update_bits(codec, WCD9360_TEST_DEBUG_PAD_DRVCTL_0, - 0x0C, dmic_clk_drv << 2); - - /* - * Default the DMIC clk rates to mad_dmic_sample_rate, - * whereas, the anc/txfe dmic rates to dmic_sample_rate - * since the anc/txfe are independent of mad block. - */ - mad_dmic_ctl_val = pahu_get_dmic_clk_val(pahu->codec, - pdata->mad_dmic_sample_rate); - snd_soc_update_bits(codec, WCD9360_CPE_SS_DMIC0_CTL, - 0x0E, mad_dmic_ctl_val << 1); - snd_soc_update_bits(codec, WCD9360_CPE_SS_DMIC1_CTL, - 0x0E, mad_dmic_ctl_val << 1); - snd_soc_update_bits(codec, WCD9360_CPE_SS_DMIC2_CTL, - 0x0E, mad_dmic_ctl_val << 1); - - if (dmic_clk_drv == WCD9360_DMIC_CLK_DIV_2) - anc_ctl_value = WCD9360_ANC_DMIC_X2_FULL_RATE; - else - anc_ctl_value = WCD9360_ANC_DMIC_X2_HALF_RATE; - - snd_soc_update_bits(codec, WCD9360_CDC_ANC0_MODE_2_CTL, - 0x40, anc_ctl_value << 6); - snd_soc_update_bits(codec, WCD9360_CDC_ANC0_MODE_2_CTL, - 0x20, anc_ctl_value << 5); - -done: - return rc; -} - -static void pahu_cdc_vote_svs(struct snd_soc_codec *codec, bool vote) -{ - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - return pahu_vote_svs(pahu, vote); -} - -static struct wcd_dsp_cdc_cb cdc_cb = { - .cdc_clk_en = pahu_codec_internal_rco_ctrl, - .cdc_vote_svs = pahu_cdc_vote_svs, -}; - -static int pahu_wdsp_initialize(struct snd_soc_codec *codec) -{ - struct wcd9xxx *control; - struct pahu_priv *pahu; - struct wcd_dsp_params params; - int ret = 0; - - control = dev_get_drvdata(codec->dev->parent); - pahu = snd_soc_codec_get_drvdata(codec); - - params.cb = &cdc_cb; - params.irqs.cpe_ipc1_irq = WCD9360_IRQ_CPE1_INTR; - params.irqs.cpe_err_irq = WCD9360_IRQ_CPE_ERROR; - params.irqs.fatal_irqs = CPE_FATAL_IRQS; - params.clk_rate = control->mclk_rate; - params.dsp_instance = 0; - - wcd9360_dsp_cntl_init(codec, ¶ms, &pahu->wdsp_cntl); - if (!pahu->wdsp_cntl) { - dev_err(pahu->dev, "%s: wcd-dsp-control init failed\n", - __func__); - ret = -EINVAL; - } - - return ret; -} - -static void pahu_mclk2_reg_defaults(struct pahu_priv *pahu) -{ - int i; - struct snd_soc_codec *codec = pahu->codec; - - /* MCLK2 configuration */ - for (i = 0; i < ARRAY_SIZE(pahu_codec_mclk2_1_0_defaults); i++) - snd_soc_update_bits(codec, - pahu_codec_mclk2_1_0_defaults[i].reg, - pahu_codec_mclk2_1_0_defaults[i].mask, - pahu_codec_mclk2_1_0_defaults[i].val); -} - -static int pahu_device_down(struct wcd9xxx *wcd9xxx) -{ - struct snd_soc_codec *codec; - struct pahu_priv *priv; - int count; - - codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); - priv = snd_soc_codec_get_drvdata(codec); - if (priv->swr.ctrl_data) - swrm_wcd_notify(priv->swr.ctrl_data[0].swr_pdev, - SWR_DEVICE_DOWN, NULL); - snd_soc_card_change_online_state(codec->component.card, 0); - for (count = 0; count < NUM_CODEC_DAIS; count++) - priv->dai[count].bus_down_in_recovery = true; - wcd9360_dsp_ssr_event(priv->wdsp_cntl, WCD_CDC_DOWN_EVENT); - wcd_resmgr_set_sido_input_src_locked(priv->resmgr, - SIDO_SOURCE_INTERNAL); - - return 0; -} - -static int pahu_post_reset_cb(struct wcd9xxx *wcd9xxx) -{ - int i, ret = 0; - struct wcd9xxx *control; - struct snd_soc_codec *codec; - struct pahu_priv *pahu; - struct wcd9xxx_pdata *pdata; - - codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); - pahu = snd_soc_codec_get_drvdata(codec); - control = dev_get_drvdata(codec->dev->parent); - - wcd9xxx_set_power_state(pahu->wcd9xxx, - WCD_REGION_POWER_COLLAPSE_REMOVE, - WCD9XXX_DIG_CORE_REGION_1); - - mutex_lock(&pahu->codec_mutex); - - pahu_vote_svs(pahu, true); - pahu_slimbus_slave_port_cfg.slave_dev_intfdev_la = - control->slim_slave->laddr; - pahu_slimbus_slave_port_cfg.slave_dev_pgd_la = - control->slim->laddr; - pahu_init_slim_slave_cfg(codec); - snd_soc_card_change_online_state(codec->component.card, 1); - - for (i = 0; i < PAHU_MAX_MICBIAS; i++) - pahu->micb_ref[i] = 0; - - dev_dbg(codec->dev, "%s: MCLK Rate = %x\n", - __func__, control->mclk_rate); - - pahu_update_reg_defaults(pahu); - wcd_resmgr_post_ssr_v2(pahu->resmgr); - __pahu_enable_efuse_sensing(pahu); - pahu_mclk2_reg_defaults(pahu); - - __pahu_cdc_mclk_enable(pahu, true); - regcache_mark_dirty(codec->component.regmap); - regcache_sync(codec->component.regmap); - __pahu_cdc_mclk_enable(pahu, false); - - pahu_update_cpr_defaults(pahu); - - pdata = dev_get_platdata(codec->dev->parent); - ret = pahu_handle_pdata(pahu, pdata); - if (ret < 0) - dev_err(codec->dev, "%s: invalid pdata\n", __func__); - - pahu_cleanup_irqs(pahu); - ret = pahu_setup_irqs(pahu); - if (ret) { - dev_err(codec->dev, "%s: pahu irq setup failed %d\n", - __func__, ret); - goto done; - } - - pahu_set_spkr_mode(codec, pahu->swr.spkr_mode); - /* - * Once the codec initialization is completed, the svs vote - * can be released allowing the codec to go to SVS2. - */ - pahu_vote_svs(pahu, false); - wcd9360_dsp_ssr_event(pahu->wdsp_cntl, WCD_CDC_UP_EVENT); - -done: - mutex_unlock(&pahu->codec_mutex); - return ret; -} - -static int pahu_soc_codec_probe(struct snd_soc_codec *codec) -{ - struct wcd9xxx *control; - struct pahu_priv *pahu; - struct wcd9xxx_pdata *pdata; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - int i, ret; - void *ptr = NULL; - - control = dev_get_drvdata(codec->dev->parent); - - dev_info(codec->dev, "%s()\n", __func__); - pahu = snd_soc_codec_get_drvdata(codec); - pahu->intf_type = wcd9xxx_get_intf_type(); - - control->dev_down = pahu_device_down; - control->post_reset = pahu_post_reset_cb; - control->ssr_priv = (void *)codec; - - /* Resource Manager post Init */ - ret = wcd_resmgr_post_init(pahu->resmgr, &pahu_resmgr_cb, codec); - if (ret) { - dev_err(codec->dev, "%s: wcd resmgr post init failed\n", - __func__); - goto err; - } - - pahu->fw_data = devm_kzalloc(codec->dev, sizeof(*(pahu->fw_data)), - GFP_KERNEL); - if (!pahu->fw_data) - goto err; - - set_bit(WCD9XXX_ANC_CAL, pahu->fw_data->cal_bit); - set_bit(WCD9XXX_MAD_CAL, pahu->fw_data->cal_bit); - - ret = wcd_cal_create_hwdep(pahu->fw_data, - WCD9XXX_CODEC_HWDEP_NODE, codec); - if (ret < 0) { - dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret); - goto err_hwdep; - } - - pahu->codec = codec; - for (i = 0; i < COMPANDER_MAX; i++) - pahu->comp_enabled[i] = 0; - - pdata = dev_get_platdata(codec->dev->parent); - ret = pahu_handle_pdata(pahu, pdata); - if (ret < 0) { - dev_err(codec->dev, "%s: bad pdata\n", __func__); - goto err_hwdep; - } - - ptr = devm_kzalloc(codec->dev, (sizeof(pahu_rx_chs) + - sizeof(pahu_tx_chs)), GFP_KERNEL); - if (!ptr) { - ret = -ENOMEM; - goto err_hwdep; - } - - snd_soc_dapm_add_routes(dapm, pahu_slim_audio_map, - ARRAY_SIZE(pahu_slim_audio_map)); - for (i = 0; i < NUM_CODEC_DAIS; i++) { - INIT_LIST_HEAD(&pahu->dai[i].wcd9xxx_ch_list); - init_waitqueue_head(&pahu->dai[i].dai_wait); - } - pahu_slimbus_slave_port_cfg.slave_dev_intfdev_la = - control->slim_slave->laddr; - pahu_slimbus_slave_port_cfg.slave_dev_pgd_la = - control->slim->laddr; - pahu_slimbus_slave_port_cfg.slave_port_mapping[0] = - WCD9360_TX13; - pahu_init_slim_slave_cfg(codec); - - control->num_rx_port = WCD9360_RX_MAX; - control->rx_chs = ptr; - memcpy(control->rx_chs, pahu_rx_chs, sizeof(pahu_rx_chs)); - control->num_tx_port = WCD9360_TX_MAX; - control->tx_chs = ptr + sizeof(pahu_rx_chs); - memcpy(control->tx_chs, pahu_tx_chs, sizeof(pahu_tx_chs)); - - ret = pahu_setup_irqs(pahu); - if (ret) { - dev_err(pahu->dev, "%s: pahu irq setup failed %d\n", - __func__, ret); - goto err_pdata; - } - - for (i = 0; i < WCD9360_NUM_DECIMATORS; i++) { - pahu->tx_hpf_work[i].pahu = pahu; - pahu->tx_hpf_work[i].decimator = i; - INIT_DELAYED_WORK(&pahu->tx_hpf_work[i].dwork, - pahu_tx_hpf_corner_freq_callback); - - pahu->tx_mute_dwork[i].pahu = pahu; - pahu->tx_mute_dwork[i].decimator = i; - INIT_DELAYED_WORK(&pahu->tx_mute_dwork[i].dwork, - pahu_tx_mute_update_callback); - } - - pahu->spk_anc_dwork.pahu = pahu; - INIT_DELAYED_WORK(&pahu->spk_anc_dwork.dwork, - pahu_spk_anc_update_callback); - - pahu_mclk2_reg_defaults(pahu); - - mutex_lock(&pahu->codec_mutex); - snd_soc_dapm_disable_pin(dapm, "ANC EAR PA"); - snd_soc_dapm_disable_pin(dapm, "ANC EAR"); - snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA"); - mutex_unlock(&pahu->codec_mutex); - - snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback"); - snd_soc_dapm_ignore_suspend(dapm, "AIF1 Capture"); - snd_soc_dapm_ignore_suspend(dapm, "AIF2 Playback"); - snd_soc_dapm_ignore_suspend(dapm, "AIF2 Capture"); - snd_soc_dapm_ignore_suspend(dapm, "AIF3 Playback"); - snd_soc_dapm_ignore_suspend(dapm, "AIF3 Capture"); - snd_soc_dapm_ignore_suspend(dapm, "AIF4 Playback"); - snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX"); - snd_soc_dapm_ignore_suspend(dapm, "VIfeed"); - snd_soc_dapm_ignore_suspend(dapm, "I2S1 Playback"); - snd_soc_dapm_ignore_suspend(dapm, "I2S1 Capture"); - - snd_soc_dapm_sync(dapm); - - pahu_wdsp_initialize(codec); - - /* - * Once the codec initialization is completed, the svs vote - * can be released allowing the codec to go to SVS2. - */ - pahu_vote_svs(pahu, false); - - return ret; - -err_pdata: - devm_kfree(codec->dev, ptr); - control->rx_chs = NULL; - control->tx_chs = NULL; -err_hwdep: - devm_kfree(codec->dev, pahu->fw_data); - pahu->fw_data = NULL; -err: - return ret; -} - -static int pahu_soc_codec_remove(struct snd_soc_codec *codec) -{ - struct wcd9xxx *control; - struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec); - - control = dev_get_drvdata(codec->dev->parent); - devm_kfree(codec->dev, control->rx_chs); - /* slimslave deinit in wcd core looks for this value */ - control->num_rx_port = 0; - control->num_tx_port = 0; - control->rx_chs = NULL; - control->tx_chs = NULL; - pahu_cleanup_irqs(pahu); - - if (pahu->wdsp_cntl) - wcd9360_dsp_cntl_deinit(&pahu->wdsp_cntl); - - return 0; -} - -static struct regmap *pahu_get_regmap(struct device *dev) -{ - struct wcd9xxx *control = dev_get_drvdata(dev->parent); - - return control->regmap; -} - -static struct snd_soc_codec_driver soc_codec_dev_pahu = { - .probe = pahu_soc_codec_probe, - .remove = pahu_soc_codec_remove, - .get_regmap = pahu_get_regmap, - .component_driver = { - .controls = pahu_snd_controls, - .num_controls = ARRAY_SIZE(pahu_snd_controls), - .dapm_widgets = pahu_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(pahu_dapm_widgets), - .dapm_routes = pahu_audio_map, - .num_dapm_routes = ARRAY_SIZE(pahu_audio_map), - }, -}; - -#ifdef CONFIG_PM -static int pahu_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct pahu_priv *pahu = platform_get_drvdata(pdev); - - if (!pahu) { - dev_err(dev, "%s: pahu private data is NULL\n", __func__); - return -EINVAL; - } - dev_dbg(dev, "%s: system suspend\n", __func__); - if (delayed_work_pending(&pahu->power_gate_work) && - cancel_delayed_work_sync(&pahu->power_gate_work)) - pahu_codec_power_gate_digital_core(pahu); - return 0; -} - -static int pahu_resume(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct pahu_priv *pahu = platform_get_drvdata(pdev); - - if (!pahu) { - dev_err(dev, "%s: pahu private data is NULL\n", __func__); - return -EINVAL; - } - dev_dbg(dev, "%s: system resume\n", __func__); - return 0; -} - -static const struct dev_pm_ops pahu_pm_ops = { - .suspend = pahu_suspend, - .resume = pahu_resume, -}; -#endif - -static int pahu_swrm_read(void *handle, int reg) -{ - struct pahu_priv *pahu; - struct wcd9xxx *wcd9xxx; - unsigned short swr_rd_addr_base; - unsigned short swr_rd_data_base; - int val, ret; - - if (!handle) { - pr_err("%s: NULL handle\n", __func__); - return -EINVAL; - } - pahu = (struct pahu_priv *)handle; - wcd9xxx = pahu->wcd9xxx; - - dev_dbg(pahu->dev, "%s: Reading soundwire register, 0x%x\n", - __func__, reg); - swr_rd_addr_base = WCD9360_SWR_AHB_BRIDGE_RD_ADDR_0; - swr_rd_data_base = WCD9360_SWR_AHB_BRIDGE_RD_DATA_0; - - mutex_lock(&pahu->swr.read_mutex); - ret = regmap_bulk_write(wcd9xxx->regmap, swr_rd_addr_base, - (u8 *)®, 4); - if (ret < 0) { - dev_err(pahu->dev, "%s: RD Addr Failure\n", __func__); - goto done; - } - ret = regmap_bulk_read(wcd9xxx->regmap, swr_rd_data_base, - (u8 *)&val, 4); - if (ret < 0) { - dev_err(pahu->dev, "%s: RD Data Failure\n", __func__); - goto done; - } - ret = val; -done: - mutex_unlock(&pahu->swr.read_mutex); - - return ret; -} - -static int pahu_swrm_bulk_write(void *handle, u32 *reg, u32 *val, size_t len) -{ - struct pahu_priv *pahu; - struct wcd9xxx *wcd9xxx; - struct wcd9xxx_reg_val *bulk_reg; - unsigned short swr_wr_addr_base; - unsigned short swr_wr_data_base; - int i, j, ret; - - if (!handle || !reg || !val) { - pr_err("%s: NULL parameter\n", __func__); - return -EINVAL; - } - if (len <= 0) { - pr_err("%s: Invalid size: %zu\n", __func__, len); - return -EINVAL; - } - pahu = (struct pahu_priv *)handle; - wcd9xxx = pahu->wcd9xxx; - - swr_wr_addr_base = WCD9360_SWR_AHB_BRIDGE_WR_ADDR_0; - swr_wr_data_base = WCD9360_SWR_AHB_BRIDGE_WR_DATA_0; - - bulk_reg = kzalloc((2 * len * sizeof(struct wcd9xxx_reg_val)), - GFP_KERNEL); - if (!bulk_reg) - return -ENOMEM; - - for (i = 0, j = 0; i < (len * 2); i += 2, j++) { - bulk_reg[i].reg = swr_wr_data_base; - bulk_reg[i].buf = (u8 *)(&val[j]); - bulk_reg[i].bytes = 4; - bulk_reg[i+1].reg = swr_wr_addr_base; - bulk_reg[i+1].buf = (u8 *)(®[j]); - bulk_reg[i+1].bytes = 4; - } - - mutex_lock(&pahu->swr.write_mutex); - ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, - (len * 2), false); - if (ret) { - dev_err(pahu->dev, "%s: swrm bulk write failed, ret: %d\n", - __func__, ret); - } - mutex_unlock(&pahu->swr.write_mutex); - - kfree(bulk_reg); - return ret; -} - -static int pahu_swrm_write(void *handle, int reg, int val) -{ - struct pahu_priv *pahu; - struct wcd9xxx *wcd9xxx; - unsigned short swr_wr_addr_base; - unsigned short swr_wr_data_base; - struct wcd9xxx_reg_val bulk_reg[2]; - int ret; - - if (!handle) { - pr_err("%s: NULL handle\n", __func__); - return -EINVAL; - } - pahu = (struct pahu_priv *)handle; - wcd9xxx = pahu->wcd9xxx; - - swr_wr_addr_base = WCD9360_SWR_AHB_BRIDGE_WR_ADDR_0; - swr_wr_data_base = WCD9360_SWR_AHB_BRIDGE_WR_DATA_0; - - /* First Write the Data to register */ - bulk_reg[0].reg = swr_wr_data_base; - bulk_reg[0].buf = (u8 *)(&val); - bulk_reg[0].bytes = 4; - bulk_reg[1].reg = swr_wr_addr_base; - bulk_reg[1].buf = (u8 *)(®); - bulk_reg[1].bytes = 4; - - mutex_lock(&pahu->swr.write_mutex); - ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, 2, false); - if (ret < 0) - dev_err(pahu->dev, "%s: WR Data Failure\n", __func__); - mutex_unlock(&pahu->swr.write_mutex); - - return ret; -} - -static int pahu_swrm_clock(void *handle, bool enable) -{ - struct pahu_priv *pahu; - - if (!handle) { - pr_err("%s: NULL handle\n", __func__); - return -EINVAL; - } - pahu = (struct pahu_priv *)handle; - - mutex_lock(&pahu->swr.clk_mutex); - dev_dbg(pahu->dev, "%s: swrm clock %s\n", - __func__, (enable?"enable" : "disable")); - if (enable) { - pahu->swr.clk_users++; - if (pahu->swr.clk_users == 1) { - regmap_update_bits(pahu->wcd9xxx->regmap, - WCD9360_TEST_DEBUG_NPL_DLY_TEST_1, - 0x10, 0x00); - __pahu_cdc_mclk_enable(pahu, true); - regmap_update_bits(pahu->wcd9xxx->regmap, - WCD9360_CDC_CLK_RST_CTRL_SWR_CONTROL, - 0x01, 0x01); - } - } else { - pahu->swr.clk_users--; - if (pahu->swr.clk_users == 0) { - regmap_update_bits(pahu->wcd9xxx->regmap, - WCD9360_CDC_CLK_RST_CTRL_SWR_CONTROL, - 0x01, 0x00); - __pahu_cdc_mclk_enable(pahu, false); - regmap_update_bits(pahu->wcd9xxx->regmap, - WCD9360_TEST_DEBUG_NPL_DLY_TEST_1, - 0x10, 0x10); - } - } - dev_dbg(pahu->dev, "%s: swrm clock users %d\n", - __func__, pahu->swr.clk_users); - mutex_unlock(&pahu->swr.clk_mutex); - - return 0; -} - -static int pahu_swrm_handle_irq(void *handle, - irqreturn_t (*swrm_irq_handler)(int irq, - void *data), - void *swrm_handle, - int action) -{ - struct pahu_priv *pahu; - int ret = 0; - struct wcd9xxx *wcd9xxx; - - if (!handle) { - pr_err("%s: NULL handle\n", __func__); - return -EINVAL; - } - pahu = (struct pahu_priv *) handle; - wcd9xxx = pahu->wcd9xxx; - - if (action) { - ret = wcd9xxx_request_irq(&wcd9xxx->core_res, - WCD9360_IRQ_SOUNDWIRE, - swrm_irq_handler, - "Pahu SWR Master", swrm_handle); - if (ret) - dev_err(pahu->dev, "%s: Failed to request irq %d\n", - __func__, WCD9360_IRQ_SOUNDWIRE); - } else - wcd9xxx_free_irq(&wcd9xxx->core_res, WCD9360_IRQ_SOUNDWIRE, - swrm_handle); - - return ret; -} - -static void pahu_codec_add_spi_device(struct pahu_priv *pahu, - struct device_node *node) -{ - struct spi_master *master; - struct spi_device *spi; - u32 prop_value; - int rc; - - /* Read the master bus num from DT node */ - rc = of_property_read_u32(node, "qcom,master-bus-num", - &prop_value); - if (rc < 0) { - dev_err(pahu->dev, "%s: prop %s not found in node %s", - __func__, "qcom,master-bus-num", node->full_name); - goto done; - } - - /* Get the reference to SPI master */ - master = spi_busnum_to_master(prop_value); - if (!master) { - dev_err(pahu->dev, "%s: Invalid spi_master for bus_num %u\n", - __func__, prop_value); - goto done; - } - - /* Allocate the spi device */ - spi = spi_alloc_device(master); - if (!spi) { - dev_err(pahu->dev, "%s: spi_alloc_device failed\n", - __func__); - goto err_spi_alloc_dev; - } - - /* Initialize device properties */ - if (of_modalias_node(node, spi->modalias, - sizeof(spi->modalias)) < 0) { - dev_err(pahu->dev, "%s: cannot find modalias for %s\n", - __func__, node->full_name); - goto err_dt_parse; - } - - rc = of_property_read_u32(node, "qcom,chip-select", - &prop_value); - if (rc < 0) { - dev_err(pahu->dev, "%s: prop %s not found in node %s", - __func__, "qcom,chip-select", node->full_name); - goto err_dt_parse; - } - spi->chip_select = prop_value; - - rc = of_property_read_u32(node, "qcom,max-frequency", - &prop_value); - if (rc < 0) { - dev_err(pahu->dev, "%s: prop %s not found in node %s", - __func__, "qcom,max-frequency", node->full_name); - goto err_dt_parse; - } - spi->max_speed_hz = prop_value; - - spi->dev.of_node = node; - - rc = spi_add_device(spi); - if (rc < 0) { - dev_err(pahu->dev, "%s: spi_add_device failed\n", __func__); - goto err_dt_parse; - } - - pahu->spi = spi; - /* Put the reference to SPI master */ - put_device(&master->dev); - - return; - -err_dt_parse: - spi_dev_put(spi); - -err_spi_alloc_dev: - /* Put the reference to SPI master */ - put_device(&master->dev); -done: - return; -} - -static void pahu_add_child_devices(struct work_struct *work) -{ - struct pahu_priv *pahu; - struct platform_device *pdev; - struct device_node *node; - struct wcd9xxx *wcd9xxx; - struct pahu_swr_ctrl_data *swr_ctrl_data = NULL, *temp; - int ret, ctrl_num = 0; - struct wcd_swr_ctrl_platform_data *platdata; - char plat_dev_name[WCD9360_STRING_LEN]; - - pahu = container_of(work, struct pahu_priv, - pahu_add_child_devices_work); - if (!pahu) { - pr_err("%s: Memory for wcd9360 does not exist\n", - __func__); - return; - } - wcd9xxx = pahu->wcd9xxx; - if (!wcd9xxx) { - pr_err("%s: Memory for WCD9XXX does not exist\n", - __func__); - return; - } - if (!wcd9xxx->dev->of_node) { - dev_err(wcd9xxx->dev, "%s: DT node for wcd9xxx does not exist\n", - __func__); - return; - } - - platdata = &pahu->swr.plat_data; - pahu->child_count = 0; - - for_each_child_of_node(wcd9xxx->dev->of_node, node) { - - /* Parse and add the SPI device node */ - if (!strcmp(node->name, "wcd_spi")) { - pahu_codec_add_spi_device(pahu, node); - continue; - } - - /* Parse other child device nodes and add platform device */ - if (!strcmp(node->name, "swr_master")) - strlcpy(plat_dev_name, "pahu_swr_ctrl", - (WCD9360_STRING_LEN - 1)); - else if (strnstr(node->name, "msm_cdc_pinctrl", - strlen("msm_cdc_pinctrl")) != NULL) - strlcpy(plat_dev_name, node->name, - (WCD9360_STRING_LEN - 1)); - else - continue; - - pdev = platform_device_alloc(plat_dev_name, -1); - if (!pdev) { - dev_err(wcd9xxx->dev, "%s: pdev memory alloc failed\n", - __func__); - ret = -ENOMEM; - goto err_mem; - } - pdev->dev.parent = pahu->dev; - pdev->dev.of_node = node; - - if (strcmp(node->name, "swr_master") == 0) { - ret = platform_device_add_data(pdev, platdata, - sizeof(*platdata)); - if (ret) { - dev_err(&pdev->dev, - "%s: cannot add plat data ctrl:%d\n", - __func__, ctrl_num); - goto err_pdev_add; - } - } - - ret = platform_device_add(pdev); - if (ret) { - dev_err(&pdev->dev, - "%s: Cannot add platform device\n", - __func__); - goto err_pdev_add; - } - - if (strcmp(node->name, "swr_master") == 0) { - temp = krealloc(swr_ctrl_data, - (ctrl_num + 1) * sizeof( - struct pahu_swr_ctrl_data), - GFP_KERNEL); - if (!temp) { - dev_err(wcd9xxx->dev, "out of memory\n"); - ret = -ENOMEM; - goto err_pdev_add; - } - swr_ctrl_data = temp; - swr_ctrl_data[ctrl_num].swr_pdev = pdev; - ctrl_num++; - dev_dbg(&pdev->dev, - "%s: Added soundwire ctrl device(s)\n", - __func__); - pahu->swr.ctrl_data = swr_ctrl_data; - } - if (pahu->child_count < WCD9360_CHILD_DEVICES_MAX) - pahu->pdev_child_devices[pahu->child_count++] = pdev; - else - goto err_mem; - } - - return; - -err_pdev_add: - platform_device_put(pdev); -err_mem: - return; -} - -static int __pahu_enable_efuse_sensing(struct pahu_priv *pahu) -{ - int val, rc; - - WCD9XXX_V2_BG_CLK_LOCK(pahu->resmgr); - __pahu_cdc_mclk_enable_locked(pahu, true); - - regmap_update_bits(pahu->wcd9xxx->regmap, - WCD9360_CHIP_TIER_CTRL_EFUSE_CTL, 0x1E, 0x10); - regmap_update_bits(pahu->wcd9xxx->regmap, - WCD9360_CHIP_TIER_CTRL_EFUSE_CTL, 0x01, 0x01); - /* - * 5ms sleep required after enabling efuse control - * before checking the status. - */ - usleep_range(5000, 5500); - wcd_resmgr_set_sido_input_src(pahu->resmgr, - SIDO_SOURCE_RCO_BG); - - WCD9XXX_V2_BG_CLK_UNLOCK(pahu->resmgr); - - rc = regmap_read(pahu->wcd9xxx->regmap, - WCD9360_CHIP_TIER_CTRL_EFUSE_STATUS, &val); - if (rc || (!(val & 0x01))) - WARN(1, "%s: Efuse sense is not complete val=%x, ret=%d\n", - __func__, val, rc); - - __pahu_cdc_mclk_enable(pahu, false); - - return rc; -} - -/* - * pahu_get_wcd_dsp_cntl: Get the reference to wcd_dsp_cntl - * @dev: Device pointer for codec device - * - * This API gets the reference to codec's struct wcd_dsp_cntl - */ -void *pahu_get_wcd_dsp_cntl(struct device *dev) -{ - struct platform_device *pdev; - struct pahu_priv *pahu; - - if (!dev) { - pr_err("%s: Invalid device\n", __func__); - return NULL; - } - - pdev = to_platform_device(dev); - pahu = platform_get_drvdata(pdev); - - return pahu->wdsp_cntl; -} -EXPORT_SYMBOL(pahu_get_wcd_dsp_cntl); - -static int pahu_probe(struct platform_device *pdev) -{ - int ret = 0; - struct pahu_priv *pahu; - struct clk *wcd_ext_clk; - struct wcd9xxx_resmgr_v2 *resmgr; - struct wcd9xxx_power_region *cdc_pwr; - - pahu = devm_kzalloc(&pdev->dev, sizeof(struct pahu_priv), - GFP_KERNEL); - if (!pahu) - return -ENOMEM; - - platform_set_drvdata(pdev, pahu); - - pahu->wcd9xxx = dev_get_drvdata(pdev->dev.parent); - pahu->dev = &pdev->dev; - INIT_DELAYED_WORK(&pahu->power_gate_work, pahu_codec_power_gate_work); - mutex_init(&pahu->power_lock); - INIT_WORK(&pahu->pahu_add_child_devices_work, - pahu_add_child_devices); - mutex_init(&pahu->micb_lock); - mutex_init(&pahu->swr.read_mutex); - mutex_init(&pahu->swr.write_mutex); - mutex_init(&pahu->swr.clk_mutex); - mutex_init(&pahu->codec_mutex); - mutex_init(&pahu->svs_mutex); - - /* - * Codec hardware by default comes up in SVS mode. - * Initialize the svs_ref_cnt to 1 to reflect the hardware - * state in the driver. - */ - pahu->svs_ref_cnt = 1; - - cdc_pwr = devm_kzalloc(&pdev->dev, sizeof(struct wcd9xxx_power_region), - GFP_KERNEL); - if (!cdc_pwr) { - ret = -ENOMEM; - goto err_resmgr; - } - pahu->wcd9xxx->wcd9xxx_pwr[WCD9XXX_DIG_CORE_REGION_1] = cdc_pwr; - cdc_pwr->pwr_collapse_reg_min = WCD9360_DIG_CORE_REG_MIN; - cdc_pwr->pwr_collapse_reg_max = WCD9360_DIG_CORE_REG_MAX; - wcd9xxx_set_power_state(pahu->wcd9xxx, - WCD_REGION_POWER_COLLAPSE_REMOVE, - WCD9XXX_DIG_CORE_REGION_1); - /* - * Init resource manager so that if child nodes such as SoundWire - * requests for clock, resource manager can honor the request - */ - resmgr = wcd_resmgr_init(&pahu->wcd9xxx->core_res, NULL); - if (IS_ERR(resmgr)) { - ret = PTR_ERR(resmgr); - dev_err(&pdev->dev, "%s: Failed to initialize wcd resmgr\n", - __func__); - goto err_resmgr; - } - pahu->resmgr = resmgr; - pahu->swr.plat_data.handle = (void *) pahu; - pahu->swr.plat_data.read = pahu_swrm_read; - pahu->swr.plat_data.write = pahu_swrm_write; - pahu->swr.plat_data.bulk_write = pahu_swrm_bulk_write; - pahu->swr.plat_data.clk = pahu_swrm_clock; - pahu->swr.plat_data.handle_irq = pahu_swrm_handle_irq; - pahu->swr.spkr_gain_offset = WCD9360_RX_GAIN_OFFSET_0_DB; - - /* Register for Clock */ - wcd_ext_clk = clk_get(pahu->wcd9xxx->dev, "wcd_clk"); - if (IS_ERR(wcd_ext_clk)) { - dev_err(pahu->wcd9xxx->dev, "%s: clk get %s failed\n", - __func__, "wcd_ext_clk"); - goto err_clk; - } - pahu->wcd_ext_clk = wcd_ext_clk; - dev_dbg(&pdev->dev, "%s: MCLK Rate = %x\n", __func__, - pahu->wcd9xxx->mclk_rate); - /* Probe defer if mlck is failed */ - ret = clk_prepare_enable(pahu->wcd_ext_clk); - if (ret) { - dev_dbg(pahu->dev, "%s: ext clk enable failed\n", - __func__); - ret = -EPROBE_DEFER; - goto err_cdc_reg; - } - clk_disable_unprepare(pahu->wcd_ext_clk); - - /* Update codec register default values */ - pahu_update_reg_defaults(pahu); - __pahu_enable_efuse_sensing(pahu); - pahu_update_cpr_defaults(pahu); - - /* Register with soc framework */ - ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pahu, - pahu_dai, ARRAY_SIZE(pahu_dai)); - if (ret) { - dev_err(&pdev->dev, "%s: Codec registration failed\n", - __func__); - goto err_cdc_reg; - } - schedule_work(&pahu->pahu_add_child_devices_work); - - return ret; - -err_cdc_reg: - clk_put(pahu->wcd_ext_clk); -err_clk: - wcd_resmgr_remove(pahu->resmgr); -err_resmgr: - mutex_destroy(&pahu->micb_lock); - mutex_destroy(&pahu->svs_mutex); - mutex_destroy(&pahu->codec_mutex); - mutex_destroy(&pahu->swr.read_mutex); - mutex_destroy(&pahu->swr.write_mutex); - mutex_destroy(&pahu->swr.clk_mutex); - devm_kfree(&pdev->dev, pahu); - - return ret; -} - -static int pahu_remove(struct platform_device *pdev) -{ - struct pahu_priv *pahu; - int count = 0; - - pahu = platform_get_drvdata(pdev); - if (!pahu) - return -EINVAL; - - if (pahu->spi) - spi_unregister_device(pahu->spi); - for (count = 0; count < pahu->child_count && - count < WCD9360_CHILD_DEVICES_MAX; count++) - platform_device_unregister(pahu->pdev_child_devices[count]); - - mutex_destroy(&pahu->micb_lock); - mutex_destroy(&pahu->svs_mutex); - mutex_destroy(&pahu->codec_mutex); - mutex_destroy(&pahu->swr.read_mutex); - mutex_destroy(&pahu->swr.write_mutex); - mutex_destroy(&pahu->swr.clk_mutex); - - snd_soc_unregister_codec(&pdev->dev); - clk_put(pahu->wcd_ext_clk); - wcd_resmgr_remove(pahu->resmgr); - devm_kfree(&pdev->dev, pahu); - return 0; -} - -static struct platform_driver pahu_codec_driver = { - .probe = pahu_probe, - .remove = pahu_remove, - .driver = { - .name = "pahu_codec", - .owner = THIS_MODULE, -#ifdef CONFIG_PM - .pm = &pahu_pm_ops, -#endif - }, -}; - -module_platform_driver(pahu_codec_driver); - -MODULE_DESCRIPTION("Pahu Codec driver"); -MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/wcd9360/wcd9360.h b/asoc/codecs/wcd9360/wcd9360.h deleted file mode 100644 index 04fb76d1a838..000000000000 --- a/asoc/codecs/wcd9360/wcd9360.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef __WCD9360_H__ -#define __WCD9360_H__ - -#include -#include "../wcd9xxx-slimslave.h" -#include "../wcd9xxx-common-v2.h" - -#define WCD9360_REGISTER_START_OFFSET 0x800 -#define WCD9360_SB_PGD_PORT_RX_BASE 0x40 -#define WCD9360_SB_PGD_PORT_TX_BASE 0x50 -#define WCD9360_RX_PORT_START_NUMBER 16 - -#define WCD9360_DMIC_CLK_DIV_2 0x0 -#define WCD9360_DMIC_CLK_DIV_3 0x1 -#define WCD9360_DMIC_CLK_DIV_4 0x2 -#define WCD9360_DMIC_CLK_DIV_6 0x3 -#define WCD9360_DMIC_CLK_DIV_8 0x4 -#define WCD9360_DMIC_CLK_DIV_16 0x5 -#define WCD9360_DMIC_CLK_DRIVE_DEFAULT 0x02 - -#define WCD9360_ANC_DMIC_X2_FULL_RATE 1 -#define WCD9360_ANC_DMIC_X2_HALF_RATE 0 - -#define PAHU_MAX_MICBIAS 4 -#define PAHU_NUM_INTERPOLATORS 10 -#define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64 - -/* Convert from vout ctl to micbias voltage in mV */ -#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50) - - -/* Number of input and output Slimbus port */ -enum { - WCD9360_RX0 = 0, - WCD9360_RX1, - WCD9360_RX2, - WCD9360_RX3, - WCD9360_RX4, - WCD9360_RX5, - WCD9360_RX6, - WCD9360_RX7, - WCD9360_RX_MAX, -}; - -enum { - WCD9360_TX0 = 0, - WCD9360_TX1, - WCD9360_TX2, - WCD9360_TX3, - WCD9360_TX4, - WCD9360_TX5, - WCD9360_TX6, - WCD9360_TX7, - WCD9360_TX8, - WCD9360_TX9, - WCD9360_TX10, - WCD9360_TX11, - WCD9360_TX12, - WCD9360_TX13, - WCD9360_TX14, - WCD9360_TX15, - WCD9360_TX_MAX, -}; - -/* - * Selects compander and smart boost settings - * for a given speaker mode - */ -enum { - WCD9360_SPKR_MODE_DEFAULT, - WCD9360_SPKR_MODE_1, /* COMP Gain = 12dB, Smartboost Max = 5.5V */ -}; - -/* - * Rx path gain offsets - */ -enum { - WCD9360_RX_GAIN_OFFSET_M1P5_DB, - WCD9360_RX_GAIN_OFFSET_0_DB, -}; - -enum { - WCD9360_MIC_BIAS_1 = 1, - WCD9360_MIC_BIAS_2, - WCD9360_MIC_BIAS_3, - WCD9360_MIC_BIAS_4 -}; - -enum { - WCD9360_MICB_PULLUP_ENABLE, - WCD9360_MICB_PULLUP_DISABLE, - WCD9360_MICB_ENABLE, - WCD9360_MICB_DISABLE, -}; - -/* - * Dai data structure holds the - * dai specific info like rate, - * channel number etc. - */ -struct pahu_codec_dai_data { - u32 rate; - u32 *ch_num; - u32 ch_act; - u32 ch_tot; -}; - -/* - * Structure used to update codec - * register defaults after reset - */ -struct pahu_reg_mask_val { - u16 reg; - u8 mask; - u8 val; -}; - -#if IS_ENABLED(CONFIG_SND_SOC_WCD9360) -extern void *pahu_get_afe_config(struct snd_soc_codec *codec, - enum afe_config_type config_type); -extern int pahu_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable); -extern int pahu_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable); -extern int pahu_set_spkr_mode(struct snd_soc_codec *codec, int mode); -extern int pahu_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset); -extern void *pahu_get_wcd_dsp_cntl(struct device *dev); -extern int wcd9360_get_micb_vout_ctl_val(u32 micb_mv); -extern int pahu_codec_info_create_codec_entry( - struct snd_info_entry *codec_root, - struct snd_soc_codec *codec); -#else -extern void *pahu_get_afe_config(struct snd_soc_codec *codec, - enum afe_config_type config_type) -{ - return NULL; -} -extern int pahu_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable) -{ - return 0; -} -extern int pahu_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable) -{ - return 0; -} -extern int pahu_set_spkr_mode(struct snd_soc_codec *codec, int mode) -{ - return 0; -} -extern int pahu_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset) -{ - return 0; -} -extern void *pahu_get_wcd_dsp_cntl(struct device *dev) -{ - return NULL; -} -extern int wcd9360_get_micb_vout_ctl_val(u32 micb_mv) -{ - return 0; -} -extern int pahu_codec_info_create_codec_entry( - struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) -{ - return 0; -} -#endif - -#endif diff --git a/asoc/codecs/wcd937x/Android.mk b/asoc/codecs/wcd937x/Android.mk index fa544664a418..95d8058d01ee 100644 --- a/asoc/codecs/wcd937x/Android.mk +++ b/asoc/codecs/wcd937x/Android.mk @@ -9,7 +9,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index 76aea1a62b69..4b7c58003df2 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -88,7 +88,6 @@ static const int wcd9xxx_cdc_types[] = { [WCD9330] = WCD9330, [WCD9335] = WCD9335, [WCD934X] = WCD934X, - [WCD9360] = WCD9360, }; static const struct of_device_id wcd9xxx_of_match[] = { @@ -330,8 +329,7 @@ int wcd9xxx_slim_write_repeat(struct wcd9xxx *wcd9xxx, unsigned short reg, struct slim_ele_access slim_msg; mutex_lock(&wcd9xxx->io_lock); - if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X || - wcd9xxx->type == WCD9360) { + if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X) { ret = wcd9xxx_page_write(wcd9xxx, ®); if (ret) goto done; @@ -1353,8 +1351,7 @@ static int wcd9xxx_slim_probe(struct slim_device *slim) * Vout_D to be ready after BUCK_SIDO is powered up. * SYS_RST_N shouldn't be pulled high during this time */ - if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X || - wcd9xxx->type == WCD9360) + if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X) usleep_range(600, 650); else usleep_range(5, 10); @@ -1600,7 +1597,6 @@ static const struct slim_device_id wcd_slim_device_id[] = { {"tomtom-slim-pgd", WCD9330}, {"tasha-slim-pgd", WCD9335}, {"tavil-slim-pgd", WCD934X}, - {"pahu-slim-pgd", WCD9360}, {} }; diff --git a/asoc/codecs/wcd9xxx-regmap.h b/asoc/codecs/wcd9xxx-regmap.h index 18e0e58b5117..1ac32bb065fb 100644 --- a/asoc/codecs/wcd9xxx-regmap.h +++ b/asoc/codecs/wcd9xxx-regmap.h @@ -19,8 +19,6 @@ typedef int (*regmap_patch_fptr)(struct regmap *, int); -extern struct regmap_config wcd9360_regmap_config; - extern struct regmap_config wcd934x_regmap_config; extern int wcd934x_regmap_register_patch(struct regmap *regmap, int version); @@ -34,9 +32,6 @@ static inline struct regmap_config *wcd9xxx_get_regmap_config(int type) struct regmap_config *regmap_config; switch (type) { - case WCD9360: - regmap_config = &wcd9360_regmap_config; - break; case WCD934X: regmap_config = &wcd934x_regmap_config; break; diff --git a/asoc/codecs/wcd9xxx-rst.c b/asoc/codecs/wcd9xxx-rst.c index 563dd78508f1..c1f456ca0783 100644 --- a/asoc/codecs/wcd9xxx-rst.c +++ b/asoc/codecs/wcd9xxx-rst.c @@ -22,8 +22,6 @@ #include "wcd9335_irq.h" #include #include "wcd934x/wcd934x_irq.h" -#include -#include "wcd9360/wcd9360-irq.h" /* wcd9335 interrupt table */ static const struct intr_data wcd9335_intr_table[] = { @@ -88,25 +86,6 @@ static const struct intr_data wcd934x_intr_table[] = { {WCD934X_IRQ_VBAT_RESTORE, false}, }; -static const struct intr_data wcd9360_intr_table[] = { - {WCD9XXX_IRQ_SLIMBUS, false}, - {WCD9360_IRQ_MISC, false}, - {WCD9360_IRQ_LDO_RXTX_SCD, false}, - {WCD9360_IRQ_EAR_PA_SCD, false}, - {WCD9360_IRQ_AUX_PA_SCD, false}, - {WCD9360_IRQ_EAR_PA_CNP_COMPLETE, false}, - {WCD9360_IRQ_AUX_PA_CNP_COMPLETE, false}, - {WCD9360_IRQ_RESERVED_3, false}, - {WCD9360_IRQ_SOUNDWIRE, false}, - {WCD9360_IRQ_RCO_ERROR, false}, - {WCD9360_IRQ_CPE_ERROR, false}, - {WCD9360_IRQ_MAD_AUDIO, false}, - {WCD9360_IRQ_MAD_BEACON, false}, - {WCD9360_IRQ_CPE1_INTR, true}, - {WCD9360_IRQ_RESERVED_4, false}, - {WCD9360_IRQ_MAD_ULTRASOUND, false}, -}; - /* * wcd9335_bring_down: Bringdown WCD Codec * @@ -405,143 +384,11 @@ static int wcd934x_get_cdc_info(struct wcd9xxx *wcd9xxx, return rc; } -/* - * wcd9360_bring_down: Bringdown WCD Codec - * - * @wcd9xxx: Pointer to wcd9xxx structure - * - * Returns 0 for success or negative error code for failure - */ -static int wcd9360_bring_down(struct wcd9xxx *wcd9xxx) -{ - if (!wcd9xxx || !wcd9xxx->regmap) - return -EINVAL; - - regmap_write(wcd9xxx->regmap, WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, - 0x04); - - return 0; -} - -/* - * wcd9360_bring_up: Bringup WCD Codec - * - * @wcd9xxx: Pointer to the wcd9xxx structure - * - * Returns 0 for success or negative error code for failure - */ -static int wcd9360_bring_up(struct wcd9xxx *wcd9xxx) -{ - struct regmap *wcd_regmap; - - if (!wcd9xxx) - return -EINVAL; - - if (!wcd9xxx->regmap) { - dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null!\n", - __func__); - return -EINVAL; - } - wcd_regmap = wcd9xxx->regmap; - - regmap_write(wcd_regmap, WCD9360_CODEC_RPM_RST_CTL, 0x01); - regmap_write(wcd_regmap, WCD9360_SIDO_NEW_VOUT_A_STARTUP, 0x19); - regmap_write(wcd_regmap, WCD9360_SIDO_NEW_VOUT_D_STARTUP, 0x15); - /* Add 1msec delay for VOUT to settle */ - usleep_range(1000, 1100); - regmap_write(wcd_regmap, WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5); - regmap_write(wcd_regmap, WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7); - regmap_write(wcd_regmap, WCD9360_CODEC_RPM_RST_CTL, 0x3); - regmap_write(wcd_regmap, WCD9360_CODEC_RPM_RST_CTL, 0x7); - regmap_write(wcd_regmap, WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3); - - return 0; -} - -/* - * wcd9360_get_cdc_info: Get codec specific information - * - * @wcd9xxx: pointer to wcd9xxx structure - * @wcd_type: pointer to wcd9xxx_codec_type structure - * - * Returns 0 for success or negative error code for failure - */ -static int wcd9360_get_cdc_info(struct wcd9xxx *wcd9xxx, - struct wcd9xxx_codec_type *wcd_type) -{ - u16 id_minor, id_major; - struct regmap *wcd_regmap; - int rc, version = -1; - - if (!wcd9xxx || !wcd_type) - return -EINVAL; - - if (!wcd9xxx->regmap) { - dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null\n", __func__); - return -EINVAL; - } - wcd_regmap = wcd9xxx->regmap; - - rc = regmap_bulk_read(wcd_regmap, WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE0, - (u8 *)&id_minor, sizeof(u16)); - if (rc) - return -EINVAL; - - rc = regmap_bulk_read(wcd_regmap, WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE2, - (u8 *)&id_major, sizeof(u16)); - if (rc) - return -EINVAL; - - dev_info(wcd9xxx->dev, "%s: wcd9xxx chip id major 0x%x, minor 0x%x\n", - __func__, id_major, id_minor); - - if (id_major != PAHU_MAJOR) - goto version_unknown; - - /* - * As fine version info cannot be retrieved before pahu probe. - * Assign coarse versions for possible future use before Pahu probe. - */ - if (id_minor == cpu_to_le16(0)) - version = PAHU_VERSION_1_0; - -version_unknown: - if (version < 0) - dev_err(wcd9xxx->dev, "%s: wcd934x version unknown\n", - __func__); - - /* Fill codec type info */ - wcd_type->id_major = id_major; - wcd_type->id_minor = id_minor; - wcd_type->num_irqs = WCD9360_NUM_IRQS; - wcd_type->version = version; - wcd_type->slim_slave_type = WCD9XXX_SLIM_SLAVE_ADDR_TYPE_1; - wcd_type->i2c_chip_status = 0x01; - wcd_type->intr_tbl = wcd9360_intr_table; - wcd_type->intr_tbl_size = ARRAY_SIZE(wcd9360_intr_table); - - wcd_type->intr_reg[WCD9XXX_INTR_STATUS_BASE] = - WCD9360_INTR_PIN1_STATUS0; - wcd_type->intr_reg[WCD9XXX_INTR_CLEAR_BASE] = - WCD9360_INTR_PIN1_CLEAR0; - wcd_type->intr_reg[WCD9XXX_INTR_MASK_BASE] = - WCD9360_INTR_PIN1_MASK0; - wcd_type->intr_reg[WCD9XXX_INTR_LEVEL_BASE] = - WCD9360_INTR_LEVEL0; - wcd_type->intr_reg[WCD9XXX_INTR_CLR_COMMIT] = - WCD9360_INTR_CLR_COMMIT; - - return rc; -} - codec_bringdown_fn wcd9xxx_bringdown_fn(int type) { codec_bringdown_fn cdc_bdown_fn; switch (type) { - case WCD9360: - cdc_bdown_fn = wcd9360_bring_down; - break; case WCD934X: cdc_bdown_fn = wcd934x_bring_down; break; @@ -561,9 +408,6 @@ codec_bringup_fn wcd9xxx_bringup_fn(int type) codec_bringup_fn cdc_bup_fn; switch (type) { - case WCD9360: - cdc_bup_fn = wcd9360_bring_up; - break; case WCD934X: cdc_bup_fn = wcd934x_bring_up; break; @@ -583,9 +427,6 @@ codec_type_fn wcd9xxx_get_codec_info_fn(int type) codec_type_fn cdc_type_fn; switch (type) { - case WCD9360: - cdc_type_fn = wcd9360_get_cdc_info; - break; case WCD934X: cdc_type_fn = wcd934x_get_cdc_info; break; diff --git a/asoc/codecs/wcd9xxx-utils.c b/asoc/codecs/wcd9xxx-utils.c index 7dc18f68b1e9..8ca55f859551 100644 --- a/asoc/codecs/wcd9xxx-utils.c +++ b/asoc/codecs/wcd9xxx-utils.c @@ -38,16 +38,6 @@ static enum wcd9xxx_intf_status wcd9xxx_intf = -1; -static struct mfd_cell pahu_devs[] = { - { - .name = "qcom-wcd-pinctrl", - .of_compatible = "qcom,wcd-pinctrl", - }, - { - .name = "pahu_codec", - }, -}; - static struct mfd_cell tavil_devs[] = { { .name = "qcom-wcd-pinctrl", @@ -490,8 +480,7 @@ int wcd9xxx_page_write(struct wcd9xxx *wcd9xxx, unsigned short *reg) unsigned short c_reg, reg_addr; u8 pg_num, prev_pg_num; - if (wcd9xxx->type != WCD9335 && wcd9xxx->type != WCD934X && - wcd9xxx->type != WCD9360) + if (wcd9xxx->type != WCD9335 && wcd9xxx->type != WCD934X) return ret; c_reg = *reg; @@ -888,10 +877,6 @@ int wcd9xxx_get_codec_info(struct device *dev) } switch (wcd9xxx->type) { - case WCD9360: - cinfo->dev = pahu_devs; - cinfo->size = ARRAY_SIZE(pahu_devs); - break; case WCD934X: cinfo->dev = tavil_devs; cinfo->size = ARRAY_SIZE(tavil_devs); diff --git a/asoc/msm8998.c b/asoc/msm8998.c deleted file mode 100644 index 1faa1930cc02..000000000000 --- a/asoc/msm8998.c +++ /dev/null @@ -1,7483 +0,0 @@ -/* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "msm-pcm-routing-v2.h" -#include "codecs/msm-cdc-pinctrl.h" -#include "codecs/wcd9335.h" -#include "codecs/wcd934x/wcd934x.h" -#include "codecs/wcd934x/wcd934x-mbhc.h" -#include "codecs/wsa881x.h" - -#define DRV_NAME "msm8998-asoc-snd" - -#define __CHIPSET__ "MSM8998 " -#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) - -#define SAMPLING_RATE_8KHZ 8000 -#define SAMPLING_RATE_11P025KHZ 11025 -#define SAMPLING_RATE_16KHZ 16000 -#define SAMPLING_RATE_22P05KHZ 22050 -#define SAMPLING_RATE_32KHZ 32000 -#define SAMPLING_RATE_44P1KHZ 44100 -#define SAMPLING_RATE_48KHZ 48000 -#define SAMPLING_RATE_88P2KHZ 88200 -#define SAMPLING_RATE_96KHZ 96000 -#define SAMPLING_RATE_176P4KHZ 176400 -#define SAMPLING_RATE_192KHZ 192000 -#define SAMPLING_RATE_352P8KHZ 352800 -#define SAMPLING_RATE_384KHZ 384000 - -#define WCD9XXX_MBHC_DEF_BUTTONS 8 -#define WCD9XXX_MBHC_DEF_RLOADS 5 -#define CODEC_EXT_CLK_RATE 9600000 -#define ADSP_STATE_READY_TIMEOUT_MS 3000 -#define DEV_NAME_STR_LEN 32 - -#define WSA8810_NAME_1 "wsa881x.20170211" -#define WSA8810_NAME_2 "wsa881x.20170212" - -#define WCN_CDC_SLIM_RX_CH_MAX 2 -#define WCN_CDC_SLIM_TX_CH_MAX 3 - -#define TDM_CHANNEL_MAX 8 -#define TDM_SLOT_OFFSET_MAX 8 - -#define MSM_HIFI_ON 1 - -enum { - SLIM_RX_0 = 0, - SLIM_RX_1, - SLIM_RX_2, - SLIM_RX_3, - SLIM_RX_4, - SLIM_RX_5, - SLIM_RX_6, - SLIM_RX_7, - SLIM_RX_MAX, -}; - -enum { - SLIM_TX_0 = 0, - SLIM_TX_1, - SLIM_TX_2, - SLIM_TX_3, - SLIM_TX_4, - SLIM_TX_5, - SLIM_TX_6, - SLIM_TX_7, - SLIM_TX_8, - SLIM_TX_MAX, -}; - -enum { - PRIM_MI2S = 0, - SEC_MI2S, - TERT_MI2S, - QUAT_MI2S, - MI2S_MAX, -}; - -enum { - PRIM_AUX_PCM = 0, - SEC_AUX_PCM, - TERT_AUX_PCM, - QUAT_AUX_PCM, - AUX_PCM_MAX, -}; - -enum { - PCM_I2S_SEL_PRIM = 0, - PCM_I2S_SEL_SEC, - PCM_I2S_SEL_TERT, - PCM_I2S_SEL_QUAT, - PCM_I2S_SEL_MAX, -}; - -struct mi2s_aux_pcm_common_conf { - struct mutex lock; - void *pcm_i2s_sel_vt_addr; -}; - -struct mi2s_conf { - struct mutex lock; - u32 ref_cnt; - u32 msm_is_mi2s_master; -}; - -struct auxpcm_conf { - struct mutex lock; - u32 ref_cnt; -}; - -struct dev_config { - u32 sample_rate; - u32 bit_format; - u32 channels; -}; - -enum { - HDMI_RX_IDX = 0, - DP_RX_IDX, - EXT_DISP_RX_IDX_MAX, -}; - -struct msm_wsa881x_dev_info { - struct device_node *of_node; - u32 index; -}; - -enum pinctrl_pin_state { - STATE_DISABLE = 0, /* All pins are in sleep state */ - STATE_MI2S_ACTIVE, /* IS2 = active, TDM = sleep */ - STATE_TDM_ACTIVE, /* IS2 = sleep, TDM = active */ -}; - -struct msm_pinctrl_info { - struct pinctrl *pinctrl; - struct pinctrl_state *mi2s_disable; - struct pinctrl_state *tdm_disable; - struct pinctrl_state *mi2s_active; - struct pinctrl_state *tdm_active; - enum pinctrl_pin_state curr_state; -}; - -struct msm_asoc_mach_data { - u32 mclk_freq; - int us_euro_gpio; /* used by gpio driver API */ - struct device_node *us_euro_gpio_p; /* used by pinctrl API */ - struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ - struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ - struct snd_info_entry *codec_root; - struct msm_pinctrl_info pinctrl_info; -}; - -struct msm_asoc_wcd93xx_codec { - void* (*get_afe_config_fn)(struct snd_soc_codec *codec, - enum afe_config_type config_type); - void (*mbhc_hs_detect_exit)(struct snd_soc_codec *codec); -}; - -static const char *const pin_states[] = {"sleep", "i2s-active", - "tdm-active"}; - -enum { - TDM_0 = 0, - TDM_1, - TDM_2, - TDM_3, - TDM_4, - TDM_5, - TDM_6, - TDM_7, - TDM_PORT_MAX, -}; - -enum { - TDM_PRI = 0, - TDM_SEC, - TDM_TERT, - TDM_QUAT, - TDM_INTERFACE_MAX, -}; - -struct tdm_port { - u32 mode; - u32 channel; -}; - -/* TDM default config */ -static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { - { /* PRI TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ - }, - { /* SEC TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ - }, - { /* TERT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ - }, - { /* QUAT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ - } -}; - -/* TDM default config */ -static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { - { /* PRI TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ - }, - { /* SEC TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ - }, - { /* TERT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ - }, - { /* QUAT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ - } -}; - -/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */ -static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { - {0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */ -}; - -/* Default configuration of slimbus channels */ -static struct dev_config slim_rx_cfg[] = { - [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, -}; - -static struct dev_config slim_tx_cfg[] = { - [SLIM_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, -}; - - -/* Default configuration of external display BE */ -static struct dev_config ext_disp_rx_cfg[] = { - [HDMI_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, - [DP_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, -}; - -static struct dev_config usb_rx_cfg = { - .sample_rate = SAMPLING_RATE_48KHZ, - .bit_format = SNDRV_PCM_FORMAT_S16_LE, - .channels = 2, -}; - -static struct dev_config usb_tx_cfg = { - .sample_rate = SAMPLING_RATE_48KHZ, - .bit_format = SNDRV_PCM_FORMAT_S16_LE, - .channels = 1, -}; - -static struct dev_config proxy_rx_cfg = { - .sample_rate = SAMPLING_RATE_48KHZ, - .bit_format = SNDRV_PCM_FORMAT_S16_LE, - .channels = 2, -}; - -/* Default configuration of MI2S channels */ -static struct dev_config mi2s_rx_cfg[] = { - [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, - [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, - [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, - [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, -}; - -static struct dev_config mi2s_tx_cfg[] = { - [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, -}; - -static struct dev_config aux_pcm_rx_cfg[] = { - [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, -}; - -static struct dev_config aux_pcm_tx_cfg[] = { - [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, -}; - -static int msm_vi_feed_tx_ch = 2; -static const char *const slim_rx_ch_text[] = {"One", "Two"}; -static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", - "Eight"}; -static const char *const vi_feed_ch_text[] = {"One", "Two"}; -static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", - "S32_LE"}; -static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE"}; -static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", - "KHZ_32", "KHZ_44P1", "KHZ_48", - "KHZ_88P2", "KHZ_96", "KHZ_176P4", - "KHZ_192", "KHZ_352P8", "KHZ_384"}; -static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_48"}; -static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", - "Eight"}; -static char const *ch_text[] = {"Two", "Three", "Four", "Five", - "Six", "Seven", "Eight"}; -static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", - "KHZ_16", "KHZ_22P05", - "KHZ_32", "KHZ_44P1", "KHZ_48", - "KHZ_88P2", "KHZ_96", "KHZ_176P4", - "KHZ_192", "KHZ_352P8", "KHZ_384"}; -static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96", - "KHZ_192", "KHZ_32", "KHZ_44P1", - "KHZ_88P2", "KHZ_176P4"}; -static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", "Eight"}; -static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; -static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", - "KHZ_44P1", "KHZ_48", "KHZ_96", - "KHZ_192", "KHZ_352P8", "KHZ_384"}; -static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; -static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16", - "KHZ_32", "KHZ_44P1", "KHZ_48", - "KHZ_96", "KHZ_192"}; -static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", - "Eight"}; -static const char *const hifi_text[] = {"Off", "On"}; - -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_1_tx_chs, slim_tx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_chs, slim_rx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, - ext_disp_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(hifi_function, hifi_text); - -static struct platform_device *spdev; -static int msm_hifi_control; - -static bool is_initial_boot; -static bool codec_reg_done; -static struct snd_soc_aux_dev *msm_aux_dev; -static struct snd_soc_codec_conf *msm_codec_conf; -static struct msm_asoc_wcd93xx_codec msm_codec_fn; - -static void *def_tasha_mbhc_cal(void); -static void *def_tavil_mbhc_cal(void); -static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, - int enable, bool dapm); -static int msm_wsa881x_init(struct snd_soc_component *component); - -/* - * Need to report LINEIN - * if R/L channel impedance is larger than 5K ohm - */ -static struct wcd_mbhc_config wcd_mbhc_cfg = { - .read_fw_bin = false, - .calibration = NULL, - .detect_extn_cable = true, - .mono_stero_detection = false, - .swap_gnd_mic = NULL, - .hs_ext_micbias = true, - .key_code[0] = KEY_MEDIA, - .key_code[1] = KEY_VOICECOMMAND, - .key_code[2] = KEY_VOLUMEUP, - .key_code[3] = KEY_VOLUMEDOWN, - .key_code[4] = 0, - .key_code[5] = 0, - .key_code[6] = 0, - .key_code[7] = 0, - .linein_th = 5000, - .moisture_en = true, - .mbhc_micbias = MIC_BIAS_2, - .anc_micbias = MIC_BIAS_2, - .enable_anc_mic_detect = false, -}; - -static struct snd_soc_dapm_route wcd_audio_paths_tasha[] = { - {"MIC BIAS1", NULL, "MCLK TX"}, - {"MIC BIAS2", NULL, "MCLK TX"}, - {"MIC BIAS3", NULL, "MCLK TX"}, - {"MIC BIAS4", NULL, "MCLK TX"}, -}; - -static struct snd_soc_dapm_route wcd_audio_paths[] = { - {"MIC BIAS1", NULL, "MCLK"}, - {"MIC BIAS2", NULL, "MCLK"}, - {"MIC BIAS3", NULL, "MCLK"}, - {"MIC BIAS4", NULL, "MCLK"}, -}; - -static struct afe_clk_set mi2s_clk[MI2S_MAX] = { - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - } -}; - -static struct mi2s_aux_pcm_common_conf mi2s_auxpcm_conf[PCM_I2S_SEL_MAX]; -static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; -static struct auxpcm_conf auxpcm_intf_conf[AUX_PCM_MAX]; - -static int slim_get_sample_rate_val(int sample_rate) -{ - int sample_rate_val = 0; - - switch (sample_rate) { - case SAMPLING_RATE_8KHZ: - sample_rate_val = 0; - break; - case SAMPLING_RATE_16KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_32KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 3; - break; - case SAMPLING_RATE_48KHZ: - sample_rate_val = 4; - break; - case SAMPLING_RATE_88P2KHZ: - sample_rate_val = 5; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 6; - break; - case SAMPLING_RATE_176P4KHZ: - sample_rate_val = 7; - break; - case SAMPLING_RATE_192KHZ: - sample_rate_val = 8; - break; - case SAMPLING_RATE_352P8KHZ: - sample_rate_val = 9; - break; - case SAMPLING_RATE_384KHZ: - sample_rate_val = 10; - break; - default: - sample_rate_val = 4; - break; - } - return sample_rate_val; -} - -static int slim_get_sample_rate(int value) -{ - int sample_rate = 0; - - switch (value) { - case 0: - sample_rate = SAMPLING_RATE_8KHZ; - break; - case 1: - sample_rate = SAMPLING_RATE_16KHZ; - break; - case 2: - sample_rate = SAMPLING_RATE_32KHZ; - break; - case 3: - sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 4: - sample_rate = SAMPLING_RATE_48KHZ; - break; - case 5: - sample_rate = SAMPLING_RATE_88P2KHZ; - break; - case 6: - sample_rate = SAMPLING_RATE_96KHZ; - break; - case 7: - sample_rate = SAMPLING_RATE_176P4KHZ; - break; - case 8: - sample_rate = SAMPLING_RATE_192KHZ; - break; - case 9: - sample_rate = SAMPLING_RATE_352P8KHZ; - break; - case 10: - sample_rate = SAMPLING_RATE_384KHZ; - break; - default: - sample_rate = SAMPLING_RATE_48KHZ; - break; - } - return sample_rate; -} - -static int slim_get_bit_format_val(int bit_format) -{ - int val = 0; - - switch (bit_format) { - case SNDRV_PCM_FORMAT_S32_LE: - val = 3; - break; - case SNDRV_PCM_FORMAT_S24_3LE: - val = 2; - break; - case SNDRV_PCM_FORMAT_S24_LE: - val = 1; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - val = 0; - break; - } - return val; -} - -static int slim_get_bit_format(int val) -{ - int bit_fmt = SNDRV_PCM_FORMAT_S16_LE; - - switch (val) { - case 0: - bit_fmt = SNDRV_PCM_FORMAT_S16_LE; - break; - case 1: - bit_fmt = SNDRV_PCM_FORMAT_S24_LE; - break; - case 2: - bit_fmt = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 3: - bit_fmt = SNDRV_PCM_FORMAT_S32_LE; - break; - default: - bit_fmt = SNDRV_PCM_FORMAT_S16_LE; - break; - } - return bit_fmt; -} - -static int slim_get_port_idx(struct snd_kcontrol *kcontrol) -{ - int port_id = 0; - - if (strnstr(kcontrol->id.name, "SLIM_0_RX", sizeof("SLIM_0_RX"))) - port_id = SLIM_RX_0; - else if (strnstr(kcontrol->id.name, "SLIM_2_RX", sizeof("SLIM_2_RX"))) - port_id = SLIM_RX_2; - else if (strnstr(kcontrol->id.name, "SLIM_5_RX", sizeof("SLIM_5_RX"))) - port_id = SLIM_RX_5; - else if (strnstr(kcontrol->id.name, "SLIM_6_RX", sizeof("SLIM_6_RX"))) - port_id = SLIM_RX_6; - else if (strnstr(kcontrol->id.name, "SLIM_0_TX", sizeof("SLIM_0_TX"))) - port_id = SLIM_TX_0; - else if (strnstr(kcontrol->id.name, "SLIM_1_TX", sizeof("SLIM_1_TX"))) - port_id = SLIM_TX_1; - else { - pr_err("%s: unsupported channel: %s", - __func__, kcontrol->id.name); - return -EINVAL; - } - - return port_id; -} - -static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - ucontrol->value.enumerated.item[0] = - slim_get_sample_rate_val(slim_rx_cfg[ch_num].sample_rate); - - pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, - ch_num, slim_rx_cfg[ch_num].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - slim_rx_cfg[ch_num].sample_rate = - slim_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, - ch_num, slim_rx_cfg[ch_num].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - ucontrol->value.enumerated.item[0] = - slim_get_sample_rate_val(slim_tx_cfg[ch_num].sample_rate); - - pr_debug("%s: slim[%d]_tx_sample_rate = %d, item = %d\n", __func__, - ch_num, slim_tx_cfg[ch_num].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate = 0; - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - sample_rate = slim_get_sample_rate(ucontrol->value.enumerated.item[0]); - if (sample_rate == SAMPLING_RATE_44P1KHZ) { - pr_err("%s: Unsupported sample rate %d: for Tx path\n", - __func__, sample_rate); - return -EINVAL; - } - slim_tx_cfg[ch_num].sample_rate = sample_rate; - - pr_debug("%s: slim[%d]_tx_sample_rate = %d, value = %d\n", __func__, - ch_num, slim_tx_cfg[ch_num].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_rx_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - ucontrol->value.enumerated.item[0] = - slim_get_bit_format_val(slim_rx_cfg[ch_num].bit_format); - - pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", - __func__, ch_num, slim_rx_cfg[ch_num].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_rx_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - slim_rx_cfg[ch_num].bit_format = - slim_get_bit_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", - __func__, ch_num, slim_rx_cfg[ch_num].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_tx_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - ucontrol->value.enumerated.item[0] = - slim_get_bit_format_val(slim_tx_cfg[ch_num].bit_format); - - pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", - __func__, ch_num, slim_tx_cfg[ch_num].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_tx_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - slim_tx_cfg[ch_num].bit_format = - slim_get_bit_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", - __func__, ch_num, slim_tx_cfg[ch_num].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_slim_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, - ch_num, slim_rx_cfg[ch_num].channels); - ucontrol->value.enumerated.item[0] = slim_rx_cfg[ch_num].channels - 1; - - return 0; -} - -static int msm_slim_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - slim_rx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; - pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, - ch_num, slim_rx_cfg[ch_num].channels); - - return 1; -} - -static int msm_slim_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, - ch_num, slim_tx_cfg[ch_num].channels); - ucontrol->value.enumerated.item[0] = slim_tx_cfg[ch_num].channels - 1; - - return 0; -} - -static int msm_slim_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - slim_tx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; - pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, - ch_num, slim_tx_cfg[ch_num].channels); - - return 1; -} - -static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1; - pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, - ucontrol->value.integer.value[0]); - return 0; -} - -static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1; - - pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch); - return 1; -} - -static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - /* - * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) - * when used for BT_SCO use case. Return either Rx or Tx sample rate - * value. - */ - switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { - case SAMPLING_RATE_48KHZ: - ucontrol->value.integer.value[0] = 2; - break; - case SAMPLING_RATE_16KHZ: - ucontrol->value.integer.value[0] = 1; - break; - case SAMPLING_RATE_8KHZ: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - pr_debug("%s: sample rate = %d", __func__, - slim_rx_cfg[SLIM_RX_7].sample_rate); - - return 0; -} - -static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 1: - slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; - slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; - break; - case 2: - slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; - slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; - break; - case 0: - default: - slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; - slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; - break; - } - pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n", - __func__, - slim_rx_cfg[SLIM_RX_7].sample_rate, - slim_tx_cfg[SLIM_TX_7].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, - usb_rx_cfg.channels); - ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1; - return 0; -} - -static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1; - - pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels); - return 1; -} - -static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val; - - switch (usb_rx_cfg.sample_rate) { - case SAMPLING_RATE_384KHZ: - sample_rate_val = 12; - break; - case SAMPLING_RATE_352P8KHZ: - sample_rate_val = 11; - break; - case SAMPLING_RATE_192KHZ: - sample_rate_val = 10; - break; - case SAMPLING_RATE_176P4KHZ: - sample_rate_val = 9; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 8; - break; - case SAMPLING_RATE_88P2KHZ: - sample_rate_val = 7; - break; - case SAMPLING_RATE_48KHZ: - sample_rate_val = 6; - break; - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 5; - break; - case SAMPLING_RATE_32KHZ: - sample_rate_val = 4; - break; - case SAMPLING_RATE_22P05KHZ: - sample_rate_val = 3; - break; - case SAMPLING_RATE_16KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_11P025KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_8KHZ: - default: - sample_rate_val = 0; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__, - usb_rx_cfg.sample_rate); - return 0; -} - -static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 12: - usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ; - break; - case 11: - usb_rx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; - break; - case 10: - usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ; - break; - case 9: - usb_rx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; - break; - case 8: - usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ; - break; - case 7: - usb_rx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; - break; - case 6: - usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; - break; - case 5: - usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 4: - usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ; - break; - case 3: - usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; - break; - case 2: - usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ; - break; - case 1: - usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; - break; - case 0: - usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ; - break; - default: - usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; - break; - } - - pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n", - __func__, ucontrol->value.integer.value[0], - usb_rx_cfg.sample_rate); - return 0; -} - -static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (usb_rx_cfg.bit_format) { - case SNDRV_PCM_FORMAT_S32_LE: - ucontrol->value.integer.value[0] = 3; - break; - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", - __func__, usb_rx_cfg.bit_format, - ucontrol->value.integer.value[0]); - return 0; -} - -static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int rc = 0; - - switch (ucontrol->value.integer.value[0]) { - case 3: - usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; - break; - case 2: - usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", - __func__, usb_rx_cfg.bit_format, - ucontrol->value.integer.value[0]); - - return rc; -} - -static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, - usb_tx_cfg.channels); - ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1; - return 0; -} - -static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1; - - pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels); - return 1; -} - -static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val; - - switch (usb_tx_cfg.sample_rate) { - case SAMPLING_RATE_384KHZ: - sample_rate_val = 12; - break; - case SAMPLING_RATE_352P8KHZ: - sample_rate_val = 11; - break; - case SAMPLING_RATE_192KHZ: - sample_rate_val = 10; - break; - case SAMPLING_RATE_176P4KHZ: - sample_rate_val = 9; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 8; - break; - case SAMPLING_RATE_88P2KHZ: - sample_rate_val = 7; - break; - case SAMPLING_RATE_48KHZ: - sample_rate_val = 6; - break; - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 5; - break; - case SAMPLING_RATE_32KHZ: - sample_rate_val = 4; - break; - case SAMPLING_RATE_22P05KHZ: - sample_rate_val = 3; - break; - case SAMPLING_RATE_16KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_11P025KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_8KHZ: - sample_rate_val = 0; - break; - default: - sample_rate_val = 6; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__, - usb_tx_cfg.sample_rate); - return 0; -} - -static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 12: - usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ; - break; - case 11: - usb_tx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; - break; - case 10: - usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ; - break; - case 9: - usb_tx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; - break; - case 8: - usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ; - break; - case 7: - usb_tx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; - break; - case 6: - usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; - break; - case 5: - usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 4: - usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ; - break; - case 3: - usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; - break; - case 2: - usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ; - break; - case 1: - usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; - break; - case 0: - usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ; - break; - default: - usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; - break; - } - - pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n", - __func__, ucontrol->value.integer.value[0], - usb_tx_cfg.sample_rate); - return 0; -} - -static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (usb_tx_cfg.bit_format) { - case SNDRV_PCM_FORMAT_S32_LE: - ucontrol->value.integer.value[0] = 3; - break; - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", - __func__, usb_tx_cfg.bit_format, - ucontrol->value.integer.value[0]); - return 0; -} - -static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int rc = 0; - - switch (ucontrol->value.integer.value[0]) { - case 3: - usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; - break; - case 2: - usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", - __func__, usb_tx_cfg.bit_format, - ucontrol->value.integer.value[0]); - - return rc; -} - -static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol) -{ - int idx; - - if (strnstr(kcontrol->id.name, "HDMI_RX", sizeof("HDMI_RX"))) - idx = HDMI_RX_IDX; - else if (strnstr(kcontrol->id.name, "Display Port RX", - sizeof("Display Port RX"))) - idx = DP_RX_IDX; - else { - pr_err("%s: unsupported BE: %s", - __func__, kcontrol->id.name); - idx = -EINVAL; - } - - return idx; -} - -static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - switch (ext_disp_rx_cfg[idx].bit_format) { - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", - __func__, idx, ext_disp_rx_cfg[idx].bit_format, - ucontrol->value.integer.value[0]); - return 0; -} - -static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - switch (ucontrol->value.integer.value[0]) { - case 1: - ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", - __func__, idx, ext_disp_rx_cfg[idx].bit_format, - ucontrol->value.integer.value[0]); - - return 0; -} - -static int ext_disp_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.integer.value[0] = - ext_disp_rx_cfg[idx].channels - 2; - - pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, - idx, ext_disp_rx_cfg[idx].channels); - - return 0; -} - -static int ext_disp_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ext_disp_rx_cfg[idx].channels = - ucontrol->value.integer.value[0] + 2; - - pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, - idx, ext_disp_rx_cfg[idx].channels); - return 1; -} - -static int ext_disp_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val; - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - switch (ext_disp_rx_cfg[idx].sample_rate) { - case SAMPLING_RATE_176P4KHZ: - sample_rate_val = 6; - break; - - case SAMPLING_RATE_88P2KHZ: - sample_rate_val = 5; - break; - - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 4; - break; - - case SAMPLING_RATE_32KHZ: - sample_rate_val = 3; - break; - - case SAMPLING_RATE_192KHZ: - sample_rate_val = 2; - break; - - case SAMPLING_RATE_96KHZ: - sample_rate_val = 1; - break; - - case SAMPLING_RATE_48KHZ: - default: - sample_rate_val = 0; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: ext_disp_rx[%d].sample_rate = %d\n", __func__, - idx, ext_disp_rx_cfg[idx].sample_rate); - - return 0; -} - -static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - switch (ucontrol->value.integer.value[0]) { - case 6: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_176P4KHZ; - break; - case 5: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_88P2KHZ; - break; - case 4: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 3: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_32KHZ; - break; - case 2: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ; - break; - case 1: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ; - break; - case 0: - default: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ; - break; - } - - pr_debug("%s: control value = %ld, ext_disp_rx[%d].sample_rate = %d\n", - __func__, ucontrol->value.integer.value[0], idx, - ext_disp_rx_cfg[idx].sample_rate); - return 0; -} - -static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: proxy_rx channels = %d\n", - __func__, proxy_rx_cfg.channels); - ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2; - - return 0; -} - -static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2; - pr_debug("%s: proxy_rx channels = %d\n", - __func__, proxy_rx_cfg.channels); - - return 1; -} - -static int tdm_get_sample_rate(int value) -{ - int sample_rate = 0; - - switch (value) { - case 0: - sample_rate = SAMPLING_RATE_8KHZ; - break; - case 1: - sample_rate = SAMPLING_RATE_16KHZ; - break; - case 2: - sample_rate = SAMPLING_RATE_32KHZ; - break; - case 3: - sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 4: - sample_rate = SAMPLING_RATE_48KHZ; - break; - case 5: - sample_rate = SAMPLING_RATE_96KHZ; - break; - case 6: - sample_rate = SAMPLING_RATE_192KHZ; - break; - case 7: - sample_rate = SAMPLING_RATE_352P8KHZ; - break; - case 8: - sample_rate = SAMPLING_RATE_384KHZ; - break; - default: - sample_rate = SAMPLING_RATE_48KHZ; - break; - } - return sample_rate; -} - -static int aux_pcm_get_sample_rate(int value) -{ - int sample_rate; - - switch (value) { - case 1: - sample_rate = SAMPLING_RATE_16KHZ; - break; - case 0: - default: - sample_rate = SAMPLING_RATE_8KHZ; - break; - } - return sample_rate; -} - -static int tdm_get_sample_rate_val(int sample_rate) -{ - int sample_rate_val = 0; - - switch (sample_rate) { - case SAMPLING_RATE_8KHZ: - sample_rate_val = 0; - break; - case SAMPLING_RATE_16KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_32KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 3; - break; - case SAMPLING_RATE_48KHZ: - sample_rate_val = 4; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 5; - break; - case SAMPLING_RATE_192KHZ: - sample_rate_val = 6; - break; - case SAMPLING_RATE_352P8KHZ: - sample_rate_val = 7; - break; - case SAMPLING_RATE_384KHZ: - sample_rate_val = 8; - break; - default: - sample_rate_val = 4; - break; - } - return sample_rate_val; -} - -static int aux_pcm_get_sample_rate_val(int sample_rate) -{ - int sample_rate_val; - - switch (sample_rate) { - case SAMPLING_RATE_16KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_8KHZ: - default: - sample_rate_val = 0; - break; - } - return sample_rate_val; -} - -static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, - struct tdm_port *port) -{ - if (port) { - if (strnstr(kcontrol->id.name, "PRI", - sizeof(kcontrol->id.name))) { - port->mode = TDM_PRI; - } else if (strnstr(kcontrol->id.name, "SEC", - sizeof(kcontrol->id.name))) { - port->mode = TDM_SEC; - } else if (strnstr(kcontrol->id.name, "TERT", - sizeof(kcontrol->id.name))) { - port->mode = TDM_TERT; - } else if (strnstr(kcontrol->id.name, "QUAT", - sizeof(kcontrol->id.name))) { - port->mode = TDM_QUAT; - } else { - pr_err("%s: unsupported mode in: %s", - __func__, kcontrol->id.name); - return -EINVAL; - } - - if (strnstr(kcontrol->id.name, "RX_0", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_0", - sizeof(kcontrol->id.name))) { - port->channel = TDM_0; - } else if (strnstr(kcontrol->id.name, "RX_1", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_1", - sizeof(kcontrol->id.name))) { - port->channel = TDM_1; - } else if (strnstr(kcontrol->id.name, "RX_2", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_2", - sizeof(kcontrol->id.name))) { - port->channel = TDM_2; - } else if (strnstr(kcontrol->id.name, "RX_3", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_3", - sizeof(kcontrol->id.name))) { - port->channel = TDM_3; - } else if (strnstr(kcontrol->id.name, "RX_4", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_4", - sizeof(kcontrol->id.name))) { - port->channel = TDM_4; - } else if (strnstr(kcontrol->id.name, "RX_5", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_5", - sizeof(kcontrol->id.name))) { - port->channel = TDM_5; - } else if (strnstr(kcontrol->id.name, "RX_6", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_6", - sizeof(kcontrol->id.name))) { - port->channel = TDM_6; - } else if (strnstr(kcontrol->id.name, "RX_7", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_7", - sizeof(kcontrol->id.name))) { - port->channel = TDM_7; - } else { - pr_err("%s: unsupported channel in: %s", - __func__, kcontrol->id.name); - return -EINVAL; - } - } else - return -EINVAL; - return 0; -} - -static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( - tdm_rx_cfg[port.mode][port.channel].sample_rate); - - pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].sample_rate, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_rx_cfg[port.mode][port.channel].sample_rate = - tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].sample_rate, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( - tdm_tx_cfg[port.mode][port.channel].sample_rate); - - pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].sample_rate, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_tx_cfg[port.mode][port.channel].sample_rate = - tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].sample_rate, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_get_format(int value) -{ - int format = 0; - - switch (value) { - case 0: - format = SNDRV_PCM_FORMAT_S16_LE; - break; - case 1: - format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 2: - format = SNDRV_PCM_FORMAT_S32_LE; - break; - default: - format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - return format; -} - -static int tdm_get_format_val(int format) -{ - int value = 0; - - switch (format) { - case SNDRV_PCM_FORMAT_S16_LE: - value = 0; - break; - case SNDRV_PCM_FORMAT_S24_LE: - value = 1; - break; - case SNDRV_PCM_FORMAT_S32_LE: - value = 2; - break; - default: - value = 0; - break; - } - return value; -} - -static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - ucontrol->value.enumerated.item[0] = tdm_get_format_val( - tdm_rx_cfg[port.mode][port.channel].bit_format); - - pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].bit_format, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_rx_cfg[port.mode][port.channel].bit_format = - tdm_get_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].bit_format, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - ucontrol->value.enumerated.item[0] = tdm_get_format_val( - tdm_tx_cfg[port.mode][port.channel].bit_format); - - pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].bit_format, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_tx_cfg[port.mode][port.channel].bit_format = - tdm_get_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].bit_format, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - - ucontrol->value.enumerated.item[0] = - tdm_rx_cfg[port.mode][port.channel].channels - 1; - - pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].channels - 1, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_rx_cfg[port.mode][port.channel].channels = - ucontrol->value.enumerated.item[0] + 1; - - pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].channels, - ucontrol->value.enumerated.item[0] + 1); - } - return ret; -} - -static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - ucontrol->value.enumerated.item[0] = - tdm_tx_cfg[port.mode][port.channel].channels - 1; - - pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].channels - 1, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_tx_cfg[port.mode][port.channel].channels = - ucontrol->value.enumerated.item[0] + 1; - - pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].channels, - ucontrol->value.enumerated.item[0] + 1); - } - return ret; -} - -static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) -{ - int idx; - - if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", - sizeof("PRIM_AUX_PCM"))) - idx = PRIM_AUX_PCM; - else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM", - sizeof("SEC_AUX_PCM"))) - idx = SEC_AUX_PCM; - else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", - sizeof("TERT_AUX_PCM"))) - idx = TERT_AUX_PCM; - else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", - sizeof("QUAT_AUX_PCM"))) - idx = QUAT_AUX_PCM; - else { - pr_err("%s: unsupported port: %s", - __func__, kcontrol->id.name); - idx = -EINVAL; - } - - return idx; -} - -static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - aux_pcm_rx_cfg[idx].sample_rate = - aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, - idx, aux_pcm_rx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate); - - pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, - idx, aux_pcm_rx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - aux_pcm_tx_cfg[idx].sample_rate = - aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, - idx, aux_pcm_tx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate); - - pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, - idx, aux_pcm_tx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) -{ - int idx; - - if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX", - sizeof("PRIM_MI2S_RX"))) - idx = PRIM_MI2S; - else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX", - sizeof("SEC_MI2S_RX"))) - idx = SEC_MI2S; - else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", - sizeof("TERT_MI2S_RX"))) - idx = TERT_MI2S; - else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", - sizeof("QUAT_MI2S_RX"))) - idx = QUAT_MI2S; - else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", - sizeof("PRIM_MI2S_TX"))) - idx = PRIM_MI2S; - else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX", - sizeof("SEC_MI2S_TX"))) - idx = SEC_MI2S; - else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", - sizeof("TERT_MI2S_TX"))) - idx = TERT_MI2S; - else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", - sizeof("QUAT_MI2S_TX"))) - idx = QUAT_MI2S; - else { - pr_err("%s: unsupported channel: %s", - __func__, kcontrol->id.name); - idx = -EINVAL; - } - - return idx; -} - -static int mi2s_get_sample_rate_val(int sample_rate) -{ - int sample_rate_val; - - switch (sample_rate) { - case SAMPLING_RATE_8KHZ: - sample_rate_val = 0; - break; - case SAMPLING_RATE_16KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_32KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 3; - break; - case SAMPLING_RATE_48KHZ: - sample_rate_val = 4; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 5; - break; - case SAMPLING_RATE_192KHZ: - sample_rate_val = 6; - break; - default: - sample_rate_val = 4; - break; - } - return sample_rate_val; -} - -static int mi2s_get_sample_rate(int value) -{ - int sample_rate; - - switch (value) { - case 0: - sample_rate = SAMPLING_RATE_8KHZ; - break; - case 1: - sample_rate = SAMPLING_RATE_16KHZ; - break; - case 2: - sample_rate = SAMPLING_RATE_32KHZ; - break; - case 3: - sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 4: - sample_rate = SAMPLING_RATE_48KHZ; - break; - case 5: - sample_rate = SAMPLING_RATE_96KHZ; - break; - case 6: - sample_rate = SAMPLING_RATE_192KHZ; - break; - default: - sample_rate = SAMPLING_RATE_48KHZ; - break; - } - return sample_rate; -} - -static int mi2s_get_format(int value) -{ - int format; - - switch (value) { - case 0: - format = SNDRV_PCM_FORMAT_S16_LE; - break; - case 1: - format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 2: - format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 3: - format = SNDRV_PCM_FORMAT_S32_LE; - break; - default: - format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - return format; -} - -static int mi2s_get_format_value(int format) -{ - int value; - - switch (format) { - case SNDRV_PCM_FORMAT_S16_LE: - value = 0; - break; - case SNDRV_PCM_FORMAT_S24_LE: - value = 1; - break; - case SNDRV_PCM_FORMAT_S24_3LE: - value = 2; - break; - case SNDRV_PCM_FORMAT_S32_LE: - value = 3; - break; - default: - value = 0; - break; - } - return value; -} - -static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_rx_cfg[idx].sample_rate = - mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, - idx, mi2s_rx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate); - - pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, - idx, mi2s_rx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_tx_cfg[idx].sample_rate = - mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, - idx, mi2s_tx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate); - - pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, - idx, mi2s_tx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, - idx, mi2s_rx_cfg[idx].channels); - ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1; - - return 0; -} - -static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; - pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, - idx, mi2s_rx_cfg[idx].channels); - - return 1; -} - -static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, - idx, mi2s_tx_cfg[idx].channels); - ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1; - - return 0; -} - -static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; - pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, - idx, mi2s_tx_cfg[idx].channels); - - return 1; -} - -static int msm_mi2s_rx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - mi2s_get_format_value(mi2s_rx_cfg[idx].bit_format); - - pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, - idx, mi2s_rx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_rx_cfg[idx].bit_format = - mi2s_get_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, - idx, mi2s_rx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_mi2s_tx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - mi2s_get_format_value(mi2s_tx_cfg[idx].bit_format); - - pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, - idx, mi2s_tx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_tx_cfg[idx].bit_format = - mi2s_get_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, - idx, mi2s_tx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_hifi_ctrl(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct snd_soc_card *card = codec->component.card; - struct msm_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - - pr_debug("%s: msm_hifi_control = %d", __func__, - msm_hifi_control); - - if (!pdata || !pdata->hph_en1_gpio_p) { - pr_err("%s: hph_en1_gpio is invalid\n", __func__); - return -EINVAL; - } - if (msm_hifi_control == MSM_HIFI_ON) { - msm_cdc_pinctrl_select_active_state(pdata->hph_en1_gpio_p); - /* 5msec delay needed as per HW requirement */ - usleep_range(5000, 5010); - } else { - msm_cdc_pinctrl_select_sleep_state(pdata->hph_en1_gpio_p); - } - snd_soc_dapm_sync(dapm); - - return 0; -} - -static int msm_hifi_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_hifi_control = %d\n", - __func__, msm_hifi_control); - ucontrol->value.integer.value[0] = msm_hifi_control; - - return 0; -} - -static int msm_hifi_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - - pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - msm_hifi_control = ucontrol->value.integer.value[0]; - msm_hifi_ctrl(codec); - - return 0; -} - -static const struct snd_kcontrol_new msm_snd_controls[] = { - SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, - msm_slim_rx_ch_get, msm_slim_rx_ch_put), - SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs, - msm_slim_rx_ch_get, msm_slim_rx_ch_put), - SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs, - msm_slim_tx_ch_get, msm_slim_tx_ch_put), - SOC_ENUM_EXT("SLIM_1_TX Channels", slim_1_tx_chs, - msm_slim_tx_ch_get, msm_slim_tx_ch_put), - SOC_ENUM_EXT("SLIM_5_RX Channels", slim_5_rx_chs, - msm_slim_rx_ch_get, msm_slim_rx_ch_put), - SOC_ENUM_EXT("SLIM_6_RX Channels", slim_6_rx_chs, - msm_slim_rx_ch_get, msm_slim_rx_ch_put), - SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, - msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), - SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, - usb_audio_rx_ch_get, usb_audio_rx_ch_put), - SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, - usb_audio_tx_ch_get, usb_audio_tx_ch_put), - SOC_ENUM_EXT("HDMI_RX Channels", ext_disp_rx_chs, - ext_disp_rx_ch_get, ext_disp_rx_ch_put), - SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, - ext_disp_rx_ch_get, ext_disp_rx_ch_put), - SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, - proxy_rx_ch_get, proxy_rx_ch_put), - SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format, - slim_rx_bit_format_get, slim_rx_bit_format_put), - SOC_ENUM_EXT("SLIM_5_RX Format", slim_5_rx_format, - slim_rx_bit_format_get, slim_rx_bit_format_put), - SOC_ENUM_EXT("SLIM_6_RX Format", slim_6_rx_format, - slim_rx_bit_format_get, slim_rx_bit_format_put), - SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format, - slim_tx_bit_format_get, slim_tx_bit_format_put), - SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, - usb_audio_rx_format_get, usb_audio_rx_format_put), - SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, - usb_audio_tx_format_get, usb_audio_tx_format_put), - SOC_ENUM_EXT("HDMI_RX Bit Format", ext_disp_rx_format, - ext_disp_rx_format_get, ext_disp_rx_format_put), - SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, - ext_disp_rx_format_get, ext_disp_rx_format_put), - SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate, - slim_rx_sample_rate_get, slim_rx_sample_rate_put), - SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate, - slim_rx_sample_rate_get, slim_rx_sample_rate_put), - SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate, - slim_tx_sample_rate_get, slim_tx_sample_rate_put), - SOC_ENUM_EXT("SLIM_5_RX SampleRate", slim_5_rx_sample_rate, - slim_rx_sample_rate_get, slim_rx_sample_rate_put), - SOC_ENUM_EXT("SLIM_6_RX SampleRate", slim_6_rx_sample_rate, - slim_rx_sample_rate_get, slim_rx_sample_rate_put), - SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, - msm_bt_sample_rate_get, - msm_bt_sample_rate_put), - SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, - usb_audio_rx_sample_rate_get, - usb_audio_rx_sample_rate_put), - SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, - usb_audio_tx_sample_rate_get, - usb_audio_tx_sample_rate_put), - SOC_ENUM_EXT("HDMI_RX SampleRate", ext_disp_rx_sample_rate, - ext_disp_rx_sample_rate_get, - ext_disp_rx_sample_rate_put), - SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, - ext_disp_rx_sample_rate_get, - ext_disp_rx_sample_rate_put), - SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, - tdm_rx_sample_rate_get, - tdm_rx_sample_rate_put), - SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, - tdm_tx_sample_rate_get, - tdm_tx_sample_rate_put), - SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, - tdm_rx_sample_rate_get, - tdm_rx_sample_rate_put), - SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, - tdm_tx_sample_rate_get, - tdm_tx_sample_rate_put), - SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, - tdm_rx_sample_rate_get, - tdm_rx_sample_rate_put), - SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, - tdm_tx_sample_rate_get, - tdm_tx_sample_rate_put), - SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, - tdm_rx_sample_rate_get, - tdm_rx_sample_rate_put), - SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, - tdm_tx_sample_rate_get, - tdm_tx_sample_rate_put), - SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, - mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate, - mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, - mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, - mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, - mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, - mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, - mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, - mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, - msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), - SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, - msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, - msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), - SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, - msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, - msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), - SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, - msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs, - msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), - SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, - msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, - msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), - SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, - msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), - SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format, - msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), - SOC_ENUM_EXT("SEC_MI2S_TX Format", mi2s_tx_format, - msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), - SOC_ENUM_EXT("TERT_MI2S_RX Format", mi2s_rx_format, - msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), - SOC_ENUM_EXT("TERT_MI2S_TX Format", mi2s_tx_format, - msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), - SOC_ENUM_EXT("QUAT_MI2S_RX Format", mi2s_rx_format, - msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), - SOC_ENUM_EXT("QUAT_MI2S_TX Format", mi2s_tx_format, - msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), - SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get, - msm_hifi_put), -}; - -static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, - int enable, bool dapm) -{ - int ret = 0; - - if (!strcmp(dev_name(codec->dev), "tasha_codec")) - ret = tasha_cdc_mclk_enable(codec, enable, dapm); - else if (!strcmp(dev_name(codec->dev), "tavil_codec")) - ret = tavil_cdc_mclk_enable(codec, enable); - else { - dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", - __func__); - ret = -EINVAL; - } - return ret; -} - -static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, - int enable, bool dapm) -{ - int ret = 0; - - if (!strcmp(dev_name(codec->dev), "tasha_codec")) - ret = tasha_cdc_mclk_tx_enable(codec, enable, dapm); - else { - dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", - __func__); - ret = -EINVAL; - } - return ret; -} - -static int msm_mclk_tx_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - pr_debug("%s: event = %d\n", __func__, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - return msm_snd_enable_codec_ext_tx_clk(codec, 1, true); - case SND_SOC_DAPM_POST_PMD: - return msm_snd_enable_codec_ext_tx_clk(codec, 0, true); - } - return 0; -} - -static int msm_mclk_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - pr_debug("%s: event = %d\n", __func__, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - return msm_snd_enable_codec_ext_clk(codec, 1, true); - case SND_SOC_DAPM_POST_PMD: - return msm_snd_enable_codec_ext_clk(codec, 0, true); - } - return 0; -} - -static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct snd_soc_card *card = codec->component.card; - struct msm_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - - pr_debug("%s: msm_hifi_control = %d", __func__, msm_hifi_control); - - if (!pdata || !pdata->hph_en0_gpio_p) { - pr_err("%s: hph_en0_gpio is invalid\n", __func__); - return -EINVAL; - } - - if (msm_hifi_control != MSM_HIFI_ON) { - pr_debug("%s: HiFi mixer control is not set\n", - __func__); - return 0; - } - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - msm_cdc_pinctrl_select_active_state(pdata->hph_en0_gpio_p); - break; - case SND_SOC_DAPM_PRE_PMD: - msm_cdc_pinctrl_select_sleep_state(pdata->hph_en0_gpio_p); - break; - } - - return 0; -} - -static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { - - SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, - msm_mclk_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0, - msm_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SPK("Lineout_1 amp", NULL), - SND_SOC_DAPM_SPK("Lineout_3 amp", NULL), - SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), - SND_SOC_DAPM_SPK("Lineout_4 amp", NULL), - SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event), - SND_SOC_DAPM_MIC("Handset Mic", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), - SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL), - SND_SOC_DAPM_MIC("Analog Mic5", NULL), - SND_SOC_DAPM_MIC("Analog Mic6", NULL), - - SND_SOC_DAPM_MIC("Digital Mic0", NULL), - SND_SOC_DAPM_MIC("Digital Mic1", NULL), - SND_SOC_DAPM_MIC("Digital Mic2", NULL), - SND_SOC_DAPM_MIC("Digital Mic3", NULL), - SND_SOC_DAPM_MIC("Digital Mic4", NULL), - SND_SOC_DAPM_MIC("Digital Mic5", NULL), -}; - -static inline int param_is_mask(int p) -{ - return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && - (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); -} - -static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, - int n) -{ - return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); -} - -static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit) -{ - if (bit >= SNDRV_MASK_MAX) - return; - if (param_is_mask(n)) { - struct snd_mask *m = param_to_mask(p, n); - - m->bits[0] = 0; - m->bits[1] = 0; - m->bits[bit >> 5] |= (1 << (bit & 31)); - } -} - -static int msm_slim_get_ch_from_beid(int32_t be_id) -{ - int ch_id = 0; - - switch (be_id) { - case MSM_BACKEND_DAI_SLIMBUS_0_RX: - ch_id = SLIM_RX_0; - break; - case MSM_BACKEND_DAI_SLIMBUS_1_RX: - ch_id = SLIM_RX_1; - break; - case MSM_BACKEND_DAI_SLIMBUS_2_RX: - ch_id = SLIM_RX_2; - break; - case MSM_BACKEND_DAI_SLIMBUS_3_RX: - ch_id = SLIM_RX_3; - break; - case MSM_BACKEND_DAI_SLIMBUS_4_RX: - ch_id = SLIM_RX_4; - break; - case MSM_BACKEND_DAI_SLIMBUS_6_RX: - ch_id = SLIM_RX_6; - break; - case MSM_BACKEND_DAI_SLIMBUS_0_TX: - ch_id = SLIM_TX_0; - break; - case MSM_BACKEND_DAI_SLIMBUS_3_TX: - ch_id = SLIM_TX_3; - break; - default: - ch_id = SLIM_RX_0; - break; - } - - return ch_id; -} - -static int msm_ext_disp_get_idx_from_beid(int32_t be_id) -{ - int idx; - - switch (be_id) { - case MSM_BACKEND_DAI_HDMI_RX: - idx = HDMI_RX_IDX; - break; - case MSM_BACKEND_DAI_DISPLAY_PORT_RX: - idx = DP_RX_IDX; - break; - default: - pr_err("%s: Incorrect ext_disp BE id %d\n", __func__, be_id); - idx = -EINVAL; - break; - } - - return idx; -} - -static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_dai_link *dai_link = rtd->dai_link; - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - int rc = 0; - int idx; - void *config = NULL; - struct snd_soc_codec *codec = NULL; - - pr_debug("%s: format = %d, rate = %d\n", - __func__, params_format(params), params_rate(params)); - - switch (dai_link->id) { - case MSM_BACKEND_DAI_SLIMBUS_0_RX: - case MSM_BACKEND_DAI_SLIMBUS_1_RX: - case MSM_BACKEND_DAI_SLIMBUS_2_RX: - case MSM_BACKEND_DAI_SLIMBUS_3_RX: - case MSM_BACKEND_DAI_SLIMBUS_4_RX: - case MSM_BACKEND_DAI_SLIMBUS_6_RX: - idx = msm_slim_get_ch_from_beid(dai_link->id); - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_rx_cfg[idx].bit_format); - rate->min = rate->max = slim_rx_cfg[idx].sample_rate; - channels->min = channels->max = slim_rx_cfg[idx].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_0_TX: - case MSM_BACKEND_DAI_SLIMBUS_3_TX: - idx = msm_slim_get_ch_from_beid(dai_link->id); - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_tx_cfg[idx].bit_format); - rate->min = rate->max = slim_tx_cfg[idx].sample_rate; - channels->min = channels->max = slim_tx_cfg[idx].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_1_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_tx_cfg[1].bit_format); - rate->min = rate->max = slim_tx_cfg[1].sample_rate; - channels->min = channels->max = slim_tx_cfg[1].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_4_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - SNDRV_PCM_FORMAT_S32_LE); - rate->min = rate->max = SAMPLING_RATE_8KHZ; - channels->min = channels->max = msm_vi_feed_tx_ch; - break; - - case MSM_BACKEND_DAI_SLIMBUS_5_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_rx_cfg[5].bit_format); - rate->min = rate->max = slim_rx_cfg[5].sample_rate; - channels->min = channels->max = slim_rx_cfg[5].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_5_TX: - codec = rtd->codec; - rate->min = rate->max = SAMPLING_RATE_16KHZ; - channels->min = channels->max = 1; - - config = msm_codec_fn.get_afe_config_fn(codec, - AFE_SLIMBUS_SLAVE_PORT_CONFIG); - if (config) { - rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, - config, SLIMBUS_5_TX); - if (rc) - pr_err("%s: Failed to set slimbus slave port config %d\n", - __func__, rc); - } - break; - - case MSM_BACKEND_DAI_SLIMBUS_7_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_rx_cfg[SLIM_RX_7].bit_format); - rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate; - channels->min = channels->max = - slim_rx_cfg[SLIM_RX_7].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_7_TX: - rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate; - channels->min = channels->max = - slim_tx_cfg[SLIM_TX_7].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_8_TX: - rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate; - channels->min = channels->max = - slim_tx_cfg[SLIM_TX_8].channels; - break; - - case MSM_BACKEND_DAI_USB_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - usb_rx_cfg.bit_format); - rate->min = rate->max = usb_rx_cfg.sample_rate; - channels->min = channels->max = usb_rx_cfg.channels; - break; - - case MSM_BACKEND_DAI_USB_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - usb_tx_cfg.bit_format); - rate->min = rate->max = usb_tx_cfg.sample_rate; - channels->min = channels->max = usb_tx_cfg.channels; - break; - - case MSM_BACKEND_DAI_HDMI_RX: - case MSM_BACKEND_DAI_DISPLAY_PORT_RX: - idx = msm_ext_disp_get_idx_from_beid(dai_link->id); - if (idx < 0) { - pr_err("%s: Incorrect ext disp idx %d\n", - __func__, idx); - rc = idx; - goto done; - } - - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - ext_disp_rx_cfg[idx].bit_format); - rate->min = rate->max = ext_disp_rx_cfg[idx].sample_rate; - channels->min = channels->max = ext_disp_rx_cfg[idx].channels; - break; - - case MSM_BACKEND_DAI_AFE_PCM_RX: - channels->min = channels->max = proxy_rx_cfg.channels; - rate->min = rate->max = SAMPLING_RATE_48KHZ; - break; - - case MSM_BACKEND_DAI_PRI_TDM_RX_0: - channels->min = channels->max = - tdm_rx_cfg[TDM_PRI][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_PRI_TDM_TX_0: - channels->min = channels->max = - tdm_tx_cfg[TDM_PRI][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); - rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_SEC_TDM_RX_0: - channels->min = channels->max = - tdm_rx_cfg[TDM_SEC][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_SEC_TDM_TX_0: - channels->min = channels->max = - tdm_tx_cfg[TDM_SEC][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); - rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_TERT_TDM_RX_0: - channels->min = channels->max = - tdm_rx_cfg[TDM_TERT][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_TERT_TDM_TX_0: - channels->min = channels->max = - tdm_tx_cfg[TDM_TERT][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); - rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_QUAT_TDM_RX_0: - channels->min = channels->max = - tdm_rx_cfg[TDM_QUAT][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_QUAT_TDM_TX_0: - channels->min = channels->max = - tdm_tx_cfg[TDM_QUAT][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); - rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_AUXPCM_RX: - rate->min = rate->max = - aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_rx_cfg[PRIM_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_AUXPCM_TX: - rate->min = rate->max = - aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_tx_cfg[PRIM_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_SEC_AUXPCM_RX: - rate->min = rate->max = - aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_rx_cfg[SEC_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_SEC_AUXPCM_TX: - rate->min = rate->max = - aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_tx_cfg[SEC_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_TERT_AUXPCM_RX: - rate->min = rate->max = - aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_rx_cfg[TERT_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_TERT_AUXPCM_TX: - rate->min = rate->max = - aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_tx_cfg[TERT_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_QUAT_AUXPCM_RX: - rate->min = rate->max = - aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_rx_cfg[QUAT_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_QUAT_AUXPCM_TX: - rate->min = rate->max = - aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_tx_cfg[QUAT_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_PRI_MI2S_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_rx_cfg[PRIM_MI2S].bit_format); - rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate; - channels->min = channels->max = - mi2s_rx_cfg[PRIM_MI2S].channels; - break; - - case MSM_BACKEND_DAI_PRI_MI2S_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_tx_cfg[PRIM_MI2S].bit_format); - rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate; - channels->min = channels->max = - mi2s_tx_cfg[PRIM_MI2S].channels; - break; - - case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_rx_cfg[SEC_MI2S].bit_format); - rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate; - channels->min = channels->max = - mi2s_rx_cfg[SEC_MI2S].channels; - break; - - case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_tx_cfg[SEC_MI2S].bit_format); - rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate; - channels->min = channels->max = - mi2s_tx_cfg[SEC_MI2S].channels; - break; - - case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_rx_cfg[TERT_MI2S].bit_format); - rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate; - channels->min = channels->max = - mi2s_rx_cfg[TERT_MI2S].channels; - break; - - case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_tx_cfg[TERT_MI2S].bit_format); - rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate; - channels->min = channels->max = - mi2s_tx_cfg[TERT_MI2S].channels; - break; - - case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_rx_cfg[QUAT_MI2S].bit_format); - rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate; - channels->min = channels->max = - mi2s_rx_cfg[QUAT_MI2S].channels; - break; - - case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_tx_cfg[QUAT_MI2S].bit_format); - rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate; - channels->min = channels->max = - mi2s_tx_cfg[QUAT_MI2S].channels; - break; - - default: - rate->min = rate->max = SAMPLING_RATE_48KHZ; - break; - } - -done: - return rc; -} - -static bool msm_swap_gnd_mic(struct snd_soc_codec *codec) -{ - struct snd_soc_card *card = codec->component.card; - struct msm_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - int value = 0; - - if (pdata->us_euro_gpio_p) { - value = msm_cdc_pinctrl_get_state(pdata->us_euro_gpio_p); - if (value) - msm_cdc_pinctrl_select_sleep_state( - pdata->us_euro_gpio_p); - else - msm_cdc_pinctrl_select_active_state( - pdata->us_euro_gpio_p); - } else if (pdata->us_euro_gpio >= 0) { - value = gpio_get_value_cansleep(pdata->us_euro_gpio); - gpio_set_value_cansleep(pdata->us_euro_gpio, !value); - } - pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value); - return true; -} - -static int msm_afe_set_config(struct snd_soc_codec *codec) -{ - int ret = 0; - void *config_data = NULL; - - if (!msm_codec_fn.get_afe_config_fn) { - dev_err(codec->dev, "%s: codec get afe config not init'ed\n", - __func__); - return -EINVAL; - } - - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_CDC_REGISTERS_CONFIG); - if (config_data) { - ret = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0); - if (ret) { - dev_err(codec->dev, - "%s: Failed to set codec registers config %d\n", - __func__, ret); - return ret; - } - } - - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_CDC_REGISTER_PAGE_CONFIG); - if (config_data) { - ret = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, - 0); - if (ret) - dev_err(codec->dev, - "%s: Failed to set cdc register page config\n", - __func__); - } - - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_SLIMBUS_SLAVE_CONFIG); - if (config_data) { - ret = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0); - if (ret) { - dev_err(codec->dev, - "%s: Failed to set slimbus slave config %d\n", - __func__, ret); - return ret; - } - } - - return 0; -} - -static void msm_afe_clear_config(void) -{ - afe_clear_config(AFE_CDC_REGISTERS_CONFIG); - afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); -} - -static int msm_adsp_power_up_config(struct snd_soc_codec *codec) -{ - int ret = 0; - unsigned long timeout; - int adsp_ready = 0; - - timeout = jiffies + - msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); - - do { - if (q6core_is_adsp_ready()) { - pr_debug("%s: ADSP Audio is ready\n", __func__); - adsp_ready = 1; - break; - } - /* - * ADSP will be coming up after subsystem restart and - * it might not be fully up when the control reaches - * here. So, wait for 50msec before checking ADSP state - */ - msleep(50); - } while (time_after(timeout, jiffies)); - - if (!adsp_ready) { - pr_err("%s: timed out waiting for ADSP Audio\n", __func__); - ret = -ETIMEDOUT; - goto err_fail; - } - - ret = msm_afe_set_config(codec); - if (ret) - pr_err("%s: Failed to set AFE config. err %d\n", - __func__, ret); - - return 0; - -err_fail: - return ret; -} - -static int msm8998_notifier_service_cb(struct notifier_block *this, - unsigned long opcode, void *ptr) -{ - int ret; - struct snd_soc_card *card = NULL; - const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; - struct snd_soc_pcm_runtime *rtd; - struct snd_soc_codec *codec; - - pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); - - switch (opcode) { - case AUDIO_NOTIFIER_SERVICE_DOWN: - /* - * Use flag to ignore initial boot notifications - * On initial boot msm_adsp_power_up_config is - * called on init. There is no need to clear - * and set the config again on initial boot. - */ - if (is_initial_boot) - break; - msm_afe_clear_config(); - break; - case AUDIO_NOTIFIER_SERVICE_UP: - if (is_initial_boot) { - is_initial_boot = false; - break; - } - if (!spdev) - return -EINVAL; - - card = platform_get_drvdata(spdev); - rtd = snd_soc_get_pcm_runtime(card, be_dl_name); - if (!rtd) { - dev_err(card->dev, - "%s: snd_soc_get_pcm_runtime for %s failed!\n", - __func__, be_dl_name); - ret = -EINVAL; - goto done; - } - codec = rtd->codec; - - ret = msm_adsp_power_up_config(codec); - if (ret < 0) { - dev_err(card->dev, - "%s: msm_adsp_power_up_config failed ret = %d!\n", - __func__, ret); - goto done; - } - break; - default: - break; - } -done: - return NOTIFY_OK; -} - -static struct notifier_block service_nb = { - .notifier_call = msm8998_notifier_service_cb, - .priority = -INT_MAX, -}; - -static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret = 0; - void *config_data; - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_component *aux_comp; - struct snd_card *card; - struct snd_info_entry *entry; - struct msm_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(rtd->card); - - /* Codec SLIMBUS configuration - * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13 - * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 - * TX14, TX15, TX16 - */ - unsigned int rx_ch[TASHA_RX_MAX] = {144, 145, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156}; - unsigned int tx_ch[TASHA_TX_MAX] = {128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143}; - - /* Tavil Codec SLIMBUS configuration - * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8 - * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 - * TX14, TX15, TX16 - */ - unsigned int rx_ch_tavil[WCD934X_RX_MAX] = {144, 145, 146, 147, 148, - 149, 150, 151}; - unsigned int tx_ch_tavil[WCD934X_TX_MAX] = {128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, - 143}; - - pr_info("%s: dev_name%s\n", __func__, dev_name(cpu_dai->dev)); - - rtd->pmdown_time = 0; - - ret = snd_soc_add_codec_controls(codec, msm_snd_controls, - ARRAY_SIZE(msm_snd_controls)); - if (ret < 0) { - pr_err("%s: add_codec_controls failed, err %d\n", - __func__, ret); - return ret; - } - - snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, - ARRAY_SIZE(msm_dapm_widgets)); - - if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) - snd_soc_dapm_add_routes(dapm, wcd_audio_paths_tasha, - ARRAY_SIZE(wcd_audio_paths_tasha)); - else - snd_soc_dapm_add_routes(dapm, wcd_audio_paths, - ARRAY_SIZE(wcd_audio_paths)); - - snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic5"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6"); - snd_soc_dapm_ignore_suspend(dapm, "MADINPUT"); - snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT"); - snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT1"); - snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT2"); - snd_soc_dapm_ignore_suspend(dapm, "EAR"); - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1"); - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2"); - snd_soc_dapm_ignore_suspend(dapm, "ANC EAR"); - snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); - snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); - snd_soc_dapm_ignore_suspend(dapm, "HPHL"); - snd_soc_dapm_ignore_suspend(dapm, "HPHR"); - snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); - snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); - snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL"); - snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR"); - - if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) { - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3"); - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4"); - snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT1"); - snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT2"); - } - - snd_soc_dapm_sync(dapm); - - if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { - snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch_tavil), - tx_ch_tavil, ARRAY_SIZE(rx_ch_tavil), - rx_ch_tavil); - } else { - snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), - tx_ch, ARRAY_SIZE(rx_ch), - rx_ch); - } - - if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { - msm_codec_fn.get_afe_config_fn = tavil_get_afe_config; - } else { - msm_codec_fn.get_afe_config_fn = tasha_get_afe_config; - msm_codec_fn.mbhc_hs_detect_exit = tasha_mbhc_hs_detect_exit; - } - - ret = msm_adsp_power_up_config(codec); - if (ret) { - pr_err("%s: Failed to set AFE config %d\n", __func__, ret); - goto err_afe_cfg; - } - - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_AANC_VERSION); - if (config_data) { - ret = afe_set_config(AFE_AANC_VERSION, config_data, 0); - if (ret) { - pr_err("%s: Failed to set aanc version %d\n", - __func__, ret); - goto err_afe_cfg; - } - } - - if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) { - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_CDC_CLIP_REGISTERS_CONFIG); - if (config_data) { - ret = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG, - config_data, 0); - if (ret) { - pr_err("%s: Failed to set clip registers %d\n", - __func__, ret); - goto err_afe_cfg; - } - } - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_CLIP_BANK_SEL); - if (config_data) { - ret = afe_set_config(AFE_CLIP_BANK_SEL, config_data, 0); - if (ret) { - pr_err("%s: Failed to set AFE bank selection %d\n", - __func__, ret); - goto err_afe_cfg; - } - } - } - - /* - * Send speaker configuration only for WSA8810. - * Defalut configuration is for WSA8815. - */ - pr_debug("%s: Number of aux devices: %d\n", - __func__, rtd->card->num_aux_devs); - if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { - if (rtd->card->num_aux_devs && - !list_empty(&rtd->card->aux_comp_list)) { - aux_comp = list_first_entry(&rtd->card->aux_comp_list, - struct snd_soc_component, list_aux); - if (!strcmp(aux_comp->name, WSA8810_NAME_1) || - !strcmp(aux_comp->name, WSA8810_NAME_2)) { - tavil_set_spkr_mode(rtd->codec, - WCD934X_SPKR_MODE_1); - tavil_set_spkr_gain_offset(rtd->codec, - WCD934X_RX_GAIN_OFFSET_M1P5_DB); - } - } - card = rtd->card->snd_card; - entry = snd_info_create_subdir(card->module, "codecs", - card->proc_root); - if (!entry) { - pr_debug("%s: Cannot create codecs module entry\n", - __func__); - pdata->codec_root = NULL; - goto done; - } - pdata->codec_root = entry; - tavil_codec_info_create_codec_entry(pdata->codec_root, codec); - } else { - if (rtd->card->num_aux_devs && - !list_empty(&rtd->card->aux_comp_list)) { - aux_comp = list_first_entry(&rtd->card->aux_comp_list, - struct snd_soc_component, list_aux); - if (!strcmp(aux_comp->name, WSA8810_NAME_1) || - !strcmp(aux_comp->name, WSA8810_NAME_2)) { - tasha_set_spkr_mode(rtd->codec, SPKR_MODE_1); - tasha_set_spkr_gain_offset(rtd->codec, - RX_GAIN_OFFSET_M1P5_DB); - } - } - card = rtd->card->snd_card; - entry = snd_info_create_subdir(card->module, "codecs", - card->proc_root); - if (!entry) { - pr_debug("%s: Cannot create codecs module entry\n", - __func__); - ret = 0; - goto err_snd_module; - } - pdata->codec_root = entry; - tasha_codec_info_create_codec_entry(pdata->codec_root, codec); - } -done: - codec_reg_done = true; - return 0; - -err_snd_module: -err_afe_cfg: - return ret; -} - -static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) -{ - unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; - unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - - return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), - tx_ch, ARRAY_SIZE(rx_ch), rx_ch); -} - -static void *def_tasha_mbhc_cal(void) -{ - void *tasha_wcd_cal; - struct wcd_mbhc_btn_detect_cfg *btn_cfg; - u16 *btn_high; - - tasha_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, - WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); - if (!tasha_wcd_cal) - return NULL; - -#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(tasha_wcd_cal)->X) = (Y)) - S(v_hs_max, 1600); -#undef S -#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(tasha_wcd_cal)->X) = (Y)) - S(num_btn, WCD_MBHC_DEF_BUTTONS); -#undef S - - btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(tasha_wcd_cal); - btn_high = ((void *)&btn_cfg->_v_btn_low) + - (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); - - btn_high[0] = 75; - btn_high[1] = 150; - btn_high[2] = 237; - btn_high[3] = 500; - btn_high[4] = 500; - btn_high[5] = 500; - btn_high[6] = 500; - btn_high[7] = 500; - - return tasha_wcd_cal; -} - -static void *def_tavil_mbhc_cal(void) -{ - void *tavil_wcd_cal; - struct wcd_mbhc_btn_detect_cfg *btn_cfg; - u16 *btn_high; - - tavil_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, - WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); - if (!tavil_wcd_cal) - return NULL; - -#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(tavil_wcd_cal)->X) = (Y)) - S(v_hs_max, 1600); -#undef S -#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal)->X) = (Y)) - S(num_btn, WCD_MBHC_DEF_BUTTONS); -#undef S - - btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal); - btn_high = ((void *)&btn_cfg->_v_btn_low) + - (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); - - btn_high[0] = 75; - btn_high[1] = 150; - btn_high[2] = 237; - btn_high[3] = 500; - btn_high[4] = 500; - btn_high[5] = 500; - btn_high[6] = 500; - btn_high[7] = 500; - - return tavil_wcd_cal; -} - -static int msm_snd_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai_link *dai_link = rtd->dai_link; - - int ret = 0; - u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; - u32 rx_ch_cnt = 0, tx_ch_cnt = 0; - u32 user_set_tx_ch = 0; - u32 rx_ch_count; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map, err:%d\n", - __func__, ret); - goto err_ch_map; - } - if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_5_RX) { - pr_debug("%s: rx_5_ch=%d\n", __func__, - slim_rx_cfg[5].channels); - rx_ch_count = slim_rx_cfg[5].channels; - } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_2_RX) { - pr_debug("%s: rx_2_ch=%d\n", __func__, - slim_rx_cfg[2].channels); - rx_ch_count = slim_rx_cfg[2].channels; - } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_6_RX) { - pr_debug("%s: rx_6_ch=%d\n", __func__, - slim_rx_cfg[6].channels); - rx_ch_count = slim_rx_cfg[6].channels; - } else { - pr_debug("%s: rx_0_ch=%d\n", __func__, - slim_rx_cfg[0].channels); - rx_ch_count = slim_rx_cfg[0].channels; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, - rx_ch_count, rx_ch); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto err_ch_map; - } - } else { - - pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__, - codec_dai->name, codec_dai->id, user_set_tx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map\n, err:%d\n", - __func__, ret); - goto err_ch_map; - } - /* For _tx1 case */ - if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_0_TX) - user_set_tx_ch = slim_tx_cfg[0].channels; - /* For _tx3 case */ - else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_1_TX) - user_set_tx_ch = slim_tx_cfg[1].channels; - else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_4_TX) - user_set_tx_ch = msm_vi_feed_tx_ch; - else - user_set_tx_ch = tx_ch_cnt; - - pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), BE id (%d)\n", - __func__, slim_tx_cfg[0].channels, user_set_tx_ch, - tx_ch_cnt, dai_link->id); - - ret = snd_soc_dai_set_channel_map(cpu_dai, - user_set_tx_ch, tx_ch, 0, 0); - if (ret < 0) - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - } - -err_ch_map: - return ret; -} - -static int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai_link *dai_link = rtd->dai_link; - - int ret = 0; - u32 tx_ch[SLIM_MAX_TX_PORTS]; - u32 tx_ch_cnt = 0; - u32 user_set_tx_ch = 0; - - if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) { - pr_err("%s: Invalid stream type %d\n", - __func__, substream->stream); - ret = -EINVAL; - goto err_stream_type; - } - - pr_debug("%s: %s_tx_dai_id_%d\n", __func__, - codec_dai->name, codec_dai->id); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, NULL, NULL); - if (ret < 0) { - pr_err("%s: failed to get codec chan map\n, err:%d\n", - __func__, ret); - goto err_ch_map; - } - - user_set_tx_ch = tx_ch_cnt; - - pr_debug("%s: tx_ch_cnt(%d) BE id %d\n", - __func__, tx_ch_cnt, dai_link->id); - - ret = snd_soc_dai_set_channel_map(cpu_dai, - user_set_tx_ch, tx_ch, 0, 0); - if (ret < 0) - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); -err_ch_map: -err_stream_type: - return ret; -} - -static int msm_slimbus_2_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; - unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0; - unsigned int num_tx_ch = 0; - unsigned int num_rx_ch = 0; - int ret = 0; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - num_rx_ch = params_channels(params); - pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__, - codec_dai->name, codec_dai->id, num_rx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map, err:%d\n", - __func__, ret); - goto err_ch_map; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, - num_rx_ch, rx_ch); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto err_ch_map; - } - } else { - num_tx_ch = params_channels(params); - pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__, - codec_dai->name, codec_dai->id, num_tx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map, err:%d\n", - __func__, ret); - goto err_ch_map; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, - num_tx_ch, tx_ch, 0, 0); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto err_ch_map; - } - } - -err_ch_map: - return ret; -} - -static int msm_wcn_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai_link *dai_link = rtd->dai_link; - u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; - u32 rx_ch_cnt = 0, tx_ch_cnt = 0; - int ret; - - dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, - codec_dai->name, codec_dai->id); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret) { - dev_err(rtd->dev, - "%s: failed to get BTFM codec chan map\n, err:%d\n", - __func__, ret); - goto exit; - } - - dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) BE id %d\n", - __func__, tx_ch_cnt, dai_link->id); - - ret = snd_soc_dai_set_channel_map(cpu_dai, - tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); - if (ret) - dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - -exit: - return ret; -} - -static int msm_aux_pcm_snd_startup(struct snd_pcm_substream *substream) -{ - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int index = cpu_dai->id - 1; - - dev_dbg(rtd->card->dev, - "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", - __func__, substream->name, substream->stream, - cpu_dai->name, cpu_dai->id); - - if (index < PRIM_AUX_PCM || index > QUAT_AUX_PCM) { - ret = -EINVAL; - dev_err(rtd->card->dev, - "%s: CPU DAI id (%d) out of range\n", - __func__, cpu_dai->id); - goto done; - } - - mutex_lock(&auxpcm_intf_conf[index].lock); - if (++auxpcm_intf_conf[index].ref_cnt == 1) { - if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) { - mutex_lock(&mi2s_auxpcm_conf[index].lock); - iowrite32(1, - mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr); - mutex_unlock(&mi2s_auxpcm_conf[index].lock); - } else { - dev_err(rtd->card->dev, - "%s lpaif_tert_muxsel_virt_addr is NULL\n", - __func__); - ret = -EINVAL; - } - } - if (ret < 0) - auxpcm_intf_conf[index].ref_cnt--; - - mutex_unlock(&auxpcm_intf_conf[index].lock); - -done: - return ret; -} - -static void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - int index = rtd->cpu_dai->id - 1; - - dev_dbg(rtd->card->dev, - "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", - __func__, - substream->name, substream->stream, - rtd->cpu_dai->name, rtd->cpu_dai->id); - - if (index < PRIM_AUX_PCM || index > QUAT_AUX_PCM) { - dev_err(rtd->card->dev, - "%s: CPU DAI id (%d) out of range\n", - __func__, rtd->cpu_dai->id); - return; - } - - mutex_lock(&auxpcm_intf_conf[index].lock); - if (--auxpcm_intf_conf[index].ref_cnt == 0) { - if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) { - mutex_lock(&mi2s_auxpcm_conf[index].lock); - iowrite32(0, - mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr); - mutex_unlock(&mi2s_auxpcm_conf[index].lock); - } else { - dev_err(rtd->card->dev, - "%s lpaif_tert_muxsel_virt_addr is NULL\n", - __func__); - } - } - mutex_unlock(&auxpcm_intf_conf[index].lock); -} - -static int msm_get_port_id(int be_id) -{ - int afe_port_id; - - switch (be_id) { - case MSM_BACKEND_DAI_PRI_MI2S_RX: - afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; - break; - case MSM_BACKEND_DAI_PRI_MI2S_TX: - afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; - break; - case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: - afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; - break; - case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: - afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; - break; - case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: - afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; - break; - case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: - afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; - break; - case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: - afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; - break; - case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: - afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; - break; - default: - pr_err("%s: Invalid BE id: %d\n", __func__, be_id); - afe_port_id = -EINVAL; - } - - return afe_port_id; -} - -static u32 get_mi2s_bits_per_sample(u32 bit_format) -{ - u32 bit_per_sample; - - switch (bit_format) { - case SNDRV_PCM_FORMAT_S32_LE: - case SNDRV_PCM_FORMAT_S24_3LE: - case SNDRV_PCM_FORMAT_S24_LE: - bit_per_sample = 32; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - bit_per_sample = 16; - break; - } - - return bit_per_sample; -} - -static void update_mi2s_clk_val(int dai_id, int stream) -{ - u32 bit_per_sample; - - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - bit_per_sample = - get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format); - mi2s_clk[dai_id].clk_freq_in_hz = - mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample; - } else { - bit_per_sample = - get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format); - mi2s_clk[dai_id].clk_freq_in_hz = - mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample; - } -} - -static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) -{ - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int port_id = 0; - int index = cpu_dai->id; - - port_id = msm_get_port_id(rtd->dai_link->id); - if (port_id < 0) { - dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); - ret = port_id; - goto done; - } - - if (enable) { - update_mi2s_clk_val(index, substream->stream); - dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, - mi2s_clk[index].clk_freq_in_hz); - } - - mi2s_clk[index].enable = enable; - ret = afe_set_lpass_clock_v2(port_id, - &mi2s_clk[index]); - if (ret < 0) { - dev_err(rtd->card->dev, - "%s: afe lpass clock failed for port 0x%x , err:%d\n", - __func__, port_id, ret); - goto done; - } - -done: - return ret; -} - -static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, - enum pinctrl_pin_state new_state) -{ - int ret = 0; - int curr_state = 0; - - if (pinctrl_info == NULL) { - pr_err("%s: pinctrl_info is NULL\n", __func__); - ret = -EINVAL; - goto err; - } - - if (pinctrl_info->pinctrl == NULL) { - pr_err("%s: pinctrl_info->pinctrl is NULL\n", __func__); - ret = -EINVAL; - goto err; - } - - curr_state = pinctrl_info->curr_state; - pinctrl_info->curr_state = new_state; - pr_debug("%s: curr_state = %s new_state = %s\n", __func__, - pin_states[curr_state], pin_states[pinctrl_info->curr_state]); - - if (curr_state == pinctrl_info->curr_state) { - pr_debug("%s: Already in same state\n", __func__); - goto err; - } - - if (curr_state != STATE_DISABLE && - pinctrl_info->curr_state != STATE_DISABLE) { - pr_debug("%s: state already active cannot switch\n", __func__); - ret = -EIO; - goto err; - } - - switch (pinctrl_info->curr_state) { - case STATE_MI2S_ACTIVE: - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_active); - if (ret) { - pr_err("%s: MI2S state select failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - break; - case STATE_TDM_ACTIVE: - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->tdm_active); - if (ret) { - pr_err("%s: TDM state select failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - break; - case STATE_DISABLE: - if (curr_state == STATE_MI2S_ACTIVE) { - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_disable); - } else { - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->tdm_disable); - } - if (ret) { - pr_err("%s: state disable failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - break; - default: - pr_err("%s: TLMM pin state is invalid\n", __func__); - return -EINVAL; - } - -err: - return ret; -} - -static void msm_release_pinctrl(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - - if (pinctrl_info->pinctrl) { - devm_pinctrl_put(pinctrl_info->pinctrl); - pinctrl_info->pinctrl = NULL; - } -} - -static int msm_get_pinctrl(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = NULL; - struct pinctrl *pinctrl; - int ret; - - pinctrl_info = &pdata->pinctrl_info; - - if (pinctrl_info == NULL) { - pr_err("%s: pinctrl_info is NULL\n", __func__); - return -EINVAL; - } - - pinctrl = devm_pinctrl_get(&pdev->dev); - if (IS_ERR_OR_NULL(pinctrl)) { - pr_err("%s: Unable to get pinctrl handle\n", __func__); - return -EINVAL; - } - pinctrl_info->pinctrl = pinctrl; - - /* get all the states handles from Device Tree */ - pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl, - "quat-mi2s-sleep"); - if (IS_ERR(pinctrl_info->mi2s_disable)) { - pr_err("%s: could not get mi2s_disable pinstate\n", __func__); - goto err; - } - pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl, - "quat-mi2s-active"); - if (IS_ERR(pinctrl_info->mi2s_active)) { - pr_err("%s: could not get mi2s_active pinstate\n", __func__); - goto err; - } - pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl, - "quat-tdm-sleep"); - if (IS_ERR(pinctrl_info->tdm_disable)) { - pr_err("%s: could not get tdm_disable pinstate\n", __func__); - goto err; - } - pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl, - "quat-tdm-active"); - if (IS_ERR(pinctrl_info->tdm_active)) { - pr_err("%s: could not get tdm_active pinstate\n", - __func__); - goto err; - } - /* Reset the TLMM pins to a default state */ - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_disable); - if (ret != 0) { - pr_err("%s: Disable TLMM pins failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - pinctrl_info->curr_state = STATE_DISABLE; - - return 0; - -err: - devm_pinctrl_put(pinctrl); - pinctrl_info->pinctrl = NULL; - return -EINVAL; -} - -static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - if (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) { - channels->min = channels->max = - tdm_rx_cfg[TDM_QUAT][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); - rate->min = rate->max = - tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; - } else if (cpu_dai->id == AFE_PORT_ID_SECONDARY_TDM_RX) { - channels->min = channels->max = - tdm_rx_cfg[TDM_SEC][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; - } else { - pr_err("%s: dai id 0x%x not supported\n", - __func__, cpu_dai->id); - return -EINVAL; - } - - pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n", - __func__, cpu_dai->id, channels->max, rate->max, - params_format(params)); - - return 0; -} - -static int msm8998_tdm_snd_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret = 0; - int channels, slot_width, slots; - unsigned int slot_mask; - unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; - - pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); - - slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; - /*2 slot config - bits 0 and 1 set for the first two slots */ - slot_mask = 0x0000FFFF >> (16-slots); - slot_width = 32; - channels = slots; - - pr_debug("%s: slot_width %d slots %d\n", __func__, slot_width, slots); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - pr_debug("%s: slot_width %d\n", __func__, slot_width); - ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, - slots, slot_width); - if (ret < 0) { - pr_err("%s: failed to set tdm slot, err:%d\n", - __func__, ret); - goto end; - } - - ret = snd_soc_dai_set_channel_map(cpu_dai, - 0, NULL, channels, slot_offset); - if (ret < 0) { - pr_err("%s: failed to set channel map, err:%d\n", - __func__, ret); - goto end; - } - } else { - pr_err("%s: invalid use case, err:%d\n", - __func__, ret); - } - -end: - return ret; -} - -static int msm8998_tdm_snd_startup(struct snd_pcm_substream *substream) -{ - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_card *card = rtd->card; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - - ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); - if (ret) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret); - - return ret; -} - -static void msm8998_tdm_snd_shutdown(struct snd_pcm_substream *substream) -{ - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_card *card = rtd->card; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - - ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); - if (ret) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret); - -} - -static struct snd_soc_ops msm8998_tdm_be_ops = { - .hw_params = msm8998_tdm_snd_hw_params, - .startup = msm8998_tdm_snd_startup, - .shutdown = msm8998_tdm_snd_shutdown -}; - -static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) -{ - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int index = cpu_dai->id; - unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; - struct snd_soc_card *card = rtd->card; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - int ret_pinctrl = 0; - - dev_dbg(rtd->card->dev, - "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", - __func__, substream->name, substream->stream, - cpu_dai->name, cpu_dai->id); - - if (index < PRIM_MI2S || index > QUAT_MI2S) { - ret = -EINVAL; - dev_err(rtd->card->dev, - "%s: CPU DAI id (%d) out of range\n", - __func__, cpu_dai->id); - goto done; - } - if (index == QUAT_MI2S) { - ret_pinctrl = msm_set_pinctrl(pinctrl_info, STATE_MI2S_ACTIVE); - if (ret_pinctrl) { - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); - } - } - - /* - * Muxtex protection in case the same MI2S - * interface using for both TX and RX so - * that the same clock won't be enable twice. - */ - mutex_lock(&mi2s_intf_conf[index].lock); - if (++mi2s_intf_conf[index].ref_cnt == 1) { - ret = msm_mi2s_set_sclk(substream, true); - if (ret < 0) { - dev_err(rtd->card->dev, - "%s: afe lpass clock failed to enable MI2S clock, err:%d\n", - __func__, ret); - goto clean_up; - } - if (mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr != NULL) { - mutex_lock(&mi2s_auxpcm_conf[index].lock); - iowrite32(0, - mi2s_auxpcm_conf[index].pcm_i2s_sel_vt_addr); - mutex_unlock(&mi2s_auxpcm_conf[index].lock); - } else { - dev_err(rtd->card->dev, - "%s lpaif_muxsel_virt_addr is NULL for dai %d\n", - __func__, index); - ret = -EINVAL; - goto clk_off; - } - /* Check if msm needs to provide the clock to the interface */ - if (!mi2s_intf_conf[index].msm_is_mi2s_master) - fmt = SND_SOC_DAIFMT_CBM_CFM; - ret = snd_soc_dai_set_fmt(cpu_dai, fmt); - if (ret < 0) { - pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n", - __func__, index, ret); - goto clk_off; - } - } -clk_off: - if (ret < 0) - msm_mi2s_set_sclk(substream, false); -clean_up: - if (ret < 0) - mi2s_intf_conf[index].ref_cnt--; - mutex_unlock(&mi2s_intf_conf[index].lock); -done: - return ret; -} - -static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) -{ - int ret; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - int index = rtd->cpu_dai->id; - struct snd_soc_card *card = rtd->card; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - int ret_pinctrl = 0; - - pr_debug("%s(): substream = %s stream = %d\n", __func__, - substream->name, substream->stream); - if (index < PRIM_MI2S || index > QUAT_MI2S) { - pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); - return; - } - - mutex_lock(&mi2s_intf_conf[index].lock); - if (--mi2s_intf_conf[index].ref_cnt == 0) { - ret = msm_mi2s_set_sclk(substream, false); - if (ret < 0) - pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", - __func__, index, ret); - } - mutex_unlock(&mi2s_intf_conf[index].lock); - - if (index == QUAT_MI2S) { - ret_pinctrl = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); - } -} - -static struct snd_soc_ops msm_mi2s_be_ops = { - .startup = msm_mi2s_snd_startup, - .shutdown = msm_mi2s_snd_shutdown, -}; - -static struct snd_soc_ops msm_aux_pcm_be_ops = { - .startup = msm_aux_pcm_snd_startup, - .shutdown = msm_aux_pcm_snd_shutdown, -}; - -static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width, - int slots) -{ - unsigned int slot_mask = 0; - int i, j; - unsigned int *slot_offset; - - for (i = TDM_0; i < TDM_PORT_MAX; i++) { - slot_offset = tdm_slot_offset[i]; - - for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) { - if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID) - slot_mask |= - (1 << ((slot_offset[j] * 8) / slot_width)); - else - break; - } - } - - return slot_mask; -} - -static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret = 0; - int channels, slot_width, slots; - unsigned int slot_mask; - unsigned int *slot_offset; - int offset_channels = 0; - int i; - - pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); - - channels = params_channels(params); - switch (channels) { - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S32_LE: - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S16_LE: - /* - * up to 8 channels HW config should - * use 32 bit slot width for max support of - * stream bit width. (slot_width > bit_width) - */ - slot_width = 32; - break; - default: - pr_err("%s: invalid param format 0x%x\n", - __func__, params_format(params)); - return -EINVAL; - } - slots = 8; - slot_mask = tdm_param_set_slot_mask(cpu_dai->id, - slot_width, - slots); - if (!slot_mask) { - pr_err("%s: invalid slot_mask 0x%x\n", - __func__, slot_mask); - return -EINVAL; - } - break; - default: - pr_err("%s: invalid param channels %d\n", - __func__, channels); - return -EINVAL; - } - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - switch (cpu_dai->id) { - case AFE_PORT_ID_PRIMARY_TDM_RX: - case AFE_PORT_ID_SECONDARY_TDM_RX: - case AFE_PORT_ID_TERTIARY_TDM_RX: - case AFE_PORT_ID_QUATERNARY_TDM_RX: - case AFE_PORT_ID_PRIMARY_TDM_TX: - case AFE_PORT_ID_SECONDARY_TDM_TX: - case AFE_PORT_ID_TERTIARY_TDM_TX: - case AFE_PORT_ID_QUATERNARY_TDM_TX: - slot_offset = tdm_slot_offset[TDM_0]; - break; - default: - pr_err("%s: dai id 0x%x not supported\n", - __func__, cpu_dai->id); - return -EINVAL; - } - - for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { - if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) - offset_channels++; - else - break; - } - - if (offset_channels == 0) { - pr_err("%s: slot offset not supported, offset_channels %d\n", - __func__, offset_channels); - return -EINVAL; - } - - if (channels > offset_channels) { - pr_err("%s: channels %d exceed offset_channels %d\n", - __func__, channels, offset_channels); - return -EINVAL; - } - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, - slots, slot_width); - if (ret < 0) { - pr_err("%s: failed to set tdm slot, err:%d\n", - __func__, ret); - goto end; - } - - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, - channels, slot_offset); - if (ret < 0) { - pr_err("%s: failed to set channel map, err:%d\n", - __func__, ret); - goto end; - } - } else { - ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, - slots, slot_width); - if (ret < 0) { - pr_err("%s: failed to set tdm slot, err:%d\n", - __func__, ret); - goto end; - } - - ret = snd_soc_dai_set_channel_map(cpu_dai, channels, - slot_offset, 0, NULL); - if (ret < 0) { - pr_err("%s: failed to set channel map, err:%d\n", - __func__, ret); - goto end; - } - } -end: - return ret; -} - -static struct snd_soc_ops msm_be_ops = { - .hw_params = msm_snd_hw_params, -}; - -static struct snd_soc_ops msm_cpe_ops = { - .hw_params = msm_snd_cpe_hw_params, -}; - -static struct snd_soc_ops msm_slimbus_2_be_ops = { - .hw_params = msm_slimbus_2_hw_params, -}; - -static struct snd_soc_ops msm_wcn_ops = { - .hw_params = msm_wcn_hw_params, -}; - -static struct snd_soc_ops msm_tdm_be_ops = { - .hw_params = msm_tdm_snd_hw_params -}; - -/* Digital audio interface glue - connects codec <---> CPU */ -static struct snd_soc_dai_link msm_common_dai_links[] = { - /* FrontEnd DAI Links */ - { - .name = MSM_DAILINK_NAME(Media1), - .stream_name = "MultiMedia1", - .cpu_dai_name = "MultiMedia1", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA1 - }, - { - .name = MSM_DAILINK_NAME(Media2), - .stream_name = "MultiMedia2", - .cpu_dai_name = "MultiMedia2", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA2, - }, - { - .name = "VoiceMMode1", - .stream_name = "VoiceMMode1", - .cpu_dai_name = "VoiceMMode1", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_VOICEMMODE1, - }, - { - .name = "MSM VoIP", - .stream_name = "VoIP", - .cpu_dai_name = "VoIP", - .platform_name = "msm-voip-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_VOIP, - }, - { - .name = MSM_DAILINK_NAME(ULL), - .stream_name = "MultiMedia3", - .cpu_dai_name = "MultiMedia3", - .platform_name = "msm-pcm-dsp.2", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA3, - }, - /* Hostless PCM purpose */ - { - .name = "SLIMBUS_0 Hostless", - .stream_name = "SLIMBUS_0 Hostless", - .cpu_dai_name = "SLIMBUS0_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "MSM AFE-PCM RX", - .stream_name = "AFE-PROXY RX", - .cpu_dai_name = "msm-dai-q6-dev.241", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .platform_name = "msm-pcm-afe", - .dpcm_playback = 1, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - }, - { - .name = "MSM AFE-PCM TX", - .stream_name = "AFE-PROXY TX", - .cpu_dai_name = "msm-dai-q6-dev.240", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .platform_name = "msm-pcm-afe", - .dpcm_capture = 1, - .ignore_suspend = 1, - }, - { - .name = MSM_DAILINK_NAME(Compress1), - .stream_name = "Compress1", - .cpu_dai_name = "MultiMedia4", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA4, - }, - { - .name = "AUXPCM Hostless", - .stream_name = "AUXPCM Hostless", - .cpu_dai_name = "AUXPCM_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "SLIMBUS_1 Hostless", - .stream_name = "SLIMBUS_1 Hostless", - .cpu_dai_name = "SLIMBUS1_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "SLIMBUS_3 Hostless", - .stream_name = "SLIMBUS_3 Hostless", - .cpu_dai_name = "SLIMBUS3_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "SLIMBUS_4 Hostless", - .stream_name = "SLIMBUS_4 Hostless", - .cpu_dai_name = "SLIMBUS4_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = MSM_DAILINK_NAME(LowLatency), - .stream_name = "MultiMedia5", - .cpu_dai_name = "MultiMedia5", - .platform_name = "msm-pcm-dsp.1", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA5, - }, - { - .name = "Listen 1 Audio Service", - .stream_name = "Listen 1 Audio Service", - .cpu_dai_name = "LSM1", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM1, - }, - /* Multiple Tunnel instances */ - { - .name = MSM_DAILINK_NAME(Compress2), - .stream_name = "Compress2", - .cpu_dai_name = "MultiMedia7", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA7, - }, - { - .name = MSM_DAILINK_NAME(MultiMedia10), - .stream_name = "MultiMedia10", - .cpu_dai_name = "MultiMedia10", - .platform_name = "msm-pcm-dsp.1", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA10, - }, - { - .name = MSM_DAILINK_NAME(ULL_NOIRQ), - .stream_name = "MM_NOIRQ", - .cpu_dai_name = "MultiMedia8", - .platform_name = "msm-pcm-dsp-noirq", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA8, - }, - /* HDMI Hostless */ - { - .name = "HDMI_RX_HOSTLESS", - .stream_name = "HDMI_RX_HOSTLESS", - .cpu_dai_name = "HDMI_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "VoiceMMode2", - .stream_name = "VoiceMMode2", - .cpu_dai_name = "VoiceMMode2", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_VOICEMMODE2, - }, - /* LSM FE */ - { - .name = "Listen 2 Audio Service", - .stream_name = "Listen 2 Audio Service", - .cpu_dai_name = "LSM2", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM2, - }, - { - .name = "Listen 3 Audio Service", - .stream_name = "Listen 3 Audio Service", - .cpu_dai_name = "LSM3", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM3, - }, - { - .name = "Listen 4 Audio Service", - .stream_name = "Listen 4 Audio Service", - .cpu_dai_name = "LSM4", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM4, - }, - { - .name = "Listen 5 Audio Service", - .stream_name = "Listen 5 Audio Service", - .cpu_dai_name = "LSM5", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM5, - }, - { - .name = "Listen 6 Audio Service", - .stream_name = "Listen 6 Audio Service", - .cpu_dai_name = "LSM6", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM6, - }, - { - .name = "Listen 7 Audio Service", - .stream_name = "Listen 7 Audio Service", - .cpu_dai_name = "LSM7", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM7, - }, - { - .name = "Listen 8 Audio Service", - .stream_name = "Listen 8 Audio Service", - .cpu_dai_name = "LSM8", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM8, - }, - { - .name = MSM_DAILINK_NAME(Media9), - .stream_name = "MultiMedia9", - .cpu_dai_name = "MultiMedia9", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA9, - }, - { - .name = MSM_DAILINK_NAME(Compress4), - .stream_name = "Compress4", - .cpu_dai_name = "MultiMedia11", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA11, - }, - { - .name = MSM_DAILINK_NAME(Compress5), - .stream_name = "Compress5", - .cpu_dai_name = "MultiMedia12", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA12, - }, - { - .name = MSM_DAILINK_NAME(Compress6), - .stream_name = "Compress6", - .cpu_dai_name = "MultiMedia13", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA13, - }, - { - .name = MSM_DAILINK_NAME(Compress7), - .stream_name = "Compress7", - .cpu_dai_name = "MultiMedia14", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA14, - }, - { - .name = MSM_DAILINK_NAME(Compress8), - .stream_name = "Compress8", - .cpu_dai_name = "MultiMedia15", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA15, - }, - { - .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), - .stream_name = "MM_NOIRQ_2", - .cpu_dai_name = "MultiMedia16", - .platform_name = "msm-pcm-dsp-noirq", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA16, - }, - { - .name = "SLIMBUS_8 Hostless", - .stream_name = "SLIMBUS8_HOSTLESS Capture", - .cpu_dai_name = "SLIMBUS8_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, -}; - -static struct snd_soc_dai_link msm_tasha_fe_dai_links[] = { - { - .name = LPASS_BE_SLIMBUS_4_TX, - .stream_name = "Slimbus4 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16393", - .platform_name = "msm-pcm-hostless", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_vifeedback", - .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - }, - /* Ultrasound RX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Playback", - .stream_name = "SLIMBUS_2 Hostless Playback", - .cpu_dai_name = "msm-dai-q6-dev.16388", - .platform_name = "msm-pcm-hostless", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx2", - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm_slimbus_2_be_ops, - }, - /* Ultrasound TX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Capture", - .stream_name = "SLIMBUS_2 Hostless Capture", - .cpu_dai_name = "msm-dai-q6-dev.16389", - .platform_name = "msm-pcm-hostless", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx2", - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm_slimbus_2_be_ops, - }, - /* CPE LSM direct dai-link */ - { - .name = "CPE Listen service", - .stream_name = "CPE Listen Audio Service", - .cpu_dai_name = "msm-dai-slim", - .platform_name = "msm-cpe-lsm", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "tasha_mad1", - .codec_name = "tasha_codec", - .ops = &msm_cpe_ops, - }, - { - .name = "SLIMBUS_6 Hostless Playback", - .stream_name = "SLIMBUS_6 Hostless", - .cpu_dai_name = "SLIMBUS6_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - /* CPE LSM EC PP direct dai-link */ - { - .name = "CPE Listen service ECPP", - .stream_name = "CPE Listen Audio Service ECPP", - .cpu_dai_name = "CPE_LSM_NOHOST", - .platform_name = "msm-cpe-lsm.3", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "tasha_cpe", - .codec_name = "tasha_codec", - }, -}; - -static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = { - { - .name = LPASS_BE_SLIMBUS_4_TX, - .stream_name = "Slimbus4 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16393", - .platform_name = "msm-pcm-hostless", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_vifeedback", - .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - }, - /* Ultrasound RX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Playback", - .stream_name = "SLIMBUS_2 Hostless Playback", - .cpu_dai_name = "msm-dai-q6-dev.16388", - .platform_name = "msm-pcm-hostless", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx2", - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm_slimbus_2_be_ops, - }, - /* Ultrasound TX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Capture", - .stream_name = "SLIMBUS_2 Hostless Capture", - .cpu_dai_name = "msm-dai-q6-dev.16389", - .platform_name = "msm-pcm-hostless", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_tx2", - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm_slimbus_2_be_ops, - }, -}; - -static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { - { - .name = MSM_DAILINK_NAME(ASM Loopback), - .stream_name = "MultiMedia6", - .cpu_dai_name = "MultiMedia6", - .platform_name = "msm-pcm-loopback", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_pmdown_time = 1, - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA6, - }, - { - .name = "USB Audio Hostless", - .stream_name = "USB Audio Hostless", - .cpu_dai_name = "USBAUDIO_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = MSM_DAILINK_NAME(Transcode Loopback Playback), - .stream_name = "Transcode Loopback Playback", - .cpu_dai_name = "MultiMedia14", - .platform_name = "msm-transcode-loopback", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA14, - }, - { - .name = MSM_DAILINK_NAME(Transcode Loopback Capture), - .stream_name = "Transcode Loopback Capture", - .cpu_dai_name = "MultiMedia18", - .platform_name = "msm-transcode-loopback", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA18, - }, -}; - -static struct snd_soc_dai_link msm_common_be_dai_links[] = { - /* Backend AFE DAI Links */ - { - .name = LPASS_BE_AFE_PCM_RX, - .stream_name = "AFE Playback", - .cpu_dai_name = "msm-dai-q6-dev.224", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_AFE_PCM_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_AFE_PCM_TX, - .stream_name = "AFE Capture", - .cpu_dai_name = "msm-dai-q6-dev.225", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_AFE_PCM_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Record Uplink BACK END DAI Link */ - { - .name = LPASS_BE_INCALL_RECORD_TX, - .stream_name = "Voice Uplink Capture", - .cpu_dai_name = "msm-dai-q6-dev.32772", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Record Downlink BACK END DAI Link */ - { - .name = LPASS_BE_INCALL_RECORD_RX, - .stream_name = "Voice Downlink Capture", - .cpu_dai_name = "msm-dai-q6-dev.32771", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Music BACK END DAI Link */ - { - .name = LPASS_BE_VOICE_PLAYBACK_TX, - .stream_name = "Voice Farend Playback", - .cpu_dai_name = "msm-dai-q6-dev.32773", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Music 2 BACK END DAI Link */ - { - .name = LPASS_BE_VOICE2_PLAYBACK_TX, - .stream_name = "Voice2 Farend Playback", - .cpu_dai_name = "msm-dai-q6-dev.32770", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_USB_AUDIO_RX, - .stream_name = "USB Audio Playback", - .cpu_dai_name = "msm-dai-q6-dev.28672", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_USB_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_USB_AUDIO_TX, - .stream_name = "USB Audio Capture", - .cpu_dai_name = "msm-dai-q6-dev.28673", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_USB_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_PRI_TDM_RX_0, - .stream_name = "Primary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36864", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_PRI_TDM_TX_0, - .stream_name = "Primary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36865", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SEC_TDM_RX_0, - .stream_name = "Secondary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36880", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SEC_TDM_TX_0, - .stream_name = "Secondary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36881", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_TERT_TDM_RX_0, - .stream_name = "Tertiary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36896", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_TERT_TDM_TX_0, - .stream_name = "Tertiary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36897", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_QUAT_TDM_RX_0, - .stream_name = "Quaternary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36912", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, - .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, - .ops = &msm8998_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_QUAT_TDM_TX_0, - .stream_name = "Quaternary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36913", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm_tasha_be_dai_links[] = { - { - .name = LPASS_BE_SLIMBUS_0_RX, - .stream_name = "Slimbus Playback", - .cpu_dai_name = "msm-dai-q6-dev.16384", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mix_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, - .init = &msm_audrx_init, - .be_hw_params_fixup = msm_be_hw_params_fixup, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_0_TX, - .stream_name = "Slimbus Capture", - .cpu_dai_name = "msm-dai-q6-dev.16385", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_1_RX, - .stream_name = "Slimbus1 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16386", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mix_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_1_TX, - .stream_name = "Slimbus1 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16387", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx3", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_3_RX, - .stream_name = "Slimbus3 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16390", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mix_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_3_TX, - .stream_name = "Slimbus3 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16391", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_4_RX, - .stream_name = "Slimbus4 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16392", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mix_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_5_RX, - .stream_name = "Slimbus5 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16394", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx3", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - /* MAD BE */ - { - .name = LPASS_BE_SLIMBUS_5_TX, - .stream_name = "Slimbus5 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16395", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mad1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_6_RX, - .stream_name = "Slimbus6 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16396", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx4", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - /* Slimbus VI Recording */ - { - .name = LPASS_BE_SLIMBUS_TX_VI, - .stream_name = "Slimbus4 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16393", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_vifeedback", - .be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_suspend = 1, - .no_pcm = 1, - .dpcm_capture = 1, - .ignore_pmdown_time = 1, - }, -}; - -static struct snd_soc_dai_link msm_tavil_be_dai_links[] = { - { - .name = LPASS_BE_SLIMBUS_0_RX, - .stream_name = "Slimbus Playback", - .cpu_dai_name = "msm-dai-q6-dev.16384", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, - .init = &msm_audrx_init, - .be_hw_params_fixup = msm_be_hw_params_fixup, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_0_TX, - .stream_name = "Slimbus Capture", - .cpu_dai_name = "msm-dai-q6-dev.16385", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_tx1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_1_RX, - .stream_name = "Slimbus1 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16386", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_1_TX, - .stream_name = "Slimbus1 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16387", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_tx3", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_2_RX, - .stream_name = "Slimbus2 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16388", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx2", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_2_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_3_RX, - .stream_name = "Slimbus3 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16390", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_3_TX, - .stream_name = "Slimbus3 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16391", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_tx1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_4_RX, - .stream_name = "Slimbus4 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16392", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_5_RX, - .stream_name = "Slimbus5 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16394", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx3", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - /* MAD BE */ - { - .name = LPASS_BE_SLIMBUS_5_TX, - .stream_name = "Slimbus5 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16395", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_mad1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_6_RX, - .stream_name = "Slimbus6 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16396", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx4", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - /* Slimbus VI Recording */ - { - .name = LPASS_BE_SLIMBUS_TX_VI, - .stream_name = "Slimbus4 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16393", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_vifeedback", - .be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_suspend = 1, - .no_pcm = 1, - .dpcm_capture = 1, - .ignore_pmdown_time = 1, - }, -}; - -static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { - { - .name = LPASS_BE_SLIMBUS_7_RX, - .stream_name = "Slimbus7 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16398", - .platform_name = "msm-pcm-routing", - .codec_name = "btfmslim_slave", - /* BT codec driver determines capabilities based on - * dai name, bt codecdai name should always contains - * supported usecase information - */ - .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_7_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_wcn_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_7_TX, - .stream_name = "Slimbus7 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16399", - .platform_name = "msm-pcm-routing", - .codec_name = "btfmslim_slave", - .codec_dai_name = "btfm_bt_sco_slim_tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_7_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_wcn_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_8_TX, - .stream_name = "Slimbus8 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16401", - .platform_name = "msm-pcm-routing", - .codec_name = "btfmslim_slave", - .codec_dai_name = "btfm_fm_slim_tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_8_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .init = &msm_wcn_init, - .ops = &msm_wcn_ops, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link ext_disp_be_dai_link[] = { - /* HDMI BACK END DAI Link */ - { - .name = LPASS_BE_HDMI, - .stream_name = "HDMI Playback", - .cpu_dai_name = "msm-dai-q6-hdmi.8", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-ext-disp-audio-codec-rx", - .codec_dai_name = "msm_hdmi_audio_codec_rx_dai", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_HDMI_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - /* DISP PORT BACK END DAI Link */ - { - .name = LPASS_BE_DISPLAY_PORT, - .stream_name = "Display Port Playback", - .cpu_dai_name = "msm-dai-q6-dp.24608", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-ext-disp-audio-codec-rx", - .codec_dai_name = "msm_dp_audio_codec_rx_dai", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { - { - .name = LPASS_BE_PRI_MI2S_RX, - .stream_name = "Primary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.0", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_PRI_MI2S_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_PRI_MI2S_TX, - .stream_name = "Primary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.0", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_PRI_MI2S_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SEC_MI2S_RX, - .stream_name = "Secondary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_SEC_MI2S_TX, - .stream_name = "Secondary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_TERT_MI2S_RX, - .stream_name = "Tertiary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_TERT_MI2S_TX, - .stream_name = "Tertiary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_QUAT_MI2S_RX, - .stream_name = "Quaternary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.3", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_QUAT_MI2S_TX, - .stream_name = "Quaternary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.3", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { - /* Primary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_AUXPCM_RX, - .stream_name = "AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_AUXPCM_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - { - .name = LPASS_BE_AUXPCM_TX, - .stream_name = "AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_AUXPCM_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - /* Secondary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_SEC_AUXPCM_RX, - .stream_name = "Sec AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - { - .name = LPASS_BE_SEC_AUXPCM_TX, - .stream_name = "Sec AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .ops = &msm_aux_pcm_be_ops, - }, - /* Tertiary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_TERT_AUXPCM_RX, - .stream_name = "Tert AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.3", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - { - .name = LPASS_BE_TERT_AUXPCM_TX, - .stream_name = "Tert AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.3", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .ops = &msm_aux_pcm_be_ops, - }, - /* Quaternary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_QUAT_AUXPCM_RX, - .stream_name = "Quat AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.4", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - { - .name = LPASS_BE_QUAT_AUXPCM_TX, - .stream_name = "Quat AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.4", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .ops = &msm_aux_pcm_be_ops, - }, -}; - -static struct snd_soc_dai_link msm_tasha_dai_links[ - ARRAY_SIZE(msm_common_dai_links) + - ARRAY_SIZE(msm_tasha_fe_dai_links) + - ARRAY_SIZE(msm_common_misc_fe_dai_links) + - ARRAY_SIZE(msm_common_be_dai_links) + - ARRAY_SIZE(msm_tasha_be_dai_links) + - ARRAY_SIZE(msm_wcn_be_dai_links) + - ARRAY_SIZE(ext_disp_be_dai_link) + - ARRAY_SIZE(msm_mi2s_be_dai_links) + - ARRAY_SIZE(msm_auxpcm_be_dai_links)]; - -static struct snd_soc_dai_link msm_tavil_dai_links[ - ARRAY_SIZE(msm_common_dai_links) + - ARRAY_SIZE(msm_tavil_fe_dai_links) + - ARRAY_SIZE(msm_common_misc_fe_dai_links) + - ARRAY_SIZE(msm_common_be_dai_links) + - ARRAY_SIZE(msm_tavil_be_dai_links) + - ARRAY_SIZE(msm_wcn_be_dai_links) + - ARRAY_SIZE(ext_disp_be_dai_link) + - ARRAY_SIZE(msm_mi2s_be_dai_links) + - ARRAY_SIZE(msm_auxpcm_be_dai_links)]; - -static int msm_snd_card_late_probe(struct snd_soc_card *card) -{ - const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; - struct snd_soc_pcm_runtime *rtd; - int ret = 0; - void *mbhc_calibration; - - rtd = snd_soc_get_pcm_runtime(card, be_dl_name); - if (!rtd) { - dev_err(card->dev, - "%s: snd_soc_get_pcm_runtime for %s failed!\n", - __func__, be_dl_name); - ret = -EINVAL; - goto err_pcm_runtime; - } - - mbhc_calibration = def_tasha_mbhc_cal(); - if (!mbhc_calibration) { - ret = -ENOMEM; - goto err_mbhc_cal; - } - wcd_mbhc_cfg.calibration = mbhc_calibration; - ret = tasha_mbhc_hs_detect(rtd->codec, &wcd_mbhc_cfg); - if (ret) { - dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", - __func__, ret); - goto err_hs_detect; - } - return 0; - -err_hs_detect: - kfree(mbhc_calibration); -err_mbhc_cal: -err_pcm_runtime: - return ret; -} - -static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) -{ - const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; - struct snd_soc_pcm_runtime *rtd; - int ret = 0; - void *mbhc_calibration; - - rtd = snd_soc_get_pcm_runtime(card, be_dl_name); - if (!rtd) { - dev_err(card->dev, - "%s: snd_soc_get_pcm_runtime for %s failed!\n", - __func__, be_dl_name); - ret = -EINVAL; - goto err_pcm_runtime; - } - - mbhc_calibration = def_tavil_mbhc_cal(); - if (!mbhc_calibration) { - ret = -ENOMEM; - goto err_mbhc_cal; - } - wcd_mbhc_cfg.calibration = mbhc_calibration; - ret = tavil_mbhc_hs_detect(rtd->codec, &wcd_mbhc_cfg); - if (ret) { - dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", - __func__, ret); - goto err_hs_detect; - } - return 0; - -err_hs_detect: - kfree(mbhc_calibration); -err_mbhc_cal: -err_pcm_runtime: - return ret; -} - -struct snd_soc_card snd_soc_card_tasha_msm = { - .name = "msm8998-tasha-snd-card", - .late_probe = msm_snd_card_late_probe, -}; - -struct snd_soc_card snd_soc_card_tavil_msm = { - .name = "msm8998-tavil-snd-card", - .late_probe = msm_snd_card_tavil_late_probe, -}; - -static int msm_populate_dai_link_component_of_node( - struct snd_soc_card *card) -{ - int i, index, ret = 0; - struct device *cdev = card->dev; - struct snd_soc_dai_link *dai_link = card->dai_link; - struct device_node *np; - - if (!cdev) { - pr_err("%s: Sound card device memory NULL\n", __func__); - return -ENODEV; - } - - for (i = 0; i < card->num_links; i++) { - if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) - continue; - - /* populate platform_of_node for snd card dai links */ - if (dai_link[i].platform_name && - !dai_link[i].platform_of_node) { - index = of_property_match_string(cdev->of_node, - "asoc-platform-names", - dai_link[i].platform_name); - if (index < 0) { - pr_err("%s: No match found for platform name: %s\n", - __func__, dai_link[i].platform_name); - ret = index; - goto err; - } - np = of_parse_phandle(cdev->of_node, "asoc-platform", - index); - if (!np) { - pr_err("%s: retrieving phandle for platform %s, index %d failed\n", - __func__, dai_link[i].platform_name, - index); - ret = -ENODEV; - goto err; - } - dai_link[i].platform_of_node = np; - dai_link[i].platform_name = NULL; - } - - /* populate cpu_of_node for snd card dai links */ - if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { - index = of_property_match_string(cdev->of_node, - "asoc-cpu-names", - dai_link[i].cpu_dai_name); - if (index >= 0) { - np = of_parse_phandle(cdev->of_node, "asoc-cpu", - index); - if (!np) { - pr_err("%s: retrieving phandle for cpu dai %s failed\n", - __func__, - dai_link[i].cpu_dai_name); - ret = -ENODEV; - goto err; - } - dai_link[i].cpu_of_node = np; - dai_link[i].cpu_dai_name = NULL; - } - } - - /* populate codec_of_node for snd card dai links */ - if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { - index = of_property_match_string(cdev->of_node, - "asoc-codec-names", - dai_link[i].codec_name); - if (index < 0) - continue; - np = of_parse_phandle(cdev->of_node, "asoc-codec", - index); - if (!np) { - pr_err("%s: retrieving phandle for codec %s failed\n", - __func__, dai_link[i].codec_name); - ret = -ENODEV; - goto err; - } - dai_link[i].codec_of_node = np; - dai_link[i].codec_name = NULL; - } - } - -err: - return ret; -} - -static int msm_prepare_us_euro(struct snd_soc_card *card) -{ - struct msm_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - int ret = 0; - - if (pdata->us_euro_gpio >= 0) { - dev_dbg(card->dev, "%s: us_euro gpio request %d", __func__, - pdata->us_euro_gpio); - ret = gpio_request(pdata->us_euro_gpio, "TASHA_CODEC_US_EURO"); - if (ret) { - dev_err(card->dev, - "%s: Failed to request codec US/EURO gpio %d error %d\n", - __func__, pdata->us_euro_gpio, ret); - } - } - - return ret; -} - -static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret = 0; - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - - ret = snd_soc_add_codec_controls(codec, msm_snd_controls, - ARRAY_SIZE(msm_snd_controls)); - if (ret < 0) { - dev_err(codec->dev, "%s: add_codec_controls failed, err%d\n", - __func__, ret); - return ret; - } - - snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, - ARRAY_SIZE(msm_dapm_widgets)); - - return 0; -} - -static int msm_snd_stub_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - - int ret = 0; - unsigned int rx_ch[] = {144, 145, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156}; - unsigned int tx_ch[] = {128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143}; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, - slim_rx_cfg[0].channels, - rx_ch); - if (ret < 0) - pr_err("%s: RX failed to set cpu chan map error %d\n", - __func__, ret); - } else { - ret = snd_soc_dai_set_channel_map(cpu_dai, - slim_tx_cfg[0].channels, - tx_ch, 0, 0); - if (ret < 0) - pr_err("%s: TX failed to set cpu chan map error %d\n", - __func__, ret); - } - - return ret; -} - -static struct snd_soc_ops msm_stub_be_ops = { - .hw_params = msm_snd_stub_hw_params, -}; - -static struct snd_soc_dai_link msm_stub_fe_dai_links[] = { - - /* FrontEnd DAI Links */ - { - .name = "MSMSTUB Media1", - .stream_name = "MultiMedia1", - .cpu_dai_name = "MultiMedia1", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA1 - }, -}; - -static struct snd_soc_dai_link msm_stub_be_dai_links[] = { - - /* Backend DAI Links */ - { - .name = LPASS_BE_SLIMBUS_0_RX, - .stream_name = "Slimbus Playback", - .cpu_dai_name = "msm-dai-q6-dev.16384", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, - .init = &msm_audrx_stub_init, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, /* dai link has playback support */ - .ignore_suspend = 1, - .ops = &msm_stub_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_0_TX, - .stream_name = "Slimbus Capture", - .cpu_dai_name = "msm-dai-q6-dev.16385", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_stub_be_ops, - }, -}; - -static struct snd_soc_dai_link msm_stub_dai_links[ - ARRAY_SIZE(msm_stub_fe_dai_links) + - ARRAY_SIZE(msm_stub_be_dai_links)]; - -struct snd_soc_card snd_soc_card_stub_msm = { - .name = "msm8998-stub-snd-card", -}; - -static const struct of_device_id msm8998_asoc_machine_of_match[] = { - { .compatible = "qcom,msm8998-asoc-snd-tasha", - .data = "tasha_codec"}, - { .compatible = "qcom,msm8998-asoc-snd-tavil", - .data = "tavil_codec"}, - { .compatible = "qcom,msm8998-asoc-snd-stub", - .data = "stub_codec"}, - {}, -}; - -static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) -{ - struct snd_soc_card *card = NULL; - struct snd_soc_dai_link *dailink; - int len_1, len_2, len_3, len_4; - int total_links; - const struct of_device_id *match; - - match = of_match_node(msm8998_asoc_machine_of_match, dev->of_node); - if (!match) { - dev_err(dev, "%s: No DT match found for sound card\n", - __func__); - return NULL; - } - - if (!strcmp(match->data, "tasha_codec")) { - card = &snd_soc_card_tasha_msm; - len_1 = ARRAY_SIZE(msm_common_dai_links); - len_2 = len_1 + ARRAY_SIZE(msm_tasha_fe_dai_links); - len_3 = len_2 + ARRAY_SIZE(msm_common_misc_fe_dai_links); - len_4 = len_3 + ARRAY_SIZE(msm_common_be_dai_links); - total_links = len_4 + ARRAY_SIZE(msm_tasha_be_dai_links); - memcpy(msm_tasha_dai_links, - msm_common_dai_links, - sizeof(msm_common_dai_links)); - memcpy(msm_tasha_dai_links + len_1, - msm_tasha_fe_dai_links, - sizeof(msm_tasha_fe_dai_links)); - memcpy(msm_tasha_dai_links + len_2, - msm_common_misc_fe_dai_links, - sizeof(msm_common_misc_fe_dai_links)); - memcpy(msm_tasha_dai_links + len_3, - msm_common_be_dai_links, - sizeof(msm_common_be_dai_links)); - memcpy(msm_tasha_dai_links + len_4, - msm_tasha_be_dai_links, - sizeof(msm_tasha_be_dai_links)); - - if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { - dev_dbg(dev, "%s(): WCN BTFM support present\n", - __func__); - memcpy(msm_tasha_dai_links + total_links, - msm_wcn_be_dai_links, - sizeof(msm_wcn_be_dai_links)); - total_links += ARRAY_SIZE(msm_wcn_be_dai_links); - } - - if (of_property_read_bool(dev->of_node, - "qcom,ext-disp-audio-rx")) { - dev_dbg(dev, "%s(): External display audio support present\n", - __func__); - memcpy(msm_tasha_dai_links + total_links, - ext_disp_be_dai_link, - sizeof(ext_disp_be_dai_link)); - total_links += ARRAY_SIZE(ext_disp_be_dai_link); - } - if (of_property_read_bool(dev->of_node, - "qcom,mi2s-audio-intf")) { - memcpy(msm_tasha_dai_links + total_links, - msm_mi2s_be_dai_links, - sizeof(msm_mi2s_be_dai_links)); - total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); - } - if (of_property_read_bool(dev->of_node, - "qcom,auxpcm-audio-intf")) { - memcpy(msm_tasha_dai_links + total_links, - msm_auxpcm_be_dai_links, - sizeof(msm_auxpcm_be_dai_links)); - total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links); - } - dailink = msm_tasha_dai_links; - } else if (!strcmp(match->data, "tavil_codec")) { - card = &snd_soc_card_tavil_msm; - len_1 = ARRAY_SIZE(msm_common_dai_links); - len_2 = len_1 + ARRAY_SIZE(msm_tavil_fe_dai_links); - len_3 = len_2 + ARRAY_SIZE(msm_common_misc_fe_dai_links); - len_4 = len_3 + ARRAY_SIZE(msm_common_be_dai_links); - total_links = len_4 + ARRAY_SIZE(msm_tavil_be_dai_links); - memcpy(msm_tavil_dai_links, - msm_common_dai_links, - sizeof(msm_common_dai_links)); - memcpy(msm_tavil_dai_links + len_1, - msm_tavil_fe_dai_links, - sizeof(msm_tavil_fe_dai_links)); - memcpy(msm_tavil_dai_links + len_2, - msm_common_misc_fe_dai_links, - sizeof(msm_common_misc_fe_dai_links)); - memcpy(msm_tavil_dai_links + len_3, - msm_common_be_dai_links, - sizeof(msm_common_be_dai_links)); - memcpy(msm_tavil_dai_links + len_4, - msm_tavil_be_dai_links, - sizeof(msm_tavil_be_dai_links)); - - if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { - dev_dbg(dev, "%s(): WCN BTFM support present\n", - __func__); - memcpy(msm_tavil_dai_links + total_links, - msm_wcn_be_dai_links, - sizeof(msm_wcn_be_dai_links)); - total_links += ARRAY_SIZE(msm_wcn_be_dai_links); - } - - if (of_property_read_bool(dev->of_node, - "qcom,ext-disp-audio-rx")) { - dev_dbg(dev, "%s(): ext disp audio support present\n", - __func__); - memcpy(msm_tavil_dai_links + total_links, - ext_disp_be_dai_link, - sizeof(ext_disp_be_dai_link)); - total_links += ARRAY_SIZE(ext_disp_be_dai_link); - } - if (of_property_read_bool(dev->of_node, - "qcom,mi2s-audio-intf")) { - memcpy(msm_tavil_dai_links + total_links, - msm_mi2s_be_dai_links, - sizeof(msm_mi2s_be_dai_links)); - total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); - } - if (of_property_read_bool(dev->of_node, - "qcom,auxpcm-audio-intf")) { - memcpy(msm_tavil_dai_links + total_links, - msm_auxpcm_be_dai_links, - sizeof(msm_auxpcm_be_dai_links)); - total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links); - } - dailink = msm_tavil_dai_links; - } else if (!strcmp(match->data, "stub_codec")) { - card = &snd_soc_card_stub_msm; - len_1 = ARRAY_SIZE(msm_stub_fe_dai_links); - len_2 = len_1 + ARRAY_SIZE(msm_stub_be_dai_links); - - memcpy(msm_stub_dai_links, - msm_stub_fe_dai_links, - sizeof(msm_stub_fe_dai_links)); - memcpy(msm_stub_dai_links + len_1, - msm_stub_be_dai_links, - sizeof(msm_stub_be_dai_links)); - - dailink = msm_stub_dai_links; - total_links = len_2; - } - - if (card) { - card->dai_link = dailink; - card->num_links = total_links; - } - - return card; -} - -static int msm_wsa881x_init(struct snd_soc_component *component) -{ - u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106}; - u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107}; - unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; - unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); - struct msm_asoc_mach_data *pdata; - struct snd_soc_dapm_context *dapm; - int ret = 0; - - if (!codec) { - pr_err("%s codec is NULL\n", __func__); - return -EINVAL; - } - - dapm = snd_soc_codec_get_dapm(codec); - - if (!strcmp(component->name_prefix, "SpkrLeft")) { - dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n", - __func__, codec->component.name); - wsa881x_set_channel_map(codec, &spkleft_ports[0], - WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0], NULL); - if (dapm->component) { - snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); - snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); - } - } else if (!strcmp(component->name_prefix, "SpkrRight")) { - dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n", - __func__, codec->component.name); - wsa881x_set_channel_map(codec, &spkright_ports[0], - WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0], NULL); - if (dapm->component) { - snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); - snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); - } - } else { - dev_err(codec->dev, "%s: wrong codec name %s\n", __func__, - codec->component.name); - ret = -EINVAL; - goto err_codec; - } - pdata = snd_soc_card_get_drvdata(component->card); - if (pdata && pdata->codec_root) - wsa881x_codec_info_create_codec_entry(pdata->codec_root, - codec); - -err_codec: - return ret; -} - -static int msm_init_wsa_dev(struct platform_device *pdev, - struct snd_soc_card *card) -{ - struct device_node *wsa_of_node; - u32 wsa_max_devs; - u32 wsa_dev_cnt; - int i; - struct msm_wsa881x_dev_info *wsa881x_dev_info; - const char *wsa_auxdev_name_prefix[1]; - char *dev_name_str = NULL; - int found = 0; - int ret = 0; - - /* Get maximum WSA device count for this platform */ - ret = of_property_read_u32(pdev->dev.of_node, - "qcom,wsa-max-devs", &wsa_max_devs); - if (ret) { - dev_dbg(&pdev->dev, - "%s: wsa-max-devs property missing in DT %s, ret = %d\n", - __func__, pdev->dev.of_node->full_name, ret); - goto err_dt; - } - if (wsa_max_devs == 0) { - dev_warn(&pdev->dev, - "%s: Max WSA devices is 0 for this target?\n", - __func__); - goto err_dt; - } - - /* Get count of WSA device phandles for this platform */ - wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node, - "qcom,wsa-devs", NULL); - if (wsa_dev_cnt == -ENOENT) { - dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n", - __func__); - goto err_dt; - } else if (wsa_dev_cnt <= 0) { - dev_err(&pdev->dev, - "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n", - __func__, wsa_dev_cnt); - ret = -EINVAL; - goto err_dt; - } - - /* - * Expect total phandles count to be NOT less than maximum possible - * WSA count. However, if it is less, then assign same value to - * max count as well. - */ - if (wsa_dev_cnt < wsa_max_devs) { - dev_dbg(&pdev->dev, - "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n", - __func__, wsa_max_devs, wsa_dev_cnt); - wsa_max_devs = wsa_dev_cnt; - } - - /* Make sure prefix string passed for each WSA device */ - ret = of_property_count_strings(pdev->dev.of_node, - "qcom,wsa-aux-dev-prefix"); - if (ret != wsa_dev_cnt) { - dev_err(&pdev->dev, - "%s: expecting %d wsa prefix. Defined only %d in DT\n", - __func__, wsa_dev_cnt, ret); - ret = -EINVAL; - goto err_dt; - } - - /* - * Alloc mem to store phandle and index info of WSA device, if already - * registered with ALSA core - */ - wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs, - sizeof(struct msm_wsa881x_dev_info), - GFP_KERNEL); - if (!wsa881x_dev_info) { - ret = -ENOMEM; - goto err_mem; - } - - /* - * search and check whether all WSA devices are already - * registered with ALSA core or not. If found a node, store - * the node and the index in a local array of struct for later - * use. - */ - for (i = 0; i < wsa_dev_cnt; i++) { - wsa_of_node = of_parse_phandle(pdev->dev.of_node, - "qcom,wsa-devs", i); - if (unlikely(!wsa_of_node)) { - /* we should not be here */ - dev_err(&pdev->dev, - "%s: wsa dev node is not present\n", - __func__); - ret = -EINVAL; - goto err_dev_node; - } - if (soc_find_component(wsa_of_node, NULL)) { - /* WSA device registered with ALSA core */ - wsa881x_dev_info[found].of_node = wsa_of_node; - wsa881x_dev_info[found].index = i; - found++; - if (found == wsa_max_devs) - break; - } - } - - if (found < wsa_max_devs) { - dev_dbg(&pdev->dev, - "%s: failed to find %d components. Found only %d\n", - __func__, wsa_max_devs, found); - return -EPROBE_DEFER; - } - dev_info(&pdev->dev, - "%s: found %d wsa881x devices registered with ALSA core\n", - __func__, found); - - card->num_aux_devs = wsa_max_devs; - card->num_configs = wsa_max_devs; - - /* Alloc array of AUX devs struct */ - msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, - sizeof(struct snd_soc_aux_dev), - GFP_KERNEL); - if (!msm_aux_dev) { - ret = -ENOMEM; - goto err_auxdev_mem; - } - - /* Alloc array of codec conf struct */ - msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs, - sizeof(struct snd_soc_codec_conf), - GFP_KERNEL); - if (!msm_codec_conf) { - ret = -ENOMEM; - goto err_codec_conf; - } - - for (i = 0; i < card->num_aux_devs; i++) { - dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN, - GFP_KERNEL); - if (!dev_name_str) { - ret = -ENOMEM; - goto err_dev_str; - } - - ret = of_property_read_string_index(pdev->dev.of_node, - "qcom,wsa-aux-dev-prefix", - wsa881x_dev_info[i].index, - wsa_auxdev_name_prefix); - if (ret) { - dev_err(&pdev->dev, - "%s: failed to read wsa aux dev prefix, ret = %d\n", - __func__, ret); - ret = -EINVAL; - goto err_dt_prop; - } - - snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i); - msm_aux_dev[i].name = dev_name_str; - msm_aux_dev[i].codec_name = NULL; - msm_aux_dev[i].codec_of_node = - wsa881x_dev_info[i].of_node; - msm_aux_dev[i].init = msm_wsa881x_init; - msm_codec_conf[i].dev_name = NULL; - msm_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0]; - msm_codec_conf[i].of_node = - wsa881x_dev_info[i].of_node; - } - card->codec_conf = msm_codec_conf; - card->aux_dev = msm_aux_dev; - - return 0; - -err_dt_prop: - devm_kfree(&pdev->dev, dev_name_str); -err_dev_str: - devm_kfree(&pdev->dev, msm_codec_conf); -err_codec_conf: - devm_kfree(&pdev->dev, msm_aux_dev); -err_auxdev_mem: -err_dev_node: - devm_kfree(&pdev->dev, wsa881x_dev_info); -err_mem: -err_dt: - return ret; -} - -static void i2s_auxpcm_init(struct platform_device *pdev) -{ - struct resource *muxsel; - int count; - u32 mi2s_master_slave[MI2S_MAX]; - int ret; - char *str[PCM_I2S_SEL_MAX] = { - "lpaif_pri_mode_muxsel", - "lpaif_sec_mode_muxsel", - "lpaif_tert_mode_muxsel", - "lpaif_quat_mode_muxsel" - }; - - for (count = 0; count < MI2S_MAX; count++) { - mutex_init(&mi2s_intf_conf[count].lock); - mi2s_intf_conf[count].ref_cnt = 0; - } - - for (count = 0; count < AUX_PCM_MAX; count++) { - mutex_init(&auxpcm_intf_conf[count].lock); - auxpcm_intf_conf[count].ref_cnt = 0; - } - - for (count = 0; count < PCM_I2S_SEL_MAX; count++) { - mutex_init(&mi2s_auxpcm_conf[count].lock); - mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr = NULL; - } - - for (count = 0; count < PCM_I2S_SEL_MAX; count++) { - muxsel = platform_get_resource_byname(pdev, IORESOURCE_MEM, - str[count]); - if (muxsel) { - mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr - = ioremap(muxsel->start, resource_size(muxsel)); - } - } - - ret = of_property_read_u32_array(pdev->dev.of_node, - "qcom,msm-mi2s-master", - mi2s_master_slave, MI2S_MAX); - if (ret) { - dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n", - __func__); - } else { - for (count = 0; count < MI2S_MAX; count++) { - mi2s_intf_conf[count].msm_is_mi2s_master = - mi2s_master_slave[count]; - } - } -} - -static void i2s_auxpcm_deinit(void) -{ - int count; - - for (count = 0; count < PCM_I2S_SEL_MAX; count++) - if (mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr != - NULL) - iounmap( - mi2s_auxpcm_conf[count].pcm_i2s_sel_vt_addr); -} - -static int msm_asoc_machine_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card; - struct msm_asoc_mach_data *pdata; - const char *mbhc_audio_jack_type = NULL; - char *mclk_freq_prop_name; - const struct of_device_id *match; - int ret; - - if (!pdev->dev.of_node) { - dev_err(&pdev->dev, "No platform supplied from device tree\n"); - return -EINVAL; - } - - pdata = devm_kzalloc(&pdev->dev, - sizeof(struct msm_asoc_mach_data), GFP_KERNEL); - if (!pdata) - return -ENOMEM; - - card = populate_snd_card_dailinks(&pdev->dev); - if (!card) { - dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); - ret = -EINVAL; - goto err; - } - card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); - snd_soc_card_set_drvdata(card, pdata); - - ret = snd_soc_of_parse_card_name(card, "qcom,model"); - if (ret) { - dev_err(&pdev->dev, "parse card name failed, err:%d\n", - ret); - goto err; - } - - ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing"); - if (ret) { - dev_err(&pdev->dev, "parse audio routing failed, err:%d\n", - ret); - goto err; - } - - match = of_match_node(msm8998_asoc_machine_of_match, - pdev->dev.of_node); - if (!match) { - dev_err(&pdev->dev, "%s: no matched codec is found.\n", - __func__); - goto err; - } - - if (!strcmp(match->data, "tasha_codec")) - mclk_freq_prop_name = "qcom,tasha-mclk-clk-freq"; - else - mclk_freq_prop_name = "qcom,tavil-mclk-clk-freq"; - - ret = of_property_read_u32(pdev->dev.of_node, - mclk_freq_prop_name, &pdata->mclk_freq); - if (ret) { - dev_err(&pdev->dev, - "Looking up %s property in node %s failed, err%d\n", - mclk_freq_prop_name, - pdev->dev.of_node->full_name, ret); - goto err; - } - - if (pdata->mclk_freq != CODEC_EXT_CLK_RATE) { - dev_err(&pdev->dev, "unsupported mclk freq %u\n", - pdata->mclk_freq); - ret = -EINVAL; - goto err; - } - - ret = msm_populate_dai_link_component_of_node(card); - if (ret) { - ret = -EPROBE_DEFER; - goto err; - } - ret = msm_init_wsa_dev(pdev, card); - if (ret) - goto err; - - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret == -EPROBE_DEFER) { - if (codec_reg_done) - ret = -EINVAL; - goto err; - } else if (ret) { - dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", - ret); - goto err; - } - dev_info(&pdev->dev, "Sound card %s registered\n", card->name); - spdev = pdev; - - ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); - if (ret) { - dev_dbg(&pdev->dev, "%s: failed to add child nodes, ret=%d\n", - __func__, ret); - } else { - pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,hph-en1-gpio", 0); - if (!pdata->hph_en1_gpio_p) { - dev_dbg(&pdev->dev, "property %s not detected in node %s", - "qcom,hph-en1-gpio", - pdev->dev.of_node->full_name); - } - - pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,hph-en0-gpio", 0); - if (!pdata->hph_en0_gpio_p) { - dev_dbg(&pdev->dev, "property %s not detected in node %s", - "qcom,hph-en0-gpio", - pdev->dev.of_node->full_name); - } - } - - ret = of_property_read_string(pdev->dev.of_node, - "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type); - if (ret) { - dev_dbg(&pdev->dev, "Looking up %s property in node %s failed", - "qcom,mbhc-audio-jack-type", - pdev->dev.of_node->full_name); - dev_dbg(&pdev->dev, "Jack type properties set to default"); - } else { - if (!strcmp(mbhc_audio_jack_type, "4-pole-jack")) { - wcd_mbhc_cfg.enable_anc_mic_detect = false; - dev_dbg(&pdev->dev, "This hardware has 4 pole jack"); - } else if (!strcmp(mbhc_audio_jack_type, "5-pole-jack")) { - wcd_mbhc_cfg.enable_anc_mic_detect = true; - dev_dbg(&pdev->dev, "This hardware has 5 pole jack"); - } else if (!strcmp(mbhc_audio_jack_type, "6-pole-jack")) { - wcd_mbhc_cfg.enable_anc_mic_detect = true; - dev_dbg(&pdev->dev, "This hardware has 6 pole jack"); - } else { - wcd_mbhc_cfg.enable_anc_mic_detect = false; - dev_dbg(&pdev->dev, "Unknown value, set to default"); - } - } - /* - * Parse US-Euro gpio info from DT. Report no error if us-euro - * entry is not found in DT file as some targets do not support - * US-Euro detection - */ - pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node, - "qcom,us-euro-gpios", 0); - if (!gpio_is_valid(pdata->us_euro_gpio)) - pdata->us_euro_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,us-euro-gpios", 0); - if (!gpio_is_valid(pdata->us_euro_gpio) && (!pdata->us_euro_gpio_p)) { - dev_dbg(&pdev->dev, "property %s not detected in node %s", - "qcom,us-euro-gpios", pdev->dev.of_node->full_name); - } else { - dev_dbg(&pdev->dev, "%s detected", - "qcom,us-euro-gpios"); - wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; - } - - ret = msm_prepare_us_euro(card); - if (ret) - dev_dbg(&pdev->dev, "msm_prepare_us_euro failed (%d)\n", - ret); - - /* Parse pinctrl info from devicetree */ - ret = msm_get_pinctrl(pdev); - if (!ret) { - pr_debug("%s: pinctrl parsing successful\n", __func__); - } else { - dev_dbg(&pdev->dev, - "%s: Parsing pinctrl failed with %d. Cannot use Ports\n", - __func__, ret); - ret = 0; - } - - i2s_auxpcm_init(pdev); - - is_initial_boot = true; - ret = audio_notifier_register("msm8998", AUDIO_NOTIFIER_ADSP_DOMAIN, - &service_nb); - if (ret < 0) - pr_err("%s: Audio notifier register failed ret = %d\n", - __func__, ret); - - return 0; -err: - if (pdata->us_euro_gpio > 0) { - dev_dbg(&pdev->dev, "%s free us_euro gpio %d\n", - __func__, pdata->us_euro_gpio); - gpio_free(pdata->us_euro_gpio); - pdata->us_euro_gpio = 0; - } - msm_release_pinctrl(pdev); - devm_kfree(&pdev->dev, pdata); - return ret; -} - -static int msm_asoc_machine_remove(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct msm_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - - if (gpio_is_valid(pdata->us_euro_gpio)) - gpio_free(pdata->us_euro_gpio); - i2s_auxpcm_deinit(); - - snd_soc_unregister_card(card); - audio_notifier_deregister("msm8998"); - return 0; -} - -static struct platform_driver msm8998_asoc_machine_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .pm = &snd_soc_pm_ops, - .of_match_table = msm8998_asoc_machine_of_match, - }, - .probe = msm_asoc_machine_probe, - .remove = msm_asoc_machine_remove, -}; -module_platform_driver(msm8998_asoc_machine_driver); - -MODULE_DESCRIPTION("ALSA SoC msm"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:" DRV_NAME); -MODULE_DEVICE_TABLE(of, msm8998_asoc_machine_of_match); diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c deleted file mode 100644 index a33bbff22e56..000000000000 --- a/asoc/sdm660-common.c +++ /dev/null @@ -1,3551 +0,0 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "msm-pcm-routing-v2.h" -#include "sdm660-common.h" -#include "sdm660-internal.h" -#include "sdm660-external.h" -#include "codecs/msm-cdc-pinctrl.h" -#include "codecs/sdm660_cdc/msm-analog-cdc.h" -#include "codecs/wsa881x.h" - -#define __CHIPSET__ "SDM660 " -#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) - -#define DRV_NAME "sdm660-asoc-snd" - -#define MSM_INT_DIGITAL_CODEC "msm-dig-codec" -#define PMIC_INT_ANALOG_CODEC "analog-codec" - -#define DEV_NAME_STR_LEN 32 -#define DEFAULT_MCLK_RATE 9600000 -#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ - -struct dev_config { - u32 sample_rate; - u32 bit_format; - u32 channels; -}; - -enum { - DP_RX_IDX, - EXT_DISP_RX_IDX_MAX, -}; - -bool codec_reg_done; - -/* TDM default config */ -static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { - { /* PRI TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ - }, - { /* SEC TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ - }, - { /* TERT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ - }, - { /* QUAT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ - }, - { /* QUIN TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ - } -}; - -/* TDM default config */ -static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { - { /* PRI TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ - }, - { /* SEC TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ - }, - { /* TERT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ - }, - { /* QUAT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ - }, - { /* QUIN TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ - } -}; - -/* Default configuration of external display BE */ -static struct dev_config ext_disp_rx_cfg[] = { - [DP_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, -}; -static struct dev_config usb_rx_cfg = { - .sample_rate = SAMPLING_RATE_48KHZ, - .bit_format = SNDRV_PCM_FORMAT_S16_LE, - .channels = 2, -}; - -static struct dev_config usb_tx_cfg = { - .sample_rate = SAMPLING_RATE_48KHZ, - .bit_format = SNDRV_PCM_FORMAT_S16_LE, - .channels = 1, -}; - -enum { - PRIM_AUX_PCM = 0, - SEC_AUX_PCM, - TERT_AUX_PCM, - QUAT_AUX_PCM, - QUIN_AUX_PCM, - AUX_PCM_MAX, -}; - -enum { - PCM_I2S_SEL_PRIM = 0, - PCM_I2S_SEL_SEC, - PCM_I2S_SEL_TERT, - PCM_I2S_SEL_QUAT, - PCM_I2S_SEL_QUIN, - PCM_I2S_SEL_MAX, -}; - -struct mi2s_conf { - struct mutex lock; - u32 ref_cnt; - u32 msm_is_mi2s_master; - u32 msm_is_ext_mclk; -}; - -static u32 mi2s_ebit_clk[MI2S_MAX] = { - Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT, - Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT, - Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT, - Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT, - Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT -}; - -struct msm_wsa881x_dev_info { - struct device_node *of_node; - u32 index; -}; -static struct snd_soc_aux_dev *msm_aux_dev; -static struct snd_soc_codec_conf *msm_codec_conf; - -static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active); - -static struct wcd_mbhc_config mbhc_cfg = { - .read_fw_bin = false, - .calibration = NULL, - .detect_extn_cable = true, - .mono_stero_detection = false, - .swap_gnd_mic = NULL, - .hs_ext_micbias = true, - .key_code[0] = KEY_MEDIA, - .key_code[1] = KEY_VOICECOMMAND, - .key_code[2] = KEY_VOLUMEUP, - .key_code[3] = KEY_VOLUMEDOWN, - .key_code[4] = 0, - .key_code[5] = 0, - .key_code[6] = 0, - .key_code[7] = 0, - .linein_th = 5000, - .moisture_en = false, - .mbhc_micbias = 0, - .anc_micbias = 0, - .enable_anc_mic_detect = false, -}; - -static struct dev_config proxy_rx_cfg = { - .sample_rate = SAMPLING_RATE_48KHZ, - .bit_format = SNDRV_PCM_FORMAT_S16_LE, - .channels = 2, -}; - -/* Default configuration of MI2S channels */ -static struct dev_config mi2s_rx_cfg[] = { - [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, - [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, - [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, - [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, - [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, -}; - -static struct dev_config mi2s_tx_cfg[] = { - [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, -}; - -static struct dev_config aux_pcm_rx_cfg[] = { - [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, -}; - -static struct dev_config aux_pcm_tx_cfg[] = { - [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, -}; - -static char const *ch_text[] = {"Two", "Three", "Four", "Five", - "Six", "Seven", "Eight"}; -static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; -static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16", - "KHZ_32", "KHZ_44P1", "KHZ_48", - "KHZ_96", "KHZ_192"}; -static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", - "Eight"}; -static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", - "S32_LE"}; -static char const *mi2s_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", - "S32_LE"}; -static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", "Eight"}; -static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; -static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", - "KHZ_44P1", "KHZ_48", "KHZ_96", - "KHZ_192", "KHZ_352P8", "KHZ_384"}; -static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", - "Eight"}; -static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", - "KHZ_16", "KHZ_22P05", - "KHZ_32", "KHZ_44P1", "KHZ_48", - "KHZ_96", "KHZ_192", "KHZ_384"}; -static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE"}; -static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96", - "KHZ_192"}; -static const char *const qos_text[] = {"Disable", "Enable"}; - -static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_rx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_tx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_format, mi2s_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_format, mi2s_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_format, mi2s_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_format, mi2s_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_format, mi2s_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_format, mi2s_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_format, mi2s_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_format, mi2s_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_format, mi2s_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_format, mi2s_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, - ext_disp_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(qos_vote, qos_text); - -static int qos_vote_status; - -static struct afe_clk_set mi2s_clk[MI2S_MAX] = { - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - } -}; - -static struct afe_clk_set mi2s_mclk[MI2S_MAX] = { - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_MCLK_3, - Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_MCLK_2, - Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_MCLK_1, - Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_MCLK_1, - Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR, - Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - } -}; - -static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; - -static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: proxy_rx channels = %d\n", - __func__, proxy_rx_cfg.channels); - ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2; - - return 0; -} - -static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2; - pr_debug("%s: proxy_rx channels = %d\n", - __func__, proxy_rx_cfg.channels); - - return 1; -} - -static int tdm_get_sample_rate(int value) -{ - int sample_rate = 0; - - switch (value) { - case 0: - sample_rate = SAMPLING_RATE_8KHZ; - break; - case 1: - sample_rate = SAMPLING_RATE_16KHZ; - break; - case 2: - sample_rate = SAMPLING_RATE_32KHZ; - break; - case 3: - sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 4: - sample_rate = SAMPLING_RATE_48KHZ; - break; - case 5: - sample_rate = SAMPLING_RATE_96KHZ; - break; - case 6: - sample_rate = SAMPLING_RATE_192KHZ; - break; - case 7: - sample_rate = SAMPLING_RATE_352P8KHZ; - break; - case 8: - sample_rate = SAMPLING_RATE_384KHZ; - break; - default: - sample_rate = SAMPLING_RATE_48KHZ; - break; - } - return sample_rate; -} - -static int tdm_get_sample_rate_val(int sample_rate) -{ - int sample_rate_val = 0; - - switch (sample_rate) { - case SAMPLING_RATE_8KHZ: - sample_rate_val = 0; - break; - case SAMPLING_RATE_16KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_32KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 3; - break; - case SAMPLING_RATE_48KHZ: - sample_rate_val = 4; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 5; - break; - case SAMPLING_RATE_192KHZ: - sample_rate_val = 6; - break; - case SAMPLING_RATE_352P8KHZ: - sample_rate_val = 7; - break; - case SAMPLING_RATE_384KHZ: - sample_rate_val = 8; - break; - default: - sample_rate_val = 4; - break; - } - return sample_rate_val; -} - -static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, - struct tdm_port *port) -{ - if (port) { - if (strnstr(kcontrol->id.name, "PRI", - sizeof(kcontrol->id.name))) { - port->mode = TDM_PRI; - } else if (strnstr(kcontrol->id.name, "SEC", - sizeof(kcontrol->id.name))) { - port->mode = TDM_SEC; - } else if (strnstr(kcontrol->id.name, "TERT", - sizeof(kcontrol->id.name))) { - port->mode = TDM_TERT; - } else if (strnstr(kcontrol->id.name, "QUAT", - sizeof(kcontrol->id.name))) { - port->mode = TDM_QUAT; - } else if (strnstr(kcontrol->id.name, "QUIN", - sizeof(kcontrol->id.name))) { - port->mode = TDM_QUIN; - } else { - pr_err("%s: unsupported mode in: %s", - __func__, kcontrol->id.name); - return -EINVAL; - } - - if (strnstr(kcontrol->id.name, "RX_0", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_0", - sizeof(kcontrol->id.name))) { - port->channel = TDM_0; - } else if (strnstr(kcontrol->id.name, "RX_1", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_1", - sizeof(kcontrol->id.name))) { - port->channel = TDM_1; - } else if (strnstr(kcontrol->id.name, "RX_2", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_2", - sizeof(kcontrol->id.name))) { - port->channel = TDM_2; - } else if (strnstr(kcontrol->id.name, "RX_3", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_3", - sizeof(kcontrol->id.name))) { - port->channel = TDM_3; - } else if (strnstr(kcontrol->id.name, "RX_4", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_4", - sizeof(kcontrol->id.name))) { - port->channel = TDM_4; - } else if (strnstr(kcontrol->id.name, "RX_5", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_5", - sizeof(kcontrol->id.name))) { - port->channel = TDM_5; - } else if (strnstr(kcontrol->id.name, "RX_6", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_6", - sizeof(kcontrol->id.name))) { - port->channel = TDM_6; - } else if (strnstr(kcontrol->id.name, "RX_7", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_7", - sizeof(kcontrol->id.name))) { - port->channel = TDM_7; - } else { - pr_err("%s: unsupported channel in: %s", - __func__, kcontrol->id.name); - return -EINVAL; - } - } else - return -EINVAL; - return 0; -} - -static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( - tdm_rx_cfg[port.mode][port.channel].sample_rate); - - pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].sample_rate, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_rx_cfg[port.mode][port.channel].sample_rate = - tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].sample_rate, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( - tdm_tx_cfg[port.mode][port.channel].sample_rate); - - pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].sample_rate, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_tx_cfg[port.mode][port.channel].sample_rate = - tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].sample_rate, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_get_format(int value) -{ - int format = 0; - - switch (value) { - case 0: - format = SNDRV_PCM_FORMAT_S16_LE; - break; - case 1: - format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 2: - format = SNDRV_PCM_FORMAT_S32_LE; - break; - default: - format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - return format; -} - -static int tdm_get_format_val(int format) -{ - int value = 0; - - switch (format) { - case SNDRV_PCM_FORMAT_S16_LE: - value = 0; - break; - case SNDRV_PCM_FORMAT_S24_LE: - value = 1; - break; - case SNDRV_PCM_FORMAT_S32_LE: - value = 2; - break; - default: - value = 0; - break; - } - return value; -} - -static int mi2s_get_format(int value) -{ - int format = 0; - - switch (value) { - case 0: - format = SNDRV_PCM_FORMAT_S16_LE; - break; - case 1: - format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 2: - format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 3: - format = SNDRV_PCM_FORMAT_S32_LE; - break; - default: - format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - return format; -} - -static int mi2s_get_format_value(int format) -{ - int value = 0; - - switch (format) { - case SNDRV_PCM_FORMAT_S16_LE: - value = 0; - break; - case SNDRV_PCM_FORMAT_S24_LE: - value = 1; - break; - case SNDRV_PCM_FORMAT_S24_3LE: - value = 2; - break; - case SNDRV_PCM_FORMAT_S32_LE: - value = 3; - break; - default: - value = 0; - break; - } - return value; -} - -static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - ucontrol->value.enumerated.item[0] = tdm_get_format_val( - tdm_rx_cfg[port.mode][port.channel].bit_format); - - pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].bit_format, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_rx_cfg[port.mode][port.channel].bit_format = - tdm_get_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].bit_format, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - ucontrol->value.enumerated.item[0] = tdm_get_format_val( - tdm_tx_cfg[port.mode][port.channel].bit_format); - - pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].bit_format, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_tx_cfg[port.mode][port.channel].bit_format = - tdm_get_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].bit_format, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - - ucontrol->value.enumerated.item[0] = - tdm_rx_cfg[port.mode][port.channel].channels - 1; - - pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].channels - 1, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_rx_cfg[port.mode][port.channel].channels = - ucontrol->value.enumerated.item[0] + 1; - - pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].channels, - ucontrol->value.enumerated.item[0] + 1); - } - return ret; -} - -static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - ucontrol->value.enumerated.item[0] = - tdm_tx_cfg[port.mode][port.channel].channels - 1; - - pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].channels - 1, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_tx_cfg[port.mode][port.channel].channels = - ucontrol->value.enumerated.item[0] + 1; - - pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].channels, - ucontrol->value.enumerated.item[0] + 1); - } - return ret; -} - -static int aux_pcm_get_sample_rate(int value) -{ - int sample_rate; - - switch (value) { - case 1: - sample_rate = SAMPLING_RATE_16KHZ; - break; - case 0: - default: - sample_rate = SAMPLING_RATE_8KHZ; - break; - } - return sample_rate; -} - -static int aux_pcm_get_sample_rate_val(int sample_rate) -{ - int sample_rate_val; - - switch (sample_rate) { - case SAMPLING_RATE_16KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_8KHZ: - default: - sample_rate_val = 0; - break; - } - return sample_rate_val; -} - -static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) -{ - int idx; - - if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", - sizeof("PRIM_AUX_PCM"))) - idx = PRIM_AUX_PCM; - else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM", - sizeof("SEC_AUX_PCM"))) - idx = SEC_AUX_PCM; - else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", - sizeof("TERT_AUX_PCM"))) - idx = TERT_AUX_PCM; - else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", - sizeof("QUAT_AUX_PCM"))) - idx = QUAT_AUX_PCM; - else if (strnstr(kcontrol->id.name, "QUIN_AUX_PCM", - sizeof("QUIN_AUX_PCM"))) - idx = QUIN_AUX_PCM; - else { - pr_err("%s: unsupported port: %s", - __func__, kcontrol->id.name); - idx = -EINVAL; - } - - return idx; -} - -static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - aux_pcm_rx_cfg[idx].sample_rate = - aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, - idx, aux_pcm_rx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate); - - pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, - idx, aux_pcm_rx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - aux_pcm_tx_cfg[idx].sample_rate = - aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, - idx, aux_pcm_tx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate); - - pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, - idx, aux_pcm_tx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) -{ - int idx; - - if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX", - sizeof("PRIM_MI2S_RX"))) - idx = PRIM_MI2S; - else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX", - sizeof("SEC_MI2S_RX"))) - idx = SEC_MI2S; - else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", - sizeof("TERT_MI2S_RX"))) - idx = TERT_MI2S; - else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", - sizeof("QUAT_MI2S_RX"))) - idx = QUAT_MI2S; - else if (strnstr(kcontrol->id.name, "QUIN_MI2S_RX", - sizeof("QUIN_MI2S_RX"))) - idx = QUIN_MI2S; - else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", - sizeof("PRIM_MI2S_TX"))) - idx = PRIM_MI2S; - else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX", - sizeof("SEC_MI2S_TX"))) - idx = SEC_MI2S; - else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", - sizeof("TERT_MI2S_TX"))) - idx = TERT_MI2S; - else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", - sizeof("QUAT_MI2S_TX"))) - idx = QUAT_MI2S; - else if (strnstr(kcontrol->id.name, "QUIN_MI2S_TX", - sizeof("QUIN_MI2S_TX"))) - idx = QUIN_MI2S; - else { - pr_err("%s: unsupported channel: %s", - __func__, kcontrol->id.name); - idx = -EINVAL; - } - - return idx; -} - -static int mi2s_get_sample_rate_val(int sample_rate) -{ - int sample_rate_val; - - switch (sample_rate) { - case SAMPLING_RATE_8KHZ: - sample_rate_val = 0; - break; - case SAMPLING_RATE_16KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_32KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 3; - break; - case SAMPLING_RATE_48KHZ: - sample_rate_val = 4; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 5; - break; - case SAMPLING_RATE_192KHZ: - sample_rate_val = 6; - break; - default: - sample_rate_val = 4; - break; - } - return sample_rate_val; -} - -static int mi2s_get_sample_rate(int value) -{ - int sample_rate; - - switch (value) { - case 0: - sample_rate = SAMPLING_RATE_8KHZ; - break; - case 1: - sample_rate = SAMPLING_RATE_16KHZ; - break; - case 2: - sample_rate = SAMPLING_RATE_32KHZ; - break; - case 3: - sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 4: - sample_rate = SAMPLING_RATE_48KHZ; - break; - case 5: - sample_rate = SAMPLING_RATE_96KHZ; - break; - case 6: - sample_rate = SAMPLING_RATE_192KHZ; - break; - default: - sample_rate = SAMPLING_RATE_48KHZ; - break; - } - return sample_rate; -} - -static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_rx_cfg[idx].sample_rate = - mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, - idx, mi2s_rx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate); - - pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, - idx, mi2s_rx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_tx_cfg[idx].sample_rate = - mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, - idx, mi2s_tx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate); - - pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, - idx, mi2s_tx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int mi2s_tx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_tx_cfg[idx].bit_format = - mi2s_get_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d] _tx_format = %d, item = %d\n", __func__, - idx, mi2s_tx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int mi2s_tx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - mi2s_get_format_value(mi2s_tx_cfg[idx].bit_format); - - pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, - idx, mi2s_tx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int mi2s_rx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_rx_cfg[idx].bit_format = - mi2s_get_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d] _rx_format = %d, item = %d\n", __func__, - idx, mi2s_rx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int mi2s_rx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - mi2s_get_format_value(mi2s_rx_cfg[idx].bit_format); - - pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, - idx, mi2s_rx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, - idx, mi2s_rx_cfg[idx].channels); - ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1; - - return 0; -} - -static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; - pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, - idx, mi2s_rx_cfg[idx].channels); - - return 1; -} - -static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, - idx, mi2s_tx_cfg[idx].channels); - ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1; - - return 0; -} - -static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; - pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, - idx, mi2s_tx_cfg[idx].channels); - - return 1; -} - -static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, - usb_rx_cfg.channels); - ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1; - return 0; -} - -static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1; - - pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels); - return 1; -} - -static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val; - - switch (usb_rx_cfg.sample_rate) { - case SAMPLING_RATE_384KHZ: - sample_rate_val = 9; - break; - case SAMPLING_RATE_192KHZ: - sample_rate_val = 8; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 7; - break; - case SAMPLING_RATE_48KHZ: - sample_rate_val = 6; - break; - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 5; - break; - case SAMPLING_RATE_32KHZ: - sample_rate_val = 4; - break; - case SAMPLING_RATE_22P05KHZ: - sample_rate_val = 3; - break; - case SAMPLING_RATE_16KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_11P025KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_8KHZ: - default: - sample_rate_val = 0; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__, - usb_rx_cfg.sample_rate); - return 0; -} - -static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 9: - usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ; - break; - case 8: - usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ; - break; - case 7: - usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ; - break; - case 6: - usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; - break; - case 5: - usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 4: - usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ; - break; - case 3: - usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; - break; - case 2: - usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ; - break; - case 1: - usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; - break; - case 0: - usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ; - break; - default: - usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; - break; - } - - pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n", - __func__, ucontrol->value.integer.value[0], - usb_rx_cfg.sample_rate); - return 0; -} - -static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (usb_rx_cfg.bit_format) { - case SNDRV_PCM_FORMAT_S32_LE: - ucontrol->value.integer.value[0] = 3; - break; - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", - __func__, usb_rx_cfg.bit_format, - ucontrol->value.integer.value[0]); - return 0; -} - -static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int rc = 0; - - switch (ucontrol->value.integer.value[0]) { - case 3: - usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; - break; - case 2: - usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", - __func__, usb_rx_cfg.bit_format, - ucontrol->value.integer.value[0]); - - return rc; -} - -static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, - usb_tx_cfg.channels); - ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1; - return 0; -} - -static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1; - - pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels); - return 1; -} - -static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val; - - switch (usb_tx_cfg.sample_rate) { - case SAMPLING_RATE_384KHZ: - sample_rate_val = 9; - break; - case SAMPLING_RATE_192KHZ: - sample_rate_val = 8; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 7; - break; - case SAMPLING_RATE_48KHZ: - sample_rate_val = 6; - break; - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 5; - break; - case SAMPLING_RATE_32KHZ: - sample_rate_val = 4; - break; - case SAMPLING_RATE_22P05KHZ: - sample_rate_val = 3; - break; - case SAMPLING_RATE_16KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_11P025KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_8KHZ: - sample_rate_val = 0; - break; - default: - sample_rate_val = 6; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__, - usb_tx_cfg.sample_rate); - return 0; -} - -static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 9: - usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ; - break; - case 8: - usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ; - break; - case 7: - usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ; - break; - case 6: - usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; - break; - case 5: - usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 4: - usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ; - break; - case 3: - usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; - break; - case 2: - usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ; - break; - case 1: - usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; - break; - case 0: - usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ; - break; - default: - usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; - break; - } - - pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n", - __func__, ucontrol->value.integer.value[0], - usb_tx_cfg.sample_rate); - return 0; -} - -static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (usb_tx_cfg.bit_format) { - case SNDRV_PCM_FORMAT_S32_LE: - ucontrol->value.integer.value[0] = 3; - break; - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", - __func__, usb_tx_cfg.bit_format, - ucontrol->value.integer.value[0]); - return 0; -} - -static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int rc = 0; - - switch (ucontrol->value.integer.value[0]) { - case 3: - usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; - break; - case 2: - usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", - __func__, usb_tx_cfg.bit_format, - ucontrol->value.integer.value[0]); - - return rc; -} - -static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol) -{ - int idx; - - if (strnstr(kcontrol->id.name, "Display Port RX", - sizeof("Display Port RX"))) - idx = DP_RX_IDX; - else { - pr_err("%s: unsupported BE: %s", - __func__, kcontrol->id.name); - idx = -EINVAL; - } - - return idx; -} - -static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - switch (ext_disp_rx_cfg[idx].bit_format) { - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", - __func__, idx, ext_disp_rx_cfg[idx].bit_format, - ucontrol->value.integer.value[0]); - return 0; -} - -static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - switch (ucontrol->value.integer.value[0]) { - case 1: - ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", - __func__, idx, ext_disp_rx_cfg[idx].bit_format, - ucontrol->value.integer.value[0]); - - return 0; -} - -static int ext_disp_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.integer.value[0] = - ext_disp_rx_cfg[idx].channels - 2; - - pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, - idx, ext_disp_rx_cfg[idx].channels); - - return 0; -} - -static int ext_disp_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ext_disp_rx_cfg[idx].channels = - ucontrol->value.integer.value[0] + 2; - - pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, - idx, ext_disp_rx_cfg[idx].channels); - return 1; -} - -static int ext_disp_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val; - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - switch (ext_disp_rx_cfg[idx].sample_rate) { - case SAMPLING_RATE_192KHZ: - sample_rate_val = 2; - break; - - case SAMPLING_RATE_96KHZ: - sample_rate_val = 1; - break; - - case SAMPLING_RATE_48KHZ: - default: - sample_rate_val = 0; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: ext_disp_rx[%d].sample_rate = %d\n", __func__, - idx, ext_disp_rx_cfg[idx].sample_rate); - - return 0; -} - -static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - switch (ucontrol->value.integer.value[0]) { - case 2: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ; - break; - case 1: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ; - break; - case 0: - default: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ; - break; - } - - pr_debug("%s: control value = %ld, ext_disp_rx[%d].sample_rate = %d\n", - __func__, ucontrol->value.integer.value[0], idx, - ext_disp_rx_cfg[idx].sample_rate); - return 0; -} - -static int msm_qos_ctl_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.enumerated.item[0] = qos_vote_status; - - return 0; -} - -static int msm_qos_ctl_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct snd_soc_card *card = codec->component.card; - const char *fe_name = MSM_DAILINK_NAME(LowLatency); - struct snd_soc_pcm_runtime *rtd; - struct snd_pcm_substream *substream; - s32 usecs; - - rtd = snd_soc_get_pcm_runtime(card, fe_name); - if (!rtd) { - pr_err("%s: fail to get pcm runtime for %s\n", - __func__, fe_name); - return -EINVAL; - } - - substream = rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; - if (!substream) { - pr_err("%s: substream is null\n", __func__); - return -EINVAL; - } - - qos_vote_status = ucontrol->value.enumerated.item[0]; - if (qos_vote_status) { - if (pm_qos_request_active(&substream->latency_pm_qos_req)) - pm_qos_remove_request(&substream->latency_pm_qos_req); - if (!substream->runtime) { - pr_err("%s: runtime is null\n", __func__); - return -EINVAL; - } - usecs = MSM_LL_QOS_VALUE; - if (usecs >= 0) - pm_qos_add_request(&substream->latency_pm_qos_req, - PM_QOS_CPU_DMA_LATENCY, usecs); - } else { - if (pm_qos_request_active(&substream->latency_pm_qos_req)) - pm_qos_remove_request(&substream->latency_pm_qos_req); - } - - return 0; -} - -const struct snd_kcontrol_new msm_common_snd_controls[] = { - SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, - proxy_rx_ch_get, proxy_rx_ch_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("QUIN_AUX_PCM_RX SampleRate", quin_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("QUIN_AUX_PCM_TX SampleRate", quin_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, - mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate, - mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, - mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, - mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("QUIN_MI2S_RX SampleRate", quin_mi2s_rx_sample_rate, - mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, - mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, - mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, - mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, - mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("QUIN_MI2S_TX SampleRate", quin_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, - mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("PRIM_MI2S_RX Format", prim_mi2s_rx_format, - mi2s_rx_format_get, - mi2s_rx_format_put), - SOC_ENUM_EXT("SEC_MI2S_RX Format", sec_mi2s_rx_format, - mi2s_rx_format_get, - mi2s_rx_format_put), - SOC_ENUM_EXT("TERT_MI2S_RX Format", tert_mi2s_rx_format, - mi2s_rx_format_get, - mi2s_rx_format_put), - SOC_ENUM_EXT("QUAT_MI2S_RX Format", quat_mi2s_rx_format, - mi2s_rx_format_get, - mi2s_rx_format_put), - SOC_ENUM_EXT("QUIN_MI2S_RX Format", quin_mi2s_rx_format, - mi2s_rx_format_get, - mi2s_rx_format_put), - SOC_ENUM_EXT("PRIM_MI2S_TX Format", prim_mi2s_tx_format, - mi2s_tx_format_get, - mi2s_tx_format_put), - SOC_ENUM_EXT("SEC_MI2S_TX Format", sec_mi2s_tx_format, - mi2s_tx_format_get, - mi2s_tx_format_put), - SOC_ENUM_EXT("TERT_MI2S_TX Format", tert_mi2s_tx_format, - mi2s_tx_format_get, - mi2s_tx_format_put), - SOC_ENUM_EXT("QUAT_MI2S_TX Format", quat_mi2s_tx_format, - mi2s_tx_format_get, - mi2s_tx_format_put), - SOC_ENUM_EXT("QUIN_MI2S_TX Format", quin_mi2s_tx_format, - mi2s_tx_format_get, - mi2s_tx_format_put), - SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, - msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), - SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, - msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, - msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), - SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, - msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, - msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), - SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, - msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs, - msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), - SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, - msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("QUIN_MI2S_RX Channels", quin_mi2s_rx_chs, - msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), - SOC_ENUM_EXT("QUIN_MI2S_TX Channels", quin_mi2s_tx_chs, - msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, - usb_audio_rx_ch_get, usb_audio_rx_ch_put), - SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, - usb_audio_tx_ch_get, usb_audio_tx_ch_put), - SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, - ext_disp_rx_ch_get, ext_disp_rx_ch_put), - SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, - usb_audio_rx_format_get, usb_audio_rx_format_put), - SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, - usb_audio_tx_format_get, usb_audio_tx_format_put), - SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, - ext_disp_rx_format_get, ext_disp_rx_format_put), - SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, - usb_audio_rx_sample_rate_get, - usb_audio_rx_sample_rate_put), - SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, - usb_audio_tx_sample_rate_get, - usb_audio_tx_sample_rate_put), - SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, - ext_disp_rx_sample_rate_get, - ext_disp_rx_sample_rate_put), - SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, - tdm_rx_sample_rate_get, - tdm_rx_sample_rate_put), - SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, - tdm_tx_sample_rate_get, - tdm_tx_sample_rate_put), - SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, - tdm_rx_sample_rate_get, - tdm_rx_sample_rate_put), - SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, - tdm_tx_sample_rate_get, - tdm_tx_sample_rate_put), - SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, - tdm_rx_sample_rate_get, - tdm_rx_sample_rate_put), - SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, - tdm_tx_sample_rate_get, - tdm_tx_sample_rate_put), - SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, - tdm_rx_sample_rate_get, - tdm_rx_sample_rate_put), - SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, - tdm_tx_sample_rate_get, - tdm_tx_sample_rate_put), - SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("QUIN_TDM_RX_0 SampleRate", tdm_rx_sample_rate, - tdm_rx_sample_rate_get, - tdm_rx_sample_rate_put), - SOC_ENUM_EXT("QUIN_TDM_TX_0 SampleRate", tdm_tx_sample_rate, - tdm_tx_sample_rate_get, - tdm_tx_sample_rate_put), - SOC_ENUM_EXT("QUIN_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("QUIN_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("QUIN_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("QUIN_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("MultiMedia5_RX QOS Vote", qos_vote, msm_qos_ctl_get, - msm_qos_ctl_put), -}; - -/** - * msm_common_snd_controls_size - to return controls size - * - * Return: returns size of common controls array - */ -int msm_common_snd_controls_size(void) -{ - return ARRAY_SIZE(msm_common_snd_controls); -} -EXPORT_SYMBOL(msm_common_snd_controls_size); - -void msm_set_codec_reg_done(bool done) -{ - codec_reg_done = done; -} -EXPORT_SYMBOL(msm_set_codec_reg_done); - -static inline int param_is_mask(int p) -{ - return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && - (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); -} - -static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, - int n) -{ - return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); -} - -static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit) -{ - if (bit >= SNDRV_MASK_MAX) - return; - if (param_is_mask(n)) { - struct snd_mask *m = param_to_mask(p, n); - - m->bits[0] = 0; - m->bits[1] = 0; - m->bits[bit >> 5] |= (1 << (bit & 31)); - } -} - -static int msm_ext_disp_get_idx_from_beid(int32_t id) -{ - int idx; - - switch (id) { - case MSM_BACKEND_DAI_DISPLAY_PORT_RX: - idx = DP_RX_IDX; - break; - default: - pr_err("%s: Incorrect ext_disp id %d\n", __func__, id); - idx = -EINVAL; - break; - } - - return idx; -} - -/** - * msm_common_be_hw_params_fixup - updates settings of ALSA BE hw params. - * - * @rtd: runtime dailink instance - * @params: HW params of associated backend dailink. - * - * Returns 0. - */ -int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_dai_link *dai_link = rtd->dai_link; - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - int rc = 0; - int idx; - - pr_debug("%s: format = %d, rate = %d\n", - __func__, params_format(params), params_rate(params)); - - switch (dai_link->id) { - case MSM_BACKEND_DAI_USB_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - usb_rx_cfg.bit_format); - rate->min = rate->max = usb_rx_cfg.sample_rate; - channels->min = channels->max = usb_rx_cfg.channels; - break; - - case MSM_BACKEND_DAI_USB_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - usb_tx_cfg.bit_format); - rate->min = rate->max = usb_tx_cfg.sample_rate; - channels->min = channels->max = usb_tx_cfg.channels; - break; - - case MSM_BACKEND_DAI_DISPLAY_PORT_RX: - idx = msm_ext_disp_get_idx_from_beid(dai_link->id); - if (idx < 0) { - pr_err("%s: Incorrect ext disp idx %d\n", - __func__, idx); - rc = idx; - break; - } - - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - ext_disp_rx_cfg[idx].bit_format); - rate->min = rate->max = ext_disp_rx_cfg[idx].sample_rate; - channels->min = channels->max = ext_disp_rx_cfg[idx].channels; - break; - - case MSM_BACKEND_DAI_AFE_PCM_RX: - channels->min = channels->max = proxy_rx_cfg.channels; - rate->min = rate->max = SAMPLING_RATE_48KHZ; - break; - - case MSM_BACKEND_DAI_PRI_TDM_RX_0: - channels->min = channels->max = - tdm_rx_cfg[TDM_PRI][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_PRI_TDM_TX_0: - channels->min = channels->max = - tdm_tx_cfg[TDM_PRI][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); - rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_SEC_TDM_RX_0: - channels->min = channels->max = - tdm_rx_cfg[TDM_SEC][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_SEC_TDM_TX_0: - channels->min = channels->max = - tdm_tx_cfg[TDM_SEC][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); - rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_TERT_TDM_RX_0: - channels->min = channels->max = - tdm_rx_cfg[TDM_TERT][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_TERT_TDM_TX_0: - channels->min = channels->max = - tdm_tx_cfg[TDM_TERT][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); - rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_QUAT_TDM_RX_0: - channels->min = channels->max = - tdm_rx_cfg[TDM_QUAT][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_QUAT_TDM_TX_0: - channels->min = channels->max = - tdm_tx_cfg[TDM_QUAT][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); - rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_QUIN_TDM_RX_0: - channels->min = channels->max = - tdm_rx_cfg[TDM_QUIN][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_QUIN_TDM_TX_0: - channels->min = channels->max = - tdm_tx_cfg[TDM_QUIN][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_tx_cfg[TDM_QUIN][TDM_0].bit_format); - rate->min = rate->max = tdm_tx_cfg[TDM_QUIN][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_AUXPCM_RX: - rate->min = rate->max = - aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_rx_cfg[PRIM_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_AUXPCM_TX: - rate->min = rate->max = - aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_tx_cfg[PRIM_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_SEC_AUXPCM_RX: - rate->min = rate->max = - aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_rx_cfg[SEC_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_SEC_AUXPCM_TX: - rate->min = rate->max = - aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_tx_cfg[SEC_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_TERT_AUXPCM_RX: - rate->min = rate->max = - aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_rx_cfg[TERT_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_TERT_AUXPCM_TX: - rate->min = rate->max = - aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_tx_cfg[TERT_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_QUAT_AUXPCM_RX: - rate->min = rate->max = - aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_rx_cfg[QUAT_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_QUAT_AUXPCM_TX: - rate->min = rate->max = - aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_tx_cfg[QUAT_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_QUIN_AUXPCM_RX: - rate->min = rate->max = - aux_pcm_rx_cfg[QUIN_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_rx_cfg[QUIN_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_QUIN_AUXPCM_TX: - rate->min = rate->max = - aux_pcm_tx_cfg[QUIN_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_tx_cfg[QUIN_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_PRI_MI2S_RX: - rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate; - channels->min = channels->max = - mi2s_rx_cfg[PRIM_MI2S].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_rx_cfg[PRIM_MI2S].bit_format); - break; - - case MSM_BACKEND_DAI_PRI_MI2S_TX: - rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate; - channels->min = channels->max = - mi2s_tx_cfg[PRIM_MI2S].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_tx_cfg[PRIM_MI2S].bit_format); - break; - - case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: - rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate; - channels->min = channels->max = - mi2s_rx_cfg[SEC_MI2S].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_rx_cfg[SEC_MI2S].bit_format); - break; - - case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: - rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate; - channels->min = channels->max = - mi2s_tx_cfg[SEC_MI2S].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_tx_cfg[SEC_MI2S].bit_format); - break; - - case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: - rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate; - channels->min = channels->max = - mi2s_rx_cfg[TERT_MI2S].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_rx_cfg[TERT_MI2S].bit_format); - break; - - case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: - rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate; - channels->min = channels->max = - mi2s_tx_cfg[TERT_MI2S].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_tx_cfg[TERT_MI2S].bit_format); - break; - - case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: - rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate; - channels->min = channels->max = - mi2s_rx_cfg[QUAT_MI2S].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_rx_cfg[QUAT_MI2S].bit_format); - break; - - case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: - rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate; - channels->min = channels->max = - mi2s_tx_cfg[QUAT_MI2S].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_tx_cfg[QUAT_MI2S].bit_format); - break; - - case MSM_BACKEND_DAI_QUINARY_MI2S_RX: - rate->min = rate->max = mi2s_rx_cfg[QUIN_MI2S].sample_rate; - channels->min = channels->max = - mi2s_rx_cfg[QUIN_MI2S].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_rx_cfg[QUIN_MI2S].bit_format); - break; - - case MSM_BACKEND_DAI_QUINARY_MI2S_TX: - rate->min = rate->max = mi2s_tx_cfg[QUIN_MI2S].sample_rate; - channels->min = channels->max = - mi2s_tx_cfg[QUIN_MI2S].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_tx_cfg[QUIN_MI2S].bit_format); - break; - - default: - rate->min = rate->max = SAMPLING_RATE_48KHZ; - break; - } - return rc; -} -EXPORT_SYMBOL(msm_common_be_hw_params_fixup); - -/** - * msm_aux_pcm_snd_startup - startup ops of auxpcm. - * - * @substream: PCM stream pointer of associated backend dailink - * - * Returns 0 on success or -EINVAL on error. - */ -int msm_aux_pcm_snd_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - - dev_dbg(rtd->card->dev, - "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", - __func__, substream->name, substream->stream, - rtd->cpu_dai->name, rtd->cpu_dai->id); - - return 0; -} -EXPORT_SYMBOL(msm_aux_pcm_snd_startup); - -/** - * msm_aux_pcm_snd_shutdown - shutdown ops of auxpcm. - * - * @substream: PCM stream pointer of associated backend dailink - */ -void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - - dev_dbg(rtd->card->dev, - "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", - __func__, - substream->name, substream->stream, - rtd->cpu_dai->name, rtd->cpu_dai->id); -} -EXPORT_SYMBOL(msm_aux_pcm_snd_shutdown); - -static int msm_get_port_id(int id) -{ - int afe_port_id; - - switch (id) { - case MSM_BACKEND_DAI_PRI_MI2S_RX: - afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; - break; - case MSM_BACKEND_DAI_PRI_MI2S_TX: - afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; - break; - case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: - afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; - break; - case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: - afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; - break; - case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: - afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; - break; - case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: - afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; - break; - case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: - afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; - break; - case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: - afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; - break; - case MSM_BACKEND_DAI_QUINARY_MI2S_RX: - afe_port_id = AFE_PORT_ID_QUINARY_MI2S_RX; - break; - case MSM_BACKEND_DAI_QUINARY_MI2S_TX: - afe_port_id = AFE_PORT_ID_QUINARY_MI2S_TX; - break; - default: - pr_err("%s: Invalid id: %d\n", __func__, id); - afe_port_id = -EINVAL; - } - - return afe_port_id; -} - -static u32 get_mi2s_bits_per_sample(u32 bit_format) -{ - u32 bit_per_sample; - - switch (bit_format) { - case SNDRV_PCM_FORMAT_S32_LE: - case SNDRV_PCM_FORMAT_S24_3LE: - case SNDRV_PCM_FORMAT_S24_LE: - bit_per_sample = 32; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - bit_per_sample = 16; - break; - } - - return bit_per_sample; -} - -static void update_mi2s_clk_val(int dai_id, int stream) -{ - u32 bit_per_sample; - - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - bit_per_sample = - get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format); - mi2s_clk[dai_id].clk_freq_in_hz = - mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample; - } else { - bit_per_sample = - get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format); - mi2s_clk[dai_id].clk_freq_in_hz = - mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample; - } -} - -static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) -{ - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int port_id = 0; - int index = cpu_dai->id; - - port_id = msm_get_port_id(rtd->dai_link->id); - if (port_id < 0) { - dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); - ret = port_id; - goto done; - } - - if (enable) { - update_mi2s_clk_val(index, substream->stream); - dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, - mi2s_clk[index].clk_freq_in_hz); - } - - mi2s_clk[index].enable = enable; - ret = afe_set_lpass_clock_v2(port_id, - &mi2s_clk[index]); - if (ret < 0) { - dev_err(rtd->card->dev, - "%s: afe lpass clock failed for port 0x%x , err:%d\n", - __func__, port_id, ret); - goto done; - } - -done: - return ret; -} - -/** - * msm_mi2s_snd_startup - startup ops of mi2s. - * - * @substream: PCM stream pointer of associated backend dailink - * - * Returns 0 on success or -EINVAL on error. - */ -int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) -{ - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int port_id = msm_get_port_id(rtd->dai_link->id); - int index = cpu_dai->id; - unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; - struct msm_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(rtd->card); - - dev_dbg(rtd->card->dev, - "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", - __func__, substream->name, substream->stream, - cpu_dai->name, cpu_dai->id); - - if (index < PRIM_MI2S || index >= MI2S_MAX) { - ret = -EINVAL; - dev_err(rtd->card->dev, - "%s: CPU DAI id (%d) out of range\n", - __func__, cpu_dai->id); - goto done; - } - /* - * Muxtex protection in case the same MI2S - * interface using for both TX and RX so - * that the same clock won't be enable twice. - */ - mutex_lock(&mi2s_intf_conf[index].lock); - if (++mi2s_intf_conf[index].ref_cnt == 1) { - /* Check if msm needs to provide the clock to the interface */ - if (!mi2s_intf_conf[index].msm_is_mi2s_master) { - mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; - fmt = SND_SOC_DAIFMT_CBM_CFM; - } - ret = msm_mi2s_set_sclk(substream, true); - if (ret < 0) { - dev_err(rtd->card->dev, - "%s: afe lpass clock failed to enable MI2S clock, err:%d\n", - __func__, ret); - goto clean_up; - } - ret = snd_soc_dai_set_fmt(cpu_dai, fmt); - if (ret < 0) { - dev_err(rtd->card->dev, - "%s: set fmt cpu dai failed for MI2S (%d), err:%d\n", - __func__, index, ret); - goto clk_off; - } - if (mi2s_intf_conf[index].msm_is_ext_mclk) { - mi2s_mclk[index].enable = 1; - pr_debug("%s: Enabling mclk, clk_freq_in_hz = %u\n", - __func__, mi2s_mclk[index].clk_freq_in_hz); - ret = afe_set_lpass_clock_v2(port_id, - &mi2s_mclk[index]); - if (ret < 0) { - pr_err("%s: afe lpass mclk failed, err:%d\n", - __func__, ret); - goto clk_off; - } - } - if (pdata->mi2s_gpio_p[index]) - msm_cdc_pinctrl_select_active_state( - pdata->mi2s_gpio_p[index]); - } - mutex_unlock(&mi2s_intf_conf[index].lock); - return 0; -clk_off: - if (ret < 0) - msm_mi2s_set_sclk(substream, false); -clean_up: - if (ret < 0) - mi2s_intf_conf[index].ref_cnt--; - mutex_unlock(&mi2s_intf_conf[index].lock); -done: - return ret; -} -EXPORT_SYMBOL(msm_mi2s_snd_startup); - -/** - * msm_mi2s_snd_shutdown - shutdown ops of mi2s. - * - * @substream: PCM stream pointer of associated backend dailink - */ -void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) -{ - int ret; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - int port_id = msm_get_port_id(rtd->dai_link->id); - int index = rtd->cpu_dai->id; - struct msm_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(rtd->card); - - pr_debug("%s(): substream = %s stream = %d\n", __func__, - substream->name, substream->stream); - if (index < PRIM_MI2S || index >= MI2S_MAX) { - pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); - return; - } - - mutex_lock(&mi2s_intf_conf[index].lock); - if (--mi2s_intf_conf[index].ref_cnt == 0) { - if (pdata->mi2s_gpio_p[index]) - msm_cdc_pinctrl_select_sleep_state( - pdata->mi2s_gpio_p[index]); - - ret = msm_mi2s_set_sclk(substream, false); - if (ret < 0) - pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", - __func__, index, ret); - - if (mi2s_intf_conf[index].msm_is_ext_mclk) { - mi2s_mclk[index].enable = 0; - pr_debug("%s: Disabling mclk, clk_freq_in_hz = %u\n", - __func__, mi2s_mclk[index].clk_freq_in_hz); - ret = afe_set_lpass_clock_v2(port_id, - &mi2s_mclk[index]); - if (ret < 0) { - pr_err("%s: mclk disable failed for MCLK (%d); ret=%d\n", - __func__, index, ret); - } - } - } - mutex_unlock(&mi2s_intf_conf[index].lock); -} -EXPORT_SYMBOL(msm_mi2s_snd_shutdown); - -/* Validate whether US EU switch is present or not */ -static int msm_prepare_us_euro(struct snd_soc_card *card) -{ - struct msm_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - int ret = 0; - - if (pdata->us_euro_gpio >= 0) { - dev_dbg(card->dev, "%s: us_euro gpio request %d", __func__, - pdata->us_euro_gpio); - ret = gpio_request(pdata->us_euro_gpio, "TASHA_CODEC_US_EURO"); - if (ret) { - dev_err(card->dev, - "%s: Failed to request codec US/EURO gpio %d error %d\n", - __func__, pdata->us_euro_gpio, ret); - } - } - - return ret; -} - - -static bool msm_usbc_swap_gnd_mic(struct snd_soc_codec *codec, bool active) -{ - int value = 0; - bool ret = false; - struct snd_soc_card *card = codec->component.card; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct pinctrl_state *en2_pinctrl_active; - struct pinctrl_state *en2_pinctrl_sleep; - - if (!pdata->usbc_en2_gpio_p) { - if (active) { - /* if active and usbc_en2_gpio undefined, get pin */ - pdata->usbc_en2_gpio_p = devm_pinctrl_get(card->dev); - if (IS_ERR_OR_NULL(pdata->usbc_en2_gpio_p)) { - dev_err(card->dev, - "%s: Can't get EN2 gpio pinctrl:%ld\n", - __func__, - PTR_ERR(pdata->usbc_en2_gpio_p)); - pdata->usbc_en2_gpio_p = NULL; - return false; - } - } else { - /* if not active and usbc_en2_gpio undefined, return */ - return false; - } - } - - pdata->usbc_en2_gpio = of_get_named_gpio(card->dev->of_node, - "qcom,usbc-analog-en2-gpio", 0); - if (!gpio_is_valid(pdata->usbc_en2_gpio)) { - dev_err(card->dev, "%s, property %s not in node %s\n", - __func__, "qcom,usbc-analog-en2-gpio", - card->dev->of_node->full_name); - return false; - } - - en2_pinctrl_active = pinctrl_lookup_state( - pdata->usbc_en2_gpio_p, "aud_active"); - if (IS_ERR_OR_NULL(en2_pinctrl_active)) { - dev_err(card->dev, - "%s: Cannot get aud_active pinctrl state:%ld\n", - __func__, PTR_ERR(en2_pinctrl_active)); - ret = false; - goto err_lookup_state; - } - - en2_pinctrl_sleep = pinctrl_lookup_state( - pdata->usbc_en2_gpio_p, "aud_sleep"); - if (IS_ERR_OR_NULL(en2_pinctrl_sleep)) { - dev_err(card->dev, - "%s: Cannot get aud_sleep pinctrl state:%ld\n", - __func__, PTR_ERR(en2_pinctrl_sleep)); - ret = false; - goto err_lookup_state; - } - - /* if active and usbc_en2_gpio_p defined, swap using usbc_en2_gpio_p */ - if (active) { - dev_dbg(codec->dev, "%s: enter\n", __func__); - if (pdata->usbc_en2_gpio_p) { - value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); - if (value) - pinctrl_select_state(pdata->usbc_en2_gpio_p, - en2_pinctrl_sleep); - else - pinctrl_select_state(pdata->usbc_en2_gpio_p, - en2_pinctrl_active); - } else if (pdata->usbc_en2_gpio >= 0) { - value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); - gpio_set_value_cansleep(pdata->usbc_en2_gpio, !value); - } - pr_debug("%s: swap select switch %d to %d\n", __func__, - value, !value); - ret = true; - } else { - /* if not active, release usbc_en2_gpio_p pin */ - pinctrl_select_state(pdata->usbc_en2_gpio_p, - en2_pinctrl_sleep); - } - -err_lookup_state: - devm_pinctrl_put(pdata->usbc_en2_gpio_p); - pdata->usbc_en2_gpio_p = NULL; - return ret; -} - -static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) -{ - struct snd_soc_card *card = codec->component.card; - struct msm_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - int value = 0; - bool ret = 0; - - if (!mbhc_cfg.enable_usbc_analog) { - if (pdata->us_euro_gpio_p) { - value = msm_cdc_pinctrl_get_state( - pdata->us_euro_gpio_p); - if (value) - msm_cdc_pinctrl_select_sleep_state( - pdata->us_euro_gpio_p); - else - msm_cdc_pinctrl_select_active_state( - pdata->us_euro_gpio_p); - } else if (pdata->us_euro_gpio >= 0) { - value = gpio_get_value_cansleep(pdata->us_euro_gpio); - gpio_set_value_cansleep(pdata->us_euro_gpio, !value); - } - pr_debug("%s: swap select switch %d to %d\n", - __func__, value, !value); - ret = true; - } else { - /* if usbc is defined, swap using usbc_en2 */ - ret = msm_usbc_swap_gnd_mic(codec, active); - } - return ret; -} - -static int msm_populate_dai_link_component_of_node( - struct msm_asoc_mach_data *pdata, - struct snd_soc_card *card) -{ - int i, index, ret = 0; - struct device *cdev = card->dev; - struct snd_soc_dai_link *dai_link = card->dai_link; - struct device_node *phandle; - - if (!cdev) { - pr_err("%s: Sound card device memory NULL\n", __func__); - return -ENODEV; - } - - for (i = 0; i < card->num_links; i++) { - if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) - continue; - - /* populate platform_of_node for snd card dai links */ - if (dai_link[i].platform_name && - !dai_link[i].platform_of_node) { - index = of_property_match_string(cdev->of_node, - "asoc-platform-names", - dai_link[i].platform_name); - if (index < 0) { - pr_err("%s: No match found for platform name: %s\n", - __func__, dai_link[i].platform_name); - ret = index; - goto cpu_dai; - } - phandle = of_parse_phandle(cdev->of_node, - "asoc-platform", - index); - if (!phandle) { - pr_err("%s: retrieving phandle for platform %s, index %d failed\n", - __func__, dai_link[i].platform_name, - index); - ret = -ENODEV; - goto err; - } - dai_link[i].platform_of_node = phandle; - dai_link[i].platform_name = NULL; - } -cpu_dai: - /* populate cpu_of_node for snd card dai links */ - if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { - index = of_property_match_string(cdev->of_node, - "asoc-cpu-names", - dai_link[i].cpu_dai_name); - if (index < 0) - goto codec_dai; - phandle = of_parse_phandle(cdev->of_node, "asoc-cpu", - index); - if (!phandle) { - pr_err("%s: retrieving phandle for cpu dai %s failed\n", - __func__, dai_link[i].cpu_dai_name); - ret = -ENODEV; - goto err; - } - dai_link[i].cpu_of_node = phandle; - dai_link[i].cpu_dai_name = NULL; - } -codec_dai: - /* populate codec_of_node for snd card dai links */ - if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { - index = of_property_match_string(cdev->of_node, - "asoc-codec-names", - dai_link[i].codec_name); - if (index < 0) - continue; - phandle = of_parse_phandle(cdev->of_node, "asoc-codec", - index); - if (!phandle) { - pr_err("%s: retrieving phandle for codec dai %s failed\n", - __func__, dai_link[i].codec_name); - ret = -ENODEV; - goto err; - } - dai_link[i].codec_of_node = phandle; - dai_link[i].codec_name = NULL; - } - if (pdata->snd_card_val == INT_SND_CARD) { - if ((dai_link[i].id == - MSM_BACKEND_DAI_INT0_MI2S_RX) || - (dai_link[i].id == - MSM_BACKEND_DAI_INT1_MI2S_RX) || - (dai_link[i].id == - MSM_BACKEND_DAI_INT2_MI2S_TX) || - (dai_link[i].id == - MSM_BACKEND_DAI_INT3_MI2S_TX)) { - index = of_property_match_string(cdev->of_node, - "asoc-codec-names", - MSM_INT_DIGITAL_CODEC); - phandle = of_parse_phandle(cdev->of_node, - "asoc-codec", - index); - dai_link[i].codecs[DIG_CDC].of_node = phandle; - index = of_property_match_string(cdev->of_node, - "asoc-codec-names", - PMIC_INT_ANALOG_CODEC); - phandle = of_parse_phandle(cdev->of_node, - "asoc-codec", - index); - dai_link[i].codecs[ANA_CDC].of_node = phandle; - } - } - } -err: - return ret; -} - -static int msm_wsa881x_init(struct snd_soc_component *component) -{ - u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106}; - u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107}; - unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; - unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); - struct msm_asoc_mach_data *pdata; - struct snd_soc_dapm_context *dapm = - snd_soc_codec_get_dapm(codec); - - if (!codec) { - pr_err("%s codec is NULL\n", __func__); - return -EINVAL; - } - - if (!strcmp(component->name_prefix, "SpkrLeft")) { - dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n", - __func__, codec->component.name); - wsa881x_set_channel_map(codec, &spkleft_ports[0], - WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0], NULL); - if (dapm->component) { - snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); - snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); - } - } else if (!strcmp(component->name_prefix, "SpkrRight")) { - dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n", - __func__, codec->component.name); - wsa881x_set_channel_map(codec, &spkright_ports[0], - WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0], NULL); - if (dapm->component) { - snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); - snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); - } - } else { - dev_err(codec->dev, "%s: wrong codec name %s\n", __func__, - codec->component.name); - return -EINVAL; - } - - - pdata = snd_soc_card_get_drvdata(component->card); - if (pdata && pdata->codec_root) - wsa881x_codec_info_create_codec_entry(pdata->codec_root, - codec); - return 0; -} - - -static int msm_init_wsa_dev(struct platform_device *pdev, - struct snd_soc_card *card) -{ - struct device_node *wsa_of_node; - u32 wsa_max_devs; - u32 wsa_dev_cnt; - char *dev_name_str = NULL; - struct msm_wsa881x_dev_info *wsa881x_dev_info; - const char *wsa_auxdev_name_prefix[1]; - int found = 0; - int i; - int ret; - - /* Get maximum WSA device count for this platform */ - ret = of_property_read_u32(pdev->dev.of_node, - "qcom,wsa-max-devs", &wsa_max_devs); - if (ret) { - dev_dbg(&pdev->dev, - "%s: wsa-max-devs property missing in DT %s, ret = %d\n", - __func__, pdev->dev.of_node->full_name, ret); - goto err_dt; - } - if (wsa_max_devs == 0) { - dev_warn(&pdev->dev, - "%s: Max WSA devices is 0 for this target?\n", - __func__); - goto err_dt; - } - - /* Get count of WSA device phandles for this platform */ - wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node, - "qcom,wsa-devs", NULL); - if (wsa_dev_cnt == -ENOENT) { - dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n", - __func__); - goto err_dt; - } else if (wsa_dev_cnt <= 0) { - dev_err(&pdev->dev, - "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n", - __func__, wsa_dev_cnt); - ret = -EINVAL; - goto err_dt; - } - - /* - * Expect total phandles count to be NOT less than maximum possible - * WSA count. However, if it is less, then assign same value to - * max count as well. - */ - if (wsa_dev_cnt < wsa_max_devs) { - dev_dbg(&pdev->dev, - "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n", - __func__, wsa_max_devs, wsa_dev_cnt); - wsa_max_devs = wsa_dev_cnt; - } - - /* Make sure prefix string passed for each WSA device */ - ret = of_property_count_strings(pdev->dev.of_node, - "qcom,wsa-aux-dev-prefix"); - if (ret != wsa_dev_cnt) { - dev_err(&pdev->dev, - "%s: expecting %d wsa prefix. Defined only %d in DT\n", - __func__, wsa_dev_cnt, ret); - ret = -EINVAL; - goto err_dt; - } - - /* - * Alloc mem to store phandle and index info of WSA device, if already - * registered with ALSA core - */ - wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs, - sizeof(struct msm_wsa881x_dev_info), - GFP_KERNEL); - if (!wsa881x_dev_info) { - ret = -ENOMEM; - goto err_mem; - } - - /* - * search and check whether all WSA devices are already - * registered with ALSA core or not. If found a node, store - * the node and the index in a local array of struct for later - * use. - */ - for (i = 0; i < wsa_dev_cnt; i++) { - wsa_of_node = of_parse_phandle(pdev->dev.of_node, - "qcom,wsa-devs", i); - if (unlikely(!wsa_of_node)) { - /* we should not be here */ - dev_err(&pdev->dev, - "%s: wsa dev node is not present\n", - __func__); - ret = -EINVAL; - goto err_dev_node; - } - if (soc_find_component(wsa_of_node, NULL)) { - /* WSA device registered with ALSA core */ - wsa881x_dev_info[found].of_node = wsa_of_node; - wsa881x_dev_info[found].index = i; - found++; - if (found == wsa_max_devs) - break; - } - } - - if (found < wsa_max_devs) { - dev_dbg(&pdev->dev, - "%s: failed to find %d components. Found only %d\n", - __func__, wsa_max_devs, found); - return -EPROBE_DEFER; - } - dev_info(&pdev->dev, - "%s: found %d wsa881x devices registered with ALSA core\n", - __func__, found); - - card->num_aux_devs = wsa_max_devs; - card->num_configs = wsa_max_devs; - - /* Alloc array of AUX devs struct */ - msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, - sizeof(struct snd_soc_aux_dev), - GFP_KERNEL); - if (!msm_aux_dev) { - ret = -ENOMEM; - goto err_auxdev_mem; - } - - /* Alloc array of codec conf struct */ - msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs, - sizeof(struct snd_soc_codec_conf), - GFP_KERNEL); - if (!msm_codec_conf) { - ret = -ENOMEM; - goto err_codec_conf; - } - - for (i = 0; i < card->num_aux_devs; i++) { - dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN, - GFP_KERNEL); - if (!dev_name_str) { - ret = -ENOMEM; - goto err_dev_str; - } - - ret = of_property_read_string_index(pdev->dev.of_node, - "qcom,wsa-aux-dev-prefix", - wsa881x_dev_info[i].index, - wsa_auxdev_name_prefix); - if (ret) { - dev_err(&pdev->dev, - "%s: failed to read wsa aux dev prefix, ret = %d\n", - __func__, ret); - ret = -EINVAL; - goto err_dt_prop; - } - - snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i); - msm_aux_dev[i].name = dev_name_str; - msm_aux_dev[i].codec_name = NULL; - msm_aux_dev[i].codec_of_node = - wsa881x_dev_info[i].of_node; - msm_aux_dev[i].init = msm_wsa881x_init; - msm_codec_conf[i].dev_name = NULL; - msm_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0]; - msm_codec_conf[i].of_node = wsa881x_dev_info[i].of_node; - } - card->codec_conf = msm_codec_conf; - card->aux_dev = msm_aux_dev; - - return 0; - -err_dt_prop: - devm_kfree(&pdev->dev, dev_name_str); -err_dev_str: - devm_kfree(&pdev->dev, msm_codec_conf); -err_codec_conf: - devm_kfree(&pdev->dev, msm_aux_dev); -err_auxdev_mem: -err_dev_node: - devm_kfree(&pdev->dev, wsa881x_dev_info); -err_mem: -err_dt: - return ret; -} - -static void i2s_auxpcm_init(struct platform_device *pdev) -{ - int count; - u32 mi2s_master_slave[MI2S_MAX]; - u32 mi2s_ext_mclk[MI2S_MAX]; - int ret; - - for (count = 0; count < MI2S_MAX; count++) { - mutex_init(&mi2s_intf_conf[count].lock); - mi2s_intf_conf[count].ref_cnt = 0; - } - - ret = of_property_read_u32_array(pdev->dev.of_node, - "qcom,msm-mi2s-master", - mi2s_master_slave, MI2S_MAX); - if (ret) { - dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n", - __func__); - } else { - for (count = 0; count < MI2S_MAX; count++) { - mi2s_intf_conf[count].msm_is_mi2s_master = - mi2s_master_slave[count]; - } - } - - ret = of_property_read_u32_array(pdev->dev.of_node, - "qcom,msm-mi2s-ext-mclk", - mi2s_ext_mclk, MI2S_MAX); - if (ret) { - dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-ext-mclk in DT node\n", - __func__); - } else { - for (count = 0; count < MI2S_MAX; count++) - mi2s_intf_conf[count].msm_is_ext_mclk = - mi2s_ext_mclk[count]; - } -} - -static const struct of_device_id sdm660_asoc_machine_of_match[] = { - { .compatible = "qcom,sdm660-asoc-snd", - .data = "internal_codec"}, - { .compatible = "qcom,sdm660-asoc-snd-tasha", - .data = "tasha_codec"}, - { .compatible = "qcom,sdm660-asoc-snd-tavil", - .data = "tavil_codec"}, - { .compatible = "qcom,sdm670-asoc-snd", - .data = "internal_codec"}, - { .compatible = "qcom,sdm670-asoc-snd-tasha", - .data = "tasha_codec"}, - { .compatible = "qcom,sdm670-asoc-snd-tavil", - .data = "tavil_codec"}, - {}, -}; - -static int msm_asoc_machine_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card = NULL; - struct msm_asoc_mach_data *pdata = NULL; - const char *mclk = "qcom,msm-mclk-freq"; - int ret = -EINVAL, id; - const struct of_device_id *match; - const char *usb_c_dt = "qcom,msm-mbhc-usbc-audio-supported"; - - pdata = devm_kzalloc(&pdev->dev, - sizeof(struct msm_asoc_mach_data), - GFP_KERNEL); - if (!pdata) - return -ENOMEM; - - msm_set_codec_reg_done(false); - match = of_match_node(sdm660_asoc_machine_of_match, - pdev->dev.of_node); - if (!match) - goto err; - - ret = of_property_read_u32(pdev->dev.of_node, mclk, &id); - if (ret) { - dev_err(&pdev->dev, - "%s: missing %s in dt node\n", __func__, mclk); - id = DEFAULT_MCLK_RATE; - } - pdata->mclk_freq = id; - - if (!strcmp(match->data, "tasha_codec") || - !strcmp(match->data, "tavil_codec")) { - if (!strcmp(match->data, "tasha_codec")) - pdata->snd_card_val = EXT_SND_CARD_TASHA; - else - pdata->snd_card_val = EXT_SND_CARD_TAVIL; - ret = msm_ext_cdc_init(pdev, pdata, &card, &mbhc_cfg); - if (ret) - goto err; - } else if (!strcmp(match->data, "internal_codec")) { - pdata->snd_card_val = INT_SND_CARD; - ret = msm_int_cdc_init(pdev, pdata, &card, &mbhc_cfg); - if (ret) - goto err; - } else { - dev_err(&pdev->dev, - "%s: Not a matching DT sound node\n", __func__); - goto err; - } - if (!card) - goto err; - - if (pdata->snd_card_val == INT_SND_CARD) { - /*reading the gpio configurations from dtsi file*/ - pdata->pdm_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,cdc-pdm-gpios", 0); - pdata->comp_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,cdc-comp-gpios", 0); - pdata->dmic_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,cdc-dmic-gpios", 0); - pdata->ext_spk_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,cdc-ext-spk-gpios", 0); - } - - pdata->mi2s_gpio_p[PRIM_MI2S] = of_parse_phandle(pdev->dev.of_node, - "qcom,pri-mi2s-gpios", 0); - pdata->mi2s_gpio_p[SEC_MI2S] = of_parse_phandle(pdev->dev.of_node, - "qcom,sec-mi2s-gpios", 0); - pdata->mi2s_gpio_p[TERT_MI2S] = of_parse_phandle(pdev->dev.of_node, - "qcom,tert-mi2s-gpios", 0); - pdata->mi2s_gpio_p[QUAT_MI2S] = of_parse_phandle(pdev->dev.of_node, - "qcom,quat-mi2s-gpios", 0); - pdata->mi2s_gpio_p[QUIN_MI2S] = of_parse_phandle(pdev->dev.of_node, - "qcom,quin-mi2s-gpios", 0); - /* - * Parse US-Euro gpio info from DT. Report no error if us-euro - * entry is not found in DT file as some targets do not support - * US-Euro detection - */ - pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node, - "qcom,us-euro-gpios", 0); - if (!gpio_is_valid(pdata->us_euro_gpio)) - pdata->us_euro_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,us-euro-gpios", 0); - if (!gpio_is_valid(pdata->us_euro_gpio) && (!pdata->us_euro_gpio_p)) { - dev_dbg(&pdev->dev, "property %s not detected in node %s", - "qcom,us-euro-gpios", pdev->dev.of_node->full_name); - } else { - dev_dbg(&pdev->dev, "%s detected", - "qcom,us-euro-gpios"); - mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; - } - - if (of_find_property(pdev->dev.of_node, usb_c_dt, NULL)) - mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; - - ret = msm_prepare_us_euro(card); - if (ret) - dev_dbg(&pdev->dev, "msm_prepare_us_euro failed (%d)\n", - ret); - - i2s_auxpcm_init(pdev); - - ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing"); - if (ret) - goto err; - - ret = msm_populate_dai_link_component_of_node(pdata, card); - if (ret) { - ret = -EPROBE_DEFER; - goto err; - } - - if (!of_property_read_bool(pdev->dev.of_node, "qcom,wsa-disable")) { - ret = msm_init_wsa_dev(pdev, card); - if (ret) - goto err; - } - - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret == -EPROBE_DEFER) { - if (codec_reg_done) { - /* - * return failure as EINVAL since other codec - * registered sound card successfully. - * This avoids any further probe calls. - */ - ret = -EINVAL; - } - goto err; - } else if (ret) { - dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", - ret); - goto err; - } - if (pdata->snd_card_val != INT_SND_CARD) - msm_ext_register_audio_notifier(pdev); - - return 0; -err: - if (pdata->us_euro_gpio > 0) { - dev_dbg(&pdev->dev, "%s free us_euro gpio %d\n", - __func__, pdata->us_euro_gpio); - pdata->us_euro_gpio = 0; - } - if (pdata->hph_en1_gpio > 0) { - dev_dbg(&pdev->dev, "%s free hph_en1_gpio %d\n", - __func__, pdata->hph_en1_gpio); - gpio_free(pdata->hph_en1_gpio); - pdata->hph_en1_gpio = 0; - } - if (pdata->hph_en0_gpio > 0) { - dev_dbg(&pdev->dev, "%s free hph_en0_gpio %d\n", - __func__, pdata->hph_en0_gpio); - gpio_free(pdata->hph_en0_gpio); - pdata->hph_en0_gpio = 0; - } - devm_kfree(&pdev->dev, pdata); - return ret; -} - -static int msm_asoc_machine_remove(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - - if (pdata->snd_card_val == INT_SND_CARD) - mutex_destroy(&pdata->cdc_int_mclk0_mutex); - - if (gpio_is_valid(pdata->us_euro_gpio)) { - gpio_free(pdata->us_euro_gpio); - pdata->us_euro_gpio = 0; - } - if (gpio_is_valid(pdata->hph_en1_gpio)) { - gpio_free(pdata->hph_en1_gpio); - pdata->hph_en1_gpio = 0; - } - if (gpio_is_valid(pdata->hph_en0_gpio)) { - gpio_free(pdata->hph_en0_gpio); - pdata->hph_en0_gpio = 0; - } - - if (pdata->snd_card_val != INT_SND_CARD) - audio_notifier_deregister("sdm660"); - - snd_soc_unregister_card(card); - return 0; -} - -static struct platform_driver sdm660_asoc_machine_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .pm = &snd_soc_pm_ops, - .of_match_table = sdm660_asoc_machine_of_match, - }, - .probe = msm_asoc_machine_probe, - .remove = msm_asoc_machine_remove, -}; -module_platform_driver(sdm660_asoc_machine_driver); - -MODULE_DESCRIPTION("ALSA SoC msm"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:" DRV_NAME); -MODULE_DEVICE_TABLE(of, sdm660_asoc_machine_of_match); diff --git a/asoc/sdm660-common.h b/asoc/sdm660-common.h deleted file mode 100644 index 6c3eefa260e3..000000000000 --- a/asoc/sdm660-common.h +++ /dev/null @@ -1,133 +0,0 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __MSM_COMMON -#define __MSM_COMMON - -#include -#include -#include "codecs/wcd-mbhc-v2.h" - -#define DEFAULT_MCLK_RATE 9600000 -#define NATIVE_MCLK_RATE 11289600 - -#define SAMPLING_RATE_8KHZ 8000 -#define SAMPLING_RATE_11P025KHZ 11025 -#define SAMPLING_RATE_16KHZ 16000 -#define SAMPLING_RATE_22P05KHZ 22050 -#define SAMPLING_RATE_32KHZ 32000 -#define SAMPLING_RATE_44P1KHZ 44100 -#define SAMPLING_RATE_48KHZ 48000 -#define SAMPLING_RATE_88P2KHZ 88200 -#define SAMPLING_RATE_96KHZ 96000 -#define SAMPLING_RATE_176P4KHZ 176400 -#define SAMPLING_RATE_192KHZ 192000 -#define SAMPLING_RATE_352P8KHZ 352800 -#define SAMPLING_RATE_384KHZ 384000 - -#define TDM_CHANNEL_MAX 8 -#define TDM_SLOT_OFFSET_MAX 8 - -enum { - TDM_0 = 0, - TDM_1, - TDM_2, - TDM_3, - TDM_4, - TDM_5, - TDM_6, - TDM_7, - TDM_PORT_MAX, -}; - -enum { - TDM_PRI = 0, - TDM_SEC, - TDM_TERT, - TDM_QUAT, - TDM_QUIN, - TDM_INTERFACE_MAX, -}; - -struct tdm_port { - u32 mode; - u32 channel; -}; - -enum { - PRIM_MI2S = 0, - SEC_MI2S, - TERT_MI2S, - QUAT_MI2S, - QUIN_MI2S, - MI2S_MAX, -}; - -enum { - DIG_CDC, - ANA_CDC, - CODECS_MAX, -}; - -extern const struct snd_kcontrol_new msm_common_snd_controls[]; -extern bool codec_reg_done; -struct sdm660_codec { - void* (*get_afe_config_fn)(struct snd_soc_codec *codec, - enum afe_config_type config_type); -}; - -enum { - INT_SND_CARD, - EXT_SND_CARD_TASHA, - EXT_SND_CARD_TAVIL, -}; - -struct msm_asoc_mach_data { - int us_euro_gpio; /* used by gpio driver API */ - int usbc_en2_gpio; /* used by gpio driver API */ - int hph_en1_gpio; - int hph_en0_gpio; - struct device_node *us_euro_gpio_p; /* used by pinctrl API */ - struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */ - struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ - struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ - struct device_node *pdm_gpio_p; /* used by pinctrl API */ - struct device_node *comp_gpio_p; /* used by pinctrl API */ - struct device_node *dmic_gpio_p; /* used by pinctrl API */ - struct device_node *ext_spk_gpio_p; /* used by pinctrl API */ - struct device_node *mi2s_gpio_p[MI2S_MAX]; /* used by pinctrl API */ - struct snd_soc_codec *codec; - struct sdm660_codec sdm660_codec_fn; - struct snd_info_entry *codec_root; - int spk_ext_pa_gpio; - int mclk_freq; - bool native_clk_set; - int lb_mode; - int snd_card_val; - u8 micbias1_cap_mode; - u8 micbias2_cap_mode; - atomic_t int_mclk0_rsc_ref; - atomic_t int_mclk0_enabled; - struct mutex cdc_int_mclk0_mutex; - struct delayed_work disable_int_mclk0_work; - struct afe_clk_set digital_cdc_core_clk; -}; - -int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params); -int msm_aux_pcm_snd_startup(struct snd_pcm_substream *substream); -void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream); -int msm_mi2s_snd_startup(struct snd_pcm_substream *substream); -void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream); -int msm_common_snd_controls_size(void); -void msm_set_codec_reg_done(bool done); -#endif diff --git a/asoc/sdm660-ext-dai-links.c b/asoc/sdm660-ext-dai-links.c deleted file mode 100644 index 5f5a60e21ca0..000000000000 --- a/asoc/sdm660-ext-dai-links.c +++ /dev/null @@ -1,2162 +0,0 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include "msm-pcm-routing-v2.h" -#include "sdm660-common.h" -#include "sdm660-external.h" -#include "codecs/core.h" -#include "codecs/wcd9335.h" -#include - -#define DEV_NAME_STR_LEN 32 -#define __CHIPSET__ "SDM660 " -#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) - -#define WCN_CDC_SLIM_RX_CH_MAX 2 -#define WCN_CDC_SLIM_TX_CH_MAX 3 -#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ - -static struct snd_soc_card snd_soc_card_msm_card_tavil = { - .name = "sdm670-tavil-snd-card", - .late_probe = msm_snd_card_tavil_late_probe, -}; - -static struct snd_soc_card snd_soc_card_msm_card_tasha = { - .name = "sdm670-tasha-snd-card", - .late_probe = msm_snd_card_tasha_late_probe, -}; - -static struct snd_soc_ops msm_ext_slimbus_be_ops = { - .hw_params = msm_snd_hw_params, -}; - -static struct snd_soc_ops msm_ext_cpe_ops = { - .hw_params = msm_snd_cpe_hw_params, -}; - -static struct snd_soc_ops msm_ext_slimbus_2_be_ops = { - .hw_params = msm_ext_slimbus_2_hw_params, -}; - -static struct snd_soc_ops msm_mi2s_be_ops = { - .startup = msm_mi2s_snd_startup, - .shutdown = msm_mi2s_snd_shutdown, -}; - -static struct snd_soc_ops msm_aux_pcm_be_ops = { - .startup = msm_aux_pcm_snd_startup, - .shutdown = msm_aux_pcm_snd_shutdown, -}; - -static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) -{ - unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; - unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - - return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), - tx_ch, ARRAY_SIZE(rx_ch), rx_ch); -} - -static int msm_wcn_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai_link *dai_link = rtd->dai_link; - u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; - u32 rx_ch_cnt = 0, tx_ch_cnt = 0; - int ret; - - dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, - codec_dai->name, codec_dai->id); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret) { - dev_err(rtd->dev, - "%s: failed to get BTFM codec chan map\n, err:%d\n", - __func__, ret); - goto exit; - } - - dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) id %d\n", - __func__, tx_ch_cnt, dai_link->id); - - ret = snd_soc_dai_set_channel_map(cpu_dai, - tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); - if (ret) - dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - -exit: - return ret; -} - -static struct snd_soc_ops msm_wcn_ops = { - .hw_params = msm_wcn_hw_params, -}; - -/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */ -static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { - {0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */ -}; - -static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width, - int slots) -{ - unsigned int slot_mask = 0; - int i, j; - unsigned int *slot_offset; - - for (i = TDM_0; i < TDM_PORT_MAX; i++) { - slot_offset = tdm_slot_offset[i]; - - for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) { - if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID) - slot_mask |= - (1 << ((slot_offset[j] * 8) / slot_width)); - else - break; - } - } - - return slot_mask; -} - -static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret = 0; - int channels, slot_width, slots; - unsigned int slot_mask; - unsigned int *slot_offset; - int offset_channels = 0; - int i; - - pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); - - channels = params_channels(params); - switch (channels) { - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S32_LE: - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S16_LE: - /* - * up to 8 channels HW config should - * use 32 bit slot width for max support of - * stream bit width. (slot_width > bit_width) - */ - slot_width = 32; - break; - default: - pr_err("%s: invalid param format 0x%x\n", - __func__, params_format(params)); - return -EINVAL; - } - slots = 8; - slot_mask = tdm_param_set_slot_mask(cpu_dai->id, - slot_width, - slots); - if (!slot_mask) { - pr_err("%s: invalid slot_mask 0x%x\n", - __func__, slot_mask); - return -EINVAL; - } - break; - default: - pr_err("%s: invalid param channels %d\n", - __func__, channels); - return -EINVAL; - } - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - switch (cpu_dai->id) { - case AFE_PORT_ID_PRIMARY_TDM_RX: - case AFE_PORT_ID_SECONDARY_TDM_RX: - case AFE_PORT_ID_TERTIARY_TDM_RX: - case AFE_PORT_ID_QUATERNARY_TDM_RX: - case AFE_PORT_ID_QUINARY_TDM_RX: - case AFE_PORT_ID_PRIMARY_TDM_TX: - case AFE_PORT_ID_SECONDARY_TDM_TX: - case AFE_PORT_ID_TERTIARY_TDM_TX: - case AFE_PORT_ID_QUATERNARY_TDM_TX: - case AFE_PORT_ID_QUINARY_TDM_TX: - slot_offset = tdm_slot_offset[TDM_0]; - break; - default: - pr_err("%s: dai id 0x%x not supported\n", - __func__, cpu_dai->id); - return -EINVAL; - } - - for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { - if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) - offset_channels++; - else - break; - } - - if (offset_channels == 0) { - pr_err("%s: slot offset not supported, offset_channels %d\n", - __func__, offset_channels); - return -EINVAL; - } - - if (channels > offset_channels) { - pr_err("%s: channels %d exceed offset_channels %d\n", - __func__, channels, offset_channels); - return -EINVAL; - } - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, - slots, slot_width); - if (ret < 0) { - pr_err("%s: failed to set tdm slot, err:%d\n", - __func__, ret); - goto end; - } - - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, - channels, slot_offset); - if (ret < 0) { - pr_err("%s: failed to set channel map, err:%d\n", - __func__, ret); - goto end; - } - } else { - ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, - slots, slot_width); - if (ret < 0) { - pr_err("%s: failed to set tdm slot, err:%d\n", - __func__, ret); - goto end; - } - - ret = snd_soc_dai_set_channel_map(cpu_dai, channels, - slot_offset, 0, NULL); - if (ret < 0) { - pr_err("%s: failed to set channel map, err:%d\n", - __func__, ret); - goto end; - } - } -end: - return ret; -} - -static struct snd_soc_ops msm_tdm_be_ops = { - .hw_params = msm_tdm_snd_hw_params -}; - -static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) -{ - cpumask_t mask; - - if (pm_qos_request_active(&substream->latency_pm_qos_req)) - pm_qos_remove_request(&substream->latency_pm_qos_req); - - cpumask_clear(&mask); - cpumask_set_cpu(1, &mask); /* affine to core 1 */ - cpumask_set_cpu(2, &mask); /* affine to core 2 */ - cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); - - substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; - - pm_qos_add_request(&substream->latency_pm_qos_req, - PM_QOS_CPU_DMA_LATENCY, - MSM_LL_QOS_VALUE); - return 0; -} - -static struct snd_soc_ops msm_fe_qos_ops = { - .prepare = msm_fe_qos_prepare, -}; - -static struct snd_soc_dai_link msm_ext_tasha_fe_dai[] = { - /* tasha_vifeedback for speaker protection */ - { - .name = LPASS_BE_SLIMBUS_4_TX, - .stream_name = "Slimbus4 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16393", - .platform_name = "msm-pcm-hostless", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_vifeedback", - .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - }, - /* Ultrasound RX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Playback", - .stream_name = "SLIMBUS_2 Hostless Playback", - .cpu_dai_name = "msm-dai-q6-dev.16388", - .platform_name = "msm-pcm-hostless", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx2", - .ignore_suspend = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .ignore_pmdown_time = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm_ext_slimbus_2_be_ops, - }, - /* Ultrasound TX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Capture", - .stream_name = "SLIMBUS_2 Hostless Capture", - .cpu_dai_name = "msm-dai-q6-dev.16389", - .platform_name = "msm-pcm-hostless", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx2", - .ignore_suspend = 1, - .dpcm_capture = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm_ext_slimbus_2_be_ops, - }, - /* CPE LSM direct dai-link */ - { - .name = "CPE Listen service", - .stream_name = "CPE Listen Audio Service", - .cpu_dai_name = "msm-dai-slim", - .platform_name = "msm-cpe-lsm", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .dpcm_capture = 1, - .codec_dai_name = "tasha_mad1", - .codec_name = "tasha_codec", - .ops = &msm_ext_cpe_ops, - }, - { - .name = "SLIMBUS_6 Hostless Playback", - .stream_name = "SLIMBUS_6 Hostless", - .cpu_dai_name = "SLIMBUS6_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - /* CPE LSM EC PP direct dai-link */ - { - .name = "CPE Listen service ECPP", - .stream_name = "CPE Listen Audio Service ECPP", - .cpu_dai_name = "CPE_LSM_NOHOST", - .platform_name = "msm-cpe-lsm.3", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "tasha_cpe", - .codec_name = "tasha_codec", - }, -}; - -static struct snd_soc_dai_link msm_ext_tavil_fe_dai[] = { - { - .name = LPASS_BE_SLIMBUS_4_TX, - .stream_name = "Slimbus4 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16393", - .platform_name = "msm-pcm-hostless", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_vifeedback", - .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - }, - /* Ultrasound RX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Playback", - .stream_name = "SLIMBUS_2 Hostless Playback", - .cpu_dai_name = "msm-dai-q6-dev.16388", - .platform_name = "msm-pcm-hostless", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx2", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm_ext_slimbus_2_be_ops, - }, - /* Ultrasound TX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Capture", - .stream_name = "SLIMBUS_2 Hostless Capture", - .cpu_dai_name = "msm-dai-q6-dev.16389", - .platform_name = "msm-pcm-hostless", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_tx2", - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm_ext_slimbus_2_be_ops, - }, -}; - -static struct snd_soc_dai_link msm_ext_tasha_be_dai[] = { - /* Backend DAI Links */ - { - .name = LPASS_BE_SLIMBUS_0_RX, - .stream_name = "Slimbus Playback", - .cpu_dai_name = "msm-dai-q6-dev.16384", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mix_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, - .init = &msm_audrx_init, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_ext_slimbus_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_0_TX, - .stream_name = "Slimbus Capture", - .cpu_dai_name = "msm-dai-q6-dev.16385", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_ext_slimbus_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_1_RX, - .stream_name = "Slimbus1 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16386", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mix_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_1_TX, - .stream_name = "Slimbus1 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16387", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx3", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_3_RX, - .stream_name = "Slimbus3 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16390", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mix_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_3_TX, - .stream_name = "Slimbus3 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16391", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_tx1", - .no_pcm = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_4_RX, - .stream_name = "Slimbus4 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16392", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mix_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_5_RX, - .stream_name = "Slimbus5 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16394", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx3", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - /* MAD BE */ - { - .name = LPASS_BE_SLIMBUS_5_TX, - .stream_name = "Slimbus5 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16395", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_mad1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_6_RX, - .stream_name = "Slimbus6 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16396", - .platform_name = "msm-pcm-routing", - .codec_name = "tasha_codec", - .codec_dai_name = "tasha_rx4", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm_ext_tavil_be_dai[] = { - { - .name = LPASS_BE_SLIMBUS_0_RX, - .stream_name = "Slimbus Playback", - .cpu_dai_name = "msm-dai-q6-dev.16384", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, - .init = &msm_audrx_init, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_ext_slimbus_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_0_TX, - .stream_name = "Slimbus Capture", - .cpu_dai_name = "msm-dai-q6-dev.16385", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_tx1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_ext_slimbus_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_1_RX, - .stream_name = "Slimbus1 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16386", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_1_TX, - .stream_name = "Slimbus1 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16387", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_tx3", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_2_RX, - .stream_name = "Slimbus2 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16388", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx2", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_2_RX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_3_RX, - .stream_name = "Slimbus3 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16390", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_3_TX, - .stream_name = "Slimbus3 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16391", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_tx1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_4_RX, - .stream_name = "Slimbus4 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16392", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_5_RX, - .stream_name = "Slimbus5 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16394", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx3", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - /* MAD BE */ - { - .name = LPASS_BE_SLIMBUS_5_TX, - .stream_name = "Slimbus5 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16395", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_mad1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_6_RX, - .stream_name = "Slimbus6 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16396", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx4", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_ext_slimbus_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { - /* FrontEnd DAI Links */ - {/* hw:x,0 */ - .name = MSM_DAILINK_NAME(Media1), - .stream_name = "MultiMedia1", - .cpu_dai_name = "MultiMedia1", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - /* this dai link has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA1 - }, - {/* hw:x,1 */ - .name = MSM_DAILINK_NAME(Media2), - .stream_name = "MultiMedia2", - .cpu_dai_name = "MultiMedia2", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - /* this dai link has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA2, - }, - {/* hw:x,2 */ - .name = "VoiceMMode1", - .stream_name = "VoiceMMode1", - .cpu_dai_name = "VoiceMMode1", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_VOICEMMODE1, - }, - {/* hw:x,3 */ - .name = "MSM VoIP", - .stream_name = "VoIP", - .cpu_dai_name = "VoIP", - .platform_name = "msm-voip-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dai link has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_VOIP, - }, - {/* hw:x,4 */ - .name = MSM_DAILINK_NAME(ULL), - .stream_name = "ULL", - .cpu_dai_name = "MultiMedia3", - .platform_name = "msm-pcm-dsp.2", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dai link has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA3, - }, - /* Hostless PCM purpose */ - {/* hw:x,5 */ - .name = "SLIMBUS_0 Hostless", - .stream_name = "SLIMBUS_0 Hostless", - .cpu_dai_name = "SLIMBUS0_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* This dai link has MI2S support */ - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,6 */ - .name = "MSM AFE-PCM RX", - .stream_name = "AFE-PROXY RX", - .cpu_dai_name = "msm-dai-q6-dev.241", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .platform_name = "msm-pcm-afe", - .ignore_suspend = 1, - /* this dai link has playback support */ - .ignore_pmdown_time = 1, - }, - {/* hw:x,7 */ - .name = "MSM AFE-PCM TX", - .stream_name = "AFE-PROXY TX", - .cpu_dai_name = "msm-dai-q6-dev.240", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .platform_name = "msm-pcm-afe", - .ignore_suspend = 1, - }, - {/* hw:x,8 */ - .name = MSM_DAILINK_NAME(Compress1), - .stream_name = "Compress1", - .cpu_dai_name = "MultiMedia4", - .platform_name = "msm-compress-dsp", - .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA4, - }, - {/* hw:x,9*/ - .name = "AUXPCM Hostless", - .stream_name = "AUXPCM Hostless", - .cpu_dai_name = "AUXPCM_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dai link has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,10 */ - .name = "SLIMBUS_1 Hostless", - .stream_name = "SLIMBUS_1 Hostless", - .cpu_dai_name = "SLIMBUS1_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, /* dai link has playback support */ - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,11 */ - .name = "SLIMBUS_3 Hostless", - .stream_name = "SLIMBUS_3 Hostless", - .cpu_dai_name = "SLIMBUS3_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, /* dai link has playback support */ - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,12 */ - .name = "SLIMBUS_4 Hostless", - .stream_name = "SLIMBUS_4 Hostless", - .cpu_dai_name = "SLIMBUS4_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, /* dai link has playback support */ - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,13 */ - .name = MSM_DAILINK_NAME(LowLatency), - .stream_name = "MultiMedia5", - .cpu_dai_name = "MultiMedia5", - .platform_name = "msm-pcm-dsp.1", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - /* this dai link has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA5, - .ops = &msm_fe_qos_ops, - }, - /* LSM FE */ - {/* hw:x,14 */ - .name = "Listen 1 Audio Service", - .stream_name = "Listen 1 Audio Service", - .cpu_dai_name = "LSM1", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM1, - }, - {/* hw:x,15 */ - .name = MSM_DAILINK_NAME(Compress2), - .stream_name = "Compress2", - .cpu_dai_name = "MultiMedia7", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - /* this dai link has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA7, - }, - {/* hw:x,16 */ - .name = MSM_DAILINK_NAME(MultiMedia10), - .stream_name = "MultiMedia10", - .cpu_dai_name = "MultiMedia10", - .platform_name = "msm-pcm-dsp.1", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA10, - }, - {/* hw:x,17 */ - .name = MSM_DAILINK_NAME(ULL_NOIRQ), - .stream_name = "MM_NOIRQ", - .cpu_dai_name = "MultiMedia8", - .platform_name = "msm-pcm-dsp-noirq", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA8, - .ops = &msm_fe_qos_ops, - }, - {/* hw:x,18 */ - .name = "HDMI_RX_HOSTLESS", - .stream_name = "HDMI_RX_HOSTLESS", - .cpu_dai_name = "HDMI_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,19 */ - .name = "VoiceMMode2", - .stream_name = "VoiceMMode2", - .cpu_dai_name = "VoiceMMode2", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_VOICEMMODE2, - }, - {/* hw:x,20 */ - .name = "Listen 2 Audio Service", - .stream_name = "Listen 2 Audio Service", - .cpu_dai_name = "LSM2", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM2, - }, - {/* hw:x,21 */ - .name = "Listen 3 Audio Service", - .stream_name = "Listen 3 Audio Service", - .cpu_dai_name = "LSM3", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM3, - }, - {/* hw:x,22 */ - .name = "Listen 4 Audio Service", - .stream_name = "Listen 4 Audio Service", - .cpu_dai_name = "LSM4", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM4, - }, - {/* hw:x,23 */ - .name = "Listen 5 Audio Service", - .stream_name = "Listen 5 Audio Service", - .cpu_dai_name = "LSM5", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM5, - }, - {/* hw:x,24 */ - .name = "Listen 6 Audio Service", - .stream_name = "Listen 6 Audio Service", - .cpu_dai_name = "LSM6", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM6 - }, - {/* hw:x,25 */ - .name = "Listen 7 Audio Service", - .stream_name = "Listen 7 Audio Service", - .cpu_dai_name = "LSM7", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM7, - }, - {/* hw:x,26 */ - .name = "Listen 8 Audio Service", - .stream_name = "Listen 8 Audio Service", - .cpu_dai_name = "LSM8", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM8, - }, - {/* hw:x,27 */ - .name = MSM_DAILINK_NAME(Media9), - .stream_name = "MultiMedia9", - .cpu_dai_name = "MultiMedia9", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA9, - }, - {/* hw:x,28 */ - .name = MSM_DAILINK_NAME(Compress4), - .stream_name = "Compress4", - .cpu_dai_name = "MultiMedia11", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA11, - }, - {/* hw:x,29 */ - .name = MSM_DAILINK_NAME(Compress5), - .stream_name = "Compress5", - .cpu_dai_name = "MultiMedia12", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA12, - }, - {/* hw:x,30 */ - .name = MSM_DAILINK_NAME(Compress6), - .stream_name = "Compress6", - .cpu_dai_name = "MultiMedia13", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA13, - }, - {/* hw:x,31 */ - .name = MSM_DAILINK_NAME(Compress7), - .stream_name = "Compress7", - .cpu_dai_name = "MultiMedia14", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA14, - }, - {/* hw:x,32 */ - .name = MSM_DAILINK_NAME(Compress8), - .stream_name = "Compress8", - .cpu_dai_name = "MultiMedia15", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA15, - }, - {/* hw:x,33 */ - .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), - .stream_name = "MM_NOIRQ_2", - .cpu_dai_name = "MultiMedia16", - .platform_name = "msm-pcm-dsp-noirq", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA16, - }, - {/* hw:x,34 */ - .name = "SLIMBUS_8 Hostless", - .stream_name = "SLIMBUS8_HOSTLESS Capture", - .cpu_dai_name = "SLIMBUS8_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,35 */ - .name = "SLIMBUS7 Hostless", - .stream_name = "SLIMBUS7 Hostless", - .cpu_dai_name = "SLIMBUS7_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,36 */ - .name = "SDM660 HFP TX", - .stream_name = "MultiMedia6", - .cpu_dai_name = "MultiMedia6", - .platform_name = "msm-pcm-loopback", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA6, - }, -}; - -static struct snd_soc_dai_link msm_ext_common_be_dai[] = { - { - .name = LPASS_BE_AFE_PCM_RX, - .stream_name = "AFE Playback", - .cpu_dai_name = "msm-dai-q6-dev.224", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_AFE_PCM_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - /* this dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_AFE_PCM_TX, - .stream_name = "AFE Capture", - .cpu_dai_name = "msm-dai-q6-dev.225", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_AFE_PCM_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Record Uplink BACK END DAI Link */ - { - .name = LPASS_BE_INCALL_RECORD_TX, - .stream_name = "Voice Uplink Capture", - .cpu_dai_name = "msm-dai-q6-dev.32772", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Record Downlink BACK END DAI Link */ - { - .name = LPASS_BE_INCALL_RECORD_RX, - .stream_name = "Voice Downlink Capture", - .cpu_dai_name = "msm-dai-q6-dev.32771", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Music BACK END DAI Link */ - { - .name = LPASS_BE_VOICE_PLAYBACK_TX, - .stream_name = "Voice Farend Playback", - .cpu_dai_name = "msm-dai-q6-dev.32773", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - /* Incall Music 2 BACK END DAI Link */ - { - .name = LPASS_BE_VOICE2_PLAYBACK_TX, - .stream_name = "Voice2 Farend Playback", - .cpu_dai_name = "msm-dai-q6-dev.32770", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_USB_AUDIO_RX, - .stream_name = "USB Audio Playback", - .cpu_dai_name = "msm-dai-q6-dev.28672", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_USB_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_USB_AUDIO_TX, - .stream_name = "USB Audio Capture", - .cpu_dai_name = "msm-dai-q6-dev.28673", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_USB_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_PRI_TDM_RX_0, - .stream_name = "Primary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36864", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_PRI_TDM_TX_0, - .stream_name = "Primary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36865", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SEC_TDM_RX_0, - .stream_name = "Secondary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36880", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_SEC_TDM_TX_0, - .stream_name = "Secondary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36881", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_TERT_TDM_RX_0, - .stream_name = "Tertiary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36896", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_TERT_TDM_TX_0, - .stream_name = "Tertiary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36897", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_QUAT_TDM_RX_0, - .stream_name = "Quaternary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36912", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_QUAT_TDM_TX_0, - .stream_name = "Quaternary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36913", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_QUIN_TDM_RX_0, - .stream_name = "Quinary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36928", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUIN_TDM_RX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_QUIN_TDM_TX_0, - .stream_name = "Quinary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36929", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUIN_TDM_TX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { - { - .name = LPASS_BE_PRI_MI2S_RX, - .stream_name = "Primary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.0", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_PRI_MI2S_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_PRI_MI2S_TX, - .stream_name = "Primary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.0", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_PRI_MI2S_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SEC_MI2S_RX, - .stream_name = "Secondary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_SEC_MI2S_TX, - .stream_name = "Secondary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_TERT_MI2S_RX, - .stream_name = "Tertiary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_TERT_MI2S_TX, - .stream_name = "Tertiary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_QUAT_MI2S_RX, - .stream_name = "Quaternary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.3", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_QUAT_MI2S_TX, - .stream_name = "Quaternary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.3", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_QUIN_MI2S_RX, - .stream_name = "Quinary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.4", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUINARY_MI2S_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_QUIN_MI2S_TX, - .stream_name = "Quinary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.4", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUINARY_MI2S_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { - /* Primary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_AUXPCM_RX, - .stream_name = "AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_AUXPCM_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - { - .name = LPASS_BE_AUXPCM_TX, - .stream_name = "AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_AUXPCM_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - /* Secondary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_SEC_AUXPCM_RX, - .stream_name = "Sec AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - { - .name = LPASS_BE_SEC_AUXPCM_TX, - .stream_name = "Sec AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - /* Tertiary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_TERT_AUXPCM_RX, - .stream_name = "Tert AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.3", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - { - .name = LPASS_BE_TERT_AUXPCM_TX, - .stream_name = "Tert AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.3", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - /* Quaternary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_QUAT_AUXPCM_RX, - .stream_name = "Quat AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.4", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - { - .name = LPASS_BE_QUAT_AUXPCM_TX, - .stream_name = "Quat AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.4", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - /* Quinary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_QUIN_AUXPCM_RX, - .stream_name = "Quin AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.5", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - { - .name = LPASS_BE_QUIN_AUXPCM_TX, - .stream_name = "Quin AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.5", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, -}; - -static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { - { - .name = LPASS_BE_SLIMBUS_7_RX, - .stream_name = "Slimbus7 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16398", - .platform_name = "msm-pcm-routing", - .codec_name = "btfmslim_slave", - /* BT codec driver determines capabilities based on - * dai name, bt codecdai name should always contains - * supported usecase information - */ - .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_7_RX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_wcn_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_7_TX, - .stream_name = "Slimbus7 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16399", - .platform_name = "msm-pcm-routing", - .codec_name = "btfmslim_slave", - .codec_dai_name = "btfm_bt_sco_slim_tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_7_TX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .ops = &msm_wcn_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_8_TX, - .stream_name = "Slimbus8 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16401", - .platform_name = "msm-pcm-routing", - .codec_name = "btfmslim_slave", - .codec_dai_name = "btfm_fm_slim_tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_8_TX, - .be_hw_params_fixup = msm_ext_be_hw_params_fixup, - .init = &msm_wcn_init, - .ops = &msm_wcn_ops, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link ext_disp_be_dai_link[] = { - /* DISP PORT BACK END DAI Link */ - { - .name = LPASS_BE_DISPLAY_PORT, - .stream_name = "Display Port Playback", - .cpu_dai_name = "msm-dai-q6-dp.24608", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-ext-disp-audio-codec-rx", - .codec_dai_name = "msm_dp_audio_codec_rx_dai", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm_ext_tasha_dai_links[ -ARRAY_SIZE(msm_ext_common_fe_dai) + -ARRAY_SIZE(msm_ext_tasha_fe_dai) + -ARRAY_SIZE(msm_ext_common_be_dai) + -ARRAY_SIZE(msm_ext_tasha_be_dai) + -ARRAY_SIZE(msm_mi2s_be_dai_links) + -ARRAY_SIZE(msm_auxpcm_be_dai_links) + -ARRAY_SIZE(msm_wcn_be_dai_links) + -ARRAY_SIZE(ext_disp_be_dai_link)]; - -static struct snd_soc_dai_link msm_ext_tavil_dai_links[ -ARRAY_SIZE(msm_ext_common_fe_dai) + -ARRAY_SIZE(msm_ext_tavil_fe_dai) + -ARRAY_SIZE(msm_ext_common_be_dai) + -ARRAY_SIZE(msm_ext_tavil_be_dai) + -ARRAY_SIZE(msm_mi2s_be_dai_links) + -ARRAY_SIZE(msm_auxpcm_be_dai_links) + -ARRAY_SIZE(msm_wcn_be_dai_links) + -ARRAY_SIZE(ext_disp_be_dai_link)]; - -/** - * populate_snd_card_dailinks - prepares dailink array and initializes card. - * - * @dev: device handle - * - * Returns card on success or NULL on failure. - */ -struct snd_soc_card *populate_snd_card_dailinks(struct device *dev, - int snd_card_val) -{ - struct snd_soc_card *card; - struct snd_soc_dai_link *msm_ext_dai_links = NULL; - int ret, len1, len2, len3, len4; - enum codec_variant codec_ver = 0; - - if (snd_card_val == EXT_SND_CARD_TASHA) { - card = &snd_soc_card_msm_card_tasha; - } else if (snd_card_val == EXT_SND_CARD_TAVIL) { - card = &snd_soc_card_msm_card_tavil; - } else { - dev_err(dev, "%s: failing as no matching card name\n", - __func__); - return NULL; - } - - card->dev = dev; - ret = snd_soc_of_parse_card_name(card, "qcom,model"); - if (ret) { - dev_err(dev, "%s: parse card name failed, err:%d\n", - __func__, ret); - return NULL; - } - - if (strnstr(card->name, "tasha", strlen(card->name))) { - codec_ver = tasha_codec_ver(); - if (codec_ver == WCD9326) { - card->name = "sdm670-tashalite-snd-card"; - } else if (codec_ver == WCD9XXX) { - dev_err(dev, "%s: Invalid codec version %d\n", - __func__, codec_ver); - return NULL; - } - - len1 = ARRAY_SIZE(msm_ext_common_fe_dai); - len2 = len1 + ARRAY_SIZE(msm_ext_tasha_fe_dai); - len3 = len2 + ARRAY_SIZE(msm_ext_common_be_dai); - memcpy(msm_ext_tasha_dai_links, msm_ext_common_fe_dai, - sizeof(msm_ext_common_fe_dai)); - memcpy(msm_ext_tasha_dai_links + len1, - msm_ext_tasha_fe_dai, sizeof(msm_ext_tasha_fe_dai)); - memcpy(msm_ext_tasha_dai_links + len2, - msm_ext_common_be_dai, sizeof(msm_ext_common_be_dai)); - memcpy(msm_ext_tasha_dai_links + len3, - msm_ext_tasha_be_dai, sizeof(msm_ext_tasha_be_dai)); - len4 = len3 + ARRAY_SIZE(msm_ext_tasha_be_dai); - if (of_property_read_bool(dev->of_node, - "qcom,mi2s-audio-intf")) { - memcpy(msm_ext_tasha_dai_links + len4, - msm_mi2s_be_dai_links, - sizeof(msm_mi2s_be_dai_links)); - len4 += ARRAY_SIZE(msm_mi2s_be_dai_links); - } - if (of_property_read_bool(dev->of_node, - "qcom,auxpcm-audio-intf")) { - memcpy(msm_ext_tasha_dai_links + len4, - msm_auxpcm_be_dai_links, - sizeof(msm_auxpcm_be_dai_links)); - len4 += ARRAY_SIZE(msm_auxpcm_be_dai_links); - } - if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { - dev_dbg(dev, "%s(): WCN BTFM support present\n", - __func__); - memcpy(msm_ext_tasha_dai_links + len4, - msm_wcn_be_dai_links, - sizeof(msm_wcn_be_dai_links)); - len4 += ARRAY_SIZE(msm_wcn_be_dai_links); - } - if (of_property_read_bool(dev->of_node, - "qcom,ext-disp-audio-rx")) { - dev_dbg(dev, "%s(): ext disp audio support present\n", - __func__); - memcpy(msm_ext_tasha_dai_links + len4, - ext_disp_be_dai_link, - sizeof(ext_disp_be_dai_link)); - len4 += ARRAY_SIZE(ext_disp_be_dai_link); - } - msm_ext_dai_links = msm_ext_tasha_dai_links; - } else if (strnstr(card->name, "tavil", strlen(card->name))) { - len1 = ARRAY_SIZE(msm_ext_common_fe_dai); - len2 = len1 + ARRAY_SIZE(msm_ext_tavil_fe_dai); - len3 = len2 + ARRAY_SIZE(msm_ext_common_be_dai); - memcpy(msm_ext_tavil_dai_links, msm_ext_common_fe_dai, - sizeof(msm_ext_common_fe_dai)); - memcpy(msm_ext_tavil_dai_links + len1, - msm_ext_tavil_fe_dai, sizeof(msm_ext_tavil_fe_dai)); - memcpy(msm_ext_tavil_dai_links + len2, - msm_ext_common_be_dai, sizeof(msm_ext_common_be_dai)); - memcpy(msm_ext_tavil_dai_links + len3, - msm_ext_tavil_be_dai, sizeof(msm_ext_tavil_be_dai)); - len4 = len3 + ARRAY_SIZE(msm_ext_tavil_be_dai); - if (of_property_read_bool(dev->of_node, - "qcom,mi2s-audio-intf")) { - memcpy(msm_ext_tavil_dai_links + len4, - msm_mi2s_be_dai_links, - sizeof(msm_mi2s_be_dai_links)); - len4 += ARRAY_SIZE(msm_mi2s_be_dai_links); - } - if (of_property_read_bool(dev->of_node, - "qcom,auxpcm-audio-intf")) { - memcpy(msm_ext_tavil_dai_links + len4, - msm_auxpcm_be_dai_links, - sizeof(msm_auxpcm_be_dai_links)); - len4 += ARRAY_SIZE(msm_auxpcm_be_dai_links); - } - if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { - dev_dbg(dev, "%s(): WCN BTFM support present\n", - __func__); - memcpy(msm_ext_tavil_dai_links + len4, - msm_wcn_be_dai_links, - sizeof(msm_wcn_be_dai_links)); - len4 += ARRAY_SIZE(msm_wcn_be_dai_links); - } - if (of_property_read_bool(dev->of_node, - "qcom,ext-disp-audio-rx")) { - dev_dbg(dev, "%s(): ext disp audio support present\n", - __func__); - memcpy(msm_ext_tavil_dai_links + len4, - ext_disp_be_dai_link, - sizeof(ext_disp_be_dai_link)); - len4 += ARRAY_SIZE(ext_disp_be_dai_link); - } - msm_ext_dai_links = msm_ext_tavil_dai_links; - } else { - dev_err(dev, "%s: failing as no matching card name\n", - __func__); - return NULL; - } - card->dai_link = msm_ext_dai_links; - card->num_links = len4; - - return card; -} -EXPORT_SYMBOL(populate_snd_card_dailinks); diff --git a/asoc/sdm660-external.c b/asoc/sdm660-external.c deleted file mode 100644 index 8ff98eddef0e..000000000000 --- a/asoc/sdm660-external.c +++ /dev/null @@ -1,1882 +0,0 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "msm-pcm-routing-v2.h" -#include "sdm660-common.h" -#include "sdm660-external.h" -#include "codecs/wcd9335.h" -#include "codecs/wcd934x/wcd934x.h" -#include "codecs/wcd934x/wcd934x-mbhc.h" - -#define SDM660_SPK_ON 1 -#define SDM660_SPK_OFF 0 - -#define WCD9XXX_MBHC_DEF_BUTTONS 8 -#define WCD9XXX_MBHC_DEF_RLOADS 5 -#define CODEC_EXT_CLK_RATE 9600000 -#define ADSP_STATE_READY_TIMEOUT_MS 3000 - -#define WSA8810_NAME_1 "wsa881x.20170211" -#define WSA8810_NAME_2 "wsa881x.20170212" - -static int msm_ext_spk_control = 1; -static struct wcd_mbhc_config *wcd_mbhc_cfg_ptr; - -struct msm_asoc_wcd93xx_codec { - void* (*get_afe_config_fn)(struct snd_soc_codec *codec, - enum afe_config_type config_type); - void (*mbhc_hs_detect_exit)(struct snd_soc_codec *codec); -}; - -static struct msm_asoc_wcd93xx_codec msm_codec_fn; -static struct platform_device *spdev; - -static bool is_initial_boot; - -static void *def_ext_mbhc_cal(void); - -enum { - SLIM_RX_0 = 0, - SLIM_RX_1, - SLIM_RX_2, - SLIM_RX_3, - SLIM_RX_4, - SLIM_RX_5, - SLIM_RX_6, - SLIM_RX_7, - SLIM_RX_MAX, -}; - -enum { - SLIM_TX_0 = 0, - SLIM_TX_1, - SLIM_TX_2, - SLIM_TX_3, - SLIM_TX_4, - SLIM_TX_5, - SLIM_TX_6, - SLIM_TX_7, - SLIM_TX_8, - SLIM_TX_MAX, -}; - -struct dev_config { - u32 sample_rate; - u32 bit_format; - u32 channels; -}; - -/* Default configuration of slimbus channels */ -static struct dev_config slim_rx_cfg[] = { - [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, -}; - -static struct dev_config slim_tx_cfg[] = { - [SLIM_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, -}; - -static int msm_vi_feed_tx_ch = 2; -static const char *const slim_rx_ch_text[] = {"One", "Two"}; -static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", - "Eight"}; -static const char *const vi_feed_ch_text[] = {"One", "Two"}; -static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", - "S32_LE"}; -static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", - "KHZ_32", "KHZ_44P1", "KHZ_48", - "KHZ_88P2", "KHZ_96", "KHZ_176P4", - "KHZ_192", "KHZ_352P8", "KHZ_384"}; -static const char *const spk_function_text[] = {"Off", "On"}; -static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", - "KHZ_44P1", "KHZ_48", - "KHZ_88P2", "KHZ_96"}; - -static SOC_ENUM_SINGLE_EXT_DECL(spk_func_en, spk_function_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_1_tx_chs, slim_tx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_chs, slim_rx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); - -static int slim_get_sample_rate_val(int sample_rate) -{ - int sample_rate_val = 0; - - switch (sample_rate) { - case SAMPLING_RATE_8KHZ: - sample_rate_val = 0; - break; - case SAMPLING_RATE_16KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_32KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 3; - break; - case SAMPLING_RATE_48KHZ: - sample_rate_val = 4; - break; - case SAMPLING_RATE_88P2KHZ: - sample_rate_val = 5; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 6; - break; - case SAMPLING_RATE_176P4KHZ: - sample_rate_val = 7; - break; - case SAMPLING_RATE_192KHZ: - sample_rate_val = 8; - break; - case SAMPLING_RATE_352P8KHZ: - sample_rate_val = 9; - break; - case SAMPLING_RATE_384KHZ: - sample_rate_val = 10; - break; - default: - sample_rate_val = 4; - break; - } - return sample_rate_val; -} - -static int slim_get_sample_rate(int value) -{ - int sample_rate = 0; - - switch (value) { - case 0: - sample_rate = SAMPLING_RATE_8KHZ; - break; - case 1: - sample_rate = SAMPLING_RATE_16KHZ; - break; - case 2: - sample_rate = SAMPLING_RATE_32KHZ; - break; - case 3: - sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 4: - sample_rate = SAMPLING_RATE_48KHZ; - break; - case 5: - sample_rate = SAMPLING_RATE_88P2KHZ; - break; - case 6: - sample_rate = SAMPLING_RATE_96KHZ; - break; - case 7: - sample_rate = SAMPLING_RATE_176P4KHZ; - break; - case 8: - sample_rate = SAMPLING_RATE_192KHZ; - break; - case 9: - sample_rate = SAMPLING_RATE_352P8KHZ; - break; - case 10: - sample_rate = SAMPLING_RATE_384KHZ; - break; - default: - sample_rate = SAMPLING_RATE_48KHZ; - break; - } - return sample_rate; -} - -static int slim_get_bit_format_val(int bit_format) -{ - int val = 0; - - switch (bit_format) { - case SNDRV_PCM_FORMAT_S32_LE: - val = 3; - break; - case SNDRV_PCM_FORMAT_S24_3LE: - val = 2; - break; - case SNDRV_PCM_FORMAT_S24_LE: - val = 1; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - val = 0; - break; - } - return val; -} - -static int slim_get_bit_format(int val) -{ - int bit_fmt = SNDRV_PCM_FORMAT_S16_LE; - - switch (val) { - case 0: - bit_fmt = SNDRV_PCM_FORMAT_S16_LE; - break; - case 1: - bit_fmt = SNDRV_PCM_FORMAT_S24_LE; - break; - case 2: - bit_fmt = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 3: - bit_fmt = SNDRV_PCM_FORMAT_S32_LE; - break; - default: - bit_fmt = SNDRV_PCM_FORMAT_S16_LE; - break; - } - return bit_fmt; -} - -static int slim_get_port_idx(struct snd_kcontrol *kcontrol) -{ - int port_id = 0; - - if (strnstr(kcontrol->id.name, "SLIM_0_RX", sizeof("SLIM_0_RX"))) - port_id = SLIM_RX_0; - else if (strnstr(kcontrol->id.name, "SLIM_2_RX", sizeof("SLIM_2_RX"))) - port_id = SLIM_RX_2; - else if (strnstr(kcontrol->id.name, "SLIM_5_RX", sizeof("SLIM_5_RX"))) - port_id = SLIM_RX_5; - else if (strnstr(kcontrol->id.name, "SLIM_6_RX", sizeof("SLIM_6_RX"))) - port_id = SLIM_RX_6; - else if (strnstr(kcontrol->id.name, "SLIM_0_TX", sizeof("SLIM_0_TX"))) - port_id = SLIM_TX_0; - else if (strnstr(kcontrol->id.name, "SLIM_1_TX", sizeof("SLIM_1_TX"))) - port_id = SLIM_TX_1; - else { - pr_err("%s: unsupported channel: %s", - __func__, kcontrol->id.name); - return -EINVAL; - } - - return port_id; -} - -static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - /* - * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) - * when used for BT_SCO use case. Return either Rx or Tx sample rate - * value. - */ - switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { - case SAMPLING_RATE_96KHZ: - ucontrol->value.integer.value[0] = 5; - break; - case SAMPLING_RATE_88P2KHZ: - ucontrol->value.integer.value[0] = 4; - break; - case SAMPLING_RATE_48KHZ: - ucontrol->value.integer.value[0] = 3; - break; - case SAMPLING_RATE_44P1KHZ: - ucontrol->value.integer.value[0] = 2; - break; - case SAMPLING_RATE_16KHZ: - ucontrol->value.integer.value[0] = 1; - break; - case SAMPLING_RATE_8KHZ: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - pr_debug("%s: sample rate = %d", __func__, - slim_rx_cfg[SLIM_RX_7].sample_rate); - - return 0; -} - -static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 1: - slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; - slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; - break; - case 2: - slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ; - slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 3: - slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; - slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; - break; - case 4: - slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ; - slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ; - break; - case 5: - slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ; - slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ; - break; - case 0: - default: - slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; - slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; - break; - } - pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n", - __func__, - slim_rx_cfg[SLIM_RX_7].sample_rate, - slim_tx_cfg[SLIM_TX_7].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - ucontrol->value.enumerated.item[0] = - slim_get_sample_rate_val(slim_rx_cfg[ch_num].sample_rate); - - pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, - ch_num, slim_rx_cfg[ch_num].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - slim_rx_cfg[ch_num].sample_rate = - slim_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, - ch_num, slim_rx_cfg[ch_num].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - ucontrol->value.enumerated.item[0] = - slim_get_sample_rate_val(slim_tx_cfg[ch_num].sample_rate); - - pr_debug("%s: slim[%d]_tx_sample_rate = %d, item = %d\n", __func__, - ch_num, slim_tx_cfg[ch_num].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate = 0; - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - sample_rate = slim_get_sample_rate(ucontrol->value.enumerated.item[0]); - if (sample_rate == SAMPLING_RATE_44P1KHZ) { - pr_err("%s: Unsupported sample rate %d: for Tx path\n", - __func__, sample_rate); - return -EINVAL; - } - slim_tx_cfg[ch_num].sample_rate = sample_rate; - - pr_debug("%s: slim[%d]_tx_sample_rate = %d, value = %d\n", __func__, - ch_num, slim_tx_cfg[ch_num].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_rx_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - ucontrol->value.enumerated.item[0] = - slim_get_bit_format_val(slim_rx_cfg[ch_num].bit_format); - - pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", - __func__, ch_num, slim_rx_cfg[ch_num].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_rx_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - slim_rx_cfg[ch_num].bit_format = - slim_get_bit_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", - __func__, ch_num, slim_rx_cfg[ch_num].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_tx_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - ucontrol->value.enumerated.item[0] = - slim_get_bit_format_val(slim_tx_cfg[ch_num].bit_format); - - pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", - __func__, ch_num, slim_tx_cfg[ch_num].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_tx_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - slim_tx_cfg[ch_num].bit_format = - slim_get_bit_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", - __func__, ch_num, slim_tx_cfg[ch_num].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_slim_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, - ch_num, slim_rx_cfg[ch_num].channels); - ucontrol->value.enumerated.item[0] = slim_rx_cfg[ch_num].channels - 1; - - return 0; -} - -static int msm_slim_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - slim_rx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; - pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, - ch_num, slim_rx_cfg[ch_num].channels); - - return 1; -} - -static int msm_slim_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, - ch_num, slim_tx_cfg[ch_num].channels); - ucontrol->value.enumerated.item[0] = slim_tx_cfg[ch_num].channels - 1; - - return 0; -} - -static int msm_slim_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - slim_tx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; - pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, - ch_num, slim_tx_cfg[ch_num].channels); - - return 1; -} - -static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1; - pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, - ucontrol->value.integer.value[0]); - return 0; -} - -static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1; - - pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch); - return 1; -} - -static void *def_ext_mbhc_cal(void) -{ - void *wcd_mbhc_cal; - struct wcd_mbhc_btn_detect_cfg *btn_cfg; - u16 *btn_high; - - wcd_mbhc_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, - WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); - if (!wcd_mbhc_cal) - return NULL; - -#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(wcd_mbhc_cal)->X) = (Y)) - S(v_hs_max, 1600); -#undef S -#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal)->X) = (Y)) - S(num_btn, WCD_MBHC_DEF_BUTTONS); -#undef S - - btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal); - btn_high = ((void *)&btn_cfg->_v_btn_low) + - (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); - - btn_high[0] = 75; - btn_high[1] = 150; - btn_high[2] = 237; - btn_high[3] = 500; - btn_high[4] = 500; - btn_high[5] = 500; - btn_high[6] = 500; - btn_high[7] = 500; - - return wcd_mbhc_cal; -} - -static inline int param_is_mask(int p) -{ - return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && - (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); -} - -static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, int n) -{ - return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); -} - - -static void msm_ext_control(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = - snd_soc_codec_get_dapm(codec); - - pr_debug("%s: msm_ext_spk_control = %d", __func__, msm_ext_spk_control); - if (msm_ext_spk_control == SDM660_SPK_ON) { - snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp"); - snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp"); - } else { - snd_soc_dapm_disable_pin(dapm, "Lineout_1 amp"); - snd_soc_dapm_disable_pin(dapm, "Lineout_3 amp"); - } - snd_soc_dapm_sync(dapm); -} - -static int msm_ext_get_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_ext_spk_control = %d\n", - __func__, msm_ext_spk_control); - ucontrol->value.integer.value[0] = msm_ext_spk_control; - return 0; -} - -static int msm_ext_set_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - - pr_debug("%s()\n", __func__); - if (msm_ext_spk_control == ucontrol->value.integer.value[0]) - return 0; - - msm_ext_spk_control = ucontrol->value.integer.value[0]; - msm_ext_control(codec); - return 1; -} - - -int msm_ext_enable_codec_mclk(struct snd_soc_codec *codec, int enable, - bool dapm) -{ - int ret; - - pr_debug("%s: enable = %d\n", __func__, enable); - - if (!strcmp(dev_name(codec->dev), "tasha_codec")) - ret = tasha_cdc_mclk_enable(codec, enable, dapm); - else if (!strcmp(dev_name(codec->dev), "tavil_codec")) - ret = tavil_cdc_mclk_enable(codec, enable); - else { - dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", - __func__); - ret = -EINVAL; - } - return ret; -} - -static const struct snd_kcontrol_new msm_snd_controls[] = { - SOC_ENUM_EXT("Speaker Function", spk_func_en, msm_ext_get_spk, - msm_ext_set_spk), - SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, - msm_slim_rx_ch_get, msm_slim_rx_ch_put), - SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs, - msm_slim_rx_ch_get, msm_slim_rx_ch_put), - SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs, - msm_slim_tx_ch_get, msm_slim_tx_ch_put), - SOC_ENUM_EXT("SLIM_1_TX Channels", slim_1_tx_chs, - msm_slim_tx_ch_get, msm_slim_tx_ch_put), - SOC_ENUM_EXT("SLIM_5_RX Channels", slim_5_rx_chs, - msm_slim_rx_ch_get, msm_slim_rx_ch_put), - SOC_ENUM_EXT("SLIM_6_RX Channels", slim_6_rx_chs, - msm_slim_rx_ch_get, msm_slim_rx_ch_put), - SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, - msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), - SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format, - slim_rx_bit_format_get, slim_rx_bit_format_put), - SOC_ENUM_EXT("SLIM_5_RX Format", slim_5_rx_format, - slim_rx_bit_format_get, slim_rx_bit_format_put), - SOC_ENUM_EXT("SLIM_6_RX Format", slim_6_rx_format, - slim_rx_bit_format_get, slim_rx_bit_format_put), - SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format, - slim_tx_bit_format_get, slim_tx_bit_format_put), - SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate, - slim_rx_sample_rate_get, slim_rx_sample_rate_put), - SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate, - slim_rx_sample_rate_get, slim_rx_sample_rate_put), - SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate, - slim_tx_sample_rate_get, slim_tx_sample_rate_put), - SOC_ENUM_EXT("SLIM_5_RX SampleRate", slim_5_rx_sample_rate, - slim_rx_sample_rate_get, slim_rx_sample_rate_put), - SOC_ENUM_EXT("SLIM_6_RX SampleRate", slim_6_rx_sample_rate, - slim_rx_sample_rate_get, slim_rx_sample_rate_put), - SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, - msm_bt_sample_rate_get, - msm_bt_sample_rate_put), -}; - -static int msm_slim_get_ch_from_beid(int32_t id) -{ - int ch_id = 0; - - switch (id) { - case MSM_BACKEND_DAI_SLIMBUS_0_RX: - ch_id = SLIM_RX_0; - break; - case MSM_BACKEND_DAI_SLIMBUS_1_RX: - ch_id = SLIM_RX_1; - break; - case MSM_BACKEND_DAI_SLIMBUS_2_RX: - ch_id = SLIM_RX_2; - break; - case MSM_BACKEND_DAI_SLIMBUS_3_RX: - ch_id = SLIM_RX_3; - break; - case MSM_BACKEND_DAI_SLIMBUS_4_RX: - ch_id = SLIM_RX_4; - break; - case MSM_BACKEND_DAI_SLIMBUS_6_RX: - ch_id = SLIM_RX_6; - break; - case MSM_BACKEND_DAI_SLIMBUS_0_TX: - ch_id = SLIM_TX_0; - break; - case MSM_BACKEND_DAI_SLIMBUS_3_TX: - ch_id = SLIM_TX_3; - break; - default: - ch_id = SLIM_RX_0; - break; - } - - return ch_id; -} - -static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit) -{ - if (bit >= SNDRV_MASK_MAX) - return; - if (param_is_mask(n)) { - struct snd_mask *m = param_to_mask(p, n); - - m->bits[0] = 0; - m->bits[1] = 0; - m->bits[bit >> 5] |= (1 << (bit & 31)); - } -} - -/** - * msm_ext_be_hw_params_fixup - updates settings of ALSA BE hw params. - * - * @rtd: runtime dailink instance - * @params: HW params of associated backend dailink. - * - * Returns 0 on success or rc on failure. - */ -int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_dai_link *dai_link = rtd->dai_link; - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - int rc = 0; - int idx; - void *config = NULL; - struct snd_soc_codec *codec = rtd->codec; - - pr_debug("%s: format = %d, rate = %d\n", - __func__, params_format(params), params_rate(params)); - - switch (dai_link->id) { - case MSM_BACKEND_DAI_SLIMBUS_0_RX: - case MSM_BACKEND_DAI_SLIMBUS_1_RX: - case MSM_BACKEND_DAI_SLIMBUS_2_RX: - case MSM_BACKEND_DAI_SLIMBUS_3_RX: - case MSM_BACKEND_DAI_SLIMBUS_4_RX: - case MSM_BACKEND_DAI_SLIMBUS_6_RX: - idx = msm_slim_get_ch_from_beid(dai_link->id); - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_rx_cfg[idx].bit_format); - rate->min = rate->max = slim_rx_cfg[idx].sample_rate; - channels->min = channels->max = slim_rx_cfg[idx].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_0_TX: - case MSM_BACKEND_DAI_SLIMBUS_3_TX: - idx = msm_slim_get_ch_from_beid(dai_link->id); - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_tx_cfg[idx].bit_format); - rate->min = rate->max = slim_tx_cfg[idx].sample_rate; - channels->min = channels->max = slim_tx_cfg[idx].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_1_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_tx_cfg[1].bit_format); - rate->min = rate->max = slim_tx_cfg[1].sample_rate; - channels->min = channels->max = slim_tx_cfg[1].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_4_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - SNDRV_PCM_FORMAT_S32_LE); - rate->min = rate->max = SAMPLING_RATE_8KHZ; - channels->min = channels->max = msm_vi_feed_tx_ch; - break; - - case MSM_BACKEND_DAI_SLIMBUS_5_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_rx_cfg[5].bit_format); - rate->min = rate->max = slim_rx_cfg[5].sample_rate; - channels->min = channels->max = slim_rx_cfg[5].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_5_TX: - rate->min = rate->max = SAMPLING_RATE_16KHZ; - channels->min = channels->max = 1; - - config = msm_codec_fn.get_afe_config_fn(codec, - AFE_SLIMBUS_SLAVE_PORT_CONFIG); - if (config) { - rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, - config, SLIMBUS_5_TX); - if (rc) - pr_err("%s: Failed to set slimbus slave port config %d\n", - __func__, rc); - } - break; - - case MSM_BACKEND_DAI_SLIMBUS_7_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_rx_cfg[SLIM_RX_7].bit_format); - rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate; - channels->min = channels->max = - slim_rx_cfg[SLIM_RX_7].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_7_TX: - rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate; - channels->min = channels->max = - slim_tx_cfg[SLIM_TX_7].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_8_TX: - rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate; - channels->min = channels->max = - slim_tx_cfg[SLIM_TX_8].channels; - break; - - default: - rate->min = rate->max = SAMPLING_RATE_48KHZ; - break; - } - return rc; -} -EXPORT_SYMBOL(msm_ext_be_hw_params_fixup); - -/** - * msm_snd_hw_params - hw params ops of backend dailink. - * - * @substream: PCM stream of associated backend dailink. - * @params: HW params of associated backend dailink. - * - * Returns 0 on success or ret on failure. - */ -int msm_snd_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai_link *dai_link = rtd->dai_link; - - int ret = 0; - u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; - u32 rx_ch_cnt = 0, tx_ch_cnt = 0; - u32 user_set_tx_ch = 0; - u32 rx_ch_count; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map, err:%d\n", - __func__, ret); - goto err_ch_map; - } - if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_5_RX) { - pr_debug("%s: rx_5_ch=%d\n", __func__, - slim_rx_cfg[5].channels); - rx_ch_count = slim_rx_cfg[5].channels; - } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_2_RX) { - pr_debug("%s: rx_2_ch=%d\n", __func__, - slim_rx_cfg[2].channels); - rx_ch_count = slim_rx_cfg[2].channels; - } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_6_RX) { - pr_debug("%s: rx_6_ch=%d\n", __func__, - slim_rx_cfg[6].channels); - rx_ch_count = slim_rx_cfg[6].channels; - } else { - pr_debug("%s: rx_0_ch=%d\n", __func__, - slim_rx_cfg[0].channels); - rx_ch_count = slim_rx_cfg[0].channels; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, - rx_ch_count, rx_ch); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto err_ch_map; - } - } else { - pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__, - codec_dai->name, codec_dai->id, user_set_tx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map\n, err:%d\n", - __func__, ret); - goto err_ch_map; - } - /* For _tx1 case */ - if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_0_TX) - user_set_tx_ch = slim_tx_cfg[0].channels; - /* For _tx3 case */ - else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_1_TX) - user_set_tx_ch = slim_tx_cfg[1].channels; - else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_4_TX) - user_set_tx_ch = msm_vi_feed_tx_ch; - else - user_set_tx_ch = tx_ch_cnt; - - pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), id (%d)\n", - __func__, slim_tx_cfg[0].channels, user_set_tx_ch, - tx_ch_cnt, dai_link->id); - - ret = snd_soc_dai_set_channel_map(cpu_dai, - user_set_tx_ch, tx_ch, 0, 0); - if (ret < 0) - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - } - -err_ch_map: - return ret; -} -EXPORT_SYMBOL(msm_snd_hw_params); - -/** - * msm_ext_slimbus_2_hw_params - hw params ops of slimbus_2 BE. - * - * @substream: PCM stream of associated backend dailink. - * @params: HW params of associated backend dailink. - * - * Returns 0 on success or ret on failure. - */ -int msm_ext_slimbus_2_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret = 0; - unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; - unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0; - unsigned int num_tx_ch = 0; - unsigned int num_rx_ch = 0; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - num_rx_ch = params_channels(params); - pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__, - codec_dai->name, codec_dai->id, num_rx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map, err:%d\n", - __func__, ret); - goto end; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, - num_rx_ch, rx_ch); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto end; - } - } else { - num_tx_ch = params_channels(params); - pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__, - codec_dai->name, codec_dai->id, num_tx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map, err:%d\n", - __func__, ret); - goto end; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, - num_tx_ch, tx_ch, 0, 0); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto end; - } - } -end: - return ret; -} -EXPORT_SYMBOL(msm_ext_slimbus_2_hw_params); - -/** - * msm_snd_cpe_hw_params - hw params ops of CPE backend. - * - * @substream: PCM stream of associated backend dailink. - * @params: HW params of associated backend dailink. - * - * Returns 0 on success or ret on failure. - */ -int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai_link *dai_link = rtd->dai_link; - int ret = 0; - u32 tx_ch[SLIM_MAX_TX_PORTS]; - u32 tx_ch_cnt = 0; - - if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) { - pr_err("%s: Invalid stream type %d\n", - __func__, substream->stream); - ret = -EINVAL; - goto end; - } - - pr_debug("%s: %s_tx_dai_id_%d\n", __func__, - codec_dai->name, codec_dai->id); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, NULL, NULL); - if (ret < 0) { - pr_err("%s: failed to get codec chan map\n, err:%d\n", - __func__, ret); - goto end; - } - - pr_debug("%s: tx_ch_cnt(%d) id %d\n", - __func__, tx_ch_cnt, dai_link->id); - - ret = snd_soc_dai_set_channel_map(cpu_dai, - tx_ch_cnt, tx_ch, 0, 0); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto end; - } -end: - return ret; -} -EXPORT_SYMBOL(msm_snd_cpe_hw_params); - -static int msm_afe_set_config(struct snd_soc_codec *codec) -{ - int rc; - void *config_data; - - pr_debug("%s: enter\n", __func__); - - if (!msm_codec_fn.get_afe_config_fn) { - dev_err(codec->dev, "%s: codec get afe config not init'ed\n", - __func__); - return -EINVAL; - } - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_CDC_REGISTERS_CONFIG); - if (config_data) { - rc = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0); - if (rc) { - pr_err("%s: Failed to set codec registers config %d\n", - __func__, rc); - return rc; - } - } - - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_CDC_REGISTER_PAGE_CONFIG); - if (config_data) { - rc = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, - 0); - if (rc) - pr_err("%s: Failed to set cdc register page config\n", - __func__); - } - - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_SLIMBUS_SLAVE_CONFIG); - if (config_data) { - rc = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0); - if (rc) { - pr_err("%s: Failed to set slimbus slave config %d\n", - __func__, rc); - return rc; - } - } - - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_AANC_VERSION); - if (config_data) { - rc = afe_set_config(AFE_AANC_VERSION, config_data, 0); - if (rc) { - pr_err("%s: Failed to set AANC version %d\n", - __func__, rc); - return rc; - } - } - - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_CDC_CLIP_REGISTERS_CONFIG); - if (config_data) { - rc = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG, - config_data, 0); - if (rc) { - pr_err("%s: Failed to set clip registers %d\n", - __func__, rc); - return rc; - } - } - - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_CLIP_BANK_SEL); - if (config_data) { - rc = afe_set_config(AFE_CLIP_BANK_SEL, - config_data, 0); - if (rc) { - pr_err("%s: Failed to set AFE bank selection %d\n", - __func__, rc); - return rc; - } - } - - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_CDC_REGISTER_PAGE_CONFIG); - if (config_data) { - rc = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, - 0); - if (rc) - pr_err("%s: Failed to set cdc register page config\n", - __func__); - } - - return 0; -} - -static void msm_afe_clear_config(void) -{ - afe_clear_config(AFE_CDC_REGISTERS_CONFIG); - afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); -} - -static int msm_adsp_power_up_config(struct snd_soc_codec *codec, - struct snd_card *card) -{ - int ret = 0; - unsigned long timeout; - int adsp_ready = 0; - bool snd_card_online = 0; - - timeout = jiffies + - msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); - - do { - if (!snd_card_online) { - snd_card_online = snd_card_is_online_state(card); - pr_debug("%s: Sound card is %s\n", __func__, - snd_card_online ? "Online" : "Offline"); - } - if (!adsp_ready) { - adsp_ready = q6core_is_adsp_ready(); - pr_debug("%s: ADSP Audio is %s\n", __func__, - adsp_ready ? "ready" : "not ready"); - } - if (snd_card_online && adsp_ready) - break; - - /* - * Sound card/ADSP will be coming up after subsystem restart and - * it might not be fully up when the control reaches - * here. So, wait for 50msec before checking ADSP state - */ - msleep(50); - } while (time_after(timeout, jiffies)); - - if (!snd_card_online || !adsp_ready) { - pr_err("%s: Timeout. Sound card is %s, ADSP Audio is %s\n", - __func__, - snd_card_online ? "Online" : "Offline", - adsp_ready ? "ready" : "not ready"); - ret = -ETIMEDOUT; - goto err_fail; - } - - ret = msm_afe_set_config(codec); - if (ret) - pr_err("%s: Failed to set AFE config. err %d\n", - __func__, ret); - - return 0; - -err_fail: - return ret; -} - -static int sdm660_notifier_service_cb(struct notifier_block *this, - unsigned long opcode, void *ptr) -{ - int ret; - struct snd_soc_card *card = NULL; - const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; - struct snd_soc_pcm_runtime *rtd; - struct snd_soc_codec *codec; - - pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); - - switch (opcode) { - case AUDIO_NOTIFIER_SERVICE_DOWN: - /* - * Use flag to ignore initial boot notifications - * On initial boot msm_adsp_power_up_config is - * called on init. There is no need to clear - * and set the config again on initial boot. - */ - if (is_initial_boot) - break; - msm_afe_clear_config(); - break; - case AUDIO_NOTIFIER_SERVICE_UP: - if (is_initial_boot) { - is_initial_boot = false; - break; - } - if (!spdev) - return -EINVAL; - - card = platform_get_drvdata(spdev); - rtd = snd_soc_get_pcm_runtime(card, be_dl_name); - if (!rtd) { - dev_err(card->dev, - "%s: snd_soc_get_pcm_runtime for %s failed!\n", - __func__, be_dl_name); - ret = -EINVAL; - goto done; - } - codec = rtd->codec; - - ret = msm_adsp_power_up_config(codec, card->snd_card); - if (ret < 0) { - dev_err(card->dev, - "%s: msm_adsp_power_up_config failed ret = %d!\n", - __func__, ret); - goto done; - } - break; - default: - break; - } -done: - return NOTIFY_OK; -} - -static struct notifier_block service_nb = { - .notifier_call = sdm660_notifier_service_cb, - .priority = -INT_MAX, -}; - -static int msm_config_hph_en0_gpio(struct snd_soc_codec *codec, bool high) -{ - struct snd_soc_card *card = codec->component.card; - struct msm_asoc_mach_data *pdata; - int val; - - if (!card) - return 0; - - pdata = snd_soc_card_get_drvdata(card); - if (!pdata || !gpio_is_valid(pdata->hph_en0_gpio)) - return 0; - - val = gpio_get_value_cansleep(pdata->hph_en0_gpio); - if ((!!val) == high) - return 0; - - gpio_direction_output(pdata->hph_en0_gpio, (int)high); - - return 1; -} - -static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, - int enable, bool dapm) -{ - int ret = 0; - - if (!strcmp(dev_name(codec->dev), "tasha_codec")) - ret = tasha_cdc_mclk_tx_enable(codec, enable, dapm); - else { - dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", - __func__); - ret = -EINVAL; - } - return ret; -} - -static int msm_ext_mclk_tx_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - pr_debug("%s: event = %d\n", __func__, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - return msm_snd_enable_codec_ext_tx_clk(codec, 1, true); - case SND_SOC_DAPM_POST_PMD: - return msm_snd_enable_codec_ext_tx_clk(codec, 0, true); - } - return 0; -} - -static int msm_ext_mclk_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - pr_debug("%s: event = %d\n", __func__, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - return msm_ext_enable_codec_mclk(codec, 1, true); - case SND_SOC_DAPM_POST_PMD: - return msm_ext_enable_codec_mclk(codec, 0, true); - } - return 0; -} - -static int msm_ext_prepare_hifi(struct msm_asoc_mach_data *pdata) -{ - int ret = 0; - - if (gpio_is_valid(pdata->hph_en1_gpio)) { - pr_debug("%s: hph_en1_gpio request %d\n", __func__, - pdata->hph_en1_gpio); - ret = gpio_request(pdata->hph_en1_gpio, "hph_en1_gpio"); - if (ret) { - pr_err("%s: hph_en1_gpio request failed, ret:%d\n", - __func__, ret); - goto err; - } - } - if (gpio_is_valid(pdata->hph_en0_gpio)) { - pr_debug("%s: hph_en0_gpio request %d\n", __func__, - pdata->hph_en0_gpio); - ret = gpio_request(pdata->hph_en0_gpio, "hph_en0_gpio"); - if (ret) - pr_err("%s: hph_en0_gpio request failed, ret:%d\n", - __func__, ret); - } - -err: - return ret; -} - -static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { - - SND_SOC_DAPM_SUPPLY_S("MCLK", -1, SND_SOC_NOPM, 0, 0, - msm_ext_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SUPPLY_S("MCLK TX", -1, SND_SOC_NOPM, 0, 0, - msm_ext_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SPK("Lineout_1 amp", NULL), - SND_SOC_DAPM_SPK("Lineout_3 amp", NULL), - SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), - SND_SOC_DAPM_SPK("Lineout_4 amp", NULL), - SND_SOC_DAPM_MIC("Handset Mic", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("Secondary Mic", NULL), - SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), - SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL), - SND_SOC_DAPM_MIC("Analog Mic4", NULL), - SND_SOC_DAPM_MIC("Analog Mic6", NULL), - SND_SOC_DAPM_MIC("Analog Mic7", NULL), - SND_SOC_DAPM_MIC("Analog Mic8", NULL), - - SND_SOC_DAPM_MIC("Digital Mic0", NULL), - SND_SOC_DAPM_MIC("Digital Mic1", NULL), - SND_SOC_DAPM_MIC("Digital Mic2", NULL), - SND_SOC_DAPM_MIC("Digital Mic3", NULL), - SND_SOC_DAPM_MIC("Digital Mic4", NULL), - SND_SOC_DAPM_MIC("Digital Mic5", NULL), - SND_SOC_DAPM_MIC("Digital Mic6", NULL), -}; - -static struct snd_soc_dapm_route wcd_audio_paths_tasha[] = { - {"MIC BIAS1", NULL, "MCLK TX"}, - {"MIC BIAS2", NULL, "MCLK TX"}, - {"MIC BIAS3", NULL, "MCLK TX"}, - {"MIC BIAS4", NULL, "MCLK TX"}, -}; - -static struct snd_soc_dapm_route wcd_audio_paths[] = { - {"MIC BIAS1", NULL, "MCLK"}, - {"MIC BIAS2", NULL, "MCLK"}, - {"MIC BIAS3", NULL, "MCLK"}, - {"MIC BIAS4", NULL, "MCLK"}, -}; - -int msm_snd_card_tasha_late_probe(struct snd_soc_card *card) -{ - const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; - struct snd_soc_pcm_runtime *rtd; - int ret = 0; - void *mbhc_calibration; - - rtd = snd_soc_get_pcm_runtime(card, be_dl_name); - if (!rtd) { - dev_err(card->dev, - "%s: snd_soc_get_pcm_runtime for %s failed!\n", - __func__, be_dl_name); - ret = -EINVAL; - goto err_pcm_runtime; - } - - mbhc_calibration = def_ext_mbhc_cal(); - if (!mbhc_calibration) { - ret = -ENOMEM; - goto err_mbhc_cal; - } - wcd_mbhc_cfg_ptr->calibration = mbhc_calibration; - ret = tasha_mbhc_hs_detect(rtd->codec, wcd_mbhc_cfg_ptr); - if (ret) { - dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", - __func__, ret); - goto err_hs_detect; - } - return 0; - -err_hs_detect: - kfree(mbhc_calibration); -err_mbhc_cal: -err_pcm_runtime: - return ret; -} - -int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) -{ - const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; - struct snd_soc_pcm_runtime *rtd; - int ret = 0; - void *mbhc_calibration; - - rtd = snd_soc_get_pcm_runtime(card, be_dl_name); - if (!rtd) { - dev_err(card->dev, - "%s: snd_soc_get_pcm_runtime for %s failed!\n", - __func__, be_dl_name); - ret = -EINVAL; - goto err; - } - - mbhc_calibration = def_ext_mbhc_cal(); - if (!mbhc_calibration) { - ret = -ENOMEM; - goto err; - } - wcd_mbhc_cfg_ptr->calibration = mbhc_calibration; - ret = tavil_mbhc_hs_detect(rtd->codec, wcd_mbhc_cfg_ptr); - if (ret) { - dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", - __func__, ret); - goto err_free_mbhc_cal; - } - return 0; - -err_free_mbhc_cal: - kfree(mbhc_calibration); -err: - return ret; -} - -/** - * msm_audrx_init - Audio init function of sound card instantiate. - * - * @rtd: runtime dailink instance - * - * Returns 0 on success or ret on failure. - */ -int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret; - void *config_data; - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = - snd_soc_codec_get_dapm(codec); - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_component *aux_comp; - struct snd_card *card; - struct snd_info_entry *entry; - struct msm_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(rtd->card); - - /* Codec SLIMBUS configuration - * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13 - * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 - * TX14, TX15, TX16 - */ - unsigned int rx_ch[TASHA_RX_MAX] = {144, 145, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156}; - unsigned int tx_ch[TASHA_TX_MAX] = {128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143}; - - /* Tavil Codec SLIMBUS configuration - * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8 - * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 - * TX14, TX15, TX16 - */ - unsigned int rx_ch_tavil[WCD934X_RX_MAX] = {144, 145, 146, 147, 148, - 149, 150, 151}; - unsigned int tx_ch_tavil[WCD934X_TX_MAX] = {128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143}; - - pr_debug("%s: dev_name%s\n", __func__, dev_name(cpu_dai->dev)); - - rtd->pmdown_time = 0; - - ret = snd_soc_add_codec_controls(codec, msm_snd_controls, - ARRAY_SIZE(msm_snd_controls)); - if (ret < 0) { - pr_err("%s: add_codec_controls failed: %d\n", - __func__, ret); - return ret; - } - - ret = snd_soc_add_codec_controls(codec, msm_common_snd_controls, - msm_common_snd_controls_size()); - if (ret < 0) { - pr_err("%s: add_common_snd_controls failed: %d\n", - __func__, ret); - return ret; - } - - snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, - ARRAY_SIZE(msm_dapm_widgets)); - - if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) - snd_soc_dapm_add_routes(dapm, wcd_audio_paths_tasha, - ARRAY_SIZE(wcd_audio_paths_tasha)); - else - snd_soc_dapm_add_routes(dapm, wcd_audio_paths, - ARRAY_SIZE(wcd_audio_paths)); - - snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp"); - snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp"); - snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp"); - snd_soc_dapm_enable_pin(dapm, "Lineout_4 amp"); - - snd_soc_dapm_ignore_suspend(dapm, "MADINPUT"); - snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT"); - snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Secondary Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Lineout_1 amp"); - snd_soc_dapm_ignore_suspend(dapm, "Lineout_3 amp"); - snd_soc_dapm_ignore_suspend(dapm, "Lineout_2 amp"); - snd_soc_dapm_ignore_suspend(dapm, "Lineout_4 amp"); - snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic7"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic8"); - - snd_soc_dapm_ignore_suspend(dapm, "EAR"); - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1"); - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC4"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC5"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC0"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC1"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC2"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC3"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC4"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC5"); - snd_soc_dapm_ignore_suspend(dapm, "ANC EAR"); - snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); - snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); - snd_soc_dapm_ignore_suspend(dapm, "HPHL"); - snd_soc_dapm_ignore_suspend(dapm, "HPHR"); - snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); - snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); - - if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) { - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3"); - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4"); - snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL"); - snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR"); - snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT1"); - snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT2"); - } else { - snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT1"); - snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT2"); - } - - snd_soc_dapm_sync(dapm); - - if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { - snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch_tavil), - tx_ch_tavil, ARRAY_SIZE(rx_ch_tavil), - rx_ch_tavil); - } else { - snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), - tx_ch, ARRAY_SIZE(rx_ch), - rx_ch); - } - - if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { - msm_codec_fn.get_afe_config_fn = tavil_get_afe_config; - } else { - msm_codec_fn.get_afe_config_fn = tasha_get_afe_config; - msm_codec_fn.mbhc_hs_detect_exit = tasha_mbhc_hs_detect_exit; - } - - ret = msm_adsp_power_up_config(codec, rtd->card->snd_card); - if (ret) { - pr_err("%s: Failed to set AFE config %d\n", __func__, ret); - goto err_afe_cfg; - } - - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_AANC_VERSION); - if (config_data) { - ret = afe_set_config(AFE_AANC_VERSION, config_data, 0); - if (ret) { - pr_err("%s: Failed to set aanc version %d\n", - __func__, ret); - goto err_afe_cfg; - } - } - - if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) { - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_CDC_CLIP_REGISTERS_CONFIG); - if (config_data) { - ret = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG, - config_data, 0); - if (ret) { - pr_err("%s: Failed to set clip registers %d\n", - __func__, ret); - goto err_afe_cfg; - } - } - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_CLIP_BANK_SEL); - if (config_data) { - ret = afe_set_config(AFE_CLIP_BANK_SEL, config_data, 0); - if (ret) { - pr_err("%s: Failed to set AFE bank selection %d\n", - __func__, ret); - goto err_afe_cfg; - } - } - } - - /* - * Send speaker configuration only for WSA8810. - * Defalut configuration is for WSA8815. - */ - pr_debug("%s: Number of aux devices: %d\n", - __func__, rtd->card->num_aux_devs); - - if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { - if (rtd->card->num_aux_devs && - !list_empty(&rtd->card->aux_comp_list)) { - aux_comp = list_first_entry(&rtd->card->aux_comp_list, - struct snd_soc_component, list_aux); - if (!strcmp(aux_comp->name, WSA8810_NAME_1) || - !strcmp(aux_comp->name, WSA8810_NAME_2)) { - tavil_set_spkr_mode(rtd->codec, SPKR_MODE_1); - tavil_set_spkr_gain_offset(rtd->codec, - RX_GAIN_OFFSET_M1P5_DB); - } - } - card = rtd->card->snd_card; - entry = snd_info_create_subdir(card->module, "codecs", - card->proc_root); - if (!entry) { - pr_debug("%s: Cannot create codecs module entry\n", - __func__); - goto done; - } - pdata->codec_root = entry; - tavil_codec_info_create_codec_entry(pdata->codec_root, codec); - } else { - if (rtd->card->num_aux_devs && - !list_empty(&rtd->card->aux_comp_list)) { - aux_comp = list_first_entry(&rtd->card->aux_comp_list, - struct snd_soc_component, list_aux); - if (!strcmp(aux_comp->name, WSA8810_NAME_1) || - !strcmp(aux_comp->name, WSA8810_NAME_2)) { - tasha_set_spkr_mode(rtd->codec, SPKR_MODE_1); - tasha_set_spkr_gain_offset(rtd->codec, - RX_GAIN_OFFSET_M1P5_DB); - } - } - card = rtd->card->snd_card; - entry = snd_info_create_subdir(card->module, "codecs", - card->proc_root); - if (!entry) { - pr_debug("%s: Cannot create codecs module entry\n", - __func__); - goto done; - } - pdata->codec_root = entry; - tasha_codec_info_create_codec_entry(pdata->codec_root, codec); - tasha_mbhc_zdet_gpio_ctrl(msm_config_hph_en0_gpio, rtd->codec); - } -done: - msm_set_codec_reg_done(true); - return 0; - -err_afe_cfg: - return ret; -} -EXPORT_SYMBOL(msm_audrx_init); - -/** - * msm_ext_register_audio_notifier - register SSR notifier. - */ -void msm_ext_register_audio_notifier(struct platform_device *pdev) -{ - int ret; - - is_initial_boot = true; - spdev = pdev; - ret = audio_notifier_register("sdm660", AUDIO_NOTIFIER_ADSP_DOMAIN, - &service_nb); - if (ret < 0) - pr_err("%s: Audio notifier register failed ret = %d\n", - __func__, ret); -} -EXPORT_SYMBOL(msm_ext_register_audio_notifier); - -/** - * msm_ext_cdc_init - external codec machine specific init. - * - * @pdev: platform device handle - * @pdata: private data of machine driver - * @card: sound card pointer reference - * @mbhc_cfg: MBHC config reference - * - * Returns 0 on success or ret on failure. - */ -int msm_ext_cdc_init(struct platform_device *pdev, - struct msm_asoc_mach_data *pdata, - struct snd_soc_card **card, - struct wcd_mbhc_config *wcd_mbhc_cfg_ptr1) -{ - int ret = 0; - - wcd_mbhc_cfg_ptr = wcd_mbhc_cfg_ptr1; - pdev->id = 0; - wcd_mbhc_cfg_ptr->moisture_en = true; - wcd_mbhc_cfg_ptr->mbhc_micbias = MIC_BIAS_2; - wcd_mbhc_cfg_ptr->anc_micbias = MIC_BIAS_2; - wcd_mbhc_cfg_ptr->enable_anc_mic_detect = false; - - *card = populate_snd_card_dailinks(&pdev->dev, pdata->snd_card_val); - if (!(*card)) { - dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); - ret = -EPROBE_DEFER; - goto err; - } - platform_set_drvdata(pdev, *card); - snd_soc_card_set_drvdata(*card, pdata); - pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node, - "qcom,hph-en1-gpio", 0); - if (!gpio_is_valid(pdata->hph_en1_gpio)) - pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,hph-en1-gpio", 0); - if (!gpio_is_valid(pdata->hph_en1_gpio) && (!pdata->hph_en1_gpio_p)) { - dev_dbg(&pdev->dev, "property %s not detected in node %s", - "qcom,hph-en1-gpio", pdev->dev.of_node->full_name); - } - - pdata->hph_en0_gpio = of_get_named_gpio(pdev->dev.of_node, - "qcom,hph-en0-gpio", 0); - if (!gpio_is_valid(pdata->hph_en0_gpio)) - pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,hph-en0-gpio", 0); - if (!gpio_is_valid(pdata->hph_en0_gpio) && (!pdata->hph_en0_gpio_p)) { - dev_dbg(&pdev->dev, "property %s not detected in node %s", - "qcom,hph-en0-gpio", pdev->dev.of_node->full_name); - } - - ret = msm_ext_prepare_hifi(pdata); - if (ret) { - dev_dbg(&pdev->dev, "msm_ext_prepare_hifi failed (%d)\n", - ret); - ret = 0; - } -err: - return ret; -} -EXPORT_SYMBOL(msm_ext_cdc_init); diff --git a/asoc/sdm660-external.h b/asoc/sdm660-external.h deleted file mode 100644 index b81e158be5f7..000000000000 --- a/asoc/sdm660-external.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __SDM660_EXTERNAL -#define __SDM660_EXTERNAL - -int msm_snd_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params); -int msm_ext_slimbus_2_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params); -int msm_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params); -int msm_proxy_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params); -int msm_proxy_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params); -int msm_audrx_init(struct snd_soc_pcm_runtime *rtd); -int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params); -struct snd_soc_card *populate_snd_card_dailinks(struct device *dev, - int snd_card_val); -int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params); -int msm_snd_card_tavil_late_probe(struct snd_soc_card *card); -int msm_snd_card_tasha_late_probe(struct snd_soc_card *card); -#if IS_ENABLED(CONFIG_SND_SOC_EXT_CODEC) -int msm_ext_cdc_init(struct platform_device *, struct msm_asoc_mach_data *, - struct snd_soc_card **, struct wcd_mbhc_config *); -void msm_ext_register_audio_notifier(struct platform_device *pdev); -#else -inline int msm_ext_cdc_init(struct platform_device *pdev, - struct msm_asoc_mach_data *pdata, - struct snd_soc_card **card, - struct wcd_mbhc_config *wcd_mbhc_cfg_ptr1) -{ - return 0; -} - -inline void msm_ext_register_audio_notifier(struct platform_device *pdev) -{ -} -#endif -#endif diff --git a/asoc/sdm660-internal.c b/asoc/sdm660-internal.c deleted file mode 100644 index fc141e32530e..000000000000 --- a/asoc/sdm660-internal.c +++ /dev/null @@ -1,3354 +0,0 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include "msm-pcm-routing-v2.h" -#include "sdm660-common.h" -#include "codecs/msm-cdc-pinctrl.h" -#include "codecs/sdm660_cdc/msm-digital-cdc.h" -#include "codecs/sdm660_cdc/msm-analog-cdc.h" -#include "codecs/msm_sdw/msm_sdw.h" -#include - -#define __CHIPSET__ "SDM660 " -#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) - -#define WCD_MBHC_DEF_RLOADS 5 - -#define WCN_CDC_SLIM_RX_CH_MAX 2 -#define WCN_CDC_SLIM_TX_CH_MAX 3 - -#define WSA8810_NAME_1 "wsa881x.20170211" -#define WSA8810_NAME_2 "wsa881x.20170212" -#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ -enum { - INT0_MI2S = 0, - INT1_MI2S, - INT2_MI2S, - INT3_MI2S, - INT4_MI2S, - INT5_MI2S, - INT6_MI2S, - INT_MI2S_MAX, -}; - -enum { - BT_SLIM7, - FM_SLIM8, - SLIM_MAX, -}; - -/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */ -static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { - {0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */ - {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */ -}; - -static struct afe_clk_set int_mi2s_clk[INT_MI2S_MAX] = { - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_INT0_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_INT1_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_INT2_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_INT3_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_INT4_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_INT5_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_INT6_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, -}; - -struct dev_config { - u32 sample_rate; - u32 bit_format; - u32 channels; -}; - -/* Default configuration of MI2S channels */ -static struct dev_config int_mi2s_cfg[] = { - [INT0_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, - [INT1_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [INT2_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [INT3_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [INT4_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [INT5_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, - [INT6_MI2S] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, -}; - -static struct dev_config bt_fm_cfg[] = { - [BT_SLIM7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [FM_SLIM8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, -}; - -static char const *int_mi2s_rate_text[] = {"KHZ_8", "KHZ_16", - "KHZ_32", "KHZ_44P1", "KHZ_48", - "KHZ_96", "KHZ_192"}; -static const char *const int_mi2s_ch_text[] = {"One", "Two"}; -static const char *const int_mi2s_tx_ch_text[] = {"One", "Two", - "Three", "Four"}; -static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"}; -static const char *const loopback_mclk_text[] = {"DISABLE", "ENABLE"}; -static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", - "KHZ_44P1", "KHZ_48", - "KHZ_88P2", "KHZ_96"}; - -static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_sample_rate, int_mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_chs, int_mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(int2_mi2s_tx_sample_rate, int_mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(int2_mi2s_tx_chs, int_mi2s_tx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(int2_mi2s_tx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(int3_mi2s_tx_sample_rate, int_mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(int3_mi2s_tx_chs, int_mi2s_tx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(int3_mi2s_tx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_sample_rate, int_mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_chs, int_mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(int5_mi2s_tx_chs, int_mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(loopback_mclk_en, loopback_mclk_text); -static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); - -static int msm_dmic_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event); -static int msm_int_enable_dig_cdc_clk(struct snd_soc_codec *codec, int enable, - bool dapm); -static int msm_int_mclk0_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event); -static int msm_int_mi2s_snd_startup(struct snd_pcm_substream *substream); -static void msm_int_mi2s_snd_shutdown(struct snd_pcm_substream *substream); - -static struct wcd_mbhc_config *mbhc_cfg_ptr; -static struct snd_info_entry *codec_root; - -static int int_mi2s_get_bit_format_val(int bit_format) -{ - int val = 0; - - switch (bit_format) { - case SNDRV_PCM_FORMAT_S24_3LE: - val = 2; - break; - case SNDRV_PCM_FORMAT_S24_LE: - val = 1; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - val = 0; - break; - } - return val; -} - -static int int_mi2s_get_bit_format(int val) -{ - int bit_fmt = SNDRV_PCM_FORMAT_S16_LE; - - switch (val) { - case 0: - bit_fmt = SNDRV_PCM_FORMAT_S16_LE; - break; - case 1: - bit_fmt = SNDRV_PCM_FORMAT_S24_LE; - break; - case 2: - bit_fmt = SNDRV_PCM_FORMAT_S24_3LE; - break; - default: - bit_fmt = SNDRV_PCM_FORMAT_S16_LE; - break; - } - return bit_fmt; -} - -static int int_mi2s_get_port_idx(struct snd_kcontrol *kcontrol) -{ - int port_id = 0; - - if (strnstr(kcontrol->id.name, "INT0_MI2S", sizeof("INT0_MI2S"))) - port_id = INT0_MI2S; - else if (strnstr(kcontrol->id.name, "INT2_MI2S", sizeof("INT2_MI2S"))) - port_id = INT2_MI2S; - else if (strnstr(kcontrol->id.name, "INT3_MI2S", sizeof("INT3_MI2S"))) - port_id = INT3_MI2S; - else if (strnstr(kcontrol->id.name, "INT4_MI2S", sizeof("INT4_MI2S"))) - port_id = INT4_MI2S; - else { - pr_err("%s: unsupported channel: %s", - __func__, kcontrol->id.name); - return -EINVAL; - } - - return port_id; -} - -static int int_mi2s_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = int_mi2s_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - ucontrol->value.enumerated.item[0] = - int_mi2s_get_bit_format_val(int_mi2s_cfg[ch_num].bit_format); - - pr_debug("%s: int_mi2s[%d]_bit_format = %d, ucontrol value = %d\n", - __func__, ch_num, int_mi2s_cfg[ch_num].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int int_mi2s_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = int_mi2s_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - int_mi2s_cfg[ch_num].bit_format = - int_mi2s_get_bit_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: int_mi2s[%d]_rx_bit_format = %d, ucontrol value = %d\n", - __func__, ch_num, int_mi2s_cfg[ch_num].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static inline int param_is_mask(int p) -{ - return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && - (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); -} - -static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, - int n) -{ - return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); -} - -static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit) -{ - if (bit >= SNDRV_MASK_MAX) - return; - if (param_is_mask(n)) { - struct snd_mask *m = param_to_mask(p, n); - - m->bits[0] = 0; - m->bits[1] = 0; - m->bits[bit >> 5] |= (1 << (bit & 31)); - } -} - -static int int_mi2s_get_sample_rate_val(int sample_rate) -{ - int sample_rate_val; - - switch (sample_rate) { - case SAMPLING_RATE_8KHZ: - sample_rate_val = 0; - break; - case SAMPLING_RATE_16KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_32KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 3; - break; - case SAMPLING_RATE_48KHZ: - sample_rate_val = 4; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 5; - break; - case SAMPLING_RATE_192KHZ: - sample_rate_val = 6; - break; - default: - sample_rate_val = 4; - break; - } - return sample_rate_val; -} - -static int int_mi2s_get_sample_rate(int value) -{ - int sample_rate; - - switch (value) { - case 0: - sample_rate = SAMPLING_RATE_8KHZ; - break; - case 1: - sample_rate = SAMPLING_RATE_16KHZ; - break; - case 2: - sample_rate = SAMPLING_RATE_32KHZ; - break; - case 3: - sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 4: - sample_rate = SAMPLING_RATE_48KHZ; - break; - case 5: - sample_rate = SAMPLING_RATE_96KHZ; - break; - case 6: - sample_rate = SAMPLING_RATE_192KHZ; - break; - default: - sample_rate = SAMPLING_RATE_48KHZ; - break; - } - return sample_rate; -} - -static int int_mi2s_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = int_mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - int_mi2s_cfg[idx].sample_rate = - int_mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_sample_rate = %d, item = %d\n", __func__, - idx, int_mi2s_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int int_mi2s_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = int_mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - int_mi2s_get_sample_rate_val(int_mi2s_cfg[idx].sample_rate); - - pr_debug("%s: idx[%d]_sample_rate = %d, item = %d\n", __func__, - idx, int_mi2s_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int int_mi2s_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = int_mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - pr_debug("%s: int_mi2s_[%d]_rx_ch = %d\n", __func__, - idx, int_mi2s_cfg[idx].channels); - ucontrol->value.enumerated.item[0] = int_mi2s_cfg[idx].channels - 1; - - return 0; -} - -static int int_mi2s_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = int_mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - int_mi2s_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; - pr_debug("%s: int_mi2s_[%d]_ch = %d\n", __func__, - idx, int_mi2s_cfg[idx].channels); - - return 1; -} - -static const struct snd_soc_dapm_widget msm_int_dapm_widgets[] = { - SND_SOC_DAPM_SUPPLY_S("INT_MCLK0", -1, SND_SOC_NOPM, 0, 0, - msm_int_mclk0_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIC("Handset Mic", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("Secondary Mic", NULL), - SND_SOC_DAPM_MIC("Digital Mic1", msm_dmic_event), - SND_SOC_DAPM_MIC("Digital Mic2", msm_dmic_event), - SND_SOC_DAPM_MIC("Digital Mic3", msm_dmic_event), - SND_SOC_DAPM_MIC("Digital Mic4", msm_dmic_event), -}; - -static int msm_config_hph_compander_gpio(bool enable, - struct snd_soc_codec *codec) -{ - struct snd_soc_card *card = codec->component.card; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - int ret = 0; - - pr_debug("%s: %s HPH Compander\n", __func__, - enable ? "Enable" : "Disable"); - - if (enable) { - ret = msm_cdc_pinctrl_select_active_state(pdata->comp_gpio_p); - if (ret) { - pr_err("%s: gpio set cannot be activated %s\n", - __func__, "comp_gpio"); - goto done; - } - } else { - ret = msm_cdc_pinctrl_select_sleep_state(pdata->comp_gpio_p); - if (ret) { - pr_err("%s: gpio set cannot be de-activated %s\n", - __func__, "comp_gpio"); - goto done; - } - } - -done: - return ret; -} - -static int is_ext_spk_gpio_support(struct platform_device *pdev, - struct msm_asoc_mach_data *pdata) -{ - const char *spk_ext_pa = "qcom,msm-spk-ext-pa"; - - pr_debug("%s:Enter\n", __func__); - - pdata->spk_ext_pa_gpio = of_get_named_gpio(pdev->dev.of_node, - spk_ext_pa, 0); - - if (pdata->spk_ext_pa_gpio < 0) { - dev_dbg(&pdev->dev, - "%s: missing %s in dt node\n", __func__, spk_ext_pa); - } else { - if (!gpio_is_valid(pdata->spk_ext_pa_gpio)) { - pr_err("%s: Invalid external speaker gpio: %d", - __func__, pdata->spk_ext_pa_gpio); - return -EINVAL; - } - } - return 0; -} - -static int enable_spk_ext_pa(struct snd_soc_codec *codec, int enable) -{ - struct snd_soc_card *card = codec->component.card; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - int ret; - - if (!gpio_is_valid(pdata->spk_ext_pa_gpio)) { - pr_err("%s: Invalid gpio: %d\n", __func__, - pdata->spk_ext_pa_gpio); - return false; - } - - pr_debug("%s: %s external speaker PA\n", __func__, - enable ? "Enable" : "Disable"); - - if (enable) { - ret = msm_cdc_pinctrl_select_active_state( - pdata->ext_spk_gpio_p); - if (ret) { - pr_err("%s: gpio set cannot be de-activated %s\n", - __func__, "ext_spk_gpio"); - return ret; - } - gpio_set_value_cansleep(pdata->spk_ext_pa_gpio, enable); - } else { - gpio_set_value_cansleep(pdata->spk_ext_pa_gpio, enable); - ret = msm_cdc_pinctrl_select_sleep_state( - pdata->ext_spk_gpio_p); - if (ret) { - pr_err("%s: gpio set cannot be de-activated %s\n", - __func__, "ext_spk_gpio"); - return ret; - } - } - return 0; -} - -static int int_mi2s_get_idx_from_beid(int32_t id) -{ - int idx = 0; - - switch (id) { - case MSM_BACKEND_DAI_INT0_MI2S_RX: - idx = INT0_MI2S; - break; - case MSM_BACKEND_DAI_INT2_MI2S_TX: - idx = INT2_MI2S; - break; - case MSM_BACKEND_DAI_INT3_MI2S_TX: - idx = INT3_MI2S; - break; - case MSM_BACKEND_DAI_INT4_MI2S_RX: - idx = INT4_MI2S; - break; - case MSM_BACKEND_DAI_INT5_MI2S_TX: - idx = INT5_MI2S; - break; - default: - idx = INT0_MI2S; - break; - } - - return idx; -} - -static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - pr_debug("%s()\n", __func__); - rate->min = rate->max = 48000; - channels->min = channels->max = 2; - - return 0; -} - -static int int_mi2s_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_dai_link *dai_link = rtd->dai_link; - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - int idx; - - pr_debug("%s: format = %d, rate = %d\n", - __func__, params_format(params), params_rate(params)); - - switch (dai_link->id) { - case MSM_BACKEND_DAI_INT0_MI2S_RX: - case MSM_BACKEND_DAI_INT2_MI2S_TX: - case MSM_BACKEND_DAI_INT3_MI2S_TX: - case MSM_BACKEND_DAI_INT4_MI2S_RX: - case MSM_BACKEND_DAI_INT5_MI2S_TX: - idx = int_mi2s_get_idx_from_beid(dai_link->id); - rate->min = rate->max = int_mi2s_cfg[idx].sample_rate; - channels->min = channels->max = - int_mi2s_cfg[idx].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - int_mi2s_cfg[idx].bit_format); - break; - default: - rate->min = rate->max = SAMPLING_RATE_48KHZ; - break; - } - return 0; -} - -static int msm_btfm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_dai_link *dai_link = rtd->dai_link; - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - switch (dai_link->id) { - case MSM_BACKEND_DAI_SLIMBUS_7_RX: - case MSM_BACKEND_DAI_SLIMBUS_7_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - bt_fm_cfg[BT_SLIM7].bit_format); - rate->min = rate->max = bt_fm_cfg[BT_SLIM7].sample_rate; - channels->min = channels->max = - bt_fm_cfg[BT_SLIM7].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_8_TX: - rate->min = rate->max = bt_fm_cfg[FM_SLIM8].sample_rate; - channels->min = channels->max = - bt_fm_cfg[FM_SLIM8].channels; - break; - - default: - rate->min = rate->max = SAMPLING_RATE_48KHZ; - break; - } - return 0; -} - -static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = - (int_mi2s_cfg[INT5_MI2S].channels/2 - 1); - pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, - ucontrol->value.integer.value[0]); - return 0; -} - -static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int_mi2s_cfg[INT5_MI2S].channels = - roundup_pow_of_two(ucontrol->value.integer.value[0] + 2); - - pr_debug("%s: msm_vi_feed_tx_ch = %d\n", - __func__, int_mi2s_cfg[INT5_MI2S].channels); - return 1; -} - -static int msm_int_enable_dig_cdc_clk(struct snd_soc_codec *codec, - int enable, bool dapm) -{ - int ret = 0; - struct msm_asoc_mach_data *pdata = NULL; - int clk_freq_in_hz; - bool int_mclk0_freq_chg = false; - - pdata = snd_soc_card_get_drvdata(codec->component.card); - pr_debug("%s: enable %d mclk ref counter %d\n", - __func__, enable, - atomic_read(&pdata->int_mclk0_rsc_ref)); - if (enable) { - if (int_mi2s_cfg[INT0_MI2S].sample_rate == - SAMPLING_RATE_44P1KHZ) { - clk_freq_in_hz = NATIVE_MCLK_RATE; - pdata->native_clk_set = true; - } else { - clk_freq_in_hz = pdata->mclk_freq; - pdata->native_clk_set = false; - } - - if (pdata->digital_cdc_core_clk.clk_freq_in_hz - != clk_freq_in_hz) - int_mclk0_freq_chg = true; - if (!atomic_read(&pdata->int_mclk0_rsc_ref) || - int_mclk0_freq_chg) { - cancel_delayed_work_sync( - &pdata->disable_int_mclk0_work); - mutex_lock(&pdata->cdc_int_mclk0_mutex); - if (atomic_read(&pdata->int_mclk0_enabled) == false || - int_mclk0_freq_chg) { - if (atomic_read(&pdata->int_mclk0_enabled)) { - pdata->digital_cdc_core_clk.enable = 0; - afe_set_lpass_clock_v2( - AFE_PORT_ID_INT0_MI2S_RX, - &pdata->digital_cdc_core_clk); - } - pdata->digital_cdc_core_clk.clk_freq_in_hz = - clk_freq_in_hz; - pdata->digital_cdc_core_clk.enable = 1; - ret = afe_set_lpass_clock_v2( - AFE_PORT_ID_INT0_MI2S_RX, - &pdata->digital_cdc_core_clk); - if (ret < 0) { - pr_err("%s: failed to enable CCLK\n", - __func__); - mutex_unlock( - &pdata->cdc_int_mclk0_mutex); - return ret; - } - pr_debug("enabled digital codec core clk\n"); - atomic_set(&pdata->int_mclk0_enabled, true); - } - mutex_unlock(&pdata->cdc_int_mclk0_mutex); - } - atomic_inc(&pdata->int_mclk0_rsc_ref); - } else { - cancel_delayed_work_sync(&pdata->disable_int_mclk0_work); - mutex_lock(&pdata->cdc_int_mclk0_mutex); - if (atomic_read(&pdata->int_mclk0_enabled) == true) { - pdata->digital_cdc_core_clk.clk_freq_in_hz = - DEFAULT_MCLK_RATE; - pdata->digital_cdc_core_clk.enable = 0; - ret = afe_set_lpass_clock_v2( - AFE_PORT_ID_INT0_MI2S_RX, - &pdata->digital_cdc_core_clk); - if (ret < 0) - pr_err("%s: failed to disable CCLK\n", - __func__); - atomic_set(&pdata->int_mclk0_enabled, false); - atomic_set(&pdata->int_mclk0_rsc_ref, 0); - } - mutex_unlock(&pdata->cdc_int_mclk0_mutex); - } - return ret; -} - -static int loopback_mclk_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s\n", __func__); - return 0; -} - -static int loopback_mclk_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = -EINVAL; - struct msm_asoc_mach_data *pdata = NULL; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - - pdata = snd_soc_card_get_drvdata(codec->component.card); - pr_debug("%s: mclk_rsc_ref %d enable %ld\n", - __func__, atomic_read(&pdata->int_mclk0_rsc_ref), - ucontrol->value.integer.value[0]); - switch (ucontrol->value.integer.value[0]) { - case 1: - ret = msm_cdc_pinctrl_select_active_state(pdata->pdm_gpio_p); - if (ret) { - pr_err("%s: failed to enable the pri gpios: %d\n", - __func__, ret); - break; - } - mutex_lock(&pdata->cdc_int_mclk0_mutex); - if ((!atomic_read(&pdata->int_mclk0_rsc_ref)) && - (!atomic_read(&pdata->int_mclk0_enabled))) { - pdata->digital_cdc_core_clk.enable = 1; - ret = afe_set_lpass_clock_v2( - AFE_PORT_ID_INT0_MI2S_RX, - &pdata->digital_cdc_core_clk); - if (ret < 0) { - pr_err("%s: failed to enable the MCLK: %d\n", - __func__, ret); - mutex_unlock(&pdata->cdc_int_mclk0_mutex); - ret = msm_cdc_pinctrl_select_sleep_state( - pdata->pdm_gpio_p); - if (ret) - pr_err("%s: failed to disable the pri gpios: %d\n", - __func__, ret); - break; - } - atomic_set(&pdata->int_mclk0_enabled, true); - } - mutex_unlock(&pdata->cdc_int_mclk0_mutex); - atomic_inc(&pdata->int_mclk0_rsc_ref); - msm_anlg_cdc_mclk_enable(codec, 1, true); - break; - case 0: - if (atomic_read(&pdata->int_mclk0_rsc_ref) <= 0) - break; - msm_anlg_cdc_mclk_enable(codec, 0, true); - mutex_lock(&pdata->cdc_int_mclk0_mutex); - if ((!atomic_dec_return(&pdata->int_mclk0_rsc_ref)) && - (atomic_read(&pdata->int_mclk0_enabled))) { - pdata->digital_cdc_core_clk.enable = 0; - ret = afe_set_lpass_clock_v2( - AFE_PORT_ID_INT0_MI2S_RX, - &pdata->digital_cdc_core_clk); - if (ret < 0) { - pr_err("%s: failed to disable the CCLK: %d\n", - __func__, ret); - mutex_unlock(&pdata->cdc_int_mclk0_mutex); - break; - } - atomic_set(&pdata->int_mclk0_enabled, false); - } - mutex_unlock(&pdata->cdc_int_mclk0_mutex); - ret = msm_cdc_pinctrl_select_sleep_state(pdata->pdm_gpio_p); - if (ret) - pr_err("%s: failed to disable the pri gpios: %d\n", - __func__, ret); - break; - default: - pr_err("%s: Unexpected input value\n", __func__); - break; - } - return ret; -} - -static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - /* - * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) - * when used for BT_SCO use case. Return either Rx or Tx sample rate - * value. - */ - switch (bt_fm_cfg[BT_SLIM7].sample_rate) { - case SAMPLING_RATE_96KHZ: - ucontrol->value.integer.value[0] = 5; - break; - case SAMPLING_RATE_88P2KHZ: - ucontrol->value.integer.value[0] = 4; - break; - case SAMPLING_RATE_48KHZ: - ucontrol->value.integer.value[0] = 3; - break; - case SAMPLING_RATE_44P1KHZ: - ucontrol->value.integer.value[0] = 2; - break; - case SAMPLING_RATE_16KHZ: - ucontrol->value.integer.value[0] = 1; - break; - case SAMPLING_RATE_8KHZ: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - pr_debug("%s: sample rate = %d", __func__, - bt_fm_cfg[BT_SLIM7].sample_rate); - - return 0; -} - -static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 1: - bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_16KHZ; - break; - case 2: - bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 3: - bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_48KHZ; - break; - case 4: - bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_88P2KHZ; - break; - case 5: - bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_96KHZ; - break; - case 0: - default: - bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_8KHZ; - break; - } - pr_debug("%s: sample rates: slim7_rx = %d, value = %d\n", - __func__, - bt_fm_cfg[BT_SLIM7].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static const struct snd_kcontrol_new msm_snd_controls[] = { - SOC_ENUM_EXT("INT0_MI2S_RX Format", int0_mi2s_rx_format, - int_mi2s_bit_format_get, int_mi2s_bit_format_put), - SOC_ENUM_EXT("INT2_MI2S_TX Format", int2_mi2s_tx_format, - int_mi2s_bit_format_get, int_mi2s_bit_format_put), - SOC_ENUM_EXT("INT3_MI2S_TX Format", int3_mi2s_tx_format, - int_mi2s_bit_format_get, int_mi2s_bit_format_put), - SOC_ENUM_EXT("INT0_MI2S_RX SampleRate", int0_mi2s_rx_sample_rate, - int_mi2s_sample_rate_get, - int_mi2s_sample_rate_put), - SOC_ENUM_EXT("INT2_MI2S_TX SampleRate", int2_mi2s_tx_sample_rate, - int_mi2s_sample_rate_get, - int_mi2s_sample_rate_put), - SOC_ENUM_EXT("INT3_MI2S_TX SampleRate", int3_mi2s_tx_sample_rate, - int_mi2s_sample_rate_get, - int_mi2s_sample_rate_put), - SOC_ENUM_EXT("INT0_MI2S_RX Channels", int0_mi2s_rx_chs, - int_mi2s_ch_get, int_mi2s_ch_put), - SOC_ENUM_EXT("INT2_MI2S_TX Channels", int2_mi2s_tx_chs, - int_mi2s_ch_get, int_mi2s_ch_put), - SOC_ENUM_EXT("INT3_MI2S_TX Channels", int3_mi2s_tx_chs, - int_mi2s_ch_get, int_mi2s_ch_put), - SOC_ENUM_EXT("Loopback MCLK", loopback_mclk_en, - loopback_mclk_get, loopback_mclk_put), - SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, - msm_bt_sample_rate_get, - msm_bt_sample_rate_put), -}; - -static const struct snd_kcontrol_new msm_sdw_controls[] = { - SOC_ENUM_EXT("INT4_MI2S_RX Format", int4_mi2s_rx_format, - int_mi2s_bit_format_get, int_mi2s_bit_format_put), - SOC_ENUM_EXT("INT4_MI2S_RX SampleRate", int4_mi2s_rx_sample_rate, - int_mi2s_sample_rate_get, - int_mi2s_sample_rate_put), - SOC_ENUM_EXT("INT4_MI2S_RX Channels", int4_mi2s_rx_chs, - int_mi2s_ch_get, int_mi2s_ch_put), - SOC_ENUM_EXT("VI_FEED_TX Channels", int5_mi2s_tx_chs, - msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), -}; - -static int msm_dmic_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct msm_asoc_mach_data *pdata = NULL; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - int ret = 0; - - pdata = snd_soc_card_get_drvdata(codec->component.card); - pr_debug("%s: event = %d\n", __func__, event); - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - ret = msm_cdc_pinctrl_select_active_state(pdata->dmic_gpio_p); - if (ret < 0) { - pr_err("%s: gpio set cannot be activated %sd", - __func__, "dmic_gpio"); - return ret; - } - break; - case SND_SOC_DAPM_POST_PMD: - ret = msm_cdc_pinctrl_select_sleep_state(pdata->dmic_gpio_p); - if (ret < 0) { - pr_err("%s: gpio set cannot be de-activated %sd", - __func__, "dmic_gpio"); - return ret; - } - break; - default: - pr_err("%s: invalid DAPM event %d\n", __func__, event); - return -EINVAL; - } - return 0; -} - -static int msm_int_mclk0_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct msm_asoc_mach_data *pdata = NULL; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - int ret = 0; - - pdata = snd_soc_card_get_drvdata(codec->component.card); - pr_debug("%s: event = %d\n", __func__, event); - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - ret = msm_cdc_pinctrl_select_active_state(pdata->pdm_gpio_p); - if (ret < 0) { - pr_err("%s: gpio set cannot be activated %s\n", - __func__, "int_pdm"); - return ret; - } - msm_int_enable_dig_cdc_clk(codec, 1, true); - msm_anlg_cdc_mclk_enable(codec, 1, true); - break; - case SND_SOC_DAPM_POST_PMD: - pr_debug("%s: mclk_res_ref = %d\n", - __func__, atomic_read(&pdata->int_mclk0_rsc_ref)); - ret = msm_cdc_pinctrl_select_sleep_state(pdata->pdm_gpio_p); - if (ret < 0) { - pr_err("%s: gpio set cannot be de-activated %sd", - __func__, "int_pdm"); - return ret; - } - pr_debug("%s: disabling MCLK\n", __func__); - /* disable the codec mclk config*/ - msm_anlg_cdc_mclk_enable(codec, 0, true); - msm_int_enable_dig_cdc_clk(codec, 0, true); - break; - default: - pr_err("%s: invalid DAPM event %d\n", __func__, event); - return -EINVAL; - } - return 0; -} - -static int int_mi2s_get_port_id(int id) -{ - int afe_port_id; - - switch (id) { - case MSM_BACKEND_DAI_INT0_MI2S_RX: - afe_port_id = AFE_PORT_ID_INT0_MI2S_RX; - break; - case MSM_BACKEND_DAI_INT2_MI2S_TX: - afe_port_id = AFE_PORT_ID_INT2_MI2S_TX; - break; - case MSM_BACKEND_DAI_INT3_MI2S_TX: - afe_port_id = AFE_PORT_ID_INT3_MI2S_TX; - break; - case MSM_BACKEND_DAI_INT4_MI2S_RX: - afe_port_id = AFE_PORT_ID_INT4_MI2S_RX; - break; - case MSM_BACKEND_DAI_INT5_MI2S_TX: - afe_port_id = AFE_PORT_ID_INT5_MI2S_TX; - break; - default: - pr_err("%s: Invalid id: %d\n", __func__, id); - afe_port_id = -EINVAL; - } - - return afe_port_id; -} - -static int int_mi2s_get_index(int port_id) -{ - int index; - - switch (port_id) { - case AFE_PORT_ID_INT0_MI2S_RX: - index = INT0_MI2S; - break; - case AFE_PORT_ID_INT2_MI2S_TX: - index = INT2_MI2S; - break; - case AFE_PORT_ID_INT3_MI2S_TX: - index = INT3_MI2S; - break; - case AFE_PORT_ID_INT4_MI2S_RX: - index = INT4_MI2S; - break; - case AFE_PORT_ID_INT5_MI2S_TX: - index = INT5_MI2S; - break; - default: - pr_err("%s: Invalid port_id: %d\n", __func__, port_id); - index = -EINVAL; - } - - return index; -} - -static u32 get_int_mi2s_bits_per_sample(u32 bit_format) -{ - u32 bit_per_sample; - - switch (bit_format) { - case SNDRV_PCM_FORMAT_S24_3LE: - case SNDRV_PCM_FORMAT_S24_LE: - bit_per_sample = 32; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - bit_per_sample = 16; - break; - } - - return bit_per_sample; -} - -static void update_int_mi2s_clk_val(int idx, int stream) -{ - u32 bit_per_sample; - - bit_per_sample = - get_int_mi2s_bits_per_sample(int_mi2s_cfg[idx].bit_format); - int_mi2s_clk[idx].clk_freq_in_hz = - (int_mi2s_cfg[idx].sample_rate * 2 * bit_per_sample); -} - -static int int_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) -{ - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - int port_id = 0; - int index; - - port_id = int_mi2s_get_port_id(rtd->dai_link->id); - if (port_id < 0) { - dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); - ret = port_id; - goto done; - } - index = int_mi2s_get_index(port_id); - if (index < 0) { - dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); - ret = port_id; - goto done; - } - if (enable) { - update_int_mi2s_clk_val(index, substream->stream); - dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, - int_mi2s_clk[index].clk_freq_in_hz); - } - - int_mi2s_clk[index].enable = enable; - ret = afe_set_lpass_clock_v2(port_id, - &int_mi2s_clk[index]); - if (ret < 0) { - dev_err(rtd->card->dev, - "%s: afe lpass clock failed for port 0x%x , err:%d\n", - __func__, port_id, ret); - goto done; - } - -done: - return ret; -} - -static int msm_sdw_mi2s_snd_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret = 0; - - pr_debug("%s(): substream = %s stream = %d\n", __func__, - substream->name, substream->stream); - - ret = int_mi2s_set_sclk(substream, true); - if (ret < 0) { - pr_err("%s: failed to enable sclk %d\n", - __func__, ret); - return ret; - } - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - pr_err("%s: set fmt cpu dai failed; ret=%d\n", __func__, ret); - - return ret; -} - -static void msm_sdw_mi2s_snd_shutdown(struct snd_pcm_substream *substream) -{ - int ret; - - pr_debug("%s(): substream = %s stream = %d\n", __func__, - substream->name, substream->stream); - - ret = int_mi2s_set_sclk(substream, false); - if (ret < 0) - pr_err("%s:clock disable failed; ret=%d\n", __func__, - ret); -} - -static int msm_int_mi2s_snd_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_codec *codec = rtd->codec_dais[ANA_CDC]->codec; - int ret = 0; - struct msm_asoc_mach_data *pdata = NULL; - - pdata = snd_soc_card_get_drvdata(codec->component.card); - pr_debug("%s(): substream = %s stream = %d\n", __func__, - substream->name, substream->stream); - - ret = int_mi2s_set_sclk(substream, true); - if (ret < 0) { - pr_err("%s: failed to enable sclk %d\n", - __func__, ret); - return ret; - } - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - pr_err("%s: set fmt cpu dai failed; ret=%d\n", __func__, ret); - - return ret; -} - -static void msm_int_mi2s_snd_shutdown(struct snd_pcm_substream *substream) -{ - int ret; - - pr_debug("%s(): substream = %s stream = %d\n", __func__, - substream->name, substream->stream); - - ret = int_mi2s_set_sclk(substream, false); - if (ret < 0) - pr_err("%s:clock disable failed; ret=%d\n", __func__, - ret); -} - -static void *def_msm_int_wcd_mbhc_cal(void) -{ - void *msm_int_wcd_cal; - struct wcd_mbhc_btn_detect_cfg *btn_cfg; - u16 *btn_low, *btn_high; - - msm_int_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, - WCD_MBHC_DEF_RLOADS), GFP_KERNEL); - if (!msm_int_wcd_cal) - return NULL; - -#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(msm_int_wcd_cal)->X) = (Y)) - S(v_hs_max, 1500); -#undef S -#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(msm_int_wcd_cal)->X) = (Y)) - S(num_btn, WCD_MBHC_DEF_BUTTONS); -#undef S - - - btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(msm_int_wcd_cal); - btn_low = btn_cfg->_v_btn_low; - btn_high = ((void *)&btn_cfg->_v_btn_low) + - (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); - - /* - * In SW we are maintaining two sets of threshold register - * one for current source and another for Micbias. - * all btn_low corresponds to threshold for current source - * all bt_high corresponds to threshold for Micbias - * Below thresholds are based on following resistances - * 0-70 == Button 0 - * 110-180 == Button 1 - * 210-290 == Button 2 - * 360-680 == Button 3 - */ - btn_low[0] = 75; - btn_high[0] = 75; - btn_low[1] = 150; - btn_high[1] = 150; - btn_low[2] = 225; - btn_high[2] = 225; - btn_low[3] = 450; - btn_high[3] = 450; - btn_low[4] = 500; - btn_high[4] = 500; - - return msm_int_wcd_cal; -} - -static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *dig_cdc = rtd->codec_dais[DIG_CDC]->codec; - struct snd_soc_codec *ana_cdc = rtd->codec_dais[ANA_CDC]->codec; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(ana_cdc); - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); - struct snd_card *card; - int ret = -ENOMEM; - - pr_debug("%s(),dev_name%s\n", __func__, dev_name(cpu_dai->dev)); - - ret = snd_soc_add_codec_controls(ana_cdc, msm_snd_controls, - ARRAY_SIZE(msm_snd_controls)); - if (ret < 0) { - pr_err("%s: add_codec_controls failed: %d\n", - __func__, ret); - return ret; - } - ret = snd_soc_add_codec_controls(ana_cdc, msm_common_snd_controls, - msm_common_snd_controls_size()); - if (ret < 0) { - pr_err("%s: add common snd controls failed: %d\n", - __func__, ret); - return ret; - } - - snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets, - ARRAY_SIZE(msm_int_dapm_widgets)); - - snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Secondary Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); - - snd_soc_dapm_ignore_suspend(dapm, "EAR"); - snd_soc_dapm_ignore_suspend(dapm, "HEADPHONE"); - snd_soc_dapm_ignore_suspend(dapm, "SPK_OUT"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); - snd_soc_dapm_sync(dapm); - - dapm = snd_soc_codec_get_dapm(dig_cdc); - snd_soc_dapm_ignore_suspend(dapm, "DMIC1"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC2"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC3"); - snd_soc_dapm_ignore_suspend(dapm, "DMIC4"); - - snd_soc_dapm_sync(dapm); - - msm_anlg_cdc_spk_ext_pa_cb(enable_spk_ext_pa, ana_cdc); - msm_dig_cdc_hph_comp_cb(msm_config_hph_compander_gpio, dig_cdc); - - card = rtd->card->snd_card; - if (!codec_root) - codec_root = snd_info_create_subdir(card->module, "codecs", - card->proc_root); - if (!codec_root) { - pr_debug("%s: Cannot create codecs module entry\n", - __func__); - goto done; - } - pdata->codec_root = codec_root; - msm_dig_codec_info_create_codec_entry(codec_root, dig_cdc); - msm_anlg_codec_info_create_codec_entry(codec_root, ana_cdc); -done: - msm_set_codec_reg_done(true); - return 0; -} - -static int msm_sdw_audrx_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = - snd_soc_codec_get_dapm(codec); - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *aux_comp; - struct snd_card *card; - - snd_soc_add_codec_controls(codec, msm_sdw_controls, - ARRAY_SIZE(msm_sdw_controls)); - - snd_soc_dapm_ignore_suspend(dapm, "AIF1_SDW Playback"); - snd_soc_dapm_ignore_suspend(dapm, "VIfeed_SDW"); - snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); - snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); - snd_soc_dapm_ignore_suspend(dapm, "AIF1_SDW VI"); - snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_SDW"); - - snd_soc_dapm_sync(dapm); - - /* - * Send speaker configuration only for WSA8810. - * Default configuration is for WSA8815. - */ - pr_debug("%s: Number of aux devices: %d\n", - __func__, rtd->card->num_aux_devs); - if (rtd->card->num_aux_devs && - !list_empty(&rtd->card->aux_comp_list)) { - aux_comp = list_first_entry(&rtd->card->aux_comp_list, - struct snd_soc_component, list_aux); - if (!strcmp(aux_comp->name, WSA8810_NAME_1) || - !strcmp(aux_comp->name, WSA8810_NAME_2)) { - msm_sdw_set_spkr_mode(rtd->codec, SPKR_MODE_1); - msm_sdw_set_spkr_gain_offset(rtd->codec, - RX_GAIN_OFFSET_M1P5_DB); - } - } - card = rtd->card->snd_card; - if (!codec_root) - codec_root = snd_info_create_subdir(card->module, "codecs", - card->proc_root); - if (!codec_root) { - pr_debug("%s: Cannot create codecs module entry\n", - __func__); - goto done; - } - pdata->codec_root = codec_root; - msm_sdw_codec_info_create_codec_entry(codec_root, codec); -done: - return 0; -} - -static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) -{ - unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; - unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - - return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), - tx_ch, ARRAY_SIZE(rx_ch), rx_ch); -} - -static int msm_wcn_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai_link *dai_link = rtd->dai_link; - u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; - u32 rx_ch_cnt = 0, tx_ch_cnt = 0; - int ret; - - dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, - codec_dai->name, codec_dai->id); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret) { - dev_err(rtd->dev, - "%s: failed to get BTFM codec chan map\n, err:%d\n", - __func__, ret); - goto exit; - } - - dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) id %d\n", - __func__, tx_ch_cnt, dai_link->id); - - ret = snd_soc_dai_set_channel_map(cpu_dai, - tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); - if (ret) - dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - -exit: - return ret; -} - -static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width, - int slots) -{ - unsigned int slot_mask = 0; - int i, j; - unsigned int *slot_offset; - - for (i = TDM_0; i < TDM_PORT_MAX; i++) { - slot_offset = tdm_slot_offset[i]; - - for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) { - if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID) - slot_mask |= - (1 << ((slot_offset[j] * 8) / slot_width)); - else - break; - } - } - - return slot_mask; -} - -static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret = 0; - int channels, slot_width, slots; - unsigned int slot_mask; - unsigned int *slot_offset; - int offset_channels = 0; - int i; - - pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); - - channels = params_channels(params); - switch (channels) { - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S32_LE: - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S16_LE: - /* - * up to 8 channels HW config should - * use 32 bit slot width for max support of - * stream bit width. (slot_width > bit_width) - */ - slot_width = 32; - break; - default: - pr_err("%s: invalid param format 0x%x\n", - __func__, params_format(params)); - return -EINVAL; - } - slots = 8; - slot_mask = tdm_param_set_slot_mask(cpu_dai->id, - slot_width, - slots); - if (!slot_mask) { - pr_err("%s: invalid slot_mask 0x%x\n", - __func__, slot_mask); - return -EINVAL; - } - break; - default: - pr_err("%s: invalid param channels %d\n", - __func__, channels); - return -EINVAL; - } - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - switch (cpu_dai->id) { - case AFE_PORT_ID_PRIMARY_TDM_RX: - case AFE_PORT_ID_SECONDARY_TDM_RX: - case AFE_PORT_ID_TERTIARY_TDM_RX: - case AFE_PORT_ID_QUATERNARY_TDM_RX: - case AFE_PORT_ID_QUINARY_TDM_RX: - case AFE_PORT_ID_PRIMARY_TDM_TX: - case AFE_PORT_ID_SECONDARY_TDM_TX: - case AFE_PORT_ID_TERTIARY_TDM_TX: - case AFE_PORT_ID_QUATERNARY_TDM_TX: - case AFE_PORT_ID_QUINARY_TDM_TX: - slot_offset = tdm_slot_offset[TDM_0]; - break; - default: - pr_err("%s: dai id 0x%x not supported\n", - __func__, cpu_dai->id); - return -EINVAL; - } - - for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { - if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) - offset_channels++; - else - break; - } - - if (offset_channels == 0) { - pr_err("%s: slot offset not supported, offset_channels %d\n", - __func__, offset_channels); - return -EINVAL; - } - - if (channels > offset_channels) { - pr_err("%s: channels %d exceed offset_channels %d\n", - __func__, channels, offset_channels); - return -EINVAL; - } - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, - slots, slot_width); - if (ret < 0) { - pr_err("%s: failed to set tdm slot, err:%d\n", - __func__, ret); - goto end; - } - - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, - channels, slot_offset); - if (ret < 0) { - pr_err("%s: failed to set channel map, err:%d\n", - __func__, ret); - goto end; - } - } else { - ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, - slots, slot_width); - if (ret < 0) { - pr_err("%s: failed to set tdm slot, err:%d\n", - __func__, ret); - goto end; - } - - ret = snd_soc_dai_set_channel_map(cpu_dai, channels, - slot_offset, 0, NULL); - if (ret < 0) { - pr_err("%s: failed to set channel map, err:%d\n", - __func__, ret); - goto end; - } - } -end: - return ret; -} - -static int msm_snd_card_late_probe(struct snd_soc_card *card) -{ - const char *be_dl_name = LPASS_BE_INT0_MI2S_RX; - struct snd_soc_codec *ana_cdc; - struct snd_soc_pcm_runtime *rtd; - int ret = 0; - - rtd = snd_soc_get_pcm_runtime(card, be_dl_name); - if (!rtd) { - dev_err(card->dev, - "%s: snd_soc_get_pcm_runtime for %s failed!\n", - __func__, be_dl_name); - return -EINVAL; - } - - ana_cdc = rtd->codec_dais[ANA_CDC]->codec; - mbhc_cfg_ptr->calibration = def_msm_int_wcd_mbhc_cal(); - if (!mbhc_cfg_ptr->calibration) - return -ENOMEM; - - ret = msm_anlg_cdc_hs_detect(ana_cdc, mbhc_cfg_ptr); - if (ret) { - dev_err(card->dev, - "%s: msm_anlg_cdc_hs_detect failed\n", __func__); - kfree(mbhc_cfg_ptr->calibration); - } - - return ret; -} - -static struct snd_soc_ops msm_tdm_be_ops = { - .hw_params = msm_tdm_snd_hw_params -}; - -static struct snd_soc_ops msm_wcn_ops = { - .hw_params = msm_wcn_hw_params, -}; - -static struct snd_soc_ops msm_mi2s_be_ops = { - .startup = msm_mi2s_snd_startup, - .shutdown = msm_mi2s_snd_shutdown, -}; - -static struct snd_soc_ops msm_aux_pcm_be_ops = { - .startup = msm_aux_pcm_snd_startup, - .shutdown = msm_aux_pcm_snd_shutdown, -}; - -static struct snd_soc_ops msm_int_mi2s_be_ops = { - .startup = msm_int_mi2s_snd_startup, - .shutdown = msm_int_mi2s_snd_shutdown, -}; - -static struct snd_soc_ops msm_sdw_mi2s_be_ops = { - .startup = msm_sdw_mi2s_snd_startup, - .shutdown = msm_sdw_mi2s_snd_shutdown, -}; - -static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) -{ - cpumask_t mask; - - if (pm_qos_request_active(&substream->latency_pm_qos_req)) - pm_qos_remove_request(&substream->latency_pm_qos_req); - - cpumask_clear(&mask); - cpumask_set_cpu(1, &mask); /* affine to core 1 */ - cpumask_set_cpu(2, &mask); /* affine to core 2 */ - cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); - - substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; - - pm_qos_add_request(&substream->latency_pm_qos_req, - PM_QOS_CPU_DMA_LATENCY, - MSM_LL_QOS_VALUE); - return 0; -} - -static struct snd_soc_ops msm_fe_qos_ops = { - .prepare = msm_fe_qos_prepare, -}; - -struct snd_soc_dai_link_component dlc_rx1[] = { - { - .of_node = NULL, - .dai_name = "msm_dig_cdc_dai_rx1", - }, - { - .of_node = NULL, - .dai_name = "msm_anlg_cdc_i2s_rx1", - }, -}; - -struct snd_soc_dai_link_component dlc_tx1[] = { - { - .of_node = NULL, - .dai_name = "msm_dig_cdc_dai_tx1", - }, - { - .of_node = NULL, - .dai_name = "msm_anlg_cdc_i2s_tx1", - }, -}; - -struct snd_soc_dai_link_component dlc_tx2[] = { - { - .of_node = NULL, - .dai_name = "msm_dig_cdc_dai_tx2", - }, - { - .of_node = NULL, - .dai_name = "msm_anlg_cdc_i2s_tx2", - }, -}; - -/* Digital audio interface glue - connects codec <---> CPU */ -static struct snd_soc_dai_link msm_int_dai[] = { - /* FrontEnd DAI Links */ - {/* hw:x,0 */ - .name = MSM_DAILINK_NAME(Media1), - .stream_name = "MultiMedia1", - .cpu_dai_name = "MultiMedia1", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - /* this dai link has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA1 - }, - {/* hw:x,1 */ - .name = MSM_DAILINK_NAME(Media2), - .stream_name = "MultiMedia2", - .cpu_dai_name = "MultiMedia2", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - /* this dai link has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA2, - }, - {/* hw:x,2 */ - .name = "VoiceMMode1", - .stream_name = "VoiceMMode1", - .cpu_dai_name = "VoiceMMode1", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_VOICEMMODE1, - }, - {/* hw:x,3 */ - .name = "MSM VoIP", - .stream_name = "VoIP", - .cpu_dai_name = "VoIP", - .platform_name = "msm-voip-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dai link has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_VOIP, - }, - {/* hw:x,4 */ - .name = MSM_DAILINK_NAME(ULL), - .stream_name = "ULL", - .cpu_dai_name = "MultiMedia3", - .platform_name = "msm-pcm-dsp.2", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dai link has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA3, - }, - /* Hostless PCM purpose */ - {/* hw:x,5 */ - .name = "INT4 MI2S_RX Hostless", - .stream_name = "INT4 MI2S_RX Hostless", - .cpu_dai_name = "INT4_MI2S_RX_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - /* This dainlink has MI2S support */ - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,6 */ - .name = "MSM AFE-PCM RX", - .stream_name = "AFE-PROXY RX", - .cpu_dai_name = "msm-dai-q6-dev.241", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .platform_name = "msm-pcm-afe", - .ignore_suspend = 1, - /* this dai link has playback support */ - .ignore_pmdown_time = 1, - }, - {/* hw:x,7 */ - .name = "MSM AFE-PCM TX", - .stream_name = "AFE-PROXY TX", - .cpu_dai_name = "msm-dai-q6-dev.240", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .platform_name = "msm-pcm-afe", - .ignore_suspend = 1, - }, - {/* hw:x,8 */ - .name = MSM_DAILINK_NAME(Compress1), - .stream_name = "Compress1", - .cpu_dai_name = "MultiMedia4", - .platform_name = "msm-compress-dsp", - .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA4, - }, - {/* hw:x,9*/ - .name = "AUXPCM Hostless", - .stream_name = "AUXPCM Hostless", - .cpu_dai_name = "AUXPCM_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dai link has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,10 */ - .name = "SLIMBUS_1 Hostless", - .stream_name = "SLIMBUS_1 Hostless", - .cpu_dai_name = "SLIMBUS1_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, /* dai link has playback support */ - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,11 */ - .name = "INT3 MI2S_TX Hostless", - .stream_name = "INT3 MI2S_TX Hostless", - .cpu_dai_name = "INT3_MI2S_TX_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,12 */ - .name = "SLIMBUS_7 Hostless", - .stream_name = "SLIMBUS_7 Hostless", - .cpu_dai_name = "SLIMBUS7_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, /* dai link has playback support */ - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,13 */ - .name = MSM_DAILINK_NAME(LowLatency), - .stream_name = "MultiMedia5", - .cpu_dai_name = "MultiMedia5", - .platform_name = "msm-pcm-dsp.1", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - /* this dai link has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA5, - .ops = &msm_fe_qos_ops, - }, - /* LSM FE */ - {/* hw:x,14 */ - .name = "Listen 1 Audio Service", - .stream_name = "Listen 1 Audio Service", - .cpu_dai_name = "LSM1", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM1, - }, - {/* hw:x,15 */ - .name = MSM_DAILINK_NAME(Compress2), - .stream_name = "Compress2", - .cpu_dai_name = "MultiMedia7", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA7, - }, - {/* hw:x,16 */ - .name = MSM_DAILINK_NAME(MultiMedia10), - .stream_name = "MultiMedia10", - .cpu_dai_name = "MultiMedia10", - .platform_name = "msm-pcm-dsp.1", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA10, - }, - {/* hw:x,17 */ - .name = MSM_DAILINK_NAME(ULL_NOIRQ), - .stream_name = "MM_NOIRQ", - .cpu_dai_name = "MultiMedia8", - .platform_name = "msm-pcm-dsp-noirq", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA8, - .ops = &msm_fe_qos_ops, - }, - {/* hw:x,18 */ - .name = "HDMI_RX_HOSTLESS", - .stream_name = "HDMI_RX_HOSTLESS", - .cpu_dai_name = "HDMI_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,19 */ - .name = "VoiceMMode2", - .stream_name = "VoiceMMode2", - .cpu_dai_name = "VoiceMMode2", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_VOICEMMODE2, - }, - {/* hw:x,20 */ - .name = "Listen 2 Audio Service", - .stream_name = "Listen 2 Audio Service", - .cpu_dai_name = "LSM2", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM2, - }, - {/* hw:x,21 */ - .name = "Listen 3 Audio Service", - .stream_name = "Listen 3 Audio Service", - .cpu_dai_name = "LSM3", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM3, - }, - {/* hw:x,22 */ - .name = "Listen 4 Audio Service", - .stream_name = "Listen 4 Audio Service", - .cpu_dai_name = "LSM4", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM4, - }, - {/* hw:x,23 */ - .name = "Listen 5 Audio Service", - .stream_name = "Listen 5 Audio Service", - .cpu_dai_name = "LSM5", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM5, - }, - {/* hw:x,24 */ - .name = "Listen 6 Audio Service", - .stream_name = "Listen 6 Audio Service", - .cpu_dai_name = "LSM6", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM6 - }, - {/* hw:x,25 */ - .name = "Listen 7 Audio Service", - .stream_name = "Listen 7 Audio Service", - .cpu_dai_name = "LSM7", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM7, - }, - {/* hw:x,26 */ - .name = "Listen 8 Audio Service", - .stream_name = "Listen 8 Audio Service", - .cpu_dai_name = "LSM8", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM8, - }, - {/* hw:x,27 */ - .name = MSM_DAILINK_NAME(Media9), - .stream_name = "MultiMedia9", - .cpu_dai_name = "MultiMedia9", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA9, - }, - {/* hw:x,28 */ - .name = MSM_DAILINK_NAME(Compress4), - .stream_name = "Compress4", - .cpu_dai_name = "MultiMedia11", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA11, - }, - {/* hw:x,29 */ - .name = MSM_DAILINK_NAME(Compress5), - .stream_name = "Compress5", - .cpu_dai_name = "MultiMedia12", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA12, - }, - {/* hw:x,30 */ - .name = MSM_DAILINK_NAME(Compress6), - .stream_name = "Compress6", - .cpu_dai_name = "MultiMedia13", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA13, - }, - {/* hw:x,31 */ - .name = MSM_DAILINK_NAME(Compress7), - .stream_name = "Compress7", - .cpu_dai_name = "MultiMedia14", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA14, - }, - {/* hw:x,32 */ - .name = MSM_DAILINK_NAME(Compress8), - .stream_name = "Compress8", - .cpu_dai_name = "MultiMedia15", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA15, - }, - {/* hw:x,33 */ - .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), - .stream_name = "MM_NOIRQ_2", - .cpu_dai_name = "MultiMedia16", - .platform_name = "msm-pcm-dsp-noirq", - .dynamic = 1, - .dpcm_capture = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dai link has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA16, - }, - {/* hw:x,34 */ - .name = "SLIMBUS_8 Hostless", - .stream_name = "SLIMBUS8_HOSTLESS Capture", - .cpu_dai_name = "SLIMBUS8_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,35 */ - .name = "Primary MI2S_RX Hostless", - .stream_name = "Primary MI2S_RX Hostless", - .cpu_dai_name = "PRI_MI2S_RX_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - /* This dainlink has MI2S support */ - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,36 */ - .name = "Secondary MI2S_RX Hostless", - .stream_name = "Secondary MI2S_RX Hostless", - .cpu_dai_name = "SEC_MI2S_RX_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - /* This dainlink has MI2S support */ - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,37 */ - .name = "Tertiary MI2S_RX Hostless", - .stream_name = "Tertiary MI2S_RX Hostless", - .cpu_dai_name = "TERT_MI2S_RX_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - /* This dainlink has MI2S support */ - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,38 */ - .name = "INT0 MI2S_RX Hostless", - .stream_name = "INT0 MI2S_RX Hostless", - .cpu_dai_name = "INT0_MI2S_RX_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - /* This dainlink has MI2S support */ - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - {/* hw:x,39 */ - .name = "SDM660 HFP TX", - .stream_name = "MultiMedia6", - .cpu_dai_name = "MultiMedia6", - .platform_name = "msm-pcm-loopback", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA6, - }, -}; - - -static struct snd_soc_dai_link msm_int_wsa_dai[] = { - {/* hw:x,40 */ - .name = LPASS_BE_INT5_MI2S_TX, - .stream_name = "INT5_mi2s Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.12", - .platform_name = "msm-pcm-hostless", - .codec_name = "msm_sdw_codec", - .codec_dai_name = "msm_sdw_vifeedback", - .id = MSM_BACKEND_DAI_INT5_MI2S_TX, - .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, - .ops = &msm_sdw_mi2s_be_ops, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .dpcm_capture = 1, - }, -}; - -static struct snd_soc_dai_link msm_int_compress_capture_dai[] = { - {/* hw:x,41 */ - .name = "Compress9", - .stream_name = "Compress9", - .cpu_dai_name = "MultiMedia17", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA17, - }, - {/* hw:x,42 */ - .name = "Compress10", - .stream_name = "Compress10", - .cpu_dai_name = "MultiMedia18", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA18, - }, - {/* hw:x,43 */ - .name = "Compress11", - .stream_name = "Compress11", - .cpu_dai_name = "MultiMedia19", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA19, - }, - {/* hw:x,44 */ - .name = "Compress12", - .stream_name = "Compress12", - .cpu_dai_name = "MultiMedia28", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA28, - }, - {/* hw:x,45 */ - .name = "Compress13", - .stream_name = "Compress13", - .cpu_dai_name = "MultiMedia29", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA29, - }, -}; - -static struct snd_soc_dai_link msm_int_be_dai[] = { - /* Backend I2S DAI Links */ - { - .name = LPASS_BE_INT0_MI2S_RX, - .stream_name = "INT0 MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.7", - .platform_name = "msm-pcm-routing", - .codecs = dlc_rx1, - .num_codecs = CODECS_MAX, - .no_pcm = 1, - .dpcm_playback = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE | - ASYNC_DPCM_SND_SOC_HW_PARAMS, - .id = MSM_BACKEND_DAI_INT0_MI2S_RX, - .init = &msm_audrx_init, - .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, - .ops = &msm_int_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_INT3_MI2S_TX, - .stream_name = "INT3 MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.10", - .platform_name = "msm-pcm-routing", - .codecs = dlc_tx1, - .num_codecs = CODECS_MAX, - .no_pcm = 1, - .dpcm_capture = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE | - ASYNC_DPCM_SND_SOC_HW_PARAMS, - .id = MSM_BACKEND_DAI_INT3_MI2S_TX, - .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, - .ops = &msm_int_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_INT2_MI2S_TX, - .stream_name = "INT2 MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.9", - .platform_name = "msm-pcm-routing", - .codecs = dlc_tx2, - .num_codecs = CODECS_MAX, - .no_pcm = 1, - .dpcm_capture = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE | - ASYNC_DPCM_SND_SOC_HW_PARAMS, - .id = MSM_BACKEND_DAI_INT2_MI2S_TX, - .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, - .ops = &msm_int_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_AFE_PCM_RX, - .stream_name = "AFE Playback", - .cpu_dai_name = "msm-dai-q6-dev.224", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_AFE_PCM_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_AFE_PCM_TX, - .stream_name = "AFE Capture", - .cpu_dai_name = "msm-dai-q6-dev.225", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_AFE_PCM_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Record Uplink BACK END DAI Link */ - { - .name = LPASS_BE_INCALL_RECORD_TX, - .stream_name = "Voice Uplink Capture", - .cpu_dai_name = "msm-dai-q6-dev.32772", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Record Downlink BACK END DAI Link */ - { - .name = LPASS_BE_INCALL_RECORD_RX, - .stream_name = "Voice Downlink Capture", - .cpu_dai_name = "msm-dai-q6-dev.32771", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Music BACK END DAI Link */ - { - .name = LPASS_BE_VOICE_PLAYBACK_TX, - .stream_name = "Voice Farend Playback", - .cpu_dai_name = "msm-dai-q6-dev.32773", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - /* Incall Music 2 BACK END DAI Link */ - { - .name = LPASS_BE_VOICE2_PLAYBACK_TX, - .stream_name = "Voice2 Farend Playback", - .cpu_dai_name = "msm-dai-q6-dev.32770", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_USB_AUDIO_RX, - .stream_name = "USB Audio Playback", - .cpu_dai_name = "msm-dai-q6-dev.28672", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_USB_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_USB_AUDIO_TX, - .stream_name = "USB Audio Capture", - .cpu_dai_name = "msm-dai-q6-dev.28673", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_USB_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_PRI_TDM_RX_0, - .stream_name = "Primary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36864", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_PRI_TDM_TX_0, - .stream_name = "Primary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36865", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SEC_TDM_RX_0, - .stream_name = "Secondary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36880", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_SEC_TDM_TX_0, - .stream_name = "Secondary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36881", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_TERT_TDM_RX_0, - .stream_name = "Tertiary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36896", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_TERT_TDM_TX_0, - .stream_name = "Tertiary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36897", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_QUAT_TDM_RX_0, - .stream_name = "Quaternary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36912", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_QUAT_TDM_TX_0, - .stream_name = "Quaternary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36913", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_QUIN_TDM_RX_0, - .stream_name = "Quinary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36928", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUIN_TDM_RX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_QUIN_TDM_TX_0, - .stream_name = "Quinary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36929", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUIN_TDM_TX_0, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_tdm_be_ops, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { - { - .name = LPASS_BE_PRI_MI2S_RX, - .stream_name = "Primary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.0", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_PRI_MI2S_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_PRI_MI2S_TX, - .stream_name = "Primary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.0", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_PRI_MI2S_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SEC_MI2S_RX, - .stream_name = "Secondary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_SEC_MI2S_TX, - .stream_name = "Secondary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_TERT_MI2S_RX, - .stream_name = "Tertiary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_TERT_MI2S_TX, - .stream_name = "Tertiary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_QUAT_MI2S_RX, - .stream_name = "Quaternary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.3", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_QUAT_MI2S_TX, - .stream_name = "Quaternary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.3", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_QUIN_MI2S_RX, - .stream_name = "Quinary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.4", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUINARY_MI2S_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_QUIN_MI2S_TX, - .stream_name = "Quinary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.4", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUINARY_MI2S_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { - /* Primary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_AUXPCM_RX, - .stream_name = "AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_AUXPCM_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - { - .name = LPASS_BE_AUXPCM_TX, - .stream_name = "AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_AUXPCM_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - /* Secondary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_SEC_AUXPCM_RX, - .stream_name = "Sec AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - { - .name = LPASS_BE_SEC_AUXPCM_TX, - .stream_name = "Sec AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - /* Tertiary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_TERT_AUXPCM_RX, - .stream_name = "Tert AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.3", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - { - .name = LPASS_BE_TERT_AUXPCM_TX, - .stream_name = "Tert AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.3", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - /* Quaternary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_QUAT_AUXPCM_RX, - .stream_name = "Quat AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.4", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - { - .name = LPASS_BE_QUAT_AUXPCM_TX, - .stream_name = "Quat AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.4", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - /* Quinary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_QUIN_AUXPCM_RX, - .stream_name = "Quin AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.5", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, - { - .name = LPASS_BE_QUIN_AUXPCM_TX, - .stream_name = "Quin AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.5", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_aux_pcm_be_ops, - }, -}; - - -static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { - { - .name = LPASS_BE_SLIMBUS_7_RX, - .stream_name = "Slimbus7 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16398", - .platform_name = "msm-pcm-routing", - .codec_name = "btfmslim_slave", - /* BT codec driver determines capabilities based on - * dai name, bt codecdai name should always contains - * supported usecase information - */ - .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_7_RX, - .be_hw_params_fixup = msm_btfm_be_hw_params_fixup, - .ops = &msm_wcn_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_7_TX, - .stream_name = "Slimbus7 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16399", - .platform_name = "msm-pcm-routing", - .codec_name = "btfmslim_slave", - .codec_dai_name = "btfm_bt_sco_slim_tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_7_TX, - .be_hw_params_fixup = msm_btfm_be_hw_params_fixup, - .ops = &msm_wcn_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_8_TX, - .stream_name = "Slimbus8 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16401", - .platform_name = "msm-pcm-routing", - .codec_name = "btfmslim_slave", - .codec_dai_name = "btfm_fm_slim_tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_8_TX, - .be_hw_params_fixup = msm_btfm_be_hw_params_fixup, - .init = &msm_wcn_init, - .ops = &msm_wcn_ops, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm_wsa_be_dai_links[] = { - { - .name = LPASS_BE_INT4_MI2S_RX, - .stream_name = "INT4 MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.11", - .platform_name = "msm-pcm-routing", - .codec_name = "msm_sdw_codec", - .codec_dai_name = "msm_sdw_i2s_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_INT4_MI2S_RX, - .init = &msm_sdw_audrx_init, - .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, - .ops = &msm_sdw_mi2s_be_ops, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link ext_disp_be_dai_link[] = { - /* DISP PORT BACK END DAI Link */ - { - .name = LPASS_BE_DISPLAY_PORT, - .stream_name = "Display Port Playback", - .cpu_dai_name = "msm-dai-q6-dp.24608", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-ext-disp-audio-codec-rx", - .codec_dai_name = "msm_dp_audio_codec_rx_dai", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, - .be_hw_params_fixup = msm_common_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm_int_dai_links[ -ARRAY_SIZE(msm_int_dai) + -ARRAY_SIZE(msm_int_wsa_dai) + -ARRAY_SIZE(msm_int_compress_capture_dai) + -ARRAY_SIZE(msm_int_be_dai) + -ARRAY_SIZE(msm_mi2s_be_dai_links) + -ARRAY_SIZE(msm_auxpcm_be_dai_links)+ -ARRAY_SIZE(msm_wcn_be_dai_links) + -ARRAY_SIZE(msm_wsa_be_dai_links) + -ARRAY_SIZE(ext_disp_be_dai_link)]; - -static struct snd_soc_card sdm660_card = { - /* snd_soc_card_sdm660 */ - .name = "sdm660-snd-card", - .dai_link = msm_int_dai, - .num_links = ARRAY_SIZE(msm_int_dai), - .late_probe = msm_snd_card_late_probe, -}; - -static void msm_disable_int_mclk0(struct work_struct *work) -{ - struct msm_asoc_mach_data *pdata = NULL; - struct delayed_work *dwork; - int ret = 0; - - dwork = to_delayed_work(work); - pdata = container_of(dwork, struct msm_asoc_mach_data, - disable_int_mclk0_work); - mutex_lock(&pdata->cdc_int_mclk0_mutex); - pr_debug("%s: mclk_enabled %d mclk_rsc_ref %d\n", __func__, - atomic_read(&pdata->int_mclk0_enabled), - atomic_read(&pdata->int_mclk0_rsc_ref)); - - if (atomic_read(&pdata->int_mclk0_enabled) == true - && atomic_read(&pdata->int_mclk0_rsc_ref) == 0) { - pr_debug("Disable the mclk\n"); - pdata->digital_cdc_core_clk.enable = 0; - pdata->digital_cdc_core_clk.clk_freq_in_hz = - DEFAULT_MCLK_RATE; - ret = afe_set_lpass_clock_v2( - AFE_PORT_ID_INT0_MI2S_RX, - &pdata->digital_cdc_core_clk); - if (ret < 0) - pr_err("%s failed to disable the CCLK\n", __func__); - atomic_set(&pdata->int_mclk0_enabled, false); - } - mutex_unlock(&pdata->cdc_int_mclk0_mutex); -} - -static void msm_int_dt_parse_cap_info(struct platform_device *pdev, - struct msm_asoc_mach_data *pdata) -{ - const char *ext1_cap = "qcom,msm-micbias1-ext-cap"; - const char *ext2_cap = "qcom,msm-micbias2-ext-cap"; - - pdata->micbias1_cap_mode = - (of_property_read_bool(pdev->dev.of_node, ext1_cap) ? - MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); - - pdata->micbias2_cap_mode = - (of_property_read_bool(pdev->dev.of_node, ext2_cap) ? - MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); -} - -static struct snd_soc_card *msm_int_populate_sndcard_dailinks( - struct device *dev) -{ - struct snd_soc_card *card = &sdm660_card; - struct snd_soc_dai_link *dailink; - int len1; - - card->name = dev_name(dev); - len1 = ARRAY_SIZE(msm_int_dai); - memcpy(msm_int_dai_links, msm_int_dai, sizeof(msm_int_dai)); - dailink = msm_int_dai_links; - if (!of_property_read_bool(dev->of_node, - "qcom,wsa-disable")) { - memcpy(dailink + len1, - msm_int_wsa_dai, - sizeof(msm_int_wsa_dai)); - len1 += ARRAY_SIZE(msm_int_wsa_dai); - } - memcpy(dailink + len1, msm_int_compress_capture_dai, - sizeof(msm_int_compress_capture_dai)); - len1 += ARRAY_SIZE(msm_int_compress_capture_dai); - - memcpy(dailink + len1, msm_int_be_dai, sizeof(msm_int_be_dai)); - len1 += ARRAY_SIZE(msm_int_be_dai); - - if (of_property_read_bool(dev->of_node, - "qcom,mi2s-audio-intf")) { - memcpy(dailink + len1, - msm_mi2s_be_dai_links, - sizeof(msm_mi2s_be_dai_links)); - len1 += ARRAY_SIZE(msm_mi2s_be_dai_links); - } - if (of_property_read_bool(dev->of_node, - "qcom,auxpcm-audio-intf")) { - memcpy(dailink + len1, - msm_auxpcm_be_dai_links, - sizeof(msm_auxpcm_be_dai_links)); - len1 += ARRAY_SIZE(msm_auxpcm_be_dai_links); - } - if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { - dev_dbg(dev, "%s(): WCN BTFM support present\n", - __func__); - memcpy(dailink + len1, - msm_wcn_be_dai_links, - sizeof(msm_wcn_be_dai_links)); - len1 += ARRAY_SIZE(msm_wcn_be_dai_links); - } - if (!of_property_read_bool(dev->of_node, "qcom,wsa-disable")) { - memcpy(dailink + len1, - msm_wsa_be_dai_links, - sizeof(msm_wsa_be_dai_links)); - len1 += ARRAY_SIZE(msm_wsa_be_dai_links); - } - if (of_property_read_bool(dev->of_node, "qcom,ext-disp-audio-rx")) { - dev_dbg(dev, "%s(): ext disp audio support present\n", - __func__); - memcpy(dailink + len1, - ext_disp_be_dai_link, - sizeof(ext_disp_be_dai_link)); - len1 += ARRAY_SIZE(ext_disp_be_dai_link); - } - card->dai_link = dailink; - card->num_links = len1; - return card; -} - -static int msm_internal_init(struct platform_device *pdev, - struct msm_asoc_mach_data *pdata, - struct snd_soc_card *card) -{ - const char *type = NULL; - const char *hs_micbias_type = "qcom,msm-hs-micbias-type"; - int ret; - - ret = is_ext_spk_gpio_support(pdev, pdata); - if (ret < 0) - dev_dbg(&pdev->dev, - "%s: doesn't support external speaker pa\n", - __func__); - - ret = of_property_read_string(pdev->dev.of_node, - hs_micbias_type, &type); - if (ret) { - dev_err(&pdev->dev, "%s: missing %s in dt node\n", - __func__, hs_micbias_type); - goto err; - } - if (!strcmp(type, "external")) { - dev_dbg(&pdev->dev, "Headset is using external micbias\n"); - mbhc_cfg_ptr->hs_ext_micbias = true; - } else { - dev_dbg(&pdev->dev, "Headset is using internal micbias\n"); - mbhc_cfg_ptr->hs_ext_micbias = false; - } - - /* initialize the int_mclk0 */ - pdata->digital_cdc_core_clk.clk_set_minor_version = - AFE_API_VERSION_I2S_CONFIG; - pdata->digital_cdc_core_clk.clk_id = - Q6AFE_LPASS_CLK_ID_INT_MCLK_0; - pdata->digital_cdc_core_clk.clk_freq_in_hz = pdata->mclk_freq; - pdata->digital_cdc_core_clk.clk_attri = - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO; - pdata->digital_cdc_core_clk.clk_root = - Q6AFE_LPASS_CLK_ROOT_DEFAULT; - pdata->digital_cdc_core_clk.enable = 1; - - /* Initialize loopback mode to false */ - pdata->lb_mode = false; - - msm_int_dt_parse_cap_info(pdev, pdata); - - card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); - snd_soc_card_set_drvdata(card, pdata); - ret = snd_soc_of_parse_card_name(card, "qcom,model"); - if (ret) - goto err; - /* initialize timer */ - INIT_DELAYED_WORK(&pdata->disable_int_mclk0_work, - msm_disable_int_mclk0); - mutex_init(&pdata->cdc_int_mclk0_mutex); - atomic_set(&pdata->int_mclk0_rsc_ref, 0); - atomic_set(&pdata->int_mclk0_enabled, false); - - dev_info(&pdev->dev, "%s: default codec configured\n", __func__); - - return 0; -err: - return ret; -} - -/** - * msm_int_cdc_init - internal codec machine specific init. - * - * @pdev: platform device handle - * @pdata: private data of machine driver - * @card: sound card pointer reference - * @mbhc_cfg: MBHC config reference - * - * Returns 0. - */ -int msm_int_cdc_init(struct platform_device *pdev, - struct msm_asoc_mach_data *pdata, - struct snd_soc_card **card, - struct wcd_mbhc_config *mbhc_cfg) -{ - mbhc_cfg_ptr = mbhc_cfg; - - *card = msm_int_populate_sndcard_dailinks(&pdev->dev); - msm_internal_init(pdev, pdata, *card); - return 0; -} -EXPORT_SYMBOL(msm_int_cdc_init); diff --git a/asoc/sdm660-internal.h b/asoc/sdm660-internal.h deleted file mode 100644 index 6918231b8b74..000000000000 --- a/asoc/sdm660-internal.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __SDM660_INTERNAL -#define __SDM660_INTERNAL - -#include - -#if IS_ENABLED(CONFIG_SND_SOC_INT_CODEC) -int msm_int_cdc_init(struct platform_device *pdev, - struct msm_asoc_mach_data *pdata, - struct snd_soc_card **card, - struct wcd_mbhc_config *mbhc_cfg); -#else -int msm_int_cdc_init(struct platform_device *pdev, - struct msm_asoc_mach_data *pdata, - struct snd_soc_card **card, - struct wcd_mbhc_config *mbhc_cfg) -{ - return 0; -} -#endif -#endif diff --git a/asoc/sdm845.c b/asoc/sdm845.c deleted file mode 100644 index 3fe402329485..000000000000 --- a/asoc/sdm845.c +++ /dev/null @@ -1,6963 +0,0 @@ -/* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "msm-pcm-routing-v2.h" -#include "codecs/msm-cdc-pinctrl.h" -#include "codecs/wcd934x/wcd934x.h" -#include "codecs/wcd934x/wcd934x-mbhc.h" -#include "codecs/wsa881x.h" - -#define DRV_NAME "sdm845-asoc-snd" - -#define __CHIPSET__ "SDM845 " -#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) - -#define SAMPLING_RATE_8KHZ 8000 -#define SAMPLING_RATE_11P025KHZ 11025 -#define SAMPLING_RATE_16KHZ 16000 -#define SAMPLING_RATE_22P05KHZ 22050 -#define SAMPLING_RATE_32KHZ 32000 -#define SAMPLING_RATE_44P1KHZ 44100 -#define SAMPLING_RATE_48KHZ 48000 -#define SAMPLING_RATE_88P2KHZ 88200 -#define SAMPLING_RATE_96KHZ 96000 -#define SAMPLING_RATE_176P4KHZ 176400 -#define SAMPLING_RATE_192KHZ 192000 -#define SAMPLING_RATE_352P8KHZ 352800 -#define SAMPLING_RATE_384KHZ 384000 - -#define WCD9XXX_MBHC_DEF_BUTTONS 8 -#define WCD9XXX_MBHC_DEF_RLOADS 5 -#define CODEC_EXT_CLK_RATE 9600000 -#define ADSP_STATE_READY_TIMEOUT_MS 3000 -#define DEV_NAME_STR_LEN 32 - -#define WSA8810_NAME_1 "wsa881x.20170211" -#define WSA8810_NAME_2 "wsa881x.20170212" - -#define WCN_CDC_SLIM_RX_CH_MAX 2 -#define WCN_CDC_SLIM_TX_CH_MAX 3 - -#define TDM_CHANNEL_MAX 8 - -#define MSM_HIFI_ON 1 -#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ - -enum { - SLIM_RX_0 = 0, - SLIM_RX_1, - SLIM_RX_2, - SLIM_RX_3, - SLIM_RX_4, - SLIM_RX_5, - SLIM_RX_6, - SLIM_RX_7, - SLIM_RX_MAX, -}; - -enum { - SLIM_TX_0 = 0, - SLIM_TX_1, - SLIM_TX_2, - SLIM_TX_3, - SLIM_TX_4, - SLIM_TX_5, - SLIM_TX_6, - SLIM_TX_7, - SLIM_TX_8, - SLIM_TX_MAX, -}; - -enum { - PRIM_MI2S = 0, - SEC_MI2S, - TERT_MI2S, - QUAT_MI2S, - MI2S_MAX, -}; - -enum { - PRIM_AUX_PCM = 0, - SEC_AUX_PCM, - TERT_AUX_PCM, - QUAT_AUX_PCM, - AUX_PCM_MAX, -}; - -struct mi2s_conf { - struct mutex lock; - u32 ref_cnt; - u32 msm_is_mi2s_master; -}; - -static u32 mi2s_ebit_clk[MI2S_MAX] = { - Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT, - Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT, - Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT, - Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT -}; - -struct dev_config { - u32 sample_rate; - u32 bit_format; - u32 channels; -}; - -enum { - DP_RX_IDX = 0, - EXT_DISP_RX_IDX_MAX, -}; - -struct msm_wsa881x_dev_info { - struct device_node *of_node; - u32 index; -}; - -enum pinctrl_pin_state { - STATE_DISABLE = 0, /* All pins are in sleep state */ - STATE_MI2S_ACTIVE, /* IS2 = active, TDM = sleep */ - STATE_TDM_ACTIVE, /* IS2 = sleep, TDM = active */ -}; - -struct msm_pinctrl_info { - struct pinctrl *pinctrl; - struct pinctrl_state *mi2s_disable; - struct pinctrl_state *tdm_disable; - struct pinctrl_state *mi2s_active; - struct pinctrl_state *tdm_active; - enum pinctrl_pin_state curr_state; -}; - -struct msm_asoc_mach_data { - u32 mclk_freq; - int us_euro_gpio; /* used by gpio driver API */ - int usbc_en2_gpio; /* used by gpio driver API */ - struct device_node *us_euro_gpio_p; /* used by pinctrl API */ - struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */ - struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ - struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ - struct snd_info_entry *codec_root; - struct msm_pinctrl_info pinctrl_info; -}; - -struct msm_asoc_wcd93xx_codec { - void* (*get_afe_config_fn)(struct snd_soc_codec *codec, - enum afe_config_type config_type); - void (*mbhc_hs_detect_exit)(struct snd_soc_codec *codec); -}; - -static const char *const pin_states[] = {"sleep", "i2s-active", - "tdm-active"}; - -enum { - TDM_0 = 0, - TDM_1, - TDM_2, - TDM_3, - TDM_4, - TDM_5, - TDM_6, - TDM_7, - TDM_PORT_MAX, -}; - -enum { - TDM_PRI = 0, - TDM_SEC, - TDM_TERT, - TDM_QUAT, - TDM_INTERFACE_MAX, -}; - -struct tdm_port { - u32 mode; - u32 channel; -}; - -/* TDM default config */ -static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { - { /* PRI TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ - }, - { /* SEC TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ - }, - { /* TERT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ - }, - { /* QUAT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ - } -}; - -/* TDM default config */ -static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { - { /* PRI TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ - }, - { /* SEC TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ - }, - { /* TERT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ - }, - { /* QUAT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ - } -}; - - -/* Default configuration of slimbus channels */ -static struct dev_config slim_rx_cfg[] = { - [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, -}; - -static struct dev_config slim_tx_cfg[] = { - [SLIM_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, -}; - - -/* Default configuration of external display BE */ -static struct dev_config ext_disp_rx_cfg[] = { - [DP_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, -}; - -static struct dev_config usb_rx_cfg = { - .sample_rate = SAMPLING_RATE_48KHZ, - .bit_format = SNDRV_PCM_FORMAT_S16_LE, - .channels = 2, -}; - -static struct dev_config usb_tx_cfg = { - .sample_rate = SAMPLING_RATE_48KHZ, - .bit_format = SNDRV_PCM_FORMAT_S16_LE, - .channels = 1, -}; - -static struct dev_config proxy_rx_cfg = { - .sample_rate = SAMPLING_RATE_48KHZ, - .bit_format = SNDRV_PCM_FORMAT_S16_LE, - .channels = 2, -}; - -/* Default configuration of MI2S channels */ -static struct dev_config mi2s_rx_cfg[] = { - [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, - [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, - [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, - [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, -}; - -static struct dev_config mi2s_tx_cfg[] = { - [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, -}; - -static struct dev_config aux_pcm_rx_cfg[] = { - [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, -}; - -static struct dev_config aux_pcm_tx_cfg[] = { - [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, -}; - -static int msm_vi_feed_tx_ch = 2; -static const char *const slim_rx_ch_text[] = {"One", "Two"}; -static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", - "Eight"}; -static const char *const vi_feed_ch_text[] = {"One", "Two"}; -static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", - "S32_LE"}; -static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE", - "S24_3LE"}; -static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", - "KHZ_32", "KHZ_44P1", "KHZ_48", - "KHZ_88P2", "KHZ_96", "KHZ_176P4", - "KHZ_192", "KHZ_352P8", "KHZ_384"}; -static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", - "KHZ_44P1", "KHZ_48", - "KHZ_88P2", "KHZ_96"}; -static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", - "Eight"}; -static char const *ch_text[] = {"Two", "Three", "Four", "Five", - "Six", "Seven", "Eight"}; -static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", - "KHZ_16", "KHZ_22P05", - "KHZ_32", "KHZ_44P1", "KHZ_48", - "KHZ_88P2", "KHZ_96", "KHZ_176P4", - "KHZ_192", "KHZ_352P8", "KHZ_384"}; -static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96", - "KHZ_192", "KHZ_32", "KHZ_44P1", - "KHZ_88P2", "KHZ_176P4" }; -static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", "Eight"}; -static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; -static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", - "KHZ_48", "KHZ_176P4", - "KHZ_352P8"}; -static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; -static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_16", - "KHZ_22P05", "KHZ_32", "KHZ_44P1", - "KHZ_48", "KHZ_96", "KHZ_192"}; -static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", - "Eight"}; -static const char *const hifi_text[] = {"Off", "On"}; -static const char *const qos_text[] = {"Disable", "Enable"}; - -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_1_tx_chs, slim_tx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_chs, slim_rx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, - ext_disp_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); -static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(hifi_function, hifi_text); -static SOC_ENUM_SINGLE_EXT_DECL(qos_vote, qos_text); - -static struct platform_device *spdev; -static int msm_hifi_control; -static int qos_vote_status; - -static bool is_initial_boot; -static bool codec_reg_done; -static struct snd_soc_aux_dev *msm_aux_dev; -static struct snd_soc_codec_conf *msm_codec_conf; -static struct msm_asoc_wcd93xx_codec msm_codec_fn; - -static void *def_tavil_mbhc_cal(void); -static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, - int enable, bool dapm); -static int msm_wsa881x_init(struct snd_soc_component *component); - -/* - * Need to report LINEIN - * if R/L channel impedance is larger than 5K ohm - */ -static struct wcd_mbhc_config wcd_mbhc_cfg = { - .read_fw_bin = false, - .calibration = NULL, - .detect_extn_cable = true, - .mono_stero_detection = false, - .swap_gnd_mic = NULL, - .hs_ext_micbias = true, - .key_code[0] = KEY_MEDIA, - .key_code[1] = KEY_VOICECOMMAND, - .key_code[2] = KEY_VOLUMEUP, - .key_code[3] = KEY_VOLUMEDOWN, - .key_code[4] = 0, - .key_code[5] = 0, - .key_code[6] = 0, - .key_code[7] = 0, - .linein_th = 5000, - .moisture_en = true, - .mbhc_micbias = MIC_BIAS_2, - .anc_micbias = MIC_BIAS_2, - .enable_anc_mic_detect = false, -}; - -static struct snd_soc_dapm_route wcd_audio_paths[] = { - {"MIC BIAS1", NULL, "MCLK TX"}, - {"MIC BIAS2", NULL, "MCLK TX"}, - {"MIC BIAS3", NULL, "MCLK TX"}, - {"MIC BIAS4", NULL, "MCLK TX"}, -}; - -static struct afe_clk_set mi2s_clk[MI2S_MAX] = { - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - }, - { - AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, - Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, - Q6AFE_LPASS_CLK_ROOT_DEFAULT, - 0, - } -}; - -static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; - -static int slim_get_sample_rate_val(int sample_rate) -{ - int sample_rate_val = 0; - - switch (sample_rate) { - case SAMPLING_RATE_8KHZ: - sample_rate_val = 0; - break; - case SAMPLING_RATE_16KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_32KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 3; - break; - case SAMPLING_RATE_48KHZ: - sample_rate_val = 4; - break; - case SAMPLING_RATE_88P2KHZ: - sample_rate_val = 5; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 6; - break; - case SAMPLING_RATE_176P4KHZ: - sample_rate_val = 7; - break; - case SAMPLING_RATE_192KHZ: - sample_rate_val = 8; - break; - case SAMPLING_RATE_352P8KHZ: - sample_rate_val = 9; - break; - case SAMPLING_RATE_384KHZ: - sample_rate_val = 10; - break; - default: - sample_rate_val = 4; - break; - } - return sample_rate_val; -} - -static int slim_get_sample_rate(int value) -{ - int sample_rate = 0; - - switch (value) { - case 0: - sample_rate = SAMPLING_RATE_8KHZ; - break; - case 1: - sample_rate = SAMPLING_RATE_16KHZ; - break; - case 2: - sample_rate = SAMPLING_RATE_32KHZ; - break; - case 3: - sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 4: - sample_rate = SAMPLING_RATE_48KHZ; - break; - case 5: - sample_rate = SAMPLING_RATE_88P2KHZ; - break; - case 6: - sample_rate = SAMPLING_RATE_96KHZ; - break; - case 7: - sample_rate = SAMPLING_RATE_176P4KHZ; - break; - case 8: - sample_rate = SAMPLING_RATE_192KHZ; - break; - case 9: - sample_rate = SAMPLING_RATE_352P8KHZ; - break; - case 10: - sample_rate = SAMPLING_RATE_384KHZ; - break; - default: - sample_rate = SAMPLING_RATE_48KHZ; - break; - } - return sample_rate; -} - -static int slim_get_bit_format_val(int bit_format) -{ - int val = 0; - - switch (bit_format) { - case SNDRV_PCM_FORMAT_S32_LE: - val = 3; - break; - case SNDRV_PCM_FORMAT_S24_3LE: - val = 2; - break; - case SNDRV_PCM_FORMAT_S24_LE: - val = 1; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - val = 0; - break; - } - return val; -} - -static int slim_get_bit_format(int val) -{ - int bit_fmt = SNDRV_PCM_FORMAT_S16_LE; - - switch (val) { - case 0: - bit_fmt = SNDRV_PCM_FORMAT_S16_LE; - break; - case 1: - bit_fmt = SNDRV_PCM_FORMAT_S24_LE; - break; - case 2: - bit_fmt = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 3: - bit_fmt = SNDRV_PCM_FORMAT_S32_LE; - break; - default: - bit_fmt = SNDRV_PCM_FORMAT_S16_LE; - break; - } - return bit_fmt; -} - -static int slim_get_port_idx(struct snd_kcontrol *kcontrol) -{ - int port_id = 0; - - if (strnstr(kcontrol->id.name, "SLIM_0_RX", sizeof("SLIM_0_RX"))) - port_id = SLIM_RX_0; - else if (strnstr(kcontrol->id.name, "SLIM_2_RX", sizeof("SLIM_2_RX"))) - port_id = SLIM_RX_2; - else if (strnstr(kcontrol->id.name, "SLIM_5_RX", sizeof("SLIM_5_RX"))) - port_id = SLIM_RX_5; - else if (strnstr(kcontrol->id.name, "SLIM_6_RX", sizeof("SLIM_6_RX"))) - port_id = SLIM_RX_6; - else if (strnstr(kcontrol->id.name, "SLIM_0_TX", sizeof("SLIM_0_TX"))) - port_id = SLIM_TX_0; - else if (strnstr(kcontrol->id.name, "SLIM_1_TX", sizeof("SLIM_1_TX"))) - port_id = SLIM_TX_1; - else { - pr_err("%s: unsupported channel: %s", - __func__, kcontrol->id.name); - return -EINVAL; - } - - return port_id; -} - -static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - ucontrol->value.enumerated.item[0] = - slim_get_sample_rate_val(slim_rx_cfg[ch_num].sample_rate); - - pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, - ch_num, slim_rx_cfg[ch_num].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - slim_rx_cfg[ch_num].sample_rate = - slim_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, - ch_num, slim_rx_cfg[ch_num].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - ucontrol->value.enumerated.item[0] = - slim_get_sample_rate_val(slim_tx_cfg[ch_num].sample_rate); - - pr_debug("%s: slim[%d]_tx_sample_rate = %d, item = %d\n", __func__, - ch_num, slim_tx_cfg[ch_num].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate = 0; - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - sample_rate = slim_get_sample_rate(ucontrol->value.enumerated.item[0]); - if (sample_rate == SAMPLING_RATE_44P1KHZ) { - pr_err("%s: Unsupported sample rate %d: for Tx path\n", - __func__, sample_rate); - return -EINVAL; - } - slim_tx_cfg[ch_num].sample_rate = sample_rate; - - pr_debug("%s: slim[%d]_tx_sample_rate = %d, value = %d\n", __func__, - ch_num, slim_tx_cfg[ch_num].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_rx_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - ucontrol->value.enumerated.item[0] = - slim_get_bit_format_val(slim_rx_cfg[ch_num].bit_format); - - pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", - __func__, ch_num, slim_rx_cfg[ch_num].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_rx_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - slim_rx_cfg[ch_num].bit_format = - slim_get_bit_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", - __func__, ch_num, slim_rx_cfg[ch_num].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_tx_bit_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - ucontrol->value.enumerated.item[0] = - slim_get_bit_format_val(slim_tx_cfg[ch_num].bit_format); - - pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", - __func__, ch_num, slim_tx_cfg[ch_num].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int slim_tx_bit_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - slim_tx_cfg[ch_num].bit_format = - slim_get_bit_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", - __func__, ch_num, slim_tx_cfg[ch_num].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_slim_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, - ch_num, slim_rx_cfg[ch_num].channels); - ucontrol->value.enumerated.item[0] = slim_rx_cfg[ch_num].channels - 1; - - return 0; -} - -static int msm_slim_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - slim_rx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; - pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, - ch_num, slim_rx_cfg[ch_num].channels); - - return 1; -} - -static int msm_slim_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, - ch_num, slim_tx_cfg[ch_num].channels); - ucontrol->value.enumerated.item[0] = slim_tx_cfg[ch_num].channels - 1; - - return 0; -} - -static int msm_slim_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ch_num = slim_get_port_idx(kcontrol); - - if (ch_num < 0) - return ch_num; - - slim_tx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; - pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, - ch_num, slim_tx_cfg[ch_num].channels); - - return 1; -} - -static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1; - pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, - ucontrol->value.integer.value[0]); - return 0; -} - -static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1; - - pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch); - return 1; -} - -static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - /* - * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) - * when used for BT_SCO use case. Return either Rx or Tx sample rate - * value. - */ - switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { - case SAMPLING_RATE_96KHZ: - ucontrol->value.integer.value[0] = 5; - break; - case SAMPLING_RATE_88P2KHZ: - ucontrol->value.integer.value[0] = 4; - break; - case SAMPLING_RATE_48KHZ: - ucontrol->value.integer.value[0] = 3; - break; - case SAMPLING_RATE_44P1KHZ: - ucontrol->value.integer.value[0] = 2; - break; - case SAMPLING_RATE_16KHZ: - ucontrol->value.integer.value[0] = 1; - break; - case SAMPLING_RATE_8KHZ: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - pr_debug("%s: sample rate = %d", __func__, - slim_rx_cfg[SLIM_RX_7].sample_rate); - - return 0; -} - -static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 1: - slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; - slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; - break; - case 2: - slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ; - slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 3: - slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; - slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; - break; - case 4: - slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ; - slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ; - break; - case 5: - slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ; - slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ; - break; - case 0: - default: - slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; - slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; - break; - } - pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n", - __func__, - slim_rx_cfg[SLIM_RX_7].sample_rate, - slim_tx_cfg[SLIM_TX_7].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, - usb_rx_cfg.channels); - ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1; - return 0; -} - -static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1; - - pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels); - return 1; -} - -static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val; - - switch (usb_rx_cfg.sample_rate) { - case SAMPLING_RATE_384KHZ: - sample_rate_val = 12; - break; - case SAMPLING_RATE_352P8KHZ: - sample_rate_val = 11; - break; - case SAMPLING_RATE_192KHZ: - sample_rate_val = 10; - break; - case SAMPLING_RATE_176P4KHZ: - sample_rate_val = 9; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 8; - break; - case SAMPLING_RATE_88P2KHZ: - sample_rate_val = 7; - break; - case SAMPLING_RATE_48KHZ: - sample_rate_val = 6; - break; - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 5; - break; - case SAMPLING_RATE_32KHZ: - sample_rate_val = 4; - break; - case SAMPLING_RATE_22P05KHZ: - sample_rate_val = 3; - break; - case SAMPLING_RATE_16KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_11P025KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_8KHZ: - default: - sample_rate_val = 0; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__, - usb_rx_cfg.sample_rate); - return 0; -} - -static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 12: - usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ; - break; - case 11: - usb_rx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; - break; - case 10: - usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ; - break; - case 9: - usb_rx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; - break; - case 8: - usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ; - break; - case 7: - usb_rx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; - break; - case 6: - usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; - break; - case 5: - usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 4: - usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ; - break; - case 3: - usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; - break; - case 2: - usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ; - break; - case 1: - usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; - break; - case 0: - usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ; - break; - default: - usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; - break; - } - - pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n", - __func__, ucontrol->value.integer.value[0], - usb_rx_cfg.sample_rate); - return 0; -} - -static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (usb_rx_cfg.bit_format) { - case SNDRV_PCM_FORMAT_S32_LE: - ucontrol->value.integer.value[0] = 3; - break; - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", - __func__, usb_rx_cfg.bit_format, - ucontrol->value.integer.value[0]); - return 0; -} - -static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int rc = 0; - - switch (ucontrol->value.integer.value[0]) { - case 3: - usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; - break; - case 2: - usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", - __func__, usb_rx_cfg.bit_format, - ucontrol->value.integer.value[0]); - - return rc; -} - -static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, - usb_tx_cfg.channels); - ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1; - return 0; -} - -static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1; - - pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels); - return 1; -} - -static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val; - - switch (usb_tx_cfg.sample_rate) { - case SAMPLING_RATE_384KHZ: - sample_rate_val = 12; - break; - case SAMPLING_RATE_352P8KHZ: - sample_rate_val = 11; - break; - case SAMPLING_RATE_192KHZ: - sample_rate_val = 10; - break; - case SAMPLING_RATE_176P4KHZ: - sample_rate_val = 9; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 8; - break; - case SAMPLING_RATE_88P2KHZ: - sample_rate_val = 7; - break; - case SAMPLING_RATE_48KHZ: - sample_rate_val = 6; - break; - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 5; - break; - case SAMPLING_RATE_32KHZ: - sample_rate_val = 4; - break; - case SAMPLING_RATE_22P05KHZ: - sample_rate_val = 3; - break; - case SAMPLING_RATE_16KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_11P025KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_8KHZ: - sample_rate_val = 0; - break; - default: - sample_rate_val = 6; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__, - usb_tx_cfg.sample_rate); - return 0; -} - -static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (ucontrol->value.integer.value[0]) { - case 12: - usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ; - break; - case 11: - usb_tx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; - break; - case 10: - usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ; - break; - case 9: - usb_tx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; - break; - case 8: - usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ; - break; - case 7: - usb_tx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; - break; - case 6: - usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; - break; - case 5: - usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 4: - usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ; - break; - case 3: - usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; - break; - case 2: - usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ; - break; - case 1: - usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; - break; - case 0: - usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ; - break; - default: - usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; - break; - } - - pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n", - __func__, ucontrol->value.integer.value[0], - usb_tx_cfg.sample_rate); - return 0; -} - -static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - switch (usb_tx_cfg.bit_format) { - case SNDRV_PCM_FORMAT_S32_LE: - ucontrol->value.integer.value[0] = 3; - break; - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", - __func__, usb_tx_cfg.bit_format, - ucontrol->value.integer.value[0]); - return 0; -} - -static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int rc = 0; - - switch (ucontrol->value.integer.value[0]) { - case 3: - usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; - break; - case 2: - usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", - __func__, usb_tx_cfg.bit_format, - ucontrol->value.integer.value[0]); - - return rc; -} - -static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol) -{ - int idx; - - if (strnstr(kcontrol->id.name, "Display Port RX", - sizeof("Display Port RX"))) { - idx = DP_RX_IDX; - } else { - pr_err("%s: unsupported BE: %s", - __func__, kcontrol->id.name); - idx = -EINVAL; - } - - return idx; -} - -static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - switch (ext_disp_rx_cfg[idx].bit_format) { - case SNDRV_PCM_FORMAT_S24_3LE: - ucontrol->value.integer.value[0] = 2; - break; - case SNDRV_PCM_FORMAT_S24_LE: - ucontrol->value.integer.value[0] = 1; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - ucontrol->value.integer.value[0] = 0; - break; - } - - pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", - __func__, idx, ext_disp_rx_cfg[idx].bit_format, - ucontrol->value.integer.value[0]); - return 0; -} - -static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - switch (ucontrol->value.integer.value[0]) { - case 2: - ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 1: - ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 0: - default: - ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", - __func__, idx, ext_disp_rx_cfg[idx].bit_format, - ucontrol->value.integer.value[0]); - - return 0; -} - -static int ext_disp_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.integer.value[0] = - ext_disp_rx_cfg[idx].channels - 2; - - pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, - idx, ext_disp_rx_cfg[idx].channels); - - return 0; -} - -static int ext_disp_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ext_disp_rx_cfg[idx].channels = - ucontrol->value.integer.value[0] + 2; - - pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, - idx, ext_disp_rx_cfg[idx].channels); - return 1; -} - -static int ext_disp_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int sample_rate_val; - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - switch (ext_disp_rx_cfg[idx].sample_rate) { - case SAMPLING_RATE_176P4KHZ: - sample_rate_val = 6; - break; - - case SAMPLING_RATE_88P2KHZ: - sample_rate_val = 5; - break; - - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 4; - break; - - case SAMPLING_RATE_32KHZ: - sample_rate_val = 3; - break; - - case SAMPLING_RATE_192KHZ: - sample_rate_val = 2; - break; - - case SAMPLING_RATE_96KHZ: - sample_rate_val = 1; - break; - - case SAMPLING_RATE_48KHZ: - default: - sample_rate_val = 0; - break; - } - - ucontrol->value.integer.value[0] = sample_rate_val; - pr_debug("%s: ext_disp_rx[%d].sample_rate = %d\n", __func__, - idx, ext_disp_rx_cfg[idx].sample_rate); - - return 0; -} - -static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = ext_disp_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - switch (ucontrol->value.integer.value[0]) { - case 6: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_176P4KHZ; - break; - case 5: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_88P2KHZ; - break; - case 4: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 3: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_32KHZ; - break; - case 2: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ; - break; - case 1: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ; - break; - case 0: - default: - ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ; - break; - } - - pr_debug("%s: control value = %ld, ext_disp_rx[%d].sample_rate = %d\n", - __func__, ucontrol->value.integer.value[0], idx, - ext_disp_rx_cfg[idx].sample_rate); - return 0; -} - -static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: proxy_rx channels = %d\n", - __func__, proxy_rx_cfg.channels); - ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2; - - return 0; -} - -static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2; - pr_debug("%s: proxy_rx channels = %d\n", - __func__, proxy_rx_cfg.channels); - - return 1; -} - -static int tdm_get_sample_rate(int value) -{ - int sample_rate = 0; - - switch (value) { - case 0: - sample_rate = SAMPLING_RATE_8KHZ; - break; - case 1: - sample_rate = SAMPLING_RATE_16KHZ; - break; - case 2: - sample_rate = SAMPLING_RATE_32KHZ; - break; - case 3: - sample_rate = SAMPLING_RATE_48KHZ; - break; - case 4: - sample_rate = SAMPLING_RATE_176P4KHZ; - break; - case 5: - sample_rate = SAMPLING_RATE_352P8KHZ; - break; - default: - sample_rate = SAMPLING_RATE_48KHZ; - break; - } - return sample_rate; -} - -static int aux_pcm_get_sample_rate(int value) -{ - int sample_rate; - - switch (value) { - case 1: - sample_rate = SAMPLING_RATE_16KHZ; - break; - case 0: - default: - sample_rate = SAMPLING_RATE_8KHZ; - break; - } - return sample_rate; -} - -static int tdm_get_sample_rate_val(int sample_rate) -{ - int sample_rate_val = 0; - - switch (sample_rate) { - case SAMPLING_RATE_8KHZ: - sample_rate_val = 0; - break; - case SAMPLING_RATE_16KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_32KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_48KHZ: - sample_rate_val = 3; - break; - case SAMPLING_RATE_176P4KHZ: - sample_rate_val = 4; - break; - case SAMPLING_RATE_352P8KHZ: - sample_rate_val = 5; - break; - default: - sample_rate_val = 3; - break; - } - return sample_rate_val; -} - -static int aux_pcm_get_sample_rate_val(int sample_rate) -{ - int sample_rate_val; - - switch (sample_rate) { - case SAMPLING_RATE_16KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_8KHZ: - default: - sample_rate_val = 0; - break; - } - return sample_rate_val; -} - -static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, - struct tdm_port *port) -{ - if (port) { - if (strnstr(kcontrol->id.name, "PRI", - sizeof(kcontrol->id.name))) { - port->mode = TDM_PRI; - } else if (strnstr(kcontrol->id.name, "SEC", - sizeof(kcontrol->id.name))) { - port->mode = TDM_SEC; - } else if (strnstr(kcontrol->id.name, "TERT", - sizeof(kcontrol->id.name))) { - port->mode = TDM_TERT; - } else if (strnstr(kcontrol->id.name, "QUAT", - sizeof(kcontrol->id.name))) { - port->mode = TDM_QUAT; - } else { - pr_err("%s: unsupported mode in: %s", - __func__, kcontrol->id.name); - return -EINVAL; - } - - if (strnstr(kcontrol->id.name, "RX_0", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_0", - sizeof(kcontrol->id.name))) { - port->channel = TDM_0; - } else if (strnstr(kcontrol->id.name, "RX_1", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_1", - sizeof(kcontrol->id.name))) { - port->channel = TDM_1; - } else if (strnstr(kcontrol->id.name, "RX_2", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_2", - sizeof(kcontrol->id.name))) { - port->channel = TDM_2; - } else if (strnstr(kcontrol->id.name, "RX_3", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_3", - sizeof(kcontrol->id.name))) { - port->channel = TDM_3; - } else if (strnstr(kcontrol->id.name, "RX_4", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_4", - sizeof(kcontrol->id.name))) { - port->channel = TDM_4; - } else if (strnstr(kcontrol->id.name, "RX_5", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_5", - sizeof(kcontrol->id.name))) { - port->channel = TDM_5; - } else if (strnstr(kcontrol->id.name, "RX_6", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_6", - sizeof(kcontrol->id.name))) { - port->channel = TDM_6; - } else if (strnstr(kcontrol->id.name, "RX_7", - sizeof(kcontrol->id.name)) || - strnstr(kcontrol->id.name, "TX_7", - sizeof(kcontrol->id.name))) { - port->channel = TDM_7; - } else { - pr_err("%s: unsupported channel in: %s", - __func__, kcontrol->id.name); - return -EINVAL; - } - } else - return -EINVAL; - return 0; -} - -static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( - tdm_rx_cfg[port.mode][port.channel].sample_rate); - - pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].sample_rate, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_rx_cfg[port.mode][port.channel].sample_rate = - tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].sample_rate, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( - tdm_tx_cfg[port.mode][port.channel].sample_rate); - - pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].sample_rate, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_tx_cfg[port.mode][port.channel].sample_rate = - tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].sample_rate, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_get_format(int value) -{ - int format = 0; - - switch (value) { - case 0: - format = SNDRV_PCM_FORMAT_S16_LE; - break; - case 1: - format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 2: - format = SNDRV_PCM_FORMAT_S32_LE; - break; - default: - format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - return format; -} - -static int tdm_get_format_val(int format) -{ - int value = 0; - - switch (format) { - case SNDRV_PCM_FORMAT_S16_LE: - value = 0; - break; - case SNDRV_PCM_FORMAT_S24_LE: - value = 1; - break; - case SNDRV_PCM_FORMAT_S32_LE: - value = 2; - break; - default: - value = 0; - break; - } - return value; -} - -static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - ucontrol->value.enumerated.item[0] = tdm_get_format_val( - tdm_rx_cfg[port.mode][port.channel].bit_format); - - pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].bit_format, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_rx_cfg[port.mode][port.channel].bit_format = - tdm_get_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].bit_format, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - ucontrol->value.enumerated.item[0] = tdm_get_format_val( - tdm_tx_cfg[port.mode][port.channel].bit_format); - - pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].bit_format, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_tx_cfg[port.mode][port.channel].bit_format = - tdm_get_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].bit_format, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - - ucontrol->value.enumerated.item[0] = - tdm_rx_cfg[port.mode][port.channel].channels - 1; - - pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].channels - 1, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_rx_cfg[port.mode][port.channel].channels = - ucontrol->value.enumerated.item[0] + 1; - - pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, - tdm_rx_cfg[port.mode][port.channel].channels, - ucontrol->value.enumerated.item[0] + 1); - } - return ret; -} - -static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - ucontrol->value.enumerated.item[0] = - tdm_tx_cfg[port.mode][port.channel].channels - 1; - - pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].channels - 1, - ucontrol->value.enumerated.item[0]); - } - return ret; -} - -static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct tdm_port port; - int ret = tdm_get_port_idx(kcontrol, &port); - - if (ret) { - pr_err("%s: unsupported control: %s", - __func__, kcontrol->id.name); - } else { - tdm_tx_cfg[port.mode][port.channel].channels = - ucontrol->value.enumerated.item[0] + 1; - - pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, - tdm_tx_cfg[port.mode][port.channel].channels, - ucontrol->value.enumerated.item[0] + 1); - } - return ret; -} - -static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) -{ - int idx; - - if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", - sizeof("PRIM_AUX_PCM"))) - idx = PRIM_AUX_PCM; - else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM", - sizeof("SEC_AUX_PCM"))) - idx = SEC_AUX_PCM; - else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", - sizeof("TERT_AUX_PCM"))) - idx = TERT_AUX_PCM; - else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", - sizeof("QUAT_AUX_PCM"))) - idx = QUAT_AUX_PCM; - else { - pr_err("%s: unsupported port: %s", - __func__, kcontrol->id.name); - idx = -EINVAL; - } - - return idx; -} - -static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - aux_pcm_rx_cfg[idx].sample_rate = - aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, - idx, aux_pcm_rx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate); - - pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, - idx, aux_pcm_rx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - aux_pcm_tx_cfg[idx].sample_rate = - aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, - idx, aux_pcm_tx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate); - - pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, - idx, aux_pcm_tx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) -{ - int idx; - - if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX", - sizeof("PRIM_MI2S_RX"))) - idx = PRIM_MI2S; - else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX", - sizeof("SEC_MI2S_RX"))) - idx = SEC_MI2S; - else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", - sizeof("TERT_MI2S_RX"))) - idx = TERT_MI2S; - else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", - sizeof("QUAT_MI2S_RX"))) - idx = QUAT_MI2S; - else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", - sizeof("PRIM_MI2S_TX"))) - idx = PRIM_MI2S; - else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX", - sizeof("SEC_MI2S_TX"))) - idx = SEC_MI2S; - else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", - sizeof("TERT_MI2S_TX"))) - idx = TERT_MI2S; - else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", - sizeof("QUAT_MI2S_TX"))) - idx = QUAT_MI2S; - else { - pr_err("%s: unsupported channel: %s", - __func__, kcontrol->id.name); - idx = -EINVAL; - } - - return idx; -} - -static int mi2s_get_sample_rate_val(int sample_rate) -{ - int sample_rate_val; - - switch (sample_rate) { - case SAMPLING_RATE_8KHZ: - sample_rate_val = 0; - break; - case SAMPLING_RATE_11P025KHZ: - sample_rate_val = 1; - break; - case SAMPLING_RATE_16KHZ: - sample_rate_val = 2; - break; - case SAMPLING_RATE_22P05KHZ: - sample_rate_val = 3; - break; - case SAMPLING_RATE_32KHZ: - sample_rate_val = 4; - break; - case SAMPLING_RATE_44P1KHZ: - sample_rate_val = 5; - break; - case SAMPLING_RATE_48KHZ: - sample_rate_val = 6; - break; - case SAMPLING_RATE_96KHZ: - sample_rate_val = 7; - break; - case SAMPLING_RATE_192KHZ: - sample_rate_val = 8; - break; - default: - sample_rate_val = 6; - break; - } - return sample_rate_val; -} - -static int mi2s_get_sample_rate(int value) -{ - int sample_rate; - - switch (value) { - case 0: - sample_rate = SAMPLING_RATE_8KHZ; - break; - case 1: - sample_rate = SAMPLING_RATE_11P025KHZ; - break; - case 2: - sample_rate = SAMPLING_RATE_16KHZ; - break; - case 3: - sample_rate = SAMPLING_RATE_22P05KHZ; - break; - case 4: - sample_rate = SAMPLING_RATE_32KHZ; - break; - case 5: - sample_rate = SAMPLING_RATE_44P1KHZ; - break; - case 6: - sample_rate = SAMPLING_RATE_48KHZ; - break; - case 7: - sample_rate = SAMPLING_RATE_96KHZ; - break; - case 8: - sample_rate = SAMPLING_RATE_192KHZ; - break; - default: - sample_rate = SAMPLING_RATE_48KHZ; - break; - } - return sample_rate; -} - -static int mi2s_auxpcm_get_format(int value) -{ - int format; - - switch (value) { - case 0: - format = SNDRV_PCM_FORMAT_S16_LE; - break; - case 1: - format = SNDRV_PCM_FORMAT_S24_LE; - break; - case 2: - format = SNDRV_PCM_FORMAT_S24_3LE; - break; - case 3: - format = SNDRV_PCM_FORMAT_S32_LE; - break; - default: - format = SNDRV_PCM_FORMAT_S16_LE; - break; - } - return format; -} - -static int mi2s_auxpcm_get_format_value(int format) -{ - int value; - - switch (format) { - case SNDRV_PCM_FORMAT_S16_LE: - value = 0; - break; - case SNDRV_PCM_FORMAT_S24_LE: - value = 1; - break; - case SNDRV_PCM_FORMAT_S24_3LE: - value = 2; - break; - case SNDRV_PCM_FORMAT_S32_LE: - value = 3; - break; - default: - value = 0; - break; - } - return value; -} - -static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_rx_cfg[idx].sample_rate = - mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, - idx, mi2s_rx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate); - - pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, - idx, mi2s_rx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_tx_cfg[idx].sample_rate = - mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, - idx, mi2s_tx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate); - - pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, - idx, mi2s_tx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, - idx, mi2s_rx_cfg[idx].channels); - ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1; - - return 0; -} - -static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; - pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, - idx, mi2s_rx_cfg[idx].channels); - - return 1; -} - -static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, - idx, mi2s_tx_cfg[idx].channels); - ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1; - - return 0; -} - -static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; - pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, - idx, mi2s_tx_cfg[idx].channels); - - return 1; -} - -static int msm_mi2s_rx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - mi2s_auxpcm_get_format_value(mi2s_rx_cfg[idx].bit_format); - - pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, - idx, mi2s_rx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_rx_cfg[idx].bit_format = - mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, - idx, mi2s_rx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_mi2s_tx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - mi2s_auxpcm_get_format_value(mi2s_tx_cfg[idx].bit_format); - - pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, - idx, mi2s_tx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = mi2s_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - mi2s_tx_cfg[idx].bit_format = - mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, - idx, mi2s_tx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_aux_pcm_rx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - mi2s_auxpcm_get_format_value(aux_pcm_rx_cfg[idx].bit_format); - - pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, - idx, aux_pcm_rx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_aux_pcm_rx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - aux_pcm_rx_cfg[idx].bit_format = - mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, - idx, aux_pcm_rx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_aux_pcm_tx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - mi2s_auxpcm_get_format_value(aux_pcm_tx_cfg[idx].bit_format); - - pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, - idx, aux_pcm_tx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - aux_pcm_tx_cfg[idx].bit_format = - mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, - idx, aux_pcm_tx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int msm_hifi_ctrl(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct snd_soc_card *card = codec->component.card; - struct msm_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - - pr_debug("%s: msm_hifi_control = %d", __func__, - msm_hifi_control); - - if (!pdata || !pdata->hph_en1_gpio_p) { - pr_err("%s: hph_en1_gpio is invalid\n", __func__); - return -EINVAL; - } - if (msm_hifi_control == MSM_HIFI_ON) { - msm_cdc_pinctrl_select_active_state(pdata->hph_en1_gpio_p); - /* 5msec delay needed as per HW requirement */ - usleep_range(5000, 5010); - } else { - msm_cdc_pinctrl_select_sleep_state(pdata->hph_en1_gpio_p); - } - snd_soc_dapm_sync(dapm); - - return 0; -} - -static int msm_hifi_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: msm_hifi_control = %d\n", - __func__, msm_hifi_control); - ucontrol->value.integer.value[0] = msm_hifi_control; - - return 0; -} - -static int msm_hifi_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - - pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n", - __func__, ucontrol->value.integer.value[0]); - - msm_hifi_control = ucontrol->value.integer.value[0]; - msm_hifi_ctrl(codec); - - return 0; -} - -static int msm_qos_ctl_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.enumerated.item[0] = qos_vote_status; - - return 0; -} - -static int msm_qos_ctl_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct snd_soc_card *card = codec->component.card; - const char *be_name = MSM_DAILINK_NAME(LowLatency); - struct snd_soc_pcm_runtime *rtd; - struct snd_pcm_substream *substream; - s32 usecs; - - rtd = snd_soc_get_pcm_runtime(card, be_name); - if (!rtd) { - pr_err("%s: fail to get pcm runtime for %s\n", - __func__, be_name); - return -EINVAL; - } - - substream = rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; - if (!substream) { - pr_err("%s: substream is null\n", __func__); - return -EINVAL; - } - - qos_vote_status = ucontrol->value.enumerated.item[0]; - if (qos_vote_status) { - if (pm_qos_request_active(&substream->latency_pm_qos_req)) - pm_qos_remove_request(&substream->latency_pm_qos_req); - if (!substream->runtime) { - pr_err("%s: runtime is null\n", __func__); - return -EINVAL; - } - usecs = MSM_LL_QOS_VALUE; - if (usecs >= 0) - pm_qos_add_request(&substream->latency_pm_qos_req, - PM_QOS_CPU_DMA_LATENCY, usecs); - } else { - if (pm_qos_request_active(&substream->latency_pm_qos_req)) - pm_qos_remove_request(&substream->latency_pm_qos_req); - } - - return 0; -} - -static const struct snd_kcontrol_new msm_snd_controls[] = { - SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, - msm_slim_rx_ch_get, msm_slim_rx_ch_put), - SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs, - msm_slim_rx_ch_get, msm_slim_rx_ch_put), - SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs, - msm_slim_tx_ch_get, msm_slim_tx_ch_put), - SOC_ENUM_EXT("SLIM_1_TX Channels", slim_1_tx_chs, - msm_slim_tx_ch_get, msm_slim_tx_ch_put), - SOC_ENUM_EXT("SLIM_5_RX Channels", slim_5_rx_chs, - msm_slim_rx_ch_get, msm_slim_rx_ch_put), - SOC_ENUM_EXT("SLIM_6_RX Channels", slim_6_rx_chs, - msm_slim_rx_ch_get, msm_slim_rx_ch_put), - SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, - msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), - SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, - usb_audio_rx_ch_get, usb_audio_rx_ch_put), - SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, - usb_audio_tx_ch_get, usb_audio_tx_ch_put), - SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, - ext_disp_rx_ch_get, ext_disp_rx_ch_put), - SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, - proxy_rx_ch_get, proxy_rx_ch_put), - SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format, - slim_rx_bit_format_get, slim_rx_bit_format_put), - SOC_ENUM_EXT("SLIM_5_RX Format", slim_5_rx_format, - slim_rx_bit_format_get, slim_rx_bit_format_put), - SOC_ENUM_EXT("SLIM_6_RX Format", slim_6_rx_format, - slim_rx_bit_format_get, slim_rx_bit_format_put), - SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format, - slim_tx_bit_format_get, slim_tx_bit_format_put), - SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, - usb_audio_rx_format_get, usb_audio_rx_format_put), - SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, - usb_audio_tx_format_get, usb_audio_tx_format_put), - SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, - ext_disp_rx_format_get, ext_disp_rx_format_put), - SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate, - slim_rx_sample_rate_get, slim_rx_sample_rate_put), - SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate, - slim_rx_sample_rate_get, slim_rx_sample_rate_put), - SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate, - slim_tx_sample_rate_get, slim_tx_sample_rate_put), - SOC_ENUM_EXT("SLIM_5_RX SampleRate", slim_5_rx_sample_rate, - slim_rx_sample_rate_get, slim_rx_sample_rate_put), - SOC_ENUM_EXT("SLIM_6_RX SampleRate", slim_6_rx_sample_rate, - slim_rx_sample_rate_get, slim_rx_sample_rate_put), - SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, - msm_bt_sample_rate_get, - msm_bt_sample_rate_put), - SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, - usb_audio_rx_sample_rate_get, - usb_audio_rx_sample_rate_put), - SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, - usb_audio_tx_sample_rate_get, - usb_audio_tx_sample_rate_put), - SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, - ext_disp_rx_sample_rate_get, - ext_disp_rx_sample_rate_put), - SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, - tdm_rx_sample_rate_get, - tdm_rx_sample_rate_put), - SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, - tdm_tx_sample_rate_get, - tdm_tx_sample_rate_put), - SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, - tdm_rx_sample_rate_get, - tdm_rx_sample_rate_put), - SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, - tdm_tx_sample_rate_get, - tdm_tx_sample_rate_put), - SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, - tdm_rx_sample_rate_get, - tdm_rx_sample_rate_put), - SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, - tdm_tx_sample_rate_get, - tdm_tx_sample_rate_put), - SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, - tdm_rx_sample_rate_get, - tdm_rx_sample_rate_put), - SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, - tdm_tx_sample_rate_get, - tdm_tx_sample_rate_put), - SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, - mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate, - mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, - mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, - mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, - mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, - mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, - mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, - mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, - msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), - SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, - msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, - msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), - SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, - msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, - msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), - SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, - msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs, - msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), - SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, - msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, - msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), - SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, - msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), - SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format, - msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), - SOC_ENUM_EXT("SEC_MI2S_TX Format", mi2s_tx_format, - msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), - SOC_ENUM_EXT("TERT_MI2S_RX Format", mi2s_rx_format, - msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), - SOC_ENUM_EXT("TERT_MI2S_TX Format", mi2s_tx_format, - msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), - SOC_ENUM_EXT("QUAT_MI2S_RX Format", mi2s_rx_format, - msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), - SOC_ENUM_EXT("QUAT_MI2S_TX Format", mi2s_tx_format, - msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("QUAT_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("QUAT_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get, - msm_hifi_put), - SOC_ENUM_EXT("MultiMedia5_RX QOS Vote", qos_vote, msm_qos_ctl_get, - msm_qos_ctl_put), -}; - -static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, - int enable, bool dapm) -{ - int ret = 0; - - if (!strcmp(dev_name(codec->dev), "tavil_codec")) { - ret = tavil_cdc_mclk_enable(codec, enable); - } else { - dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", - __func__); - ret = -EINVAL; - } - return ret; -} - -static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, - int enable, bool dapm) -{ - int ret = 0; - - if (!strcmp(dev_name(codec->dev), "tavil_codec")) { - ret = tavil_cdc_mclk_tx_enable(codec, enable); - } else { - dev_err(codec->dev, "%s: unknown codec to enable TX ext clk\n", - __func__); - ret = -EINVAL; - } - - return ret; -} - -static int msm_mclk_tx_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - pr_debug("%s: event = %d\n", __func__, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - return msm_snd_enable_codec_ext_tx_clk(codec, 1, true); - case SND_SOC_DAPM_POST_PMD: - return msm_snd_enable_codec_ext_tx_clk(codec, 0, true); - } - return 0; -} - -static int msm_mclk_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - pr_debug("%s: event = %d\n", __func__, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - return msm_snd_enable_codec_ext_clk(codec, 1, true); - case SND_SOC_DAPM_POST_PMD: - return msm_snd_enable_codec_ext_clk(codec, 0, true); - } - return 0; -} - -static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct snd_soc_card *card = codec->component.card; - struct msm_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - - pr_debug("%s: msm_hifi_control = %d", __func__, msm_hifi_control); - - if (!pdata || !pdata->hph_en0_gpio_p) { - pr_err("%s: hph_en0_gpio is invalid\n", __func__); - return -EINVAL; - } - - if (msm_hifi_control != MSM_HIFI_ON) { - pr_debug("%s: HiFi mixer control is not set\n", - __func__); - return 0; - } - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - msm_cdc_pinctrl_select_active_state(pdata->hph_en0_gpio_p); - break; - case SND_SOC_DAPM_PRE_PMD: - msm_cdc_pinctrl_select_sleep_state(pdata->hph_en0_gpio_p); - break; - } - - return 0; -} - -static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { - - SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, - msm_mclk_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0, - msm_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SPK("Lineout_1 amp", NULL), - SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), - SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event), - SND_SOC_DAPM_MIC("Handset Mic", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), - SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL), - SND_SOC_DAPM_MIC("Analog Mic5", NULL), - - SND_SOC_DAPM_MIC("Digital Mic0", NULL), - SND_SOC_DAPM_MIC("Digital Mic1", NULL), - SND_SOC_DAPM_MIC("Digital Mic2", NULL), - SND_SOC_DAPM_MIC("Digital Mic3", NULL), - SND_SOC_DAPM_MIC("Digital Mic4", NULL), - SND_SOC_DAPM_MIC("Digital Mic5", NULL), -}; - -static inline int param_is_mask(int p) -{ - return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && - (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); -} - -static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, - int n) -{ - return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); -} - -static void param_set_mask(struct snd_pcm_hw_params *p, int n, - unsigned int bit) -{ - if (bit >= SNDRV_MASK_MAX) - return; - if (param_is_mask(n)) { - struct snd_mask *m = param_to_mask(p, n); - - m->bits[0] = 0; - m->bits[1] = 0; - m->bits[bit >> 5] |= (1 << (bit & 31)); - } -} - -static int msm_slim_get_ch_from_beid(int32_t be_id) -{ - int ch_id = 0; - - switch (be_id) { - case MSM_BACKEND_DAI_SLIMBUS_0_RX: - ch_id = SLIM_RX_0; - break; - case MSM_BACKEND_DAI_SLIMBUS_1_RX: - ch_id = SLIM_RX_1; - break; - case MSM_BACKEND_DAI_SLIMBUS_2_RX: - ch_id = SLIM_RX_2; - break; - case MSM_BACKEND_DAI_SLIMBUS_3_RX: - ch_id = SLIM_RX_3; - break; - case MSM_BACKEND_DAI_SLIMBUS_4_RX: - ch_id = SLIM_RX_4; - break; - case MSM_BACKEND_DAI_SLIMBUS_6_RX: - ch_id = SLIM_RX_6; - break; - case MSM_BACKEND_DAI_SLIMBUS_0_TX: - ch_id = SLIM_TX_0; - break; - case MSM_BACKEND_DAI_SLIMBUS_3_TX: - ch_id = SLIM_TX_3; - break; - default: - ch_id = SLIM_RX_0; - break; - } - - return ch_id; -} - -static int msm_ext_disp_get_idx_from_beid(int32_t be_id) -{ - int idx; - - switch (be_id) { - case MSM_BACKEND_DAI_DISPLAY_PORT_RX: - idx = DP_RX_IDX; - break; - default: - pr_err("%s: Incorrect ext_disp BE id %d\n", __func__, be_id); - idx = -EINVAL; - break; - } - - return idx; -} - -static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_dai_link *dai_link = rtd->dai_link; - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - int rc = 0; - int idx; - void *config = NULL; - struct snd_soc_codec *codec = NULL; - - pr_debug("%s: format = %d, rate = %d\n", - __func__, params_format(params), params_rate(params)); - - switch (dai_link->id) { - case MSM_BACKEND_DAI_SLIMBUS_0_RX: - case MSM_BACKEND_DAI_SLIMBUS_1_RX: - case MSM_BACKEND_DAI_SLIMBUS_2_RX: - case MSM_BACKEND_DAI_SLIMBUS_3_RX: - case MSM_BACKEND_DAI_SLIMBUS_4_RX: - case MSM_BACKEND_DAI_SLIMBUS_6_RX: - idx = msm_slim_get_ch_from_beid(dai_link->id); - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_rx_cfg[idx].bit_format); - rate->min = rate->max = slim_rx_cfg[idx].sample_rate; - channels->min = channels->max = slim_rx_cfg[idx].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_0_TX: - case MSM_BACKEND_DAI_SLIMBUS_3_TX: - idx = msm_slim_get_ch_from_beid(dai_link->id); - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_tx_cfg[idx].bit_format); - rate->min = rate->max = slim_tx_cfg[idx].sample_rate; - channels->min = channels->max = slim_tx_cfg[idx].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_1_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_tx_cfg[1].bit_format); - rate->min = rate->max = slim_tx_cfg[1].sample_rate; - channels->min = channels->max = slim_tx_cfg[1].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_4_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - SNDRV_PCM_FORMAT_S32_LE); - rate->min = rate->max = SAMPLING_RATE_8KHZ; - channels->min = channels->max = msm_vi_feed_tx_ch; - break; - - case MSM_BACKEND_DAI_SLIMBUS_5_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_rx_cfg[5].bit_format); - rate->min = rate->max = slim_rx_cfg[5].sample_rate; - channels->min = channels->max = slim_rx_cfg[5].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_5_TX: - codec = rtd->codec; - rate->min = rate->max = SAMPLING_RATE_16KHZ; - channels->min = channels->max = 1; - - config = msm_codec_fn.get_afe_config_fn(codec, - AFE_SLIMBUS_SLAVE_PORT_CONFIG); - if (config) { - rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, - config, SLIMBUS_5_TX); - if (rc) - pr_err("%s: Failed to set slimbus slave port config %d\n", - __func__, rc); - } - break; - - case MSM_BACKEND_DAI_SLIMBUS_7_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - slim_rx_cfg[SLIM_RX_7].bit_format); - rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate; - channels->min = channels->max = - slim_rx_cfg[SLIM_RX_7].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_7_TX: - rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate; - channels->min = channels->max = - slim_tx_cfg[SLIM_TX_7].channels; - break; - - case MSM_BACKEND_DAI_SLIMBUS_8_TX: - rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate; - channels->min = channels->max = - slim_tx_cfg[SLIM_TX_8].channels; - break; - - case MSM_BACKEND_DAI_USB_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - usb_rx_cfg.bit_format); - rate->min = rate->max = usb_rx_cfg.sample_rate; - channels->min = channels->max = usb_rx_cfg.channels; - break; - - case MSM_BACKEND_DAI_USB_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - usb_tx_cfg.bit_format); - rate->min = rate->max = usb_tx_cfg.sample_rate; - channels->min = channels->max = usb_tx_cfg.channels; - break; - - case MSM_BACKEND_DAI_DISPLAY_PORT_RX: - idx = msm_ext_disp_get_idx_from_beid(dai_link->id); - if (idx < 0) { - pr_err("%s: Incorrect ext disp idx %d\n", - __func__, idx); - rc = idx; - goto done; - } - - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - ext_disp_rx_cfg[idx].bit_format); - rate->min = rate->max = ext_disp_rx_cfg[idx].sample_rate; - channels->min = channels->max = ext_disp_rx_cfg[idx].channels; - break; - - case MSM_BACKEND_DAI_AFE_PCM_RX: - channels->min = channels->max = proxy_rx_cfg.channels; - rate->min = rate->max = SAMPLING_RATE_48KHZ; - break; - - case MSM_BACKEND_DAI_PRI_TDM_RX_0: - channels->min = channels->max = - tdm_rx_cfg[TDM_PRI][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_PRI_TDM_TX_0: - channels->min = channels->max = - tdm_tx_cfg[TDM_PRI][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); - rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_SEC_TDM_RX_0: - channels->min = channels->max = - tdm_rx_cfg[TDM_SEC][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_SEC_TDM_TX_0: - channels->min = channels->max = - tdm_tx_cfg[TDM_SEC][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); - rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_TERT_TDM_RX_0: - channels->min = channels->max = - tdm_rx_cfg[TDM_TERT][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_TERT_TDM_TX_0: - channels->min = channels->max = - tdm_tx_cfg[TDM_TERT][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); - rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_QUAT_TDM_RX_0: - channels->min = channels->max = - tdm_rx_cfg[TDM_QUAT][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_QUAT_TDM_TX_0: - channels->min = channels->max = - tdm_tx_cfg[TDM_QUAT][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); - rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; - break; - - case MSM_BACKEND_DAI_AUXPCM_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format); - rate->min = rate->max = - aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_rx_cfg[PRIM_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_AUXPCM_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - aux_pcm_tx_cfg[PRIM_AUX_PCM].bit_format); - rate->min = rate->max = - aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_tx_cfg[PRIM_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_SEC_AUXPCM_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - aux_pcm_rx_cfg[SEC_AUX_PCM].bit_format); - rate->min = rate->max = - aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_rx_cfg[SEC_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_SEC_AUXPCM_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - aux_pcm_tx_cfg[SEC_AUX_PCM].bit_format); - rate->min = rate->max = - aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_tx_cfg[SEC_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_TERT_AUXPCM_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - aux_pcm_rx_cfg[TERT_AUX_PCM].bit_format); - rate->min = rate->max = - aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_rx_cfg[TERT_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_TERT_AUXPCM_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - aux_pcm_tx_cfg[TERT_AUX_PCM].bit_format); - rate->min = rate->max = - aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_tx_cfg[TERT_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_QUAT_AUXPCM_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - aux_pcm_rx_cfg[QUAT_AUX_PCM].bit_format); - rate->min = rate->max = - aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_rx_cfg[QUAT_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_QUAT_AUXPCM_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - aux_pcm_tx_cfg[QUAT_AUX_PCM].bit_format); - rate->min = rate->max = - aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_tx_cfg[QUAT_AUX_PCM].channels; - break; - - case MSM_BACKEND_DAI_PRI_MI2S_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_rx_cfg[PRIM_MI2S].bit_format); - rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate; - channels->min = channels->max = - mi2s_rx_cfg[PRIM_MI2S].channels; - break; - - case MSM_BACKEND_DAI_PRI_MI2S_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_tx_cfg[PRIM_MI2S].bit_format); - rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate; - channels->min = channels->max = - mi2s_tx_cfg[PRIM_MI2S].channels; - break; - - case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_rx_cfg[SEC_MI2S].bit_format); - rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate; - channels->min = channels->max = - mi2s_rx_cfg[SEC_MI2S].channels; - break; - - case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_tx_cfg[SEC_MI2S].bit_format); - rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate; - channels->min = channels->max = - mi2s_tx_cfg[SEC_MI2S].channels; - break; - - case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_rx_cfg[TERT_MI2S].bit_format); - rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate; - channels->min = channels->max = - mi2s_rx_cfg[TERT_MI2S].channels; - break; - - case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_tx_cfg[TERT_MI2S].bit_format); - rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate; - channels->min = channels->max = - mi2s_tx_cfg[TERT_MI2S].channels; - break; - - case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_rx_cfg[QUAT_MI2S].bit_format); - rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate; - channels->min = channels->max = - mi2s_rx_cfg[QUAT_MI2S].channels; - break; - - case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - mi2s_tx_cfg[QUAT_MI2S].bit_format); - rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate; - channels->min = channels->max = - mi2s_tx_cfg[QUAT_MI2S].channels; - break; - - default: - rate->min = rate->max = SAMPLING_RATE_48KHZ; - break; - } - -done: - return rc; -} - -static bool msm_usbc_swap_gnd_mic(struct snd_soc_codec *codec, bool active) -{ - int value = 0; - bool ret = 0; - struct snd_soc_card *card = codec->component.card; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct pinctrl_state *en2_pinctrl_active; - struct pinctrl_state *en2_pinctrl_sleep; - - if (!pdata->usbc_en2_gpio_p) { - if (active) { - /* if active and usbc_en2_gpio undefined, get pin */ - pdata->usbc_en2_gpio_p = devm_pinctrl_get(card->dev); - if (IS_ERR_OR_NULL(pdata->usbc_en2_gpio_p)) { - dev_err(card->dev, - "%s: Can't get EN2 gpio pinctrl:%ld\n", - __func__, - PTR_ERR(pdata->usbc_en2_gpio_p)); - pdata->usbc_en2_gpio_p = NULL; - return false; - } - } else - /* if not active and usbc_en2_gpio undefined, return */ - return false; - } - - pdata->usbc_en2_gpio = of_get_named_gpio(card->dev->of_node, - "qcom,usbc-analog-en2-gpio", 0); - if (!gpio_is_valid(pdata->usbc_en2_gpio)) { - dev_err(card->dev, "%s, property %s not in node %s", - __func__, "qcom,usbc-analog-en2-gpio", - card->dev->of_node->full_name); - return false; - } - - en2_pinctrl_active = pinctrl_lookup_state( - pdata->usbc_en2_gpio_p, "aud_active"); - if (IS_ERR_OR_NULL(en2_pinctrl_active)) { - dev_err(card->dev, - "%s: Cannot get aud_active pinctrl state:%ld\n", - __func__, PTR_ERR(en2_pinctrl_active)); - ret = false; - goto err_lookup_state; - } - - en2_pinctrl_sleep = pinctrl_lookup_state( - pdata->usbc_en2_gpio_p, "aud_sleep"); - if (IS_ERR_OR_NULL(en2_pinctrl_sleep)) { - dev_err(card->dev, - "%s: Cannot get aud_sleep pinctrl state:%ld\n", - __func__, PTR_ERR(en2_pinctrl_sleep)); - ret = false; - goto err_lookup_state; - } - - /* if active and usbc_en2_gpio_p defined, swap using usbc_en2_gpio_p */ - if (active) { - dev_dbg(codec->dev, "%s: enter\n", __func__); - if (pdata->usbc_en2_gpio_p) { - value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); - if (value) - pinctrl_select_state(pdata->usbc_en2_gpio_p, - en2_pinctrl_sleep); - else - pinctrl_select_state(pdata->usbc_en2_gpio_p, - en2_pinctrl_active); - } else if (pdata->usbc_en2_gpio >= 0) { - value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); - gpio_set_value_cansleep(pdata->usbc_en2_gpio, !value); - } - pr_debug("%s: swap select switch %d to %d\n", __func__, - value, !value); - ret = true; - } else { - /* if not active, release usbc_en2_gpio_p pin */ - pinctrl_select_state(pdata->usbc_en2_gpio_p, - en2_pinctrl_sleep); - } - -err_lookup_state: - devm_pinctrl_put(pdata->usbc_en2_gpio_p); - pdata->usbc_en2_gpio_p = NULL; - return ret; -} - -static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) -{ - int value = 0; - int ret = 0; - struct snd_soc_card *card = codec->component.card; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - - if (!pdata) - return false; - - if (!wcd_mbhc_cfg.enable_usbc_analog) { - /* if usbc is not defined, swap using us_euro_gpio_p */ - if (pdata->us_euro_gpio_p) { - value = msm_cdc_pinctrl_get_state( - pdata->us_euro_gpio_p); - if (value) - msm_cdc_pinctrl_select_sleep_state( - pdata->us_euro_gpio_p); - else - msm_cdc_pinctrl_select_active_state( - pdata->us_euro_gpio_p); - } else if (pdata->us_euro_gpio >= 0) { - value = gpio_get_value_cansleep( - pdata->us_euro_gpio); - gpio_set_value_cansleep( - pdata->us_euro_gpio, !value); - } - pr_debug("%s: swap select switch %d to %d\n", __func__, - value, !value); - ret = true; - } else { - /* if usbc is defined, swap using usbc_en2 */ - ret = msm_usbc_swap_gnd_mic(codec, active); - } - return ret; -} - -static int msm_afe_set_config(struct snd_soc_codec *codec) -{ - int ret = 0; - void *config_data = NULL; - - if (!msm_codec_fn.get_afe_config_fn) { - dev_err(codec->dev, "%s: codec get afe config not init'ed\n", - __func__); - return -EINVAL; - } - - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_CDC_REGISTERS_CONFIG); - if (config_data) { - ret = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0); - if (ret) { - dev_err(codec->dev, - "%s: Failed to set codec registers config %d\n", - __func__, ret); - return ret; - } - } - - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_CDC_REGISTER_PAGE_CONFIG); - if (config_data) { - ret = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, - 0); - if (ret) - dev_err(codec->dev, - "%s: Failed to set cdc register page config\n", - __func__); - } - - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_SLIMBUS_SLAVE_CONFIG); - if (config_data) { - ret = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0); - if (ret) { - dev_err(codec->dev, - "%s: Failed to set slimbus slave config %d\n", - __func__, ret); - return ret; - } - } - - return 0; -} - -static void msm_afe_clear_config(void) -{ - afe_clear_config(AFE_CDC_REGISTERS_CONFIG); - afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); -} - -static int msm_adsp_power_up_config(struct snd_soc_codec *codec, - struct snd_card *card) -{ - int ret = 0; - unsigned long timeout; - int adsp_ready = 0; - bool snd_card_online = 0; - - timeout = jiffies + - msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); - - do { - if (!snd_card_online) { - snd_card_online = snd_card_is_online_state(card); - pr_debug("%s: Sound card is %s\n", __func__, - snd_card_online ? "Online" : "Offline"); - } - if (!adsp_ready) { - adsp_ready = q6core_is_adsp_ready(); - pr_debug("%s: ADSP Audio is %s\n", __func__, - adsp_ready ? "ready" : "not ready"); - } - if (snd_card_online && adsp_ready) - break; - - /* - * Sound card/ADSP will be coming up after subsystem restart and - * it might not be fully up when the control reaches - * here. So, wait for 50msec before checking ADSP state - */ - msleep(50); - } while (time_after(timeout, jiffies)); - - if (!snd_card_online || !adsp_ready) { - pr_err("%s: Timeout. Sound card is %s, ADSP Audio is %s\n", - __func__, - snd_card_online ? "Online" : "Offline", - adsp_ready ? "ready" : "not ready"); - ret = -ETIMEDOUT; - goto err; - } - - ret = msm_afe_set_config(codec); - if (ret) - pr_err("%s: Failed to set AFE config. err %d\n", - __func__, ret); - - return 0; - -err: - return ret; -} - -static int sdm845_notifier_service_cb(struct notifier_block *this, - unsigned long opcode, void *ptr) -{ - int ret; - struct snd_soc_card *card = NULL; - const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; - struct snd_soc_pcm_runtime *rtd; - struct snd_soc_codec *codec; - - pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); - - switch (opcode) { - case AUDIO_NOTIFIER_SERVICE_DOWN: - /* - * Use flag to ignore initial boot notifications - * On initial boot msm_adsp_power_up_config is - * called on init. There is no need to clear - * and set the config again on initial boot. - */ - if (is_initial_boot) - break; - msm_afe_clear_config(); - break; - case AUDIO_NOTIFIER_SERVICE_UP: - if (is_initial_boot) { - is_initial_boot = false; - break; - } - if (!spdev) - return -EINVAL; - - card = platform_get_drvdata(spdev); - rtd = snd_soc_get_pcm_runtime(card, be_dl_name); - if (!rtd) { - dev_err(card->dev, - "%s: snd_soc_get_pcm_runtime for %s failed!\n", - __func__, be_dl_name); - ret = -EINVAL; - goto err; - } - codec = rtd->codec; - - ret = msm_adsp_power_up_config(codec, card->snd_card); - if (ret < 0) { - dev_err(card->dev, - "%s: msm_adsp_power_up_config failed ret = %d!\n", - __func__, ret); - goto err; - } - break; - default: - break; - } -err: - return NOTIFY_OK; -} - -static struct notifier_block service_nb = { - .notifier_call = sdm845_notifier_service_cb, - .priority = -INT_MAX, -}; - -static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret = 0; - void *config_data; - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_component *aux_comp; - struct snd_card *card; - struct snd_info_entry *entry; - struct msm_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(rtd->card); - - /* Codec SLIMBUS configuration - * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8 - * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 - * TX14, TX15, TX16 - */ - unsigned int rx_ch[WCD934X_RX_MAX] = {144, 145, 146, 147, 148, 149, - 150, 151}; - unsigned int tx_ch[WCD934X_TX_MAX] = {128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143}; - - pr_info("%s: dev_name%s\n", __func__, dev_name(cpu_dai->dev)); - - rtd->pmdown_time = 0; - - ret = snd_soc_add_codec_controls(codec, msm_snd_controls, - ARRAY_SIZE(msm_snd_controls)); - if (ret < 0) { - pr_err("%s: add_codec_controls failed, err %d\n", - __func__, ret); - return ret; - } - - snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, - ARRAY_SIZE(msm_dapm_widgets)); - - snd_soc_dapm_add_routes(dapm, wcd_audio_paths, - ARRAY_SIZE(wcd_audio_paths)); - - snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic5"); - snd_soc_dapm_ignore_suspend(dapm, "MADINPUT"); - snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT"); - snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT1"); - snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT2"); - snd_soc_dapm_ignore_suspend(dapm, "EAR"); - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1"); - snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2"); - snd_soc_dapm_ignore_suspend(dapm, "ANC EAR"); - snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); - snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); - snd_soc_dapm_ignore_suspend(dapm, "HPHL"); - snd_soc_dapm_ignore_suspend(dapm, "HPHR"); - snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); - snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); - snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL"); - snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR"); - - snd_soc_dapm_sync(dapm); - - snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), - tx_ch, ARRAY_SIZE(rx_ch), rx_ch); - - msm_codec_fn.get_afe_config_fn = tavil_get_afe_config; - - ret = msm_adsp_power_up_config(codec, rtd->card->snd_card); - if (ret) { - pr_err("%s: Failed to set AFE config %d\n", __func__, ret); - goto err; - } - - config_data = msm_codec_fn.get_afe_config_fn(codec, - AFE_AANC_VERSION); - if (config_data) { - ret = afe_set_config(AFE_AANC_VERSION, config_data, 0); - if (ret) { - pr_err("%s: Failed to set aanc version %d\n", - __func__, ret); - goto err; - } - } - - /* - * Send speaker configuration only for WSA8810. - * Default configuration is for WSA8815. - */ - pr_debug("%s: Number of aux devices: %d\n", - __func__, rtd->card->num_aux_devs); - if (rtd->card->num_aux_devs && - !list_empty(&rtd->card->aux_comp_list)) { - aux_comp = list_first_entry(&rtd->card->aux_comp_list, - struct snd_soc_component, list_aux); - if (!strcmp(aux_comp->name, WSA8810_NAME_1) || - !strcmp(aux_comp->name, WSA8810_NAME_2)) { - tavil_set_spkr_mode(rtd->codec, WCD934X_SPKR_MODE_1); - tavil_set_spkr_gain_offset(rtd->codec, - WCD934X_RX_GAIN_OFFSET_M1P5_DB); - } - } - card = rtd->card->snd_card; - entry = snd_info_create_subdir(card->module, "codecs", - card->proc_root); - if (!entry) { - pr_debug("%s: Cannot create codecs module entry\n", - __func__); - pdata->codec_root = NULL; - goto done; - } - pdata->codec_root = entry; - tavil_codec_info_create_codec_entry(pdata->codec_root, codec); - -done: - codec_reg_done = true; - return 0; - -err: - return ret; -} - -static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) -{ - unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; - unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - - return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), - tx_ch, ARRAY_SIZE(rx_ch), rx_ch); -} - -static void *def_tavil_mbhc_cal(void) -{ - void *tavil_wcd_cal; - struct wcd_mbhc_btn_detect_cfg *btn_cfg; - u16 *btn_high; - - tavil_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, - WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); - if (!tavil_wcd_cal) - return NULL; - -#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(tavil_wcd_cal)->X) = (Y)) - S(v_hs_max, 1600); -#undef S -#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal)->X) = (Y)) - S(num_btn, WCD_MBHC_DEF_BUTTONS); -#undef S - - btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal); - btn_high = ((void *)&btn_cfg->_v_btn_low) + - (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); - - btn_high[0] = 75; - btn_high[1] = 150; - btn_high[2] = 237; - btn_high[3] = 500; - btn_high[4] = 500; - btn_high[5] = 500; - btn_high[6] = 500; - btn_high[7] = 500; - - return tavil_wcd_cal; -} - -static int msm_snd_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai_link *dai_link = rtd->dai_link; - - int ret = 0; - u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; - u32 rx_ch_cnt = 0, tx_ch_cnt = 0; - u32 user_set_tx_ch = 0; - u32 rx_ch_count; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map, err:%d\n", - __func__, ret); - goto err; - } - if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_5_RX) { - pr_debug("%s: rx_5_ch=%d\n", __func__, - slim_rx_cfg[5].channels); - rx_ch_count = slim_rx_cfg[5].channels; - } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_2_RX) { - pr_debug("%s: rx_2_ch=%d\n", __func__, - slim_rx_cfg[2].channels); - rx_ch_count = slim_rx_cfg[2].channels; - } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_6_RX) { - pr_debug("%s: rx_6_ch=%d\n", __func__, - slim_rx_cfg[6].channels); - rx_ch_count = slim_rx_cfg[6].channels; - } else { - pr_debug("%s: rx_0_ch=%d\n", __func__, - slim_rx_cfg[0].channels); - rx_ch_count = slim_rx_cfg[0].channels; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, - rx_ch_count, rx_ch); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto err; - } - } else { - - pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__, - codec_dai->name, codec_dai->id, user_set_tx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map\n, err:%d\n", - __func__, ret); - goto err; - } - /* For _tx1 case */ - if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_0_TX) - user_set_tx_ch = slim_tx_cfg[0].channels; - /* For _tx3 case */ - else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_1_TX) - user_set_tx_ch = slim_tx_cfg[1].channels; - else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_4_TX) - user_set_tx_ch = msm_vi_feed_tx_ch; - else - user_set_tx_ch = tx_ch_cnt; - - pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), BE id (%d)\n", - __func__, slim_tx_cfg[0].channels, user_set_tx_ch, - tx_ch_cnt, dai_link->id); - - ret = snd_soc_dai_set_channel_map(cpu_dai, - user_set_tx_ch, tx_ch, 0, 0); - if (ret < 0) - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - } - -err: - return ret; -} - -static int msm_slimbus_2_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; - unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0; - unsigned int num_tx_ch = 0; - unsigned int num_rx_ch = 0; - int ret = 0; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - num_rx_ch = params_channels(params); - pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__, - codec_dai->name, codec_dai->id, num_rx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map, err:%d\n", - __func__, ret); - goto err; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, - num_rx_ch, rx_ch); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto err; - } - } else { - num_tx_ch = params_channels(params); - pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__, - codec_dai->name, codec_dai->id, num_tx_ch); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret < 0) { - pr_err("%s: failed to get codec chan map, err:%d\n", - __func__, ret); - goto err; - } - ret = snd_soc_dai_set_channel_map(cpu_dai, - num_tx_ch, tx_ch, 0, 0); - if (ret < 0) { - pr_err("%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - goto err; - } - } - -err: - return ret; -} - -static int msm_wcn_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai_link *dai_link = rtd->dai_link; - u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; - u32 rx_ch_cnt = 0, tx_ch_cnt = 0; - int ret; - - dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, - codec_dai->name, codec_dai->id); - ret = snd_soc_dai_get_channel_map(codec_dai, - &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); - if (ret) { - dev_err(rtd->dev, - "%s: failed to get BTFM codec chan map\n, err:%d\n", - __func__, ret); - goto err; - } - - dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) BE id %d\n", - __func__, tx_ch_cnt, dai_link->id); - - ret = snd_soc_dai_set_channel_map(cpu_dai, - tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); - if (ret) - dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", - __func__, ret); - -err: - return ret; -} - -static int msm_get_port_id(int be_id) -{ - int afe_port_id; - - switch (be_id) { - case MSM_BACKEND_DAI_PRI_MI2S_RX: - afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; - break; - case MSM_BACKEND_DAI_PRI_MI2S_TX: - afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; - break; - case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: - afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; - break; - case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: - afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; - break; - case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: - afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; - break; - case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: - afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; - break; - case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: - afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; - break; - case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: - afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; - break; - default: - pr_err("%s: Invalid BE id: %d\n", __func__, be_id); - afe_port_id = -EINVAL; - } - - return afe_port_id; -} - -static u32 get_mi2s_bits_per_sample(u32 bit_format) -{ - u32 bit_per_sample; - - switch (bit_format) { - case SNDRV_PCM_FORMAT_S32_LE: - case SNDRV_PCM_FORMAT_S24_3LE: - case SNDRV_PCM_FORMAT_S24_LE: - bit_per_sample = 32; - break; - case SNDRV_PCM_FORMAT_S16_LE: - default: - bit_per_sample = 16; - break; - } - - return bit_per_sample; -} - -static void update_mi2s_clk_val(int dai_id, int stream) -{ - u32 bit_per_sample; - - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - bit_per_sample = - get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format); - mi2s_clk[dai_id].clk_freq_in_hz = - mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample; - } else { - bit_per_sample = - get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format); - mi2s_clk[dai_id].clk_freq_in_hz = - mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample; - } -} - -static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) -{ - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int port_id = 0; - int index = cpu_dai->id; - - port_id = msm_get_port_id(rtd->dai_link->id); - if (port_id < 0) { - dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); - ret = port_id; - goto err; - } - - if (enable) { - update_mi2s_clk_val(index, substream->stream); - dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, - mi2s_clk[index].clk_freq_in_hz); - } - - mi2s_clk[index].enable = enable; - ret = afe_set_lpass_clock_v2(port_id, - &mi2s_clk[index]); - if (ret < 0) { - dev_err(rtd->card->dev, - "%s: afe lpass clock failed for port 0x%x , err:%d\n", - __func__, port_id, ret); - goto err; - } - -err: - return ret; -} - -static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, - enum pinctrl_pin_state new_state) -{ - int ret = 0; - int curr_state = 0; - - if (pinctrl_info == NULL) { - pr_err("%s: pinctrl_info is NULL\n", __func__); - ret = -EINVAL; - goto err; - } - - if (pinctrl_info->pinctrl == NULL) { - pr_err("%s: pinctrl_info->pinctrl is NULL\n", __func__); - ret = -EINVAL; - goto err; - } - - curr_state = pinctrl_info->curr_state; - pinctrl_info->curr_state = new_state; - pr_debug("%s: curr_state = %s new_state = %s\n", __func__, - pin_states[curr_state], pin_states[pinctrl_info->curr_state]); - - if (curr_state == pinctrl_info->curr_state) { - pr_debug("%s: Already in same state\n", __func__); - goto err; - } - - if (curr_state != STATE_DISABLE && - pinctrl_info->curr_state != STATE_DISABLE) { - pr_debug("%s: state already active cannot switch\n", __func__); - ret = -EIO; - goto err; - } - - switch (pinctrl_info->curr_state) { - case STATE_MI2S_ACTIVE: - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_active); - if (ret) { - pr_err("%s: MI2S state select failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - break; - case STATE_TDM_ACTIVE: - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->tdm_active); - if (ret) { - pr_err("%s: TDM state select failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - break; - case STATE_DISABLE: - if (curr_state == STATE_MI2S_ACTIVE) { - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_disable); - } else { - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->tdm_disable); - } - if (ret) { - pr_err("%s: state disable failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - break; - default: - pr_err("%s: TLMM pin state is invalid\n", __func__); - return -EINVAL; - } - -err: - return ret; -} - -static void msm_release_pinctrl(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - - if (pinctrl_info->pinctrl) { - devm_pinctrl_put(pinctrl_info->pinctrl); - pinctrl_info->pinctrl = NULL; - } -} - -static int msm_get_pinctrl(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = NULL; - struct pinctrl *pinctrl; - int ret; - - pinctrl_info = &pdata->pinctrl_info; - - if (pinctrl_info == NULL) { - pr_err("%s: pinctrl_info is NULL\n", __func__); - return -EINVAL; - } - - pinctrl = devm_pinctrl_get(&pdev->dev); - if (IS_ERR_OR_NULL(pinctrl)) { - pr_err("%s: Unable to get pinctrl handle\n", __func__); - return -EINVAL; - } - pinctrl_info->pinctrl = pinctrl; - - /* get all the states handles from Device Tree */ - pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl, - "quat-mi2s-sleep"); - if (IS_ERR(pinctrl_info->mi2s_disable)) { - pr_err("%s: could not get mi2s_disable pinstate\n", __func__); - goto err; - } - pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl, - "quat-mi2s-active"); - if (IS_ERR(pinctrl_info->mi2s_active)) { - pr_err("%s: could not get mi2s_active pinstate\n", __func__); - goto err; - } - pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl, - "quat-tdm-sleep"); - if (IS_ERR(pinctrl_info->tdm_disable)) { - pr_err("%s: could not get tdm_disable pinstate\n", __func__); - goto err; - } - pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl, - "quat-tdm-active"); - if (IS_ERR(pinctrl_info->tdm_active)) { - pr_err("%s: could not get tdm_active pinstate\n", - __func__); - goto err; - } - /* Reset the TLMM pins to a default state */ - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_disable); - if (ret != 0) { - pr_err("%s: Disable TLMM pins failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - pinctrl_info->curr_state = STATE_DISABLE; - - return 0; - -err: - devm_pinctrl_put(pinctrl); - pinctrl_info->pinctrl = NULL; - return -EINVAL; -} - -static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - if (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) { - channels->min = channels->max = - tdm_rx_cfg[TDM_QUAT][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); - rate->min = rate->max = - tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; - } else if (cpu_dai->id == AFE_PORT_ID_SECONDARY_TDM_RX) { - channels->min = channels->max = - tdm_rx_cfg[TDM_SEC][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; - } else { - pr_err("%s: dai id 0x%x not supported\n", - __func__, cpu_dai->id); - return -EINVAL; - } - - pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n", - __func__, cpu_dai->id, channels->max, rate->max, - params_format(params)); - - return 0; -} - -static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret = 0; - int slot_width = 32; - int channels, slots; - unsigned int slot_mask, rate, clk_freq; - unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; - - pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); - - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - switch (cpu_dai->id) { - case AFE_PORT_ID_PRIMARY_TDM_RX: - slots = tdm_rx_cfg[TDM_PRI][TDM_0].channels; - break; - case AFE_PORT_ID_SECONDARY_TDM_RX: - slots = tdm_rx_cfg[TDM_SEC][TDM_0].channels; - break; - case AFE_PORT_ID_TERTIARY_TDM_RX: - slots = tdm_rx_cfg[TDM_TERT][TDM_0].channels; - break; - case AFE_PORT_ID_QUATERNARY_TDM_RX: - slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; - break; - case AFE_PORT_ID_PRIMARY_TDM_TX: - slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels; - break; - case AFE_PORT_ID_SECONDARY_TDM_TX: - slots = tdm_tx_cfg[TDM_SEC][TDM_0].channels; - break; - case AFE_PORT_ID_TERTIARY_TDM_TX: - slots = tdm_tx_cfg[TDM_TERT][TDM_0].channels; - break; - case AFE_PORT_ID_QUATERNARY_TDM_TX: - slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels; - break; - default: - pr_err("%s: dai id 0x%x not supported\n", - __func__, cpu_dai->id); - return -EINVAL; - } - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - /*2 slot config - bits 0 and 1 set for the first two slots */ - slot_mask = 0x0000FFFF >> (16-slots); - channels = slots; - - pr_debug("%s: tdm rx slot_width %d slots %d\n", - __func__, slot_width, slots); - - ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, - slots, slot_width); - if (ret < 0) { - pr_err("%s: failed to set tdm rx slot, err:%d\n", - __func__, ret); - goto end; - } - - ret = snd_soc_dai_set_channel_map(cpu_dai, - 0, NULL, channels, slot_offset); - if (ret < 0) { - pr_err("%s: failed to set tdm rx channel map, err:%d\n", - __func__, ret); - goto end; - } - } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - /*2 slot config - bits 0 and 1 set for the first two slots */ - slot_mask = 0x0000FFFF >> (16-slots); - channels = slots; - - pr_debug("%s: tdm tx slot_width %d slots %d\n", - __func__, slot_width, slots); - - ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, - slots, slot_width); - if (ret < 0) { - pr_err("%s: failed to set tdm tx slot, err:%d\n", - __func__, ret); - goto end; - } - - ret = snd_soc_dai_set_channel_map(cpu_dai, - channels, slot_offset, 0, NULL); - if (ret < 0) { - pr_err("%s: failed to set tdm tx channel map, err:%d\n", - __func__, ret); - goto end; - } - } else { - ret = -EINVAL; - pr_err("%s: invalid use case, err:%d\n", - __func__, ret); - goto end; - } - - rate = params_rate(params); - clk_freq = rate * slot_width * slots; - ret = snd_soc_dai_set_sysclk(cpu_dai, 0, clk_freq, SND_SOC_CLOCK_OUT); - if (ret < 0) - pr_err("%s: failed to set tdm clk, err:%d\n", - __func__, ret); - -end: - return ret; -} - -static int sdm845_tdm_snd_startup(struct snd_pcm_substream *substream) -{ - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_card *card = rtd->card; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || - (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { - ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); - if (ret) - pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret); - } - - return ret; -} - -static void sdm845_tdm_snd_shutdown(struct snd_pcm_substream *substream) -{ - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_card *card = rtd->card; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || - (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { - ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); - if (ret) - pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret); - } -} - -static struct snd_soc_ops sdm845_tdm_be_ops = { - .hw_params = sdm845_tdm_snd_hw_params, - .startup = sdm845_tdm_snd_startup, - .shutdown = sdm845_tdm_snd_shutdown -}; - -static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) -{ - cpumask_t mask; - - if (pm_qos_request_active(&substream->latency_pm_qos_req)) - pm_qos_remove_request(&substream->latency_pm_qos_req); - - cpumask_clear(&mask); - cpumask_set_cpu(1, &mask); /* affine to core 1 */ - cpumask_set_cpu(2, &mask); /* affine to core 2 */ - cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); - - substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; - - pm_qos_add_request(&substream->latency_pm_qos_req, - PM_QOS_CPU_DMA_LATENCY, - MSM_LL_QOS_VALUE); - return 0; -} - -static struct snd_soc_ops msm_fe_qos_ops = { - .prepare = msm_fe_qos_prepare, -}; - -static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) -{ - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int index = cpu_dai->id; - unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; - struct snd_soc_card *card = rtd->card; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - int ret_pinctrl = 0; - - dev_dbg(rtd->card->dev, - "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", - __func__, substream->name, substream->stream, - cpu_dai->name, cpu_dai->id); - - if (index < PRIM_MI2S || index > QUAT_MI2S) { - ret = -EINVAL; - dev_err(rtd->card->dev, - "%s: CPU DAI id (%d) out of range\n", - __func__, cpu_dai->id); - goto err; - } - if (index == QUAT_MI2S) { - ret_pinctrl = msm_set_pinctrl(pinctrl_info, STATE_MI2S_ACTIVE); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); - } - /* - * Muxtex protection in case the same MI2S - * interface using for both TX and RX so - * that the same clock won't be enable twice. - */ - mutex_lock(&mi2s_intf_conf[index].lock); - if (++mi2s_intf_conf[index].ref_cnt == 1) { - /* Check if msm needs to provide the clock to the interface */ - if (!mi2s_intf_conf[index].msm_is_mi2s_master) { - mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; - fmt = SND_SOC_DAIFMT_CBM_CFM; - } - ret = msm_mi2s_set_sclk(substream, true); - if (ret < 0) { - dev_err(rtd->card->dev, - "%s: afe lpass clock failed to enable MI2S clock, err:%d\n", - __func__, ret); - goto clean_up; - } - - ret = snd_soc_dai_set_fmt(cpu_dai, fmt); - if (ret < 0) { - pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n", - __func__, index, ret); - goto clk_off; - } - } -clk_off: - if (ret < 0) - msm_mi2s_set_sclk(substream, false); -clean_up: - if (ret < 0) - mi2s_intf_conf[index].ref_cnt--; - mutex_unlock(&mi2s_intf_conf[index].lock); -err: - return ret; -} - -static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) -{ - int ret; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - int index = rtd->cpu_dai->id; - struct snd_soc_card *card = rtd->card; - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - int ret_pinctrl = 0; - - pr_debug("%s(): substream = %s stream = %d\n", __func__, - substream->name, substream->stream); - if (index < PRIM_MI2S || index > QUAT_MI2S) { - pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); - return; - } - - mutex_lock(&mi2s_intf_conf[index].lock); - if (--mi2s_intf_conf[index].ref_cnt == 0) { - ret = msm_mi2s_set_sclk(substream, false); - if (ret < 0) - pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", - __func__, index, ret); - } - mutex_unlock(&mi2s_intf_conf[index].lock); - - if (index == QUAT_MI2S) { - ret_pinctrl = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); - } -} - -static struct snd_soc_ops msm_mi2s_be_ops = { - .startup = msm_mi2s_snd_startup, - .shutdown = msm_mi2s_snd_shutdown, -}; - -static struct snd_soc_ops msm_be_ops = { - .hw_params = msm_snd_hw_params, -}; - -static struct snd_soc_ops msm_slimbus_2_be_ops = { - .hw_params = msm_slimbus_2_hw_params, -}; - -static struct snd_soc_ops msm_wcn_ops = { - .hw_params = msm_wcn_hw_params, -}; - - -/* Digital audio interface glue - connects codec <---> CPU */ -static struct snd_soc_dai_link msm_common_dai_links[] = { - /* FrontEnd DAI Links */ - { - .name = MSM_DAILINK_NAME(Media1), - .stream_name = "MultiMedia1", - .cpu_dai_name = "MultiMedia1", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA1 - }, - { - .name = MSM_DAILINK_NAME(Media2), - .stream_name = "MultiMedia2", - .cpu_dai_name = "MultiMedia2", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA2, - }, - { - .name = "VoiceMMode1", - .stream_name = "VoiceMMode1", - .cpu_dai_name = "VoiceMMode1", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_VOICEMMODE1, - }, - { - .name = "MSM VoIP", - .stream_name = "VoIP", - .cpu_dai_name = "VoIP", - .platform_name = "msm-voip-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_VOIP, - }, - { - .name = MSM_DAILINK_NAME(ULL), - .stream_name = "MultiMedia3", - .cpu_dai_name = "MultiMedia3", - .platform_name = "msm-pcm-dsp.2", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA3, - }, - /* Hostless PCM purpose */ - { - .name = "SLIMBUS_0 Hostless", - .stream_name = "SLIMBUS_0 Hostless", - .cpu_dai_name = "SLIMBUS0_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "MSM AFE-PCM RX", - .stream_name = "AFE-PROXY RX", - .cpu_dai_name = "msm-dai-q6-dev.241", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .platform_name = "msm-pcm-afe", - .dpcm_playback = 1, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - }, - { - .name = "MSM AFE-PCM TX", - .stream_name = "AFE-PROXY TX", - .cpu_dai_name = "msm-dai-q6-dev.240", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .platform_name = "msm-pcm-afe", - .dpcm_capture = 1, - .ignore_suspend = 1, - }, - { - .name = MSM_DAILINK_NAME(Compress1), - .stream_name = "Compress1", - .cpu_dai_name = "MultiMedia4", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA4, - }, - { - .name = "AUXPCM Hostless", - .stream_name = "AUXPCM Hostless", - .cpu_dai_name = "AUXPCM_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "SLIMBUS_1 Hostless", - .stream_name = "SLIMBUS_1 Hostless", - .cpu_dai_name = "SLIMBUS1_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "SLIMBUS_3 Hostless", - .stream_name = "SLIMBUS_3 Hostless", - .cpu_dai_name = "SLIMBUS3_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "SLIMBUS_4 Hostless", - .stream_name = "SLIMBUS_4 Hostless", - .cpu_dai_name = "SLIMBUS4_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - /* this dailink has playback support */ - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = MSM_DAILINK_NAME(LowLatency), - .stream_name = "MultiMedia5", - .cpu_dai_name = "MultiMedia5", - .platform_name = "msm-pcm-dsp.1", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA5, - .ops = &msm_fe_qos_ops, - }, - { - .name = "Listen 1 Audio Service", - .stream_name = "Listen 1 Audio Service", - .cpu_dai_name = "LSM1", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM1, - }, - /* Multiple Tunnel instances */ - { - .name = MSM_DAILINK_NAME(Compress2), - .stream_name = "Compress2", - .cpu_dai_name = "MultiMedia7", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA7, - }, - { - .name = MSM_DAILINK_NAME(MultiMedia10), - .stream_name = "MultiMedia10", - .cpu_dai_name = "MultiMedia10", - .platform_name = "msm-pcm-dsp.1", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA10, - }, - { - .name = MSM_DAILINK_NAME(ULL_NOIRQ), - .stream_name = "MM_NOIRQ", - .cpu_dai_name = "MultiMedia8", - .platform_name = "msm-pcm-dsp-noirq", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA8, - .ops = &msm_fe_qos_ops, - }, - /* HDMI Hostless */ - { - .name = "HDMI_RX_HOSTLESS", - .stream_name = "HDMI_RX_HOSTLESS", - .cpu_dai_name = "HDMI_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, - { - .name = "VoiceMMode2", - .stream_name = "VoiceMMode2", - .cpu_dai_name = "VoiceMMode2", - .platform_name = "msm-pcm-voice", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_VOICEMMODE2, - }, - /* LSM FE */ - { - .name = "Listen 2 Audio Service", - .stream_name = "Listen 2 Audio Service", - .cpu_dai_name = "LSM2", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM2, - }, - { - .name = "Listen 3 Audio Service", - .stream_name = "Listen 3 Audio Service", - .cpu_dai_name = "LSM3", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM3, - }, - { - .name = "Listen 4 Audio Service", - .stream_name = "Listen 4 Audio Service", - .cpu_dai_name = "LSM4", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM4, - }, - { - .name = "Listen 5 Audio Service", - .stream_name = "Listen 5 Audio Service", - .cpu_dai_name = "LSM5", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM5, - }, - { - .name = "Listen 6 Audio Service", - .stream_name = "Listen 6 Audio Service", - .cpu_dai_name = "LSM6", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM6, - }, - { - .name = "Listen 7 Audio Service", - .stream_name = "Listen 7 Audio Service", - .cpu_dai_name = "LSM7", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM7, - }, - { - .name = "Listen 8 Audio Service", - .stream_name = "Listen 8 Audio Service", - .cpu_dai_name = "LSM8", - .platform_name = "msm-lsm-client", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = { SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST }, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .id = MSM_FRONTEND_DAI_LSM8, - }, - { - .name = MSM_DAILINK_NAME(Media9), - .stream_name = "MultiMedia9", - .cpu_dai_name = "MultiMedia9", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA9, - }, - { - .name = MSM_DAILINK_NAME(Compress4), - .stream_name = "Compress4", - .cpu_dai_name = "MultiMedia11", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA11, - }, - { - .name = MSM_DAILINK_NAME(Compress5), - .stream_name = "Compress5", - .cpu_dai_name = "MultiMedia12", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA12, - }, - { - .name = MSM_DAILINK_NAME(Compress6), - .stream_name = "Compress6", - .cpu_dai_name = "MultiMedia13", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA13, - }, - { - .name = MSM_DAILINK_NAME(Compress7), - .stream_name = "Compress7", - .cpu_dai_name = "MultiMedia14", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA14, - }, - { - .name = MSM_DAILINK_NAME(Compress8), - .stream_name = "Compress8", - .cpu_dai_name = "MultiMedia15", - .platform_name = "msm-compress-dsp", - .dynamic = 1, - .dpcm_playback = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA15, - }, - { - .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), - .stream_name = "MM_NOIRQ_2", - .cpu_dai_name = "MultiMedia16", - .platform_name = "msm-pcm-dsp-noirq", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - /* this dainlink has playback support */ - .id = MSM_FRONTEND_DAI_MULTIMEDIA16, - }, - { - .name = "SLIMBUS_8 Hostless", - .stream_name = "SLIMBUS8_HOSTLESS Capture", - .cpu_dai_name = "SLIMBUS8_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, -}; - -static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = { - { - .name = LPASS_BE_SLIMBUS_4_TX, - .stream_name = "Slimbus4 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16393", - .platform_name = "msm-pcm-hostless", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_vifeedback", - .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - }, - /* Ultrasound RX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Playback", - .stream_name = "SLIMBUS_2 Hostless Playback", - .cpu_dai_name = "msm-dai-q6-dev.16388", - .platform_name = "msm-pcm-hostless", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx2", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm_slimbus_2_be_ops, - }, - /* Ultrasound TX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Capture", - .stream_name = "SLIMBUS_2 Hostless Capture", - .cpu_dai_name = "msm-dai-q6-dev.16389", - .platform_name = "msm-pcm-hostless", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_tx2", - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm_slimbus_2_be_ops, - }, -}; - -static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { - { - .name = MSM_DAILINK_NAME(ASM Loopback), - .stream_name = "MultiMedia6", - .cpu_dai_name = "MultiMedia6", - .platform_name = "msm-pcm-loopback", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA6, - }, - { - .name = "USB Audio Hostless", - .stream_name = "USB Audio Hostless", - .cpu_dai_name = "USBAUDIO_HOSTLESS", - .platform_name = "msm-pcm-hostless", - .dynamic = 1, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - }, -}; - -static struct snd_soc_dai_link msm_common_be_dai_links[] = { - /* Backend AFE DAI Links */ - { - .name = LPASS_BE_AFE_PCM_RX, - .stream_name = "AFE Playback", - .cpu_dai_name = "msm-dai-q6-dev.224", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_AFE_PCM_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_AFE_PCM_TX, - .stream_name = "AFE Capture", - .cpu_dai_name = "msm-dai-q6-dev.225", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_AFE_PCM_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Record Uplink BACK END DAI Link */ - { - .name = LPASS_BE_INCALL_RECORD_TX, - .stream_name = "Voice Uplink Capture", - .cpu_dai_name = "msm-dai-q6-dev.32772", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Record Downlink BACK END DAI Link */ - { - .name = LPASS_BE_INCALL_RECORD_RX, - .stream_name = "Voice Downlink Capture", - .cpu_dai_name = "msm-dai-q6-dev.32771", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Music BACK END DAI Link */ - { - .name = LPASS_BE_VOICE_PLAYBACK_TX, - .stream_name = "Voice Farend Playback", - .cpu_dai_name = "msm-dai-q6-dev.32773", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - /* Incall Music 2 BACK END DAI Link */ - { - .name = LPASS_BE_VOICE2_PLAYBACK_TX, - .stream_name = "Voice2 Farend Playback", - .cpu_dai_name = "msm-dai-q6-dev.32770", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_USB_AUDIO_RX, - .stream_name = "USB Audio Playback", - .cpu_dai_name = "msm-dai-q6-dev.28672", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_USB_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_USB_AUDIO_TX, - .stream_name = "USB Audio Capture", - .cpu_dai_name = "msm-dai-q6-dev.28673", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_USB_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_PRI_TDM_RX_0, - .stream_name = "Primary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36864", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &sdm845_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_PRI_TDM_TX_0, - .stream_name = "Primary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36865", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &sdm845_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SEC_TDM_RX_0, - .stream_name = "Secondary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36880", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &sdm845_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SEC_TDM_TX_0, - .stream_name = "Secondary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36881", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &sdm845_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_TERT_TDM_RX_0, - .stream_name = "Tertiary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36896", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &sdm845_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_TERT_TDM_TX_0, - .stream_name = "Tertiary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36897", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &sdm845_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_QUAT_TDM_RX_0, - .stream_name = "Quaternary TDM0 Playback", - .cpu_dai_name = "msm-dai-q6-tdm.36912", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, - .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, - .ops = &sdm845_tdm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_QUAT_TDM_TX_0, - .stream_name = "Quaternary TDM0 Capture", - .cpu_dai_name = "msm-dai-q6-tdm.36913", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &sdm845_tdm_be_ops, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm_tavil_be_dai_links[] = { - { - .name = LPASS_BE_SLIMBUS_0_RX, - .stream_name = "Slimbus Playback", - .cpu_dai_name = "msm-dai-q6-dev.16384", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, - .init = &msm_audrx_init, - .be_hw_params_fixup = msm_be_hw_params_fixup, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_0_TX, - .stream_name = "Slimbus Capture", - .cpu_dai_name = "msm-dai-q6-dev.16385", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_tx1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_1_RX, - .stream_name = "Slimbus1 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16386", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_1_TX, - .stream_name = "Slimbus1 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16387", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_tx3", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_2_RX, - .stream_name = "Slimbus2 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16388", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx2", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_2_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_3_RX, - .stream_name = "Slimbus3 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16390", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_3_TX, - .stream_name = "Slimbus3 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16391", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_tx1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_4_RX, - .stream_name = "Slimbus4 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16392", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_5_RX, - .stream_name = "Slimbus5 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16394", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx3", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - /* MAD BE */ - { - .name = LPASS_BE_SLIMBUS_5_TX, - .stream_name = "Slimbus5 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16395", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_mad1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_6_RX, - .stream_name = "Slimbus6 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16396", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_rx4", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - /* Slimbus VI Recording */ - { - .name = LPASS_BE_SLIMBUS_TX_VI, - .stream_name = "Slimbus4 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16393", - .platform_name = "msm-pcm-routing", - .codec_name = "tavil_codec", - .codec_dai_name = "tavil_vifeedback", - .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_suspend = 1, - .no_pcm = 1, - .dpcm_capture = 1, - .ignore_pmdown_time = 1, - }, -}; - -static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { - { - .name = LPASS_BE_SLIMBUS_7_RX, - .stream_name = "Slimbus7 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16398", - .platform_name = "msm-pcm-routing", - .codec_name = "btfmslim_slave", - /* BT codec driver determines capabilities based on - * dai name, bt codecdai name should always contains - * supported usecase information - */ - .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_7_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_wcn_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_7_TX, - .stream_name = "Slimbus7 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16399", - .platform_name = "msm-pcm-routing", - .codec_name = "btfmslim_slave", - .codec_dai_name = "btfm_bt_sco_slim_tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_7_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_wcn_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_8_TX, - .stream_name = "Slimbus8 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16401", - .platform_name = "msm-pcm-routing", - .codec_name = "btfmslim_slave", - .codec_dai_name = "btfm_fm_slim_tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_8_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .init = &msm_wcn_init, - .ops = &msm_wcn_ops, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link ext_disp_be_dai_link[] = { - /* DISP PORT BACK END DAI Link */ - { - .name = LPASS_BE_DISPLAY_PORT, - .stream_name = "Display Port Playback", - .cpu_dai_name = "msm-dai-q6-dp.24608", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-ext-disp-audio-codec-rx", - .codec_dai_name = "msm_dp_audio_codec_rx_dai", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { - { - .name = LPASS_BE_PRI_MI2S_RX, - .stream_name = "Primary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.0", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_PRI_MI2S_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_PRI_MI2S_TX, - .stream_name = "Primary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.0", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_PRI_MI2S_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SEC_MI2S_RX, - .stream_name = "Secondary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_SEC_MI2S_TX, - .stream_name = "Secondary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_TERT_MI2S_RX, - .stream_name = "Tertiary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_TERT_MI2S_TX, - .stream_name = "Tertiary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_QUAT_MI2S_RX, - .stream_name = "Quaternary MI2S Playback", - .cpu_dai_name = "msm-dai-q6-mi2s.3", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - { - .name = LPASS_BE_QUAT_MI2S_TX, - .stream_name = "Quaternary MI2S Capture", - .cpu_dai_name = "msm-dai-q6-mi2s.3", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_mi2s_be_ops, - .ignore_suspend = 1, - }, -}; - -static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { - /* Primary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_AUXPCM_RX, - .stream_name = "AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_AUXPCM_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_AUXPCM_TX, - .stream_name = "AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.1", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_AUXPCM_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - /* Secondary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_SEC_AUXPCM_RX, - .stream_name = "Sec AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SEC_AUXPCM_TX, - .stream_name = "Sec AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.2", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - /* Tertiary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_TERT_AUXPCM_RX, - .stream_name = "Tert AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.3", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_TERT_AUXPCM_TX, - .stream_name = "Tert AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.3", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, - /* Quaternary AUX PCM Backend DAI Links */ - { - .name = LPASS_BE_QUAT_AUXPCM_RX, - .stream_name = "Quat AUX PCM Playback", - .cpu_dai_name = "msm-dai-q6-auxpcm.4", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_QUAT_AUXPCM_TX, - .stream_name = "Quat AUX PCM Capture", - .cpu_dai_name = "msm-dai-q6-auxpcm.4", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - }, -}; - -static struct snd_soc_dai_link msm_tavil_snd_card_dai_links[ - ARRAY_SIZE(msm_common_dai_links) + - ARRAY_SIZE(msm_tavil_fe_dai_links) + - ARRAY_SIZE(msm_common_misc_fe_dai_links) + - ARRAY_SIZE(msm_common_be_dai_links) + - ARRAY_SIZE(msm_tavil_be_dai_links) + - ARRAY_SIZE(msm_wcn_be_dai_links) + - ARRAY_SIZE(ext_disp_be_dai_link) + - ARRAY_SIZE(msm_mi2s_be_dai_links) + - ARRAY_SIZE(msm_auxpcm_be_dai_links)]; - -static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) -{ - const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; - struct snd_soc_pcm_runtime *rtd; - int ret = 0; - void *mbhc_calibration; - - rtd = snd_soc_get_pcm_runtime(card, be_dl_name); - if (!rtd) { - dev_err(card->dev, - "%s: snd_soc_get_pcm_runtime for %s failed!\n", - __func__, be_dl_name); - ret = -EINVAL; - goto err; - } - - mbhc_calibration = def_tavil_mbhc_cal(); - if (!mbhc_calibration) { - ret = -ENOMEM; - goto err; - } - wcd_mbhc_cfg.calibration = mbhc_calibration; - ret = tavil_mbhc_hs_detect(rtd->codec, &wcd_mbhc_cfg); - if (ret) { - dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", - __func__, ret); - goto err_free_mbhc_cal; - } - return 0; - -err_free_mbhc_cal: - kfree(mbhc_calibration); -err: - return ret; -} - -struct snd_soc_card snd_soc_card_tavil_msm = { - .name = "sdm845-tavil-snd-card", - .late_probe = msm_snd_card_tavil_late_probe, -}; - -static int msm_populate_dai_link_component_of_node( - struct snd_soc_card *card) -{ - int i, index, ret = 0; - struct device *cdev = card->dev; - struct snd_soc_dai_link *dai_link = card->dai_link; - struct device_node *np; - - if (!cdev) { - pr_err("%s: Sound card device memory NULL\n", __func__); - return -ENODEV; - } - - for (i = 0; i < card->num_links; i++) { - if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) - continue; - - /* populate platform_of_node for snd card dai links */ - if (dai_link[i].platform_name && - !dai_link[i].platform_of_node) { - index = of_property_match_string(cdev->of_node, - "asoc-platform-names", - dai_link[i].platform_name); - if (index < 0) { - pr_err("%s: No match found for platform name: %s\n", - __func__, dai_link[i].platform_name); - ret = index; - goto err; - } - np = of_parse_phandle(cdev->of_node, "asoc-platform", - index); - if (!np) { - pr_err("%s: retrieving phandle for platform %s, index %d failed\n", - __func__, dai_link[i].platform_name, - index); - ret = -ENODEV; - goto err; - } - dai_link[i].platform_of_node = np; - dai_link[i].platform_name = NULL; - } - - /* populate cpu_of_node for snd card dai links */ - if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { - index = of_property_match_string(cdev->of_node, - "asoc-cpu-names", - dai_link[i].cpu_dai_name); - if (index >= 0) { - np = of_parse_phandle(cdev->of_node, "asoc-cpu", - index); - if (!np) { - pr_err("%s: retrieving phandle for cpu dai %s failed\n", - __func__, - dai_link[i].cpu_dai_name); - ret = -ENODEV; - goto err; - } - dai_link[i].cpu_of_node = np; - dai_link[i].cpu_dai_name = NULL; - } - } - - /* populate codec_of_node for snd card dai links */ - if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { - index = of_property_match_string(cdev->of_node, - "asoc-codec-names", - dai_link[i].codec_name); - if (index < 0) - continue; - np = of_parse_phandle(cdev->of_node, "asoc-codec", - index); - if (!np) { - pr_err("%s: retrieving phandle for codec %s failed\n", - __func__, dai_link[i].codec_name); - ret = -ENODEV; - goto err; - } - dai_link[i].codec_of_node = np; - dai_link[i].codec_name = NULL; - } - } - -err: - return ret; -} - -static int msm_prepare_us_euro(struct snd_soc_card *card) -{ - struct msm_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - int ret = 0; - - if (pdata->us_euro_gpio >= 0) { - dev_dbg(card->dev, "%s: us_euro gpio request %d", __func__, - pdata->us_euro_gpio); - ret = gpio_request(pdata->us_euro_gpio, "TAVIL_CODEC_US_EURO"); - if (ret) { - dev_err(card->dev, - "%s: Failed to request codec US/EURO gpio %d error %d\n", - __func__, pdata->us_euro_gpio, ret); - } - } - - return ret; -} - -static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret = 0; - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - - ret = snd_soc_add_codec_controls(codec, msm_snd_controls, - ARRAY_SIZE(msm_snd_controls)); - if (ret < 0) { - dev_err(codec->dev, - "%s: add_codec_controls failed, err = %d\n", - __func__, ret); - return ret; - } - - snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, - ARRAY_SIZE(msm_dapm_widgets)); - - return 0; -} - -static int msm_snd_stub_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - - int ret = 0; - unsigned int rx_ch[] = {144, 145, 146, 147, 148, 149, 150, - 151}; - unsigned int tx_ch[] = {128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143}; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, - slim_rx_cfg[0].channels, - rx_ch); - if (ret < 0) - pr_err("%s: RX failed to set cpu chan map error %d\n", - __func__, ret); - } else { - ret = snd_soc_dai_set_channel_map(cpu_dai, - slim_tx_cfg[0].channels, - tx_ch, 0, 0); - if (ret < 0) - pr_err("%s: TX failed to set cpu chan map error %d\n", - __func__, ret); - } - - return ret; -} - -static struct snd_soc_ops msm_stub_be_ops = { - .hw_params = msm_snd_stub_hw_params, -}; - -static struct snd_soc_dai_link msm_stub_fe_dai_links[] = { - - /* FrontEnd DAI Links */ - { - .name = "MSMSTUB Media1", - .stream_name = "MultiMedia1", - .cpu_dai_name = "MultiMedia1", - .platform_name = "msm-pcm-dsp.0", - .dynamic = 1, - .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, - .dpcm_playback = 1, - .dpcm_capture = 1, - .trigger = {SND_SOC_DPCM_TRIGGER_POST, - SND_SOC_DPCM_TRIGGER_POST}, - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .ignore_suspend = 1, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .id = MSM_FRONTEND_DAI_MULTIMEDIA1 - }, -}; - -static struct snd_soc_dai_link msm_stub_be_dai_links[] = { - - /* Backend DAI Links */ - { - .name = LPASS_BE_SLIMBUS_0_RX, - .stream_name = "Slimbus Playback", - .cpu_dai_name = "msm-dai-q6-dev.16384", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-rx", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, - .init = &msm_audrx_stub_init, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_pmdown_time = 1, /* dai link has playback support */ - .ignore_suspend = 1, - .ops = &msm_stub_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_0_TX, - .stream_name = "Slimbus Capture", - .cpu_dai_name = "msm-dai-q6-dev.16385", - .platform_name = "msm-pcm-routing", - .codec_name = "msm-stub-codec.1", - .codec_dai_name = "msm-stub-tx", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_stub_be_ops, - }, -}; - -static struct snd_soc_dai_link msm_stub_dai_links[ - ARRAY_SIZE(msm_stub_fe_dai_links) + - ARRAY_SIZE(msm_stub_be_dai_links)]; - -struct snd_soc_card snd_soc_card_stub_msm = { - .name = "sdm845-stub-snd-card", -}; - -static const struct of_device_id sdm845_asoc_machine_of_match[] = { - { .compatible = "qcom,sdm845-asoc-snd-tavil", - .data = "tavil_codec"}, - { .compatible = "qcom,sdm845-asoc-snd-stub", - .data = "stub_codec"}, - {}, -}; - -static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) -{ - struct snd_soc_card *card = NULL; - struct snd_soc_dai_link *dailink; - int len_1, len_2, len_3, len_4; - int total_links; - const struct of_device_id *match; - - match = of_match_node(sdm845_asoc_machine_of_match, dev->of_node); - if (!match) { - dev_err(dev, "%s: No DT match found for sound card\n", - __func__); - return NULL; - } - - if (!strcmp(match->data, "tavil_codec")) { - card = &snd_soc_card_tavil_msm; - len_1 = ARRAY_SIZE(msm_common_dai_links); - len_2 = len_1 + ARRAY_SIZE(msm_tavil_fe_dai_links); - len_3 = len_2 + ARRAY_SIZE(msm_common_misc_fe_dai_links); - len_4 = len_3 + ARRAY_SIZE(msm_common_be_dai_links); - total_links = len_4 + ARRAY_SIZE(msm_tavil_be_dai_links); - memcpy(msm_tavil_snd_card_dai_links, - msm_common_dai_links, - sizeof(msm_common_dai_links)); - memcpy(msm_tavil_snd_card_dai_links + len_1, - msm_tavil_fe_dai_links, - sizeof(msm_tavil_fe_dai_links)); - memcpy(msm_tavil_snd_card_dai_links + len_2, - msm_common_misc_fe_dai_links, - sizeof(msm_common_misc_fe_dai_links)); - memcpy(msm_tavil_snd_card_dai_links + len_3, - msm_common_be_dai_links, - sizeof(msm_common_be_dai_links)); - memcpy(msm_tavil_snd_card_dai_links + len_4, - msm_tavil_be_dai_links, - sizeof(msm_tavil_be_dai_links)); - - if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { - dev_dbg(dev, "%s(): WCN BTFM support present\n", - __func__); - memcpy(msm_tavil_snd_card_dai_links + total_links, - msm_wcn_be_dai_links, - sizeof(msm_wcn_be_dai_links)); - total_links += ARRAY_SIZE(msm_wcn_be_dai_links); - } - - if (of_property_read_bool(dev->of_node, - "qcom,ext-disp-audio-rx")) { - dev_dbg(dev, "%s(): ext disp audio support present\n", - __func__); - memcpy(msm_tavil_snd_card_dai_links + total_links, - ext_disp_be_dai_link, - sizeof(ext_disp_be_dai_link)); - total_links += ARRAY_SIZE(ext_disp_be_dai_link); - } - if (of_property_read_bool(dev->of_node, - "qcom,mi2s-audio-intf")) { - memcpy(msm_tavil_snd_card_dai_links + total_links, - msm_mi2s_be_dai_links, - sizeof(msm_mi2s_be_dai_links)); - total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); - } - if (of_property_read_bool(dev->of_node, - "qcom,auxpcm-audio-intf")) { - memcpy(msm_tavil_snd_card_dai_links + total_links, - msm_auxpcm_be_dai_links, - sizeof(msm_auxpcm_be_dai_links)); - total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links); - } - dailink = msm_tavil_snd_card_dai_links; - } else if (!strcmp(match->data, "stub_codec")) { - card = &snd_soc_card_stub_msm; - len_1 = ARRAY_SIZE(msm_stub_fe_dai_links); - len_2 = len_1 + ARRAY_SIZE(msm_stub_be_dai_links); - - memcpy(msm_stub_dai_links, - msm_stub_fe_dai_links, - sizeof(msm_stub_fe_dai_links)); - memcpy(msm_stub_dai_links + len_1, - msm_stub_be_dai_links, - sizeof(msm_stub_be_dai_links)); - - dailink = msm_stub_dai_links; - total_links = len_2; - } - - if (card) { - card->dai_link = dailink; - card->num_links = total_links; - } - - return card; -} - -static int msm_wsa881x_init(struct snd_soc_component *component) -{ - u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106}; - u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107}; - unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; - unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); - struct msm_asoc_mach_data *pdata; - struct snd_soc_dapm_context *dapm; - int ret = 0; - - if (!codec) { - pr_err("%s codec is NULL\n", __func__); - return -EINVAL; - } - - dapm = snd_soc_codec_get_dapm(codec); - - if (!strcmp(component->name_prefix, "SpkrLeft")) { - dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n", - __func__, codec->component.name); - wsa881x_set_channel_map(codec, &spkleft_ports[0], - WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0], NULL); - if (dapm->component) { - snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); - snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); - } - } else if (!strcmp(component->name_prefix, "SpkrRight")) { - dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n", - __func__, codec->component.name); - wsa881x_set_channel_map(codec, &spkright_ports[0], - WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0], NULL); - if (dapm->component) { - snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); - snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); - } - } else { - dev_err(codec->dev, "%s: wrong codec name %s\n", __func__, - codec->component.name); - ret = -EINVAL; - goto err; - } - pdata = snd_soc_card_get_drvdata(component->card); - if (pdata && pdata->codec_root) - wsa881x_codec_info_create_codec_entry(pdata->codec_root, - codec); - -err: - return ret; -} - -static int msm_init_wsa_dev(struct platform_device *pdev, - struct snd_soc_card *card) -{ - struct device_node *wsa_of_node; - u32 wsa_max_devs; - u32 wsa_dev_cnt; - int i; - struct msm_wsa881x_dev_info *wsa881x_dev_info; - const char *wsa_auxdev_name_prefix[1]; - char *dev_name_str = NULL; - int found = 0; - int ret = 0; - - /* Get maximum WSA device count for this platform */ - ret = of_property_read_u32(pdev->dev.of_node, - "qcom,wsa-max-devs", &wsa_max_devs); - if (ret) { - dev_info(&pdev->dev, - "%s: wsa-max-devs property missing in DT %s, ret = %d\n", - __func__, pdev->dev.of_node->full_name, ret); - card->num_aux_devs = 0; - return 0; - } - if (wsa_max_devs == 0) { - dev_warn(&pdev->dev, - "%s: Max WSA devices is 0 for this target?\n", - __func__); - card->num_aux_devs = 0; - return 0; - } - - /* Get count of WSA device phandles for this platform */ - wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node, - "qcom,wsa-devs", NULL); - if (wsa_dev_cnt == -ENOENT) { - dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n", - __func__); - goto err; - } else if (wsa_dev_cnt <= 0) { - dev_err(&pdev->dev, - "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n", - __func__, wsa_dev_cnt); - ret = -EINVAL; - goto err; - } - - /* - * Expect total phandles count to be NOT less than maximum possible - * WSA count. However, if it is less, then assign same value to - * max count as well. - */ - if (wsa_dev_cnt < wsa_max_devs) { - dev_dbg(&pdev->dev, - "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n", - __func__, wsa_max_devs, wsa_dev_cnt); - wsa_max_devs = wsa_dev_cnt; - } - - /* Make sure prefix string passed for each WSA device */ - ret = of_property_count_strings(pdev->dev.of_node, - "qcom,wsa-aux-dev-prefix"); - if (ret != wsa_dev_cnt) { - dev_err(&pdev->dev, - "%s: expecting %d wsa prefix. Defined only %d in DT\n", - __func__, wsa_dev_cnt, ret); - ret = -EINVAL; - goto err; - } - - /* - * Alloc mem to store phandle and index info of WSA device, if already - * registered with ALSA core - */ - wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs, - sizeof(struct msm_wsa881x_dev_info), - GFP_KERNEL); - if (!wsa881x_dev_info) { - ret = -ENOMEM; - goto err; - } - - /* - * search and check whether all WSA devices are already - * registered with ALSA core or not. If found a node, store - * the node and the index in a local array of struct for later - * use. - */ - for (i = 0; i < wsa_dev_cnt; i++) { - wsa_of_node = of_parse_phandle(pdev->dev.of_node, - "qcom,wsa-devs", i); - if (unlikely(!wsa_of_node)) { - /* we should not be here */ - dev_err(&pdev->dev, - "%s: wsa dev node is not present\n", - __func__); - ret = -EINVAL; - goto err_free_dev_info; - } - if (soc_find_component(wsa_of_node, NULL)) { - /* WSA device registered with ALSA core */ - wsa881x_dev_info[found].of_node = wsa_of_node; - wsa881x_dev_info[found].index = i; - found++; - if (found == wsa_max_devs) - break; - } - } - - if (found < wsa_max_devs) { - dev_dbg(&pdev->dev, - "%s: failed to find %d components. Found only %d\n", - __func__, wsa_max_devs, found); - return -EPROBE_DEFER; - } - dev_info(&pdev->dev, - "%s: found %d wsa881x devices registered with ALSA core\n", - __func__, found); - - card->num_aux_devs = wsa_max_devs; - card->num_configs = wsa_max_devs; - - /* Alloc array of AUX devs struct */ - msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, - sizeof(struct snd_soc_aux_dev), - GFP_KERNEL); - if (!msm_aux_dev) { - ret = -ENOMEM; - goto err_free_dev_info; - } - - /* Alloc array of codec conf struct */ - msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs, - sizeof(struct snd_soc_codec_conf), - GFP_KERNEL); - if (!msm_codec_conf) { - ret = -ENOMEM; - goto err_free_aux_dev; - } - - for (i = 0; i < card->num_aux_devs; i++) { - dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN, - GFP_KERNEL); - if (!dev_name_str) { - ret = -ENOMEM; - goto err_free_cdc_conf; - } - - ret = of_property_read_string_index(pdev->dev.of_node, - "qcom,wsa-aux-dev-prefix", - wsa881x_dev_info[i].index, - wsa_auxdev_name_prefix); - if (ret) { - dev_err(&pdev->dev, - "%s: failed to read wsa aux dev prefix, ret = %d\n", - __func__, ret); - ret = -EINVAL; - goto err_free_dev_name_str; - } - - snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i); - msm_aux_dev[i].name = dev_name_str; - msm_aux_dev[i].codec_name = NULL; - msm_aux_dev[i].codec_of_node = - wsa881x_dev_info[i].of_node; - msm_aux_dev[i].init = msm_wsa881x_init; - msm_codec_conf[i].dev_name = NULL; - msm_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0]; - msm_codec_conf[i].of_node = - wsa881x_dev_info[i].of_node; - } - card->codec_conf = msm_codec_conf; - card->aux_dev = msm_aux_dev; - - return 0; - -err_free_dev_name_str: - devm_kfree(&pdev->dev, dev_name_str); -err_free_cdc_conf: - devm_kfree(&pdev->dev, msm_codec_conf); -err_free_aux_dev: - devm_kfree(&pdev->dev, msm_aux_dev); -err_free_dev_info: - devm_kfree(&pdev->dev, wsa881x_dev_info); -err: - return ret; -} - -static void msm_i2s_auxpcm_init(struct platform_device *pdev) -{ - int count; - u32 mi2s_master_slave[MI2S_MAX]; - int ret; - - for (count = 0; count < MI2S_MAX; count++) { - mutex_init(&mi2s_intf_conf[count].lock); - mi2s_intf_conf[count].ref_cnt = 0; - } - - ret = of_property_read_u32_array(pdev->dev.of_node, - "qcom,msm-mi2s-master", - mi2s_master_slave, MI2S_MAX); - if (ret) { - dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n", - __func__); - } else { - for (count = 0; count < MI2S_MAX; count++) { - mi2s_intf_conf[count].msm_is_mi2s_master = - mi2s_master_slave[count]; - } - } -} - -static void msm_i2s_auxpcm_deinit(void) -{ - int count; - - for (count = 0; count < MI2S_MAX; count++) { - mutex_destroy(&mi2s_intf_conf[count].lock); - mi2s_intf_conf[count].ref_cnt = 0; - mi2s_intf_conf[count].msm_is_mi2s_master = 0; - } -} - -static int msm_asoc_machine_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card; - struct msm_asoc_mach_data *pdata; - const char *mbhc_audio_jack_type = NULL; - char *mclk_freq_prop_name; - const struct of_device_id *match; - int ret; - const char *usb_c_dt = "qcom,msm-mbhc-usbc-audio-supported"; - - if (!pdev->dev.of_node) { - dev_err(&pdev->dev, "No platform supplied from device tree\n"); - return -EINVAL; - } - - pdata = devm_kzalloc(&pdev->dev, - sizeof(struct msm_asoc_mach_data), GFP_KERNEL); - if (!pdata) - return -ENOMEM; - - card = populate_snd_card_dailinks(&pdev->dev); - if (!card) { - dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); - ret = -EINVAL; - goto err; - } - card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); - snd_soc_card_set_drvdata(card, pdata); - - ret = snd_soc_of_parse_card_name(card, "qcom,model"); - if (ret) { - dev_err(&pdev->dev, "parse card name failed, err:%d\n", - ret); - goto err; - } - - ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing"); - if (ret) { - dev_err(&pdev->dev, "parse audio routing failed, err:%d\n", - ret); - goto err; - } - - match = of_match_node(sdm845_asoc_machine_of_match, - pdev->dev.of_node); - if (!match) { - dev_err(&pdev->dev, "%s: no matched codec is found.\n", - __func__); - goto err; - } - - mclk_freq_prop_name = "qcom,tavil-mclk-clk-freq"; - - ret = of_property_read_u32(pdev->dev.of_node, - mclk_freq_prop_name, &pdata->mclk_freq); - if (ret) { - dev_err(&pdev->dev, - "Looking up %s property in node %s failed, err%d\n", - mclk_freq_prop_name, - pdev->dev.of_node->full_name, ret); - goto err; - } - - if (pdata->mclk_freq != CODEC_EXT_CLK_RATE) { - dev_err(&pdev->dev, "unsupported mclk freq %u\n", - pdata->mclk_freq); - ret = -EINVAL; - goto err; - } - - ret = msm_populate_dai_link_component_of_node(card); - if (ret) { - ret = -EPROBE_DEFER; - goto err; - } - ret = msm_init_wsa_dev(pdev, card); - if (ret) - goto err; - - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret == -EPROBE_DEFER) { - if (codec_reg_done) - ret = -EINVAL; - goto err; - } else if (ret) { - dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", - ret); - goto err; - } - dev_info(&pdev->dev, "Sound card %s registered\n", card->name); - spdev = pdev; - - ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); - if (ret) { - dev_dbg(&pdev->dev, "%s: failed to add child nodes, ret=%d\n", - __func__, ret); - } else { - pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,hph-en1-gpio", 0); - if (!pdata->hph_en1_gpio_p) { - dev_dbg(&pdev->dev, "property %s not detected in node %s", - "qcom,hph-en1-gpio", - pdev->dev.of_node->full_name); - } - - pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,hph-en0-gpio", 0); - if (!pdata->hph_en0_gpio_p) { - dev_dbg(&pdev->dev, "property %s not detected in node %s", - "qcom,hph-en0-gpio", - pdev->dev.of_node->full_name); - } - } - - ret = of_property_read_string(pdev->dev.of_node, - "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type); - if (ret) { - dev_dbg(&pdev->dev, "Looking up %s property in node %s failed", - "qcom,mbhc-audio-jack-type", - pdev->dev.of_node->full_name); - dev_dbg(&pdev->dev, "Jack type properties set to default"); - } else { - if (!strcmp(mbhc_audio_jack_type, "4-pole-jack")) { - wcd_mbhc_cfg.enable_anc_mic_detect = false; - dev_dbg(&pdev->dev, "This hardware has 4 pole jack"); - } else if (!strcmp(mbhc_audio_jack_type, "5-pole-jack")) { - wcd_mbhc_cfg.enable_anc_mic_detect = true; - dev_dbg(&pdev->dev, "This hardware has 5 pole jack"); - } else if (!strcmp(mbhc_audio_jack_type, "6-pole-jack")) { - wcd_mbhc_cfg.enable_anc_mic_detect = true; - dev_dbg(&pdev->dev, "This hardware has 6 pole jack"); - } else { - wcd_mbhc_cfg.enable_anc_mic_detect = false; - dev_dbg(&pdev->dev, "Unknown value, set to default"); - } - } - /* - * Parse US-Euro gpio info from DT. Report no error if us-euro - * entry is not found in DT file as some targets do not support - * US-Euro detection - */ - pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node, - "qcom,us-euro-gpios", 0); - if (!gpio_is_valid(pdata->us_euro_gpio)) - pdata->us_euro_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,us-euro-gpios", 0); - if (!gpio_is_valid(pdata->us_euro_gpio) && (!pdata->us_euro_gpio_p)) { - dev_dbg(&pdev->dev, "property %s not detected in node %s", - "qcom,us-euro-gpios", pdev->dev.of_node->full_name); - } else { - dev_dbg(&pdev->dev, "%s detected", - "qcom,us-euro-gpios"); - wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; - } - - if (of_find_property(pdev->dev.of_node, usb_c_dt, NULL)) - wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; - - ret = msm_prepare_us_euro(card); - if (ret) - dev_dbg(&pdev->dev, "msm_prepare_us_euro failed (%d)\n", - ret); - - /* Parse pinctrl info from devicetree */ - ret = msm_get_pinctrl(pdev); - if (!ret) { - pr_debug("%s: pinctrl parsing successful\n", __func__); - } else { - dev_dbg(&pdev->dev, - "%s: Parsing pinctrl failed with %d. Cannot use Ports\n", - __func__, ret); - ret = 0; - } - - msm_i2s_auxpcm_init(pdev); - - is_initial_boot = true; - ret = audio_notifier_register("sdm845", AUDIO_NOTIFIER_ADSP_DOMAIN, - &service_nb); - if (ret < 0) - pr_err("%s: Audio notifier register failed ret = %d\n", - __func__, ret); - - return 0; -err: - msm_release_pinctrl(pdev); - devm_kfree(&pdev->dev, pdata); - return ret; -} - -static int msm_asoc_machine_remove(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct msm_asoc_mach_data *pdata = - snd_soc_card_get_drvdata(card); - - audio_notifier_deregister("sdm845"); - if (pdata->us_euro_gpio > 0) { - gpio_free(pdata->us_euro_gpio); - pdata->us_euro_gpio = 0; - } - msm_i2s_auxpcm_deinit(); - - msm_release_pinctrl(pdev); - snd_soc_unregister_card(card); - return 0; -} - -static struct platform_driver sdm845_asoc_machine_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .pm = &snd_soc_pm_ops, - .of_match_table = sdm845_asoc_machine_of_match, - }, - .probe = msm_asoc_machine_probe, - .remove = msm_asoc_machine_remove, -}; -module_platform_driver(sdm845_asoc_machine_driver); - -MODULE_DESCRIPTION("ALSA SoC msm"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:" DRV_NAME); -MODULE_DEVICE_TABLE(of, sdm845_asoc_machine_of_match); diff --git a/config/sdm670auto.conf b/config/sdm670auto.conf deleted file mode 100644 index 4c0b284c9c96..000000000000 --- a/config/sdm670auto.conf +++ /dev/null @@ -1,50 +0,0 @@ -CONFIG_PINCTRL_LPI=m -CONFIG_PINCTRL_WCD=m -CONFIG_AUDIO_EXT_CLK=m -CONFIG_SND_SOC_WCD9XXX_V2=m -CONFIG_SND_SOC_WCD_MBHC=m -CONFIG_SND_SOC_WSA881X=m -CONFIG_SND_SOC_WCD_DSP_MGR=m -CONFIG_SND_SOC_WCD_SPI=m -CONFIG_SND_SOC_WCD_CPE=m -CONFIG_SND_SOC_CPE=m -CONFIG_SND_SOC_WCD9335=m -CONFIG_SND_SOC_WCD934X=m -CONFIG_SND_SOC_WCD934X_MBHC=m -CONFIG_SND_SOC_WCD934X_DSD=m -CONFIG_MSM_QDSP6V2_CODECS=m -CONFIG_MSM_ULTRASOUND=m -CONFIG_MSM_QDSP6_APRV2_GLINK=m -CONFIG_MSM_ADSP_LOADER=m -CONFIG_REGMAP_SWR=m -CONFIG_MSM_QDSP6_SSR=m -CONFIG_MSM_QDSP6_PDR=m -CONFIG_MSM_QDSP6_NOTIFIER=m -CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m -CONFIG_SND_SOC_SDM670=m -CONFIG_MSM_GLINK_SPI_XPRT=m -CONFIG_SOUNDWIRE=m -CONFIG_SOUNDWIRE_WCD_CTRL=m -CONFIG_SND_SOC_QDSP6V2=m -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m -CONFIG_WCD9XXX_CODEC_CORE=m -CONFIG_MSM_CDC_PINCTRL=m -CONFIG_SND_SOC_WCD_MBHC_ADC=m -CONFIG_SND_SOC_WCD_MBHC_LEGACY=m -CONFIG_QTI_PP=m -CONFIG_SND_HWDEP_ROUTING=m -CONFIG_DTS_EAGLE=m -CONFIG_DOLBY_DS2=m -CONFIG_DOLBY_LICENSE=m -CONFIG_DTS_SRS_TM=m -CONFIG_SND_SOC_EXT_CODEC=m -CONFIG_SND_SOC_INT_CODEC=m -CONFIG_SND_SOC_MSM_STUB=m -CONFIG_WCD_DSP_GLINK=m -CONFIG_MSM_AVTIMER=m -CONFIG_SND_SOC_SDM660_CDC=m -CONFIG_SND_SOC_ANALOG_CDC=m -CONFIG_SND_SOC_DIGITAL_CDC=m -CONFIG_SND_SOC_MSM_SDW=m -CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m diff --git a/config/sdm670auto_static.conf b/config/sdm670auto_static.conf deleted file mode 100644 index 91a84649da8f..000000000000 --- a/config/sdm670auto_static.conf +++ /dev/null @@ -1,50 +0,0 @@ -CONFIG_PINCTRL_LPI=y -CONFIG_PINCTRL_WCD=y -CONFIG_AUDIO_EXT_CLK=y -CONFIG_SND_SOC_WCD9XXX_V2=y -CONFIG_SND_SOC_WCD_MBHC=y -CONFIG_SND_SOC_WSA881X=y -CONFIG_SND_SOC_WCD_DSP_MGR=y -CONFIG_SND_SOC_WCD_SPI=y -CONFIG_SND_SOC_WCD_CPE=y -CONFIG_SND_SOC_CPE=y -CONFIG_SND_SOC_WCD9335=y -CONFIG_SND_SOC_WCD934X=y -CONFIG_SND_SOC_WCD934X_MBHC=y -CONFIG_SND_SOC_WCD934X_DSD=y -CONFIG_MSM_QDSP6V2_CODECS=y -CONFIG_MSM_ULTRASOUND=y -CONFIG_MSM_QDSP6_APRV2_GLINK=y -CONFIG_MSM_ADSP_LOADER=y -CONFIG_REGMAP_SWR=y -CONFIG_MSM_QDSP6_SSR=y -CONFIG_MSM_QDSP6_PDR=y -CONFIG_MSM_QDSP6_NOTIFIER=y -CONFIG_SND_SOC_MSM_HOSTLESS_PCM=y -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y -CONFIG_SND_SOC_SDM670=y -CONFIG_MSM_GLINK_SPI_XPRT=y -CONFIG_SOUNDWIRE=y -CONFIG_SOUNDWIRE_WCD_CTRL=y -CONFIG_SND_SOC_QDSP6V2=y -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y -CONFIG_WCD9XXX_CODEC_CORE=y -CONFIG_MSM_CDC_PINCTRL=y -CONFIG_SND_SOC_WCD_MBHC_ADC=y -CONFIG_SND_SOC_WCD_MBHC_LEGACY=y -CONFIG_QTI_PP=y -CONFIG_SND_HWDEP_ROUTING=y -CONFIG_DTS_EAGLE=y -CONFIG_DOLBY_DS2=y -CONFIG_DOLBY_LICENSE=y -CONFIG_DTS_SRS_TM=y -CONFIG_SND_SOC_EXT_CODEC=y -CONFIG_SND_SOC_INT_CODEC=y -CONFIG_SND_SOC_MSM_STUB=y -CONFIG_WCD_DSP_GLINK=y -CONFIG_MSM_AVTIMER=y -CONFIG_SND_SOC_SDM660_CDC=y -CONFIG_SND_SOC_ANALOG_CDC=y -CONFIG_SND_SOC_DIGITAL_CDC=y -CONFIG_SND_SOC_MSM_SDW=y -CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y diff --git a/config/sdm670autoconf.h b/config/sdm670autoconf.h deleted file mode 100644 index 55f9548fc44a..000000000000 --- a/config/sdm670autoconf.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#define CONFIG_PINCTRL_LPI 1 -#define CONFIG_PINCTRL_WCD 1 -#define CONFIG_AUDIO_EXT_CLK 1 -#define CONFIG_SND_SOC_WCD9XXX_V2 1 -#define CONFIG_SND_SOC_WCD_CPE 1 -#define CONFIG_SND_SOC_WCD_MBHC 1 -#define CONFIG_SND_SOC_WSA881X 1 -#define CONFIG_SND_SOC_WCD_DSP_MGR 1 -#define CONFIG_SND_SOC_WCD_SPI 1 -#define CONFIG_SND_SOC_WCD9335 1 -#define CONFIG_SND_SOC_WCD934X 1 -#define CONFIG_SND_SOC_WCD934X_MBHC 1 -#define CONFIG_SND_SOC_WCD934X_DSD 1 -#define CONFIG_MSM_QDSP6V2_CODECS 1 -#define CONFIG_MSM_ULTRASOUND 1 -#define CONFIG_MSM_QDSP6_APRV2_GLINK 1 -#define CONFIG_MSM_ADSP_LOADER 1 -#define CONFIG_REGMAP_SWR 1 -#define CONFIG_MSM_QDSP6_SSR 1 -#define CONFIG_MSM_QDSP6_PDR 1 -#define CONFIG_MSM_QDSP6_NOTIFIER 1 -#define CONFIG_SND_SOC_MSM_HOSTLESS_PCM 1 -#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 -#define CONFIG_SND_SOC_SDM670 1 -#define CONFIG_MSM_GLINK_SPI_XPRT 1 -#define CONFIG_SOUNDWIRE 1 -#define CONFIG_SOUNDWIRE_WCD_CTRL 1 -#define CONFIG_SND_SOC_WCD_MBHC_ADC 1 -#define CONFIG_SND_SOC_WCD_MBHC_LEGACY 1 -#define CONFIG_SND_SOC_QDSP6V2 1 -#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 -#define CONFIG_QTI_PP 1 -#define CONFIG_SND_HWDEP_ROUTING 1 -#define CONFIG_DTS_EAGLE 1 -#define CONFIG_DOLBY_DS2 1 -#define CONFIG_DOLBY_LICENSE 1 -#define CONFIG_DTS_SRS_TM 1 -#define CONFIG_WCD9XXX_CODEC_CORE 1 -#define CONFIG_MSM_CDC_PINCTRL 1 -#define CONFIG_SND_SOC_MSM_STUB 1 -#define CONFIG_WCD_DSP_GLINK 1 -#define CONFIG_MSM_AVTIMER 1 -#define CONFIG_SND_SOC_EXT_CODEC 1 -#define CONFIG_SND_SOC_INT_CODEC 1 -#define CONFIG_SND_SOC_CPE 1 -#define CONFIG_SND_SOC_SDM660_CDC 1 -#define CONFIG_SND_SOC_ANALOG_CDC 1 -#define CONFIG_SND_SOC_DIGITAL_CDC 1 -#define CONFIG_SND_SOC_MSM_SDW 1 -#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 diff --git a/config/sdm845auto.conf b/config/sdm845auto.conf deleted file mode 100644 index 4c195b43ddc6..000000000000 --- a/config/sdm845auto.conf +++ /dev/null @@ -1,37 +0,0 @@ -CONFIG_PINCTRL_WCD=m -CONFIG_SND_SOC_WCD9XXX_V2=m -CONFIG_SND_SOC_WCD_MBHC=m -CONFIG_SND_SOC_WSA881X=m -CONFIG_SND_SOC_WCD_SPI=m -CONFIG_SND_SOC_WCD934X=m -CONFIG_SOUNDWIRE_WCD_CTRL=m -CONFIG_WCD9XXX_CODEC_CORE=m -CONFIG_MSM_CDC_PINCTRL=m -CONFIG_SND_SOC_WCD934X_MBHC=m -CONFIG_SND_SOC_WCD934X_DSD=m -CONFIG_SND_SOC_MACHINE_SDM845=m -CONFIG_WCD_DSP_GLINK=m -CONFIG_MSM_QDSP6V2_CODECS=y -CONFIG_MSM_ULTRASOUND=y -CONFIG_MSM_QDSP6_APRV2_GLINK=y -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y -CONFIG_MSM_ADSP_LOADER=y -CONFIG_REGMAP_SWR=y -CONFIG_MSM_QDSP6_SSR=y -CONFIG_MSM_QDSP6_PDR=y -CONFIG_MSM_QDSP6_NOTIFIER=y -CONFIG_SND_SOC_MSM_HOSTLESS_PCM=y -CONFIG_SND_SOC_SDM845=y -CONFIG_MSM_GLINK_SPI_XPRT=y -CONFIG_SOUNDWIRE=y -CONFIG_SND_SOC_QDSP6V2=y -CONFIG_SND_SOC_WCD_MBHC_ADC=y -CONFIG_QTI_PP=y -CONFIG_SND_HWDEP_ROUTING=y -CONFIG_DTS_EAGLE=y -CONFIG_DOLBY_DS2=y -CONFIG_DOLBY_LICENSE=y -CONFIG_DTS_SRS_TM=y -CONFIG_SND_SOC_MSM_STUB=y -CONFIG_MSM_AVTIMER=y -CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y diff --git a/config/sdm845autoconf.h b/config/sdm845autoconf.h deleted file mode 100644 index 6ef465a61871..000000000000 --- a/config/sdm845autoconf.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#define CONFIG_PINCTRL_WCD 1 -#define CONFIG_SND_SOC_WCD934X 1 -#define CONFIG_SND_SOC_WCD9XXX_V2 1 -#define CONFIG_SND_SOC_WCD_CPE 1 -#define CONFIG_SND_SOC_WCD_MBHC 1 -#define CONFIG_SND_SOC_WSA881X 1 -#define CONFIG_SND_SOC_WCD_SPI 1 -#define CONFIG_SND_SOC_WCD934X_MBHC 1 -#define CONFIG_SND_SOC_WCD934X_DSD 1 -#define CONFIG_MSM_QDSP6V2_CODECS 1 -#define CONFIG_MSM_ULTRASOUND 1 -#define CONFIG_MSM_QDSP6_APRV2_GLINK 1 -#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 -#define CONFIG_MSM_ADSP_LOADER 1 -#define CONFIG_REGMAP_SWR 1 -#define CONFIG_MSM_QDSP6_SSR 1 -#define CONFIG_MSM_QDSP6_PDR 1 -#define CONFIG_MSM_QDSP6_NOTIFIER 1 -#define CONFIG_SND_SOC_MSM_HOSTLESS_PCM 1 -#define CONFIG_SND_SOC_SDM845 1 -#define CONFIG_MSM_GLINK_SPI_XPRT 1 -#define CONFIG_SOUNDWIRE 1 -#define CONFIG_SOUNDWIRE_WCD_CTRL 1 -#define CONFIG_SND_SOC_WCD_MBHC_ADC 1 -#define CONFIG_SND_SOC_QDSP6V2 1 -#define CONFIG_MSM_CDC_PINCTRL 1 -#define CONFIG_QTI_PP 1 -#define CONFIG_SND_HWDEP_ROUTING 1 -#define CONFIG_DTS_EAGLE 1 -#define CONFIG_DOLBY_DS2 1 -#define CONFIG_DOLBY_LICENSE 1 -#define CONFIG_DTS_SRS_TM 1 -#define CONFIG_WCD9XXX_CODEC_CORE 1 -#define CONFIG_SND_SOC_MSM_STUB 1 -#define CONFIG_WCD_DSP_GLINK 1 -#define CONFIG_MSM_AVTIMER 1 -#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 diff --git a/dsp/Android.mk b/dsp/Android.mk index 310bd01f104f..c81a1bdc5255 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -3,14 +3,6 @@ # Assume no targets will be supported # Check if this driver needs be built for current target -ifeq ($(call is-board-platform,sdm845),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m -endif - -ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m -endif - ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif @@ -21,7 +13,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/Kbuild b/dsp/Kbuild index 11db9d57b061..6d9ea15ad5ee 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -14,21 +14,6 @@ ifeq ($(KERNEL_BUILD), 1) endif ifeq ($(KERNEL_BUILD), 0) - ifeq ($(CONFIG_ARCH_SDM845), y) - include $(AUDIO_ROOT)/config/sdm845auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM670), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM450), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm6150auto.conf export diff --git a/dsp/codecs/Android.mk b/dsp/codecs/Android.mk index 0e22e03a8cd8..62f6db80a881 100644 --- a/dsp/codecs/Android.mk +++ b/dsp/codecs/Android.mk @@ -3,14 +3,6 @@ # Assume no targets will be supported # Check if this driver needs be built for current target -ifeq ($(call is-board-platform,sdm845),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m -endif - -ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m -endif - ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif @@ -21,7 +13,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 34e3b720baf1..f6c9ea446438 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -14,22 +14,6 @@ ifeq ($(KERNEL_BUILD), 1) endif ifeq ($(KERNEL_BUILD), 0) - ifeq ($(CONFIG_ARCH_SDM845), y) - include $(AUDIO_ROOT)/config/sdm845auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h - - endif - ifeq ($(CONFIG_ARCH_SDM670), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM450), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm6150auto.conf export diff --git a/include/asoc/wcd9360-registers.h b/include/asoc/wcd9360-registers.h deleted file mode 100644 index bca9de3019e3..000000000000 --- a/include/asoc/wcd9360-registers.h +++ /dev/null @@ -1,1158 +0,0 @@ -/* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _WCD9360_REGISTERS_H -#define _WCD9360_REGISTERS_H - -#define WCD9360_PAGE_SIZE 256 -#define WCD9360_NUM_PAGES 256 - -enum { - WCD9360_PAGE_0 = 0, - WCD9360_PAGE_1, - WCD9360_PAGE_2, - WCD9360_PAGE_4 = 4, - WCD9360_PAGE_6 = 6, - WCD9360_PAGE_7, - WCD9360_PAGE_10 = 10, - WCD9360_PAGE_11, - WCD9360_PAGE_12, - WCD9360_PAGE_13, - WCD9360_PAGE_14, - WCD9360_PAGE_80, - WCD9360_PAGE_128, - WCD9360_PAGE_MAX, -}; - -enum { - WCD9360_WO = 0, - WCD9360_RO, - WCD9360_RW, -}; - -extern const u8 * const wcd9360_reg[WCD9360_PAGE_MAX]; - -/* Page-0 Registers */ -#define WCD9360_PAGE0_PAGE_REGISTER (0x00000000) -#define WCD9360_CODEC_RPM_CLK_BYPASS (0x00000001) -#define WCD9360_CODEC_RPM_CLK_GATE (0x00000002) -#define WCD9360_CODEC_RPM_CLK_MCLK_CFG (0x00000003) -#define WCD9360_CODEC_RPM_CLK_MCLK2_CFG (0x00000004) -#define WCD9360_CODEC_RPM_I2S_DSD_CLK_SEL (0x00000005) -#define WCD9360_CODEC_RPM_RST_CTL (0x00000009) -#define WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL (0x00000011) -#define WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE0 (0x00000021) -#define WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE1 (0x00000022) -#define WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE2 (0x00000023) -#define WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE3 (0x00000024) -#define WCD9360_CHIP_TIER_CTRL_EFUSE_CTL (0x00000025) -#define WCD9360_CHIP_TIER_CTRL_EFUSE_TEST0 (0x00000026) -#define WCD9360_CHIP_TIER_CTRL_EFUSE_TEST1 (0x00000027) -#define WCD9360_CHIP_TIER_CTRL_EFUSE_STATUS (0x00000039) -#define WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO (0x0000003A) -#define WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_1 (0x0000003B) -#define WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_2 (0x0000003C) -#define WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_3 (0x0000003D) -#define WCD9360_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL (0x0000003E) -#define WCD9360_CHIP_TIER_CTRL_I2C_ACTIVE (0x00000040) -#define WCD9360_CHIP_TIER_CTRL_ALT_FUNC_EN (0x00000041) -#define WCD9360_CHIP_TIER_CTRL_GPIO_CTL_OE (0x00000042) -#define WCD9360_CHIP_TIER_CTRL_GPIO_CTL_DATA (0x00000043) -#define WCD9360_DATA_HUB_RX0_CFG (0x00000051) -#define WCD9360_DATA_HUB_RX1_CFG (0x00000052) -#define WCD9360_DATA_HUB_RX2_CFG (0x00000053) -#define WCD9360_DATA_HUB_RX3_CFG (0x00000054) -#define WCD9360_DATA_HUB_RX4_CFG (0x00000055) -#define WCD9360_DATA_HUB_RX5_CFG (0x00000056) -#define WCD9360_DATA_HUB_RX6_CFG (0x00000057) -#define WCD9360_DATA_HUB_RX7_CFG (0x00000058) -#define WCD9360_DATA_HUB_SB_TX0_INP_CFG (0x00000061) -#define WCD9360_DATA_HUB_SB_TX1_INP_CFG (0x00000062) -#define WCD9360_DATA_HUB_SB_TX2_INP_CFG (0x00000063) -#define WCD9360_DATA_HUB_SB_TX3_INP_CFG (0x00000064) -#define WCD9360_DATA_HUB_SB_TX4_INP_CFG (0x00000065) -#define WCD9360_DATA_HUB_SB_TX5_INP_CFG (0x00000066) -#define WCD9360_DATA_HUB_SB_TX6_INP_CFG (0x00000067) -#define WCD9360_DATA_HUB_SB_TX7_INP_CFG (0x00000068) -#define WCD9360_DATA_HUB_SB_TX8_INP_CFG (0x00000069) -#define WCD9360_DATA_HUB_SB_TX9_INP_CFG (0x0000006A) -#define WCD9360_DATA_HUB_SB_TX10_INP_CFG (0x0000006B) -#define WCD9360_DATA_HUB_SB_TX11_INP_CFG (0x0000006C) -#define WCD9360_DATA_HUB_SB_TX12_INP_CFG (0x0000006D) -#define WCD9360_DATA_HUB_SB_TX13_INP_CFG (0x0000006E) -#define WCD9360_DATA_HUB_SB_TX14_INP_CFG (0x0000006F) -#define WCD9360_DATA_HUB_SB_TX15_INP_CFG (0x00000070) -#define WCD9360_DATA_HUB_I2S_TX0_CFG (0x00000071) -#define WCD9360_DATA_HUB_I2S_TX0_CFG2 (0x00000072) -#define WCD9360_DATA_HUB_I2S_TX1_0_CFG (0x00000073) -#define WCD9360_DATA_HUB_I2S_TX1_1_CFG (0x00000074) -#define WCD9360_DATA_HUB_DATA_HUB_CFG (0x00000079) -#define WCD9360_DATA_HUB_I2S_0_CTL (0x00000081) -#define WCD9360_DATA_HUB_I2S_1_CTL (0x00000082) -#define WCD9360_DATA_HUB_I2S_0_CTL2 (0x00000083) -#define WCD9360_DATA_HUB_I2S_1_CTL2 (0x00000084) -#define WCD9360_DATA_HUB_I2S_CLKSRC_CTL (0x00000085) -#define WCD9360_DATA_HUB_I2S_COMMON_CTL (0x00000086) -#define WCD9360_DATA_HUB_I2S_0_TDM_CTL (0x00000087) -#define WCD9360_DATA_HUB_I2S_0_TDM_CTL2 (0x00000089) -#define WCD9360_DATA_HUB_I2S_0_TDM_CH_RX (0x0000008A) -#define WCD9360_DATA_HUB_I2S_0_TDM_CH_TX (0x0000008B) -#define WCD9360_DATA_HUB_I2S_0_TDM_CFG (0x0000008C) -#define WCD9360_DATA_HUB_I2S_0_TDM_STRETCH (0x0000008D) -#define WCD9360_DATA_HUB_I2S_RESET_CTL (0x00000090) -#define WCD9360_DMA_RDMA_CTL_0 (0x00000091) -#define WCD9360_DMA_CH_2_3_CFG_RDMA_0 (0x00000092) -#define WCD9360_DMA_CH_0_1_CFG_RDMA_0 (0x00000093) -#define WCD9360_DMA_RDMA_CTL_1 (0x00000094) -#define WCD9360_DMA_CH_2_3_CFG_RDMA_1 (0x00000095) -#define WCD9360_DMA_CH_0_1_CFG_RDMA_1 (0x00000096) -#define WCD9360_DMA_RDMA_CTL_2 (0x00000097) -#define WCD9360_DMA_CH_2_3_CFG_RDMA_2 (0x00000098) -#define WCD9360_DMA_CH_0_1_CFG_RDMA_2 (0x00000099) -#define WCD9360_DMA_RDMA_CTL_3 (0x0000009A) -#define WCD9360_DMA_CH_2_3_CFG_RDMA_3 (0x0000009B) -#define WCD9360_DMA_CH_0_1_CFG_RDMA_3 (0x0000009C) -#define WCD9360_DMA_RDMA_CTL_4 (0x0000009D) -#define WCD9360_DMA_CH_2_3_CFG_RDMA_4 (0x0000009E) -#define WCD9360_DMA_CH_0_1_CFG_RDMA_4 (0x0000009F) -#define WCD9360_DMA_RDMA4_PRT_CFG (0x000000B1) -#define WCD9360_DMA_RDMA_SBTX0_7_CFG (0x000000B9) -#define WCD9360_DMA_RDMA_SBTX8_10_CFG (0x000000BA) -#define WCD9360_DMA_WDMA_CTL_0 (0x000000C1) -#define WCD9360_DMA_WDMA_CTL_1 (0x000000C6) -#define WCD9360_DMA_WDMA_CTL_2 (0x000000CB) -#define WCD9360_DMA_WDMA_CTL_3 (0x000000D0) -#define WCD9360_DMA_WDMA_CTL_4 (0x000000D5) -#define WCD9360_DMA_CH_4_5_CFG_WDMA_0 (0x000000C2) -#define WCD9360_DMA_CH_4_5_CFG_WDMA_1 (0x000000C7) -#define WCD9360_DMA_CH_4_5_CFG_WDMA_2 (0x000000CC) -#define WCD9360_DMA_CH_4_5_CFG_WDMA_3 (0x000000D1) -#define WCD9360_DMA_CH_4_5_CFG_WDMA_4 (0x000000D6) -#define WCD9360_DMA_CH_2_3_CFG_WDMA_0 (0x000000C3) -#define WCD9360_DMA_CH_2_3_CFG_WDMA_1 (0x000000C8) -#define WCD9360_DMA_CH_2_3_CFG_WDMA_2 (0x000000CD) -#define WCD9360_DMA_CH_2_3_CFG_WDMA_3 (0x000000D2) -#define WCD9360_DMA_CH_2_3_CFG_WDMA_4 (0x000000D7) -#define WCD9360_DMA_CH_0_1_CFG_WDMA_0 (0x000000C4) -#define WCD9360_DMA_CH_0_1_CFG_WDMA_1 (0x000000C9) -#define WCD9360_DMA_CH_0_1_CFG_WDMA_2 (0x000000CE) -#define WCD9360_DMA_CH_0_1_CFG_WDMA_3 (0x000000D3) -#define WCD9360_DMA_CH_0_1_CFG_WDMA_4 (0x000000D8) -#define WCD9360_DMA_WDMA0_PRT_CFG (0x000000E1) -#define WCD9360_DMA_WDMA3_PRT_CFG (0x000000E2) -#define WCD9360_DMA_WDMA4_PRT0_3_CFG (0x000000E3) -#define WCD9360_DMA_WDMA4_PRT4_7_CFG (0x000000E4) -#define WCD9360_PAGE1_PAGE_REGISTER (0x00000100) -#define WCD9360_CPE_FLL_USER_CTL_0 (0x00000101) -#define WCD9360_CPE_FLL_USER_CTL_1 (0x00000102) -#define WCD9360_CPE_FLL_USER_CTL_2 (0x00000103) -#define WCD9360_CPE_FLL_USER_CTL_3 (0x00000104) -#define WCD9360_CPE_FLL_USER_CTL_4 (0x00000105) -#define WCD9360_CPE_FLL_USER_CTL_5 (0x00000106) -#define WCD9360_CPE_FLL_USER_CTL_6 (0x00000107) -#define WCD9360_CPE_FLL_USER_CTL_7 (0x00000108) -#define WCD9360_CPE_FLL_USER_CTL_8 (0x00000109) -#define WCD9360_CPE_FLL_USER_CTL_9 (0x0000010A) -#define WCD9360_CPE_FLL_L_VAL_CTL_0 (0x0000010B) -#define WCD9360_CPE_FLL_L_VAL_CTL_1 (0x0000010C) -#define WCD9360_CPE_FLL_DSM_FRAC_CTL_0 (0x0000010D) -#define WCD9360_CPE_FLL_DSM_FRAC_CTL_1 (0x0000010E) -#define WCD9360_CPE_FLL_CONFIG_CTL_0 (0x0000010F) -#define WCD9360_CPE_FLL_CONFIG_CTL_1 (0x00000110) -#define WCD9360_CPE_FLL_CONFIG_CTL_2 (0x00000111) -#define WCD9360_CPE_FLL_CONFIG_CTL_3 (0x00000112) -#define WCD9360_CPE_FLL_CONFIG_CTL_4 (0x00000113) -#define WCD9360_CPE_FLL_TEST_CTL_0 (0x00000114) -#define WCD9360_CPE_FLL_TEST_CTL_1 (0x00000115) -#define WCD9360_CPE_FLL_TEST_CTL_2 (0x00000116) -#define WCD9360_CPE_FLL_TEST_CTL_3 (0x00000117) -#define WCD9360_CPE_FLL_TEST_CTL_4 (0x00000118) -#define WCD9360_CPE_FLL_TEST_CTL_5 (0x00000119) -#define WCD9360_CPE_FLL_TEST_CTL_6 (0x0000011A) -#define WCD9360_CPE_FLL_TEST_CTL_7 (0x0000011B) -#define WCD9360_CPE_FLL_FREQ_CTL_0 (0x0000011C) -#define WCD9360_CPE_FLL_FREQ_CTL_1 (0x0000011D) -#define WCD9360_CPE_FLL_FREQ_CTL_2 (0x0000011E) -#define WCD9360_CPE_FLL_FREQ_CTL_3 (0x0000011F) -#define WCD9360_CPE_FLL_SSC_CTL_0 (0x00000120) -#define WCD9360_CPE_FLL_SSC_CTL_1 (0x00000121) -#define WCD9360_CPE_FLL_SSC_CTL_2 (0x00000122) -#define WCD9360_CPE_FLL_SSC_CTL_3 (0x00000123) -#define WCD9360_CPE_FLL_FLL_MODE (0x00000124) -#define WCD9360_CPE_FLL_STATUS_0 (0x00000125) -#define WCD9360_CPE_FLL_STATUS_1 (0x00000126) -#define WCD9360_CPE_FLL_STATUS_2 (0x00000127) -#define WCD9360_CPE_FLL_STATUS_3 (0x00000128) -#define WCD9360_I2S_FLL_USER_CTL_0 (0x00000141) -#define WCD9360_I2S_FLL_USER_CTL_1 (0x00000142) -#define WCD9360_I2S_FLL_USER_CTL_2 (0x00000143) -#define WCD9360_I2S_FLL_USER_CTL_3 (0x00000144) -#define WCD9360_I2S_FLL_USER_CTL_4 (0x00000145) -#define WCD9360_I2S_FLL_USER_CTL_5 (0x00000146) -#define WCD9360_I2S_FLL_USER_CTL_6 (0x00000147) -#define WCD9360_I2S_FLL_USER_CTL_7 (0x00000148) -#define WCD9360_I2S_FLL_USER_CTL_8 (0x00000149) -#define WCD9360_I2S_FLL_USER_CTL_9 (0x0000014A) -#define WCD9360_I2S_FLL_L_VAL_CTL_0 (0x0000014B) -#define WCD9360_I2S_FLL_L_VAL_CTL_1 (0x0000014C) -#define WCD9360_I2S_FLL_DSM_FRAC_CTL_0 (0x0000014D) -#define WCD9360_I2S_FLL_DSM_FRAC_CTL_1 (0x0000014E) -#define WCD9360_I2S_FLL_CONFIG_CTL_0 (0x0000014F) -#define WCD9360_I2S_FLL_CONFIG_CTL_1 (0x00000150) -#define WCD9360_I2S_FLL_CONFIG_CTL_2 (0x00000151) -#define WCD9360_I2S_FLL_CONFIG_CTL_3 (0x00000152) -#define WCD9360_I2S_FLL_CONFIG_CTL_4 (0x00000153) -#define WCD9360_I2S_FLL_TEST_CTL_0 (0x00000154) -#define WCD9360_I2S_FLL_TEST_CTL_1 (0x00000155) -#define WCD9360_I2S_FLL_TEST_CTL_2 (0x00000156) -#define WCD9360_I2S_FLL_TEST_CTL_3 (0x00000157) -#define WCD9360_I2S_FLL_TEST_CTL_4 (0x00000158) -#define WCD9360_I2S_FLL_TEST_CTL_5 (0x00000159) -#define WCD9360_I2S_FLL_TEST_CTL_6 (0x0000015A) -#define WCD9360_I2S_FLL_TEST_CTL_7 (0x0000015B) -#define WCD9360_I2S_FLL_FREQ_CTL_0 (0x0000015C) -#define WCD9360_I2S_FLL_FREQ_CTL_1 (0x0000015D) -#define WCD9360_I2S_FLL_FREQ_CTL_2 (0x0000015E) -#define WCD9360_I2S_FLL_FREQ_CTL_3 (0x0000015F) -#define WCD9360_I2S_FLL_SSC_CTL_0 (0x00000160) -#define WCD9360_I2S_FLL_SSC_CTL_1 (0x00000161) -#define WCD9360_I2S_FLL_SSC_CTL_2 (0x00000162) -#define WCD9360_I2S_FLL_SSC_CTL_3 (0x00000163) -#define WCD9360_I2S_FLL_FLL_MODE (0x00000164) -#define WCD9360_I2S_FLL_STATUS_0 (0x00000165) -#define WCD9360_I2S_FLL_STATUS_1 (0x00000166) -#define WCD9360_I2S_FLL_STATUS_2 (0x00000167) -#define WCD9360_I2S_FLL_STATUS_3 (0x00000168) -#define WCD9360_PAGE2_PAGE_REGISTER (0x00000200) -#define WCD9360_CPE_SS_CPE_CTL (0x00000201) -#define WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_0 (0x00000202) -#define WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_1 (0x00000203) -#define WCD9360_CPE_SS_PWR_CPEFLL_CTL (0x00000204) -#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0 (0x00000205) -#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1 (0x00000206) -#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0 (0x00000208) -#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1 (0x00000209) -#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2 (0x0000020A) -#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3 (0x0000020B) -#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_4 (0x0000020C) -#define WCD9360_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN (0x0000020E) -#define WCD9360_CPE_SS_US_BUF_INT_PERIOD (0x00000212) -#define WCD9360_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD (0x00000213) -#define WCD9360_CPE_SS_SVA_CFG (0x00000214) -#define WCD9360_CPE_SS_US_CFG (0x00000215) -#define WCD9360_CPE_SS_MAD_CTL (0x00000216) -#define WCD9360_CPE_SS_CPAR_CTL (0x00000217) -#define WCD9360_CPE_SS_DMIC0_CTL (0x00000218) -#define WCD9360_CPE_SS_DMIC1_CTL (0x00000219) -#define WCD9360_CPE_SS_DMIC2_CTL (0x0000021A) -#define WCD9360_CPE_SS_DMIC_CFG (0x0000021B) -#define WCD9360_CPE_SS_CPAR_CFG (0x0000021C) -#define WCD9360_CPE_SS_WDOG_CFG (0x0000021D) -#define WCD9360_CPE_SS_BACKUP_INT (0x0000021E) -#define WCD9360_CPE_SS_STATUS (0x0000021F) -#define WCD9360_CPE_SS_CPE_OCD_CFG (0x00000220) -#define WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A (0x00000221) -#define WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B (0x00000222) -#define WCD9360_CPE_SS_SS_ERROR_INT_MASK_1A (0x00000223) -#define WCD9360_CPE_SS_SS_ERROR_INT_MASK_1B (0x00000224) -#define WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0A (0x00000225) -#define WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0B (0x00000226) -#define WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1A (0x00000227) -#define WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1B (0x00000228) -#define WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0A (0x00000229) -#define WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0B (0x0000022A) -#define WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1A (0x0000022B) -#define WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1B (0x0000022C) -#define WCD9360_CPE_SS_DMIC3_CTL (0x00000231) -#define WCD9360_CPE_SS_WDOG_RESET (0x00000239) -#define WCD9360_CPE_SS_LPASS_MCLK_PRG (0x00000240) -#define WCD9360_CPE_SS_LPASS_IPC_IN_0 (0x00000241) -#define WCD9360_CPE_SS_LPASS_IPC_IN_1 (0x00000242) -#define WCD9360_CPE_SS_LPASS_IPC_IN_2 (0x00000243) -#define WCD9360_CPE_SS_LPASS_IPC_IN_3 (0x00000244) -#define WCD9360_CPE_SS_LPASS_IPC_IN_4 (0x00000245) -#define WCD9360_CPE_SS_LPASS_IPC_IN_5 (0x00000246) -#define WCD9360_CPE_SS_LPASS_IPC_IN_6 (0x00000247) -#define WCD9360_CPE_SS_LPASS_IPC_IN_7 (0x00000248) -#define WCD9360_CPE_SS_LPASS_IPC_IN_8 (0x00000249) -#define WCD9360_CPE_SS_LPASS_IPC_IN_9 (0x0000024A) -#define WCD9360_CPE_SS_LPASS_IPC_IN_10 (0x0000024B) -#define WCD9360_CPE_SS_LPASS_IPC_IN_11 (0x0000024C) -#define WCD9360_CPE_SS_LPASS_IPC_IN_12 (0x0000024D) -#define WCD9360_CPE_SS_LPASS_IPC_IN_13 (0x0000024E) -#define WCD9360_CPE_SS_LPASS_IPC_IN_14 (0x0000024F) -#define WCD9360_CPE_SS_LPASS_IPC_IN_15 (0x00000250) -#define WCD9360_CPE_SS_LPASS_IPC_OUT_0 (0x00000251) -#define WCD9360_CPE_SS_LPASS_IPC_OUT_1 (0x00000252) -#define WCD9360_CPE_SS_LPASS_IPC_OUT_2 (0x00000253) -#define WCD9360_CPE_SS_LPASS_IPC_OUT_3 (0x00000254) -#define WCD9360_CPE_SS_LPASS_IPC_OUT_4 (0x00000255) -#define WCD9360_CPE_SS_LPASS_IPC_OUT_5 (0x00000256) -#define WCD9360_CPE_SS_LPASS_IPC_OUT_6 (0x00000257) -#define WCD9360_CPE_SS_LPASS_IPC_OUT_7 (0x00000258) -#define WCD9360_CPE_SS_LPASS_IPC_OUT_8 (0x00000259) -#define WCD9360_CPE_SS_LPASS_IPC_OUT_9 (0x0000025A) -#define WCD9360_CPE_SS_LPASS_IPC_OUT_10 (0x0000025B) -#define WCD9360_CPE_SS_LPASS_IPC_OUT_11 (0x0000025C) -#define WCD9360_CPE_SS_LPASS_IPC_OUT_12 (0x0000025D) -#define WCD9360_CPE_SS_LPASS_IPC_OUT_13 (0x0000025E) -#define WCD9360_CPE_SS_LPASS_IPC_OUT_14 (0x0000025F) -#define WCD9360_CPE_SS_LPASS_IPC_OUT_15 (0x00000260) -#define WCD9360_CPE_SS_LPASS_ARB_CTL (0x00000261) -#define WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_0 (0x00000271) -#define WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_1 (0x00000272) -#define WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_0 (0x00000273) -#define WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_1 (0x00000274) -#define WCD9360_SOC_MAD_MAIN_CTL_1 (0x00000281) -#define WCD9360_SOC_MAD_MAIN_CTL_2 (0x00000282) -#define WCD9360_SOC_MAD_AUDIO_CTL_1 (0x00000283) -#define WCD9360_SOC_MAD_AUDIO_CTL_2 (0x00000284) -#define WCD9360_SOC_MAD_AUDIO_CTL_3 (0x00000285) -#define WCD9360_SOC_MAD_AUDIO_CTL_4 (0x00000286) -#define WCD9360_SOC_MAD_AUDIO_CTL_5 (0x00000287) -#define WCD9360_SOC_MAD_AUDIO_CTL_6 (0x00000288) -#define WCD9360_SOC_MAD_AUDIO_CTL_7 (0x00000289) -#define WCD9360_SOC_MAD_AUDIO_CTL_8 (0x0000028A) -#define WCD9360_SOC_MAD_AUDIO_IIR_CTL_PTR (0x0000028B) -#define WCD9360_SOC_MAD_AUDIO_IIR_CTL_VAL (0x0000028C) -#define WCD9360_SOC_MAD_ULTR_CTL_1 (0x0000028D) -#define WCD9360_SOC_MAD_ULTR_CTL_2 (0x0000028E) -#define WCD9360_SOC_MAD_ULTR_CTL_3 (0x0000028F) -#define WCD9360_SOC_MAD_ULTR_CTL_4 (0x00000290) -#define WCD9360_SOC_MAD_ULTR_CTL_5 (0x00000291) -#define WCD9360_SOC_MAD_ULTR_CTL_6 (0x00000292) -#define WCD9360_SOC_MAD_ULTR_CTL_7 (0x00000293) -#define WCD9360_SOC_MAD_BEACON_CTL_1 (0x00000294) -#define WCD9360_SOC_MAD_BEACON_CTL_2 (0x00000295) -#define WCD9360_SOC_MAD_BEACON_CTL_3 (0x00000296) -#define WCD9360_SOC_MAD_BEACON_CTL_4 (0x00000297) -#define WCD9360_SOC_MAD_BEACON_CTL_5 (0x00000298) -#define WCD9360_SOC_MAD_BEACON_CTL_6 (0x00000299) -#define WCD9360_SOC_MAD_BEACON_CTL_7 (0x0000029A) -#define WCD9360_SOC_MAD_BEACON_CTL_8 (0x0000029B) -#define WCD9360_SOC_MAD_BEACON_IIR_CTL_PTR (0x0000029C) -#define WCD9360_SOC_MAD_BEACON_IIR_CTL_VAL (0x0000029D) -#define WCD9360_SOC_MAD_INP_SEL (0x0000029E) -#define WCD9360_SOC_MAD_MAD2_INP_SEL (0x0000029F) -#define WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_CTRL (0x000002B1) -#define WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_STATUS (0x000002B2) -#define WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_FS (0x000002B3) -#define WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_IN_SEL (0x000002B4) -#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT0 (0x000002C1) -#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT1 (0x000002C2) -#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT2 (0x000002C3) -#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT3 (0x000002C4) -#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT4 (0x000002C5) -#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT5 (0x000002C6) -#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT6 (0x000002C7) -#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT7 (0x000002C8) -#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT8 (0x000002C9) -#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT9 (0x000002CA) -#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT10 (0x000002CB) -#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT11 (0x000002CC) -#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT12 (0x000002CD) -#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT13 (0x000002CE) -#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT14 (0x000002CF) -#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT15 (0x000002D0) -#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT0 (0x000002D1) -#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT1 (0x000002D2) -#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT2 (0x000002D3) -#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT3 (0x000002D4) -#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT4 (0x000002D5) -#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT5 (0x000002D6) -#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT6 (0x000002D7) -#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT7 (0x000002D8) -#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT8 (0x000002D9) -#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT9 (0x000002DA) -#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT10 (0x000002DB) -#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT11 (0x000002DC) -#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT12 (0x000002DD) -#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT13 (0x000002DE) -#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT14 (0x000002DF) -#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT15 (0x000002E0) -#define WCD9360_PAGE4_PAGE_REGISTER (0x00000400) -#define WCD9360_INTR_CFG (0x00000401) -#define WCD9360_INTR_CLR_COMMIT (0x00000402) -#define WCD9360_INTR_PIN1_MASK0 (0x00000409) -#define WCD9360_INTR_PIN1_MASK1 (0x0000040A) -#define WCD9360_INTR_PIN1_MASK2 (0x0000040B) -#define WCD9360_INTR_PIN1_MASK3 (0x0000040C) -#define WCD9360_INTR_PIN1_STATUS0 (0x00000411) -#define WCD9360_INTR_PIN1_STATUS1 (0x00000412) -#define WCD9360_INTR_PIN1_STATUS2 (0x00000413) -#define WCD9360_INTR_PIN1_STATUS3 (0x00000414) -#define WCD9360_INTR_PIN1_CLEAR0 (0x00000419) -#define WCD9360_INTR_PIN1_CLEAR1 (0x0000041A) -#define WCD9360_INTR_PIN1_CLEAR2 (0x0000041B) -#define WCD9360_INTR_PIN1_CLEAR3 (0x0000041C) -#define WCD9360_INTR_PIN2_MASK3 (0x00000424) -#define WCD9360_INTR_PIN2_STATUS3 (0x0000042C) -#define WCD9360_INTR_PIN2_CLEAR3 (0x00000434) -#define WCD9360_INTR_CPESS_SUMRY_MASK2 (0x0000043B) -#define WCD9360_INTR_CPESS_SUMRY_MASK3 (0x0000043C) -#define WCD9360_INTR_CPESS_SUMRY_STATUS2 (0x00000443) -#define WCD9360_INTR_CPESS_SUMRY_STATUS3 (0x00000444) -#define WCD9360_INTR_CPESS_SUMRY_CLEAR2 (0x0000044B) -#define WCD9360_INTR_CPESS_SUMRY_CLEAR3 (0x0000044C) -#define WCD9360_INTR_LEVEL0 (0x00000461) -#define WCD9360_INTR_LEVEL1 (0x00000462) -#define WCD9360_INTR_LEVEL2 (0x00000463) -#define WCD9360_INTR_LEVEL3 (0x00000464) -#define WCD9360_INTR_BYPASS0 (0x00000469) -#define WCD9360_INTR_BYPASS1 (0x0000046A) -#define WCD9360_INTR_BYPASS2 (0x0000046B) -#define WCD9360_INTR_BYPASS3 (0x0000046C) -#define WCD9360_INTR_SET0 (0x00000471) -#define WCD9360_INTR_SET1 (0x00000472) -#define WCD9360_INTR_SET2 (0x00000473) -#define WCD9360_INTR_SET3 (0x00000474) -#define WCD9360_INTR_CODEC_MISC_MASK (0x000004B1) -#define WCD9360_INTR_CODEC_MISC_STATUS (0x000004B2) -#define WCD9360_INTR_CODEC_MISC_CLEAR (0x000004B3) -#define WCD9360_ANA_PAGE_REGISTER (0x00000600) -#define WCD9360_ANA_BIAS (0x00000601) -#define WCD9360_ANA_AMIC_INPUT_SWITCH_CTL (0x00000602) -#define WCD9360_ANA_RCO (0x00000603) -#define WCD9360_ANA_BUCK_CTL (0x00000606) -#define WCD9360_ANA_BUCK_STATUS (0x00000607) -#define WCD9360_ANA_EAR (0x0000060A) -#define WCD9360_ANA_MAD_SETUP (0x0000060D) -#define WCD9360_ANA_AMIC1 (0x0000060E) -#define WCD9360_ANA_AMIC2 (0x0000060F) -#define WCD9360_ANA_AMIC3 (0x00000610) -#define WCD9360_ANA_AMIC4 (0x00000611) -#define WCD9360_ANA_MICB1 (0x00000622) -#define WCD9360_ANA_MICB2 (0x00000623) -#define WCD9360_ANA_MICB3 (0x00000625) -#define WCD9360_ANA_MICB4 (0x00000626) -#define WCD9360_BIAS_CTL (0x00000628) -#define WCD9360_BIAS_VBG_FINE_ADJ (0x00000629) -#define WCD9360_RCO_CTRL_1 (0x0000062E) -#define WCD9360_RCO_CTRL_2 (0x0000062F) -#define WCD9360_RCO_CAL (0x00000630) -#define WCD9360_RCO_CAL_1 (0x00000631) -#define WCD9360_RCO_CAL_2 (0x00000632) -#define WCD9360_RCO_TEST_CTRL (0x00000633) -#define WCD9360_RCO_CAL_OUT_1 (0x00000634) -#define WCD9360_RCO_CAL_OUT_2 (0x00000635) -#define WCD9360_RCO_CAL_OUT_3 (0x00000636) -#define WCD9360_RCO_CAL_OUT_4 (0x00000637) -#define WCD9360_RCO_CAL_OUT_5 (0x00000638) -#define WCD9360_SIDO_MODE_1 (0x0000063A) -#define WCD9360_SIDO_MODE_2 (0x0000063B) -#define WCD9360_SIDO_MODE_3 (0x0000063C) -#define WCD9360_SIDO_MODE_4 (0x0000063D) -#define WCD9360_SIDO_VCL_1 (0x0000063E) -#define WCD9360_SIDO_VCL_2 (0x0000063F) -#define WCD9360_SIDO_VCL_3 (0x00000640) -#define WCD9360_SIDO_CCL_1 (0x00000641) -#define WCD9360_SIDO_CCL_2 (0x00000642) -#define WCD9360_SIDO_CCL_3 (0x00000643) -#define WCD9360_SIDO_CCL_4 (0x00000644) -#define WCD9360_SIDO_CCL_5 (0x00000645) -#define WCD9360_SIDO_CCL_6 (0x00000646) -#define WCD9360_SIDO_CCL_7 (0x00000647) -#define WCD9360_SIDO_CCL_8 (0x00000648) -#define WCD9360_SIDO_CCL_9 (0x00000649) -#define WCD9360_SIDO_CCL_10 (0x0000064A) -#define WCD9360_SIDO_FILTER_1 (0x0000064B) -#define WCD9360_SIDO_FILTER_2 (0x0000064C) -#define WCD9360_SIDO_DRIVER_1 (0x0000064D) -#define WCD9360_SIDO_DRIVER_2 (0x0000064E) -#define WCD9360_SIDO_DRIVER_3 (0x0000064F) -#define WCD9360_SIDO_CAL_CODE_EXT_1 (0x00000650) -#define WCD9360_SIDO_CAL_CODE_EXT_2 (0x00000651) -#define WCD9360_SIDO_CAL_CODE_OUT_1 (0x00000652) -#define WCD9360_SIDO_CAL_CODE_OUT_2 (0x00000653) -#define WCD9360_SIDO_TEST_1 (0x00000654) -#define WCD9360_SIDO_TEST_2 (0x00000655) -#define WCD9360_LDOH_MODE (0x00000667) -#define WCD9360_LDOH_BIAS (0x00000668) -#define WCD9360_LDOH_STB_LOADS (0x00000669) -#define WCD9360_LDOH_SLOWRAMP (0x0000066A) -#define WCD9360_MICB1_TEST_CTL_1 (0x0000066B) -#define WCD9360_MICB1_TEST_CTL_2 (0x0000066C) -#define WCD9360_MICB1_TEST_CTL_3 (0x0000066D) -#define WCD9360_MICB2_TEST_CTL_1 (0x0000066E) -#define WCD9360_MICB2_TEST_CTL_2 (0x0000066F) -#define WCD9360_MICB2_TEST_CTL_3 (0x00000670) -#define WCD9360_MICB3_TEST_CTL_1 (0x00000671) -#define WCD9360_MICB3_TEST_CTL_2 (0x00000672) -#define WCD9360_MICB3_TEST_CTL_3 (0x00000673) -#define WCD9360_MICB4_TEST_CTL_1 (0x00000674) -#define WCD9360_MICB4_TEST_CTL_2 (0x00000675) -#define WCD9360_MICB4_TEST_CTL_3 (0x00000676) -#define WCD9360_TX_COM_ADC_VCM (0x00000677) -#define WCD9360_TX_COM_BIAS_ATEST (0x00000678) -#define WCD9360_TX_COM_ADC_INT1_IB (0x00000679) -#define WCD9360_TX_COM_ADC_INT2_IB (0x0000067A) -#define WCD9360_TX_COM_TXFE_DIV_CTL (0x0000067B) -#define WCD9360_TX_COM_TXFE_DIV_START (0x0000067C) -#define WCD9360_TX_COM_TXFE_DIV_STOP_9P6M (0x0000067D) -#define WCD9360_TX_COM_TXFE_DIV_STOP_12P288M (0x0000067E) -#define WCD9360_TX_1_2_TEST_EN (0x0000067F) -#define WCD9360_TX_1_2_ADC_IB (0x00000680) -#define WCD9360_TX_1_2_ATEST_REFCTL (0x00000681) -#define WCD9360_TX_1_2_TEST_CTL (0x00000682) -#define WCD9360_TX_1_2_TEST_BLK_EN (0x00000683) -#define WCD9360_TX_1_2_TXFE_CLKDIV (0x00000684) -#define WCD9360_TX_1_2_SAR1_ERR (0x00000685) -#define WCD9360_TX_1_2_SAR2_ERR (0x00000686) -#define WCD9360_TX_3_4_TEST_EN (0x00000687) -#define WCD9360_TX_3_4_ADC_IB (0x00000688) -#define WCD9360_TX_3_4_ATEST_REFCTL (0x00000689) -#define WCD9360_TX_3_4_TEST_CTL (0x0000068A) -#define WCD9360_TX_3_4_TEST_BLK_EN (0x0000068B) -#define WCD9360_TX_3_4_TXFE_CLKDIV (0x0000068C) -#define WCD9360_TX_3_4_SAR1_ERR (0x0000068D) -#define WCD9360_TX_3_4_SAR2_ERR (0x0000068E) -#define WCD9360_RX_RX_EAR_BIAS_CON_1 (0x000006B3) -#define WCD9360_RX_RX_EAR_BIAS_CON_2 (0x000006B4) -#define WCD9360_RX_RX_AUX_BIAS_CON_1 (0x000006B5) -#define WCD9360_RX_RX_AUX_BIAS_CON_2 (0x000006B6) -#define WCD9360_RX_RX_BIAS_ATEST (0x000006B7) -#define WCD9360_RX_RXTOP_RESERVED (0x000006B8) -#define WCD9360_EAR_EAR_EN_REG (0x000006E1) -#define WCD9360_EAR_EAR_PA_CON (0x000006E2) -#define WCD9360_EAR_EAR_SP_CON (0x000006E3) -#define WCD9360_EAR_EAR_DAC_CON (0x000006E4) -#define WCD9360_EAR_EAR_CNP_FSM_CON (0x000006E5) -#define WCD9360_EAR_DAC_CTL_TEST (0x000006E6) -#define WCD9360_EAR_STATUS_REG (0x000006E7) -#define WCD9360_EAR_EAR_COMPANDER_CON (0x000006E8) -#define WCD9360_ANA_NEW_PAGE_REGISTER (0x00000700) -#define WCD9360_CLK_SYS_PLL_ENABLES (0x0000070E) -#define WCD9360_CLK_SYS_PLL_PRESET (0x0000070F) -#define WCD9360_CLK_SYS_PLL_STATUS (0x00000710) -#define WCD9360_CLK_SYS_MCLK_PRG (0x00000711) -#define WCD9360_CLK_SYS_MCLK2_PRG1 (0x00000712) -#define WCD9360_CLK_SYS_MCLK_MISC (0x00000713) -#define WCD9360_SIDO_NEW_VOUT_A_STARTUP (0x0000071B) -#define WCD9360_SIDO_NEW_VOUT_D_STARTUP (0x0000071C) -#define WCD9360_SIDO_NEW_VOUT_D_FREQ1 (0x0000071D) -#define WCD9360_SIDO_NEW_VOUT_D_FREQ2 (0x0000071E) -#define WCD9360_AUX_ANA_EAR (0x00000728) -#define WCD9360_LDORXTX_LDORXTX (0x00000729) -#define WCD9360_DIE_CRACK_CTL (0x0000072A) -#define WCD9360_DIE_CRACK_OUT (0x0000072B) -#define WCD9360_LOOP_BACK_EN (0x0000072C) -#define WCD9360_CLK_SYS_INT_POST_DIV_REG0 (0x0000076C) -#define WCD9360_CLK_SYS_INT_POST_DIV_REG1 (0x0000076D) -#define WCD9360_CLK_SYS_INT_REF_DIV_REG0 (0x0000076E) -#define WCD9360_CLK_SYS_INT_REF_DIV_REG1 (0x0000076F) -#define WCD9360_CLK_SYS_INT_FILTER_REG0 (0x00000770) -#define WCD9360_CLK_SYS_INT_FILTER_REG1 (0x00000771) -#define WCD9360_CLK_SYS_INT_PLL_L_VAL (0x00000772) -#define WCD9360_CLK_SYS_INT_PLL_M_VAL (0x00000773) -#define WCD9360_CLK_SYS_INT_PLL_N_VAL (0x00000774) -#define WCD9360_CLK_SYS_INT_TEST_REG0 (0x00000775) -#define WCD9360_CLK_SYS_INT_PFD_CP_DSM_PROG (0x00000776) -#define WCD9360_CLK_SYS_INT_VCO_PROG (0x00000777) -#define WCD9360_CLK_SYS_INT_TEST_REG1 (0x00000778) -#define WCD9360_CLK_SYS_INT_LDO_LOCK_CFG (0x00000779) -#define WCD9360_CLK_SYS_INT_DIG_LOCK_DET_CFG (0x0000077A) -#define WCD9360_CLK_SYS_INT_CLK_TEST1 (0x0000077B) -#define WCD9360_CLK_SYS_INT_CLK_TEST2 (0x0000077C) -#define WCD9360_CLK_SYS_INT_CLK_TEST3 (0x0000077D) -#define WCD9360_SIDO_NEW_INT_RAMP_STATUS (0x00000796) -#define WCD9360_SIDO_NEW_INT_SPARE_1 (0x00000797) -#define WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_A (0x00000798) -#define WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_D (0x00000799) -#define WCD9360_SIDO_NEW_INT_RAMP_INC_WAIT (0x0000079A) -#define WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_CTL (0x0000079B) -#define WCD9360_SIDO_NEW_INT_RAMP_IBLEED_CTL (0x0000079C) -#define WCD9360_SIDO_NEW_INT_DEBUG_CPROVR_TEST (0x0000079D) -#define WCD9360_SIDO_NEW_INT_RAMP_CTL_A (0x0000079E) -#define WCD9360_SIDO_NEW_INT_RAMP_CTL_D (0x0000079F) -#define WCD9360_SIDO_NEW_INT_RAMP_TIMEOUT_PERIOD (0x000007A0) -#define WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING1 (0x000007A1) -#define WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING2 (0x000007A2) -#define WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING3 (0x000007A3) -#define WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL1 (0x000007A4) -#define WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL2 (0x000007A5) -#define WCD9360_EAR_INT_NEW_EAR_CHOPPER_CON (0x000007B7) -#define WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON1 (0x000007B8) -#define WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON2 (0x000007B9) -#define WCD9360_EAR_INT_NEW_EAR_DYNAMIC_BIAS (0x000007BA) -#define WCD9360_AUX_INT_AUX_EN_REG (0x000007BD) -#define WCD9360_AUX_INT_AUX_PA_CON (0x000007BE) -#define WCD9360_AUX_INT_AUX_SP_CON (0x000007BF) -#define WCD9360_AUX_INT_AUX_DAC_CON (0x000007C0) -#define WCD9360_AUX_INT_AUX_CNP_FSM_CON (0x000007C1) -#define WCD9360_AUX_INT_AUX_TEST (0x000007C2) -#define WCD9360_AUX_INT_STATUS_REG (0x000007C3) -#define WCD9360_AUX_INT_AUX_MISC (0x000007C4) -#define WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL1 (0x000007C5) -#define WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL2 (0x000007C6) -#define WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL3 (0x000007C7) -#define WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL4 (0x000007C8) -#define WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL5 (0x000007C9) -#define WCD9360_LDORXTX_INT_ANA_LDORXTX_STATUS (0x000007CA) -#define WCD9360_DIE_CRACK_INT_INT1 (0x000007CC) -#define WCD9360_DIE_CRACK_INT_INT2 (0x000007CD) -#define WCD9360_LOOP_BACK_INT_SPARE (0x000007CE) -#define WCD9360_PAGE10_PAGE_REGISTER (0x00000A00) -#define WCD9360_CDC_ANC0_CLK_RESET_CTL (0x00000A01) -#define WCD9360_CDC_ANC0_MODE_1_CTL (0x00000A02) -#define WCD9360_CDC_ANC0_MODE_2_CTL (0x00000A03) -#define WCD9360_CDC_ANC0_FF_SHIFT (0x00000A04) -#define WCD9360_CDC_ANC0_FB_SHIFT (0x00000A05) -#define WCD9360_CDC_ANC0_LPF_FF_A_CTL (0x00000A06) -#define WCD9360_CDC_ANC0_LPF_FF_B_CTL (0x00000A07) -#define WCD9360_CDC_ANC0_LPF_FB_CTL (0x00000A08) -#define WCD9360_CDC_ANC0_SMLPF_CTL (0x00000A09) -#define WCD9360_CDC_ANC0_DCFLT_SHIFT_CTL (0x00000A0A) -#define WCD9360_CDC_ANC0_IIR_ADAPT_CTL (0x00000A0B) -#define WCD9360_CDC_ANC0_IIR_COEFF_1_CTL (0x00000A0C) -#define WCD9360_CDC_ANC0_IIR_COEFF_2_CTL (0x00000A0D) -#define WCD9360_CDC_ANC0_FF_A_GAIN_CTL (0x00000A0E) -#define WCD9360_CDC_ANC0_FF_B_GAIN_CTL (0x00000A0F) -#define WCD9360_CDC_ANC0_FB_GAIN_CTL (0x00000A10) -#define WCD9360_CDC_TX0_TX_PATH_CTL (0x00000A31) -#define WCD9360_CDC_TX0_TX_PATH_CFG0 (0x00000A32) -#define WCD9360_CDC_TX0_TX_PATH_CFG1 (0x00000A33) -#define WCD9360_CDC_TX0_TX_VOL_CTL (0x00000A34) -#define WCD9360_CDC_TX0_TX_PATH_192_CTL (0x00000A35) -#define WCD9360_CDC_TX0_TX_PATH_192_CFG (0x00000A36) -#define WCD9360_CDC_TX0_TX_PATH_SEC0 (0x00000A37) -#define WCD9360_CDC_TX0_TX_PATH_SEC1 (0x00000A38) -#define WCD9360_CDC_TX0_TX_PATH_SEC2 (0x00000A39) -#define WCD9360_CDC_TX0_TX_PATH_SEC3 (0x00000A3A) -#define WCD9360_CDC_TX0_TX_PATH_SEC4 (0x00000A3B) -#define WCD9360_CDC_TX0_TX_PATH_SEC5 (0x00000A3C) -#define WCD9360_CDC_TX0_TX_PATH_SEC6 (0x00000A3D) -#define WCD9360_CDC_TX1_TX_PATH_CTL (0x00000A41) -#define WCD9360_CDC_TX1_TX_PATH_CFG0 (0x00000A42) -#define WCD9360_CDC_TX1_TX_PATH_CFG1 (0x00000A43) -#define WCD9360_CDC_TX1_TX_VOL_CTL (0x00000A44) -#define WCD9360_CDC_TX1_TX_PATH_192_CTL (0x00000A45) -#define WCD9360_CDC_TX1_TX_PATH_192_CFG (0x00000A46) -#define WCD9360_CDC_TX1_TX_PATH_SEC0 (0x00000A47) -#define WCD9360_CDC_TX1_TX_PATH_SEC1 (0x00000A48) -#define WCD9360_CDC_TX1_TX_PATH_SEC2 (0x00000A49) -#define WCD9360_CDC_TX1_TX_PATH_SEC3 (0x00000A4A) -#define WCD9360_CDC_TX1_TX_PATH_SEC4 (0x00000A4B) -#define WCD9360_CDC_TX1_TX_PATH_SEC5 (0x00000A4C) -#define WCD9360_CDC_TX1_TX_PATH_SEC6 (0x00000A4D) -#define WCD9360_CDC_TX2_TX_PATH_CTL (0x00000A51) -#define WCD9360_CDC_TX2_TX_PATH_CFG0 (0x00000A52) -#define WCD9360_CDC_TX2_TX_PATH_CFG1 (0x00000A53) -#define WCD9360_CDC_TX2_TX_VOL_CTL (0x00000A54) -#define WCD9360_CDC_TX2_TX_PATH_192_CTL (0x00000A55) -#define WCD9360_CDC_TX2_TX_PATH_192_CFG (0x00000A56) -#define WCD9360_CDC_TX2_TX_PATH_SEC0 (0x00000A57) -#define WCD9360_CDC_TX2_TX_PATH_SEC1 (0x00000A58) -#define WCD9360_CDC_TX2_TX_PATH_SEC2 (0x00000A59) -#define WCD9360_CDC_TX2_TX_PATH_SEC3 (0x00000A5A) -#define WCD9360_CDC_TX2_TX_PATH_SEC4 (0x00000A5B) -#define WCD9360_CDC_TX2_TX_PATH_SEC5 (0x00000A5C) -#define WCD9360_CDC_TX2_TX_PATH_SEC6 (0x00000A5D) -#define WCD9360_CDC_TX3_TX_PATH_CTL (0x00000A61) -#define WCD9360_CDC_TX3_TX_PATH_CFG0 (0x00000A62) -#define WCD9360_CDC_TX3_TX_PATH_CFG1 (0x00000A63) -#define WCD9360_CDC_TX3_TX_VOL_CTL (0x00000A64) -#define WCD9360_CDC_TX3_TX_PATH_192_CTL (0x00000A65) -#define WCD9360_CDC_TX3_TX_PATH_192_CFG (0x00000A66) -#define WCD9360_CDC_TX3_TX_PATH_SEC0 (0x00000A67) -#define WCD9360_CDC_TX3_TX_PATH_SEC1 (0x00000A68) -#define WCD9360_CDC_TX3_TX_PATH_SEC2 (0x00000A69) -#define WCD9360_CDC_TX3_TX_PATH_SEC3 (0x00000A6A) -#define WCD9360_CDC_TX3_TX_PATH_SEC4 (0x00000A6B) -#define WCD9360_CDC_TX3_TX_PATH_SEC5 (0x00000A6C) -#define WCD9360_CDC_TX3_TX_PATH_SEC6 (0x00000A6D) -#define WCD9360_CDC_TX4_TX_PATH_CTL (0x00000A71) -#define WCD9360_CDC_TX4_TX_PATH_CFG0 (0x00000A72) -#define WCD9360_CDC_TX4_TX_PATH_CFG1 (0x00000A73) -#define WCD9360_CDC_TX4_TX_VOL_CTL (0x00000A74) -#define WCD9360_CDC_TX4_TX_PATH_192_CTL (0x00000A75) -#define WCD9360_CDC_TX4_TX_PATH_192_CFG (0x00000A76) -#define WCD9360_CDC_TX4_TX_PATH_SEC0 (0x00000A77) -#define WCD9360_CDC_TX4_TX_PATH_SEC1 (0x00000A78) -#define WCD9360_CDC_TX4_TX_PATH_SEC2 (0x00000A79) -#define WCD9360_CDC_TX4_TX_PATH_SEC3 (0x00000A7A) -#define WCD9360_CDC_TX4_TX_PATH_SEC4 (0x00000A7B) -#define WCD9360_CDC_TX4_TX_PATH_SEC5 (0x00000A7C) -#define WCD9360_CDC_TX4_TX_PATH_SEC6 (0x00000A7D) -#define WCD9360_CDC_TX5_TX_PATH_CTL (0x00000A81) -#define WCD9360_CDC_TX5_TX_PATH_CFG0 (0x00000A82) -#define WCD9360_CDC_TX5_TX_PATH_CFG1 (0x00000A83) -#define WCD9360_CDC_TX5_TX_VOL_CTL (0x00000A84) -#define WCD9360_CDC_TX5_TX_PATH_192_CTL (0x00000A85) -#define WCD9360_CDC_TX5_TX_PATH_192_CFG (0x00000A86) -#define WCD9360_CDC_TX5_TX_PATH_SEC0 (0x00000A87) -#define WCD9360_CDC_TX5_TX_PATH_SEC1 (0x00000A88) -#define WCD9360_CDC_TX5_TX_PATH_SEC2 (0x00000A89) -#define WCD9360_CDC_TX5_TX_PATH_SEC3 (0x00000A8A) -#define WCD9360_CDC_TX5_TX_PATH_SEC4 (0x00000A8B) -#define WCD9360_CDC_TX5_TX_PATH_SEC5 (0x00000A8C) -#define WCD9360_CDC_TX5_TX_PATH_SEC6 (0x00000A8D) -#define WCD9360_CDC_TX6_TX_PATH_CTL (0x00000A91) -#define WCD9360_CDC_TX6_TX_PATH_CFG0 (0x00000A92) -#define WCD9360_CDC_TX6_TX_PATH_CFG1 (0x00000A93) -#define WCD9360_CDC_TX6_TX_VOL_CTL (0x00000A94) -#define WCD9360_CDC_TX6_TX_PATH_192_CTL (0x00000A95) -#define WCD9360_CDC_TX6_TX_PATH_192_CFG (0x00000A96) -#define WCD9360_CDC_TX6_TX_PATH_SEC0 (0x00000A97) -#define WCD9360_CDC_TX6_TX_PATH_SEC1 (0x00000A98) -#define WCD9360_CDC_TX6_TX_PATH_SEC2 (0x00000A99) -#define WCD9360_CDC_TX6_TX_PATH_SEC3 (0x00000A9A) -#define WCD9360_CDC_TX6_TX_PATH_SEC4 (0x00000A9B) -#define WCD9360_CDC_TX6_TX_PATH_SEC5 (0x00000A9C) -#define WCD9360_CDC_TX6_TX_PATH_SEC6 (0x00000A9D) -#define WCD9360_CDC_TX7_TX_PATH_CTL (0x00000AA1) -#define WCD9360_CDC_TX7_TX_PATH_CFG0 (0x00000AA2) -#define WCD9360_CDC_TX7_TX_PATH_CFG1 (0x00000AA3) -#define WCD9360_CDC_TX7_TX_VOL_CTL (0x00000AA4) -#define WCD9360_CDC_TX7_TX_PATH_192_CTL (0x00000AA5) -#define WCD9360_CDC_TX7_TX_PATH_192_CFG (0x00000AA6) -#define WCD9360_CDC_TX7_TX_PATH_SEC0 (0x00000AA7) -#define WCD9360_CDC_TX7_TX_PATH_SEC1 (0x00000AA8) -#define WCD9360_CDC_TX7_TX_PATH_SEC2 (0x00000AA9) -#define WCD9360_CDC_TX7_TX_PATH_SEC3 (0x00000AAA) -#define WCD9360_CDC_TX7_TX_PATH_SEC4 (0x00000AAB) -#define WCD9360_CDC_TX7_TX_PATH_SEC5 (0x00000AAC) -#define WCD9360_CDC_TX7_TX_PATH_SEC6 (0x00000AAD) -#define WCD9360_CDC_TX8_TX_PATH_CTL (0x00000AB1) -#define WCD9360_CDC_TX8_TX_PATH_CFG0 (0x00000AB2) -#define WCD9360_CDC_TX8_TX_PATH_CFG1 (0x00000AB3) -#define WCD9360_CDC_TX8_TX_VOL_CTL (0x00000AB4) -#define WCD9360_CDC_TX8_TX_PATH_192_CTL (0x00000AB5) -#define WCD9360_CDC_TX8_TX_PATH_192_CFG (0x00000AB6) -#define WCD9360_CDC_TX8_TX_PATH_SEC0 (0x00000AB7) -#define WCD9360_CDC_TX8_TX_PATH_SEC1 (0x00000AB8) -#define WCD9360_CDC_TX8_TX_PATH_SEC2 (0x00000AB9) -#define WCD9360_CDC_TX8_TX_PATH_SEC3 (0x00000ABA) -#define WCD9360_CDC_TX8_TX_PATH_SEC4 (0x00000ABB) -#define WCD9360_CDC_TX8_TX_PATH_SEC5 (0x00000ABC) -#define WCD9360_CDC_TX8_TX_PATH_SEC6 (0x00000ABD) -#define WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL (0x00000AC2) -#define WCD9360_CDC_TX9_SPKR_PROT_PATH_CFG0 (0x00000AC3) -#define WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL (0x00000AC6) -#define WCD9360_CDC_TX10_SPKR_PROT_PATH_CFG0 (0x00000AC7) -#define WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL (0x00000ACA) -#define WCD9360_CDC_TX11_SPKR_PROT_PATH_CFG0 (0x00000ACB) -#define WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL (0x00000ACE) -#define WCD9360_CDC_TX12_SPKR_PROT_PATH_CFG0 (0x00000ACF) -#define WCD9360_PAGE11_PAGE_REGISTER (0x00000B00) -#define WCD9360_CDC_COMPANDER0_CTL0 (0x00000B21) -#define WCD9360_CDC_COMPANDER0_CTL1 (0x00000B22) -#define WCD9360_CDC_COMPANDER0_CTL2 (0x00000B23) -#define WCD9360_CDC_COMPANDER0_CTL3 (0x00000B24) -#define WCD9360_CDC_COMPANDER0_CTL4 (0x00000B25) -#define WCD9360_CDC_COMPANDER0_CTL5 (0x00000B26) -#define WCD9360_CDC_COMPANDER0_CTL6 (0x00000B27) -#define WCD9360_CDC_COMPANDER0_CTL7 (0x00000B28) -#define WCD9360_CDC_COMPANDER7_CTL0 (0x00000B31) -#define WCD9360_CDC_COMPANDER7_CTL1 (0x00000B32) -#define WCD9360_CDC_COMPANDER7_CTL2 (0x00000B33) -#define WCD9360_CDC_COMPANDER7_CTL3 (0x00000B34) -#define WCD9360_CDC_COMPANDER7_CTL4 (0x00000B35) -#define WCD9360_CDC_COMPANDER7_CTL5 (0x00000B36) -#define WCD9360_CDC_COMPANDER7_CTL6 (0x00000B37) -#define WCD9360_CDC_COMPANDER7_CTL7 (0x00000B38) -#define WCD9360_CDC_COMPANDER8_CTL0 (0x00000B39) -#define WCD9360_CDC_COMPANDER8_CTL1 (0x00000B3A) -#define WCD9360_CDC_COMPANDER8_CTL2 (0x00000B3B) -#define WCD9360_CDC_COMPANDER8_CTL3 (0x00000B3C) -#define WCD9360_CDC_COMPANDER8_CTL4 (0x00000B3D) -#define WCD9360_CDC_COMPANDER8_CTL5 (0x00000B3E) -#define WCD9360_CDC_COMPANDER8_CTL6 (0x00000B3F) -#define WCD9360_CDC_COMPANDER8_CTL7 (0x00000B40) -#define WCD9360_CDC_RX0_RX_PATH_CTL (0x00000B41) -#define WCD9360_CDC_RX0_RX_PATH_CFG0 (0x00000B42) -#define WCD9360_CDC_RX0_RX_PATH_CFG1 (0x00000B43) -#define WCD9360_CDC_RX0_RX_PATH_CFG2 (0x00000B44) -#define WCD9360_CDC_RX0_RX_VOL_CTL (0x00000B45) -#define WCD9360_CDC_RX0_RX_PATH_MIX_CTL (0x00000B46) -#define WCD9360_CDC_RX0_RX_PATH_MIX_CFG (0x00000B47) -#define WCD9360_CDC_RX0_RX_VOL_MIX_CTL (0x00000B48) -#define WCD9360_CDC_RX0_RX_PATH_SEC0 (0x00000B49) -#define WCD9360_CDC_RX0_RX_PATH_SEC1 (0x00000B4A) -#define WCD9360_CDC_RX0_RX_PATH_SEC2 (0x00000B4B) -#define WCD9360_CDC_RX0_RX_PATH_SEC3 (0x00000B4C) -#define WCD9360_CDC_RX0_RX_PATH_SEC5 (0x00000B4E) -#define WCD9360_CDC_RX0_RX_PATH_SEC6 (0x00000B4F) -#define WCD9360_CDC_RX0_RX_PATH_SEC7 (0x00000B50) -#define WCD9360_CDC_RX0_RX_PATH_MIX_SEC0 (0x00000B51) -#define WCD9360_CDC_RX0_RX_PATH_MIX_SEC1 (0x00000B52) -#define WCD9360_CDC_RX0_RX_PATH_DSMDEM_CTL (0x00000B53) -#define WCD9360_CDC_RX9_RX_PATH_CTL (0x00000BA5) -#define WCD9360_CDC_RX9_RX_PATH_CFG0 (0x00000BA6) -#define WCD9360_CDC_RX9_RX_PATH_CFG1 (0x00000BA7) -#define WCD9360_CDC_RX9_RX_PATH_CFG2 (0x00000BA8) -#define WCD9360_CDC_RX9_RX_VOL_CTL (0x00000BA9) -#define WCD9360_CDC_RX9_RX_PATH_MIX_CTL (0x00000BAA) -#define WCD9360_CDC_RX9_RX_PATH_MIX_CFG (0x00000BAB) -#define WCD9360_CDC_RX9_RX_VOL_MIX_CTL (0x00000BAC) -#define WCD9360_CDC_RX9_RX_PATH_SEC0 (0x00000BAD) -#define WCD9360_CDC_RX9_RX_PATH_SEC1 (0x00000BAE) -#define WCD9360_CDC_RX9_RX_PATH_SEC2 (0x00000BAF) -#define WCD9360_CDC_RX9_RX_PATH_SEC3 (0x00000BB0) -#define WCD9360_CDC_RX9_RX_PATH_SEC5 (0x00000BB2) -#define WCD9360_CDC_RX9_RX_PATH_SEC6 (0x00000BB3) -#define WCD9360_CDC_RX9_RX_PATH_SEC7 (0x00000BB4) -#define WCD9360_CDC_RX9_RX_PATH_MIX_SEC0 (0x00000BB5) -#define WCD9360_CDC_RX9_RX_PATH_MIX_SEC1 (0x00000BB6) -#define WCD9360_CDC_RX9_RX_PATH_DSMDEM_CTL (0x00000BB7) -#define WCD9360_CDC_RX7_RX_PATH_CTL (0x00000BCD) -#define WCD9360_CDC_RX7_RX_PATH_CFG0 (0x00000BCE) -#define WCD9360_CDC_RX7_RX_PATH_CFG1 (0x00000BCF) -#define WCD9360_CDC_RX7_RX_PATH_CFG2 (0x00000BD0) -#define WCD9360_CDC_RX7_RX_VOL_CTL (0x00000BD1) -#define WCD9360_CDC_RX7_RX_PATH_MIX_CTL (0x00000BD2) -#define WCD9360_CDC_RX7_RX_PATH_MIX_CFG (0x00000BD3) -#define WCD9360_CDC_RX7_RX_VOL_MIX_CTL (0x00000BD4) -#define WCD9360_CDC_RX7_RX_PATH_SEC0 (0x00000BD5) -#define WCD9360_CDC_RX7_RX_PATH_SEC1 (0x00000BD6) -#define WCD9360_CDC_RX7_RX_PATH_SEC2 (0x00000BD7) -#define WCD9360_CDC_RX7_RX_PATH_SEC3 (0x00000BD8) -#define WCD9360_CDC_RX7_RX_PATH_SEC5 (0x00000BDA) -#define WCD9360_CDC_RX7_RX_PATH_SEC6 (0x00000BDB) -#define WCD9360_CDC_RX7_RX_PATH_SEC7 (0x00000BDC) -#define WCD9360_CDC_RX7_RX_PATH_MIX_SEC0 (0x00000BDD) -#define WCD9360_CDC_RX7_RX_PATH_MIX_SEC1 (0x00000BDE) -#define WCD9360_CDC_RX7_RX_PATH_DSMDEM_CTL (0x00000BDF) -#define WCD9360_CDC_RX8_RX_PATH_CTL (0x00000BE1) -#define WCD9360_CDC_RX8_RX_PATH_CFG0 (0x00000BE2) -#define WCD9360_CDC_RX8_RX_PATH_CFG1 (0x00000BE3) -#define WCD9360_CDC_RX8_RX_PATH_CFG2 (0x00000BE4) -#define WCD9360_CDC_RX8_RX_VOL_CTL (0x00000BE5) -#define WCD9360_CDC_RX8_RX_PATH_MIX_CTL (0x00000BE6) -#define WCD9360_CDC_RX8_RX_PATH_MIX_CFG (0x00000BE7) -#define WCD9360_CDC_RX8_RX_VOL_MIX_CTL (0x00000BE8) -#define WCD9360_CDC_RX8_RX_PATH_SEC0 (0x00000BE9) -#define WCD9360_CDC_RX8_RX_PATH_SEC1 (0x00000BEA) -#define WCD9360_CDC_RX8_RX_PATH_SEC2 (0x00000BEB) -#define WCD9360_CDC_RX8_RX_PATH_SEC3 (0x00000BEC) -#define WCD9360_CDC_RX8_RX_PATH_SEC5 (0x00000BEE) -#define WCD9360_CDC_RX8_RX_PATH_SEC6 (0x00000BEF) -#define WCD9360_CDC_RX8_RX_PATH_SEC7 (0x00000BF0) -#define WCD9360_CDC_RX8_RX_PATH_MIX_SEC0 (0x00000BF1) -#define WCD9360_CDC_RX8_RX_PATH_MIX_SEC1 (0x00000BF2) -#define WCD9360_CDC_RX8_RX_PATH_DSMDEM_CTL (0x00000BF3) -#define WCD9360_PAGE12_PAGE_REGISTER (0x00000C00) -#define WCD9360_CDC_BOOST0_BOOST_PATH_CTL (0x00000C19) -#define WCD9360_CDC_BOOST0_BOOST_CTL (0x00000C1A) -#define WCD9360_CDC_BOOST0_BOOST_CFG1 (0x00000C1B) -#define WCD9360_CDC_BOOST0_BOOST_CFG2 (0x00000C1C) -#define WCD9360_CDC_BOOST1_BOOST_PATH_CTL (0x00000C21) -#define WCD9360_CDC_BOOST1_BOOST_CTL (0x00000C22) -#define WCD9360_CDC_BOOST1_BOOST_CFG1 (0x00000C23) -#define WCD9360_CDC_BOOST1_BOOST_CFG2 (0x00000C24) -#define WCD9360_MIXING_ASRC2_CLK_RST_CTL (0x00000C6D) -#define WCD9360_MIXING_ASRC2_CTL0 (0x00000C6E) -#define WCD9360_MIXING_ASRC2_CTL1 (0x00000C6F) -#define WCD9360_MIXING_ASRC2_FIFO_CTL (0x00000C70) -#define WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_LSB (0x00000C71) -#define WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_MSB (0x00000C72) -#define WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_LSB (0x00000C73) -#define WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_MSB (0x00000C74) -#define WCD9360_MIXING_ASRC2_STATUS_FIFO (0x00000C75) -#define WCD9360_MIXING_ASRC3_CLK_RST_CTL (0x00000C79) -#define WCD9360_MIXING_ASRC3_CTL0 (0x00000C7A) -#define WCD9360_MIXING_ASRC3_CTL1 (0x00000C7B) -#define WCD9360_MIXING_ASRC3_FIFO_CTL (0x00000C7C) -#define WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_LSB (0x00000C7D) -#define WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_MSB (0x00000C7E) -#define WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_LSB (0x00000C7F) -#define WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_MSB (0x00000C80) -#define WCD9360_MIXING_ASRC3_STATUS_FIFO (0x00000C81) -#define WCD9360_SWR_AHB_BRIDGE_WR_DATA_0 (0x00000C85) -#define WCD9360_SWR_AHB_BRIDGE_WR_DATA_1 (0x00000C86) -#define WCD9360_SWR_AHB_BRIDGE_WR_DATA_2 (0x00000C87) -#define WCD9360_SWR_AHB_BRIDGE_WR_DATA_3 (0x00000C88) -#define WCD9360_SWR_AHB_BRIDGE_WR_ADDR_0 (0x00000C89) -#define WCD9360_SWR_AHB_BRIDGE_WR_ADDR_1 (0x00000C8A) -#define WCD9360_SWR_AHB_BRIDGE_WR_ADDR_2 (0x00000C8B) -#define WCD9360_SWR_AHB_BRIDGE_WR_ADDR_3 (0x00000C8C) -#define WCD9360_SWR_AHB_BRIDGE_RD_ADDR_0 (0x00000C8D) -#define WCD9360_SWR_AHB_BRIDGE_RD_ADDR_1 (0x00000C8E) -#define WCD9360_SWR_AHB_BRIDGE_RD_ADDR_2 (0x00000C8F) -#define WCD9360_SWR_AHB_BRIDGE_RD_ADDR_3 (0x00000C90) -#define WCD9360_SWR_AHB_BRIDGE_RD_DATA_0 (0x00000C91) -#define WCD9360_SWR_AHB_BRIDGE_RD_DATA_1 (0x00000C92) -#define WCD9360_SWR_AHB_BRIDGE_RD_DATA_2 (0x00000C93) -#define WCD9360_SWR_AHB_BRIDGE_RD_DATA_3 (0x00000C94) -#define WCD9360_SWR_AHB_BRIDGE_ACCESS_CFG (0x00000C95) -#define WCD9360_SWR_AHB_BRIDGE_ACCESS_STATUS (0x00000C96) -#define WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL (0x00000CB5) -#define WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1 (0x00000CB6) -#define WCD9360_SIDETONE_ASRC0_CLK_RST_CTL (0x00000CBD) -#define WCD9360_SIDETONE_ASRC0_CTL0 (0x00000CBE) -#define WCD9360_SIDETONE_ASRC0_CTL1 (0x00000CBF) -#define WCD9360_SIDETONE_ASRC0_FIFO_CTL (0x00000CC0) -#define WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB (0x00000CC1) -#define WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB (0x00000CC2) -#define WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB (0x00000CC3) -#define WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB (0x00000CC4) -#define WCD9360_SIDETONE_ASRC0_STATUS_FIFO (0x00000CC5) -#define WCD9360_EC_REF_HQ0_EC_REF_HQ_PATH_CTL (0x00000CD5) -#define WCD9360_EC_REF_HQ0_EC_REF_HQ_CFG0 (0x00000CD6) -#define WCD9360_EC_REF_HQ1_EC_REF_HQ_PATH_CTL (0x00000CDD) -#define WCD9360_EC_REF_HQ1_EC_REF_HQ_CFG0 (0x00000CDE) -#define WCD9360_EC_ASRC0_CLK_RST_CTL (0x00000CE5) -#define WCD9360_EC_ASRC0_CTL0 (0x00000CE6) -#define WCD9360_EC_ASRC0_CTL1 (0x00000CE7) -#define WCD9360_EC_ASRC0_FIFO_CTL (0x00000CE8) -#define WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_LSB (0x00000CE9) -#define WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_MSB (0x00000CEA) -#define WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_LSB (0x00000CEB) -#define WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_MSB (0x00000CEC) -#define WCD9360_EC_ASRC0_STATUS_FIFO (0x00000CED) -#define WCD9360_EC_ASRC1_CLK_RST_CTL (0x00000CF1) -#define WCD9360_EC_ASRC1_CTL0 (0x00000CF2) -#define WCD9360_EC_ASRC1_CTL1 (0x00000CF3) -#define WCD9360_EC_ASRC1_FIFO_CTL (0x00000CF4) -#define WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_LSB (0x00000CF5) -#define WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_MSB (0x00000CF6) -#define WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_LSB (0x00000CF7) -#define WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_MSB (0x00000CF8) -#define WCD9360_EC_ASRC1_STATUS_FIFO (0x00000CF9) -#define WCD9360_PAGE13_PAGE_REGISTER (0x00000D00) -#define WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0 (0x00000D01) -#define WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1 (0x00000D02) -#define WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0 (0x00000D0B) -#define WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1 (0x00000D0C) -#define WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0 (0x00000D0F) -#define WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1 (0x00000D10) -#define WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0 (0x00000D11) -#define WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1 (0x00000D12) -#define WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG0 (0x00000D13) -#define WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG1 (0x00000D14) -#define WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG2 (0x00000D15) -#define WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG3 (0x00000D16) -#define WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG4 (0x00000D17) -#define WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0 (0x00000D18) -#define WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1 (0x00000D19) -#define WCD9360_CDC_RX_INP_MUX_ANC_CFG0 (0x00000D1A) -#define WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0 (0x00000D1B) -#define WCD9360_CDC_RX_INP_MUX_EC_REF_HQ_CFG0 (0x00000D1C) -#define WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0 (0x00000D1D) -#define WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1 (0x00000D1E) -#define WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG0 (0x00000D1F) -#define WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1 (0x00000D20) -#define WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG0 (0x00000D21) -#define WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1 (0x00000D22) -#define WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG0 (0x00000D23) -#define WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1 (0x00000D25) -#define WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0 (0x00000D26) -#define WCD9360_CDC_TX_INP_MUX_ADC_MUX5_CFG0 (0x00000D27) -#define WCD9360_CDC_TX_INP_MUX_ADC_MUX6_CFG0 (0x00000D28) -#define WCD9360_CDC_TX_INP_MUX_ADC_MUX7_CFG0 (0x00000D29) -#define WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0 (0x00000D2A) -#define WCD9360_CDC_TX_INP_MUX_ADC_MUX10_CFG0 (0x00000D2B) -#define WCD9360_CDC_TX_INP_MUX_ADC_MUX11_CFG0 (0x00000D2C) -#define WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0 (0x00000D31) -#define WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1 (0x00000D32) -#define WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2 (0x00000D33) -#define WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3 (0x00000D34) -#define WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0 (0x00000D3A) -#define WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1 (0x00000D3B) -#define WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2 (0x00000D3C) -#define WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3 (0x00000D3D) -#define WCD9360_CDC_CLK_RST_CTRL_MCLK_CONTROL (0x00000D41) -#define WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL (0x00000D42) -#define WCD9360_CDC_CLK_RST_CTRL_SWR_CONTROL (0x00000D43) -#define WCD9360_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL (0x00000D45) -#define WCD9360_CDC_PROX_DETECT_PROX_CTL (0x00000D49) -#define WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD0 (0x00000D4A) -#define WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD1 (0x00000D4B) -#define WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB (0x00000D4C) -#define WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB (0x00000D4D) -#define WCD9360_CDC_PROX_DETECT_PROX_STATUS (0x00000D4E) -#define WCD9360_CDC_PROX_DETECT_PROX_TEST_CTRL (0x00000D4F) -#define WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB (0x00000D50) -#define WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB (0x00000D51) -#define WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD (0x00000D52) -#define WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD (0x00000D53) -#define WCD9360_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT (0x00000D54) -#define WCD9360_CDC_SIDETONE_IIR0_IIR_PATH_CTL (0x00000D55) -#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL (0x00000D56) -#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL (0x00000D57) -#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL (0x00000D58) -#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL (0x00000D59) -#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL (0x00000D5A) -#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL (0x00000D5B) -#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL (0x00000D5C) -#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL (0x00000D5D) -#define WCD9360_CDC_SIDETONE_IIR0_IIR_CTL (0x00000D5E) -#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL (0x00000D5F) -#define WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL (0x00000D60) -#define WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL (0x00000D61) -#define WCD9360_CDC_TOP_TOP_CFG0 (0x00000D81) -#define WCD9360_CDC_TOP_TOP_CFG1 (0x00000D82) -#define WCD9360_CDC_TOP_TOP_CFG7 (0x00000D88) -#define WCD9360_CDC_TOP_EAR_COMP_WR_LSB (0x00000DA9) -#define WCD9360_CDC_TOP_EAR_COMP_WR_MSB (0x00000DAA) -#define WCD9360_CDC_TOP_EAR_COMP_LUT (0x00000DAB) -#define WCD9360_CDC_TOP_EAR_COMP_RD_LSB (0x00000DAC) -#define WCD9360_CDC_TOP_EAR_COMP_RD_MSB (0x00000DAD) -#define WCD9360_CDC_TOP_TOP_DEBUG (0x00000DAE) -#define WCD9360_PAGE80_PAGE_REGISTER (0x00005000) -#define WCD9360_CODEC_CPR_WR_DATA_0 (0x00005001) -#define WCD9360_CODEC_CPR_WR_DATA_1 (0x00005002) -#define WCD9360_CODEC_CPR_WR_DATA_2 (0x00005003) -#define WCD9360_CODEC_CPR_WR_DATA_3 (0x00005004) -#define WCD9360_CODEC_CPR_WR_ADDR_0 (0x00005005) -#define WCD9360_CODEC_CPR_WR_ADDR_1 (0x00005006) -#define WCD9360_CODEC_CPR_WR_ADDR_2 (0x00005007) -#define WCD9360_CODEC_CPR_WR_ADDR_3 (0x00005008) -#define WCD9360_CODEC_CPR_RD_ADDR_0 (0x00005009) -#define WCD9360_CODEC_CPR_RD_ADDR_1 (0x0000500A) -#define WCD9360_CODEC_CPR_RD_ADDR_2 (0x0000500B) -#define WCD9360_CODEC_CPR_RD_ADDR_3 (0x0000500C) -#define WCD9360_CODEC_CPR_RD_DATA_0 (0x0000500D) -#define WCD9360_CODEC_CPR_RD_DATA_1 (0x0000500E) -#define WCD9360_CODEC_CPR_RD_DATA_2 (0x0000500F) -#define WCD9360_CODEC_CPR_RD_DATA_3 (0x00005010) -#define WCD9360_CODEC_CPR_ACCESS_CFG (0x00005011) -#define WCD9360_CODEC_CPR_ACCESS_STATUS (0x00005012) -#define WCD9360_CODEC_CPR_NOM_CX_VDD (0x00005021) -#define WCD9360_CODEC_CPR_SVS_CX_VDD (0x00005022) -#define WCD9360_CODEC_CPR_SVS2_CX_VDD (0x00005023) -#define WCD9360_CODEC_CPR_NOM_MX_VDD (0x00005024) -#define WCD9360_CODEC_CPR_SVS_MX_VDD (0x00005025) -#define WCD9360_CODEC_CPR_SVS2_MX_VDD (0x00005026) -#define WCD9360_CODEC_CPR_SVS2_MIN_CX_VDD (0x00005027) -#define WCD9360_CODEC_CPR_MAX_SVS2_STEP (0x00005028) -#define WCD9360_CODEC_CPR_CTL (0x00005029) -#define WCD9360_CODEC_CPR_SW_MODECHNG_STATUS (0x0000502A) -#define WCD9360_CODEC_CPR_SW_MODECHNG_START (0x0000502B) -#define WCD9360_CODEC_CPR_CPR_STATUS (0x0000502C) -#define WCD9360_PAGE128_PAGE_REGISTER (0x00008000) -#define WCD9360_TLMM_JTCK_PINCFG (0x00008001) -#define WCD9360_TLMM_INTR1_PINCFG (0x00008002) -#define WCD9360_TLMM_INTR2_PINCFG (0x00008003) -#define WCD9360_TLMM_SWR_DATA_PINCFG (0x00008004) -#define WCD9360_TLMM_SWR_CLK_PINCFG (0x00008005) -#define WCD9360_TLMM_SLIMBUS_DATA1_PINCFG (0x00008006) -#define WCD9360_TLMM_SLIMBUS_DATA2_PINCFG (0x00008007) -#define WCD9360_TLMM_SLIMBUS_CLK_PINCFG (0x00008008) -#define WCD9360_TLMM_I2C_CLK_PINCFG (0x00008009) -#define WCD9360_TLMM_I2C_DATA_PINCFG (0x0000800A) -#define WCD9360_TLMM_I2S_0_RX_PINCFG (0x0000800B) -#define WCD9360_TLMM_I2S_0_TX_PINCFG (0x0000800C) -#define WCD9360_TLMM_I2S_0_SCK_PINCFG (0x0000800D) -#define WCD9360_TLMM_I2S_0_WS_PINCFG (0x0000800E) -#define WCD9360_TLMM_I2S_1_RX_PINCFG (0x0000800F) -#define WCD9360_TLMM_I2S_1_TX_PINCFG (0x00008010) -#define WCD9360_TLMM_I2S_1_SCK_PINCFG (0x00008011) -#define WCD9360_TLMM_I2S_1_WS_PINCFG (0x00008012) -#define WCD9360_TLMM_DMIC1_CLK_PINCFG (0x00008013) -#define WCD9360_TLMM_DMIC1_DATA_PINCFG (0x00008014) -#define WCD9360_TLMM_DMIC2_CLK_PINCFG (0x00008015) -#define WCD9360_TLMM_DMIC2_DATA_PINCFG (0x00008016) -#define WCD9360_TLMM_GPIO1_PINCFG (0x00008017) -#define WCD9360_TLMM_GPIO2_PINCFG (0x00008018) -#define WCD9360_TLMM_GPIO3_PINCFG (0x00008019) -#define WCD9360_TLMM_GPIO4_PINCFG (0x0000801A) -#define WCD9360_TLMM_SPI_S_CSN_PINCFG (0x0000801B) -#define WCD9360_TLMM_SPI_S_CLK_PINCFG (0x0000801C) -#define WCD9360_TLMM_SPI_S_DOUT_PINCFG (0x0000801D) -#define WCD9360_TLMM_SPI_S_DIN_PINCFG (0x0000801E) -#define WCD9360_TLMM_GPIO0_PINCFG (0x0000801F) -#define WCD9360_TLMM_DMIC3_CLK_PINCFG (0x00008020) -#define WCD9360_TLMM_DMIC3_DATA_PINCFG (0x00008021) -#define WCD9360_TLMM_DMIC4_CLK_PINCFG (0x00008022) -#define WCD9360_TLMM_DMIC4_DATA_PINCFG (0x00008023) -#define WCD9360_TEST_DEBUG_PIN_CTL_OE_0 (0x00008031) -#define WCD9360_TEST_DEBUG_PIN_CTL_OE_1 (0x00008032) -#define WCD9360_TEST_DEBUG_PIN_CTL_OE_2 (0x00008033) -#define WCD9360_TEST_DEBUG_PIN_CTL_OE_3 (0x00008034) -#define WCD9360_TEST_DEBUG_PIN_CTL_OE_4 (0x00008035) -#define WCD9360_TEST_DEBUG_PIN_CTL_DATA_0 (0x00008036) -#define WCD9360_TEST_DEBUG_PIN_CTL_DATA_1 (0x00008037) -#define WCD9360_TEST_DEBUG_PIN_CTL_DATA_2 (0x00008038) -#define WCD9360_TEST_DEBUG_PIN_CTL_DATA_3 (0x00008039) -#define WCD9360_TEST_DEBUG_PIN_CTL_DATA_4 (0x0000803A) -#define WCD9360_TEST_DEBUG_PAD_DRVCTL_0 (0x0000803B) -#define WCD9360_TEST_DEBUG_PAD_DRVCTL_1 (0x0000803C) -#define WCD9360_TEST_DEBUG_PIN_STATUS (0x0000803D) -#define WCD9360_TEST_DEBUG_NPL_DLY_TEST_1 (0x0000803E) -#define WCD9360_TEST_DEBUG_NPL_DLY_TEST_2 (0x0000803F) -#define WCD9360_TEST_DEBUG_MEM_CTRL (0x00008040) -#define WCD9360_TEST_DEBUG_DEBUG_BUS_SEL (0x00008041) -#define WCD9360_TEST_DEBUG_DEBUG_JTAG (0x00008042) -#define WCD9360_TEST_DEBUG_DEBUG_EN_1 (0x00008043) -#define WCD9360_TEST_DEBUG_DEBUG_EN_2 (0x00008044) -#define WCD9360_TEST_DEBUG_DEBUG_EN_3 (0x00008045) -#define WCD9360_TEST_DEBUG_DEBUG_EN_4 (0x00008046) -#define WCD9360_TEST_DEBUG_DEBUG_EN_5 (0x00008047) -#define WCD9360_TEST_DEBUG_ANA_DTEST_DIR (0x0000804A) -#define WCD9360_TEST_DEBUG_PAD_INP_DISABLE_0 (0x0000804B) -#define WCD9360_TEST_DEBUG_PAD_INP_DISABLE_1 (0x0000804C) -#define WCD9360_TEST_DEBUG_PAD_INP_DISABLE_2 (0x0000804D) -#define WCD9360_TEST_DEBUG_PAD_INP_DISABLE_3 (0x0000804E) -#define WCD9360_TEST_DEBUG_PAD_INP_DISABLE_4 (0x0000804F) -#define WCD9360_TEST_DEBUG_SYSMEM_CTRL (0x00008050) -#define WCD9360_TEST_DEBUG_LVAL_NOM_LOW (0x00008052) -#define WCD9360_TEST_DEBUG_LVAL_NOM_HIGH (0x00008053) -#define WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_LOW (0x00008054) -#define WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_HIGH (0x00008055) -#define WCD9360_TEST_DEBUG_SPI_SLAVE_CHAR (0x00008056) -#define WCD9360_TEST_DEBUG_CODEC_DIAGS (0x00008057) -#define WCD9360_TEST_DEBUG_PAD_TEST (0x00008058) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_0 (0x00008061) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_1 (0x00008062) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_2 (0x00008063) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_3 (0x00008064) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_4 (0x00008065) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_5 (0x00008066) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_6 (0x00008067) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_7 (0x00008068) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_8 (0x00008069) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_9 (0x0000806A) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_10 (0x0000806B) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_11 (0x0000806C) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_12 (0x0000806D) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_13 (0x0000806E) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_14 (0x0000806F) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_15 (0x00008070) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_16 (0x00008071) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_17 (0x00008072) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_18 (0x00008073) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_19 (0x00008074) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_20 (0x00008075) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_21 (0x00008076) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_22 (0x00008077) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_23 (0x00008078) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_24 (0x00008079) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_25 (0x0000807A) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_26 (0x0000807B) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_27 (0x0000807C) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_28 (0x0000807D) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_29 (0x0000807E) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_30 (0x0000807F) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_31 (0x00008080) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_RD_CTRL (0x00008081) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_RD_7_0 (0x00008082) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_RD_15_8 (0x00008083) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_RD_23_16 (0x00008084) -#define WCD9360_TEST_DEBUG_DEBUG_MUX_RD_31_24 (0x00008085) -#define WCD9360_MAX_REGISTER 0x80FF - -/* SLIMBUS Slave Registers */ -#define WCD9360_SLIM_PGD_PORT_INT_RX_EN0 (0x30) -#define WCD9360_SLIM_PGD_PORT_INT_TX_EN0 (0x32) -#define WCD9360_SLIM_PGD_PORT_INT_STATUS_RX_0 (0x34) -#define WCD9360_SLIM_PGD_PORT_INT_STATUS_RX_1 (0x35) -#define WCD9360_SLIM_PGD_PORT_INT_STATUS_TX_0 (0x36) -#define WCD9360_SLIM_PGD_PORT_INT_STATUS_TX_1 (0x37) -#define WCD9360_SLIM_PGD_PORT_INT_CLR_RX_0 (0x38) -#define WCD9360_SLIM_PGD_PORT_INT_CLR_RX_1 (0x39) -#define WCD9360_SLIM_PGD_PORT_INT_CLR_TX_0 (0x3A) -#define WCD9360_SLIM_PGD_PORT_INT_CLR_TX_1 (0x3B) -#define WCD9360_SLIM_PGD_PORT_INT_RX_SOURCE0 (0x60) -#define WCD9360_SLIM_PGD_PORT_INT_TX_SOURCE0 (0x70) - -#endif diff --git a/ipc/Android.mk b/ipc/Android.mk index 18dbedf7b60a..b54e5225b6a1 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -3,14 +3,6 @@ # Assume no targets will be supported # Check if this driver needs be built for current target -ifeq ($(call is-board-platform,sdm845),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m -endif - -ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m -endif - ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif @@ -21,7 +13,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) diff --git a/ipc/Kbuild b/ipc/Kbuild index 4e2d54bd7183..3ecf01dd87e9 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -15,21 +15,6 @@ ifeq ($(KERNEL_BUILD), 1) endif ifeq ($(KERNEL_BUILD), 0) - ifeq ($(CONFIG_ARCH_SDM845), y) - include $(AUDIO_ROOT)/config/sdm845auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM670), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM450), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm6150auto.conf export diff --git a/soc/Android.mk b/soc/Android.mk index 65770ba66d8b..7a8bd0e8fbc6 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -3,14 +3,6 @@ # Assume no targets will be supported # Check if this driver needs be built for current target -ifeq ($(call is-board-platform,sdm845),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m -endif - -ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true) -AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m -endif - ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif @@ -21,7 +13,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) LOCAL_PATH := $(call my-dir) @@ -48,7 +40,7 @@ KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) KBUILD_OPTIONS += $(AUDIO_SELECT) ########################################################### -ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605 $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_lpi.ko LOCAL_MODULE_KBUILD_NAME := pinctrl_lpi_dlkm.ko diff --git a/soc/Kbuild b/soc/Kbuild index 29306ceaac24..69eb0b988c9b 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -14,21 +14,6 @@ ifeq ($(KERNEL_BUILD), 1) endif ifeq ($(KERNEL_BUILD), 0) - ifeq ($(CONFIG_ARCH_SDM845), y) - include $(AUDIO_ROOT)/config/sdm845auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm845autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM670), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif - ifeq ($(CONFIG_ARCH_SDM450), y) - include $(AUDIO_ROOT)/config/sdm670auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h - endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export -- GitLab From 7c067e898b9e2c108db0da28fb71c7205f45cd27 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 15 Nov 2018 06:53:35 +0530 Subject: [PATCH 0673/1645] Soundwire: Check complete soundwire slave device ID Soundwire slave device ID is 48 bits. Check the complete soundwire slave device ID during enumeration for proper slave driver registration. Change-Id: Iac11eb818a29c227947f3cf50cafd336b4e410a2 Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index efb20f7b0bb6..fb1a48bd62e0 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -36,7 +36,7 @@ #define SWR_BROADCAST_CMD_ID 0x0F #define SWR_AUTO_SUSPEND_DELAY 3 /* delay in sec */ -#define SWR_DEV_ID_MASK 0xFFFFFFFF +#define SWR_DEV_ID_MASK 0xFFFFFFFFFFFF #define SWR_REG_VAL_PACK(data, dev, id, reg) \ ((reg) | ((id) << 16) | ((dev) << 20) | ((data) << 24)) -- GitLab From 64aae620b02328870818f9c58ef814bcd0827d8c Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 29 Nov 2018 13:51:39 +0800 Subject: [PATCH 0674/1645] ASoC: wcd-irq: correct identifier name to fix compile error The two arguments in functions wcd_request_irq, wcd_free_irq, wcd_enable_irq and wcd_disable_irq have same identifier names. Correct wcd_irq_info identifier name to fix compile error Change-Id: I6f240d3af1cd253336d070d0f3228eae96a4fcb6 Signed-off-by: Meng Wang --- include/asoc/wcd-irq.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/asoc/wcd-irq.h b/include/asoc/wcd-irq.h index 63502f828ed8..a071c77ec9b4 100644 --- a/include/asoc/wcd-irq.h +++ b/include/asoc/wcd-irq.h @@ -44,19 +44,19 @@ static inline int wcd_irq_exit(struct wcd_irq_info *irq_info, { return 0; }; -static inline int wcd_request_irq(struct wcd_irq_info *irq, +static inline int wcd_request_irq(struct wcd_irq_info *irq_info, int irq, const char *name, irq_handler_t handler, void *data) { return 0; }; -static inline void wcd_free_irq(struct wcd_irq_info *irq, int irq, void *data); +static inline void wcd_free_irq(struct wcd_irq_info *irq_info, int irq, void *data); { }; -static inline void wcd_enable_irq(struct wcd_irq_info *irq, int irq); +static inline void wcd_enable_irq(struct wcd_irq_info *irq_info, int irq); { }; -static inline void wcd_disable_irq(struct wcd_irq_info *irq, int irq); +static inline void wcd_disable_irq(struct wcd_irq_info *irq_info, int irq); { }; #endif -- GitLab From 978ae25e313e51eb9f729cff8afee6e4fba5fd00 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 19 Sep 2018 17:09:50 +0800 Subject: [PATCH 0675/1645] ASoc: ep92: change setup_timer to timer_setup On kernel-4.19, setup_timer is changed to timer_setup. Update ep92 driver to fix compile error. Change-Id: I844241413c72c415819774921f267d84692ba177 Signed-off-by: Meng Wang --- asoc/codecs/ep92/ep92.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/ep92/ep92.c b/asoc/codecs/ep92/ep92.c index 52f5e6d0b98a..d3c67a26144d 100644 --- a/asoc/codecs/ep92/ep92.c +++ b/asoc/codecs/ep92/ep92.c @@ -733,9 +733,9 @@ static irqreturn_t ep92_irq(int irq, void *data) return IRQ_HANDLED; }; -void ep92_poll_status(unsigned long data) +void ep92_poll_status(struct timer_list *t) { - struct ep92_pdata *ep92 = (struct ep92_pdata *)data; + struct ep92_pdata *ep92 = from_timer(ep92, t, timer); u32 poll_msec; if ((ep92->gc.ctl & EP92_GC_POWER_MASK) == 0) @@ -1493,8 +1493,7 @@ static int ep92_i2c_probe(struct i2c_client *client, } /* poll status if IRQ is not configured */ if (ep92->irq == 0) { - setup_timer(&ep92->timer, ep92_poll_status, - (unsigned long)ep92); + timer_setup(&ep92->timer, ep92_poll_status, 0); mod_timer(&ep92->timer, jiffies + msecs_to_jiffies(EP92_POLL_INTERVAL_OFF_MSEC)); } -- GitLab From 61af6849e9cc1b8d9b84b231a9a3935575a94b2d Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 10 Sep 2018 17:47:55 +0800 Subject: [PATCH 0676/1645] ASoC: switch audio drivers to SPDX identifier Switch audio drivers to SPDX identifier on msm-4.19. Change-Id: Ic3f0230a516db251b8d81e8a7e73dbc04d66fe1b Signed-off-by: Meng Wang --- asoc/codecs/aqt1000/aqt1000-api.h | 10 +--------- asoc/codecs/aqt1000/aqt1000-clsh.c | 10 +--------- asoc/codecs/aqt1000/aqt1000-clsh.h | 10 +--------- asoc/codecs/aqt1000/aqt1000-core.c | 10 +--------- asoc/codecs/aqt1000/aqt1000-internal.h | 10 +--------- asoc/codecs/aqt1000/aqt1000-irq.c | 10 +--------- asoc/codecs/aqt1000/aqt1000-irq.h | 10 +--------- asoc/codecs/aqt1000/aqt1000-mbhc.c | 10 +--------- asoc/codecs/aqt1000/aqt1000-mbhc.h | 10 +--------- asoc/codecs/aqt1000/aqt1000-reg-defaults.h | 10 +--------- asoc/codecs/aqt1000/aqt1000-registers.h | 10 +--------- asoc/codecs/aqt1000/aqt1000-regmap.c | 10 +--------- asoc/codecs/aqt1000/aqt1000-routing.h | 10 +--------- asoc/codecs/aqt1000/aqt1000-utils.c | 10 +--------- asoc/codecs/aqt1000/aqt1000-utils.h | 10 +--------- asoc/codecs/aqt1000/aqt1000.c | 10 +--------- asoc/codecs/aqt1000/aqt1000.h | 10 +--------- asoc/codecs/aqt1000/pdata.h | 10 +--------- asoc/codecs/audio-ext-clk-up.c | 10 +--------- asoc/codecs/audio-ext-clk-up.h | 10 +--------- asoc/codecs/audio-ext-clk.c | 10 +--------- asoc/codecs/bolero/bolero-cdc-registers.h | 10 +--------- asoc/codecs/bolero/bolero-cdc-regmap.c | 10 +--------- asoc/codecs/bolero/bolero-cdc-tables.c | 10 +--------- asoc/codecs/bolero/bolero-cdc-utils.c | 10 +--------- asoc/codecs/bolero/bolero-cdc.c | 10 +--------- asoc/codecs/bolero/bolero-cdc.h | 10 +--------- asoc/codecs/bolero/internal.h | 10 +--------- asoc/codecs/bolero/rx-macro.c | 10 +--------- asoc/codecs/bolero/tx-macro.c | 10 +--------- asoc/codecs/bolero/va-macro.c | 10 +--------- asoc/codecs/bolero/wsa-macro.c | 10 +--------- asoc/codecs/bolero/wsa-macro.h | 10 +--------- asoc/codecs/core.h | 10 +--------- asoc/codecs/cpe_cmi.h | 10 +--------- asoc/codecs/cpe_core.h | 10 +--------- asoc/codecs/cpe_err.h | 10 +--------- asoc/codecs/csra66x0/csra66x0.c | 10 +--------- asoc/codecs/csra66x0/csra66x0.h | 10 +--------- asoc/codecs/ep92/ep92.c | 10 +--------- asoc/codecs/ep92/ep92.h | 10 +--------- asoc/codecs/msm-cdc-pinctrl.c | 10 +--------- asoc/codecs/msm-cdc-pinctrl.h | 10 +--------- asoc/codecs/msm-cdc-supply.c | 10 +--------- asoc/codecs/msm-cdc-supply.h | 10 +--------- asoc/codecs/msm_hdmi_codec_rx.c | 10 +--------- asoc/codecs/msm_stub.c | 11 ++--------- asoc/codecs/pdata.h | 10 +--------- asoc/codecs/wcd-clsh.c | 10 +--------- asoc/codecs/wcd-clsh.h | 10 +--------- asoc/codecs/wcd-dsp-mgr.c | 10 +--------- asoc/codecs/wcd-dsp-utils.c | 10 +--------- asoc/codecs/wcd-dsp-utils.h | 10 +--------- asoc/codecs/wcd-irq.c | 10 +--------- asoc/codecs/wcd-mbhc-adc.c | 10 +--------- asoc/codecs/wcd-mbhc-adc.h | 10 +--------- asoc/codecs/wcd-mbhc-legacy.c | 10 +--------- asoc/codecs/wcd-mbhc-legacy.h | 10 +--------- asoc/codecs/wcd-mbhc-v2-api.h | 10 +--------- asoc/codecs/wcd-mbhc-v2.c | 10 +--------- asoc/codecs/wcd-mbhc-v2.h | 10 +--------- asoc/codecs/wcd-spi-registers.h | 10 +--------- asoc/codecs/wcd-spi.c | 10 +--------- asoc/codecs/wcd9335-regmap.c | 10 +--------- asoc/codecs/wcd9335-tables.c | 10 +--------- asoc/codecs/wcd9335.c | 10 +--------- asoc/codecs/wcd9335.h | 10 +--------- asoc/codecs/wcd9335_irq.h | 10 +--------- asoc/codecs/wcd9335_registers.h | 10 +--------- asoc/codecs/wcd934x/wcd934x-dsd.c | 10 +--------- asoc/codecs/wcd934x/wcd934x-dsd.h | 10 +--------- asoc/codecs/wcd934x/wcd934x-dsp-cntl.c | 10 +--------- asoc/codecs/wcd934x/wcd934x-dsp-cntl.h | 10 +--------- asoc/codecs/wcd934x/wcd934x-mbhc.c | 10 +--------- asoc/codecs/wcd934x/wcd934x-mbhc.h | 10 +--------- asoc/codecs/wcd934x/wcd934x-regmap.c | 10 +--------- asoc/codecs/wcd934x/wcd934x-routing.h | 10 +--------- asoc/codecs/wcd934x/wcd934x-tables.c | 10 +--------- asoc/codecs/wcd934x/wcd934x.c | 10 +--------- asoc/codecs/wcd934x/wcd934x.h | 10 +--------- asoc/codecs/wcd934x/wcd934x_irq.h | 10 +--------- asoc/codecs/wcd937x/internal.h | 10 +--------- asoc/codecs/wcd937x/wcd937x-mbhc.c | 10 +--------- asoc/codecs/wcd937x/wcd937x-mbhc.h | 10 +--------- asoc/codecs/wcd937x/wcd937x-registers.h | 10 +--------- asoc/codecs/wcd937x/wcd937x-regmap.c | 10 +--------- asoc/codecs/wcd937x/wcd937x-tables.c | 10 +--------- asoc/codecs/wcd937x/wcd937x.c | 10 +--------- asoc/codecs/wcd937x/wcd937x.h | 10 +--------- asoc/codecs/wcd937x/wcd937x_slave.c | 10 +--------- asoc/codecs/wcd9xxx-common-v2.c | 10 +--------- asoc/codecs/wcd9xxx-common-v2.h | 10 +--------- asoc/codecs/wcd9xxx-core-init.c | 10 +--------- asoc/codecs/wcd9xxx-core.c | 10 +--------- asoc/codecs/wcd9xxx-irq.c | 10 +--------- asoc/codecs/wcd9xxx-irq.h | 10 +--------- asoc/codecs/wcd9xxx-regmap.h | 10 +--------- asoc/codecs/wcd9xxx-resmgr-v2.c | 10 +--------- asoc/codecs/wcd9xxx-resmgr-v2.h | 10 +--------- asoc/codecs/wcd9xxx-rst.c | 10 +--------- asoc/codecs/wcd9xxx-slimslave.c | 10 +--------- asoc/codecs/wcd9xxx-slimslave.h | 10 +--------- asoc/codecs/wcd9xxx-soc-init.c | 10 +--------- asoc/codecs/wcd9xxx-utils.c | 10 +--------- asoc/codecs/wcd9xxx-utils.h | 10 +--------- asoc/codecs/wcd_cmi_api.h | 10 +--------- asoc/codecs/wcd_cpe_core.c | 10 +--------- asoc/codecs/wcd_cpe_core.h | 10 +--------- asoc/codecs/wcd_cpe_services.c | 10 +--------- asoc/codecs/wcd_cpe_services.h | 10 +--------- asoc/codecs/wcdcal-hwdep.c | 10 +--------- asoc/codecs/wcdcal-hwdep.h | 10 +--------- asoc/codecs/wsa881x-registers.h | 10 +--------- asoc/codecs/wsa881x-regmap.c | 10 +--------- asoc/codecs/wsa881x-tables.c | 10 +--------- asoc/codecs/wsa881x-temp-sensor.c | 10 +--------- asoc/codecs/wsa881x-temp-sensor.h | 10 +--------- asoc/codecs/wsa881x.c | 10 +--------- asoc/codecs/wsa881x.h | 10 +--------- asoc/device_event.h | 10 +--------- asoc/machine_815x_init.c | 15 +++------------ asoc/machine_815x_init.h | 11 +---------- asoc/msm-audio-effects-q6-v2.c | 10 +--------- asoc/msm-compress-q6-v2.c | 10 +--------- asoc/msm-cpe-lsm.c | 10 +--------- asoc/msm-dai-fe.c | 10 +--------- asoc/msm-dai-q6-hdmi-v2.c | 10 +--------- asoc/msm-dai-q6-v2.c | 10 +--------- asoc/msm-dai-q6-v2.h | 10 +--------- asoc/msm-dai-slim.c | 10 +--------- asoc/msm-dai-stub-v2.c | 10 +--------- asoc/msm-dolby-common.h | 11 ++--------- asoc/msm-dolby-dap-config.h | 11 ++--------- asoc/msm-ds2-dap-config.c | 10 +--------- asoc/msm-ds2-dap-config.h | 11 ++--------- asoc/msm-lsm-client.c | 10 +--------- asoc/msm-pcm-afe-v2.c | 10 +--------- asoc/msm-pcm-afe-v2.h | 10 +--------- asoc/msm-pcm-dtmf-v2.c | 10 +--------- asoc/msm-pcm-host-voice-v2.c | 10 +--------- asoc/msm-pcm-hostless.c | 12 ++---------- asoc/msm-pcm-loopback-v2.c | 10 +--------- asoc/msm-pcm-q6-noirq.c | 10 +--------- asoc/msm-pcm-q6-v2.c | 10 +--------- asoc/msm-pcm-q6-v2.h | 13 +------------ asoc/msm-pcm-routing-devdep.c | 10 +--------- asoc/msm-pcm-routing-devdep.h | 10 +--------- asoc/msm-pcm-routing-v2.c | 10 +--------- asoc/msm-pcm-routing-v2.h | 10 +--------- asoc/msm-pcm-voice-v2.c | 10 +--------- asoc/msm-pcm-voice-v2.h | 10 +--------- asoc/msm-pcm-voip-v2.c | 10 +--------- asoc/msm-qti-pp-config.c | 10 +--------- asoc/msm-qti-pp-config.h | 9 +-------- asoc/msm-slim-dma.h | 10 +--------- asoc/msm-transcode-loopback-q6-v2.c | 10 +--------- asoc/platform_init.c | 13 ++----------- asoc/platform_init.h | 15 +++------------ asoc/qcs405.c | 10 +--------- asoc/sa8155.c | 10 +--------- asoc/sm6150.c | 10 +--------- asoc/sm8150.c | 10 +--------- config/qcs405autoconf.h | 10 +--------- config/sdxpoorwillsautoconf.h | 10 +--------- config/sm6150autoconf.h | 10 +--------- config/sm8150autoconf.h | 10 +--------- dsp/adsp-loader.c | 10 +--------- dsp/adsp_err.c | 10 +--------- dsp/adsp_err.h | 10 +--------- dsp/audio_cal_utils.c | 14 +++----------- dsp/audio_calibration.c | 14 +++----------- dsp/audio_notifier.c | 13 +++---------- dsp/audio_pdr.c | 13 +++---------- dsp/audio_pdr.h | 14 +++----------- dsp/audio_slimslave.c | 13 +++---------- dsp/audio_ssr.c | 13 +++---------- dsp/audio_ssr.h | 14 +++----------- dsp/avtimer.c | 10 +--------- dsp/codecs/aac_in.c | 11 +---------- dsp/codecs/amrnb_in.c | 10 +--------- dsp/codecs/amrwb_in.c | 10 +--------- dsp/codecs/audio_aac.c | 11 +---------- dsp/codecs/audio_alac.c | 14 +++----------- dsp/codecs/audio_amrnb.c | 11 +---------- dsp/codecs/audio_amrwb.c | 11 +---------- dsp/codecs/audio_amrwbplus.c | 11 +---------- dsp/codecs/audio_ape.c | 11 +---------- dsp/codecs/audio_evrc.c | 11 +---------- dsp/codecs/audio_g711alaw.c | 11 +---------- dsp/codecs/audio_g711mlaw.c | 11 +---------- dsp/codecs/audio_hwacc_effects.c | 10 +--------- dsp/codecs/audio_mp3.c | 11 +---------- dsp/codecs/audio_multi_aac.c | 11 +---------- dsp/codecs/audio_native.c | 15 +++------------ dsp/codecs/audio_qcelp.c | 11 +---------- dsp/codecs/audio_utils.c | 11 +---------- dsp/codecs/audio_utils.h | 11 +---------- dsp/codecs/audio_utils_aio.c | 11 +---------- dsp/codecs/audio_utils_aio.h | 11 +---------- dsp/codecs/audio_wma.c | 11 +---------- dsp/codecs/audio_wmapro.c | 11 +---------- dsp/codecs/evrc_in.c | 11 +---------- dsp/codecs/g711alaw_in.c | 11 +---------- dsp/codecs/g711mlaw_in.c | 11 +---------- dsp/codecs/q6audio_common.h | 11 +---------- dsp/codecs/q6audio_v2.c | 10 +--------- dsp/codecs/q6audio_v2_aio.c | 11 +---------- dsp/codecs/qcelp_in.c | 11 +---------- dsp/msm-audio-event-notify.c | 13 +++---------- dsp/msm-dts-srs-tm-config.c | 10 +--------- dsp/msm_audio_ion.c | 10 +--------- dsp/msm_mdf.c | 11 +---------- dsp/q6_init.c | 13 ++----------- dsp/q6_init.h | 13 ++----------- dsp/q6adm.c | 13 +++---------- dsp/q6afe.c | 13 +++---------- dsp/q6afecal-hwdep.c | 13 ++----------- dsp/q6afecal-hwdep.h | 12 ++---------- dsp/q6asm.c | 12 +----------- dsp/q6audio-v2.c | 13 +++---------- dsp/q6common.c | 13 +++---------- dsp/q6core.c | 13 +++---------- dsp/q6lsm.c | 10 +--------- dsp/q6usm.c | 14 +++----------- dsp/q6usm.h | 14 +++----------- dsp/q6voice.c | 13 +++---------- dsp/rtac.c | 14 +++----------- dsp/usf.c | 14 +++----------- dsp/usf.h | 14 +++----------- dsp/usfcdev.c | 14 +++----------- dsp/usfcdev.h | 14 +++----------- include/asoc/wcd-irq.h | 13 +++---------- include/asoc/wcd934x_registers.h | 10 +--------- include/asoc/wcd9xxx_registers.h | 10 +--------- include/dsp/apr_audio-v2.h | 13 +++---------- include/dsp/audio_cal_utils.h | 14 +++----------- include/dsp/audio_calibration.h | 14 +++----------- include/dsp/audio_notifier.h | 14 +++----------- include/dsp/msm-audio-effects-q6-v2.h | 10 +--------- include/dsp/msm-audio-event-notify.h | 14 +++----------- include/dsp/msm-dts-srs-tm-config.h | 11 ++--------- include/dsp/msm_audio_ion.h | 10 +--------- include/dsp/msm_mdf.h | 10 +--------- include/dsp/q6adm-v2.h | 13 +++---------- include/dsp/q6afe-v2.h | 13 +++---------- include/dsp/q6asm-v2.h | 13 +++---------- include/dsp/q6audio-v2.h | 13 +++---------- include/dsp/q6common.h | 13 +++---------- include/dsp/q6core.h | 13 +++---------- include/dsp/q6lsm.h | 10 +--------- include/dsp/q6voice.h | 13 +++---------- include/dsp/rtac.h | 11 +---------- include/ipc/apr.h | 14 +++----------- include/ipc/apr_tal.h | 14 +++----------- include/ipc/apr_us.h | 14 +++----------- include/soc/soundwire.h | 13 +++---------- include/soc/swr-wcd.h | 13 +++---------- include/uapi/linux/msm_audio.h | 13 ++----------- ipc/apr.c | 13 +++---------- ipc/apr_tal_rpmsg.c | 10 +--------- ipc/apr_v2.c | 12 ++---------- ipc/apr_v3.c | 10 +--------- ipc/wcd-dsp-glink.c | 13 +++---------- soc/pinctrl-lpi.c | 10 +--------- soc/pinctrl-wcd.c | 10 +--------- soc/regmap-swr.c | 10 +--------- soc/soundwire.c | 13 +++---------- soc/swr-mstr-ctrl.c | 13 +++---------- soc/swr-mstr-ctrl.h | 13 +++---------- soc/swr-wcd-ctrl.c | 10 +--------- soc/swr-wcd-ctrl.h | 13 +++---------- soc/swrm_port_config.h | 13 +++---------- soc/swrm_registers.h | 13 +++---------- 273 files changed, 390 insertions(+), 2578 deletions(-) diff --git a/asoc/codecs/aqt1000/aqt1000-api.h b/asoc/codecs/aqt1000/aqt1000-api.h index ef2e5267fe77..629e9d67bfc8 100644 --- a/asoc/codecs/aqt1000/aqt1000-api.h +++ b/asoc/codecs/aqt1000/aqt1000-api.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef AQT1000_API_H diff --git a/asoc/codecs/aqt1000/aqt1000-clsh.c b/asoc/codecs/aqt1000/aqt1000-clsh.c index 640795dc7900..b8f403a4e81d 100644 --- a/asoc/codecs/aqt1000/aqt1000-clsh.c +++ b/asoc/codecs/aqt1000/aqt1000-clsh.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/aqt1000/aqt1000-clsh.h b/asoc/codecs/aqt1000/aqt1000-clsh.h index 4a829b0c6925..04b8ca256d67 100644 --- a/asoc/codecs/aqt1000/aqt1000-clsh.h +++ b/asoc/codecs/aqt1000/aqt1000-clsh.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _AQT1000_CLSH_H diff --git a/asoc/codecs/aqt1000/aqt1000-core.c b/asoc/codecs/aqt1000/aqt1000-core.c index e6313c13eafb..e643b6afc899 100644 --- a/asoc/codecs/aqt1000/aqt1000-core.c +++ b/asoc/codecs/aqt1000/aqt1000-core.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/aqt1000/aqt1000-internal.h b/asoc/codecs/aqt1000/aqt1000-internal.h index 19b4b57b176d..abfae1b2bc4c 100644 --- a/asoc/codecs/aqt1000/aqt1000-internal.h +++ b/asoc/codecs/aqt1000/aqt1000-internal.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _AQT1000_INTERNAL_H diff --git a/asoc/codecs/aqt1000/aqt1000-irq.c b/asoc/codecs/aqt1000/aqt1000-irq.c index 321b490befee..b4d2ef6fe374 100644 --- a/asoc/codecs/aqt1000/aqt1000-irq.c +++ b/asoc/codecs/aqt1000/aqt1000-irq.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/aqt1000/aqt1000-irq.h b/asoc/codecs/aqt1000/aqt1000-irq.h index 60be49c21163..cd1a95f37462 100644 --- a/asoc/codecs/aqt1000/aqt1000-irq.h +++ b/asoc/codecs/aqt1000/aqt1000-irq.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __AQT1000_IRQ_H_ diff --git a/asoc/codecs/aqt1000/aqt1000-mbhc.c b/asoc/codecs/aqt1000/aqt1000-mbhc.c index 24f14a46e55e..0d96f71e9541 100644 --- a/asoc/codecs/aqt1000/aqt1000-mbhc.c +++ b/asoc/codecs/aqt1000/aqt1000-mbhc.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/codecs/aqt1000/aqt1000-mbhc.h b/asoc/codecs/aqt1000/aqt1000-mbhc.h index bdf0f5a69cf8..1fad90a2fbd3 100644 --- a/asoc/codecs/aqt1000/aqt1000-mbhc.h +++ b/asoc/codecs/aqt1000/aqt1000-mbhc.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __AQT1000_MBHC_H__ #define __AQT1000_MBHC_H__ diff --git a/asoc/codecs/aqt1000/aqt1000-reg-defaults.h b/asoc/codecs/aqt1000/aqt1000-reg-defaults.h index 5a5da25fa725..edcfe07599f3 100644 --- a/asoc/codecs/aqt1000/aqt1000-reg-defaults.h +++ b/asoc/codecs/aqt1000/aqt1000-reg-defaults.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _AQT1000_REG_DEFAULTS_H diff --git a/asoc/codecs/aqt1000/aqt1000-registers.h b/asoc/codecs/aqt1000/aqt1000-registers.h index 9033466656f7..e2b6770d2746 100644 --- a/asoc/codecs/aqt1000/aqt1000-registers.h +++ b/asoc/codecs/aqt1000/aqt1000-registers.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _AQT1000_REGISTERS_H diff --git a/asoc/codecs/aqt1000/aqt1000-regmap.c b/asoc/codecs/aqt1000/aqt1000-regmap.c index e38c32748f31..67bcd26d5029 100644 --- a/asoc/codecs/aqt1000/aqt1000-regmap.c +++ b/asoc/codecs/aqt1000/aqt1000-regmap.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/aqt1000/aqt1000-routing.h b/asoc/codecs/aqt1000/aqt1000-routing.h index 7ae3276ff79a..6a3d8953aff6 100644 --- a/asoc/codecs/aqt1000/aqt1000-routing.h +++ b/asoc/codecs/aqt1000/aqt1000-routing.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef AQT1000_ROUTING_H #define AQT1000_ROUTING_H diff --git a/asoc/codecs/aqt1000/aqt1000-utils.c b/asoc/codecs/aqt1000/aqt1000-utils.c index f1c16de8a686..a788b5d37ffc 100644 --- a/asoc/codecs/aqt1000/aqt1000-utils.c +++ b/asoc/codecs/aqt1000/aqt1000-utils.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/aqt1000/aqt1000-utils.h b/asoc/codecs/aqt1000/aqt1000-utils.h index 9f68cf12b064..c2c7aeb3cc35 100644 --- a/asoc/codecs/aqt1000/aqt1000-utils.h +++ b/asoc/codecs/aqt1000/aqt1000-utils.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD9XXX_UTILS_H__ diff --git a/asoc/codecs/aqt1000/aqt1000.c b/asoc/codecs/aqt1000/aqt1000.c index 8463d8223060..59a9d87266db 100644 --- a/asoc/codecs/aqt1000/aqt1000.c +++ b/asoc/codecs/aqt1000/aqt1000.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/codecs/aqt1000/aqt1000.h b/asoc/codecs/aqt1000/aqt1000.h index 7b870db7a492..88fdc90d2c27 100644 --- a/asoc/codecs/aqt1000/aqt1000.h +++ b/asoc/codecs/aqt1000/aqt1000.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef AQT1000_H diff --git a/asoc/codecs/aqt1000/pdata.h b/asoc/codecs/aqt1000/pdata.h index 2c29848d7989..89fcb3cee3de 100644 --- a/asoc/codecs/aqt1000/pdata.h +++ b/asoc/codecs/aqt1000/pdata.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _AQT1000_PDATA_H_ diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index ba72fd8f6107..2bbbc9e95a4b 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/audio-ext-clk-up.h b/asoc/codecs/audio-ext-clk-up.h index 8a0232e11d0f..655189731773 100644 --- a/asoc/codecs/audio-ext-clk-up.h +++ b/asoc/codecs/audio-ext-clk-up.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __AUDIO_EXT_CLK_UP_H_ diff --git a/asoc/codecs/audio-ext-clk.c b/asoc/codecs/audio-ext-clk.c index 72f16f5848dd..c06c9c5662fe 100644 --- a/asoc/codecs/audio-ext-clk.c +++ b/asoc/codecs/audio-ext-clk.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/bolero/bolero-cdc-registers.h b/asoc/codecs/bolero/bolero-cdc-registers.h index d413ff9616f8..5f88c85988f8 100644 --- a/asoc/codecs/bolero/bolero-cdc-registers.h +++ b/asoc/codecs/bolero/bolero-cdc-registers.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _BOLERO_CDC_REGISTERS_H diff --git a/asoc/codecs/bolero/bolero-cdc-regmap.c b/asoc/codecs/bolero/bolero-cdc-regmap.c index ecc13243d999..8f55ff29b50b 100644 --- a/asoc/codecs/bolero/bolero-cdc-regmap.c +++ b/asoc/codecs/bolero/bolero-cdc-regmap.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/bolero/bolero-cdc-tables.c b/asoc/codecs/bolero/bolero-cdc-tables.c index 2407ac70e8f3..e92508fd0280 100644 --- a/asoc/codecs/bolero/bolero-cdc-tables.c +++ b/asoc/codecs/bolero/bolero-cdc-tables.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/bolero/bolero-cdc-utils.c b/asoc/codecs/bolero/bolero-cdc-utils.c index b7f41420d0fe..6acf69eac71f 100644 --- a/asoc/codecs/bolero/bolero-cdc-utils.c +++ b/asoc/codecs/bolero/bolero-cdc-utils.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 68a7ff5c2e78..430a0b3e5eb8 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index a00c06530c2e..7193a8ccf176 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef BOLERO_CDC_H diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 71750fb37adf..8b7c0923cb01 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _BOLERO_INTERNAL_H diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 8aca6fdc1ffa..aa49e898bc5b 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index e58cbd5c989e..2051e5f4e868 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index eccd8dbdd3b1..ed052ae58a73 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 2cd1b4360e46..823954e410df 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/bolero/wsa-macro.h b/asoc/codecs/bolero/wsa-macro.h index ec1aa9a280f6..ec8f5249b2d6 100644 --- a/asoc/codecs/bolero/wsa-macro.h +++ b/asoc/codecs/bolero/wsa-macro.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef WSA_MACRO_H #define WSA_MACRO_H diff --git a/asoc/codecs/core.h b/asoc/codecs/core.h index c102a55e24c0..ab0f0c724156 100644 --- a/asoc/codecs/core.h +++ b/asoc/codecs/core.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __MFD_TABLA_CORE_H__ diff --git a/asoc/codecs/cpe_cmi.h b/asoc/codecs/cpe_cmi.h index c145a8a64261..21df2ae2b837 100644 --- a/asoc/codecs/cpe_cmi.h +++ b/asoc/codecs/cpe_cmi.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __CPE_CMI_H__ diff --git a/asoc/codecs/cpe_core.h b/asoc/codecs/cpe_core.h index 99504c5c9625..989c4a9d1d2f 100644 --- a/asoc/codecs/cpe_core.h +++ b/asoc/codecs/cpe_core.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __CPE_CORE_H__ diff --git a/asoc/codecs/cpe_err.h b/asoc/codecs/cpe_err.h index b70dc490fb1a..5a2dea1bc2b4 100644 --- a/asoc/codecs/cpe_err.h +++ b/asoc/codecs/cpe_err.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015, 2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __CPE_ERR__ diff --git a/asoc/codecs/csra66x0/csra66x0.c b/asoc/codecs/csra66x0/csra66x0.c index 2189f9bfd873..97041a19d8b7 100644 --- a/asoc/codecs/csra66x0/csra66x0.c +++ b/asoc/codecs/csra66x0/csra66x0.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/codecs/csra66x0/csra66x0.h b/asoc/codecs/csra66x0/csra66x0.h index 43d83d847a52..c449d670dc37 100644 --- a/asoc/codecs/csra66x0/csra66x0.h +++ b/asoc/codecs/csra66x0/csra66x0.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _CSRA66X0_H diff --git a/asoc/codecs/ep92/ep92.c b/asoc/codecs/ep92/ep92.c index 52f5e6d0b98a..aac1d883c3f0 100644 --- a/asoc/codecs/ep92/ep92.c +++ b/asoc/codecs/ep92/ep92.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/ep92/ep92.h b/asoc/codecs/ep92/ep92.h index ad067ea1dc93..7aafab2aa8f3 100644 --- a/asoc/codecs/ep92/ep92.h +++ b/asoc/codecs/ep92/ep92.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __EP92_H__ diff --git a/asoc/codecs/msm-cdc-pinctrl.c b/asoc/codecs/msm-cdc-pinctrl.c index 79e322f1a277..901864ab5a07 100644 --- a/asoc/codecs/msm-cdc-pinctrl.c +++ b/asoc/codecs/msm-cdc-pinctrl.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/msm-cdc-pinctrl.h b/asoc/codecs/msm-cdc-pinctrl.h index 4286fffa3bf4..3bd344318b6c 100644 --- a/asoc/codecs/msm-cdc-pinctrl.h +++ b/asoc/codecs/msm-cdc-pinctrl.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __MFD_CDC_PINCTRL_H_ diff --git a/asoc/codecs/msm-cdc-supply.c b/asoc/codecs/msm-cdc-supply.c index 1b3c5f9381cf..751d81e06897 100644 --- a/asoc/codecs/msm-cdc-supply.c +++ b/asoc/codecs/msm-cdc-supply.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/msm-cdc-supply.h b/asoc/codecs/msm-cdc-supply.h index b6516fa944be..6d7b41a8d49c 100644 --- a/asoc/codecs/msm-cdc-supply.h +++ b/asoc/codecs/msm-cdc-supply.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2016, 2018 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __CODEC_POWER_SUPPLY_H__ diff --git a/asoc/codecs/msm_hdmi_codec_rx.c b/asoc/codecs/msm_hdmi_codec_rx.c index 07e1cef370d5..3e4c2d5ca6ce 100644 --- a/asoc/codecs/msm_hdmi_codec_rx.c +++ b/asoc/codecs/msm_hdmi_codec_rx.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/codecs/msm_stub.c b/asoc/codecs/msm_stub.c index 68e55ae1da16..5bfaa495261b 100644 --- a/asoc/codecs/msm_stub.c +++ b/asoc/codecs/msm_stub.c @@ -1,13 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2011-2014, 2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + */ #include #include diff --git a/asoc/codecs/pdata.h b/asoc/codecs/pdata.h index d38ae84914b7..c19c11893d70 100644 --- a/asoc/codecs/pdata.h +++ b/asoc/codecs/pdata.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __MFD_WCD9XXX_PDATA_H__ diff --git a/asoc/codecs/wcd-clsh.c b/asoc/codecs/wcd-clsh.c index d119b837c3f2..8c2ae689312e 100644 --- a/asoc/codecs/wcd-clsh.c +++ b/asoc/codecs/wcd-clsh.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd-clsh.h b/asoc/codecs/wcd-clsh.h index df305bcf7aa1..29e5da5a6883 100644 --- a/asoc/codecs/wcd-clsh.h +++ b/asoc/codecs/wcd-clsh.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _WCD_CLSH diff --git a/asoc/codecs/wcd-dsp-mgr.c b/asoc/codecs/wcd-dsp-mgr.c index b45a9b3b7516..612161f094ed 100644 --- a/asoc/codecs/wcd-dsp-mgr.c +++ b/asoc/codecs/wcd-dsp-mgr.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/codecs/wcd-dsp-utils.c b/asoc/codecs/wcd-dsp-utils.c index 1c95d48a1a81..2e24de9419ab 100644 --- a/asoc/codecs/wcd-dsp-utils.c +++ b/asoc/codecs/wcd-dsp-utils.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd-dsp-utils.h b/asoc/codecs/wcd-dsp-utils.h index a530a1c3b67d..1016fc099351 100644 --- a/asoc/codecs/wcd-dsp-utils.h +++ b/asoc/codecs/wcd-dsp-utils.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD_DSP_UTILS_H__ diff --git a/asoc/codecs/wcd-irq.c b/asoc/codecs/wcd-irq.c index 48495f553999..37ed56697990 100644 --- a/asoc/codecs/wcd-irq.c +++ b/asoc/codecs/wcd-irq.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index 1f0c5ba4d1c1..2170869342b3 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/codecs/wcd-mbhc-adc.h b/asoc/codecs/wcd-mbhc-adc.h index 31161089e793..9383d1ad3bca 100644 --- a/asoc/codecs/wcd-mbhc-adc.h +++ b/asoc/codecs/wcd-mbhc-adc.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD_MBHC_ADC_H__ #define __WCD_MBHC_ADC_H__ diff --git a/asoc/codecs/wcd-mbhc-legacy.c b/asoc/codecs/wcd-mbhc-legacy.c index 9ebdeca01fff..e4196b10359d 100644 --- a/asoc/codecs/wcd-mbhc-legacy.c +++ b/asoc/codecs/wcd-mbhc-legacy.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/codecs/wcd-mbhc-legacy.h b/asoc/codecs/wcd-mbhc-legacy.h index af3a7dc6d06b..a79b673313c4 100644 --- a/asoc/codecs/wcd-mbhc-legacy.h +++ b/asoc/codecs/wcd-mbhc-legacy.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD_MBHC_LEGACY_H__ #define __WCD_MBHC_LEGACY_H__ diff --git a/asoc/codecs/wcd-mbhc-v2-api.h b/asoc/codecs/wcd-mbhc-v2-api.h index 7b6e94507ad0..d89da4caa875 100644 --- a/asoc/codecs/wcd-mbhc-v2-api.h +++ b/asoc/codecs/wcd-mbhc-v2-api.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD_MBHC_V2_API_H__ #define __WCD_MBHC_V2_API_H__ diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 12057654510d..79944b588496 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/codecs/wcd-mbhc-v2.h b/asoc/codecs/wcd-mbhc-v2.h index fafac14083a4..6915344ae08d 100644 --- a/asoc/codecs/wcd-mbhc-v2.h +++ b/asoc/codecs/wcd-mbhc-v2.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD_MBHC_V2_H__ #define __WCD_MBHC_V2_H__ diff --git a/asoc/codecs/wcd-spi-registers.h b/asoc/codecs/wcd-spi-registers.h index 4e579696cc49..df48cd076409 100644 --- a/asoc/codecs/wcd-spi-registers.h +++ b/asoc/codecs/wcd-spi-registers.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2016, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD_SPI_REGISTERS_H__ diff --git a/asoc/codecs/wcd-spi.c b/asoc/codecs/wcd-spi.c index bb9333485e3b..9acf24afdcf7 100644 --- a/asoc/codecs/wcd-spi.c +++ b/asoc/codecs/wcd-spi.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd9335-regmap.c b/asoc/codecs/wcd9335-regmap.c index a21257c85e07..9d1ccb84e067 100644 --- a/asoc/codecs/wcd9335-regmap.c +++ b/asoc/codecs/wcd9335-regmap.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd9335-tables.c b/asoc/codecs/wcd9335-tables.c index 7df2778f3498..cd223c9a83f0 100644 --- a/asoc/codecs/wcd9335-tables.c +++ b/asoc/codecs/wcd9335-tables.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index d7db8ee1fa50..afd8c5d62e94 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/codecs/wcd9335.h b/asoc/codecs/wcd9335.h index f5f103853b30..105fc2eca5e1 100644 --- a/asoc/codecs/wcd9335.h +++ b/asoc/codecs/wcd9335.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef WCD9335_H #define WCD9335_H diff --git a/asoc/codecs/wcd9335_irq.h b/asoc/codecs/wcd9335_irq.h index c666d3144359..ae81a1ab450b 100644 --- a/asoc/codecs/wcd9335_irq.h +++ b/asoc/codecs/wcd9335_irq.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD9335_IRQ_H_ diff --git a/asoc/codecs/wcd9335_registers.h b/asoc/codecs/wcd9335_registers.h index c50430d4278f..4af4e1b5fd74 100644 --- a/asoc/codecs/wcd9335_registers.h +++ b/asoc/codecs/wcd9335_registers.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _WCD9335_REGISTERS_H diff --git a/asoc/codecs/wcd934x/wcd934x-dsd.c b/asoc/codecs/wcd934x/wcd934x-dsd.c index eea18c3d951b..2069c8d14d4b 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsd.c +++ b/asoc/codecs/wcd934x/wcd934x-dsd.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd934x/wcd934x-dsd.h b/asoc/codecs/wcd934x/wcd934x-dsd.h index 834b96cd1805..cd6b57924fb3 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsd.h +++ b/asoc/codecs/wcd934x/wcd934x-dsd.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD934X_DSD_H__ diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c index f18cc81a91f8..a7a836faef14 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h index 5ce4fd85da13..8035176fe100 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD934X_DSP_CNTL_H__ diff --git a/asoc/codecs/wcd934x/wcd934x-mbhc.c b/asoc/codecs/wcd934x/wcd934x-mbhc.c index bfe1e17a4534..f23dcf1e46f6 100644 --- a/asoc/codecs/wcd934x/wcd934x-mbhc.c +++ b/asoc/codecs/wcd934x/wcd934x-mbhc.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/codecs/wcd934x/wcd934x-mbhc.h b/asoc/codecs/wcd934x/wcd934x-mbhc.h index 53c886da0f6b..07e6207d7495 100644 --- a/asoc/codecs/wcd934x/wcd934x-mbhc.h +++ b/asoc/codecs/wcd934x/wcd934x-mbhc.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD934X_MBHC_H__ #define __WCD934X_MBHC_H__ diff --git a/asoc/codecs/wcd934x/wcd934x-regmap.c b/asoc/codecs/wcd934x/wcd934x-regmap.c index e62b69c6931f..051586fa6172 100644 --- a/asoc/codecs/wcd934x/wcd934x-regmap.c +++ b/asoc/codecs/wcd934x/wcd934x-regmap.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd934x/wcd934x-routing.h b/asoc/codecs/wcd934x/wcd934x-routing.h index 8adeef79a7f0..51a361848a3f 100644 --- a/asoc/codecs/wcd934x/wcd934x-routing.h +++ b/asoc/codecs/wcd934x/wcd934x-routing.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef WCD934X_ROUTING_H #define WCD934X_ROUTING_H diff --git a/asoc/codecs/wcd934x/wcd934x-tables.c b/asoc/codecs/wcd934x/wcd934x-tables.c index 4e6c2fb2a1cc..afe7939c43e9 100644 --- a/asoc/codecs/wcd934x/wcd934x-tables.c +++ b/asoc/codecs/wcd934x/wcd934x-tables.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2016, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 0ca7dbbe4e6b..71a680622ea4 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/codecs/wcd934x/wcd934x.h b/asoc/codecs/wcd934x/wcd934x.h index 926096a7c12f..c0aec9efc061 100644 --- a/asoc/codecs/wcd934x/wcd934x.h +++ b/asoc/codecs/wcd934x/wcd934x.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef WCD934X_H #define WCD934X_H diff --git a/asoc/codecs/wcd934x/wcd934x_irq.h b/asoc/codecs/wcd934x/wcd934x_irq.h index 1a18be376eb1..7c054ea436c9 100644 --- a/asoc/codecs/wcd934x/wcd934x_irq.h +++ b/asoc/codecs/wcd934x/wcd934x_irq.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD934X_IRQ_H_ diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index f1a752bc8c9b..46c0c022b8d8 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _WCD937X_INTERNAL_H diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index 96343b8ce391..1e0fcf8082ea 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.h b/asoc/codecs/wcd937x/wcd937x-mbhc.h index 554cb88781fc..c0689e4bf0c7 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.h +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD937X_MBHC_H__ #define __WCD937X_MBHC_H__ diff --git a/asoc/codecs/wcd937x/wcd937x-registers.h b/asoc/codecs/wcd937x/wcd937x-registers.h index 1f89f803c0d3..c7ee8e6d3266 100644 --- a/asoc/codecs/wcd937x/wcd937x-registers.h +++ b/asoc/codecs/wcd937x/wcd937x-registers.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _WCD937X_REGISTERS_H diff --git a/asoc/codecs/wcd937x/wcd937x-regmap.c b/asoc/codecs/wcd937x/wcd937x-regmap.c index 0d15c105f2c8..205dfe461121 100644 --- a/asoc/codecs/wcd937x/wcd937x-regmap.c +++ b/asoc/codecs/wcd937x/wcd937x-regmap.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd937x/wcd937x-tables.c b/asoc/codecs/wcd937x/wcd937x-tables.c index 5baf7733514f..a1f6d10f022b 100644 --- a/asoc/codecs/wcd937x/wcd937x-tables.c +++ b/asoc/codecs/wcd937x/wcd937x-tables.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018 , The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 27e3cfaaa9f5..ea0e2ee9e64b 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd937x/wcd937x.h b/asoc/codecs/wcd937x/wcd937x.h index 49905d77f54c..14504609411c 100644 --- a/asoc/codecs/wcd937x/wcd937x.h +++ b/asoc/codecs/wcd937x/wcd937x.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _WCD937X_H diff --git a/asoc/codecs/wcd937x/wcd937x_slave.c b/asoc/codecs/wcd937x/wcd937x_slave.c index baab26fe6de3..61b6a0c1923d 100644 --- a/asoc/codecs/wcd937x/wcd937x_slave.c +++ b/asoc/codecs/wcd937x/wcd937x_slave.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd9xxx-common-v2.c b/asoc/codecs/wcd9xxx-common-v2.c index 478c0c6d72e6..78cfc15a5981 100644 --- a/asoc/codecs/wcd9xxx-common-v2.c +++ b/asoc/codecs/wcd9xxx-common-v2.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd9xxx-common-v2.h b/asoc/codecs/wcd9xxx-common-v2.h index 53c9a84b51ad..94679e88f527 100644 --- a/asoc/codecs/wcd9xxx-common-v2.h +++ b/asoc/codecs/wcd9xxx-common-v2.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _WCD9XXX_COMMON_V2 diff --git a/asoc/codecs/wcd9xxx-core-init.c b/asoc/codecs/wcd9xxx-core-init.c index e575e0d3472e..ee1ba516b1a6 100644 --- a/asoc/codecs/wcd9xxx-core-init.c +++ b/asoc/codecs/wcd9xxx-core-init.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index 4b7c58003df2..ba4dc333ab40 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd9xxx-irq.c b/asoc/codecs/wcd9xxx-irq.c index ad15470a393f..92841932ca12 100644 --- a/asoc/codecs/wcd9xxx-irq.c +++ b/asoc/codecs/wcd9xxx-irq.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/codecs/wcd9xxx-irq.h b/asoc/codecs/wcd9xxx-irq.h index dfe0b929a84b..83f86b3beff2 100644 --- a/asoc/codecs/wcd9xxx-irq.h +++ b/asoc/codecs/wcd9xxx-irq.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd9xxx-regmap.h b/asoc/codecs/wcd9xxx-regmap.h index 1ac32bb065fb..8019fa12c0c3 100644 --- a/asoc/codecs/wcd9xxx-regmap.h +++ b/asoc/codecs/wcd9xxx-regmap.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _WCD9XXX_REGMAP_ diff --git a/asoc/codecs/wcd9xxx-resmgr-v2.c b/asoc/codecs/wcd9xxx-resmgr-v2.c index d390558ce660..f14ba5e73c6e 100644 --- a/asoc/codecs/wcd9xxx-resmgr-v2.c +++ b/asoc/codecs/wcd9xxx-resmgr-v2.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/codecs/wcd9xxx-resmgr-v2.h b/asoc/codecs/wcd9xxx-resmgr-v2.h index e9d3531e262e..d1aeb04cec8f 100644 --- a/asoc/codecs/wcd9xxx-resmgr-v2.h +++ b/asoc/codecs/wcd9xxx-resmgr-v2.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD9XXX_COMMON_V2_H__ #define __WCD9XXX_COMMON_V2_H__ diff --git a/asoc/codecs/wcd9xxx-rst.c b/asoc/codecs/wcd9xxx-rst.c index c1f456ca0783..84225deb47c3 100644 --- a/asoc/codecs/wcd9xxx-rst.c +++ b/asoc/codecs/wcd9xxx-rst.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ diff --git a/asoc/codecs/wcd9xxx-slimslave.c b/asoc/codecs/wcd9xxx-slimslave.c index 66a83320d03b..3636bb55d261 100644 --- a/asoc/codecs/wcd9xxx-slimslave.c +++ b/asoc/codecs/wcd9xxx-slimslave.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/codecs/wcd9xxx-slimslave.h b/asoc/codecs/wcd9xxx-slimslave.h index 5132e43efad0..9ab74043b7bb 100644 --- a/asoc/codecs/wcd9xxx-slimslave.h +++ b/asoc/codecs/wcd9xxx-slimslave.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD9XXX_SLIMSLAVE_H_ diff --git a/asoc/codecs/wcd9xxx-soc-init.c b/asoc/codecs/wcd9xxx-soc-init.c index fa8abb7de5e4..4e2d837c29e8 100644 --- a/asoc/codecs/wcd9xxx-soc-init.c +++ b/asoc/codecs/wcd9xxx-soc-init.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd9xxx-utils.c b/asoc/codecs/wcd9xxx-utils.c index 8ca55f859551..0e238fcb55de 100644 --- a/asoc/codecs/wcd9xxx-utils.c +++ b/asoc/codecs/wcd9xxx-utils.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd9xxx-utils.h b/asoc/codecs/wcd9xxx-utils.h index a7ec56c2da0a..048c61c232cc 100644 --- a/asoc/codecs/wcd9xxx-utils.h +++ b/asoc/codecs/wcd9xxx-utils.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD9XXX_UTILS_H__ diff --git a/asoc/codecs/wcd_cmi_api.h b/asoc/codecs/wcd_cmi_api.h index 39be6417e327..bc7bd8621efb 100644 --- a/asoc/codecs/wcd_cmi_api.h +++ b/asoc/codecs/wcd_cmi_api.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2014, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __CMI_API__ diff --git a/asoc/codecs/wcd_cpe_core.c b/asoc/codecs/wcd_cpe_core.c index 2e154e701c8c..1fa6eae59863 100644 --- a/asoc/codecs/wcd_cpe_core.c +++ b/asoc/codecs/wcd_cpe_core.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd_cpe_core.h b/asoc/codecs/wcd_cpe_core.h index 269c5f2a5b00..ad2ff106abc5 100644 --- a/asoc/codecs/wcd_cpe_core.h +++ b/asoc/codecs/wcd_cpe_core.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef WCD_CPE_CORE_H diff --git a/asoc/codecs/wcd_cpe_services.c b/asoc/codecs/wcd_cpe_services.c index e584cf05a6ef..a443963b4596 100644 --- a/asoc/codecs/wcd_cpe_services.c +++ b/asoc/codecs/wcd_cpe_services.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wcd_cpe_services.h b/asoc/codecs/wcd_cpe_services.h index 68eb61996a69..1627cd888d2c 100644 --- a/asoc/codecs/wcd_cpe_services.h +++ b/asoc/codecs/wcd_cpe_services.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __CPE_SERVICES__ diff --git a/asoc/codecs/wcdcal-hwdep.c b/asoc/codecs/wcdcal-hwdep.c index 31eae69b1f4b..9c5d0e2962b4 100644 --- a/asoc/codecs/wcdcal-hwdep.c +++ b/asoc/codecs/wcdcal-hwdep.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include #include diff --git a/asoc/codecs/wcdcal-hwdep.h b/asoc/codecs/wcdcal-hwdep.h index 632e2f11f323..05f1c48e265b 100644 --- a/asoc/codecs/wcdcal-hwdep.h +++ b/asoc/codecs/wcdcal-hwdep.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD9XXX_HWDEP_H__ #define __WCD9XXX_HWDEP_H__ diff --git a/asoc/codecs/wsa881x-registers.h b/asoc/codecs/wsa881x-registers.h index 825a5f034da8..c39edef2203f 100644 --- a/asoc/codecs/wsa881x-registers.h +++ b/asoc/codecs/wsa881x-registers.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef WSA881X_REGISTERS_H diff --git a/asoc/codecs/wsa881x-regmap.c b/asoc/codecs/wsa881x-regmap.c index 63bbbfa6beab..8663db9776db 100644 --- a/asoc/codecs/wsa881x-regmap.c +++ b/asoc/codecs/wsa881x-regmap.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wsa881x-tables.c b/asoc/codecs/wsa881x-tables.c index 4f1212be9c5b..e53183252ae7 100644 --- a/asoc/codecs/wsa881x-tables.c +++ b/asoc/codecs/wsa881x-tables.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wsa881x-temp-sensor.c b/asoc/codecs/wsa881x-temp-sensor.c index 2a1291f34f02..5f6840d1f88c 100644 --- a/asoc/codecs/wsa881x-temp-sensor.c +++ b/asoc/codecs/wsa881x-temp-sensor.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wsa881x-temp-sensor.h b/asoc/codecs/wsa881x-temp-sensor.h index 26828b716d07..0d61c99fa2d5 100644 --- a/asoc/codecs/wsa881x-temp-sensor.h +++ b/asoc/codecs/wsa881x-temp-sensor.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef WSA881X_TEMP_SENSOR_H #define WSA881X_TEMP_SENSOR_H diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index c8ae53d27b76..238430cc0522 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/codecs/wsa881x.h b/asoc/codecs/wsa881x.h index 9f998e37f9e5..ae30d4bd3736 100644 --- a/asoc/codecs/wsa881x.h +++ b/asoc/codecs/wsa881x.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _WSA881X_H diff --git a/asoc/device_event.h b/asoc/device_event.h index 408d114e3c84..e63656ecd627 100644 --- a/asoc/device_event.h +++ b/asoc/device_event.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2014, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __DEVICE_EVENT_H diff --git a/asoc/machine_815x_init.c b/asoc/machine_815x_init.c index ab1bdc1f6d29..ff01a90e2c54 100644 --- a/asoc/machine_815x_init.c +++ b/asoc/machine_815x_init.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* -Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 and -only version 2 as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -* -*/ + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + */ #include #include diff --git a/asoc/machine_815x_init.h b/asoc/machine_815x_init.h index 4ee6d4f96dc2..d096d972e1ef 100644 --- a/asoc/machine_815x_init.h +++ b/asoc/machine_815x_init.h @@ -1,15 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 and -only version 2 as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -* */ #ifndef __MACHINE_815X_INIT_H__ diff --git a/asoc/msm-audio-effects-q6-v2.c b/asoc/msm-audio-effects-q6-v2.c index b4dc30ab5948..dcc7474cef13 100644 --- a/asoc/msm-audio-effects-q6-v2.c +++ b/asoc/msm-audio-effects-q6-v2.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index d35ed890d66f..1503d9d2eb79 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ diff --git a/asoc/msm-cpe-lsm.c b/asoc/msm-cpe-lsm.c index 4094c1ed8bf7..d7286e3dad36 100644 --- a/asoc/msm-cpe-lsm.c +++ b/asoc/msm-cpe-lsm.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index 7654e561f00d..36fa5dd2e64a 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ diff --git a/asoc/msm-dai-q6-hdmi-v2.c b/asoc/msm-dai-q6-hdmi-v2.c index 4291077fcbb9..69332fc073ac 100644 --- a/asoc/msm-dai-q6-hdmi-v2.c +++ b/asoc/msm-dai-q6-hdmi-v2.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 9516867c1aae..b77c08f02200 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/msm-dai-q6-v2.h b/asoc/msm-dai-q6-v2.h index 2327cfd72eca..91737c9a7586 100644 --- a/asoc/msm-dai-q6-v2.h +++ b/asoc/msm-dai-q6-v2.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __MSM_DAI_Q6_PDATA_H__ diff --git a/asoc/msm-dai-slim.c b/asoc/msm-dai-slim.c index e8bdf13fdc6c..db8f3dd64fae 100644 --- a/asoc/msm-dai-slim.c +++ b/asoc/msm-dai-slim.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/msm-dai-stub-v2.c b/asoc/msm-dai-stub-v2.c index c8b6b7736631..76ea52cde288 100644 --- a/asoc/msm-dai-stub-v2.c +++ b/asoc/msm-dai-stub-v2.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/msm-dolby-common.h b/asoc/msm-dolby-common.h index 885d283ef03d..c56e11523043 100644 --- a/asoc/msm-dolby-common.h +++ b/asoc/msm-dolby-common.h @@ -1,13 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2013-2014, 2016 The Linux Foundation. All rights reserved. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved. */ #ifndef _MSM_DOLBY_COMMON_H_ diff --git a/asoc/msm-dolby-dap-config.h b/asoc/msm-dolby-dap-config.h index b2b713907130..f7d4fa94a47a 100644 --- a/asoc/msm-dolby-dap-config.h +++ b/asoc/msm-dolby-dap-config.h @@ -1,13 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Copyright (c) 2013-2014, 2017-2018, The Linux Foundation. All rights reserved. */ #ifndef _MSM_DOLBY_DAP_CONFIG_H_ diff --git a/asoc/msm-ds2-dap-config.c b/asoc/msm-ds2-dap-config.c index ad7a3c6a406f..4971907360e8 100644 --- a/asoc/msm-ds2-dap-config.c +++ b/asoc/msm-ds2-dap-config.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/msm-ds2-dap-config.h b/asoc/msm-ds2-dap-config.h index 4d6b5eb3d210..d734790fcbee 100644 --- a/asoc/msm-ds2-dap-config.h +++ b/asoc/msm-ds2-dap-config.h @@ -1,13 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2013-2014, 2017-2018 The Linux Foundation. All rights reserved. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. */ #ifndef _MSM_DS2_DAP_CONFIG_H_ diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 391d71946957..67f262386f16 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/msm-pcm-afe-v2.c b/asoc/msm-pcm-afe-v2.c index 3a65fe5d4df6..1565a76ea097 100644 --- a/asoc/msm-pcm-afe-v2.c +++ b/asoc/msm-pcm-afe-v2.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ diff --git a/asoc/msm-pcm-afe-v2.h b/asoc/msm-pcm-afe-v2.h index 926b626de37d..ca9dfccc604f 100644 --- a/asoc/msm-pcm-afe-v2.h +++ b/asoc/msm-pcm-afe-v2.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2012,2015-2016 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _MSM_PCM_AFE_H #define _MSM_PCM_AFE_H diff --git a/asoc/msm-pcm-dtmf-v2.c b/asoc/msm-pcm-dtmf-v2.c index 77dc81ce9c21..ecec8bf9b5df 100644 --- a/asoc/msm-pcm-dtmf-v2.c +++ b/asoc/msm-pcm-dtmf-v2.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2013-2014, 2017-2018 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/msm-pcm-host-voice-v2.c b/asoc/msm-pcm-host-voice-v2.c index 7486ad7dc80c..1cc5c161ea66 100644 --- a/asoc/msm-pcm-host-voice-v2.c +++ b/asoc/msm-pcm-host-voice-v2.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/msm-pcm-hostless.c b/asoc/msm-pcm-hostless.c index e2850a421d67..9c69e12e5138 100644 --- a/asoc/msm-pcm-hostless.c +++ b/asoc/msm-pcm-hostless.c @@ -1,13 +1,5 @@ -/* Copyright (c) 2011-2014, 2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2011-2014, 2017, The Linux Foundation. All rights reserved. */ #include diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index 32c727aca14a..3ef6280bbcaa 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index be34903d929d..8e5c423433d5 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 5da97952c8f5..ad25aae605db 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ diff --git a/asoc/msm-pcm-q6-v2.h b/asoc/msm-pcm-q6-v2.h index 201c7e580494..ca18a85ccd68 100644 --- a/asoc/msm-pcm-q6-v2.h +++ b/asoc/msm-pcm-q6-v2.h @@ -1,19 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org. */ #ifndef _MSM_PCM_H diff --git a/asoc/msm-pcm-routing-devdep.c b/asoc/msm-pcm-routing-devdep.c index 7335951522b3..6d26c54e5483 100644 --- a/asoc/msm-pcm-routing-devdep.c +++ b/asoc/msm-pcm-routing-devdep.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2014, 2016-2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/msm-pcm-routing-devdep.h b/asoc/msm-pcm-routing-devdep.h index 8a0b96700329..651edd9d96b6 100644 --- a/asoc/msm-pcm-routing-devdep.h +++ b/asoc/msm-pcm-routing-devdep.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2014-2015, 2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _MSM_PCM_ROUTING_DEVDEP_H_ diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 0d07dd4773af..2d1ec243c029 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index f06dfc003cb9..92fd3c205d81 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _MSM_PCM_ROUTING_H #define _MSM_PCM_ROUTING_H diff --git a/asoc/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c index 38da7e7d765a..5a7ee0ad67d3 100644 --- a/asoc/msm-pcm-voice-v2.c +++ b/asoc/msm-pcm-voice-v2.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/msm-pcm-voice-v2.h b/asoc/msm-pcm-voice-v2.h index 60f5adcf5757..671c1aad522e 100644 --- a/asoc/msm-pcm-voice-v2.h +++ b/asoc/msm-pcm-voice-v2.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _MSM_PCM_VOICE_H #define _MSM_PCM_VOICE_H diff --git a/asoc/msm-pcm-voip-v2.c b/asoc/msm-pcm-voip-v2.c index b8d7390bbb8a..ba0e7984ac32 100644 --- a/asoc/msm-pcm-voip-v2.c +++ b/asoc/msm-pcm-voip-v2.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index a8e20bc69ba6..1a2c7aa15b15 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/msm-qti-pp-config.h b/asoc/msm-qti-pp-config.h index edbd603487c8..ddb80831f843 100644 --- a/asoc/msm-qti-pp-config.h +++ b/asoc/msm-qti-pp-config.h @@ -1,13 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _MSM_QTI_PP_H_ diff --git a/asoc/msm-slim-dma.h b/asoc/msm-slim-dma.h index daf394bffaff..f179a2e4dba7 100644 --- a/asoc/msm-slim-dma.h +++ b/asoc/msm-slim-dma.h @@ -1,15 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2014, 2017 The Linux Foundation. All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #ifndef _MSM_SLIMBUS_DMA_H #define _MSM_SLIMBUS_DMA_H diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index f44e87d44d57..ed461820b809 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/platform_init.c b/asoc/platform_init.c index 79d0e41998f5..3b72ebe49c9d 100644 --- a/asoc/platform_init.c +++ b/asoc/platform_init.c @@ -1,15 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* -Copyright (c) 2017, The Linux Foundation. All rights reserved. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 and -only version 2 as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -* + * Copyright (c) 2017 The Linux Foundation. All rights reserved. */ #include diff --git a/asoc/platform_init.h b/asoc/platform_init.h index db9b32d2ee5c..ff5eafb6b85e 100644 --- a/asoc/platform_init.h +++ b/asoc/platform_init.h @@ -1,16 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* -Copyright (c) 2017, The Linux Foundation. All rights reserved. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 and -only version 2 as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -* -*/ + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ #ifndef __PLATFORM_INIT_H__ #define __PLATFORM_INIT_H__ diff --git a/asoc/qcs405.c b/asoc/qcs405.c index a0f54600e0bb..4d1de74b3746 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/asoc/sa8155.c b/asoc/sa8155.c index a477a85a7592..879119584db4 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* * Copyright 2011, The Android Open Source Project diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 59bbf69664be..a2abeb63731c 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/asoc/sm8150.c b/asoc/sm8150.c index 30f3b130a5f1..7328be3eaf19 100644 --- a/asoc/sm8150.c +++ b/asoc/sm8150.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/config/qcs405autoconf.h b/config/qcs405autoconf.h index fd9407bdbce3..07e5429da89b 100644 --- a/config/qcs405autoconf.h +++ b/config/qcs405autoconf.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define CONFIG_PINCTRL_LPI 1 diff --git a/config/sdxpoorwillsautoconf.h b/config/sdxpoorwillsautoconf.h index 7b7dac403b63..9d7158ec6d55 100644 --- a/config/sdxpoorwillsautoconf.h +++ b/config/sdxpoorwillsautoconf.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define CONFIG_PINCTRL_WCD 1 diff --git a/config/sm6150autoconf.h b/config/sm6150autoconf.h index d69a9dec0f2e..2a63d0423ce3 100644 --- a/config/sm6150autoconf.h +++ b/config/sm6150autoconf.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define CONFIG_PINCTRL_WCD 1 diff --git a/config/sm8150autoconf.h b/config/sm8150autoconf.h index fbaca24adae2..6f21874ad22a 100644 --- a/config/sm8150autoconf.h +++ b/config/sm8150autoconf.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define CONFIG_PINCTRL_WCD 1 diff --git a/dsp/adsp-loader.c b/dsp/adsp-loader.c index 5afd48cd8d63..725e3703c819 100644 --- a/dsp/adsp-loader.c +++ b/dsp/adsp-loader.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2012-2014, 2017-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/dsp/adsp_err.c b/dsp/adsp_err.c index e34d76b6aae6..1b30b2b40ae0 100644 --- a/dsp/adsp_err.c +++ b/dsp/adsp_err.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/dsp/adsp_err.h b/dsp/adsp_err.h index 43be91d6ba8f..9b3c4c449e8a 100644 --- a/dsp/adsp_err.h +++ b/dsp/adsp_err.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __ADSP_ERR__ diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index 47ac5becfc2b..36068d3b949b 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -1,14 +1,6 @@ -/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. */ #include #include diff --git a/dsp/audio_calibration.c b/dsp/audio_calibration.c index c895fa788315..93bd352ad9b1 100644 --- a/dsp/audio_calibration.c +++ b/dsp/audio_calibration.c @@ -1,14 +1,6 @@ -/* Copyright (c) 2014, 2016-2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved. */ #include #include diff --git a/dsp/audio_notifier.c b/dsp/audio_notifier.c index 485c703d25b1..cb23c4c523e0 100644 --- a/dsp/audio_notifier.c +++ b/dsp/audio_notifier.c @@ -1,13 +1,6 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. */ #include diff --git a/dsp/audio_pdr.c b/dsp/audio_pdr.c index 75f3bbb5062b..509d5c81a77c 100644 --- a/dsp/audio_pdr.c +++ b/dsp/audio_pdr.c @@ -1,13 +1,6 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. */ #include diff --git a/dsp/audio_pdr.h b/dsp/audio_pdr.h index d1235bcac39d..398d6871ce48 100644 --- a/dsp/audio_pdr.h +++ b/dsp/audio_pdr.h @@ -1,14 +1,6 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ #ifndef __AUDIO_PDR_H_ diff --git a/dsp/audio_slimslave.c b/dsp/audio_slimslave.c index 55982f33474b..69cdf59db929 100644 --- a/dsp/audio_slimslave.c +++ b/dsp/audio_slimslave.c @@ -1,13 +1,6 @@ -/* Copyright (c) 2013-2014, 2017-2018 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2013-2014, 2017-2018, The Linux Foundation. All rights reserved. */ #include diff --git a/dsp/audio_ssr.c b/dsp/audio_ssr.c index b1acb918e0fc..8c27097085e4 100644 --- a/dsp/audio_ssr.c +++ b/dsp/audio_ssr.c @@ -1,13 +1,6 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. */ #include diff --git a/dsp/audio_ssr.h b/dsp/audio_ssr.h index a807021ba7ca..d633ffd9cac2 100644 --- a/dsp/audio_ssr.h +++ b/dsp/audio_ssr.h @@ -1,14 +1,6 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. */ #ifndef __AUDIO_SSR_H_ diff --git a/dsp/avtimer.c b/dsp/avtimer.c index 41718ef6720b..ee73826cb329 100644 --- a/dsp/avtimer.c +++ b/dsp/avtimer.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2012-2015, 2017-2018 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/dsp/codecs/aac_in.c b/dsp/codecs/aac_in.c index e10fbee605f7..11e7bcca0b75 100644 --- a/dsp/codecs/aac_in.c +++ b/dsp/codecs/aac_in.c @@ -1,15 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include #include diff --git a/dsp/codecs/amrnb_in.c b/dsp/codecs/amrnb_in.c index 4e3586036702..266d9c875c35 100644 --- a/dsp/codecs/amrnb_in.c +++ b/dsp/codecs/amrnb_in.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2010-2012, 2014, 2016-2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/dsp/codecs/amrwb_in.c b/dsp/codecs/amrwb_in.c index ce9dc45c1d96..6435f25e14b0 100644 --- a/dsp/codecs/amrwb_in.c +++ b/dsp/codecs/amrwb_in.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2011-2012, 2014, 2016-2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/dsp/codecs/audio_aac.c b/dsp/codecs/audio_aac.c index 44444efef477..bbf9c36219f3 100644 --- a/dsp/codecs/audio_aac.c +++ b/dsp/codecs/audio_aac.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* aac audio output device * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation * Copyright (c) 2010-2018, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/audio_alac.c b/dsp/codecs/audio_alac.c index 975a1e903937..9ece77f54f66 100644 --- a/dsp/codecs/audio_alac.c +++ b/dsp/codecs/audio_alac.c @@ -1,14 +1,6 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #include diff --git a/dsp/codecs/audio_amrnb.c b/dsp/codecs/audio_amrnb.c index 1b5dd949f7f2..1549f43a35f6 100644 --- a/dsp/codecs/audio_amrnb.c +++ b/dsp/codecs/audio_amrnb.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* amrnb audio output device * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/audio_amrwb.c b/dsp/codecs/audio_amrwb.c index 14087821481f..63baa9db2a92 100644 --- a/dsp/codecs/audio_amrwb.c +++ b/dsp/codecs/audio_amrwb.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* amrwb audio output device * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/audio_amrwbplus.c b/dsp/codecs/audio_amrwbplus.c index 9d6c118712ec..95ada7066c29 100644 --- a/dsp/codecs/audio_amrwbplus.c +++ b/dsp/codecs/audio_amrwbplus.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* amr-wbplus audio output device * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation * Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include #include diff --git a/dsp/codecs/audio_ape.c b/dsp/codecs/audio_ape.c index f2a6bf7ccd99..8d617919b465 100644 --- a/dsp/codecs/audio_ape.c +++ b/dsp/codecs/audio_ape.c @@ -1,14 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/audio_evrc.c b/dsp/codecs/audio_evrc.c index 6cddc9cacf70..2376eb31c193 100644 --- a/dsp/codecs/audio_evrc.c +++ b/dsp/codecs/audio_evrc.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* evrc audio output device * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include "audio_utils_aio.h" diff --git a/dsp/codecs/audio_g711alaw.c b/dsp/codecs/audio_g711alaw.c index 6382616fab55..509fba23af4a 100644 --- a/dsp/codecs/audio_g711alaw.c +++ b/dsp/codecs/audio_g711alaw.c @@ -1,14 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/audio_g711mlaw.c b/dsp/codecs/audio_g711mlaw.c index 9994aabc9591..d01e3363a515 100644 --- a/dsp/codecs/audio_g711mlaw.c +++ b/dsp/codecs/audio_g711mlaw.c @@ -1,14 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/audio_hwacc_effects.c b/dsp/codecs/audio_hwacc_effects.c index f66164bfc62f..d90c4246c349 100644 --- a/dsp/codecs/audio_hwacc_effects.c +++ b/dsp/codecs/audio_hwacc_effects.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/dsp/codecs/audio_mp3.c b/dsp/codecs/audio_mp3.c index 4435f3e71c88..d676609954f2 100644 --- a/dsp/codecs/audio_mp3.c +++ b/dsp/codecs/audio_mp3.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* mp3 audio output device * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include "audio_utils_aio.h" diff --git a/dsp/codecs/audio_multi_aac.c b/dsp/codecs/audio_multi_aac.c index 87e4f4ec0fdb..38b2090373bd 100644 --- a/dsp/codecs/audio_multi_aac.c +++ b/dsp/codecs/audio_multi_aac.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* aac audio output device * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/audio_native.c b/dsp/codecs/audio_native.c index 8f21cc74f0d7..e5a038fa4265 100644 --- a/dsp/codecs/audio_native.c +++ b/dsp/codecs/audio_native.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* -Copyright (c) 2017, The Linux Foundation. All rights reserved. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 and -only version 2 as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -* -*/ + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ #include #include diff --git a/dsp/codecs/audio_qcelp.c b/dsp/codecs/audio_qcelp.c index 4b23bace509d..cd1c9e3a3722 100644 --- a/dsp/codecs/audio_qcelp.c +++ b/dsp/codecs/audio_qcelp.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* qcelp(v13k) audio output device * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include "audio_utils_aio.h" diff --git a/dsp/codecs/audio_utils.c b/dsp/codecs/audio_utils.c index e55967841fa6..7b3af387369b 100644 --- a/dsp/codecs/audio_utils.c +++ b/dsp/codecs/audio_utils.c @@ -1,14 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2010-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/audio_utils.h b/dsp/codecs/audio_utils.h index 3ad6903b3365..600aee7b0f0a 100644 --- a/dsp/codecs/audio_utils.h +++ b/dsp/codecs/audio_utils.h @@ -1,14 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2010-2015, 2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include #include diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c index 445bd3f72784..bd3ec8864933 100644 --- a/dsp/codecs/audio_utils_aio.c +++ b/dsp/codecs/audio_utils_aio.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/audio_utils_aio.h b/dsp/codecs/audio_utils_aio.h index bd99c3680697..5d7f88884b7d 100644 --- a/dsp/codecs/audio_utils_aio.h +++ b/dsp/codecs/audio_utils_aio.h @@ -1,16 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/audio_wma.c b/dsp/codecs/audio_wma.c index 0e8341e1088c..1c6bfcb5501f 100644 --- a/dsp/codecs/audio_wma.c +++ b/dsp/codecs/audio_wma.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* wma audio output device * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/audio_wmapro.c b/dsp/codecs/audio_wmapro.c index 6b1e46f45b60..6295c7fa33e6 100644 --- a/dsp/codecs/audio_wmapro.c +++ b/dsp/codecs/audio_wmapro.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* wmapro audio output device * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/evrc_in.c b/dsp/codecs/evrc_in.c index 15f08e7450b8..1cf4eae021bd 100644 --- a/dsp/codecs/evrc_in.c +++ b/dsp/codecs/evrc_in.c @@ -1,14 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/g711alaw_in.c b/dsp/codecs/g711alaw_in.c index c668b48b812d..18bf8175ad1e 100644 --- a/dsp/codecs/g711alaw_in.c +++ b/dsp/codecs/g711alaw_in.c @@ -1,14 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/g711mlaw_in.c b/dsp/codecs/g711mlaw_in.c index 2f20c1335f6e..cbe18988e476 100644 --- a/dsp/codecs/g711mlaw_in.c +++ b/dsp/codecs/g711mlaw_in.c @@ -1,14 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/q6audio_common.h b/dsp/codecs/q6audio_common.h index 75f20e5ac2bd..bcbcb4947945 100644 --- a/dsp/codecs/q6audio_common.h +++ b/dsp/codecs/q6audio_common.h @@ -1,14 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ diff --git a/dsp/codecs/q6audio_v2.c b/dsp/codecs/q6audio_v2.c index ea3113217281..bc5cacf3e3f0 100644 --- a/dsp/codecs/q6audio_v2.c +++ b/dsp/codecs/q6audio_v2.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2012-2013, 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/dsp/codecs/q6audio_v2_aio.c b/dsp/codecs/q6audio_v2_aio.c index 973108de9d78..25d1d03abe31 100644 --- a/dsp/codecs/q6audio_v2_aio.c +++ b/dsp/codecs/q6audio_v2_aio.c @@ -1,14 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/qcelp_in.c b/dsp/codecs/qcelp_in.c index be09ea4a0508..72465a86fe8b 100644 --- a/dsp/codecs/qcelp_in.c +++ b/dsp/codecs/qcelp_in.c @@ -1,14 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/msm-audio-event-notify.c b/dsp/msm-audio-event-notify.c index 3f02ebb6a7b2..da3188c3656e 100644 --- a/dsp/msm-audio-event-notify.c +++ b/dsp/msm-audio-event-notify.c @@ -1,13 +1,6 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ #include #include diff --git a/dsp/msm-dts-srs-tm-config.c b/dsp/msm-dts-srs-tm-config.c index fff98b57287c..d021e58f85b0 100644 --- a/dsp/msm-dts-srs-tm-config.c +++ b/dsp/msm-dts-srs-tm-config.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2012-2014, 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index 8bfcdc4493c8..af2b3c46322d 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/dsp/msm_mdf.c b/dsp/msm_mdf.c index fcc8a5ceedd3..674dd748aafe 100644 --- a/dsp/msm_mdf.c +++ b/dsp/msm_mdf.c @@ -1,15 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include #include diff --git a/dsp/q6_init.c b/dsp/q6_init.c index 5c194fb06a4d..bd8a2f86da4a 100644 --- a/dsp/q6_init.c +++ b/dsp/q6_init.c @@ -1,15 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* -Copyright (c) 2017, The Linux Foundation. All rights reserved. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 and -only version 2 as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. */ #include diff --git a/dsp/q6_init.h b/dsp/q6_init.h index 541fbe762ee3..71af2dacdff5 100644 --- a/dsp/q6_init.h +++ b/dsp/q6_init.h @@ -1,15 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* -Copyright (c) 2017, The Linux Foundation. All rights reserved. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 and -only version 2 as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. */ #ifndef __Q6_INIT_H__ diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 423b52e276a9..4534c4cbae1e 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -1,13 +1,6 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ #include #include diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 2810bebd9829..8ae2739e234a 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1,13 +1,6 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ #include #include diff --git a/dsp/q6afecal-hwdep.c b/dsp/q6afecal-hwdep.c index 5fea2d27a40f..c399fa6d93d8 100644 --- a/dsp/q6afecal-hwdep.c +++ b/dsp/q6afecal-hwdep.c @@ -1,15 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2015, 2017 - 2018 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * + * Copyright (c) 2015, 2017, The Linux Foundation. All rights reserved. */ #include #include diff --git a/dsp/q6afecal-hwdep.h b/dsp/q6afecal-hwdep.h index 7e6efdac57f4..d48b80f82aa9 100644 --- a/dsp/q6afecal-hwdep.h +++ b/dsp/q6afecal-hwdep.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2014,2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Copyright (c) 2014, 2018, The Linux Foundation. All rights reserved. */ #ifndef __Q6AFECAL_HWDEP_H__ #define __Q6AFECAL_HWDEP_H__ diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 7a8b941f1024..473284608f5b 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1,16 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include #include diff --git a/dsp/q6audio-v2.c b/dsp/q6audio-v2.c index 5a7fa6f62e09..29a99feb5ee9 100644 --- a/dsp/q6audio-v2.c +++ b/dsp/q6audio-v2.c @@ -1,13 +1,6 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ #include diff --git a/dsp/q6common.c b/dsp/q6common.c index 7a186dc566c7..0c5427de2d90 100644 --- a/dsp/q6common.c +++ b/dsp/q6common.c @@ -1,13 +1,6 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ #include diff --git a/dsp/q6core.c b/dsp/q6core.c index d4ea98466308..2fdc7943139d 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -1,13 +1,6 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ #include diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 46e20132f180..3a7cee4f149d 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2013-2018, Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include #include diff --git a/dsp/q6usm.c b/dsp/q6usm.c index 3c335a841995..70ebc9fe5b2d 100644 --- a/dsp/q6usm.c +++ b/dsp/q6usm.c @@ -1,14 +1,6 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ #include #include diff --git a/dsp/q6usm.h b/dsp/q6usm.h index ba4f9a9a84a7..975b89606043 100644 --- a/dsp/q6usm.h +++ b/dsp/q6usm.h @@ -1,14 +1,6 @@ -/* Copyright (c) 2011-2014, 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2011-2014, 2018, The Linux Foundation. All rights reserved. */ #ifndef __Q6_USM_H__ #define __Q6_USM_H__ diff --git a/dsp/q6voice.c b/dsp/q6voice.c index ce86564b151f..95a153d4fa25 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -1,13 +1,6 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ #include #include diff --git a/dsp/rtac.c b/dsp/rtac.c index c6bca9874270..94cb715ff503 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -1,14 +1,6 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ #include diff --git a/dsp/usf.c b/dsp/usf.c index 263ba1f8b04e..c6850e5a52de 100644 --- a/dsp/usf.c +++ b/dsp/usf.c @@ -1,14 +1,6 @@ -/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. */ #include diff --git a/dsp/usf.h b/dsp/usf.h index 544b624c2cda..5aeec06e2dac 100644 --- a/dsp/usf.h +++ b/dsp/usf.h @@ -1,14 +1,6 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. */ #ifndef __USF_H__ diff --git a/dsp/usfcdev.c b/dsp/usfcdev.c index 289616669f48..cab76612916c 100644 --- a/dsp/usfcdev.c +++ b/dsp/usfcdev.c @@ -1,14 +1,6 @@ -/* Copyright (c) 2012-2013, 2016-2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2012-2013, 2016-2017 The Linux Foundation. All rights reserved. */ #include diff --git a/dsp/usfcdev.h b/dsp/usfcdev.h index 03b62c5ec83c..dcde63b05d08 100644 --- a/dsp/usfcdev.h +++ b/dsp/usfcdev.h @@ -1,14 +1,6 @@ -/* Copyright (c) 2012, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. */ #ifndef __USFCDEV_H__ #define __USFCDEV_H__ diff --git a/include/asoc/wcd-irq.h b/include/asoc/wcd-irq.h index 63502f828ed8..b0da38d3b0b8 100644 --- a/include/asoc/wcd-irq.h +++ b/include/asoc/wcd-irq.h @@ -1,13 +1,6 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ #ifndef __WCD_IRQ_H_ diff --git a/include/asoc/wcd934x_registers.h b/include/asoc/wcd934x_registers.h index a824875096e4..785b906d963c 100644 --- a/include/asoc/wcd934x_registers.h +++ b/include/asoc/wcd934x_registers.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2016, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _WCD934X_REGISTERS_H diff --git a/include/asoc/wcd9xxx_registers.h b/include/asoc/wcd9xxx_registers.h index 928dfcc56d56..5d270cd03e85 100644 --- a/include/asoc/wcd9xxx_registers.h +++ b/include/asoc/wcd9xxx_registers.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _WCD9XXX_REGISTERS_H diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 9ac728185953..d8e6d34ba86d 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1,13 +1,6 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/audio_cal_utils.h b/include/dsp/audio_cal_utils.h index 614ef236644d..c3772b01806a 100644 --- a/include/dsp/audio_cal_utils.h +++ b/include/dsp/audio_cal_utils.h @@ -1,14 +1,6 @@ -/* Copyright (c) 2014, 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2014, 2018, The Linux Foundation. All rights reserved. */ #ifndef _AUDIO_CAL_UTILS_H #define _AUDIO_CAL_UTILS_H diff --git a/include/dsp/audio_calibration.h b/include/dsp/audio_calibration.h index 5decff913493..d414d8f5e201 100644 --- a/include/dsp/audio_calibration.h +++ b/include/dsp/audio_calibration.h @@ -1,14 +1,6 @@ -/* Copyright (c) 2014, 2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. */ #ifndef _AUDIO_CALIBRATION_H #define _AUDIO_CALIBRATION_H diff --git a/include/dsp/audio_notifier.h b/include/dsp/audio_notifier.h index 7eda2c35c2d0..2b738260d7b1 100644 --- a/include/dsp/audio_notifier.h +++ b/include/dsp/audio_notifier.h @@ -1,14 +1,6 @@ -/* Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved. */ #ifndef __AUDIO_NOTIFIER_H_ diff --git a/include/dsp/msm-audio-effects-q6-v2.h b/include/dsp/msm-audio-effects-q6-v2.h index 6bc2338bcf55..da7ec8b1bb4f 100644 --- a/include/dsp/msm-audio-effects-q6-v2.h +++ b/include/dsp/msm-audio-effects-q6-v2.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _MSM_AUDIO_EFFECTS_H diff --git a/include/dsp/msm-audio-event-notify.h b/include/dsp/msm-audio-event-notify.h index fc47eff8abbf..49c00b75627c 100644 --- a/include/dsp/msm-audio-event-notify.h +++ b/include/dsp/msm-audio-event-notify.h @@ -1,14 +1,6 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ #ifndef __MSM_AUDIO_EVENT_NOTIFY_H_ diff --git a/include/dsp/msm-dts-srs-tm-config.h b/include/dsp/msm-dts-srs-tm-config.h index c00461b84bf0..7eeb4222bb91 100644 --- a/include/dsp/msm-dts-srs-tm-config.h +++ b/include/dsp/msm-dts-srs-tm-config.h @@ -1,13 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Copyright (c) 2012-2014, 2017, The Linux Foundation. All rights reserved. */ #ifndef _MSM_DTS_SRS_TM_CONFIG_H_ diff --git a/include/dsp/msm_audio_ion.h b/include/dsp/msm_audio_ion.h index 9235adc1e0e4..5120383ae2d7 100644 --- a/include/dsp/msm_audio_ion.h +++ b/include/dsp/msm_audio_ion.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2013-2015, 2017-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _LINUX_MSM_AUDIO_ION_H diff --git a/include/dsp/msm_mdf.h b/include/dsp/msm_mdf.h index 5b27f1211ae0..efd6fc557cc1 100644 --- a/include/dsp/msm_mdf.h +++ b/include/dsp/msm_mdf.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _LINUX_MSM_MDF_H diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index bf3d0f048205..404f84c2b1f0 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -1,13 +1,6 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ #ifndef __Q6_ADM_V2_H__ #define __Q6_ADM_V2_H__ diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index eb5fc834d96a..423a16906077 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -1,13 +1,6 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ #ifndef __Q6AFE_V2_H__ #define __Q6AFE_V2_H__ diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index 2d738d6356ba..df2c0d70e6e2 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -1,13 +1,6 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ #ifndef __Q6_ASM_V2_H__ #define __Q6_ASM_V2_H__ diff --git a/include/dsp/q6audio-v2.h b/include/dsp/q6audio-v2.h index 5df88fcbb6f0..4c9daebb5fe4 100644 --- a/include/dsp/q6audio-v2.h +++ b/include/dsp/q6audio-v2.h @@ -1,13 +1,6 @@ -/* Copyright (c) 2012-2013, 2015 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2012-2013, 2015, The Linux Foundation. All rights reserved. */ #ifndef _Q6_AUDIO_H_ diff --git a/include/dsp/q6common.h b/include/dsp/q6common.h index 552f97632d4d..0d270bdb4c31 100644 --- a/include/dsp/q6common.h +++ b/include/dsp/q6common.h @@ -1,13 +1,6 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ #ifndef __Q6COMMON_H__ diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index e1f8b97dbb90..5e008e18dc34 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -1,13 +1,6 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ #ifndef __Q6CORE_H__ diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h index 5670d776c58d..c6a0d60d433f 100644 --- a/include/dsp/q6lsm.h +++ b/include/dsp/q6lsm.h @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __Q6LSM_H__ #define __Q6LSM_H__ diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index ca4250872591..a674384b7b45 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -1,13 +1,6 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ #ifndef __QDSP6VOICE_H__ #define __QDSP6VOICE_H__ diff --git a/include/dsp/rtac.h b/include/dsp/rtac.h index 05dd82a7fcab..7a1fed5fe555 100644 --- a/include/dsp/rtac.h +++ b/include/dsp/rtac.h @@ -1,15 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2011, 2013-2015, 2017-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #ifndef __RTAC_H__ diff --git a/include/ipc/apr.h b/include/ipc/apr.h index 6b4817edeeb5..4e29b02827a9 100644 --- a/include/ipc/apr.h +++ b/include/ipc/apr.h @@ -1,14 +1,6 @@ -/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. */ #ifndef __APR_H_ #define __APR_H_ diff --git a/include/ipc/apr_tal.h b/include/ipc/apr_tal.h index 534fd84d2ba8..9e412e57f40d 100644 --- a/include/ipc/apr_tal.h +++ b/include/ipc/apr_tal.h @@ -1,14 +1,6 @@ -/* Copyright (c) 2010-2011, 2016-2018 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2010-2011, 2016-2018 The Linux Foundation. All rights reserved. */ #ifndef __APR_TAL_H_ #define __APR_TAL_H_ diff --git a/include/ipc/apr_us.h b/include/ipc/apr_us.h index 6e2f63de9756..ea9a275f4992 100644 --- a/include/ipc/apr_us.h +++ b/include/ipc/apr_us.h @@ -1,14 +1,6 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. */ #ifndef __APR_US_H__ #define __APR_US_H__ diff --git a/include/soc/soundwire.h b/include/soc/soundwire.h index 3bc3332af4c1..daacb7a408f2 100644 --- a/include/soc/soundwire.h +++ b/include/soc/soundwire.h @@ -1,13 +1,6 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #ifndef _LINUX_SOUNDWIRE_H diff --git a/include/soc/swr-wcd.h b/include/soc/swr-wcd.h index 7eaad27562d2..93c5ffd78959 100644 --- a/include/soc/swr-wcd.h +++ b/include/soc/swr-wcd.h @@ -1,13 +1,6 @@ -/* Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved. */ #ifndef _LINUX_SWR_WCD_H diff --git a/include/uapi/linux/msm_audio.h b/include/uapi/linux/msm_audio.h index 3213d00842c0..171d5b394c7b 100644 --- a/include/uapi/linux/msm_audio.h +++ b/include/uapi/linux/msm_audio.h @@ -1,17 +1,8 @@ -/* include/linux/msm_audio.h +/* SPDX-License-Identifier: GPL-2.0 */ +/* * * Copyright (C) 2008 Google, Inc. * Copyright (c) 2012, 2014, 2017 The Linux Foundation. All rights reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #ifndef _UAPI_LINUX_MSM_AUDIO_H diff --git a/ipc/apr.c b/ipc/apr.c index 990a1032719c..573d52d35fcd 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -1,13 +1,6 @@ -/* Copyright (c) 2010-2014, 2016-2018 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2010-2014, 2016-2018 The Linux Foundation. All rights reserved. */ #include diff --git a/ipc/apr_tal_rpmsg.c b/ipc/apr_tal_rpmsg.c index aaadca486844..a4175b4cb695 100644 --- a/ipc/apr_tal_rpmsg.c +++ b/ipc/apr_tal_rpmsg.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/ipc/apr_v2.c b/ipc/apr_v2.c index e85173cd2158..f74218efd16e 100644 --- a/ipc/apr_v2.c +++ b/ipc/apr_v2.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. */ #include diff --git a/ipc/apr_v3.c b/ipc/apr_v3.c index fa68daf55e84..a2df4d818ac9 100644 --- a/ipc/apr_v3.c +++ b/ipc/apr_v3.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/ipc/wcd-dsp-glink.c b/ipc/wcd-dsp-glink.c index 79ff26aef65a..455a34847460 100644 --- a/ipc/wcd-dsp-glink.c +++ b/ipc/wcd-dsp-glink.c @@ -1,13 +1,6 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ #include diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index 279ec0000084..91a0bce31c2b 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/soc/pinctrl-wcd.c b/soc/pinctrl-wcd.c index d7695dbe77b8..8dc97bdd4bf3 100644 --- a/soc/pinctrl-wcd.c +++ b/soc/pinctrl-wcd.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/soc/regmap-swr.c b/soc/regmap-swr.c index ba092a2aaa70..7f00aab66dda 100644 --- a/soc/regmap-swr.c +++ b/soc/regmap-swr.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/soc/soundwire.c b/soc/soundwire.c index 573d39dcd7b9..bd91caf7baae 100644 --- a/soc/soundwire.c +++ b/soc/soundwire.c @@ -1,13 +1,6 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #include diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index efb20f7b0bb6..7fa07373c067 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1,13 +1,6 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #include diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index b3e358a0d944..085a06567b15 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -1,13 +1,6 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #ifndef _SWR_WCD_CTRL_H diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c index ecca5f699fde..ed410fd7670e 100644 --- a/soc/swr-wcd-ctrl.c +++ b/soc/swr-wcd-ctrl.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/soc/swr-wcd-ctrl.h b/soc/swr-wcd-ctrl.h index 14b2b48dbb84..23b44348769c 100644 --- a/soc/swr-wcd-ctrl.h +++ b/soc/swr-wcd-ctrl.h @@ -1,13 +1,6 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #ifndef _SWR_WCD_CTRL_H diff --git a/soc/swrm_port_config.h b/soc/swrm_port_config.h index 6dbd1de41586..8c2903274d2a 100644 --- a/soc/swrm_port_config.h +++ b/soc/swrm_port_config.h @@ -1,13 +1,6 @@ -/* Copyright (c) 2018 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018 The Linux Foundation. All rights reserved. */ #ifndef _SWRM_PORT_CONFIG diff --git a/soc/swrm_registers.h b/soc/swrm_registers.h index ecff48d69941..c8ec2a32313d 100644 --- a/soc/swrm_registers.h +++ b/soc/swrm_registers.h @@ -1,13 +1,6 @@ -/* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved. */ #ifndef _SWRM_REGISTERS_H -- GitLab From c7b180ec7cff28bf5c4853e46726bff89da864d1 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 13 Nov 2018 09:28:48 +0800 Subject: [PATCH 0677/1645] asoc: Avoid usage of variable length array chmap in msm_lsm_check_and_set_lab_controls, data in wcd9xxx_i2c_write_device and irq_level in wcd9xxx_irq_init are Variable Length Array (VLA). VLAs are considered unfit when it comes to security, performance, code quality and so on. Hence, allocate the memory dynamically. Change-Id: I52f33e61f857a00774eb26dc1d6372f2ed3d425c Signed-off-by: Meng Wang --- asoc/codecs/wcd9xxx-core.c | 13 ++++++++++--- asoc/codecs/wcd9xxx-irq.c | 17 +++++++++++------ asoc/msm-lsm-client.c | 13 +++++++++---- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index ba4dc333ab40..28b0708604e1 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -844,7 +844,7 @@ static int wcd9xxx_i2c_write_device(struct wcd9xxx *wcd9xxx, u16 reg, u8 *value, struct i2c_msg *msg; int ret = 0; u8 reg_addr = 0; - u8 data[bytes + 1]; + u8 *data = NULL; struct wcd9xxx_i2c *wcd9xxx_i2c; wcd9xxx_i2c = wcd9xxx_i2c_get_device_info(wcd9xxx, reg); @@ -852,6 +852,11 @@ static int wcd9xxx_i2c_write_device(struct wcd9xxx *wcd9xxx, u16 reg, u8 *value, pr_err("failed to get device info\n"); return -ENODEV; } + + data = kzalloc(bytes + 1, GFP_KERNEL); + if (!data) + return -ENOMEM; + reg_addr = (u8)reg; msg = &wcd9xxx_i2c->xfer_msg[0]; msg->addr = wcd9xxx_i2c->client->addr; @@ -868,11 +873,13 @@ static int wcd9xxx_i2c_write_device(struct wcd9xxx *wcd9xxx, u16 reg, u8 *value, wcd9xxx_i2c->xfer_msg, 1); if (ret != 1) { pr_err("failed to write the device\n"); - return ret; + goto fail; } } pr_debug("write success register = %x val = %x\n", reg, data[1]); - return 0; +fail: + kfree(data); + return ret; } diff --git a/asoc/codecs/wcd9xxx-irq.c b/asoc/codecs/wcd9xxx-irq.c index 92841932ca12..5b685fbdcc9f 100644 --- a/asoc/codecs/wcd9xxx-irq.c +++ b/asoc/codecs/wcd9xxx-irq.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. */ #include #include @@ -525,7 +525,7 @@ static int wcd9xxx_irq_setup_downstream_irq( int wcd9xxx_irq_init(struct wcd9xxx_core_resource *wcd9xxx_res) { int i, ret; - u8 irq_level[wcd9xxx_res->num_irq_regs]; + u8 *irq_level = NULL; struct irq_domain *domain; struct device_node *pnode; @@ -555,9 +555,7 @@ int wcd9xxx_irq_init(struct wcd9xxx_core_resource *wcd9xxx_res) ret = wcd9xxx_irq_setup_downstream_irq(wcd9xxx_res); if (ret) { pr_err("%s: Failed to setup downstream IRQ\n", __func__); - wcd9xxx_irq_put_upstream_irq(wcd9xxx_res); - mutex_destroy(&wcd9xxx_res->irq_lock); - mutex_destroy(&wcd9xxx_res->nested_irq_lock); + goto fail_irq_level; return ret; } @@ -565,7 +563,11 @@ int wcd9xxx_irq_init(struct wcd9xxx_core_resource *wcd9xxx_res) wcd9xxx_res->irq_level_high[0] = true; /* mask all the interrupts */ - memset(irq_level, 0, wcd9xxx_res->num_irq_regs); + irq_level = kzalloc(wcd9xxx_res->num_irq_regs, GFP_KERNEL); + if (!irq_level) { + ret = -ENOMEM; + goto fail_irq_level; + } for (i = 0; i < wcd9xxx_res->num_irqs; i++) { wcd9xxx_res->irq_masks_cur[BIT_BYTE(i)] |= BYTE_BIT_MASK(i); wcd9xxx_res->irq_masks_cache[BIT_BYTE(i)] |= BYTE_BIT_MASK(i); @@ -610,11 +612,14 @@ int wcd9xxx_irq_init(struct wcd9xxx_core_resource *wcd9xxx_res) if (ret) goto fail_irq_init; + kfree(irq_level); return ret; fail_irq_init: dev_err(wcd9xxx_res->dev, "%s: Failed to init wcd9xxx irq\n", __func__); + kfree(irq_level); +fail_irq_level: wcd9xxx_irq_put_upstream_irq(wcd9xxx_res); mutex_destroy(&wcd9xxx_res->irq_lock); mutex_destroy(&wcd9xxx_res->nested_irq_lock); diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 67f262386f16..98132b4b8979 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -729,7 +729,7 @@ static int msm_lsm_check_and_set_lab_controls(struct snd_pcm_substream *substrea struct lsm_priv *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct lsm_hw_params *out_hw_params = &prtd->lsm_client->out_hw_params; - u8 chmap[out_hw_params->num_chs]; + u8 *chmap = NULL; u32 ch_idx; int rc = 0, stage_idx = p_info->stage_idx; @@ -740,11 +740,15 @@ static int msm_lsm_check_and_set_lab_controls(struct snd_pcm_substream *substrea return rc; } + chmap = kzalloc(out_hw_params->num_chs, GFP_KERNEL); + if (!chmap) + return -ENOMEM; + rc = q6lsm_lab_control(prtd->lsm_client, enable, p_info); if (rc) { dev_err(rtd->dev, "%s: Failed to set lab_control param, err = %d\n", __func__, rc); - return rc; + goto fail; } else { if (LSM_IS_LAST_STAGE(prtd->lsm_client, stage_idx)) { rc = msm_lsm_lab_buffer_alloc(prtd, @@ -753,7 +757,7 @@ static int msm_lsm_check_and_set_lab_controls(struct snd_pcm_substream *substrea dev_err(rtd->dev, "%s: msm_lsm_lab_buffer_alloc failed rc %d for %s\n", __func__, rc, enable ? "ALLOC" : "DEALLOC"); - return rc; + goto fail; } else { /* set client level flag based on last stage control */ prtd->lsm_client->lab_enable = enable; @@ -763,7 +767,6 @@ static int msm_lsm_check_and_set_lab_controls(struct snd_pcm_substream *substrea prtd->lsm_client->stage_cfg[stage_idx].lab_enable = enable; } - memset(chmap, 0, out_hw_params->num_chs); /* * First channel to be read from lab is always the * best channel (0xff). For second channel onwards, @@ -778,6 +781,8 @@ static int msm_lsm_check_and_set_lab_controls(struct snd_pcm_substream *substrea dev_err(rtd->dev, "%s: Failed to set lab out ch cfg %d\n", __func__, rc); +fail: + kfree(chmap); return rc; } -- GitLab From e9abcd0fbde5d4fce598e9b74fed6ee70b877c09 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Mon, 1 Oct 2018 15:55:25 -0700 Subject: [PATCH 0678/1645] ASoC: msm: add machine driver for kona Add machine driver for Kona with stub codec. Change-Id: Ic214324e22e2eaeaa2651e4fbeb8fd187aeb458e Signed-off-by: Vignesh Kulothungan --- asoc/Kbuild | 8 + asoc/kona.c | 696 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 704 insertions(+) create mode 100644 asoc/kona.c diff --git a/asoc/Kbuild b/asoc/Kbuild index 17d4d211d97a..59a6e53fcae3 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -84,6 +84,11 @@ ifdef CONFIG_SND_SOC_QCS405 MACHINE_OBJS += qcs405.o endif +# for KONA sound card driver +ifdef CONFIG_SND_SOC_KONA + MACHINE_OBJS += kona.o +endif + ifdef CONFIG_SND_SOC_CPE CPE_LSM_OBJS += msm-cpe-lsm.o endif @@ -177,6 +182,9 @@ machine_dlkm-y := $(MACHINE_OBJS) obj-$(CONFIG_SND_SOC_QCS405) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) +obj-$(CONFIG_SND_SOC_KONA) += machine_dlkm.o +machine_dlkm-y := $(MACHINE_OBJS) + obj-$(CONFIG_SND_SOC_CPE) += cpe_lsm_dlkm.o cpe_lsm_dlkm-y := $(CPE_LSM_OBJS) diff --git a/asoc/kona.c b/asoc/kona.c new file mode 100644 index 000000000000..0d8772519a30 --- /dev/null +++ b/asoc/kona.c @@ -0,0 +1,696 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "device_event.h" +#include "msm-pcm-routing-v2.h" +#include "codecs/wsa881x.h" + +#define DRV_NAME "kona-asoc-snd" + +#define __CHIPSET__ "KONA " +#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) + +#define SAMPLING_RATE_8KHZ 8000 +#define SAMPLING_RATE_16KHZ 16000 + +struct msm_asoc_mach_data { + u32 mclk_freq; + struct snd_info_entry *codec_root; +}; + +struct dev_config { + u32 sample_rate; + u32 bit_format; + u32 channels; +}; + +enum { + PRIM_AUX_PCM = 0, +}; + +static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; + +/* Default configuration of aux pcm channels */ +static struct dev_config aux_pcm_rx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_tx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, + int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, + unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx = 0; + + if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", + sizeof("PRIM_AUX_PCM"))) { + idx = PRIM_AUX_PCM; + } else { + pr_err("%s: unsupported port: %s\n", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int aux_pcm_get_format(int value) +{ + int format = 0; + + switch (value) { + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 0: + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int auxpcm_get_format_value(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + value = 2; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 3; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + value = 0; + break; + } + return value; +} + +static int aux_pcm_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 0: + default: + sample_rate = SAMPLING_RATE_8KHZ; + break; + } + return sample_rate; +} + +static int aux_pcm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + return sample_rate_val; +} + +static int msm_aux_pcm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + auxpcm_get_format_value(aux_pcm_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].bit_format = + aux_pcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + auxpcm_get_format_value(aux_pcm_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].bit_format = + aux_pcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), +}; + +static int msm_populate_dai_link_component_of_node( + struct snd_soc_card *card) +{ + int i, index, ret = 0; + struct device *cdev = card->dev; + struct snd_soc_dai_link *dai_link = card->dai_link; + struct device_node *np; + + if (!cdev) { + dev_err(cdev, "%s: Sound card device memory NULL\n", __func__); + return -ENODEV; + } + + for (i = 0; i < card->num_links; i++) { + if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) + continue; + + /* populate platform_of_node for snd card dai links */ + if (dai_link[i].platform_name && + !dai_link[i].platform_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-platform-names", + dai_link[i].platform_name); + if (index < 0) { + dev_err(cdev, "%s: No match found for platform name: %s\n", + __func__, dai_link[i].platform_name); + ret = index; + goto err; + } + np = of_parse_phandle(cdev->of_node, "asoc-platform", + index); + if (!np) { + dev_err(cdev, "%s: retrieving phandle for platform %s, index %d failed\n", + __func__, dai_link[i].platform_name, + index); + ret = -ENODEV; + goto err; + } + dai_link[i].platform_of_node = np; + dai_link[i].platform_name = NULL; + } + + /* populate cpu_of_node for snd card dai links */ + if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-cpu-names", + dai_link[i].cpu_dai_name); + if (index >= 0) { + np = of_parse_phandle(cdev->of_node, "asoc-cpu", + index); + if (!np) { + dev_err(cdev, "%s: retrieving phandle for cpu dai %s failed\n", + __func__, + dai_link[i].cpu_dai_name); + ret = -ENODEV; + goto err; + } + dai_link[i].cpu_of_node = np; + dai_link[i].cpu_dai_name = NULL; + } + } + + /* populate codec_of_node for snd card dai links */ + if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-codec-names", + dai_link[i].codec_name); + if (index < 0) + continue; + np = of_parse_phandle(cdev->of_node, "asoc-codec", + index); + if (!np) { + dev_err(cdev, "%s: retrieving phandle for codec %s failed\n", + __func__, dai_link[i].codec_name); + ret = -ENODEV; + goto err; + } + dai_link[i].codec_of_node = np; + dai_link[i].codec_name = NULL; + } + } + +err: + return ret; +} + +static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = -EINVAL; + struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, "msm-stub-codec"); + + if (!component) { + pr_err("* %s: No match for msm-stub-codec component\n", __func__); + return ret; + } + + ret = snd_soc_add_component_controls(component, msm_snd_controls, + ARRAY_SIZE(msm_snd_controls)); + if (ret < 0) { + dev_err(component->dev, + "%s: add_codec_controls failed, err = %d\n", + __func__, ret); + return ret; + } + + return ret; +} + +static int msm_snd_stub_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + return 0; +} + +static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int rc = 0; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->id) { + case MSM_BACKEND_DAI_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].channels; + break; + case MSM_BACKEND_DAI_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[PRIM_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].channels; + break; + default: + rate->min = rate->max = SAMPLING_RATE_8KHZ; + break; + } + + return rc; +} + +static struct snd_soc_ops msm_stub_be_ops = { + .hw_params = msm_snd_stub_hw_params, +}; + +struct snd_soc_card snd_soc_card_stub_msm = { + .name = "kona-stub-snd-card", +}; + +static struct snd_soc_dai_link msm_stub_fe_dai_links[] = { + /* FrontEnd DAI Links */ + { + .name = "MSMSTUB Media1", + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, +}; + +static struct snd_soc_dai_link msm_stub_be_dai_links[] = { + /* Backend DAI Links */ + { + .name = LPASS_BE_AUXPCM_RX, + .stream_name = "AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AUXPCM_RX, + .init = &msm_audrx_stub_init, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_stub_be_ops, + }, + { + .name = LPASS_BE_AUXPCM_TX, + .stream_name = "AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_stub_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_stub_dai_links[ + ARRAY_SIZE(msm_stub_fe_dai_links) + + ARRAY_SIZE(msm_stub_be_dai_links)]; + +static const struct of_device_id kona_asoc_machine_of_match[] = { + { .compatible = "qcom,kona-asoc-snd-stub", + .data = "stub_codec"}, + {}, +}; + +static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) +{ + struct snd_soc_card *card = NULL; + struct snd_soc_dai_link *dailink; + int len_1, len_2; + int total_links; + const struct of_device_id *match; + + match = of_match_node(kona_asoc_machine_of_match, dev->of_node); + if (!match) { + dev_err(dev, "%s: No DT match found for sound card\n", + __func__); + return NULL; + } + + if (!strcmp(match->data, "stub_codec")) { + card = &snd_soc_card_stub_msm; + len_1 = ARRAY_SIZE(msm_stub_fe_dai_links); + len_2 = len_1 + ARRAY_SIZE(msm_stub_be_dai_links); + + memcpy(msm_stub_dai_links, + msm_stub_fe_dai_links, + sizeof(msm_stub_fe_dai_links)); + memcpy(msm_stub_dai_links + len_1, + msm_stub_be_dai_links, + sizeof(msm_stub_be_dai_links)); + + dailink = msm_stub_dai_links; + total_links = len_2; + } + + if (card) { + card->dai_link = dailink; + card->num_links = total_links; + } + + return card; +} + +static int msm_asoc_machine_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card; + struct msm_asoc_mach_data *pdata; + const struct of_device_id *match; + int ret; + + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, "%s: No platform supplied from device tree\n", __func__); + return -EINVAL; + } + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct msm_asoc_mach_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + card = populate_snd_card_dailinks(&pdev->dev); + if (!card) { + dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); + ret = -EINVAL; + goto err; + } + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, pdata); + + ret = snd_soc_of_parse_card_name(card, "qcom,model"); + if (ret) { + dev_err(&pdev->dev, "%s: parse card name failed, err:%d\n", + __func__, ret); + goto err; + } + + match = of_match_node(kona_asoc_machine_of_match, + pdev->dev.of_node); + if (!match) { + dev_err(&pdev->dev, "%s: no matched codec is found.\n", + __func__); + goto err; + } + + ret = msm_populate_dai_link_component_of_node(card); + if (ret) { + ret = -EPROBE_DEFER; + goto err; + } + + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret) { + dev_err(&pdev->dev, "%s: snd_soc_register_card failed (%d)\n", + __func__, ret); + goto err; + } + dev_info(&pdev->dev, "%s: Sound card %s registered\n", + __func__, card->name); + + return 0; +err: + devm_kfree(&pdev->dev, pdata); + return ret; +} + +static int msm_asoc_machine_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + return 0; +} + +static struct platform_driver kona_asoc_machine_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = kona_asoc_machine_of_match, + }, + .probe = msm_asoc_machine_probe, + .remove = msm_asoc_machine_remove, +}; +module_platform_driver(kona_asoc_machine_driver); + +MODULE_DESCRIPTION("ALSA SoC msm"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, kona_asoc_machine_of_match); -- GitLab From ee084a068eb2b4bd8fc5fbfed720f46d036113bd Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 4 Sep 2018 16:11:58 +0800 Subject: [PATCH 0679/1645] ASoC: Change platform driver to component driver snd_soc_platform_driver is removed in kernel-4.19. Update snd_soc_platform_driver to snd_soc_component_driver. Change-Id: I434b6fd173d1f4365a610d9164342d5d04d6c5bc Signed-off-by: Meng Wang --- asoc/msm-compress-q6-v2.c | 230 +++++++++++++++++++++------- asoc/msm-cpe-lsm.c | 48 +++--- asoc/msm-dolby-dap-config.h | 2 +- asoc/msm-lsm-client.c | 12 +- asoc/msm-pcm-afe-v2.c | 13 +- asoc/msm-pcm-dtmf-v2.c | 15 +- asoc/msm-pcm-host-voice-v2.c | 14 +- asoc/msm-pcm-hostless.c | 13 +- asoc/msm-pcm-loopback-v2.c | 83 +++++++--- asoc/msm-pcm-q6-noirq.c | 42 ++++- asoc/msm-pcm-q6-v2.c | 102 +++++++++--- asoc/msm-pcm-routing-v2.c | 65 ++++---- asoc/msm-pcm-voice-v2.c | 16 +- asoc/msm-pcm-voip-v2.c | 16 +- asoc/msm-qti-pp-config.c | 43 +++--- asoc/msm-qti-pp-config.h | 4 +- asoc/msm-transcode-loopback-q6-v2.c | 114 +++++++++++--- dsp/msm-dts-srs-tm-config.c | 12 +- include/dsp/msm-dts-srs-tm-config.h | 6 +- 19 files changed, 600 insertions(+), 250 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index e12005135c0c..bf22f87c8cf2 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -38,6 +38,8 @@ #include "msm-pcm-routing-v2.h" #include "msm-qti-pp-config.h" +#define DRV_NAME "msm-compress-q6-v2" + #define DSP_PP_BUFFERING_IN_MSEC 25 #define PARTIAL_DRAIN_ACK_EARLY_BY_MSEC 150 #define MP3_OUTPUT_FRAME_SZ 1152 @@ -346,6 +348,7 @@ static int msm_compr_set_volume(struct snd_compr_stream *cstream, uint32_t avg_vol, gain_list[VOLUME_CONTROL_MAX_CHANNELS]; uint32_t num_channels; struct snd_soc_pcm_runtime *rtd; + struct snd_soc_component *component = NULL; struct msm_compr_pdata *pdata; bool use_default = true; u8 *chmap = NULL; @@ -358,12 +361,13 @@ static int msm_compr_set_volume(struct snd_compr_stream *cstream, } rtd = cstream->private_data; prtd = cstream->runtime->private_data; + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); - if (!rtd || !rtd->platform || !prtd || !prtd->audio_client) { + if (!rtd || !component || !prtd || !prtd->audio_client) { pr_err("%s: invalid rtd, prtd or audio client", __func__); return rc; } - pdata = snd_soc_platform_get_drvdata(rtd->platform); + pdata = snd_soc_component_get_drvdata(component); if (prtd->compr_passthr != LEGACY_PCM) { pr_debug("%s: No volume config for passthrough %d\n", @@ -952,8 +956,8 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, struct snd_compr_runtime *runtime = cstream->runtime; struct msm_compr_audio *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd = cstream->private_data; - struct msm_compr_pdata *pdata = - snd_soc_platform_get_drvdata(rtd->platform); + struct snd_soc_component *component =NULL; + struct msm_compr_pdata *pdata = NULL; struct asm_aac_cfg aac_cfg; struct asm_wma_cfg wma_cfg; struct asm_wmapro_cfg wma_pro_cfg; @@ -974,6 +978,13 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, pr_debug("%s: use_gapless_codec_options %d\n", __func__, use_gapless_codec_options); + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + pdata = snd_soc_component_get_drvdata(component); + if (use_gapless_codec_options) codec_options = &(prtd->gapless_state.codec_options); else @@ -1598,11 +1609,17 @@ static int msm_compr_playback_open(struct snd_compr_stream *cstream) { struct snd_compr_runtime *runtime = cstream->runtime; struct snd_soc_pcm_runtime *rtd = cstream->private_data; + struct snd_soc_component *component = NULL; struct msm_compr_audio *prtd = NULL; - struct msm_compr_pdata *pdata = - snd_soc_platform_get_drvdata(rtd->platform); + struct msm_compr_pdata *pdata = NULL; pr_debug("%s\n", __func__); + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + pdata = snd_soc_component_get_drvdata(component); if (pdata->is_in_use[rtd->dai_link->id] == true) { pr_err("%s: %s is already in use, err: %d\n", __func__, rtd->dai_link->cpu_dai_name, -EBUSY); @@ -1699,13 +1716,23 @@ static int msm_compr_capture_open(struct snd_compr_stream *cstream) { struct snd_compr_runtime *runtime = cstream->runtime; struct snd_soc_pcm_runtime *rtd = cstream->private_data; + struct snd_soc_component *component = NULL; struct msm_compr_audio *prtd; - struct msm_compr_pdata *pdata = - snd_soc_platform_get_drvdata(rtd->platform); + struct msm_compr_pdata *pdata = NULL; pr_debug("%s\n", __func__); + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + pdata = snd_soc_component_get_drvdata(component); + if (!pdata) { + pr_err("%s: pdata is NULL\n", __func__); + return -EINVAL; + } prtd = kzalloc(sizeof(struct msm_compr_audio), GFP_KERNEL); - if (prtd == NULL) { + if (!prtd) { pr_err("Failed to allocate memory for msm_compr_audio\n"); return -ENOMEM; } @@ -1766,6 +1793,7 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream) struct snd_compr_runtime *runtime; struct msm_compr_audio *prtd; struct snd_soc_pcm_runtime *soc_prtd; + struct snd_soc_component *component = NULL; struct msm_compr_pdata *pdata; struct audio_client *ac; int dir = IN, ret = 0, stream_id; @@ -1780,8 +1808,9 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream) } runtime = cstream->runtime; soc_prtd = cstream->private_data; - if (!runtime || !soc_prtd || !(soc_prtd->platform)) { - pr_err("%s runtime or soc_prtd or platform is null\n", + component = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); + if (!runtime || !soc_prtd || !component) { + pr_err("%s runtime or soc_prtd or component is null\n", __func__); return 0; } @@ -1792,7 +1821,7 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream) } prtd->cmd_interrupt = 1; wake_up(&prtd->drain_wait); - pdata = snd_soc_platform_get_drvdata(soc_prtd->platform); + pdata = snd_soc_component_get_drvdata(component); ac = prtd->audio_client; if (!pdata || !ac) { pr_err("%s pdata or ac is null\n", __func__); @@ -1867,6 +1896,7 @@ static int msm_compr_capture_free(struct snd_compr_stream *cstream) struct snd_compr_runtime *runtime; struct msm_compr_audio *prtd; struct snd_soc_pcm_runtime *soc_prtd; + struct snd_soc_component *component = NULL; struct msm_compr_pdata *pdata; struct audio_client *ac; int dir = OUT, stream_id; @@ -1879,8 +1909,9 @@ static int msm_compr_capture_free(struct snd_compr_stream *cstream) } runtime = cstream->runtime; soc_prtd = cstream->private_data; - if (!runtime || !soc_prtd || !(soc_prtd->platform)) { - pr_err("%s runtime or soc_prtd or platform is null\n", + component = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); + if (!runtime || !soc_prtd || !component) { + pr_err("%s runtime or soc_prtd or component is null\n", __func__); return 0; } @@ -1889,7 +1920,7 @@ static int msm_compr_capture_free(struct snd_compr_stream *cstream) pr_err("%s prtd is null\n", __func__); return 0; } - pdata = snd_soc_platform_get_drvdata(soc_prtd->platform); + pdata = snd_soc_component_get_drvdata(component); ac = prtd->audio_client; if (!pdata || !ac) { pr_err("%s pdata or ac is null\n", __func__); @@ -2207,9 +2238,9 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd) struct snd_compr_runtime *runtime = cstream->runtime; struct msm_compr_audio *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd = cstream->private_data; - struct msm_compr_pdata *pdata = - snd_soc_platform_get_drvdata(rtd->platform); - uint32_t *volume = pdata->volume[rtd->dai_link->id]; + struct snd_soc_component *component = NULL; + struct msm_compr_pdata *pdata = NULL; + uint32_t *volume = NULL; struct audio_client *ac = prtd->audio_client; unsigned long fe_id = rtd->dai_link->id; int rc = 0; @@ -2219,6 +2250,18 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd) uint32_t stream_index; uint16_t bits_per_sample = 16; + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + pdata = snd_soc_component_get_drvdata(component); + if (!pdata) { + pr_err("%s: pdata is NULL\n", __func__); + return -EINVAL; + } + volume = pdata->volume[rtd->dai_link->id]; + spin_lock_irqsave(&prtd->lock, flags); if (atomic_read(&prtd->error)) { pr_err("%s Got RESET EVENTS notification, return immediately", @@ -2676,6 +2719,7 @@ static int msm_compr_pointer(struct snd_compr_stream *cstream, struct snd_compr_runtime *runtime = cstream->runtime; struct snd_soc_pcm_runtime *rtd = cstream->private_data; struct msm_compr_audio *prtd = runtime->private_data; + struct snd_soc_component *component = NULL; struct msm_compr_pdata *pdata = NULL; struct snd_compr_tstamp tstamp; uint64_t timestamp = 0; @@ -2683,7 +2727,17 @@ static int msm_compr_pointer(struct snd_compr_stream *cstream, unsigned long flags; uint32_t gapless_transition; - pdata = snd_soc_platform_get_drvdata(rtd->platform); + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + pdata = snd_soc_component_get_drvdata(component); + if (!pdata) { + pr_err("%s: pdata is NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s\n", __func__); memset(&tstamp, 0x0, sizeof(struct snd_compr_tstamp)); @@ -3906,7 +3960,7 @@ static const struct snd_kcontrol_new msm_compr_gapless_controls[] = { msm_compr_gapless_put), }; -static int msm_compr_probe(struct snd_soc_platform *platform) +static int msm_compr_probe(struct snd_soc_component *component) { struct msm_compr_pdata *pdata; int i; @@ -3919,7 +3973,7 @@ static int msm_compr_probe(struct snd_soc_platform *platform) if (!pdata) return -ENOMEM; - snd_soc_platform_set_drvdata(platform, pdata); + snd_soc_component_set_drvdata(component, pdata); for (i = 0; i < MSM_FRONTEND_DAI_MAX; i++) { pdata->volume[i][0] = COMPRESSED_LR_VOL_MAX_STEPS; @@ -3931,10 +3985,10 @@ static int msm_compr_probe(struct snd_soc_platform *platform) pdata->is_in_use[i] = false; } - snd_soc_add_platform_controls(platform, msm_compr_gapless_controls, + snd_soc_add_component_controls(component, msm_compr_gapless_controls, ARRAY_SIZE(msm_compr_gapless_controls)); - rc = of_property_read_string(platform->dev->of_node, + rc = of_property_read_string(component->dev->of_node, "qcom,adsp-version", &qdsp_version); if (!rc) { if (!strcmp(qdsp_version, "MDSP 1.2")) @@ -4018,6 +4072,7 @@ static int msm_compr_channel_map_info(struct snd_kcontrol *kcontrol, static int msm_compr_add_volume_control(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = "Compress Playback"; const char *deviceNo = "NN"; const char *suffix = "Volume"; @@ -4041,6 +4096,12 @@ static int msm_compr_add_volume_control(struct snd_soc_pcm_runtime *rtd) pr_err("%s NULL rtd\n", __func__); return 0; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return 0; + } + pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n", __func__, rtd->dai_link->name, rtd->dai_link->id, rtd->dai_link->cpu_dai_name, rtd->pcm->device); @@ -4056,7 +4117,7 @@ static int msm_compr_add_volume_control(struct snd_soc_pcm_runtime *rtd) fe_volume_control[0].name = mixer_str; fe_volume_control[0].private_value = rtd->dai_link->id; pr_debug("Registering new mixer ctl %s", mixer_str); - snd_soc_add_platform_controls(rtd->platform, fe_volume_control, + snd_soc_add_component_controls(component, fe_volume_control, ARRAY_SIZE(fe_volume_control)); kfree(mixer_str); return 0; @@ -4064,6 +4125,7 @@ static int msm_compr_add_volume_control(struct snd_soc_pcm_runtime *rtd) static int msm_compr_add_audio_effects_control(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = "Audio Effects Config"; const char *deviceNo = "NN"; char *mixer_str = NULL; @@ -4080,12 +4142,17 @@ static int msm_compr_add_audio_effects_control(struct snd_soc_pcm_runtime *rtd) } }; - if (!rtd) { pr_err("%s NULL rtd\n", __func__); return 0; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return 0; + } + pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n", __func__, rtd->dai_link->name, rtd->dai_link->id, rtd->dai_link->cpu_dai_name, rtd->pcm->device); @@ -4101,7 +4168,7 @@ static int msm_compr_add_audio_effects_control(struct snd_soc_pcm_runtime *rtd) fe_audio_effects_config_control[0].name = mixer_str; fe_audio_effects_config_control[0].private_value = rtd->dai_link->id; pr_debug("Registering new mixer ctl %s\n", mixer_str); - snd_soc_add_platform_controls(rtd->platform, + snd_soc_add_component_controls(component, fe_audio_effects_config_control, ARRAY_SIZE(fe_audio_effects_config_control)); kfree(mixer_str); @@ -4111,6 +4178,7 @@ static int msm_compr_add_audio_effects_control(struct snd_soc_pcm_runtime *rtd) static int msm_compr_add_query_audio_effect_control( struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = "Query Audio Effect Param"; const char *deviceNo = "NN"; char *mixer_str = NULL; @@ -4130,6 +4198,13 @@ static int msm_compr_add_query_audio_effect_control( pr_err("%s NULL rtd\n", __func__); return 0; } + + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return 0; + } + pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n", __func__, rtd->dai_link->name, rtd->dai_link->id, rtd->dai_link->cpu_dai_name, rtd->pcm->device); @@ -4143,7 +4218,7 @@ static int msm_compr_add_query_audio_effect_control( fe_query_audio_effect_control[0].name = mixer_str; fe_query_audio_effect_control[0].private_value = rtd->dai_link->id; pr_debug("%s: registering new mixer ctl %s\n", __func__, mixer_str); - snd_soc_add_platform_controls(rtd->platform, + snd_soc_add_component_controls(component, fe_query_audio_effect_control, ARRAY_SIZE(fe_query_audio_effect_control)); kfree(mixer_str); @@ -4153,6 +4228,7 @@ static int msm_compr_add_query_audio_effect_control( static int msm_compr_add_audio_adsp_stream_cmd_control( struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = DSP_STREAM_CMD; const char *deviceNo = "NN"; char *mixer_str = NULL; @@ -4170,23 +4246,26 @@ static int msm_compr_add_audio_adsp_stream_cmd_control( if (!rtd) { pr_err("%s NULL rtd\n", __func__); - ret = -EINVAL; - goto done; + return -EINVAL; + } + + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; } ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; mixer_str = kzalloc(ctl_len, GFP_KERNEL); - if (!mixer_str) { - ret = -ENOMEM; - goto done; - } + if (!mixer_str) + return -ENOMEM; snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device); fe_audio_adsp_stream_cmd_config_control[0].name = mixer_str; fe_audio_adsp_stream_cmd_config_control[0].private_value = rtd->dai_link->id; pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); - ret = snd_soc_add_platform_controls(rtd->platform, + ret = snd_soc_add_component_controls(component, fe_audio_adsp_stream_cmd_config_control, ARRAY_SIZE(fe_audio_adsp_stream_cmd_config_control)); if (ret < 0) @@ -4201,6 +4280,7 @@ static int msm_compr_add_audio_adsp_stream_cmd_control( static int msm_compr_add_audio_adsp_stream_callback_control( struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = DSP_STREAM_CALLBACK; const char *deviceNo = "NN"; char *mixer_str = NULL; @@ -4224,6 +4304,12 @@ static int msm_compr_add_audio_adsp_stream_callback_control( goto done; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; mixer_str = kzalloc(ctl_len, GFP_KERNEL); if (!mixer_str) { @@ -4236,7 +4322,7 @@ static int msm_compr_add_audio_adsp_stream_callback_control( fe_audio_adsp_callback_config_control[0].private_value = rtd->dai_link->id; pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); - ret = snd_soc_add_platform_controls(rtd->platform, + ret = snd_soc_add_component_controls(component, fe_audio_adsp_callback_config_control, ARRAY_SIZE(fe_audio_adsp_callback_config_control)); if (ret < 0) { @@ -4264,6 +4350,7 @@ static int msm_compr_add_audio_adsp_stream_callback_control( static int msm_compr_add_dec_runtime_params_control( struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = "Audio Stream"; const char *deviceNo = "NN"; const char *suffix = "Dec Params"; @@ -4286,6 +4373,12 @@ static int msm_compr_add_dec_runtime_params_control( return 0; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return 0; + } + pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n", __func__, rtd->dai_link->name, rtd->dai_link->id, rtd->dai_link->cpu_dai_name, rtd->pcm->device); @@ -4303,7 +4396,7 @@ static int msm_compr_add_dec_runtime_params_control( fe_dec_params_control[0].name = mixer_str; fe_dec_params_control[0].private_value = rtd->dai_link->id; pr_debug("Registering new mixer ctl %s", mixer_str); - snd_soc_add_platform_controls(rtd->platform, + snd_soc_add_component_controls(component, fe_dec_params_control, ARRAY_SIZE(fe_dec_params_control)); kfree(mixer_str); @@ -4312,6 +4405,7 @@ static int msm_compr_add_dec_runtime_params_control( static int msm_compr_add_app_type_cfg_control(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *playback_mixer_ctl_name = "Audio Stream"; const char *capture_mixer_ctl_name = "Audio Stream Capture"; const char *deviceNo = "NN"; @@ -4335,6 +4429,12 @@ static int msm_compr_add_app_type_cfg_control(struct snd_soc_pcm_runtime *rtd) return 0; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return 0; + } + pr_debug("%s: added new compr FE ctl with name %s, id %d, cpu dai %s, device no %d\n", __func__, rtd->dai_link->name, rtd->dai_link->id, rtd->dai_link->cpu_dai_name, rtd->pcm->device); @@ -4372,7 +4472,7 @@ static int msm_compr_add_app_type_cfg_control(struct snd_soc_pcm_runtime *rtd) msm_compr_capture_app_type_cfg_get; } pr_debug("Registering new mixer ctl %s", mixer_str); - snd_soc_add_platform_controls(rtd->platform, + snd_soc_add_component_controls(component, fe_app_type_cfg_control, ARRAY_SIZE(fe_app_type_cfg_control)); kfree(mixer_str); @@ -4381,6 +4481,7 @@ static int msm_compr_add_app_type_cfg_control(struct snd_soc_pcm_runtime *rtd) static int msm_compr_add_channel_map_control(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = "Playback Channel Map"; const char *deviceNo = "NN"; char *mixer_str = NULL; @@ -4403,6 +4504,12 @@ static int msm_compr_add_channel_map_control(struct snd_soc_pcm_runtime *rtd) return -EINVAL; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n", __func__, rtd->dai_link->name, rtd->dai_link->id, rtd->dai_link->cpu_dai_name, rtd->pcm->device); @@ -4418,11 +4525,11 @@ static int msm_compr_add_channel_map_control(struct snd_soc_pcm_runtime *rtd) fe_channel_map_control[0].name = mixer_str; fe_channel_map_control[0].private_value = rtd->dai_link->id; pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); - snd_soc_add_platform_controls(rtd->platform, + snd_soc_add_component_controls(component, fe_channel_map_control, ARRAY_SIZE(fe_channel_map_control)); - pdata = snd_soc_platform_get_drvdata(rtd->platform); + pdata = snd_soc_component_get_drvdata(component); pdata->ch_map[rtd->dai_link->id] = kzalloc(sizeof(struct msm_compr_ch_map), GFP_KERNEL); if (!pdata->ch_map[rtd->dai_link->id]) { @@ -4437,6 +4544,7 @@ static int msm_compr_add_channel_map_control(struct snd_soc_pcm_runtime *rtd) static int msm_compr_add_io_fd_cmd_control(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = "Playback ION FD"; const char *deviceNo = "NN"; char *mixer_str = NULL; @@ -4454,22 +4562,25 @@ static int msm_compr_add_io_fd_cmd_control(struct snd_soc_pcm_runtime *rtd) if (!rtd) { pr_err("%s NULL rtd\n", __func__); - ret = -EINVAL; - goto done; + return -EINVAL; + } + + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; } ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; mixer_str = kzalloc(ctl_len, GFP_KERNEL); - if (!mixer_str) { - ret = -ENOMEM; - goto done; - } + if (!mixer_str) + return -ENOMEM; snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device); fe_ion_fd_config_control[0].name = mixer_str; fe_ion_fd_config_control[0].private_value = rtd->dai_link->id; pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); - ret = snd_soc_add_platform_controls(rtd->platform, + ret = snd_soc_add_component_controls(component, fe_ion_fd_config_control, ARRAY_SIZE(fe_ion_fd_config_control)); if (ret < 0) @@ -4482,6 +4593,7 @@ static int msm_compr_add_io_fd_cmd_control(struct snd_soc_pcm_runtime *rtd) static int msm_compr_add_event_ack_cmd_control(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = "Playback Event Ack"; const char *deviceNo = "NN"; char *mixer_str = NULL; @@ -4499,22 +4611,25 @@ static int msm_compr_add_event_ack_cmd_control(struct snd_soc_pcm_runtime *rtd) if (!rtd) { pr_err("%s NULL rtd\n", __func__); - ret = -EINVAL; - goto done; + return -EINVAL; + } + + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; } ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; mixer_str = kzalloc(ctl_len, GFP_KERNEL); - if (!mixer_str) { - ret = -ENOMEM; - goto done; - } + if (!mixer_str) + return -ENOMEM; snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device); fe_event_ack_config_control[0].name = mixer_str; fe_event_ack_config_control[0].private_value = rtd->dai_link->id; pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); - ret = snd_soc_add_platform_controls(rtd->platform, + ret = snd_soc_add_component_controls(component, fe_event_ack_config_control, ARRAY_SIZE(fe_event_ack_config_control)); if (ret < 0) @@ -4593,7 +4708,8 @@ static struct snd_compr_ops msm_compr_ops = { .get_codec_caps = msm_compr_get_codec_caps, }; -static struct snd_soc_platform_driver msm_soc_platform = { +static struct snd_soc_component_driver msm_soc_component = { + .name = DRV_NAME, .probe = msm_compr_probe, .compr_ops = &msm_compr_ops, .pcm_new = msm_compr_new, @@ -4603,13 +4719,13 @@ static int msm_compr_dev_probe(struct platform_device *pdev) { pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev)); - return snd_soc_register_platform(&pdev->dev, - &msm_soc_platform); + return snd_soc_register_component(&pdev->dev, + &msm_soc_component, NULL, 0); } static int msm_compr_remove(struct platform_device *pdev) { - snd_soc_unregister_platform(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } diff --git a/asoc/msm-cpe-lsm.c b/asoc/msm-cpe-lsm.c index d7286e3dad36..19f57a1aab65 100644 --- a/asoc/msm-cpe-lsm.c +++ b/asoc/msm-cpe-lsm.c @@ -20,6 +20,8 @@ #include "msm-slim-dma.h" #include "codecs/cpe_core.h" +#define DRV_NAME "msm-cpe-lsm" + #define SAMPLE_RATE_48KHZ 48000 #define SAMPLE_RATE_16KHZ 16000 #define LSM_VOICE_WAKEUP_APP_V2 2 @@ -3202,55 +3204,57 @@ static int msm_cpe_lsm_copy(struct snd_pcm_substream *substream, int a, } /* - * msm_asoc_cpe_lsm_probe: ASoC framework for lsm platform driver - * @platform: platform registered with ASoC core + * msm_asoc_cpe_lsm_probe: ASoC framework for lsm component driver + * @component: component registered with ASoC core * - * Allocate the private data for this platform and obtain the ops for + * Allocate the private data for this component and obtain the ops for * lsm and afe modules from underlying driver. Also find the codec - * for this platform as specified by machine driver for ASoC framework. + * for this component as specified by machine driver for ASoC framework. */ -static int msm_asoc_cpe_lsm_probe(struct snd_soc_platform *platform) +static int msm_asoc_cpe_lsm_probe(struct snd_soc_component *component) { struct snd_soc_card *card; struct snd_soc_pcm_runtime *rtd; struct snd_soc_codec *codec; struct cpe_priv *cpe_priv; + struct snd_soc_component *component_rtd = NULL; const struct snd_kcontrol_new *kcontrol; bool found_runtime = false; const char *cpe_dev_id = "qcom,msm-cpe-lsm-id"; u32 port_id = 0; int ret = 0; - if (!platform || !platform->component.card) { - pr_err("%s: Invalid platform or card\n", + if (!component || !component->card) { + pr_err("%s: Invalid component or card\n", __func__); return -EINVAL; } - card = platform->component.card; + card = component->card; - /* Match platform to codec */ + /* Match component to codec */ list_for_each_entry(rtd, &card->rtd_list, list) { - if (!rtd->platform) + component_rtd = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component_rtd) continue; - if (!strcmp(rtd->platform->component.name, - platform->component.name)) { + if (!strcmp(component_rtd->name, + component->name)) { found_runtime = true; break; } } if (!found_runtime) { - dev_err(platform->dev, - "%s: Failed to find runtime for platform\n", + dev_err(component->dev, + "%s: Failed to find runtime for component\n", __func__); return -EINVAL; } - ret = of_property_read_u32(platform->dev->of_node, cpe_dev_id, + ret = of_property_read_u32(component->dev->of_node, cpe_dev_id, &port_id); if (ret) { - dev_dbg(platform->dev, + dev_dbg(component->dev, "%s: missing 0x%x in dt node\n", __func__, port_id); port_id = 1; } @@ -3267,7 +3271,7 @@ static int msm_asoc_cpe_lsm_probe(struct snd_soc_platform *platform) wcd_cpe_get_lsm_ops(&cpe_priv->lsm_ops); wcd_cpe_get_afe_ops(&cpe_priv->afe_ops); - snd_soc_platform_set_drvdata(platform, cpe_priv); + snd_soc_component_set_drvdata(component, cpe_priv); kcontrol = &msm_cpe_kcontrols[0]; snd_ctl_add(card->snd_card, snd_ctl_new1(kcontrol, cpe_priv)); return 0; @@ -3285,7 +3289,8 @@ static const struct snd_pcm_ops msm_cpe_lsm_ops = { .compat_ioctl = msm_cpe_lsm_ioctl_compat, }; -static struct snd_soc_platform_driver msm_soc_cpe_platform = { +static struct snd_soc_component_driver msm_soc_cpe_component = { + .name = DRV_NAME, .ops = &msm_cpe_lsm_ops, .probe = msm_asoc_cpe_lsm_probe, }; @@ -3299,8 +3304,9 @@ static struct snd_soc_platform_driver msm_soc_cpe_platform = { static int msm_cpe_lsm_probe(struct platform_device *pdev) { - return snd_soc_register_platform(&pdev->dev, - &msm_soc_cpe_platform); + return snd_soc_register_component(&pdev->dev, + &msm_soc_cpe_component, + NULL, 0); } /* @@ -3311,7 +3317,7 @@ static int msm_cpe_lsm_probe(struct platform_device *pdev) */ static int msm_cpe_lsm_remove(struct platform_device *pdev) { - snd_soc_unregister_platform(&pdev->dev); + snd_soc_unregister_commponent(&pdev->dev); return 0; } diff --git a/asoc/msm-dolby-dap-config.h b/asoc/msm-dolby-dap-config.h index f7d4fa94a47a..f7e21d685337 100644 --- a/asoc/msm-dolby-dap-config.h +++ b/asoc/msm-dolby-dap-config.h @@ -67,7 +67,7 @@ int msm_dolby_dap_init(int port_id, int copp_idx, int channels, return 0; } void msm_dolby_dap_deinit(int port_id) { } -void msm_dolby_dap_add_controls(struct snd_soc_platform *platform) { } +void msm_dolby_dap_add_controls(struct snd_soc_component *component) { } int dolby_dap_set_custom_stereo_onoff(int port_id, int copp_idx, bool is_custom_stereo_enabled) { diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 98132b4b8979..74263e381434 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -25,6 +25,8 @@ #include #include "msm-pcm-routing-v2.h" +#define DRV_NAME "msm-lsm-client" + #define CAPTURE_MIN_NUM_PERIODS 2 #define CAPTURE_MAX_NUM_PERIODS 8 #define CAPTURE_MAX_PERIOD_SIZE 61440 @@ -2932,14 +2934,15 @@ static int msm_asoc_lsm_new(struct snd_soc_pcm_runtime *rtd) return ret; } -static int msm_asoc_lsm_probe(struct snd_soc_platform *platform) +static int msm_asoc_lsm_probe(struct snd_soc_component *component) { pr_debug("enter %s\n", __func__); return 0; } -static struct snd_soc_platform_driver msm_soc_platform = { +static struct snd_soc_component_driver msm_soc_component = { + .name = DRV_NAME, .ops = &msm_lsm_ops, .pcm_new = msm_asoc_lsm_new, .probe = msm_asoc_lsm_probe, @@ -2948,12 +2951,13 @@ static struct snd_soc_platform_driver msm_soc_platform = { static int msm_lsm_probe(struct platform_device *pdev) { - return snd_soc_register_platform(&pdev->dev, &msm_soc_platform); + return snd_soc_register_component(&pdev->dev, &msm_soc_component, + NULL, 0); } static int msm_lsm_remove(struct platform_device *pdev) { - snd_soc_unregister_platform(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } diff --git a/asoc/msm-pcm-afe-v2.c b/asoc/msm-pcm-afe-v2.c index 1565a76ea097..a34514bb821d 100644 --- a/asoc/msm-pcm-afe-v2.c +++ b/asoc/msm-pcm-afe-v2.c @@ -24,6 +24,8 @@ #include #include "msm-pcm-afe-v2.h" +#define DRV_NAME "msm-pcm-afe-v2" + #define MIN_PLAYBACK_PERIOD_SIZE (128 * 2) #define MAX_PLAYBACK_PERIOD_SIZE (128 * 2 * 2 * 6) #define MIN_PLAYBACK_NUM_PERIODS (4) @@ -854,13 +856,14 @@ static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) return ret; } -static int msm_afe_afe_probe(struct snd_soc_platform *platform) +static int msm_afe_afe_probe(struct snd_soc_component *component) { pr_debug("%s\n", __func__); return 0; } -static struct snd_soc_platform_driver msm_soc_platform = { +static struct snd_soc_component_driver msm_soc_component = { + .name = DRV_NAME, .ops = &msm_afe_ops, .pcm_new = msm_asoc_pcm_new, .probe = msm_afe_afe_probe, @@ -870,14 +873,14 @@ static int msm_afe_probe(struct platform_device *pdev) { pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev)); - return snd_soc_register_platform(&pdev->dev, - &msm_soc_platform); + return snd_soc_register_component(&pdev->dev, + &msm_soc_component, NULL, 0); } static int msm_afe_remove(struct platform_device *pdev) { pr_debug("%s\n", __func__); - snd_soc_unregister_platform(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } static const struct of_device_id msm_pcm_afe_dt_match[] = { diff --git a/asoc/msm-pcm-dtmf-v2.c b/asoc/msm-pcm-dtmf-v2.c index ecec8bf9b5df..e8eb468090fb 100644 --- a/asoc/msm-pcm-dtmf-v2.c +++ b/asoc/msm-pcm-dtmf-v2.c @@ -18,6 +18,8 @@ #include "msm-pcm-q6-v2.h" #include "msm-pcm-routing-v2.h" +#define DRV_NAME "msm-pcm-dtmf-v2" + enum { DTMF_IN_RX, DTMF_IN_TX, @@ -157,9 +159,9 @@ static struct snd_kcontrol_new msm_dtmf_controls[] = { msm_dtmf_detect_volte_rx_put), }; -static int msm_pcm_dtmf_probe(struct snd_soc_platform *platform) +static int msm_pcm_dtmf_probe(struct snd_soc_component *component) { - snd_soc_add_platform_controls(platform, msm_dtmf_controls, + snd_soc_add_component_controls(component, msm_dtmf_controls, ARRAY_SIZE(msm_dtmf_controls)); return 0; } @@ -531,7 +533,8 @@ static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) return ret; } -static struct snd_soc_platform_driver msm_soc_platform = { +static struct snd_soc_component_driver msm_soc_component = { + .name = DRV_NAME, .ops = &msm_pcm_ops, .pcm_new = msm_asoc_pcm_new, .probe = msm_pcm_dtmf_probe, @@ -541,13 +544,13 @@ static int msm_pcm_probe(struct platform_device *pdev) { pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev)); - return snd_soc_register_platform(&pdev->dev, - &msm_soc_platform); + return snd_soc_register_component(&pdev->dev, + &msm_soc_component, NULL, 0); } static int msm_pcm_remove(struct platform_device *pdev) { - snd_soc_unregister_platform(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } diff --git a/asoc/msm-pcm-host-voice-v2.c b/asoc/msm-pcm-host-voice-v2.c index 1cc5c161ea66..9fc7c8867953 100644 --- a/asoc/msm-pcm-host-voice-v2.c +++ b/asoc/msm-pcm-host-voice-v2.c @@ -20,6 +20,8 @@ #include #include +#define DRV_NAME "msm-pcm-host-voice-v2" + #define HPCM_MAX_Q_LEN 2 #define HPCM_MIN_VOC_PKT_SIZE 320 #define HPCM_MAX_VOC_PKT_SIZE 640 @@ -1435,15 +1437,16 @@ static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) return 0; } -static int msm_pcm_hpcm_probe(struct snd_soc_platform *platform) +static int msm_pcm_hpcm_probe(struct snd_soc_component *component) { - snd_soc_add_platform_controls(platform, msm_hpcm_controls, + snd_soc_add_component_controls(component, msm_hpcm_controls, ARRAY_SIZE(msm_hpcm_controls)); return 0; } -static struct snd_soc_platform_driver msm_soc_platform = { +static struct snd_soc_component_driver msm_soc_component = { + .name = DRV_NAME, .ops = &msm_pcm_ops, .pcm_new = msm_asoc_pcm_new, .probe = msm_pcm_hpcm_probe, @@ -1453,12 +1456,13 @@ static int msm_pcm_probe(struct platform_device *pdev) { pr_info("%s: dev name %s\n", __func__, dev_name(&pdev->dev)); - return snd_soc_register_platform(&pdev->dev, &msm_soc_platform); + return snd_soc_register_component(&pdev->dev, &msm_soc_component, + NULL, 0); } static int msm_pcm_remove(struct platform_device *pdev) { - snd_soc_unregister_platform(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } diff --git a/asoc/msm-pcm-hostless.c b/asoc/msm-pcm-hostless.c index 9c69e12e5138..9a0c52b01169 100644 --- a/asoc/msm-pcm-hostless.c +++ b/asoc/msm-pcm-hostless.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2011-2014, 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2017-2018, The Linux Foundation. All rights reserved. */ #include @@ -10,6 +10,7 @@ #include #include +#define DRV_NAME "msm-pcm-hostless" static int msm_pcm_hostless_prepare(struct snd_pcm_substream *substream) { @@ -25,7 +26,8 @@ static const struct snd_pcm_ops msm_pcm_hostless_ops = { .prepare = msm_pcm_hostless_prepare }; -static struct snd_soc_platform_driver msm_soc_hostless_platform = { +static struct snd_soc_component_driver msm_soc_hostless_component = { + .name = DRV_NAME, .ops = &msm_pcm_hostless_ops, }; @@ -33,13 +35,14 @@ static int msm_pcm_hostless_probe(struct platform_device *pdev) { pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev)); - return snd_soc_register_platform(&pdev->dev, - &msm_soc_hostless_platform); + return snd_soc_register_component(&pdev->dev, + &msm_soc_hostless_component, + NULL, 0); } static int msm_pcm_hostless_remove(struct platform_device *pdev) { - snd_soc_unregister_platform(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index 3ef6280bbcaa..9b90935b6dac 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -21,6 +21,8 @@ #include "msm-pcm-routing-v2.h" +#define DRV_NAME "msm-pcm-loopback-v2" + #define LOOPBACK_VOL_MAX_STEPS 0x2000 #define LOOPBACK_SESSION_MAX 4 @@ -151,9 +153,9 @@ static struct snd_kcontrol_new msm_loopback_controls[] = { msm_loopback_session_mute_put), }; -static int msm_pcm_loopback_probe(struct snd_soc_platform *platform) +static int msm_pcm_loopback_probe(struct snd_soc_component *component) { - snd_soc_add_platform_controls(platform, msm_loopback_controls, + snd_soc_add_component_controls(component, msm_loopback_controls, ARRAY_SIZE(msm_loopback_controls)); return 0; @@ -180,10 +182,17 @@ static int pcm_loopback_set_volume(struct msm_pcm_loopback *prtd, static int msm_pcm_loopback_get_session(struct snd_soc_pcm_runtime *rtd, struct msm_pcm_loopback **pcm) { + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(rtd, DRV_NAME); int ret = 0; int n, index = -1; - dev_dbg(rtd->platform->dev, "%s: stream %s\n", __func__, + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + dev_dbg(component->dev, "%s: stream %s\n", __func__, rtd->dai_link->stream_name); mutex_lock(&loopback_session_lock); @@ -206,7 +215,7 @@ static int msm_pcm_loopback_get_session(struct snd_soc_pcm_runtime *rtd, } if (index < 0) { - dev_err(rtd->platform->dev, "%s: Max Sessions allocated\n", + dev_err(component->dev, "%s: Max Sessions allocated\n", __func__); ret = -EAGAIN; goto exit; @@ -222,7 +231,7 @@ static int msm_pcm_loopback_get_session(struct snd_soc_pcm_runtime *rtd, strlcpy(session_map[index].stream_name, rtd->dai_link->stream_name, sizeof(session_map[index].stream_name)); - dev_dbg(rtd->platform->dev, "%s: stream %s index %d\n", + dev_dbg(component->dev, "%s: stream %s index %d\n", __func__, session_map[index].stream_name, index); mutex_init(&session_map[index].loopback_priv->lock); @@ -236,6 +245,8 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(rtd, DRV_NAME); struct msm_pcm_loopback *pcm = NULL; int ret = 0; uint16_t bits_per_sample = 16; @@ -244,6 +255,11 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) uint32_t param_id; struct msm_pcm_pdata *pdata; + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + ret = msm_pcm_loopback_get_session(rtd, &pcm); if (ret) return ret; @@ -258,7 +274,7 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) pcm->capture_substream = substream; pcm->instance++; - dev_dbg(rtd->platform->dev, "%s: pcm out open: %d,%d\n", __func__, + dev_dbg(component->dev, "%s: pcm out open: %d,%d\n", __func__, pcm->instance, substream->stream); if (pcm->instance == 2) { struct snd_soc_pcm_runtime *soc_pcm_rx = @@ -269,9 +285,9 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) stop_pcm(pcm); pdata = (struct msm_pcm_pdata *) - dev_get_drvdata(rtd->platform->dev); + dev_get_drvdata(component->dev); if (!pdata) { - dev_err(rtd->platform->dev, + dev_err(component->dev, "%s: platform data not populated\n", __func__); mutex_unlock(&pcm->lock); return -EINVAL; @@ -280,7 +296,7 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) pcm->audio_client = q6asm_audio_client_alloc( (app_cb)msm_pcm_loopback_event_handler, pcm); if (!pcm->audio_client) { - dev_err(rtd->platform->dev, + dev_err(component->dev, "%s: Could not allocate memory\n", __func__); mutex_unlock(&pcm->lock); return -ENOMEM; @@ -290,7 +306,7 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) ret = q6asm_open_loopback_v2(pcm->audio_client, bits_per_sample); if (ret < 0) { - dev_err(rtd->platform->dev, + dev_err(component->dev, "%s: pcm out open failed\n", __func__); q6asm_audio_client_free(pcm->audio_client); mutex_unlock(&pcm->lock); @@ -309,7 +325,7 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) pcm->playback_substream = substream; ret = pcm_loopback_set_volume(pcm, pcm->volume); if (ret < 0) - dev_err(rtd->platform->dev, + dev_err(component->dev, "Error %d setting volume", ret); } /* Set to largest negative value */ @@ -327,7 +343,7 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) &asm_mtmx_strtr_window, param_id); } - dev_info(rtd->platform->dev, "%s: Instance = %d, Stream ID = %s\n", + dev_info(component->dev, "%s: Instance = %d, Stream ID = %s\n", __func__, pcm->instance, substream->pcm->id); runtime->private_data = pcm; @@ -364,12 +380,19 @@ static int msm_pcm_close(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct msm_pcm_loopback *pcm = runtime->private_data; struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(rtd, DRV_NAME); int ret = 0, n; bool found = false; + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + mutex_lock(&pcm->lock); - dev_dbg(rtd->platform->dev, "%s: end pcm call:%d\n", + dev_dbg(component->dev, "%s: end pcm call:%d\n", __func__, substream->stream); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) pcm->playback_start = 0; @@ -378,7 +401,7 @@ static int msm_pcm_close(struct snd_pcm_substream *substream) pcm->instance--; if (!pcm->playback_start || !pcm->capture_start) { - dev_dbg(rtd->platform->dev, "%s: end pcm call\n", __func__); + dev_dbg(component->dev, "%s: end pcm call\n", __func__); stop_pcm(pcm); } @@ -398,7 +421,7 @@ static int msm_pcm_close(struct snd_pcm_substream *substream) mutex_destroy(&session_map[n].loopback_priv->lock); session_map[n].loopback_priv = NULL; kfree(pcm); - dev_dbg(rtd->platform->dev, "%s: stream freed %s\n", + dev_dbg(component->dev, "%s: stream freed %s\n", __func__, rtd->dai_link->stream_name); mutex_unlock(&loopback_session_lock); return 0; @@ -415,10 +438,17 @@ static int msm_pcm_prepare(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct msm_pcm_loopback *pcm = runtime->private_data; struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(rtd, DRV_NAME); + + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } mutex_lock(&pcm->lock); - dev_dbg(rtd->platform->dev, "%s: ASM loopback stream:%d\n", + dev_dbg(component->dev, "%s: ASM loopback stream:%d\n", __func__, substream->stream); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (!pcm->playback_start) @@ -437,12 +467,19 @@ static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd) struct snd_pcm_runtime *runtime = substream->runtime; struct msm_pcm_loopback *pcm = runtime->private_data; struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(rtd, DRV_NAME); + + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - dev_dbg(rtd->platform->dev, + dev_dbg(component->dev, "%s: playback_start:%d,capture_start:%d\n", __func__, pcm->playback_start, pcm->capture_start); if (pcm->playback_start && pcm->capture_start) @@ -451,7 +488,7 @@ static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_STOP: - dev_dbg(rtd->platform->dev, + dev_dbg(component->dev, "%s:Pause/Stop - playback_start:%d,capture_start:%d\n", __func__, pcm->playback_start, pcm->capture_start); if (pcm->playback_start && pcm->capture_start) @@ -727,7 +764,8 @@ static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) return ret; } -static struct snd_soc_platform_driver msm_soc_platform = { +static struct snd_soc_component_driver msm_soc_component = { + .name = DRV_NAME, .ops = &msm_pcm_ops, .pcm_new = msm_asoc_pcm_new, .probe = msm_pcm_loopback_probe, @@ -752,13 +790,14 @@ static int msm_pcm_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, pdata); - return snd_soc_register_platform(&pdev->dev, - &msm_soc_platform); + return snd_soc_register_component(&pdev->dev, + &msm_soc_component, + NULL, 0); } static int msm_pcm_remove(struct platform_device *pdev) { - snd_soc_unregister_platform(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index 8e5c423433d5..aac3fe022938 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -33,6 +33,9 @@ #include "msm-pcm-q6-v2.h" #include "msm-pcm-routing-v2.h" + +#define DRV_NAME "msm-pcm-q6-noirq" + #define PCM_MASTER_VOL_MAX_STEPS 0x2000 static const DECLARE_TLV_DB_LINEAR(msm_pcm_vol_gain, 0, PCM_MASTER_VOL_MAX_STEPS); @@ -256,6 +259,8 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream, { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); struct msm_audio *prtd = runtime->private_data; struct msm_plat_data *pdata; struct snd_dma_buffer *dma_buf = &substream->dma_buffer; @@ -270,8 +275,13 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream, bool use_default_chmap = true; char *chmap = NULL; + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + pdata = (struct msm_plat_data *) - dev_get_drvdata(soc_prtd->platform->dev); + dev_get_drvdata(component->dev); if (!pdata) { ret = -EINVAL; pr_err("%s: platform data not populated ret: %d\n", __func__, @@ -790,6 +800,7 @@ static int msm_pcm_channel_map_get(struct snd_kcontrol *kcontrol, static int msm_pcm_add_channel_map_control(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = "Playback Channel Map"; const char *deviceNo = "NN"; char *mixer_str = NULL; @@ -812,6 +823,12 @@ static int msm_pcm_add_channel_map_control(struct snd_soc_pcm_runtime *rtd) return -EINVAL; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: added new pcm FE with name %s, id %d, cpu dai %s, device no %d\n", __func__, rtd->dai_link->name, rtd->dai_link->id, rtd->dai_link->cpu_dai_name, rtd->pcm->device); @@ -826,11 +843,11 @@ static int msm_pcm_add_channel_map_control(struct snd_soc_pcm_runtime *rtd) fe_channel_map_control[0].name = mixer_str; fe_channel_map_control[0].private_value = rtd->dai_link->id; pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); - snd_soc_add_platform_controls(rtd->platform, + snd_soc_add_component_controls(component, fe_channel_map_control, ARRAY_SIZE(fe_channel_map_control)); - pdata = snd_soc_platform_get_drvdata(rtd->platform); + pdata = snd_soc_component_get_drvdata(component); pdata->ch_map[rtd->dai_link->id] = kzalloc(sizeof(struct msm_pcm_ch_map), GFP_KERNEL); if (!pdata->ch_map[rtd->dai_link->id]) { @@ -893,6 +910,7 @@ static int msm_pcm_fe_topology_put(struct snd_kcontrol *kcontrol, static int msm_pcm_add_fe_topology_control(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = "PCM_Dev"; const char *deviceNo = "NN"; const char *topo_text = "Topology"; @@ -911,6 +929,12 @@ static int msm_pcm_add_fe_topology_control(struct snd_soc_pcm_runtime *rtd) }, }; + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 + strlen(topo_text) + 1; mixer_str = kzalloc(ctl_len, GFP_KERNEL); @@ -923,7 +947,7 @@ static int msm_pcm_add_fe_topology_control(struct snd_soc_pcm_runtime *rtd) topology_control[0].name = mixer_str; topology_control[0].private_value = rtd->dai_link->id; - ret = snd_soc_add_platform_controls(rtd->platform, topology_control, + ret = snd_soc_add_component_controls(component, topology_control, ARRAY_SIZE(topology_control)); msm_pcm_fe_topology[rtd->dai_link->id] = 0; kfree(mixer_str); @@ -1240,7 +1264,8 @@ static const struct snd_pcm_ops msm_pcm_ops = { .close = msm_pcm_close, }; -static struct snd_soc_platform_driver msm_soc_platform = { +static struct snd_soc_component_driver msm_soc_component = { + .name = DRV_NAME, .ops = &msm_pcm_ops, .pcm_new = msm_asoc_pcm_new, }; @@ -1279,8 +1304,9 @@ static int msm_pcm_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "%s: dev name %s\n", __func__, dev_name(&pdev->dev)); dev_dbg(&pdev->dev, "Pull mode driver register\n"); - rc = snd_soc_register_platform(&pdev->dev, - &msm_soc_platform); + rc = snd_soc_register_component(&pdev->dev, + &msm_soc_component, + NULL, 0); if (rc) dev_err(&pdev->dev, "Failed to register pull mode driver\n"); @@ -1295,7 +1321,7 @@ static int msm_pcm_remove(struct platform_device *pdev) dev_dbg(&pdev->dev, "Pull mode remove\n"); pdata = dev_get_drvdata(&pdev->dev); devm_kfree(&pdev->dev, pdata); - snd_soc_unregister_platform(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } static const struct of_device_id msm_pcm_noirq_dt_match[] = { diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index ad25aae605db..1ad10db61ff5 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -34,6 +34,8 @@ #include "msm-pcm-routing-v2.h" #include "msm-qti-pp-config.h" +#define DRV_NAME "msm-pcm-q6-v2" + enum stream_state { IDLE = 0, STOPPED, @@ -312,6 +314,8 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); struct msm_audio *prtd = runtime->private_data; struct msm_plat_data *pdata; struct snd_pcm_hw_params *params; @@ -320,8 +324,13 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) uint16_t bits_per_sample; uint16_t sample_word_size; + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + pdata = (struct msm_plat_data *) - dev_get_drvdata(soc_prtd->platform->dev); + dev_get_drvdata(component->dev); if (!pdata) { pr_err("%s: platform data not populated\n", __func__); return -EINVAL; @@ -464,6 +473,8 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct msm_audio *prtd = runtime->private_data; struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); struct msm_plat_data *pdata; struct snd_pcm_hw_params *params; struct msm_pcm_routing_evt event; @@ -472,8 +483,13 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) uint16_t bits_per_sample = 16; uint16_t sample_word_size; + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + pdata = (struct msm_plat_data *) - dev_get_drvdata(soc_prtd->platform->dev); + dev_get_drvdata(component->dev); if (!pdata) { pr_err("%s: platform data not populated\n", __func__); return -EINVAL; @@ -658,12 +674,19 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); struct msm_audio *prtd; struct msm_plat_data *pdata; int ret = 0; + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + pdata = (struct msm_plat_data *) - dev_get_drvdata(soc_prtd->platform->dev); + dev_get_drvdata(component->dev); if (!pdata) { pr_err("%s: platform data not populated\n", __func__); return -EINVAL; @@ -682,7 +705,7 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) return -ENOMEM; } - prtd->audio_client->dev = soc_prtd->platform->dev; + prtd->audio_client->dev = component->dev; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) runtime->hw = msm_pcm_hardware_playback; @@ -858,6 +881,8 @@ static int msm_pcm_playback_close(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; struct msm_audio *prtd = runtime->private_data; + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); struct msm_plat_data *pdata; uint32_t timeout; int dir = 0; @@ -867,13 +892,17 @@ static int msm_pcm_playback_close(struct snd_pcm_substream *substream) if (prtd->audio_client) { dir = IN; + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } /* * Unvote to downgrade the Rx thread priority from * RT Thread for Low-Latency use case. */ pdata = (struct msm_plat_data *) - dev_get_drvdata(soc_prtd->platform->dev); + dev_get_drvdata(component->dev); if (pdata) { if (pdata->perf_mode == LOW_LATENCY_PCM_MODE) apr_end_rx_rt(prtd->audio_client->apr); @@ -1139,14 +1168,20 @@ static const struct snd_pcm_ops msm_pcm_ops = { static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *pcm = snd_kcontrol_chip(kcontrol); - struct snd_soc_platform *platform = snd_soc_component_to_platform(pcm); - struct msm_plat_data *pdata = dev_get_drvdata(platform->dev); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct msm_plat_data *pdata = NULL; struct snd_pcm_substream *substream; struct msm_audio *prtd; int ret = 0; struct msm_adsp_event_data *event_data = NULL; + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + pdata = dev_get_drvdata(component->dev); if (!pdata) { pr_err("%s pdata is NULL\n", __func__); ret = -ENODEV; @@ -1207,6 +1242,7 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, static int msm_pcm_add_audio_adsp_stream_cmd_control( struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = DSP_STREAM_CMD; const char *deviceNo = "NN"; char *mixer_str = NULL; @@ -1228,6 +1264,12 @@ static int msm_pcm_add_audio_adsp_stream_cmd_control( goto done; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; mixer_str = kzalloc(ctl_len, GFP_KERNEL); if (!mixer_str) { @@ -1240,7 +1282,7 @@ static int msm_pcm_add_audio_adsp_stream_cmd_control( fe_audio_adsp_stream_cmd_config_control[0].private_value = rtd->dai_link->id; pr_debug("Registering new mixer ctl %s\n", mixer_str); - ret = snd_soc_add_platform_controls(rtd->platform, + ret = snd_soc_add_component_controls(component, fe_audio_adsp_stream_cmd_config_control, ARRAY_SIZE(fe_audio_adsp_stream_cmd_config_control)); if (ret < 0) @@ -1255,6 +1297,7 @@ static int msm_pcm_add_audio_adsp_stream_cmd_control( static int msm_pcm_add_audio_adsp_stream_callback_control( struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = DSP_STREAM_CALLBACK; const char *deviceNo = "NN"; char *mixer_str = NULL; @@ -1278,6 +1321,12 @@ static int msm_pcm_add_audio_adsp_stream_callback_control( goto done; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: added new pcm FE with name %s, id %d, cpu dai %s, device no %d\n", __func__, rtd->dai_link->name, rtd->dai_link->id, rtd->dai_link->cpu_dai_name, rtd->pcm->device); @@ -1293,7 +1342,7 @@ static int msm_pcm_add_audio_adsp_stream_callback_control( fe_audio_adsp_callback_config_control[0].private_value = rtd->dai_link->id; pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); - ret = snd_soc_add_platform_controls(rtd->platform, + ret = snd_soc_add_component_controls(component, fe_audio_adsp_callback_config_control, ARRAY_SIZE(fe_audio_adsp_callback_config_control)); if (ret < 0) { @@ -1419,9 +1468,8 @@ static int msm_pcm_compress_ctl_info(struct snd_kcontrol *kcontrol, static int msm_pcm_compress_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); - struct snd_soc_platform *platform = snd_soc_component_to_platform(comp); - struct msm_plat_data *pdata = dev_get_drvdata(platform->dev); + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct msm_plat_data *pdata = dev_get_drvdata(comp->dev); struct snd_pcm_substream *substream; struct msm_audio *prtd; @@ -1448,9 +1496,8 @@ static int msm_pcm_compress_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int rc = 0; - struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); - struct snd_soc_platform *platform = snd_soc_component_to_platform(comp); - struct msm_plat_data *pdata = dev_get_drvdata(platform->dev); + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct msm_plat_data *pdata = dev_get_drvdata(comp->dev); struct snd_pcm_substream *substream; struct msm_audio *prtd; int compress = ucontrol->value.integer.value[0]; @@ -1480,6 +1527,7 @@ static int msm_pcm_compress_ctl_put(struct snd_kcontrol *kcontrol, static int msm_pcm_add_compress_control(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = "Playback "; const char *mixer_ctl_end_name = " Compress"; const char *deviceNo = "NN"; @@ -1504,6 +1552,12 @@ static int msm_pcm_add_compress_control(struct snd_soc_pcm_runtime *rtd) return -EINVAL; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + ctl_len = strlen(mixer_ctl_name) + strlen(deviceNo) + strlen(mixer_ctl_end_name) + 1; mixer_str = kzalloc(ctl_len, GFP_KERNEL); @@ -1517,16 +1571,16 @@ static int msm_pcm_add_compress_control(struct snd_soc_pcm_runtime *rtd) pcm_compress_control[0].name = mixer_str; pcm_compress_control[0].private_value = rtd->dai_link->id; pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); - pdata = dev_get_drvdata(rtd->platform->dev); + pdata = dev_get_drvdata(component->dev); if (pdata) { if (!pdata->pcm) { pdata->pcm = rtd->pcm; - snd_soc_add_platform_controls(rtd->platform, + snd_soc_add_component_controls(component, pcm_compress_control, ARRAY_SIZE (pcm_compress_control)); pr_debug("%s: add control success plt = %pK\n", - __func__, rtd->platform); + __func__, component); } } else { pr_err("%s: NULL pdata\n", __func__); @@ -1860,7 +1914,8 @@ static snd_pcm_sframes_t msm_pcm_delay_blk(struct snd_pcm_substream *substream, return frames; } -static struct snd_soc_platform_driver msm_soc_platform = { +static struct snd_soc_component_driver msm_soc_component = { + .name = DRV_NAME, .ops = &msm_pcm_ops, .pcm_new = msm_asoc_pcm_new, .delay_blk = msm_pcm_delay_blk, @@ -1907,8 +1962,9 @@ static int msm_pcm_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "%s: dev name %s\n", __func__, dev_name(&pdev->dev)); - return snd_soc_register_platform(&pdev->dev, - &msm_soc_platform); + return snd_soc_register_component(&pdev->dev, + &msm_soc_component, + NULL, 0); } static int msm_pcm_remove(struct platform_device *pdev) @@ -1917,7 +1973,7 @@ static int msm_pcm_remove(struct platform_device *pdev) pdata = dev_get_drvdata(&pdev->dev); kfree(pdata); - snd_soc_unregister_platform(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } static const struct of_device_id msm_pcm_dt_match[] = { diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 443ff3a3fff1..db5713b8e370 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -38,6 +38,8 @@ #include "msm-dolby-dap-config.h" #include "msm-ds2-dap-config.h" +#define DRV_NAME "msm-pcm-routing-v2" + #ifndef CONFIG_DOLBY_DAP #undef DOLBY_ADM_COPP_TOPOLOGY_ID #define DOLBY_ADM_COPP_TOPOLOGY_ID 0xFFFFFFFE @@ -23588,75 +23590,76 @@ static const struct snd_pcm_ops msm_routing_pcm_ops = { }; /* Not used but frame seems to require it */ -static int msm_routing_probe(struct snd_soc_platform *platform) +static int msm_routing_probe(struct snd_soc_component *component) { - snd_soc_dapm_new_controls(&platform->component.dapm, msm_qdsp6_widgets, + snd_soc_dapm_new_controls(&component->dapm, msm_qdsp6_widgets, ARRAY_SIZE(msm_qdsp6_widgets)); - snd_soc_dapm_add_routes(&platform->component.dapm, intercon, + snd_soc_dapm_add_routes(&component->dapm, intercon, ARRAY_SIZE(intercon)); - snd_soc_dapm_new_widgets(platform->component.dapm.card); + snd_soc_dapm_new_widgets(component->dapm.card); - snd_soc_add_platform_controls(platform, lsm_controls, + snd_soc_add_component_controls(component, lsm_controls, ARRAY_SIZE(lsm_controls)); - snd_soc_add_platform_controls(platform, aanc_slim_0_rx_mux, + snd_soc_add_component_controls(component, aanc_slim_0_rx_mux, ARRAY_SIZE(aanc_slim_0_rx_mux)); - snd_soc_add_platform_controls(platform, aanc_noise_level, + snd_soc_add_component_controls(component, aanc_noise_level, ARRAY_SIZE(aanc_noise_level)); - snd_soc_add_platform_controls(platform, msm_voc_session_controls, + snd_soc_add_component_controls(component, msm_voc_session_controls, ARRAY_SIZE(msm_voc_session_controls)); - snd_soc_add_platform_controls(platform, app_type_cfg_controls, + snd_soc_add_component_controls(component, app_type_cfg_controls, ARRAY_SIZE(app_type_cfg_controls)); - snd_soc_add_platform_controls(platform, lsm_app_type_cfg_controls, + snd_soc_add_component_controls(component, lsm_app_type_cfg_controls, ARRAY_SIZE(lsm_app_type_cfg_controls)); - snd_soc_add_platform_controls(platform, module_cfg_controls, + snd_soc_add_component_controls(component, module_cfg_controls, ARRAY_SIZE(module_cfg_controls)); - snd_soc_add_platform_controls(platform, + snd_soc_add_component_controls(component, stereo_to_custom_stereo_controls, ARRAY_SIZE(stereo_to_custom_stereo_controls)); - snd_soc_add_platform_controls(platform, ec_ref_param_controls, + snd_soc_add_component_controls(component, ec_ref_param_controls, ARRAY_SIZE(ec_ref_param_controls)); - snd_soc_add_platform_controls(platform, channel_mixer_controls, + snd_soc_add_component_controls(component, channel_mixer_controls, ARRAY_SIZE(channel_mixer_controls)); - msm_qti_pp_add_controls(platform); + msm_qti_pp_add_controls(component); - msm_dts_srs_tm_add_controls(platform); + msm_dts_srs_tm_add_controls(component); - msm_dolby_dap_add_controls(platform); + msm_dolby_dap_add_controls(component); - snd_soc_add_platform_controls(platform, + snd_soc_add_component_controls(component, use_ds1_or_ds2_controls, ARRAY_SIZE(use_ds1_or_ds2_controls)); - snd_soc_add_platform_controls(platform, + snd_soc_add_component_controls(component, device_pp_params_mixer_controls, ARRAY_SIZE(device_pp_params_mixer_controls)); - snd_soc_add_platform_controls(platform, + snd_soc_add_component_controls(component, msm_routing_be_dai_name_table_mixer_controls, ARRAY_SIZE(msm_routing_be_dai_name_table_mixer_controls)); - snd_soc_add_platform_controls(platform, msm_source_tracking_controls, + snd_soc_add_component_controls(component, msm_source_tracking_controls, ARRAY_SIZE(msm_source_tracking_controls)); - snd_soc_add_platform_controls(platform, adm_channel_config_controls, + snd_soc_add_component_controls(component, adm_channel_config_controls, ARRAY_SIZE(adm_channel_config_controls)); - snd_soc_add_platform_controls(platform, aptx_dec_license_controls, + snd_soc_add_component_controls(component, aptx_dec_license_controls, ARRAY_SIZE(aptx_dec_license_controls)); - snd_soc_add_platform_controls(platform, stereo_channel_reverse_control, + snd_soc_add_component_controls(component, + stereo_channel_reverse_control, ARRAY_SIZE(stereo_channel_reverse_control)); - snd_soc_add_platform_controls( - platform, msm_routing_feature_support_mixer_controls, + snd_soc_add_component_controls( + component, msm_routing_feature_support_mixer_controls, ARRAY_SIZE(msm_routing_feature_support_mixer_controls)); return 0; @@ -23672,7 +23675,8 @@ void msm_routing_pcm_free(struct snd_pcm *pcm) msm_pcm_routing_hwdep_free(pcm); } -static struct snd_soc_platform_driver msm_soc_routing_platform = { +static struct snd_soc_component_driver msm_soc_routing_component = { + .name = DRV_NAME, .ops = &msm_routing_pcm_ops, .probe = msm_routing_probe, .pcm_new = msm_routing_pcm_new, @@ -23683,13 +23687,14 @@ static int msm_routing_pcm_probe(struct platform_device *pdev) { dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev)); - return snd_soc_register_platform(&pdev->dev, - &msm_soc_routing_platform); + return snd_soc_register_component(&pdev->dev, + &msm_soc_routing_component, + NULL, 0); } static int msm_routing_pcm_remove(struct platform_device *pdev) { - snd_soc_unregister_platform(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } diff --git a/asoc/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c index 5a7ee0ad67d3..3fd83391331b 100644 --- a/asoc/msm-pcm-voice-v2.c +++ b/asoc/msm-pcm-voice-v2.c @@ -22,6 +22,8 @@ #include "msm-pcm-voice-v2.h" +#define DRV_NAME "msm-pcm-voice-v2" + static struct msm_voice voice_info[VOICE_SESSION_INDEX_MAX]; static struct snd_pcm_hardware msm_pcm_hardware = { @@ -697,15 +699,16 @@ static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) return ret; } -static int msm_pcm_voice_probe(struct snd_soc_platform *platform) +static int msm_pcm_voice_probe(struct snd_soc_component *component) { - snd_soc_add_platform_controls(platform, msm_voice_controls, + snd_soc_add_component_controls(component, msm_voice_controls, ARRAY_SIZE(msm_voice_controls)); return 0; } -static struct snd_soc_platform_driver msm_soc_platform = { +static struct snd_soc_component_driver msm_soc_component = { + .name = DRV_NAME, .ops = &msm_pcm_ops, .pcm_new = msm_asoc_pcm_new, .probe = msm_pcm_voice_probe, @@ -742,8 +745,9 @@ static int msm_pcm_probe(struct platform_device *pdev) is_destroy_cvd); voc_set_destroy_cvd_flag(destroy_cvd); - rc = snd_soc_register_platform(&pdev->dev, - &msm_soc_platform); + rc = snd_soc_register_component(&pdev->dev, + &msm_soc_component, + NULL, 0); done: return rc; @@ -751,7 +755,7 @@ static int msm_pcm_probe(struct platform_device *pdev) static int msm_pcm_remove(struct platform_device *pdev) { - snd_soc_unregister_platform(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } diff --git a/asoc/msm-pcm-voip-v2.c b/asoc/msm-pcm-voip-v2.c index ba0e7984ac32..ac12b90c8371 100644 --- a/asoc/msm-pcm-voip-v2.c +++ b/asoc/msm-pcm-voip-v2.c @@ -23,6 +23,8 @@ #include "msm-pcm-q6-v2.h" #include "msm-pcm-routing-v2.h" +#define DRV_NAME "msm-pcm-voip-v2" + #define SHARED_MEM_BUF 2 #define VOIP_MAX_Q_LEN 10 #define VOIP_MAX_VOC_PKT_SIZE 4096 @@ -300,9 +302,9 @@ static struct snd_kcontrol_new msm_voip_controls[] = { msm_voip_dtx_mode_get, msm_voip_dtx_mode_put), }; -static int msm_pcm_voip_probe(struct snd_soc_platform *platform) +static int msm_pcm_voip_probe(struct snd_soc_component *component) { - snd_soc_add_platform_controls(platform, msm_voip_controls, + snd_soc_add_component_controls(component, msm_voip_controls, ARRAY_SIZE(msm_voip_controls)); return 0; @@ -1605,7 +1607,8 @@ static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) return ret; } -static struct snd_soc_platform_driver msm_soc_platform = { +static struct snd_soc_component_driver msm_soc_component = { + .name = DRV_NAME, .ops = &msm_pcm_ops, .pcm_new = msm_asoc_pcm_new, .probe = msm_pcm_voip_probe, @@ -1642,8 +1645,9 @@ static int msm_pcm_probe(struct platform_device *pdev) pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev)); - rc = snd_soc_register_platform(&pdev->dev, - &msm_soc_platform); + rc = snd_soc_register_component(&pdev->dev, + &msm_soc_component, + NULL, 0); done: return rc; @@ -1651,7 +1655,7 @@ static int msm_pcm_probe(struct platform_device *pdev) static int msm_pcm_remove(struct platform_device *pdev) { - snd_soc_unregister_platform(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index 1a2c7aa15b15..e5d1ba2048d8 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -1561,63 +1561,68 @@ static const struct snd_kcontrol_new asphere_mixer_controls[] = { }; #ifdef CONFIG_QTI_PP -void msm_qti_pp_add_controls(struct snd_soc_platform *platform) +void msm_qti_pp_add_controls(struct snd_soc_component *component) { - snd_soc_add_platform_controls(platform, int_fm_vol_mixer_controls, + snd_soc_add_component_controls(component, int_fm_vol_mixer_controls, ARRAY_SIZE(int_fm_vol_mixer_controls)); - snd_soc_add_platform_controls(platform, pri_mi2s_lb_vol_mixer_controls, + snd_soc_add_component_controls(component, + pri_mi2s_lb_vol_mixer_controls, ARRAY_SIZE(pri_mi2s_lb_vol_mixer_controls)); - snd_soc_add_platform_controls(platform, sec_mi2s_lb_vol_mixer_controls, + snd_soc_add_component_controls(component, + sec_mi2s_lb_vol_mixer_controls, ARRAY_SIZE(sec_mi2s_lb_vol_mixer_controls)); - snd_soc_add_platform_controls(platform, tert_mi2s_lb_vol_mixer_controls, + snd_soc_add_component_controls(component, + tert_mi2s_lb_vol_mixer_controls, ARRAY_SIZE(tert_mi2s_lb_vol_mixer_controls)); - snd_soc_add_platform_controls(platform, slimbus_7_lb_vol_mixer_controls, + snd_soc_add_component_controls(component, + slimbus_7_lb_vol_mixer_controls, ARRAY_SIZE(slimbus_7_lb_vol_mixer_controls)); - snd_soc_add_platform_controls(platform, slimbus_8_lb_vol_mixer_controls, + snd_soc_add_component_controls(component, + slimbus_8_lb_vol_mixer_controls, ARRAY_SIZE(slimbus_8_lb_vol_mixer_controls)); - snd_soc_add_platform_controls(platform, int_hfp_vol_mixer_controls, + snd_soc_add_component_controls(component, int_hfp_vol_mixer_controls, ARRAY_SIZE(int_hfp_vol_mixer_controls)); - snd_soc_add_platform_controls(platform, int_icc_vol_mixer_controls, + snd_soc_add_component_controls(component, int_icc_vol_mixer_controls, ARRAY_SIZE(int_icc_vol_mixer_controls)); - snd_soc_add_platform_controls(platform, + snd_soc_add_component_controls(component, pri_auxpcm_lb_vol_mixer_controls, ARRAY_SIZE(pri_auxpcm_lb_vol_mixer_controls)); - snd_soc_add_platform_controls(platform, + snd_soc_add_component_controls(component, sec_auxpcm_lb_vol_mixer_controls, ARRAY_SIZE(sec_auxpcm_lb_vol_mixer_controls)); - snd_soc_add_platform_controls(platform, + snd_soc_add_component_controls(component, multi_ch_channel_map_mixer_controls, ARRAY_SIZE(multi_ch_channel_map_mixer_controls)); - snd_soc_add_platform_controls(platform, get_rms_controls, + snd_soc_add_component_controls(component, get_rms_controls, ARRAY_SIZE(get_rms_controls)); - snd_soc_add_platform_controls(platform, eq_enable_mixer_controls, + snd_soc_add_component_controls(component, eq_enable_mixer_controls, ARRAY_SIZE(eq_enable_mixer_controls)); - snd_soc_add_platform_controls(platform, eq_band_mixer_controls, + snd_soc_add_component_controls(component, eq_band_mixer_controls, ARRAY_SIZE(eq_band_mixer_controls)); - snd_soc_add_platform_controls(platform, eq_coeff_mixer_controls, + snd_soc_add_component_controls(component, eq_coeff_mixer_controls, ARRAY_SIZE(eq_coeff_mixer_controls)); - snd_soc_add_platform_controls(platform, asphere_mixer_controls, + snd_soc_add_component_controls(component, asphere_mixer_controls, ARRAY_SIZE(asphere_mixer_controls)); - snd_soc_add_platform_controls(platform, msm_multichannel_ec_controls, + snd_soc_add_component_controls(component, msm_multichannel_ec_controls, ARRAY_SIZE(msm_multichannel_ec_controls)); - snd_soc_add_platform_controls(platform, dsp_bit_width_controls, + snd_soc_add_component_controls(component, dsp_bit_width_controls, ARRAY_SIZE(dsp_bit_width_controls)); } #endif /* CONFIG_QTI_PP */ diff --git a/asoc/msm-qti-pp-config.h b/asoc/msm-qti-pp-config.h index ddb80831f843..8d103375c45e 100644 --- a/asoc/msm-qti-pp-config.h +++ b/asoc/msm-qti-pp-config.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ #ifndef _MSM_QTI_PP_H_ @@ -26,7 +26,7 @@ int msm_qti_pp_send_stereo_to_custom_stereo_cmd(int port_id, int copp_idx, uint16_t op_FL_ip_FR_weight, uint16_t op_FR_ip_FL_weight, uint16_t op_FR_ip_FR_weight); -void msm_qti_pp_add_controls(struct snd_soc_platform *platform); +void msm_qti_pp_add_controls(struct snd_soc_component *component); int msm_qti_pp_send_chmix_cfg_cmd(int port_id, int copp_idx, unsigned int session_id, int ip_channel_count, int out_channel_cnt, int *ch_wght_coeff, diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index ed461820b809..12863a28102c 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -33,6 +33,8 @@ #include "msm-pcm-routing-v2.h" #include "msm-qti-pp-config.h" +#define DRV_NAME "msm-transcode-loopback-v2" + #define LOOPBACK_SESSION_MAX_NUM_STREAMS 2 /* Max volume corresponding to 24dB */ #define TRANSCODE_LR_VOL_MAX_DB 0xFFFF @@ -199,6 +201,7 @@ static int msm_transcode_loopback_open(struct snd_compr_stream *cstream) struct snd_soc_pcm_runtime *rtd; struct msm_transcode_loopback *trans = &transcode_info; struct trans_loopback_pdata *pdata; + struct snd_soc_component *component; if (cstream == NULL) { pr_err("%s: Invalid substream\n", __func__); @@ -206,7 +209,13 @@ static int msm_transcode_loopback_open(struct snd_compr_stream *cstream) } runtime = cstream->runtime; rtd = snd_pcm_substream_chip(cstream); - pdata = snd_soc_platform_get_drvdata(rtd->platform); + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + pdata = snd_soc_component_get_drvdata(component); pdata->cstream[rtd->dai_link->id] = cstream; pdata->audio_effects[rtd->dai_link->id] = kzalloc(sizeof(struct msm_transcode_audio_effects), GFP_KERNEL); @@ -299,10 +308,17 @@ static int msm_transcode_loopback_free(struct snd_compr_stream *cstream) struct snd_compr_runtime *runtime = cstream->runtime; struct msm_transcode_loopback *trans = runtime->private_data; struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(cstream); + struct snd_soc_component *component; struct trans_loopback_pdata *pdata; int ret = 0; - pdata = snd_soc_platform_get_drvdata(rtd->platform); + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + pdata = snd_soc_component_get_drvdata(component); mutex_lock(&trans->lock); @@ -404,6 +420,7 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, struct snd_soc_pcm_runtime *soc_pcm_rx; struct snd_soc_pcm_runtime *soc_pcm_tx; struct snd_soc_pcm_runtime *rtd; + struct snd_soc_component *component; struct trans_loopback_pdata *pdata; uint32_t bit_width = 16; int ret = 0; @@ -416,7 +433,8 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, mutex_lock(&trans->lock); rtd = snd_pcm_substream_chip(cstream); - pdata = snd_soc_platform_get_drvdata(rtd->platform); + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + pdata = snd_soc_component_get_drvdata(component); if (cstream->direction == SND_COMPRESS_PLAYBACK) { if (codec_param->codec.id == SND_AUDIOCODEC_PCM) { @@ -570,6 +588,7 @@ static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream, struct snd_soc_pcm_runtime *rtd; struct trans_loopback_pdata *pdata; struct msm_transcode_loopback *prtd = NULL; + struct snd_soc_component *component; struct audio_client *ac = NULL; if (!metadata || !cstream) { @@ -578,7 +597,8 @@ static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream, } rtd = snd_pcm_substream_chip(cstream); - pdata = snd_soc_platform_get_drvdata(rtd->platform); + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + pdata = snd_soc_component_get_drvdata(component); prtd = cstream->runtime->private_data; @@ -870,7 +890,7 @@ static int msm_transcode_set_volume(struct snd_compr_stream *cstream, rtd = cstream->private_data; prtd = cstream->runtime->private_data; - if (!rtd || !rtd->platform || !prtd || !prtd->audio_client) { + if (!rtd || !prtd || !prtd->audio_client) { pr_err("%s: invalid rtd, prtd or audio client", __func__); return -EINVAL; } @@ -1065,6 +1085,7 @@ static int msm_transcode_audio_effects_config_put(struct snd_kcontrol *kcontrol, static int msm_transcode_add_audio_effects_control(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = "Audio Effects Config"; const char *deviceNo = "NN"; char *mixer_str = NULL; @@ -1088,6 +1109,12 @@ static int msm_transcode_add_audio_effects_control(struct snd_soc_pcm_runtime *r goto done; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n", __func__, rtd->dai_link->name, rtd->dai_link->id, rtd->dai_link->cpu_dai_name, rtd->pcm->device); @@ -1104,7 +1131,7 @@ static int msm_transcode_add_audio_effects_control(struct snd_soc_pcm_runtime *r fe_audio_effects_config_control[0].name = mixer_str; fe_audio_effects_config_control[0].private_value = rtd->dai_link->id; - ret = snd_soc_add_platform_controls(rtd->platform, + ret = snd_soc_add_component_controls(component, fe_audio_effects_config_control, ARRAY_SIZE(fe_audio_effects_config_control)); if (ret < 0) @@ -1118,6 +1145,7 @@ static int msm_transcode_add_audio_effects_control(struct snd_soc_pcm_runtime *r static int msm_transcode_stream_cmd_control( struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = DSP_STREAM_CMD; const char *deviceNo = "NN"; char *mixer_str = NULL; @@ -1139,6 +1167,12 @@ static int msm_transcode_stream_cmd_control( goto done; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; mixer_str = kzalloc(ctl_len, GFP_KERNEL); if (!mixer_str) { @@ -1151,7 +1185,7 @@ static int msm_transcode_stream_cmd_control( fe_loopback_stream_cmd_config_control[0].private_value = rtd->dai_link->id; pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); - ret = snd_soc_add_platform_controls(rtd->platform, + ret = snd_soc_add_component_controls(component, fe_loopback_stream_cmd_config_control, ARRAY_SIZE(fe_loopback_stream_cmd_config_control)); if (ret < 0) @@ -1166,6 +1200,7 @@ static int msm_transcode_stream_cmd_control( static int msm_transcode_stream_callback_control( struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = DSP_STREAM_CALLBACK; const char *deviceNo = "NN"; char *mixer_str = NULL; @@ -1189,6 +1224,12 @@ static int msm_transcode_stream_callback_control( goto done; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; mixer_str = kzalloc(ctl_len, GFP_KERNEL); if (!mixer_str) { @@ -1201,7 +1242,7 @@ static int msm_transcode_stream_callback_control( fe_loopback_callback_config_control[0].private_value = rtd->dai_link->id; pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); - ret = snd_soc_add_platform_controls(rtd->platform, + ret = snd_soc_add_component_controls(component, fe_loopback_callback_config_control, ARRAY_SIZE(fe_loopback_callback_config_control)); if (ret < 0) { @@ -1227,6 +1268,7 @@ static int msm_transcode_stream_callback_control( static int msm_transcode_add_ion_fd_cmd_control(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = "Playback ION FD"; const char *deviceNo = "NN"; char *mixer_str = NULL; @@ -1248,6 +1290,12 @@ static int msm_transcode_add_ion_fd_cmd_control(struct snd_soc_pcm_runtime *rtd) goto done; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; mixer_str = kzalloc(ctl_len, GFP_KERNEL); if (!mixer_str) { @@ -1259,7 +1307,7 @@ static int msm_transcode_add_ion_fd_cmd_control(struct snd_soc_pcm_runtime *rtd) fe_ion_fd_config_control[0].name = mixer_str; fe_ion_fd_config_control[0].private_value = rtd->dai_link->id; pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); - ret = snd_soc_add_platform_controls(rtd->platform, + ret = snd_soc_add_component_controls(component, fe_ion_fd_config_control, ARRAY_SIZE(fe_ion_fd_config_control)); if (ret < 0) @@ -1273,6 +1321,7 @@ static int msm_transcode_add_ion_fd_cmd_control(struct snd_soc_pcm_runtime *rtd) static int msm_transcode_add_event_ack_cmd_control( struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; const char *mixer_ctl_name = "Playback Event Ack"; const char *deviceNo = "NN"; char *mixer_str = NULL; @@ -1294,6 +1343,12 @@ static int msm_transcode_add_event_ack_cmd_control( goto done; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1; mixer_str = kzalloc(ctl_len, GFP_KERNEL); if (!mixer_str) { @@ -1305,7 +1360,7 @@ static int msm_transcode_add_event_ack_cmd_control( fe_event_ack_config_control[0].name = mixer_str; fe_event_ack_config_control[0].private_value = rtd->dai_link->id; pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str); - ret = snd_soc_add_platform_controls(rtd->platform, + ret = snd_soc_add_component_controls(component, fe_event_ack_config_control, ARRAY_SIZE(fe_event_ack_config_control)); if (ret < 0) @@ -1329,6 +1384,7 @@ static int msm_transcode_app_type_cfg_info(struct snd_kcontrol *kcontrol, static int msm_transcode_add_app_type_cfg_control( struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; char mixer_str[32]; struct snd_kcontrol_new fe_app_type_cfg_control[1] = { { @@ -1346,6 +1402,12 @@ static int msm_transcode_add_app_type_cfg_control( return -EINVAL; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + if (rtd->compr->direction == SND_COMPRESS_PLAYBACK) { snprintf(mixer_str, sizeof(mixer_str), "Audio Stream %d App Type Cfg", @@ -1360,7 +1422,7 @@ static int msm_transcode_add_app_type_cfg_control( msm_transcode_playback_app_type_cfg_get; pr_debug("Registering new mixer ctl %s", mixer_str); - snd_soc_add_platform_controls(rtd->platform, + snd_soc_add_component_controls(component, fe_app_type_cfg_control, ARRAY_SIZE(fe_app_type_cfg_control)); } @@ -1379,6 +1441,7 @@ static int msm_transcode_volume_info(struct snd_kcontrol *kcontrol, static int msm_transcode_add_volume_control(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = NULL; struct snd_kcontrol_new fe_volume_control[1] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -1396,11 +1459,18 @@ static int msm_transcode_add_volume_control(struct snd_soc_pcm_runtime *rtd) pr_err("%s NULL rtd\n", __func__); return -EINVAL; } + + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + if (rtd->compr->direction == SND_COMPRESS_PLAYBACK) { fe_volume_control[0].private_value = rtd->dai_link->id; pr_debug("Registering new mixer ctl %s", fe_volume_control[0].name); - snd_soc_add_platform_controls(rtd->platform, fe_volume_control, + snd_soc_add_component_controls(component, fe_volume_control, ARRAY_SIZE(fe_volume_control)); } return 0; @@ -1457,7 +1527,7 @@ static struct snd_compr_ops msm_transcode_loopback_ops = { }; -static int msm_transcode_loopback_probe(struct snd_soc_platform *platform) +static int msm_transcode_loopback_probe(struct snd_soc_component *component) { struct trans_loopback_pdata *pdata = NULL; int i; @@ -1473,21 +1543,22 @@ static int msm_transcode_loopback_probe(struct snd_soc_platform *platform) for (i = 0; i < MSM_FRONTEND_DAI_MAX; i++) pdata->audio_effects[i] = NULL; - snd_soc_platform_set_drvdata(platform, pdata); + snd_soc_component_set_drvdata(component, pdata); return 0; } -static int msm_transcode_loopback_remove(struct snd_soc_platform *platform) +static void msm_transcode_loopback_remove(struct snd_soc_component *component) { struct trans_loopback_pdata *pdata = NULL; pdata = (struct trans_loopback_pdata *) - snd_soc_platform_get_drvdata(platform); + snd_soc_component_get_drvdata(component); kfree(pdata); - return 0; + return; } -static struct snd_soc_platform_driver msm_soc_platform = { +static struct snd_soc_component_driver msm_soc_component = { + .name = DRV_NAME, .probe = msm_transcode_loopback_probe, .compr_ops = &msm_transcode_loopback_ops, .pcm_new = msm_transcode_loopback_new, @@ -1501,13 +1572,14 @@ static int msm_transcode_dev_probe(struct platform_device *pdev) if (pdev->dev.of_node) dev_set_name(&pdev->dev, "%s", "msm-transcode-loopback"); - return snd_soc_register_platform(&pdev->dev, - &msm_soc_platform); + return snd_soc_register_component(&pdev->dev, + &msm_soc_component, + NULL, 0); } static int msm_transcode_remove(struct platform_device *pdev) { - snd_soc_unregister_platform(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } diff --git a/dsp/msm-dts-srs-tm-config.c b/dsp/msm-dts-srs-tm-config.c index d021e58f85b0..81bb7941bd97 100644 --- a/dsp/msm-dts-srs-tm-config.c +++ b/dsp/msm-dts-srs-tm-config.c @@ -264,23 +264,23 @@ static const struct snd_kcontrol_new lpa_srs_trumedia_controls_mi2s[] = { * msm_dts_srs_tm_add_controls - * Add DTS SRS module controls * - * @platform: component to which controls can be registered + * @component: component to which controls can be registered * */ -void msm_dts_srs_tm_add_controls(struct snd_soc_platform *platform) +void msm_dts_srs_tm_add_controls(struct snd_soc_component *component) { - snd_soc_add_platform_controls(platform, + snd_soc_add_component_controls(component, lpa_srs_trumedia_controls, ARRAY_SIZE(lpa_srs_trumedia_controls)); - snd_soc_add_platform_controls(platform, + snd_soc_add_component_controls(component, lpa_srs_trumedia_controls_hdmi, ARRAY_SIZE(lpa_srs_trumedia_controls_hdmi)); - snd_soc_add_platform_controls(platform, + snd_soc_add_component_controls(component, lpa_srs_trumedia_controls_i2s, ARRAY_SIZE(lpa_srs_trumedia_controls_i2s)); - snd_soc_add_platform_controls(platform, + snd_soc_add_component_controls(component, lpa_srs_trumedia_controls_mi2s, ARRAY_SIZE(lpa_srs_trumedia_controls_mi2s)); } diff --git a/include/dsp/msm-dts-srs-tm-config.h b/include/dsp/msm-dts-srs-tm-config.h index 7eeb4222bb91..36d25be0f03b 100644 --- a/include/dsp/msm-dts-srs-tm-config.h +++ b/include/dsp/msm-dts-srs-tm-config.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2012-2014, 2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014, 2017-2018, The Linux Foundation. All rights reserved. */ #ifndef _MSM_DTS_SRS_TM_CONFIG_H_ @@ -21,13 +21,13 @@ union srs_trumedia_params_u { void msm_dts_srs_tm_ion_memmap(struct param_outband *po_); void msm_dts_srs_tm_init(int port_id, int copp_idx); void msm_dts_srs_tm_deinit(int port_id); -void msm_dts_srs_tm_add_controls(struct snd_soc_platform *platform); +void msm_dts_srs_tm_add_controls(struct snd_soc_component *component); #else static inline void msm_dts_srs_tm_ion_memmap(struct param_outband *po_) { } static inline void msm_dts_srs_tm_init(int port_id, int copp_idx) { } static inline void msm_dts_srs_tm_deinit(int port_id) { } static inline void msm_dts_srs_tm_add_controls( - struct snd_soc_platform *platform) { } + struct snd_soc_component *component) { } #endif -- GitLab From 15c825d077fe7c1cb3eead4db07685130b9df63e Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 6 Sep 2018 10:49:18 +0800 Subject: [PATCH 0680/1645] ASoC: codec: Update codec driver to component driver Some alsa API are removed in kernel-4.19 which would cause codec driver compile failure. Update codec driver to fix it. Change-Id: Ie358ec1863082166958059c179300b453d2a03ad Signed-off-by: Meng Wang --- asoc/codecs/aqt1000/aqt1000-api.h | 9 +- asoc/codecs/aqt1000/aqt1000-clsh.c | 388 +-- asoc/codecs/aqt1000/aqt1000-clsh.h | 6 +- asoc/codecs/aqt1000/aqt1000-irq.c | 4 +- asoc/codecs/aqt1000/aqt1000-mbhc.c | 370 +-- asoc/codecs/aqt1000/aqt1000-mbhc.h | 20 +- asoc/codecs/aqt1000/aqt1000.c | 1243 +++++---- asoc/codecs/aqt1000/aqt1000.h | 2 +- asoc/codecs/audio-ext-clk-up.c | 1 + asoc/codecs/bolero/bolero-cdc.c | 90 +- asoc/codecs/bolero/bolero-cdc.h | 16 +- asoc/codecs/bolero/internal.h | 2 +- asoc/codecs/bolero/rx-macro.c | 752 ++--- asoc/codecs/bolero/tx-macro.c | 209 +- asoc/codecs/bolero/va-macro.c | 170 +- asoc/codecs/bolero/wsa-macro.c | 649 +++-- asoc/codecs/bolero/wsa-macro.h | 13 +- asoc/codecs/cpe_core.h | 30 +- asoc/codecs/csra66x0/csra66x0.c | 295 +- asoc/codecs/ep92/ep92.c | 152 +- asoc/codecs/msm_hdmi_codec_rx.c | 126 +- asoc/codecs/msm_stub.c | 12 +- asoc/codecs/wcd-clsh.c | 318 ++- asoc/codecs/wcd-clsh.h | 4 +- asoc/codecs/wcd-irq.c | 4 +- asoc/codecs/wcd-mbhc-adc.c | 54 +- asoc/codecs/wcd-mbhc-legacy.c | 71 +- asoc/codecs/wcd-mbhc-v2-api.h | 6 +- asoc/codecs/wcd-mbhc-v2.c | 227 +- asoc/codecs/wcd-mbhc-v2.h | 101 +- asoc/codecs/wcd9335.c | 3568 +++++++++++++----------- asoc/codecs/wcd9335.h | 75 +- asoc/codecs/wcd934x/wcd934x-dsd.c | 363 ++- asoc/codecs/wcd934x/wcd934x-dsd.h | 8 +- asoc/codecs/wcd934x/wcd934x-dsp-cntl.c | 422 +-- asoc/codecs/wcd934x/wcd934x-dsp-cntl.h | 8 +- asoc/codecs/wcd934x/wcd934x-mbhc.c | 385 +-- asoc/codecs/wcd934x/wcd934x-mbhc.h | 23 +- asoc/codecs/wcd934x/wcd934x.c | 2698 ++++++++++-------- asoc/codecs/wcd934x/wcd934x.h | 52 +- asoc/codecs/wcd937x/internal.h | 11 +- asoc/codecs/wcd937x/wcd937x-mbhc.c | 352 +-- asoc/codecs/wcd937x/wcd937x-mbhc.h | 21 +- asoc/codecs/wcd937x/wcd937x.c | 763 ++--- asoc/codecs/wcd937x/wcd937x.h | 4 +- asoc/codecs/wcd9xxx-common-v2.c | 619 ++-- asoc/codecs/wcd9xxx-common-v2.h | 8 +- asoc/codecs/wcd9xxx-regmap.h | 2 +- asoc/codecs/wcd9xxx-resmgr-v2.c | 27 +- asoc/codecs/wcd9xxx-resmgr-v2.h | 10 +- asoc/codecs/wcd9xxx-utils.h | 10 +- asoc/codecs/wcd_cpe_core.c | 117 +- asoc/codecs/wcd_cpe_core.h | 28 +- asoc/codecs/wcdcal-hwdep.c | 20 +- asoc/codecs/wcdcal-hwdep.h | 5 +- asoc/codecs/wsa881x-temp-sensor.c | 8 +- asoc/codecs/wsa881x-temp-sensor.h | 4 +- asoc/codecs/wsa881x.c | 499 ++-- asoc/codecs/wsa881x.h | 14 +- 59 files changed, 8542 insertions(+), 6926 deletions(-) diff --git a/asoc/codecs/aqt1000/aqt1000-api.h b/asoc/codecs/aqt1000/aqt1000-api.h index 629e9d67bfc8..fc5d23a57e7c 100644 --- a/asoc/codecs/aqt1000/aqt1000-api.h +++ b/asoc/codecs/aqt1000/aqt1000-api.h @@ -10,11 +10,12 @@ #include #include -extern int aqt_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, +extern int aqt_mbhc_micb_adjust_voltage(struct snd_soc_component *component, int volt, int micb_num); -extern int aqt_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable); +extern int aqt_cdc_mclk_enable(struct snd_soc_component *component, + bool enable); extern int aqt_get_micb_vout_ctl_val(u32 micb_mv); -extern int aqt_micbias_control(struct snd_soc_codec *codec, int micb_num, - int req, bool is_dapm); +extern int aqt_micbias_control(struct snd_soc_component *component, + int micb_num, int req, bool is_dapm); #endif /* AQT1000_API_H */ diff --git a/asoc/codecs/aqt1000/aqt1000-clsh.c b/asoc/codecs/aqt1000/aqt1000-clsh.c index b8f403a4e81d..218425b5256a 100644 --- a/asoc/codecs/aqt1000/aqt1000-clsh.c +++ b/asoc/codecs/aqt1000/aqt1000-clsh.c @@ -136,7 +136,7 @@ static const struct aqt_imped_val imped_index[] = { {13, 9}, }; -static void (*clsh_state_fp[NUM_CLSH_STATES])(struct snd_soc_codec *, +static void (*clsh_state_fp[NUM_CLSH_STATES])(struct snd_soc_component *, struct aqt_clsh_cdc_data *, u8 req_state, bool en, int mode); @@ -169,12 +169,13 @@ static int get_impedance_index(int imped) /* * Function: aqt_clsh_imped_config - * Params: codec, imped, reset + * Params: component, imped, reset * Description: * This function updates HPHL and HPHR gain settings * according to the impedance value. */ -void aqt_clsh_imped_config(struct snd_soc_codec *codec, int imped, bool reset) +void aqt_clsh_imped_config(struct snd_soc_component *component, + int imped, bool reset) { int i; int index = 0; @@ -189,7 +190,7 @@ void aqt_clsh_imped_config(struct snd_soc_codec *codec, int imped, bool reset) /* reset = 1, which means request is to reset the register values */ if (reset) { for (i = 0; i < MAX_IMPED_PARAMS; i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, imped_table_ptr[index][i].reg, imped_table_ptr[index][i].mask, 0); return; @@ -205,7 +206,7 @@ void aqt_clsh_imped_config(struct snd_soc_codec *codec, int imped, bool reset) return; } for (i = 0; i < MAX_IMPED_PARAMS; i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, imped_table_ptr[index][i].reg, imped_table_ptr[index][i].mask, imped_table_ptr[index][i].val); @@ -242,22 +243,23 @@ static const char *const state_to_str[] = { }; static inline void -aqt_enable_clsh_block(struct snd_soc_codec *codec, +aqt_enable_clsh_block(struct snd_soc_component *component, struct aqt_clsh_cdc_data *clsh_d, bool enable) { if ((enable && ++clsh_d->clsh_users == 1) || (!enable && --clsh_d->clsh_users == 0)) - snd_soc_update_bits(codec, AQT1000_CDC_CLSH_CRC, 0x01, - (u8) enable); + snd_soc_component_update_bits(component, AQT1000_CDC_CLSH_CRC, + 0x01, (u8) enable); if (clsh_d->clsh_users < 0) clsh_d->clsh_users = 0; - dev_dbg(codec->dev, "%s: clsh_users %d, enable %d", __func__, + dev_dbg(component->dev, "%s: clsh_users %d, enable %d", __func__, clsh_d->clsh_users, enable); } -static inline bool aqt_clsh_enable_status(struct snd_soc_codec *codec) +static inline bool aqt_clsh_enable_status(struct snd_soc_component *component) { - return snd_soc_read(codec, AQT1000_CDC_CLSH_CRC) & 0x01; + return snd_soc_component_read32( + component, AQT1000_CDC_CLSH_CRC) & 0x01; } static inline int aqt_clsh_get_int_mode(struct aqt_clsh_cdc_data *clsh_d, @@ -284,87 +286,106 @@ static inline void aqt_clsh_set_int_mode(struct aqt_clsh_cdc_data *clsh_d, clsh_d->interpolator_modes[ffs(clsh_state)] = mode; } -static inline void aqt_clsh_set_buck_mode(struct snd_soc_codec *codec, +static inline void aqt_clsh_set_buck_mode(struct snd_soc_component *component, int mode) { if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || mode == CLS_AB_HIFI || mode == CLS_AB) - snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, - 0x08, 0x08); /* set to HIFI */ + snd_soc_component_update_bits(component, + AQT1000_ANA_RX_SUPPLIES, + 0x08, 0x08); /* set to HIFI */ else - snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, - 0x08, 0x00); /* set to default */ + snd_soc_component_update_bits(component, + AQT1000_ANA_RX_SUPPLIES, + 0x08, 0x00); /* set to default */ } -static inline void aqt_clsh_set_flyback_mode(struct snd_soc_codec *codec, - int mode) +static inline void aqt_clsh_set_flyback_mode( + struct snd_soc_component *component, int mode) { if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || mode == CLS_AB_HIFI || mode == CLS_AB) - snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, - 0x04, 0x04); /* set to HIFI */ + snd_soc_component_update_bits(component, + AQT1000_ANA_RX_SUPPLIES, + 0x04, 0x04); /* set to HIFI */ else - snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, - 0x04, 0x00); /* set to Default */ + snd_soc_component_update_bits(component, + AQT1000_ANA_RX_SUPPLIES, + 0x04, 0x00); /* set to Default */ } -static inline void aqt_clsh_gm3_boost_disable(struct snd_soc_codec *codec, - int mode) +static inline void aqt_clsh_gm3_boost_disable( + struct snd_soc_component *component, int mode) { if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || mode == CLS_AB_HIFI || mode == CLS_AB) { - snd_soc_update_bits(codec, AQT1000_HPH_CNP_WG_CTL, - 0x80, 0x0); /* disable GM3 Boost */ - snd_soc_update_bits(codec, AQT1000_FLYBACK_VNEG_CTRL_4, - 0xF0, 0x80); + snd_soc_component_update_bits(component, + AQT1000_HPH_CNP_WG_CTL, + 0x80, 0x0); /* disable GM3 Boost */ + snd_soc_component_update_bits(component, + AQT1000_FLYBACK_VNEG_CTRL_4, + 0xF0, 0x80); } else { - snd_soc_update_bits(codec, AQT1000_HPH_CNP_WG_CTL, - 0x80, 0x80); /* set to Default */ - snd_soc_update_bits(codec, AQT1000_FLYBACK_VNEG_CTRL_4, - 0xF0, 0x70); + snd_soc_component_update_bits(component, + AQT1000_HPH_CNP_WG_CTL, + 0x80, 0x80); /* set to Default */ + snd_soc_component_update_bits(component, + AQT1000_FLYBACK_VNEG_CTRL_4, + 0xF0, 0x70); } } -static inline void aqt_clsh_flyback_dac_ctl(struct snd_soc_codec *codec, - int vref) +static inline void aqt_clsh_flyback_dac_ctl( + struct snd_soc_component *component, int vref) { - snd_soc_update_bits(codec, AQT1000_FLYBACK_VNEGDAC_CTRL_2, - 0xE0, (vref << 5)); + snd_soc_component_update_bits(component, + AQT1000_FLYBACK_VNEGDAC_CTRL_2, + 0xE0, (vref << 5)); } -static inline void aqt_clsh_mode_vref_ctl(struct snd_soc_codec *codec, - int vref_ctl) +static inline void aqt_clsh_mode_vref_ctl(struct snd_soc_component *component, + int vref_ctl) { if (vref_ctl == I2C) { - snd_soc_update_bits(codec, AQT1000_CLASSH_MODE_3, 0x02, 0x02); - snd_soc_update_bits(codec, AQT1000_CLASSH_MODE_2, 0xFF, 0x1C); + snd_soc_component_update_bits(component, AQT1000_CLASSH_MODE_3, + 0x02, 0x02); + snd_soc_component_update_bits(component, AQT1000_CLASSH_MODE_2, + 0xFF, 0x1C); } else { - snd_soc_update_bits(codec, AQT1000_CLASSH_MODE_2, 0xFF, 0x3A); - snd_soc_update_bits(codec, AQT1000_CLASSH_MODE_3, 0x02, 0x00); + snd_soc_component_update_bits(component, AQT1000_CLASSH_MODE_2, + 0xFF, 0x3A); + snd_soc_component_update_bits(component, AQT1000_CLASSH_MODE_3, + 0x02, 0x00); } } -static inline void aqt_clsh_buck_current_bias_ctl(struct snd_soc_codec *codec, - bool enable) +static inline void aqt_clsh_buck_current_bias_ctl( + struct snd_soc_component *component, bool enable) { if (enable) { - snd_soc_update_bits(codec, AQT1000_BUCK_5V_IBIAS_CTL_4, - 0x70, (I_2UA << 4)); - snd_soc_update_bits(codec, AQT1000_BUCK_5V_IBIAS_CTL_4, - 0x07, I_0P25UA); - snd_soc_update_bits(codec, AQT1000_BUCK_5V_CTRL_CCL_2, - 0x3F, 0x3F); + snd_soc_component_update_bits(component, + AQT1000_BUCK_5V_IBIAS_CTL_4, + 0x70, (I_2UA << 4)); + snd_soc_component_update_bits(component, + AQT1000_BUCK_5V_IBIAS_CTL_4, + 0x07, I_0P25UA); + snd_soc_component_update_bits(component, + AQT1000_BUCK_5V_CTRL_CCL_2, + 0x3F, 0x3F); } else { - snd_soc_update_bits(codec, AQT1000_BUCK_5V_IBIAS_CTL_4, - 0x70, (I_1UA << 4)); - snd_soc_update_bits(codec, AQT1000_BUCK_5V_IBIAS_CTL_4, - 0x07, I_1UA); - snd_soc_update_bits(codec, AQT1000_BUCK_5V_CTRL_CCL_2, - 0x3F, 0x20); + snd_soc_component_update_bits(component, + AQT1000_BUCK_5V_IBIAS_CTL_4, + 0x70, (I_1UA << 4)); + snd_soc_component_update_bits(component, + AQT1000_BUCK_5V_IBIAS_CTL_4, + 0x07, I_1UA); + snd_soc_component_update_bits(component, + AQT1000_BUCK_5V_CTRL_CCL_2, + 0x3F, 0x20); } } -static inline void aqt_clsh_rdac_hd2_ctl(struct snd_soc_codec *codec, +static inline void aqt_clsh_rdac_hd2_ctl(struct snd_soc_component *component, u8 hd2_div_ctl, u8 state) { u16 reg = 0; @@ -374,34 +395,41 @@ static inline void aqt_clsh_rdac_hd2_ctl(struct snd_soc_codec *codec, else if (state == AQT_CLSH_STATE_HPHR) reg = AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_R; else - dev_err(codec->dev, "%s: Invalid state: %d\n", + dev_err(component->dev, "%s: Invalid state: %d\n", __func__, state); if (!reg) - snd_soc_update_bits(codec, reg, 0x0F, hd2_div_ctl); + snd_soc_component_update_bits(component, reg, + 0x0F, hd2_div_ctl); } -static inline void aqt_clsh_force_iq_ctl(struct snd_soc_codec *codec, +static inline void aqt_clsh_force_iq_ctl(struct snd_soc_component *component, int mode) { if (mode == CLS_H_LOHIFI || mode == CLS_AB) { - snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_PA_MISC2, - 0x20, 0x20); - snd_soc_update_bits(codec, AQT1000_RX_BIAS_HPH_LOWPOWER, - 0xF0, 0xC0); - snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL1, - 0x0E, 0x02); + snd_soc_component_update_bits(component, + AQT1000_HPH_NEW_INT_PA_MISC2, + 0x20, 0x20); + snd_soc_component_update_bits(component, + AQT1000_RX_BIAS_HPH_LOWPOWER, + 0xF0, 0xC0); + snd_soc_component_update_bits(component, + AQT1000_HPH_PA_CTL1, + 0x0E, 0x02); } else { - snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_PA_MISC2, - 0x20, 0x0); - snd_soc_update_bits(codec, AQT1000_RX_BIAS_HPH_LOWPOWER, - 0xF0, 0x80); - snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL1, - 0x0E, 0x06); + snd_soc_component_update_bits(component, + AQT1000_HPH_NEW_INT_PA_MISC2, + 0x20, 0x0); + snd_soc_component_update_bits(component, + AQT1000_RX_BIAS_HPH_LOWPOWER, + 0xF0, 0x80); + snd_soc_component_update_bits(component, + AQT1000_HPH_PA_CTL1, + 0x0E, 0x06); } } -static void aqt_clsh_buck_ctrl(struct snd_soc_codec *codec, +static void aqt_clsh_buck_ctrl(struct snd_soc_component *component, struct aqt_clsh_cdc_data *clsh_d, int mode, bool enable) @@ -409,9 +437,10 @@ static void aqt_clsh_buck_ctrl(struct snd_soc_codec *codec, /* enable/disable buck */ if ((enable && (++clsh_d->buck_users == 1)) || (!enable && (--clsh_d->buck_users == 0))) - snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, - (1 << 7), (enable << 7)); - dev_dbg(codec->dev, "%s: buck_users %d, enable %d, mode: %s", + snd_soc_component_update_bits(component, + AQT1000_ANA_RX_SUPPLIES, + (1 << 7), (enable << 7)); + dev_dbg(component->dev, "%s: buck_users %d, enable %d, mode: %s", __func__, clsh_d->buck_users, enable, mode_to_str(mode)); /* * 500us sleep is required after buck enable/disable @@ -420,7 +449,7 @@ static void aqt_clsh_buck_ctrl(struct snd_soc_codec *codec, usleep_range(500, 500 + AQT_USLEEP_RANGE); } -static void aqt_clsh_flyback_ctrl(struct snd_soc_codec *codec, +static void aqt_clsh_flyback_ctrl(struct snd_soc_component *component, struct aqt_clsh_cdc_data *clsh_d, int mode, bool enable) @@ -428,12 +457,13 @@ static void aqt_clsh_flyback_ctrl(struct snd_soc_codec *codec, /* enable/disable flyback */ if ((enable && (++clsh_d->flyback_users == 1)) || (!enable && (--clsh_d->flyback_users == 0))) { - snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, - (1 << 6), (enable << 6)); + snd_soc_component_update_bits(component, + AQT1000_ANA_RX_SUPPLIES, + (1 << 6), (enable << 6)); /* 100usec delay is needed as per HW requirement */ usleep_range(100, 110); } - dev_dbg(codec->dev, "%s: flyback_users %d, enable %d, mode: %s", + dev_dbg(component->dev, "%s: flyback_users %d, enable %d, mode: %s", __func__, clsh_d->flyback_users, enable, mode_to_str(mode)); /* * 500us sleep is required after flyback enable/disable @@ -442,7 +472,7 @@ static void aqt_clsh_flyback_ctrl(struct snd_soc_codec *codec, usleep_range(500, 500 + AQT_USLEEP_RANGE); } -static void aqt_clsh_set_hph_mode(struct snd_soc_codec *codec, +static void aqt_clsh_set_hph_mode(struct snd_soc_component *component, int mode) { u8 val = 0; @@ -487,21 +517,22 @@ static void aqt_clsh_set_hph_mode(struct snd_soc_codec *codec, if (mode == CLS_H_LOHIFI || mode == CLS_AB) val = 0x04; - snd_soc_update_bits(codec, AQT1000_ANA_HPH, 0x0C, val); + snd_soc_component_update_bits(component, AQT1000_ANA_HPH, 0x0C, val); } -static void aqt_clsh_set_buck_regulator_mode(struct snd_soc_codec *codec, - int mode) +static void aqt_clsh_set_buck_regulator_mode( + struct snd_soc_component *component, int mode) { - snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, + snd_soc_component_update_bits(component, AQT1000_ANA_RX_SUPPLIES, 0x02, 0x00); } -static void aqt_clsh_state_hph_st(struct snd_soc_codec *codec, +static void aqt_clsh_state_hph_st(struct snd_soc_component *component, struct aqt_clsh_cdc_data *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); if (mode == CLS_AB || mode == CLS_AB_HIFI) @@ -509,158 +540,163 @@ static void aqt_clsh_state_hph_st(struct snd_soc_codec *codec, if (is_enable) { if (req_state == AQT_CLSH_STATE_HPHL) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_RX1_RX_PATH_CFG0, 0x40, 0x40); if (req_state == AQT_CLSH_STATE_HPHR) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_RX2_RX_PATH_CFG0, 0x40, 0x40); } else { if (req_state == AQT_CLSH_STATE_HPHL) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_RX1_RX_PATH_CFG0, 0x40, 0x00); if (req_state == AQT_CLSH_STATE_HPHR) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_RX2_RX_PATH_CFG0, 0x40, 0x00); } } -static void aqt_clsh_state_hph_r(struct snd_soc_codec *codec, +static void aqt_clsh_state_hph_r(struct snd_soc_component *component, struct aqt_clsh_cdc_data *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); if (mode == CLS_H_NORMAL) { - dev_err(codec->dev, "%s: Normal mode not applicable for hph_r\n", + dev_err(component->dev, "%s: Normal mode not applicable for hph_r\n", __func__); return; } if (is_enable) { if (mode != CLS_AB && mode != CLS_AB_HIFI) { - aqt_enable_clsh_block(codec, clsh_d, true); + aqt_enable_clsh_block(component, clsh_d, true); /* * These K1 values depend on the Headphone Impedance * For now it is assumed to be 16 ohm */ - snd_soc_update_bits(codec, AQT1000_CDC_CLSH_K1_MSB, - 0x0F, 0x00); - snd_soc_update_bits(codec, AQT1000_CDC_CLSH_K1_LSB, - 0xFF, 0xC0); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, + AQT1000_CDC_CLSH_K1_MSB, + 0x0F, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CDC_CLSH_K1_LSB, + 0xFF, 0xC0); + snd_soc_component_update_bits(component, AQT1000_CDC_RX2_RX_PATH_CFG0, 0x40, 0x40); } - aqt_clsh_set_buck_regulator_mode(codec, mode); - aqt_clsh_set_flyback_mode(codec, mode); - aqt_clsh_gm3_boost_disable(codec, mode); - aqt_clsh_flyback_dac_ctl(codec, VREF_N0P9V); - aqt_clsh_mode_vref_ctl(codec, I2C); - aqt_clsh_force_iq_ctl(codec, mode); - aqt_clsh_rdac_hd2_ctl(codec, P82_0P77, req_state); - aqt_clsh_flyback_ctrl(codec, clsh_d, mode, true); - aqt_clsh_flyback_dac_ctl(codec, VREF_N1P827V); - aqt_clsh_set_buck_mode(codec, mode); - aqt_clsh_buck_ctrl(codec, clsh_d, mode, true); - aqt_clsh_mode_vref_ctl(codec, CONTROLLER); - aqt_clsh_buck_current_bias_ctl(codec, true); - aqt_clsh_set_hph_mode(codec, mode); + aqt_clsh_set_buck_regulator_mode(component, mode); + aqt_clsh_set_flyback_mode(component, mode); + aqt_clsh_gm3_boost_disable(component, mode); + aqt_clsh_flyback_dac_ctl(component, VREF_N0P9V); + aqt_clsh_mode_vref_ctl(component, I2C); + aqt_clsh_force_iq_ctl(component, mode); + aqt_clsh_rdac_hd2_ctl(component, P82_0P77, req_state); + aqt_clsh_flyback_ctrl(component, clsh_d, mode, true); + aqt_clsh_flyback_dac_ctl(component, VREF_N1P827V); + aqt_clsh_set_buck_mode(component, mode); + aqt_clsh_buck_ctrl(component, clsh_d, mode, true); + aqt_clsh_mode_vref_ctl(component, CONTROLLER); + aqt_clsh_buck_current_bias_ctl(component, true); + aqt_clsh_set_hph_mode(component, mode); } else { - aqt_clsh_set_hph_mode(codec, CLS_H_NORMAL); - aqt_clsh_buck_current_bias_ctl(codec, false); + aqt_clsh_set_hph_mode(component, CLS_H_NORMAL); + aqt_clsh_buck_current_bias_ctl(component, false); if (mode != CLS_AB && mode != CLS_AB_HIFI) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_RX2_RX_PATH_CFG0, 0x40, 0x00); - aqt_enable_clsh_block(codec, clsh_d, false); + aqt_enable_clsh_block(component, clsh_d, false); } /* buck and flyback set to default mode and disable */ - aqt_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false); - aqt_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false); - aqt_clsh_rdac_hd2_ctl(codec, P5_0P35, req_state); - aqt_clsh_force_iq_ctl(codec, CLS_H_NORMAL); - aqt_clsh_gm3_boost_disable(codec, CLS_H_NORMAL); - aqt_clsh_set_flyback_mode(codec, CLS_H_NORMAL); - aqt_clsh_set_buck_mode(codec, CLS_H_NORMAL); - aqt_clsh_set_buck_regulator_mode(codec, CLS_H_NORMAL); + aqt_clsh_buck_ctrl(component, clsh_d, CLS_H_NORMAL, false); + aqt_clsh_flyback_ctrl(component, clsh_d, CLS_H_NORMAL, false); + aqt_clsh_rdac_hd2_ctl(component, P5_0P35, req_state); + aqt_clsh_force_iq_ctl(component, CLS_H_NORMAL); + aqt_clsh_gm3_boost_disable(component, CLS_H_NORMAL); + aqt_clsh_set_flyback_mode(component, CLS_H_NORMAL); + aqt_clsh_set_buck_mode(component, CLS_H_NORMAL); + aqt_clsh_set_buck_regulator_mode(component, CLS_H_NORMAL); } } -static void aqt_clsh_state_hph_l(struct snd_soc_codec *codec, +static void aqt_clsh_state_hph_l(struct snd_soc_component *component, struct aqt_clsh_cdc_data *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), - is_enable ? "enable" : "disable"); + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); if (mode == CLS_H_NORMAL) { - dev_err(codec->dev, "%s: Normal mode not applicable for hph_l\n", + dev_err(component->dev, "%s: Normal mode not applicable for hph_l\n", __func__); return; } if (is_enable) { if (mode != CLS_AB && mode != CLS_AB_HIFI) { - aqt_enable_clsh_block(codec, clsh_d, true); + aqt_enable_clsh_block(component, clsh_d, true); /* * These K1 values depend on the Headphone Impedance * For now it is assumed to be 16 ohm */ - snd_soc_update_bits(codec, AQT1000_CDC_CLSH_K1_MSB, - 0x0F, 0x00); - snd_soc_update_bits(codec, AQT1000_CDC_CLSH_K1_LSB, - 0xFF, 0xC0); - snd_soc_update_bits(codec, - AQT1000_CDC_RX1_RX_PATH_CFG0, - 0x40, 0x40); + snd_soc_component_update_bits(component, + AQT1000_CDC_CLSH_K1_MSB, + 0x0F, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CDC_CLSH_K1_LSB, + 0xFF, 0xC0); + snd_soc_component_update_bits(component, + AQT1000_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x40); } - aqt_clsh_set_buck_regulator_mode(codec, mode); - aqt_clsh_set_flyback_mode(codec, mode); - aqt_clsh_gm3_boost_disable(codec, mode); - aqt_clsh_flyback_dac_ctl(codec, VREF_N0P9V); - aqt_clsh_mode_vref_ctl(codec, I2C); - aqt_clsh_force_iq_ctl(codec, mode); - aqt_clsh_rdac_hd2_ctl(codec, P82_0P77, req_state); - aqt_clsh_flyback_ctrl(codec, clsh_d, mode, true); - aqt_clsh_flyback_dac_ctl(codec, VREF_N1P827V); - aqt_clsh_set_buck_mode(codec, mode); - aqt_clsh_buck_ctrl(codec, clsh_d, mode, true); - aqt_clsh_mode_vref_ctl(codec, CONTROLLER); - aqt_clsh_buck_current_bias_ctl(codec, true); - aqt_clsh_set_hph_mode(codec, mode); + aqt_clsh_set_buck_regulator_mode(component, mode); + aqt_clsh_set_flyback_mode(component, mode); + aqt_clsh_gm3_boost_disable(component, mode); + aqt_clsh_flyback_dac_ctl(component, VREF_N0P9V); + aqt_clsh_mode_vref_ctl(component, I2C); + aqt_clsh_force_iq_ctl(component, mode); + aqt_clsh_rdac_hd2_ctl(component, P82_0P77, req_state); + aqt_clsh_flyback_ctrl(component, clsh_d, mode, true); + aqt_clsh_flyback_dac_ctl(component, VREF_N1P827V); + aqt_clsh_set_buck_mode(component, mode); + aqt_clsh_buck_ctrl(component, clsh_d, mode, true); + aqt_clsh_mode_vref_ctl(component, CONTROLLER); + aqt_clsh_buck_current_bias_ctl(component, true); + aqt_clsh_set_hph_mode(component, mode); } else { - aqt_clsh_set_hph_mode(codec, CLS_H_NORMAL); - aqt_clsh_buck_current_bias_ctl(codec, false); + aqt_clsh_set_hph_mode(component, CLS_H_NORMAL); + aqt_clsh_buck_current_bias_ctl(component, false); if (mode != CLS_AB && mode != CLS_AB_HIFI) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_RX1_RX_PATH_CFG0, 0x40, 0x00); - aqt_enable_clsh_block(codec, clsh_d, false); + aqt_enable_clsh_block(component, clsh_d, false); } /* set buck and flyback to Default Mode */ - aqt_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false); - aqt_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false); - aqt_clsh_rdac_hd2_ctl(codec, P5_0P35, req_state); - aqt_clsh_force_iq_ctl(codec, CLS_H_NORMAL); - aqt_clsh_gm3_boost_disable(codec, CLS_H_NORMAL); - aqt_clsh_set_flyback_mode(codec, CLS_H_NORMAL); - aqt_clsh_set_buck_mode(codec, CLS_H_NORMAL); - aqt_clsh_set_buck_regulator_mode(codec, CLS_H_NORMAL); + aqt_clsh_buck_ctrl(component, clsh_d, CLS_H_NORMAL, false); + aqt_clsh_flyback_ctrl(component, clsh_d, CLS_H_NORMAL, false); + aqt_clsh_rdac_hd2_ctl(component, P5_0P35, req_state); + aqt_clsh_force_iq_ctl(component, CLS_H_NORMAL); + aqt_clsh_gm3_boost_disable(component, CLS_H_NORMAL); + aqt_clsh_set_flyback_mode(component, CLS_H_NORMAL); + aqt_clsh_set_buck_mode(component, CLS_H_NORMAL); + aqt_clsh_set_buck_regulator_mode(component, CLS_H_NORMAL); } } -static void aqt_clsh_state_err(struct snd_soc_codec *codec, +static void aqt_clsh_state_err(struct snd_soc_component *component, struct aqt_clsh_cdc_data *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_err(codec->dev, + dev_err(component->dev, "%s Wrong request for class H state machine requested to %s %s", __func__, is_enable ? "enable" : "disable", state_to_str[req_state]); @@ -687,14 +723,14 @@ static bool aqt_clsh_is_state_valid(u8 state) /* * Function: aqt_clsh_fsm - * Params: codec, cdc_clsh_d, req_state, req_type, clsh_event + * Params: component, cdc_clsh_d, req_state, req_type, clsh_event * Description: * This function handles PRE DAC and POST DAC conditions of different devices * and updates class H configuration of different combination of devices * based on validity of their states. cdc_clsh_d will contain current * class h state information */ -void aqt_clsh_fsm(struct snd_soc_codec *codec, +void aqt_clsh_fsm(struct snd_soc_component *component, struct aqt_clsh_cdc_data *cdc_clsh_d, u8 clsh_event, u8 req_state, int int_mode) @@ -707,22 +743,22 @@ void aqt_clsh_fsm(struct snd_soc_codec *codec, new_state = old_state | req_state; if (!aqt_clsh_is_state_valid(new_state)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Class-H not a valid new state: %s\n", __func__, state_to_str[new_state]); return; } if (new_state == old_state) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Class-H already in requested state: %s\n", __func__, state_to_str[new_state]); return; } cdc_clsh_d->state = new_state; aqt_clsh_set_int_mode(cdc_clsh_d, req_state, int_mode); - (*clsh_state_fp[new_state]) (codec, cdc_clsh_d, req_state, + (*clsh_state_fp[new_state]) (component, cdc_clsh_d, req_state, CLSH_REQ_ENABLE, int_mode); - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: ClassH state transition from %s to %s\n", __func__, state_to_str[old_state], state_to_str[cdc_clsh_d->state]); @@ -732,23 +768,23 @@ void aqt_clsh_fsm(struct snd_soc_codec *codec, new_state = old_state & (~req_state); if (new_state < NUM_CLSH_STATES) { if (!aqt_clsh_is_state_valid(old_state)) { - dev_err(codec->dev, + dev_err(component->dev, "%s:Invalid old state:%s\n", __func__, state_to_str[old_state]); return; } if (new_state == old_state) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Class-H already in requested state: %s\n", __func__,state_to_str[new_state]); return; } - (*clsh_state_fp[old_state]) (codec, cdc_clsh_d, + (*clsh_state_fp[old_state]) (component, cdc_clsh_d, req_state, CLSH_REQ_DISABLE, int_mode); cdc_clsh_d->state = new_state; aqt_clsh_set_int_mode(cdc_clsh_d, req_state, CLS_NONE); - dev_dbg(codec->dev, "%s: ClassH state transition from %s to %s\n", + dev_dbg(component->dev, "%s: ClassH state transition from %s to %s\n", __func__, state_to_str[old_state], state_to_str[cdc_clsh_d->state]); } diff --git a/asoc/codecs/aqt1000/aqt1000-clsh.h b/asoc/codecs/aqt1000/aqt1000-clsh.h index 04b8ca256d67..7079450a73d0 100644 --- a/asoc/codecs/aqt1000/aqt1000-clsh.h +++ b/asoc/codecs/aqt1000/aqt1000-clsh.h @@ -94,14 +94,14 @@ struct aqt_reg_mask_val { u8 val; }; -extern void aqt_clsh_fsm(struct snd_soc_codec *codec, +extern void aqt_clsh_fsm(struct snd_soc_component *component, struct aqt_clsh_cdc_data *cdc_clsh_d, u8 clsh_event, u8 req_state, int int_mode); extern void aqt_clsh_init(struct aqt_clsh_cdc_data *clsh); extern int aqt_clsh_get_clsh_state(struct aqt_clsh_cdc_data *clsh); -extern void aqt_clsh_imped_config(struct snd_soc_codec *codec, int imped, - bool reset); +extern void aqt_clsh_imped_config(struct snd_soc_component *component, + int imped, bool reset); #endif /* _AQT1000_CLSH_H */ diff --git a/asoc/codecs/aqt1000/aqt1000-irq.c b/asoc/codecs/aqt1000/aqt1000-irq.c index b4d2ef6fe374..5f715738aa32 100644 --- a/asoc/codecs/aqt1000/aqt1000-irq.c +++ b/asoc/codecs/aqt1000/aqt1000-irq.c @@ -154,6 +154,7 @@ static struct irq_chip aqt_irq_chip = { }; static struct lock_class_key aqt_irq_lock_class; +static struct lock_class_key aqt_irq_lock_requested_class; static int aqt_irq_map(struct irq_domain *irqd, unsigned int virq, irq_hw_number_t hw) @@ -162,7 +163,8 @@ static int aqt_irq_map(struct irq_domain *irqd, unsigned int virq, irq_set_chip_data(virq, data); irq_set_chip_and_handler(virq, &aqt_irq_chip, handle_simple_irq); - irq_set_lockdep_class(virq, &aqt_irq_lock_class); + irq_set_lockdep_class(virq, &aqt_irq_lock_class, + &aqt_irq_lock_requested_class); irq_set_nested_thread(virq, 1); irq_set_noprobe(virq); diff --git a/asoc/codecs/aqt1000/aqt1000-mbhc.c b/asoc/codecs/aqt1000/aqt1000-mbhc.c index 0d96f71e9541..4146c6bfbbf6 100644 --- a/asoc/codecs/aqt1000/aqt1000-mbhc.c +++ b/asoc/codecs/aqt1000/aqt1000-mbhc.c @@ -153,19 +153,19 @@ struct aqt_mbhc_zdet_param { u16 btn7; }; -static int aqt_mbhc_request_irq(struct snd_soc_codec *codec, +static int aqt_mbhc_request_irq(struct snd_soc_component *component, int irq, irq_handler_t handler, const char *name, void *data) { - struct aqt1000 *aqt = dev_get_drvdata(codec->dev); + struct aqt1000 *aqt = dev_get_drvdata(component->dev); return aqt_request_irq(aqt, irq, name, handler, data); } -static void aqt_mbhc_irq_control(struct snd_soc_codec *codec, +static void aqt_mbhc_irq_control(struct snd_soc_component *component, int irq, bool enable) { - struct aqt1000 *aqt = dev_get_drvdata(codec->dev); + struct aqt1000 *aqt = dev_get_drvdata(component->dev); if (enable) aqt_enable_irq(aqt, irq); @@ -173,44 +173,49 @@ static void aqt_mbhc_irq_control(struct snd_soc_codec *codec, aqt_disable_irq(aqt, irq); } -static int aqt_mbhc_free_irq(struct snd_soc_codec *codec, +static int aqt_mbhc_free_irq(struct snd_soc_component *component, int irq, void *data) { - struct aqt1000 *aqt = dev_get_drvdata(codec->dev); + struct aqt1000 *aqt = dev_get_drvdata(component->dev); aqt_free_irq(aqt, irq, data); return 0; } -static void aqt_mbhc_clk_setup(struct snd_soc_codec *codec, +static void aqt_mbhc_clk_setup(struct snd_soc_component *component, bool enable) { if (enable) - snd_soc_update_bits(codec, AQT1000_MBHC_NEW_CTL_1, - 0x80, 0x80); + snd_soc_component_update_bits(component, + AQT1000_MBHC_NEW_CTL_1, + 0x80, 0x80); else - snd_soc_update_bits(codec, AQT1000_MBHC_NEW_CTL_1, - 0x80, 0x00); + snd_soc_component_update_bits(component, + AQT1000_MBHC_NEW_CTL_1, + 0x80, 0x00); } -static int aqt_mbhc_btn_to_num(struct snd_soc_codec *codec) +static int aqt_mbhc_btn_to_num(struct snd_soc_component *component) { - return snd_soc_read(codec, AQT1000_ANA_MBHC_RESULT_3) & 0x7; + return snd_soc_component_read32(component, + AQT1000_ANA_MBHC_RESULT_3) & 0x7; } -static void aqt_mbhc_mbhc_bias_control(struct snd_soc_codec *codec, +static void aqt_mbhc_mbhc_bias_control(struct snd_soc_component *component, bool enable) { if (enable) - snd_soc_update_bits(codec, AQT1000_ANA_MBHC_ELECT, - 0x01, 0x01); + snd_soc_component_update_bits(component, + AQT1000_ANA_MBHC_ELECT, + 0x01, 0x01); else - snd_soc_update_bits(codec, AQT1000_ANA_MBHC_ELECT, - 0x01, 0x00); + snd_soc_component_update_bits(component, + AQT1000_ANA_MBHC_ELECT, + 0x01, 0x00); } -static void aqt_mbhc_program_btn_thr(struct snd_soc_codec *codec, +static void aqt_mbhc_program_btn_thr(struct snd_soc_component *component, s16 *btn_low, s16 *btn_high, int num_btn, bool is_micbias) { @@ -218,24 +223,25 @@ static void aqt_mbhc_program_btn_thr(struct snd_soc_codec *codec, int vth; if (num_btn > WCD_MBHC_DEF_BUTTONS) { - dev_err(codec->dev, "%s: invalid number of buttons: %d\n", + dev_err(component->dev, "%s: invalid number of buttons: %d\n", __func__, num_btn); return; } for (i = 0; i < num_btn; i++) { vth = ((btn_high[i] * 2) / 25) & 0x3F; - snd_soc_update_bits(codec, AQT1000_ANA_MBHC_BTN0 + i, - 0xFC, vth << 2); - dev_dbg(codec->dev, "%s: btn_high[%d]: %d, vth: %d\n", + snd_soc_component_update_bits(component, + AQT1000_ANA_MBHC_BTN0 + i, + 0xFC, vth << 2); + dev_dbg(component->dev, "%s: btn_high[%d]: %d, vth: %d\n", __func__, i, btn_high[i], vth); } } static bool aqt_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock) { - struct snd_soc_codec *codec = mbhc->codec; - struct aqt1000 *aqt = dev_get_drvdata(codec->dev); + struct snd_soc_component *component = mbhc->component; + struct aqt1000 *aqt = dev_get_drvdata(component->dev); bool ret = 0; dev_dbg(aqt->dev, "%s: lock: %d\n", __func__, lock); @@ -264,7 +270,8 @@ static bool aqt_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) u8 val; if (micb_num == MIC_BIAS_1) { - val = ((snd_soc_read(mbhc->codec, AQT1000_ANA_MICB1) & 0xC0) + val = ((snd_soc_component_read32( + mbhc->component, AQT1000_ANA_MICB1) & 0xC0) >> 6); if (val == 0x01) return true; @@ -272,12 +279,13 @@ static bool aqt_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) return false; } -static bool aqt_mbhc_hph_pa_on_status(struct snd_soc_codec *codec) +static bool aqt_mbhc_hph_pa_on_status(struct snd_soc_component *component) { - return (snd_soc_read(codec, AQT1000_ANA_HPH) & 0xC0) ? true : false; + return (snd_soc_component_read32(component, AQT1000_ANA_HPH) & 0xC0) ? + true : false; } -static void aqt_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec, +static void aqt_mbhc_hph_l_pull_up_control(struct snd_soc_component *component, int pull_up_cur) { /* Default pull up current to 2uA */ @@ -285,14 +293,15 @@ static void aqt_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec, pull_up_cur == HS_PULLUP_I_DEFAULT) pull_up_cur = HS_PULLUP_I_2P0_UA; - dev_dbg(codec->dev, "%s: HS pull up current:%d\n", + dev_dbg(component->dev, "%s: HS pull up current:%d\n", __func__, pull_up_cur); - snd_soc_update_bits(codec, AQT1000_MBHC_NEW_INT_MECH_DET_CURRENT, - 0x1F, pull_up_cur); + snd_soc_component_update_bits(component, + AQT1000_MBHC_NEW_INT_MECH_DET_CURRENT, + 0x1F, pull_up_cur); } -static int aqt_mbhc_request_micbias(struct snd_soc_codec *codec, +static int aqt_mbhc_request_micbias(struct snd_soc_component *component, int micb_num, int req) { int ret = 0; @@ -302,33 +311,37 @@ static int aqt_mbhc_request_micbias(struct snd_soc_codec *codec, * is vote to enable mclk */ if (req == MICB_ENABLE) - aqt_cdc_mclk_enable(codec, true); + aqt_cdc_mclk_enable(component, true); - ret = aqt_micbias_control(codec, micb_num, req, false); + ret = aqt_micbias_control(component, micb_num, req, false); /* * Release vote for mclk while requesting for * micbias disable */ if (req == MICB_DISABLE) - aqt_cdc_mclk_enable(codec, false); + aqt_cdc_mclk_enable(component, false); return ret; } -static void aqt_mbhc_micb_ramp_control(struct snd_soc_codec *codec, +static void aqt_mbhc_micb_ramp_control(struct snd_soc_component *component, bool enable) { if (enable) { - snd_soc_update_bits(codec, AQT1000_ANA_MICB1_RAMP, - 0x1C, 0x0C); - snd_soc_update_bits(codec, AQT1000_ANA_MICB1_RAMP, - 0x80, 0x80); + snd_soc_component_update_bits(component, + AQT1000_ANA_MICB1_RAMP, + 0x1C, 0x0C); + snd_soc_component_update_bits(component, + AQT1000_ANA_MICB1_RAMP, + 0x80, 0x80); } else { - snd_soc_update_bits(codec, AQT1000_ANA_MICB1_RAMP, - 0x80, 0x00); - snd_soc_update_bits(codec, AQT1000_ANA_MICB1_RAMP, - 0x1C, 0x00); + snd_soc_component_update_bits(component, + AQT1000_ANA_MICB1_RAMP, + 0x80, 0x00); + snd_soc_component_update_bits(component, + AQT1000_ANA_MICB1_RAMP, + 0x1C, 0x00); } } @@ -337,26 +350,27 @@ static struct firmware_cal *aqt_get_hwdep_fw_cal(struct wcd_mbhc *mbhc, { struct aqt1000_mbhc *aqt_mbhc; struct firmware_cal *hwdep_cal; - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; aqt_mbhc = container_of(mbhc, struct aqt1000_mbhc, wcd_mbhc); - if (!codec) { + if (!component) { pr_err("%s: NULL codec pointer\n", __func__); return NULL; } hwdep_cal = wcdcal_get_fw_cal(aqt_mbhc->fw_data, type); if (!hwdep_cal) - dev_err(codec->dev, "%s: cal not sent by %d\n", + dev_err(component->dev, "%s: cal not sent by %d\n", __func__, type); return hwdep_cal; } -static int aqt_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec, - int micb_num, bool req_en) +static int aqt_mbhc_micb_ctrl_threshold_mic( + struct snd_soc_component *component, + int micb_num, bool req_en) { - struct aqt1000_pdata *pdata = dev_get_platdata(codec->dev); + struct aqt1000_pdata *pdata = dev_get_platdata(component->dev); int rc, micb_mv; if (micb_num != MIC_BIAS_1) @@ -372,7 +386,7 @@ static int aqt_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec, micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb1_mv; - rc = aqt_mbhc_micb_adjust_voltage(codec, micb_mv, MIC_BIAS_1); + rc = aqt_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_1); return rc; } @@ -433,25 +447,26 @@ static inline void aqt_mbhc_get_result_params(struct aqt1000 *aqt, } } -static void aqt_mbhc_zdet_ramp(struct snd_soc_codec *codec, +static void aqt_mbhc_zdet_ramp(struct snd_soc_component *component, struct aqt_mbhc_zdet_param *zdet_param, int32_t *zl, int32_t *zr, s16 *d1_a) { - struct aqt1000 *aqt = dev_get_drvdata(codec->dev); + struct aqt1000 *aqt = dev_get_drvdata(component->dev); int32_t zdet = 0; - snd_soc_update_bits(codec, AQT1000_MBHC_NEW_ZDET_ANA_CTL, 0x70, - zdet_param->ldo_ctl << 4); - snd_soc_update_bits(codec, AQT1000_ANA_MBHC_BTN5, 0xFC, - zdet_param->btn5); - snd_soc_update_bits(codec, AQT1000_ANA_MBHC_BTN6, 0xFC, - zdet_param->btn6); - snd_soc_update_bits(codec, AQT1000_ANA_MBHC_BTN7, 0xFC, - zdet_param->btn7); - snd_soc_update_bits(codec, AQT1000_MBHC_NEW_ZDET_ANA_CTL, 0x0F, - zdet_param->noff); - snd_soc_update_bits(codec, AQT1000_MBHC_NEW_ZDET_RAMP_CTL, 0x0F, - zdet_param->nshift); + snd_soc_component_update_bits(component, + AQT1000_MBHC_NEW_ZDET_ANA_CTL, 0x70, + zdet_param->ldo_ctl << 4); + snd_soc_component_update_bits(component, AQT1000_ANA_MBHC_BTN5, + 0xFC, zdet_param->btn5); + snd_soc_component_update_bits(component, AQT1000_ANA_MBHC_BTN6, + 0xFC, zdet_param->btn6); + snd_soc_component_update_bits(component, AQT1000_ANA_MBHC_BTN7, + 0xFC, zdet_param->btn7); + snd_soc_component_update_bits(component, AQT1000_MBHC_NEW_ZDET_ANA_CTL, + 0x0F, zdet_param->noff); + snd_soc_component_update_bits(component, AQT1000_MBHC_NEW_ZDET_RAMP_CTL, + 0x0F, zdet_param->nshift); if (!zl) goto z_right; @@ -481,17 +496,17 @@ static void aqt_mbhc_zdet_ramp(struct snd_soc_codec *codec, *zr = zdet; } -static inline void aqt_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec, +static inline void aqt_wcd_mbhc_qfuse_cal(struct snd_soc_component *component, int32_t *z_val, int flag_l_r) { s16 q1; int q1_cal; if (*z_val < (AQT_ZDET_VAL_400/1000)) - q1 = snd_soc_read(codec, + q1 = snd_soc_component_read32(component, AQT1000_CHIP_CFG0_EFUSE_VAL_OUT1 + (2 * flag_l_r)); else - q1 = snd_soc_read(codec, + q1 = snd_soc_component_read32(component, AQT1000_CHIP_CFG0_EFUSE_VAL_OUT2 + (2 * flag_l_r)); if (q1 & 0x80) q1_cal = (10000 - ((q1 & 0x7F) * 25)); @@ -504,8 +519,8 @@ static inline void aqt_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec, static void aqt_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, uint32_t *zr) { - struct snd_soc_codec *codec = mbhc->codec; - struct aqt1000 *aqt = dev_get_drvdata(codec->dev); + struct snd_soc_component *component = mbhc->component; + struct aqt1000 *aqt = dev_get_drvdata(component->dev); s16 reg0, reg1, reg2, reg3, reg4; int32_t z1L, z1R, z1Ls; int zMono, z_diff1, z_diff2; @@ -527,13 +542,15 @@ static void aqt_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); - reg0 = snd_soc_read(codec, AQT1000_ANA_MBHC_BTN5); - reg1 = snd_soc_read(codec, AQT1000_ANA_MBHC_BTN6); - reg2 = snd_soc_read(codec, AQT1000_ANA_MBHC_BTN7); - reg3 = snd_soc_read(codec, AQT1000_MBHC_CTL_CLK); - reg4 = snd_soc_read(codec, AQT1000_MBHC_NEW_ZDET_ANA_CTL); + reg0 = snd_soc_component_read32(component, AQT1000_ANA_MBHC_BTN5); + reg1 = snd_soc_component_read32(component, AQT1000_ANA_MBHC_BTN6); + reg2 = snd_soc_component_read32(component, AQT1000_ANA_MBHC_BTN7); + reg3 = snd_soc_component_read32(component, AQT1000_MBHC_CTL_CLK); + reg4 = snd_soc_component_read32(component, + AQT1000_MBHC_NEW_ZDET_ANA_CTL); - if (snd_soc_read(codec, AQT1000_ANA_MBHC_ELECT) & 0x80) { + if (snd_soc_component_read32(component, + AQT1000_ANA_MBHC_ELECT) & 0x80) { is_fsm_disable = true; regmap_update_bits(aqt->regmap, AQT1000_ANA_MBHC_ELECT, 0x80, 0x00); @@ -551,7 +568,7 @@ static void aqt_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, /* First get impedance on Left */ d1 = d1_a[1]; zdet_param_ptr = &zdet_param[1]; - aqt_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + aqt_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1); if (!AQT_MBHC_IS_SECOND_RAMP_REQUIRED(z1L)) goto left_ch_impedance; @@ -567,7 +584,7 @@ static void aqt_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, zdet_param_ptr = &zdet_param[3]; d1 = d1_a[3]; } - aqt_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + aqt_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1); left_ch_impedance: if ((z1L == AQT_ZDET_FLOATING_IMPEDANCE) || @@ -577,13 +594,13 @@ static void aqt_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, d1 = d1_a[1]; } else { *zl = z1L/1000; - aqt_wcd_mbhc_qfuse_cal(codec, zl, 0); + aqt_wcd_mbhc_qfuse_cal(component, zl, 0); } - dev_dbg(codec->dev, "%s: impedance on HPH_L = %d(ohms)\n", + dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n", __func__, *zl); /* Start of right impedance ramp and calculation */ - aqt_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + aqt_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1); if (AQT_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) { if (((z1R > AQT_ZDET_VAL_1200) && (zdet_param_ptr->noff == 0x6)) || @@ -601,7 +618,7 @@ static void aqt_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, zdet_param_ptr = &zdet_param[3]; d1 = d1_a[3]; } - aqt_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + aqt_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1); } right_ch_impedance: if ((z1R == AQT_ZDET_FLOATING_IMPEDANCE) || @@ -609,15 +626,15 @@ static void aqt_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, *zr = AQT_ZDET_FLOATING_IMPEDANCE; } else { *zr = z1R/1000; - aqt_wcd_mbhc_qfuse_cal(codec, zr, 1); + aqt_wcd_mbhc_qfuse_cal(component, zr, 1); } - dev_dbg(codec->dev, "%s: impedance on HPH_R = %d(ohms)\n", + dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n", __func__, *zr); /* Mono/stereo detection */ if ((*zl == AQT_ZDET_FLOATING_IMPEDANCE) && (*zr == AQT_ZDET_FLOATING_IMPEDANCE)) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: plug type is invalid or extension cable\n", __func__); goto zdet_complete; @@ -626,40 +643,44 @@ static void aqt_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, (*zr == AQT_ZDET_FLOATING_IMPEDANCE) || ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) || ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: Mono plug type with one ch floating or shorted to GND\n", __func__); mbhc->hph_type = WCD_MBHC_HPH_MONO; goto zdet_complete; } - snd_soc_update_bits(codec, AQT1000_HPH_R_ATEST, 0x02, 0x02); - snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2, 0x40, 0x01); + snd_soc_component_update_bits(component, AQT1000_HPH_R_ATEST, + 0x02, 0x02); + snd_soc_component_update_bits(component, AQT1000_HPH_PA_CTL2, + 0x40, 0x01); if (*zl < (AQT_ZDET_VAL_32/1000)) - aqt_mbhc_zdet_ramp(codec, &zdet_param[0], &z1Ls, NULL, d1); + aqt_mbhc_zdet_ramp(component, &zdet_param[0], &z1Ls, NULL, d1); else - aqt_mbhc_zdet_ramp(codec, &zdet_param[1], &z1Ls, NULL, d1); - snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2, 0x40, 0x00); - snd_soc_update_bits(codec, AQT1000_HPH_R_ATEST, 0x02, 0x00); + aqt_mbhc_zdet_ramp(component, &zdet_param[1], &z1Ls, NULL, d1); + snd_soc_component_update_bits(component, AQT1000_HPH_PA_CTL2, + 0x40, 0x00); + snd_soc_component_update_bits(component, AQT1000_HPH_R_ATEST, + 0x02, 0x00); z1Ls /= 1000; - aqt_wcd_mbhc_qfuse_cal(codec, &z1Ls, 0); + aqt_wcd_mbhc_qfuse_cal(component, &z1Ls, 0); /* Parallel of left Z and 9 ohm pull down resistor */ zMono = ((*zl) * 9) / ((*zl) + 9); z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls); z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl)); if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) { - dev_dbg(codec->dev, "%s: stereo plug type detected\n", + dev_dbg(component->dev, "%s: stereo plug type detected\n", __func__); mbhc->hph_type = WCD_MBHC_HPH_STEREO; } else { - dev_dbg(codec->dev, "%s: MONO plug type detected\n", + dev_dbg(component->dev, "%s: MONO plug type detected\n", __func__); mbhc->hph_type = WCD_MBHC_HPH_MONO; } zdet_complete: - snd_soc_write(codec, AQT1000_ANA_MBHC_BTN5, reg0); - snd_soc_write(codec, AQT1000_ANA_MBHC_BTN6, reg1); - snd_soc_write(codec, AQT1000_ANA_MBHC_BTN7, reg2); + snd_soc_component_write(component, AQT1000_ANA_MBHC_BTN5, reg0); + snd_soc_component_write(component, AQT1000_ANA_MBHC_BTN6, reg1); + snd_soc_component_write(component, AQT1000_ANA_MBHC_BTN7, reg2); /* Turn on 100k pull down on HPHL */ regmap_update_bits(aqt->regmap, AQT1000_ANA_MBHC_MECH, 0x01, 0x01); @@ -669,77 +690,83 @@ static void aqt_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, regmap_update_bits(aqt->regmap, AQT1000_ANA_MBHC_MECH, 0x80, 0x80); - snd_soc_write(codec, AQT1000_MBHC_NEW_ZDET_ANA_CTL, reg4); - snd_soc_write(codec, AQT1000_MBHC_CTL_CLK, reg3); + snd_soc_component_write(component, AQT1000_MBHC_NEW_ZDET_ANA_CTL, + reg4); + snd_soc_component_write(component, AQT1000_MBHC_CTL_CLK, reg3); if (is_fsm_disable) regmap_update_bits(aqt->regmap, AQT1000_ANA_MBHC_ELECT, 0x80, 0x80); } -static void aqt_mbhc_gnd_det_ctrl(struct snd_soc_codec *codec, bool enable) +static void aqt_mbhc_gnd_det_ctrl(struct snd_soc_component *component, + bool enable) { if (enable) { - snd_soc_update_bits(codec, AQT1000_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, AQT1000_ANA_MBHC_MECH, 0x02, 0x02); - snd_soc_update_bits(codec, AQT1000_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, AQT1000_ANA_MBHC_MECH, 0x40, 0x40); } else { - snd_soc_update_bits(codec, AQT1000_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, AQT1000_ANA_MBHC_MECH, 0x40, 0x00); - snd_soc_update_bits(codec, AQT1000_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, AQT1000_ANA_MBHC_MECH, 0x02, 0x00); } } -static void aqt_mbhc_hph_pull_down_ctrl(struct snd_soc_codec *codec, +static void aqt_mbhc_hph_pull_down_ctrl(struct snd_soc_component *component, bool enable) { if (enable) { - snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2, + snd_soc_component_update_bits(component, AQT1000_HPH_PA_CTL2, 0x40, 0x40); - snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2, + snd_soc_component_update_bits(component, AQT1000_HPH_PA_CTL2, 0x10, 0x10); } else { - snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2, + snd_soc_component_update_bits(component, AQT1000_HPH_PA_CTL2, 0x40, 0x00); - snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2, + snd_soc_component_update_bits(component, AQT1000_HPH_PA_CTL2, 0x10, 0x00); } } static void aqt_mbhc_moisture_config(struct wcd_mbhc *mbhc) { - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; if ((mbhc->moist_rref == R_OFF) || (mbhc->mbhc_cfg->enable_usbc_analog)) { - snd_soc_update_bits(codec, AQT1000_MBHC_NEW_CTL_2, - 0x0C, R_OFF << 2); + snd_soc_component_update_bits(component, + AQT1000_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); return; } /* Do not enable moisture detection if jack type is NC */ if (!mbhc->hphl_swh) { - dev_dbg(codec->dev, "%s: disable moisture detection for NC\n", + dev_dbg(component->dev, "%s: disable moisture detection for NC\n", __func__); - snd_soc_update_bits(codec, AQT1000_MBHC_NEW_CTL_2, - 0x0C, R_OFF << 2); + snd_soc_component_update_bits(component, + AQT1000_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); return; } - snd_soc_update_bits(codec, AQT1000_MBHC_NEW_CTL_2, + snd_soc_component_update_bits(component, AQT1000_MBHC_NEW_CTL_2, 0x0C, mbhc->moist_rref << 2); } -static void aqt_update_anc_state(struct snd_soc_codec *codec, bool enable, - int anc_num) +static void aqt_update_anc_state(struct snd_soc_component *component, + bool enable, int anc_num) { if (enable) - snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CFG0 + - (20 * anc_num), 0x10, 0x10); + snd_soc_component_update_bits(component, + AQT1000_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num), + 0x10, 0x10); else - snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CFG0 + - (20 * anc_num), 0x10, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num), + 0x10, 0x00); } static bool aqt_is_anc_on(struct wcd_mbhc *mbhc) @@ -748,9 +775,11 @@ static bool aqt_is_anc_on(struct wcd_mbhc *mbhc) u16 ancl, ancr; ancl = - (snd_soc_read(mbhc->codec, AQT1000_CDC_RX1_RX_PATH_CFG0)) & 0x10; + (snd_soc_component_read32(mbhc->component, + AQT1000_CDC_RX1_RX_PATH_CFG0)) & 0x10; ancr = - (snd_soc_read(mbhc->codec, AQT1000_CDC_RX2_RX_PATH_CFG0)) & 0x10; + (snd_soc_component_read32(mbhc->component, + AQT1000_CDC_RX2_RX_PATH_CFG0)) & 0x10; anc_on = !!(ancl | ancr); @@ -785,20 +814,23 @@ static const struct wcd_mbhc_cb mbhc_cb = { static int aqt_get_hph_type(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); struct aqt1000_mbhc *aqt_mbhc = aqt->mbhc; struct wcd_mbhc *mbhc; if (!aqt_mbhc) { - dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + dev_err(component->dev, "%s: mbhc not initialized!\n", + __func__); return -EINVAL; } mbhc = &aqt_mbhc->wcd_mbhc; ucontrol->value.integer.value[0] = (u32) mbhc->hph_type; - dev_dbg(codec->dev, "%s: hph_type = %u\n", __func__, mbhc->hph_type); + dev_dbg(component->dev, "%s: hph_type = %u\n", __func__, + mbhc->hph_type); return 0; } @@ -809,19 +841,22 @@ static int aqt_hph_impedance_get(struct snd_kcontrol *kcontrol, uint32_t zl, zr; bool hphr; struct soc_multi_mixer_control *mc; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); struct aqt1000_mbhc *aqt_mbhc = aqt->mbhc; if (!aqt_mbhc) { - dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + dev_err(component->dev, "%s: mbhc not initialized!\n", + __func__); return -EINVAL; } mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); hphr = mc->shift; wcd_mbhc_get_impedance(&aqt_mbhc->wcd_mbhc, &zl, &zr); - dev_dbg(codec->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr); + dev_dbg(component->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, + zl, zr); ucontrol->value.integer.value[0] = hphr ? zr : zl; return 0; @@ -864,22 +899,22 @@ EXPORT_SYMBOL(aqt_mbhc_get_impedance); /* * aqt_mbhc_hs_detect: starts mbhc insertion/removal functionality - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * * @mbhc_cfg: handle to mbhc configuration structure * return 0 if mbhc_start is success or error code in case of failure */ -int aqt_mbhc_hs_detect(struct snd_soc_codec *codec, +int aqt_mbhc_hs_detect(struct snd_soc_component *component, struct wcd_mbhc_config *mbhc_cfg) { struct aqt1000 *aqt; struct aqt1000_mbhc *aqt_mbhc; - if (!codec) { + if (!component) { pr_err("%s: codec is NULL\n", __func__); return -EINVAL; } - aqt = snd_soc_codec_get_drvdata(codec); + aqt = snd_soc_component_get_drvdata(component); if (!aqt) { pr_err("%s: aqt is NULL\n", __func__); return -EINVAL; @@ -887,7 +922,8 @@ int aqt_mbhc_hs_detect(struct snd_soc_codec *codec, aqt_mbhc = aqt->mbhc; if (!aqt_mbhc) { - dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + dev_err(component->dev, "%s: mbhc not initialized!\n", + __func__); return -EINVAL; } @@ -897,19 +933,19 @@ EXPORT_SYMBOL(aqt_mbhc_hs_detect); /* * aqt_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * */ -void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +void aqt_mbhc_hs_detect_exit(struct snd_soc_component *component) { struct aqt1000 *aqt; struct aqt1000_mbhc *aqt_mbhc; - if (!codec) { + if (!component) { pr_err("%s: codec is NULL\n", __func__); return; } - aqt = snd_soc_codec_get_drvdata(codec); + aqt = snd_soc_component_get_drvdata(component); if (!aqt) { pr_err("%s: aqt is NULL\n", __func__); return; @@ -917,7 +953,8 @@ void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec) aqt_mbhc = aqt->mbhc; if (!aqt_mbhc) { - dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + dev_err(component->dev, "%s: mbhc not initialized!\n", + __func__); return; } wcd_mbhc_stop(&aqt_mbhc->wcd_mbhc); @@ -927,17 +964,17 @@ EXPORT_SYMBOL(aqt_mbhc_hs_detect_exit); /* * aqt_mbhc_post_ssr_init: initialize mbhc for aqt post subsystem restart * @mbhc: poniter to aqt_mbhc structure - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * * * return 0 if mbhc_init is success or error code in case of failure */ int aqt_mbhc_post_ssr_init(struct aqt1000_mbhc *mbhc, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { int ret; struct wcd_mbhc *wcd_mbhc; - if (!mbhc || !codec) + if (!mbhc || !component) return -EINVAL; wcd_mbhc = &mbhc->wcd_mbhc; @@ -947,10 +984,10 @@ int aqt_mbhc_post_ssr_init(struct aqt1000_mbhc *mbhc, } wcd_mbhc_deinit(wcd_mbhc); - ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids, + ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb, &intr_ids, wcd_mbhc_registers, AQT_ZDET_SUPPORTED); if (ret) { - dev_err(codec->dev, "%s: mbhc initialization failed\n", + dev_err(component->dev, "%s: mbhc initialization failed\n", __func__); goto done; } @@ -963,29 +1000,30 @@ EXPORT_SYMBOL(aqt_mbhc_post_ssr_init); /* * aqt_mbhc_init: initialize mbhc for aqt * @mbhc: poniter to aqt_mbhc struct pointer to store the configs - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * * @fw_data: handle to firmware data * * return 0 if mbhc_init is success or error code in case of failure */ -int aqt_mbhc_init(struct aqt1000_mbhc **mbhc, struct snd_soc_codec *codec, - struct fw_info *fw_data) +int aqt_mbhc_init(struct aqt1000_mbhc **mbhc, + struct snd_soc_component *component, + struct fw_info *fw_data) { struct aqt1000_mbhc *aqt_mbhc; struct wcd_mbhc *wcd_mbhc; int ret; - if (!codec) { + if (!component) { pr_err("%s: codec is NULL\n", __func__); return -EINVAL; } - aqt_mbhc = devm_kzalloc(codec->dev, sizeof(struct aqt1000_mbhc), + aqt_mbhc = devm_kzalloc(component->dev, sizeof(struct aqt1000_mbhc), GFP_KERNEL); if (!aqt_mbhc) return -ENOMEM; - aqt_mbhc->aqt = dev_get_drvdata(codec->dev); + aqt_mbhc->aqt = dev_get_drvdata(component->dev); aqt_mbhc->fw_data = fw_data; BLOCKING_INIT_NOTIFIER_HEAD(&aqt_mbhc->notifier); wcd_mbhc = &aqt_mbhc->wcd_mbhc; @@ -999,43 +1037,43 @@ int aqt_mbhc_init(struct aqt1000_mbhc **mbhc, struct snd_soc_codec *codec, /* Setting default mbhc detection logic to ADC */ wcd_mbhc->mbhc_detection_logic = WCD_DETECTION_ADC; - ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, + ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb, &intr_ids, wcd_mbhc_registers, AQT_ZDET_SUPPORTED); if (ret) { - dev_err(codec->dev, "%s: mbhc initialization failed\n", + dev_err(component->dev, "%s: mbhc initialization failed\n", __func__); goto err; } (*mbhc) = aqt_mbhc; - snd_soc_add_codec_controls(codec, impedance_detect_controls, + snd_soc_add_component_controls(component, impedance_detect_controls, ARRAY_SIZE(impedance_detect_controls)); - snd_soc_add_codec_controls(codec, hph_type_detect_controls, + snd_soc_add_component_controls(component, hph_type_detect_controls, ARRAY_SIZE(hph_type_detect_controls)); return 0; err: - devm_kfree(codec->dev, aqt_mbhc); + devm_kfree(component->dev, aqt_mbhc); return ret; } EXPORT_SYMBOL(aqt_mbhc_init); /* * aqt_mbhc_deinit: deinitialize mbhc for aqt - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * */ -void aqt_mbhc_deinit(struct snd_soc_codec *codec) +void aqt_mbhc_deinit(struct snd_soc_component *component) { struct aqt1000 *aqt; struct aqt1000_mbhc *aqt_mbhc; - if (!codec) { - pr_err("%s: codec is NULL\n", __func__); + if (!component) { + pr_err("%s: component is NULL\n", __func__); return; } - aqt = snd_soc_codec_get_drvdata(codec); + aqt = snd_soc_component_get_drvdata(component); if (!aqt) { pr_err("%s: aqt is NULL\n", __func__); return; @@ -1044,7 +1082,7 @@ void aqt_mbhc_deinit(struct snd_soc_codec *codec) aqt_mbhc = aqt->mbhc; if (aqt_mbhc) { wcd_mbhc_deinit(&aqt_mbhc->wcd_mbhc); - devm_kfree(codec->dev, aqt_mbhc); + devm_kfree(component->dev, aqt_mbhc); } } EXPORT_SYMBOL(aqt_mbhc_deinit); diff --git a/asoc/codecs/aqt1000/aqt1000-mbhc.h b/asoc/codecs/aqt1000/aqt1000-mbhc.h index 1fad90a2fbd3..aea788cc5e37 100644 --- a/asoc/codecs/aqt1000/aqt1000-mbhc.h +++ b/asoc/codecs/aqt1000/aqt1000-mbhc.h @@ -15,36 +15,36 @@ struct aqt1000_mbhc { #if IS_ENABLED(CONFIG_SND_SOC_AQT1000) extern int aqt_mbhc_init(struct aqt1000_mbhc **mbhc, - struct snd_soc_codec *codec, + struct snd_soc_component *component, struct fw_info *fw_data); -extern void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec); -extern int aqt_mbhc_hs_detect(struct snd_soc_codec *codec, +extern void aqt_mbhc_hs_detect_exit(struct snd_soc_component *component); +extern int aqt_mbhc_hs_detect(struct snd_soc_component *component, struct wcd_mbhc_config *mbhc_cfg); -extern void aqt_mbhc_deinit(struct snd_soc_codec *codec); +extern void aqt_mbhc_deinit(struct snd_soc_component *component); extern int aqt_mbhc_post_ssr_init(struct aqt1000_mbhc *mbhc, - struct snd_soc_codec *codec); + struct snd_soc_component *component); extern int aqt_mbhc_get_impedance(struct aqt1000_mbhc *aqt_mbhc, uint32_t *zl, uint32_t *zr); #else static inline int aqt_mbhc_init(struct aqt1000_mbhc **mbhc, - struct snd_soc_codec *codec, + struct snd_soc_component *component, struct fw_info *fw_data) { return 0; } -static inline void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +static inline void aqt_mbhc_hs_detect_exit(struct snd_soc_component *component) { } -static inline int aqt_mbhc_hs_detect(struct snd_soc_codec *codec, +static inline int aqt_mbhc_hs_detect(struct snd_soc_component *component, struct wcd_mbhc_config *mbhc_cfg) { return 0; } -static inline void aqt_mbhc_deinit(struct snd_soc_codec *codec) +static inline void aqt_mbhc_deinit(struct snd_soc_component *component) { } static inline int aqt_mbhc_post_ssr_init(struct aqt1000_mbhc *mbhc, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { return 0; } diff --git a/asoc/codecs/aqt1000/aqt1000.c b/asoc/codecs/aqt1000/aqt1000.c index 59a9d87266db..ef0c265e0a89 100644 --- a/asoc/codecs/aqt1000/aqt1000.c +++ b/asoc/codecs/aqt1000/aqt1000.c @@ -33,6 +33,8 @@ #include "../wcdcal-hwdep.h" #include "aqt1000-internal.h" +#define DRV_NAME "aqt_codec" + #define AQT1000_TX_UNMUTE_DELAY_MS 40 #define TX_HPF_CUT_OFF_FREQ_MASK 0x60 #define CF_MIN_3DB_4HZ 0x0 @@ -52,7 +54,7 @@ static int tx_unmute_delay = AQT1000_TX_UNMUTE_DELAY_MS; module_param(tx_unmute_delay, int, 0664); MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path"); -static void aqt_codec_set_tx_hold(struct snd_soc_codec *, u16, bool); +static void aqt_codec_set_tx_hold(struct snd_soc_component *, u16, bool); /* Cutoff frequency for high pass filter */ static const char * const cf_text[] = { @@ -91,8 +93,9 @@ static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); static int aqt_get_anc_slot(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = aqt->anc_slot; return 0; @@ -101,8 +104,9 @@ static int aqt_get_anc_slot(struct snd_kcontrol *kcontrol, static int aqt_put_anc_slot(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); aqt->anc_slot = ucontrol->value.integer.value[0]; return 0; @@ -111,8 +115,9 @@ static int aqt_put_anc_slot(struct snd_kcontrol *kcontrol, static int aqt_get_anc_func(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = (aqt->anc_func == true ? 1 : 0); return 0; @@ -121,13 +126,15 @@ static int aqt_get_anc_func(struct snd_kcontrol *kcontrol, static int aqt_put_anc_func(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); mutex_lock(&aqt->codec_mutex); aqt->anc_func = (!ucontrol->value.integer.value[0] ? false : true); - dev_dbg(codec->dev, "%s: anc_func %x", __func__, aqt->anc_func); + dev_dbg(component->dev, "%s: anc_func %x", __func__, aqt->anc_func); if (aqt->anc_func == true) { snd_soc_dapm_enable_pin(dapm, "ANC HPHL PA"); @@ -161,8 +168,9 @@ static const struct soc_enum aqt_anc_func_enum = static int aqt_rx_hph_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = aqt->hph_mode; return 0; @@ -171,16 +179,17 @@ static int aqt_rx_hph_mode_get(struct snd_kcontrol *kcontrol, static int aqt_rx_hph_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); u32 mode_val; mode_val = ucontrol->value.enumerated.item[0]; - dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val); + dev_dbg(component->dev, "%s: mode: %d\n", __func__, mode_val); if (mode_val == 0) { - dev_warn(codec->dev, "%s:Invalid HPH Mode, default to Cls-H LOHiFi\n", + dev_warn(component->dev, "%s:Invalid HPH Mode, default to Cls-H LOHiFi\n", __func__); mode_val = CLS_H_LOHIFI; } @@ -200,15 +209,16 @@ static const struct soc_enum rx_hph_mode_mux_enum = static int aqt_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int band_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; - ucontrol->value.integer.value[0] = (snd_soc_read(codec, + ucontrol->value.integer.value[0] = (snd_soc_component_read32(component, AQT1000_CDC_SIDETONE_IIR0_IIR_CTL) & (1 << band_idx)) != 0; - dev_dbg(codec->dev, "%s: IIR0 band #%d enable %d\n", __func__, + dev_dbg(component->dev, "%s: IIR0 band #%d enable %d\n", __func__, band_idx, (uint32_t)ucontrol->value.integer.value[0]); return 0; @@ -217,60 +227,64 @@ static int aqt_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol, static int aqt_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int band_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; bool iir_band_en_status; int value = ucontrol->value.integer.value[0]; /* Mask first 5 bits, 6-8 are reserved */ - snd_soc_update_bits(codec, AQT1000_CDC_SIDETONE_IIR0_IIR_CTL, - (1 << band_idx), (value << band_idx)); + snd_soc_component_update_bits(component, + AQT1000_CDC_SIDETONE_IIR0_IIR_CTL, + (1 << band_idx), (value << band_idx)); - iir_band_en_status = ((snd_soc_read(codec, + iir_band_en_status = ((snd_soc_component_read32(component, AQT1000_CDC_SIDETONE_IIR0_IIR_CTL) & (1 << band_idx)) != 0); - dev_dbg(codec->dev, "%s: IIR0 band #%d enable %d\n", __func__, + dev_dbg(component->dev, "%s: IIR0 band #%d enable %d\n", __func__, band_idx, iir_band_en_status); return 0; } -static uint32_t aqt_get_iir_band_coeff(struct snd_soc_codec *codec, +static uint32_t aqt_get_iir_band_coeff(struct snd_soc_component *component, int band_idx, int coeff_idx) { uint32_t value = 0; /* Address does not automatically update if reading */ - snd_soc_write(codec, + snd_soc_component_write(component, AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, ((band_idx * BAND_MAX + coeff_idx) * sizeof(uint32_t)) & 0x7F); - value |= snd_soc_read(codec, AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL); + value |= snd_soc_component_read32(component, + AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL); - snd_soc_write(codec, AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, + snd_soc_component_write(component, + AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, ((band_idx * BAND_MAX + coeff_idx) * sizeof(uint32_t) + 1) & 0x7F); - value |= (snd_soc_read(codec, - AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL) << 8); + value |= (snd_soc_component_read32(component, + AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL) << 8); - snd_soc_write(codec, + snd_soc_component_write(component, AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, ((band_idx * BAND_MAX + coeff_idx) * sizeof(uint32_t) + 2) & 0x7F); - value |= (snd_soc_read(codec, - AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL) << 16); + value |= (snd_soc_component_read32(component, + AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL) << 16); - snd_soc_write(codec, + snd_soc_component_write(component, AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, ((band_idx * BAND_MAX + coeff_idx) * sizeof(uint32_t) + 3) & 0x7F); /* Mask bits top 2 bits since they are reserved */ - value |= ((snd_soc_read(codec, + value |= ((snd_soc_component_read32(component, AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL) & 0x3F) << 24); @@ -280,22 +294,23 @@ static uint32_t aqt_get_iir_band_coeff(struct snd_soc_codec *codec, static int aqt_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int band_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; ucontrol->value.integer.value[0] = - aqt_get_iir_band_coeff(codec, band_idx, 0); + aqt_get_iir_band_coeff(component, band_idx, 0); ucontrol->value.integer.value[1] = - aqt_get_iir_band_coeff(codec, band_idx, 1); + aqt_get_iir_band_coeff(component, band_idx, 1); ucontrol->value.integer.value[2] = - aqt_get_iir_band_coeff(codec, band_idx, 2); + aqt_get_iir_band_coeff(component, band_idx, 2); ucontrol->value.integer.value[3] = - aqt_get_iir_band_coeff(codec, band_idx, 3); + aqt_get_iir_band_coeff(component, band_idx, 3); ucontrol->value.integer.value[4] = - aqt_get_iir_band_coeff(codec, band_idx, 4); + aqt_get_iir_band_coeff(component, band_idx, 4); - dev_dbg(codec->dev, "%s: IIR band #%d b0 = 0x%x\n" + dev_dbg(component->dev, "%s: IIR band #%d b0 = 0x%x\n" "%s: IIR band #%d b1 = 0x%x\n" "%s: IIR band #%d b2 = 0x%x\n" "%s: IIR band #%d a1 = 0x%x\n" @@ -314,23 +329,23 @@ static int aqt_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol, return 0; } -static void aqt_set_iir_band_coeff(struct snd_soc_codec *codec, +static void aqt_set_iir_band_coeff(struct snd_soc_component *component, int band_idx, uint32_t value) { - snd_soc_write(codec, + snd_soc_component_write(component, (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL), (value & 0xFF)); - snd_soc_write(codec, + snd_soc_component_write(component, (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL), (value >> 8) & 0xFF); - snd_soc_write(codec, + snd_soc_component_write(component, (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL), (value >> 16) & 0xFF); /* Mask top 2 bits, 7-8 are reserved */ - snd_soc_write(codec, + snd_soc_component_write(component, (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL), (value >> 24) & 0x3F); } @@ -338,7 +353,8 @@ static void aqt_set_iir_band_coeff(struct snd_soc_codec *codec, static int aqt_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int band_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; int coeff_idx; @@ -347,31 +363,31 @@ static int aqt_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, * Mask top bit it is reserved * Updates addr automatically for each B2 write */ - snd_soc_write(codec, + snd_soc_component_write(component, (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL), (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); for (coeff_idx = 0; coeff_idx < AQT1000_CDC_SIDETONE_IIR_COEFF_MAX; coeff_idx++) { - aqt_set_iir_band_coeff(codec, band_idx, + aqt_set_iir_band_coeff(component, band_idx, ucontrol->value.integer.value[coeff_idx]); } - dev_dbg(codec->dev, "%s: IIR band #%d b0 = 0x%x\n" + dev_dbg(component->dev, "%s: IIR band #%d b0 = 0x%x\n" "%s: IIR band #%d b1 = 0x%x\n" "%s: IIR band #%d b2 = 0x%x\n" "%s: IIR band #%d a1 = 0x%x\n" "%s: IIR band #%d a2 = 0x%x\n", __func__, band_idx, - aqt_get_iir_band_coeff(codec, band_idx, 0), + aqt_get_iir_band_coeff(component, band_idx, 0), __func__, band_idx, - aqt_get_iir_band_coeff(codec, band_idx, 1), + aqt_get_iir_band_coeff(component, band_idx, 1), __func__, band_idx, - aqt_get_iir_band_coeff(codec, band_idx, 2), + aqt_get_iir_band_coeff(component, band_idx, 2), __func__, band_idx, - aqt_get_iir_band_coeff(codec, band_idx, 3), + aqt_get_iir_band_coeff(component, band_idx, 3), __func__, band_idx, - aqt_get_iir_band_coeff(codec, band_idx, 4)); + aqt_get_iir_band_coeff(component, band_idx, 4)); return 0; } @@ -380,10 +396,11 @@ static int aqt_compander_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int comp = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = aqt->comp_enabled[comp]; return 0; @@ -392,13 +409,14 @@ static int aqt_compander_get(struct snd_kcontrol *kcontrol, static int aqt_compander_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); int comp = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; int value = ucontrol->value.integer.value[0]; - dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n", + dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n", __func__, comp + 1, aqt->comp_enabled[comp], value); aqt->comp_enabled[comp] = value; @@ -406,12 +424,14 @@ static int aqt_compander_put(struct snd_kcontrol *kcontrol, switch (comp) { case COMPANDER_1: /* Set Gain Source Select based on compander enable/disable */ - snd_soc_update_bits(codec, AQT1000_HPH_L_EN, 0x20, - (value ? 0x00:0x20)); + snd_soc_component_update_bits(component, + AQT1000_HPH_L_EN, 0x20, + (value ? 0x00 : 0x20)); break; case COMPANDER_2: - snd_soc_update_bits(codec, AQT1000_HPH_R_EN, 0x20, - (value ? 0x00:0x20)); + snd_soc_component_update_bits(component, + AQT1000_HPH_R_EN, 0x20, + (value ? 0x00 : 0x20)); break; default: /* @@ -419,7 +439,7 @@ static int aqt_compander_put(struct snd_kcontrol *kcontrol, * it does not cause any audio failure, so do not * return error in this case, but just print a log */ - dev_warn(codec->dev, "%s: unknown compander: %d\n", + dev_warn(component->dev, "%s: unknown compander: %d\n", __func__, comp); }; return 0; @@ -428,8 +448,9 @@ static int aqt_compander_put(struct snd_kcontrol *kcontrol, static int aqt_hph_asrc_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); int index = -EINVAL; if (!strcmp(kcontrol->id.name, "AQT ASRC0 Output Mode")) @@ -447,8 +468,9 @@ static int aqt_hph_asrc_mode_put(struct snd_kcontrol *kcontrol, static int aqt_hph_asrc_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); int val = 0; int index = -EINVAL; @@ -473,8 +495,9 @@ static SOC_ENUM_SINGLE_EXT_DECL(asrc_mode_enum, asrc_mode_text); static int aqt_hph_idle_detect_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); int val = 0; if (aqt) @@ -488,8 +511,9 @@ static int aqt_hph_idle_detect_get(struct snd_kcontrol *kcontrol, static int aqt_hph_idle_detect_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); if (aqt) aqt->idle_det_cfg.hph_idle_detect_en = @@ -507,7 +531,8 @@ static SOC_ENUM_SINGLE_EXT_DECL(hph_idle_detect_enum, hph_idle_detect_text); static int aqt_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); u16 amic_reg = 0; if (!strcmp(kcontrol->id.name, "AQT AMIC_1_2 PWR MODE")) @@ -517,7 +542,7 @@ static int aqt_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, if (amic_reg) ucontrol->value.integer.value[0] = - (snd_soc_read(codec, amic_reg) & + (snd_soc_component_read32(component, amic_reg) & AQT1000_AMIC_PWR_LVL_MASK) >> AQT1000_AMIC_PWR_LVL_SHIFT; return 0; @@ -526,13 +551,14 @@ static int aqt_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, static int aqt_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); u32 mode_val; u16 amic_reg = 0; mode_val = ucontrol->value.enumerated.item[0]; - dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val); + dev_dbg(component->dev, "%s: mode: %d\n", __func__, mode_val); if (!strcmp(kcontrol->id.name, "AQT AMIC_1_2 PWR MODE")) amic_reg = AQT1000_ANA_AMIC1; @@ -540,8 +566,9 @@ static int aqt_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, amic_reg = AQT1000_ANA_AMIC3; if (amic_reg) - snd_soc_update_bits(codec, amic_reg, AQT1000_AMIC_PWR_LVL_MASK, - mode_val << AQT1000_AMIC_PWR_LVL_SHIFT); + snd_soc_component_update_bits(component, amic_reg, + AQT1000_AMIC_PWR_LVL_MASK, + mode_val << AQT1000_AMIC_PWR_LVL_SHIFT); return 0; } @@ -651,41 +678,44 @@ static const struct snd_kcontrol_new aqt_snd_controls[] = { static int aqt_codec_enable_rx_bias(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: aqt->rx_bias_count++; if (aqt->rx_bias_count == 1) { - snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, - 0x01, 0x01); + snd_soc_component_update_bits(component, + AQT1000_ANA_RX_SUPPLIES, + 0x01, 0x01); } break; case SND_SOC_DAPM_POST_PMD: aqt->rx_bias_count--; if (!aqt->rx_bias_count) - snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES, - 0x01, 0x00); + snd_soc_component_update_bits(component, + AQT1000_ANA_RX_SUPPLIES, + 0x01, 0x00); break; }; - dev_dbg(codec->dev, "%s: Current RX BIAS user count: %d\n", __func__, - aqt->rx_bias_count); + dev_dbg(component->dev, "%s: Current RX BIAS user count: %d\n", + __func__, aqt->rx_bias_count); return 0; } /* * aqt_mbhc_micb_adjust_voltage: adjust specific micbias voltage - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * * @req_volt: micbias voltage to be set * @micb_num: micbias to be set, e.g. micbias1 or micbias2 * * return 0 if adjustment is success or error code in case of failure */ -int aqt_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, +int aqt_mbhc_micb_adjust_voltage(struct snd_soc_component *component, int req_volt, int micb_num) { struct aqt1000 *aqt; @@ -693,8 +723,8 @@ int aqt_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, int micb_reg, micb_val, micb_en; int ret = 0; - if (!codec) { - pr_err("%s: Invalid codec pointer\n", __func__); + if (!component) { + pr_err("%s: Invalid component pointer\n", __func__); return -EINVAL; } @@ -703,7 +733,7 @@ int aqt_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, else micb_reg = AQT1000_ANA_MICB1; - aqt = snd_soc_codec_get_drvdata(codec); + aqt = snd_soc_component_get_drvdata(component); mutex_lock(&aqt->micb_lock); /* @@ -714,7 +744,7 @@ int aqt_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, * momentarily, change the micbias value and then re-enable * micbias. */ - micb_val = snd_soc_read(codec, micb_reg); + micb_val = snd_soc_component_read32(component, micb_reg); micb_en = (micb_val & 0xC0) >> 6; cur_vout_ctl = micb_val & 0x3F; @@ -728,17 +758,17 @@ int aqt_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, goto exit; } - dev_dbg(codec->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n", + dev_dbg(component->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n", __func__, micb_num, AQT_VOUT_CTL_TO_MICB(cur_vout_ctl), req_volt, micb_en); if (micb_en == 0x1) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + snd_soc_component_update_bits(component, micb_reg, 0xC0, 0x80); - snd_soc_update_bits(codec, micb_reg, 0x3F, req_vout_ctl); + snd_soc_component_update_bits(component, micb_reg, 0x3F, req_vout_ctl); if (micb_en == 0x1) { - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + snd_soc_component_update_bits(component, micb_reg, 0xC0, 0x40); /* * Add 2ms delay as per HW requirement after enabling * micbias @@ -754,17 +784,17 @@ EXPORT_SYMBOL(aqt_mbhc_micb_adjust_voltage); /* * aqt_micbias_control: enable/disable micbias - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * * @micb_num: micbias to be enabled/disabled, e.g. micbias1 or micbias2 * @req: control requested, enable/disable or pullup enable/disable * @is_dapm: triggered by dapm or not * * return 0 if control is success or error code in case of failure */ -int aqt_micbias_control(struct snd_soc_codec *codec, +int aqt_micbias_control(struct snd_soc_component *component, int micb_num, int req, bool is_dapm) { - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); u16 micb_reg; int pre_off_event = 0, post_off_event = 0; int post_on_event = 0, post_dapm_off = 0; @@ -781,7 +811,7 @@ int aqt_micbias_control(struct snd_soc_codec *codec, post_dapm_off = AQT_EVENT_POST_DAPM_MICBIAS_1_OFF; break; default: - dev_err(codec->dev, "%s: Invalid micbias number: %d\n", + dev_err(component->dev, "%s: Invalid micbias number: %d\n", __func__, micb_num); return -EINVAL; } @@ -792,19 +822,22 @@ int aqt_micbias_control(struct snd_soc_codec *codec, aqt->pullup_ref++; if ((aqt->pullup_ref == 1) && (aqt->micb_ref == 0)) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x80); break; case MICB_PULLUP_DISABLE: if (aqt->pullup_ref > 0) aqt->pullup_ref--; if ((aqt->pullup_ref == 0) && (aqt->micb_ref == 0)) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x00); break; case MICB_ENABLE: aqt->micb_ref++; if (aqt->micb_ref == 1) { - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x40); if (post_on_event && aqt->mbhc) blocking_notifier_call_chain( &aqt->mbhc->notifier, @@ -820,7 +853,8 @@ int aqt_micbias_control(struct snd_soc_codec *codec, aqt->micb_ref--; if ((aqt->micb_ref == 0) && (aqt->pullup_ref > 0)) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x80); else if ((aqt->micb_ref == 0) && (aqt->pullup_ref == 0)) { if (pre_off_event && aqt->mbhc) @@ -828,7 +862,8 @@ int aqt_micbias_control(struct snd_soc_codec *codec, &aqt->mbhc->notifier, pre_off_event, &aqt->mbhc->wcd_mbhc); - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x00); if (post_off_event && aqt->mbhc) blocking_notifier_call_chain( &aqt->mbhc->notifier, @@ -840,14 +875,14 @@ int aqt_micbias_control(struct snd_soc_codec *codec, post_dapm_off, &aqt->mbhc->wcd_mbhc); break; default: - dev_err(codec->dev, "%s: Invalid micbias request: %d\n", + dev_err(component->dev, "%s: Invalid micbias request: %d\n", __func__, req); ret = -EINVAL; break; }; if (!ret) - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", __func__, micb_num, aqt->micb_ref, aqt->pullup_ref); @@ -860,10 +895,11 @@ EXPORT_SYMBOL(aqt_micbias_control); static int __aqt_codec_enable_micbias(struct snd_soc_dapm_widget *w, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); int micb_num; - dev_dbg(codec->dev, "%s: wname: %s, event: %d\n", + dev_dbg(component->dev, "%s: wname: %s, event: %d\n", __func__, w->name, event); if (strnstr(w->name, "AQT MIC BIAS1", sizeof("AQT MIC BIAS1"))) @@ -878,14 +914,14 @@ static int __aqt_codec_enable_micbias(struct snd_soc_dapm_widget *w, * so use ref count to handle micbias pullup * and enable requests */ - aqt_micbias_control(codec, micb_num, MICB_ENABLE, true); + aqt_micbias_control(component, micb_num, MICB_ENABLE, true); break; case SND_SOC_DAPM_POST_PMU: /* wait for cnp time */ usleep_range(1000, 1100); break; case SND_SOC_DAPM_POST_PMD: - aqt_micbias_control(codec, micb_num, MICB_DISABLE, true); + aqt_micbias_control(component, micb_num, MICB_DISABLE, true); break; }; @@ -898,28 +934,30 @@ static int aqt_codec_enable_micbias(struct snd_soc_dapm_widget *w, return __aqt_codec_enable_micbias(w, event); } -static int aqt_codec_enable_i2s_block(struct snd_soc_codec *codec) +static int aqt_codec_enable_i2s_block(struct snd_soc_component *component) { - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); mutex_lock(&aqt->i2s_lock); if (++aqt->i2s_users == 1) - snd_soc_update_bits(codec, AQT1000_I2S_I2S_0_CTL, 0x01, 0x01); + snd_soc_component_update_bits(component, AQT1000_I2S_I2S_0_CTL, + 0x01, 0x01); mutex_unlock(&aqt->i2s_lock); return 0; } -static int aqt_codec_disable_i2s_block(struct snd_soc_codec *codec) +static int aqt_codec_disable_i2s_block(struct snd_soc_component *component) { - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); mutex_lock(&aqt->i2s_lock); if (--aqt->i2s_users == 0) - snd_soc_update_bits(codec, AQT1000_I2S_I2S_0_CTL, 0x01, 0x00); + snd_soc_component_update_bits(component, AQT1000_I2S_I2S_0_CTL, + 0x01, 0x00); if (aqt->i2s_users < 0) - dev_warn(codec->dev, "%s: i2s_users count (%d) < 0\n", + dev_warn(component->dev, "%s: i2s_users count (%d) < 0\n", __func__, aqt->i2s_users); mutex_unlock(&aqt->i2s_lock); @@ -930,17 +968,18 @@ static int aqt_codec_enable_i2s_tx(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); switch (event) { case SND_SOC_DAPM_PRE_PMU: - aqt_codec_enable_i2s_block(codec); + aqt_codec_enable_i2s_block(component); break; case SND_SOC_DAPM_POST_PMD: - aqt_codec_disable_i2s_block(codec); + aqt_codec_disable_i2s_block(component); break; } - dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); + dev_dbg(component->dev, "%s: event: %d\n", __func__, event); return 0; } @@ -949,17 +988,18 @@ static int aqt_codec_enable_i2s_rx(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); switch (event) { case SND_SOC_DAPM_PRE_PMU: - aqt_codec_enable_i2s_block(codec); + aqt_codec_enable_i2s_block(component); break; case SND_SOC_DAPM_POST_PMD: - aqt_codec_disable_i2s_block(codec); + aqt_codec_disable_i2s_block(component); break; } - dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); + dev_dbg(component->dev, "%s: event: %d\n", __func__, event); return 0; } @@ -980,7 +1020,8 @@ AQT_DAPM_ENUM(tx_adc1, AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0, AQT_DAPM_ENUM(tx_adc2, AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0, tx_adc_mux_text); -static int aqt_find_amic_input(struct snd_soc_codec *codec, int adc_mux_n) +static int aqt_find_amic_input(struct snd_soc_component *component, + int adc_mux_n) { u8 mask; u16 adc_mux_in_reg = 0, amic_mux_sel_reg = 0; @@ -996,14 +1037,17 @@ static int aqt_find_amic_input(struct snd_soc_codec *codec, int adc_mux_n) amic_mux_sel_reg = AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + 2 * adc_mux_n; } - is_amic = (((snd_soc_read(codec, adc_mux_in_reg) & mask)) == 0); + is_amic = ( + ((snd_soc_component_read32(component, adc_mux_in_reg) + & mask)) == 0); if (!is_amic) return 0; - return snd_soc_read(codec, amic_mux_sel_reg) & 0x07; + return snd_soc_component_read32(component, amic_mux_sel_reg) & 0x07; } -static u16 aqt_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic) +static u16 aqt_codec_get_amic_pwlvl_reg( + struct snd_soc_component *component, int amic) { u16 pwr_level_reg = 0; @@ -1016,7 +1060,7 @@ static u16 aqt_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic) pwr_level_reg = AQT1000_ANA_AMIC3; break; default: - dev_dbg(codec->dev, "%s: invalid amic: %d\n", + dev_dbg(component->dev, "%s: invalid amic: %d\n", __func__, amic); break; } @@ -1029,7 +1073,7 @@ static void aqt_tx_hpf_corner_freq_callback(struct work_struct *work) struct delayed_work *hpf_delayed_work; struct hpf_work *hpf_work; struct aqt1000 *aqt; - struct snd_soc_codec *codec; + struct snd_soc_component *component; u16 dec_cfg_reg, amic_reg, go_bit_reg; u8 hpf_cut_off_freq; int amic_n; @@ -1037,26 +1081,27 @@ static void aqt_tx_hpf_corner_freq_callback(struct work_struct *work) hpf_delayed_work = to_delayed_work(work); hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); aqt = hpf_work->aqt; - codec = aqt->codec; + component = aqt->component; hpf_cut_off_freq = hpf_work->hpf_cut_off_freq; dec_cfg_reg = AQT1000_CDC_TX0_TX_PATH_CFG0 + 16 * hpf_work->decimator; go_bit_reg = dec_cfg_reg + 7; - dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", + dev_dbg(component->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", __func__, hpf_work->decimator, hpf_cut_off_freq); - amic_n = aqt_find_amic_input(codec, hpf_work->decimator); + amic_n = aqt_find_amic_input(component, hpf_work->decimator); if (amic_n) { amic_reg = AQT1000_ANA_AMIC1 + amic_n - 1; - aqt_codec_set_tx_hold(codec, amic_reg, false); + aqt_codec_set_tx_hold(component, amic_reg, false); } - snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, - hpf_cut_off_freq << 5); - snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x02); + snd_soc_component_update_bits(component, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_component_update_bits(component, go_bit_reg, 0x02, 0x02); /* Minimum 1 clk cycle delay is required as per HW spec */ usleep_range(1000, 1010); - snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x00); + snd_soc_component_update_bits(component, go_bit_reg, 0x02, 0x00); } static void aqt_tx_mute_update_callback(struct work_struct *work) @@ -1064,26 +1109,27 @@ static void aqt_tx_mute_update_callback(struct work_struct *work) struct tx_mute_work *tx_mute_dwork; struct aqt1000 *aqt; struct delayed_work *delayed_work; - struct snd_soc_codec *codec; + struct snd_soc_component *component; u16 tx_vol_ctl_reg, hpf_gate_reg; delayed_work = to_delayed_work(work); tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); aqt = tx_mute_dwork->aqt; - codec = aqt->codec; + component = aqt->component; tx_vol_ctl_reg = AQT1000_CDC_TX0_TX_PATH_CTL + 16 * tx_mute_dwork->decimator; hpf_gate_reg = AQT1000_CDC_TX0_TX_PATH_SEC2 + 16 * tx_mute_dwork->decimator; - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x00); } static int aqt_codec_enable_dec(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); char *widget_name = NULL; char *dec = NULL; unsigned int decimator = 0; @@ -1093,14 +1139,14 @@ static int aqt_codec_enable_dec(struct snd_soc_dapm_widget *w, int ret = 0; u8 hpf_cut_off_freq; - dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); + dev_dbg(component->dev, "%s: event: %d\n", __func__, event); widget_name = kstrndup(w->name, 15, GFP_KERNEL); if (!widget_name) return -ENOMEM; dec = strpbrk(widget_name, "012"); if (!dec) { - dev_err(codec->dev, "%s: decimator index not found\n", + dev_err(component->dev, "%s: decimator index not found\n", __func__); ret = -EINVAL; goto out; @@ -1108,12 +1154,12 @@ static int aqt_codec_enable_dec(struct snd_soc_dapm_widget *w, ret = kstrtouint(dec, 10, &decimator); if (ret < 0) { - dev_err(codec->dev, "%s: Invalid decimator = %s\n", + dev_err(component->dev, "%s: Invalid decimator = %s\n", __func__, widget_name); ret = -EINVAL; goto out; } - dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__, + dev_dbg(component->dev, "%s(): widget = %s decimator = %u\n", __func__, w->name, decimator); tx_vol_ctl_reg = AQT1000_CDC_TX0_TX_PATH_CTL + 16 * decimator; @@ -1121,56 +1167,64 @@ static int aqt_codec_enable_dec(struct snd_soc_dapm_widget *w, dec_cfg_reg = AQT1000_CDC_TX0_TX_PATH_CFG0 + 16 * decimator; tx_gain_ctl_reg = AQT1000_CDC_TX0_TX_VOL_CTL + 16 * decimator; - amic_n = aqt_find_amic_input(codec, decimator); + amic_n = aqt_find_amic_input(component, decimator); switch (event) { case SND_SOC_DAPM_PRE_PMU: if (amic_n) - pwr_level_reg = aqt_codec_get_amic_pwlvl_reg(codec, + pwr_level_reg = aqt_codec_get_amic_pwlvl_reg(component, amic_n); if (pwr_level_reg) { - switch ((snd_soc_read(codec, pwr_level_reg) & - AQT1000_AMIC_PWR_LVL_MASK) >> - AQT1000_AMIC_PWR_LVL_SHIFT) { + switch ((snd_soc_component_read32( + component, pwr_level_reg) & + AQT1000_AMIC_PWR_LVL_MASK) >> + AQT1000_AMIC_PWR_LVL_SHIFT) { case AQT1000_AMIC_PWR_LEVEL_LP: - snd_soc_update_bits(codec, dec_cfg_reg, - AQT1000_DEC_PWR_LVL_MASK, - AQT1000_DEC_PWR_LVL_LP); + snd_soc_component_update_bits( + component, dec_cfg_reg, + AQT1000_DEC_PWR_LVL_MASK, + AQT1000_DEC_PWR_LVL_LP); break; case AQT1000_AMIC_PWR_LEVEL_HP: - snd_soc_update_bits(codec, dec_cfg_reg, - AQT1000_DEC_PWR_LVL_MASK, - AQT1000_DEC_PWR_LVL_HP); + snd_soc_component_update_bits( + component, dec_cfg_reg, + AQT1000_DEC_PWR_LVL_MASK, + AQT1000_DEC_PWR_LVL_HP); break; case AQT1000_AMIC_PWR_LEVEL_DEFAULT: default: - snd_soc_update_bits(codec, dec_cfg_reg, - AQT1000_DEC_PWR_LVL_MASK, - AQT1000_DEC_PWR_LVL_DF); + snd_soc_component_update_bits( + component, dec_cfg_reg, + AQT1000_DEC_PWR_LVL_MASK, + AQT1000_DEC_PWR_LVL_DF); break; } } /* Enable TX PGA Mute */ - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x10, 0x10); break; case SND_SOC_DAPM_POST_PMU: - hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) & - TX_HPF_CUT_OFF_FREQ_MASK) >> 5; + hpf_cut_off_freq = (snd_soc_component_read32( + component, dec_cfg_reg) & + TX_HPF_CUT_OFF_FREQ_MASK) >> 5; aqt->tx_hpf_work[decimator].hpf_cut_off_freq = hpf_cut_off_freq; if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { - snd_soc_update_bits(codec, dec_cfg_reg, + snd_soc_component_update_bits(component, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, CF_MIN_3DB_150HZ << 5); - snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); + snd_soc_component_update_bits(component, hpf_gate_reg, + 0x02, 0x02); /* * Minimum 1 clk cycle delay is required as per * HW spec. */ usleep_range(1000, 1010); - snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00); + snd_soc_component_update_bits(component, hpf_gate_reg, + 0x02, 0x00); } /* schedule work queue to Remove Mute */ schedule_delayed_work(&aqt->tx_mute_dwork[decimator].dwork, @@ -1181,36 +1235,42 @@ static int aqt_codec_enable_dec(struct snd_soc_dapm_widget *w, &aqt->tx_hpf_work[decimator].dwork, msecs_to_jiffies(300)); /* apply gain after decimator is enabled */ - snd_soc_write(codec, tx_gain_ctl_reg, - snd_soc_read(codec, tx_gain_ctl_reg)); + snd_soc_component_write(component, tx_gain_ctl_reg, + snd_soc_component_read32( + component, tx_gain_ctl_reg)); break; case SND_SOC_DAPM_PRE_PMD: hpf_cut_off_freq = aqt->tx_hpf_work[decimator].hpf_cut_off_freq; - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x10, 0x10); if (cancel_delayed_work_sync( &aqt->tx_hpf_work[decimator].dwork)) { if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { - snd_soc_update_bits(codec, dec_cfg_reg, - TX_HPF_CUT_OFF_FREQ_MASK, - hpf_cut_off_freq << 5); - snd_soc_update_bits(codec, hpf_gate_reg, - 0x02, 0x02); + snd_soc_component_update_bits( + component, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_component_update_bits( + component, hpf_gate_reg, + 0x02, 0x02); /* * Minimum 1 clk cycle delay is required as per * HW spec. */ usleep_range(1000, 1010); - snd_soc_update_bits(codec, hpf_gate_reg, - 0x02, 0x00); + snd_soc_component_update_bits( + component, hpf_gate_reg, + 0x02, 0x00); } } cancel_delayed_work_sync( &aqt->tx_mute_dwork[decimator].dwork); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); - snd_soc_update_bits(codec, dec_cfg_reg, + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x10, 0x00); + snd_soc_component_update_bits(component, dec_cfg_reg, AQT1000_DEC_PWR_LVL_MASK, AQT1000_DEC_PWR_LVL_DF); break; @@ -1240,11 +1300,12 @@ AQT_DAPM_ENUM(tx_amic13, AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 0, static int aqt_codec_enable_adc(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); switch (event) { case SND_SOC_DAPM_PRE_PMU: - aqt_codec_set_tx_hold(codec, w->reg, true); + aqt_codec_set_tx_hold(component, w->reg, true); break; default: break; @@ -1259,15 +1320,15 @@ static const struct snd_kcontrol_new anc_hphl_pa_switch = static const struct snd_kcontrol_new anc_hphr_pa_switch = SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); -static int aqt_config_compander(struct snd_soc_codec *codec, int interp_n, - int event) +static int aqt_config_compander(struct snd_soc_component *component, + int interp_n, int event) { - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); int comp; u16 comp_ctl0_reg, rx_path_cfg0_reg; comp = interp_n; - dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n", + dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n", __func__, event, comp, aqt->comp_enabled[comp]); if (!aqt->comp_enabled[comp]) @@ -1278,29 +1339,39 @@ static int aqt_config_compander(struct snd_soc_codec *codec, int interp_n, if (SND_SOC_DAPM_EVENT_ON(event)) { /* Enable Compander Clock */ - snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02); + snd_soc_component_update_bits( + component, comp_ctl0_reg, 0x01, 0x01); + snd_soc_component_update_bits( + component, comp_ctl0_reg, 0x02, 0x02); + snd_soc_component_update_bits( + component, comp_ctl0_reg, 0x02, 0x00); + snd_soc_component_update_bits( + component, rx_path_cfg0_reg, 0x02, 0x02); } if (SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); + snd_soc_component_update_bits( + component, rx_path_cfg0_reg, 0x02, 0x00); + snd_soc_component_update_bits( + component, comp_ctl0_reg, 0x04, 0x04); + snd_soc_component_update_bits( + component, comp_ctl0_reg, 0x02, 0x02); + snd_soc_component_update_bits( + component, comp_ctl0_reg, 0x02, 0x00); + snd_soc_component_update_bits( + component, comp_ctl0_reg, 0x01, 0x00); + snd_soc_component_update_bits( + component, comp_ctl0_reg, 0x04, 0x00); } return 0; } -static void aqt_codec_idle_detect_control(struct snd_soc_codec *codec, +static void aqt_codec_idle_detect_control(struct snd_soc_component *component, int interp, int event) { int reg = 0, mask, val; - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); if (!aqt->idle_det_cfg.hph_idle_detect_en) return; @@ -1317,19 +1388,20 @@ static void aqt_codec_idle_detect_control(struct snd_soc_codec *codec, } if (reg && SND_SOC_DAPM_EVENT_ON(event)) - snd_soc_update_bits(codec, reg, mask, val); + snd_soc_component_update_bits(component, reg, mask, val); if (reg && SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, reg, mask, 0x00); + snd_soc_component_update_bits(component, reg, mask, 0x00); aqt->idle_det_cfg.hph_idle_thr = 0; - snd_soc_write(codec, AQT1000_CDC_RX_IDLE_DET_CFG3, 0x0); + snd_soc_component_write(component, + AQT1000_CDC_RX_IDLE_DET_CFG3, 0x0); } } -static void aqt_codec_hphdelay_lutbypass(struct snd_soc_codec *codec, +static void aqt_codec_hphdelay_lutbypass(struct snd_soc_component *component, u16 interp_idx, int event) { - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); u8 hph_dly_mask; u16 hph_lut_bypass_reg = 0; u16 hph_comp_ctrl7 = 0; @@ -1351,48 +1423,55 @@ static void aqt_codec_hphdelay_lutbypass(struct snd_soc_codec *codec, } if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) { - snd_soc_update_bits(codec, AQT1000_CDC_CLSH_TEST0, - hph_dly_mask, 0x0); - snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x80); + snd_soc_component_update_bits(component, AQT1000_CDC_CLSH_TEST0, + hph_dly_mask, 0x0); + snd_soc_component_update_bits(component, hph_lut_bypass_reg, + 0x80, 0x80); if (aqt->hph_mode == CLS_H_ULP) - snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x20); + snd_soc_component_update_bits(component, hph_comp_ctrl7, + 0x20, 0x20); } if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, AQT1000_CDC_CLSH_TEST0, - hph_dly_mask, hph_dly_mask); - snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x00); - snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x0); + snd_soc_component_update_bits(component, AQT1000_CDC_CLSH_TEST0, + hph_dly_mask, hph_dly_mask); + snd_soc_component_update_bits(component, hph_lut_bypass_reg, + 0x80, 0x00); + snd_soc_component_update_bits(component, hph_comp_ctrl7, + 0x20, 0x0); } } -static int aqt_codec_enable_interp_clk(struct snd_soc_codec *codec, +static int aqt_codec_enable_interp_clk(struct snd_soc_component *component, int event, int interp_idx) { struct aqt1000 *aqt; u16 main_reg, dsm_reg; - if (!codec) { - pr_err("%s: codec is NULL\n", __func__); + if (!component) { + pr_err("%s: component is NULL\n", __func__); return -EINVAL; } - aqt = snd_soc_codec_get_drvdata(codec); + aqt = snd_soc_component_get_drvdata(component); main_reg = AQT1000_CDC_RX1_RX_PATH_CTL + (interp_idx * 20); dsm_reg = AQT1000_CDC_RX1_RX_PATH_DSMDEM_CTL + (interp_idx * 20); if (SND_SOC_DAPM_EVENT_ON(event)) { if (aqt->main_clk_users[interp_idx] == 0) { /* Main path PGA mute enable */ - snd_soc_update_bits(codec, main_reg, 0x10, 0x10); + snd_soc_component_update_bits(component, main_reg, + 0x10, 0x10); /* Clk enable */ - snd_soc_update_bits(codec, dsm_reg, 0x01, 0x01); - snd_soc_update_bits(codec, main_reg, 0x20, 0x20); - aqt_codec_idle_detect_control(codec, interp_idx, + snd_soc_component_update_bits(component, dsm_reg, + 0x01, 0x01); + snd_soc_component_update_bits(component, main_reg, + 0x20, 0x20); + aqt_codec_idle_detect_control(component, interp_idx, event); - aqt_codec_hphdelay_lutbypass(codec, interp_idx, + aqt_codec_hphdelay_lutbypass(component, interp_idx, event); - aqt_config_compander(codec, interp_idx, event); + aqt_config_compander(component, interp_idx, event); } aqt->main_clk_users[interp_idx]++; } @@ -1401,23 +1480,28 @@ static int aqt_codec_enable_interp_clk(struct snd_soc_codec *codec, aqt->main_clk_users[interp_idx]--; if (aqt->main_clk_users[interp_idx] <= 0) { aqt->main_clk_users[interp_idx] = 0; - aqt_config_compander(codec, interp_idx, event); - aqt_codec_hphdelay_lutbypass(codec, interp_idx, + aqt_config_compander(component, interp_idx, event); + aqt_codec_hphdelay_lutbypass(component, interp_idx, event); - aqt_codec_idle_detect_control(codec, interp_idx, + aqt_codec_idle_detect_control(component, interp_idx, event); /* Clk Disable */ - snd_soc_update_bits(codec, main_reg, 0x20, 0x00); - snd_soc_update_bits(codec, dsm_reg, 0x01, 0x00); + snd_soc_component_update_bits(component, main_reg, + 0x20, 0x00); + snd_soc_component_update_bits(component, dsm_reg, + 0x01, 0x00); /* Reset enable and disable */ - snd_soc_update_bits(codec, main_reg, 0x40, 0x40); - snd_soc_update_bits(codec, main_reg, 0x40, 0x00); + snd_soc_component_update_bits(component, main_reg, + 0x40, 0x40); + snd_soc_component_update_bits(component, main_reg, + 0x40, 0x00); /* Reset rate to 48K*/ - snd_soc_update_bits(codec, main_reg, 0x0F, 0x04); + snd_soc_component_update_bits(component, main_reg, + 0x0F, 0x04); } } - dev_dbg(codec->dev, "%s event %d main_clk_users %d\n", + dev_dbg(component->dev, "%s event %d main_clk_users %d\n", __func__, event, aqt->main_clk_users[interp_idx]); return aqt->main_clk_users[interp_idx]; @@ -1426,9 +1510,10 @@ static int aqt_codec_enable_interp_clk(struct snd_soc_codec *codec, static int aqt_anc_out_switch_cb(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); - aqt_codec_enable_interp_clk(codec, event, w->shift); + aqt_codec_enable_interp_clk(component, event, w->shift); return 0; } @@ -1473,14 +1558,14 @@ AQT_DAPM_ENUM(rx_int2_1, AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, AQT_DAPM_ENUM(rx_int2_2, AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, rx_int2_2_mux_text); -static int aqt_codec_set_idle_detect_thr(struct snd_soc_codec *codec, +static int aqt_codec_set_idle_detect_thr(struct snd_soc_component *component, int interp, int path_type) { int port_id[4] = { 0, 0, 0, 0 }; int *port_ptr, num_ports; int bit_width = 0; int mux_reg = 0, mux_reg_val = 0; - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); int idle_thr; if ((interp != INTERP_HPHL) && (interp != INTERP_HPHR)) @@ -1505,12 +1590,13 @@ static int aqt_codec_set_idle_detect_thr(struct snd_soc_codec *codec, else mux_reg = AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0; } - mux_reg_val = snd_soc_read(codec, mux_reg); + mux_reg_val = snd_soc_component_read32(component, mux_reg); /* Read bit width from I2S reg if mux is set to I2S0_L or I2S0_R */ if (mux_reg_val == 0x02 || mux_reg_val == 0x03) - bit_width = ((snd_soc_read(codec, AQT1000_I2S_I2S_0_CTL) & - 0x40) >> 6); + bit_width = ((snd_soc_component_read32( + component, AQT1000_I2S_I2S_0_CTL) & + 0x40) >> 6); switch (bit_width) { case 1: /* 16 bit */ @@ -1522,12 +1608,13 @@ static int aqt_codec_set_idle_detect_thr(struct snd_soc_codec *codec, break; } - dev_dbg(codec->dev, "%s: (new) idle_thr: %d, (cur) idle_thr: %d\n", + dev_dbg(component->dev, "%s: (new) idle_thr: %d, (cur) idle_thr: %d\n", __func__, idle_thr, aqt->idle_det_cfg.hph_idle_thr); if ((aqt->idle_det_cfg.hph_idle_thr == 0) || (idle_thr < aqt->idle_det_cfg.hph_idle_thr)) { - snd_soc_write(codec, AQT1000_CDC_RX_IDLE_DET_CFG3, idle_thr); + snd_soc_component_write(component, AQT1000_CDC_RX_IDLE_DET_CFG3, + idle_thr); aqt->idle_det_cfg.hph_idle_thr = idle_thr; } @@ -1538,14 +1625,15 @@ static int aqt_codec_enable_main_path(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); u16 gain_reg = 0; int val = 0; - dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name); if (w->shift >= AQT1000_NUM_INTERPOLATORS) { - dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", + dev_err(component->dev, "%s: Invalid Interpolator value %d for name %s\n", __func__, w->shift, w->name); return -EINVAL; }; @@ -1555,17 +1643,17 @@ static int aqt_codec_enable_main_path(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - aqt_codec_enable_interp_clk(codec, event, w->shift); + aqt_codec_enable_interp_clk(component, event, w->shift); break; case SND_SOC_DAPM_POST_PMU: - aqt_codec_set_idle_detect_thr(codec, w->shift, + aqt_codec_set_idle_detect_thr(component, w->shift, INTERP_MAIN_PATH); /* apply gain after int clk is enabled */ - val = snd_soc_read(codec, gain_reg); - snd_soc_write(codec, gain_reg, val); + val = snd_soc_component_read32(component, gain_reg); + snd_soc_component_write(component, gain_reg, val); break; case SND_SOC_DAPM_POST_PMD: - aqt_codec_enable_interp_clk(codec, event, w->shift); + aqt_codec_enable_interp_clk(component, event, w->shift); break; }; @@ -1576,12 +1664,13 @@ static int aqt_codec_enable_mix_path(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); u16 gain_reg = 0; u16 mix_reg = 0; if (w->shift >= AQT1000_NUM_INTERPOLATORS) { - dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", + dev_err(component->dev, "%s: Invalid Interpolator value %d for name %s\n", __func__, w->shift, w->name); return -EINVAL; }; @@ -1592,25 +1681,26 @@ static int aqt_codec_enable_mix_path(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - aqt_codec_enable_interp_clk(codec, event, w->shift); + aqt_codec_enable_interp_clk(component, event, w->shift); /* Clk enable */ - snd_soc_update_bits(codec, mix_reg, 0x20, 0x20); + snd_soc_component_update_bits(component, mix_reg, 0x20, 0x20); break; case SND_SOC_DAPM_POST_PMU: - aqt_codec_set_idle_detect_thr(codec, w->shift, + aqt_codec_set_idle_detect_thr(component, w->shift, INTERP_MIX_PATH); break; case SND_SOC_DAPM_POST_PMD: /* Clk Disable */ - snd_soc_update_bits(codec, mix_reg, 0x20, 0x00); - aqt_codec_enable_interp_clk(codec, event, w->shift); + snd_soc_component_update_bits(component, mix_reg, 0x20, 0x00); + aqt_codec_enable_interp_clk(component, event, w->shift); /* Reset enable and disable */ - snd_soc_update_bits(codec, mix_reg, 0x40, 0x40); - snd_soc_update_bits(codec, mix_reg, 0x40, 0x00); + snd_soc_component_update_bits(component, mix_reg, 0x40, 0x40); + snd_soc_component_update_bits(component, mix_reg, 0x40, 0x00); break; }; - dev_dbg(codec->dev, "%s event %d name %s\n", __func__, event, w->name); + dev_dbg(component->dev, "%s event %d name %s\n", __func__, + event, w->name); return 0; } @@ -1693,8 +1783,9 @@ static int aqt_codec_enable_asrc_resampler(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); int asrc = 0, ret = 0; u8 cfg; u16 cfg_reg = 0; @@ -1705,9 +1796,10 @@ static int aqt_codec_enable_asrc_resampler(struct snd_soc_dapm_widget *w, u16 paired_reg = 0; u8 main_sr, mix_sr, asrc_mode = 0; - cfg = snd_soc_read(codec, AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0); + cfg = snd_soc_component_read32(component, + AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0); if (!(cfg & 0xFF)) { - dev_err(codec->dev, "%s: ASRC%u input not selected\n", + dev_err(component->dev, "%s: ASRC%u input not selected\n", __func__, w->shift); return -EINVAL; } @@ -1732,7 +1824,7 @@ static int aqt_codec_enable_asrc_resampler(struct snd_soc_dapm_widget *w, } break; default: - dev_err(codec->dev, "%s: Invalid asrc:%u\n", __func__, + dev_err(component->dev, "%s: Invalid asrc:%u\n", __func__, w->shift); ret = -EINVAL; break; @@ -1744,26 +1836,30 @@ static int aqt_codec_enable_asrc_resampler(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - if ((snd_soc_read(codec, clk_reg) & 0x02) || - (snd_soc_read(codec, paired_reg) & 0x02)) { - snd_soc_update_bits(codec, clk_reg, 0x02, 0x00); - snd_soc_update_bits(codec, paired_reg, 0x02, 0x00); + if ((snd_soc_component_read32(component, clk_reg) & 0x02) || + (snd_soc_component_read32(component, paired_reg) & 0x02)) { + snd_soc_component_update_bits(component, clk_reg, + 0x02, 0x00); + snd_soc_component_update_bits(component, paired_reg, + 0x02, 0x00); } - snd_soc_update_bits(codec, cfg_reg, 0x80, 0x80); - snd_soc_update_bits(codec, clk_reg, 0x01, 0x01); - main_sr = snd_soc_read(codec, ctl_reg) & 0x0F; + snd_soc_component_update_bits(component, cfg_reg, 0x80, 0x80); + snd_soc_component_update_bits(component, clk_reg, 0x01, 0x01); + main_sr = snd_soc_component_read32(component, ctl_reg) & 0x0F; mix_ctl_reg = ctl_reg + 5; - mix_sr = snd_soc_read(codec, mix_ctl_reg) & 0x0F; + mix_sr = snd_soc_component_read32( + component, mix_ctl_reg) & 0x0F; asrc_mode = aqt_get_asrc_mode(aqt, asrc, main_sr, mix_sr); - dev_dbg(codec->dev, "%s: main_sr:%d mix_sr:%d asrc_mode %d\n", + dev_dbg(component->dev, "%s: main_sr:%d mix_sr:%d asrc_mode %d\n", __func__, main_sr, mix_sr, asrc_mode); - snd_soc_update_bits(codec, asrc_ctl, 0x07, asrc_mode); + snd_soc_component_update_bits( + component, asrc_ctl, 0x07, asrc_mode); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, asrc_ctl, 0x07, 0x00); - snd_soc_update_bits(codec, cfg_reg, 0x80, 0x00); - snd_soc_update_bits(codec, clk_reg, 0x03, 0x02); + snd_soc_component_update_bits(component, asrc_ctl, 0x07, 0x00); + snd_soc_component_update_bits(component, cfg_reg, 0x80, 0x00); + snd_soc_component_update_bits(component, clk_reg, 0x03, 0x02); break; }; @@ -1774,8 +1870,9 @@ static int aqt_codec_enable_asrc_resampler(struct snd_soc_dapm_widget *w, static int aqt_codec_enable_anc(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); const char *filename; const struct firmware *fw; int i; @@ -1801,28 +1898,28 @@ static int aqt_codec_enable_anc(struct snd_soc_dapm_widget *w, if (hwdep_cal) { data = hwdep_cal->data; cal_size = hwdep_cal->size; - dev_dbg(codec->dev, "%s: using hwdep calibration, cal_size %zd", + dev_dbg(component->dev, "%s: using hwdep calibration, cal_size %zd", __func__, cal_size); } else { filename = "AQT1000/AQT1000_anc.bin"; - ret = request_firmware(&fw, filename, codec->dev); + ret = request_firmware(&fw, filename, component->dev); if (ret < 0) { - dev_err(codec->dev, "%s: Failed to acquire ANC data: %d\n", + dev_err(component->dev, "%s: Failed to acquire ANC data: %d\n", __func__, ret); return ret; } if (!fw) { - dev_err(codec->dev, "%s: Failed to get anc fw\n", + dev_err(component->dev, "%s: Failed to get anc fw\n", __func__); return -ENODEV; } data = fw->data; cal_size = fw->size; - dev_dbg(codec->dev, "%s: using request_firmware calibration\n", + dev_dbg(component->dev, "%s: using request_firmware calibration\n", __func__); } if (cal_size < sizeof(struct aqt1000_anc_header)) { - dev_err(codec->dev, "%s: Invalid cal_size %zd\n", + dev_err(component->dev, "%s: Invalid cal_size %zd\n", __func__, cal_size); ret = -EINVAL; goto err; @@ -1835,14 +1932,14 @@ static int aqt_codec_enable_anc(struct snd_soc_dapm_widget *w, num_anc_slots = anc_head->num_anc_slots; if (aqt->anc_slot >= num_anc_slots) { - dev_err(codec->dev, "%s: Invalid ANC slot selected\n", + dev_err(component->dev, "%s: Invalid ANC slot selected\n", __func__); ret = -EINVAL; goto err; } for (i = 0; i < num_anc_slots; i++) { if (anc_size_remaining < AQT1000_PACKED_REG_SIZE) { - dev_err(codec->dev, "%s: Invalid register format\n", + dev_err(component->dev, "%s: Invalid register format\n", __func__); ret = -EINVAL; goto err; @@ -1853,7 +1950,7 @@ static int aqt_codec_enable_anc(struct snd_soc_dapm_widget *w, if ((anc_writes_size * AQT1000_PACKED_REG_SIZE) > anc_size_remaining) { - dev_err(codec->dev, "%s: Invalid register format\n", + dev_err(component->dev, "%s: Invalid register format\n", __func__); ret = -EINVAL; goto err; @@ -1867,7 +1964,7 @@ static int aqt_codec_enable_anc(struct snd_soc_dapm_widget *w, anc_ptr += anc_writes_size; } if (i == num_anc_slots) { - dev_err(codec->dev, "%s: Selected ANC slot not present\n", + dev_err(component->dev, "%s: Selected ANC slot not present\n", __func__); ret = -EINVAL; goto err; @@ -1877,36 +1974,36 @@ static int aqt_codec_enable_anc(struct snd_soc_dapm_widget *w, anc_cal_size = anc_writes_size; /* Rate converter clk enable and set bypass mode */ if (!strcmp(w->name, "AQT RX INT1 DAC")) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_ANC0_RC_COMMON_CTL, 0x05, 0x05); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_ANC0_FIFO_COMMON_CTL, 0x66, 0x66); anc_writes_size = anc_cal_size / 2; - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_ANC0_CLK_RESET_CTL, 0x39, 0x39); } else if (!strcmp(w->name, "AQT RX INT2 DAC")) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_ANC1_RC_COMMON_CTL, 0x05, 0x05); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_ANC1_FIFO_COMMON_CTL, 0x66, 0x66); i = anc_cal_size / 2; - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_ANC1_CLK_RESET_CTL, 0x39, 0x39); } for (; i < anc_writes_size; i++) { AQT1000_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val); - snd_soc_write(codec, reg, (val & mask)); + snd_soc_component_write(component, reg, (val & mask)); } if (!strcmp(w->name, "AQT RX INT1 DAC")) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x08); else if (!strcmp(w->name, "AQT RX INT2 DAC")) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x08); if (!hwdep_cal) @@ -1915,53 +2012,58 @@ static int aqt_codec_enable_anc(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: /* Remove ANC Rx from reset */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x00); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, AQT1000_CDC_ANC0_RC_COMMON_CTL, - 0x05, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CDC_ANC0_RC_COMMON_CTL, + 0x05, 0x00); if (!strcmp(w->name, "AQT ANC HPHL PA")) { - snd_soc_update_bits(codec, AQT1000_CDC_ANC0_MODE_1_CTL, - 0x30, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CDC_ANC0_MODE_1_CTL, + 0x30, 0x00); /* 50 msec sleep is needed to avoid click and pop as * per HW requirement */ msleep(50); - snd_soc_update_bits(codec, AQT1000_CDC_ANC0_MODE_1_CTL, - 0x01, 0x00); - snd_soc_update_bits(codec, - AQT1000_CDC_ANC0_CLK_RESET_CTL, - 0x38, 0x38); - snd_soc_update_bits(codec, - AQT1000_CDC_ANC0_CLK_RESET_CTL, - 0x07, 0x00); - snd_soc_update_bits(codec, - AQT1000_CDC_ANC0_CLK_RESET_CTL, - 0x38, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CDC_ANC0_MODE_1_CTL, + 0x01, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CDC_ANC0_CLK_RESET_CTL, + 0x38, 0x38); + snd_soc_component_update_bits(component, + AQT1000_CDC_ANC0_CLK_RESET_CTL, + 0x07, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CDC_ANC0_CLK_RESET_CTL, + 0x38, 0x00); } else if (!strcmp(w->name, "AQT ANC HPHR PA")) { - snd_soc_update_bits(codec, AQT1000_CDC_ANC1_MODE_1_CTL, - 0x30, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CDC_ANC1_MODE_1_CTL, + 0x30, 0x00); /* 50 msec sleep is needed to avoid click and pop as * per HW requirement */ msleep(50); - snd_soc_update_bits(codec, AQT1000_CDC_ANC1_MODE_1_CTL, - 0x01, 0x00); - snd_soc_update_bits(codec, - AQT1000_CDC_ANC1_CLK_RESET_CTL, - 0x38, 0x38); - snd_soc_update_bits(codec, - AQT1000_CDC_ANC1_CLK_RESET_CTL, - 0x07, 0x00); - snd_soc_update_bits(codec, - AQT1000_CDC_ANC1_CLK_RESET_CTL, - 0x38, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CDC_ANC1_MODE_1_CTL, + 0x01, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CDC_ANC1_CLK_RESET_CTL, + 0x38, 0x38); + snd_soc_component_update_bits(component, + AQT1000_CDC_ANC1_CLK_RESET_CTL, + 0x07, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CDC_ANC1_CLK_RESET_CTL, + 0x38, 0x00); } break; } @@ -1973,25 +2075,25 @@ static int aqt_codec_enable_anc(struct snd_soc_dapm_widget *w, return ret; } -static void aqt_codec_override(struct snd_soc_codec *codec, int mode, +static void aqt_codec_override(struct snd_soc_component *component, int mode, int event) { if (mode == CLS_AB || mode == CLS_AB_HIFI) { switch (event) { case SND_SOC_DAPM_PRE_PMU: case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_ANA_RX_SUPPLIES, 0x02, 0x02); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_ANA_RX_SUPPLIES, 0x02, 0x00); break; } } } -static void aqt_codec_set_tx_hold(struct snd_soc_codec *codec, +static void aqt_codec_set_tx_hold(struct snd_soc_component *component, u16 amic_reg, bool set) { u8 mask = 0x20; @@ -2006,13 +2108,15 @@ static void aqt_codec_set_tx_hold(struct snd_soc_codec *codec, switch (amic_reg) { case AQT1000_ANA_AMIC1: case AQT1000_ANA_AMIC2: - snd_soc_update_bits(codec, AQT1000_ANA_AMIC2, mask, val); + snd_soc_component_update_bits(component, AQT1000_ANA_AMIC2, + mask, val); break; case AQT1000_ANA_AMIC3: - snd_soc_update_bits(codec, AQT1000_ANA_AMIC3_HPF, mask, val); + snd_soc_component_update_bits(component, AQT1000_ANA_AMIC3_HPF, + mask, val); break; default: - dev_dbg(codec->dev, "%s: invalid amic: %d\n", + dev_dbg(component->dev, "%s: invalid amic: %d\n", __func__, amic_reg); break; } @@ -2021,11 +2125,11 @@ static void aqt_codec_set_tx_hold(struct snd_soc_codec *codec, static void aqt_codec_clear_anc_tx_hold(struct aqt1000 *aqt) { if (test_and_clear_bit(ANC_MIC_AMIC1, &aqt->status_mask)) - aqt_codec_set_tx_hold(aqt->codec, AQT1000_ANA_AMIC1, false); + aqt_codec_set_tx_hold(aqt->component, AQT1000_ANA_AMIC1, false); if (test_and_clear_bit(ANC_MIC_AMIC2, &aqt->status_mask)) - aqt_codec_set_tx_hold(aqt->codec, AQT1000_ANA_AMIC2, false); + aqt_codec_set_tx_hold(aqt->component, AQT1000_ANA_AMIC2, false); if (test_and_clear_bit(ANC_MIC_AMIC3, &aqt->status_mask)) - aqt_codec_set_tx_hold(aqt->codec, AQT1000_ANA_AMIC3, false); + aqt_codec_set_tx_hold(aqt->component, AQT1000_ANA_AMIC3, false); } static const char * const rx_int_dem_inp_mux_text[] = { @@ -2037,7 +2141,8 @@ static int aqt_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val; unsigned short look_ahead_dly_reg = AQT1000_CDC_RX1_RX_PATH_CFG0; @@ -2046,7 +2151,7 @@ static int aqt_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, if (val >= e->items) return -EINVAL; - dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__, widget->name, val); if (e->reg == AQT1000_CDC_RX1_RX_PATH_SEC0) @@ -2055,7 +2160,7 @@ static int aqt_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, look_ahead_dly_reg = AQT1000_CDC_RX2_RX_PATH_CFG0; /* Set Look Ahead Delay */ - snd_soc_update_bits(codec, look_ahead_dly_reg, + snd_soc_component_update_bits(component, look_ahead_dly_reg, 0x08, (val ? 0x08 : 0x00)); /* Set DEM INP Select */ return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); @@ -2072,16 +2177,17 @@ static int aqt_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); int hph_mode = aqt->hph_mode; u8 dem_inp; int ret = 0; uint32_t impedl = 0; uint32_t impedr = 0; - dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, - w->name, event, hph_mode); + dev_dbg(component->dev, "%s wname: %s event: %d hph_mode: %d\n", + __func__, w->name, event, hph_mode); switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -2091,35 +2197,37 @@ static int aqt_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, msleep(40); } /* Read DEM INP Select */ - dem_inp = snd_soc_read(codec, AQT1000_CDC_RX1_RX_PATH_SEC0) & - 0x03; + dem_inp = snd_soc_component_read32( + component, AQT1000_CDC_RX1_RX_PATH_SEC0) & + 0x03; if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { - dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", + dev_err(component->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", __func__, hph_mode); return -EINVAL; } /* Disable AutoChop timer during power up */ - snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_HPH_TIMER1, - 0x02, 0x00); + snd_soc_component_update_bits(component, + AQT1000_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x00); - aqt_clsh_fsm(codec, &aqt->clsh_d, + aqt_clsh_fsm(component, &aqt->clsh_d, AQT_CLSH_EVENT_PRE_DAC, AQT_CLSH_STATE_HPHL, hph_mode); if (aqt->anc_func) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_RX1_RX_PATH_CFG0, 0x10, 0x10); ret = aqt_mbhc_get_impedance(aqt->mbhc, &impedl, &impedr); if (!ret) { - aqt_clsh_imped_config(codec, impedl, false); + aqt_clsh_imped_config(component, impedl, false); set_bit(CLSH_Z_CONFIG, &aqt->status_mask); } else { - dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n", + dev_dbg(component->dev, "%s: Failed to get mbhc impedance %d\n", __func__, ret); ret = 0; } @@ -2127,12 +2235,12 @@ static int aqt_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMD: /* 1000us required as per HW requirement */ usleep_range(1000, 1100); - aqt_clsh_fsm(codec, &aqt->clsh_d, + aqt_clsh_fsm(component, &aqt->clsh_d, AQT_CLSH_EVENT_POST_PA, AQT_CLSH_STATE_HPHL, hph_mode); if (test_bit(CLSH_Z_CONFIG, &aqt->status_mask)) { - aqt_clsh_imped_config(codec, impedl, true); + aqt_clsh_imped_config(component, impedl, true); clear_bit(CLSH_Z_CONFIG, &aqt->status_mask); } break; @@ -2147,14 +2255,15 @@ static int aqt_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); int hph_mode = aqt->hph_mode; u8 dem_inp; int ret = 0; - dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, - w->name, event, hph_mode); + dev_dbg(component->dev, "%s wname: %s event: %d hph_mode: %d\n", + __func__, w->name, event, hph_mode); switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -2164,30 +2273,32 @@ static int aqt_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, msleep(40); } /* Read DEM INP Select */ - dem_inp = snd_soc_read(codec, AQT1000_CDC_RX2_RX_PATH_SEC0) & - 0x03; + dem_inp = snd_soc_component_read32( + component, AQT1000_CDC_RX2_RX_PATH_SEC0) & + 0x03; if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { - dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", + dev_err(component->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", __func__, hph_mode); return -EINVAL; } /* Disable AutoChop timer during power up */ - snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_HPH_TIMER1, - 0x02, 0x00); - aqt_clsh_fsm(codec, &aqt->clsh_d, + snd_soc_component_update_bits(component, + AQT1000_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x00); + aqt_clsh_fsm(component, &aqt->clsh_d, AQT_CLSH_EVENT_PRE_DAC, AQT_CLSH_STATE_HPHR, hph_mode); if (aqt->anc_func) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_RX2_RX_PATH_CFG0, 0x10, 0x10); break; case SND_SOC_DAPM_POST_PMD: /* 1000us required as per HW requirement */ usleep_range(1000, 1100); - aqt_clsh_fsm(codec, &aqt->clsh_d, + aqt_clsh_fsm(component, &aqt->clsh_d, AQT_CLSH_EVENT_POST_PA, AQT_CLSH_STATE_HPHR, hph_mode); @@ -2203,23 +2314,26 @@ static int aqt_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); int ret = 0; - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: if ((!(strcmp(w->name, "AQT ANC HPHR PA"))) && (test_bit(HPH_PA_DELAY, &aqt->status_mask))) - snd_soc_update_bits(codec, AQT1000_ANA_HPH, 0xC0, 0xC0); + snd_soc_component_update_bits(component, + AQT1000_ANA_HPH, 0xC0, 0xC0); set_bit(HPH_PA_DELAY, &aqt->status_mask); break; case SND_SOC_DAPM_POST_PMU: if ((!(strcmp(w->name, "AQT ANC HPHR PA")))) { - if ((snd_soc_read(codec, AQT1000_ANA_HPH) & 0xC0) + if ((snd_soc_component_read32( + component, AQT1000_ANA_HPH) & 0xC0) != 0xC0) /* * If PA_EN is not set (potentially in ANC case) @@ -2242,64 +2356,76 @@ static int aqt_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, } if (aqt->anc_func) { /* Clear Tx FE HOLD if both PAs are enabled */ - if ((snd_soc_read(aqt->codec, AQT1000_ANA_HPH) & + if ((snd_soc_component_read32( + aqt->component, AQT1000_ANA_HPH) & 0xC0) == 0xC0) aqt_codec_clear_anc_tx_hold(aqt); } - snd_soc_update_bits(codec, AQT1000_HPH_R_TEST, 0x01, 0x01); + snd_soc_component_update_bits( + component, AQT1000_HPH_R_TEST, 0x01, 0x01); /* Remove mute */ - snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL, - 0x10, 0x00); + snd_soc_component_update_bits( + component, AQT1000_CDC_RX2_RX_PATH_CTL, + 0x10, 0x00); /* Enable GM3 boost */ - snd_soc_update_bits(codec, AQT1000_HPH_CNP_WG_CTL, - 0x80, 0x80); + snd_soc_component_update_bits( + component, AQT1000_HPH_CNP_WG_CTL, + 0x80, 0x80); /* Enable AutoChop timer at the end of power up */ - snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_HPH_TIMER1, - 0x02, 0x02); + snd_soc_component_update_bits(component, + AQT1000_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x02); /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, AQT1000_CDC_RX2_RX_PATH_MIX_CTL)) & - 0x10) - snd_soc_update_bits(codec, + if ((snd_soc_component_read32( + component, AQT1000_CDC_RX2_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_component_update_bits(component, AQT1000_CDC_RX2_RX_PATH_MIX_CTL, 0x10, 0x00); if (!(strcmp(w->name, "AQT ANC HPHR PA"))) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s:Do everything needed for left channel\n", __func__); /* Do everything needed for left channel */ - snd_soc_update_bits(codec, AQT1000_HPH_L_TEST, - 0x01, 0x01); + snd_soc_component_update_bits( + component, AQT1000_HPH_L_TEST, + 0x01, 0x01); /* Remove mute */ - snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL, - 0x10, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CDC_RX1_RX_PATH_CTL, + 0x10, 0x00); /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, + if ((snd_soc_component_read32(component, AQT1000_CDC_RX1_RX_PATH_MIX_CTL)) & 0x10) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_RX1_RX_PATH_MIX_CTL, 0x10, 0x00); /* Remove ANC Rx from reset */ ret = aqt_codec_enable_anc(w, kcontrol, event); } - aqt_codec_override(codec, aqt->hph_mode, event); + aqt_codec_override(component, aqt->hph_mode, event); break; case SND_SOC_DAPM_PRE_PMD: blocking_notifier_call_chain(&aqt->mbhc->notifier, AQT_EVENT_PRE_HPHR_PA_OFF, &aqt->mbhc->wcd_mbhc); - snd_soc_update_bits(codec, AQT1000_HPH_R_TEST, 0x01, 0x00); - snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL, - 0x10, 0x10); - snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_MIX_CTL, - 0x10, 0x10); + snd_soc_component_update_bits(component, + AQT1000_HPH_R_TEST, 0x01, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CDC_RX2_RX_PATH_CTL, + 0x10, 0x10); + snd_soc_component_update_bits(component, + AQT1000_CDC_RX2_RX_PATH_MIX_CTL, + 0x10, 0x10); if (!(strcmp(w->name, "AQT ANC HPHR PA"))) - snd_soc_update_bits(codec, AQT1000_ANA_HPH, 0x40, 0x00); + snd_soc_component_update_bits(component, + AQT1000_ANA_HPH, 0x40, 0x00); break; case SND_SOC_DAPM_POST_PMD: /* @@ -2310,13 +2436,13 @@ static int aqt_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, usleep_range(20000, 20100); else usleep_range(5000, 5100); - aqt_codec_override(codec, aqt->hph_mode, event); + aqt_codec_override(component, aqt->hph_mode, event); blocking_notifier_call_chain(&aqt->mbhc->notifier, AQT_EVENT_POST_HPHR_PA_OFF, &aqt->mbhc->wcd_mbhc); if (!(strcmp(w->name, "AQT ANC HPHR PA"))) { ret = aqt_codec_enable_anc(w, kcontrol, event); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_RX2_RX_PATH_CFG0, 0x10, 0x00); } @@ -2330,23 +2456,26 @@ static int aqt_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); int ret = 0; - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: if ((!(strcmp(w->name, "AQT ANC HPHL PA"))) && (test_bit(HPH_PA_DELAY, &aqt->status_mask))) - snd_soc_update_bits(codec, AQT1000_ANA_HPH, - 0xC0, 0xC0); + snd_soc_component_update_bits(component, + AQT1000_ANA_HPH, + 0xC0, 0xC0); set_bit(HPH_PA_DELAY, &aqt->status_mask); break; case SND_SOC_DAPM_POST_PMU: if (!(strcmp(w->name, "AQT ANC HPHL PA"))) { - if ((snd_soc_read(codec, AQT1000_ANA_HPH) & 0xC0) + if ((snd_soc_component_read32( + component, AQT1000_ANA_HPH) & 0xC0) != 0xC0) /* * If PA_EN is not set (potentially in ANC @@ -2369,64 +2498,73 @@ static int aqt_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, } if (aqt->anc_func) { /* Clear Tx FE HOLD if both PAs are enabled */ - if ((snd_soc_read(aqt->codec, AQT1000_ANA_HPH) & + if ((snd_soc_component_read32( + aqt->component, AQT1000_ANA_HPH) & 0xC0) == 0xC0) aqt_codec_clear_anc_tx_hold(aqt); } - snd_soc_update_bits(codec, AQT1000_HPH_L_TEST, 0x01, 0x01); + snd_soc_component_update_bits(component, + AQT1000_HPH_L_TEST, 0x01, 0x01); /* Remove Mute on primary path */ - snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL, - 0x10, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CDC_RX1_RX_PATH_CTL, + 0x10, 0x00); /* Enable GM3 boost */ - snd_soc_update_bits(codec, AQT1000_HPH_CNP_WG_CTL, - 0x80, 0x80); + snd_soc_component_update_bits(component, + AQT1000_HPH_CNP_WG_CTL, + 0x80, 0x80); /* Enable AutoChop timer at the end of power up */ - snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_HPH_TIMER1, - 0x02, 0x02); + snd_soc_component_update_bits(component, + AQT1000_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x02); /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, AQT1000_CDC_RX1_RX_PATH_MIX_CTL)) & - 0x10) - snd_soc_update_bits(codec, + if ((snd_soc_component_read32(component, + AQT1000_CDC_RX1_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_component_update_bits(component, AQT1000_CDC_RX1_RX_PATH_MIX_CTL, 0x10, 0x00); if (!(strcmp(w->name, "AQT ANC HPHL PA"))) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s:Do everything needed for right channel\n", __func__); /* Do everything needed for right channel */ - snd_soc_update_bits(codec, AQT1000_HPH_R_TEST, - 0x01, 0x01); + snd_soc_component_update_bits(component, + AQT1000_HPH_R_TEST, + 0x01, 0x01); /* Remove mute */ - snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL, + snd_soc_component_update_bits(component, + AQT1000_CDC_RX2_RX_PATH_CTL, 0x10, 0x00); /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, + if ((snd_soc_component_read32(component, AQT1000_CDC_RX2_RX_PATH_MIX_CTL)) & 0x10) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_RX2_RX_PATH_MIX_CTL, 0x10, 0x00); /* Remove ANC Rx from reset */ ret = aqt_codec_enable_anc(w, kcontrol, event); } - aqt_codec_override(codec, aqt->hph_mode, event); + aqt_codec_override(component, aqt->hph_mode, event); break; case SND_SOC_DAPM_PRE_PMD: blocking_notifier_call_chain(&aqt->mbhc->notifier, AQT_EVENT_PRE_HPHL_PA_OFF, &aqt->mbhc->wcd_mbhc); - snd_soc_update_bits(codec, AQT1000_HPH_L_TEST, 0x01, 0x00); - snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL, - 0x10, 0x10); - snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_MIX_CTL, - 0x10, 0x10); + snd_soc_component_update_bits(component, + AQT1000_HPH_L_TEST, 0x01, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CDC_RX1_RX_PATH_CTL, 0x10, 0x10); + snd_soc_component_update_bits(component, + AQT1000_CDC_RX1_RX_PATH_MIX_CTL, 0x10, 0x10); if (!(strcmp(w->name, "AQT ANC HPHL PA"))) - snd_soc_update_bits(codec, AQT1000_ANA_HPH, - 0x80, 0x00); + snd_soc_component_update_bits(component, + AQT1000_ANA_HPH, 0x80, 0x00); break; case SND_SOC_DAPM_POST_PMD: /* @@ -2437,13 +2575,13 @@ static int aqt_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, usleep_range(20000, 20100); else usleep_range(5000, 5100); - aqt_codec_override(codec, aqt->hph_mode, event); + aqt_codec_override(component, aqt->hph_mode, event); blocking_notifier_call_chain(&aqt->mbhc->notifier, AQT_EVENT_POST_HPHL_PA_OFF, &aqt->mbhc->wcd_mbhc); if (!(strcmp(w->name, "AQT ANC HPHL PA"))) { ret = aqt_codec_enable_anc(w, kcontrol, event); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_RX1_RX_PATH_CFG0, 0x10, 0x00); } break; @@ -2455,29 +2593,30 @@ static int aqt_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, static int aqt_codec_set_iir_gain(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); - dev_dbg(codec->dev, "%s: event = %d\n", __func__, event); + dev_dbg(component->dev, "%s: event = %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_POST_PMU: /* fall through */ case SND_SOC_DAPM_PRE_PMD: if (strnstr(w->name, "AQT IIR0", sizeof("AQT IIR0"))) { - snd_soc_write(codec, + snd_soc_component_write(component, AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)); } break; @@ -2488,20 +2627,22 @@ static int aqt_codec_set_iir_gain(struct snd_soc_dapm_widget *w, static int aqt_enable_native_supply(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); switch (event) { case SND_SOC_DAPM_PRE_PMU: if (++aqt->native_clk_users == 1) { - snd_soc_update_bits(codec, AQT1000_CLK_SYS_PLL_ENABLES, - 0x01, 0x01); + snd_soc_component_update_bits(component, + AQT1000_CLK_SYS_PLL_ENABLES, + 0x01, 0x01); /* 100usec is needed as per HW requirement */ usleep_range(100, 120); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x02, 0x02); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x10, 0x10); } @@ -2509,19 +2650,20 @@ static int aqt_enable_native_supply(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMD: if (aqt->native_clk_users && (--aqt->native_clk_users == 0)) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x10, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x02, 0x00); - snd_soc_update_bits(codec, AQT1000_CLK_SYS_PLL_ENABLES, - 0x01, 0x00); + snd_soc_component_update_bits(component, + AQT1000_CLK_SYS_PLL_ENABLES, + 0x01, 0x00); } break; } - dev_dbg(codec->dev, "%s: native_clk_users: %d, event: %d\n", + dev_dbg(component->dev, "%s: native_clk_users: %d, event: %d\n", __func__, aqt->native_clk_users, event); return 0; @@ -2537,17 +2679,18 @@ AQT_DAPM_ENUM(int2_1_native, SND_SOC_NOPM, 0, native_mux_text); static int aqt_mclk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); int ret = 0; - dev_dbg(codec->dev, "%s: event = %d\n", __func__, event); + dev_dbg(component->dev, "%s: event = %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - ret = aqt_cdc_mclk_enable(codec, true); + ret = aqt_cdc_mclk_enable(component, true); break; case SND_SOC_DAPM_POST_PMD: - ret = aqt_cdc_mclk_enable(codec, false); + ret = aqt_cdc_mclk_enable(component, false); break; } @@ -2766,7 +2909,7 @@ static void aqt_shutdown(struct snd_pcm_substream *substream, static int aqt_set_decimator_rate(struct snd_soc_dai *dai, u32 sample_rate) { - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; u8 tx_fs_rate = 0; u8 tx_mux_sel = 0, tx0_mux_sel = 0, tx1_mux_sel = 0; u16 tx_path_ctl_reg = 0; @@ -2791,27 +2934,30 @@ static int aqt_set_decimator_rate(struct snd_soc_dai *dai, tx_fs_rate = 6; break; default: - dev_err(codec->dev, "%s: Invalid TX sample rate: %d\n", + dev_err(component->dev, "%s: Invalid TX sample rate: %d\n", __func__, sample_rate); return -EINVAL; }; /* Find which decimator path is enabled */ - tx_mux_sel = snd_soc_read(codec, AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0); + tx_mux_sel = snd_soc_component_read32(component, + AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0); tx0_mux_sel = (tx_mux_sel & 0x03); tx1_mux_sel = (tx_mux_sel & 0xC0); if (tx0_mux_sel) { tx_path_ctl_reg = AQT1000_CDC_TX0_TX_PATH_CTL + ((tx0_mux_sel - 1) * 16); - snd_soc_update_bits(codec, tx_path_ctl_reg, 0x0F, tx_fs_rate); + snd_soc_component_update_bits(component, tx_path_ctl_reg, + 0x0F, tx_fs_rate); } if (tx1_mux_sel) { tx_path_ctl_reg = AQT1000_CDC_TX0_TX_PATH_CTL + ((tx1_mux_sel - 1) * 16); - snd_soc_update_bits(codec, tx_path_ctl_reg, 0x0F, tx_fs_rate); + snd_soc_component_update_bits(component, tx_path_ctl_reg, + 0x0F, tx_fs_rate); } return 0; @@ -2820,7 +2966,7 @@ static int aqt_set_decimator_rate(struct snd_soc_dai *dai, static int aqt_set_interpolator_rate(struct snd_soc_dai *dai, u32 sample_rate) { - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; int rate_val = 0; int i; @@ -2831,23 +2977,25 @@ static int aqt_set_interpolator_rate(struct snd_soc_dai *dai, } } if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) { - dev_err(codec->dev, "%s: Unsupported sample rate: %d\n", + dev_err(component->dev, "%s: Unsupported sample rate: %d\n", __func__, sample_rate); return -EINVAL; } /* TODO - Set the rate only to enabled path */ /* Set Primary interpolator rate */ - snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL, + snd_soc_component_update_bits(component, AQT1000_CDC_RX1_RX_PATH_CTL, 0x0F, (u8)rate_val); - snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL, + snd_soc_component_update_bits(component, AQT1000_CDC_RX2_RX_PATH_CTL, 0x0F, (u8)rate_val); /* Set mixing path interpolator rate */ - snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_MIX_CTL, - 0x0F, (u8)rate_val); - snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_MIX_CTL, - 0x0F, (u8)rate_val); + snd_soc_component_update_bits(component, + AQT1000_CDC_RX1_RX_PATH_MIX_CTL, + 0x0F, (u8)rate_val); + snd_soc_component_update_bits(component, + AQT1000_CDC_RX2_RX_PATH_MIX_CTL, + 0x0F, (u8)rate_val); return 0; } @@ -2864,7 +3012,7 @@ static int aqt_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(dai->codec); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(dai->component); int ret = 0; dev_dbg(aqt->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", @@ -2965,7 +3113,7 @@ struct snd_soc_dai_driver aqt_dai[] = { static int aqt_enable_mclk(struct aqt1000 *aqt) { - struct snd_soc_codec *codec = aqt->codec; + struct snd_soc_component *component = aqt->component; /* Enable mclk requires master bias to be enabled first */ if (aqt->master_bias_users <= 0) { @@ -2977,14 +3125,14 @@ static int aqt_enable_mclk(struct aqt1000 *aqt) if (++aqt->mclk_users == 1) { /* Set clock div 2 */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CLK_SYS_MCLK1_PRG, 0x0C, 0x04); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CLK_SYS_MCLK1_PRG, 0x10, 0x10); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x01); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x01); /* @@ -3001,7 +3149,7 @@ static int aqt_enable_mclk(struct aqt1000 *aqt) static int aqt_disable_mclk(struct aqt1000 *aqt) { - struct snd_soc_codec *codec = aqt->codec; + struct snd_soc_component *component = aqt->component; if (aqt->mclk_users <= 0) { dev_err(aqt->dev, "%s: No mclk users, cannot disable mclk\n", @@ -3010,37 +3158,41 @@ static int aqt_disable_mclk(struct aqt1000 *aqt) } if (--aqt->mclk_users == 0) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, AQT1000_CLK_SYS_MCLK1_PRG, 0x10, 0x00); } - dev_dbg(codec->dev, "%s: mclk_users: %d\n", __func__, aqt->mclk_users); + dev_dbg(component->dev, "%s: mclk_users: %d\n", __func__, + aqt->mclk_users); return 0; } static int aqt_enable_master_bias(struct aqt1000 *aqt) { - struct snd_soc_codec *codec = aqt->codec; + struct snd_soc_component *component = aqt->component; mutex_lock(&aqt->master_bias_lock); aqt->master_bias_users++; if (aqt->master_bias_users == 1) { - snd_soc_update_bits(codec, AQT1000_ANA_BIAS, 0x80, 0x80); - snd_soc_update_bits(codec, AQT1000_ANA_BIAS, 0x40, 0x40); + snd_soc_component_update_bits(component, AQT1000_ANA_BIAS, + 0x80, 0x80); + snd_soc_component_update_bits(component, AQT1000_ANA_BIAS, + 0x40, 0x40); /* * 1ms delay is required after pre-charge is enabled * as per HW requirement */ usleep_range(1000, 1100); - snd_soc_update_bits(codec, AQT1000_ANA_BIAS, 0x40, 0x00); + snd_soc_component_update_bits(component, AQT1000_ANA_BIAS, + 0x40, 0x00); } mutex_unlock(&aqt->master_bias_lock); @@ -3050,7 +3202,7 @@ static int aqt_enable_master_bias(struct aqt1000 *aqt) static int aqt_disable_master_bias(struct aqt1000 *aqt) { - struct snd_soc_codec *codec = aqt->codec; + struct snd_soc_component *component = aqt->component; mutex_lock(&aqt->master_bias_lock); if (aqt->master_bias_users <= 0) { @@ -3060,7 +3212,8 @@ static int aqt_disable_master_bias(struct aqt1000 *aqt) aqt->master_bias_users--; if (aqt->master_bias_users == 0) - snd_soc_update_bits(codec, AQT1000_ANA_BIAS, 0x80, 0x00); + snd_soc_component_update_bits(component, AQT1000_ANA_BIAS, + 0x80, 0x00); mutex_unlock(&aqt->master_bias_lock); return 0; @@ -3126,14 +3279,14 @@ static int __aqt_cdc_mclk_enable(struct aqt1000 *aqt, /** * aqt_cdc_mclk_enable - Enable/disable codec mclk * - * @codec: codec instance + * @component: codec component instance * @enable: Indicates clk enable or disable * * Returns 0 on Success and error on failure */ -int aqt_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable) +int aqt_cdc_mclk_enable(struct snd_soc_component *component, bool enable) { - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); return __aqt_cdc_mclk_enable(aqt, enable); } @@ -3160,11 +3313,11 @@ EXPORT_SYMBOL(aqt_get_micb_vout_ctl_val); static int aqt_set_micbias(struct aqt1000 *aqt, struct aqt1000_pdata *pdata) { - struct snd_soc_codec *codec = aqt->codec; + struct snd_soc_component *component = aqt->component; int vout_ctl_1; if (!pdata) { - dev_err(codec->dev, "%s: NULL pdata\n", __func__); + dev_err(component->dev, "%s: NULL pdata\n", __func__); return -ENODEV; } @@ -3173,7 +3326,8 @@ static int aqt_set_micbias(struct aqt1000 *aqt, if (vout_ctl_1 < 0) return -EINVAL; - snd_soc_update_bits(codec, AQT1000_ANA_MICB1, 0x3F, vout_ctl_1); + snd_soc_component_update_bits(component, AQT1000_ANA_MICB1, + 0x3F, vout_ctl_1); return 0; } @@ -3199,7 +3353,7 @@ static struct snd_info_entry_ops aqt_codec_info_ops = { /* * aqt_codec_info_create_codec_entry - creates aqt1000 module * @codec_root: The parent directory - * @codec: Codec instance + * @component: Codec component instance * * Creates aqt1000 module and version entry under the given * parent directory. @@ -3207,25 +3361,25 @@ static struct snd_info_entry_ops aqt_codec_info_ops = { * Return: 0 on success or negative error code on failure. */ int aqt_codec_info_create_codec_entry(struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { struct snd_info_entry *version_entry; struct aqt1000 *aqt; struct snd_soc_card *card; - if (!codec_root || !codec) + if (!codec_root || !component) return -EINVAL; - aqt = snd_soc_codec_get_drvdata(codec); + aqt = snd_soc_component_get_drvdata(component); if (!aqt) { - dev_dbg(codec->dev, "%s: aqt is NULL\n", __func__); + dev_dbg(component->dev, "%s: aqt is NULL\n", __func__); return -EINVAL; } - card = codec->component.card; + card = component->card; aqt->entry = snd_info_create_subdir(codec_root->module, "aqt1000", codec_root); if (!aqt->entry) { - dev_dbg(codec->dev, "%s: failed to create aqt1000 entry\n", + dev_dbg(component->dev, "%s: failed to create aqt1000 entry\n", __func__); return -ENOMEM; } @@ -3234,7 +3388,7 @@ int aqt_codec_info_create_codec_entry(struct snd_info_entry *codec_root, "version", aqt->entry); if (!version_entry) { - dev_dbg(codec->dev, "%s: failed to create aqt1000 version entry\n", + dev_dbg(component->dev, "%s: failed to create aqt1000 version entry\n", __func__); return -ENOMEM; } @@ -3271,11 +3425,11 @@ static const struct aqt_reg_mask_val aqt_codec_reg_update[] = { static void aqt_codec_init_reg(struct aqt1000 *priv) { - struct snd_soc_codec *codec = priv->codec; + struct snd_soc_component *component = priv->component; u32 i; for (i = 0; i < ARRAY_SIZE(aqt_codec_reg_init); i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, aqt_codec_reg_init[i].reg, aqt_codec_reg_init[i].mask, aqt_codec_reg_init[i].val); @@ -3283,26 +3437,29 @@ static void aqt_codec_init_reg(struct aqt1000 *priv) static void aqt_codec_update_reg(struct aqt1000 *priv) { - struct snd_soc_codec *codec = priv->codec; + struct snd_soc_component *component = priv->component; u32 i; for (i = 0; i < ARRAY_SIZE(aqt_codec_reg_update); i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, aqt_codec_reg_update[i].reg, aqt_codec_reg_update[i].mask, aqt_codec_reg_update[i].val); } -static int aqt_soc_codec_probe(struct snd_soc_codec *codec) +static int aqt_soc_codec_probe(struct snd_soc_component *component) { struct aqt1000 *aqt; struct aqt1000_pdata *pdata; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); int i, ret = 0; - dev_dbg(codec->dev, "%s()\n", __func__); - aqt = snd_soc_codec_get_drvdata(codec); + dev_dbg(component->dev, "%s()\n", __func__); + aqt = snd_soc_component_get_drvdata(component); + + snd_soc_component_init_regmap(component, aqt->regmap); mutex_init(&aqt->codec_mutex); mutex_init(&aqt->i2s_lock); @@ -3311,7 +3468,7 @@ static int aqt_soc_codec_probe(struct snd_soc_codec *codec) /* Default HPH Mode to Class-H Low HiFi */ aqt->hph_mode = CLS_H_LOHIFI; - aqt->fw_data = devm_kzalloc(codec->dev, sizeof(*(aqt->fw_data)), + aqt->fw_data = devm_kzalloc(component->dev, sizeof(*(aqt->fw_data)), GFP_KERNEL); if (!aqt->fw_data) goto err; @@ -3328,39 +3485,40 @@ static int aqt_soc_codec_probe(struct snd_soc_codec *codec) } ret = wcd_cal_create_hwdep(aqt->fw_data, - AQT1000_CODEC_HWDEP_NODE, codec); + AQT1000_CODEC_HWDEP_NODE, component); if (ret < 0) { - dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret); + dev_err(component->dev, "%s hwdep failed %d\n", __func__, ret); goto err_hwdep; } /* Initialize MBHC module */ - ret = aqt_mbhc_init(&aqt->mbhc, codec, aqt->fw_data); + ret = aqt_mbhc_init(&aqt->mbhc, component, aqt->fw_data); if (ret) { pr_err("%s: mbhc initialization failed\n", __func__); goto err_hwdep; } - aqt->codec = codec; + aqt->component = component; for (i = 0; i < COMPANDER_MAX; i++) aqt->comp_enabled[i] = 0; - aqt_cdc_mclk_enable(codec, true); + aqt_cdc_mclk_enable(component, true); aqt_codec_init_reg(aqt); - aqt_cdc_mclk_enable(codec, false); + aqt_cdc_mclk_enable(component, false); /* Add 100usec delay as per HW requirement */ usleep_range(100, 110); aqt_codec_update_reg(aqt); - pdata = dev_get_platdata(codec->dev); + pdata = dev_get_platdata(component->dev); /* If 1.8v is supplied externally, then disable internal 1.8v supply */ for (i = 0; i < pdata->num_supplies; i++) { if (!strcmp(pdata->regulator->name, "aqt_vdd1p8")) { - snd_soc_update_bits(codec, AQT1000_BUCK_5V_EN_CTL, - 0x03, 0x00); - dev_dbg(codec->dev, "%s: Disabled internal supply\n", + snd_soc_component_update_bits(component, + AQT1000_BUCK_5V_EN_CTL, + 0x03, 0x00); + dev_dbg(component->dev, "%s: Disabled internal supply\n", __func__); break; } @@ -3405,7 +3563,7 @@ static int aqt_soc_codec_probe(struct snd_soc_codec *codec) err_hwdep: clk_put(aqt->ext_clk); err_clk: - devm_kfree(codec->dev, aqt->fw_data); + devm_kfree(component->dev, aqt->fw_data); aqt->fw_data = NULL; err: mutex_destroy(&aqt->i2s_lock); @@ -3413,39 +3571,30 @@ static int aqt_soc_codec_probe(struct snd_soc_codec *codec) return ret; } -static int aqt_soc_codec_remove(struct snd_soc_codec *codec) +static void aqt_soc_codec_remove(struct snd_soc_component *component) { - struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec); + struct aqt1000 *aqt = snd_soc_component_get_drvdata(component); /* Deinitialize MBHC module */ - aqt_mbhc_deinit(codec); + aqt_mbhc_deinit(component); aqt->mbhc = NULL; mutex_destroy(&aqt->i2s_lock); mutex_destroy(&aqt->codec_mutex); clk_put(aqt->ext_clk); - return 0; + return; } -static struct regmap *aqt_get_regmap(struct device *dev) -{ - struct aqt1000 *control = dev_get_drvdata(dev); - - return control->regmap; -} - -struct snd_soc_codec_driver snd_cdc_dev_aqt = { +static const struct snd_soc_component_driver snd_cdc_dev_aqt = { + .name = DRV_NAME, .probe = aqt_soc_codec_probe, .remove = aqt_soc_codec_remove, - .get_regmap = aqt_get_regmap, - .component_driver = { - .controls = aqt_snd_controls, - .num_controls = ARRAY_SIZE(aqt_snd_controls), - .dapm_widgets = aqt_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(aqt_dapm_widgets), - .dapm_routes = aqt_audio_map, - .num_dapm_routes = ARRAY_SIZE(aqt_audio_map), - }, + .controls = aqt_snd_controls, + .num_controls = ARRAY_SIZE(aqt_snd_controls), + .dapm_widgets = aqt_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(aqt_dapm_widgets), + .dapm_routes = aqt_audio_map, + .num_dapm_routes = ARRAY_SIZE(aqt_audio_map), }; /* @@ -3456,7 +3605,7 @@ struct snd_soc_codec_driver snd_cdc_dev_aqt = { */ int aqt_register_codec(struct device *dev) { - return snd_soc_register_codec(dev, &snd_cdc_dev_aqt, aqt_dai, + return snd_soc_register_component(dev, &snd_cdc_dev_aqt, aqt_dai, ARRAY_SIZE(aqt_dai)); } EXPORT_SYMBOL(aqt_register_codec); diff --git a/asoc/codecs/aqt1000/aqt1000.h b/asoc/codecs/aqt1000/aqt1000.h index 88fdc90d2c27..6148213f651e 100644 --- a/asoc/codecs/aqt1000/aqt1000.h +++ b/asoc/codecs/aqt1000/aqt1000.h @@ -145,7 +145,7 @@ struct aqt1000 { u32 mclk_rate; struct regmap *regmap; - struct snd_soc_codec *codec; + struct snd_soc_component *component; bool dev_up; bool prev_pg_valid; u8 prev_pg; diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index 2bbbc9e95a4b..74ab9e243a5b 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -10,6 +10,7 @@ #include #include #include "../../../drivers/clk/qcom/common.h" +#include #include #include #include diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 430a0b3e5eb8..2d63c431cfe8 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -16,13 +16,15 @@ #include "bolero-cdc.h" #include "internal.h" +#define DRV_NAME "bolero_codec" + #define BOLERO_VERSION_1_0 0x0001 #define BOLERO_VERSION_1_1 0x0002 #define BOLERO_VERSION_1_2 0x0003 #define BOLERO_VERSION_ENTRY_SIZE 32 #define BOLERO_CDC_STRING_LEN 80 -static struct snd_soc_codec_driver bolero; +static const struct snd_soc_component_driver bolero; /* pm runtime auto suspend timer in msecs */ #define BOLERO_AUTO_SUSPEND_DELAY 100 /* delay in msec */ @@ -145,17 +147,20 @@ static int bolero_cdc_update_wcd_event(void *handle, u16 event, u32 data) switch (event) { case WCD_BOLERO_EVT_RX_MUTE: if (priv->macro_params[RX_MACRO].event_handler) - priv->macro_params[RX_MACRO].event_handler(priv->codec, + priv->macro_params[RX_MACRO].event_handler( + priv->component, BOLERO_MACRO_EVT_RX_MUTE, data); break; case WCD_BOLERO_EVT_IMPED_TRUE: if (priv->macro_params[RX_MACRO].event_handler) - priv->macro_params[RX_MACRO].event_handler(priv->codec, + priv->macro_params[RX_MACRO].event_handler( + priv->component, BOLERO_MACRO_EVT_IMPED_TRUE, data); break; case WCD_BOLERO_EVT_IMPED_FALSE: if (priv->macro_params[RX_MACRO].event_handler) - priv->macro_params[RX_MACRO].event_handler(priv->codec, + priv->macro_params[RX_MACRO].event_handler( + priv->component, BOLERO_MACRO_EVT_IMPED_FALSE, data); break; default: @@ -367,7 +372,7 @@ int bolero_register_macro(struct device *dev, u16 macro_id, bolero_mclk_mux_tbl[VA_MACRO][MCLK_MUX0] = VA_MACRO; priv->current_mclk_mux_macro[VA_MACRO] = VA_MACRO; } - ret = snd_soc_register_codec(dev->parent, &bolero, + ret = snd_soc_register_component(dev->parent, &bolero, priv->bolero_dais, priv->num_dais); if (ret < 0) { dev_err(dev, "%s: register codec failed\n", __func__); @@ -418,7 +423,7 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) /* UNREGISTER CODEC HERE */ if (priv->num_macros - 1 == priv->num_macros_registered) - snd_soc_unregister_codec(dev->parent); + snd_soc_unregister_component(dev->parent); } EXPORT_SYMBOL(bolero_unregister_macro); @@ -568,7 +573,8 @@ static int bolero_ssr_enable(struct device *dev, void *data) } if (priv->macro_params[VA_MACRO].event_handler) - priv->macro_params[VA_MACRO].event_handler(priv->codec, + priv->macro_params[VA_MACRO].event_handler( + priv->component, BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET, 0x0); regcache_cache_only(priv->regmap, false); @@ -576,7 +582,8 @@ static int bolero_ssr_enable(struct device *dev, void *data) for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { if (!priv->macro_params[macro_idx].event_handler) continue; - priv->macro_params[macro_idx].event_handler(priv->codec, + priv->macro_params[macro_idx].event_handler( + priv->component, BOLERO_MACRO_EVT_SSR_UP, 0x0); } mutex_lock(&priv->clk_lock); @@ -601,7 +608,8 @@ static void bolero_ssr_disable(struct device *dev, void *data) for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { if (!priv->macro_params[macro_idx].event_handler) continue; - priv->macro_params[macro_idx].event_handler(priv->codec, + priv->macro_params[macro_idx].event_handler( + priv->component, BOLERO_MACRO_EVT_SSR_DOWN, 0x0); } bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_SSR_DOWN); @@ -619,7 +627,7 @@ static const struct snd_event_ops bolero_ssr_ops = { /* * bolero_info_create_codec_entry - creates bolero module * @codec_root: The parent directory - * @codec: Codec instance + * @component: Codec component instance * * Creates bolero module and version entry under the given * parent directory. @@ -627,26 +635,26 @@ static const struct snd_event_ops bolero_ssr_ops = { * Return: 0 on success or negative error code on failure. */ int bolero_info_create_codec_entry(struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { struct snd_info_entry *version_entry; struct bolero_priv *priv; struct snd_soc_card *card; - if (!codec_root || !codec) + if (!codec_root || !component) return -EINVAL; - priv = snd_soc_codec_get_drvdata(codec); + priv = snd_soc_component_get_drvdata(component); if (priv->entry) { dev_dbg(priv->dev, "%s:bolero module already created\n", __func__); return 0; } - card = codec->component.card; + card = component->card; priv->entry = snd_info_create_subdir(codec_root->module, "bolero", codec_root); if (!priv->entry) { - dev_dbg(codec->dev, "%s: failed to create bolero entry\n", + dev_dbg(component->dev, "%s: failed to create bolero entry\n", __func__); return -ENOMEM; } @@ -654,7 +662,7 @@ int bolero_info_create_codec_entry(struct snd_info_entry *codec_root, "version", priv->entry); if (!version_entry) { - dev_err(codec->dev, "%s: failed to create bolero version entry\n", + dev_err(component->dev, "%s: failed to create bolero version entry\n", __func__); return -ENOMEM; } @@ -677,52 +685,56 @@ EXPORT_SYMBOL(bolero_info_create_codec_entry); /** * bolero_register_wake_irq - Register wake irq of Tx macro * - * @codec: codec ptr. + * @component: codec component ptr. * @ipc_wakeup: bool to identify ipc_wakeup to be used or HW interrupt line. * * Return: 0 on success or negative error code on failure. */ -int bolero_register_wake_irq(struct snd_soc_codec *codec, u32 ipc_wakeup) +int bolero_register_wake_irq(struct snd_soc_component *component, + u32 ipc_wakeup) { struct bolero_priv *priv = NULL; - if (!codec) + if (!component) return -EINVAL; - priv = snd_soc_codec_get_drvdata(codec); + priv = snd_soc_component_get_drvdata(component); if (!priv) return -EINVAL; if (!bolero_is_valid_codec_dev(priv->dev)) { - dev_err(codec->dev, "%s: invalid codec\n", __func__); + dev_err(component->dev, "%s: invalid codec\n", __func__); return -EINVAL; } if (priv->macro_params[TX_MACRO].reg_wake_irq) - priv->macro_params[TX_MACRO].reg_wake_irq(codec, ipc_wakeup); + priv->macro_params[TX_MACRO].reg_wake_irq( + component, ipc_wakeup); return 0; } EXPORT_SYMBOL(bolero_register_wake_irq); -static int bolero_soc_codec_probe(struct snd_soc_codec *codec) +static int bolero_soc_codec_probe(struct snd_soc_component *component) { - struct bolero_priv *priv = dev_get_drvdata(codec->dev); + struct bolero_priv *priv = dev_get_drvdata(component->dev); int macro_idx, ret = 0; + snd_soc_component_init_regmap(component, priv->regmap); + /* call init for supported macros */ for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { if (priv->macro_params[macro_idx].init) { - ret = priv->macro_params[macro_idx].init(codec); + ret = priv->macro_params[macro_idx].init(component); if (ret < 0) { - dev_err(codec->dev, + dev_err(component->dev, "%s: init for macro %d failed\n", __func__, macro_idx); goto err; } } } - priv->codec = codec; + priv->component = component; /* * In order for the ADIE RTC to differentiate between targets * version info is used. @@ -741,42 +753,36 @@ static int bolero_soc_codec_probe(struct snd_soc_codec *codec) if (!ret) { snd_event_notify(priv->dev, SND_EVENT_UP); } else { - dev_err(codec->dev, + dev_err(component->dev, "%s: Registration with SND event FWK failed ret = %d\n", __func__, ret); goto err; } - dev_dbg(codec->dev, "%s: bolero soc codec probe success\n", __func__); + dev_dbg(component->dev, "%s: bolero soc codec probe success\n", + __func__); err: return ret; } -static int bolero_soc_codec_remove(struct snd_soc_codec *codec) +static void bolero_soc_codec_remove(struct snd_soc_component *component) { - struct bolero_priv *priv = dev_get_drvdata(codec->dev); + struct bolero_priv *priv = dev_get_drvdata(component->dev); int macro_idx; snd_event_client_deregister(priv->dev); /* call exit for supported macros */ for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) if (priv->macro_params[macro_idx].exit) - priv->macro_params[macro_idx].exit(codec); - - return 0; -} - -static struct regmap *bolero_get_regmap(struct device *dev) -{ - struct bolero_priv *priv = dev_get_drvdata(dev); + priv->macro_params[macro_idx].exit(component); - return priv->regmap; + return; } -static struct snd_soc_codec_driver bolero = { +static const struct snd_soc_component_driver bolero = { + .name = DRV_NAME, .probe = bolero_soc_codec_probe, .remove = bolero_soc_codec_remove, - .get_regmap = bolero_get_regmap, }; static void bolero_add_child_devices(struct work_struct *work) diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 7193a8ccf176..386fa628bf2b 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -42,15 +42,15 @@ enum { }; struct macro_ops { - int (*init)(struct snd_soc_codec *codec); - int (*exit)(struct snd_soc_codec *codec); + int (*init)(struct snd_soc_component *component); + int (*exit)(struct snd_soc_component *component); u16 num_dais; struct device *dev; struct snd_soc_dai_driver *dai_ptr; int (*mclk_fn)(struct device *dev, bool enable); - int (*event_handler)(struct snd_soc_codec *codec, u16 event, + int (*event_handler)(struct snd_soc_component *component, u16 event, u32 data); - int (*reg_wake_irq)(struct snd_soc_codec *codec, u32 data); + int (*reg_wake_irq)(struct snd_soc_component *component, u32 data); char __iomem *io_base; }; @@ -64,8 +64,8 @@ int bolero_request_clock(struct device *dev, u16 macro_id, bool enable); int bolero_info_create_codec_entry( struct snd_info_entry *codec_root, - struct snd_soc_codec *codec); -int bolero_register_wake_irq(struct snd_soc_codec *codec, u32 data); + struct snd_soc_component *component); +int bolero_register_wake_irq(struct snd_soc_component *component, u32 data); void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n); int bolero_runtime_resume(struct device *dev); int bolero_runtime_suspend(struct device *dev); @@ -96,7 +96,7 @@ static inline int bolero_request_clock(struct device *dev, u16 macro_id, static int bolero_info_create_codec_entry( struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { return 0; } @@ -105,7 +105,7 @@ static inline void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n) { } -static inline int bolero_register_wake_irq(struct snd_soc_codec *codec, +static inline int bolero_register_wake_irq(struct snd_soc_component *component, u32 data) static inline int bolero_runtime_resume(struct device *dev) { diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 8b7c0923cb01..be00482a3e5f 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -41,7 +41,7 @@ struct wcd_ctrl_platform_data { struct bolero_priv { struct device *dev; - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct regmap *regmap; struct mutex io_lock; struct mutex clk_lock; diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index aa49e898bc5b..75a3a0a15d93 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -271,7 +271,7 @@ static int rx_macro_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); static int rx_macro_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, +static int rx_macro_enable_interp_clk(struct snd_soc_component *component, int event, int interp_idx); /* Hold instance to soundwire platform device */ @@ -320,7 +320,7 @@ enum { * @rx_swr_gpio_p: used by pinctrl API * @rx_core_clk: MCLK for rx macro * @rx_npl_clk: NPL clock for RX soundwire - * @codec: codec handle + * @component: codec handle */ struct rx_macro_priv { struct device *dev; @@ -347,7 +347,7 @@ struct rx_macro_priv { struct device_node *rx_swr_gpio_p; struct clk *rx_core_clk; struct clk *rx_npl_clk; - struct snd_soc_codec *codec; + struct snd_soc_component *component; unsigned long active_ch_mask[RX_MACRO_MAX_DAIS]; unsigned long active_ch_cnt[RX_MACRO_MAX_DAIS]; u16 bit_width[RX_MACRO_MAX_DAIS]; @@ -631,11 +631,11 @@ static int get_impedance_index(int imped) * This function updates HPHL and HPHR gain settings * according to the impedance value. * - * @codec: codec pointer handle + * @component: codec pointer handle * @imped: impedance value of HPHL/R * @reset: bool variable to reset registers when teardown */ -static void rx_macro_wcd_clsh_imped_config(struct snd_soc_codec *codec, +static void rx_macro_wcd_clsh_imped_config(struct snd_soc_component *component, int imped, bool reset) { int i; @@ -650,7 +650,7 @@ static void rx_macro_wcd_clsh_imped_config(struct snd_soc_codec *codec, /* reset = 1, which means request is to reset the register values */ if (reset) { for (i = 0; i < MAX_IMPED_PARAMS; i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, imped_table_ptr[index][i].reg, imped_table_ptr[index][i].mask, 0); return; @@ -666,34 +666,34 @@ static void rx_macro_wcd_clsh_imped_config(struct snd_soc_codec *codec, return; } for (i = 0; i < MAX_IMPED_PARAMS; i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, imped_table_ptr[index][i].reg, imped_table_ptr[index][i].mask, imped_table_ptr[index][i].val); } -static bool rx_macro_get_data(struct snd_soc_codec *codec, +static bool rx_macro_get_data(struct snd_soc_component *component, struct device **rx_dev, struct rx_macro_priv **rx_priv, const char *func_name) { - *rx_dev = bolero_get_device_ptr(codec->dev, RX_MACRO); + *rx_dev = bolero_get_device_ptr(component->dev, RX_MACRO); if (!(*rx_dev)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: null device for macro!\n", func_name); return false; } *rx_priv = dev_get_drvdata((*rx_dev)); if (!(*rx_priv)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: priv is null for macro!\n", func_name); return false; } - if (!(*rx_priv)->codec) { - dev_err(codec->dev, + if (!(*rx_priv)->component) { + dev_err(component->dev, "%s: tx_priv codec is not initialized!\n", func_name); return false; } @@ -706,7 +706,8 @@ static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val = 0; unsigned short look_ahead_dly_reg = @@ -716,7 +717,7 @@ static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, if (val >= e->items) return -EINVAL; - dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__, widget->name, val); if (e->reg == BOLERO_CDC_RX_RX0_RX_PATH_CFG1) @@ -725,7 +726,7 @@ static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, look_ahead_dly_reg = BOLERO_CDC_RX_RX1_RX_PATH_CFG0; /* Set Look Ahead Delay */ - snd_soc_update_bits(codec, look_ahead_dly_reg, + snd_soc_component_update_bits(component, look_ahead_dly_reg, 0x08, (val ? 0x08 : 0x00)); /* Set DEM INP Select */ return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); @@ -741,11 +742,11 @@ static int rx_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, u16 int_fs_reg = 0; u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0; u8 inp0_sel = 0, inp1_sel = 0, inp2_sel = 0; - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; for_each_set_bit(port, &rx_priv->active_ch_mask[dai->id], @@ -768,8 +769,10 @@ static int rx_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, for (j = 0; j < INTERP_MAX; j++) { int_mux_cfg1 = int_mux_cfg0 + 4; - int_mux_cfg0_val = snd_soc_read(codec, int_mux_cfg0); - int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1); + int_mux_cfg0_val = snd_soc_component_read32( + component, int_mux_cfg0); + int_mux_cfg1_val = snd_soc_component_read32( + component, int_mux_cfg1); inp0_sel = int_mux_cfg0_val & 0x07; inp1_sel = (int_mux_cfg0_val >> 4) & 0x038; inp2_sel = (int_mux_cfg1_val >> 4) & 0x038; @@ -783,7 +786,8 @@ static int rx_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, pr_debug("%s: set INT%u_1 sample rate to %u\n", __func__, j, sample_rate); /* sample_rate is in Hz */ - snd_soc_update_bits(codec, int_fs_reg, + snd_soc_component_update_bits(component, + int_fs_reg, 0x0F, rate_reg_val); } int_mux_cfg0 += 8; @@ -801,11 +805,11 @@ static int rx_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, u32 j = 0, port = 0; u16 int_mux_cfg1 = 0, int_fs_reg = 0; u8 int_mux_cfg1_val = 0; - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; for_each_set_bit(port, &rx_priv->active_ch_mask[dai->id], @@ -820,7 +824,8 @@ static int rx_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, int_mux_cfg1 = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1; for (j = 0; j < INTERP_MAX; j++) { - int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1) & + int_mux_cfg1_val = snd_soc_component_read32( + component, int_mux_cfg1) & 0x07; if (int_mux_cfg1_val == int_2_inp) { int_fs_reg = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL + @@ -829,7 +834,8 @@ static int rx_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, __func__, dai->id, j); pr_debug("%s: set INT%u_2 sample rate to %u\n", __func__, j, sample_rate); - snd_soc_update_bits(codec, int_fs_reg, + snd_soc_component_update_bits( + component, int_fs_reg, 0x0F, rate_reg_val); } int_mux_cfg1 += 8; @@ -855,13 +861,13 @@ static bool rx_macro_is_fractional_sample_rate(u32 sample_rate) static int rx_macro_set_interpolator_rate(struct snd_soc_dai *dai, u32 sample_rate) { - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; int rate_val = 0; int i = 0, ret = 0; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; @@ -876,7 +882,7 @@ static int rx_macro_set_interpolator_rate(struct snd_soc_dai *dai, } } if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) { - dev_err(codec->dev, "%s: Unsupported sample rate: %d\n", + dev_err(component->dev, "%s: Unsupported sample rate: %d\n", __func__, sample_rate); return -EINVAL; } @@ -895,15 +901,15 @@ static int rx_macro_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; int ret = 0; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__, dai->name, dai->id, params_rate(params), params_channels(params)); @@ -929,13 +935,13 @@ static int rx_macro_get_channel_map(struct snd_soc_dai *dai, unsigned int *tx_num, unsigned int *tx_slot, unsigned int *rx_num, unsigned int *rx_slot) { - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; unsigned int temp = 0, ch_mask = 0; u16 i = 0; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; switch (dai->id) { @@ -1031,13 +1037,14 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); int ret = 0; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; int mclk_freq = MCLK_FREQ; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; dev_dbg(rx_dev, "%s: event = %d\n", __func__, event); @@ -1111,14 +1118,14 @@ static int rx_macro_mclk_ctrl(struct device *dev, bool enable) return 0; } -static int rx_macro_event_handler(struct snd_soc_codec *codec, u16 event, - u32 data) +static int rx_macro_event_handler(struct snd_soc_component *component, + u16 event, u32 data) { u16 reg = 0, reg_mix = 0, rx_idx = 0, mute = 0x0, val = 0; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; switch (event) { @@ -1130,14 +1137,16 @@ static int rx_macro_event_handler(struct snd_soc_codec *codec, u16 event, RX_MACRO_RX_PATH_OFFSET); reg_mix = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL + (rx_idx * RX_MACRO_RX_PATH_OFFSET); - snd_soc_update_bits(codec, reg, 0x10, val); - snd_soc_update_bits(codec, reg_mix, 0x10, val); + snd_soc_component_update_bits(component, reg, + 0x10, val); + snd_soc_component_update_bits(component, reg_mix, + 0x10, val); break; case BOLERO_MACRO_EVT_IMPED_TRUE: - rx_macro_wcd_clsh_imped_config(codec, data, true); + rx_macro_wcd_clsh_imped_config(component, data, true); break; case BOLERO_MACRO_EVT_IMPED_FALSE: - rx_macro_wcd_clsh_imped_config(codec, data, false); + rx_macro_wcd_clsh_imped_config(component, data, false); break; case BOLERO_MACRO_EVT_SSR_DOWN: rx_priv->dev_up = false; @@ -1176,7 +1185,7 @@ static int rx_macro_find_playback_dai_id_for_port(int port_id, return -EINVAL; } -static int rx_macro_set_idle_detect_thr(struct snd_soc_codec *codec, +static int rx_macro_set_idle_detect_thr(struct snd_soc_component *component, struct rx_macro_priv *rx_priv, int interp, int path_type) { @@ -1204,7 +1213,8 @@ static int rx_macro_set_idle_detect_thr(struct snd_soc_codec *codec, if (path_type == INTERP_MIX_PATH) { mux_reg = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1 + 2 * interp; - mux_reg_val = snd_soc_read(codec, mux_reg) & 0x0f; + mux_reg_val = snd_soc_component_read32(component, mux_reg) & + 0x0f; if ((mux_reg_val >= INTn_2_INP_SEL_RX0) && (mux_reg_val <= INTn_2_INP_SEL_RX5)) { @@ -1216,7 +1226,8 @@ static int rx_macro_set_idle_detect_thr(struct snd_soc_codec *codec, if (path_type == INTERP_MAIN_PATH) { mux_reg = BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0 + 2 * (interp - 1); - mux_reg_val = snd_soc_read(codec, mux_reg) & 0x0f; + mux_reg_val = snd_soc_component_read32(component, mux_reg) & + 0x0f; i = RX_MACRO_INTERP_MUX_NUM_INPUTS; while (i) { @@ -1226,14 +1237,15 @@ static int rx_macro_set_idle_detect_thr(struct snd_soc_codec *codec, INTn_1_INP_SEL_RX0; num_ports++; } - mux_reg_val = (snd_soc_read(codec, mux_reg) & - 0xf0) >> 4; + mux_reg_val = + (snd_soc_component_read32(component, mux_reg) & + 0xf0) >> 4; mux_reg += 1; i--; } } - dev_dbg(codec->dev, "%s: num_ports: %d, ports[%d %d %d %d]\n", + dev_dbg(component->dev, "%s: num_ports: %d, ports[%d %d %d %d]\n", __func__, num_ports, port_id[0], port_id[1], port_id[2], port_id[3]); @@ -1243,7 +1255,7 @@ static int rx_macro_set_idle_detect_thr(struct snd_soc_codec *codec, rx_priv); if ((dai_id >= 0) && (dai_id < RX_MACRO_MAX_DAIS)) { - dev_dbg(codec->dev, "%s: dai_id: %d bit_width: %d\n", + dev_dbg(component->dev, "%s: dai_id: %d bit_width: %d\n", __func__, dai_id, rx_priv->bit_width[dai_id]); @@ -1266,12 +1278,13 @@ static int rx_macro_set_idle_detect_thr(struct snd_soc_codec *codec, break; } - dev_dbg(codec->dev, "%s: (new) idle_thr: %d, (cur) idle_thr: %d\n", + dev_dbg(component->dev, "%s: (new) idle_thr: %d, (cur) idle_thr: %d\n", __func__, idle_thr, rx_priv->idle_det_cfg.hph_idle_thr); if ((rx_priv->idle_det_cfg.hph_idle_thr == 0) || (idle_thr < rx_priv->idle_det_cfg.hph_idle_thr)) { - snd_soc_write(codec, BOLERO_CDC_RX_IDLE_DETECT_CFG3, idle_thr); + snd_soc_component_write(component, + BOLERO_CDC_RX_IDLE_DETECT_CFG3, idle_thr); rx_priv->idle_det_cfg.hph_idle_thr = idle_thr; } @@ -1281,16 +1294,17 @@ static int rx_macro_set_idle_detect_thr(struct snd_soc_codec *codec, static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); u16 gain_reg = 0, mix_reg = 0; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; if (w->shift >= INTERP_MAX) { - dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", + dev_err(component->dev, "%s: Invalid Interpolator value %d for name %s\n", __func__, w->shift, w->name); return -EINVAL; } @@ -1300,27 +1314,27 @@ static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w, mix_reg = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL + (w->shift * RX_MACRO_RX_PATH_OFFSET); - dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name); switch (event) { case SND_SOC_DAPM_PRE_PMU: - rx_macro_set_idle_detect_thr(codec, rx_priv, w->shift, + rx_macro_set_idle_detect_thr(component, rx_priv, w->shift, INTERP_MIX_PATH); - rx_macro_enable_interp_clk(codec, event, w->shift); + rx_macro_enable_interp_clk(component, event, w->shift); /* Clk enable */ - snd_soc_update_bits(codec, mix_reg, 0x20, 0x20); + snd_soc_component_update_bits(component, mix_reg, 0x20, 0x20); break; case SND_SOC_DAPM_POST_PMU: - snd_soc_write(codec, gain_reg, - snd_soc_read(codec, gain_reg)); + snd_soc_component_write(component, gain_reg, + snd_soc_component_read32(component, gain_reg)); break; case SND_SOC_DAPM_POST_PMD: /* Clk Disable */ - snd_soc_update_bits(codec, mix_reg, 0x20, 0x00); - rx_macro_enable_interp_clk(codec, event, w->shift); + snd_soc_component_update_bits(component, mix_reg, 0x20, 0x00); + rx_macro_enable_interp_clk(component, event, w->shift); /* Reset enable and disable */ - snd_soc_update_bits(codec, mix_reg, 0x40, 0x40); - snd_soc_update_bits(codec, mix_reg, 0x40, 0x00); + snd_soc_component_update_bits(component, mix_reg, 0x40, 0x40); + snd_soc_component_update_bits(component, mix_reg, 0x40, 0x00); break; } @@ -1331,19 +1345,20 @@ static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); u16 gain_reg = 0; u16 reg = 0; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; - dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name); if (w->shift >= INTERP_MAX) { - dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", + dev_err(component->dev, "%s: Invalid Interpolator value %d for name %s\n", __func__, w->shift, w->name); return -EINVAL; } @@ -1355,23 +1370,23 @@ static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - rx_macro_set_idle_detect_thr(codec, rx_priv, w->shift, + rx_macro_set_idle_detect_thr(component, rx_priv, w->shift, INTERP_MAIN_PATH); - rx_macro_enable_interp_clk(codec, event, w->shift); + rx_macro_enable_interp_clk(component, event, w->shift); break; case SND_SOC_DAPM_POST_PMU: - snd_soc_write(codec, gain_reg, - snd_soc_read(codec, gain_reg)); + snd_soc_component_write(component, gain_reg, + snd_soc_component_read32(component, gain_reg)); break; case SND_SOC_DAPM_POST_PMD: - rx_macro_enable_interp_clk(codec, event, w->shift); + rx_macro_enable_interp_clk(component, event, w->shift); break; } return 0; } -static int rx_macro_config_compander(struct snd_soc_codec *codec, +static int rx_macro_config_compander(struct snd_soc_component *component, struct rx_macro_priv *rx_priv, int interp_n, int event) { @@ -1383,7 +1398,7 @@ static int rx_macro_config_compander(struct snd_soc_codec *codec, return 0; comp = interp_n; - dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n", + dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n", __func__, event, comp + 1, rx_priv->comp_enabled[comp]); if (!rx_priv->comp_enabled[comp]) @@ -1396,46 +1411,54 @@ static int rx_macro_config_compander(struct snd_soc_codec *codec, if (SND_SOC_DAPM_EVENT_ON(event)) { /* Enable Compander Clock */ - snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x01, 0x01); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x02); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x00); + snd_soc_component_update_bits(component, rx_path_cfg0_reg, + 0x02, 0x02); } if (SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); - snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x04, 0x04); + snd_soc_component_update_bits(component, rx_path_cfg0_reg, + 0x02, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x01, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x04, 0x00); } return 0; } -static void rx_macro_enable_softclip_clk(struct snd_soc_codec *codec, +static void rx_macro_enable_softclip_clk(struct snd_soc_component *component, struct rx_macro_priv *rx_priv, bool enable) { if (enable) { if (rx_priv->softclip_clk_users == 0) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_SOFTCLIP_CRC, 0x01, 0x01); rx_priv->softclip_clk_users++; } else { rx_priv->softclip_clk_users--; if (rx_priv->softclip_clk_users == 0) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_SOFTCLIP_CRC, 0x01, 0x00); } } -static int rx_macro_config_softclip(struct snd_soc_codec *codec, +static int rx_macro_config_softclip(struct snd_soc_component *component, struct rx_macro_priv *rx_priv, int event) { - dev_dbg(codec->dev, "%s: event %d, enabled %d\n", + dev_dbg(component->dev, "%s: event %d, enabled %d\n", __func__, event, rx_priv->is_softclip_on); if (!rx_priv->is_softclip_on) @@ -1443,16 +1466,16 @@ static int rx_macro_config_softclip(struct snd_soc_codec *codec, if (SND_SOC_DAPM_EVENT_ON(event)) { /* Enable Softclip clock */ - rx_macro_enable_softclip_clk(codec, rx_priv, true); + rx_macro_enable_softclip_clk(component, rx_priv, true); /* Enable Softclip control */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x01, 0x01); } if (SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x01, 0x00); - rx_macro_enable_softclip_clk(codec, rx_priv, false); + rx_macro_enable_softclip_clk(component, rx_priv, false); } return 0; @@ -1463,7 +1486,7 @@ rx_macro_enable_clsh_block(struct rx_macro_priv *rx_priv, bool enable) { if ((enable && ++rx_priv->clsh_users == 1) || (!enable && --rx_priv->clsh_users == 0)) - snd_soc_update_bits(rx_priv->codec, + snd_soc_component_update_bits(rx_priv->component, BOLERO_CDC_RX_CLSH_CRC, 0x01, (u8) enable); if (rx_priv->clsh_users < 0) @@ -1472,7 +1495,7 @@ rx_macro_enable_clsh_block(struct rx_macro_priv *rx_priv, bool enable) rx_priv->clsh_users, enable); } -static int rx_macro_config_classh(struct snd_soc_codec *codec, +static int rx_macro_config_classh(struct snd_soc_component *component, struct rx_macro_priv *rx_priv, int interp_n, int event) { @@ -1491,36 +1514,44 @@ static int rx_macro_config_classh(struct snd_soc_codec *codec, * These K1 values depend on the Headphone Impedance * For now it is assumed to be 16 ohm */ - snd_soc_update_bits(codec, BOLERO_CDC_RX_CLSH_K1_LSB, - 0xFF, 0xC0); - snd_soc_update_bits(codec, BOLERO_CDC_RX_CLSH_K1_MSB, - 0x0F, 0x00); + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_CLSH_K1_LSB, + 0xFF, 0xC0); + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_CLSH_K1_MSB, + 0x0F, 0x00); } switch (interp_n) { case INTERP_HPHL: if (rx_priv->is_ear_mode_on) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_CLSH_HPH_V_PA, 0x3F, 0x39); else - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_CLSH_HPH_V_PA, 0x3F, 0x1C); - snd_soc_update_bits(codec, BOLERO_CDC_RX_CLSH_DECAY_CTRL, + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_CLSH_DECAY_CTRL, 0x07, 0x00); - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX0_RX_PATH_CFG0, + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX0_RX_PATH_CFG0, 0x40, 0x40); break; case INTERP_HPHR: - snd_soc_update_bits(codec, BOLERO_CDC_RX_CLSH_HPH_V_PA, + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_CLSH_HPH_V_PA, 0x3F, 0x1C); - snd_soc_update_bits(codec, BOLERO_CDC_RX_CLSH_DECAY_CTRL, + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_CLSH_DECAY_CTRL, 0x07, 0x00); - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX1_RX_PATH_CFG0, + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX1_RX_PATH_CFG0, 0x40, 0x40); break; case INTERP_AUX: - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG0, + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX2_RX_PATH_CFG0, 0x10, 0x10); break; } @@ -1528,7 +1559,7 @@ static int rx_macro_config_classh(struct snd_soc_codec *codec, return 0; } -static void rx_macro_hd2_control(struct snd_soc_codec *codec, +static void rx_macro_hd2_control(struct snd_soc_component *component, u16 interp_idx, int event) { u16 hd2_scale_reg = 0; @@ -1546,26 +1577,31 @@ static void rx_macro_hd2_control(struct snd_soc_codec *codec, } if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { - snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x14); - snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x04); + snd_soc_component_update_bits(component, hd2_scale_reg, + 0x3C, 0x14); + snd_soc_component_update_bits(component, hd2_enable_reg, + 0x04, 0x04); } if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x00); - snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x00); + snd_soc_component_update_bits(component, hd2_enable_reg, + 0x04, 0x00); + snd_soc_component_update_bits(component, hd2_scale_reg, + 0x3C, 0x00); } } static int rx_macro_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int comp = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; ucontrol->value.integer.value[0] = rx_priv->comp_enabled[comp]; @@ -1575,17 +1611,18 @@ static int rx_macro_get_compander(struct snd_kcontrol *kcontrol, static int rx_macro_set_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int comp = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; int value = ucontrol->value.integer.value[0]; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; - dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n", + dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n", __func__, comp + 1, rx_priv->comp_enabled[comp], value); rx_priv->comp_enabled[comp] = value; @@ -1597,11 +1634,12 @@ static int rx_macro_mux_get(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; ucontrol->value.integer.value[0] = @@ -1614,7 +1652,8 @@ static int rx_macro_mux_put(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct snd_soc_dapm_update *update = NULL; u32 rx_port_value = ucontrol->value.integer.value[0]; @@ -1622,7 +1661,7 @@ static int rx_macro_mux_put(struct snd_kcontrol *kcontrol, struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; aif_rst = rx_priv->rx_port_value[widget->shift]; @@ -1649,7 +1688,7 @@ static int rx_macro_mux_put(struct snd_kcontrol *kcontrol, rx_priv->active_ch_cnt[rx_port_value]++; break; default: - dev_err(codec->dev, + dev_err(component->dev, "%s:Invalid AIF_ID for RX_MACRO MUX\n", __func__); goto err; } @@ -1664,11 +1703,12 @@ static int rx_macro_mux_put(struct snd_kcontrol *kcontrol, static int rx_macro_get_ear_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; ucontrol->value.integer.value[0] = rx_priv->is_ear_mode_on; @@ -1678,11 +1718,12 @@ static int rx_macro_get_ear_mode(struct snd_kcontrol *kcontrol, static int rx_macro_put_ear_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; rx_priv->is_ear_mode_on = @@ -1693,11 +1734,12 @@ static int rx_macro_put_ear_mode(struct snd_kcontrol *kcontrol, static int rx_macro_get_hph_hd2_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; ucontrol->value.integer.value[0] = rx_priv->hph_hd2_mode; @@ -1707,11 +1749,12 @@ static int rx_macro_get_hph_hd2_mode(struct snd_kcontrol *kcontrol, static int rx_macro_put_hph_hd2_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; rx_priv->hph_hd2_mode = ucontrol->value.integer.value[0]; @@ -1721,11 +1764,12 @@ static int rx_macro_put_hph_hd2_mode(struct snd_kcontrol *kcontrol, static int rx_macro_get_hph_pwr_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; ucontrol->value.integer.value[0] = rx_priv->hph_pwr_mode; @@ -1735,11 +1779,12 @@ static int rx_macro_get_hph_pwr_mode(struct snd_kcontrol *kcontrol, static int rx_macro_put_hph_pwr_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; rx_priv->hph_pwr_mode = ucontrol->value.integer.value[0]; @@ -1749,13 +1794,15 @@ static int rx_macro_put_hph_pwr_mode(struct snd_kcontrol *kcontrol, static int rx_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); ucontrol->value.integer.value[0] = - ((snd_soc_read(codec, BOLERO_CDC_RX_BCL_VBAT_CFG) & 0x04) ? + ((snd_soc_component_read32( + component, BOLERO_CDC_RX_BCL_VBAT_CFG) & 0x04) ? 1 : 0); - dev_dbg(codec->dev, "%s: value: %lu\n", __func__, + dev_dbg(component->dev, "%s: value: %lu\n", __func__, ucontrol->value.integer.value[0]); return 0; @@ -1764,18 +1811,21 @@ static int rx_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol, static int rx_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - dev_dbg(codec->dev, "%s: value: %lu\n", __func__, + dev_dbg(component->dev, "%s: value: %lu\n", __func__, ucontrol->value.integer.value[0]); /* Set Vbat register configuration for GSM mode bit based on value */ if (ucontrol->value.integer.value[0]) - snd_soc_update_bits(codec, BOLERO_CDC_RX_BCL_VBAT_CFG, - 0x04, 0x04); + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_BCL_VBAT_CFG, + 0x04, 0x04); else - snd_soc_update_bits(codec, BOLERO_CDC_RX_BCL_VBAT_CFG, - 0x04, 0x00); + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_BCL_VBAT_CFG, + 0x04, 0x00); return 0; } @@ -1783,16 +1833,17 @@ static int rx_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol, static int rx_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; ucontrol->value.integer.value[0] = rx_priv->is_softclip_on; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); return 0; @@ -1801,16 +1852,17 @@ static int rx_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol, static int rx_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; - rx_priv->is_softclip_on = ucontrol->value.integer.value[0]; + rx_priv->is_softclip_on = ucontrol->value.integer.value[0]; - dev_dbg(codec->dev, "%s: soft clip enable = %d\n", __func__, + dev_dbg(component->dev, "%s: soft clip enable = %d\n", __func__, rx_priv->is_softclip_on); return 0; @@ -1820,108 +1872,113 @@ static int rx_macro_enable_vbat(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; switch (event) { case SND_SOC_DAPM_PRE_PMU: /* Enable clock for VBAT block */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_PATH_CTL, 0x10, 0x10); /* Enable VBAT block */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_CFG, 0x01, 0x01); /* Update interpolator with 384K path */ - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG1, - 0x80, 0x80); + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX2_RX_PATH_CFG1, 0x80, 0x80); /* Update DSM FS rate */ - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_SEC7, - 0x02, 0x02); + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX2_RX_PATH_SEC7, 0x02, 0x02); /* Use attenuation mode */ - snd_soc_update_bits(codec, BOLERO_CDC_RX_BCL_VBAT_CFG, - 0x02, 0x00); + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_BCL_VBAT_CFG, 0x02, 0x00); /* BCL block needs softclip clock to be enabled */ - rx_macro_enable_softclip_clk(codec, rx_priv, true); + rx_macro_enable_softclip_clk(component, rx_priv, true); /* Enable VBAT at channel level */ - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG1, - 0x02, 0x02); + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX2_RX_PATH_CFG1, 0x02, 0x02); /* Set the ATTK1 gain */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1, 0xFF, 0xFF); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2, 0xFF, 0x03); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3, 0xFF, 0x00); /* Set the ATTK2 gain */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4, 0xFF, 0xFF); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5, 0xFF, 0x03); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6, 0xFF, 0x00); /* Set the ATTK3 gain */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7, 0xFF, 0xFF); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8, 0xFF, 0x03); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9, 0xFF, 0x00); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG1, - 0x80, 0x00); - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_SEC7, - 0x02, 0x00); - snd_soc_update_bits(codec, BOLERO_CDC_RX_BCL_VBAT_CFG, - 0x02, 0x02); - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG1, - 0x02, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX2_RX_PATH_CFG1, + 0x80, 0x00); + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX2_RX_PATH_SEC7, + 0x02, 0x00); + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_BCL_VBAT_CFG, + 0x02, 0x02); + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX2_RX_PATH_CFG1, + 0x02, 0x00); + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1, 0xFF, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2, 0xFF, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3, 0xFF, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4, 0xFF, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5, 0xFF, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6, 0xFF, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7, 0xFF, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8, 0xFF, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9, 0xFF, 0x00); - rx_macro_enable_softclip_clk(codec, rx_priv, false); - snd_soc_update_bits(codec, + rx_macro_enable_softclip_clk(component, rx_priv, false); + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_CFG, 0x01, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_PATH_CTL, 0x10, 0x00); break; default: @@ -1931,7 +1988,7 @@ static int rx_macro_enable_vbat(struct snd_soc_dapm_widget *w, return 0; } -static void rx_macro_idle_detect_control(struct snd_soc_codec *codec, +static void rx_macro_idle_detect_control(struct snd_soc_component *component, struct rx_macro_priv *rx_priv, int interp, int event) { @@ -1952,16 +2009,17 @@ static void rx_macro_idle_detect_control(struct snd_soc_codec *codec, } if (reg && SND_SOC_DAPM_EVENT_ON(event)) - snd_soc_update_bits(codec, reg, mask, val); + snd_soc_component_update_bits(component, reg, mask, val); if (reg && SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, reg, mask, 0x00); + snd_soc_component_update_bits(component, reg, mask, 0x00); rx_priv->idle_det_cfg.hph_idle_thr = 0; - snd_soc_write(codec, BOLERO_CDC_RX_IDLE_DETECT_CFG3, 0x0); + snd_soc_component_write(component, + BOLERO_CDC_RX_IDLE_DETECT_CFG3, 0x0); } } -static void rx_macro_hphdelay_lutbypass(struct snd_soc_codec *codec, +static void rx_macro_hphdelay_lutbypass(struct snd_soc_component *component, struct rx_macro_priv *rx_priv, u16 interp_idx, int event) { @@ -1984,43 +2042,48 @@ static void rx_macro_hphdelay_lutbypass(struct snd_soc_codec *codec, if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) { if (interp_idx == INTERP_HPHL) { if (rx_priv->is_ear_mode_on) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX0_RX_PATH_CFG1, 0x02, 0x02); else - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, hph_lut_bypass_reg, 0x80, 0x80); } else { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, hph_lut_bypass_reg, 0x80, 0x80); } if (rx_priv->hph_pwr_mode) - snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x00); + snd_soc_component_update_bits(component, + hph_comp_ctrl7, + 0x20, 0x00); } if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX0_RX_PATH_CFG1, + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX0_RX_PATH_CFG1, 0x02, 0x00); - snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x00); - snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x20); + snd_soc_component_update_bits(component, hph_lut_bypass_reg, + 0x80, 0x00); + snd_soc_component_update_bits(component, hph_comp_ctrl7, + 0x20, 0x0); } } -static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, +static int rx_macro_enable_interp_clk(struct snd_soc_component *component, int event, int interp_idx) { u16 main_reg = 0, dsm_reg = 0, rx_cfg2_reg = 0; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!codec) { - pr_err("%s: codec is NULL\n", __func__); + if (!component) { + pr_err("%s: component is NULL\n", __func__); return -EINVAL; } - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; main_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + @@ -2032,24 +2095,29 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, if (SND_SOC_DAPM_EVENT_ON(event)) { if (rx_priv->main_clk_users[interp_idx] == 0) { - snd_soc_update_bits(codec, dsm_reg, 0x01, 0x01); + snd_soc_component_update_bits(component, dsm_reg, + 0x01, 0x01); /* Main path PGA mute enable */ - snd_soc_update_bits(codec, main_reg, 0x10, 0x10); + snd_soc_component_update_bits(component, main_reg, + 0x10, 0x10); /* Clk enable */ - snd_soc_update_bits(codec, main_reg, 0x20, 0x20); - snd_soc_update_bits(codec, rx_cfg2_reg, 0x03, 0x03); - rx_macro_idle_detect_control(codec, rx_priv, + snd_soc_component_update_bits(component, main_reg, + 0x20, 0x20); + snd_soc_component_update_bits(component, rx_cfg2_reg, + 0x03, 0x03); + rx_macro_idle_detect_control(component, rx_priv, interp_idx, event); if (rx_priv->hph_hd2_mode) - rx_macro_hd2_control(codec, interp_idx, event); - rx_macro_hphdelay_lutbypass(codec, rx_priv, interp_idx, - event); - rx_macro_config_compander(codec, rx_priv, + rx_macro_hd2_control( + component, interp_idx, event); + rx_macro_hphdelay_lutbypass(component, rx_priv, + interp_idx, event); + rx_macro_config_compander(component, rx_priv, interp_idx, event); if (interp_idx == INTERP_AUX) - rx_macro_config_softclip(codec, rx_priv, + rx_macro_config_softclip(component, rx_priv, event); - rx_macro_config_classh(codec, rx_priv, + rx_macro_config_classh(component, rx_priv, interp_idx, event); } rx_priv->main_clk_users[interp_idx]++; @@ -2060,31 +2128,38 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, if (rx_priv->main_clk_users[interp_idx] <= 0) { rx_priv->main_clk_users[interp_idx] = 0; /* Clk Disable */ - snd_soc_update_bits(codec, dsm_reg, 0x01, 0x00); - snd_soc_update_bits(codec, main_reg, 0x20, 0x00); + snd_soc_component_update_bits(component, dsm_reg, + 0x01, 0x00); + snd_soc_component_update_bits(component, main_reg, + 0x20, 0x00); /* Reset enable and disable */ - snd_soc_update_bits(codec, main_reg, 0x40, 0x40); - snd_soc_update_bits(codec, main_reg, 0x40, 0x00); + snd_soc_component_update_bits(component, main_reg, + 0x40, 0x40); + snd_soc_component_update_bits(component, main_reg, + 0x40, 0x00); /* Reset rate to 48K*/ - snd_soc_update_bits(codec, main_reg, 0x0F, 0x04); - snd_soc_update_bits(codec, rx_cfg2_reg, 0x03, 0x00); - rx_macro_config_classh(codec, rx_priv, + snd_soc_component_update_bits(component, main_reg, + 0x0F, 0x04); + snd_soc_component_update_bits(component, rx_cfg2_reg, + 0x03, 0x00); + rx_macro_config_classh(component, rx_priv, interp_idx, event); - rx_macro_config_compander(codec, rx_priv, + rx_macro_config_compander(component, rx_priv, interp_idx, event); if (interp_idx == INTERP_AUX) - rx_macro_config_softclip(codec, rx_priv, + rx_macro_config_softclip(component, rx_priv, event); - rx_macro_hphdelay_lutbypass(codec, rx_priv, interp_idx, - event); + rx_macro_hphdelay_lutbypass(component, rx_priv, + interp_idx, event); if (rx_priv->hph_hd2_mode) - rx_macro_hd2_control(codec, interp_idx, event); - rx_macro_idle_detect_control(codec, rx_priv, + rx_macro_hd2_control(component, interp_idx, + event); + rx_macro_idle_detect_control(component, rx_priv, interp_idx, event); } } - dev_dbg(codec->dev, "%s event %d main_clk_users %d\n", + dev_dbg(component->dev, "%s event %d main_clk_users %d\n", __func__, event, rx_priv->main_clk_users[interp_idx]); return rx_priv->main_clk_users[interp_idx]; @@ -2093,21 +2168,24 @@ static int rx_macro_enable_interp_clk(struct snd_soc_codec *codec, static int rx_macro_enable_rx_path_clk(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); u16 sidetone_reg = 0; - dev_dbg(codec->dev, "%s %d %d\n", __func__, event, w->shift); + dev_dbg(component->dev, "%s %d %d\n", __func__, event, w->shift); sidetone_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG1 + RX_MACRO_RX_PATH_OFFSET * (w->shift); switch (event) { case SND_SOC_DAPM_PRE_PMU: - rx_macro_enable_interp_clk(codec, event, w->shift); - snd_soc_update_bits(codec, sidetone_reg, 0x10, 0x10); + rx_macro_enable_interp_clk(component, event, w->shift); + snd_soc_component_update_bits(component, sidetone_reg, + 0x10, 0x10); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, sidetone_reg, 0x10, 0x00); - rx_macro_enable_interp_clk(codec, event, w->shift); + snd_soc_component_update_bits(component, sidetone_reg, + 0x10, 0x00); + rx_macro_enable_interp_clk(component, event, w->shift); break; default: break; @@ -2150,7 +2228,8 @@ static void rx_macro_restore_iir_coeff(struct rx_macro_priv *rx_priv, int iir_id static int rx_macro_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int iir_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->reg; int band_idx = ((struct soc_multi_mixer_control *) @@ -2158,10 +2237,11 @@ static int rx_macro_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol, /* IIR filter band registers are at integer multiples of 0x80 */ u16 iir_reg = BOLERO_CDC_RX_SIDETONE_IIR0_IIR_CTL + 0x80 * iir_idx; - ucontrol->value.integer.value[0] = (snd_soc_read(codec, iir_reg) & - (1 << band_idx)) != 0; + ucontrol->value.integer.value[0] = ( + snd_soc_component_read32(component, iir_reg) & + (1 << band_idx)) != 0; - dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, + dev_dbg(component->dev, "%s: IIR #%d band #%d enable %d\n", __func__, iir_idx, band_idx, (uint32_t)ucontrol->value.integer.value[0]); return 0; @@ -2170,7 +2250,8 @@ static int rx_macro_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol, static int rx_macro_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int iir_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->reg; int band_idx = ((struct soc_multi_mixer_control *) @@ -2181,62 +2262,62 @@ static int rx_macro_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol, struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; rx_macro_restore_iir_coeff(rx_priv, iir_idx, band_idx); /* Mask first 5 bits, 6-8 are reserved */ - snd_soc_update_bits(codec, iir_reg, (1 << band_idx), + snd_soc_component_update_bits(component, iir_reg, (1 << band_idx), (value << band_idx)); - iir_band_en_status = ((snd_soc_read(codec, iir_reg) & + iir_band_en_status = ((snd_soc_component_read32(component, iir_reg) & (1 << band_idx)) != 0); - dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, + dev_dbg(component->dev, "%s: IIR #%d band #%d enable %d\n", __func__, iir_idx, band_idx, iir_band_en_status); return 0; } -static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec, +static uint32_t get_iir_band_coeff(struct snd_soc_component *component, int iir_idx, int band_idx, int coeff_idx) { uint32_t value = 0; /* Address does not automatically update if reading */ - snd_soc_write(codec, + snd_soc_component_write(component, (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx), ((band_idx * BAND_MAX + coeff_idx) * sizeof(uint32_t)) & 0x7F); - value |= snd_soc_read(codec, + value |= snd_soc_component_read32(component, (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx)); - snd_soc_write(codec, + snd_soc_component_write(component, (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx), ((band_idx * BAND_MAX + coeff_idx) * sizeof(uint32_t) + 1) & 0x7F); - value |= (snd_soc_read(codec, + value |= (snd_soc_component_read32(component, (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx)) << 8); - snd_soc_write(codec, + snd_soc_component_write(component, (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx), ((band_idx * BAND_MAX + coeff_idx) * sizeof(uint32_t) + 2) & 0x7F); - value |= (snd_soc_read(codec, + value |= (snd_soc_component_read32(component, (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx)) << 16); - snd_soc_write(codec, + snd_soc_component_write(component, (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx), ((band_idx * BAND_MAX + coeff_idx) * sizeof(uint32_t) + 3) & 0x7F); /* Mask bits top 2 bits since they are reserved */ - value |= ((snd_soc_read(codec, + value |= ((snd_soc_component_read32(component, (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx)) & 0x3F) << 24); @@ -2246,24 +2327,25 @@ static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec, static int rx_macro_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int iir_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->reg; int band_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; ucontrol->value.integer.value[0] = - get_iir_band_coeff(codec, iir_idx, band_idx, 0); + get_iir_band_coeff(component, iir_idx, band_idx, 0); ucontrol->value.integer.value[1] = - get_iir_band_coeff(codec, iir_idx, band_idx, 1); + get_iir_band_coeff(component, iir_idx, band_idx, 1); ucontrol->value.integer.value[2] = - get_iir_band_coeff(codec, iir_idx, band_idx, 2); + get_iir_band_coeff(component, iir_idx, band_idx, 2); ucontrol->value.integer.value[3] = - get_iir_band_coeff(codec, iir_idx, band_idx, 3); + get_iir_band_coeff(component, iir_idx, band_idx, 3); ucontrol->value.integer.value[4] = - get_iir_band_coeff(codec, iir_idx, band_idx, 4); + get_iir_band_coeff(component, iir_idx, band_idx, 4); - dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n" + dev_dbg(component->dev, "%s: IIR #%d band #%d b0 = 0x%x\n" "%s: IIR #%d band #%d b1 = 0x%x\n" "%s: IIR #%d band #%d b2 = 0x%x\n" "%s: IIR #%d band #%d a1 = 0x%x\n" @@ -2281,24 +2363,24 @@ static int rx_macro_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol, return 0; } -static void set_iir_band_coeff(struct snd_soc_codec *codec, +static void set_iir_band_coeff(struct snd_soc_component *component, int iir_idx, int band_idx, uint32_t value) { - snd_soc_write(codec, + snd_soc_component_write(component, (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx), (value & 0xFF)); - snd_soc_write(codec, + snd_soc_component_write(component, (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx), (value >> 8) & 0xFF); - snd_soc_write(codec, + snd_soc_component_write(component, (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx), (value >> 16) & 0xFF); /* Mask top 2 bits, 7-8 are reserved */ - snd_soc_write(codec, + snd_soc_component_write(component, (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx), (value >> 24) & 0x3F); } @@ -2306,7 +2388,8 @@ static void set_iir_band_coeff(struct snd_soc_codec *codec, static int rx_macro_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int iir_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->reg; int band_idx = ((struct soc_multi_mixer_control *) @@ -2315,14 +2398,14 @@ static int rx_macro_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; /* * Mask top bit it is reserved * Updates addr automatically for each B2 write */ - snd_soc_write(codec, + snd_soc_component_write(component, (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); @@ -2331,7 +2414,7 @@ static int rx_macro_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, coeff_idx++) { uint32_t value = ucontrol->value.integer.value[coeff_idx]; - set_iir_band_coeff(codec, iir_idx, band_idx, value); + set_iir_band_coeff(component, iir_idx, band_idx, value); /* Four 8 bit values(one 32 bit) per coefficient */ rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] = @@ -2350,61 +2433,62 @@ static int rx_macro_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, "%s: IIR #%d band #%d a1 = 0x%x\n" "%s: IIR #%d band #%d a2 = 0x%x\n", __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 0), + get_iir_band_coeff(component, iir_idx, band_idx, 0), __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 1), + get_iir_band_coeff(component, iir_idx, band_idx, 1), __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 2), + get_iir_band_coeff(component, iir_idx, band_idx, 2), __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 3), + get_iir_band_coeff(component, iir_idx, band_idx, 3), __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 4)); + get_iir_band_coeff(component, iir_idx, band_idx, 4)); return 0; } static int rx_macro_set_iir_gain(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); - dev_dbg(codec->dev, "%s: event = %d\n", __func__, event); + dev_dbg(component->dev, "%s: event = %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_POST_PMU: /* fall through */ case SND_SOC_DAPM_PRE_PMD: if (strnstr(w->name, "IIR0", sizeof("IIR0"))) { - snd_soc_write(codec, + snd_soc_component_write(component, BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL)); } else { - snd_soc_write(codec, + snd_soc_component_write(component, BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL)); } break; @@ -3018,43 +3102,43 @@ static int rx_swrm_clock(void *handle, bool enable) return ret; } -static void rx_macro_init_bcl_pmic_reg(struct snd_soc_codec *codec) +static void rx_macro_init_bcl_pmic_reg(struct snd_soc_component *component) { struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!codec) { - pr_err("%s: NULL codec pointer!\n", __func__); + if (!component) { + pr_err("%s: NULL component pointer!\n", __func__); return; } - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return; switch (rx_priv->bcl_pmic_params.id) { case 0: /* Enable ID0 to listen to respective PMIC group interrupts */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1, 0x02, 0x02); /* Update MC_SID0 */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1, 0x0F, rx_priv->bcl_pmic_params.sid); /* Update MC_PPID0 */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG2, 0xFF, rx_priv->bcl_pmic_params.ppid); break; case 1: /* Enable ID1 to listen to respective PMIC group interrupts */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1, 0x01, 0x01); /* Update MC_SID1 */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG3, 0x0F, rx_priv->bcl_pmic_params.sid); /* Update MC_PPID1 */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1, 0xFF, rx_priv->bcl_pmic_params.ppid); break; @@ -3065,22 +3149,23 @@ static void rx_macro_init_bcl_pmic_reg(struct snd_soc_codec *codec) } } -static int rx_macro_init(struct snd_soc_codec *codec) +static int rx_macro_init(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); int ret = 0; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - rx_dev = bolero_get_device_ptr(codec->dev, RX_MACRO); + rx_dev = bolero_get_device_ptr(component->dev, RX_MACRO); if (!rx_dev) { - dev_err(codec->dev, + dev_err(component->dev, "%s: null device for macro!\n", __func__); return -EINVAL; } rx_priv = dev_get_drvdata(rx_dev); if (!rx_priv) { - dev_err(codec->dev, + dev_err(component->dev, "%s: priv is null for macro!\n", __func__); return -EINVAL; } @@ -3102,7 +3187,7 @@ static int rx_macro_init(struct snd_soc_codec *codec) dev_err(rx_dev, "%s: failed to add widgets\n", __func__); return ret; } - ret = snd_soc_add_codec_controls(codec, rx_macro_snd_controls, + ret = snd_soc_add_component_controls(component, rx_macro_snd_controls, ARRAY_SIZE(rx_macro_snd_controls)); if (ret < 0) { dev_err(rx_dev, "%s: failed to add snd_ctls\n", __func__); @@ -3122,31 +3207,44 @@ static int rx_macro_init(struct snd_soc_codec *codec) snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC3_INP"); snd_soc_dapm_sync(dapm); - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL, 0x01, 0x01); - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX1_RX_PATH_DSM_CTL, 0x01, 0x01); - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL, 0x01, 0x01); - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX0_RX_PATH_SEC7, 0x07, 0x02); - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX1_RX_PATH_SEC7, 0x07, 0x02); - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_SEC7, 0x07, 0x02); - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX0_RX_PATH_CFG3, 0x03, 0x02); - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX1_RX_PATH_CFG3, 0x03, 0x02); - snd_soc_update_bits(codec, BOLERO_CDC_RX_RX2_RX_PATH_CFG3, 0x03, 0x02); - rx_macro_init_bcl_pmic_reg(codec); - - rx_priv->codec = codec; + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL, + 0x01, 0x01); + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX1_RX_PATH_DSM_CTL, + 0x01, 0x01); + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL, + 0x01, 0x01); + snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX0_RX_PATH_SEC7, + 0x07, 0x02); + snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX1_RX_PATH_SEC7, + 0x07, 0x02); + snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX2_RX_PATH_SEC7, + 0x07, 0x02); + snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX0_RX_PATH_CFG3, + 0x03, 0x02); + snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX1_RX_PATH_CFG3, + 0x03, 0x02); + snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX2_RX_PATH_CFG3, + 0x03, 0x02); + + rx_macro_init_bcl_pmic_reg(component); + + rx_priv->component = component; return 0; } -static int rx_macro_deinit(struct snd_soc_codec *codec) +static int rx_macro_deinit(struct snd_soc_component *component) { struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; - if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__)) + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; - rx_priv->codec = NULL; + rx_priv->component = NULL; return 0; } diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 2051e5f4e868..96182d3c86c8 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -130,7 +130,7 @@ struct tx_macro_priv { struct clk *tx_npl_clk; struct mutex mclk_lock; struct mutex swr_clk_lock; - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct device_node *tx_swr_gpio_p; struct tx_macro_swr_ctrl_data *swr_ctrl_data; struct tx_macro_swr_ctrl_platform_data swr_plat_data; @@ -150,28 +150,28 @@ struct tx_macro_priv { int child_count; }; -static bool tx_macro_get_data(struct snd_soc_codec *codec, +static bool tx_macro_get_data(struct snd_soc_component *component, struct device **tx_dev, struct tx_macro_priv **tx_priv, const char *func_name) { - *tx_dev = bolero_get_device_ptr(codec->dev, TX_MACRO); + *tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO); if (!(*tx_dev)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: null device for macro!\n", func_name); return false; } *tx_priv = dev_get_drvdata((*tx_dev)); if (!(*tx_priv)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: priv is null for macro!\n", func_name); return false; } - if (!(*tx_priv)->codec) { - dev_err(codec->dev, - "%s: tx_priv->codec not initialized!\n", func_name); + if (!(*tx_priv)->component) { + dev_err(component->dev, + "%s: tx_priv->component not initialized!\n", func_name); return false; } @@ -245,12 +245,13 @@ static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv, static int tx_macro_mclk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); int ret = 0; struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; - if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; dev_dbg(tx_dev, "%s: event = %d\n", __func__, event); @@ -296,13 +297,13 @@ static int tx_macro_mclk_ctrl(struct device *dev, bool enable) return ret; } -static int tx_macro_event_handler(struct snd_soc_codec *codec, u16 event, - u32 data) +static int tx_macro_event_handler(struct snd_soc_component *component, + u16 event, u32 data) { struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; - if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; switch (event) { @@ -323,7 +324,7 @@ static int tx_macro_event_handler(struct snd_soc_codec *codec, u16 event, return 0; } -static int tx_macro_reg_wake_irq(struct snd_soc_codec *codec, +static int tx_macro_reg_wake_irq(struct snd_soc_component *component, u32 data) { struct device *tx_dev = NULL; @@ -331,7 +332,7 @@ static int tx_macro_reg_wake_irq(struct snd_soc_codec *codec, u32 ipc_wakeup = data; int ret = 0; - if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; ret = swrm_wcd_notify( @@ -346,7 +347,7 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) struct delayed_work *hpf_delayed_work = NULL; struct hpf_work *hpf_work = NULL; struct tx_macro_priv *tx_priv = NULL; - struct snd_soc_codec *codec = NULL; + struct snd_soc_component *component = NULL; u16 dec_cfg_reg = 0, hpf_gate_reg = 0; u8 hpf_cut_off_freq = 0; u16 adc_mux_reg = 0, adc_n = 0, adc_reg = 0; @@ -354,7 +355,7 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) hpf_delayed_work = to_delayed_work(work); hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); tx_priv = hpf_work->tx_priv; - codec = tx_priv->codec; + component = tx_priv->component; hpf_cut_off_freq = hpf_work->hpf_cut_off_freq; dec_cfg_reg = BOLERO_CDC_TX0_TX_PATH_CFG0 + @@ -362,34 +363,35 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) hpf_gate_reg = BOLERO_CDC_TX0_TX_PATH_SEC2 + TX_MACRO_TX_PATH_OFFSET * hpf_work->decimator; - dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", + dev_dbg(component->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", __func__, hpf_work->decimator, hpf_cut_off_freq); adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator; - if (snd_soc_read(codec, adc_mux_reg) & SWR_MIC) { + if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) { adc_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator; - adc_n = snd_soc_read(codec, adc_reg) & + adc_n = snd_soc_component_read32(component, adc_reg) & TX_MACRO_SWR_MIC_MUX_SEL_MASK; if (adc_n >= BOLERO_ADC_MAX) goto tx_hpf_set; /* analog mic clear TX hold */ - bolero_clear_amic_tx_hold(codec->dev, adc_n); + bolero_clear_amic_tx_hold(component->dev, adc_n); } tx_hpf_set: - snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, - hpf_cut_off_freq << 5); - snd_soc_update_bits(codec, hpf_gate_reg, 0x03, 0x02); + snd_soc_component_update_bits(component, + dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x02); /* Minimum 1 clk cycle delay is required as per HW spec */ usleep_range(1000, 1010); - snd_soc_update_bits(codec, hpf_gate_reg, 0x03, 0x01); + snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x01); } static void tx_macro_mute_update_callback(struct work_struct *work) { struct tx_mute_work *tx_mute_dwork = NULL; - struct snd_soc_codec *codec = NULL; + struct snd_soc_component *component = NULL; struct tx_macro_priv *tx_priv = NULL; struct delayed_work *delayed_work = NULL; u16 tx_vol_ctl_reg = 0; @@ -398,13 +400,13 @@ static void tx_macro_mute_update_callback(struct work_struct *work) delayed_work = to_delayed_work(work); tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); tx_priv = tx_mute_dwork->tx_priv; - codec = tx_priv->codec; + component = tx_priv->component; decimator = tx_mute_dwork->decimator; tx_vol_ctl_reg = BOLERO_CDC_TX0_TX_PATH_CTL + TX_MACRO_TX_PATH_OFFSET * decimator; - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x00); dev_dbg(tx_priv->dev, "%s: decimator %u unmute\n", __func__, decimator); } @@ -414,7 +416,8 @@ static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val = 0; u16 mic_sel_reg = 0; @@ -423,7 +426,7 @@ static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol, if (val > e->items - 1) return -EINVAL; - dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__, widget->name, val); switch (e->reg) { @@ -452,23 +455,26 @@ static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol, mic_sel_reg = BOLERO_CDC_TX7_TX_PATH_CFG0; break; default: - dev_err(codec->dev, "%s: e->reg: 0x%x not expected\n", + dev_err(component->dev, "%s: e->reg: 0x%x not expected\n", __func__, e->reg); return -EINVAL; } if (strnstr(widget->name, "SMIC", strlen(widget->name))) { if (val != 0) { if (val < 5) - snd_soc_update_bits(codec, mic_sel_reg, + snd_soc_component_update_bits(component, + mic_sel_reg, 1 << 7, 0x0 << 7); else - snd_soc_update_bits(codec, mic_sel_reg, + snd_soc_component_update_bits(component, + mic_sel_reg, 1 << 7, 0x1 << 7); } } else { /* DMIC selected */ if (val != 0) - snd_soc_update_bits(codec, mic_sel_reg, 1 << 7, 1 << 7); + snd_soc_component_update_bits(component, mic_sel_reg, + 1 << 7, 1 << 7); } return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); @@ -479,7 +485,8 @@ static int tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct soc_multi_mixer_control *mixer = ((struct soc_multi_mixer_control *)kcontrol->private_value); u32 dai_id = widget->shift; @@ -487,7 +494,7 @@ static int tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol, struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; - if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; if (test_bit(dec_id, &tx_priv->active_ch_mask[dai_id])) @@ -502,7 +509,8 @@ static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct snd_soc_dapm_update *update = NULL; struct soc_multi_mixer_control *mixer = ((struct soc_multi_mixer_control *)kcontrol->private_value); @@ -512,7 +520,7 @@ static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; - if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; if (enable) { @@ -530,7 +538,8 @@ static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); u8 dmic_clk_en = 0x01; u16 dmic_clk_reg = 0; s32 *dmic_clk_cnt = NULL; @@ -540,18 +549,18 @@ static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w, struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; - if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; wname = strpbrk(w->name, "01234567"); if (!wname) { - dev_err(codec->dev, "%s: widget not found\n", __func__); + dev_err(component->dev, "%s: widget not found\n", __func__); return -EINVAL; } ret = kstrtouint(wname, 10, &dmic); if (ret < 0) { - dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n", + dev_err(component->dev, "%s: Invalid DMIC line on the codec\n", __func__); return -EINVAL; } @@ -578,30 +587,31 @@ static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w, dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL; break; default: - dev_err(codec->dev, "%s: Invalid DMIC Selection\n", + dev_err(component->dev, "%s: Invalid DMIC Selection\n", __func__); return -EINVAL; } - dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", + dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", __func__, event, dmic, *dmic_clk_cnt); switch (event) { case SND_SOC_DAPM_PRE_PMU: (*dmic_clk_cnt)++; if (*dmic_clk_cnt == 1) { - snd_soc_update_bits(codec, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, + snd_soc_component_update_bits(component, + BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, 0x80, 0x00); - snd_soc_update_bits(codec, dmic_clk_reg, + snd_soc_component_update_bits(component, dmic_clk_reg, 0x0E, tx_priv->dmic_clk_div << 0x1); - snd_soc_update_bits(codec, dmic_clk_reg, + snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, dmic_clk_en); } break; case SND_SOC_DAPM_POST_PMD: (*dmic_clk_cnt)--; if (*dmic_clk_cnt == 0) - snd_soc_update_bits(codec, dmic_clk_reg, + snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, 0); break; } @@ -612,7 +622,8 @@ static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w, static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); unsigned int decimator = 0; u16 tx_vol_ctl_reg = 0; u16 dec_cfg_reg = 0; @@ -622,12 +633,12 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; - if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; decimator = w->shift; - dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__, + dev_dbg(component->dev, "%s(): widget = %s decimator = %u\n", __func__, w->name, decimator); tx_vol_ctl_reg = BOLERO_CDC_TX0_TX_PATH_CTL + @@ -642,21 +653,27 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: /* Enable TX PGA Mute */ - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + snd_soc_component_update_bits(component, + tx_vol_ctl_reg, 0x10, 0x10); break; case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x20, 0x20); - snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00); + snd_soc_component_update_bits(component, + tx_vol_ctl_reg, 0x20, 0x20); + snd_soc_component_update_bits(component, + hpf_gate_reg, 0x01, 0x00); + + hpf_cut_off_freq = ( + snd_soc_component_read32(component, dec_cfg_reg) & + TX_HPF_CUT_OFF_FREQ_MASK) >> 5; - hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) & - TX_HPF_CUT_OFF_FREQ_MASK) >> 5; tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq = - hpf_cut_off_freq; + hpf_cut_off_freq; if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) - snd_soc_update_bits(codec, dec_cfg_reg, - TX_HPF_CUT_OFF_FREQ_MASK, - CF_MIN_3DB_150HZ << 5); + snd_soc_component_update_bits(component, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + CF_MIN_3DB_150HZ << 5); + /* schedule work queue to Remove Mute */ schedule_delayed_work(&tx_priv->tx_mute_dwork[decimator].dwork, msecs_to_jiffies(tx_unmute_delay)); @@ -665,35 +682,42 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, schedule_delayed_work( &tx_priv->tx_hpf_work[decimator].dwork, msecs_to_jiffies(300)); - snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); + snd_soc_component_update_bits(component, + hpf_gate_reg, 0x02, 0x02); /* * Minimum 1 clk cycle delay is required as per HW spec */ usleep_range(1000, 1010); - snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00); + snd_soc_component_update_bits(component, + hpf_gate_reg, 0x02, 0x00); } /* apply gain after decimator is enabled */ - snd_soc_write(codec, tx_gain_ctl_reg, - snd_soc_read(codec, tx_gain_ctl_reg)); + snd_soc_component_write(component, tx_gain_ctl_reg, + snd_soc_component_read32(component, + tx_gain_ctl_reg)); break; case SND_SOC_DAPM_PRE_PMD: hpf_cut_off_freq = tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq; - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + snd_soc_component_update_bits(component, + tx_vol_ctl_reg, 0x10, 0x10); if (cancel_delayed_work_sync( &tx_priv->tx_hpf_work[decimator].dwork)) { if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { - snd_soc_update_bits(codec, dec_cfg_reg, - TX_HPF_CUT_OFF_FREQ_MASK, - hpf_cut_off_freq << 5); - snd_soc_update_bits(codec, hpf_gate_reg, + snd_soc_component_update_bits( + component, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_component_update_bits(component, + hpf_gate_reg, 0x02, 0x02); /* * Minimum 1 clk cycle delay is required * as per HW spec */ usleep_range(1000, 1010); - snd_soc_update_bits(codec, hpf_gate_reg, + snd_soc_component_update_bits(component, + hpf_gate_reg, 0x02, 0x00); } } @@ -701,8 +725,10 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, &tx_priv->tx_mute_dwork[decimator].dwork); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x20, 0x00); - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x20, 0x00); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x10, 0x00); break; } return 0; @@ -719,14 +745,14 @@ static int tx_macro_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { int tx_fs_rate = -EINVAL; - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; u32 decimator = 0; u32 sample_rate = 0; u16 tx_fs_reg = 0; struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; - if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__, @@ -757,7 +783,7 @@ static int tx_macro_hw_params(struct snd_pcm_substream *substream, tx_fs_rate = 7; break; default: - dev_err(codec->dev, "%s: Invalid TX sample rate: %d\n", + dev_err(component->dev, "%s: Invalid TX sample rate: %d\n", __func__, params_rate(params)); return -EINVAL; } @@ -766,12 +792,12 @@ static int tx_macro_hw_params(struct snd_pcm_substream *substream, if (decimator >= 0) { tx_fs_reg = BOLERO_CDC_TX0_TX_PATH_CTL + TX_MACRO_TX_PATH_OFFSET * decimator; - dev_dbg(codec->dev, "%s: set DEC%u rate to %u\n", + dev_dbg(component->dev, "%s: set DEC%u rate to %u\n", __func__, decimator, sample_rate); - snd_soc_update_bits(codec, tx_fs_reg, 0x0F, - tx_fs_rate); + snd_soc_component_update_bits(component, tx_fs_reg, + 0x0F, tx_fs_rate); } else { - dev_err(codec->dev, + dev_err(component->dev, "%s: ERROR: Invalid decimator: %d\n", __func__, decimator); return -EINVAL; @@ -784,11 +810,11 @@ static int tx_macro_get_channel_map(struct snd_soc_dai *dai, unsigned int *tx_num, unsigned int *tx_slot, unsigned int *rx_num, unsigned int *rx_slot) { - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; - if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; switch (dai->id) { @@ -1483,22 +1509,23 @@ static int tx_macro_validate_dmic_sample_rate(u32 dmic_sample_rate, return dmic_sample_rate; } -static int tx_macro_init(struct snd_soc_codec *codec) +static int tx_macro_init(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); int ret = 0, i = 0; struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; - tx_dev = bolero_get_device_ptr(codec->dev, TX_MACRO); + tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO); if (!tx_dev) { - dev_err(codec->dev, + dev_err(component->dev, "%s: null device for macro!\n", __func__); return -EINVAL; } tx_priv = dev_get_drvdata(tx_dev); if (!tx_priv) { - dev_err(codec->dev, + dev_err(component->dev, "%s: priv is null for macro!\n", __func__); return -EINVAL; } @@ -1522,7 +1549,7 @@ static int tx_macro_init(struct snd_soc_codec *codec) return ret; } - ret = snd_soc_add_codec_controls(codec, tx_macro_snd_controls, + ret = snd_soc_add_component_controls(component, tx_macro_snd_controls, ARRAY_SIZE(tx_macro_snd_controls)); if (ret < 0) { dev_err(tx_dev, "%s: Failed to add snd_ctls\n", __func__); @@ -1558,20 +1585,20 @@ static int tx_macro_init(struct snd_soc_codec *codec) INIT_DELAYED_WORK(&tx_priv->tx_mute_dwork[i].dwork, tx_macro_mute_update_callback); } - tx_priv->codec = codec; + tx_priv->component = component; return 0; } -static int tx_macro_deinit(struct snd_soc_codec *codec) +static int tx_macro_deinit(struct snd_soc_component *component) { struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; - if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; - tx_priv->codec = NULL; + tx_priv->component = NULL; return 0; } diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index ed052ae58a73..985424a5b6ba 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -95,7 +95,7 @@ struct va_macro_priv { bool va_without_decimation; struct clk *va_core_clk; struct mutex mclk_lock; - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct hpf_work va_hpf_work[VA_MACRO_NUM_DECIMATORS]; struct va_mute_work va_mute_dwork[VA_MACRO_NUM_DECIMATORS]; unsigned long active_ch_mask[VA_MACRO_MAX_DAIS]; @@ -113,20 +113,20 @@ struct va_macro_priv { int micb_users; }; -static bool va_macro_get_data(struct snd_soc_codec *codec, +static bool va_macro_get_data(struct snd_soc_component *component, struct device **va_dev, struct va_macro_priv **va_priv, const char *func_name) { - *va_dev = bolero_get_device_ptr(codec->dev, VA_MACRO); + *va_dev = bolero_get_device_ptr(component->dev, VA_MACRO); if (!(*va_dev)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: null device for macro!\n", func_name); return false; } *va_priv = dev_get_drvdata((*va_dev)); - if (!(*va_priv) || !(*va_priv)->codec) { - dev_err(codec->dev, + if (!(*va_priv) || !(*va_priv)->component) { + dev_err(component->dev, "%s: priv is null for macro!\n", func_name); return false; } @@ -200,14 +200,14 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, return ret; } -static int va_macro_event_handler(struct snd_soc_codec *codec, u16 event, - u32 data) +static int va_macro_event_handler(struct snd_soc_component *component, + u16 event, u32 data) { struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; int retry_cnt = MAX_RETRY_ATTEMPTS; - if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; switch (event) { @@ -237,12 +237,13 @@ static int va_macro_event_handler(struct snd_soc_codec *codec, u16 event, static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); int ret = 0; struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; - if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; dev_dbg(va_dev, "%s: event = %d\n", __func__, event); @@ -285,14 +286,14 @@ static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) struct delayed_work *hpf_delayed_work; struct hpf_work *hpf_work; struct va_macro_priv *va_priv; - struct snd_soc_codec *codec; + struct snd_soc_component *component; u16 dec_cfg_reg, hpf_gate_reg; u8 hpf_cut_off_freq; hpf_delayed_work = to_delayed_work(work); hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); va_priv = hpf_work->va_priv; - codec = va_priv->codec; + component = va_priv->component; hpf_cut_off_freq = hpf_work->hpf_cut_off_freq; dec_cfg_reg = BOLERO_CDC_VA_TX0_TX_PATH_CFG0 + @@ -303,18 +304,19 @@ static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) dev_dbg(va_priv->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", __func__, hpf_work->decimator, hpf_cut_off_freq); - snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, - hpf_cut_off_freq << 5); - snd_soc_update_bits(codec, hpf_gate_reg, 0x03, 0x02); + snd_soc_component_update_bits(component, + dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x02); /* Minimum 1 clk cycle delay is required as per HW spec */ usleep_range(1000, 1010); - snd_soc_update_bits(codec, hpf_gate_reg, 0x03, 0x01); + snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x01); } static void va_macro_mute_update_callback(struct work_struct *work) { struct va_mute_work *va_mute_dwork; - struct snd_soc_codec *codec = NULL; + struct snd_soc_component *component = NULL; struct va_macro_priv *va_priv; struct delayed_work *delayed_work; u16 tx_vol_ctl_reg, decimator; @@ -322,13 +324,13 @@ static void va_macro_mute_update_callback(struct work_struct *work) delayed_work = to_delayed_work(work); va_mute_dwork = container_of(delayed_work, struct va_mute_work, dwork); va_priv = va_mute_dwork->va_priv; - codec = va_priv->codec; + component = va_priv->component; decimator = va_mute_dwork->decimator; tx_vol_ctl_reg = BOLERO_CDC_VA_TX0_TX_PATH_CTL + VA_MACRO_TX_PATH_OFFSET * decimator; - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x00); dev_dbg(va_priv->dev, "%s: decimator %u unmute\n", __func__, decimator); } @@ -338,7 +340,8 @@ static int va_macro_put_dec_enum(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val; u16 mic_sel_reg; @@ -347,7 +350,7 @@ static int va_macro_put_dec_enum(struct snd_kcontrol *kcontrol, if (val > e->items - 1) return -EINVAL; - dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__, widget->name, val); switch (e->reg) { @@ -376,13 +379,14 @@ static int va_macro_put_dec_enum(struct snd_kcontrol *kcontrol, mic_sel_reg = BOLERO_CDC_VA_TX7_TX_PATH_CFG0; break; default: - dev_err(codec->dev, "%s: e->reg: 0x%x not expected\n", + dev_err(component->dev, "%s: e->reg: 0x%x not expected\n", __func__, e->reg); return -EINVAL; } /* DMIC selected */ if (val != 0) - snd_soc_update_bits(codec, mic_sel_reg, 1 << 7, 1 << 7); + snd_soc_component_update_bits(component, mic_sel_reg, + 1 << 7, 1 << 7); return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); } @@ -392,7 +396,8 @@ static int va_macro_tx_mixer_get(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct soc_multi_mixer_control *mixer = ((struct soc_multi_mixer_control *)kcontrol->private_value); u32 dai_id = widget->shift; @@ -400,7 +405,7 @@ static int va_macro_tx_mixer_get(struct snd_kcontrol *kcontrol, struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; - if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; if (test_bit(dec_id, &va_priv->active_ch_mask[dai_id])) @@ -415,7 +420,8 @@ static int va_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct snd_soc_dapm_update *update = NULL; struct soc_multi_mixer_control *mixer = ((struct soc_multi_mixer_control *)kcontrol->private_value); @@ -425,7 +431,7 @@ static int va_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; - if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; if (enable) { @@ -444,7 +450,8 @@ static int va_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); u8 dmic_clk_en = 0x01; u16 dmic_clk_reg; s32 *dmic_clk_cnt; @@ -454,7 +461,7 @@ static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w, struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; - if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; wname = strpbrk(w->name, "01234567"); @@ -503,21 +510,21 @@ static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMU: (*dmic_clk_cnt)++; if (*dmic_clk_cnt == 1) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, 0x80, 0x00); - snd_soc_update_bits(codec, dmic_clk_reg, + snd_soc_component_update_bits(component, dmic_clk_reg, VA_MACRO_TX_DMIC_CLK_DIV_MASK, va_priv->dmic_clk_div << VA_MACRO_TX_DMIC_CLK_DIV_SHFT); - snd_soc_update_bits(codec, dmic_clk_reg, + snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, dmic_clk_en); } break; case SND_SOC_DAPM_POST_PMD: (*dmic_clk_cnt)--; if (*dmic_clk_cnt == 0) { - snd_soc_update_bits(codec, dmic_clk_reg, + snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, 0); } break; @@ -529,7 +536,8 @@ static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w, static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); unsigned int decimator; u16 tx_vol_ctl_reg, dec_cfg_reg, hpf_gate_reg; u16 tx_gain_ctl_reg; @@ -537,7 +545,7 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; - if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; decimator = w->shift; @@ -557,28 +565,34 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: /* Enable TX PGA Mute */ - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + snd_soc_component_update_bits(component, + tx_vol_ctl_reg, 0x10, 0x10); break; case SND_SOC_DAPM_POST_PMU: /* Enable TX CLK */ - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x20, 0x20); - snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00); + snd_soc_component_update_bits(component, + tx_vol_ctl_reg, 0x20, 0x20); + snd_soc_component_update_bits(component, + hpf_gate_reg, 0x01, 0x00); - hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) & + hpf_cut_off_freq = (snd_soc_component_read32( + component, dec_cfg_reg) & TX_HPF_CUT_OFF_FREQ_MASK) >> 5; va_priv->va_hpf_work[decimator].hpf_cut_off_freq = hpf_cut_off_freq; if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { - snd_soc_update_bits(codec, dec_cfg_reg, + snd_soc_component_update_bits(component, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, CF_MIN_3DB_150HZ << 5); - snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); + snd_soc_component_update_bits(component, + hpf_gate_reg, 0x02, 0x02); /* * Minimum 1 clk cycle delay is required as per HW spec */ usleep_range(1000, 1010); - snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00); + snd_soc_component_update_bits(component, + hpf_gate_reg, 0x02, 0x00); } /* schedule work queue to Remove Mute */ schedule_delayed_work(&va_priv->va_mute_dwork[decimator].dwork, @@ -589,28 +603,32 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, &va_priv->va_hpf_work[decimator].dwork, msecs_to_jiffies(300)); /* apply gain after decimator is enabled */ - snd_soc_write(codec, tx_gain_ctl_reg, - snd_soc_read(codec, tx_gain_ctl_reg)); + snd_soc_component_write(component, tx_gain_ctl_reg, + snd_soc_component_read32(component, tx_gain_ctl_reg)); break; case SND_SOC_DAPM_PRE_PMD: hpf_cut_off_freq = va_priv->va_hpf_work[decimator].hpf_cut_off_freq; - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x10, 0x10); if (cancel_delayed_work_sync( &va_priv->va_hpf_work[decimator].dwork)) { if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { - snd_soc_update_bits(codec, dec_cfg_reg, - TX_HPF_CUT_OFF_FREQ_MASK, - hpf_cut_off_freq << 5); - snd_soc_update_bits(codec, hpf_gate_reg, - 0x02, 0x02); + snd_soc_component_update_bits(component, + dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_component_update_bits(component, + hpf_gate_reg, + 0x02, 0x02); /* * Minimum 1 clk cycle delay is required * as per HW spec */ usleep_range(1000, 1010); - snd_soc_update_bits(codec, hpf_gate_reg, - 0x02, 0x00); + snd_soc_component_update_bits(component, + hpf_gate_reg, + 0x02, 0x00); } } cancel_delayed_work_sync( @@ -618,8 +636,10 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: /* Disable TX CLK */ - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x20, 0x00); - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x20, 0x00); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x10, 0x00); break; } return 0; @@ -628,12 +648,13 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, static int va_macro_enable_micbias(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; int ret = 0; - if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; if (!va_priv->micb_supply) { @@ -695,13 +716,13 @@ static int va_macro_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { int tx_fs_rate = -EINVAL; - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; u32 decimator, sample_rate; u16 tx_fs_reg = 0; struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; - if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; dev_dbg(va_dev, @@ -744,8 +765,8 @@ static int va_macro_hw_params(struct snd_pcm_substream *substream, VA_MACRO_TX_PATH_OFFSET * decimator; dev_dbg(va_dev, "%s: set DEC%u rate to %u\n", __func__, decimator, sample_rate); - snd_soc_update_bits(codec, tx_fs_reg, 0x0F, - tx_fs_rate); + snd_soc_component_update_bits(component, tx_fs_reg, + 0x0F, tx_fs_rate); } else { dev_err(va_dev, "%s: ERROR: Invalid decimator: %d\n", @@ -760,11 +781,11 @@ static int va_macro_get_channel_map(struct snd_soc_dai *dai, unsigned int *tx_num, unsigned int *tx_slot, unsigned int *rx_num, unsigned int *rx_slot) { - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; - if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; switch (dai->id) { @@ -1393,22 +1414,23 @@ static int va_macro_validate_dmic_sample_rate(u32 dmic_sample_rate, return dmic_sample_rate; } -static int va_macro_init(struct snd_soc_codec *codec) +static int va_macro_init(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); int ret, i; struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; - va_dev = bolero_get_device_ptr(codec->dev, VA_MACRO); + va_dev = bolero_get_device_ptr(component->dev, VA_MACRO); if (!va_dev) { - dev_err(codec->dev, + dev_err(component->dev, "%s: null device for macro!\n", __func__); return -EINVAL; } va_priv = dev_get_drvdata(va_dev); if (!va_priv) { - dev_err(codec->dev, + dev_err(component->dev, "%s: priv is null for macro!\n", __func__); return -EINVAL; } @@ -1422,7 +1444,7 @@ static int va_macro_init(struct snd_soc_codec *codec) __func__); return ret; } - va_priv->codec = codec; + va_priv->component = component; return 0; } @@ -1445,7 +1467,7 @@ static int va_macro_init(struct snd_soc_codec *codec) dev_err(va_dev, "%s: Failed to add widgets\n", __func__); return ret; } - ret = snd_soc_add_codec_controls(codec, va_macro_snd_controls, + ret = snd_soc_add_component_controls(component, va_macro_snd_controls, ARRAY_SIZE(va_macro_snd_controls)); if (ret < 0) { dev_err(va_dev, "%s: Failed to add snd_ctls\n", __func__); @@ -1481,20 +1503,20 @@ static int va_macro_init(struct snd_soc_codec *codec) INIT_DELAYED_WORK(&va_priv->va_mute_dwork[i].dwork, va_macro_mute_update_callback); } - va_priv->codec = codec; + va_priv->component = component; return 0; } -static int va_macro_deinit(struct snd_soc_codec *codec) +static int va_macro_deinit(struct snd_soc_component *component) { struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; - if (!va_macro_get_data(codec, &va_dev, &va_priv, __func__)) + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; - va_priv->codec = NULL; + va_priv->component = NULL; return 0; } diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 823954e410df..9586770f77cc 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -173,7 +173,7 @@ enum { * @wsa_swr_gpio_p: used by pinctrl API * @wsa_core_clk: MCLK for wsa macro * @wsa_npl_clk: NPL clock for WSA soundwire - * @codec: codec handle + * @component: codec handle * @rx_0_count: RX0 interpolation users * @rx_1_count: RX1 interpolation users * @active_ch_mask: channel mask for all AIF DAIs @@ -197,7 +197,7 @@ struct wsa_macro_priv { struct device_node *wsa_swr_gpio_p; struct clk *wsa_core_clk; struct clk *wsa_npl_clk; - struct snd_soc_codec *codec; + struct snd_soc_component *component; int rx_0_count; int rx_1_count; unsigned long active_ch_mask[WSA_MACRO_MAX_DAIS]; @@ -215,7 +215,7 @@ struct wsa_macro_priv { struct wsa_macro_bcl_pmic_params bcl_pmic_params; }; -static int wsa_macro_config_ear_spkr_gain(struct snd_soc_codec *codec, +static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component, struct wsa_macro_priv *wsa_priv, int event, int gain_reg); static struct snd_soc_dai_driver wsa_macro_dai[]; @@ -429,20 +429,20 @@ static const struct wsa_macro_reg_mask_val wsa_macro_spkr_mode1[] = { {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x44}, }; -static bool wsa_macro_get_data(struct snd_soc_codec *codec, +static bool wsa_macro_get_data(struct snd_soc_component *component, struct device **wsa_dev, struct wsa_macro_priv **wsa_priv, const char *func_name) { - *wsa_dev = bolero_get_device_ptr(codec->dev, WSA_MACRO); + *wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO); if (!(*wsa_dev)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: null device for macro!\n", func_name); return false; } *wsa_priv = dev_get_drvdata((*wsa_dev)); - if (!(*wsa_priv) || !(*wsa_priv)->codec) { - dev_err(codec->dev, + if (!(*wsa_priv) || !(*wsa_priv)->component) { + dev_err(component->dev, "%s: priv is null for macro!\n", func_name); return false; } @@ -453,22 +453,23 @@ static bool wsa_macro_get_data(struct snd_soc_codec *codec, * wsa_macro_set_spkr_gain_offset - offset the speaker path * gain with the given offset value. * - * @codec: codec instance + * @component: codec instance * @offset: Indicates speaker path gain offset value. * * Returns 0 on success or -EINVAL on error. */ -int wsa_macro_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset) +int wsa_macro_set_spkr_gain_offset(struct snd_soc_component *component, + int offset) { struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!codec) { - pr_err("%s: NULL codec pointer!\n", __func__); + if (!component) { + pr_err("%s: NULL component pointer!\n", __func__); return -EINVAL; } - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; wsa_priv->spkr_gain_offset = offset; @@ -480,12 +481,12 @@ EXPORT_SYMBOL(wsa_macro_set_spkr_gain_offset); * wsa_macro_set_spkr_mode - Configures speaker compander and smartboost * settings based on speaker mode. * - * @codec: codec instance + * @component: codec instance * @mode: Indicates speaker configuration mode. * * Returns 0 on success or -EINVAL on error. */ -int wsa_macro_set_spkr_mode(struct snd_soc_codec *codec, int mode) +int wsa_macro_set_spkr_mode(struct snd_soc_component *component, int mode) { int i; const struct wsa_macro_reg_mask_val *regs; @@ -493,12 +494,12 @@ int wsa_macro_set_spkr_mode(struct snd_soc_codec *codec, int mode) struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!codec) { + if (!component) { pr_err("%s: NULL codec pointer!\n", __func__); return -EINVAL; } - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; switch (mode) { @@ -514,7 +515,7 @@ int wsa_macro_set_spkr_mode(struct snd_soc_codec *codec, int mode) wsa_priv->spkr_mode = mode; for (i = 0; i < size; i++) - snd_soc_update_bits(codec, regs[i].reg, + snd_soc_component_update_bits(component, regs[i].reg, regs[i].mask, regs[i].val); return 0; } @@ -530,11 +531,11 @@ static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, u16 int_fs_reg; u8 int_mux_cfg0_val, int_mux_cfg1_val; u8 inp0_sel, inp1_sel, inp2_sel; - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id], @@ -558,8 +559,10 @@ static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, for (j = 0; j < NUM_INTERPOLATORS; j++) { int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET; - int_mux_cfg0_val = snd_soc_read(codec, int_mux_cfg0); - int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1); + int_mux_cfg0_val = snd_soc_component_read32(component, + int_mux_cfg0); + int_mux_cfg1_val = snd_soc_component_read32(component, + int_mux_cfg1); inp0_sel = int_mux_cfg0_val & WSA_MACRO_MUX_INP_MASK1; inp1_sel = (int_mux_cfg0_val >> WSA_MACRO_MUX_INP_SHFT) & @@ -579,7 +582,8 @@ static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, "%s: set INT%u_1 sample rate to %u\n", __func__, j, sample_rate); /* sample_rate is in Hz */ - snd_soc_update_bits(codec, int_fs_reg, + snd_soc_component_update_bits(component, + int_fs_reg, WSA_MACRO_FS_RATE_MASK, int_prim_fs_rate_reg_val); } @@ -598,11 +602,11 @@ static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, u32 j, port; u16 int_mux_cfg1, int_fs_reg; u8 int_mux_cfg1_val; - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; @@ -619,7 +623,8 @@ static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, int_mux_cfg1 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1; for (j = 0; j < NUM_INTERPOLATORS; j++) { - int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1) & + int_mux_cfg1_val = snd_soc_component_read32(component, + int_mux_cfg1) & WSA_MACRO_MUX_INP_MASK1; if (int_mux_cfg1_val == int_2_inp) { int_fs_reg = @@ -632,7 +637,8 @@ static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, dev_dbg(wsa_dev, "%s: set INT%u_2 sample rate to %u\n", __func__, j, sample_rate); - snd_soc_update_bits(codec, int_fs_reg, + snd_soc_component_update_bits(component, + int_fs_reg, WSA_MACRO_FS_RATE_MASK, int_mix_fs_rate_reg_val); } @@ -684,10 +690,10 @@ static int wsa_macro_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; int ret; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__, dai->name, dai->id, params_rate(params), params_channels(params)); @@ -696,7 +702,7 @@ static int wsa_macro_hw_params(struct snd_pcm_substream *substream, case SNDRV_PCM_STREAM_PLAYBACK: ret = wsa_macro_set_interpolator_rate(dai, params_rate(params)); if (ret) { - dev_err(codec->dev, + dev_err(component->dev, "%s: cannot set sample rate: %u\n", __func__, params_rate(params)); return ret; @@ -713,11 +719,11 @@ static int wsa_macro_get_channel_map(struct snd_soc_dai *dai, unsigned int *tx_num, unsigned int *tx_slot, unsigned int *rx_num, unsigned int *rx_slot) { - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; wsa_priv = dev_get_drvdata(wsa_dev); @@ -809,12 +815,13 @@ static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv, static int wsa_macro_mclk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); int ret = 0; struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; dev_dbg(wsa_dev, "%s: event = %d\n", __func__, event); @@ -862,13 +869,13 @@ static int wsa_macro_mclk_ctrl(struct device *dev, bool enable) return ret; } -static int wsa_macro_event_handler(struct snd_soc_codec *codec, u16 event, - u32 data) +static int wsa_macro_event_handler(struct snd_soc_component *component, + u16 event, u32 data) { struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; switch (event) { @@ -893,11 +900,12 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; switch (event) { @@ -906,28 +914,28 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w, &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) { dev_dbg(wsa_dev, "%s: spkr1 enabled\n", __func__); /* Enable V&I sensing */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, 0x0F, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL, 0x0F, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, 0x20, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL, 0x20, 0x00); } @@ -935,28 +943,28 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w, &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) { dev_dbg(wsa_dev, "%s: spkr2 enabled\n", __func__); /* Enable V&I sensing */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, 0x0F, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL, 0x0F, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, 0x20, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL, 0x20, 0x00); } @@ -965,17 +973,17 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w, if (test_bit(WSA_MACRO_TX0, &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) { /* Disable V&I sensing */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL, 0x20, 0x20); dev_dbg(wsa_dev, "%s: spkr1 disabled\n", __func__); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, 0x10, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL, 0x10, 0x00); } @@ -983,16 +991,16 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w, &wsa_priv->active_ch_mask[WSA_MACRO_AIF_VI])) { /* Disable V&I sensing */ dev_dbg(wsa_dev, "%s: spkr2 disabled\n", __func__); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, 0x10, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL, 0x10, 0x00); } @@ -1005,12 +1013,13 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w, static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); u16 gain_reg; int offset_val = 0; int val = 0; - dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name); switch (w->reg) { case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL: @@ -1020,16 +1029,16 @@ static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w, gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL; break; default: - dev_err(codec->dev, "%s: No gain register avail for %s\n", + dev_err(component->dev, "%s: No gain register avail for %s\n", __func__, w->name); return 0; } switch (event) { case SND_SOC_DAPM_POST_PMU: - val = snd_soc_read(codec, gain_reg); + val = snd_soc_component_read32(component, gain_reg); val += offset_val; - snd_soc_write(codec, gain_reg, val); + snd_soc_component_write(component, gain_reg, val); break; case SND_SOC_DAPM_POST_PMD: break; @@ -1038,7 +1047,7 @@ static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w, return 0; } -static void wsa_macro_hd2_control(struct snd_soc_codec *codec, +static void wsa_macro_hd2_control(struct snd_soc_component *component, u16 reg, int event) { u16 hd2_scale_reg; @@ -1054,27 +1063,34 @@ static void wsa_macro_hd2_control(struct snd_soc_codec *codec, } if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { - snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x10); - snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x01); - snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x04); + snd_soc_component_update_bits(component, hd2_scale_reg, + 0x3C, 0x10); + snd_soc_component_update_bits(component, hd2_scale_reg, + 0x03, 0x01); + snd_soc_component_update_bits(component, hd2_enable_reg, + 0x04, 0x04); } if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x00); - snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x00); - snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x00); + snd_soc_component_update_bits(component, hd2_enable_reg, + 0x04, 0x00); + snd_soc_component_update_bits(component, hd2_scale_reg, + 0x03, 0x00); + snd_soc_component_update_bits(component, hd2_scale_reg, + 0x3C, 0x00); } } static int wsa_macro_enable_swr(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); int ch_cnt; struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; switch (event) { @@ -1114,17 +1130,17 @@ static int wsa_macro_enable_swr(struct snd_soc_dapm_widget *w, return 0; } -static int wsa_macro_config_compander(struct snd_soc_codec *codec, +static int wsa_macro_config_compander(struct snd_soc_component *component, int comp, int event) { u16 comp_ctl0_reg, rx_path_cfg0_reg; struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; - dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n", + dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n", __func__, event, comp + 1, wsa_priv->comp_enabled[comp]); if (!wsa_priv->comp_enabled[comp]) @@ -1137,25 +1153,35 @@ static int wsa_macro_config_compander(struct snd_soc_codec *codec, if (SND_SOC_DAPM_EVENT_ON(event)) { /* Enable Compander Clock */ - snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x01, 0x01); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x02); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x00); + snd_soc_component_update_bits(component, rx_path_cfg0_reg, + 0x02, 0x02); } if (SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); - snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x04, 0x04); + snd_soc_component_update_bits(component, rx_path_cfg0_reg, + 0x02, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x02); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x01, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x04, 0x00); } return 0; } -static void wsa_macro_enable_softclip_clk(struct snd_soc_codec *codec, +static void wsa_macro_enable_softclip_clk(struct snd_soc_component *component, struct wsa_macro_priv *wsa_priv, int path, bool enable) @@ -1165,13 +1191,13 @@ static void wsa_macro_enable_softclip_clk(struct snd_soc_codec *codec, u8 softclip_mux_mask = (1 << path); u8 softclip_mux_value = (1 << path); - dev_dbg(codec->dev, "%s: path %d, enable %d\n", + dev_dbg(component->dev, "%s: path %d, enable %d\n", __func__, path, enable); if (enable) { if (wsa_priv->softclip_clk_users[path] == 0) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, softclip_clk_reg, 0x01, 0x01); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0, softclip_mux_mask, softclip_mux_value); } @@ -1179,16 +1205,16 @@ static void wsa_macro_enable_softclip_clk(struct snd_soc_codec *codec, } else { wsa_priv->softclip_clk_users[path]--; if (wsa_priv->softclip_clk_users[path] == 0) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, softclip_clk_reg, 0x01, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0, softclip_mux_mask, 0x00); } } } -static int wsa_macro_config_softclip(struct snd_soc_codec *codec, +static int wsa_macro_config_softclip(struct snd_soc_component *component, int path, int event) { u16 softclip_ctrl_reg = 0; @@ -1196,7 +1222,7 @@ static int wsa_macro_config_softclip(struct snd_soc_codec *codec, struct wsa_macro_priv *wsa_priv = NULL; int softclip_path = 0; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; if (path == WSA_MACRO_COMP1) @@ -1204,7 +1230,7 @@ static int wsa_macro_config_softclip(struct snd_soc_codec *codec, else if (path == WSA_MACRO_COMP2) softclip_path = WSA_MACRO_SOFTCLIP1; - dev_dbg(codec->dev, "%s: event %d path %d, enabled %d\n", + dev_dbg(component->dev, "%s: event %d path %d, enabled %d\n", __func__, event, softclip_path, wsa_priv->is_softclip_on[softclip_path]); @@ -1216,16 +1242,18 @@ static int wsa_macro_config_softclip(struct snd_soc_codec *codec, if (SND_SOC_DAPM_EVENT_ON(event)) { /* Enable Softclip clock and mux */ - wsa_macro_enable_softclip_clk(codec, wsa_priv, softclip_path, - true); + wsa_macro_enable_softclip_clk(component, wsa_priv, + softclip_path, true); /* Enable Softclip control */ - snd_soc_update_bits(codec, softclip_ctrl_reg, 0x01, 0x01); + snd_soc_component_update_bits(component, softclip_ctrl_reg, + 0x01, 0x01); } if (SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, softclip_ctrl_reg, 0x01, 0x00); - wsa_macro_enable_softclip_clk(codec, wsa_priv, softclip_path, - false); + snd_soc_component_update_bits(component, softclip_ctrl_reg, + 0x01, 0x00); + wsa_macro_enable_softclip_clk(component, wsa_priv, + softclip_path, false); } return 0; @@ -1252,7 +1280,7 @@ static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind) } static int wsa_macro_enable_prim_interpolator( - struct snd_soc_codec *codec, + struct snd_soc_component *component, u16 reg, int event) { u16 prim_int_reg; @@ -1260,7 +1288,7 @@ static int wsa_macro_enable_prim_interpolator( struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; prim_int_reg = wsa_macro_interp_get_primary_reg(reg, &ind); @@ -1269,37 +1297,39 @@ static int wsa_macro_enable_prim_interpolator( case SND_SOC_DAPM_PRE_PMU: wsa_priv->prim_int_users[ind]++; if (wsa_priv->prim_int_users[ind] == 1) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, prim_int_reg + WSA_MACRO_RX_PATH_CFG3_OFFSET, 0x03, 0x03); - snd_soc_update_bits(codec, prim_int_reg, + snd_soc_component_update_bits(component, prim_int_reg, 0x10, 0x10); - wsa_macro_hd2_control(codec, prim_int_reg, event); - snd_soc_update_bits(codec, + wsa_macro_hd2_control(component, prim_int_reg, event); + snd_soc_component_update_bits(component, prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET, 0x1, 0x1); - snd_soc_update_bits(codec, prim_int_reg, + snd_soc_component_update_bits(component, prim_int_reg, 1 << 0x5, 1 << 0x5); } if ((reg != prim_int_reg) && - ((snd_soc_read(codec, prim_int_reg)) & 0x10)) - snd_soc_update_bits(codec, reg, 0x10, 0x10); + ((snd_soc_component_read32( + component, prim_int_reg)) & 0x10)) + snd_soc_component_update_bits(component, reg, + 0x10, 0x10); break; case SND_SOC_DAPM_POST_PMD: wsa_priv->prim_int_users[ind]--; if (wsa_priv->prim_int_users[ind] == 0) { - snd_soc_update_bits(codec, prim_int_reg, + snd_soc_component_update_bits(component, prim_int_reg, 1 << 0x5, 0 << 0x5); - snd_soc_update_bits(codec, prim_int_reg, + snd_soc_component_update_bits(component, prim_int_reg, 0x40, 0x40); - snd_soc_update_bits(codec, prim_int_reg, + snd_soc_component_update_bits(component, prim_int_reg, 0x40, 0x00); - wsa_macro_hd2_control(codec, prim_int_reg, event); + wsa_macro_hd2_control(component, prim_int_reg, event); } break; } - dev_dbg(codec->dev, "%s: primary interpolator: INT%d, users: %d\n", + dev_dbg(component->dev, "%s: primary interpolator: INT%d, users: %d\n", __func__, ind, wsa_priv->prim_int_users[ind]); return 0; } @@ -1308,7 +1338,8 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); u16 gain_reg; u16 reg; int val; @@ -1316,10 +1347,10 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; - dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name); if (!(strcmp(w->name, "WSA_RX INT0 INTERP"))) { reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL; @@ -1328,7 +1359,7 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL; gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_CTL; } else { - dev_err(codec->dev, "%s: Interpolator reg not found\n", + dev_err(component->dev, "%s: Interpolator reg not found\n", __func__); return -EINVAL; } @@ -1336,11 +1367,11 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: /* Reset if needed */ - wsa_macro_enable_prim_interpolator(codec, reg, event); + wsa_macro_enable_prim_interpolator(component, reg, event); break; case SND_SOC_DAPM_POST_PMU: - wsa_macro_config_compander(codec, w->shift, event); - wsa_macro_config_softclip(codec, w->shift, event); + wsa_macro_config_compander(component, w->shift, event); + wsa_macro_config_softclip(component, w->shift, event); /* apply gain after int clk is enabled */ if ((wsa_priv->spkr_gain_offset == WSA_MACRO_GAIN_OFFSET_M1P5_DB) && @@ -1348,50 +1379,54 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, wsa_priv->comp_enabled[WSA_MACRO_COMP2]) && (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL || gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) { - snd_soc_update_bits(codec, BOLERO_CDC_WSA_RX0_RX_PATH_SEC1, - 0x01, 0x01); - snd_soc_update_bits(codec, - BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0, - 0x01, 0x01); - snd_soc_update_bits(codec, BOLERO_CDC_WSA_RX1_RX_PATH_SEC1, - 0x01, 0x01); - snd_soc_update_bits(codec, - BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0, - 0x01, 0x01); + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_RX0_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0, + 0x01, 0x01); + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_RX1_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0, + 0x01, 0x01); offset_val = -2; } - val = snd_soc_read(codec, gain_reg); + val = snd_soc_component_read32(component, gain_reg); val += offset_val; - snd_soc_write(codec, gain_reg, val); - wsa_macro_config_ear_spkr_gain(codec, wsa_priv, + snd_soc_component_write(component, gain_reg, val); + wsa_macro_config_ear_spkr_gain(component, wsa_priv, event, gain_reg); break; case SND_SOC_DAPM_POST_PMD: - wsa_macro_config_compander(codec, w->shift, event); - wsa_macro_config_softclip(codec, w->shift, event); - wsa_macro_enable_prim_interpolator(codec, reg, event); + wsa_macro_config_compander(component, w->shift, event); + wsa_macro_config_softclip(component, w->shift, event); + wsa_macro_enable_prim_interpolator(component, reg, event); if ((wsa_priv->spkr_gain_offset == WSA_MACRO_GAIN_OFFSET_M1P5_DB) && (wsa_priv->comp_enabled[WSA_MACRO_COMP1] || wsa_priv->comp_enabled[WSA_MACRO_COMP2]) && (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL || gain_reg == BOLERO_CDC_WSA_RX1_RX_VOL_CTL)) { - snd_soc_update_bits(codec, BOLERO_CDC_WSA_RX0_RX_PATH_SEC1, - 0x01, 0x00); - snd_soc_update_bits(codec, - BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0, - 0x01, 0x00); - snd_soc_update_bits(codec, BOLERO_CDC_WSA_RX1_RX_PATH_SEC1, - 0x01, 0x00); - snd_soc_update_bits(codec, - BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0, - 0x01, 0x00); + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_RX0_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0, + 0x01, 0x00); + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_RX1_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0, + 0x01, 0x00); offset_val = 2; - val = snd_soc_read(codec, gain_reg); + val = snd_soc_component_read32(component, gain_reg); val += offset_val; - snd_soc_write(codec, gain_reg, val); + snd_soc_component_write(component, gain_reg, val); } - wsa_macro_config_ear_spkr_gain(codec, wsa_priv, + wsa_macro_config_ear_spkr_gain(component, wsa_priv, event, gain_reg); break; } @@ -1399,7 +1434,7 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, return 0; } -static int wsa_macro_config_ear_spkr_gain(struct snd_soc_codec *codec, +static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component, struct wsa_macro_priv *wsa_priv, int event, int gain_reg) { @@ -1424,7 +1459,7 @@ static int wsa_macro_config_ear_spkr_gain(struct snd_soc_codec *codec, (wsa_priv->ear_spkr_gain != 0)) { /* For example, val is -8(-12+5-1) for 4dB of gain */ val = comp_gain_offset + wsa_priv->ear_spkr_gain - 1; - snd_soc_write(codec, gain_reg, val); + snd_soc_component_write(component, gain_reg, val); dev_dbg(wsa_priv->dev, "%s: RX0 Volume %d dB\n", __func__, val); @@ -1438,7 +1473,7 @@ static int wsa_macro_config_ear_spkr_gain(struct snd_soc_codec *codec, if (wsa_priv->comp_enabled[WSA_MACRO_COMP1] && (gain_reg == BOLERO_CDC_WSA_RX0_RX_VOL_CTL) && (wsa_priv->ear_spkr_gain != 0)) { - snd_soc_write(codec, gain_reg, 0x0); + snd_soc_component_write(component, gain_reg, 0x0); dev_dbg(wsa_priv->dev, "%s: Reset RX0 Volume to 0 dB\n", __func__); @@ -1453,11 +1488,12 @@ static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); u16 boost_path_ctl, boost_path_cfg1; u16 reg, reg_mix; - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); if (!strcmp(w->name, "WSA_RX INT0 CHAIN")) { boost_path_ctl = BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL; @@ -1470,24 +1506,29 @@ static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w, reg = BOLERO_CDC_WSA_RX1_RX_PATH_CTL; reg_mix = BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL; } else { - dev_err(codec->dev, "%s: unknown widget: %s\n", + dev_err(component->dev, "%s: unknown widget: %s\n", __func__, w->name); return -EINVAL; } switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x01); - snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x10); - if ((snd_soc_read(codec, reg_mix)) & 0x10) - snd_soc_update_bits(codec, reg_mix, 0x10, 0x00); + snd_soc_component_update_bits(component, boost_path_cfg1, + 0x01, 0x01); + snd_soc_component_update_bits(component, boost_path_ctl, + 0x10, 0x10); + if ((snd_soc_component_read32(component, reg_mix)) & 0x10) + snd_soc_component_update_bits(component, reg_mix, + 0x10, 0x00); break; case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, reg, 0x10, 0x00); + snd_soc_component_update_bits(component, reg, 0x10, 0x00); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x00); - snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x00); + snd_soc_component_update_bits(component, boost_path_ctl, + 0x10, 0x00); + snd_soc_component_update_bits(component, boost_path_cfg1, + 0x01, 0x00); break; } @@ -1499,16 +1540,17 @@ static int wsa_macro_enable_vbat(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; u16 vbat_path_cfg = 0; int softclip_path = 0; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); if (!strcmp(w->name, "WSA_RX INT0 VBAT")) { vbat_path_cfg = BOLERO_CDC_WSA_RX0_RX_PATH_CFG1; softclip_path = WSA_MACRO_SOFTCLIP0; @@ -1520,92 +1562,97 @@ static int wsa_macro_enable_vbat(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: /* Enable clock for VBAT block */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x10); /* Enable VBAT block */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x01); /* Update interpolator with 384K path */ - snd_soc_update_bits(codec, vbat_path_cfg, 0x80, 0x80); + snd_soc_component_update_bits(component, vbat_path_cfg, + 0x80, 0x80); /* Use attenuation mode */ - snd_soc_update_bits(codec, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, - 0x02, 0x00); + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x02, 0x00); /* * BCL block needs softclip clock and mux config to be enabled */ - wsa_macro_enable_softclip_clk(codec, wsa_priv, softclip_path, - true); + wsa_macro_enable_softclip_clk(component, wsa_priv, + softclip_path, true); /* Enable VBAT at channel level */ - snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x02); + snd_soc_component_update_bits(component, vbat_path_cfg, + 0x02, 0x02); /* Set the ATTK1 gain */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1, 0xFF, 0xFF); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2, 0xFF, 0x03); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3, 0xFF, 0x00); /* Set the ATTK2 gain */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4, 0xFF, 0xFF); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5, 0xFF, 0x03); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6, 0xFF, 0x00); /* Set the ATTK3 gain */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7, 0xFF, 0xFF); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8, 0xFF, 0x03); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9, 0xFF, 0x00); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, vbat_path_cfg, 0x80, 0x00); - snd_soc_update_bits(codec, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, - 0x02, 0x02); - snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, vbat_path_cfg, + 0x80, 0x00); + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, + 0x02, 0x02); + snd_soc_component_update_bits(component, vbat_path_cfg, + 0x02, 0x00); + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1, 0xFF, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2, 0xFF, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3, 0xFF, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4, 0xFF, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5, 0xFF, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6, 0xFF, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7, 0xFF, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8, 0xFF, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9, 0xFF, 0x00); - wsa_macro_enable_softclip_clk(codec, wsa_priv, softclip_path, - false); - snd_soc_update_bits(codec, + wsa_macro_enable_softclip_clk(component, wsa_priv, + softclip_path, false); + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x00); break; default: @@ -1619,17 +1666,19 @@ static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; u16 val, ec_tx = 0, ec_hq_reg; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; dev_dbg(wsa_dev, "%s %d %s\n", __func__, event, w->name); - val = snd_soc_read(codec, BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0); + val = snd_soc_component_read32(component, + BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0); if (!(strcmp(w->name, "WSA RX_MIX EC0_MUX"))) ec_tx = (val & 0x07) - 1; else @@ -1641,16 +1690,16 @@ static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w, return -EINVAL; } if (wsa_priv->ec_hq[ec_tx]) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0, 0x1 << ec_tx, 0x1 << ec_tx); ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL + 0x20 * ec_tx; - snd_soc_update_bits(codec, ec_hq_reg, 0x01, 0x01); + snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01); ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 + 0x20 * ec_tx; /* default set to 48k */ - snd_soc_update_bits(codec, ec_hq_reg, 0x1E, 0x08); + snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08); } return 0; @@ -1660,13 +1709,14 @@ static int wsa_macro_get_ec_hq(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int ec_tx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; ucontrol->value.integer.value[0] = wsa_priv->ec_hq[ec_tx]; @@ -1676,14 +1726,15 @@ static int wsa_macro_get_ec_hq(struct snd_kcontrol *kcontrol, static int wsa_macro_set_ec_hq(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int ec_tx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; int value = ucontrol->value.integer.value[0]; struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; dev_dbg(wsa_dev, "%s: enable current %d, new %d\n", @@ -1697,13 +1748,14 @@ static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int comp = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; ucontrol->value.integer.value[0] = wsa_priv->comp_enabled[comp]; @@ -1713,17 +1765,18 @@ static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol, static int wsa_macro_set_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int comp = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; int value = ucontrol->value.integer.value[0]; struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; - dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n", + dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n", __func__, comp + 1, wsa_priv->comp_enabled[comp], value); wsa_priv->comp_enabled[comp] = value; @@ -1733,16 +1786,17 @@ static int wsa_macro_set_compander(struct snd_kcontrol *kcontrol, static int wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; ucontrol->value.integer.value[0] = wsa_priv->ear_spkr_gain; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); return 0; @@ -1751,16 +1805,17 @@ static int wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, static int wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; wsa_priv->ear_spkr_gain = ucontrol->value.integer.value[0]; - dev_dbg(codec->dev, "%s: gain = %d\n", __func__, + dev_dbg(component->dev, "%s: gain = %d\n", __func__, wsa_priv->ear_spkr_gain); return 0; @@ -1770,12 +1825,14 @@ static int wsa_macro_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 bst_state_max = 0; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - bst_state_max = snd_soc_read(codec, BOLERO_CDC_WSA_BOOST0_BOOST_CTL); + bst_state_max = snd_soc_component_read32(component, + BOLERO_CDC_WSA_BOOST0_BOOST_CTL); bst_state_max = (bst_state_max & 0x0c) >> 2; ucontrol->value.integer.value[0] = bst_state_max; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); return 0; @@ -1785,13 +1842,15 @@ static int wsa_macro_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 bst_state_max; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); bst_state_max = ucontrol->value.integer.value[0] << 2; - snd_soc_update_bits(codec, BOLERO_CDC_WSA_BOOST0_BOOST_CTL, - 0x0c, bst_state_max); + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_BOOST0_BOOST_CTL, + 0x0c, bst_state_max); return 0; } @@ -1800,12 +1859,14 @@ static int wsa_macro_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 bst_state_max = 0; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - bst_state_max = snd_soc_read(codec, BOLERO_CDC_WSA_BOOST1_BOOST_CTL); + bst_state_max = snd_soc_component_read32(component, + BOLERO_CDC_WSA_BOOST1_BOOST_CTL); bst_state_max = (bst_state_max & 0x0c) >> 2; ucontrol->value.integer.value[0] = bst_state_max; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); return 0; @@ -1815,13 +1876,15 @@ static int wsa_macro_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 bst_state_max; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); bst_state_max = ucontrol->value.integer.value[0] << 2; - snd_soc_update_bits(codec, BOLERO_CDC_WSA_BOOST1_BOOST_CTL, - 0x0c, bst_state_max); + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_BOOST1_BOOST_CTL, + 0x0c, bst_state_max); return 0; } @@ -1831,11 +1894,12 @@ static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; ucontrol->value.integer.value[0] = @@ -1848,7 +1912,8 @@ static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct snd_soc_dapm_update *update = NULL; u32 rx_port_value = ucontrol->value.integer.value[0]; @@ -1857,7 +1922,7 @@ static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol, struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; aif_rst = wsa_priv->rx_port_value[widget->shift]; @@ -1899,13 +1964,15 @@ static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol, static int wsa_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); ucontrol->value.integer.value[0] = - ((snd_soc_read(codec, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG) & 0x04) ? + ((snd_soc_component_read32( + component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG) & 0x04) ? 1 : 0); - dev_dbg(codec->dev, "%s: value: %lu\n", __func__, + dev_dbg(component->dev, "%s: value: %lu\n", __func__, ucontrol->value.integer.value[0]); return 0; @@ -1914,18 +1981,21 @@ static int wsa_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol, static int wsa_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - dev_dbg(codec->dev, "%s: value: %lu\n", __func__, + dev_dbg(component->dev, "%s: value: %lu\n", __func__, ucontrol->value.integer.value[0]); /* Set Vbat register configuration for GSM mode bit based on value */ if (ucontrol->value.integer.value[0]) - snd_soc_update_bits(codec, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, - 0x04, 0x04); + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, + 0x04, 0x04); else - snd_soc_update_bits(codec, BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, - 0x04, 0x00); + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, + 0x04, 0x00); return 0; } @@ -1933,18 +2003,19 @@ static int wsa_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol, static int wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; int path = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; ucontrol->value.integer.value[0] = wsa_priv->is_softclip_on[path]; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); return 0; @@ -1953,18 +2024,19 @@ static int wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol, static int wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; int path = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; wsa_priv->is_softclip_on[path] = ucontrol->value.integer.value[0]; - dev_dbg(codec->dev, "%s: soft clip enable for %d: %d\n", __func__, + dev_dbg(component->dev, "%s: soft clip enable for %d: %d\n", __func__, path, wsa_priv->is_softclip_on[path]); return 0; @@ -2028,7 +2100,8 @@ static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct soc_multi_mixer_control *mixer = ((struct soc_multi_mixer_control *)kcontrol->private_value); u32 dai_id = widget->shift; @@ -2036,7 +2109,7 @@ static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; if (test_bit(spk_tx_id, &wsa_priv->active_ch_mask[dai_id])) @@ -2052,7 +2125,8 @@ static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct soc_multi_mixer_control *mixer = ((struct soc_multi_mixer_control *)kcontrol->private_value); u32 spk_tx_id = mixer->shift; @@ -2060,7 +2134,7 @@ static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; wsa_priv->vi_feed_value = ucontrol->value.integer.value[0]; @@ -2369,43 +2443,43 @@ static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = { {BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x01, 0x01}, }; -static void wsa_macro_init_bcl_pmic_reg(struct snd_soc_codec *codec) +static void wsa_macro_init_bcl_pmic_reg(struct snd_soc_component *component) { struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!codec) { - pr_err("%s: NULL codec pointer!\n", __func__); + if (!component) { + pr_err("%s: NULL component pointer!\n", __func__); return; } - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return; switch (wsa_priv->bcl_pmic_params.id) { case 0: /* Enable ID0 to listen to respective PMIC group interrupts */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x02, 0x02); /* Update MC_SID0 */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1, 0x0F, wsa_priv->bcl_pmic_params.sid); /* Update MC_PPID0 */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2, 0xFF, wsa_priv->bcl_pmic_params.ppid); break; case 1: /* Enable ID1 to listen to respective PMIC group interrupts */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x01, 0x01); /* Update MC_SID1 */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3, 0x0F, wsa_priv->bcl_pmic_params.sid); /* Update MC_PPID1 */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4, 0xFF, wsa_priv->bcl_pmic_params.ppid); break; @@ -2416,17 +2490,17 @@ static void wsa_macro_init_bcl_pmic_reg(struct snd_soc_codec *codec) } } -static void wsa_macro_init_reg(struct snd_soc_codec *codec) +static void wsa_macro_init_reg(struct snd_soc_component *component) { int i; for (i = 0; i < ARRAY_SIZE(wsa_macro_reg_init); i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, wsa_macro_reg_init[i].reg, wsa_macro_reg_init[i].mask, wsa_macro_reg_init[i].val); - wsa_macro_init_bcl_pmic_reg(codec); + wsa_macro_init_bcl_pmic_reg(component); } static int wsa_swrm_clock(void *handle, bool enable) @@ -2487,22 +2561,23 @@ static int wsa_swrm_clock(void *handle, bool enable) return ret; } -static int wsa_macro_init(struct snd_soc_codec *codec) +static int wsa_macro_init(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); int ret; struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - wsa_dev = bolero_get_device_ptr(codec->dev, WSA_MACRO); + wsa_dev = bolero_get_device_ptr(component->dev, WSA_MACRO); if (!wsa_dev) { - dev_err(codec->dev, + dev_err(component->dev, "%s: null device for macro!\n", __func__); return -EINVAL; } wsa_priv = dev_get_drvdata(wsa_dev); if (!wsa_priv) { - dev_err(codec->dev, + dev_err(component->dev, "%s: priv is null for macro!\n", __func__); return -EINVAL; } @@ -2527,7 +2602,7 @@ static int wsa_macro_init(struct snd_soc_codec *codec) return ret; } - ret = snd_soc_add_codec_controls(codec, wsa_macro_snd_controls, + ret = snd_soc_add_component_controls(component, wsa_macro_snd_controls, ARRAY_SIZE(wsa_macro_snd_controls)); if (ret < 0) { dev_err(wsa_dev, "%s: Failed to add snd_ctls\n", __func__); @@ -2545,22 +2620,22 @@ static int wsa_macro_init(struct snd_soc_codec *codec) snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC1_INP"); snd_soc_dapm_sync(dapm); - wsa_priv->codec = codec; + wsa_priv->component = component; wsa_priv->spkr_gain_offset = WSA_MACRO_GAIN_OFFSET_0_DB; - wsa_macro_init_reg(codec); + wsa_macro_init_reg(component); return 0; } -static int wsa_macro_deinit(struct snd_soc_codec *codec) +static int wsa_macro_deinit(struct snd_soc_component *component) { struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - if (!wsa_macro_get_data(codec, &wsa_dev, &wsa_priv, __func__)) + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; - wsa_priv->codec = NULL; + wsa_priv->component = NULL; return 0; } diff --git a/asoc/codecs/bolero/wsa-macro.h b/asoc/codecs/bolero/wsa-macro.h index ec8f5249b2d6..f2553c02d30a 100644 --- a/asoc/codecs/bolero/wsa-macro.h +++ b/asoc/codecs/bolero/wsa-macro.h @@ -21,16 +21,19 @@ enum { #if IS_ENABLED(CONFIG_WSA_MACRO) -extern int wsa_macro_set_spkr_mode(struct snd_soc_codec *codec, int mode); -extern int wsa_macro_set_spkr_gain_offset(struct snd_soc_codec *codec, +extern int wsa_macro_set_spkr_mode(struct snd_soc_component *component, + int mode); +extern int wsa_macro_set_spkr_gain_offset(struct snd_soc_component *component, int offset); #else /* CONFIG_WSA_MACRO */ -static inline int wsa_macro_set_spkr_mode(struct snd_soc_codec *codec, int mode) +static inline int wsa_macro_set_spkr_mode(struct snd_soc_component *component, + int mode) { return 0; } -static inline int wsa_macro_set_spkr_gain_offset(struct snd_soc_codec *codec, - int offset); +static inline int wsa_macro_set_spkr_gain_offset( + struct snd_soc_component *component, + int offset); { return 0; } diff --git a/asoc/codecs/cpe_core.h b/asoc/codecs/cpe_core.h index 989c4a9d1d2f..7cfbd43302d3 100644 --- a/asoc/codecs/cpe_core.h +++ b/asoc/codecs/cpe_core.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. */ #ifndef __CPE_CORE_H__ @@ -107,35 +107,37 @@ struct wcd_cpe_lsm_ops { u8 size, u8 *payload)); int (*lsm_dealloc_session) - (void *core_handle, struct cpe_lsm_session *); + (void *core_handle, struct cpe_lsm_session *session); int (*lsm_open_tx)(void *core_handle, - struct cpe_lsm_session *, u16, u16); + struct cpe_lsm_session *session, u16 app_id, + u16 sample_rate); int (*lsm_close_tx)(void *core_handle, - struct cpe_lsm_session *); + struct cpe_lsm_session *session); int (*lsm_shmem_alloc)(void *core_handle, - struct cpe_lsm_session *, u32 size); + struct cpe_lsm_session *session, u32 size); int (*lsm_shmem_dealloc)(void *core_handle, - struct cpe_lsm_session *); + struct cpe_lsm_session *session); int (*lsm_register_snd_model)(void *core_handle, - struct cpe_lsm_session *, - enum lsm_detection_mode, bool); + struct cpe_lsm_session *session, + enum lsm_detection_mode, + bool detect_failure); int (*lsm_deregister_snd_model)(void *core_handle, - struct cpe_lsm_session *); + struct cpe_lsm_session *session); int (*lsm_get_afe_out_port_id)(void *core_handle, struct cpe_lsm_session *session); int (*lsm_start)(void *core_handle, - struct cpe_lsm_session *); + struct cpe_lsm_session *session); int (*lsm_stop)(void *core_handle, - struct cpe_lsm_session *); + struct cpe_lsm_session *session); int (*lsm_lab_control)(void *core_handle, struct cpe_lsm_session *session, @@ -156,7 +158,7 @@ struct wcd_cpe_lsm_ops { struct lsm_params_info *p_info, void *data, uint32_t param_type); void (*lsm_get_snd_model_offset) - (void *core_handle, struct cpe_lsm_session *, + (void *core_handle, struct cpe_lsm_session *session, size_t *offset); int (*lsm_set_media_fmt_params)(void *core_handle, struct cpe_lsm_session *session, @@ -168,7 +170,7 @@ struct wcd_cpe_lsm_ops { #if IS_ENABLED(CONFIG_SND_SOC_WCD_CPE) int wcd_cpe_get_lsm_ops(struct wcd_cpe_lsm_ops *lsm_ops); int wcd_cpe_get_afe_ops(struct wcd_cpe_afe_ops *afe_ops); -void *wcd_cpe_get_core_handle(struct snd_soc_codec *codec); +void *wcd_cpe_get_core_handle(struct snd_soc_component *component); #else /* CONFIG_SND_SOC_WCD_CPE */ static inline int wcd_cpe_get_lsm_ops(struct wcd_cpe_lsm_ops *lsm_ops) { @@ -178,7 +180,7 @@ static inline int wcd_cpe_get_afe_ops(struct wcd_cpe_afe_ops *afe_ops) { return 0; } -static inline void *wcd_cpe_get_core_handle(struct snd_soc_codec *codec) +static inline void *wcd_cpe_get_core_handle(struct snd_soc_component *component) { return NULL; } diff --git a/asoc/codecs/csra66x0/csra66x0.c b/asoc/codecs/csra66x0/csra66x0.c index 97041a19d8b7..33e53340f282 100644 --- a/asoc/codecs/csra66x0/csra66x0.c +++ b/asoc/codecs/csra66x0/csra66x0.c @@ -19,6 +19,8 @@ #include #include "csra66x0.h" +#define DRV_NAME "csra66x0_codec" + /* CSRA66X0 register default values */ static struct reg_default csra66x0_reg_defaults[] = { {CSRA66X0_AUDIO_IF_RX_CONFIG1, 0x00}, @@ -247,7 +249,7 @@ static bool csra66x0_readable_registers(struct device *dev, unsigned int reg) /* codec private data */ struct csra66x0_priv { struct regmap *regmap; - struct snd_soc_codec *codec; + struct snd_soc_component *component; int spk_volume_ch1; int spk_volume_ch2; int irq; @@ -312,7 +314,7 @@ static ssize_t debugfs_codec_write_op(struct file *filp, { struct csra66x0_priv *csra66x0 = (struct csra66x0_priv *) filp->private_data; - struct snd_soc_codec *codec = csra66x0->codec; + struct snd_soc_component *component = csra66x0->component; char lbuf[32]; int rc; u32 param[2]; @@ -328,46 +330,47 @@ static ssize_t debugfs_codec_write_op(struct file *filp, rc = debugfs_get_parameters(lbuf, param, 2); if ((param[0] < CSRA66X0_AUDIO_IF_RX_CONFIG1) || (param[0] > CSRA66X0_MAX_REGISTER_ADDR)) { - dev_err(codec->dev, "%s: register address 0x%04X out of range\n", + dev_err(component->dev, "%s: register address 0x%04X out of range\n", __func__, param[0]); return -EINVAL; } if ((param[1] < 0) || (param[1] > 255)) { - dev_err(codec->dev, "%s: register data 0x%02X out of range\n", + dev_err(component->dev, "%s: register data 0x%02X out of range\n", __func__, param[1]); return -EINVAL; } if (rc == 0) { rc = cnt; - dev_info(codec->dev, "%s: reg[0x%04X]=0x%02X\n", + dev_info(component->dev, "%s: reg[0x%04X]=0x%02X\n", __func__, param[0], param[1]); - snd_soc_write(codec, param[0], param[1]); + snd_soc_component_write(component, param[0], param[1]); } else { - dev_err(codec->dev, "%s: write to register addr=0x%04X failed\n", + dev_err(component->dev, "%s: write to register addr=0x%04X failed\n", __func__, param[0]); } return rc; } -static ssize_t debugfs_csra66x0_reg_show(struct snd_soc_codec *codec, +static ssize_t debugfs_csra66x0_reg_show(struct snd_soc_component *component, char __user *ubuf, size_t count, loff_t *ppos) { int i, reg_val, len; ssize_t total = 0; char tmp_buf[20]; - if (!ubuf || !ppos || !codec || *ppos < 0) + if (!ubuf || !ppos || !component || *ppos < 0) return -EINVAL; for (i = ((int) *ppos + CSRA66X0_BASE); i <= CSRA66X0_MAX_REGISTER_ADDR; i++) { - reg_val = snd_soc_read(codec, i); + reg_val = snd_soc_component_read32(component, i); len = snprintf(tmp_buf, 20, "0x%04X: 0x%02X\n", i, (reg_val & 0xFF)); if ((total + len) >= count - 1) break; if (copy_to_user((ubuf + total), tmp_buf, len)) { - dev_err(codec->dev, "%s: fail to copy reg dump\n", __func__); + dev_err(component->dev, "%s: fail to copy reg dump\n", + __func__); total = -EFAULT; goto copy_err; } @@ -384,12 +387,12 @@ static ssize_t debugfs_codec_read_op(struct file *filp, { struct csra66x0_priv *csra66x0 = (struct csra66x0_priv *) filp->private_data; - struct snd_soc_codec *codec = csra66x0->codec; + struct snd_soc_component *component = csra66x0->component; ssize_t ret_cnt; if (!filp || !ppos || !ubuf || *ppos < 0) return -EINVAL; - ret_cnt = debugfs_csra66x0_reg_show(codec, ubuf, cnt, ppos); + ret_cnt = debugfs_csra66x0_reg_show(component, ubuf, cnt, ppos); return ret_cnt; } @@ -415,16 +418,17 @@ static int csra66x0_get_volume(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); unsigned int reg_l = mc->reg; unsigned int reg_r = mc->rreg; unsigned int val_l, val_r; - val_l = (snd_soc_read(codec, reg_l) & 0xff) | - ((snd_soc_read(codec, + val_l = (snd_soc_component_read32(component, reg_l) & 0xff) | + ((snd_soc_component_read32(component, CSRA66X0_CH1_VOLUME_1_FA) & (0x01)) << 8); - val_r = (snd_soc_read(codec, reg_r) & 0xff) | - ((snd_soc_read(codec, + val_r = (snd_soc_component_read32(component, reg_r) & 0xff) | + ((snd_soc_component_read32(component, CSRA66X0_CH2_VOLUME_1_FA) & (0x01)) << 8); ucontrol->value.integer.value[0] = val_l; ucontrol->value.integer.value[1] = val_r; @@ -436,8 +440,10 @@ static int csra66x0_set_volume(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct csra66x0_priv *csra66x0 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct csra66x0_priv *csra66x0 = + snd_soc_component_get_drvdata(component); unsigned int reg_l = mc->reg; unsigned int reg_r = mc->rreg; unsigned int val_l[2]; @@ -449,10 +455,10 @@ static int csra66x0_set_volume(struct snd_kcontrol *kcontrol, val_l[1] = (csra66x0->spk_volume_ch1 & SPK_VOLUME_MSB_MSK) ? 1 : 0; val_r[0] = csra66x0->spk_volume_ch2 & SPK_VOLUME_LSB_MSK; val_r[1] = (csra66x0->spk_volume_ch2 & SPK_VOLUME_MSB_MSK) ? 1 : 0; - snd_soc_write(codec, reg_l, val_l[0]); - snd_soc_write(codec, reg_r, val_r[0]); - snd_soc_write(codec, CSRA66X0_CH1_VOLUME_1_FA, val_l[1]); - snd_soc_write(codec, CSRA66X0_CH2_VOLUME_1_FA, val_r[1]); + snd_soc_component_write(component, reg_l, val_l[0]); + snd_soc_component_write(component, reg_r, val_r[0]); + snd_soc_component_write(component, CSRA66X0_CH1_VOLUME_1_FA, val_l[1]); + snd_soc_component_write(component, CSRA66X0_CH2_VOLUME_1_FA, val_r[1]); return 0; } @@ -526,51 +532,66 @@ static const struct snd_soc_dapm_route csra66x0_dapm_routes[] = { static int csra66x0_init(struct csra66x0_priv *csra66x0) { - struct snd_soc_codec *codec = csra66x0->codec; + struct snd_soc_component *component = csra66x0->component; - dev_dbg(codec->dev, "%s: initialize %s\n", - __func__, codec->component.name); + dev_dbg(component->dev, "%s: initialize %s\n", + __func__, component->name); /* config */ - snd_soc_write(codec, CSRA66X0_CHIP_STATE_CTRL_FA, CONFIG_STATE); + snd_soc_component_write(component, CSRA66X0_CHIP_STATE_CTRL_FA, + CONFIG_STATE); /* settle time in HW is min. 500ms before proceeding */ msleep(500); /* setup */ - snd_soc_write(codec, CSRA66X0_MISC_CONTROL_STATUS_0, 0x09); - snd_soc_write(codec, CSRA66X0_TEMP_PROT_BACKOFF, 0x0C); - snd_soc_write(codec, CSRA66X0_EXT_PA_PROTECT_POLARITY, 0x03); - snd_soc_write(codec, CSRA66X0_PWM_OUTPUT_CONFIG, 0xC8); + snd_soc_component_write(component, CSRA66X0_MISC_CONTROL_STATUS_0, + 0x09); + snd_soc_component_write(component, CSRA66X0_TEMP_PROT_BACKOFF, 0x0C); + snd_soc_component_write(component, CSRA66X0_EXT_PA_PROTECT_POLARITY, + 0x03); + snd_soc_component_write(component, CSRA66X0_PWM_OUTPUT_CONFIG, 0xC8); csra66x0->spk_volume_ch1 = SPK_VOLUME_M20DB; csra66x0->spk_volume_ch2 = SPK_VOLUME_M20DB; - snd_soc_write(codec, CSRA66X0_CH1_VOLUME_0_FA, SPK_VOLUME_M20DB_LSB); - snd_soc_write(codec, CSRA66X0_CH2_VOLUME_0_FA, SPK_VOLUME_M20DB_LSB); - snd_soc_write(codec, CSRA66X0_CH1_VOLUME_1_FA, SPK_VOLUME_M20DB_MSB); - snd_soc_write(codec, CSRA66X0_CH2_VOLUME_1_FA, SPK_VOLUME_M20DB_MSB); - - snd_soc_write(codec, CSRA66X0_DEAD_TIME_CTRL, 0x0); - snd_soc_write(codec, CSRA66X0_DEAD_TIME_THRESHOLD_0, 0xE7); - snd_soc_write(codec, CSRA66X0_DEAD_TIME_THRESHOLD_1, 0x26); - snd_soc_write(codec, CSRA66X0_DEAD_TIME_THRESHOLD_2, 0x40); - - snd_soc_write(codec, CSRA66X0_MIN_MODULATION_PULSE_WIDTH, 0x7A); - snd_soc_write(codec, CSRA66X0_CH1_HARD_CLIP_THRESH, 0x00); - snd_soc_write(codec, CSRA66X0_CH2_HARD_CLIP_THRESH, 0x00); - - snd_soc_write(codec, CSRA66X0_CH1_DCA_THRESH, 0x40); - snd_soc_write(codec, CSRA66X0_CH2_DCA_THRESH, 0x40); - snd_soc_write(codec, CSRA66X0_DCA_ATTACK_RATE, 0x00); - snd_soc_write(codec, CSRA66X0_DCA_RELEASE_RATE, 0x00); + snd_soc_component_write(component, CSRA66X0_CH1_VOLUME_0_FA, + SPK_VOLUME_M20DB_LSB); + snd_soc_component_write(component, CSRA66X0_CH2_VOLUME_0_FA, + SPK_VOLUME_M20DB_LSB); + snd_soc_component_write(component, CSRA66X0_CH1_VOLUME_1_FA, + SPK_VOLUME_M20DB_MSB); + snd_soc_component_write(component, CSRA66X0_CH2_VOLUME_1_FA, + SPK_VOLUME_M20DB_MSB); + + snd_soc_component_write(component, CSRA66X0_DEAD_TIME_CTRL, 0x0); + snd_soc_component_write(component, CSRA66X0_DEAD_TIME_THRESHOLD_0, + 0xE7); + snd_soc_component_write(component, CSRA66X0_DEAD_TIME_THRESHOLD_1, + 0x26); + snd_soc_component_write(component, CSRA66X0_DEAD_TIME_THRESHOLD_2, + 0x40); + + snd_soc_component_write(component, CSRA66X0_MIN_MODULATION_PULSE_WIDTH, + 0x7A); + snd_soc_component_write(component, CSRA66X0_CH1_HARD_CLIP_THRESH, 0x00); + snd_soc_component_write(component, CSRA66X0_CH2_HARD_CLIP_THRESH, 0x00); + + snd_soc_component_write(component, CSRA66X0_CH1_DCA_THRESH, 0x40); + snd_soc_component_write(component, CSRA66X0_CH2_DCA_THRESH, 0x40); + snd_soc_component_write(component, CSRA66X0_DCA_ATTACK_RATE, 0x00); + snd_soc_component_write(component, CSRA66X0_DCA_RELEASE_RATE, 0x00); if (csra66x0->irq) { - snd_soc_write(codec, CSRA66X0_PIO0_SELECT, 0x1); + snd_soc_component_write(component, CSRA66X0_PIO0_SELECT, 0x1); if (csra66x0->irq_active_low) - snd_soc_write(codec, CSRA66X0_IRQ_OUTPUT_POLARITY, 0x0); + snd_soc_component_write(component, + CSRA66X0_IRQ_OUTPUT_POLARITY, 0x0); else - snd_soc_write(codec, CSRA66X0_IRQ_OUTPUT_POLARITY, 0x1); + snd_soc_component_write(component, + CSRA66X0_IRQ_OUTPUT_POLARITY, 0x1); - snd_soc_write(codec, CSRA66X0_IRQ_OUTPUT_ENABLE, 0x01); + snd_soc_component_write(component, + CSRA66X0_IRQ_OUTPUT_ENABLE, 0x01); } else { - snd_soc_write(codec, CSRA66X0_IRQ_OUTPUT_ENABLE, 0x00); + snd_soc_component_write(component, + CSRA66X0_IRQ_OUTPUT_ENABLE, 0x00); } /* settle time in HW is min. 500ms before slave initializing */ msleep(500); @@ -579,37 +600,39 @@ static int csra66x0_init(struct csra66x0_priv *csra66x0) static int csra66x0_reset(struct csra66x0_priv *csra66x0) { - struct snd_soc_codec *codec = csra66x0->codec; + struct snd_soc_component *component = csra66x0->component; u16 val; - val = snd_soc_read(codec, CSRA66X0_FAULT_STATUS_FA); + val = snd_soc_component_read32(component, CSRA66X0_FAULT_STATUS_FA); if (val & FAULT_STATUS_INTERNAL) - dev_dbg(codec->dev, "%s: FAULT_STATUS_INTERNAL 0x%X\n", + dev_dbg(component->dev, "%s: FAULT_STATUS_INTERNAL 0x%X\n", __func__, val); if (val & FAULT_STATUS_OTP_INTEGRITY) - dev_dbg(codec->dev, "%s: FAULT_STATUS_OTP_INTEGRITY 0x%X\n", + dev_dbg(component->dev, "%s: FAULT_STATUS_OTP_INTEGRITY 0x%X\n", __func__, val); if (val & FAULT_STATUS_PADS2) - dev_dbg(codec->dev, "%s: FAULT_STATUS_PADS2 0x%X\n", + dev_dbg(component->dev, "%s: FAULT_STATUS_PADS2 0x%X\n", __func__, val); if (val & FAULT_STATUS_SMPS) - dev_dbg(codec->dev, "%s: FAULT_STATUS_SMPS 0x%X\n", + dev_dbg(component->dev, "%s: FAULT_STATUS_SMPS 0x%X\n", __func__, val); if (val & FAULT_STATUS_TEMP) - dev_dbg(codec->dev, "%s: FAULT_STATUS_TEMP 0x%X\n", + dev_dbg(component->dev, "%s: FAULT_STATUS_TEMP 0x%X\n", __func__, val); if (val & FAULT_STATUS_PROTECT) - dev_dbg(codec->dev, "%s: FAULT_STATUS_PROTECT 0x%X\n", + dev_dbg(component->dev, "%s: FAULT_STATUS_PROTECT 0x%X\n", __func__, val); - dev_dbg(codec->dev, "%s: reset %s\n", - __func__, codec->component.name); + dev_dbg(component->dev, "%s: reset %s\n", + __func__, component->name); /* clear fault state and re-init */ - snd_soc_write(codec, CSRA66X0_FAULT_STATUS_FA, 0x00); - snd_soc_write(codec, CSRA66X0_IRQ_OUTPUT_STATUS_FA, 0x00); + snd_soc_component_write(component, CSRA66X0_FAULT_STATUS_FA, 0x00); + snd_soc_component_write(component, CSRA66X0_IRQ_OUTPUT_STATUS_FA, 0x00); /* apply reset to CSRA66X0 */ - val = snd_soc_read(codec, CSRA66X0_MISC_CONTROL_STATUS_1_FA); - snd_soc_write(codec, CSRA66X0_MISC_CONTROL_STATUS_1_FA, val | 0x08); + val = snd_soc_component_read32(component, + CSRA66X0_MISC_CONTROL_STATUS_1_FA); + snd_soc_component_write(component, CSRA66X0_MISC_CONTROL_STATUS_1_FA, + val | 0x08); /* wait 500ms after reset to recover CSRA66X0 */ msleep(500); return 0; @@ -617,51 +640,58 @@ static int csra66x0_reset(struct csra66x0_priv *csra66x0) static int csra66x0_msconfig(struct csra66x0_priv *csra66x0) { - struct snd_soc_codec *codec = csra66x0->codec; + struct snd_soc_component *component = csra66x0->component; - dev_dbg(codec->dev, "%s: configure %s\n", - __func__, codec->component.name); + dev_dbg(component->dev, "%s: configure %s\n", + __func__, component->name); /* config */ - snd_soc_write(codec, CSRA66X0_CHIP_STATE_CTRL_FA, + snd_soc_component_write(component, CSRA66X0_CHIP_STATE_CTRL_FA, CONFIG_STATE); /* settle time in HW is min. 500ms before proceeding */ msleep(500); - snd_soc_write(codec, CSRA66X0_PIO7_SELECT, 0x04); - snd_soc_write(codec, CSRA66X0_PIO8_SELECT, 0x04); + snd_soc_component_write(component, CSRA66X0_PIO7_SELECT, 0x04); + snd_soc_component_write(component, CSRA66X0_PIO8_SELECT, 0x04); if (csra66x0->is_master) { /* Master specific config */ - snd_soc_write(codec, CSRA66X0_PIO_PULL_EN0, 0xFF); - snd_soc_write(codec, CSRA66X0_PIO_PULL_DIR0, 0x80); - snd_soc_write(codec, CSRA66X0_PIO_PULL_EN1, 0x01); - snd_soc_write(codec, CSRA66X0_PIO_PULL_DIR1, 0x01); + snd_soc_component_write(component, + CSRA66X0_PIO_PULL_EN0, 0xFF); + snd_soc_component_write(component, + CSRA66X0_PIO_PULL_DIR0, 0x80); + snd_soc_component_write(component, + CSRA66X0_PIO_PULL_EN1, 0x01); + snd_soc_component_write(component, + CSRA66X0_PIO_PULL_DIR1, 0x01); } else { /* Slave specific config */ - snd_soc_write(codec, CSRA66X0_PIO_PULL_EN0, 0x7F); - snd_soc_write(codec, CSRA66X0_PIO_PULL_EN1, 0x00); + snd_soc_component_write(component, + CSRA66X0_PIO_PULL_EN0, 0x7F); + snd_soc_component_write(component, + CSRA66X0_PIO_PULL_EN1, 0x00); } - snd_soc_write(codec, CSRA66X0_DCA_CTRL, 0x05); + snd_soc_component_write(component, CSRA66X0_DCA_CTRL, 0x05); return 0; } -static int csra66x0_soc_probe(struct snd_soc_codec *codec) +static int csra66x0_soc_probe(struct snd_soc_component *component) { - struct csra66x0_priv *csra66x0 = snd_soc_codec_get_drvdata(codec); + struct csra66x0_priv *csra66x0 = + snd_soc_component_get_drvdata(component); struct snd_soc_dapm_context *dapm; char name[50]; unsigned int i, max_num_cluster_devices; - csra66x0->codec = codec; + csra66x0->component = component; if (csra66x0->in_cluster) { - dapm = snd_soc_codec_get_dapm(codec); - dev_dbg(codec->dev, "%s: assign prefix %s to codec device %s\n", - __func__, codec->component.name_prefix, - codec->component.name); + dapm = snd_soc_component_get_dapm(component); + dev_dbg(component->dev, "%s: assign prefix %s to codec device %s\n", + __func__, component->name_prefix, + component->name); /* add device to cluster table */ max_num_cluster_devices = sizeof(csra_clust_dev_tbl)/ sizeof(csra_clust_dev_tbl[0]); for (i = 0; i < max_num_cluster_devices; i++) { - if (!strncmp(codec->component.name_prefix, + if (!strncmp(component->name_prefix, csra_clust_dev_tbl[i].csra66x0_prefix, strlen( csra_clust_dev_tbl[i].csra66x0_prefix))) { @@ -669,21 +699,21 @@ static int csra66x0_soc_probe(struct snd_soc_codec *codec) break; } if (i == max_num_cluster_devices-1) - dev_warn(codec->dev, + dev_warn(component->dev, "%s: Unknown prefix %s of cluster device %s\n", - __func__, codec->component.name_prefix, - codec->component.name); + __func__, component->name_prefix, + component->name); } /* master slave config */ csra66x0_msconfig(csra66x0); if (dapm->component) { strlcpy(name, dapm->component->name_prefix, - sizeof(name)); + sizeof(name)); strlcat(name, " IN", sizeof(name)); snd_soc_dapm_ignore_suspend(dapm, name); strlcpy(name, dapm->component->name_prefix, - sizeof(name)); + sizeof(name)); strlcat(name, " SPKR", sizeof(name)); snd_soc_dapm_ignore_suspend(dapm, name); } @@ -694,53 +724,45 @@ static int csra66x0_soc_probe(struct snd_soc_codec *codec) return 0; } -static int csra66x0_soc_remove(struct snd_soc_codec *codec) +static void csra66x0_soc_remove(struct snd_soc_component *component) { - snd_soc_write(codec, CSRA66X0_CHIP_STATE_CTRL_FA, STDBY_STATE); - return 0; + snd_soc_component_write(component, CSRA66X0_CHIP_STATE_CTRL_FA, + STDBY_STATE); + return; } -static int csra66x0_soc_suspend(struct snd_soc_codec *codec) +static int csra66x0_soc_suspend(struct snd_soc_component *component) { - u16 state_reg = snd_soc_read(codec, CSRA66X0_CHIP_STATE_CTRL_FA) & 0xFC; + u16 state_reg = snd_soc_component_read32(component, + CSRA66X0_CHIP_STATE_CTRL_FA) & 0xFC; - snd_soc_write(codec, CSRA66X0_CHIP_STATE_CTRL_FA, state_reg | - STDBY_STATE); + snd_soc_component_write(component, CSRA66X0_CHIP_STATE_CTRL_FA, + state_reg | STDBY_STATE); return 0; } -static int csra66x0_soc_resume(struct snd_soc_codec *codec) +static int csra66x0_soc_resume(struct snd_soc_component *component) { - u16 state_reg = snd_soc_read(codec, CSRA66X0_CHIP_STATE_CTRL_FA) & 0xFC; + u16 state_reg = snd_soc_component_read32( + component, CSRA66X0_CHIP_STATE_CTRL_FA) & 0xFC; - snd_soc_write(codec, CSRA66X0_CHIP_STATE_CTRL_FA, state_reg | - RUN_STATE); + snd_soc_component_write(component, CSRA66X0_CHIP_STATE_CTRL_FA, + state_reg | RUN_STATE); return 0; } -static struct regmap *csra66x0_get_regmap(struct device *dev) -{ - struct csra66x0_priv *csra66x0_ctrl = dev_get_drvdata(dev); - - if (!csra66x0_ctrl) - return NULL; - return csra66x0_ctrl->regmap; -} - -static struct snd_soc_codec_driver soc_codec_drv_csra66x0 = { +static const struct snd_soc_component_driver soc_codec_drv_csra66x0 = { + .name = DRV_NAME, .probe = csra66x0_soc_probe, .remove = csra66x0_soc_remove, .suspend = csra66x0_soc_suspend, .resume = csra66x0_soc_resume, - .get_regmap = csra66x0_get_regmap, - .component_driver = { - .controls = csra66x0_snd_controls, - .num_controls = ARRAY_SIZE(csra66x0_snd_controls), - .dapm_widgets = csra66x0_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(csra66x0_dapm_widgets), - .dapm_routes = csra66x0_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(csra66x0_dapm_routes), - }, + .controls = csra66x0_snd_controls, + .num_controls = ARRAY_SIZE(csra66x0_snd_controls), + .dapm_widgets = csra66x0_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(csra66x0_dapm_widgets), + .dapm_routes = csra66x0_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(csra66x0_dapm_routes), }; static struct regmap_config csra66x0_regmap_config = { @@ -758,19 +780,20 @@ static struct regmap_config csra66x0_regmap_config = { static irqreturn_t csra66x0_irq(int irq, void *data) { struct csra66x0_priv *csra66x0 = (struct csra66x0_priv *) data; - struct snd_soc_codec *codec = csra66x0->codec; + struct snd_soc_component *component = csra66x0->component; u16 val; unsigned int i, max_num_cluster_devices; - /* Treat interrupt before codec is initialized as spurious */ - if (codec == NULL) + /* Treat interrupt before component is initialized as spurious */ + if (component == NULL) return IRQ_NONE; - dev_dbg(codec->dev, "%s: csra66x0_interrupt triggered by %s\n", - __func__, codec->component.name); + dev_dbg(component->dev, "%s: csra66x0_interrupt triggered by %s\n", + __func__, component->name); /* fault indication */ - val = snd_soc_read(codec, CSRA66X0_IRQ_OUTPUT_STATUS_FA) & 0x1; + val = snd_soc_component_read32(component, CSRA66X0_IRQ_OUTPUT_STATUS_FA) + & 0x1; if (!val) return IRQ_HANDLED; @@ -780,7 +803,7 @@ static irqreturn_t csra66x0_irq(int irq, void *data) sizeof(csra_clust_dev_tbl) / sizeof(csra_clust_dev_tbl[0]); for (i = 0; i < max_num_cluster_devices; i++) { - if (i >= codec->component.card->num_aux_devs) + if (i >= component->card->num_aux_devs) break; if (csra_clust_dev_tbl[i].csra66x0_ptr == NULL) continue; @@ -790,7 +813,7 @@ static irqreturn_t csra66x0_irq(int irq, void *data) } /* reset all master codecs */ for (i = 0; i < max_num_cluster_devices; i++) { - if (i >= codec->component.card->num_aux_devs) + if (i >= component->card->num_aux_devs) break; if (csra_clust_dev_tbl[i].csra66x0_ptr == NULL) continue; @@ -800,7 +823,7 @@ static irqreturn_t csra66x0_irq(int irq, void *data) } /* recover all codecs */ for (i = 0; i < max_num_cluster_devices; i++) { - if (i >= codec->component.card->num_aux_devs) + if (i >= component->card->num_aux_devs) break; if (csra_clust_dev_tbl[i].csra66x0_ptr == NULL) continue; @@ -958,7 +981,7 @@ static int csra66x0_i2c_probe(struct i2c_client *client_i2c, #endif /* CONFIG_DEBUG_FS */ /* register codec */ - ret = snd_soc_register_codec(&client_i2c->dev, + ret = snd_soc_register_component(&client_i2c->dev, &soc_codec_drv_csra66x0, NULL, 0); if (ret != 0) { dev_err(&client_i2c->dev, "%s %d: Failed to register codec: %d\n", @@ -985,7 +1008,7 @@ static int csra66x0_i2c_remove(struct i2c_client *i2c_client) debugfs_remove_recursive(csra66x0->debugfs_dir); #endif } - snd_soc_unregister_codec(&i2c_client->dev); + snd_soc_unregister_component(&i2c_client->dev); return 0; } diff --git a/asoc/codecs/ep92/ep92.c b/asoc/codecs/ep92/ep92.c index cdcd7ab98fd0..81ff656b9273 100644 --- a/asoc/codecs/ep92/ep92.c +++ b/asoc/codecs/ep92/ep92.c @@ -21,6 +21,8 @@ #include #include "ep92.h" +#define DRV_NAME "ep92_codec" + #define EP92_POLL_INTERVAL_OFF_MSEC 200 #define EP92_POLL_INTERVAL_ON_MSEC 20 #define EP92_SYSFS_ENTRY_MAX_LEN 64 @@ -91,7 +93,7 @@ static bool ep92_readable_registers(struct device *dev, unsigned int reg) /* codec private data */ struct ep92_pdata { struct regmap *regmap; - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct timer_list timer; struct work_struct read_status_worker; int irq; @@ -169,7 +171,7 @@ static ssize_t debugfs_codec_write_op(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) { struct ep92_pdata *ep92 = (struct ep92_pdata *) filp->private_data; - struct snd_soc_codec *codec = ep92->codec; + struct snd_soc_component *component = ep92->component; char lbuf[32]; int rc; u32 param[2]; @@ -185,45 +187,45 @@ static ssize_t debugfs_codec_write_op(struct file *filp, rc = debugfs_get_parameters(lbuf, param, 2); if ((param[0] < EP92_ISP_MODE_ENTER_ISP) || (param[0] > EP92_GENERAL_CONTROL_4)) { - dev_err(codec->dev, "%s: reg address 0x%02X out of range\n", + dev_err(component->dev, "%s: reg address 0x%02X out of range\n", __func__, param[0]); return -EINVAL; } if ((param[1] < 0) || (param[1] > 255)) { - dev_err(codec->dev, "%s: reg data 0x%02X out of range\n", + dev_err(component->dev, "%s: reg data 0x%02X out of range\n", __func__, param[1]); return -EINVAL; } if (rc == 0) { rc = cnt; - dev_info(codec->dev, "%s: reg[0x%02X]=0x%02X\n", + dev_info(component->dev, "%s: reg[0x%02X]=0x%02X\n", __func__, param[0], param[1]); - snd_soc_write(codec, param[0], param[1]); + snd_soc_component_write(component, param[0], param[1]); } else { - dev_err(codec->dev, "%s: write to register addr=0x%02X failed\n", + dev_err(component->dev, "%s: write to register addr=0x%02X failed\n", __func__, param[0]); } return rc; } -static ssize_t debugfs_ep92_reg_show(struct snd_soc_codec *codec, +static ssize_t debugfs_ep92_reg_show(struct snd_soc_component *component, char __user *ubuf, size_t count, loff_t *ppos) { int i, reg_val, len; ssize_t total = 0; char tmp_buf[20]; - if (!ubuf || !ppos || !codec || *ppos < 0) + if (!ubuf || !ppos || !component || *ppos < 0) return -EINVAL; for (i = (int) *ppos / 11; i <= EP92_MAX_REGISTER_ADDR; i++) { - reg_val = snd_soc_read(codec, i); + reg_val = snd_soc_component_read32(component, i); len = snprintf(tmp_buf, 20, "0x%02X: 0x%02X\n", i, (reg_val & 0xFF)); if ((total + len) > count) break; if (copy_to_user((ubuf + total), tmp_buf, len)) { - dev_err(codec->dev, "%s: fail to copy reg dump\n", + dev_err(component->dev, "%s: fail to copy reg dump\n", __func__); total = -EFAULT; goto copy_err; @@ -240,12 +242,12 @@ static ssize_t debugfs_codec_read_op(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { struct ep92_pdata *ep92 = (struct ep92_pdata *) filp->private_data; - struct snd_soc_codec *codec = ep92->codec; + struct snd_soc_component *component = ep92->component; ssize_t ret_cnt; if (!filp || !ppos || !ubuf || *ppos < 0) return -EINVAL; - ret_cnt = debugfs_ep92_reg_show(codec, ubuf, cnt, ppos); + ret_cnt = debugfs_ep92_reg_show(component, ubuf, cnt, ppos); return ret_cnt; } @@ -263,7 +265,8 @@ static int ep92_send_uevent(struct ep92_pdata *ep92, char *event) if (!event || !ep92) return -EINVAL; - return kobject_uevent_env(&ep92->codec->dev->kobj, KOBJ_CHANGE, env); + return kobject_uevent_env(&ep92->component->dev->kobj, + KOBJ_CHANGE, env); } static int ep92_startup(struct snd_pcm_substream *substream, @@ -320,14 +323,15 @@ static struct snd_soc_dai_driver ep92_dai[] = { }, }; -static void ep92_read_general_control(struct snd_soc_codec *codec, +static void ep92_read_general_control(struct snd_soc_component *component, struct ep92_pdata *ep92) { u8 old, change; int val; old = ep92->gi.tx_info; - ep92->gi.tx_info = snd_soc_read(codec, EP92_BI_GENERAL_INFO_0); + ep92->gi.tx_info = snd_soc_component_read32(component, + EP92_BI_GENERAL_INFO_0); if (ep92->gi.tx_info == 0xff) { pr_debug("ep92 EP92_BI_GENERAL_INFO_0 read 0xff\n"); ep92->gi.tx_info = old; @@ -358,7 +362,8 @@ static void ep92_read_general_control(struct snd_soc_codec *codec, } old = ep92->gi.video_latency; - ep92->gi.video_latency = snd_soc_read(codec, EP92_BI_GENERAL_INFO_4); + ep92->gi.video_latency = snd_soc_component_read32(component, + EP92_BI_GENERAL_INFO_4); if (ep92->gi.video_latency == 0xff) { pr_debug("ep92 EP92_BI_GENERAL_INFO_4 read 0xff\n"); ep92->gi.video_latency = old; @@ -373,7 +378,8 @@ static void ep92_read_general_control(struct snd_soc_codec *codec, } old = ep92->gc.ctl; - ep92->gc.ctl = snd_soc_read(codec, EP92_GENERAL_CONTROL_0); + ep92->gc.ctl = snd_soc_component_read32(component, + EP92_GENERAL_CONTROL_0); if (ep92->gc.ctl == 0xff) { pr_debug("ep92 EP92_GENERAL_CONTROL_0 read 0xff\n"); ep92->gc.ctl = old; @@ -416,7 +422,8 @@ static void ep92_read_general_control(struct snd_soc_codec *codec, } old = ep92->gc.rx_sel; - ep92->gc.rx_sel = snd_soc_read(codec, EP92_GENERAL_CONTROL_1); + ep92->gc.rx_sel = snd_soc_component_read32(component, + EP92_GENERAL_CONTROL_1); if (ep92->gc.rx_sel == 0xff) { pr_debug("ep92 EP92_GENERAL_CONTROL_1 read 0xff\n"); ep92->gc.rx_sel = old; @@ -429,7 +436,8 @@ static void ep92_read_general_control(struct snd_soc_codec *codec, } old = ep92->gc.cec_volume; - ep92->gc.cec_volume = snd_soc_read(codec, EP92_GENERAL_CONTROL_3); + ep92->gc.cec_volume = snd_soc_component_read32(component, + EP92_GENERAL_CONTROL_3); if (ep92->gc.cec_volume == 0xff) { pr_debug("ep92 EP92_GENERAL_CONTROL_3 read 0xff\n"); ep92->gc.cec_volume = old; @@ -442,7 +450,8 @@ static void ep92_read_general_control(struct snd_soc_codec *codec, } old = ep92->gc.link; - ep92->gc.link = snd_soc_read(codec, EP92_GENERAL_CONTROL_4); + ep92->gc.link = snd_soc_component_read32(component, + EP92_GENERAL_CONTROL_4); if (ep92->gc.link == 0xff) { pr_debug("ep92 EP92_GENERAL_CONTROL_4 read 0xff\n"); ep92->gc.link = old; @@ -524,7 +533,7 @@ static void ep92_read_general_control(struct snd_soc_codec *codec, } } -static void ep92_read_audio_info(struct snd_soc_codec *codec, +static void ep92_read_audio_info(struct snd_soc_component *component, struct ep92_pdata *ep92) { u8 old, change; @@ -532,7 +541,7 @@ static void ep92_read_audio_info(struct snd_soc_codec *codec, bool send_uevent = false; old = ep92->ai.system_status_0; - ep92->ai.system_status_0 = snd_soc_read(codec, + ep92->ai.system_status_0 = snd_soc_component_read32(component, EP92_AUDIO_INFO_SYSTEM_STATUS_0); if (ep92->ai.system_status_0 == 0xff) { pr_debug("ep92 EP92_AUDIO_INFO_SYSTEM_STATUS_0 read 0xff\n"); @@ -558,7 +567,7 @@ static void ep92_read_audio_info(struct snd_soc_codec *codec, } old = ep92->ai.audio_status; - ep92->ai.audio_status = snd_soc_read(codec, + ep92->ai.audio_status = snd_soc_component_read32(component, EP92_AUDIO_INFO_AUDIO_STATUS); if (ep92->ai.audio_status == 0xff) { pr_debug("ep92 EP92_AUDIO_INFO_AUDIO_STATUS read 0xff\n"); @@ -575,7 +584,7 @@ static void ep92_read_audio_info(struct snd_soc_codec *codec, new_mode = ep92->old_mode; if (ep92->ai.audio_status & EP92_AI_STD_ADO_MASK) { old = ep92->ai.cs[0]; - ep92->ai.cs[0] = snd_soc_read(codec, + ep92->ai.cs[0] = snd_soc_component_read32(component, EP92_AUDIO_INFO_CHANNEL_STATUS_0); if (ep92->ai.cs[0] == 0xff) { pr_debug("ep92 EP92_AUDIO_INFO_CHANNEL_STATUS_0 read 0xff\n"); @@ -595,7 +604,8 @@ static void ep92_read_audio_info(struct snd_soc_codec *codec, ep92->old_mode = new_mode; old = ep92->ai.cc; - ep92->ai.cc = snd_soc_read(codec, EP92_AUDIO_INFO_ADO_INFO_FRAME_1); + ep92->ai.cc = snd_soc_component_read32(component, + EP92_AUDIO_INFO_ADO_INFO_FRAME_1); if (ep92->ai.cc == 0xff) { pr_debug("ep92 EP92_AUDIO_INFO_ADO_INFO_FRAME_1 read 0xff\n"); ep92->ai.cc = old; @@ -610,7 +620,8 @@ static void ep92_read_audio_info(struct snd_soc_codec *codec, } old = ep92->ai.ca; - ep92->ai.ca = snd_soc_read(codec, EP92_AUDIO_INFO_ADO_INFO_FRAME_4); + ep92->ai.ca = snd_soc_component_read32(component, + EP92_AUDIO_INFO_ADO_INFO_FRAME_4); if (ep92->ai.ca == 0xff) { pr_debug("ep92 EP92_AUDIO_INFO_ADO_INFO_FRAME_4 read 0xff\n"); ep92->ai.ca = old; @@ -626,42 +637,33 @@ static void ep92_read_audio_info(struct snd_soc_codec *codec, ep92_send_uevent(ep92, "EP92EVT_AUDIO=MEDIA_CONFIG_CHANGE"); } -static void ep92_init(struct snd_soc_codec *codec, struct ep92_pdata *ep92) +static void ep92_init(struct snd_soc_component *component, + struct ep92_pdata *ep92) { /* update the format information in mixer controls */ - ep92_read_general_control(codec, ep92); - ep92_read_audio_info(codec, ep92); + ep92_read_general_control(component, ep92); + ep92_read_audio_info(component, ep92); } -static int ep92_probe(struct snd_soc_codec *codec) +static int ep92_probe(struct snd_soc_component *component) { - struct ep92_pdata *ep92 = snd_soc_codec_get_drvdata(codec); + struct ep92_pdata *ep92 = snd_soc_component_get_drvdata(component); - ep92->codec = codec; - ep92_init(codec, ep92); + ep92->component = component; + ep92_init(component, ep92); return 0; } -static int ep92_remove(struct snd_soc_codec *codec) +static void ep92_remove(struct snd_soc_component *component) { - return 0; -} - -static struct regmap *ep92_get_regmap(struct device *dev) -{ - struct ep92_pdata *ep92_ctrl = dev_get_drvdata(dev); - - if (!ep92_ctrl) - return NULL; - - return ep92_ctrl->regmap; + return; } -static struct snd_soc_codec_driver soc_codec_drv_ep92 = { +static const struct snd_soc_component_driver soc_codec_drv_ep92 = { + .name = DRV_NAME, .probe = ep92_probe, .remove = ep92_remove, - .get_regmap = ep92_get_regmap, }; static struct regmap_config ep92_regmap_config = { @@ -680,18 +682,19 @@ void ep92_read_status(struct work_struct *work) { struct ep92_pdata *ep92 = container_of(work, struct ep92_pdata, read_status_worker); - struct snd_soc_codec *codec = ep92->codec; + struct snd_soc_component *component = ep92->component; u8 val; /* No polling before codec is initialized */ - if (codec == NULL) + if (component == NULL) return; /* check ADO_CHF that is set when audio format has changed */ - val = snd_soc_read(codec, EP92_BI_GENERAL_INFO_1); + val = snd_soc_component_read32(component, EP92_BI_GENERAL_INFO_1); if (val == 0xff) { /* workaround for Nak'ed first read */ - val = snd_soc_read(codec, EP92_BI_GENERAL_INFO_1); + val = snd_soc_component_read32(component, + EP92_BI_GENERAL_INFO_1); if (val == 0xff) return; /* assume device not present */ } @@ -703,22 +706,22 @@ void ep92_read_status(struct work_struct *work) pr_debug("ep92 CEC change trigger.\n"); /* check for general control changes */ - ep92_read_general_control(codec, ep92); + ep92_read_general_control(component, ep92); /* update the format information in mixer controls */ - ep92_read_audio_info(codec, ep92); + ep92_read_audio_info(component, ep92); } static irqreturn_t ep92_irq(int irq, void *data) { struct ep92_pdata *ep92 = data; - struct snd_soc_codec *codec = ep92->codec; + struct snd_soc_component *component = ep92->component; /* Treat interrupt before codec is initialized as spurious */ - if (codec == NULL) + if (component == NULL) return IRQ_NONE; - dev_dbg(codec->dev, "ep92_interrupt\n"); + dev_dbg(component->dev, "ep92_interrupt\n"); schedule_work(&ep92->read_status_worker); @@ -1038,10 +1041,11 @@ static ssize_t ep92_sysfs_wta_arc_disable(struct device *dev, goto end; } - reg = snd_soc_read(ep92->codec, EP92_GENERAL_CONTROL_2); + reg = snd_soc_component_read32(ep92->component, + EP92_GENERAL_CONTROL_2); reg &= ~EP92_GC_ARC_DIS_MASK; reg |= ((val << EP92_GC_ARC_DIS_SHIFT) & EP92_GC_ARC_DIS_MASK); - snd_soc_write(ep92->codec, EP92_GENERAL_CONTROL_2, reg); + snd_soc_component_write(ep92->component, EP92_GENERAL_CONTROL_2, reg); ep92->gc.ctl2 &= ~EP92_GC_ARC_DIS_MASK; ep92->gc.ctl2 |= (val << EP92_GC_ARC_DIS_SHIFT) & EP92_GC_ARC_DIS_MASK; @@ -1092,10 +1096,10 @@ static ssize_t ep92_sysfs_wta_power(struct device *dev, goto end; } - reg = snd_soc_read(ep92->codec, EP92_GENERAL_CONTROL_0); + reg = snd_soc_component_read32(ep92->component, EP92_GENERAL_CONTROL_0); reg &= ~EP92_GC_POWER_MASK; reg |= (val << EP92_GC_POWER_SHIFT) & EP92_GC_POWER_MASK; - snd_soc_write(ep92->codec, EP92_GENERAL_CONTROL_0, reg); + snd_soc_component_write(ep92->component, EP92_GENERAL_CONTROL_0, reg); ep92->gc.ctl &= ~EP92_GC_POWER_MASK; ep92->gc.ctl |= (val << EP92_GC_POWER_SHIFT) & EP92_GC_POWER_MASK; @@ -1146,10 +1150,11 @@ static ssize_t ep92_sysfs_wta_audio_path(struct device *dev, goto end; } - reg = snd_soc_read(ep92->codec, EP92_GENERAL_CONTROL_0); + reg = snd_soc_component_read32(ep92->component, + EP92_GENERAL_CONTROL_0); reg &= ~EP92_GC_AUDIO_PATH_MASK; reg |= (val << EP92_GC_AUDIO_PATH_SHIFT) & EP92_GC_AUDIO_PATH_MASK; - snd_soc_write(ep92->codec, EP92_GENERAL_CONTROL_0, reg); + snd_soc_component_write(ep92->component, EP92_GENERAL_CONTROL_0, reg); ep92->gc.ctl &= ~EP92_GC_AUDIO_PATH_MASK; ep92->gc.ctl |= (val << EP92_GC_AUDIO_PATH_SHIFT) & EP92_GC_AUDIO_PATH_MASK; @@ -1201,10 +1206,11 @@ static ssize_t ep92_sysfs_wta_src_sel(struct device *dev, goto end; } - reg = snd_soc_read(ep92->codec, EP92_GENERAL_CONTROL_1); + reg = snd_soc_component_read32(ep92->component, + EP92_GENERAL_CONTROL_1); reg &= ~EP92_GC_RX_SEL_MASK; reg |= (val << EP92_GC_RX_SEL_SHIFT) & EP92_GC_RX_SEL_MASK; - snd_soc_write(ep92->codec, EP92_GENERAL_CONTROL_1, reg); + snd_soc_component_write(ep92->component, EP92_GENERAL_CONTROL_1, reg); ep92->gc.rx_sel &= ~EP92_GC_RX_SEL_MASK; ep92->gc.rx_sel |= (val << EP92_GC_RX_SEL_SHIFT) & EP92_GC_RX_SEL_MASK; @@ -1255,10 +1261,10 @@ static ssize_t ep92_sysfs_wta_arc_enable(struct device *dev, goto end; } - reg = snd_soc_read(ep92->codec, EP92_GENERAL_CONTROL_0); + reg = snd_soc_component_read32(ep92->component, EP92_GENERAL_CONTROL_0); reg &= ~EP92_GC_AUDIO_PATH_MASK; reg |= (val << EP92_GC_AUDIO_PATH_SHIFT) & EP92_GC_AUDIO_PATH_MASK; - snd_soc_write(ep92->codec, EP92_GENERAL_CONTROL_0, reg); + snd_soc_component_write(ep92->component, EP92_GENERAL_CONTROL_0, reg); ep92->gc.ctl &= ~EP92_GC_AUDIO_PATH_MASK; ep92->gc.ctl |= (val << EP92_GC_AUDIO_PATH_SHIFT) & EP92_GC_AUDIO_PATH_MASK; @@ -1310,10 +1316,10 @@ static ssize_t ep92_sysfs_wta_cec_mute(struct device *dev, goto end; } - reg = snd_soc_read(ep92->codec, EP92_GENERAL_CONTROL_0); + reg = snd_soc_component_read32(ep92->component, EP92_GENERAL_CONTROL_0); reg &= ~EP92_GC_CEC_MUTE_MASK; reg |= (val << EP92_GC_CEC_MUTE_SHIFT) & EP92_GC_CEC_MUTE_MASK; - snd_soc_write(ep92->codec, EP92_GENERAL_CONTROL_0, reg); + snd_soc_component_write(ep92->component, EP92_GENERAL_CONTROL_0, reg); ep92->gc.ctl &= ~EP92_GC_CEC_MUTE_MASK; ep92->gc.ctl |= (val << EP92_GC_CEC_MUTE_SHIFT) & EP92_GC_CEC_MUTE_MASK; @@ -1367,7 +1373,7 @@ static ssize_t ep92_sysfs_wta_cec_volume(struct device *dev, } reg = val & EP92_GC_CEC_VOLUME_MASK; - snd_soc_write(ep92->codec, EP92_GENERAL_CONTROL_3, reg); + snd_soc_component_write(ep92->component, EP92_GENERAL_CONTROL_3, reg); ep92->gc.cec_volume = val & EP92_GC_CEC_VOLUME_MASK; rc = strnlen(buf, EP92_SYSFS_ENTRY_MAX_LEN); @@ -1524,7 +1530,7 @@ static int ep92_i2c_probe(struct i2c_client *client, #endif /* CONFIG_DEBUG_FS */ /* register codec */ - ret = snd_soc_register_codec(&client->dev, &soc_codec_drv_ep92, + ret = snd_soc_register_component(&client->dev, &soc_codec_drv_ep92, ep92_dai, ARRAY_SIZE(ep92_dai)); if (ret) { dev_err(&client->dev, @@ -1542,7 +1548,7 @@ static int ep92_i2c_probe(struct i2c_client *client, return 0; err_sysfs: - snd_soc_unregister_codec(&client->dev); + snd_soc_unregister_component(&client->dev); err_reg: if (ep92->irq == 0) del_timer(&ep92->timer); @@ -1563,7 +1569,7 @@ static int ep92_i2c_remove(struct i2c_client *client) debugfs_remove_recursive(ep92->debugfs_dir); #endif } - snd_soc_unregister_codec(&client->dev); + snd_soc_unregister_component(&client->dev); ep92_sysfs_remove(client, ep92); diff --git a/asoc/codecs/msm_hdmi_codec_rx.c b/asoc/codecs/msm_hdmi_codec_rx.c index 3e4c2d5ca6ce..95bb26d027e3 100644 --- a/asoc/codecs/msm_hdmi_codec_rx.c +++ b/asoc/codecs/msm_hdmi_codec_rx.c @@ -11,6 +11,8 @@ #include #include +#define DRV_NAME "HDMI_codec" + #define MSM_EXT_DISP_PCM_RATES SNDRV_PCM_RATE_48000 #define AUD_EXT_DISP_ACK_DISCONNECT (AUDIO_ACK_CONNECT ^ AUDIO_ACK_CONNECT) #define AUD_EXT_DISP_ACK_CONNECT (AUDIO_ACK_CONNECT) @@ -64,29 +66,30 @@ struct msm_ext_disp_audio_codec_rx_data { static int msm_ext_disp_edid_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct msm_ext_disp_audio_codec_rx_data *codec_data; struct msm_ext_disp_audio_edid_blk edid_blk; int rc = 0; struct msm_ext_disp_codec_id codec_info; int dai_id = kcontrol->private_value; - codec_data = snd_soc_codec_get_drvdata(codec); + codec_data = snd_soc_component_get_drvdata(component); if (!codec_data) { - dev_err(codec->dev, "%s: codec_data is NULL\n", __func__); + dev_err(component->dev, "%s: codec_data is NULL\n", __func__); return -EINVAL; } if (!codec_data->ext_disp_ops.get_audio_edid_blk) { - dev_dbg(codec->dev, "%s: get_audio_edid_blk() is NULL\n", + dev_dbg(component->dev, "%s: get_audio_edid_blk() is NULL\n", __func__); uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; uinfo->count = 0; return 0; } - dev_dbg(codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__, + dev_dbg(component->dev, "%s: DP ctl id %d Stream id %d\n", __func__, codec_data->ctl[dai_id], codec_data->stream[dai_id]); mutex_lock(&codec_data->dp_ops_lock); @@ -100,28 +103,29 @@ static int msm_ext_disp_edid_ctl_info(struct snd_kcontrol *kcontrol, edid_blk.spk_alloc_data_blk_size; } - dev_dbg(codec->dev, "%s: count: %d\n", __func__, uinfo->count); + dev_dbg(component->dev, "%s: count: %d\n", __func__, uinfo->count); return rc; } static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct msm_ext_disp_audio_codec_rx_data *codec_data; struct msm_ext_disp_audio_edid_blk edid_blk; struct msm_ext_disp_codec_id codec_info; int rc = 0; int dai_id = kcontrol->private_value; - codec_data = snd_soc_codec_get_drvdata(codec); + codec_data = snd_soc_component_get_drvdata(component); if (!codec_data || !codec_data->ext_disp_ops.get_audio_edid_blk) { - dev_err(codec->dev, "%s: codec_data or get_audio_edid_blk() is NULL\n", + dev_err(component->dev, "%s: codec_data or get_audio_edid_blk() is NULL\n", __func__); return -EINVAL; } - dev_dbg(codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__, + dev_dbg(component->dev, "%s: DP ctl id %d Stream id %d\n", __func__, codec_data->ctl[dai_id], codec_data->stream[dai_id]); mutex_lock(&codec_data->dp_ops_lock); @@ -133,7 +137,7 @@ static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol, if (sizeof(ucontrol->value.bytes.data) < (edid_blk.audio_data_blk_size + edid_blk.spk_alloc_data_blk_size)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Not enough memory to copy EDID data\n", __func__); return -ENOMEM; @@ -147,7 +151,7 @@ static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol, edid_blk.spk_alloc_data_blk, edid_blk.spk_alloc_data_blk_size); - dev_dbg(codec->dev, "%s: data_blk_size:%d, spk_alloc_data_blk_size:%d\n", + dev_dbg(component->dev, "%s: data_blk_size:%d, spk_alloc_data_blk_size:%d\n", __func__, edid_blk.audio_data_blk_size, edid_blk.spk_alloc_data_blk_size); } @@ -158,7 +162,8 @@ static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol, static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct msm_ext_disp_audio_codec_rx_data *codec_data; enum msm_ext_disp_cable_state cable_state; enum msm_ext_disp_type disp_type; @@ -166,16 +171,16 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, int rc = 0; int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l; - codec_data = snd_soc_codec_get_drvdata(codec); + codec_data = snd_soc_component_get_drvdata(component); if (!codec_data || !codec_data->ext_disp_ops.get_audio_edid_blk || !codec_data->ext_disp_ops.get_intf_id) { - dev_err(codec->dev, "%s: codec_data, get_audio_edid_blk() or get_intf_id is NULL\n", + dev_err(component->dev, "%s: codec_data, get_audio_edid_blk() or get_intf_id is NULL\n", __func__); return -EINVAL; } - dev_dbg(codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__, + dev_dbg(component->dev, "%s: DP ctl id %d Stream id %d\n", __func__, codec_data->ctl[dai_id], codec_data->stream[dai_id]); mutex_lock(&codec_data->dp_ops_lock); @@ -183,7 +188,7 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, cable_state = codec_data->ext_disp_ops.cable_status( codec_data->ext_disp_core_pdev, 1); if (cable_state < 0) { - dev_err(codec->dev, "%s: Error retrieving cable state from ext_disp, err:%d\n", + dev_err(component->dev, "%s: Error retrieving cable state from ext_disp, err:%d\n", __func__, cable_state); rc = cable_state; goto cable_err; @@ -191,7 +196,7 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, codec_data->cable_status = cable_state; if (cable_state == EXT_DISPLAY_CABLE_DISCONNECT) { - dev_err(codec->dev, "%s: Display cable disconnected\n", + dev_err(component->dev, "%s: Display cable disconnected\n", __func__); ucontrol->value.integer.value[0] = 0; rc = 0; @@ -213,14 +218,14 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, break; default: rc = -EINVAL; - dev_err(codec->dev, "%s: Invalid disp_type:%d\n", + dev_err(component->dev, "%s: Invalid disp_type:%d\n", __func__, disp_type); goto done; } - dev_dbg(codec->dev, "%s: Display type: %d\n", + dev_dbg(component->dev, "%s: Display type: %d\n", __func__, disp_type); } else { - dev_err(codec->dev, "%s: Error retrieving disp_type from ext_disp, err:%d\n", + dev_err(component->dev, "%s: Error retrieving disp_type from ext_disp, err:%d\n", __func__, disp_type); rc = disp_type; } @@ -235,24 +240,25 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct msm_ext_disp_audio_codec_rx_data *codec_data; u32 ack_state = 0; struct msm_ext_disp_codec_id codec_info; int rc = 0; int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l; - codec_data = snd_soc_codec_get_drvdata(codec); + codec_data = snd_soc_component_get_drvdata(component); if (!codec_data || !codec_data->ext_disp_ops.acknowledge) { - dev_err(codec->dev, + dev_err(component->dev, "%s: codec_data or ops acknowledge() is NULL\n", __func__); rc = -EINVAL; goto done; } - dev_dbg(codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__, + dev_dbg(component->dev, "%s: DP ctl id %d Stream id %d\n", __func__, codec_data->ctl[dai_id], codec_data->stream[dai_id]); switch (ucontrol->value.enumerated.item[0]) { @@ -267,12 +273,12 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, break; default: rc = -EINVAL; - dev_err(codec->dev, + dev_err(component->dev, "%s: invalid value %d for mixer ctl\n", __func__, ucontrol->value.enumerated.item[0]); goto done; } - dev_dbg(codec->dev, "%s: control %d, ack set value 0x%x\n", + dev_dbg(component->dev, "%s: control %d, ack set value 0x%x\n", __func__, ucontrol->value.enumerated.item[0], ack_state); mutex_lock(&codec_data->dp_ops_lock); @@ -281,7 +287,7 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, codec_data->ext_disp_core_pdev, ack_state); mutex_unlock(&codec_data->dp_ops_lock); if (rc < 0) { - dev_err(codec->dev, "%s: error from acknowledge(), err:%d\n", + dev_err(component->dev, "%s: error from acknowledge(), err:%d\n", __func__, rc); } @@ -292,14 +298,15 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, static int msm_ext_disp_audio_device_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); struct msm_ext_disp_audio_codec_rx_data *codec_data; int rc = 0; int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l; - codec_data = snd_soc_codec_get_drvdata(codec); + codec_data = snd_soc_component_get_drvdata(component); if (!codec_data) { - dev_err(codec->dev, + dev_err(component->dev, "%s: codec_data or ops acknowledge() is NULL\n", __func__); rc = -EINVAL; @@ -371,7 +378,7 @@ static int msm_ext_disp_audio_codec_rx_dai_startup( int ret = 0; struct msm_ext_disp_codec_id codec_info; struct msm_ext_disp_audio_codec_rx_data *codec_data = - dev_get_drvdata(dai->codec->dev); + dev_get_drvdata(dai->component->dev); if (!codec_data || !codec_data->ext_disp_ops.cable_status) { dev_err(dai->dev, "%s() codec_data or cable_status is null\n", @@ -379,7 +386,8 @@ static int msm_ext_disp_audio_codec_rx_dai_startup( return -EINVAL; } - dev_dbg(dai->codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__, + dev_dbg(dai->component->dev, "%s: DP ctl id %d Stream id %d\n", + __func__, codec_data->ctl[dai->id], codec_data->stream[dai->id]); mutex_lock(&codec_data->dp_ops_lock); @@ -417,7 +425,7 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params( struct msm_ext_disp_audio_setup_params audio_setup_params = {0}; struct msm_ext_disp_audio_codec_rx_data *codec_data = - dev_get_drvdata(dai->codec->dev); + dev_get_drvdata(dai->component->dev); if (!codec_data || !codec_data->ext_disp_ops.audio_info_setup) { dev_err(dai->dev, "%s: codec_data or audio_info_setup is null\n", @@ -425,7 +433,8 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params( return -EINVAL; } - dev_dbg(dai->codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__, + dev_dbg(dai->component->dev, "%s: DP ctl id %d Stream id %d\n", + __func__, codec_data->ctl[dai->id], codec_data->stream[dai->id]); if (codec_data->cable_status < 0) { @@ -507,7 +516,7 @@ static void msm_ext_disp_audio_codec_rx_dai_shutdown( struct msm_ext_disp_codec_id codec_info; struct msm_ext_disp_audio_codec_rx_data *codec_data = - dev_get_drvdata(dai->codec->dev); + dev_get_drvdata(dai->component->dev); if (!codec_data || !codec_data->ext_disp_ops.teardown_done || !codec_data->ext_disp_ops.cable_status) { @@ -516,7 +525,8 @@ static void msm_ext_disp_audio_codec_rx_dai_shutdown( return; } - dev_dbg(dai->codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__, + dev_dbg(dai->component->dev, "%s: DP ctl id %d Stream id %d\n", + __func__, codec_data->ctl[dai->id], codec_data->stream[dai->id]); mutex_lock(&codec_data->dp_ops_lock); @@ -534,7 +544,8 @@ static void msm_ext_disp_audio_codec_rx_dai_shutdown( mutex_unlock(&codec_data->dp_ops_lock); } -static int msm_ext_disp_audio_codec_rx_probe(struct snd_soc_codec *codec) +static int msm_ext_disp_audio_codec_rx_probe( + struct snd_soc_component *component) { struct msm_ext_disp_audio_codec_rx_data *codec_data; struct device_node *of_node_parent = NULL; @@ -543,14 +554,14 @@ static int msm_ext_disp_audio_codec_rx_probe(struct snd_soc_codec *codec) GFP_KERNEL); if (!codec_data) { - dev_err(codec->dev, "%s(): fail to allocate dai data\n", + dev_err(component->dev, "%s(): fail to allocate dai data\n", __func__); return -ENOMEM; } - of_node_parent = of_get_parent(codec->dev->of_node); + of_node_parent = of_get_parent(component->dev->of_node); if (!of_node_parent) { - dev_err(codec->dev, "%s(): Parent device tree node not found\n", + dev_err(component->dev, "%s(): Parent device tree node not found\n", __func__); kfree(codec_data); return -ENODEV; @@ -558,37 +569,39 @@ static int msm_ext_disp_audio_codec_rx_probe(struct snd_soc_codec *codec) codec_data->ext_disp_core_pdev = of_find_device_by_node(of_node_parent); if (!codec_data->ext_disp_core_pdev) { - dev_err(codec->dev, "%s(): can't get parent pdev\n", __func__); + dev_err(component->dev, "%s(): can't get parent pdev\n", + __func__); kfree(codec_data); return -ENODEV; } if (msm_ext_disp_register_audio_codec(codec_data->ext_disp_core_pdev, &codec_data->ext_disp_ops)) { - dev_err(codec->dev, "%s(): can't register with ext disp core", + dev_err(component->dev, "%s(): can't register with ext disp core", __func__); kfree(codec_data); return -ENODEV; } mutex_init(&codec_data->dp_ops_lock); - dev_set_drvdata(codec->dev, codec_data); + dev_set_drvdata(component->dev, codec_data); - dev_dbg(codec->dev, "%s(): registered %s with ext disp core\n", - __func__, codec->component.name); + dev_dbg(component->dev, "%s(): registered %s with ext disp core\n", + __func__, component->name); return 0; } -static int msm_ext_disp_audio_codec_rx_remove(struct snd_soc_codec *codec) +static void msm_ext_disp_audio_codec_rx_remove( + struct snd_soc_component *component) { struct msm_ext_disp_audio_codec_rx_data *codec_data; - codec_data = dev_get_drvdata(codec->dev); + codec_data = dev_get_drvdata(component->dev); mutex_destroy(&codec_data->dp_ops_lock); kfree(codec_data); - return 0; + return; } static struct snd_soc_dai_ops msm_ext_disp_audio_codec_rx_dai_ops = { @@ -648,13 +661,12 @@ static struct snd_soc_dai_driver msm_ext_disp_audio_codec_rx_dais[] = { }, }; -static struct snd_soc_codec_driver msm_ext_disp_audio_codec_rx_soc_driver = { +static const struct snd_soc_component_driver msm_ext_disp_codec_rx_driver = { + .name = DRV_NAME, .probe = msm_ext_disp_audio_codec_rx_probe, .remove = msm_ext_disp_audio_codec_rx_remove, - .component_driver = { - .controls = msm_ext_disp_codec_rx_controls, - .num_controls = ARRAY_SIZE(msm_ext_disp_codec_rx_controls), - }, + .controls = msm_ext_disp_codec_rx_controls, + .num_controls = ARRAY_SIZE(msm_ext_disp_codec_rx_controls), }; static int msm_ext_disp_audio_codec_rx_plat_probe( @@ -663,8 +675,8 @@ static int msm_ext_disp_audio_codec_rx_plat_probe( dev_dbg(&pdev->dev, "%s(): dev name %s\n", __func__, dev_name(&pdev->dev)); - return snd_soc_register_codec(&pdev->dev, - &msm_ext_disp_audio_codec_rx_soc_driver, + return snd_soc_register_component(&pdev->dev, + &msm_ext_disp_codec_rx_driver, msm_ext_disp_audio_codec_rx_dais, ARRAY_SIZE(msm_ext_disp_audio_codec_rx_dais)); } @@ -672,7 +684,7 @@ static int msm_ext_disp_audio_codec_rx_plat_probe( static int msm_ext_disp_audio_codec_rx_plat_remove( struct platform_device *pdev) { - snd_soc_unregister_codec(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } static const struct of_device_id msm_ext_disp_audio_codec_rx_dt_match[] = { diff --git a/asoc/codecs/msm_stub.c b/asoc/codecs/msm_stub.c index 5bfaa495261b..a27111aeac96 100644 --- a/asoc/codecs/msm_stub.c +++ b/asoc/codecs/msm_stub.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2011-2014, 2017 The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2017-2018 The Linux Foundation. All rights reserved. */ #include @@ -10,6 +10,8 @@ #include #include +#define DRV_NAME "msm-stub-codec" + /* A dummy driver useful only to advertise hardware parameters */ static struct snd_soc_dai_driver msm_stub_dais[] = { { @@ -35,19 +37,21 @@ static struct snd_soc_dai_driver msm_stub_dais[] = { }, }; -static struct snd_soc_codec_driver soc_msm_stub = {}; +static const struct snd_soc_component_driver soc_msm_stub = { + .name = DRV_NAME, +}; static int msm_stub_dev_probe(struct platform_device *pdev) { dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev)); - return snd_soc_register_codec(&pdev->dev, + return snd_soc_register_component(&pdev->dev, &soc_msm_stub, msm_stub_dais, ARRAY_SIZE(msm_stub_dais)); } static int msm_stub_dev_remove(struct platform_device *pdev) { - snd_soc_unregister_codec(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } static const struct of_device_id msm_stub_codec_dt_match[] = { diff --git a/asoc/codecs/wcd-clsh.c b/asoc/codecs/wcd-clsh.c index 8c2ae689312e..7aec959474aa 100644 --- a/asoc/codecs/wcd-clsh.c +++ b/asoc/codecs/wcd-clsh.c @@ -13,7 +13,7 @@ #define WCD_USLEEP_RANGE 50 -static void (*clsh_state_fp[NUM_CLSH_STATES])(struct snd_soc_codec *, +static void (*clsh_state_fp[NUM_CLSH_STATES])(struct snd_soc_component *, struct wcd_clsh_cdc_info *, u8 req_state, bool en, int mode); @@ -103,66 +103,82 @@ static inline void wcd_clsh_set_int_mode(struct wcd_clsh_cdc_info *clsh_d, clsh_d->interpolator_modes[ffs(clsh_state)] = mode; } -static inline void wcd_clsh_set_buck_mode(struct snd_soc_codec *codec, +static inline void wcd_clsh_set_buck_mode(struct snd_soc_component *component, int mode) { if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || mode == CLS_AB_HIFI) - snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES, - 0x08, 0x08); /* set to HIFI */ + snd_soc_component_update_bits(component, + WCD9XXX_ANA_RX_SUPPLIES, + 0x08, 0x08); /* set to HIFI */ else - snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES, - 0x08, 0x00); /* set to default */ + snd_soc_component_update_bits(component, + WCD9XXX_ANA_RX_SUPPLIES, + 0x08, 0x00); /* set to default */ } -static inline void wcd_clsh_set_flyback_mode(struct snd_soc_codec *codec, - int mode) +static inline void wcd_clsh_set_flyback_mode( + struct snd_soc_component *component, + int mode) { if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || mode == CLS_AB_HIFI) { - snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES, - 0x04, 0x04); - snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEG_CTRL_4, - 0xF0, 0x80); + snd_soc_component_update_bits(component, + WCD9XXX_ANA_RX_SUPPLIES, + 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD9XXX_FLYBACK_VNEG_CTRL_4, + 0xF0, 0x80); } else { - snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES, - 0x04, 0x00); /* set to Default */ - snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEG_CTRL_4, - 0xF0, 0x70); + snd_soc_component_update_bits(component, + WCD9XXX_ANA_RX_SUPPLIES, + 0x04, 0x00); /* set to Default */ + snd_soc_component_update_bits(component, + WCD9XXX_FLYBACK_VNEG_CTRL_4, + 0xF0, 0x70); } } -static inline void wcd_clsh_force_iq_ctl(struct snd_soc_codec *codec, +static inline void wcd_clsh_force_iq_ctl(struct snd_soc_component *component, int mode, bool enable) { if (enable) { - snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEGDAC_CTRL_2, - 0xE0, 0xA0); + snd_soc_component_update_bits(component, + WCD9XXX_FLYBACK_VNEGDAC_CTRL_2, + 0xE0, 0xA0); /* 100usec delay is needed as per HW requirement */ usleep_range(100, 110); - snd_soc_update_bits(codec, WCD9XXX_CLASSH_MODE_3, - 0x02, 0x02); - snd_soc_update_bits(codec, WCD9XXX_CLASSH_MODE_2, - 0xFF, 0x1C); + snd_soc_component_update_bits(component, + WCD9XXX_CLASSH_MODE_3, + 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD9XXX_CLASSH_MODE_2, + 0xFF, 0x1C); if (mode == CLS_H_LOHIFI) { - snd_soc_update_bits(codec, WCD9XXX_HPH_NEW_INT_PA_MISC2, - 0x20, 0x20); - snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_HPH_LOWPOWER, - 0xF0, 0xC0); - snd_soc_update_bits(codec, WCD9XXX_HPH_PA_CTL1, - 0x0E, 0x02); + snd_soc_component_update_bits(component, + WCD9XXX_HPH_NEW_INT_PA_MISC2, + 0x20, 0x20); + snd_soc_component_update_bits(component, + WCD9XXX_RX_BIAS_HPH_LOWPOWER, + 0xF0, 0xC0); + snd_soc_component_update_bits(component, + WCD9XXX_HPH_PA_CTL1, + 0x0E, 0x02); } } else { - snd_soc_update_bits(codec, WCD9XXX_HPH_NEW_INT_PA_MISC2, - 0x20, 0x00); - snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_HPH_LOWPOWER, - 0xF0, 0x80); - snd_soc_update_bits(codec, WCD9XXX_HPH_PA_CTL1, - 0x0E, 0x06); + snd_soc_component_update_bits(component, + WCD9XXX_HPH_NEW_INT_PA_MISC2, + 0x20, 0x00); + snd_soc_component_update_bits(component, + WCD9XXX_RX_BIAS_HPH_LOWPOWER, + 0xF0, 0x80); + snd_soc_component_update_bits(component, + WCD9XXX_HPH_PA_CTL1, + 0x0E, 0x06); } } -static void wcd_clsh_buck_ctrl(struct snd_soc_codec *codec, +static void wcd_clsh_buck_ctrl(struct snd_soc_component *component, struct wcd_clsh_cdc_info *clsh_d, int mode, bool enable) @@ -170,8 +186,9 @@ static void wcd_clsh_buck_ctrl(struct snd_soc_codec *codec, /* enable/disable buck */ if ((enable && (++clsh_d->buck_users == 1)) || (!enable && (--clsh_d->buck_users == 0))) { - snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES, - (1 << 7), (enable << 7)); + snd_soc_component_update_bits(component, + WCD9XXX_ANA_RX_SUPPLIES, + (1 << 7), (enable << 7)); /* * 500us sleep is required after buck enable/disable * as per HW requirement @@ -179,18 +196,21 @@ static void wcd_clsh_buck_ctrl(struct snd_soc_codec *codec, usleep_range(500, 510); if (mode == CLS_H_LOHIFI || mode == CLS_H_ULP || mode == CLS_H_HIFI || mode == CLS_H_LP) - snd_soc_update_bits(codec, WCD9XXX_CLASSH_MODE_3, - 0x02, 0x00); + snd_soc_component_update_bits(component, + WCD9XXX_CLASSH_MODE_3, + 0x02, 0x00); - snd_soc_update_bits(codec, WCD9XXX_CLASSH_MODE_2, 0xFF, 0x3A); + snd_soc_component_update_bits(component, + WCD9XXX_CLASSH_MODE_2, + 0xFF, 0x3A); /* 500usec delay is needed as per HW requirement */ usleep_range(500, 500 + WCD_USLEEP_RANGE); } - dev_dbg(codec->dev, "%s: buck_users %d, enable %d, mode: %s\n", + dev_dbg(component->dev, "%s: buck_users %d, enable %d, mode: %s\n", __func__, clsh_d->buck_users, enable, mode_to_str(mode)); } -static void wcd_clsh_flyback_ctrl(struct snd_soc_codec *codec, +static void wcd_clsh_flyback_ctrl(struct snd_soc_component *component, struct wcd_clsh_cdc_info *clsh_d, int mode, bool enable) @@ -198,23 +218,25 @@ static void wcd_clsh_flyback_ctrl(struct snd_soc_codec *codec, /* enable/disable flyback */ if ((enable && (++clsh_d->flyback_users == 1)) || (!enable && (--clsh_d->flyback_users == 0))) { - snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES, - (1 << 6), (enable << 6)); + snd_soc_component_update_bits(component, + WCD9XXX_ANA_RX_SUPPLIES, + (1 << 6), (enable << 6)); /* * 100us sleep is required after flyback enable/disable * as per HW requirement */ usleep_range(100, 110); - snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEGDAC_CTRL_2, - 0xE0, 0xE0); + snd_soc_component_update_bits(component, + WCD9XXX_FLYBACK_VNEGDAC_CTRL_2, + 0xE0, 0xE0); /* 500usec delay is needed as per HW requirement */ usleep_range(500, 500 + WCD_USLEEP_RANGE); } - dev_dbg(codec->dev, "%s: flyback_users %d, enable %d, mode: %s\n", + dev_dbg(component->dev, "%s: flyback_users %d, enable %d, mode: %s\n", __func__, clsh_d->flyback_users, enable, mode_to_str(mode)); } -static void wcd_clsh_set_hph_mode(struct snd_soc_codec *codec, +static void wcd_clsh_set_hph_mode(struct snd_soc_component *component, int mode) { u8 val = 0; @@ -236,185 +258,189 @@ static void wcd_clsh_set_hph_mode(struct snd_soc_codec *codec, val = 0x04; break; default: - dev_err(codec->dev, "%s:Invalid mode %d\n", __func__, mode); + dev_err(component->dev, "%s:Invalid mode %d\n", __func__, mode); return; }; - snd_soc_update_bits(codec, WCD9XXX_ANA_HPH, 0x0C, val); + snd_soc_component_update_bits(component, WCD9XXX_ANA_HPH, 0x0C, val); } -static void wcd_clsh_set_flyback_current(struct snd_soc_codec *codec, int mode) +static void wcd_clsh_set_flyback_current(struct snd_soc_component *component, + int mode) { - - snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_FLYB_BUFF, 0x0F, 0x0A); - snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_FLYB_BUFF, 0xF0, 0xA0); + snd_soc_component_update_bits(component, WCD9XXX_RX_BIAS_FLYB_BUFF, + 0x0F, 0x0A); + snd_soc_component_update_bits(component, WCD9XXX_RX_BIAS_FLYB_BUFF, + 0xF0, 0xA0); /* Sleep needed to avoid click and pop as per HW requirement */ usleep_range(100, 110); } -static void wcd_clsh_set_buck_regulator_mode(struct snd_soc_codec *codec, - int mode) +static void wcd_clsh_set_buck_regulator_mode( + struct snd_soc_component *component, + int mode) { - snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES, + snd_soc_component_update_bits(component, WCD9XXX_ANA_RX_SUPPLIES, 0x02, 0x00); } -static void wcd_clsh_state_ear_aux(struct snd_soc_codec *codec, +static void wcd_clsh_state_ear_aux(struct snd_soc_component *component, struct wcd_clsh_cdc_info *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), - is_enable ? "enable" : "disable"); + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); } -static void wcd_clsh_state_hph_aux(struct snd_soc_codec *codec, +static void wcd_clsh_state_hph_aux(struct snd_soc_component *component, struct wcd_clsh_cdc_info *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), - is_enable ? "enable" : "disable"); + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); } -static void wcd_clsh_state_hph_ear(struct snd_soc_codec *codec, +static void wcd_clsh_state_hph_ear(struct snd_soc_component *component, struct wcd_clsh_cdc_info *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), - is_enable ? "enable" : "disable"); + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); } -static void wcd_clsh_state_hph_st(struct snd_soc_codec *codec, +static void wcd_clsh_state_hph_st(struct snd_soc_component *component, struct wcd_clsh_cdc_info *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), - is_enable ? "enable" : "disable"); + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); } -static void wcd_clsh_state_hph_r(struct snd_soc_codec *codec, +static void wcd_clsh_state_hph_r(struct snd_soc_component *component, struct wcd_clsh_cdc_info *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), - is_enable ? "enable" : "disable"); + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); if (mode == CLS_H_NORMAL) { - dev_dbg(codec->dev, "%s: Normal mode not applicable for hph_r\n", + dev_dbg(component->dev, "%s: Normal mode not applicable for hph_r\n", __func__); return; } if (is_enable) { - wcd_clsh_set_buck_regulator_mode(codec, mode); - wcd_clsh_set_flyback_mode(codec, mode); - wcd_clsh_force_iq_ctl(codec, mode, true); - wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true); - wcd_clsh_set_flyback_current(codec, mode); - wcd_clsh_set_buck_mode(codec, mode); - wcd_clsh_buck_ctrl(codec, clsh_d, mode, true); - wcd_clsh_set_hph_mode(codec, mode); + wcd_clsh_set_buck_regulator_mode(component, mode); + wcd_clsh_set_flyback_mode(component, mode); + wcd_clsh_force_iq_ctl(component, mode, true); + wcd_clsh_flyback_ctrl(component, clsh_d, mode, true); + wcd_clsh_set_flyback_current(component, mode); + wcd_clsh_set_buck_mode(component, mode); + wcd_clsh_buck_ctrl(component, clsh_d, mode, true); + wcd_clsh_set_hph_mode(component, mode); } else { - wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_hph_mode(component, CLS_H_NORMAL); /* buck and flyback set to default mode and disable */ - wcd_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false); - wcd_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false); - wcd_clsh_force_iq_ctl(codec, CLS_H_NORMAL, false); - wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); - wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + wcd_clsh_flyback_ctrl(component, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_buck_ctrl(component, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_force_iq_ctl(component, CLS_H_NORMAL, false); + wcd_clsh_set_flyback_mode(component, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(component, CLS_H_NORMAL); } } -static void wcd_clsh_state_hph_l(struct snd_soc_codec *codec, +static void wcd_clsh_state_hph_l(struct snd_soc_component *component, struct wcd_clsh_cdc_info *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), - is_enable ? "enable" : "disable"); + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); if (mode == CLS_H_NORMAL) { - dev_dbg(codec->dev, "%s: Normal mode not applicable for hph_l\n", + dev_dbg(component->dev, "%s: Normal mode not applicable for hph_l\n", __func__); return; } if (is_enable) { - wcd_clsh_set_buck_regulator_mode(codec, mode); - wcd_clsh_set_flyback_mode(codec, mode); - wcd_clsh_force_iq_ctl(codec, mode, true); - wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true); - wcd_clsh_set_flyback_current(codec, mode); - wcd_clsh_set_buck_mode(codec, mode); - wcd_clsh_buck_ctrl(codec, clsh_d, mode, true); - wcd_clsh_set_hph_mode(codec, mode); + wcd_clsh_set_buck_regulator_mode(component, mode); + wcd_clsh_set_flyback_mode(component, mode); + wcd_clsh_force_iq_ctl(component, mode, true); + wcd_clsh_flyback_ctrl(component, clsh_d, mode, true); + wcd_clsh_set_flyback_current(component, mode); + wcd_clsh_set_buck_mode(component, mode); + wcd_clsh_buck_ctrl(component, clsh_d, mode, true); + wcd_clsh_set_hph_mode(component, mode); } else { - wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_hph_mode(component, CLS_H_NORMAL); /* set buck and flyback to Default Mode */ - wcd_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false); - wcd_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false); - wcd_clsh_force_iq_ctl(codec, CLS_H_NORMAL, false); - wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); - wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + wcd_clsh_flyback_ctrl(component, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_buck_ctrl(component, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_force_iq_ctl(component, CLS_H_NORMAL, false); + wcd_clsh_set_flyback_mode(component, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(component, CLS_H_NORMAL); } } -static void wcd_clsh_state_aux(struct snd_soc_codec *codec, +static void wcd_clsh_state_aux(struct snd_soc_component *component, struct wcd_clsh_cdc_info *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), - is_enable ? "enable" : "disable"); + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); if (is_enable) { - wcd_clsh_set_buck_mode(codec, mode); - wcd_clsh_set_flyback_mode(codec, mode); - wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true); - wcd_clsh_set_flyback_current(codec, mode); - wcd_clsh_buck_ctrl(codec, clsh_d, mode, true); + wcd_clsh_set_buck_mode(component, mode); + wcd_clsh_set_flyback_mode(component, mode); + wcd_clsh_flyback_ctrl(component, clsh_d, mode, true); + wcd_clsh_set_flyback_current(component, mode); + wcd_clsh_buck_ctrl(component, clsh_d, mode, true); } else { - wcd_clsh_buck_ctrl(codec, clsh_d, mode, false); - wcd_clsh_flyback_ctrl(codec, clsh_d, mode, false); - wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); - wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + wcd_clsh_buck_ctrl(component, clsh_d, mode, false); + wcd_clsh_flyback_ctrl(component, clsh_d, mode, false); + wcd_clsh_set_flyback_mode(component, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(component, CLS_H_NORMAL); } } -static void wcd_clsh_state_ear(struct snd_soc_codec *codec, +static void wcd_clsh_state_ear(struct snd_soc_component *component, struct wcd_clsh_cdc_info *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); if (is_enable) { - wcd_clsh_set_buck_regulator_mode(codec, mode); - wcd_clsh_set_flyback_mode(codec, mode); - wcd_clsh_force_iq_ctl(codec, mode, true); - wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true); - wcd_clsh_set_flyback_current(codec, mode); - wcd_clsh_set_buck_mode(codec, mode); - wcd_clsh_buck_ctrl(codec, clsh_d, mode, true); - wcd_clsh_set_hph_mode(codec, mode); + wcd_clsh_set_buck_regulator_mode(component, mode); + wcd_clsh_set_flyback_mode(component, mode); + wcd_clsh_force_iq_ctl(component, mode, true); + wcd_clsh_flyback_ctrl(component, clsh_d, mode, true); + wcd_clsh_set_flyback_current(component, mode); + wcd_clsh_set_buck_mode(component, mode); + wcd_clsh_buck_ctrl(component, clsh_d, mode, true); + wcd_clsh_set_hph_mode(component, mode); } else { - wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_hph_mode(component, CLS_H_NORMAL); /* set buck and flyback to Default Mode */ - wcd_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false); - wcd_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false); - wcd_clsh_force_iq_ctl(codec, CLS_H_NORMAL, false); - wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); - wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + wcd_clsh_flyback_ctrl(component, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_buck_ctrl(component, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_force_iq_ctl(component, CLS_H_NORMAL, false); + wcd_clsh_set_flyback_mode(component, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(component, CLS_H_NORMAL); } } -static void wcd_clsh_state_err(struct snd_soc_codec *codec, +static void wcd_clsh_state_err(struct snd_soc_component *component, struct wcd_clsh_cdc_info *clsh_d, u8 req_state, bool is_enable, int mode) { char msg[128]; - dev_err(codec->dev, + dev_err(component->dev, "%s Wrong request for class H state machine requested to %s %s\n", __func__, is_enable ? "enable" : "disable", state_to_str(req_state, msg, sizeof(msg))); @@ -447,14 +473,14 @@ static bool wcd_clsh_is_state_valid(u8 state) /* * Function: wcd_cls_h_fsm - * Params: codec, cdc_clsh_d, req_state, req_type, clsh_event + * Params: component, cdc_clsh_d, req_state, req_type, clsh_event * Description: * This function handles PRE DAC and POST DAC conditions of different devices * and updates class H configuration of different combination of devices * based on validity of their states. cdc_clsh_d will contain current * class h state information */ -void wcd_cls_h_fsm(struct snd_soc_codec *codec, +void wcd_cls_h_fsm(struct snd_soc_component *component, struct wcd_clsh_cdc_info *cdc_clsh_d, u8 clsh_event, u8 req_state, int int_mode) @@ -468,14 +494,14 @@ void wcd_cls_h_fsm(struct snd_soc_codec *codec, new_state = old_state | req_state; if (!wcd_clsh_is_state_valid(new_state)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Class-H not a valid new state: %s\n", __func__, state_to_str(new_state, msg0, sizeof(msg0))); return; } if (new_state == old_state) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Class-H already in requested state: %s\n", __func__, state_to_str(new_state, msg0, sizeof(msg0))); @@ -483,9 +509,9 @@ void wcd_cls_h_fsm(struct snd_soc_codec *codec, } cdc_clsh_d->state = new_state; wcd_clsh_set_int_mode(cdc_clsh_d, req_state, int_mode); - (*clsh_state_fp[new_state]) (codec, cdc_clsh_d, req_state, + (*clsh_state_fp[new_state]) (component, cdc_clsh_d, req_state, CLSH_REQ_ENABLE, int_mode); - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: ClassH state transition from %s to %s\n", __func__, state_to_str(old_state, msg0, sizeof(msg0)), state_to_str(cdc_clsh_d->state, msg1, sizeof(msg1))); @@ -495,7 +521,7 @@ void wcd_cls_h_fsm(struct snd_soc_codec *codec, new_state = old_state & (~req_state); if (new_state < NUM_CLSH_STATES) { if (!wcd_clsh_is_state_valid(old_state)) { - dev_err(codec->dev, + dev_err(component->dev, "%s:Invalid old state:%s\n", __func__, state_to_str(old_state, msg0, @@ -503,19 +529,19 @@ void wcd_cls_h_fsm(struct snd_soc_codec *codec, return; } if (new_state == old_state) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Class-H already in requested state: %s\n", __func__, state_to_str(new_state, msg0, sizeof(msg0))); return; } - (*clsh_state_fp[old_state]) (codec, cdc_clsh_d, + (*clsh_state_fp[old_state]) (component, cdc_clsh_d, req_state, CLSH_REQ_DISABLE, int_mode); cdc_clsh_d->state = new_state; wcd_clsh_set_int_mode(cdc_clsh_d, req_state, CLS_NONE); - dev_dbg(codec->dev, "%s: ClassH state transition from %s to %s\n", + dev_dbg(component->dev, "%s: ClassH state transition from %s to %s\n", __func__, state_to_str(old_state, msg0, sizeof(msg0)), state_to_str(cdc_clsh_d->state, msg1, diff --git a/asoc/codecs/wcd-clsh.h b/asoc/codecs/wcd-clsh.h index 29e5da5a6883..1a7759ef0e9a 100644 --- a/asoc/codecs/wcd-clsh.h +++ b/asoc/codecs/wcd-clsh.h @@ -74,14 +74,14 @@ struct wcd_clsh_cdc_info { }; #ifdef CONFIG_SND_SOC_WCD9XXX_V2 -extern void wcd_cls_h_fsm(struct snd_soc_codec *codec, +extern void wcd_cls_h_fsm(struct snd_soc_component *component, struct wcd_clsh_cdc_info *cdc_clsh_d, u8 clsh_event, u8 req_state, int int_mode); extern void wcd_cls_h_init(struct wcd_clsh_cdc_info *clsh); #else -extern void wcd_cls_h_fsm(struct snd_soc_codec *codec, +extern void wcd_cls_h_fsm(struct snd_soc_component *component, struct wcd_clsh_cdc_info *cdc_clsh_d, u8 clsh_event, u8 req_state, int int_mode) diff --git a/asoc/codecs/wcd-irq.c b/asoc/codecs/wcd-irq.c index 37ed56697990..d294d40f598b 100644 --- a/asoc/codecs/wcd-irq.c +++ b/asoc/codecs/wcd-irq.c @@ -112,12 +112,14 @@ static struct irq_chip wcd_irq_chip = { }; static struct lock_class_key wcd_irq_lock_class; +static struct lock_class_key wcd_irq_lock_requested_class; static int wcd_irq_chip_map(struct irq_domain *irqd, unsigned int virq, irq_hw_number_t hw) { irq_set_chip_and_handler(virq, &wcd_irq_chip, handle_simple_irq); - irq_set_lockdep_class(virq, &wcd_irq_lock_class); + irq_set_lockdep_class(virq, &wcd_irq_lock_class, + &wcd_irq_lock_requested_class); irq_set_nested_thread(virq, 1); irq_set_noprobe(virq); diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index 2170869342b3..c7882d6cb3fb 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -193,7 +193,7 @@ static bool wcd_mbhc_adc_detect_anc_plug_type(struct wcd_mbhc *mbhc) wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, false); WCD_MBHC_REG_READ(WCD_MBHC_FSM_EN, fsm_en); - mbhc->mbhc_cb->mbhc_micbias_control(mbhc->codec, + mbhc->mbhc_cb->mbhc_micbias_control(mbhc->component, mbhc->mbhc_cfg->anc_micbias, MICB_ENABLE); @@ -254,7 +254,7 @@ static bool wcd_mbhc_adc_detect_anc_plug_type(struct wcd_mbhc *mbhc) /* Restore electrical detection */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, elect_ctl); - mbhc->mbhc_cb->mbhc_micbias_control(mbhc->codec, + mbhc->mbhc_cb->mbhc_micbias_control(mbhc->component, mbhc->mbhc_cfg->anc_micbias, MICB_DISABLE); pr_debug("%s: anc mic %sfound\n", __func__, @@ -283,7 +283,7 @@ static int wcd_check_cross_conn(struct wcd_mbhc *mbhc) /* If PA is enabled, dont check for cross-connection */ if (mbhc->mbhc_cb->hph_pa_on_status) - if (mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec)) + if (mbhc->mbhc_cb->hph_pa_on_status(mbhc->component)) return -EINVAL; /* Read legacy electircal detection and disable */ @@ -349,15 +349,15 @@ static bool wcd_mbhc_adc_check_for_spl_headset(struct wcd_mbhc *mbhc, bool spl_hs = false; int output_mv = 0; int adc_threshold = 0, adc_hph_threshold = 0; - struct snd_soc_codec *codec = mbhc->codec; - struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + struct snd_soc_component *component = mbhc->component; + struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent); pr_debug("%s: enter\n", __func__); if (!mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) goto exit; /* Bump up MB2 to 2.7V */ - mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->codec, + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->component, mbhc->mbhc_cfg->mbhc_micbias, true); usleep_range(10000, 10100); @@ -391,7 +391,7 @@ static bool wcd_mbhc_adc_check_for_spl_headset(struct wcd_mbhc *mbhc, /* MB2 back to 1.8v if the type is not special headset */ if (spl_hs_cnt && (*spl_hs_cnt != WCD_MBHC_SPL_HS_CNT)) { - mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->codec, + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->component, mbhc->mbhc_cfg->mbhc_micbias, false); /* Add 10ms delay for micbias to settle */ usleep_range(10000, 10100); @@ -412,8 +412,8 @@ static bool wcd_is_special_headset(struct wcd_mbhc *mbhc) bool is_spl_hs = false; int output_mv = 0; int adc_threshold = 0; - struct snd_soc_codec *codec = mbhc->codec; - struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + struct snd_soc_component *component = mbhc->component; + struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent); /* * Increase micbias to 2.7V to detect headsets with @@ -425,7 +425,7 @@ static bool wcd_is_special_headset(struct wcd_mbhc *mbhc) __func__); return false; } else if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) { - ret = mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->codec, + ret = mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->component, MIC_BIAS_2, true); if (ret) { pr_err("%s: mbhc_micb_ctrl_thr_mic failed, ret: %d\n", @@ -470,7 +470,8 @@ static bool wcd_is_special_headset(struct wcd_mbhc *mbhc) } if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic && !mbhc->micbias_enable) - mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->codec, MIC_BIAS_2, + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->component, + MIC_BIAS_2, false); pr_debug("%s: leave, micb_enable: %d\n", __func__, mbhc->micbias_enable); @@ -530,18 +531,18 @@ static void wcd_cancel_hs_detect_plug(struct wcd_mbhc *mbhc, /* called under codec_resource_lock acquisition */ static void wcd_mbhc_adc_detect_plug_type(struct wcd_mbhc *mbhc) { - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; pr_debug("%s: enter\n", __func__); WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); if (mbhc->mbhc_cb->hph_pull_down_ctrl) - mbhc->mbhc_cb->hph_pull_down_ctrl(codec, false); + mbhc->mbhc_cb->hph_pull_down_ctrl(component, false); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_DETECTION_DONE, 0); if (mbhc->mbhc_cb->mbhc_micbias_control) { - mbhc->mbhc_cb->mbhc_micbias_control(codec, MIC_BIAS_2, + mbhc->mbhc_cb->mbhc_micbias_control(component, MIC_BIAS_2, MICB_ENABLE); } else { pr_err("%s: Mic Bias is not enabled\n", __func__); @@ -558,10 +559,10 @@ static void wcd_micbias_disable(struct wcd_mbhc *mbhc) { if (mbhc->micbias_enable) { mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( - mbhc->codec, MIC_BIAS_2, false); + mbhc->component, MIC_BIAS_2, false); if (mbhc->mbhc_cb->set_micbias_value) mbhc->mbhc_cb->set_micbias_value( - mbhc->codec); + mbhc->component); mbhc->micbias_enable = false; } } @@ -596,7 +597,7 @@ static int wcd_mbhc_get_plug_from_adc(struct wcd_mbhc *mbhc, int adc_result) static void wcd_correct_swch_plug(struct work_struct *work) { struct wcd_mbhc *mbhc; - struct snd_soc_codec *codec; + struct snd_soc_component *component; enum wcd_mbhc_plug_type plug_type = MBHC_PLUG_TYPE_INVALID; unsigned long timeout; bool wrk_complete = false; @@ -612,7 +613,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) pr_debug("%s: enter\n", __func__); mbhc = container_of(work, struct wcd_mbhc, correct_plug_swch); - codec = mbhc->codec; + component = mbhc->component; WCD_MBHC_RSC_LOCK(mbhc); /* Mask ADC COMPLETE interrupt */ @@ -703,7 +704,8 @@ static void wcd_correct_swch_plug(struct work_struct *work) } if (mbhc->mbhc_cb->hph_pa_on_status) - is_pa_on = mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec); + is_pa_on = mbhc->mbhc_cb->hph_pa_on_status( + mbhc->component); if ((output_mv <= WCD_MBHC_ADC_HS_THRESHOLD_MV) && (!is_pa_on)) { @@ -750,7 +752,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) * otherwise report unsupported plug */ if (mbhc->mbhc_cfg->swap_gnd_mic && - mbhc->mbhc_cfg->swap_gnd_mic(codec, + mbhc->mbhc_cfg->swap_gnd_mic(component, true)) { pr_debug("%s: US_EU gpio present,flip switch\n" , __func__); @@ -858,7 +860,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) exit: if (mbhc->mbhc_cb->mbhc_micbias_control && !mbhc->micbias_enable) - mbhc->mbhc_cb->mbhc_micbias_control(codec, MIC_BIAS_2, + mbhc->mbhc_cb->mbhc_micbias_control(component, MIC_BIAS_2, MICB_DISABLE); /* @@ -870,14 +872,14 @@ static void wcd_correct_swch_plug(struct work_struct *work) mbhc->micbias_enable) { if (mbhc->mbhc_cb->mbhc_micbias_control) mbhc->mbhc_cb->mbhc_micbias_control( - codec, MIC_BIAS_2, + component, MIC_BIAS_2, MICB_DISABLE); if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( - codec, + component, MIC_BIAS_2, false); if (mbhc->mbhc_cb->set_micbias_value) { - mbhc->mbhc_cb->set_micbias_value(codec); + mbhc->mbhc_cb->set_micbias_value(component); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MICB_CTRL, 0); } mbhc->micbias_enable = false; @@ -905,7 +907,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) } if (mbhc->mbhc_cb->hph_pull_down_ctrl) - mbhc->mbhc_cb->hph_pull_down_ctrl(codec, true); + mbhc->mbhc_cb->hph_pull_down_ctrl(component, true); mbhc->mbhc_cb->lock_sleep(mbhc, false); pr_debug("%s: leave\n", __func__); @@ -953,7 +955,7 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) if (mbhc->mbhc_cfg->moisture_en) { if (mbhc->mbhc_cb->hph_pa_on_status) - if (mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec)) { + if (mbhc->mbhc_cb->hph_pa_on_status(mbhc->component)) { hphpa_on = true; WCD_MBHC_REG_UPDATE_BITS( WCD_MBHC_HPHL_PA_EN, 0); diff --git a/asoc/codecs/wcd-mbhc-legacy.c b/asoc/codecs/wcd-mbhc-legacy.c index e4196b10359d..4b8917d156e3 100644 --- a/asoc/codecs/wcd-mbhc-legacy.c +++ b/asoc/codecs/wcd-mbhc-legacy.c @@ -48,7 +48,7 @@ static bool wcd_mbhc_detect_anc_plug_type(struct wcd_mbhc *mbhc) if (val) WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); - mbhc->mbhc_cb->mbhc_micbias_control(mbhc->codec, + mbhc->mbhc_cb->mbhc_micbias_control(mbhc->component, mbhc->mbhc_cfg->anc_micbias, MICB_ENABLE); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MUX_CTL, 0x2); @@ -103,7 +103,7 @@ static bool wcd_mbhc_detect_anc_plug_type(struct wcd_mbhc *mbhc) WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ANC_DET_EN, 0); - mbhc->mbhc_cb->mbhc_micbias_control(mbhc->codec, + mbhc->mbhc_cb->mbhc_micbias_control(mbhc->component, mbhc->mbhc_cfg->anc_micbias, MICB_DISABLE); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MUX_CTL, 0x0); @@ -127,7 +127,7 @@ static int wcd_check_cross_conn(struct wcd_mbhc *mbhc) /* If PA is enabled, dont check for cross-connection */ if (mbhc->mbhc_cb->hph_pa_on_status) - if (mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec)) + if (mbhc->mbhc_cb->hph_pa_on_status(mbhc->component)) return false; WCD_MBHC_REG_READ(WCD_MBHC_ELECT_SCHMT_ISRC, reg1); @@ -168,7 +168,7 @@ static int wcd_check_cross_conn(struct wcd_mbhc *mbhc) static bool wcd_is_special_headset(struct wcd_mbhc *mbhc) { - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; int delay = 0, rc; bool ret = false; u16 hs_comp_res; @@ -184,7 +184,7 @@ static bool wcd_is_special_headset(struct wcd_mbhc *mbhc) __func__); return false; } else if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) { - rc = mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(codec, + rc = mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(component, MIC_BIAS_2, true); if (rc) { pr_err("%s: Micbias control for thr mic failed, rc: %d\n", @@ -206,17 +206,17 @@ static bool wcd_is_special_headset(struct wcd_mbhc *mbhc) } delay = delay + 50; if (mbhc->mbhc_cb->mbhc_common_micb_ctrl) { - mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, + mbhc->mbhc_cb->mbhc_common_micb_ctrl(component, MBHC_COMMON_MICB_PRECHARGE, true); - mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, + mbhc->mbhc_cb->mbhc_common_micb_ctrl(component, MBHC_COMMON_MICB_SET_VAL, true); } /* Wait for 50msec for MICBIAS to settle down */ msleep(50); if (mbhc->mbhc_cb->set_auto_zeroing) - mbhc->mbhc_cb->set_auto_zeroing(codec, true); + mbhc->mbhc_cb->set_auto_zeroing(component, true); /* Wait for 50msec for FSM to update result values */ msleep(50); WCD_MBHC_REG_READ(WCD_MBHC_HS_COMP_RESULT, hs_comp_res); @@ -237,17 +237,17 @@ static bool wcd_is_special_headset(struct wcd_mbhc *mbhc) ret = true; } if (mbhc->mbhc_cb->mbhc_common_micb_ctrl) - mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, + mbhc->mbhc_cb->mbhc_common_micb_ctrl(component, MBHC_COMMON_MICB_PRECHARGE, false); if (mbhc->mbhc_cb->set_micbias_value && !mbhc->micbias_enable) - mbhc->mbhc_cb->set_micbias_value(codec); + mbhc->mbhc_cb->set_micbias_value(component); if (mbhc->mbhc_cb->set_auto_zeroing) - mbhc->mbhc_cb->set_auto_zeroing(codec, false); + mbhc->mbhc_cb->set_auto_zeroing(component, false); if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic && !mbhc->micbias_enable) - mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(codec, MIC_BIAS_2, + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(component, MIC_BIAS_2, false); pr_debug("%s: leave, micb_enable: %d\n", __func__, @@ -282,7 +282,7 @@ static void wcd_enable_mbhc_supply(struct wcd_mbhc *mbhc, enum wcd_mbhc_plug_type plug_type) { - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; /* * Do not disable micbias if recording is going on or @@ -294,7 +294,7 @@ static void wcd_enable_mbhc_supply(struct wcd_mbhc *mbhc, */ if (det_extn_cable_en && mbhc->is_extn_cable && mbhc->mbhc_cb && mbhc->mbhc_cb->extn_use_mb && - mbhc->mbhc_cb->extn_use_mb(codec)) { + mbhc->mbhc_cb->extn_use_mb(component)) { if (plug_type == MBHC_PLUG_TYPE_HEADPHONE || plug_type == MBHC_PLUG_TYPE_HEADSET) wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); @@ -340,7 +340,7 @@ static bool wcd_mbhc_check_for_spl_headset(struct wcd_mbhc *mbhc, } /* Bump up MB2 to 2.7v */ - mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->codec, + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->component, mbhc->mbhc_cfg->mbhc_micbias, true); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); @@ -356,7 +356,7 @@ static bool wcd_mbhc_check_for_spl_headset(struct wcd_mbhc *mbhc, /* MB2 back to 1.8v */ if (*spl_hs_cnt != WCD_MBHC_SPL_HS_CNT) { - mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->codec, + mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->component, mbhc->mbhc_cfg->mbhc_micbias, false); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); @@ -399,24 +399,24 @@ static void wcd_cancel_hs_detect_plug(struct wcd_mbhc *mbhc, /* called under codec_resource_lock acquisition */ static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc) { - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; bool micbias1 = false; pr_debug("%s: enter\n", __func__); WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); if (mbhc->mbhc_cb->hph_pull_down_ctrl) - mbhc->mbhc_cb->hph_pull_down_ctrl(codec, false); + mbhc->mbhc_cb->hph_pull_down_ctrl(component, false); if (mbhc->mbhc_cb->micbias_enable_status) micbias1 = mbhc->mbhc_cb->micbias_enable_status(mbhc, MIC_BIAS_1); if (mbhc->mbhc_cb->set_cap_mode) - mbhc->mbhc_cb->set_cap_mode(codec, micbias1, true); + mbhc->mbhc_cb->set_cap_mode(component, micbias1, true); if (mbhc->mbhc_cb->mbhc_micbias_control) - mbhc->mbhc_cb->mbhc_micbias_control(codec, MIC_BIAS_2, + mbhc->mbhc_cb->mbhc_micbias_control(component, MIC_BIAS_2, MICB_ENABLE); else wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); @@ -430,7 +430,7 @@ static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc) static void wcd_correct_swch_plug(struct work_struct *work) { struct wcd_mbhc *mbhc; - struct snd_soc_codec *codec; + struct snd_soc_component *component; enum wcd_mbhc_plug_type plug_type = MBHC_PLUG_TYPE_INVALID; unsigned long timeout; u16 hs_comp_res = 0, hphl_sch = 0, mic_sch = 0, btn_result = 0; @@ -448,7 +448,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) pr_debug("%s: enter\n", __func__); mbhc = container_of(work, struct wcd_mbhc, correct_plug_swch); - codec = mbhc->codec; + component = mbhc->component; /* * Enable micbias/pullup for detection in correct work. @@ -528,10 +528,10 @@ static void wcd_correct_swch_plug(struct work_struct *work) if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic && mbhc->micbias_enable) { mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( - mbhc->codec, MIC_BIAS_2, false); + mbhc->component, MIC_BIAS_2, false); if (mbhc->mbhc_cb->set_micbias_value) mbhc->mbhc_cb->set_micbias_value( - mbhc->codec); + mbhc->component); mbhc->micbias_enable = false; } goto exit; @@ -554,10 +554,10 @@ static void wcd_correct_swch_plug(struct work_struct *work) if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic && mbhc->micbias_enable) { mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( - mbhc->codec, MIC_BIAS_2, false); + mbhc->component, MIC_BIAS_2, false); if (mbhc->mbhc_cb->set_micbias_value) mbhc->mbhc_cb->set_micbias_value( - mbhc->codec); + mbhc->component); mbhc->micbias_enable = false; } goto exit; @@ -566,7 +566,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) pr_debug("%s: hs_comp_res: %x\n", __func__, hs_comp_res); if (mbhc->mbhc_cb->hph_pa_on_status) - is_pa_on = mbhc->mbhc_cb->hph_pa_on_status(codec); + is_pa_on = mbhc->mbhc_cb->hph_pa_on_status(component); /* * instead of hogging system by contineous polling, wait for @@ -627,7 +627,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) * otherwise report unsupported plug */ if (mbhc->mbhc_cfg->swap_gnd_mic && - mbhc->mbhc_cfg->swap_gnd_mic(codec, + mbhc->mbhc_cfg->swap_gnd_mic(component, true)) { pr_debug("%s: US_EU gpio present,flip switch\n" , __func__); @@ -733,7 +733,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) exit: if (mbhc->mbhc_cb->mbhc_micbias_control && !mbhc->micbias_enable) - mbhc->mbhc_cb->mbhc_micbias_control(codec, MIC_BIAS_2, + mbhc->mbhc_cb->mbhc_micbias_control(component, MIC_BIAS_2, MICB_DISABLE); /* @@ -745,14 +745,14 @@ static void wcd_correct_swch_plug(struct work_struct *work) mbhc->micbias_enable) { if (mbhc->mbhc_cb->mbhc_micbias_control) mbhc->mbhc_cb->mbhc_micbias_control( - codec, MIC_BIAS_2, + component, MIC_BIAS_2, MICB_DISABLE); if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( - codec, + component, MIC_BIAS_2, false); if (mbhc->mbhc_cb->set_micbias_value) { - mbhc->mbhc_cb->set_micbias_value(codec); + mbhc->mbhc_cb->set_micbias_value(component); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MICB_CTRL, 0); } mbhc->micbias_enable = false; @@ -774,10 +774,10 @@ static void wcd_correct_swch_plug(struct work_struct *work) WCD_MBHC_RSC_UNLOCK(mbhc); } if (mbhc->mbhc_cb->set_cap_mode) - mbhc->mbhc_cb->set_cap_mode(codec, micbias1, micbias2); + mbhc->mbhc_cb->set_cap_mode(component, micbias1, micbias2); if (mbhc->mbhc_cb->hph_pull_down_ctrl) - mbhc->mbhc_cb->hph_pull_down_ctrl(codec, true); + mbhc->mbhc_cb->hph_pull_down_ctrl(component, true); mbhc->mbhc_cb->lock_sleep(mbhc, false); pr_debug("%s: leave\n", __func__); @@ -833,7 +833,8 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) if (mbhc->mbhc_cfg->moisture_en) { if (mbhc->mbhc_cb->hph_pa_on_status) if ( - mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec)) { + mbhc->mbhc_cb->hph_pa_on_status( + mbhc->component)) { hphpa_on = true; WCD_MBHC_REG_UPDATE_BITS( WCD_MBHC_HPHL_PA_EN, 0); diff --git a/asoc/codecs/wcd-mbhc-v2-api.h b/asoc/codecs/wcd-mbhc-v2-api.h index d89da4caa875..fc00e14174fd 100644 --- a/asoc/codecs/wcd-mbhc-v2-api.h +++ b/asoc/codecs/wcd-mbhc-v2-api.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. */ #ifndef __WCD_MBHC_V2_API_H__ #define __WCD_MBHC_V2_API_H__ @@ -10,7 +10,7 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg); void wcd_mbhc_stop(struct wcd_mbhc *mbhc); -int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, +int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_component *component, const struct wcd_mbhc_cb *mbhc_cb, const struct wcd_mbhc_intr *mbhc_cdc_intr_ids, struct wcd_mbhc_register *wcd_mbhc_regs, @@ -23,7 +23,7 @@ void wcd_mbhc_deinit(struct wcd_mbhc *mbhc); static inline void wcd_mbhc_stop(struct wcd_mbhc *mbhc) { } -int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, +int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_component *component, const struct wcd_mbhc_cb *mbhc_cb, const struct wcd_mbhc_intr *mbhc_cdc_intr_ids, struct wcd_mbhc_register *wcd_mbhc_regs, diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 79944b588496..971cf519ba30 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -36,9 +36,9 @@ EXPORT_SYMBOL(wcd_mbhc_jack_report); static void __hphocp_off_report(struct wcd_mbhc *mbhc, u32 jack_status, int irq) { - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; - dev_dbg(codec->dev, "%s: clear ocp status %x\n", + dev_dbg(component->dev, "%s: clear ocp status %x\n", __func__, jack_status); if (mbhc->hph_status & jack_status) { @@ -55,7 +55,7 @@ static void __hphocp_off_report(struct wcd_mbhc *mbhc, u32 jack_status, mbhc->hphlocp_cnt = 0; else mbhc->hphrocp_cnt = 0; - mbhc->mbhc_cb->irq_control(codec, irq, true); + mbhc->mbhc_cb->irq_control(component, irq, true); } } @@ -74,21 +74,21 @@ static void hphlocp_off_report(struct wcd_mbhc *mbhc, u32 jack_status) static void wcd_program_hs_vref(struct wcd_mbhc *mbhc) { struct wcd_mbhc_plug_type_cfg *plug_type_cfg; - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; u32 reg_val; plug_type_cfg = WCD_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration); reg_val = ((plug_type_cfg->v_hs_max - HS_VREF_MIN_VAL) / 100); - dev_dbg(codec->dev, "%s: reg_val = %x\n", __func__, reg_val); + dev_dbg(component->dev, "%s: reg_val = %x\n", __func__, reg_val); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_VREF, reg_val); } static void wcd_program_btn_threshold(const struct wcd_mbhc *mbhc, bool micbias) { struct wcd_mbhc_btn_detect_cfg *btn_det; - struct snd_soc_codec *codec = mbhc->codec; - struct snd_soc_card *card = codec->component.card; + struct snd_soc_component *component = mbhc->component; + struct snd_soc_card *card = component->card; s16 *btn_low, *btn_high; if (mbhc->mbhc_cfg->calibration == NULL) { @@ -101,8 +101,8 @@ static void wcd_program_btn_threshold(const struct wcd_mbhc *mbhc, bool micbias) btn_high = ((void *)&btn_det->_v_btn_low) + (sizeof(btn_det->_v_btn_low[0]) * btn_det->num_btn); - mbhc->mbhc_cb->set_btn_thr(codec, btn_low, btn_high, btn_det->num_btn, - micbias); + mbhc->mbhc_cb->set_btn_thr(component, btn_low, btn_high, + btn_det->num_btn, micbias); } void wcd_enable_curr_micbias(const struct wcd_mbhc *mbhc, @@ -203,7 +203,7 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, { struct wcd_mbhc *mbhc = (struct wcd_mbhc *)data; enum wcd_notify_event event = (enum wcd_notify_event)val; - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; bool micbias2 = false; bool micbias1 = false; u8 fsm_en = 0; @@ -227,10 +227,10 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, if (!mbhc->micbias_enable) goto out_micb_en; if (mbhc->mbhc_cb->mbhc_common_micb_ctrl) { - mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, + mbhc->mbhc_cb->mbhc_common_micb_ctrl(component, MBHC_COMMON_MICB_PRECHARGE, true); - mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, + mbhc->mbhc_cb->mbhc_common_micb_ctrl(component, MBHC_COMMON_MICB_SET_VAL, true); /* @@ -240,9 +240,9 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, msleep(50); } if (mbhc->mbhc_cb->set_auto_zeroing) - mbhc->mbhc_cb->set_auto_zeroing(codec, true); + mbhc->mbhc_cb->set_auto_zeroing(component, true); if (mbhc->mbhc_cb->mbhc_common_micb_ctrl) - mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, + mbhc->mbhc_cb->mbhc_common_micb_ctrl(component, MBHC_COMMON_MICB_PRECHARGE, false); out_micb_en: @@ -258,7 +258,7 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, } /* configure cap settings properly when micbias is enabled */ if (mbhc->mbhc_cb->set_cap_mode) - mbhc->mbhc_cb->set_cap_mode(codec, micbias1, true); + mbhc->mbhc_cb->set_cap_mode(component, micbias1, true); break; case WCD_EVENT_PRE_MICBIAS_2_OFF: /* @@ -289,9 +289,9 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, } if (mbhc->mbhc_cb->set_auto_zeroing) - mbhc->mbhc_cb->set_auto_zeroing(codec, false); + mbhc->mbhc_cb->set_auto_zeroing(component, false); if (mbhc->mbhc_cb->set_micbias_value && !mbhc->micbias_enable) - mbhc->mbhc_cb->set_micbias_value(codec); + mbhc->mbhc_cb->set_micbias_value(component); /* Enable PULL UP if PA's are enabled */ if ((test_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state)) || (test_bit(WCD_MBHC_EVENT_PA_HPHR, @@ -304,7 +304,7 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, /* configure cap settings properly when micbias is disabled */ if (mbhc->mbhc_cb->set_cap_mode) - mbhc->mbhc_cb->set_cap_mode(codec, micbias1, false); + mbhc->mbhc_cb->set_cap_mode(component, micbias1, false); break; case WCD_EVENT_PRE_HPHL_PA_OFF: mutex_lock(&mbhc->hphl_pa_lock); @@ -363,12 +363,12 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_PULLUP); break; case WCD_EVENT_OCP_OFF: - mbhc->mbhc_cb->irq_control(mbhc->codec, + mbhc->mbhc_cb->irq_control(mbhc->component, mbhc->intr_ids->hph_left_ocp, false); break; case WCD_EVENT_OCP_ON: - mbhc->mbhc_cb->irq_control(mbhc->codec, + mbhc->mbhc_cb->irq_control(mbhc->component, mbhc->intr_ids->hph_left_ocp, true); break; @@ -441,7 +441,8 @@ static void wcd_mbhc_clr_and_turnon_hph_padac(struct wcd_mbhc *mbhc) pr_debug("%s: HPHL ANC clear flag and enable ANC_EN\n", __func__); if (mbhc->mbhc_cb->update_anc_state) - mbhc->mbhc_cb->update_anc_state(mbhc->codec, true, 0); + mbhc->mbhc_cb->update_anc_state(mbhc->component, + true, 0); } if (test_and_clear_bit(WCD_MBHC_ANC1_OFF_ACK, @@ -450,7 +451,8 @@ static void wcd_mbhc_clr_and_turnon_hph_padac(struct wcd_mbhc *mbhc) pr_debug("%s: HPHR ANC clear flag and enable ANC_EN\n", __func__); if (mbhc->mbhc_cb->update_anc_state) - mbhc->mbhc_cb->update_anc_state(mbhc->codec, true, 1); + mbhc->mbhc_cb->update_anc_state(mbhc->component, + true, 1); } } @@ -493,8 +495,10 @@ static void wcd_mbhc_set_and_turnoff_hph_padac(struct wcd_mbhc *mbhc) set_bit(WCD_MBHC_ANC0_OFF_ACK, &mbhc->hph_anc_state); set_bit(WCD_MBHC_ANC1_OFF_ACK, &mbhc->hph_anc_state); if (mbhc->mbhc_cb->update_anc_state) { - mbhc->mbhc_cb->update_anc_state(mbhc->codec, false, 0); - mbhc->mbhc_cb->update_anc_state(mbhc->codec, false, 1); + mbhc->mbhc_cb->update_anc_state(mbhc->component, + false, 0); + mbhc->mbhc_cb->update_anc_state(mbhc->component, + false, 1); } else { pr_debug("%s ANC is off\n", __func__); } @@ -534,7 +538,7 @@ void wcd_mbhc_hs_elec_irq(struct wcd_mbhc *mbhc, int irq_type, pr_debug("%s: irq: %d, enable: %d, intr_status:%lu\n", __func__, irq, enable, mbhc->intr_status); if ((test_bit(irq_type, &mbhc->intr_status)) != enable) { - mbhc->mbhc_cb->irq_control(mbhc->codec, irq, enable); + mbhc->mbhc_cb->irq_control(mbhc->component, irq, enable); if (enable) set_bit(irq_type, &mbhc->intr_status); else @@ -546,7 +550,7 @@ EXPORT_SYMBOL(wcd_mbhc_hs_elec_irq); void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, enum snd_jack_types jack_type) { - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; bool is_pa_on = false; u8 fsm_en = 0; @@ -575,14 +579,14 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, if (mbhc->micbias_enable) { if (mbhc->mbhc_cb->mbhc_micbias_control) mbhc->mbhc_cb->mbhc_micbias_control( - codec, MIC_BIAS_2, + component, MIC_BIAS_2, MICB_DISABLE); if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( - codec, + component, MIC_BIAS_2, false); if (mbhc->mbhc_cb->set_micbias_value) { - mbhc->mbhc_cb->set_micbias_value(codec); + mbhc->mbhc_cb->set_micbias_value(component); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MICB_CTRL, 0); } mbhc->micbias_enable = false; @@ -614,15 +618,15 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, mbhc->hph_status == SND_JACK_HEADSET) { if (mbhc->mbhc_cb->mbhc_micbias_control) mbhc->mbhc_cb->mbhc_micbias_control( - codec, MIC_BIAS_2, + component, MIC_BIAS_2, MICB_DISABLE); if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( - codec, + component, MIC_BIAS_2, false); if (mbhc->mbhc_cb->set_micbias_value) { mbhc->mbhc_cb->set_micbias_value( - codec); + component); WCD_MBHC_REG_UPDATE_BITS( WCD_MBHC_MICB_CTRL, 0); } @@ -672,7 +676,7 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, mbhc->current_plug = MBHC_PLUG_TYPE_ANC_HEADPHONE; if (mbhc->mbhc_cb->hph_pa_on_status) - is_pa_on = mbhc->mbhc_cb->hph_pa_on_status(codec); + is_pa_on = mbhc->mbhc_cb->hph_pa_on_status(component); if (mbhc->impedance_detect && mbhc->mbhc_cb->compute_impedance && @@ -876,10 +880,10 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) { bool detection_type = 0; bool micbias1 = false; - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; enum snd_jack_types jack_type; - dev_dbg(codec->dev, "%s: enter\n", __func__); + dev_dbg(component->dev, "%s: enter\n", __func__); WCD_MBHC_RSC_LOCK(mbhc); mbhc->in_swch_irq_handler = true; @@ -915,10 +919,10 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) goto done; /* Make sure MASTER_BIAS_CTL is enabled */ - mbhc->mbhc_cb->mbhc_bias(codec, true); + mbhc->mbhc_cb->mbhc_bias(component, true); if (mbhc->mbhc_cb->mbhc_common_micb_ctrl) - mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, + mbhc->mbhc_cb->mbhc_common_micb_ctrl(component, MBHC_COMMON_MICB_TAIL_CURR, true); if (!mbhc->mbhc_cfg->hs_ext_micbias && @@ -927,13 +931,13 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) * Enable Tx2 RBias if the headset * is using internal micbias */ - mbhc->mbhc_cb->micb_internal(codec, 1, true); + mbhc->mbhc_cb->micb_internal(component, 1, true); /* Remove micbias pulldown */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_PULLDOWN_CTRL, 0); /* Apply trim if needed on the device */ if (mbhc->mbhc_cb->trim_btn_reg) - mbhc->mbhc_cb->trim_btn_reg(codec); + mbhc->mbhc_cb->trim_btn_reg(component); /* Enable external voltage source to micbias if present */ if (mbhc->mbhc_cb->enable_mb_source) mbhc->mbhc_cb->enable_mb_source(mbhc, true); @@ -950,11 +954,11 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0); if (mbhc->mbhc_cb->mbhc_common_micb_ctrl) - mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec, + mbhc->mbhc_cb->mbhc_common_micb_ctrl(component, MBHC_COMMON_MICB_TAIL_CURR, false); if (mbhc->mbhc_cb->set_cap_mode) - mbhc->mbhc_cb->set_cap_mode(codec, micbias1, false); + mbhc->mbhc_cb->set_cap_mode(component, micbias1, false); mbhc->btn_press_intr = false; mbhc->is_btn_press = false; @@ -968,7 +972,8 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) case MBHC_PLUG_TYPE_HEADSET: /* make sure to turn off Rbias */ if (mbhc->mbhc_cb->micb_internal) - mbhc->mbhc_cb->micb_internal(codec, 1, false); + mbhc->mbhc_cb->micb_internal(component, + 1, false); /* Pulldown micbias */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_PULLDOWN_CTRL, 1); jack_type = SND_JACK_HEADSET; @@ -998,7 +1003,8 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) if (mbhc->mbhc_cfg->enable_usbc_analog) { WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 0); if (mbhc->mbhc_cb->clk_setup) - mbhc->mbhc_cb->clk_setup(mbhc->codec, false); + mbhc->mbhc_cb->clk_setup( + mbhc->component, false); } if (mbhc->mbhc_cfg->moisture_en && @@ -1050,7 +1056,7 @@ int wcd_mbhc_get_button_mask(struct wcd_mbhc *mbhc) int mask = 0; int btn; - btn = mbhc->mbhc_cb->map_btn_code_to_num(mbhc->codec); + btn = mbhc->mbhc_cb->map_btn_code_to_num(mbhc->component); switch (btn) { case 0: @@ -1265,7 +1271,7 @@ static irqreturn_t wcd_mbhc_hphl_ocp_irq(int irq, void *data) WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_OCP_FSM_EN, 0); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_OCP_FSM_EN, 1); } else { - mbhc->mbhc_cb->irq_control(mbhc->codec, + mbhc->mbhc_cb->irq_control(mbhc->component, mbhc->intr_ids->hph_left_ocp, false); mbhc->hph_status |= SND_JACK_OC_HPHL; @@ -1308,7 +1314,7 @@ static irqreturn_t wcd_mbhc_hphr_ocp_irq(int irq, void *data) WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_OCP_FSM_EN, 0); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_OCP_FSM_EN, 1); } else { - mbhc->mbhc_cb->irq_control(mbhc->codec, + mbhc->mbhc_cb->irq_control(mbhc->component, mbhc->intr_ids->hph_right_ocp, false); mbhc->hph_status |= SND_JACK_OC_HPHR; @@ -1322,17 +1328,17 @@ static irqreturn_t wcd_mbhc_hphr_ocp_irq(int irq, void *data) static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) { int ret = 0; - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; pr_debug("%s: enter\n", __func__); WCD_MBHC_RSC_LOCK(mbhc); /* enable HS detection */ if (mbhc->mbhc_cb->hph_pull_up_control_v2) - mbhc->mbhc_cb->hph_pull_up_control_v2(codec, + mbhc->mbhc_cb->hph_pull_up_control_v2(component, HS_PULLUP_I_DEFAULT); else if (mbhc->mbhc_cb->hph_pull_up_control) - mbhc->mbhc_cb->hph_pull_up_control(codec, I_DEFAULT); + mbhc->mbhc_cb->hph_pull_up_control(component, I_DEFAULT); else WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, 3); @@ -1350,10 +1356,10 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) mbhc->gnd_swh = 0; if (mbhc->mbhc_cb->hph_pull_up_control_v2) - mbhc->mbhc_cb->hph_pull_up_control_v2(codec, + mbhc->mbhc_cb->hph_pull_up_control_v2(component, HS_PULLUP_I_OFF); else if (mbhc->mbhc_cb->hph_pull_up_control) - mbhc->mbhc_cb->hph_pull_up_control(codec, I_OFF); + mbhc->mbhc_cb->hph_pull_up_control(component, I_OFF); else WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, 0); @@ -1363,7 +1369,7 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_GND_PLUG_TYPE, mbhc->gnd_swh); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_SW_HPH_LP_100K_TO_GND, 1); if (mbhc->mbhc_cfg->gnd_det_en && mbhc->mbhc_cb->mbhc_gnd_det_ctrl) - mbhc->mbhc_cb->mbhc_gnd_det_ctrl(codec, true); + mbhc->mbhc_cb->mbhc_gnd_det_ctrl(component, true); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL, 1); /* @@ -1389,15 +1395,15 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) /* Enable micbias ramp */ if (mbhc->mbhc_cb->mbhc_micb_ramp_control) - mbhc->mbhc_cb->mbhc_micb_ramp_control(codec, true); + mbhc->mbhc_cb->mbhc_micb_ramp_control(component, true); /* enable bias */ - mbhc->mbhc_cb->mbhc_bias(codec, true); + mbhc->mbhc_cb->mbhc_bias(component, true); /* enable MBHC clock */ if (mbhc->mbhc_cb->clk_setup) { if (mbhc->mbhc_cfg->enable_usbc_analog) - mbhc->mbhc_cb->clk_setup(codec, false); + mbhc->mbhc_cb->clk_setup(component, false); else - mbhc->mbhc_cb->clk_setup(codec, true); + mbhc->mbhc_cb->clk_setup(component, true); } /* program HS_VREF value */ @@ -1417,7 +1423,7 @@ static void wcd_mbhc_fw_read(struct work_struct *work) { struct delayed_work *dwork; struct wcd_mbhc *mbhc; - struct snd_soc_codec *codec; + struct snd_soc_component *component; const struct firmware *fw; struct firmware_cal *fw_data = NULL; int ret = -1, retry = 0; @@ -1425,7 +1431,7 @@ static void wcd_mbhc_fw_read(struct work_struct *work) dwork = to_delayed_work(work); mbhc = container_of(dwork, struct wcd_mbhc, mbhc_firmware_dwork); - codec = mbhc->codec; + component = mbhc->component; while (retry < FW_READ_ATTEMPTS) { retry++; @@ -1436,7 +1442,7 @@ static void wcd_mbhc_fw_read(struct work_struct *work) WCD9XXX_MBHC_CAL); if (!fw_data) ret = request_firmware(&fw, "wcd9320/wcd9320_mbhc.bin", - codec->dev); + component->dev); /* * if request_firmware and hwdep cal both fail then * sleep for 4sec for the userspace to send data to kernel @@ -1557,11 +1563,11 @@ static int wcd_mbhc_usbc_ana_event_handler(struct notifier_block *nb, if (!mbhc) return -EINVAL; - dev_dbg(mbhc->codec->dev, "%s: mode = %lu\n", __func__, mode); + dev_dbg(mbhc->component->dev, "%s: mode = %lu\n", __func__, mode); if (mode == POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) { if (mbhc->mbhc_cb->clk_setup) - mbhc->mbhc_cb->clk_setup(mbhc->codec, true); + mbhc->mbhc_cb->clk_setup(mbhc->component, true); /* insertion detected, enable L_DET_EN */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1); } @@ -1571,20 +1577,20 @@ static int wcd_mbhc_usbc_ana_event_handler(struct notifier_block *nb, int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) { int rc = 0; - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct snd_soc_card *card; const char *usb_c_dt = "qcom,msm-mbhc-usbc-audio-supported"; if (!mbhc || !mbhc_cfg) return -EINVAL; - codec = mbhc->codec; - card = codec->component.card; + component = mbhc->component; + card = component->card; /* update the mbhc config */ mbhc->mbhc_cfg = mbhc_cfg; - dev_dbg(mbhc->codec->dev, "%s: enter\n", __func__); + dev_dbg(mbhc->component->dev, "%s: enter\n", __func__); /* check if USB C analog is defined on device tree */ mbhc_cfg->enable_usbc_analog = 0; @@ -1602,7 +1608,7 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) /* Parse fsa switch handle */ if (mbhc_cfg->enable_usbc_analog) { - dev_dbg(mbhc->codec->dev, "%s: usbc analog enabled\n", + dev_dbg(mbhc->component->dev, "%s: usbc analog enabled\n", __func__); mbhc->swap_thr = GND_MIC_USBC_SWAP_THRESHOLD; mbhc->fsa_np = of_parse_phandle(card->dev->of_node, @@ -1645,7 +1651,7 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg) return rc; err: - dev_dbg(mbhc->codec->dev, "%s: leave %d\n", __func__, rc); + dev_dbg(mbhc->component->dev, "%s: leave %d\n", __func__, rc); return rc; } EXPORT_SYMBOL(wcd_mbhc_start); @@ -1656,15 +1662,15 @@ void wcd_mbhc_stop(struct wcd_mbhc *mbhc) if (mbhc->current_plug != MBHC_PLUG_TYPE_NONE) { if (mbhc->mbhc_cb && mbhc->mbhc_cb->skip_imped_detect) - mbhc->mbhc_cb->skip_imped_detect(mbhc->codec); + mbhc->mbhc_cb->skip_imped_detect(mbhc->component); } mbhc->current_plug = MBHC_PLUG_TYPE_NONE; mbhc->hph_status = 0; if (mbhc->mbhc_cb && mbhc->mbhc_cb->irq_control) { - mbhc->mbhc_cb->irq_control(mbhc->codec, + mbhc->mbhc_cb->irq_control(mbhc->component, mbhc->intr_ids->hph_left_ocp, false); - mbhc->mbhc_cb->irq_control(mbhc->codec, + mbhc->mbhc_cb->irq_control(mbhc->component, mbhc->intr_ids->hph_right_ocp, false); } @@ -1688,7 +1694,7 @@ EXPORT_SYMBOL(wcd_mbhc_stop); * * NOTE: mbhc->mbhc_cfg is not YET configure so shouldn't be used */ -int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, +int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_component *component, const struct wcd_mbhc_cb *mbhc_cb, const struct wcd_mbhc_intr *mbhc_cdc_intr_ids, struct wcd_mbhc_register *wcd_mbhc_regs, @@ -1698,7 +1704,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, int hph_swh = 0; int gnd_swh = 0; u32 hph_moist_config[3]; - struct snd_soc_card *card = codec->component.card; + struct snd_soc_card *card = component->card; const char *hph_switch = "qcom,msm-mbhc-hphl-swh"; const char *gnd_switch = "qcom,msm-mbhc-gnd-swh"; const char *hs_thre = "qcom,msm-mbhc-hs-mic-max-threshold-mv"; @@ -1750,7 +1756,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, mbhc->in_swch_irq_handler = false; mbhc->current_plug = MBHC_PLUG_TYPE_NONE; mbhc->is_btn_press = false; - mbhc->codec = codec; + mbhc->component = component; mbhc->intr_ids = mbhc_cdc_intr_ids; mbhc->impedance_detect = impedance_det_en; mbhc->hphl_swh = hph_swh; @@ -1770,7 +1776,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, return -EINVAL; } if (!mbhc->wcd_mbhc_regs) { - dev_err(codec->dev, "%s: mbhc registers are not defined\n", + dev_err(component->dev, "%s: mbhc registers are not defined\n", __func__); return -EINVAL; } @@ -1780,14 +1786,14 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, !mbhc_cb->free_irq || !mbhc_cb->map_btn_code_to_num || !mbhc_cb->lock_sleep || !mbhc_cb->mbhc_bias || !mbhc_cb->set_btn_thr) { - dev_err(codec->dev, "%s: required mbhc callbacks are not defined\n", + dev_err(component->dev, "%s: required mbhc callbacks are not defined\n", __func__); return -EINVAL; } /* No need to create new sound card jacks if is is already created */ if (mbhc->headset_jack.jack == NULL) { - ret = snd_soc_card_jack_new(codec->component.card, + ret = snd_soc_card_jack_new(component->card, "Headset Jack", WCD_MBHC_JACK_MASK, &mbhc->headset_jack, NULL, 0); if (ret) { @@ -1795,7 +1801,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, return ret; } - ret = snd_soc_card_jack_new(codec->component.card, + ret = snd_soc_card_jack_new(component->card, "Button Jack", WCD_MBHC_JACK_BUTTON_MASK, &mbhc->button_jack, NULL, 0); @@ -1857,16 +1863,17 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, pr_err("%s: mbhc function pointer is NULL\n", __func__); goto err_mbhc_sw_irq; } - ret = mbhc->mbhc_cb->request_irq(codec, mbhc->intr_ids->mbhc_sw_intr, - wcd_mbhc_mech_plug_detect_irq, - "mbhc sw intr", mbhc); + ret = mbhc->mbhc_cb->request_irq(component, + mbhc->intr_ids->mbhc_sw_intr, + wcd_mbhc_mech_plug_detect_irq, + "mbhc sw intr", mbhc); if (ret) { pr_err("%s: Failed to request irq %d, ret = %d\n", __func__, mbhc->intr_ids->mbhc_sw_intr, ret); goto err_mbhc_sw_irq; } - ret = mbhc->mbhc_cb->request_irq(codec, + ret = mbhc->mbhc_cb->request_irq(component, mbhc->intr_ids->mbhc_btn_press_intr, wcd_mbhc_btn_press_handler, "Button Press detect", mbhc); @@ -1876,7 +1883,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, goto err_btn_press_irq; } - ret = mbhc->mbhc_cb->request_irq(codec, + ret = mbhc->mbhc_cb->request_irq(component, mbhc->intr_ids->mbhc_btn_release_intr, wcd_mbhc_release_handler, "Button Release detect", mbhc); @@ -1886,7 +1893,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, goto err_btn_release_irq; } - ret = mbhc->mbhc_cb->request_irq(codec, + ret = mbhc->mbhc_cb->request_irq(component, mbhc->intr_ids->mbhc_hs_ins_intr, mbhc->mbhc_fn->wcd_mbhc_hs_ins_irq, "Elect Insert", mbhc); @@ -1895,11 +1902,11 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, mbhc->intr_ids->mbhc_hs_ins_intr); goto err_mbhc_hs_ins_irq; } - mbhc->mbhc_cb->irq_control(codec, mbhc->intr_ids->mbhc_hs_ins_intr, + mbhc->mbhc_cb->irq_control(component, mbhc->intr_ids->mbhc_hs_ins_intr, false); clear_bit(WCD_MBHC_ELEC_HS_INS, &mbhc->intr_status); - ret = mbhc->mbhc_cb->request_irq(codec, + ret = mbhc->mbhc_cb->request_irq(component, mbhc->intr_ids->mbhc_hs_rem_intr, mbhc->mbhc_fn->wcd_mbhc_hs_rem_irq, "Elect Remove", mbhc); @@ -1908,22 +1915,24 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, mbhc->intr_ids->mbhc_hs_rem_intr); goto err_mbhc_hs_rem_irq; } - mbhc->mbhc_cb->irq_control(codec, mbhc->intr_ids->mbhc_hs_rem_intr, + mbhc->mbhc_cb->irq_control(component, mbhc->intr_ids->mbhc_hs_rem_intr, false); clear_bit(WCD_MBHC_ELEC_HS_REM, &mbhc->intr_status); - ret = mbhc->mbhc_cb->request_irq(codec, mbhc->intr_ids->hph_left_ocp, - wcd_mbhc_hphl_ocp_irq, "HPH_L OCP detect", - mbhc); + ret = mbhc->mbhc_cb->request_irq(component, + mbhc->intr_ids->hph_left_ocp, + wcd_mbhc_hphl_ocp_irq, "HPH_L OCP detect", + mbhc); if (ret) { pr_err("%s: Failed to request irq %d\n", __func__, mbhc->intr_ids->hph_left_ocp); goto err_hphl_ocp_irq; } - ret = mbhc->mbhc_cb->request_irq(codec, mbhc->intr_ids->hph_right_ocp, - wcd_mbhc_hphr_ocp_irq, "HPH_R OCP detect", - mbhc); + ret = mbhc->mbhc_cb->request_irq(component, + mbhc->intr_ids->hph_right_ocp, + wcd_mbhc_hphr_ocp_irq, "HPH_R OCP detect", + mbhc); if (ret) { pr_err("%s: Failed to request irq %d\n", __func__, mbhc->intr_ids->hph_right_ocp); @@ -1935,19 +1944,22 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, return ret; err_hphr_ocp_irq: - mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->hph_left_ocp, mbhc); + mbhc->mbhc_cb->free_irq(component, mbhc->intr_ids->hph_left_ocp, mbhc); err_hphl_ocp_irq: - mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_hs_rem_intr, mbhc); + mbhc->mbhc_cb->free_irq(component, mbhc->intr_ids->mbhc_hs_rem_intr, + mbhc); err_mbhc_hs_rem_irq: - mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_hs_ins_intr, mbhc); + mbhc->mbhc_cb->free_irq(component, mbhc->intr_ids->mbhc_hs_ins_intr, + mbhc); err_mbhc_hs_ins_irq: - mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_btn_release_intr, + mbhc->mbhc_cb->free_irq(component, + mbhc->intr_ids->mbhc_btn_release_intr, mbhc); err_btn_release_irq: - mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_btn_press_intr, + mbhc->mbhc_cb->free_irq(component, mbhc->intr_ids->mbhc_btn_press_intr, mbhc); err_btn_press_irq: - mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_sw_intr, mbhc); + mbhc->mbhc_cb->free_irq(component, mbhc->intr_ids->mbhc_sw_intr, mbhc); err_mbhc_sw_irq: if (mbhc->mbhc_cb->register_notifier) mbhc->mbhc_cb->register_notifier(mbhc, &mbhc->nblock, false); @@ -1960,17 +1972,20 @@ EXPORT_SYMBOL(wcd_mbhc_init); void wcd_mbhc_deinit(struct wcd_mbhc *mbhc) { - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; - mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_sw_intr, mbhc); - mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_btn_press_intr, + mbhc->mbhc_cb->free_irq(component, mbhc->intr_ids->mbhc_sw_intr, mbhc); + mbhc->mbhc_cb->free_irq(component, mbhc->intr_ids->mbhc_btn_press_intr, + mbhc); + mbhc->mbhc_cb->free_irq(component, + mbhc->intr_ids->mbhc_btn_release_intr, + mbhc); + mbhc->mbhc_cb->free_irq(component, mbhc->intr_ids->mbhc_hs_ins_intr, mbhc); - mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_btn_release_intr, + mbhc->mbhc_cb->free_irq(component, mbhc->intr_ids->mbhc_hs_rem_intr, mbhc); - mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_hs_ins_intr, mbhc); - mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->mbhc_hs_rem_intr, mbhc); - mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->hph_left_ocp, mbhc); - mbhc->mbhc_cb->free_irq(codec, mbhc->intr_ids->hph_right_ocp, mbhc); + mbhc->mbhc_cb->free_irq(component, mbhc->intr_ids->hph_left_ocp, mbhc); + mbhc->mbhc_cb->free_irq(component, mbhc->intr_ids->hph_right_ocp, mbhc); if (mbhc->mbhc_cb && mbhc->mbhc_cb->register_notifier) mbhc->mbhc_cb->register_notifier(mbhc, &mbhc->nblock, false); if (mbhc->mbhc_fn->wcd_cancel_hs_detect_plug) { diff --git a/asoc/codecs/wcd-mbhc-v2.h b/asoc/codecs/wcd-mbhc-v2.h index 6915344ae08d..451ca91cd816 100644 --- a/asoc/codecs/wcd-mbhc-v2.h +++ b/asoc/codecs/wcd-mbhc-v2.h @@ -51,7 +51,7 @@ #define WCD_MBHC_REG_UPDATE_BITS(function, val) \ do { \ if (mbhc->wcd_mbhc_regs[function].reg) { \ - snd_soc_update_bits(mbhc->codec, \ + snd_soc_component_update_bits(mbhc->component, \ mbhc->wcd_mbhc_regs[function].reg, \ mbhc->wcd_mbhc_regs[function].mask, \ val << (mbhc->wcd_mbhc_regs[function].offset)); \ @@ -61,7 +61,7 @@ do { \ #define WCD_MBHC_REG_READ(function, val) \ do { \ if (mbhc->wcd_mbhc_regs[function].reg) { \ - val = (((snd_soc_read(mbhc->codec, \ + val = (((snd_soc_component_read32(mbhc->component, \ mbhc->wcd_mbhc_regs[function].reg)) & \ (mbhc->wcd_mbhc_regs[function].mask)) >> \ (mbhc->wcd_mbhc_regs[function].offset)); \ @@ -420,7 +420,7 @@ struct wcd_mbhc_config { void *calibration; bool detect_extn_cable; bool mono_stero_detection; - bool (*swap_gnd_mic)(struct snd_soc_codec *codec, bool active); + bool (*swap_gnd_mic)(struct snd_soc_component *component, bool active); bool hs_ext_micbias; bool gnd_det_en; int key_code[WCD_MBHC_KEYCODE_NUM]; @@ -452,53 +452,64 @@ struct wcd_mbhc_register { }; struct wcd_mbhc_cb { - int (*enable_mb_source)(struct wcd_mbhc *, bool); - void (*trim_btn_reg)(struct snd_soc_codec *); - void (*compute_impedance)(struct wcd_mbhc *, uint32_t *, uint32_t *); - void (*set_micbias_value)(struct snd_soc_codec *); - void (*set_auto_zeroing)(struct snd_soc_codec *, bool); - struct firmware_cal * (*get_hwdep_fw_cal)(struct wcd_mbhc *, + int (*enable_mb_source)(struct wcd_mbhc *mbhc, bool turn_on); + void (*trim_btn_reg)(struct snd_soc_component *component); + void (*compute_impedance)(struct wcd_mbhc *mbhc, + uint32_t *zl, uint32_t *zr); + void (*set_micbias_value)(struct snd_soc_component *component); + void (*set_auto_zeroing)(struct snd_soc_component *component, + bool enable); + struct firmware_cal * (*get_hwdep_fw_cal)(struct wcd_mbhc *mbhc, enum wcd_cal_type); - void (*set_cap_mode)(struct snd_soc_codec *, bool, bool); - int (*register_notifier)(struct wcd_mbhc *, + void (*set_cap_mode)(struct snd_soc_component *component, + bool micbias1, bool micbias2); + int (*register_notifier)(struct wcd_mbhc *mbhc, struct notifier_block *nblock, bool enable); - int (*request_irq)(struct snd_soc_codec *, - int, irq_handler_t, const char *, void *); - void (*irq_control)(struct snd_soc_codec *, + int (*request_irq)(struct snd_soc_component *component, + int irq, irq_handler_t handler, + const char *name, void *data); + void (*irq_control)(struct snd_soc_component *component, int irq, bool enable); - int (*free_irq)(struct snd_soc_codec *, - int irq, void *); - void (*clk_setup)(struct snd_soc_codec *, bool); - int (*map_btn_code_to_num)(struct snd_soc_codec *); - bool (*lock_sleep)(struct wcd_mbhc *, bool); - bool (*micbias_enable_status)(struct wcd_mbhc *, int); - void (*mbhc_bias)(struct snd_soc_codec *, bool); - void (*mbhc_common_micb_ctrl)(struct snd_soc_codec *, - int event, bool); - void (*micb_internal)(struct snd_soc_codec *, - int micb_num, bool); - bool (*hph_pa_on_status)(struct snd_soc_codec *); - void (*set_btn_thr)(struct snd_soc_codec *, s16 *, s16 *, - int num_btn, bool); - void (*hph_pull_up_control)(struct snd_soc_codec *, + int (*free_irq)(struct snd_soc_component *component, + int irq, void *data); + void (*clk_setup)(struct snd_soc_component *component, bool enable); + int (*map_btn_code_to_num)(struct snd_soc_component *component); + bool (*lock_sleep)(struct wcd_mbhc *mbhc, bool lock); + bool (*micbias_enable_status)(struct wcd_mbhc *mbhc, int micb_num); + void (*mbhc_bias)(struct snd_soc_component *component, bool enable); + void (*mbhc_common_micb_ctrl)(struct snd_soc_component *component, + int event, bool enable); + void (*micb_internal)(struct snd_soc_component *component, + int micb_num, bool enable); + bool (*hph_pa_on_status)(struct snd_soc_component *component); + void (*set_btn_thr)(struct snd_soc_component *component, + s16 *btn_low, s16 *btn_high, + int num_btn, bool is_micbias); + void (*hph_pull_up_control)(struct snd_soc_component *component, enum mbhc_hs_pullup_iref); - int (*mbhc_micbias_control)(struct snd_soc_codec *, int, int req); - void (*mbhc_micb_ramp_control)(struct snd_soc_codec *, bool); - void (*skip_imped_detect)(struct snd_soc_codec *); - bool (*extn_use_mb)(struct snd_soc_codec *); - int (*mbhc_micb_ctrl_thr_mic)(struct snd_soc_codec *, int, bool); - void (*mbhc_gnd_det_ctrl)(struct snd_soc_codec *, bool); - void (*hph_pull_down_ctrl)(struct snd_soc_codec *, bool); - void (*mbhc_moisture_config)(struct wcd_mbhc *); - bool (*hph_register_recovery)(struct wcd_mbhc *); - void (*update_anc_state)(struct snd_soc_codec *codec, - bool enable, int anc_num); + int (*mbhc_micbias_control)(struct snd_soc_component *component, + int micb_num, int req); + void (*mbhc_micb_ramp_control)(struct snd_soc_component *component, + bool enable); + void (*skip_imped_detect)(struct snd_soc_component *component); + bool (*extn_use_mb)(struct snd_soc_component *component); + int (*mbhc_micb_ctrl_thr_mic)(struct snd_soc_component *component, + int micb_num, bool req_en); + void (*mbhc_gnd_det_ctrl)(struct snd_soc_component *component, + bool enable); + void (*hph_pull_down_ctrl)(struct snd_soc_component *component, + bool enable); + void (*mbhc_moisture_config)(struct wcd_mbhc *mbhc); + bool (*hph_register_recovery)(struct wcd_mbhc *mbhc); + void (*update_anc_state)(struct snd_soc_component *component, + bool enable, int anc_num); bool (*is_anc_on)(struct wcd_mbhc *mbhc); - void (*hph_pull_up_control_v2)(struct snd_soc_codec *, int); - bool (*mbhc_get_moisture_status)(struct wcd_mbhc *); - void (*mbhc_moisture_polling_ctrl)(struct wcd_mbhc *, bool); - void (*mbhc_moisture_detect_en)(struct wcd_mbhc *, bool); + void (*hph_pull_up_control_v2)(struct snd_soc_component *component, + int pull_up_cur); + bool (*mbhc_get_moisture_status)(struct wcd_mbhc *mbhc); + void (*mbhc_moisture_polling_ctrl)(struct wcd_mbhc *mbhc, bool enable); + void (*mbhc_moisture_detect_en)(struct wcd_mbhc *mbhc, bool enable); }; struct wcd_mbhc_fn { @@ -544,7 +555,7 @@ struct wcd_mbhc { bool is_btn_already_regd; bool extn_cable_hph_rem; - struct snd_soc_codec *codec; + struct snd_soc_component *component; /* Work to perform MBHC Firmware Read */ struct delayed_work mbhc_firmware_dwork; const struct firmware *mbhc_fw; diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index afd8c5d62e94..740f232b709f 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -41,6 +41,8 @@ #include "wcdcal-hwdep.h" #include "wcd-mbhc-v2-api.h" +#define DRV_NAME "tasha_codec" + #define TASHA_RX_PORT_START_NUMBER 16 #define WCD9335_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ @@ -547,9 +549,9 @@ static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); static struct snd_soc_dai_driver tasha_dai[]; static int wcd9335_get_micb_vout_ctl_val(u32 micb_mv); -static int tasha_config_compander(struct snd_soc_codec *, int, int); -static void tasha_codec_set_tx_hold(struct snd_soc_codec *, u16, bool); -static int tasha_codec_internal_rco_ctrl(struct snd_soc_codec *codec, +static int tasha_config_compander(struct snd_soc_component *, int, int); +static void tasha_codec_set_tx_hold(struct snd_soc_component *, u16, bool); +static int tasha_codec_internal_rco_ctrl(struct snd_soc_component *component, bool enable); /* Hold instance to soundwire platform device */ @@ -699,7 +701,7 @@ struct tasha_priv { struct device *dev; struct wcd9xxx *wcd9xxx; - struct snd_soc_codec *codec; + struct snd_soc_component *component; u32 adc_count; u32 rx_bias_count; s32 dmic_0_1_clk_cnt; @@ -797,7 +799,7 @@ struct tasha_priv { struct mutex swr_clk_lock; int swr_clk_users; int native_clk_users; - int (*zdet_gpio_cb)(struct snd_soc_codec *codec, bool high); + int (*zdet_gpio_cb)(struct snd_soc_component *component, bool high); struct snd_info_entry *entry; struct snd_info_entry *version_entry; @@ -805,7 +807,7 @@ struct tasha_priv { struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX]; - int (*machine_codec_event_cb)(struct snd_soc_codec *codec, + int (*machine_codec_event_cb)(struct snd_soc_component *component, enum wcd9335_codec_event); int spkr_gain_offset; int spkr_mode; @@ -832,7 +834,7 @@ struct tasha_priv { int child_count; }; -static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec, +static int tasha_codec_vote_max_bw(struct snd_soc_component *component, bool vote); static const struct tasha_reg_mask_val tasha_spkr_default[] = { @@ -857,14 +859,14 @@ static const struct tasha_reg_mask_val tasha_spkr_mode1[] = { * tasha_set_spkr_gain_offset - offset the speaker path * gain with the given offset value. * - * @codec: codec instance + * @component: codec component instance * @offset: Indicates speaker path gain offset value. * * Returns 0 on success or -EINVAL on error. */ -int tasha_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset) +int tasha_set_spkr_gain_offset(struct snd_soc_component *component, int offset) { - struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *priv = snd_soc_component_get_drvdata(component); if (!priv) return -EINVAL; @@ -878,14 +880,14 @@ EXPORT_SYMBOL(tasha_set_spkr_gain_offset); * tasha_set_spkr_mode - Configures speaker compander and smartboost * settings based on speaker mode. * - * @codec: codec instance + * @component: codec component instance * @mode: Indicates speaker configuration mode. * * Returns 0 on success or -EINVAL on error. */ -int tasha_set_spkr_mode(struct snd_soc_codec *codec, int mode) +int tasha_set_spkr_mode(struct snd_soc_component *component, int mode) { - struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *priv = snd_soc_component_get_drvdata(component); int i; const struct tasha_reg_mask_val *regs; int size; @@ -906,21 +908,23 @@ int tasha_set_spkr_mode(struct snd_soc_codec *codec, int mode) priv->spkr_mode = mode; for (i = 0; i < size; i++) - snd_soc_update_bits(codec, regs[i].reg, + snd_soc_component_update_bits(component, regs[i].reg, regs[i].mask, regs[i].val); return 0; } EXPORT_SYMBOL(tasha_set_spkr_mode); -static void tasha_enable_sido_buck(struct snd_soc_codec *codec) +static void tasha_enable_sido_buck(struct snd_soc_component *component) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); - snd_soc_update_bits(codec, WCD9335_ANA_RCO, 0x80, 0x80); - snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, 0x02, 0x02); + snd_soc_component_update_bits(component, WCD9335_ANA_RCO, 0x80, 0x80); + snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL, + 0x02, 0x02); /* 100us sleep needed after IREF settings */ usleep_range(100, 110); - snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, 0x04, 0x04); + snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL, + 0x04, 0x04); /* 100us sleep needed after VREF settings */ usleep_range(100, 110); tasha->resmgr->sido_input_src = SIDO_SOURCE_RCO_BG; @@ -928,30 +932,30 @@ static void tasha_enable_sido_buck(struct snd_soc_codec *codec) static void tasha_cdc_sido_ccl_enable(struct tasha_priv *tasha, bool ccl_flag) { - struct snd_soc_codec *codec = tasha->codec; + struct snd_soc_component *component = tasha->component; - if (!codec) + if (!component) return; if (!TASHA_IS_2_0(tasha->wcd9xxx)) { - dev_dbg(codec->dev, "%s: tasha version < 2p0, return\n", + dev_dbg(component->dev, "%s: tasha version < 2p0, return\n", __func__); return; } - dev_dbg(codec->dev, "%s: sido_ccl_cnt=%d, ccl_flag:%d\n", + dev_dbg(component->dev, "%s: sido_ccl_cnt=%d, ccl_flag:%d\n", __func__, tasha->sido_ccl_cnt, ccl_flag); if (ccl_flag) { if (++tasha->sido_ccl_cnt == 1) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_SIDO_SIDO_CCL_10, 0xFF, 0x6E); } else { if (tasha->sido_ccl_cnt == 0) { - dev_dbg(codec->dev, "%s: sido_ccl already disabled\n", + dev_dbg(component->dev, "%s: sido_ccl already disabled\n", __func__); return; } if (--tasha->sido_ccl_cnt == 0) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_SIDO_SIDO_CCL_10, 0xFF, 0x02); } } @@ -1010,10 +1014,10 @@ static void tasha_codec_apply_sido_voltage( enum tasha_sido_voltage req_mv) { u32 vout_d_val; - struct snd_soc_codec *codec = tasha->codec; + struct snd_soc_component *component = tasha->component; int ret; - if (!codec) + if (!component) return; if (!tasha_cdc_is_svs_enabled(tasha)) @@ -1025,19 +1029,19 @@ static void tasha_codec_apply_sido_voltage( ret = tasha_cdc_check_sido_value(req_mv); if (ret < 0) { - dev_dbg(codec->dev, "%s: requested mv=%d not in range\n", + dev_dbg(component->dev, "%s: requested mv=%d not in range\n", __func__, req_mv); return; } if (req_mv == tasha->sido_voltage) { - dev_dbg(codec->dev, "%s: Already at requested mv=%d\n", + dev_dbg(component->dev, "%s: Already at requested mv=%d\n", __func__, req_mv); return; } if (req_mv == sido_buck_svs_voltage) { if (test_bit(AUDIO_NOMINAL, &tasha->status_mask) || test_bit(CPE_NOMINAL, &tasha->status_mask)) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: nominal client running, status_mask=%lu\n", __func__, tasha->status_mask); return; @@ -1045,17 +1049,19 @@ static void tasha_codec_apply_sido_voltage( } /* compute the vout_d step value */ vout_d_val = CALCULATE_VOUT_D(req_mv); - snd_soc_write(codec, WCD9335_ANA_BUCK_VOUT_D, vout_d_val & 0xFF); - snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, 0x80, 0x80); + snd_soc_component_write(component, WCD9335_ANA_BUCK_VOUT_D, + vout_d_val & 0xFF); + snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL, + 0x80, 0x80); /* 1 msec sleep required after SIDO Vout_D voltage change */ usleep_range(1000, 1100); tasha->sido_voltage = req_mv; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: updated SIDO buck Vout_D to %d, vout_d step = %u\n", __func__, tasha->sido_voltage, vout_d_val); - snd_soc_update_bits(codec, WCD9335_ANA_BUCK_CTL, + snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL, 0x80, 0x00); } @@ -1084,43 +1090,47 @@ static int tasha_codec_update_sido_voltage( return ret; } -int tasha_enable_efuse_sensing(struct snd_soc_codec *codec) +int tasha_enable_efuse_sensing(struct snd_soc_component *component) { - struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *priv = snd_soc_component_get_drvdata(component); - tasha_cdc_mclk_enable(codec, true, false); + tasha_cdc_mclk_enable(component, true, false); if (!TASHA_IS_2_0(priv->wcd9xxx)) - snd_soc_update_bits(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, - 0x1E, 0x02); - snd_soc_update_bits(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, - 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, + 0x1E, 0x02); + snd_soc_component_update_bits(component, + WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, + 0x01, 0x01); /* * 5ms sleep required after enabling efuse control * before checking the status. */ usleep_range(5000, 5500); - if (!(snd_soc_read(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS) & 0x01)) + if (!(snd_soc_component_read32( + component, WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS) & 0x01)) WARN(1, "%s: Efuse sense is not complete\n", __func__); if (TASHA_IS_2_0(priv->wcd9xxx)) { - if (!(snd_soc_read(codec, + if (!(snd_soc_component_read32(component, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0) & 0x40)) - snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST, - 0x04, 0x00); - tasha_enable_sido_buck(codec); + snd_soc_component_update_bits(component, + WCD9335_HPH_R_ATEST, + 0x04, 0x00); + tasha_enable_sido_buck(component); } - tasha_cdc_mclk_enable(codec, false, false); + tasha_cdc_mclk_enable(component, false, false); return 0; } EXPORT_SYMBOL(tasha_enable_efuse_sensing); -void *tasha_get_afe_config(struct snd_soc_codec *codec, +void *tasha_get_afe_config(struct snd_soc_component *component, enum afe_config_type config_type) { - struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *priv = snd_soc_component_get_drvdata(component); switch (config_type) { case AFE_SLIMBUS_SLAVE_CONFIG: @@ -1138,7 +1148,7 @@ void *tasha_get_afe_config(struct snd_soc_codec *codec, case AFE_CDC_REGISTER_PAGE_CONFIG: return &tasha_cdc_reg_page_cfg; default: - dev_err(codec->dev, "%s: Unknown config_type 0x%x\n", + dev_err(component->dev, "%s: Unknown config_type 0x%x\n", __func__, config_type); return NULL; } @@ -1152,29 +1162,30 @@ EXPORT_SYMBOL(tasha_get_afe_config); * codec driver once codec comes out of reset after ADSP SSR. * * @machine_event_cb: callback function from machine driver - * @codec: Codec instance + * @component: Codec component instance * * Return: none */ void tasha_event_register( - int (*machine_event_cb)(struct snd_soc_codec *codec, + int (*machine_event_cb)(struct snd_soc_component *component, enum wcd9335_codec_event), - struct snd_soc_codec *codec) + struct snd_soc_component *component) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); if (tasha) tasha->machine_codec_event_cb = machine_event_cb; else - dev_dbg(codec->dev, "%s: Invalid tasha_priv data\n", __func__); + dev_dbg(component->dev, "%s: Invalid tasha_priv data\n", + __func__); } EXPORT_SYMBOL(tasha_event_register); -static int tasha_mbhc_request_irq(struct snd_soc_codec *codec, +static int tasha_mbhc_request_irq(struct snd_soc_component *component, int irq, irq_handler_t handler, const char *name, void *data) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; @@ -1182,10 +1193,10 @@ static int tasha_mbhc_request_irq(struct snd_soc_codec *codec, return wcd9xxx_request_irq(core_res, irq, handler, name, data); } -static void tasha_mbhc_irq_control(struct snd_soc_codec *codec, +static void tasha_mbhc_irq_control(struct snd_soc_component *component, int irq, bool enable) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; @@ -1195,10 +1206,10 @@ static void tasha_mbhc_irq_control(struct snd_soc_codec *codec, wcd9xxx_disable_irq(core_res, irq); } -static int tasha_mbhc_free_irq(struct snd_soc_codec *codec, +static int tasha_mbhc_free_irq(struct snd_soc_component *component, int irq, void *data) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; @@ -1207,34 +1218,35 @@ static int tasha_mbhc_free_irq(struct snd_soc_codec *codec, return 0; } -static void tasha_mbhc_clk_setup(struct snd_soc_codec *codec, +static void tasha_mbhc_clk_setup(struct snd_soc_component *component, bool enable) { if (enable) - snd_soc_update_bits(codec, WCD9335_MBHC_CTL_1, + snd_soc_component_update_bits(component, WCD9335_MBHC_CTL_1, 0x80, 0x80); else - snd_soc_update_bits(codec, WCD9335_MBHC_CTL_1, + snd_soc_component_update_bits(component, WCD9335_MBHC_CTL_1, 0x80, 0x00); } -static int tasha_mbhc_btn_to_num(struct snd_soc_codec *codec) +static int tasha_mbhc_btn_to_num(struct snd_soc_component *component) { - return snd_soc_read(codec, WCD9335_ANA_MBHC_RESULT_3) & 0x7; + return snd_soc_component_read32( + component, WCD9335_ANA_MBHC_RESULT_3) & 0x7; } -static void tasha_mbhc_mbhc_bias_control(struct snd_soc_codec *codec, +static void tasha_mbhc_mbhc_bias_control(struct snd_soc_component *component, bool enable) { if (enable) - snd_soc_update_bits(codec, WCD9335_ANA_MBHC_ELECT, + snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_ELECT, 0x01, 0x01); else - snd_soc_update_bits(codec, WCD9335_ANA_MBHC_ELECT, + snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_ELECT, 0x01, 0x00); } -static void tasha_mbhc_program_btn_thr(struct snd_soc_codec *codec, +static void tasha_mbhc_program_btn_thr(struct snd_soc_component *component, s16 *btn_low, s16 *btn_high, int num_btn, bool is_micbias) { @@ -1242,7 +1254,7 @@ static void tasha_mbhc_program_btn_thr(struct snd_soc_codec *codec, int vth; if (num_btn > WCD_MBHC_DEF_BUTTONS) { - dev_err(codec->dev, "%s: invalid number of buttons: %d\n", + dev_err(component->dev, "%s: invalid number of buttons: %d\n", __func__, num_btn); return; } @@ -1254,17 +1266,18 @@ static void tasha_mbhc_program_btn_thr(struct snd_soc_codec *codec, */ for (i = 0; i < num_btn; i++) { vth = ((btn_high[i] * 2) / 25) & 0x3F; - snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN0 + i, - 0xFC, vth << 2); - dev_dbg(codec->dev, "%s: btn_high[%d]: %d, vth: %d\n", + snd_soc_component_update_bits( + component, WCD9335_ANA_MBHC_BTN0 + i, + 0xFC, vth << 2); + dev_dbg(component->dev, "%s: btn_high[%d]: %d, vth: %d\n", __func__, i, btn_high[i], vth); } } static bool tasha_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock) { - struct snd_soc_codec *codec = mbhc->codec; - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = mbhc->component; + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; @@ -1280,8 +1293,8 @@ static int tasha_mbhc_register_notifier(struct wcd_mbhc *mbhc, struct notifier_block *nblock, bool enable) { - struct snd_soc_codec *codec = mbhc->codec; - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = mbhc->component; + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); if (enable) return blocking_notifier_chain_register(&tasha->notifier, @@ -1296,22 +1309,25 @@ static bool tasha_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) u8 val; if (micb_num == MIC_BIAS_2) { - val = (snd_soc_read(mbhc->codec, WCD9335_ANA_MICB2) >> 6); + val = (snd_soc_component_read32( + mbhc->component, WCD9335_ANA_MICB2) >> 6); if (val == 0x01) return true; } return false; } -static bool tasha_mbhc_hph_pa_on_status(struct snd_soc_codec *codec) +static bool tasha_mbhc_hph_pa_on_status(struct snd_soc_component *component) { - return (snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0) ? true : false; + return (snd_soc_component_read32(component, WCD9335_ANA_HPH) & 0xC0) ? + true : false; } -static void tasha_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec, - enum mbhc_hs_pullup_iref pull_up_cur) +static void tasha_mbhc_hph_l_pull_up_control( + struct snd_soc_component *component, + enum mbhc_hs_pullup_iref pull_up_cur) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); if (!tasha) return; @@ -1321,22 +1337,24 @@ static void tasha_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec, pull_up_cur == I_DEFAULT) pull_up_cur = I_2P0_UA; - dev_dbg(codec->dev, "%s: HS pull up current:%d\n", + dev_dbg(component->dev, "%s: HS pull up current:%d\n", __func__, pull_up_cur); if (TASHA_IS_2_0(tasha->wcd9xxx)) - snd_soc_update_bits(codec, WCD9335_MBHC_PLUG_DETECT_CTL, - 0xC0, pull_up_cur << 6); + snd_soc_component_update_bits(component, + WCD9335_MBHC_PLUG_DETECT_CTL, + 0xC0, pull_up_cur << 6); else - snd_soc_update_bits(codec, WCD9335_MBHC_PLUG_DETECT_CTL, - 0xC0, 0x40); + snd_soc_component_update_bits(component, + WCD9335_MBHC_PLUG_DETECT_CTL, + 0xC0, 0x40); } static int tasha_enable_ext_mb_source(struct wcd_mbhc *mbhc, bool turn_on) { - struct snd_soc_codec *codec = mbhc->codec; - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = mbhc->component; + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); int ret = 0; struct on_demand_supply *supply; @@ -1345,20 +1363,21 @@ static int tasha_enable_ext_mb_source(struct wcd_mbhc *mbhc, supply = &tasha->on_demand_list[ON_DEMAND_MICBIAS]; if (!supply->supply) { - dev_dbg(codec->dev, "%s: warning supply not present ond for %s\n", + dev_dbg(component->dev, "%s: warning supply not present ond for %s\n", __func__, "onDemand Micbias"); return ret; } - dev_dbg(codec->dev, "%s turn_on: %d count: %d\n", __func__, turn_on, + dev_dbg(component->dev, "%s turn_on: %d count: %d\n", __func__, turn_on, supply->ondemand_supply_count); if (turn_on) { if (!(supply->ondemand_supply_count)) { ret = snd_soc_dapm_force_enable_pin( - snd_soc_codec_get_dapm(codec), + snd_soc_component_get_dapm(component), "MICBIAS_REGULATOR"); - snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + snd_soc_dapm_sync( + snd_soc_component_get_dapm(component)); } supply->ondemand_supply_count++; } else { @@ -1366,27 +1385,27 @@ static int tasha_enable_ext_mb_source(struct wcd_mbhc *mbhc, supply->ondemand_supply_count--; if (!(supply->ondemand_supply_count)) { ret = snd_soc_dapm_disable_pin( - snd_soc_codec_get_dapm(codec), + snd_soc_component_get_dapm(component), "MICBIAS_REGULATOR"); - snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + snd_soc_dapm_sync(snd_soc_component_get_dapm(component)); } } if (ret) - dev_err(codec->dev, "%s: Failed to %s external micbias source\n", + dev_err(component->dev, "%s: Failed to %s external micbias source\n", __func__, turn_on ? "enable" : "disabled"); else - dev_dbg(codec->dev, "%s: %s external micbias source\n", + dev_dbg(component->dev, "%s: %s external micbias source\n", __func__, turn_on ? "Enabled" : "Disabled"); return ret; } -static int tasha_micbias_control(struct snd_soc_codec *codec, +static int tasha_micbias_control(struct snd_soc_component *component, int micb_num, int req, bool is_dapm) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); int micb_index = micb_num - 1; u16 micb_reg; int pre_off_event = 0, post_off_event = 0; @@ -1394,7 +1413,7 @@ static int tasha_micbias_control(struct snd_soc_codec *codec, int post_dapm_on = 0; if ((micb_index < 0) || (micb_index > TASHA_MAX_MICBIAS - 1)) { - dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n", + dev_err(component->dev, "%s: Invalid micbias index, micb_ind:%d\n", __func__, micb_index); return -EINVAL; } @@ -1417,7 +1436,7 @@ static int tasha_micbias_control(struct snd_soc_codec *codec, micb_reg = WCD9335_ANA_MICB4; break; default: - dev_err(codec->dev, "%s: Invalid micbias number: %d\n", + dev_err(component->dev, "%s: Invalid micbias number: %d\n", __func__, micb_num); return -EINVAL; } @@ -1428,19 +1447,22 @@ static int tasha_micbias_control(struct snd_soc_codec *codec, tasha->pullup_ref[micb_index]++; if ((tasha->pullup_ref[micb_index] == 1) && (tasha->micb_ref[micb_index] == 0)) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x80); break; case MICB_PULLUP_DISABLE: if (tasha->pullup_ref[micb_index] > 0) tasha->pullup_ref[micb_index]--; if ((tasha->pullup_ref[micb_index] == 0) && (tasha->micb_ref[micb_index] == 0)) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x00); break; case MICB_ENABLE: tasha->micb_ref[micb_index]++; if (tasha->micb_ref[micb_index] == 1) { - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x40); if (post_on_event) blocking_notifier_call_chain(&tasha->notifier, post_on_event, &tasha->mbhc); @@ -1454,13 +1476,15 @@ static int tasha_micbias_control(struct snd_soc_codec *codec, tasha->micb_ref[micb_index]--; if ((tasha->micb_ref[micb_index] == 0) && (tasha->pullup_ref[micb_index] > 0)) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x80); else if ((tasha->micb_ref[micb_index] == 0) && (tasha->pullup_ref[micb_index] == 0)) { if (pre_off_event) blocking_notifier_call_chain(&tasha->notifier, pre_off_event, &tasha->mbhc); - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x00); if (post_off_event) blocking_notifier_call_chain(&tasha->notifier, post_off_event, &tasha->mbhc); @@ -1471,7 +1495,7 @@ static int tasha_micbias_control(struct snd_soc_codec *codec, break; }; - dev_dbg(codec->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", + dev_dbg(component->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", __func__, micb_num, tasha->micb_ref[micb_index], tasha->pullup_ref[micb_index]); @@ -1480,7 +1504,7 @@ static int tasha_micbias_control(struct snd_soc_codec *codec, return 0; } -static int tasha_mbhc_request_micbias(struct snd_soc_codec *codec, +static int tasha_mbhc_request_micbias(struct snd_soc_component *component, int micb_num, int req) { int ret; @@ -1490,32 +1514,32 @@ static int tasha_mbhc_request_micbias(struct snd_soc_codec *codec, * is vote to enable mclk */ if (req == MICB_ENABLE) - tasha_cdc_mclk_enable(codec, true, false); + tasha_cdc_mclk_enable(component, true, false); - ret = tasha_micbias_control(codec, micb_num, req, false); + ret = tasha_micbias_control(component, micb_num, req, false); /* * Release vote for mclk while requesting for * micbias disable */ if (req == MICB_DISABLE) - tasha_cdc_mclk_enable(codec, false, false); + tasha_cdc_mclk_enable(component, false, false); return ret; } -static void tasha_mbhc_micb_ramp_control(struct snd_soc_codec *codec, +static void tasha_mbhc_micb_ramp_control(struct snd_soc_component *component, bool enable) { if (enable) { - snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP, + snd_soc_component_update_bits(component, WCD9335_ANA_MICB2_RAMP, 0x1C, 0x0C); - snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP, + snd_soc_component_update_bits(component, WCD9335_ANA_MICB2_RAMP, 0x80, 0x80); } else { - snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP, + snd_soc_component_update_bits(component, WCD9335_ANA_MICB2_RAMP, 0x80, 0x00); - snd_soc_update_bits(codec, WCD9335_ANA_MICB2_RAMP, + snd_soc_component_update_bits(component, WCD9335_ANA_MICB2_RAMP, 0x1C, 0x00); } } @@ -1525,22 +1549,22 @@ static struct firmware_cal *tasha_get_hwdep_fw_cal(struct wcd_mbhc *mbhc, { struct tasha_priv *tasha; struct firmware_cal *hwdep_cal; - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; - if (!codec) { - pr_err("%s: NULL codec pointer\n", __func__); + if (!component) { + pr_err("%s: NULL component pointer\n", __func__); return NULL; } - tasha = snd_soc_codec_get_drvdata(codec); + tasha = snd_soc_component_get_drvdata(component); hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, type); if (!hwdep_cal) - dev_err(codec->dev, "%s: cal not sent by %d\n", + dev_err(component->dev, "%s: cal not sent by %d\n", __func__, type); return hwdep_cal; } -static int tasha_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, +static int tasha_mbhc_micb_adjust_voltage(struct snd_soc_component *component, int req_volt, int micb_num) { @@ -1572,7 +1596,7 @@ static int tasha_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, * momentarily, change the micbias value and then re-enable * micbias. */ - micb_val = snd_soc_read(codec, micb_reg); + micb_val = snd_soc_component_read32(component, micb_reg); micb_en = (micb_val & 0xC0) >> 6; cur_vout_ctl = micb_val & 0x3F; @@ -1582,17 +1606,17 @@ static int tasha_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, if (cur_vout_ctl == req_vout_ctl) return 0; - dev_dbg(codec->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n", + dev_dbg(component->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n", __func__, micb_num, WCD_VOUT_CTL_TO_MICB(cur_vout_ctl), req_volt, micb_en); if (micb_en == 0x1) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + snd_soc_component_update_bits(component, micb_reg, 0xC0, 0x80); - snd_soc_update_bits(codec, micb_reg, 0x3F, req_vout_ctl); + snd_soc_component_update_bits(component, micb_reg, 0x3F, req_vout_ctl); if (micb_en == 0x1) { - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + snd_soc_component_update_bits(component, micb_reg, 0xC0, 0x40); /* * Add 2ms delay as per HW requirement after enabling * micbias @@ -1603,11 +1627,12 @@ static int tasha_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, return 0; } -static int tasha_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec, - int micb_num, bool req_en) +static int tasha_mbhc_micb_ctrl_threshold_mic( + struct snd_soc_component *component, + int micb_num, bool req_en) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); + struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent); int rc, micb_mv; if (micb_num != MIC_BIAS_2) @@ -1624,7 +1649,7 @@ static int tasha_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec, micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb2_mv; mutex_lock(&tasha->micb_lock); - rc = tasha_mbhc_micb_adjust_voltage(codec, micb_mv, MIC_BIAS_2); + rc = tasha_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2); mutex_unlock(&tasha->micb_lock); return rc; @@ -1694,39 +1719,40 @@ static inline void tasha_mbhc_get_result_params(struct wcd9xxx *wcd9xxx, * to make the switch open. * * @zdet_gpio_cb: callback function from machine driver - * @codec: Codec instance + * @component: Codec instance * * Return: none */ void tasha_mbhc_zdet_gpio_ctrl( - int (*zdet_gpio_cb)(struct snd_soc_codec *codec, bool high), - struct snd_soc_codec *codec) + int (*zdet_gpio_cb)( + struct snd_soc_component *component, bool high), + struct snd_soc_component *component) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); tasha->zdet_gpio_cb = zdet_gpio_cb; } EXPORT_SYMBOL(tasha_mbhc_zdet_gpio_ctrl); -static void tasha_mbhc_zdet_ramp(struct snd_soc_codec *codec, +static void tasha_mbhc_zdet_ramp(struct snd_soc_component *component, struct tasha_mbhc_zdet_param *zdet_param, int32_t *zl, int32_t *zr, s16 *d1_a) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); int32_t zdet = 0; - snd_soc_update_bits(codec, WCD9335_MBHC_ZDET_ANA_CTL, 0x70, - zdet_param->ldo_ctl << 4); - snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN5, 0xFC, - zdet_param->btn5); - snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN6, 0xFC, - zdet_param->btn6); - snd_soc_update_bits(codec, WCD9335_ANA_MBHC_BTN7, 0xFC, - zdet_param->btn7); - snd_soc_update_bits(codec, WCD9335_MBHC_ZDET_ANA_CTL, 0x0F, - zdet_param->noff); - snd_soc_update_bits(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x0F, - zdet_param->nshift); + snd_soc_component_update_bits(component, WCD9335_MBHC_ZDET_ANA_CTL, + 0x70, zdet_param->ldo_ctl << 4); + snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_BTN5, 0xFC, + zdet_param->btn5); + snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_BTN6, 0xFC, + zdet_param->btn6); + snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_BTN7, 0xFC, + zdet_param->btn7); + snd_soc_component_update_bits(component, WCD9335_MBHC_ZDET_ANA_CTL, + 0x0F, zdet_param->noff); + snd_soc_component_update_bits(component, WCD9335_MBHC_ZDET_RAMP_CTL, + 0x0F, zdet_param->nshift); if (!zl) goto z_right; @@ -1756,17 +1782,17 @@ static void tasha_mbhc_zdet_ramp(struct snd_soc_codec *codec, *zr = zdet; } -static inline void tasha_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec, +static inline void tasha_wcd_mbhc_qfuse_cal(struct snd_soc_component *component, int32_t *z_val, int flag_l_r) { s16 q1; int q1_cal; if (*z_val < (TASHA_ZDET_VAL_400/1000)) - q1 = snd_soc_read(codec, + q1 = snd_soc_component_read32(component, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT1 + (2 * flag_l_r)); else - q1 = snd_soc_read(codec, + q1 = snd_soc_component_read32(component, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT2 + (2 * flag_l_r)); if (q1 & 0x80) q1_cal = (10000 - ((q1 & 0x7F) * 25)); @@ -1779,8 +1805,8 @@ static inline void tasha_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec, static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, uint32_t *zr) { - struct snd_soc_codec *codec = mbhc->codec; - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = mbhc->component; + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; s16 reg0, reg1, reg2, reg3, reg4; int32_t z1L, z1R, z1Ls; @@ -1803,7 +1829,7 @@ static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, s16 *d1 = NULL; if (!TASHA_IS_2_0(wcd9xxx)) { - dev_dbg(codec->dev, "%s: Z-det is not supported for this codec version\n", + dev_dbg(component->dev, "%s: Z-det is not supported for this codec version\n", __func__); *zl = 0; *zr = 0; @@ -1812,15 +1838,16 @@ static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); if (tasha->zdet_gpio_cb) - is_change = tasha->zdet_gpio_cb(codec, true); + is_change = tasha->zdet_gpio_cb(component, true); - reg0 = snd_soc_read(codec, WCD9335_ANA_MBHC_BTN5); - reg1 = snd_soc_read(codec, WCD9335_ANA_MBHC_BTN6); - reg2 = snd_soc_read(codec, WCD9335_ANA_MBHC_BTN7); - reg3 = snd_soc_read(codec, WCD9335_MBHC_CTL_1); - reg4 = snd_soc_read(codec, WCD9335_MBHC_ZDET_ANA_CTL); + reg0 = snd_soc_component_read32(component, WCD9335_ANA_MBHC_BTN5); + reg1 = snd_soc_component_read32(component, WCD9335_ANA_MBHC_BTN6); + reg2 = snd_soc_component_read32(component, WCD9335_ANA_MBHC_BTN7); + reg3 = snd_soc_component_read32(component, WCD9335_MBHC_CTL_1); + reg4 = snd_soc_component_read32(component, WCD9335_MBHC_ZDET_ANA_CTL); - if (snd_soc_read(codec, WCD9335_ANA_MBHC_ELECT) & 0x80) { + if (snd_soc_component_read32( + component, WCD9335_ANA_MBHC_ELECT) & 0x80) { is_fsm_disable = true; regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_ELECT, 0x80, 0x00); @@ -1832,7 +1859,8 @@ static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, WCD9335_ANA_MBHC_MECH, 0x80, 0x00); /* Enable AZ */ - snd_soc_update_bits(codec, WCD9335_MBHC_CTL_1, 0x0C, 0x04); + snd_soc_component_update_bits(component, WCD9335_MBHC_CTL_1, + 0x0C, 0x04); /* Turn off 100k pull down on HPHL */ regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_MECH, 0x01, 0x00); @@ -1840,7 +1868,7 @@ static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, /* First get impedance on Left */ d1 = d1_a[1]; zdet_param_ptr = &zdet_param[1]; - tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + tasha_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1); if (!TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z1L)) goto left_ch_impedance; @@ -1856,7 +1884,7 @@ static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, zdet_param_ptr = &zdet_param[3]; d1 = d1_a[3]; } - tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + tasha_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1); left_ch_impedance: if ((z1L == TASHA_ZDET_FLOATING_IMPEDANCE) || @@ -1866,13 +1894,13 @@ static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, d1 = d1_a[1]; } else { *zl = z1L/1000; - tasha_wcd_mbhc_qfuse_cal(codec, zl, 0); + tasha_wcd_mbhc_qfuse_cal(component, zl, 0); } - dev_dbg(codec->dev, "%s: impedance on HPH_L = %d(ohms)\n", + dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n", __func__, *zl); /* start of right impedance ramp and calculation */ - tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + tasha_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1); if (TASHA_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) { if (((z1R > TASHA_ZDET_VAL_1200) && (zdet_param_ptr->noff == 0x6)) || @@ -1890,7 +1918,7 @@ static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, zdet_param_ptr = &zdet_param[3]; d1 = d1_a[3]; } - tasha_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + tasha_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1); } right_ch_impedance: if ((z1R == TASHA_ZDET_FLOATING_IMPEDANCE) || @@ -1898,15 +1926,15 @@ static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, *zr = TASHA_ZDET_FLOATING_IMPEDANCE; } else { *zr = z1R/1000; - tasha_wcd_mbhc_qfuse_cal(codec, zr, 1); + tasha_wcd_mbhc_qfuse_cal(component, zr, 1); } - dev_dbg(codec->dev, "%s: impedance on HPH_R = %d(ohms)\n", + dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n", __func__, *zr); /* mono/stereo detection */ if ((*zl == TASHA_ZDET_FLOATING_IMPEDANCE) && (*zr == TASHA_ZDET_FLOATING_IMPEDANCE)) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: plug type is invalid or extension cable\n", __func__); goto zdet_complete; @@ -1915,40 +1943,46 @@ static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, (*zr == TASHA_ZDET_FLOATING_IMPEDANCE) || ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) || ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: Mono plug type with one ch floating or shorted to GND\n", __func__); mbhc->hph_type = WCD_MBHC_HPH_MONO; goto zdet_complete; } - snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST, 0x02, 0x02); - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x40, 0x01); + snd_soc_component_update_bits(component, WCD9335_HPH_R_ATEST, + 0x02, 0x02); + snd_soc_component_update_bits(component, WCD9335_HPH_PA_CTL2, + 0x40, 0x01); if (*zl < (TASHA_ZDET_VAL_32/1000)) - tasha_mbhc_zdet_ramp(codec, &zdet_param[0], &z1Ls, NULL, d1); + tasha_mbhc_zdet_ramp(component, &zdet_param[0], + &z1Ls, NULL, d1); else - tasha_mbhc_zdet_ramp(codec, &zdet_param[1], &z1Ls, NULL, d1); - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x40, 0x00); - snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST, 0x02, 0x00); + tasha_mbhc_zdet_ramp(component, &zdet_param[1], + &z1Ls, NULL, d1); + snd_soc_component_update_bits(component, WCD9335_HPH_PA_CTL2, + 0x40, 0x00); + snd_soc_component_update_bits(component, WCD9335_HPH_R_ATEST, + 0x02, 0x00); z1Ls /= 1000; - tasha_wcd_mbhc_qfuse_cal(codec, &z1Ls, 0); + tasha_wcd_mbhc_qfuse_cal(component, &z1Ls, 0); /* parallel of left Z and 9 ohm pull down resistor */ zMono = ((*zl) * 9) / ((*zl) + 9); z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls); z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl)); if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) { - dev_dbg(codec->dev, "%s: stereo plug type detected\n", + dev_dbg(component->dev, "%s: stereo plug type detected\n", __func__); mbhc->hph_type = WCD_MBHC_HPH_STEREO; } else { - dev_dbg(codec->dev, "%s: MONO plug type detected\n", + dev_dbg(component->dev, "%s: MONO plug type detected\n", __func__); mbhc->hph_type = WCD_MBHC_HPH_MONO; } zdet_complete: - snd_soc_write(codec, WCD9335_ANA_MBHC_BTN5, reg0); - snd_soc_write(codec, WCD9335_ANA_MBHC_BTN6, reg1); - snd_soc_write(codec, WCD9335_ANA_MBHC_BTN7, reg2); + snd_soc_component_write(component, WCD9335_ANA_MBHC_BTN5, reg0); + snd_soc_component_write(component, WCD9335_ANA_MBHC_BTN6, reg1); + snd_soc_component_write(component, WCD9335_ANA_MBHC_BTN7, reg2); /* Turn on 100k pull down on HPHL */ regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_MECH, 0x01, 0x01); @@ -1958,78 +1992,83 @@ static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_MECH, 0x80, 0x80); - snd_soc_write(codec, WCD9335_MBHC_ZDET_ANA_CTL, reg4); - snd_soc_write(codec, WCD9335_MBHC_CTL_1, reg3); + snd_soc_component_write(component, WCD9335_MBHC_ZDET_ANA_CTL, reg4); + snd_soc_component_write(component, WCD9335_MBHC_CTL_1, reg3); if (is_fsm_disable) regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_ELECT, 0x80, 0x80); if (tasha->zdet_gpio_cb && is_change) - tasha->zdet_gpio_cb(codec, false); + tasha->zdet_gpio_cb(component, false); } -static void tasha_mbhc_gnd_det_ctrl(struct snd_soc_codec *codec, bool enable) +static void tasha_mbhc_gnd_det_ctrl( + struct snd_soc_component *component, bool enable) { if (enable) { - snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_MECH, 0x02, 0x02); - snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_MECH, 0x40, 0x40); } else { - snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_MECH, 0x40, 0x00); - snd_soc_update_bits(codec, WCD9335_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, WCD9335_ANA_MBHC_MECH, 0x02, 0x00); } } -static void tasha_mbhc_hph_pull_down_ctrl(struct snd_soc_codec *codec, +static void tasha_mbhc_hph_pull_down_ctrl(struct snd_soc_component *component, bool enable) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); if (enable) { - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, + snd_soc_component_update_bits(component, WCD9335_HPH_PA_CTL2, 0x40, 0x40); if (TASHA_IS_2_0(tasha->wcd9xxx)) - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, - 0x10, 0x10); + snd_soc_component_update_bits(component, + WCD9335_HPH_PA_CTL2, + 0x10, 0x10); } else { - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, - 0x40, 0x00); + snd_soc_component_update_bits(component, WCD9335_HPH_PA_CTL2, + 0x40, 0x00); if (TASHA_IS_2_0(tasha->wcd9xxx)) - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, - 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD9335_HPH_PA_CTL2, + 0x10, 0x00); } } static void tasha_mbhc_moisture_config(struct wcd_mbhc *mbhc) { - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; if (mbhc->moist_vref == V_OFF) return; /* Donot enable moisture detection if jack type is NC */ if (!mbhc->hphl_swh) { - dev_dbg(codec->dev, "%s: disable moisture detection for NC\n", + dev_dbg(component->dev, "%s: disable moisture detection for NC\n", __func__); return; } - snd_soc_update_bits(codec, WCD9335_MBHC_CTL_2, + snd_soc_component_update_bits(component, WCD9335_MBHC_CTL_2, 0x0C, mbhc->moist_vref << 2); - tasha_mbhc_hph_l_pull_up_control(codec, mbhc->moist_iref); + tasha_mbhc_hph_l_pull_up_control(component, mbhc->moist_iref); } -static void tasha_update_anc_state(struct snd_soc_codec *codec, bool enable, - int anc_num) +static void tasha_update_anc_state(struct snd_soc_component *component, + bool enable, int anc_num) { if (enable) - snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CFG0 + - (20 * anc_num), 0x10, 0x10); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num), + 0x10, 0x10); else - snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CFG0 + - (20 * anc_num), 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num), + 0x10, 0x00); } static bool tasha_is_anc_on(struct wcd_mbhc *mbhc) @@ -2038,9 +2077,11 @@ static bool tasha_is_anc_on(struct wcd_mbhc *mbhc) u16 ancl, ancr; ancl = - (snd_soc_read(mbhc->codec, WCD9335_CDC_RX1_RX_PATH_CFG0)) & 0x10; + (snd_soc_component_read32( + mbhc->component, WCD9335_CDC_RX1_RX_PATH_CFG0)) & 0x10; ancr = - (snd_soc_read(mbhc->codec, WCD9335_CDC_RX2_RX_PATH_CFG0)) & 0x10; + (snd_soc_component_read32( + mbhc->component, WCD9335_CDC_RX2_RX_PATH_CFG0)) & 0x10; anc_on = !!(ancl | ancr); @@ -2076,8 +2117,9 @@ static const struct wcd_mbhc_cb mbhc_cb = { static int tasha_get_anc_slot(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = tasha->anc_slot; return 0; @@ -2086,8 +2128,9 @@ static int tasha_get_anc_slot(struct snd_kcontrol *kcontrol, static int tasha_put_anc_slot(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); tasha->anc_slot = ucontrol->value.integer.value[0]; return 0; @@ -2096,8 +2139,9 @@ static int tasha_put_anc_slot(struct snd_kcontrol *kcontrol, static int tasha_get_anc_func(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = (tasha->anc_func == true ? 1 : 0); return 0; @@ -2106,14 +2150,16 @@ static int tasha_get_anc_func(struct snd_kcontrol *kcontrol, static int tasha_put_anc_func(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); mutex_lock(&tasha->codec_mutex); tasha->anc_func = (!ucontrol->value.integer.value[0] ? false : true); - dev_dbg(codec->dev, "%s: anc_func %x", __func__, tasha->anc_func); + dev_dbg(component->dev, "%s: anc_func %x", __func__, tasha->anc_func); if (tasha->anc_func == true) { snd_soc_dapm_enable_pin(dapm, "ANC LINEOUT2 PA"); @@ -2168,11 +2214,13 @@ static int tasha_put_anc_func(struct snd_kcontrol *kcontrol, static int tasha_get_clkmode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); ucontrol->value.enumerated.item[0] = tasha->clk_mode; - dev_dbg(codec->dev, "%s: clk_mode: %d\n", __func__, tasha->clk_mode); + dev_dbg(component->dev, "%s: clk_mode: %d\n", __func__, + tasha->clk_mode); return 0; } @@ -2180,11 +2228,13 @@ static int tasha_get_clkmode(struct snd_kcontrol *kcontrol, static int tasha_put_clkmode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); tasha->clk_mode = ucontrol->value.enumerated.item[0]; - dev_dbg(codec->dev, "%s: clk_mode: %d\n", __func__, tasha->clk_mode); + dev_dbg(component->dev, "%s: clk_mode: %d\n", __func__, + tasha->clk_mode); return 0; } @@ -2193,7 +2243,8 @@ static int tasha_get_iir_enable_audio_mixer( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int iir_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->reg; int band_idx = ((struct soc_multi_mixer_control *) @@ -2201,10 +2252,11 @@ static int tasha_get_iir_enable_audio_mixer( /* IIR filter band registers are at integer multiples of 16 */ u16 iir_reg = WCD9335_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx; - ucontrol->value.integer.value[0] = (snd_soc_read(codec, iir_reg) & - (1 << band_idx)) != 0; + ucontrol->value.integer.value[0] = ( + snd_soc_component_read32(component, iir_reg) & + (1 << band_idx)) != 0; - dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, + dev_dbg(component->dev, "%s: IIR #%d band #%d enable %d\n", __func__, iir_idx, band_idx, (uint32_t)ucontrol->value.integer.value[0]); return 0; @@ -2216,13 +2268,15 @@ static int tasha_hph_impedance_get(struct snd_kcontrol *kcontrol, uint32_t zl, zr; bool hphr; struct soc_multi_mixer_control *mc; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tasha_priv *priv = snd_soc_component_get_drvdata(component); mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); hphr = mc->shift; wcd_mbhc_get_impedance(&priv->mbhc, &zl, &zr); - dev_dbg(codec->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr); + dev_dbg(component->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, + zl, zr); ucontrol->value.integer.value[0] = hphr ? zr : zl; return 0; @@ -2238,24 +2292,26 @@ static const struct snd_kcontrol_new impedance_detect_controls[] = { static int tasha_get_hph_type(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tasha_priv *priv = snd_soc_component_get_drvdata(component); struct wcd_mbhc *mbhc; if (!priv) { - dev_dbg(codec->dev, "%s: wcd9335 private data is NULL\n", + dev_dbg(component->dev, "%s: wcd9335 private data is NULL\n", __func__); return 0; } mbhc = &priv->mbhc; if (!mbhc) { - dev_dbg(codec->dev, "%s: mbhc not initialized\n", __func__); + dev_dbg(component->dev, "%s: mbhc not initialized\n", __func__); return 0; } ucontrol->value.integer.value[0] = (u32) mbhc->hph_type; - dev_dbg(codec->dev, "%s: hph_type = %u\n", __func__, mbhc->hph_type); + dev_dbg(component->dev, "%s: hph_type = %u\n", __func__, + mbhc->hph_type); return 0; } @@ -2269,9 +2325,10 @@ static int tasha_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = tasha_p->vi_feed_value; @@ -2282,9 +2339,10 @@ static int tasha_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component); struct wcd9xxx *core = tasha_p->wcd9xxx; struct soc_multi_mixer_control *mixer = ((struct soc_multi_mixer_control *)kcontrol->private_value); @@ -2292,7 +2350,7 @@ static int tasha_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, u32 port_id = mixer->shift; u32 enable = ucontrol->value.integer.value[0]; - dev_dbg(codec->dev, "%s: enable: %d, port_id:%d, dai_id: %d\n", + dev_dbg(component->dev, "%s: enable: %d, port_id:%d, dai_id: %d\n", __func__, enable, port_id, dai_id); tasha_p->vi_feed_value = ucontrol->value.integer.value[0]; @@ -2335,8 +2393,9 @@ static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = tasha_p->tx_port_value; return 0; @@ -2346,10 +2405,11 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component); + struct wcd9xxx *core = dev_get_drvdata(component->dev->parent); struct snd_soc_dapm_update *update = NULL; struct soc_multi_mixer_control *mixer = ((struct soc_multi_mixer_control *)kcontrol->private_value); @@ -2359,7 +2419,7 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, u32 vtable; - dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", + dev_dbg(component->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", __func__, widget->name, ucontrol->id.name, tasha_p->tx_port_value, widget->shift, ucontrol->value.integer.value[0]); @@ -2367,16 +2427,16 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, mutex_lock(&tasha_p->codec_mutex); if (tasha_p->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) { - if (dai_id >= ARRAY_SIZE(vport_slim_check_table)) { - dev_err(codec->dev, "%s: dai_id: %d, out of bounds\n", - __func__, dai_id); + if (dai_id != AIF1_CAP) { + dev_err(component->dev, "%s: invalid AIF for I2C mode\n", + __func__); mutex_unlock(&tasha_p->codec_mutex); return -EINVAL; } vtable = vport_slim_check_table[dai_id]; } else { if (dai_id >= ARRAY_SIZE(vport_i2s_check_table)) { - dev_err(codec->dev, "%s: dai_id: %d, out of bounds\n", + dev_err(component->dev, "%s: dai_id: %d, out of bounds\n", __func__, dai_id); return -EINVAL; } @@ -2391,7 +2451,7 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, if (wcd9xxx_tx_vport_validation(vtable, port_id, tasha_p->dai, NUM_CODEC_DAIS)) { - dev_dbg(codec->dev, "%s: TX%u is used by other virtual port\n", + dev_dbg(component->dev, "%s: TX%u is used by other virtual port\n", __func__, port_id); mutex_unlock(&tasha_p->codec_mutex); return 0; @@ -2406,11 +2466,11 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, list_del_init(&core->tx_chs[port_id].list); } else { if (enable) - dev_dbg(codec->dev, "%s: TX%u port is used by\n" + dev_dbg(component->dev, "%s: TX%u port is used by\n" "this virtual port\n", __func__, port_id); else - dev_dbg(codec->dev, "%s: TX%u port is not used by\n" + dev_dbg(component->dev, "%s: TX%u port is not used by\n" "this virtual port\n", __func__, port_id); /* avoid update power function */ @@ -2441,8 +2501,9 @@ static int slim_rx_mux_get(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component); ucontrol->value.enumerated.item[0] = tasha_p->rx_port_value[widget->shift]; @@ -2458,9 +2519,10 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component); + struct wcd9xxx *core = dev_get_drvdata(component->dev->parent); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct snd_soc_dapm_update *update = NULL; unsigned int rx_port_value; @@ -2477,7 +2539,7 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) { if (rx_port_value > 2) { - dev_err(codec->dev, "%s: invalid AIF for I2C mode\n", + dev_err(component->dev, "%s: invalid AIF for I2C mode\n", __func__); goto err; } @@ -2491,7 +2553,7 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, if (wcd9xxx_rx_vport_validation(port_id + TASHA_RX_PORT_START_NUMBER, &tasha_p->dai[AIF1_PB].wcd9xxx_ch_list)) { - dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + dev_dbg(component->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", __func__, port_id); goto rtn; } @@ -2502,7 +2564,7 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, if (wcd9xxx_rx_vport_validation(port_id + TASHA_RX_PORT_START_NUMBER, &tasha_p->dai[AIF2_PB].wcd9xxx_ch_list)) { - dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + dev_dbg(component->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", __func__, port_id); goto rtn; } @@ -2513,7 +2575,7 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, if (wcd9xxx_rx_vport_validation(port_id + TASHA_RX_PORT_START_NUMBER, &tasha_p->dai[AIF3_PB].wcd9xxx_ch_list)) { - dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + dev_dbg(component->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", __func__, port_id); goto rtn; } @@ -2524,7 +2586,7 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, if (wcd9xxx_rx_vport_validation(port_id + TASHA_RX_PORT_START_NUMBER, &tasha_p->dai[AIF4_PB].wcd9xxx_ch_list)) { - dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + dev_dbg(component->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", __func__, port_id); goto rtn; } @@ -2535,7 +2597,7 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, if (wcd9xxx_rx_vport_validation(port_id + TASHA_RX_PORT_START_NUMBER, &tasha_p->dai[AIF_MIX1_PB].wcd9xxx_ch_list)) { - dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + dev_dbg(component->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", __func__, port_id); goto rtn; } @@ -2741,7 +2803,8 @@ static int tasha_put_iir_enable_audio_mixer( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int iir_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->reg; int band_idx = ((struct soc_multi_mixer_control *) @@ -2751,56 +2814,56 @@ static int tasha_put_iir_enable_audio_mixer( u16 iir_reg = WCD9335_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx; /* Mask first 5 bits, 6-8 are reserved */ - snd_soc_update_bits(codec, iir_reg, (1 << band_idx), + snd_soc_component_update_bits(component, iir_reg, (1 << band_idx), (value << band_idx)); - iir_band_en_status = ((snd_soc_read(codec, iir_reg) & + iir_band_en_status = ((snd_soc_component_read32(component, iir_reg) & (1 << band_idx)) != 0); pr_debug("%s: IIR #%d band #%d enable %d\n", __func__, iir_idx, band_idx, iir_band_en_status); return 0; } -static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec, +static uint32_t get_iir_band_coeff(struct snd_soc_component *component, int iir_idx, int band_idx, int coeff_idx) { uint32_t value = 0; /* Address does not automatically update if reading */ - snd_soc_write(codec, + snd_soc_component_write(component, (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), ((band_idx * BAND_MAX + coeff_idx) * sizeof(uint32_t)) & 0x7F); - value |= snd_soc_read(codec, + value |= snd_soc_component_read32(component, (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx)); - snd_soc_write(codec, + snd_soc_component_write(component, (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), ((band_idx * BAND_MAX + coeff_idx) * sizeof(uint32_t) + 1) & 0x7F); - value |= (snd_soc_read(codec, + value |= (snd_soc_component_read32(component, (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx)) << 8); - snd_soc_write(codec, + snd_soc_component_write(component, (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), ((band_idx * BAND_MAX + coeff_idx) * sizeof(uint32_t) + 2) & 0x7F); - value |= (snd_soc_read(codec, + value |= (snd_soc_component_read32(component, (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx)) << 16); - snd_soc_write(codec, + snd_soc_component_write(component, (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), ((band_idx * BAND_MAX + coeff_idx) * sizeof(uint32_t) + 3) & 0x7F); /* Mask bits top 2 bits since they are reserved */ - value |= ((snd_soc_read(codec, + value |= ((snd_soc_component_read32(component, (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx)) & 0x3F) << 24); @@ -2811,22 +2874,23 @@ static int tasha_get_iir_band_audio_mixer( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int iir_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->reg; int band_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; ucontrol->value.integer.value[0] = - get_iir_band_coeff(codec, iir_idx, band_idx, 0); + get_iir_band_coeff(component, iir_idx, band_idx, 0); ucontrol->value.integer.value[1] = - get_iir_band_coeff(codec, iir_idx, band_idx, 1); + get_iir_band_coeff(component, iir_idx, band_idx, 1); ucontrol->value.integer.value[2] = - get_iir_band_coeff(codec, iir_idx, band_idx, 2); + get_iir_band_coeff(component, iir_idx, band_idx, 2); ucontrol->value.integer.value[3] = - get_iir_band_coeff(codec, iir_idx, band_idx, 3); + get_iir_band_coeff(component, iir_idx, band_idx, 3); ucontrol->value.integer.value[4] = - get_iir_band_coeff(codec, iir_idx, band_idx, 4); + get_iir_band_coeff(component, iir_idx, band_idx, 4); pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n" "%s: IIR #%d band #%d b1 = 0x%x\n" @@ -2846,30 +2910,30 @@ static int tasha_get_iir_band_audio_mixer( return 0; } -static void set_iir_band_coeff(struct snd_soc_codec *codec, +static void set_iir_band_coeff(struct snd_soc_component *component, int iir_idx, int band_idx, uint32_t value) { - snd_soc_write(codec, + snd_soc_component_write(component, (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), (value & 0xFF)); - snd_soc_write(codec, + snd_soc_component_write(component, (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), (value >> 8) & 0xFF); - snd_soc_write(codec, + snd_soc_component_write(component, (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), (value >> 16) & 0xFF); /* Mask top 2 bits, 7-8 are reserved */ - snd_soc_write(codec, + snd_soc_component_write(component, (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), (value >> 24) & 0x3F); } static void tasha_codec_enable_int_port(struct wcd9xxx_codec_dai_data *dai, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { struct wcd9xxx_ch *ch; int port_num = 0; @@ -2877,12 +2941,12 @@ static void tasha_codec_enable_int_port(struct wcd9xxx_codec_dai_data *dai, u8 val = 0; struct tasha_priv *tasha_p; - if (!dai || !codec) { + if (!dai || !component) { pr_err("%s: Invalid params\n", __func__); return; } - tasha_p = snd_soc_codec_get_drvdata(codec); + tasha_p = snd_soc_component_get_drvdata(component); list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) { if (ch->port >= TASHA_RX_PORT_START_NUMBER) { port_num = ch->port - TASHA_RX_PORT_START_NUMBER; @@ -2949,48 +3013,49 @@ static int tasha_codec_enable_slimrx(struct snd_soc_dapm_widget *w, int event) { struct wcd9xxx *core; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component); int ret = 0; struct wcd9xxx_codec_dai_data *dai; - core = dev_get_drvdata(codec->dev->parent); + core = dev_get_drvdata(component->dev->parent); - dev_dbg(codec->dev, "%s: event called! codec name %s num_dai %d\n" + dev_dbg(component->dev, "%s: event called! component name %s num_dai %d\n" "stream name %s event %d\n", - __func__, codec->component.name, - codec->component.num_dai, w->sname, event); + __func__, component->name, + component->num_dai, w->sname, event); /* Execute the callback only if interface type is slimbus */ if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) return 0; dai = &tasha_p->dai[w->shift]; - dev_dbg(codec->dev, "%s: w->name %s w->shift %d event %d\n", + dev_dbg(component->dev, "%s: w->name %s w->shift %d event %d\n", __func__, w->name, w->shift, event); switch (event) { case SND_SOC_DAPM_POST_PMU: dai->bus_down_in_recovery = false; - tasha_codec_enable_int_port(dai, codec); + tasha_codec_enable_int_port(dai, component); (void) tasha_codec_enable_slim_chmask(dai, true); ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list, dai->rate, dai->bit_width, &dai->grph); break; case SND_SOC_DAPM_PRE_PMD: - tasha_codec_vote_max_bw(codec, true); + tasha_codec_vote_max_bw(component, true); break; case SND_SOC_DAPM_POST_PMD: ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list, dai->grph); - dev_dbg(codec->dev, "%s: Disconnect RX port, ret = %d\n", + dev_dbg(component->dev, "%s: Disconnect RX port, ret = %d\n", __func__, ret); if (!dai->bus_down_in_recovery) ret = tasha_codec_enable_slim_chmask(dai, false); else - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: bus in recovery skip enable slim_chmask", __func__); ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list, @@ -3005,7 +3070,7 @@ static int tasha_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w, int event) { struct wcd9xxx *core = NULL; - struct snd_soc_codec *codec = NULL; + struct snd_soc_component *component = NULL; struct tasha_priv *tasha_p = NULL; int ret = 0; struct wcd9xxx_codec_dai_data *dai = NULL; @@ -3014,20 +3079,21 @@ static int tasha_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w, pr_err("%s invalid params\n", __func__); return -EINVAL; } - codec = snd_soc_dapm_to_codec(w->dapm); - tasha_p = snd_soc_codec_get_drvdata(codec); + component = snd_soc_dapm_to_component(w->dapm); + tasha_p = snd_soc_component_get_drvdata(component); core = tasha_p->wcd9xxx; - dev_dbg(codec->dev, "%s: num_dai %d stream name %s\n", - __func__, codec->component.num_dai, w->sname); + dev_dbg(component->dev, "%s: num_dai %d stream name %s\n", + __func__, component->num_dai, w->sname); /* Execute the callback only if interface type is slimbus */ if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) { - dev_err(codec->dev, "%s Interface is not correct", __func__); + dev_err(component->dev, "%s Interface is not correct", + __func__); return 0; } - dev_dbg(codec->dev, "%s(): w->name %s event %d w->shift %d\n", + dev_dbg(component->dev, "%s(): w->name %s event %d w->shift %d\n", __func__, w->name, event, w->shift); if (w->shift != AIF4_VIFEED) { pr_err("%s Error in enabling the tx path\n", __func__); @@ -3038,59 +3104,60 @@ static int tasha_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMU: if (test_bit(VI_SENSE_1, &tasha_p->status_mask)) { - dev_dbg(codec->dev, "%s: spkr1 enabled\n", __func__); + dev_dbg(component->dev, "%s: spkr1 enabled\n", + __func__); /* Enable V&I sensing */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x0F, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x0F, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, 0x00); } if (test_bit(VI_SENSE_2, &tasha_p->status_mask)) { pr_debug("%s: spkr2 enabled\n", __func__); /* Enable V&I sensing */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x0F, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x0F, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, 0x00); } dai->bus_down_in_recovery = false; - tasha_codec_enable_int_port(dai, codec); + tasha_codec_enable_int_port(dai, component); (void) tasha_codec_enable_slim_chmask(dai, true); ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list, dai->rate, dai->bit_width, @@ -3100,7 +3167,7 @@ static int tasha_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w, ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list, dai->grph); if (ret) - dev_err(codec->dev, "%s error in close_slim_sch_tx %d\n", + dev_err(component->dev, "%s error in close_slim_sch_tx %d\n", __func__, ret); if (!dai->bus_down_in_recovery) ret = tasha_codec_enable_slim_chmask(dai, false); @@ -3108,36 +3175,38 @@ static int tasha_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w, ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list, dai->grph); - dev_dbg(codec->dev, "%s: Disconnect TX port, ret = %d\n", + dev_dbg(component->dev, "%s: Disconnect TX port, ret = %d\n", __func__, ret); } if (test_bit(VI_SENSE_1, &tasha_p->status_mask)) { /* Disable V&I sensing */ - dev_dbg(codec->dev, "%s: spkr1 disabled\n", __func__); - snd_soc_update_bits(codec, + dev_dbg(component->dev, "%s: spkr1 disabled\n", + __func__); + snd_soc_component_update_bits(component, WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10, 0x00); } if (test_bit(VI_SENSE_2, &tasha_p->status_mask)) { /* Disable V&I sensing */ - dev_dbg(codec->dev, "%s: spkr2 disabled\n", __func__); - snd_soc_update_bits(codec, + dev_dbg(component->dev, "%s: spkr2 disabled\n", + __func__); + snd_soc_component_update_bits(component, WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10, 0x00); } @@ -3150,29 +3219,29 @@ static int tasha_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w, /* * __tasha_codec_enable_slimtx: Enable the slimbus slave port * for TX path - * @codec: Handle to the codec for which the slave port is to be + * @component: Handle to the codec for which the slave port is to be * enabled. * @dai_data: The dai specific data for dai which is enabled. */ -static int __tasha_codec_enable_slimtx(struct snd_soc_codec *codec, +static int __tasha_codec_enable_slimtx(struct snd_soc_component *component, int event, struct wcd9xxx_codec_dai_data *dai) { struct wcd9xxx *core; - struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component); int ret = 0; /* Execute the callback only if interface type is slimbus */ if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) return 0; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: event = %d\n", __func__, event); - core = dev_get_drvdata(codec->dev->parent); + core = dev_get_drvdata(component->dev->parent); switch (event) { case SND_SOC_DAPM_POST_PMU: dai->bus_down_in_recovery = false; - tasha_codec_enable_int_port(dai, codec); + tasha_codec_enable_int_port(dai, component); (void) tasha_codec_enable_slim_chmask(dai, true); ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list, dai->rate, dai->bit_width, @@ -3201,22 +3270,24 @@ static int tasha_codec_enable_slimtx(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component); struct wcd9xxx_codec_dai_data *dai; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: w->name %s, w->shift = %d, num_dai %d stream name %s\n", __func__, w->name, w->shift, - codec->component.num_dai, w->sname); + component->num_dai, w->sname); dai = &tasha_p->dai[w->shift]; - return __tasha_codec_enable_slimtx(codec, event, dai); + return __tasha_codec_enable_slimtx(component, event, dai); } -static void tasha_codec_cpe_pp_set_cfg(struct snd_soc_codec *codec, int event) +static void tasha_codec_cpe_pp_set_cfg(struct snd_soc_component *component, + int event) { - struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component); struct wcd9xxx_codec_dai_data *dai; u8 bit_width, rate, buf_period; @@ -3238,8 +3309,8 @@ static void tasha_codec_cpe_pp_set_cfg(struct snd_soc_codec *codec, int event) bit_width = 0x0; break; } - snd_soc_update_bits(codec, WCD9335_CPE_SS_TX_PP_CFG, 0x0F, - bit_width); + snd_soc_component_update_bits(component, + WCD9335_CPE_SS_TX_PP_CFG, 0x0F, bit_width); switch (dai->rate) { case 384000: @@ -3256,19 +3327,23 @@ static void tasha_codec_cpe_pp_set_cfg(struct snd_soc_codec *codec, int event) rate = 0x00; break; } - snd_soc_update_bits(codec, WCD9335_CPE_SS_TX_PP_CFG, 0x70, - rate); + snd_soc_component_update_bits(component, + WCD9335_CPE_SS_TX_PP_CFG, 0x70, rate); buf_period = (dai->rate * (dai->bit_width/8)) / (16*1000); - snd_soc_update_bits(codec, WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD, - 0xFF, buf_period); - dev_dbg(codec->dev, "%s: PP buffer period= 0x%x\n", + snd_soc_component_update_bits(component, + WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD, + 0xFF, buf_period); + dev_dbg(component->dev, "%s: PP buffer period= 0x%x\n", __func__, buf_period); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_write(codec, WCD9335_CPE_SS_TX_PP_CFG, 0x3C); - snd_soc_write(codec, WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD, 0x60); + snd_soc_component_write(component, WCD9335_CPE_SS_TX_PP_CFG, + 0x3C); + snd_soc_component_write(component, + WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD, + 0x60); break; default: @@ -3279,20 +3354,20 @@ static void tasha_codec_cpe_pp_set_cfg(struct snd_soc_codec *codec, int event) /* * tasha_codec_get_mad_port_id: Callback function that will be invoked * to get the port ID for MAD. - * @codec: Handle to the codec + * @component: Handle to the codec * @port_id: cpe port_id needs to enable */ -static int tasha_codec_get_mad_port_id(struct snd_soc_codec *codec, +static int tasha_codec_get_mad_port_id(struct snd_soc_component *component, u16 *port_id) { struct tasha_priv *tasha_p; struct wcd9xxx_codec_dai_data *dai; struct wcd9xxx_ch *ch; - if (!port_id || !codec) + if (!port_id || !component) return -EINVAL; - tasha_p = snd_soc_codec_get_drvdata(codec); + tasha_p = snd_soc_component_get_drvdata(component); if (!tasha_p) return -EINVAL; @@ -3303,12 +3378,12 @@ static int tasha_codec_get_mad_port_id(struct snd_soc_codec *codec, else if (ch->port == TASHA_TX13) *port_id = WCD_CPE_AFE_OUT_PORT_4; else { - dev_err(codec->dev, "%s: invalid mad_port = %d\n", + dev_err(component->dev, "%s: invalid mad_port = %d\n", __func__, ch->port); return -EINVAL; } } - dev_dbg(codec->dev, "%s: port_id = %d\n", __func__, *port_id); + dev_dbg(component->dev, "%s: port_id = %d\n", __func__, *port_id); return 0; } @@ -3316,13 +3391,13 @@ static int tasha_codec_get_mad_port_id(struct snd_soc_codec *codec, /* * tasha_codec_enable_slimtx_mad: Callback function that will be invoked * to setup the slave port for MAD. - * @codec: Handle to the codec + * @component: Handle to the codec * @event: Indicates whether to enable or disable the slave port */ -static int tasha_codec_enable_slimtx_mad(struct snd_soc_codec *codec, +static int tasha_codec_enable_slimtx_mad(struct snd_soc_component *component, u8 event) { - struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component); struct wcd9xxx_codec_dai_data *dai; struct wcd9xxx_ch *ch; int dapm_event = SND_SOC_DAPM_POST_PMU; @@ -3334,43 +3409,45 @@ static int tasha_codec_enable_slimtx_mad(struct snd_soc_codec *codec, if (event == 0) dapm_event = SND_SOC_DAPM_POST_PMD; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: mad_channel, event = 0x%x\n", __func__, event); list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) { - dev_dbg(codec->dev, "%s: mad_port = %d, event = 0x%x\n", + dev_dbg(component->dev, "%s: mad_port = %d, event = 0x%x\n", __func__, ch->port, event); if (ch->port == TASHA_TX13) { - tasha_codec_cpe_pp_set_cfg(codec, dapm_event); + tasha_codec_cpe_pp_set_cfg(component, dapm_event); port = TASHA_TX13; break; } } - ret = __tasha_codec_enable_slimtx(codec, dapm_event, dai); + ret = __tasha_codec_enable_slimtx(component, dapm_event, dai); if (port == TASHA_TX13) { switch (dapm_event) { case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN, 0x20, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG, 0x03, 0x02); - snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, - 0x80, 0x80); + snd_soc_component_update_bits(component, + WCD9335_CPE_SS_CFG, + 0x80, 0x80); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG, 0x03, 0x00); - snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, - 0x80, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CPE_SS_CFG, + 0x80, 0x00); break; } } @@ -3382,7 +3459,8 @@ static int tasha_put_iir_band_audio_mixer( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int iir_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->reg; int band_idx = ((struct soc_multi_mixer_control *) @@ -3392,19 +3470,19 @@ static int tasha_put_iir_band_audio_mixer( * Mask top bit it is reserved * Updates addr automatically for each B2 write */ - snd_soc_write(codec, + snd_soc_component_write(component, (WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); - set_iir_band_coeff(codec, iir_idx, band_idx, + set_iir_band_coeff(component, iir_idx, band_idx, ucontrol->value.integer.value[0]); - set_iir_band_coeff(codec, iir_idx, band_idx, + set_iir_band_coeff(component, iir_idx, band_idx, ucontrol->value.integer.value[1]); - set_iir_band_coeff(codec, iir_idx, band_idx, + set_iir_band_coeff(component, iir_idx, band_idx, ucontrol->value.integer.value[2]); - set_iir_band_coeff(codec, iir_idx, band_idx, + set_iir_band_coeff(component, iir_idx, band_idx, ucontrol->value.integer.value[3]); - set_iir_band_coeff(codec, iir_idx, band_idx, + set_iir_band_coeff(component, iir_idx, band_idx, ucontrol->value.integer.value[4]); pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n" @@ -3413,15 +3491,15 @@ static int tasha_put_iir_band_audio_mixer( "%s: IIR #%d band #%d a1 = 0x%x\n" "%s: IIR #%d band #%d a2 = 0x%x\n", __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 0), + get_iir_band_coeff(component, iir_idx, band_idx, 0), __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 1), + get_iir_band_coeff(component, iir_idx, band_idx, 1), __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 2), + get_iir_band_coeff(component, iir_idx, band_idx, 2), __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 3), + get_iir_band_coeff(component, iir_idx, band_idx, 3), __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 4)); + get_iir_band_coeff(component, iir_idx, band_idx, 4)); return 0; } @@ -3429,10 +3507,11 @@ static int tasha_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int comp = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = tasha->comp_enabled[comp]; return 0; @@ -3441,8 +3520,9 @@ static int tasha_get_compander(struct snd_kcontrol *kcontrol, static int tasha_set_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); int comp = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; int value = ucontrol->value.integer.value[0]; @@ -3455,11 +3535,11 @@ static int tasha_set_compander(struct snd_kcontrol *kcontrol, switch (comp) { case COMPANDER_1: /* Set Gain Source Select based on compander enable/disable */ - snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0x20, + snd_soc_component_update_bits(component, WCD9335_HPH_L_EN, 0x20, (value ? 0x00:0x20)); break; case COMPANDER_2: - snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0x20, + snd_soc_component_update_bits(component, WCD9335_HPH_R_EN, 0x20, (value ? 0x00:0x20)); break; case COMPANDER_3: @@ -3467,12 +3547,12 @@ static int tasha_set_compander(struct snd_kcontrol *kcontrol, case COMPANDER_4: break; case COMPANDER_5: - snd_soc_update_bits(codec, WCD9335_SE_LO_LO3_GAIN, 0x20, - (value ? 0x00:0x20)); + snd_soc_component_update_bits(component, WCD9335_SE_LO_LO3_GAIN, + 0x20, (value ? 0x00:0x20)); break; case COMPANDER_6: - snd_soc_update_bits(codec, WCD9335_SE_LO_LO4_GAIN, 0x20, - (value ? 0x00:0x20)); + snd_soc_component_update_bits(component, WCD9335_SE_LO_LO4_GAIN, + 0x20, (value ? 0x00:0x20)); break; case COMPANDER_7: break; @@ -3484,85 +3564,90 @@ static int tasha_set_compander(struct snd_kcontrol *kcontrol, * it does not cause any audio failure, so do not * return error in this case, but just print a log */ - dev_warn(codec->dev, "%s: unknown compander: %d\n", + dev_warn(component->dev, "%s: unknown compander: %d\n", __func__, comp); }; return 0; } -static void tasha_codec_init_flyback(struct snd_soc_codec *codec) +static void tasha_codec_init_flyback(struct snd_soc_component *component) { - snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0xC0, 0x00); - snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0xC0, 0x00); - snd_soc_update_bits(codec, WCD9335_RX_BIAS_FLYB_BUFF, 0x0F, 0x00); - snd_soc_update_bits(codec, WCD9335_RX_BIAS_FLYB_BUFF, 0xF0, 0x00); + snd_soc_component_update_bits(component, WCD9335_HPH_L_EN, 0xC0, 0x00); + snd_soc_component_update_bits(component, WCD9335_HPH_R_EN, 0xC0, 0x00); + snd_soc_component_update_bits(component, WCD9335_RX_BIAS_FLYB_BUFF, + 0x0F, 0x00); + snd_soc_component_update_bits(component, WCD9335_RX_BIAS_FLYB_BUFF, + 0xF0, 0x00); } static int tasha_codec_enable_rx_bias(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: tasha->rx_bias_count++; if (tasha->rx_bias_count == 1) { if (TASHA_IS_2_0(tasha->wcd9xxx)) - tasha_codec_init_flyback(codec); - snd_soc_update_bits(codec, WCD9335_ANA_RX_SUPPLIES, - 0x01, 0x01); + tasha_codec_init_flyback(component); + snd_soc_component_update_bits(component, + WCD9335_ANA_RX_SUPPLIES, + 0x01, 0x01); } break; case SND_SOC_DAPM_POST_PMD: tasha->rx_bias_count--; if (!tasha->rx_bias_count) - snd_soc_update_bits(codec, WCD9335_ANA_RX_SUPPLIES, - 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD9335_ANA_RX_SUPPLIES, + 0x01, 0x00); break; }; - dev_dbg(codec->dev, "%s: Current RX BIAS user count: %d\n", __func__, - tasha->rx_bias_count); + dev_dbg(component->dev, "%s: Current RX BIAS user count: %d\n", + __func__, tasha->rx_bias_count); return 0; } -static void tasha_realign_anc_coeff(struct snd_soc_codec *codec, +static void tasha_realign_anc_coeff(struct snd_soc_component *component, u16 reg1, u16 reg2) { u8 val1, val2, tmpval1, tmpval2; - snd_soc_write(codec, reg1, 0x00); - tmpval1 = snd_soc_read(codec, reg2); - tmpval2 = snd_soc_read(codec, reg2); - snd_soc_write(codec, reg1, 0x00); - snd_soc_write(codec, reg2, 0xFF); - snd_soc_write(codec, reg1, 0x01); - snd_soc_write(codec, reg2, 0xFF); + snd_soc_component_write(component, reg1, 0x00); + tmpval1 = snd_soc_component_read32(component, reg2); + tmpval2 = snd_soc_component_read32(component, reg2); + snd_soc_component_write(component, reg1, 0x00); + snd_soc_component_write(component, reg2, 0xFF); + snd_soc_component_write(component, reg1, 0x01); + snd_soc_component_write(component, reg2, 0xFF); - snd_soc_write(codec, reg1, 0x00); - val1 = snd_soc_read(codec, reg2); - val2 = snd_soc_read(codec, reg2); + snd_soc_component_write(component, reg1, 0x00); + val1 = snd_soc_component_read32(component, reg2); + val2 = snd_soc_component_read32(component, reg2); if (val1 == 0x0F && val2 == 0xFF) { - dev_dbg(codec->dev, "%s: ANC0 co-eff index re-aligned\n", + dev_dbg(component->dev, "%s: ANC0 co-eff index re-aligned\n", __func__); - snd_soc_read(codec, reg2); - snd_soc_write(codec, reg1, 0x00); - snd_soc_write(codec, reg2, tmpval2); - snd_soc_write(codec, reg1, 0x01); - snd_soc_write(codec, reg2, tmpval1); + snd_soc_component_read32(component, reg2); + snd_soc_component_write(component, reg1, 0x00); + snd_soc_component_write(component, reg2, tmpval2); + snd_soc_component_write(component, reg1, 0x01); + snd_soc_component_write(component, reg2, tmpval1); } else if (val1 == 0xFF && val2 == 0x0F) { - dev_dbg(codec->dev, "%s: ANC1 co-eff index already aligned\n", + dev_dbg(component->dev, "%s: ANC1 co-eff index already aligned\n", __func__); - snd_soc_write(codec, reg1, 0x00); - snd_soc_write(codec, reg2, tmpval1); - snd_soc_write(codec, reg1, 0x01); - snd_soc_write(codec, reg2, tmpval2); + snd_soc_component_write(component, reg1, 0x00); + snd_soc_component_write(component, reg2, tmpval1); + snd_soc_component_write(component, reg1, 0x01); + snd_soc_component_write(component, reg2, tmpval2); } else { - dev_err(codec->dev, "%s: ANC0 co-eff index not aligned\n", + dev_err(component->dev, "%s: ANC0 co-eff index not aligned\n", __func__); } } @@ -3570,8 +3655,9 @@ static void tasha_realign_anc_coeff(struct snd_soc_codec *codec, static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); const char *filename; const struct firmware *fw; int i; @@ -3597,27 +3683,27 @@ static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w, if (hwdep_cal) { data = hwdep_cal->data; cal_size = hwdep_cal->size; - dev_dbg(codec->dev, "%s: using hwdep calibration\n", + dev_dbg(component->dev, "%s: using hwdep calibration\n", __func__); } else { filename = "wcd9335/wcd9335_anc.bin"; - ret = request_firmware(&fw, filename, codec->dev); + ret = request_firmware(&fw, filename, component->dev); if (ret != 0) { - dev_err(codec->dev, + dev_err(component->dev, "Failed to acquire ANC data: %d\n", ret); return -ENODEV; } if (!fw) { - dev_err(codec->dev, "failed to get anc fw"); + dev_err(component->dev, "failed to get anc fw"); return -ENODEV; } data = fw->data; cal_size = fw->size; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: using request_firmware calibration\n", __func__); } if (cal_size < sizeof(struct wcd9xxx_anc_header)) { - dev_err(codec->dev, "Not enough data\n"); + dev_err(component->dev, "Not enough data\n"); ret = -ENOMEM; goto err; } @@ -3630,13 +3716,13 @@ static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w, num_anc_slots = anc_head->num_anc_slots; if (tasha->anc_slot >= num_anc_slots) { - dev_err(codec->dev, "Invalid ANC slot selected\n"); + dev_err(component->dev, "Invalid ANC slot selected\n"); ret = -EINVAL; goto err; } for (i = 0; i < num_anc_slots; i++) { if (anc_size_remaining < TASHA_PACKED_REG_SIZE) { - dev_err(codec->dev, + dev_err(component->dev, "Invalid register format\n"); ret = -EINVAL; goto err; @@ -3647,7 +3733,7 @@ static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w, if (anc_writes_size * TASHA_PACKED_REG_SIZE > anc_size_remaining) { - dev_err(codec->dev, + dev_err(component->dev, "Invalid register format\n"); ret = -EINVAL; goto err; @@ -3661,7 +3747,7 @@ static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w, anc_ptr += anc_writes_size; } if (i == num_anc_slots) { - dev_err(codec->dev, "Selected ANC slot not present\n"); + dev_err(component->dev, "Selected ANC slot not present\n"); ret = -EINVAL; goto err; } @@ -3671,39 +3757,39 @@ static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w, if (!strcmp(w->name, "RX INT0 DAC") || !strcmp(w->name, "ANC SPK1 PA")) - tasha_realign_anc_coeff(codec, + tasha_realign_anc_coeff(component, WCD9335_CDC_ANC0_IIR_COEFF_1_CTL, WCD9335_CDC_ANC0_IIR_COEFF_2_CTL); if (!strcmp(w->name, "RX INT1 DAC") || !strcmp(w->name, "RX INT3 DAC")) { - tasha_realign_anc_coeff(codec, + tasha_realign_anc_coeff(component, WCD9335_CDC_ANC0_IIR_COEFF_1_CTL, WCD9335_CDC_ANC0_IIR_COEFF_2_CTL); anc_writes_size = anc_cal_size / 2; - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x39, 0x39); } else if (!strcmp(w->name, "RX INT2 DAC") || !strcmp(w->name, "RX INT4 DAC")) { - tasha_realign_anc_coeff(codec, + tasha_realign_anc_coeff(component, WCD9335_CDC_ANC1_IIR_COEFF_1_CTL, WCD9335_CDC_ANC1_IIR_COEFF_2_CTL); i = anc_cal_size / 2; - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x39, 0x39); } for (; i < anc_writes_size; i++) { TASHA_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val); - snd_soc_write(codec, reg, (val & mask)); + snd_soc_component_write(component, reg, (val & mask)); } if (!strcmp(w->name, "RX INT1 DAC") || !strcmp(w->name, "RX INT3 DAC")) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x08); } else if (!strcmp(w->name, "RX INT2 DAC") || !strcmp(w->name, "RX INT4 DAC")) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x08); } @@ -3712,39 +3798,41 @@ static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMU: /* Remove ANC Rx from reset */ - snd_soc_update_bits(codec, WCD9335_CDC_ANC0_CLK_RESET_CTL, - 0x08, 0x00); - snd_soc_update_bits(codec, WCD9335_CDC_ANC1_CLK_RESET_CTL, - 0x08, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_ANC0_CLK_RESET_CTL, + 0x08, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_ANC1_CLK_RESET_CTL, + 0x08, 0x00); break; case SND_SOC_DAPM_POST_PMD: if (!strcmp(w->name, "ANC HPHL PA") || !strcmp(w->name, "ANC EAR PA") || !strcmp(w->name, "ANC SPK1 PA") || !strcmp(w->name, "ANC LINEOUT1 PA")) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC0_MODE_1_CTL, 0x30, 0x00); msleep(50); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC0_MODE_1_CTL, 0x01, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x38); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x07, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x00); } else if (!strcmp(w->name, "ANC HPHR PA") || !strcmp(w->name, "ANC LINEOUT2 PA")) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC1_MODE_1_CTL, 0x30, 0x00); msleep(50); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC1_MODE_1_CTL, 0x01, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x38, 0x38); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x07, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x38, 0x00); } break; @@ -3760,17 +3848,23 @@ static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w, static void tasha_codec_clear_anc_tx_hold(struct tasha_priv *tasha) { if (test_and_clear_bit(ANC_MIC_AMIC1, &tasha->status_mask)) - tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC1, false); + tasha_codec_set_tx_hold(tasha->component, + WCD9335_ANA_AMIC1, false); if (test_and_clear_bit(ANC_MIC_AMIC2, &tasha->status_mask)) - tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC2, false); + tasha_codec_set_tx_hold(tasha->component, + WCD9335_ANA_AMIC2, false); if (test_and_clear_bit(ANC_MIC_AMIC3, &tasha->status_mask)) - tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC3, false); + tasha_codec_set_tx_hold(tasha->component, + WCD9335_ANA_AMIC3, false); if (test_and_clear_bit(ANC_MIC_AMIC4, &tasha->status_mask)) - tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC4, false); + tasha_codec_set_tx_hold(tasha->component, + WCD9335_ANA_AMIC4, false); if (test_and_clear_bit(ANC_MIC_AMIC5, &tasha->status_mask)) - tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC5, false); + tasha_codec_set_tx_hold(tasha->component, + WCD9335_ANA_AMIC5, false); if (test_and_clear_bit(ANC_MIC_AMIC6, &tasha->status_mask)) - tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC6, false); + tasha_codec_set_tx_hold(tasha->component, + WCD9335_ANA_AMIC6, false); } static void tasha_codec_hph_post_pa_config(struct tasha_priv *tasha, @@ -3793,8 +3887,9 @@ static void tasha_codec_hph_post_pa_config(struct tasha_priv *tasha, } if (tasha->anc_func) { /* Clear Tx FE HOLD if both PAs are enabled */ - if ((snd_soc_read(tasha->codec, WCD9335_ANA_HPH) & - 0xC0) == 0xC0) { + if ((snd_soc_component_read32( + tasha->component, WCD9335_ANA_HPH) & + 0xC0) == 0xC0) { tasha_codec_clear_anc_tx_hold(tasha); } } @@ -3805,46 +3900,53 @@ static void tasha_codec_hph_post_pa_config(struct tasha_priv *tasha, } if (scale_val) - snd_soc_update_bits(tasha->codec, WCD9335_HPH_PA_CTL1, 0x0E, - scale_val << 1); + snd_soc_component_update_bits(tasha->component, + WCD9335_HPH_PA_CTL1, 0x0E, + scale_val << 1); if (SND_SOC_DAPM_EVENT_ON(event)) { if (tasha->comp_enabled[COMPANDER_1] || tasha->comp_enabled[COMPANDER_2]) { - snd_soc_update_bits(tasha->codec, WCD9335_HPH_L_EN, - 0x20, 0x00); - snd_soc_update_bits(tasha->codec, WCD9335_HPH_R_EN, - 0x20, 0x00); - snd_soc_update_bits(tasha->codec, WCD9335_HPH_AUTO_CHOP, - 0x20, 0x20); + snd_soc_component_update_bits(tasha->component, + WCD9335_HPH_L_EN, + 0x20, 0x00); + snd_soc_component_update_bits(tasha->component, + WCD9335_HPH_R_EN, + 0x20, 0x00); + snd_soc_component_update_bits(tasha->component, + WCD9335_HPH_AUTO_CHOP, + 0x20, 0x20); } - snd_soc_update_bits(tasha->codec, WCD9335_HPH_L_EN, 0x1F, - tasha->hph_l_gain); - snd_soc_update_bits(tasha->codec, WCD9335_HPH_R_EN, 0x1F, - tasha->hph_r_gain); + snd_soc_component_update_bits(tasha->component, + WCD9335_HPH_L_EN, 0x1F, + tasha->hph_l_gain); + snd_soc_component_update_bits(tasha->component, + WCD9335_HPH_R_EN, 0x1F, + tasha->hph_r_gain); } if (SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(tasha->codec, WCD9335_HPH_AUTO_CHOP, 0x20, - 0x00); + snd_soc_component_update_bits(tasha->component, + WCD9335_HPH_AUTO_CHOP, 0x20, + 0x00); } } -static void tasha_codec_override(struct snd_soc_codec *codec, +static void tasha_codec_override(struct snd_soc_component *component, int mode, int event) { if (mode == CLS_AB) { switch (event) { case SND_SOC_DAPM_POST_PMU: - if (!(snd_soc_read(codec, + if (!(snd_soc_component_read32(component, WCD9335_CDC_RX2_RX_PATH_CTL) & 0x10) && - (!(snd_soc_read(codec, + (!(snd_soc_component_read32(component, WCD9335_CDC_RX1_RX_PATH_CTL) & 0x10))) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x02); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x00); break; } @@ -3855,27 +3957,30 @@ static int tasha_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); int hph_mode = tasha->hph_mode; int ret = 0; - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: if ((!(strcmp(w->name, "ANC HPHR PA"))) && (test_bit(HPH_PA_DELAY, &tasha->status_mask))) { - snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0xC0, 0xC0); + snd_soc_component_update_bits( + component, WCD9335_ANA_HPH, 0xC0, 0xC0); } set_bit(HPH_PA_DELAY, &tasha->status_mask); if (!(strcmp(w->name, "HPHR PA"))) - snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x40, 0x40); + snd_soc_component_update_bits( + component, WCD9335_ANA_HPH, 0x40, 0x40); break; case SND_SOC_DAPM_POST_PMU: if (!(strcmp(w->name, "ANC HPHR PA"))) { - if ((snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0) - != 0xC0) + if ((snd_soc_component_read32( + component, WCD9335_ANA_HPH) & 0xC0) != 0xC0) /* * If PA_EN is not set (potentially in ANC case) * then do nothing for POST_PMU and let left @@ -3892,30 +3997,32 @@ static int tasha_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, clear_bit(HPH_PA_DELAY, &tasha->status_mask); } tasha_codec_hph_post_pa_config(tasha, hph_mode, event); - snd_soc_update_bits(codec, WCD9335_CDC_RX2_RX_PATH_CTL, - 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX2_RX_PATH_CTL, + 0x10, 0x00); /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) & - 0x10) - snd_soc_update_bits(codec, + if ((snd_soc_component_read32( + component, WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) & 0x10) + snd_soc_component_update_bits(component, WCD9335_CDC_RX2_RX_PATH_MIX_CTL, 0x10, 0x00); if (!(strcmp(w->name, "ANC HPHR PA"))) { /* Do everything needed for left channel */ - snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CTL, - 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX1_RX_PATH_CTL, + 0x10, 0x00); /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, + if ((snd_soc_component_read32(component, WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) & 0x10) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_RX1_RX_PATH_MIX_CTL, 0x10, 0x00); /* Remove ANC Rx from reset */ ret = tasha_codec_enable_anc(w, kcontrol, event); } - tasha_codec_override(codec, hph_mode, event); + tasha_codec_override(component, hph_mode, event); break; case SND_SOC_DAPM_PRE_PMD: @@ -3925,21 +4032,22 @@ static int tasha_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, tasha_codec_hph_post_pa_config(tasha, hph_mode, event); if (!(strcmp(w->name, "ANC HPHR PA")) || !(strcmp(w->name, "HPHR PA"))) - snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x40, 0x00); + snd_soc_component_update_bits(component, + WCD9335_ANA_HPH, 0x40, 0x00); break; case SND_SOC_DAPM_POST_PMD: /* 5ms sleep is required after PA is disabled as per * HW requirement */ usleep_range(5000, 5500); - tasha_codec_override(codec, hph_mode, event); + tasha_codec_override(component, hph_mode, event); blocking_notifier_call_chain(&tasha->notifier, WCD_EVENT_POST_HPHR_PA_OFF, &tasha->mbhc); if (!(strcmp(w->name, "ANC HPHR PA"))) { ret = tasha_codec_enable_anc(w, kcontrol, event); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_RX2_RX_PATH_CFG0, 0x10, 0x00); } break; @@ -3952,27 +4060,30 @@ static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); int hph_mode = tasha->hph_mode; int ret = 0; - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: if ((!(strcmp(w->name, "ANC HPHL PA"))) && (test_bit(HPH_PA_DELAY, &tasha->status_mask))) { - snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0xC0, 0xC0); + snd_soc_component_update_bits(component, + WCD9335_ANA_HPH, 0xC0, 0xC0); } if (!(strcmp(w->name, "HPHL PA"))) - snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x80, 0x80); + snd_soc_component_update_bits(component, + WCD9335_ANA_HPH, 0x80, 0x80); set_bit(HPH_PA_DELAY, &tasha->status_mask); break; case SND_SOC_DAPM_POST_PMU: if (!(strcmp(w->name, "ANC HPHL PA"))) { - if ((snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0) - != 0xC0) + if ((snd_soc_component_read32( + component, WCD9335_ANA_HPH) & 0xC0) != 0xC0) /* * If PA_EN is not set (potentially in ANC case) * then do nothing for POST_PMU and let right @@ -3990,31 +4101,33 @@ static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, } tasha_codec_hph_post_pa_config(tasha, hph_mode, event); - snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CTL, - 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX1_RX_PATH_CTL, + 0x10, 0x00); /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) & - 0x10) - snd_soc_update_bits(codec, + if ((snd_soc_component_read32( + component, WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) & 0x10) + snd_soc_component_update_bits(component, WCD9335_CDC_RX1_RX_PATH_MIX_CTL, 0x10, 0x00); if (!(strcmp(w->name, "ANC HPHL PA"))) { /* Do everything needed for right channel */ - snd_soc_update_bits(codec, WCD9335_CDC_RX2_RX_PATH_CTL, - 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX2_RX_PATH_CTL, + 0x10, 0x00); /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, + if ((snd_soc_component_read32(component, WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) & 0x10) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_RX2_RX_PATH_MIX_CTL, 0x10, 0x00); /* Remove ANC Rx from reset */ ret = tasha_codec_enable_anc(w, kcontrol, event); } - tasha_codec_override(codec, hph_mode, event); + tasha_codec_override(component, hph_mode, event); break; case SND_SOC_DAPM_PRE_PMD: blocking_notifier_call_chain(&tasha->notifier, @@ -4023,21 +4136,22 @@ static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, tasha_codec_hph_post_pa_config(tasha, hph_mode, event); if (!(strcmp(w->name, "ANC HPHL PA")) || !(strcmp(w->name, "HPHL PA"))) - snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x80, 0x00); + snd_soc_component_update_bits(component, + WCD9335_ANA_HPH, 0x80, 0x00); break; case SND_SOC_DAPM_POST_PMD: /* 5ms sleep is required after PA is disabled as per * HW requirement */ usleep_range(5000, 5500); - tasha_codec_override(codec, hph_mode, event); + tasha_codec_override(component, hph_mode, event); blocking_notifier_call_chain(&tasha->notifier, WCD_EVENT_POST_HPHL_PA_OFF, &tasha->mbhc); if (!(strcmp(w->name, "ANC HPHL PA"))) { ret = tasha_codec_enable_anc(w, kcontrol, event); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x00); } break; @@ -4050,11 +4164,12 @@ static int tasha_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); u16 lineout_vol_reg = 0, lineout_mix_vol_reg = 0; int ret = 0; - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); if (w->reg == WCD9335_ANA_LO_1_2) { if (w->shift == 7) { @@ -4073,7 +4188,7 @@ static int tasha_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w, lineout_mix_vol_reg = WCD9335_CDC_RX6_RX_PATH_MIX_CTL; } } else { - dev_err(codec->dev, "%s: Error enabling lineout PA\n", + dev_err(component->dev, "%s: Error enabling lineout PA\n", __func__); return -EINVAL; } @@ -4084,32 +4199,33 @@ static int tasha_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w, * HW requirement */ usleep_range(5000, 5500); - snd_soc_update_bits(codec, lineout_vol_reg, + snd_soc_component_update_bits(component, lineout_vol_reg, 0x10, 0x00); /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, lineout_mix_vol_reg)) & 0x10) - snd_soc_update_bits(codec, + if ((snd_soc_component_read32( + component, lineout_mix_vol_reg)) & 0x10) + snd_soc_component_update_bits(component, lineout_mix_vol_reg, 0x10, 0x00); if (!(strcmp(w->name, "ANC LINEOUT1 PA")) || !(strcmp(w->name, "ANC LINEOUT2 PA"))) ret = tasha_codec_enable_anc(w, kcontrol, event); - tasha_codec_override(codec, CLS_AB, event); + tasha_codec_override(component, CLS_AB, event); break; case SND_SOC_DAPM_POST_PMD: /* 5ms sleep is required after PA is disabled as per * HW requirement */ usleep_range(5000, 5500); - tasha_codec_override(codec, CLS_AB, event); + tasha_codec_override(component, CLS_AB, event); if (!(strcmp(w->name, "ANC LINEOUT1 PA")) || !(strcmp(w->name, "ANC LINEOUT2 PA"))) { ret = tasha_codec_enable_anc(w, kcontrol, event); if (!(strcmp(w->name, "ANC LINEOUT1 PA"))) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_RX3_RX_PATH_CFG0, 0x10, 0x10); else - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_RX4_RX_PATH_CFG0, 0x10, 0x10); } break; @@ -4123,14 +4239,15 @@ static void tasha_spk_anc_update_callback(struct work_struct *work) struct spk_anc_work *spk_anc_dwork; struct tasha_priv *tasha; struct delayed_work *delayed_work; - struct snd_soc_codec *codec; + struct snd_soc_component *component; delayed_work = to_delayed_work(work); spk_anc_dwork = container_of(delayed_work, struct spk_anc_work, dwork); tasha = spk_anc_dwork->tasha; - codec = tasha->codec; + component = tasha->component; - snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_CFG0, 0x10, 0x10); + snd_soc_component_update_bits(component, WCD9335_CDC_RX7_RX_PATH_CFG0, + 0x10, 0x10); } static int tasha_codec_enable_spk_anc(struct snd_soc_dapm_widget *w, @@ -4138,10 +4255,11 @@ static int tasha_codec_enable_spk_anc(struct snd_soc_dapm_widget *w, int event) { int ret = 0; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); - dev_dbg(codec->dev, "%s %s %d %d\n", __func__, w->name, event, + dev_dbg(component->dev, "%s %s %d %d\n", __func__, w->name, event, tasha->anc_func); if (!tasha->anc_func) @@ -4155,8 +4273,9 @@ static int tasha_codec_enable_spk_anc(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: cancel_delayed_work_sync(&tasha->spk_anc_dwork.dwork); - snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_CFG0, - 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX7_RX_PATH_CFG0, + 0x10, 0x00); ret = tasha_codec_enable_anc(w, kcontrol, event); break; } @@ -4167,10 +4286,11 @@ static int tasha_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); int ret = 0; - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_POST_PMU: @@ -4178,12 +4298,13 @@ static int tasha_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, * HW requirement */ usleep_range(5000, 5500); - snd_soc_update_bits(codec, WCD9335_CDC_RX0_RX_PATH_CTL, - 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX0_RX_PATH_CTL, + 0x10, 0x00); /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, WCD9335_CDC_RX0_RX_PATH_MIX_CTL)) & - 0x10) - snd_soc_update_bits(codec, + if ((snd_soc_component_read32( + component, WCD9335_CDC_RX0_RX_PATH_MIX_CTL)) & 0x10) + snd_soc_component_update_bits(component, WCD9335_CDC_RX0_RX_PATH_MIX_CTL, 0x10, 0x00); break; @@ -4195,7 +4316,7 @@ static int tasha_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, if (!(strcmp(w->name, "ANC EAR PA"))) { ret = tasha_codec_enable_anc(w, kcontrol, event); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_RX0_RX_PATH_CFG0, 0x10, 0x00); } break; @@ -4204,21 +4325,21 @@ static int tasha_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, return ret; } -static void tasha_codec_hph_mode_gain_opt(struct snd_soc_codec *codec, +static void tasha_codec_hph_mode_gain_opt(struct snd_soc_component *component, u8 gain) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); u8 hph_l_en, hph_r_en; u8 l_val, r_val; u8 hph_pa_status; bool is_hphl_pa, is_hphr_pa; - hph_pa_status = snd_soc_read(codec, WCD9335_ANA_HPH); + hph_pa_status = snd_soc_component_read32(component, WCD9335_ANA_HPH); is_hphl_pa = hph_pa_status >> 7; is_hphr_pa = (hph_pa_status & 0x40) >> 6; - hph_l_en = snd_soc_read(codec, WCD9335_HPH_L_EN); - hph_r_en = snd_soc_read(codec, WCD9335_HPH_R_EN); + hph_l_en = snd_soc_component_read32(component, WCD9335_HPH_L_EN); + hph_r_en = snd_soc_component_read32(component, WCD9335_HPH_R_EN); l_val = (hph_l_en & 0xC0) | 0x20 | gain; r_val = (hph_r_en & 0xC0) | 0x20 | gain; @@ -4230,102 +4351,135 @@ static void tasha_codec_hph_mode_gain_opt(struct snd_soc_codec *codec, * PA gains to be applied after PAs are enabled */ if ((l_val != hph_l_en) && !is_hphl_pa) { - snd_soc_write(codec, WCD9335_HPH_L_EN, l_val); + snd_soc_component_write(component, WCD9335_HPH_L_EN, l_val); tasha->hph_l_gain = hph_l_en & 0x1F; } if ((r_val != hph_r_en) && !is_hphr_pa) { - snd_soc_write(codec, WCD9335_HPH_R_EN, r_val); + snd_soc_component_write(component, WCD9335_HPH_R_EN, r_val); tasha->hph_r_gain = hph_r_en & 0x1F; } } -static void tasha_codec_hph_lohifi_config(struct snd_soc_codec *codec, +static void tasha_codec_hph_lohifi_config(struct snd_soc_component *component, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) { - snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_PA, 0x0F, 0x06); - snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2, - 0xF0, 0x40); - snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03); - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08); - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C); - tasha_codec_hph_mode_gain_opt(codec, 0x11); + snd_soc_component_update_bits(component, + WCD9335_RX_BIAS_HPH_PA, + 0x0F, 0x06); + snd_soc_component_update_bits(component, + WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2, + 0xF0, 0x40); + snd_soc_component_update_bits(component, + WCD9335_HPH_CNP_WG_CTL, + 0x07, 0x03); + snd_soc_component_update_bits(component, + WCD9335_HPH_PA_CTL2, + 0x08, 0x08); + snd_soc_component_update_bits(component, + WCD9335_HPH_PA_CTL1, + 0x0E, 0x0C); + tasha_codec_hph_mode_gain_opt(component, 0x11); } if (SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00); - snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02); - snd_soc_write(codec, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8A); - snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_PA, 0x0F, 0x0A); + snd_soc_component_update_bits(component, + WCD9335_HPH_PA_CTL2, + 0x08, 0x00); + snd_soc_component_update_bits(component, + WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02); + snd_soc_component_write(component, + WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8A); + snd_soc_component_update_bits(component, + WCD9335_RX_BIAS_HPH_PA, + 0x0F, 0x0A); } } -static void tasha_codec_hph_lp_config(struct snd_soc_codec *codec, +static void tasha_codec_hph_lp_config(struct snd_soc_component *component, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) { - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C); - tasha_codec_hph_mode_gain_opt(codec, 0x10); - snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03); - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08); - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x04, 0x04); - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x20, 0x20); - snd_soc_update_bits(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x07, - 0x01); - snd_soc_update_bits(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x70, - 0x10); - snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO, - 0x0F, 0x01); - snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO, - 0xF0, 0x10); + snd_soc_component_update_bits(component, + WCD9335_HPH_PA_CTL1, 0x0E, 0x0C); + tasha_codec_hph_mode_gain_opt(component, 0x10); + snd_soc_component_update_bits(component, + WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03); + snd_soc_component_update_bits(component, + WCD9335_HPH_PA_CTL2, 0x08, 0x08); + snd_soc_component_update_bits(component, + WCD9335_HPH_PA_CTL2, 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD9335_HPH_PA_CTL2, 0x20, 0x20); + snd_soc_component_update_bits(component, + WCD9335_HPH_RDAC_LDO_CTL, 0x07, 0x01); + snd_soc_component_update_bits(component, + WCD9335_HPH_RDAC_LDO_CTL, 0x70, 0x10); + snd_soc_component_update_bits(component, + WCD9335_RX_BIAS_HPH_RDAC_LDO, 0x0F, 0x01); + snd_soc_component_update_bits(component, + WCD9335_RX_BIAS_HPH_RDAC_LDO, 0xF0, 0x10); } if (SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_write(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO, 0x88); - snd_soc_write(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x33); - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x20, 0x00); - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x04, 0x00); - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00); - snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02); - snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0xC0, 0x80); - snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0xC0, 0x80); - } -} - -static void tasha_codec_hph_hifi_config(struct snd_soc_codec *codec, + snd_soc_component_write(component, + WCD9335_RX_BIAS_HPH_RDAC_LDO, 0x88); + snd_soc_component_write(component, + WCD9335_HPH_RDAC_LDO_CTL, 0x33); + snd_soc_component_update_bits(component, + WCD9335_HPH_PA_CTL2, 0x20, 0x00); + snd_soc_component_update_bits(component, + WCD9335_HPH_PA_CTL2, 0x04, 0x00); + snd_soc_component_update_bits(component, + WCD9335_HPH_PA_CTL2, 0x08, 0x00); + snd_soc_component_update_bits(component, + WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02); + snd_soc_component_update_bits(component, + WCD9335_HPH_R_EN, 0xC0, 0x80); + snd_soc_component_update_bits(component, + WCD9335_HPH_L_EN, 0xC0, 0x80); + } +} + +static void tasha_codec_hph_hifi_config(struct snd_soc_component *component, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) { - snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03); - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08); - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C); - tasha_codec_hph_mode_gain_opt(codec, 0x11); + snd_soc_component_update_bits(component, + WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03); + snd_soc_component_update_bits(component, + WCD9335_HPH_PA_CTL2, 0x08, 0x08); + snd_soc_component_update_bits(component, + WCD9335_HPH_PA_CTL1, 0x0E, 0x0C); + tasha_codec_hph_mode_gain_opt(component, 0x11); } if (SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00); - snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02); + snd_soc_component_update_bits(component, + WCD9335_HPH_PA_CTL2, 0x08, 0x00); + snd_soc_component_update_bits(component, + WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02); } } -static void tasha_codec_hph_mode_config(struct snd_soc_codec *codec, +static void tasha_codec_hph_mode_config(struct snd_soc_component *component, int event, int mode) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); if (!TASHA_IS_2_0(tasha->wcd9xxx)) return; switch (mode) { case CLS_H_LP: - tasha_codec_hph_lp_config(codec, event); + tasha_codec_hph_lp_config(component, event); break; case CLS_H_LOHIFI: - tasha_codec_hph_lohifi_config(codec, event); + tasha_codec_hph_lohifi_config(component, event); break; case CLS_H_HIFI: - tasha_codec_hph_hifi_config(codec, event); + tasha_codec_hph_hifi_config(component, event); break; } } @@ -4334,15 +4488,16 @@ static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); int hph_mode = tasha->hph_mode; u8 dem_inp; int ret = 0; - dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, - w->name, event, hph_mode); + dev_dbg(component->dev, "%s wname: %s event: %d hph_mode: %d\n", + __func__, w->name, event, hph_mode); switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -4353,27 +4508,29 @@ static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, } /* Read DEM INP Select */ - dem_inp = snd_soc_read(codec, WCD9335_CDC_RX2_RX_PATH_SEC0) & - 0x03; + dem_inp = snd_soc_component_read32( + component, WCD9335_CDC_RX2_RX_PATH_SEC0) & + 0x03; if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { - dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", + dev_err(component->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", __func__, hph_mode); return -EINVAL; } - wcd_clsh_fsm(codec, &tasha->clsh_d, + wcd_clsh_fsm(component, &tasha->clsh_d, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_HPHR, ((hph_mode == CLS_H_LOHIFI) ? CLS_H_HIFI : hph_mode)); if (!(strcmp(w->name, "RX INT2 DAC"))) - snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x10, 0x10); + snd_soc_component_update_bits(component, + WCD9335_ANA_HPH, 0x10, 0x10); - tasha_codec_hph_mode_config(codec, event, hph_mode); + tasha_codec_hph_mode_config(component, event, hph_mode); if (tasha->anc_func) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_RX2_RX_PATH_CFG0, 0x10, 0x10); break; @@ -4382,18 +4539,20 @@ static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, usleep_range(1000, 1100); if ((hph_mode == CLS_H_LP) && (TASHA_IS_1_1(wcd9xxx))) { - snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL, - 0x03, 0x03); + snd_soc_component_update_bits(component, + WCD9335_HPH_L_DAC_CTL, 0x03, 0x03); } break; case SND_SOC_DAPM_PRE_PMD: if ((hph_mode == CLS_H_LP) && (TASHA_IS_1_1(wcd9xxx))) { - snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL, - 0x03, 0x00); + snd_soc_component_update_bits(component, + WCD9335_HPH_L_DAC_CTL, + 0x03, 0x00); } if (!(strcmp(w->name, "RX INT2 DAC"))) - snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD9335_ANA_HPH, 0x10, 0x00); break; case SND_SOC_DAPM_POST_PMD: /* 1000us required as per HW requirement */ @@ -4401,9 +4560,9 @@ static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, if (!(wcd_clsh_get_clsh_state(&tasha->clsh_d) & WCD_CLSH_STATE_HPHL)) - tasha_codec_hph_mode_config(codec, event, hph_mode); + tasha_codec_hph_mode_config(component, event, hph_mode); - wcd_clsh_fsm(codec, &tasha->clsh_d, + wcd_clsh_fsm(component, &tasha->clsh_d, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_HPHR, ((hph_mode == CLS_H_LOHIFI) ? @@ -4418,16 +4577,17 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); int hph_mode = tasha->hph_mode; u8 dem_inp; int ret = 0; uint32_t impedl = 0, impedr = 0; - dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, - w->name, event, hph_mode); + dev_dbg(component->dev, "%s wname: %s event: %d hph_mode: %d\n", + __func__, w->name, event, hph_mode); switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -4438,36 +4598,38 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, } /* Read DEM INP Select */ - dem_inp = snd_soc_read(codec, WCD9335_CDC_RX1_RX_PATH_SEC0) & - 0x03; + dem_inp = snd_soc_component_read32( + component, WCD9335_CDC_RX1_RX_PATH_SEC0) & + 0x03; if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { - dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", + dev_err(component->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", __func__, hph_mode); return -EINVAL; } - wcd_clsh_fsm(codec, &tasha->clsh_d, + wcd_clsh_fsm(component, &tasha->clsh_d, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_HPHL, ((hph_mode == CLS_H_LOHIFI) ? CLS_H_HIFI : hph_mode)); if (!(strcmp(w->name, "RX INT1 DAC"))) - snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x20, 0x20); + snd_soc_component_update_bits(component, + WCD9335_ANA_HPH, 0x20, 0x20); - tasha_codec_hph_mode_config(codec, event, hph_mode); + tasha_codec_hph_mode_config(component, event, hph_mode); if (tasha->anc_func) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x10); ret = wcd_mbhc_get_impedance(&tasha->mbhc, &impedl, &impedr); if (!ret) { - wcd_clsh_imped_config(codec, impedl, false); + wcd_clsh_imped_config(component, impedl, false); set_bit(CLASSH_CONFIG, &tasha->status_mask); } else { - dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n", + dev_dbg(component->dev, "%s: Failed to get mbhc impedance %d\n", __func__, ret); ret = 0; } @@ -4479,17 +4641,20 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, usleep_range(1000, 1100); if ((hph_mode == CLS_H_LP) && (TASHA_IS_1_1(wcd9xxx))) { - snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL, - 0x03, 0x03); + snd_soc_component_update_bits(component, + WCD9335_HPH_L_DAC_CTL, + 0x03, 0x03); } break; case SND_SOC_DAPM_PRE_PMD: if (!(strcmp(w->name, "RX INT1 DAC"))) - snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x20, 0x00); + snd_soc_component_update_bits(component, + WCD9335_ANA_HPH, 0x20, 0x00); if ((hph_mode == CLS_H_LP) && (TASHA_IS_1_1(wcd9xxx))) { - snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL, - 0x03, 0x00); + snd_soc_component_update_bits(component, + WCD9335_HPH_L_DAC_CTL, + 0x03, 0x00); } break; case SND_SOC_DAPM_POST_PMD: @@ -4498,18 +4663,18 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, if (!(wcd_clsh_get_clsh_state(&tasha->clsh_d) & WCD_CLSH_STATE_HPHR)) - tasha_codec_hph_mode_config(codec, event, hph_mode); - wcd_clsh_fsm(codec, &tasha->clsh_d, + tasha_codec_hph_mode_config(component, event, hph_mode); + wcd_clsh_fsm(component, &tasha->clsh_d, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_HPHL, ((hph_mode == CLS_H_LOHIFI) ? CLS_H_HIFI : hph_mode)); if (test_bit(CLASSH_CONFIG, &tasha->status_mask)) { - wcd_clsh_imped_config(codec, impedl, true); + wcd_clsh_imped_config(component, impedl, true); clear_bit(CLASSH_CONFIG, &tasha->status_mask); } else - dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n", + dev_dbg(component->dev, "%s: Failed to get mbhc impedance %d\n", __func__, ret); @@ -4523,11 +4688,12 @@ static int tasha_codec_lineout_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); int ret = 0; - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -4536,22 +4702,22 @@ static int tasha_codec_lineout_dac_event(struct snd_soc_dapm_widget *w, !strcmp(w->name, "RX INT4 DAC"))) ret = tasha_codec_enable_anc(w, kcontrol, event); - wcd_clsh_fsm(codec, &tasha->clsh_d, + wcd_clsh_fsm(component, &tasha->clsh_d, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_LO, CLS_AB); if (tasha->anc_func) { if (!strcmp(w->name, "RX INT3 DAC")) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_RX3_RX_PATH_CFG0, 0x10, 0x10); else if (!strcmp(w->name, "RX INT4 DAC")) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_RX4_RX_PATH_CFG0, 0x10, 0x10); } break; case SND_SOC_DAPM_POST_PMD: - wcd_clsh_fsm(codec, &tasha->clsh_d, + wcd_clsh_fsm(component, &tasha->clsh_d, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_LO, CLS_AB); @@ -4572,23 +4738,24 @@ static int tasha_codec_ear_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); int ret = 0; - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: if (tasha->anc_func) ret = tasha_codec_enable_anc(w, kcontrol, event); - wcd_clsh_fsm(codec, &tasha->clsh_d, + wcd_clsh_fsm(component, &tasha->clsh_d, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_EAR, CLS_H_NORMAL); if (tasha->anc_func) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_RX0_RX_PATH_CFG0, 0x10, 0x10); break; @@ -4597,7 +4764,7 @@ static int tasha_codec_ear_dac_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMD: break; case SND_SOC_DAPM_POST_PMD: - wcd_clsh_fsm(codec, &tasha->clsh_d, + wcd_clsh_fsm(component, &tasha->clsh_d, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_EAR, CLS_H_NORMAL); @@ -4611,11 +4778,12 @@ static int tasha_codec_spk_boost_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); u16 boost_path_ctl, boost_path_cfg1; u16 reg, reg_mix; - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); if (!strcmp(w->name, "RX INT7 CHAIN")) { boost_path_ctl = WCD9335_CDC_BOOST0_BOOST_PATH_CTL; @@ -4628,22 +4796,27 @@ static int tasha_codec_spk_boost_event(struct snd_soc_dapm_widget *w, reg = WCD9335_CDC_RX8_RX_PATH_CTL; reg_mix = WCD9335_CDC_RX8_RX_PATH_MIX_CTL; } else { - dev_err(codec->dev, "%s: unknown widget: %s\n", + dev_err(component->dev, "%s: unknown widget: %s\n", __func__, w->name); return -EINVAL; } switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x10); - snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x01); - snd_soc_update_bits(codec, reg, 0x10, 0x00); - if ((snd_soc_read(codec, reg_mix)) & 0x10) - snd_soc_update_bits(codec, reg_mix, 0x10, 0x00); + snd_soc_component_update_bits(component, boost_path_ctl, + 0x10, 0x10); + snd_soc_component_update_bits(component, boost_path_cfg1, + 0x01, 0x01); + snd_soc_component_update_bits(component, reg, 0x10, 0x00); + if ((snd_soc_component_read32(component, reg_mix)) & 0x10) + snd_soc_component_update_bits(component, reg_mix, + 0x10, 0x00); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x00); - snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x00); + snd_soc_component_update_bits(component, boost_path_cfg1, + 0x01, 0x00); + snd_soc_component_update_bits(component, boost_path_ctl, + 0x10, 0x00); break; }; @@ -4705,10 +4878,10 @@ static u16 tasha_interp_get_primary_reg(u16 reg, u16 *ind) return prim_int_reg; } -static void tasha_codec_hd2_control(struct snd_soc_codec *codec, +static void tasha_codec_hd2_control(struct snd_soc_component *component, u16 prim_int_reg, int event) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); u16 hd2_scale_reg; u16 hd2_enable_reg = 0; @@ -4725,23 +4898,29 @@ static void tasha_codec_hd2_control(struct snd_soc_codec *codec, } if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { - snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x10); - snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x01); - snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x04); + snd_soc_component_update_bits(component, hd2_scale_reg, + 0x3C, 0x10); + snd_soc_component_update_bits(component, hd2_scale_reg, + 0x03, 0x01); + snd_soc_component_update_bits(component, hd2_enable_reg, + 0x04, 0x04); } if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x00); - snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x00); - snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x00); + snd_soc_component_update_bits(component, hd2_enable_reg, + 0x04, 0x00); + snd_soc_component_update_bits(component, hd2_scale_reg, + 0x03, 0x00); + snd_soc_component_update_bits(component, hd2_scale_reg, + 0x3C, 0x00); } } static int tasha_codec_enable_prim_interpolator( - struct snd_soc_codec *codec, + struct snd_soc_component *component, u16 reg, int event) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); u16 prim_int_reg; u16 ind = 0; @@ -4751,36 +4930,38 @@ static int tasha_codec_enable_prim_interpolator( case SND_SOC_DAPM_PRE_PMU: tasha->prim_int_users[ind]++; if (tasha->prim_int_users[ind] == 1) { - snd_soc_update_bits(codec, prim_int_reg, + snd_soc_component_update_bits(component, prim_int_reg, 0x10, 0x10); - tasha_codec_hd2_control(codec, prim_int_reg, event); - snd_soc_update_bits(codec, prim_int_reg, + tasha_codec_hd2_control(component, prim_int_reg, event); + snd_soc_component_update_bits(component, prim_int_reg, 1 << 0x5, 1 << 0x5); } if ((reg != prim_int_reg) && - ((snd_soc_read(codec, prim_int_reg)) & 0x10)) - snd_soc_update_bits(codec, reg, 0x10, 0x10); + ((snd_soc_component_read32( + component, prim_int_reg)) & 0x10)) + snd_soc_component_update_bits(component, reg, + 0x10, 0x10); break; case SND_SOC_DAPM_POST_PMD: tasha->prim_int_users[ind]--; if (tasha->prim_int_users[ind] == 0) { - snd_soc_update_bits(codec, prim_int_reg, + snd_soc_component_update_bits(component, prim_int_reg, 1 << 0x5, 0 << 0x5); - snd_soc_update_bits(codec, prim_int_reg, + snd_soc_component_update_bits(component, prim_int_reg, 0x40, 0x40); - snd_soc_update_bits(codec, prim_int_reg, + snd_soc_component_update_bits(component, prim_int_reg, 0x40, 0x00); - tasha_codec_hd2_control(codec, prim_int_reg, event); + tasha_codec_hd2_control(component, prim_int_reg, event); } break; }; - dev_dbg(codec->dev, "%s: primary interpolator: INT%d, users: %d\n", + dev_dbg(component->dev, "%s: primary interpolator: INT%d, users: %d\n", __func__, ind, tasha->prim_int_users[ind]); return 0; } -static int tasha_codec_enable_spline_src(struct snd_soc_codec *codec, +static int tasha_codec_enable_spline_src(struct snd_soc_component *component, int src_num, int event) { @@ -4791,7 +4972,7 @@ static int tasha_codec_enable_spline_src(struct snd_soc_codec *codec, int *src_users, count, spl_src = SPLINE_SRC0; u16 src_clk_reg = WCD9335_SPLINE_SRC0_CLK_RST_CTL_0; - tasha = snd_soc_codec_get_drvdata(codec); + tasha = snd_soc_component_get_drvdata(component); switch (src_num) { case SRC_IN_HPHL: @@ -4859,16 +5040,19 @@ static int tasha_codec_enable_spline_src(struct snd_soc_codec *codec, count = *src_users; count++; if (count == 1) { - if ((snd_soc_read(codec, src_clk_reg) & 0x02) || - (snd_soc_read(codec, src_paired_reg) & 0x02)) { - snd_soc_update_bits(codec, src_clk_reg, 0x02, - 0x00); - snd_soc_update_bits(codec, src_paired_reg, - 0x02, 0x00); + if ((snd_soc_component_read32( + component, src_clk_reg) & 0x02) || + (snd_soc_component_read32( + component, src_paired_reg) & 0x02)) { + snd_soc_component_update_bits(component, + src_clk_reg, 0x02, 0x00); + snd_soc_component_update_bits(component, + src_paired_reg, 0x02, 0x00); } - snd_soc_update_bits(codec, src_clk_reg, 0x01, 0x01); - snd_soc_update_bits(codec, rx_path_cfg_reg, 0x80, - 0x80); + snd_soc_component_update_bits(component, src_clk_reg, + 0x01, 0x01); + snd_soc_component_update_bits(component, + rx_path_cfg_reg, 0x80, 0x80); } *src_users = count; break; @@ -4876,18 +5060,19 @@ static int tasha_codec_enable_spline_src(struct snd_soc_codec *codec, count = *src_users; count--; if (count == 0) { - snd_soc_update_bits(codec, rx_path_cfg_reg, 0x80, - 0x00); - snd_soc_update_bits(codec, src_clk_reg, 0x03, 0x02); + snd_soc_component_update_bits(component, + rx_path_cfg_reg, 0x80, 0x00); + snd_soc_component_update_bits(component, + src_clk_reg, 0x03, 0x02); /* default sample rate */ - snd_soc_update_bits(codec, rx_path_ctl_reg, 0x0f, - 0x04); + snd_soc_component_update_bits(component, + rx_path_ctl_reg, 0x0f, 0x04); } *src_users = count; break; }; - dev_dbg(codec->dev, "%s: Spline SRC%d, users: %d\n", + dev_dbg(component->dev, "%s: Spline SRC%d, users: %d\n", __func__, spl_src, *src_users); return 0; } @@ -4896,40 +5081,42 @@ static int tasha_codec_enable_spline_resampler(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); int ret = 0; u8 src_in; - src_in = snd_soc_read(codec, WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0); + src_in = snd_soc_component_read32( + component, WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0); if (!(src_in & 0xFF)) { - dev_err(codec->dev, "%s: Spline SRC%u input not selected\n", + dev_err(component->dev, "%s: Spline SRC%u input not selected\n", __func__, w->shift); return -EINVAL; } switch (w->shift) { case SPLINE_SRC0: - ret = tasha_codec_enable_spline_src(codec, + ret = tasha_codec_enable_spline_src(component, ((src_in & 0x03) == 1) ? SRC_IN_HPHL : SRC_IN_LO1, event); break; case SPLINE_SRC1: - ret = tasha_codec_enable_spline_src(codec, + ret = tasha_codec_enable_spline_src(component, ((src_in & 0x0C) == 4) ? SRC_IN_HPHR : SRC_IN_LO2, event); break; case SPLINE_SRC2: - ret = tasha_codec_enable_spline_src(codec, + ret = tasha_codec_enable_spline_src(component, ((src_in & 0x30) == 0x10) ? SRC_IN_LO3 : SRC_IN_SPKRL, event); break; case SPLINE_SRC3: - ret = tasha_codec_enable_spline_src(codec, + ret = tasha_codec_enable_spline_src(component, ((src_in & 0xC0) == 0x40) ? SRC_IN_LO4 : SRC_IN_SPKRR, event); break; default: - dev_err(codec->dev, "%s: Invalid spline src:%u\n", __func__, + dev_err(component->dev, "%s: Invalid spline src:%u\n", __func__, w->shift); ret = -EINVAL; }; @@ -4940,11 +5127,12 @@ static int tasha_codec_enable_spline_resampler(struct snd_soc_dapm_widget *w, static int tasha_codec_enable_swr(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); struct tasha_priv *tasha; int i, ch_cnt; - tasha = snd_soc_codec_get_drvdata(codec); + tasha = snd_soc_component_get_drvdata(component); if (!tasha->nr) return 0; @@ -4987,11 +5175,11 @@ static int tasha_codec_enable_swr(struct snd_soc_dapm_widget *w, return 0; } -static int tasha_codec_config_ear_spkr_gain(struct snd_soc_codec *codec, +static int tasha_codec_config_ear_spkr_gain(struct snd_soc_component *component, int event, int gain_reg) { int comp_gain_offset, val; - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); switch (tasha->spkr_mode) { /* Compander gain in SPKR_MODE1 case is 12 dB */ @@ -5013,9 +5201,9 @@ static int tasha_codec_config_ear_spkr_gain(struct snd_soc_codec *codec, (tasha->ear_spkr_gain != 0)) { /* For example, val is -8(-12+5-1) for 4dB of gain */ val = comp_gain_offset + tasha->ear_spkr_gain - 1; - snd_soc_write(codec, gain_reg, val); + snd_soc_component_write(component, gain_reg, val); - dev_dbg(codec->dev, "%s: RX7 Volume %d dB\n", + dev_dbg(component->dev, "%s: RX7 Volume %d dB\n", __func__, val); } break; @@ -5028,9 +5216,9 @@ static int tasha_codec_config_ear_spkr_gain(struct snd_soc_codec *codec, (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL || gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL) && (tasha->ear_spkr_gain != 0)) { - snd_soc_write(codec, gain_reg, 0x0); + snd_soc_component_write(component, gain_reg, 0x0); - dev_dbg(codec->dev, "%s: Reset RX7 Volume to 0 dB\n", + dev_dbg(component->dev, "%s: Reset RX7 Volume to 0 dB\n", __func__); } break; @@ -5042,13 +5230,14 @@ static int tasha_codec_config_ear_spkr_gain(struct snd_soc_codec *codec, static int tasha_codec_enable_mix_path(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); u16 gain_reg; int offset_val = 0; int val = 0; - dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name); switch (w->reg) { case WCD9335_CDC_RX0_RX_PATH_MIX_CTL: @@ -5079,7 +5268,7 @@ static int tasha_codec_enable_mix_path(struct snd_soc_dapm_widget *w, gain_reg = WCD9335_CDC_RX8_RX_VOL_MIX_CTL; break; default: - dev_err(codec->dev, "%s: No gain register avail for %s\n", + dev_err(component->dev, "%s: No gain register avail for %s\n", __func__, w->name); return 0; }; @@ -5091,22 +5280,24 @@ static int tasha_codec_enable_mix_path(struct snd_soc_dapm_widget *w, tasha->comp_enabled[COMPANDER_8]) && (gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL || gain_reg == WCD9335_CDC_RX8_RX_VOL_MIX_CTL)) { - snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1, - 0x01, 0x01); - snd_soc_update_bits(codec, - WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, - 0x01, 0x01); - snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1, - 0x01, 0x01); - snd_soc_update_bits(codec, - WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, - 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x01); offset_val = -2; } - val = snd_soc_read(codec, gain_reg); + val = snd_soc_component_read32(component, gain_reg); val += offset_val; - snd_soc_write(codec, gain_reg, val); - tasha_codec_config_ear_spkr_gain(codec, event, gain_reg); + snd_soc_component_write(component, gain_reg, val); + tasha_codec_config_ear_spkr_gain(component, event, gain_reg); break; case SND_SOC_DAPM_POST_PMD: if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && @@ -5114,22 +5305,24 @@ static int tasha_codec_enable_mix_path(struct snd_soc_dapm_widget *w, tasha->comp_enabled[COMPANDER_8]) && (gain_reg == WCD9335_CDC_RX7_RX_VOL_MIX_CTL || gain_reg == WCD9335_CDC_RX8_RX_VOL_MIX_CTL)) { - snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1, - 0x01, 0x00); - snd_soc_update_bits(codec, - WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, - 0x01, 0x00); - snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1, - 0x01, 0x00); - snd_soc_update_bits(codec, - WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, - 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x00); offset_val = 2; - val = snd_soc_read(codec, gain_reg); + val = snd_soc_component_read32(component, gain_reg); val += offset_val; - snd_soc_write(codec, gain_reg, val); + snd_soc_component_write(component, gain_reg, val); } - tasha_codec_config_ear_spkr_gain(codec, event, gain_reg); + tasha_codec_config_ear_spkr_gain(component, event, gain_reg); break; }; @@ -5140,14 +5333,16 @@ static int __tasha_cdc_native_clk_enable(struct tasha_priv *tasha, bool enable) { int ret = 0; - struct snd_soc_codec *codec = tasha->codec; + struct snd_soc_component *component = tasha->component; if (!tasha->wcd_native_clk) { - dev_err(tasha->dev, "%s: wcd native clock is NULL\n", __func__); + dev_err(tasha->dev, "%s: wcd native clock is NULL\n", + __func__); return -EINVAL; } - dev_dbg(tasha->dev, "%s: native_clk_enable = %u\n", __func__, enable); + dev_dbg(tasha->dev, "%s: native_clk_enable = %u\n", + __func__, enable); if (enable) { ret = clk_prepare_enable(tasha->wcd_native_clk); @@ -5157,40 +5352,47 @@ static int __tasha_cdc_native_clk_enable(struct tasha_priv *tasha, goto err; } if (++tasha->native_clk_users == 1) { - snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL, - 0x10, 0x10); - snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL, - 0x80, 0x80); - snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_GATE, - 0x04, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, + WCD9335_CLOCK_TEST_CTL, + 0x10, 0x10); + snd_soc_component_update_bits(component, + WCD9335_CLOCK_TEST_CTL, + 0x80, 0x80); + snd_soc_component_update_bits(component, + WCD9335_CODEC_RPM_CLK_GATE, + 0x04, 0x00); + snd_soc_component_update_bits(component, WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x02, 0x02); } } else { if (tasha->native_clk_users && (--tasha->native_clk_users == 0)) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x02, 0x00); - snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_GATE, - 0x04, 0x04); - snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL, - 0x80, 0x00); - snd_soc_update_bits(codec, WCD9335_CLOCK_TEST_CTL, - 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CODEC_RPM_CLK_GATE, + 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD9335_CLOCK_TEST_CTL, + 0x80, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CLOCK_TEST_CTL, + 0x10, 0x00); } clk_disable_unprepare(tasha->wcd_native_clk); } - dev_dbg(codec->dev, "%s: native_clk_users: %d\n", __func__, + dev_dbg(component->dev, "%s: native_clk_users: %d\n", __func__, tasha->native_clk_users); err: return ret; } -static int tasha_codec_get_native_fifo_sync_mask(struct snd_soc_codec *codec, - int interp_n) +static int tasha_codec_get_native_fifo_sync_mask( + struct snd_soc_component *component, + int interp_n) { int mask = 0; u16 reg; @@ -5199,8 +5401,8 @@ static int tasha_codec_get_native_fifo_sync_mask(struct snd_soc_codec *codec, reg = WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0 + (2 * interp_n) - 2; - val1 = snd_soc_read(codec, reg); - val2 = snd_soc_read(codec, reg + 1); + val1 = snd_soc_component_read32(component, reg); + val2 = snd_soc_component_read32(component, reg + 1); inp0 = val1 & 0x0F; inp1 = (val1 >> 4) & 0x0F; @@ -5213,9 +5415,9 @@ static int tasha_codec_get_native_fifo_sync_mask(struct snd_soc_codec *codec, if (IS_VALID_NATIVE_FIFO_PORT(inp2)) mask |= (1 << (inp2 - 5)); - dev_dbg(codec->dev, "%s: native fifo mask: 0x%x\n", __func__, mask); + dev_dbg(component->dev, "%s: native fifo mask: 0x%x\n", __func__, mask); if (!mask) - dev_err(codec->dev, "native fifo err,int:%d,inp0:%d,inp1:%d,inp2:%d\n", + dev_err(component->dev, "native fifo err,int:%d,inp0:%d,inp1:%d,inp2:%d\n", interp_n, inp0, inp1, inp2); return mask; } @@ -5224,11 +5426,12 @@ static int tasha_enable_native_supply(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { int mask; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); u16 interp_reg; - dev_dbg(codec->dev, "%s: event: %d, shift:%d\n", __func__, event, + dev_dbg(component->dev, "%s: event: %d, shift:%d\n", __func__, event, w->shift); if (w->shift < INTERP_HPHL || w->shift > INTERP_LO2) @@ -5236,24 +5439,28 @@ static int tasha_enable_native_supply(struct snd_soc_dapm_widget *w, interp_reg = WCD9335_CDC_RX1_RX_PATH_CTL + 20 * (w->shift - 1); - mask = tasha_codec_get_native_fifo_sync_mask(codec, w->shift); + mask = tasha_codec_get_native_fifo_sync_mask(component, w->shift); if (!mask) return -EINVAL; switch (event) { case SND_SOC_DAPM_PRE_PMU: /* Adjust interpolator rate to 44P1_NATIVE */ - snd_soc_update_bits(codec, interp_reg, 0x0F, 0x09); + snd_soc_component_update_bits(component, interp_reg, + 0x0F, 0x09); __tasha_cdc_native_clk_enable(tasha, true); - snd_soc_update_bits(codec, WCD9335_DATA_HUB_NATIVE_FIFO_SYNC, - mask, mask); + snd_soc_component_update_bits(component, + WCD9335_DATA_HUB_NATIVE_FIFO_SYNC, + mask, mask); break; case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, WCD9335_DATA_HUB_NATIVE_FIFO_SYNC, - mask, 0x0); + snd_soc_component_update_bits(component, + WCD9335_DATA_HUB_NATIVE_FIFO_SYNC, + mask, 0x0); __tasha_cdc_native_clk_enable(tasha, false); /* Adjust interpolator rate to default */ - snd_soc_update_bits(codec, interp_reg, 0x0F, 0x04); + snd_soc_component_update_bits(component, interp_reg, + 0x0F, 0x04); break; } @@ -5263,14 +5470,15 @@ static int tasha_enable_native_supply(struct snd_soc_dapm_widget *w, static int tasha_codec_enable_interpolator(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); u16 gain_reg; u16 reg; int val; int offset_val = 0; - dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name); if (!(strcmp(w->name, "RX INT0 INTERP"))) { reg = WCD9335_CDC_RX0_RX_PATH_CTL; @@ -5300,66 +5508,70 @@ static int tasha_codec_enable_interpolator(struct snd_soc_dapm_widget *w, reg = WCD9335_CDC_RX8_RX_PATH_CTL; gain_reg = WCD9335_CDC_RX8_RX_VOL_CTL; } else { - dev_err(codec->dev, "%s: Interpolator reg not found\n", + dev_err(component->dev, "%s: Interpolator reg not found\n", __func__); return -EINVAL; } switch (event) { case SND_SOC_DAPM_PRE_PMU: - tasha_codec_vote_max_bw(codec, true); + tasha_codec_vote_max_bw(component, true); /* Reset if needed */ - tasha_codec_enable_prim_interpolator(codec, reg, event); + tasha_codec_enable_prim_interpolator(component, reg, event); break; case SND_SOC_DAPM_POST_PMU: - tasha_config_compander(codec, w->shift, event); + tasha_config_compander(component, w->shift, event); /* apply gain after int clk is enabled */ if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && (tasha->comp_enabled[COMPANDER_7] || tasha->comp_enabled[COMPANDER_8]) && (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL || gain_reg == WCD9335_CDC_RX8_RX_VOL_CTL)) { - snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1, - 0x01, 0x01); - snd_soc_update_bits(codec, - WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, - 0x01, 0x01); - snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1, - 0x01, 0x01); - snd_soc_update_bits(codec, - WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, - 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x01); offset_val = -2; } - val = snd_soc_read(codec, gain_reg); + val = snd_soc_component_read32(component, gain_reg); val += offset_val; - snd_soc_write(codec, gain_reg, val); - tasha_codec_config_ear_spkr_gain(codec, event, gain_reg); + snd_soc_component_write(component, gain_reg, val); + tasha_codec_config_ear_spkr_gain(component, event, gain_reg); break; case SND_SOC_DAPM_POST_PMD: - tasha_config_compander(codec, w->shift, event); - tasha_codec_enable_prim_interpolator(codec, reg, event); + tasha_config_compander(component, w->shift, event); + tasha_codec_enable_prim_interpolator(component, reg, event); if ((tasha->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && (tasha->comp_enabled[COMPANDER_7] || tasha->comp_enabled[COMPANDER_8]) && (gain_reg == WCD9335_CDC_RX7_RX_VOL_CTL || gain_reg == WCD9335_CDC_RX8_RX_VOL_CTL)) { - snd_soc_update_bits(codec, WCD9335_CDC_RX7_RX_PATH_SEC1, - 0x01, 0x00); - snd_soc_update_bits(codec, - WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, - 0x01, 0x00); - snd_soc_update_bits(codec, WCD9335_CDC_RX8_RX_PATH_SEC1, - 0x01, 0x00); - snd_soc_update_bits(codec, - WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, - 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x00); offset_val = 2; - val = snd_soc_read(codec, gain_reg); + val = snd_soc_component_read32(component, gain_reg); val += offset_val; - snd_soc_write(codec, gain_reg, val); + snd_soc_component_write(component, gain_reg, val); } - tasha_codec_config_ear_spkr_gain(codec, event, gain_reg); + tasha_codec_config_ear_spkr_gain(component, event, gain_reg); break; }; @@ -5369,42 +5581,43 @@ static int tasha_codec_enable_interpolator(struct snd_soc_dapm_widget *w, static int tasha_codec_set_iir_gain(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); - dev_dbg(codec->dev, "%s: event = %d\n", __func__, event); + dev_dbg(component->dev, "%s: event = %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_POST_PMU: /* fall through */ case SND_SOC_DAPM_PRE_PMD: if (strnstr(w->name, "IIR0", sizeof("IIR0"))) { - snd_soc_write(codec, + snd_soc_component_write(component, WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)); } else { - snd_soc_write(codec, + snd_soc_component_write(component, WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL)); } break; @@ -5417,25 +5630,26 @@ static int tasha_codec_enable_on_demand_supply( struct snd_kcontrol *kcontrol, int event) { int ret = 0; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); struct on_demand_supply *supply; if (w->shift >= ON_DEMAND_SUPPLIES_MAX) { - dev_err(codec->dev, "%s: error index > MAX Demand supplies", + dev_err(component->dev, "%s: error index > MAX Demand supplies", __func__); ret = -EINVAL; goto out; } - dev_dbg(codec->dev, "%s: supply: %s event: %d\n", + dev_dbg(component->dev, "%s: supply: %s event: %d\n", __func__, on_demand_supply_name[w->shift], event); supply = &tasha->on_demand_list[w->shift]; WARN_ONCE(!supply->supply, "%s isn't defined\n", on_demand_supply_name[w->shift]); if (!supply->supply) { - dev_err(codec->dev, "%s: err supply not present ond for %d", + dev_err(component->dev, "%s: err supply not present ond for %d", __func__, w->shift); goto out; } @@ -5444,14 +5658,14 @@ static int tasha_codec_enable_on_demand_supply( case SND_SOC_DAPM_PRE_PMU: ret = regulator_enable(supply->supply); if (ret) - dev_err(codec->dev, "%s: Failed to enable %s\n", + dev_err(component->dev, "%s: Failed to enable %s\n", __func__, on_demand_supply_name[w->shift]); break; case SND_SOC_DAPM_POST_PMD: ret = regulator_disable(supply->supply); if (ret) - dev_err(codec->dev, "%s: Failed to disable %s\n", + dev_err(component->dev, "%s: Failed to disable %s\n", __func__, on_demand_supply_name[w->shift]); break; @@ -5463,7 +5677,7 @@ static int tasha_codec_enable_on_demand_supply( return ret; } -static int tasha_codec_find_amic_input(struct snd_soc_codec *codec, +static int tasha_codec_find_amic_input(struct snd_soc_component *component, int adc_mux_n) { u16 mask, shift, adc_mux_in_reg; @@ -5489,15 +5703,15 @@ static int tasha_codec_find_amic_input(struct snd_soc_codec *codec, mask = 0xC0; shift = 6; } - is_amic = (((snd_soc_read(codec, adc_mux_in_reg) & mask) >> shift) - == 1); + is_amic = (((snd_soc_component_read32( + component, adc_mux_in_reg) & mask) >> shift) == 1); if (!is_amic) return 0; - return snd_soc_read(codec, amic_mux_sel_reg) & 0x07; + return snd_soc_component_read32(component, amic_mux_sel_reg) & 0x07; } -static void tasha_codec_set_tx_hold(struct snd_soc_codec *codec, +static void tasha_codec_set_tx_hold(struct snd_soc_component *component, u16 amic_reg, bool set) { u8 mask = 0x20; @@ -5513,18 +5727,21 @@ static void tasha_codec_set_tx_hold(struct snd_soc_codec *codec, switch (amic_reg) { case WCD9335_ANA_AMIC1: case WCD9335_ANA_AMIC2: - snd_soc_update_bits(codec, WCD9335_ANA_AMIC2, mask, val); + snd_soc_component_update_bits(component, WCD9335_ANA_AMIC2, + mask, val); break; case WCD9335_ANA_AMIC3: case WCD9335_ANA_AMIC4: - snd_soc_update_bits(codec, WCD9335_ANA_AMIC4, mask, val); + snd_soc_component_update_bits(component, WCD9335_ANA_AMIC4, + mask, val); break; case WCD9335_ANA_AMIC5: case WCD9335_ANA_AMIC6: - snd_soc_update_bits(codec, WCD9335_ANA_AMIC6, mask, val); + snd_soc_component_update_bits(component, WCD9335_ANA_AMIC6, + mask, val); break; default: - dev_dbg(codec->dev, "%s: invalid amic: %d\n", + dev_dbg(component->dev, "%s: invalid amic: %d\n", __func__, amic_reg); break; } @@ -5534,15 +5751,16 @@ static int tasha_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { int adc_mux_n = w->shift; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); int amic_n; - dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); + dev_dbg(component->dev, "%s: event: %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_POST_PMU: - amic_n = tasha_codec_find_amic_input(codec, adc_mux_n); + amic_n = tasha_codec_find_amic_input(component, adc_mux_n); if (amic_n) { /* * Prevent ANC Rx pop by leaving Tx FE in HOLD @@ -5560,7 +5778,8 @@ static int tasha_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w, return 0; } -static u16 tasha_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic) +static u16 tasha_codec_get_amic_pwlvl_reg( + struct snd_soc_component *component, int amic) { u16 pwr_level_reg = 0; @@ -5580,7 +5799,7 @@ static u16 tasha_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic) pwr_level_reg = WCD9335_ANA_AMIC5; break; default: - dev_dbg(codec->dev, "%s: invalid amic: %d\n", + dev_dbg(component->dev, "%s: invalid amic: %d\n", __func__, amic); break; } @@ -5598,7 +5817,7 @@ static void tasha_tx_hpf_corner_freq_callback(struct work_struct *work) struct delayed_work *hpf_delayed_work; struct hpf_work *hpf_work; struct tasha_priv *tasha; - struct snd_soc_codec *codec; + struct snd_soc_component *component; u16 dec_cfg_reg, amic_reg; u8 hpf_cut_off_freq; int amic_n; @@ -5606,23 +5825,24 @@ static void tasha_tx_hpf_corner_freq_callback(struct work_struct *work) hpf_delayed_work = to_delayed_work(work); hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); tasha = hpf_work->tasha; - codec = tasha->codec; + component = tasha->component; hpf_cut_off_freq = hpf_work->hpf_cut_off_freq; dec_cfg_reg = WCD9335_CDC_TX0_TX_PATH_CFG0 + 16 * hpf_work->decimator; - dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", + dev_dbg(component->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", __func__, hpf_work->decimator, hpf_cut_off_freq); - amic_n = tasha_codec_find_amic_input(codec, hpf_work->decimator); + amic_n = tasha_codec_find_amic_input(component, hpf_work->decimator); if (amic_n) { amic_reg = WCD9335_ANA_AMIC1 + amic_n - 1; - tasha_codec_set_tx_hold(codec, amic_reg, false); + tasha_codec_set_tx_hold(component, amic_reg, false); } - tasha_codec_vote_max_bw(codec, true); - snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, - hpf_cut_off_freq << 5); - tasha_codec_vote_max_bw(codec, false); + tasha_codec_vote_max_bw(component, true); + snd_soc_component_update_bits(component, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + tasha_codec_vote_max_bw(component, false); } static void tasha_tx_mute_update_callback(struct work_struct *work) @@ -5630,26 +5850,27 @@ static void tasha_tx_mute_update_callback(struct work_struct *work) struct tx_mute_work *tx_mute_dwork; struct tasha_priv *tasha; struct delayed_work *delayed_work; - struct snd_soc_codec *codec; + struct snd_soc_component *component; u16 tx_vol_ctl_reg, hpf_gate_reg; delayed_work = to_delayed_work(work); tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); tasha = tx_mute_dwork->tasha; - codec = tasha->codec; + component = tasha->component; tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL + 16 * tx_mute_dwork->decimator; hpf_gate_reg = WCD9335_CDC_TX0_TX_PATH_SEC2 + 16 * tx_mute_dwork->decimator; - snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x01); - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); + snd_soc_component_update_bits(component, hpf_gate_reg, 0x01, 0x01); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x00); } static int tasha_codec_enable_dec(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); unsigned int decimator; char *dec_adc_mux_name = NULL; char *widget_name = NULL; @@ -5659,9 +5880,9 @@ static int tasha_codec_enable_dec(struct snd_soc_dapm_widget *w, u16 tx_gain_ctl_reg; char *dec; u8 hpf_cut_off_freq; - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); - dev_dbg(codec->dev, "%s %d\n", __func__, event); + dev_dbg(component->dev, "%s %d\n", __func__, event); widget_name = kstrndup(w->name, 15, GFP_KERNEL); if (!widget_name) @@ -5670,7 +5891,7 @@ static int tasha_codec_enable_dec(struct snd_soc_dapm_widget *w, wname = widget_name; dec_adc_mux_name = strsep(&widget_name, " "); if (!dec_adc_mux_name) { - dev_err(codec->dev, "%s: Invalid decimator = %s\n", + dev_err(component->dev, "%s: Invalid decimator = %s\n", __func__, w->name); ret = -EINVAL; goto out; @@ -5679,7 +5900,7 @@ static int tasha_codec_enable_dec(struct snd_soc_dapm_widget *w, dec = strpbrk(dec_adc_mux_name, "012345678"); if (!dec) { - dev_err(codec->dev, "%s: decimator index not found\n", + dev_err(component->dev, "%s: decimator index not found\n", __func__); ret = -EINVAL; goto out; @@ -5687,13 +5908,13 @@ static int tasha_codec_enable_dec(struct snd_soc_dapm_widget *w, ret = kstrtouint(dec, 10, &decimator); if (ret < 0) { - dev_err(codec->dev, "%s: Invalid decimator = %s\n", + dev_err(component->dev, "%s: Invalid decimator = %s\n", __func__, wname); ret = -EINVAL; goto out; } - dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__, + dev_dbg(component->dev, "%s(): widget = %s decimator = %u\n", __func__, w->name, decimator); tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL + 16 * decimator; @@ -5703,54 +5924,65 @@ static int tasha_codec_enable_dec(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - amic_n = tasha_codec_find_amic_input(codec, decimator); + amic_n = tasha_codec_find_amic_input(component, decimator); if (amic_n) - pwr_level_reg = tasha_codec_get_amic_pwlvl_reg(codec, - amic_n); + pwr_level_reg = tasha_codec_get_amic_pwlvl_reg( + component, amic_n); if (pwr_level_reg) { - switch ((snd_soc_read(codec, pwr_level_reg) & + switch ( + (snd_soc_component_read32(component, pwr_level_reg) & WCD9335_AMIC_PWR_LVL_MASK) >> WCD9335_AMIC_PWR_LVL_SHIFT) { case WCD9335_AMIC_PWR_LEVEL_LP: - snd_soc_update_bits(codec, dec_cfg_reg, - WCD9335_DEC_PWR_LVL_MASK, - WCD9335_DEC_PWR_LVL_LP); + snd_soc_component_update_bits( + component, dec_cfg_reg, + WCD9335_DEC_PWR_LVL_MASK, + WCD9335_DEC_PWR_LVL_LP); break; case WCD9335_AMIC_PWR_LEVEL_HP: - snd_soc_update_bits(codec, dec_cfg_reg, - WCD9335_DEC_PWR_LVL_MASK, - WCD9335_DEC_PWR_LVL_HP); + snd_soc_component_update_bits( + component, dec_cfg_reg, + WCD9335_DEC_PWR_LVL_MASK, + WCD9335_DEC_PWR_LVL_HP); break; case WCD9335_AMIC_PWR_LEVEL_DEFAULT: default: - snd_soc_update_bits(codec, dec_cfg_reg, - WCD9335_DEC_PWR_LVL_MASK, - WCD9335_DEC_PWR_LVL_DF); + snd_soc_component_update_bits( + component, dec_cfg_reg, + WCD9335_DEC_PWR_LVL_MASK, + WCD9335_DEC_PWR_LVL_DF); break; } } - hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) & + hpf_cut_off_freq = ( + snd_soc_component_read32(component, dec_cfg_reg) & TX_HPF_CUT_OFF_FREQ_MASK) >> 5; tasha->tx_hpf_work[decimator].hpf_cut_off_freq = hpf_cut_off_freq; if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) - snd_soc_update_bits(codec, dec_cfg_reg, + snd_soc_component_update_bits(component, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, CF_MIN_3DB_150HZ << 5); /* Enable TX PGA Mute */ - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x10, 0x10); break; case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, hpf_gate_reg, 0x01, 0x00); + snd_soc_component_update_bits(component, hpf_gate_reg, + 0x01, 0x00); if (decimator == 0) { - snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x83); - snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0xA3); - snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x83); - snd_soc_write(codec, WCD9335_MBHC_ZDET_RAMP_CTL, 0x03); + snd_soc_component_write(component, + WCD9335_MBHC_ZDET_RAMP_CTL, 0x83); + snd_soc_component_write(component, + WCD9335_MBHC_ZDET_RAMP_CTL, 0xA3); + snd_soc_component_write(component, + WCD9335_MBHC_ZDET_RAMP_CTL, 0x83); + snd_soc_component_write(component, + WCD9335_MBHC_ZDET_RAMP_CTL, 0x03); } /* schedule work queue to Remove Mute */ schedule_delayed_work(&tasha->tx_mute_dwork[decimator].dwork, @@ -5761,28 +5993,32 @@ static int tasha_codec_enable_dec(struct snd_soc_dapm_widget *w, &tasha->tx_hpf_work[decimator].dwork, msecs_to_jiffies(300)); /* apply gain after decimator is enabled */ - snd_soc_write(codec, tx_gain_ctl_reg, - snd_soc_read(codec, tx_gain_ctl_reg)); + snd_soc_component_write(component, tx_gain_ctl_reg, + snd_soc_component_read32( + component, tx_gain_ctl_reg)); break; case SND_SOC_DAPM_PRE_PMD: hpf_cut_off_freq = tasha->tx_hpf_work[decimator].hpf_cut_off_freq; - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x10, 0x10); if (cancel_delayed_work_sync( &tasha->tx_hpf_work[decimator].dwork)) { if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { - tasha_codec_vote_max_bw(codec, true); - snd_soc_update_bits(codec, dec_cfg_reg, - TX_HPF_CUT_OFF_FREQ_MASK, - hpf_cut_off_freq << 5); - tasha_codec_vote_max_bw(codec, false); + tasha_codec_vote_max_bw(component, true); + snd_soc_component_update_bits(component, + dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + tasha_codec_vote_max_bw(component, false); } } cancel_delayed_work_sync( &tasha->tx_mute_dwork[decimator].dwork); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x10, 0x00); break; }; out: @@ -5790,7 +6026,7 @@ static int tasha_codec_enable_dec(struct snd_soc_dapm_widget *w, return ret; } -static u32 tasha_get_dmic_sample_rate(struct snd_soc_codec *codec, +static u32 tasha_get_dmic_sample_rate(struct snd_soc_component *component, unsigned int dmic, struct wcd9xxx_pdata *pdata) { u8 tx_stream_fs; @@ -5803,13 +6039,13 @@ static u32 tasha_get_dmic_sample_rate(struct snd_soc_codec *codec, if (adc_mux_index < 4) { adc_mux_ctl_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + (adc_mux_index * 2); - adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) & - 0x78) >> 3) - 1; + adc_mux_sel = ((snd_soc_component_read32(component, + adc_mux_ctl_reg) & 0x78) >> 3) - 1; } else if (adc_mux_index < 9) { adc_mux_ctl_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + ((adc_mux_index - 4) * 1); - adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) & - 0x38) >> 3) - 1; + adc_mux_sel = ((snd_soc_component_read32( + component, adc_mux_ctl_reg) & 0x38) >> 3) - 1; } else if (adc_mux_index == 9) { ++adc_mux_index; continue; @@ -5822,7 +6058,8 @@ static u32 tasha_get_dmic_sample_rate(struct snd_soc_codec *codec, if (dec_found == true && adc_mux_index <= 8) { tx_fs_reg = WCD9335_CDC_TX0_TX_PATH_CTL + (16 * adc_mux_index); - tx_stream_fs = snd_soc_read(codec, tx_fs_reg) & 0x0F; + tx_stream_fs = + snd_soc_component_read32(component, tx_fs_reg) & 0x0F; dmic_fs = tx_stream_fs <= 4 ? WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ : WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ; @@ -5831,10 +6068,12 @@ static u32 tasha_get_dmic_sample_rate(struct snd_soc_codec *codec, * any other audio path to apply ECPP DMIC sample rate */ if ((adc_mux_index == 1) && - ((snd_soc_read(codec, WCD9335_CPE_SS_US_EC_MUX_CFG) - & 0x0F) == 0x0A) && - ((snd_soc_read(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0) - & 0x0C) == 0x00)) { + ((snd_soc_component_read32( + component, WCD9335_CPE_SS_US_EC_MUX_CFG) + & 0x0F) == 0x0A) && + ((snd_soc_component_read32( + component, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0) + & 0x0C) == 0x00)) { dmic_fs = pdata->ecpp_dmic_sample_rate; } } else { @@ -5844,13 +6083,13 @@ static u32 tasha_get_dmic_sample_rate(struct snd_soc_codec *codec, return dmic_fs; } -static u8 tasha_get_dmic_clk_val(struct snd_soc_codec *codec, +static u8 tasha_get_dmic_clk_val(struct snd_soc_component *component, u32 mclk_rate, u32 dmic_clk_rate) { u32 div_factor; u8 dmic_ctl_val; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: mclk_rate = %d, dmic_sample_rate = %d\n", __func__, mclk_rate, dmic_clk_rate); @@ -5861,7 +6100,7 @@ static u8 tasha_get_dmic_clk_val(struct snd_soc_codec *codec, dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3; if (dmic_clk_rate == 0) { - dev_err(codec->dev, + dev_err(component->dev, "%s: dmic_sample_rate cannot be 0\n", __func__); goto done; @@ -5888,7 +6127,7 @@ static u8 tasha_get_dmic_clk_val(struct snd_soc_codec *codec, dmic_ctl_val = WCD9335_DMIC_CLK_DIV_16; break; default: - dev_err(codec->dev, + dev_err(component->dev, "%s: Invalid div_factor %u, clk_rate(%u), dmic_rate(%u)\n", __func__, div_factor, mclk_rate, dmic_clk_rate); break; @@ -5901,13 +6140,14 @@ static u8 tasha_get_dmic_clk_val(struct snd_soc_codec *codec, static int tasha_codec_enable_adc(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); - dev_dbg(codec->dev, "%s: event:%d\n", __func__, event); + dev_dbg(component->dev, "%s: event:%d\n", __func__, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - tasha_codec_set_tx_hold(codec, w->reg, true); + tasha_codec_set_tx_hold(component, w->reg, true); break; default: break; @@ -5919,9 +6159,10 @@ static int tasha_codec_enable_adc(struct snd_soc_dapm_widget *w, static int tasha_codec_enable_dmic(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); + struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent); u8 dmic_clk_en = 0x01; u16 dmic_clk_reg; s32 *dmic_clk_cnt; @@ -5933,13 +6174,13 @@ static int tasha_codec_enable_dmic(struct snd_soc_dapm_widget *w, wname = strpbrk(w->name, "012345"); if (!wname) { - dev_err(codec->dev, "%s: widget not found\n", __func__); + dev_err(component->dev, "%s: widget not found\n", __func__); return -EINVAL; } ret = kstrtouint(wname, 10, &dmic); if (ret < 0) { - dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n", + dev_err(component->dev, "%s: Invalid DMIC line on the codec\n", __func__); return -EINVAL; } @@ -5961,42 +6202,42 @@ static int tasha_codec_enable_dmic(struct snd_soc_dapm_widget *w, dmic_clk_reg = WCD9335_CPE_SS_DMIC2_CTL; break; default: - dev_err(codec->dev, "%s: Invalid DMIC Selection\n", + dev_err(component->dev, "%s: Invalid DMIC Selection\n", __func__); return -EINVAL; }; - dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", + dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", __func__, event, dmic, *dmic_clk_cnt); switch (event) { case SND_SOC_DAPM_PRE_PMU: - dmic_sample_rate = tasha_get_dmic_sample_rate(codec, dmic, + dmic_sample_rate = tasha_get_dmic_sample_rate(component, dmic, pdata); dmic_rate_val = - tasha_get_dmic_clk_val(codec, + tasha_get_dmic_clk_val(component, pdata->mclk_rate, dmic_sample_rate); (*dmic_clk_cnt)++; if (*dmic_clk_cnt == 1) { - snd_soc_update_bits(codec, dmic_clk_reg, + snd_soc_component_update_bits(component, dmic_clk_reg, 0x07 << dmic_rate_shift, dmic_rate_val << dmic_rate_shift); - snd_soc_update_bits(codec, dmic_clk_reg, + snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, dmic_clk_en); } break; case SND_SOC_DAPM_POST_PMD: dmic_rate_val = - tasha_get_dmic_clk_val(codec, + tasha_get_dmic_clk_val(component, pdata->mclk_rate, pdata->mad_dmic_sample_rate); (*dmic_clk_cnt)--; if (*dmic_clk_cnt == 0) { - snd_soc_update_bits(codec, dmic_clk_reg, + snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, 0); - snd_soc_update_bits(codec, dmic_clk_reg, + snd_soc_component_update_bits(component, dmic_clk_reg, 0x07 << dmic_rate_shift, dmic_rate_val << dmic_rate_shift); } @@ -6009,10 +6250,11 @@ static int tasha_codec_enable_dmic(struct snd_soc_dapm_widget *w, static int __tasha_codec_enable_micbias(struct snd_soc_dapm_widget *w, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); int micb_num; - dev_dbg(codec->dev, "%s: wname: %s, event: %d\n", + dev_dbg(component->dev, "%s: wname: %s, event: %d\n", __func__, w->name, event); if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) @@ -6033,14 +6275,14 @@ static int __tasha_codec_enable_micbias(struct snd_soc_dapm_widget *w, * so use ref count to handle micbias pullup * and enable requests */ - tasha_micbias_control(codec, micb_num, MICB_ENABLE, true); + tasha_micbias_control(component, micb_num, MICB_ENABLE, true); break; case SND_SOC_DAPM_POST_PMU: /* wait for cnp time */ usleep_range(1000, 1100); break; case SND_SOC_DAPM_POST_PMD: - tasha_micbias_control(codec, micb_num, MICB_DISABLE, true); + tasha_micbias_control(component, micb_num, MICB_DISABLE, true); break; }; @@ -6050,15 +6292,17 @@ static int __tasha_codec_enable_micbias(struct snd_soc_dapm_widget *w, static int tasha_codec_ldo_h_control(struct snd_soc_dapm_widget *w, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); if (SND_SOC_DAPM_EVENT_ON(event)) { tasha->ldo_h_users++; if (tasha->ldo_h_users == 1) - snd_soc_update_bits(codec, WCD9335_LDOH_MODE, - 0x80, 0x80); + snd_soc_component_update_bits(component, + WCD9335_LDOH_MODE, + 0x80, 0x80); } if (SND_SOC_DAPM_EVENT_OFF(event)) { @@ -6068,8 +6312,9 @@ static int tasha_codec_ldo_h_control(struct snd_soc_dapm_widget *w, tasha->ldo_h_users = 0; if (tasha->ldo_h_users == 0) - snd_soc_update_bits(codec, WCD9335_LDOH_MODE, - 0x80, 0x00); + snd_soc_component_update_bits(component, + WCD9335_LDOH_MODE, + 0x80, 0x00); } return 0; @@ -6079,8 +6324,9 @@ static int tasha_codec_force_enable_ldo_h(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -6101,17 +6347,18 @@ static int tasha_codec_force_enable_micbias(struct snd_soc_dapm_widget *w, int event) { int ret = 0; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); switch (event) { case SND_SOC_DAPM_PRE_PMU: wcd_resmgr_enable_master_bias(tasha->resmgr); - tasha_cdc_mclk_enable(codec, true, true); + tasha_cdc_mclk_enable(component, true, true); ret = __tasha_codec_enable_micbias(w, SND_SOC_DAPM_PRE_PMU); /* Wait for 1ms for better cnp */ usleep_range(1000, 1100); - tasha_cdc_mclk_enable(codec, false, true); + tasha_cdc_mclk_enable(component, false, true); break; case SND_SOC_DAPM_POST_PMD: ret = __tasha_codec_enable_micbias(w, SND_SOC_DAPM_POST_PMD); @@ -6128,24 +6375,25 @@ static int tasha_codec_enable_micbias(struct snd_soc_dapm_widget *w, return __tasha_codec_enable_micbias(w, event); } -static int tasha_codec_enable_standalone_ldo_h(struct snd_soc_codec *codec, - bool enable) +static int tasha_codec_enable_standalone_ldo_h( + struct snd_soc_component *component, + bool enable) { int rc; if (enable) rc = snd_soc_dapm_force_enable_pin( - snd_soc_codec_get_dapm(codec), + snd_soc_component_get_dapm(component), DAPM_LDO_H_STANDALONE); else rc = snd_soc_dapm_disable_pin( - snd_soc_codec_get_dapm(codec), + snd_soc_component_get_dapm(component), DAPM_LDO_H_STANDALONE); if (!rc) - snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + snd_soc_dapm_sync(snd_soc_component_get_dapm(component)); else - dev_err(codec->dev, "%s: ldo_h force %s pin failed\n", + dev_err(component->dev, "%s: ldo_h force %s pin failed\n", __func__, (enable ? "enable" : "disable")); return rc; @@ -6153,7 +6401,7 @@ static int tasha_codec_enable_standalone_ldo_h(struct snd_soc_codec *codec, /* * tasha_codec_enable_standalone_micbias - enable micbias standalone - * @codec: pointer to codec instance + * @component: pointer to codec instance * @micb_num: number of micbias to be enabled * @enable: true to enable micbias or false to disable * @@ -6162,7 +6410,7 @@ static int tasha_codec_enable_standalone_ldo_h(struct snd_soc_codec *codec, * * Return: error code in case of failure or 0 for success */ -int tasha_codec_enable_standalone_micbias(struct snd_soc_codec *codec, +int tasha_codec_enable_standalone_micbias(struct snd_soc_component *component, int micb_num, bool enable) { @@ -6173,29 +6421,30 @@ int tasha_codec_enable_standalone_micbias(struct snd_soc_codec *codec, int micb_index = micb_num - 1; int rc; - if (!codec) { - pr_err("%s: Codec memory is NULL\n", __func__); + if (!component) { + pr_err("%s: Component memory is NULL\n", __func__); return -EINVAL; } if ((micb_index < 0) || (micb_index > TASHA_MAX_MICBIAS - 1)) { - dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n", + dev_err(component->dev, "%s: Invalid micbias index, micb_ind:%d\n", __func__, micb_index); return -EINVAL; } if (enable) rc = snd_soc_dapm_force_enable_pin( - snd_soc_codec_get_dapm(codec), - micb_names[micb_index]); + snd_soc_component_get_dapm(component), + micb_names[micb_index]); else - rc = snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(codec), - micb_names[micb_index]); + rc = snd_soc_dapm_disable_pin( + snd_soc_component_get_dapm(component), + micb_names[micb_index]); if (!rc) - snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + snd_soc_dapm_sync(snd_soc_component_get_dapm(component)); else - dev_err(codec->dev, "%s: micbias%d force %s pin failed\n", + dev_err(component->dev, "%s: micbias%d force %s pin failed\n", __func__, micb_num, (enable ? "enable" : "disable")); return rc; @@ -7622,7 +7871,8 @@ static const struct snd_soc_dapm_route audio_map[] = { static int tasha_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); u16 amic_reg; if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE")) @@ -7633,8 +7883,9 @@ static int tasha_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, amic_reg = WCD9335_ANA_AMIC5; ucontrol->value.integer.value[0] = - (snd_soc_read(codec, amic_reg) & WCD9335_AMIC_PWR_LVL_MASK) >> - WCD9335_AMIC_PWR_LVL_SHIFT; + (snd_soc_component_read32(component, amic_reg) & + WCD9335_AMIC_PWR_LVL_MASK) >> + WCD9335_AMIC_PWR_LVL_SHIFT; return 0; } @@ -7642,13 +7893,14 @@ static int tasha_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, static int tasha_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); u32 mode_val; u16 amic_reg; mode_val = ucontrol->value.enumerated.item[0]; - dev_dbg(codec->dev, "%s: mode: %d\n", + dev_dbg(component->dev, "%s: mode: %d\n", __func__, mode_val); if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE")) @@ -7658,8 +7910,9 @@ static int tasha_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, if (!strcmp(kcontrol->id.name, "AMIC_5_6 PWR MODE")) amic_reg = WCD9335_ANA_AMIC5; - snd_soc_update_bits(codec, amic_reg, WCD9335_AMIC_PWR_LVL_MASK, - mode_val << WCD9335_AMIC_PWR_LVL_SHIFT); + snd_soc_component_update_bits(component, amic_reg, + WCD9335_AMIC_PWR_LVL_MASK, + mode_val << WCD9335_AMIC_PWR_LVL_SHIFT); return 0; } @@ -7667,8 +7920,9 @@ static int tasha_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, static int tasha_rx_hph_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = tasha->hph_mode; return 0; @@ -7677,17 +7931,18 @@ static int tasha_rx_hph_mode_get(struct snd_kcontrol *kcontrol, static int tasha_rx_hph_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); u32 mode_val; mode_val = ucontrol->value.enumerated.item[0]; - dev_dbg(codec->dev, "%s: mode: %d\n", + dev_dbg(component->dev, "%s: mode: %d\n", __func__, mode_val); if (mode_val == 0) { - dev_warn(codec->dev, "%s:Invalid HPH Mode, default to Cls-H HiFi\n", + dev_warn(component->dev, "%s:Invalid HPH Mode, default to Cls-H HiFi\n", __func__); mode_val = CLS_H_HIFI; } @@ -7708,11 +7963,13 @@ static const struct soc_enum tasha_conn_mad_enum = static int tasha_enable_ldo_h_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); u8 val = 0; - if (codec) - val = snd_soc_read(codec, WCD9335_LDOH_MODE) & 0x80; + if (component) + val = snd_soc_component_read32(component, WCD9335_LDOH_MODE) & + 0x80; ucontrol->value.integer.value[0] = !!val; @@ -7722,13 +7979,14 @@ static int tasha_enable_ldo_h_get(struct snd_kcontrol *kcontrol, static int tasha_enable_ldo_h_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int value = ucontrol->value.integer.value[0]; bool enable; enable = !!value; - if (codec) - tasha_codec_enable_standalone_ldo_h(codec, enable); + if (component) + tasha_codec_enable_standalone_ldo_h(component, enable); return 0; } @@ -7737,13 +7995,14 @@ static int tasha_mad_input_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 tasha_mad_input; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - tasha_mad_input = snd_soc_read(codec, + tasha_mad_input = snd_soc_component_read32(component, WCD9335_SOC_MAD_INP_SEL) & 0x0F; ucontrol->value.integer.value[0] = tasha_mad_input; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: tasha_mad_input = %s\n", __func__, tasha_conn_mad_text[tasha_mad_input]); return 0; @@ -7753,8 +8012,9 @@ static int tasha_mad_input_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 tasha_mad_input; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct snd_soc_card *card = codec->component.card; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct snd_soc_card *card = component->card; char mad_amic_input_widget[6]; const char *mad_input_widget; const char *source_widget = NULL; @@ -7765,7 +8025,7 @@ static int tasha_mad_input_put(struct snd_kcontrol *kcontrol, tasha_mad_input = ucontrol->value.integer.value[0]; if (tasha_mad_input >= ARRAY_SIZE(tasha_conn_mad_text)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: tasha_mad_input = %d out of bounds\n", __func__, tasha_mad_input); return -EINVAL; @@ -7775,7 +8035,7 @@ static int tasha_mad_input_put(struct snd_kcontrol *kcontrol, !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED2") || !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED3") || !strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED4")) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Unsupported tasha_mad_input = %s\n", __func__, tasha_conn_mad_text[tasha_mad_input]); return -EINVAL; @@ -7786,14 +8046,14 @@ static int tasha_mad_input_put(struct snd_kcontrol *kcontrol, mad_input = strpbrk(tasha_conn_mad_text[tasha_mad_input], "123456"); if (!mad_input) { - dev_err(codec->dev, "%s: Invalid MAD input %s\n", + dev_err(component->dev, "%s: Invalid MAD input %s\n", __func__, tasha_conn_mad_text[tasha_mad_input]); return -EINVAL; } ret = kstrtouint(mad_input, 10, &adc); if ((ret < 0) || (adc > 6)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Invalid ADC = %s\n", __func__, tasha_conn_mad_text[tasha_mad_input]); ret = -EINVAL; @@ -7807,7 +8067,7 @@ static int tasha_mad_input_put(struct snd_kcontrol *kcontrol, mad_input_widget = tasha_conn_mad_text[tasha_mad_input]; } - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: tasha input widget = %s\n", __func__, mad_input_widget); @@ -7815,7 +8075,7 @@ static int tasha_mad_input_put(struct snd_kcontrol *kcontrol, if (!strcmp(card->of_dapm_routes[i].sink, mad_input_widget)) { source_widget = card->of_dapm_routes[i].source; if (!source_widget) { - dev_err(codec->dev, + dev_err(component->dev, "%s: invalid source widget\n", __func__); return -EINVAL; @@ -7842,19 +8102,19 @@ static int tasha_mad_input_put(struct snd_kcontrol *kcontrol, } if (!mic_bias_found) { - dev_err(codec->dev, + dev_err(component->dev, "%s: mic bias source not found for input = %s\n", __func__, mad_input_widget); return -EINVAL; } - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: mic_bias found = %d\n", __func__, mic_bias_found); - snd_soc_update_bits(codec, WCD9335_SOC_MAD_INP_SEL, + snd_soc_component_update_bits(component, WCD9335_SOC_MAD_INP_SEL, 0x0F, tasha_mad_input); - snd_soc_update_bits(codec, WCD9335_ANA_MAD_SETUP, + snd_soc_component_update_bits(component, WCD9335_ANA_MAD_SETUP, 0x07, mic_bias_found); return 0; @@ -7863,7 +8123,8 @@ static int tasha_mad_input_put(struct snd_kcontrol *kcontrol, static int tasha_pinctl_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); u16 ctl_reg; u8 reg_val, pinctl_position; @@ -7883,12 +8144,12 @@ static int tasha_pinctl_mode_get(struct snd_kcontrol *kcontrol, ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_3; break; default: - dev_err(codec->dev, "%s: Invalid pinctl position = %d\n", + dev_err(component->dev, "%s: Invalid pinctl position = %d\n", __func__, pinctl_position); return -EINVAL; } - reg_val = snd_soc_read(codec, ctl_reg); + reg_val = snd_soc_component_read32(component, ctl_reg); reg_val = (reg_val >> (pinctl_position & 0x07)) & 0x1; ucontrol->value.integer.value[0] = reg_val; @@ -7898,8 +8159,9 @@ static int tasha_pinctl_mode_get(struct snd_kcontrol *kcontrol, static int tasha_pinctl_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); u16 ctl_reg, cfg_reg; u8 ctl_val, cfg_val, pinctl_position, pinctl_mode, mask; @@ -7922,14 +8184,14 @@ static int tasha_pinctl_mode_put(struct snd_kcontrol *kcontrol, ctl_reg = WCD9335_TEST_DEBUG_PIN_CTL_OE_3; break; default: - dev_err(codec->dev, "%s: Invalid pinctl position = %d\n", + dev_err(component->dev, "%s: Invalid pinctl position = %d\n", __func__, pinctl_position); return -EINVAL; } ctl_val = pinctl_mode << (pinctl_position & 0x07); mask = 1 << (pinctl_position & 0x07); - snd_soc_update_bits(codec, ctl_reg, mask, ctl_val); + snd_soc_component_update_bits(component, ctl_reg, mask, ctl_val); cfg_reg = WCD9335_TLMM_BIST_MODE_PINCFG + pinctl_position; if (!pinctl_mode) { @@ -7940,16 +8202,16 @@ static int tasha_pinctl_mode_put(struct snd_kcontrol *kcontrol, } else { cfg_val = 0; } - snd_soc_update_bits(codec, cfg_reg, 0x07, cfg_val); + snd_soc_component_update_bits(component, cfg_reg, 0x07, cfg_val); - dev_dbg(codec->dev, "%s: reg=0x%x mask=0x%x val=%d reg=0x%x val=%d\n", + dev_dbg(component->dev, "%s: reg=0x%x mask=0x%x val=%d reg=0x%x val=%d\n", __func__, ctl_reg, mask, ctl_val, cfg_reg, cfg_val); return 0; } static void wcd_vbat_adc_out_config_2_0(struct wcd_vbat *vbat, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { u8 val1, val2; @@ -7957,51 +8219,65 @@ static void wcd_vbat_adc_out_config_2_0(struct wcd_vbat *vbat, * Measure dcp1 by using "ALT" branch of band gap * voltage(Vbg) and use it in FAST mode */ - snd_soc_update_bits(codec, WCD9335_BIAS_CTL, 0x82, 0x82); - snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01, 0x01); - snd_soc_update_bits(codec, WCD9335_ANA_VBADC, 0x80, 0x80); - snd_soc_update_bits(codec, WCD9335_VBADC_SUBBLOCK_EN, 0x20, 0x00); - - snd_soc_update_bits(codec, WCD9335_VBADC_FE_CTRL, 0x20, 0x20); + snd_soc_component_update_bits(component, WCD9335_BIAS_CTL, + 0x82, 0x82); + snd_soc_component_update_bits(component, WCD9335_CDC_VBAT_VBAT_PATH_CTL, + 0x10, 0x10); + snd_soc_component_update_bits(component, WCD9335_CDC_VBAT_VBAT_DEBUG1, + 0x01, 0x01); + snd_soc_component_update_bits(component, WCD9335_ANA_VBADC, + 0x80, 0x80); + snd_soc_component_update_bits(component, WCD9335_VBADC_SUBBLOCK_EN, + 0x20, 0x00); + snd_soc_component_update_bits(component, WCD9335_VBADC_FE_CTRL, + 0x20, 0x20); /* Wait 100 usec after calibration select as Vbg */ usleep_range(100, 110); - snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x40); - val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB); - val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB); - snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x00); + snd_soc_component_update_bits(component, WCD9335_VBADC_ADC_IO, + 0x40, 0x40); + val1 = snd_soc_component_read32(component, WCD9335_VBADC_ADC_DOUTMSB); + val2 = snd_soc_component_read32(component, WCD9335_VBADC_ADC_DOUTLSB); + snd_soc_component_update_bits(component, WCD9335_VBADC_ADC_IO, + 0x40, 0x00); vbat->dcp1 = (((val1 & 0xFF) << 3) | (val2 & 0x07)); - snd_soc_update_bits(codec, WCD9335_BIAS_CTL, 0x40, 0x40); + snd_soc_component_update_bits(component, WCD9335_BIAS_CTL, 0x40, 0x40); /* Wait 100 usec after selecting Vbg as 1.05V */ usleep_range(100, 110); - snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x40); - val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB); - val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB); - snd_soc_update_bits(codec, WCD9335_VBADC_ADC_IO, 0x40, 0x00); + snd_soc_component_update_bits(component, WCD9335_VBADC_ADC_IO, + 0x40, 0x40); + val1 = snd_soc_component_read32(component, WCD9335_VBADC_ADC_DOUTMSB); + val2 = snd_soc_component_read32(component, WCD9335_VBADC_ADC_DOUTLSB); + snd_soc_component_update_bits(component, WCD9335_VBADC_ADC_IO, + 0x40, 0x00); vbat->dcp2 = (((val1 & 0xFF) << 3) | (val2 & 0x07)); - dev_dbg(codec->dev, "%s: dcp1:0x%x, dcp2:0x%x\n", + dev_dbg(component->dev, "%s: dcp1:0x%x, dcp2:0x%x\n", __func__, vbat->dcp1, vbat->dcp2); - snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28); + snd_soc_component_write(component, WCD9335_BIAS_CTL, 0x28); /* Wait 100 usec after selecting Vbg as 0.85V */ usleep_range(100, 110); - snd_soc_update_bits(codec, WCD9335_VBADC_FE_CTRL, 0x20, 0x00); - snd_soc_update_bits(codec, WCD9335_VBADC_SUBBLOCK_EN, 0x20, 0x20); - snd_soc_update_bits(codec, WCD9335_ANA_VBADC, 0x80, 0x00); + snd_soc_component_update_bits(component, WCD9335_VBADC_FE_CTRL, + 0x20, 0x00); + snd_soc_component_update_bits(component, WCD9335_VBADC_SUBBLOCK_EN, + 0x20, 0x20); + snd_soc_component_update_bits(component, WCD9335_ANA_VBADC, + 0x80, 0x00); - snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x00); - snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01, 0x00); + snd_soc_component_update_bits(component, WCD9335_CDC_VBAT_VBAT_PATH_CTL, + 0x10, 0x00); + snd_soc_component_update_bits(component, WCD9335_CDC_VBAT_VBAT_DEBUG1, + 0x01, 0x00); } static void wcd_vbat_adc_out_config_1_x(struct wcd_vbat *vbat, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { u8 val1, val2; @@ -8009,29 +8285,30 @@ static void wcd_vbat_adc_out_config_1_x(struct wcd_vbat *vbat, * Measure dcp1 by applying band gap voltage(Vbg) * of 0.85V */ - snd_soc_write(codec, WCD9335_ANA_BIAS, 0x20); - snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28); - snd_soc_write(codec, WCD9335_BIAS_VBG_FINE_ADJ, 0x05); - snd_soc_write(codec, WCD9335_ANA_BIAS, 0xA0); + snd_soc_component_write(component, WCD9335_ANA_BIAS, 0x20); + snd_soc_component_write(component, WCD9335_BIAS_CTL, 0x28); + snd_soc_component_write(component, WCD9335_BIAS_VBG_FINE_ADJ, 0x05); + snd_soc_component_write(component, WCD9335_ANA_BIAS, 0xA0); /* Wait 2 sec after enabling band gap bias */ usleep_range(2000000, 2000100); - snd_soc_write(codec, WCD9335_ANA_CLK_TOP, 0x82); - snd_soc_write(codec, WCD9335_ANA_CLK_TOP, 0x87); - snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x10, 0x10); - snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_CFG, 0x0D); - snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01); + snd_soc_component_write(component, WCD9335_ANA_CLK_TOP, 0x82); + snd_soc_component_write(component, WCD9335_ANA_CLK_TOP, 0x87); + snd_soc_component_update_bits(component, WCD9335_CDC_VBAT_VBAT_PATH_CTL, + 0x10, 0x10); + snd_soc_component_write(component, WCD9335_CDC_VBAT_VBAT_CFG, 0x0D); + snd_soc_component_write(component, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x01); - snd_soc_write(codec, WCD9335_ANA_VBADC, 0x80); - snd_soc_write(codec, WCD9335_VBADC_SUBBLOCK_EN, 0xDE); - snd_soc_write(codec, WCD9335_VBADC_FE_CTRL, 0x3C); + snd_soc_component_write(component, WCD9335_ANA_VBADC, 0x80); + snd_soc_component_write(component, WCD9335_VBADC_SUBBLOCK_EN, 0xDE); + snd_soc_component_write(component, WCD9335_VBADC_FE_CTRL, 0x3C); /* Wait 1 msec after calibration select as Vbg */ usleep_range(1000, 1100); - snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0xC0); - val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB); - val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB); - snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80); + snd_soc_component_write(component, WCD9335_VBADC_ADC_IO, 0xC0); + val1 = snd_soc_component_read32(component, WCD9335_VBADC_ADC_DOUTMSB); + val2 = snd_soc_component_read32(component, WCD9335_VBADC_ADC_DOUTLSB); + snd_soc_component_write(component, WCD9335_VBADC_ADC_IO, 0x80); vbat->dcp1 = (((val1 & 0xFF) << 3) | (val2 & 0x07)); @@ -8039,69 +8316,70 @@ static void wcd_vbat_adc_out_config_1_x(struct wcd_vbat *vbat, * Measure dcp2 by applying band gap voltage(Vbg) * of 1.05V */ - snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80); - snd_soc_write(codec, WCD9335_ANA_BIAS, 0xC0); - snd_soc_write(codec, WCD9335_BIAS_CTL, 0x68); + snd_soc_component_write(component, WCD9335_ANA_BIAS, 0x80); + snd_soc_component_write(component, WCD9335_ANA_BIAS, 0xC0); + snd_soc_component_write(component, WCD9335_BIAS_CTL, 0x68); /* Wait 2 msec after selecting Vbg as 1.05V */ usleep_range(2000, 2100); - snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80); + snd_soc_component_write(component, WCD9335_ANA_BIAS, 0x80); /* Wait 1 sec after enabling band gap bias */ usleep_range(1000000, 1000100); - snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0xC0); - val1 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTMSB); - val2 = snd_soc_read(codec, WCD9335_VBADC_ADC_DOUTLSB); - snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80); + snd_soc_component_write(component, WCD9335_VBADC_ADC_IO, 0xC0); + val1 = snd_soc_component_read32(component, WCD9335_VBADC_ADC_DOUTMSB); + val2 = snd_soc_component_read32(component, WCD9335_VBADC_ADC_DOUTLSB); + snd_soc_component_write(component, WCD9335_VBADC_ADC_IO, 0x80); vbat->dcp2 = (((val1 & 0xFF) << 3) | (val2 & 0x07)); - dev_dbg(codec->dev, "%s: dcp1:0x%x, dcp2:0x%x\n", + dev_dbg(component->dev, "%s: dcp1:0x%x, dcp2:0x%x\n", __func__, vbat->dcp1, vbat->dcp2); /* Reset the Vbat ADC configuration */ - snd_soc_write(codec, WCD9335_ANA_BIAS, 0x80); - snd_soc_write(codec, WCD9335_ANA_BIAS, 0xC0); + snd_soc_component_write(component, WCD9335_ANA_BIAS, 0x80); + snd_soc_component_write(component, WCD9335_ANA_BIAS, 0xC0); - snd_soc_write(codec, WCD9335_BIAS_CTL, 0x28); + snd_soc_component_write(component, WCD9335_BIAS_CTL, 0x28); /* Wait 2 msec after selecting Vbg as 0.85V */ usleep_range(2000, 2100); - snd_soc_write(codec, WCD9335_ANA_BIAS, 0xA0); + snd_soc_component_write(component, WCD9335_ANA_BIAS, 0xA0); /* Wait 1 sec after enabling band gap bias */ usleep_range(1000000, 1000100); - snd_soc_write(codec, WCD9335_VBADC_FE_CTRL, 0x1C); - snd_soc_write(codec, WCD9335_VBADC_SUBBLOCK_EN, 0xFE); - snd_soc_write(codec, WCD9335_VBADC_ADC_IO, 0x80); - snd_soc_write(codec, WCD9335_ANA_VBADC, 0x00); + snd_soc_component_write(component, WCD9335_VBADC_FE_CTRL, 0x1C); + snd_soc_component_write(component, WCD9335_VBADC_SUBBLOCK_EN, 0xFE); + snd_soc_component_write(component, WCD9335_VBADC_ADC_IO, 0x80); + snd_soc_component_write(component, WCD9335_ANA_VBADC, 0x00); - snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x00); - snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_PATH_CTL, 0x00); - snd_soc_write(codec, WCD9335_CDC_VBAT_VBAT_CFG, 0x0A); + snd_soc_component_write(component, WCD9335_CDC_VBAT_VBAT_DEBUG1, 0x00); + snd_soc_component_write(component, WCD9335_CDC_VBAT_VBAT_PATH_CTL, + 0x00); + snd_soc_component_write(component, WCD9335_CDC_VBAT_VBAT_CFG, 0x0A); } static void wcd_vbat_adc_out_config(struct wcd_vbat *vbat, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); if (!vbat->adc_config) { - tasha_cdc_mclk_enable(codec, true, false); + tasha_cdc_mclk_enable(component, true, false); if (TASHA_IS_2_0(wcd9xxx)) - wcd_vbat_adc_out_config_2_0(vbat, codec); + wcd_vbat_adc_out_config_2_0(vbat, component); else - wcd_vbat_adc_out_config_1_x(vbat, codec); + wcd_vbat_adc_out_config_1_x(vbat, component); - tasha_cdc_mclk_enable(codec, false, false); + tasha_cdc_mclk_enable(component, false, false); vbat->adc_config = true; } } -static int tasha_update_vbat_reg_config(struct snd_soc_codec *codec) +static int tasha_update_vbat_reg_config(struct snd_soc_component *component) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); struct firmware_cal *hwdep_cal = NULL; struct vbat_monitor_reg *vbat_reg_ptr = NULL; const void *data; @@ -8115,17 +8393,17 @@ static int tasha_update_vbat_reg_config(struct snd_soc_codec *codec) if (hwdep_cal) { data = hwdep_cal->data; cal_size = hwdep_cal->size; - dev_dbg(codec->dev, "%s: using hwdep calibration\n", + dev_dbg(component->dev, "%s: using hwdep calibration\n", __func__); } else { - dev_err(codec->dev, "%s: Vbat cal not received\n", + dev_err(component->dev, "%s: Vbat cal not received\n", __func__); ret = -EINVAL; goto done; } if (cal_size < sizeof(*vbat_reg_ptr)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Incorrect size %zd for Vbat Cal, expected %zd\n", __func__, cal_size, sizeof(*vbat_reg_ptr)); ret = -EINVAL; @@ -8135,7 +8413,7 @@ static int tasha_update_vbat_reg_config(struct snd_soc_codec *codec) vbat_reg_ptr = (struct vbat_monitor_reg *) (data); if (!vbat_reg_ptr) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Invalid calibration data for Vbat\n", __func__); ret = -EINVAL; @@ -8144,7 +8422,7 @@ static int tasha_update_vbat_reg_config(struct snd_soc_codec *codec) vbat_writes_size = vbat_reg_ptr->size; vbat_size_remaining = cal_size - sizeof(u32); - dev_dbg(codec->dev, "%s: vbat_writes_sz: %d, vbat_sz_remaining: %zd\n", + dev_dbg(component->dev, "%s: vbat_writes_sz: %d, vbat_sz_remaining: %zd\n", __func__, vbat_writes_size, vbat_size_remaining); if ((vbat_writes_size * TASHA_PACKED_REG_SIZE) @@ -8157,8 +8435,9 @@ static int tasha_update_vbat_reg_config(struct snd_soc_codec *codec) for (i = 0 ; i < vbat_writes_size; i++) { TASHA_CODEC_UNPACK_ENTRY(vbat_reg_ptr->writes[i], reg, mask, val); - old_val = snd_soc_read(codec, reg); - snd_soc_write(codec, reg, (old_val & ~mask) | (val & mask)); + old_val = snd_soc_component_read32(component, reg); + snd_soc_component_write(component, reg, (old_val & ~mask) | + (val & mask)); } done: @@ -8168,15 +8447,16 @@ static int tasha_update_vbat_reg_config(struct snd_soc_codec *codec) static int tasha_vbat_adc_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); - wcd_vbat_adc_out_config(&tasha->vbat, codec); + wcd_vbat_adc_out_config(&tasha->vbat, component); ucontrol->value.integer.value[0] = tasha->vbat.dcp1; ucontrol->value.integer.value[1] = tasha->vbat.dcp2; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: Vbat ADC output values, Dcp1 : %lu, Dcp2: %lu\n", __func__, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1]); @@ -8193,13 +8473,14 @@ static const struct soc_enum tasha_vbat_gsm_mode_enum = static int tasha_vbat_gsm_mode_func_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); ucontrol->value.integer.value[0] = - ((snd_soc_read(codec, WCD9335_CDC_VBAT_VBAT_CFG) & 0x04) ? - 1 : 0); + ((snd_soc_component_read32( + component, WCD9335_CDC_VBAT_VBAT_CFG) & 0x04) ? 1 : 0); - dev_dbg(codec->dev, "%s: value: %lu\n", __func__, + dev_dbg(component->dev, "%s: value: %lu\n", __func__, ucontrol->value.integer.value[0]); return 0; @@ -8208,18 +8489,21 @@ static int tasha_vbat_gsm_mode_func_get(struct snd_kcontrol *kcontrol, static int tasha_vbat_gsm_mode_func_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - dev_dbg(codec->dev, "%s: value: %lu\n", __func__, + dev_dbg(component->dev, "%s: value: %lu\n", __func__, ucontrol->value.integer.value[0]); /* Set Vbat register configuration for GSM mode bit based on value */ if (ucontrol->value.integer.value[0]) - snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_CFG, - 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD9335_CDC_VBAT_VBAT_CFG, + 0x04, 0x04); else - snd_soc_update_bits(codec, WCD9335_CDC_VBAT_VBAT_CFG, - 0x04, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_VBAT_VBAT_CFG, + 0x04, 0x00); return 0; } @@ -8229,8 +8513,9 @@ static int tasha_codec_vbat_enable_event(struct snd_soc_dapm_widget *w, int event) { int ret = 0; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); u16 vbat_path_ctl, vbat_cfg, vbat_path_cfg; vbat_path_ctl = WCD9335_CDC_VBAT_VBAT_PATH_CTL; @@ -8248,25 +8533,31 @@ static int tasha_codec_vbat_enable_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - ret = tasha_update_vbat_reg_config(codec); + ret = tasha_update_vbat_reg_config(component); if (ret) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s : VBAT isn't calibrated, So not enabling it\n", __func__); return 0; } - snd_soc_write(codec, WCD9335_ANA_VBADC, 0x80); - snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x02); - snd_soc_update_bits(codec, vbat_path_ctl, 0x10, 0x10); - snd_soc_update_bits(codec, vbat_cfg, 0x01, 0x01); + snd_soc_component_write(component, WCD9335_ANA_VBADC, 0x80); + snd_soc_component_update_bits(component, vbat_path_cfg, + 0x02, 0x02); + snd_soc_component_update_bits(component, vbat_path_ctl, + 0x10, 0x10); + snd_soc_component_update_bits(component, vbat_cfg, 0x01, 0x01); tasha->vbat.is_enabled = true; break; case SND_SOC_DAPM_POST_PMD: if (tasha->vbat.is_enabled) { - snd_soc_update_bits(codec, vbat_cfg, 0x01, 0x00); - snd_soc_update_bits(codec, vbat_path_ctl, 0x10, 0x00); - snd_soc_update_bits(codec, vbat_path_cfg, 0x02, 0x00); - snd_soc_write(codec, WCD9335_ANA_VBADC, 0x00); + snd_soc_component_update_bits(component, vbat_cfg, + 0x01, 0x00); + snd_soc_component_update_bits(component, vbat_path_ctl, + 0x10, 0x00); + snd_soc_component_update_bits(component, vbat_path_cfg, + 0x02, 0x00); + snd_soc_component_write(component, WCD9335_ANA_VBADC, + 0x00); tasha->vbat.is_enabled = false; } break; @@ -8523,8 +8814,9 @@ static int tasha_put_dec_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val; u16 mic_sel_reg; @@ -8534,7 +8826,7 @@ static int tasha_put_dec_enum(struct snd_kcontrol *kcontrol, if (val > e->items - 1) return -EINVAL; - dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__, widget->name, val); switch (e->reg) { @@ -8566,14 +8858,15 @@ static int tasha_put_dec_enum(struct snd_kcontrol *kcontrol, mic_sel_reg = WCD9335_CDC_TX8_TX_PATH_CFG0; break; default: - dev_err(codec->dev, "%s: e->reg: 0x%x not expected\n", + dev_err(component->dev, "%s: e->reg: 0x%x not expected\n", __func__, e->reg); return -EINVAL; } /* ADC: 0, DMIC: 1 */ mic_sel = val ? 0x0 : 0x1; - snd_soc_update_bits(codec, mic_sel_reg, 1 << 7, mic_sel << 7); + snd_soc_component_update_bits(component, mic_sel_reg, + 1 << 7, mic_sel << 7); return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); } @@ -8582,8 +8875,9 @@ static int tasha_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val; unsigned short look_ahead_dly_reg = WCD9335_CDC_RX0_RX_PATH_CFG0; @@ -8592,7 +8886,7 @@ static int tasha_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, if (val >= e->items) return -EINVAL; - dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__, widget->name, val); if (e->reg == WCD9335_CDC_RX0_RX_PATH_SEC0) @@ -8603,7 +8897,7 @@ static int tasha_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, look_ahead_dly_reg = WCD9335_CDC_RX2_RX_PATH_CFG0; /* Set Look Ahead Delay */ - snd_soc_update_bits(codec, look_ahead_dly_reg, + snd_soc_component_update_bits(component, look_ahead_dly_reg, 0x08, (val ? 0x08 : 0x00)); /* Set DEM INP Select */ return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); @@ -8613,15 +8907,16 @@ static int tasha_ear_pa_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 ear_pa_gain; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - ear_pa_gain = snd_soc_read(codec, WCD9335_ANA_EAR); + ear_pa_gain = snd_soc_component_read32(component, WCD9335_ANA_EAR); ear_pa_gain = (ear_pa_gain & 0x70) >> 4; ucontrol->value.integer.value[0] = ear_pa_gain; - dev_dbg(codec->dev, "%s: ear_pa_gain = 0x%x\n", __func__, + dev_dbg(component->dev, "%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain); return 0; @@ -8631,26 +8926,29 @@ static int tasha_ear_pa_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 ear_pa_gain; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); ear_pa_gain = ucontrol->value.integer.value[0] << 4; - snd_soc_update_bits(codec, WCD9335_ANA_EAR, 0x70, ear_pa_gain); + snd_soc_component_update_bits(component, WCD9335_ANA_EAR, + 0x70, ear_pa_gain); return 0; } static int tasha_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = tasha->ear_spkr_gain; - dev_dbg(codec->dev, "%s: ear_spkr_gain = %ld\n", __func__, + dev_dbg(component->dev, "%s: ear_spkr_gain = %ld\n", __func__, ucontrol->value.integer.value[0]); return 0; @@ -8659,10 +8957,11 @@ static int tasha_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, static int tasha_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); tasha->ear_spkr_gain = ucontrol->value.integer.value[0]; @@ -8674,12 +8973,14 @@ static int tasha_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 bst_state_max = 0; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - bst_state_max = snd_soc_read(codec, WCD9335_CDC_BOOST0_BOOST_CTL); + bst_state_max = snd_soc_component_read32( + component, WCD9335_CDC_BOOST0_BOOST_CTL); bst_state_max = (bst_state_max & 0x0c) >> 2; ucontrol->value.integer.value[0] = bst_state_max; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); return 0; @@ -8689,12 +8990,13 @@ static int tasha_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 bst_state_max; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); bst_state_max = ucontrol->value.integer.value[0] << 2; - snd_soc_update_bits(codec, WCD9335_CDC_BOOST0_BOOST_CTL, + snd_soc_component_update_bits(component, WCD9335_CDC_BOOST0_BOOST_CTL, 0x0c, bst_state_max); return 0; @@ -8704,12 +9006,14 @@ static int tasha_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 bst_state_max = 0; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - bst_state_max = snd_soc_read(codec, WCD9335_CDC_BOOST1_BOOST_CTL); + bst_state_max = snd_soc_component_read32( + component, WCD9335_CDC_BOOST1_BOOST_CTL); bst_state_max = (bst_state_max & 0x0c) >> 2; ucontrol->value.integer.value[0] = bst_state_max; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); return 0; @@ -8719,21 +9023,22 @@ static int tasha_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 bst_state_max; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); bst_state_max = ucontrol->value.integer.value[0] << 2; - snd_soc_update_bits(codec, WCD9335_CDC_BOOST1_BOOST_CTL, + snd_soc_component_update_bits(component, WCD9335_CDC_BOOST1_BOOST_CTL, 0x0c, bst_state_max); return 0; } -static int tasha_config_compander(struct snd_soc_codec *codec, int interp_n, - int event) +static int tasha_config_compander(struct snd_soc_component *component, + int interp_n, int event) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); int comp; u16 comp_ctl0_reg, rx_path_cfg0_reg; @@ -8742,7 +9047,7 @@ static int tasha_config_compander(struct snd_soc_codec *codec, int interp_n, return 0; comp = interp_n - 1; - dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n", + dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n", __func__, event, comp + 1, tasha->comp_enabled[comp]); if (!tasha->comp_enabled[comp]) @@ -8753,25 +9058,35 @@ static int tasha_config_compander(struct snd_soc_codec *codec, int interp_n, if (SND_SOC_DAPM_EVENT_ON(event)) { /* Enable Compander Clock */ - snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x01, 0x01); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x02); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x00); + snd_soc_component_update_bits(component, rx_path_cfg0_reg, + 0x02, 0x02); } if (SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); - snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x04, 0x04); + snd_soc_component_update_bits(component, rx_path_cfg0_reg, + 0x02, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x02); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x01, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x04, 0x00); } return 0; } -static int tasha_codec_config_mad(struct snd_soc_codec *codec) +static int tasha_codec_config_mad(struct snd_soc_component *component) { int ret = 0; int idx; @@ -8780,31 +9095,31 @@ static int tasha_codec_config_mad(struct snd_soc_codec *codec) struct wcd_mad_audio_cal *mad_cal = NULL; const void *data; const char *filename = TASHA_MAD_AUDIO_FIRMWARE_PATH; - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); size_t cal_size; hwdep_cal = wcdcal_get_fw_cal(tasha->fw_data, WCD9XXX_MAD_CAL); if (hwdep_cal) { data = hwdep_cal->data; cal_size = hwdep_cal->size; - dev_dbg(codec->dev, "%s: using hwdep calibration\n", + dev_dbg(component->dev, "%s: using hwdep calibration\n", __func__); } else { - ret = request_firmware(&fw, filename, codec->dev); + ret = request_firmware(&fw, filename, component->dev); if (ret || !fw) { - dev_err(codec->dev, + dev_err(component->dev, "%s: MAD firmware acquire failed, err = %d\n", __func__, ret); return -ENODEV; } data = fw->data; cal_size = fw->size; - dev_dbg(codec->dev, "%s: using request_firmware calibration\n", + dev_dbg(component->dev, "%s: using request_firmware calibration\n", __func__); } if (cal_size < sizeof(*mad_cal)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Incorrect size %zd for MAD Cal, expected %zd\n", __func__, cal_size, sizeof(*mad_cal)); ret = -ENOMEM; @@ -8813,80 +9128,86 @@ static int tasha_codec_config_mad(struct snd_soc_codec *codec) mad_cal = (struct wcd_mad_audio_cal *) (data); if (!mad_cal) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Invalid calibration data\n", __func__); ret = -EINVAL; goto done; } - snd_soc_write(codec, WCD9335_SOC_MAD_MAIN_CTL_2, + snd_soc_component_write(component, WCD9335_SOC_MAD_MAIN_CTL_2, mad_cal->microphone_info.cycle_time); - snd_soc_update_bits(codec, WCD9335_SOC_MAD_MAIN_CTL_1, 0xFF << 3, - ((uint16_t)mad_cal->microphone_info.settle_time) - << 3); + snd_soc_component_update_bits(component, WCD9335_SOC_MAD_MAIN_CTL_1, + 0xFF << 3, + ((uint16_t)mad_cal->microphone_info.settle_time) << 3); /* Audio */ - snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_8, + snd_soc_component_write(component, WCD9335_SOC_MAD_AUDIO_CTL_8, mad_cal->audio_info.rms_omit_samples); - snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_CTL_1, + snd_soc_component_update_bits(component, WCD9335_SOC_MAD_AUDIO_CTL_1, 0x07 << 4, mad_cal->audio_info.rms_comp_time << 4); - snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03 << 2, - mad_cal->audio_info.detection_mechanism << 2); - snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_7, + snd_soc_component_update_bits(component, WCD9335_SOC_MAD_AUDIO_CTL_2, + 0x03 << 2, + mad_cal->audio_info.detection_mechanism << 2); + snd_soc_component_write(component, WCD9335_SOC_MAD_AUDIO_CTL_7, mad_cal->audio_info.rms_diff_threshold & 0x3F); - snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_5, + snd_soc_component_write(component, WCD9335_SOC_MAD_AUDIO_CTL_5, mad_cal->audio_info.rms_threshold_lsb); - snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_CTL_6, + snd_soc_component_write(component, WCD9335_SOC_MAD_AUDIO_CTL_6, mad_cal->audio_info.rms_threshold_msb); for (idx = 0; idx < ARRAY_SIZE(mad_cal->audio_info.iir_coefficients); idx++) { - snd_soc_update_bits(codec, WCD9335_SOC_MAD_AUDIO_IIR_CTL_PTR, - 0x3F, idx); - snd_soc_write(codec, WCD9335_SOC_MAD_AUDIO_IIR_CTL_VAL, - mad_cal->audio_info.iir_coefficients[idx]); - dev_dbg(codec->dev, "%s:MAD Audio IIR Coef[%d] = 0X%x", + snd_soc_component_update_bits(component, + WCD9335_SOC_MAD_AUDIO_IIR_CTL_PTR, 0x3F, idx); + snd_soc_component_write(component, + WCD9335_SOC_MAD_AUDIO_IIR_CTL_VAL, + mad_cal->audio_info.iir_coefficients[idx]); + dev_dbg(component->dev, "%s:MAD Audio IIR Coef[%d] = 0X%x", __func__, idx, mad_cal->audio_info.iir_coefficients[idx]); } /* Beacon */ - snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_8, + snd_soc_component_write(component, WCD9335_SOC_MAD_BEACON_CTL_8, mad_cal->beacon_info.rms_omit_samples); - snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_CTL_1, + snd_soc_component_update_bits(component, WCD9335_SOC_MAD_BEACON_CTL_1, 0x07 << 4, mad_cal->beacon_info.rms_comp_time << 4); - snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_CTL_2, 0x03 << 2, - mad_cal->beacon_info.detection_mechanism << 2); - snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_7, + snd_soc_component_update_bits(component, WCD9335_SOC_MAD_BEACON_CTL_2, + 0x03 << 2, + mad_cal->beacon_info.detection_mechanism << 2); + snd_soc_component_write(component, WCD9335_SOC_MAD_BEACON_CTL_7, mad_cal->beacon_info.rms_diff_threshold & 0x1F); - snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_5, + snd_soc_component_write(component, WCD9335_SOC_MAD_BEACON_CTL_5, mad_cal->beacon_info.rms_threshold_lsb); - snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_CTL_6, + snd_soc_component_write(component, WCD9335_SOC_MAD_BEACON_CTL_6, mad_cal->beacon_info.rms_threshold_msb); for (idx = 0; idx < ARRAY_SIZE(mad_cal->beacon_info.iir_coefficients); idx++) { - snd_soc_update_bits(codec, WCD9335_SOC_MAD_BEACON_IIR_CTL_PTR, - 0x3F, idx); - snd_soc_write(codec, WCD9335_SOC_MAD_BEACON_IIR_CTL_VAL, - mad_cal->beacon_info.iir_coefficients[idx]); - dev_dbg(codec->dev, "%s:MAD Beacon IIR Coef[%d] = 0X%x", + snd_soc_component_update_bits(component, + WCD9335_SOC_MAD_BEACON_IIR_CTL_PTR, + 0x3F, idx); + snd_soc_component_write(component, + WCD9335_SOC_MAD_BEACON_IIR_CTL_VAL, + mad_cal->beacon_info.iir_coefficients[idx]); + dev_dbg(component->dev, "%s:MAD Beacon IIR Coef[%d] = 0X%x", __func__, idx, mad_cal->beacon_info.iir_coefficients[idx]); } /* Ultrasound */ - snd_soc_update_bits(codec, WCD9335_SOC_MAD_ULTR_CTL_1, + snd_soc_component_update_bits(component, WCD9335_SOC_MAD_ULTR_CTL_1, 0x07 << 4, mad_cal->ultrasound_info.rms_comp_time << 4); - snd_soc_update_bits(codec, WCD9335_SOC_MAD_ULTR_CTL_2, 0x03 << 2, - mad_cal->ultrasound_info.detection_mechanism << 2); - snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_7, + snd_soc_component_update_bits(component, WCD9335_SOC_MAD_ULTR_CTL_2, + 0x03 << 2, + mad_cal->ultrasound_info.detection_mechanism << 2); + snd_soc_component_write(component, WCD9335_SOC_MAD_ULTR_CTL_7, mad_cal->ultrasound_info.rms_diff_threshold & 0x1F); - snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_5, + snd_soc_component_write(component, WCD9335_SOC_MAD_ULTR_CTL_5, mad_cal->ultrasound_info.rms_threshold_lsb); - snd_soc_write(codec, WCD9335_SOC_MAD_ULTR_CTL_6, + snd_soc_component_write(component, WCD9335_SOC_MAD_ULTR_CTL_6, mad_cal->ultrasound_info.rms_threshold_msb); done: @@ -8899,38 +9220,39 @@ static int tasha_codec_config_mad(struct snd_soc_codec *codec) static int tasha_codec_enable_mad(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); int ret = 0; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: event = %d\n", __func__, event); /* Return if CPE INPUT is DEC1 */ - if (snd_soc_read(codec, WCD9335_CPE_SS_SVA_CFG) & 0x01) + if (snd_soc_component_read32(component, WCD9335_CPE_SS_SVA_CFG) & 0x01) return ret; switch (event) { case SND_SOC_DAPM_PRE_PMU: /* Turn on MAD clk */ - snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL, + snd_soc_component_update_bits(component, WCD9335_CPE_SS_MAD_CTL, 0x01, 0x01); /* Undo reset for MAD */ - snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL, + snd_soc_component_update_bits(component, WCD9335_CPE_SS_MAD_CTL, 0x02, 0x00); - ret = tasha_codec_config_mad(codec); + ret = tasha_codec_config_mad(component); if (ret) - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to config MAD, err = %d\n", __func__, ret); break; case SND_SOC_DAPM_POST_PMD: /* Reset the MAD block */ - snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL, + snd_soc_component_update_bits(component, WCD9335_CPE_SS_MAD_CTL, 0x02, 0x02); /* Turn off MAD clk */ - snd_soc_update_bits(codec, WCD9335_CPE_SS_MAD_CTL, + snd_soc_component_update_bits(component, WCD9335_CPE_SS_MAD_CTL, 0x01, 0x00); break; } @@ -8941,27 +9263,30 @@ static int tasha_codec_enable_mad(struct snd_soc_dapm_widget *w, static int tasha_codec_configure_cpe_input(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: event = %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: /* Configure CPE input as DEC1 */ - snd_soc_update_bits(codec, WCD9335_CPE_SS_SVA_CFG, - 0x01, 0x01); + snd_soc_component_update_bits(component, WCD9335_CPE_SS_SVA_CFG, + 0x01, 0x01); /* Configure DEC1 Tx out with sample rate as 16K */ - snd_soc_update_bits(codec, WCD9335_CDC_TX1_TX_PATH_CTL, - 0x0F, 0x01); + snd_soc_component_update_bits(component, + WCD9335_CDC_TX1_TX_PATH_CTL, + 0x0F, 0x01); break; case SND_SOC_DAPM_POST_PMD: /* Reset DEC1 Tx out sample rate */ - snd_soc_update_bits(codec, WCD9335_CDC_TX1_TX_PATH_CTL, - 0x0F, 0x04); - snd_soc_update_bits(codec, WCD9335_CPE_SS_SVA_CFG, + snd_soc_component_update_bits(component, + WCD9335_CDC_TX1_TX_PATH_CTL, + 0x0F, 0x04); + snd_soc_component_update_bits(component, WCD9335_CPE_SS_SVA_CFG, 0x01, 0x00); break; @@ -8976,15 +9301,16 @@ static int tasha_codec_aif4_mixer_switch_get(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component); if (test_bit(AIF4_SWITCH_VALUE, &tasha_p->status_mask)) ucontrol->value.integer.value[0] = 1; else ucontrol->value.integer.value[0] = 0; - dev_dbg(codec->dev, "%s: AIF4 switch value = %ld\n", + dev_dbg(component->dev, "%s: AIF4 switch value = %ld\n", __func__, ucontrol->value.integer.value[0]); return 0; } @@ -8995,10 +9321,11 @@ static int tasha_codec_aif4_mixer_switch_put(struct snd_kcontrol *kcontrol, struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_dapm_update *update = NULL; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tasha_priv *tasha_p = snd_soc_component_get_drvdata(component); - dev_dbg(codec->dev, "%s: AIF4 switch value = %ld\n", + dev_dbg(component->dev, "%s: AIF4 switch value = %ld\n", __func__, ucontrol->value.integer.value[0]); if (ucontrol->value.integer.value[0]) { @@ -10306,23 +10633,29 @@ static int tasha_codec_ec_buf_mux_enable(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); - dev_dbg(codec->dev, "%s: event = %d name = %s\n", + dev_dbg(component->dev, "%s: event = %d name = %s\n", __func__, event, w->name); switch (event) { case SND_SOC_DAPM_POST_PMU: - snd_soc_write(codec, WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x3B); - snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, 0x08, 0x08); - snd_soc_update_bits(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, - 0x08, 0x08); + snd_soc_component_write(component, + WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x3B); + snd_soc_component_update_bits(component, + WCD9335_CPE_SS_CFG, 0x08, 0x08); + snd_soc_component_update_bits(component, + WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 0x08, 0x08); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, - 0x08, 0x00); - snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, 0x08, 0x00); - snd_soc_write(codec, WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, + 0x08, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CPE_SS_CFG, 0x08, 0x00); + snd_soc_component_write(component, + WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x00); break; } @@ -11128,7 +11461,8 @@ static int tasha_get_channel_map(struct snd_soc_dai *dai, unsigned int *tx_num, unsigned int *tx_slot, unsigned int *rx_num, unsigned int *rx_slot) { - struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(dai->codec); + struct tasha_priv *tasha_p = + snd_soc_component_get_drvdata(dai->component); u32 i = 0; struct wcd9xxx_ch *ch; @@ -11192,8 +11526,8 @@ static int tasha_set_channel_map(struct snd_soc_dai *dai, pr_err("%s: dai is empty\n", __func__); return -EINVAL; } - tasha = snd_soc_codec_get_drvdata(dai->codec); - core = dev_get_drvdata(dai->codec->dev->parent); + tasha = snd_soc_component_get_drvdata(dai->component); + core = dev_get_drvdata(dai->component->dev->parent); if (!tx_slot || !rx_slot) { pr_err("%s: Invalid tx_slot=%pK, rx_slot=%pK\n", @@ -11234,7 +11568,8 @@ static int tasha_startup(struct snd_pcm_substream *substream, static void tasha_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec); + struct tasha_priv *tasha = + snd_soc_component_get_drvdata(dai->component); pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); @@ -11243,15 +11578,15 @@ static void tasha_shutdown(struct snd_pcm_substream *substream, return; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - tasha_codec_vote_max_bw(dai->codec, false); + tasha_codec_vote_max_bw(dai->component, false); } static int tasha_set_decimator_rate(struct snd_soc_dai *dai, u8 tx_fs_rate_reg_val, u32 sample_rate) { - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; struct wcd9xxx_ch *ch; - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); u32 tx_port = 0; u8 shift = 0, shift_val = 0, tx_mux_sel = 0; int decimator = -1; @@ -11259,11 +11594,11 @@ static int tasha_set_decimator_rate(struct snd_soc_dai *dai, list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) { tx_port = ch->port; - dev_dbg(codec->dev, "%s: dai->id = %d, tx_port = %d", + dev_dbg(component->dev, "%s: dai->id = %d, tx_port = %d", __func__, dai->id, tx_port); if ((tx_port < 0) || (tx_port == 12) || (tx_port >= 14)) { - dev_err(codec->dev, "%s: Invalid SLIM TX%u port. DAI ID: %d\n", + dev_err(component->dev, "%s: Invalid SLIM TX%u port. DAI ID: %d\n", __func__, tx_port, dai->id); return -EINVAL; } @@ -11289,7 +11624,7 @@ static int tasha_set_decimator_rate(struct snd_soc_dai *dai, shift = 4; shift_val = 0x03; } - tx_mux_sel = snd_soc_read(codec, tx_port_reg) & + tx_mux_sel = snd_soc_component_read32(component, tx_port_reg) & (shift_val << shift); tx_mux_sel = tx_mux_sel >> shift; @@ -11310,16 +11645,16 @@ static int tasha_set_decimator_rate(struct snd_soc_dai *dai, if (decimator >= 0) { tx_fs_reg = WCD9335_CDC_TX0_TX_PATH_CTL + 16 * decimator; - dev_dbg(codec->dev, "%s: set DEC%u (-> SLIM_TX%u) rate to %u\n", + dev_dbg(component->dev, "%s: set DEC%u (-> SLIM_TX%u) rate to %u\n", __func__, decimator, tx_port, sample_rate); - snd_soc_update_bits(codec, tx_fs_reg, 0x0F, - tx_fs_rate_reg_val); + snd_soc_component_update_bits(component, tx_fs_reg, + 0x0F, tx_fs_rate_reg_val); } else if ((tx_port <= 8) && (tx_mux_sel == 0x01)) { /* Check if the TX Mux input is RX MIX TXn */ - dev_dbg(codec->dev, "%s: RX_MIX_TX%u going to SLIM TX%u\n", + dev_dbg(component->dev, "%s: RX_MIX_TX%u going to SLIM TX%u\n", __func__, tx_port, tx_port); } else { - dev_err(codec->dev, "%s: ERROR: Invalid decimator: %d\n", + dev_err(component->dev, "%s: ERROR: Invalid decimator: %d\n", __func__, decimator); return -EINVAL; } @@ -11335,9 +11670,9 @@ static int tasha_set_mix_interpolator_rate(struct snd_soc_dai *dai, u32 j; u16 int_mux_cfg1, int_fs_reg; u8 int_mux_cfg1_val; - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; struct wcd9xxx_ch *ch; - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) { int_2_inp = ch->port + INTn_2_INP_SEL_RX0 - @@ -11353,7 +11688,8 @@ static int tasha_set_mix_interpolator_rate(struct snd_soc_dai *dai, int_mux_cfg1 = WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1; for (j = 0; j < TASHA_NUM_INTERPOLATORS; j++) { - int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1) & + int_mux_cfg1_val = snd_soc_component_read32( + component, int_mux_cfg1) & 0x0F; if (int_mux_cfg1_val == int_2_inp) { int_fs_reg = WCD9335_CDC_RX0_RX_PATH_MIX_CTL + @@ -11362,7 +11698,8 @@ static int tasha_set_mix_interpolator_rate(struct snd_soc_dai *dai, __func__, dai->id, j); pr_debug("%s: set INT%u_2 sample rate to %u\n", __func__, j, sample_rate); - snd_soc_update_bits(codec, int_fs_reg, + snd_soc_component_update_bits(component, + int_fs_reg, 0x0F, int_mix_fs_rate_reg_val); } int_mux_cfg1 += 2; @@ -11381,9 +11718,9 @@ static int tasha_set_prim_interpolator_rate(struct snd_soc_dai *dai, u16 int_fs_reg; u8 int_mux_cfg0_val, int_mux_cfg1_val; u8 inp0_sel, inp1_sel, inp2_sel; - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; struct wcd9xxx_ch *ch; - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); list_for_each_entry(ch, &tasha->dai[dai->id].wcd9xxx_ch_list, list) { int_1_mix1_inp = ch->port + INTn_1_MIX_INP_SEL_RX0 - @@ -11407,8 +11744,10 @@ static int tasha_set_prim_interpolator_rate(struct snd_soc_dai *dai, for (j = 0; j < TASHA_NUM_INTERPOLATORS; j++) { int_mux_cfg1 = int_mux_cfg0 + 1; - int_mux_cfg0_val = snd_soc_read(codec, int_mux_cfg0); - int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1); + int_mux_cfg0_val = snd_soc_component_read32(component, + int_mux_cfg0); + int_mux_cfg1_val = snd_soc_component_read32(component, + int_mux_cfg1); inp0_sel = int_mux_cfg0_val & 0x0F; inp1_sel = (int_mux_cfg0_val >> 4) & 0x0F; inp2_sel = (int_mux_cfg1_val >> 4) & 0x0F; @@ -11426,7 +11765,8 @@ static int tasha_set_prim_interpolator_rate(struct snd_soc_dai *dai, pr_info("%s: Cannot set 44.1KHz on INT0\n", __func__); } else - snd_soc_update_bits(codec, int_fs_reg, + snd_soc_component_update_bits( + component, int_fs_reg, 0x0F, int_prim_fs_rate_reg_val); } int_mux_cfg0 += 2; @@ -11482,7 +11822,7 @@ static int tasha_prepare(struct snd_pcm_substream *substream, substream->name, substream->stream); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - tasha_codec_vote_max_bw(dai->codec, false); + tasha_codec_vote_max_bw(dai->component, false); return 0; } @@ -11490,12 +11830,13 @@ static int tasha_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec); + struct tasha_priv *tasha = + snd_soc_component_get_drvdata(dai->component); int ret; int tx_fs_rate = -EINVAL; int rx_fs_rate = -EINVAL; int i2s_bit_mode; - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__, dai->name, dai->id, params_rate(params), @@ -11548,10 +11889,10 @@ static int tasha_hw_params(struct snd_pcm_substream *substream, __func__, params_rate(params)); return -EINVAL; }; - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL, 0x20, i2s_bit_mode << 5); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL, 0x1c, (rx_fs_rate << 2)); } @@ -11615,27 +11956,27 @@ static int tasha_hw_params(struct snd_pcm_substream *substream, return -EINVAL; }; if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL, 0x20, i2s_bit_mode << 5); if (tx_fs_rate > 1) tx_fs_rate--; - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL, 0x1c, tx_fs_rate << 2); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG, 0x05, 0x05); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG, 0x05, 0x05); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG, 0x05, 0x05); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG, 0x05, 0x05); } @@ -11653,18 +11994,19 @@ static int tasha_hw_params(struct snd_pcm_substream *substream, static int tasha_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(dai->codec); + struct tasha_priv *tasha = + snd_soc_component_get_drvdata(dai->component); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: /* CPU is master */ if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { if (dai->id == AIF1_CAP) - snd_soc_update_bits(dai->codec, + snd_soc_component_update_bits(dai->component, WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL, 0x2, 0); else if (dai->id == AIF1_PB) - snd_soc_update_bits(dai->codec, + snd_soc_component_update_bits(dai->component, WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL, 0x2, 0); } @@ -11673,11 +12015,11 @@ static int tasha_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) /* CPU is slave */ if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { if (dai->id == AIF1_CAP) - snd_soc_update_bits(dai->codec, + snd_soc_component_update_bits(dai->component, WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL, 0x2, 0x2); else if (dai->id == AIF1_PB) - snd_soc_update_bits(dai->codec, + snd_soc_component_update_bits(dai->component, WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL, 0x2, 0x2); } @@ -11939,13 +12281,13 @@ static struct snd_soc_dai_driver tasha_i2s_dai[] = { static void tasha_codec_power_gate_digital_core(struct tasha_priv *tasha) { - struct snd_soc_codec *codec = tasha->codec; + struct snd_soc_component *component = tasha->component; - if (!codec) + if (!component) return; mutex_lock(&tasha->power_lock); - dev_dbg(codec->dev, "%s: Entering power gating function, %d\n", + dev_dbg(component->dev, "%s: Entering power gating function, %d\n", __func__, tasha->power_active_ref); if (tasha->power_active_ref > 0) @@ -11954,18 +12296,21 @@ static void tasha_codec_power_gate_digital_core(struct tasha_priv *tasha) wcd9xxx_set_power_state(tasha->wcd9xxx, WCD_REGION_POWER_COLLAPSE_BEGIN, WCD9XXX_DIG_CORE_REGION_1); - snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + snd_soc_component_update_bits(component, + WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x04, 0x04); - snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + snd_soc_component_update_bits(component, + WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x01, 0x00); - snd_soc_update_bits(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + snd_soc_component_update_bits(component, + WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x02, 0x00); clear_bit(AUDIO_NOMINAL, &tasha->status_mask); tasha_codec_update_sido_voltage(tasha, sido_buck_svs_voltage); wcd9xxx_set_power_state(tasha->wcd9xxx, WCD_REGION_POWER_DOWN, WCD9XXX_DIG_CORE_REGION_1); exit: - dev_dbg(codec->dev, "%s: Exiting power gating function, %d\n", + dev_dbg(component->dev, "%s: Exiting power gating function, %d\n", __func__, tasha->power_active_ref); mutex_unlock(&tasha->power_lock); } @@ -11974,37 +12319,43 @@ static void tasha_codec_power_gate_work(struct work_struct *work) { struct tasha_priv *tasha; struct delayed_work *dwork; - struct snd_soc_codec *codec; + struct snd_soc_component *component; dwork = to_delayed_work(work); tasha = container_of(dwork, struct tasha_priv, power_gate_work); - codec = tasha->codec; + component = tasha->component; - if (!codec) + if (!component) return; tasha_codec_power_gate_digital_core(tasha); } /* called under power_lock acquisition */ -static int tasha_dig_core_remove_power_collapse(struct snd_soc_codec *codec) -{ - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); - - tasha_codec_vote_max_bw(codec, true); - snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5); - snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7); - snd_soc_write(codec, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3); - snd_soc_update_bits(codec, WCD9335_CODEC_RPM_RST_CTL, 0x02, 0x00); - snd_soc_update_bits(codec, WCD9335_CODEC_RPM_RST_CTL, 0x02, 0x02); +static int tasha_dig_core_remove_power_collapse( + struct snd_soc_component *component) +{ + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); + + tasha_codec_vote_max_bw(component, true); + snd_soc_component_write(component, + WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5); + snd_soc_component_write(component, + WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7); + snd_soc_component_write(component, + WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3); + snd_soc_component_update_bits(component, WCD9335_CODEC_RPM_RST_CTL, + 0x02, 0x00); + snd_soc_component_update_bits(component, WCD9335_CODEC_RPM_RST_CTL, + 0x02, 0x02); wcd9xxx_set_power_state(tasha->wcd9xxx, WCD_REGION_POWER_COLLAPSE_REMOVE, WCD9XXX_DIG_CORE_REGION_1); - regcache_mark_dirty(codec->component.regmap); - regcache_sync_region(codec->component.regmap, + regcache_mark_dirty(component->regmap); + regcache_sync_region(component->regmap, TASHA_DIG_CORE_REG_MIN, TASHA_DIG_CORE_REG_MAX); - tasha_codec_vote_max_bw(codec, false); + tasha_codec_vote_max_bw(component, false); return 0; } @@ -12012,7 +12363,7 @@ static int tasha_dig_core_remove_power_collapse(struct snd_soc_codec *codec) static int tasha_dig_core_power_collapse(struct tasha_priv *tasha, int req_state) { - struct snd_soc_codec *codec; + struct snd_soc_component *component; int cur_state; /* Exit if feature is disabled */ @@ -12033,8 +12384,8 @@ static int tasha_dig_core_power_collapse(struct tasha_priv *tasha, goto unlock_mutex; } - codec = tasha->codec; - if (!codec) + component = tasha->component; + if (!component) goto unlock_mutex; if (req_state == POWER_COLLAPSE) { @@ -12054,7 +12405,7 @@ static int tasha_dig_core_power_collapse(struct tasha_priv *tasha, tasha->wcd9xxx, WCD9XXX_DIG_CORE_REGION_1); if (cur_state == WCD_REGION_POWER_DOWN) - tasha_dig_core_remove_power_collapse(codec); + tasha_dig_core_remove_power_collapse(component); else { mutex_unlock(&tasha->power_lock); cancel_delayed_work_sync( @@ -12117,17 +12468,19 @@ static int __tasha_cdc_mclk_enable(struct tasha_priv *tasha, return ret; } -int tasha_cdc_mclk_enable(struct snd_soc_codec *codec, int enable, bool dapm) +int tasha_cdc_mclk_enable(struct snd_soc_component *component, + int enable, bool dapm) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); return __tasha_cdc_mclk_enable(tasha, enable); } EXPORT_SYMBOL(tasha_cdc_mclk_enable); -int tasha_cdc_mclk_tx_enable(struct snd_soc_codec *codec, int enable, bool dapm) +int tasha_cdc_mclk_tx_enable(struct snd_soc_component *component, + int enable, bool dapm) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); int ret = 0; dev_dbg(tasha->dev, "%s: clk_mode: %d, enable: %d, clk_internal: %d\n", @@ -12137,10 +12490,10 @@ int tasha_cdc_mclk_tx_enable(struct snd_soc_codec *codec, int enable, bool dapm) tasha_cdc_sido_ccl_enable(tasha, true); wcd_resmgr_enable_master_bias(tasha->resmgr); tasha_dig_core_power_collapse(tasha, POWER_RESUME); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x01); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x01); set_bit(CPE_NOMINAL, &tasha->status_mask); @@ -12202,7 +12555,7 @@ static struct snd_info_entry_ops tasha_codec_info_ops = { /* * tasha_codec_info_create_codec_entry - creates wcd9335 module * @codec_root: The parent directory - * @codec: Codec instance + * @component: Codec instance * * Creates wcd9335 module and version entry under the given * parent directory. @@ -12210,21 +12563,21 @@ static struct snd_info_entry_ops tasha_codec_info_ops = { * Return: 0 on success or negative error code on failure. */ int tasha_codec_info_create_codec_entry(struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { struct snd_info_entry *version_entry; struct tasha_priv *tasha; struct snd_soc_card *card; - if (!codec_root || !codec) + if (!codec_root || !component) return -EINVAL; - tasha = snd_soc_codec_get_drvdata(codec); - card = codec->component.card; + tasha = snd_soc_component_get_drvdata(component); + card = component->card; tasha->entry = snd_info_create_subdir(codec_root->module, "tasha", codec_root); if (!tasha->entry) { - dev_dbg(codec->dev, "%s: failed to create wcd9335 entry\n", + dev_dbg(component->dev, "%s: failed to create wcd9335 entry\n", __func__); return -ENOMEM; } @@ -12233,7 +12586,7 @@ int tasha_codec_info_create_codec_entry(struct snd_info_entry *codec_root, "version", tasha->entry); if (!version_entry) { - dev_dbg(codec->dev, "%s: failed to create wcd9335 version entry\n", + dev_dbg(component->dev, "%s: failed to create wcd9335 version entry\n", __func__); return -ENOMEM; } @@ -12254,9 +12607,9 @@ int tasha_codec_info_create_codec_entry(struct snd_info_entry *codec_root, EXPORT_SYMBOL(tasha_codec_info_create_codec_entry); static int __tasha_codec_internal_rco_ctrl( - struct snd_soc_codec *codec, bool enable) + struct snd_soc_component *component, bool enable) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); int ret = 0; if (enable) { @@ -12279,7 +12632,7 @@ static int __tasha_codec_internal_rco_ctrl( } if (ret) { - dev_err(codec->dev, "%s: Error in %s RCO\n", + dev_err(component->dev, "%s: Error in %s RCO\n", __func__, (enable ? "enabling" : "disabling")); ret = -EINVAL; } @@ -12292,28 +12645,28 @@ static int __tasha_codec_internal_rco_ctrl( * Make sure that the caller does not acquire * BG_CLK_LOCK. */ -static int tasha_codec_internal_rco_ctrl(struct snd_soc_codec *codec, +static int tasha_codec_internal_rco_ctrl(struct snd_soc_component *component, bool enable) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); int ret = 0; WCD9XXX_V2_BG_CLK_LOCK(tasha->resmgr); - ret = __tasha_codec_internal_rco_ctrl(codec, enable); + ret = __tasha_codec_internal_rco_ctrl(component, enable); WCD9XXX_V2_BG_CLK_UNLOCK(tasha->resmgr); return ret; } /* * tasha_mbhc_hs_detect: starts mbhc insertion/removal functionality - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * * @mbhc_cfg: handle to mbhc configuration structure * return 0 if mbhc_start is success or error code in case of failure */ -int tasha_mbhc_hs_detect(struct snd_soc_codec *codec, +int tasha_mbhc_hs_detect(struct snd_soc_component *component, struct wcd_mbhc_config *mbhc_cfg) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); return wcd_mbhc_start(&tasha->mbhc, mbhc_cfg); } @@ -12321,11 +12674,11 @@ EXPORT_SYMBOL(tasha_mbhc_hs_detect); /* * tasha_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * */ -void tasha_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +void tasha_mbhc_hs_detect_exit(struct snd_soc_component *component) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); wcd_mbhc_stop(&tasha->mbhc); } @@ -12519,27 +12872,27 @@ static const struct tasha_reg_mask_val tasha_codec_reg_init_1_x_val[] = { {WCD9335_DIFF_LO_COM_PA_FREQ, 0x70, 0x40}, }; -static void tasha_update_reg_reset_values(struct snd_soc_codec *codec) +static void tasha_update_reg_reset_values(struct snd_soc_component *component) { u32 i; - struct wcd9xxx *tasha_core = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx *tasha_core = dev_get_drvdata(component->dev->parent); if (TASHA_IS_1_1(tasha_core)) { for (i = 0; i < ARRAY_SIZE(tasha_reg_update_reset_val_1_1); i++) - snd_soc_write(codec, + snd_soc_component_write(component, tasha_reg_update_reset_val_1_1[i].reg, tasha_reg_update_reset_val_1_1[i].val); } } -static void tasha_codec_init_reg(struct snd_soc_codec *codec) +static void tasha_codec_init_reg(struct snd_soc_component *component) { u32 i; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_common_val); i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, tasha_codec_reg_init_common_val[i].reg, tasha_codec_reg_init_common_val[i].mask, tasha_codec_reg_init_common_val[i].val); @@ -12547,26 +12900,26 @@ static void tasha_codec_init_reg(struct snd_soc_codec *codec) if (TASHA_IS_1_1(wcd9xxx) || TASHA_IS_1_0(wcd9xxx)) for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_1_x_val); i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, tasha_codec_reg_init_1_x_val[i].reg, tasha_codec_reg_init_1_x_val[i].mask, tasha_codec_reg_init_1_x_val[i].val); if (TASHA_IS_1_1(wcd9xxx)) { for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_1_1); i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, tasha_codec_reg_init_val_1_1[i].reg, tasha_codec_reg_init_val_1_1[i].mask, tasha_codec_reg_init_val_1_1[i].val); } else if (TASHA_IS_1_0(wcd9xxx)) { for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_1_0); i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, tasha_codec_reg_init_val_1_0[i].reg, tasha_codec_reg_init_val_1_0[i].mask, tasha_codec_reg_init_val_1_0[i].val); } else if (TASHA_IS_2_0(wcd9xxx)) { for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_2_0); i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, tasha_codec_reg_init_val_2_0[i].reg, tasha_codec_reg_init_val_2_0[i].mask, tasha_codec_reg_init_val_2_0[i].val); @@ -12595,10 +12948,10 @@ static void tasha_update_reg_defaults(struct tasha_priv *tasha) } -static void tasha_slim_interface_init_reg(struct snd_soc_codec *codec) +static void tasha_slim_interface_init_reg(struct snd_soc_component *component) { int i; - struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *priv = snd_soc_component_get_drvdata(component); for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++) wcd9xxx_interface_reg_write(priv->wcd9xxx, @@ -12707,7 +13060,7 @@ static irqreturn_t tasha_slimbus_irq(int irq, void *data) static int tasha_setup_irqs(struct tasha_priv *tasha) { int ret = 0; - struct snd_soc_codec *codec = tasha->codec; + struct snd_soc_component *component = tasha->component; struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; @@ -12718,14 +13071,14 @@ static int tasha_setup_irqs(struct tasha_priv *tasha) pr_err("%s: Failed to request irq %d\n", __func__, WCD9XXX_IRQ_SLIMBUS); else - tasha_slim_interface_init_reg(codec); + tasha_slim_interface_init_reg(component); return ret; } -static void tasha_init_slim_slave_cfg(struct snd_soc_codec *codec) +static void tasha_init_slim_slave_cfg(struct snd_soc_component *component) { - struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *priv = snd_soc_component_get_drvdata(component); struct afe_param_cdc_slimbus_slave_cfg *cfg; struct wcd9xxx *wcd9xxx = priv->wcd9xxx; uint64_t eaddr = 0; @@ -12740,7 +13093,7 @@ static void tasha_init_slim_slave_cfg(struct snd_soc_codec *codec) cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF; cfg->device_enum_addr_msw = eaddr >> 32; - dev_dbg(codec->dev, "%s: slimbus logical address 0x%llx\n", + dev_dbg(component->dev, "%s: slimbus logical address 0x%llx\n", __func__, eaddr); } @@ -12756,7 +13109,7 @@ static void tasha_cleanup_irqs(struct tasha_priv *tasha) static int tasha_handle_pdata(struct tasha_priv *tasha, struct wcd9xxx_pdata *pdata) { - struct snd_soc_codec *codec = tasha->codec; + struct snd_soc_component *component = tasha->component; u8 dmic_ctl_val, mad_dmic_ctl_val; u8 anc_ctl_value; u32 def_dmic_rate, dmic_clk_drv; @@ -12764,7 +13117,7 @@ static int tasha_handle_pdata(struct tasha_priv *tasha, int rc = 0; if (!pdata) { - dev_err(codec->dev, "%s: NULL pdata\n", __func__); + dev_err(component->dev, "%s: NULL pdata\n", __func__); return -ENODEV; } @@ -12778,10 +13131,14 @@ static int tasha_handle_pdata(struct tasha_priv *tasha, rc = -EINVAL; goto done; } - snd_soc_update_bits(codec, WCD9335_ANA_MICB1, 0x3F, vout_ctl_1); - snd_soc_update_bits(codec, WCD9335_ANA_MICB2, 0x3F, vout_ctl_2); - snd_soc_update_bits(codec, WCD9335_ANA_MICB3, 0x3F, vout_ctl_3); - snd_soc_update_bits(codec, WCD9335_ANA_MICB4, 0x3F, vout_ctl_4); + snd_soc_component_update_bits(component, WCD9335_ANA_MICB1, + 0x3F, vout_ctl_1); + snd_soc_component_update_bits(component, WCD9335_ANA_MICB2, + 0x3F, vout_ctl_2); + snd_soc_component_update_bits(component, WCD9335_ANA_MICB3, + 0x3F, vout_ctl_3); + snd_soc_component_update_bits(component, WCD9335_ANA_MICB4, + 0x3F, vout_ctl_4); /* Set the DMIC sample rate */ switch (pdata->mclk_rate) { @@ -12793,7 +13150,7 @@ static int tasha_handle_pdata(struct tasha_priv *tasha, break; default: /* should never happen */ - dev_err(codec->dev, "%s: Invalid mclk_rate %d\n", + dev_err(component->dev, "%s: Invalid mclk_rate %d\n", __func__, pdata->mclk_rate); rc = -EINVAL; goto done; @@ -12801,13 +13158,13 @@ static int tasha_handle_pdata(struct tasha_priv *tasha, if (pdata->dmic_sample_rate == WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) { - dev_info(codec->dev, "%s: dmic_rate invalid default = %d\n", + dev_info(component->dev, "%s: dmic_rate invalid default = %d\n", __func__, def_dmic_rate); pdata->dmic_sample_rate = def_dmic_rate; } if (pdata->mad_dmic_sample_rate == WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) { - dev_info(codec->dev, "%s: mad_dmic_rate invalid default = %d\n", + dev_info(component->dev, "%s: mad_dmic_rate invalid default = %d\n", __func__, def_dmic_rate); /* * use dmic_sample_rate as the default for MAD @@ -12817,7 +13174,7 @@ static int tasha_handle_pdata(struct tasha_priv *tasha, } if (pdata->ecpp_dmic_sample_rate == WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) { - dev_info(codec->dev, + dev_info(component->dev, "%s: ecpp_dmic_rate invalid default = %d\n", __func__, def_dmic_rate); /* @@ -12830,7 +13187,7 @@ static int tasha_handle_pdata(struct tasha_priv *tasha, if (pdata->dmic_clk_drv == WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED) { pdata->dmic_clk_drv = WCD9335_DMIC_CLK_DRIVE_DEFAULT; - dev_info(codec->dev, + dev_info(component->dev, "%s: dmic_clk_strength invalid, default = %d\n", __func__, pdata->dmic_clk_drv); } @@ -12849,14 +13206,14 @@ static int tasha_handle_pdata(struct tasha_priv *tasha, dmic_clk_drv = 3; break; default: - dev_err(codec->dev, + dev_err(component->dev, "%s: invalid dmic_clk_drv %d, using default\n", __func__, pdata->dmic_clk_drv); dmic_clk_drv = 0; break; } - snd_soc_update_bits(codec, WCD9335_TEST_DEBUG_PAD_DRVCTL, + snd_soc_component_update_bits(component, WCD9335_TEST_DEBUG_PAD_DRVCTL, 0x0C, dmic_clk_drv << 2); /* @@ -12864,17 +13221,17 @@ static int tasha_handle_pdata(struct tasha_priv *tasha, * whereas, the anc/txfe dmic rates to dmic_sample_rate * since the anc/txfe are independent of mad block. */ - mad_dmic_ctl_val = tasha_get_dmic_clk_val(tasha->codec, + mad_dmic_ctl_val = tasha_get_dmic_clk_val(tasha->component, pdata->mclk_rate, pdata->mad_dmic_sample_rate); - snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC0_CTL, + snd_soc_component_update_bits(component, WCD9335_CPE_SS_DMIC0_CTL, 0x0E, mad_dmic_ctl_val << 1); - snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC1_CTL, + snd_soc_component_update_bits(component, WCD9335_CPE_SS_DMIC1_CTL, 0x0E, mad_dmic_ctl_val << 1); - snd_soc_update_bits(codec, WCD9335_CPE_SS_DMIC2_CTL, + snd_soc_component_update_bits(component, WCD9335_CPE_SS_DMIC2_CTL, 0x0E, mad_dmic_ctl_val << 1); - dmic_ctl_val = tasha_get_dmic_clk_val(tasha->codec, + dmic_ctl_val = tasha_get_dmic_clk_val(tasha->component, pdata->mclk_rate, pdata->dmic_sample_rate); @@ -12883,38 +13240,38 @@ static int tasha_handle_pdata(struct tasha_priv *tasha, else anc_ctl_value = WCD9335_ANC_DMIC_X2_HALF_RATE; - snd_soc_update_bits(codec, WCD9335_CDC_ANC0_MODE_2_CTL, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC0_MODE_2_CTL, 0x40, anc_ctl_value << 6); - snd_soc_update_bits(codec, WCD9335_CDC_ANC0_MODE_2_CTL, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC0_MODE_2_CTL, 0x20, anc_ctl_value << 5); - snd_soc_update_bits(codec, WCD9335_CDC_ANC1_MODE_2_CTL, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC1_MODE_2_CTL, 0x40, anc_ctl_value << 6); - snd_soc_update_bits(codec, WCD9335_CDC_ANC1_MODE_2_CTL, + snd_soc_component_update_bits(component, WCD9335_CDC_ANC1_MODE_2_CTL, 0x20, anc_ctl_value << 5); done: return rc; } static struct wcd_cpe_core *tasha_codec_get_cpe_core( - struct snd_soc_codec *codec) + struct snd_soc_component *component) { - struct tasha_priv *priv = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *priv = snd_soc_component_get_drvdata(component); return priv->cpe_core; } static int tasha_codec_cpe_fll_update_divider( - struct snd_soc_codec *codec, u32 cpe_fll_rate) + struct snd_soc_component *component, u32 cpe_fll_rate) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); u32 div_val = 0, l_val = 0; u32 computed_cpe_fll; if (cpe_fll_rate != CPE_FLL_CLK_75MHZ && cpe_fll_rate != CPE_FLL_CLK_150MHZ) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Invalid CPE fll rate request %u\n", __func__, cpe_fll_rate); return -EINVAL; @@ -12922,18 +13279,20 @@ static int tasha_codec_cpe_fll_update_divider( if (wcd9xxx->mclk_rate == TASHA_MCLK_CLK_12P288MHZ) { /* update divider to 10 and enable 5x divider */ - snd_soc_write(codec, WCD9335_CPE_FLL_USER_CTL_1, + snd_soc_component_write(component, WCD9335_CPE_FLL_USER_CTL_1, 0x55); div_val = 10; } else if (wcd9xxx->mclk_rate == TASHA_MCLK_CLK_9P6MHZ) { /* update divider to 8 and enable 2x divider */ - snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0, - 0x7C, 0x70); - snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_1, - 0xE0, 0x20); + snd_soc_component_update_bits(component, + WCD9335_CPE_FLL_USER_CTL_0, + 0x7C, 0x70); + snd_soc_component_update_bits(component, + WCD9335_CPE_FLL_USER_CTL_1, + 0xE0, 0x20); div_val = 8; } else { - dev_err(codec->dev, + dev_err(component->dev, "%s: Invalid MCLK rate %u\n", __func__, wcd9xxx->mclk_rate); return -EINVAL; @@ -12949,102 +13308,106 @@ static int tasha_codec_cpe_fll_update_divider( /* update L value LSB and MSB */ - snd_soc_write(codec, WCD9335_CPE_FLL_L_VAL_CTL_0, + snd_soc_component_write(component, WCD9335_CPE_FLL_L_VAL_CTL_0, (l_val & 0xFF)); - snd_soc_write(codec, WCD9335_CPE_FLL_L_VAL_CTL_1, + snd_soc_component_write(component, WCD9335_CPE_FLL_L_VAL_CTL_1, ((l_val >> 8) & 0xFF)); tasha->current_cpe_clk_freq = cpe_fll_rate; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: updated l_val to %u for cpe_clk %u and mclk %u\n", __func__, l_val, cpe_fll_rate, wcd9xxx->mclk_rate); return 0; } -static int __tasha_cdc_change_cpe_clk(struct snd_soc_codec *codec, +static int __tasha_cdc_change_cpe_clk(struct snd_soc_component *component, u32 clk_freq) { int ret = 0; - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); if (!tasha_cdc_is_svs_enabled(tasha)) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: SVS not enabled or tasha is not 2p0, return\n", __func__); return 0; } - dev_dbg(codec->dev, "%s: clk_freq = %u\n", __func__, clk_freq); + dev_dbg(component->dev, "%s: clk_freq = %u\n", __func__, clk_freq); if (clk_freq == CPE_FLL_CLK_75MHZ) { /* Change to SVS */ - snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE, - 0x08, 0x08); - if (tasha_codec_cpe_fll_update_divider(codec, clk_freq)) { + snd_soc_component_update_bits(component, + WCD9335_CPE_FLL_FLL_MODE, + 0x08, 0x08); + if (tasha_codec_cpe_fll_update_divider(component, clk_freq)) { ret = -EINVAL; goto done; } - snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE, - 0x10, 0x10); + snd_soc_component_update_bits(component, + WCD9335_CPE_FLL_FLL_MODE, + 0x10, 0x10); clear_bit(CPE_NOMINAL, &tasha->status_mask); tasha_codec_update_sido_voltage(tasha, sido_buck_svs_voltage); } else if (clk_freq == CPE_FLL_CLK_150MHZ) { /* change to nominal */ - snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE, - 0x08, 0x08); + snd_soc_component_update_bits(component, + WCD9335_CPE_FLL_FLL_MODE, + 0x08, 0x08); set_bit(CPE_NOMINAL, &tasha->status_mask); tasha_codec_update_sido_voltage(tasha, SIDO_VOLTAGE_NOMINAL_MV); - if (tasha_codec_cpe_fll_update_divider(codec, clk_freq)) { + if (tasha_codec_cpe_fll_update_divider(component, clk_freq)) { ret = -EINVAL; goto done; } - snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE, - 0x10, 0x10); + snd_soc_component_update_bits(component, + WCD9335_CPE_FLL_FLL_MODE, + 0x10, 0x10); } else { - dev_err(codec->dev, + dev_err(component->dev, "%s: Invalid clk_freq request %d for CPE FLL\n", __func__, clk_freq); ret = -EINVAL; } done: - snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE, - 0x10, 0x00); - snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE, - 0x08, 0x00); + snd_soc_component_update_bits(component, WCD9335_CPE_FLL_FLL_MODE, + 0x10, 0x00); + snd_soc_component_update_bits(component, WCD9335_CPE_FLL_FLL_MODE, + 0x08, 0x00); return ret; } -static int tasha_codec_cpe_fll_enable(struct snd_soc_codec *codec, +static int tasha_codec_cpe_fll_enable(struct snd_soc_component *component, bool enable) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); u8 clk_sel_reg_val = 0x00; - dev_dbg(codec->dev, "%s: enable = %s\n", + dev_dbg(component->dev, "%s: enable = %s\n", __func__, enable ? "true" : "false"); if (enable) { if (tasha_cdc_is_svs_enabled(tasha)) { /* FLL enable is always at SVS */ - if (__tasha_cdc_change_cpe_clk(codec, + if (__tasha_cdc_change_cpe_clk(component, CPE_FLL_CLK_75MHZ)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: clk change to %d failed\n", __func__, CPE_FLL_CLK_75MHZ); return -EINVAL; } } else { - if (tasha_codec_cpe_fll_update_divider(codec, + if (tasha_codec_cpe_fll_update_divider(component, CPE_FLL_CLK_75MHZ)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: clk change to %d failed\n", __func__, CPE_FLL_CLK_75MHZ); return -EINVAL; @@ -13052,53 +13415,61 @@ static int tasha_codec_cpe_fll_enable(struct snd_soc_codec *codec, } if (TASHA_IS_1_0(wcd9xxx)) { - tasha_cdc_mclk_enable(codec, true, false); + tasha_cdc_mclk_enable(component, true, false); clk_sel_reg_val = 0x02; } /* Setup CPE reference clk */ - snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP, - 0x02, clk_sel_reg_val); + snd_soc_component_update_bits(component, WCD9335_ANA_CLK_TOP, + 0x02, clk_sel_reg_val); /* enable CPE FLL reference clk */ - snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP, - 0x01, 0x01); + snd_soc_component_update_bits(component, WCD9335_ANA_CLK_TOP, + 0x01, 0x01); /* program the PLL */ - snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0, - 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD9335_CPE_FLL_USER_CTL_0, + 0x01, 0x01); /* TEST clk setting */ - snd_soc_update_bits(codec, WCD9335_CPE_FLL_TEST_CTL_0, - 0x80, 0x80); + snd_soc_component_update_bits(component, + WCD9335_CPE_FLL_TEST_CTL_0, + 0x80, 0x80); /* set FLL mode to HW controlled */ - snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE, - 0x60, 0x00); - snd_soc_write(codec, WCD9335_CPE_FLL_FLL_MODE, 0x80); + snd_soc_component_update_bits(component, + WCD9335_CPE_FLL_FLL_MODE, + 0x60, 0x00); + snd_soc_component_write(component, WCD9335_CPE_FLL_FLL_MODE, + 0x80); } else { /* disable CPE FLL reference clk */ - snd_soc_update_bits(codec, WCD9335_ANA_CLK_TOP, - 0x01, 0x00); + snd_soc_component_update_bits(component, WCD9335_ANA_CLK_TOP, + 0x01, 0x00); /* undo TEST clk setting */ - snd_soc_update_bits(codec, WCD9335_CPE_FLL_TEST_CTL_0, - 0x80, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CPE_FLL_TEST_CTL_0, + 0x80, 0x00); /* undo FLL mode to HW control */ - snd_soc_write(codec, WCD9335_CPE_FLL_FLL_MODE, 0x00); - snd_soc_update_bits(codec, WCD9335_CPE_FLL_FLL_MODE, - 0x60, 0x20); + snd_soc_component_write(component, + WCD9335_CPE_FLL_FLL_MODE, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CPE_FLL_FLL_MODE, + 0x60, 0x20); /* undo the PLL */ - snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0, - 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CPE_FLL_USER_CTL_0, + 0x01, 0x00); if (TASHA_IS_1_0(wcd9xxx)) - tasha_cdc_mclk_enable(codec, false, false); + tasha_cdc_mclk_enable(component, false, false); /* * FLL could get disabled while at nominal, * scale it back to SVS */ if (tasha_cdc_is_svs_enabled(tasha)) - __tasha_cdc_change_cpe_clk(codec, + __tasha_cdc_change_cpe_clk(component, CPE_FLL_CLK_75MHZ); } @@ -13109,20 +13480,20 @@ static int tasha_codec_cpe_fll_enable(struct snd_soc_codec *codec, static void tasha_cdc_query_cpe_clk_plan(void *data, struct cpe_svc_cfg_clk_plan *clk_freq) { - struct snd_soc_codec *codec = data; + struct snd_soc_component *component = data; struct tasha_priv *tasha; u32 cpe_clk_khz; - if (!codec) { - pr_err("%s: Invalid codec handle\n", + if (!component) { + pr_err("%s: Invalid component handle\n", __func__); return; } - tasha = snd_soc_codec_get_drvdata(codec); + tasha = snd_soc_component_get_drvdata(component); cpe_clk_khz = tasha->current_cpe_clk_freq / 1000; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: current_clk_freq = %u\n", __func__, tasha->current_cpe_clk_freq); @@ -13141,17 +13512,17 @@ static void tasha_cdc_query_cpe_clk_plan(void *data, static void tasha_cdc_change_cpe_clk(void *data, u32 clk_freq) { - struct snd_soc_codec *codec = data; + struct snd_soc_component *component = data; struct tasha_priv *tasha; u32 cpe_clk_khz, req_freq = 0; - if (!codec) { + if (!component) { pr_err("%s: Invalid codec handle\n", __func__); return; } - tasha = snd_soc_codec_get_drvdata(codec); + tasha = snd_soc_component_get_drvdata(component); cpe_clk_khz = tasha->current_cpe_clk_freq / 1000; if (tasha_cdc_is_svs_enabled(tasha)) { @@ -13161,34 +13532,34 @@ static void tasha_cdc_change_cpe_clk(void *data, req_freq = CPE_FLL_CLK_150MHZ; } - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: requested clk_freq = %u, current clk_freq = %u\n", __func__, clk_freq * 1000, tasha->current_cpe_clk_freq); if (tasha_cdc_is_svs_enabled(tasha)) { - if (__tasha_cdc_change_cpe_clk(codec, req_freq)) - dev_err(codec->dev, + if (__tasha_cdc_change_cpe_clk(component, req_freq)) + dev_err(component->dev, "%s: clock/voltage scaling failed\n", __func__); } } -static int tasha_codec_slim_reserve_bw(struct snd_soc_codec *codec, +static int tasha_codec_slim_reserve_bw(struct snd_soc_component *component, u32 bw_ops, bool commit) { struct wcd9xxx *wcd9xxx; - if (!codec) { + if (!component) { pr_err("%s: Invalid handle to codec\n", __func__); return -EINVAL; } - wcd9xxx = dev_get_drvdata(codec->dev->parent); + wcd9xxx = dev_get_drvdata(component->dev->parent); if (!wcd9xxx) { - dev_err(codec->dev, "%s: Invalid parent drv_data\n", + dev_err(component->dev, "%s: Invalid parent drv_data\n", __func__); return -EINVAL; } @@ -13196,11 +13567,11 @@ static int tasha_codec_slim_reserve_bw(struct snd_soc_codec *codec, return wcd9xxx_slim_reserve_bw(wcd9xxx, bw_ops, commit); } -static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec, +static int tasha_codec_vote_max_bw(struct snd_soc_component *component, bool vote) { u32 bw_ops; - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) return 0; @@ -13210,19 +13581,19 @@ static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec, tasha->ref_count++; if (tasha->ref_count == 1) { bw_ops = SLIM_BW_CLK_GEAR_9; - tasha_codec_slim_reserve_bw(codec, + tasha_codec_slim_reserve_bw(component, bw_ops, true); } } else if (!vote && tasha->ref_count > 0) { tasha->ref_count--; if (tasha->ref_count == 0) { bw_ops = SLIM_BW_UNVOTE; - tasha_codec_slim_reserve_bw(codec, + tasha_codec_slim_reserve_bw(component, bw_ops, true); } }; - dev_dbg(codec->dev, "%s Value of counter after vote or un-vote is %d\n", + dev_dbg(component->dev, "%s Value of counter after vote or un-vote is %d\n", __func__, tasha->ref_count); mutex_unlock(&tasha->sb_clk_gear_lock); @@ -13230,10 +13601,10 @@ static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec, return 0; } -static int tasha_cpe_err_irq_control(struct snd_soc_codec *codec, +static int tasha_cpe_err_irq_control(struct snd_soc_component *component, enum cpe_err_irq_cntl_type cntl_type, u8 *status) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); u8 irq_bits; if (TASHA_IS_2_0(tasha->wcd9xxx)) @@ -13246,24 +13617,25 @@ static int tasha_cpe_err_irq_control(struct snd_soc_codec *codec, switch (cntl_type) { case CPE_ERR_IRQ_MASK: - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CPE_SS_SS_ERROR_INT_MASK, irq_bits, irq_bits); break; case CPE_ERR_IRQ_UNMASK: - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9335_CPE_SS_SS_ERROR_INT_MASK, irq_bits, 0x00); break; case CPE_ERR_IRQ_CLEAR: - snd_soc_write(codec, WCD9335_CPE_SS_SS_ERROR_INT_CLEAR, - irq_bits); + snd_soc_component_write(component, + WCD9335_CPE_SS_SS_ERROR_INT_CLEAR, + irq_bits); break; case CPE_ERR_IRQ_STATUS: if (!status) return -EINVAL; - *status = snd_soc_read(codec, - WCD9335_CPE_SS_SS_ERROR_INT_STATUS); + *status = snd_soc_component_read32(component, + WCD9335_CPE_SS_SS_ERROR_INT_STATUS); break; } @@ -13286,14 +13658,14 @@ static struct cpe_svc_init_param cpe_svc_params = { .change_freq_plan_cb = tasha_cdc_change_cpe_clk, }; -static int tasha_cpe_initialize(struct snd_soc_codec *codec) +static int tasha_cpe_initialize(struct snd_soc_component *component) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); struct wcd_cpe_params cpe_params; memset(&cpe_params, 0, sizeof(struct wcd_cpe_params)); - cpe_params.codec = codec; + cpe_params.component = component; cpe_params.get_cpe_core = tasha_codec_get_cpe_core; cpe_params.cdc_cb = &cpe_cb; cpe_params.dbg_mode = cpe_debug_mode; @@ -13308,13 +13680,13 @@ static int tasha_cpe_initialize(struct snd_soc_codec *codec) cpe_params.cdc_irq_info.cpe_fatal_irqs = TASHA_CPE_FATAL_IRQS; - cpe_svc_params.context = codec; + cpe_svc_params.context = component; cpe_params.cpe_svc_params = &cpe_svc_params; - tasha->cpe_core = wcd_cpe_init("cpe_9335", codec, + tasha->cpe_core = wcd_cpe_init("cpe_9335", component, &cpe_params); if (IS_ERR_OR_NULL(tasha->cpe_core)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to enable CPE\n", __func__); return -EINVAL; @@ -13329,18 +13701,18 @@ static const struct wcd_resmgr_cb tasha_resmgr_cb = { static int tasha_device_down(struct wcd9xxx *wcd9xxx) { - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct tasha_priv *priv; int count; int i = 0; - codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); - priv = snd_soc_codec_get_drvdata(codec); + component = (struct snd_soc_component *)(wcd9xxx->ssr_priv); + priv = snd_soc_component_get_drvdata(component); wcd_cpe_ssr_event(priv->cpe_core, WCD_CPE_BUS_DOWN_EVENT); for (i = 0; i < priv->nr; i++) swrm_wcd_notify(priv->swr_ctrl_data[i].swr_pdev, SWR_DEVICE_DOWN, NULL); - snd_soc_card_change_online_state(codec->component.card, 0); + snd_soc_card_change_online_state(component->card, 0); for (count = 0; count < NUM_CODEC_DAIS; count++) priv->dai[count].bus_down_in_recovery = true; @@ -13353,13 +13725,13 @@ static int tasha_post_reset_cb(struct wcd9xxx *wcd9xxx) { int i, ret = 0; struct wcd9xxx *control; - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct tasha_priv *tasha; struct wcd9xxx_pdata *pdata; - codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); - tasha = snd_soc_codec_get_drvdata(codec); - control = dev_get_drvdata(codec->dev->parent); + component = (struct snd_soc_component *)(wcd9xxx->ssr_priv); + tasha = snd_soc_component_get_drvdata(component); + control = dev_get_drvdata(component->dev->parent); wcd9xxx_set_power_state(tasha->wcd9xxx, WCD_REGION_POWER_COLLAPSE_REMOVE, @@ -13371,11 +13743,11 @@ static int tasha_post_reset_cb(struct wcd9xxx *wcd9xxx) control->slim_slave->laddr; tasha_slimbus_slave_port_cfg.slave_dev_pgd_la = control->slim->laddr; - tasha_init_slim_slave_cfg(codec); + tasha_init_slim_slave_cfg(component); if (tasha->machine_codec_event_cb) - tasha->machine_codec_event_cb(codec, + tasha->machine_codec_event_cb(component, WCD9335_CODEC_EVENT_CODEC_UP); - snd_soc_card_change_online_state(codec->component.card, 1); + snd_soc_card_change_online_state(component->card, 1); /* Class-H Init*/ wcd_clsh_init(&tasha->clsh_d); @@ -13385,30 +13757,32 @@ static int tasha_post_reset_cb(struct wcd9xxx *wcd9xxx) tasha_update_reg_defaults(tasha); - tasha->codec = codec; + tasha->component = component; - dev_dbg(codec->dev, "%s: MCLK Rate = %x\n", + dev_dbg(component->dev, "%s: MCLK Rate = %x\n", __func__, control->mclk_rate); if (control->mclk_rate == TASHA_MCLK_CLK_12P288MHZ) - snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG, - 0x03, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CODEC_RPM_CLK_MCLK_CFG, + 0x03, 0x00); else if (control->mclk_rate == TASHA_MCLK_CLK_9P6MHZ) - snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG, - 0x03, 0x01); - tasha_codec_init_reg(codec); + snd_soc_component_update_bits(component, + WCD9335_CODEC_RPM_CLK_MCLK_CFG, + 0x03, 0x01); + tasha_codec_init_reg(component); wcd_resmgr_post_ssr_v2(tasha->resmgr); - tasha_enable_efuse_sensing(codec); + tasha_enable_efuse_sensing(component); - regcache_mark_dirty(codec->component.regmap); - regcache_sync(codec->component.regmap); + regcache_mark_dirty(component->regmap); + regcache_sync(component->regmap); - pdata = dev_get_platdata(codec->dev->parent); + pdata = dev_get_platdata(component->dev->parent); ret = tasha_handle_pdata(tasha, pdata); if (ret < 0) - dev_err(codec->dev, "%s: invalid pdata\n", __func__); + dev_err(component->dev, "%s: invalid pdata\n", __func__); /* Reset reference counter for voting for max bw */ tasha->ref_count = 0; @@ -13417,23 +13791,23 @@ static int tasha_post_reset_cb(struct wcd9xxx *wcd9xxx) tasha->mbhc_started = false; /* Initialize MBHC module */ - ret = wcd_mbhc_init(&tasha->mbhc, codec, &mbhc_cb, &intr_ids, + ret = wcd_mbhc_init(&tasha->mbhc, component, &mbhc_cb, &intr_ids, wcd_mbhc_registers, TASHA_ZDET_SUPPORTED); if (ret) - dev_err(codec->dev, "%s: mbhc initialization failed\n", + dev_err(component->dev, "%s: mbhc initialization failed\n", __func__); else - tasha_mbhc_hs_detect(codec, tasha->mbhc.mbhc_cfg); + tasha_mbhc_hs_detect(component, tasha->mbhc.mbhc_cfg); tasha_cleanup_irqs(tasha); ret = tasha_setup_irqs(tasha); if (ret) { - dev_err(codec->dev, "%s: tasha irq setup failed %d\n", + dev_err(component->dev, "%s: tasha irq setup failed %d\n", __func__, ret); goto err; } - tasha_set_spkr_mode(codec, tasha->spkr_mode); + tasha_set_spkr_mode(component, tasha->spkr_mode); wcd_cpe_ssr_event(tasha->cpe_core, WCD_CPE_BUS_UP_EVENT); err: @@ -13442,12 +13816,12 @@ static int tasha_post_reset_cb(struct wcd9xxx *wcd9xxx) } static struct regulator *tasha_codec_find_ondemand_regulator( - struct snd_soc_codec *codec, const char *name) + struct snd_soc_component *component, const char *name) { int i; - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; - struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent); for (i = 0; i < wcd9xxx->num_of_supplies; ++i) { if (pdata->regulator[i].ondemand && @@ -13461,32 +13835,35 @@ static struct regulator *tasha_codec_find_ondemand_regulator( return NULL; } -static int tasha_codec_probe(struct snd_soc_codec *codec) +static int tasha_codec_probe(struct snd_soc_component *component) { struct wcd9xxx *control; struct tasha_priv *tasha; struct wcd9xxx_pdata *pdata; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); int i, ret; void *ptr = NULL; struct regulator *supply; - control = dev_get_drvdata(codec->dev->parent); + control = dev_get_drvdata(component->dev->parent); + + snd_soc_component_init_regmap(component, control->regmap); - dev_info(codec->dev, "%s()\n", __func__); - tasha = snd_soc_codec_get_drvdata(codec); + dev_info(component->dev, "%s()\n", __func__); + tasha = snd_soc_component_get_drvdata(component); tasha->intf_type = wcd9xxx_get_intf_type(); if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) { control->dev_down = tasha_device_down; control->post_reset = tasha_post_reset_cb; - control->ssr_priv = (void *)codec; + control->ssr_priv = (void *)component; } /* Resource Manager post Init */ - ret = wcd_resmgr_post_init(tasha->resmgr, &tasha_resmgr_cb, codec); + ret = wcd_resmgr_post_init(tasha->resmgr, &tasha_resmgr_cb, component); if (ret) { - dev_err(codec->dev, "%s: wcd resmgr post init failed\n", + dev_err(component->dev, "%s: wcd resmgr post init failed\n", __func__); goto err; } @@ -13495,32 +13872,34 @@ static int tasha_codec_probe(struct snd_soc_codec *codec) /* Default HPH Mode to Class-H HiFi */ tasha->hph_mode = CLS_H_HIFI; - tasha->codec = codec; + tasha->component = component; for (i = 0; i < COMPANDER_MAX; i++) tasha->comp_enabled[i] = 0; tasha->spkr_gain_offset = RX_GAIN_OFFSET_0_DB; tasha->intf_type = wcd9xxx_get_intf_type(); - tasha_update_reg_reset_values(codec); + tasha_update_reg_reset_values(component); pr_debug("%s: MCLK Rate = %x\n", __func__, control->mclk_rate); if (control->mclk_rate == TASHA_MCLK_CLK_12P288MHZ) - snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG, - 0x03, 0x00); + snd_soc_component_update_bits(component, + WCD9335_CODEC_RPM_CLK_MCLK_CFG, + 0x03, 0x00); else if (control->mclk_rate == TASHA_MCLK_CLK_9P6MHZ) - snd_soc_update_bits(codec, WCD9335_CODEC_RPM_CLK_MCLK_CFG, - 0x03, 0x01); - tasha_codec_init_reg(codec); + snd_soc_component_update_bits(component, + WCD9335_CODEC_RPM_CLK_MCLK_CFG, + 0x03, 0x01); + tasha_codec_init_reg(component); - tasha_enable_efuse_sensing(codec); + tasha_enable_efuse_sensing(component); - pdata = dev_get_platdata(codec->dev->parent); + pdata = dev_get_platdata(component->dev->parent); ret = tasha_handle_pdata(tasha, pdata); if (ret < 0) { pr_err("%s: bad pdata\n", __func__); goto err; } - supply = tasha_codec_find_ondemand_regulator(codec, + supply = tasha_codec_find_ondemand_regulator(component, on_demand_supply_name[ON_DEMAND_MICBIAS]); if (supply) { tasha->on_demand_list[ON_DEMAND_MICBIAS].supply = supply; @@ -13528,7 +13907,7 @@ static int tasha_codec_probe(struct snd_soc_codec *codec) 0; } - tasha->fw_data = devm_kzalloc(codec->dev, + tasha->fw_data = devm_kzalloc(component->dev, sizeof(*(tasha->fw_data)), GFP_KERNEL); if (!tasha->fw_data) goto err; @@ -13538,9 +13917,9 @@ static int tasha_codec_probe(struct snd_soc_codec *codec) set_bit(WCD9XXX_VBAT_CAL, tasha->fw_data->cal_bit); ret = wcd_cal_create_hwdep(tasha->fw_data, - WCD9XXX_CODEC_HWDEP_NODE, codec); + WCD9XXX_CODEC_HWDEP_NODE, component); if (ret < 0) { - dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret); + dev_err(component->dev, "%s hwdep failed %d\n", __func__, ret); goto err_hwdep; } @@ -13550,14 +13929,14 @@ static int tasha_codec_probe(struct snd_soc_codec *codec) WCD9335_MBHC_FSM_STATUS; wcd_mbhc_registers[WCD_MBHC_FSM_STATUS].mask = 0x01; } - ret = wcd_mbhc_init(&tasha->mbhc, codec, &mbhc_cb, &intr_ids, + ret = wcd_mbhc_init(&tasha->mbhc, component, &mbhc_cb, &intr_ids, wcd_mbhc_registers, TASHA_ZDET_SUPPORTED); if (ret) { pr_err("%s: mbhc initialization failed\n", __func__); goto err_hwdep; } - ptr = devm_kzalloc(codec->dev, (sizeof(tasha_rx_chs) + + ptr = devm_kzalloc(component->dev, (sizeof(tasha_rx_chs) + sizeof(tasha_tx_chs)), GFP_KERNEL); if (!ptr) { ret = -ENOMEM; @@ -13584,19 +13963,19 @@ static int tasha_codec_probe(struct snd_soc_codec *codec) control->slim->laddr; tasha_slimbus_slave_port_cfg.slave_port_mapping[0] = TASHA_TX13; - tasha_init_slim_slave_cfg(codec); + tasha_init_slim_slave_cfg(component); } - snd_soc_add_codec_controls(codec, impedance_detect_controls, + snd_soc_add_component_controls(component, impedance_detect_controls, ARRAY_SIZE(impedance_detect_controls)); - snd_soc_add_codec_controls(codec, hph_type_detect_controls, + snd_soc_add_component_controls(component, hph_type_detect_controls, ARRAY_SIZE(hph_type_detect_controls)); - snd_soc_add_codec_controls(codec, + snd_soc_add_component_controls(component, tasha_analog_gain_controls, ARRAY_SIZE(tasha_analog_gain_controls)); if (tasha->is_wsa_attach) - snd_soc_add_codec_controls(codec, + snd_soc_add_component_controls(component, tasha_spkr_wsa_controls, ARRAY_SIZE(tasha_spkr_wsa_controls)); control->num_rx_port = TASHA_RX_MAX; @@ -13629,9 +14008,9 @@ static int tasha_codec_probe(struct snd_soc_codec *codec) goto err_pdata; } - ret = tasha_cpe_initialize(codec); + ret = tasha_cpe_initialize(component); if (ret) { - dev_err(codec->dev, + dev_err(component->dev, "%s: cpe initialization failed, err = %d\n", __func__, ret); /* Do not fail probe if CPE failed */ @@ -13674,22 +14053,22 @@ static int tasha_codec_probe(struct snd_soc_codec *codec) return ret; err_pdata: - devm_kfree(codec->dev, ptr); + devm_kfree(component->dev, ptr); control->rx_chs = NULL; control->tx_chs = NULL; err_hwdep: - devm_kfree(codec->dev, tasha->fw_data); + devm_kfree(component->dev, tasha->fw_data); tasha->fw_data = NULL; err: return ret; } -static int tasha_codec_remove(struct snd_soc_codec *codec) +static void tasha_codec_remove(struct snd_soc_component *component) { - struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); + struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); struct wcd9xxx *control; - control = dev_get_drvdata(codec->dev->parent); + control = dev_get_drvdata(component->dev->parent); control->num_rx_port = 0; control->num_tx_port = 0; control->rx_chs = NULL; @@ -13700,28 +14079,19 @@ static int tasha_codec_remove(struct snd_soc_codec *codec) wcd_mbhc_deinit(&tasha->mbhc); /* Cleanup resmgr */ - return 0; -} - -static struct regmap *tasha_get_regmap(struct device *dev) -{ - struct wcd9xxx *control = dev_get_drvdata(dev->parent); - - return control->regmap; + return; } -static struct snd_soc_codec_driver soc_codec_dev_tasha = { +static const struct snd_soc_component_driver soc_codec_dev_tasha = { + .name = DRV_NAME, .probe = tasha_codec_probe, .remove = tasha_codec_remove, - .get_regmap = tasha_get_regmap, - .component_driver = { - .controls = tasha_snd_controls, - .num_controls = ARRAY_SIZE(tasha_snd_controls), - .dapm_widgets = tasha_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(tasha_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), - }, + .controls = tasha_snd_controls, + .num_controls = ARRAY_SIZE(tasha_snd_controls), + .dapm_widgets = tasha_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tasha_dapm_widgets), + .dapm_routes = audio_map, + .num_dapm_routes = ARRAY_SIZE(audio_map), }; #ifdef CONFIG_PM @@ -14115,7 +14485,7 @@ static void tasha_add_child_devices(struct work_struct *work) /* * tasha_codec_ver: to get tasha codec version - * @codec: handle to snd_soc_codec * + * @codec: handle to snd_soc_component * * return enum codec_variant - version */ enum codec_variant tasha_codec_ver(void) @@ -14265,12 +14635,14 @@ static int tasha_probe(struct platform_device *pdev) tasha->wcd_native_clk = wcd_native_clk; if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS) - ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tasha, - tasha_dai, ARRAY_SIZE(tasha_dai)); + ret = snd_soc_register_component(&pdev->dev, + &soc_codec_dev_tasha, + tasha_dai, ARRAY_SIZE(tasha_dai)); else if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C) - ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tasha, - tasha_i2s_dai, - ARRAY_SIZE(tasha_i2s_dai)); + ret = snd_soc_register_component(&pdev->dev, + &soc_codec_dev_tasha, + tasha_i2s_dai, + ARRAY_SIZE(tasha_i2s_dai)); else ret = -EINVAL; if (ret) { @@ -14320,7 +14692,7 @@ static int tasha_remove(struct platform_device *pdev) clk_put(tasha->wcd_native_clk); mutex_destroy(&tasha->mclk_lock); mutex_destroy(&tasha->sb_clk_gear_lock); - snd_soc_unregister_codec(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); devm_kfree(&pdev->dev, tasha); return 0; } diff --git a/asoc/codecs/wcd9335.h b/asoc/codecs/wcd9335.h index 105fc2eca5e1..203c6de0aaba 100644 --- a/asoc/codecs/wcd9335.h +++ b/asoc/codecs/wcd9335.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #ifndef WCD9335_H #define WCD9335_H @@ -130,95 +130,102 @@ enum { }; #if IS_ENABLED(CONFIG_SND_SOC_WCD9335) -extern void *tasha_get_afe_config(struct snd_soc_codec *codec, +extern void *tasha_get_afe_config(struct snd_soc_component *component, enum afe_config_type config_type); -extern int tasha_cdc_mclk_enable(struct snd_soc_codec *codec, int enable, - bool dapm); -extern int tasha_cdc_mclk_tx_enable(struct snd_soc_codec *codec, int enable, - bool dapm); -extern int tasha_enable_efuse_sensing(struct snd_soc_codec *codec); -extern int tasha_mbhc_hs_detect(struct snd_soc_codec *codec, +extern int tasha_cdc_mclk_enable(struct snd_soc_component *component, + int enable, bool dapm); +extern int tasha_cdc_mclk_tx_enable(struct snd_soc_component *component, + int enable, bool dapm); +extern int tasha_enable_efuse_sensing(struct snd_soc_component *component); +extern int tasha_mbhc_hs_detect(struct snd_soc_component *component, struct wcd_mbhc_config *mbhc_cfg); -extern void tasha_mbhc_hs_detect_exit(struct snd_soc_codec *codec); +extern void tasha_mbhc_hs_detect_exit(struct snd_soc_component *component); extern void tasha_mbhc_zdet_gpio_ctrl( - int (*zdet_gpio_cb)(struct snd_soc_codec *codec, bool high), - struct snd_soc_codec *codec); + int (*zdet_gpio_cb)(struct snd_soc_component *component, + bool high), struct snd_soc_component *component); extern int tasha_codec_info_create_codec_entry( struct snd_info_entry *codec_root, - struct snd_soc_codec *codec); + struct snd_soc_component *component); extern void tasha_event_register( - int (*machine_event_cb)(struct snd_soc_codec *codec, + int (*machine_event_cb)(struct snd_soc_component *component, enum wcd9335_codec_event), - struct snd_soc_codec *codec); -extern int tasha_codec_enable_standalone_micbias(struct snd_soc_codec *codec, - int micb_num, - bool enable); -extern int tasha_set_spkr_mode(struct snd_soc_codec *codec, int mode); -extern int tasha_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset); + struct snd_soc_component *component); +extern int tasha_codec_enable_standalone_micbias( + struct snd_soc_component *component, + int micb_num, + bool enable); +extern int tasha_set_spkr_mode(struct snd_soc_component *component, int mode); +extern int tasha_set_spkr_gain_offset(struct snd_soc_component *component, + int offset); extern enum codec_variant tasha_codec_ver(void); #else /* CONFIG_SND_SOC_WCD9335 */ -static inline void *tasha_get_afe_config(struct snd_soc_codec *codec, +static inline void *tasha_get_afe_config(struct snd_soc_component *component, enum afe_config_type config_type) { return NULL; } -static inline int tasha_cdc_mclk_enable(struct snd_soc_codec *codec, +static inline int tasha_cdc_mclk_enable(struct snd_soc_component *component, int enable, bool dapm) { return 0; } -static inline int tasha_cdc_mclk_tx_enable(struct snd_soc_codec *codec, +static inline int tasha_cdc_mclk_tx_enable(struct snd_soc_component *component, int enable, bool dapm) { return 0; } -static inline int tasha_enable_efuse_sensing(struct snd_soc_codec *codec) +static inline int tasha_enable_efuse_sensing( + struct snd_soc_component *component) { return 0; } -static inline int tasha_mbhc_hs_detect(struct snd_soc_codec *codec, +static inline int tasha_mbhc_hs_detect(struct snd_soc_component *component, struct wcd_mbhc_config *mbhc_cfg) { return 0; } -static inline void tasha_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +static inline void tasha_mbhc_hs_detect_exit( + struct snd_soc_component *component) { } static inline void tasha_mbhc_zdet_gpio_ctrl( - int (*zdet_gpio_cb)(struct snd_soc_codec *codec, bool high), - struct snd_soc_codec *codec) + int (*zdet_gpio_cb)(struct snd_soc_component *component, + bool high), + struct snd_soc_component *component) { } static inline int tasha_codec_info_create_codec_entry( struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { return 0; } static inline void tasha_event_register( - int (*machine_event_cb)(struct snd_soc_codec *codec, + int (*machine_event_cb)(struct snd_soc_component *component, enum wcd9335_codec_event), - struct snd_soc_codec *codec) + struct snd_soc_component *component) { } static inline int tasha_codec_enable_standalone_micbias( - struct snd_soc_codec *codec, + struct snd_soc_component *component, int micb_num, bool enable) { return 0; } -static inline int tasha_set_spkr_mode(struct snd_soc_codec *codec, int mode) +static inline int tasha_set_spkr_mode(struct snd_soc_component *component, + int mode) { return 0; } -static inline int tasha_set_spkr_gain_offset(struct snd_soc_codec *codec, - int offset) +static inline int tasha_set_spkr_gain_offset( + struct snd_soc_component *component, + int offset) { return 0; } diff --git a/asoc/codecs/wcd934x/wcd934x-dsd.c b/asoc/codecs/wcd934x/wcd934x-dsd.c index 2069c8d14d4b..0a9c55696ce7 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsd.c +++ b/asoc/codecs/wcd934x/wcd934x-dsd.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ #include @@ -162,15 +162,15 @@ int tavil_dsd_set_out_select(struct tavil_dsd_config *dsd_conf, int interp_num) { unsigned int reg, val; - struct snd_soc_codec *codec; + struct snd_soc_component *component; - if (!dsd_conf || !dsd_conf->codec) + if (!dsd_conf || !dsd_conf->component) return -EINVAL; - codec = dsd_conf->codec; + component = dsd_conf->component; if (!is_valid_dsd_interpolator(interp_num)) { - dev_err(codec->dev, "%s: Invalid Interpolator: %d for DSD\n", + dev_err(component->dev, "%s: Invalid Interpolator: %d for DSD\n", __func__, interp_num); return -EINVAL; } @@ -196,7 +196,7 @@ int tavil_dsd_set_out_select(struct tavil_dsd_config *dsd_conf, return -EINVAL; } - snd_soc_update_bits(codec, reg, 0x02, val); + snd_soc_component_update_bits(component, reg, 0x02, val); return 0; } @@ -210,17 +210,21 @@ EXPORT_SYMBOL(tavil_dsd_set_out_select); */ void tavil_dsd_reset(struct tavil_dsd_config *dsd_conf) { - if (!dsd_conf || !dsd_conf->codec) + if (!dsd_conf || !dsd_conf->component) return; - snd_soc_update_bits(dsd_conf->codec, WCD934X_CDC_DSD0_PATH_CTL, - 0x02, 0x02); - snd_soc_update_bits(dsd_conf->codec, WCD934X_CDC_DSD0_PATH_CTL, - 0x01, 0x00); - snd_soc_update_bits(dsd_conf->codec, WCD934X_CDC_DSD1_PATH_CTL, - 0x02, 0x02); - snd_soc_update_bits(dsd_conf->codec, WCD934X_CDC_DSD1_PATH_CTL, - 0x01, 0x00); + snd_soc_component_update_bits(dsd_conf->component, + WCD934X_CDC_DSD0_PATH_CTL, + 0x02, 0x02); + snd_soc_component_update_bits(dsd_conf->component, + WCD934X_CDC_DSD0_PATH_CTL, + 0x01, 0x00); + snd_soc_component_update_bits(dsd_conf->component, + WCD934X_CDC_DSD1_PATH_CTL, + 0x02, 0x02); + snd_soc_component_update_bits(dsd_conf->component, + WCD934X_CDC_DSD1_PATH_CTL, + 0x01, 0x00); } EXPORT_SYMBOL(tavil_dsd_reset); @@ -240,17 +244,17 @@ void tavil_dsd_set_interp_rate(struct tavil_dsd_config *dsd_conf, u16 rx_port, u8 val0, val1; u8 dsd0_out_sel, dsd1_out_sel; u16 int_fs_reg, interp_num = 0; - struct snd_soc_codec *codec; + struct snd_soc_component *component; - if (!dsd_conf || !dsd_conf->codec) + if (!dsd_conf || !dsd_conf->component) return; - codec = dsd_conf->codec; + component = dsd_conf->component; dsd_inp_sel = DSD_INP_SEL_RX0 + rx_port - WCD934X_RX_PORT_START_NUMBER; - val0 = snd_soc_read(codec, WCD934X_CDC_DSD0_CFG0); - val1 = snd_soc_read(codec, WCD934X_CDC_DSD1_CFG0); + val0 = snd_soc_component_read32(component, WCD934X_CDC_DSD0_CFG0); + val1 = snd_soc_component_read32(component, WCD934X_CDC_DSD1_CFG0); dsd0_inp = (val0 & 0x3C) >> 2; dsd1_inp = (val1 & 0x3C) >> 2; dsd0_out_sel = (val0 & 0x02) >> 1; @@ -270,23 +274,24 @@ void tavil_dsd_set_interp_rate(struct tavil_dsd_config *dsd_conf, u16 rx_port, if (interp_num) { int_fs_reg = WCD934X_CDC_RX0_RX_PATH_CTL + 20 * interp_num; - if ((snd_soc_read(codec, int_fs_reg) & 0x0f) < 0x09) { - dev_dbg(codec->dev, "%s: Set Interp %d to sample_rate val 0x%x\n", + if ((snd_soc_component_read32(component, int_fs_reg) & 0x0f) < + 0x09) { + dev_dbg(component->dev, "%s: Set Interp %d to sample_rate val 0x%x\n", __func__, interp_num, sample_rate_val); - snd_soc_update_bits(codec, int_fs_reg, 0x0F, - sample_rate_val); + snd_soc_component_update_bits(component, int_fs_reg, + 0x0F, sample_rate_val); } } } EXPORT_SYMBOL(tavil_dsd_set_interp_rate); -static int tavil_set_dsd_mode(struct snd_soc_codec *codec, int dsd_num, +static int tavil_set_dsd_mode(struct snd_soc_component *component, int dsd_num, u8 *pcm_rate_val) { unsigned int dsd_out_sel_reg; u8 dsd_mode; u32 sample_rate; - struct tavil_dsd_config *dsd_conf = tavil_get_dsd_config(codec); + struct tavil_dsd_config *dsd_conf = tavil_get_dsd_config(component); if (!dsd_conf) return -EINVAL; @@ -307,17 +312,19 @@ static int tavil_set_dsd_mode(struct snd_soc_codec *codec, int dsd_num, *pcm_rate_val = 0xc; break; default: - dev_err(codec->dev, "%s: Invalid DSD rate: %d\n", + dev_err(component->dev, "%s: Invalid DSD rate: %d\n", __func__, sample_rate); return -EINVAL; } - snd_soc_update_bits(codec, dsd_out_sel_reg, 0x01, dsd_mode); + snd_soc_component_update_bits(component, dsd_out_sel_reg, + 0x01, dsd_mode); return 0; } -static void tavil_dsd_data_pull(struct snd_soc_codec *codec, int dsd_num, +static void tavil_dsd_data_pull(struct snd_soc_component *component, + int dsd_num, u8 pcm_rate_val, bool enable) { u8 clk_en, mute_en; @@ -332,37 +339,41 @@ static void tavil_dsd_data_pull(struct snd_soc_codec *codec, int dsd_num, } if (dsd_num & 0x01) { - snd_soc_update_bits(codec, WCD934X_CDC_RX7_RX_PATH_MIX_CTL, - 0x20, clk_en); - dsd_inp_sel = (snd_soc_read(codec, WCD934X_CDC_DSD0_CFG0) & + snd_soc_component_update_bits(component, + WCD934X_CDC_RX7_RX_PATH_MIX_CTL, + 0x20, clk_en); + dsd_inp_sel = (snd_soc_component_read32( + component, WCD934X_CDC_DSD0_CFG0) & 0x3C) >> 2; dsd_inp_sel = (enable) ? dsd_inp_sel : 0; if (dsd_inp_sel < 9) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG1, 0x0F, dsd_inp_sel); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_RX7_RX_PATH_MIX_CTL, 0x0F, pcm_rate_val); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_RX7_RX_PATH_MIX_CTL, 0x10, mute_en); } } if (dsd_num & 0x02) { - snd_soc_update_bits(codec, WCD934X_CDC_RX8_RX_PATH_MIX_CTL, - 0x20, clk_en); - dsd_inp_sel = (snd_soc_read(codec, WCD934X_CDC_DSD1_CFG0) & + snd_soc_component_update_bits(component, + WCD934X_CDC_RX8_RX_PATH_MIX_CTL, + 0x20, clk_en); + dsd_inp_sel = (snd_soc_component_read32( + component, WCD934X_CDC_DSD1_CFG0) & 0x3C) >> 2; dsd_inp_sel = (enable) ? dsd_inp_sel : 0; if (dsd_inp_sel < 9) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG1, 0x0F, dsd_inp_sel); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_RX8_RX_PATH_MIX_CTL, 0x0F, pcm_rate_val); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_RX8_RX_PATH_MIX_CTL, 0x10, mute_en); } @@ -371,85 +382,99 @@ static void tavil_dsd_data_pull(struct snd_soc_codec *codec, int dsd_num, static void tavil_dsd_update_volume(struct tavil_dsd_config *dsd_conf) { - snd_soc_update_bits(dsd_conf->codec, WCD934X_CDC_TOP_TOP_CFG0, - 0x01, 0x01); - snd_soc_update_bits(dsd_conf->codec, WCD934X_CDC_TOP_TOP_CFG0, - 0x01, 0x00); + snd_soc_component_update_bits(dsd_conf->component, + WCD934X_CDC_TOP_TOP_CFG0, + 0x01, 0x01); + snd_soc_component_update_bits(dsd_conf->component, + WCD934X_CDC_TOP_TOP_CFG0, + 0x01, 0x00); } static int tavil_enable_dsd(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_dsd_config *dsd_conf = tavil_get_dsd_config(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_dsd_config *dsd_conf = tavil_get_dsd_config(component); int rc, clk_users; int interp_idx; u8 pcm_rate_val; if (!dsd_conf) { - dev_err(codec->dev, "%s: null dsd_config pointer\n", __func__); + dev_err(component->dev, "%s: null dsd_config pointer\n", + __func__); return -EINVAL; } - dev_dbg(codec->dev, "%s: DSD%d, event: %d\n", __func__, + dev_dbg(component->dev, "%s: DSD%d, event: %d\n", __func__, w->shift, event); if (w->shift == DSD0) { /* Read out select */ - if (snd_soc_read(codec, WCD934X_CDC_DSD0_CFG0) & 0x02) + if (snd_soc_component_read32( + component, WCD934X_CDC_DSD0_CFG0) & 0x02) interp_idx = INTERP_LO1; else interp_idx = INTERP_HPHL; } else if (w->shift == DSD1) { /* Read out select */ - if (snd_soc_read(codec, WCD934X_CDC_DSD1_CFG0) & 0x02) + if (snd_soc_component_read32( + component, WCD934X_CDC_DSD1_CFG0) & 0x02) interp_idx = INTERP_LO2; else interp_idx = INTERP_HPHR; } else { - dev_err(codec->dev, "%s: Unsupported DSD:%d\n", + dev_err(component->dev, "%s: Unsupported DSD:%d\n", __func__, w->shift); return -EINVAL; } switch (event) { case SND_SOC_DAPM_PRE_PMU: - clk_users = tavil_codec_enable_interp_clk(codec, event, + clk_users = tavil_codec_enable_interp_clk(component, event, interp_idx); - rc = tavil_set_dsd_mode(codec, w->shift, &pcm_rate_val); + rc = tavil_set_dsd_mode(component, w->shift, &pcm_rate_val); if (rc) return rc; - tavil_dsd_data_pull(codec, (1 << w->shift), pcm_rate_val, + tavil_dsd_data_pull(component, (1 << w->shift), pcm_rate_val, true); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_CLK_RST_CTRL_DSD_CONTROL, 0x01, 0x01); if (w->shift == DSD0) { - snd_soc_update_bits(codec, WCD934X_CDC_DSD0_PATH_CTL, - 0x02, 0x02); - snd_soc_update_bits(codec, WCD934X_CDC_DSD0_PATH_CTL, - 0x02, 0x00); - snd_soc_update_bits(codec, WCD934X_CDC_DSD0_PATH_CTL, - 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD0_PATH_CTL, + 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD0_PATH_CTL, + 0x02, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD0_PATH_CTL, + 0x01, 0x01); /* Apply Gain */ - snd_soc_write(codec, WCD934X_CDC_DSD0_CFG1, - dsd_conf->volume[DSD0]); + snd_soc_component_write(component, + WCD934X_CDC_DSD0_CFG1, + dsd_conf->volume[DSD0]); if (dsd_conf->version == TAVIL_VERSION_1_1) tavil_dsd_update_volume(dsd_conf); } else if (w->shift == DSD1) { - snd_soc_update_bits(codec, WCD934X_CDC_DSD1_PATH_CTL, - 0x02, 0x02); - snd_soc_update_bits(codec, WCD934X_CDC_DSD1_PATH_CTL, - 0x02, 0x00); - snd_soc_update_bits(codec, WCD934X_CDC_DSD1_PATH_CTL, - 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD1_PATH_CTL, + 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD1_PATH_CTL, + 0x02, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD1_PATH_CTL, + 0x01, 0x01); /* Apply Gain */ - snd_soc_write(codec, WCD934X_CDC_DSD1_CFG1, - dsd_conf->volume[DSD1]); + snd_soc_component_write(component, + WCD934X_CDC_DSD1_CFG1, + dsd_conf->volume[DSD1]); if (dsd_conf->version == TAVIL_VERSION_1_1) tavil_dsd_update_volume(dsd_conf); } @@ -457,14 +482,15 @@ static int tavil_enable_dsd(struct snd_soc_dapm_widget *w, usleep_range(10000, 10100); if (clk_users > 1) { - snd_soc_update_bits(codec, WCD934X_ANA_RX_SUPPLIES, - 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD934X_ANA_RX_SUPPLIES, + 0x02, 0x02); if (w->shift == DSD0) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_DSD0_CFG2, 0x04, 0x00); if (w->shift == DSD1) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_DSD1_CFG2, 0x04, 0x00); @@ -472,25 +498,31 @@ static int tavil_enable_dsd(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: if (w->shift == DSD0) { - snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, - 0x04, 0x04); - snd_soc_update_bits(codec, WCD934X_CDC_DSD0_PATH_CTL, - 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD0_CFG2, + 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD0_PATH_CTL, + 0x01, 0x00); } else if (w->shift == DSD1) { - snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, - 0x04, 0x04); - snd_soc_update_bits(codec, WCD934X_CDC_DSD1_PATH_CTL, - 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD1_CFG2, + 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD1_PATH_CTL, + 0x01, 0x00); } - tavil_codec_enable_interp_clk(codec, event, interp_idx); + tavil_codec_enable_interp_clk(component, event, interp_idx); - if (!(snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01) && - !(snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) { - snd_soc_update_bits(codec, + if (!(snd_soc_component_read32( + component, WCD934X_CDC_DSD0_PATH_CTL) & 0x01) && + !(snd_soc_component_read32( + component, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) { + snd_soc_component_update_bits(component, WCD934X_CDC_CLK_RST_CTRL_DSD_CONTROL, 0x01, 0x00); - tavil_dsd_data_pull(codec, 0x03, 0x04, false); + tavil_dsd_data_pull(component, 0x03, 0x04, false); tavil_dsd_reset(dsd_conf); } break; @@ -513,8 +545,9 @@ static int tavil_dsd_vol_info(struct snd_kcontrol *kcontrol, static int tavil_dsd_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_dsd_config *dsd_conf = tavil_get_dsd_config(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_dsd_config *dsd_conf = tavil_get_dsd_config(component); int nv[DSD_MAX], cv[DSD_MAX]; int step_size, nv1; int i, dsd_idx; @@ -537,7 +570,7 @@ static int tavil_dsd_vol_put(struct snd_kcontrol *kcontrol, if (cv[dsd_idx] == nv[dsd_idx]) continue; - dev_dbg(codec->dev, "%s: DSD%d cur.vol: %d, new vol: %d\n", + dev_dbg(component->dev, "%s: DSD%d cur.vol: %d, new vol: %d\n", __func__, dsd_idx, cv[dsd_idx], nv[dsd_idx]); step_size = (nv[dsd_idx] - cv[dsd_idx]) / @@ -547,7 +580,7 @@ static int tavil_dsd_vol_put(struct snd_kcontrol *kcontrol, for (i = 0; i < DSD_VOLUME_STEPS; i++) { nv1 += step_size; - snd_soc_write(codec, + snd_soc_component_write(component, WCD934X_CDC_DSD0_CFG1 + 16 * dsd_idx, nv1); if (dsd_conf->version == TAVIL_VERSION_1_1) @@ -559,7 +592,7 @@ static int tavil_dsd_vol_put(struct snd_kcontrol *kcontrol, DSD_VOLUME_USLEEP_MARGIN_US)); } if (nv1 != nv[dsd_idx]) { - snd_soc_write(codec, + snd_soc_component_write(component, WCD934X_CDC_DSD0_CFG1 + 16 * dsd_idx, nv[dsd_idx]); @@ -579,8 +612,9 @@ static int tavil_dsd_vol_put(struct snd_kcontrol *kcontrol, static int tavil_dsd_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_dsd_config *dsd_conf = tavil_get_dsd_config(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_dsd_config *dsd_conf = tavil_get_dsd_config(component); if (dsd_conf) { ucontrol->value.integer.value[0] = dsd_conf->volume[DSD0]; @@ -618,45 +652,63 @@ static const struct snd_soc_dapm_widget tavil_dsd_widgets[] = { /** * tavil_dsd_post_ssr_init - DSD intialization after subsystem restart * - * @codec: pointer to snd_soc_codec + * @component: pointer to snd_soc_component * * Returns 0 on success or error on failure */ int tavil_dsd_post_ssr_init(struct tavil_dsd_config *dsd_conf) { - struct snd_soc_codec *codec; + struct snd_soc_component *component; - if (!dsd_conf || !dsd_conf->codec) + if (!dsd_conf || !dsd_conf->component) return -EINVAL; - codec = dsd_conf->codec; + component = dsd_conf->component; /* Disable DSD Interrupts */ - snd_soc_update_bits(codec, WCD934X_INTR_CODEC_MISC_MASK, 0x08, 0x08); + snd_soc_component_update_bits(component, + WCD934X_INTR_CODEC_MISC_MASK, + 0x08, 0x08); /* DSD registers init */ if (dsd_conf->version == TAVIL_VERSION_1_0) { - snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, 0x02, 0x00); - snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, 0x02, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD0_CFG2, + 0x02, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD1_CFG2, + 0x02, 0x00); } /* DSD0: Mute EN */ - snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD0_CFG2, + 0x04, 0x04); /* DSD1: Mute EN */ - snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, 0x04, 0x04); - snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG3, 0x10, - 0x10); - snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG3, 0x10, - 0x10); - snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG0, 0x0E, - 0x0A); - snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG0, 0x0E, - 0x0A); - snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG1, 0x07, - 0x04); - snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG1, 0x07, - 0x04); + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD1_CFG2, + 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG3, + 0x10, 0x10); + snd_soc_component_update_bits(component, + WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG3, + 0x10, 0x10); + snd_soc_component_update_bits(component, + WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG0, + 0x0E, 0x0A); + snd_soc_component_update_bits(component, + WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG0, + 0x0E, 0x0A); + snd_soc_component_update_bits(component, + WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG1, + 0x07, 0x04); + snd_soc_component_update_bits(component, + WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG1, + 0x07, 0x04); /* Enable DSD Interrupts */ - snd_soc_update_bits(codec, WCD934X_INTR_CODEC_MISC_MASK, 0x08, 0x00); + snd_soc_component_update_bits(component, + WCD934X_INTR_CODEC_MISC_MASK, + 0x08, 0x00); return 0; } @@ -665,60 +717,71 @@ EXPORT_SYMBOL(tavil_dsd_post_ssr_init); /** * tavil_dsd_init - DSD intialization * - * @codec: pointer to snd_soc_codec + * @component: pointer to snd_soc_component * * Returns pointer to tavil_dsd_config for success or NULL for failure */ -struct tavil_dsd_config *tavil_dsd_init(struct snd_soc_codec *codec) +struct tavil_dsd_config *tavil_dsd_init(struct snd_soc_component *component) { struct snd_soc_dapm_context *dapm; struct tavil_dsd_config *dsd_conf; u8 val; - if (!codec) + if (!component) return NULL; - dapm = snd_soc_codec_get_dapm(codec); + dapm = snd_soc_component_get_dapm(component); /* Read efuse register to check if DSD is supported */ - val = snd_soc_read(codec, WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT14); + val = snd_soc_component_read32(component, + WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT14); if (val & 0x80) { - dev_info(codec->dev, "%s: DSD unsupported for this codec version\n", + dev_info(component->dev, "%s: DSD unsupported for this codec version\n", __func__); return NULL; } - dsd_conf = devm_kzalloc(codec->dev, sizeof(struct tavil_dsd_config), + dsd_conf = devm_kzalloc(component->dev, sizeof(struct tavil_dsd_config), GFP_KERNEL); if (!dsd_conf) return NULL; - dsd_conf->codec = codec; + dsd_conf->component = component; /* Read version */ - dsd_conf->version = snd_soc_read(codec, + dsd_conf->version = snd_soc_component_read32(component, WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE0); /* DSD registers init */ if (dsd_conf->version == TAVIL_VERSION_1_0) { - snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, 0x02, 0x00); - snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, 0x02, 0x00); + snd_soc_component_update_bits(component, WCD934X_CDC_DSD0_CFG2, + 0x02, 0x00); + snd_soc_component_update_bits(component, WCD934X_CDC_DSD1_CFG2, + 0x02, 0x00); } /* DSD0: Mute EN */ - snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, 0x04, 0x04); + snd_soc_component_update_bits(component, WCD934X_CDC_DSD0_CFG2, + 0x04, 0x04); /* DSD1: Mute EN */ - snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, 0x04, 0x04); - snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG3, 0x10, - 0x10); - snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG3, 0x10, - 0x10); - snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG0, 0x0E, - 0x0A); - snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG0, 0x0E, - 0x0A); - snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG1, 0x07, - 0x04); - snd_soc_update_bits(codec, WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG1, 0x07, - 0x04); + snd_soc_component_update_bits(component, WCD934X_CDC_DSD1_CFG2, + 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG3, + 0x10, 0x10); + snd_soc_component_update_bits(component, + WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG3, + 0x10, 0x10); + snd_soc_component_update_bits(component, + WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG0, + 0x0E, 0x0A); + snd_soc_component_update_bits(component, + WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG0, + 0x0E, 0x0A); + snd_soc_component_update_bits(component, + WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG1, + 0x07, 0x04); + snd_soc_component_update_bits(component, + WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG1, + 0x07, 0x04); snd_soc_dapm_new_controls(dapm, tavil_dsd_widgets, ARRAY_SIZE(tavil_dsd_widgets)); @@ -730,11 +793,12 @@ struct tavil_dsd_config *tavil_dsd_init(struct snd_soc_codec *codec) dsd_conf->volume[DSD0] = DSD_VOLUME_MAX_0dB; dsd_conf->volume[DSD1] = DSD_VOLUME_MAX_0dB; - snd_soc_add_codec_controls(codec, tavil_dsd_vol_controls, + snd_soc_add_component_controls(component, tavil_dsd_vol_controls, ARRAY_SIZE(tavil_dsd_vol_controls)); /* Enable DSD Interrupts */ - snd_soc_update_bits(codec, WCD934X_INTR_CODEC_MISC_MASK, 0x08, 0x00); + snd_soc_component_update_bits(component, + WCD934X_INTR_CODEC_MISC_MASK, 0x08, 0x00); return dsd_conf; } @@ -747,18 +811,19 @@ EXPORT_SYMBOL(tavil_dsd_init); */ void tavil_dsd_deinit(struct tavil_dsd_config *dsd_conf) { - struct snd_soc_codec *codec; + struct snd_soc_component *component; if (!dsd_conf) return; - codec = dsd_conf->codec; + component = dsd_conf->component; mutex_destroy(&dsd_conf->vol_mutex); /* Disable DSD Interrupts */ - snd_soc_update_bits(codec, WCD934X_INTR_CODEC_MISC_MASK, 0x08, 0x08); + snd_soc_component_update_bits(component, + WCD934X_INTR_CODEC_MISC_MASK, 0x08, 0x08); - devm_kfree(codec->dev, dsd_conf); + devm_kfree(component->dev, dsd_conf); } EXPORT_SYMBOL(tavil_dsd_deinit); diff --git a/asoc/codecs/wcd934x/wcd934x-dsd.h b/asoc/codecs/wcd934x/wcd934x-dsd.h index cd6b57924fb3..e078c077f807 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsd.h +++ b/asoc/codecs/wcd934x/wcd934x-dsd.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ #ifndef __WCD934X_DSD_H__ @@ -27,7 +27,7 @@ enum { }; struct tavil_dsd_config { - struct snd_soc_codec *codec; + struct snd_soc_component *component; unsigned int dsd_interp_mixer[INTERP_MAX]; u32 base_sample_rate[DSD_MAX]; int volume[DSD_MAX]; @@ -45,7 +45,7 @@ int tavil_dsd_set_out_select(struct tavil_dsd_config *dsd_conf, void tavil_dsd_reset(struct tavil_dsd_config *dsd_conf); void tavil_dsd_set_interp_rate(struct tavil_dsd_config *dsd_conf, u16 rx_port, u32 sample_rate, u8 sample_rate_val); -struct tavil_dsd_config *tavil_dsd_init(struct snd_soc_codec *codec); +struct tavil_dsd_config *tavil_dsd_init(struct snd_soc_component *component); void tavil_dsd_deinit(struct tavil_dsd_config *dsd_config); int tavil_dsd_post_ssr_init(struct tavil_dsd_config *dsd_config); #else @@ -74,7 +74,7 @@ void tavil_dsd_set_interp_rate(struct tavil_dsd_config *dsd_conf, u16 rx_port, u32 sample_rate, u8 sample_rate_val) { } -struct tavil_dsd_config *tavil_dsd_init(struct snd_soc_codec *codec) +struct tavil_dsd_config *tavil_dsd_init(struct snd_soc_component *component) { return NULL; } diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c index a7a836faef14..e64b1588a82e 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c @@ -25,16 +25,16 @@ #define WCD_934X_RAMDUMP_SIZE ((1024 * 1024) - 128) #define WCD_MISCDEV_CMD_MAX_LEN 11 -#define WCD_CNTL_MUTEX_LOCK(codec, lock) \ +#define WCD_CNTL_MUTEX_LOCK(component, lock) \ { \ - dev_dbg(codec->dev, "%s: mutex_lock(%s)\n", \ + dev_dbg(component->dev, "%s: mutex_lock(%s)\n", \ __func__, __stringify_1(lock)); \ mutex_lock(&lock); \ } -#define WCD_CNTL_MUTEX_UNLOCK(codec, lock) \ +#define WCD_CNTL_MUTEX_UNLOCK(component, lock) \ { \ - dev_dbg(codec->dev, "%s: mutex_unlock(%s)\n", \ + dev_dbg(component->dev, "%s: mutex_unlock(%s)\n", \ __func__, __stringify_1(lock)); \ mutex_unlock(&lock); \ } @@ -109,7 +109,7 @@ static u16 wdsp_reg_for_debug_dump[] = { static void wcd_cntl_collect_debug_dumps(struct wcd_dsp_cntl *cntl, bool internal) { - struct snd_soc_codec *codec = cntl->codec; + struct snd_soc_component *component = cntl->component; struct wdsp_err_signal_arg arg; enum wdsp_signal signal; int i; @@ -120,21 +120,22 @@ static void wcd_cntl_collect_debug_dumps(struct wcd_dsp_cntl *cntl, return; /* Mask all error interrupts */ - snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, + snd_soc_component_write(component, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, 0xFF); - snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, + snd_soc_component_write(component, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, 0xFF); /* Collect important WDSP registers dump for debug use */ pr_err("%s: Dump the WDSP registers for debug use\n", __func__); for (i = 0; i < sizeof(wdsp_reg_for_debug_dump)/sizeof(u16); i++) { - val = snd_soc_read(codec, wdsp_reg_for_debug_dump[i]); + val = snd_soc_component_read32(component, + wdsp_reg_for_debug_dump[i]); pr_err("%s: reg = 0x%x, val = 0x%x\n", __func__, wdsp_reg_for_debug_dump[i], val); } /* Trigger NMI in WDSP to sync and update the memory */ - snd_soc_write(codec, WCD934X_CPE_SS_BACKUP_INT, 0x02); + snd_soc_component_write(component, WCD934X_CPE_SS_BACKUP_INT, 0x02); /* Collect WDSP ramdump for debug use */ if (cntl->m_dev && cntl->m_ops && cntl->m_ops->signal_handler) { @@ -146,9 +147,9 @@ static void wcd_cntl_collect_debug_dumps(struct wcd_dsp_cntl *cntl, } /* Unmask the fatal irqs */ - snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, + snd_soc_component_write(component, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, ~(cntl->irqs.fatal_irqs & 0xFF)); - snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, + snd_soc_component_write(component, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, ~((cntl->irqs.fatal_irqs >> 8) & 0xFF)); WCD_CNTL_CLR_ERR_IRQ_FLAG(cntl); @@ -177,7 +178,7 @@ static ssize_t wdsp_boot_store(struct wcd_dsp_cntl *cntl, ret = kstrtou32(buf, 10, &val); if (ret) { - dev_err(cntl->codec->dev, + dev_err(cntl->component->dev, "%s: Invalid entry, ret = %d\n", __func__, ret); return -EINVAL; } @@ -197,7 +198,7 @@ static ssize_t wdsp_boot_store(struct wcd_dsp_cntl *cntl, ret = -EINVAL; if (ret < 0) - dev_err(cntl->codec->dev, + dev_err(cntl->component->dev, "%s: failed to %s dsp\n", __func__, vote ? "enable" : "disable"); return count; @@ -247,17 +248,17 @@ static void wcd_cntl_change_online_state(struct wcd_dsp_cntl *cntl, struct wdsp_ssr_entry *ssr_entry = &cntl->ssr_entry; unsigned long ret; - WCD_CNTL_MUTEX_LOCK(cntl->codec, cntl->ssr_mutex); + WCD_CNTL_MUTEX_LOCK(cntl->component, cntl->ssr_mutex); ssr_entry->offline = !online; /* Make sure the write is complete */ wmb(); ret = xchg(&ssr_entry->offline_change, 1); wake_up_interruptible(&ssr_entry->offline_poll_wait); - dev_dbg(cntl->codec->dev, + dev_dbg(cntl->component->dev, "%s: requested %u, offline %u offline_change %u, ret = %ldn", __func__, online, ssr_entry->offline, ssr_entry->offline_change, ret); - WCD_CNTL_MUTEX_UNLOCK(cntl->codec, cntl->ssr_mutex); + WCD_CNTL_MUTEX_UNLOCK(cntl->component, cntl->ssr_mutex); } static ssize_t wdsp_ssr_entry_read(struct snd_info_entry *entry, @@ -280,16 +281,16 @@ static ssize_t wdsp_ssr_entry_read(struct snd_info_entry *entry, ssr_entry = &cntl->ssr_entry; - WCD_CNTL_MUTEX_LOCK(cntl->codec, cntl->ssr_mutex); + WCD_CNTL_MUTEX_LOCK(cntl->component, cntl->ssr_mutex); offline = ssr_entry->offline; /* Make sure the read is complete */ rmb(); - dev_dbg(cntl->codec->dev, "%s: offline = %s\n", __func__, + dev_dbg(cntl->component->dev, "%s: offline = %s\n", __func__, offline ? "true" : "false"); len = snprintf(buffer, sizeof(buffer), "%s\n", offline ? "OFFLINE" : "ONLINE"); ret = simple_read_from_buffer(buf, count, &pos, buffer, len); - WCD_CNTL_MUTEX_UNLOCK(cntl->codec, cntl->ssr_mutex); + WCD_CNTL_MUTEX_UNLOCK(cntl->component, cntl->ssr_mutex); return ret; } @@ -311,18 +312,18 @@ static unsigned int wdsp_ssr_entry_poll(struct snd_info_entry *entry, cntl = (struct wcd_dsp_cntl *) entry->private_data; ssr_entry = &cntl->ssr_entry; - dev_dbg(cntl->codec->dev, "%s: Poll wait, offline = %u\n", + dev_dbg(cntl->component->dev, "%s: Poll wait, offline = %u\n", __func__, ssr_entry->offline); poll_wait(file, &ssr_entry->offline_poll_wait, wait); - dev_dbg(cntl->codec->dev, "%s: Woken up Poll wait, offline = %u\n", + dev_dbg(cntl->component->dev, "%s: Woken up Poll wait, offline = %u\n", __func__, ssr_entry->offline); - WCD_CNTL_MUTEX_LOCK(cntl->codec, cntl->ssr_mutex); + WCD_CNTL_MUTEX_LOCK(cntl->component, cntl->ssr_mutex); if (xchg(&ssr_entry->offline_change, 0)) ret = POLLIN | POLLPRI | POLLRDNORM; - dev_dbg(cntl->codec->dev, "%s: ret (%d) from poll_wait\n", + dev_dbg(cntl->component->dev, "%s: ret (%d) from poll_wait\n", __func__, ret); - WCD_CNTL_MUTEX_UNLOCK(cntl->codec, cntl->ssr_mutex); + WCD_CNTL_MUTEX_UNLOCK(cntl->component, cntl->ssr_mutex); return ret; } @@ -334,25 +335,25 @@ static struct snd_info_entry_ops wdsp_ssr_entry_ops = { static int wcd_cntl_cpe_fll_calibrate(struct wcd_dsp_cntl *cntl) { - struct snd_soc_codec *codec = cntl->codec; + struct snd_soc_component *component = cntl->component; int ret = 0, retry = 0; u8 cal_lsb, cal_msb; u8 lock_det; /* Make sure clocks are gated */ - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPE_CTL, + snd_soc_component_update_bits(component, WCD934X_CPE_SS_CPE_CTL, 0x05, 0x00); /* Enable CPE FLL reference clock */ - snd_soc_update_bits(codec, WCD934X_CLK_SYS_MCLK2_PRG1, + snd_soc_component_update_bits(component, WCD934X_CLK_SYS_MCLK2_PRG1, 0x80, 0x80); - snd_soc_update_bits(codec, WCD934X_CPE_FLL_USER_CTL_5, + snd_soc_component_update_bits(component, WCD934X_CPE_FLL_USER_CTL_5, 0xF3, 0x13); - snd_soc_write(codec, WCD934X_CPE_FLL_L_VAL_CTL_0, 0x50); + snd_soc_component_write(component, WCD934X_CPE_FLL_L_VAL_CTL_0, 0x50); /* Disable CPAR reset and Enable CPAR clk */ - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, + snd_soc_component_update_bits(component, WCD934X_CPE_SS_CPAR_CTL, 0x02, 0x02); /* Write calibration l-value based on cdc clk rate */ @@ -363,56 +364,57 @@ static int wcd_cntl_cpe_fll_calibrate(struct wcd_dsp_cntl *cntl) cal_lsb = 0x56; cal_msb = 0x00; } - snd_soc_write(codec, WCD934X_CPE_FLL_USER_CTL_6, cal_lsb); - snd_soc_write(codec, WCD934X_CPE_FLL_USER_CTL_7, cal_msb); + snd_soc_component_write(component, WCD934X_CPE_FLL_USER_CTL_6, cal_lsb); + snd_soc_component_write(component, WCD934X_CPE_FLL_USER_CTL_7, cal_msb); /* FLL mode to follow power up sequence */ - snd_soc_update_bits(codec, WCD934X_CPE_FLL_FLL_MODE, + snd_soc_component_update_bits(component, WCD934X_CPE_FLL_FLL_MODE, 0x60, 0x00); /* HW controlled CPE FLL */ - snd_soc_update_bits(codec, WCD934X_CPE_FLL_FLL_MODE, + snd_soc_component_update_bits(component, WCD934X_CPE_FLL_FLL_MODE, 0x80, 0x80); /* Force on CPE FLL */ - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CFG, + snd_soc_component_update_bits(component, WCD934X_CPE_SS_CPAR_CFG, 0x04, 0x04); do { /* Time for FLL calibration to complete */ usleep_range(1000, 1100); - lock_det = snd_soc_read(codec, WCD934X_CPE_FLL_STATUS_3); + lock_det = snd_soc_component_read32( + component, WCD934X_CPE_FLL_STATUS_3); retry++; } while (!(lock_det & 0x01) && retry <= WCD_CPE_FLL_MAX_RETRIES); if (!(lock_det & 0x01)) { - dev_err(codec->dev, "%s: lock detect not set, 0x%02x\n", + dev_err(component->dev, "%s: lock detect not set, 0x%02x\n", __func__, lock_det); ret = -EIO; goto err_lock_det; } - snd_soc_update_bits(codec, WCD934X_CPE_FLL_FLL_MODE, + snd_soc_component_update_bits(component, WCD934X_CPE_FLL_FLL_MODE, 0x60, 0x20); - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CFG, + snd_soc_component_update_bits(component, WCD934X_CPE_SS_CPAR_CFG, 0x04, 0x00); return ret; err_lock_det: /* Undo the register settings */ - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CFG, + snd_soc_component_update_bits(component, WCD934X_CPE_SS_CPAR_CFG, 0x04, 0x00); - snd_soc_update_bits(codec, WCD934X_CPE_FLL_FLL_MODE, + snd_soc_component_update_bits(component, WCD934X_CPE_FLL_FLL_MODE, 0x80, 0x00); - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, + snd_soc_component_update_bits(component, WCD934X_CPE_SS_CPAR_CTL, 0x02, 0x00); return ret; } static void wcd_cntl_config_cpar(struct wcd_dsp_cntl *cntl) { - struct snd_soc_codec *codec = cntl->codec; + struct snd_soc_component *component = cntl->component; u8 nom_lo, nom_hi, svs2_lo, svs2_hi; /* Configure CPAR */ @@ -425,25 +427,30 @@ static void wcd_cntl_config_cpar(struct wcd_dsp_cntl *cntl) svs2_lo = 0x3e; } - snd_soc_write(codec, WCD934X_TEST_DEBUG_LVAL_NOM_LOW, nom_lo); - snd_soc_write(codec, WCD934X_TEST_DEBUG_LVAL_NOM_HIGH, nom_hi); - snd_soc_write(codec, WCD934X_TEST_DEBUG_LVAL_SVS_SVS2_LOW, svs2_lo); - snd_soc_write(codec, WCD934X_TEST_DEBUG_LVAL_SVS_SVS2_HIGH, svs2_hi); - - snd_soc_update_bits(codec, WCD934X_CPE_SS_PWR_CPEFLL_CTL, + snd_soc_component_write(component, WCD934X_TEST_DEBUG_LVAL_NOM_LOW, + nom_lo); + snd_soc_component_write(component, WCD934X_TEST_DEBUG_LVAL_NOM_HIGH, + nom_hi); + snd_soc_component_write(component, WCD934X_TEST_DEBUG_LVAL_SVS_SVS2_LOW, + svs2_lo); + snd_soc_component_write(component, + WCD934X_TEST_DEBUG_LVAL_SVS_SVS2_HIGH, + svs2_hi); + + snd_soc_component_update_bits(component, WCD934X_CPE_SS_PWR_CPEFLL_CTL, 0x03, 0x03); } static int wcd_cntl_cpe_fll_ctrl(struct wcd_dsp_cntl *cntl, bool enable) { - struct snd_soc_codec *codec = cntl->codec; + struct snd_soc_component *component = cntl->component; int ret = 0; if (enable) { ret = wcd_cntl_cpe_fll_calibrate(cntl); if (ret < 0) { - dev_err(codec->dev, + dev_err(component->dev, "%s: cpe_fll_cal failed, err = %d\n", __func__, ret); goto done; @@ -452,18 +459,21 @@ static int wcd_cntl_cpe_fll_ctrl(struct wcd_dsp_cntl *cntl, wcd_cntl_config_cpar(cntl); /* Enable AHB CLK and CPE CLK*/ - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPE_CTL, + snd_soc_component_update_bits(component, WCD934X_CPE_SS_CPE_CTL, 0x05, 0x05); } else { /* Disable AHB CLK and CPE CLK */ - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPE_CTL, + snd_soc_component_update_bits(component, WCD934X_CPE_SS_CPE_CTL, 0x05, 0x00); /* Reset the CPAR mode for CPE FLL */ - snd_soc_write(codec, WCD934X_CPE_FLL_FLL_MODE, 0x20); - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CFG, - 0x04, 0x00); - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, - 0x02, 0x00); + snd_soc_component_write(component, WCD934X_CPE_FLL_FLL_MODE, + 0x20); + snd_soc_component_update_bits(component, + WCD934X_CPE_SS_CPAR_CFG, + 0x04, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CPE_SS_CPAR_CTL, + 0x02, 0x00); } done: return ret; @@ -471,29 +481,30 @@ static int wcd_cntl_cpe_fll_ctrl(struct wcd_dsp_cntl *cntl, static int wcd_cntl_clocks_enable(struct wcd_dsp_cntl *cntl) { - struct snd_soc_codec *codec = cntl->codec; + struct snd_soc_component *component = cntl->component; int ret; - WCD_CNTL_MUTEX_LOCK(codec, cntl->clk_mutex); + WCD_CNTL_MUTEX_LOCK(component, cntl->clk_mutex); /* Enable codec clock */ if (cntl->cdc_cb && cntl->cdc_cb->cdc_clk_en) - ret = cntl->cdc_cb->cdc_clk_en(codec, true); + ret = cntl->cdc_cb->cdc_clk_en(component, true); else ret = -EINVAL; if (ret < 0) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to enable cdc clk, err = %d\n", __func__, ret); goto done; } /* Pull CPAR out of reset */ - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, 0x04, 0x00); + snd_soc_component_update_bits(component, WCD934X_CPE_SS_CPAR_CTL, + 0x04, 0x00); /* Configure and Enable CPE FLL clock */ ret = wcd_cntl_cpe_fll_ctrl(cntl, true); if (ret < 0) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to enable cpe clk, err = %d\n", __func__, ret); goto err_cpe_clk; @@ -501,39 +512,42 @@ static int wcd_cntl_clocks_enable(struct wcd_dsp_cntl *cntl) cntl->is_clk_enabled = true; /* Ungate the CPR clock */ - snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_GATE, 0x10, 0x00); + snd_soc_component_update_bits(component, WCD934X_CODEC_RPM_CLK_GATE, + 0x10, 0x00); done: - WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex); + WCD_CNTL_MUTEX_UNLOCK(component, cntl->clk_mutex); return ret; err_cpe_clk: if (cntl->cdc_cb && cntl->cdc_cb->cdc_clk_en) - cntl->cdc_cb->cdc_clk_en(codec, false); + cntl->cdc_cb->cdc_clk_en(component, false); - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, 0x04, 0x04); - WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex); + snd_soc_component_update_bits(component, WCD934X_CPE_SS_CPAR_CTL, + 0x04, 0x04); + WCD_CNTL_MUTEX_UNLOCK(component, cntl->clk_mutex); return ret; } static int wcd_cntl_clocks_disable(struct wcd_dsp_cntl *cntl) { - struct snd_soc_codec *codec = cntl->codec; + struct snd_soc_component *component = cntl->component; int ret = 0; - WCD_CNTL_MUTEX_LOCK(codec, cntl->clk_mutex); + WCD_CNTL_MUTEX_LOCK(component, cntl->clk_mutex); if (!cntl->is_clk_enabled) { - dev_info(codec->dev, "%s: clocks already disabled\n", + dev_info(component->dev, "%s: clocks already disabled\n", __func__); goto done; } /* Gate the CPR clock */ - snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_GATE, 0x10, 0x10); + snd_soc_component_update_bits(component, WCD934X_CODEC_RPM_CLK_GATE, + 0x10, 0x10); /* Disable CPE FLL clock */ ret = wcd_cntl_cpe_fll_ctrl(cntl, false); if (ret < 0) - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to disable cpe clk, err = %d\n", __func__, ret); @@ -542,35 +556,38 @@ static int wcd_cntl_clocks_disable(struct wcd_dsp_cntl *cntl) * the codec clock */ if (cntl->cdc_cb && cntl->cdc_cb->cdc_clk_en) - ret = cntl->cdc_cb->cdc_clk_en(codec, false); + ret = cntl->cdc_cb->cdc_clk_en(component, false); else ret = -EINVAL; cntl->is_clk_enabled = false; /* Put CPAR in reset */ - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, 0x04, 0x04); + snd_soc_component_update_bits(component, WCD934X_CPE_SS_CPAR_CTL, + 0x04, 0x04); done: - WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex); + WCD_CNTL_MUTEX_UNLOCK(component, cntl->clk_mutex); return ret; } static void wcd_cntl_cpar_ctrl(struct wcd_dsp_cntl *cntl, bool enable) { - struct snd_soc_codec *codec = cntl->codec; + struct snd_soc_component *component = cntl->component; if (enable) - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, 0x03, 0x03); + snd_soc_component_update_bits(component, + WCD934X_CPE_SS_CPAR_CTL, 0x03, 0x03); else - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, 0x03, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CPE_SS_CPAR_CTL, 0x03, 0x00); } static int wcd_cntl_enable_memory(struct wcd_dsp_cntl *cntl, enum wcd_mem_type mem_type) { - struct snd_soc_codec *codec = cntl->codec; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct snd_soc_component *component = cntl->component; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); int loop_cnt = 0; u8 status; int ret = 0; @@ -593,23 +610,26 @@ static int wcd_cntl_enable_memory(struct wcd_dsp_cntl *cntl, case WCD_MEM_TYPE_SWITCHABLE: - snd_soc_update_bits(codec, WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL, - 0x04, 0x00); - snd_soc_update_bits(codec, WCD934X_TEST_DEBUG_MEM_CTRL, - 0x80, 0x80); - snd_soc_update_bits(codec, WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL, - 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL, + 0x04, 0x00); + snd_soc_component_update_bits(component, + WCD934X_TEST_DEBUG_MEM_CTRL, + 0x80, 0x80); + snd_soc_component_update_bits(component, + WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL, + 0x01, 0x01); do { loop_cnt++; /* Time to enable the power domain for memory */ usleep_range(100, 150); - status = snd_soc_read(codec, + status = snd_soc_component_read32(component, WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL); } while ((status & 0x02) != 0x02 && loop_cnt != WCD_MEM_ENABLE_MAX_RETRIES); if ((status & 0x02) != 0x02) { - dev_err(cntl->codec->dev, + dev_err(cntl->component->dev, "%s: power domain not enabled, status = 0x%02x\n", __func__, status); ret = -EIO; @@ -626,20 +646,23 @@ static int wcd_cntl_enable_memory(struct wcd_dsp_cntl *cntl, ARRAY_SIZE(mem_enable_values), mem_enable_values); - snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN, - 0x05); + snd_soc_component_write(component, + WCD934X_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN, + 0x05); break; default: - dev_err(cntl->codec->dev, "%s: Invalid mem_type %d\n", + dev_err(cntl->component->dev, "%s: Invalid mem_type %d\n", __func__, mem_type); ret = -EINVAL; break; } done: /* Make sure Deep sleep of memories is enabled for all banks */ - snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, 0xFF); - snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, 0x0F); + snd_soc_component_write(component, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, 0xFF); + snd_soc_component_write(component, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, 0x0F); return ret; } @@ -647,66 +670,76 @@ static int wcd_cntl_enable_memory(struct wcd_dsp_cntl *cntl, static void wcd_cntl_disable_memory(struct wcd_dsp_cntl *cntl, enum wcd_mem_type mem_type) { - struct snd_soc_codec *codec = cntl->codec; + struct snd_soc_component *component = cntl->component; u8 val; switch (mem_type) { case WCD_MEM_TYPE_ALWAYS_ON: - snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1, - 0xFF); - snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0, - 0xFF); + snd_soc_component_write(component, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1, + 0xFF); + snd_soc_component_write(component, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0, + 0xFF); break; case WCD_MEM_TYPE_SWITCHABLE: - snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3, - 0xFF); - snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2, - 0xFF); - snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN, - 0x07); - - snd_soc_update_bits(codec, WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL, - 0x01, 0x00); - val = snd_soc_read(codec, WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL); + snd_soc_component_write(component, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3, + 0xFF); + snd_soc_component_write(component, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2, + 0xFF); + snd_soc_component_write(component, + WCD934X_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN, + 0x07); + + snd_soc_component_update_bits(component, + WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL, + 0x01, 0x00); + val = snd_soc_component_read32(component, + WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL); if (val & 0x02) - dev_err(codec->dev, + dev_err(component->dev, "%s: Disable switchable failed, val = 0x%02x", __func__, val); - snd_soc_update_bits(codec, WCD934X_TEST_DEBUG_MEM_CTRL, - 0x80, 0x00); + snd_soc_component_update_bits(component, + WCD934X_TEST_DEBUG_MEM_CTRL, + 0x80, 0x00); break; default: - dev_err(cntl->codec->dev, "%s: Invalid mem_type %d\n", + dev_err(cntl->component->dev, "%s: Invalid mem_type %d\n", __func__, mem_type); break; } - snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, 0xFF); - snd_soc_write(codec, WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, 0x0F); + snd_soc_component_write(component, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, 0xFF); + snd_soc_component_write(component, + WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, 0x0F); } static void wcd_cntl_do_shutdown(struct wcd_dsp_cntl *cntl) { - struct snd_soc_codec *codec = cntl->codec; + struct snd_soc_component *component = cntl->component; /* Disable WDOG */ - snd_soc_update_bits(codec, WCD934X_CPE_SS_WDOG_CFG, + snd_soc_component_update_bits(component, WCD934X_CPE_SS_WDOG_CFG, 0x3F, 0x01); /* Put WDSP in reset state */ - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPE_CTL, + snd_soc_component_update_bits(component, WCD934X_CPE_SS_CPE_CTL, 0x02, 0x00); /* If DSP transitions from boot to shutdown, then vote for SVS */ if (cntl->is_wdsp_booted) - cntl->cdc_cb->cdc_vote_svs(codec, true); + cntl->cdc_cb->cdc_vote_svs(component, true); cntl->is_wdsp_booted = false; } static int wcd_cntl_do_boot(struct wcd_dsp_cntl *cntl) { - struct snd_soc_codec *codec = cntl->codec; + struct snd_soc_component *component = cntl->component; int ret = 0; /* @@ -715,21 +748,25 @@ static int wcd_cntl_do_boot(struct wcd_dsp_cntl *cntl) * will be required for debugging the DSP firmware. */ if (cntl->debug_mode) { - snd_soc_update_bits(codec, WCD934X_CPE_SS_WDOG_CFG, - 0x3F, 0x01); + snd_soc_component_update_bits(component, + WCD934X_CPE_SS_WDOG_CFG, + 0x3F, 0x01); } else { - snd_soc_update_bits(codec, WCD934X_CPE_SS_WDOG_CFG, - 0x3F, 0x21); + snd_soc_component_update_bits(component, + WCD934X_CPE_SS_WDOG_CFG, + 0x3F, 0x21); } /* Make sure all the error interrupts are cleared */ - snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_0A, 0xFF); - snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_0B, 0xFF); + snd_soc_component_write(component, WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_0A, + 0xFF); + snd_soc_component_write(component, WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_0B, + 0xFF); reinit_completion(&cntl->boot_complete); /* Remove WDSP out of reset */ - snd_soc_update_bits(codec, WCD934X_CPE_SS_CPE_CTL, + snd_soc_component_update_bits(component, WCD934X_CPE_SS_CPE_CTL, 0x02, 0x02); /* @@ -738,7 +775,8 @@ static int wcd_cntl_do_boot(struct wcd_dsp_cntl *cntl) */ if (cntl->debug_mode) { wait_for_completion(&cntl->boot_complete); - dev_dbg(codec->dev, "%s: WDSP booted in dbg mode\n", __func__); + dev_dbg(component->dev, "%s: WDSP booted in dbg mode\n", + __func__); cntl->is_wdsp_booted = true; goto done; } @@ -747,7 +785,7 @@ static int wcd_cntl_do_boot(struct wcd_dsp_cntl *cntl) ret = wait_for_completion_timeout(&cntl->boot_complete, msecs_to_jiffies(WCD_DSP_BOOT_TIMEOUT_MS)); if (!ret) { - dev_err(codec->dev, "%s: WDSP boot timed out\n", + dev_err(component->dev, "%s: WDSP boot timed out\n", __func__); if (cntl->dbg_dmp_enable) wcd_cntl_collect_debug_dumps(cntl, true); @@ -761,16 +799,16 @@ static int wcd_cntl_do_boot(struct wcd_dsp_cntl *cntl) ret = 0; } - dev_dbg(codec->dev, "%s: WDSP booted in normal mode\n", __func__); + dev_dbg(component->dev, "%s: WDSP booted in normal mode\n", __func__); cntl->is_wdsp_booted = true; /* Enable WDOG */ - snd_soc_update_bits(codec, WCD934X_CPE_SS_WDOG_CFG, + snd_soc_component_update_bits(component, WCD934X_CPE_SS_WDOG_CFG, 0x10, 0x10); done: /* If dsp booted up, then remove vote on SVS */ if (cntl->is_wdsp_booted) - cntl->cdc_cb->cdc_vote_svs(codec, false); + cntl->cdc_cb->cdc_vote_svs(component, false); return ret; err_boot: @@ -794,7 +832,7 @@ static irqreturn_t wcd_cntl_ipc_irq(int irq, void *data) ret = -EINVAL; if (ret < 0) - dev_err(cntl->codec->dev, + dev_err(cntl->component->dev, "%s: Failed to handle irq %d\n", __func__, irq); return IRQ_HANDLED; @@ -803,19 +841,21 @@ static irqreturn_t wcd_cntl_ipc_irq(int irq, void *data) static irqreturn_t wcd_cntl_err_irq(int irq, void *data) { struct wcd_dsp_cntl *cntl = data; - struct snd_soc_codec *codec = cntl->codec; + struct snd_soc_component *component = cntl->component; struct wdsp_err_signal_arg arg; u16 status = 0; u8 reg_val; int rc, ret = 0; - reg_val = snd_soc_read(codec, WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0A); + reg_val = snd_soc_component_read32(component, + WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0A); status = status | reg_val; - reg_val = snd_soc_read(codec, WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0B); + reg_val = snd_soc_component_read32(component, + WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0B); status = status | (reg_val << 8); - dev_info(codec->dev, "%s: error interrupt status = 0x%x\n", + dev_info(component->dev, "%s: error interrupt status = 0x%x\n", __func__, status); if ((status & cntl->irqs.fatal_irqs) && @@ -832,14 +872,14 @@ static irqreturn_t wcd_cntl_err_irq(int irq, void *data) ret = cntl->m_ops->signal_handler(cntl->m_dev, WDSP_ERR_INTR, &arg); if (ret < 0) - dev_err(cntl->codec->dev, + dev_err(cntl->component->dev, "%s: Failed to handle fatal irq 0x%x\n", __func__, status & cntl->irqs.fatal_irqs); wcd_cntl_change_online_state(cntl, 0); if (rc == 0) WCD_CNTL_CLR_ERR_IRQ_FLAG(cntl); } else { - dev_err(cntl->codec->dev, "%s: Invalid signal_handler\n", + dev_err(cntl->component->dev, "%s: Invalid signal_handler\n", __func__); } @@ -850,7 +890,7 @@ static int wcd_control_handler(struct device *dev, void *priv_data, enum wdsp_event_type event, void *data) { struct wcd_dsp_cntl *cntl = priv_data; - struct snd_soc_codec *codec = cntl->codec; + struct snd_soc_component *component = cntl->component; int ret = 0; switch (event) { @@ -864,7 +904,7 @@ static int wcd_control_handler(struct device *dev, void *priv_data, /* Disable all the clocks */ ret = wcd_cntl_clocks_disable(cntl); if (ret < 0) - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to disable clocks, err = %d\n", __func__, ret); @@ -879,7 +919,7 @@ static int wcd_control_handler(struct device *dev, void *priv_data, /* Enable all the clocks */ ret = wcd_cntl_clocks_enable(cntl); if (ret < 0) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to enable clocks, err = %d\n", __func__, ret); goto done; @@ -898,7 +938,7 @@ static int wcd_control_handler(struct device *dev, void *priv_data, ret = wcd_cntl_do_boot(cntl); if (ret < 0) - dev_err(codec->dev, + dev_err(component->dev, "%s: WDSP boot failed, err = %d\n", __func__, ret); break; @@ -910,7 +950,7 @@ static int wcd_control_handler(struct device *dev, void *priv_data, break; default: - dev_dbg(codec->dev, "%s: unhandled event %d\n", + dev_dbg(component->dev, "%s: unhandled event %d\n", __func__, event); } @@ -920,13 +960,13 @@ static int wcd_control_handler(struct device *dev, void *priv_data, static int wcd_cntl_sysfs_init(char *dir, struct wcd_dsp_cntl *cntl) { - struct snd_soc_codec *codec = cntl->codec; + struct snd_soc_component *component = cntl->component; int ret = 0; ret = kobject_init_and_add(&cntl->wcd_kobj, &wcd_cntl_ktype, kernel_kobj, dir); if (ret < 0) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to add kobject %s, err = %d\n", __func__, dir, ret); goto done; @@ -934,7 +974,7 @@ static int wcd_cntl_sysfs_init(char *dir, struct wcd_dsp_cntl *cntl) ret = sysfs_create_file(&cntl->wcd_kobj, &cntl_attr_boot.attr); if (ret < 0) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to add wdsp_boot sysfs entry to %s\n", __func__, dir); goto fail_create_file; @@ -956,11 +996,11 @@ static void wcd_cntl_sysfs_remove(struct wcd_dsp_cntl *cntl) static void wcd_cntl_debugfs_init(char *dir, struct wcd_dsp_cntl *cntl) { - struct snd_soc_codec *codec = cntl->codec; + struct snd_soc_component *component = cntl->component; cntl->entry = debugfs_create_dir(dir, NULL); if (IS_ERR_OR_NULL(dir)) { - dev_err(codec->dev, "%s debugfs_create_dir failed for %s\n", + dev_err(component->dev, "%s debugfs_create_dir failed for %s\n", __func__, dir); goto done; } @@ -987,7 +1027,7 @@ static int wcd_miscdev_release(struct inode *inode, struct file *filep) struct wcd_dsp_cntl, miscdev); if (!cntl->m_dev || !cntl->m_ops || !cntl->m_ops->vote_for_dsp) { - dev_err(cntl->codec->dev, + dev_err(cntl->component->dev, "%s: DSP not ready to boot\n", __func__); return -EINVAL; } @@ -1020,7 +1060,7 @@ static ssize_t wcd_miscdev_write(struct file *filep, const char __user *ubuf, ret = copy_from_user(val, ubuf, count); if (ret < 0) { - dev_err(cntl->codec->dev, + dev_err(cntl->component->dev, "%s: copy_from_user failed, err = %d\n", __func__, ret); ret = -EFAULT; @@ -1032,7 +1072,7 @@ static ssize_t wcd_miscdev_write(struct file *filep, const char __user *ubuf, vote = true; } else if (val[0] == '0') { if (cntl->boot_reqs == 0) { - dev_err(cntl->codec->dev, + dev_err(cntl->component->dev, "%s: WDSP already disabled\n", __func__); ret = -EINVAL; @@ -1042,7 +1082,7 @@ static ssize_t wcd_miscdev_write(struct file *filep, const char __user *ubuf, vote = false; } else if (!strcmp(val, "DEBUG_DUMP")) { if (cntl->dbg_dmp_enable) { - dev_dbg(cntl->codec->dev, + dev_dbg(cntl->component->dev, "%s: Collect dumps for debug use\n", __func__); wcd_cntl_collect_debug_dumps(cntl, false); } @@ -1052,13 +1092,13 @@ static ssize_t wcd_miscdev_write(struct file *filep, const char __user *ubuf, */ goto done; } else { - dev_err(cntl->codec->dev, "%s: Invalid value %s\n", + dev_err(cntl->component->dev, "%s: Invalid value %s\n", __func__, val); ret = -EINVAL; goto done; } - dev_dbg(cntl->codec->dev, + dev_dbg(cntl->component->dev, "%s: booted = %s, ref_cnt = %d, vote = %s\n", __func__, cntl->is_wdsp_booted ? "true" : "false", cntl->boot_reqs, vote ? "true" : "false"); @@ -1087,7 +1127,7 @@ static int wcd_cntl_miscdev_create(struct wcd_dsp_cntl *cntl) cntl->miscdev.minor = MISC_DYNAMIC_MINOR; cntl->miscdev.name = cntl->miscdev_name; cntl->miscdev.fops = &wcd_miscdev_fops; - cntl->miscdev.parent = cntl->codec->dev; + cntl->miscdev.parent = cntl->component->dev; return misc_register(&cntl->miscdev); } @@ -1100,8 +1140,8 @@ static void wcd_cntl_miscdev_destroy(struct wcd_dsp_cntl *cntl) static int wcd_control_init(struct device *dev, void *priv_data) { struct wcd_dsp_cntl *cntl = priv_data; - struct snd_soc_codec *codec = cntl->codec; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct snd_soc_component *component = cntl->component; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; int ret; bool err_irq_requested = false; @@ -1111,16 +1151,16 @@ static int wcd_control_init(struct device *dev, void *priv_data) wcd_cntl_ipc_irq, "CPE IPC1", cntl); if (ret < 0) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to request cpe ipc irq, err = %d\n", __func__, ret); goto done; } /* Unmask the fatal irqs */ - snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, + snd_soc_component_write(component, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, ~(cntl->irqs.fatal_irqs & 0xFF)); - snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, + snd_soc_component_write(component, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, ~((cntl->irqs.fatal_irqs >> 8) & 0xFF)); /* @@ -1130,7 +1170,7 @@ static int wcd_control_init(struct device *dev, void *priv_data) */ if (wcd9xxx_request_irq(core_res, cntl->irqs.cpe_err_irq, wcd_cntl_err_irq, "CPE ERR", cntl)) - dev_info(codec->dev, "%s: Failed request_irq(cpe_err_irq)", + dev_info(component->dev, "%s: Failed request_irq(cpe_err_irq)", __func__); else err_irq_requested = true; @@ -1139,7 +1179,7 @@ static int wcd_control_init(struct device *dev, void *priv_data) /* Enable all the clocks */ ret = wcd_cntl_clocks_enable(cntl); if (ret < 0) { - dev_err(codec->dev, "%s: Failed to enable clocks, err = %d\n", + dev_err(component->dev, "%s: Failed to enable clocks, err = %d\n", __func__, ret); goto err_clk_enable; } @@ -1149,8 +1189,10 @@ static int wcd_control_init(struct device *dev, void *priv_data) err_clk_enable: /* Mask all error interrupts */ - snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, 0xFF); - snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, 0xFF); + snd_soc_component_write(component, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, + 0xFF); + snd_soc_component_write(component, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, + 0xFF); /* Free the irq's requested */ wcd9xxx_free_irq(core_res, cntl->irqs.cpe_ipc1_irq, cntl); @@ -1164,16 +1206,18 @@ static int wcd_control_init(struct device *dev, void *priv_data) static int wcd_control_deinit(struct device *dev, void *priv_data) { struct wcd_dsp_cntl *cntl = priv_data; - struct snd_soc_codec *codec = cntl->codec; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct snd_soc_component *component = cntl->component; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; wcd_cntl_clocks_disable(cntl); wcd_cntl_cpar_ctrl(cntl, false); /* Mask all error interrupts */ - snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, 0xFF); - snd_soc_write(codec, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, 0xFF); + snd_soc_component_write(component, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A, + 0xFF); + snd_soc_component_write(component, WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B, + 0xFF); /* Free the irq's requested */ wcd9xxx_free_irq(core_res, cntl->irqs.cpe_err_irq, cntl); @@ -1193,7 +1237,7 @@ static int wcd_ctrl_component_bind(struct device *dev, void *data) { struct wcd_dsp_cntl *cntl; - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct snd_card *card; struct snd_info_entry *entry; char proc_name[WCD_PROCFS_ENTRY_MAX_LEN]; @@ -1247,8 +1291,8 @@ static int wcd_ctrl_component_bind(struct device *dev, wcd_cntl_debugfs_init(wcd_cntl_dir_name, cntl); - codec = cntl->codec; - card = codec->component.card->snd_card; + component = cntl->component; + card = component->card->snd_card; snprintf(proc_name, WCD_PROCFS_ENTRY_MAX_LEN, "%s%d%s", "cpe", cntl->dsp_instance, "_state"); entry = snd_info_create_card_entry(card, proc_name, card->proc_root); @@ -1335,7 +1379,7 @@ int wcd_dsp_ssr_event(struct wcd_dsp_cntl *cntl, enum cdc_ssr_event event) } if (!cntl->m_dev || !cntl->m_ops || !cntl->m_ops->signal_handler) { - dev_err(cntl->codec->dev, + dev_err(cntl->component->dev, "%s: Invalid signal_handler callback\n", __func__); return -EINVAL; } @@ -1346,7 +1390,7 @@ int wcd_dsp_ssr_event(struct wcd_dsp_cntl *cntl, enum cdc_ssr_event event) WDSP_CDC_DOWN_SIGNAL, NULL); if (ret < 0) - dev_err(cntl->codec->dev, + dev_err(cntl->component->dev, "%s: WDSP_CDC_DOWN_SIGNAL failed, err = %d\n", __func__, ret); wcd_cntl_change_online_state(cntl, 0); @@ -1356,12 +1400,12 @@ int wcd_dsp_ssr_event(struct wcd_dsp_cntl *cntl, enum cdc_ssr_event event) WDSP_CDC_UP_SIGNAL, NULL); if (ret < 0) - dev_err(cntl->codec->dev, + dev_err(cntl->component->dev, "%s: WDSP_CDC_UP_SIGNAL failed, err = %d\n", __func__, ret); break; default: - dev_err(cntl->codec->dev, "%s: Invalid event %d\n", + dev_err(cntl->component->dev, "%s: Invalid event %d\n", __func__, event); ret = -EINVAL; break; @@ -1373,23 +1417,23 @@ EXPORT_SYMBOL(wcd_dsp_ssr_event); /* * wcd_dsp_cntl_init: Initialize the wcd-dsp control - * @codec: pointer to the codec handle + * @component: pointer to the codec component handle * @params: Parameters required to initialize wcd-dsp control * * This API is expected to be invoked by the codec driver and * provide information essential for the wcd dsp control to * configure and initialize the dsp */ -void wcd_dsp_cntl_init(struct snd_soc_codec *codec, +void wcd_dsp_cntl_init(struct snd_soc_component *component, struct wcd_dsp_params *params, struct wcd_dsp_cntl **cntl) { struct wcd_dsp_cntl *control; int ret; - if (!codec || !params) { + if (!component || !params) { pr_err("%s: Invalid handle to %s\n", __func__, - (!codec) ? "codec" : "params"); + (!component) ? "component" : "params"); *cntl = NULL; return; } @@ -1402,7 +1446,7 @@ void wcd_dsp_cntl_init(struct snd_soc_codec *codec, if (!params->cb || !params->cb->cdc_clk_en || !params->cb->cdc_vote_svs) { - dev_err(codec->dev, + dev_err(component->dev, "%s: clk_en and vote_svs callbacks must be provided\n", __func__); return; @@ -1412,7 +1456,7 @@ void wcd_dsp_cntl_init(struct snd_soc_codec *codec, if (!(control)) return; - control->codec = codec; + control->component = component; control->clk_rate = params->clk_rate; control->cdc_cb = params->cb; control->dsp_instance = params->dsp_instance; @@ -1428,7 +1472,7 @@ void wcd_dsp_cntl_init(struct snd_soc_codec *codec, * Vote for SVS now, the vote will be removed only * after DSP is booted up. */ - control->cdc_cb->cdc_vote_svs(codec, true); + control->cdc_cb->cdc_vote_svs(component, true); /* * If this is the last component needed by master to be ready, @@ -1437,9 +1481,9 @@ void wcd_dsp_cntl_init(struct snd_soc_codec *codec, * so that we can access it during this component's bind call. */ *cntl = control; - ret = component_add(codec->dev, &wcd_ctrl_component_ops); + ret = component_add(component->dev, &wcd_ctrl_component_ops); if (ret) { - dev_err(codec->dev, "%s: component_add failed, err = %d\n", + dev_err(component->dev, "%s: component_add failed, err = %d\n", __func__, ret); kfree(*cntl); *cntl = NULL; @@ -1457,12 +1501,12 @@ EXPORT_SYMBOL(wcd_dsp_cntl_init); void wcd_dsp_cntl_deinit(struct wcd_dsp_cntl **cntl) { struct wcd_dsp_cntl *control = *cntl; - struct snd_soc_codec *codec; + struct snd_soc_component *component; /* If control is NULL, there is nothing to de-initialize */ if (!control) return; - codec = control->codec; + component = control->component; /* * Calling shutdown will cleanup all register states, @@ -1472,7 +1516,7 @@ void wcd_dsp_cntl_deinit(struct wcd_dsp_cntl **cntl) wcd_cntl_disable_memory(control, WCD_MEM_TYPE_SWITCHABLE); wcd_cntl_disable_memory(control, WCD_MEM_TYPE_ALWAYS_ON); - component_del(codec->dev, &wcd_ctrl_component_ops); + component_del(component->dev, &wcd_ctrl_component_ops); mutex_destroy(&control->clk_mutex); mutex_destroy(&control->ssr_mutex); diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h index 8035176fe100..a4b18a3cbae4 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h @@ -17,9 +17,9 @@ enum cdc_ssr_event { struct wcd_dsp_cdc_cb { /* Callback to enable codec clock */ - int (*cdc_clk_en)(struct snd_soc_codec *, bool); + int (*cdc_clk_en)(struct snd_soc_component *component, bool enable); /* Callback to vote and unvote for SVS2 mode */ - void (*cdc_vote_svs)(struct snd_soc_codec *, bool); + void (*cdc_vote_svs)(struct snd_soc_component *component, bool enable); }; struct wcd_dsp_irq_info { @@ -61,7 +61,7 @@ struct wdsp_ssr_entry { struct wcd_dsp_cntl { /* Handle to codec */ - struct snd_soc_codec *codec; + struct snd_soc_component *component; /* Clk rate of the codec clock */ u32 clk_rate; @@ -109,7 +109,7 @@ struct wcd_dsp_cntl { #endif }; -void wcd_dsp_cntl_init(struct snd_soc_codec *codec, +void wcd_dsp_cntl_init(struct snd_soc_component *component, struct wcd_dsp_params *params, struct wcd_dsp_cntl **cntl); void wcd_dsp_cntl_deinit(struct wcd_dsp_cntl **cntl); diff --git a/asoc/codecs/wcd934x/wcd934x-mbhc.c b/asoc/codecs/wcd934x/wcd934x-mbhc.c index f23dcf1e46f6..7a91bf348288 100644 --- a/asoc/codecs/wcd934x/wcd934x-mbhc.c +++ b/asoc/codecs/wcd934x/wcd934x-mbhc.c @@ -169,21 +169,21 @@ struct tavil_mbhc_zdet_param { u16 btn7; }; -static int tavil_mbhc_request_irq(struct snd_soc_codec *codec, +static int tavil_mbhc_request_irq(struct snd_soc_component *component, int irq, irq_handler_t handler, const char *name, void *data) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; return wcd9xxx_request_irq(core_res, irq, handler, name, data); } -static void tavil_mbhc_irq_control(struct snd_soc_codec *codec, +static void tavil_mbhc_irq_control(struct snd_soc_component *component, int irq, bool enable) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; if (enable) @@ -192,10 +192,10 @@ static void tavil_mbhc_irq_control(struct snd_soc_codec *codec, wcd9xxx_disable_irq(core_res, irq); } -static int tavil_mbhc_free_irq(struct snd_soc_codec *codec, +static int tavil_mbhc_free_irq(struct snd_soc_component *component, int irq, void *data) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; @@ -203,27 +203,28 @@ static int tavil_mbhc_free_irq(struct snd_soc_codec *codec, return 0; } -static void tavil_mbhc_clk_setup(struct snd_soc_codec *codec, +static void tavil_mbhc_clk_setup(struct snd_soc_component *component, bool enable) { if (enable) - snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_1, + snd_soc_component_update_bits(component, WCD934X_MBHC_NEW_CTL_1, 0x80, 0x80); else - snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_1, + snd_soc_component_update_bits(component, WCD934X_MBHC_NEW_CTL_1, 0x80, 0x00); } -static int tavil_mbhc_btn_to_num(struct snd_soc_codec *codec) +static int tavil_mbhc_btn_to_num(struct snd_soc_component *component) { - return snd_soc_read(codec, WCD934X_ANA_MBHC_RESULT_3) & 0x7; + return snd_soc_component_read32(component, WCD934X_ANA_MBHC_RESULT_3) & + 0x7; } static int tavil_enable_ext_mb_source(struct wcd_mbhc *mbhc, bool turn_on) { struct wcd934x_mbhc *wcd934x_mbhc; - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; struct wcd934x_on_demand_supply *supply; int ret = 0; @@ -231,20 +232,21 @@ static int tavil_enable_ext_mb_source(struct wcd_mbhc *mbhc, supply = &wcd934x_mbhc->on_demand_list[WCD934X_ON_DEMAND_MICBIAS]; if (!supply->supply) { - dev_dbg(codec->dev, "%s: warning supply not present ond for %s\n", + dev_dbg(component->dev, "%s: warning supply not present ond for %s\n", __func__, "onDemand Micbias"); return ret; } - dev_dbg(codec->dev, "%s turn_on: %d count: %d\n", __func__, turn_on, + dev_dbg(component->dev, "%s turn_on: %d count: %d\n", __func__, turn_on, supply->ondemand_supply_count); if (turn_on) { if (!(supply->ondemand_supply_count)) { ret = snd_soc_dapm_force_enable_pin( - snd_soc_codec_get_dapm(codec), + snd_soc_component_get_dapm(component), "MICBIAS_REGULATOR"); - snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + snd_soc_dapm_sync( + snd_soc_component_get_dapm(component)); } supply->ondemand_supply_count++; } else { @@ -252,34 +254,34 @@ static int tavil_enable_ext_mb_source(struct wcd_mbhc *mbhc, supply->ondemand_supply_count--; if (!(supply->ondemand_supply_count)) { ret = snd_soc_dapm_disable_pin( - snd_soc_codec_get_dapm(codec), + snd_soc_component_get_dapm(component), "MICBIAS_REGULATOR"); - snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + snd_soc_dapm_sync(snd_soc_component_get_dapm(component)); } } if (ret) - dev_err(codec->dev, "%s: Failed to %s external micbias source\n", + dev_err(component->dev, "%s: Failed to %s external micbias source\n", __func__, turn_on ? "enable" : "disabled"); else - dev_dbg(codec->dev, "%s: %s external micbias source\n", + dev_dbg(component->dev, "%s: %s external micbias source\n", __func__, turn_on ? "Enabled" : "Disabled"); return ret; } -static void tavil_mbhc_mbhc_bias_control(struct snd_soc_codec *codec, +static void tavil_mbhc_mbhc_bias_control(struct snd_soc_component *component, bool enable) { if (enable) - snd_soc_update_bits(codec, WCD934X_ANA_MBHC_ELECT, + snd_soc_component_update_bits(component, WCD934X_ANA_MBHC_ELECT, 0x01, 0x01); else - snd_soc_update_bits(codec, WCD934X_ANA_MBHC_ELECT, + snd_soc_component_update_bits(component, WCD934X_ANA_MBHC_ELECT, 0x01, 0x00); } -static void tavil_mbhc_program_btn_thr(struct snd_soc_codec *codec, +static void tavil_mbhc_program_btn_thr(struct snd_soc_component *component, s16 *btn_low, s16 *btn_high, int num_btn, bool is_micbias) { @@ -287,7 +289,7 @@ static void tavil_mbhc_program_btn_thr(struct snd_soc_codec *codec, int vth; if (num_btn > WCD_MBHC_DEF_BUTTONS) { - dev_err(codec->dev, "%s: invalid number of buttons: %d\n", + dev_err(component->dev, "%s: invalid number of buttons: %d\n", __func__, num_btn); return; } @@ -299,17 +301,18 @@ static void tavil_mbhc_program_btn_thr(struct snd_soc_codec *codec, */ for (i = 0; i < num_btn; i++) { vth = ((btn_high[i] * 2) / 25) & 0x3F; - snd_soc_update_bits(codec, WCD934X_ANA_MBHC_BTN0 + i, - 0xFC, vth << 2); - dev_dbg(codec->dev, "%s: btn_high[%d]: %d, vth: %d\n", + snd_soc_component_update_bits(component, + WCD934X_ANA_MBHC_BTN0 + i, + 0xFC, vth << 2); + dev_dbg(component->dev, "%s: btn_high[%d]: %d, vth: %d\n", __func__, i, btn_high[i], vth); } } static bool tavil_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock) { - struct snd_soc_codec *codec = mbhc->codec; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct snd_soc_component *component = mbhc->component; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; bool ret = 0; @@ -343,20 +346,22 @@ static bool tavil_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) u8 val; if (micb_num == MIC_BIAS_2) { - val = (snd_soc_read(mbhc->codec, WCD934X_ANA_MICB2) >> 6); + val = (snd_soc_component_read32( + mbhc->component, WCD934X_ANA_MICB2) >> 6); if (val == 0x01) return true; } return false; } -static bool tavil_mbhc_hph_pa_on_status(struct snd_soc_codec *codec) +static bool tavil_mbhc_hph_pa_on_status(struct snd_soc_component *component) { - return (snd_soc_read(codec, WCD934X_ANA_HPH) & 0xC0) ? true : false; + return (snd_soc_component_read32(component, WCD934X_ANA_HPH) & 0xC0) ? + true : false; } static void tavil_mbhc_hph_l_pull_up_control( - struct snd_soc_codec *codec, + struct snd_soc_component *component, enum mbhc_hs_pullup_iref pull_up_cur) { /* Default pull up current to 2uA */ @@ -364,14 +369,15 @@ static void tavil_mbhc_hph_l_pull_up_control( pull_up_cur == I_DEFAULT) pull_up_cur = I_2P0_UA; - dev_dbg(codec->dev, "%s: HS pull up current:%d\n", + dev_dbg(component->dev, "%s: HS pull up current:%d\n", __func__, pull_up_cur); - snd_soc_update_bits(codec, WCD934X_MBHC_NEW_PLUG_DETECT_CTL, - 0xC0, pull_up_cur << 6); + snd_soc_component_update_bits(component, + WCD934X_MBHC_NEW_PLUG_DETECT_CTL, + 0xC0, pull_up_cur << 6); } -static int tavil_mbhc_request_micbias(struct snd_soc_codec *codec, +static int tavil_mbhc_request_micbias(struct snd_soc_component *component, int micb_num, int req) { int ret; @@ -381,32 +387,32 @@ static int tavil_mbhc_request_micbias(struct snd_soc_codec *codec, * is vote to enable mclk */ if (req == MICB_ENABLE) - tavil_cdc_mclk_enable(codec, true); + tavil_cdc_mclk_enable(component, true); - ret = tavil_micbias_control(codec, micb_num, req, false); + ret = tavil_micbias_control(component, micb_num, req, false); /* * Release vote for mclk while requesting for * micbias disable */ if (req == MICB_DISABLE) - tavil_cdc_mclk_enable(codec, false); + tavil_cdc_mclk_enable(component, false); return ret; } -static void tavil_mbhc_micb_ramp_control(struct snd_soc_codec *codec, +static void tavil_mbhc_micb_ramp_control(struct snd_soc_component *component, bool enable) { if (enable) { - snd_soc_update_bits(codec, WCD934X_ANA_MICB2_RAMP, + snd_soc_component_update_bits(component, WCD934X_ANA_MICB2_RAMP, 0x1C, 0x0C); - snd_soc_update_bits(codec, WCD934X_ANA_MICB2_RAMP, + snd_soc_component_update_bits(component, WCD934X_ANA_MICB2_RAMP, 0x80, 0x80); } else { - snd_soc_update_bits(codec, WCD934X_ANA_MICB2_RAMP, + snd_soc_component_update_bits(component, WCD934X_ANA_MICB2_RAMP, 0x80, 0x00); - snd_soc_update_bits(codec, WCD934X_ANA_MICB2_RAMP, + snd_soc_component_update_bits(component, WCD934X_ANA_MICB2_RAMP, 0x1C, 0x00); } } @@ -416,26 +422,27 @@ static struct firmware_cal *tavil_get_hwdep_fw_cal(struct wcd_mbhc *mbhc, { struct wcd934x_mbhc *wcd934x_mbhc; struct firmware_cal *hwdep_cal; - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; wcd934x_mbhc = container_of(mbhc, struct wcd934x_mbhc, wcd_mbhc); - if (!codec) { - pr_err("%s: NULL codec pointer\n", __func__); + if (!component) { + pr_err("%s: NULL component pointer\n", __func__); return NULL; } hwdep_cal = wcdcal_get_fw_cal(wcd934x_mbhc->fw_data, type); if (!hwdep_cal) - dev_err(codec->dev, "%s: cal not sent by %d\n", + dev_err(component->dev, "%s: cal not sent by %d\n", __func__, type); return hwdep_cal; } -static int tavil_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec, - int micb_num, bool req_en) +static int tavil_mbhc_micb_ctrl_threshold_mic( + struct snd_soc_component *component, + int micb_num, bool req_en) { - struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent); int rc, micb_mv; if (micb_num != MIC_BIAS_2) @@ -451,7 +458,7 @@ static int tavil_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec, micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb2_mv; - rc = tavil_mbhc_micb_adjust_voltage(codec, micb_mv, MIC_BIAS_2); + rc = tavil_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2); return rc; } @@ -512,25 +519,25 @@ static inline void tavil_mbhc_get_result_params(struct wcd9xxx *wcd9xxx, } } -static void tavil_mbhc_zdet_ramp(struct snd_soc_codec *codec, +static void tavil_mbhc_zdet_ramp(struct snd_soc_component *component, struct tavil_mbhc_zdet_param *zdet_param, int32_t *zl, int32_t *zr, s16 *d1_a) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); int32_t zdet = 0; - snd_soc_update_bits(codec, WCD934X_MBHC_NEW_ZDET_ANA_CTL, 0x70, - zdet_param->ldo_ctl << 4); - snd_soc_update_bits(codec, WCD934X_ANA_MBHC_BTN5, 0xFC, - zdet_param->btn5); - snd_soc_update_bits(codec, WCD934X_ANA_MBHC_BTN6, 0xFC, - zdet_param->btn6); - snd_soc_update_bits(codec, WCD934X_ANA_MBHC_BTN7, 0xFC, - zdet_param->btn7); - snd_soc_update_bits(codec, WCD934X_MBHC_NEW_ZDET_ANA_CTL, 0x0F, - zdet_param->noff); - snd_soc_update_bits(codec, WCD934X_MBHC_NEW_ZDET_RAMP_CTL, 0x0F, - zdet_param->nshift); + snd_soc_component_update_bits(component, WCD934X_MBHC_NEW_ZDET_ANA_CTL, + 0x70, zdet_param->ldo_ctl << 4); + snd_soc_component_update_bits(component, WCD934X_ANA_MBHC_BTN5, 0xFC, + zdet_param->btn5); + snd_soc_component_update_bits(component, WCD934X_ANA_MBHC_BTN6, 0xFC, + zdet_param->btn6); + snd_soc_component_update_bits(component, WCD934X_ANA_MBHC_BTN7, 0xFC, + zdet_param->btn7); + snd_soc_component_update_bits(component, WCD934X_MBHC_NEW_ZDET_ANA_CTL, + 0x0F, zdet_param->noff); + snd_soc_component_update_bits(component, WCD934X_MBHC_NEW_ZDET_RAMP_CTL, + 0x0F, zdet_param->nshift); if (!zl) goto z_right; @@ -560,17 +567,17 @@ static void tavil_mbhc_zdet_ramp(struct snd_soc_codec *codec, *zr = zdet; } -static inline void tavil_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec, +static inline void tavil_wcd_mbhc_qfuse_cal(struct snd_soc_component *component, int32_t *z_val, int flag_l_r) { s16 q1; int q1_cal; if (*z_val < (TAVIL_ZDET_VAL_400/1000)) - q1 = snd_soc_read(codec, + q1 = snd_soc_component_read32(component, WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT1 + (2 * flag_l_r)); else - q1 = snd_soc_read(codec, + q1 = snd_soc_component_read32(component, WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT2 + (2 * flag_l_r)); if (q1 & 0x80) q1_cal = (10000 - ((q1 & 0x7F) * 25)); @@ -583,8 +590,8 @@ static inline void tavil_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec, static void tavil_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, uint32_t *zr) { - struct snd_soc_codec *codec = mbhc->codec; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct snd_soc_component *component = mbhc->component; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); s16 reg0, reg1, reg2, reg3, reg4; int32_t z1L, z1R, z1Ls; int zMono, z_diff1, z_diff2; @@ -606,13 +613,15 @@ static void tavil_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); - reg0 = snd_soc_read(codec, WCD934X_ANA_MBHC_BTN5); - reg1 = snd_soc_read(codec, WCD934X_ANA_MBHC_BTN6); - reg2 = snd_soc_read(codec, WCD934X_ANA_MBHC_BTN7); - reg3 = snd_soc_read(codec, WCD934X_MBHC_CTL_CLK); - reg4 = snd_soc_read(codec, WCD934X_MBHC_NEW_ZDET_ANA_CTL); + reg0 = snd_soc_component_read32(component, WCD934X_ANA_MBHC_BTN5); + reg1 = snd_soc_component_read32(component, WCD934X_ANA_MBHC_BTN6); + reg2 = snd_soc_component_read32(component, WCD934X_ANA_MBHC_BTN7); + reg3 = snd_soc_component_read32(component, WCD934X_MBHC_CTL_CLK); + reg4 = snd_soc_component_read32(component, + WCD934X_MBHC_NEW_ZDET_ANA_CTL); - if (snd_soc_read(codec, WCD934X_ANA_MBHC_ELECT) & 0x80) { + if (snd_soc_component_read32(component, WCD934X_ANA_MBHC_ELECT) & + 0x80) { is_fsm_disable = true; regmap_update_bits(wcd9xxx->regmap, WCD934X_ANA_MBHC_ELECT, 0x80, 0x00); @@ -630,7 +639,7 @@ static void tavil_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, /* First get impedance on Left */ d1 = d1_a[1]; zdet_param_ptr = &zdet_param[1]; - tavil_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + tavil_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1); if (!TAVIL_MBHC_IS_SECOND_RAMP_REQUIRED(z1L)) goto left_ch_impedance; @@ -646,7 +655,7 @@ static void tavil_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, zdet_param_ptr = &zdet_param[3]; d1 = d1_a[3]; } - tavil_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + tavil_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1); left_ch_impedance: if ((z1L == TAVIL_ZDET_FLOATING_IMPEDANCE) || @@ -656,13 +665,13 @@ static void tavil_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, d1 = d1_a[1]; } else { *zl = z1L/1000; - tavil_wcd_mbhc_qfuse_cal(codec, zl, 0); + tavil_wcd_mbhc_qfuse_cal(component, zl, 0); } - dev_dbg(codec->dev, "%s: impedance on HPH_L = %d(ohms)\n", + dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n", __func__, *zl); /* Start of right impedance ramp and calculation */ - tavil_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + tavil_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1); if (TAVIL_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) { if (((z1R > TAVIL_ZDET_VAL_1200) && (zdet_param_ptr->noff == 0x6)) || @@ -680,7 +689,7 @@ static void tavil_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, zdet_param_ptr = &zdet_param[3]; d1 = d1_a[3]; } - tavil_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + tavil_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1); } right_ch_impedance: if ((z1R == TAVIL_ZDET_FLOATING_IMPEDANCE) || @@ -688,15 +697,15 @@ static void tavil_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, *zr = TAVIL_ZDET_FLOATING_IMPEDANCE; } else { *zr = z1R/1000; - tavil_wcd_mbhc_qfuse_cal(codec, zr, 1); + tavil_wcd_mbhc_qfuse_cal(component, zr, 1); } - dev_dbg(codec->dev, "%s: impedance on HPH_R = %d(ohms)\n", + dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n", __func__, *zr); /* Mono/stereo detection */ if ((*zl == TAVIL_ZDET_FLOATING_IMPEDANCE) && (*zr == TAVIL_ZDET_FLOATING_IMPEDANCE)) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: plug type is invalid or extension cable\n", __func__); goto zdet_complete; @@ -705,40 +714,46 @@ static void tavil_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, (*zr == TAVIL_ZDET_FLOATING_IMPEDANCE) || ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) || ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: Mono plug type with one ch floating or shorted to GND\n", __func__); mbhc->hph_type = WCD_MBHC_HPH_MONO; goto zdet_complete; } - snd_soc_update_bits(codec, WCD934X_HPH_R_ATEST, 0x02, 0x02); - snd_soc_update_bits(codec, WCD934X_HPH_PA_CTL2, 0x40, 0x01); + snd_soc_component_update_bits(component, WCD934X_HPH_R_ATEST, + 0x02, 0x02); + snd_soc_component_update_bits(component, WCD934X_HPH_PA_CTL2, + 0x40, 0x01); if (*zl < (TAVIL_ZDET_VAL_32/1000)) - tavil_mbhc_zdet_ramp(codec, &zdet_param[0], &z1Ls, NULL, d1); + tavil_mbhc_zdet_ramp(component, &zdet_param[0], + &z1Ls, NULL, d1); else - tavil_mbhc_zdet_ramp(codec, &zdet_param[1], &z1Ls, NULL, d1); - snd_soc_update_bits(codec, WCD934X_HPH_PA_CTL2, 0x40, 0x00); - snd_soc_update_bits(codec, WCD934X_HPH_R_ATEST, 0x02, 0x00); + tavil_mbhc_zdet_ramp(component, &zdet_param[1], + &z1Ls, NULL, d1); + snd_soc_component_update_bits(component, WCD934X_HPH_PA_CTL2, + 0x40, 0x00); + snd_soc_component_update_bits(component, WCD934X_HPH_R_ATEST, + 0x02, 0x00); z1Ls /= 1000; - tavil_wcd_mbhc_qfuse_cal(codec, &z1Ls, 0); + tavil_wcd_mbhc_qfuse_cal(component, &z1Ls, 0); /* Parallel of left Z and 9 ohm pull down resistor */ zMono = ((*zl) * 9) / ((*zl) + 9); z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls); z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl)); if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) { - dev_dbg(codec->dev, "%s: stereo plug type detected\n", + dev_dbg(component->dev, "%s: stereo plug type detected\n", __func__); mbhc->hph_type = WCD_MBHC_HPH_STEREO; } else { - dev_dbg(codec->dev, "%s: MONO plug type detected\n", + dev_dbg(component->dev, "%s: MONO plug type detected\n", __func__); mbhc->hph_type = WCD_MBHC_HPH_MONO; } zdet_complete: - snd_soc_write(codec, WCD934X_ANA_MBHC_BTN5, reg0); - snd_soc_write(codec, WCD934X_ANA_MBHC_BTN6, reg1); - snd_soc_write(codec, WCD934X_ANA_MBHC_BTN7, reg2); + snd_soc_component_write(component, WCD934X_ANA_MBHC_BTN5, reg0); + snd_soc_component_write(component, WCD934X_ANA_MBHC_BTN6, reg1); + snd_soc_component_write(component, WCD934X_ANA_MBHC_BTN7, reg2); /* Turn on 100k pull down on HPHL */ regmap_update_bits(wcd9xxx->regmap, WCD934X_ANA_MBHC_MECH, 0x01, 0x01); @@ -748,96 +763,99 @@ static void tavil_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, regmap_update_bits(wcd9xxx->regmap, WCD934X_ANA_MBHC_MECH, 0x80, 0x80); - snd_soc_write(codec, WCD934X_MBHC_NEW_ZDET_ANA_CTL, reg4); - snd_soc_write(codec, WCD934X_MBHC_CTL_CLK, reg3); + snd_soc_component_write(component, WCD934X_MBHC_NEW_ZDET_ANA_CTL, reg4); + snd_soc_component_write(component, WCD934X_MBHC_CTL_CLK, reg3); if (is_fsm_disable) regmap_update_bits(wcd9xxx->regmap, WCD934X_ANA_MBHC_ELECT, 0x80, 0x80); } -static void tavil_mbhc_gnd_det_ctrl(struct snd_soc_codec *codec, bool enable) +static void tavil_mbhc_gnd_det_ctrl(struct snd_soc_component *component, + bool enable) { if (enable) { - snd_soc_update_bits(codec, WCD934X_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, WCD934X_ANA_MBHC_MECH, 0x02, 0x02); - snd_soc_update_bits(codec, WCD934X_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, WCD934X_ANA_MBHC_MECH, 0x40, 0x40); } else { - snd_soc_update_bits(codec, WCD934X_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, WCD934X_ANA_MBHC_MECH, 0x40, 0x00); - snd_soc_update_bits(codec, WCD934X_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, WCD934X_ANA_MBHC_MECH, 0x02, 0x00); } } -static void tavil_mbhc_hph_pull_down_ctrl(struct snd_soc_codec *codec, +static void tavil_mbhc_hph_pull_down_ctrl(struct snd_soc_component *component, bool enable) { if (enable) { - snd_soc_update_bits(codec, WCD934X_HPH_PA_CTL2, + snd_soc_component_update_bits(component, WCD934X_HPH_PA_CTL2, 0x40, 0x40); - snd_soc_update_bits(codec, WCD934X_HPH_PA_CTL2, + snd_soc_component_update_bits(component, WCD934X_HPH_PA_CTL2, 0x10, 0x10); } else { - snd_soc_update_bits(codec, WCD934X_HPH_PA_CTL2, + snd_soc_component_update_bits(component, WCD934X_HPH_PA_CTL2, 0x40, 0x00); - snd_soc_update_bits(codec, WCD934X_HPH_PA_CTL2, + snd_soc_component_update_bits(component, WCD934X_HPH_PA_CTL2, 0x10, 0x00); } } static void tavil_mbhc_moisture_config(struct wcd_mbhc *mbhc) { - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; if ((mbhc->moist_rref == R_OFF) || (mbhc->mbhc_cfg->enable_usbc_analog)) { - snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_2, + snd_soc_component_update_bits(component, WCD934X_MBHC_NEW_CTL_2, 0x0C, R_OFF << 2); return; } /* Donot enable moisture detection if jack type is NC */ if (!mbhc->hphl_swh) { - dev_dbg(codec->dev, "%s: disable moisture detection for NC\n", + dev_dbg(component->dev, "%s: disable moisture detection for NC\n", __func__); - snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_2, + snd_soc_component_update_bits(component, WCD934X_MBHC_NEW_CTL_2, 0x0C, R_OFF << 2); return; } - snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_2, + snd_soc_component_update_bits(component, WCD934X_MBHC_NEW_CTL_2, 0x0C, mbhc->moist_rref << 2); } static bool tavil_hph_register_recovery(struct wcd_mbhc *mbhc) { - struct snd_soc_codec *codec = mbhc->codec; - struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(codec); + struct snd_soc_component *component = mbhc->component; + struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(component); if (!wcd934x_mbhc) return false; wcd934x_mbhc->is_hph_recover = false; - snd_soc_dapm_force_enable_pin(snd_soc_codec_get_dapm(codec), + snd_soc_dapm_force_enable_pin(snd_soc_component_get_dapm(component), "RESET_HPH_REGISTERS"); - snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + snd_soc_dapm_sync(snd_soc_component_get_dapm(component)); - snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(codec), + snd_soc_dapm_disable_pin(snd_soc_component_get_dapm(component), "RESET_HPH_REGISTERS"); - snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + snd_soc_dapm_sync(snd_soc_component_get_dapm(component)); return wcd934x_mbhc->is_hph_recover; } -static void tavil_update_anc_state(struct snd_soc_codec *codec, bool enable, - int anc_num) +static void tavil_update_anc_state(struct snd_soc_component *component, + bool enable, int anc_num) { if (enable) - snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CFG0 + - (20 * anc_num), 0x10, 0x10); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num), + 0x10, 0x10); else - snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CFG0 + - (20 * anc_num), 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num), + 0x10, 0x00); } static bool tavil_is_anc_on(struct wcd_mbhc *mbhc) @@ -846,9 +864,11 @@ static bool tavil_is_anc_on(struct wcd_mbhc *mbhc) u16 ancl, ancr; ancl = - (snd_soc_read(mbhc->codec, WCD934X_CDC_RX1_RX_PATH_CFG0)) & 0x10; + (snd_soc_component_read32( + mbhc->component, WCD934X_CDC_RX1_RX_PATH_CFG0)) & 0x10; ancr = - (snd_soc_read(mbhc->codec, WCD934X_CDC_RX2_RX_PATH_CFG0)) & 0x10; + (snd_soc_component_read32( + mbhc->component, WCD934X_CDC_RX2_RX_PATH_CFG0)) & 0x10; anc_on = !!(ancl | ancr); @@ -883,11 +903,11 @@ static const struct wcd_mbhc_cb mbhc_cb = { }; static struct regulator *tavil_codec_find_ondemand_regulator( - struct snd_soc_codec *codec, const char *name) + struct snd_soc_component *component, const char *name) { int i; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); - struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); + struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent); for (i = 0; i < wcd9xxx->num_of_supplies; ++i) { if (pdata->regulator[i].ondemand && @@ -896,7 +916,7 @@ static struct regulator *tavil_codec_find_ondemand_regulator( return wcd9xxx->supplies[i].consumer; } - dev_dbg(codec->dev, "Warning: regulator not found:%s\n", + dev_dbg(component->dev, "Warning: regulator not found:%s\n", name); return NULL; } @@ -904,19 +924,22 @@ static struct regulator *tavil_codec_find_ondemand_regulator( static int tavil_get_hph_type(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(component); struct wcd_mbhc *mbhc; if (!wcd934x_mbhc) { - dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + dev_err(component->dev, "%s: mbhc not initialized!\n", + __func__); return -EINVAL; } mbhc = &wcd934x_mbhc->wcd_mbhc; ucontrol->value.integer.value[0] = (u32) mbhc->hph_type; - dev_dbg(codec->dev, "%s: hph_type = %u\n", __func__, mbhc->hph_type); + dev_dbg(component->dev, "%s: hph_type = %u\n", __func__, + mbhc->hph_type); return 0; } @@ -927,18 +950,21 @@ static int tavil_hph_impedance_get(struct snd_kcontrol *kcontrol, uint32_t zl, zr; bool hphr; struct soc_multi_mixer_control *mc; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(component); if (!wcd934x_mbhc) { - dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + dev_err(component->dev, "%s: mbhc not initialized!\n", + __func__); return -EINVAL; } mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); hphr = mc->shift; wcd_mbhc_get_impedance(&wcd934x_mbhc->wcd_mbhc, &zl, &zr); - dev_dbg(codec->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr); + dev_dbg(component->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, + zl, zr); ucontrol->value.integer.value[0] = hphr ? zr : zl; return 0; @@ -981,17 +1007,18 @@ EXPORT_SYMBOL(tavil_mbhc_get_impedance); /* * tavil_mbhc_hs_detect: starts mbhc insertion/removal functionality - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * * @mbhc_cfg: handle to mbhc configuration structure * return 0 if mbhc_start is success or error code in case of failure */ -int tavil_mbhc_hs_detect(struct snd_soc_codec *codec, +int tavil_mbhc_hs_detect(struct snd_soc_component *component, struct wcd_mbhc_config *mbhc_cfg) { - struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(codec); + struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(component); if (!wcd934x_mbhc) { - dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + dev_err(component->dev, "%s: mbhc not initialized!\n", + __func__); return -EINVAL; } @@ -1001,14 +1028,15 @@ EXPORT_SYMBOL(tavil_mbhc_hs_detect); /* * tavil_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * */ -void tavil_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +void tavil_mbhc_hs_detect_exit(struct snd_soc_component *component) { - struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(codec); + struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(component); if (!wcd934x_mbhc) { - dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + dev_err(component->dev, "%s: mbhc not initialized!\n", + __func__); return; } wcd_mbhc_stop(&wcd934x_mbhc->wcd_mbhc); @@ -1018,17 +1046,17 @@ EXPORT_SYMBOL(tavil_mbhc_hs_detect_exit); /* * tavil_mbhc_post_ssr_init: initialize mbhc for tavil post subsystem restart * @mbhc: poniter to wcd934x_mbhc structure - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * * * return 0 if mbhc_init is success or error code in case of failure */ int tavil_mbhc_post_ssr_init(struct wcd934x_mbhc *mbhc, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { int ret; struct wcd_mbhc *wcd_mbhc; - if (!mbhc || !codec) + if (!mbhc || !component) return -EINVAL; wcd_mbhc = &mbhc->wcd_mbhc; @@ -1037,18 +1065,20 @@ int tavil_mbhc_post_ssr_init(struct wcd934x_mbhc *mbhc, return -EINVAL; } - tavil_mbhc_hs_detect_exit(codec); + tavil_mbhc_hs_detect_exit(component); wcd_mbhc_deinit(wcd_mbhc); - ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids, + ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb, &intr_ids, wcd_mbhc_registers, TAVIL_ZDET_SUPPORTED); if (ret) { - dev_err(codec->dev, "%s: mbhc initialization failed\n", + dev_err(component->dev, "%s: mbhc initialization failed\n", __func__); goto done; } if (wcd_mbhc->mbhc_detection_logic == WCD_DETECTION_LEGACY) { - snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_1, 0x04, 0x04); - snd_soc_update_bits(codec, WCD934X_MBHC_CTL_BCS, 0x01, 0x01); + snd_soc_component_update_bits(component, WCD934X_MBHC_NEW_CTL_1, + 0x04, 0x04); + snd_soc_component_update_bits(component, WCD934X_MBHC_CTL_BCS, + 0x01, 0x01); } done: @@ -1059,12 +1089,13 @@ EXPORT_SYMBOL(tavil_mbhc_post_ssr_init); /* * tavil_mbhc_init: initialize mbhc for tavil * @mbhc: poniter to wcd934x_mbhc struct pointer to store the configs - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * * @fw_data: handle to firmware data * * return 0 if mbhc_init is success or error code in case of failure */ -int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, struct snd_soc_codec *codec, +int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, + struct snd_soc_component *component, struct fw_info *fw_data) { struct regulator *supply; @@ -1072,12 +1103,12 @@ int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, struct snd_soc_codec *codec, struct wcd_mbhc *wcd_mbhc; int ret; - wcd934x_mbhc = devm_kzalloc(codec->dev, sizeof(struct wcd934x_mbhc), + wcd934x_mbhc = devm_kzalloc(component->dev, sizeof(struct wcd934x_mbhc), GFP_KERNEL); if (!wcd934x_mbhc) return -ENOMEM; - wcd934x_mbhc->wcd9xxx = dev_get_drvdata(codec->dev->parent); + wcd934x_mbhc->wcd9xxx = dev_get_drvdata(component->dev->parent); wcd934x_mbhc->fw_data = fw_data; BLOCKING_INIT_NOTIFIER_HEAD(&wcd934x_mbhc->notifier); wcd_mbhc = &wcd934x_mbhc->wcd_mbhc; @@ -1091,16 +1122,16 @@ int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, struct snd_soc_codec *codec, /* Setting default mbhc detection logic to ADC for Tavil */ wcd_mbhc->mbhc_detection_logic = WCD_DETECTION_ADC; - ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, + ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb, &intr_ids, wcd_mbhc_registers, TAVIL_ZDET_SUPPORTED); if (ret) { - dev_err(codec->dev, "%s: mbhc initialization failed\n", + dev_err(component->dev, "%s: mbhc initialization failed\n", __func__); goto err; } - supply = tavil_codec_find_ondemand_regulator(codec, + supply = tavil_codec_find_ondemand_regulator(component, on_demand_supply_name[WCD934X_ON_DEMAND_MICBIAS]); if (supply) { wcd934x_mbhc->on_demand_list[ @@ -1112,34 +1143,36 @@ int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, struct snd_soc_codec *codec, } (*mbhc) = wcd934x_mbhc; - snd_soc_add_codec_controls(codec, impedance_detect_controls, + snd_soc_add_component_controls(component, impedance_detect_controls, ARRAY_SIZE(impedance_detect_controls)); - snd_soc_add_codec_controls(codec, hph_type_detect_controls, + snd_soc_add_component_controls(component, hph_type_detect_controls, ARRAY_SIZE(hph_type_detect_controls)); if (wcd_mbhc->mbhc_detection_logic == WCD_DETECTION_LEGACY) { - snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_1, 0x04, 0x04); - snd_soc_update_bits(codec, WCD934X_MBHC_CTL_BCS, 0x01, 0x01); + snd_soc_component_update_bits(component, WCD934X_MBHC_NEW_CTL_1, + 0x04, 0x04); + snd_soc_component_update_bits(component, WCD934X_MBHC_CTL_BCS, + 0x01, 0x01); } return 0; err: - devm_kfree(codec->dev, wcd934x_mbhc); + devm_kfree(component->dev, wcd934x_mbhc); return ret; } EXPORT_SYMBOL(tavil_mbhc_init); /* * tavil_mbhc_deinit: deinitialize mbhc for tavil - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * */ -void tavil_mbhc_deinit(struct snd_soc_codec *codec) +void tavil_mbhc_deinit(struct snd_soc_component *component) { - struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(codec); + struct wcd934x_mbhc *wcd934x_mbhc = tavil_soc_get_mbhc(component); if (wcd934x_mbhc) { wcd_mbhc_deinit(&wcd934x_mbhc->wcd_mbhc); - devm_kfree(codec->dev, wcd934x_mbhc); + devm_kfree(component->dev, wcd934x_mbhc); } } EXPORT_SYMBOL(tavil_mbhc_deinit); diff --git a/asoc/codecs/wcd934x/wcd934x-mbhc.h b/asoc/codecs/wcd934x/wcd934x-mbhc.h index 07e6207d7495..69cd46033678 100644 --- a/asoc/codecs/wcd934x/wcd934x-mbhc.h +++ b/asoc/codecs/wcd934x/wcd934x-mbhc.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #ifndef __WCD934X_MBHC_H__ #define __WCD934X_MBHC_H__ @@ -29,36 +29,37 @@ struct wcd934x_mbhc { #if IS_ENABLED(CONFIG_SND_SOC_WCD934X_MBHC) extern int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, - struct snd_soc_codec *codec, + struct snd_soc_component *component, struct fw_info *fw_data); -extern void tavil_mbhc_hs_detect_exit(struct snd_soc_codec *codec); -extern int tavil_mbhc_hs_detect(struct snd_soc_codec *codec, +extern void tavil_mbhc_hs_detect_exit(struct snd_soc_component *component); +extern int tavil_mbhc_hs_detect(struct snd_soc_component *component, struct wcd_mbhc_config *mbhc_cfg); -extern void tavil_mbhc_deinit(struct snd_soc_codec *codec); +extern void tavil_mbhc_deinit(struct snd_soc_component *component); extern int tavil_mbhc_post_ssr_init(struct wcd934x_mbhc *mbhc, - struct snd_soc_codec *codec); + struct snd_soc_component *component); extern int tavil_mbhc_get_impedance(struct wcd934x_mbhc *wcd934x_mbhc, uint32_t *zl, uint32_t *zr); #else static inline int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, - struct snd_soc_codec *codec, + struct snd_soc_component *component, struct fw_info *fw_data) { return 0; } -static inline void tavil_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +static inline void tavil_mbhc_hs_detect_exit( + struct snd_soc_component *component) { } -static inline int tavil_mbhc_hs_detect(struct snd_soc_codec *codec, +static inline int tavil_mbhc_hs_detect(struct snd_soc_component *component, struct wcd_mbhc_config *mbhc_cfg) { return 0; } -static inline void tavil_mbhc_deinit(struct snd_soc_codec *codec) +static inline void tavil_mbhc_deinit(struct snd_soc_component *component) { } static inline int tavil_mbhc_post_ssr_init(struct wcd934x_mbhc *mbhc, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { return 0; } diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 71a680622ea4..d930ec83ad21 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -43,6 +43,8 @@ #include "../wcdcal-hwdep.h" #include "wcd934x-dsd.h" +#define DRV_NAME "tavil_codec" + #define WCD934X_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\ @@ -485,7 +487,7 @@ static int tx_unmute_delay = WCD934X_TX_UNMUTE_DELAY_MS; module_param(tx_unmute_delay, int, 0664); MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path"); -static void tavil_codec_set_tx_hold(struct snd_soc_codec *, u16, bool); +static void tavil_codec_set_tx_hold(struct snd_soc_component *, u16, bool); /* Hold instance to soundwire platform device */ struct tavil_swr_ctrl_data { @@ -543,7 +545,7 @@ struct hpf_work { struct tavil_priv { struct device *dev; struct wcd9xxx *wcd9xxx; - struct snd_soc_codec *codec; + struct snd_soc_component *component; u32 rx_bias_count; s32 dmic_0_1_clk_cnt; s32 dmic_2_3_clk_cnt; @@ -661,14 +663,14 @@ static int __tavil_enable_efuse_sensing(struct tavil_priv *tavil); * tavil_set_spkr_gain_offset - offset the speaker path * gain with the given offset value. * - * @codec: codec instance + * @component: codec component instance * @offset: Indicates speaker path gain offset value. * * Returns 0 on success or -EINVAL on error. */ -int tavil_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset) +int tavil_set_spkr_gain_offset(struct snd_soc_component *component, int offset) { - struct tavil_priv *priv = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *priv = snd_soc_component_get_drvdata(component); if (!priv) return -EINVAL; @@ -682,14 +684,14 @@ EXPORT_SYMBOL(tavil_set_spkr_gain_offset); * tavil_set_spkr_mode - Configures speaker compander and smartboost * settings based on speaker mode. * - * @codec: codec instance + * @component: codec component instance * @mode: Indicates speaker configuration mode. * * Returns 0 on success or -EINVAL on error. */ -int tavil_set_spkr_mode(struct snd_soc_codec *codec, int mode) +int tavil_set_spkr_mode(struct snd_soc_component *component, int mode) { - struct tavil_priv *priv = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *priv = snd_soc_component_get_drvdata(component); int i; const struct tavil_reg_mask_val *regs; int size; @@ -710,7 +712,7 @@ int tavil_set_spkr_mode(struct snd_soc_codec *codec, int mode) priv->swr.spkr_mode = mode; for (i = 0; i < size; i++) - snd_soc_update_bits(codec, regs[i].reg, + snd_soc_component_update_bits(component, regs[i].reg, regs[i].mask, regs[i].val); return 0; } @@ -719,13 +721,13 @@ EXPORT_SYMBOL(tavil_set_spkr_mode); /** * tavil_get_afe_config - returns specific codec configuration to afe to write * - * @codec: codec instance + * @component: codec component instance * @config_type: Indicates type of configuration to write. */ -void *tavil_get_afe_config(struct snd_soc_codec *codec, +void *tavil_get_afe_config(struct snd_soc_component *component, enum afe_config_type config_type) { - struct tavil_priv *priv = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *priv = snd_soc_component_get_drvdata(component); switch (config_type) { case AFE_SLIMBUS_SLAVE_CONFIG: @@ -739,7 +741,7 @@ void *tavil_get_afe_config(struct snd_soc_codec *codec, case AFE_CDC_REGISTER_PAGE_CONFIG: return &tavil_cdc_reg_page_cfg; default: - dev_info(codec->dev, "%s: Unknown config_type 0x%x\n", + dev_info(component->dev, "%s: Unknown config_type 0x%x\n", __func__, config_type); return NULL; } @@ -810,8 +812,9 @@ static void tavil_vote_svs(struct tavil_priv *tavil, bool vote) static int tavil_get_anc_slot(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = tavil->anc_slot; return 0; @@ -820,8 +823,9 @@ static int tavil_get_anc_slot(struct snd_kcontrol *kcontrol, static int tavil_put_anc_slot(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); tavil->anc_slot = ucontrol->value.integer.value[0]; return 0; @@ -830,8 +834,9 @@ static int tavil_put_anc_slot(struct snd_kcontrol *kcontrol, static int tavil_get_anc_func(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = (tavil->anc_func == true ? 1 : 0); return 0; @@ -840,13 +845,15 @@ static int tavil_get_anc_func(struct snd_kcontrol *kcontrol, static int tavil_put_anc_func(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); mutex_lock(&tavil->codec_mutex); tavil->anc_func = (!ucontrol->value.integer.value[0] ? false : true); - dev_dbg(codec->dev, "%s: anc_func %x", __func__, tavil->anc_func); + dev_dbg(component->dev, "%s: anc_func %x", __func__, tavil->anc_func); if (tavil->anc_func == true) { snd_soc_dapm_enable_pin(dapm, "ANC EAR PA"); @@ -886,8 +893,9 @@ static int tavil_put_anc_func(struct snd_kcontrol *kcontrol, static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); const char *filename; const struct firmware *fw; int i; @@ -912,28 +920,28 @@ static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w, if (hwdep_cal) { data = hwdep_cal->data; cal_size = hwdep_cal->size; - dev_dbg(codec->dev, "%s: using hwdep calibration, cal_size %zd", + dev_dbg(component->dev, "%s: using hwdep calibration, cal_size %zd", __func__, cal_size); } else { filename = "WCD934X/WCD934X_anc.bin"; - ret = request_firmware(&fw, filename, codec->dev); + ret = request_firmware(&fw, filename, component->dev); if (ret < 0) { - dev_err(codec->dev, "%s: Failed to acquire ANC data: %d\n", + dev_err(component->dev, "%s: Failed to acquire ANC data: %d\n", __func__, ret); return ret; } if (!fw) { - dev_err(codec->dev, "%s: Failed to get anc fw\n", + dev_err(component->dev, "%s: Failed to get anc fw\n", __func__); return -ENODEV; } data = fw->data; cal_size = fw->size; - dev_dbg(codec->dev, "%s: using request_firmware calibration\n", + dev_dbg(component->dev, "%s: using request_firmware calibration\n", __func__); } if (cal_size < sizeof(struct wcd9xxx_anc_header)) { - dev_err(codec->dev, "%s: Invalid cal_size %zd\n", + dev_err(component->dev, "%s: Invalid cal_size %zd\n", __func__, cal_size); ret = -EINVAL; goto err; @@ -946,14 +954,14 @@ static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w, num_anc_slots = anc_head->num_anc_slots; if (tavil->anc_slot >= num_anc_slots) { - dev_err(codec->dev, "%s: Invalid ANC slot selected\n", + dev_err(component->dev, "%s: Invalid ANC slot selected\n", __func__); ret = -EINVAL; goto err; } for (i = 0; i < num_anc_slots; i++) { if (anc_size_remaining < WCD934X_PACKED_REG_SIZE) { - dev_err(codec->dev, "%s: Invalid register format\n", + dev_err(component->dev, "%s: Invalid register format\n", __func__); ret = -EINVAL; goto err; @@ -964,7 +972,7 @@ static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w, if ((anc_writes_size * WCD934X_PACKED_REG_SIZE) > anc_size_remaining) { - dev_err(codec->dev, "%s: Invalid register format\n", + dev_err(component->dev, "%s: Invalid register format\n", __func__); ret = -EINVAL; goto err; @@ -978,7 +986,7 @@ static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w, anc_ptr += anc_writes_size; } if (i == num_anc_slots) { - dev_err(codec->dev, "%s: Selected ANC slot not present\n", + dev_err(component->dev, "%s: Selected ANC slot not present\n", __func__); ret = -EINVAL; goto err; @@ -995,34 +1003,34 @@ static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w, for (; i < anc_writes_size; i++) { WCD934X_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val); - snd_soc_write(codec, reg, (val & mask)); + snd_soc_component_write(component, reg, (val & mask)); } /* Rate converter clk enable and set bypass mode */ if (!strcmp(w->name, "RX INT0 DAC") || !strcmp(w->name, "RX INT1 DAC") || !strcmp(w->name, "ANC SPK1 PA")) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_ANC0_RC_COMMON_CTL, 0x05, 0x05); if (!strcmp(w->name, "RX INT1 DAC")) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_ANC0_FIFO_COMMON_CTL, 0x66, 0x66); } } else if (!strcmp(w->name, "RX INT2 DAC")) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_ANC1_RC_COMMON_CTL, 0x05, 0x05); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_ANC1_FIFO_COMMON_CTL, 0x66, 0x66); } if (!strcmp(w->name, "RX INT1 DAC")) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x08); else if (!strcmp(w->name, "RX INT2 DAC")) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x08); if (!hwdep_cal) @@ -1033,10 +1041,10 @@ static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w, if (!strcmp(w->name, "ANC HPHL PA") || !strcmp(w->name, "ANC HPHR PA")) { /* Remove ANC Rx from reset */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x00); } @@ -1044,40 +1052,45 @@ static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, WCD934X_CDC_ANC0_RC_COMMON_CTL, - 0x05, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_ANC0_RC_COMMON_CTL, + 0x05, 0x00); if (!strcmp(w->name, "ANC EAR PA") || !strcmp(w->name, "ANC SPK1 PA") || !strcmp(w->name, "ANC HPHL PA")) { - snd_soc_update_bits(codec, WCD934X_CDC_ANC0_MODE_1_CTL, - 0x30, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_ANC0_MODE_1_CTL, + 0x30, 0x00); msleep(50); - snd_soc_update_bits(codec, WCD934X_CDC_ANC0_MODE_1_CTL, - 0x01, 0x00); - snd_soc_update_bits(codec, - WCD934X_CDC_ANC0_CLK_RESET_CTL, - 0x38, 0x38); - snd_soc_update_bits(codec, - WCD934X_CDC_ANC0_CLK_RESET_CTL, - 0x07, 0x00); - snd_soc_update_bits(codec, - WCD934X_CDC_ANC0_CLK_RESET_CTL, - 0x38, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_ANC0_MODE_1_CTL, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_ANC0_CLK_RESET_CTL, + 0x38, 0x38); + snd_soc_component_update_bits(component, + WCD934X_CDC_ANC0_CLK_RESET_CTL, + 0x07, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_ANC0_CLK_RESET_CTL, + 0x38, 0x00); } else if (!strcmp(w->name, "ANC HPHR PA")) { - snd_soc_update_bits(codec, WCD934X_CDC_ANC1_MODE_1_CTL, - 0x30, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_ANC1_MODE_1_CTL, + 0x30, 0x00); msleep(50); - snd_soc_update_bits(codec, WCD934X_CDC_ANC1_MODE_1_CTL, - 0x01, 0x00); - snd_soc_update_bits(codec, - WCD934X_CDC_ANC1_CLK_RESET_CTL, - 0x38, 0x38); - snd_soc_update_bits(codec, - WCD934X_CDC_ANC1_CLK_RESET_CTL, - 0x07, 0x00); - snd_soc_update_bits(codec, - WCD934X_CDC_ANC1_CLK_RESET_CTL, - 0x38, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_ANC1_MODE_1_CTL, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_ANC1_CLK_RESET_CTL, + 0x38, 0x38); + snd_soc_component_update_bits(component, + WCD934X_CDC_ANC1_CLK_RESET_CTL, + 0x07, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_ANC1_CLK_RESET_CTL, + 0x38, 0x00); } break; } @@ -1092,15 +1105,16 @@ static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w, static int tavil_get_clkmode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); if (test_bit(CLK_MODE, &tavil_p->status_mask)) ucontrol->value.enumerated.item[0] = 1; else ucontrol->value.enumerated.item[0] = 0; - dev_dbg(codec->dev, "%s: is_low_power_clock: %s\n", __func__, + dev_dbg(component->dev, "%s: is_low_power_clock: %s\n", __func__, test_bit(CLK_MODE, &tavil_p->status_mask) ? "true" : "false"); return 0; @@ -1109,15 +1123,16 @@ static int tavil_get_clkmode(struct snd_kcontrol *kcontrol, static int tavil_put_clkmode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); if (ucontrol->value.enumerated.item[0]) set_bit(CLK_MODE, &tavil_p->status_mask); else clear_bit(CLK_MODE, &tavil_p->status_mask); - dev_dbg(codec->dev, "%s: is_low_power_clock: %s\n", __func__, + dev_dbg(component->dev, "%s: is_low_power_clock: %s\n", __func__, test_bit(CLK_MODE, &tavil_p->status_mask) ? "true" : "false"); return 0; @@ -1128,8 +1143,9 @@ static int tavil_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = tavil_p->vi_feed_value; @@ -1141,16 +1157,17 @@ static int tavil_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); + struct wcd9xxx *core = dev_get_drvdata(component->dev->parent); struct soc_multi_mixer_control *mixer = ((struct soc_multi_mixer_control *)kcontrol->private_value); u32 dai_id = widget->shift; u32 port_id = mixer->shift; u32 enable = ucontrol->value.integer.value[0]; - dev_dbg(codec->dev, "%s: enable: %d, port_id:%d, dai_id: %d\n", + dev_dbg(component->dev, "%s: enable: %d, port_id:%d, dai_id: %d\n", __func__, enable, port_id, dai_id); tavil_p->vi_feed_value = ucontrol->value.integer.value[0]; @@ -1191,9 +1208,10 @@ static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = tavil_p->tx_port_value; return 0; @@ -1203,10 +1221,11 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); + struct wcd9xxx *core = dev_get_drvdata(component->dev->parent); struct snd_soc_dapm_update *update = NULL; struct soc_multi_mixer_control *mixer = ((struct soc_multi_mixer_control *)kcontrol->private_value); @@ -1215,14 +1234,14 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, u32 enable = ucontrol->value.integer.value[0]; u32 vtable; - dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", + dev_dbg(component->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", __func__, widget->name, ucontrol->id.name, tavil_p->tx_port_value, widget->shift, ucontrol->value.integer.value[0]); mutex_lock(&tavil_p->codec_mutex); if (dai_id >= ARRAY_SIZE(vport_slim_check_table)) { - dev_err(codec->dev, "%s: dai_id: %d, out of bounds\n", + dev_err(component->dev, "%s: dai_id: %d, out of bounds\n", __func__, dai_id); mutex_unlock(&tavil_p->codec_mutex); return -EINVAL; @@ -1237,7 +1256,7 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, if (enable && !(tavil_p->tx_port_value & 1 << port_id)) { if (wcd9xxx_tx_vport_validation(vtable, port_id, tavil_p->dai, NUM_CODEC_DAIS)) { - dev_dbg(codec->dev, "%s: TX%u is used by other virtual port\n", + dev_dbg(component->dev, "%s: TX%u is used by other virtual port\n", __func__, port_id); mutex_unlock(&tavil_p->codec_mutex); return 0; @@ -1251,11 +1270,11 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, list_del_init(&core->tx_chs[port_id].list); } else { if (enable) - dev_dbg(codec->dev, "%s: TX%u port is used by\n" + dev_dbg(component->dev, "%s: TX%u port is used by\n" "this virtual port\n", __func__, port_id); else - dev_dbg(codec->dev, "%s: TX%u port is not used by\n" + dev_dbg(component->dev, "%s: TX%u port is not used by\n" "this virtual port\n", __func__, port_id); /* avoid update power function */ @@ -1266,11 +1285,11 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol, case AIF4_MAD_TX: break; default: - dev_err(codec->dev, "Unknown AIF %d\n", dai_id); + dev_err(component->dev, "Unknown AIF %d\n", dai_id); mutex_unlock(&tavil_p->codec_mutex); return -EINVAL; } - dev_dbg(codec->dev, "%s: name %s sname %s updated value %u shift %d\n", + dev_dbg(component->dev, "%s: name %s sname %s updated value %u shift %d\n", __func__, widget->name, widget->sname, tavil_p->tx_port_value, widget->shift); @@ -1285,8 +1304,9 @@ static int i2s_tx_mixer_get(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = tavil_p->tx_port_value; return 0; @@ -1297,8 +1317,9 @@ static int i2s_tx_mixer_put(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); struct snd_soc_dapm_update *update = NULL; struct soc_multi_mixer_control *mixer = (struct soc_multi_mixer_control *)kcontrol->private_value; @@ -1307,14 +1328,14 @@ static int i2s_tx_mixer_put(struct snd_kcontrol *kcontrol, u32 enable = ucontrol->value.integer.value[0]; u32 vtable; - dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", + dev_dbg(component->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", __func__, widget->name, ucontrol->id.name, tavil_p->tx_port_value, widget->shift, ucontrol->value.integer.value[0]); mutex_lock(&tavil_p->codec_mutex); if (dai_id >= ARRAY_SIZE(vport_slim_check_table)) { - dev_err(codec->dev, "%s: dai_id: %d, out of bounds\n", + dev_err(component->dev, "%s: dai_id: %d, out of bounds\n", __func__, dai_id); mutex_unlock(&tavil_p->codec_mutex); return -EINVAL; @@ -1329,7 +1350,7 @@ static int i2s_tx_mixer_put(struct snd_kcontrol *kcontrol, if (enable && !(tavil_p->tx_port_value & 1 << port_id)) { if (wcd9xxx_tx_vport_validation(vtable, port_id, tavil_p->dai, NUM_CODEC_DAIS)) { - dev_dbg(codec->dev, "%s: TX%u is used by other virtual port\n", + dev_dbg(component->dev, "%s: TX%u is used by other virtual port\n", __func__, port_id); mutex_unlock(&tavil_p->codec_mutex); return 0; @@ -1340,11 +1361,11 @@ static int i2s_tx_mixer_put(struct snd_kcontrol *kcontrol, tavil_p->tx_port_value &= ~(1 << port_id); } else { if (enable) - dev_dbg(codec->dev, "%s: TX%u port is used by\n" + dev_dbg(component->dev, "%s: TX%u port is used by\n" "this virtual port\n", __func__, port_id); else - dev_dbg(codec->dev, "%s: TX%u port is not used by\n" + dev_dbg(component->dev, "%s: TX%u port is not used by\n" "this virtual port\n", __func__, port_id); /* avoid update power function */ @@ -1353,11 +1374,11 @@ static int i2s_tx_mixer_put(struct snd_kcontrol *kcontrol, } break; default: - dev_err(codec->dev, "Unknown AIF %d\n", dai_id); + dev_err(component->dev, "Unknown AIF %d\n", dai_id); mutex_unlock(&tavil_p->codec_mutex); return -EINVAL; } - dev_dbg(codec->dev, "%s: name %s sname %s updated value %u shift %d\n", + dev_dbg(component->dev, "%s: name %s sname %s updated value %u shift %d\n", __func__, widget->name, widget->sname, tavil_p->tx_port_value, widget->shift); @@ -1372,8 +1393,9 @@ static int slim_rx_mux_get(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); ucontrol->value.enumerated.item[0] = tavil_p->rx_port_value[widget->shift]; @@ -1385,9 +1407,10 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); + struct wcd9xxx *core = dev_get_drvdata(component->dev->parent); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct snd_soc_dapm_update *update = NULL; unsigned int rx_port_value; @@ -1397,7 +1420,7 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, rx_port_value = tavil_p->rx_port_value[port_id]; mutex_lock(&tavil_p->codec_mutex); - dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", + dev_dbg(component->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", __func__, widget->name, ucontrol->id.name, rx_port_value, widget->shift, ucontrol->value.integer.value[0]); @@ -1411,7 +1434,7 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, if (wcd9xxx_rx_vport_validation(port_id + WCD934X_RX_PORT_START_NUMBER, &tavil_p->dai[AIF1_PB].wcd9xxx_ch_list)) { - dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + dev_dbg(component->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", __func__, port_id); goto rtn; } @@ -1422,7 +1445,7 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, if (wcd9xxx_rx_vport_validation(port_id + WCD934X_RX_PORT_START_NUMBER, &tavil_p->dai[AIF2_PB].wcd9xxx_ch_list)) { - dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + dev_dbg(component->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", __func__, port_id); goto rtn; } @@ -1433,7 +1456,7 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, if (wcd9xxx_rx_vport_validation(port_id + WCD934X_RX_PORT_START_NUMBER, &tavil_p->dai[AIF3_PB].wcd9xxx_ch_list)) { - dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + dev_dbg(component->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", __func__, port_id); goto rtn; } @@ -1444,7 +1467,7 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, if (wcd9xxx_rx_vport_validation(port_id + WCD934X_RX_PORT_START_NUMBER, &tavil_p->dai[AIF4_PB].wcd9xxx_ch_list)) { - dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", + dev_dbg(component->dev, "%s: RX%u is used by current requesting AIF_PB itself\n", __func__, port_id); goto rtn; } @@ -1452,7 +1475,7 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, &tavil_p->dai[AIF4_PB].wcd9xxx_ch_list); break; default: - dev_err(codec->dev, "Unknown AIF %d\n", rx_port_value); + dev_err(component->dev, "Unknown AIF %d\n", rx_port_value); goto err; } rtn: @@ -1468,7 +1491,7 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol, static void tavil_codec_enable_slim_port_intr( struct wcd9xxx_codec_dai_data *dai, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { struct wcd9xxx_ch *ch; int port_num = 0; @@ -1476,12 +1499,12 @@ static void tavil_codec_enable_slim_port_intr( u8 val = 0; struct tavil_priv *tavil_p; - if (!dai || !codec) { + if (!dai || !component) { pr_err("%s: Invalid params\n", __func__); return; } - tavil_p = snd_soc_codec_get_drvdata(codec); + tavil_p = snd_soc_component_get_drvdata(component); list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) { if (ch->port >= WCD934X_RX_PORT_START_NUMBER) { port_num = ch->port - WCD934X_RX_PORT_START_NUMBER; @@ -1543,7 +1566,7 @@ static int tavil_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai, return ret; } -static void tavil_codec_mute_dsd(struct snd_soc_codec *codec, +static void tavil_codec_mute_dsd(struct snd_soc_component *component, struct list_head *ch_list) { u8 dsd0_in; @@ -1551,8 +1574,10 @@ static void tavil_codec_mute_dsd(struct snd_soc_codec *codec, struct wcd9xxx_ch *ch; /* Read DSD Input Ports */ - dsd0_in = (snd_soc_read(codec, WCD934X_CDC_DSD0_CFG0) & 0x3C) >> 2; - dsd1_in = (snd_soc_read(codec, WCD934X_CDC_DSD1_CFG0) & 0x3C) >> 2; + dsd0_in = (snd_soc_component_read32( + component, WCD934X_CDC_DSD0_CFG0) & 0x3C) >> 2; + dsd1_in = (snd_soc_component_read32( + component, WCD934X_CDC_DSD1_CFG0) & 0x3C) >> 2; if ((dsd0_in == 0) && (dsd1_in == 0)) return; @@ -1563,11 +1588,13 @@ static void tavil_codec_mute_dsd(struct snd_soc_codec *codec, */ list_for_each_entry(ch, ch_list, list) { if (ch->port == (dsd0_in + WCD934X_RX_PORT_START_NUMBER - 1)) - snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, - 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD0_CFG2, + 0x04, 0x04); if (ch->port == (dsd1_in + WCD934X_RX_PORT_START_NUMBER - 1)) - snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, - 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD1_CFG2, + 0x04, 0x04); } } @@ -1576,8 +1603,9 @@ static int tavil_codec_set_i2s_rx_ch(struct snd_soc_dapm_widget *w, { int rx_fs_rate = -EINVAL; int i2s_bit_mode; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); struct wcd9xxx_codec_dai_data *dai; dai = &tavil_p->dai[w->shift]; @@ -1616,14 +1644,14 @@ static int tavil_codec_set_i2s_rx_ch(struct snd_soc_dapm_widget *w, __func__, dai->rate); return -EINVAL; }; - snd_soc_update_bits(codec, i2s_reg, + snd_soc_component_update_bits(component, i2s_reg, 0x40, i2s_bit_mode << 6); - snd_soc_update_bits(codec, i2s_reg, + snd_soc_component_update_bits(component, i2s_reg, 0x3c, (rx_fs_rate << 2)); } else { - snd_soc_update_bits(codec, i2s_reg, + snd_soc_component_update_bits(component, i2s_reg, 0x40, 0x00); - snd_soc_update_bits(codec, i2s_reg, + snd_soc_component_update_bits(component, i2s_reg, 0x3c, 0x00); } return 0; @@ -1634,8 +1662,9 @@ static int tavil_codec_set_i2s_tx_ch(struct snd_soc_dapm_widget *w, { int tx_fs_rate = -EINVAL; int i2s_bit_mode; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); struct wcd9xxx_codec_dai_data *dai; dai = &tavil_p->dai[w->shift]; @@ -1645,7 +1674,8 @@ static int tavil_codec_set_i2s_tx_ch(struct snd_soc_dapm_widget *w, else i2s_bit_mode = 0x00; - snd_soc_update_bits(codec, i2s_reg, 0x40, i2s_bit_mode << 6); + snd_soc_component_update_bits( + component, i2s_reg, 0x40, i2s_bit_mode << 6); switch (dai->rate) { case 8000: @@ -1675,40 +1705,41 @@ static int tavil_codec_set_i2s_tx_ch(struct snd_soc_dapm_widget *w, return -EINVAL; }; - snd_soc_update_bits(codec, i2s_reg, 0x3c, tx_fs_rate << 2); + snd_soc_component_update_bits( + component, i2s_reg, 0x3c, tx_fs_rate << 2); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_DATA_HUB_I2S_TX0_CFG, 0x03, 0x01); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_DATA_HUB_I2S_TX0_CFG, 0x0C, 0x01); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_DATA_HUB_I2S_TX1_0_CFG, 0x03, 0x01); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_DATA_HUB_I2S_TX1_1_CFG, 0x05, 0x05); } else { - snd_soc_update_bits(codec, i2s_reg, 0x40, 0x00); - snd_soc_update_bits(codec, i2s_reg, 0x3c, 0x00); + snd_soc_component_update_bits(component, i2s_reg, 0x40, 0x00); + snd_soc_component_update_bits(component, i2s_reg, 0x3c, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_DATA_HUB_I2S_TX0_CFG, 0x03, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_DATA_HUB_I2S_TX0_CFG, 0x0C, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_DATA_HUB_I2S_TX1_0_CFG, 0x03, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_DATA_HUB_I2S_TX1_1_CFG, 0x05, 0x00); } @@ -1719,8 +1750,9 @@ static int tavil_codec_enable_rx_i2c(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); int ret = -EINVAL; u32 i2s_reg; @@ -1738,7 +1770,7 @@ static int tavil_codec_enable_rx_i2c(struct snd_soc_dapm_widget *w, i2s_reg = WCD934X_DATA_HUB_I2S_2_CTL; break; default: - dev_err(codec->dev, "%s Invalid i2s Id received", __func__); + dev_err(component->dev, "%s Invalid i2s Id received", __func__); return -EINVAL; } @@ -1759,21 +1791,22 @@ static int tavil_codec_enable_rx(struct snd_soc_dapm_widget *w, int event) { struct wcd9xxx *core; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); int ret = 0; struct wcd9xxx_codec_dai_data *dai; struct tavil_dsd_config *dsd_conf = tavil_p->dsd_config; - core = dev_get_drvdata(codec->dev->parent); + core = dev_get_drvdata(component->dev->parent); - dev_dbg(codec->dev, "%s: event called! codec name %s num_dai %d\n" + dev_dbg(component->dev, "%s: event called! codec name %s num_dai %d\n" "stream name %s event %d\n", - __func__, codec->component.name, - codec->component.num_dai, w->sname, event); + __func__, component->name, + component->num_dai, w->sname, event); dai = &tavil_p->dai[w->shift]; - dev_dbg(codec->dev, "%s: w->name %s w->shift %d event %d\n", + dev_dbg(component->dev, "%s: w->name %s w->shift %d event %d\n", __func__, w->name, w->shift, event); if (tavil_p->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { @@ -1784,7 +1817,7 @@ static int tavil_codec_enable_rx(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMU: dai->bus_down_in_recovery = false; - tavil_codec_enable_slim_port_intr(dai, codec); + tavil_codec_enable_slim_port_intr(dai, component); (void) tavil_codec_enable_slim_chmask(dai, true); ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list, dai->rate, dai->bit_width, @@ -1792,17 +1825,17 @@ static int tavil_codec_enable_rx(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: if (dsd_conf) - tavil_codec_mute_dsd(codec, &dai->wcd9xxx_ch_list); + tavil_codec_mute_dsd(component, &dai->wcd9xxx_ch_list); ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list, dai->grph); - dev_dbg(codec->dev, "%s: Disconnect RX port, ret = %d\n", + dev_dbg(component->dev, "%s: Disconnect RX port, ret = %d\n", __func__, ret); if (!dai->bus_down_in_recovery) ret = tavil_codec_enable_slim_chmask(dai, false); else - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: bus in recovery skip enable slim_chmask", __func__); ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list, @@ -1816,8 +1849,9 @@ static int tavil_codec_enable_tx_i2c(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); int ret = -EINVAL; u32 i2s_reg; @@ -1835,7 +1869,7 @@ static int tavil_codec_enable_tx_i2c(struct snd_soc_dapm_widget *w, i2s_reg = WCD934X_DATA_HUB_I2S_2_CTL; break; default: - dev_err(codec->dev, "%s Invalid i2s Id received", __func__); + dev_err(component->dev, "%s Invalid i2s Id received", __func__); return -EINVAL; } @@ -1855,19 +1889,20 @@ static int tavil_codec_enable_tx(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); struct wcd9xxx_codec_dai_data *dai; struct wcd9xxx *core; int ret = 0; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: w->name %s, w->shift = %d, num_dai %d stream name %s\n", __func__, w->name, w->shift, - codec->component.num_dai, w->sname); + component->num_dai, w->sname); dai = &tavil_p->dai[w->shift]; - core = dev_get_drvdata(codec->dev->parent); + core = dev_get_drvdata(component->dev->parent); if (tavil_p->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { ret = tavil_codec_enable_tx_i2c(w, kcontrol, event); @@ -1877,7 +1912,7 @@ static int tavil_codec_enable_tx(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMU: dai->bus_down_in_recovery = false; - tavil_codec_enable_slim_port_intr(dai, codec); + tavil_codec_enable_slim_port_intr(dai, component); (void) tavil_codec_enable_slim_chmask(dai, true); ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list, dai->rate, dai->bit_width, @@ -1892,7 +1927,7 @@ static int tavil_codec_enable_tx(struct snd_soc_dapm_widget *w, ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list, dai->grph); - dev_dbg(codec->dev, "%s: Disconnect RX port, ret = %d\n", + dev_dbg(component->dev, "%s: Disconnect RX port, ret = %d\n", __func__, ret); } break; @@ -1905,18 +1940,18 @@ static int tavil_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w, int event) { struct wcd9xxx *core = NULL; - struct snd_soc_codec *codec = NULL; + struct snd_soc_component *component = NULL; struct tavil_priv *tavil_p = NULL; int ret = 0; struct wcd9xxx_codec_dai_data *dai = NULL; - codec = snd_soc_dapm_to_codec(w->dapm); - tavil_p = snd_soc_codec_get_drvdata(codec); - core = dev_get_drvdata(codec->dev->parent); + component = snd_soc_dapm_to_component(w->dapm); + tavil_p = snd_soc_component_get_drvdata(component); + core = dev_get_drvdata(component->dev->parent); - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: num_dai %d stream name %s w->name %s event %d shift %d\n", - __func__, codec->component.num_dai, w->sname, + __func__, component->num_dai, w->sname, w->name, event, w->shift); if (w->shift != AIF4_VIFEED) { @@ -1928,59 +1963,60 @@ static int tavil_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMU: if (test_bit(VI_SENSE_1, &tavil_p->status_mask)) { - dev_dbg(codec->dev, "%s: spkr1 enabled\n", __func__); + dev_dbg(component->dev, "%s: spkr1 enabled\n", + __func__); /* Enable V&I sensing */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX9_SPKR_PROT_PATH_CTL, 0x0F, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX10_SPKR_PROT_PATH_CTL, 0x0F, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, 0x00); } if (test_bit(VI_SENSE_2, &tavil_p->status_mask)) { pr_debug("%s: spkr2 enabled\n", __func__); /* Enable V&I sensing */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX11_SPKR_PROT_PATH_CTL, 0x0F, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX12_SPKR_PROT_PATH_CTL, 0x0F, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, 0x00); } dai->bus_down_in_recovery = false; - tavil_codec_enable_slim_port_intr(dai, codec); + tavil_codec_enable_slim_port_intr(dai, component); (void) tavil_codec_enable_slim_chmask(dai, true); ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list, dai->rate, dai->bit_width, @@ -1990,7 +2026,7 @@ static int tavil_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w, ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list, dai->grph); if (ret) - dev_err(codec->dev, "%s error in close_slim_sch_tx %d\n", + dev_err(component->dev, "%s error in close_slim_sch_tx %d\n", __func__, ret); if (!dai->bus_down_in_recovery) ret = tavil_codec_enable_slim_chmask(dai, false); @@ -1998,36 +2034,38 @@ static int tavil_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w, ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list, dai->grph); - dev_dbg(codec->dev, "%s: Disconnect TX port, ret = %d\n", + dev_dbg(component->dev, "%s: Disconnect TX port, ret = %d\n", __func__, ret); } if (test_bit(VI_SENSE_1, &tavil_p->status_mask)) { /* Disable V&I sensing */ - dev_dbg(codec->dev, "%s: spkr1 disabled\n", __func__); - snd_soc_update_bits(codec, + dev_dbg(component->dev, "%s: spkr1 disabled\n", + __func__); + snd_soc_component_update_bits(component, WCD934X_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10, 0x00); } if (test_bit(VI_SENSE_2, &tavil_p->status_mask)) { /* Disable V&I sensing */ - dev_dbg(codec->dev, "%s: spkr2 disabled\n", __func__); - snd_soc_update_bits(codec, + dev_dbg(component->dev, "%s: spkr2 disabled\n", + __func__); + snd_soc_component_update_bits(component, WCD934X_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20, 0x20); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10, 0x00); } @@ -2040,28 +2078,31 @@ static int tavil_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w, static int tavil_codec_enable_rx_bias(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: tavil->rx_bias_count++; if (tavil->rx_bias_count == 1) { - snd_soc_update_bits(codec, WCD934X_ANA_RX_SUPPLIES, - 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_ANA_RX_SUPPLIES, + 0x01, 0x01); } break; case SND_SOC_DAPM_POST_PMD: tavil->rx_bias_count--; if (!tavil->rx_bias_count) - snd_soc_update_bits(codec, WCD934X_ANA_RX_SUPPLIES, - 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_ANA_RX_SUPPLIES, + 0x01, 0x00); break; }; - dev_dbg(codec->dev, "%s: Current RX BIAS user count: %d\n", __func__, - tavil->rx_bias_count); + dev_dbg(component->dev, "%s: Current RX BIAS user count: %d\n", + __func__, tavil->rx_bias_count); return 0; } @@ -2071,14 +2112,15 @@ static void tavil_spk_anc_update_callback(struct work_struct *work) struct spk_anc_work *spk_anc_dwork; struct tavil_priv *tavil; struct delayed_work *delayed_work; - struct snd_soc_codec *codec; + struct snd_soc_component *component; delayed_work = to_delayed_work(work); spk_anc_dwork = container_of(delayed_work, struct spk_anc_work, dwork); tavil = spk_anc_dwork->tavil; - codec = tavil->codec; + component = tavil->component; - snd_soc_update_bits(codec, WCD934X_CDC_RX7_RX_PATH_CFG0, 0x10, 0x10); + snd_soc_component_update_bits(component, WCD934X_CDC_RX7_RX_PATH_CFG0, + 0x10, 0x10); } static int tavil_codec_enable_spkr_anc(struct snd_soc_dapm_widget *w, @@ -2086,13 +2128,14 @@ static int tavil_codec_enable_spkr_anc(struct snd_soc_dapm_widget *w, int event) { int ret = 0; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); if (!tavil->anc_func) return 0; - dev_dbg(codec->dev, "%s: w: %s event: %d anc: %d\n", __func__, + dev_dbg(component->dev, "%s: w: %s event: %d anc: %d\n", __func__, w->name, event, tavil->anc_func); switch (event) { @@ -2103,8 +2146,9 @@ static int tavil_codec_enable_spkr_anc(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: cancel_delayed_work_sync(&tavil->spk_anc_dwork.dwork); - snd_soc_update_bits(codec, WCD934X_CDC_RX7_RX_PATH_CFG0, - 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX7_RX_PATH_CFG0, + 0x10, 0x00); ret = tavil_codec_enable_anc(w, kcontrol, event); break; } @@ -2116,9 +2160,10 @@ static int tavil_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, int event) { int ret = 0; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_POST_PMU: @@ -2127,12 +2172,14 @@ static int tavil_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, * HW requirement */ usleep_range(5000, 5500); - snd_soc_update_bits(codec, WCD934X_CDC_RX0_RX_PATH_CTL, - 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX0_RX_PATH_CTL, + 0x10, 0x00); /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, WCD934X_CDC_RX0_RX_PATH_MIX_CTL)) & + if ((snd_soc_component_read32(component, + WCD934X_CDC_RX0_RX_PATH_MIX_CTL)) & 0x10) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_RX0_RX_PATH_MIX_CTL, 0x10, 0x00); break; @@ -2145,8 +2192,9 @@ static int tavil_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, if (!(strcmp(w->name, "ANC EAR PA"))) { ret = tavil_codec_enable_anc(w, kcontrol, event); - snd_soc_update_bits(codec, WCD934X_CDC_RX0_RX_PATH_CFG0, - 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX0_RX_PATH_CFG0, + 0x10, 0x00); } break; }; @@ -2154,18 +2202,18 @@ static int tavil_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, return ret; } -static void tavil_codec_override(struct snd_soc_codec *codec, int mode, +static void tavil_codec_override(struct snd_soc_component *component, int mode, int event) { if (mode == CLS_AB || mode == CLS_AB_HIFI) { switch (event) { case SND_SOC_DAPM_PRE_PMU: case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x02); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x00); break; } @@ -2175,24 +2223,32 @@ static void tavil_codec_override(struct snd_soc_codec *codec, int mode, static void tavil_codec_clear_anc_tx_hold(struct tavil_priv *tavil) { if (test_and_clear_bit(ANC_MIC_AMIC1, &tavil->status_mask)) - tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC1, false); + tavil_codec_set_tx_hold(tavil->component, + WCD934X_ANA_AMIC1, false); if (test_and_clear_bit(ANC_MIC_AMIC2, &tavil->status_mask)) - tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC2, false); + tavil_codec_set_tx_hold(tavil->component, + WCD934X_ANA_AMIC2, false); if (test_and_clear_bit(ANC_MIC_AMIC3, &tavil->status_mask)) - tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC3, false); + tavil_codec_set_tx_hold(tavil->component, + WCD934X_ANA_AMIC3, false); if (test_and_clear_bit(ANC_MIC_AMIC4, &tavil->status_mask)) - tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC4, false); + tavil_codec_set_tx_hold(tavil->component, + WCD934X_ANA_AMIC4, false); } -static void tavil_ocp_control(struct snd_soc_codec *codec, bool enable) +static void tavil_ocp_control(struct snd_soc_component *component, bool enable) { if (enable) { - snd_soc_update_bits(codec, WCD934X_HPH_OCP_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, WCD934X_RX_OCP_CTL, 0x0F, 0x02); + snd_soc_component_update_bits(component, WCD934X_HPH_OCP_CTL, + 0x10, 0x10); + snd_soc_component_update_bits(component, WCD934X_RX_OCP_CTL, + 0x0F, 0x02); } else { - snd_soc_update_bits(codec, WCD934X_RX_OCP_CTL, 0x0F, 0x0F); - snd_soc_update_bits(codec, WCD934X_HPH_OCP_CTL, 0x10, 0x00); + snd_soc_component_update_bits(component, WCD934X_RX_OCP_CTL, + 0x0F, 0x0F); + snd_soc_component_update_bits(component, WCD934X_HPH_OCP_CTL, + 0x10, 0x00); } } @@ -2200,36 +2256,41 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); struct tavil_dsd_config *dsd_conf = tavil->dsd_config; int ret = 0; - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - tavil_ocp_control(codec, false); + tavil_ocp_control(component, false); if (TAVIL_IS_1_0(tavil->wcd9xxx)) - snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL, - 0x06, (0x03 << 1)); + snd_soc_component_update_bits(component, + WCD934X_HPH_REFBUFF_LP_CTL, + 0x06, (0x03 << 1)); if ((!(strcmp(w->name, "ANC HPHR PA"))) && (test_bit(HPH_PA_DELAY, &tavil->status_mask))) - snd_soc_update_bits(codec, WCD934X_ANA_HPH, 0xC0, 0xC0); + snd_soc_component_update_bits(component, + WCD934X_ANA_HPH, 0xC0, 0xC0); set_bit(HPH_PA_DELAY, &tavil->status_mask); if (dsd_conf && - (snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) { + (snd_soc_component_read32(component, + WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) { /* Set regulator mode to AB if DSD is enabled */ - snd_soc_update_bits(codec, WCD934X_ANA_RX_SUPPLIES, - 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD934X_ANA_RX_SUPPLIES, + 0x02, 0x02); } break; case SND_SOC_DAPM_POST_PMU: if ((!(strcmp(w->name, "ANC HPHR PA")))) { - if ((snd_soc_read(codec, WCD934X_ANA_HPH) & 0xC0) - != 0xC0) + if ((snd_soc_component_read32(component, + WCD934X_ANA_HPH) & 0xC0) != 0xC0) /* * If PA_EN is not set (potentially in ANC case) * then do nothing for POST_PMU and let left @@ -2251,80 +2312,92 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, } if (tavil->anc_func) { /* Clear Tx FE HOLD if both PAs are enabled */ - if ((snd_soc_read(tavil->codec, WCD934X_ANA_HPH) & - 0xC0) == 0xC0) + if ((snd_soc_component_read32(tavil->component, + WCD934X_ANA_HPH) & 0xC0) == 0xC0) tavil_codec_clear_anc_tx_hold(tavil); } - snd_soc_update_bits(codec, WCD934X_HPH_R_TEST, 0x01, 0x01); + snd_soc_component_update_bits(component, WCD934X_HPH_R_TEST, + 0x01, 0x01); /* Remove mute */ - snd_soc_update_bits(codec, WCD934X_CDC_RX2_RX_PATH_CTL, - 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX2_RX_PATH_CTL, + 0x10, 0x00); /* Enable GM3 boost */ - snd_soc_update_bits(codec, WCD934X_HPH_CNP_WG_CTL, - 0x80, 0x80); + snd_soc_component_update_bits(component, WCD934X_HPH_CNP_WG_CTL, + 0x80, 0x80); /* Enable AutoChop timer at the end of power up */ - snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_HPH_TIMER1, - 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD934X_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x02); /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, WCD934X_CDC_RX2_RX_PATH_MIX_CTL)) & - 0x10) - snd_soc_update_bits(codec, + if ((snd_soc_component_read32(component, + WCD934X_CDC_RX2_RX_PATH_MIX_CTL)) & 0x10) + snd_soc_component_update_bits(component, WCD934X_CDC_RX2_RX_PATH_MIX_CTL, 0x10, 0x00); if (dsd_conf && - (snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) - snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, - 0x04, 0x00); + (snd_soc_component_read32( + component, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD1_CFG2, 0x04, 0x00); if (!(strcmp(w->name, "ANC HPHR PA"))) { pr_debug("%s:Do everything needed for left channel\n", __func__); /* Do everything needed for left channel */ - snd_soc_update_bits(codec, WCD934X_HPH_L_TEST, - 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_HPH_L_TEST, + 0x01, 0x01); /* Remove mute */ - snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CTL, - 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX1_RX_PATH_CTL, + 0x10, 0x00); /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, + if ((snd_soc_component_read32(component, WCD934X_CDC_RX1_RX_PATH_MIX_CTL)) & 0x10) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_RX1_RX_PATH_MIX_CTL, 0x10, 0x00); - if (dsd_conf && (snd_soc_read(codec, + if (dsd_conf && (snd_soc_component_read32(component, WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_DSD0_CFG2, 0x04, 0x00); /* Remove ANC Rx from reset */ ret = tavil_codec_enable_anc(w, kcontrol, event); } - tavil_codec_override(codec, tavil->hph_mode, event); - tavil_ocp_control(codec, true); + tavil_codec_override(component, tavil->hph_mode, event); + tavil_ocp_control(component, true); break; case SND_SOC_DAPM_PRE_PMD: - tavil_ocp_control(codec, false); + tavil_ocp_control(component, false); blocking_notifier_call_chain(&tavil->mbhc->notifier, WCD_EVENT_PRE_HPHR_PA_OFF, &tavil->mbhc->wcd_mbhc); /* Enable DSD Mute before PA disable */ if (dsd_conf && - (snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) - snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, - 0x04, 0x04); - snd_soc_update_bits(codec, WCD934X_HPH_R_TEST, 0x01, 0x00); - snd_soc_update_bits(codec, WCD934X_CDC_RX2_RX_PATH_CTL, - 0x10, 0x10); - snd_soc_update_bits(codec, WCD934X_CDC_RX2_RX_PATH_MIX_CTL, - 0x10, 0x10); + (snd_soc_component_read32(component, + WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD1_CFG2, + 0x04, 0x04); + snd_soc_component_update_bits(component, WCD934X_HPH_R_TEST, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX2_RX_PATH_CTL, + 0x10, 0x10); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX2_RX_PATH_MIX_CTL, + 0x10, 0x10); if (!(strcmp(w->name, "ANC HPHR PA"))) - snd_soc_update_bits(codec, WCD934X_ANA_HPH, 0x40, 0x00); + snd_soc_component_update_bits(component, + WCD934X_ANA_HPH, 0x40, 0x00); break; case SND_SOC_DAPM_POST_PMD: /* @@ -2335,20 +2408,21 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, usleep_range(20000, 20100); else usleep_range(5000, 5100); - tavil_codec_override(codec, tavil->hph_mode, event); + tavil_codec_override(component, tavil->hph_mode, event); blocking_notifier_call_chain(&tavil->mbhc->notifier, WCD_EVENT_POST_HPHR_PA_OFF, &tavil->mbhc->wcd_mbhc); if (TAVIL_IS_1_0(tavil->wcd9xxx)) - snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL, - 0x06, 0x0); + snd_soc_component_update_bits(component, + WCD934X_HPH_REFBUFF_LP_CTL, + 0x06, 0x0); if (!(strcmp(w->name, "ANC HPHR PA"))) { ret = tavil_codec_enable_anc(w, kcontrol, event); - snd_soc_update_bits(codec, - WCD934X_CDC_RX2_RX_PATH_CFG0, - 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX2_RX_PATH_CFG0, + 0x10, 0x00); } - tavil_ocp_control(codec, true); + tavil_ocp_control(component, true); break; }; @@ -2359,35 +2433,40 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); struct tavil_dsd_config *dsd_conf = tavil->dsd_config; int ret = 0; - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - tavil_ocp_control(codec, false); + tavil_ocp_control(component, false); if (TAVIL_IS_1_0(tavil->wcd9xxx)) - snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL, - 0x06, (0x03 << 1)); + snd_soc_component_update_bits(component, + WCD934X_HPH_REFBUFF_LP_CTL, + 0x06, (0x03 << 1)); if ((!(strcmp(w->name, "ANC HPHL PA"))) && (test_bit(HPH_PA_DELAY, &tavil->status_mask))) - snd_soc_update_bits(codec, WCD934X_ANA_HPH, - 0xC0, 0xC0); + snd_soc_component_update_bits(component, + WCD934X_ANA_HPH, + 0xC0, 0xC0); set_bit(HPH_PA_DELAY, &tavil->status_mask); if (dsd_conf && - (snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) { + (snd_soc_component_read32(component, + WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) { /* Set regulator mode to AB if DSD is enabled */ - snd_soc_update_bits(codec, WCD934X_ANA_RX_SUPPLIES, - 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD934X_ANA_RX_SUPPLIES, + 0x02, 0x02); } break; case SND_SOC_DAPM_POST_PMU: if (!(strcmp(w->name, "ANC HPHL PA"))) { - if ((snd_soc_read(codec, WCD934X_ANA_HPH) & 0xC0) - != 0xC0) + if ((snd_soc_component_read32( + component, WCD934X_ANA_HPH) & 0xC0) != 0xC0) /* * If PA_EN is not set (potentially in ANC * case) then do nothing for POST_PMU and @@ -2409,80 +2488,95 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, } if (tavil->anc_func) { /* Clear Tx FE HOLD if both PAs are enabled */ - if ((snd_soc_read(tavil->codec, WCD934X_ANA_HPH) & - 0xC0) == 0xC0) + if ((snd_soc_component_read32( + tavil->component, WCD934X_ANA_HPH) & 0xC0) == + 0xC0) tavil_codec_clear_anc_tx_hold(tavil); } - snd_soc_update_bits(codec, WCD934X_HPH_L_TEST, 0x01, 0x01); + snd_soc_component_update_bits(component, WCD934X_HPH_L_TEST, + 0x01, 0x01); /* Remove Mute on primary path */ - snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CTL, - 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX1_RX_PATH_CTL, + 0x10, 0x00); /* Enable GM3 boost */ - snd_soc_update_bits(codec, WCD934X_HPH_CNP_WG_CTL, - 0x80, 0x80); + snd_soc_component_update_bits(component, + WCD934X_HPH_CNP_WG_CTL, + 0x80, 0x80); /* Enable AutoChop timer at the end of power up */ - snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_HPH_TIMER1, - 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD934X_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x02); /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, WCD934X_CDC_RX1_RX_PATH_MIX_CTL)) & - 0x10) - snd_soc_update_bits(codec, + if ((snd_soc_component_read32(component, + WCD934X_CDC_RX1_RX_PATH_MIX_CTL)) & 0x10) + snd_soc_component_update_bits(component, WCD934X_CDC_RX1_RX_PATH_MIX_CTL, 0x10, 0x00); if (dsd_conf && - (snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) - snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, - 0x04, 0x00); + (snd_soc_component_read32( + component, WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD0_CFG2, + 0x04, 0x00); if (!(strcmp(w->name, "ANC HPHL PA"))) { pr_debug("%s:Do everything needed for right channel\n", __func__); /* Do everything needed for right channel */ - snd_soc_update_bits(codec, WCD934X_HPH_R_TEST, - 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_HPH_R_TEST, + 0x01, 0x01); /* Remove mute */ - snd_soc_update_bits(codec, WCD934X_CDC_RX2_RX_PATH_CTL, - 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX2_RX_PATH_CTL, + 0x10, 0x00); /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, + if ((snd_soc_component_read32(component, WCD934X_CDC_RX2_RX_PATH_MIX_CTL)) & 0x10) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_RX2_RX_PATH_MIX_CTL, 0x10, 0x00); - if (dsd_conf && (snd_soc_read(codec, + if (dsd_conf && (snd_soc_component_read32(component, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_DSD1_CFG2, 0x04, 0x00); /* Remove ANC Rx from reset */ ret = tavil_codec_enable_anc(w, kcontrol, event); } - tavil_codec_override(codec, tavil->hph_mode, event); - tavil_ocp_control(codec, true); + tavil_codec_override(component, tavil->hph_mode, event); + tavil_ocp_control(component, true); break; case SND_SOC_DAPM_PRE_PMD: - tavil_ocp_control(codec, false); + tavil_ocp_control(component, false); blocking_notifier_call_chain(&tavil->mbhc->notifier, WCD_EVENT_PRE_HPHL_PA_OFF, &tavil->mbhc->wcd_mbhc); /* Enable DSD Mute before PA disable */ if (dsd_conf && - (snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) - snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, + (snd_soc_component_read32(component, + WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) + snd_soc_component_update_bits(component, + WCD934X_CDC_DSD0_CFG2, 0x04, 0x04); - snd_soc_update_bits(codec, WCD934X_HPH_L_TEST, 0x01, 0x00); - snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CTL, - 0x10, 0x10); - snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_MIX_CTL, - 0x10, 0x10); + snd_soc_component_update_bits(component, WCD934X_HPH_L_TEST, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX1_RX_PATH_CTL, + 0x10, 0x10); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX1_RX_PATH_MIX_CTL, + 0x10, 0x10); if (!(strcmp(w->name, "ANC HPHL PA"))) - snd_soc_update_bits(codec, WCD934X_ANA_HPH, - 0x80, 0x00); + snd_soc_component_update_bits(component, + WCD934X_ANA_HPH, + 0x80, 0x00); break; case SND_SOC_DAPM_POST_PMD: /* @@ -2493,19 +2587,20 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, usleep_range(20000, 20100); else usleep_range(5000, 5100); - tavil_codec_override(codec, tavil->hph_mode, event); + tavil_codec_override(component, tavil->hph_mode, event); blocking_notifier_call_chain(&tavil->mbhc->notifier, WCD_EVENT_POST_HPHL_PA_OFF, &tavil->mbhc->wcd_mbhc); if (TAVIL_IS_1_0(tavil->wcd9xxx)) - snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL, - 0x06, 0x0); + snd_soc_component_update_bits(component, + WCD934X_HPH_REFBUFF_LP_CTL, + 0x06, 0x0); if (!(strcmp(w->name, "ANC HPHL PA"))) { ret = tavil_codec_enable_anc(w, kcontrol, event); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_RX1_RX_PATH_CFG0, 0x10, 0x00); } - tavil_ocp_control(codec, true); + tavil_ocp_control(component, true); break; }; @@ -2516,13 +2611,14 @@ static int tavil_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); u16 lineout_vol_reg = 0, lineout_mix_vol_reg = 0; u16 dsd_mute_reg = 0, dsd_clk_reg = 0; - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); struct tavil_dsd_config *dsd_conf = tavil->dsd_config; - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); if (w->reg == WCD934X_ANA_LO_1_2) { if (w->shift == 7) { @@ -2537,14 +2633,14 @@ static int tavil_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w, dsd_clk_reg = WCD934X_CDC_DSD1_PATH_CTL; } } else { - dev_err(codec->dev, "%s: Error enabling lineout PA\n", + dev_err(component->dev, "%s: Error enabling lineout PA\n", __func__); return -EINVAL; } switch (event) { case SND_SOC_DAPM_PRE_PMU: - tavil_codec_override(codec, CLS_AB, event); + tavil_codec_override(component, CLS_AB, event); break; case SND_SOC_DAPM_POST_PMU: /* @@ -2552,19 +2648,24 @@ static int tavil_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w, * HW requirement */ usleep_range(5000, 5500); - snd_soc_update_bits(codec, lineout_vol_reg, + snd_soc_component_update_bits(component, lineout_vol_reg, 0x10, 0x00); /* Remove mix path mute if it is enabled */ - if ((snd_soc_read(codec, lineout_mix_vol_reg)) & 0x10) - snd_soc_update_bits(codec, + if ((snd_soc_component_read32( + component, lineout_mix_vol_reg)) & 0x10) + snd_soc_component_update_bits(component, lineout_mix_vol_reg, 0x10, 0x00); - if (dsd_conf && (snd_soc_read(codec, dsd_clk_reg) & 0x01)) - snd_soc_update_bits(codec, dsd_mute_reg, 0x04, 0x00); + if (dsd_conf && (snd_soc_component_read32( + component, dsd_clk_reg) & 0x01)) + snd_soc_component_update_bits(component, dsd_mute_reg, + 0x04, 0x00); break; case SND_SOC_DAPM_PRE_PMD: - if (dsd_conf && (snd_soc_read(codec, dsd_clk_reg) & 0x01)) - snd_soc_update_bits(codec, dsd_mute_reg, 0x04, 0x04); + if (dsd_conf && (snd_soc_component_read32( + component, dsd_clk_reg) & 0x01)) + snd_soc_component_update_bits(component, dsd_mute_reg, + 0x04, 0x04); break; case SND_SOC_DAPM_POST_PMD: /* @@ -2572,7 +2673,7 @@ static int tavil_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w, * HW requirement */ usleep_range(5000, 5500); - tavil_codec_override(codec, CLS_AB, event); + tavil_codec_override(component, CLS_AB, event); default: break; }; @@ -2585,8 +2686,9 @@ static int i2s_rx_mux_get(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); ucontrol->value.enumerated.item[0] = tavil_p->rx_port_value[widget->shift]; @@ -2598,8 +2700,9 @@ static int i2s_rx_mux_put(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct snd_soc_dapm_update *update = NULL; unsigned int rx_port_value; @@ -2608,7 +2711,7 @@ static int i2s_rx_mux_put(struct snd_kcontrol *kcontrol, tavil_p->rx_port_value[port_id] = ucontrol->value.enumerated.item[0]; rx_port_value = tavil_p->rx_port_value[port_id]; - dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", + dev_dbg(component->dev, "%s: wname %s cname %s value %u shift %d item %ld\n", __func__, widget->name, ucontrol->id.name, rx_port_value, widget->shift, ucontrol->value.integer.value[0]); @@ -2624,8 +2727,9 @@ static int tavil_codec_enable_i2s_path(struct snd_soc_dapm_widget *w, { int ret = 0; u32 i2s_reg; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); switch (tavil_p->rx_port_value[w->shift]) { case AIF1_PB: @@ -2641,16 +2745,18 @@ static int tavil_codec_enable_i2s_path(struct snd_soc_dapm_widget *w, i2s_reg = WCD934X_DATA_HUB_I2S_2_CTL; break; default: - dev_err(codec->dev, "%s Invalid i2s Id received", __func__); + dev_err(component->dev, "%s Invalid i2s Id received", __func__); return -EINVAL; } switch (event) { case SND_SOC_DAPM_PRE_PMU: - ret = snd_soc_update_bits(codec, i2s_reg, 0x01, 0x01); + ret = snd_soc_component_update_bits(component, i2s_reg, + 0x01, 0x01); break; case SND_SOC_DAPM_POST_PMD: - ret = snd_soc_update_bits(codec, i2s_reg, 0x01, 0x00); + ret = snd_soc_component_update_bits(component, i2s_reg, + 0x01, 0x00); break; } @@ -2662,30 +2768,33 @@ static int tavil_codec_ear_dac_event(struct snd_soc_dapm_widget *w, int event) { int ret = 0; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: /* Disable AutoChop timer during power up */ - snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_HPH_TIMER1, - 0x02, 0x00); + snd_soc_component_update_bits(component, + WCD934X_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x00); if (tavil->anc_func) ret = tavil_codec_enable_anc(w, kcontrol, event); - wcd_clsh_fsm(codec, &tavil->clsh_d, + wcd_clsh_fsm(component, &tavil->clsh_d, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_EAR, CLS_H_NORMAL); if (tavil->anc_func) - snd_soc_update_bits(codec, WCD934X_CDC_RX0_RX_PATH_CFG0, + snd_soc_component_update_bits(component, + WCD934X_CDC_RX0_RX_PATH_CFG0, 0x10, 0x10); break; case SND_SOC_DAPM_POST_PMD: - wcd_clsh_fsm(codec, &tavil->clsh_d, + wcd_clsh_fsm(component, &tavil->clsh_d, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_EAR, CLS_H_NORMAL); @@ -2701,15 +2810,16 @@ static int tavil_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int hph_mode = tavil->hph_mode; u8 dem_inp; struct tavil_dsd_config *dsd_conf = tavil->dsd_config; int ret = 0; - dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, - w->name, event, hph_mode); + dev_dbg(component->dev, "%s wname: %s event: %d hph_mode: %d\n", + __func__, w->name, event, hph_mode); switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -2719,55 +2829,57 @@ static int tavil_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, msleep(40); } /* Read DEM INP Select */ - dem_inp = snd_soc_read(codec, WCD934X_CDC_RX2_RX_PATH_SEC0) & - 0x03; + dem_inp = snd_soc_component_read32(component, + WCD934X_CDC_RX2_RX_PATH_SEC0) & 0x03; if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { - dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", + dev_err(component->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", __func__, hph_mode); return -EINVAL; } if ((hph_mode != CLS_H_LP) && (hph_mode != CLS_H_ULP)) /* Ripple freq control enable */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_SIDO_NEW_VOUT_D_FREQ2, 0x01, 0x01); /* Disable AutoChop timer during power up */ - snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_HPH_TIMER1, - 0x02, 0x00); + snd_soc_component_update_bits(component, + WCD934X_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x00); /* Set RDAC gain */ if (TAVIL_IS_1_0(tavil->wcd9xxx)) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, 0xF0, 0x40); if (dsd_conf && - (snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) + (snd_soc_component_read32(component, + WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) hph_mode = CLS_H_HIFI; - wcd_clsh_fsm(codec, &tavil->clsh_d, + wcd_clsh_fsm(component, &tavil->clsh_d, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_HPHR, hph_mode); if (tavil->anc_func) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_RX2_RX_PATH_CFG0, 0x10, 0x10); break; case SND_SOC_DAPM_POST_PMD: /* 1000us required as per HW requirement */ usleep_range(1000, 1100); - wcd_clsh_fsm(codec, &tavil->clsh_d, + wcd_clsh_fsm(component, &tavil->clsh_d, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_HPHR, hph_mode); if ((hph_mode != CLS_H_LP) && (hph_mode != CLS_H_ULP)) /* Ripple freq control disable */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_SIDO_NEW_VOUT_D_FREQ2, 0x01, 0x0); /* Re-set RDAC gain */ if (TAVIL_IS_1_0(tavil->wcd9xxx)) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, 0xF0, 0x0); break; @@ -2782,16 +2894,17 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int hph_mode = tavil->hph_mode; u8 dem_inp; int ret = 0; struct tavil_dsd_config *dsd_conf = tavil->dsd_config; uint32_t impedl = 0, impedr = 0; - dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, - w->name, event, hph_mode); + dev_dbg(component->dev, "%s wname: %s event: %d hph_mode: %d\n", + __func__, w->name, event, hph_mode); switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -2801,48 +2914,50 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, msleep(40); } /* Read DEM INP Select */ - dem_inp = snd_soc_read(codec, WCD934X_CDC_RX1_RX_PATH_SEC0) & - 0x03; + dem_inp = snd_soc_component_read32(component, + WCD934X_CDC_RX1_RX_PATH_SEC0) & 0x03; if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { - dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", + dev_err(component->dev, "%s: DEM Input not set correctly, hph_mode: %d\n", __func__, hph_mode); return -EINVAL; } if ((hph_mode != CLS_H_LP) && (hph_mode != CLS_H_ULP)) /* Ripple freq control enable */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_SIDO_NEW_VOUT_D_FREQ2, 0x01, 0x01); /* Disable AutoChop timer during power up */ - snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_HPH_TIMER1, - 0x02, 0x00); + snd_soc_component_update_bits(component, + WCD934X_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x00); /* Set RDAC gain */ if (TAVIL_IS_1_0(tavil->wcd9xxx)) - snd_soc_update_bits(codec, - WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, - 0xF0, 0x40); + snd_soc_component_update_bits(component, + WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, + 0xF0, 0x40); if (dsd_conf && - (snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) + (snd_soc_component_read32(component, + WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) hph_mode = CLS_H_HIFI; - wcd_clsh_fsm(codec, &tavil->clsh_d, + wcd_clsh_fsm(component, &tavil->clsh_d, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_HPHL, hph_mode); if (tavil->anc_func) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_RX1_RX_PATH_CFG0, 0x10, 0x10); ret = tavil_mbhc_get_impedance(tavil->mbhc, &impedl, &impedr); if (!ret) { - wcd_clsh_imped_config(codec, impedl, false); + wcd_clsh_imped_config(component, impedl, false); set_bit(CLSH_Z_CONFIG, &tavil->status_mask); } else { - dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n", + dev_dbg(component->dev, "%s: Failed to get mbhc impedance %d\n", __func__, ret); ret = 0; } @@ -2851,23 +2966,23 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMD: /* 1000us required as per HW requirement */ usleep_range(1000, 1100); - wcd_clsh_fsm(codec, &tavil->clsh_d, + wcd_clsh_fsm(component, &tavil->clsh_d, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_HPHL, hph_mode); if ((hph_mode != CLS_H_LP) && (hph_mode != CLS_H_ULP)) /* Ripple freq control disable */ - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_SIDO_NEW_VOUT_D_FREQ2, 0x01, 0x0); /* Re-set RDAC gain */ if (TAVIL_IS_1_0(tavil->wcd9xxx)) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, 0xF0, 0x0); if (test_bit(CLSH_Z_CONFIG, &tavil->status_mask)) { - wcd_clsh_imped_config(codec, impedl, true); + wcd_clsh_imped_config(component, impedl, true); clear_bit(CLSH_Z_CONFIG, &tavil->status_mask); } break; @@ -2882,20 +2997,21 @@ static int tavil_codec_lineout_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - wcd_clsh_fsm(codec, &tavil->clsh_d, + wcd_clsh_fsm(component, &tavil->clsh_d, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_LO, CLS_AB); break; case SND_SOC_DAPM_POST_PMD: - wcd_clsh_fsm(codec, &tavil->clsh_d, + wcd_clsh_fsm(component, &tavil->clsh_d, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_LO, CLS_AB); @@ -2909,11 +3025,12 @@ static int tavil_codec_spk_boost_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); u16 boost_path_ctl, boost_path_cfg1; u16 reg, reg_mix; - dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); if (!strcmp(w->name, "RX INT7 CHAIN")) { boost_path_ctl = WCD934X_CDC_BOOST0_BOOST_PATH_CTL; @@ -2926,22 +3043,27 @@ static int tavil_codec_spk_boost_event(struct snd_soc_dapm_widget *w, reg = WCD934X_CDC_RX8_RX_PATH_CTL; reg_mix = WCD934X_CDC_RX8_RX_PATH_MIX_CTL; } else { - dev_err(codec->dev, "%s: unknown widget: %s\n", + dev_err(component->dev, "%s: unknown widget: %s\n", __func__, w->name); return -EINVAL; } switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x01); - snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x10); - snd_soc_update_bits(codec, reg, 0x10, 0x00); - if ((snd_soc_read(codec, reg_mix)) & 0x10) - snd_soc_update_bits(codec, reg_mix, 0x10, 0x00); + snd_soc_component_update_bits(component, boost_path_cfg1, + 0x01, 0x01); + snd_soc_component_update_bits(component, boost_path_ctl, + 0x10, 0x10); + snd_soc_component_update_bits(component, reg, 0x10, 0x00); + if ((snd_soc_component_read32(component, reg_mix)) & 0x10) + snd_soc_component_update_bits(component, reg_mix, + 0x10, 0x00); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x00); - snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x00); + snd_soc_component_update_bits(component, boost_path_ctl, + 0x10, 0x00); + snd_soc_component_update_bits(component, boost_path_cfg1, + 0x01, 0x00); break; }; @@ -2950,11 +3072,12 @@ static int tavil_codec_spk_boost_event(struct snd_soc_dapm_widget *w, static int __tavil_codec_enable_swr(struct snd_soc_dapm_widget *w, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); struct tavil_priv *tavil; int ch_cnt = 0; - tavil = snd_soc_codec_get_drvdata(codec); + tavil = snd_soc_component_get_drvdata(component); if (!tavil->swr.ctrl_data) return -EINVAL; @@ -3010,7 +3133,7 @@ static int tavil_codec_enable_swr(struct snd_soc_dapm_widget *w, return __tavil_codec_enable_swr(w, event); } -static int tavil_codec_config_mad(struct snd_soc_codec *codec) +static int tavil_codec_config_mad(struct snd_soc_component *component) { int ret = 0; int idx; @@ -3019,31 +3142,31 @@ static int tavil_codec_config_mad(struct snd_soc_codec *codec) struct wcd_mad_audio_cal *mad_cal = NULL; const void *data; const char *filename = WCD934X_MAD_AUDIO_FIRMWARE_PATH; - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); size_t cal_size; hwdep_cal = wcdcal_get_fw_cal(tavil->fw_data, WCD9XXX_MAD_CAL); if (hwdep_cal) { data = hwdep_cal->data; cal_size = hwdep_cal->size; - dev_dbg(codec->dev, "%s: using hwdep calibration\n", + dev_dbg(component->dev, "%s: using hwdep calibration\n", __func__); } else { - ret = request_firmware(&fw, filename, codec->dev); + ret = request_firmware(&fw, filename, component->dev); if (ret || !fw) { - dev_err(codec->dev, + dev_err(component->dev, "%s: MAD firmware acquire failed, err = %d\n", __func__, ret); return -ENODEV; } data = fw->data; cal_size = fw->size; - dev_dbg(codec->dev, "%s: using request_firmware calibration\n", + dev_dbg(component->dev, "%s: using request_firmware calibration\n", __func__); } if (cal_size < sizeof(*mad_cal)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Incorrect size %zd for MAD Cal, expected %zd\n", __func__, cal_size, sizeof(*mad_cal)); ret = -ENOMEM; @@ -3052,80 +3175,87 @@ static int tavil_codec_config_mad(struct snd_soc_codec *codec) mad_cal = (struct wcd_mad_audio_cal *) (data); if (!mad_cal) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Invalid calibration data\n", __func__); ret = -EINVAL; goto done; } - snd_soc_write(codec, WCD934X_SOC_MAD_MAIN_CTL_2, + snd_soc_component_write(component, WCD934X_SOC_MAD_MAIN_CTL_2, mad_cal->microphone_info.cycle_time); - snd_soc_update_bits(codec, WCD934X_SOC_MAD_MAIN_CTL_1, 0xFF << 3, - ((uint16_t)mad_cal->microphone_info.settle_time) - << 3); + snd_soc_component_update_bits(component, WCD934X_SOC_MAD_MAIN_CTL_1, + 0xFF << 3, + ((uint16_t)mad_cal->microphone_info.settle_time) << 3); /* Audio */ - snd_soc_write(codec, WCD934X_SOC_MAD_AUDIO_CTL_8, + snd_soc_component_write(component, WCD934X_SOC_MAD_AUDIO_CTL_8, mad_cal->audio_info.rms_omit_samples); - snd_soc_update_bits(codec, WCD934X_SOC_MAD_AUDIO_CTL_1, + snd_soc_component_update_bits(component, WCD934X_SOC_MAD_AUDIO_CTL_1, 0x07 << 4, mad_cal->audio_info.rms_comp_time << 4); - snd_soc_update_bits(codec, WCD934X_SOC_MAD_AUDIO_CTL_2, 0x03 << 2, - mad_cal->audio_info.detection_mechanism << 2); - snd_soc_write(codec, WCD934X_SOC_MAD_AUDIO_CTL_7, - mad_cal->audio_info.rms_diff_threshold & 0x3F); - snd_soc_write(codec, WCD934X_SOC_MAD_AUDIO_CTL_5, - mad_cal->audio_info.rms_threshold_lsb); - snd_soc_write(codec, WCD934X_SOC_MAD_AUDIO_CTL_6, - mad_cal->audio_info.rms_threshold_msb); + snd_soc_component_update_bits(component, WCD934X_SOC_MAD_AUDIO_CTL_2, + 0x03 << 2, + mad_cal->audio_info.detection_mechanism << 2); + snd_soc_component_write(component, WCD934X_SOC_MAD_AUDIO_CTL_7, + mad_cal->audio_info.rms_diff_threshold & 0x3F); + snd_soc_component_write(component, WCD934X_SOC_MAD_AUDIO_CTL_5, + mad_cal->audio_info.rms_threshold_lsb); + snd_soc_component_write(component, WCD934X_SOC_MAD_AUDIO_CTL_6, + mad_cal->audio_info.rms_threshold_msb); for (idx = 0; idx < ARRAY_SIZE(mad_cal->audio_info.iir_coefficients); idx++) { - snd_soc_update_bits(codec, WCD934X_SOC_MAD_AUDIO_IIR_CTL_PTR, + snd_soc_component_update_bits(component, + WCD934X_SOC_MAD_AUDIO_IIR_CTL_PTR, 0x3F, idx); - snd_soc_write(codec, WCD934X_SOC_MAD_AUDIO_IIR_CTL_VAL, - mad_cal->audio_info.iir_coefficients[idx]); - dev_dbg(codec->dev, "%s:MAD Audio IIR Coef[%d] = 0X%x", + snd_soc_component_write(component, + WCD934X_SOC_MAD_AUDIO_IIR_CTL_VAL, + mad_cal->audio_info.iir_coefficients[idx]); + dev_dbg(component->dev, "%s:MAD Audio IIR Coef[%d] = 0X%x", __func__, idx, mad_cal->audio_info.iir_coefficients[idx]); } /* Beacon */ - snd_soc_write(codec, WCD934X_SOC_MAD_BEACON_CTL_8, - mad_cal->beacon_info.rms_omit_samples); - snd_soc_update_bits(codec, WCD934X_SOC_MAD_BEACON_CTL_1, - 0x07 << 4, mad_cal->beacon_info.rms_comp_time << 4); - snd_soc_update_bits(codec, WCD934X_SOC_MAD_BEACON_CTL_2, 0x03 << 2, - mad_cal->beacon_info.detection_mechanism << 2); - snd_soc_write(codec, WCD934X_SOC_MAD_BEACON_CTL_7, - mad_cal->beacon_info.rms_diff_threshold & 0x1F); - snd_soc_write(codec, WCD934X_SOC_MAD_BEACON_CTL_5, - mad_cal->beacon_info.rms_threshold_lsb); - snd_soc_write(codec, WCD934X_SOC_MAD_BEACON_CTL_6, - mad_cal->beacon_info.rms_threshold_msb); + snd_soc_component_write(component, WCD934X_SOC_MAD_BEACON_CTL_8, + mad_cal->beacon_info.rms_omit_samples); + snd_soc_component_update_bits(component, WCD934X_SOC_MAD_BEACON_CTL_1, + 0x07 << 4, mad_cal->beacon_info.rms_comp_time << 4); + snd_soc_component_update_bits(component, WCD934X_SOC_MAD_BEACON_CTL_2, + 0x03 << 2, + mad_cal->beacon_info.detection_mechanism << 2); + snd_soc_component_write(component, WCD934X_SOC_MAD_BEACON_CTL_7, + mad_cal->beacon_info.rms_diff_threshold & 0x1F); + snd_soc_component_write(component, WCD934X_SOC_MAD_BEACON_CTL_5, + mad_cal->beacon_info.rms_threshold_lsb); + snd_soc_component_write(component, WCD934X_SOC_MAD_BEACON_CTL_6, + mad_cal->beacon_info.rms_threshold_msb); for (idx = 0; idx < ARRAY_SIZE(mad_cal->beacon_info.iir_coefficients); idx++) { - snd_soc_update_bits(codec, WCD934X_SOC_MAD_BEACON_IIR_CTL_PTR, - 0x3F, idx); - snd_soc_write(codec, WCD934X_SOC_MAD_BEACON_IIR_CTL_VAL, - mad_cal->beacon_info.iir_coefficients[idx]); - dev_dbg(codec->dev, "%s:MAD Beacon IIR Coef[%d] = 0X%x", + snd_soc_component_update_bits(component, + WCD934X_SOC_MAD_BEACON_IIR_CTL_PTR, + 0x3F, idx); + snd_soc_component_write(component, + WCD934X_SOC_MAD_BEACON_IIR_CTL_VAL, + mad_cal->beacon_info.iir_coefficients[idx]); + dev_dbg(component->dev, "%s:MAD Beacon IIR Coef[%d] = 0X%x", __func__, idx, mad_cal->beacon_info.iir_coefficients[idx]); } /* Ultrasound */ - snd_soc_update_bits(codec, WCD934X_SOC_MAD_ULTR_CTL_1, - 0x07 << 4, - mad_cal->ultrasound_info.rms_comp_time << 4); - snd_soc_update_bits(codec, WCD934X_SOC_MAD_ULTR_CTL_2, 0x03 << 2, - mad_cal->ultrasound_info.detection_mechanism << 2); - snd_soc_write(codec, WCD934X_SOC_MAD_ULTR_CTL_7, - mad_cal->ultrasound_info.rms_diff_threshold & 0x1F); - snd_soc_write(codec, WCD934X_SOC_MAD_ULTR_CTL_5, + snd_soc_component_update_bits(component, WCD934X_SOC_MAD_ULTR_CTL_1, + 0x07 << 4, + mad_cal->ultrasound_info.rms_comp_time << 4); + snd_soc_component_update_bits(component, WCD934X_SOC_MAD_ULTR_CTL_2, + 0x03 << 2, + mad_cal->ultrasound_info.detection_mechanism << 2); + snd_soc_component_write(component, WCD934X_SOC_MAD_ULTR_CTL_7, + mad_cal->ultrasound_info.rms_diff_threshold & 0x1F); + snd_soc_component_write(component, WCD934X_SOC_MAD_ULTR_CTL_5, mad_cal->ultrasound_info.rms_threshold_lsb); - snd_soc_write(codec, WCD934X_SOC_MAD_ULTR_CTL_6, + snd_soc_component_write(component, WCD934X_SOC_MAD_ULTR_CTL_6, mad_cal->ultrasound_info.rms_threshold_msb); done: @@ -3135,46 +3265,54 @@ static int tavil_codec_config_mad(struct snd_soc_codec *codec) return ret; } -static int __tavil_codec_enable_mad(struct snd_soc_codec *codec, bool enable) +static int __tavil_codec_enable_mad(struct snd_soc_component *component, + bool enable) { int rc = 0; /* Return if CPE INPUT is DEC1 */ - if (snd_soc_read(codec, WCD934X_CPE_SS_SVA_CFG) & 0x04) { - dev_dbg(codec->dev, "%s: MAD is bypassed, skip mad %s\n", + if (snd_soc_component_read32( + component, WCD934X_CPE_SS_SVA_CFG) & 0x04) { + dev_dbg(component->dev, "%s: MAD is bypassed, skip mad %s\n", __func__, enable ? "enable" : "disable"); return rc; } - dev_dbg(codec->dev, "%s: enable = %s\n", __func__, + dev_dbg(component->dev, "%s: enable = %s\n", __func__, enable ? "enable" : "disable"); if (enable) { - snd_soc_update_bits(codec, WCD934X_SOC_MAD_AUDIO_CTL_2, - 0x03, 0x03); - rc = tavil_codec_config_mad(codec); + snd_soc_component_update_bits(component, + WCD934X_SOC_MAD_AUDIO_CTL_2, + 0x03, 0x03); + rc = tavil_codec_config_mad(component); if (rc < 0) { - snd_soc_update_bits(codec, WCD934X_SOC_MAD_AUDIO_CTL_2, - 0x03, 0x00); + snd_soc_component_update_bits(component, + WCD934X_SOC_MAD_AUDIO_CTL_2, + 0x03, 0x00); goto done; } /* Turn on MAD clk */ - snd_soc_update_bits(codec, WCD934X_CPE_SS_MAD_CTL, - 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_CPE_SS_MAD_CTL, + 0x01, 0x01); /* Undo reset for MAD */ - snd_soc_update_bits(codec, WCD934X_CPE_SS_MAD_CTL, - 0x02, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CPE_SS_MAD_CTL, + 0x02, 0x00); } else { - snd_soc_update_bits(codec, WCD934X_SOC_MAD_AUDIO_CTL_2, - 0x03, 0x00); + snd_soc_component_update_bits(component, + WCD934X_SOC_MAD_AUDIO_CTL_2, + 0x03, 0x00); /* Reset the MAD block */ - snd_soc_update_bits(codec, WCD934X_CPE_SS_MAD_CTL, - 0x02, 0x02); - /* Turn off MAD clk */ - snd_soc_update_bits(codec, WCD934X_CPE_SS_MAD_CTL, - 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CPE_SS_MAD_CTL, + 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD934X_CPE_SS_MAD_CTL, + 0x01, 0x00); } done: return rc; @@ -3184,18 +3322,21 @@ static int tavil_codec_ape_enable_mad(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int rc = 0; switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, WCD934X_CPE_SS_SVA_CFG, 0x40, 0x40); - rc = __tavil_codec_enable_mad(codec, true); + snd_soc_component_update_bits(component, + WCD934X_CPE_SS_SVA_CFG, 0x40, 0x40); + rc = __tavil_codec_enable_mad(component, true); break; case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, WCD934X_CPE_SS_SVA_CFG, 0x40, 0x00); - __tavil_codec_enable_mad(codec, false); + snd_soc_component_update_bits(component, + WCD934X_CPE_SS_SVA_CFG, 0x40, 0x00); + __tavil_codec_enable_mad(component, false); break; } @@ -3206,8 +3347,9 @@ static int tavil_codec_ape_enable_mad(struct snd_soc_dapm_widget *w, static int tavil_codec_cpe_mad_ctl(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int rc = 0; switch (event) { @@ -3216,8 +3358,9 @@ static int tavil_codec_cpe_mad_ctl(struct snd_soc_dapm_widget *w, if (tavil->mad_switch_cnt != 1) goto done; - snd_soc_update_bits(codec, WCD934X_CPE_SS_SVA_CFG, 0x20, 0x20); - rc = __tavil_codec_enable_mad(codec, true); + snd_soc_component_update_bits(component, WCD934X_CPE_SS_SVA_CFG, + 0x20, 0x20); + rc = __tavil_codec_enable_mad(component, true); if (rc < 0) { tavil->mad_switch_cnt--; goto done; @@ -3229,8 +3372,9 @@ static int tavil_codec_cpe_mad_ctl(struct snd_soc_dapm_widget *w, if (tavil->mad_switch_cnt != 0) goto done; - snd_soc_update_bits(codec, WCD934X_CPE_SS_SVA_CFG, 0x20, 0x00); - __tavil_codec_enable_mad(codec, false); + snd_soc_component_update_bits(component, WCD934X_CPE_SS_SVA_CFG, + 0x20, 0x00); + __tavil_codec_enable_mad(component, false); break; } done: @@ -3281,24 +3425,25 @@ static int tavil_get_asrc_mode(struct tavil_priv *tavil, int asrc, static int tavil_codec_wdma3_ctl(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); switch (event) { case SND_SOC_DAPM_PRE_PMU: /* Fix to 16KHz */ - snd_soc_update_bits(codec, WCD934X_DMA_WDMA_CTL_3, + snd_soc_component_update_bits(component, WCD934X_DMA_WDMA_CTL_3, 0xF0, 0x10); /* Select mclk_1 */ - snd_soc_update_bits(codec, WCD934X_DMA_WDMA_CTL_3, + snd_soc_component_update_bits(component, WCD934X_DMA_WDMA_CTL_3, 0x02, 0x00); /* Enable DMA */ - snd_soc_update_bits(codec, WCD934X_DMA_WDMA_CTL_3, + snd_soc_component_update_bits(component, WCD934X_DMA_WDMA_CTL_3, 0x01, 0x01); break; case SND_SOC_DAPM_POST_PMD: /* Disable DMA */ - snd_soc_update_bits(codec, WCD934X_DMA_WDMA_CTL_3, + snd_soc_component_update_bits(component, WCD934X_DMA_WDMA_CTL_3, 0x01, 0x00); break; @@ -3307,10 +3452,10 @@ static int tavil_codec_wdma3_ctl(struct snd_soc_dapm_widget *w, return 0; } -static int tavil_codec_enable_asrc(struct snd_soc_codec *codec, +static int tavil_codec_enable_asrc(struct snd_soc_component *component, int asrc_in, int event) { - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); u16 cfg_reg, ctl_reg, clk_reg, asrc_ctl, mix_ctl_reg, paired_reg; int asrc, ret = 0; u8 main_sr, mix_sr, asrc_mode = 0; @@ -3365,8 +3510,8 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec, asrc = ASRC3; break; default: - dev_err(codec->dev, "%s: Invalid asrc input :%d\n", __func__, - asrc_in); + dev_err(component->dev, "%s: Invalid asrc input :%d\n", + __func__, asrc_in); ret = -EINVAL; goto done; }; @@ -3374,23 +3519,30 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec, switch (event) { case SND_SOC_DAPM_PRE_PMU: if (tavil->asrc_users[asrc] == 0) { - if ((snd_soc_read(codec, clk_reg) & 0x02) || - (snd_soc_read(codec, paired_reg) & 0x02)) { - snd_soc_update_bits(codec, clk_reg, - 0x02, 0x00); - snd_soc_update_bits(codec, paired_reg, - 0x02, 0x00); + if ((snd_soc_component_read32( + component, clk_reg) & 0x02) || + (snd_soc_component_read32( + component, paired_reg) & 0x02)) { + snd_soc_component_update_bits( + component, clk_reg, 0x02, 0x00); + snd_soc_component_update_bits( + component, paired_reg, 0x02, 0x00); } - snd_soc_update_bits(codec, cfg_reg, 0x80, 0x80); - snd_soc_update_bits(codec, clk_reg, 0x01, 0x01); - main_sr = snd_soc_read(codec, ctl_reg) & 0x0F; + snd_soc_component_update_bits( + component, cfg_reg, 0x80, 0x80); + snd_soc_component_update_bits( + component, clk_reg, 0x01, 0x01); + main_sr = snd_soc_component_read32( + component, ctl_reg) & 0x0F; mix_ctl_reg = ctl_reg + 5; - mix_sr = snd_soc_read(codec, mix_ctl_reg) & 0x0F; + mix_sr = snd_soc_component_read32( + component, mix_ctl_reg) & 0x0F; asrc_mode = tavil_get_asrc_mode(tavil, asrc, main_sr, mix_sr); - dev_dbg(codec->dev, "%s: main_sr:%d mix_sr:%d asrc_mode %d\n", + dev_dbg(component->dev, "%s: main_sr:%d mix_sr:%d asrc_mode %d\n", __func__, main_sr, mix_sr, asrc_mode); - snd_soc_update_bits(codec, asrc_ctl, 0x07, asrc_mode); + snd_soc_component_update_bits(component, asrc_ctl, + 0x07, asrc_mode); } tavil->asrc_users[asrc]++; break; @@ -3398,14 +3550,17 @@ static int tavil_codec_enable_asrc(struct snd_soc_codec *codec, tavil->asrc_users[asrc]--; if (tavil->asrc_users[asrc] <= 0) { tavil->asrc_users[asrc] = 0; - snd_soc_update_bits(codec, asrc_ctl, 0x07, 0x00); - snd_soc_update_bits(codec, cfg_reg, 0x80, 0x00); - snd_soc_update_bits(codec, clk_reg, 0x03, 0x02); + snd_soc_component_update_bits(component, asrc_ctl, + 0x07, 0x00); + snd_soc_component_update_bits(component, cfg_reg, + 0x80, 0x00); + snd_soc_component_update_bits(component, clk_reg, + 0x03, 0x02); } break; }; - dev_dbg(codec->dev, "%s: ASRC%d, users: %d\n", + dev_dbg(component->dev, "%s: ASRC%d, users: %d\n", __func__, asrc, tavil->asrc_users[asrc]); done: @@ -3416,13 +3571,15 @@ static int tavil_codec_enable_asrc_resampler(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); int ret = 0; u8 cfg, asrc_in; - cfg = snd_soc_read(codec, WCD934X_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0); + cfg = snd_soc_component_read32(component, + WCD934X_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0); if (!(cfg & 0xFF)) { - dev_err(codec->dev, "%s: ASRC%u input not selected\n", + dev_err(component->dev, "%s: ASRC%u input not selected\n", __func__, w->shift); return -EINVAL; } @@ -3430,22 +3587,22 @@ static int tavil_codec_enable_asrc_resampler(struct snd_soc_dapm_widget *w, switch (w->shift) { case ASRC0: asrc_in = ((cfg & 0x03) == 1) ? ASRC_IN_HPHL : ASRC_IN_LO1; - ret = tavil_codec_enable_asrc(codec, asrc_in, event); + ret = tavil_codec_enable_asrc(component, asrc_in, event); break; case ASRC1: asrc_in = ((cfg & 0x0C) == 4) ? ASRC_IN_HPHR : ASRC_IN_LO2; - ret = tavil_codec_enable_asrc(codec, asrc_in, event); + ret = tavil_codec_enable_asrc(component, asrc_in, event); break; case ASRC2: asrc_in = ((cfg & 0x30) == 0x20) ? ASRC_IN_SPKR1 : ASRC_INVALID; - ret = tavil_codec_enable_asrc(codec, asrc_in, event); + ret = tavil_codec_enable_asrc(component, asrc_in, event); break; case ASRC3: asrc_in = ((cfg & 0xC0) == 0x80) ? ASRC_IN_SPKR2 : ASRC_INVALID; - ret = tavil_codec_enable_asrc(codec, asrc_in, event); + ret = tavil_codec_enable_asrc(component, asrc_in, event); break; default: - dev_err(codec->dev, "%s: Invalid asrc:%u\n", __func__, + dev_err(component->dev, "%s: Invalid asrc:%u\n", __func__, w->shift); ret = -EINVAL; break; @@ -3457,26 +3614,31 @@ static int tavil_codec_enable_asrc_resampler(struct snd_soc_dapm_widget *w, static int tavil_enable_native_supply(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); switch (event) { case SND_SOC_DAPM_PRE_PMU: if (++tavil->native_clk_users == 1) { - snd_soc_update_bits(codec, WCD934X_CLK_SYS_PLL_ENABLES, - 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_CLK_SYS_PLL_ENABLES, + 0x01, 0x01); usleep_range(100, 120); - snd_soc_update_bits(codec, WCD934X_CLK_SYS_MCLK2_PRG1, - 0x06, 0x02); - snd_soc_update_bits(codec, WCD934X_CLK_SYS_MCLK2_PRG1, - 0x01, 0x01); - snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_GATE, - 0x04, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CLK_SYS_MCLK2_PRG1, + 0x06, 0x02); + snd_soc_component_update_bits(component, + WCD934X_CLK_SYS_MCLK2_PRG1, + 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_CODEC_RPM_CLK_GATE, + 0x04, 0x00); usleep_range(30, 50); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x02, 0x02); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x10, 0x10); } @@ -3484,39 +3646,42 @@ static int tavil_enable_native_supply(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMD: if (tavil->native_clk_users && (--tavil->native_clk_users == 0)) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x10, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD934X_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x02, 0x00); - snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_GATE, - 0x04, 0x04); - snd_soc_update_bits(codec, WCD934X_CLK_SYS_MCLK2_PRG1, - 0x01, 0x00); - snd_soc_update_bits(codec, WCD934X_CLK_SYS_MCLK2_PRG1, - 0x06, 0x00); - snd_soc_update_bits(codec, WCD934X_CLK_SYS_PLL_ENABLES, - 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CODEC_RPM_CLK_GATE, + 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD934X_CLK_SYS_MCLK2_PRG1, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CLK_SYS_MCLK2_PRG1, + 0x06, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CLK_SYS_PLL_ENABLES, + 0x01, 0x00); } break; } - dev_dbg(codec->dev, "%s: native_clk_users: %d, event: %d\n", + dev_dbg(component->dev, "%s: native_clk_users: %d, event: %d\n", __func__, tavil->native_clk_users, event); return 0; } -static void tavil_codec_hphdelay_lutbypass(struct snd_soc_codec *codec, +static void tavil_codec_hphdelay_lutbypass(struct snd_soc_component *component, u16 interp_idx, int event) { - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); u8 hph_dly_mask; u16 hph_lut_bypass_reg = 0; u16 hph_comp_ctrl7 = 0; - switch (interp_idx) { case INTERP_HPHL: hph_dly_mask = 1; @@ -3533,18 +3698,22 @@ static void tavil_codec_hphdelay_lutbypass(struct snd_soc_codec *codec, } if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) { - snd_soc_update_bits(codec, WCD934X_CDC_CLSH_TEST0, + snd_soc_component_update_bits(component, WCD934X_CDC_CLSH_TEST0, hph_dly_mask, 0x0); - snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x80); + snd_soc_component_update_bits(component, hph_lut_bypass_reg, + 0x80, 0x80); if (tavil->hph_mode == CLS_H_ULP) - snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x20); + snd_soc_component_update_bits(component, hph_comp_ctrl7, + 0x20, 0x20); } if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, WCD934X_CDC_CLSH_TEST0, + snd_soc_component_update_bits(component, WCD934X_CDC_CLSH_TEST0, hph_dly_mask, hph_dly_mask); - snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x00); - snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x0); + snd_soc_component_update_bits(component, hph_lut_bypass_reg, + 0x80, 0x00); + snd_soc_component_update_bits(component, hph_comp_ctrl7, + 0x20, 0x0); } } @@ -3553,7 +3722,7 @@ static void tavil_codec_hd2_control(struct tavil_priv *priv, { u16 hd2_scale_reg; u16 hd2_enable_reg = 0; - struct snd_soc_codec *codec = priv->codec; + struct snd_soc_component *component = priv->component; if (TAVIL_IS_1_1(priv->wcd9xxx)) return; @@ -3570,21 +3739,25 @@ static void tavil_codec_hd2_control(struct tavil_priv *priv, } if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { - snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x14); - snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x04); + snd_soc_component_update_bits(component, hd2_scale_reg, + 0x3C, 0x14); + snd_soc_component_update_bits(component, hd2_enable_reg, + 0x04, 0x04); } if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x00); - snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x00); + snd_soc_component_update_bits(component, hd2_enable_reg, + 0x04, 0x00); + snd_soc_component_update_bits(component, hd2_scale_reg, + 0x3C, 0x00); } } -static int tavil_codec_config_ear_spkr_gain(struct snd_soc_codec *codec, +static int tavil_codec_config_ear_spkr_gain(struct snd_soc_component *component, int event, int gain_reg) { int comp_gain_offset, val; - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); switch (tavil->swr.spkr_mode) { /* Compander gain in SPKR_MODE1 case is 12 dB */ @@ -3606,9 +3779,9 @@ static int tavil_codec_config_ear_spkr_gain(struct snd_soc_codec *codec, (tavil->ear_spkr_gain != 0)) { /* For example, val is -8(-12+5-1) for 4dB of gain */ val = comp_gain_offset + tavil->ear_spkr_gain - 1; - snd_soc_write(codec, gain_reg, val); + snd_soc_component_write(component, gain_reg, val); - dev_dbg(codec->dev, "%s: RX7 Volume %d dB\n", + dev_dbg(component->dev, "%s: RX7 Volume %d dB\n", __func__, val); } break; @@ -3621,9 +3794,9 @@ static int tavil_codec_config_ear_spkr_gain(struct snd_soc_codec *codec, (gain_reg == WCD934X_CDC_RX7_RX_VOL_CTL || gain_reg == WCD934X_CDC_RX7_RX_VOL_MIX_CTL) && (tavil->ear_spkr_gain != 0)) { - snd_soc_write(codec, gain_reg, 0x0); + snd_soc_component_write(component, gain_reg, 0x0); - dev_dbg(codec->dev, "%s: Reset RX7 Volume to 0 dB\n", + dev_dbg(component->dev, "%s: Reset RX7 Volume to 0 dB\n", __func__); } break; @@ -3632,10 +3805,10 @@ static int tavil_codec_config_ear_spkr_gain(struct snd_soc_codec *codec, return 0; } -static int tavil_config_compander(struct snd_soc_codec *codec, int interp_n, - int event) +static int tavil_config_compander(struct snd_soc_component *component, + int interp_n, int event) { - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int comp; u16 comp_ctl0_reg, rx_path_cfg0_reg; @@ -3644,7 +3817,7 @@ static int tavil_config_compander(struct snd_soc_codec *codec, int interp_n, return 0; comp = interp_n - 1; - dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n", + dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n", __func__, event, comp + 1, tavil->comp_enabled[comp]); if (!tavil->comp_enabled[comp]) @@ -3655,29 +3828,39 @@ static int tavil_config_compander(struct snd_soc_codec *codec, int interp_n, if (SND_SOC_DAPM_EVENT_ON(event)) { /* Enable Compander Clock */ - snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x01, 0x01); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x02); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x00); + snd_soc_component_update_bits(component, rx_path_cfg0_reg, + 0x02, 0x02); } if (SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00); - snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00); + snd_soc_component_update_bits(component, rx_path_cfg0_reg, + 0x02, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x04, 0x04); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x02); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x01, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x04, 0x00); } return 0; } -static void tavil_codec_idle_detect_control(struct snd_soc_codec *codec, +static void tavil_codec_idle_detect_control(struct snd_soc_component *component, int interp, int event) { int reg = 0, mask, val; - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); if (!tavil->idle_det_cfg.hph_idle_detect_en) return; @@ -3694,12 +3877,13 @@ static void tavil_codec_idle_detect_control(struct snd_soc_codec *codec, } if (reg && SND_SOC_DAPM_EVENT_ON(event)) - snd_soc_update_bits(codec, reg, mask, val); + snd_soc_component_update_bits(component, reg, mask, val); if (reg && SND_SOC_DAPM_EVENT_OFF(event)) { - snd_soc_update_bits(codec, reg, mask, 0x00); + snd_soc_component_update_bits(component, reg, mask, 0x00); tavil->idle_det_cfg.hph_idle_thr = 0; - snd_soc_write(codec, WCD934X_CDC_RX_IDLE_DET_CFG3, 0x0); + snd_soc_component_write(component, WCD934X_CDC_RX_IDLE_DET_CFG3, + 0x0); } } @@ -3707,37 +3891,39 @@ static void tavil_codec_idle_detect_control(struct snd_soc_codec *codec, * tavil_codec_enable_interp_clk - Enable main path Interpolator * clock. * - * @codec: Codec instance + * @component: Codec component instance * @event: Indicates speaker path gain offset value * @intp_idx: Interpolator index * Returns number of main clock users */ -int tavil_codec_enable_interp_clk(struct snd_soc_codec *codec, +int tavil_codec_enable_interp_clk(struct snd_soc_component *component, int event, int interp_idx) { struct tavil_priv *tavil; u16 main_reg; - if (!codec) { - pr_err("%s: codec is NULL\n", __func__); + if (!component) { + pr_err("%s: component is NULL\n", __func__); return -EINVAL; } - tavil = snd_soc_codec_get_drvdata(codec); + tavil = snd_soc_component_get_drvdata(component); main_reg = WCD934X_CDC_RX0_RX_PATH_CTL + (interp_idx * 20); if (SND_SOC_DAPM_EVENT_ON(event)) { if (tavil->main_clk_users[interp_idx] == 0) { /* Main path PGA mute enable */ - snd_soc_update_bits(codec, main_reg, 0x10, 0x10); + snd_soc_component_update_bits(component, main_reg, + 0x10, 0x10); /* Clk enable */ - snd_soc_update_bits(codec, main_reg, 0x20, 0x20); - tavil_codec_idle_detect_control(codec, interp_idx, + snd_soc_component_update_bits(component, main_reg, + 0x20, 0x20); + tavil_codec_idle_detect_control(component, interp_idx, event); tavil_codec_hd2_control(tavil, interp_idx, event); - tavil_codec_hphdelay_lutbypass(codec, interp_idx, + tavil_codec_hphdelay_lutbypass(component, interp_idx, event); - tavil_config_compander(codec, interp_idx, event); + tavil_config_compander(component, interp_idx, event); } tavil->main_clk_users[interp_idx]++; } @@ -3746,23 +3932,27 @@ int tavil_codec_enable_interp_clk(struct snd_soc_codec *codec, tavil->main_clk_users[interp_idx]--; if (tavil->main_clk_users[interp_idx] <= 0) { tavil->main_clk_users[interp_idx] = 0; - tavil_config_compander(codec, interp_idx, event); - tavil_codec_hphdelay_lutbypass(codec, interp_idx, + tavil_config_compander(component, interp_idx, event); + tavil_codec_hphdelay_lutbypass(component, interp_idx, event); tavil_codec_hd2_control(tavil, interp_idx, event); - tavil_codec_idle_detect_control(codec, interp_idx, + tavil_codec_idle_detect_control(component, interp_idx, event); /* Clk Disable */ - snd_soc_update_bits(codec, main_reg, 0x20, 0x00); + snd_soc_component_update_bits(component, main_reg, + 0x20, 0x00); /* Reset enable and disable */ - snd_soc_update_bits(codec, main_reg, 0x40, 0x40); - snd_soc_update_bits(codec, main_reg, 0x40, 0x00); + snd_soc_component_update_bits(component, main_reg, + 0x40, 0x40); + snd_soc_component_update_bits(component, main_reg, + 0x40, 0x00); /* Reset rate to 48K*/ - snd_soc_update_bits(codec, main_reg, 0x0F, 0x04); + snd_soc_component_update_bits(component, main_reg, + 0x0F, 0x04); } } - dev_dbg(codec->dev, "%s event %d main_clk_users %d\n", + dev_dbg(component->dev, "%s event %d main_clk_users %d\n", __func__, event, tavil->main_clk_users[interp_idx]); return tavil->main_clk_users[interp_idx]; @@ -3772,20 +3962,21 @@ EXPORT_SYMBOL(tavil_codec_enable_interp_clk); static int tavil_anc_out_switch_cb(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); - tavil_codec_enable_interp_clk(codec, event, w->shift); + tavil_codec_enable_interp_clk(component, event, w->shift); return 0; } -static int tavil_codec_set_idle_detect_thr(struct snd_soc_codec *codec, +static int tavil_codec_set_idle_detect_thr(struct snd_soc_component *component, int interp, int path_type) { int port_id[4] = { 0, 0, 0, 0 }; int *port_ptr, num_ports; int bit_width = 0, i; int mux_reg, mux_reg_val; - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int dai_id, idle_thr; if ((interp != INTERP_HPHL) && (interp != INTERP_HPHR)) @@ -3805,7 +3996,8 @@ static int tavil_codec_set_idle_detect_thr(struct snd_soc_codec *codec, if (path_type == INTERP_MIX_PATH) { mux_reg = WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG1 + 2 * (interp - 1); - mux_reg_val = snd_soc_read(codec, mux_reg) & 0x0f; + mux_reg_val = snd_soc_component_read32(component, mux_reg) & + 0x0f; if ((mux_reg_val >= INTn_2_INP_SEL_RX0) && (mux_reg_val < INTn_2_INP_SEL_PROXIMITY)) { @@ -3818,7 +4010,8 @@ static int tavil_codec_set_idle_detect_thr(struct snd_soc_codec *codec, if (path_type == INTERP_MAIN_PATH) { mux_reg = WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG0 + 2 * (interp - 1); - mux_reg_val = snd_soc_read(codec, mux_reg) & 0x0f; + mux_reg_val = snd_soc_component_read32(component, mux_reg) & + 0x0f; i = WCD934X_INTERP_MUX_NUM_INPUTS; while (i) { @@ -3829,14 +4022,14 @@ static int tavil_codec_set_idle_detect_thr(struct snd_soc_codec *codec, INTn_1_INP_SEL_RX0; num_ports++; } - mux_reg_val = (snd_soc_read(codec, mux_reg) & - 0xf0) >> 4; + mux_reg_val = (snd_soc_component_read32( + component, mux_reg) & 0xf0) >> 4; mux_reg += 1; i--; } } - dev_dbg(codec->dev, "%s: num_ports: %d, ports[%d %d %d %d]\n", + dev_dbg(component->dev, "%s: num_ports: %d, ports[%d %d %d %d]\n", __func__, num_ports, port_id[0], port_id[1], port_id[2], port_id[3]); @@ -3846,7 +4039,7 @@ static int tavil_codec_set_idle_detect_thr(struct snd_soc_codec *codec, tavil); if ((dai_id >= 0) && (dai_id < NUM_CODEC_DAIS)) { - dev_dbg(codec->dev, "%s: dai_id: %d bit_width: %d\n", + dev_dbg(component->dev, "%s: dai_id: %d bit_width: %d\n", __func__, dai_id, tavil->dai[dai_id].bit_width); @@ -3870,12 +4063,13 @@ static int tavil_codec_set_idle_detect_thr(struct snd_soc_codec *codec, break; } - dev_dbg(codec->dev, "%s: (new) idle_thr: %d, (cur) idle_thr: %d\n", + dev_dbg(component->dev, "%s: (new) idle_thr: %d, (cur) idle_thr: %d\n", __func__, idle_thr, tavil->idle_det_cfg.hph_idle_thr); if ((tavil->idle_det_cfg.hph_idle_thr == 0) || (idle_thr < tavil->idle_det_cfg.hph_idle_thr)) { - snd_soc_write(codec, WCD934X_CDC_RX_IDLE_DET_CFG3, idle_thr); + snd_soc_component_write(component, WCD934X_CDC_RX_IDLE_DET_CFG3, + idle_thr); tavil->idle_det_cfg.hph_idle_thr = idle_thr; } @@ -3886,15 +4080,16 @@ static int tavil_codec_enable_mix_path(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); u16 gain_reg, mix_reg; int offset_val = 0; int val = 0; if (w->shift >= WCD934X_NUM_INTERPOLATORS || w->shift == INTERP_LO3_NA || w->shift == INTERP_LO4_NA) { - dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", + dev_err(component->dev, "%s: Invalid Interpolator value %d for name %s\n", __func__, w->shift, w->name); return -EINVAL; }; @@ -3909,11 +4104,11 @@ static int tavil_codec_enable_mix_path(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - tavil_codec_set_idle_detect_thr(codec, w->shift, + tavil_codec_set_idle_detect_thr(component, w->shift, INTERP_MIX_PATH); - tavil_codec_enable_interp_clk(codec, event, w->shift); + tavil_codec_enable_interp_clk(component, event, w->shift); /* Clk enable */ - snd_soc_update_bits(codec, mix_reg, 0x20, 0x20); + snd_soc_component_update_bits(component, mix_reg, 0x20, 0x20); break; case SND_SOC_DAPM_POST_PMU: if ((tavil->swr.spkr_gain_offset == @@ -3922,30 +4117,32 @@ static int tavil_codec_enable_mix_path(struct snd_soc_dapm_widget *w, tavil->comp_enabled[COMPANDER_8]) && (gain_reg == WCD934X_CDC_RX7_RX_VOL_MIX_CTL || gain_reg == WCD934X_CDC_RX8_RX_VOL_MIX_CTL)) { - snd_soc_update_bits(codec, WCD934X_CDC_RX7_RX_PATH_SEC1, - 0x01, 0x01); - snd_soc_update_bits(codec, - WCD934X_CDC_RX7_RX_PATH_MIX_SEC0, - 0x01, 0x01); - snd_soc_update_bits(codec, WCD934X_CDC_RX8_RX_PATH_SEC1, - 0x01, 0x01); - snd_soc_update_bits(codec, - WCD934X_CDC_RX8_RX_PATH_MIX_SEC0, - 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x01); offset_val = -2; } - val = snd_soc_read(codec, gain_reg); + val = snd_soc_component_read32(component, gain_reg); val += offset_val; - snd_soc_write(codec, gain_reg, val); - tavil_codec_config_ear_spkr_gain(codec, event, gain_reg); + snd_soc_component_write(component, gain_reg, val); + tavil_codec_config_ear_spkr_gain(component, event, gain_reg); break; case SND_SOC_DAPM_POST_PMD: /* Clk Disable */ - snd_soc_update_bits(codec, mix_reg, 0x20, 0x00); - tavil_codec_enable_interp_clk(codec, event, w->shift); + snd_soc_component_update_bits(component, mix_reg, 0x20, 0x00); + tavil_codec_enable_interp_clk(component, event, w->shift); /* Reset enable and disable */ - snd_soc_update_bits(codec, mix_reg, 0x40, 0x40); - snd_soc_update_bits(codec, mix_reg, 0x40, 0x00); + snd_soc_component_update_bits(component, mix_reg, 0x40, 0x40); + snd_soc_component_update_bits(component, mix_reg, 0x40, 0x00); if ((tavil->swr.spkr_gain_offset == WCD934X_RX_GAIN_OFFSET_M1P5_DB) && @@ -3953,25 +4150,28 @@ static int tavil_codec_enable_mix_path(struct snd_soc_dapm_widget *w, tavil->comp_enabled[COMPANDER_8]) && (gain_reg == WCD934X_CDC_RX7_RX_VOL_MIX_CTL || gain_reg == WCD934X_CDC_RX8_RX_VOL_MIX_CTL)) { - snd_soc_update_bits(codec, WCD934X_CDC_RX7_RX_PATH_SEC1, - 0x01, 0x00); - snd_soc_update_bits(codec, - WCD934X_CDC_RX7_RX_PATH_MIX_SEC0, - 0x01, 0x00); - snd_soc_update_bits(codec, WCD934X_CDC_RX8_RX_PATH_SEC1, - 0x01, 0x00); - snd_soc_update_bits(codec, - WCD934X_CDC_RX8_RX_PATH_MIX_SEC0, - 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x00); offset_val = 2; - val = snd_soc_read(codec, gain_reg); + val = snd_soc_component_read32(component, gain_reg); val += offset_val; - snd_soc_write(codec, gain_reg, val); + snd_soc_component_write(component, gain_reg, val); } - tavil_codec_config_ear_spkr_gain(codec, event, gain_reg); + tavil_codec_config_ear_spkr_gain(component, event, gain_reg); break; }; - dev_dbg(codec->dev, "%s event %d name %s\n", __func__, event, w->name); + dev_dbg(component->dev, "%s event %d name %s\n", __func__, + event, w->name); return 0; } @@ -3979,18 +4179,19 @@ static int tavil_codec_enable_mix_path(struct snd_soc_dapm_widget *w, /** * tavil_get_dsd_config - Get pointer to dsd config structure * - * @codec: pointer to snd_soc_codec structure + * @component: pointer to snd_soc_component structure * * Returns pointer to tavil_dsd_config structure */ -struct tavil_dsd_config *tavil_get_dsd_config(struct snd_soc_codec *codec) +struct tavil_dsd_config *tavil_get_dsd_config( + struct snd_soc_component *component) { struct tavil_priv *tavil; - if (!codec) + if (!component) return NULL; - tavil = snd_soc_codec_get_drvdata(codec); + tavil = snd_soc_component_get_drvdata(component); if (!tavil) return NULL; @@ -4003,18 +4204,19 @@ static int tavil_codec_enable_main_path(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); u16 gain_reg; u16 reg; int val; int offset_val = 0; - dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name); + dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name); if (w->shift >= WCD934X_NUM_INTERPOLATORS || w->shift == INTERP_LO3_NA || w->shift == INTERP_LO4_NA) { - dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n", + dev_err(component->dev, "%s: Invalid Interpolator value %d for name %s\n", __func__, w->shift, w->name); return -EINVAL; }; @@ -4026,9 +4228,9 @@ static int tavil_codec_enable_main_path(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - tavil_codec_set_idle_detect_thr(codec, w->shift, + tavil_codec_set_idle_detect_thr(component, w->shift, INTERP_MAIN_PATH); - tavil_codec_enable_interp_clk(codec, event, w->shift); + tavil_codec_enable_interp_clk(component, event, w->shift); break; case SND_SOC_DAPM_POST_PMU: /* apply gain after int clk is enabled */ @@ -4038,25 +4240,27 @@ static int tavil_codec_enable_main_path(struct snd_soc_dapm_widget *w, tavil->comp_enabled[COMPANDER_8]) && (gain_reg == WCD934X_CDC_RX7_RX_VOL_CTL || gain_reg == WCD934X_CDC_RX8_RX_VOL_CTL)) { - snd_soc_update_bits(codec, WCD934X_CDC_RX7_RX_PATH_SEC1, - 0x01, 0x01); - snd_soc_update_bits(codec, - WCD934X_CDC_RX7_RX_PATH_MIX_SEC0, - 0x01, 0x01); - snd_soc_update_bits(codec, WCD934X_CDC_RX8_RX_PATH_SEC1, - 0x01, 0x01); - snd_soc_update_bits(codec, - WCD934X_CDC_RX8_RX_PATH_MIX_SEC0, - 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x01); offset_val = -2; } - val = snd_soc_read(codec, gain_reg); + val = snd_soc_component_read32(component, gain_reg); val += offset_val; - snd_soc_write(codec, gain_reg, val); - tavil_codec_config_ear_spkr_gain(codec, event, gain_reg); + snd_soc_component_write(component, gain_reg, val); + tavil_codec_config_ear_spkr_gain(component, event, gain_reg); break; case SND_SOC_DAPM_POST_PMD: - tavil_codec_enable_interp_clk(codec, event, w->shift); + tavil_codec_enable_interp_clk(component, event, w->shift); if ((tavil->swr.spkr_gain_offset == WCD934X_RX_GAIN_OFFSET_M1P5_DB) && @@ -4064,22 +4268,24 @@ static int tavil_codec_enable_main_path(struct snd_soc_dapm_widget *w, tavil->comp_enabled[COMPANDER_8]) && (gain_reg == WCD934X_CDC_RX7_RX_VOL_CTL || gain_reg == WCD934X_CDC_RX8_RX_VOL_CTL)) { - snd_soc_update_bits(codec, WCD934X_CDC_RX7_RX_PATH_SEC1, - 0x01, 0x00); - snd_soc_update_bits(codec, - WCD934X_CDC_RX7_RX_PATH_MIX_SEC0, - 0x01, 0x00); - snd_soc_update_bits(codec, WCD934X_CDC_RX8_RX_PATH_SEC1, - 0x01, 0x00); - snd_soc_update_bits(codec, - WCD934X_CDC_RX8_RX_PATH_MIX_SEC0, - 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX7_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX8_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CDC_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x00); offset_val = 2; - val = snd_soc_read(codec, gain_reg); + val = snd_soc_component_read32(component, gain_reg); val += offset_val; - snd_soc_write(codec, gain_reg, val); + snd_soc_component_write(component, gain_reg, val); } - tavil_codec_config_ear_spkr_gain(codec, event, gain_reg); + tavil_codec_config_ear_spkr_gain(component, event, gain_reg); break; }; @@ -4089,42 +4295,43 @@ static int tavil_codec_enable_main_path(struct snd_soc_dapm_widget *w, static int tavil_codec_set_iir_gain(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); - dev_dbg(codec->dev, "%s: event = %d\n", __func__, event); + dev_dbg(component->dev, "%s: event = %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_POST_PMU: /* fall through */ case SND_SOC_DAPM_PRE_PMD: if (strnstr(w->name, "IIR0", sizeof("IIR0"))) { - snd_soc_write(codec, + snd_soc_component_write(component, WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)); } else { - snd_soc_write(codec, + snd_soc_component_write(component, WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL)); - snd_soc_write(codec, + snd_soc_component_write(component, WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, - snd_soc_read(codec, + snd_soc_component_read32(component, WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL)); } break; @@ -4132,7 +4339,7 @@ static int tavil_codec_set_iir_gain(struct snd_soc_dapm_widget *w, return 0; } -static int tavil_codec_find_amic_input(struct snd_soc_codec *codec, +static int tavil_codec_find_amic_input(struct snd_soc_component *component, int adc_mux_n) { u16 mask, shift, adc_mux_in_reg; @@ -4192,15 +4399,16 @@ static int tavil_codec_find_amic_input(struct snd_soc_codec *codec, adc_mux_n - 5; } - is_amic = (((snd_soc_read(codec, adc_mux_in_reg) & mask) >> shift) + is_amic = (((snd_soc_component_read32(component, adc_mux_in_reg) & + mask) >> shift) == 1); if (!is_amic) return 0; - return snd_soc_read(codec, amic_mux_sel_reg) & 0x07; + return snd_soc_component_read32(component, amic_mux_sel_reg) & 0x07; } -static void tavil_codec_set_tx_hold(struct snd_soc_codec *codec, +static void tavil_codec_set_tx_hold(struct snd_soc_component *component, u16 amic_reg, bool set) { u8 mask = 0x20; @@ -4215,14 +4423,16 @@ static void tavil_codec_set_tx_hold(struct snd_soc_codec *codec, switch (amic_reg) { case WCD934X_ANA_AMIC1: case WCD934X_ANA_AMIC2: - snd_soc_update_bits(codec, WCD934X_ANA_AMIC2, mask, val); + snd_soc_component_update_bits(component, WCD934X_ANA_AMIC2, + mask, val); break; case WCD934X_ANA_AMIC3: case WCD934X_ANA_AMIC4: - snd_soc_update_bits(codec, WCD934X_ANA_AMIC4, mask, val); + snd_soc_component_update_bits(component, WCD934X_ANA_AMIC4, + mask, val); break; default: - dev_dbg(codec->dev, "%s: invalid amic: %d\n", + dev_dbg(component->dev, "%s: invalid amic: %d\n", __func__, amic_reg); break; } @@ -4232,15 +4442,16 @@ static int tavil_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { int adc_mux_n = w->shift; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int amic_n; - dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); + dev_dbg(component->dev, "%s: event: %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_POST_PMU: - amic_n = tavil_codec_find_amic_input(codec, adc_mux_n); + amic_n = tavil_codec_find_amic_input(component, adc_mux_n); if (amic_n) { /* * Prevent ANC Rx pop by leaving Tx FE in HOLD @@ -4258,7 +4469,8 @@ static int tavil_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w, return 0; } -static u16 tavil_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic) +static u16 tavil_codec_get_amic_pwlvl_reg(struct snd_soc_component *component, + int amic) { u16 pwr_level_reg = 0; @@ -4273,7 +4485,7 @@ static u16 tavil_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic) pwr_level_reg = WCD934X_ANA_AMIC3; break; default: - dev_dbg(codec->dev, "%s: invalid amic: %d\n", + dev_dbg(component->dev, "%s: invalid amic: %d\n", __func__, amic); break; } @@ -4291,7 +4503,7 @@ static void tavil_tx_hpf_corner_freq_callback(struct work_struct *work) struct delayed_work *hpf_delayed_work; struct hpf_work *hpf_work; struct tavil_priv *tavil; - struct snd_soc_codec *codec; + struct snd_soc_component *component; u16 dec_cfg_reg, amic_reg, go_bit_reg; u8 hpf_cut_off_freq; int amic_n; @@ -4299,26 +4511,27 @@ static void tavil_tx_hpf_corner_freq_callback(struct work_struct *work) hpf_delayed_work = to_delayed_work(work); hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); tavil = hpf_work->tavil; - codec = tavil->codec; + component = tavil->component; hpf_cut_off_freq = hpf_work->hpf_cut_off_freq; dec_cfg_reg = WCD934X_CDC_TX0_TX_PATH_CFG0 + 16 * hpf_work->decimator; go_bit_reg = dec_cfg_reg + 7; - dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", + dev_dbg(component->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", __func__, hpf_work->decimator, hpf_cut_off_freq); - amic_n = tavil_codec_find_amic_input(codec, hpf_work->decimator); + amic_n = tavil_codec_find_amic_input(component, hpf_work->decimator); if (amic_n) { amic_reg = WCD934X_ANA_AMIC1 + amic_n - 1; - tavil_codec_set_tx_hold(codec, amic_reg, false); + tavil_codec_set_tx_hold(component, amic_reg, false); } - snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, - hpf_cut_off_freq << 5); - snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x02); + snd_soc_component_update_bits(component, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_component_update_bits(component, go_bit_reg, 0x02, 0x02); /* Minimum 1 clk cycle delay is required as per HW spec */ usleep_range(1000, 1010); - snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x00); + snd_soc_component_update_bits(component, go_bit_reg, 0x02, 0x00); } static void tavil_tx_mute_update_callback(struct work_struct *work) @@ -4326,40 +4539,43 @@ static void tavil_tx_mute_update_callback(struct work_struct *work) struct tx_mute_work *tx_mute_dwork; struct tavil_priv *tavil; struct delayed_work *delayed_work; - struct snd_soc_codec *codec; + struct snd_soc_component *component; u16 tx_vol_ctl_reg, hpf_gate_reg; delayed_work = to_delayed_work(work); tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); tavil = tx_mute_dwork->tavil; - codec = tavil->codec; + component = tavil->component; tx_vol_ctl_reg = WCD934X_CDC_TX0_TX_PATH_CTL + 16 * tx_mute_dwork->decimator; hpf_gate_reg = WCD934X_CDC_TX0_TX_PATH_SEC2 + 16 * tx_mute_dwork->decimator; - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x00); } static int tavil_codec_enable_rx_path_clk(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); u16 sidetone_reg; - dev_dbg(codec->dev, "%s %d %d\n", __func__, event, w->shift); + dev_dbg(component->dev, "%s %d %d\n", __func__, event, w->shift); sidetone_reg = WCD934X_CDC_RX0_RX_PATH_CFG1 + 0x14*(w->shift); switch (event) { case SND_SOC_DAPM_PRE_PMU: if (!strcmp(w->name, "RX INT7 MIX2 INP")) __tavil_codec_enable_swr(w, event); - tavil_codec_enable_interp_clk(codec, event, w->shift); - snd_soc_update_bits(codec, sidetone_reg, 0x10, 0x10); + tavil_codec_enable_interp_clk(component, event, w->shift); + snd_soc_component_update_bits(component, sidetone_reg, + 0x10, 0x10); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, sidetone_reg, 0x10, 0x00); - tavil_codec_enable_interp_clk(codec, event, w->shift); + snd_soc_component_update_bits(component, sidetone_reg, + 0x10, 0x00); + tavil_codec_enable_interp_clk(component, event, w->shift); if (!strcmp(w->name, "RX INT7 MIX2 INP")) __tavil_codec_enable_swr(w, event); break; @@ -4372,8 +4588,9 @@ static int tavil_codec_enable_rx_path_clk(struct snd_soc_dapm_widget *w, static int tavil_codec_enable_dec(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); unsigned int decimator; char *dec_adc_mux_name = NULL; char *widget_name = NULL; @@ -4384,7 +4601,7 @@ static int tavil_codec_enable_dec(struct snd_soc_dapm_widget *w, char *dec; u8 hpf_cut_off_freq; - dev_dbg(codec->dev, "%s %d\n", __func__, event); + dev_dbg(component->dev, "%s %d\n", __func__, event); widget_name = kstrndup(w->name, 15, GFP_KERNEL); if (!widget_name) @@ -4393,7 +4610,7 @@ static int tavil_codec_enable_dec(struct snd_soc_dapm_widget *w, wname = widget_name; dec_adc_mux_name = strsep(&widget_name, " "); if (!dec_adc_mux_name) { - dev_err(codec->dev, "%s: Invalid decimator = %s\n", + dev_err(component->dev, "%s: Invalid decimator = %s\n", __func__, w->name); ret = -EINVAL; goto out; @@ -4402,7 +4619,7 @@ static int tavil_codec_enable_dec(struct snd_soc_dapm_widget *w, dec = strpbrk(dec_adc_mux_name, "012345678"); if (!dec) { - dev_err(codec->dev, "%s: decimator index not found\n", + dev_err(component->dev, "%s: decimator index not found\n", __func__); ret = -EINVAL; goto out; @@ -4410,13 +4627,13 @@ static int tavil_codec_enable_dec(struct snd_soc_dapm_widget *w, ret = kstrtouint(dec, 10, &decimator); if (ret < 0) { - dev_err(codec->dev, "%s: Invalid decimator = %s\n", + dev_err(component->dev, "%s: Invalid decimator = %s\n", __func__, wname); ret = -EINVAL; goto out; } - dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__, + dev_dbg(component->dev, "%s(): widget = %s decimator = %u\n", __func__, w->name, decimator); tx_vol_ctl_reg = WCD934X_CDC_TX0_TX_PATH_CTL + 16 * decimator; @@ -4426,55 +4643,63 @@ static int tavil_codec_enable_dec(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - amic_n = tavil_codec_find_amic_input(codec, decimator); + amic_n = tavil_codec_find_amic_input(component, decimator); if (amic_n) - pwr_level_reg = tavil_codec_get_amic_pwlvl_reg(codec, - amic_n); + pwr_level_reg = tavil_codec_get_amic_pwlvl_reg( + component, amic_n); if (pwr_level_reg) { - switch ((snd_soc_read(codec, pwr_level_reg) & - WCD934X_AMIC_PWR_LVL_MASK) >> - WCD934X_AMIC_PWR_LVL_SHIFT) { + switch ((snd_soc_component_read32( + component, pwr_level_reg) & + WCD934X_AMIC_PWR_LVL_MASK) >> + WCD934X_AMIC_PWR_LVL_SHIFT) { case WCD934X_AMIC_PWR_LEVEL_LP: - snd_soc_update_bits(codec, dec_cfg_reg, - WCD934X_DEC_PWR_LVL_MASK, - WCD934X_DEC_PWR_LVL_LP); + snd_soc_component_update_bits( + component, dec_cfg_reg, + WCD934X_DEC_PWR_LVL_MASK, + WCD934X_DEC_PWR_LVL_LP); break; case WCD934X_AMIC_PWR_LEVEL_HP: - snd_soc_update_bits(codec, dec_cfg_reg, - WCD934X_DEC_PWR_LVL_MASK, - WCD934X_DEC_PWR_LVL_HP); + snd_soc_component_update_bits( + component, dec_cfg_reg, + WCD934X_DEC_PWR_LVL_MASK, + WCD934X_DEC_PWR_LVL_HP); break; case WCD934X_AMIC_PWR_LEVEL_DEFAULT: case WCD934X_AMIC_PWR_LEVEL_HYBRID: default: - snd_soc_update_bits(codec, dec_cfg_reg, - WCD934X_DEC_PWR_LVL_MASK, - WCD934X_DEC_PWR_LVL_DF); + snd_soc_component_update_bits( + component, dec_cfg_reg, + WCD934X_DEC_PWR_LVL_MASK, + WCD934X_DEC_PWR_LVL_DF); break; } } /* Enable TX PGA Mute */ - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x10, 0x10); break; case SND_SOC_DAPM_POST_PMU: - hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) & - TX_HPF_CUT_OFF_FREQ_MASK) >> 5; + hpf_cut_off_freq = (snd_soc_component_read32( + component, dec_cfg_reg) & + TX_HPF_CUT_OFF_FREQ_MASK) >> 5; tavil->tx_hpf_work[decimator].hpf_cut_off_freq = hpf_cut_off_freq; if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { - snd_soc_update_bits(codec, dec_cfg_reg, + snd_soc_component_update_bits(component, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, CF_MIN_3DB_150HZ << 5); - snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02); + snd_soc_component_update_bits(component, hpf_gate_reg, + 0x02, 0x02); /* * Minimum 1 clk cycle delay is required as per * HW spec. */ usleep_range(1000, 1010); - snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00); + snd_soc_component_update_bits(component, hpf_gate_reg, + 0x02, 0x00); } /* schedule work queue to Remove Mute */ schedule_delayed_work(&tavil->tx_mute_dwork[decimator].dwork, @@ -4485,36 +4710,42 @@ static int tavil_codec_enable_dec(struct snd_soc_dapm_widget *w, &tavil->tx_hpf_work[decimator].dwork, msecs_to_jiffies(300)); /* apply gain after decimator is enabled */ - snd_soc_write(codec, tx_gain_ctl_reg, - snd_soc_read(codec, tx_gain_ctl_reg)); + snd_soc_component_write(component, tx_gain_ctl_reg, + snd_soc_component_read32( + component, tx_gain_ctl_reg)); break; case SND_SOC_DAPM_PRE_PMD: hpf_cut_off_freq = tavil->tx_hpf_work[decimator].hpf_cut_off_freq; - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x10, 0x10); if (cancel_delayed_work_sync( &tavil->tx_hpf_work[decimator].dwork)) { if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { - snd_soc_update_bits(codec, dec_cfg_reg, - TX_HPF_CUT_OFF_FREQ_MASK, - hpf_cut_off_freq << 5); - snd_soc_update_bits(codec, hpf_gate_reg, - 0x02, 0x02); + snd_soc_component_update_bits(component, + dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_component_update_bits(component, + hpf_gate_reg, + 0x02, 0x02); /* * Minimum 1 clk cycle delay is required as per * HW spec. */ usleep_range(1000, 1010); - snd_soc_update_bits(codec, hpf_gate_reg, - 0x02, 0x00); + snd_soc_component_update_bits(component, + hpf_gate_reg, + 0x02, 0x00); } } cancel_delayed_work_sync( &tavil->tx_mute_dwork[decimator].dwork); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); - snd_soc_update_bits(codec, dec_cfg_reg, + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x10, 0x00); + snd_soc_component_update_bits(component, dec_cfg_reg, WCD934X_DEC_PWR_LVL_MASK, WCD934X_DEC_PWR_LVL_DF); break; @@ -4524,7 +4755,7 @@ static int tavil_codec_enable_dec(struct snd_soc_dapm_widget *w, return ret; } -static u32 tavil_get_dmic_sample_rate(struct snd_soc_codec *codec, +static u32 tavil_get_dmic_sample_rate(struct snd_soc_component *component, unsigned int dmic, struct wcd9xxx_pdata *pdata) { @@ -4545,7 +4776,8 @@ static u32 tavil_get_dmic_sample_rate(struct snd_soc_codec *codec, ++adc_mux_index; continue; } - adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) & + adc_mux_sel = ((snd_soc_component_read32( + component, adc_mux_ctl_reg) & 0xF8) >> 3) - 1; if (adc_mux_sel == dmic) { @@ -4558,7 +4790,8 @@ static u32 tavil_get_dmic_sample_rate(struct snd_soc_codec *codec, if (dec_found && adc_mux_index <= 8) { tx_fs_reg = WCD934X_CDC_TX0_TX_PATH_CTL + (16 * adc_mux_index); - tx_stream_fs = snd_soc_read(codec, tx_fs_reg) & 0x0F; + tx_stream_fs = snd_soc_component_read32( + component, tx_fs_reg) & 0x0F; if (tx_stream_fs <= 4) { if (pdata->dmic_sample_rate <= WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ) @@ -4574,13 +4807,13 @@ static u32 tavil_get_dmic_sample_rate(struct snd_soc_codec *codec, return dmic_fs; } -static u8 tavil_get_dmic_clk_val(struct snd_soc_codec *codec, +static u8 tavil_get_dmic_clk_val(struct snd_soc_component *component, u32 mclk_rate, u32 dmic_clk_rate) { u32 div_factor; u8 dmic_ctl_val; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: mclk_rate = %d, dmic_sample_rate = %d\n", __func__, mclk_rate, dmic_clk_rate); @@ -4591,7 +4824,7 @@ static u8 tavil_get_dmic_clk_val(struct snd_soc_codec *codec, dmic_ctl_val = WCD934X_DMIC_CLK_DIV_3; if (dmic_clk_rate == 0) { - dev_err(codec->dev, + dev_err(component->dev, "%s: dmic_sample_rate cannot be 0\n", __func__); goto done; @@ -4618,7 +4851,7 @@ static u8 tavil_get_dmic_clk_val(struct snd_soc_codec *codec, dmic_ctl_val = WCD934X_DMIC_CLK_DIV_16; break; default: - dev_err(codec->dev, + dev_err(component->dev, "%s: Invalid div_factor %u, clk_rate(%u), dmic_rate(%u)\n", __func__, div_factor, mclk_rate, dmic_clk_rate); break; @@ -4631,13 +4864,14 @@ static u8 tavil_get_dmic_clk_val(struct snd_soc_codec *codec, static int tavil_codec_enable_adc(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); - dev_dbg(codec->dev, "%s: event:%d\n", __func__, event); + dev_dbg(component->dev, "%s: event:%d\n", __func__, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - tavil_codec_set_tx_hold(codec, w->reg, true); + tavil_codec_set_tx_hold(component, w->reg, true); break; default: break; @@ -4649,9 +4883,10 @@ static int tavil_codec_enable_adc(struct snd_soc_dapm_widget *w, static int tavil_codec_enable_dmic(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); + struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent); u8 dmic_clk_en = 0x01; u16 dmic_clk_reg; s32 *dmic_clk_cnt; @@ -4663,13 +4898,13 @@ static int tavil_codec_enable_dmic(struct snd_soc_dapm_widget *w, wname = strpbrk(w->name, "012345"); if (!wname) { - dev_err(codec->dev, "%s: widget not found\n", __func__); + dev_err(component->dev, "%s: widget not found\n", __func__); return -EINVAL; } ret = kstrtouint(wname, 10, &dmic); if (ret < 0) { - dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n", + dev_err(component->dev, "%s: Invalid DMIC line on the codec\n", __func__); return -EINVAL; } @@ -4691,42 +4926,42 @@ static int tavil_codec_enable_dmic(struct snd_soc_dapm_widget *w, dmic_clk_reg = WCD934X_CPE_SS_DMIC2_CTL; break; default: - dev_err(codec->dev, "%s: Invalid DMIC Selection\n", + dev_err(component->dev, "%s: Invalid DMIC Selection\n", __func__); return -EINVAL; }; - dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", + dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", __func__, event, dmic, *dmic_clk_cnt); switch (event) { case SND_SOC_DAPM_PRE_PMU: - dmic_sample_rate = tavil_get_dmic_sample_rate(codec, dmic, + dmic_sample_rate = tavil_get_dmic_sample_rate(component, dmic, pdata); dmic_rate_val = - tavil_get_dmic_clk_val(codec, + tavil_get_dmic_clk_val(component, pdata->mclk_rate, dmic_sample_rate); (*dmic_clk_cnt)++; if (*dmic_clk_cnt == 1) { - snd_soc_update_bits(codec, dmic_clk_reg, + snd_soc_component_update_bits(component, dmic_clk_reg, 0x07 << dmic_rate_shift, dmic_rate_val << dmic_rate_shift); - snd_soc_update_bits(codec, dmic_clk_reg, + snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, dmic_clk_en); } break; case SND_SOC_DAPM_POST_PMD: dmic_rate_val = - tavil_get_dmic_clk_val(codec, + tavil_get_dmic_clk_val(component, pdata->mclk_rate, pdata->mad_dmic_sample_rate); (*dmic_clk_cnt)--; if (*dmic_clk_cnt == 0) { - snd_soc_update_bits(codec, dmic_clk_reg, + snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_en, 0); - snd_soc_update_bits(codec, dmic_clk_reg, + snd_soc_component_update_bits(component, dmic_clk_reg, 0x07 << dmic_rate_shift, dmic_rate_val << dmic_rate_shift); } @@ -4738,16 +4973,16 @@ static int tavil_codec_enable_dmic(struct snd_soc_dapm_widget *w, /* * tavil_mbhc_micb_adjust_voltage: adjust specific micbias voltage - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * * @req_volt: micbias voltage to be set * @micb_num: micbias to be set, e.g. micbias1 or micbias2 * * return 0 if adjustment is success or error code in case of failure */ -int tavil_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, +int tavil_mbhc_micb_adjust_voltage(struct snd_soc_component *component, int req_volt, int micb_num) { - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int cur_vout_ctl, req_vout_ctl; int micb_reg, micb_val, micb_en; int ret = 0; @@ -4778,7 +5013,7 @@ int tavil_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, * momentarily, change the micbias value and then re-enable * micbias. */ - micb_val = snd_soc_read(codec, micb_reg); + micb_val = snd_soc_component_read32(component, micb_reg); micb_en = (micb_val & 0xC0) >> 6; cur_vout_ctl = micb_val & 0x3F; @@ -4792,17 +5027,17 @@ int tavil_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, goto exit; } - dev_dbg(codec->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n", + dev_dbg(component->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n", __func__, micb_num, WCD_VOUT_CTL_TO_MICB(cur_vout_ctl), req_volt, micb_en); if (micb_en == 0x1) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + snd_soc_component_update_bits(component, micb_reg, 0xC0, 0x80); - snd_soc_update_bits(codec, micb_reg, 0x3F, req_vout_ctl); + snd_soc_component_update_bits(component, micb_reg, 0x3F, req_vout_ctl); if (micb_en == 0x1) { - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + snd_soc_component_update_bits(component, micb_reg, 0xC0, 0x40); /* * Add 2ms delay as per HW requirement after enabling * micbias @@ -4817,17 +5052,17 @@ EXPORT_SYMBOL(tavil_mbhc_micb_adjust_voltage); /* * tavil_micbias_control: enable/disable micbias - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * * @micb_num: micbias to be enabled/disabled, e.g. micbias1 or micbias2 * @req: control requested, enable/disable or pullup enable/disable * @is_dapm: triggered by dapm or not * * return 0 if control is success or error code in case of failure */ -int tavil_micbias_control(struct snd_soc_codec *codec, +int tavil_micbias_control(struct snd_soc_component *component, int micb_num, int req, bool is_dapm) { - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int micb_index = micb_num - 1; u16 micb_reg; int pre_off_event = 0, post_off_event = 0; @@ -4835,7 +5070,7 @@ int tavil_micbias_control(struct snd_soc_codec *codec, int post_dapm_on = 0; if ((micb_index < 0) || (micb_index > TAVIL_MAX_MICBIAS - 1)) { - dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n", + dev_err(component->dev, "%s: Invalid micbias index, micb_ind:%d\n", __func__, micb_index); return -EINVAL; } @@ -4859,7 +5094,7 @@ int tavil_micbias_control(struct snd_soc_codec *codec, micb_reg = WCD934X_ANA_MICB4; break; default: - dev_err(codec->dev, "%s: Invalid micbias number: %d\n", + dev_err(component->dev, "%s: Invalid micbias number: %d\n", __func__, micb_num); return -EINVAL; } @@ -4870,14 +5105,16 @@ int tavil_micbias_control(struct snd_soc_codec *codec, tavil->pullup_ref[micb_index]++; if ((tavil->pullup_ref[micb_index] == 1) && (tavil->micb_ref[micb_index] == 0)) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x80); break; case MICB_PULLUP_DISABLE: if (tavil->pullup_ref[micb_index] > 0) tavil->pullup_ref[micb_index]--; if ((tavil->pullup_ref[micb_index] == 0) && (tavil->micb_ref[micb_index] == 0)) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x00); break; case MICB_ENABLE: tavil->micb_ref[micb_index]++; @@ -4885,7 +5122,8 @@ int tavil_micbias_control(struct snd_soc_codec *codec, if (tavil->micb_load) regulator_set_load(tavil->micb_load, tavil->micb_load_high); - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x40); if (post_on_event && tavil->mbhc) blocking_notifier_call_chain( &tavil->mbhc->notifier, @@ -4901,7 +5139,8 @@ int tavil_micbias_control(struct snd_soc_codec *codec, tavil->micb_ref[micb_index]--; if ((tavil->micb_ref[micb_index] == 0) && (tavil->pullup_ref[micb_index] > 0)) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x80); else if ((tavil->micb_ref[micb_index] == 0) && (tavil->pullup_ref[micb_index] == 0)) { if (pre_off_event && tavil->mbhc) @@ -4909,7 +5148,8 @@ int tavil_micbias_control(struct snd_soc_codec *codec, &tavil->mbhc->notifier, pre_off_event, &tavil->mbhc->wcd_mbhc); - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x00); if (post_off_event && tavil->mbhc) blocking_notifier_call_chain( &tavil->mbhc->notifier, @@ -4925,7 +5165,7 @@ int tavil_micbias_control(struct snd_soc_codec *codec, break; }; - dev_dbg(codec->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", + dev_dbg(component->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", __func__, micb_num, tavil->micb_ref[micb_index], tavil->pullup_ref[micb_index]); @@ -4938,10 +5178,11 @@ EXPORT_SYMBOL(tavil_micbias_control); static int __tavil_codec_enable_micbias(struct snd_soc_dapm_widget *w, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); int micb_num; - dev_dbg(codec->dev, "%s: wname: %s, event: %d\n", + dev_dbg(component->dev, "%s: wname: %s, event: %d\n", __func__, w->name, event); if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) @@ -4962,14 +5203,14 @@ static int __tavil_codec_enable_micbias(struct snd_soc_dapm_widget *w, * so use ref count to handle micbias pullup * and enable requests */ - tavil_micbias_control(codec, micb_num, MICB_ENABLE, true); + tavil_micbias_control(component, micb_num, MICB_ENABLE, true); break; case SND_SOC_DAPM_POST_PMU: /* wait for cnp time */ usleep_range(1000, 1100); break; case SND_SOC_DAPM_POST_PMD: - tavil_micbias_control(codec, micb_num, MICB_DISABLE, true); + tavil_micbias_control(component, micb_num, MICB_DISABLE, true); break; }; @@ -4978,7 +5219,7 @@ static int __tavil_codec_enable_micbias(struct snd_soc_dapm_widget *w, /* * tavil_codec_enable_standalone_micbias - enable micbias standalone - * @codec: pointer to codec instance + * @component: pointer to codec component instance * @micb_num: number of micbias to be enabled * @enable: true to enable micbias or false to disable * @@ -4987,7 +5228,7 @@ static int __tavil_codec_enable_micbias(struct snd_soc_dapm_widget *w, * * Return: error code in case of failure or 0 for success */ -int tavil_codec_enable_standalone_micbias(struct snd_soc_codec *codec, +int tavil_codec_enable_standalone_micbias(struct snd_soc_component *component, int micb_num, bool enable) { @@ -4998,29 +5239,30 @@ int tavil_codec_enable_standalone_micbias(struct snd_soc_codec *codec, int micb_index = micb_num - 1; int rc; - if (!codec) { - pr_err("%s: Codec memory is NULL\n", __func__); + if (!component) { + pr_err("%s: Component memory is NULL\n", __func__); return -EINVAL; } if ((micb_index < 0) || (micb_index > TAVIL_MAX_MICBIAS - 1)) { - dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n", + dev_err(component->dev, "%s: Invalid micbias index, micb_ind:%d\n", __func__, micb_index); return -EINVAL; } if (enable) rc = snd_soc_dapm_force_enable_pin( - snd_soc_codec_get_dapm(codec), - micb_names[micb_index]); + snd_soc_component_get_dapm(component), + micb_names[micb_index]); else - rc = snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(codec), - micb_names[micb_index]); + rc = snd_soc_dapm_disable_pin( + snd_soc_component_get_dapm(component), + micb_names[micb_index]); if (!rc) - snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec)); + snd_soc_dapm_sync(snd_soc_component_get_dapm(component)); else - dev_err(codec->dev, "%s: micbias%d force %s pin failed\n", + dev_err(component->dev, "%s: micbias%d force %s pin failed\n", __func__, micb_num, (enable ? "enable" : "disable")); return rc; @@ -5032,17 +5274,18 @@ static int tavil_codec_force_enable_micbias(struct snd_soc_dapm_widget *w, int event) { int ret = 0; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); switch (event) { case SND_SOC_DAPM_PRE_PMU: wcd_resmgr_enable_master_bias(tavil->resmgr); - tavil_cdc_mclk_enable(codec, true); + tavil_cdc_mclk_enable(component, true); ret = __tavil_codec_enable_micbias(w, SND_SOC_DAPM_PRE_PMU); /* Wait for 1ms for better cnp */ usleep_range(1000, 1100); - tavil_cdc_mclk_enable(codec, false); + tavil_cdc_mclk_enable(component, false); break; case SND_SOC_DAPM_POST_PMD: ret = __tavil_codec_enable_micbias(w, SND_SOC_DAPM_POST_PMD); @@ -5318,9 +5561,10 @@ static int tavil_codec_reset_hph_registers(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); u8 cache_val[TAVIL_HPH_TOTAL_REG]; u8 hw_val[TAVIL_HPH_TOTAL_REG]; int pa_status; @@ -5347,12 +5591,12 @@ static int tavil_codec_reset_hph_registers(struct snd_soc_dapm_widget *w, /* If both the values are same, it means no corruption */ if (ret) { - dev_dbg(codec->dev, "%s: cache and hw reg are not same\n", + dev_dbg(component->dev, "%s: cache and hw reg are not same\n", __func__); tavil_codec_hph_reg_recover(tavil, wcd9xxx->regmap, pa_status); } else { - dev_dbg(codec->dev, "%s: cache and hw reg are same\n", + dev_dbg(component->dev, "%s: cache and hw reg are same\n", __func__); tavil->mbhc->is_hph_recover = false; } @@ -5397,7 +5641,8 @@ static void tavil_restore_iir_coeff(struct tavil_priv *tavil, int iir_idx, static int tavil_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int iir_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->reg; int band_idx = ((struct soc_multi_mixer_control *) @@ -5405,10 +5650,11 @@ static int tavil_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol, /* IIR filter band registers are at integer multiples of 16 */ u16 iir_reg = WCD934X_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx; - ucontrol->value.integer.value[0] = (snd_soc_read(codec, iir_reg) & - (1 << band_idx)) != 0; + ucontrol->value.integer.value[0] = + (snd_soc_component_read32(component, iir_reg) & + (1 << band_idx)) != 0; - dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, + dev_dbg(component->dev, "%s: IIR #%d band #%d enable %d\n", __func__, iir_idx, band_idx, (uint32_t)ucontrol->value.integer.value[0]); return 0; @@ -5417,8 +5663,9 @@ static int tavil_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol, static int tavil_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int iir_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->reg; int band_idx = ((struct soc_multi_mixer_control *) @@ -5430,56 +5677,56 @@ static int tavil_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol, tavil_restore_iir_coeff(tavil, iir_idx, band_idx); /* Mask first 5 bits, 6-8 are reserved */ - snd_soc_update_bits(codec, iir_reg, (1 << band_idx), + snd_soc_component_update_bits(component, iir_reg, (1 << band_idx), (value << band_idx)); - iir_band_en_status = ((snd_soc_read(codec, iir_reg) & + iir_band_en_status = ((snd_soc_component_read32(component, iir_reg) & (1 << band_idx)) != 0); - dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__, + dev_dbg(component->dev, "%s: IIR #%d band #%d enable %d\n", __func__, iir_idx, band_idx, iir_band_en_status); return 0; } -static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec, +static uint32_t get_iir_band_coeff(struct snd_soc_component *component, int iir_idx, int band_idx, int coeff_idx) { uint32_t value = 0; /* Address does not automatically update if reading */ - snd_soc_write(codec, + snd_soc_component_write(component, (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), ((band_idx * BAND_MAX + coeff_idx) * sizeof(uint32_t)) & 0x7F); - value |= snd_soc_read(codec, + value |= snd_soc_component_read32(component, (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx)); - snd_soc_write(codec, + snd_soc_component_write(component, (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), ((band_idx * BAND_MAX + coeff_idx) * sizeof(uint32_t) + 1) & 0x7F); - value |= (snd_soc_read(codec, + value |= (snd_soc_component_read32(component, (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx)) << 8); - snd_soc_write(codec, + snd_soc_component_write(component, (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), ((band_idx * BAND_MAX + coeff_idx) * sizeof(uint32_t) + 2) & 0x7F); - value |= (snd_soc_read(codec, + value |= (snd_soc_component_read32(component, (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx)) << 16); - snd_soc_write(codec, + snd_soc_component_write(component, (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), ((band_idx * BAND_MAX + coeff_idx) * sizeof(uint32_t) + 3) & 0x7F); /* Mask bits top 2 bits since they are reserved */ - value |= ((snd_soc_read(codec, + value |= ((snd_soc_component_read32(component, (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx)) & 0x3F) << 24); @@ -5489,24 +5736,25 @@ static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec, static int tavil_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int iir_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->reg; int band_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; ucontrol->value.integer.value[0] = - get_iir_band_coeff(codec, iir_idx, band_idx, 0); + get_iir_band_coeff(component, iir_idx, band_idx, 0); ucontrol->value.integer.value[1] = - get_iir_band_coeff(codec, iir_idx, band_idx, 1); + get_iir_band_coeff(component, iir_idx, band_idx, 1); ucontrol->value.integer.value[2] = - get_iir_band_coeff(codec, iir_idx, band_idx, 2); + get_iir_band_coeff(component, iir_idx, band_idx, 2); ucontrol->value.integer.value[3] = - get_iir_band_coeff(codec, iir_idx, band_idx, 3); + get_iir_band_coeff(component, iir_idx, band_idx, 3); ucontrol->value.integer.value[4] = - get_iir_band_coeff(codec, iir_idx, band_idx, 4); + get_iir_band_coeff(component, iir_idx, band_idx, 4); - dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n" + dev_dbg(component->dev, "%s: IIR #%d band #%d b0 = 0x%x\n" "%s: IIR #%d band #%d b1 = 0x%x\n" "%s: IIR #%d band #%d b2 = 0x%x\n" "%s: IIR #%d band #%d a1 = 0x%x\n" @@ -5524,24 +5772,24 @@ static int tavil_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol, return 0; } -static void set_iir_band_coeff(struct snd_soc_codec *codec, +static void set_iir_band_coeff(struct snd_soc_component *component, int iir_idx, int band_idx, uint32_t value) { - snd_soc_write(codec, + snd_soc_component_write(component, (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), (value & 0xFF)); - snd_soc_write(codec, + snd_soc_component_write(component, (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), (value >> 8) & 0xFF); - snd_soc_write(codec, + snd_soc_component_write(component, (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), (value >> 16) & 0xFF); /* Mask top 2 bits, 7-8 are reserved */ - snd_soc_write(codec, + snd_soc_component_write(component, (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx), (value >> 24) & 0x3F); } @@ -5549,8 +5797,9 @@ static void set_iir_band_coeff(struct snd_soc_codec *codec, static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int iir_idx = ((struct soc_multi_mixer_control *) kcontrol->private_value)->reg; int band_idx = ((struct soc_multi_mixer_control *) @@ -5561,7 +5810,7 @@ static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, * Mask top bit it is reserved * Updates addr automatically for each B2 write */ - snd_soc_write(codec, + snd_soc_component_write(component, (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx), (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); @@ -5570,7 +5819,7 @@ static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, coeff_idx++) { uint32_t value = ucontrol->value.integer.value[coeff_idx]; - set_iir_band_coeff(codec, iir_idx, band_idx, value); + set_iir_band_coeff(component, iir_idx, band_idx, value); /* Four 8 bit values(one 32 bit) per coefficient */ tavil->sidetone_coeff_array[iir_idx][band_idx][idx++] = @@ -5589,15 +5838,15 @@ static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol, "%s: IIR #%d band #%d a1 = 0x%x\n" "%s: IIR #%d band #%d a2 = 0x%x\n", __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 0), + get_iir_band_coeff(component, iir_idx, band_idx, 0), __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 1), + get_iir_band_coeff(component, iir_idx, band_idx, 1), __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 2), + get_iir_band_coeff(component, iir_idx, band_idx, 2), __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 3), + get_iir_band_coeff(component, iir_idx, band_idx, 3), __func__, iir_idx, band_idx, - get_iir_band_coeff(codec, iir_idx, band_idx, 4)); + get_iir_band_coeff(component, iir_idx, band_idx, 4)); return 0; } @@ -5605,10 +5854,11 @@ static int tavil_compander_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); int comp = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = tavil->comp_enabled[comp]; return 0; @@ -5617,13 +5867,14 @@ static int tavil_compander_get(struct snd_kcontrol *kcontrol, static int tavil_compander_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int comp = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; int value = ucontrol->value.integer.value[0]; - dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n", + dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n", __func__, comp + 1, tavil->comp_enabled[comp], value); tavil->comp_enabled[comp] = value; @@ -5631,11 +5882,11 @@ static int tavil_compander_put(struct snd_kcontrol *kcontrol, switch (comp) { case COMPANDER_1: /* Set Gain Source Select based on compander enable/disable */ - snd_soc_update_bits(codec, WCD934X_HPH_L_EN, 0x20, + snd_soc_component_update_bits(component, WCD934X_HPH_L_EN, 0x20, (value ? 0x00:0x20)); break; case COMPANDER_2: - snd_soc_update_bits(codec, WCD934X_HPH_R_EN, 0x20, + snd_soc_component_update_bits(component, WCD934X_HPH_R_EN, 0x20, (value ? 0x00:0x20)); break; case COMPANDER_3: @@ -5649,7 +5900,7 @@ static int tavil_compander_put(struct snd_kcontrol *kcontrol, * it does not cause any audio failure, so do not * return error in this case, but just print a log */ - dev_warn(codec->dev, "%s: unknown compander: %d\n", + dev_warn(component->dev, "%s: unknown compander: %d\n", __func__, comp); }; return 0; @@ -5658,8 +5909,9 @@ static int tavil_compander_put(struct snd_kcontrol *kcontrol, static int tavil_hph_asrc_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int index = -EINVAL; if (!strcmp(kcontrol->id.name, "ASRC0 Output Mode")) @@ -5677,8 +5929,9 @@ static int tavil_hph_asrc_mode_put(struct snd_kcontrol *kcontrol, static int tavil_hph_asrc_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int val = 0; int index = -EINVAL; @@ -5698,8 +5951,9 @@ static int tavil_hph_asrc_mode_get(struct snd_kcontrol *kcontrol, static int tavil_hph_idle_detect_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int val = 0; if (tavil) @@ -5713,8 +5967,9 @@ static int tavil_hph_idle_detect_get(struct snd_kcontrol *kcontrol, static int tavil_hph_idle_detect_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); if (tavil) tavil->idle_det_cfg.hph_idle_detect_en = @@ -5726,7 +5981,8 @@ static int tavil_hph_idle_detect_put(struct snd_kcontrol *kcontrol, static int tavil_dmic_pin_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); u16 dmic_pin; u8 reg_val, pinctl_position; @@ -5734,7 +5990,7 @@ static int tavil_dmic_pin_mode_get(struct snd_kcontrol *kcontrol, kcontrol->private_value)->shift; dmic_pin = pinctl_position & 0x07; - reg_val = snd_soc_read(codec, + reg_val = snd_soc_component_read32(component, WCD934X_TLMM_DMIC1_CLK_PINCFG + dmic_pin - 1); ucontrol->value.integer.value[0] = !!reg_val; @@ -5745,8 +6001,9 @@ static int tavil_dmic_pin_mode_get(struct snd_kcontrol *kcontrol, static int tavil_dmic_pin_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); u16 ctl_reg, cfg_reg, dmic_pin; u8 ctl_val, cfg_val, pinctl_position, pinctl_mode, mask; @@ -5769,14 +6026,14 @@ static int tavil_dmic_pin_mode_put(struct snd_kcontrol *kcontrol, ctl_reg = WCD934X_TEST_DEBUG_PIN_CTL_OE_3; break; default: - dev_err(codec->dev, "%s: Invalid pinctl position = %d\n", + dev_err(component->dev, "%s: Invalid pinctl position = %d\n", __func__, pinctl_position); return -EINVAL; } ctl_val = ~(pinctl_mode << (pinctl_position & 0x07)); mask = 1 << (pinctl_position & 0x07); - snd_soc_update_bits(codec, ctl_reg, mask, ctl_val); + snd_soc_component_update_bits(component, ctl_reg, mask, ctl_val); dmic_pin = pinctl_position & 0x07; cfg_reg = WCD934X_TLMM_DMIC1_CLK_PINCFG + dmic_pin - 1; @@ -5787,9 +6044,9 @@ static int tavil_dmic_pin_mode_put(struct snd_kcontrol *kcontrol, cfg_val = 0xD; } else cfg_val = 0; - snd_soc_update_bits(codec, cfg_reg, 0x1F, cfg_val); + snd_soc_component_update_bits(component, cfg_reg, 0x1F, cfg_val); - dev_dbg(codec->dev, "%s: reg=0x%x mask=0x%x val=%d reg=0x%x val=%d\n", + dev_dbg(component->dev, "%s: reg=0x%x mask=0x%x val=%d reg=0x%x val=%d\n", __func__, ctl_reg, mask, ctl_val, cfg_reg, cfg_val); return 0; @@ -5798,7 +6055,8 @@ static int tavil_dmic_pin_mode_put(struct snd_kcontrol *kcontrol, static int tavil_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); u16 amic_reg = 0; if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE")) @@ -5808,7 +6066,7 @@ static int tavil_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, if (amic_reg) ucontrol->value.integer.value[0] = - (snd_soc_read(codec, amic_reg) & + (snd_soc_component_read32(component, amic_reg) & WCD934X_AMIC_PWR_LVL_MASK) >> WCD934X_AMIC_PWR_LVL_SHIFT; return 0; @@ -5817,13 +6075,14 @@ static int tavil_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, static int tavil_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); u32 mode_val; u16 amic_reg = 0; mode_val = ucontrol->value.enumerated.item[0]; - dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val); + dev_dbg(component->dev, "%s: mode: %d\n", __func__, mode_val); if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE")) amic_reg = WCD934X_ANA_AMIC1; @@ -5831,8 +6090,9 @@ static int tavil_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, amic_reg = WCD934X_ANA_AMIC3; if (amic_reg) - snd_soc_update_bits(codec, amic_reg, WCD934X_AMIC_PWR_LVL_MASK, - mode_val << WCD934X_AMIC_PWR_LVL_SHIFT); + snd_soc_component_update_bits(component, amic_reg, + WCD934X_AMIC_PWR_LVL_MASK, + mode_val << WCD934X_AMIC_PWR_LVL_SHIFT); return 0; } @@ -5849,13 +6109,15 @@ static const struct soc_enum tavil_conn_mad_enum = static int tavil_mad_input_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); u8 tavil_mad_input; - tavil_mad_input = snd_soc_read(codec, WCD934X_SOC_MAD_INP_SEL) & 0x0F; + tavil_mad_input = snd_soc_component_read32( + component, WCD934X_SOC_MAD_INP_SEL) & 0x0F; ucontrol->value.integer.value[0] = tavil_mad_input; - dev_dbg(codec->dev, "%s: tavil_mad_input = %s\n", __func__, + dev_dbg(component->dev, "%s: tavil_mad_input = %s\n", __func__, tavil_conn_mad_text[tavil_mad_input]); return 0; @@ -5864,8 +6126,9 @@ static int tavil_mad_input_get(struct snd_kcontrol *kcontrol, static int tavil_mad_input_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct snd_soc_card *card = codec->component.card; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct snd_soc_card *card = component->card; u8 tavil_mad_input; char mad_amic_input_widget[6]; const char *mad_input_widget; @@ -5879,7 +6142,7 @@ static int tavil_mad_input_put(struct snd_kcontrol *kcontrol, if (tavil_mad_input >= sizeof(tavil_conn_mad_text)/ sizeof(tavil_conn_mad_text[0])) { - dev_err(codec->dev, + dev_err(component->dev, "%s: tavil_mad_input = %d out of bounds\n", __func__, tavil_mad_input); return -EINVAL; @@ -5887,11 +6150,11 @@ static int tavil_mad_input_put(struct snd_kcontrol *kcontrol, if (strnstr(tavil_conn_mad_text[tavil_mad_input], "NOTUSED", sizeof("NOTUSED"))) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: Unsupported tavil_mad_input = %s\n", __func__, tavil_conn_mad_text[tavil_mad_input]); /* Make sure the MAD register is updated */ - snd_soc_update_bits(codec, WCD934X_ANA_MAD_SETUP, + snd_soc_component_update_bits(component, WCD934X_ANA_MAD_SETUP, 0x88, 0x00); return -EINVAL; } @@ -5901,21 +6164,23 @@ static int tavil_mad_input_put(struct snd_kcontrol *kcontrol, mad_input = strpbrk(tavil_conn_mad_text[tavil_mad_input], "1234"); if (!mad_input) { - dev_err(codec->dev, "%s: Invalid MAD input %s\n", + dev_err(component->dev, "%s: Invalid MAD input %s\n", __func__, tavil_conn_mad_text[tavil_mad_input]); return -EINVAL; } ret = kstrtouint(mad_input, 10, &adc); if ((ret < 0) || (adc > 4)) { - dev_err(codec->dev, "%s: Invalid ADC = %s\n", __func__, + dev_err(component->dev, "%s: Invalid ADC = %s\n", + __func__, tavil_conn_mad_text[tavil_mad_input]); return -EINVAL; } /*AMIC4 and AMIC5 share ADC4*/ if ((adc == 4) && - (snd_soc_read(codec, WCD934X_TX_NEW_AMIC_4_5_SEL) & 0x10)) + (snd_soc_component_read32( + component, WCD934X_TX_NEW_AMIC_4_5_SEL) & 0x10)) adc = 5; snprintf(mad_amic_input_widget, 6, "%s%u", "AMIC", adc); @@ -5927,7 +6192,7 @@ static int tavil_mad_input_put(struct snd_kcontrol *kcontrol, mad_input_widget = tavil_conn_mad_text[tavil_mad_input]; } - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: tavil input widget = %s, adc_input = %s\n", __func__, mad_input_widget, is_adc_input ? "true" : "false"); @@ -5935,7 +6200,7 @@ static int tavil_mad_input_put(struct snd_kcontrol *kcontrol, if (!strcmp(card->of_dapm_routes[i].sink, mad_input_widget)) { source_widget = card->of_dapm_routes[i].source; if (!source_widget) { - dev_err(codec->dev, + dev_err(component->dev, "%s: invalid source widget\n", __func__); return -EINVAL; @@ -5962,24 +6227,24 @@ static int tavil_mad_input_put(struct snd_kcontrol *kcontrol, } if (!mic_bias_found) { - dev_err(codec->dev, "%s: mic bias not found for input %s\n", + dev_err(component->dev, "%s: mic bias not found for input %s\n", __func__, mad_input_widget); return -EINVAL; } - dev_dbg(codec->dev, "%s: mic_bias found = %d\n", __func__, + dev_dbg(component->dev, "%s: mic_bias found = %d\n", __func__, mic_bias_found); - snd_soc_update_bits(codec, WCD934X_SOC_MAD_INP_SEL, + snd_soc_component_update_bits(component, WCD934X_SOC_MAD_INP_SEL, 0x0F, tavil_mad_input); - snd_soc_update_bits(codec, WCD934X_ANA_MAD_SETUP, + snd_soc_component_update_bits(component, WCD934X_ANA_MAD_SETUP, 0x07, mic_bias_found); /* for all adc inputs, mad should be in micbias mode with BG enabled */ if (is_adc_input) - snd_soc_update_bits(codec, WCD934X_ANA_MAD_SETUP, + snd_soc_component_update_bits(component, WCD934X_ANA_MAD_SETUP, 0x88, 0x88); else - snd_soc_update_bits(codec, WCD934X_ANA_MAD_SETUP, + snd_soc_component_update_bits(component, WCD934X_ANA_MAD_SETUP, 0x88, 0x00); return 0; } @@ -5988,15 +6253,16 @@ static int tavil_ear_pa_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 ear_pa_gain; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - ear_pa_gain = snd_soc_read(codec, WCD934X_ANA_EAR); + ear_pa_gain = snd_soc_component_read32(component, WCD934X_ANA_EAR); ear_pa_gain = (ear_pa_gain & 0x70) >> 4; ucontrol->value.integer.value[0] = ear_pa_gain; - dev_dbg(codec->dev, "%s: ear_pa_gain = 0x%x\n", __func__, + dev_dbg(component->dev, "%s: ear_pa_gain = 0x%x\n", __func__, ear_pa_gain); return 0; @@ -6006,26 +6272,29 @@ static int tavil_ear_pa_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 ear_pa_gain; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); ear_pa_gain = ucontrol->value.integer.value[0] << 4; - snd_soc_update_bits(codec, WCD934X_ANA_EAR, 0x70, ear_pa_gain); + snd_soc_component_update_bits(component, WCD934X_ANA_EAR, + 0x70, ear_pa_gain); return 0; } static int tavil_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = tavil->ear_spkr_gain; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); return 0; @@ -6034,12 +6303,14 @@ static int tavil_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, static int tavil_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); tavil->ear_spkr_gain = ucontrol->value.integer.value[0]; - dev_dbg(codec->dev, "%s: gain = %d\n", __func__, tavil->ear_spkr_gain); + dev_dbg(component->dev, "%s: gain = %d\n", __func__, + tavil->ear_spkr_gain); return 0; } @@ -6048,12 +6319,14 @@ static int tavil_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 bst_state_max = 0; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - bst_state_max = snd_soc_read(codec, WCD934X_CDC_BOOST0_BOOST_CTL); + bst_state_max = snd_soc_component_read32( + component, WCD934X_CDC_BOOST0_BOOST_CTL); bst_state_max = (bst_state_max & 0x0c) >> 2; ucontrol->value.integer.value[0] = bst_state_max; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); return 0; @@ -6063,12 +6336,13 @@ static int tavil_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 bst_state_max; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); bst_state_max = ucontrol->value.integer.value[0] << 2; - snd_soc_update_bits(codec, WCD934X_CDC_BOOST0_BOOST_CTL, + snd_soc_component_update_bits(component, WCD934X_CDC_BOOST0_BOOST_CTL, 0x0c, bst_state_max); return 0; @@ -6078,12 +6352,14 @@ static int tavil_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 bst_state_max = 0; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - bst_state_max = snd_soc_read(codec, WCD934X_CDC_BOOST1_BOOST_CTL); + bst_state_max = snd_soc_component_read32(component, + WCD934X_CDC_BOOST1_BOOST_CTL); bst_state_max = (bst_state_max & 0x0c) >> 2; ucontrol->value.integer.value[0] = bst_state_max; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); return 0; @@ -6093,12 +6369,13 @@ static int tavil_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 bst_state_max; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); bst_state_max = ucontrol->value.integer.value[0] << 2; - snd_soc_update_bits(codec, WCD934X_CDC_BOOST1_BOOST_CTL, + snd_soc_component_update_bits(component, WCD934X_CDC_BOOST1_BOOST_CTL, 0x0c, bst_state_max); return 0; @@ -6107,8 +6384,9 @@ static int tavil_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol, static int tavil_rx_hph_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = tavil->hph_mode; return 0; @@ -6117,16 +6395,17 @@ static int tavil_rx_hph_mode_get(struct snd_kcontrol *kcontrol, static int tavil_rx_hph_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); u32 mode_val; mode_val = ucontrol->value.enumerated.item[0]; - dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val); + dev_dbg(component->dev, "%s: mode: %d\n", __func__, mode_val); if (mode_val == 0) { - dev_warn(codec->dev, "%s:Invalid HPH Mode, default to Cls-H LOHiFi\n", + dev_warn(component->dev, "%s:Invalid HPH Mode, default to Cls-H LOHiFi\n", __func__); mode_val = CLS_H_LOHIFI; } @@ -6477,8 +6756,9 @@ static int tavil_dec_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val; u16 mic_sel_reg = 0; @@ -6488,7 +6768,7 @@ static int tavil_dec_enum_put(struct snd_kcontrol *kcontrol, if (val > e->items - 1) return -EINVAL; - dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__, widget->name, val); switch (e->reg) { @@ -6519,7 +6799,7 @@ static int tavil_dec_enum_put(struct snd_kcontrol *kcontrol, mic_sel_reg = WCD934X_CDC_TX7_TX_PATH_CFG0; break; default: - dev_err(codec->dev, "%s: e->reg: 0x%x not expected\n", + dev_err(component->dev, "%s: e->reg: 0x%x not expected\n", __func__, e->reg); return -EINVAL; } @@ -6527,7 +6807,8 @@ static int tavil_dec_enum_put(struct snd_kcontrol *kcontrol, /* ADC: 0, DMIC: 1 */ mic_sel = val ? 0x0 : 0x1; if (mic_sel_reg) - snd_soc_update_bits(codec, mic_sel_reg, 1 << 7, mic_sel << 7); + snd_soc_component_update_bits(component, mic_sel_reg, 1 << 7, + mic_sel << 7); return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); } @@ -6537,7 +6818,8 @@ static int tavil_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val; unsigned short look_ahead_dly_reg = WCD934X_CDC_RX0_RX_PATH_CFG0; @@ -6546,7 +6828,7 @@ static int tavil_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, if (val >= e->items) return -EINVAL; - dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__, + dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__, widget->name, val); if (e->reg == WCD934X_CDC_RX0_RX_PATH_SEC0) @@ -6557,7 +6839,7 @@ static int tavil_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, look_ahead_dly_reg = WCD934X_CDC_RX2_RX_PATH_CFG0; /* Set Look Ahead Delay */ - snd_soc_update_bits(codec, look_ahead_dly_reg, + snd_soc_component_update_bits(component, look_ahead_dly_reg, 0x08, (val ? 0x08 : 0x00)); /* Set DEM INP Select */ return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); @@ -7454,8 +7736,9 @@ static int tavil_dsd_mixer_get(struct snd_kcontrol *kcontrol, { struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct tavil_dsd_config *dsd_conf = tavil_p->dsd_config; @@ -7475,8 +7758,8 @@ static int tavil_dsd_mixer_put(struct snd_kcontrol *kcontrol, (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); - struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); + struct tavil_priv *tavil_p = snd_soc_component_get_drvdata(component); unsigned int wval = ucontrol->value.integer.value[0]; struct tavil_dsd_config *dsd_conf = tavil_p->dsd_config; @@ -8168,7 +8451,8 @@ static int tavil_get_channel_map(struct snd_soc_dai *dai, unsigned int *tx_num, unsigned int *tx_slot, unsigned int *rx_num, unsigned int *rx_slot) { - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(dai->codec); + struct tavil_priv *tavil = + snd_soc_component_get_drvdata(dai->component); u32 i = 0; struct wcd9xxx_ch *ch; int ret = 0; @@ -8243,8 +8527,8 @@ static int tavil_set_channel_map(struct snd_soc_dai *dai, struct wcd9xxx *core; struct wcd9xxx_codec_dai_data *dai_data = NULL; - tavil = snd_soc_codec_get_drvdata(dai->codec); - core = dev_get_drvdata(dai->codec->dev->parent); + tavil = snd_soc_component_get_drvdata(dai->component); + core = dev_get_drvdata(dai->component->dev->parent); if (!tx_slot || !rx_slot) { dev_err(tavil->dev, "%s: Invalid tx_slot 0x%pK, rx_slot 0x%pK\n", @@ -8284,9 +8568,10 @@ static void tavil_shutdown(struct snd_pcm_substream *substream, static int tavil_set_decimator_rate(struct snd_soc_dai *dai, u32 sample_rate) { - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; struct wcd9xxx_ch *ch; - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = + snd_soc_component_get_drvdata(component); u32 tx_port = 0, tx_fs_rate = 0; u8 shift = 0, shift_val = 0, tx_mux_sel = 0; int decimator = -1; @@ -8320,11 +8605,11 @@ static int tavil_set_decimator_rate(struct snd_soc_dai *dai, list_for_each_entry(ch, &tavil->dai[dai->id].wcd9xxx_ch_list, list) { tx_port = ch->port; - dev_dbg(codec->dev, "%s: dai->id = %d, tx_port = %d", + dev_dbg(component->dev, "%s: dai->id = %d, tx_port = %d", __func__, dai->id, tx_port); if ((tx_port < 0) || (tx_port == 12) || (tx_port >= 14)) { - dev_err(codec->dev, "%s: Invalid SLIM TX%u port. DAI ID: %d\n", + dev_err(component->dev, "%s: Invalid SLIM TX%u port. DAI ID: %d\n", __func__, tx_port, dai->id); return -EINVAL; } @@ -8350,7 +8635,7 @@ static int tavil_set_decimator_rate(struct snd_soc_dai *dai, shift = 4; shift_val = 0x03; } - tx_mux_sel = snd_soc_read(codec, tx_port_reg) & + tx_mux_sel = snd_soc_component_read32(component, tx_port_reg) & (shift_val << shift); tx_mux_sel = tx_mux_sel >> shift; @@ -8371,15 +8656,16 @@ static int tavil_set_decimator_rate(struct snd_soc_dai *dai, if (decimator >= 0) { tx_fs_reg = WCD934X_CDC_TX0_TX_PATH_CTL + 16 * decimator; - dev_dbg(codec->dev, "%s: set DEC%u (-> SLIM_TX%u) rate to %u\n", + dev_dbg(component->dev, "%s: set DEC%u (-> SLIM_TX%u) rate to %u\n", __func__, decimator, tx_port, sample_rate); - snd_soc_update_bits(codec, tx_fs_reg, 0x0F, tx_fs_rate); + snd_soc_component_update_bits(component, tx_fs_reg, + 0x0F, tx_fs_rate); } else if ((tx_port <= 8) && (tx_mux_sel == 0x01)) { /* Check if the TX Mux input is RX MIX TXn */ - dev_dbg(codec->dev, "%s: RX_MIX_TX%u going to CDC_IF TX%u\n", + dev_dbg(component->dev, "%s: RX_MIX_TX%u going to CDC_IF TX%u\n", __func__, tx_port, tx_port); } else { - dev_err(codec->dev, "%s: ERROR: Invalid decimator: %d\n", + dev_err(component->dev, "%s: ERROR: Invalid decimator: %d\n", __func__, decimator); return -EINVAL; } @@ -8395,16 +8681,16 @@ static int tavil_set_mix_interpolator_rate(struct snd_soc_dai *dai, u32 j; u16 int_mux_cfg1, int_fs_reg; u8 int_mux_cfg1_val; - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; struct wcd9xxx_ch *ch; - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); list_for_each_entry(ch, &tavil->dai[dai->id].wcd9xxx_ch_list, list) { int_2_inp = INTn_2_INP_SEL_RX0 + ch->port - WCD934X_RX_PORT_START_NUMBER; if ((int_2_inp < INTn_2_INP_SEL_RX0) || (int_2_inp > INTn_2_INP_SEL_RX7)) { - dev_err(codec->dev, "%s: Invalid RX%u port, Dai ID is %d\n", + dev_err(component->dev, "%s: Invalid RX%u port, Dai ID is %d\n", __func__, (ch->port - WCD934X_RX_PORT_START_NUMBER), dai->id); @@ -8418,8 +8704,8 @@ static int tavil_set_mix_interpolator_rate(struct snd_soc_dai *dai, int_mux_cfg1 += 2; continue; } - int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1) & - 0x0F; + int_mux_cfg1_val = snd_soc_component_read32(component, + int_mux_cfg1) & 0x0F; if (int_mux_cfg1_val == int_2_inp) { /* * Ear mix path supports only 48, 96, 192, @@ -8428,7 +8714,7 @@ static int tavil_set_mix_interpolator_rate(struct snd_soc_dai *dai, if ((j == INTERP_EAR) && (rate_reg_val < 0x4 || rate_reg_val > 0x7)) { - dev_err_ratelimited(codec->dev, + dev_err_ratelimited(component->dev, "%s: Invalid rate for AIF_PB DAI(%d)\n", __func__, dai->id); return -EINVAL; @@ -8436,12 +8722,12 @@ static int tavil_set_mix_interpolator_rate(struct snd_soc_dai *dai, int_fs_reg = WCD934X_CDC_RX0_RX_PATH_MIX_CTL + 20 * j; - dev_dbg(codec->dev, "%s: AIF_PB DAI(%d) connected to INT%u_2\n", + dev_dbg(component->dev, "%s: AIF_PB DAI(%d) connected to INT%u_2\n", __func__, dai->id, j); - dev_dbg(codec->dev, "%s: set INT%u_2 sample rate to %u\n", + dev_dbg(component->dev, "%s: set INT%u_2 sample rate to %u\n", __func__, j, sample_rate); - snd_soc_update_bits(codec, int_fs_reg, 0x0F, - rate_reg_val); + snd_soc_component_update_bits(component, + int_fs_reg, 0x0F, rate_reg_val); } int_mux_cfg1 += 2; } @@ -8459,9 +8745,9 @@ static int tavil_set_prim_interpolator_rate(struct snd_soc_dai *dai, u16 int_fs_reg; u8 int_mux_cfg0_val, int_mux_cfg1_val; u8 inp0_sel, inp1_sel, inp2_sel; - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; struct wcd9xxx_ch *ch; - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); struct tavil_dsd_config *dsd_conf = tavil->dsd_config; list_for_each_entry(ch, &tavil->dai[dai->id].wcd9xxx_ch_list, list) { @@ -8469,7 +8755,7 @@ static int tavil_set_prim_interpolator_rate(struct snd_soc_dai *dai, WCD934X_RX_PORT_START_NUMBER; if ((int_1_mix1_inp < INTn_1_INP_SEL_RX0) || (int_1_mix1_inp > INTn_1_INP_SEL_RX7)) { - dev_err(codec->dev, "%s: Invalid RX%u port, Dai ID is %d\n", + dev_err(component->dev, "%s: Invalid RX%u port, Dai ID is %d\n", __func__, (ch->port - WCD934X_RX_PORT_START_NUMBER), dai->id); @@ -8491,8 +8777,10 @@ static int tavil_set_prim_interpolator_rate(struct snd_soc_dai *dai, } int_mux_cfg1 = int_mux_cfg0 + 1; - int_mux_cfg0_val = snd_soc_read(codec, int_mux_cfg0); - int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1); + int_mux_cfg0_val = snd_soc_component_read32( + component, int_mux_cfg0); + int_mux_cfg1_val = snd_soc_component_read32( + component, int_mux_cfg1); inp0_sel = int_mux_cfg0_val & 0x0F; inp1_sel = (int_mux_cfg0_val >> 4) & 0x0F; inp2_sel = (int_mux_cfg1_val >> 4) & 0x0F; @@ -8506,7 +8794,7 @@ static int tavil_set_prim_interpolator_rate(struct snd_soc_dai *dai, if ((j == INTERP_EAR || j == INTERP_SPKR1 || j == INTERP_SPKR2) && (rate_reg_val > 0x7)) { - dev_err_ratelimited(codec->dev, + dev_err_ratelimited(component->dev, "%s: Invalid rate for AIF_PB DAI(%d)\n", __func__, dai->id); return -EINVAL; @@ -8514,14 +8802,14 @@ static int tavil_set_prim_interpolator_rate(struct snd_soc_dai *dai, int_fs_reg = WCD934X_CDC_RX0_RX_PATH_CTL + 20 * j; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: AIF_PB DAI(%d) connected to INT%u_1\n", __func__, dai->id, j); - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: set INT%u_1 sample rate to %u\n", __func__, j, sample_rate); - snd_soc_update_bits(codec, int_fs_reg, 0x0F, - rate_reg_val); + snd_soc_component_update_bits(component, + int_fs_reg, 0x0F, rate_reg_val); } int_mux_cfg0 += 2; } @@ -8537,7 +8825,7 @@ static int tavil_set_prim_interpolator_rate(struct snd_soc_dai *dai, static int tavil_set_interpolator_rate(struct snd_soc_dai *dai, u32 sample_rate) { - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; int rate_val = 0; int i, ret; @@ -8548,7 +8836,7 @@ static int tavil_set_interpolator_rate(struct snd_soc_dai *dai, } } if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) { - dev_err(codec->dev, "%s: Unsupported sample rate: %d\n", + dev_err(component->dev, "%s: Unsupported sample rate: %d\n", __func__, sample_rate); return -EINVAL; } @@ -8575,7 +8863,8 @@ static int tavil_vi_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(dai->codec); + struct tavil_priv *tavil = + snd_soc_component_get_drvdata(dai->component); dev_dbg(tavil->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__, dai->name, dai->id, params_rate(params), @@ -8591,7 +8880,8 @@ static int tavil_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(dai->codec); + struct tavil_priv *tavil = + snd_soc_component_get_drvdata(dai->component); int ret = 0; dev_dbg(tavil->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", @@ -8671,18 +8961,20 @@ static int tavil_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) i2s_reg = WCD934X_DATA_HUB_I2S_2_CTL; break; default: - dev_err(dai->codec->dev, "%s Invalid i2s Id", __func__); + dev_err(dai->component->dev, "%s Invalid i2s Id", __func__); return -EINVAL; } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: /* CPU is master */ - snd_soc_update_bits(dai->codec, i2s_reg, 0x2, 0x0); + snd_soc_component_update_bits(dai->component, i2s_reg, + 0x2, 0x0); break; case SND_SOC_DAIFMT_CBM_CFM: /* CPU is slave */ - snd_soc_update_bits(dai->codec, i2s_reg, 0x2, 0x2); + snd_soc_component_update_bits(dai->component, i2s_reg, + 0x2, 0x2); break; default: return -EINVAL; @@ -9168,7 +9460,7 @@ static struct snd_info_entry_ops tavil_codec_info_ops = { /* * tavil_codec_info_create_codec_entry - creates wcd934x module * @codec_root: The parent directory - * @codec: Codec instance + * @component: Codec component instance * * Creates wcd934x module and version entry under the given * parent directory. @@ -9176,21 +9468,21 @@ static struct snd_info_entry_ops tavil_codec_info_ops = { * Return: 0 on success or negative error code on failure. */ int tavil_codec_info_create_codec_entry(struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { struct snd_info_entry *version_entry; struct tavil_priv *tavil; struct snd_soc_card *card; - if (!codec_root || !codec) + if (!codec_root || !component) return -EINVAL; - tavil = snd_soc_codec_get_drvdata(codec); - card = codec->component.card; + tavil = snd_soc_component_get_drvdata(component); + card = component->card; tavil->entry = snd_info_create_subdir(codec_root->module, "tavil", codec_root); if (!tavil->entry) { - dev_dbg(codec->dev, "%s: failed to create wcd934x entry\n", + dev_dbg(component->dev, "%s: failed to create wcd934x entry\n", __func__); return -ENOMEM; } @@ -9199,7 +9491,7 @@ int tavil_codec_info_create_codec_entry(struct snd_info_entry *codec_root, "version", tavil->entry); if (!version_entry) { - dev_dbg(codec->dev, "%s: failed to create wcd934x version entry\n", + dev_dbg(component->dev, "%s: failed to create wcd934x version entry\n", __func__); return -ENOMEM; } @@ -9222,23 +9514,23 @@ EXPORT_SYMBOL(tavil_codec_info_create_codec_entry); /** * tavil_cdc_mclk_enable - Enable/disable codec mclk * - * @codec: codec instance + * @component: codec component instance * @enable: Indicates clk enable or disable * * Returns 0 on Success and error on failure */ -int tavil_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable) +int tavil_cdc_mclk_enable(struct snd_soc_component *component, bool enable) { - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); return __tavil_cdc_mclk_enable(tavil, enable); } EXPORT_SYMBOL(tavil_cdc_mclk_enable); -static int __tavil_codec_internal_rco_ctrl(struct snd_soc_codec *codec, +static int __tavil_codec_internal_rco_ctrl(struct snd_soc_component *component, bool enable) { - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int ret = 0; if (enable) { @@ -9249,7 +9541,7 @@ static int __tavil_codec_internal_rco_ctrl(struct snd_soc_codec *codec, } else { ret = tavil_cdc_req_mclk_enable(tavil, true); if (ret) { - dev_err(codec->dev, + dev_err(component->dev, "%s: mclk_enable failed, err = %d\n", __func__, ret); goto done; @@ -9267,7 +9559,7 @@ static int __tavil_codec_internal_rco_ctrl(struct snd_soc_codec *codec, } if (ret) { - dev_err(codec->dev, "%s: Error in %s RCO\n", + dev_err(component->dev, "%s: Error in %s RCO\n", __func__, (enable ? "enabling" : "disabling")); ret = -EINVAL; } @@ -9278,41 +9570,41 @@ static int __tavil_codec_internal_rco_ctrl(struct snd_soc_codec *codec, /* * tavil_codec_internal_rco_ctrl: Enable/Disable codec's RCO clock - * @codec: Handle to the codec + * @component: Handle to the codec * @enable: Indicates whether clock should be enabled or disabled */ -static int tavil_codec_internal_rco_ctrl(struct snd_soc_codec *codec, +static int tavil_codec_internal_rco_ctrl(struct snd_soc_component *component, bool enable) { - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); int ret = 0; WCD9XXX_V2_BG_CLK_LOCK(tavil->resmgr); - ret = __tavil_codec_internal_rco_ctrl(codec, enable); + ret = __tavil_codec_internal_rco_ctrl(component, enable); WCD9XXX_V2_BG_CLK_UNLOCK(tavil->resmgr); return ret; } /* * tavil_cdc_mclk_tx_enable: Enable/Disable codec's clock for TX path - * @codec: Handle to codec + * @component: Handle to codec * @enable: Indicates whether clock should be enabled or disabled */ -int tavil_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable) +int tavil_cdc_mclk_tx_enable(struct snd_soc_component *component, bool enable) { struct tavil_priv *tavil_p; int ret = 0; bool clk_mode; bool clk_internal; - if (!codec) + if (!component) return -EINVAL; - tavil_p = snd_soc_codec_get_drvdata(codec); + tavil_p = snd_soc_component_get_drvdata(component); clk_mode = test_bit(CLK_MODE, &tavil_p->status_mask); clk_internal = test_bit(CLK_INTERNAL, &tavil_p->status_mask); - dev_dbg(codec->dev, "%s: clkmode: %d, enable: %d, clk_internal: %d\n", + dev_dbg(component->dev, "%s: clkmode: %d, enable: %d, clk_internal: %d\n", __func__, clk_mode, enable, clk_internal); if (clk_mode || clk_internal) { @@ -9320,11 +9612,11 @@ int tavil_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable) wcd_resmgr_enable_master_bias(tavil_p->resmgr); tavil_dig_core_power_collapse(tavil_p, POWER_RESUME); tavil_vote_svs(tavil_p, true); - ret = tavil_codec_internal_rco_ctrl(codec, enable); + ret = tavil_codec_internal_rco_ctrl(component, enable); set_bit(CLK_INTERNAL, &tavil_p->status_mask); } else { clear_bit(CLK_INTERNAL, &tavil_p->status_mask); - tavil_codec_internal_rco_ctrl(codec, enable); + tavil_codec_internal_rco_ctrl(component, enable); tavil_vote_svs(tavil_p, false); tavil_dig_core_power_collapse(tavil_p, POWER_COLLAPSE); wcd_resmgr_disable_master_bias(tavil_p->resmgr); @@ -9470,18 +9762,18 @@ static const struct tavil_reg_mask_val tavil_codec_reg_init_common_val[] = { static void tavil_codec_init_reg(struct tavil_priv *priv) { - struct snd_soc_codec *codec = priv->codec; + struct snd_soc_component *component = priv->component; u32 i; for (i = 0; i < ARRAY_SIZE(tavil_codec_reg_init_common_val); i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, tavil_codec_reg_init_common_val[i].reg, tavil_codec_reg_init_common_val[i].mask, tavil_codec_reg_init_common_val[i].val); if (TAVIL_IS_1_1(priv->wcd9xxx)) { for (i = 0; i < ARRAY_SIZE(tavil_codec_reg_init_1_1_val); i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, tavil_codec_reg_init_1_1_val[i].reg, tavil_codec_reg_init_1_1_val[i].mask, tavil_codec_reg_init_1_1_val[i].val); @@ -9553,10 +9845,10 @@ static void tavil_update_cpr_defaults(struct tavil_priv *tavil) __tavil_cdc_mclk_enable(tavil, false); } -static void tavil_slim_interface_init_reg(struct snd_soc_codec *codec) +static void tavil_slim_interface_init_reg(struct snd_soc_component *component) { int i; - struct tavil_priv *priv = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *priv = snd_soc_component_get_drvdata(component); for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++) wcd9xxx_interface_reg_write(priv->wcd9xxx, @@ -9690,7 +9982,7 @@ static irqreturn_t tavil_slimbus_irq(int irq, void *data) static int tavil_setup_irqs(struct tavil_priv *tavil) { int ret = 0; - struct snd_soc_codec *codec = tavil->codec; + struct snd_soc_component *component = tavil->component; struct wcd9xxx *wcd9xxx = tavil->wcd9xxx; struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; @@ -9698,24 +9990,24 @@ static int tavil_setup_irqs(struct tavil_priv *tavil) ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_SLIMBUS, tavil_slimbus_irq, "SLIMBUS Slave", tavil); if (ret) - dev_err(codec->dev, "%s: Failed to request irq %d\n", __func__, - WCD9XXX_IRQ_SLIMBUS); + dev_err(component->dev, "%s: Failed to request irq %d\n", + __func__, WCD9XXX_IRQ_SLIMBUS); else - tavil_slim_interface_init_reg(codec); + tavil_slim_interface_init_reg(component); /* Register for misc interrupts as well */ ret = wcd9xxx_request_irq(core_res, WCD934X_IRQ_MISC, tavil_misc_irq, "CDC MISC Irq", tavil); if (ret) - dev_err(codec->dev, "%s: Failed to request cdc misc irq\n", + dev_err(component->dev, "%s: Failed to request cdc misc irq\n", __func__); return ret; } -static void tavil_init_slim_slave_cfg(struct snd_soc_codec *codec) +static void tavil_init_slim_slave_cfg(struct snd_soc_component *component) { - struct tavil_priv *priv = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *priv = snd_soc_component_get_drvdata(component); struct afe_param_cdc_slimbus_slave_cfg *cfg; struct wcd9xxx *wcd9xxx = priv->wcd9xxx; uint64_t eaddr = 0; @@ -9730,7 +10022,7 @@ static void tavil_init_slim_slave_cfg(struct snd_soc_codec *codec) cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF; cfg->device_enum_addr_msw = eaddr >> 32; - dev_dbg(codec->dev, "%s: slimbus logical address 0x%llx\n", + dev_dbg(component->dev, "%s: slimbus logical address 0x%llx\n", __func__, eaddr); } @@ -9765,7 +10057,7 @@ EXPORT_SYMBOL(wcd934x_get_micb_vout_ctl_val); static int tavil_handle_pdata(struct tavil_priv *tavil, struct wcd9xxx_pdata *pdata) { - struct snd_soc_codec *codec = tavil->codec; + struct snd_soc_component *component = tavil->component; u8 mad_dmic_ctl_val; u8 anc_ctl_value; u32 def_dmic_rate, dmic_clk_drv; @@ -9773,7 +10065,7 @@ static int tavil_handle_pdata(struct tavil_priv *tavil, int rc = 0; if (!pdata) { - dev_err(codec->dev, "%s: NULL pdata\n", __func__); + dev_err(component->dev, "%s: NULL pdata\n", __func__); return -ENODEV; } @@ -9787,10 +10079,14 @@ static int tavil_handle_pdata(struct tavil_priv *tavil, rc = -EINVAL; goto done; } - snd_soc_update_bits(codec, WCD934X_ANA_MICB1, 0x3F, vout_ctl_1); - snd_soc_update_bits(codec, WCD934X_ANA_MICB2, 0x3F, vout_ctl_2); - snd_soc_update_bits(codec, WCD934X_ANA_MICB3, 0x3F, vout_ctl_3); - snd_soc_update_bits(codec, WCD934X_ANA_MICB4, 0x3F, vout_ctl_4); + snd_soc_component_update_bits(component, WCD934X_ANA_MICB1, + 0x3F, vout_ctl_1); + snd_soc_component_update_bits(component, WCD934X_ANA_MICB2, + 0x3F, vout_ctl_2); + snd_soc_component_update_bits(component, WCD934X_ANA_MICB3, + 0x3F, vout_ctl_3); + snd_soc_component_update_bits(component, WCD934X_ANA_MICB4, + 0x3F, vout_ctl_4); /* Set the DMIC sample rate */ switch (pdata->mclk_rate) { @@ -9802,7 +10098,7 @@ static int tavil_handle_pdata(struct tavil_priv *tavil, break; default: /* should never happen */ - dev_err(codec->dev, "%s: Invalid mclk_rate %d\n", + dev_err(component->dev, "%s: Invalid mclk_rate %d\n", __func__, pdata->mclk_rate); rc = -EINVAL; goto done; @@ -9810,13 +10106,13 @@ static int tavil_handle_pdata(struct tavil_priv *tavil, if (pdata->dmic_sample_rate == WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) { - dev_info(codec->dev, "%s: dmic_rate invalid default = %d\n", + dev_info(component->dev, "%s: dmic_rate invalid default = %d\n", __func__, def_dmic_rate); pdata->dmic_sample_rate = def_dmic_rate; } if (pdata->mad_dmic_sample_rate == WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) { - dev_info(codec->dev, "%s: mad_dmic_rate invalid default = %d\n", + dev_info(component->dev, "%s: mad_dmic_rate invalid default = %d\n", __func__, def_dmic_rate); /* * use dmic_sample_rate as the default for MAD @@ -9828,7 +10124,7 @@ static int tavil_handle_pdata(struct tavil_priv *tavil, if (pdata->dmic_clk_drv == WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED) { pdata->dmic_clk_drv = WCD934X_DMIC_CLK_DRIVE_DEFAULT; - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: dmic_clk_strength invalid, default = %d\n", __func__, pdata->dmic_clk_drv); } @@ -9847,29 +10143,30 @@ static int tavil_handle_pdata(struct tavil_priv *tavil, dmic_clk_drv = 3; break; default: - dev_err(codec->dev, + dev_err(component->dev, "%s: invalid dmic_clk_drv %d, using default\n", __func__, pdata->dmic_clk_drv); dmic_clk_drv = 0; break; } - snd_soc_update_bits(codec, WCD934X_TEST_DEBUG_PAD_DRVCTL_0, - 0x0C, dmic_clk_drv << 2); + snd_soc_component_update_bits(component, + WCD934X_TEST_DEBUG_PAD_DRVCTL_0, + 0x0C, dmic_clk_drv << 2); /* * Default the DMIC clk rates to mad_dmic_sample_rate, * whereas, the anc/txfe dmic rates to dmic_sample_rate * since the anc/txfe are independent of mad block. */ - mad_dmic_ctl_val = tavil_get_dmic_clk_val(tavil->codec, + mad_dmic_ctl_val = tavil_get_dmic_clk_val(tavil->component, pdata->mclk_rate, pdata->mad_dmic_sample_rate); - snd_soc_update_bits(codec, WCD934X_CPE_SS_DMIC0_CTL, + snd_soc_component_update_bits(component, WCD934X_CPE_SS_DMIC0_CTL, 0x0E, mad_dmic_ctl_val << 1); - snd_soc_update_bits(codec, WCD934X_CPE_SS_DMIC1_CTL, + snd_soc_component_update_bits(component, WCD934X_CPE_SS_DMIC1_CTL, 0x0E, mad_dmic_ctl_val << 1); - snd_soc_update_bits(codec, WCD934X_CPE_SS_DMIC2_CTL, + snd_soc_component_update_bits(component, WCD934X_CPE_SS_DMIC2_CTL, 0x0E, mad_dmic_ctl_val << 1); if (dmic_clk_drv == WCD934X_DMIC_CLK_DIV_2) @@ -9877,22 +10174,22 @@ static int tavil_handle_pdata(struct tavil_priv *tavil, else anc_ctl_value = WCD934X_ANC_DMIC_X2_HALF_RATE; - snd_soc_update_bits(codec, WCD934X_CDC_ANC0_MODE_2_CTL, + snd_soc_component_update_bits(component, WCD934X_CDC_ANC0_MODE_2_CTL, 0x40, anc_ctl_value << 6); - snd_soc_update_bits(codec, WCD934X_CDC_ANC0_MODE_2_CTL, + snd_soc_component_update_bits(component, WCD934X_CDC_ANC0_MODE_2_CTL, 0x20, anc_ctl_value << 5); - snd_soc_update_bits(codec, WCD934X_CDC_ANC1_MODE_2_CTL, + snd_soc_component_update_bits(component, WCD934X_CDC_ANC1_MODE_2_CTL, 0x40, anc_ctl_value << 6); - snd_soc_update_bits(codec, WCD934X_CDC_ANC1_MODE_2_CTL, + snd_soc_component_update_bits(component, WCD934X_CDC_ANC1_MODE_2_CTL, 0x20, anc_ctl_value << 5); done: return rc; } -static void tavil_cdc_vote_svs(struct snd_soc_codec *codec, bool vote) +static void tavil_cdc_vote_svs(struct snd_soc_component *component, bool vote) { - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); return tavil_vote_svs(tavil, vote); } @@ -9902,15 +10199,15 @@ static struct wcd_dsp_cdc_cb cdc_cb = { .cdc_vote_svs = tavil_cdc_vote_svs, }; -static int tavil_wdsp_initialize(struct snd_soc_codec *codec) +static int tavil_wdsp_initialize(struct snd_soc_component *component) { struct wcd9xxx *control; struct tavil_priv *tavil; struct wcd_dsp_params params; int ret = 0; - control = dev_get_drvdata(codec->dev->parent); - tavil = snd_soc_codec_get_drvdata(codec); + control = dev_get_drvdata(component->dev->parent); + tavil = snd_soc_component_get_drvdata(component); params.cb = &cdc_cb; params.irqs.cpe_ipc1_irq = WCD934X_IRQ_CPE1_INTR; @@ -9919,7 +10216,7 @@ static int tavil_wdsp_initialize(struct snd_soc_codec *codec) params.clk_rate = control->mclk_rate; params.dsp_instance = 0; - wcd_dsp_cntl_init(codec, ¶ms, &tavil->wdsp_cntl); + wcd_dsp_cntl_init(component, ¶ms, &tavil->wdsp_cntl); if (!tavil->wdsp_cntl) { dev_err(tavil->dev, "%s: wcd-dsp-control init failed\n", __func__); @@ -9931,19 +10228,19 @@ static int tavil_wdsp_initialize(struct snd_soc_codec *codec) /* * tavil_soc_get_mbhc: get wcd934x_mbhc handle of corresponding codec - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * * * return wcd934x_mbhc handle or error code in case of failure */ -struct wcd934x_mbhc *tavil_soc_get_mbhc(struct snd_soc_codec *codec) +struct wcd934x_mbhc *tavil_soc_get_mbhc(struct snd_soc_component *component) { struct tavil_priv *tavil; - if (!codec) { + if (!component) { pr_err("%s: Invalid params, NULL codec\n", __func__); return NULL; } - tavil = snd_soc_codec_get_drvdata(codec); + tavil = snd_soc_component_get_drvdata(component); if (!tavil) { pr_err("%s: Invalid params, NULL tavil\n", __func__); @@ -9957,12 +10254,12 @@ EXPORT_SYMBOL(tavil_soc_get_mbhc); static void tavil_mclk2_reg_defaults(struct tavil_priv *tavil) { int i; - struct snd_soc_codec *codec = tavil->codec; + struct snd_soc_component *component = tavil->component; if (TAVIL_IS_1_0(tavil->wcd9xxx)) { /* MCLK2 configuration */ for (i = 0; i < ARRAY_SIZE(tavil_codec_mclk2_1_0_defaults); i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, tavil_codec_mclk2_1_0_defaults[i].reg, tavil_codec_mclk2_1_0_defaults[i].mask, tavil_codec_mclk2_1_0_defaults[i].val); @@ -9970,7 +10267,7 @@ static void tavil_mclk2_reg_defaults(struct tavil_priv *tavil) if (TAVIL_IS_1_1(tavil->wcd9xxx)) { /* MCLK2 configuration */ for (i = 0; i < ARRAY_SIZE(tavil_codec_mclk2_1_1_defaults); i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, tavil_codec_mclk2_1_1_defaults[i].reg, tavil_codec_mclk2_1_1_defaults[i].mask, tavil_codec_mclk2_1_1_defaults[i].val); @@ -9979,20 +10276,20 @@ static void tavil_mclk2_reg_defaults(struct tavil_priv *tavil) static int tavil_device_down(struct wcd9xxx *wcd9xxx) { - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct tavil_priv *priv; int count; int decimator; int ret; - codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); - if (!codec->component.card) { - dev_err(codec->dev, "%s: sound card is not enumerated.\n", + component = (struct snd_soc_component *)(wcd9xxx->ssr_priv); + if (!component->card) { + dev_err(component->dev, "%s: sound card is not enumerated.\n", __func__); return -EINVAL; } - priv = snd_soc_codec_get_drvdata(codec); + priv = snd_soc_component_get_drvdata(component); for (count = 0; count < NUM_CODEC_DAIS; count++) priv->dai[count].bus_down_in_recovery = true; snd_event_notify(priv->dev->parent, SND_EVENT_DOWN); @@ -10028,7 +10325,7 @@ static int tavil_device_down(struct wcd9xxx *wcd9xxx) } tavil_dsd_reset(priv->dsd_config); if (!is_snd_event_fwk_enabled()) - snd_soc_card_change_online_state(codec->component.card, 0); + snd_soc_card_change_online_state(component->card, 0); wcd_dsp_ssr_event(priv->wdsp_cntl, WCD_CDC_DOWN_EVENT); wcd_resmgr_set_sido_input_src_locked(priv->resmgr, SIDO_SOURCE_INTERNAL); @@ -10040,19 +10337,19 @@ static int tavil_post_reset_cb(struct wcd9xxx *wcd9xxx) { int i, ret = 0; struct wcd9xxx *control; - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct tavil_priv *tavil; struct wcd9xxx_pdata *pdata; struct wcd_mbhc *mbhc; - codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); - if (!codec->component.card) { + component = (struct snd_soc_component *)(wcd9xxx->ssr_priv); + if (!component->card) { dev_err(codec->dev, "%s: sound card is not enumerated.\n", __func__); return -EINVAL; } - tavil = snd_soc_codec_get_drvdata(codec); - control = dev_get_drvdata(codec->dev->parent); + tavil = snd_soc_component_get_drvdata(component); + control = dev_get_drvdata(component->dev->parent); wcd9xxx_set_power_state(tavil->wcd9xxx, WCD_REGION_POWER_COLLAPSE_REMOVE, @@ -10065,22 +10362,24 @@ static int tavil_post_reset_cb(struct wcd9xxx *wcd9xxx) control->slim_slave->laddr; tavil_slimbus_slave_port_cfg.slave_dev_pgd_la = control->slim->laddr; - tavil_init_slim_slave_cfg(codec); + tavil_init_slim_slave_cfg(component); if (!is_snd_event_fwk_enabled()) - snd_soc_card_change_online_state(codec->component.card, 1); + snd_soc_card_change_online_state(component->card, 1); for (i = 0; i < TAVIL_MAX_MICBIAS; i++) tavil->micb_ref[i] = 0; - dev_dbg(codec->dev, "%s: MCLK Rate = %x\n", + dev_dbg(component->dev, "%s: MCLK Rate = %x\n", __func__, control->mclk_rate); if (control->mclk_rate == WCD934X_MCLK_CLK_12P288MHZ) - snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_MCLK_CFG, - 0x03, 0x00); + snd_soc_component_update_bits(component, + WCD934X_CODEC_RPM_CLK_MCLK_CFG, + 0x03, 0x00); else if (control->mclk_rate == WCD934X_MCLK_CLK_9P6MHZ) - snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_MCLK_CFG, - 0x03, 0x01); + snd_soc_component_update_bits(component, + WCD934X_CODEC_RPM_CLK_MCLK_CFG, + 0x03, 0x01); tavil_update_reg_defaults(tavil); wcd_resmgr_post_ssr_v2(tavil->resmgr); tavil_codec_init_reg(tavil); @@ -10088,26 +10387,26 @@ static int tavil_post_reset_cb(struct wcd9xxx *wcd9xxx) tavil_mclk2_reg_defaults(tavil); __tavil_cdc_mclk_enable(tavil, true); - regcache_mark_dirty(codec->component.regmap); - regcache_sync(codec->component.regmap); + regcache_mark_dirty(component->regmap); + regcache_sync(component->regmap); __tavil_cdc_mclk_enable(tavil, false); tavil_update_cpr_defaults(tavil); - pdata = dev_get_platdata(codec->dev->parent); + pdata = dev_get_platdata(component->dev->parent); ret = tavil_handle_pdata(tavil, pdata); if (ret < 0) - dev_err(codec->dev, "%s: invalid pdata\n", __func__); + dev_err(component->dev, "%s: invalid pdata\n", __func__); /* Initialize MBHC module */ mbhc = &tavil->mbhc->wcd_mbhc; - ret = tavil_mbhc_post_ssr_init(tavil->mbhc, codec); + ret = tavil_mbhc_post_ssr_init(tavil->mbhc, component); if (ret) { - dev_err(codec->dev, "%s: mbhc initialization failed\n", + dev_err(component->dev, "%s: mbhc initialization failed\n", __func__); goto done; } else { - tavil_mbhc_hs_detect(codec, mbhc->mbhc_cfg); + tavil_mbhc_hs_detect(component, mbhc->mbhc_cfg); } /* DSD initialization */ @@ -10118,7 +10417,7 @@ static int tavil_post_reset_cb(struct wcd9xxx *wcd9xxx) tavil_cleanup_irqs(tavil); ret = tavil_setup_irqs(tavil); if (ret) { - dev_err(codec->dev, "%s: tavil irq setup failed %d\n", + dev_err(component->dev, "%s: tavil irq setup failed %d\n", __func__, ret); goto done; } @@ -10126,7 +10425,7 @@ static int tavil_post_reset_cb(struct wcd9xxx *wcd9xxx) if (tavil->swr.ctrl_data && is_snd_event_fwk_enabled()) swrm_wcd_notify(tavil->swr.ctrl_data[0].swr_pdev, SWR_DEVICE_SSR_UP, NULL); - tavil_set_spkr_mode(codec, tavil->swr.spkr_mode); + tavil_set_spkr_mode(component, tavil->swr.spkr_mode); /* * Once the codec initialization is completed, the svs vote * can be released allowing the codec to go to SVS2. @@ -10140,29 +10439,32 @@ static int tavil_post_reset_cb(struct wcd9xxx *wcd9xxx) return ret; } -static int tavil_soc_codec_probe(struct snd_soc_codec *codec) +static int tavil_soc_codec_probe(struct snd_soc_component *component) { struct wcd9xxx *control; struct tavil_priv *tavil; struct wcd9xxx_pdata *pdata; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); int i, ret; void *ptr = NULL; - control = dev_get_drvdata(codec->dev->parent); + control = dev_get_drvdata(component->dev->parent); + + snd_soc_component_init_regmap(component, control->regmap); - dev_info(codec->dev, "%s()\n", __func__); - tavil = snd_soc_codec_get_drvdata(codec); + dev_info(component->dev, "%s()\n", __func__); + tavil = snd_soc_component_get_drvdata(component); tavil->intf_type = wcd9xxx_get_intf_type(); control->dev_down = tavil_device_down; control->post_reset = tavil_post_reset_cb; - control->ssr_priv = (void *)codec; + control->ssr_priv = (void *)component; /* Resource Manager post Init */ - ret = wcd_resmgr_post_init(tavil->resmgr, &tavil_resmgr_cb, codec); + ret = wcd_resmgr_post_init(tavil->resmgr, &tavil_resmgr_cb, component); if (ret) { - dev_err(codec->dev, "%s: wcd resmgr post init failed\n", + dev_err(component->dev, "%s: wcd resmgr post init failed\n", __func__); goto err; } @@ -10171,7 +10473,7 @@ static int tavil_soc_codec_probe(struct snd_soc_codec *codec) /* Default HPH Mode to Class-H Low HiFi */ tavil->hph_mode = CLS_H_LOHIFI; - tavil->fw_data = devm_kzalloc(codec->dev, sizeof(*(tavil->fw_data)), + tavil->fw_data = devm_kzalloc(component->dev, sizeof(*(tavil->fw_data)), GFP_KERNEL); if (!tavil->fw_data) goto err; @@ -10182,33 +10484,33 @@ static int tavil_soc_codec_probe(struct snd_soc_codec *codec) set_bit(WCD9XXX_VBAT_CAL, tavil->fw_data->cal_bit); ret = wcd_cal_create_hwdep(tavil->fw_data, - WCD9XXX_CODEC_HWDEP_NODE, codec); + WCD9XXX_CODEC_HWDEP_NODE, component); if (ret < 0) { - dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret); + dev_err(component->dev, "%s hwdep failed %d\n", __func__, ret); goto err_hwdep; } /* Initialize MBHC module */ - ret = tavil_mbhc_init(&tavil->mbhc, codec, tavil->fw_data); + ret = tavil_mbhc_init(&tavil->mbhc, component, tavil->fw_data); if (ret) { pr_err("%s: mbhc initialization failed\n", __func__); goto err_hwdep; } - tavil->codec = codec; + tavil->component = component; for (i = 0; i < COMPANDER_MAX; i++) tavil->comp_enabled[i] = 0; tavil_codec_init_reg(tavil); - pdata = dev_get_platdata(codec->dev->parent); + pdata = dev_get_platdata(component->dev->parent); ret = tavil_handle_pdata(tavil, pdata); if (ret < 0) { - dev_err(codec->dev, "%s: bad pdata\n", __func__); + dev_err(component->dev, "%s: bad pdata\n", __func__); goto err_hwdep; } - ptr = devm_kzalloc(codec->dev, (sizeof(tavil_rx_chs) + + ptr = devm_kzalloc(component->dev, (sizeof(tavil_rx_chs) + sizeof(tavil_tx_chs)), GFP_KERNEL); if (!ptr) { ret = -ENOMEM; @@ -10231,7 +10533,7 @@ static int tavil_soc_codec_probe(struct snd_soc_codec *codec) control->slim->laddr; tavil_slimbus_slave_port_cfg.slave_port_mapping[0] = WCD934X_TX13; - tavil_init_slim_slave_cfg(codec); + tavil_init_slim_slave_cfg(component); } else { snd_soc_dapm_new_controls(dapm, tavil_dapm_i2s_widgets, ARRAY_SIZE(tavil_dapm_i2s_widgets)); @@ -10272,7 +10574,7 @@ static int tavil_soc_codec_probe(struct snd_soc_codec *codec) tavil_mclk2_reg_defaults(tavil); /* DSD initialization */ - tavil->dsd_config = tavil_dsd_init(codec); + tavil->dsd_config = tavil_dsd_init(component); if (IS_ERR_OR_NULL(tavil->dsd_config)) dev_dbg(tavil->dev, "%s: DSD init failed\n", __func__); @@ -10302,7 +10604,7 @@ static int tavil_soc_codec_probe(struct snd_soc_codec *codec) snd_soc_dapm_sync(dapm); - tavil_wdsp_initialize(codec); + tavil_wdsp_initialize(component); /* * Once the codec initialization is completed, the svs vote @@ -10313,23 +10615,23 @@ static int tavil_soc_codec_probe(struct snd_soc_codec *codec) return ret; err_pdata: - devm_kfree(codec->dev, ptr); + devm_kfree(component->dev, ptr); control->rx_chs = NULL; control->tx_chs = NULL; err_hwdep: - devm_kfree(codec->dev, tavil->fw_data); + devm_kfree(component->dev, tavil->fw_data); tavil->fw_data = NULL; err: return ret; } -static int tavil_soc_codec_remove(struct snd_soc_codec *codec) +static void tavil_soc_codec_remove(struct snd_soc_component *component) { struct wcd9xxx *control; - struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec); + struct tavil_priv *tavil = snd_soc_component_get_drvdata(component); - control = dev_get_drvdata(codec->dev->parent); - devm_kfree(codec->dev, control->rx_chs); + control = dev_get_drvdata(component->dev->parent); + devm_kfree(component->dev, control->rx_chs); /* slimslave deinit in wcd core looks for this value */ control->num_rx_port = 0; control->num_tx_port = 0; @@ -10341,31 +10643,22 @@ static int tavil_soc_codec_remove(struct snd_soc_codec *codec) wcd_dsp_cntl_deinit(&tavil->wdsp_cntl); /* Deinitialize MBHC module */ - tavil_mbhc_deinit(codec); + tavil_mbhc_deinit(component); tavil->mbhc = NULL; - return 0; -} - -static struct regmap *tavil_get_regmap(struct device *dev) -{ - struct wcd9xxx *control = dev_get_drvdata(dev->parent); - - return control->regmap; + return; } -static struct snd_soc_codec_driver soc_codec_dev_tavil = { +static const struct snd_soc_component_driver soc_codec_dev_tavil = { + .name = DRV_NAME, .probe = tavil_soc_codec_probe, .remove = tavil_soc_codec_remove, - .get_regmap = tavil_get_regmap, - .component_driver = { - .controls = tavil_snd_controls, - .num_controls = ARRAY_SIZE(tavil_snd_controls), - .dapm_widgets = tavil_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(tavil_dapm_widgets), - .dapm_routes = tavil_audio_map, - .num_dapm_routes = ARRAY_SIZE(tavil_audio_map), - }, + .controls = tavil_snd_controls, + .num_controls = ARRAY_SIZE(tavil_snd_controls), + .dapm_widgets = tavil_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tavil_dapm_widgets), + .dapm_routes = tavil_audio_map, + .num_dapm_routes = ARRAY_SIZE(tavil_audio_map), }; #ifdef CONFIG_PM @@ -10938,15 +11231,15 @@ static void wcd934x_ssr_disable(struct device *dev, void *data) { struct wcd9xxx *wcd9xxx = dev_get_drvdata(dev); struct tavil_priv *tavil; - struct snd_soc_codec *codec; + struct snd_soc_component *component; int count = 0; if (!wcd9xxx) { dev_dbg(dev, "%s: wcd9xxx pointer NULL.\n", __func__); return; } - codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv); - tavil = snd_soc_codec_get_drvdata(codec); + component = (struct snd_soc_component *)(wcd9xxx->ssr_priv); + tavil = snd_soc_component_get_drvdata(component); for (count = 0; count < NUM_CODEC_DAIS; count++) tavil->dai[count].bus_down_in_recovery = true; @@ -11066,13 +11359,15 @@ static int tavil_probe(struct platform_device *pdev) /* Register with soc framework */ if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) - ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tavil, - tavil_i2s_dai, - ARRAY_SIZE(tavil_i2s_dai)); + ret = snd_soc_register_component(&pdev->dev, + &soc_codec_dev_tavil, + tavil_i2s_dai, + ARRAY_SIZE(tavil_i2s_dai)); else - ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tavil, - tavil_slim_dai, - ARRAY_SIZE(tavil_slim_dai)); + ret = snd_soc_register_component(&pdev->dev, + &soc_codec_dev_tavil, + tavil_slim_dai, + ARRAY_SIZE(tavil_slim_dai)); if (ret) { dev_err(&pdev->dev, "%s: Codec registration failed\n", @@ -11081,7 +11376,8 @@ static int tavil_probe(struct platform_device *pdev) } schedule_work(&tavil->tavil_add_child_devices_work); - ret = snd_event_client_register(pdev->dev.parent, &wcd934x_ssr_ops, NULL); + ret = snd_event_client_register(pdev->dev.parent, + &wcd934x_ssr_ops, NULL); if (!ret) { snd_event_notify(pdev->dev.parent, SND_EVENT_UP); } else { @@ -11161,7 +11457,7 @@ static int tavil_remove(struct platform_device *pdev) mutex_destroy(&tavil->swr.write_mutex); mutex_destroy(&tavil->swr.clk_mutex); - snd_soc_unregister_codec(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); clk_put(tavil->wcd_ext_clk); wcd_resmgr_remove(tavil->resmgr); devm_kfree(&pdev->dev, tavil); diff --git a/asoc/codecs/wcd934x/wcd934x.h b/asoc/codecs/wcd934x/wcd934x.h index c0aec9efc061..a14e6eb05091 100644 --- a/asoc/codecs/wcd934x/wcd934x.h +++ b/asoc/codecs/wcd934x/wcd934x.h @@ -127,47 +127,54 @@ struct tavil_reg_mask_val { }; #if IS_ENABLED(CONFIG_SND_SOC_WCD934X) -extern void *tavil_get_afe_config(struct snd_soc_codec *codec, +extern void *tavil_get_afe_config(struct snd_soc_component *component, enum afe_config_type config_type); -extern int tavil_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable); -extern int tavil_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable); -extern int tavil_set_spkr_mode(struct snd_soc_codec *codec, int mode); -extern int tavil_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset); +extern int tavil_cdc_mclk_enable(struct snd_soc_component *component, + bool enable); +extern int tavil_cdc_mclk_tx_enable(struct snd_soc_component *component, + bool enable); +extern int tavil_set_spkr_mode(struct snd_soc_component *component, int mode); +extern int tavil_set_spkr_gain_offset(struct snd_soc_component *component, + int offset); extern struct wcd_dsp_cntl *tavil_get_wcd_dsp_cntl(struct device *dev); extern int wcd934x_get_micb_vout_ctl_val(u32 micb_mv); -extern int tavil_micbias_control(struct snd_soc_codec *codec, +extern int tavil_micbias_control(struct snd_soc_component *component, int micb_num, int req, bool is_dapm); -extern int tavil_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, +extern int tavil_mbhc_micb_adjust_voltage(struct snd_soc_component *component, int req_volt, int micb_num); -extern struct wcd934x_mbhc *tavil_soc_get_mbhc(struct snd_soc_codec *codec); -extern int tavil_codec_enable_interp_clk(struct snd_soc_codec *codec, +extern struct wcd934x_mbhc *tavil_soc_get_mbhc( + struct snd_soc_component *component); +extern int tavil_codec_enable_interp_clk(struct snd_soc_component *component, int event, int intp_idx); extern struct tavil_dsd_config *tavil_get_dsd_config( - struct snd_soc_codec *codec); + struct snd_soc_component *component); extern int tavil_codec_info_create_codec_entry( struct snd_info_entry *codec_root, - struct snd_soc_codec *codec); + struct snd_soc_component *component); #else -extern void *tavil_get_afe_config(struct snd_soc_codec *codec, +extern void *tavil_get_afe_config(struct snd_soc_component *component, enum afe_config_type config_type) { return NULL; } -extern int tavil_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable) +extern int tavil_cdc_mclk_enable(struct snd_soc_component *component, + bool enable) { return 0; } -extern int tavil_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable) +extern int tavil_cdc_mclk_tx_enable(struct snd_soc_component *component, + bool enable) { return 0; } -extern int tavil_set_spkr_mode(struct snd_soc_codec *codec, int mode) +extern int tavil_set_spkr_mode(struct snd_soc_component *component, int mode) { return 0; } -extern int tavil_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset) +extern int tavil_set_spkr_gain_offset(struct snd_soc_component *component, + int offset) { return 0; } @@ -179,35 +186,36 @@ extern int wcd934x_get_micb_vout_ctl_val(u32 micb_mv) { return 0; } -extern int tavil_micbias_control(struct snd_soc_codec *codec, +extern int tavil_micbias_control(struct snd_soc_component *component, int micb_num, int req, bool is_dapm) { return 0; } -extern int tavil_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, +extern int tavil_mbhc_micb_adjust_voltage(struct snd_soc_component *component, int req_volt, int micb_num) { return 0; } -extern struct wcd934x_mbhc *tavil_soc_get_mbhc(struct snd_soc_codec *codec) +extern struct wcd934x_mbhc *tavil_soc_get_mbhc( + struct snd_soc_component *component) { return NULL; } -extern int tavil_codec_enable_interp_clk(struct snd_soc_codec *codec, +extern int tavil_codec_enable_interp_clk(struct snd_soc_component *component, int event, int intp_idx) { return 0; } extern struct tavil_dsd_config *tavil_get_dsd_config( - struct snd_soc_codec *codec) + struct snd_soc_component *component) { return NULL; } extern int tavil_codec_info_create_codec_entry( struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { return 0; } diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index 46c0c022b8d8..b4165115b8b1 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -30,7 +30,7 @@ struct wcd937x_priv { struct device *dev; int variant; - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct device_node *rst_np; struct regmap *regmap; @@ -160,10 +160,11 @@ enum { WCD937X_NUM_IRQS, }; -extern struct wcd937x_mbhc *wcd937x_soc_get_mbhc(struct snd_soc_codec *codec); -extern int wcd937x_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, +extern struct wcd937x_mbhc *wcd937x_soc_get_mbhc( + struct snd_soc_component *component); +extern int wcd937x_mbhc_micb_adjust_voltage(struct snd_soc_component *component, int volt, int micb_num); extern int wcd937x_get_micb_vout_ctl_val(u32 micb_mv); -extern int wcd937x_micbias_control(struct snd_soc_codec *codec, int micb_num, - int req, bool is_dapm); +extern int wcd937x_micbias_control(struct snd_soc_component *component, + int micb_num, int req, bool is_dapm); #endif diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index 1e0fcf8082ea..543897628acd 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -157,19 +157,19 @@ struct wcd937x_mbhc_zdet_param { u16 btn7; }; -static int wcd937x_mbhc_request_irq(struct snd_soc_codec *codec, +static int wcd937x_mbhc_request_irq(struct snd_soc_component *component, int irq, irq_handler_t handler, const char *name, void *data) { - struct wcd937x_priv *wcd937x = dev_get_drvdata(codec->dev); + struct wcd937x_priv *wcd937x = dev_get_drvdata(component->dev); return wcd_request_irq(&wcd937x->irq_info, irq, name, handler, data); } -static void wcd937x_mbhc_irq_control(struct snd_soc_codec *codec, +static void wcd937x_mbhc_irq_control(struct snd_soc_component *component, int irq, bool enable) { - struct wcd937x_priv *wcd937x = dev_get_drvdata(codec->dev); + struct wcd937x_priv *wcd937x = dev_get_drvdata(component->dev); if (enable) wcd_enable_irq(&wcd937x->irq_info, irq); @@ -177,44 +177,45 @@ static void wcd937x_mbhc_irq_control(struct snd_soc_codec *codec, wcd_disable_irq(&wcd937x->irq_info, irq); } -static int wcd937x_mbhc_free_irq(struct snd_soc_codec *codec, +static int wcd937x_mbhc_free_irq(struct snd_soc_component *component, int irq, void *data) { - struct wcd937x_priv *wcd937x = dev_get_drvdata(codec->dev); + struct wcd937x_priv *wcd937x = dev_get_drvdata(component->dev); wcd_free_irq(&wcd937x->irq_info, irq, data); return 0; } -static void wcd937x_mbhc_clk_setup(struct snd_soc_codec *codec, +static void wcd937x_mbhc_clk_setup(struct snd_soc_component *component, bool enable) { if (enable) - snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_1, + snd_soc_component_update_bits(component, WCD937X_MBHC_NEW_CTL_1, 0x80, 0x80); else - snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_1, + snd_soc_component_update_bits(component, WCD937X_MBHC_NEW_CTL_1, 0x80, 0x00); } -static int wcd937x_mbhc_btn_to_num(struct snd_soc_codec *codec) +static int wcd937x_mbhc_btn_to_num(struct snd_soc_component *component) { - return snd_soc_read(codec, WCD937X_ANA_MBHC_RESULT_3) & 0x7; + return snd_soc_component_read32(component, WCD937X_ANA_MBHC_RESULT_3) & + 0x7; } -static void wcd937x_mbhc_mbhc_bias_control(struct snd_soc_codec *codec, +static void wcd937x_mbhc_mbhc_bias_control(struct snd_soc_component *component, bool enable) { if (enable) - snd_soc_update_bits(codec, WCD937X_ANA_MBHC_ELECT, + snd_soc_component_update_bits(component, WCD937X_ANA_MBHC_ELECT, 0x01, 0x01); else - snd_soc_update_bits(codec, WCD937X_ANA_MBHC_ELECT, + snd_soc_component_update_bits(component, WCD937X_ANA_MBHC_ELECT, 0x01, 0x00); } -static void wcd937x_mbhc_program_btn_thr(struct snd_soc_codec *codec, +static void wcd937x_mbhc_program_btn_thr(struct snd_soc_component *component, s16 *btn_low, s16 *btn_high, int num_btn, bool is_micbias) { @@ -222,16 +223,17 @@ static void wcd937x_mbhc_program_btn_thr(struct snd_soc_codec *codec, int vth; if (num_btn > WCD_MBHC_DEF_BUTTONS) { - dev_err(codec->dev, "%s: invalid number of buttons: %d\n", + dev_err(component->dev, "%s: invalid number of buttons: %d\n", __func__, num_btn); return; } for (i = 0; i < num_btn; i++) { vth = ((btn_high[i] * 2) / 25) & 0x3F; - snd_soc_update_bits(codec, WCD937X_ANA_MBHC_BTN0 + i, - 0xFC, vth << 2); - dev_dbg(codec->dev, "%s: btn_high[%d]: %d, vth: %d\n", + snd_soc_component_update_bits(component, + WCD937X_ANA_MBHC_BTN0 + i, + 0xFC, vth << 2); + dev_dbg(component->dev, "%s: btn_high[%d]: %d, vth: %d\n", __func__, i, btn_high[i], vth); } } @@ -262,7 +264,8 @@ static bool wcd937x_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) u8 val = 0; if (micb_num == MIC_BIAS_2) { - val = ((snd_soc_read(mbhc->codec, WCD937X_ANA_MICB2) & 0xC0) + val = ((snd_soc_component_read32(mbhc->component, + WCD937X_ANA_MICB2) & 0xC0) >> 6); if (val == 0x01) return true; @@ -270,48 +273,51 @@ static bool wcd937x_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) return false; } -static bool wcd937x_mbhc_hph_pa_on_status(struct snd_soc_codec *codec) +static bool wcd937x_mbhc_hph_pa_on_status(struct snd_soc_component *component) { - return (snd_soc_read(codec, WCD937X_ANA_HPH) & 0xC0) ? true : false; + return (snd_soc_component_read32(component, WCD937X_ANA_HPH) & 0xC0) ? + true : false; } -static void wcd937x_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec, - int pull_up_cur) +static void wcd937x_mbhc_hph_l_pull_up_control( + struct snd_soc_component *component, + int pull_up_cur) { /* Default pull up current to 2uA */ if (pull_up_cur > HS_PULLUP_I_OFF || pull_up_cur < HS_PULLUP_I_3P0_UA || pull_up_cur == HS_PULLUP_I_DEFAULT) pull_up_cur = HS_PULLUP_I_2P0_UA; - dev_dbg(codec->dev, "%s: HS pull up current:%d\n", + dev_dbg(component->dev, "%s: HS pull up current:%d\n", __func__, pull_up_cur); - snd_soc_update_bits(codec, WCD937X_MBHC_NEW_INT_MECH_DET_CURRENT, - 0x1F, pull_up_cur); + snd_soc_component_update_bits(component, + WCD937X_MBHC_NEW_INT_MECH_DET_CURRENT, + 0x1F, pull_up_cur); } -static int wcd937x_mbhc_request_micbias(struct snd_soc_codec *codec, +static int wcd937x_mbhc_request_micbias(struct snd_soc_component *component, int micb_num, int req) { int ret = 0; - ret = wcd937x_micbias_control(codec, micb_num, req, false); + ret = wcd937x_micbias_control(component, micb_num, req, false); return ret; } -static void wcd937x_mbhc_micb_ramp_control(struct snd_soc_codec *codec, +static void wcd937x_mbhc_micb_ramp_control(struct snd_soc_component *component, bool enable) { if (enable) { - snd_soc_update_bits(codec, WCD937X_ANA_MICB2_RAMP, + snd_soc_component_update_bits(component, WCD937X_ANA_MICB2_RAMP, 0x1C, 0x0C); - snd_soc_update_bits(codec, WCD937X_ANA_MICB2_RAMP, + snd_soc_component_update_bits(component, WCD937X_ANA_MICB2_RAMP, 0x80, 0x80); } else { - snd_soc_update_bits(codec, WCD937X_ANA_MICB2_RAMP, + snd_soc_component_update_bits(component, WCD937X_ANA_MICB2_RAMP, 0x80, 0x00); - snd_soc_update_bits(codec, WCD937X_ANA_MICB2_RAMP, + snd_soc_component_update_bits(component, WCD937X_ANA_MICB2_RAMP, 0x1C, 0x00); } } @@ -321,26 +327,27 @@ static struct firmware_cal *wcd937x_get_hwdep_fw_cal(struct wcd_mbhc *mbhc, { struct wcd937x_mbhc *wcd937x_mbhc; struct firmware_cal *hwdep_cal; - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; wcd937x_mbhc = container_of(mbhc, struct wcd937x_mbhc, wcd_mbhc); - if (!codec) { - pr_err("%s: NULL codec pointer\n", __func__); + if (!component) { + pr_err("%s: NULL component pointer\n", __func__); return NULL; } hwdep_cal = wcdcal_get_fw_cal(wcd937x_mbhc->fw_data, type); if (!hwdep_cal) - dev_err(codec->dev, "%s: cal not sent by %d\n", + dev_err(component->dev, "%s: cal not sent by %d\n", __func__, type); return hwdep_cal; } -static int wcd937x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec, - int micb_num, bool req_en) +static int wcd937x_mbhc_micb_ctrl_threshold_mic( + struct snd_soc_component *component, + int micb_num, bool req_en) { - struct wcd937x_pdata *pdata = dev_get_platdata(codec->dev); + struct wcd937x_pdata *pdata = dev_get_platdata(component->dev); int rc, micb_mv; if (micb_num != MIC_BIAS_2) @@ -355,7 +362,7 @@ static int wcd937x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec, micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb2_mv; - rc = wcd937x_mbhc_micb_adjust_voltage(codec, micb_mv, MIC_BIAS_2); + rc = wcd937x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2); return rc; } @@ -418,25 +425,25 @@ static inline void wcd937x_mbhc_get_result_params(struct wcd937x_priv *wcd937x, } } -static void wcd937x_mbhc_zdet_ramp(struct snd_soc_codec *codec, +static void wcd937x_mbhc_zdet_ramp(struct snd_soc_component *component, struct wcd937x_mbhc_zdet_param *zdet_param, int32_t *zl, int32_t *zr, s16 *d1_a) { - struct wcd937x_priv *wcd937x = dev_get_drvdata(codec->dev); + struct wcd937x_priv *wcd937x = dev_get_drvdata(component->dev); int32_t zdet = 0; - snd_soc_update_bits(codec, WCD937X_MBHC_NEW_ZDET_ANA_CTL, 0x70, - zdet_param->ldo_ctl << 4); - snd_soc_update_bits(codec, WCD937X_ANA_MBHC_BTN5, 0xFC, - zdet_param->btn5); - snd_soc_update_bits(codec, WCD937X_ANA_MBHC_BTN6, 0xFC, - zdet_param->btn6); - snd_soc_update_bits(codec, WCD937X_ANA_MBHC_BTN7, 0xFC, - zdet_param->btn7); - snd_soc_update_bits(codec, WCD937X_MBHC_NEW_ZDET_ANA_CTL, 0x0F, - zdet_param->noff); - snd_soc_update_bits(codec, WCD937X_MBHC_NEW_ZDET_RAMP_CTL, 0x0F, - zdet_param->nshift); + snd_soc_component_update_bits(component, WCD937X_MBHC_NEW_ZDET_ANA_CTL, + 0x70, zdet_param->ldo_ctl << 4); + snd_soc_component_update_bits(component, WCD937X_ANA_MBHC_BTN5, 0xFC, + zdet_param->btn5); + snd_soc_component_update_bits(component, WCD937X_ANA_MBHC_BTN6, 0xFC, + zdet_param->btn6); + snd_soc_component_update_bits(component, WCD937X_ANA_MBHC_BTN7, 0xFC, + zdet_param->btn7); + snd_soc_component_update_bits(component, WCD937X_MBHC_NEW_ZDET_ANA_CTL, + 0x0F, zdet_param->noff); + snd_soc_component_update_bits(component, WCD937X_MBHC_NEW_ZDET_RAMP_CTL, + 0x0F, zdet_param->nshift); if (!zl) goto z_right; @@ -466,17 +473,18 @@ static void wcd937x_mbhc_zdet_ramp(struct snd_soc_codec *codec, *zr = zdet; } -static inline void wcd937x_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec, - int32_t *z_val, int flag_l_r) +static inline void wcd937x_wcd_mbhc_qfuse_cal( + struct snd_soc_component *component, + int32_t *z_val, int flag_l_r) { s16 q1; int q1_cal; if (*z_val < (WCD937X_ZDET_VAL_400/1000)) - q1 = snd_soc_read(codec, + q1 = snd_soc_component_read32(component, WCD937X_DIGITAL_EFUSE_REG_23 + (2 * flag_l_r)); else - q1 = snd_soc_read(codec, + q1 = snd_soc_component_read32(component, WCD937X_DIGITAL_EFUSE_REG_24 + (2 * flag_l_r)); if (q1 & 0x80) q1_cal = (10000 - ((q1 & 0x7F) * 25)); @@ -489,8 +497,8 @@ static inline void wcd937x_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec, static void wcd937x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, uint32_t *zr) { - struct snd_soc_codec *codec = mbhc->codec; - struct wcd937x_priv *wcd937x = dev_get_drvdata(codec->dev); + struct snd_soc_component *component = mbhc->component; + struct wcd937x_priv *wcd937x = dev_get_drvdata(component->dev); s16 reg0, reg1, reg2, reg3, reg4; int32_t z1L, z1R, z1Ls; int zMono, z_diff1, z_diff2; @@ -512,13 +520,15 @@ static void wcd937x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); - reg0 = snd_soc_read(codec, WCD937X_ANA_MBHC_BTN5); - reg1 = snd_soc_read(codec, WCD937X_ANA_MBHC_BTN6); - reg2 = snd_soc_read(codec, WCD937X_ANA_MBHC_BTN7); - reg3 = snd_soc_read(codec, WCD937X_MBHC_CTL_CLK); - reg4 = snd_soc_read(codec, WCD937X_MBHC_NEW_ZDET_ANA_CTL); + reg0 = snd_soc_component_read32(component, WCD937X_ANA_MBHC_BTN5); + reg1 = snd_soc_component_read32(component, WCD937X_ANA_MBHC_BTN6); + reg2 = snd_soc_component_read32(component, WCD937X_ANA_MBHC_BTN7); + reg3 = snd_soc_component_read32(component, WCD937X_MBHC_CTL_CLK); + reg4 = snd_soc_component_read32(component, + WCD937X_MBHC_NEW_ZDET_ANA_CTL); - if (snd_soc_read(codec, WCD937X_ANA_MBHC_ELECT) & 0x80) { + if (snd_soc_component_read32(component, WCD937X_ANA_MBHC_ELECT) & + 0x80) { is_fsm_disable = true; regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MBHC_ELECT, 0x80, 0x00); @@ -536,7 +546,7 @@ static void wcd937x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, /* First get impedance on Left */ d1 = d1_a[1]; zdet_param_ptr = &zdet_param[1]; - wcd937x_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + wcd937x_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1); if (!WCD937X_MBHC_IS_SECOND_RAMP_REQUIRED(z1L)) goto left_ch_impedance; @@ -553,7 +563,7 @@ static void wcd937x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, zdet_param_ptr = &zdet_param[3]; d1 = d1_a[3]; } - wcd937x_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1); + wcd937x_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1); left_ch_impedance: if ((z1L == WCD937X_ZDET_FLOATING_IMPEDANCE) || @@ -563,13 +573,13 @@ static void wcd937x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, d1 = d1_a[1]; } else { *zl = z1L/1000; - wcd937x_wcd_mbhc_qfuse_cal(codec, zl, 0); + wcd937x_wcd_mbhc_qfuse_cal(component, zl, 0); } - dev_dbg(codec->dev, "%s: impedance on HPH_L = %d(ohms)\n", + dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n", __func__, *zl); /* Start of right impedance ramp and calculation */ - wcd937x_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + wcd937x_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1); if (WCD937X_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) { if (((z1R > WCD937X_ZDET_VAL_1200) && (zdet_param_ptr->noff == 0x6)) || @@ -587,7 +597,8 @@ static void wcd937x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, zdet_param_ptr = &zdet_param[3]; d1 = d1_a[3]; } - wcd937x_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1); + wcd937x_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, + &z1R, d1); } right_ch_impedance: if ((z1R == WCD937X_ZDET_FLOATING_IMPEDANCE) || @@ -595,15 +606,15 @@ static void wcd937x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, *zr = WCD937X_ZDET_FLOATING_IMPEDANCE; } else { *zr = z1R/1000; - wcd937x_wcd_mbhc_qfuse_cal(codec, zr, 1); + wcd937x_wcd_mbhc_qfuse_cal(component, zr, 1); } - dev_dbg(codec->dev, "%s: impedance on HPH_R = %d(ohms)\n", + dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n", __func__, *zr); /* Mono/stereo detection */ if ((*zl == WCD937X_ZDET_FLOATING_IMPEDANCE) && (*zr == WCD937X_ZDET_FLOATING_IMPEDANCE)) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: plug type is invalid or extension cable\n", __func__); goto zdet_complete; @@ -612,40 +623,46 @@ static void wcd937x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, (*zr == WCD937X_ZDET_FLOATING_IMPEDANCE) || ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) || ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: Mono plug type with one ch floating or shorted to GND\n", __func__); mbhc->hph_type = WCD_MBHC_HPH_MONO; goto zdet_complete; } - snd_soc_update_bits(codec, WCD937X_HPH_R_ATEST, 0x02, 0x02); - snd_soc_update_bits(codec, WCD937X_HPH_PA_CTL2, 0x40, 0x01); + snd_soc_component_update_bits(component, WCD937X_HPH_R_ATEST, + 0x02, 0x02); + snd_soc_component_update_bits(component, WCD937X_HPH_PA_CTL2, + 0x40, 0x01); if (*zl < (WCD937X_ZDET_VAL_32/1000)) - wcd937x_mbhc_zdet_ramp(codec, &zdet_param[0], &z1Ls, NULL, d1); + wcd937x_mbhc_zdet_ramp(component, &zdet_param[0], &z1Ls, + NULL, d1); else - wcd937x_mbhc_zdet_ramp(codec, &zdet_param[1], &z1Ls, NULL, d1); - snd_soc_update_bits(codec, WCD937X_HPH_PA_CTL2, 0x40, 0x00); - snd_soc_update_bits(codec, WCD937X_HPH_R_ATEST, 0x02, 0x00); + wcd937x_mbhc_zdet_ramp(component, &zdet_param[1], &z1Ls, + NULL, d1); + snd_soc_component_update_bits(component, WCD937X_HPH_PA_CTL2, + 0x40, 0x00); + snd_soc_component_update_bits(component, WCD937X_HPH_R_ATEST, + 0x02, 0x00); z1Ls /= 1000; - wcd937x_wcd_mbhc_qfuse_cal(codec, &z1Ls, 0); + wcd937x_wcd_mbhc_qfuse_cal(component, &z1Ls, 0); /* Parallel of left Z and 9 ohm pull down resistor */ zMono = ((*zl) * 9) / ((*zl) + 9); z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls); z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl)); if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) { - dev_dbg(codec->dev, "%s: stereo plug type detected\n", + dev_dbg(component->dev, "%s: stereo plug type detected\n", __func__); mbhc->hph_type = WCD_MBHC_HPH_STEREO; } else { - dev_dbg(codec->dev, "%s: MONO plug type detected\n", + dev_dbg(component->dev, "%s: MONO plug type detected\n", __func__); mbhc->hph_type = WCD_MBHC_HPH_MONO; } zdet_complete: - snd_soc_write(codec, WCD937X_ANA_MBHC_BTN5, reg0); - snd_soc_write(codec, WCD937X_ANA_MBHC_BTN6, reg1); - snd_soc_write(codec, WCD937X_ANA_MBHC_BTN7, reg2); + snd_soc_component_write(component, WCD937X_ANA_MBHC_BTN5, reg0); + snd_soc_component_write(component, WCD937X_ANA_MBHC_BTN6, reg1); + snd_soc_component_write(component, WCD937X_ANA_MBHC_BTN7, reg2); /* Turn on 100k pull down on HPHL */ regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MBHC_MECH, 0x01, 0x01); @@ -655,97 +672,98 @@ static void wcd937x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MBHC_MECH, 0x80, 0x80); - snd_soc_write(codec, WCD937X_MBHC_NEW_ZDET_ANA_CTL, reg4); - snd_soc_write(codec, WCD937X_MBHC_CTL_CLK, reg3); + snd_soc_component_write(component, WCD937X_MBHC_NEW_ZDET_ANA_CTL, reg4); + snd_soc_component_write(component, WCD937X_MBHC_CTL_CLK, reg3); if (is_fsm_disable) regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MBHC_ELECT, 0x80, 0x80); } -static void wcd937x_mbhc_gnd_det_ctrl(struct snd_soc_codec *codec, bool enable) +static void wcd937x_mbhc_gnd_det_ctrl(struct snd_soc_component *component, + bool enable) { if (enable) { - snd_soc_update_bits(codec, WCD937X_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, WCD937X_ANA_MBHC_MECH, 0x02, 0x02); - snd_soc_update_bits(codec, WCD937X_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, WCD937X_ANA_MBHC_MECH, 0x40, 0x40); } else { - snd_soc_update_bits(codec, WCD937X_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, WCD937X_ANA_MBHC_MECH, 0x40, 0x00); - snd_soc_update_bits(codec, WCD937X_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, WCD937X_ANA_MBHC_MECH, 0x02, 0x00); } } -static void wcd937x_mbhc_hph_pull_down_ctrl(struct snd_soc_codec *codec, +static void wcd937x_mbhc_hph_pull_down_ctrl(struct snd_soc_component *component, bool enable) { if (enable) { - snd_soc_update_bits(codec, WCD937X_HPH_PA_CTL2, + snd_soc_component_update_bits(component, WCD937X_HPH_PA_CTL2, 0x40, 0x40); - snd_soc_update_bits(codec, WCD937X_HPH_PA_CTL2, + snd_soc_component_update_bits(component, WCD937X_HPH_PA_CTL2, 0x10, 0x10); } else { - snd_soc_update_bits(codec, WCD937X_HPH_PA_CTL2, + snd_soc_component_update_bits(component, WCD937X_HPH_PA_CTL2, 0x40, 0x00); - snd_soc_update_bits(codec, WCD937X_HPH_PA_CTL2, + snd_soc_component_update_bits(component, WCD937X_HPH_PA_CTL2, 0x10, 0x00); } } static void wcd937x_mbhc_moisture_config(struct wcd_mbhc *mbhc) { - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; if ((mbhc->moist_rref == R_OFF) || (mbhc->mbhc_cfg->enable_usbc_analog)) { - snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_2, + snd_soc_component_update_bits(component, WCD937X_MBHC_NEW_CTL_2, 0x0C, R_OFF << 2); return; } /* Do not enable moisture detection if jack type is NC */ if (!mbhc->hphl_swh) { - dev_dbg(codec->dev, "%s: disable moisture detection for NC\n", + dev_dbg(component->dev, "%s: disable moisture detection for NC\n", __func__); - snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_2, + snd_soc_component_update_bits(component, WCD937X_MBHC_NEW_CTL_2, 0x0C, R_OFF << 2); return; } - snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_2, + snd_soc_component_update_bits(component, WCD937X_MBHC_NEW_CTL_2, 0x0C, mbhc->moist_rref << 2); } static void wcd937x_mbhc_moisture_detect_en(struct wcd_mbhc *mbhc, bool enable) { - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; if (enable) - snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_2, + snd_soc_component_update_bits(component, WCD937X_MBHC_NEW_CTL_2, 0x0C, mbhc->moist_rref << 2); else - snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_2, + snd_soc_component_update_bits(component, WCD937X_MBHC_NEW_CTL_2, 0x0C, R_OFF << 2); } static bool wcd937x_mbhc_get_moisture_status(struct wcd_mbhc *mbhc) { - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; bool ret = false; if ((mbhc->moist_rref == R_OFF) || (mbhc->mbhc_cfg->enable_usbc_analog)) { - snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_2, + snd_soc_component_update_bits(component, WCD937X_MBHC_NEW_CTL_2, 0x0C, R_OFF << 2); goto done; } /* Do not enable moisture detection if jack type is NC */ if (!mbhc->hphl_swh) { - dev_dbg(codec->dev, "%s: disable moisture detection for NC\n", + dev_dbg(component->dev, "%s: disable moisture detection for NC\n", __func__); - snd_soc_update_bits(codec, WCD937X_MBHC_NEW_CTL_2, + snd_soc_component_update_bits(component, WCD937X_MBHC_NEW_CTL_2, 0x0C, R_OFF << 2); goto done; } @@ -753,12 +771,13 @@ static bool wcd937x_mbhc_get_moisture_status(struct wcd_mbhc *mbhc) /* If moisture_en is already enabled, then skip to plug type * detection. */ - if ((snd_soc_read(codec, WCD937X_MBHC_NEW_CTL_2) & 0x0C)) + if ((snd_soc_component_read32(component, WCD937X_MBHC_NEW_CTL_2) & + 0x0C)) goto done; wcd937x_mbhc_moisture_detect_en(mbhc, true); /* Read moisture comparator status */ - ret = ((snd_soc_read(codec, WCD937X_MBHC_NEW_FSM_STATUS) + ret = ((snd_soc_component_read32(component, WCD937X_MBHC_NEW_FSM_STATUS) & 0x20) ? 0 : 1); done: @@ -769,9 +788,9 @@ static bool wcd937x_mbhc_get_moisture_status(struct wcd_mbhc *mbhc) static void wcd937x_mbhc_moisture_polling_ctrl(struct wcd_mbhc *mbhc, bool enable) { - struct snd_soc_codec *codec = mbhc->codec; + struct snd_soc_component *component = mbhc->component; - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL, 0x04, (enable << 2)); } @@ -805,19 +824,22 @@ static const struct wcd_mbhc_cb mbhc_cb = { static int wcd937x_get_hph_type(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wcd937x_mbhc *wcd937x_mbhc = wcd937x_soc_get_mbhc(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd937x_mbhc *wcd937x_mbhc = wcd937x_soc_get_mbhc(component); struct wcd_mbhc *mbhc; if (!wcd937x_mbhc) { - dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + dev_err(component->dev, "%s: mbhc not initialized!\n", + __func__); return -EINVAL; } mbhc = &wcd937x_mbhc->wcd_mbhc; ucontrol->value.integer.value[0] = (u32) mbhc->hph_type; - dev_dbg(codec->dev, "%s: hph_type = %u\n", __func__, mbhc->hph_type); + dev_dbg(component->dev, "%s: hph_type = %u\n", __func__, + mbhc->hph_type); return 0; } @@ -828,18 +850,21 @@ static int wcd937x_hph_impedance_get(struct snd_kcontrol *kcontrol, uint32_t zl, zr; bool hphr; struct soc_multi_mixer_control *mc; - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wcd937x_mbhc *wcd937x_mbhc = wcd937x_soc_get_mbhc(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd937x_mbhc *wcd937x_mbhc = wcd937x_soc_get_mbhc(component); if (!wcd937x_mbhc) { - dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + dev_err(component->dev, "%s: mbhc not initialized!\n", + __func__); return -EINVAL; } mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); hphr = mc->shift; wcd_mbhc_get_impedance(&wcd937x_mbhc->wcd_mbhc, &zl, &zr); - dev_dbg(codec->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr); + dev_dbg(component->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, + zl, zr); ucontrol->value.integer.value[0] = hphr ? zr : zl; return 0; @@ -883,22 +908,22 @@ EXPORT_SYMBOL(wcd937x_mbhc_get_impedance); /* * wcd937x_mbhc_hs_detect: starts mbhc insertion/removal functionality - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * * @mbhc_cfg: handle to mbhc configuration structure * return 0 if mbhc_start is success or error code in case of failure */ -int wcd937x_mbhc_hs_detect(struct snd_soc_codec *codec, +int wcd937x_mbhc_hs_detect(struct snd_soc_component *component, struct wcd_mbhc_config *mbhc_cfg) { struct wcd937x_priv *wcd937x = NULL; struct wcd937x_mbhc *wcd937x_mbhc = NULL; - if (!codec) { - pr_err("%s: codec is NULL\n", __func__); + if (!component) { + pr_err("%s: component is NULL\n", __func__); return -EINVAL; } - wcd937x = snd_soc_codec_get_drvdata(codec); + wcd937x = snd_soc_component_get_drvdata(component); if (!wcd937x) { pr_err("%s: wcd937x is NULL\n", __func__); return -EINVAL; @@ -906,7 +931,8 @@ int wcd937x_mbhc_hs_detect(struct snd_soc_codec *codec, wcd937x_mbhc = wcd937x->mbhc; if (!wcd937x_mbhc) { - dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + dev_err(component->dev, "%s: mbhc not initialized!\n", + __func__); return -EINVAL; } @@ -916,19 +942,19 @@ EXPORT_SYMBOL(wcd937x_mbhc_hs_detect); /* * wcd937x_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * */ -void wcd937x_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +void wcd937x_mbhc_hs_detect_exit(struct snd_soc_component *component) { struct wcd937x_priv *wcd937x = NULL; struct wcd937x_mbhc *wcd937x_mbhc = NULL; - if (!codec) { - pr_err("%s: codec is NULL\n", __func__); + if (!component) { + pr_err("%s: component is NULL\n", __func__); return; } - wcd937x = snd_soc_codec_get_drvdata(codec); + wcd937x = snd_soc_component_get_drvdata(component); if (!wcd937x) { pr_err("%s: wcd937x is NULL\n", __func__); return; @@ -936,7 +962,8 @@ void wcd937x_mbhc_hs_detect_exit(struct snd_soc_codec *codec) wcd937x_mbhc = wcd937x->mbhc; if (!wcd937x_mbhc) { - dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__); + dev_err(component->dev, "%s: mbhc not initialized!\n", + __func__); return; } wcd_mbhc_stop(&wcd937x_mbhc->wcd_mbhc); @@ -947,17 +974,17 @@ EXPORT_SYMBOL(wcd937x_mbhc_hs_detect_exit); * wcd937x_mbhc_post_ssr_init: initialize mbhc for * wcd937x post subsystem restart * @mbhc: poniter to wcd937x_mbhc structure - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * * * return 0 if mbhc_init is success or error code in case of failure */ int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { int ret = 0; struct wcd_mbhc *wcd_mbhc = NULL; - if (!mbhc || !codec) + if (!mbhc || !component) return -EINVAL; wcd_mbhc = &mbhc->wcd_mbhc; @@ -966,14 +993,14 @@ int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc, return -EINVAL; } - wcd937x_mbhc_hs_detect_exit(codec); + wcd937x_mbhc_hs_detect_exit(component); wcd_mbhc_deinit(wcd_mbhc); - snd_soc_update_bits(codec, WCD937X_ANA_MBHC_MECH, + snd_soc_component_update_bits(component, WCD937X_ANA_MBHC_MECH, 0x20, 0x20); - ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids, + ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb, &intr_ids, wcd_mbhc_registers, WCD937X_ZDET_SUPPORTED); if (ret) { - dev_err(codec->dev, "%s: mbhc initialization failed\n", + dev_err(component->dev, "%s: mbhc initialization failed\n", __func__); goto done; } @@ -986,24 +1013,25 @@ EXPORT_SYMBOL(wcd937x_mbhc_post_ssr_init); /* * wcd937x_mbhc_init: initialize mbhc for wcd937x * @mbhc: poniter to wcd937x_mbhc struct pointer to store the configs - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * * @fw_data: handle to firmware data * * return 0 if mbhc_init is success or error code in case of failure */ -int wcd937x_mbhc_init(struct wcd937x_mbhc **mbhc, struct snd_soc_codec *codec, - struct fw_info *fw_data) +int wcd937x_mbhc_init(struct wcd937x_mbhc **mbhc, + struct snd_soc_component *component, + struct fw_info *fw_data) { struct wcd937x_mbhc *wcd937x_mbhc = NULL; struct wcd_mbhc *wcd_mbhc = NULL; int ret = 0; - if (!codec) { - pr_err("%s: codec is NULL\n", __func__); + if (!component) { + pr_err("%s: component is NULL\n", __func__); return -EINVAL; } - wcd937x_mbhc = devm_kzalloc(codec->dev, sizeof(struct wcd937x_mbhc), + wcd937x_mbhc = devm_kzalloc(component->dev, sizeof(struct wcd937x_mbhc), GFP_KERNEL); if (!wcd937x_mbhc) return -ENOMEM; @@ -1021,43 +1049,43 @@ int wcd937x_mbhc_init(struct wcd937x_mbhc **mbhc, struct snd_soc_codec *codec, /* Setting default mbhc detection logic to ADC */ wcd_mbhc->mbhc_detection_logic = WCD_DETECTION_ADC; - ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, + ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb, &intr_ids, wcd_mbhc_registers, WCD937X_ZDET_SUPPORTED); if (ret) { - dev_err(codec->dev, "%s: mbhc initialization failed\n", + dev_err(component->dev, "%s: mbhc initialization failed\n", __func__); goto err; } (*mbhc) = wcd937x_mbhc; - snd_soc_add_codec_controls(codec, impedance_detect_controls, + snd_soc_add_component_controls(component, impedance_detect_controls, ARRAY_SIZE(impedance_detect_controls)); - snd_soc_add_codec_controls(codec, hph_type_detect_controls, + snd_soc_add_component_controls(component, hph_type_detect_controls, ARRAY_SIZE(hph_type_detect_controls)); return 0; err: - devm_kfree(codec->dev, wcd937x_mbhc); + devm_kfree(component->dev, wcd937x_mbhc); return ret; } EXPORT_SYMBOL(wcd937x_mbhc_init); /* * wcd937x_mbhc_deinit: deinitialize mbhc for wcd937x - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * */ -void wcd937x_mbhc_deinit(struct snd_soc_codec *codec) +void wcd937x_mbhc_deinit(struct snd_soc_component *component) { struct wcd937x_priv *wcd937x; struct wcd937x_mbhc *wcd937x_mbhc; - if (!codec) { - pr_err("%s: codec is NULL\n", __func__); + if (!component) { + pr_err("%s: component is NULL\n", __func__); return; } - wcd937x = snd_soc_codec_get_drvdata(codec); + wcd937x = snd_soc_component_get_drvdata(component); if (!wcd937x) { pr_err("%s: wcd937x is NULL\n", __func__); return; @@ -1066,7 +1094,7 @@ void wcd937x_mbhc_deinit(struct snd_soc_codec *codec) wcd937x_mbhc = wcd937x->mbhc; if (wcd937x_mbhc) { wcd_mbhc_deinit(&wcd937x_mbhc->wcd_mbhc); - devm_kfree(codec->dev, wcd937x_mbhc); + devm_kfree(component->dev, wcd937x_mbhc); } } EXPORT_SYMBOL(wcd937x_mbhc_deinit); diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.h b/asoc/codecs/wcd937x/wcd937x-mbhc.h index c0689e4bf0c7..d7bfb16954a7 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.h +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.h @@ -13,36 +13,37 @@ struct wcd937x_mbhc { #if IS_ENABLED(CONFIG_SND_SOC_WCD937X) extern int wcd937x_mbhc_init(struct wcd937x_mbhc **mbhc, - struct snd_soc_codec *codec, + struct snd_soc_component *component, struct fw_info *fw_data); -extern void wcd937x_mbhc_hs_detect_exit(struct snd_soc_codec *codec); -extern int wcd937x_mbhc_hs_detect(struct snd_soc_codec *codec, +extern void wcd937x_mbhc_hs_detect_exit(struct snd_soc_component *component); +extern int wcd937x_mbhc_hs_detect(struct snd_soc_component *component, struct wcd_mbhc_config *mbhc_cfg); -extern void wcd937x_mbhc_deinit(struct snd_soc_codec *codec); +extern void wcd937x_mbhc_deinit(struct snd_soc_component *component); extern int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc, - struct snd_soc_codec *codec); + struct snd_soc_component *component); extern int wcd937x_mbhc_get_impedance(struct wcd937x_mbhc *wcd937x_mbhc, uint32_t *zl, uint32_t *zr); #else static inline int wcd937x_mbhc_init(struct wcd937x_mbhc **mbhc, - struct snd_soc_codec *codec, + struct snd_soc_component *component, struct fw_info *fw_data) { return 0; } -static inline void wcd937x_mbhc_hs_detect_exit(struct snd_soc_codec *codec) +static inline void wcd937x_mbhc_hs_detect_exit( + struct snd_soc_component *component) { } -static inline int wcd937x_mbhc_hs_detect(struct snd_soc_codec *codec, +static inline int wcd937x_mbhc_hs_detect(struct snd_soc_component *component, struct wcd_mbhc_config *mbhc_cfg) { return 0; } -static inline void wcd937x_mbhc_deinit(struct snd_soc_codec *codec) +static inline void wcd937x_mbhc_deinit(struct snd_soc_component *component) { } static inline int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { return 0; } diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index ea0e2ee9e64b..fbd553a841a4 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -25,6 +25,8 @@ #include #include "../msm-cdc-supply.h" +#define DRV_NAME "wcd937x_codec" + #define WCD9370_VARIANT 0 #define WCD9375_VARIANT 5 @@ -83,7 +85,6 @@ static struct regmap_irq_chip wcd937x_regmap_irq_chip = { .mask_base = WCD937X_DIGITAL_INTR_MASK_0, .ack_base = WCD937X_DIGITAL_INTR_CLEAR_0, .use_ack = 1, - .clear_ack = 1, .type_base = WCD937X_DIGITAL_INTR_LEVEL_0, .runtime_pm = false, .handle_post_irq = wcd937x_handle_post_irq, @@ -104,35 +105,48 @@ static int wcd937x_handle_post_irq(void *data) return IRQ_HANDLED; } -static int wcd937x_init_reg(struct snd_soc_codec *codec) +static int wcd937x_init_reg(struct snd_soc_component *component) { - snd_soc_update_bits(codec, WCD937X_SLEEP_CTL, 0x0E, 0x0E); - snd_soc_update_bits(codec, WCD937X_SLEEP_CTL, 0x80, 0x80); + snd_soc_component_update_bits(component, WCD937X_SLEEP_CTL, + 0x0E, 0x0E); + snd_soc_component_update_bits(component, WCD937X_SLEEP_CTL, + 0x80, 0x80); usleep_range(1000, 1010); - snd_soc_update_bits(codec, WCD937X_SLEEP_CTL, 0x40, 0x40); + snd_soc_component_update_bits(component, WCD937X_SLEEP_CTL, + 0x40, 0x40); usleep_range(1000, 1010); - snd_soc_update_bits(codec, WCD937X_LDORXTX_CONFIG, 0x10, 0x00); - snd_soc_update_bits(codec, WCD937X_BIAS_VBG_FINE_ADJ, 0xF0, 0x80); - snd_soc_update_bits(codec, WCD937X_ANA_BIAS, 0x80, 0x80); - snd_soc_update_bits(codec, WCD937X_ANA_BIAS, 0x40, 0x40); + snd_soc_component_update_bits(component, WCD937X_LDORXTX_CONFIG, + 0x10, 0x00); + snd_soc_component_update_bits(component, WCD937X_BIAS_VBG_FINE_ADJ, + 0xF0, 0x80); + snd_soc_component_update_bits(component, WCD937X_ANA_BIAS, + 0x80, 0x80); + snd_soc_component_update_bits(component, WCD937X_ANA_BIAS, + 0x40, 0x40); usleep_range(10000, 10010); - snd_soc_update_bits(codec, WCD937X_ANA_BIAS, 0x40, 0x00); - snd_soc_update_bits(codec, WCD937X_HPH_OCP_CTL, 0xFF, 0x3A); - snd_soc_update_bits(codec, WCD937X_RX_OCP_CTL, 0x0F, 0x02); - snd_soc_update_bits(codec, WCD937X_HPH_R_TEST, 0x01, 0x01); - snd_soc_update_bits(codec, WCD937X_HPH_L_TEST, 0x01, 0x01); + snd_soc_component_update_bits(component, WCD937X_ANA_BIAS, + 0x40, 0x00); + snd_soc_component_update_bits(component, WCD937X_HPH_OCP_CTL, + 0xFF, 0x3A); + snd_soc_component_update_bits(component, WCD937X_RX_OCP_CTL, + 0x0F, 0x02); + snd_soc_component_update_bits(component, WCD937X_HPH_R_TEST, + 0x01, 0x01); + snd_soc_component_update_bits(component, WCD937X_HPH_L_TEST, + 0x01, 0x01); return 0; } -static int wcd937x_set_port_params(struct snd_soc_codec *codec, u8 slv_prt_type, - u8 *port_id, u8 *num_ch, u8 *ch_mask, u32 *ch_rate, - u8 *port_type, u8 path) +static int wcd937x_set_port_params(struct snd_soc_component *component, + u8 slv_prt_type, u8 *port_id, u8 *num_ch, + u8 *ch_mask, u32 *ch_rate, + u8 *port_type, u8 path) { int i, j; u8 num_ports = 0; struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT] = NULL; - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); switch (path) { case CODEC_RX: @@ -153,7 +167,7 @@ static int wcd937x_set_port_params(struct snd_soc_codec *codec, u8 slv_prt_type, } found: if (i > num_ports || j == MAX_CH_PER_PORT) { - dev_err(codec->dev, "%s Failed to find slave port for type %u\n", + dev_err(component->dev, "%s Failed to find slave port for type %u\n", __func__, slv_prt_type); return -EINVAL; } @@ -240,10 +254,10 @@ static int wcd937x_parse_port_mapping(struct device *dev, return ret; } -static int wcd937x_tx_connect_port(struct snd_soc_codec *codec, +static int wcd937x_tx_connect_port(struct snd_soc_component *component, u8 slv_port_type, u8 enable) { - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); u8 port_id; u8 num_ch; u8 ch_mask; @@ -252,7 +266,7 @@ static int wcd937x_tx_connect_port(struct snd_soc_codec *codec, u8 num_port = 1; int ret = 0; - ret = wcd937x_set_port_params(codec, slv_port_type, &port_id, + ret = wcd937x_set_port_params(component, slv_port_type, &port_id, &num_ch, &ch_mask, &ch_rate, &port_type, CODEC_TX); @@ -269,10 +283,10 @@ static int wcd937x_tx_connect_port(struct snd_soc_codec *codec, return ret; } -static int wcd937x_rx_connect_port(struct snd_soc_codec *codec, +static int wcd937x_rx_connect_port(struct snd_soc_component *component, u8 slv_port_type, u8 enable) { - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); u8 port_id; u8 num_ch; u8 ch_mask; @@ -281,7 +295,7 @@ static int wcd937x_rx_connect_port(struct snd_soc_codec *codec, u8 num_port = 1; int ret = 0; - ret = wcd937x_set_port_params(codec, slv_port_type, &port_id, + ret = wcd937x_set_port_params(component, slv_port_type, &port_id, &num_ch, &ch_mask, &ch_rate, &port_type, CODEC_RX); @@ -298,33 +312,34 @@ static int wcd937x_rx_connect_port(struct snd_soc_codec *codec, return ret; } -static int wcd937x_rx_clk_enable(struct snd_soc_codec *codec) +static int wcd937x_rx_clk_enable(struct snd_soc_component *component) { - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); if (wcd937x->rx_clk_cnt == 0) { - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, - 0x08, 0x08); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, - 0x01, 0x01); - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x01, 0x01); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_RX0_CTL, - 0x40, 0x00); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_RX1_CTL, - 0x40, 0x00); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_RX2_CTL, - 0x40, 0x00); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, - 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x08, 0x08); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD937X_ANA_RX_SUPPLIES, 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_RX0_CTL, 0x40, 0x00); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_RX1_CTL, 0x40, 0x00); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_RX2_CTL, 0x40, 0x00); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x02); } wcd937x->rx_clk_cnt++; return 0; } -static int wcd937x_rx_clk_disable(struct snd_soc_codec *codec) +static int wcd937x_rx_clk_disable(struct snd_soc_component *component) { - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); if (wcd937x->rx_clk_cnt == 0) { dev_dbg(wcd937x->dev, "%s:clk already disabled\n", __func__); @@ -332,30 +347,33 @@ static int wcd937x_rx_clk_disable(struct snd_soc_codec *codec) } wcd937x->rx_clk_cnt--; if (wcd937x->rx_clk_cnt == 0) { - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, 0x01, 0x00); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, - 0x02, 0x00); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, - 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD937X_ANA_RX_SUPPLIES, 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_ANA_CLK_CTL, + 0x02, 0x00); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_ANA_CLK_CTL, + 0x01, 0x00); } return 0; } /* - * wcd937x_soc_get_mbhc: get wcd937x_mbhc handle of corresponding codec - * @codec: handle to snd_soc_codec * + * wcd937x_soc_get_mbhc: get wcd937x_mbhc handle of corresponding component + * @component: handle to snd_soc_component * * * return wcd937x_mbhc handle or error code in case of failure */ -struct wcd937x_mbhc *wcd937x_soc_get_mbhc(struct snd_soc_codec *codec) +struct wcd937x_mbhc *wcd937x_soc_get_mbhc(struct snd_soc_component *component) { struct wcd937x_priv *wcd937x; - if (!codec) { - pr_err("%s: Invalid params, NULL codec\n", __func__); + if (!component) { + pr_err("%s: Invalid params, NULL component\n", __func__); return NULL; } - wcd937x = snd_soc_codec_get_drvdata(codec); + wcd937x = snd_soc_component_get_drvdata(component); if (!wcd937x) { pr_err("%s: Invalid params, NULL tavil\n", __func__); @@ -370,44 +388,48 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); int hph_mode = wcd937x->hph_mode; - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - wcd937x_rx_clk_enable(codec); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, - 0x01, 0x01); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_HPH_GAIN_CTL, - 0x04, 0x04); - snd_soc_update_bits(codec, WCD937X_HPH_RDAC_CLK_CTL1, - 0x80, 0x00); + wcd937x_rx_clk_enable(component); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_HPH_GAIN_CTL, + 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD937X_HPH_RDAC_CLK_CTL1, + 0x80, 0x00); set_bit(HPH_COMP_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x02); else if (hph_mode == CLS_H_LOHIFI) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x06); if (wcd937x->comp1_enable) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x02); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_HPH_L_EN, 0x20, 0x00); if (wcd937x->comp2_enable) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_COMP_CTL_0, 0x01, 0x01); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_HPH_R_EN, 0x20, 0x00); } /* @@ -420,17 +442,17 @@ static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, &wcd937x->status_mask); } } else { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_HPH_L_EN, 0x20, 0x20); } - snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, - 0x02, 0x00); + snd_soc_component_update_bits(component, + WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x01); break; @@ -443,44 +465,45 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); int hph_mode = wcd937x->hph_mode; - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - wcd937x_rx_clk_enable(codec); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, - 0x02, 0x02); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_HPH_GAIN_CTL, - 0x08, 0x08); - snd_soc_update_bits(codec, WCD937X_HPH_RDAC_CLK_CTL1, - 0x80, 0x00); + wcd937x_rx_clk_enable(component); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_HPH_GAIN_CTL, 0x08, 0x08); + snd_soc_component_update_bits(component, + WCD937X_HPH_RDAC_CLK_CTL1, 0x80, 0x00); set_bit(HPH_COMP_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMU: if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x0F, 0x02); else if (hph_mode == CLS_H_LOHIFI) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x0F, 0x06); if (wcd937x->comp2_enable) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_COMP_CTL_0, 0x01, 0x01); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_HPH_R_EN, 0x20, 0x00); if (wcd937x->comp1_enable) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x02); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_HPH_L_EN, 0x20, 0x00); } /* @@ -493,17 +516,17 @@ static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, &wcd937x->status_mask); } } else { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_COMP_CTL_0, 0x01, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_HPH_R_EN, 0x20, 0x20); } - snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, - 0x02, 0x00); + snd_soc_component_update_bits(component, + WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x0F, 0x01); break; @@ -516,32 +539,36 @@ static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); int hph_mode = wcd937x->hph_mode; - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - wcd937x_rx_clk_enable(codec); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_HPH_GAIN_CTL, - 0x04, 0x04); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, - 0x01, 0x01); + wcd937x_rx_clk_enable(component); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_HPH_GAIN_CTL, + 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x01, 0x01); if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x02); else if (hph_mode == CLS_H_LOHIFI) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x06); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_COMP_CTL_0, - 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_COMP_CTL_0, + 0x02, 0x02); usleep_range(5000, 5010); - wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + wcd_cls_h_fsm(component, &wcd937x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_EAR, hph_mode); @@ -550,7 +577,7 @@ static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMD: if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_LOHIFI || hph_mode == CLS_H_HIFI) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x01); break; @@ -563,32 +590,37 @@ static int wcd937x_codec_aux_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); int hph_mode = wcd937x->hph_mode; - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - wcd937x_rx_clk_enable(codec); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, - 0x04, 0x04); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, - 0x04, 0x04); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_AUX_GAIN_CTL, - 0x01, 0x01); - wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + wcd937x_rx_clk_enable(component); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_ANA_CLK_CTL, + 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_AUX_GAIN_CTL, + 0x01, 0x01); + wcd_cls_h_fsm(component, &wcd937x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_AUX, hph_mode); break; case SND_SOC_DAPM_POST_PMD: - wcd937x_rx_clk_disable(codec); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, - 0x04, 0x00); + wcd937x_rx_clk_disable(component); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_ANA_CLK_CTL, + 0x04, 0x00); break; }; return 0; @@ -599,12 +631,13 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); int ret = 0; int hph_mode = wcd937x->hph_mode; - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { @@ -612,11 +645,12 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, true); - wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + wcd_cls_h_fsm(component, &wcd937x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_HPHR, hph_mode); - snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x10, 0x10); + snd_soc_component_update_bits(component, WCD937X_ANA_HPH, + 0x10, 0x10); usleep_range(100, 110); set_bit(HPH_PA_DELAY, &wcd937x->status_mask); break; @@ -634,11 +668,13 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, clear_bit(HPH_PA_DELAY, &wcd937x->status_mask); } - snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, - 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD937X_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x02); if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, - 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD937X_ANA_RX_SUPPLIES, + 0x02, 0x02); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -658,8 +694,9 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, blocking_notifier_call_chain(&wcd937x->mbhc->notifier, WCD_EVENT_POST_HPHR_PA_OFF, &wcd937x->mbhc->wcd_mbhc); - snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x10, 0x00); - wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + snd_soc_component_update_bits(component, WCD937X_ANA_HPH, + 0x10, 0x00); + wcd_cls_h_fsm(component, &wcd937x->clsh_info, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_HPHR, hph_mode); @@ -672,12 +709,13 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); int ret = 0; int hph_mode = wcd937x->hph_mode; - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { @@ -685,11 +723,12 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, true); - wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + wcd_cls_h_fsm(component, &wcd937x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_HPHL, hph_mode); - snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x20, 0x20); + snd_soc_component_update_bits(component, WCD937X_ANA_HPH, + 0x20, 0x20); usleep_range(100, 110); set_bit(HPH_PA_DELAY, &wcd937x->status_mask); break; @@ -707,11 +746,13 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, clear_bit(HPH_PA_DELAY, &wcd937x->status_mask); } - snd_soc_update_bits(codec, WCD937X_HPH_NEW_INT_HPH_TIMER1, - 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD937X_HPH_NEW_INT_HPH_TIMER1, + 0x02, 0x02); if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, - 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD937X_ANA_RX_SUPPLIES, + 0x02, 0x02); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -731,8 +772,9 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, blocking_notifier_call_chain(&wcd937x->mbhc->notifier, WCD_EVENT_POST_HPHL_PA_OFF, &wcd937x->mbhc->wcd_mbhc); - snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0x20, 0x00); - wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + snd_soc_component_update_bits(component, WCD937X_ANA_HPH, + 0x20, 0x00); + wcd_cls_h_fsm(component, &wcd937x->clsh_info, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_HPHL, hph_mode); @@ -745,12 +787,13 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); int hph_mode = wcd937x->hph_mode; int ret = 0; - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { @@ -762,8 +805,9 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: usleep_range(1000, 1010); if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, - 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD937X_ANA_RX_SUPPLIES, + 0x02, 0x02); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -778,7 +822,7 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMD: usleep_range(1000, 1010); usleep_range(1000, 1010); - wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + wcd_cls_h_fsm(component, &wcd937x->clsh_info, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_AUX, hph_mode); @@ -791,12 +835,13 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); int hph_mode = wcd937x->hph_mode; int ret = 0; - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { @@ -808,8 +853,9 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: usleep_range(6000, 6010); if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) - snd_soc_update_bits(codec, WCD937X_ANA_RX_SUPPLIES, - 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD937X_ANA_RX_SUPPLIES, + 0x02, 0x02); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -823,7 +869,7 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: usleep_range(7000, 7010); - wcd_cls_h_fsm(codec, &wcd937x->clsh_info, + wcd_cls_h_fsm(component, &wcd937x->clsh_info, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_EAR, hph_mode); @@ -836,17 +882,18 @@ static int wcd937x_enable_clsh(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); int mode = wcd937x->hph_mode; int ret = 0; - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); if (mode == CLS_H_LOHIFI || mode == CLS_H_ULP || mode == CLS_H_HIFI || mode == CLS_H_LP) { - wcd937x_rx_connect_port(codec, CLSH, + wcd937x_rx_connect_port(component, CLSH, SND_SOC_DAPM_EVENT_ON(event)); } if (SND_SOC_DAPM_EVENT_OFF(event)) @@ -861,25 +908,27 @@ static int wcd937x_enable_rx1(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - wcd937x_rx_connect_port(codec, HPH_L, true); + wcd937x_rx_connect_port(component, HPH_L, true); if (wcd937x->comp1_enable) - wcd937x_rx_connect_port(codec, COMP_L, true); + wcd937x_rx_connect_port(component, COMP_L, true); break; case SND_SOC_DAPM_POST_PMD: - wcd937x_rx_connect_port(codec, HPH_L, false); + wcd937x_rx_connect_port(component, HPH_L, false); if (wcd937x->comp1_enable) - wcd937x_rx_connect_port(codec, COMP_L, false); - wcd937x_rx_clk_disable(codec); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, - 0x01, 0x00); + wcd937x_rx_connect_port(component, COMP_L, false); + wcd937x_rx_clk_disable(component); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x01, 0x00); break; }; return 0; @@ -888,25 +937,27 @@ static int wcd937x_enable_rx1(struct snd_soc_dapm_widget *w, static int wcd937x_enable_rx2(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - wcd937x_rx_connect_port(codec, HPH_R, true); + wcd937x_rx_connect_port(component, HPH_R, true); if (wcd937x->comp2_enable) - wcd937x_rx_connect_port(codec, COMP_R, true); + wcd937x_rx_connect_port(component, COMP_R, true); break; case SND_SOC_DAPM_POST_PMD: - wcd937x_rx_connect_port(codec, HPH_R, false); + wcd937x_rx_connect_port(component, HPH_R, false); if (wcd937x->comp2_enable) - wcd937x_rx_connect_port(codec, COMP_R, false); - wcd937x_rx_clk_disable(codec); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, - 0x02, 0x00); + wcd937x_rx_connect_port(component, COMP_R, false); + wcd937x_rx_clk_disable(component); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, + 0x02, 0x00); break; }; @@ -917,22 +968,22 @@ static int wcd937x_enable_rx3(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - wcd937x_rx_connect_port(codec, LO, true); + wcd937x_rx_connect_port(component, LO, true); break; case SND_SOC_DAPM_POST_PMD: - wcd937x_rx_connect_port(codec, LO, false); + wcd937x_rx_connect_port(component, LO, false); usleep_range(6000, 6010); - wcd937x_rx_clk_disable(codec); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, - 0x04, 0x00); + wcd937x_rx_clk_disable(component); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x04, 0x00); break; } return 0; @@ -943,8 +994,9 @@ static int wcd937x_codec_enable_dmic(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); u16 dmic_clk_reg; s32 *dmic_clk_cnt; unsigned int dmic; @@ -954,18 +1006,18 @@ static int wcd937x_codec_enable_dmic(struct snd_soc_dapm_widget *w, wname = strpbrk(w->name, "012345"); if (!wname) { - dev_err(codec->dev, "%s: widget not found\n", __func__); + dev_err(component->dev, "%s: widget not found\n", __func__); return -EINVAL; } ret = kstrtouint(wname, 10, &dmic); if (ret < 0) { - dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n", + dev_err(component->dev, "%s: Invalid DMIC line on the codec\n", __func__); return -EINVAL; } - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (dmic) { @@ -985,24 +1037,27 @@ static int wcd937x_codec_enable_dmic(struct snd_soc_dapm_widget *w, dmic_clk_reg = WCD937X_DIGITAL_CDC_DMIC2_CTL; break; default: - dev_err(codec->dev, "%s: Invalid DMIC Selection\n", + dev_err(component->dev, "%s: Invalid DMIC Selection\n", __func__); return -EINVAL; }; - dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", + dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", __func__, event, dmic, *dmic_clk_cnt); switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, - 0x80, 0x80); - snd_soc_update_bits(codec, dmic_clk_reg, 0x07, 0x02); - snd_soc_update_bits(codec, dmic_clk_reg, 0x08, 0x08); - snd_soc_update_bits(codec, dmic_clk_reg, 0x70, 0x20); - wcd937x_tx_connect_port(codec, DMIC0 + (w->shift), true); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x80); + snd_soc_component_update_bits(component, + dmic_clk_reg, 0x07, 0x02); + snd_soc_component_update_bits(component, + dmic_clk_reg, 0x08, 0x08); + snd_soc_component_update_bits(component, + dmic_clk_reg, 0x70, 0x20); + wcd937x_tx_connect_port(component, DMIC0 + (w->shift), true); break; case SND_SOC_DAPM_POST_PMD: - wcd937x_tx_connect_port(codec, DMIC0 + (w->shift), false); + wcd937x_tx_connect_port(component, DMIC0 + (w->shift), false); break; }; @@ -1029,16 +1084,17 @@ EXPORT_SYMBOL(wcd937x_get_micb_vout_ctl_val); /* * wcd937x_mbhc_micb_adjust_voltage: adjust specific micbias voltage - * @codec: handle to snd_soc_codec * + * @component: handle to snd_soc_component * * @req_volt: micbias voltage to be set * @micb_num: micbias to be set, e.g. micbias1 or micbias2 * * return 0 if adjustment is success or error code in case of failure */ -int wcd937x_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, +int wcd937x_mbhc_micb_adjust_voltage(struct snd_soc_component *component, int req_volt, int micb_num) { - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct wcd937x_priv *wcd937x = + snd_soc_component_get_drvdata(component); int cur_vout_ctl, req_vout_ctl; int micb_reg, micb_val, micb_en; int ret = 0; @@ -1066,7 +1122,7 @@ int wcd937x_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, * momentarily, change the micbias value and then re-enable * micbias. */ - micb_val = snd_soc_read(codec, micb_reg); + micb_val = snd_soc_component_read32(component, micb_reg); micb_en = (micb_val & 0xC0) >> 6; cur_vout_ctl = micb_val & 0x3F; @@ -1080,17 +1136,17 @@ int wcd937x_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec, goto exit; } - dev_dbg(codec->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n", + dev_dbg(component->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n", __func__, micb_num, WCD_VOUT_CTL_TO_MICB(cur_vout_ctl), req_volt, micb_en); if (micb_en == 0x1) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + snd_soc_component_update_bits(component, micb_reg, 0xC0, 0x80); - snd_soc_update_bits(codec, micb_reg, 0x3F, req_vout_ctl); + snd_soc_component_update_bits(component, micb_reg, 0x3F, req_vout_ctl); if (micb_en == 0x1) { - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); + snd_soc_component_update_bits(component, micb_reg, 0xC0, 0x40); /* * Add 2ms delay as per HW requirement after enabling * micbias @@ -1107,8 +1163,9 @@ static int wcd937x_tx_swr_ctrl(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); int ret = 0; switch (event) { @@ -1131,25 +1188,26 @@ static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event){ - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, - 0x80, 0x80); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, - 0x08, 0x08); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, - 0x10, 0x10); - wcd937x_tx_connect_port(codec, ADC1 + (w->shift), true); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x80); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x08); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); + wcd937x_tx_connect_port(component, ADC1 + (w->shift), true); break; case SND_SOC_DAPM_POST_PMD: - wcd937x_tx_connect_port(codec, ADC1 + (w->shift), false); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, - 0x08, 0x00); + wcd937x_tx_connect_port(component, ADC1 + (w->shift), false); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00); break; }; @@ -1159,43 +1217,50 @@ static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w, static int wcd937x_enable_req(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_REQ_CTL, - 0x02, 0x02); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_REQ_CTL, 0x01, - 0x00); - snd_soc_update_bits(codec, WCD937X_ANA_TX_CH2, 0x40, 0x40); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, - 0x30, 0x30); - snd_soc_update_bits(codec, WCD937X_ANA_TX_CH1, 0x80, 0x80); - snd_soc_update_bits(codec, WCD937X_ANA_TX_CH2, 0x40, 0x00); - snd_soc_update_bits(codec, WCD937X_ANA_TX_CH2, 0x80, 0x80); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_REQ_CTL, 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_REQ_CTL, 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD937X_ANA_TX_CH2, 0x40, 0x40); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x30, 0x30); + snd_soc_component_update_bits(component, + WCD937X_ANA_TX_CH1, 0x80, 0x80); + snd_soc_component_update_bits(component, + WCD937X_ANA_TX_CH2, 0x40, 0x00); + snd_soc_component_update_bits(component, + WCD937X_ANA_TX_CH2, 0x80, 0x80); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, WCD937X_ANA_TX_CH1, 0x80, 0x00); - snd_soc_update_bits(codec, WCD937X_ANA_TX_CH2, 0x80, 0x00); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, - 0x10, 0x00); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, - 0x10, 0x00); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, - 0x80, 0x00); + snd_soc_component_update_bits(component, + WCD937X_ANA_TX_CH1, 0x80, 0x00); + snd_soc_component_update_bits(component, + WCD937X_ANA_TX_CH2, 0x80, 0x00); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x00); break; }; return 0; } -int wcd937x_micbias_control(struct snd_soc_codec *codec, +int wcd937x_micbias_control(struct snd_soc_component *component, int micb_num, int req, bool is_dapm) { - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); int micb_index = micb_num - 1; u16 micb_reg; int pre_off_event = 0, post_off_event = 0; @@ -1203,7 +1268,7 @@ int wcd937x_micbias_control(struct snd_soc_codec *codec, int post_dapm_on = 0; if ((micb_index < 0) || (micb_index > WCD937X_MAX_MICBIAS - 1)) { - dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n", + dev_err(component->dev, "%s: Invalid micbias index, micb_ind:%d\n", __func__, micb_index); return -EINVAL; } @@ -1223,7 +1288,7 @@ int wcd937x_micbias_control(struct snd_soc_codec *codec, micb_reg = WCD937X_ANA_MICB3; break; default: - dev_err(codec->dev, "%s: Invalid micbias number: %d\n", + dev_err(component->dev, "%s: Invalid micbias number: %d\n", __func__, micb_num); return -EINVAL; }; @@ -1234,25 +1299,33 @@ int wcd937x_micbias_control(struct snd_soc_codec *codec, wcd937x->pullup_ref[micb_index]++; if ((wcd937x->pullup_ref[micb_index] == 1) && (wcd937x->micb_ref[micb_index] == 0)) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x80); break; case MICB_PULLUP_DISABLE: if (wcd937x->pullup_ref[micb_index] > 0) wcd937x->pullup_ref[micb_index]--; if ((wcd937x->pullup_ref[micb_index] == 0) && (wcd937x->micb_ref[micb_index] == 0)) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x00); break; case MICB_ENABLE: wcd937x->micb_ref[micb_index]++; if (wcd937x->micb_ref[micb_index] == 1) { - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0xE0, 0xE0); - snd_soc_update_bits(codec, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); - snd_soc_update_bits(codec, WCD937X_MICB1_TEST_CTL_2, 0x01, 0x01); - snd_soc_update_bits(codec, WCD937X_MICB2_TEST_CTL_2, 0x01, 0x01); - snd_soc_update_bits(codec, WCD937X_MICB3_TEST_CTL_2, 0x01, 0x01); - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); - if (post_on_event && wcd937x->mbhc) + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0xE0, 0xE0); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); + snd_soc_component_update_bits(component, + WCD937X_MICB1_TEST_CTL_2, 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD937X_MICB2_TEST_CTL_2, 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD937X_MICB3_TEST_CTL_2, 0x01, 0x01); + snd_soc_component_update_bits(component, + micb_reg, 0xC0, 0x40); + if (post_on_event) blocking_notifier_call_chain( &wcd937x->mbhc->notifier, post_on_event, &wcd937x->mbhc->wcd_mbhc); @@ -1267,14 +1340,16 @@ int wcd937x_micbias_control(struct snd_soc_codec *codec, wcd937x->micb_ref[micb_index]--; if ((wcd937x->micb_ref[micb_index] == 0) && (wcd937x->pullup_ref[micb_index] > 0)) - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x80); else if ((wcd937x->micb_ref[micb_index] == 0) && (wcd937x->pullup_ref[micb_index] == 0)) { if (pre_off_event && wcd937x->mbhc) blocking_notifier_call_chain( &wcd937x->mbhc->notifier, pre_off_event, &wcd937x->mbhc->wcd_mbhc); - snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x00); if (post_off_event && wcd937x->mbhc) blocking_notifier_call_chain( &wcd937x->mbhc->notifier, @@ -1288,7 +1363,7 @@ int wcd937x_micbias_control(struct snd_soc_codec *codec, break; }; - dev_dbg(codec->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", + dev_dbg(component->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", __func__, micb_num, wcd937x->micb_ref[micb_index], wcd937x->pullup_ref[micb_index]); mutex_unlock(&wcd937x->micb_lock); @@ -1323,7 +1398,7 @@ static int wcd937x_event_notify(struct notifier_block *block, u16 mask = 0x40, reg = 0x0; int ret = 0; struct wcd937x_priv *wcd937x = dev_get_drvdata((struct device *)data); - struct snd_soc_codec *codec = wcd937x->codec; + struct snd_soc_component *component = wcd937x->component; struct wcd_mbhc *mbhc; switch (event) { @@ -1336,12 +1411,15 @@ static int wcd937x_event_notify(struct notifier_block *block, return 0; if (amic == 0x2) mask = 0x20; - snd_soc_update_bits(codec, reg, mask, 0x00); + snd_soc_component_update_bits(component, reg, mask, 0x00); break; case BOLERO_WCD_EVT_PA_OFF_PRE_SSR: - snd_soc_update_bits(codec, WCD937X_ANA_HPH, 0xC0, 0x00); - snd_soc_update_bits(codec, WCD937X_ANA_EAR, 0x80, 0x00); - snd_soc_update_bits(codec, WCD937X_AUX_AUXPA, 0x80, 0x00); + snd_soc_component_update_bits(component, WCD937X_ANA_HPH, + 0xC0, 0x00); + snd_soc_component_update_bits(component, WCD937X_ANA_EAR, + 0x80, 0x00); + snd_soc_component_update_bits(component, WCD937X_AUX_AUXPA, + 0x80, 0x00); break; case BOLERO_WCD_EVT_SSR_DOWN: wcd937x_reset_low(wcd937x->dev); @@ -1354,16 +1432,17 @@ static int wcd937x_event_notify(struct notifier_block *block, regcache_sync(wcd937x->regmap); /* Initialize MBHC module */ mbhc = &wcd937x->mbhc->wcd_mbhc; - ret = wcd937x_mbhc_post_ssr_init(wcd937x->mbhc, codec); + ret = wcd937x_mbhc_post_ssr_init(wcd937x->mbhc, component); if (ret) { - dev_err(codec->dev, "%s: mbhc initialization failed\n", + dev_err(component->dev, "%s: mbhc initialization failed\n", __func__); } else { - wcd937x_mbhc_hs_detect(codec, mbhc->mbhc_cfg); + wcd937x_mbhc_hs_detect(component, mbhc->mbhc_cfg); } break; default: - dev_err(codec->dev, "%s: invalid event %d\n", __func__, event); + dev_err(component->dev, "%s: invalid event %d\n", __func__, + event); break; } return 0; @@ -1372,10 +1451,11 @@ static int wcd937x_event_notify(struct notifier_block *block, static int __wcd937x_codec_enable_micbias(struct snd_soc_dapm_widget *w, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); int micb_num; - dev_dbg(codec->dev, "%s: wname: %s, event: %d\n", + dev_dbg(component->dev, "%s: wname: %s, event: %d\n", __func__, w->name, event); if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) @@ -1389,13 +1469,15 @@ static int __wcd937x_codec_enable_micbias(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - wcd937x_micbias_control(codec, micb_num, MICB_ENABLE, true); + wcd937x_micbias_control(component, micb_num, + MICB_ENABLE, true); break; case SND_SOC_DAPM_POST_PMU: usleep_range(1000, 1100); break; case SND_SOC_DAPM_POST_PMD: - wcd937x_micbias_control(codec, micb_num, MICB_DISABLE, true); + wcd937x_micbias_control(component, micb_num, + MICB_DISABLE, true); break; }; @@ -1413,8 +1495,9 @@ static int wcd937x_codec_enable_micbias(struct snd_soc_dapm_widget *w, static int wcd937x_rx_hph_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = wcd937x->hph_mode; return 0; @@ -1423,16 +1506,17 @@ static int wcd937x_rx_hph_mode_get(struct snd_kcontrol *kcontrol, static int wcd937x_rx_hph_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); u32 mode_val; mode_val = ucontrol->value.enumerated.item[0]; - dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val); + dev_dbg(component->dev, "%s: mode: %d\n", __func__, mode_val); if (mode_val == 0) { - dev_warn(codec->dev, "%s:Invalid HPH Mode, default to class_AB\n", + dev_warn(component->dev, "%s:Invalid HPH Mode, default to class_AB\n", __func__); mode_val = 3; /* enum will be updated later */ } @@ -1444,8 +1528,9 @@ static int wcd937x_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); bool hphr; struct soc_multi_mixer_control *mc; @@ -1460,8 +1545,9 @@ static int wcd937x_get_compander(struct snd_kcontrol *kcontrol, static int wcd937x_set_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); int value = ucontrol->value.integer.value[0]; bool hphr; struct soc_multi_mixer_control *mc; @@ -1480,25 +1566,26 @@ static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); struct wcd937x_pdata *pdata = NULL; int ret = 0; pdata = dev_get_platdata(wcd937x->dev); if (!pdata) { - dev_err(codec->dev, "%s: pdata is NULL\n", __func__); + dev_err(component->dev, "%s: pdata is NULL\n", __func__); return -EINVAL; } - dev_dbg(codec->dev, "%s wname: %s event: %d\n", __func__, + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: if (test_bit(ALLOW_BUCK_DISABLE, &wcd937x->status_mask)) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: buck already in enabled state\n", __func__); return 0; @@ -1509,7 +1596,7 @@ static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, pdata->num_supplies, "cdc-vdd-buck"); if (ret == -EINVAL) { - dev_err(codec->dev, "%s: vdd buck is not enabled\n", + dev_err(component->dev, "%s: vdd buck is not enabled\n", __func__); return ret; } @@ -1546,9 +1633,12 @@ static const struct snd_kcontrol_new wcd937x_snd_controls[] = { SOC_SINGLE_TLV("HPHL Volume", WCD937X_HPH_L_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("HPHR Volume", WCD937X_HPH_R_EN, 0, 20, 1, line_gain), - SOC_SINGLE_TLV("ADC1 Volume", WCD937X_ANA_TX_CH1, 0, 20, 0, analog_gain), - SOC_SINGLE_TLV("ADC2 Volume", WCD937X_ANA_TX_CH2, 0, 20, 0, analog_gain), - SOC_SINGLE_TLV("ADC3 Volume", WCD937X_ANA_TX_CH3, 0, 20, 0, analog_gain), + SOC_SINGLE_TLV("ADC1 Volume", WCD937X_ANA_TX_CH1, 0, 20, 0, + analog_gain), + SOC_SINGLE_TLV("ADC2 Volume", WCD937X_ANA_TX_CH2, 0, 20, 0, + analog_gain), + SOC_SINGLE_TLV("ADC3 Volume", WCD937X_ANA_TX_CH3, 0, 20, 0, + analog_gain), }; static const struct snd_kcontrol_new adc1_switch[] = { @@ -1937,7 +2027,7 @@ static struct snd_info_entry_ops wcd937x_info_ops = { /* * wcd937x_info_create_codec_entry - creates wcd937x module * @codec_root: The parent directory - * @codec: Codec instance + * @component: component instance * * Creates wcd937x module and version entry under the given * parent directory. @@ -1945,26 +2035,26 @@ static struct snd_info_entry_ops wcd937x_info_ops = { * Return: 0 on success or negative error code on failure. */ int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { struct snd_info_entry *version_entry; struct wcd937x_priv *priv; struct snd_soc_card *card; - if (!codec_root || !codec) + if (!codec_root || !component) return -EINVAL; - priv = snd_soc_codec_get_drvdata(codec); + priv = snd_soc_component_get_drvdata(component); if (priv->entry) { dev_dbg(priv->dev, "%s:wcd937x module already created\n", __func__); return 0; } - card = codec->component.card; + card = component->card; priv->entry = snd_info_create_subdir(codec_root->module, "wcd937x", codec_root); if (!priv->entry) { - dev_dbg(codec->dev, "%s: failed to create wcd937x entry\n", + dev_dbg(component->dev, "%s: failed to create wcd937x entry\n", __func__); return -ENOMEM; } @@ -1972,7 +2062,7 @@ int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root, "version", priv->entry); if (!version_entry) { - dev_dbg(codec->dev, "%s: failed to create wcd937x version entry\n", + dev_dbg(component->dev, "%s: failed to create wcd937x version entry\n", __func__); return -ENOMEM; } @@ -1992,42 +2082,44 @@ int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root, } EXPORT_SYMBOL(wcd937x_info_create_codec_entry); -static int wcd937x_soc_codec_probe(struct snd_soc_codec *codec) +static int wcd937x_soc_codec_probe(struct snd_soc_component *component) { - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); int variant; int ret = -EINVAL; - dev_info(codec->dev, "%s()\n", __func__); - wcd937x = snd_soc_codec_get_drvdata(codec); + dev_info(component->dev, "%s()\n", __func__); + wcd937x = snd_soc_component_get_drvdata(component); if (!wcd937x) return -EINVAL; - wcd937x->codec = codec; - variant = (snd_soc_read(codec, WCD937X_DIGITAL_EFUSE_REG_0) & 0x0E) >> 1; + wcd937x->component = component; + variant = (snd_soc_component_read32( + component, WCD937X_DIGITAL_EFUSE_REG_0) & 0x0E) >> 1; wcd937x->variant = variant; - wcd937x->fw_data = devm_kzalloc(codec->dev, + wcd937x->fw_data = devm_kzalloc(component->dev, sizeof(*(wcd937x->fw_data)), GFP_KERNEL); if (!wcd937x->fw_data) { - dev_err(codec->dev, "Failed to allocate fw_data\n"); + dev_err(component->dev, "Failed to allocate fw_data\n"); ret = -ENOMEM; goto err; } set_bit(WCD9XXX_MBHC_CAL, wcd937x->fw_data->cal_bit); ret = wcd_cal_create_hwdep(wcd937x->fw_data, - WCD9XXX_CODEC_HWDEP_NODE, codec); + WCD9XXX_CODEC_HWDEP_NODE, component); if (ret < 0) { - dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret); + dev_err(component->dev, "%s hwdep failed %d\n", __func__, ret); goto err_hwdep; } - ret = wcd937x_mbhc_init(&wcd937x->mbhc, codec, wcd937x->fw_data); + ret = wcd937x_mbhc_init(&wcd937x->mbhc, component, wcd937x->fw_data); if (ret) { pr_err("%s: mbhc initialization failed\n", __func__); goto err_hwdep; @@ -2047,20 +2139,20 @@ static int wcd937x_soc_codec_probe(struct snd_soc_codec *codec) snd_soc_dapm_sync(dapm); wcd_cls_h_init(&wcd937x->clsh_info); - wcd937x_init_reg(codec); + wcd937x_init_reg(component); if (wcd937x->variant == WCD9375_VARIANT) { ret = snd_soc_dapm_new_controls(dapm, wcd9375_dapm_widgets, ARRAY_SIZE(wcd9375_dapm_widgets)); if (ret < 0) { - dev_err(codec->dev, "%s: Failed to add snd_ctls\n", + dev_err(component->dev, "%s: Failed to add snd_ctls\n", __func__); goto err_hwdep; } ret = snd_soc_dapm_add_routes(dapm, wcd9375_audio_map, ARRAY_SIZE(wcd9375_audio_map)); if (ret < 0) { - dev_err(codec->dev, "%s: Failed to add routes\n", + dev_err(component->dev, "%s: Failed to add routes\n", __func__); goto err_hwdep; } @@ -2082,7 +2174,7 @@ static int wcd937x_soc_codec_probe(struct snd_soc_codec *codec) &wcd937x->nblock, true); if (ret) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to register notifier %d\n", __func__, ret); return ret; @@ -2097,39 +2189,30 @@ static int wcd937x_soc_codec_probe(struct snd_soc_codec *codec) return ret; } -static int wcd937x_soc_codec_remove(struct snd_soc_codec *codec) +static void wcd937x_soc_codec_remove(struct snd_soc_component *component) { - struct wcd937x_priv *wcd937x = snd_soc_codec_get_drvdata(codec); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); if (!wcd937x) - return -EINVAL; + return; if (wcd937x->register_notifier) - return wcd937x->register_notifier(wcd937x->handle, + wcd937x->register_notifier(wcd937x->handle, &wcd937x->nblock, false); - return 0; + return; } -static struct regmap *wcd937x_get_regmap(struct device *dev) -{ - struct wcd937x_priv *wcd937x = dev_get_drvdata(dev); - - return wcd937x->regmap; -} - -static struct snd_soc_codec_driver soc_codec_dev_wcd937x = { +static const struct snd_soc_component_driver soc_codec_dev_wcd937x = { + .name = DRV_NAME, .probe = wcd937x_soc_codec_probe, .remove = wcd937x_soc_codec_remove, - .get_regmap = wcd937x_get_regmap, - .component_driver = { - .controls = wcd937x_snd_controls, - .num_controls = ARRAY_SIZE(wcd937x_snd_controls), - .dapm_widgets = wcd937x_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(wcd937x_dapm_widgets), - .dapm_routes = wcd937x_audio_map, - .num_dapm_routes = ARRAY_SIZE(wcd937x_audio_map), - }, + .controls = wcd937x_snd_controls, + .num_controls = ARRAY_SIZE(wcd937x_snd_controls), + .dapm_widgets = wcd937x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wcd937x_dapm_widgets), + .dapm_routes = wcd937x_audio_map, + .num_dapm_routes = ARRAY_SIZE(wcd937x_audio_map), }; #ifdef CONFIG_PM_SLEEP @@ -2472,7 +2555,7 @@ static int wcd937x_bind(struct device *dev) wcd937x->tx_swr_dev->slave_irq = wcd937x->virq; mutex_init(&wcd937x->micb_lock); - ret = snd_soc_register_codec(dev, &soc_codec_dev_wcd937x, + ret = snd_soc_register_component(dev, &soc_codec_dev_wcd937x, NULL, 0); if (ret) { dev_err(dev, "%s: Codec registration failed\n", @@ -2493,7 +2576,7 @@ static void wcd937x_unbind(struct device *dev) struct wcd937x_priv *wcd937x = dev_get_drvdata(dev); wcd_irq_exit(&wcd937x->irq_info, wcd937x->virq); - snd_soc_unregister_codec(dev); + snd_soc_unregister_component(dev); component_unbind_all(dev, wcd937x); mutex_destroy(&wcd937x->micb_lock); } diff --git a/asoc/codecs/wcd937x/wcd937x.h b/asoc/codecs/wcd937x/wcd937x.h index 14504609411c..a40554e1963f 100644 --- a/asoc/codecs/wcd937x/wcd937x.h +++ b/asoc/codecs/wcd937x/wcd937x.h @@ -7,10 +7,10 @@ #ifdef CONFIG_SND_SOC_WCD937X extern int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root, - struct snd_soc_codec *codec); + struct snd_soc_component *component); #else extern int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { return 0; } diff --git a/asoc/codecs/wcd9xxx-common-v2.c b/asoc/codecs/wcd9xxx-common-v2.c index 78cfc15a5981..d45a071b1db5 100644 --- a/asoc/codecs/wcd9xxx-common-v2.c +++ b/asoc/codecs/wcd9xxx-common-v2.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #include @@ -210,7 +210,7 @@ static const struct wcd_imped_val imped_index[] = { {13, 9}, }; -static void (*clsh_state_fp[NUM_CLSH_STATES_V2])(struct snd_soc_codec *, +static void (*clsh_state_fp[NUM_CLSH_STATES_V2])(struct snd_soc_component *, struct wcd_clsh_cdc_data *, u8 req_state, bool en, int mode); @@ -243,12 +243,13 @@ static int get_impedance_index(int imped) /* * Function: wcd_clsh_imped_config - * Params: codec, imped, reset + * Params: component, imped, reset * Description: * This function updates HPHL and HPHR gain settings * according to the impedance value. */ -void wcd_clsh_imped_config(struct snd_soc_codec *codec, int imped, bool reset) +void wcd_clsh_imped_config(struct snd_soc_component *component, int imped, + bool reset) { int i; int index = 0; @@ -256,7 +257,7 @@ void wcd_clsh_imped_config(struct snd_soc_codec *codec, int imped, bool reset) static const struct wcd_reg_mask_val (*imped_table_ptr)[MAX_IMPED_PARAMS]; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); if (IS_CODEC_TYPE(wcd9xxx, WCD934X)) { table_size = ARRAY_SIZE(imped_table_tavil); @@ -269,7 +270,7 @@ void wcd_clsh_imped_config(struct snd_soc_codec *codec, int imped, bool reset) /* reset = 1, which means request is to reset the register values */ if (reset) { for (i = 0; i < MAX_IMPED_PARAMS; i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, imped_table_ptr[index][i].reg, imped_table_ptr[index][i].mask, 0); return; @@ -285,24 +286,25 @@ void wcd_clsh_imped_config(struct snd_soc_codec *codec, int imped, bool reset) return; } for (i = 0; i < MAX_IMPED_PARAMS; i++) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, imped_table_ptr[index][i].reg, imped_table_ptr[index][i].mask, imped_table_ptr[index][i].val); } EXPORT_SYMBOL(wcd_clsh_imped_config); -static bool is_native_44_1_active(struct snd_soc_codec *codec) +static bool is_native_44_1_active(struct snd_soc_component *component) { bool native_active = false; u8 native_clk, rx1_rate, rx2_rate; - native_clk = snd_soc_read(codec, + native_clk = snd_soc_component_read32(component, WCD9XXX_CDC_CLK_RST_CTRL_MCLK_CONTROL); - rx1_rate = snd_soc_read(codec, WCD9XXX_CDC_RX1_RX_PATH_CTL); - rx2_rate = snd_soc_read(codec, WCD9XXX_CDC_RX2_RX_PATH_CTL); - - dev_dbg(codec->dev, "%s: native_clk %x rx1_rate= %x rx2_rate= %x", + rx1_rate = snd_soc_component_read32(component, + WCD9XXX_CDC_RX1_RX_PATH_CTL); + rx2_rate = snd_soc_component_read32(component, + WCD9XXX_CDC_RX2_RX_PATH_CTL); + dev_dbg(component->dev, "%s: native_clk %x rx1_rate= %x rx2_rate= %x", __func__, native_clk, rx1_rate, rx2_rate); if ((native_clk & 0x2) && @@ -371,22 +373,23 @@ static const char *state_to_str(u8 state, char *buf, size_t buflen) } static inline void -wcd_enable_clsh_block(struct snd_soc_codec *codec, +wcd_enable_clsh_block(struct snd_soc_component *component, struct wcd_clsh_cdc_data *clsh_d, bool enable) { if ((enable && ++clsh_d->clsh_users == 1) || (!enable && --clsh_d->clsh_users == 0)) - snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLSH_CRC, 0x01, - (u8) enable); + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_CLSH_CRC, + 0x01, (u8) enable); if (clsh_d->clsh_users < 0) clsh_d->clsh_users = 0; - dev_dbg(codec->dev, "%s: clsh_users %d, enable %d", __func__, + dev_dbg(component->dev, "%s: clsh_users %d, enable %d", __func__, clsh_d->clsh_users, enable); } -static inline bool wcd_clsh_enable_status(struct snd_soc_codec *codec) +static inline bool wcd_clsh_enable_status(struct snd_soc_component *component) { - return snd_soc_read(codec, WCD9XXX_A_CDC_CLSH_CRC) & 0x01; + return snd_soc_component_read32(component, WCD9XXX_A_CDC_CLSH_CRC) & + 0x01; } static inline int wcd_clsh_get_int_mode(struct wcd_clsh_cdc_data *clsh_d, @@ -417,34 +420,40 @@ static inline void wcd_clsh_set_int_mode(struct wcd_clsh_cdc_data *clsh_d, clsh_d->interpolator_modes[ffs(clsh_state)] = mode; } -static inline void wcd_clsh_set_buck_mode(struct snd_soc_codec *codec, +static inline void wcd_clsh_set_buck_mode(struct snd_soc_component *component, int mode) { if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || mode == CLS_AB_HIFI || mode == CLS_AB) - snd_soc_update_bits(codec, WCD9XXX_A_ANA_RX_SUPPLIES, - 0x08, 0x08); /* set to HIFI */ + snd_soc_component_update_bits(component, + WCD9XXX_A_ANA_RX_SUPPLIES, + 0x08, 0x08); /* set to HIFI */ else - snd_soc_update_bits(codec, WCD9XXX_A_ANA_RX_SUPPLIES, - 0x08, 0x00); /* set to default */ + snd_soc_component_update_bits(component, + WCD9XXX_A_ANA_RX_SUPPLIES, + 0x08, 0x00); /* set to default */ } -static inline void wcd_clsh_set_flyback_mode(struct snd_soc_codec *codec, - int mode) +static inline void wcd_clsh_set_flyback_mode( + struct snd_soc_component *component, + int mode) { if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || mode == CLS_AB_HIFI || mode == CLS_AB) - snd_soc_update_bits(codec, WCD9XXX_A_ANA_RX_SUPPLIES, - 0x04, 0x04); /* set to HIFI */ + snd_soc_component_update_bits(component, + WCD9XXX_A_ANA_RX_SUPPLIES, + 0x04, 0x04); /* set to HIFI */ else - snd_soc_update_bits(codec, WCD9XXX_A_ANA_RX_SUPPLIES, - 0x04, 0x00); /* set to Default */ + snd_soc_component_update_bits(component, + WCD9XXX_A_ANA_RX_SUPPLIES, + 0x04, 0x00); /* set to Default */ } -static inline void wcd_clsh_gm3_boost_disable(struct snd_soc_codec *codec, - int mode) +static inline void wcd_clsh_gm3_boost_disable( + struct snd_soc_component *component, + int mode) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); if (!IS_CODEC_TYPE(wcd9xxx, WCD934X)) return; @@ -452,46 +461,56 @@ static inline void wcd_clsh_gm3_boost_disable(struct snd_soc_codec *codec, if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || mode == CLS_AB_HIFI || mode == CLS_AB) { if (TAVIL_IS_1_0(wcd9xxx)) - snd_soc_update_bits(codec, WCD9XXX_HPH_CNP_WG_CTL, - 0x80, 0x0); /* disable GM3 Boost */ - snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEG_CTRL_4, - 0xF0, 0x80); + snd_soc_component_update_bits(component, + WCD9XXX_HPH_CNP_WG_CTL, + 0x80, 0x0); /* disable GM3 Boost */ + snd_soc_component_update_bits(component, + WCD9XXX_FLYBACK_VNEG_CTRL_4, + 0xF0, 0x80); } else { - snd_soc_update_bits(codec, WCD9XXX_HPH_CNP_WG_CTL, - 0x80, 0x80); /* set to Default */ - snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEG_CTRL_4, - 0xF0, 0x70); + snd_soc_component_update_bits(component, + WCD9XXX_HPH_CNP_WG_CTL, + 0x80, 0x80); /* set to Default */ + snd_soc_component_update_bits(component, + WCD9XXX_FLYBACK_VNEG_CTRL_4, + 0xF0, 0x70); } } -static inline void wcd_clsh_force_iq_ctl(struct snd_soc_codec *codec, +static inline void wcd_clsh_force_iq_ctl(struct snd_soc_component *component, int mode) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); if (!IS_CODEC_TYPE(wcd9xxx, WCD934X)) return; if (mode == CLS_H_LOHIFI || mode == CLS_AB) { - snd_soc_update_bits(codec, WCD9XXX_HPH_NEW_INT_PA_MISC2, - 0x20, 0x20); - snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_HPH_LOWPOWER, - 0xF0, 0xC0); - snd_soc_update_bits(codec, WCD9XXX_HPH_PA_CTL1, - 0x0E, 0x02); + snd_soc_component_update_bits(component, + WCD9XXX_HPH_NEW_INT_PA_MISC2, + 0x20, 0x20); + snd_soc_component_update_bits(component, + WCD9XXX_RX_BIAS_HPH_LOWPOWER, + 0xF0, 0xC0); + snd_soc_component_update_bits(component, + WCD9XXX_HPH_PA_CTL1, + 0x0E, 0x02); } else { - snd_soc_update_bits(codec, WCD9XXX_HPH_NEW_INT_PA_MISC2, - 0x20, 0x0); - snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_HPH_LOWPOWER, - 0xF0, 0x80); - snd_soc_update_bits(codec, WCD9XXX_HPH_PA_CTL1, - 0x0E, 0x06); + snd_soc_component_update_bits(component, + WCD9XXX_HPH_NEW_INT_PA_MISC2, + 0x20, 0x0); + snd_soc_component_update_bits(component, + WCD9XXX_RX_BIAS_HPH_LOWPOWER, + 0xF0, 0x80); + snd_soc_component_update_bits(component, + WCD9XXX_HPH_PA_CTL1, + 0x0E, 0x06); } } -static void wcd_clsh_buck_ctrl(struct snd_soc_codec *codec, +static void wcd_clsh_buck_ctrl(struct snd_soc_component *component, struct wcd_clsh_cdc_data *clsh_d, int mode, bool enable) @@ -499,9 +518,10 @@ static void wcd_clsh_buck_ctrl(struct snd_soc_codec *codec, /* enable/disable buck */ if ((enable && (++clsh_d->buck_users == 1)) || (!enable && (--clsh_d->buck_users == 0))) - snd_soc_update_bits(codec, WCD9XXX_A_ANA_RX_SUPPLIES, - (1 << 7), (enable << 7)); - dev_dbg(codec->dev, "%s: buck_users %d, enable %d, mode: %s", + snd_soc_component_update_bits(component, + WCD9XXX_A_ANA_RX_SUPPLIES, + (1 << 7), (enable << 7)); + dev_dbg(component->dev, "%s: buck_users %d, enable %d, mode: %s", __func__, clsh_d->buck_users, enable, mode_to_str(mode)); /* * 500us sleep is required after buck enable/disable @@ -510,29 +530,32 @@ static void wcd_clsh_buck_ctrl(struct snd_soc_codec *codec, usleep_range(500, 500 + WCD_USLEEP_RANGE); } -static void wcd_clsh_flyback_ctrl(struct snd_soc_codec *codec, +static void wcd_clsh_flyback_ctrl(struct snd_soc_component *component, struct wcd_clsh_cdc_data *clsh_d, int mode, bool enable) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); struct wcd9xxx_reg_val bulk_reg[2]; u8 vneg[] = {0x00, 0x40}; /* enable/disable flyback */ if ((enable && (++clsh_d->flyback_users == 1)) || (!enable && (--clsh_d->flyback_users == 0))) { - snd_soc_update_bits(codec, WCD9XXX_A_ANA_RX_SUPPLIES, - (1 << 6), (enable << 6)); + snd_soc_component_update_bits(component, + WCD9XXX_A_ANA_RX_SUPPLIES, + (1 << 6), (enable << 6)); /* 100usec delay is needed as per HW requirement */ usleep_range(100, 110); if (enable && (TASHA_IS_1_1(wcd9xxx))) { - wcd_clsh_set_flyback_mode(codec, CLS_H_HIFI); - snd_soc_update_bits(codec, WCD9XXX_FLYBACK_EN, - 0x60, 0x40); - snd_soc_update_bits(codec, WCD9XXX_FLYBACK_EN, - 0x10, 0x10); - vneg[0] = snd_soc_read(codec, + wcd_clsh_set_flyback_mode(component, CLS_H_HIFI); + snd_soc_component_update_bits(component, + WCD9XXX_FLYBACK_EN, + 0x60, 0x40); + snd_soc_component_update_bits(component, + WCD9XXX_FLYBACK_EN, + 0x10, 0x10); + vneg[0] = snd_soc_component_read32(component, WCD9XXX_A_ANA_RX_SUPPLIES); vneg[0] &= ~(0x40); vneg[1] = vneg[0] | 0x40; @@ -546,13 +569,14 @@ static void wcd_clsh_flyback_ctrl(struct snd_soc_codec *codec, usleep_range(500, 510); wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, 2, false); - snd_soc_update_bits(codec, WCD9XXX_FLYBACK_EN, - 0x10, 0x00); - wcd_clsh_set_flyback_mode(codec, mode); + snd_soc_component_update_bits(component, + WCD9XXX_FLYBACK_EN, + 0x10, 0x00); + wcd_clsh_set_flyback_mode(component, mode); } } - dev_dbg(codec->dev, "%s: flyback_users %d, enable %d, mode: %s", + dev_dbg(component->dev, "%s: flyback_users %d, enable %d, mode: %s", __func__, clsh_d->flyback_users, enable, mode_to_str(mode)); /* * 500us sleep is required after flyback enable/disable @@ -561,11 +585,11 @@ static void wcd_clsh_flyback_ctrl(struct snd_soc_codec *codec, usleep_range(500, 500 + WCD_USLEEP_RANGE); } -static void wcd_clsh_set_gain_path(struct snd_soc_codec *codec, +static void wcd_clsh_set_gain_path(struct snd_soc_component *component, int mode) { u8 val = 0; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); if (!TASHA_IS_2_0(wcd9xxx)) return; @@ -584,11 +608,13 @@ static void wcd_clsh_set_gain_path(struct snd_soc_codec *codec, default: return; }; - snd_soc_update_bits(codec, WCD9XXX_HPH_L_EN, 0xC0, (val << 6)); - snd_soc_update_bits(codec, WCD9XXX_HPH_R_EN, 0xC0, (val << 6)); + snd_soc_component_update_bits(component, WCD9XXX_HPH_L_EN, + 0xC0, (val << 6)); + snd_soc_component_update_bits(component, WCD9XXX_HPH_R_EN, + 0xC0, (val << 6)); } -static void wcd_clsh_set_hph_mode(struct snd_soc_codec *codec, +static void wcd_clsh_set_hph_mode(struct snd_soc_component *component, int mode) { u8 val = 0; @@ -596,7 +622,7 @@ static void wcd_clsh_set_hph_mode(struct snd_soc_codec *codec, u8 res_val = VREF_FILT_R_0OHM; u8 ipeak = DELTA_I_50MA; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); switch (mode) { case CLS_H_NORMAL: @@ -646,97 +672,109 @@ static void wcd_clsh_set_hph_mode(struct snd_soc_codec *codec, (mode == CLS_H_LOHIFI || mode == CLS_AB)) val = 0x04; - snd_soc_update_bits(codec, WCD9XXX_A_ANA_HPH, 0x0C, val); + snd_soc_component_update_bits(component, WCD9XXX_A_ANA_HPH, 0x0C, val); if (TASHA_IS_2_0(wcd9xxx)) { - snd_soc_update_bits(codec, WCD9XXX_CLASSH_CTRL_VCL_2, - 0x30, (res_val << 4)); + snd_soc_component_update_bits(component, + WCD9XXX_CLASSH_CTRL_VCL_2, + 0x30, (res_val << 4)); if (mode != CLS_H_LP) - snd_soc_update_bits(codec, WCD9XXX_HPH_REFBUFF_UHQA_CTL, - 0x07, gain); - snd_soc_update_bits(codec, WCD9XXX_CLASSH_CTRL_CCL_1, - 0xF0, (ipeak << 4)); + snd_soc_component_update_bits(component, + WCD9XXX_HPH_REFBUFF_UHQA_CTL, + 0x07, gain); + snd_soc_component_update_bits(component, + WCD9XXX_CLASSH_CTRL_CCL_1, + 0xF0, (ipeak << 4)); } } -static void wcd_clsh_set_flyback_vneg_ctl(struct snd_soc_codec *codec, +static void wcd_clsh_set_flyback_vneg_ctl(struct snd_soc_component *component, bool enable) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); if (!TASHA_IS_2_0(wcd9xxx)) return; if (enable) { - snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEG_CTRL_1, 0xE0, - 0x00); - snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEGDAC_CTRL_2, - 0xE0, (0x07 << 5)); + snd_soc_component_update_bits(component, + WCD9XXX_FLYBACK_VNEG_CTRL_1, 0xE0, 0x00); + snd_soc_component_update_bits(component, + WCD9XXX_FLYBACK_VNEGDAC_CTRL_2, + 0xE0, (0x07 << 5)); } else { - snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEG_CTRL_1, 0xE0, - (0x07 << 5)); - snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEGDAC_CTRL_2, - 0xE0, (0x02 << 5)); + snd_soc_component_update_bits(component, + WCD9XXX_FLYBACK_VNEG_CTRL_1, + 0xE0, (0x07 << 5)); + snd_soc_component_update_bits(component, + WCD9XXX_FLYBACK_VNEGDAC_CTRL_2, + 0xE0, (0x02 << 5)); } } -static void wcd_clsh_set_flyback_current(struct snd_soc_codec *codec, int mode) +static void wcd_clsh_set_flyback_current(struct snd_soc_component *component, + int mode) { - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); if (!TASHA_IS_2_0(wcd9xxx)) return; - snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_FLYB_BUFF, 0x0F, 0x0A); - snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_FLYB_BUFF, 0xF0, 0xA0); + snd_soc_component_update_bits(component, WCD9XXX_RX_BIAS_FLYB_BUFF, + 0x0F, 0x0A); + snd_soc_component_update_bits(component, WCD9XXX_RX_BIAS_FLYB_BUFF, + 0xF0, 0xA0); /* Sleep needed to avoid click and pop as per HW requirement */ usleep_range(100, 110); } -static void wcd_clsh_set_buck_regulator_mode(struct snd_soc_codec *codec, - int mode) +static void wcd_clsh_set_buck_regulator_mode( + struct snd_soc_component *component, + int mode) { - snd_soc_update_bits(codec, WCD9XXX_A_ANA_RX_SUPPLIES, + snd_soc_component_update_bits(component, WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x00); } -static void wcd_clsh_state_lo(struct snd_soc_codec *codec, +static void wcd_clsh_state_lo(struct snd_soc_component *component, struct wcd_clsh_cdc_data *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); if (mode != CLS_AB && mode != CLS_AB_HIFI) { - dev_err(codec->dev, "%s: LO cannot be in this mode: %d\n", + dev_err(component->dev, "%s: LO cannot be in this mode: %d\n", __func__, mode); return; } if (is_enable) { - wcd_clsh_set_buck_regulator_mode(codec, mode); - wcd_clsh_set_flyback_vneg_ctl(codec, true); - wcd_clsh_set_buck_mode(codec, mode); - wcd_clsh_set_flyback_mode(codec, mode); - wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true); - wcd_clsh_set_flyback_current(codec, mode); - wcd_clsh_buck_ctrl(codec, clsh_d, mode, true); + wcd_clsh_set_buck_regulator_mode(component, mode); + wcd_clsh_set_flyback_vneg_ctl(component, true); + wcd_clsh_set_buck_mode(component, mode); + wcd_clsh_set_flyback_mode(component, mode); + wcd_clsh_flyback_ctrl(component, clsh_d, mode, true); + wcd_clsh_set_flyback_current(component, mode); + wcd_clsh_buck_ctrl(component, clsh_d, mode, true); } else { - wcd_clsh_buck_ctrl(codec, clsh_d, mode, false); - wcd_clsh_flyback_ctrl(codec, clsh_d, mode, false); - wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); - wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); - wcd_clsh_set_flyback_vneg_ctl(codec, false); - wcd_clsh_set_buck_regulator_mode(codec, CLS_H_NORMAL); + wcd_clsh_buck_ctrl(component, clsh_d, mode, false); + wcd_clsh_flyback_ctrl(component, clsh_d, mode, false); + wcd_clsh_set_flyback_mode(component, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(component, CLS_H_NORMAL); + wcd_clsh_set_flyback_vneg_ctl(component, false); + wcd_clsh_set_buck_regulator_mode(component, CLS_H_NORMAL); } } -static void wcd_clsh_state_hph_ear(struct snd_soc_codec *codec, +static void wcd_clsh_state_hph_ear(struct snd_soc_component *component, struct wcd_clsh_cdc_data *clsh_d, u8 req_state, bool is_enable, int mode) { int hph_mode = 0; - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); if (is_enable) { @@ -755,37 +793,38 @@ static void wcd_clsh_state_hph_ear(struct snd_soc_codec *codec, else return; if (hph_mode != CLS_AB && hph_mode != CLS_AB_HIFI - && !is_native_44_1_active(codec)) - snd_soc_update_bits(codec, + && !is_native_44_1_active(component)) + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, 0x40, 0x40); } - if (is_native_44_1_active(codec)) { - snd_soc_write(codec, WCD9XXX_CDC_CLSH_HPH_V_PA, 0x39); - snd_soc_update_bits(codec, + if (is_native_44_1_active(component)) { + snd_soc_component_write(component, + WCD9XXX_CDC_CLSH_HPH_V_PA, 0x39); + snd_soc_component_update_bits(component, WCD9XXX_CDC_RX0_RX_PATH_SEC0, 0x03, 0x00); if ((req_state == WCD_CLSH_STATE_HPHL) || (req_state == WCD_CLSH_STATE_HPHR)) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, 0x40, 0x00); } if (req_state == WCD_CLSH_STATE_HPHL) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, 0x40, 0x40); if (req_state == WCD_CLSH_STATE_HPHR) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, 0x40, 0x40); if ((req_state == WCD_CLSH_STATE_HPHL) || (req_state == WCD_CLSH_STATE_HPHR)) { - wcd_clsh_set_gain_path(codec, mode); - wcd_clsh_set_flyback_mode(codec, mode); - wcd_clsh_set_buck_mode(codec, mode); + wcd_clsh_set_gain_path(component, mode); + wcd_clsh_set_flyback_mode(component, mode); + wcd_clsh_set_buck_mode(component, mode); } } else { if (req_state == WCD_CLSH_STATE_EAR) { @@ -795,54 +834,56 @@ static void wcd_clsh_state_hph_ear(struct snd_soc_codec *codec, * and if HPH requested mode is CLS_AB then * no need to disable EAR channel enable bit. */ - if (wcd_clsh_enable_status(codec)) - snd_soc_update_bits(codec, + if (wcd_clsh_enable_status(component)) + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, 0x40, 0x00); } - if (is_native_44_1_active(codec)) { - snd_soc_write(codec, WCD9XXX_CDC_CLSH_HPH_V_PA, 0x1C); - snd_soc_update_bits(codec, + if (is_native_44_1_active(component)) { + snd_soc_component_write(component, + WCD9XXX_CDC_CLSH_HPH_V_PA, 0x1C); + snd_soc_component_update_bits(component, WCD9XXX_CDC_RX0_RX_PATH_SEC0, 0x03, 0x01); if (((clsh_d->state & WCD_CLSH_STATE_HPH_ST) != WCD_CLSH_STATE_HPH_ST) && ((req_state == WCD_CLSH_STATE_HPHL) || (req_state == WCD_CLSH_STATE_HPHR))) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, 0x40, 0x40); } if (req_state == WCD_CLSH_STATE_HPHL) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, 0x40, 0x00); if (req_state == WCD_CLSH_STATE_HPHR) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, 0x40, 0x00); if ((req_state & WCD_CLSH_STATE_HPH_ST) && - !wcd_clsh_enable_status(codec)) { + !wcd_clsh_enable_status(component)) { /* If Class-H is not enabled when HPH is turned * off, enable it as EAR is in progress */ - wcd_enable_clsh_block(codec, clsh_d, true); - snd_soc_update_bits(codec, + wcd_enable_clsh_block(component, clsh_d, true); + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, 0x40, 0x40); - wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); - wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_flyback_mode(component, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(component, CLS_H_NORMAL); } } } -static void wcd_clsh_state_ear_lo(struct snd_soc_codec *codec, +static void wcd_clsh_state_ear_lo(struct snd_soc_component *component, struct wcd_clsh_cdc_data *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); if (is_enable) { @@ -851,22 +892,22 @@ static void wcd_clsh_state_ear_lo(struct snd_soc_codec *codec, */ if (req_state == WCD_CLSH_STATE_EAR) { /* EAR powerup.*/ - if (!wcd_clsh_enable_status(codec)) { - wcd_enable_clsh_block(codec, clsh_d, true); - wcd_clsh_set_buck_mode(codec, mode); - wcd_clsh_set_flyback_mode(codec, mode); + if (!wcd_clsh_enable_status(component)) { + wcd_enable_clsh_block(component, clsh_d, true); + wcd_clsh_set_buck_mode(component, mode); + wcd_clsh_set_flyback_mode(component, mode); } - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, 0x40, 0x40); } } else { if (req_state == WCD_CLSH_STATE_EAR) { /* EAR powerdown.*/ - wcd_enable_clsh_block(codec, clsh_d, false); - wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); - wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); - snd_soc_update_bits(codec, + wcd_enable_clsh_block(component, clsh_d, false); + wcd_clsh_set_buck_mode(component, CLS_H_NORMAL); + wcd_clsh_set_flyback_mode(component, CLS_H_NORMAL); + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, 0x40, 0x00); } @@ -876,13 +917,14 @@ static void wcd_clsh_state_ear_lo(struct snd_soc_codec *codec, } } -static void wcd_clsh_state_hph_lo(struct snd_soc_codec *codec, +static void wcd_clsh_state_hph_lo(struct snd_soc_component *component, struct wcd_clsh_cdc_data *clsh_d, u8 req_state, bool is_enable, int mode) { int hph_mode = 0; - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); if (is_enable) { @@ -895,31 +937,31 @@ static void wcd_clsh_state_hph_lo(struct snd_soc_codec *codec, * and buck. */ if (req_state == WCD_CLSH_STATE_LO) - wcd_clsh_set_buck_regulator_mode(codec, CLS_AB); + wcd_clsh_set_buck_regulator_mode(component, CLS_AB); else { - if (!wcd_clsh_enable_status(codec)) { - wcd_enable_clsh_block(codec, clsh_d, true); - snd_soc_update_bits(codec, + if (!wcd_clsh_enable_status(component)) { + wcd_enable_clsh_block(component, clsh_d, true); + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_CLSH_K1_MSB, 0x0F, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_CLSH_K1_LSB, 0xFF, 0xC0); - wcd_clsh_set_flyback_mode(codec, mode); - wcd_clsh_set_flyback_vneg_ctl(codec, false); - wcd_clsh_set_buck_mode(codec, mode); - wcd_clsh_set_hph_mode(codec, mode); - wcd_clsh_set_gain_path(codec, mode); + wcd_clsh_set_flyback_mode(component, mode); + wcd_clsh_set_flyback_vneg_ctl(component, false); + wcd_clsh_set_buck_mode(component, mode); + wcd_clsh_set_hph_mode(component, mode); + wcd_clsh_set_gain_path(component, mode); } else { - dev_dbg(codec->dev, "%s:clsh is already enabled\n", + dev_dbg(component->dev, "%s:clsh is already enabled\n", __func__); } if (req_state == WCD_CLSH_STATE_HPHL) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, 0x40, 0x40); if (req_state == WCD_CLSH_STATE_HPHR) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, 0x40, 0x40); } @@ -927,11 +969,11 @@ static void wcd_clsh_state_hph_lo(struct snd_soc_codec *codec, if ((req_state == WCD_CLSH_STATE_HPHL) || (req_state == WCD_CLSH_STATE_HPHR)) { if (req_state == WCD_CLSH_STATE_HPHL) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, 0x40, 0x00); if (req_state == WCD_CLSH_STATE_HPHR) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, 0x40, 0x00); /* @@ -941,10 +983,11 @@ static void wcd_clsh_state_hph_lo(struct snd_soc_codec *codec, */ if ((clsh_d->state & WCD_CLSH_STATE_HPH_ST) != WCD_CLSH_STATE_HPH_ST) { - wcd_enable_clsh_block(codec, clsh_d, false); - wcd_clsh_set_flyback_vneg_ctl(codec, true); - wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); - wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + wcd_enable_clsh_block(component, clsh_d, false); + wcd_clsh_set_flyback_vneg_ctl(component, true); + wcd_clsh_set_flyback_mode( + component, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(component, CLS_H_NORMAL); } } else { /* LO powerdown. @@ -960,7 +1003,7 @@ static void wcd_clsh_state_hph_lo(struct snd_soc_codec *codec, WCD_CLSH_STATE_HPHR); else return; - dev_dbg(codec->dev, "%s: hph_mode = %d\n", __func__, + dev_dbg(component->dev, "%s: hph_mode = %d\n", __func__, hph_mode); if ((hph_mode == CLS_AB) || @@ -973,44 +1016,45 @@ static void wcd_clsh_state_hph_lo(struct snd_soc_codec *codec, * LO ON), no need to turn on again, just set the * regulator mode. */ - if (wcd_clsh_enable_status(codec)) { - wcd_clsh_set_buck_regulator_mode(codec, + if (wcd_clsh_enable_status(component)) { + wcd_clsh_set_buck_regulator_mode(component, hph_mode); goto end; } else { - dev_dbg(codec->dev, "%s: clsh is not enabled\n", + dev_dbg(component->dev, "%s: clsh is not enabled\n", __func__); } - wcd_enable_clsh_block(codec, clsh_d, true); - snd_soc_update_bits(codec, + wcd_enable_clsh_block(component, clsh_d, true); + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_CLSH_K1_MSB, 0x0F, 0x00); - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_CLSH_K1_LSB, 0xFF, 0xC0); - wcd_clsh_set_buck_regulator_mode(codec, + wcd_clsh_set_buck_regulator_mode(component, hph_mode); if (clsh_d->state & WCD_CLSH_STATE_HPHL) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, 0x40, 0x40); if (clsh_d->state & WCD_CLSH_STATE_HPHR) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, 0x40, 0x40); - wcd_clsh_set_hph_mode(codec, hph_mode); + wcd_clsh_set_hph_mode(component, hph_mode); } } end: return; } -static void wcd_clsh_state_hph_st(struct snd_soc_codec *codec, +static void wcd_clsh_state_hph_st(struct snd_soc_component *component, struct wcd_clsh_cdc_data *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); if (mode == CLS_AB || mode == CLS_AB_HIFI) @@ -1018,183 +1062,190 @@ static void wcd_clsh_state_hph_st(struct snd_soc_codec *codec, if (is_enable) { if (req_state == WCD_CLSH_STATE_HPHL) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, 0x40, 0x40); if (req_state == WCD_CLSH_STATE_HPHR) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, 0x40, 0x40); } else { if (req_state == WCD_CLSH_STATE_HPHL) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, 0x40, 0x00); if (req_state == WCD_CLSH_STATE_HPHR) - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, 0x40, 0x00); } } -static void wcd_clsh_state_hph_r(struct snd_soc_codec *codec, +static void wcd_clsh_state_hph_r(struct snd_soc_component *component, struct wcd_clsh_cdc_data *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); if (mode == CLS_H_NORMAL) { - dev_err(codec->dev, "%s: Normal mode not applicable for hph_r\n", + dev_err(component->dev, "%s: Normal mode not applicable for hph_r\n", __func__); return; } if (is_enable) { if (mode != CLS_AB && mode != CLS_AB_HIFI) { - wcd_enable_clsh_block(codec, clsh_d, true); + wcd_enable_clsh_block(component, clsh_d, true); /* * These K1 values depend on the Headphone Impedance * For now it is assumed to be 16 ohm */ - snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLSH_K1_MSB, - 0x0F, 0x00); - snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLSH_K1_LSB, - 0xFF, 0xC0); - snd_soc_update_bits(codec, - WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, - 0x40, 0x40); + snd_soc_component_update_bits(component, + WCD9XXX_A_CDC_CLSH_K1_MSB, + 0x0F, 0x00); + snd_soc_component_update_bits(component, + WCD9XXX_A_CDC_CLSH_K1_LSB, + 0xFF, 0xC0); + snd_soc_component_update_bits(component, + WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, + 0x40, 0x40); } - wcd_clsh_set_buck_regulator_mode(codec, mode); - wcd_clsh_set_flyback_mode(codec, mode); - wcd_clsh_gm3_boost_disable(codec, mode); - wcd_clsh_force_iq_ctl(codec, mode); - wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true); - wcd_clsh_set_flyback_current(codec, mode); - wcd_clsh_set_buck_mode(codec, mode); - wcd_clsh_buck_ctrl(codec, clsh_d, mode, true); - wcd_clsh_set_hph_mode(codec, mode); - wcd_clsh_set_gain_path(codec, mode); + wcd_clsh_set_buck_regulator_mode(component, mode); + wcd_clsh_set_flyback_mode(component, mode); + wcd_clsh_gm3_boost_disable(component, mode); + wcd_clsh_force_iq_ctl(component, mode); + wcd_clsh_flyback_ctrl(component, clsh_d, mode, true); + wcd_clsh_set_flyback_current(component, mode); + wcd_clsh_set_buck_mode(component, mode); + wcd_clsh_buck_ctrl(component, clsh_d, mode, true); + wcd_clsh_set_hph_mode(component, mode); + wcd_clsh_set_gain_path(component, mode); } else { - wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_hph_mode(component, CLS_H_NORMAL); if (mode != CLS_AB && mode != CLS_AB_HIFI) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX2_RX_PATH_CFG0, 0x40, 0x00); - wcd_enable_clsh_block(codec, clsh_d, false); + wcd_enable_clsh_block(component, clsh_d, false); } /* buck and flyback set to default mode and disable */ - wcd_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false); - wcd_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false); - wcd_clsh_force_iq_ctl(codec, CLS_H_NORMAL); - wcd_clsh_gm3_boost_disable(codec, CLS_H_NORMAL); - wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); - wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); - wcd_clsh_set_buck_regulator_mode(codec, CLS_H_NORMAL); + wcd_clsh_buck_ctrl(component, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_flyback_ctrl(component, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_force_iq_ctl(component, CLS_H_NORMAL); + wcd_clsh_gm3_boost_disable(component, CLS_H_NORMAL); + wcd_clsh_set_flyback_mode(component, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(component, CLS_H_NORMAL); + wcd_clsh_set_buck_regulator_mode(component, CLS_H_NORMAL); } } -static void wcd_clsh_state_hph_l(struct snd_soc_codec *codec, +static void wcd_clsh_state_hph_l(struct snd_soc_component *component, struct wcd_clsh_cdc_data *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); if (mode == CLS_H_NORMAL) { - dev_err(codec->dev, "%s: Normal mode not applicable for hph_l\n", + dev_err(component->dev, "%s: Normal mode not applicable for hph_l\n", __func__); return; } if (is_enable) { if (mode != CLS_AB && mode != CLS_AB_HIFI) { - wcd_enable_clsh_block(codec, clsh_d, true); + wcd_enable_clsh_block(component, clsh_d, true); /* * These K1 values depend on the Headphone Impedance * For now it is assumed to be 16 ohm */ - snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLSH_K1_MSB, - 0x0F, 0x00); - snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLSH_K1_LSB, - 0xFF, 0xC0); - snd_soc_update_bits(codec, - WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, - 0x40, 0x40); + snd_soc_component_update_bits(component, + WCD9XXX_A_CDC_CLSH_K1_MSB, + 0x0F, 0x00); + snd_soc_component_update_bits(component, + WCD9XXX_A_CDC_CLSH_K1_LSB, + 0xFF, 0xC0); + snd_soc_component_update_bits(component, + WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, + 0x40, 0x40); } - wcd_clsh_set_buck_regulator_mode(codec, mode); - wcd_clsh_set_flyback_mode(codec, mode); - wcd_clsh_gm3_boost_disable(codec, mode); - wcd_clsh_force_iq_ctl(codec, mode); - wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true); - wcd_clsh_set_flyback_current(codec, mode); - wcd_clsh_set_buck_mode(codec, mode); - wcd_clsh_buck_ctrl(codec, clsh_d, mode, true); - wcd_clsh_set_hph_mode(codec, mode); - wcd_clsh_set_gain_path(codec, mode); + wcd_clsh_set_buck_regulator_mode(component, mode); + wcd_clsh_set_flyback_mode(component, mode); + wcd_clsh_gm3_boost_disable(component, mode); + wcd_clsh_force_iq_ctl(component, mode); + wcd_clsh_flyback_ctrl(component, clsh_d, mode, true); + wcd_clsh_set_flyback_current(component, mode); + wcd_clsh_set_buck_mode(component, mode); + wcd_clsh_buck_ctrl(component, clsh_d, mode, true); + wcd_clsh_set_hph_mode(component, mode); + wcd_clsh_set_gain_path(component, mode); } else { - wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL); + wcd_clsh_set_hph_mode(component, CLS_H_NORMAL); if (mode != CLS_AB && mode != CLS_AB_HIFI) { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX1_RX_PATH_CFG0, 0x40, 0x00); - wcd_enable_clsh_block(codec, clsh_d, false); + wcd_enable_clsh_block(component, clsh_d, false); } /* set buck and flyback to Default Mode */ - wcd_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false); - wcd_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false); - wcd_clsh_force_iq_ctl(codec, CLS_H_NORMAL); - wcd_clsh_gm3_boost_disable(codec, CLS_H_NORMAL); - wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); - wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); - wcd_clsh_set_buck_regulator_mode(codec, CLS_H_NORMAL); + wcd_clsh_buck_ctrl(component, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_flyback_ctrl(component, clsh_d, CLS_H_NORMAL, false); + wcd_clsh_force_iq_ctl(component, CLS_H_NORMAL); + wcd_clsh_gm3_boost_disable(component, CLS_H_NORMAL); + wcd_clsh_set_flyback_mode(component, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(component, CLS_H_NORMAL); + wcd_clsh_set_buck_regulator_mode(component, CLS_H_NORMAL); } } -static void wcd_clsh_state_ear(struct snd_soc_codec *codec, +static void wcd_clsh_state_ear(struct snd_soc_component *component, struct wcd_clsh_cdc_data *clsh_d, u8 req_state, bool is_enable, int mode) { - dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode), + dev_dbg(component->dev, "%s: mode: %s, %s\n", __func__, + mode_to_str(mode), is_enable ? "enable" : "disable"); if (mode != CLS_H_NORMAL) { - dev_err(codec->dev, "%s: mode: %s cannot be used for EAR\n", + dev_err(component->dev, "%s: mode: %s cannot be used for EAR\n", __func__, mode_to_str(mode)); return; } if (is_enable) { - wcd_enable_clsh_block(codec, clsh_d, true); - snd_soc_update_bits(codec, + wcd_enable_clsh_block(component, clsh_d, true); + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, 0x40, 0x40); - wcd_clsh_set_buck_mode(codec, mode); - wcd_clsh_set_flyback_mode(codec, mode); - wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true); - wcd_clsh_set_flyback_current(codec, mode); - wcd_clsh_buck_ctrl(codec, clsh_d, mode, true); + wcd_clsh_set_buck_mode(component, mode); + wcd_clsh_set_flyback_mode(component, mode); + wcd_clsh_flyback_ctrl(component, clsh_d, mode, true); + wcd_clsh_set_flyback_current(component, mode); + wcd_clsh_buck_ctrl(component, clsh_d, mode, true); } else { - snd_soc_update_bits(codec, + snd_soc_component_update_bits(component, WCD9XXX_A_CDC_RX0_RX_PATH_CFG0, 0x40, 0x00); - wcd_enable_clsh_block(codec, clsh_d, false); - wcd_clsh_buck_ctrl(codec, clsh_d, mode, false); - wcd_clsh_flyback_ctrl(codec, clsh_d, mode, false); - wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL); - wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL); + wcd_enable_clsh_block(component, clsh_d, false); + wcd_clsh_buck_ctrl(component, clsh_d, mode, false); + wcd_clsh_flyback_ctrl(component, clsh_d, mode, false); + wcd_clsh_set_flyback_mode(component, CLS_H_NORMAL); + wcd_clsh_set_buck_mode(component, CLS_H_NORMAL); } } -static void wcd_clsh_state_err(struct snd_soc_codec *codec, +static void wcd_clsh_state_err(struct snd_soc_component *component, struct wcd_clsh_cdc_data *clsh_d, u8 req_state, bool is_enable, int mode) { char msg[128]; - dev_err(codec->dev, + dev_err(component->dev, "%s Wrong request for class H state machine requested to %s %s", __func__, is_enable ? "enable" : "disable", state_to_str(req_state, msg, sizeof(msg))); @@ -1231,14 +1282,14 @@ static bool wcd_clsh_is_state_valid(u8 state) /* * Function: wcd_clsh_fsm - * Params: codec, cdc_clsh_d, req_state, req_type, clsh_event + * Params: component, cdc_clsh_d, req_state, req_type, clsh_event * Description: * This function handles PRE DAC and POST DAC conditions of different devices * and updates class H configuration of different combination of devices * based on validity of their states. cdc_clsh_d will contain current * class h state information */ -void wcd_clsh_fsm(struct snd_soc_codec *codec, +void wcd_clsh_fsm(struct snd_soc_component *component, struct wcd_clsh_cdc_data *cdc_clsh_d, u8 clsh_event, u8 req_state, int int_mode) @@ -1252,14 +1303,14 @@ void wcd_clsh_fsm(struct snd_soc_codec *codec, new_state = old_state | req_state; if (!wcd_clsh_is_state_valid(new_state)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Class-H not a valid new state: %s\n", __func__, state_to_str(new_state, msg0, sizeof(msg0))); return; } if (new_state == old_state) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Class-H already in requested state: %s\n", __func__, state_to_str(new_state, msg0, sizeof(msg0))); @@ -1267,9 +1318,9 @@ void wcd_clsh_fsm(struct snd_soc_codec *codec, } cdc_clsh_d->state = new_state; wcd_clsh_set_int_mode(cdc_clsh_d, req_state, int_mode); - (*clsh_state_fp[new_state]) (codec, cdc_clsh_d, req_state, + (*clsh_state_fp[new_state]) (component, cdc_clsh_d, req_state, CLSH_REQ_ENABLE, int_mode); - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: ClassH state transition from %s to %s\n", __func__, state_to_str(old_state, msg0, sizeof(msg0)), state_to_str(cdc_clsh_d->state, msg1, sizeof(msg1))); @@ -1279,7 +1330,7 @@ void wcd_clsh_fsm(struct snd_soc_codec *codec, new_state = old_state & (~req_state); if (new_state < NUM_CLSH_STATES_V2) { if (!wcd_clsh_is_state_valid(old_state)) { - dev_err(codec->dev, + dev_err(component->dev, "%s:Invalid old state:%s\n", __func__, state_to_str(old_state, msg0, @@ -1287,19 +1338,19 @@ void wcd_clsh_fsm(struct snd_soc_codec *codec, return; } if (new_state == old_state) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Class-H already in requested state: %s\n", __func__, state_to_str(new_state, msg0, sizeof(msg0))); return; } - (*clsh_state_fp[old_state]) (codec, cdc_clsh_d, + (*clsh_state_fp[old_state]) (component, cdc_clsh_d, req_state, CLSH_REQ_DISABLE, int_mode); cdc_clsh_d->state = new_state; wcd_clsh_set_int_mode(cdc_clsh_d, req_state, CLS_NONE); - dev_dbg(codec->dev, "%s: ClassH state transition from %s to %s\n", + dev_dbg(component->dev, "%s: ClassH state transition from %s to %s\n", __func__, state_to_str(old_state, msg0, sizeof(msg0)), state_to_str(cdc_clsh_d->state, msg1, diff --git a/asoc/codecs/wcd9xxx-common-v2.h b/asoc/codecs/wcd9xxx-common-v2.h index 94679e88f527..21eadd7c6a77 100644 --- a/asoc/codecs/wcd9xxx-common-v2.h +++ b/asoc/codecs/wcd9xxx-common-v2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #ifndef _WCD9XXX_COMMON_V2 @@ -141,15 +141,15 @@ struct wcd_reg_mask_val { u8 val; }; -extern void wcd_clsh_fsm(struct snd_soc_codec *codec, +extern void wcd_clsh_fsm(struct snd_soc_component *component, struct wcd_clsh_cdc_data *cdc_clsh_d, u8 clsh_event, u8 req_state, int int_mode); extern void wcd_clsh_init(struct wcd_clsh_cdc_data *clsh); extern int wcd_clsh_get_clsh_state(struct wcd_clsh_cdc_data *clsh); -extern void wcd_clsh_imped_config(struct snd_soc_codec *codec, int imped, - bool reset); +extern void wcd_clsh_imped_config(struct snd_soc_component *component, + int imped, bool reset); enum { RESERVED = 0, diff --git a/asoc/codecs/wcd9xxx-regmap.h b/asoc/codecs/wcd9xxx-regmap.h index 8019fa12c0c3..2c7af0d0471f 100644 --- a/asoc/codecs/wcd9xxx-regmap.h +++ b/asoc/codecs/wcd9xxx-regmap.h @@ -9,7 +9,7 @@ #include #include "core.h" -typedef int (*regmap_patch_fptr)(struct regmap *, int); +typedef int (*regmap_patch_fptr)(struct regmap *regmap, int version); extern struct regmap_config wcd934x_regmap_config; extern int wcd934x_regmap_register_patch(struct regmap *regmap, diff --git a/asoc/codecs/wcd9xxx-resmgr-v2.c b/asoc/codecs/wcd9xxx-resmgr-v2.c index f14ba5e73c6e..4636f43b4bb5 100644 --- a/asoc/codecs/wcd9xxx-resmgr-v2.c +++ b/asoc/codecs/wcd9xxx-resmgr-v2.c @@ -49,8 +49,9 @@ static int wcd_resmgr_codec_reg_update_bits(struct wcd9xxx_resmgr_v2 *resmgr, if (reg == WCD93XX_CLK_SYS_MCLK_PRG) return 0; } - if (resmgr->codec) { - ret = snd_soc_update_bits(resmgr->codec, reg, mask, val); + if (resmgr->component) { + ret = snd_soc_component_update_bits(resmgr->component, reg, + mask, val); } else if (resmgr->core_res->wcd_core_regmap) { ret = regmap_update_bits_check( resmgr->core_res->wcd_core_regmap, @@ -77,8 +78,8 @@ static int wcd_resmgr_codec_reg_read(struct wcd9xxx_resmgr_v2 *resmgr, if (reg == WCD93XX_CLK_SYS_MCLK_PRG) return 0; } - if (resmgr->codec) { - val = snd_soc_read(resmgr->codec, reg); + if (resmgr->component) { + val = snd_soc_component_read32(resmgr->component, reg); } else if (resmgr->core_res->wcd_core_regmap) { ret = regmap_read(resmgr->core_res->wcd_core_regmap, reg, &val); @@ -114,8 +115,8 @@ static void wcd_resmgr_cdc_specific_get_clk(struct wcd9xxx_resmgr_v2 *resmgr, if (resmgr->resmgr_cb && resmgr->resmgr_cb->cdc_rco_ctrl) { while (clk_users--) - resmgr->resmgr_cb->cdc_rco_ctrl(resmgr->codec, - true); + resmgr->resmgr_cb->cdc_rco_ctrl( + resmgr->component, true); } } } @@ -608,11 +609,11 @@ EXPORT_SYMBOL(wcd_resmgr_disable_clk_block); * wcd_resmgr_init: initialize wcd resource manager * @core_res: handle to struct wcd9xxx_core_resource * - * Early init call without a handle to snd_soc_codec * + * Early init call without a handle to snd_soc_component * */ struct wcd9xxx_resmgr_v2 *wcd_resmgr_init( struct wcd9xxx_core_resource *core_res, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { struct wcd9xxx_resmgr_v2 *resmgr; struct wcd9xxx *wcd9xxx; @@ -634,7 +635,7 @@ struct wcd9xxx_resmgr_v2 *wcd_resmgr_init( resmgr->clk_mclk_users = 0; resmgr->clk_rco_users = 0; resmgr->master_bias_users = 0; - resmgr->codec = codec; + resmgr->component = component; resmgr->core_res = core_res; resmgr->sido_input_src = SIDO_SOURCE_INTERNAL; resmgr->codec_type = wcd9xxx->type; @@ -658,24 +659,24 @@ EXPORT_SYMBOL(wcd_resmgr_remove); * wcd_resmgr_post_init: post init call to assign codec handle * @resmgr: handle to struct wcd9xxx_resmgr_v2 created during early init * @resmgr_cb: codec callback function for resmgr - * @codec: handle to struct snd_soc_codec + * @component: handle to struct snd_soc_component */ int wcd_resmgr_post_init(struct wcd9xxx_resmgr_v2 *resmgr, const struct wcd_resmgr_cb *resmgr_cb, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { if (!resmgr) { pr_err("%s: resmgr not allocated\n", __func__); return -EINVAL; } - if (!codec) { + if (!component) { pr_err("%s: Codec memory is NULL, nothing to post init\n", __func__); return -EINVAL; } - resmgr->codec = codec; + resmgr->component = component; resmgr->resmgr_cb = resmgr_cb; return 0; diff --git a/asoc/codecs/wcd9xxx-resmgr-v2.h b/asoc/codecs/wcd9xxx-resmgr-v2.h index d1aeb04cec8f..8eceb8392d04 100644 --- a/asoc/codecs/wcd9xxx-resmgr-v2.h +++ b/asoc/codecs/wcd9xxx-resmgr-v2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #ifndef __WCD9XXX_COMMON_V2_H__ #define __WCD9XXX_COMMON_V2_H__ @@ -20,11 +20,11 @@ enum { }; struct wcd_resmgr_cb { - int (*cdc_rco_ctrl)(struct snd_soc_codec *, bool); + int (*cdc_rco_ctrl)(struct snd_soc_component *component, bool enable); }; struct wcd9xxx_resmgr_v2 { - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct wcd9xxx_core_resource *core_res; int master_bias_users; @@ -66,11 +66,11 @@ int wcd_resmgr_enable_master_bias(struct wcd9xxx_resmgr_v2 *resmgr); int wcd_resmgr_disable_master_bias(struct wcd9xxx_resmgr_v2 *resmgr); struct wcd9xxx_resmgr_v2 *wcd_resmgr_init( struct wcd9xxx_core_resource *core_res, - struct snd_soc_codec *codec); + struct snd_soc_component *component); void wcd_resmgr_remove(struct wcd9xxx_resmgr_v2 *resmgr); int wcd_resmgr_post_init(struct wcd9xxx_resmgr_v2 *resmgr, const struct wcd_resmgr_cb *resmgr_cb, - struct snd_soc_codec *codec); + struct snd_soc_component *component); int wcd_resmgr_enable_clk_block(struct wcd9xxx_resmgr_v2 *resmgr, enum wcd_clock_type type); int wcd_resmgr_disable_clk_block(struct wcd9xxx_resmgr_v2 *resmgr, diff --git a/asoc/codecs/wcd9xxx-utils.h b/asoc/codecs/wcd9xxx-utils.h index 048c61c232cc..17bb9fd1750b 100644 --- a/asoc/codecs/wcd9xxx-utils.h +++ b/asoc/codecs/wcd9xxx-utils.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ #ifndef __WCD9XXX_UTILS_H__ @@ -20,10 +20,10 @@ int wcd9xxx_reset(struct device *dev); int wcd9xxx_reset_low(struct device *dev); int wcd9xxx_get_codec_info(struct device *dev); -typedef int (*codec_bringup_fn)(struct wcd9xxx *); -typedef int (*codec_bringdown_fn)(struct wcd9xxx *); -typedef int (*codec_type_fn)(struct wcd9xxx *, - struct wcd9xxx_codec_type *); +typedef int (*codec_bringup_fn)(struct wcd9xxx *dev); +typedef int (*codec_bringdown_fn)(struct wcd9xxx *dev); +typedef int (*codec_type_fn)(struct wcd9xxx *dev, + struct wcd9xxx_codec_type *wcd_type); codec_bringdown_fn wcd9xxx_bringdown_fn(int type); codec_bringup_fn wcd9xxx_bringup_fn(int type); diff --git a/asoc/codecs/wcd_cpe_core.c b/asoc/codecs/wcd_cpe_core.c index 1fa6eae59863..00a384369c07 100644 --- a/asoc/codecs/wcd_cpe_core.c +++ b/asoc/codecs/wcd_cpe_core.c @@ -92,7 +92,7 @@ struct cpe_lsm_ids { static struct wcd_cpe_core *core_d; static struct cpe_lsm_session *lsm_sessions[WCD_CPE_LSM_MAX_SESSIONS + 1]; -struct wcd_cpe_core * (*wcd_get_cpe_core)(struct snd_soc_codec *); +struct wcd_cpe_core * (*wcd_get_cpe_core)(struct snd_soc_component *component); static struct wcd_cmi_afe_port_data afe_ports[WCD_CPE_AFE_MAX_PORTS + 1]; static void wcd_cpe_svc_event_cb(const struct cpe_svc_notification *param); static int wcd_cpe_setup_irqs(struct wcd_cpe_core *core); @@ -370,7 +370,7 @@ static int wcd_cpe_enable_cpe_clks(struct wcd_cpe_core *core, bool enable) return -EINVAL; } - ret = core->cpe_cdc_cb->cdc_clk_en(core->codec, enable); + ret = core->cpe_cdc_cb->cdc_clk_en(core->component, enable); if (ret) { dev_err(core->dev, "%s: Failed to enable RCO\n", __func__); @@ -385,7 +385,7 @@ static int wcd_cpe_enable_cpe_clks(struct wcd_cpe_core *core, bool enable) * and be disabled at the last time. */ if (core->cpe_clk_ref == 0) { - ret = core->cpe_cdc_cb->cpe_clk_en(core->codec, enable); + ret = core->cpe_cdc_cb->cpe_clk_en(core->component, enable); if (ret) { dev_err(core->dev, "%s: cpe_clk_en() failed, err = %d\n", @@ -402,7 +402,7 @@ static int wcd_cpe_enable_cpe_clks(struct wcd_cpe_core *core, bool enable) cpe_clk_fail: /* Release the codec clk if CPE clk enable failed */ if (enable) { - ret1 = core->cpe_cdc_cb->cdc_clk_en(core->codec, !enable); + ret1 = core->cpe_cdc_cb->cdc_clk_en(core->component, !enable); if (ret1) dev_err(core->dev, "%s: Fail to release codec clk, err = %d\n", @@ -434,7 +434,7 @@ static int wcd_cpe_bus_vote_max_bw(struct wcd_cpe_core *core, if (core->cpe_cdc_cb->bus_vote_bw) { dev_dbg(core->dev, "%s: %s cdc bus max bandwidth\n", __func__, vote ? "Vote" : "Unvote"); - core->cpe_cdc_cb->bus_vote_bw(core->codec, vote); + core->cpe_cdc_cb->bus_vote_bw(core->component, vote); } return 0; @@ -454,7 +454,7 @@ static int wcd_cpe_load_fw(struct wcd_cpe_core *core, { int ret, phdr_idx; - struct snd_soc_codec *codec = NULL; + struct snd_soc_component *component = NULL; struct wcd9xxx *wcd9xxx = NULL; const struct elf32_hdr *ehdr; const struct elf32_phdr *phdr; @@ -469,8 +469,8 @@ static int wcd_cpe_load_fw(struct wcd_cpe_core *core, core); return -EINVAL; } - codec = core->codec; - wcd9xxx = dev_get_drvdata(codec->dev->parent); + component = core->component; + wcd9xxx = dev_get_drvdata(component->dev->parent); snprintf(mdt_name, sizeof(mdt_name), "%s.mdt", core->fname); ret = request_firmware(&fw, mdt_name, core->dev); if (ret < 0) { @@ -617,32 +617,32 @@ static void wcd_cpe_load_fw_image(struct work_struct *work) /* * wcd_cpe_get_core_handle: get the handle to wcd_cpe_core - * @codec: codec from which this handle is to be obtained + * @component: codec from which this handle is to be obtained * Codec driver should provide a callback function to obtain * handle to wcd_cpe_core during initialization of wcd_cpe_core */ void *wcd_cpe_get_core_handle( - struct snd_soc_codec *codec) + struct snd_soc_component *component) { struct wcd_cpe_core *core = NULL; - if (!codec) { + if (!component) { pr_err("%s: Invalid codec handle\n", __func__); goto done; } if (!wcd_get_cpe_core) { - dev_err(codec->dev, + dev_err(component->dev, "%s: codec callback not available\n", __func__); goto done; } - core = wcd_get_cpe_core(codec); + core = wcd_get_cpe_core(component); if (!core) - dev_err(codec->dev, + dev_err(component->dev, "%s: handle to core not available\n", __func__); done: @@ -1018,7 +1018,7 @@ static void wcd_cpe_ssr_work(struct work_struct *work) if (core->ssr_type == WCD_CPE_SSR_EVENT) { if (CPE_ERR_IRQ_CB(core)) core->cpe_cdc_cb->cpe_err_irq_control( - core->codec, + core->component, CPE_ERR_IRQ_STATUS, &status); if (status & core->irq_info.cpe_fatal_irqs) @@ -1080,7 +1080,7 @@ static void wcd_cpe_ssr_work(struct work_struct *work) * error interrupts are cleared */ if (CPE_ERR_IRQ_CB(core)) - core->cpe_cdc_cb->cpe_err_irq_control(core->codec, + core->cpe_cdc_cb->cpe_err_irq_control(core->component, CPE_ERR_IRQ_CLEAR, NULL); err_ret: @@ -1178,7 +1178,7 @@ static irqreturn_t svass_exception_irq(int irq, void *data) return IRQ_HANDLED; } - core->cpe_cdc_cb->cpe_err_irq_control(core->codec, + core->cpe_cdc_cb->cpe_err_irq_control(core->component, CPE_ERR_IRQ_STATUS, &status); while (status != 0) { @@ -1198,18 +1198,18 @@ static irqreturn_t svass_exception_irq(int irq, void *data) * Mask the interrupt that was raised to * avoid spurious interrupts */ - core->cpe_cdc_cb->cpe_err_irq_control(core->codec, + core->cpe_cdc_cb->cpe_err_irq_control(core->component, CPE_ERR_IRQ_MASK, &status); /* Clear only the interrupt that was raised */ - core->cpe_cdc_cb->cpe_err_irq_control(core->codec, + core->cpe_cdc_cb->cpe_err_irq_control(core->component, CPE_ERR_IRQ_CLEAR, &status); dev_err(core->dev, "%s: err_interrupt status = 0x%x\n", __func__, status); /* Read status for pending interrupts */ - core->cpe_cdc_cb->cpe_err_irq_control(core->codec, + core->cpe_cdc_cb->cpe_err_irq_control(core->component, CPE_ERR_IRQ_STATUS, &status); } @@ -1329,7 +1329,7 @@ static void wcd_cpe_deinitialize_afe_port_data(void) */ static void wcd_cpe_svc_event_cb(const struct cpe_svc_notification *param) { - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct wcd_cpe_core *core; struct cpe_svc_boot_event *boot_data; bool active_sessions; @@ -1339,14 +1339,14 @@ static void wcd_cpe_svc_event_cb(const struct cpe_svc_notification *param) return; } - codec = param->private_data; - if (!codec) { + component = param->private_data; + if (!component) { pr_err("%s: Invalid handle to codec\n", __func__); return; } - core = wcd_cpe_get_core_handle(codec); + core = wcd_cpe_get_core_handle(component); if (!core) { pr_err("%s: Invalid handle to core\n", __func__); @@ -1422,8 +1422,8 @@ static void wcd_cpe_svc_event_cb(const struct cpe_svc_notification *param) static void wcd_cpe_cleanup_irqs(struct wcd_cpe_core *core) { - struct snd_soc_codec *codec = core->codec; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct snd_soc_component *component = core->component; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; wcd9xxx_free_irq(core_res, @@ -1444,8 +1444,8 @@ static void wcd_cpe_cleanup_irqs(struct wcd_cpe_core *core) static int wcd_cpe_setup_irqs(struct wcd_cpe_core *core) { int ret; - struct snd_soc_codec *codec = core->codec; - struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent); + struct snd_soc_component *component = core->component; + struct wcd9xxx *wcd9xxx = dev_get_drvdata(component->dev->parent); struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res; ret = wcd9xxx_request_irq(core_res, @@ -1461,14 +1461,14 @@ static int wcd_cpe_setup_irqs(struct wcd_cpe_core *core) /* Make sure all error interrupts are cleared */ if (CPE_ERR_IRQ_CB(core)) core->cpe_cdc_cb->cpe_err_irq_control( - core->codec, + core->component, CPE_ERR_IRQ_CLEAR, NULL); /* Enable required error interrupts */ if (CPE_ERR_IRQ_CB(core)) core->cpe_cdc_cb->cpe_err_irq_control( - core->codec, + core->component, CPE_ERR_IRQ_UNMASK, NULL); @@ -1854,27 +1854,27 @@ static ssize_t cpe_ftm_test_trigger(struct file *file, } static int wcd_cpe_validate_params( - struct snd_soc_codec *codec, + struct snd_soc_component *component, struct wcd_cpe_params *params) { - if (!codec) { + if (!component) { pr_err("%s: Invalid codec\n", __func__); return -EINVAL; } if (!params) { - dev_err(codec->dev, + dev_err(component->dev, "%s: No params supplied for codec %s\n", - __func__, codec->component.name); + __func__, component->name); return -EINVAL; } - if (!params->codec || !params->get_cpe_core || + if (!params->component || !params->get_cpe_core || !params->cdc_cb) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Invalid params for codec %s\n", - __func__, codec->component.name); + __func__, component->name); return -EINVAL; } @@ -1884,14 +1884,14 @@ static int wcd_cpe_validate_params( /* * wcd_cpe_init: Initialize CPE related structures * @img_fname: filename for firmware image - * @codec: handle to codec requesting for image download + * @component: handle to codec requesting for image download * @params: parameter structure passed from caller * * This API will initialize the cpe core but will not * download the image or boot the cpe core. */ struct wcd_cpe_core *wcd_cpe_init(const char *img_fname, - struct snd_soc_codec *codec, + struct snd_soc_component *component, struct wcd_cpe_params *params) { struct wcd_cpe_core *core; @@ -1904,7 +1904,7 @@ struct wcd_cpe_core *wcd_cpe_init(const char *img_fname, const struct cpe_svc_hw_cfg *hw_info; int id = 0; - if (wcd_cpe_validate_params(codec, params)) + if (wcd_cpe_validate_params(component, params)) return NULL; core = kzalloc(sizeof(struct wcd_cpe_core), GFP_KERNEL); @@ -1916,8 +1916,8 @@ struct wcd_cpe_core *wcd_cpe_init(const char *img_fname, wcd_get_cpe_core = params->get_cpe_core; - core->codec = params->codec; - core->dev = params->codec->dev; + core->component = params->component; + core->dev = params->component->dev; core->cpe_debug_mode = params->dbg_mode; core->cdc_info.major_version = params->cdc_major_ver; @@ -1969,7 +1969,7 @@ struct wcd_cpe_core *wcd_cpe_init(const char *img_fname, goto fail_cpe_register; } - card = codec->component.card->snd_card; + card = component->card->snd_card; snprintf(proc_name, (sizeof("cpe") + sizeof("_state") + sizeof(id) - 2), "%s%d%s", cpe_name, id, state_name); entry = snd_info_create_card_entry(card, proc_name, @@ -3248,10 +3248,10 @@ static int wcd_cpe_lsm_get_afe_out_port_id(void *core_handle, struct cpe_lsm_session *session) { struct wcd_cpe_core *core = core_handle; - struct snd_soc_codec *codec; + struct snd_soc_component *component; int rc = 0; - if (!core || !core->codec) { + if (!core || !core->component) { pr_err("%s: Invalid handle to %s\n", __func__, (!core) ? "core" : "codec"); @@ -3275,8 +3275,8 @@ static int wcd_cpe_lsm_get_afe_out_port_id(void *core_handle, goto done; } - codec = core->codec; - rc = core->cpe_cdc_cb->get_afe_out_port_id(codec, + component = core->component; + rc = core->cpe_cdc_cb->get_afe_out_port_id(component, &session->afe_out_port_id); if (rc) { dev_err(core->dev, @@ -3667,11 +3667,11 @@ static int wcd_cpe_lab_ch_setup(void *core_handle, enum wcd_cpe_event event) { struct wcd_cpe_core *core = core_handle; - struct snd_soc_codec *codec; + struct snd_soc_component *component; int rc = 0; u8 cpe_intr_bits; - if (!core || !core->codec) { + if (!core || !core->component) { pr_err("%s: Invalid handle to %s\n", __func__, (!core) ? "core" : "codec"); @@ -3689,14 +3689,14 @@ static int wcd_cpe_lab_ch_setup(void *core_handle, goto done; } - codec = core->codec; + component = core->component; dev_dbg(core->dev, "%s: event = 0x%x\n", __func__, event); switch (event) { case WCD_CPE_PRE_ENABLE: - rc = core->cpe_cdc_cb->cdc_ext_clk(codec, true, false); + rc = core->cpe_cdc_cb->cdc_ext_clk(component, true, false); if (rc) { dev_err(core->dev, "%s: failed to enable cdc clk, err = %d\n", @@ -3704,13 +3704,14 @@ static int wcd_cpe_lab_ch_setup(void *core_handle, goto done; } - rc = core->cpe_cdc_cb->lab_cdc_ch_ctl(codec, + rc = core->cpe_cdc_cb->lab_cdc_ch_ctl(component, true); if (rc) { dev_err(core->dev, "%s: failed to enable cdc port, err = %d\n", __func__, rc); - rc = core->cpe_cdc_cb->cdc_ext_clk(codec, false, false); + rc = core->cpe_cdc_cb->cdc_ext_clk( + component, false, false); goto done; } @@ -3731,11 +3732,11 @@ static int wcd_cpe_lab_ch_setup(void *core_handle, cpe_intr_bits = ~(core->irq_info.cpe_fatal_irqs & 0xFF); if (CPE_ERR_IRQ_CB(core)) core->cpe_cdc_cb->cpe_err_irq_control( - core->codec, + core->component, CPE_ERR_IRQ_MASK, &cpe_intr_bits); - rc = core->cpe_cdc_cb->lab_cdc_ch_ctl(codec, + rc = core->cpe_cdc_cb->lab_cdc_ch_ctl(component, false); if (rc) dev_err(core->dev, @@ -3757,7 +3758,7 @@ static int wcd_cpe_lab_ch_setup(void *core_handle, "%s: Failed to disable lab\n", __func__); /* Continue with disabling even if toggle lab fails */ - rc = core->cpe_cdc_cb->cdc_ext_clk(codec, false, false); + rc = core->cpe_cdc_cb->cdc_ext_clk(component, false, false); if (rc) dev_err(core->dev, "%s: failed to disable cdc clk, err = %d\n", @@ -3767,7 +3768,7 @@ static int wcd_cpe_lab_ch_setup(void *core_handle, cpe_intr_bits = ~(core->irq_info.cpe_fatal_irqs & 0xFF); if (CPE_ERR_IRQ_CB(core)) core->cpe_cdc_cb->cpe_err_irq_control( - core->codec, + core->component, CPE_ERR_IRQ_UNMASK, &cpe_intr_bits); break; @@ -3907,7 +3908,7 @@ static int wcd_cpe_lsm_set_port(void *core_handle, /* * wcd_cpe_get_lsm_ops: register lsm driver to codec * @lsm_ops: structure with lsm callbacks - * @codec: codec to which this lsm driver is registered to + * @component: codec to which this lsm driver is registered to */ int wcd_cpe_get_lsm_ops(struct wcd_cpe_lsm_ops *lsm_ops) { diff --git a/asoc/codecs/wcd_cpe_core.h b/asoc/codecs/wcd_cpe_core.h index ad2ff106abc5..105ece0a97f3 100644 --- a/asoc/codecs/wcd_cpe_core.h +++ b/asoc/codecs/wcd_cpe_core.h @@ -50,18 +50,20 @@ enum cpe_err_irq_cntl_type { struct wcd_cpe_cdc_cb { /* codec provided callback to enable RCO */ - int (*cdc_clk_en)(struct snd_soc_codec *, bool); + int (*cdc_clk_en)(struct snd_soc_component *cpmponent, bool enable); /* callback for FLL setup for codec */ - int (*cpe_clk_en)(struct snd_soc_codec *, bool); - int (*cdc_ext_clk)(struct snd_soc_codec *codec, int enable, bool dapm); - int (*lab_cdc_ch_ctl)(struct snd_soc_codec *codec, u8 event); - int (*get_afe_out_port_id)(struct snd_soc_codec *codec, u16 *port_id); - int (*bus_vote_bw)(struct snd_soc_codec *codec, + int (*cpe_clk_en)(struct snd_soc_component *component, bool enable); + int (*cdc_ext_clk)(struct snd_soc_component *component, int enable, + bool dapm); + int (*lab_cdc_ch_ctl)(struct snd_soc_component *component, u8 event); + int (*get_afe_out_port_id)(struct snd_soc_component *component, + u16 *port_id); + int (*bus_vote_bw)(struct snd_soc_component *component, bool vote); /* Callback to control the cpe error interrupt mask/status/clear */ - int (*cpe_err_irq_control)(struct snd_soc_codec *codec, + int (*cpe_err_irq_control)(struct snd_soc_component *component, enum cpe_err_irq_cntl_type cntl_type, u8 *status); }; @@ -114,7 +116,7 @@ struct wcd_cpe_core { void *cmi_afe_handle; /* handle to codec */ - struct snd_soc_codec *codec; + struct snd_soc_component *component; /* codec device */ struct device *dev; @@ -200,9 +202,9 @@ struct wcd_cpe_core { }; struct wcd_cpe_params { - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct wcd_cpe_core * (*get_cpe_core)( - struct snd_soc_codec *); + struct snd_soc_component *component); const struct wcd_cpe_cdc_cb *cdc_cb; int dbg_mode; u16 cdc_major_ver; @@ -218,7 +220,7 @@ struct wcd_cpe_params { int wcd_cpe_ssr_event(void *core_handle, enum wcd_cpe_ssr_state_event event); struct wcd_cpe_core *wcd_cpe_init(const char *img_fname, -struct snd_soc_codec *codec, struct wcd_cpe_params *params); +struct snd_soc_component *component, struct wcd_cpe_params *params); #else /* CONFIG_SND_SOC_WCD_CPE */ static inline int wcd_cpe_ssr_event(void *core_handle, enum wcd_cpe_ssr_state_event event) @@ -226,8 +228,8 @@ static inline int wcd_cpe_ssr_event(void *core_handle, return 0; } static inline struct wcd_cpe_core *wcd_cpe_init(const char *img_fname, - struct snd_soc_codec *codec, - struct wcd_cpe_params *params) + struct snd_soc_component *component, + struct wcd_cpe_params *params) { return NULL; } diff --git a/asoc/codecs/wcdcal-hwdep.c b/asoc/codecs/wcdcal-hwdep.c index 9c5d0e2962b4..162c40746a02 100644 --- a/asoc/codecs/wcdcal-hwdep.c +++ b/asoc/codecs/wcdcal-hwdep.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved. * */ #include @@ -152,7 +152,8 @@ static int wcdcal_hwdep_release(struct snd_hwdep *hw, struct file *file) return 0; } -int wcd_cal_create_hwdep(void *data, int node, struct snd_soc_codec *codec) +int wcd_cal_create_hwdep(void *data, int node, + struct snd_soc_component *component) { char hwname[40]; struct snd_hwdep *hwdep; @@ -160,23 +161,23 @@ int wcd_cal_create_hwdep(void *data, int node, struct snd_soc_codec *codec) struct fw_info *fw_data = data; int err, cal_bit; - if (!fw_data || !codec) { + if (!fw_data || !component) { pr_err("%s: wrong arguments passed\n", __func__); return -EINVAL; } fw = fw_data->fw; snprintf(hwname, strlen("Codec %s"), "Codec %s", - codec->component.name); - err = snd_hwdep_new(codec->component.card->snd_card, + component->name); + err = snd_hwdep_new(component->card->snd_card, hwname, node, &hwdep); if (err < 0) { - dev_err(codec->dev, "%s: new hwdep failed %d\n", + dev_err(component->dev, "%s: new hwdep failed %d\n", __func__, err); return err; } snprintf(hwdep->name, strlen("Codec %s"), "Codec %s", - codec->component.name); + component->name); hwdep->iface = SNDRV_HWDEP_IFACE_AUDIO_CODEC; hwdep->private_data = fw_data; hwdep->ops.ioctl_compat = wcdcal_hwdep_ioctl_compat; @@ -188,11 +189,8 @@ int wcd_cal_create_hwdep(void *data, int node, struct snd_soc_codec *codec) set_bit(WCDCAL_UNINITIALISED, &fw_data->wcdcal_state[cal_bit]); fw[cal_bit] = kzalloc(sizeof *(fw[cal_bit]), GFP_KERNEL); - if (!fw[cal_bit]) { - dev_err(codec->dev, "%s: no memory for %s cal\n", - __func__, cal_name_info[cal_bit]); + if (!fw[cal_bit]) goto end; - } } for_each_set_bit(cal_bit, fw_data->cal_bit, WCD9XXX_MAX_CAL) { fw[cal_bit]->data = kzalloc(cal_size_info[cal_bit], diff --git a/asoc/codecs/wcdcal-hwdep.h b/asoc/codecs/wcdcal-hwdep.h index 05f1c48e265b..9606cd577f16 100644 --- a/asoc/codecs/wcdcal-hwdep.h +++ b/asoc/codecs/wcdcal-hwdep.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2014, 2018, The Linux Foundation. All rights reserved. */ #ifndef __WCD9XXX_HWDEP_H__ #define __WCD9XXX_HWDEP_H__ @@ -26,7 +26,8 @@ struct firmware_cal { }; struct snd_soc_codec; -int wcd_cal_create_hwdep(void *fw, int node, struct snd_soc_codec *codec); +int wcd_cal_create_hwdep(void *fw, int node, + struct snd_soc_component *component); struct firmware_cal *wcdcal_get_fw_cal(struct fw_info *fw_data, enum wcd_cal_type type); #endif /* __WCD9XXX_HWDEP_H__ */ diff --git a/asoc/codecs/wsa881x-temp-sensor.c b/asoc/codecs/wsa881x-temp-sensor.c index 5f6840d1f88c..598449c13986 100644 --- a/asoc/codecs/wsa881x-temp-sensor.c +++ b/asoc/codecs/wsa881x-temp-sensor.c @@ -30,7 +30,7 @@ int wsa881x_get_temp(struct thermal_zone_device *thermal, int *temp) { struct wsa881x_tz_priv *pdata; - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct wsa_temp_register reg; int dmeas, d1, d2; int ret = 0; @@ -44,8 +44,8 @@ int wsa881x_get_temp(struct thermal_zone_device *thermal, if (thermal->devdata) { pdata = thermal->devdata; - if (pdata->codec) { - codec = pdata->codec; + if (pdata->component) { + component = pdata->component; } else { pr_err("%s: codec is NULL\n", __func__); return -EINVAL; @@ -70,7 +70,7 @@ int wsa881x_get_temp(struct thermal_zone_device *thermal, temp_retry: if (pdata->wsa_temp_reg_read) { - ret = pdata->wsa_temp_reg_read(codec, ®); + ret = pdata->wsa_temp_reg_read(component, ®); if (ret) { pr_err("%s: temp read failed: %d, current temp: %d\n", __func__, ret, pdata->curr_temp); diff --git a/asoc/codecs/wsa881x-temp-sensor.h b/asoc/codecs/wsa881x-temp-sensor.h index 0d61c99fa2d5..7c9052615d85 100644 --- a/asoc/codecs/wsa881x-temp-sensor.h +++ b/asoc/codecs/wsa881x-temp-sensor.h @@ -15,11 +15,11 @@ struct wsa_temp_register { u8 dmeas_msb; u8 dmeas_lsb; }; -typedef int32_t (*wsa_temp_register_read)(struct snd_soc_codec *codec, +typedef int32_t (*wsa_temp_register_read)(struct snd_soc_component *component, struct wsa_temp_register *wsa_temp_reg); struct wsa881x_tz_priv { struct thermal_zone_device *tz_dev; - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct wsa_temp_register *wsa_temp_reg; char name[80]; wsa_temp_register_read wsa_temp_reg_read; diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index 238430cc0522..da33494e0f5f 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -28,6 +28,7 @@ #include "wsa881x.h" #include "wsa881x-temp-sensor.h" +#define DRV_NAME "wsa-codec" #define WSA881X_NUM_RETRY 5 enum { @@ -80,7 +81,7 @@ struct wsa881x_priv { struct regmap *regmap; struct device *dev; struct swr_device *swr_slave; - struct snd_soc_codec *codec; + struct snd_soc_component *component; bool comp_enable; bool boost_enable; bool visense_enable; @@ -127,7 +128,7 @@ static struct dentry *debugfs_reg_dump; static unsigned int read_data; static unsigned int devnum; -static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec, +static int32_t wsa881x_resource_acquire(struct snd_soc_component *component, bool enable); static const char * const wsa_pa_gain_text[] = { @@ -142,12 +143,14 @@ static const struct soc_enum wsa_pa_gain_enum = static int wsa_pa_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = wsa881x->pa_gain; - dev_dbg(codec->dev, "%s: PA gain = 0x%x\n", __func__, wsa881x->pa_gain); + dev_dbg(component->dev, "%s: PA gain = 0x%x\n", __func__, + wsa881x->pa_gain); return 0; } @@ -155,10 +158,11 @@ static int wsa_pa_gain_get(struct snd_kcontrol *kcontrol, static int wsa_pa_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); wsa881x->pa_gain = ucontrol->value.integer.value[0]; @@ -170,8 +174,9 @@ static int wsa881x_get_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = wsa881x->pa_mute; @@ -181,15 +186,17 @@ static int wsa881x_get_mute(struct snd_kcontrol *kcontrol, static int wsa881x_set_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); int value = ucontrol->value.integer.value[0]; - dev_dbg(codec->dev, "%s: mute current %d, new %d\n", + dev_dbg(component->dev, "%s: mute current %d, new %d\n", __func__, wsa881x->pa_mute, value); if (value) - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, 0x80, 0x00); + snd_soc_component_update_bits(component, WSA881X_SPKR_DRV_EN, + 0x80, 0x00); wsa881x->pa_mute = value; return 0; @@ -199,12 +206,13 @@ static int wsa881x_get_t0_init(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); struct wsa881x_tz_priv *pdata = &wsa881x->tz_pdata; ucontrol->value.integer.value[0] = pdata->t0_init; - dev_dbg(codec->dev, "%s: t0 init %d\n", __func__, pdata->t0_init); + dev_dbg(component->dev, "%s: t0 init %d\n", __func__, pdata->t0_init); return 0; } @@ -212,12 +220,13 @@ static int wsa881x_get_t0_init(struct snd_kcontrol *kcontrol, static int wsa881x_set_t0_init(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); struct wsa881x_tz_priv *pdata = &wsa881x->tz_pdata; pdata->t0_init = ucontrol->value.integer.value[0]; - dev_dbg(codec->dev, "%s: t0 init %d\n", __func__, pdata->t0_init); + dev_dbg(component->dev, "%s: t0 init %d\n", __func__, pdata->t0_init); return 0; } @@ -286,7 +295,7 @@ static struct snd_info_entry_ops wsa881x_codec_info_ops = { /* * wsa881x_codec_info_create_codec_entry - creates wsa881x module * @codec_root: The parent directory - * @codec: Codec instance + * @component: Codec instance * * Creates wsa881x module and version entry under the given * parent directory. @@ -294,18 +303,18 @@ static struct snd_info_entry_ops wsa881x_codec_info_ops = { * Return: 0 on success or negative error code on failure. */ int wsa881x_codec_info_create_codec_entry(struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { struct snd_info_entry *version_entry; struct wsa881x_priv *wsa881x; struct snd_soc_card *card; char name[80]; - if (!codec_root || !codec) + if (!codec_root || !component) return -EINVAL; - wsa881x = snd_soc_codec_get_drvdata(codec); - card = codec->component.card; + wsa881x = snd_soc_component_get_drvdata(component); + card = component->card; snprintf(name, sizeof(name), "%s.%x", "wsa881x", (u32)wsa881x->swr_slave->addr); @@ -313,7 +322,7 @@ int wsa881x_codec_info_create_codec_entry(struct snd_info_entry *codec_root, (const char *)name, codec_root); if (!wsa881x->entry) { - dev_dbg(codec->dev, "%s: failed to create wsa881x entry\n", + dev_dbg(component->dev, "%s: failed to create wsa881x entry\n", __func__); return -ENOMEM; } @@ -322,7 +331,7 @@ int wsa881x_codec_info_create_codec_entry(struct snd_info_entry *codec_root, "version", wsa881x->entry); if (!version_entry) { - dev_dbg(codec->dev, "%s: failed to create wsa881x version entry\n", + dev_dbg(component->dev, "%s: failed to create wsa881x version entry\n", __func__); return -ENOMEM; } @@ -530,13 +539,15 @@ static const struct reg_sequence wsa881x_vi_txfe_en_2_0[] = { {WSA881X_SPKR_PROT_FE_GAIN, 0x47, 0}, }; -static int wsa881x_boost_ctrl(struct snd_soc_codec *codec, bool enable) +static int wsa881x_boost_ctrl(struct snd_soc_component *component, bool enable) { - dev_dbg(codec->dev, "%s: enable:%d\n", __func__, enable); + dev_dbg(component->dev, "%s: enable:%d\n", __func__, enable); if (enable) - snd_soc_update_bits(codec, WSA881X_BOOST_EN_CTL, 0x80, 0x80); + snd_soc_component_update_bits(component, WSA881X_BOOST_EN_CTL, + 0x80, 0x80); else - snd_soc_update_bits(codec, WSA881X_BOOST_EN_CTL, 0x80, 0x00); + snd_soc_component_update_bits(component, WSA881X_BOOST_EN_CTL, + 0x80, 0x00); /* * 1.5ms sleep is needed after boost enable/disable as per * HW requirement @@ -545,13 +556,13 @@ static int wsa881x_boost_ctrl(struct snd_soc_codec *codec, bool enable) return 0; } -static int wsa881x_visense_txfe_ctrl(struct snd_soc_codec *codec, bool enable, - u8 isense1_gain, u8 isense2_gain, - u8 vsense_gain) +static int wsa881x_visense_txfe_ctrl(struct snd_soc_component *component, + bool enable, u8 isense1_gain, + u8 isense2_gain, u8 vsense_gain) { - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); - dev_dbg(codec->dev, + dev_dbg(component->dev, "%s: enable:%d, isense1 gain: %d, isense2 gain: %d, vsense_gain %d\n", __func__, enable, isense1_gain, isense2_gain, vsense_gain); @@ -560,79 +571,91 @@ static int wsa881x_visense_txfe_ctrl(struct snd_soc_codec *codec, bool enable, wsa881x_vi_txfe_en_2_0, ARRAY_SIZE(wsa881x_vi_txfe_en_2_0)); } else { - snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_VSENSE_VCM, - 0x08, 0x08); + snd_soc_component_update_bits(component, + WSA881X_SPKR_PROT_FE_VSENSE_VCM, + 0x08, 0x08); /* * 200us sleep is needed after visense txfe disable as per * HW requirement. */ usleep_range(200, 210); - snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_GAIN, - 0x01, 0x00); + snd_soc_component_update_bits(component, + WSA881X_SPKR_PROT_FE_GAIN, + 0x01, 0x00); } return 0; } -static int wsa881x_visense_adc_ctrl(struct snd_soc_codec *codec, bool enable) +static int wsa881x_visense_adc_ctrl(struct snd_soc_component *component, + bool enable) { - dev_dbg(codec->dev, "%s: enable:%d\n", __func__, enable); - snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_V, (0x01 << 7), - (enable << 7)); - snd_soc_update_bits(codec, WSA881X_ADC_EN_MODU_I, (0x01 << 7), - (enable << 7)); + dev_dbg(component->dev, "%s: enable:%d\n", __func__, enable); + snd_soc_component_update_bits(component, WSA881X_ADC_EN_MODU_V, + (0x01 << 7), (enable << 7)); + snd_soc_component_update_bits(component, WSA881X_ADC_EN_MODU_I, + (0x01 << 7), (enable << 7)); return 0; } -static void wsa881x_bandgap_ctrl(struct snd_soc_codec *codec, bool enable) +static void wsa881x_bandgap_ctrl(struct snd_soc_component *component, + bool enable) { - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); - dev_dbg(codec->dev, "%s: enable:%d, bg_count:%d\n", __func__, + dev_dbg(component->dev, "%s: enable:%d, bg_count:%d\n", __func__, enable, wsa881x->bg_cnt); mutex_lock(&wsa881x->bg_lock); if (enable) { ++wsa881x->bg_cnt; if (wsa881x->bg_cnt == 1) { - snd_soc_update_bits(codec, WSA881X_TEMP_OP, - 0x08, 0x08); + snd_soc_component_update_bits(component, + WSA881X_TEMP_OP, + 0x08, 0x08); /* 400usec sleep is needed as per HW requirement */ usleep_range(400, 410); - snd_soc_update_bits(codec, WSA881X_TEMP_OP, - 0x04, 0x04); + snd_soc_component_update_bits(component, + WSA881X_TEMP_OP, + 0x04, 0x04); } } else { --wsa881x->bg_cnt; if (wsa881x->bg_cnt <= 0) { WARN_ON(wsa881x->bg_cnt < 0); wsa881x->bg_cnt = 0; - snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x00); - snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x08, 0x00); + snd_soc_component_update_bits(component, + WSA881X_TEMP_OP, 0x04, 0x00); + snd_soc_component_update_bits(component, + WSA881X_TEMP_OP, 0x08, 0x00); } } mutex_unlock(&wsa881x->bg_lock); } -static void wsa881x_clk_ctrl(struct snd_soc_codec *codec, bool enable) +static void wsa881x_clk_ctrl(struct snd_soc_component *component, bool enable) { - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); - dev_dbg(codec->dev, "%s: enable:%d, clk_count:%d\n", __func__, + dev_dbg(component->dev, "%s: enable:%d, clk_count:%d\n", __func__, enable, wsa881x->clk_cnt); mutex_lock(&wsa881x->res_lock); if (enable) { ++wsa881x->clk_cnt; if (wsa881x->clk_cnt == 1) { - snd_soc_write(codec, WSA881X_CDC_DIG_CLK_CTL, 0x01); - snd_soc_write(codec, WSA881X_CDC_ANA_CLK_CTL, 0x01); + snd_soc_component_write(component, + WSA881X_CDC_DIG_CLK_CTL, 0x01); + snd_soc_component_write(component, + WSA881X_CDC_ANA_CLK_CTL, 0x01); } } else { --wsa881x->clk_cnt; if (wsa881x->clk_cnt <= 0) { WARN_ON(wsa881x->clk_cnt < 0); wsa881x->clk_cnt = 0; - snd_soc_write(codec, WSA881X_CDC_DIG_CLK_CTL, 0x00); - snd_soc_write(codec, WSA881X_CDC_ANA_CLK_CTL, 0x00); + snd_soc_component_write(component, + WSA881X_CDC_DIG_CLK_CTL, 0x00); + snd_soc_component_write(component, + WSA881X_CDC_ANA_CLK_CTL, 0x00); } } mutex_unlock(&wsa881x->res_lock); @@ -642,8 +665,9 @@ static int wsa881x_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = wsa881x->comp_enable; return 0; @@ -652,11 +676,12 @@ static int wsa881x_get_compander(struct snd_kcontrol *kcontrol, static int wsa881x_set_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); int value = ucontrol->value.integer.value[0]; - dev_dbg(codec->dev, "%s: Compander enable current %d, new %d\n", + dev_dbg(component->dev, "%s: Compander enable current %d, new %d\n", __func__, wsa881x->comp_enable, value); wsa881x->comp_enable = value; return 0; @@ -666,8 +691,9 @@ static int wsa881x_get_boost(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = wsa881x->boost_enable; return 0; @@ -676,11 +702,12 @@ static int wsa881x_get_boost(struct snd_kcontrol *kcontrol, static int wsa881x_set_boost(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); int value = ucontrol->value.integer.value[0]; - dev_dbg(codec->dev, "%s: Boost enable current %d, new %d\n", + dev_dbg(component->dev, "%s: Boost enable current %d, new %d\n", __func__, wsa881x->boost_enable, value); wsa881x->boost_enable = value; return 0; @@ -690,8 +717,9 @@ static int wsa881x_get_visense(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); ucontrol->value.integer.value[0] = wsa881x->visense_enable; return 0; @@ -700,11 +728,12 @@ static int wsa881x_get_visense(struct snd_kcontrol *kcontrol, static int wsa881x_set_visense(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); int value = ucontrol->value.integer.value[0]; - dev_dbg(codec->dev, "%s: VIsense enable current %d, new %d\n", + dev_dbg(component->dev, "%s: VIsense enable current %d, new %d\n", __func__, wsa881x->visense_enable, value); wsa881x->visense_enable = value; return 0; @@ -713,14 +742,15 @@ static int wsa881x_set_visense(struct snd_kcontrol *kcontrol, static int wsa881x_set_boost_level(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); u8 wsa_boost_level = 0; - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); wsa_boost_level = ucontrol->value.integer.value[0]; - snd_soc_update_bits(codec, WSA881X_BOOST_PRESET_OUT1, + snd_soc_component_update_bits(component, WSA881X_BOOST_PRESET_OUT1, 0xff, wsa_boost_level); return 0; @@ -729,12 +759,14 @@ static int wsa881x_set_boost_level(struct snd_kcontrol *kcontrol, static int wsa881x_get_boost_level(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); u8 wsa_boost_level = 0; - wsa_boost_level = snd_soc_read(codec, WSA881X_BOOST_PRESET_OUT1); + wsa_boost_level = snd_soc_component_read32(component, + WSA881X_BOOST_PRESET_OUT1); ucontrol->value.integer.value[0] = wsa_boost_level; - dev_dbg(codec->dev, "%s: boost level = 0x%x\n", __func__, + dev_dbg(component->dev, "%s: boost level = 0x%x\n", __func__, wsa_boost_level); return 0; @@ -758,11 +790,11 @@ static const struct snd_kcontrol_new swr_dac_port[] = { SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) }; -static int wsa881x_set_port(struct snd_soc_codec *codec, int port_idx, +static int wsa881x_set_port(struct snd_soc_component *component, int port_idx, u8 *port_id, u8 *num_ch, u8 *ch_mask, u32 *ch_rate, u8 *port_type) { - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); *port_id = wsa881x->port[port_idx].port_id; *num_ch = wsa881x->port[port_idx].num_ch; @@ -775,8 +807,9 @@ static int wsa881x_set_port(struct snd_soc_codec *codec, int port_idx, static int wsa881x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); u8 port_id[WSA881X_MAX_SWR_PORTS]; u8 num_ch[WSA881X_MAX_SWR_PORTS]; u8 ch_mask[WSA881X_MAX_SWR_PORTS]; @@ -784,35 +817,35 @@ static int wsa881x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, u8 port_type[WSA881X_MAX_SWR_PORTS]; u8 num_port = 0; - dev_dbg(codec->dev, "%s: event %d name %s\n", __func__, + dev_dbg(component->dev, "%s: event %d name %s\n", __func__, event, w->name); if (wsa881x == NULL) return -EINVAL; switch (event) { case SND_SOC_DAPM_PRE_PMU: - wsa881x_set_port(codec, SWR_DAC_PORT, + wsa881x_set_port(component, SWR_DAC_PORT, &port_id[num_port], &num_ch[num_port], &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; if (wsa881x->comp_enable) { - wsa881x_set_port(codec, SWR_COMP_PORT, + wsa881x_set_port(component, SWR_COMP_PORT, &port_id[num_port], &num_ch[num_port], &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; } if (wsa881x->boost_enable) { - wsa881x_set_port(codec, SWR_BOOST_PORT, + wsa881x_set_port(component, SWR_BOOST_PORT, &port_id[num_port], &num_ch[num_port], &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; } if (wsa881x->visense_enable) { - wsa881x_set_port(codec, SWR_VISENSE_PORT, + wsa881x_set_port(component, SWR_VISENSE_PORT, &port_id[num_port], &num_ch[num_port], &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); @@ -827,28 +860,28 @@ static int wsa881x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMD: break; case SND_SOC_DAPM_POST_PMD: - wsa881x_set_port(codec, SWR_DAC_PORT, + wsa881x_set_port(component, SWR_DAC_PORT, &port_id[num_port], &num_ch[num_port], &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; if (wsa881x->comp_enable) { - wsa881x_set_port(codec, SWR_COMP_PORT, + wsa881x_set_port(component, SWR_COMP_PORT, &port_id[num_port], &num_ch[num_port], &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; } if (wsa881x->boost_enable) { - wsa881x_set_port(codec, SWR_BOOST_PORT, + wsa881x_set_port(component, SWR_BOOST_PORT, &port_id[num_port], &num_ch[num_port], &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); ++num_port; } if (wsa881x->visense_enable) { - wsa881x_set_port(codec, SWR_VISENSE_PORT, + wsa881x_set_port(component, SWR_VISENSE_PORT, &port_id[num_port], &num_ch[num_port], &ch_mask[num_port], &ch_rate[num_port], &port_type[num_port]); @@ -866,40 +899,41 @@ static int wsa881x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, static int wsa881x_rdac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); - dev_dbg(codec->dev, "%s: %s %d boost %d visense %d\n", __func__, + dev_dbg(component->dev, "%s: %s %d boost %d visense %d\n", __func__, w->name, event, wsa881x->boost_enable, wsa881x->visense_enable); switch (event) { case SND_SOC_DAPM_PRE_PMU: mutex_lock(&wsa881x->temp_lock); - wsa881x_resource_acquire(codec, ENABLE); + wsa881x_resource_acquire(component, ENABLE); mutex_unlock(&wsa881x->temp_lock); - wsa881x_boost_ctrl(codec, ENABLE); + wsa881x_boost_ctrl(component, ENABLE); break; case SND_SOC_DAPM_POST_PMD: swr_slvdev_datapath_control(wsa881x->swr_slave, wsa881x->swr_slave->dev_num, false); - wsa881x_boost_ctrl(codec, DISABLE); + wsa881x_boost_ctrl(component, DISABLE); mutex_lock(&wsa881x->temp_lock); - wsa881x_resource_acquire(codec, DISABLE); + wsa881x_resource_acquire(component, DISABLE); mutex_unlock(&wsa881x->temp_lock); break; } return 0; } -static int wsa881x_ramp_pa_gain(struct snd_soc_codec *codec, +static int wsa881x_ramp_pa_gain(struct snd_soc_component *component, int min_gain, int max_gain, int udelay) { int val; for (val = min_gain; max_gain <= val; val--) { - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, + snd_soc_component_update_bits(component, WSA881X_SPKR_DRV_GAIN, 0xF0, val << 4); /* * 1ms delay is needed for every step change in gain as per @@ -914,20 +948,22 @@ static void wsa881x_ocp_ctl_work(struct work_struct *work) { struct wsa881x_priv *wsa881x; struct delayed_work *dwork; - struct snd_soc_codec *codec; + struct snd_soc_component *component; int temp_val; dwork = to_delayed_work(work); wsa881x = container_of(dwork, struct wsa881x_priv, ocp_ctl_work); - codec = wsa881x->codec; + component = wsa881x->component; wsa881x_get_temp(wsa881x->tz_pdata.tz_dev, &temp_val); - dev_dbg(codec->dev, " temp = %d\n", temp_val); + dev_dbg(component->dev, " temp = %d\n", temp_val); if (temp_val <= WSA881X_OCP_CTL_TEMP_CELSIUS) - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0x00); + snd_soc_component_update_bits(component, WSA881X_SPKR_OCP_CTL, + 0xC0, 0x00); else - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0); + snd_soc_component_update_bits(component, WSA881X_SPKR_OCP_CTL, + 0xC0, 0xC0); schedule_delayed_work(&wsa881x->ocp_ctl_work, msecs_to_jiffies(wsa881x_ocp_poll_timer_sec * 1000)); @@ -936,14 +972,16 @@ static void wsa881x_ocp_ctl_work(struct work_struct *work) static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); int min_gain, max_gain; - dev_dbg(codec->dev, "%s: %s %d\n", __func__, w->name, event); + dev_dbg(component->dev, "%s: %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0x80); + snd_soc_component_update_bits(component, WSA881X_SPKR_OCP_CTL, + 0xC0, 0x80); regmap_multi_reg_write(wsa881x->regmap, wsa881x_pre_pmu_pa_2_0, ARRAY_SIZE(wsa881x_pre_pmu_pa_2_0)); @@ -952,11 +990,13 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, true); /* Set register mode if compander is not enabled */ if (!wsa881x->comp_enable) - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, - 0x08, 0x08); + snd_soc_component_update_bits(component, + WSA881X_SPKR_DRV_GAIN, + 0x08, 0x08); else - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, - 0x08, 0x00); + snd_soc_component_update_bits(component, + WSA881X_SPKR_DRV_GAIN, + 0x08, 0x00); break; case SND_SOC_DAPM_POST_PMU: @@ -975,14 +1015,16 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, * as per HW requirement. */ usleep_range(1000, 1010); - wsa881x_ramp_pa_gain(codec, min_gain, max_gain, 1000); + wsa881x_ramp_pa_gain(component, min_gain, max_gain, + 1000); } if (wsa881x->visense_enable) { - wsa881x_visense_txfe_ctrl(codec, ENABLE, + wsa881x_visense_txfe_ctrl(component, ENABLE, 0x00, 0x03, 0x01); - snd_soc_update_bits(codec, WSA881X_ADC_EN_SEL_IBAIS, - 0x07, 0x01); - wsa881x_visense_adc_ctrl(codec, ENABLE); + snd_soc_component_update_bits(component, + WSA881X_ADC_EN_SEL_IBAIS, + 0x07, 0x01); + wsa881x_visense_adc_ctrl(component, ENABLE); } schedule_delayed_work(&wsa881x->ocp_ctl_work, msecs_to_jiffies(WSA881X_OCP_CTL_TIMER_SEC * 1000)); @@ -992,12 +1034,13 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: if (wsa881x->visense_enable) { - wsa881x_visense_adc_ctrl(codec, DISABLE); - wsa881x_visense_txfe_ctrl(codec, DISABLE, + wsa881x_visense_adc_ctrl(component, DISABLE); + wsa881x_visense_txfe_ctrl(component, DISABLE, 0x00, 0x01, 0x01); } cancel_delayed_work_sync(&wsa881x->ocp_ctl_work); - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0); + snd_soc_component_update_bits(component, WSA881X_SPKR_OCP_CTL, + 0xC0, 0xC0); break; } return 0; @@ -1029,16 +1072,16 @@ static const struct snd_soc_dapm_route wsa881x_audio_map[] = { {"SPKR", NULL, "SPKR PGA"}, }; -int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, u8 num_port, - unsigned int *ch_mask, unsigned int *ch_rate, - u8 *port_type) +int wsa881x_set_channel_map(struct snd_soc_component *component, u8 *port, + u8 num_port, unsigned int *ch_mask, + unsigned int *ch_rate, u8 *port_type) { - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); int i; if (!port || !ch_mask || !ch_rate || (num_port > WSA881X_MAX_SWR_PORTS)) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Invalid port=%pK, ch_mask=%pK, ch_rate=%pK\n", __func__, port, ch_mask, ch_rate); return -EINVAL; @@ -1055,70 +1098,91 @@ int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, u8 num_port, } EXPORT_SYMBOL(wsa881x_set_channel_map); -static void wsa881x_init(struct snd_soc_codec *codec) +static void wsa881x_init(struct snd_soc_component *component) { - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); - wsa881x->version = snd_soc_read(codec, WSA881X_CHIP_ID1); + wsa881x->version = + snd_soc_component_read32(component, WSA881X_CHIP_ID1); wsa881x_regmap_defaults(wsa881x->regmap, wsa881x->version); /* Enable software reset output from soundwire slave */ - snd_soc_update_bits(codec, WSA881X_SWR_RESET_EN, 0x07, 0x07); + snd_soc_component_update_bits(component, WSA881X_SWR_RESET_EN, + 0x07, 0x07); /* Bring out of analog reset */ - snd_soc_update_bits(codec, WSA881X_CDC_RST_CTL, 0x02, 0x02); + snd_soc_component_update_bits(component, WSA881X_CDC_RST_CTL, + 0x02, 0x02); /* Bring out of digital reset */ - snd_soc_update_bits(codec, WSA881X_CDC_RST_CTL, 0x01, 0x01); - - snd_soc_update_bits(codec, WSA881X_CLOCK_CONFIG, 0x10, 0x10); - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0x02, 0x02); - snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL1, 0xC0, 0x80); - snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL1, 0x06, 0x06); - snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_INT, 0xFF, 0x00); - snd_soc_update_bits(codec, WSA881X_SPKR_PA_INT, 0xF0, 0x40); - snd_soc_update_bits(codec, WSA881X_SPKR_PA_INT, 0x0E, 0x0E); - snd_soc_update_bits(codec, WSA881X_BOOST_LOOP_STABILITY, - 0x03, 0x03); - snd_soc_update_bits(codec, WSA881X_BOOST_MISC2_CTL, 0xFF, 0x14); - snd_soc_update_bits(codec, WSA881X_BOOST_START_CTL, 0x80, 0x80); - snd_soc_update_bits(codec, WSA881X_BOOST_START_CTL, 0x03, 0x00); - snd_soc_update_bits(codec, WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, - 0x0C, 0x04); - snd_soc_update_bits(codec, WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, - 0x03, 0x00); - if (snd_soc_read(codec, WSA881X_OTP_REG_0)) - snd_soc_update_bits(codec, WSA881X_BOOST_PRESET_OUT1, - 0xF0, 0x70); - snd_soc_update_bits(codec, WSA881X_BOOST_PRESET_OUT2, - 0xF0, 0x30); - snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, 0x08, 0x08); - snd_soc_update_bits(codec, WSA881X_BOOST_CURRENT_LIMIT, - 0x0F, 0x08); - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0x30, 0x30); - snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0x0C, 0x00); - snd_soc_update_bits(codec, WSA881X_OTP_REG_28, 0x3F, 0x3A); - snd_soc_update_bits(codec, WSA881X_BONGO_RESRV_REG1, - 0xFF, 0xB2); - snd_soc_update_bits(codec, WSA881X_BONGO_RESRV_REG2, - 0xFF, 0x05); + snd_soc_component_update_bits(component, WSA881X_CDC_RST_CTL, + 0x01, 0x01); + + snd_soc_component_update_bits(component, WSA881X_CLOCK_CONFIG, + 0x10, 0x10); + snd_soc_component_update_bits(component, WSA881X_SPKR_OCP_CTL, + 0x02, 0x02); + snd_soc_component_update_bits(component, WSA881X_SPKR_MISC_CTL1, + 0xC0, 0x80); + snd_soc_component_update_bits(component, WSA881X_SPKR_MISC_CTL1, + 0x06, 0x06); + snd_soc_component_update_bits(component, WSA881X_SPKR_BIAS_INT, + 0xFF, 0x00); + snd_soc_component_update_bits(component, WSA881X_SPKR_PA_INT, + 0xF0, 0x40); + snd_soc_component_update_bits(component, WSA881X_SPKR_PA_INT, + 0x0E, 0x0E); + snd_soc_component_update_bits(component, WSA881X_BOOST_LOOP_STABILITY, + 0x03, 0x03); + snd_soc_component_update_bits(component, WSA881X_BOOST_MISC2_CTL, + 0xFF, 0x14); + snd_soc_component_update_bits(component, WSA881X_BOOST_START_CTL, + 0x80, 0x80); + snd_soc_component_update_bits(component, WSA881X_BOOST_START_CTL, + 0x03, 0x00); + snd_soc_component_update_bits(component, + WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, + 0x0C, 0x04); + snd_soc_component_update_bits(component, + WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, + 0x03, 0x00); + if (snd_soc_component_read32(component, WSA881X_OTP_REG_0)) + snd_soc_component_update_bits(component, + WSA881X_BOOST_PRESET_OUT1, + 0xF0, 0x70); + snd_soc_component_update_bits(component, WSA881X_BOOST_PRESET_OUT2, + 0xF0, 0x30); + snd_soc_component_update_bits(component, WSA881X_SPKR_DRV_EN, + 0x08, 0x08); + snd_soc_component_update_bits(component, WSA881X_BOOST_CURRENT_LIMIT, + 0x0F, 0x08); + snd_soc_component_update_bits(component, WSA881X_SPKR_OCP_CTL, + 0x30, 0x30); + snd_soc_component_update_bits(component, WSA881X_SPKR_OCP_CTL, + 0x0C, 0x00); + snd_soc_component_update_bits(component, WSA881X_OTP_REG_28, + 0x3F, 0x3A); + snd_soc_component_update_bits(component, WSA881X_BONGO_RESRV_REG1, + 0xFF, 0xB2); + snd_soc_component_update_bits(component, WSA881X_BONGO_RESRV_REG2, + 0xFF, 0x05); } -static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec, +static int32_t wsa881x_resource_acquire(struct snd_soc_component *component, bool enable) { - wsa881x_clk_ctrl(codec, enable); - wsa881x_bandgap_ctrl(codec, enable); + wsa881x_clk_ctrl(component, enable); + wsa881x_bandgap_ctrl(component, enable); return 0; } -static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec, +static int32_t wsa881x_temp_reg_read(struct snd_soc_component *component, struct wsa_temp_register *wsa_temp_reg) { - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); struct swr_device *dev; u8 retry = WSA881X_NUM_RETRY; u8 devnum = 0; if (!wsa881x) { - dev_err(codec->dev, "%s: wsa881x is NULL\n", __func__); + dev_err(component->dev, "%s: wsa881x is NULL\n", __func__); return -EINVAL; } dev = wsa881x->swr_slave; @@ -1129,7 +1193,7 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec, usleep_range(1000, 1100); } if (retry == 0) { - dev_err(codec->dev, + dev_err(component->dev, "%s get devnum %d for dev addr %lx failed\n", __func__, devnum, dev->addr); return -EINVAL; @@ -1137,81 +1201,78 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec, } wsa881x_regcache_sync(wsa881x); mutex_lock(&wsa881x->temp_lock); - wsa881x_resource_acquire(codec, ENABLE); - - snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x00); - wsa_temp_reg->dmeas_msb = snd_soc_read(codec, WSA881X_TEMP_MSB); - wsa_temp_reg->dmeas_lsb = snd_soc_read(codec, WSA881X_TEMP_LSB); - snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x01); - wsa_temp_reg->d1_msb = snd_soc_read(codec, WSA881X_OTP_REG_1); - wsa_temp_reg->d1_lsb = snd_soc_read(codec, WSA881X_OTP_REG_2); - wsa_temp_reg->d2_msb = snd_soc_read(codec, WSA881X_OTP_REG_3); - wsa_temp_reg->d2_lsb = snd_soc_read(codec, WSA881X_OTP_REG_4); - - wsa881x_resource_acquire(codec, DISABLE); + wsa881x_resource_acquire(component, ENABLE); + + snd_soc_component_update_bits(component, WSA881X_TADC_VALUE_CTL, + 0x01, 0x00); + wsa_temp_reg->dmeas_msb = snd_soc_component_read32( + component, WSA881X_TEMP_MSB); + wsa_temp_reg->dmeas_lsb = snd_soc_component_read32( + component, WSA881X_TEMP_LSB); + snd_soc_component_update_bits(component, WSA881X_TADC_VALUE_CTL, + 0x01, 0x01); + wsa_temp_reg->d1_msb = snd_soc_component_read32( + component, WSA881X_OTP_REG_1); + wsa_temp_reg->d1_lsb = snd_soc_component_read32( + component, WSA881X_OTP_REG_2); + wsa_temp_reg->d2_msb = snd_soc_component_read32( + component, WSA881X_OTP_REG_3); + wsa_temp_reg->d2_lsb = snd_soc_component_read32( + component, WSA881X_OTP_REG_4); + + wsa881x_resource_acquire(component, DISABLE); mutex_unlock(&wsa881x->temp_lock); return 0; } -static int wsa881x_probe(struct snd_soc_codec *codec) +static int wsa881x_probe(struct snd_soc_component *component) { - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); struct swr_device *dev; if (!wsa881x) return -EINVAL; + snd_soc_component_init_regmap(component, wsa881x->regmap); dev = wsa881x->swr_slave; - wsa881x->codec = codec; + wsa881x->component = component; mutex_init(&wsa881x->bg_lock); - wsa881x_init(codec); + wsa881x_init(component); snprintf(wsa881x->tz_pdata.name, sizeof(wsa881x->tz_pdata.name), "%s.%x", "wsatz", (u8)dev->addr); wsa881x->bg_cnt = 0; wsa881x->clk_cnt = 0; - wsa881x->tz_pdata.codec = codec; + wsa881x->tz_pdata.component = component; wsa881x->tz_pdata.wsa_temp_reg_read = wsa881x_temp_reg_read; wsa881x_init_thermal(&wsa881x->tz_pdata); - snd_soc_add_codec_controls(codec, wsa_snd_controls, + snd_soc_add_component_controls(component, wsa_snd_controls, ARRAY_SIZE(wsa_snd_controls)); INIT_DELAYED_WORK(&wsa881x->ocp_ctl_work, wsa881x_ocp_ctl_work); return 0; } -static int wsa881x_remove(struct snd_soc_codec *codec) +static void wsa881x_remove(struct snd_soc_component *component) { - struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); + struct wsa881x_priv *wsa881x = snd_soc_component_get_drvdata(component); if (wsa881x->tz_pdata.tz_dev) wsa881x_deinit_thermal(wsa881x->tz_pdata.tz_dev); mutex_destroy(&wsa881x->bg_lock); - return 0; + return; } -static struct regmap *wsa881x_get_regmap(struct device *dev) -{ - struct wsa881x_priv *control = swr_get_dev_data(to_swr_device(dev)); - - if (!control) - return NULL; - - return control->regmap; -} - -static struct snd_soc_codec_driver soc_codec_dev_wsa881x = { +static const struct snd_soc_component_driver soc_codec_dev_wsa881x = { + .name = DRV_NAME, .probe = wsa881x_probe, .remove = wsa881x_remove, - .get_regmap = wsa881x_get_regmap, - .component_driver = { - .controls = wsa881x_snd_controls, - .num_controls = ARRAY_SIZE(wsa881x_snd_controls), - .dapm_widgets = wsa881x_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(wsa881x_dapm_widgets), - .dapm_routes = wsa881x_audio_map, - .num_dapm_routes = ARRAY_SIZE(wsa881x_audio_map), - }, + .controls = wsa881x_snd_controls, + .num_controls = ARRAY_SIZE(wsa881x_snd_controls), + .dapm_widgets = wsa881x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wsa881x_dapm_widgets), + .dapm_routes = wsa881x_audio_map, + .num_dapm_routes = ARRAY_SIZE(wsa881x_audio_map), }; static int wsa881x_gpio_ctrl(struct wsa881x_priv *wsa881x, bool enable) @@ -1361,7 +1422,7 @@ static int wsa881x_swr_probe(struct swr_device *pdev) goto dev_err; } - ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wsa881x, + ret = snd_soc_register_component(&pdev->dev, &soc_codec_dev_wsa881x, NULL, 0); if (ret) { dev_err(&pdev->dev, "%s: Codec registration failed\n", @@ -1394,7 +1455,7 @@ static int wsa881x_swr_remove(struct swr_device *pdev) debugfs_wsa881x_dent = NULL; mutex_destroy(&wsa881x->res_lock); mutex_destroy(&wsa881x->temp_lock); - snd_soc_unregister_codec(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); if (wsa881x->pd_gpio) gpio_free(wsa881x->pd_gpio); swr_set_dev_data(pdev, NULL); diff --git a/asoc/codecs/wsa881x.h b/asoc/codecs/wsa881x.h index ae30d4bd3736..3922fc835dae 100644 --- a/asoc/codecs/wsa881x.h +++ b/asoc/codecs/wsa881x.h @@ -13,28 +13,28 @@ #define WSA881X_MAX_SWR_PORTS 4 #if IS_ENABLED(CONFIG_SND_SOC_WSA881X) -extern int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, - u8 num_port, unsigned int *ch_mask, +extern int wsa881x_set_channel_map(struct snd_soc_component *component, + u8 *port, u8 num_port, unsigned int *ch_mask, unsigned int *ch_rate, u8 *port_type); extern const u8 wsa881x_reg_readable[WSA881X_CACHE_SIZE]; extern struct regmap_config wsa881x_regmap_config; extern int wsa881x_codec_info_create_codec_entry( struct snd_info_entry *codec_root, - struct snd_soc_codec *codec); + struct snd_soc_component *component); void wsa881x_regmap_defaults(struct regmap *regmap, u8 version); #else -extern int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, - u8 num_port, unsigned int *ch_mask, - unsigned int *ch_rate, u8 *port_type); +extern int wsa881x_set_channel_map(struct snd_soc_component *component, + u8 *port, u8 num_port, unsigned int *ch_mask, + unsigned int *ch_rate, u8 *port_type) { return 0; } extern int wsa881x_codec_info_create_codec_entry( struct snd_info_entry *codec_root, - struct snd_soc_codec *codec) + struct snd_soc_component *component) { return 0; } -- GitLab From 56a0f8f7489f9cab72e73e5a449afade43c30fe1 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 6 Sep 2018 18:17:30 +0800 Subject: [PATCH 0681/1645] ASoC: update machine driver for kernel-4.19 snd_soc_codec is removed from kernel-4.19. Update machine driver to fix compile error. Change-Id: I1bdfda07c0d150d008c434c361142b655de1e9db Signed-off-by: Meng Wang --- asoc/qcs405.c | 194 ++++++++------- asoc/sm6150.c | 238 ++++++++++-------- asoc/sm8150.c | 670 ++++++++++++++------------------------------------ 3 files changed, 431 insertions(+), 671 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 4d1de74b3746..d0cba849784c 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -191,7 +191,7 @@ struct msm_asoc_mach_data { }; struct msm_asoc_wcd93xx_codec { - void* (*get_afe_config_fn)(struct snd_soc_codec *codec, + void* (*get_afe_config_fn)(struct snd_soc_component *component, enum afe_config_type config_type); }; @@ -610,7 +610,7 @@ static struct snd_soc_aux_dev *msm_aux_dev; static struct snd_soc_codec_conf *msm_codec_conf; static struct msm_asoc_wcd93xx_codec msm_codec_fn; -static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, +static int msm_snd_enable_codec_ext_clk(struct snd_soc_component *component, int enable, bool dapm); static int msm_wsa881x_init(struct snd_soc_component *component); static int msm_snd_vad_cfg_put(struct snd_kcontrol *kcontrol, @@ -3773,30 +3773,30 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_spdif_tx_format_get, msm_spdif_tx_format_put), }; -static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, +static int msm_snd_enable_codec_ext_clk(struct snd_soc_component *component, int enable, bool dapm) { int ret = 0; - if (!strcmp(dev_name(codec->dev), "tasha_codec")) { - ret = tasha_cdc_mclk_enable(codec, enable, dapm); + if (!strcmp(component.name, "tasha_codec")) { + ret = tasha_cdc_mclk_enable(component, enable, dapm); } else { - dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", + dev_err(component->dev, "%s: unknown codec to enable ext clk\n", __func__); ret = -EINVAL; } return ret; } -static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, +static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_component *component, int enable, bool dapm) { int ret = 0; - if (!strcmp(dev_name(codec->dev), "tasha_codec")) { - ret = tasha_cdc_mclk_tx_enable(codec, enable, dapm); + if (!strcmp(component.name, "tasha_codec")) { + ret = tasha_cdc_mclk_tx_enable(component, enable, dapm); } else { - dev_err(codec->dev, "%s: unknown codec to enable TX ext clk\n", + dev_err(component->dev, "%s: unknown codec to enable TX ext clk\n", __func__); ret = -EINVAL; } @@ -3807,15 +3807,16 @@ static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, static int msm_mclk_tx_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); pr_debug("%s: event = %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - return msm_snd_enable_codec_ext_tx_clk(codec, 1, true); + return msm_snd_enable_codec_ext_tx_clk(component, 1, true); case SND_SOC_DAPM_POST_PMD: - return msm_snd_enable_codec_ext_tx_clk(codec, 0, true); + return msm_snd_enable_codec_ext_tx_clk(component, 0, true); } return 0; } @@ -3823,15 +3824,16 @@ static int msm_mclk_tx_event(struct snd_soc_dapm_widget *w, static int msm_mclk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); pr_debug("%s: event = %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - return msm_snd_enable_codec_ext_clk(codec, 1, true); + return msm_snd_enable_codec_ext_clk(component, 1, true); case SND_SOC_DAPM_POST_PMD: - return msm_snd_enable_codec_ext_clk(codec, 0, true); + return msm_snd_enable_codec_ext_clk(component, 0, true); } return 0; } @@ -3854,7 +3856,8 @@ static int msm_dmic_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct msm_asoc_mach_data *pdata = NULL; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); int ret = 0; uint32_t dmic_idx; int *dmic_gpio_cnt; @@ -3863,18 +3866,18 @@ static int msm_dmic_event(struct snd_soc_dapm_widget *w, wname = strpbrk(w->name, "01234567"); if (!wname) { - dev_err(codec->dev, "%s: widget not found\n", __func__); + dev_err(component->dev, "%s: widget not found\n", __func__); return -EINVAL; } ret = kstrtouint(wname, 10, &dmic_idx); if (ret < 0) { - dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n", + dev_err(component->dev, "%s: Invalid DMIC line on the codec\n", __func__); return -EINVAL; } - pdata = snd_soc_card_get_drvdata(codec->component.card); + pdata = snd_soc_card_get_drvdata(component->card); switch (dmic_idx) { case 0: @@ -3898,12 +3901,12 @@ static int msm_dmic_event(struct snd_soc_dapm_widget *w, dmic_gpio = pdata->dmic_67_gpio_p; break; default: - dev_err(codec->dev, "%s: Invalid DMIC Selection\n", + dev_err(component->dev, "%s: Invalid DMIC Selection\n", __func__); return -EINVAL; } - dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_gpio_cnt %d\n", + dev_dbg(component->dev, "%s: event %d DMIC%d dmic_gpio_cnt %d\n", __func__, event, dmic_idx, *dmic_gpio_cnt); switch (event) { @@ -3913,7 +3916,7 @@ static int msm_dmic_event(struct snd_soc_dapm_widget *w, ret = msm_cdc_pinctrl_select_active_state( dmic_gpio); if (ret < 0) { - dev_err(codec->dev, "%s: gpio set cannot be activated %sd\n", + dev_err(component->dev, "%s: gpio set cannot be activated %sd\n", __func__, "dmic_gpio"); return ret; } @@ -3925,14 +3928,14 @@ static int msm_dmic_event(struct snd_soc_dapm_widget *w, ret = msm_cdc_pinctrl_select_sleep_state( dmic_gpio); if (ret < 0) { - dev_err(codec->dev, "%s: gpio set cannot be de-activated %sd\n", + dev_err(component->dev, "%s: gpio set cannot be de-activated %sd\n", __func__, "dmic_gpio"); return ret; } } break; default: - dev_err(codec->dev, "%s: invalid DAPM event %d\n", + dev_err(component->dev, "%s: invalid DAPM event %d\n", __func__, event); return -EINVAL; } @@ -4087,7 +4090,7 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, int rc = 0; int idx; void *config = NULL; - struct snd_soc_codec *codec = NULL; + struct snd_soc_component *component = NULL; pr_debug("%s: format = %d, rate = %d\n", __func__, params_format(params), params_rate(params)); @@ -4137,11 +4140,16 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; case MSM_BACKEND_DAI_SLIMBUS_5_TX: - codec = rtd->codec; + component = snd_soc_rtdcom_lookup(rtd, "tasha_codec"); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + rate->min = rate->max = SAMPLING_RATE_16KHZ; channels->min = channels->max = 1; - config = msm_codec_fn.get_afe_config_fn(codec, + config = msm_codec_fn.get_afe_config_fn(component, AFE_SLIMBUS_SLAVE_PORT_CONFIG); if (config) { rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, @@ -4553,46 +4561,46 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return rc; } -static int msm_afe_set_config(struct snd_soc_codec *codec) +static int msm_afe_set_config(struct snd_soc_component *component) { int ret = 0; void *config_data = NULL; if (!msm_codec_fn.get_afe_config_fn) { - dev_err(codec->dev, "%s: codec get afe config not init'ed\n", + dev_err(component->dev, "%s: codec get afe config not init'ed\n", __func__); return -EINVAL; } - config_data = msm_codec_fn.get_afe_config_fn(codec, + config_data = msm_codec_fn.get_afe_config_fn(component, AFE_CDC_REGISTERS_CONFIG); if (config_data) { ret = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0); if (ret) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to set codec registers config %d\n", __func__, ret); return ret; } } - config_data = msm_codec_fn.get_afe_config_fn(codec, + config_data = msm_codec_fn.get_afe_config_fn(component, AFE_CDC_REGISTER_PAGE_CONFIG); if (config_data) { ret = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, 0); if (ret) - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to set cdc register page config\n", __func__); } - config_data = msm_codec_fn.get_afe_config_fn(codec, + config_data = msm_codec_fn.get_afe_config_fn(component, AFE_SLIMBUS_SLAVE_CONFIG); if (config_data) { ret = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0); if (ret) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to set slimbus slave config %d\n", __func__, ret); return ret; @@ -4608,7 +4616,7 @@ static void msm_afe_clear_config(void) afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); } -static int msm_adsp_power_up_config(struct snd_soc_codec *codec, +static int msm_adsp_power_up_config(struct snd_soc_component *component, struct snd_card *card) { int ret = 0; @@ -4650,7 +4658,7 @@ static int msm_adsp_power_up_config(struct snd_soc_codec *codec, goto err; } - ret = msm_afe_set_config(codec); + ret = msm_afe_set_config(component); if (ret) pr_err("%s: Failed to set AFE config. err %d\n", __func__, ret); @@ -4668,7 +4676,8 @@ static int qcs405_notifier_service_cb(struct notifier_block *this, struct snd_soc_card *card = NULL; const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; struct snd_soc_pcm_runtime *rtd; - struct snd_soc_codec *codec; + struct snd_soc_dai *codec_dai; + struct snd_soc_component *component; pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); @@ -4701,9 +4710,11 @@ static int qcs405_notifier_service_cb(struct notifier_block *this, ret = -EINVAL; goto err; } - codec = rtd->codec; + codec_dai = rtd->codec_dai; + if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) + component = snd_soc_rtdcom_lookup(rtd, "tasha_codec"); - ret = msm_adsp_power_up_config(codec, card->snd_card); + ret = msm_adsp_power_up_config(component, card->snd_card); if (ret < 0) { dev_err(card->dev, "%s: msm_adsp_power_up_config failed ret = %d!\n", @@ -4727,8 +4738,8 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; void *config_data; - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_component *component; + struct snd_soc_dapm_context *dapm; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_card *card; @@ -4751,7 +4762,12 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) rtd->pmdown_time = 0; - ret = snd_soc_add_codec_controls(codec, msm_snd_sb_controls, + if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) { + component = snd_soc_rtdcom_lookup(rtd, "tasha_codec"); + dapm = snd_soc_component_get_dapm(component); + } + + ret = snd_soc_add_component_controls(component, msm_snd_sb_controls, ARRAY_SIZE(msm_snd_sb_controls)); if (ret < 0) { pr_err("%s: add_codec_controls failed, err %d\n", @@ -4777,19 +4793,19 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) msm_codec_fn.get_afe_config_fn = tasha_get_afe_config; - ret = msm_adsp_power_up_config(codec, rtd->card->snd_card); + ret = msm_adsp_power_up_config(component, rtd->card->snd_card); if (ret) { - dev_err(codec->dev, "%s: Failed to set AFE config %d\n", + dev_err(component->dev, "%s: Failed to set AFE config %d\n", __func__, ret); goto err; } - config_data = msm_codec_fn.get_afe_config_fn(codec, + config_data = msm_codec_fn.get_afe_config_fn(component, AFE_AANC_VERSION); if (config_data) { ret = afe_set_config(AFE_AANC_VERSION, config_data, 0); if (ret) { - dev_err(codec->dev, "%s: Failed to set aanc version %d\n", + dev_err(component->dev, "%s: Failed to set aanc version %d\n", __func__, ret); goto err; } @@ -4805,7 +4821,7 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) ret = 0; goto err; } - tasha_codec_info_create_codec_entry(pdata->codec_root, codec); + tasha_codec_info_create_codec_entry(pdata->codec_root, component); codec_reg_done = true; return 0; @@ -4817,16 +4833,25 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) static int msm_va_cdc_dma_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_component *component; + struct snd_soc_dapm_context *dapm; struct snd_card *card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + component = snd_soc_rtdcom_lookup(rtd, "bolero_codec"); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + dapm = snd_soc_component_get_dapm(component); - ret = snd_soc_add_codec_controls(codec, msm_snd_va_controls, + ret = snd_soc_add_component_controls(component, msm_snd_va_controls, ARRAY_SIZE(msm_snd_va_controls)); if (ret < 0) { - dev_err(codec->dev, "%s: add_codec_controls for va failed, err %d\n", + dev_err(component->dev, "%s: add_component_controls for va failed, err %d\n", __func__, ret); return ret; } @@ -4855,7 +4880,7 @@ static int msm_va_cdc_dma_init(struct snd_soc_pcm_runtime *rtd) ret = 0; goto done; } - bolero_info_create_codec_entry(pdata->codec_root, codec); + bolero_info_create_codec_entry(pdata->codec_root, component); done: return ret; } @@ -4863,17 +4888,24 @@ static int msm_va_cdc_dma_init(struct snd_soc_pcm_runtime *rtd) static int msm_wsa_cdc_dma_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct snd_soc_component *aux_comp; - struct snd_card *card; + struct snd_soc_component *component = NULL; + struct snd_soc_dapm_context *dapm = NULL; + struct snd_soc_component *aux_comp = NULL; + struct snd_card *card = NULL; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); - ret = snd_soc_add_codec_controls(codec, msm_snd_wsa_controls, + component = snd_soc_rtdcom_lookup(rtd, "bolero_codec"); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + dapm = snd_soc_component_get_dapm(component); + + ret = snd_soc_add_component_controls(component, msm_snd_wsa_controls, ARRAY_SIZE(msm_snd_wsa_controls)); if (ret < 0) { - dev_err(codec->dev, "%s: add_codec_controls for wsa failed, err %d\n", + dev_err(component->dev, "%s: add_codec_controls for wsa failed, err %d\n", __func__, ret); return ret; } @@ -4891,7 +4923,7 @@ static int msm_wsa_cdc_dma_init(struct snd_soc_pcm_runtime *rtd) * Send speaker configuration only for WSA8810. * Default configuration is for WSA8815. */ - dev_dbg(codec->dev, "%s: Number of aux devices: %d\n", + dev_dbg(component->dev, "%s: Number of aux devices: %d\n", __func__, rtd->card->num_aux_devs); if (rtd->card->num_aux_devs && !list_empty(&rtd->card->component_dev_list)) { @@ -4901,9 +4933,9 @@ static int msm_wsa_cdc_dma_init(struct snd_soc_pcm_runtime *rtd) card_aux_list); if (!strcmp(aux_comp->name, WSA8810_NAME_1) || !strcmp(aux_comp->name, WSA8810_NAME_2)) { - wsa_macro_set_spkr_mode(rtd->codec, + wsa_macro_set_spkr_mode(component, WSA_MACRO_SPKR_MODE_1); - wsa_macro_set_spkr_gain_offset(rtd->codec, + wsa_macro_set_spkr_gain_offset(component, WSA_MACRO_GAIN_OFFSET_M1P5_DB); } } @@ -4912,12 +4944,12 @@ static int msm_wsa_cdc_dma_init(struct snd_soc_pcm_runtime *rtd) pdata->codec_root = snd_info_create_subdir(card->module, "codecs", card->proc_root); if (!pdata->codec_root) { - dev_dbg(codec->dev, "%s: Cannot create codecs module entry\n", + dev_dbg(component->dev, "%s: Cannot create codecs module entry\n", __func__); ret = 0; goto done; } - bolero_info_create_codec_entry(pdata->codec_root, codec); + bolero_info_create_codec_entry(pdata->codec_root, component); done: return ret; } @@ -7884,22 +7916,20 @@ static int msm_wsa881x_init(struct snd_soc_component *component) SPKR_R_BOOST, SPKR_R_VI}; unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); struct msm_asoc_mach_data *pdata; struct snd_soc_dapm_context *dapm; int ret = 0; - if (!codec) { - pr_err("%s codec is NULL\n", __func__); + if (!component) { + pr_err("%s component is NULL\n", __func__); return -EINVAL; } - - dapm = snd_soc_codec_get_dapm(codec); + dapm = snd_soc_component_get_dapm(component); if (!strcmp(component->name_prefix, "SpkrLeft")) { - dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n", - __func__, codec->component.name); - wsa881x_set_channel_map(codec, &spkleft_ports[0], + dev_dbg(component->dev, "%s: setting left ch map to codec %s\n", + __func__, component->name); + wsa881x_set_channel_map(component, &spkleft_ports[0], WSA881X_MAX_SWR_PORTS, &ch_mask[0], &ch_rate[0], &spkleft_port_types[0]); if (dapm->component) { @@ -7907,9 +7937,9 @@ static int msm_wsa881x_init(struct snd_soc_component *component) snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); } } else if (!strcmp(component->name_prefix, "SpkrRight")) { - dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n", - __func__, codec->component.name); - wsa881x_set_channel_map(codec, &spkright_ports[0], + dev_dbg(component->dev, "%s: setting right ch map to codec %s\n", + __func__, component->name); + wsa881x_set_channel_map(component, &spkright_ports[0], WSA881X_MAX_SWR_PORTS, &ch_mask[0], &ch_rate[0], &spkright_port_types[0]); if (dapm->component) { @@ -7917,15 +7947,15 @@ static int msm_wsa881x_init(struct snd_soc_component *component) snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); } } else { - dev_err(codec->dev, "%s: wrong codec name %s\n", __func__, - codec->component.name); + dev_err(component->dev, "%s: wrong codec name %s\n", __func__, + component->name); ret = -EINVAL; goto err; } pdata = snd_soc_card_get_drvdata(component->card); if (pdata && pdata->codec_root) wsa881x_codec_info_create_codec_entry(pdata->codec_root, - codec); + component); err: return ret; @@ -8120,10 +8150,8 @@ static int msm_init_wsa_dev(struct platform_device *pdev, static int msm_csra66x0_init(struct snd_soc_component *component) { - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); - - if (!codec) { - pr_err("%s codec is NULL\n", __func__); + if (!component) { + pr_err("%s component is NULL\n", __func__); return -EINVAL; } return 0; diff --git a/asoc/sm6150.c b/asoc/sm6150.c index a2abeb63731c..9fb08304c3b7 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -203,7 +203,7 @@ struct msm_asoc_mach_data { }; struct msm_asoc_wcd93xx_codec { - void* (*get_afe_config_fn)(struct snd_soc_codec *codec, + void* (*get_afe_config_fn)(struct snd_soc_component *component, enum afe_config_type config_type); }; @@ -645,7 +645,7 @@ static int dmic_0_1_gpio_cnt; static int dmic_2_3_gpio_cnt; static void *def_wcd_mbhc_cal(void); -static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, +static int msm_snd_enable_codec_ext_clk(struct snd_soc_component *component, int enable, bool dapm); static int msm_wsa881x_init(struct snd_soc_component *component); static int msm_aux_codec_init(struct snd_soc_component *component); @@ -3394,18 +3394,20 @@ static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol, return 0; } -static int msm_hifi_ctrl(struct snd_soc_codec *codec) +static int msm_hifi_ctrl(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct snd_soc_card *card = codec->component.card; + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); + struct snd_soc_card *card = component->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - dev_dbg(codec->dev, "%s: msm_hifi_control = %d\n", __func__, + dev_dbg(component->dev, "%s: msm_hifi_control = %d\n", __func__, msm_hifi_control); if (!pdata || !pdata->hph_en1_gpio_p) { - dev_err(codec->dev, "%s: hph_en1_gpio is invalid\n", __func__); + dev_err(component->dev, "%s: hph_en1_gpio is invalid\n", + __func__); return -EINVAL; } if (msm_hifi_control == MSM_HIFI_ON) { @@ -3433,13 +3435,14 @@ static int msm_hifi_get(struct snd_kcontrol *kcontrol, static int msm_hifi_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); msm_hifi_control = ucontrol->value.integer.value[0]; - msm_hifi_ctrl(codec); + msm_hifi_ctrl(component); return 0; } @@ -3831,30 +3834,30 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), }; -static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, +static int msm_snd_enable_codec_ext_clk(struct snd_soc_component *component, int enable, bool dapm) { int ret = 0; - if (!strcmp(dev_name(codec->dev), "tavil_codec")) { - ret = tavil_cdc_mclk_enable(codec, enable); + if (!strcmp(component->name, "tavil_codec")) { + ret = tavil_cdc_mclk_enable(component, enable); } else { - dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", + dev_err(component->dev, "%s: unknown codec to enable ext clk\n", __func__); ret = -EINVAL; } return ret; } -static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, +static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_component *component, int enable, bool dapm) { int ret = 0; - if (!strcmp(dev_name(codec->dev), "tavil_codec")) { - ret = tavil_cdc_mclk_tx_enable(codec, enable); + if (!strcmp(component->name, "tavil_codec")) { + ret = tavil_cdc_mclk_tx_enable(component, enable); } else { - dev_err(codec->dev, "%s: unknown codec to enable TX ext clk\n", + dev_err(component->dev, "%s: unknown codec to enable TX ext clk\n", __func__); ret = -EINVAL; } @@ -3865,15 +3868,16 @@ static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, static int msm_mclk_tx_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); pr_debug("%s: event = %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - return msm_snd_enable_codec_ext_tx_clk(codec, 1, true); + return msm_snd_enable_codec_ext_tx_clk(component, 1, true); case SND_SOC_DAPM_POST_PMD: - return msm_snd_enable_codec_ext_tx_clk(codec, 0, true); + return msm_snd_enable_codec_ext_tx_clk(component, 0, true); } return 0; } @@ -3881,15 +3885,16 @@ static int msm_mclk_tx_event(struct snd_soc_dapm_widget *w, static int msm_mclk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); pr_debug("%s: event = %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - return msm_snd_enable_codec_ext_clk(codec, 1, true); + return msm_snd_enable_codec_ext_clk(component, 1, true); case SND_SOC_DAPM_POST_PMD: - return msm_snd_enable_codec_ext_clk(codec, 0, true); + return msm_snd_enable_codec_ext_clk(component, 0, true); } return 0; } @@ -3897,21 +3902,23 @@ static int msm_mclk_event(struct snd_soc_dapm_widget *w, static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct snd_soc_card *card = codec->component.card; + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct snd_soc_card *card = component->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - dev_dbg(codec->dev, "%s: msm_hifi_control = %d\n", + dev_dbg(component->dev, "%s: msm_hifi_control = %d\n", __func__, msm_hifi_control); if (!pdata || !pdata->hph_en0_gpio_p) { - dev_err(codec->dev, "%s: hph_en0_gpio is invalid\n", __func__); + dev_err(component->dev, "%s: hph_en0_gpio is invalid\n", + __func__); return -EINVAL; } if (msm_hifi_control != MSM_HIFI_ON) { - dev_dbg(codec->dev, "%s: HiFi mixer control is not set\n", + dev_dbg(component->dev, "%s: HiFi mixer control is not set\n", __func__); return 0; } @@ -3958,7 +3965,8 @@ static int msm_dmic_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct msm_asoc_mach_data *pdata = NULL; - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); int ret = 0; u32 dmic_idx; int *dmic_gpio_cnt; @@ -3967,18 +3975,18 @@ static int msm_dmic_event(struct snd_soc_dapm_widget *w, wname = strpbrk(w->name, "0123"); if (!wname) { - dev_err(codec->dev, "%s: widget not found\n", __func__); + dev_err(component->dev, "%s: widget not found\n", __func__); return -EINVAL; } ret = kstrtouint(wname, 10, &dmic_idx); if (ret < 0) { - dev_err(codec->dev, "%s: Invalid DMIC line on the codec\n", + dev_err(component->dev, "%s: Invalid DMIC line on the codec\n", __func__); return -EINVAL; } - pdata = snd_soc_card_get_drvdata(codec->component.card); + pdata = snd_soc_card_get_drvdata(component->card); switch (dmic_idx) { case 0: @@ -3992,12 +4000,12 @@ static int msm_dmic_event(struct snd_soc_dapm_widget *w, dmic_gpio = pdata->dmic23_gpio_p; break; default: - dev_err(codec->dev, "%s: Invalid DMIC Selection\n", + dev_err(component->dev, "%s: Invalid DMIC Selection\n", __func__); return -EINVAL; } - dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_gpio_cnt %d\n", + dev_dbg(component->dev, "%s: event %d DMIC%d dmic_gpio_cnt %d\n", __func__, event, dmic_idx, *dmic_gpio_cnt); switch (event) { @@ -4184,10 +4192,12 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_soc_dai *codec_dai = rtd->codec_dai; + int rc = 0; int idx; void *config = NULL; - struct snd_soc_codec *codec = NULL; + struct snd_soc_component *component = NULL; pr_debug("%s: format = %d, rate = %d\n", __func__, params_format(params), params_rate(params)); @@ -4237,11 +4247,17 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; case MSM_BACKEND_DAI_SLIMBUS_5_TX: - codec = rtd->codec; + component = snd_soc_rtdcom_lookup(rtd, "tavil_codec"); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + rc = -EINVAL; + goto done; + } + rate->min = rate->max = SAMPLING_RATE_16KHZ; channels->min = channels->max = 1; - config = msm_codec_fn.get_afe_config_fn(codec, + config = msm_codec_fn.get_afe_config_fn(component, AFE_SLIMBUS_SLAVE_PORT_CONFIG); if (config) { rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, @@ -4597,9 +4613,10 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return rc; } -static bool msm_usbc_swap_gnd_mic(struct snd_soc_codec *codec, bool active) +static bool msm_usbc_swap_gnd_mic(struct snd_soc_component *component, + bool active) { - struct snd_soc_card *card = codec->component.card; + struct snd_soc_card *card = component->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); @@ -4609,25 +4626,25 @@ static bool msm_usbc_swap_gnd_mic(struct snd_soc_codec *codec, bool active) return fsa4480_switch_event(pdata->fsa_handle, FSA_MIC_GND_SWAP); } -static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) +static bool msm_swap_gnd_mic(struct snd_soc_component *component, bool active) { int value = 0; bool ret = false; struct snd_soc_card *card; struct msm_asoc_mach_data *pdata; - if (!codec) { - pr_err("%s codec is NULL\n", __func__); + if (!component) { + pr_err("%s component is NULL\n", __func__); return false; } - card = codec->component.card; + card = component->card; pdata = snd_soc_card_get_drvdata(card); if (!pdata) return false; if (wcd_mbhc_cfg.enable_usbc_analog) - return msm_usbc_swap_gnd_mic(codec, active); + return msm_usbc_swap_gnd_mic(component, active); /* if usbc is not defined, swap using us_euro_gpio_p */ if (pdata->us_euro_gpio_p) { @@ -4639,53 +4656,53 @@ static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) else msm_cdc_pinctrl_select_active_state( pdata->us_euro_gpio_p); - dev_dbg(codec->dev, "%s: swap select switch %d to %d\n", + dev_dbg(component->dev, "%s: swap select switch %d to %d\n", __func__, value, !value); ret = true; } return ret; } -static int msm_afe_set_config(struct snd_soc_codec *codec) +static int msm_afe_set_config(struct snd_soc_component *component) { int ret = 0; void *config_data = NULL; if (!msm_codec_fn.get_afe_config_fn) { - dev_err(codec->dev, "%s: codec get afe config not init'ed\n", + dev_err(component->dev, "%s: codec get afe config not init'ed\n", __func__); return -EINVAL; } - config_data = msm_codec_fn.get_afe_config_fn(codec, + config_data = msm_codec_fn.get_afe_config_fn(component, AFE_CDC_REGISTERS_CONFIG); if (config_data) { ret = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0); if (ret) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to set codec registers config %d\n", __func__, ret); return ret; } } - config_data = msm_codec_fn.get_afe_config_fn(codec, + config_data = msm_codec_fn.get_afe_config_fn(component, AFE_CDC_REGISTER_PAGE_CONFIG); if (config_data) { ret = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, 0); if (ret) - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to set cdc register page config\n", __func__); } - config_data = msm_codec_fn.get_afe_config_fn(codec, + config_data = msm_codec_fn.get_afe_config_fn(component, AFE_SLIMBUS_SLAVE_CONFIG); if (config_data) { ret = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0); if (ret) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to set slimbus slave config %d\n", __func__, ret); return ret; @@ -4705,12 +4722,12 @@ static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; void *config_data; - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_component *component = NULL; + struct snd_soc_dapm_context *dapm; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_component *aux_comp; - struct snd_card *card; + struct snd_card *card = rtd->card->snd_card; struct snd_info_entry *entry; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); @@ -4731,7 +4748,14 @@ static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) rtd->pmdown_time = 0; - ret = snd_soc_add_codec_controls(codec, msm_tavil_snd_controls, + component = snd_soc_rtdcom_lookup(rtd, "tavil_codec"); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + dapm = snd_soc_component_get_dapm(component); + + ret = snd_soc_add_component_controls(component, msm_tavil_snd_controls, ARRAY_SIZE(msm_tavil_snd_controls)); if (ret < 0) { pr_err("%s: add_codec_controls failed, err %d\n", @@ -4739,7 +4763,7 @@ static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = snd_soc_add_codec_controls(codec, msm_common_snd_controls, + ret = snd_soc_add_component_controls(component, msm_common_snd_controls, ARRAY_SIZE(msm_common_snd_controls)); if (ret < 0) { pr_err("%s: add_codec_controls failed, err %d\n", @@ -4788,14 +4812,14 @@ static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) msm_codec_fn.get_afe_config_fn = tavil_get_afe_config; - ret = msm_afe_set_config(codec); + ret = msm_afe_set_config(component); if (ret) { pr_err("%s: Failed to set AFE config %d\n", __func__, ret); goto err; } pdata->is_afe_config_done = true; - config_data = msm_codec_fn.get_afe_config_fn(codec, + config_data = msm_codec_fn.get_afe_config_fn(component, AFE_AANC_VERSION); if (config_data) { ret = afe_set_config(AFE_AANC_VERSION, config_data, 0); @@ -4818,8 +4842,8 @@ static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_component, card_aux_list); if (!strcmp(aux_comp->name, WSA8810_NAME_1) || !strcmp(aux_comp->name, WSA8810_NAME_2)) { - tavil_set_spkr_mode(rtd->codec, WCD934X_SPKR_MODE_1); - tavil_set_spkr_gain_offset(rtd->codec, + tavil_set_spkr_mode(component, WCD934X_SPKR_MODE_1); + tavil_set_spkr_gain_offset(component, WCD934X_RX_GAIN_OFFSET_M1P5_DB); } } @@ -4834,7 +4858,7 @@ static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) goto err; } pdata->codec_root = entry; - tavil_codec_info_create_codec_entry(pdata->codec_root, codec); + tavil_codec_info_create_codec_entry(pdata->codec_root, component); codec_reg_done = true; return 0; @@ -4845,22 +4869,30 @@ static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_component *component; + struct snd_soc_dapm_context *dapm; struct snd_card *card; struct snd_info_entry *entry; struct snd_soc_component *aux_comp; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_dai *codec_dai = rtd->codec_dai; - ret = snd_soc_add_codec_controls(codec, msm_int_snd_controls, + component = snd_soc_rtdcom_lookup(rtd, "bolero_codec"); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + dapm = snd_soc_component_get_dapm(component); + + ret = snd_soc_add_component_controls(component, msm_int_snd_controls, ARRAY_SIZE(msm_int_snd_controls)); if (ret < 0) { - pr_err("%s: add_codec_controls failed: %d\n", + pr_err("%s: add_component_controls failed: %d\n", __func__, ret); return ret; } - ret = snd_soc_add_codec_controls(codec, msm_common_snd_controls, + ret = snd_soc_add_component_controls(component, msm_common_snd_controls, ARRAY_SIZE(msm_common_snd_controls)); if (ret < 0) { pr_err("%s: add common snd controls failed: %d\n", @@ -4892,7 +4924,7 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) * Send speaker configuration only for WSA8810. * Default configuration is for WSA8815. */ - dev_dbg(codec->dev, "%s: Number of aux devices: %d\n", + dev_dbg(component->dev, "%s: Number of aux devices: %d\n", __func__, rtd->card->num_aux_devs); if (rtd->card->num_aux_devs && !list_empty(&rtd->card->component_dev_list)) { @@ -4902,9 +4934,9 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) card_aux_list); if (!strcmp(aux_comp->name, WSA8810_NAME_1) || !strcmp(aux_comp->name, WSA8810_NAME_2)) { - wsa_macro_set_spkr_mode(rtd->codec, + wsa_macro_set_spkr_mode(component, WSA_MACRO_SPKR_MODE_1); - wsa_macro_set_spkr_gain_offset(rtd->codec, + wsa_macro_set_spkr_gain_offset(component, WSA_MACRO_GAIN_OFFSET_M1P5_DB); } } @@ -4930,9 +4962,9 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) */ if (socinfo_get_id() == SM6150_SOC_MSM_ID && socinfo_get_version() == SM6150_SOC_VERSION_1_0) - bolero_register_wake_irq(codec, true); + bolero_register_wake_irq(component, true); else - bolero_register_wake_irq(codec, false); + bolero_register_wake_irq(component, false); codec_reg_done = true; return 0; @@ -7490,6 +7522,7 @@ static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) { const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; struct snd_soc_pcm_runtime *rtd; + struct snd_soc_component *component; int ret = 0; void *mbhc_calibration; @@ -7502,13 +7535,19 @@ static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) goto err_pcm_runtime; } + component = snd_soc_rtdcom_lookup(rtd, "tavil_codec"); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + ret = -EINVAL; + goto err_pcm_runtime; + } mbhc_calibration = def_wcd_mbhc_cal(); if (!mbhc_calibration) { ret = -ENOMEM; goto err_mbhc_cal; } wcd_mbhc_cfg.calibration = mbhc_calibration; - ret = tavil_mbhc_hs_detect(rtd->codec, &wcd_mbhc_cfg); + ret = tavil_mbhc_hs_detect(component, &wcd_mbhc_cfg); if (ret) { dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", __func__, ret); @@ -7613,12 +7652,13 @@ static int msm_populate_dai_link_component_of_node( static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; - struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(rtd, "msm-stub-codec"); - ret = snd_soc_add_codec_controls(codec, msm_tavil_snd_controls, + ret = snd_soc_add_component_controls(component, msm_tavil_snd_controls, ARRAY_SIZE(msm_tavil_snd_controls)); if (ret < 0) { - dev_err(codec->dev, + dev_err(component->dev, "%s: add_codec_controls failed, err = %d\n", __func__, ret); return ret; @@ -7916,24 +7956,23 @@ static int msm_wsa881x_init(struct snd_soc_component *component) SPKR_R_BOOST, SPKR_R_VI}; unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); struct msm_asoc_mach_data *pdata; struct snd_soc_dapm_context *dapm; struct snd_card *card = component->card->snd_card; struct snd_info_entry *entry; int ret = 0; - if (!codec) { + if (!component) { pr_err("%s codec is NULL\n", __func__); return -EINVAL; } - dapm = snd_soc_codec_get_dapm(codec); + dapm = snd_soc_component_get_dapm(component); if (!strcmp(component->name_prefix, "SpkrLeft")) { - dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n", - __func__, codec->component.name); - wsa881x_set_channel_map(codec, &spkleft_ports[0], + dev_dbg(component->dev, "%s: setting left ch map to codec %s\n", + __func__, component->name); + wsa881x_set_channel_map(component, &spkleft_ports[0], WSA881X_MAX_SWR_PORTS, &ch_mask[0], &ch_rate[0], &spkleft_port_types[0]); if (dapm->component) { @@ -7941,9 +7980,9 @@ static int msm_wsa881x_init(struct snd_soc_component *component) snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); } } else if (!strcmp(component->name_prefix, "SpkrRight")) { - dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n", - __func__, codec->component.name); - wsa881x_set_channel_map(codec, &spkright_ports[0], + dev_dbg(component->dev, "%s: setting right ch map to codec %s\n", + __func__, component->name); + wsa881x_set_channel_map(component, &spkright_ports[0], WSA881X_MAX_SWR_PORTS, &ch_mask[0], &ch_rate[0], &spkright_port_types[0]); if (dapm->component) { @@ -7951,8 +7990,8 @@ static int msm_wsa881x_init(struct snd_soc_component *component) snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); } } else { - dev_err(codec->dev, "%s: wrong codec name %s\n", __func__, - codec->component.name); + dev_err(component->dev, "%s: wrong codec name %s\n", __func__, + component->name); ret = -EINVAL; goto err; } @@ -7969,15 +8008,14 @@ static int msm_wsa881x_init(struct snd_soc_component *component) pdata->codec_root = entry; } wsa881x_codec_info_create_codec_entry(pdata->codec_root, - codec); + component); err: return ret; } static int msm_aux_codec_init(struct snd_soc_component *component) { - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); int ret = 0; void *mbhc_calibration; struct snd_info_entry *entry; @@ -8006,14 +8044,14 @@ static int msm_aux_codec_init(struct snd_soc_component *component) } pdata->codec_root = entry; } - wcd937x_info_create_codec_entry(pdata->codec_root, codec); + wcd937x_info_create_codec_entry(pdata->codec_root, component); codec_root_err: mbhc_calibration = def_wcd_mbhc_cal(); if (!mbhc_calibration) { return -ENOMEM; } wcd_mbhc_cfg.calibration = mbhc_calibration; - ret = wcd937x_mbhc_hs_detect(codec, &wcd_mbhc_cfg); + ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg); return ret; } @@ -8319,7 +8357,8 @@ static int sm6150_ssr_enable(struct device *dev, void *data) { struct platform_device *pdev = to_platform_device(dev); struct snd_soc_card *card = platform_get_drvdata(pdev); - struct msm_asoc_mach_data *pdata; + struct msm_asoc_mach_data *pdata = NULL; + struct snd_soc_component *component = NULL; int ret = 0; if (!card) { @@ -8342,7 +8381,14 @@ static int sm6150_ssr_enable(struct device *dev, void *data) ret = -EINVAL; goto err; } - ret = msm_afe_set_config(rtd->codec); + component = snd_soc_rtdcom_lookup(rtd, "tavil_codec"); + if (!component) { + dev_err(dev, "%s: component is NULL\n", + __func__); + ret = -EINVAL; + goto err; + } + ret = msm_afe_set_config(component); if (ret) dev_err(dev, "%s: Failed to set AFE config. err %d\n", __func__, ret); diff --git a/asoc/sm8150.c b/asoc/sm8150.c index 7328be3eaf19..e1d8bc462663 100644 --- a/asoc/sm8150.c +++ b/asoc/sm8150.c @@ -28,7 +28,6 @@ #include "codecs/msm-cdc-pinctrl.h" #include "codecs/wcd934x/wcd934x.h" #include "codecs/wcd934x/wcd934x-mbhc.h" -#include "codecs/wcd9360/wcd9360.h" #include "codecs/wsa881x.h" #include "codecs/wcd-mbhc-v2.h" @@ -159,12 +158,12 @@ struct msm_asoc_mach_data { struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ struct device_node *fsa_handle; - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct work_struct adsp_power_up_work; }; struct msm_asoc_wcd93xx_codec { - void* (*get_afe_config_fn)(struct snd_soc_codec *codec, + void* (*get_afe_config_fn)(struct snd_soc_component *component, enum afe_config_type config_type); }; @@ -520,7 +519,7 @@ static struct snd_soc_codec_conf *msm_codec_conf; static struct msm_asoc_wcd93xx_codec msm_codec_fn; static void *def_wcd_mbhc_cal(void); -static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, +static int msm_snd_enable_codec_ext_clk(struct snd_soc_component *component, int enable, bool dapm); static int msm_wsa881x_init(struct snd_soc_component *component); @@ -767,7 +766,7 @@ static int slim_get_port_idx(struct snd_kcontrol *kcontrol) "SLIM_1_TX", sizeof("SLIM_1_TX"))) { port_id = SLIM_TX_1; } else { - pr_err("%s: unsupported channel: %s", + pr_err("%s: unsupported channel: %s\n", __func__, kcontrol->id.name); return -EINVAL; } @@ -1032,7 +1031,7 @@ static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[0] = 0; break; } - pr_debug("%s: sample rate = %d", __func__, + pr_debug("%s: sample rate = %d\n", __func__, slim_rx_cfg[SLIM_RX_7].sample_rate); return 0; @@ -1101,7 +1100,7 @@ static int msm_bt_sample_rate_rx_get(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[0] = 0; break; } - pr_debug("%s: sample rate rx = %d", __func__, + pr_debug("%s: sample rate rx = %d\n", __func__, slim_rx_cfg[SLIM_RX_7].sample_rate); return 0; @@ -1163,7 +1162,7 @@ static int msm_bt_sample_rate_tx_get(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[0] = 0; break; } - pr_debug("%s: sample rate tx = %d", __func__, + pr_debug("%s: sample rate tx = %d\n", __func__, slim_tx_cfg[SLIM_TX_7].sample_rate); return 0; @@ -1567,7 +1566,7 @@ static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol) sizeof("Display Port RX"))) { idx = DP_RX_IDX; } else { - pr_err("%s: unsupported BE: %s", + pr_err("%s: unsupported BE: %s\n", __func__, kcontrol->id.name); idx = -EINVAL; } @@ -1880,7 +1879,7 @@ static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, sizeof(kcontrol->id.name))) { port->mode = TDM_QUIN; } else { - pr_err("%s: unsupported mode in: %s", + pr_err("%s: unsupported mode in: %s\n", __func__, kcontrol->id.name); return -EINVAL; } @@ -1926,12 +1925,13 @@ static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, sizeof(kcontrol->id.name))) { port->channel = TDM_7; } else { - pr_err("%s: unsupported channel in: %s", + pr_err("%s: unsupported channel in: %s\n", __func__, kcontrol->id.name); return -EINVAL; } - } else + } else { return -EINVAL; + } return 0; } @@ -1942,7 +1942,7 @@ static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( @@ -1962,7 +1962,7 @@ static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { tdm_rx_cfg[port.mode][port.channel].sample_rate = @@ -1982,7 +1982,7 @@ static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( @@ -2002,7 +2002,7 @@ static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { tdm_tx_cfg[port.mode][port.channel].sample_rate = @@ -2064,7 +2064,7 @@ static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { ucontrol->value.enumerated.item[0] = tdm_get_format_val( @@ -2084,7 +2084,7 @@ static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { tdm_rx_cfg[port.mode][port.channel].bit_format = @@ -2104,7 +2104,7 @@ static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { ucontrol->value.enumerated.item[0] = tdm_get_format_val( @@ -2124,7 +2124,7 @@ static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { tdm_tx_cfg[port.mode][port.channel].bit_format = @@ -2144,7 +2144,7 @@ static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { @@ -2165,7 +2165,7 @@ static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { tdm_rx_cfg[port.mode][port.channel].channels = @@ -2185,7 +2185,7 @@ static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { ucontrol->value.enumerated.item[0] = @@ -2205,7 +2205,7 @@ static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { tdm_tx_cfg[port.mode][port.channel].channels = @@ -2223,22 +2223,22 @@ static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) int idx; if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", - sizeof("PRIM_AUX_PCM"))) + sizeof("PRIM_AUX_PCM"))) { idx = PRIM_AUX_PCM; - else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM", - sizeof("SEC_AUX_PCM"))) + } else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM", + sizeof("SEC_AUX_PCM"))) { idx = SEC_AUX_PCM; - else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", - sizeof("TERT_AUX_PCM"))) + } else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", + sizeof("TERT_AUX_PCM"))) { idx = TERT_AUX_PCM; - else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", - sizeof("QUAT_AUX_PCM"))) + } else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", + sizeof("QUAT_AUX_PCM"))) { idx = QUAT_AUX_PCM; - else if (strnstr(kcontrol->id.name, "QUIN_AUX_PCM", - sizeof("QUIN_AUX_PCM"))) + } else if (strnstr(kcontrol->id.name, "QUIN_AUX_PCM", + sizeof("QUIN_AUX_PCM"))) { idx = QUIN_AUX_PCM; - else { - pr_err("%s: unsupported port: %s", + } else { + pr_err("%s: unsupported port: %s\n", __func__, kcontrol->id.name); idx = -EINVAL; } @@ -2323,37 +2323,37 @@ static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) int idx; if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX", - sizeof("PRIM_MI2S_RX"))) + sizeof("PRIM_MI2S_RX"))) { idx = PRIM_MI2S; - else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX", - sizeof("SEC_MI2S_RX"))) + } else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX", + sizeof("SEC_MI2S_RX"))) { idx = SEC_MI2S; - else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", - sizeof("TERT_MI2S_RX"))) + } else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", + sizeof("TERT_MI2S_RX"))) { idx = TERT_MI2S; - else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", - sizeof("QUAT_MI2S_RX"))) + } else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", + sizeof("QUAT_MI2S_RX"))) { idx = QUAT_MI2S; - else if (strnstr(kcontrol->id.name, "QUIN_MI2S_RX", - sizeof("QUIN_MI2S_RX"))) + } else if (strnstr(kcontrol->id.name, "QUIN_MI2S_RX", + sizeof("QUIN_MI2S_RX"))) { idx = QUIN_MI2S; - else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", - sizeof("PRIM_MI2S_TX"))) + } else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", + sizeof("PRIM_MI2S_TX"))) { idx = PRIM_MI2S; - else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX", - sizeof("SEC_MI2S_TX"))) + } else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX", + sizeof("SEC_MI2S_TX"))) { idx = SEC_MI2S; - else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", - sizeof("TERT_MI2S_TX"))) + } else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", + sizeof("TERT_MI2S_TX"))) { idx = TERT_MI2S; - else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", - sizeof("QUAT_MI2S_TX"))) + } else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", + sizeof("QUAT_MI2S_TX"))) { idx = QUAT_MI2S; - else if (strnstr(kcontrol->id.name, "QUIN_MI2S_TX", - sizeof("QUIN_MI2S_TX"))) + } else if (strnstr(kcontrol->id.name, "QUIN_MI2S_TX", + sizeof("QUIN_MI2S_TX"))) { idx = QUIN_MI2S; - else { - pr_err("%s: unsupported channel: %s", + } else { + pr_err("%s: unsupported channel: %s\n", __func__, kcontrol->id.name); idx = -EINVAL; } @@ -2763,18 +2763,20 @@ static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol, return 0; } -static int msm_hifi_ctrl(struct snd_soc_codec *codec) +static int msm_hifi_ctrl(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); - struct snd_soc_card *card = codec->component.card; + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); + struct snd_soc_card *card = component->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - dev_dbg(codec->dev, "%s: msm_hifi_control = %d\n", __func__, + dev_dbg(component->dev, "%s: msm_hifi_control = %d\n", __func__, msm_hifi_control); if (!pdata || !pdata->hph_en1_gpio_p) { - dev_err(codec->dev, "%s: hph_en1_gpio is invalid\n", __func__); + dev_err(component->dev, "%s: hph_en1_gpio is invalid\n", + __func__); return -EINVAL; } if (msm_hifi_control == MSM_HIFI_ON) { @@ -2802,13 +2804,14 @@ static int msm_hifi_get(struct snd_kcontrol *kcontrol, static int msm_hifi_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); - dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); msm_hifi_control = ucontrol->value.integer.value[0]; - msm_hifi_ctrl(codec); + msm_hifi_ctrl(component); return 0; } @@ -3093,34 +3096,30 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { }; -static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, +static int msm_snd_enable_codec_ext_clk(struct snd_soc_component *component, int enable, bool dapm) { int ret = 0; - if (!strcmp(dev_name(codec->dev), "pahu_codec")) { - ret = pahu_cdc_mclk_enable(codec, enable); - } else if (!strcmp(dev_name(codec->dev), "tavil_codec")) { - ret = tavil_cdc_mclk_enable(codec, enable); + if (!strcmp(component->name, "tavil_codec")) { + ret = tavil_cdc_mclk_enable(component, enable); } else { - dev_err(codec->dev, "%s: unknown codec to enable ext clk\n", + dev_err(component->dev, "%s: unknown codec to enable ext clk\n", __func__); ret = -EINVAL; } return ret; } -static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, +static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_component *component, int enable, bool dapm) { int ret = 0; - if (!strcmp(dev_name(codec->dev), "pahu_codec")) { - ret = pahu_cdc_mclk_tx_enable(codec, enable); - } else if (!strcmp(dev_name(codec->dev), "tavil_codec")) { - ret = tavil_cdc_mclk_tx_enable(codec, enable); + if (!strcmp(component->name, "tavil_codec")) { + ret = tavil_cdc_mclk_tx_enable(component, enable); } else { - dev_err(codec->dev, "%s: unknown codec to enable TX ext clk\n", + dev_err(component->dev, "%s: unknown codec to enable TX ext clk\n", __func__); ret = -EINVAL; } @@ -3131,15 +3130,16 @@ static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec, static int msm_mclk_tx_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); pr_debug("%s: event = %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - return msm_snd_enable_codec_ext_tx_clk(codec, 1, true); + return msm_snd_enable_codec_ext_tx_clk(component, 1, true); case SND_SOC_DAPM_POST_PMD: - return msm_snd_enable_codec_ext_tx_clk(codec, 0, true); + return msm_snd_enable_codec_ext_tx_clk(component, 0, true); } return 0; } @@ -3147,15 +3147,16 @@ static int msm_mclk_tx_event(struct snd_soc_dapm_widget *w, static int msm_mclk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); pr_debug("%s: event = %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - return msm_snd_enable_codec_ext_clk(codec, 1, true); + return msm_snd_enable_codec_ext_clk(component, 1, true); case SND_SOC_DAPM_POST_PMD: - return msm_snd_enable_codec_ext_clk(codec, 0, true); + return msm_snd_enable_codec_ext_clk(component, 0, true); } return 0; } @@ -3163,21 +3164,23 @@ static int msm_mclk_event(struct snd_soc_dapm_widget *w, static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); - struct snd_soc_card *card = codec->component.card; + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct snd_soc_card *card = component->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - dev_dbg(codec->dev, "%s: msm_hifi_control = %d\n", + dev_dbg(component->dev, "%s: msm_hifi_control = %d\n", __func__, msm_hifi_control); if (!pdata || !pdata->hph_en0_gpio_p) { - dev_err(codec->dev, "%s: hph_en0_gpio is invalid\n", __func__); + dev_err(component->dev, "%s: hph_en0_gpio is invalid\n", + __func__); return -EINVAL; } if (msm_hifi_control != MSM_HIFI_ON) { - dev_dbg(codec->dev, "%s: HiFi mixer control is not set\n", + dev_dbg(component->dev, "%s: HiFi mixer control is not set\n", __func__); return 0; } @@ -3332,10 +3335,12 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_soc_dai *codec_dai = rtd->codec_dai; + int rc = 0; int idx; void *config = NULL; - struct snd_soc_codec *codec = NULL; + struct snd_soc_component *component = NULL; pr_debug("%s: format = %d, rate = %d\n", __func__, params_format(params), params_rate(params)); @@ -3385,11 +3390,13 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; case MSM_BACKEND_DAI_SLIMBUS_5_TX: - codec = rtd->codec; + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) + component = snd_soc_rtdcom_lookup(rtd, "tavil_codec"); + rate->min = rate->max = SAMPLING_RATE_16KHZ; channels->min = channels->max = 1; - config = msm_codec_fn.get_afe_config_fn(codec, + config = msm_codec_fn.get_afe_config_fn(component, AFE_SLIMBUS_SLAVE_PORT_CONFIG); if (config) { rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, @@ -3714,9 +3721,10 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return rc; } -static bool msm_usbc_swap_gnd_mic(struct snd_soc_codec *codec, bool active) +static bool msm_usbc_swap_gnd_mic(struct snd_soc_component *component, + bool active) { - struct snd_soc_card *card = codec->component.card; + struct snd_soc_card *card = component->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); @@ -3726,25 +3734,25 @@ static bool msm_usbc_swap_gnd_mic(struct snd_soc_codec *codec, bool active) return fsa4480_switch_event(pdata->fsa_handle, FSA_MIC_GND_SWAP); } -static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) +static bool msm_swap_gnd_mic(struct snd_soc_component *component, bool active) { int value = 0; bool ret = false; struct snd_soc_card *card; struct msm_asoc_mach_data *pdata; - if (!codec) { - pr_err("%s codec is NULL\n", __func__); + if (!component) { + pr_err("%s component is NULL\n", __func__); return false; } - card = codec->component.card; + card = component->card; pdata = snd_soc_card_get_drvdata(card); if (!pdata) return false; if (wcd_mbhc_cfg.enable_usbc_analog) - return msm_usbc_swap_gnd_mic(codec, active); + return msm_usbc_swap_gnd_mic(component, active); /* if usbc is not defined, swap using us_euro_gpio_p */ if (pdata->us_euro_gpio_p) { @@ -3756,7 +3764,7 @@ static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) else msm_cdc_pinctrl_select_active_state( pdata->us_euro_gpio_p); - dev_dbg(codec->dev, "%s: swap select switch %d to %d\n", + dev_dbg(component->dev, "%s: swap select switch %d to %d\n", __func__, value, !value); ret = true; } @@ -3764,46 +3772,46 @@ static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active) return ret; } -static int msm_afe_set_config(struct snd_soc_codec *codec) +static int msm_afe_set_config(struct snd_soc_component *component) { int ret = 0; void *config_data = NULL; if (!msm_codec_fn.get_afe_config_fn) { - dev_err(codec->dev, "%s: codec get afe config not init'ed\n", + dev_err(component->dev, "%s: codec get afe config not init'ed\n", __func__); return -EINVAL; } - config_data = msm_codec_fn.get_afe_config_fn(codec, + config_data = msm_codec_fn.get_afe_config_fn(component, AFE_CDC_REGISTERS_CONFIG); if (config_data) { ret = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0); if (ret) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to set codec registers config %d\n", __func__, ret); return ret; } } - config_data = msm_codec_fn.get_afe_config_fn(codec, + config_data = msm_codec_fn.get_afe_config_fn(component, AFE_CDC_REGISTER_PAGE_CONFIG); if (config_data) { ret = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, 0); if (ret) - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to set cdc register page config\n", __func__); } - config_data = msm_codec_fn.get_afe_config_fn(codec, + config_data = msm_codec_fn.get_afe_config_fn(component, AFE_SLIMBUS_SLAVE_CONFIG); if (config_data) { ret = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0); if (ret) { - dev_err(codec->dev, + dev_err(component->dev, "%s: Failed to set slimbus slave config %d\n", __func__, ret); return ret; @@ -3819,7 +3827,7 @@ static void msm_afe_clear_config(void) afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); } -static int msm_adsp_power_up_config(struct snd_soc_codec *codec, +static int msm_adsp_power_up_config(struct snd_soc_component *component, struct snd_card *card) { int ret = 0; @@ -3861,7 +3869,7 @@ static int msm_adsp_power_up_config(struct snd_soc_codec *codec, goto err; } - ret = msm_afe_set_config(codec); + ret = msm_afe_set_config(component); if (ret) pr_err("%s: Failed to set AFE config. err %d\n", __func__, ret); @@ -3875,14 +3883,14 @@ static int msm_adsp_power_up_config(struct snd_soc_codec *codec, static void msm_adsp_power_up_config_work(struct work_struct *work) { struct msm_asoc_mach_data *pdata; - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct snd_card *card; pdata = container_of(work, struct msm_asoc_mach_data, adsp_power_up_work); - codec = pdata->codec; - card = codec->component.card->snd_card; - msm_adsp_power_up_config(codec, card); + component = pdata->component; + card = component->card->snd_card; + msm_adsp_power_up_config(component, card); } static int sm8150_notifier_service_cb(struct notifier_block *this, @@ -3892,7 +3900,8 @@ static int sm8150_notifier_service_cb(struct notifier_block *this, struct snd_soc_card *card = NULL; const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; struct snd_soc_pcm_runtime *rtd; - struct snd_soc_codec *codec; + struct snd_soc_dai *codec_dai; + struct snd_soc_component *component; struct msm_asoc_mach_data *pdata; pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); @@ -3926,10 +3935,12 @@ static int sm8150_notifier_service_cb(struct notifier_block *this, ret = -EINVAL; goto err; } - codec = rtd->codec; + codec_dai = rtd->codec_dai; + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) + component = snd_soc_rtdcom_lookup(rtd, "tavil_codec"); pdata = snd_soc_card_get_drvdata(card); - pdata->codec = codec; + pdata->component = component; schedule_work(&pdata->adsp_power_up_work); break; default: @@ -3948,12 +3959,12 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; void *config_data; - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + struct snd_soc_component *component; + struct snd_soc_dapm_context *dapm; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_component *aux_comp; - struct snd_card *card; + struct snd_card *card = rtd->card->snd_card; struct snd_info_entry *entry; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); @@ -3964,9 +3975,9 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 * TX14, TX15, TX16 */ - unsigned int rx_ch[WCD9360_RX_MAX] = {144, 145, 146, 147, 148, 149, + unsigned int rx_ch[WCD934X_RX_MAX] = {144, 145, 146, 147, 148, 149, 150, 151}; - unsigned int tx_ch[WCD9360_TX_MAX] = {128, 129, 130, 131, 132, 133, + unsigned int tx_ch[WCD934X_TX_MAX] = {128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143}; @@ -3974,7 +3985,14 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) rtd->pmdown_time = 0; - ret = snd_soc_add_codec_controls(codec, msm_snd_controls, + component = snd_soc_rtdcom_lookup(rtd, "tavil_codec"); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + dapm = snd_soc_component_get_dapm(component); + + ret = snd_soc_add_component_controls(component, msm_snd_controls, ARRAY_SIZE(msm_snd_controls)); if (ret < 0) { pr_err("%s: add_codec_controls failed, err %d\n", @@ -3982,17 +4000,10 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) return ret; } - if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { - snd_soc_dapm_new_controls(dapm, msm_dapm_widgets_tavil, - ARRAY_SIZE(msm_dapm_widgets_tavil)); - snd_soc_dapm_add_routes(dapm, wcd_audio_paths_tavil, - ARRAY_SIZE(wcd_audio_paths_tavil)); - } else { - snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, - ARRAY_SIZE(msm_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, wcd_audio_paths, - ARRAY_SIZE(wcd_audio_paths)); - } + snd_soc_dapm_new_controls(dapm, msm_dapm_widgets_tavil, + ARRAY_SIZE(msm_dapm_widgets_tavil)); + snd_soc_dapm_add_routes(dapm, wcd_audio_paths_tavil, + ARRAY_SIZE(wcd_audio_paths_tavil)); snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); @@ -4023,11 +4034,6 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_ignore_suspend(dapm, "HPHR"); snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL"); snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR"); - } else { - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic6"); - snd_soc_dapm_ignore_suspend(dapm, "Digital Mic7"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic3"); - snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4"); } snd_soc_dapm_sync(dapm); @@ -4037,16 +4043,14 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) msm_codec_fn.get_afe_config_fn = tavil_get_afe_config; - else - msm_codec_fn.get_afe_config_fn = pahu_get_afe_config; - ret = msm_adsp_power_up_config(codec, rtd->card->snd_card); + ret = msm_adsp_power_up_config(component, rtd->card->snd_card); if (ret) { pr_err("%s: Failed to set AFE config %d\n", __func__, ret); goto err; } - config_data = msm_codec_fn.get_afe_config_fn(codec, + config_data = msm_codec_fn.get_afe_config_fn(component, AFE_AANC_VERSION); if (config_data) { ret = afe_set_config(AFE_AANC_VERSION, config_data, 0); @@ -4072,9 +4076,9 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) card_aux_list); if (!strcmp(aux_comp->name, WSA8810_NAME_1) || !strcmp(aux_comp->name, WSA8810_NAME_2)) { - tavil_set_spkr_mode(rtd->codec, + tavil_set_spkr_mode(component, WCD934X_SPKR_MODE_1); - tavil_set_spkr_gain_offset(rtd->codec, + tavil_set_spkr_gain_offset(component, WCD934X_RX_GAIN_OFFSET_M1P5_DB); } } @@ -4088,30 +4092,8 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) goto done; } pdata->codec_root = entry; - tavil_codec_info_create_codec_entry(pdata->codec_root, codec); - } else { - if (rtd->card->num_aux_devs && - !list_empty(&rtd->card->component_dev_list)) { - aux_comp = list_first_entry(&rtd->card->component_dev_list, - struct snd_soc_component, card_aux_list); - if (!strcmp(aux_comp->name, WSA8810_NAME_1) || - !strcmp(aux_comp->name, WSA8810_NAME_2)) { - pahu_set_spkr_mode(rtd->codec, WCD9360_SPKR_MODE_1); - pahu_set_spkr_gain_offset(rtd->codec, - WCD9360_RX_GAIN_OFFSET_M1P5_DB); - } - } - card = rtd->card->snd_card; - entry = snd_info_create_subdir(card->module, "codecs", - card->proc_root); - if (!entry) { - pr_debug("%s: Cannot create codecs module entry\n", - __func__); - pdata->codec_root = NULL; - goto done; - } - pdata->codec_root = entry; - pahu_codec_info_create_codec_entry(pdata->codec_root, codec); + tavil_codec_info_create_codec_entry(pdata->codec_root, + component); } done: codec_reg_done = true; @@ -5528,47 +5510,6 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { }, }; -static struct snd_soc_dai_link msm_pahu_fe_dai_links[] = { - { - .name = LPASS_BE_SLIMBUS_4_TX, - .stream_name = "Slimbus4 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16393", - .platform_name = "msm-pcm-hostless", - .codec_name = "pahu_codec", - .codec_dai_name = "pahu_vifeedback", - .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ignore_suspend = 1, - }, - /* Ultrasound RX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Playback", - .stream_name = "SLIMBUS_2 Hostless Playback", - .cpu_dai_name = "msm-dai-q6-dev.16388", - .platform_name = "msm-pcm-hostless", - .codec_name = "pahu_codec", - .codec_dai_name = "pahu_rx2", - .ignore_suspend = 1, - .ignore_pmdown_time = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm_slimbus_2_be_ops, - }, - /* Ultrasound TX DAI Link */ - { - .name = "SLIMBUS_2 Hostless Capture", - .stream_name = "SLIMBUS_2 Hostless Capture", - .cpu_dai_name = "msm-dai-q6-dev.16389", - .platform_name = "msm-pcm-hostless", - .codec_name = "pahu_codec", - .codec_dai_name = "pahu_tx2", - .ignore_suspend = 1, - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, - .ops = &msm_slimbus_2_be_ops, - }, -}; - static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = { { .name = LPASS_BE_SLIMBUS_4_TX, @@ -5910,193 +5851,6 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { }, }; -static struct snd_soc_dai_link msm_pahu_be_dai_links[] = { - { - .name = LPASS_BE_SLIMBUS_0_RX, - .stream_name = "Slimbus Playback", - .cpu_dai_name = "msm-dai-q6-dev.16384", - .platform_name = "msm-pcm-routing", - .codec_name = "pahu_codec", - .codec_dai_name = "pahu_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, - .init = &msm_audrx_init, - .be_hw_params_fixup = msm_be_hw_params_fixup, - /* this dainlink has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - .ops = &msm_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_0_TX, - .stream_name = "Slimbus Capture", - .cpu_dai_name = "msm-dai-q6-dev.16385", - .platform_name = "msm-pcm-routing", - .codec_name = "pahu_codec", - .codec_dai_name = "pahu_tx1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ignore_suspend = 1, - .ops = &msm_be_ops, - }, - { - .name = LPASS_BE_SLIMBUS_1_RX, - .stream_name = "Slimbus1 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16386", - .platform_name = "msm-pcm-routing", - .codec_name = "pahu_codec", - .codec_dai_name = "pahu_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_1_TX, - .stream_name = "Slimbus1 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16387", - .platform_name = "msm-pcm-routing", - .codec_name = "pahu_codec", - .codec_dai_name = "pahu_tx3", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_2_RX, - .stream_name = "Slimbus2 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16388", - .platform_name = "msm-pcm-routing", - .codec_name = "pahu_codec", - .codec_dai_name = "pahu_rx2", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_2_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_3_RX, - .stream_name = "Slimbus3 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16390", - .platform_name = "msm-pcm-routing", - .codec_name = "pahu_codec", - .codec_dai_name = "pahu_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_3_TX, - .stream_name = "Slimbus3 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16391", - .platform_name = "msm-pcm-routing", - .codec_name = "pahu_codec", - .codec_dai_name = "pahu_tx1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_4_RX, - .stream_name = "Slimbus4 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16392", - .platform_name = "msm-pcm-routing", - .codec_name = "pahu_codec", - .codec_dai_name = "pahu_rx1", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_5_RX, - .stream_name = "Slimbus5 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16394", - .platform_name = "msm-pcm-routing", - .codec_name = "pahu_codec", - .codec_dai_name = "pahu_rx3", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - /* MAD BE */ - { - .name = LPASS_BE_SLIMBUS_5_TX, - .stream_name = "Slimbus5 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16395", - .platform_name = "msm-pcm-routing", - .codec_name = "pahu_codec", - .codec_dai_name = "pahu_mad1", - .no_pcm = 1, - .dpcm_capture = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_suspend = 1, - }, - { - .name = LPASS_BE_SLIMBUS_6_RX, - .stream_name = "Slimbus6 Playback", - .cpu_dai_name = "msm-dai-q6-dev.16396", - .platform_name = "msm-pcm-routing", - .codec_name = "pahu_codec", - .codec_dai_name = "pahu_rx4", - .no_pcm = 1, - .dpcm_playback = 1, - .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - /* dai link has playback support */ - .ignore_pmdown_time = 1, - .ignore_suspend = 1, - }, - /* Slimbus VI Recording */ - { - .name = LPASS_BE_SLIMBUS_TX_VI, - .stream_name = "Slimbus4 Capture", - .cpu_dai_name = "msm-dai-q6-dev.16393", - .platform_name = "msm-pcm-routing", - .codec_name = "pahu_codec", - .codec_dai_name = "pahu_vifeedback", - .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, - .be_hw_params_fixup = msm_be_hw_params_fixup, - .ops = &msm_be_ops, - .ignore_suspend = 1, - .no_pcm = 1, - .dpcm_capture = 1, - }, -}; - static struct snd_soc_dai_link msm_tavil_be_dai_links[] = { { .name = LPASS_BE_SLIMBUS_0_RX, @@ -6660,17 +6414,6 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { }, }; -static struct snd_soc_dai_link msm_pahu_snd_card_dai_links[ - ARRAY_SIZE(msm_common_dai_links) + - ARRAY_SIZE(msm_pahu_fe_dai_links) + - ARRAY_SIZE(msm_common_misc_fe_dai_links) + - ARRAY_SIZE(msm_common_be_dai_links) + - ARRAY_SIZE(msm_pahu_be_dai_links) + - ARRAY_SIZE(msm_wcn_be_dai_links) + - ARRAY_SIZE(ext_disp_be_dai_link) + - ARRAY_SIZE(msm_mi2s_be_dai_links) + - ARRAY_SIZE(msm_auxpcm_be_dai_links)]; - static struct snd_soc_dai_link msm_tavil_dai_links[ ARRAY_SIZE(msm_common_dai_links) + ARRAY_SIZE(msm_tavil_fe_dai_links) + @@ -6686,6 +6429,7 @@ static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) { const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; struct snd_soc_pcm_runtime *rtd; + struct snd_soc_component *component; int ret = 0; void *mbhc_calibration; @@ -6698,13 +6442,20 @@ static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) goto err_pcm_runtime; } + component = snd_soc_rtdcom_lookup(rtd, "tavil_codec"); + if (!component) { + dev_err(card->dev, + "%s: component is NULL\n", __func__); + ret = -EINVAL; + goto err_pcm_runtime; + } mbhc_calibration = def_wcd_mbhc_cal(); if (!mbhc_calibration) { ret = -ENOMEM; goto err_mbhc_cal; } wcd_mbhc_cfg.calibration = mbhc_calibration; - ret = tavil_mbhc_hs_detect(rtd->codec, &wcd_mbhc_cfg); + ret = tavil_mbhc_hs_detect(component, &wcd_mbhc_cfg); if (ret) { dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", __func__, ret); @@ -6719,10 +6470,6 @@ static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) return ret; } -struct snd_soc_card snd_soc_card_pahu_msm = { - .name = "sm8150-pahu-snd-card", -}; - struct snd_soc_card snd_soc_card_tavil_msm = { .name = "sm8150-tavil-snd-card", .late_probe = msm_snd_card_tavil_late_probe, @@ -6817,12 +6564,17 @@ static int msm_populate_dai_link_component_of_node( static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; - struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(rtd, "msm-stub-codec"); - ret = snd_soc_add_codec_controls(codec, msm_snd_controls, + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + ret = snd_soc_add_component_controls(component, msm_snd_controls, ARRAY_SIZE(msm_snd_controls)); if (ret < 0) { - dev_err(codec->dev, + dev_err(component->dev, "%s: add_codec_controls failed, err = %d\n", __func__, ret); return ret; @@ -6934,8 +6686,6 @@ struct snd_soc_card snd_soc_card_stub_msm = { }; static const struct of_device_id sm8150_asoc_machine_of_match[] = { - { .compatible = "qcom,sm8150-asoc-snd-pahu", - .data = "pahu_codec"}, { .compatible = "qcom,sm8150-asoc-snd-tavil", .data = "tavil_codec"}, { .compatible = "qcom,sm8150-asoc-snd-stub", @@ -6960,70 +6710,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) return NULL; } - if (!strcmp(match->data, "pahu_codec")) { - card = &snd_soc_card_pahu_msm; - len_1 = ARRAY_SIZE(msm_common_dai_links); - len_2 = len_1 + ARRAY_SIZE(msm_pahu_fe_dai_links); - len_3 = len_2 + ARRAY_SIZE(msm_common_misc_fe_dai_links); - len_4 = len_3 + ARRAY_SIZE(msm_common_be_dai_links); - total_links = len_4 + ARRAY_SIZE(msm_pahu_be_dai_links); - memcpy(msm_pahu_snd_card_dai_links, - msm_common_dai_links, - sizeof(msm_common_dai_links)); - memcpy(msm_pahu_snd_card_dai_links + len_1, - msm_pahu_fe_dai_links, - sizeof(msm_pahu_fe_dai_links)); - memcpy(msm_pahu_snd_card_dai_links + len_2, - msm_common_misc_fe_dai_links, - sizeof(msm_common_misc_fe_dai_links)); - memcpy(msm_pahu_snd_card_dai_links + len_3, - msm_common_be_dai_links, - sizeof(msm_common_be_dai_links)); - memcpy(msm_pahu_snd_card_dai_links + len_4, - msm_pahu_be_dai_links, - sizeof(msm_pahu_be_dai_links)); - - ret = of_property_read_u32(dev->of_node, "qcom,wcn-btfm", &val); - if (!ret && val) { - dev_dbg(dev, "%s(): WCN BTFM support present\n", - __func__); - memcpy(msm_pahu_snd_card_dai_links + total_links, - msm_wcn_be_dai_links, - sizeof(msm_wcn_be_dai_links)); - total_links += ARRAY_SIZE(msm_wcn_be_dai_links); - } - - ret = of_property_read_u32(dev->of_node, - "qcom,ext-disp-audio-rx", &val); - if (!ret && val) { - dev_dbg(dev, "%s(): ext disp audio support present\n", - __func__); - memcpy(msm_pahu_snd_card_dai_links + total_links, - ext_disp_be_dai_link, - sizeof(ext_disp_be_dai_link)); - total_links += ARRAY_SIZE(ext_disp_be_dai_link); - } - - ret = of_property_read_u32(dev->of_node, - "qcom,mi2s-audio-intf", &val); - if (!ret && val) { - memcpy(msm_pahu_snd_card_dai_links + total_links, - msm_mi2s_be_dai_links, - sizeof(msm_mi2s_be_dai_links)); - total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); - } - - ret = of_property_read_u32(dev->of_node, - "qcom,auxpcm-audio-intf", &val); - if (!ret && val) { - memcpy(msm_pahu_snd_card_dai_links + total_links, - msm_auxpcm_be_dai_links, - sizeof(msm_auxpcm_be_dai_links)); - total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links); - } - - dailink = msm_pahu_snd_card_dai_links; - } else if (!strcmp(match->data, "tavil_codec")) { + if (!strcmp(match->data, "tavil_codec")) { card = &snd_soc_card_tavil_msm; len_1 = ARRAY_SIZE(msm_common_dai_links); len_2 = len_1 + ARRAY_SIZE(msm_tavil_fe_dai_links); @@ -7115,22 +6802,21 @@ static int msm_wsa881x_init(struct snd_soc_component *component) u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107}; unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); struct msm_asoc_mach_data *pdata; struct snd_soc_dapm_context *dapm; int ret = 0; - if (!codec) { + if (!component) { pr_err("%s codec is NULL\n", __func__); return -EINVAL; } - dapm = snd_soc_codec_get_dapm(codec); + dapm = snd_soc_component_get_dapm(component); if (!strcmp(component->name_prefix, "SpkrLeft")) { - dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n", - __func__, codec->component.name); - wsa881x_set_channel_map(codec, &spkleft_ports[0], + dev_dbg(component->dev, "%s: setting left ch map to codec %s\n", + __func__, component->name); + wsa881x_set_channel_map(component, &spkleft_ports[0], WSA881X_MAX_SWR_PORTS, &ch_mask[0], &ch_rate[0], NULL); if (dapm->component) { @@ -7138,9 +6824,9 @@ static int msm_wsa881x_init(struct snd_soc_component *component) snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); } } else if (!strcmp(component->name_prefix, "SpkrRight")) { - dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n", - __func__, codec->component.name); - wsa881x_set_channel_map(codec, &spkright_ports[0], + dev_dbg(codec->dev, "%s: setting right ch map to component %s\n", + __func__, component->name); + wsa881x_set_channel_map(component, &spkright_ports[0], WSA881X_MAX_SWR_PORTS, &ch_mask[0], &ch_rate[0], NULL); if (dapm->component) { @@ -7148,15 +6834,15 @@ static int msm_wsa881x_init(struct snd_soc_component *component) snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); } } else { - dev_err(codec->dev, "%s: wrong codec name %s\n", __func__, - codec->component.name); + dev_err(codec->dev, "%s: wrong component name %s\n", __func__, + component->name); ret = -EINVAL; goto err; } pdata = snd_soc_card_get_drvdata(component->card); if (pdata && pdata->codec_root) wsa881x_codec_info_create_codec_entry(pdata->codec_root, - codec); + component); err: return ret; -- GitLab From 04dff947201ff32812c659bd06257fa145f23fc5 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 29 Nov 2018 09:20:18 +0800 Subject: [PATCH 0682/1645] dsp: ion: Remove smmu initialization SMMU initialization is not required to be done in client probe process. SMMU framework takes care of creating domain and attaching device. Remove related code from audio ion driver. Change-Id: I3756c5abb7488afb43e20fae698c7008461a18cb Signed-off-by: Meng Wang --- dsp/msm_audio_ion.c | 48 --------------------------------------------- 1 file changed, 48 deletions(-) diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index af2b3c46322d..95d4fd4e2bcf 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -13,13 +13,11 @@ #include #include #include -#include #include #include #include #include #include -#include #include #define MSM_AUDIO_ION_PROBED (1 << 0) @@ -27,21 +25,16 @@ #define MSM_AUDIO_ION_PHYS_ADDR(alloc_data) \ alloc_data->table->sgl->dma_address -#define MSM_AUDIO_ION_VA_START 0x10000000 -#define MSM_AUDIO_ION_VA_LEN 0x0FFFFFFF - #define MSM_AUDIO_SMMU_SID_OFFSET 32 struct msm_audio_ion_private { bool smmu_enabled; struct device *cb_dev; - struct dma_iommu_mapping *mapping; u8 device_status; struct list_head alloc_list; struct mutex list_mutex; u64 smmu_sid_bits; u32 smmu_version; - u32 iova_start_addr; }; struct msm_audio_alloc_data { @@ -654,31 +647,10 @@ EXPORT_SYMBOL(msm_audio_populate_upper_32_bits); static int msm_audio_smmu_init(struct device *dev) { - struct dma_iommu_mapping *mapping; - int ret; - - mapping = arm_iommu_create_mapping(&platform_bus_type, - msm_audio_ion_data.iova_start_addr, - MSM_AUDIO_ION_VA_LEN); - if (IS_ERR(mapping)) - return PTR_ERR(mapping); - - ret = arm_iommu_attach_device(dev, mapping); - if (ret) { - dev_err(dev, "%s: Attach failed, err = %d\n", - __func__, ret); - goto fail_attach; - } - - msm_audio_ion_data.mapping = mapping; INIT_LIST_HEAD(&msm_audio_ion_data.alloc_list); mutex_init(&(msm_audio_ion_data.list_mutex)); return 0; - -fail_attach: - arm_iommu_release_mapping(mapping); - return ret; } static const struct of_device_id msm_audio_ion_dt_match[] = { @@ -694,7 +666,6 @@ static int msm_audio_ion_probe(struct platform_device *pdev) u64 smmu_sid_mask = 0; const char *msm_audio_ion_dt = "qcom,smmu-enabled"; const char *msm_audio_ion_smmu = "qcom,smmu-version"; - const char *msm_audio_ion_iova_start_addr = "qcom,iova-start-addr"; const char *msm_audio_ion_smmu_sid_mask = "qcom,smmu-sid-mask"; bool smmu_enabled; enum apr_subsys_state q6_state; @@ -740,18 +711,6 @@ static int msm_audio_ion_probe(struct platform_device *pdev) dev_dbg(dev, "%s: SMMU is Enabled. SMMU version is (%d)", __func__, msm_audio_ion_data.smmu_version); - rc = of_property_read_u32(dev->of_node, - msm_audio_ion_iova_start_addr, - &msm_audio_ion_data.iova_start_addr); - if (rc) { - dev_dbg(dev, - "%s: qcom,iova_start_addr missing in DT node, initialize with default val\n", - __func__); - msm_audio_ion_data.iova_start_addr = MSM_AUDIO_ION_VA_START; - } else { - dev_dbg(dev, "%s:IOVA start addr: 0x%x\n", - __func__, msm_audio_ion_data.iova_start_addr); - } /* Get SMMU SID information from Devicetree */ rc = of_property_read_u64(dev->of_node, msm_audio_ion_smmu_sid_mask, @@ -796,17 +755,10 @@ static int msm_audio_ion_probe(struct platform_device *pdev) static int msm_audio_ion_remove(struct platform_device *pdev) { - struct dma_iommu_mapping *mapping; struct device *audio_cb_dev; - mapping = msm_audio_ion_data.mapping; audio_cb_dev = msm_audio_ion_data.cb_dev; - if (audio_cb_dev && mapping) { - arm_iommu_detach_device(audio_cb_dev); - arm_iommu_release_mapping(mapping); - } - msm_audio_ion_data.smmu_enabled = 0; msm_audio_ion_data.device_status = 0; return 0; -- GitLab From 43bbb876521759e6bc15d12acf2326dba8f946dc Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 10 Dec 2018 12:32:05 +0800 Subject: [PATCH 0683/1645] asoc: Update file header to GPL-2.0-only Update file header to GPL-2.0-only. Change-Id: Ic1542a3209a5fe73c937a5b36491ede4a451936d Signed-off-by: Meng Wang --- asoc/codecs/aqt1000/aqt1000-api.h | 2 +- asoc/codecs/aqt1000/aqt1000-clsh.c | 2 +- asoc/codecs/aqt1000/aqt1000-clsh.h | 2 +- asoc/codecs/aqt1000/aqt1000-core.c | 2 +- asoc/codecs/aqt1000/aqt1000-internal.h | 2 +- asoc/codecs/aqt1000/aqt1000-irq.c | 2 +- asoc/codecs/aqt1000/aqt1000-irq.h | 2 +- asoc/codecs/aqt1000/aqt1000-mbhc.c | 2 +- asoc/codecs/aqt1000/aqt1000-mbhc.h | 2 +- asoc/codecs/aqt1000/aqt1000-reg-defaults.h | 2 +- asoc/codecs/aqt1000/aqt1000-registers.h | 2 +- asoc/codecs/aqt1000/aqt1000-regmap.c | 2 +- asoc/codecs/aqt1000/aqt1000-routing.h | 2 +- asoc/codecs/aqt1000/aqt1000-utils.c | 2 +- asoc/codecs/aqt1000/aqt1000-utils.h | 2 +- asoc/codecs/aqt1000/aqt1000.c | 2 +- asoc/codecs/aqt1000/aqt1000.h | 2 +- asoc/codecs/aqt1000/pdata.h | 2 +- asoc/codecs/audio-ext-clk-up.c | 2 +- asoc/codecs/audio-ext-clk-up.h | 2 +- asoc/codecs/audio-ext-clk.c | 2 +- asoc/codecs/bolero/bolero-cdc-registers.h | 2 +- asoc/codecs/bolero/bolero-cdc-regmap.c | 2 +- asoc/codecs/bolero/bolero-cdc-tables.c | 2 +- asoc/codecs/bolero/bolero-cdc-utils.c | 2 +- asoc/codecs/bolero/bolero-cdc.c | 2 +- asoc/codecs/bolero/bolero-cdc.h | 2 +- asoc/codecs/bolero/internal.h | 2 +- asoc/codecs/bolero/rx-macro.c | 2 +- asoc/codecs/bolero/tx-macro.c | 2 +- asoc/codecs/bolero/va-macro.c | 2 +- asoc/codecs/bolero/wsa-macro.c | 2 +- asoc/codecs/bolero/wsa-macro.h | 2 +- asoc/codecs/core.h | 2 +- asoc/codecs/cpe_cmi.h | 2 +- asoc/codecs/cpe_core.h | 2 +- asoc/codecs/cpe_err.h | 2 +- asoc/codecs/csra66x0/csra66x0.c | 2 +- asoc/codecs/csra66x0/csra66x0.h | 2 +- asoc/codecs/ep92/ep92.c | 2 +- asoc/codecs/ep92/ep92.h | 2 +- asoc/codecs/msm-cdc-pinctrl.c | 2 +- asoc/codecs/msm-cdc-pinctrl.h | 2 +- asoc/codecs/msm-cdc-supply.c | 2 +- asoc/codecs/msm-cdc-supply.h | 2 +- asoc/codecs/msm_hdmi_codec_rx.c | 2 +- asoc/codecs/msm_stub.c | 3 +-- asoc/codecs/pdata.h | 2 +- asoc/codecs/wcd-clsh.c | 2 +- asoc/codecs/wcd-clsh.h | 2 +- asoc/codecs/wcd-dsp-mgr.c | 2 +- asoc/codecs/wcd-dsp-utils.c | 2 +- asoc/codecs/wcd-dsp-utils.h | 2 +- asoc/codecs/wcd-irq.c | 2 +- asoc/codecs/wcd-mbhc-adc.c | 2 +- asoc/codecs/wcd-mbhc-adc.h | 2 +- asoc/codecs/wcd-mbhc-legacy.c | 2 +- asoc/codecs/wcd-mbhc-legacy.h | 2 +- asoc/codecs/wcd-mbhc-v2-api.h | 2 +- asoc/codecs/wcd-mbhc-v2.c | 2 +- asoc/codecs/wcd-mbhc-v2.h | 2 +- asoc/codecs/wcd-spi-registers.h | 2 +- asoc/codecs/wcd-spi.c | 2 +- asoc/codecs/wcd9335-regmap.c | 2 +- asoc/codecs/wcd9335-tables.c | 2 +- asoc/codecs/wcd9335.c | 2 +- asoc/codecs/wcd9335.h | 2 +- asoc/codecs/wcd9335_irq.h | 2 +- asoc/codecs/wcd9335_registers.h | 2 +- asoc/codecs/wcd934x/wcd934x-dsd.c | 2 +- asoc/codecs/wcd934x/wcd934x-dsd.h | 2 +- asoc/codecs/wcd934x/wcd934x-dsp-cntl.c | 2 +- asoc/codecs/wcd934x/wcd934x-dsp-cntl.h | 2 +- asoc/codecs/wcd934x/wcd934x-mbhc.c | 2 +- asoc/codecs/wcd934x/wcd934x-mbhc.h | 2 +- asoc/codecs/wcd934x/wcd934x-regmap.c | 2 +- asoc/codecs/wcd934x/wcd934x-routing.h | 2 +- asoc/codecs/wcd934x/wcd934x-tables.c | 2 +- asoc/codecs/wcd934x/wcd934x.c | 2 +- asoc/codecs/wcd934x/wcd934x.h | 2 +- asoc/codecs/wcd934x/wcd934x_irq.h | 2 +- asoc/codecs/wcd937x/internal.h | 2 +- asoc/codecs/wcd937x/wcd937x-mbhc.c | 2 +- asoc/codecs/wcd937x/wcd937x-mbhc.h | 2 +- asoc/codecs/wcd937x/wcd937x-registers.h | 2 +- asoc/codecs/wcd937x/wcd937x-regmap.c | 2 +- asoc/codecs/wcd937x/wcd937x-tables.c | 2 +- asoc/codecs/wcd937x/wcd937x.c | 2 +- asoc/codecs/wcd937x/wcd937x.h | 2 +- asoc/codecs/wcd937x/wcd937x_slave.c | 2 +- asoc/codecs/wcd9xxx-common-v2.c | 2 +- asoc/codecs/wcd9xxx-common-v2.h | 2 +- asoc/codecs/wcd9xxx-core-init.c | 2 +- asoc/codecs/wcd9xxx-core.c | 2 +- asoc/codecs/wcd9xxx-irq.c | 2 +- asoc/codecs/wcd9xxx-irq.h | 2 +- asoc/codecs/wcd9xxx-regmap.h | 2 +- asoc/codecs/wcd9xxx-resmgr-v2.c | 2 +- asoc/codecs/wcd9xxx-resmgr-v2.h | 2 +- asoc/codecs/wcd9xxx-rst.c | 2 +- asoc/codecs/wcd9xxx-slimslave.c | 2 +- asoc/codecs/wcd9xxx-slimslave.h | 2 +- asoc/codecs/wcd9xxx-soc-init.c | 2 +- asoc/codecs/wcd9xxx-utils.c | 2 +- asoc/codecs/wcd9xxx-utils.h | 2 +- asoc/codecs/wcd_cmi_api.h | 2 +- asoc/codecs/wcd_cpe_core.c | 2 +- asoc/codecs/wcd_cpe_core.h | 2 +- asoc/codecs/wcd_cpe_services.c | 2 +- asoc/codecs/wcd_cpe_services.h | 2 +- asoc/codecs/wcdcal-hwdep.c | 2 +- asoc/codecs/wcdcal-hwdep.h | 2 +- asoc/codecs/wsa881x-registers.h | 2 +- asoc/codecs/wsa881x-regmap.c | 2 +- asoc/codecs/wsa881x-tables.c | 2 +- asoc/codecs/wsa881x-temp-sensor.c | 2 +- asoc/codecs/wsa881x-temp-sensor.h | 2 +- asoc/codecs/wsa881x.c | 2 +- asoc/codecs/wsa881x.h | 2 +- asoc/device_event.h | 2 +- asoc/machine_815x_init.c | 2 +- asoc/machine_815x_init.h | 2 +- asoc/msm-audio-effects-q6-v2.c | 2 +- asoc/msm-compress-q6-v2.c | 2 +- asoc/msm-cpe-lsm.c | 2 +- asoc/msm-dai-fe.c | 2 +- asoc/msm-dai-q6-hdmi-v2.c | 2 +- asoc/msm-dai-q6-v2.c | 2 +- asoc/msm-dai-q6-v2.h | 2 +- asoc/msm-dai-slim.c | 2 +- asoc/msm-dai-stub-v2.c | 2 +- asoc/msm-dolby-common.h | 2 +- asoc/msm-dolby-dap-config.h | 2 +- asoc/msm-ds2-dap-config.c | 2 +- asoc/msm-ds2-dap-config.h | 2 +- asoc/msm-lsm-client.c | 2 +- asoc/msm-pcm-afe-v2.c | 2 +- asoc/msm-pcm-afe-v2.h | 2 +- asoc/msm-pcm-dtmf-v2.c | 2 +- asoc/msm-pcm-host-voice-v2.c | 2 +- asoc/msm-pcm-hostless.c | 2 +- asoc/msm-pcm-loopback-v2.c | 2 +- asoc/msm-pcm-q6-noirq.c | 2 +- asoc/msm-pcm-q6-v2.c | 2 +- asoc/msm-pcm-q6-v2.h | 2 +- asoc/msm-pcm-routing-devdep.c | 2 +- asoc/msm-pcm-routing-devdep.h | 2 +- asoc/msm-pcm-routing-v2.c | 2 +- asoc/msm-pcm-routing-v2.h | 2 +- asoc/msm-pcm-voice-v2.c | 2 +- asoc/msm-pcm-voice-v2.h | 2 +- asoc/msm-pcm-voip-v2.c | 2 +- asoc/msm-qti-pp-config.c | 2 +- asoc/msm-qti-pp-config.h | 2 +- asoc/msm-slim-dma.h | 2 +- asoc/msm-transcode-loopback-q6-v2.c | 2 +- asoc/platform_init.c | 2 +- asoc/platform_init.h | 2 +- asoc/qcs405.c | 2 +- asoc/sa8155.c | 2 +- asoc/sm6150.c | 2 +- asoc/sm8150.c | 2 +- config/qcs405autoconf.h | 2 +- config/sdxpoorwillsautoconf.h | 2 +- config/sm6150autoconf.h | 2 +- config/sm8150autoconf.h | 2 +- dsp/codecs/aac_in.c | 2 +- dsp/codecs/amrnb_in.c | 2 +- dsp/codecs/amrwb_in.c | 2 +- dsp/codecs/audio_aac.c | 2 +- dsp/codecs/audio_alac.c | 2 +- dsp/codecs/audio_amrnb.c | 2 +- dsp/codecs/audio_amrwb.c | 2 +- dsp/codecs/audio_amrwbplus.c | 2 +- dsp/codecs/audio_ape.c | 2 +- dsp/codecs/audio_evrc.c | 2 +- dsp/codecs/audio_g711alaw.c | 2 +- dsp/codecs/audio_g711mlaw.c | 2 +- dsp/codecs/audio_hwacc_effects.c | 2 +- dsp/codecs/audio_mp3.c | 2 +- dsp/codecs/audio_multi_aac.c | 2 +- dsp/codecs/audio_native.c | 2 +- dsp/codecs/audio_qcelp.c | 2 +- dsp/codecs/audio_utils.c | 2 +- dsp/codecs/audio_utils.h | 2 +- dsp/codecs/audio_utils_aio.c | 2 +- dsp/codecs/audio_utils_aio.h | 2 +- dsp/codecs/audio_wma.c | 2 +- dsp/codecs/audio_wmapro.c | 2 +- dsp/codecs/evrc_in.c | 2 +- dsp/codecs/g711alaw_in.c | 2 +- dsp/codecs/g711mlaw_in.c | 2 +- dsp/codecs/q6audio_common.h | 2 +- dsp/codecs/q6audio_v2.c | 2 +- dsp/codecs/q6audio_v2_aio.c | 2 +- dsp/codecs/qcelp_in.c | 2 +- include/asoc/wcd-irq.h | 2 +- include/asoc/wcd934x_registers.h | 2 +- include/asoc/wcd9xxx_registers.h | 2 +- include/dsp/apr_audio-v2.h | 2 +- include/dsp/audio_cal_utils.h | 2 +- include/dsp/audio_calibration.h | 2 +- include/dsp/audio_notifier.h | 2 +- include/dsp/msm-audio-effects-q6-v2.h | 2 +- include/dsp/msm-audio-event-notify.h | 2 +- include/dsp/msm-dts-srs-tm-config.h | 2 +- include/dsp/msm_audio_ion.h | 2 +- include/dsp/msm_mdf.h | 2 +- include/dsp/q6adm-v2.h | 2 +- include/dsp/q6afe-v2.h | 2 +- include/dsp/q6asm-v2.h | 2 +- include/dsp/q6audio-v2.h | 2 +- include/dsp/q6common.h | 2 +- include/dsp/q6core.h | 2 +- include/dsp/q6lsm.h | 2 +- include/dsp/q6voice.h | 2 +- include/dsp/rtac.h | 2 +- include/ipc/apr.h | 2 +- include/ipc/apr_tal.h | 2 +- include/ipc/apr_us.h | 2 +- include/soc/snd_event.h | 2 +- include/soc/soundwire.h | 2 +- include/soc/swr-wcd.h | 2 +- include/uapi/linux/msm_audio.h | 2 +- ipc/apr.c | 2 +- ipc/apr_tal_rpmsg.c | 2 +- ipc/apr_v2.c | 2 +- ipc/apr_v3.c | 2 +- ipc/wcd-dsp-glink.c | 2 +- soc/pinctrl-lpi.c | 2 +- soc/pinctrl-wcd.c | 2 +- soc/regmap-swr.c | 2 +- soc/snd_event.c | 2 +- soc/soundwire.c | 2 +- soc/swr-mstr-ctrl.c | 2 +- soc/swr-mstr-ctrl.h | 2 +- soc/swr-wcd-ctrl.c | 2 +- soc/swr-wcd-ctrl.h | 2 +- soc/swrm_port_config.h | 2 +- soc/swrm_registers.h | 2 +- 240 files changed, 240 insertions(+), 241 deletions(-) diff --git a/asoc/codecs/aqt1000/aqt1000-api.h b/asoc/codecs/aqt1000/aqt1000-api.h index fc5d23a57e7c..bf90fad02a2a 100644 --- a/asoc/codecs/aqt1000/aqt1000-api.h +++ b/asoc/codecs/aqt1000/aqt1000-api.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/aqt1000/aqt1000-clsh.c b/asoc/codecs/aqt1000/aqt1000-clsh.c index 218425b5256a..ef70cc941c81 100644 --- a/asoc/codecs/aqt1000/aqt1000-clsh.c +++ b/asoc/codecs/aqt1000/aqt1000-clsh.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/aqt1000/aqt1000-clsh.h b/asoc/codecs/aqt1000/aqt1000-clsh.h index 7079450a73d0..5a0b427a65a6 100644 --- a/asoc/codecs/aqt1000/aqt1000-clsh.h +++ b/asoc/codecs/aqt1000/aqt1000-clsh.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/aqt1000/aqt1000-core.c b/asoc/codecs/aqt1000/aqt1000-core.c index e643b6afc899..e5562a4d3001 100644 --- a/asoc/codecs/aqt1000/aqt1000-core.c +++ b/asoc/codecs/aqt1000/aqt1000-core.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/aqt1000/aqt1000-internal.h b/asoc/codecs/aqt1000/aqt1000-internal.h index abfae1b2bc4c..0ae66703f014 100644 --- a/asoc/codecs/aqt1000/aqt1000-internal.h +++ b/asoc/codecs/aqt1000/aqt1000-internal.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/aqt1000/aqt1000-irq.c b/asoc/codecs/aqt1000/aqt1000-irq.c index 5f715738aa32..34d647a8f89e 100644 --- a/asoc/codecs/aqt1000/aqt1000-irq.c +++ b/asoc/codecs/aqt1000/aqt1000-irq.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/aqt1000/aqt1000-irq.h b/asoc/codecs/aqt1000/aqt1000-irq.h index cd1a95f37462..6fb29b1a6852 100644 --- a/asoc/codecs/aqt1000/aqt1000-irq.h +++ b/asoc/codecs/aqt1000/aqt1000-irq.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/aqt1000/aqt1000-mbhc.c b/asoc/codecs/aqt1000/aqt1000-mbhc.c index 4146c6bfbbf6..66449b2db3f9 100644 --- a/asoc/codecs/aqt1000/aqt1000-mbhc.c +++ b/asoc/codecs/aqt1000/aqt1000-mbhc.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #include diff --git a/asoc/codecs/aqt1000/aqt1000-mbhc.h b/asoc/codecs/aqt1000/aqt1000-mbhc.h index aea788cc5e37..b6ce8751559b 100644 --- a/asoc/codecs/aqt1000/aqt1000-mbhc.h +++ b/asoc/codecs/aqt1000/aqt1000-mbhc.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #ifndef __AQT1000_MBHC_H__ diff --git a/asoc/codecs/aqt1000/aqt1000-reg-defaults.h b/asoc/codecs/aqt1000/aqt1000-reg-defaults.h index edcfe07599f3..760289bb637f 100644 --- a/asoc/codecs/aqt1000/aqt1000-reg-defaults.h +++ b/asoc/codecs/aqt1000/aqt1000-reg-defaults.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/aqt1000/aqt1000-registers.h b/asoc/codecs/aqt1000/aqt1000-registers.h index e2b6770d2746..1ba388255feb 100644 --- a/asoc/codecs/aqt1000/aqt1000-registers.h +++ b/asoc/codecs/aqt1000/aqt1000-registers.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/aqt1000/aqt1000-regmap.c b/asoc/codecs/aqt1000/aqt1000-regmap.c index 67bcd26d5029..31002fa9e2a9 100644 --- a/asoc/codecs/aqt1000/aqt1000-regmap.c +++ b/asoc/codecs/aqt1000/aqt1000-regmap.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/aqt1000/aqt1000-routing.h b/asoc/codecs/aqt1000/aqt1000-routing.h index 6a3d8953aff6..876f62278b41 100644 --- a/asoc/codecs/aqt1000/aqt1000-routing.h +++ b/asoc/codecs/aqt1000/aqt1000-routing.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ #ifndef AQT1000_ROUTING_H diff --git a/asoc/codecs/aqt1000/aqt1000-utils.c b/asoc/codecs/aqt1000/aqt1000-utils.c index a788b5d37ffc..078be0b942a3 100644 --- a/asoc/codecs/aqt1000/aqt1000-utils.c +++ b/asoc/codecs/aqt1000/aqt1000-utils.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/aqt1000/aqt1000-utils.h b/asoc/codecs/aqt1000/aqt1000-utils.h index c2c7aeb3cc35..72c8fcf39691 100644 --- a/asoc/codecs/aqt1000/aqt1000-utils.h +++ b/asoc/codecs/aqt1000/aqt1000-utils.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/aqt1000/aqt1000.c b/asoc/codecs/aqt1000/aqt1000.c index ef0c265e0a89..1ba5605b62b0 100644 --- a/asoc/codecs/aqt1000/aqt1000.c +++ b/asoc/codecs/aqt1000/aqt1000.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ #include diff --git a/asoc/codecs/aqt1000/aqt1000.h b/asoc/codecs/aqt1000/aqt1000.h index 6148213f651e..ebc646050f9e 100644 --- a/asoc/codecs/aqt1000/aqt1000.h +++ b/asoc/codecs/aqt1000/aqt1000.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/aqt1000/pdata.h b/asoc/codecs/aqt1000/pdata.h index 89fcb3cee3de..c490b56d1d3a 100644 --- a/asoc/codecs/aqt1000/pdata.h +++ b/asoc/codecs/aqt1000/pdata.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index 74ab9e243a5b..0d95ff1041ea 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/audio-ext-clk-up.h b/asoc/codecs/audio-ext-clk-up.h index 655189731773..e7c195405ed4 100644 --- a/asoc/codecs/audio-ext-clk-up.h +++ b/asoc/codecs/audio-ext-clk-up.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/audio-ext-clk.c b/asoc/codecs/audio-ext-clk.c index c06c9c5662fe..07556ee59086 100644 --- a/asoc/codecs/audio-ext-clk.c +++ b/asoc/codecs/audio-ext-clk.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/bolero/bolero-cdc-registers.h b/asoc/codecs/bolero/bolero-cdc-registers.h index 5f88c85988f8..99890cc9fb9d 100644 --- a/asoc/codecs/bolero/bolero-cdc-registers.h +++ b/asoc/codecs/bolero/bolero-cdc-registers.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/bolero/bolero-cdc-regmap.c b/asoc/codecs/bolero/bolero-cdc-regmap.c index 8f55ff29b50b..a0ecd83565c5 100644 --- a/asoc/codecs/bolero/bolero-cdc-regmap.c +++ b/asoc/codecs/bolero/bolero-cdc-regmap.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/bolero/bolero-cdc-tables.c b/asoc/codecs/bolero/bolero-cdc-tables.c index e92508fd0280..529876336897 100644 --- a/asoc/codecs/bolero/bolero-cdc-tables.c +++ b/asoc/codecs/bolero/bolero-cdc-tables.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018 The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/bolero/bolero-cdc-utils.c b/asoc/codecs/bolero/bolero-cdc-utils.c index 6acf69eac71f..b2fd15325b1c 100644 --- a/asoc/codecs/bolero/bolero-cdc-utils.c +++ b/asoc/codecs/bolero/bolero-cdc-utils.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 2d63c431cfe8..aec455a3628b 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 386fa628bf2b..488ccf7eb506 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index be00482a3e5f..909333420897 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 75a3a0a15d93..6e0916eaf430 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 96182d3c86c8..c33a857acbaa 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 985424a5b6ba..da68da847e30 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 9586770f77cc..d761d942bd7b 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/bolero/wsa-macro.h b/asoc/codecs/bolero/wsa-macro.h index f2553c02d30a..a4dc77f8f87a 100644 --- a/asoc/codecs/bolero/wsa-macro.h +++ b/asoc/codecs/bolero/wsa-macro.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ #ifndef WSA_MACRO_H diff --git a/asoc/codecs/core.h b/asoc/codecs/core.h index ab0f0c724156..8acfa26d863d 100644 --- a/asoc/codecs/core.h +++ b/asoc/codecs/core.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/cpe_cmi.h b/asoc/codecs/cpe_cmi.h index 21df2ae2b837..cd94c71826cb 100644 --- a/asoc/codecs/cpe_cmi.h +++ b/asoc/codecs/cpe_cmi.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/cpe_core.h b/asoc/codecs/cpe_core.h index 7cfbd43302d3..86f1c57593c6 100644 --- a/asoc/codecs/cpe_core.h +++ b/asoc/codecs/cpe_core.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/cpe_err.h b/asoc/codecs/cpe_err.h index 5a2dea1bc2b4..29ea92292646 100644 --- a/asoc/codecs/cpe_err.h +++ b/asoc/codecs/cpe_err.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015, 2017, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/csra66x0/csra66x0.c b/asoc/codecs/csra66x0/csra66x0.c index 33e53340f282..595e7ca8fa03 100644 --- a/asoc/codecs/csra66x0/csra66x0.c +++ b/asoc/codecs/csra66x0/csra66x0.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/csra66x0/csra66x0.h b/asoc/codecs/csra66x0/csra66x0.h index c449d670dc37..2ff651c73575 100644 --- a/asoc/codecs/csra66x0/csra66x0.h +++ b/asoc/codecs/csra66x0/csra66x0.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/ep92/ep92.c b/asoc/codecs/ep92/ep92.c index 81ff656b9273..c2cce8e2af49 100644 --- a/asoc/codecs/ep92/ep92.c +++ b/asoc/codecs/ep92/ep92.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/ep92/ep92.h b/asoc/codecs/ep92/ep92.h index 7aafab2aa8f3..bfc8d8000d87 100644 --- a/asoc/codecs/ep92/ep92.h +++ b/asoc/codecs/ep92/ep92.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/msm-cdc-pinctrl.c b/asoc/codecs/msm-cdc-pinctrl.c index 901864ab5a07..142e73d27e22 100644 --- a/asoc/codecs/msm-cdc-pinctrl.c +++ b/asoc/codecs/msm-cdc-pinctrl.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/msm-cdc-pinctrl.h b/asoc/codecs/msm-cdc-pinctrl.h index 3bd344318b6c..4024d90becde 100644 --- a/asoc/codecs/msm-cdc-pinctrl.h +++ b/asoc/codecs/msm-cdc-pinctrl.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/msm-cdc-supply.c b/asoc/codecs/msm-cdc-supply.c index 751d81e06897..16dfebbf1f0b 100644 --- a/asoc/codecs/msm-cdc-supply.c +++ b/asoc/codecs/msm-cdc-supply.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/msm-cdc-supply.h b/asoc/codecs/msm-cdc-supply.h index 6d7b41a8d49c..9801115c31b9 100644 --- a/asoc/codecs/msm-cdc-supply.h +++ b/asoc/codecs/msm-cdc-supply.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2016, 2018 The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/msm_hdmi_codec_rx.c b/asoc/codecs/msm_hdmi_codec_rx.c index 95bb26d027e3..0c142f1fd6b2 100644 --- a/asoc/codecs/msm_hdmi_codec_rx.c +++ b/asoc/codecs/msm_hdmi_codec_rx.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ #include diff --git a/asoc/codecs/msm_stub.c b/asoc/codecs/msm_stub.c index a27111aeac96..a754c49ee383 100644 --- a/asoc/codecs/msm_stub.c +++ b/asoc/codecs/msm_stub.c @@ -1,6 +1,5 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2011-2014, 2017-2018 The Linux Foundation. All rights reserved. - */ #include #include diff --git a/asoc/codecs/pdata.h b/asoc/codecs/pdata.h index c19c11893d70..1182ef7881a6 100644 --- a/asoc/codecs/pdata.h +++ b/asoc/codecs/pdata.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd-clsh.c b/asoc/codecs/wcd-clsh.c index 7aec959474aa..834454afab3a 100644 --- a/asoc/codecs/wcd-clsh.c +++ b/asoc/codecs/wcd-clsh.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd-clsh.h b/asoc/codecs/wcd-clsh.h index 1a7759ef0e9a..64250e1b6323 100644 --- a/asoc/codecs/wcd-clsh.h +++ b/asoc/codecs/wcd-clsh.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd-dsp-mgr.c b/asoc/codecs/wcd-dsp-mgr.c index 612161f094ed..e0070e659e64 100644 --- a/asoc/codecs/wcd-dsp-mgr.c +++ b/asoc/codecs/wcd-dsp-mgr.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd-dsp-utils.c b/asoc/codecs/wcd-dsp-utils.c index 2e24de9419ab..c157ab1c32ee 100644 --- a/asoc/codecs/wcd-dsp-utils.c +++ b/asoc/codecs/wcd-dsp-utils.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd-dsp-utils.h b/asoc/codecs/wcd-dsp-utils.h index 1016fc099351..3fb42e458397 100644 --- a/asoc/codecs/wcd-dsp-utils.h +++ b/asoc/codecs/wcd-dsp-utils.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd-irq.c b/asoc/codecs/wcd-irq.c index d294d40f598b..3c8e777ec859 100644 --- a/asoc/codecs/wcd-irq.c +++ b/asoc/codecs/wcd-irq.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index c7882d6cb3fb..2b596c3ac276 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ #include diff --git a/asoc/codecs/wcd-mbhc-adc.h b/asoc/codecs/wcd-mbhc-adc.h index 9383d1ad3bca..95e0ff2f154d 100644 --- a/asoc/codecs/wcd-mbhc-adc.h +++ b/asoc/codecs/wcd-mbhc-adc.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2017, The Linux Foundation. All rights reserved. */ #ifndef __WCD_MBHC_ADC_H__ diff --git a/asoc/codecs/wcd-mbhc-legacy.c b/asoc/codecs/wcd-mbhc-legacy.c index 4b8917d156e3..94c4560bf41d 100644 --- a/asoc/codecs/wcd-mbhc-legacy.c +++ b/asoc/codecs/wcd-mbhc-legacy.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #include diff --git a/asoc/codecs/wcd-mbhc-legacy.h b/asoc/codecs/wcd-mbhc-legacy.h index a79b673313c4..c7835c596383 100644 --- a/asoc/codecs/wcd-mbhc-legacy.h +++ b/asoc/codecs/wcd-mbhc-legacy.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. */ #ifndef __WCD_MBHC_LEGACY_H__ diff --git a/asoc/codecs/wcd-mbhc-v2-api.h b/asoc/codecs/wcd-mbhc-v2-api.h index fc00e14174fd..ef5efc668c29 100644 --- a/asoc/codecs/wcd-mbhc-v2-api.h +++ b/asoc/codecs/wcd-mbhc-v2-api.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. */ #ifndef __WCD_MBHC_V2_API_H__ diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 971cf519ba30..162ccde7e075 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #include diff --git a/asoc/codecs/wcd-mbhc-v2.h b/asoc/codecs/wcd-mbhc-v2.h index 451ca91cd816..c98cdda944c9 100644 --- a/asoc/codecs/wcd-mbhc-v2.h +++ b/asoc/codecs/wcd-mbhc-v2.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. */ #ifndef __WCD_MBHC_V2_H__ diff --git a/asoc/codecs/wcd-spi-registers.h b/asoc/codecs/wcd-spi-registers.h index df48cd076409..e0d9612af015 100644 --- a/asoc/codecs/wcd-spi-registers.h +++ b/asoc/codecs/wcd-spi-registers.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd-spi.c b/asoc/codecs/wcd-spi.c index 9acf24afdcf7..35b0d93b468a 100644 --- a/asoc/codecs/wcd-spi.c +++ b/asoc/codecs/wcd-spi.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9335-regmap.c b/asoc/codecs/wcd9335-regmap.c index 9d1ccb84e067..0a83fd582cbc 100644 --- a/asoc/codecs/wcd9335-regmap.c +++ b/asoc/codecs/wcd9335-regmap.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9335-tables.c b/asoc/codecs/wcd9335-tables.c index cd223c9a83f0..991b2bc0dcdc 100644 --- a/asoc/codecs/wcd9335-tables.c +++ b/asoc/codecs/wcd9335-tables.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 740f232b709f..2372e20b7b61 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9335.h b/asoc/codecs/wcd9335.h index 203c6de0aaba..261ea407a673 100644 --- a/asoc/codecs/wcd9335.h +++ b/asoc/codecs/wcd9335.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9335_irq.h b/asoc/codecs/wcd9335_irq.h index ae81a1ab450b..39a223d026ba 100644 --- a/asoc/codecs/wcd9335_irq.h +++ b/asoc/codecs/wcd9335_irq.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9335_registers.h b/asoc/codecs/wcd9335_registers.h index 4af4e1b5fd74..19a942c2a6be 100644 --- a/asoc/codecs/wcd9335_registers.h +++ b/asoc/codecs/wcd9335_registers.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd934x/wcd934x-dsd.c b/asoc/codecs/wcd934x/wcd934x-dsd.c index 0a9c55696ce7..98f126481a65 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsd.c +++ b/asoc/codecs/wcd934x/wcd934x-dsd.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd934x/wcd934x-dsd.h b/asoc/codecs/wcd934x/wcd934x-dsd.h index e078c077f807..0dc4516b2cce 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsd.h +++ b/asoc/codecs/wcd934x/wcd934x-dsd.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c index e64b1588a82e..0c6c6f033282 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h index a4b18a3cbae4..2bb55f99bb8d 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd934x/wcd934x-mbhc.c b/asoc/codecs/wcd934x/wcd934x-mbhc.c index 7a91bf348288..5801f311385b 100644 --- a/asoc/codecs/wcd934x/wcd934x-mbhc.c +++ b/asoc/codecs/wcd934x/wcd934x-mbhc.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd934x/wcd934x-mbhc.h b/asoc/codecs/wcd934x/wcd934x-mbhc.h index 69cd46033678..a0bd05a2aa82 100644 --- a/asoc/codecs/wcd934x/wcd934x-mbhc.h +++ b/asoc/codecs/wcd934x/wcd934x-mbhc.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd934x/wcd934x-regmap.c b/asoc/codecs/wcd934x/wcd934x-regmap.c index 051586fa6172..2a2187f953a1 100644 --- a/asoc/codecs/wcd934x/wcd934x-regmap.c +++ b/asoc/codecs/wcd934x/wcd934x-regmap.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd934x/wcd934x-routing.h b/asoc/codecs/wcd934x/wcd934x-routing.h index 51a361848a3f..771f91f1cbab 100644 --- a/asoc/codecs/wcd934x/wcd934x-routing.h +++ b/asoc/codecs/wcd934x/wcd934x-routing.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd934x/wcd934x-tables.c b/asoc/codecs/wcd934x/wcd934x-tables.c index afe7939c43e9..a74004fc25e6 100644 --- a/asoc/codecs/wcd934x/wcd934x-tables.c +++ b/asoc/codecs/wcd934x/wcd934x-tables.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index d930ec83ad21..250a483387a0 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #include diff --git a/asoc/codecs/wcd934x/wcd934x.h b/asoc/codecs/wcd934x/wcd934x.h index a14e6eb05091..8d5aec500294 100644 --- a/asoc/codecs/wcd934x/wcd934x.h +++ b/asoc/codecs/wcd934x/wcd934x.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd934x/wcd934x_irq.h b/asoc/codecs/wcd934x/wcd934x_irq.h index 7c054ea436c9..b880e97f2046 100644 --- a/asoc/codecs/wcd934x/wcd934x_irq.h +++ b/asoc/codecs/wcd934x/wcd934x_irq.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index b4165115b8b1..8e6928ad4c65 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index 543897628acd..7ffa11744e31 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ #include diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.h b/asoc/codecs/wcd937x/wcd937x-mbhc.h index d7bfb16954a7..3ac42ef5ada2 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.h +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ #ifndef __WCD937X_MBHC_H__ diff --git a/asoc/codecs/wcd937x/wcd937x-registers.h b/asoc/codecs/wcd937x/wcd937x-registers.h index c7ee8e6d3266..be818c28af10 100644 --- a/asoc/codecs/wcd937x/wcd937x-registers.h +++ b/asoc/codecs/wcd937x/wcd937x-registers.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd937x/wcd937x-regmap.c b/asoc/codecs/wcd937x/wcd937x-regmap.c index 205dfe461121..2bb70ca9b6dd 100644 --- a/asoc/codecs/wcd937x/wcd937x-regmap.c +++ b/asoc/codecs/wcd937x/wcd937x-regmap.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd937x/wcd937x-tables.c b/asoc/codecs/wcd937x/wcd937x-tables.c index a1f6d10f022b..0a58c87a2c4c 100644 --- a/asoc/codecs/wcd937x/wcd937x-tables.c +++ b/asoc/codecs/wcd937x/wcd937x-tables.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018 , The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index fbd553a841a4..8810fec525d8 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd937x/wcd937x.h b/asoc/codecs/wcd937x/wcd937x.h index a40554e1963f..27d7c6e62d1c 100644 --- a/asoc/codecs/wcd937x/wcd937x.h +++ b/asoc/codecs/wcd937x/wcd937x.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd937x/wcd937x_slave.c b/asoc/codecs/wcd937x/wcd937x_slave.c index 61b6a0c1923d..761e5fe5bacd 100644 --- a/asoc/codecs/wcd937x/wcd937x_slave.c +++ b/asoc/codecs/wcd937x/wcd937x_slave.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9xxx-common-v2.c b/asoc/codecs/wcd9xxx-common-v2.c index d45a071b1db5..56a3fa59e9ce 100644 --- a/asoc/codecs/wcd9xxx-common-v2.c +++ b/asoc/codecs/wcd9xxx-common-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9xxx-common-v2.h b/asoc/codecs/wcd9xxx-common-v2.h index 21eadd7c6a77..1334b711aa17 100644 --- a/asoc/codecs/wcd9xxx-common-v2.h +++ b/asoc/codecs/wcd9xxx-common-v2.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9xxx-core-init.c b/asoc/codecs/wcd9xxx-core-init.c index ee1ba516b1a6..bb865a982416 100644 --- a/asoc/codecs/wcd9xxx-core-init.c +++ b/asoc/codecs/wcd9xxx-core-init.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2017, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index 28b0708604e1..5794ef214153 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9xxx-irq.c b/asoc/codecs/wcd9xxx-irq.c index 5b685fbdcc9f..06dbf75d6118 100644 --- a/asoc/codecs/wcd9xxx-irq.c +++ b/asoc/codecs/wcd9xxx-irq.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. */ #include diff --git a/asoc/codecs/wcd9xxx-irq.h b/asoc/codecs/wcd9xxx-irq.h index 83f86b3beff2..2c7e7ec6352f 100644 --- a/asoc/codecs/wcd9xxx-irq.h +++ b/asoc/codecs/wcd9xxx-irq.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9xxx-regmap.h b/asoc/codecs/wcd9xxx-regmap.h index 2c7af0d0471f..19b9de3a6363 100644 --- a/asoc/codecs/wcd9xxx-regmap.h +++ b/asoc/codecs/wcd9xxx-regmap.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9xxx-resmgr-v2.c b/asoc/codecs/wcd9xxx-resmgr-v2.c index 4636f43b4bb5..f280fcc1eb53 100644 --- a/asoc/codecs/wcd9xxx-resmgr-v2.c +++ b/asoc/codecs/wcd9xxx-resmgr-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9xxx-resmgr-v2.h b/asoc/codecs/wcd9xxx-resmgr-v2.h index 8eceb8392d04..a4b919f969c1 100644 --- a/asoc/codecs/wcd9xxx-resmgr-v2.h +++ b/asoc/codecs/wcd9xxx-resmgr-v2.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9xxx-rst.c b/asoc/codecs/wcd9xxx-rst.c index 84225deb47c3..4a729a0a545a 100644 --- a/asoc/codecs/wcd9xxx-rst.c +++ b/asoc/codecs/wcd9xxx-rst.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9xxx-slimslave.c b/asoc/codecs/wcd9xxx-slimslave.c index 3636bb55d261..a4f07ef0f8da 100644 --- a/asoc/codecs/wcd9xxx-slimslave.c +++ b/asoc/codecs/wcd9xxx-slimslave.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. */ #include diff --git a/asoc/codecs/wcd9xxx-slimslave.h b/asoc/codecs/wcd9xxx-slimslave.h index 9ab74043b7bb..70b9a4c92bbd 100644 --- a/asoc/codecs/wcd9xxx-slimslave.h +++ b/asoc/codecs/wcd9xxx-slimslave.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9xxx-soc-init.c b/asoc/codecs/wcd9xxx-soc-init.c index 4e2d837c29e8..06a991ca99a2 100644 --- a/asoc/codecs/wcd9xxx-soc-init.c +++ b/asoc/codecs/wcd9xxx-soc-init.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9xxx-utils.c b/asoc/codecs/wcd9xxx-utils.c index 0e238fcb55de..bcc909b8fc8c 100644 --- a/asoc/codecs/wcd9xxx-utils.c +++ b/asoc/codecs/wcd9xxx-utils.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd9xxx-utils.h b/asoc/codecs/wcd9xxx-utils.h index 17bb9fd1750b..1e063abfb5f5 100644 --- a/asoc/codecs/wcd9xxx-utils.h +++ b/asoc/codecs/wcd9xxx-utils.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd_cmi_api.h b/asoc/codecs/wcd_cmi_api.h index bc7bd8621efb..b02c66583604 100644 --- a/asoc/codecs/wcd_cmi_api.h +++ b/asoc/codecs/wcd_cmi_api.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2014, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd_cpe_core.c b/asoc/codecs/wcd_cpe_core.c index 00a384369c07..629b803d7d9a 100644 --- a/asoc/codecs/wcd_cpe_core.c +++ b/asoc/codecs/wcd_cpe_core.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd_cpe_core.h b/asoc/codecs/wcd_cpe_core.h index 105ece0a97f3..b16503d9cbde 100644 --- a/asoc/codecs/wcd_cpe_core.h +++ b/asoc/codecs/wcd_cpe_core.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd_cpe_services.c b/asoc/codecs/wcd_cpe_services.c index a443963b4596..fd8e8090d28d 100644 --- a/asoc/codecs/wcd_cpe_services.c +++ b/asoc/codecs/wcd_cpe_services.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcd_cpe_services.h b/asoc/codecs/wcd_cpe_services.h index 1627cd888d2c..caf645bb5614 100644 --- a/asoc/codecs/wcd_cpe_services.h +++ b/asoc/codecs/wcd_cpe_services.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wcdcal-hwdep.c b/asoc/codecs/wcdcal-hwdep.c index 162c40746a02..e826eae3b834 100644 --- a/asoc/codecs/wcdcal-hwdep.c +++ b/asoc/codecs/wcdcal-hwdep.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved. * diff --git a/asoc/codecs/wcdcal-hwdep.h b/asoc/codecs/wcdcal-hwdep.h index 9606cd577f16..ddd5856a3b81 100644 --- a/asoc/codecs/wcdcal-hwdep.h +++ b/asoc/codecs/wcdcal-hwdep.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2014, 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wsa881x-registers.h b/asoc/codecs/wsa881x-registers.h index c39edef2203f..6e19b32b1145 100644 --- a/asoc/codecs/wsa881x-registers.h +++ b/asoc/codecs/wsa881x-registers.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2015, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wsa881x-regmap.c b/asoc/codecs/wsa881x-regmap.c index 8663db9776db..27e45a1878c3 100644 --- a/asoc/codecs/wsa881x-regmap.c +++ b/asoc/codecs/wsa881x-regmap.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wsa881x-tables.c b/asoc/codecs/wsa881x-tables.c index e53183252ae7..40d2fa244431 100644 --- a/asoc/codecs/wsa881x-tables.c +++ b/asoc/codecs/wsa881x-tables.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wsa881x-temp-sensor.c b/asoc/codecs/wsa881x-temp-sensor.c index 598449c13986..97f4d46f3335 100644 --- a/asoc/codecs/wsa881x-temp-sensor.c +++ b/asoc/codecs/wsa881x-temp-sensor.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wsa881x-temp-sensor.h b/asoc/codecs/wsa881x-temp-sensor.h index 7c9052615d85..fbb5941abab6 100644 --- a/asoc/codecs/wsa881x-temp-sensor.h +++ b/asoc/codecs/wsa881x-temp-sensor.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved. */ #ifndef WSA881X_TEMP_SENSOR_H diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index da33494e0f5f..4dceb0449c4e 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/codecs/wsa881x.h b/asoc/codecs/wsa881x.h index 3922fc835dae..0486a0fe9779 100644 --- a/asoc/codecs/wsa881x.h +++ b/asoc/codecs/wsa881x.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/device_event.h b/asoc/device_event.h index e63656ecd627..5327f0ef1a22 100644 --- a/asoc/device_event.h +++ b/asoc/device_event.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2014, The Linux Foundation. All rights reserved. */ diff --git a/asoc/machine_815x_init.c b/asoc/machine_815x_init.c index ff01a90e2c54..cf8fbed4bf86 100644 --- a/asoc/machine_815x_init.c +++ b/asoc/machine_815x_init.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/machine_815x_init.h b/asoc/machine_815x_init.h index d096d972e1ef..8ff46101898c 100644 --- a/asoc/machine_815x_init.h +++ b/asoc/machine_815x_init.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-audio-effects-q6-v2.c b/asoc/msm-audio-effects-q6-v2.c index dcc7474cef13..7ab6db4d3f30 100644 --- a/asoc/msm-audio-effects-q6-v2.c +++ b/asoc/msm-audio-effects-q6-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index bf22f87c8cf2..dd166cf51926 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-cpe-lsm.c b/asoc/msm-cpe-lsm.c index 19f57a1aab65..b1a6fe30c19f 100644 --- a/asoc/msm-cpe-lsm.c +++ b/asoc/msm-cpe-lsm.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index 36fa5dd2e64a..c4976a48a7f4 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-dai-q6-hdmi-v2.c b/asoc/msm-dai-q6-hdmi-v2.c index 69332fc073ac..32add91326f1 100644 --- a/asoc/msm-dai-q6-hdmi-v2.c +++ b/asoc/msm-dai-q6-hdmi-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index b77c08f02200..962a1bdfe7b0 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-dai-q6-v2.h b/asoc/msm-dai-q6-v2.h index 91737c9a7586..950ecd2e91c7 100644 --- a/asoc/msm-dai-q6-v2.h +++ b/asoc/msm-dai-q6-v2.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-dai-slim.c b/asoc/msm-dai-slim.c index db8f3dd64fae..545590fa3735 100644 --- a/asoc/msm-dai-slim.c +++ b/asoc/msm-dai-slim.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-dai-stub-v2.c b/asoc/msm-dai-stub-v2.c index 76ea52cde288..7e7d4e4a1334 100644 --- a/asoc/msm-dai-stub-v2.c +++ b/asoc/msm-dai-stub-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. */ #include diff --git a/asoc/msm-dolby-common.h b/asoc/msm-dolby-common.h index c56e11523043..46a2957593d4 100644 --- a/asoc/msm-dolby-common.h +++ b/asoc/msm-dolby-common.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-dolby-dap-config.h b/asoc/msm-dolby-dap-config.h index f7e21d685337..75d6e0718d20 100644 --- a/asoc/msm-dolby-dap-config.h +++ b/asoc/msm-dolby-dap-config.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2013-2014, 2017-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-ds2-dap-config.c b/asoc/msm-ds2-dap-config.c index 4971907360e8..f40b74b0479d 100644 --- a/asoc/msm-ds2-dap-config.c +++ b/asoc/msm-ds2-dap-config.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-ds2-dap-config.h b/asoc/msm-ds2-dap-config.h index d734790fcbee..165dbe186070 100644 --- a/asoc/msm-ds2-dap-config.h +++ b/asoc/msm-ds2-dap-config.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 74263e381434..6bf44c44ca04 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-pcm-afe-v2.c b/asoc/msm-pcm-afe-v2.c index a34514bb821d..e2961223b175 100644 --- a/asoc/msm-pcm-afe-v2.c +++ b/asoc/msm-pcm-afe-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-pcm-afe-v2.h b/asoc/msm-pcm-afe-v2.h index ca9dfccc604f..3c0d52089887 100644 --- a/asoc/msm-pcm-afe-v2.h +++ b/asoc/msm-pcm-afe-v2.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2012,2015-2016 The Linux Foundation. All rights reserved. */ #ifndef _MSM_PCM_AFE_H diff --git a/asoc/msm-pcm-dtmf-v2.c b/asoc/msm-pcm-dtmf-v2.c index e8eb468090fb..58ae5fa6920f 100644 --- a/asoc/msm-pcm-dtmf-v2.c +++ b/asoc/msm-pcm-dtmf-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2013-2014, 2017-2018 The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-pcm-host-voice-v2.c b/asoc/msm-pcm-host-voice-v2.c index 9fc7c8867953..49e9591120b5 100644 --- a/asoc/msm-pcm-host-voice-v2.c +++ b/asoc/msm-pcm-host-voice-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-pcm-hostless.c b/asoc/msm-pcm-hostless.c index 9a0c52b01169..3109b72d9538 100644 --- a/asoc/msm-pcm-hostless.c +++ b/asoc/msm-pcm-hostless.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2011-2014, 2017-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index 9b90935b6dac..b516634fd1b3 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index aac3fe022938..a317142b642e 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 1ad10db61ff5..50186daeb417 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-pcm-q6-v2.h b/asoc/msm-pcm-q6-v2.h index ca18a85ccd68..8699a4825ce5 100644 --- a/asoc/msm-pcm-q6-v2.h +++ b/asoc/msm-pcm-q6-v2.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation diff --git a/asoc/msm-pcm-routing-devdep.c b/asoc/msm-pcm-routing-devdep.c index 6d26c54e5483..cddc2a1e3f26 100644 --- a/asoc/msm-pcm-routing-devdep.c +++ b/asoc/msm-pcm-routing-devdep.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2014, 2016-2017 The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-pcm-routing-devdep.h b/asoc/msm-pcm-routing-devdep.h index 651edd9d96b6..ac3594af2d56 100644 --- a/asoc/msm-pcm-routing-devdep.h +++ b/asoc/msm-pcm-routing-devdep.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2014-2015, 2017 The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index db5713b8e370..936f97fc13d4 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 92fd3c205d81..02d1f54bd8da 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ #ifndef _MSM_PCM_ROUTING_H diff --git a/asoc/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c index 3fd83391331b..e4d34d1bf67f 100644 --- a/asoc/msm-pcm-voice-v2.c +++ b/asoc/msm-pcm-voice-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-pcm-voice-v2.h b/asoc/msm-pcm-voice-v2.h index 671c1aad522e..d300abf9b15b 100644 --- a/asoc/msm-pcm-voice-v2.h +++ b/asoc/msm-pcm-voice-v2.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. */ #ifndef _MSM_PCM_VOICE_H diff --git a/asoc/msm-pcm-voip-v2.c b/asoc/msm-pcm-voip-v2.c index ac12b90c8371..3bfa4d6cb0e3 100644 --- a/asoc/msm-pcm-voip-v2.c +++ b/asoc/msm-pcm-voip-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index e5d1ba2048d8..222a3a953236 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-qti-pp-config.h b/asoc/msm-qti-pp-config.h index 8d103375c45e..7fddb9f49840 100644 --- a/asoc/msm-qti-pp-config.h +++ b/asoc/msm-qti-pp-config.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/msm-slim-dma.h b/asoc/msm-slim-dma.h index f179a2e4dba7..911ce1f4dba8 100644 --- a/asoc/msm-slim-dma.h +++ b/asoc/msm-slim-dma.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2014, 2017 The Linux Foundation. All rights reserved. * diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index 12863a28102c..277ad3c44539 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/platform_init.c b/asoc/platform_init.c index 3b72ebe49c9d..e9ff68fc30a8 100644 --- a/asoc/platform_init.c +++ b/asoc/platform_init.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017 The Linux Foundation. All rights reserved. */ diff --git a/asoc/platform_init.h b/asoc/platform_init.h index ff5eafb6b85e..17f07845e627 100644 --- a/asoc/platform_init.h +++ b/asoc/platform_init.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017, The Linux Foundation. All rights reserved. */ diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 4d1de74b3746..781521ab9085 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ #include diff --git a/asoc/sa8155.c b/asoc/sa8155.c index 879119584db4..f5aa549516ec 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. */ /* diff --git a/asoc/sm6150.c b/asoc/sm6150.c index a2abeb63731c..e2277a27eca4 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/asoc/sm8150.c b/asoc/sm8150.c index 7328be3eaf19..a34731076c4c 100644 --- a/asoc/sm8150.c +++ b/asoc/sm8150.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/config/qcs405autoconf.h b/config/qcs405autoconf.h index 07e5429da89b..0a2e2865aa48 100644 --- a/config/qcs405autoconf.h +++ b/config/qcs405autoconf.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/config/sdxpoorwillsautoconf.h b/config/sdxpoorwillsautoconf.h index 9d7158ec6d55..49bbe41c0bec 100644 --- a/config/sdxpoorwillsautoconf.h +++ b/config/sdxpoorwillsautoconf.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ diff --git a/config/sm6150autoconf.h b/config/sm6150autoconf.h index 2a63d0423ce3..9a3cdd0ad898 100644 --- a/config/sm6150autoconf.h +++ b/config/sm6150autoconf.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/config/sm8150autoconf.h b/config/sm8150autoconf.h index 6f21874ad22a..0c19fd39f9c3 100644 --- a/config/sm8150autoconf.h +++ b/config/sm8150autoconf.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/aac_in.c b/dsp/codecs/aac_in.c index 11e7bcca0b75..04f69876ab6b 100644 --- a/dsp/codecs/aac_in.c +++ b/dsp/codecs/aac_in.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/amrnb_in.c b/dsp/codecs/amrnb_in.c index 266d9c875c35..924ac5c7f51c 100644 --- a/dsp/codecs/amrnb_in.c +++ b/dsp/codecs/amrnb_in.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2010-2012, 2014, 2016-2017 The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/amrwb_in.c b/dsp/codecs/amrwb_in.c index 6435f25e14b0..9a9b4a0ae9ae 100644 --- a/dsp/codecs/amrwb_in.c +++ b/dsp/codecs/amrwb_in.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2011-2012, 2014, 2016-2017 The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/audio_aac.c b/dsp/codecs/audio_aac.c index bbf9c36219f3..cf3d4484708d 100644 --- a/dsp/codecs/audio_aac.c +++ b/dsp/codecs/audio_aac.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* aac audio output device * * Copyright (C) 2008 Google, Inc. diff --git a/dsp/codecs/audio_alac.c b/dsp/codecs/audio_alac.c index 9ece77f54f66..ea05d7100a4a 100644 --- a/dsp/codecs/audio_alac.c +++ b/dsp/codecs/audio_alac.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/audio_amrnb.c b/dsp/codecs/audio_amrnb.c index 1549f43a35f6..efec4d2d332b 100644 --- a/dsp/codecs/audio_amrnb.c +++ b/dsp/codecs/audio_amrnb.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* amrnb audio output device * * Copyright (C) 2008 Google, Inc. diff --git a/dsp/codecs/audio_amrwb.c b/dsp/codecs/audio_amrwb.c index 63baa9db2a92..688a94d3ec26 100644 --- a/dsp/codecs/audio_amrwb.c +++ b/dsp/codecs/audio_amrwb.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* amrwb audio output device * * Copyright (C) 2008 Google, Inc. diff --git a/dsp/codecs/audio_amrwbplus.c b/dsp/codecs/audio_amrwbplus.c index 95ada7066c29..d06b054b3723 100644 --- a/dsp/codecs/audio_amrwbplus.c +++ b/dsp/codecs/audio_amrwbplus.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* amr-wbplus audio output device * * Copyright (C) 2008 Google, Inc. diff --git a/dsp/codecs/audio_ape.c b/dsp/codecs/audio_ape.c index 8d617919b465..219df404e543 100644 --- a/dsp/codecs/audio_ape.c +++ b/dsp/codecs/audio_ape.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/audio_evrc.c b/dsp/codecs/audio_evrc.c index 2376eb31c193..c3bf9b8bedda 100644 --- a/dsp/codecs/audio_evrc.c +++ b/dsp/codecs/audio_evrc.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* evrc audio output device * * Copyright (C) 2008 Google, Inc. diff --git a/dsp/codecs/audio_g711alaw.c b/dsp/codecs/audio_g711alaw.c index 509fba23af4a..3dac27d50d19 100644 --- a/dsp/codecs/audio_g711alaw.c +++ b/dsp/codecs/audio_g711alaw.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/audio_g711mlaw.c b/dsp/codecs/audio_g711mlaw.c index d01e3363a515..c0102d0d64d7 100644 --- a/dsp/codecs/audio_g711mlaw.c +++ b/dsp/codecs/audio_g711mlaw.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/audio_hwacc_effects.c b/dsp/codecs/audio_hwacc_effects.c index d90c4246c349..d0717d792cca 100644 --- a/dsp/codecs/audio_hwacc_effects.c +++ b/dsp/codecs/audio_hwacc_effects.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/audio_mp3.c b/dsp/codecs/audio_mp3.c index d676609954f2..47446d3cc8b0 100644 --- a/dsp/codecs/audio_mp3.c +++ b/dsp/codecs/audio_mp3.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* mp3 audio output device * * Copyright (C) 2008 Google, Inc. diff --git a/dsp/codecs/audio_multi_aac.c b/dsp/codecs/audio_multi_aac.c index 38b2090373bd..fc3f4924851f 100644 --- a/dsp/codecs/audio_multi_aac.c +++ b/dsp/codecs/audio_multi_aac.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* aac audio output device * * Copyright (C) 2008 Google, Inc. diff --git a/dsp/codecs/audio_native.c b/dsp/codecs/audio_native.c index e5a038fa4265..93370295d4bc 100644 --- a/dsp/codecs/audio_native.c +++ b/dsp/codecs/audio_native.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017, The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/audio_qcelp.c b/dsp/codecs/audio_qcelp.c index cd1c9e3a3722..fcf39f56b09c 100644 --- a/dsp/codecs/audio_qcelp.c +++ b/dsp/codecs/audio_qcelp.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* qcelp(v13k) audio output device * * Copyright (C) 2008 Google, Inc. diff --git a/dsp/codecs/audio_utils.c b/dsp/codecs/audio_utils.c index 7b3af387369b..1c44fcceb7f4 100644 --- a/dsp/codecs/audio_utils.c +++ b/dsp/codecs/audio_utils.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2010-2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/audio_utils.h b/dsp/codecs/audio_utils.h index 600aee7b0f0a..5116a464f833 100644 --- a/dsp/codecs/audio_utils.h +++ b/dsp/codecs/audio_utils.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2010-2015, 2017 The Linux Foundation. All rights reserved. */ #include diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c index bd3ec8864933..eabf170a8cce 100644 --- a/dsp/codecs/audio_utils_aio.c +++ b/dsp/codecs/audio_utils_aio.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. diff --git a/dsp/codecs/audio_utils_aio.h b/dsp/codecs/audio_utils_aio.h index 5d7f88884b7d..a50e1ef29e7c 100644 --- a/dsp/codecs/audio_utils_aio.h +++ b/dsp/codecs/audio_utils_aio.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. diff --git a/dsp/codecs/audio_wma.c b/dsp/codecs/audio_wma.c index 1c6bfcb5501f..cdd23ff57b13 100644 --- a/dsp/codecs/audio_wma.c +++ b/dsp/codecs/audio_wma.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* wma audio output device * * Copyright (C) 2008 Google, Inc. diff --git a/dsp/codecs/audio_wmapro.c b/dsp/codecs/audio_wmapro.c index 6295c7fa33e6..c0a27576b4d2 100644 --- a/dsp/codecs/audio_wmapro.c +++ b/dsp/codecs/audio_wmapro.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* wmapro audio output device * * Copyright (C) 2008 Google, Inc. diff --git a/dsp/codecs/evrc_in.c b/dsp/codecs/evrc_in.c index 1cf4eae021bd..dae6fc8e62cc 100644 --- a/dsp/codecs/evrc_in.c +++ b/dsp/codecs/evrc_in.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/g711alaw_in.c b/dsp/codecs/g711alaw_in.c index 18bf8175ad1e..013007ecd066 100644 --- a/dsp/codecs/g711alaw_in.c +++ b/dsp/codecs/g711alaw_in.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/g711mlaw_in.c b/dsp/codecs/g711mlaw_in.c index cbe18988e476..3d3175415c7d 100644 --- a/dsp/codecs/g711mlaw_in.c +++ b/dsp/codecs/g711mlaw_in.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/q6audio_common.h b/dsp/codecs/q6audio_common.h index bcbcb4947945..c37813edd0de 100644 --- a/dsp/codecs/q6audio_common.h +++ b/dsp/codecs/q6audio_common.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/q6audio_v2.c b/dsp/codecs/q6audio_v2.c index bc5cacf3e3f0..c98ef1c4bc0a 100644 --- a/dsp/codecs/q6audio_v2.c +++ b/dsp/codecs/q6audio_v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2013, 2015-2017, The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/q6audio_v2_aio.c b/dsp/codecs/q6audio_v2_aio.c index 25d1d03abe31..4cb46365b12c 100644 --- a/dsp/codecs/q6audio_v2_aio.c +++ b/dsp/codecs/q6audio_v2_aio.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/codecs/qcelp_in.c b/dsp/codecs/qcelp_in.c index 72465a86fe8b..806f8b233ffc 100644 --- a/dsp/codecs/qcelp_in.c +++ b/dsp/codecs/qcelp_in.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. */ diff --git a/include/asoc/wcd-irq.h b/include/asoc/wcd-irq.h index 7ae15dc9e65d..1388cfcb778f 100644 --- a/include/asoc/wcd-irq.h +++ b/include/asoc/wcd-irq.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/include/asoc/wcd934x_registers.h b/include/asoc/wcd934x_registers.h index 785b906d963c..e529f6415650 100644 --- a/include/asoc/wcd934x_registers.h +++ b/include/asoc/wcd934x_registers.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016, The Linux Foundation. All rights reserved. */ diff --git a/include/asoc/wcd9xxx_registers.h b/include/asoc/wcd9xxx_registers.h index 5d270cd03e85..cf3c408dd3db 100644 --- a/include/asoc/wcd9xxx_registers.h +++ b/include/asoc/wcd9xxx_registers.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index d8e6d34ba86d..6193209b4955 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/audio_cal_utils.h b/include/dsp/audio_cal_utils.h index c3772b01806a..0607815037f0 100644 --- a/include/dsp/audio_cal_utils.h +++ b/include/dsp/audio_cal_utils.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2014, 2018, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/audio_calibration.h b/include/dsp/audio_calibration.h index d414d8f5e201..a68c768cb8de 100644 --- a/include/dsp/audio_calibration.h +++ b/include/dsp/audio_calibration.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/audio_notifier.h b/include/dsp/audio_notifier.h index 2b738260d7b1..bc1a286c59ee 100644 --- a/include/dsp/audio_notifier.h +++ b/include/dsp/audio_notifier.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/msm-audio-effects-q6-v2.h b/include/dsp/msm-audio-effects-q6-v2.h index da7ec8b1bb4f..b1fad6d6a6f4 100644 --- a/include/dsp/msm-audio-effects-q6-v2.h +++ b/include/dsp/msm-audio-effects-q6-v2.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/msm-audio-event-notify.h b/include/dsp/msm-audio-event-notify.h index 49c00b75627c..c730d315894f 100644 --- a/include/dsp/msm-audio-event-notify.h +++ b/include/dsp/msm-audio-event-notify.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/msm-dts-srs-tm-config.h b/include/dsp/msm-dts-srs-tm-config.h index 36d25be0f03b..03753ab2909d 100644 --- a/include/dsp/msm-dts-srs-tm-config.h +++ b/include/dsp/msm-dts-srs-tm-config.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2012-2014, 2017-2018, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/msm_audio_ion.h b/include/dsp/msm_audio_ion.h index 5120383ae2d7..09d590b52a31 100644 --- a/include/dsp/msm_audio_ion.h +++ b/include/dsp/msm_audio_ion.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2013-2015, 2017-2018, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/msm_mdf.h b/include/dsp/msm_mdf.h index efd6fc557cc1..6f143db2ddab 100644 --- a/include/dsp/msm_mdf.h +++ b/include/dsp/msm_mdf.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 404f84c2b1f0..95fbb0d1fc49 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 423a16906077..ec2a4368abac 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index df2c0d70e6e2..4851a81ff023 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/q6audio-v2.h b/include/dsp/q6audio-v2.h index 4c9daebb5fe4..079d0b14b585 100644 --- a/include/dsp/q6audio-v2.h +++ b/include/dsp/q6audio-v2.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2012-2013, 2015, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/q6common.h b/include/dsp/q6common.h index 0d270bdb4c31..c21ac5cc81c1 100644 --- a/include/dsp/q6common.h +++ b/include/dsp/q6common.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index 5e008e18dc34..61bede7f99d1 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h index c6a0d60d433f..758bba0ec30e 100644 --- a/include/dsp/q6lsm.h +++ b/include/dsp/q6lsm.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index a674384b7b45..1e6212491840 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/include/dsp/rtac.h b/include/dsp/rtac.h index 7a1fed5fe555..1b4541cfa37c 100644 --- a/include/dsp/rtac.h +++ b/include/dsp/rtac.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2011, 2013-2015, 2017-2018, The Linux Foundation. All rights reserved. */ diff --git a/include/ipc/apr.h b/include/ipc/apr.h index 4e29b02827a9..79d87dc0f8a3 100644 --- a/include/ipc/apr.h +++ b/include/ipc/apr.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. */ diff --git a/include/ipc/apr_tal.h b/include/ipc/apr_tal.h index 9e412e57f40d..6a4fbdfc5ef0 100644 --- a/include/ipc/apr_tal.h +++ b/include/ipc/apr_tal.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, 2016-2018 The Linux Foundation. All rights reserved. */ diff --git a/include/ipc/apr_us.h b/include/ipc/apr_us.h index ea9a275f4992..27075ef35962 100644 --- a/include/ipc/apr_us.h +++ b/include/ipc/apr_us.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. */ diff --git a/include/soc/snd_event.h b/include/soc/snd_event.h index 835941126e02..ec92a68a5112 100644 --- a/include/soc/snd_event.h +++ b/include/soc/snd_event.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/include/soc/soundwire.h b/include/soc/soundwire.h index daacb7a408f2..bfd77c3bfb51 100644 --- a/include/soc/soundwire.h +++ b/include/soc/soundwire.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/include/soc/swr-wcd.h b/include/soc/swr-wcd.h index 93c5ffd78959..0f1762545e73 100644 --- a/include/soc/swr-wcd.h +++ b/include/soc/swr-wcd.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved. */ diff --git a/include/uapi/linux/msm_audio.h b/include/uapi/linux/msm_audio.h index 171d5b394c7b..21ded047b808 100644 --- a/include/uapi/linux/msm_audio.h +++ b/include/uapi/linux/msm_audio.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * * Copyright (C) 2008 Google, Inc. diff --git a/ipc/apr.c b/ipc/apr.c index 573d52d35fcd..d3ee38ea4f75 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2010-2014, 2016-2018 The Linux Foundation. All rights reserved. */ diff --git a/ipc/apr_tal_rpmsg.c b/ipc/apr_tal_rpmsg.c index a4175b4cb695..723de56b9df8 100644 --- a/ipc/apr_tal_rpmsg.c +++ b/ipc/apr_tal_rpmsg.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. */ diff --git a/ipc/apr_v2.c b/ipc/apr_v2.c index f74218efd16e..d748a5e1f126 100644 --- a/ipc/apr_v2.c +++ b/ipc/apr_v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. */ diff --git a/ipc/apr_v3.c b/ipc/apr_v3.c index a2df4d818ac9..7bf47749ef80 100644 --- a/ipc/apr_v3.c +++ b/ipc/apr_v3.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. */ diff --git a/ipc/wcd-dsp-glink.c b/ipc/wcd-dsp-glink.c index 455a34847460..8cfcba93f9f4 100644 --- a/ipc/wcd-dsp-glink.c +++ b/ipc/wcd-dsp-glink.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index 91a0bce31c2b..4212816c05c5 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/soc/pinctrl-wcd.c b/soc/pinctrl-wcd.c index 8dc97bdd4bf3..d02fdc0839c2 100644 --- a/soc/pinctrl-wcd.c +++ b/soc/pinctrl-wcd.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. */ diff --git a/soc/regmap-swr.c b/soc/regmap-swr.c index 7f00aab66dda..4d8fbb8c708b 100644 --- a/soc/regmap-swr.c +++ b/soc/regmap-swr.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. */ diff --git a/soc/snd_event.c b/soc/snd_event.c index f8bffb81c2e4..ace76b2e85a7 100644 --- a/soc/snd_event.c +++ b/soc/snd_event.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/soc/soundwire.c b/soc/soundwire.c index bd91caf7baae..ef51e16e6cfe 100644 --- a/soc/soundwire.c +++ b/soc/soundwire.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 7fa07373c067..b6a459e613ad 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 085a06567b15..13b85f42200e 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c index ed410fd7670e..4a41bd773049 100644 --- a/soc/swr-wcd-ctrl.c +++ b/soc/swr-wcd-ctrl.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/soc/swr-wcd-ctrl.h b/soc/swr-wcd-ctrl.h index 23b44348769c..20baa5a39246 100644 --- a/soc/swr-wcd-ctrl.h +++ b/soc/swr-wcd-ctrl.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ diff --git a/soc/swrm_port_config.h b/soc/swrm_port_config.h index 8c2903274d2a..5c6870bb6200 100644 --- a/soc/swrm_port_config.h +++ b/soc/swrm_port_config.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018 The Linux Foundation. All rights reserved. */ diff --git a/soc/swrm_registers.h b/soc/swrm_registers.h index c8ec2a32313d..c53d37bc7c63 100644 --- a/soc/swrm_registers.h +++ b/soc/swrm_registers.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved. */ -- GitLab From 3f8ba5480b2c473771077e3d8f05fe363474b33a Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 10 Dec 2018 14:17:10 +0800 Subject: [PATCH 0684/1645] asoc: routing: add afe loopback for FM on kona Add support for AFE loopback between DMA backends and tertiary mi2s tx on Kona. This is required for FM playback usecase. Change-Id: Idc0a1afc522365d15f3cdf28f01ea49f5c399850 Signed-off-by: Meng Wang --- asoc/msm-pcm-routing-v2.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index db5713b8e370..b82660c80807 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -13690,6 +13690,10 @@ static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_port_mixer_controls[] = { MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new rx_cdc_dma_rx_0_port_mixer_controls[] = { @@ -13702,9 +13706,14 @@ static const struct snd_kcontrol_new rx_cdc_dma_rx_0_port_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + }; static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { @@ -22470,7 +22479,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"RX_CDC_DMA_RX_0 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"WSA_CDC_DMA_RX_0 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"RX_CDC_DMA_RX_0 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - + {"WSA_CDC_DMA_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"RX_CDC_DMA_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, -- GitLab From ec279c75045bf9a729351eebb00e123031d5e52d Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 22 Nov 2018 15:52:25 +0530 Subject: [PATCH 0685/1645] asoc: sm6150: Add logic to parse codec_max_aux_devs Add parsing logic for codec_max_aux_devs in init_aux_dev in order to identify whether auxilary codec is supported or not for a target. CRs-Fixed: 2353292 Change-Id: I88a84ab064da50ab243ad3f7d6b61cd03b9bbc77 Signed-off-by: Aditya Bavanari --- asoc/sm6150.c | 49 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 9727dffbbdbf..f71ca2d66ffc 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -8063,6 +8063,7 @@ static int msm_init_aux_dev(struct platform_device *pdev, struct device_node *aux_codec_of_node; u32 wsa_max_devs; u32 wsa_dev_cnt; + u32 codec_max_aux_devs; u32 codec_aux_dev_cnt = 0; int i; struct msm_wsa881x_dev_info *wsa881x_dev_info = NULL; @@ -8077,14 +8078,14 @@ static int msm_init_aux_dev(struct platform_device *pdev, ret = of_property_read_u32(pdev->dev.of_node, "qcom,wsa-max-devs", &wsa_max_devs); if (ret) { - dev_info(&pdev->dev, + dev_err(&pdev->dev, "%s: wsa-max-devs property missing in DT %s, ret = %d\n", __func__, pdev->dev.of_node->full_name, ret); wsa_max_devs = 0; goto codec_aux_dev; } if (wsa_max_devs == 0) { - dev_warn(&pdev->dev, + dev_dbg(&pdev->dev, "%s: Max WSA devices is 0 for this target?\n", __func__); goto codec_aux_dev; @@ -8179,6 +8180,24 @@ static int msm_init_aux_dev(struct platform_device *pdev, codec_aux_dev: if (strcmp(card->name, "sm6150-tavil-snd-card")) { + /* Get maximum aux codec device count for this platform */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,codec-max-aux-devs", + &codec_max_aux_devs); + if (ret) { + dev_err(&pdev->dev, + "%s: codec-max-aux-devs property missing in DT %s, ret = %d\n", + __func__, pdev->dev.of_node->full_name, ret); + codec_max_aux_devs = 0; + goto aux_dev_register; + } + if (codec_max_aux_devs == 0) { + dev_dbg(&pdev->dev, + "%s: Max aux codec devices is 0 for this target?\n", + __func__); + goto aux_dev_register; + } + /* Get count of aux codec device phandles for this platform */ codec_aux_dev_cnt = of_count_phandle_with_args( pdev->dev.of_node, @@ -8195,11 +8214,24 @@ static int msm_init_aux_dev(struct platform_device *pdev, goto err; } + /* + * Expect total phandles count to be NOT less than maximum possible + * AUX device count. However, if it is less, then assign same value to + * max count as well. + */ + if (codec_aux_dev_cnt < codec_max_aux_devs) { + dev_dbg(&pdev->dev, + "%s: codec_max_aux_devs = %d cannot exceed codec_aux_dev_cnt = %d\n", + __func__, codec_max_aux_devs, + codec_aux_dev_cnt); + codec_max_aux_devs = codec_aux_dev_cnt; + } + /* * Alloc mem to store phandle and index info of aux codec * if already registered with ALSA core */ - aux_cdc_dev_info = devm_kcalloc(&pdev->dev, codec_aux_dev_cnt, + aux_cdc_dev_info = devm_kcalloc(&pdev->dev, codec_max_aux_devs, sizeof(struct aux_codec_dev_info), GFP_KERNEL); if (!aux_cdc_dev_info) { @@ -8233,10 +8265,10 @@ static int msm_init_aux_dev(struct platform_device *pdev, } } - if (codecs_found < codec_aux_dev_cnt) { + if (codecs_found < codec_max_aux_devs) { dev_dbg(&pdev->dev, "%s: failed to find %d components. Found only %d\n", - __func__, codec_aux_dev_cnt, codecs_found); + __func__, codec_max_aux_devs, codecs_found); return -EPROBE_DEFER; } dev_info(&pdev->dev, @@ -8245,8 +8277,9 @@ static int msm_init_aux_dev(struct platform_device *pdev, } - card->num_aux_devs = wsa_max_devs + codec_aux_dev_cnt; - card->num_configs = wsa_max_devs + codec_aux_dev_cnt; +aux_dev_register: + card->num_aux_devs = wsa_max_devs + codec_max_aux_devs; + card->num_configs = wsa_max_devs + codec_max_aux_devs; /* Alloc array of AUX devs struct */ msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, @@ -8299,7 +8332,7 @@ static int msm_init_aux_dev(struct platform_device *pdev, } for (i = 0; i < codec_aux_dev_cnt; i++) { - msm_aux_dev[wsa_max_devs + i].name = NULL; + msm_aux_dev[wsa_max_devs + i].name = "aux_codec"; msm_aux_dev[wsa_max_devs + i].codec_name = NULL; msm_aux_dev[wsa_max_devs + i].codec_of_node = aux_cdc_dev_info[i].of_node; -- GitLab From 1b9932e154a1ce720766a280f9ab8e6d1f2dec48 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 31 Aug 2018 23:47:20 +0530 Subject: [PATCH 0686/1645] SoC: soundwire: Add support for device wakeup Add soundwire API to wakeup soundwire master and slave devices. These APIs will be used by slave driver to vote and unvote for master wakeup, when it requires master for register access operations. Master will be aware of the slave usage with the vote for device wakeup. Change-Id: Ifa93f35ab2cffba778cd2fd9a2461e5a58445b75 Signed-off-by: Sudheer Papothi Signed-off-by: Ramprasad Katkam --- include/soc/soundwire.h | 6 +++++ soc/soundwire.c | 55 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/include/soc/soundwire.h b/include/soc/soundwire.h index bfd77c3bfb51..655b53ef604c 100644 --- a/include/soc/soundwire.h +++ b/include/soc/soundwire.h @@ -167,6 +167,8 @@ struct swr_master { u8 *dev_num); int (*slvdev_datapath_control)(struct swr_master *mstr, bool enable); bool (*remove_from_group)(struct swr_master *mstr); + void (*device_wakeup_vote)(struct swr_master *mstr); + void (*device_wakeup_unvote)(struct swr_master *mstr); u16 port_en_mask; }; @@ -334,4 +336,8 @@ extern void swr_remove_device(struct swr_device *swr_dev); extern struct swr_device *get_matching_swr_slave_device(struct device_node *np); +extern int swr_device_wakeup_vote(struct swr_device *dev); + +extern int swr_device_wakeup_unvote(struct swr_device *dev); + #endif /* _LINUX_SOUNDWIRE_H */ diff --git a/soc/soundwire.c b/soc/soundwire.c index ef51e16e6cfe..23e373a1f453 100644 --- a/soc/soundwire.c +++ b/soc/soundwire.c @@ -482,6 +482,61 @@ int swr_get_logical_dev_num(struct swr_device *dev, u64 dev_id, } EXPORT_SYMBOL(swr_get_logical_dev_num); +/** + * swr_device_wakeup_vote - Wakeup master and slave devices from clock stop + * @dev: pointer to soundwire slave device + * + * This API will wake up soundwire master and slave device(s) from + * clock stop. + */ +int swr_device_wakeup_vote(struct swr_device *dev) +{ + int ret = 0; + struct swr_master *master = dev->master; + + if (!master) { + pr_err("%s: Master is NULL\n", __func__); + return -EINVAL; + } + mutex_lock(&master->mlock); + if (master->device_wakeup_vote) + master->device_wakeup_vote(master); + else + ret = -EINVAL; + mutex_unlock(&master->mlock); + + return ret; +} +EXPORT_SYMBOL(swr_device_wakeup_vote); + +/** + * swr_device_wakeup_unvote - Unvote Wakeup so that master and slave + * devices can go back to clock stop + * @dev: pointer to soundwire slave device + * + * This API will remove vote for wakeup so that soundwire master and + * slave device(s) can go back to clock stop. + */ +int swr_device_wakeup_unvote(struct swr_device *dev) +{ + int ret = 0; + struct swr_master *master = dev->master; + + if (!master) { + pr_err("%s: Master is NULL\n", __func__); + return -EINVAL; + } + mutex_lock(&master->mlock); + if (master->device_wakeup_unvote) + master->device_wakeup_unvote(master); + else + ret = -EINVAL; + mutex_unlock(&master->mlock); + + return ret; +} +EXPORT_SYMBOL(swr_device_wakeup_unvote); + /** * swr_read - read soundwire slave device registers * @dev: pointer to soundwire slave device -- GitLab From 6abd2debae64bdb0181eb18949d934dd6d8ed84c Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 5 Sep 2018 05:57:04 +0530 Subject: [PATCH 0687/1645] SoC: swr-mstr: Add support for device wakeup Add support for soundwire device wakeup through bus driver. These APIs will be used by slave driver through bus driver to vote and unvote for master wakeup, when it requires master for register access operations. Master will be aware of the slave usage with the vote for device wakeup. Change-Id: I24f0ec0344f05926dc866edb04294cb31348e1ce Signed-off-by: Sudheer Papothi Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index b6a459e613ad..8f1ad0822550 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1535,6 +1535,32 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, pm_runtime_put_autosuspend(swrm->dev); return ret; } + +static void swrm_device_wakeup_vote(struct swr_master *mstr) +{ + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(mstr); + + if (!swrm) { + pr_err("%s: Invalid handle to swr controller\n", + __func__); + return; + } + pm_runtime_get_sync(swrm->dev); +} + +static void swrm_device_wakeup_unvote(struct swr_master *mstr) +{ + struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(mstr); + + if (!swrm) { + pr_err("%s: Invalid handle to swr controller\n", + __func__); + return; + } + pm_runtime_mark_last_busy(swrm->dev); + pm_runtime_put_autosuspend(swrm->dev); +} + static int swrm_master_init(struct swr_mstr_ctrl *swrm) { int ret = 0; @@ -1777,6 +1803,8 @@ static int swrm_probe(struct platform_device *pdev) swrm->master.disconnect_port = swrm_disconnect_port; swrm->master.slvdev_datapath_control = swrm_slvdev_datapath_control; swrm->master.remove_from_group = swrm_remove_from_group; + swrm->master.device_wakeup_vote = swrm_device_wakeup_vote; + swrm->master.device_wakeup_unvote = swrm_device_wakeup_unvote; swrm->master.dev.parent = &pdev->dev; swrm->master.dev.of_node = pdev->dev.of_node; swrm->master.num_port = 0; -- GitLab From b6dda1e6be0218fae70c4bcefb93da66431630c5 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Tue, 23 Oct 2018 18:25:30 +0530 Subject: [PATCH 0688/1645] asoc: wcd937x: use swr device wakeup api Use device wakeup api exposed by soundwire to vote and unvote for soundwire master for mbhc operations. Change-Id: Id83c8d3fb2eb351133790f69af56e4981bcac543 Signed-off-by: Ramprasad Katkam --- asoc/codecs/wcd937x/internal.h | 3 +-- asoc/codecs/wcd937x/wcd937x-mbhc.c | 4 ++++ asoc/codecs/wcd937x/wcd937x.c | 20 ++++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index 8e6928ad4c65..ca401b43f2a9 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -70,7 +70,6 @@ struct wcd937x_priv { struct codec_port_info rx_port_mapping[MAX_PORT][MAX_CH_PER_PORT]; struct regulator_bulk_data *supplies; - struct notifier_block nblock; /* wcd callback to bolero */ void *handle; @@ -78,7 +77,7 @@ struct wcd937x_priv { int (*register_notifier)(void *handle, struct notifier_block *nblock, bool enable); - + int (*wakeup)(void *handle, bool enable); u32 version; /* Entry for version info */ struct snd_info_entry *entry; diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index 7ffa11744e31..0703017a0dc5 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -240,6 +240,10 @@ static void wcd937x_mbhc_program_btn_thr(struct snd_soc_component *component, static bool wcd937x_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock) { + struct snd_soc_component *component = mbhc->component; + struct wcd937x_priv *wcd937x = dev_get_drvdata(component->dev); + + wcd937x->wakeup((void*)wcd937x, lock); return true; } diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 8810fec525d8..45c990e1c331 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -2426,6 +2426,25 @@ struct wcd937x_pdata *wcd937x_populate_dt_data(struct device *dev) return pdata; } +static int wcd937x_wakeup(void *handle, bool enable) +{ + struct wcd937x_priv *priv; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + priv = (struct wcd937x_priv *)handle; + if (!priv->tx_swr_dev) { + pr_err("%s: tx swr dev is NULL\n", __func__); + return -EINVAL; + } + if (enable) + return swr_device_wakeup_vote(priv->tx_swr_dev); + else + return swr_device_wakeup_unvote(priv->tx_swr_dev); +} + static int wcd937x_bind(struct device *dev) { int ret = 0, i = 0; @@ -2495,6 +2514,7 @@ static int wcd937x_bind(struct device *dev) * as per HW requirement. */ usleep_range(5000, 5010); + wcd937x->wakeup = wcd937x_wakeup; ret = component_bind_all(dev, wcd937x); if (ret) { -- GitLab From 5734987f6196854c9c51a69b28a4afbe8519e216 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Sun, 11 Nov 2018 18:34:57 +0530 Subject: [PATCH 0689/1645] soc: swr-mstr: Add wake lock support to prevent suspend Add lock and unlock sleep functions to master to prevent system suspend during interrupts or slave wakeup requests. Change-Id: Icb4ea354ec6e2925f83c2380f30ea8e37aca7449 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 215 ++++++++++++++++++++++++++++++++++++++++---- soc/swr-mstr-ctrl.h | 13 +++ 2 files changed, 210 insertions(+), 18 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 8f1ad0822550..06f3883a1184 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -26,7 +26,8 @@ #include "swr-mstr-ctrl.h" #include "swrm_port_config.h" - +#define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700 +#define SWRM_SYS_SUSPEND_WAIT 1 #define SWR_BROADCAST_CMD_ID 0x0F #define SWR_AUTO_SUSPEND_DELAY 3 /* delay in sec */ #define SWR_DEV_ID_MASK 0xFFFFFFFF @@ -82,6 +83,8 @@ static struct dentry *debugfs_poke; static struct dentry *debugfs_reg_dump; static unsigned int read_data; +static bool swrm_lock_sleep(struct swr_mstr_ctrl *swrm); +static void swrm_unlock_sleep(struct swr_mstr_ctrl *swrm); static bool swrm_is_msm_variant(int val) { @@ -1262,6 +1265,10 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) struct swr_device *swr_dev; struct swr_master *mstr = &swrm->master; + if (unlikely(swrm_lock_sleep(swrm) == false)) { + dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__); + return IRQ_NONE; + } mutex_lock(&swrm->reslock); swrm_clk_request(swrm, true); @@ -1411,6 +1418,7 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) mutex_lock(&swrm->reslock); swrm_clk_request(swrm, false); mutex_unlock(&swrm->reslock); + swrm_unlock_sleep(swrm); return ret; } @@ -1454,12 +1462,19 @@ static void swrm_wakeup_work(struct work_struct *work) mutex_lock(&swrm->devlock); if (!swrm->dev_up) { mutex_unlock(&swrm->devlock); - return; + goto exit; } mutex_unlock(&swrm->devlock); + if (unlikely(swrm_lock_sleep(swrm) == false)) { + dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__); + goto exit; + } pm_runtime_get_sync(swrm->dev); pm_runtime_mark_last_busy(swrm->dev); pm_runtime_put_autosuspend(swrm->dev); + swrm_unlock_sleep(swrm); +exit: + pm_relax(swrm->dev); } static int swrm_get_device_status(struct swr_mstr_ctrl *swrm, u8 devnum) @@ -1545,6 +1560,10 @@ static void swrm_device_wakeup_vote(struct swr_master *mstr) __func__); return; } + if (unlikely(swrm_lock_sleep(swrm) == false)) { + dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__); + return; + } pm_runtime_get_sync(swrm->dev); } @@ -1559,6 +1578,7 @@ static void swrm_device_wakeup_unvote(struct swr_master *mstr) } pm_runtime_mark_last_busy(swrm->dev); pm_runtime_put_autosuspend(swrm->dev); + swrm_unlock_sleep(swrm); } static int swrm_master_init(struct swr_mstr_ctrl *swrm) @@ -1639,6 +1659,7 @@ static int swrm_event_notify(struct notifier_block *self, case SWR_WAKE_IRQ_EVENT: if (swrm->ipc_wakeup && !swrm->ipc_wakeup_triggered) { swrm->ipc_wakeup_triggered = true; + pm_stay_awake(swrm->dev); schedule_work(&swrm->wakeup_work); } break; @@ -1745,6 +1766,21 @@ static int swrm_probe(struct platform_device *pdev) &swrm->clk_stop_mode0_supp)) { swrm->clk_stop_mode0_supp = FALSE; } + + ret = of_property_read_u32(swrm->dev->of_node, "qcom,swr-num-dev", + &swrm->num_dev); + if (ret) { + dev_dbg(&pdev->dev, "%s: Looking up %s property failed\n", + __func__, "qcom,swr-num-dev"); + } else { + if (swrm->num_dev > SWR_MAX_SLAVE_DEVICES) { + dev_err(&pdev->dev, "%s: num_dev %d > max limit %d\n", + __func__, swrm->num_dev, SWR_MAX_SLAVE_DEVICES); + ret = -EINVAL; + goto err_pdata_fail; + } + } + /* Parse soundwire port mapping */ ret = of_property_read_u32(pdev->dev.of_node, "qcom,swr-num-ports", &num_ports); @@ -1827,24 +1863,17 @@ static int swrm_probe(struct platform_device *pdev) mutex_init(&swrm->iolock); mutex_init(&swrm->clklock); mutex_init(&swrm->devlock); + mutex_init(&swrm->pm_lock); + swrm->wlock_holders = 0; + swrm->pm_state = SWRM_PM_SLEEPABLE; + init_waitqueue_head(&swrm->pm_wq); + pm_qos_add_request(&swrm->pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + PM_QOS_DEFAULT_VALUE); for (i = 0 ; i < SWR_MSTR_PORT_LEN; i++) INIT_LIST_HEAD(&swrm->mport_cfg[i].port_req_list); - ret = of_property_read_u32(swrm->dev->of_node, "qcom,swr-num-dev", - &swrm->num_dev); - if (ret) { - dev_dbg(&pdev->dev, "%s: Looking up %s property failed\n", - __func__, "qcom,swr-num-dev"); - } else { - if (swrm->num_dev > SWR_MAX_SLAVE_DEVICES) { - dev_err(&pdev->dev, "%s: num_dev %d > max limit %d\n", - __func__, swrm->num_dev, SWR_MAX_SLAVE_DEVICES); - ret = -EINVAL; - goto err_pdata_fail; - } - } - if (swrm->reg_irq) { ret = swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, SWR_IRQ_REGISTER); @@ -1940,6 +1969,9 @@ static int swrm_probe(struct platform_device *pdev) mutex_destroy(&swrm->force_down_lock); mutex_destroy(&swrm->iolock); mutex_destroy(&swrm->clklock); + mutex_destroy(&swrm->pm_lock); + pm_qos_remove_request(&swrm->pm_qos_req); + err_pdata_fail: err_memory_fail: return ret; @@ -1956,7 +1988,7 @@ static int swrm_remove(struct platform_device *pdev) free_irq(swrm->irq, swrm); else if (swrm->wake_irq > 0) free_irq(swrm->wake_irq, swrm); - + cancel_work_sync(&swrm->wakeup_work); pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); swr_unregister_master(&swrm->master); @@ -1966,6 +1998,8 @@ static int swrm_remove(struct platform_device *pdev) mutex_destroy(&swrm->iolock); mutex_destroy(&swrm->clklock); mutex_destroy(&swrm->force_down_lock); + mutex_destroy(&swrm->pm_lock); + pm_qos_remove_request(&swrm->pm_qos_req); devm_kfree(&pdev->dev, swrm); return 0; } @@ -2301,6 +2335,94 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) } EXPORT_SYMBOL(swrm_wcd_notify); +/* + * swrm_pm_cmpxchg: + * Check old state and exchange with pm new state + * if old state matches with current state + * + * @swrm: pointer to wcd core resource + * @o: pm old state + * @n: pm new state + * + * Returns old state + */ +static enum swrm_pm_state swrm_pm_cmpxchg( + struct swr_mstr_ctrl *swrm, + enum swrm_pm_state o, + enum swrm_pm_state n) +{ + enum swrm_pm_state old; + + if (!swrm) + return o; + + mutex_lock(&swrm->pm_lock); + old = swrm->pm_state; + if (old == o) + swrm->pm_state = n; + mutex_unlock(&swrm->pm_lock); + + return old; +} + +static bool swrm_lock_sleep(struct swr_mstr_ctrl *swrm) +{ + enum swrm_pm_state os; + + /* + * swrm_{lock/unlock}_sleep will be called by swr irq handler + * and slave wake up requests.. + * + * If system didn't resume, we can simply return false so + * IRQ handler can return without handling IRQ. + */ + mutex_lock(&swrm->pm_lock); + if (swrm->wlock_holders++ == 0) { + dev_dbg(swrm->dev, "%s: holding wake lock\n", __func__); + pm_qos_update_request(&swrm->pm_qos_req, + msm_cpuidle_get_deep_idle_latency()); + pm_stay_awake(swrm->dev); + } + mutex_unlock(&swrm->pm_lock); + + if (!wait_event_timeout(swrm->pm_wq, + ((os = swrm_pm_cmpxchg(swrm, + SWRM_PM_SLEEPABLE, + SWRM_PM_AWAKE)) == + SWRM_PM_SLEEPABLE || + (os == SWRM_PM_AWAKE)), + msecs_to_jiffies( + SWRM_SYSTEM_RESUME_TIMEOUT_MS))) { + dev_err(swrm->dev, "%s: system didn't resume within %dms, s %d, w %d\n", + __func__, SWRM_SYSTEM_RESUME_TIMEOUT_MS, swrm->pm_state, + swrm->wlock_holders); + swrm_unlock_sleep(swrm); + return false; + } + wake_up_all(&swrm->pm_wq); + return true; +} + +static void swrm_unlock_sleep(struct swr_mstr_ctrl *swrm) +{ + mutex_lock(&swrm->pm_lock); + if (--swrm->wlock_holders == 0) { + dev_dbg(swrm->dev, "%s: releasing wake lock pm_state %d -> %d\n", + __func__, swrm->pm_state, SWRM_PM_SLEEPABLE); + /* + * if swrm_lock_sleep failed, pm_state would be still + * swrm_PM_ASLEEP, don't overwrite + */ + if (likely(swrm->pm_state == SWRM_PM_AWAKE)) + swrm->pm_state = SWRM_PM_SLEEPABLE; + pm_qos_update_request(&swrm->pm_qos_req, + PM_QOS_DEFAULT_VALUE); + pm_relax(swrm->dev); + } + mutex_unlock(&swrm->pm_lock); + wake_up_all(&swrm->pm_wq); +} + #ifdef CONFIG_PM_SLEEP static int swrm_suspend(struct device *dev) { @@ -2309,7 +2431,49 @@ static int swrm_suspend(struct device *dev) struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); dev_dbg(dev, "%s: system suspend, state: %d\n", __func__, swrm->state); - if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) { + + mutex_lock(&swrm->pm_lock); + + if (swrm->pm_state == SWRM_PM_SLEEPABLE) { + dev_dbg(swrm->dev, "%s: suspending system, state %d, wlock %d\n", + __func__, swrm->pm_state, + swrm->wlock_holders); + swrm->pm_state = SWRM_PM_ASLEEP; + } else if (swrm->pm_state == SWRM_PM_AWAKE) { + /* + * unlock to wait for pm_state == SWRM_PM_SLEEPABLE + * then set to SWRM_PM_ASLEEP + */ + dev_dbg(swrm->dev, "%s: waiting to suspend system, state %d, wlock %d\n", + __func__, swrm->pm_state, + swrm->wlock_holders); + mutex_unlock(&swrm->pm_lock); + if (!(wait_event_timeout(swrm->pm_wq, swrm_pm_cmpxchg( + swrm, SWRM_PM_SLEEPABLE, + SWRM_PM_ASLEEP) == + SWRM_PM_SLEEPABLE, + msecs_to_jiffies( + SWRM_SYS_SUSPEND_WAIT)))) { + dev_dbg(swrm->dev, "%s: suspend failed state %d, wlock %d\n", + __func__, swrm->pm_state, + swrm->wlock_holders); + return -EBUSY; + } else { + dev_dbg(swrm->dev, + "%s: done, state %d, wlock %d\n", + __func__, swrm->pm_state, + swrm->wlock_holders); + } + mutex_lock(&swrm->pm_lock); + } else if (swrm->pm_state == SWRM_PM_ASLEEP) { + dev_dbg(swrm->dev, "%s: system is already suspended, state %d, wlock %d\n", + __func__, swrm->pm_state, + swrm->wlock_holders); + } + + mutex_unlock(&swrm->pm_lock); + + if ((!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev))) { ret = swrm_runtime_suspend(dev); if (!ret) { /* @@ -2355,6 +2519,21 @@ static int swrm_resume(struct device *dev) pm_request_autosuspend(dev); } } + mutex_lock(&swrm->pm_lock); + if (swrm->pm_state == SWRM_PM_ASLEEP) { + dev_dbg(swrm->dev, + "%s: resuming system, state %d, wlock %d\n", + __func__, swrm->pm_state, + swrm->wlock_holders); + swrm->pm_state = SWRM_PM_SLEEPABLE; + } else { + dev_dbg(swrm->dev, "%s: system is already awake, state %d wlock %d\n", + __func__, swrm->pm_state, + swrm->wlock_holders); + } + mutex_unlock(&swrm->pm_lock); + wake_up_all(&swrm->pm_wq); + return ret; } #endif /* CONFIG_PM_SLEEP */ diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 13b85f42200e..a32fdc69b1b4 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -7,6 +7,8 @@ #define _SWR_WCD_CTRL_H #include #include +#include +#include #define SWR_ROW_48 0 #define SWR_ROW_50 1 @@ -35,6 +37,12 @@ enum { SWR_MSTR_SSR, }; +enum swrm_pm_state { + SWRM_PM_SLEEPABLE, + SWRM_PM_AWAKE, + SWRM_PM_ASLEEP, +}; + enum { SWR_IRQ_FREE, SWR_IRQ_REGISTER, @@ -111,6 +119,7 @@ struct swr_mstr_ctrl { struct mutex devlock; struct mutex mlock; struct mutex reslock; + struct mutex pm_lock; u32 swrm_base_reg; char __iomem *swrm_dig_base; u8 rcmd_id; @@ -149,6 +158,10 @@ struct swr_mstr_ctrl { u32 ipc_wakeup; bool dev_up; bool ipc_wakeup_triggered; + struct pm_qos_request pm_qos_req; + enum swrm_pm_state pm_state; + wait_queue_head_t pm_wq; + int wlock_holders; }; #endif /* _SWR_WCD_CTRL_H */ -- GitLab From 18065271af5aab22ca7d2c2a4bcfa6cc94557eea Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 11 Dec 2018 14:33:40 +0800 Subject: [PATCH 0690/1645] asoc: remove find tag to fix compile error Remove unused find tag to fix compile error. Change-Id: Id4b6d210ef51f3ad419968a9413a691d7f7a779e Signed-off-by: Meng Wang --- asoc/msm-compress-q6-v2.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index dd166cf51926..fb9f19add0aa 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -4273,7 +4273,6 @@ static int msm_compr_add_audio_adsp_stream_cmd_control( __func__, mixer_str, ret); kfree(mixer_str); -done: return ret; } @@ -4587,7 +4586,6 @@ static int msm_compr_add_io_fd_cmd_control(struct snd_soc_pcm_runtime *rtd) pr_err("%s: failed to add ctl %s\n", __func__, mixer_str); kfree(mixer_str); -done: return ret; } @@ -4636,7 +4634,6 @@ static int msm_compr_add_event_ack_cmd_control(struct snd_soc_pcm_runtime *rtd) pr_err("%s: failed to add ctl %s\n", __func__, mixer_str); kfree(mixer_str); -done: return ret; } -- GitLab From d99fac02103881d1becc85a39de2eabe372e9ff2 Mon Sep 17 00:00:00 2001 From: Manisha Agarwal Date: Sun, 4 Nov 2018 15:46:02 +0530 Subject: [PATCH 0691/1645] ASoC: Add TWS+ mono mode support Add support to enable mono mode when one TWS+ earbud is connected. Change the encoder config when device switches from two earbuds to single earbud. CRs-Fixed: 2341876 Change-Id: I880aa6a2767d88e99be2d80afff0e5fbec94b8a4 Signed-off-by: Manisha Agarwal --- asoc/msm-dai-q6-v2.c | 69 ++++++++++++++++++++++++++++++++++++++ dsp/q6afe.c | 59 ++++++++++++++++++++++++++++---- include/dsp/apr_audio-v2.h | 6 ++++ include/dsp/q6afe-v2.h | 1 + 4 files changed, 129 insertions(+), 6 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 962a1bdfe7b0..bd104a4bf7a5 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -26,6 +26,8 @@ #define MSM_DAI_QUAT_AUXPCM_DT_DEV_ID 4 #define MSM_DAI_QUIN_AUXPCM_DT_DEV_ID 5 +#define MSM_DAI_TWS_CHANNEL_MODE_ONE 1 +#define MSM_DAI_TWS_CHANNEL_MODE_TWO 2 #define spdif_clock_value(rate) (2*rate*32*2) #define CHANNEL_STATUS_SIZE 24 @@ -2928,6 +2930,12 @@ static const struct soc_enum afe_bit_format_enum[] = { SOC_ENUM_SINGLE_EXT(3, afe_bit_format_text), }; +static const char *const tws_chs_mode_text[] = {"Zero", "One", "Two"}; + +static const struct soc_enum tws_chs_mode_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tws_chs_mode_text), tws_chs_mode_text), +}; + static int msm_dai_q6_afe_input_channel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2956,6 +2964,61 @@ static int msm_dai_q6_afe_input_channel_put(struct snd_kcontrol *kcontrol, return 0; } +static int msm_dai_q6_tws_channel_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dai *dai = kcontrol->private_data; + struct msm_dai_q6_dai_data *dai_data = NULL; + + if (dai) + dai_data = dev_get_drvdata(dai->dev); + + if (dai_data) { + ucontrol->value.integer.value[0] = + dai_data->enc_config.mono_mode; + pr_debug("%s:tws channel mode = %d\n", + __func__, dai_data->enc_config.mono_mode); + } + + return 0; +} + +static int msm_dai_q6_tws_channel_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dai *dai = kcontrol->private_data; + struct msm_dai_q6_dai_data *dai_data = NULL; + int ret = 0; + + if (dai) + dai_data = dev_get_drvdata(dai->dev); + + if (dai_data && (dai_data->enc_config.format == ENC_FMT_APTX)) { + if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + ret = afe_set_tws_channel_mode(dai->id, + ucontrol->value.integer.value[0]); + if (ret < 0) { + pr_err("%s: channel mode setting failed for TWS\n", + __func__); + goto exit; + } else { + pr_debug("%s: updating tws channel mode : %d\n", + __func__, dai_data->enc_config.mono_mode); + } + } + if (ucontrol->value.integer.value[0] == + MSM_DAI_TWS_CHANNEL_MODE_ONE || + ucontrol->value.integer.value[0] == + MSM_DAI_TWS_CHANNEL_MODE_TWO) + dai_data->enc_config.mono_mode = + ucontrol->value.integer.value[0]; + else + return -EINVAL; + } +exit: + return ret; +} + static int msm_dai_q6_afe_input_bit_format_get( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -3149,6 +3212,9 @@ static const struct snd_kcontrol_new afe_enc_config_controls[] = { 0, 0, 1, 0, msm_dai_q6_afe_scrambler_mode_get, msm_dai_q6_afe_scrambler_mode_put), + SOC_ENUM_EXT("TWS Channel Mode", tws_chs_mode_enum[0], + msm_dai_q6_tws_channel_mode_get, + msm_dai_q6_tws_channel_mode_put) }; static int msm_dai_q6_afe_dec_cfg_info(struct snd_kcontrol *kcontrol, @@ -3432,6 +3498,9 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&afe_enc_config_controls[3], dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&afe_enc_config_controls[4], + dai)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&avd_drift_config_controls[2], dai)); diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 8ae2739e234a..5eebb0566288 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -3615,7 +3615,7 @@ static int q6afe_send_enc_config(u16 port_id, union afe_enc_config_data *cfg, u32 format, union afe_port_config afe_config, u16 afe_in_channels, u16 afe_in_bit_width, - u32 scrambler_mode) + u32 scrambler_mode, u32 mono_mode) { u32 enc_fmt; struct afe_enc_cfg_blk_param_t enc_blk_param; @@ -3626,6 +3626,7 @@ static int q6afe_send_enc_config(u16 port_id, struct afe_enc_level_to_bitrate_map_param_t map_param; struct afe_enc_dec_imc_info_param_t imc_info_param; struct afe_port_media_type_t media_type; + struct aptx_channel_mode_param_t channel_mode_param; struct param_hdr_v3 param_hdr; int ret; @@ -3760,6 +3761,23 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } + if (format == ASM_MEDIA_FMT_APTX) { + pr_debug("%s:sending CAPI_V2_PARAM_ID_APTX_ENC_SWITCH_TO_MONO mode= %d to DSP payload\n", + __func__, mono_mode); + param_hdr.param_id = CAPI_V2_PARAM_ID_APTX_ENC_SWITCH_TO_MONO; + param_hdr.param_size = sizeof(channel_mode_param); + channel_mode_param.channel_mode = mono_mode; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &channel_mode_param); + + if (ret) { + pr_err("%s: CAPI_V2_PARAM_ID_APTX_ENC_SWITCH_TO_MONO for port 0x%x failed %d\n", + __func__, port_id, ret); + } + } + if ((format == ASM_MEDIA_FMT_LDAC && cfg->ldac_config.abr_config.is_abr_enabled) || format == ASM_MEDIA_FMT_APTX_ADAPTIVE) { @@ -3843,10 +3861,38 @@ static int q6afe_send_enc_config(u16 port_id, return ret; } +int afe_set_tws_channel_mode(u16 port_id, u32 channel_mode) +{ + struct aptx_channel_mode_param_t channel_mode_param; + struct param_hdr_v3 param_info; + int ret = 0; + + memset(¶m_info, 0, sizeof(param_info)); + memset(&channel_mode_param, 0, sizeof(channel_mode_param)); + + param_info.module_id = AFE_MODULE_ID_ENCODER; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = CAPI_V2_PARAM_ID_APTX_ENC_SWITCH_TO_MONO; + param_info.param_size = sizeof(channel_mode_param); + + channel_mode_param.channel_mode = channel_mode; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_info, + (u8 *) &channel_mode_param); + if (ret) + pr_err("%s: AFE set channel mode cfg for port 0x%x failed %d\n", + __func__, port_id, ret); + + return ret; +} +EXPORT_SYMBOL(afe_set_tws_channel_mode); + static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, union afe_enc_config_data *enc_cfg, - u32 codec_format, u32 scrambler_mode, + u32 codec_format, u32 scrambler_mode, u32 mono_mode, struct afe_dec_config *dec_cfg) { union afe_port_config port_cfg; @@ -4149,7 +4195,7 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, codec_format, *afe_config, afe_in_channels, afe_in_bit_width, - scrambler_mode); + scrambler_mode, mono_mode); if (ret) { pr_err("%s: AFE encoder config for port 0x%x failed %d\n", __func__, port_id, ret); @@ -4216,7 +4262,7 @@ int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate) { return __afe_port_start(port_id, afe_config, rate, - 0, 0, NULL, ASM_MEDIA_FMT_NONE, 0, NULL); + 0, 0, NULL, ASM_MEDIA_FMT_NONE, 0, 0, NULL); } EXPORT_SYMBOL(afe_port_start); @@ -4245,11 +4291,12 @@ int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, ret = __afe_port_start(port_id, afe_config, rate, afe_in_channels, afe_in_bit_width, &enc_cfg->data, enc_cfg->format, - enc_cfg->scrambler_mode, dec_cfg); + enc_cfg->scrambler_mode, + enc_cfg->mono_mode, dec_cfg); else if (dec_cfg != NULL) ret = __afe_port_start(port_id, afe_config, rate, afe_in_channels, afe_in_bit_width, - NULL, dec_cfg->format, 0, dec_cfg); + NULL, dec_cfg->format, 0, 0, dec_cfg); return ret; } diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 6193209b4955..fcba1c19f20b 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -3914,6 +3914,11 @@ struct afe_id_aptx_adaptive_enc_init */ #define AFE_DECODER_PARAM_ID_DEPACKETIZER_ID 0x00013235 +#define CAPI_V2_PARAM_ID_APTX_ENC_SWITCH_TO_MONO 0x0001332A + +struct aptx_channel_mode_param_t { + u32 channel_mode; +} __packed; /* * Decoder buffer ID parameter for the #AVS_MODULE_ID_DECODER module. * This parameter cannot be set runtime. @@ -4418,6 +4423,7 @@ union afe_enc_config_data { struct afe_enc_config { u32 format; u32 scrambler_mode; + u32 mono_mode; union afe_enc_config_data data; }; diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index ec2a4368abac..3f951156c15c 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -366,6 +366,7 @@ void afe_set_island_mode_cfg(u16 port_id, u32 enable_flag); void afe_get_island_mode_cfg(u16 port_id, u32 *enable_flag); int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate); +int afe_set_tws_channel_mode(u16 port_id, u32 channel_mode); int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, struct afe_enc_config *enc_config, -- GitLab From d4b85ecad1aeb1981a3f0ac3512557ec6a0bcbb3 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 23 Aug 2018 12:50:46 +0530 Subject: [PATCH 0692/1645] soc: Add flag GCOV_PROFILE to makefile Enable GCOV for soc if config GCOV_PROFILE is set to true. Change-Id: I01e7cf24eb78c541f6f5d5b13c5a3b21f1f18d40 Signed-off-by: Vatsal Bucha --- soc/Kbuild | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/soc/Kbuild b/soc/Kbuild index 69eb0b988c9b..49ba00fccec4 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -133,6 +133,10 @@ ifeq ($(call cc-option-yn, -Wheader-guard),y) EXTRA_CFLAGS += -Wheader-guard endif +ifeq ($(CONFIG_SND_SOC_GCOV), y) +GCOV_PROFILE := y +endif + # Module information used by KBuild framework obj-$(CONFIG_PINCTRL_WCD) += pinctrl_wcd_dlkm.o pinctrl_wcd_dlkm-y := $(PINCTRL_WCD_OBJS) -- GitLab From 1d3f38bb108a5b5ec7051d27eb9916bcd365001d Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 23 Aug 2018 12:45:38 +0530 Subject: [PATCH 0693/1645] ipc: Add flag GCOV_PROFILE to makefile Enable GCOV if config GCOV_PROFILE is set to true. Change-Id: Ia49884a7ed161052ff1b286970b01d160024313e Signed-off-by: Vatsal Bucha --- ipc/Kbuild | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ipc/Kbuild b/ipc/Kbuild index 3ecf01dd87e9..ec9dc78a851e 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -131,6 +131,10 @@ CHIP_NAME ?= $(MODNAME) CDEFINES += -DMULTI_IF_NAME=\"$(CHIP_NAME)\" endif +ifeq ($(CONFIG_SND_SOC_GCOV), y) +GCOV_PROFILE := y +endif + # Module information used by KBuild framework obj-$(CONFIG_MSM_QDSP6_APRV2_RPMSG) += apr_dlkm.o obj-$(CONFIG_MSM_QDSP6_APRV3_RPMSG) += apr_dlkm.o -- GitLab From 68725bb2bf995ed031cc4e39785014310960a4bb Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Fri, 23 Nov 2018 16:52:58 +0530 Subject: [PATCH 0694/1645] ASoC: audio-ext-clk: Add support for external pll clk Add clock node to support external pll clock source. Change-Id: Ic524f61933d3834896bd113c60a0499915794d0d Signed-off-by: Rohit kumar --- asoc/codecs/audio-ext-clk-up.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index 0d95ff1041ea..e86b30eed11a 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -29,7 +29,8 @@ enum { AUDIO_EXT_CLK_LPASS7, AUDIO_EXT_CLK_LPASS_NPA_RSC_ISLAND, AUDIO_EXT_CLK_LPASS_MAX, - AUDIO_EXT_CLK_MAX = AUDIO_EXT_CLK_LPASS_MAX, + AUDIO_EXT_CLK_EXTERNAL_PLL = AUDIO_EXT_CLK_LPASS_MAX, + AUDIO_EXT_CLK_MAX, }; struct pinctrl_info { @@ -325,6 +326,17 @@ static struct audio_ext_clk audio_clk_array[] = { }, }, }, + { + .pnctrl_info = {NULL}, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_external_pll_clk", + .ops = &audio_ext_clk_ops, + }, + }, + }, }; static int audio_get_pinctrl(struct platform_device *pdev) -- GitLab From 91674b50e6efbdc49d80234ae2fb00127fb5de98 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 23 Nov 2018 17:02:49 +0530 Subject: [PATCH 0695/1645] dsp: afe: Cleanup task_struct related implementation Cleanup task_struct related implementation in AFE driver as it is not used anymore and causes invalid pointer access in stability tests. Change-Id: I97ad810f9389338af85c7cea3213432917a21106 Signed-off-by: Aditya Bavanari --- dsp/q6afe.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 8ae2739e234a..de7782c48d32 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -88,7 +88,6 @@ struct afe_ctl { atomic_t status; wait_queue_head_t wait[AFE_MAX_PORTS]; wait_queue_head_t wait_wakeup; - struct task_struct *task; void (*tx_cb)(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv); void (*rx_cb)(uint32_t opcode, @@ -438,12 +437,6 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) this_afe.apr = NULL; rtac_set_afe_handle(this_afe.apr); } - /* send info to user */ - if (this_afe.task == NULL) - this_afe.task = current; - pr_debug("%s: task_name = %s pid = %d\n", - __func__, - this_afe.task->comm, this_afe.task->pid); /* * Pass reset events to proxy driver, if cb is registered @@ -2799,7 +2792,7 @@ EXPORT_SYMBOL(afe_send_spdif_ch_status_cfg); int afe_send_cmd_wakeup_register(void *handle, bool enable) { struct afe_svc_cmd_evt_cfg_payload wakeup_irq; - int ret; + int ret = 0; pr_debug("%s: enter\n", __func__); @@ -2813,18 +2806,13 @@ int afe_send_cmd_wakeup_register(void *handle, bool enable) wakeup_irq.hdr.opcode = AFE_SVC_CMD_EVENT_CFG; wakeup_irq.event_id = AFE_EVENT_ID_MBHC_DETECTION_SW_WA; wakeup_irq.reg_flag = enable; - pr_debug("%s: cmd device start opcode[0x%x] register:%d\n", + pr_debug("%s: cmd wakeup register opcode[0x%x] register:%d\n", __func__, wakeup_irq.hdr.opcode, wakeup_irq.reg_flag); ret = afe_apr_send_pkt(&wakeup_irq, &this_afe.wait_wakeup); - if (ret) { + if (ret) pr_err("%s: AFE wakeup command register %d failed %d\n", __func__, enable, ret); - } else if (this_afe.task != current) { - this_afe.task = current; - pr_debug("task_name = %s pid = %d\n", - this_afe.task->comm, this_afe.task->pid); - } return ret; } @@ -2861,14 +2849,9 @@ static int afe_send_cmd_port_start(u16 port_id) __func__, start.hdr.opcode, start.port_id); ret = afe_apr_send_pkt(&start, &this_afe.wait[index]); - if (ret) { + if (ret) pr_err("%s: AFE enable for port 0x%x failed %d\n", __func__, port_id, ret); - } else if (this_afe.task != current) { - this_afe.task = current; - pr_debug("task_name = %s pid = %d\n", - this_afe.task->comm, this_afe.task->pid); - } return ret; } -- GitLab From 1a96a612365a989ec79d0e194720e250a37272e2 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 26 Nov 2018 13:04:56 +0530 Subject: [PATCH 0696/1645] ASoC: codecs: bolero: Fix playback issue over RX1 Mono playback over RX1 is not happening due to incorrect channel mask sent to AFE. Update channel mask for RX to enable playback. Change-Id: I06eeb565149c635ddbcce39f4260f67b80474335 Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/rx-macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 6e0916eaf430..666f6e5e229f 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -951,7 +951,7 @@ static int rx_macro_get_channel_map(struct snd_soc_dai *dai, case RX_MACRO_AIF4_PB: for_each_set_bit(temp, &rx_priv->active_ch_mask[dai->id], RX_MACRO_PORTS_MAX) { - ch_mask |= (1 << i); + ch_mask |= (1 << temp); if (++i == RX_MACRO_MAX_DMA_CH_PER_PORT) break; } -- GitLab From 579c6d9898a70dc5ca290ec5151ed80eca796881 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 23 Nov 2018 17:29:31 +0530 Subject: [PATCH 0697/1645] soc: soundwire: Update samping interval of class-H port Use sampling interval of 32 for class-H port to ensure consistent setting for both 48k and 44.1k family sample rates as recommended by HW. Change-Id: I5f683f628ea3a4cd3ac72f827a51be70c3ac6ec6 Signed-off-by: Laxminath Kasam --- soc/swrm_port_config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soc/swrm_port_config.h b/soc/swrm_port_config.h index 5c6870bb6200..0458696380eb 100644 --- a/soc/swrm_port_config.h +++ b/soc/swrm_port_config.h @@ -27,7 +27,7 @@ struct port_params wsa_frame_superset[SWR_MSTR_PORT_LEN] = { struct port_params rx_frame_params[SWR_MSTR_PORT_LEN] = { {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1}, - {63, 0, 0, 3, 6, 7, 0, 0xFF, 0}, + {31, 0, 0, 3, 6, 7, 0, 0xFF, 0}, {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0}, {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0}, {0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0}, @@ -35,7 +35,7 @@ struct port_params rx_frame_params[SWR_MSTR_PORT_LEN] = { struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = { {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1}, - {63, 0, 0, 3, 6, 7, 0, 0xFF, 0}, + {31, 0, 0, 3, 6, 7, 0, 0xFF, 0}, {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0}, {7, 9, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0}, {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 3, 0}, -- GitLab From 353a583a48ddeb5a674e3393d7accc727caa3878 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 22 Nov 2018 15:10:32 +0530 Subject: [PATCH 0698/1645] asoc: sm6150: Add support for MI2S and TDM interfaces Add startup and shutdown functions for MI2S and TDM interfaces and activate the respective GPIOs. CRs-Fixed: 2353292 Change-Id: I3eec88c851f0f34584c7a70d55ab8f1d5fc9dff4 Signed-off-by: Aditya Bavanari --- asoc/sm6150.c | 505 ++++++++++++++++++++++---------------------------- 1 file changed, 223 insertions(+), 282 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 9727dffbbdbf..7c6ec22a6bdf 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -117,6 +117,32 @@ enum { AUX_PCM_MAX, }; +enum { + TDM_0 = 0, + TDM_1, + TDM_2, + TDM_3, + TDM_4, + TDM_5, + TDM_6, + TDM_7, + TDM_PORT_MAX, +}; + +enum { + TDM_PRI = 0, + TDM_SEC, + TDM_TERT, + TDM_QUAT, + TDM_QUIN, + TDM_INTERFACE_MAX, +}; + +struct tdm_port { + u32 mode; + u32 channel; +}; + enum { WSA_CDC_DMA_RX_0 = 0, WSA_CDC_DMA_RX_1, @@ -142,6 +168,7 @@ struct mi2s_conf { struct mutex lock; u32 ref_cnt; u32 msm_is_mi2s_master; + u32 msm_is_ext_mclk; }; static u32 mi2s_ebit_clk[MI2S_MAX] = { @@ -173,25 +200,10 @@ struct aux_codec_dev_info { u32 index; }; -enum pinctrl_pin_state { - STATE_DISABLE = 0, /* All pins are in sleep state */ - STATE_MI2S_ACTIVE, /* I2S = active, TDM = sleep */ - STATE_TDM_ACTIVE, /* I2S = sleep, TDM = active */ -}; - -struct msm_pinctrl_info { - struct pinctrl *pinctrl; - struct pinctrl_state *mi2s_disable; - struct pinctrl_state *tdm_disable; - struct pinctrl_state *mi2s_active; - struct pinctrl_state *tdm_active; - enum pinctrl_pin_state curr_state; -}; - struct msm_asoc_mach_data { struct snd_info_entry *codec_root; - struct msm_pinctrl_info pinctrl_info; int usbc_en2_gpio; /* used by gpio driver API */ + struct device_node *mi2s_gpio_p[MI2S_MAX]; /* used by pinctrl API */ struct device_node *dmic01_gpio_p; /* used by pinctrl API */ struct device_node *dmic23_gpio_p; /* used by pinctrl API */ struct device_node *us_euro_gpio_p; /* used by pinctrl API */ @@ -207,37 +219,8 @@ struct msm_asoc_wcd93xx_codec { enum afe_config_type config_type); }; -static const char *const pin_states[] = {"sleep", "i2s-active", - "tdm-active"}; - static struct snd_soc_card snd_soc_card_sm6150_msm; -enum { - TDM_0 = 0, - TDM_1, - TDM_2, - TDM_3, - TDM_4, - TDM_5, - TDM_6, - TDM_7, - TDM_PORT_MAX, -}; - -enum { - TDM_PRI = 0, - TDM_SEC, - TDM_TERT, - TDM_QUAT, - TDM_QUIN, - TDM_INTERFACE_MAX, -}; - -struct tdm_port { - u32 mode; - u32 channel; -}; - /* TDM default config */ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { { /* PRI TDM */ @@ -727,6 +710,49 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = { }; +static struct afe_clk_set mi2s_mclk[MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_MCLK_3, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_MCLK_2, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_MCLK_1, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_MCLK_1, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + } +}; + static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; static int slim_get_sample_rate_val(int sample_rate) @@ -4927,11 +4953,9 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) dev_dbg(component->dev, "%s: Number of aux devices: %d\n", __func__, rtd->card->num_aux_devs); if (rtd->card->num_aux_devs && - !list_empty(&rtd->card->component_dev_list)) { - aux_comp = list_first_entry( - &rtd->card->component_dev_list, - struct snd_soc_component, - card_aux_list); + !list_empty(&rtd->card->aux_comp_list)) { + aux_comp = list_first_entry(&rtd->card->aux_comp_list, + struct snd_soc_component, card_aux_list); if (!strcmp(aux_comp->name, WSA8810_NAME_1) || !strcmp(aux_comp->name, WSA8810_NAME_2)) { wsa_macro_set_spkr_mode(component, @@ -5387,194 +5411,6 @@ static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) return ret; } -static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, - enum pinctrl_pin_state new_state) -{ - int ret = 0; - int curr_state = 0; - - if (pinctrl_info == NULL) { - pr_err("%s: pinctrl_info is NULL\n", __func__); - ret = -EINVAL; - goto err; - } - - if (pinctrl_info->pinctrl == NULL) { - pr_err("%s: pinctrl_info->pinctrl is NULL\n", __func__); - ret = -EINVAL; - goto err; - } - - curr_state = pinctrl_info->curr_state; - pinctrl_info->curr_state = new_state; - pr_debug("%s: curr_state = %s new_state = %s\n", __func__, - pin_states[curr_state], pin_states[pinctrl_info->curr_state]); - - if (curr_state == pinctrl_info->curr_state) { - pr_debug("%s: Already in same state\n", __func__); - goto err; - } - - if (curr_state != STATE_DISABLE && - pinctrl_info->curr_state != STATE_DISABLE) { - pr_debug("%s: state already active cannot switch\n", __func__); - ret = -EIO; - goto err; - } - - switch (pinctrl_info->curr_state) { - case STATE_MI2S_ACTIVE: - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_active); - if (ret) { - pr_err("%s: MI2S state select failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - break; - case STATE_TDM_ACTIVE: - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->tdm_active); - if (ret) { - pr_err("%s: TDM state select failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - break; - case STATE_DISABLE: - if (curr_state == STATE_MI2S_ACTIVE) { - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_disable); - } else { - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->tdm_disable); - } - if (ret) { - pr_err("%s: state disable failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - break; - default: - pr_err("%s: TLMM pin state is invalid\n", __func__); - return -EINVAL; - } - -err: - return ret; -} - -static int msm_get_pinctrl(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = NULL; - struct pinctrl *pinctrl; - int ret = 0; - - pinctrl_info = &pdata->pinctrl_info; - - if (pinctrl_info == NULL) { - pr_err("%s: pinctrl_info is NULL\n", __func__); - return -EINVAL; - } - - pinctrl = devm_pinctrl_get(&pdev->dev); - if (IS_ERR_OR_NULL(pinctrl)) { - pr_err("%s: Unable to get pinctrl handle\n", __func__); - return -EINVAL; - } - pinctrl_info->pinctrl = pinctrl; - - /* get all the states handles from Device Tree */ - pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl, - "quat-mi2s-sleep"); - if (IS_ERR(pinctrl_info->mi2s_disable)) { - pr_err("%s: could not get mi2s_disable pinstate\n", __func__); - goto err; - } - pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl, - "quat-mi2s-active"); - if (IS_ERR(pinctrl_info->mi2s_active)) { - pr_err("%s: could not get mi2s_active pinstate\n", __func__); - goto err; - } - pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl, - "quat-tdm-sleep"); - if (IS_ERR(pinctrl_info->tdm_disable)) { - pr_err("%s: could not get tdm_disable pinstate\n", __func__); - goto err; - } - pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl, - "quat-tdm-active"); - if (IS_ERR(pinctrl_info->tdm_active)) { - pr_err("%s: could not get tdm_active pinstate\n", - __func__); - goto err; - } - /* Reset the TLMM pins to a default state */ - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_disable); - if (ret != 0) { - pr_err("%s: Disable TLMM pins failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - pinctrl_info->curr_state = STATE_DISABLE; - - return 0; - -err: - devm_pinctrl_put(pinctrl); - pinctrl_info->pinctrl = NULL; - return -EINVAL; -} - -static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - - if (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) { - channels->min = channels->max = - tdm_rx_cfg[TDM_QUAT][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); - rate->min = rate->max = - tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; - } else if (cpu_dai->id == AFE_PORT_ID_SECONDARY_TDM_RX) { - channels->min = channels->max = - tdm_rx_cfg[TDM_SEC][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; - } else if (cpu_dai->id == AFE_PORT_ID_QUINARY_TDM_RX) { - channels->min = channels->max = - tdm_rx_cfg[TDM_QUIN][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate; - } else { - pr_err("%s: dai id 0x%x not supported\n", - __func__, cpu_dai->id); - return -EINVAL; - } - - pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n", - __func__, cpu_dai->id, channels->max, rate->max, - params_format(params)); - - return 0; -} - static int sm6150_tdm_snd_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -5691,6 +5527,38 @@ static int sm6150_tdm_snd_hw_params(struct snd_pcm_substream *substream, return ret; } +static int msm_get_tdm_mode(u32 port_id) +{ + int tdm_mode; + + switch (port_id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_TX: + tdm_mode = TDM_PRI; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_TX: + tdm_mode = TDM_SEC; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_TX: + tdm_mode = TDM_TERT; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + tdm_mode = TDM_QUAT; + break; + case AFE_PORT_ID_QUINARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_TX: + tdm_mode = TDM_QUIN; + break; + default: + pr_err("%s: Invalid port id: %d\n", __func__, port_id); + tdm_mode = -EINVAL; + } + return tdm_mode; +} + static int sm6150_tdm_snd_startup(struct snd_pcm_substream *substream) { int ret = 0; @@ -5698,37 +5566,38 @@ static int sm6150_tdm_snd_startup(struct snd_pcm_substream *substream) struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int tdm_mode = msm_get_tdm_mode(cpu_dai->id); - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || - (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { - ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); - if (ret) - pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret); + if (tdm_mode < 0) { + dev_err(rtd->card->dev, "%s: Invalid tdm_mode\n", __func__); + return tdm_mode; } + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + if (pdata->mi2s_gpio_p[tdm_mode]) + ret = msm_cdc_pinctrl_select_active_state( + pdata->mi2s_gpio_p[tdm_mode]); + return ret; } static void sm6150_tdm_snd_shutdown(struct snd_pcm_substream *substream) { - int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int tdm_mode = msm_get_tdm_mode(cpu_dai->id); - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || - (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { - ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); - if (ret) - pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret); + if (tdm_mode < 0) { + dev_err(rtd->card->dev, "%s: Invalid tdm_mode\n", __func__); + return; } + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + if (pdata->mi2s_gpio_p[tdm_mode]) + msm_cdc_pinctrl_select_sleep_state( + pdata->mi2s_gpio_p[tdm_mode]); } static struct snd_soc_ops sm6150_tdm_be_ops = { @@ -5767,17 +5636,22 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int index = cpu_dai->id; + int port_id = msm_get_port_id(rtd->dai_link->id); unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - int ret_pinctrl = 0; dev_dbg(rtd->card->dev, "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", __func__, substream->name, substream->stream, cpu_dai->name, cpu_dai->id); + if (port_id < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto err; + } + if (index < PRIM_MI2S || index >= MI2S_MAX) { ret = -EINVAL; dev_err(rtd->card->dev, @@ -5811,13 +5685,21 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) __func__, index, ret); goto clk_off; } - if (index == QUAT_MI2S) { - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_MI2S_ACTIVE); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); + if (mi2s_intf_conf[index].msm_is_ext_mclk) { + pr_debug("%s: Enabling mclk, clk_freq_in_hz = %u\n", + __func__, mi2s_mclk[index].clk_freq_in_hz); + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_mclk[index]); + if (ret < 0) { + pr_err("%s: afe lpass mclk failed, err:%d\n", + __func__, ret); + goto clk_off; + } + mi2s_mclk[index].enable = 1; } + if (pdata->mi2s_gpio_p[index]) + msm_cdc_pinctrl_select_active_state( + pdata->mi2s_gpio_p[index]); } clk_off: if (ret < 0) @@ -5835,13 +5717,18 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) int ret; struct snd_soc_pcm_runtime *rtd = substream->private_data; int index = rtd->cpu_dai->id; + int port_id = msm_get_port_id(rtd->dai_link->id); struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; - int ret_pinctrl = 0; pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); + + if (port_id < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + return; + } + if (index < PRIM_MI2S || index >= MI2S_MAX) { pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); return; @@ -5849,16 +5736,24 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) mutex_lock(&mi2s_intf_conf[index].lock); if (--mi2s_intf_conf[index].ref_cnt == 0) { + if (pdata->mi2s_gpio_p[index]) + msm_cdc_pinctrl_select_sleep_state( + pdata->mi2s_gpio_p[index]); + ret = msm_mi2s_set_sclk(substream, false); if (ret < 0) pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", __func__, index, ret); - if (index == QUAT_MI2S) { - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_DISABLE); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); + + if (mi2s_intf_conf[index].msm_is_ext_mclk) { + pr_debug("%s: Disabling mclk, clk_freq_in_hz = %u\n", + __func__, mi2s_mclk[index].clk_freq_in_hz); + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_mclk[index]); + if (ret < 0) + pr_err("%s: mclk disable failed for MCLK (%d); ret=%d\n", + __func__, index, ret); + mi2s_mclk[index].enable = 0; } } mutex_unlock(&mi2s_intf_conf[index].lock); @@ -6793,7 +6688,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .no_pcm = 1, .dpcm_playback = 1, .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, - .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .be_hw_params_fixup = msm_be_hw_params_fixup, .ops = &sm6150_tdm_be_ops, .ignore_suspend = 1, .ignore_pmdown_time = 1, @@ -6812,6 +6707,35 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .ops = &sm6150_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUIN_TDM_RX_0, + .stream_name = "Quinary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36928", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &sm6150_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_TDM_TX_0, + .stream_name = "Quinary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36929", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &sm6150_tdm_be_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link msm_tavil_be_dai_links[] = { @@ -8321,6 +8245,7 @@ static void msm_i2s_auxpcm_init(struct platform_device *pdev) { int count; u32 mi2s_master_slave[MI2S_MAX]; + u32 mi2s_ext_mclk[MI2S_MAX]; int ret; for (count = 0; count < MI2S_MAX; count++) { @@ -8340,6 +8265,18 @@ static void msm_i2s_auxpcm_init(struct platform_device *pdev) mi2s_master_slave[count]; } } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-ext-mclk", + mi2s_ext_mclk, MI2S_MAX); + if (ret) { + dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-ext-mclk in DT node\n", + __func__); + } else { + for (count = 0; count < MI2S_MAX; count++) + mi2s_intf_conf[count].msm_is_ext_mclk = + mi2s_ext_mclk[count]; + } } static void msm_i2s_auxpcm_deinit(void) @@ -8350,6 +8287,7 @@ static void msm_i2s_auxpcm_deinit(void) mutex_destroy(&mi2s_intf_conf[count].lock); mi2s_intf_conf[count].ref_cnt = 0; mi2s_intf_conf[count].msm_is_mi2s_master = 0; + mi2s_intf_conf[count].msm_is_ext_mclk = 0; } } @@ -8548,6 +8486,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) "qcom,mbhc-audio-jack-type", pdev->dev.of_node->full_name); dev_dbg(&pdev->dev, "Jack type properties set to default\n"); + ret = 0; } else { if (!strcmp(mbhc_audio_jack_type, "4-pole-jack")) { wcd_mbhc_cfg.enable_anc_mic_detect = false; @@ -8563,6 +8502,18 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "Unknown value, set to default\n"); } } + + pdata->mi2s_gpio_p[PRIM_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,pri-mi2s-gpios", 0); + pdata->mi2s_gpio_p[SEC_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,sec-mi2s-gpios", 0); + pdata->mi2s_gpio_p[TERT_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,tert-mi2s-gpios", 0); + pdata->mi2s_gpio_p[QUAT_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,quat-mi2s-gpios", 0); + pdata->mi2s_gpio_p[QUIN_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,quin-mi2s-gpios", 0); + /* * Parse US-Euro gpio info from DT. Report no error if us-euro * entry is not found in DT file as some targets do not support @@ -8590,16 +8541,6 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) "fsa4480-i2c-handle", pdev->dev.of_node->full_name); } - /* Parse pinctrl info from devicetree */ - ret = msm_get_pinctrl(pdev); - if (!ret) { - pr_debug("%s: pinctrl parsing successful\n", __func__); - } else { - dev_dbg(&pdev->dev, - "%s: Parsing pinctrl failed with %d. Cannot use Ports\n", - __func__, ret); - ret = 0; - } msm_i2s_auxpcm_init(pdev); if (strcmp(card->name, "sm6150-tavil-snd-card")) { -- GitLab From d47fda4407f93422dbe578e4c24cba3f3783ac73 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Sun, 20 May 2018 19:21:10 +0530 Subject: [PATCH 0699/1645] asoc: add support for afe_loopback_tx BE dai Add dai driver and routing driver changes for afe loopback BE. This BE is used to capture EC reference data. Change-Id: Ia57f335bde5f8a47de0030fbf1cdb784c8821e17 Signed-off-by: Surendar Karka --- asoc/msm-dai-q6-v2.c | 34 +++++++++++++- asoc/msm-pcm-routing-v2.c | 95 +++++++++++++++++++++++++++++++++++++- asoc/msm-pcm-routing-v2.h | 2 + dsp/q6afe.c | 2 + include/dsp/apr_audio-v2.h | 1 + include/dsp/q6afe-v2.h | 1 + 6 files changed, 132 insertions(+), 3 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 962a1bdfe7b0..de8d96ff20d1 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -3558,6 +3558,30 @@ static struct snd_soc_dai_driver msm_dai_q6_afe_rx_dai[] = { }, }; +static struct snd_soc_dai_driver msm_dai_q6_afe_lb_tx_dai[] = { + { + .capture = { + .stream_name = "AFE Loopback Capture", + .aif_name = "AFE_LOOPBACK_TX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE ), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 192000, + }, + .id = AFE_LOOPBACK_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, + }, +}; + static struct snd_soc_dai_driver msm_dai_q6_afe_tx_dai[] = { { .capture = { @@ -3569,7 +3593,7 @@ static struct snd_soc_dai_driver msm_dai_q6_afe_tx_dai[] = { .channels_min = 1, .channels_max = 8, .rate_min = 8000, - .rate_max = 48000, + .rate_max = 48000, }, .ops = &msm_dai_q6_ops, .id = RT_PROXY_DAI_002_TX, @@ -3585,7 +3609,7 @@ static struct snd_soc_dai_driver msm_dai_q6_afe_tx_dai[] = { .channels_min = 1, .channels_max = 8, .rate_min = 8000, - .rate_max = 48000, + .rate_max = 48000, }, .ops = &msm_dai_q6_ops, .id = RT_PROXY_DAI_001_TX, @@ -5970,6 +5994,12 @@ static int msm_dai_q6_dev_probe(struct platform_device *pdev) pr_err("%s: Device not found stream name %s\n", __func__, stream_name); break; + case AFE_LOOPBACK_TX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, + &msm_dai_q6_afe_lb_tx_dai[0], + 1); + break; case INT_BT_SCO_RX: rc = snd_soc_register_component(&pdev->dev, &msm_dai_q6_component, &msm_dai_q6_bt_sco_rx_dai, 1); diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 936f97fc13d4..a671639d9be2 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -642,6 +642,7 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_SEC_SPDIF_TX}, { SLIMBUS_9_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_9_RX}, { SLIMBUS_9_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_9_TX}, + { AFE_LOOPBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_AFE_LOOPBACK_TX}, }; /* Track ASM playback & capture sessions of DAI @@ -9563,6 +9564,10 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_9_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul2_mixer_controls[] = { @@ -9758,6 +9763,10 @@ static const struct snd_kcontrol_new mmul2_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_9_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul3_mixer_controls[] = { @@ -9949,6 +9958,10 @@ static const struct snd_kcontrol_new mmul3_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul4_mixer_controls[] = { @@ -10136,6 +10149,10 @@ static const struct snd_kcontrol_new mmul4_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul5_mixer_controls[] = { @@ -10351,6 +10368,10 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_9_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul6_mixer_controls[] = { @@ -10542,6 +10563,10 @@ static const struct snd_kcontrol_new mmul6_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul8_mixer_controls[] = { @@ -10741,6 +10766,10 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_9_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul16_mixer_controls[] = { @@ -10946,6 +10975,10 @@ static const struct snd_kcontrol_new mmul16_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_9_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul9_mixer_controls[] = { @@ -11081,6 +11114,10 @@ static const struct snd_kcontrol_new mmul9_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul10_mixer_controls[] = { @@ -11250,6 +11287,10 @@ static const struct snd_kcontrol_new mmul10_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_9_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul17_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, @@ -11350,6 +11391,10 @@ static const struct snd_kcontrol_new mmul17_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul18_mixer_controls[] = { @@ -11455,6 +11500,10 @@ static const struct snd_kcontrol_new mmul18_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul19_mixer_controls[] = { @@ -11556,6 +11605,10 @@ static const struct snd_kcontrol_new mmul19_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul20_mixer_controls[] = { @@ -11711,6 +11764,10 @@ static const struct snd_kcontrol_new mmul20_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul21_mixer_controls[] = { @@ -11854,6 +11911,10 @@ static const struct snd_kcontrol_new mmul21_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul27_mixer_controls[] = { @@ -11901,6 +11962,10 @@ static const struct snd_kcontrol_new mmul27_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_9_TX, MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul28_mixer_controls[] = { @@ -12002,6 +12067,10 @@ static const struct snd_kcontrol_new mmul28_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul29_mixer_controls[] = { @@ -12103,6 +12172,10 @@ static const struct snd_kcontrol_new mmul29_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { @@ -18853,7 +18926,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { /* In- call recording */ SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_RX", "Slimbus6 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("SLIMBUS_6_TX", "Slimbus6 Capture", 0, 0, 0, 0), - + SND_SOC_DAPM_AIF_IN("AFE_LOOPBACK_TX", "AFE Loopback Capture", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("SLIMBUS_7_RX", "Slimbus7 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("SLIMBUS_7_TX", "Slimbus7 Capture", 0, 0, 0, 0), @@ -20746,6 +20820,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia1 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia1 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia1 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia1 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"MultiMedia1 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia1 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, @@ -20780,6 +20855,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia2 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia2 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia2 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia2 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia2 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"MultiMedia2 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia2 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, @@ -20814,6 +20890,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia3 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia3 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia3 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia3 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia3 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"MultiMedia3 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia3 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, @@ -20848,6 +20925,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia4 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia4 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia4 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia4 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia4 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"MultiMedia4 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia4 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, @@ -20882,6 +20960,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia5 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia5 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia5 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia5 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"MultiMedia5 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia5 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, @@ -20916,6 +20995,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia6 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia6 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia6 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia6 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"MultiMedia6 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia6 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, @@ -20950,6 +21030,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia8 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia8 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia8 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia8 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"MultiMedia8 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia8 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, @@ -20993,6 +21074,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia9 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia9 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia9 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia10 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"MultiMedia10 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, @@ -21008,6 +21090,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia10 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia20 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia20 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, @@ -21047,6 +21130,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia20 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia20 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia20 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia21 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"MultiMedia21 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, @@ -21083,6 +21167,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia21 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia21 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia21 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia27 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia27 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, @@ -21095,6 +21180,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia27 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"MultiMedia27 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia27 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia27 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, @@ -21134,6 +21220,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia16 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia16 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia16 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, @@ -21141,6 +21228,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia17 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, @@ -21148,6 +21236,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia18 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, @@ -21155,6 +21244,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia19 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, @@ -21162,6 +21252,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia28 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, @@ -21169,6 +21260,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia29 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, @@ -22850,6 +22942,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_TX_1", NULL, "BE_IN"}, {"QUAT_TDM_TX_2", NULL, "BE_IN"}, {"QUAT_TDM_TX_3", NULL, "BE_IN"}, + {"AFE_LOOPBACK_TX", NULL, "BE_IN"}, {"QUIN_TDM_TX_0", NULL, "BE_IN"}, {"QUIN_TDM_TX_1", NULL, "BE_IN"}, {"QUIN_TDM_TX_2", NULL, "BE_IN"}, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 02d1f54bd8da..1691b365dfa2 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -144,6 +144,7 @@ #define LPASS_BE_QUAT_TDM_TX_6 "QUAT_TDM_TX_6" #define LPASS_BE_QUAT_TDM_RX_7 "QUAT_TDM_RX_7" #define LPASS_BE_QUAT_TDM_TX_7 "QUAT_TDM_TX_7" +#define LPASS_BE_AFE_LOOPBACK_TX "AFE_LOOPBACK_TX" #define LPASS_BE_QUIN_TDM_RX_0 "QUIN_TDM_RX_0" #define LPASS_BE_QUIN_TDM_TX_0 "QUIN_TDM_TX_0" #define LPASS_BE_QUIN_TDM_RX_1 "QUIN_TDM_RX_1" @@ -455,6 +456,7 @@ enum { MSM_BACKEND_DAI_SEC_SPDIF_TX, MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, MSM_BACKEND_DAI_MAX, }; diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 8ae2739e234a..5841d3c50b39 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -4584,6 +4584,8 @@ int afe_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_6; case AFE_PORT_ID_RX_CODEC_DMA_RX_7: return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_7; + case AFE_LOOPBACK_TX: + return IDX_AFE_LOOPBACK_TX; default: pr_err("%s: port 0x%x\n", __func__, port_id); return -EINVAL; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 6193209b4955..5bf833045f88 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1341,6 +1341,7 @@ struct adm_cmd_connect_afe_port_v5 { #define INT_FM_TX 0x3005 #define RT_PROXY_PORT_001_RX 0x2000 #define RT_PROXY_PORT_001_TX 0x2001 +#define AFE_LOOPBACK_TX 0x6001 #define DISPLAY_PORT_RX 0x6020 #define AFE_PORT_INVALID 0xFFFF diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index ec2a4368abac..3cccb3a4ba31 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -258,6 +258,7 @@ enum { /* IDX 187 -> 189 */ IDX_AFE_PORT_ID_SENARY_PCM_RX, IDX_AFE_PORT_ID_SENARY_PCM_TX, + IDX_AFE_LOOPBACK_TX, AFE_MAX_PORTS }; -- GitLab From 8c6a1841890dc676eea46a4f6ac10a58b0c07c6a Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Fri, 16 Nov 2018 15:02:39 +0530 Subject: [PATCH 0700/1645] dsp: add support to get Direction of Arrival target scores Add support to get DOA tracking monitor data. This is required to support SVA LED display feature with FFECNS/FFNS enabled. Change-Id: I7e39c2f3998fcc3f9ed0767c0090f862e1ba7539 Signed-off-by: Chaithanya Krishna Bacharaju --- dsp/q6adm.c | 75 +++++++++++++++++++++++++++ dsp/q6afe.c | 103 ++++++++++++++++++++++++++++++++++++- include/dsp/apr_audio-v2.h | 24 +++++++++ include/dsp/q6adm-v2.h | 2 + include/dsp/q6afe-v2.h | 2 + 5 files changed, 204 insertions(+), 2 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 4534c4cbae1e..c205601355e8 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -4986,6 +4986,81 @@ int adm_get_source_tracking(int port_id, int copp_idx, } EXPORT_SYMBOL(adm_get_source_tracking); +/** + * adm_get_doa_tracking_mon - + * Retrieve doa tracking monitor info + * + * @port_id: Port ID number + * @copp_idx: copp index assigned + * @doa_tracking_data: pointer for doa data to be updated with + * + * Returns 0 on success or error on failure + */ +int adm_get_doa_tracking_mon(int port_id, int copp_idx, + struct doa_tracking_mon_param *doa_tracking_data) +{ + int ret = 0, i; + char *params_value; + uint32_t max_param_size = 0; + struct adm_param_doa_tracking_mon_t *doa_tracking_params = NULL; + struct param_hdr_v3 param_hdr; + + pr_debug("%s: Enter, port_id %d, copp_idx %d\n", + __func__, port_id, copp_idx); + + if (doa_tracking_data == NULL) { + pr_err("%s: Received NULL pointer for doa tracking data\n", + __func__); + return -EINVAL; + } + + max_param_size = sizeof(struct adm_param_doa_tracking_mon_t) + + sizeof(union param_hdrs); + params_value = kzalloc(max_param_size, GFP_KERNEL); + if (!params_value) + return -ENOMEM; + + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_FFECNS; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_FFV_DOA_TRACKING_MONITOR; + param_hdr.param_size = max_param_size; + ret = adm_get_pp_params(port_id, copp_idx, + ADM_CLIENT_ID_DEFAULT, NULL, ¶m_hdr, + params_value); + if (ret) { + pr_err("%s: get parameters failed ret:%d\n", __func__, ret); + goto done; + } + + doa_tracking_params = + (struct adm_param_doa_tracking_mon_t *)params_value; + for (i = 0; i < MAX_DOA_TRACKING_ANGLES; i++) { + doa_tracking_data->target_angle_L16[i] = + doa_tracking_params->target_angle_L16[i]; + pr_debug("%s: target angle[%d] = %d\n", + __func__, i, doa_tracking_data->target_angle_L16[i]); + } + + for (i = 0; i < MAX_DOA_TRACKING_ANGLES; i++) { + doa_tracking_data->interf_angle_L16[i] = + doa_tracking_params->interf_angle_L16[i]; + pr_debug("%s: interference angle[%d] = %d\n", + __func__, i, doa_tracking_data->interf_angle_L16[i]); + } + + for (i = 0; i < MAX_POLAR_ACTIVITY_INDICATORS; i++) { + doa_tracking_data->polar_activity[i] = + doa_tracking_params->polar_activity[i]; + } + +done: + pr_debug("%s: Exit, ret = %d\n", __func__, ret); + kfree(params_value); + return ret; +} +EXPORT_SYMBOL(adm_get_doa_tracking_mon); + int __init adm_init(void) { int i = 0, j; diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 8ae2739e234a..aa83dd37e5cc 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -122,6 +122,7 @@ struct afe_ctl { struct afe_sp_th_vi_get_param_resp th_vi_resp; struct afe_sp_ex_vi_get_param_resp ex_vi_resp; struct afe_av_dev_drift_get_param_resp av_dev_drift_resp; + struct afe_doa_tracking_mon_get_param_resp doa_tracking_mon_resp; int vi_tx_port; int vi_rx_port; uint32_t afe_sample_rates[AFE_MAX_PORTS]; @@ -264,12 +265,60 @@ static void av_dev_drift_afe_cb_handler(uint32_t opcode, uint32_t *payload, if (!this_afe.av_dev_drift_resp.status) { atomic_set(&this_afe.state, 0); } else { - pr_debug("%s: av_dev_drift_resp status: %d", __func__, + pr_debug("%s: av_dev_drift_resp status: %d\n", __func__, this_afe.av_dev_drift_resp.status); atomic_set(&this_afe.state, -1); } } +static void doa_tracking_mon_afe_cb_handler(uint32_t opcode, uint32_t *payload, + uint32_t payload_size) +{ + size_t expected_size = + sizeof(u32) + sizeof(struct doa_tracking_mon_param); + + switch (opcode) { + case AFE_PORT_CMDRSP_GET_PARAM_V2: + expected_size += sizeof(struct param_hdr_v1); + if (payload_size < expected_size) { + pr_err("%s: Error: received size %d, expected size %zu\n", + __func__, payload_size, expected_size); + return; + } + /* Repack response to add IID */ + this_afe.doa_tracking_mon_resp.status = payload[0]; + this_afe.doa_tracking_mon_resp.pdata.module_id = payload[1]; + this_afe.doa_tracking_mon_resp.pdata.instance_id = + INSTANCE_ID_0; + this_afe.doa_tracking_mon_resp.pdata.param_id = payload[2]; + this_afe.doa_tracking_mon_resp.pdata.param_size = payload[3]; + memcpy(&this_afe.doa_tracking_mon_resp.doa, &payload[4], + sizeof(struct doa_tracking_mon_param)); + break; + case AFE_PORT_CMDRSP_GET_PARAM_V3: + expected_size += sizeof(struct param_hdr_v3); + if (payload_size < expected_size) { + pr_err("%s: Error: received size %d, expected size %zu\n", + __func__, payload_size, expected_size); + return; + } + memcpy(&this_afe.doa_tracking_mon_resp, payload, + sizeof(this_afe.doa_tracking_mon_resp)); + break; + default: + pr_err("%s: Unrecognized command %d\n", __func__, opcode); + return; + } + + if (!this_afe.doa_tracking_mon_resp.status) { + atomic_set(&this_afe.state, 0); + } else { + pr_debug("%s: doa_tracking_mon_resp status: %d\n", __func__, + this_afe.doa_tracking_mon_resp.status); + atomic_set(&this_afe.state, -1); + } +} + static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, uint32_t payload_size) { @@ -479,7 +528,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) param_id = (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) ? payload[3] : payload[2]; - if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) { + if (param_id == AUDPROC_PARAM_ID_FFV_DOA_TRACKING_MONITOR) { + doa_tracking_mon_afe_cb_handler(data->opcode, + data->payload, data->payload_size); + } else if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) { av_dev_drift_afe_cb_handler(data->opcode, data->payload, data->payload_size); } else { @@ -7350,6 +7402,53 @@ int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats, } EXPORT_SYMBOL(afe_get_av_dev_drift); +/** + * afe_get_doa_tracking_mon - + * command to retrieve doa tracking monitor data + * + * @port: AFE port ID + * @doa_tracking_data: param to be updated with doa tracking data + * + * Returns 0 on success or error on failure + */ +int afe_get_doa_tracking_mon(u16 port, + struct doa_tracking_mon_param *doa_tracking_data) +{ + struct param_hdr_v3 param_hdr; + int ret = -EINVAL, i = 0; + + if (!doa_tracking_data) { + pr_err("%s: Invalid params\n", __func__); + goto exit; + } + + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AUDPROC_MODULE_ID_FFNS; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_FFV_DOA_TRACKING_MONITOR; + param_hdr.param_size = sizeof(struct doa_tracking_mon_param); + + ret = q6afe_get_params(port, NULL, ¶m_hdr); + if (ret < 0) { + pr_err("%s: get param port 0x%x param id[0x%x] failed %d\n", + __func__, port, param_hdr.param_id, ret); + goto exit; + } + + memcpy(doa_tracking_data, &this_afe.doa_tracking_mon_resp.doa, + param_hdr.param_size); + for (i = 0; i < MAX_DOA_TRACKING_ANGLES; i++) { + pr_debug("%s: target angle[%d] = %d\n", + __func__, i, doa_tracking_data->target_angle_L16[i]); + pr_debug("%s: interference angle[%d] = %d\n", + __func__, i, doa_tracking_data->interf_angle_L16[i]); + } + +exit: + return ret; +} +EXPORT_SYMBOL(afe_get_doa_tracking_mon); + int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) { struct param_hdr_v3 param_hdr; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 6193209b4955..1199fa11f193 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -12188,6 +12188,7 @@ struct adm_set_compressed_device_latency { #define MAX_SECTORS 8 #define MAX_NOISE_SOURCE_INDICATORS 3 #define MAX_POLAR_ACTIVITY_INDICATORS 360 +#define MAX_DOA_TRACKING_ANGLES 2 struct sound_focus_param { uint16_t start_angle[MAX_SECTORS]; @@ -12202,6 +12203,12 @@ struct source_tracking_param { uint8_t polar_activity[MAX_POLAR_ACTIVITY_INDICATORS]; } __packed; +struct doa_tracking_mon_param { + uint16_t target_angle_L16[MAX_DOA_TRACKING_ANGLES]; + uint16_t interf_angle_L16[MAX_DOA_TRACKING_ANGLES]; + uint8_t polar_activity[MAX_POLAR_ACTIVITY_INDICATORS]; +} __packed; + struct adm_param_fluence_soundfocus_t { uint16_t start_angles[MAX_SECTORS]; uint8_t enables[MAX_SECTORS]; @@ -12216,6 +12223,18 @@ struct adm_param_fluence_sourcetracking_t { uint8_t polar_activity[MAX_POLAR_ACTIVITY_INDICATORS]; } __packed; +struct adm_param_doa_tracking_mon_t { + uint16_t target_angle_L16[MAX_DOA_TRACKING_ANGLES]; + uint16_t interf_angle_L16[MAX_DOA_TRACKING_ANGLES]; + uint8_t polar_activity[MAX_POLAR_ACTIVITY_INDICATORS]; +} __packed; + +struct afe_doa_tracking_mon_get_param_resp { + uint32_t status; + struct param_hdr_v3 pdata; + struct doa_tracking_mon_param doa; +} __packed; + #define AUDPROC_MODULE_ID_AUDIOSPHERE 0x00010916 #define AUDPROC_PARAM_ID_AUDIOSPHERE_ENABLE 0x00010917 #define AUDPROC_PARAM_ID_AUDIOSPHERE_STRENGTH 0x00010918 @@ -12231,6 +12250,11 @@ struct adm_param_fluence_sourcetracking_t { #define AUDPROC_MODULE_ID_VOICE_TX_SECNS 0x10027059 #define AUDPROC_PARAM_IDX_SEC_PRIMARY_MIC_CH 0x10014444 +#define AUDPROC_MODULE_ID_FFECNS 0x00010952 +#define AUDPROC_MODULE_ID_FFNS 0x00010962 +#define AUDPROC_PARAM_ID_FFV_DOA_TRACKING_PARAM 0x11003 +#define AUDPROC_PARAM_ID_FFV_DOA_TRACKING_MONITOR 0x11004 + struct admx_sec_primary_mic_ch { uint16_t version; uint16_t reserved; diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 95fbb0d1fc49..d65e6d49b321 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -191,6 +191,8 @@ int adm_get_sound_focus(int port_id, int copp_idx, struct sound_focus_param *soundFocusData); int adm_get_source_tracking(int port_id, int copp_idx, struct source_tracking_param *sourceTrackingData); +int adm_get_doa_tracking_mon(int port_id, int copp_idx, + struct doa_tracking_mon_param *doa_tracking_data); int adm_set_custom_chmix_cfg(int port_id, int copp_idx, unsigned int session_id, char *params, uint32_t params_length, int direction, diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index ec2a4368abac..9954d24a8fe8 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -448,4 +448,6 @@ int afe_send_port_island_mode(u16 port_id); int afe_send_cmd_wakeup_register(void *handle, bool enable); void afe_register_wakeup_irq_callback( void (*afe_cb_wakeup_irq)(void *handle)); +int afe_get_doa_tracking_mon(u16 port_id, + struct doa_tracking_mon_param *doa_tracking_data); #endif /* __Q6AFE_V2_H__ */ -- GitLab From 62cd1975a32d118e6dd603011627ca6fc58b5019 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 27 Nov 2018 18:12:11 +0530 Subject: [PATCH 0701/1645] soc: swr-wcd: Apply div2 setting on slave side before bank switch In soundwire controller, bank switch happen twice for a playback session with stereo speakers. Ensure the setting of div2 applied to inactive bank before bank switch occurs to avoid impact based on bank chosen. Change-Id: I033b19e78309485ca9da85ec67b54409e6fe22cc Signed-off-by: Laxminath Kasam --- soc/swr-wcd-ctrl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c index 4a41bd773049..13e5fa81c53a 100644 --- a/soc/swr-wcd-ctrl.c +++ b/soc/swr-wcd-ctrl.c @@ -647,6 +647,10 @@ static u8 get_inactive_bank_num(struct swr_mstr_ctrl *swrm) static void enable_bank_switch(struct swr_mstr_ctrl *swrm, u8 bank, u8 row, u8 col) { + /* apply div2 setting for inactive bank before bank switch */ + swrm_cmd_fifo_wr_cmd(swrm, 0x01, 0xF, 0x00, + SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(bank)); + swrm_cmd_fifo_wr_cmd(swrm, ((row << 3) | col), 0xF, 0xF, SWRS_SCP_FRAME_CTRL_BANK(bank)); } @@ -885,10 +889,6 @@ static void swrm_apply_port_config(struct swr_master *master) dev_dbg(swrm->dev, "%s: enter bank: %d master_ports: %d\n", __func__, bank, master->num_port); - - swrm_cmd_fifo_wr_cmd(swrm, 0x01, 0xF, 0x00, - SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(bank)); - swrm_copy_data_port_config(master, bank); } -- GitLab From 2b901bc05b642df585156110817b0f110b1d838f Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 10 Apr 2018 11:12:30 +0800 Subject: [PATCH 0702/1645] ASoC: codecs: update max value for HPH volume On tavil, the range for HPHL/HPHR volume is 0 to 24. Update max value for HPHL/HPHR Volume. Change-Id: I03f2eb3f833e5dc93a7cddaba09e765aa6077616 Signed-off-by: Meng Wang --- asoc/codecs/wcd934x/wcd934x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 250a483387a0..becf7ee75862 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -6531,8 +6531,8 @@ static const struct snd_kcontrol_new tavil_snd_controls[] = { SOC_ENUM_EXT("SPKR Right Boost Max State", tavil_spkr_boost_stage_enum, tavil_spkr_right_boost_stage_get, tavil_spkr_right_boost_stage_put), - SOC_SINGLE_TLV("HPHL Volume", WCD934X_HPH_L_EN, 0, 20, 1, line_gain), - SOC_SINGLE_TLV("HPHR Volume", WCD934X_HPH_R_EN, 0, 20, 1, line_gain), + SOC_SINGLE_TLV("HPHL Volume", WCD934X_HPH_L_EN, 0, 24, 1, line_gain), + SOC_SINGLE_TLV("HPHR Volume", WCD934X_HPH_R_EN, 0, 24, 1, line_gain), SOC_SINGLE_TLV("LINEOUT1 Volume", WCD934X_DIFF_LO_LO1_COMPANDER, 3, 16, 1, line_gain), SOC_SINGLE_TLV("LINEOUT2 Volume", WCD934X_DIFF_LO_LO2_COMPANDER, -- GitLab From 779b11e4999d1dbc41f87980902f884a9aee91c2 Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Tue, 20 Nov 2018 14:37:19 +0530 Subject: [PATCH 0703/1645] asoc: add support to get Direction of Arrival target scores Add support to get DOA tracking monitor data. This is required to support SVA LED display feature with FFECNS/FFNS enabled. Change-Id: I819cdd2971195653a955b22597d35b0fe521ec51 Signed-off-by: Chaithanya Krishna Bacharaju --- asoc/msm-pcm-routing-v2.c | 68 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 936f97fc13d4..2bce468abea2 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -17494,7 +17494,11 @@ static int msm_audio_get_copp_idx_from_port_id(int port_id, int session_type, } for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0], - MSM_FRONTEND_DAI_MM_SIZE) { + MSM_FRONTEND_DAI_MAX) { + if (!(is_mm_lsm_fe_id(i) && + route_check_fe_id_adm_support(i))) + continue; + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { copp = session_copp_map[i] [session_type][be_idx]; @@ -17506,7 +17510,7 @@ static int msm_audio_get_copp_idx_from_port_id(int port_id, int session_type, else break; } - if (i >= MSM_FRONTEND_DAI_MM_SIZE) { + if (i >= MSM_FRONTEND_DAI_MAX) { pr_debug("%s: Invalid FE, exiting\n", __func__); ret = -EINVAL; @@ -17692,6 +17696,59 @@ static int msm_audio_source_tracking_get(struct snd_kcontrol *kcontrol, return ret; } +static int msm_doa_tracking_mon_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(struct doa_tracking_mon_param); + + return 0; +} + +static int msm_doa_tracking_mon_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct doa_tracking_mon_param doa_tracking_data; + int port_id, copp_idx; + + memset(&doa_tracking_data, 0, sizeof(struct doa_tracking_mon_param)); + ret = msm_audio_sound_focus_derive_port_id(kcontrol, + "Doa Tracking Monitor Listen ", &port_id); + if (ret) { + pr_err("%s: Error in deriving port id, err=%d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + /* + * If copp id exists for given port id, query adm to get doa data. + * Else query afe for doa tracking params. + * This is to support in cases where LSM directly connects to + * AFE for FFNS. + */ + ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, + &copp_idx); + if (!ret) + ret = adm_get_doa_tracking_mon(port_id, copp_idx, + &doa_tracking_data); + else + ret = afe_get_doa_tracking_mon(port_id, &doa_tracking_data); + + if (ret) { + pr_err("%s: Error getting Doa Tracking Params, err=%d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + memcpy(ucontrol->value.bytes.data, (void *)&doa_tracking_data, + sizeof(struct doa_tracking_mon_param)); +done: + return ret; +} + static const struct snd_kcontrol_new msm_source_tracking_controls[] = { { .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, @@ -17873,6 +17930,13 @@ static const struct snd_kcontrol_new msm_source_tracking_controls[] = { .info = msm_source_tracking_info, .get = msm_audio_source_tracking_get, }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Doa Tracking Monitor Listen VA_CDC_DMA_TX_0", + .info = msm_doa_tracking_mon_info, + .get = msm_doa_tracking_mon_get, + }, }; static int spkr_prot_put_vi_lch_port(struct snd_kcontrol *kcontrol, -- GitLab From 0253cb9698f0924fa7ff0dfcbc51c39409a97f73 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 30 Nov 2018 11:14:36 -0800 Subject: [PATCH 0704/1645] dsp: q6afe: return error on no configuration data Move the return value to within the error check condition to avoid returning error for valid scenarios too. Change-Id: I718786d9eb3c779a85da3a4cb3929806692f5424 Signed-off-by: Karthikeyan Mani --- dsp/q6afe.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 8ae2739e234a..4f170fcce2e7 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2776,9 +2776,10 @@ int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg struct param_hdr_v3 param_hdr; int ret = 0; - if (!ch_status_cfg) + if (!ch_status_cfg) { pr_err("%s: Error, no configuration data\n", __func__); - return -EINVAL; + return -EINVAL; + } memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; -- GitLab From c21e98a1a4fc2a0762763a05e72e976102bc1f3e Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 4 Dec 2018 11:21:01 +0530 Subject: [PATCH 0705/1645] asoc: codecs: bolero: Update hph_pwr enum value same as class-H options Update hph_pwr enum value for LOHIFI as per class-H power options to maintain consistent naming. Change-Id: Ib7deb8d84bd1163a933d06ae92a51cb29b76e3c8 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 6e0916eaf430..5cd90d40f1e5 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -430,7 +430,7 @@ static const char *const rx_macro_hph_hd2_mode_text[] = {"OFF", "ON"}; static const struct soc_enum rx_macro_hph_hd2_mode_enum = SOC_ENUM_SINGLE_EXT(2, rx_macro_hph_hd2_mode_text); -static const char *const rx_macro_hph_pwr_mode_text[] = {"ULP", "LoHIFI"}; +static const char *const rx_macro_hph_pwr_mode_text[] = {"ULP", "LOHIFI"}; static const struct soc_enum rx_macro_hph_pwr_mode_enum = SOC_ENUM_SINGLE_EXT(2, rx_macro_hph_pwr_mode_text); -- GitLab From 849a5fdeb117ed96e77c3468225f7f808a8210f6 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 4 Dec 2018 15:51:56 +0530 Subject: [PATCH 0706/1645] asoc: sm6150: use locked version of soc_find_component use soc_find_component locked version to ensure proper access of component list while trying to find wsa or aux codec components from the list. Change-Id: I01303cbce13df45f290242776231d17aad68521e Signed-off-by: Aditya Bavanari --- asoc/sm6150.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 9727dffbbdbf..227a27011ab5 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -8157,7 +8157,7 @@ static int msm_init_aux_dev(struct platform_device *pdev, ret = -EINVAL; goto err; } - if (soc_find_component(wsa_of_node, NULL)) { + if (soc_find_component_locked(wsa_of_node, NULL)) { /* WSA device registered with ALSA core */ wsa881x_dev_info[found].of_node = wsa_of_node; wsa881x_dev_info[found].index = i; @@ -8224,7 +8224,7 @@ static int msm_init_aux_dev(struct platform_device *pdev, ret = -EINVAL; goto err; } - if (soc_find_component(aux_codec_of_node, NULL)) { + if (soc_find_component_locked(aux_codec_of_node, NULL)) { /* AUX codec registered with ALSA core */ aux_cdc_dev_info[codecs_found].of_node = aux_codec_of_node; -- GitLab From e7507516c49c4adf2672eaa3d46ca7e44ef02013 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Fri, 20 Jul 2018 15:46:54 +0530 Subject: [PATCH 0707/1645] asoc: set AFE_LOOPBACK_TX port id to EC ref port - AFE_LOOPBACK_TX BE is the dummy backend created to establish the EC reference capture path. While opening COPP pass playback port id instead of AFE_LOOPBACK_TX to get reference stream data from AFE RX port. - Add session type support in creating new COPP and while checking for existing COPP. CRs-Fixed: 2080421 Change-Id: I979f3ce1009cc18ff14130bebb8bd51a78fbe5ac Signed-off-by: Surendar Karka --- asoc/msm-pcm-routing-v2.c | 98 ++++++++++++++++++++------------------- dsp/q6adm.c | 21 +++++++-- include/dsp/q6adm-v2.h | 2 +- 3 files changed, 69 insertions(+), 52 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index a671639d9be2..4b2f185280cc 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -79,6 +79,7 @@ static bool is_ds2_on; static bool swap_ch; static int aanc_level; static int num_app_cfg_types; +static int msm_ec_ref_port_id; #define WEIGHT_0_DB 0x4000 /* all the FEs which can support channel mixer */ @@ -844,6 +845,11 @@ static int msm_pcm_routing_get_lsm_app_type_idx(int app_type) return 0; } +static int get_port_id(int port_id) +{ + return (port_id == AFE_LOOPBACK_TX ? msm_ec_ref_port_id : port_id); +} + static bool is_mm_lsm_fe_id(int fe_id) { bool rc = true; @@ -1162,12 +1168,12 @@ static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type, (afe_get_port_type(msm_bedais[i].port_id) == port_type) && (msm_bedais[i].active) && (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) { + int port_id = get_port_id(msm_bedais[i].port_id); for (j = 0; j < MAX_COPPS_PER_PORT; j++) { unsigned long copp = session_copp_map[fedai_id][sess_type][i]; if (test_bit(j, &copp)) { - payload.port_id[num_copps] = - msm_bedais[i].port_id; + payload.port_id[num_copps] = port_id; payload.copp_idx[num_copps] = j; payload.app_type[num_copps] = fe_dai_app_type_cfg @@ -1347,6 +1353,7 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, (msm_bedais[i].active) && (test_bit(fe_id, &msm_bedais[i].fe_sessions[0]))) { int app_type, app_type_idx, copp_idx, acdb_dev_id; + int port_id = get_port_id(msm_bedais[i].port_id); /* * check if ADM needs to be configured with different @@ -1395,10 +1402,10 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, topology); copp_idx = - adm_open(msm_bedais[i].port_id, - path_type, sample_rate, channels, - topology, perf_mode, bit_width, - app_type, acdb_dev_id); + adm_open(port_id, path_type, sample_rate, + channels, topology, perf_mode, + bit_width, app_type, acdb_dev_id, + session_type); if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { pr_err("%s:adm open failed coppid:%d\n", @@ -1414,16 +1421,14 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, if (msm_is_resample_needed( sample_rate, msm_bedais[i].sample_rate)) - adm_copp_mfc_cfg( - msm_bedais[i].port_id, copp_idx, + adm_copp_mfc_cfg(port_id, copp_idx, msm_bedais[i].sample_rate); for (j = 0; j < MAX_COPPS_PER_PORT; j++) { unsigned long copp = session_copp_map[fe_id][session_type][i]; if (test_bit(j, &copp)) { - payload.port_id[num_copps] = - msm_bedais[i].port_id; + payload.port_id[num_copps] = port_id; payload.copp_idx[num_copps] = j; payload.app_type[num_copps] = fe_dai_app_type_cfg @@ -1443,9 +1448,8 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, if (passthr_mode != COMPRESSED_PASSTHROUGH_DSD && passthr_mode != COMPRESSED_PASSTHROUGH_GEN && passthr_mode != COMPRESSED_PASSTHROUGH_IEC61937) - msm_routing_send_device_pp_params( - msm_bedais[i].port_id, - copp_idx, fe_id); + msm_routing_send_device_pp_params(port_id, + copp_idx, fe_id); } } if (num_copps) { @@ -1580,6 +1584,8 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, (msm_bedais[i].active) && (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) { int app_type, app_type_idx, copp_idx, acdb_dev_id; + int port_id = get_port_id(msm_bedais[i].port_id); + /* * check if ADM needs to be configured with different * channel mapping than backend @@ -1611,10 +1617,11 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, topology = msm_routing_get_adm_topology(fedai_id, session_type, i); - copp_idx = adm_open(msm_bedais[i].port_id, path_type, + copp_idx = adm_open(port_id, path_type, sample_rate, channels, topology, perf_mode, bits_per_sample, - app_type, acdb_dev_id); + app_type, acdb_dev_id, + session_type); if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { pr_err("%s: adm open failed copp_idx:%d\n", @@ -1630,16 +1637,14 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, if (msm_is_resample_needed( sample_rate, msm_bedais[i].sample_rate)) - adm_copp_mfc_cfg( - msm_bedais[i].port_id, copp_idx, + adm_copp_mfc_cfg(port_id, copp_idx, msm_bedais[i].sample_rate); for (j = 0; j < MAX_COPPS_PER_PORT; j++) { unsigned long copp = session_copp_map[fedai_id][session_type][i]; if (test_bit(j, &copp)) { - payload.port_id[num_copps] = - msm_bedais[i].port_id; + payload.port_id[num_copps] = port_id; payload.copp_idx[num_copps] = j; payload.app_type[num_copps] = fe_dai_app_type_cfg @@ -1657,8 +1662,8 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, } } if (perf_mode == LEGACY_PCM_MODE) - msm_pcm_routing_cfg_pp(msm_bedais[i].port_id, - copp_idx, topology, channels); + msm_pcm_routing_cfg_pp(port_id, copp_idx, + topology, channels); } } if (num_copps) { @@ -1693,7 +1698,7 @@ int msm_pcm_routing_reg_phy_stream_v2(int fedai_id, int perf_mode, void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type) { - int i, port_type, session_type, path_type, topology; + int i, port_type, session_type, path_type, topology, port_id; struct msm_pcm_routing_fdai_data *fdai; if (!is_mm_lsm_fe_id(fedai_id)) { @@ -1732,10 +1737,11 @@ void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type) __func__); continue; } + port_id = get_port_id(msm_bedais[i].port_id); topology = adm_get_topology_for_port_copp_idx( - msm_bedais[i].port_id, idx); + port_id, idx); msm_routing_unload_topology(topology); - adm_close(msm_bedais[i].port_id, fdai->perf_mode, idx); + adm_close(port_id, fdai->perf_mode, idx); pr_debug("%s:copp:%ld,idx bit fe:%d,type:%d,be:%d\n", __func__, copp, fedai_id, session_type, i); clear_bit(idx, @@ -1744,8 +1750,7 @@ void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type) topology == DS2_ADM_COPP_TOPOLOGY_ID) && (fdai->perf_mode == LEGACY_PCM_MODE) && (fdai->passthr_mode == LEGACY_PCM)) - msm_pcm_routing_deinit_pp(msm_bedais[i].port_id, - topology); + msm_pcm_routing_deinit_pp(port_id, topology); } } @@ -1824,6 +1829,7 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) if (msm_bedais[reg].active && fdai->strm_id != INVALID_SESSION) { int app_type, app_type_idx, copp_idx, acdb_dev_id; + int port_id = get_port_id(msm_bedais[reg].port_id); /* * check if ADM needs to be configured with different * channel mapping than backend @@ -1874,10 +1880,11 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) reg); acdb_dev_id = fe_dai_app_type_cfg[val][session_type][reg].acdb_dev_id; - copp_idx = adm_open(msm_bedais[reg].port_id, path_type, + copp_idx = adm_open(port_id, path_type, sample_rate, channels, topology, fdai->perf_mode, bits_per_sample, - app_type, acdb_dev_id); + app_type, acdb_dev_id, + session_type); if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { pr_err("%s: adm open failed\n", __func__); @@ -1892,8 +1899,7 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) if (msm_is_resample_needed( sample_rate, msm_bedais[reg].sample_rate)) - adm_copp_mfc_cfg( - msm_bedais[reg].port_id, copp_idx, + adm_copp_mfc_cfg(port_id, copp_idx, msm_bedais[reg].sample_rate); if (session_type == SESSION_TYPE_RX && @@ -1908,9 +1914,8 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) passthr_mode); if ((fdai->perf_mode == LEGACY_PCM_MODE) && (passthr_mode == LEGACY_PCM)) - msm_pcm_routing_cfg_pp(msm_bedais[reg].port_id, - copp_idx, topology, - channels); + msm_pcm_routing_cfg_pp(port_id, copp_idx, + topology, channels); } } else { if (test_bit(val, &msm_bedais[reg].fe_sessions[0]) && @@ -1934,12 +1939,11 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) mutex_unlock(&routing_lock); return; } - port_id = msm_bedais[reg].port_id; + port_id = get_port_id(msm_bedais[reg].port_id); topology = adm_get_topology_for_port_copp_idx(port_id, idx); msm_routing_unload_topology(topology); - adm_close(msm_bedais[reg].port_id, fdai->perf_mode, - idx); + adm_close(port_id, fdai->perf_mode, idx); pr_debug("%s: copp: %ld, reset idx bit fe:%d, type: %d, be:%d topology=0x%x\n", __func__, copp, val, session_type, reg, topology); @@ -1949,9 +1953,7 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) topology == DS2_ADM_COPP_TOPOLOGY_ID) && (fdai->perf_mode == LEGACY_PCM_MODE) && (passthr_mode == LEGACY_PCM)) - msm_pcm_routing_deinit_pp( - msm_bedais[reg].port_id, - topology); + msm_pcm_routing_deinit_pp(port_id, topology); msm_pcm_routing_build_matrix(val, session_type, path_type, fdai->perf_mode, @@ -3952,6 +3954,7 @@ static int msm_routing_ec_ref_rx_put(struct snd_kcontrol *kcontrol, ec_ref_port_id = AFE_PORT_INVALID; break; } + msm_ec_ref_port_id = ec_ref_port_id; adm_ec_ref_rx_id(ec_ref_port_id); pr_debug("%s: msm_route_ec_ref_rx = %d\n", __func__, msm_route_ec_ref_rx); @@ -23028,11 +23031,11 @@ static int msm_pcm_routing_close(struct snd_pcm_substream *substream) continue; } fdai->be_srate = bedai->sample_rate; - port_id = bedai->port_id; + port_id = get_port_id(bedai->port_id); topology = adm_get_topology_for_port_copp_idx(port_id, idx); msm_routing_unload_topology(topology); - adm_close(bedai->port_id, fdai->perf_mode, idx); + adm_close(port_id, fdai->perf_mode, idx); pr_debug("%s: copp:%ld,idx bit fe:%d, type:%d,be:%d topology=0x%x\n", __func__, copp, i, session_type, be_id, topology); @@ -23040,7 +23043,7 @@ static int msm_pcm_routing_close(struct snd_pcm_substream *substream) &session_copp_map[i][session_type][be_id]); if ((fdai->perf_mode == LEGACY_PCM_MODE) && (fdai->passthr_mode == LEGACY_PCM)) - msm_pcm_routing_deinit_pp(bedai->port_id, + msm_pcm_routing_deinit_pp(port_id, topology); } } @@ -23113,6 +23116,7 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) (i <= MSM_FRONTEND_DAI_LSM8); if (fdai->strm_id != INVALID_SESSION) { int app_type, app_type_idx, copp_idx, acdb_dev_id; + int port_id = get_port_id(bedai->port_id); if (session_type == SESSION_TYPE_TX && fdai->be_srate && @@ -23168,10 +23172,11 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) || (fdai->passthr_mode == COMPRESSED_PASSTHROUGH_IEC61937)) topology = COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY; - copp_idx = adm_open(bedai->port_id, path_type, + copp_idx = adm_open(port_id, path_type, sample_rate, channels, topology, fdai->perf_mode, bits_per_sample, - app_type, acdb_dev_id); + app_type, acdb_dev_id, + session_type); if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { pr_err("%s: adm open failed\n", __func__); @@ -23186,15 +23191,14 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) if (msm_is_resample_needed( sample_rate, bedai->sample_rate)) - adm_copp_mfc_cfg( - bedai->port_id, copp_idx, + adm_copp_mfc_cfg(port_id, copp_idx, bedai->sample_rate); msm_pcm_routing_build_matrix(i, session_type, path_type, fdai->perf_mode, fdai->passthr_mode); if ((fdai->perf_mode == LEGACY_PCM_MODE) && (fdai->passthr_mode == LEGACY_PCM)) - msm_pcm_routing_cfg_pp(bedai->port_id, copp_idx, + msm_pcm_routing_cfg_pp(port_id, copp_idx, topology, channels); } } diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 4534c4cbae1e..7db6cf68492e 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -61,6 +61,7 @@ struct adm_copp { atomic_t channels[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; atomic_t app_type[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; atomic_t acdb_id[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; + atomic_t session_type[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; wait_queue_head_t wait[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; wait_queue_head_t adm_delay_wait[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; atomic_t adm_delay_stat[AFE_MAX_PORTS][MAX_COPPS_PER_PORT]; @@ -269,7 +270,8 @@ static int adm_get_copp_id(int port_idx, int copp_idx) } static int adm_get_idx_if_copp_exists(int port_idx, int topology, int mode, - int rate, int bit_width, int app_type) + int rate, int bit_width, int app_type, + int session_type) { int idx; @@ -283,6 +285,9 @@ static int adm_get_idx_if_copp_exists(int port_idx, int topology, int mode, (rate == atomic_read(&this_adm.copp.rate[port_idx][idx])) && (bit_width == atomic_read(&this_adm.copp.bit_width[port_idx][idx])) && + (session_type == + atomic_read( + &this_adm.copp.session_type[port_idx][idx])) && (app_type == atomic_read(&this_adm.copp.app_type[port_idx][idx]))) return idx; @@ -1484,6 +1489,8 @@ static void adm_reset_data(void) &this_adm.copp.app_type[i][j], 0); atomic_set( &this_adm.copp.acdb_id[i][j], 0); + atomic_set( + &this_adm.copp.session_type[i][j], 0); this_adm.copp.adm_status[i][j] = ADM_STATUS_CALIBRATION_REQUIRED; } @@ -2750,11 +2757,13 @@ static int adm_arrange_mch_ep2_map_v8( * @bit_width: bit width to set for copp * @app_type: App type used for this session * @acdb_id: ACDB ID of this device + * @session_type: type of session * * Returns 0 on success or error on failure */ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, - int perf_mode, uint16_t bit_width, int app_type, int acdb_id) + int perf_mode, uint16_t bit_width, int app_type, int acdb_id, + int session_type) { struct adm_cmd_device_open_v5 open; struct adm_cmd_device_open_v6 open_v6; @@ -2838,7 +2847,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, copp_idx = adm_get_idx_if_copp_exists(port_idx, topology, perf_mode, rate, bit_width, - app_type); + app_type, session_type); if (copp_idx < 0) { copp_idx = adm_get_next_available_copp(port_idx); @@ -2862,6 +2871,8 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, app_type); atomic_set(&this_adm.copp.acdb_id[port_idx][copp_idx], acdb_id); + atomic_set(&this_adm.copp.session_type[port_idx][copp_idx], + session_type); set_bit(ADM_STATUS_CALIBRATION_REQUIRED, (void *)&this_adm.copp.adm_status[port_idx][copp_idx]); if ((path != ADM_PATH_COMPRESSED_RX) && @@ -3047,7 +3058,8 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, open.endpoint_id_1 = tmp_port; open.endpoint_id_2 = 0xFFFF; - if (this_adm.ec_ref_rx && (path != 1)) { + if (this_adm.ec_ref_rx && (path != 1) && + (afe_get_port_type(tmp_port) == MSM_AFE_PORT_TYPE_TX)) { open.endpoint_id_2 = this_adm.ec_ref_rx; this_adm.ec_ref_rx = -1; } @@ -3578,6 +3590,7 @@ int adm_close(int port_id, int perf_mode, int copp_idx) atomic_set(&this_adm.copp.channels[port_idx][copp_idx], 0); atomic_set(&this_adm.copp.bit_width[port_idx][copp_idx], 0); atomic_set(&this_adm.copp.app_type[port_idx][copp_idx], 0); + atomic_set(&this_adm.copp.session_type[port_idx][copp_idx], 0); clear_bit(ADM_STATUS_CALIBRATION_REQUIRED, (void *)&this_adm.copp.adm_status[port_idx][copp_idx]); diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 95fbb0d1fc49..a72fc083ba0c 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -107,7 +107,7 @@ int adm_pack_and_set_one_pp_param(int port_id, int copp_idx, int adm_open(int port, int path, int rate, int mode, int topology, int perf_mode, uint16_t bits_per_sample, - int app_type, int acdbdev_id); + int app_type, int acdbdev_id, int session_type); int adm_map_rtac_block(struct rtac_cal_block_data *cal_block); -- GitLab From 1efff87050b4c9b00228f4502e26ace818378471 Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Tue, 23 Oct 2018 16:11:49 +0200 Subject: [PATCH 0708/1645] asoc: codecs: Add ep92 version read and NULL check Provide chipid and version info in sysfs. Fix error handling and avoid polling when device is not present. Change-Id: Ie31b14e494e527ede001c334e3617f16fd687a28 Signed-off-by: Ralf Herz --- asoc/codecs/ep92/ep92.c | 436 +++++++++++++++++++++++----------------- 1 file changed, 248 insertions(+), 188 deletions(-) diff --git a/asoc/codecs/ep92/ep92.c b/asoc/codecs/ep92/ep92.c index c2cce8e2af49..06d29ff8207f 100644 --- a/asoc/codecs/ep92/ep92.c +++ b/asoc/codecs/ep92/ep92.c @@ -41,37 +41,8 @@ static const unsigned int ep92_samp_freq_table[8] = { static bool ep92_volatile_register(struct device *dev, unsigned int reg) { - switch (reg) { - case EP92_BI_GENERAL_INFO_0: - case EP92_BI_GENERAL_INFO_1: - case EP92_BI_GENERAL_INFO_2: - case EP92_BI_GENERAL_INFO_3: - case EP92_BI_GENERAL_INFO_4: - case EP92_BI_GENERAL_INFO_5: - case EP92_BI_GENERAL_INFO_6: - case EP92_GENERAL_CONTROL_0: - case EP92_GENERAL_CONTROL_1: - case EP92_GENERAL_CONTROL_2: - case EP92_GENERAL_CONTROL_3: - case EP92_GENERAL_CONTROL_4: - case EP92_AUDIO_INFO_SYSTEM_STATUS_0: - case EP92_AUDIO_INFO_SYSTEM_STATUS_1: - case EP92_AUDIO_INFO_AUDIO_STATUS: - case EP92_AUDIO_INFO_CHANNEL_STATUS_0: - case EP92_AUDIO_INFO_CHANNEL_STATUS_1: - case EP92_AUDIO_INFO_CHANNEL_STATUS_2: - case EP92_AUDIO_INFO_CHANNEL_STATUS_3: - case EP92_AUDIO_INFO_CHANNEL_STATUS_4: - case EP92_AUDIO_INFO_ADO_INFO_FRAME_0: - case EP92_AUDIO_INFO_ADO_INFO_FRAME_1: - case EP92_AUDIO_INFO_ADO_INFO_FRAME_2: - case EP92_AUDIO_INFO_ADO_INFO_FRAME_3: - case EP92_AUDIO_INFO_ADO_INFO_FRAME_4: - case EP92_AUDIO_INFO_ADO_INFO_FRAME_5: - return true; - default: - return false; - } + /* do not cache register state in regmap */ + return true; } static bool ep92_writeable_registers(struct device *dev, unsigned int reg) @@ -176,6 +147,9 @@ static ssize_t debugfs_codec_write_op(struct file *filp, int rc; u32 param[2]; + if (!component) + return -ENODEV; + if (!filp || !ppos || !ubuf) return -EINVAL; if (cnt > sizeof(lbuf) - 1) @@ -245,6 +219,9 @@ static ssize_t debugfs_codec_read_op(struct file *filp, struct snd_soc_component *component = ep92->component; ssize_t ret_cnt; + if (!component) + return -ENODEV; + if (!filp || !ppos || !ubuf || *ppos < 0) return -EINVAL; ret_cnt = debugfs_ep92_reg_show(component, ubuf, cnt, ppos); @@ -265,6 +242,8 @@ static int ep92_send_uevent(struct ep92_pdata *ep92, char *event) if (!event || !ep92) return -EINVAL; + if (!ep92->component) + return -ENODEV; return kobject_uevent_env(&ep92->component->dev->kobj, KOBJ_CHANGE, env); } @@ -333,7 +312,7 @@ static void ep92_read_general_control(struct snd_soc_component *component, ep92->gi.tx_info = snd_soc_component_read32(component, EP92_BI_GENERAL_INFO_0); if (ep92->gi.tx_info == 0xff) { - pr_debug("ep92 EP92_BI_GENERAL_INFO_0 read 0xff\n"); + dev_dbg(component->dev, "ep92 EP92_BI_GENERAL_INFO_0 read 0xff\n"); ep92->gi.tx_info = old; } /* implement hysteresis to prevent events on glitches */ @@ -343,7 +322,7 @@ static void ep92_read_general_control(struct snd_soc_component *component, if ((ep92->hyst_tx_plug == EP92_HYST_CNT) && (ep92->filt_tx_plug == 0)) { ep92->filt_tx_plug = 1; - pr_debug("ep92 out_plug changed to 1\n"); + dev_dbg(component->dev, "ep92 out_plug changed to 1\n"); ep92_send_uevent(ep92, "EP92EVT_OUT_PLUG=CONNECTED"); } @@ -354,7 +333,7 @@ static void ep92_read_general_control(struct snd_soc_component *component, if ((ep92->hyst_tx_plug == 0) && (ep92->filt_tx_plug == 1)) { ep92->filt_tx_plug = 0; - pr_debug("ep92 out_plug changed to 0\n"); + dev_dbg(component->dev, "ep92 out_plug changed to 0\n"); ep92_send_uevent(ep92, "EP92EVT_OUT_PLUG=DISCONNECTED"); } @@ -365,7 +344,7 @@ static void ep92_read_general_control(struct snd_soc_component *component, ep92->gi.video_latency = snd_soc_component_read32(component, EP92_BI_GENERAL_INFO_4); if (ep92->gi.video_latency == 0xff) { - pr_debug("ep92 EP92_BI_GENERAL_INFO_4 read 0xff\n"); + dev_dbg(component->dev, "ep92 EP92_BI_GENERAL_INFO_4 read 0xff\n"); ep92->gi.video_latency = old; } change = ep92->gi.video_latency ^ old; @@ -373,7 +352,7 @@ static void ep92_read_general_control(struct snd_soc_component *component, val = ep92->gi.video_latency; if (val > 0) val = (val - 1) * 2; - pr_debug("ep92 video latency changed to %d\n", val); + dev_dbg(component->dev, "ep92 video latency changed to %d\n", val); ep92_send_uevent(ep92, "EP92EVT_VIDEO_LATENCY=CHANGED"); } @@ -381,14 +360,14 @@ static void ep92_read_general_control(struct snd_soc_component *component, ep92->gc.ctl = snd_soc_component_read32(component, EP92_GENERAL_CONTROL_0); if (ep92->gc.ctl == 0xff) { - pr_debug("ep92 EP92_GENERAL_CONTROL_0 read 0xff\n"); + dev_dbg(component->dev, "ep92 EP92_GENERAL_CONTROL_0 read 0xff\n"); ep92->gc.ctl = old; } change = ep92->gc.ctl ^ old; if (change & EP92_GC_POWER_MASK) { val = (ep92->gc.ctl >> EP92_GC_POWER_SHIFT) & EP92_2CHOICE_MASK; - pr_debug("ep92 power changed to %d\n", val); + dev_dbg(component->dev, "ep92 power changed to %d\n", val); if (val) ep92_send_uevent(ep92, "EP92EVT_POWER=ON"); else @@ -397,7 +376,7 @@ static void ep92_read_general_control(struct snd_soc_component *component, if (change & EP92_GC_AUDIO_PATH_MASK) { val = (ep92->gc.ctl >> EP92_GC_AUDIO_PATH_SHIFT) & EP92_2CHOICE_MASK; - pr_debug("ep92 audio_path changed to %d\n", val); + dev_dbg(component->dev, "ep92 audio_path changed to %d\n", val); if (val) ep92_send_uevent(ep92, "EP92EVT_AUDIO_PATH=TV"); else @@ -406,7 +385,7 @@ static void ep92_read_general_control(struct snd_soc_component *component, if (change & EP92_GC_CEC_MUTE_MASK) { val = (ep92->gc.ctl >> EP92_GC_CEC_MUTE_SHIFT) & EP92_2CHOICE_MASK; - pr_debug("ep92 cec_mute changed to %d\n", val); + dev_dbg(component->dev, "ep92 cec_mute changed to %d\n", val); if (val) ep92_send_uevent(ep92, "EP92EVT_CEC_MUTE=NORMAL"); else @@ -414,7 +393,7 @@ static void ep92_read_general_control(struct snd_soc_component *component, } if (change & EP92_GC_ARC_EN_MASK) { val = ep92->gc.ctl & EP92_2CHOICE_MASK; - pr_debug("ep92 arc_en changed to %d\n", val); + dev_dbg(component->dev, "ep92 arc_en changed to %d\n", val); if (val) ep92_send_uevent(ep92, "EP92EVT_ARC_EN=ON"); else @@ -425,13 +404,13 @@ static void ep92_read_general_control(struct snd_soc_component *component, ep92->gc.rx_sel = snd_soc_component_read32(component, EP92_GENERAL_CONTROL_1); if (ep92->gc.rx_sel == 0xff) { - pr_debug("ep92 EP92_GENERAL_CONTROL_1 read 0xff\n"); + dev_dbg(component->dev, "ep92 EP92_GENERAL_CONTROL_1 read 0xff\n"); ep92->gc.rx_sel = old; } change = ep92->gc.rx_sel ^ old; if (change & EP92_GC_RX_SEL_MASK) { val = ep92->gc.rx_sel & EP92_GC_RX_SEL_MASK; - pr_debug("ep92 rx_sel changed to %d\n", val); + dev_dbg(component->dev, "ep92 rx_sel changed to %d\n", val); ep92_send_uevent(ep92, "EP92EVT_SRC_SEL=CHANGED"); } @@ -439,13 +418,13 @@ static void ep92_read_general_control(struct snd_soc_component *component, ep92->gc.cec_volume = snd_soc_component_read32(component, EP92_GENERAL_CONTROL_3); if (ep92->gc.cec_volume == 0xff) { - pr_debug("ep92 EP92_GENERAL_CONTROL_3 read 0xff\n"); + dev_dbg(component->dev, "ep92 EP92_GENERAL_CONTROL_3 read 0xff\n"); ep92->gc.cec_volume = old; } change = ep92->gc.cec_volume ^ old; if (change & EP92_GC_CEC_VOLUME_MASK) { val = ep92->gc.cec_volume & EP92_GC_CEC_VOLUME_MASK; - pr_debug("ep92 cec_volume changed to %d\n", val); + dev_dbg(component->dev, "ep92 cec_volume changed to %d\n", val); ep92_send_uevent(ep92, "EP92EVT_CEC_VOLUME=CHANGED"); } @@ -453,7 +432,7 @@ static void ep92_read_general_control(struct snd_soc_component *component, ep92->gc.link = snd_soc_component_read32(component, EP92_GENERAL_CONTROL_4); if (ep92->gc.link == 0xff) { - pr_debug("ep92 EP92_GENERAL_CONTROL_4 read 0xff\n"); + dev_dbg(component->dev, "ep92 EP92_GENERAL_CONTROL_4 read 0xff\n"); ep92->gc.link = old; } @@ -464,7 +443,7 @@ static void ep92_read_general_control(struct snd_soc_component *component, if ((ep92->hyst_link_on0 == EP92_HYST_CNT) && (ep92->filt_link_on0 == 0)) { ep92->filt_link_on0 = 1; - pr_debug("ep92 link_on0 changed to 1\n"); + dev_dbg(component->dev, "ep92 link_on0 changed to 1\n"); ep92_send_uevent(ep92, "EP92EVT_LINK_ON0=CONNECTED"); } @@ -475,7 +454,7 @@ static void ep92_read_general_control(struct snd_soc_component *component, if ((ep92->hyst_link_on0 == 0) && (ep92->filt_link_on0 == 1)) { ep92->filt_link_on0 = 0; - pr_debug("ep92 link_on0 changed to 0\n"); + dev_dbg(component->dev, "ep92 link_on0 changed to 0\n"); ep92_send_uevent(ep92, "EP92EVT_LINK_ON0=DISCONNECTED"); } @@ -489,7 +468,7 @@ static void ep92_read_general_control(struct snd_soc_component *component, if ((ep92->hyst_link_on1 == EP92_HYST_CNT) && (ep92->filt_link_on1 == 0)) { ep92->filt_link_on1 = 1; - pr_debug("ep92 link_on1 changed to 1\n"); + dev_dbg(component->dev, "ep92 link_on1 changed to 1\n"); ep92_send_uevent(ep92, "EP92EVT_LINK_ON1=CONNECTED"); } @@ -500,7 +479,7 @@ static void ep92_read_general_control(struct snd_soc_component *component, if ((ep92->hyst_link_on1 == 0) && (ep92->filt_link_on1 == 1)) { ep92->filt_link_on1 = 0; - pr_debug("ep92 link_on1 changed to 0\n"); + dev_dbg(component->dev, "ep92 link_on1 changed to 0\n"); ep92_send_uevent(ep92, "EP92EVT_LINK_ON1=DISCONNECTED"); } @@ -514,7 +493,7 @@ static void ep92_read_general_control(struct snd_soc_component *component, if ((ep92->hyst_link_on2 == EP92_HYST_CNT) && (ep92->filt_link_on2 == 0)) { ep92->filt_link_on2 = 1; - pr_debug("ep92 link_on2 changed to 1\n"); + dev_dbg(component->dev, "ep92 link_on2 changed to 1\n"); ep92_send_uevent(ep92, "EP92EVT_LINK_ON2=CONNECTED"); } @@ -525,7 +504,7 @@ static void ep92_read_general_control(struct snd_soc_component *component, if ((ep92->hyst_link_on2 == 0) && (ep92->filt_link_on2 == 1)) { ep92->filt_link_on2 = 0; - pr_debug("ep92 link_on2 changed to 0\n"); + dev_dbg(component->dev, "ep92 link_on2 changed to 0\n"); ep92_send_uevent(ep92, "EP92EVT_LINK_ON2=DISCONNECTED"); } @@ -544,24 +523,24 @@ static void ep92_read_audio_info(struct snd_soc_component *component, ep92->ai.system_status_0 = snd_soc_component_read32(component, EP92_AUDIO_INFO_SYSTEM_STATUS_0); if (ep92->ai.system_status_0 == 0xff) { - pr_debug("ep92 EP92_AUDIO_INFO_SYSTEM_STATUS_0 read 0xff\n"); + dev_dbg(component->dev, "ep92 EP92_AUDIO_INFO_SYSTEM_STATUS_0 read 0xff\n"); ep92->ai.system_status_0 = old; } change = ep92->ai.system_status_0 ^ old; if (change & EP92_AI_MCLK_ON_MASK) { - pr_debug("ep92 status changed to %d\n", + dev_dbg(component->dev, "ep92 status changed to %d\n", (ep92->ai.system_status_0 >> EP92_AI_MCLK_ON_SHIFT) & EP92_2CHOICE_MASK); send_uevent = true; } if (change & EP92_AI_AVMUTE_MASK) { - pr_debug("ep92 avmute changed to %d\n", + dev_dbg(component->dev, "ep92 avmute changed to %d\n", (ep92->ai.system_status_0 >> EP92_AI_AVMUTE_SHIFT) & EP92_2CHOICE_MASK); send_uevent = true; } if (change & EP92_AI_LAYOUT_MASK) { - pr_debug("ep92 layout changed to %d\n", + dev_dbg(component->dev, "ep92 layout changed to %d\n", (ep92->ai.system_status_0) & EP92_2CHOICE_MASK); send_uevent = true; } @@ -570,12 +549,12 @@ static void ep92_read_audio_info(struct snd_soc_component *component, ep92->ai.audio_status = snd_soc_component_read32(component, EP92_AUDIO_INFO_AUDIO_STATUS); if (ep92->ai.audio_status == 0xff) { - pr_debug("ep92 EP92_AUDIO_INFO_AUDIO_STATUS read 0xff\n"); + dev_dbg(component->dev, "ep92 EP92_AUDIO_INFO_AUDIO_STATUS read 0xff\n"); ep92->ai.audio_status = old; } change = ep92->ai.audio_status ^ old; if (change & EP92_AI_RATE_MASK) { - pr_debug("ep92 rate changed to %d\n", + dev_dbg(component->dev, "ep92 rate changed to %d\n", ep92_samp_freq_table[(ep92->ai.audio_status) & EP92_AI_RATE_MASK]); send_uevent = true; @@ -587,7 +566,7 @@ static void ep92_read_audio_info(struct snd_soc_component *component, ep92->ai.cs[0] = snd_soc_component_read32(component, EP92_AUDIO_INFO_CHANNEL_STATUS_0); if (ep92->ai.cs[0] == 0xff) { - pr_debug("ep92 EP92_AUDIO_INFO_CHANNEL_STATUS_0 read 0xff\n"); + dev_dbg(component->dev, "ep92 EP92_AUDIO_INFO_CHANNEL_STATUS_0 read 0xff\n"); ep92->ai.cs[0] = old; } if (ep92->ai.cs[0] & EP92_AI_NPCM_MASK) @@ -598,7 +577,7 @@ static void ep92_read_audio_info(struct snd_soc_component *component, new_mode = 1; /* Compr */ if (ep92->old_mode != new_mode) { - pr_debug("ep92 mode changed to %d\n", new_mode); + dev_dbg(component->dev, "ep92 mode changed to %d\n", new_mode); send_uevent = true; } ep92->old_mode = new_mode; @@ -607,12 +586,12 @@ static void ep92_read_audio_info(struct snd_soc_component *component, ep92->ai.cc = snd_soc_component_read32(component, EP92_AUDIO_INFO_ADO_INFO_FRAME_1); if (ep92->ai.cc == 0xff) { - pr_debug("ep92 EP92_AUDIO_INFO_ADO_INFO_FRAME_1 read 0xff\n"); + dev_dbg(component->dev, "ep92 EP92_AUDIO_INFO_ADO_INFO_FRAME_1 read 0xff\n"); ep92->ai.cc = old; } change = ep92->ai.cc ^ old; if (change & EP92_AI_CH_COUNT_MASK) { - pr_debug("ep92 ch_count changed to %d (%d)\n", + dev_dbg(component->dev, "ep92 ch_count changed to %d (%d)\n", ep92->ai.cc & EP92_AI_CH_COUNT_MASK, (ep92->ai.cc & EP92_AI_CH_COUNT_MASK) == 0 ? 0 : (ep92->ai.cc & EP92_AI_CH_COUNT_MASK) + 1); @@ -623,12 +602,12 @@ static void ep92_read_audio_info(struct snd_soc_component *component, ep92->ai.ca = snd_soc_component_read32(component, EP92_AUDIO_INFO_ADO_INFO_FRAME_4); if (ep92->ai.ca == 0xff) { - pr_debug("ep92 EP92_AUDIO_INFO_ADO_INFO_FRAME_4 read 0xff\n"); + dev_dbg(component->dev, "ep92 EP92_AUDIO_INFO_ADO_INFO_FRAME_4 read 0xff\n"); ep92->ai.ca = old; } change = ep92->ai.ca ^ old; if (change & EP92_AI_CH_ALLOC_MASK) { - pr_debug("ep92 ch_alloc changed to 0x%02x\n", + dev_dbg(component->dev, "ep92 ch_alloc changed to 0x%02x\n", (ep92->ai.ca) & EP92_AI_CH_ALLOC_MASK); send_uevent = true; } @@ -640,6 +619,22 @@ static void ep92_read_audio_info(struct snd_soc_component *component, static void ep92_init(struct snd_soc_component *component, struct ep92_pdata *ep92) { + int reg0 = 0; + int reg1 = 0; + int reg2 = 0; + int reg3 = 0; + + if (!ep92 || !component) + return; + + reg0 = snd_soc_component_read32(component, EP92_BI_VERSION_YEAR); + reg1 = snd_soc_component_read32(component, EP92_BI_VERSION_MONTH); + reg2 = snd_soc_component_read32(component, EP92_BI_VERSION_DATE); + reg3 = snd_soc_component_read32(component, EP92_BI_VERSION_NUM); + + dev_info(compoent->dev, "ep92 version info %02d/%02d/%02d %d\n", + reg0, reg1, reg2, reg3); + /* update the format information in mixer controls */ ep92_read_general_control(component, ep92); ep92_read_audio_info(component, ep92); @@ -652,6 +647,12 @@ static int ep92_probe(struct snd_soc_component *component) ep92->component = component; ep92_init(component, ep92); + /* start polling when codec is registered */ + if (ep92->irq == 0) { + mod_timer(&ep92->timer, jiffies + + msecs_to_jiffies(EP92_POLL_INTERVAL_OFF_MSEC)); + } + return 0; } @@ -685,7 +686,7 @@ void ep92_read_status(struct work_struct *work) struct snd_soc_component *component = ep92->component; u8 val; - /* No polling before codec is initialized */ + /* No polling before component is initialized */ if (component == NULL) return; @@ -700,10 +701,10 @@ void ep92_read_status(struct work_struct *work) } if (val & EP92_GI_ADO_CHF_MASK) - pr_debug("ep92 audio mode change trigger.\n"); + dev_dbg(component->dev, "ep92 audio mode change trigger.\n"); if (val & EP92_GI_CEC_ECF_MASK) - pr_debug("ep92 CEC change trigger.\n"); + dev_dbg(component->dev, "ep92 CEC change trigger.\n"); /* check for general control changes */ ep92_read_general_control(component, ep92); @@ -717,7 +718,7 @@ static irqreturn_t ep92_irq(int irq, void *data) struct ep92_pdata *ep92 = data; struct snd_soc_component *component = ep92->component; - /* Treat interrupt before codec is initialized as spurious */ + /* Treat interrupt before component is initialized as spurious */ if (component == NULL) return IRQ_NONE; @@ -749,6 +750,64 @@ static const struct of_device_id ep92_of_match[] = { }; MODULE_DEVICE_TABLE(of, ep92_of_match); +static ssize_t ep92_sysfs_rda_chipid(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret = 0; + int reg0 = 0; + int reg1 = 0; + int reg2 = 0; + int reg3 = 0; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; + } + + reg0 = snd_soc_component_read32(ep92->component, EP92_BI_VENDOR_ID_0); + reg1 = snd_soc_component_read32(ep92->component, EP92_BI_VENDOR_ID_1); + reg2 = snd_soc_component_read32(ep92->component, EP92_BI_DEVICE_ID_0); + reg3 = snd_soc_component_read32(ep92->component, EP92_BI_DEVICE_ID_1); + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%02x%02x/%02x%02x\n", + reg0, reg1, reg2, reg3); + dev_dbg(dev, "%s: '%s'\n", __func__, buf); + + return ret; +} + +static ssize_t ep92_sysfs_rda_version(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret = 0; + int reg0 = 0; + int reg1 = 0; + int reg2 = 0; + int reg3 = 0; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; + } + + reg0 = snd_soc_component_read32(ep92->component, + EP92_BI_VERSION_YEAR); + reg1 = snd_soc_component_read32(ep92->component, + EP92_BI_VERSION_MONTH); + reg2 = snd_soc_component_read32(ep92->component, + EP92_BI_VERSION_DATE); + reg3 = snd_soc_component_read32(ep92->component, + EP92_BI_VERSION_NUM); + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%02d/%02d/%02d %d\n", + reg0, reg1, reg2, reg3); + dev_dbg(dev, "%s: '%s'\n", __func__, buf); + + return ret; +} + static ssize_t ep92_sysfs_rda_audio_state(struct device *dev, struct device_attribute *attr, char *buf) { @@ -756,16 +815,16 @@ static ssize_t ep92_sysfs_rda_audio_state(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = (ep92->ai.system_status_0 & EP92_AI_MCLK_ON_MASK) >> EP92_AI_MCLK_ON_SHIFT; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -777,15 +836,15 @@ static ssize_t ep92_sysfs_rda_audio_format(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = ep92->old_mode; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -797,15 +856,15 @@ static ssize_t ep92_sysfs_rda_audio_rate(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = ep92_samp_freq_table[(ep92->ai.audio_status) & EP92_AI_RATE_MASK]; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -817,16 +876,16 @@ static ssize_t ep92_sysfs_rda_audio_layout(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = (ep92->ai.system_status_0 & EP92_AI_LAYOUT_MASK) >> EP92_AI_LAYOUT_SHIFT; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -838,9 +897,9 @@ static ssize_t ep92_sysfs_rda_audio_ch_count(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = ep92->ai.cc & EP92_AI_CH_COUNT_MASK; @@ -849,7 +908,7 @@ static ssize_t ep92_sysfs_rda_audio_ch_count(struct device *dev, val += 1; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -861,15 +920,15 @@ static ssize_t ep92_sysfs_rda_audio_ch_alloc(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = ep92->ai.ca & EP92_AI_CH_ALLOC_MASK; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -881,9 +940,9 @@ static ssize_t ep92_sysfs_rda_avmute(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } @@ -891,7 +950,7 @@ static ssize_t ep92_sysfs_rda_avmute(struct device *dev, EP92_2CHOICE_MASK; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -903,15 +962,15 @@ static ssize_t ep92_sysfs_rda_link_on0(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = ep92->filt_link_on0; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -923,15 +982,15 @@ static ssize_t ep92_sysfs_rda_link_on1(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = ep92->filt_link_on1; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -943,15 +1002,15 @@ static ssize_t ep92_sysfs_rda_link_on2(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = ep92->filt_link_on2; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -963,15 +1022,15 @@ static ssize_t ep92_sysfs_rda_out_plug(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = ep92->filt_tx_plug; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -983,9 +1042,9 @@ static ssize_t ep92_sysfs_rda_video_latency(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = ep92->gi.video_latency & EP92_GI_VIDEO_LATENCY_MASK; @@ -993,7 +1052,7 @@ static ssize_t ep92_sysfs_rda_video_latency(struct device *dev, val = (val - 1) * 2; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -1005,16 +1064,16 @@ static ssize_t ep92_sysfs_rda_arc_disable(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = (ep92->gc.ctl2 >> EP92_GC_ARC_DIS_SHIFT) & EP92_2CHOICE_MASK; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -1025,18 +1084,18 @@ static ssize_t ep92_sysfs_wta_arc_disable(struct device *dev, int reg, val, rc; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } rc = kstrtoint(buf, 10, &val); if (rc) { - pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + dev_err(dev, "%s: kstrtoint failed. rc=%d\n", __func__, rc); goto end; } if ((val < 0) || (val > 1)) { - pr_err("%s: value out of range.\n", __func__); + dev_err(dev, "%s: value out of range.\n", __func__); rc = -EINVAL; goto end; } @@ -1061,15 +1120,15 @@ static ssize_t ep92_sysfs_rda_power(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = (ep92->gc.ctl >> EP92_GC_POWER_SHIFT) & EP92_2CHOICE_MASK; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -1080,18 +1139,18 @@ static ssize_t ep92_sysfs_wta_power(struct device *dev, int reg, val, rc; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } rc = kstrtoint(buf, 10, &val); if (rc) { - pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + dev_err(dev, "%s: kstrtoint failed. rc=%d\n", __func__, rc); goto end; } if ((val < 0) || (val > 1)) { - pr_err("%s: value out of range.\n", __func__); + dev_err(dev, "%s: value out of range.\n", __func__); rc = -EINVAL; goto end; } @@ -1115,15 +1174,15 @@ static ssize_t ep92_sysfs_rda_audio_path(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = (ep92->gc.ctl >> EP92_GC_AUDIO_PATH_SHIFT) & EP92_2CHOICE_MASK; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -1134,18 +1193,18 @@ static ssize_t ep92_sysfs_wta_audio_path(struct device *dev, int reg, val, rc; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } rc = kstrtoint(buf, 10, &val); if (rc) { - pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + dev_err(dev, "%s: kstrtoint failed. rc=%d\n", __func__, rc); goto end; } if ((val < 0) || (val > 1)) { - pr_err("%s: value out of range.\n", __func__); + dev_err(dev, "%s: value out of range.\n", __func__); rc = -EINVAL; goto end; } @@ -1171,15 +1230,15 @@ static ssize_t ep92_sysfs_rda_src_sel(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = ep92->gc.rx_sel & EP92_GC_RX_SEL_MASK; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -1190,18 +1249,18 @@ static ssize_t ep92_sysfs_wta_src_sel(struct device *dev, int reg, val, rc; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } rc = kstrtoint(buf, 10, &val); if (rc) { - pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + dev_err(dev, "%s: kstrtoint failed. rc=%d\n", __func__, rc); goto end; } if ((val < 0) || (val > 7)) { - pr_err("%s: value out of range.\n", __func__); + dev_err(dev, "%s: value out of range.\n", __func__); rc = -EINVAL; goto end; } @@ -1226,15 +1285,15 @@ static ssize_t ep92_sysfs_rda_arc_enable(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = (ep92->gc.ctl >> EP92_GC_ARC_EN_SHIFT) & EP92_2CHOICE_MASK; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -1245,18 +1304,18 @@ static ssize_t ep92_sysfs_wta_arc_enable(struct device *dev, int reg, val, rc; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } rc = kstrtoint(buf, 10, &val); if (rc) { - pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + dev_err(dev, "%s: kstrtoint failed. rc=%d\n", __func__, rc); goto end; } if ((val < 0) || (val > 1)) { - pr_err("%s: value out of range.\n", __func__); + dev_err(dev, "%s: value out of range.\n", __func__); rc = -EINVAL; goto end; } @@ -1281,15 +1340,15 @@ static ssize_t ep92_sysfs_rda_cec_mute(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = (ep92->gc.ctl >> EP92_GC_CEC_MUTE_SHIFT) & EP92_2CHOICE_MASK; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -1300,18 +1359,18 @@ static ssize_t ep92_sysfs_wta_cec_mute(struct device *dev, int reg, val, rc; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } rc = kstrtoint(buf, 10, &val); if (rc) { - pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + dev_err(dev, "%s: kstrtoint failed. rc=%d\n", __func__, rc); goto end; } if ((val < 0) || (val > 1)) { - pr_err("%s: value out of range.\n", __func__); + dev_err(dev, "%s: value out of range.\n", __func__); rc = -EINVAL; goto end; } @@ -1336,16 +1395,16 @@ static ssize_t ep92_sysfs_rda_cec_volume(struct device *dev, int val; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } val = (ep92->gc.cec_volume >> EP92_GC_CEC_VOLUME_SHIFT) & EP92_GC_CEC_VOLUME_MASK; ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); - pr_debug("%s: '%d'\n", __func__, val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); return ret; } @@ -1356,18 +1415,18 @@ static ssize_t ep92_sysfs_wta_cec_volume(struct device *dev, int reg, val, rc; struct ep92_pdata *ep92 = dev_get_drvdata(dev); - if (!ep92) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; } rc = kstrtoint(buf, 10, &val); if (rc) { - pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + dev_err(dev, "%s: kstrtoint failed. rc=%d\n", __func__, rc); goto end; } if ((val < 0) || (val > EP92_GC_CEC_VOLUME_MAX)) { - pr_err("%s: value out of range.\n", __func__); + dev_err(dev, "%s: value out of range.\n", __func__); rc = -EINVAL; goto end; } @@ -1381,6 +1440,8 @@ static ssize_t ep92_sysfs_wta_cec_volume(struct device *dev, return rc; } +static DEVICE_ATTR(chipid, 0444, ep92_sysfs_rda_chipid, NULL); +static DEVICE_ATTR(version, 0444, ep92_sysfs_rda_version, NULL); static DEVICE_ATTR(audio_state, 0444, ep92_sysfs_rda_audio_state, NULL); static DEVICE_ATTR(audio_format, 0444, ep92_sysfs_rda_audio_format, NULL); static DEVICE_ATTR(audio_rate, 0444, ep92_sysfs_rda_audio_rate, NULL); @@ -1408,6 +1469,8 @@ static DEVICE_ATTR(cec_volume, 0644, ep92_sysfs_rda_cec_volume, ep92_sysfs_wta_cec_volume); static struct attribute *ep92_fs_attrs[] = { + &dev_attr_chipid.attr, + &dev_attr_version.attr, &dev_attr_audio_state.attr, &dev_attr_audio_format.attr, &dev_attr_audio_rate.attr, @@ -1490,11 +1553,8 @@ static int ep92_i2c_probe(struct i2c_client *client, } } /* poll status if IRQ is not configured */ - if (ep92->irq == 0) { + if (ep92->irq == 0) timer_setup(&ep92->timer, ep92_poll_status, 0); - mod_timer(&ep92->timer, jiffies + - msecs_to_jiffies(EP92_POLL_INTERVAL_OFF_MSEC)); - } #if IS_ENABLED(CONFIG_DEBUG_FS) /* debugfs interface */ @@ -1529,19 +1589,19 @@ static int ep92_i2c_probe(struct i2c_client *client, } #endif /* CONFIG_DEBUG_FS */ - /* register codec */ + /* register component */ ret = snd_soc_register_component(&client->dev, &soc_codec_drv_ep92, ep92_dai, ARRAY_SIZE(ep92_dai)); if (ret) { - dev_err(&client->dev, - "%s %d: Failed to register CODEC: %d\n", - __func__, __LINE__, ret); + dev_err(&client->dev, "%s %d: Failed to register CODEC: %d\n", + __func__, __LINE__, ret); goto err_reg; } ret = ep92_sysfs_create(client, ep92); if (ret) { - pr_err("%s: sysfs creation failed ret=%d\n", __func__, ret); + dev_err(&client->dev, "%s: sysfs creation failed ret=%d\n", + __func__, ret); goto err_sysfs; } -- GitLab From 7e35478bf686128e73bbba9fcd9e61c6e173c233 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 21 Nov 2018 15:52:54 +0530 Subject: [PATCH 0709/1645] soc: swr-mstr: Store enabled interrupts information in master data Store interrupt mask variable in master private data to indicate the interrupts which are currently enabled. This is to avoid reading interrupt enable register, which varies on hardware version, for knowing the interrupt enabled info. Change-Id: Ic990decd1b1112a1ad2a6af0d9b42269fe4e1b4c Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 27 ++++++++++++++------------- soc/swr-mstr-ctrl.h | 1 + 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 06f3883a1184..03d6c27b811d 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -977,6 +977,7 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) pr_err("%s: swrm is null\n", __func__); return -EFAULT; } + mutex_lock(&swrm->mlock); bank = get_inactive_bank_num(swrm); @@ -996,7 +997,7 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) return -EINVAL; } swr_master_write(swrm, SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN, - SWRM_INTERRUPT_STATUS_MASK); + SWRM_INTERRUPT_STATUS_MASK); /* apply the new port config*/ swrm_apply_port_config(master); } else { @@ -1257,7 +1258,7 @@ static int swrm_check_slave_change_status(struct swr_mstr_ctrl *swrm, static irqreturn_t swr_mstr_interrupt(int irq, void *dev) { struct swr_mstr_ctrl *swrm = dev; - u32 value, intr_sts, intr_mask; + u32 value, intr_sts, intr_sts_masked; u32 temp = 0; u32 status, chg_sts, i; u8 devnum = 0; @@ -1275,11 +1276,10 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) mutex_unlock(&swrm->reslock); intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); - intr_mask = swr_master_read(swrm, SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN); - intr_sts &= intr_mask; + intr_sts_masked = intr_sts & swrm->intr_mask; handle_irq: for (i = 0; i < SWRM_INTERRUPT_MAX; i++) { - value = intr_sts & (1 << i); + value = intr_sts_masked & (1 << i); if (!value) continue; @@ -1371,16 +1371,16 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) break; case SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION: dev_err_ratelimited(swrm->dev, "SWR Port collision detected\n"); - intr_mask &= ~SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION; + swrm->intr_mask &= ~SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION; swr_master_write(swrm, - SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN, intr_mask); + SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN, swrm->intr_mask); break; case SWRM_INTERRUPT_STATUS_READ_EN_RD_VALID_MISMATCH: dev_dbg(swrm->dev, "SWR read enable valid mismatch\n"); - intr_mask &= + swrm->intr_mask &= ~SWRM_INTERRUPT_STATUS_READ_EN_RD_VALID_MISMATCH; swr_master_write(swrm, - SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN, intr_mask); + SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN, swrm->intr_mask); break; case SWRM_INTERRUPT_STATUS_SPECIAL_CMD_ID_FINISHED: complete(&swrm->broadcast); @@ -1408,9 +1408,9 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, 0x0); intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); - intr_sts &= intr_mask; + intr_sts_masked = intr_sts & swrm->intr_mask; - if (intr_sts) { + if (intr_sts_masked) { dev_dbg(swrm->dev, "%s: new interrupt received\n", __func__); goto handle_irq; } @@ -1630,12 +1630,13 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) reg[len] = SWRM_INTERRUPT_CLEAR; value[len++] = 0xFFFFFFFF; + swrm->intr_mask = SWRM_INTERRUPT_STATUS_MASK; /* Mask soundwire interrupts */ reg[len] = SWRM_INTERRUPT_MASK_ADDR; - value[len++] = 0x1FFFD; + value[len++] = swrm->intr_mask; reg[len] = SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN; - value[len++] = SWRM_INTERRUPT_STATUS_MASK; + value[len++] = swrm->intr_mask; swr_master_bulk_write(swrm, reg, value, len); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index a32fdc69b1b4..8582c51ea96c 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -162,6 +162,7 @@ struct swr_mstr_ctrl { enum swrm_pm_state pm_state; wait_queue_head_t pm_wq; int wlock_holders; + u32 intr_mask; }; #endif /* _SWR_WCD_CTRL_H */ -- GitLab From 32b3e5e2d6c057f284ef894cfcb8bf8d4f860732 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 4 Dec 2018 17:19:56 +0530 Subject: [PATCH 0710/1645] asoc: sm6150: Initialize variable in msm_init_aux_dev Initialize codec_max_aux_devs variable in msm_init_aux_dev function to avoid uninitialized variable usage. CRs-Fixed: 2357928 Change-Id: I4806f68dfaa9ea22c244fd6b102d8f0eed5abe0c Signed-off-by: Aditya Bavanari --- asoc/sm6150.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index f71ca2d66ffc..03b5ba49ccbd 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -8063,7 +8063,7 @@ static int msm_init_aux_dev(struct platform_device *pdev, struct device_node *aux_codec_of_node; u32 wsa_max_devs; u32 wsa_dev_cnt; - u32 codec_max_aux_devs; + u32 codec_max_aux_devs = 0; u32 codec_aux_dev_cnt = 0; int i; struct msm_wsa881x_dev_info *wsa881x_dev_info = NULL; -- GitLab From ab44f1b566e0be6383e73262fde99009036c6b8d Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Tue, 13 Nov 2018 16:39:17 +0530 Subject: [PATCH 0711/1645] asoc: qcs405: add afe loopback support in machine driver Add machine driver changes for AFE Rx to Tx loopback. Change-Id: I033d0b769126c229a7734f50d48601e4bf9810bb Signed-off-by: Meng Wang --- asoc/qcs405.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 835032ee9be9..e5310ab6952f 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -7463,6 +7463,22 @@ static struct snd_soc_dai_link msm_spdif_be_dai_links[] = { }, }; +static struct snd_soc_dai_link msm_afe_rxtx_lb_be_dai_link[] = { + { + .name = LPASS_BE_AFE_LOOPBACK_TX, + .stream_name = "AFE Loopback Capture", + .cpu_dai_name = "msm-dai-q6-dev.24577", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + static struct snd_soc_dai_link msm_qcs405_dai_links[ ARRAY_SIZE(msm_common_dai_links) + ARRAY_SIZE(msm_common_misc_fe_dai_links) + @@ -7474,7 +7490,8 @@ static struct snd_soc_dai_link msm_qcs405_dai_links[ ARRAY_SIZE(msm_va_cdc_dma_be_dai_links) + ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links) + ARRAY_SIZE(msm_bolero_fe_dai_links) + - ARRAY_SIZE(msm_spdif_be_dai_links)]; + ARRAY_SIZE(msm_spdif_be_dai_links) + + ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link)]; static int msm_snd_card_tasha_late_probe(struct snd_soc_card *card) { @@ -7724,6 +7741,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) uint32_t tasha_codec = 0, auxpcm_audio_intf = 0; uint32_t va_bolero_codec = 0, wsa_bolero_codec = 0, mi2s_audio_intf = 0; uint32_t spdif_audio_intf = 0, wcn_audio_intf = 0; + uint32_t afe_loopback_intf = 0; const struct of_device_id *match; char __iomem *spdif_cfg, *spdif_pin_ctl; int rc = 0; @@ -7881,6 +7899,20 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) ARRAY_SIZE(msm_wcn_be_dai_links); } } + rc = of_property_read_u32(dev->of_node, "qcom,afe-rxtx-lb", + &afe_loopback_intf); + if (rc) { + dev_dbg(dev, "%s: No DT match AFE loopback audio interface\n", + __func__); + } else { + if (afe_loopback_intf) { + memcpy(msm_qcs405_dai_links + total_links, + msm_afe_rxtx_lb_be_dai_link, + sizeof(msm_afe_rxtx_lb_be_dai_link)); + total_links += + ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link); + } + } dailink = msm_qcs405_dai_links; } else if (!strcmp(match->data, "stub_codec")) { card = &snd_soc_card_stub_msm; -- GitLab From c9443c282afadaaf50c82512d140e45818ba4489 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 28 Aug 2018 05:35:34 +0530 Subject: [PATCH 0712/1645] ASoC: wcd938x: Add support for wcd938x codec WCD938x codec is a soundwire based codec that supports AMICs, DMICs, Headphones, Ear and Aux paths. Add support to enable all device paths of wcd938x codec. Change-Id: I81b5e603ef73afba74b8d2274012752f9ca5cb6f Signed-off-by: Sudheer Papothi --- Android.mk | 7 + asoc/codecs/wcd938x/Android.mk | 57 + asoc/codecs/wcd938x/Kbuild | 112 + asoc/codecs/wcd938x/internal.h | 182 ++ asoc/codecs/wcd938x/wcd938x-mbhc.c | 1082 +++++++++ asoc/codecs/wcd938x/wcd938x-mbhc.h | 63 + asoc/codecs/wcd938x/wcd938x-registers.h | 502 +++++ asoc/codecs/wcd938x/wcd938x-regmap.c | 513 +++++ asoc/codecs/wcd938x/wcd938x-slave.c | 117 + asoc/codecs/wcd938x/wcd938x-tables.c | 474 ++++ asoc/codecs/wcd938x/wcd938x.c | 2704 +++++++++++++++++++++++ 11 files changed, 5813 insertions(+) create mode 100644 asoc/codecs/wcd938x/Android.mk create mode 100644 asoc/codecs/wcd938x/Kbuild create mode 100644 asoc/codecs/wcd938x/internal.h create mode 100644 asoc/codecs/wcd938x/wcd938x-mbhc.c create mode 100644 asoc/codecs/wcd938x/wcd938x-mbhc.h create mode 100644 asoc/codecs/wcd938x/wcd938x-registers.h create mode 100644 asoc/codecs/wcd938x/wcd938x-regmap.c create mode 100644 asoc/codecs/wcd938x/wcd938x-slave.c create mode 100644 asoc/codecs/wcd938x/wcd938x-tables.c create mode 100644 asoc/codecs/wcd938x/wcd938x.c diff --git a/Android.mk b/Android.mk index e3a969652da3..76813c110967 100644 --- a/Android.mk +++ b/Android.mk @@ -35,3 +35,10 @@ include $(MY_LOCAL_PATH)/asoc/codecs/bolero/Android.mk $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd937x/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wcd937x/Android.mk endif + +ifeq ($(call is-board-platform-in-list, kona),true) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/bolero/Module.symvers) +include $(MY_LOCAL_PATH)/asoc/codecs/bolero/Android.mk +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd938x/Module.symvers) +include $(MY_LOCAL_PATH)/asoc/codecs/wcd938x/Android.mk +endif diff --git a/asoc/codecs/wcd938x/Android.mk b/asoc/codecs/wcd938x/Android.mk new file mode 100644 index 000000000000..81bb35670715 --- /dev/null +++ b/asoc/codecs/wcd938x/Android.mk @@ -0,0 +1,57 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,kona),true) +AUDIO_SELECT := CONFIG_SND_SOC_KONA=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,kona),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=wcd938x_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd938x.ko +LOCAL_MODULE_KBUILD_NAME := wcd938x_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd938x_slave.ko +LOCAL_MODULE_KBUILD_NAME := wcd938x_slave_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/asoc/codecs/wcd938x/Kbuild b/asoc/codecs/wcd938x/Kbuild new file mode 100644 index 000000000000..309089074f24 --- /dev/null +++ b/asoc/codecs/wcd938x/Kbuild @@ -0,0 +1,112 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + +ifeq ($(KERNEL_BUILD), 1) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.19 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) + ifeq ($(CONFIG_ARCH_KONA), y) + include $(AUDIO_ROOT)/config/konaauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h + endif + +endif + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ WCD938X ############ + +# for WCD938X Codec +ifdef CONFIG_SND_SOC_WCD938X + WCD938X_OBJS += wcd938x.o + WCD938X_OBJS += wcd938x-regmap.o + WCD938X_OBJS += wcd938x-tables.o + WCD938X_OBJS += wcd938x-mbhc.o +endif + +ifdef CONFIG_SND_SOC_WCD938X_SLAVE + WCD938X_SLAVE_OBJS += wcd938x-slave.o +endif + +LINUX_INC += -Iinclude/linux + +INCS += $(COMMON_INC) \ + $(UAPI_INC) + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +ifeq ($(KERNEL_BUILD), 0) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_WCD938X) += wcd938x_dlkm.o +wcd938x_dlkm-y := $(WCD938X_OBJS) + +obj-$(CONFIG_SND_SOC_WCD938X_SLAVE) += wcd938x_slave_dlkm.o +wcd938x_slave_dlkm-y := $(WCD938X_SLAVE_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h new file mode 100644 index 000000000000..4811bd0f4ad0 --- /dev/null +++ b/asoc/codecs/wcd938x/internal.h @@ -0,0 +1,182 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _WCD938X_INTERNAL_H +#define _WCD938X_INTERNAL_H + +#include +#include +#include "wcd938x-mbhc.h" + +#define WCD938X_MAX_MICBIAS 4 + +/* Convert from vout ctl to micbias voltage in mV */ +#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50) +#define MAX_PORT 8 +#define MAX_CH_PER_PORT 8 + +enum { + TX_HDR12 = 0, + TX_HDR34, + TX_HDR_MAX, +}; + +extern struct regmap_config wcd938x_regmap_config; + +struct codec_port_info { + u32 slave_port_type; + u32 master_port_type; + u32 ch_mask; + u32 num_ch; + u32 ch_rate; +}; + +struct wcd938x_priv { + struct device *dev; + + int variant; + struct snd_soc_component *component; + struct device_node *rst_np; + struct regmap *regmap; + + struct swr_device *rx_swr_dev; + struct swr_device *tx_swr_dev; + + s32 micb_ref[WCD938X_MAX_MICBIAS]; + s32 pullup_ref[WCD938X_MAX_MICBIAS]; + + struct fw_info *fw_data; + struct device_node *wcd_rst_np; + + struct mutex micb_lock; + s32 dmic_0_1_clk_cnt; + s32 dmic_2_3_clk_cnt; + s32 dmic_4_5_clk_cnt; + s32 dmic_6_7_clk_cnt; + int hdr_en[TX_HDR_MAX]; + /* class h specific info */ + struct wcd_clsh_cdc_info clsh_info; + /* mbhc module */ + struct wcd938x_mbhc *mbhc; + + u32 hph_mode; + bool comp1_enable; + bool comp2_enable; + + struct irq_domain *virq; + struct wcd_irq_info irq_info; + u32 rx_clk_cnt; + int num_irq_regs; + /* to track the status */ + unsigned long status_mask; + + u8 num_tx_ports; + u8 num_rx_ports; + struct codec_port_info + tx_port_mapping[MAX_PORT][MAX_CH_PER_PORT]; + struct codec_port_info + rx_port_mapping[MAX_PORT][MAX_CH_PER_PORT]; + struct regulator_bulk_data *supplies; + + struct notifier_block nblock; + /* wcd callback to bolero */ + void *handle; + int (*update_wcd_event)(void *handle, u16 event, u32 data); + int (*register_notifier)(void *handle, + struct notifier_block *nblock, + bool enable); + u32 version; + /* Entry for version info */ + struct snd_info_entry *entry; + struct snd_info_entry *version_entry; +}; + +struct wcd938x_micbias_setting { + u8 ldoh_v; + u32 cfilt1_mv; + u32 micb1_mv; + u32 micb2_mv; + u32 micb3_mv; + u32 micb4_mv; + u8 bias1_cfilt_sel; +}; + +struct wcd938x_pdata { + struct device_node *rst_np; + struct device_node *rx_slave; + struct device_node *tx_slave; + struct wcd938x_micbias_setting micbias; + + struct cdc_regulator *regulator; + int num_supplies; +}; + +struct wcd_ctrl_platform_data { + void *handle; + int (*update_wcd_event)(void *handle, u16 event, u32 data); + int (*register_notifier)(void *handle, + struct notifier_block *nblock, + bool enable); +}; + +enum { + WCD_RX1, + WCD_RX2, + WCD_RX3 +}; + +enum { + BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1, + BOLERO_WCD_EVT_PA_OFF_PRE_SSR, + BOLERO_WCD_EVT_SSR_DOWN, + BOLERO_WCD_EVT_SSR_UP, + BOLERO_WCD_EVT_CLK_NOTIFY, +}; + +enum { + WCD_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */ + WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */ + WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */ +}; + +enum { + /* INTR_CTRL_INT_MASK_0 */ + WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET = 0, + WCD938X_IRQ_MBHC_BUTTON_PRESS_DET, + WCD938X_IRQ_MBHC_ELECT_INS_REM_DET, + WCD938X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, + WCD938X_IRQ_MBHC_SW_DET, + WCD938X_IRQ_HPHR_OCP_INT, + WCD938X_IRQ_HPHR_CNP_INT, + WCD938X_IRQ_HPHL_OCP_INT, + + /* INTR_CTRL_INT_MASK_1 */ + WCD938X_IRQ_HPHL_CNP_INT, + WCD938X_IRQ_EAR_CNP_INT, + WCD938X_IRQ_EAR_SCD_INT, + WCD938X_IRQ_AUX_CNP_INT, + WCD938X_IRQ_AUX_SCD_INT, + WCD938X_IRQ_HPHL_PDM_WD_INT, + WCD938X_IRQ_HPHR_PDM_WD_INT, + WCD938X_IRQ_AUX_PDM_WD_INT, + + /* INTR_CTRL_INT_MASK_2 */ + WCD938X_IRQ_LDORT_SCD_INT, + WCD938X_IRQ_MBHC_MOISTURE_INT, + WCD938X_IRQ_HPHL_SURGE_DET_INT, + WCD938X_IRQ_HPHR_SURGE_DET_INT, + WCD938X_NUM_IRQS, +}; + +extern struct wcd938x_mbhc *wcd938x_soc_get_mbhc( + struct snd_soc_component *component); +extern int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component *component, + int volt, int micb_num); +extern int wcd938x_get_micb_vout_ctl_val(u32 micb_mv); +extern int wcd938x_micbias_control(struct snd_soc_component *component, + int micb_num, int req, bool is_dapm); +extern int wcd938x_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_component *component); +#endif /* _WCD938X_INTERNAL_H */ diff --git a/asoc/codecs/wcd938x/wcd938x-mbhc.c b/asoc/codecs/wcd938x/wcd938x-mbhc.c new file mode 100644 index 000000000000..6d9f500378bf --- /dev/null +++ b/asoc/codecs/wcd938x/wcd938x-mbhc.c @@ -0,0 +1,1082 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wcd938x-registers.h" +#include "internal.h" + +#define WCD938X_ZDET_SUPPORTED true +/* Z value defined in milliohm */ +#define WCD938X_ZDET_VAL_32 32000 +#define WCD938X_ZDET_VAL_400 400000 +#define WCD938X_ZDET_VAL_1200 1200000 +#define WCD938X_ZDET_VAL_100K 100000000 +/* Z floating defined in ohms */ +#define WCD938X_ZDET_FLOATING_IMPEDANCE 0x0FFFFFFE + +#define WCD938X_ZDET_NUM_MEASUREMENTS 900 +#define WCD938X_MBHC_GET_C1(c) ((c & 0xC000) >> 14) +#define WCD938X_MBHC_GET_X1(x) (x & 0x3FFF) +/* Z value compared in milliOhm */ +#define WCD938X_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000)) +#define WCD938X_MBHC_ZDET_CONST (86 * 16384) +#define WCD938X_MBHC_MOISTURE_RREF R_24_KOHM + +static struct wcd_mbhc_register + wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = { + WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN", + WCD938X_ANA_MBHC_MECH, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_DET_EN", + WCD938X_ANA_MBHC_MECH, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MECH_DETECTION_TYPE", + WCD938X_ANA_MBHC_MECH, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_CLAMP_CTL", + WCD938X_MBHC_NEW_PLUG_DETECT_CTL, 0x30, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_DETECTION_TYPE", + WCD938X_ANA_MBHC_ELECT, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_CTRL", + WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT, 0x1F, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL", + WCD938X_ANA_MBHC_MECH, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PLUG_TYPE", + WCD938X_ANA_MBHC_MECH, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_PLUG_TYPE", + WCD938X_ANA_MBHC_MECH, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SW_HPH_LP_100K_TO_GND", + WCD938X_ANA_MBHC_MECH, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_SCHMT_ISRC", + WCD938X_ANA_MBHC_ELECT, 0x06, 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_EN", + WCD938X_ANA_MBHC_ELECT, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_INSREM_DBNC", + WCD938X_MBHC_NEW_PLUG_DETECT_CTL, 0x0F, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_DBNC", + WCD938X_MBHC_NEW_CTL_1, 0x03, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_VREF", + WCD938X_MBHC_NEW_CTL_2, 0x03, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT", + WCD938X_ANA_MBHC_RESULT_3, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_IN2P_CLAMP_STATE", + WCD938X_ANA_MBHC_RESULT_3, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT", + WCD938X_ANA_MBHC_RESULT_3, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT", + WCD938X_ANA_MBHC_RESULT_3, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_SCHMT_RESULT", + WCD938X_ANA_MBHC_RESULT_3, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_OCP_FSM_EN", + WCD938X_HPH_OCP_CTL, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_RESULT", + WCD938X_ANA_MBHC_RESULT_3, 0x07, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_ISRC_CTL", + WCD938X_ANA_MBHC_ELECT, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT", + WCD938X_ANA_MBHC_RESULT_3, 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL", + WCD938X_ANA_MICB2, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME", + WCD938X_HPH_CNP_WG_TIME, 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN", + WCD938X_ANA_HPH, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PA_EN", + WCD938X_ANA_HPH, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_PA_EN", + WCD938X_ANA_HPH, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE", + WCD938X_ANA_MBHC_RESULT_3, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL", + 0, 0, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN", + WCD938X_MBHC_CTL_BCS, 0x02, 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_STATUS", + WCD938X_MBHC_NEW_FSM_STATUS, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL", + WCD938X_MBHC_NEW_CTL_2, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MOISTURE_STATUS", + WCD938X_MBHC_NEW_FSM_STATUS, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_GND", + WCD938X_HPH_PA_CTL2, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_GND", + WCD938X_HPH_PA_CTL2, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_DET_EN", + WCD938X_HPH_L_TEST, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_DET_EN", + WCD938X_HPH_R_TEST, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_STATUS", + WCD938X_DIGITAL_INTR_STATUS_0, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_STATUS", + WCD938X_DIGITAL_INTR_STATUS_0, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_EN", + WCD938X_MBHC_NEW_CTL_1, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_COMPLETE", WCD938X_MBHC_NEW_FSM_STATUS, + 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_TIMEOUT", WCD938X_MBHC_NEW_FSM_STATUS, + 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_RESULT", WCD938X_MBHC_NEW_ADC_RESULT, + 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB2_VOUT", WCD938X_ANA_MICB2, 0x3F, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_MODE", + WCD938X_MBHC_NEW_CTL_1, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_DETECTION_DONE", + WCD938X_MBHC_NEW_CTL_1, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_ISRC_EN", + WCD938X_ANA_MBHC_ZDET, 0x02, 1, 0), +}; + +static const struct wcd_mbhc_intr intr_ids = { + .mbhc_sw_intr = WCD938X_IRQ_MBHC_SW_DET, + .mbhc_btn_press_intr = WCD938X_IRQ_MBHC_BUTTON_PRESS_DET, + .mbhc_btn_release_intr = WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET, + .mbhc_hs_ins_intr = WCD938X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, + .mbhc_hs_rem_intr = WCD938X_IRQ_MBHC_ELECT_INS_REM_DET, + .hph_left_ocp = WCD938X_IRQ_HPHL_OCP_INT, + .hph_right_ocp = WCD938X_IRQ_HPHR_OCP_INT, +}; + +struct wcd938x_mbhc_zdet_param { + u16 ldo_ctl; + u16 noff; + u16 nshift; + u16 btn5; + u16 btn6; + u16 btn7; +}; + +static int wcd938x_mbhc_request_irq(struct snd_soc_component *component, + int irq, irq_handler_t handler, + const char *name, void *data) +{ + struct wcd938x_priv *wcd938x = dev_get_drvdata(component->dev); + + return wcd_request_irq(&wcd938x->irq_info, irq, name, handler, data); +} + +static void wcd938x_mbhc_irq_control(struct snd_soc_component *component, + int irq, bool enable) +{ + struct wcd938x_priv *wcd938x = dev_get_drvdata(component->dev); + + if (enable) + wcd_enable_irq(&wcd938x->irq_info, irq); + else + wcd_disable_irq(&wcd938x->irq_info, irq); +} + +static int wcd938x_mbhc_free_irq(struct snd_soc_component *component, + int irq, void *data) +{ + struct wcd938x_priv *wcd938x = dev_get_drvdata(component->dev); + + wcd_free_irq(&wcd938x->irq_info, irq, data); + + return 0; +} + +static void wcd938x_mbhc_clk_setup(struct snd_soc_component *component, + bool enable) +{ + if (enable) + snd_soc_component_update_bits(component, WCD938X_MBHC_NEW_CTL_1, + 0x80, 0x80); + else + snd_soc_component_update_bits(component, WCD938X_MBHC_NEW_CTL_1, + 0x80, 0x00); +} + +static int wcd938x_mbhc_btn_to_num(struct snd_soc_component *component) +{ + return snd_soc_component_read32(component, WCD938X_ANA_MBHC_RESULT_3) & 0x7; +} + +static void wcd938x_mbhc_mbhc_bias_control(struct snd_soc_component *component, + bool enable) +{ + if (enable) + snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_ELECT, + 0x01, 0x01); + else + snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_ELECT, + 0x01, 0x00); +} + +static void wcd938x_mbhc_program_btn_thr(struct snd_soc_component *component, + s16 *btn_low, s16 *btn_high, + int num_btn, bool is_micbias) +{ + int i; + int vth; + + if (num_btn > WCD_MBHC_DEF_BUTTONS) { + dev_err(component->dev, "%s: invalid number of buttons: %d\n", + __func__, num_btn); + return; + } + + for (i = 0; i < num_btn; i++) { + vth = ((btn_high[i] * 2) / 25) & 0x3F; + snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_BTN0 + i, + 0xFC, vth << 2); + dev_dbg(component->dev, "%s: btn_high[%d]: %d, vth: %d\n", + __func__, i, btn_high[i], vth); + } +} + +static bool wcd938x_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock) +{ + return true; +} + +static int wcd938x_mbhc_register_notifier(struct wcd_mbhc *mbhc, + struct notifier_block *nblock, + bool enable) +{ + struct wcd938x_mbhc *wcd938x_mbhc; + + wcd938x_mbhc = container_of(mbhc, struct wcd938x_mbhc, wcd_mbhc); + + if (enable) + return blocking_notifier_chain_register(&wcd938x_mbhc->notifier, + nblock); + else + return blocking_notifier_chain_unregister( + &wcd938x_mbhc->notifier, nblock); +} + +static bool wcd938x_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) +{ + u8 val = 0; + + if (micb_num == MIC_BIAS_2) { + val = ((snd_soc_component_read32(mbhc->component, + WCD938X_ANA_MICB2) & 0xC0) + >> 6); + if (val == 0x01) + return true; + } + return false; +} + +static bool wcd938x_mbhc_hph_pa_on_status(struct snd_soc_component *component) +{ + return (snd_soc_component_read32(component, WCD938X_ANA_HPH) & 0xC0) ? + true : false; +} + +static void wcd938x_mbhc_hph_l_pull_up_control( + struct snd_soc_component *component, + int pull_up_cur) +{ + /* Default pull up current to 2uA */ + if (pull_up_cur > HS_PULLUP_I_OFF || pull_up_cur < HS_PULLUP_I_3P0_UA || + pull_up_cur == HS_PULLUP_I_DEFAULT) + pull_up_cur = HS_PULLUP_I_2P0_UA; + + dev_dbg(component->dev, "%s: HS pull up current:%d\n", + __func__, pull_up_cur); + + snd_soc_component_update_bits(component, + WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT, + 0x1F, pull_up_cur); +} + +static int wcd938x_mbhc_request_micbias(struct snd_soc_component *component, + int micb_num, int req) +{ + int ret = 0; + + ret = wcd938x_micbias_control(component, micb_num, req, false); + + return ret; +} + +static void wcd938x_mbhc_micb_ramp_control(struct snd_soc_component *component, + bool enable) +{ + if (enable) { + snd_soc_component_update_bits(component, WCD938X_ANA_MICB2_RAMP, + 0x1C, 0x0C); + snd_soc_component_update_bits(component, WCD938X_ANA_MICB2_RAMP, + 0x80, 0x80); + } else { + snd_soc_component_update_bits(component, WCD938X_ANA_MICB2_RAMP, + 0x80, 0x00); + snd_soc_component_update_bits(component, WCD938X_ANA_MICB2_RAMP, + 0x1C, 0x00); + } +} + +static struct firmware_cal *wcd938x_get_hwdep_fw_cal(struct wcd_mbhc *mbhc, + enum wcd_cal_type type) +{ + struct wcd938x_mbhc *wcd938x_mbhc; + struct firmware_cal *hwdep_cal; + struct snd_soc_component *component = mbhc->component; + + wcd938x_mbhc = container_of(mbhc, struct wcd938x_mbhc, wcd_mbhc); + + if (!component) { + pr_err("%s: NULL component pointer\n", __func__); + return NULL; + } + hwdep_cal = wcdcal_get_fw_cal(wcd938x_mbhc->fw_data, type); + if (!hwdep_cal) + dev_err(component->dev, "%s: cal not sent by %d\n", + __func__, type); + + return hwdep_cal; +} + +static int wcd938x_mbhc_micb_ctrl_threshold_mic( + struct snd_soc_component *component, + int micb_num, bool req_en) +{ + struct wcd938x_pdata *pdata = dev_get_platdata(component->dev); + int rc, micb_mv; + + if (micb_num != MIC_BIAS_2) + return -EINVAL; + /* + * If device tree micbias level is already above the minimum + * voltage needed to detect threshold microphone, then do + * not change the micbias, just return. + */ + if (pdata->micbias.micb2_mv >= WCD_MBHC_THR_HS_MICB_MV) + return 0; + + micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb2_mv; + + rc = wcd938x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2); + + return rc; +} + +static inline void wcd938x_mbhc_get_result_params(struct wcd938x_priv *wcd938x, + s16 *d1_a, u16 noff, + int32_t *zdet) +{ + int i; + int val, val1; + s16 c1; + s32 x1, d1; + int32_t denom; + int minCode_param[] = { + 3277, 1639, 820, 410, 205, 103, 52, 26 + }; + + regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MBHC_ZDET, 0x20, 0x20); + for (i = 0; i < WCD938X_ZDET_NUM_MEASUREMENTS; i++) { + regmap_read(wcd938x->regmap, WCD938X_ANA_MBHC_RESULT_2, &val); + if (val & 0x80) + break; + } + val = val << 0x8; + regmap_read(wcd938x->regmap, WCD938X_ANA_MBHC_RESULT_1, &val1); + val |= val1; + regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MBHC_ZDET, 0x20, 0x00); + x1 = WCD938X_MBHC_GET_X1(val); + c1 = WCD938X_MBHC_GET_C1(val); + /* If ramp is not complete, give additional 5ms */ + if ((c1 < 2) && x1) + usleep_range(5000, 5050); + + if (!c1 || !x1) { + dev_dbg(wcd938x->dev, + "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n", + __func__, c1, x1); + goto ramp_down; + } + d1 = d1_a[c1]; + denom = (x1 * d1) - (1 << (14 - noff)); + if (denom > 0) + *zdet = (WCD938X_MBHC_ZDET_CONST * 1000) / denom; + else if (x1 < minCode_param[noff]) + *zdet = WCD938X_ZDET_FLOATING_IMPEDANCE; + + dev_dbg(wcd938x->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n", + __func__, d1, c1, x1, *zdet); +ramp_down: + i = 0; + while (x1) { + regmap_read(wcd938x->regmap, + WCD938X_ANA_MBHC_RESULT_1, &val); + regmap_read(wcd938x->regmap, + WCD938X_ANA_MBHC_RESULT_2, &val1); + val = val << 0x08; + val |= val1; + x1 = WCD938X_MBHC_GET_X1(val); + i++; + if (i == WCD938X_ZDET_NUM_MEASUREMENTS) + break; + } +} + +static void wcd938x_mbhc_zdet_ramp(struct snd_soc_component *component, + struct wcd938x_mbhc_zdet_param *zdet_param, + int32_t *zl, int32_t *zr, s16 *d1_a) +{ + struct wcd938x_priv *wcd938x = dev_get_drvdata(component->dev); + int32_t zdet = 0; + + snd_soc_component_update_bits(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL, + 0x70, zdet_param->ldo_ctl << 4); + snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_BTN5, 0xFC, + zdet_param->btn5); + snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_BTN6, 0xFC, + zdet_param->btn6); + snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_BTN7, 0xFC, + zdet_param->btn7); + snd_soc_component_update_bits(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL, + 0x0F, zdet_param->noff); + snd_soc_component_update_bits(component, WCD938X_MBHC_NEW_ZDET_RAMP_CTL, + 0x0F, zdet_param->nshift); + + if (!zl) + goto z_right; + /* Start impedance measurement for HPH_L */ + regmap_update_bits(wcd938x->regmap, + WCD938X_ANA_MBHC_ZDET, 0x80, 0x80); + dev_dbg(wcd938x->dev, "%s: ramp for HPH_L, noff = %d\n", + __func__, zdet_param->noff); + wcd938x_mbhc_get_result_params(wcd938x, d1_a, zdet_param->noff, &zdet); + regmap_update_bits(wcd938x->regmap, + WCD938X_ANA_MBHC_ZDET, 0x80, 0x00); + + *zl = zdet; + +z_right: + if (!zr) + return; + /* Start impedance measurement for HPH_R */ + regmap_update_bits(wcd938x->regmap, + WCD938X_ANA_MBHC_ZDET, 0x40, 0x40); + dev_dbg(wcd938x->dev, "%s: ramp for HPH_R, noff = %d\n", + __func__, zdet_param->noff); + wcd938x_mbhc_get_result_params(wcd938x, d1_a, zdet_param->noff, &zdet); + regmap_update_bits(wcd938x->regmap, + WCD938X_ANA_MBHC_ZDET, 0x40, 0x00); + + *zr = zdet; +} + +static inline void wcd938x_wcd_mbhc_qfuse_cal( + struct snd_soc_component *component, + int32_t *z_val, int flag_l_r) +{ + s16 q1; + int q1_cal; + + if (*z_val < (WCD938X_ZDET_VAL_400/1000)) + q1 = snd_soc_component_read32(component, + WCD938X_DIGITAL_EFUSE_REG_23 + (2 * flag_l_r)); + else + q1 = snd_soc_component_read32(component, + WCD938X_DIGITAL_EFUSE_REG_24 + (2 * flag_l_r)); + if (q1 & 0x80) + q1_cal = (10000 - ((q1 & 0x7F) * 25)); + else + q1_cal = (10000 + (q1 * 25)); + if (q1_cal > 0) + *z_val = ((*z_val) * 10000) / q1_cal; +} + +static void wcd938x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, + uint32_t *zr) +{ + struct snd_soc_component *component = mbhc->component; + struct wcd938x_priv *wcd938x = dev_get_drvdata(component->dev); + s16 reg0, reg1, reg2, reg3, reg4; + int32_t z1L, z1R, z1Ls; + int zMono, z_diff1, z_diff2; + bool is_fsm_disable = false; + struct wcd938x_mbhc_zdet_param zdet_param[] = { + {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */ + {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */ + {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */ + {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */ + }; + struct wcd938x_mbhc_zdet_param *zdet_param_ptr = NULL; + s16 d1_a[][4] = { + {0, 30, 90, 30}, + {0, 30, 30, 5}, + {0, 30, 30, 5}, + {0, 30, 30, 5}, + }; + s16 *d1 = NULL; + + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + + reg0 = snd_soc_component_read32(component, WCD938X_ANA_MBHC_BTN5); + reg1 = snd_soc_component_read32(component, WCD938X_ANA_MBHC_BTN6); + reg2 = snd_soc_component_read32(component, WCD938X_ANA_MBHC_BTN7); + reg3 = snd_soc_component_read32(component, WCD938X_MBHC_CTL_CLK); + reg4 = snd_soc_component_read32(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL); + + if (snd_soc_component_read32(component, WCD938X_ANA_MBHC_ELECT) & 0x80) { + is_fsm_disable = true; + regmap_update_bits(wcd938x->regmap, + WCD938X_ANA_MBHC_ELECT, 0x80, 0x00); + } + + /* For NO-jack, disable L_DET_EN before Z-det measurements */ + if (mbhc->hphl_swh) + regmap_update_bits(wcd938x->regmap, + WCD938X_ANA_MBHC_MECH, 0x80, 0x00); + + /* Turn off 100k pull down on HPHL */ + regmap_update_bits(wcd938x->regmap, + WCD938X_ANA_MBHC_MECH, 0x01, 0x00); + + /* First get impedance on Left */ + d1 = d1_a[1]; + zdet_param_ptr = &zdet_param[1]; + wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1); + + if (!WCD938X_MBHC_IS_SECOND_RAMP_REQUIRED(z1L)) + goto left_ch_impedance; + + /* Second ramp for left ch */ + if (z1L < WCD938X_ZDET_VAL_32) { + zdet_param_ptr = &zdet_param[0]; + d1 = d1_a[0]; + } else if ((z1L > WCD938X_ZDET_VAL_400) && + (z1L <= WCD938X_ZDET_VAL_1200)) { + zdet_param_ptr = &zdet_param[2]; + d1 = d1_a[2]; + } else if (z1L > WCD938X_ZDET_VAL_1200) { + zdet_param_ptr = &zdet_param[3]; + d1 = d1_a[3]; + } + wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1); + +left_ch_impedance: + if ((z1L == WCD938X_ZDET_FLOATING_IMPEDANCE) || + (z1L > WCD938X_ZDET_VAL_100K)) { + *zl = WCD938X_ZDET_FLOATING_IMPEDANCE; + zdet_param_ptr = &zdet_param[1]; + d1 = d1_a[1]; + } else { + *zl = z1L/1000; + wcd938x_wcd_mbhc_qfuse_cal(component, zl, 0); + } + dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n", + __func__, *zl); + + /* Start of right impedance ramp and calculation */ + wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1); + if (WCD938X_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) { + if (((z1R > WCD938X_ZDET_VAL_1200) && + (zdet_param_ptr->noff == 0x6)) || + ((*zl) != WCD938X_ZDET_FLOATING_IMPEDANCE)) + goto right_ch_impedance; + /* Second ramp for right ch */ + if (z1R < WCD938X_ZDET_VAL_32) { + zdet_param_ptr = &zdet_param[0]; + d1 = d1_a[0]; + } else if ((z1R > WCD938X_ZDET_VAL_400) && + (z1R <= WCD938X_ZDET_VAL_1200)) { + zdet_param_ptr = &zdet_param[2]; + d1 = d1_a[2]; + } else if (z1R > WCD938X_ZDET_VAL_1200) { + zdet_param_ptr = &zdet_param[3]; + d1 = d1_a[3]; + } + wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1); + } +right_ch_impedance: + if ((z1R == WCD938X_ZDET_FLOATING_IMPEDANCE) || + (z1R > WCD938X_ZDET_VAL_100K)) { + *zr = WCD938X_ZDET_FLOATING_IMPEDANCE; + } else { + *zr = z1R/1000; + wcd938x_wcd_mbhc_qfuse_cal(component, zr, 1); + } + dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n", + __func__, *zr); + + /* Mono/stereo detection */ + if ((*zl == WCD938X_ZDET_FLOATING_IMPEDANCE) && + (*zr == WCD938X_ZDET_FLOATING_IMPEDANCE)) { + dev_dbg(component->dev, + "%s: plug type is invalid or extension cable\n", + __func__); + goto zdet_complete; + } + if ((*zl == WCD938X_ZDET_FLOATING_IMPEDANCE) || + (*zr == WCD938X_ZDET_FLOATING_IMPEDANCE) || + ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) || + ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) { + dev_dbg(component->dev, + "%s: Mono plug type with one ch floating or shorted to GND\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_MONO; + goto zdet_complete; + } + snd_soc_component_update_bits(component, WCD938X_HPH_R_ATEST, 0x02, 0x02); + snd_soc_component_update_bits(component, WCD938X_HPH_PA_CTL2, 0x40, 0x01); + if (*zl < (WCD938X_ZDET_VAL_32/1000)) + wcd938x_mbhc_zdet_ramp(component, &zdet_param[0], &z1Ls, NULL, d1); + else + wcd938x_mbhc_zdet_ramp(component, &zdet_param[1], &z1Ls, NULL, d1); + snd_soc_component_update_bits(component, WCD938X_HPH_PA_CTL2, 0x40, 0x00); + snd_soc_component_update_bits(component, WCD938X_HPH_R_ATEST, 0x02, 0x00); + z1Ls /= 1000; + wcd938x_wcd_mbhc_qfuse_cal(component, &z1Ls, 0); + /* Parallel of left Z and 9 ohm pull down resistor */ + zMono = ((*zl) * 9) / ((*zl) + 9); + z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls); + z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl)); + if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) { + dev_dbg(component->dev, "%s: stereo plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_STEREO; + } else { + dev_dbg(component->dev, "%s: MONO plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_MONO; + } + +zdet_complete: + snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN5, reg0); + snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN6, reg1); + snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN7, reg2); + /* Turn on 100k pull down on HPHL */ + regmap_update_bits(wcd938x->regmap, + WCD938X_ANA_MBHC_MECH, 0x01, 0x01); + + /* For NO-jack, re-enable L_DET_EN after Z-det measurements */ + if (mbhc->hphl_swh) + regmap_update_bits(wcd938x->regmap, + WCD938X_ANA_MBHC_MECH, 0x80, 0x80); + + snd_soc_component_write(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL, reg4); + snd_soc_component_write(component, WCD938X_MBHC_CTL_CLK, reg3); + if (is_fsm_disable) + regmap_update_bits(wcd938x->regmap, + WCD938X_ANA_MBHC_ELECT, 0x80, 0x80); +} + +static void wcd938x_mbhc_gnd_det_ctrl(struct snd_soc_component *component, + bool enable) +{ + if (enable) { + snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_MECH, + 0x02, 0x02); + snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_MECH, + 0x40, 0x40); + } else { + snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_MECH, + 0x40, 0x00); + snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_MECH, + 0x02, 0x00); + } +} + +static void wcd938x_mbhc_hph_pull_down_ctrl(struct snd_soc_component *component, + bool enable) +{ + if (enable) { + snd_soc_component_update_bits(component, WCD938X_HPH_PA_CTL2, + 0x40, 0x40); + snd_soc_component_update_bits(component, WCD938X_HPH_PA_CTL2, + 0x10, 0x10); + } else { + snd_soc_component_update_bits(component, WCD938X_HPH_PA_CTL2, + 0x40, 0x00); + snd_soc_component_update_bits(component, WCD938X_HPH_PA_CTL2, + 0x10, 0x00); + } +} + +static void wcd938x_mbhc_moisture_config(struct wcd_mbhc *mbhc) +{ + struct snd_soc_component *component = mbhc->component; + + if ((mbhc->moist_rref == R_OFF) || + (mbhc->mbhc_cfg->enable_usbc_analog)) { + snd_soc_component_update_bits(component, WCD938X_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); + return; + } + + /* Do not enable moisture detection if jack type is NC */ + if (!mbhc->hphl_swh) { + dev_dbg(component->dev, "%s: disable moisture detection for NC\n", + __func__); + snd_soc_component_update_bits(component, WCD938X_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); + return; + } + + snd_soc_component_update_bits(component, WCD938X_MBHC_NEW_CTL_2, + 0x0C, mbhc->moist_rref << 2); +} + +static void wcd938x_mbhc_moisture_detect_en(struct wcd_mbhc *mbhc, bool enable) +{ + struct snd_soc_component *component = mbhc->component; + + if (enable) + snd_soc_component_update_bits(component, WCD938X_MBHC_NEW_CTL_2, + 0x0C, mbhc->moist_rref << 2); + else + snd_soc_component_update_bits(component, WCD938X_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); +} + +static bool wcd938x_mbhc_get_moisture_status(struct wcd_mbhc *mbhc) +{ + struct snd_soc_component *component = mbhc->component; + bool ret = false; + + if ((mbhc->moist_rref == R_OFF) || + (mbhc->mbhc_cfg->enable_usbc_analog)) { + snd_soc_component_update_bits(component, WCD938X_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); + goto done; + } + + /* Do not enable moisture detection if jack type is NC */ + if (!mbhc->hphl_swh) { + dev_dbg(component->dev, "%s: disable moisture detection for NC\n", + __func__); + snd_soc_component_update_bits(component, WCD938X_MBHC_NEW_CTL_2, + 0x0C, R_OFF << 2); + goto done; + } + + /* + * If moisture_en is already enabled, then skip to plug type + * detection. + */ + if ((snd_soc_component_read32(component, WCD938X_MBHC_NEW_CTL_2) & 0x0C)) + goto done; + + wcd938x_mbhc_moisture_detect_en(mbhc, true); + /* Read moisture comparator status */ + ret = ((snd_soc_component_read32(component, WCD938X_MBHC_NEW_FSM_STATUS) + & 0x20) ? 0 : 1); + +done: + return ret; + +} + +static void wcd938x_mbhc_moisture_polling_ctrl(struct wcd_mbhc *mbhc, + bool enable) +{ + struct snd_soc_component *component = mbhc->component; + + snd_soc_component_update_bits(component, + WCD938X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL, + 0x04, (enable << 2)); +} + +static const struct wcd_mbhc_cb mbhc_cb = { + .request_irq = wcd938x_mbhc_request_irq, + .irq_control = wcd938x_mbhc_irq_control, + .free_irq = wcd938x_mbhc_free_irq, + .clk_setup = wcd938x_mbhc_clk_setup, + .map_btn_code_to_num = wcd938x_mbhc_btn_to_num, + .mbhc_bias = wcd938x_mbhc_mbhc_bias_control, + .set_btn_thr = wcd938x_mbhc_program_btn_thr, + .lock_sleep = wcd938x_mbhc_lock_sleep, + .register_notifier = wcd938x_mbhc_register_notifier, + .micbias_enable_status = wcd938x_mbhc_micb_en_status, + .hph_pa_on_status = wcd938x_mbhc_hph_pa_on_status, + .hph_pull_up_control_v2 = wcd938x_mbhc_hph_l_pull_up_control, + .mbhc_micbias_control = wcd938x_mbhc_request_micbias, + .mbhc_micb_ramp_control = wcd938x_mbhc_micb_ramp_control, + .get_hwdep_fw_cal = wcd938x_get_hwdep_fw_cal, + .mbhc_micb_ctrl_thr_mic = wcd938x_mbhc_micb_ctrl_threshold_mic, + .compute_impedance = wcd938x_wcd_mbhc_calc_impedance, + .mbhc_gnd_det_ctrl = wcd938x_mbhc_gnd_det_ctrl, + .hph_pull_down_ctrl = wcd938x_mbhc_hph_pull_down_ctrl, + .mbhc_moisture_config = wcd938x_mbhc_moisture_config, + .mbhc_get_moisture_status = wcd938x_mbhc_get_moisture_status, + .mbhc_moisture_polling_ctrl = wcd938x_mbhc_moisture_polling_ctrl, + .mbhc_moisture_detect_en = wcd938x_mbhc_moisture_detect_en, +}; + +static int wcd938x_get_hph_type(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd938x_mbhc *wcd938x_mbhc = wcd938x_soc_get_mbhc(component); + struct wcd_mbhc *mbhc; + + if (!wcd938x_mbhc) { + dev_err(component->dev, "%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + + mbhc = &wcd938x_mbhc->wcd_mbhc; + + ucontrol->value.integer.value[0] = (u32) mbhc->hph_type; + dev_dbg(component->dev, "%s: hph_type = %u\n", __func__, mbhc->hph_type); + + return 0; +} + +static int wcd938x_hph_impedance_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + uint32_t zl, zr; + bool hphr; + struct soc_multi_mixer_control *mc; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd938x_mbhc *wcd938x_mbhc = wcd938x_soc_get_mbhc(component); + + if (!wcd938x_mbhc) { + dev_err(component->dev, "%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + + mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); + hphr = mc->shift; + wcd_mbhc_get_impedance(&wcd938x_mbhc->wcd_mbhc, &zl, &zr); + dev_dbg(component->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr); + ucontrol->value.integer.value[0] = hphr ? zr : zl; + + return 0; +} + +static const struct snd_kcontrol_new hph_type_detect_controls[] = { + SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0, + wcd938x_get_hph_type, NULL), +}; + +static const struct snd_kcontrol_new impedance_detect_controls[] = { + SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0, + wcd938x_hph_impedance_get, NULL), + SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0, + wcd938x_hph_impedance_get, NULL), +}; + +/* + * wcd938x_mbhc_get_impedance: get impedance of headphone + * left and right channels + * @wcd938x_mbhc: handle to struct wcd938x_mbhc * + * @zl: handle to left-ch impedance + * @zr: handle to right-ch impedance + * return 0 for success or error code in case of failure + */ +int wcd938x_mbhc_get_impedance(struct wcd938x_mbhc *wcd938x_mbhc, + uint32_t *zl, uint32_t *zr) +{ + if (!wcd938x_mbhc) { + pr_err("%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + if (!zl || !zr) { + pr_err("%s: zl or zr null!\n", __func__); + return -EINVAL; + } + + return wcd_mbhc_get_impedance(&wcd938x_mbhc->wcd_mbhc, zl, zr); +} +EXPORT_SYMBOL(wcd938x_mbhc_get_impedance); + +/* + * wcd938x_mbhc_hs_detect: starts mbhc insertion/removal functionality + * @codec: handle to snd_soc_component * + * @mbhc_cfg: handle to mbhc configuration structure + * return 0 if mbhc_start is success or error code in case of failure + */ +int wcd938x_mbhc_hs_detect(struct snd_soc_component *component, + struct wcd_mbhc_config *mbhc_cfg) +{ + struct wcd938x_priv *wcd938x = NULL; + struct wcd938x_mbhc *wcd938x_mbhc = NULL; + + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + wcd938x = snd_soc_component_get_drvdata(component); + if (!wcd938x) { + pr_err("%s: wcd938x is NULL\n", __func__); + return -EINVAL; + } + + wcd938x_mbhc = wcd938x->mbhc; + if (!wcd938x_mbhc) { + dev_err(component->dev, "%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + + return wcd_mbhc_start(&wcd938x_mbhc->wcd_mbhc, mbhc_cfg); +} +EXPORT_SYMBOL(wcd938x_mbhc_hs_detect); + +/* + * wcd938x_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality + * @component: handle to snd_soc_component * + */ +void wcd938x_mbhc_hs_detect_exit(struct snd_soc_component *component) +{ + struct wcd938x_priv *wcd938x = NULL; + struct wcd938x_mbhc *wcd938x_mbhc = NULL; + + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return; + } + + wcd938x = snd_soc_component_get_drvdata(component); + if (!wcd938x) { + pr_err("%s: wcd938x is NULL\n", __func__); + return; + } + + wcd938x_mbhc = wcd938x->mbhc; + if (!wcd938x_mbhc) { + dev_err(component->dev, "%s: mbhc not initialized!\n", __func__); + return; + } + wcd_mbhc_stop(&wcd938x_mbhc->wcd_mbhc); +} +EXPORT_SYMBOL(wcd938x_mbhc_hs_detect_exit); + +/* + * wcd938x_mbhc_post_ssr_init: initialize mbhc for + * wcd938x post subsystem restart + * @mbhc: poniter to wcd938x_mbhc structure + * @component: handle to snd_soc_component * + * + * return 0 if mbhc_init is success or error code in case of failure + */ +int wcd938x_mbhc_post_ssr_init(struct wcd938x_mbhc *mbhc, + struct snd_soc_component *component) +{ + int ret = 0; + struct wcd_mbhc *wcd_mbhc = NULL; + + if (!mbhc || !component) + return -EINVAL; + + wcd_mbhc = &mbhc->wcd_mbhc; + if (wcd_mbhc == NULL) { + pr_err("%s: wcd_mbhc is NULL\n", __func__); + return -EINVAL; + } + + wcd_mbhc_deinit(wcd_mbhc); + ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb, &intr_ids, + wcd_mbhc_registers, WCD938X_ZDET_SUPPORTED); + if (ret) { + dev_err(component->dev, "%s: mbhc initialization failed\n", + __func__); + goto done; + } + +done: + return ret; +} +EXPORT_SYMBOL(wcd938x_mbhc_post_ssr_init); + +/* + * wcd938x_mbhc_init: initialize mbhc for wcd938x + * @mbhc: poniter to wcd938x_mbhc struct pointer to store the configs + * @codec: handle to snd_soc_component * + * @fw_data: handle to firmware data + * + * return 0 if mbhc_init is success or error code in case of failure + */ +int wcd938x_mbhc_init(struct wcd938x_mbhc **mbhc, + struct snd_soc_component *component, + struct fw_info *fw_data) +{ + struct wcd938x_mbhc *wcd938x_mbhc = NULL; + struct wcd_mbhc *wcd_mbhc = NULL; + int ret = 0; + + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + wcd938x_mbhc = devm_kzalloc(component->dev, sizeof(struct wcd938x_mbhc), + GFP_KERNEL); + if (!wcd938x_mbhc) + return -ENOMEM; + + wcd938x_mbhc->fw_data = fw_data; + BLOCKING_INIT_NOTIFIER_HEAD(&wcd938x_mbhc->notifier); + wcd_mbhc = &wcd938x_mbhc->wcd_mbhc; + if (wcd_mbhc == NULL) { + pr_err("%s: wcd_mbhc is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + /* Setting default mbhc detection logic to ADC */ + wcd_mbhc->mbhc_detection_logic = WCD_DETECTION_ADC; + + ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb, + &intr_ids, wcd_mbhc_registers, + WCD938X_ZDET_SUPPORTED); + if (ret) { + dev_err(component->dev, "%s: mbhc initialization failed\n", + __func__); + goto err; + } + + (*mbhc) = wcd938x_mbhc; + snd_soc_add_component_controls(component, impedance_detect_controls, + ARRAY_SIZE(impedance_detect_controls)); + snd_soc_add_component_controls(component, hph_type_detect_controls, + ARRAY_SIZE(hph_type_detect_controls)); + + return 0; +err: + devm_kfree(component->dev, wcd938x_mbhc); + return ret; +} +EXPORT_SYMBOL(wcd938x_mbhc_init); + +/* + * wcd938x_mbhc_deinit: deinitialize mbhc for wcd938x + * @codec: handle to snd_soc_component * + */ +void wcd938x_mbhc_deinit(struct snd_soc_component *component) +{ + struct wcd938x_priv *wcd938x; + struct wcd938x_mbhc *wcd938x_mbhc; + + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return; + } + + wcd938x = snd_soc_component_get_drvdata(component); + if (!wcd938x) { + pr_err("%s: wcd938x is NULL\n", __func__); + return; + } + + wcd938x_mbhc = wcd938x->mbhc; + if (wcd938x_mbhc) { + wcd_mbhc_deinit(&wcd938x_mbhc->wcd_mbhc); + devm_kfree(component->dev, wcd938x_mbhc); + } +} +EXPORT_SYMBOL(wcd938x_mbhc_deinit); diff --git a/asoc/codecs/wcd938x/wcd938x-mbhc.h b/asoc/codecs/wcd938x/wcd938x-mbhc.h new file mode 100644 index 000000000000..cf4c60e0ae6d --- /dev/null +++ b/asoc/codecs/wcd938x/wcd938x-mbhc.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ +#ifndef __WCD938X_MBHC_H__ +#define __WCD938X_MBHC_H__ +#include + +struct wcd938x_mbhc { + struct wcd_mbhc wcd_mbhc; + struct blocking_notifier_head notifier; + struct fw_info *fw_data; +}; + +#if IS_ENABLED(CONFIG_SND_SOC_WCD938X) +extern int wcd938x_mbhc_init(struct wcd938x_mbhc **mbhc, + struct snd_soc_component *component, + struct fw_info *fw_data); +extern void wcd938x_mbhc_hs_detect_exit(struct snd_soc_component *component); +extern int wcd938x_mbhc_hs_detect(struct snd_soc_component *component, + struct wcd_mbhc_config *mbhc_cfg); +extern void wcd938x_mbhc_deinit(struct snd_soc_component *component); +extern int wcd938x_mbhc_post_ssr_init(struct wcd938x_mbhc *mbhc, + struct snd_soc_component *component); +extern int wcd938x_mbhc_get_impedance(struct wcd938x_mbhc *wcd938x_mbhc, + uint32_t *zl, uint32_t *zr); +#else +static inline int wcd938x_mbhc_init(struct wcd938x_mbhc **mbhc, + struct snd_soc_component *component, + struct fw_info *fw_data) +{ + return 0; +} +static inline void wcd938x_mbhc_hs_detect_exit( + struct snd_soc_component *component) +{ +} +static inline int wcd938x_mbhc_hs_detect(struct snd_soc_component *component, + struct wcd_mbhc_config *mbhc_cfg) +{ + return 0; +} +static inline void wcd938x_mbhc_deinit(struct snd_soc_component *component) +{ +} +static inline int wcd938x_mbhc_post_ssr_init(struct wcd938x_mbhc *mbhc, + struct snd_soc_component *component) +{ + return 0; +} + +static inline int wcd938x_mbhc_get_impedance(struct wcd938x_mbhc *wcd938x_mbhc, + uint32_t *zl, uint32_t *zr) +{ + if (zl) + *zl = 0; + if (zr) + *zr = 0; + return -EINVAL; +} +#endif + +#endif /* __WCD938X_MBHC_H__ */ diff --git a/asoc/codecs/wcd938x/wcd938x-registers.h b/asoc/codecs/wcd938x/wcd938x-registers.h new file mode 100644 index 000000000000..409c4139fc68 --- /dev/null +++ b/asoc/codecs/wcd938x/wcd938x-registers.h @@ -0,0 +1,502 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _WCD938X_REGISTERS_H +#define _WCD938X_REGISTERS_H + +#define WCD938X_BASE_ADDRESS 0x3000 +#define WCD938X_REG(reg) (reg - WCD938X_BASE_ADDRESS) + +enum { + REG_NO_ACCESS, + RD_REG, + WR_REG, + RD_WR_REG +}; + + +#define WCD938X_ANA_PAGE_REGISTER (WCD938X_BASE_ADDRESS + 0x0000) +#define WCD938X_ANA_BIAS (WCD938X_BASE_ADDRESS + 0x0001) +#define WCD938X_ANA_RX_SUPPLIES (WCD938X_BASE_ADDRESS + 0x0008) +#define WCD938X_ANA_HPH (WCD938X_BASE_ADDRESS + 0x0009) +#define WCD938X_ANA_EAR (WCD938X_BASE_ADDRESS + 0x000A) +#define WCD938X_ANA_EAR_COMPANDER_CTL (WCD938X_BASE_ADDRESS + 0x000B) +#define WCD938X_ANA_TX_CH1 (WCD938X_BASE_ADDRESS + 0x000E) +#define WCD938X_ANA_TX_CH2 (WCD938X_BASE_ADDRESS + 0x000F) +#define WCD938X_ANA_TX_CH3 (WCD938X_BASE_ADDRESS + 0x0010) +#define WCD938X_ANA_TX_CH4 (WCD938X_BASE_ADDRESS + 0x0011) +#define WCD938X_ANA_MICB1_MICB2_DSP_EN_LOGIC (WCD938X_BASE_ADDRESS + 0x0012) +#define WCD938X_ANA_MICB3_DSP_EN_LOGIC (WCD938X_BASE_ADDRESS + 0x0013) +#define WCD938X_ANA_MBHC_MECH (WCD938X_BASE_ADDRESS + 0x0014) +#define WCD938X_ANA_MBHC_ELECT (WCD938X_BASE_ADDRESS + 0x0015) +#define WCD938X_ANA_MBHC_ZDET (WCD938X_BASE_ADDRESS + 0x0016) +#define WCD938X_ANA_MBHC_RESULT_1 (WCD938X_BASE_ADDRESS + 0x0017) +#define WCD938X_ANA_MBHC_RESULT_2 (WCD938X_BASE_ADDRESS + 0x0018) +#define WCD938X_ANA_MBHC_RESULT_3 (WCD938X_BASE_ADDRESS + 0x0019) +#define WCD938X_ANA_MBHC_BTN0 (WCD938X_BASE_ADDRESS + 0x001A) +#define WCD938X_ANA_MBHC_BTN1 (WCD938X_BASE_ADDRESS + 0x001B) +#define WCD938X_ANA_MBHC_BTN2 (WCD938X_BASE_ADDRESS + 0x001C) +#define WCD938X_ANA_MBHC_BTN3 (WCD938X_BASE_ADDRESS + 0x001D) +#define WCD938X_ANA_MBHC_BTN4 (WCD938X_BASE_ADDRESS + 0x001E) +#define WCD938X_ANA_MBHC_BTN5 (WCD938X_BASE_ADDRESS + 0x001F) +#define WCD938X_ANA_MBHC_BTN6 (WCD938X_BASE_ADDRESS + 0x0020) +#define WCD938X_ANA_MBHC_BTN7 (WCD938X_BASE_ADDRESS + 0x0021) +#define WCD938X_ANA_MICB1 (WCD938X_BASE_ADDRESS + 0x0022) +#define WCD938X_ANA_MICB2 (WCD938X_BASE_ADDRESS + 0x0023) +#define WCD938X_ANA_MICB2_RAMP (WCD938X_BASE_ADDRESS + 0x0024) +#define WCD938X_ANA_MICB3 (WCD938X_BASE_ADDRESS + 0x0025) +#define WCD938X_ANA_MICB4 (WCD938X_BASE_ADDRESS + 0x0026) +#define WCD938X_BIAS_CTL (WCD938X_BASE_ADDRESS + 0x0028) +#define WCD938X_BIAS_VBG_FINE_ADJ (WCD938X_BASE_ADDRESS + 0x0029) +#define WCD938X_LDOL_VDDCX_ADJUST (WCD938X_BASE_ADDRESS + 0x0040) +#define WCD938X_LDOL_DISABLE_LDOL (WCD938X_BASE_ADDRESS + 0x0041) +#define WCD938X_MBHC_CTL_CLK (WCD938X_BASE_ADDRESS + 0x0056) +#define WCD938X_MBHC_CTL_ANA (WCD938X_BASE_ADDRESS + 0x0057) +#define WCD938X_MBHC_CTL_SPARE_1 (WCD938X_BASE_ADDRESS + 0x0058) +#define WCD938X_MBHC_CTL_SPARE_2 (WCD938X_BASE_ADDRESS + 0x0059) +#define WCD938X_MBHC_CTL_BCS (WCD938X_BASE_ADDRESS + 0x005A) +#define WCD938X_MBHC_MOISTURE_DET_FSM_STATUS (WCD938X_BASE_ADDRESS + 0x005B) +#define WCD938X_MBHC_TEST_CTL (WCD938X_BASE_ADDRESS + 0x005C) +#define WCD938X_LDOH_MODE (WCD938X_BASE_ADDRESS + 0x0067) +#define WCD938X_LDOH_BIAS (WCD938X_BASE_ADDRESS + 0x0068) +#define WCD938X_LDOH_STB_LOADS (WCD938X_BASE_ADDRESS + 0x0069) +#define WCD938X_LDOH_SLOWRAMP (WCD938X_BASE_ADDRESS + 0x006A) +#define WCD938X_MICB1_TEST_CTL_1 (WCD938X_BASE_ADDRESS + 0x006B) +#define WCD938X_MICB1_TEST_CTL_2 (WCD938X_BASE_ADDRESS + 0x006C) +#define WCD938X_MICB1_TEST_CTL_3 (WCD938X_BASE_ADDRESS + 0x006D) +#define WCD938X_MICB2_TEST_CTL_1 (WCD938X_BASE_ADDRESS + 0x006E) +#define WCD938X_MICB2_TEST_CTL_2 (WCD938X_BASE_ADDRESS + 0x006F) +#define WCD938X_MICB2_TEST_CTL_3 (WCD938X_BASE_ADDRESS + 0x0070) +#define WCD938X_MICB3_TEST_CTL_1 (WCD938X_BASE_ADDRESS + 0x0071) +#define WCD938X_MICB3_TEST_CTL_2 (WCD938X_BASE_ADDRESS + 0x0072) +#define WCD938X_MICB3_TEST_CTL_3 (WCD938X_BASE_ADDRESS + 0x0073) +#define WCD938X_MICB4_TEST_CTL_1 (WCD938X_BASE_ADDRESS + 0x0074) +#define WCD938X_MICB4_TEST_CTL_2 (WCD938X_BASE_ADDRESS + 0x0075) +#define WCD938X_MICB4_TEST_CTL_3 (WCD938X_BASE_ADDRESS + 0x0076) +#define WCD938X_TX_COM_ADC_VCM (WCD938X_BASE_ADDRESS + 0x0077) +#define WCD938X_TX_COM_BIAS_ATEST (WCD938X_BASE_ADDRESS + 0x0078) +#define WCD938X_TX_COM_SPARE1 (WCD938X_BASE_ADDRESS + 0x0079) +#define WCD938X_TX_COM_SPARE2 (WCD938X_BASE_ADDRESS + 0x007A) +#define WCD938X_TX_COM_TXFE_DIV_CTL (WCD938X_BASE_ADDRESS + 0x007B) +#define WCD938X_TX_COM_TXFE_DIV_START (WCD938X_BASE_ADDRESS + 0x007C) +#define WCD938X_TX_COM_SPARE3 (WCD938X_BASE_ADDRESS + 0x007D) +#define WCD938X_TX_COM_SPARE4 (WCD938X_BASE_ADDRESS + 0x007E) +#define WCD938X_TX_1_2_TEST_EN (WCD938X_BASE_ADDRESS + 0x007F) +#define WCD938X_TX_1_2_ADC_IB (WCD938X_BASE_ADDRESS + 0x0080) +#define WCD938X_TX_1_2_ATEST_REFCTL (WCD938X_BASE_ADDRESS + 0x0081) +#define WCD938X_TX_1_2_TEST_CTL (WCD938X_BASE_ADDRESS + 0x0082) +#define WCD938X_TX_1_2_TEST_BLK_EN1 (WCD938X_BASE_ADDRESS + 0x0083) +#define WCD938X_TX_1_2_TXFE1_CLKDIV (WCD938X_BASE_ADDRESS + 0x0084) +#define WCD938X_TX_1_2_SAR2_ERR (WCD938X_BASE_ADDRESS + 0x0085) +#define WCD938X_TX_1_2_SAR1_ERR (WCD938X_BASE_ADDRESS + 0x0086) +#define WCD938X_TX_3_4_TEST_EN (WCD938X_BASE_ADDRESS + 0x0087) +#define WCD938X_TX_3_4_ADC_IB (WCD938X_BASE_ADDRESS + 0x0088) +#define WCD938X_TX_3_4_ATEST_REFCTL (WCD938X_BASE_ADDRESS + 0x0089) +#define WCD938X_TX_3_4_TEST_CTL (WCD938X_BASE_ADDRESS + 0x008A) +#define WCD938X_TX_3_4_TEST_BLK_EN3 (WCD938X_BASE_ADDRESS + 0x008B) +#define WCD938X_TX_3_4_TXFE3_CLKDIV (WCD938X_BASE_ADDRESS + 0x008C) +#define WCD938X_TX_3_4_SAR4_ERR (WCD938X_BASE_ADDRESS + 0x008D) +#define WCD938X_TX_3_4_SAR3_ERR (WCD938X_BASE_ADDRESS + 0x008E) +#define WCD938X_TX_3_4_TEST_BLK_EN2 (WCD938X_BASE_ADDRESS + 0x008F) +#define WCD938X_TX_3_4_TXFE2_CLKDIV (WCD938X_BASE_ADDRESS + 0x0090) +#define WCD938X_TX_3_4_SPARE1 (WCD938X_BASE_ADDRESS + 0x0091) +#define WCD938X_TX_3_4_TEST_BLK_EN4 (WCD938X_BASE_ADDRESS + 0x0092) +#define WCD938X_TX_3_4_TXFE4_CLKDIV (WCD938X_BASE_ADDRESS + 0x0093) +#define WCD938X_TX_3_4_SPARE2 (WCD938X_BASE_ADDRESS + 0x0094) +#define WCD938X_CLASSH_MODE_1 (WCD938X_BASE_ADDRESS + 0x0097) +#define WCD938X_CLASSH_MODE_2 (WCD938X_BASE_ADDRESS + 0x0098) +#define WCD938X_CLASSH_MODE_3 (WCD938X_BASE_ADDRESS + 0x0099) +#define WCD938X_CLASSH_CTRL_VCL_1 (WCD938X_BASE_ADDRESS + 0x009A) +#define WCD938X_CLASSH_CTRL_VCL_2 (WCD938X_BASE_ADDRESS + 0x009B) +#define WCD938X_CLASSH_CTRL_CCL_1 (WCD938X_BASE_ADDRESS + 0x009C) +#define WCD938X_CLASSH_CTRL_CCL_2 (WCD938X_BASE_ADDRESS + 0x009D) +#define WCD938X_CLASSH_CTRL_CCL_3 (WCD938X_BASE_ADDRESS + 0x009E) +#define WCD938X_CLASSH_CTRL_CCL_4 (WCD938X_BASE_ADDRESS + 0x009F) +#define WCD938X_CLASSH_CTRL_CCL_5 (WCD938X_BASE_ADDRESS + 0x00A0) +#define WCD938X_CLASSH_BUCK_TMUX_A_D (WCD938X_BASE_ADDRESS + 0x00A1) +#define WCD938X_CLASSH_BUCK_SW_DRV_CNTL (WCD938X_BASE_ADDRESS + 0x00A2) +#define WCD938X_CLASSH_SPARE (WCD938X_BASE_ADDRESS + 0x00A3) +#define WCD938X_FLYBACK_EN (WCD938X_BASE_ADDRESS + 0x00A4) +#define WCD938X_FLYBACK_VNEG_CTRL_1 (WCD938X_BASE_ADDRESS + 0x00A5) +#define WCD938X_FLYBACK_VNEG_CTRL_2 (WCD938X_BASE_ADDRESS + 0x00A6) +#define WCD938X_FLYBACK_VNEG_CTRL_3 (WCD938X_BASE_ADDRESS + 0x00A7) +#define WCD938X_FLYBACK_VNEG_CTRL_4 (WCD938X_BASE_ADDRESS + 0x00A8) +#define WCD938X_FLYBACK_VNEG_CTRL_5 (WCD938X_BASE_ADDRESS + 0x00A9) +#define WCD938X_FLYBACK_VNEG_CTRL_6 (WCD938X_BASE_ADDRESS + 0x00AA) +#define WCD938X_FLYBACK_VNEG_CTRL_7 (WCD938X_BASE_ADDRESS + 0x00AB) +#define WCD938X_FLYBACK_VNEG_CTRL_8 (WCD938X_BASE_ADDRESS + 0x00AC) +#define WCD938X_FLYBACK_VNEG_CTRL_9 (WCD938X_BASE_ADDRESS + 0x00AD) +#define WCD938X_FLYBACK_VNEGDAC_CTRL_1 (WCD938X_BASE_ADDRESS + 0x00AE) +#define WCD938X_FLYBACK_VNEGDAC_CTRL_2 (WCD938X_BASE_ADDRESS + 0x00AF) +#define WCD938X_FLYBACK_VNEGDAC_CTRL_3 (WCD938X_BASE_ADDRESS + 0x00B0) +#define WCD938X_FLYBACK_CTRL_1 (WCD938X_BASE_ADDRESS + 0x00B1) +#define WCD938X_FLYBACK_TEST_CTL (WCD938X_BASE_ADDRESS + 0x00B2) +#define WCD938X_RX_AUX_SW_CTL (WCD938X_BASE_ADDRESS + 0x00B3) +#define WCD938X_RX_PA_AUX_IN_CONN (WCD938X_BASE_ADDRESS + 0x00B4) +#define WCD938X_RX_TIMER_DIV (WCD938X_BASE_ADDRESS + 0x00B5) +#define WCD938X_RX_OCP_CTL (WCD938X_BASE_ADDRESS + 0x00B6) +#define WCD938X_RX_OCP_COUNT (WCD938X_BASE_ADDRESS + 0x00B7) +#define WCD938X_RX_BIAS_EAR_DAC (WCD938X_BASE_ADDRESS + 0x00B8) +#define WCD938X_RX_BIAS_EAR_AMP (WCD938X_BASE_ADDRESS + 0x00B9) +#define WCD938X_RX_BIAS_HPH_LDO (WCD938X_BASE_ADDRESS + 0x00BA) +#define WCD938X_RX_BIAS_HPH_PA (WCD938X_BASE_ADDRESS + 0x00BB) +#define WCD938X_RX_BIAS_HPH_RDACBUFF_CNP2 (WCD938X_BASE_ADDRESS + 0x00BC) +#define WCD938X_RX_BIAS_HPH_RDAC_LDO (WCD938X_BASE_ADDRESS + 0x00BD) +#define WCD938X_RX_BIAS_HPH_CNP1 (WCD938X_BASE_ADDRESS + 0x00BE) +#define WCD938X_RX_BIAS_HPH_LOWPOWER (WCD938X_BASE_ADDRESS + 0x00BF) +#define WCD938X_RX_BIAS_AUX_DAC (WCD938X_BASE_ADDRESS + 0x00C0) +#define WCD938X_RX_BIAS_AUX_AMP (WCD938X_BASE_ADDRESS + 0x00C1) +#define WCD938X_RX_BIAS_VNEGDAC_BLEEDER (WCD938X_BASE_ADDRESS + 0x00C2) +#define WCD938X_RX_BIAS_MISC (WCD938X_BASE_ADDRESS + 0x00C3) +#define WCD938X_RX_BIAS_BUCK_RST (WCD938X_BASE_ADDRESS + 0x00C4) +#define WCD938X_RX_BIAS_BUCK_VREF_ERRAMP (WCD938X_BASE_ADDRESS + 0x00C5) +#define WCD938X_RX_BIAS_FLYB_ERRAMP (WCD938X_BASE_ADDRESS + 0x00C6) +#define WCD938X_RX_BIAS_FLYB_BUFF (WCD938X_BASE_ADDRESS + 0x00C7) +#define WCD938X_RX_BIAS_FLYB_MID_RST (WCD938X_BASE_ADDRESS + 0x00C8) +#define WCD938X_HPH_L_STATUS (WCD938X_BASE_ADDRESS + 0x00C9) +#define WCD938X_HPH_R_STATUS (WCD938X_BASE_ADDRESS + 0x00CA) +#define WCD938X_HPH_CNP_EN (WCD938X_BASE_ADDRESS + 0x00CB) +#define WCD938X_HPH_CNP_WG_CTL (WCD938X_BASE_ADDRESS + 0x00CC) +#define WCD938X_HPH_CNP_WG_TIME (WCD938X_BASE_ADDRESS + 0x00CD) +#define WCD938X_HPH_OCP_CTL (WCD938X_BASE_ADDRESS + 0x00CE) +#define WCD938X_HPH_AUTO_CHOP (WCD938X_BASE_ADDRESS + 0x00CF) +#define WCD938X_HPH_CHOP_CTL (WCD938X_BASE_ADDRESS + 0x00D0) +#define WCD938X_HPH_PA_CTL1 (WCD938X_BASE_ADDRESS + 0x00D1) +#define WCD938X_HPH_PA_CTL2 (WCD938X_BASE_ADDRESS + 0x00D2) +#define WCD938X_HPH_L_EN (WCD938X_BASE_ADDRESS + 0x00D3) +#define WCD938X_HPH_L_TEST (WCD938X_BASE_ADDRESS + 0x00D4) +#define WCD938X_HPH_L_ATEST (WCD938X_BASE_ADDRESS + 0x00D5) +#define WCD938X_HPH_R_EN (WCD938X_BASE_ADDRESS + 0x00D6) +#define WCD938X_HPH_R_TEST (WCD938X_BASE_ADDRESS + 0x00D7) +#define WCD938X_HPH_R_ATEST (WCD938X_BASE_ADDRESS + 0x00D8) +#define WCD938X_HPH_RDAC_CLK_CTL1 (WCD938X_BASE_ADDRESS + 0x00D9) +#define WCD938X_HPH_RDAC_CLK_CTL2 (WCD938X_BASE_ADDRESS + 0x00DA) +#define WCD938X_HPH_RDAC_LDO_CTL (WCD938X_BASE_ADDRESS + 0x00DB) +#define WCD938X_HPH_RDAC_CHOP_CLK_LP_CTL (WCD938X_BASE_ADDRESS + 0x00DC) +#define WCD938X_HPH_REFBUFF_UHQA_CTL (WCD938X_BASE_ADDRESS + 0x00DD) +#define WCD938X_HPH_REFBUFF_LP_CTL (WCD938X_BASE_ADDRESS + 0x00DE) +#define WCD938X_HPH_L_DAC_CTL (WCD938X_BASE_ADDRESS + 0x00DF) +#define WCD938X_HPH_R_DAC_CTL (WCD938X_BASE_ADDRESS + 0x00E0) +#define WCD938X_HPH_SURGE_HPHLR_SURGE_COMP_SEL (WCD938X_BASE_ADDRESS + 0x00E1) +#define WCD938X_HPH_SURGE_HPHLR_SURGE_EN (WCD938X_BASE_ADDRESS + 0x00E2) +#define WCD938X_HPH_SURGE_HPHLR_SURGE_MISC1 (WCD938X_BASE_ADDRESS + 0x00E3) +#define WCD938X_HPH_SURGE_HPHLR_SURGE_STATUS (WCD938X_BASE_ADDRESS + 0x00E4) +#define WCD938X_EAR_EAR_EN_REG (WCD938X_BASE_ADDRESS + 0x00E9) +#define WCD938X_EAR_EAR_PA_CON (WCD938X_BASE_ADDRESS + 0x00EA) +#define WCD938X_EAR_EAR_SP_CON (WCD938X_BASE_ADDRESS + 0x00EB) +#define WCD938X_EAR_EAR_DAC_CON (WCD938X_BASE_ADDRESS + 0x00EC) +#define WCD938X_EAR_EAR_CNP_FSM_CON (WCD938X_BASE_ADDRESS + 0x00ED) +#define WCD938X_EAR_TEST_CTL (WCD938X_BASE_ADDRESS + 0x00EE) +#define WCD938X_EAR_STATUS_REG_1 (WCD938X_BASE_ADDRESS + 0x00EF) +#define WCD938X_EAR_STATUS_REG_2 (WCD938X_BASE_ADDRESS + 0x00F0) +#define WCD938X_ANA_NEW_PAGE_REGISTER (WCD938X_BASE_ADDRESS + 0x0100) +#define WCD938X_HPH_NEW_ANA_HPH2 (WCD938X_BASE_ADDRESS + 0x0101) +#define WCD938X_HPH_NEW_ANA_HPH3 (WCD938X_BASE_ADDRESS + 0x0102) +#define WCD938X_SLEEP_CTL (WCD938X_BASE_ADDRESS + 0x0103) +#define WCD938X_SLEEP_WATCHDOG_CTL (WCD938X_BASE_ADDRESS + 0x0104) +#define WCD938X_MBHC_NEW_ELECT_REM_CLAMP_CTL (WCD938X_BASE_ADDRESS + 0x011F) +#define WCD938X_MBHC_NEW_CTL_1 (WCD938X_BASE_ADDRESS + 0x0120) +#define WCD938X_MBHC_NEW_CTL_2 (WCD938X_BASE_ADDRESS + 0x0121) +#define WCD938X_MBHC_NEW_PLUG_DETECT_CTL (WCD938X_BASE_ADDRESS + 0x0122) +#define WCD938X_MBHC_NEW_ZDET_ANA_CTL (WCD938X_BASE_ADDRESS + 0x0123) +#define WCD938X_MBHC_NEW_ZDET_RAMP_CTL (WCD938X_BASE_ADDRESS + 0x0124) +#define WCD938X_MBHC_NEW_FSM_STATUS (WCD938X_BASE_ADDRESS + 0x0125) +#define WCD938X_MBHC_NEW_ADC_RESULT (WCD938X_BASE_ADDRESS + 0x0126) +#define WCD938X_TX_NEW_AMIC_MUX_CFG (WCD938X_BASE_ADDRESS + 0x0127) +#define WCD938X_AUX_AUXPA (WCD938X_BASE_ADDRESS + 0x0128) +#define WCD938X_LDORXTX_MODE (WCD938X_BASE_ADDRESS + 0x0129) +#define WCD938X_LDORXTX_CONFIG (WCD938X_BASE_ADDRESS + 0x012A) +#define WCD938X_DIE_CRACK_DIE_CRK_DET_EN (WCD938X_BASE_ADDRESS + 0x012C) +#define WCD938X_DIE_CRACK_DIE_CRK_DET_OUT (WCD938X_BASE_ADDRESS + 0x012D) +#define WCD938X_HPH_NEW_INT_RDAC_GAIN_CTL (WCD938X_BASE_ADDRESS + 0x0132) +#define WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L (WCD938X_BASE_ADDRESS + 0x0133) +#define WCD938X_HPH_NEW_INT_RDAC_VREF_CTL (WCD938X_BASE_ADDRESS + 0x0134) +#define WCD938X_HPH_NEW_INT_RDAC_OVERRIDE_CTL (WCD938X_BASE_ADDRESS + 0x0135) +#define WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R (WCD938X_BASE_ADDRESS + 0x0136) +#define WCD938X_HPH_NEW_INT_PA_MISC1 (WCD938X_BASE_ADDRESS + 0x0137) +#define WCD938X_HPH_NEW_INT_PA_MISC2 (WCD938X_BASE_ADDRESS + 0x0138) +#define WCD938X_HPH_NEW_INT_PA_RDAC_MISC (WCD938X_BASE_ADDRESS + 0x0139) +#define WCD938X_HPH_NEW_INT_HPH_TIMER1 (WCD938X_BASE_ADDRESS + 0x013A) +#define WCD938X_HPH_NEW_INT_HPH_TIMER2 (WCD938X_BASE_ADDRESS + 0x013B) +#define WCD938X_HPH_NEW_INT_HPH_TIMER3 (WCD938X_BASE_ADDRESS + 0x013C) +#define WCD938X_HPH_NEW_INT_HPH_TIMER4 (WCD938X_BASE_ADDRESS + 0x013D) +#define WCD938X_HPH_NEW_INT_PA_RDAC_MISC2 (WCD938X_BASE_ADDRESS + 0x013E) +#define WCD938X_HPH_NEW_INT_PA_RDAC_MISC3 (WCD938X_BASE_ADDRESS + 0x013F) +#define WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L_NEW (WCD938X_BASE_ADDRESS + 0x0140) +#define WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R_NEW (WCD938X_BASE_ADDRESS + 0x0141) +#define WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI (WCD938X_BASE_ADDRESS + 0x0145) +#define WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_ULP (WCD938X_BASE_ADDRESS + 0x0146) +#define WCD938X_RX_NEW_INT_HPH_RDAC_LDO_LP (WCD938X_BASE_ADDRESS + 0x0147) +#define WCD938X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL \ + (WCD938X_BASE_ADDRESS + 0x01AF) +#define WCD938X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL \ + (WCD938X_BASE_ADDRESS + 0x01B0) +#define WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT (WCD938X_BASE_ADDRESS + 0x01B1) +#define WCD938X_MBHC_NEW_INT_SPARE_2 (WCD938X_BASE_ADDRESS + 0x01B2) +#define WCD938X_EAR_INT_NEW_EAR_CHOPPER_CON (WCD938X_BASE_ADDRESS + 0x01B7) +#define WCD938X_EAR_INT_NEW_CNP_VCM_CON1 (WCD938X_BASE_ADDRESS + 0x01B8) +#define WCD938X_EAR_INT_NEW_CNP_VCM_CON2 (WCD938X_BASE_ADDRESS + 0x01B9) +#define WCD938X_EAR_INT_NEW_EAR_DYNAMIC_BIAS (WCD938X_BASE_ADDRESS + 0x01BA) +#define WCD938X_AUX_INT_EN_REG (WCD938X_BASE_ADDRESS + 0x01BD) +#define WCD938X_AUX_INT_PA_CTRL (WCD938X_BASE_ADDRESS + 0x01BE) +#define WCD938X_AUX_INT_SP_CTRL (WCD938X_BASE_ADDRESS + 0x01BF) +#define WCD938X_AUX_INT_DAC_CTRL (WCD938X_BASE_ADDRESS + 0x01C0) +#define WCD938X_AUX_INT_CLK_CTRL (WCD938X_BASE_ADDRESS + 0x01C1) +#define WCD938X_AUX_INT_TEST_CTRL (WCD938X_BASE_ADDRESS + 0x01C2) +#define WCD938X_AUX_INT_STATUS_REG (WCD938X_BASE_ADDRESS + 0x01C3) +#define WCD938X_AUX_INT_MISC (WCD938X_BASE_ADDRESS + 0x01C4) +#define WCD938X_LDORXTX_INT_BIAS (WCD938X_BASE_ADDRESS + 0x01C5) +#define WCD938X_LDORXTX_INT_STB_LOADS_DTEST (WCD938X_BASE_ADDRESS + 0x01C6) +#define WCD938X_LDORXTX_INT_TEST0 (WCD938X_BASE_ADDRESS + 0x01C7) +#define WCD938X_LDORXTX_INT_STARTUP_TIMER (WCD938X_BASE_ADDRESS + 0x01C8) +#define WCD938X_LDORXTX_INT_TEST1 (WCD938X_BASE_ADDRESS + 0x01C9) +#define WCD938X_LDORXTX_INT_STATUS (WCD938X_BASE_ADDRESS + 0x01CA) +#define WCD938X_SLEEP_INT_WATCHDOG_CTL_1 (WCD938X_BASE_ADDRESS + 0x01D0) +#define WCD938X_SLEEP_INT_WATCHDOG_CTL_2 (WCD938X_BASE_ADDRESS + 0x01D1) +#define WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT1 (WCD938X_BASE_ADDRESS + 0x01D3) +#define WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT2 (WCD938X_BASE_ADDRESS + 0x01D4) +#define WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L2 (WCD938X_BASE_ADDRESS + 0x01D5) +#define WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L1 (WCD938X_BASE_ADDRESS + 0x01D6) +#define WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L0 (WCD938X_BASE_ADDRESS + 0x01D7) +#define WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP1P2M \ + (WCD938X_BASE_ADDRESS + 0x01D8) +#define WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP0P6M \ + (WCD938X_BASE_ADDRESS + 0x01D9) +#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L2L1 \ + (WCD938X_BASE_ADDRESS + 0x01DA) +#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L0 \ + (WCD938X_BASE_ADDRESS + 0x01DB) +#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_ULP \ + (WCD938X_BASE_ADDRESS + 0x01DC) +#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L2L1 \ + (WCD938X_BASE_ADDRESS + 0x01DD) +#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L0 \ + (WCD938X_BASE_ADDRESS + 0x01DE) +#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_ULP \ + (WCD938X_BASE_ADDRESS + 0x01DF) +#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_L2L1L0 \ + (WCD938X_BASE_ADDRESS + 0x01E0) +#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_ULP \ + (WCD938X_BASE_ADDRESS + 0x01E1) +#define WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L2L1 \ + (WCD938X_BASE_ADDRESS + 0x01E2) +#define WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L0ULP \ + (WCD938X_BASE_ADDRESS + 0x01E3) +#define WCD938X_TX_COM_NEW_INT_TXADC_INT_L2 (WCD938X_BASE_ADDRESS + 0x01E4) +#define WCD938X_TX_COM_NEW_INT_TXADC_INT_L1 (WCD938X_BASE_ADDRESS + 0x01E5) +#define WCD938X_TX_COM_NEW_INT_TXADC_INT_L0 (WCD938X_BASE_ADDRESS + 0x01E6) +#define WCD938X_TX_COM_NEW_INT_TXADC_INT_ULP (WCD938X_BASE_ADDRESS + 0x01E7) +#define WCD938X_DIGITAL_PAGE_REGISTER (WCD938X_BASE_ADDRESS + 0x0400) +#define WCD938X_DIGITAL_CHIP_ID0 (WCD938X_BASE_ADDRESS + 0x0401) +#define WCD938X_DIGITAL_CHIP_ID1 (WCD938X_BASE_ADDRESS + 0x0402) +#define WCD938X_DIGITAL_CHIP_ID2 (WCD938X_BASE_ADDRESS + 0x0403) +#define WCD938X_DIGITAL_CHIP_ID3 (WCD938X_BASE_ADDRESS + 0x0404) +#define WCD938X_DIGITAL_SWR_TX_CLK_RATE (WCD938X_BASE_ADDRESS + 0x0405) +#define WCD938X_DIGITAL_CDC_RST_CTL (WCD938X_BASE_ADDRESS + 0x0406) +#define WCD938X_DIGITAL_TOP_CLK_CFG (WCD938X_BASE_ADDRESS + 0x0407) +#define WCD938X_DIGITAL_CDC_ANA_CLK_CTL (WCD938X_BASE_ADDRESS + 0x0408) +#define WCD938X_DIGITAL_CDC_DIG_CLK_CTL (WCD938X_BASE_ADDRESS + 0x0409) +#define WCD938X_DIGITAL_SWR_RST_EN (WCD938X_BASE_ADDRESS + 0x040A) +#define WCD938X_DIGITAL_CDC_PATH_MODE (WCD938X_BASE_ADDRESS + 0x040B) +#define WCD938X_DIGITAL_CDC_RX_RST (WCD938X_BASE_ADDRESS + 0x040C) +#define WCD938X_DIGITAL_CDC_RX0_CTL (WCD938X_BASE_ADDRESS + 0x040D) +#define WCD938X_DIGITAL_CDC_RX1_CTL (WCD938X_BASE_ADDRESS + 0x040E) +#define WCD938X_DIGITAL_CDC_RX2_CTL (WCD938X_BASE_ADDRESS + 0x040F) +#define WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1 (WCD938X_BASE_ADDRESS + 0x0410) +#define WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3 (WCD938X_BASE_ADDRESS + 0x0411) +#define WCD938X_DIGITAL_CDC_COMP_CTL_0 (WCD938X_BASE_ADDRESS + 0x0414) +#define WCD938X_DIGITAL_CDC_ANA_TX_CLK_CTL (WCD938X_BASE_ADDRESS + 0x0417) +#define WCD938X_DIGITAL_CDC_HPH_DSM_A1_0 (WCD938X_BASE_ADDRESS + 0x0418) +#define WCD938X_DIGITAL_CDC_HPH_DSM_A1_1 (WCD938X_BASE_ADDRESS + 0x0419) +#define WCD938X_DIGITAL_CDC_HPH_DSM_A2_0 (WCD938X_BASE_ADDRESS + 0x041A) +#define WCD938X_DIGITAL_CDC_HPH_DSM_A2_1 (WCD938X_BASE_ADDRESS + 0x041B) +#define WCD938X_DIGITAL_CDC_HPH_DSM_A3_0 (WCD938X_BASE_ADDRESS + 0x041C) +#define WCD938X_DIGITAL_CDC_HPH_DSM_A3_1 (WCD938X_BASE_ADDRESS + 0x041D) +#define WCD938X_DIGITAL_CDC_HPH_DSM_A4_0 (WCD938X_BASE_ADDRESS + 0x041E) +#define WCD938X_DIGITAL_CDC_HPH_DSM_A4_1 (WCD938X_BASE_ADDRESS + 0x041F) +#define WCD938X_DIGITAL_CDC_HPH_DSM_A5_0 (WCD938X_BASE_ADDRESS + 0x0420) +#define WCD938X_DIGITAL_CDC_HPH_DSM_A5_1 (WCD938X_BASE_ADDRESS + 0x0421) +#define WCD938X_DIGITAL_CDC_HPH_DSM_A6_0 (WCD938X_BASE_ADDRESS + 0x0422) +#define WCD938X_DIGITAL_CDC_HPH_DSM_A7_0 (WCD938X_BASE_ADDRESS + 0x0423) +#define WCD938X_DIGITAL_CDC_HPH_DSM_C_0 (WCD938X_BASE_ADDRESS + 0x0424) +#define WCD938X_DIGITAL_CDC_HPH_DSM_C_1 (WCD938X_BASE_ADDRESS + 0x0425) +#define WCD938X_DIGITAL_CDC_HPH_DSM_C_2 (WCD938X_BASE_ADDRESS + 0x0426) +#define WCD938X_DIGITAL_CDC_HPH_DSM_C_3 (WCD938X_BASE_ADDRESS + 0x0427) +#define WCD938X_DIGITAL_CDC_HPH_DSM_R1 (WCD938X_BASE_ADDRESS + 0x0428) +#define WCD938X_DIGITAL_CDC_HPH_DSM_R2 (WCD938X_BASE_ADDRESS + 0x0429) +#define WCD938X_DIGITAL_CDC_HPH_DSM_R3 (WCD938X_BASE_ADDRESS + 0x042A) +#define WCD938X_DIGITAL_CDC_HPH_DSM_R4 (WCD938X_BASE_ADDRESS + 0x042B) +#define WCD938X_DIGITAL_CDC_HPH_DSM_R5 (WCD938X_BASE_ADDRESS + 0x042C) +#define WCD938X_DIGITAL_CDC_HPH_DSM_R6 (WCD938X_BASE_ADDRESS + 0x042D) +#define WCD938X_DIGITAL_CDC_HPH_DSM_R7 (WCD938X_BASE_ADDRESS + 0x042E) +#define WCD938X_DIGITAL_CDC_AUX_DSM_A1_0 (WCD938X_BASE_ADDRESS + 0x042F) +#define WCD938X_DIGITAL_CDC_AUX_DSM_A1_1 (WCD938X_BASE_ADDRESS + 0x0430) +#define WCD938X_DIGITAL_CDC_AUX_DSM_A2_0 (WCD938X_BASE_ADDRESS + 0x0431) +#define WCD938X_DIGITAL_CDC_AUX_DSM_A2_1 (WCD938X_BASE_ADDRESS + 0x0432) +#define WCD938X_DIGITAL_CDC_AUX_DSM_A3_0 (WCD938X_BASE_ADDRESS + 0x0433) +#define WCD938X_DIGITAL_CDC_AUX_DSM_A3_1 (WCD938X_BASE_ADDRESS + 0x0434) +#define WCD938X_DIGITAL_CDC_AUX_DSM_A4_0 (WCD938X_BASE_ADDRESS + 0x0435) +#define WCD938X_DIGITAL_CDC_AUX_DSM_A4_1 (WCD938X_BASE_ADDRESS + 0x0436) +#define WCD938X_DIGITAL_CDC_AUX_DSM_A5_0 (WCD938X_BASE_ADDRESS + 0x0437) +#define WCD938X_DIGITAL_CDC_AUX_DSM_A5_1 (WCD938X_BASE_ADDRESS + 0x0438) +#define WCD938X_DIGITAL_CDC_AUX_DSM_A6_0 (WCD938X_BASE_ADDRESS + 0x0439) +#define WCD938X_DIGITAL_CDC_AUX_DSM_A7_0 (WCD938X_BASE_ADDRESS + 0x043A) +#define WCD938X_DIGITAL_CDC_AUX_DSM_C_0 (WCD938X_BASE_ADDRESS + 0x043B) +#define WCD938X_DIGITAL_CDC_AUX_DSM_C_1 (WCD938X_BASE_ADDRESS + 0x043C) +#define WCD938X_DIGITAL_CDC_AUX_DSM_C_2 (WCD938X_BASE_ADDRESS + 0x043D) +#define WCD938X_DIGITAL_CDC_AUX_DSM_C_3 (WCD938X_BASE_ADDRESS + 0x043E) +#define WCD938X_DIGITAL_CDC_AUX_DSM_R1 (WCD938X_BASE_ADDRESS + 0x043F) +#define WCD938X_DIGITAL_CDC_AUX_DSM_R2 (WCD938X_BASE_ADDRESS + 0x0440) +#define WCD938X_DIGITAL_CDC_AUX_DSM_R3 (WCD938X_BASE_ADDRESS + 0x0441) +#define WCD938X_DIGITAL_CDC_AUX_DSM_R4 (WCD938X_BASE_ADDRESS + 0x0442) +#define WCD938X_DIGITAL_CDC_AUX_DSM_R5 (WCD938X_BASE_ADDRESS + 0x0443) +#define WCD938X_DIGITAL_CDC_AUX_DSM_R6 (WCD938X_BASE_ADDRESS + 0x0444) +#define WCD938X_DIGITAL_CDC_AUX_DSM_R7 (WCD938X_BASE_ADDRESS + 0x0445) +#define WCD938X_DIGITAL_CDC_HPH_GAIN_RX_0 (WCD938X_BASE_ADDRESS + 0x0446) +#define WCD938X_DIGITAL_CDC_HPH_GAIN_RX_1 (WCD938X_BASE_ADDRESS + 0x0447) +#define WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_0 (WCD938X_BASE_ADDRESS + 0x0448) +#define WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_1 (WCD938X_BASE_ADDRESS + 0x0449) +#define WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_2 (WCD938X_BASE_ADDRESS + 0x044A) +#define WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_0 (WCD938X_BASE_ADDRESS + 0x044B) +#define WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_1 (WCD938X_BASE_ADDRESS + 0x044C) +#define WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_2 (WCD938X_BASE_ADDRESS + 0x044D) +#define WCD938X_DIGITAL_CDC_HPH_GAIN_CTL (WCD938X_BASE_ADDRESS + 0x044E) +#define WCD938X_DIGITAL_CDC_AUX_GAIN_CTL (WCD938X_BASE_ADDRESS + 0x044F) +#define WCD938X_DIGITAL_CDC_EAR_PATH_CTL (WCD938X_BASE_ADDRESS + 0x0450) +#define WCD938X_DIGITAL_CDC_SWR_CLH (WCD938X_BASE_ADDRESS + 0x0451) +#define WCD938X_DIGITAL_SWR_CLH_BYP (WCD938X_BASE_ADDRESS + 0x0452) +#define WCD938X_DIGITAL_CDC_TX0_CTL (WCD938X_BASE_ADDRESS + 0x0453) +#define WCD938X_DIGITAL_CDC_TX1_CTL (WCD938X_BASE_ADDRESS + 0x0454) +#define WCD938X_DIGITAL_CDC_TX2_CTL (WCD938X_BASE_ADDRESS + 0x0455) +#define WCD938X_DIGITAL_CDC_TX_RST (WCD938X_BASE_ADDRESS + 0x0456) +#define WCD938X_DIGITAL_CDC_REQ_CTL (WCD938X_BASE_ADDRESS + 0x0457) +#define WCD938X_DIGITAL_CDC_RST (WCD938X_BASE_ADDRESS + 0x0458) +#define WCD938X_DIGITAL_CDC_AMIC_CTL (WCD938X_BASE_ADDRESS + 0x045A) +#define WCD938X_DIGITAL_CDC_DMIC_CTL (WCD938X_BASE_ADDRESS + 0x045B) +#define WCD938X_DIGITAL_CDC_DMIC1_CTL (WCD938X_BASE_ADDRESS + 0x045C) +#define WCD938X_DIGITAL_CDC_DMIC2_CTL (WCD938X_BASE_ADDRESS + 0x045D) +#define WCD938X_DIGITAL_CDC_DMIC3_CTL (WCD938X_BASE_ADDRESS + 0x045E) +#define WCD938X_DIGITAL_CDC_DMIC4_CTL (WCD938X_BASE_ADDRESS + 0x045F) +#define WCD938X_DIGITAL_EFUSE_PRG_CTL (WCD938X_BASE_ADDRESS + 0x0460) +#define WCD938X_DIGITAL_EFUSE_CTL (WCD938X_BASE_ADDRESS + 0x0461) +#define WCD938X_DIGITAL_CDC_DMIC_RATE_1_2 (WCD938X_BASE_ADDRESS + 0x0462) +#define WCD938X_DIGITAL_CDC_DMIC_RATE_3_4 (WCD938X_BASE_ADDRESS + 0x0463) +#define WCD938X_DIGITAL_PDM_WD_CTL0 (WCD938X_BASE_ADDRESS + 0x0465) +#define WCD938X_DIGITAL_PDM_WD_CTL1 (WCD938X_BASE_ADDRESS + 0x0466) +#define WCD938X_DIGITAL_PDM_WD_CTL2 (WCD938X_BASE_ADDRESS + 0x0467) +#define WCD938X_DIGITAL_INTR_MODE (WCD938X_BASE_ADDRESS + 0x046A) +#define WCD938X_DIGITAL_INTR_MASK_0 (WCD938X_BASE_ADDRESS + 0x046B) +#define WCD938X_DIGITAL_INTR_MASK_1 (WCD938X_BASE_ADDRESS + 0x046C) +#define WCD938X_DIGITAL_INTR_MASK_2 (WCD938X_BASE_ADDRESS + 0x046D) +#define WCD938X_DIGITAL_INTR_STATUS_0 (WCD938X_BASE_ADDRESS + 0x046E) +#define WCD938X_DIGITAL_INTR_STATUS_1 (WCD938X_BASE_ADDRESS + 0x046F) +#define WCD938X_DIGITAL_INTR_STATUS_2 (WCD938X_BASE_ADDRESS + 0x0470) +#define WCD938X_DIGITAL_INTR_CLEAR_0 (WCD938X_BASE_ADDRESS + 0x0471) +#define WCD938X_DIGITAL_INTR_CLEAR_1 (WCD938X_BASE_ADDRESS + 0x0472) +#define WCD938X_DIGITAL_INTR_CLEAR_2 (WCD938X_BASE_ADDRESS + 0x0473) +#define WCD938X_DIGITAL_INTR_LEVEL_0 (WCD938X_BASE_ADDRESS + 0x0474) +#define WCD938X_DIGITAL_INTR_LEVEL_1 (WCD938X_BASE_ADDRESS + 0x0475) +#define WCD938X_DIGITAL_INTR_LEVEL_2 (WCD938X_BASE_ADDRESS + 0x0476) +#define WCD938X_DIGITAL_INTR_SET_0 (WCD938X_BASE_ADDRESS + 0x0477) +#define WCD938X_DIGITAL_INTR_SET_1 (WCD938X_BASE_ADDRESS + 0x0478) +#define WCD938X_DIGITAL_INTR_SET_2 (WCD938X_BASE_ADDRESS + 0x0479) +#define WCD938X_DIGITAL_INTR_TEST_0 (WCD938X_BASE_ADDRESS + 0x047A) +#define WCD938X_DIGITAL_INTR_TEST_1 (WCD938X_BASE_ADDRESS + 0x047B) +#define WCD938X_DIGITAL_INTR_TEST_2 (WCD938X_BASE_ADDRESS + 0x047C) +#define WCD938X_DIGITAL_TX_MODE_DBG_EN (WCD938X_BASE_ADDRESS + 0x047F) +#define WCD938X_DIGITAL_TX_MODE_DBG_0_1 (WCD938X_BASE_ADDRESS + 0x0480) +#define WCD938X_DIGITAL_TX_MODE_DBG_2_3 (WCD938X_BASE_ADDRESS + 0x0481) +#define WCD938X_DIGITAL_LB_IN_SEL_CTL (WCD938X_BASE_ADDRESS + 0x0482) +#define WCD938X_DIGITAL_LOOP_BACK_MODE (WCD938X_BASE_ADDRESS + 0x0483) +#define WCD938X_DIGITAL_SWR_DAC_TEST (WCD938X_BASE_ADDRESS + 0x0484) +#define WCD938X_DIGITAL_SWR_HM_TEST_RX_0 (WCD938X_BASE_ADDRESS + 0x0485) +#define WCD938X_DIGITAL_SWR_HM_TEST_TX_0 (WCD938X_BASE_ADDRESS + 0x0486) +#define WCD938X_DIGITAL_SWR_HM_TEST_RX_1 (WCD938X_BASE_ADDRESS + 0x0487) +#define WCD938X_DIGITAL_SWR_HM_TEST_TX_1 (WCD938X_BASE_ADDRESS + 0x0488) +#define WCD938X_DIGITAL_SWR_HM_TEST_TX_2 (WCD938X_BASE_ADDRESS + 0x0489) +#define WCD938X_DIGITAL_SWR_HM_TEST_0 (WCD938X_BASE_ADDRESS + 0x048A) +#define WCD938X_DIGITAL_SWR_HM_TEST_1 (WCD938X_BASE_ADDRESS + 0x048B) +#define WCD938X_DIGITAL_PAD_CTL_SWR_0 (WCD938X_BASE_ADDRESS + 0x048C) +#define WCD938X_DIGITAL_PAD_CTL_SWR_1 (WCD938X_BASE_ADDRESS + 0x048D) +#define WCD938X_DIGITAL_I2C_CTL (WCD938X_BASE_ADDRESS + 0x048E) +#define WCD938X_DIGITAL_CDC_TX_TANGGU_SW_MODE (WCD938X_BASE_ADDRESS + 0x048F) +#define WCD938X_DIGITAL_EFUSE_TEST_CTL_0 (WCD938X_BASE_ADDRESS + 0x0490) +#define WCD938X_DIGITAL_EFUSE_TEST_CTL_1 (WCD938X_BASE_ADDRESS + 0x0491) +#define WCD938X_DIGITAL_EFUSE_T_DATA_0 (WCD938X_BASE_ADDRESS + 0x0492) +#define WCD938X_DIGITAL_EFUSE_T_DATA_1 (WCD938X_BASE_ADDRESS + 0x0493) +#define WCD938X_DIGITAL_PAD_CTL_PDM_RX0 (WCD938X_BASE_ADDRESS + 0x0494) +#define WCD938X_DIGITAL_PAD_CTL_PDM_RX1 (WCD938X_BASE_ADDRESS + 0x0495) +#define WCD938X_DIGITAL_PAD_CTL_PDM_TX0 (WCD938X_BASE_ADDRESS + 0x0496) +#define WCD938X_DIGITAL_PAD_CTL_PDM_TX1 (WCD938X_BASE_ADDRESS + 0x0497) +#define WCD938X_DIGITAL_PAD_CTL_PDM_TX2 (WCD938X_BASE_ADDRESS + 0x0498) +#define WCD938X_DIGITAL_PAD_INP_DIS_0 (WCD938X_BASE_ADDRESS + 0x0499) +#define WCD938X_DIGITAL_PAD_INP_DIS_1 (WCD938X_BASE_ADDRESS + 0x049A) +#define WCD938X_DIGITAL_DRIVE_STRENGTH_0 (WCD938X_BASE_ADDRESS + 0x049B) +#define WCD938X_DIGITAL_DRIVE_STRENGTH_1 (WCD938X_BASE_ADDRESS + 0x049C) +#define WCD938X_DIGITAL_DRIVE_STRENGTH_2 (WCD938X_BASE_ADDRESS + 0x049D) +#define WCD938X_DIGITAL_RX_DATA_EDGE_CTL (WCD938X_BASE_ADDRESS + 0x049E) +#define WCD938X_DIGITAL_TX_DATA_EDGE_CTL (WCD938X_BASE_ADDRESS + 0x049F) +#define WCD938X_DIGITAL_GPIO_MODE (WCD938X_BASE_ADDRESS + 0x04A0) +#define WCD938X_DIGITAL_PIN_CTL_OE (WCD938X_BASE_ADDRESS + 0x04A1) +#define WCD938X_DIGITAL_PIN_CTL_DATA_0 (WCD938X_BASE_ADDRESS + 0x04A2) +#define WCD938X_DIGITAL_PIN_CTL_DATA_1 (WCD938X_BASE_ADDRESS + 0x04A3) +#define WCD938X_DIGITAL_PIN_STATUS_0 (WCD938X_BASE_ADDRESS + 0x04A4) +#define WCD938X_DIGITAL_PIN_STATUS_1 (WCD938X_BASE_ADDRESS + 0x04A5) +#define WCD938X_DIGITAL_DIG_DEBUG_CTL (WCD938X_BASE_ADDRESS + 0x04A6) +#define WCD938X_DIGITAL_DIG_DEBUG_EN (WCD938X_BASE_ADDRESS + 0x04A7) +#define WCD938X_DIGITAL_ANA_CSR_DBG_ADD (WCD938X_BASE_ADDRESS + 0x04A8) +#define WCD938X_DIGITAL_ANA_CSR_DBG_CTL (WCD938X_BASE_ADDRESS + 0x04A9) +#define WCD938X_DIGITAL_SSP_DBG (WCD938X_BASE_ADDRESS + 0x04AA) +#define WCD938X_DIGITAL_MODE_STATUS_0 (WCD938X_BASE_ADDRESS + 0x04AB) +#define WCD938X_DIGITAL_MODE_STATUS_1 (WCD938X_BASE_ADDRESS + 0x04AC) +#define WCD938X_DIGITAL_SPARE_0 (WCD938X_BASE_ADDRESS + 0x04AD) +#define WCD938X_DIGITAL_SPARE_1 (WCD938X_BASE_ADDRESS + 0x04AE) +#define WCD938X_DIGITAL_SPARE_2 (WCD938X_BASE_ADDRESS + 0x04AF) +#define WCD938X_DIGITAL_EFUSE_REG_0 (WCD938X_BASE_ADDRESS + 0x04B0) +#define WCD938X_DIGITAL_EFUSE_REG_1 (WCD938X_BASE_ADDRESS + 0x04B1) +#define WCD938X_DIGITAL_EFUSE_REG_2 (WCD938X_BASE_ADDRESS + 0x04B2) +#define WCD938X_DIGITAL_EFUSE_REG_3 (WCD938X_BASE_ADDRESS + 0x04B3) +#define WCD938X_DIGITAL_EFUSE_REG_4 (WCD938X_BASE_ADDRESS + 0x04B4) +#define WCD938X_DIGITAL_EFUSE_REG_5 (WCD938X_BASE_ADDRESS + 0x04B5) +#define WCD938X_DIGITAL_EFUSE_REG_6 (WCD938X_BASE_ADDRESS + 0x04B6) +#define WCD938X_DIGITAL_EFUSE_REG_7 (WCD938X_BASE_ADDRESS + 0x04B7) +#define WCD938X_DIGITAL_EFUSE_REG_8 (WCD938X_BASE_ADDRESS + 0x04B8) +#define WCD938X_DIGITAL_EFUSE_REG_9 (WCD938X_BASE_ADDRESS + 0x04B9) +#define WCD938X_DIGITAL_EFUSE_REG_10 (WCD938X_BASE_ADDRESS + 0x04BA) +#define WCD938X_DIGITAL_EFUSE_REG_11 (WCD938X_BASE_ADDRESS + 0x04BB) +#define WCD938X_DIGITAL_EFUSE_REG_12 (WCD938X_BASE_ADDRESS + 0x04BC) +#define WCD938X_DIGITAL_EFUSE_REG_13 (WCD938X_BASE_ADDRESS + 0x04BD) +#define WCD938X_DIGITAL_EFUSE_REG_14 (WCD938X_BASE_ADDRESS + 0x04BE) +#define WCD938X_DIGITAL_EFUSE_REG_15 (WCD938X_BASE_ADDRESS + 0x04BF) +#define WCD938X_DIGITAL_EFUSE_REG_16 (WCD938X_BASE_ADDRESS + 0x04C0) +#define WCD938X_DIGITAL_EFUSE_REG_17 (WCD938X_BASE_ADDRESS + 0x04C1) +#define WCD938X_DIGITAL_EFUSE_REG_18 (WCD938X_BASE_ADDRESS + 0x04C2) +#define WCD938X_DIGITAL_EFUSE_REG_19 (WCD938X_BASE_ADDRESS + 0x04C3) +#define WCD938X_DIGITAL_EFUSE_REG_20 (WCD938X_BASE_ADDRESS + 0x04C4) +#define WCD938X_DIGITAL_EFUSE_REG_21 (WCD938X_BASE_ADDRESS + 0x04C5) +#define WCD938X_DIGITAL_EFUSE_REG_22 (WCD938X_BASE_ADDRESS + 0x04C6) +#define WCD938X_DIGITAL_EFUSE_REG_23 (WCD938X_BASE_ADDRESS + 0x04C7) +#define WCD938X_DIGITAL_EFUSE_REG_24 (WCD938X_BASE_ADDRESS + 0x04C8) +#define WCD938X_DIGITAL_EFUSE_REG_25 (WCD938X_BASE_ADDRESS + 0x04C9) +#define WCD938X_DIGITAL_EFUSE_REG_26 (WCD938X_BASE_ADDRESS + 0x04CA) +#define WCD938X_DIGITAL_EFUSE_REG_27 (WCD938X_BASE_ADDRESS + 0x04CB) +#define WCD938X_DIGITAL_EFUSE_REG_28 (WCD938X_BASE_ADDRESS + 0x04CC) +#define WCD938X_DIGITAL_EFUSE_REG_29 (WCD938X_BASE_ADDRESS + 0x04CD) +#define WCD938X_DIGITAL_EFUSE_REG_30 (WCD938X_BASE_ADDRESS + 0x04CE) +#define WCD938X_DIGITAL_EFUSE_REG_31 (WCD938X_BASE_ADDRESS + 0x04CF) +#define WCD938X_DIGITAL_TX_REQ_FB_CTL_0 (WCD938X_BASE_ADDRESS + 0x04D0) +#define WCD938X_DIGITAL_TX_REQ_FB_CTL_1 (WCD938X_BASE_ADDRESS + 0x04D1) +#define WCD938X_DIGITAL_TX_REQ_FB_CTL_2 (WCD938X_BASE_ADDRESS + 0x04D2) +#define WCD938X_DIGITAL_TX_REQ_FB_CTL_3 (WCD938X_BASE_ADDRESS + 0x04D3) +#define WCD938X_DIGITAL_TX_REQ_FB_CTL_4 (WCD938X_BASE_ADDRESS + 0x04D4) +#define WCD938X_DIGITAL_DEM_BYPASS_DATA0 (WCD938X_BASE_ADDRESS + 0x04D5) +#define WCD938X_DIGITAL_DEM_BYPASS_DATA1 (WCD938X_BASE_ADDRESS + 0x04D6) +#define WCD938X_DIGITAL_DEM_BYPASS_DATA2 (WCD938X_BASE_ADDRESS + 0x04D7) +#define WCD938X_DIGITAL_DEM_BYPASS_DATA3 (WCD938X_BASE_ADDRESS + 0x04D8) + +#define WCD938X_REGISTERS_MAX_SIZE (WCD938X_DIGITAL_DEM_BYPASS_DATA3 + 1) +#define WCD938X_MAX_REGISTER (WCD938X_REGISTERS_MAX_SIZE - 1) + +#endif /*_WCD938X_REGISTERS_H*/ diff --git a/asoc/codecs/wcd938x/wcd938x-regmap.c b/asoc/codecs/wcd938x/wcd938x-regmap.c new file mode 100644 index 000000000000..a06f97532d8d --- /dev/null +++ b/asoc/codecs/wcd938x/wcd938x-regmap.c @@ -0,0 +1,513 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include "wcd938x-registers.h" + +extern const u8 wcd938x_reg_access[WCD938X_REGISTERS_MAX_SIZE]; + +static const struct reg_default wcd938x_defaults[] = { + {WCD938X_ANA_PAGE_REGISTER, 0x00}, + {WCD938X_ANA_BIAS, 0x00}, + {WCD938X_ANA_RX_SUPPLIES, 0x00}, + {WCD938X_ANA_HPH, 0x0C}, + {WCD938X_ANA_EAR, 0x00}, + {WCD938X_ANA_EAR_COMPANDER_CTL, 0x02}, + {WCD938X_ANA_TX_CH1, 0x20}, + {WCD938X_ANA_TX_CH2, 0x00}, + {WCD938X_ANA_TX_CH3, 0x20}, + {WCD938X_ANA_TX_CH4, 0x00}, + {WCD938X_ANA_MICB1_MICB2_DSP_EN_LOGIC, 0x00}, + {WCD938X_ANA_MICB3_DSP_EN_LOGIC, 0x00}, + {WCD938X_ANA_MBHC_MECH, 0x39}, + {WCD938X_ANA_MBHC_ELECT, 0x08}, + {WCD938X_ANA_MBHC_ZDET, 0x00}, + {WCD938X_ANA_MBHC_RESULT_1, 0x00}, + {WCD938X_ANA_MBHC_RESULT_2, 0x00}, + {WCD938X_ANA_MBHC_RESULT_3, 0x00}, + {WCD938X_ANA_MBHC_BTN0, 0x00}, + {WCD938X_ANA_MBHC_BTN1, 0x10}, + {WCD938X_ANA_MBHC_BTN2, 0x20}, + {WCD938X_ANA_MBHC_BTN3, 0x30}, + {WCD938X_ANA_MBHC_BTN4, 0x40}, + {WCD938X_ANA_MBHC_BTN5, 0x50}, + {WCD938X_ANA_MBHC_BTN6, 0x60}, + {WCD938X_ANA_MBHC_BTN7, 0x70}, + {WCD938X_ANA_MICB1, 0x10}, + {WCD938X_ANA_MICB2, 0x10}, + {WCD938X_ANA_MICB2_RAMP, 0x00}, + {WCD938X_ANA_MICB3, 0x10}, + {WCD938X_ANA_MICB4, 0x10}, + {WCD938X_BIAS_CTL, 0x2A}, + {WCD938X_BIAS_VBG_FINE_ADJ, 0x55}, + {WCD938X_LDOL_VDDCX_ADJUST, 0x01}, + {WCD938X_LDOL_DISABLE_LDOL, 0x00}, + {WCD938X_MBHC_CTL_CLK, 0x00}, + {WCD938X_MBHC_CTL_ANA, 0x00}, + {WCD938X_MBHC_CTL_SPARE_1, 0x00}, + {WCD938X_MBHC_CTL_SPARE_2, 0x00}, + {WCD938X_MBHC_CTL_BCS, 0x00}, + {WCD938X_MBHC_MOISTURE_DET_FSM_STATUS, 0x00}, + {WCD938X_MBHC_TEST_CTL, 0x00}, + {WCD938X_LDOH_MODE, 0x2B}, + {WCD938X_LDOH_BIAS, 0x68}, + {WCD938X_LDOH_STB_LOADS, 0x00}, + {WCD938X_LDOH_SLOWRAMP, 0x50}, + {WCD938X_MICB1_TEST_CTL_1, 0x1A}, + {WCD938X_MICB1_TEST_CTL_2, 0x00}, + {WCD938X_MICB1_TEST_CTL_3, 0xA4}, + {WCD938X_MICB2_TEST_CTL_1, 0x1A}, + {WCD938X_MICB2_TEST_CTL_2, 0x00}, + {WCD938X_MICB2_TEST_CTL_3, 0x24}, + {WCD938X_MICB3_TEST_CTL_1, 0x1A}, + {WCD938X_MICB3_TEST_CTL_2, 0x00}, + {WCD938X_MICB3_TEST_CTL_3, 0xA4}, + {WCD938X_MICB4_TEST_CTL_1, 0x1A}, + {WCD938X_MICB4_TEST_CTL_2, 0x00}, + {WCD938X_MICB4_TEST_CTL_3, 0xA4}, + {WCD938X_TX_COM_ADC_VCM, 0x39}, + {WCD938X_TX_COM_BIAS_ATEST, 0xE0}, + {WCD938X_TX_COM_SPARE1, 0x00}, + {WCD938X_TX_COM_SPARE2, 0x00}, + {WCD938X_TX_COM_TXFE_DIV_CTL, 0x22}, + {WCD938X_TX_COM_TXFE_DIV_START, 0x00}, + {WCD938X_TX_COM_SPARE3, 0x00}, + {WCD938X_TX_COM_SPARE4, 0x00}, + {WCD938X_TX_1_2_TEST_EN, 0xCC}, + {WCD938X_TX_1_2_ADC_IB, 0xE9}, + {WCD938X_TX_1_2_ATEST_REFCTL, 0x0A}, + {WCD938X_TX_1_2_TEST_CTL, 0x38}, + {WCD938X_TX_1_2_TEST_BLK_EN1, 0xFF}, + {WCD938X_TX_1_2_TXFE1_CLKDIV, 0x00}, + {WCD938X_TX_1_2_SAR2_ERR, 0x00}, + {WCD938X_TX_1_2_SAR1_ERR, 0x00}, + {WCD938X_TX_3_4_TEST_EN, 0xCC}, + {WCD938X_TX_3_4_ADC_IB, 0xE9}, + {WCD938X_TX_3_4_ATEST_REFCTL, 0x0A}, + {WCD938X_TX_3_4_TEST_CTL, 0x38}, + {WCD938X_TX_3_4_TEST_BLK_EN3, 0xFF}, + {WCD938X_TX_3_4_TXFE3_CLKDIV, 0x00}, + {WCD938X_TX_3_4_SAR4_ERR, 0x00}, + {WCD938X_TX_3_4_SAR3_ERR, 0x00}, + {WCD938X_TX_3_4_TEST_BLK_EN2, 0xFB}, + {WCD938X_TX_3_4_TXFE2_CLKDIV, 0x00}, + {WCD938X_TX_3_4_SPARE1, 0x00}, + {WCD938X_TX_3_4_TEST_BLK_EN4, 0xFB}, + {WCD938X_TX_3_4_TXFE4_CLKDIV, 0x00}, + {WCD938X_TX_3_4_SPARE2, 0x00}, + {WCD938X_CLASSH_MODE_1, 0x40}, + {WCD938X_CLASSH_MODE_2, 0x3A}, + {WCD938X_CLASSH_MODE_3, 0x00}, + {WCD938X_CLASSH_CTRL_VCL_1, 0x70}, + {WCD938X_CLASSH_CTRL_VCL_2, 0x82}, + {WCD938X_CLASSH_CTRL_CCL_1, 0x31}, + {WCD938X_CLASSH_CTRL_CCL_2, 0x80}, + {WCD938X_CLASSH_CTRL_CCL_3, 0x80}, + {WCD938X_CLASSH_CTRL_CCL_4, 0x51}, + {WCD938X_CLASSH_CTRL_CCL_5, 0x00}, + {WCD938X_CLASSH_BUCK_TMUX_A_D, 0x00}, + {WCD938X_CLASSH_BUCK_SW_DRV_CNTL, 0x77}, + {WCD938X_CLASSH_SPARE, 0x00}, + {WCD938X_FLYBACK_EN, 0x4E}, + {WCD938X_FLYBACK_VNEG_CTRL_1, 0x0B}, + {WCD938X_FLYBACK_VNEG_CTRL_2, 0x45}, + {WCD938X_FLYBACK_VNEG_CTRL_3, 0x74}, + {WCD938X_FLYBACK_VNEG_CTRL_4, 0x7F}, + {WCD938X_FLYBACK_VNEG_CTRL_5, 0x83}, + {WCD938X_FLYBACK_VNEG_CTRL_6, 0x98}, + {WCD938X_FLYBACK_VNEG_CTRL_7, 0xA9}, + {WCD938X_FLYBACK_VNEG_CTRL_8, 0x68}, + {WCD938X_FLYBACK_VNEG_CTRL_9, 0x64}, + {WCD938X_FLYBACK_VNEGDAC_CTRL_1, 0xED}, + {WCD938X_FLYBACK_VNEGDAC_CTRL_2, 0xF0}, + {WCD938X_FLYBACK_VNEGDAC_CTRL_3, 0xA6}, + {WCD938X_FLYBACK_CTRL_1, 0x65}, + {WCD938X_FLYBACK_TEST_CTL, 0x00}, + {WCD938X_RX_AUX_SW_CTL, 0x00}, + {WCD938X_RX_PA_AUX_IN_CONN, 0x01}, + {WCD938X_RX_TIMER_DIV, 0x32}, + {WCD938X_RX_OCP_CTL, 0x1F}, + {WCD938X_RX_OCP_COUNT, 0x77}, + {WCD938X_RX_BIAS_EAR_DAC, 0xA0}, + {WCD938X_RX_BIAS_EAR_AMP, 0xAA}, + {WCD938X_RX_BIAS_HPH_LDO, 0xA9}, + {WCD938X_RX_BIAS_HPH_PA, 0xAA}, + {WCD938X_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8A}, + {WCD938X_RX_BIAS_HPH_RDAC_LDO, 0x88}, + {WCD938X_RX_BIAS_HPH_CNP1, 0x82}, + {WCD938X_RX_BIAS_HPH_LOWPOWER, 0x82}, + {WCD938X_RX_BIAS_AUX_DAC, 0xA0}, + {WCD938X_RX_BIAS_AUX_AMP, 0xAA}, + {WCD938X_RX_BIAS_VNEGDAC_BLEEDER, 0x50}, + {WCD938X_RX_BIAS_MISC, 0x00}, + {WCD938X_RX_BIAS_BUCK_RST, 0x08}, + {WCD938X_RX_BIAS_BUCK_VREF_ERRAMP, 0x44}, + {WCD938X_RX_BIAS_FLYB_ERRAMP, 0x40}, + {WCD938X_RX_BIAS_FLYB_BUFF, 0xAA}, + {WCD938X_RX_BIAS_FLYB_MID_RST, 0x14}, + {WCD938X_HPH_L_STATUS, 0x04}, + {WCD938X_HPH_R_STATUS, 0x04}, + {WCD938X_HPH_CNP_EN, 0x80}, + {WCD938X_HPH_CNP_WG_CTL, 0x9A}, + {WCD938X_HPH_CNP_WG_TIME, 0x14}, + {WCD938X_HPH_OCP_CTL, 0x28}, + {WCD938X_HPH_AUTO_CHOP, 0x16}, + {WCD938X_HPH_CHOP_CTL, 0x83}, + {WCD938X_HPH_PA_CTL1, 0x46}, + {WCD938X_HPH_PA_CTL2, 0x50}, + {WCD938X_HPH_L_EN, 0x80}, + {WCD938X_HPH_L_TEST, 0xE0}, + {WCD938X_HPH_L_ATEST, 0x50}, + {WCD938X_HPH_R_EN, 0x80}, + {WCD938X_HPH_R_TEST, 0xE0}, + {WCD938X_HPH_R_ATEST, 0x54}, + {WCD938X_HPH_RDAC_CLK_CTL1, 0x99}, + {WCD938X_HPH_RDAC_CLK_CTL2, 0x9B}, + {WCD938X_HPH_RDAC_LDO_CTL, 0x33}, + {WCD938X_HPH_RDAC_CHOP_CLK_LP_CTL, 0x00}, + {WCD938X_HPH_REFBUFF_UHQA_CTL, 0x68}, + {WCD938X_HPH_REFBUFF_LP_CTL, 0x0E}, + {WCD938X_HPH_L_DAC_CTL, 0x20}, + {WCD938X_HPH_R_DAC_CTL, 0x20}, + {WCD938X_HPH_SURGE_HPHLR_SURGE_COMP_SEL, 0x55}, + {WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0x19}, + {WCD938X_HPH_SURGE_HPHLR_SURGE_MISC1, 0xA0}, + {WCD938X_HPH_SURGE_HPHLR_SURGE_STATUS, 0x00}, + {WCD938X_EAR_EAR_EN_REG, 0x22}, + {WCD938X_EAR_EAR_PA_CON, 0x44}, + {WCD938X_EAR_EAR_SP_CON, 0xDB}, + {WCD938X_EAR_EAR_DAC_CON, 0x80}, + {WCD938X_EAR_EAR_CNP_FSM_CON, 0xB2}, + {WCD938X_EAR_TEST_CTL, 0x00}, + {WCD938X_EAR_STATUS_REG_1, 0x00}, + {WCD938X_EAR_STATUS_REG_2, 0x08}, + {WCD938X_ANA_NEW_PAGE_REGISTER, 0x00}, + {WCD938X_HPH_NEW_ANA_HPH2, 0x00}, + {WCD938X_HPH_NEW_ANA_HPH3, 0x00}, + {WCD938X_SLEEP_CTL, 0x16}, + {WCD938X_SLEEP_WATCHDOG_CTL, 0x00}, + {WCD938X_MBHC_NEW_ELECT_REM_CLAMP_CTL, 0x00}, + {WCD938X_MBHC_NEW_CTL_1, 0x02}, + {WCD938X_MBHC_NEW_CTL_2, 0x05}, + {WCD938X_MBHC_NEW_PLUG_DETECT_CTL, 0xE9}, + {WCD938X_MBHC_NEW_ZDET_ANA_CTL, 0x0F}, + {WCD938X_MBHC_NEW_ZDET_RAMP_CTL, 0x00}, + {WCD938X_MBHC_NEW_FSM_STATUS, 0x00}, + {WCD938X_MBHC_NEW_ADC_RESULT, 0x00}, + {WCD938X_TX_NEW_AMIC_MUX_CFG, 0x00}, + {WCD938X_AUX_AUXPA, 0x00}, + {WCD938X_LDORXTX_MODE, 0x0C}, + {WCD938X_LDORXTX_CONFIG, 0x10}, + {WCD938X_DIE_CRACK_DIE_CRK_DET_EN, 0x00}, + {WCD938X_DIE_CRACK_DIE_CRK_DET_OUT, 0x00}, + {WCD938X_HPH_NEW_INT_RDAC_GAIN_CTL, 0x40}, + {WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x81}, + {WCD938X_HPH_NEW_INT_RDAC_VREF_CTL, 0x10}, + {WCD938X_HPH_NEW_INT_RDAC_OVERRIDE_CTL, 0x00}, + {WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x81}, + {WCD938X_HPH_NEW_INT_PA_MISC1, 0x22}, + {WCD938X_HPH_NEW_INT_PA_MISC2, 0x00}, + {WCD938X_HPH_NEW_INT_PA_RDAC_MISC, 0x00}, + {WCD938X_HPH_NEW_INT_HPH_TIMER1, 0xFE}, + {WCD938X_HPH_NEW_INT_HPH_TIMER2, 0x02}, + {WCD938X_HPH_NEW_INT_HPH_TIMER3, 0x4E}, + {WCD938X_HPH_NEW_INT_HPH_TIMER4, 0x54}, + {WCD938X_HPH_NEW_INT_PA_RDAC_MISC2, 0x00}, + {WCD938X_HPH_NEW_INT_PA_RDAC_MISC3, 0x00}, + {WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L_NEW, 0x90}, + {WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R_NEW, 0x90}, + {WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI, 0x62}, + {WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_ULP, 0x01}, + {WCD938X_RX_NEW_INT_HPH_RDAC_LDO_LP, 0x11}, + {WCD938X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL, 0x57}, + {WCD938X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL, 0x01}, + {WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT, 0x00}, + {WCD938X_MBHC_NEW_INT_SPARE_2, 0x00}, + {WCD938X_EAR_INT_NEW_EAR_CHOPPER_CON, 0xA8}, + {WCD938X_EAR_INT_NEW_CNP_VCM_CON1, 0x42}, + {WCD938X_EAR_INT_NEW_CNP_VCM_CON2, 0x22}, + {WCD938X_EAR_INT_NEW_EAR_DYNAMIC_BIAS, 0x00}, + {WCD938X_AUX_INT_EN_REG, 0x00}, + {WCD938X_AUX_INT_PA_CTRL, 0x06}, + {WCD938X_AUX_INT_SP_CTRL, 0xD2}, + {WCD938X_AUX_INT_DAC_CTRL, 0x80}, + {WCD938X_AUX_INT_CLK_CTRL, 0x50}, + {WCD938X_AUX_INT_TEST_CTRL, 0x00}, + {WCD938X_AUX_INT_STATUS_REG, 0x00}, + {WCD938X_AUX_INT_MISC, 0x00}, + {WCD938X_LDORXTX_INT_BIAS, 0x6E}, + {WCD938X_LDORXTX_INT_STB_LOADS_DTEST, 0x50}, + {WCD938X_LDORXTX_INT_TEST0, 0x1C}, + {WCD938X_LDORXTX_INT_STARTUP_TIMER, 0xFF}, + {WCD938X_LDORXTX_INT_TEST1, 0x1F}, + {WCD938X_LDORXTX_INT_STATUS, 0x00}, + {WCD938X_SLEEP_INT_WATCHDOG_CTL_1, 0x0A}, + {WCD938X_SLEEP_INT_WATCHDOG_CTL_2, 0x0A}, + {WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT1, 0x02}, + {WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT2, 0x60}, + {WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L2, 0xFF}, + {WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L1, 0x7F}, + {WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L0, 0x3F}, + {WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP1P2M, 0x1F}, + {WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP0P6M, 0x0F}, + {WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L2L1, 0xD7}, + {WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L0, 0xC8}, + {WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_ULP, 0xC6}, + {WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L2L1, 0xD5}, + {WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L0, 0xCA}, + {WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_ULP, 0x05}, + {WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_L2L1L0, 0xA5}, + {WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_ULP, 0x13}, + {WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L2L1, 0x88}, + {WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L0ULP, 0x42}, + {WCD938X_TX_COM_NEW_INT_TXADC_INT_L2, 0xFF}, + {WCD938X_TX_COM_NEW_INT_TXADC_INT_L1, 0x64}, + {WCD938X_TX_COM_NEW_INT_TXADC_INT_L0, 0x64}, + {WCD938X_TX_COM_NEW_INT_TXADC_INT_ULP, 0x77}, + {WCD938X_DIGITAL_PAGE_REGISTER, 0x00}, + {WCD938X_DIGITAL_CHIP_ID0, 0x00}, + {WCD938X_DIGITAL_CHIP_ID1, 0x00}, + {WCD938X_DIGITAL_CHIP_ID2, 0x0D}, + {WCD938X_DIGITAL_CHIP_ID3, 0x01}, + {WCD938X_DIGITAL_SWR_TX_CLK_RATE, 0x00}, + {WCD938X_DIGITAL_CDC_RST_CTL, 0x03}, + {WCD938X_DIGITAL_TOP_CLK_CFG, 0x00}, + {WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x00}, + {WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0xF0}, + {WCD938X_DIGITAL_SWR_RST_EN, 0x00}, + {WCD938X_DIGITAL_CDC_PATH_MODE, 0x55}, + {WCD938X_DIGITAL_CDC_RX_RST, 0x00}, + {WCD938X_DIGITAL_CDC_RX0_CTL, 0xFC}, + {WCD938X_DIGITAL_CDC_RX1_CTL, 0xFC}, + {WCD938X_DIGITAL_CDC_RX2_CTL, 0xFC}, + {WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1, 0x00}, + {WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3, 0x00}, + {WCD938X_DIGITAL_CDC_COMP_CTL_0, 0x00}, + {WCD938X_DIGITAL_CDC_ANA_TX_CLK_CTL, 0x1E}, + {WCD938X_DIGITAL_CDC_HPH_DSM_A1_0, 0x00}, + {WCD938X_DIGITAL_CDC_HPH_DSM_A1_1, 0x01}, + {WCD938X_DIGITAL_CDC_HPH_DSM_A2_0, 0x63}, + {WCD938X_DIGITAL_CDC_HPH_DSM_A2_1, 0x04}, + {WCD938X_DIGITAL_CDC_HPH_DSM_A3_0, 0xAC}, + {WCD938X_DIGITAL_CDC_HPH_DSM_A3_1, 0x04}, + {WCD938X_DIGITAL_CDC_HPH_DSM_A4_0, 0x1A}, + {WCD938X_DIGITAL_CDC_HPH_DSM_A4_1, 0x03}, + {WCD938X_DIGITAL_CDC_HPH_DSM_A5_0, 0xBC}, + {WCD938X_DIGITAL_CDC_HPH_DSM_A5_1, 0x02}, + {WCD938X_DIGITAL_CDC_HPH_DSM_A6_0, 0xC7}, + {WCD938X_DIGITAL_CDC_HPH_DSM_A7_0, 0xF8}, + {WCD938X_DIGITAL_CDC_HPH_DSM_C_0, 0x47}, + {WCD938X_DIGITAL_CDC_HPH_DSM_C_1, 0x43}, + {WCD938X_DIGITAL_CDC_HPH_DSM_C_2, 0xB1}, + {WCD938X_DIGITAL_CDC_HPH_DSM_C_3, 0x17}, + {WCD938X_DIGITAL_CDC_HPH_DSM_R1, 0x4D}, + {WCD938X_DIGITAL_CDC_HPH_DSM_R2, 0x29}, + {WCD938X_DIGITAL_CDC_HPH_DSM_R3, 0x34}, + {WCD938X_DIGITAL_CDC_HPH_DSM_R4, 0x59}, + {WCD938X_DIGITAL_CDC_HPH_DSM_R5, 0x66}, + {WCD938X_DIGITAL_CDC_HPH_DSM_R6, 0x87}, + {WCD938X_DIGITAL_CDC_HPH_DSM_R7, 0x64}, + {WCD938X_DIGITAL_CDC_AUX_DSM_A1_0, 0x00}, + {WCD938X_DIGITAL_CDC_AUX_DSM_A1_1, 0x01}, + {WCD938X_DIGITAL_CDC_AUX_DSM_A2_0, 0x96}, + {WCD938X_DIGITAL_CDC_AUX_DSM_A2_1, 0x09}, + {WCD938X_DIGITAL_CDC_AUX_DSM_A3_0, 0xAB}, + {WCD938X_DIGITAL_CDC_AUX_DSM_A3_1, 0x05}, + {WCD938X_DIGITAL_CDC_AUX_DSM_A4_0, 0x1C}, + {WCD938X_DIGITAL_CDC_AUX_DSM_A4_1, 0x02}, + {WCD938X_DIGITAL_CDC_AUX_DSM_A5_0, 0x17}, + {WCD938X_DIGITAL_CDC_AUX_DSM_A5_1, 0x02}, + {WCD938X_DIGITAL_CDC_AUX_DSM_A6_0, 0xAA}, + {WCD938X_DIGITAL_CDC_AUX_DSM_A7_0, 0xE3}, + {WCD938X_DIGITAL_CDC_AUX_DSM_C_0, 0x69}, + {WCD938X_DIGITAL_CDC_AUX_DSM_C_1, 0x54}, + {WCD938X_DIGITAL_CDC_AUX_DSM_C_2, 0x02}, + {WCD938X_DIGITAL_CDC_AUX_DSM_C_3, 0x15}, + {WCD938X_DIGITAL_CDC_AUX_DSM_R1, 0xA4}, + {WCD938X_DIGITAL_CDC_AUX_DSM_R2, 0xB5}, + {WCD938X_DIGITAL_CDC_AUX_DSM_R3, 0x86}, + {WCD938X_DIGITAL_CDC_AUX_DSM_R4, 0x85}, + {WCD938X_DIGITAL_CDC_AUX_DSM_R5, 0xAA}, + {WCD938X_DIGITAL_CDC_AUX_DSM_R6, 0xE2}, + {WCD938X_DIGITAL_CDC_AUX_DSM_R7, 0x62}, + {WCD938X_DIGITAL_CDC_HPH_GAIN_RX_0, 0x55}, + {WCD938X_DIGITAL_CDC_HPH_GAIN_RX_1, 0xA9}, + {WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_0, 0x3D}, + {WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_1, 0x2E}, + {WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_2, 0x01}, + {WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_0, 0x00}, + {WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_1, 0xFC}, + {WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_2, 0x01}, + {WCD938X_DIGITAL_CDC_HPH_GAIN_CTL, 0x00}, + {WCD938X_DIGITAL_CDC_AUX_GAIN_CTL, 0x00}, + {WCD938X_DIGITAL_CDC_EAR_PATH_CTL, 0x00}, + {WCD938X_DIGITAL_CDC_SWR_CLH, 0x00}, + {WCD938X_DIGITAL_SWR_CLH_BYP, 0x00}, + {WCD938X_DIGITAL_CDC_TX0_CTL, 0x68}, + {WCD938X_DIGITAL_CDC_TX1_CTL, 0x68}, + {WCD938X_DIGITAL_CDC_TX2_CTL, 0x68}, + {WCD938X_DIGITAL_CDC_TX_RST, 0x00}, + {WCD938X_DIGITAL_CDC_REQ_CTL, 0x01}, + {WCD938X_DIGITAL_CDC_RST, 0x00}, + {WCD938X_DIGITAL_CDC_AMIC_CTL, 0x0F}, + {WCD938X_DIGITAL_CDC_DMIC_CTL, 0x04}, + {WCD938X_DIGITAL_CDC_DMIC1_CTL, 0x01}, + {WCD938X_DIGITAL_CDC_DMIC2_CTL, 0x01}, + {WCD938X_DIGITAL_CDC_DMIC3_CTL, 0x01}, + {WCD938X_DIGITAL_CDC_DMIC4_CTL, 0x01}, + {WCD938X_DIGITAL_EFUSE_PRG_CTL, 0x00}, + {WCD938X_DIGITAL_EFUSE_CTL, 0x2B}, + {WCD938X_DIGITAL_CDC_DMIC_RATE_1_2, 0x11}, + {WCD938X_DIGITAL_CDC_DMIC_RATE_3_4, 0x11}, + {WCD938X_DIGITAL_PDM_WD_CTL0, 0x00}, + {WCD938X_DIGITAL_PDM_WD_CTL1, 0x00}, + {WCD938X_DIGITAL_PDM_WD_CTL2, 0x00}, + {WCD938X_DIGITAL_INTR_MODE, 0x00}, + {WCD938X_DIGITAL_INTR_MASK_0, 0xFF}, + {WCD938X_DIGITAL_INTR_MASK_1, 0xFF}, + {WCD938X_DIGITAL_INTR_MASK_2, 0x3F}, + {WCD938X_DIGITAL_INTR_STATUS_0, 0x00}, + {WCD938X_DIGITAL_INTR_STATUS_1, 0x00}, + {WCD938X_DIGITAL_INTR_STATUS_2, 0x00}, + {WCD938X_DIGITAL_INTR_CLEAR_0, 0x00}, + {WCD938X_DIGITAL_INTR_CLEAR_1, 0x00}, + {WCD938X_DIGITAL_INTR_CLEAR_2, 0x00}, + {WCD938X_DIGITAL_INTR_LEVEL_0, 0x00}, + {WCD938X_DIGITAL_INTR_LEVEL_1, 0x00}, + {WCD938X_DIGITAL_INTR_LEVEL_2, 0x00}, + {WCD938X_DIGITAL_INTR_SET_0, 0x00}, + {WCD938X_DIGITAL_INTR_SET_1, 0x00}, + {WCD938X_DIGITAL_INTR_SET_2, 0x00}, + {WCD938X_DIGITAL_INTR_TEST_0, 0x00}, + {WCD938X_DIGITAL_INTR_TEST_1, 0x00}, + {WCD938X_DIGITAL_INTR_TEST_2, 0x00}, + {WCD938X_DIGITAL_TX_MODE_DBG_EN, 0x00}, + {WCD938X_DIGITAL_TX_MODE_DBG_0_1, 0x00}, + {WCD938X_DIGITAL_TX_MODE_DBG_2_3, 0x00}, + {WCD938X_DIGITAL_LB_IN_SEL_CTL, 0x00}, + {WCD938X_DIGITAL_LOOP_BACK_MODE, 0x00}, + {WCD938X_DIGITAL_SWR_DAC_TEST, 0x00}, + {WCD938X_DIGITAL_SWR_HM_TEST_RX_0, 0x40}, + {WCD938X_DIGITAL_SWR_HM_TEST_TX_0, 0x40}, + {WCD938X_DIGITAL_SWR_HM_TEST_RX_1, 0x00}, + {WCD938X_DIGITAL_SWR_HM_TEST_TX_1, 0x00}, + {WCD938X_DIGITAL_SWR_HM_TEST_TX_2, 0x00}, + {WCD938X_DIGITAL_SWR_HM_TEST_0, 0x00}, + {WCD938X_DIGITAL_SWR_HM_TEST_1, 0x00}, + {WCD938X_DIGITAL_PAD_CTL_SWR_0, 0x8F}, + {WCD938X_DIGITAL_PAD_CTL_SWR_1, 0x06}, + {WCD938X_DIGITAL_I2C_CTL, 0x00}, + {WCD938X_DIGITAL_CDC_TX_TANGGU_SW_MODE, 0x00}, + {WCD938X_DIGITAL_EFUSE_TEST_CTL_0, 0x00}, + {WCD938X_DIGITAL_EFUSE_TEST_CTL_1, 0x00}, + {WCD938X_DIGITAL_EFUSE_T_DATA_0, 0x00}, + {WCD938X_DIGITAL_EFUSE_T_DATA_1, 0x00}, + {WCD938X_DIGITAL_PAD_CTL_PDM_RX0, 0xF1}, + {WCD938X_DIGITAL_PAD_CTL_PDM_RX1, 0xF1}, + {WCD938X_DIGITAL_PAD_CTL_PDM_TX0, 0xF1}, + {WCD938X_DIGITAL_PAD_CTL_PDM_TX1, 0xF1}, + {WCD938X_DIGITAL_PAD_CTL_PDM_TX2, 0xF1}, + {WCD938X_DIGITAL_PAD_INP_DIS_0, 0x00}, + {WCD938X_DIGITAL_PAD_INP_DIS_1, 0x00}, + {WCD938X_DIGITAL_DRIVE_STRENGTH_0, 0x00}, + {WCD938X_DIGITAL_DRIVE_STRENGTH_1, 0x00}, + {WCD938X_DIGITAL_DRIVE_STRENGTH_2, 0x00}, + {WCD938X_DIGITAL_RX_DATA_EDGE_CTL, 0x1F}, + {WCD938X_DIGITAL_TX_DATA_EDGE_CTL, 0x80}, + {WCD938X_DIGITAL_GPIO_MODE, 0x00}, + {WCD938X_DIGITAL_PIN_CTL_OE, 0x00}, + {WCD938X_DIGITAL_PIN_CTL_DATA_0, 0x00}, + {WCD938X_DIGITAL_PIN_CTL_DATA_1, 0x00}, + {WCD938X_DIGITAL_PIN_STATUS_0, 0x00}, + {WCD938X_DIGITAL_PIN_STATUS_1, 0x00}, + {WCD938X_DIGITAL_DIG_DEBUG_CTL, 0x00}, + {WCD938X_DIGITAL_DIG_DEBUG_EN, 0x00}, + {WCD938X_DIGITAL_ANA_CSR_DBG_ADD, 0x00}, + {WCD938X_DIGITAL_ANA_CSR_DBG_CTL, 0x48}, + {WCD938X_DIGITAL_SSP_DBG, 0x00}, + {WCD938X_DIGITAL_MODE_STATUS_0, 0x00}, + {WCD938X_DIGITAL_MODE_STATUS_1, 0x00}, + {WCD938X_DIGITAL_SPARE_0, 0x00}, + {WCD938X_DIGITAL_SPARE_1, 0x00}, + {WCD938X_DIGITAL_SPARE_2, 0x00}, + {WCD938X_DIGITAL_EFUSE_REG_0, 0x00}, + {WCD938X_DIGITAL_EFUSE_REG_1, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_2, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_3, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_4, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_5, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_6, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_7, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_8, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_9, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_10, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_11, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_12, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_13, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_14, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_15, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_16, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_17, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_18, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_19, 0xFF}, + {WCD938X_DIGITAL_EFUSE_REG_20, 0x0E}, + {WCD938X_DIGITAL_EFUSE_REG_21, 0x00}, + {WCD938X_DIGITAL_EFUSE_REG_22, 0x00}, + {WCD938X_DIGITAL_EFUSE_REG_23, 0xF8}, + {WCD938X_DIGITAL_EFUSE_REG_24, 0x16}, + {WCD938X_DIGITAL_EFUSE_REG_25, 0x00}, + {WCD938X_DIGITAL_EFUSE_REG_26, 0x00}, + {WCD938X_DIGITAL_EFUSE_REG_27, 0x00}, + {WCD938X_DIGITAL_EFUSE_REG_28, 0x00}, + {WCD938X_DIGITAL_EFUSE_REG_29, 0x00}, + {WCD938X_DIGITAL_EFUSE_REG_30, 0x00}, + {WCD938X_DIGITAL_EFUSE_REG_31, 0x00}, + {WCD938X_DIGITAL_TX_REQ_FB_CTL_0, 0x88}, + {WCD938X_DIGITAL_TX_REQ_FB_CTL_1, 0x88}, + {WCD938X_DIGITAL_TX_REQ_FB_CTL_2, 0x88}, + {WCD938X_DIGITAL_TX_REQ_FB_CTL_3, 0x88}, + {WCD938X_DIGITAL_TX_REQ_FB_CTL_4, 0x88}, + {WCD938X_DIGITAL_DEM_BYPASS_DATA0, 0x55}, + {WCD938X_DIGITAL_DEM_BYPASS_DATA1, 0x55}, + {WCD938X_DIGITAL_DEM_BYPASS_DATA2, 0x55}, + {WCD938X_DIGITAL_DEM_BYPASS_DATA3, 0x01}, +}; + +static bool wcd938x_readable_register(struct device *dev, unsigned int reg) +{ + if(reg <= WCD938X_BASE_ADDRESS) + return 0; + return wcd938x_reg_access[WCD938X_REG(reg)] & RD_REG; +} + +static bool wcd938x_writeable_register(struct device *dev, unsigned int reg) +{ + if(reg <= WCD938X_BASE_ADDRESS) + return 0; + return wcd938x_reg_access[WCD938X_REG(reg)] & WR_REG; +} + +static bool wcd938x_volatile_register(struct device *dev, unsigned int reg) +{ + if(reg <= WCD938X_BASE_ADDRESS) + return 0; + return (wcd938x_reg_access[WCD938X_REG(reg)] & RD_REG) + & ~(wcd938x_reg_access[WCD938X_REG(reg)] & WR_REG); +} + +struct regmap_config wcd938x_regmap_config = { + .name = "wcd938x_csr", + .reg_bits = 16, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wcd938x_defaults, + .num_reg_defaults = ARRAY_SIZE(wcd938x_defaults), + .max_register = WCD938X_MAX_REGISTER, + .readable_reg = wcd938x_readable_register, + .writeable_reg = wcd938x_writeable_register, + .volatile_reg = wcd938x_volatile_register, + .can_multi_write = true, +}; diff --git a/asoc/codecs/wcd938x/wcd938x-slave.c b/asoc/codecs/wcd938x/wcd938x-slave.c new file mode 100644 index 000000000000..b7c02306cb99 --- /dev/null +++ b/asoc/codecs/wcd938x/wcd938x-slave.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include + +struct wcd938x_slave_priv { + struct swr_device *swr_slave; +}; + +static int wcd938x_slave_bind(struct device *dev, + struct device *master, void *data) +{ + int ret = 0; + uint8_t devnum = 0; + struct swr_device *pdev = to_swr_device(dev); + + ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum); + if (ret) { + dev_dbg(&pdev->dev, + "%s get devnum %d for dev addr %lx failed\n", + __func__, devnum, pdev->addr); + return ret; + } + pdev->dev_num = devnum; + + return ret; +} + +static void wcd938x_slave_unbind(struct device *dev, + struct device *master, void *data) +{ + struct wcd938x_slave_priv *wcd938x_slave = NULL; + struct swr_device *pdev = to_swr_device(dev); + + wcd938x_slave = swr_get_dev_data(pdev); + if (!wcd938x_slave) { + dev_err(&pdev->dev, "%s: wcd938x_slave is NULL\n", __func__); + return; + } +} + +static const struct swr_device_id wcd938x_swr_id[] = { + {"wcd938x-slave", 0}, + {} +}; + +static const struct of_device_id wcd938x_swr_dt_match[] = { + { + .compatible = "qcom,wcd938x-slave", + }, + {} +}; + +static const struct component_ops wcd938x_slave_comp_ops = { + .bind = wcd938x_slave_bind, + .unbind = wcd938x_slave_unbind, +}; + +static int wcd938x_swr_probe(struct swr_device *pdev) +{ + struct wcd938x_slave_priv *wcd938x_slave = NULL; + + wcd938x_slave = devm_kzalloc(&pdev->dev, + sizeof(struct wcd938x_slave_priv), GFP_KERNEL); + if (!wcd938x_slave) + return -ENOMEM; + + swr_set_dev_data(pdev, wcd938x_slave); + + wcd938x_slave->swr_slave = pdev; + + return component_add(&pdev->dev, &wcd938x_slave_comp_ops); +} + +static int wcd938x_swr_remove(struct swr_device *pdev) +{ + component_del(&pdev->dev, &wcd938x_slave_comp_ops); + swr_set_dev_data(pdev, NULL); + swr_remove_device(pdev); + + return 0; +} + +static struct swr_driver wcd938x_slave_driver = { + .driver = { + .name = "wcd938x-slave", + .owner = THIS_MODULE, + .of_match_table = wcd938x_swr_dt_match, + }, + .probe = wcd938x_swr_probe, + .remove = wcd938x_swr_remove, + .id_table = wcd938x_swr_id, +}; + +static int __init wcd938x_slave_init(void) +{ + return swr_driver_register(&wcd938x_slave_driver); +} + +static void __exit wcd938x_slave_exit(void) +{ + swr_driver_unregister(&wcd938x_slave_driver); +} + +module_init(wcd938x_slave_init); +module_exit(wcd938x_slave_exit); + +MODULE_DESCRIPTION("WCD938X Swr Slave driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/wcd938x/wcd938x-tables.c b/asoc/codecs/wcd938x/wcd938x-tables.c new file mode 100644 index 000000000000..d2f7d61b6d63 --- /dev/null +++ b/asoc/codecs/wcd938x/wcd938x-tables.c @@ -0,0 +1,474 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018 , The Linux Foundation. All rights reserved. + */ + +#include +#include "wcd938x-registers.h" + +const u8 wcd938x_reg_access[WCD938X_REG(WCD938X_REGISTERS_MAX_SIZE)] = { + [WCD938X_REG(WCD938X_ANA_PAGE_REGISTER)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_BIAS)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_RX_SUPPLIES)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_HPH)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_EAR)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_EAR_COMPANDER_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_TX_CH1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_TX_CH2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_TX_CH3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_TX_CH4)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MICB1_MICB2_DSP_EN_LOGIC)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MICB3_DSP_EN_LOGIC)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MBHC_MECH)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MBHC_ELECT)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MBHC_ZDET)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MBHC_RESULT_1)] = RD_REG, + [WCD938X_REG(WCD938X_ANA_MBHC_RESULT_2)] = RD_REG, + [WCD938X_REG(WCD938X_ANA_MBHC_RESULT_3)] = RD_REG, + [WCD938X_REG(WCD938X_ANA_MBHC_BTN0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MBHC_BTN1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MBHC_BTN2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MBHC_BTN3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MBHC_BTN4)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MBHC_BTN5)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MBHC_BTN6)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MBHC_BTN7)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MICB1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MICB2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MICB2_RAMP)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MICB3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_ANA_MICB4)] = RD_WR_REG, + [WCD938X_REG(WCD938X_BIAS_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_BIAS_VBG_FINE_ADJ)] = RD_WR_REG, + [WCD938X_REG(WCD938X_LDOL_VDDCX_ADJUST)] = RD_WR_REG, + [WCD938X_REG(WCD938X_LDOL_DISABLE_LDOL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_CTL_CLK)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_CTL_ANA)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_CTL_SPARE_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_CTL_SPARE_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_CTL_BCS)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_MOISTURE_DET_FSM_STATUS)] = RD_REG, + [WCD938X_REG(WCD938X_MBHC_TEST_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_LDOH_MODE)] = RD_WR_REG, + [WCD938X_REG(WCD938X_LDOH_BIAS)] = RD_WR_REG, + [WCD938X_REG(WCD938X_LDOH_STB_LOADS)] = RD_WR_REG, + [WCD938X_REG(WCD938X_LDOH_SLOWRAMP)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MICB1_TEST_CTL_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MICB1_TEST_CTL_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MICB1_TEST_CTL_3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MICB2_TEST_CTL_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MICB2_TEST_CTL_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MICB2_TEST_CTL_3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MICB3_TEST_CTL_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MICB3_TEST_CTL_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MICB3_TEST_CTL_3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MICB4_TEST_CTL_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MICB4_TEST_CTL_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MICB4_TEST_CTL_3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_ADC_VCM)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_BIAS_ATEST)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_SPARE1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_SPARE2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_TXFE_DIV_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_TXFE_DIV_START)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_SPARE3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_SPARE4)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_1_2_TEST_EN)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_1_2_ADC_IB)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_1_2_ATEST_REFCTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_1_2_TEST_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_1_2_TEST_BLK_EN1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_1_2_TXFE1_CLKDIV)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_1_2_SAR2_ERR)] = RD_REG, + [WCD938X_REG(WCD938X_TX_1_2_SAR1_ERR)] = RD_REG, + [WCD938X_REG(WCD938X_TX_3_4_TEST_EN)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_3_4_ADC_IB)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_3_4_ATEST_REFCTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_3_4_TEST_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_3_4_TEST_BLK_EN3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_3_4_TXFE3_CLKDIV)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_3_4_SAR4_ERR)] = RD_REG, + [WCD938X_REG(WCD938X_TX_3_4_SAR3_ERR)] = RD_REG, + [WCD938X_REG(WCD938X_TX_3_4_TEST_BLK_EN2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_3_4_TXFE2_CLKDIV)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_3_4_SPARE1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_3_4_TEST_BLK_EN4)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_3_4_TXFE4_CLKDIV)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_3_4_SPARE2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_CLASSH_MODE_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_CLASSH_MODE_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_CLASSH_MODE_3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_CLASSH_CTRL_VCL_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_CLASSH_CTRL_VCL_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_CLASSH_CTRL_CCL_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_CLASSH_CTRL_CCL_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_CLASSH_CTRL_CCL_3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_CLASSH_CTRL_CCL_4)] = RD_WR_REG, + [WCD938X_REG(WCD938X_CLASSH_CTRL_CCL_5)] = RD_WR_REG, + [WCD938X_REG(WCD938X_CLASSH_BUCK_TMUX_A_D)] = RD_WR_REG, + [WCD938X_REG(WCD938X_CLASSH_BUCK_SW_DRV_CNTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_CLASSH_SPARE)] = RD_WR_REG, + [WCD938X_REG(WCD938X_FLYBACK_EN)] = RD_WR_REG, + [WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_4)] = RD_WR_REG, + [WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_5)] = RD_WR_REG, + [WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_6)] = RD_WR_REG, + [WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_7)] = RD_WR_REG, + [WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_8)] = RD_WR_REG, + [WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_9)] = RD_WR_REG, + [WCD938X_REG(WCD938X_FLYBACK_VNEGDAC_CTRL_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_FLYBACK_VNEGDAC_CTRL_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_FLYBACK_VNEGDAC_CTRL_3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_FLYBACK_CTRL_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_FLYBACK_TEST_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_AUX_SW_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_PA_AUX_IN_CONN)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_TIMER_DIV)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_OCP_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_OCP_COUNT)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_EAR_DAC)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_EAR_AMP)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_HPH_LDO)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_HPH_PA)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_HPH_RDACBUFF_CNP2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_HPH_RDAC_LDO)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_HPH_CNP1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_HPH_LOWPOWER)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_AUX_DAC)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_AUX_AMP)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_VNEGDAC_BLEEDER)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_MISC)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_BUCK_RST)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_BUCK_VREF_ERRAMP)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_FLYB_ERRAMP)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_FLYB_BUFF)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_BIAS_FLYB_MID_RST)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_L_STATUS)] = RD_REG, + [WCD938X_REG(WCD938X_HPH_R_STATUS)] = RD_REG, + [WCD938X_REG(WCD938X_HPH_CNP_EN)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_CNP_WG_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_CNP_WG_TIME)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_OCP_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_AUTO_CHOP)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_CHOP_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_PA_CTL1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_PA_CTL2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_L_EN)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_L_TEST)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_L_ATEST)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_R_EN)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_R_TEST)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_R_ATEST)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_RDAC_CLK_CTL1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_RDAC_CLK_CTL2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_RDAC_LDO_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_RDAC_CHOP_CLK_LP_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_REFBUFF_UHQA_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_REFBUFF_LP_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_L_DAC_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_R_DAC_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_SURGE_HPHLR_SURGE_COMP_SEL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_SURGE_HPHLR_SURGE_EN)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_SURGE_HPHLR_SURGE_MISC1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_SURGE_HPHLR_SURGE_STATUS)] = RD_REG, + [WCD938X_REG(WCD938X_EAR_EAR_EN_REG)] = RD_WR_REG, + [WCD938X_REG(WCD938X_EAR_EAR_PA_CON)] = RD_WR_REG, + [WCD938X_REG(WCD938X_EAR_EAR_SP_CON)] = RD_WR_REG, + [WCD938X_REG(WCD938X_EAR_EAR_DAC_CON)] = RD_WR_REG, + [WCD938X_REG(WCD938X_EAR_EAR_CNP_FSM_CON)] = RD_WR_REG, + [WCD938X_REG(WCD938X_EAR_TEST_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_EAR_STATUS_REG_1)] = RD_REG, + [WCD938X_REG(WCD938X_EAR_STATUS_REG_2)] = RD_REG, + [WCD938X_REG(WCD938X_ANA_NEW_PAGE_REGISTER)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_ANA_HPH2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_ANA_HPH3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_SLEEP_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_SLEEP_WATCHDOG_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_NEW_ELECT_REM_CLAMP_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_NEW_CTL_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_NEW_CTL_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_NEW_PLUG_DETECT_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_NEW_ZDET_ANA_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_NEW_ZDET_RAMP_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_NEW_FSM_STATUS)] = RD_REG, + [WCD938X_REG(WCD938X_MBHC_NEW_ADC_RESULT)] = RD_REG, + [WCD938X_REG(WCD938X_TX_NEW_AMIC_MUX_CFG)] = RD_WR_REG, + [WCD938X_REG(WCD938X_AUX_AUXPA)] = RD_WR_REG, + [WCD938X_REG(WCD938X_LDORXTX_MODE)] = RD_WR_REG, + [WCD938X_REG(WCD938X_LDORXTX_CONFIG)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIE_CRACK_DIE_CRK_DET_EN)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIE_CRACK_DIE_CRK_DET_OUT)] = RD_REG, + [WCD938X_REG(WCD938X_HPH_NEW_INT_RDAC_GAIN_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_INT_RDAC_VREF_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_INT_RDAC_OVERRIDE_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_INT_PA_MISC1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_INT_PA_MISC2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_INT_PA_RDAC_MISC)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_INT_HPH_TIMER1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_INT_HPH_TIMER2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_INT_HPH_TIMER3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_INT_HPH_TIMER4)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_INT_PA_RDAC_MISC2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_INT_PA_RDAC_MISC3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L_NEW)] = RD_WR_REG, + [WCD938X_REG(WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R_NEW)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_ULP)] = RD_WR_REG, + [WCD938X_REG(WCD938X_RX_NEW_INT_HPH_RDAC_LDO_LP)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT)] = RD_WR_REG, + [WCD938X_REG(WCD938X_MBHC_NEW_INT_SPARE_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_EAR_INT_NEW_EAR_CHOPPER_CON)] = RD_WR_REG, + [WCD938X_REG(WCD938X_EAR_INT_NEW_CNP_VCM_CON1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_EAR_INT_NEW_CNP_VCM_CON2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_EAR_INT_NEW_EAR_DYNAMIC_BIAS)] = RD_WR_REG, + [WCD938X_REG(WCD938X_AUX_INT_EN_REG)] = RD_WR_REG, + [WCD938X_REG(WCD938X_AUX_INT_PA_CTRL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_AUX_INT_SP_CTRL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_AUX_INT_DAC_CTRL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_AUX_INT_CLK_CTRL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_AUX_INT_TEST_CTRL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_AUX_INT_STATUS_REG)] = RD_REG, + [WCD938X_REG(WCD938X_AUX_INT_MISC)] = RD_WR_REG, + [WCD938X_REG(WCD938X_LDORXTX_INT_BIAS)] = RD_WR_REG, + [WCD938X_REG(WCD938X_LDORXTX_INT_STB_LOADS_DTEST)] = RD_WR_REG, + [WCD938X_REG(WCD938X_LDORXTX_INT_TEST0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_LDORXTX_INT_STARTUP_TIMER)] = RD_WR_REG, + [WCD938X_REG(WCD938X_LDORXTX_INT_TEST1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_LDORXTX_INT_STATUS)] = RD_REG, + [WCD938X_REG(WCD938X_SLEEP_INT_WATCHDOG_CTL_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_SLEEP_INT_WATCHDOG_CTL_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP1P2M)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP0P6M)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L2L1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_ULP)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L2L1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_ULP)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_L2L1L0)]=RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_ULP)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L2L1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L0ULP)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXADC_INT_L2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXADC_INT_L1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXADC_INT_L0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXADC_INT_ULP)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_PAGE_REGISTER)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CHIP_ID0)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_CHIP_ID1)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_CHIP_ID2)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_CHIP_ID3)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_SWR_TX_CLK_RATE)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_RST_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_TOP_CLK_CFG)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_ANA_CLK_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_DIG_CLK_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_SWR_RST_EN)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_PATH_MODE)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_RX_RST)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_RX0_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_RX1_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_RX2_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_COMP_CTL_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_ANA_TX_CLK_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A1_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A1_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A2_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A2_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A3_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A3_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A4_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A4_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A5_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A5_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A6_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A7_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_C_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_C_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_C_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_C_3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_R1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_R2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_R3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_R4)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_R5)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_R6)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_R7)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A1_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A1_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A2_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A2_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A3_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A3_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A4_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A4_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A5_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A5_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A6_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A7_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_C_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_C_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_C_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_C_3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_R1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_R2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_R3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_R4)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_R5)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_R6)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_R7)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_GAIN_RX_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_GAIN_RX_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_GAIN_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_GAIN_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_EAR_PATH_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_SWR_CLH)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_SWR_CLH_BYP)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_TX0_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_TX1_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_TX2_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_TX_RST)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_REQ_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_RST)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_AMIC_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_DMIC_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_DMIC1_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_DMIC2_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_DMIC3_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_DMIC4_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_PRG_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_DMIC_RATE_1_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_DMIC_RATE_3_4)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_PDM_WD_CTL0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_PDM_WD_CTL1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_PDM_WD_CTL2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_MODE)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_MASK_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_MASK_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_MASK_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_STATUS_0)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_STATUS_1)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_STATUS_2)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_CLEAR_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_CLEAR_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_CLEAR_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_LEVEL_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_LEVEL_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_LEVEL_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_SET_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_SET_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_SET_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_TEST_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_TEST_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_INTR_TEST_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_TX_MODE_DBG_EN)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_TX_MODE_DBG_0_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_TX_MODE_DBG_2_3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_LB_IN_SEL_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_LOOP_BACK_MODE)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_SWR_DAC_TEST)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_SWR_HM_TEST_RX_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_SWR_HM_TEST_TX_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_SWR_HM_TEST_RX_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_SWR_HM_TEST_TX_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_SWR_HM_TEST_TX_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_SWR_HM_TEST_0)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_SWR_HM_TEST_1)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_PAD_CTL_SWR_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_PAD_CTL_SWR_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_I2C_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_CDC_TX_TANGGU_SW_MODE)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_TEST_CTL_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_TEST_CTL_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_T_DATA_0)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_T_DATA_1)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_PAD_CTL_PDM_RX0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_PAD_CTL_PDM_RX1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_PAD_CTL_PDM_TX0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_PAD_CTL_PDM_TX1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_PAD_CTL_PDM_TX2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_PAD_INP_DIS_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_PAD_INP_DIS_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_DRIVE_STRENGTH_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_DRIVE_STRENGTH_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_DRIVE_STRENGTH_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_RX_DATA_EDGE_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_TX_DATA_EDGE_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_GPIO_MODE)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_PIN_CTL_OE)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_PIN_CTL_DATA_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_PIN_CTL_DATA_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_PIN_STATUS_0)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_PIN_STATUS_1)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_DIG_DEBUG_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_DIG_DEBUG_EN)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_ANA_CSR_DBG_ADD)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_ANA_CSR_DBG_CTL)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_SSP_DBG)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_MODE_STATUS_0)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_MODE_STATUS_1)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_SPARE_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_SPARE_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_SPARE_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_0)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_1)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_2)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_3)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_4)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_5)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_6)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_7)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_8)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_9)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_10)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_11)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_12)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_13)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_14)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_15)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_16)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_17)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_18)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_19)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_20)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_21)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_22)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_23)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_24)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_25)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_26)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_27)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_28)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_29)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_30)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_31)] = RD_REG, + [WCD938X_REG(WCD938X_DIGITAL_TX_REQ_FB_CTL_0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_TX_REQ_FB_CTL_1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_TX_REQ_FB_CTL_2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_TX_REQ_FB_CTL_3)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_TX_REQ_FB_CTL_4)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_DEM_BYPASS_DATA0)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_DEM_BYPASS_DATA1)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_DEM_BYPASS_DATA2)] = RD_WR_REG, + [WCD938X_REG(WCD938X_DIGITAL_DEM_BYPASS_DATA3)] = RD_WR_REG, +}; diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c new file mode 100644 index 000000000000..2905c59e19bc --- /dev/null +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -0,0 +1,2704 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "wcd938x-registers.h" + +#define WCD938X_DRV_NAME "wcd938x_codec" +#define NUM_SWRS_DT_PARAMS 5 + +#define WCD938X_VERSION_1_0 1 +#define WCD938X_VERSION_ENTRY_SIZE 32 + +enum { + WCD9380 = 0, + WCD9385, + WCD9385FX, +}; + +enum { + CODEC_TX = 0, + CODEC_RX, +}; + +enum { + ALLOW_BUCK_DISABLE, + HPH_COMP_DELAY, + HPH_PA_DELAY, +}; + +static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); +static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); + +static int wcd938x_handle_post_irq(void *data); +static int wcd938x_reset(struct device *dev); +static int wcd938x_reset_low(struct device *dev); + +static const struct regmap_irq wcd938x_irqs[WCD938X_NUM_IRQS] = { + REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x01), + REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET, 0, 0x02), + REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_ELECT_INS_REM_DET, 0, 0x04), + REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, 0, 0x08), + REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_SW_DET, 0, 0x10), + REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_OCP_INT, 0, 0x20), + REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_CNP_INT, 0, 0x40), + REGMAP_IRQ_REG(WCD938X_IRQ_HPHL_OCP_INT, 0, 0x80), + REGMAP_IRQ_REG(WCD938X_IRQ_HPHL_CNP_INT, 1, 0x01), + REGMAP_IRQ_REG(WCD938X_IRQ_EAR_CNP_INT, 1, 0x02), + REGMAP_IRQ_REG(WCD938X_IRQ_EAR_SCD_INT, 1, 0x04), + REGMAP_IRQ_REG(WCD938X_IRQ_AUX_CNP_INT, 1, 0x08), + REGMAP_IRQ_REG(WCD938X_IRQ_AUX_SCD_INT, 1, 0x10), + REGMAP_IRQ_REG(WCD938X_IRQ_HPHL_PDM_WD_INT, 1, 0x20), + REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_PDM_WD_INT, 1, 0x40), + REGMAP_IRQ_REG(WCD938X_IRQ_AUX_PDM_WD_INT, 1, 0x80), + REGMAP_IRQ_REG(WCD938X_IRQ_LDORT_SCD_INT, 2, 0x01), + REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_MOISTURE_INT, 2, 0x02), + REGMAP_IRQ_REG(WCD938X_IRQ_HPHL_SURGE_DET_INT, 2, 0x04), + REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_SURGE_DET_INT, 2, 0x08), +}; + +static struct regmap_irq_chip wcd938x_regmap_irq_chip = { + .name = "wcd938x", + .irqs = wcd938x_irqs, + .num_irqs = ARRAY_SIZE(wcd938x_irqs), + .num_regs = 3, + .status_base = WCD938X_DIGITAL_INTR_STATUS_0, + .mask_base = WCD938X_DIGITAL_INTR_MASK_0, + .type_base = WCD938X_DIGITAL_INTR_LEVEL_0, + .ack_base = WCD938X_DIGITAL_INTR_CLEAR_0, + .use_ack = 1, + .clear_ack = 1, + .runtime_pm = true, + .handle_post_irq = wcd938x_handle_post_irq, + .irq_drv_data = NULL, +}; + +static int wcd938x_handle_post_irq(void *data) +{ + struct wcd938x_priv *wcd938x = data; + u32 sts1 = 0, sts2 = 0, sts3 = 0; + + regmap_read(wcd938x->regmap, WCD938X_DIGITAL_INTR_STATUS_0, &sts1); + regmap_read(wcd938x->regmap, WCD938X_DIGITAL_INTR_STATUS_1, &sts2); + regmap_read(wcd938x->regmap, WCD938X_DIGITAL_INTR_STATUS_2, &sts3); + + wcd938x->tx_swr_dev->slave_irq_pending = + ((sts1 || sts2 || sts3) ? true : false); + + return IRQ_HANDLED; +} + +static int wcd938x_init_reg(struct snd_soc_component *component) +{ + snd_soc_component_update_bits(component, WCD938X_SLEEP_CTL, 0x0E, 0x0E); + snd_soc_component_update_bits(component, WCD938X_SLEEP_CTL, 0x80, 0x80); + /* 1 msec delay as per HW requirement */ + usleep_range(1000, 1010); + snd_soc_component_update_bits(component, WCD938X_SLEEP_CTL, 0x40, 0x40); + /* 1 msec delay as per HW requirement */ + usleep_range(1000, 1010); + snd_soc_component_update_bits(component, WCD938X_LDORXTX_CONFIG, + 0x10, 0x00); + snd_soc_component_update_bits(component, WCD938X_BIAS_VBG_FINE_ADJ, + 0xF0, 0x80); + snd_soc_component_update_bits(component, WCD938X_ANA_BIAS, 0x80, 0x80); + snd_soc_component_update_bits(component, WCD938X_ANA_BIAS, 0x40, 0x40); + /* 10 msec delay as per HW requirement */ + usleep_range(10000, 10010); + snd_soc_component_update_bits(component, WCD938X_ANA_BIAS, 0x40, 0x00); + snd_soc_component_update_bits(component, WCD938X_HPH_OCP_CTL, + 0xFF, 0x3A); + snd_soc_component_update_bits(component, WCD938X_RX_OCP_CTL, + 0x0F, 0x02); + snd_soc_component_update_bits(component, WCD938X_HPH_R_TEST, + 0x01, 0x01); + snd_soc_component_update_bits(component, WCD938X_HPH_L_TEST, + 0x01, 0x01); + + return 0; +} + +static int wcd938x_set_port_params(struct snd_soc_component *component, + u8 slv_prt_type, u8 *port_id, u8 *num_ch, + u8 *ch_mask, u32 *ch_rate, + u8 *port_type, u8 path) +{ + int i, j; + u8 num_ports; + struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT]; + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + switch (path) { + case CODEC_RX: + map = &wcd938x->rx_port_mapping; + num_ports = wcd938x->num_rx_ports; + break; + case CODEC_TX: + map = &wcd938x->tx_port_mapping; + num_ports = wcd938x->num_tx_ports; + break; + } + + for (i = 0; i <= num_ports; i++) { + for (j = 0; j < MAX_CH_PER_PORT; j++) { + if ((*map)[i][j].port_type == slv_prt_type) + goto found; + } + } +found: + if (i > num_ports || j == MAX_CH_PER_PORT) { + dev_err(component->dev, "%s Failed to find slave port for type %u\n", + __func__, slv_prt_type); + return -EINVAL; + } + *port_id = i; + *num_ch = (*map)[i][j].num_ch; + *ch_mask = (*map)[i][j].ch_mask; + *ch_rate = (*map)[i][j].ch_rate; + *port_type = (*map)[i][j].master_port_type; + + return 0; +} + +static int wcd938x_parse_port_mapping(struct device *dev, + char *prop, u8 path) +{ + u32 *dt_array, map_size, map_length; + u32 port_num, ch_mask, ch_rate, old_port_num = 0; + u32 slave_port_type, master_port_type; + u32 i, ch_iter = 0; + int ret = 0; + u8 *num_ports; + struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT]; + struct wcd938x_priv *wcd938x = dev_get_drvdata(dev); + + switch (path) { + case CODEC_RX: + map = &wcd938x->rx_port_mapping; + num_ports = &wcd938x->num_rx_ports; + break; + case CODEC_TX: + map = &wcd938x->tx_port_mapping; + num_ports = &wcd938x->num_tx_ports; + break; + } + + if (!of_find_property(dev->of_node, prop, + &map_size)) { + dev_err(dev, "missing port mapping prop %s\n", prop); + ret = -EINVAL; + goto err_port_map; + } + + map_length = map_size / (NUM_SWRS_DT_PARAMS * sizeof(u32)); + + dt_array = kzalloc(map_size, GFP_KERNEL); + + if (!dt_array) { + ret = -ENOMEM; + goto err_alloc; + } + ret = of_property_read_u32_array(dev->of_node, prop, dt_array, + NUM_SWRS_DT_PARAMS * map_length); + if (ret) { + dev_err(dev, "%s: Failed to read port mapping from prop %s\n", + __func__, prop); + goto err_pdata_fail; + } + + for (i = 0; i < map_length; i++) { + port_num = dt_array[NUM_SWRS_DT_PARAMS * i]; + slave_port_type = dt_array[NUM_SWRS_DT_PARAMS * i + 1]; + ch_mask = dt_array[NUM_SWRS_DT_PARAMS * i + 2]; + ch_rate = dt_array[NUM_SWRS_DT_PARAMS * i + 3]; + master_port_type = dt_array[NUM_SWRS_DT_PARAMS * i + 4]; + + if (port_num != old_port_num) + ch_iter = 0; + + (*map)[port_num][ch_iter].port_type = slave_port_type; + (*map)[port_num][ch_iter].ch_mask = ch_mask; + (*map)[port_num][ch_iter].master_port_type = master_port_type; + (*map)[port_num][ch_iter].num_ch = __sw_hweight8(ch_mask); + (*map)[port_num][ch_iter++].ch_rate = ch_rate; + old_port_num = port_num; + } + *num_ports = port_num; + kfree(dt_array); + return 0; + +err_pdata_fail: + kfree(dt_array); +err_alloc: +err_port_map: + return ret; +} + +static int wcd938x_tx_connect_port(struct snd_soc_component *component, + u8 slv_port_type, u8 enable) +{ + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + u8 port_id, num_ch, ch_mask, port_type; + u32 ch_rate; + u8 num_port = 1; + int ret = 0; + + ret = wcd938x_set_port_params(component, slv_port_type, &port_id, + &num_ch, &ch_mask, &ch_rate, + &port_type, CODEC_TX); + + if (ret) + return ret; + + if (enable) + ret = swr_connect_port(wcd938x->tx_swr_dev, &port_id, + num_port, &ch_mask, &ch_rate, + &num_ch, &port_type); + else + ret = swr_disconnect_port(wcd938x->tx_swr_dev, &port_id, + num_port, &ch_mask, &port_type); + return ret; + +} +static int wcd938x_rx_connect_port(struct snd_soc_component *component, + u8 slv_port_type, u8 enable) +{ + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + u8 port_id, num_ch, ch_mask, port_type; + u32 ch_rate; + u8 num_port = 1; + int ret = 0; + + ret = wcd938x_set_port_params(component, slv_port_type, &port_id, + &num_ch, &ch_mask, &ch_rate, + &port_type, CODEC_RX); + + if (ret) + return ret; + + if (enable) + ret = swr_connect_port(wcd938x->rx_swr_dev, &port_id, + num_port, &ch_mask, &ch_rate, + &num_ch, &port_type); + else + ret = swr_disconnect_port(wcd938x->rx_swr_dev, &port_id, + num_port, &ch_mask, &port_type); + return ret; +} + +static int wcd938x_rx_clk_enable(struct snd_soc_component *component) +{ + + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + if (wcd938x->rx_clk_cnt == 0) { + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x08, 0x08); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD938X_ANA_RX_SUPPLIES, 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_RX0_CTL, 0x40, 0x00); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_RX1_CTL, 0x40, 0x00); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_RX2_CTL, 0x40, 0x00); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x02); + } + wcd938x->rx_clk_cnt++; + + return 0; +} + +static int wcd938x_rx_clk_disable(struct snd_soc_component *component) +{ + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + wcd938x->rx_clk_cnt--; + if (wcd938x->rx_clk_cnt == 0) { + snd_soc_component_update_bits(component, + WCD938X_ANA_RX_SUPPLIES, 0x40, 0x00); + snd_soc_component_update_bits(component, + WCD938X_ANA_RX_SUPPLIES, 0x80, 0x00); + snd_soc_component_update_bits(component, + WCD938X_ANA_RX_SUPPLIES, 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x00); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x01, 0x00); + } + return 0; +} + +/* + * wcd938x_soc_get_mbhc: get wcd938x_mbhc handle of corresponding component + * @component: handle to snd_soc_component * + * + * return wcd938x_mbhc handle or error code in case of failure + */ +struct wcd938x_mbhc *wcd938x_soc_get_mbhc(struct snd_soc_component *component) +{ + struct wcd938x_priv *wcd938x; + + if (!component) { + pr_err("%s: Invalid params, NULL component\n", __func__); + return NULL; + } + wcd938x = snd_soc_component_get_drvdata(component); + + if (!wcd938x) { + pr_err("%s: wcd938x is NULL\n", __func__); + return NULL; + } + + return wcd938x->mbhc; +} +EXPORT_SYMBOL(wcd938x_soc_get_mbhc); + +static int wcd938x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd938x_rx_clk_enable(component); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_HPH_GAIN_CTL, 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD938X_HPH_RDAC_CLK_CTL1, 0x80, 0x00); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_component_update_bits(component, + WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x02); + if (wcd938x->comp1_enable) { + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x02); + /* 5msec compander delay as per HW requirement */ + if (!wcd938x->comp2_enable || + (snd_soc_component_read(component, + WCD938X_DIGITAL_CDC_COMP_CTL_0) & 0x01)) + usleep_range(5000, 5010); + snd_soc_component_update_bits(component, + WCD938X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); + } else { + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_COMP_CTL_0, + 0x02, 0x00); + snd_soc_component_update_bits(component, + WCD938X_HPH_L_EN, 0x20, 0x20); + + } + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, + WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R, + 0x0F, 0x01); + break; + } + + return 0; +} + +static int wcd938x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd938x_rx_clk_enable(component); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_HPH_GAIN_CTL, 0x08, 0x08); + snd_soc_component_update_bits(component, + WCD938X_HPH_RDAC_CLK_CTL1, 0x80, 0x00); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_component_update_bits(component, + WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x0F, 0x02); + if (wcd938x->comp2_enable) { + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_COMP_CTL_0, 0x01, 0x01); + /* 5msec compander delay as per HW requirement */ + if (!wcd938x->comp1_enable || + (snd_soc_component_read(component, + WCD938X_DIGITAL_CDC_COMP_CTL_0) & 0x02)) + usleep_range(5000, 5010); + snd_soc_component_update_bits(component, + WCD938X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x00); + } else { + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_COMP_CTL_0, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD938X_HPH_R_EN, 0x20, 0x20); + } + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, + WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R, + 0x0F, 0x01); + break; + } + + return 0; +} + +static int wcd938x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd938x_rx_clk_enable(component); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_HPH_GAIN_CTL, 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x02); + /* 5 msec delay as per HW requirement */ + usleep_range(5000, 5010); + wcd_cls_h_fsm(component, &wcd938x->clsh_info, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_EAR, + wcd938x->hph_mode); + break; + case SND_SOC_DAPM_POST_PMD: + break; + }; + return 0; + +} + +static int wcd938x_codec_aux_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + int ret = 0; + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd938x_rx_clk_enable(component); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_AUX_GAIN_CTL, 0x01, 0x01); + wcd_cls_h_fsm(component, &wcd938x->clsh_info, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_AUX, + wcd938x->hph_mode); + break; + case SND_SOC_DAPM_POST_PMD: + wcd938x_rx_clk_disable(component); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x04, 0x00); + break; + }; + return ret; + +} + +static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + int ret = 0; + int hph_mode = wcd938x->hph_mode; + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = swr_slvdev_datapath_control(wcd938x->rx_swr_dev, + wcd938x->rx_swr_dev->dev_num, + true); + wcd_cls_h_fsm(component, &wcd938x->clsh_info, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_HPHR, + hph_mode); + snd_soc_component_update_bits(component, WCD938X_ANA_HPH, + 0x10, 0x10); + /* 100 usec delay as per HW requirement */ + usleep_range(100, 110); + set_bit(HPH_PA_DELAY, &wcd938x->status_mask); + break; + case SND_SOC_DAPM_POST_PMU: + /* + * 7ms sleep is required if compander is enabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is required. + */ + if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) { + if (!wcd938x->comp2_enable) + usleep_range(20000, 20100); + else + usleep_range(7000, 7100); + clear_bit(HPH_PA_DELAY, &wcd938x->status_mask); + } + snd_soc_component_update_bits(component, + WCD938X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02); + if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) + snd_soc_component_update_bits(component, + WCD938X_ANA_RX_SUPPLIES, 0x02, 0x02); + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX2 << 0x10)); + break; + case SND_SOC_DAPM_PRE_PMD: + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX2 << 0x10 | 0x1)); + blocking_notifier_call_chain(&wcd938x->mbhc->notifier, + WCD_EVENT_PRE_HPHR_PA_OFF, + &wcd938x->mbhc->wcd_mbhc); + break; + case SND_SOC_DAPM_POST_PMD: + /* 7 msec delay as per HW requirement */ + usleep_range(7000, 7010); + blocking_notifier_call_chain(&wcd938x->mbhc->notifier, + WCD_EVENT_POST_HPHR_PA_OFF, + &wcd938x->mbhc->wcd_mbhc); + snd_soc_component_update_bits(component, WCD938X_ANA_HPH, + 0x10, 0x00); + wcd_cls_h_fsm(component, &wcd93x->clsh_info, + WCD_CLSH_EVENT_POST_PA, + WCD_CLSH_STATE_HPHR, + hph_mode); + break; + }; + return ret; +} + +static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + int ret = 0; + int hph_mode = wcd938x->hph_mode; + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = swr_slvdev_datapath_control(wcd938x->rx_swr_dev, + wcd938x->rx_swr_dev->dev_num, + true); + wcd_cls_h_fsm(component, &wcd938x->clsh_info, + WCD_CLSH_EVENT_PRE_DAC, + WCD_CLSH_STATE_HPHL, + hph_mode); + snd_soc_component_update_bits(component, WCD938X_ANA_HPH, + 0x20, 0x20); + /* 100 usec delay as per HW requirement */ + usleep_range(100, 110); + set_bit(HPH_PA_DELAY, &wcd938x->status_mask); + break; + case SND_SOC_DAPM_POST_PMU: + /* + * 7ms sleep is required if compander is enabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is required. + */ + if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) { + if (!wcd938x->comp1_enable) + usleep_range(20000, 20100); + else + usleep_range(7000, 7100); + clear_bit(HPH_PA_DELAY, &wcd938x->status_mask); + } + snd_soc_component_update_bits(component, + WCD938X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02); + if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) + snd_soc_component_update_bits(component, + WCD938X_ANA_RX_SUPPLIES, 0x02, 0x02); + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10)); + break; + case SND_SOC_DAPM_PRE_PMD: + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10 | 0x1)); + blocking_notifier_call_chain(&wcd938x->mbhc->notifier, + WCD_EVENT_PRE_HPHL_PA_OFF, + &wcd938x->mbhc->wcd_mbhc); + break; + case SND_SOC_DAPM_POST_PMD: + /* 7 msec delay as per HW requirement */ + usleep_range(7000, 7010); + blocking_notifier_call_chain(&wcd938x->mbhc->notifier, + WCD_EVENT_POST_HPHL_PA_OFF, + &wcd938x->mbhc->wcd_mbhc); + snd_soc_component_update_bits(component, WCD938X_ANA_HPH, + 0x20, 0x00); + wcd_cls_h_fsm(component, &wcd938x->clsh_info, + WCD_CLSH_EVENT_POST_PA, + WCD_CLSH_STATE_HPHL, + hph_mode); + break; + }; + return ret; +} + +static int wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + int hph_mode = wcd938x->hph_mode; + int ret = 0; + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = swr_slvdev_datapath_control(wcd938x->rx_swr_dev, + wcd938x->rx_swr_dev->dev_num, + true); + break; + case SND_SOC_DAPM_POST_PMU: + /* 1 msec delay as per HW requirement */ + usleep_range(1000, 1010); + if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) + snd_soc_component_update_bits(component, + WCD938X_ANA_RX_SUPPLIES, + 0x20, 0x20); + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX3 << 0x10)); + break; + case SND_SOC_DAPM_PRE_PMD: + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX3 << 0x10 | 0x1)); + break; + case SND_SOC_DAPM_POST_PMD: + /* 1 msec delay as per HW requirement */ + usleep_range(1000, 1010); + wcd_cls_h_fsm(component, &wcd938x->clsh_info, + WCD_CLSH_EVENT_POST_PA, + WCD_CLSH_STATE_AUX, + hph_mode); + break; + }; + return ret; +} + +static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + int hph_mode = wcd938x->hph_mode; + int ret = 0; + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = swr_slvdev_datapath_control(wcd938x->rx_swr_dev, + wcd938x->rx_swr_dev->dev_num, + true); + break; + case SND_SOC_DAPM_POST_PMU: + /* 6 msec delay as per HW requirement */ + usleep_range(6000, 6010); + if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) + snd_soc_component_update_bits(component, + WCD938X_ANA_RX_SUPPLIES, + 0x02, 0x02); + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10)); + break; + case SND_SOC_DAPM_PRE_PMD: + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10 | 0x1)); + break; + case SND_SOC_DAPM_POST_PMD: + /* 7 msec delay as per HW requirement */ + usleep_range(7000, 7010); + wcd_cls_h_fsm(component, &wcd938x->clsh_info, + WCD_CLSH_EVENT_POST_PA, + WCD_CLSH_STATE_EAR, + hph_mode); + break; + }; + return ret; +} + +static int wcd938x_enable_clsh(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + int mode = wcd938x->hph_mode; + int ret = 0; + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + if (mode == CLS_H_LOHIFI || mode == CLS_H_ULP || + mode == CLS_H_HIFI || mode == CLS_H_LP) { + wcd938x_rx_connect_port(component, CLSH, + SND_SOC_DAPM_EVENT_ON(event)); + } + if (SND_SOC_DAPM_EVENT_OFF(event)) + ret = swr_slvdev_datapath_control( + wcd938x->rx_swr_dev, + wcd938x->rx_swr_dev->dev_num, + false); + return ret; +} + +static int wcd938x_enable_rx1(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd938x_rx_connect_port(component, HPH_L, true); + if (wcd938x->comp1_enable) + wcd938x_rx_connect_port(component, COMP_L, true); + break; + case SND_SOC_DAPM_POST_PMD: + wcd938x_rx_connect_port(component, HPH_L, false); + if (wcd938x->comp1_enable) + wcd938x_rx_connect_port(component, COMP_L, false); + wcd938x_rx_clk_disable(component); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, + 0x01, 0x00); + break; + }; + + return 0; +} + +static int wcd938x_enable_rx2(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd938x_rx_connect_port(component, HPH_R, true); + if (wcd938x->comp2_enable) + wcd938x_rx_connect_port(component, COMP_R, true); + break; + case SND_SOC_DAPM_POST_PMD: + wcd938x_rx_connect_port(component, HPH_R, false); + if (wcd938x->comp2_enable) + wcd938x_rx_connect_port(component, COMP_R, false); + wcd938x_rx_clk_disable(component); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, + 0x02, 0x00); + break; + }; + + return 0; +} + +static int wcd938x_enable_rx3(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd938x_rx_connect_port(component, LO, true); + break; + case SND_SOC_DAPM_POST_PMD: + wcd938x_rx_connect_port(component, LO, false); + /* 6 msec delay as per HW requirement */ + usleep_range(6000, 6010); + wcd938x_rx_clk_disable(component); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x04, 0x00); + break; + } + + return 0; +} + +static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + u16 dmic_clk_reg; + s32 *dmic_clk_cnt; + unsigned int dmic; + char *wname; + int ret = 0; + + wname = strpbrk(w->name, "012345"); + + if (!wname) { + dev_err(component->dev, "%s: widget not found\n", __func__); + return -EINVAL; + } + + ret = kstrtouint(wname, 10, &dmic); + if (ret < 0) { + dev_err(component->dev, "%s: Invalid DMIC line on the codec\n", + __func__); + return -EINVAL; + } + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (dmic) { + case 0: + case 1: + dmic_clk_cnt = &(wcd938x->dmic_0_1_clk_cnt); + dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_CTL; + break; + case 2: + case 3: + dmic_clk_cnt = &(wcd938x->dmic_2_3_clk_cnt); + dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC1_CTL; + break; + case 4: + case 5: + dmic_clk_cnt = &(wcd938x->dmic_4_5_clk_cnt); + dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC2_CTL; + break; + default: + dev_err(component->dev, "%s: Invalid DMIC Selection\n", + __func__); + return -EINVAL; + }; + dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", + __func__, event, dmic, *dmic_clk_cnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x80); + snd_soc_component_update_bits(component, + dmic_clk_reg, 0x07, 0x02); + snd_soc_component_update_bits(component, + dmic_clk_reg, 0x08, 0x08); + snd_soc_component_update_bits(component, + dmic_clk_reg, 0x70, 0x20); + wcd938x_tx_connect_port(component, DMIC0 + (w->shift), true); + break; + case SND_SOC_DAPM_POST_PMD: + wcd938x_tx_connect_port(component, DMIC0 + (w->shift), false); + break; + + }; + return 0; +} + +/* + * wcd938x_get_micb_vout_ctl_val: converts micbias from volts to register value + * @micb_mv: micbias in mv + * + * return register value converted + */ +int wcd938x_get_micb_vout_ctl_val(u32 micb_mv) +{ + /* min micbias voltage is 1V and maximum is 2.85V */ + if (micb_mv < 1000 || micb_mv > 2850) { + pr_err("%s: unsupported micbias voltage\n", __func__); + return -EINVAL; + } + + return (micb_mv - 1000) / 50; +} +EXPORT_SYMBOL(wcd938x_get_micb_vout_ctl_val); + +/* + * wcd938x_mbhc_micb_adjust_voltage: adjust specific micbias voltage + * @component: handle to snd_soc_component * + * @req_volt: micbias voltage to be set + * @micb_num: micbias to be set, e.g. micbias1 or micbias2 + * + * return 0 if adjustment is success or error code in case of failure + */ +int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component *component, + int req_volt, int micb_num) +{ + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + int cur_vout_ctl, req_vout_ctl; + int micb_reg, micb_val, micb_en; + int ret = 0; + + switch (micb_num) { + case MIC_BIAS_1: + micb_reg = WCD938X_ANA_MICB1; + break; + case MIC_BIAS_2: + micb_reg = WCD938X_ANA_MICB2; + break; + case MIC_BIAS_3: + micb_reg = WCD938X_ANA_MICB3; + break; + case MIC_BIAS_4: + micb_reg = WCD938X_ANA_MICB4; + break; + default: + return -EINVAL; + } + mutex_lock(&wcd938x->micb_lock); + + /* + * If requested micbias voltage is same as current micbias + * voltage, then just return. Otherwise, adjust voltage as + * per requested value. If micbias is already enabled, then + * to avoid slow micbias ramp-up or down enable pull-up + * momentarily, change the micbias value and then re-enable + * micbias. + */ + micb_val = snd_soc_component_read32(component, micb_reg); + micb_en = (micb_val & 0xC0) >> 6; + cur_vout_ctl = micb_val & 0x3F; + + req_vout_ctl = wcd938x_get_micb_vout_ctl_val(req_volt); + if (req_vout_ctl < 0) { + ret = -EINVAL; + goto exit; + } + if (cur_vout_ctl == req_vout_ctl) { + ret = 0; + goto exit; + } + + dev_dbg(component->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n", + __func__, micb_num, WCD_VOUT_CTL_TO_MICB(cur_vout_ctl), + req_volt, micb_en); + + if (micb_en == 0x1) + snd_soc_component_update_bits(component, micb_reg, 0xC0, 0x80); + + snd_soc_component_update_bits(component, micb_reg, 0x3F, req_vout_ctl); + + if (micb_en == 0x1) { + snd_soc_component_update_bits(component, micb_reg, 0xC0, 0x40); + /* + * Add 2ms delay as per HW requirement after enabling + * micbias + */ + usleep_range(2000, 2100); + } +exit: + mutex_unlock(&wcd938x->micb_lock); + return ret; +} +EXPORT_SYMBOL(wcd938x_mbhc_micb_adjust_voltage); + +static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + int ret = 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev, + wcd938x->tx_swr_dev->dev_num, + true); + break; + case SND_SOC_DAPM_POST_PMD: + ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev, + wcd938x->tx_swr_dev->dev_num, + false); + break; + }; + + return ret; +} + +static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event){ + + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x80); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x08); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); + wcd938x_tx_connect_port(component, ADC1 + (w->shift), true); + break; + case SND_SOC_DAPM_POST_PMD: + wcd938x_tx_connect_port(component, ADC1 + (w->shift), false); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00); + break; + }; + + return 0; +} + +static int wcd938x_enable_req(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_REQ_CTL, 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_REQ_CTL, 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD938X_ANA_TX_CH2, 0x40, 0x40); + snd_soc_component_update_bits(component, + WCD938X_ANA_TX_CH2, 0x20, 0x20); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x30, 0x30); + snd_soc_component_update_bits(component, + WCD938X_ANA_TX_CH1, 0x80, 0x80); + snd_soc_component_update_bits(component, + WCD938X_ANA_TX_CH2, 0x40, 0x00); + snd_soc_component_update_bits(component, + WCD938X_ANA_TX_CH2, 0x80, 0x80); + snd_soc_component_update_bits(component, + WCD938X_ANA_TX_CH2, 0x20, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, + WCD938X_ANA_TX_CH1, 0x80, 0x00); + snd_soc_component_update_bits(component, + WCD938X_ANA_TX_CH2, 0x80, 0x00); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x00); + break; + }; + return 0; +} + +int wcd938x_micbias_control(struct snd_soc_component *component, + int micb_num, int req, bool is_dapm) +{ + + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + int micb_index = micb_num - 1; + u16 micb_reg; + int pre_off_event = 0, post_off_event = 0; + int post_on_event = 0, post_dapm_off = 0; + int post_dapm_on = 0; + + if ((micb_index < 0) || (micb_index > WCD938X_MAX_MICBIAS - 1)) { + dev_err(component->dev, + "%s: Invalid micbias index, micb_ind:%d\n", + __func__, micb_index); + return -EINVAL; + } + switch (micb_num) { + case MIC_BIAS_1: + micb_reg = WCD938X_ANA_MICB1; + break; + case MIC_BIAS_2: + micb_reg = WCD938X_ANA_MICB2; + pre_off_event = WCD_EVENT_PRE_MICBIAS_2_OFF; + post_off_event = WCD_EVENT_POST_MICBIAS_2_OFF; + post_on_event = WCD_EVENT_POST_MICBIAS_2_ON; + post_dapm_on = WCD_EVENT_POST_DAPM_MICBIAS_2_ON; + post_dapm_off = WCD_EVENT_POST_DAPM_MICBIAS_2_OFF; + break; + case MIC_BIAS_3: + micb_reg = WCD938X_ANA_MICB3; + break; + case MIC_BIAS_4: + micb_reg = WCD938X_ANA_MICB4; + break; + default: + dev_err(component->dev, "%s: Invalid micbias number: %d\n", + __func__, micb_num); + return -EINVAL; + }; + mutex_lock(&wcd938x->micb_lock); + + switch (req) { + case MICB_PULLUP_ENABLE: + wcd938x->pullup_ref[micb_index]++; + if ((wcd938x->pullup_ref[micb_index] == 1) && + (wcd938x->micb_ref[micb_index] == 0)) + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x80); + break; + case MICB_PULLUP_DISABLE: + if (wcd938x->pullup_ref[micb_index] > 0) + wcd938x->pullup_ref[micb_index]--; + if ((wcd938x->pullup_ref[micb_index] == 0) && + (wcd938x->micb_ref[micb_index] == 0)) + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x00); + break; + case MICB_ENABLE: + wcd938x->micb_ref[micb_index]++; + if (wcd938x->micb_ref[micb_index] == 1) { + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0xE0, 0xE0); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); + snd_soc_component_update_bits(component, + WCD938X_MICB1_TEST_CTL_2, 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD938X_MICB2_TEST_CTL_2, 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD938X_MICB3_TEST_CTL_2, 0x01, 0x01); + snd_soc_component_update_bits(component, + micb_reg, 0xC0, 0x40); + if (post_on_event) + blocking_notifier_call_chain( + &wcd938x->mbhc->notifier, + post_on_event, + &wcd938x->mbhc->wcd_mbhc); + } + if (is_dapm && post_dapm_on && wcd938x->mbhc) + blocking_notifier_call_chain(&wcd938x->mbhc->notifier, + post_dapm_on, + &wcd938x->mbhc->wcd_mbhc); + break; + case MICB_DISABLE: + if (wcd938x->micb_ref[micb_index] > 0) + wcd938x->micb_ref[micb_index]--; + if ((wcd938x->micb_ref[micb_index] == 0) && + (wcd938x->pullup_ref[micb_index] > 0)) + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x80); + else if ((wcd938x->micb_ref[micb_index] == 0) && + (wcd938x->pullup_ref[micb_index] == 0)) { + if (pre_off_event && wcd938x->mbhc) + blocking_notifier_call_chain( + &wcd938x->mbhc->notifier, + pre_off_event, + &wcd938x->mbhc->wcd_mbhc); + snd_soc_component_update_bits(component, micb_reg, + 0xC0, 0x00); + if (post_off_event && wcd938x->mbhc) + blocking_notifier_call_chain( + &wcd938x->mbhc->notifier, + post_off_event, + &wcd938x->mbhc->wcd_mbhc); + } + if (is_dapm && post_dapm_off && wcd938x->mbhc) + blocking_notifier_call_chain(&wcd938x->mbhc->notifier, + post_dapm_off, + &wcd938x->mbhc->wcd_mbhc); + break; + }; + + dev_dbg(component->dev, + "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", + __func__, micb_num, wcd938x->micb_ref[micb_index], + wcd938x->pullup_ref[micb_index]); + mutex_unlock(&wcd938x->micb_lock); + + return 0; +} +EXPORT_SYMBOL(wcd938x_micbias_control); + +static int wcd938x_get_logical_addr(struct swr_device *swr_dev) +{ + int ret = 0; + uint8_t devnum = 0; + + ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum); + if (ret) { + dev_err(&swr_dev->dev, + "%s get devnum %d for dev addr %lx failed\n", + __func__, devnum, swr_dev->addr); + swr_remove_device(swr_dev); + return ret; + } + swr_dev->dev_num = devnum; + return 0; +} + +static int wcd938x_event_notify(struct notifier_block *block, + unsigned long val, + void *data) +{ + u16 event = (val & 0xffff); + u16 amic; + u16 mask = 0x40, reg = 0x0; + int ret = 0; + struct wcd938x_priv *wcd938x = dev_get_drvdata((struct device *)data); + struct snd_soc_component *component = wcd938x->component; + struct wcd_mbhc *mbhc; + + switch (event) { + case BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR: + amic = (val >> 0x10); + if (amic == 0x1 || amic == 0x2) + reg = WCD938X_ANA_TX_CH2; + else if (amic == 0x3) + reg = WCD938X_ANA_TX_CH3_HPF; + else + return 0; + if (amic == 0x2) + mask = 0x20; + snd_soc_component_update_bits(component, reg, mask, 0x00); + break; + case BOLERO_WCD_EVT_PA_OFF_PRE_SSR: + snd_soc_component_update_bits(component, WCD938X_ANA_HPH, + 0xC0, 0x00); + snd_soc_component_update_bits(component, WCD938X_ANA_EAR, + 0x80, 0x00); + snd_soc_component_update_bits(component, WCD938X_AUX_AUXPA, + 0x80, 0x00); + break; + case BOLERO_WCD_EVT_SSR_DOWN: + wcd938x_reset_low(wcd938x->dev); + break; + case BOLERO_WCD_EVT_SSR_UP: + wcd938x_reset(wcd938x->dev); + wcd938x_get_logical_addr(wcd938x->tx_swr_dev); + wcd938x_get_logical_addr(wcd938x->rx_swr_dev); + regcache_mark_dirty(wcd938x->regmap); + regcache_sync(wcd938x->regmap); + /* Initialize MBHC module */ + mbhc = &wcd938x->mbhc->wcd_mbhc; + ret = wcd938x_mbhc_post_ssr_init(wcd938x->mbhc, component); + if (ret) { + dev_err(component->dev, "%s: mbhc initialization failed\n", + __func__); + } else { + wcd938x_mbhc_hs_detect(component, mbhc->mbhc_cfg); + } + break; + case BOLERO_WCD_EVT_CLK_NOTIFY: + snd_soc_update_bits(codec, WCD938X_DIGITAL_TOP_CLK_CFG, 0x06, + ((val >> 0x10) << 0x01)); + break; + default: + dev_dbg(component->dev, "%s: invalid event %d\n", __func__, event); + break; + } + return 0; +} + +static int __wcd938x_codec_enable_micbias(struct snd_soc_dapm_widget *w, + int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + int micb_num; + + dev_dbg(component->dev, "%s: wname: %s, event: %d\n", + __func__, w->name, event); + + if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) + micb_num = MIC_BIAS_1; + else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2"))) + micb_num = MIC_BIAS_2; + else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3"))) + micb_num = MIC_BIAS_3; + else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4"))) + micb_num = MIC_BIAS_4; + else + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd938x_micbias_control(component, micb_num, + MICB_ENABLE, true); + break; + case SND_SOC_DAPM_POST_PMU: + /* 1 msec delay as per HW requirement */ + usleep_range(1000, 1100); + break; + case SND_SOC_DAPM_POST_PMD: + wcd938x_micbias_control(component, micb_num, + MICB_DISABLE, true); + break; + }; + + return 0; + +} + +static int wcd938x_codec_enable_micbias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + return __wcd938x_codec_enable_micbias(w, event); +} + +static int wcd938x_rx_hph_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wcd938x->hph_mode; + return 0; +} + +static int wcd938x_rx_hph_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + u32 mode_val; + + mode_val = ucontrol->value.enumerated.item[0]; + + dev_dbg(component->dev, "%s: mode: %d\n", __func__, mode_val); + + if (mode_val == 0) { + dev_info(component->dev, + "%s:Invalid HPH Mode, default to class_AB\n", + __func__); + mode_val = 3; /* enum will be updated later */ + } + wcd938x->hph_mode = mode_val; + return 0; +} + +static int wcd938x_get_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + bool hphr; + struct soc_multi_mixer_control *mc; + + mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); + hphr = mc->shift; + + ucontrol->value.integer.value[0] = hphr ? wcd938x->comp2_enable : + wcd938x->comp1_enable; + return 0; +} + +static int wcd938x_set_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + int value = ucontrol->value.integer.value[0]; + bool hphr; + struct soc_multi_mixer_control *mc; + + mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); + hphr = mc->shift; + if (hphr) + wcd938x->comp2_enable = value; + else + wcd938x->comp1_enable = value; + + return 0; +} + +static int wcd938x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + struct wcd938x_pdata *pdata = NULL; + int ret = 0; + + pdata = dev_get_platdata(wcd938x->dev); + + if (!pdata) { + dev_err(component->dev, "%s: pdata is NULL\n", __func__); + return -EINVAL; + } + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = msm_cdc_enable_ondemand_supply(wcd938x->dev, + wcd938x->supplies, + pdata->regulator, + pdata->num_supplies, + "cdc-vdd-buck"); + if (ret == -EINVAL) { + dev_err(component->dev, "%s: vdd buck is not enabled\n", + __func__); + return ret; + } + /* + * 200us sleep is required after LDO15 is enabled as per + * HW requirement + */ + usleep_range(200, 250); + break; + case SND_SOC_DAPM_POST_PMD: + ret = msm_cdc_disable_ondemand_supply(wcd938x->dev, + wcd938x->supplies, + pdata->regulator, + pdata->num_supplies, + "cdc-vdd-buck"); + if (ret == -EINVAL) { + dev_err(dev, "%s: vdd buck is not disabled\n", + __func__); + return 0; + } + break; + } + return 0; +} + +static int wcd938x_tx_hdr_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + int hdr = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + ucontrol->value.integer.value[0] = wcd938x->hdr_en[hdr]; + + return 0; +} + +static int wcd938x_tx_hdr_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + int hdr = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int val = ucontrol->value.integer.value[0]; + u8 mask = 0; + + wcd938x->hdr_en[hdr] = val; + + switch(val) { + case TX_HDR12: + mask = (1 << 4); + val = (val << 4); + break; + case TX_HDR34: + mask = (1 << 3); + val = (val << 3); + break; + default: + dev_err(component->dev, "%s: unknown HDR input: %d\n", + __func__, hdr); + break; + } + + if (mask) + snd_soc_component_update_bits(component, + WCD938X_TX_NEW_AMIC_MUX_CFG, mask, val); + + return 0; +} + +static const char * const rx_hph_mode_mux_text[] = { + "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI", + "CLS_H_ULP", "CLS_AB_HIFI", +}; + +static const struct soc_enum rx_hph_mode_mux_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text), + rx_hph_mode_mux_text); + +static const struct snd_kcontrol_new wcd938x_snd_controls[] = { + SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum, + wcd938x_rx_hph_mode_get, wcd938x_rx_hph_mode_put), + + SOC_SINGLE_EXT("HPHL_COMP Switch", SND_SOC_NOPM, 0, 1, 0, + wcd938x_get_compander, wcd938x_set_compander), + SOC_SINGLE_EXT("HPHR_COMP Switch", SND_SOC_NOPM, 1, 1, 0, + wcd938x_get_compander, wcd938x_set_compander), + + SOC_SINGLE_EXT("TX HDR12", SND_SOC_NOPM, TX_HDR12, 1, 0, + wcd938x_tx_hdr_get, wcd938x_tx_hdr_put), + + SOC_SINGLE_EXT("TX HDR34", SND_SOC_NOPM, TX_HDR34, 1, 0, + wcd938x_tx_hdr_get, wcd938x_tx_hdr_put), + + SOC_SINGLE_TLV("HPHL Volume", WCD938X_HPH_L_EN, 0, 20, 1, line_gain), + SOC_SINGLE_TLV("HPHR Volume", WCD938X_HPH_R_EN, 0, 20, 1, line_gain), + SOC_SINGLE_TLV("ADC1 Volume", WCD938X_ANA_TX_CH1, 0, 20, 0, + analog_gain), + SOC_SINGLE_TLV("ADC2 Volume", WCD938X_ANA_TX_CH2, 0, 20, 0, + analog_gain), + SOC_SINGLE_TLV("ADC3 Volume", WCD938X_ANA_TX_CH3, 0, 20, 0, + analog_gain), + SOC_SINGLE_TLV("ADC4 Volume", WCD938X_ANA_TX_CH4, 0, 20, 0, + analog_gain), +}; + +static const struct snd_kcontrol_new adc1_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new adc2_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new adc3_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new adc4_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new dmic1_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new dmic2_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new dmic3_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new dmic4_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new dmic5_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new dmic6_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new dmic7_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new dmic8_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new ear_rdac_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new aux_rdac_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new hphl_rdac_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new hphr_rdac_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const char * const adc2_mux_text[] = { + "INP2", "INP3" +}; + +static const struct soc_enum adc2_enum = + SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 7, + ARRAY_SIZE(adc2_mux_text), adc2_mux_text); + +static const struct snd_kcontrol_new tx_adc2_mux = + SOC_DAPM_ENUM("ADC2 MUX Mux", adc2_enum); + +static const char * const adc3_mux_text[] = { + "INP4", "INP6" +}; + +static const struct soc_enum adc3_enum = + SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 6, + ARRAY_SIZE(adc3_mux_text), adc3_mux_text); + +static const struct snd_kcontrol_new tx_adc3_mux = + SOC_DAPM_ENUM("ADC3 MUX Mux", adc3_enum); + +static const char * const adc4_mux_text[] = { + "INP5", "INP7" +}; + +static const struct soc_enum adc4_enum = + SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 5, + ARRAY_SIZE(adc4_mux_text), adc4_mux_text); + +static const struct snd_kcontrol_new tx_adc4_mux = + SOC_DAPM_ENUM("ADC4 MUX Mux", adc4_enum); + +static const char * const rdac3_mux_text[] = { + "RX1", "RX3" +}; + +static const struct soc_enum rdac3_enum = + SOC_ENUM_SINGLE(WCD938X_DIGITAL_CDC_EAR_PATH_CTL, 0, + ARRAY_SIZE(rdac3_mux_text), rdac3_mux_text); + +static const struct snd_kcontrol_new rx_rdac3_mux = + SOC_DAPM_ENUM("RDAC3_MUX Mux", rdac3_enum); + +static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = { + + /*input widgets*/ + SND_SOC_DAPM_INPUT("AMIC1"), + SND_SOC_DAPM_INPUT("AMIC2"), + SND_SOC_DAPM_INPUT("AMIC3"), + SND_SOC_DAPM_INPUT("AMIC4"), + SND_SOC_DAPM_INPUT("AMIC5"), + SND_SOC_DAPM_INPUT("AMIC6"), + SND_SOC_DAPM_INPUT("AMIC7"), + SND_SOC_DAPM_INPUT("IN1_HPHL"), + SND_SOC_DAPM_INPUT("IN2_HPHR"), + SND_SOC_DAPM_INPUT("IN3_AUX"), + + /*tx widgets*/ + SND_SOC_DAPM_ADC_E("ADC1", NULL, SND_SOC_NOPM, 0, 0, + wcd938x_codec_enable_adc, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("ADC2", NULL, SND_SOC_NOPM, 0, 1, + wcd938x_codec_enable_adc, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("ADC3", NULL, SND_SOC_NOPM, 0, 2, + wcd938x_codec_enable_adc, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("ADC4", NULL, SND_SOC_NOPM, 0, 3, + wcd938x_codec_enable_adc, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0, + wcd938x_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 1, + wcd938x_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 2, + wcd938x_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 3, + wcd938x_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 4, + wcd938x_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 0, 5, + wcd938x_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC7", NULL, SND_SOC_NOPM, 0, 6, + wcd938x_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC8", NULL, SND_SOC_NOPM, 0, 7, + wcd938x_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER_E("ADC1 REQ", SND_SOC_NOPM, 0, 0, + NULL, 0, wcd938x_enable_req, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("ADC2 REQ", SND_SOC_NOPM, 0, 0, + NULL, 0, wcd938x_enable_req, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("ADC3 REQ", SND_SOC_NOPM, 0, 0, + NULL, 0, wcd938x_enable_req, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("ADC4 REQ", SND_SOC_NOPM, 0, 0, + NULL, 0, wcd938x_enable_req, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, + &tx_adc2_mux), + SND_SOC_DAPM_MUX("ADC3 MUX", SND_SOC_NOPM, 0, 0, + &tx_adc3_mux), + SND_SOC_DAPM_MUX("ADC4 MUX", SND_SOC_NOPM, 0, 0, + &tx_adc4_mux), + + /*tx mixers*/ + SND_SOC_DAPM_MIXER_E("ADC1_MIXER", SND_SOC_NOPM, 0, 0, + adc1_switch, ARRAY_SIZE(adc1_switch), + wcd938x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("ADC2_MIXER", SND_SOC_NOPM, 0, 0, + adc2_switch, ARRAY_SIZE(adc2_switch), + wcd938x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("ADC3_MIXER", SND_SOC_NOPM, 0, 0, adc3_switch, + ARRAY_SIZE(adc3_switch), wcd938x_tx_swr_ctrl, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("ADC4_MIXER", SND_SOC_NOPM, 0, 0, adc4_switch, + ARRAY_SIZE(adc4_switch), wcd938x_tx_swr_ctrl, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("DMIC1_MIXER", SND_SOC_NOPM, 0, + 0, dmic1_switch, ARRAY_SIZE(dmic1_switch), + wcd938x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("DMIC2_MIXER", SND_SOC_NOPM, 0, + 0, dmic2_switch, ARRAY_SIZE(dmic2_switch), + wcd938x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("DMIC3_MIXER", SND_SOC_NOPM, 0, + 0, dmic3_switch, ARRAY_SIZE(dmic3_switch), + wcd938x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("DMIC4_MIXER", SND_SOC_NOPM, 0, + 0, dmic4_switch, ARRAY_SIZE(dmic4_switch), + wcd938x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("DMIC5_MIXER", SND_SOC_NOPM, 0, + 0, dmic5_switch, ARRAY_SIZE(dmic5_switch), + wcd938x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("DMIC6_MIXER", SND_SOC_NOPM, 0, + 0, dmic6_switch, ARRAY_SIZE(dmic6_switch), + wcd938x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("DMIC7_MIXER", SND_SOC_NOPM, 0, + 0, dmic7_switch, ARRAY_SIZE(dmic7_switch), + wcd938x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("DMIC8_MIXER", SND_SOC_NOPM, 0, + 0, dmic8_switch, ARRAY_SIZE(dmic8_switch), + wcd938x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + /* micbias widgets*/ + SND_SOC_DAPM_MICBIAS_E("MIC BIAS1", SND_SOC_NOPM, 0, 0, + wcd938x_codec_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS2", SND_SOC_NOPM, 0, 0, + wcd938x_codec_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS3", SND_SOC_NOPM, 0, 0, + wcd938x_codec_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS4", SND_SOC_NOPM, 0, 0, + wcd938x_codec_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("VDD_BUCK", SND_SOC_NOPM, 0, 0, + wcd938x_codec_enable_vdd_buck, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("CLS_H_PORT", 1, SND_SOC_NOPM, 0, 0, + wcd938x_enable_clsh, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /*rx widgets*/ + SND_SOC_DAPM_PGA_E("EAR PGA", WCD938X_ANA_EAR, 7, 0, NULL, 0, + wcd938x_codec_enable_ear_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("AUX PGA", WCD938X_AUX_AUXPA, 7, 0, NULL, 0, + wcd938x_codec_enable_aux_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("HPHL PGA", WCD938X_ANA_HPH, 7, 0, NULL, 0, + wcd938x_codec_enable_hphl_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("HPHR PGA", WCD938X_ANA_HPH, 6, 0, NULL, 0, + wcd938x_codec_enable_hphr_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_DAC_E("RDAC1", NULL, SND_SOC_NOPM, 0, 0, + wcd938x_codec_hphl_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RDAC2", NULL, SND_SOC_NOPM, 0, 0, + wcd938x_codec_hphr_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RDAC3", NULL, SND_SOC_NOPM, 0, 0, + wcd938x_codec_ear_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RDAC4", NULL, SND_SOC_NOPM, 0, 0, + wcd938x_codec_aux_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("RDAC3_MUX", SND_SOC_NOPM, 0, 0, &rx_rdac3_mux), + + SND_SOC_DAPM_MIXER_E("RX1", SND_SOC_NOPM, 0, 0, NULL, 0, + wcd938x_enable_rx1, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX2", SND_SOC_NOPM, 0, 0, NULL, 0, + wcd938x_enable_rx2, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX3", SND_SOC_NOPM, 0, 0, NULL, 0, + wcd938x_enable_rx3, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + /* rx mixer widgets*/ + + SND_SOC_DAPM_MIXER("EAR_RDAC", SND_SOC_NOPM, 0, 0, + ear_rdac_switch, ARRAY_SIZE(ear_rdac_switch)), + SND_SOC_DAPM_MIXER("AUX_RDAC", SND_SOC_NOPM, 0, 0, + aux_rdac_switch, ARRAY_SIZE(aux_rdac_switch)), + SND_SOC_DAPM_MIXER("HPHL_RDAC", SND_SOC_NOPM, 0, 0, + hphl_rdac_switch, ARRAY_SIZE(hphl_rdac_switch)), + SND_SOC_DAPM_MIXER("HPHR_RDAC", SND_SOC_NOPM, 0, 0, + hphr_rdac_switch, ARRAY_SIZE(hphr_rdac_switch)), + + /*output widgets tx*/ + SND_SOC_DAPM_OUTPUT("ADC1_OUTPUT"), + SND_SOC_DAPM_OUTPUT("ADC2_OUTPUT"), + SND_SOC_DAPM_OUTPUT("ADC3_OUTPUT"), + SND_SOC_DAPM_OUTPUT("ADC4_OUTPUT"), + SND_SOC_DAPM_OUTPUT("DMIC1_OUTPUT"), + SND_SOC_DAPM_OUTPUT("DMIC2_OUTPUT"), + SND_SOC_DAPM_OUTPUT("DMIC3_OUTPUT"), + SND_SOC_DAPM_OUTPUT("DMIC4_OUTPUT"), + SND_SOC_DAPM_OUTPUT("DMIC5_OUTPUT"), + SND_SOC_DAPM_OUTPUT("DMIC6_OUTPUT"), + SND_SOC_DAPM_OUTPUT("DMIC7_OUTPUT"), + SND_SOC_DAPM_OUTPUT("DMIC8_OUTPUT"), + + /*output widgets rx*/ + SND_SOC_DAPM_OUTPUT("EAR"), + SND_SOC_DAPM_OUTPUT("AUX"), + SND_SOC_DAPM_OUTPUT("HPHL"), + SND_SOC_DAPM_OUTPUT("HPHR"), +}; + +static const struct snd_soc_dapm_route wcd938x_audio_map[] = { + + {"ADC1_OUTPUT", NULL, "ADC1_MIXER"}, + {"ADC1_MIXER", "Switch", "ADC1 REQ"}, + {"ADC1 REQ", NULL, "ADC1"}, + {"ADC1", NULL, "AMIC1"}, + + {"ADC2_OUTPUT", NULL, "ADC2_MIXER"}, + {"ADC2_MIXER", "Switch", "ADC2 REQ"}, + {"ADC2 REQ", NULL, "ADC2"}, + {"ADC2", NULL, "ADC2 MUX"}, + {"ADC2 MUX", "INP3", "AMIC3"}, + {"ADC2 MUX", "INP2", "AMIC2"}, + + {"ADC3_OUTPUT", NULL, "ADC3_MIXER"}, + {"ADC3_MIXER", "Switch", "ADC3 REQ"}, + {"ADC3 REQ", NULL, "ADC3"}, + {"ADC3", NULL, "ADC3 MUX"}, + {"ADC3 MUX", "INP4", "AMIC4"}, + {"ADC3 MUX", "INP6", "AMIC6"}, + + {"ADC4_OUTPUT", NULL, "ADC4_MIXER"}, + {"ADC4_MIXER", "Switch", "ADC4 REQ"}, + {"ADC4 REQ", NULL, "ADC4"}, + {"ADC4", NULL, "ADC4 MUX"}, + {"ADC4 MUX", "INP5", "AMIC5"}, + {"ADC4 MUX", "INP7", "AMIC7"}, + + {"DMIC1_OUTPUT", NULL, "DMIC1_MIXER"}, + {"DMIC1_MIXER", "Switch", "DMIC1"}, + + {"DMIC2_OUTPUT", NULL, "DMIC2_MIXER"}, + {"DMIC2_MIXER", "Switch", "DMIC2"}, + + {"DMIC3_OUTPUT", NULL, "DMIC3_MIXER"}, + {"DMIC3_MIXER", "Switch", "DMIC3"}, + + {"DMIC4_OUTPUT", NULL, "DMIC4_MIXER"}, + {"DMIC4_MIXER", "Switch", "DMIC4"}, + + {"DMIC5_OUTPUT", NULL, "DMIC5_MIXER"}, + {"DMIC5_MIXER", "Switch", "DMIC5"}, + + {"DMIC6_OUTPUT", NULL, "DMIC6_MIXER"}, + {"DMIC6_MIXER", "Switch", "DMIC6"}, + + {"DMIC7_OUTPUT", NULL, "DMIC7_MIXER"}, + {"DMIC7_MIXER", "Switch", "DMIC7"}, + + {"DMIC8_OUTPUT", NULL, "DMIC8_MIXER"}, + {"DMIC8_MIXER", "Switch", "DMIC8"}, + + {"IN1_HPHL", NULL, "VDD_BUCK"}, + {"IN1_HPHL", NULL, "CLS_H_PORT"}, + {"RX1", NULL, "IN1_HPHL"}, + {"RDAC1", NULL, "RX1"}, + {"HPHL_RDAC", "Switch", "RDAC1"}, + {"HPHL PGA", NULL, "HPHL_RDAC"}, + {"HPHL", NULL, "HPHL PGA"}, + + {"IN2_HPHR", NULL, "VDD_BUCK"}, + {"IN2_HPHR", NULL, "CLS_H_PORT"}, + {"RX2", NULL, "IN2_HPHR"}, + {"RDAC2", NULL, "RX2"}, + {"HPHR_RDAC", "Switch", "RDAC2"}, + {"HPHR PGA", NULL, "HPHR_RDAC"}, + {"HPHR", NULL, "HPHR PGA"}, + + {"IN3_AUX", NULL, "VDD_BUCK"}, + {"IN3_AUX", NULL, "CLS_H_PORT"}, + {"RX3", NULL, "IN3_AUX"}, + {"RDAC4", NULL, "RX3"}, + {"AUX_RDAC", "Switch", "RDAC4"}, + {"AUX PGA", NULL, "AUX_RDAC"}, + {"AUX", NULL, "AUX PGA"}, + + {"RDAC3_MUX", "RX3", "RX3"}, + {"RDAC3_MUX", "RX1", "RX1"}, + {"RDAC3", NULL, "RDAC3_MUX"}, + {"EAR_RDAC", "Switch", "RDAC3"}, + {"EAR PGA", NULL, "EAR_RDAC"}, + {"EAR", NULL, "EAR PGA"}, +}; + +static ssize_t wcd938x_version_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, size_t count, + loff_t pos) +{ + struct wcd938x_priv *priv; + char buffer[WCD938X_VERSION_ENTRY_SIZE]; + int len = 0; + + priv = (struct wcd938x_priv *) entry->private_data; + if (!priv) { + pr_err("%s: wcd938x priv is null\n", __func__); + return -EINVAL; + } + + switch (priv->version) { + case WCD938X_VERSION_1_0: + len = snprintf(buffer, sizeof(buffer), "WCD938X_1_0\n"); + break; + default: + len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + } + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops wcd938x_info_ops = { + .read = wcd938x_version_read, +}; + +/* + * wcd938x_info_create_codec_entry - creates wcd938x module + * @codec_root: The parent directory + * @component: component instance + * + * Creates wcd938x module and version entry under the given + * parent directory. + * + * Return: 0 on success or negative error code on failure. + */ +int wcd938x_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_component *component) +{ + struct snd_info_entry *version_entry; + struct wcd938x_priv *priv; + struct snd_soc_card *card; + + if (!codec_root || !component) + return -EINVAL; + + priv = snd_soc_component_get_drvdata(component); + if (priv->entry) { + dev_dbg(priv->dev, + "%s:wcd938x module already created\n", __func__); + return 0; + } + card = component->card; + priv->entry = snd_info_create_subdir(codec_root->module, + "wcd938x", codec_root); + if (!priv->entry) { + dev_dbg(component->dev, "%s: failed to create wcd938x entry\n", + __func__); + return -ENOMEM; + } + version_entry = snd_info_create_card_entry(card->snd_card, + "version", + priv->entry); + if (!version_entry) { + dev_dbg(component->dev, "%s: failed to create wcd938x version entry\n", + __func__); + return -ENOMEM; + } + + version_entry->private_data = priv; + version_entry->size = WCD938X_VERSION_ENTRY_SIZE; + version_entry->content = SNDRV_INFO_CONTENT_DATA; + version_entry->c.ops = &wcd938x_info_ops; + + if (snd_info_register(version_entry) < 0) { + snd_info_free_entry(version_entry); + return -ENOMEM; + } + priv->version_entry = version_entry; + + return 0; +} +EXPORT_SYMBOL(wcd938x_info_create_codec_entry); + +static int wcd938x_soc_codec_probe(struct snd_soc_component *component) +{ + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + int variant; + int ret = -EINVAL; + + dev_info(component->dev, "%s()\n", __func__); + wcd938x = snd_soc_component_get_drvdata(component); + + if (!wcd938x) + return -EINVAL; + + wcd938x->component = component; + snd_soc_component_init_regmap(component, wcd938x->regmap); + + variant = (snd_soc_component_read32(component, + WCD938X_DIGITAL_EFUSE_REG_0) & 0x1E) >> 1; + wcd938x->variant = variant; + + wcd938x->fw_data = devm_kzalloc(component->dev, + sizeof(*(wcd938x->fw_data)), + GFP_KERNEL); + if (!wcd938x->fw_data) { + dev_err(component->dev, "Failed to allocate fw_data\n"); + ret = -ENOMEM; + goto err; + } + + set_bit(WCD9XXX_MBHC_CAL, wcd938x->fw_data->cal_bit); + ret = wcd_cal_create_hwdep(wcd938x->fw_data, + WCD9XXX_CODEC_HWDEP_NODE, component); + + if (ret < 0) { + dev_err(component->dev, "%s hwdep failed %d\n", __func__, ret); + goto err_hwdep; + } + + ret = wcd938x_mbhc_init(&wcd938x->mbhc, component, wcd938x->fw_data); + if (ret) { + pr_err("%s: mbhc initialization failed\n", __func__); + goto err_hwdep; + } + + snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC4"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC5"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC6"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC7"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC1_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC2_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC3_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC4_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC5_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC6_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC7_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC8_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "ADC1_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "ADC2_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "ADC3_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "ADC4_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "IN1_HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "IN2_HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "IN3_AUX"); + snd_soc_dapm_ignore_suspend(dapm, "EAR"); + snd_soc_dapm_ignore_suspend(dapm, "AUX"); + snd_soc_dapm_ignore_suspend(dapm, "HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "HPHR"); + snd_soc_dapm_sync(dapm); + + wcd_cls_h_init(&wcd938x->clsh_info); + wcd938x_init_reg(component); + + wcd938x->version = WCD938X_VERSION_1_0; + /* Register event notifier */ + wcd938x->nblock.notifier_call = wcd938x_event_notify; + if (wcd938x->register_notifier) { + ret = wcd938x->register_notifier(wcd938x->handle, + &wcd938x->nblock, + true); + if (ret) { + dev_err(component->dev, + "%s: Failed to register notifier %d\n", + __func__, ret); + return ret; + } + } + return ret; + +err_hwdep: + wcd938x->fw_data = NULL; + +err: + return ret; +} + +static void wcd938x_soc_codec_remove(struct snd_soc_component *component) +{ + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + if (!wcd938x) { + dev_err(component->dev, "%s: wcd938x is already NULL\n", + __func__); + return; + } + if (wcd938x->register_notifier) + wcd938x->register_notifier(wcd938x->handle, + &wcd938x->nblock, + false); +} + +static struct snd_soc_component_driver soc_codec_dev_wcd938x = { + .name = WCD938X_DRV_NAME, + .probe = wcd938x_soc_codec_probe, + .remove = wcd938x_soc_codec_remove, + .controls = wcd938x_snd_controls, + .num_controls = ARRAY_SIZE(wcd938x_snd_controls), + .dapm_widgets = wcd938x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wcd938x_dapm_widgets), + .dapm_routes = wcd938x_audio_map, + .num_dapm_routes = ARRAY_SIZE(wcd938x_audio_map), +}; + +static int wcd938x_reset(struct device *dev) +{ + struct wcd938x_priv *wcd938x = NULL; + int rc = 0; + int value = 0; + + if (!dev) + return -ENODEV; + + wcd938x = dev_get_drvdata(dev); + if (!wcd938x) + return -EINVAL; + + if (!wcd938x->rst_np) { + dev_err(dev, "%s: reset gpio device node not specified\n", + __func__); + return -EINVAL; + } + + value = msm_cdc_pinctrl_get_state(wcd938x->rst_np); + if (value > 0) + return 0; + + rc = msm_cdc_pinctrl_select_sleep_state(wcd938x->rst_np); + if (rc) { + dev_err(dev, "%s: wcd sleep state request fail!\n", + __func__); + return rc; + } + /* 20us sleep required after pulling the reset gpio to LOW */ + usleep_range(20, 30); + + rc = msm_cdc_pinctrl_select_active_state(wcd938x->rst_np); + if (rc) { + dev_err(dev, "%s: wcd active state request fail!\n", + __func__); + return rc; + } + /* 20us sleep required after pulling the reset gpio to HIGH */ + usleep_range(20, 30); + + return rc; +} + +static int wcd938x_read_of_property_u32(struct device *dev, const char *name, + u32 *val) +{ + int rc = 0; + + rc = of_property_read_u32(dev->of_node, name, val); + if (rc) + dev_err(dev, "%s: Looking up %s property in node %s failed\n", + __func__, name, dev->of_node->full_name); + + return rc; +} + +static void wcd938x_dt_parse_micbias_info(struct device *dev, + struct wcd938x_micbias_setting *mb) +{ + u32 prop_val = 0; + int rc = 0; + + /* MB1 */ + if (of_find_property(dev->of_node, "qcom,cdc-micbias1-mv", + NULL)) { + rc = wcd938x_read_of_property_u32(dev, + "qcom,cdc-micbias1-mv", + &prop_val); + if (!rc) + mb->micb1_mv = prop_val; + } else { + dev_info(dev, "%s: Micbias1 DT property not found\n", + __func__); + } + + /* MB2 */ + if (of_find_property(dev->of_node, "qcom,cdc-micbias2-mv", + NULL)) { + rc = wcd938x_read_of_property_u32(dev, + "qcom,cdc-micbias2-mv", + &prop_val); + if (!rc) + mb->micb2_mv = prop_val; + } else { + dev_info(dev, "%s: Micbias2 DT property not found\n", + __func__); + } + + /* MB3 */ + if (of_find_property(dev->of_node, "qcom,cdc-micbias3-mv", + NULL)) { + rc = wcd938x_read_of_property_u32(dev, + "qcom,cdc-micbias3-mv", + &prop_val); + if (!rc) + mb->micb3_mv = prop_val; + } else { + dev_info(dev, "%s: Micbias3 DT property not found\n", + __func__); + } +} + +static int wcd938x_reset_low(struct device *dev) +{ + struct wcd938x_priv *wcd938x = NULL; + int rc = 0; + + if (!dev) + return -ENODEV; + + wcd938x = dev_get_drvdata(dev); + if (!wcd938x) + return -EINVAL; + + if (!wcd938x->rst_np) { + dev_err(dev, "%s: reset gpio device node not specified\n", + __func__); + return -EINVAL; + } + + rc = msm_cdc_pinctrl_select_sleep_state(wcd938x->rst_np); + if (rc) { + dev_err(dev, "%s: wcd sleep state request fail!\n", + __func__); + return rc; + } + /* 20us sleep required after pulling the reset gpio to LOW */ + usleep_range(20, 30); + + return rc; +} + +struct wcd938x_pdata *wcd938x_populate_dt_data(struct device *dev) +{ + struct wcd938x_pdata *pdata = NULL; + + pdata = devm_kzalloc(dev, sizeof(struct wcd938x_pdata), + GFP_KERNEL); + if (!pdata) + return NULL; + + pdata->rst_np = of_parse_phandle(dev->of_node, + "qcom,wcd-rst-gpio-node", 0); + + if (!pdata->rst_np) { + dev_err(dev, "%s: Looking up %s property in node %s failed\n", + __func__, "qcom,wcd-rst-gpio-node", + dev->of_node->full_name); + return NULL; + } + + /* Parse power supplies */ + msm_cdc_get_power_supplies(dev, &pdata->regulator, + &pdata->num_supplies); + if (!pdata->regulator || (pdata->num_supplies <= 0)) { + dev_err(dev, "%s: no power supplies defined for codec\n", + __func__); + return NULL; + } + + pdata->rx_slave = of_parse_phandle(dev->of_node, "qcom,rx-swr-slave", 0); + pdata->tx_slave = of_parse_phandle(dev->of_node, "qcom,tx-swr-slave", 0); + + wcd938x_dt_parse_micbias_info(dev, &pdata->micbias); + + return pdata; +} + +static int wcd938x_bind(struct device *dev) +{ + int ret = 0, i = 0; + struct wcd938x_pdata *pdata = dev_get_platdata(dev); + struct wcd938x_priv *wcd938x = dev_get_drvdata(dev); + + /* + * Add 5msec delay to provide sufficient time for + * soundwire auto enumeration of slave devices as + * as per HW requirement. + */ + usleep_range(5000, 5010); + + ret = component_bind_all(dev, wcd938x); + if (ret) { + dev_err(dev, "%s: Slave bind failed, ret = %d\n", + __func__, ret); + return ret; + } + + wcd938x->rx_swr_dev = get_matching_swr_slave_device(pdata->rx_slave); + if (!wcd938x->rx_swr_dev) { + dev_err(dev, "%s: Could not find RX swr slave device\n", + __func__); + ret = -ENODEV; + goto err; + } + + wcd938x->tx_swr_dev = get_matching_swr_slave_device(pdata->tx_slave); + if (!wcd938x->tx_swr_dev) { + dev_err(dev, "%s: Could not find TX swr slave device\n", + __func__); + ret = -ENODEV; + goto err; + } + + wcd938x->regmap = devm_regmap_init_swr(wcd938x->tx_swr_dev, + &wcd938x_regmap_config); + if (!wcd938x->regmap) { + dev_err(dev, "%s: Regmap init failed\n", + __func__); + goto err; + } + + /* Set all interupts as edge triggered */ + for (i = 0; i < wcd938x_regmap_irq_chip.num_regs; i++) + regmap_write(wcd938x->regmap, + (WCD938X_DIGITAL_INTR_LEVEL_0 + i), 0); + + wcd938x_regmap_irq_chip.irq_drv_data = wcd938x; + wcd938x->irq_info.wcd_regmap_irq_chip = &wcd938x_regmap_irq_chip; + wcd938x->irq_info.codec_name = "WCD938X"; + wcd938x->irq_info.regmap = wcd938x->regmap; + wcd938x->irq_info.dev = dev; + ret = wcd_irq_init(&wcd938x->irq_info, &wcd938x->virq); + + if (ret) { + dev_err(wcd938x->dev, "%s: IRQ init failed: %d\n", + __func__, ret); + goto err; + } + wcd938x->tx_swr_dev->slave_irq = wcd938x->virq; + + ret = snd_soc_register_component(dev, &soc_codec_dev_wcd938x, + NULL, 0); + if (ret) { + dev_err(dev, "%s: Codec registration failed\n", + __func__); + goto err_irq; + } + + return ret; +err_irq: + wcd_irq_exit(&wcd938x->irq_info, wcd938x->virq); +err: + component_unbind_all(dev, wcd938x); + return ret; +} + +static void wcd938x_unbind(struct device *dev) +{ + struct wcd938x_priv *wcd938x = dev_get_drvdata(dev); + + wcd_irq_exit(&wcd938x->irq_info, wcd938x->virq); + snd_soc_unregister_component(dev); + component_unbind_all(dev, wcd938x); +} + +static const struct of_device_id wcd938x_dt_match[] = { + { .compatible = "qcom,wcd938x-codec" }, + {} +}; + +static const struct component_master_ops wcd938x_comp_ops = { + .bind = wcd938x_bind, + .unbind = wcd938x_unbind, +}; + +static int wcd938x_compare_of(struct device *dev, void *data) +{ + return dev->of_node == data; +} + +static void wcd938x_release_of(struct device *dev, void *data) +{ + of_node_put(data); +} + +static int wcd938x_add_slave_components(struct device *dev, + struct component_match **matchptr) +{ + struct device_node *np, *rx_node, *tx_node; + + np = dev->of_node; + + rx_node = of_parse_phandle(np, "qcom,rx-swr-slave", 0); + if (!rx_node) { + dev_err(dev, "%s: Rx-slave node not defined\n", __func__); + return -ENODEV; + } + of_node_get(rx_node); + component_match_add_release(dev, matchptr, + wcd938x_release_of, + wcd938x_compare_of, + rx_node); + + tx_node = of_parse_phandle(np, "qcom,tx-swr-slave", 0); + if (!tx_node) { + dev_err(dev, "%s: Tx-slave node not defined\n", __func__); + return -ENODEV; + } + of_node_get(tx_node); + component_match_add_release(dev, matchptr, + wcd938x_release_of, + wcd938x_compare_of, + tx_node); + return 0; +} + +static int wcd938x_probe(struct platform_device *pdev) +{ + struct component_match *match = NULL; + struct wcd938x_priv *wcd938x = NULL; + struct wcd938x_pdata *pdata = NULL; + int ret; + + wcd938x = devm_kzalloc(&pdev->dev, sizeof(struct wcd938x_priv), + GFP_KERNEL); + if (!wcd938x) + return -ENOMEM; + + dev_set_drvdata(&pdev->dev, wcd938x); + + pdata = wcd938x_populate_dt_data(&pdev->dev); + if (!pdata) { + dev_err(&pdev->dev, "%s: Fail to obtain platform data\n", __func__); + return -EINVAL; + } + dev->platform_data = pdata; + + wcd938x->rst_np = pdata->rst_np; + ret = msm_cdc_init_supplies(&pdev->dev, &wcd938x->supplies, + pdata->regulator, pdata->num_supplies); + if (!wcd938x->supplies) { + dev_err(&pdev->dev, "%s: Cannot init wcd supplies\n", + __func__); + return ret; + } + + wcd938x->handle = (void *)pdata->handle; + if (!wcd938x->handle) { + dev_err(dev, "%s: handle is NULL\n", __func__); + return -EINVAL; + } + + wcd938x->update_wcd_event = pdata->update_wcd_event; + if (!wcd938x->update_wcd_event) { + dev_err(dev, "%s: update_wcd_event api is null!\n", + __func__); + return -EINVAL; + } + wcd938x->register_notifier = pdata->register_notifier; + if (!wcd938x->register_notifier) { + dev_err(dev, "%s: register_notifier api is null!\n", + __func__); + return -EINVAL; + } + + ret = msm_cdc_enable_static_supplies(&pdev->dev, wcd938x->supplies, + pdata->regulator, + pdata->num_supplies); + if (ret) { + dev_err(&pdev->dev, "%s: wcd static supply enable failed!\n", + __func__); + return ret; + } + + ret = wcd938x_parse_port_mapping(&pdev->dev, "qcom,rx_swr_ch_map", + CODEC_RX); + ret |= wcd938x_parse_port_mapping(&pdev->dev, "qcom,tx_swr_ch_map", + CODEC_TX); + + if (ret) { + dev_err(&pdev->dev, "Failed to read port mapping\n"); + goto err; + } + + ret = wcd938x_add_slave_components(&pdev->dev, &match); + if (ret) + goto err; + + wcd938x_reset(dev); + + return component_master_add_with_match(&pdev->dev, + &wcd938x_comp_ops, match); + +err: + return ret; +} + +static int wcd938x_remove(struct platform_device *pdev) +{ + component_master_del(&pdev->dev, &wcd938x_comp_ops); + dev_set_drvdata(&pdev->dev, NULL); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int wcd938x_suspend(struct device *dev) +{ + return 0; +} + +static int wcd938x_resume(struct device *dev) +{ + return 0; +} + +static const struct dev_pm_ops wcd938x_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS( + wcd938x_suspend, + wcd938x_resume + ) +}; +#endif + +static struct platform_driver wcd938x_codec_driver = { + .probe = wcd938x_probe, + .remove = wcd938x_remove, + .driver = { + .name = "wcd938x_codec", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(wcd938x_dt_match), +#ifdef CONFIG_PM_SLEEP + .pm = &wcd938x_dev_pm_ops, +#endif + }, +}; + +module_platform_driver(wcd938x_codec_driver); +MODULE_DESCRIPTION("WCD938X Codec driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 4d31c00084f0e7782dba4a61565cd30737b9c37a Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 7 Dec 2018 01:23:01 +0530 Subject: [PATCH 0713/1645] asoc: wcd938x: Move APIs from internal header file Move APIs from internal header file for access to other audio modules. Change-Id: Ib34d052e4beb63c6805abacc3c99dbff18c9af6c Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd938x/internal.h | 2 -- asoc/codecs/wcd938x/wcd938x.h | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 asoc/codecs/wcd938x/wcd938x.h diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index 4811bd0f4ad0..71528c71d6ad 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -177,6 +177,4 @@ extern int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component *component, extern int wcd938x_get_micb_vout_ctl_val(u32 micb_mv); extern int wcd938x_micbias_control(struct snd_soc_component *component, int micb_num, int req, bool is_dapm); -extern int wcd938x_info_create_codec_entry(struct snd_info_entry *codec_root, - struct snd_soc_component *component); #endif /* _WCD938X_INTERNAL_H */ diff --git a/asoc/codecs/wcd938x/wcd938x.h b/asoc/codecs/wcd938x/wcd938x.h new file mode 100644 index 000000000000..12b5f1a12686 --- /dev/null +++ b/asoc/codecs/wcd938x/wcd938x.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _WCD938X_H +#define _WCD938X_H + +#ifdef CONFIG_SND_SOC_WCD938X +extern int wcd938x_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_component *component); +#else +extern int wcd938x_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_component *component) +{ + return 0; +} +#endif /* CONFIG_SND_SOC_WCD938X */ +#endif /* _WCD938X_H */ -- GitLab From d1c3e9b51e0b7d36cb1d1cf339fa46ecdceb0b89 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 5 Sep 2018 05:43:51 +0530 Subject: [PATCH 0714/1645] ASoC: wcd938x: Add support for codec wakeup Add an API to wakeup codec from sleep. Change-Id: I90de653947f794cbc4a47a91bd5f22251440ef75 Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd938x/internal.h | 2 +- asoc/codecs/wcd938x/wcd938x.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index 71528c71d6ad..616a2eaff85e 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -79,7 +79,6 @@ struct wcd938x_priv { struct codec_port_info rx_port_mapping[MAX_PORT][MAX_CH_PER_PORT]; struct regulator_bulk_data *supplies; - struct notifier_block nblock; /* wcd callback to bolero */ void *handle; @@ -87,6 +86,7 @@ struct wcd938x_priv { int (*register_notifier)(void *handle, struct notifier_block *nblock, bool enable); + int (*wakeup)(void *handle, bool enable); u32 version; /* Entry for version info */ struct snd_info_entry *entry; diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 2905c59e19bc..40136e43181d 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -2578,6 +2578,25 @@ static int wcd938x_add_slave_components(struct device *dev, return 0; } +static int wcd938x_wakeup(void *handle, bool enable) +{ + struct wcd938x_priv *priv; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + priv = (struct wcd938x_priv *)handle; + if (!priv->tx_swr_dev) { + pr_err("%s: tx swr dev is NULL\n", __func__); + return -EINVAL; + } + if (enable) + return swr_device_wakeup_vote(priv->tx_swr_dev); + else + return swr_device_wakeup_unvote(priv->tx_swr_dev); +} + static int wcd938x_probe(struct platform_device *pdev) { struct component_match *match = NULL; @@ -2652,6 +2671,8 @@ static int wcd938x_probe(struct platform_device *pdev) wcd938x_reset(dev); + wcd938x->wakeup = wcd938x_wakeup; + return component_master_add_with_match(&pdev->dev, &wcd938x_comp_ops, match); -- GitLab From 5d9ea8df64b1d4bf39096d564683b5b424cfee53 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 28 Nov 2018 14:32:40 +0530 Subject: [PATCH 0715/1645] asoc: codecs: bolero: Update channel mask for ec_ref port For get_channel_map API, return proper channel mask and channel count for EC ref port on WSA macro. Change-Id: Ia90f1a1c5e90075d08f01c50349d6a8479be7897 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/wsa-macro.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index d761d942bd7b..48a42ac46531 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -47,6 +47,9 @@ #define WSA_MACRO_RX_PATH_CFG3_OFFSET 0x10 #define WSA_MACRO_RX_PATH_DSMDEM_OFFSET 0x4C #define WSA_MACRO_FS_RATE_MASK 0x0F +#define WSA_MACRO_EC_MIX_TX0_MASK 0x03 +#define WSA_MACRO_EC_MIX_TX1_MASK 0x18 + enum { WSA_MACRO_RX0 = 0, @@ -722,6 +725,7 @@ static int wsa_macro_get_channel_map(struct snd_soc_dai *dai, struct snd_soc_component *component = dai->component; struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; + u16 val = 0, mask = 0, cnt = 0; if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; @@ -732,7 +736,6 @@ static int wsa_macro_get_channel_map(struct snd_soc_dai *dai, switch (dai->id) { case WSA_MACRO_AIF_VI: - case WSA_MACRO_AIF_ECHO: *tx_slot = wsa_priv->active_ch_mask[dai->id]; *tx_num = wsa_priv->active_ch_cnt[dai->id]; break; @@ -741,6 +744,20 @@ static int wsa_macro_get_channel_map(struct snd_soc_dai *dai, *rx_slot = wsa_priv->active_ch_mask[dai->id]; *rx_num = wsa_priv->active_ch_cnt[dai->id]; break; + case WSA_MACRO_AIF_ECHO: + val = snd_soc_component_read32(component, + BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0); + if (val & WSA_MACRO_EC_MIX_TX1_MASK) { + mask |= 0x2; + cnt++; + } + if (val & WSA_MACRO_EC_MIX_TX0_MASK) { + mask |= 0x1; + cnt++; + } + *tx_slot = mask; + *tx_num = cnt; + break; default: dev_err(wsa_dev, "%s: Invalid AIF\n", __func__); break; @@ -1694,10 +1711,10 @@ static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w, BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0, 0x1 << ec_tx, 0x1 << ec_tx); ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL + - 0x20 * ec_tx; + 0x40 * ec_tx; snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01); ec_hq_reg = BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 + - 0x20 * ec_tx; + 0x40 * ec_tx; /* default set to 48k */ snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08); } -- GitLab From 64e8c2b2aff2f274ad9b8dd49a70d8e1f8834b6d Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 17 Dec 2018 18:55:51 +0800 Subject: [PATCH 0716/1645] asoc: wcd938x: update wcd938x driver Update wcd938x driver to fix compile error. Change-Id: Ifc939a46d7e09852b147289dd9e69d2f56a67751 Signed-off-by: Meng Wang --- asoc/codecs/wcd938x/internal.h | 1 + asoc/codecs/wcd938x/wcd938x.c | 60 ++++++++++++++++++++-------------- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index 616a2eaff85e..ea1ff234d00b 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -8,6 +8,7 @@ #include #include +#include #include "wcd938x-mbhc.h" #define WCD938X_MAX_MICBIAS 4 diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 40136e43181d..87668313bd85 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -87,7 +87,6 @@ static struct regmap_irq_chip wcd938x_regmap_irq_chip = { .type_base = WCD938X_DIGITAL_INTR_LEVEL_0, .ack_base = WCD938X_DIGITAL_INTR_CLEAR_0, .use_ack = 1, - .clear_ack = 1, .runtime_pm = true, .handle_post_irq = wcd938x_handle_post_irq, .irq_drv_data = NULL, @@ -161,7 +160,7 @@ static int wcd938x_set_port_params(struct snd_soc_component *component, for (i = 0; i <= num_ports; i++) { for (j = 0; j < MAX_CH_PER_PORT; j++) { - if ((*map)[i][j].port_type == slv_prt_type) + if ((*map)[i][j].slave_port_type == slv_prt_type) goto found; } } @@ -236,7 +235,7 @@ static int wcd938x_parse_port_mapping(struct device *dev, if (port_num != old_port_num) ch_iter = 0; - (*map)[port_num][ch_iter].port_type = slave_port_type; + (*map)[port_num][ch_iter].slave_port_type = slave_port_type; (*map)[port_num][ch_iter].ch_mask = ch_mask; (*map)[port_num][ch_iter].master_port_type = master_port_type; (*map)[port_num][ch_iter].num_ch = __sw_hweight8(ch_mask); @@ -405,7 +404,7 @@ static int wcd938x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, WCD938X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x02); /* 5msec compander delay as per HW requirement */ if (!wcd938x->comp2_enable || - (snd_soc_component_read(component, + (snd_soc_component_read32(component, WCD938X_DIGITAL_CDC_COMP_CTL_0) & 0x01)) usleep_range(5000, 5010); snd_soc_component_update_bits(component, @@ -457,7 +456,7 @@ static int wcd938x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, WCD938X_DIGITAL_CDC_COMP_CTL_0, 0x01, 0x01); /* 5msec compander delay as per HW requirement */ if (!wcd938x->comp1_enable || - (snd_soc_component_read(component, + (snd_soc_component_read32(component, WCD938X_DIGITAL_CDC_COMP_CTL_0) & 0x02)) usleep_range(5000, 5010); snd_soc_component_update_bits(component, @@ -615,7 +614,7 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, &wcd938x->mbhc->wcd_mbhc); snd_soc_component_update_bits(component, WCD938X_ANA_HPH, 0x10, 0x00); - wcd_cls_h_fsm(component, &wcd93x->clsh_info, + wcd_cls_h_fsm(component, &wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_HPHR, hph_mode); @@ -1342,7 +1341,7 @@ static int wcd938x_event_notify(struct notifier_block *block, if (amic == 0x1 || amic == 0x2) reg = WCD938X_ANA_TX_CH2; else if (amic == 0x3) - reg = WCD938X_ANA_TX_CH3_HPF; + reg = WCD938X_ANA_TX_CH4; else return 0; if (amic == 0x2) @@ -1377,8 +1376,9 @@ static int wcd938x_event_notify(struct notifier_block *block, } break; case BOLERO_WCD_EVT_CLK_NOTIFY: - snd_soc_update_bits(codec, WCD938X_DIGITAL_TOP_CLK_CFG, 0x06, - ((val >> 0x10) << 0x01)); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_TOP_CLK_CFG, 0x06, + ((val >> 0x10) << 0x01)); break; default: dev_dbg(component->dev, "%s: invalid event %d\n", __func__, event); @@ -1547,7 +1547,7 @@ static int wcd938x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, pdata->num_supplies, "cdc-vdd-buck"); if (ret == -EINVAL) { - dev_err(dev, "%s: vdd buck is not disabled\n", + dev_err(component->dev, "%s: vdd buck is not disabled\n", __func__); return 0; } @@ -2149,6 +2149,8 @@ EXPORT_SYMBOL(wcd938x_info_create_codec_entry); static int wcd938x_soc_codec_probe(struct snd_soc_component *component) { struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); int variant; int ret = -EINVAL; @@ -2602,44 +2604,52 @@ static int wcd938x_probe(struct platform_device *pdev) struct component_match *match = NULL; struct wcd938x_priv *wcd938x = NULL; struct wcd938x_pdata *pdata = NULL; + struct wcd_ctrl_platform_data *plat_data = NULL; + struct device *dev = &pdev->dev; int ret; - wcd938x = devm_kzalloc(&pdev->dev, sizeof(struct wcd938x_priv), + wcd938x = devm_kzalloc(dev, sizeof(struct wcd938x_priv), GFP_KERNEL); if (!wcd938x) return -ENOMEM; - dev_set_drvdata(&pdev->dev, wcd938x); + dev_set_drvdata(dev, wcd938x); - pdata = wcd938x_populate_dt_data(&pdev->dev); + pdata = wcd938x_populate_dt_data(dev); if (!pdata) { - dev_err(&pdev->dev, "%s: Fail to obtain platform data\n", __func__); + dev_err(dev, "%s: Fail to obtain platform data\n", __func__); return -EINVAL; } dev->platform_data = pdata; wcd938x->rst_np = pdata->rst_np; - ret = msm_cdc_init_supplies(&pdev->dev, &wcd938x->supplies, + ret = msm_cdc_init_supplies(dev, &wcd938x->supplies, pdata->regulator, pdata->num_supplies); if (!wcd938x->supplies) { - dev_err(&pdev->dev, "%s: Cannot init wcd supplies\n", + dev_err(dev, "%s: Cannot init wcd supplies\n", __func__); return ret; } - wcd938x->handle = (void *)pdata->handle; + plat_data = dev_get_platdata(dev->parent); + if (!plat_data) { + dev_err(dev, "%s: platform data from parent is NULL\n", + __func__); + return -EINVAL; + } + wcd938x->handle = (void *)plat_data->handle; if (!wcd938x->handle) { dev_err(dev, "%s: handle is NULL\n", __func__); return -EINVAL; } - wcd938x->update_wcd_event = pdata->update_wcd_event; + wcd938x->update_wcd_event = plat_data->update_wcd_event; if (!wcd938x->update_wcd_event) { dev_err(dev, "%s: update_wcd_event api is null!\n", __func__); return -EINVAL; } - wcd938x->register_notifier = pdata->register_notifier; + wcd938x->register_notifier = plat_data->register_notifier; if (!wcd938x->register_notifier) { dev_err(dev, "%s: register_notifier api is null!\n", __func__); @@ -2650,22 +2660,22 @@ static int wcd938x_probe(struct platform_device *pdev) pdata->regulator, pdata->num_supplies); if (ret) { - dev_err(&pdev->dev, "%s: wcd static supply enable failed!\n", + dev_err(dev, "%s: wcd static supply enable failed!\n", __func__); return ret; } - ret = wcd938x_parse_port_mapping(&pdev->dev, "qcom,rx_swr_ch_map", + ret = wcd938x_parse_port_mapping(dev, "qcom,rx_swr_ch_map", CODEC_RX); - ret |= wcd938x_parse_port_mapping(&pdev->dev, "qcom,tx_swr_ch_map", + ret |= wcd938x_parse_port_mapping(dev, "qcom,tx_swr_ch_map", CODEC_TX); if (ret) { - dev_err(&pdev->dev, "Failed to read port mapping\n"); + dev_err(dev, "Failed to read port mapping\n"); goto err; } - ret = wcd938x_add_slave_components(&pdev->dev, &match); + ret = wcd938x_add_slave_components(dev, &match); if (ret) goto err; @@ -2673,7 +2683,7 @@ static int wcd938x_probe(struct platform_device *pdev) wcd938x->wakeup = wcd938x_wakeup; - return component_master_add_with_match(&pdev->dev, + return component_master_add_with_match(dev, &wcd938x_comp_ops, match); err: -- GitLab From 3d1596e2c60f1bc1be2e7719e437451262b48f12 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 27 Oct 2018 06:19:18 +0530 Subject: [PATCH 0717/1645] soc: swr-mstr: Add support for platform specific port configuration Different platforms have different configuration for soundwire ports. Add support to get the port configuration information from the machine driver. Change-Id: If2c006c4d4a43e2a8dc67c076f6d1c0f36eae16b Signed-off-by: Sudheer Papothi --- include/soc/swr-common.h | 45 +++++++++++++++++++++++++ include/soc/swr-wcd.h | 1 + soc/swr-mstr-ctrl.c | 72 +++++++++++++++++++++++++++++++++++++++- soc/swr-mstr-ctrl.h | 15 ++------- 4 files changed, 120 insertions(+), 13 deletions(-) create mode 100644 include/soc/swr-common.h diff --git a/include/soc/swr-common.h b/include/soc/swr-common.h new file mode 100644 index 000000000000..92b79c79a9fb --- /dev/null +++ b/include/soc/swr-common.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved. + */ + +#ifndef _LINUX_SWR_COMMON_H +#define _LINUX_SWR_COMMON_H +#include +#include +#include +#include + +enum { + SWR_UC0 = 0, + SWR_UC1, + SWR_UC_MAX, +}; + +struct port_params { + u8 si; + u8 off1; + u8 off2; + u8 hstart;/* head start */ + u8 hstop; /* head stop */ + u8 wd_len;/* word length */ + u8 bp_mode; /* block pack mode */ + u8 bgp_ctrl;/* block group control */ + u8 lane_ctrl;/* lane to be used */ +}; + +struct swrm_port_config { + u32 size; + u32 uc; + void *params; +}; + +struct swr_mstr_port_map { + u32 id; + u32 uc; + struct port_params *swr_port_params; +}; + +#define SWR_MSTR_PORT_LEN 8 /* Number of master ports */ + +#endif /* _LINUX_SWR_COMMON_H */ diff --git a/include/soc/swr-wcd.h b/include/soc/swr-wcd.h index 0f1762545e73..ad129c832700 100644 --- a/include/soc/swr-wcd.h +++ b/include/soc/swr-wcd.h @@ -20,6 +20,7 @@ enum { SWR_DEVICE_SSR_DOWN, SWR_DEVICE_SSR_UP, SWR_REGISTER_WAKE_IRQ, + SWR_SET_PORT_MAP, }; struct swr_mstr_port { diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 26433539ea5c..2379df88b837 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include "swrm_registers.h" @@ -28,6 +28,7 @@ #define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700 #define SWRM_SYS_SUSPEND_WAIT 1 + #define SWR_BROADCAST_CMD_ID 0x0F #define SWR_AUTO_SUSPEND_DELAY 3 /* delay in sec */ #define SWR_DEV_ID_MASK 0xFFFFFFFFFFFF @@ -2187,6 +2188,53 @@ int swrm_register_wake_irq(struct swr_mstr_ctrl *swrm) return ret; } +static int swrm_alloc_port_mem(struct device *dev, struct swr_mstr_ctrl *swrm, + u32 uc, u32 size) +{ + if (!swrm->port_param) { + swrm->port_param = devm_kzalloc(dev, + sizeof(swrm->port_param) * SWR_UC_MAX, + GFP_KERNEL); + if (!swrm->port_param) + return -ENOMEM; + } + if (!swrm->port_param[uc]) { + swrm->port_param[uc] = devm_kcalloc(dev, size, + sizeof(struct port_params), + GFP_KERNEL); + if (!swrm->port_param[uc]) + return -ENOMEM; + } else { + dev_err_ratelimited(swrm->dev, "%s: called more than once\n", + __func__); + } + + return 0; +} + +static int swrm_copy_port_config(struct swr_mstr_ctrl *swrm, + struct swrm_port_config *port_cfg, + u32 size) +{ + int idx; + struct port_params *params; + int uc = port_cfg->uc; + int ret = 0; + + for (idx = 0; idx < size; idx++) { + params = &((struct port_params *)port_cfg->params)[idx]; + if (!params) { + dev_err(swrm->dev, "%s: Invalid params\n", __func__); + ret = -EINVAL; + break; + } + memcpy(&swrm->port_param[uc][idx], params, + sizeof(struct port_params)); + } + + return ret; +} + /** * swrm_wcd_notify - parent device can notify to soundwire master through * this function @@ -2200,6 +2248,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) int ret = 0; struct swr_master *mstr; struct swr_device *swr_dev; + struct swrm_port_config *port_cfg; if (!pdev) { pr_err("%s: pdev is NULL\n", __func__); @@ -2327,6 +2376,27 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) mutex_unlock(&swrm->mlock); } break; + case SWR_SET_PORT_MAP: + if (!data) { + dev_err(swrm->dev, "%s: data is NULL for id=%d\n", + __func__, id); + ret = -EINVAL; + } else { + mutex_lock(&swrm->mlock); + port_cfg = (struct swrm_port_config *)data; + if (!port_cfg->size) { + ret = -EINVAL; + goto done; + } + ret = swrm_alloc_port_mem(&pdev->dev, swrm, + port_cfg->uc, port_cfg->size); + if (!ret) + swrm_copy_port_config(swrm, port_cfg, + port_cfg->size); +done: + mutex_unlock(&swrm->mlock); + } + break; default: dev_err(swrm->dev, "%s: swr master unknown id %d\n", __func__, id); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 8582c51ea96c..afbbe4682932 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -9,6 +9,7 @@ #include #include #include +#include #define SWR_ROW_48 0 #define SWR_ROW_50 1 @@ -61,18 +62,6 @@ struct usecase { u32 chrate; }; -struct port_params { - u8 si; - u8 off1; - u8 off2; - u8 hstart;/* head start */ - u8 hstop; /* head stop */ - u8 wd_len;/* word length */ - u8 bp_mode; /* block pack mode */ - u8 bgp_ctrl;/* block group control */ - u8 lane_ctrl;/* lane to be used */ -}; - struct swrm_mports { struct list_head port_req_list; bool port_en; @@ -163,6 +152,8 @@ struct swr_mstr_ctrl { wait_queue_head_t pm_wq; int wlock_holders; u32 intr_mask; + struct port_params **port_param; + u8 num_usecase; }; #endif /* _SWR_WCD_CTRL_H */ -- GitLab From a3e969d6f0e7ed1ad68b520884df125103971c2a Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 27 Oct 2018 06:22:10 +0530 Subject: [PATCH 0718/1645] ASoC: bolero: Add support to retrieve soundwire port configuration Add support to get the platform specific soundwire port configuration for soundwire master ports. Change-Id: Ie1d32a77d534f6c3f397936b85c025b14d01f321 Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/bolero-cdc.c | 37 +++++++++++++++++++++++++++++++++ asoc/codecs/bolero/bolero-cdc.h | 14 +++++++++++++ asoc/codecs/bolero/rx-macro.c | 25 ++++++++++++++++++++++ asoc/codecs/bolero/tx-macro.c | 25 ++++++++++++++++++++++ asoc/codecs/bolero/wsa-macro.c | 25 ++++++++++++++++++++++ 5 files changed, 126 insertions(+) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index aec455a3628b..14a0defeb97d 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "bolero-cdc.h" #include "internal.h" @@ -37,6 +38,41 @@ static u16 bolero_mclk_mux_tbl[MAX_MACRO][MCLK_MUX_MAX] = { {TX_MACRO, VA_MACRO}, }; +static bool bolero_is_valid_codec_dev(struct device *dev); + +int bolero_set_port_map(struct snd_soc_component *component, + u32 size, void *data) +{ + struct bolero_priv *priv = NULL; + struct swr_mstr_port_map *map = NULL; + u16 idx; + + if (!component || (size == 0) || !data) + return -EINVAL; + + priv = snd_soc_component_get_drvdata(component); + if (!priv) + return -EINVAL; + + if (!bolero_is_valid_codec_dev(priv->dev)) { + dev_err(priv->dev, "%s: invalid codec\n", __func__); + return -EINVAL; + } + map = (struct swr_mstr_port_map *)data; + + for (idx = 0; idx < size; idx++) { + if (priv->macro_params[map->id].set_port_map) + priv->macro_params[map->id].set_port_map(component, + map->uc, + SWR_MSTR_PORT_LEN, + map->swr_port_params); + map += 1; + } + + return 0; +} +EXPORT_SYMBOL(bolero_set_port_map); + static void bolero_ahb_write_device(char __iomem *io_base, u16 reg, u8 value) { @@ -350,6 +386,7 @@ int bolero_register_macro(struct device *dev, u16 macro_id, priv->macro_params[macro_id].dai_ptr = ops->dai_ptr; priv->macro_params[macro_id].mclk_fn = ops->mclk_fn; priv->macro_params[macro_id].event_handler = ops->event_handler; + priv->macro_params[macro_id].set_port_map = ops->set_port_map; priv->macro_params[macro_id].dev = dev; priv->current_mclk_mux_macro[macro_id] = bolero_mclk_mux_tbl[macro_id][MCLK_MUX0]; diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 488ccf7eb506..524225e795dd 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -51,6 +51,8 @@ struct macro_ops { int (*event_handler)(struct snd_soc_component *component, u16 event, u32 data); int (*reg_wake_irq)(struct snd_soc_component *component, u32 data); + int (*set_port_map)(struct snd_soc_component *component, u32 uc, + u32 size, void *data); char __iomem *io_base; }; @@ -69,6 +71,7 @@ int bolero_register_wake_irq(struct snd_soc_component *component, u32 data); void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n); int bolero_runtime_resume(struct device *dev); int bolero_runtime_suspend(struct device *dev); +int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *data); #else static inline int bolero_register_macro(struct device *dev, u16 macro_id, @@ -107,13 +110,24 @@ static inline void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n) static inline int bolero_register_wake_irq(struct snd_soc_component *component, u32 data) +{ + return 0; +} + static inline int bolero_runtime_resume(struct device *dev) { return 0; } + static int bolero_runtime_suspend(struct device *dev) { return 0; } + +static inline int bolero_set_port_map(struct snd_soc_component *component, + u32 size, void *data) +{ + return 0; +} #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index ff8684f7170b..db01461ead69 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "bolero-cdc.h" @@ -701,6 +702,29 @@ static bool rx_macro_get_data(struct snd_soc_component *component, return true; } +static int rx_macro_set_port_map(struct snd_soc_component *component, + u32 usecase, u32 size, void *data) +{ + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + struct swrm_port_config port_cfg; + int ret = 0; + + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + memset(&port_cfg, 0, sizeof(port_cfg)); + port_cfg.uc = usecase; + port_cfg.size = size; + port_cfg.params = data; + + ret = swrm_wcd_notify( + rx_priv->swr_ctrl_data[0].rx_swr_pdev, + SWR_SET_PORT_MAP, &port_cfg); + + return ret; +} + static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -3366,6 +3390,7 @@ static void rx_macro_init_ops(struct macro_ops *ops, char __iomem *rx_io_base) ops->num_dais = ARRAY_SIZE(rx_macro_dai); ops->mclk_fn = rx_macro_mclk_ctrl; ops->event_handler = rx_macro_event_handler; + ops->set_port_map = rx_macro_set_port_map; } static int rx_macro_probe(struct platform_device *pdev) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index c33a857acbaa..2cb0714ef9d2 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "bolero-cdc.h" #include "bolero-cdc-registers.h" @@ -1709,6 +1710,29 @@ static void tx_macro_add_child_devices(struct work_struct *work) return; } +static int tx_macro_set_port_map(struct snd_soc_component *component, + u32 usecase, u32 size, void *data) +{ + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + struct swrm_port_config port_cfg; + int ret = 0; + + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + memset(&port_cfg, 0, sizeof(port_cfg)); + port_cfg.uc = usecase; + port_cfg.size = size; + port_cfg.params = data; + + ret = swrm_wcd_notify( + tx_priv->swr_ctrl_data[0].tx_swr_pdev, + SWR_SET_PORT_MAP, &port_cfg); + + return ret; +} + static void tx_macro_init_ops(struct macro_ops *ops, char __iomem *tx_io_base) { @@ -1721,6 +1745,7 @@ static void tx_macro_init_ops(struct macro_ops *ops, ops->mclk_fn = tx_macro_mclk_ctrl; ops->event_handler = tx_macro_event_handler; ops->reg_wake_irq = tx_macro_reg_wake_irq; + ops->set_port_map = tx_macro_set_port_map; } static int tx_macro_probe(struct platform_device *pdev) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 48a42ac46531..d9facd823080 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "bolero-cdc.h" @@ -452,6 +453,29 @@ static bool wsa_macro_get_data(struct snd_soc_component *component, return true; } +static int wsa_macro_set_port_map(struct snd_soc_component *component, + u32 usecase, u32 size, void *data) +{ + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + struct swrm_port_config port_cfg; + int ret = 0; + + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + memset(&port_cfg, 0, sizeof(port_cfg)); + port_cfg.uc = usecase; + port_cfg.size = size; + port_cfg.params = data; + + ret = swrm_wcd_notify( + wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, + SWR_SET_PORT_MAP, &port_cfg); + + return ret; +} + /** * wsa_macro_set_spkr_gain_offset - offset the speaker path * gain with the given offset value. @@ -2770,6 +2794,7 @@ static void wsa_macro_init_ops(struct macro_ops *ops, ops->num_dais = ARRAY_SIZE(wsa_macro_dai); ops->mclk_fn = wsa_macro_mclk_ctrl; ops->event_handler = wsa_macro_event_handler; + ops->set_port_map = wsa_macro_set_port_map; } static int wsa_macro_probe(struct platform_device *pdev) -- GitLab From 4c322b1c80b1c7f583c421c15c7d6a8773fa5d16 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 31 Oct 2018 06:34:01 +0530 Subject: [PATCH 0719/1645] Soundwire: Fix soundwire master port configuration Existing soundwire master controller driver uses static tables directly for soundwire port configuration. But, this is not scalable to add support for new targets. So, define platform specific soundwire master port configuration from machine driver. Change-Id: I37d499c77914b413e6e16ab2689dbaae8fcd194c Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 28 ++++++++--------------- soc/swrm_port_config.h | 51 ------------------------------------------ 2 files changed, 9 insertions(+), 70 deletions(-) delete mode 100644 soc/swrm_port_config.h diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 2379df88b837..fd77cf59dffa 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -24,11 +24,12 @@ #include #include "swrm_registers.h" #include "swr-mstr-ctrl.h" -#include "swrm_port_config.h" #define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700 #define SWRM_SYS_SUSPEND_WAIT 1 +#define SWRM_DSD_PARAMS_PORT 4 + #define SWR_BROADCAST_CMD_ID 0x0F #define SWR_AUTO_SUSPEND_DELAY 3 /* delay in sec */ #define SWR_DEV_ID_MASK 0xFFFFFFFFFFFF @@ -378,27 +379,16 @@ static void copy_port_tables(struct swr_mstr_ctrl *swrm, static int swrm_get_port_config(struct swr_mstr_ctrl *swrm) { struct port_params *params; + u32 usecase = 0; - switch (swrm->master_id) { - case MASTER_ID_WSA: - params = wsa_frame_superset; - break; - case MASTER_ID_RX: - /* Two RX tables for dsd and without dsd enabled */ - if (swrm->mport_cfg[4].port_en) - params = rx_frame_params_dsd; - else - params = rx_frame_params; - break; - case MASTER_ID_TX: - params = tx_frame_params_superset; - break; - default: /* MASTER_GENERIC*/ - /* computer generic frame parameters */ - return -EINVAL; - } + /* TODO - Send usecase information to avoid checking for master_id */ + if (swrm->mport_cfg[SWRM_DSD_PARAMS_PORT].port_en && + (swrm->master_id == MASTER_ID_RX)) + usecase = 1; + params = swrm->port_param[usecase]; copy_port_tables(swrm, params); + return 0; } diff --git a/soc/swrm_port_config.h b/soc/swrm_port_config.h deleted file mode 100644 index 0458696380eb..000000000000 --- a/soc/swrm_port_config.h +++ /dev/null @@ -1,51 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. - */ - -#ifndef _SWRM_PORT_CONFIG -#define _SWRM_PORT_CONFIG - -#define WSA_MSTR_PORT_MASK 0xFF - - -/* - * Add port configuration in the format - *{ si, off1, off2, hstart, hstop, wd_len, bp_mode, bgp_ctrl, lane_ctrl} - */ - -struct port_params wsa_frame_superset[SWR_MSTR_PORT_LEN] = { - {7, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - {31, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - {63, 12, 31, 0xFF, 0xFF, 0xFF, 0x1, 0xFF, 0xFF}, - {7, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - {31, 18, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - {63, 13, 31, 0xFF, 0xFF, 0xFF, 0x1, 0xFF, 0xFF}, - {15, 7, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - {15, 10, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, -}; - -struct port_params rx_frame_params[SWR_MSTR_PORT_LEN] = { - {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1}, - {31, 0, 0, 3, 6, 7, 0, 0xFF, 0}, - {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0}, - {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0}, - {0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0}, -}; - -struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = { - {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1}, - {31, 0, 0, 3, 6, 7, 0, 0xFF, 0}, - {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0}, - {7, 9, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0}, - {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 3, 0}, -}; - -struct port_params tx_frame_params_superset[SWR_MSTR_PORT_LEN] = { - {1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, - {1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, - {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, - {3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, -}; - -#endif /* _SWRM_REGISTERS_H */ -- GitLab From d61f0a4c25fcce25b63a896da0a743c74e8f05ef Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 14 Nov 2018 06:00:33 +0530 Subject: [PATCH 0720/1645] ASoC: sm8250: Add soundwire port configuration Add soundwire port configuration for sm8250 target. Change-Id: Id9554c1075d07adb2258a7450453032185f17e01 Signed-off-by: Sudheer Papothi --- asoc/sm8250-port-config.h | 58 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 asoc/sm8250-port-config.h diff --git a/asoc/sm8250-port-config.h b/asoc/sm8250-port-config.h new file mode 100644 index 000000000000..0f8c3c1b0722 --- /dev/null +++ b/asoc/sm8250-port-config.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _SM8250_PORT_CONFIG +#define _SM8250_PORT_CONFIG + +#include + +#define WSA_MSTR_PORT_MASK 0xFF +/* + * Add port configuration in the format + *{ si, off1, off2, hstart, hstop, wd_len, bp_mode, bgp_ctrl, lane_ctrl} + */ + +static struct port_params wsa_frame_params_default[SWR_MSTR_PORT_LEN] = { + {7, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {31, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {63, 12, 31, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {7, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {31, 18, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {63, 13, 31, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {15, 7, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {15, 10, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, +}; + +static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = { + {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1}, + {31, 0, 0, 3, 6, 7, 0, 0xFF, 0}, + {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0}, + {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0}, + {0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0}, +}; + +static struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = { + {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1}, + {31, 0, 0, 3, 6, 7, 0, 0xFF, 0}, + {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0}, + {7, 9, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0}, + {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 3, 0}, +}; + +/* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */ +static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = { + {1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX1 */ + {1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, /* TX2 */ + {3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX3 */ +}; + +static struct swr_mstr_port_map sm_port_map[] = { + {TX_MACRO, SWR_UC0, tx_frame_params_default}, + {RX_MACRO, SWR_UC0, rx_frame_params_default}, + {RX_MACRO, SWR_UC1, rx_frame_params_dsd}, + {WSA_MACRO, SWR_UC0, wsa_frame_params_default}, +}; + +#endif /* _SM8250_PORT_CONFIG */ -- GitLab From 11a25cf657508ce4f17098dc346901f8a6ab4d63 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 31 Oct 2018 14:11:26 +0800 Subject: [PATCH 0721/1645] asoc: update relative header files Move all relative header files to include folder. Change-Id: Ic61a61a88823b4749dbe8c1f680d08201a3b4a48 Signed-off-by: Meng Wang --- asoc/codecs/aqt1000/aqt1000-core.c | 4 ++-- asoc/codecs/aqt1000/aqt1000-mbhc.c | 4 ++-- asoc/codecs/aqt1000/aqt1000-mbhc.h | 2 +- asoc/codecs/aqt1000/aqt1000.c | 2 +- asoc/codecs/aqt1000/pdata.h | 2 +- asoc/codecs/bolero/rx-macro.c | 2 +- asoc/codecs/bolero/tx-macro.c | 2 +- asoc/codecs/bolero/wsa-macro.c | 2 +- asoc/codecs/msm-cdc-pinctrl.c | 4 ++-- asoc/codecs/msm-cdc-supply.c | 2 +- asoc/codecs/wcd-clsh.c | 2 +- asoc/codecs/wcd-mbhc-adc.c | 4 ++-- asoc/codecs/wcd-mbhc-adc.h | 4 ++-- asoc/codecs/wcd-mbhc-legacy.c | 2 +- asoc/codecs/wcd-mbhc-legacy.h | 6 +++--- asoc/codecs/wcd-mbhc-v2.c | 6 +++--- asoc/codecs/wcd9335-regmap.c | 6 +++--- asoc/codecs/wcd9335.c | 16 ++++++++-------- asoc/codecs/wcd9335.h | 4 ++-- asoc/codecs/wcd934x/wcd934x-dsp-cntl.c | 4 ++-- asoc/codecs/wcd934x/wcd934x-mbhc.c | 10 +++++----- asoc/codecs/wcd934x/wcd934x-mbhc.h | 2 +- asoc/codecs/wcd934x/wcd934x-regmap.c | 4 ++-- asoc/codecs/wcd934x/wcd934x.c | 12 ++++++------ asoc/codecs/wcd934x/wcd934x.h | 6 +++--- asoc/codecs/wcd937x/internal.h | 6 +++--- asoc/codecs/wcd937x/wcd937x-mbhc.c | 4 ++-- asoc/codecs/wcd937x/wcd937x-mbhc.h | 2 +- asoc/codecs/wcd937x/wcd937x.c | 6 +++--- asoc/codecs/wcd9xxx-common-v2.c | 4 ++-- asoc/codecs/wcd9xxx-core-init.c | 8 ++++---- asoc/codecs/wcd9xxx-core.c | 14 +++++++------- asoc/codecs/wcd9xxx-irq.c | 4 ++-- asoc/codecs/wcd9xxx-resmgr-v2.c | 4 ++-- asoc/codecs/wcd9xxx-rst.c | 4 ++-- asoc/codecs/wcd9xxx-slimslave.c | 4 ++-- asoc/codecs/wcd9xxx-utils.c | 10 +++++----- asoc/codecs/wcd_cpe_core.c | 4 ++-- asoc/codecs/wcd_cpe_services.c | 2 +- asoc/codecs/wcdcal-hwdep.c | 2 +- asoc/codecs/wsa881x.c | 2 +- asoc/msm-dai-q6-v2.c | 2 +- asoc/qcs405.c | 2 +- asoc/sm6150.c | 2 +- asoc/sm8150.c | 4 ++-- {asoc/codecs => include/asoc}/core.h | 0 {asoc/codecs => include/asoc}/cpe_core.h | 0 {asoc/codecs => include/asoc}/msm-cdc-pinctrl.h | 0 {asoc/codecs => include/asoc}/msm-cdc-supply.h | 0 {asoc/codecs => include/asoc}/pdata.h | 0 {asoc/codecs => include/asoc}/wcd-clsh.h | 0 {asoc/codecs => include/asoc}/wcd-mbhc-v2-api.h | 0 {asoc/codecs => include/asoc}/wcd-mbhc-v2.h | 0 .../codecs => include/asoc}/wcd9xxx-common-v2.h | 0 {asoc/codecs => include/asoc}/wcd9xxx-irq.h | 0 {asoc/codecs => include/asoc}/wcd9xxx-regmap.h | 0 .../codecs => include/asoc}/wcd9xxx-resmgr-v2.h | 0 .../codecs => include/asoc}/wcd9xxx-slimslave.h | 0 {asoc/codecs => include/asoc}/wcdcal-hwdep.h | 0 59 files changed, 102 insertions(+), 102 deletions(-) rename {asoc/codecs => include/asoc}/core.h (100%) rename {asoc/codecs => include/asoc}/cpe_core.h (100%) rename {asoc/codecs => include/asoc}/msm-cdc-pinctrl.h (100%) rename {asoc/codecs => include/asoc}/msm-cdc-supply.h (100%) rename {asoc/codecs => include/asoc}/pdata.h (100%) rename {asoc/codecs => include/asoc}/wcd-clsh.h (100%) rename {asoc/codecs => include/asoc}/wcd-mbhc-v2-api.h (100%) rename {asoc/codecs => include/asoc}/wcd-mbhc-v2.h (100%) rename {asoc/codecs => include/asoc}/wcd9xxx-common-v2.h (100%) rename {asoc/codecs => include/asoc}/wcd9xxx-irq.h (100%) rename {asoc/codecs => include/asoc}/wcd9xxx-regmap.h (100%) rename {asoc/codecs => include/asoc}/wcd9xxx-resmgr-v2.h (100%) rename {asoc/codecs => include/asoc}/wcd9xxx-slimslave.h (100%) rename {asoc/codecs => include/asoc}/wcdcal-hwdep.h (100%) diff --git a/asoc/codecs/aqt1000/aqt1000-core.c b/asoc/codecs/aqt1000/aqt1000-core.c index e5562a4d3001..7b4efa1a0082 100644 --- a/asoc/codecs/aqt1000/aqt1000-core.c +++ b/asoc/codecs/aqt1000/aqt1000-core.c @@ -19,8 +19,8 @@ #include #include #include -#include "../msm-cdc-pinctrl.h" -#include "../msm-cdc-supply.h" +#include +#include #include "aqt1000-registers.h" #include "aqt1000-internal.h" #include "aqt1000.h" diff --git a/asoc/codecs/aqt1000/aqt1000-mbhc.c b/asoc/codecs/aqt1000/aqt1000-mbhc.c index 66449b2db3f9..33a7c974cd7c 100644 --- a/asoc/codecs/aqt1000/aqt1000-mbhc.c +++ b/asoc/codecs/aqt1000/aqt1000-mbhc.c @@ -21,8 +21,8 @@ #include "aqt1000-registers.h" #include "aqt1000-irq.h" #include "pdata.h" -#include "../wcdcal-hwdep.h" -#include "../wcd-mbhc-v2-api.h" +#include +#include #define AQT_ZDET_SUPPORTED true /* Z value defined in milliohm */ diff --git a/asoc/codecs/aqt1000/aqt1000-mbhc.h b/asoc/codecs/aqt1000/aqt1000-mbhc.h index b6ce8751559b..770472c32887 100644 --- a/asoc/codecs/aqt1000/aqt1000-mbhc.h +++ b/asoc/codecs/aqt1000/aqt1000-mbhc.h @@ -3,7 +3,7 @@ */ #ifndef __AQT1000_MBHC_H__ #define __AQT1000_MBHC_H__ -#include "../wcd-mbhc-v2.h" +#include struct aqt1000_mbhc { struct wcd_mbhc wcd_mbhc; diff --git a/asoc/codecs/aqt1000/aqt1000.c b/asoc/codecs/aqt1000/aqt1000.c index 1ba5605b62b0..a92a1541c418 100644 --- a/asoc/codecs/aqt1000/aqt1000.c +++ b/asoc/codecs/aqt1000/aqt1000.c @@ -25,12 +25,12 @@ #include #include #include +#include #include "aqt1000-registers.h" #include "aqt1000.h" #include "aqt1000-api.h" #include "aqt1000-mbhc.h" #include "aqt1000-routing.h" -#include "../wcdcal-hwdep.h" #include "aqt1000-internal.h" #define DRV_NAME "aqt_codec" diff --git a/asoc/codecs/aqt1000/pdata.h b/asoc/codecs/aqt1000/pdata.h index c490b56d1d3a..ba9e68f79fa3 100644 --- a/asoc/codecs/aqt1000/pdata.h +++ b/asoc/codecs/aqt1000/pdata.h @@ -8,7 +8,7 @@ #include #include -#include "../msm-cdc-supply.h" +#include struct aqt1000_micbias_setting { u8 ldoh_v; diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index ff8684f7170b..6b700a68a57a 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -14,9 +14,9 @@ #include #include +#include #include "bolero-cdc.h" #include "bolero-cdc-registers.h" -#include "../msm-cdc-pinctrl.h" #define RX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index c33a857acbaa..3c51c3fb3e78 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -12,9 +12,9 @@ #include #include #include +#include #include "bolero-cdc.h" #include "bolero-cdc-registers.h" -#include "../msm-cdc-pinctrl.h" #define TX_MACRO_MAX_OFFSET 0x1000 diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 48a42ac46531..9b2c3240b835 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -12,10 +12,10 @@ #include #include +#include #include "bolero-cdc.h" #include "bolero-cdc-registers.h" #include "wsa-macro.h" -#include "../msm-cdc-pinctrl.h" #define WSA_MACRO_MAX_OFFSET 0x1000 diff --git a/asoc/codecs/msm-cdc-pinctrl.c b/asoc/codecs/msm-cdc-pinctrl.c index 142e73d27e22..b626e5721dfb 100644 --- a/asoc/codecs/msm-cdc-pinctrl.c +++ b/asoc/codecs/msm-cdc-pinctrl.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ #include @@ -11,7 +11,7 @@ #include #include #include -#include "msm-cdc-pinctrl.h" +#include struct msm_cdc_pinctrl_info { struct pinctrl *pinctrl; diff --git a/asoc/codecs/msm-cdc-supply.c b/asoc/codecs/msm-cdc-supply.c index 16dfebbf1f0b..04fd2de13887 100644 --- a/asoc/codecs/msm-cdc-supply.c +++ b/asoc/codecs/msm-cdc-supply.c @@ -8,8 +8,8 @@ #include #include #include -#include "msm-cdc-supply.h" #include +#include #define CODEC_DT_MAX_PROP_SIZE 40 diff --git a/asoc/codecs/wcd-clsh.c b/asoc/codecs/wcd-clsh.c index 834454afab3a..3cd76f709f8e 100644 --- a/asoc/codecs/wcd-clsh.c +++ b/asoc/codecs/wcd-clsh.c @@ -9,7 +9,7 @@ #include #include #include -#include "wcd-clsh.h" +#include #define WCD_USLEEP_RANGE 50 diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index 2b596c3ac276..d63c67ced291 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -20,8 +20,8 @@ #include #include #include "wcd-mbhc-adc.h" -#include "wcd-mbhc-v2.h" -#include "pdata.h" +#include +#include #define WCD_MBHC_ADC_HS_THRESHOLD_MV 1700 #define WCD_MBHC_ADC_HPH_THRESHOLD_MV 75 diff --git a/asoc/codecs/wcd-mbhc-adc.h b/asoc/codecs/wcd-mbhc-adc.h index 95e0ff2f154d..97fd12d8a08c 100644 --- a/asoc/codecs/wcd-mbhc-adc.h +++ b/asoc/codecs/wcd-mbhc-adc.h @@ -1,10 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ #ifndef __WCD_MBHC_ADC_H__ #define __WCD_MBHC_ADC_H__ -#include "wcd-mbhc-v2.h" +#include enum wcd_mbhc_adc_mux_ctl { MUX_CTL_AUTO = 0, diff --git a/asoc/codecs/wcd-mbhc-legacy.c b/asoc/codecs/wcd-mbhc-legacy.c index 94c4560bf41d..b266da699bc2 100644 --- a/asoc/codecs/wcd-mbhc-legacy.c +++ b/asoc/codecs/wcd-mbhc-legacy.c @@ -20,7 +20,7 @@ #include #include #include "wcd-mbhc-legacy.h" -#include "wcd-mbhc-v2.h" +#include static int det_extn_cable_en; module_param(det_extn_cable_en, int, 0664); diff --git a/asoc/codecs/wcd-mbhc-legacy.h b/asoc/codecs/wcd-mbhc-legacy.h index c7835c596383..314bb1332cbc 100644 --- a/asoc/codecs/wcd-mbhc-legacy.h +++ b/asoc/codecs/wcd-mbhc-legacy.h @@ -1,11 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. */ #ifndef __WCD_MBHC_LEGACY_H__ #define __WCD_MBHC_LEGACY_H__ -#include "wcdcal-hwdep.h" -#include "wcd-mbhc-v2.h" +#include +#include #if IS_ENABLED(CONFIG_SND_SOC_WCD_MBHC_LEGACY) void wcd_mbhc_legacy_init(struct wcd_mbhc *mbhc); diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 162ccde7e075..6839203bd990 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -20,11 +20,11 @@ #include #include #include -#include "msm-cdc-pinctrl.h" -#include "wcdcal-hwdep.h" +#include +#include #include "wcd-mbhc-legacy.h" #include "wcd-mbhc-adc.h" -#include "wcd-mbhc-v2-api.h" +#include void wcd_mbhc_jack_report(struct wcd_mbhc *mbhc, struct snd_soc_jack *jack, int status, int mask) diff --git a/asoc/codecs/wcd9335-regmap.c b/asoc/codecs/wcd9335-regmap.c index 0a83fd582cbc..7b3363f08f1b 100644 --- a/asoc/codecs/wcd9335-regmap.c +++ b/asoc/codecs/wcd9335-regmap.c @@ -5,9 +5,9 @@ #include #include -#include "core.h" -#include "wcd9xxx-regmap.h" -#include "wcd9335_registers.h" +#include +#include +#include static const struct reg_sequence wcd9335_1_x_defaults[] = { { WCD9335_CODEC_RPM_CLK_GATE, 0x03, 0x00 }, diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 2372e20b7b61..22bc0e6aba69 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -28,18 +28,18 @@ #include #include #include -#include "core.h" -#include "pdata.h" +#include +#include #include "wcd9335.h" -#include "wcd-mbhc-v2.h" -#include "wcd9xxx-common-v2.h" -#include "wcd9xxx-resmgr-v2.h" -#include "wcd9xxx-irq.h" +#include +#include +#include +#include #include "wcd9335_registers.h" #include "wcd9335_irq.h" #include "wcd_cpe_core.h" -#include "wcdcal-hwdep.h" -#include "wcd-mbhc-v2-api.h" +#include +#include #define DRV_NAME "tasha_codec" diff --git a/asoc/codecs/wcd9335.h b/asoc/codecs/wcd9335.h index 261ea407a673..969ac6709370 100644 --- a/asoc/codecs/wcd9335.h +++ b/asoc/codecs/wcd9335.h @@ -8,8 +8,8 @@ #include #include #include -#include "wcd9xxx-slimslave.h" -#include "wcd-mbhc-v2.h" +#include +#include #define TASHA_REG_VAL(reg, val) {reg, 0, val} diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c index 0c6c6f033282..a7c9ea6e98d3 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c @@ -12,8 +12,8 @@ #include #include "wcd934x.h" #include "wcd934x-dsp-cntl.h" -#include "../wcd9xxx-irq.h" -#include "../core.h" +#include +#include #define WCD_CNTL_DIR_NAME_LEN_MAX 32 #define WCD_CPE_FLL_MAX_RETRIES 5 diff --git a/asoc/codecs/wcd934x/wcd934x-mbhc.c b/asoc/codecs/wcd934x/wcd934x-mbhc.c index 5801f311385b..f00e4c0a9868 100644 --- a/asoc/codecs/wcd934x/wcd934x-mbhc.c +++ b/asoc/codecs/wcd934x/wcd934x-mbhc.c @@ -21,11 +21,11 @@ #include "wcd934x-mbhc.h" #include #include "wcd934x_irq.h" -#include "../core.h" -#include "../pdata.h" -#include "../wcd9xxx-irq.h" -#include "../wcdcal-hwdep.h" -#include "../wcd-mbhc-v2-api.h" +#include +#include +#include +#include +#include #define TAVIL_ZDET_SUPPORTED true /* Z value defined in milliohm */ diff --git a/asoc/codecs/wcd934x/wcd934x-mbhc.h b/asoc/codecs/wcd934x/wcd934x-mbhc.h index a0bd05a2aa82..d474f6338b86 100644 --- a/asoc/codecs/wcd934x/wcd934x-mbhc.h +++ b/asoc/codecs/wcd934x/wcd934x-mbhc.h @@ -4,7 +4,7 @@ */ #ifndef __WCD934X_MBHC_H__ #define __WCD934X_MBHC_H__ -#include "../wcd-mbhc-v2.h" +#include enum wcd934x_on_demand_supply_name { WCD934X_ON_DEMAND_MICBIAS = 0, diff --git a/asoc/codecs/wcd934x/wcd934x-regmap.c b/asoc/codecs/wcd934x/wcd934x-regmap.c index 2a2187f953a1..a9642091a66e 100644 --- a/asoc/codecs/wcd934x/wcd934x-regmap.c +++ b/asoc/codecs/wcd934x/wcd934x-regmap.c @@ -6,8 +6,8 @@ #include #include #include -#include "../core.h" -#include "../wcd9xxx-regmap.h" +#include +#include static const struct reg_sequence wcd934x_1_1_defaults[] = { diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index becf7ee75862..07bbcb39b7d4 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -35,12 +35,12 @@ #include "wcd934x-routing.h" #include "wcd934x-dsp-cntl.h" #include "wcd934x_irq.h" -#include "../core.h" -#include "../pdata.h" -#include "../wcd9xxx-irq.h" -#include "../wcd9xxx-common-v2.h" -#include "../wcd9xxx-resmgr-v2.h" -#include "../wcdcal-hwdep.h" +#include +#include +#include +#include +#include +#include #include "wcd934x-dsd.h" #define DRV_NAME "tavil_codec" diff --git a/asoc/codecs/wcd934x/wcd934x.h b/asoc/codecs/wcd934x/wcd934x.h index 8d5aec500294..7cc0ec171bcd 100644 --- a/asoc/codecs/wcd934x/wcd934x.h +++ b/asoc/codecs/wcd934x/wcd934x.h @@ -7,9 +7,9 @@ #include #include "wcd934x-dsp-cntl.h" -#include "../wcd9xxx-slimslave.h" -#include "../wcd9xxx-common-v2.h" -#include "../wcd-mbhc-v2.h" +#include +#include +#include #define WCD934X_REGISTER_START_OFFSET 0x800 #define WCD934X_SB_PGD_PORT_RX_BASE 0x40 diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index ca401b43f2a9..eaf6860d42e9 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -5,9 +5,9 @@ #ifndef _WCD937X_INTERNAL_H #define _WCD937X_INTERNAL_H -#include "../wcd-clsh.h" -#include "../wcd-mbhc-v2.h" -#include "asoc/wcd-irq.h" +#include +#include +#include #include "wcd937x-mbhc.h" #define WCD937X_MAX_MICBIAS 3 diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index 0703017a0dc5..54d9f4595402 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -16,8 +16,8 @@ #include #include #include "wcd937x-registers.h" -#include "../wcdcal-hwdep.h" -#include "../wcd-mbhc-v2-api.h" +#include +#include #include "internal.h" #define WCD937X_ZDET_SUPPORTED true diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.h b/asoc/codecs/wcd937x/wcd937x-mbhc.h index 3ac42ef5ada2..3c7495165996 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.h +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.h @@ -3,7 +3,7 @@ */ #ifndef __WCD937X_MBHC_H__ #define __WCD937X_MBHC_H__ -#include "../wcd-mbhc-v2.h" +#include struct wcd937x_mbhc { struct wcd_mbhc wcd_mbhc; diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 45c990e1c331..004ce796c98a 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -19,11 +19,11 @@ #include #include "internal.h" #include "wcd937x.h" -#include "../wcdcal-hwdep.h" +#include #include "wcd937x-registers.h" -#include "../msm-cdc-pinctrl.h" +#include #include -#include "../msm-cdc-supply.h" +#include #define DRV_NAME "wcd937x_codec" diff --git a/asoc/codecs/wcd9xxx-common-v2.c b/asoc/codecs/wcd9xxx-common-v2.c index 56a3fa59e9ce..17f0fb730354 100644 --- a/asoc/codecs/wcd9xxx-common-v2.c +++ b/asoc/codecs/wcd9xxx-common-v2.c @@ -9,8 +9,8 @@ #include #include #include -#include "core.h" -#include "wcd9xxx-common-v2.h" +#include +#include #define WCD_USLEEP_RANGE 50 #define MAX_IMPED_PARAMS 6 diff --git a/asoc/codecs/wcd9xxx-core-init.c b/asoc/codecs/wcd9xxx-core-init.c index bb865a982416..cd35a9e24b12 100644 --- a/asoc/codecs/wcd9xxx-core-init.c +++ b/asoc/codecs/wcd9xxx-core-init.c @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ #include -#include "msm-cdc-pinctrl.h" -#include "wcd9xxx-irq.h" -#include "core.h" +#include +#include +#include #define NUM_DRIVERS_REG_RET 3 diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index 5794ef214153..b0cb9c72e404 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -15,14 +15,14 @@ #include #include #include -#include "core.h" -#include "pdata.h" -#include "msm-cdc-pinctrl.h" -#include "msm-cdc-supply.h" -#include "wcd9xxx-irq.h" +#include +#include +#include +#include +#include #include "wcd9xxx-utils.h" -#include "wcd9xxx-regmap.h" -#include "wcd9xxx-slimslave.h" +#include +#include #define WCD9XXX_REGISTER_START_OFFSET 0x800 #define WCD9XXX_SLIM_RW_MAX_TRIES 3 diff --git a/asoc/codecs/wcd9xxx-irq.c b/asoc/codecs/wcd9xxx-irq.c index 06dbf75d6118..b748bb2e9171 100644 --- a/asoc/codecs/wcd9xxx-irq.c +++ b/asoc/codecs/wcd9xxx-irq.c @@ -19,8 +19,8 @@ #include #include #include -#include "core.h" -#include "wcd9xxx-irq.h" +#include +#include #define BYTE_BIT_MASK(nr) (1UL << ((nr) % BITS_PER_BYTE)) #define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE) diff --git a/asoc/codecs/wcd9xxx-resmgr-v2.c b/asoc/codecs/wcd9xxx-resmgr-v2.c index f280fcc1eb53..fcb82f96e150 100644 --- a/asoc/codecs/wcd9xxx-resmgr-v2.c +++ b/asoc/codecs/wcd9xxx-resmgr-v2.c @@ -7,8 +7,8 @@ #include #include #include -#include "wcd9xxx-resmgr-v2.h" -#include "core.h" +#include +#include #define WCD9XXX_RCO_CALIBRATION_DELAY_INC_US 5000 /* This register is valid only for WCD9335 */ diff --git a/asoc/codecs/wcd9xxx-rst.c b/asoc/codecs/wcd9xxx-rst.c index 4a729a0a545a..4171a713f6c0 100644 --- a/asoc/codecs/wcd9xxx-rst.c +++ b/asoc/codecs/wcd9xxx-rst.c @@ -7,8 +7,8 @@ #include #include #include -#include "core.h" -#include "pdata.h" +#include +#include #include "wcd9xxx-utils.h" #include "wcd9335_registers.h" #include "wcd9335_irq.h" diff --git a/asoc/codecs/wcd9xxx-slimslave.c b/asoc/codecs/wcd9xxx-slimslave.c index a4f07ef0f8da..502bbf55e569 100644 --- a/asoc/codecs/wcd9xxx-slimslave.c +++ b/asoc/codecs/wcd9xxx-slimslave.c @@ -1,10 +1,10 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ #include #include #include -#include "wcd9xxx-slimslave.h" +#include struct wcd9xxx_slim_sch { u16 rx_port_ch_reg_base; diff --git a/asoc/codecs/wcd9xxx-utils.c b/asoc/codecs/wcd9xxx-utils.c index bcc909b8fc8c..06968dca4b8f 100644 --- a/asoc/codecs/wcd9xxx-utils.c +++ b/asoc/codecs/wcd9xxx-utils.c @@ -12,11 +12,11 @@ #include #include #include -#include "core.h" -#include "msm-cdc-supply.h" -#include "msm-cdc-pinctrl.h" -#include "pdata.h" -#include "wcd9xxx-irq.h" +#include +#include +#include +#include +#include #include "wcd9xxx-utils.h" #define REG_BYTES 2 diff --git a/asoc/codecs/wcd_cpe_core.c b/asoc/codecs/wcd_cpe_core.c index 629b803d7d9a..2ef4ae61e11e 100644 --- a/asoc/codecs/wcd_cpe_core.c +++ b/asoc/codecs/wcd_cpe_core.c @@ -17,14 +17,14 @@ #include #include #include -#include "core.h" +#include #include "cpe_core.h" #include "cpe_err.h" #include "cpe_cmi.h" #include "wcd_cpe_core.h" #include "wcd_cpe_services.h" #include "wcd_cmi_api.h" -#include "wcd9xxx-irq.h" +#include #define CMI_CMD_TIMEOUT (10 * HZ) #define WCD_CPE_LSM_MAX_SESSIONS 2 diff --git a/asoc/codecs/wcd_cpe_services.c b/asoc/codecs/wcd_cpe_services.c index fd8e8090d28d..96e2bb1945a4 100644 --- a/asoc/codecs/wcd_cpe_services.c +++ b/asoc/codecs/wcd_cpe_services.c @@ -11,7 +11,7 @@ #include #include #include "wcd9335_registers.h" -#include "core.h" +#include #include "cpe_cmi.h" #include "wcd_cpe_services.h" #include "wcd_cmi_api.h" diff --git a/asoc/codecs/wcdcal-hwdep.c b/asoc/codecs/wcdcal-hwdep.c index e826eae3b834..f9097e339b24 100644 --- a/asoc/codecs/wcdcal-hwdep.c +++ b/asoc/codecs/wcdcal-hwdep.c @@ -11,7 +11,7 @@ #include #include #include -#include "wcdcal-hwdep.h" +#include const int cal_size_info[WCD9XXX_MAX_CAL] = { [WCD9XXX_ANC_CAL] = 16384, diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index 4dceb0449c4e..f98de2e19373 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -24,7 +24,7 @@ #include #include #include -#include "msm-cdc-pinctrl.h" +#include #include "wsa881x.h" #include "wsa881x-temp-sensor.h" diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 8cdeff71ffdc..02e454e3939a 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -18,7 +18,7 @@ #include #include #include "msm-dai-q6-v2.h" -#include "codecs/core.h" +#include #define MSM_DAI_PRI_AUXPCM_DT_DEV_ID 1 #define MSM_DAI_SEC_AUXPCM_DT_DEV_ID 2 diff --git a/asoc/qcs405.c b/asoc/qcs405.c index e5310ab6952f..6e4596fdad7e 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -26,7 +26,7 @@ #include #include "device_event.h" #include "msm-pcm-routing-v2.h" -#include "codecs/msm-cdc-pinctrl.h" +#include #include "codecs/wcd9335.h" #include "codecs/wsa881x.h" #include "codecs/csra66x0/csra66x0.h" diff --git a/asoc/sm6150.c b/asoc/sm6150.c index a13eb06538a5..02f8fc5eae12 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -27,7 +27,7 @@ #include #include "device_event.h" #include "msm-pcm-routing-v2.h" -#include "codecs/msm-cdc-pinctrl.h" +#include #include "codecs/wcd934x/wcd934x.h" #include "codecs/wcd934x/wcd934x-mbhc.h" #include "codecs/wcd937x/wcd937x-mbhc.h" diff --git a/asoc/sm8150.c b/asoc/sm8150.c index 7f73dae75b36..aad476575948 100644 --- a/asoc/sm8150.c +++ b/asoc/sm8150.c @@ -25,11 +25,11 @@ #include #include "device_event.h" #include "msm-pcm-routing-v2.h" -#include "codecs/msm-cdc-pinctrl.h" +#include #include "codecs/wcd934x/wcd934x.h" #include "codecs/wcd934x/wcd934x-mbhc.h" #include "codecs/wsa881x.h" -#include "codecs/wcd-mbhc-v2.h" +#include #define DRV_NAME "sm8150-asoc-snd" diff --git a/asoc/codecs/core.h b/include/asoc/core.h similarity index 100% rename from asoc/codecs/core.h rename to include/asoc/core.h diff --git a/asoc/codecs/cpe_core.h b/include/asoc/cpe_core.h similarity index 100% rename from asoc/codecs/cpe_core.h rename to include/asoc/cpe_core.h diff --git a/asoc/codecs/msm-cdc-pinctrl.h b/include/asoc/msm-cdc-pinctrl.h similarity index 100% rename from asoc/codecs/msm-cdc-pinctrl.h rename to include/asoc/msm-cdc-pinctrl.h diff --git a/asoc/codecs/msm-cdc-supply.h b/include/asoc/msm-cdc-supply.h similarity index 100% rename from asoc/codecs/msm-cdc-supply.h rename to include/asoc/msm-cdc-supply.h diff --git a/asoc/codecs/pdata.h b/include/asoc/pdata.h similarity index 100% rename from asoc/codecs/pdata.h rename to include/asoc/pdata.h diff --git a/asoc/codecs/wcd-clsh.h b/include/asoc/wcd-clsh.h similarity index 100% rename from asoc/codecs/wcd-clsh.h rename to include/asoc/wcd-clsh.h diff --git a/asoc/codecs/wcd-mbhc-v2-api.h b/include/asoc/wcd-mbhc-v2-api.h similarity index 100% rename from asoc/codecs/wcd-mbhc-v2-api.h rename to include/asoc/wcd-mbhc-v2-api.h diff --git a/asoc/codecs/wcd-mbhc-v2.h b/include/asoc/wcd-mbhc-v2.h similarity index 100% rename from asoc/codecs/wcd-mbhc-v2.h rename to include/asoc/wcd-mbhc-v2.h diff --git a/asoc/codecs/wcd9xxx-common-v2.h b/include/asoc/wcd9xxx-common-v2.h similarity index 100% rename from asoc/codecs/wcd9xxx-common-v2.h rename to include/asoc/wcd9xxx-common-v2.h diff --git a/asoc/codecs/wcd9xxx-irq.h b/include/asoc/wcd9xxx-irq.h similarity index 100% rename from asoc/codecs/wcd9xxx-irq.h rename to include/asoc/wcd9xxx-irq.h diff --git a/asoc/codecs/wcd9xxx-regmap.h b/include/asoc/wcd9xxx-regmap.h similarity index 100% rename from asoc/codecs/wcd9xxx-regmap.h rename to include/asoc/wcd9xxx-regmap.h diff --git a/asoc/codecs/wcd9xxx-resmgr-v2.h b/include/asoc/wcd9xxx-resmgr-v2.h similarity index 100% rename from asoc/codecs/wcd9xxx-resmgr-v2.h rename to include/asoc/wcd9xxx-resmgr-v2.h diff --git a/asoc/codecs/wcd9xxx-slimslave.h b/include/asoc/wcd9xxx-slimslave.h similarity index 100% rename from asoc/codecs/wcd9xxx-slimslave.h rename to include/asoc/wcd9xxx-slimslave.h diff --git a/asoc/codecs/wcdcal-hwdep.h b/include/asoc/wcdcal-hwdep.h similarity index 100% rename from asoc/codecs/wcdcal-hwdep.h rename to include/asoc/wcdcal-hwdep.h -- GitLab From ccdb91522ab2a168b0e944e60c4f346def9330b1 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Thu, 6 Dec 2018 15:14:02 -0800 Subject: [PATCH 0722/1645] asoc: bolero: add support to enable VA MCLK MUX select on Kona VA macro is currently lacking capability to dynamically select MCLK on Kona. Add support in VA macro driver to read MUX select property from DT to enable dynamic MCLK MUX select. Change-Id: I46d0b760119a2d8c2ed754ae9cb43ba717fa300b Signed-off-by: Xiaoyu Ye --- asoc/codecs/bolero/va-macro.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index da68da847e30..db078e2a6cdf 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -138,6 +138,7 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, { struct regmap *regmap = dev_get_regmap(va_priv->dev->parent, NULL); int ret = 0; + u16 mclk_mux_sel = MCLK_MUX0; if (regmap == NULL) { dev_err(va_priv->dev, "%s: regmap is NULL\n", __func__); @@ -148,10 +149,21 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, __func__, mclk_enable, dapm, va_priv->va_mclk_users); mutex_lock(&va_priv->mclk_lock); + if (of_property_read_u16(va_priv->dev->of_node, + "qcom,va-clk-mux-select", &mclk_mux_sel)) + dev_dbg(va_priv->dev, + "%s: could not find %s entry in dt, use default\n", + __func__, "qcom,va-clk-mux-select"); + if (mclk_mux_sel != MCLK_MUX0 && mclk_mux_sel != MCLK_MUX1) { + dev_err(va_priv->dev, "%s: mclk_mux_sel: %d is invalid\n", + __func__, mclk_mux_sel); + return -EINVAL; + } + if (mclk_enable) { if (va_priv->va_mclk_users == 0) { ret = bolero_request_clock(va_priv->dev, - VA_MACRO, MCLK_MUX0, true); + VA_MACRO, mclk_mux_sel, true); if (ret < 0) { dev_err(va_priv->dev, "%s: va request clock en failed\n", @@ -192,7 +204,7 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x00); bolero_request_clock(va_priv->dev, - VA_MACRO, MCLK_MUX0, false); + VA_MACRO, mclk_mux_sel, false); } } exit: -- GitLab From 0862e6ad0aa48b84d18c3d7658330c54e99cd5a4 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 20 Dec 2018 11:12:46 +0800 Subject: [PATCH 0723/1645] ASoC: update symbolic link for internal.h, core.h and pinctrl-utils.h Update symbolic link for internal.h, core.h and pinctrl-utils.h for kona. Change-Id: I3bb585700a531e97a0b1b163b191105628f3d22c Signed-off-by: Meng Wang --- include/soc/internal.h | 2 +- soc/core.h | 2 +- soc/pinctrl-utils.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/soc/internal.h b/include/soc/internal.h index ad0a98dfc101..3180181282b0 120000 --- a/include/soc/internal.h +++ b/include/soc/internal.h @@ -1 +1 @@ -../../../../../../kernel/msm-4.14/drivers/base/regmap/internal.h \ No newline at end of file +../../../../../../kernel/msm-4.19/drivers/base/regmap/internal.h \ No newline at end of file diff --git a/soc/core.h b/soc/core.h index b9f94ca74f63..62a868d5c80f 120000 --- a/soc/core.h +++ b/soc/core.h @@ -1 +1 @@ -../../../../../kernel/msm-4.14/drivers/pinctrl/core.h \ No newline at end of file +../../../../../kernel/msm-4.19/drivers/pinctrl/core.h \ No newline at end of file diff --git a/soc/pinctrl-utils.h b/soc/pinctrl-utils.h index 0f74549b32c1..879947148999 120000 --- a/soc/pinctrl-utils.h +++ b/soc/pinctrl-utils.h @@ -1 +1 @@ -../../../../../kernel/msm-4.14/drivers/pinctrl/pinctrl-utils.h \ No newline at end of file +../../../../../kernel/msm-4.19/drivers/pinctrl/pinctrl-utils.h \ No newline at end of file -- GitLab From 19fa6defdca68db2d902d345a217b95d5f7fe5c5 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 20 Dec 2018 11:25:47 +0800 Subject: [PATCH 0724/1645] asoc: update kernel version for kona Update kernel version for kona. Change-Id: I490832f0a62f8f1b5cfe6fc6134e22cc5d8ae583 Signed-off-by: Meng Wang --- asoc/Kbuild | 2 +- asoc/codecs/Kbuild | 2 +- asoc/codecs/aqt1000/Kbuild | 2 +- asoc/codecs/bolero/Kbuild | 2 +- asoc/codecs/csra66x0/Kbuild | 2 +- asoc/codecs/ep92/Kbuild | 2 +- asoc/codecs/wcd934x/Kbuild | 2 +- asoc/codecs/wcd937x/Kbuild | 2 +- dsp/Kbuild | 2 +- dsp/codecs/Kbuild | 2 +- ipc/Kbuild | 2 +- soc/Kbuild | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/asoc/Kbuild b/asoc/Kbuild index 59a6e53fcae3..ee290b26a7cc 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -9,7 +9,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.19 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 6f04844027d5..ee4c61f92959 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -9,7 +9,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.19 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/aqt1000/Kbuild b/asoc/codecs/aqt1000/Kbuild index 60ac86649e0a..d83955f0ad37 100644 --- a/asoc/codecs/aqt1000/Kbuild +++ b/asoc/codecs/aqt1000/Kbuild @@ -9,7 +9,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.19 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild index dfb7596a35d0..1c60ec6fa47e 100644 --- a/asoc/codecs/bolero/Kbuild +++ b/asoc/codecs/bolero/Kbuild @@ -11,7 +11,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.19 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/csra66x0/Kbuild b/asoc/codecs/csra66x0/Kbuild index bb26a384ec4f..ef599622dd25 100644 --- a/asoc/codecs/csra66x0/Kbuild +++ b/asoc/codecs/csra66x0/Kbuild @@ -10,7 +10,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.19 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/ep92/Kbuild b/asoc/codecs/ep92/Kbuild index 1c54a44dcfa9..1b38aad9fff9 100644 --- a/asoc/codecs/ep92/Kbuild +++ b/asoc/codecs/ep92/Kbuild @@ -11,7 +11,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.19 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index d81618f6054c..63a75a770c23 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -11,7 +11,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.9 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.19 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/wcd937x/Kbuild b/asoc/codecs/wcd937x/Kbuild index 48d333035b20..b8db20277d70 100644 --- a/asoc/codecs/wcd937x/Kbuild +++ b/asoc/codecs/wcd937x/Kbuild @@ -11,7 +11,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.9 + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.19 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/dsp/Kbuild b/dsp/Kbuild index 6d9ea15ad5ee..724dc12aef21 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -9,7 +9,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.19 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index f6c9ea446438..54d64f2d8755 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -9,7 +9,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.19 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/ipc/Kbuild b/ipc/Kbuild index ec9dc78a851e..484d79a37fa8 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -8,7 +8,7 @@ endif # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds -KDIR := $(TOP)/kernel/msm-4.14 +KDIR := $(TOP)/kernel/msm-4.19 ifeq ($(KERNEL_BUILD), 1) AUDIO_ROOT := $(KDIR)/techpack/audio diff --git a/soc/Kbuild b/soc/Kbuild index 49ba00fccec4..4e545778bfeb 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -9,7 +9,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.14 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.19 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif -- GitLab From 483a5595b2d270aa52d95d058f28f4da1ce8b822 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Fri, 19 Oct 2018 15:00:08 -0700 Subject: [PATCH 0725/1645] ASoC: msm: add common dai's for kona Add common front end and back end dais. Add TDM, AUX PCM and MI2S dais. Change-Id: I3ecbe10ea9246aadedd02a881c937ce69f33cbbe Signed-off-by: Vignesh Kulothungan --- asoc/kona.c | 3614 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 3407 insertions(+), 207 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index 0d8772519a30..302d6f0bede6 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -19,24 +19,88 @@ #include #include #include +#include #include #include #include #include "device_event.h" #include "msm-pcm-routing-v2.h" -#include "codecs/wsa881x.h" +#include "codecs/wcd-mbhc-v2.h" #define DRV_NAME "kona-asoc-snd" - #define __CHIPSET__ "KONA " #define MSM_DAILINK_NAME(name) (__CHIPSET__#name) #define SAMPLING_RATE_8KHZ 8000 +#define SAMPLING_RATE_11P025KHZ 11025 #define SAMPLING_RATE_16KHZ 16000 +#define SAMPLING_RATE_22P05KHZ 22050 +#define SAMPLING_RATE_32KHZ 32000 +#define SAMPLING_RATE_44P1KHZ 44100 +#define SAMPLING_RATE_48KHZ 48000 +#define SAMPLING_RATE_88P2KHZ 88200 +#define SAMPLING_RATE_96KHZ 96000 +#define SAMPLING_RATE_176P4KHZ 176400 +#define SAMPLING_RATE_192KHZ 192000 +#define SAMPLING_RATE_352P8KHZ 352800 +#define SAMPLING_RATE_384KHZ 384000 + +#define TDM_CHANNEL_MAX 8 +#define DEV_NAME_STR_LEN 32 + +#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ + +#define ADSP_STATE_READY_TIMEOUT_MS 3000 + +enum { + TDM_0 = 0, + TDM_1, + TDM_2, + TDM_3, + TDM_4, + TDM_5, + TDM_6, + TDM_7, + TDM_PORT_MAX, +}; + +enum { + TDM_PRI = 0, + TDM_SEC, + TDM_TERT, + TDM_INTERFACE_MAX, +}; + +enum { + PRIM_AUX_PCM = 0, + SEC_AUX_PCM, + TERT_AUX_PCM, + AUX_PCM_MAX, +}; + +enum { + PRIM_MI2S = 0, + SEC_MI2S, + TERT_MI2S, + MI2S_MAX, +}; struct msm_asoc_mach_data { - u32 mclk_freq; struct snd_info_entry *codec_root; + int usbc_en2_gpio; /* used by gpio driver API */ + struct device_node *dmic01_gpio_p; /* used by pinctrl API */ + struct device_node *dmic23_gpio_p; /* used by pinctrl API */ + struct device_node *dmic45_gpio_p; /* used by pinctrl API */ + struct device_node *us_euro_gpio_p; /* used by pinctrl API */ + struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */ + struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ + struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ + bool is_afe_config_done; +}; + +struct tdm_port { + u32 mode; + u32 channel; }; struct dev_config { @@ -45,27 +109,249 @@ struct dev_config { u32 channels; }; -enum { - PRIM_AUX_PCM = 0, +static struct dev_config usb_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, }; -static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; -static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", - "S32_LE"}; +static struct dev_config usb_tx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 1, +}; + +static struct dev_config proxy_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +static struct afe_clk_set mi2s_clk[MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, +}; + +struct mi2s_conf { + struct mutex lock; + u32 ref_cnt; + u32 msm_is_mi2s_master; +}; + +static u32 mi2s_ebit_clk[MI2S_MAX] = { + Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT, +}; + +static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; + +/* Default configuration of TDM channels */ +static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, +}; + +static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, +}; -/* Default configuration of aux pcm channels */ +/* Default configuration of AUX PCM channels */ static struct dev_config aux_pcm_rx_cfg[] = { [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; static struct dev_config aux_pcm_tx_cfg[] = { [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +/* Default configuration of MI2S channels */ +static struct dev_config mi2s_rx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config mi2s_tx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; +static char const *ch_text[] = {"Two", "Three", "Four", "Five", + "Six", "Seven", "Eight"}; +static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", + "KHZ_48", "KHZ_176P4", + "KHZ_352P8"}; +static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; +static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", "Eight"}; +static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; +static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_16", + "KHZ_22P05", "KHZ_32", "KHZ_44P1", + "KHZ_48", "KHZ_96", "KHZ_192"}; +static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; + +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); + +static bool is_initial_boot; +static bool codec_reg_done; +static struct snd_soc_card snd_soc_card_kona_msm; + +/* + * Need to report LINEIN + * if R/L channel impedance is larger than 5K ohm + */ +static struct wcd_mbhc_config wcd_mbhc_cfg = { + .read_fw_bin = false, + .calibration = NULL, + .detect_extn_cable = true, + .mono_stero_detection = false, + .swap_gnd_mic = NULL, + .hs_ext_micbias = true, + .key_code[0] = KEY_MEDIA, + .key_code[1] = KEY_VOICECOMMAND, + .key_code[2] = KEY_VOLUMEUP, + .key_code[3] = KEY_VOLUMEDOWN, + .key_code[4] = 0, + .key_code[5] = 0, + .key_code[6] = 0, + .key_code[7] = 0, + .linein_th = 5000, + .moisture_en = true, + .mbhc_micbias = MIC_BIAS_2, + .anc_micbias = MIC_BIAS_2, + .enable_anc_mic_detect = false, +}; static inline int param_is_mask(int p) { @@ -93,255 +379,2981 @@ static void param_set_mask(struct snd_pcm_hw_params *p, int n, } } -static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) +static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - int idx = 0; + int sample_rate_val = 0; - if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", - sizeof("PRIM_AUX_PCM"))) { - idx = PRIM_AUX_PCM; - } else { - pr_err("%s: unsupported port: %s\n", - __func__, kcontrol->id.name); - idx = -EINVAL; + switch (usb_rx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; } - return idx; + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__, + usb_rx_cfg.sample_rate); + return 0; } -static int aux_pcm_get_format(int value) +static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - int format = 0; - - switch (value) { - case 1: - format = SNDRV_PCM_FORMAT_S24_LE; + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ; break; - case 2: - format = SNDRV_PCM_FORMAT_S24_3LE; + case 11: + usb_rx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_rx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_rx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ; break; case 3: - format = SNDRV_PCM_FORMAT_S32_LE; + usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; break; case 0: + usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; default: - format = SNDRV_PCM_FORMAT_S16_LE; + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; break; } - return format; + + pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_rx_cfg.sample_rate); + return 0; } -static int auxpcm_get_format_value(int format) +static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - int value = 0; + int sample_rate_val = 0; - switch (format) { - case SNDRV_PCM_FORMAT_S24_LE: - value = 1; + switch (usb_tx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; break; - case SNDRV_PCM_FORMAT_S24_3LE: - value = 2; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; break; - case SNDRV_PCM_FORMAT_S32_LE: - value = 3; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; break; - case SNDRV_PCM_FORMAT_S16_LE: default: - value = 0; + sample_rate_val = 6; break; } - return value; + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__, + usb_tx_cfg.sample_rate); + return 0; } -static int aux_pcm_get_sample_rate(int value) +static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - int sample_rate = 0; - - switch (value) { + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_tx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_tx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_tx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; case 1: - sample_rate = SAMPLING_RATE_16KHZ; + usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; break; case 0: + usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; default: - sample_rate = SAMPLING_RATE_8KHZ; + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; break; } - return sample_rate; + + pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_tx_cfg.sample_rate); + return 0; } -static int aux_pcm_get_sample_rate_val(int sample_rate) +static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - int sample_rate_val = 0; - - switch (sample_rate) { - case SAMPLING_RATE_16KHZ: - sample_rate_val = 1; + switch (usb_rx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; break; - case SAMPLING_RATE_8KHZ: + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: default: - sample_rate_val = 0; + ucontrol->value.integer.value[0] = 0; break; } - return sample_rate_val; + + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; } -static int msm_aux_pcm_rx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - int idx = aux_pcm_get_port_idx(kcontrol); + int rc = 0; - if (idx < 0) - return idx; + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); - ucontrol->value.enumerated.item[0] = - auxpcm_get_format_value(aux_pcm_rx_cfg[idx].bit_format); + return rc; +} - pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, - idx, aux_pcm_rx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); +static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_tx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); return 0; } -static int msm_aux_pcm_rx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; + int rc = 0; - aux_pcm_rx_cfg[idx].bit_format = - aux_pcm_get_format(ucontrol->value.enumerated.item[0]); + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); - pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, - idx, aux_pcm_rx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); + return rc; +} +static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, + usb_rx_cfg.channels); + ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1; return 0; } -static int msm_aux_pcm_tx_format_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - int idx = aux_pcm_get_port_idx(kcontrol); - - if (idx < 0) - return idx; - - ucontrol->value.enumerated.item[0] = - auxpcm_get_format_value(aux_pcm_tx_cfg[idx].bit_format); + usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1; - pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, - idx, aux_pcm_tx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels); + return 1; +} +static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, + usb_tx_cfg.channels); + ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1; return 0; } -static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - int idx = aux_pcm_get_port_idx(kcontrol); + usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1; - if (idx < 0) - return idx; + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels); + return 1; +} - aux_pcm_tx_cfg[idx].bit_format = - aux_pcm_get_format(ucontrol->value.enumerated.item[0]); +static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2; - pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, - idx, aux_pcm_tx_cfg[idx].bit_format, - ucontrol->value.enumerated.item[0]); + return 0; +} + +static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2; + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + + return 1; +} + +static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, + struct tdm_port *port) +{ + if (port) { + if (strnstr(kcontrol->id.name, "PRI", + sizeof(kcontrol->id.name))) { + port->mode = TDM_PRI; + } else if (strnstr(kcontrol->id.name, "SEC", + sizeof(kcontrol->id.name))) { + port->mode = TDM_SEC; + } else if (strnstr(kcontrol->id.name, "TERT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_TERT; + } else { + pr_err("%s: unsupported mode in: %s\n", + __func__, kcontrol->id.name); + return -EINVAL; + } + if (strnstr(kcontrol->id.name, "RX_0", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_0", + sizeof(kcontrol->id.name))) { + port->channel = TDM_0; + } else if (strnstr(kcontrol->id.name, "RX_1", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_1", + sizeof(kcontrol->id.name))) { + port->channel = TDM_1; + } else if (strnstr(kcontrol->id.name, "RX_2", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_2", + sizeof(kcontrol->id.name))) { + port->channel = TDM_2; + } else if (strnstr(kcontrol->id.name, "RX_3", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_3", + sizeof(kcontrol->id.name))) { + port->channel = TDM_3; + } else if (strnstr(kcontrol->id.name, "RX_4", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_4", + sizeof(kcontrol->id.name))) { + port->channel = TDM_4; + } else if (strnstr(kcontrol->id.name, "RX_5", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_5", + sizeof(kcontrol->id.name))) { + port->channel = TDM_5; + } else if (strnstr(kcontrol->id.name, "RX_6", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_6", + sizeof(kcontrol->id.name))) { + port->channel = TDM_6; + } else if (strnstr(kcontrol->id.name, "RX_7", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_7", + sizeof(kcontrol->id.name))) { + port->channel = TDM_7; + } else { + pr_err("%s: unsupported channel in: %s\n", + __func__, kcontrol->id.name); + return -EINVAL; + } + } else { + return -EINVAL; + } return 0; } -static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int tdm_get_sample_rate(int value) { - int idx = aux_pcm_get_port_idx(kcontrol); + int sample_rate = 0; - if (idx < 0) - return idx; + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} - aux_pcm_rx_cfg[idx].sample_rate = - aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); +static int tdm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; - pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, - idx, aux_pcm_rx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 5; + break; + default: + sample_rate_val = 3; + break; + } + return sample_rate_val; +} - return 0; +static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_rx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; } -static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - int idx = aux_pcm_get_port_idx(kcontrol); + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); - if (idx < 0) - return idx; + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); - ucontrol->value.enumerated.item[0] = - aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate); + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} - pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, - idx, aux_pcm_rx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); +static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); - return 0; + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_tx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; } -static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - int idx = aux_pcm_get_port_idx(kcontrol); + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); - if (idx < 0) - return idx; + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); - aux_pcm_tx_cfg[idx].sample_rate = - aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} - pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, - idx, aux_pcm_tx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); +static int tdm_get_format(int value) +{ + int format = 0; - return 0; + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; } -static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, +static int tdm_get_format_val(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 2; + break; + default: + value = 0; + break; + } + return value; +} + +static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_rx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_tx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + + ucontrol->value.enumerated.item[0] = + tdm_rx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - int idx = aux_pcm_get_port_idx(kcontrol); + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); - if (idx < 0) - return idx; + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = + tdm_tx_cfg[port.mode][port.channel].channels - 1; - ucontrol->value.enumerated.item[0] = - aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate); + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} - pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, - idx, aux_pcm_tx_cfg[idx].sample_rate, - ucontrol->value.enumerated.item[0]); +static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); - return 0; + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; } -static const struct snd_kcontrol_new msm_snd_controls[] = { - SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), +static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx = 0; + + if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", + sizeof("PRIM_AUX_PCM"))) { + idx = PRIM_AUX_PCM; + } else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM", + sizeof("SEC_AUX_PCM"))) { + idx = SEC_AUX_PCM; + } else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", + sizeof("TERT_AUX_PCM"))) { + idx = TERT_AUX_PCM; + } else { + pr_err("%s: unsupported port: %s\n", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int aux_pcm_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 0: + default: + sample_rate = SAMPLING_RATE_8KHZ; + break; + } + return sample_rate; +} + +static int aux_pcm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + return sample_rate_val; +} + +static int mi2s_auxpcm_get_format(int value) +{ + int format = 0; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int mi2s_auxpcm_get_format_value(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + value = 2; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 3; + break; + default: + value = 0; + break; + } + return value; +} + +static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(aux_pcm_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(aux_pcm_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx = 0; + + if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX", + sizeof("PRIM_MI2S_RX"))) { + idx = PRIM_MI2S; + } else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX", + sizeof("SEC_MI2S_RX"))) { + idx = SEC_MI2S; + } else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", + sizeof("TERT_MI2S_RX"))) { + idx = TERT_MI2S; + } else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", + sizeof("PRIM_MI2S_TX"))) { + idx = PRIM_MI2S; + } else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX", + sizeof("SEC_MI2S_TX"))) { + idx = SEC_MI2S; + } else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", + sizeof("TERT_MI2S_TX"))) { + idx = TERT_MI2S; + } else { + pr_err("%s: unsupported channel: %s\n", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int mi2s_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_192KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int mi2s_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + default: + sample_rate_val = 6; + break; + } + return sample_rate_val; +} + +static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(mi2s_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(mi2s_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} +static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + + return 1; +} + +static int msm_get_port_id(int be_id) +{ + int afe_port_id = 0; + + switch (be_id) { + case MSM_BACKEND_DAI_PRI_MI2S_RX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_PRI_MI2S_TX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + break; + default: + pr_err("%s: Invalid BE id: %d\n", __func__, be_id); + afe_port_id = -EINVAL; + } + + return afe_port_id; +} + +static u32 get_mi2s_bits_per_sample(u32 bit_format) +{ + u32 bit_per_sample = 0; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + case SNDRV_PCM_FORMAT_S24_LE: + bit_per_sample = 32; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bit_per_sample = 16; + break; + } + + return bit_per_sample; +} + +static void update_mi2s_clk_val(int dai_id, int stream) +{ + u32 bit_per_sample = 0; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } else { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } +} + +static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int port_id = 0; + int index = cpu_dai->id; + + port_id = msm_get_port_id(rtd->dai_link->id); + if (port_id < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto err; + } + + if (enable) { + update_mi2s_clk_val(index, substream->stream); + dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, + mi2s_clk[index].clk_freq_in_hz); + } + + mi2s_clk[index].enable = enable; + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_clk[index]); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed for port 0x%x , err:%d\n", + __func__, port_id, ret); + goto err; + } + +err: + return ret; +} + +static const struct snd_kcontrol_new msm_common_snd_controls[] = { + SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, + usb_audio_rx_sample_rate_get, + usb_audio_rx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, + usb_audio_tx_sample_rate_get, + usb_audio_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, + usb_audio_rx_format_get, usb_audio_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, + usb_audio_tx_format_get, usb_audio_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("TERT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("SEC_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("TERT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, + usb_audio_rx_ch_get, usb_audio_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, + usb_audio_tx_ch_get, usb_audio_tx_ch_put), + SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, + proxy_rx_ch_get, proxy_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), +}; + +static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), +}; + +static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int rc = 0; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->id) { + case MSM_BACKEND_DAI_USB_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_rx_cfg.bit_format); + rate->min = rate->max = usb_rx_cfg.sample_rate; + channels->min = channels->max = usb_rx_cfg.channels; + break; + + case MSM_BACKEND_DAI_USB_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_tx_cfg.bit_format); + rate->min = rate->max = usb_tx_cfg.sample_rate; + channels->min = channels->max = usb_tx_cfg.channels; + break; + case MSM_BACKEND_DAI_AFE_PCM_RX: + channels->min = channels->max = proxy_rx_cfg.channels; + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + + case MSM_BACKEND_DAI_PRI_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_PRI_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[PRIM_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[SEC_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[SEC_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[TERT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[TERT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[TERT_MI2S].channels; + break; + + default: + rate->min = rate->max = SAMPLING_RATE_8KHZ; + break; + } + + return rc; +} + +static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + int slot_width = 32; + int channels, slots; + unsigned int slot_mask, rate, clk_freq; + unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; + + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + slots = tdm_rx_cfg[TDM_PRI][TDM_0].channels; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + slots = tdm_rx_cfg[TDM_SEC][TDM_0].channels; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + slots = tdm_rx_cfg[TDM_TERT][TDM_0].channels; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX: + slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX: + slots = tdm_tx_cfg[TDM_SEC][TDM_0].channels; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX: + slots = tdm_tx_cfg[TDM_TERT][TDM_0].channels; + break; + + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + /*2 slot config - bits 0 and 1 set for the first two slots */ + slot_mask = 0x0000FFFF >> (16 - slots); + channels = slots; + + pr_debug("%s: tdm rx slot_width %d slots %d\n", + __func__, slot_width, slots); + + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm rx slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + 0, NULL, channels, slot_offset); + if (ret < 0) { + pr_err("%s: failed to set tdm rx channel map, err:%d\n", + __func__, ret); + goto end; + } + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + /*2 slot config - bits 0 and 1 set for the first two slots */ + slot_mask = 0x0000FFFF >> (16 - slots); + channels = slots; + + pr_debug("%s: tdm tx slot_width %d slots %d\n", + __func__, slot_width, slots); + + ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm tx slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + channels, slot_offset, 0, NULL); + if (ret < 0) { + pr_err("%s: failed to set tdm tx channel map, err:%d\n", + __func__, ret); + goto end; + } + } else { + ret = -EINVAL; + pr_err("%s: invalid use case, err:%d\n", + __func__, ret); + goto end; + } + + rate = params_rate(params); + clk_freq = rate * slot_width * slots; + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, clk_freq, SND_SOC_CLOCK_OUT); + if (ret < 0) + pr_err("%s: failed to set tdm clk, err:%d\n", + __func__, ret); + +end: + return ret; +} + +static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) +{ + cpumask_t mask; + + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + + cpumask_clear(&mask); + cpumask_set_cpu(1, &mask); /* affine to core 1 */ + cpumask_set_cpu(2, &mask); /* affine to core 2 */ + cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); + + substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; + + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + MSM_LL_QOS_VALUE); + return 0; +} + +static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int index = cpu_dai->id; + unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + if (index < PRIM_MI2S || index >= MI2S_MAX) { + ret = -EINVAL; + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto err; + } + /* + * Mutex protection in case the same MI2S + * interface using for both TX and RX so + * that the same clock won't be enable twice. + */ + mutex_lock(&mi2s_intf_conf[index].lock); + if (++mi2s_intf_conf[index].ref_cnt == 1) { + /* Check if msm needs to provide the clock to the interface */ + if (!mi2s_intf_conf[index].msm_is_mi2s_master) { + mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; + fmt = SND_SOC_DAIFMT_CBM_CFM; + } + ret = msm_mi2s_set_sclk(substream, true); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed to enable MI2S clock, err:%d\n", + __func__, ret); + goto clean_up; + } + + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) { + pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n", + __func__, index, ret); + goto clk_off; + } + } +clk_off: + if (ret < 0) + msm_mi2s_set_sclk(substream, false); +clean_up: + if (ret < 0) + mi2s_intf_conf[index].ref_cnt--; + mutex_unlock(&mi2s_intf_conf[index].lock); +err: + return ret; +} + +static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int index = rtd->cpu_dai->id; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + if (index < PRIM_MI2S || index >= MI2S_MAX) { + pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); + return; + } + + mutex_lock(&mi2s_intf_conf[index].lock); + if (--mi2s_intf_conf[index].ref_cnt == 0) { + ret = msm_mi2s_set_sclk(substream, false); + if (ret < 0) + pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", + __func__, index, ret); + } + mutex_unlock(&mi2s_intf_conf[index].lock); +} + +static struct snd_soc_ops kona_tdm_be_ops = { + .hw_params = kona_tdm_snd_hw_params, +}; + +static struct snd_soc_ops msm_mi2s_be_ops = { + .startup = msm_mi2s_snd_startup, + .shutdown = msm_mi2s_snd_shutdown, +}; + +static struct snd_soc_ops msm_fe_qos_ops = { + .prepare = msm_fe_qos_prepare, +}; + +/* Digital audio interface glue - connects codec <---> CPU */ +static struct snd_soc_dai_link msm_common_dai_links[] = { + /* FrontEnd DAI Links */ + {/* hw:x,0 */ + .name = MSM_DAILINK_NAME(Media1), + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, + {/* hw:x,1 */ + .name = MSM_DAILINK_NAME(Media2), + .stream_name = "MultiMedia2", + .cpu_dai_name = "MultiMedia2", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, + }, + {/* hw:x,2 */ + .name = "VoiceMMode1", + .stream_name = "VoiceMMode1", + .cpu_dai_name = "VoiceMMode1", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE1, + }, + {/* hw:x,3 */ + .name = "MSM VoIP", + .stream_name = "VoIP", + .cpu_dai_name = "VoIP", + .platform_name = "msm-voip-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_VOIP, + }, + {/* hw:x,4 */ + .name = MSM_DAILINK_NAME(ULL), + .stream_name = "MultiMedia3", + .cpu_dai_name = "MultiMedia3", + .platform_name = "msm-pcm-dsp.2", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA3, + }, + /* Hostless PCM purpose */ + {/* hw:x,5 */ + .name = "MSM AFE-PCM RX", + .stream_name = "AFE-PROXY RX", + .cpu_dai_name = "msm-dai-q6-dev.241", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .platform_name = "msm-pcm-afe", + .dpcm_playback = 1, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + }, + {/* hw:x,6 */ + .name = "MSM AFE-PCM TX", + .stream_name = "AFE-PROXY TX", + .cpu_dai_name = "msm-dai-q6-dev.240", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .platform_name = "msm-pcm-afe", + .dpcm_capture = 1, + .ignore_suspend = 1, + }, + {/* hw:x,7 */ + .name = MSM_DAILINK_NAME(Compress1), + .stream_name = "Compress1", + .cpu_dai_name = "MultiMedia4", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA4, + }, + {/* hw:x,8 */ + .name = "AUXPCM Hostless", + .stream_name = "AUXPCM Hostless", + .cpu_dai_name = "AUXPCM_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,9 */ + .name = MSM_DAILINK_NAME(LowLatency), + .stream_name = "MultiMedia5", + .cpu_dai_name = "MultiMedia5", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .ops = &msm_fe_qos_ops, + }, + {/* hw:x,10 */ + .name = "Listen 1 Audio Service", + .stream_name = "Listen 1 Audio Service", + .cpu_dai_name = "LSM1", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM1, + }, + /* Multiple Tunnel instances */ + {/* hw:x,11 */ + .name = MSM_DAILINK_NAME(Compress2), + .stream_name = "Compress2", + .cpu_dai_name = "MultiMedia7", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA7, + }, + {/* hw:x,12 */ + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", + .cpu_dai_name = "MultiMedia10", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA10, + }, + {/* hw:x,13 */ + .name = MSM_DAILINK_NAME(ULL_NOIRQ), + .stream_name = "MM_NOIRQ", + .cpu_dai_name = "MultiMedia8", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + .ops = &msm_fe_qos_ops, + }, + /* HDMI Hostless */ + {/* hw:x,14 */ + .name = "HDMI_RX_HOSTLESS", + .stream_name = "HDMI_RX_HOSTLESS", + .cpu_dai_name = "HDMI_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,15 */ + .name = "VoiceMMode2", + .stream_name = "VoiceMMode2", + .cpu_dai_name = "VoiceMMode2", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE2, + }, + /* LSM FE */ + {/* hw:x,16 */ + .name = "Listen 2 Audio Service", + .stream_name = "Listen 2 Audio Service", + .cpu_dai_name = "LSM2", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM2, + }, + {/* hw:x,17 */ + .name = "Listen 3 Audio Service", + .stream_name = "Listen 3 Audio Service", + .cpu_dai_name = "LSM3", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM3, + }, + {/* hw:x,18 */ + .name = "Listen 4 Audio Service", + .stream_name = "Listen 4 Audio Service", + .cpu_dai_name = "LSM4", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM4, + }, + {/* hw:x,19 */ + .name = "Listen 5 Audio Service", + .stream_name = "Listen 5 Audio Service", + .cpu_dai_name = "LSM5", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM5, + }, + {/* hw:x,20 */ + .name = "Listen 6 Audio Service", + .stream_name = "Listen 6 Audio Service", + .cpu_dai_name = "LSM6", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM6, + }, + {/* hw:x,21 */ + .name = "Listen 7 Audio Service", + .stream_name = "Listen 7 Audio Service", + .cpu_dai_name = "LSM7", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM7, + }, + {/* hw:x,22 */ + .name = "Listen 8 Audio Service", + .stream_name = "Listen 8 Audio Service", + .cpu_dai_name = "LSM8", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM8, + }, + {/* hw:x,23 */ + .name = MSM_DAILINK_NAME(Media9), + .stream_name = "MultiMedia9", + .cpu_dai_name = "MultiMedia9", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA9, + }, + {/* hw:x,24 */ + .name = MSM_DAILINK_NAME(Compress4), + .stream_name = "Compress4", + .cpu_dai_name = "MultiMedia11", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA11, + }, + {/* hw:x,25 */ + .name = MSM_DAILINK_NAME(Compress5), + .stream_name = "Compress5", + .cpu_dai_name = "MultiMedia12", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA12, + }, + {/* hw:x,26 */ + .name = MSM_DAILINK_NAME(Compress6), + .stream_name = "Compress6", + .cpu_dai_name = "MultiMedia13", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA13, + }, + {/* hw:x,27 */ + .name = MSM_DAILINK_NAME(Compress7), + .stream_name = "Compress7", + .cpu_dai_name = "MultiMedia14", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA14, + }, + {/* hw:x,28 */ + .name = MSM_DAILINK_NAME(Compress8), + .stream_name = "Compress8", + .cpu_dai_name = "MultiMedia15", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA15, + }, + {/* hw:x,29 */ + .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), + .stream_name = "MM_NOIRQ_2", + .cpu_dai_name = "MultiMedia16", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA16, + }, + {/* hw:x,30 */ + .name = "CDC_DMA Hostless", + .stream_name = "CDC_DMA Hostless", + .cpu_dai_name = "CDC_DMA_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,31 */ + .name = "TX3_CDC_DMA Hostless", + .stream_name = "TX3_CDC_DMA Hostless", + .cpu_dai_name = "TX3_CDC_DMA_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +}; + +static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { + { + .name = MSM_DAILINK_NAME(ASM Loopback), + .stream_name = "MultiMedia6", + .cpu_dai_name = "MultiMedia6", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA6, + }, + { + .name = "USB Audio Hostless", + .stream_name = "USB Audio Hostless", + .cpu_dai_name = "USBAUDIO_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "SLIMBUS_7 Hostless", + .stream_name = "SLIMBUS_7 Hostless", + .cpu_dai_name = "SLIMBUS7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +}; + +static struct snd_soc_dai_link msm_common_be_dai_links[] = { + /* Backend AFE DAI Links */ + { + .name = LPASS_BE_AFE_PCM_RX, + .stream_name = "AFE Playback", + .cpu_dai_name = "msm-dai-q6-dev.224", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AFE_PCM_TX, + .stream_name = "AFE Capture", + .cpu_dai_name = "msm-dai-q6-dev.225", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Uplink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_TX, + .stream_name = "Voice Uplink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32772", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Downlink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_RX, + .stream_name = "Voice Downlink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32771", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music BACK END DAI Link */ + { + .name = LPASS_BE_VOICE_PLAYBACK_TX, + .stream_name = "Voice Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32773", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + /* Incall Music 2 BACK END DAI Link */ + { + .name = LPASS_BE_VOICE2_PLAYBACK_TX, + .stream_name = "Voice2 Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32770", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_RX, + .stream_name = "USB Audio Playback", + .cpu_dai_name = "msm-dai-q6-dev.28672", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_USB_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_TX, + .stream_name = "USB Audio Capture", + .cpu_dai_name = "msm-dai-q6-dev.28673", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_USB_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_0, + .stream_name = "Primary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36864", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_0, + .stream_name = "Primary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36865", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_0, + .stream_name = "Secondary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36880", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_0, + .stream_name = "Secondary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36881", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_0, + .stream_name = "Tertiary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36896", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_0, + .stream_name = "Tertiary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36897", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_tdm_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { + { + .name = LPASS_BE_PRI_MI2S_RX, + .stream_name = "Primary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_MI2S_TX, + .stream_name = "Primary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX, + .stream_name = "Secondary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX, + .stream_name = "Secondary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX, + .stream_name = "Tertiary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX, + .stream_name = "Tertiary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { + /* Primary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_AUXPCM_RX, + .stream_name = "AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AUXPCM_TX, + .stream_name = "AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Secondary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_SEC_AUXPCM_RX, + .stream_name = "Sec AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_AUXPCM_TX, + .stream_name = "Sec AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Tertiary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_TERT_AUXPCM_RX, + .stream_name = "Tert AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_AUXPCM_TX, + .stream_name = "Tert AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, }; +static struct snd_soc_dai_link msm_kona_dai_links[ + ARRAY_SIZE(msm_common_dai_links) + + ARRAY_SIZE(msm_common_misc_fe_dai_links) + + ARRAY_SIZE(msm_common_be_dai_links) + + ARRAY_SIZE(msm_mi2s_be_dai_links) + + ARRAY_SIZE(msm_auxpcm_be_dai_links)]; + static int msm_populate_dai_link_component_of_node( struct snd_soc_card *card) { @@ -456,44 +3468,6 @@ static int msm_snd_stub_hw_params(struct snd_pcm_substream *substream, return 0; } -static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_dai_link *dai_link = rtd->dai_link; - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - int rc = 0; - - pr_debug("%s: format = %d, rate = %d\n", - __func__, params_format(params), params_rate(params)); - - switch (dai_link->id) { - case MSM_BACKEND_DAI_AUXPCM_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format); - rate->min = rate->max = - aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_rx_cfg[PRIM_AUX_PCM].channels; - break; - case MSM_BACKEND_DAI_AUXPCM_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - aux_pcm_tx_cfg[PRIM_AUX_PCM].bit_format); - rate->min = rate->max = - aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; - channels->min = channels->max = - aux_pcm_tx_cfg[PRIM_AUX_PCM].channels; - break; - default: - rate->min = rate->max = SAMPLING_RATE_8KHZ; - break; - } - - return rc; -} - static struct snd_soc_ops msm_stub_be_ops = { .hw_params = msm_snd_stub_hw_params, }; @@ -571,9 +3545,13 @@ static const struct of_device_id kona_asoc_machine_of_match[] = { static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) { struct snd_soc_card *card = NULL; - struct snd_soc_dai_link *dailink; - int len_1, len_2; - int total_links; + struct snd_soc_dai_link *dailink = NULL; + int len_1 = 0; + int len_2 = 0; + int total_links = 0; + int rc = 0; + u32 mi2s_audio_intf = 0; + u32 auxpcm_audio_intf = 0; const struct of_device_id *match; match = of_match_node(kona_asoc_machine_of_match, dev->of_node); @@ -583,7 +3561,57 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) return NULL; } - if (!strcmp(match->data, "stub_codec")) { + if (!strcmp(match->data, "codec")) { + card = &snd_soc_card_kona_msm; + + memcpy(msm_kona_dai_links + total_links, + msm_common_dai_links, + sizeof(msm_common_dai_links)); + total_links += ARRAY_SIZE(msm_common_dai_links); + + memcpy(msm_kona_dai_links + total_links, + msm_common_misc_fe_dai_links, + sizeof(msm_common_misc_fe_dai_links)); + total_links += ARRAY_SIZE(msm_common_misc_fe_dai_links); + + memcpy(msm_kona_dai_links + total_links, + msm_common_be_dai_links, + sizeof(msm_common_be_dai_links)); + total_links += ARRAY_SIZE(msm_common_be_dai_links); + + rc = of_property_read_u32(dev->of_node, "qcom,mi2s-audio-intf", + &mi2s_audio_intf); + if (rc) { + dev_dbg(dev, "%s: No DT match MI2S audio interface\n", + __func__); + } else { + if (mi2s_audio_intf) { + memcpy(msm_kona_dai_links + total_links, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + total_links += + ARRAY_SIZE(msm_mi2s_be_dai_links); + } + } + + rc = of_property_read_u32(dev->of_node, + "qcom,auxpcm-audio-intf", + &auxpcm_audio_intf); + if (rc) { + dev_dbg(dev, "%s: No DT match Aux PCM interface\n", + __func__); + } else { + if (auxpcm_audio_intf) { + memcpy(msm_kona_dai_links + total_links, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + total_links += + ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + } + + dailink = msm_kona_dai_links; + } else if(!strcmp(match->data, "stub_codec")) { card = &snd_soc_card_stub_msm; len_1 = ARRAY_SIZE(msm_stub_fe_dai_links); len_2 = len_1 + ARRAY_SIZE(msm_stub_be_dai_links); @@ -607,12 +3635,129 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) return card; } +static void msm_i2s_auxpcm_init(struct platform_device *pdev) +{ + int count = 0; + u32 mi2s_master_slave[MI2S_MAX]; + int ret = 0; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_init(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-master", + mi2s_master_slave, MI2S_MAX); + if (ret) { + dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n", + __func__); + } else { + for (count = 0; count < MI2S_MAX; count++) { + mi2s_intf_conf[count].msm_is_mi2s_master = + mi2s_master_slave[count]; + } + } +} + +static void msm_i2s_auxpcm_deinit(void) +{ + int count = 0; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_destroy(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + mi2s_intf_conf[count].msm_is_mi2s_master = 0; + } +} + +static int kona_ssr_enable(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct snd_soc_card *card = platform_get_drvdata(pdev); + int ret = 0; + + if (!card) { + dev_err(dev, "%s: card is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + if (!strcmp(card->name, "kona-stub-snd-card")) { + /* TODO */ + dev_dbg(dev, "%s: TODO \n", __func__); + } + + snd_soc_card_change_online_state(card, 1); + dev_dbg(dev, "%s: setting snd_card to ONLINE\n", __func__); + +err: + return ret; +} + +static void kona_ssr_disable(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct snd_soc_card *card = platform_get_drvdata(pdev); + + if (!card) { + dev_err(dev, "%s: card is NULL\n", __func__); + return; + } + + dev_dbg(dev, "%s: setting snd_card to OFFLINE\n", __func__); + snd_soc_card_change_online_state(card, 0); + + if (!strcmp(card->name, "kona-stub-snd-card")) { + /* TODO */ + dev_dbg(dev, "%s: TODO \n", __func__); + } +} + +static const struct snd_event_ops kona_ssr_ops = { + .enable = kona_ssr_enable, + .disable = kona_ssr_disable, +}; + +static int msm_audio_ssr_compare(struct device *dev, void *data) +{ + struct device_node *node = data; + + dev_dbg(dev, "%s: dev->of_node = 0x%p, node = 0x%p\n", + __func__, dev->of_node, node); + return (dev->of_node && dev->of_node == node); +} + +static int msm_audio_ssr_register(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct snd_event_clients *ssr_clients = NULL; + struct device_node *node = NULL; + int ret = 0; + int i = 0; + + for (i = 0; ; i++) { + node = of_parse_phandle(np, "qcom,msm_audio_ssr_devs", i); + if (!node) + break; + snd_event_mstr_add_client(&ssr_clients, + msm_audio_ssr_compare, node); + } + + ret = snd_event_master_register(dev, &kona_ssr_ops, + ssr_clients, NULL); + if (!ret) + snd_event_notify(dev, SND_EVENT_UP); + + return ret; +} + static int msm_asoc_machine_probe(struct platform_device *pdev) { - struct snd_soc_card *card; - struct msm_asoc_mach_data *pdata; - const struct of_device_id *match; - int ret; + struct snd_soc_card *card = NULL; + struct msm_asoc_mach_data *pdata = NULL; + const char *mbhc_audio_jack_type = NULL; + int ret = 0; if (!pdev->dev.of_node) { dev_err(&pdev->dev, "%s: No platform supplied from device tree\n", __func__); @@ -630,6 +3775,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) ret = -EINVAL; goto err; } + card->dev = &pdev->dev; platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, pdata); @@ -641,11 +3787,10 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) goto err; } - match = of_match_node(kona_asoc_machine_of_match, - pdev->dev.of_node); - if (!match) { - dev_err(&pdev->dev, "%s: no matched codec is found.\n", - __func__); + ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing"); + if (ret) { + dev_err(&pdev->dev, "%s: parse audio routing failed, err:%d\n", + __func__, ret); goto err; } @@ -656,7 +3801,11 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) } ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) { + if (ret == -EPROBE_DEFER) { + if (codec_reg_done) + ret = -EINVAL; + goto err; + } else if (ret) { dev_err(&pdev->dev, "%s: snd_soc_register_card failed (%d)\n", __func__, ret); goto err; @@ -664,6 +3813,54 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) dev_info(&pdev->dev, "%s: Sound card %s registered\n", __func__, card->name); + pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en1-gpio", 0); + if (!pdata->hph_en1_gpio_p) { + dev_dbg(&pdev->dev, "%s: property %s not detected in node %s\n", + __func__, "qcom,hph-en1-gpio", + pdev->dev.of_node->full_name); + } + + pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en0-gpio", 0); + if (!pdata->hph_en0_gpio_p) { + dev_dbg(&pdev->dev, "%s: property %s not detected in node %s\n", + __func__, "qcom,hph-en0-gpio", + pdev->dev.of_node->full_name); + } + + ret = of_property_read_string(pdev->dev.of_node, + "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type); + if (ret) { + dev_dbg(&pdev->dev, "%s: Looking up %s property in node %s failed\n", + __func__, "qcom,mbhc-audio-jack-type", + pdev->dev.of_node->full_name); + dev_dbg(&pdev->dev, "Jack type properties set to default\n"); + } else { + if (!strcmp(mbhc_audio_jack_type, "4-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = false; + dev_dbg(&pdev->dev, "This hardware has 4 pole jack"); + } else if (!strcmp(mbhc_audio_jack_type, "5-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = true; + dev_dbg(&pdev->dev, "This hardware has 5 pole jack"); + } else if (!strcmp(mbhc_audio_jack_type, "6-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = true; + dev_dbg(&pdev->dev, "This hardware has 6 pole jack"); + } else { + wcd_mbhc_cfg.enable_anc_mic_detect = false; + dev_dbg(&pdev->dev, "Unknown value, set to default\n"); + } + } + + msm_i2s_auxpcm_init(pdev); + + ret = msm_audio_ssr_register(&pdev->dev); + if (ret) + pr_err("%s: Registration with SND event FWK failed ret = %d\n", + __func__, ret); + + is_initial_boot = true; + return 0; err: devm_kfree(&pdev->dev, pdata); @@ -674,7 +3871,10 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); + snd_event_master_deregister(&pdev->dev); snd_soc_unregister_card(card); + msm_i2s_auxpcm_deinit(); + return 0; } -- GitLab From 3e5ebbf46657a8d81170664768ea3438a73138bf Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Tue, 23 Oct 2018 12:19:13 -0700 Subject: [PATCH 0726/1645] ASoC: msm: add bolero codec functionality Add codec specific functions for basic audio functionality on Kona. Change-Id: I58a12010f5894341c59de3c70ada216b5ec764e6 Signed-off-by: Vignesh Kulothungan --- asoc/kona.c | 2164 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 1902 insertions(+), 262 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index 302d6f0bede6..e4dce7d4b352 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -25,7 +25,12 @@ #include #include "device_event.h" #include "msm-pcm-routing-v2.h" -#include "codecs/wcd-mbhc-v2.h" +#include "asoc/msm-cdc-pinctrl.h" +#include "asoc/wcd-mbhc-v2.h" +#include "codecs/wsa881x.h" +#include "codecs/bolero/bolero-cdc.h" +#include +#include "codecs/bolero/wsa-macro.h" #define DRV_NAME "kona-asoc-snd" #define __CHIPSET__ "KONA " @@ -52,6 +57,9 @@ #define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define WSA8810_NAME_1 "wsa881x.20170211" +#define WSA8810_NAME_2 "wsa881x.20170212" + enum { TDM_0 = 0, TDM_1, @@ -85,6 +93,27 @@ enum { MI2S_MAX, }; +enum { + WSA_CDC_DMA_RX_0 = 0, + WSA_CDC_DMA_RX_1, + RX_CDC_DMA_RX_0, + RX_CDC_DMA_RX_1, + RX_CDC_DMA_RX_2, + RX_CDC_DMA_RX_3, + RX_CDC_DMA_RX_5, + CDC_DMA_RX_MAX, +}; + +enum { + WSA_CDC_DMA_TX_0 = 0, + WSA_CDC_DMA_TX_1, + WSA_CDC_DMA_TX_2, + TX_CDC_DMA_TX_0, + TX_CDC_DMA_TX_3, + TX_CDC_DMA_TX_4, + CDC_DMA_TX_MAX, +}; + struct msm_asoc_mach_data { struct snd_info_entry *codec_root; int usbc_en2_gpio; /* used by gpio driver API */ @@ -103,6 +132,16 @@ struct tdm_port { u32 channel; }; +struct msm_wsa881x_dev_info { + struct device_node *of_node; + u32 index; +}; + +struct aux_codec_dev_info { + struct device_node *of_node; + u32 index; +}; + struct dev_config { u32 sample_rate; u32 bit_format; @@ -261,6 +300,27 @@ static struct dev_config mi2s_tx_cfg[] = { [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; +/* Default configuration of Codec DMA Interface RX */ +static struct dev_config cdc_dma_rx_cfg[] = { + [WSA_CDC_DMA_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [WSA_CDC_DMA_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [RX_CDC_DMA_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [RX_CDC_DMA_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [RX_CDC_DMA_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [RX_CDC_DMA_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [RX_CDC_DMA_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +/* Default configuration of Codec DMA Interface TX */ +static struct dev_config cdc_dma_tx_cfg[] = { + [WSA_CDC_DMA_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [WSA_CDC_DMA_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [WSA_CDC_DMA_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TX_CDC_DMA_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TX_CDC_DMA_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TX_CDC_DMA_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", "S32_LE"}; static char const *ch_text[] = {"Two", "Three", "Four", "Five", @@ -287,6 +347,17 @@ static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; +static const char *const cdc_dma_rx_ch_text[] = {"One", "Two"}; +static const char *const cdc_dma_tx_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *cdc_dma_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", + "KHZ_176P4", "KHZ_192", + "KHZ_352P8", "KHZ_384"}; + static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); @@ -322,10 +393,67 @@ static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_0_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_1_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_2_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_0_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_3_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_1_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_2_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_0_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_3_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_1_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_2_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_3_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_sample_rate, + cdc_dma_sample_rate_text); static bool is_initial_boot; static bool codec_reg_done; +static struct snd_soc_aux_dev *msm_aux_dev; +static struct snd_soc_codec_conf *msm_codec_conf; static struct snd_soc_card snd_soc_card_kona_msm; +static int dmic_0_1_gpio_cnt; +static int dmic_2_3_gpio_cnt; +static int dmic_4_5_gpio_cnt; +static int msm_vi_feed_tx_ch = 2; /* * Need to report LINEIN @@ -1830,237 +1958,906 @@ static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) return ret; } -static const struct snd_kcontrol_new msm_common_snd_controls[] = { - SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, - usb_audio_rx_sample_rate_get, - usb_audio_rx_sample_rate_put), - SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, - usb_audio_tx_sample_rate_get, - usb_audio_tx_sample_rate_put), - SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, - tdm_rx_sample_rate_get, - tdm_rx_sample_rate_put), - SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, - tdm_rx_sample_rate_get, - tdm_rx_sample_rate_put), - SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, - tdm_rx_sample_rate_get, - tdm_rx_sample_rate_put), - SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, - tdm_tx_sample_rate_get, - tdm_tx_sample_rate_put), - SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, - tdm_tx_sample_rate_get, - tdm_tx_sample_rate_put), - SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, - tdm_tx_sample_rate_get, - tdm_tx_sample_rate_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, - mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate, - mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, - mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, - mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, - mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, - mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, - usb_audio_rx_format_get, usb_audio_rx_format_put), - SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, - usb_audio_tx_format_get, usb_audio_tx_format_put), - SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, - msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), - SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format, - msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), - SOC_ENUM_EXT("TERT_MI2S_RX Format", mi2s_rx_format, - msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), - SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, - msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), - SOC_ENUM_EXT("SEC_MI2S_TX Format", mi2s_tx_format, - msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), - SOC_ENUM_EXT("TERT_MI2S_TX Format", mi2s_tx_format, - msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), - SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, - usb_audio_rx_ch_get, usb_audio_rx_ch_put), - SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, - usb_audio_tx_ch_get, usb_audio_tx_ch_put), - SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, - proxy_rx_ch_get, proxy_rx_ch_put), - SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, - msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), - SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, - msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), - SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, - msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), - SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, - msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, - msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, - msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), -}; +static int cdc_dma_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx = 0; -static const struct snd_kcontrol_new msm_snd_controls[] = { - SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, - aux_pcm_rx_sample_rate_get, - aux_pcm_rx_sample_rate_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, - aux_pcm_tx_sample_rate_get, - aux_pcm_tx_sample_rate_put), -}; + if (strnstr(kcontrol->id.name, "WSA_CDC_DMA_RX_0", + sizeof("WSA_CDC_DMA_RX_0"))) + idx = WSA_CDC_DMA_RX_0; + else if (strnstr(kcontrol->id.name, "WSA_CDC_DMA_RX_1", + sizeof("WSA_CDC_DMA_RX_0"))) + idx = WSA_CDC_DMA_RX_1; + else if (strnstr(kcontrol->id.name, "RX_CDC_DMA_RX_0", + sizeof("RX_CDC_DMA_RX_0"))) + idx = RX_CDC_DMA_RX_0; + else if (strnstr(kcontrol->id.name, "RX_CDC_DMA_RX_1", + sizeof("RX_CDC_DMA_RX_1"))) + idx = RX_CDC_DMA_RX_1; + else if (strnstr(kcontrol->id.name, "RX_CDC_DMA_RX_2", + sizeof("RX_CDC_DMA_RX_2"))) + idx = RX_CDC_DMA_RX_2; + else if (strnstr(kcontrol->id.name, "RX_CDC_DMA_RX_3", + sizeof("RX_CDC_DMA_RX_3"))) + idx = RX_CDC_DMA_RX_3; + else if (strnstr(kcontrol->id.name, "RX_CDC_DMA_RX_5", + sizeof("RX_CDC_DMA_RX_5"))) + idx = RX_CDC_DMA_RX_5; + else if (strnstr(kcontrol->id.name, "WSA_CDC_DMA_TX_0", + sizeof("WSA_CDC_DMA_TX_0"))) + idx = WSA_CDC_DMA_TX_0; + else if (strnstr(kcontrol->id.name, "WSA_CDC_DMA_TX_1", + sizeof("WSA_CDC_DMA_TX_1"))) + idx = WSA_CDC_DMA_TX_1; + else if (strnstr(kcontrol->id.name, "WSA_CDC_DMA_TX_2", + sizeof("WSA_CDC_DMA_TX_2"))) + idx = WSA_CDC_DMA_TX_2; + else if (strnstr(kcontrol->id.name, "TX_CDC_DMA_TX_0", + sizeof("TX_CDC_DMA_TX_0"))) + idx = TX_CDC_DMA_TX_0; + else if (strnstr(kcontrol->id.name, "TX_CDC_DMA_TX_3", + sizeof("TX_CDC_DMA_TX_3"))) + idx = TX_CDC_DMA_TX_3; + else if (strnstr(kcontrol->id.name, "TX_CDC_DMA_TX_4", + sizeof("TX_CDC_DMA_TX_4"))) + idx = TX_CDC_DMA_TX_4; + else { + pr_err("%s: unsupported channel: %s\n", + __func__, kcontrol->id.name); + return -EINVAL; + } -static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) + return idx; +} + +static int cdc_dma_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dai_link *dai_link = rtd->dai_link; - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - int rc = 0; + int ch_num = cdc_dma_get_port_idx(kcontrol); - pr_debug("%s: format = %d, rate = %d\n", - __func__, params_format(params), params_rate(params)); + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } - switch (dai_link->id) { - case MSM_BACKEND_DAI_USB_RX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - usb_rx_cfg.bit_format); - rate->min = rate->max = usb_rx_cfg.sample_rate; - channels->min = channels->max = usb_rx_cfg.channels; - break; + pr_debug("%s: cdc_dma_rx_ch = %d\n", __func__, + cdc_dma_rx_cfg[ch_num].channels - 1); + ucontrol->value.integer.value[0] = cdc_dma_rx_cfg[ch_num].channels - 1; + return 0; +} - case MSM_BACKEND_DAI_USB_TX: - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - usb_tx_cfg.bit_format); - rate->min = rate->max = usb_tx_cfg.sample_rate; - channels->min = channels->max = usb_tx_cfg.channels; - break; - case MSM_BACKEND_DAI_AFE_PCM_RX: - channels->min = channels->max = proxy_rx_cfg.channels; - rate->min = rate->max = SAMPLING_RATE_48KHZ; - break; +static int cdc_dma_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); - case MSM_BACKEND_DAI_PRI_TDM_RX_0: - channels->min = channels->max = - tdm_rx_cfg[TDM_PRI][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; - break; + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } - case MSM_BACKEND_DAI_PRI_TDM_TX_0: - channels->min = channels->max = - tdm_tx_cfg[TDM_PRI][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); - rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; - break; + cdc_dma_rx_cfg[ch_num].channels = ucontrol->value.integer.value[0] + 1; - case MSM_BACKEND_DAI_SEC_TDM_RX_0: - channels->min = channels->max = - tdm_rx_cfg[TDM_SEC][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; - break; + pr_debug("%s: cdc_dma_rx_ch = %d\n", __func__, + cdc_dma_rx_cfg[ch_num].channels); + return 1; +} - case MSM_BACKEND_DAI_SEC_TDM_TX_0: - channels->min = channels->max = - tdm_tx_cfg[TDM_SEC][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); - rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; - break; +static int cdc_dma_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); - case MSM_BACKEND_DAI_TERT_TDM_RX_0: - channels->min = channels->max = - tdm_rx_cfg[TDM_TERT][TDM_0].channels; - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); - rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; - break; + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } - case MSM_BACKEND_DAI_TERT_TDM_TX_0: + switch (cdc_dma_rx_cfg[ch_num].bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: cdc_dma_rx_format = %d, ucontrol value = %ld\n", + __func__, cdc_dma_rx_cfg[ch_num].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int cdc_dma_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + switch (ucontrol->value.integer.value[0]) { + case 3: + cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: cdc_dma_rx_format = %d, ucontrol value = %ld\n", + __func__, cdc_dma_rx_cfg[ch_num].bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + + +static int cdc_dma_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + default: + sample_rate_val = 6; + break; + } + return sample_rate_val; +} + +static int cdc_dma_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 9: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 10: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 11: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 12: + sample_rate = SAMPLING_RATE_384KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int cdc_dma_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + ucontrol->value.enumerated.item[0] = + cdc_dma_get_sample_rate_val(cdc_dma_rx_cfg[ch_num].sample_rate); + + pr_debug("%s: cdc_dma_rx_sample_rate = %d\n", __func__, + cdc_dma_rx_cfg[ch_num].sample_rate); + return 0; +} + +static int cdc_dma_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + cdc_dma_rx_cfg[ch_num].sample_rate = + cdc_dma_get_sample_rate(ucontrol->value.enumerated.item[0]); + + + pr_debug("%s: control value = %d, cdc_dma_rx_sample_rate = %d\n", + __func__, ucontrol->value.enumerated.item[0], + cdc_dma_rx_cfg[ch_num].sample_rate); + return 0; +} + +static int cdc_dma_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + pr_debug("%s: cdc_dma_tx_ch = %d\n", __func__, + cdc_dma_tx_cfg[ch_num].channels); + ucontrol->value.integer.value[0] = cdc_dma_tx_cfg[ch_num].channels - 1; + return 0; +} + +static int cdc_dma_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + cdc_dma_tx_cfg[ch_num].channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: cdc_dma_tx_ch = %d\n", __func__, + cdc_dma_tx_cfg[ch_num].channels); + return 1; +} + +static int cdc_dma_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + switch (cdc_dma_tx_cfg[ch_num].sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + default: + sample_rate_val = 6; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: cdc_dma_tx_sample_rate = %d\n", __func__, + cdc_dma_tx_cfg[ch_num].sample_rate); + return 0; +} + +static int cdc_dma_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + switch (ucontrol->value.integer.value[0]) { + case 12: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, cdc_dma_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + cdc_dma_tx_cfg[ch_num].sample_rate); + return 0; +} + +static int cdc_dma_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + switch (cdc_dma_tx_cfg[ch_num].bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: cdc_dma_tx_format = %d, ucontrol value = %ld\n", + __func__, cdc_dma_tx_cfg[ch_num].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int cdc_dma_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + switch (ucontrol->value.integer.value[0]) { + case 3: + cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: cdc_dma_tx_format = %d, ucontrol value = %ld\n", + __func__, cdc_dma_tx_cfg[ch_num].bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int msm_cdc_dma_get_idx_from_beid(int32_t be_id) +{ + int idx = 0; + + switch (be_id) { + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0: + idx = WSA_CDC_DMA_RX_0; + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0: + idx = WSA_CDC_DMA_TX_0; + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1: + idx = WSA_CDC_DMA_RX_1; + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1: + idx = WSA_CDC_DMA_TX_1; + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2: + idx = WSA_CDC_DMA_TX_2; + break; + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_0: + idx = RX_CDC_DMA_RX_0; + break; + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_1: + idx = RX_CDC_DMA_RX_1; + break; + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_2: + idx = RX_CDC_DMA_RX_2; + break; + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_3: + idx = RX_CDC_DMA_RX_3; + break; + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_5: + idx = RX_CDC_DMA_RX_5; + break; + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_0: + idx = TX_CDC_DMA_TX_0; + break; + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_3: + idx = TX_CDC_DMA_TX_3; + break; + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_4: + idx = TX_CDC_DMA_TX_4; + break; + default: + idx = RX_CDC_DMA_RX_0; + break; + } + + return idx; +} + +static const struct snd_kcontrol_new msm_int_snd_controls[] = { + SOC_ENUM_EXT("WSA_CDC_DMA_RX_0 Channels", wsa_cdc_dma_rx_0_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("WSA_CDC_DMA_RX_1 Channels", wsa_cdc_dma_rx_1_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 Channels", rx_cdc_dma_rx_0_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 Channels", rx_cdc_dma_rx_1_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 Channels", rx_cdc_dma_rx_2_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 Channels", rx_cdc_dma_rx_3_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 Channels", rx_cdc_dma_rx_5_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_0 Channels", wsa_cdc_dma_tx_0_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_1 Channels", wsa_cdc_dma_tx_1_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_2 Channels", wsa_cdc_dma_tx_2_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_0 Channels", tx_cdc_dma_tx_0_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_3 Channels", tx_cdc_dma_tx_3_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_4 Channels", tx_cdc_dma_tx_4_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("WSA_CDC_DMA_RX_0 Format", wsa_cdc_dma_rx_0_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("WSA_CDC_DMA_RX_1 Format", wsa_cdc_dma_rx_1_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 Format", rx_cdc_dma_rx_0_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 Format", rx_cdc_dma_rx_1_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 Format", rx_cdc_dma_rx_2_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 Format", rx_cdc_dma_rx_3_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 Format", rx_cdc_dma_rx_5_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_1 Format", wsa_cdc_dma_tx_1_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_2 Format", wsa_cdc_dma_tx_2_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_0 Format", tx_cdc_dma_tx_0_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_3 Format", tx_cdc_dma_tx_3_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_4 Format", tx_cdc_dma_tx_4_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("WSA_CDC_DMA_RX_0 SampleRate", + wsa_cdc_dma_rx_0_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("WSA_CDC_DMA_RX_1 SampleRate", + wsa_cdc_dma_rx_1_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 SampleRate", + rx_cdc_dma_rx_0_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 SampleRate", + rx_cdc_dma_rx_1_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 SampleRate", + rx_cdc_dma_rx_2_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 SampleRate", + rx_cdc_dma_rx_3_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 SampleRate", + rx_cdc_dma_rx_5_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_0 SampleRate", + wsa_cdc_dma_tx_0_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_1 SampleRate", + wsa_cdc_dma_tx_1_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("WSA_CDC_DMA_TX_2 SampleRate", + wsa_cdc_dma_tx_2_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_0 SampleRate", + tx_cdc_dma_tx_0_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_3 SampleRate", + tx_cdc_dma_tx_3_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_4 SampleRate", + tx_cdc_dma_tx_4_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), +}; + +static const struct snd_kcontrol_new msm_common_snd_controls[] = { + SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, + usb_audio_rx_sample_rate_get, + usb_audio_rx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, + usb_audio_tx_sample_rate_get, + usb_audio_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, + usb_audio_rx_format_get, usb_audio_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, + usb_audio_tx_format_get, usb_audio_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("TERT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("SEC_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("TERT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, + usb_audio_rx_ch_get, usb_audio_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, + usb_audio_tx_ch_get, usb_audio_tx_ch_put), + SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, + proxy_rx_ch_get, proxy_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), +}; + +static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), +}; + +static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int rc = 0; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->id) { + case MSM_BACKEND_DAI_USB_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_rx_cfg.bit_format); + rate->min = rate->max = usb_rx_cfg.sample_rate; + channels->min = channels->max = usb_rx_cfg.channels; + break; + + case MSM_BACKEND_DAI_USB_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_tx_cfg.bit_format); + rate->min = rate->max = usb_tx_cfg.sample_rate; + channels->min = channels->max = usb_tx_cfg.channels; + break; + case MSM_BACKEND_DAI_AFE_PCM_RX: + channels->min = channels->max = proxy_rx_cfg.channels; + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + + case MSM_BACKEND_DAI_PRI_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_PRI_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_TX_0: channels->min = channels->max = tdm_tx_cfg[TDM_TERT][TDM_0].channels; param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, @@ -2282,6 +3079,90 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream, return ret; } +static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + int ret = 0; + u32 rx_ch_cdc_dma, tx_ch_cdc_dma; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + u32 user_set_tx_ch = 0; + u32 user_set_rx_ch = 0; + u32 ch_id; + + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, &tx_ch_cdc_dma, &rx_ch_cnt, + &rx_ch_cdc_dma); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + switch (dai_link->id) { + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0: + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_0: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_1: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_2: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_3: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_4: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_5: + { + ch_id = msm_cdc_dma_get_idx_from_beid(dai_link->id); + pr_debug("%s: id %d rx_ch=%d\n", __func__, + ch_id, cdc_dma_rx_cfg[ch_id].channels); + user_set_rx_ch = cdc_dma_rx_cfg[ch_id].channels; + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + user_set_rx_ch, &rx_ch_cdc_dma); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + + } + break; + } + } else { + switch (dai_link->id) { + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0: + { + user_set_tx_ch = msm_vi_feed_tx_ch; + } + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1: + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_0: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_3: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_4: + { + ch_id = msm_cdc_dma_get_idx_from_beid(dai_link->id); + pr_debug("%s: id %d tx_ch=%d\n", __func__, + ch_id, cdc_dma_tx_cfg[ch_id].channels); + user_set_tx_ch = cdc_dma_tx_cfg[ch_id].channels; + } + break; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, user_set_tx_ch, + &tx_ch_cdc_dma, 0, 0); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + } + +err: + return ret; +} + static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) { cpumask_t mask; @@ -2349,52 +3230,247 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) goto clk_off; } } -clk_off: - if (ret < 0) - msm_mi2s_set_sclk(substream, false); -clean_up: - if (ret < 0) - mi2s_intf_conf[index].ref_cnt--; - mutex_unlock(&mi2s_intf_conf[index].lock); -err: - return ret; +clk_off: + if (ret < 0) + msm_mi2s_set_sclk(substream, false); +clean_up: + if (ret < 0) + mi2s_intf_conf[index].ref_cnt--; + mutex_unlock(&mi2s_intf_conf[index].lock); +err: + return ret; +} + +static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int index = rtd->cpu_dai->id; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + if (index < PRIM_MI2S || index >= MI2S_MAX) { + pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); + return; + } + + mutex_lock(&mi2s_intf_conf[index].lock); + if (--mi2s_intf_conf[index].ref_cnt == 0) { + ret = msm_mi2s_set_sclk(substream, false); + if (ret < 0) + pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", + __func__, index, ret); + } + mutex_unlock(&mi2s_intf_conf[index].lock); +} + +static struct snd_soc_ops kona_tdm_be_ops = { + .hw_params = kona_tdm_snd_hw_params, +}; + +static struct snd_soc_ops msm_mi2s_be_ops = { + .startup = msm_mi2s_snd_startup, + .shutdown = msm_mi2s_snd_shutdown, +}; + +static struct snd_soc_ops msm_fe_qos_ops = { + .prepare = msm_fe_qos_prepare, +}; + +static struct snd_soc_ops msm_cdc_dma_be_ops = { + .hw_params = msm_snd_cdc_dma_hw_params, +}; + +static int msm_dmic_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct msm_asoc_mach_data *pdata = NULL; + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + int ret = 0; + u32 dmic_idx; + int *dmic_gpio_cnt; + struct device_node *dmic_gpio; + char *wname; + + wname = strpbrk(w->name, "012345"); + if (!wname) { + dev_err(component->dev, "%s: widget not found\n", __func__); + return -EINVAL; + } + + ret = kstrtouint(wname, 10, &dmic_idx); + if (ret < 0) { + dev_err(component->dev, "%s: Invalid DMIC line on the codec\n", + __func__); + return -EINVAL; + } + + pdata = snd_soc_card_get_drvdata(component->card); + + switch (dmic_idx) { + case 0: + case 1: + dmic_gpio_cnt = &dmic_0_1_gpio_cnt; + dmic_gpio = pdata->dmic01_gpio_p; + break; + case 2: + case 3: + dmic_gpio_cnt = &dmic_2_3_gpio_cnt; + dmic_gpio = pdata->dmic23_gpio_p; + break; + case 4: + case 5: + dmic_gpio_cnt = &dmic_4_5_gpio_cnt; + dmic_gpio = pdata->dmic45_gpio_p; + break; + default: + dev_err(component->dev, "%s: Invalid DMIC Selection\n", + __func__); + return -EINVAL; + } + + dev_dbg(component->dev, "%s: event %d DMIC%d dmic_gpio_cnt %d\n", + __func__, event, dmic_idx, *dmic_gpio_cnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + (*dmic_gpio_cnt)++; + if (*dmic_gpio_cnt == 1) { + ret = msm_cdc_pinctrl_select_active_state( + dmic_gpio); + if (ret < 0) { + pr_err("%s: gpio set cannot be activated %sd", + __func__, "dmic_gpio"); + return ret; + } + } + + break; + case SND_SOC_DAPM_POST_PMD: + (*dmic_gpio_cnt)--; + if (*dmic_gpio_cnt == 0) { + ret = msm_cdc_pinctrl_select_sleep_state( + dmic_gpio); + if (ret < 0) { + pr_err("%s: gpio set cannot be de-activated %sd", + __func__, "dmic_gpio"); + return ret; + } + } + break; + default: + pr_err("%s: invalid DAPM event %d\n", __func__, event); + return -EINVAL; + } + return 0; } -static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) -{ - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - int index = rtd->cpu_dai->id; +static const struct snd_soc_dapm_widget msm_int_dapm_widgets[] = { + SND_SOC_DAPM_MIC("Analog Mic1", NULL), + SND_SOC_DAPM_MIC("Analog Mic2", NULL), + SND_SOC_DAPM_MIC("Analog Mic3", NULL), + SND_SOC_DAPM_MIC("Analog Mic4", NULL), + SND_SOC_DAPM_MIC("Digital Mic0", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic1", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic2", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic3", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic4", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic5", msm_dmic_event), +}; - pr_debug("%s(): substream = %s stream = %d\n", __func__, - substream->name, substream->stream); - if (index < PRIM_MI2S || index >= MI2S_MAX) { - pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); - return; +static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = -EINVAL; + struct snd_soc_component *component; + struct snd_soc_dapm_context *dapm; + struct snd_card *card; + struct snd_info_entry *entry; + struct snd_soc_component *aux_comp; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); + + component = snd_soc_rtdcom_lookup(rtd, "bolero_codec"); + if (!component) { + pr_err("%s: could not find component for bolero_codec\n", + __func__); + return ret; } - mutex_lock(&mi2s_intf_conf[index].lock); - if (--mi2s_intf_conf[index].ref_cnt == 0) { - ret = msm_mi2s_set_sclk(substream, false); - if (ret < 0) - pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", - __func__, index, ret); + dapm = snd_soc_component_get_dapm(component); + + ret = snd_soc_add_component_controls(component, msm_int_snd_controls, + ARRAY_SIZE(msm_int_snd_controls)); + if (ret < 0) { + pr_err("%s: add_component_controls failed: %d\n", + __func__, ret); + return ret; + } + ret = snd_soc_add_component_controls(component, msm_common_snd_controls, + ARRAY_SIZE(msm_common_snd_controls)); + if (ret < 0) { + pr_err("%s: add common snd controls failed: %d\n", + __func__, ret); + return ret; } - mutex_unlock(&mi2s_intf_conf[index].lock); -} -static struct snd_soc_ops kona_tdm_be_ops = { - .hw_params = kona_tdm_snd_hw_params, -}; + snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets, + ARRAY_SIZE(msm_int_dapm_widgets)); -static struct snd_soc_ops msm_mi2s_be_ops = { - .startup = msm_mi2s_snd_startup, - .shutdown = msm_mi2s_snd_shutdown, -}; + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); -static struct snd_soc_ops msm_fe_qos_ops = { - .prepare = msm_fe_qos_prepare, -}; + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic2"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic3"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4"); + + snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK1 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK2 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "WSA AIF VI"); + snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_WSA"); + + snd_soc_dapm_sync(dapm); + + /* + * Send speaker configuration only for WSA8810. + * Default configuration is for WSA8815. + */ + dev_dbg(component->dev, "%s: Number of aux devices: %d\n", + __func__, rtd->card->num_aux_devs); + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->component_dev_list)) { + aux_comp = list_first_entry( + &rtd->card->component_dev_list, + struct snd_soc_component, + card_aux_list); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { + wsa_macro_set_spkr_mode(component, + WSA_MACRO_SPKR_MODE_1); + wsa_macro_set_spkr_gain_offset(component, + WSA_MACRO_GAIN_OFFSET_M1P5_DB); + } + } + card = rtd->card->snd_card; + if (!pdata->codec_root) { + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto err; + } + pdata->codec_root = entry; + } + bolero_info_create_codec_entry(pdata->codec_root, component); + codec_reg_done = true; + return 0; +err: + return ret; +} /* Digital audio interface glue - connects codec <---> CPU */ static struct snd_soc_dai_link msm_common_dai_links[] = { @@ -2915,6 +3991,22 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { }, }; +static struct snd_soc_dai_link msm_bolero_fe_dai_links[] = { + {/* hw:x,37 */ + .name = LPASS_BE_WSA_CDC_DMA_TX_0, + .stream_name = "WSA CDC DMA0 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45057", + .platform_name = "msm-pcm-hostless", + .codec_name = "bolero_codec", + .codec_dai_name = "wsa_macro_vifeedback", + .id = MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_cdc_dma_be_ops, + }, +}; + static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { { .name = MSM_DAILINK_NAME(ASM Loopback), @@ -3347,12 +4439,157 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { }, }; +static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = { + /* WSA CDC DMA Backend DAI Links */ + { + .name = LPASS_BE_WSA_CDC_DMA_RX_0, + .stream_name = "WSA CDC DMA0 Playback", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45056", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "wsa_macro_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .init = &msm_int_audrx_init, + .id = MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_WSA_CDC_DMA_RX_1, + .stream_name = "WSA CDC DMA1 Playback", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45058", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "wsa_macro_rx_mix", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_WSA_CDC_DMA_TX_1, + .stream_name = "WSA CDC DMA1 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45059", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "wsa_macro_echo", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { + /* RX CDC DMA Backend DAI Links */ + { + .name = LPASS_BE_RX_CDC_DMA_RX_0, + .stream_name = "RX CDC DMA0 Playback", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45104", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "rx_macro_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_RX_CDC_DMA_RX_1, + .stream_name = "RX CDC DMA1 Playback", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45106", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "rx_macro_rx2", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_RX_CDC_DMA_RX_2, + .stream_name = "RX CDC DMA2 Playback", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45108", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "rx_macro_rx3", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_RX_CDC_DMA_RX_3, + .stream_name = "RX CDC DMA3 Playback", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45110", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "rx_macro_rx4", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + /* TX CDC DMA Backend DAI Links */ + { + .name = LPASS_BE_TX_CDC_DMA_TX_3, + .stream_name = "TX CDC DMA3 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45111", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "tx_macro_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_TX_CDC_DMA_TX_4, + .stream_name = "TX CDC DMA4 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45113", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "tx_macro_tx2", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, +}; + static struct snd_soc_dai_link msm_kona_dai_links[ - ARRAY_SIZE(msm_common_dai_links) + - ARRAY_SIZE(msm_common_misc_fe_dai_links) + - ARRAY_SIZE(msm_common_be_dai_links) + - ARRAY_SIZE(msm_mi2s_be_dai_links) + - ARRAY_SIZE(msm_auxpcm_be_dai_links)]; + ARRAY_SIZE(msm_common_dai_links) + + ARRAY_SIZE(msm_bolero_fe_dai_links) + + ARRAY_SIZE(msm_common_misc_fe_dai_links) + + ARRAY_SIZE(msm_common_be_dai_links) + + ARRAY_SIZE(msm_mi2s_be_dai_links) + + ARRAY_SIZE(msm_auxpcm_be_dai_links) + + ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links) + + ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links)]; static int msm_populate_dai_link_component_of_node( struct snd_soc_card *card) @@ -3537,6 +4774,8 @@ static struct snd_soc_dai_link msm_stub_dai_links[ ARRAY_SIZE(msm_stub_be_dai_links)]; static const struct of_device_id kona_asoc_machine_of_match[] = { + { .compatible = "qcom,kona-asoc-snd", + .data = "codec"}, { .compatible = "qcom,kona-asoc-snd-stub", .data = "stub_codec"}, {}, @@ -3569,6 +4808,12 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) sizeof(msm_common_dai_links)); total_links += ARRAY_SIZE(msm_common_dai_links); + memcpy(msm_kona_dai_links + total_links, + msm_bolero_fe_dai_links, + sizeof(msm_bolero_fe_dai_links)); + total_links += + ARRAY_SIZE(msm_bolero_fe_dai_links); + memcpy(msm_kona_dai_links + total_links, msm_common_misc_fe_dai_links, sizeof(msm_common_misc_fe_dai_links)); @@ -3579,6 +4824,18 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) sizeof(msm_common_be_dai_links)); total_links += ARRAY_SIZE(msm_common_be_dai_links); + memcpy(msm_kona_dai_links + total_links, + msm_wsa_cdc_dma_be_dai_links, + sizeof(msm_wsa_cdc_dma_be_dai_links)); + total_links += + ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links); + + memcpy(msm_kona_dai_links + total_links, + msm_rx_tx_cdc_dma_be_dai_links, + sizeof(msm_rx_tx_cdc_dma_be_dai_links)); + total_links += + ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links); + rc = of_property_read_u32(dev->of_node, "qcom,mi2s-audio-intf", &mi2s_audio_intf); if (rc) { @@ -3635,6 +4892,374 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) return card; } +static int msm_wsa881x_init(struct snd_soc_component *component) +{ + u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {0, 1, 2, 3}; + u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {0, 1, 2, 3}; + u8 spkleft_port_types[WSA881X_MAX_SWR_PORTS] = {SPKR_L, SPKR_L_COMP, + SPKR_L_BOOST, SPKR_L_VI}; + u8 spkright_port_types[WSA881X_MAX_SWR_PORTS] = {SPKR_R, SPKR_R_COMP, + SPKR_R_BOOST, SPKR_R_VI}; + unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; + unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; + struct msm_asoc_mach_data *pdata; + struct snd_soc_dapm_context *dapm; + struct snd_card *card; + struct snd_info_entry *entry; + int ret = 0; + + if (!component) { + pr_err("%s component is NULL\n", __func__); + return -EINVAL; + } + + card = component->card->snd_card; + dapm = snd_soc_component_get_dapm(component); + + if (!strcmp(component->name_prefix, "SpkrLeft")) { + dev_dbg(component->dev, "%s: setting left ch map to codec %s\n", + __func__, component->name); + wsa881x_set_channel_map(component, &spkleft_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0], &spkleft_port_types[0]); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); + } + } else if (!strcmp(component->name_prefix, "SpkrRight")) { + dev_dbg(component->dev, "%s: setting right ch map to codec %s\n", + __func__, component->name); + wsa881x_set_channel_map(component, &spkright_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0], &spkright_port_types[0]); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); + } + } else { + dev_err(component->dev, "%s: wrong codec name %s\n", __func__, + component->name); + ret = -EINVAL; + goto err; + } + pdata = snd_soc_card_get_drvdata(component->card); + if (!pdata->codec_root) { + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_err("%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto err; + } + pdata->codec_root = entry; + } + wsa881x_codec_info_create_codec_entry(pdata->codec_root, + component); +err: + return ret; +} + +static int msm_aux_codec_init(struct snd_soc_component *component) +{ + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + int ret = 0; + struct snd_info_entry *entry; + struct snd_card *card = component->card->snd_card; + struct msm_asoc_mach_data *pdata; + + snd_soc_dapm_ignore_suspend(dapm, "EAR"); + snd_soc_dapm_ignore_suspend(dapm, "AUX"); + snd_soc_dapm_ignore_suspend(dapm, "HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC4"); + snd_soc_dapm_sync(dapm); + + pdata = snd_soc_card_get_drvdata(component->card); + if (!pdata->codec_root) { + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_err("%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto codec_root_err; + } + pdata->codec_root = entry; + } +codec_root_err: + return ret; +} + +static int msm_init_aux_dev(struct platform_device *pdev, + struct snd_soc_card *card) +{ + struct device_node *wsa_of_node; + struct device_node *aux_codec_of_node; + u32 wsa_max_devs; + u32 wsa_dev_cnt; + u32 codec_aux_dev_cnt = 0; + u32 bolero_codec = 0; + int i; + struct msm_wsa881x_dev_info *wsa881x_dev_info; + struct aux_codec_dev_info *aux_cdc_dev_info; + const char *auxdev_name_prefix[1]; + char *dev_name_str = NULL; + int found = 0; + int codecs_found = 0; + int ret = 0; + + /* Get maximum WSA device count for this platform */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,wsa-max-devs", &wsa_max_devs); + if (ret) { + dev_info(&pdev->dev, + "%s: wsa-max-devs property missing in DT %s, ret = %d\n", + __func__, pdev->dev.of_node->full_name, ret); + wsa_max_devs = 0; + goto codec_aux_dev; + } + if (wsa_max_devs == 0) { + dev_warn(&pdev->dev, + "%s: Max WSA devices is 0 for this target?\n", + __func__); + goto codec_aux_dev; + } + + /* Get count of WSA device phandles for this platform */ + wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node, + "qcom,wsa-devs", NULL); + if (wsa_dev_cnt == -ENOENT) { + dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n", + __func__); + goto err; + } else if (wsa_dev_cnt <= 0) { + dev_err(&pdev->dev, + "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n", + __func__, wsa_dev_cnt); + ret = -EINVAL; + goto err; + } + + /* + * Expect total phandles count to be NOT less than maximum possible + * WSA count. However, if it is less, then assign same value to + * max count as well. + */ + if (wsa_dev_cnt < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n", + __func__, wsa_max_devs, wsa_dev_cnt); + wsa_max_devs = wsa_dev_cnt; + } + + /* Make sure prefix string passed for each WSA device */ + ret = of_property_count_strings(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix"); + if (ret != wsa_dev_cnt) { + dev_err(&pdev->dev, + "%s: expecting %d wsa prefix. Defined only %d in DT\n", + __func__, wsa_dev_cnt, ret); + ret = -EINVAL; + goto err; + } + + /* + * Alloc mem to store phandle and index info of WSA device, if already + * registered with ALSA core + */ + wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs, + sizeof(struct msm_wsa881x_dev_info), + GFP_KERNEL); + if (!wsa881x_dev_info) { + ret = -ENOMEM; + goto err; + } + + /* + * search and check whether all WSA devices are already + * registered with ALSA core or not. If found a node, store + * the node and the index in a local array of struct for later + * use. + */ + for (i = 0; i < wsa_dev_cnt; i++) { + wsa_of_node = of_parse_phandle(pdev->dev.of_node, + "qcom,wsa-devs", i); + if (unlikely(!wsa_of_node)) { + /* we should not be here */ + dev_err(&pdev->dev, + "%s: wsa dev node is not present\n", + __func__); + ret = -EINVAL; + goto err; + } + if (soc_find_component(wsa_of_node, NULL)) { + /* WSA device registered with ALSA core */ + wsa881x_dev_info[found].of_node = wsa_of_node; + wsa881x_dev_info[found].index = i; + found++; + if (found == wsa_max_devs) + break; + } + } + + if (found < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: failed to find %d components. Found only %d\n", + __func__, wsa_max_devs, found); + return -EPROBE_DEFER; + } + dev_info(&pdev->dev, + "%s: found %d wsa881x devices registered with ALSA core\n", + __func__, found); + +codec_aux_dev: + ret = of_property_read_u32(pdev->dev.of_node, "qcom,bolero-codec", &bolero_codec); + if (ret) + dev_dbg(&pdev->dev, "%s: No DT match for bolero codec\n", __func__); + + if (bolero_codec) { + /* Get count of aux codec device phandles for this platform */ + codec_aux_dev_cnt = of_count_phandle_with_args( + pdev->dev.of_node, + "qcom,codec-aux-devs", NULL); + if (codec_aux_dev_cnt == -ENOENT) { + dev_warn(&pdev->dev, "%s: No aux codec defined in DT.\n", + __func__); + goto err; + } else if (codec_aux_dev_cnt <= 0) { + dev_err(&pdev->dev, + "%s: Error reading aux codec device from DT, dev_cnt=%d\n", + __func__, codec_aux_dev_cnt); + ret = -EINVAL; + goto err; + } + + /* + * Alloc mem to store phandle and index info of aux codec + * if already registered with ALSA core + */ + aux_cdc_dev_info = devm_kcalloc(&pdev->dev, codec_aux_dev_cnt, + sizeof(struct aux_codec_dev_info), + GFP_KERNEL); + if (!aux_cdc_dev_info) { + ret = -ENOMEM; + goto err; + } + + /* + * search and check whether all aux codecs are already + * registered with ALSA core or not. If found a node, store + * the node and the index in a local array of struct for later + * use. + */ + for (i = 0; i < codec_aux_dev_cnt; i++) { + aux_codec_of_node = of_parse_phandle(pdev->dev.of_node, + "qcom,codec-aux-devs", i); + if (unlikely(!aux_codec_of_node)) { + /* we should not be here */ + dev_err(&pdev->dev, + "%s: aux codec dev node is not present\n", + __func__); + ret = -EINVAL; + goto err; + } + if (soc_find_component(aux_codec_of_node, NULL)) { + /* AUX codec registered with ALSA core */ + aux_cdc_dev_info[codecs_found].of_node = + aux_codec_of_node; + aux_cdc_dev_info[codecs_found].index = i; + codecs_found++; + } + } + + if (codecs_found < codec_aux_dev_cnt) { + dev_dbg(&pdev->dev, + "%s: failed to find %d components. Found only %d\n", + __func__, codec_aux_dev_cnt, codecs_found); + return -EPROBE_DEFER; + } + dev_info(&pdev->dev, + "%s: found %d AUX codecs registered with ALSA core\n", + __func__, codecs_found); + + } + + card->num_aux_devs = wsa_max_devs + codec_aux_dev_cnt; + card->num_configs = wsa_max_devs + codec_aux_dev_cnt; + + /* Alloc array of AUX devs struct */ + msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_aux_dev), + GFP_KERNEL); + if (!msm_aux_dev) { + ret = -ENOMEM; + goto err; + } + + /* Alloc array of codec conf struct */ + msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_configs, + sizeof(struct snd_soc_codec_conf), + GFP_KERNEL); + if (!msm_codec_conf) { + ret = -ENOMEM; + goto err; + } + + for (i = 0; i < wsa_max_devs; i++) { + dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN, + GFP_KERNEL); + if (!dev_name_str) { + ret = -ENOMEM; + goto err; + } + + ret = of_property_read_string_index(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix", + wsa881x_dev_info[i].index, + auxdev_name_prefix); + if (ret) { + dev_err(&pdev->dev, + "%s: failed to read wsa aux dev prefix, ret = %d\n", + __func__, ret); + ret = -EINVAL; + goto err; + } + + snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i); + msm_aux_dev[i].name = dev_name_str; + msm_aux_dev[i].codec_name = NULL; + msm_aux_dev[i].codec_of_node = + wsa881x_dev_info[i].of_node; + msm_aux_dev[i].init = msm_wsa881x_init; + msm_codec_conf[i].dev_name = NULL; + msm_codec_conf[i].name_prefix = auxdev_name_prefix[0]; + msm_codec_conf[i].of_node = + wsa881x_dev_info[i].of_node; + } + + for (i = 0; i < codec_aux_dev_cnt; i++) { + msm_aux_dev[wsa_max_devs + i].name = NULL; + msm_aux_dev[wsa_max_devs + i].codec_name = NULL; + msm_aux_dev[wsa_max_devs + i].codec_of_node = + aux_cdc_dev_info[i].of_node; + msm_aux_dev[wsa_max_devs + i].init = msm_aux_codec_init; + msm_codec_conf[wsa_max_devs + i].dev_name = NULL; + msm_codec_conf[wsa_max_devs + i].name_prefix = + NULL; + msm_codec_conf[wsa_max_devs + i].of_node = + aux_cdc_dev_info[i].of_node; + } + + card->codec_conf = msm_codec_conf; + card->aux_dev = msm_aux_dev; +err: + return ret; +} + static void msm_i2s_auxpcm_init(struct platform_device *pdev) { int count = 0; @@ -3800,6 +5425,10 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) goto err; } + ret = msm_init_aux_dev(pdev, card); + if (ret) + goto err; + ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret == -EPROBE_DEFER) { if (codec_reg_done) @@ -3853,6 +5482,17 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) } msm_i2s_auxpcm_init(pdev); + if (strcmp(card->name, "kona-mtp-snd-card")) { + pdata->dmic01_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-dmic01-gpios", + 0); + pdata->dmic23_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-dmic23-gpios", + 0); + pdata->dmic45_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-dmic45-gpios", + 0); + } ret = msm_audio_ssr_register(&pdev->dev); if (ret) -- GitLab From b0e04799e4bb9d751bb3f527dfb835b357672f98 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 27 Sep 2018 18:46:44 +0800 Subject: [PATCH 0727/1645] ASoC: config: add config to compile audio drivers for kona Add config to compile audio drivers for kona. Change-Id: I3367a68d0109c80de8525fd74ebaef2959684865 Signed-off-by: Meng Wang --- Android.mk | 7 ++++-- asoc/Android.mk | 7 +++++- asoc/Kbuild | 9 +++++++- asoc/codecs/Android.mk | 8 ++++++- asoc/codecs/Kbuild | 16 +++++++++++++- asoc/codecs/bolero/Android.mk | 8 +++++-- asoc/codecs/bolero/Kbuild | 5 +++++ asoc/codecs/ep92/Android.mk | 2 +- asoc/codecs/ep92/Kbuild | 2 +- asoc/codecs/wcd937x/Android.mk | 2 +- asoc/platform_init.h | 16 +++++++++++--- config/konaauto.conf | 36 ++++++++++++++++++++++++++++++ config/konaautoconf.h | 40 ++++++++++++++++++++++++++++++++++ dsp/Android.mk | 6 ++++- dsp/Kbuild | 9 +++++++- dsp/codecs/Android.mk | 6 ++++- dsp/codecs/Kbuild | 5 +++++ dsp/q6_init.h | 16 +++++++++++--- include/asoc/pdata.h | 5 +++++ include/asoc/wcd-irq.h | 3 ++- ipc/Android.mk | 8 ++++++- ipc/Kbuild | 5 +++++ soc/Android.mk | 8 +++++-- soc/Kbuild | 5 +++++ 24 files changed, 210 insertions(+), 24 deletions(-) create mode 100644 config/konaauto.conf create mode 100644 config/konaautoconf.h diff --git a/Android.mk b/Android.mk index 76813c110967..c10d1caf8c09 100644 --- a/Android.mk +++ b/Android.mk @@ -3,7 +3,7 @@ MY_LOCAL_PATH := $(call my-dir) UAPI_OUT := $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/include -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona),true) $(shell mkdir -p $(UAPI_OUT)/linux;) $(shell mkdir -p $(UAPI_OUT)/sound;) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers) @@ -12,7 +12,6 @@ $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/codecs $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers) -$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers) include $(MY_LOCAL_PATH)/include/uapi/Android.mk include $(MY_LOCAL_PATH)/ipc/Android.mk @@ -21,6 +20,10 @@ include $(MY_LOCAL_PATH)/dsp/codecs/Android.mk include $(MY_LOCAL_PATH)/soc/Android.mk include $(MY_LOCAL_PATH)/asoc/Android.mk include $(MY_LOCAL_PATH)/asoc/codecs/Android.mk +endif + +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk endif diff --git a/asoc/Android.mk b/asoc/Android.mk index 793712008402..db01167eba1e 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -18,9 +18,14 @@ TARGET := trinket AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif +ifeq ($(call is-board-platform,kona),true) +TARGET := kona +AUDIO_SELECT := CONFIG_SND_SOC_KONA=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/Kbuild b/asoc/Kbuild index ee290b26a7cc..945d554c7014 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -29,6 +29,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_KONA), y) + include $(AUDIO_ROOT)/config/konaauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h + endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export @@ -99,7 +104,6 @@ ifdef CONFIG_SND_SOC_QDSP6V2 PLATFORM_OBJS += msm-dai-fe.o PLATFORM_OBJS += msm-dai-q6-hdmi-v2.o PLATFORM_OBJS += msm-dai-q6-v2.o - PLATFORM_OBJS += msm-dai-slim.o PLATFORM_OBJS += msm-dai-stub-v2.o PLATFORM_OBJS += msm-lsm-client.o PLATFORM_OBJS += msm-pcm-afe-v2.o @@ -115,6 +119,9 @@ ifdef CONFIG_SND_SOC_QDSP6V2 PLATFORM_OBJS += msm-transcode-loopback-q6-v2.o PLATFORM_OBJS += platform_init.o endif +ifdef CONFIG_WCD9XXX_CODEC_CORE + PLATFORM_OBJS += msm-dai-slim.o +endif ifdef CONFIG_DOLBY_DS2 PLATFORM_OBJS += msm-ds2-dap-config.o endif diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index 8eb61c1d01fe..b73b983ca01a 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -15,9 +15,13 @@ ifeq ($(call is-board-platform,$(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif +ifeq ($(call is-board-platform,kona),true) +AUDIO_SELECT := CONFIG_SND_SOC_KONA=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona),true) LOCAL_PATH := $(call my-dir) @@ -70,6 +74,7 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk endif ########################################################### +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd_spi.ko LOCAL_MODULE_KBUILD_NAME := wcd_spi_dlkm.ko @@ -77,6 +82,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk +endif ########################################################### ifeq ($(call is-board-platform-in-list, ),true) include $(CLEAR_VARS) diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index ee4c61f92959..a4cbc45d7505 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -29,6 +29,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_KONA), y) + include $(AUDIO_ROOT)/config/konaauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h + endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export @@ -81,10 +86,18 @@ ifdef CONFIG_WCD9XXX_CODEC_CORE CORE_OBJS += wcd934x/wcd934x-tables.o endif +ifdef CONFIG_WCD9XXX_CODEC_CORE_V2 + CORE_OBJS += msm-cdc-pinctrl.o + CORE_OBJS += msm-cdc-supply.o +endif + ifdef CONFIG_SND_SOC_WCD9XXX_V2 - WCD9XXX_OBJS += wcd-clsh.o +ifdef CONFIG_WCD9XXX_CODEC_CORE WCD9XXX_OBJS += wcd9xxx-common-v2.o WCD9XXX_OBJS += wcd9xxx-resmgr-v2.o +else + WCD9XXX_OBJS += wcd-clsh.o +endif WCD9XXX_OBJS += wcdcal-hwdep.o WCD9XXX_OBJS += wcd9xxx-soc-init.o WCD9XXX_OBJS += wcd-dsp-utils.o @@ -181,6 +194,7 @@ ifeq ($(KERNEL_BUILD), 1) endif # Module information used by KBuild framework obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd_core_dlkm.o +obj-$(CONFIG_WCD9XXX_CODEC_CORE_V2) += wcd_core_dlkm.o wcd_core_dlkm-y := $(CORE_OBJS) obj-$(CONFIG_SND_SOC_WCD9XXX_V2) += wcd9xxx_dlkm.o diff --git a/asoc/codecs/bolero/Android.mk b/asoc/codecs/bolero/Android.mk index e858207320f9..d96d61645ef7 100644 --- a/asoc/codecs/bolero/Android.mk +++ b/asoc/codecs/bolero/Android.mk @@ -7,9 +7,13 @@ ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif +ifeq ($(call is-board-platform,kona),true) +AUDIO_SELECT := CONFIG_SND_SOC_KONA=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona),true) LOCAL_PATH := $(call my-dir) @@ -17,7 +21,7 @@ LOCAL_PATH := $(call my-dir) ifneq ($(findstring vendor,$(LOCAL_PATH)),) ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel endif # opensource DLKM_DIR := $(TOP)/device/qcom/common/dlkm diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild index 1c60ec6fa47e..f01f523dcfb0 100644 --- a/asoc/codecs/bolero/Kbuild +++ b/asoc/codecs/bolero/Kbuild @@ -26,6 +26,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_KONA), y) + include $(AUDIO_ROOT)/config/konaauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h + endif ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf export diff --git a/asoc/codecs/ep92/Android.mk b/asoc/codecs/ep92/Android.mk index c2ac0599f7d8..e50f8ebe8609 100644 --- a/asoc/codecs/ep92/Android.mk +++ b/asoc/codecs/ep92/Android.mk @@ -17,7 +17,7 @@ LOCAL_PATH := $(call my-dir) ifneq ($(findstring vendor,$(LOCAL_PATH)),) ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel endif # opensource DLKM_DIR := $(TOP)/device/qcom/common/dlkm diff --git a/asoc/codecs/ep92/Kbuild b/asoc/codecs/ep92/Kbuild index 1b38aad9fff9..fc46a72f775d 100644 --- a/asoc/codecs/ep92/Kbuild +++ b/asoc/codecs/ep92/Kbuild @@ -11,7 +11,7 @@ endif ifeq ($(KERNEL_BUILD), 1) # These are configurable via Kconfig for kernel-based builds # Need to explicitly configure for Android-based builds - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.19 + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.19 AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio endif diff --git a/asoc/codecs/wcd937x/Android.mk b/asoc/codecs/wcd937x/Android.mk index 95d8058d01ee..cbd087733d06 100644 --- a/asoc/codecs/wcd937x/Android.mk +++ b/asoc/codecs/wcd937x/Android.mk @@ -17,7 +17,7 @@ LOCAL_PATH := $(call my-dir) ifneq ($(findstring vendor,$(LOCAL_PATH)),) ifneq ($(findstring opensource,$(LOCAL_PATH)),) - AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel endif # opensource DLKM_DIR := $(TOP)/device/qcom/common/dlkm diff --git a/asoc/platform_init.h b/asoc/platform_init.h index 17f07845e627..caa54042cff4 100644 --- a/asoc/platform_init.h +++ b/asoc/platform_init.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ #ifndef __PLATFORM_INIT_H__ @@ -9,7 +9,6 @@ int msm_compress_dsp_init(void); int msm_fe_dai_init(void); int msm_dai_q6_hdmi_init(void); int msm_dai_q6_init(void); -int msm_dai_slim_init(void); int msm_dai_stub_init(void); int msm_lsm_client_init(void); int msm_pcm_afe_init(void); @@ -39,11 +38,22 @@ void msm_pcm_dtmf_exit(void); void msm_pcm_afe_exit(void); void msm_lsm_client_exit(void); void msm_dai_stub_exit(void); -void msm_dai_slim_exit(void); void msm_dai_q6_exit(void); void msm_dai_q6_hdmi_exit(void); void msm_fe_dai_exit(void); void msm_compress_dsp_exit(void); +#if IS_ENABLED(CONFIG_WCD9XXX_CODEC_CORE) +int msm_dai_slim_init(void); +void msm_dai_slim_exit(void); +#else +static inline int msm_dai_slim_init(void) +{ + return 0; +}; +static inline void msm_dai_slim_exit(void) +{ +}; +#endif #endif diff --git a/config/konaauto.conf b/config/konaauto.conf new file mode 100644 index 000000000000..328b67f8bdb0 --- /dev/null +++ b/config/konaauto.conf @@ -0,0 +1,36 @@ +CONFIG_PINCTRL_WCD=m +CONFIG_AUDIO_EXT_CLK=m +CONFIG_SND_SOC_WCD9XXX_V2=m +CONFIG_SND_SOC_WCD_MBHC=m +CONFIG_SND_SOC_WSA881X=m +CONFIG_WCD9XXX_CODEC_CORE_V2=m +CONFIG_MSM_CDC_PINCTRL=m +CONFIG_MSM_QDSP6V2_CODECS=m +CONFIG_MSM_ULTRASOUND=m +CONFIG_MSM_QDSP6_APRV2_RPMSG=m +CONFIG_MSM_ADSP_LOADER=m +CONFIG_REGMAP_SWR=m +CONFIG_MSM_QDSP6_SSR=m +CONFIG_MSM_QDSP6_PDR=m +CONFIG_MSM_QDSP6_NOTIFIER=m +CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +CONFIG_SOUNDWIRE=m +CONFIG_SOUNDWIRE_MSTR_CTRL=m +CONFIG_SND_SOC_QDSP6V2=m +CONFIG_SND_SOC_WCD_MBHC_ADC=m +CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m +CONFIG_QTI_PP=m +CONFIG_SND_HWDEP_ROUTING=m +CONFIG_SND_SOC_MSM_STUB=m +CONFIG_MSM_AVTIMER=m +CONFIG_SND_SOC_BOLERO=m +CONFIG_WSA_MACRO=m +CONFIG_VA_MACRO=m +CONFIG_RX_MACRO=m +CONFIG_TX_MACRO=m +CONFIG_SND_SOC_WCD_IRQ=m +CONFIG_SND_SOC_WCD938X=m +CONFIG_SND_SOC_WCD938X_SLAVE=m +CONFIG_SND_SOC_KONA=m +CONFIG_SND_EVENT=m diff --git a/config/konaautoconf.h b/config/konaautoconf.h new file mode 100644 index 000000000000..4e6da4a0bee1 --- /dev/null +++ b/config/konaautoconf.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#define CONFIG_PINCTRL_WCD 1 +#define CONFIG_AUDIO_EXT_CLK 1 +#define CONFIG_SND_SOC_WCD9XXX_V2 1 +#define CONFIG_SND_SOC_WCD_MBHC 1 +#define CONFIG_SND_SOC_WSA881X 1 +#define CONFIG_WCD9XXX_CODEC_CORE_V2 1 +#define CONFIG_MSM_CDC_PINCTRL 1 +#define CONFIG_MSM_QDSP6V2_CODECS 1 +#define CONFIG_MSM_ULTRASOUND 1 +#define CONFIG_MSM_QDSP6_APRV2_RPMSG 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_MSM_ADSP_LOADER 1 +#define CONFIG_REGMAP_SWR 1 +#define CONFIG_MSM_QDSP6_SSR 1 +#define CONFIG_MSM_QDSP6_PDR 1 +#define CONFIG_MSM_QDSP6_NOTIFIER 1 +#define CONFIG_SND_SOC_MSM_HOSTLESS_PCM 1 +#define CONFIG_SOUNDWIRE 1 +#define CONFIG_SOUNDWIRE_MSTR_CTRL 1 +#define CONFIG_SND_SOC_WCD_MBHC_ADC 1 +#define CONFIG_SND_SOC_QDSP6V2 1 +#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 +#define CONFIG_QTI_PP 1 +#define CONFIG_SND_HWDEP_ROUTING 1 +#define CONFIG_SND_SOC_MSM_STUB 1 +#define CONFIG_MSM_AVTIMER 1 +#define CONFIG_SND_SOC_BOLERO 1 +#define CONFIG_WSA_MACRO 1 +#define CONFIG_VA_MACRO 1 +#define CONFIG_RX_MACRO 1 +#define CONFIG_TX_MACRO 1 +#define CONFIG_SND_SOC_WCD_IRQ 1 +#define CONFIG_SND_SOC_WCD938X 1 +#define CONFIG_SND_SOC_WCD938X_SLAVE 1 +#define CONFIG_SND_SOC_KONA 1 +#define CONFIG_SND_EVENT 1 diff --git a/dsp/Android.mk b/dsp/Android.mk index c81a1bdc5255..ddaebe2d6168 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -11,9 +11,13 @@ ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif +ifeq ($(call is-board-platform, kona),true) +AUDIO_SELECT := CONFIG_SND_SOC_KONA=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/Kbuild b/dsp/Kbuild index 724dc12aef21..11e87c2068eb 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -24,6 +24,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_KONA), y) + include $(AUDIO_ROOT)/config/konaauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export @@ -82,13 +87,15 @@ ifdef CONFIG_SND_SOC_MSM_QDSP6V2_INTF Q6_OBJS += q6common.o Q6_OBJS += rtac.o Q6_OBJS += q6lsm.o - Q6_OBJS += audio_slimslave.o Q6_OBJS += adsp_err.o Q6_OBJS += msm_audio_ion.o Q6_OBJS += avtimer.o Q6_OBJS += q6_init.o endif +ifdef CONFIG_WCD9XXX_CODEC_CORE + Q6_OBJS += audio_slimslave.o +endif ifdef CONFIG_DTS_SRS_TM Q6_OBJS += msm-dts-srs-tm-config.o endif diff --git a/dsp/codecs/Android.mk b/dsp/codecs/Android.mk index 62f6db80a881..25726ace8f31 100644 --- a/dsp/codecs/Android.mk +++ b/dsp/codecs/Android.mk @@ -11,9 +11,13 @@ ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif +ifeq ($(call is-board-platform,kona),true) +AUDIO_SELECT := CONFIG_SND_SOC_KONA=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 54d64f2d8755..c80cace5eec2 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -24,6 +24,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_KONA), y) + include $(AUDIO_ROOT)/config/konaauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/dsp/q6_init.h b/dsp/q6_init.h index 71af2dacdff5..21be5241ac68 100644 --- a/dsp/q6_init.h +++ b/dsp/q6_init.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ #ifndef __Q6_INIT_H__ @@ -15,7 +15,6 @@ int audio_cal_init(void); int core_init(void); int rtac_init(void); int msm_audio_ion_init(void); -int audio_slimslave_init(void); int avtimer_init(void); #ifdef CONFIG_MSM_MDF int msm_mdf_init(void); @@ -33,7 +32,6 @@ static inline void msm_mdf_exit(void) #endif void avtimer_exit(void); -void audio_slimslave_exit(void); void msm_audio_ion_exit(void); void rtac_exit(void); void core_exit(void); @@ -44,5 +42,17 @@ void q6asm_exit(void); void afe_exit(void); void adm_exit(void); void adsp_err_exit(void); +#if IS_ENABLED(CONFIG_WCD9XXX_CODEC_CORE) +int audio_slimslave_init(void); +void audio_slimslave_exit(void); +#else +static inline int audio_slimslave_init(void) +{ + return 0; +}; +static inline void audio_slimslave_exit(void) +{ +}; +#endif #endif diff --git a/include/asoc/pdata.h b/include/asoc/pdata.h index 1182ef7881a6..d24d56aed3c8 100644 --- a/include/asoc/pdata.h +++ b/include/asoc/pdata.h @@ -6,7 +6,10 @@ #define __MFD_WCD9XXX_PDATA_H__ +#if IS_ENABLED(CONFIG_WCD9XXX_CODEC_CORE) #include +#endif + #include "msm-cdc-supply.h" #define MICBIAS_EXT_BYP_CAP 0x00 @@ -177,7 +180,9 @@ struct wcd9xxx_pdata { struct device_node *micb_en_ctl; struct device_node *wcd_rst_np; struct wcd9xxx_amic amic_settings; +#if IS_ENABLED(CONFIG_WCD9XXX_CODEC_CORE) struct slim_device slimbus_slave_device; +#endif struct wcd9xxx_micbias_setting micbias; struct wcd9xxx_ocp_setting ocp; struct cdc_regulator *regulator; diff --git a/include/asoc/wcd-irq.h b/include/asoc/wcd-irq.h index 1388cfcb778f..5460e18067c3 100644 --- a/include/asoc/wcd-irq.h +++ b/include/asoc/wcd-irq.h @@ -18,7 +18,8 @@ struct wcd_irq_info { struct device *dev; }; -#if IS_ENABLED(CONFIG_WCD9XXX_CODEC_CORE) +#if (IS_ENABLED(CONFIG_WCD9XXX_CODEC_CORE) | \ + IS_ENABLED(CONFIG_WCD9XXX_CODEC_CORE_V2)) int wcd_irq_init(struct wcd_irq_info *irq_info, struct irq_domain **virq); int wcd_irq_exit(struct wcd_irq_info *irq_info, struct irq_domain *virq); int wcd_request_irq(struct wcd_irq_info *irq_info, int irq, const char *name, diff --git a/ipc/Android.mk b/ipc/Android.mk index b54e5225b6a1..066c5b801c91 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -11,9 +11,13 @@ ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif +ifeq ($(call is-board-platform,kona),true) +AUDIO_SELECT := CONFIG_SND_SOC_KONA=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona),true) LOCAL_PATH := $(call my-dir) @@ -48,6 +52,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wglink.ko LOCAL_MODULE_KBUILD_NAME := wglink_dlkm.ko @@ -55,6 +60,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk +endif ########################################################### endif # DLKM check diff --git a/ipc/Kbuild b/ipc/Kbuild index 484d79a37fa8..3577623d5a14 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -25,6 +25,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_KONA), y) + include $(AUDIO_ROOT)/config/konaauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/soc/Android.mk b/soc/Android.mk index 7a8bd0e8fbc6..8ce2c7515f7a 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -11,9 +11,13 @@ ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif +ifeq ($(call is-board-platform,kona),true) +AUDIO_SELECT := CONFIG_SND_SOC_KONA=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona),true) LOCAL_PATH := $(call my-dir) @@ -74,7 +78,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### -ifeq ($(call is-board-platform-in-list, $(MSMSTEPPE)),true) +ifeq ($(call is-board-platform-in-list, $(MSMSTEPPE) kona),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_snd_event.ko LOCAL_MODULE_KBUILD_NAME := snd_event_dlkm.ko diff --git a/soc/Kbuild b/soc/Kbuild index 4e545778bfeb..12d99c3dc059 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -19,6 +19,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif + ifeq ($(CONFIG_ARCH_KONA), y) + include $(AUDIO_ROOT)/config/konaauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h + endif ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm6150auto.conf export -- GitLab From 7eef68ef9e942068ee9f9fbcbb996f9c884e4b9f Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 13 Dec 2018 17:45:02 -0800 Subject: [PATCH 0728/1645] ASoC: msm: Get the soundwire port configuration Send the kona platform specific soundwire port configuration to the soundwire master driver through machine driver. Change-Id: I1144d00b6bd430f330833141e681dcc93bfff9d2 Signed-off-by: Karthikeyan Mani --- asoc/kona.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asoc/kona.c b/asoc/kona.c index e4dce7d4b352..a312e6eac090 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include "device_event.h" @@ -31,6 +32,7 @@ #include "codecs/bolero/bolero-cdc.h" #include #include "codecs/bolero/wsa-macro.h" +#include "sm8250-port-config.h" #define DRV_NAME "kona-asoc-snd" #define __CHIPSET__ "KONA " @@ -3452,6 +3454,8 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) wsa_macro_set_spkr_gain_offset(component, WSA_MACRO_GAIN_OFFSET_M1P5_DB); } + bolero_set_port_map(component, ARRAY_SIZE(sm_port_map), + sm_port_map); } card = rtd->card->snd_card; if (!pdata->codec_root) { -- GitLab From 63f481553592839f2da47d70abb10d2253f7e13a Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 15 Nov 2018 01:08:03 +0530 Subject: [PATCH 0729/1645] soc: swr-mstr: Support to execute commands on command ignore If the optional commands/registers in soundwire slave(s) are not implemented, then soundwire bus will ignore the corresponding commands and executes the next commands in queue. Change-Id: I24dd929975218a150717f03f5c17c2be173a5005 Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 9 +++++++++ soc/swr-mstr-ctrl.h | 1 + 2 files changed, 10 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index fd77cf59dffa..ddf04ab4c2d3 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1631,6 +1631,15 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) swr_master_bulk_write(swrm, reg, value, len); + /* + * For SWR master version 1.5.1, continue + * execute on command ignore. + */ + if (swrm->version == SWRM_VERSION_1_5_1) + swr_master_write(swrm, SWRM_CMD_FIFO_CFG_ADDR, + (swr_master_read(swrm, + SWRM_CMD_FIFO_CFG_ADDR) | 0x80000000)); + return ret; } diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index afbbe4682932..fab66c39d26c 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -25,6 +25,7 @@ #define SWRM_VERSION_1_2 0x01030000 #define SWRM_VERSION_1_3 0x01040000 #define SWRM_VERSION_1_5 0x01050000 +#define SWRM_VERSION_1_5_1 0x01050001 #define SWR_MAX_CH_PER_PORT 8 -- GitLab From 809cb8ed58f3d59374c94d2b1d1fac7cd6c4a81c Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Wed, 28 Nov 2018 16:51:54 +0530 Subject: [PATCH 0730/1645] asoc: wsa881x: change WSA temparature log level to pr_debug Dmesg logs are getting flooded with WSA temparature logs. Change the log level to pr_debug to get rid of this messages. Change-Id: Ia4ccca47c5e6e5d56883ff73e1ae4278ff855be3 Signed-off-by: Surendar Karka --- asoc/codecs/wsa881x-temp-sensor.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/wsa881x-temp-sensor.c b/asoc/codecs/wsa881x-temp-sensor.c index 97f4d46f3335..eb7832a4d2a0 100644 --- a/asoc/codecs/wsa881x-temp-sensor.c +++ b/asoc/codecs/wsa881x-temp-sensor.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2015, 2017-2019 The Linux Foundation. All rights reserved. */ #include @@ -109,9 +109,8 @@ int wsa881x_get_temp(struct thermal_zone_device *thermal, if (temp_val <= LOW_TEMP_THRESHOLD || temp_val >= HIGH_TEMP_THRESHOLD) { - printk_ratelimited("%s: T0: %d is out of range[%d, %d]\n", - __func__, temp_val, LOW_TEMP_THRESHOLD, - HIGH_TEMP_THRESHOLD); + pr_debug("%s: T0: %d is out of range[%d, %d]\n", __func__, + temp_val, LOW_TEMP_THRESHOLD, HIGH_TEMP_THRESHOLD); if (retry--) { msleep(20); goto temp_retry; -- GitLab From fc7555991654013307fab3e8fe75d4a9fcca49fa Mon Sep 17 00:00:00 2001 From: Md Mansoor Ahmed Date: Thu, 29 Nov 2018 11:50:59 +0530 Subject: [PATCH 0731/1645] Asoc: sm6150: Add compress capture support Add FE dialinks to enable multi compress capture sessions on sm6150 target. Change-Id: Ib26fc6c84d7993c34725a3b67596d4f059aa286e Signed-off-by: Md Mansoor Ahmed --- asoc/sm6150.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 02f8fc5eae12..1a5bb3c97da1 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -6424,6 +6424,79 @@ static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = { }, }; +static struct snd_soc_dai_link msm_int_compress_capture_dai[] = { + { + .name = "Compress9", + .stream_name = "Compress9", + .cpu_dai_name = "MultiMedia17", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA17, + }, + { + .name = "Compress10", + .stream_name = "Compress10", + .cpu_dai_name = "MultiMedia18", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA18, + }, + { + .name = "Compress11", + .stream_name = "Compress11", + .cpu_dai_name = "MultiMedia19", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA19, + }, + { + .name = "Compress12", + .stream_name = "Compress12", + .cpu_dai_name = "MultiMedia28", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA28, + }, + { + .name = "Compress13", + .stream_name = "Compress13", + .cpu_dai_name = "MultiMedia29", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA29, + }, +}; + static struct snd_soc_dai_link msm_bolero_fe_dai_links[] = { {/* hw:x,37 */ .name = LPASS_BE_WSA_CDC_DMA_TX_0, @@ -7433,6 +7506,7 @@ static struct snd_soc_dai_link msm_sm6150_dai_links[ ARRAY_SIZE(msm_tavil_fe_dai_links) + ARRAY_SIZE(msm_bolero_fe_dai_links) + ARRAY_SIZE(msm_common_misc_fe_dai_links) + + ARRAY_SIZE(msm_int_compress_capture_dai) + ARRAY_SIZE(msm_common_be_dai_links) + ARRAY_SIZE(msm_tavil_be_dai_links) + ARRAY_SIZE(msm_wcn_be_dai_links) + @@ -7757,6 +7831,12 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) ARRAY_SIZE(msm_bolero_fe_dai_links); } + memcpy(msm_sm6150_dai_links + total_links, + msm_int_compress_capture_dai, + sizeof(msm_int_compress_capture_dai)); + + total_links += ARRAY_SIZE(msm_int_compress_capture_dai); + memcpy(msm_sm6150_dai_links + total_links, msm_common_be_dai_links, sizeof(msm_common_be_dai_links)); -- GitLab From c910c02395f07a9f44ba0f40573f7bbebc163a2e Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 4 Apr 2018 10:59:57 +0530 Subject: [PATCH 0732/1645] dsp: return ENETRESET error if apr is down In SSR/PDR, return ENETRESET errno to propagate this failure to userspace. After audio HAL receives ENETRESET, it stops retry for pcm_open continuously. Rate limit the logs when apr send packet fails during PDR/SSR usecases to avoid watchdog timeouts. Change-Id: I03a80aef6ffedb4f15f953fff5213d6a3c9efc4b Signed-off-by: Laxminath Kasam --- dsp/q6afe.c | 4 ++-- dsp/q6core.c | 6 +++--- ipc/apr.c | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index f36f06f2e61e..915e296246d2 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -866,7 +866,7 @@ int afe_q6_interface_prepare(void) 0xFFFFFFFF, &this_afe); if (this_afe.apr == NULL) { pr_err("%s: Unable to register AFE\n", __func__); - ret = -ENODEV; + ret = -ENETRESET; } rtac_set_afe_handle(this_afe.apr); } diff --git a/dsp/q6core.c b/dsp/q6core.c index 2fdc7943139d..38551439637f 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include @@ -432,7 +432,7 @@ void ocm_core_open(void) aprv2_core_fn_q, 0xFFFFFFFF, NULL); pr_debug("%s: Open_q %pK\n", __func__, q6core_lcl.core_handle_q); if (q6core_lcl.core_handle_q == NULL) - pr_err("%s: Unable to register CORE\n", __func__); + pr_err_ratelimited("%s: Unable to register CORE\n", __func__); } struct cal_block_data *cal_utils_get_cal_block_by_key( @@ -926,7 +926,7 @@ bool q6core_is_adsp_ready(void) q6core_lcl.bus_bw_resp_received = 0; rc = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *)&hdr); if (rc < 0) { - pr_err("%s: Get ADSP state APR packet send event %d\n", + pr_err_ratelimited("%s: Get ADSP state APR packet send event %d\n", __func__, rc); goto bail; } diff --git a/ipc/apr.c b/ipc/apr.c index d3ee38ea4f75..ec05d3b15cdc 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2010-2014, 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2014, 2016-2019 The Linux Foundation. All rights reserved. */ #include @@ -368,13 +368,13 @@ int apr_send_pkt(void *handle, uint32_t *buf) return -EINVAL; } if (svc->need_reset) { - pr_err("apr: send_pkt service need reset\n"); + pr_err_ratelimited("apr: send_pkt service need reset\n"); return -ENETRESET; } if ((svc->dest_id == APR_DEST_QDSP6) && (apr_get_q6_state() != APR_SUBSYS_LOADED)) { - pr_err("%s: Still dsp is not Up\n", __func__); + pr_err_ratelimited("%s: Still dsp is not Up\n", __func__); return -ENETRESET; } else if ((svc->dest_id == APR_DEST_MODEM) && (apr_get_modem_state() == APR_SUBSYS_DOWN)) { @@ -388,7 +388,7 @@ int apr_send_pkt(void *handle, uint32_t *buf) clnt = &client[dest_id][client_id]; if (!client[dest_id][client_id].handle) { - pr_err("APR: Still service is not yet opened\n"); + pr_err_ratelimited("APR: Still service is not yet opened\n"); spin_unlock_irqrestore(&svc->w_lock, flags); return -EINVAL; } @@ -501,7 +501,7 @@ struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn, if (dest_id == APR_DEST_QDSP6) { if (apr_get_q6_state() != APR_SUBSYS_LOADED) { - pr_err("%s: adsp not up\n", __func__); + pr_err_ratelimited("%s: adsp not up\n", __func__); return NULL; } pr_debug("%s: adsp Up\n", __func__); @@ -525,7 +525,7 @@ struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn, } if (apr_get_svc(svc_name, domain_id, &client_id, &svc_idx, &svc_id)) { - pr_err("%s: apr_get_svc failed\n", __func__); + pr_err_ratelimited("%s: apr_get_svc failed\n", __func__); goto done; } @@ -536,7 +536,7 @@ struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn, APR_DL_SMD, apr_cb_func, NULL); if (!clnt->handle) { svc = NULL; - pr_err("APR: Unable to open handle\n"); + pr_err_ratelimited("APR: Unable to open handle\n"); mutex_unlock(&clnt->m_lock); goto done; } @@ -547,7 +547,7 @@ struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn, clnt->id = client_id; if (svc->need_reset) { mutex_unlock(&svc->m_lock); - pr_err("APR: Service needs reset\n"); + pr_err_ratelimited("APR: Service needs reset\n"); svc = NULL; goto done; } -- GitLab From ea2b058566d1773fcb40f8c74e2267f096a5d095 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 3 Dec 2018 20:30:02 +0530 Subject: [PATCH 0733/1645] asoc: codecs: Update power setting for CLS_H_LOHIFI mode In new class-H driver used for tanggu or later variants, use LP(low power) power setting for CLS_H_LOHIFI same as tavil codec. Change-Id: I6a0f6e6d39e5704d6ea429ae2f3698750b7ea487 Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd-clsh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd-clsh.c b/asoc/codecs/wcd-clsh.c index 3cd76f709f8e..fd30148b7026 100644 --- a/asoc/codecs/wcd-clsh.c +++ b/asoc/codecs/wcd-clsh.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #include @@ -243,7 +243,6 @@ static void wcd_clsh_set_hph_mode(struct snd_soc_component *component, switch (mode) { case CLS_H_NORMAL: - case CLS_H_LOHIFI: val = 0x00; break; case CLS_AB: @@ -255,6 +254,7 @@ static void wcd_clsh_set_hph_mode(struct snd_soc_component *component, val = 0x08; break; case CLS_H_LP: + case CLS_H_LOHIFI: val = 0x04; break; default: -- GitLab From 1793ff07cbf5182660b90c3b50cb9c78badc12a2 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 15 Nov 2018 17:02:02 +0530 Subject: [PATCH 0734/1645] asoc: wcd937x: Change voltage for micbias depending on dt value MICBIAS is always set to 1.8V. Change this voltage depending on dt value for respective micbias. Change-Id: I8eb1e71ae0256423bfd0bcc8ba2cd6bcc4a5ee61 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x.c | 38 ++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 004ce796c98a..ec094ffaf00d 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -2082,6 +2082,36 @@ int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root, } EXPORT_SYMBOL(wcd937x_info_create_codec_entry); +static int wcd937x_set_micbias_data(struct wcd937x_priv *wcd937x, + struct wcd937x_pdata *pdata) +{ + int vout_ctl_1 = 0, vout_ctl_2 = 0, vout_ctl_3 = 0; + int rc = 0; + + if (!pdata) { + dev_err(wcd937x->dev, "%s: NULL pdata\n", __func__); + return -ENODEV; + } + + /* set micbias voltage */ + vout_ctl_1 = wcd937x_get_micb_vout_ctl_val(pdata->micbias.micb1_mv); + vout_ctl_2 = wcd937x_get_micb_vout_ctl_val(pdata->micbias.micb2_mv); + vout_ctl_3 = wcd937x_get_micb_vout_ctl_val(pdata->micbias.micb3_mv); + if (vout_ctl_1 < 0 || vout_ctl_2 < 0 || vout_ctl_3 < 0) { + rc = -EINVAL; + goto done; + } + regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB1, 0x3F, + vout_ctl_1); + regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB2, 0x3F, + vout_ctl_2); + regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB3, 0x3F, + vout_ctl_3); + +done: + return rc; +} + static int wcd937x_soc_codec_probe(struct snd_soc_component *component) { struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); @@ -2574,6 +2604,12 @@ static int wcd937x_bind(struct device *dev) } wcd937x->tx_swr_dev->slave_irq = wcd937x->virq; + ret = wcd937x_set_micbias_data(wcd937x, pdata); + if (ret < 0) { + dev_err(dev, "%s: bad micbias pdata\n", __func__); + goto err_irq; + } + mutex_init(&wcd937x->micb_lock); ret = snd_soc_register_component(dev, &soc_codec_dev_wcd937x, NULL, 0); -- GitLab From 3517b1102a1711d94a8b718fd650fee00c0abccf Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 3 Dec 2018 13:26:59 +0530 Subject: [PATCH 0735/1645] soc: swr-mstr: Fix headset detection issue Do not disable wake irq during registration of wake up interrupt as it leads to multiple disable calls of wake irq during boot up and headset detection fails sometimes. CRs-Fixed: 2356299 Change-Id: I79aa0ab46d26dc0e352d399e0d4381a11ed936f4 Signed-off-by: Aditya Bavanari --- soc/swr-mstr-ctrl.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index ddf04ab4c2d3..407e2a6fb0e2 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #include @@ -2181,8 +2181,7 @@ int swrm_register_wake_irq(struct swr_mstr_ctrl *swrm) __func__, ret); return -EINVAL; } - /* Disable wake irq - enable it after clock stop */ - disable_irq(swrm->wake_irq); + irq_set_irq_wake(swrm->wake_irq, 1); } return ret; } -- GitLab From 0fcf2af3df068888f5b31684478bdb1d8a279315 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 20 Sep 2018 17:43:49 -0700 Subject: [PATCH 0736/1645] asoc: dsp: ipc: Reduce wait timeout to 1 second Reduce the amount of time driver waits to get a response from ADSP. Current wait time in some cases is 5 secconds, which might cause user space crashes in Android P. So reducing the timeout to 1 second. CRs-Fixed: 2318751 Change-Id: I6b6789aa5b408659dd57f8f6b017df52d14b28aa Signed-off-by: Vignesh Kulothungan --- asoc/msm-compress-q6-v2.c | 9 +- asoc/msm-pcm-afe-v2.c | 6 +- asoc/msm-pcm-q6-v2.c | 9 +- dsp/q6adm.c | 7 +- dsp/q6asm.c | 196 +++++++++++++++++++++++++------------- dsp/q6lsm.c | 4 +- dsp/rtac.c | 4 +- 7 files changed, 153 insertions(+), 82 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index fb9f19add0aa..2bde61af1057 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ @@ -40,6 +40,7 @@ #define DRV_NAME "msm-compress-q6-v2" +#define TIMEOUT_MS 1000 #define DSP_PP_BUFFERING_IN_MSEC 25 #define PARTIAL_DRAIN_ACK_EARLY_BY_MSEC 150 #define MP3_OUTPUT_FRAME_SZ 1152 @@ -1829,7 +1830,8 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream) } if (atomic_read(&prtd->eos)) { ret = wait_event_timeout(prtd->eos_wait, - prtd->eos_ack, 5 * HZ); + prtd->eos_ack, + msecs_to_jiffies(TIMEOUT_MS)); if (!ret) pr_err("%s: CMD_EOS failed\n", __func__); } @@ -1837,7 +1839,8 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream) prtd->cmd_ack = 0; atomic_set(&prtd->wait_on_close, 1); ret = wait_event_timeout(prtd->close_wait, - prtd->cmd_ack, 5 * HZ); + prtd->cmd_ack, + msecs_to_jiffies(TIMEOUT_MS)); if (!ret) pr_err("%s: CMD_CLOSE failed\n", __func__); } diff --git a/asoc/msm-pcm-afe-v2.c b/asoc/msm-pcm-afe-v2.c index e2961223b175..3db81db1133f 100644 --- a/asoc/msm-pcm-afe-v2.c +++ b/asoc/msm-pcm-afe-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ @@ -26,6 +26,7 @@ #define DRV_NAME "msm-pcm-afe-v2" +#define TIMEOUT_MS 1000 #define MIN_PLAYBACK_PERIOD_SIZE (128 * 2) #define MAX_PLAYBACK_PERIOD_SIZE (128 * 2 * 2 * 6) #define MIN_PLAYBACK_NUM_PERIODS (4) @@ -571,7 +572,8 @@ static int msm_afe_capture_copy(struct snd_pcm_substream *substream, prtd->dsp_cnt++; ret = wait_event_timeout(prtd->read_wait, - atomic_read(&prtd->rec_bytes_avail), 5 * HZ); + atomic_read(&prtd->rec_bytes_avail), + msecs_to_jiffies(TIMEOUT_MS)); if (ret < 0) { pr_err("%s: wait_event_timeout failed\n", __func__); diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 50186daeb417..5886736286c5 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ @@ -35,6 +35,7 @@ #include "msm-qti-pp-config.h" #define DRV_NAME "msm-pcm-q6-v2" +#define TIMEOUT_MS 1000 enum stream_state { IDLE = 0, @@ -805,7 +806,8 @@ static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a, } ret = wait_event_timeout(the_locks.write_wait, - (atomic_read(&prtd->out_count)), 5 * HZ); + (atomic_read(&prtd->out_count)), + msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { pr_err("%s: wait_event_timeout failed\n", __func__); ret = -ETIMEDOUT; @@ -966,7 +968,8 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, return -ENETRESET; } ret = wait_event_timeout(the_locks.read_wait, - (atomic_read(&prtd->in_count)), 5 * HZ); + (atomic_read(&prtd->in_count)), + msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { pr_debug("%s: wait_event_timeout failed\n", __func__); goto fail; diff --git a/dsp/q6adm.c b/dsp/q6adm.c index d0b94177bce6..d5287a84f865 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -1852,7 +1851,7 @@ static int adm_memory_map_regions(phys_addr_t *buf_add, uint32_t mempool_id, ret = wait_event_timeout(this_adm.adm_wait, atomic_read(&this_adm.adm_stat) >= 0, - 5 * HZ); + msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { pr_err("%s: timeout. waited for memory_map\n", __func__); ret = -EINVAL; @@ -1902,7 +1901,7 @@ static int adm_memory_unmap_regions(void) ret = wait_event_timeout(this_adm.adm_wait, atomic_read(&this_adm.adm_stat) >= 0, - 5 * HZ); + msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { pr_err("%s: timeout. waited for memory_unmap\n", __func__); diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 473284608f5b..5c9de064feed 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -12,7 +12,6 @@ #include #include #include - #include #include #include @@ -33,6 +32,7 @@ #include #include "adsp_err.h" +#define TIMEOUT_MS 1000 #define TRUE 0x01 #define FALSE 0x00 #define SESSION_MAX 8 @@ -813,7 +813,8 @@ int send_asm_custom_topology(struct audio_client *ac) } result = wait_event_timeout(ac->mem_wait, - (atomic_read(&ac->mem_state) >= 0), 5*HZ); + (atomic_read(&ac->mem_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!result) { pr_err("%s: Set topologies failed timeout\n", __func__); pr_debug("%s: Set topologies failed after timedout payload = 0x%pK\n", @@ -1251,7 +1252,8 @@ int q6asm_send_stream_cmd(struct audio_client *ac, } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 1 * HZ); + (atomic_read(&ac->cmd_state_pp) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout for stream event cmd resp\n", __func__); rc = -ETIMEDOUT; @@ -2782,7 +2784,8 @@ int q6asm_set_pp_params(struct audio_client *ac, } ret = wait_event_timeout(ac->cmd_wait, - atomic_read(&ac->cmd_state_pp) >= 0, 5 * HZ); + atomic_read(&ac->cmd_state_pp) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { pr_err("%s: timeout sending apr pkt\n", __func__); ret = -ETIMEDOUT; @@ -2932,7 +2935,8 @@ int q6asm_open_read_compressed(struct audio_client *ac, uint32_t format, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 1*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for OPEN_READ_COMPR rc[%d]\n", __func__, rc); @@ -3055,7 +3059,8 @@ static int __q6asm_open_read(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for open read\n", __func__); @@ -3248,7 +3253,8 @@ int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 1*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for OPEN_WRITE_COMPR rc[%d]\n", __func__, rc); @@ -3407,7 +3413,8 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for open write\n", __func__); rc = -ETIMEDOUT; @@ -3710,7 +3717,8 @@ static int __q6asm_open_read_write(struct audio_client *ac, uint32_t rd_format, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for open read-write\n", __func__); @@ -3864,7 +3872,8 @@ int q6asm_open_loopback_v2(struct audio_client *ac, uint16_t bits_per_sample) } } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for open_loopback\n", __func__); @@ -3974,7 +3983,8 @@ int q6asm_open_transcode_loopback(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for open_transcode_loopback\n", __func__); @@ -4265,7 +4275,8 @@ int q6asm_open_shared_io(struct audio_client *ac, pr_debug("%s: sent open apr pkt\n", __func__); rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) <= 0), 5*HZ); + (atomic_read(&ac->cmd_state) <= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: Timeout. Waited for open write apr pkt rc[%d]\n", __func__, rc); @@ -4435,7 +4446,8 @@ int q6asm_run(struct audio_client *ac, uint32_t flags, } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for run success", __func__); @@ -4580,7 +4592,8 @@ int q6asm_enc_cfg_blk_custom(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for FORMAT_UPDATE\n", __func__); @@ -4651,7 +4664,8 @@ int q6asm_enc_cfg_blk_aac(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for FORMAT_UPDATE\n", __func__); @@ -4713,7 +4727,8 @@ int q6asm_enc_cfg_blk_g711(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for FORMAT_UPDATE\n", __func__); @@ -4776,7 +4791,8 @@ int q6asm_set_encdec_chan_map(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout opcode[0x%x]\n", __func__, chan_map.hdr.opcode); @@ -4980,7 +4996,8 @@ int q6asm_enc_cfg_blk_pcm_v4(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout opcode[0x%x]\n", __func__, enc_cfg.hdr.opcode); @@ -5077,7 +5094,8 @@ int q6asm_enc_cfg_blk_pcm_v3(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout opcode[0x%x]\n", __func__, enc_cfg.hdr.opcode); @@ -5171,7 +5189,8 @@ int q6asm_enc_cfg_blk_pcm_v2(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout opcode[0x%x]\n", __func__, enc_cfg.hdr.opcode); @@ -5379,7 +5398,8 @@ int q6asm_enc_cfg_blk_pcm_native(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout opcode[0x%x]\n", __func__, enc_cfg.hdr.opcode); @@ -5551,7 +5571,8 @@ int q6asm_enable_sbrps(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout opcode[0x%x] ", __func__, sbrps.hdr.opcode); rc = -ETIMEDOUT; @@ -5610,7 +5631,8 @@ int q6asm_cfg_dual_mono_aac(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout opcode[0x%x]\n", __func__, dual_mono.hdr.opcode); @@ -5656,7 +5678,8 @@ int q6asm_cfg_aac_sel_mix_coef(struct audio_client *ac, uint32_t mix_coeff) goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout opcode[0x%x]\n", __func__, aac_mix_coeff.hdr.opcode); @@ -5725,7 +5748,8 @@ int q6asm_enc_cfg_blk_qcelp(struct audio_client *ac, uint32_t frames_per_buf, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for setencdec v13k resp\n", __func__); @@ -5792,7 +5816,8 @@ int q6asm_enc_cfg_blk_evrc(struct audio_client *ac, uint32_t frames_per_buf, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for encdec evrc\n", __func__); rc = -ETIMEDOUT; @@ -5853,7 +5878,8 @@ int q6asm_enc_cfg_blk_amrnb(struct audio_client *ac, uint32_t frames_per_buf, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for set encdec amrnb\n", __func__); rc = -ETIMEDOUT; @@ -5914,7 +5940,8 @@ int q6asm_enc_cfg_blk_amrwb(struct audio_client *ac, uint32_t frames_per_buf, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for FORMAT_UPDATE\n", __func__); rc = -ETIMEDOUT; @@ -5995,7 +6022,8 @@ static int __q6asm_media_format_block_pcm(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for format update\n", __func__); rc = -ETIMEDOUT; @@ -6076,7 +6104,8 @@ static int __q6asm_media_format_block_pcm_v3(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for format update\n", __func__); rc = -ETIMEDOUT; @@ -6161,7 +6190,8 @@ static int __q6asm_media_format_block_pcm_v4(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for format update\n", __func__); rc = -ETIMEDOUT; @@ -6483,7 +6513,8 @@ static int __q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for format update\n", __func__); rc = -ETIMEDOUT; @@ -6552,7 +6583,8 @@ static int __q6asm_media_format_block_multi_ch_pcm_v3(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for format update\n", __func__); rc = -ETIMEDOUT; @@ -6625,7 +6657,8 @@ static int __q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for format update\n", __func__); rc = -ETIMEDOUT; @@ -6887,7 +6920,8 @@ int q6asm_media_format_block_gen_compr(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for format update\n", __func__); rc = -ETIMEDOUT; @@ -6943,7 +6977,8 @@ int q6asm_media_format_block_iec(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for format update\n", __func__); rc = -ETIMEDOUT; @@ -7012,7 +7047,8 @@ static int __q6asm_media_format_block_multi_aac(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for FORMAT_UPDATE\n", __func__); rc = -ETIMEDOUT; @@ -7126,7 +7162,8 @@ int q6asm_media_format_block_wma(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for FORMAT_UPDATE\n", __func__); rc = -ETIMEDOUT; @@ -7197,7 +7234,8 @@ int q6asm_media_format_block_wmapro(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for FORMAT_UPDATE\n", __func__); rc = -ETIMEDOUT; @@ -7256,7 +7294,8 @@ int q6asm_media_format_block_amrwbplus(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for FORMAT_UPDATE\n", __func__); rc = -ETIMEDOUT; @@ -7319,7 +7358,8 @@ int q6asm_stream_media_format_block_flac(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s :timeout. waited for FORMAT_UPDATE\n", __func__); rc = -ETIMEDOUT; @@ -7386,7 +7426,8 @@ int q6asm_media_format_block_alac(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s :timeout. waited for FORMAT_UPDATE\n", __func__); rc = -ETIMEDOUT; @@ -7455,7 +7496,8 @@ int q6asm_media_format_block_g711(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s :timeout. waited for FORMAT_UPDATE\n", __func__); rc = -ETIMEDOUT; @@ -7511,7 +7553,8 @@ int q6asm_stream_media_format_block_vorbis(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s :timeout. waited for FORMAT_UPDATE\n", __func__); rc = -ETIMEDOUT; @@ -7576,7 +7619,8 @@ int q6asm_media_format_block_ape(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s :timeout. waited for FORMAT_UPDATE\n", __func__); rc = -ETIMEDOUT; @@ -7636,7 +7680,8 @@ int q6asm_media_format_block_dsd(struct audio_client *ac, goto done; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for DSD FORMAT_UPDATE\n", __func__); rc = -ETIMEDOUT; @@ -7698,7 +7743,8 @@ int q6asm_stream_media_format_block_aptx_dec(struct audio_client *ac, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s :timeout. waited for FORMAT_UPDATE\n", __func__); rc = -ETIMEDOUT; @@ -7756,7 +7802,8 @@ static int __q6asm_ds1_set_endp_params(struct audio_client *ac, int param_id, goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout opcode[0x%x]\n", __func__, ddp_cfg.hdr.opcode); @@ -7892,7 +7939,8 @@ int q6asm_memory_map(struct audio_client *ac, phys_addr_t buf_add, int dir, rc = wait_event_timeout(ac->mem_wait, (atomic_read(&ac->mem_state) >= 0 && - ac->port[dir].tmp_hdl), 5*HZ); + ac->port[dir].tmp_hdl), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for memory_map\n", __func__); rc = -ETIMEDOUT; @@ -7980,7 +8028,8 @@ int q6asm_memory_unmap(struct audio_client *ac, phys_addr_t buf_add, int dir) } rc = wait_event_timeout(ac->mem_wait, - (atomic_read(&ac->mem_state) >= 0), 5 * HZ); + (atomic_read(&ac->mem_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for memory_unmap of handle 0x%x\n", __func__, mem_unmap.mem_map_handle); @@ -8132,7 +8181,8 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, rc = wait_event_timeout(ac->mem_wait, (atomic_read(&ac->mem_state) >= 0 && - ac->port[dir].tmp_hdl), 5*HZ); + ac->port[dir].tmp_hdl), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for memory_map\n", __func__); rc = -ETIMEDOUT; @@ -8231,7 +8281,8 @@ static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir) } rc = wait_event_timeout(ac->mem_wait, - (atomic_read(&ac->mem_state) >= 0), 5*HZ); + (atomic_read(&ac->mem_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for memory_unmap of handle 0x%x\n", __func__, mem_unmap.mem_map_handle); @@ -8495,7 +8546,8 @@ int q6asm_set_aptx_dec_bt_addr(struct audio_client *ac, } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, paylod.encdec.param_id); @@ -8590,7 +8642,8 @@ int q6asm_send_ion_fd(struct audio_client *ac, int fd) } ret = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 1*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { pr_err("%s: timeout, shm.encdec paramid[0x%x]\n", __func__, shm.encdec.param_id); @@ -8662,7 +8715,8 @@ int q6asm_send_rtic_event_ack(struct audio_client *ac, } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 1 * HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout for rtic event ack cmd\n", __func__); rc = -ETIMEDOUT; @@ -9468,7 +9522,8 @@ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) goto fail_cmd; } rc = wait_event_timeout(ac->time_wait, - (atomic_read(&ac->time_flag) == 0), 5*HZ); + (atomic_read(&ac->time_flag) == 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout in getting session time from DSP\n", __func__); @@ -9524,7 +9579,8 @@ int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp) goto fail_cmd; } rc = wait_event_timeout(ac->time_wait, - (atomic_read(&ac->time_flag) == 0), 5*HZ); + (atomic_read(&ac->time_flag) == 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout in getting session time from DSP\n", __func__); @@ -9602,7 +9658,8 @@ int q6asm_send_mtmx_strtr_window(struct audio_client *ac, } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout, Render window start paramid[0x%x]\n", __func__, matrix.data.param_id); @@ -9697,7 +9754,8 @@ int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac, } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout, Render mode send paramid [0x%x]\n", __func__, matrix.data.param_id); @@ -9792,7 +9850,8 @@ int q6asm_send_mtmx_strtr_clk_rec_mode(struct audio_client *ac, } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout, clk rec mode send paramid [0x%x]\n", __func__, matrix.data.param_id); @@ -9875,7 +9934,8 @@ int q6asm_send_mtmx_strtr_enable_adjust_session_clock(struct audio_client *ac, } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: enable adjust session failed failed paramid [0x%x]\n", __func__, matrix.data.param_id); @@ -9976,7 +10036,8 @@ static int __q6asm_cmd(struct audio_client *ac, int cmd, uint32_t stream_id) rc = -EINVAL; goto fail_cmd; } - rc = wait_event_timeout(ac->cmd_wait, (atomic_read(state) >= 0), 5*HZ); + rc = wait_event_timeout(ac->cmd_wait, (atomic_read(state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for response opcode[0x%x]\n", __func__, hdr.opcode); @@ -10302,7 +10363,8 @@ int q6asm_reg_tx_overflow(struct audio_client *ac, uint16_t enable) goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for tx overflow\n", __func__); rc = -ETIMEDOUT; @@ -10407,7 +10469,8 @@ int q6asm_adjust_session_clock(struct audio_client *ac, } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5*HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout, adjust_clock paramid[0x%x]\n", __func__, adjust_clock.hdr.opcode); @@ -10459,7 +10522,8 @@ int q6asm_get_path_delay(struct audio_client *ac) } rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state) >= 0), 5 * HZ); + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout. waited for response opcode[0x%x]\n", __func__, hdr.opcode); diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 3a7cee4f149d..7e40ec44fba1 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2013-2018, Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019, Linux Foundation. All rights reserved. */ #include #include @@ -27,7 +27,7 @@ #include #include "adsp_err.h" -#define APR_TIMEOUT (5 * HZ) +#define APR_TIMEOUT (HZ) #define LSM_ALIGN_BOUNDARY 512 #define LSM_SAMPLE_RATE 16000 #define QLSM_PARAM_ID_MINOR_VERSION 1 diff --git a/dsp/rtac.c b/dsp/rtac.c index 94cb715ff503..6e606d17edb4 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include @@ -1136,7 +1136,7 @@ int send_rtac_asm_apr(void *buf, u32 opcode) /* Wait for the callback */ result = wait_event_timeout(rtac_asm_apr_data[session_id].cmd_wait, (atomic_read(&rtac_asm_apr_data[session_id].cmd_state) == 0), - 5 * HZ); + msecs_to_jiffies(TIMEOUT_MS)); if (!result) { pr_err("%s: Set params timed out session = %d\n", __func__, session_id); -- GitLab From beccfad9b68993c0bd7d88993d9e08ea9f57f3f6 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 22 Oct 2018 12:03:15 +0530 Subject: [PATCH 0737/1645] ASoC: wcd937x: Enable watchdog interrupt Handle PDM watchdog interrupt. Enable watchdog before analog PA is enabled and disable it after analog PA is disabled so as to prevent false alarms. CRs-Fixed: 2336526 Change-Id: I3c16a9dcd0f4f84bf8ad0bfde9560330c143cdf9 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/internal.h | 3 +- asoc/codecs/wcd937x/wcd937x.c | 64 ++++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index eaf6860d42e9..110425a8924e 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #ifndef _WCD937X_INTERNAL_H @@ -82,6 +82,7 @@ struct wcd937x_priv { /* Entry for version info */ struct snd_info_entry *entry; struct snd_info_entry *version_entry; + int ear_rx_path; }; struct wcd937x_micbias_setting { diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 004ce796c98a..f54e7a0c30aa 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -34,6 +34,7 @@ #define WCD937X_VERSION_1_0 1 #define WCD937X_VERSION_ENTRY_SIZE 32 +#define EAR_RX_PATH_AUX 1 enum { CODEC_TX = 0, @@ -653,6 +654,11 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, 0x10, 0x10); usleep_range(100, 110); set_bit(HPH_PA_DELAY, &wcd937x->status_mask); + ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, + wcd937x->rx_swr_dev->dev_num, + true); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_PDM_WD_CTL1, 0x17, 0x13); break; case SND_SOC_DAPM_POST_PMU: /* @@ -691,6 +697,8 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: usleep_range(7000, 7010); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_PDM_WD_CTL1, 0x17, 0x00); blocking_notifier_call_chain(&wcd937x->mbhc->notifier, WCD_EVENT_POST_HPHR_PA_OFF, &wcd937x->mbhc->wcd_mbhc); @@ -731,6 +739,8 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, 0x20, 0x20); usleep_range(100, 110); set_bit(HPH_PA_DELAY, &wcd937x->status_mask); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_PDM_WD_CTL0, 0x17, 0x13); break; case SND_SOC_DAPM_POST_PMU: /* @@ -769,6 +779,8 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: usleep_range(7000, 7010); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_PDM_WD_CTL0, 0x17, 0x00); blocking_notifier_call_chain(&wcd937x->mbhc->notifier, WCD_EVENT_POST_HPHL_PA_OFF, &wcd937x->mbhc->wcd_mbhc); @@ -801,6 +813,8 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, true); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_PDM_WD_CTL2, 0x05, 0x05); break; case SND_SOC_DAPM_POST_PMU: usleep_range(1000, 1010); @@ -820,12 +834,14 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, (WCD_RX3 << 0x10 | 0x1)); break; case SND_SOC_DAPM_POST_PMD: - usleep_range(1000, 1010); - usleep_range(1000, 1010); + /* Add delay as per hw requirement */ + usleep_range(2000, 2010); wcd_cls_h_fsm(component, &wcd937x->clsh_info, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_AUX, hph_mode); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_PDM_WD_CTL2, 0x05, 0x00); break; }; return ret; @@ -849,6 +865,21 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, ret = swr_slvdev_datapath_control(wcd937x->rx_swr_dev, wcd937x->rx_swr_dev->dev_num, true); + /* + * Enable watchdog interrupt for HPHL or AUX + * depending on mux value + */ + wcd937x->ear_rx_path = + snd_soc_component_read32( + component, WCD937X_DIGITAL_CDC_EAR_PATH_CTL); + if (wcd937x->ear_rx_path & EAR_RX_PATH_AUX) + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_PDM_WD_CTL2, + 0x05, 0x05); + else + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_PDM_WD_CTL0, + 0x17, 0x13); break; case SND_SOC_DAPM_POST_PMU: usleep_range(6000, 6010); @@ -873,6 +904,14 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_EAR, hph_mode); + if (wcd937x->ear_rx_path & EAR_RX_PATH_AUX) + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_PDM_WD_CTL2, + 0x05, 0x00); + else + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_PDM_WD_CTL0, + 0x17, 0x00); break; }; return ret; @@ -2445,6 +2484,13 @@ static int wcd937x_wakeup(void *handle, bool enable) return swr_device_wakeup_unvote(priv->tx_swr_dev); } +static irqreturn_t wcd937x_wd_handle_irq(int irq, void *data) +{ + pr_err_ratelimited("%s: Watchdog interrupt for irq =%d triggered\n", + __func__, irq); + return IRQ_HANDLED; +} + static int wcd937x_bind(struct device *dev) { int ret = 0, i = 0; @@ -2575,6 +2621,18 @@ static int wcd937x_bind(struct device *dev) wcd937x->tx_swr_dev->slave_irq = wcd937x->virq; mutex_init(&wcd937x->micb_lock); + /* Request for watchdog interrupt */ + wcd_request_irq(&wcd937x->irq_info, WCD937X_IRQ_HPHR_PDM_WD_INT, + "HPHR PDM WD INT", wcd937x_wd_handle_irq, NULL); + wcd_request_irq(&wcd937x->irq_info, WCD937X_IRQ_HPHL_PDM_WD_INT, + "HPHL PDM WD INT", wcd937x_wd_handle_irq, NULL); + wcd_request_irq(&wcd937x->irq_info, WCD937X_IRQ_AUX_PDM_WD_INT, + "AUX PDM WD INT", wcd937x_wd_handle_irq, NULL); + /* Enable watchdog interrupt for HPH and AUX */ + wcd_enable_irq(&wcd937x->irq_info, WCD937X_IRQ_HPHR_PDM_WD_INT); + wcd_enable_irq(&wcd937x->irq_info, WCD937X_IRQ_HPHL_PDM_WD_INT); + wcd_enable_irq(&wcd937x->irq_info, WCD937X_IRQ_AUX_PDM_WD_INT); + ret = snd_soc_register_component(dev, &soc_codec_dev_wcd937x, NULL, 0); if (ret) { -- GitLab From ea69fedaa3322e28b9fa72855d4f15b7d6e04641 Mon Sep 17 00:00:00 2001 From: Josh Kirsch Date: Tue, 11 Dec 2018 16:15:08 -0800 Subject: [PATCH 0738/1645] audio-kernel: asoc: Remove extra const def Remove extra const definition. Causing compilation error on ARM compiler. Change-Id: I56961168c8a4fc1248d5d43661159b9cf1ff2d98 Signed-off-by: Josh Kirsch --- asoc/msm-pcm-routing-v2.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index d8d9f3eb6f44..62b332d67d22 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include @@ -18143,32 +18143,32 @@ static const char * const int4_mi2s_rx_vi_fb_tx_stereo_mux_text[] = { "ZERO", "INT5_MI2S_TX" }; -static const int const slim0_rx_vi_fb_tx_lch_value[] = { +static const int slim0_rx_vi_fb_tx_lch_value[] = { MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SLIMBUS_4_TX }; -static const int const slim0_rx_vi_fb_tx_rch_value[] = { +static const int slim0_rx_vi_fb_tx_rch_value[] = { MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SLIMBUS_4_TX }; -static const int const wsa_rx_0_vi_fb_tx_lch_value[] = { +static const int wsa_rx_0_vi_fb_tx_lch_value[] = { MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0 }; -static const int const wsa_rx_0_vi_fb_tx_rch_value[] = { +static const int wsa_rx_0_vi_fb_tx_rch_value[] = { MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0 }; -static const int const mi2s_rx_vi_fb_tx_value[] = { +static const int mi2s_rx_vi_fb_tx_value[] = { MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SENARY_MI2S_TX }; -static const int const int4_mi2s_rx_vi_fb_tx_mono_ch_value[] = { +static const int int4_mi2s_rx_vi_fb_tx_mono_ch_value[] = { MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_INT5_MI2S_TX }; -static const int const int4_mi2s_rx_vi_fb_tx_stereo_ch_value[] = { +static const int int4_mi2s_rx_vi_fb_tx_stereo_ch_value[] = { MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_INT5_MI2S_TX }; -- GitLab From 8883e449af114318f8bafb1c87da1a07a48e8e7c Mon Sep 17 00:00:00 2001 From: Romed Schur Date: Tue, 6 Nov 2018 14:06:58 +0100 Subject: [PATCH 0739/1645] asoc: csra66x0: Support of sysfs interface Sysfs interface added to support filter register access. Change-Id: I6dcbd3e728ab6c80c6a1d29f6fc2e795f4a09119 Signed-off-by: Romed Schur --- asoc/codecs/csra66x0/csra66x0.c | 662 ++++++++++++++++++++++++++------ asoc/codecs/csra66x0/csra66x0.h | 17 +- 2 files changed, 566 insertions(+), 113 deletions(-) diff --git a/asoc/codecs/csra66x0/csra66x0.c b/asoc/codecs/csra66x0/csra66x0.c index 595e7ca8fa03..42768f10ca7d 100644 --- a/asoc/codecs/csra66x0/csra66x0.c +++ b/asoc/codecs/csra66x0/csra66x0.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -20,6 +20,7 @@ #include "csra66x0.h" #define DRV_NAME "csra66x0_codec" +#define CSRA66X0_SYSFS_ENTRY_MAX_LEN 64 /* CSRA66X0 register default values */ static struct reg_default csra66x0_reg_defaults[] = { @@ -204,8 +205,24 @@ static struct reg_default csra66x0_reg_defaults[] = { /* RESERVED */ }; +static bool csra66x0_addr_is_in_range(unsigned int addr, + unsigned int addr_min, unsigned int addr_max) +{ + if ((addr >= addr_min) + && (addr <= addr_max)) + return true; + else + return false; +} + static bool csra66x0_volatile_register(struct device *dev, unsigned int reg) { + /* coeff registers */ + if (csra66x0_addr_is_in_range(reg, CSRA66X0_COEFF_BASE, + CSRA66X0_MAX_COEFF_ADDR)) + return true; + + /* control registers */ switch (reg) { case CSRA66X0_CHIP_ID_FA: case CSRA66X0_ROM_VER_FA: @@ -213,6 +230,7 @@ static bool csra66x0_volatile_register(struct device *dev, unsigned int reg) case CSRA66X0_CHIP_REV_1_FA: case CSRA66X0_TEMP_READ0_FA: case CSRA66X0_TEMP_READ1_FA: + case CSRA66X0_CHIP_STATE_CTRL_FA: case CSRA66X0_MISC_CONTROL_STATUS_1_FA: case CSRA66X0_IRQ_OUTPUT_STATUS_FA: case CSRA66X0_CLIP_DCA_STATUS_FA: @@ -222,6 +240,41 @@ static bool csra66x0_volatile_register(struct device *dev, unsigned int reg) case CSRA66X0_AUDIO_IF_STATUS_FA: case CSRA66X0_DSP_SATURATION_STATUS_FA: case CSRA66X0_AUDIO_RATE_STATUS_FA: + case CSRA66X0_CH1_MIX_SEL: + case CSRA66X0_CH2_MIX_SEL: + case CSRA66X0_CH1_SAMPLE1_SCALE_0: + case CSRA66X0_CH1_SAMPLE1_SCALE_1: + case CSRA66X0_CH1_SAMPLE3_SCALE_0: + case CSRA66X0_CH1_SAMPLE3_SCALE_1: + case CSRA66X0_CH1_SAMPLE5_SCALE_0: + case CSRA66X0_CH1_SAMPLE5_SCALE_1: + case CSRA66X0_CH1_SAMPLE7_SCALE_0: + case CSRA66X0_CH1_SAMPLE7_SCALE_1: + case CSRA66X0_CH1_SAMPLE2_SCALE_0: + case CSRA66X0_CH1_SAMPLE2_SCALE_1: + case CSRA66X0_CH1_SAMPLE4_SCALE_0: + case CSRA66X0_CH1_SAMPLE4_SCALE_1: + case CSRA66X0_CH1_SAMPLE6_SCALE_0: + case CSRA66X0_CH1_SAMPLE6_SCALE_1: + case CSRA66X0_CH1_SAMPLE8_SCALE_0: + case CSRA66X0_CH1_SAMPLE8_SCALE_1: + case CSRA66X0_CH2_SAMPLE1_SCALE_0: + case CSRA66X0_CH2_SAMPLE1_SCALE_1: + case CSRA66X0_CH2_SAMPLE3_SCALE_0: + case CSRA66X0_CH2_SAMPLE3_SCALE_1: + case CSRA66X0_CH2_SAMPLE5_SCALE_0: + case CSRA66X0_CH2_SAMPLE5_SCALE_1: + case CSRA66X0_CH2_SAMPLE7_SCALE_0: + case CSRA66X0_CH2_SAMPLE7_SCALE_1: + case CSRA66X0_CH2_SAMPLE2_SCALE_0: + case CSRA66X0_CH2_SAMPLE2_SCALE_1: + case CSRA66X0_CH2_SAMPLE4_SCALE_0: + case CSRA66X0_CH2_SAMPLE4_SCALE_1: + case CSRA66X0_CH2_SAMPLE6_SCALE_0: + case CSRA66X0_CH2_SAMPLE6_SCALE_1: + case CSRA66X0_CH2_SAMPLE8_SCALE_0: + case CSRA66X0_CH2_SAMPLE8_SCALE_1: + case CSRA66X0_RAM_VER_FA: return true; default: return false; @@ -230,20 +283,24 @@ static bool csra66x0_volatile_register(struct device *dev, unsigned int reg) static bool csra66x0_writeable_registers(struct device *dev, unsigned int reg) { - if ((reg >= CSRA66X0_AUDIO_IF_RX_CONFIG1) - && (reg <= CSRA66X0_MAX_REGISTER_ADDR)) + if (csra66x0_addr_is_in_range(reg, CSRA66X0_BASE, + CSRA66X0_MAX_REGISTER_ADDR) + || csra66x0_addr_is_in_range(reg, CSRA66X0_COEFF_BASE, + CSRA66X0_MAX_COEFF_ADDR)) return true; - - return false; + else + return false; } static bool csra66x0_readable_registers(struct device *dev, unsigned int reg) { - if ((reg >= CSRA66X0_AUDIO_IF_RX_CONFIG1) - && (reg <= CSRA66X0_MAX_REGISTER_ADDR)) + if (csra66x0_addr_is_in_range(reg, CSRA66X0_BASE, + CSRA66X0_MAX_REGISTER_ADDR) + || csra66x0_addr_is_in_range(reg, CSRA66X0_COEFF_BASE, + CSRA66X0_MAX_COEFF_ADDR)) return true; - - return false; + else + return false; } /* codec private data */ @@ -257,6 +314,10 @@ struct csra66x0_priv { u32 irq_active_low; u32 in_cluster; u32 is_master; + bool is_probed; + u32 max_num_cluster_devices; + u32 num_cluster_devices; + u32 sysfs_reg_addr; #if IS_ENABLED(CONFIG_DEBUG_FS) struct dentry *debugfs_dir; struct dentry *debugfs_file_wo; @@ -278,14 +339,7 @@ struct csra66x0_cluster_device csra_clust_dev_tbl[] = { {NULL, "CSRA_BC"} }; -#if IS_ENABLED(CONFIG_DEBUG_FS) -static int debugfs_codec_open_op(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static int debugfs_get_parameters(char *buf, u32 *param1, int num_of_par) +static int sysfs_get_param(char *buf, u32 *param, int num_of_par) { char *token; int base, cnt; @@ -298,7 +352,7 @@ static int debugfs_get_parameters(char *buf, u32 *param1, int num_of_par) else base = 10; - if (kstrtou32(token, base, ¶m1[cnt]) != 0) + if (kstrtou32(token, base, ¶m[cnt]) != 0) return -EINVAL; token = strsep(&buf, " "); @@ -309,6 +363,13 @@ static int debugfs_get_parameters(char *buf, u32 *param1, int num_of_par) return 0; } +#if IS_ENABLED(CONFIG_DEBUG_FS) +static int debugfs_codec_open_op(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t debugfs_codec_write_op(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) { @@ -319,7 +380,7 @@ static ssize_t debugfs_codec_write_op(struct file *filp, int rc; u32 param[2]; - if (!filp || !ppos || !ubuf) + if (!filp || !ppos || !ubuf || !component) return -EINVAL; if (cnt > sizeof(lbuf) - 1) return -EINVAL; @@ -327,9 +388,12 @@ static ssize_t debugfs_codec_write_op(struct file *filp, if (rc) return -EFAULT; lbuf[cnt] = '\0'; - rc = debugfs_get_parameters(lbuf, param, 2); - if ((param[0] < CSRA66X0_AUDIO_IF_RX_CONFIG1) - || (param[0] > CSRA66X0_MAX_REGISTER_ADDR)) { + rc = sysfs_get_param(lbuf, param, 2); + + if (!(csra66x0_addr_is_in_range(param[0], + CSRA66X0_BASE, CSRA66X0_MAX_REGISTER_ADDR) + || csra66x0_addr_is_in_range(param[0], + CSRA66X0_COEFF_BASE, CSRA66X0_MAX_COEFF_ADDR))) { dev_err(component->dev, "%s: register address 0x%04X out of range\n", __func__, param[0]); return -EINVAL; @@ -352,18 +416,30 @@ static ssize_t debugfs_codec_write_op(struct file *filp, return rc; } -static ssize_t debugfs_csra66x0_reg_show(struct snd_soc_component *component, +static ssize_t debugfs_csra66x0_reg_show(struct csra66x0_priv *csra66x0, char __user *ubuf, size_t count, loff_t *ppos) { int i, reg_val, len; + int addr_min, addr_max; ssize_t total = 0; char tmp_buf[20]; + struct snd_soc_component *component = csra66x0->component; if (!ubuf || !ppos || !component || *ppos < 0) return -EINVAL; - for (i = ((int) *ppos + CSRA66X0_BASE); - i <= CSRA66X0_MAX_REGISTER_ADDR; i++) { + if (csra66x0_addr_is_in_range(csra66x0->sysfs_reg_addr, + CSRA66X0_COEFF_BASE, CSRA66X0_MAX_COEFF_ADDR)) { + addr_min = CSRA66X0_COEFF_BASE; + addr_max = CSRA66X0_MAX_COEFF_ADDR; + csra66x0->sysfs_reg_addr = CSRA66X0_BASE; + } else { + addr_min = CSRA66X0_BASE; + addr_max = CSRA66X0_MAX_REGISTER_ADDR; + } + + for (i = ((int) *ppos + addr_min); + i <= addr_max; i++) { reg_val = snd_soc_component_read32(component, i); len = snprintf(tmp_buf, 20, "0x%04X: 0x%02X\n", i, (reg_val & 0xFF)); if ((total + len) >= count - 1) @@ -387,12 +463,11 @@ static ssize_t debugfs_codec_read_op(struct file *filp, { struct csra66x0_priv *csra66x0 = (struct csra66x0_priv *) filp->private_data; - struct snd_soc_component *component = csra66x0->component; ssize_t ret_cnt; if (!filp || !ppos || !ubuf || *ppos < 0) return -EINVAL; - ret_cnt = debugfs_csra66x0_reg_show(component, ubuf, cnt, ppos); + ret_cnt = debugfs_csra66x0_reg_show(csra66x0, ubuf, cnt, ppos); return ret_cnt; } @@ -515,11 +590,8 @@ static const struct snd_soc_dapm_widget csra66x0_dapm_widgets[] = { SND_SOC_DAPM_MIXER("MIXER", SND_SOC_NOPM, 0, 0, csra_mix_switch, ARRAY_SIZE(csra_mix_switch)), SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_PGA("PGA", CSRA66X0_CHIP_STATE_CTRL_FA, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("PGA", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_OUTPUT("SPKR"), - - SND_SOC_DAPM_SUPPLY("POWER", CSRA66X0_CHIP_STATE_CTRL_FA, - 1, 1, NULL, 0), }; static const struct snd_soc_dapm_route csra66x0_dapm_routes[] = { @@ -527,20 +599,140 @@ static const struct snd_soc_dapm_route csra66x0_dapm_routes[] = { {"DAC", NULL, "MIXER"}, {"PGA", NULL, "DAC"}, {"SPKR", NULL, "PGA"}, - {"SPKR", NULL, "POWER"}, }; +static int csra66x0_wait_for_config_state(struct snd_soc_component *component) +{ + u16 val; + int cntdwn = WAIT_FOR_CONFIG_STATE_TIMEOUT_MS; + + do { + /* wait >= 100ms to check if HW has moved to config state */ + msleep(100); + val = snd_soc_component_read32(component, + CSRA66X0_CHIP_STATE_STATUS_FA); + if (val == CONFIG_STATE_ID) + break; + + cntdwn = cntdwn - 100; + } while (cntdwn > 0); + if (cntdwn <= 0) + return -EFAULT; + + return 0; +} + +static int csra66x0_allow_run(struct csra66x0_priv *csra66x0) +{ + struct snd_soc_component *component = csra66x0->component; + int i; + + /* csra66x0 is not in cluster */ + if (!csra66x0->in_cluster) { + /* enable interrupts */ + if (csra66x0->irq) { + snd_soc_component_write(component, + CSRA66X0_PIO0_SELECT, 0x1); + if (csra66x0->irq_active_low) + snd_soc_component_write(component, + CSRA66X0_IRQ_OUTPUT_POLARITY, 0x0); + else + snd_soc_component_write(component, + CSRA66X0_IRQ_OUTPUT_POLARITY, 0x1); + + snd_soc_component_write(component, + CSRA66X0_IRQ_OUTPUT_ENABLE, 0x01); + } else { + snd_soc_component_write(component, + CSRA66X0_IRQ_OUTPUT_ENABLE, 0x00); + } + /* allow run */ + snd_soc_component_write(component, + CSRA66X0_CHIP_STATE_CTRL_FA, SET_RUN_STATE); + return 0; + } + + /* csra66x0 is part of cluster */ + /* get number of probed cluster devices */ + csra66x0->num_cluster_devices = 0; + for (i = 0; i < component->card->num_aux_devs; i++) { + if (i >= csra66x0->max_num_cluster_devices) + break; + if (csra_clust_dev_tbl[i].csra66x0_ptr == NULL) + continue; + if (csra_clust_dev_tbl[i].csra66x0_ptr->is_probed) + csra66x0->num_cluster_devices++; + } + + /* check if all cluster devices are probed */ + if (csra66x0->num_cluster_devices + == component->card->num_aux_devs) { + /* allow run of all slave components */ + for (i = 0; i < component->card->num_aux_devs; i++) { + if (i >= csra66x0->max_num_cluster_devices) + break; + if (csra_clust_dev_tbl[i].csra66x0_ptr == NULL) + continue; + if (csra_clust_dev_tbl[i].csra66x0_ptr->is_master) + continue; + snd_soc_component_write( + csra_clust_dev_tbl[i].csra66x0_ptr->component, + CSRA66X0_CHIP_STATE_CTRL_FA, SET_RUN_STATE); + } + /* allow run of all master components */ + for (i = 0; i < component->card->num_aux_devs; i++) { + if (i >= csra66x0->max_num_cluster_devices) + break; + if (csra_clust_dev_tbl[i].csra66x0_ptr == NULL) + continue; + if (!csra_clust_dev_tbl[i].csra66x0_ptr->is_master) + continue; + + /* enable interrupts */ + if (csra66x0->irq) { + snd_soc_component_write(component, + CSRA66X0_PIO0_SELECT, 0x1); + if (csra66x0->irq_active_low) + snd_soc_component_write(component, + CSRA66X0_IRQ_OUTPUT_POLARITY, + 0x0); + else + snd_soc_component_write(component, + CSRA66X0_IRQ_OUTPUT_POLARITY, + 0x1); + + snd_soc_component_write(component, + CSRA66X0_IRQ_OUTPUT_ENABLE, 0x01); + } else { + snd_soc_component_write(component, + CSRA66X0_IRQ_OUTPUT_ENABLE, 0x00); + } + /* allow run */ + snd_soc_component_write( + csra_clust_dev_tbl[i].csra66x0_ptr->component, + CSRA66X0_CHIP_STATE_CTRL_FA, SET_RUN_STATE); + } + } + return 0; +} + static int csra66x0_init(struct csra66x0_priv *csra66x0) { struct snd_soc_component *component = csra66x0->component; + int ret; dev_dbg(component->dev, "%s: initialize %s\n", __func__, component->name); + csra66x0->sysfs_reg_addr = CSRA66X0_BASE; /* config */ snd_soc_component_write(component, CSRA66X0_CHIP_STATE_CTRL_FA, - CONFIG_STATE); - /* settle time in HW is min. 500ms before proceeding */ - msleep(500); + SET_CONFIG_STATE); + /* wait until HW is in config state before proceeding */ + ret = csra66x0_wait_for_config_state(component); + if (ret) { + dev_err(component->dev, "%s: timeout while %s is waiting for config state\n", + __func__, component->name); + } /* setup */ snd_soc_component_write(component, CSRA66X0_MISC_CONTROL_STATUS_0, @@ -578,23 +770,7 @@ static int csra66x0_init(struct csra66x0_priv *csra66x0) snd_soc_component_write(component, CSRA66X0_DCA_ATTACK_RATE, 0x00); snd_soc_component_write(component, CSRA66X0_DCA_RELEASE_RATE, 0x00); - if (csra66x0->irq) { - snd_soc_component_write(component, CSRA66X0_PIO0_SELECT, 0x1); - if (csra66x0->irq_active_low) - snd_soc_component_write(component, - CSRA66X0_IRQ_OUTPUT_POLARITY, 0x0); - else - snd_soc_component_write(component, - CSRA66X0_IRQ_OUTPUT_POLARITY, 0x1); - - snd_soc_component_write(component, - CSRA66X0_IRQ_OUTPUT_ENABLE, 0x01); - } else { - snd_soc_component_write(component, - CSRA66X0_IRQ_OUTPUT_ENABLE, 0x00); - } - /* settle time in HW is min. 500ms before slave initializing */ - msleep(500); + csra66x0_allow_run(csra66x0); return 0; } @@ -641,14 +817,20 @@ static int csra66x0_reset(struct csra66x0_priv *csra66x0) static int csra66x0_msconfig(struct csra66x0_priv *csra66x0) { struct snd_soc_component *component = csra66x0->component; + int ret; dev_dbg(component->dev, "%s: configure %s\n", __func__, component->name); /* config */ snd_soc_component_write(component, CSRA66X0_CHIP_STATE_CTRL_FA, - CONFIG_STATE); - /* settle time in HW is min. 500ms before proceeding */ - msleep(500); + SET_CONFIG_STATE); + /* wait until HW is in config state before proceeding */ + ret = csra66x0_wait_for_config_state(component); + if (ret) { + dev_err(component->dev, "%s: timeout while %s is waiting for config state\n", + __func__, component->name); + return ret; + } snd_soc_component_write(component, CSRA66X0_PIO7_SELECT, 0x04); snd_soc_component_write(component, CSRA66X0_PIO8_SELECT, 0x04); if (csra66x0->is_master) { @@ -678,27 +860,29 @@ static int csra66x0_soc_probe(struct snd_soc_component *component) snd_soc_component_get_drvdata(component); struct snd_soc_dapm_context *dapm; char name[50]; - unsigned int i, max_num_cluster_devices; + unsigned int i; csra66x0->component = component; if (csra66x0->in_cluster) { dapm = snd_soc_component_get_dapm(component); - dev_dbg(component->dev, "%s: assign prefix %s to codec device %s\n", + dev_dbg(component->dev, "%s: assign prefix %s to component device %s\n", __func__, component->name_prefix, component->name); /* add device to cluster table */ - max_num_cluster_devices = sizeof(csra_clust_dev_tbl)/ - sizeof(csra_clust_dev_tbl[0]); - for (i = 0; i < max_num_cluster_devices; i++) { + csra66x0->max_num_cluster_devices = + ARRAY_SIZE(csra_clust_dev_tbl); + for (i = 0; i < csra66x0->max_num_cluster_devices; i++) { if (!strncmp(component->name_prefix, - csra_clust_dev_tbl[i].csra66x0_prefix, - strlen( - csra_clust_dev_tbl[i].csra66x0_prefix))) { + csra_clust_dev_tbl[i].csra66x0_prefix, + strnlen( + csra_clust_dev_tbl[i].csra66x0_prefix, + sizeof( + csra_clust_dev_tbl[i].csra66x0_prefix)))) { csra_clust_dev_tbl[i].csra66x0_ptr = csra66x0; break; } - if (i == max_num_cluster_devices-1) + if (i == csra66x0->max_num_cluster_devices - 1) dev_warn(component->dev, "%s: Unknown prefix %s of cluster device %s\n", __func__, component->name_prefix, @@ -720,6 +904,7 @@ static int csra66x0_soc_probe(struct snd_soc_component *component) } /* common initialization */ + csra66x0->is_probed = 1; csra66x0_init(csra66x0); return 0; } @@ -727,36 +912,14 @@ static int csra66x0_soc_probe(struct snd_soc_component *component) static void csra66x0_soc_remove(struct snd_soc_component *component) { snd_soc_component_write(component, CSRA66X0_CHIP_STATE_CTRL_FA, - STDBY_STATE); + SET_STDBY_STATE); return; } -static int csra66x0_soc_suspend(struct snd_soc_component *component) -{ - u16 state_reg = snd_soc_component_read32(component, - CSRA66X0_CHIP_STATE_CTRL_FA) & 0xFC; - - snd_soc_component_write(component, CSRA66X0_CHIP_STATE_CTRL_FA, - state_reg | STDBY_STATE); - return 0; -} - -static int csra66x0_soc_resume(struct snd_soc_component *component) -{ - u16 state_reg = snd_soc_component_read32( - component, CSRA66X0_CHIP_STATE_CTRL_FA) & 0xFC; - - snd_soc_component_write(component, CSRA66X0_CHIP_STATE_CTRL_FA, - state_reg | RUN_STATE); - return 0; -} - static const struct snd_soc_component_driver soc_codec_drv_csra66x0 = { .name = DRV_NAME, .probe = csra66x0_soc_probe, .remove = csra66x0_soc_remove, - .suspend = csra66x0_soc_suspend, - .resume = csra66x0_soc_resume, .controls = csra66x0_snd_controls, .num_controls = ARRAY_SIZE(csra66x0_snd_controls), .dapm_widgets = csra66x0_dapm_widgets, @@ -771,7 +934,7 @@ static struct regmap_config csra66x0_regmap_config = { .cache_type = REGCACHE_RBTREE, .reg_defaults = csra66x0_reg_defaults, .num_reg_defaults = ARRAY_SIZE(csra66x0_reg_defaults), - .max_register = CSRA66X0_MAX_REGISTER_ADDR, + .max_register = CSRA66X0_MAX_COEFF_ADDR, .volatile_reg = csra66x0_volatile_register, .writeable_reg = csra66x0_writeable_registers, .readable_reg = csra66x0_readable_registers, @@ -782,7 +945,7 @@ static irqreturn_t csra66x0_irq(int irq, void *data) struct csra66x0_priv *csra66x0 = (struct csra66x0_priv *) data; struct snd_soc_component *component = csra66x0->component; u16 val; - unsigned int i, max_num_cluster_devices; + unsigned int i; /* Treat interrupt before component is initialized as spurious */ if (component == NULL) @@ -798,12 +961,9 @@ static irqreturn_t csra66x0_irq(int irq, void *data) return IRQ_HANDLED; if (csra66x0->in_cluster) { - /* reset all slave codecs */ - max_num_cluster_devices = - sizeof(csra_clust_dev_tbl) / - sizeof(csra_clust_dev_tbl[0]); - for (i = 0; i < max_num_cluster_devices; i++) { - if (i >= component->card->num_aux_devs) + /* reset all slave components */ + for (i = 0; i < component->card->num_aux_devs; i++) { + if (i >= csra66x0->max_num_cluster_devices) break; if (csra_clust_dev_tbl[i].csra66x0_ptr == NULL) continue; @@ -811,9 +971,9 @@ static irqreturn_t csra66x0_irq(int irq, void *data) continue; csra66x0_reset(csra_clust_dev_tbl[i].csra66x0_ptr); } - /* reset all master codecs */ - for (i = 0; i < max_num_cluster_devices; i++) { - if (i >= component->card->num_aux_devs) + /* reset all master components */ + for (i = 0; i < component->card->num_aux_devs; i++) { + if (i >= csra66x0->max_num_cluster_devices) break; if (csra_clust_dev_tbl[i].csra66x0_ptr == NULL) continue; @@ -821,9 +981,9 @@ static irqreturn_t csra66x0_irq(int irq, void *data) csra66x0_reset( csra_clust_dev_tbl[i].csra66x0_ptr); } - /* recover all codecs */ - for (i = 0; i < max_num_cluster_devices; i++) { - if (i >= component->card->num_aux_devs) + /* recover all components */ + for (i = 0; i < component->card->num_aux_devs; i++) { + if (i >= csra66x0->max_num_cluster_devices) break; if (csra_clust_dev_tbl[i].csra66x0_ptr == NULL) continue; @@ -843,13 +1003,275 @@ static const struct of_device_id csra66x0_of_match[] = { }; MODULE_DEVICE_TABLE(of, csra66x0_of_match); +static ssize_t csra66x0_sysfs_write2reg_addr_value(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int ret; + u32 param[2]; /*reg_addr, reg_value */ + char lbuf[CSRA66X0_SYSFS_ENTRY_MAX_LEN]; + struct csra66x0_priv *csra66x0 = dev_get_drvdata(dev); + struct snd_soc_component *component = csra66x0->component; + + if (!csra66x0) { + dev_err(component->dev, "%s: invalid input\n", __func__); + return -EINVAL; + } + + if (count > sizeof(lbuf) - 1) + return -EINVAL; + + ret = strlcpy(lbuf, buf, count); + if (ret != count) { + dev_err(component->dev, "%s: copy input from user space failed. ret=%d\n", + __func__, ret); + ret = -EFAULT; + goto end; + } + + lbuf[count] = '\0'; + ret = sysfs_get_param(lbuf, param, 2); + if (ret) { + dev_err(component->dev, "%s: get sysfs parameter failed. ret=%d\n", + __func__, ret); + goto end; + } + + if (!(csra66x0_addr_is_in_range(param[0], + CSRA66X0_BASE, CSRA66X0_MAX_REGISTER_ADDR) + || csra66x0_addr_is_in_range(param[0], + CSRA66X0_COEFF_BASE, CSRA66X0_MAX_COEFF_ADDR))) { + dev_err(component->dev, "%s: register address 0x%04X out of range\n", + __func__, param[0]); + ret = -EINVAL; + goto end; + } + + if ((param[1] < 0) || (param[1] > 255)) { + dev_err(component->dev, "%s: register data 0x%02X out of range\n", + __func__, param[1]); + ret = -EINVAL; + goto end; + } + + snd_soccomponent_component_write(component, param[0], param[1]); + ret = count; + +end: + return ret; +} + +static ssize_t csra66x0_sysfs_read2reg_addr_set(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int ret; + u32 reg_addr; + char lbuf[CSRA66X0_SYSFS_ENTRY_MAX_LEN]; + struct csra66x0_priv *csra66x0 = dev_get_drvdata(dev); + + if (!csra66x0) { + dev_err(dev, "%s: invalid input\n", __func__); + return -EINVAL; + } + + if (count > sizeof(lbuf) - 1) + return -EINVAL; + + ret = strlcpy(lbuf, buf, count); + if (ret != count) { + dev_err(dev, "%s: copy input from user space failed. ret=%d\n", + __func__, ret); + ret = -EFAULT; + goto end; + } + + lbuf[count] = '\0'; + ret = sysfs_get_param(lbuf, ®_addr, 1); + if (ret) { + dev_err(dev, "%s: get sysfs parameter failed. ret=%d\n", + __func__, ret); + goto end; + } + + if (!(csra66x0_addr_is_in_range(reg_addr, + CSRA66X0_BASE, CSRA66X0_MAX_REGISTER_ADDR) + || csra66x0_addr_is_in_range(reg_addr, + CSRA66X0_COEFF_BASE, CSRA66X0_MAX_COEFF_ADDR))) { + dev_err(dev, "%s: register address 0x%04X out of range\n", + __func__, reg_addr); + ret = -EINVAL; + goto end; + } + + csra66x0->sysfs_reg_addr = reg_addr; + ret = count; + +end: + return ret; +} + +static ssize_t csra66x0_sysfs_read2reg_addr_get(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + u32 reg_addr; + struct csra66x0_priv *csra66x0 = dev_get_drvdata(dev); + + if (!csra66x0) { + dev_err(dev, "%s: invalid input\n", __func__); + return -EINVAL; + } + + reg_addr = csra66x0->sysfs_reg_addr; + + ret = snprintf(buf, CSRA66X0_SYSFS_ENTRY_MAX_LEN, + "0x%04X\n", reg_addr); + pr_debug("%s: 0x%04X\n", __func__, reg_addr); + + return ret; +} + +static ssize_t csra66x0_sysfs_read2reg_value(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + u32 reg_val, reg_addr; + struct csra66x0_priv *csra66x0 = dev_get_drvdata(dev); + struct snd_soc_component *component = csra66x0->component; + + if (!csra66x0) { + dev_err(dev, "%s: invalid input\n", __func__); + return -EINVAL; + } + + reg_addr = csra66x0->sysfs_reg_addr; + if (!(csra66x0_addr_is_in_range(reg_addr, + CSRA66X0_BASE, CSRA66X0_MAX_REGISTER_ADDR) + || csra66x0_addr_is_in_range(reg_addr, + CSRA66X0_COEFF_BASE, CSRA66X0_MAX_COEFF_ADDR))) { + pr_debug("%s: 0x%04X: register address out of range\n", + __func__, reg_addr); + ret = snprintf(buf, CSRA66X0_SYSFS_ENTRY_MAX_LEN, + "0x%04X: register address out of range\n", reg_addr); + goto end; + } + + reg_val = snd_soc_component_read32(component, csra66x0->sysfs_reg_addr); + ret = snprintf(buf, CSRA66X0_SYSFS_ENTRY_MAX_LEN, + "0x%04X: 0x%02X\n", csra66x0->sysfs_reg_addr, reg_val); + pr_debug("%s: 0x%04X: 0x%02X\n", __func__, + csra66x0->sysfs_reg_addr, reg_val); + +end: + return ret; +} + +static ssize_t csra66x0_sysfs_reset(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int val, rc; + struct csra66x0_priv *csra66x0 = dev_get_drvdata(dev); + struct snd_soc_component *component = csra66x0->component; + unsigned int i; + + if (!csra66x0) { + dev_err(dev, "%s: invalid input\n", __func__); + return -EINVAL; + } + rc = kstrtoint(buf, 10, &val); + if (rc) { + dev_err(dev, "%s: kstrtoint failed. rc=%d\n", __func__, rc); + goto end; + } + if (val != SYSFS_RESET) { + dev_err(dev, "%s: value out of range.\n", __func__); + rc = -EINVAL; + goto end; + } + + pr_debug("%s: reset device\n", __func__); + if (csra66x0->in_cluster) { + /* reset all slave components */ + for (i = 0; i < component->card->num_aux_devs; i++) { + if (i >= csra66x0->max_num_cluster_devices) + break; + if (csra_clust_dev_tbl[i].csra66x0_ptr == NULL) + continue; + if (csra_clust_dev_tbl[i].csra66x0_ptr->is_master) + continue; + csra66x0_reset(csra_clust_dev_tbl[i].csra66x0_ptr); + } + /* reset all master components */ + for (i = 0; i < component->card->num_aux_devs; i++) { + if (i >= csra66x0->max_num_cluster_devices) + break; + if (csra_clust_dev_tbl[i].csra66x0_ptr == NULL) + continue; + if (csra_clust_dev_tbl[i].csra66x0_ptr->is_master) + csra66x0_reset( + csra_clust_dev_tbl[i].csra66x0_ptr); + } + /* recover all components */ + for (i = 0; i < component->card->num_aux_devs; i++) { + if (i >= csra66x0->max_num_cluster_devices) + break; + if (csra_clust_dev_tbl[i].csra66x0_ptr == NULL) + continue; + csra66x0_msconfig(csra_clust_dev_tbl[i].csra66x0_ptr); + csra66x0_init(csra_clust_dev_tbl[i].csra66x0_ptr); + } + } else { + csra66x0_reset(csra66x0); + csra66x0_init(csra66x0); + } + + rc = strnlen(buf, CSRA66X0_SYSFS_ENTRY_MAX_LEN); +end: + return rc; +} + +static DEVICE_ATTR(write2reg_addr_value, 0200, NULL, + csra66x0_sysfs_write2reg_addr_value); +static DEVICE_ATTR(read2reg_addr, 0644, csra66x0_sysfs_read2reg_addr_get, + csra66x0_sysfs_read2reg_addr_set); +static DEVICE_ATTR(read2reg_value, 0444, csra66x0_sysfs_read2reg_value, NULL); +static DEVICE_ATTR(reset, 0200, NULL, csra66x0_sysfs_reset); + +static struct attribute *csra66x0_fs_attrs[] = { + &dev_attr_write2reg_addr_value.attr, + &dev_attr_read2reg_addr.attr, + &dev_attr_read2reg_value.attr, + &dev_attr_reset.attr, + NULL, +}; + +static struct attribute_group csra66x0_fs_attrs_group = { + .attrs = csra66x0_fs_attrs, +}; + +static int csra66x0_sysfs_create(struct i2c_client *client, + struct csra66x0_priv *csra66x0) +{ + int rc; + + rc = sysfs_create_group(&client->dev.kobj, &csra66x0_fs_attrs_group); + return rc; +} + +static void csra66x0_sysfs_remove(struct i2c_client *client, + struct csra66x0_priv *csra66x0) +{ + sysfs_remove_group(&client->dev.kobj, &csra66x0_fs_attrs_group); +} + #if IS_ENABLED(CONFIG_I2C) static int csra66x0_i2c_probe(struct i2c_client *client_i2c, const struct i2c_device_id *id) { struct csra66x0_priv *csra66x0; int ret, irq_trigger; +#if IS_ENABLED(CONFIG_DEBUG_FS) char debugfs_dir_name[32]; +#endif csra66x0 = devm_kzalloc(&client_i2c->dev, sizeof(struct csra66x0_priv), GFP_KERNEL); @@ -956,7 +1378,8 @@ static int csra66x0_i2c_probe(struct i2c_client *client_i2c, dev_dbg(&client_i2c->dev, "%s: Failed to create /sys/kernel/debug/%s for debugfs\n", __func__, debugfs_dir_name); - return -ENOMEM; + ret = -ENOMEM; + goto err_debugfs; } csra66x0->debugfs_file_wo = debugfs_create_file( "write_reg_val", S_IFREG | S_IRUGO, csra66x0->debugfs_dir, @@ -966,7 +1389,8 @@ static int csra66x0_i2c_probe(struct i2c_client *client_i2c, dev_dbg(&client_i2c->dev, "%s: Failed to create /sys/kernel/debug/%s/write_reg_val\n", __func__, debugfs_dir_name); - return -ENOMEM; + ret = -ENOMEM; + goto err_debugfs; } csra66x0->debugfs_file_ro = debugfs_create_file( "show_reg_dump", S_IFREG | S_IRUGO, csra66x0->debugfs_dir, @@ -976,15 +1400,16 @@ static int csra66x0_i2c_probe(struct i2c_client *client_i2c, dev_dbg(&client_i2c->dev, "%s: Failed to create /sys/kernel/debug/%s/show_reg_dump\n", __func__, debugfs_dir_name); - return -ENOMEM; + ret = -ENOMEM; + goto err_debugfs; } #endif /* CONFIG_DEBUG_FS */ - /* register codec */ + /* register component */ ret = snd_soc_register_component(&client_i2c->dev, &soc_codec_drv_csra66x0, NULL, 0); if (ret != 0) { - dev_err(&client_i2c->dev, "%s %d: Failed to register codec: %d\n", + dev_err(&client_i2c->dev, "%s %d: Failed to register component: %d\n", __func__, __LINE__, ret); if (gpio_is_valid(csra66x0->vreg_gpio)) { gpio_set_value(csra66x0->vreg_gpio, 0); @@ -992,12 +1417,30 @@ static int csra66x0_i2c_probe(struct i2c_client *client_i2c, } return ret; } + + ret = csra66x0_sysfs_create(client_i2c, csra66x0); + if (ret) { + dev_err(&client_i2c->dev, "%s: sysfs creation failed ret=%d\n", + __func__, ret); + goto err_sysfs; + } + return 0; + +err_sysfs: + snd_soc_unregister_component(&client_i2c->dev); + return ret; + +#if IS_ENABLED(CONFIG_DEBUG_FS) +err_debugfs: + debugfs_remove_recursive(csra66x0->debugfs_dir); + return ret; +#endif } -static int csra66x0_i2c_remove(struct i2c_client *i2c_client) +static int csra66x0_i2c_remove(struct i2c_client *client_i2c) { - struct csra66x0_priv *csra66x0 = i2c_get_clientdata(i2c_client); + struct csra66x0_priv *csra66x0 = i2c_get_clientdata(client_i2c); if (csra66x0) { if (gpio_is_valid(csra66x0->vreg_gpio)) { @@ -1008,7 +1451,10 @@ static int csra66x0_i2c_remove(struct i2c_client *i2c_client) debugfs_remove_recursive(csra66x0->debugfs_dir); #endif } + + csra66x0_sysfs_remove(client_i2c, csra66x0); snd_soc_unregister_component(&i2c_client->dev); + return 0; } diff --git a/asoc/codecs/csra66x0/csra66x0.h b/asoc/codecs/csra66x0/csra66x0.h index 2ff651c73575..04d9ef836dfd 100644 --- a/asoc/codecs/csra66x0/csra66x0.h +++ b/asoc/codecs/csra66x0/csra66x0.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #ifndef _CSRA66X0_H @@ -198,7 +198,10 @@ /* RESERVED (CSRA66X0_BASE+0x00C6) */ /* ... */ /* RESERVED (CSRA66X0_BASE+0x00FF) */ -#define CSRA66X0_MAX_REGISTER_ADDR CSRA66X0_DCA_FREEZE_CTRL +#define CSRA66X0_MAX_REGISTER_ADDR CSRA66X0_DCA_FREEZE_CTRL + +#define CSRA66X0_COEFF_BASE 0xD000 +#define CSRA66X0_MAX_COEFF_ADDR 0xD6DF #define EXPECTED_CSRA66X0_CHIP_ID 0x39 @@ -208,9 +211,13 @@ #define SPK_VOLUME_LSB_MSK 0x00FF #define SPK_VOLUME_MSB_MSK 0x0100 -#define CONFIG_STATE 0x0 -#define RUN_STATE 0x1 -#define STDBY_STATE 0x2 +#define SET_CONFIG_STATE 0x0 +#define SET_RUN_STATE 0x1 +#define SET_STDBY_STATE 0x2 + +#define CONFIG_STATE_ID 0x3 +#define WAIT_FOR_CONFIG_STATE_TIMEOUT_MS 2000 +#define SYSFS_RESET 1 #define FAULT_STATUS_INTERNAL 0x01 #define FAULT_STATUS_OTP_INTEGRITY 0x02 -- GitLab From 46ec0f2835fa94b3a64466d829d6496401ac096a Mon Sep 17 00:00:00 2001 From: Tanya Dixit Date: Tue, 16 Oct 2018 14:48:37 +0530 Subject: [PATCH 0740/1645] asoc: wcd937x: Fix register names and properties Update the register names and default values to be same as the software document of codec. CRs-Fixed: 2334177 Change-Id: Iec3ce76dceb44cef64c1f38a6cd75cb40ee2a539 Signed-off-by: Tanya Dixit --- asoc/codecs/wcd937x/wcd937x-registers.h | 12 ++-- asoc/codecs/wcd937x/wcd937x-regmap.c | 31 ++++++----- asoc/codecs/wcd937x/wcd937x-tables.c | 73 ++++++++++++------------- asoc/codecs/wcd937x/wcd937x.c | 10 ++-- 4 files changed, 63 insertions(+), 63 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x-registers.h b/asoc/codecs/wcd937x/wcd937x-registers.h index be818c28af10..f2c914f15592 100644 --- a/asoc/codecs/wcd937x/wcd937x-registers.h +++ b/asoc/codecs/wcd937x/wcd937x-registers.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #ifndef _WCD937X_REGISTERS_H @@ -330,9 +330,9 @@ enum { #define WCD937X_DIGITAL_CDC_REQ_CTL (WCD937X_BASE_ADDRESS+0x457) #define WCD937X_DIGITAL_CDC_AMIC_CTL (WCD937X_BASE_ADDRESS+0x45A) #define WCD937X_DIGITAL_CDC_DMIC_CTL (WCD937X_BASE_ADDRESS+0x45B) -#define WCD937X_DIGITAL_CDC_DMIC0_CTL (WCD937X_BASE_ADDRESS+0x45C) -#define WCD937X_DIGITAL_CDC_DMIC1_CTL (WCD937X_BASE_ADDRESS+0x45D) -#define WCD937X_DIGITAL_CDC_DMIC2_CTL (WCD937X_BASE_ADDRESS+0x45E) +#define WCD937X_DIGITAL_CDC_DMIC1_CTL (WCD937X_BASE_ADDRESS+0x45C) +#define WCD937X_DIGITAL_CDC_DMIC2_CTL (WCD937X_BASE_ADDRESS+0x45D) +#define WCD937X_DIGITAL_CDC_DMIC3_CTL (WCD937X_BASE_ADDRESS+0x45E) #define WCD937X_DIGITAL_EFUSE_CTL (WCD937X_BASE_ADDRESS+0x45F) #define WCD937X_DIGITAL_EFUSE_PRG_CTL (WCD937X_BASE_ADDRESS+0x460) #define WCD937X_DIGITAL_EFUSE_TEST_CTL_0 (WCD937X_BASE_ADDRESS+0x461) @@ -374,8 +374,8 @@ enum { #define WCD937X_DIGITAL_SWR_HM_TEST (WCD937X_BASE_ADDRESS+0x494) #define WCD937X_DIGITAL_PAD_CTL_PDM_RX0 (WCD937X_BASE_ADDRESS+0x495) #define WCD937X_DIGITAL_PAD_CTL_PDM_RX1 (WCD937X_BASE_ADDRESS+0x496) -#define WCD937X_DIGITAL_PAD_CTL_PDM_RX2 (WCD937X_BASE_ADDRESS+0x497) -#define WCD937X_DIGITAL_PAD_CTL_PDM_TX (WCD937X_BASE_ADDRESS+0x498) +#define WCD937X_DIGITAL_PAD_CTL_PDM_TX0 (WCD937X_BASE_ADDRESS+0x497) +#define WCD937X_DIGITAL_PAD_CTL_PDM_TX1 (WCD937X_BASE_ADDRESS+0x498) #define WCD937X_DIGITAL_PAD_INP_DIS_0 (WCD937X_BASE_ADDRESS+0x499) #define WCD937X_DIGITAL_PAD_INP_DIS_1 (WCD937X_BASE_ADDRESS+0x49A) #define WCD937X_DIGITAL_DRIVE_STRENGTH_0 (WCD937X_BASE_ADDRESS+0x49B) diff --git a/asoc/codecs/wcd937x/wcd937x-regmap.c b/asoc/codecs/wcd937x/wcd937x-regmap.c index 2bb70ca9b6dd..ec29826d58cc 100644 --- a/asoc/codecs/wcd937x/wcd937x-regmap.c +++ b/asoc/codecs/wcd937x/wcd937x-regmap.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -236,7 +236,7 @@ static const struct reg_default wcd937x_defaults[] = { { WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT1, 0x02 }, { WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT2, 0x60 }, { WCD937X_DIGITAL_PAGE_REGISTER, 0x00 }, - { WCD937X_DIGITAL_CHIP_ID0, 0x00 }, + { WCD937X_DIGITAL_CHIP_ID0, 0x01 }, { WCD937X_DIGITAL_CHIP_ID1, 0x00 }, { WCD937X_DIGITAL_CHIP_ID2, 0x0A }, { WCD937X_DIGITAL_CHIP_ID3, 0x01 }, @@ -273,12 +273,12 @@ static const struct reg_default wcd937x_defaults[] = { { WCD937X_DIGITAL_CDC_HPH_DSM_C_2, 0xB1 }, { WCD937X_DIGITAL_CDC_HPH_DSM_C_3, 0x17 }, { WCD937X_DIGITAL_CDC_HPH_DSM_R1, 0x4B }, - { WCD937X_DIGITAL_CDC_HPH_DSM_R2, 0x27 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_R2, 0x26 }, { WCD937X_DIGITAL_CDC_HPH_DSM_R3, 0x32 }, { WCD937X_DIGITAL_CDC_HPH_DSM_R4, 0x57 }, - { WCD937X_DIGITAL_CDC_HPH_DSM_R4, 0x63 }, - { WCD937X_DIGITAL_CDC_HPH_DSM_R4, 0x7C }, - { WCD937X_DIGITAL_CDC_HPH_DSM_R4, 0x57 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_R5, 0x63 }, + { WCD937X_DIGITAL_CDC_HPH_DSM_R6, 0x7C }, + { WCD937X_DIGITAL_CDC_HPH_DSM_R7, 0x57 }, { WCD937X_DIGITAL_CDC_AUX_DSM_A1_0, 0x00 }, { WCD937X_DIGITAL_CDC_AUX_DSM_A1_1, 0x01 }, { WCD937X_DIGITAL_CDC_AUX_DSM_A2_0, 0x96 }, @@ -322,9 +322,9 @@ static const struct reg_default wcd937x_defaults[] = { { WCD937X_DIGITAL_CDC_REQ_CTL, 0x01 }, { WCD937X_DIGITAL_CDC_AMIC_CTL, 0x07 }, { WCD937X_DIGITAL_CDC_DMIC_CTL, 0x00 }, - { WCD937X_DIGITAL_CDC_DMIC0_CTL, 0x01 }, { WCD937X_DIGITAL_CDC_DMIC1_CTL, 0x01 }, { WCD937X_DIGITAL_CDC_DMIC2_CTL, 0x01 }, + { WCD937X_DIGITAL_CDC_DMIC3_CTL, 0x01 }, { WCD937X_DIGITAL_EFUSE_CTL, 0x2B }, { WCD937X_DIGITAL_EFUSE_PRG_CTL, 0x00 }, { WCD937X_DIGITAL_EFUSE_TEST_CTL_0, 0x00 }, @@ -337,7 +337,7 @@ static const struct reg_default wcd937x_defaults[] = { { WCD937X_DIGITAL_INTR_MODE, 0x00 }, { WCD937X_DIGITAL_INTR_MASK_0, 0xFF }, { WCD937X_DIGITAL_INTR_MASK_1, 0xFF }, - { WCD937X_DIGITAL_INTR_MASK_2, 0xFF }, + { WCD937X_DIGITAL_INTR_MASK_2, 0x0F }, { WCD937X_DIGITAL_INTR_STATUS_0, 0x00 }, { WCD937X_DIGITAL_INTR_STATUS_1, 0x00 }, { WCD937X_DIGITAL_INTR_STATUS_2, 0x00 }, @@ -366,8 +366,9 @@ static const struct reg_default wcd937x_defaults[] = { { WCD937X_DIGITAL_SWR_HM_TEST, 0x00 }, { WCD937X_DIGITAL_PAD_CTL_PDM_RX0, 0xF1 }, { WCD937X_DIGITAL_PAD_CTL_PDM_RX1, 0xF1 }, - { WCD937X_DIGITAL_PAD_CTL_PDM_RX2, 0xF1 }, - { WCD937X_DIGITAL_PAD_CTL_PDM_TX, 0xF1 }, + { WCD937X_DIGITAL_PAD_CTL_PDM_TX0, 0xF1 }, + { WCD937X_DIGITAL_PAD_CTL_PDM_TX1, 0xF1 }, + { WCD937X_DIGITAL_PAD_INP_DIS_0, 0x00 }, { WCD937X_DIGITAL_PAD_INP_DIS_1, 0x00 }, { WCD937X_DIGITAL_DRIVE_STRENGTH_0, 0x00 }, { WCD937X_DIGITAL_DRIVE_STRENGTH_1, 0x00 }, @@ -390,7 +391,7 @@ static const struct reg_default wcd937x_defaults[] = { { WCD937X_DIGITAL_SPARE_0, 0x00 }, { WCD937X_DIGITAL_SPARE_1, 0x00 }, { WCD937X_DIGITAL_SPARE_2, 0x00 }, - { WCD937X_DIGITAL_EFUSE_REG_0, 0xFF }, + { WCD937X_DIGITAL_EFUSE_REG_0, 0x00 }, { WCD937X_DIGITAL_EFUSE_REG_1, 0xFF }, { WCD937X_DIGITAL_EFUSE_REG_2, 0xFF }, { WCD937X_DIGITAL_EFUSE_REG_3, 0xFF }, @@ -411,10 +412,10 @@ static const struct reg_default wcd937x_defaults[] = { { WCD937X_DIGITAL_EFUSE_REG_18, 0xFF }, { WCD937X_DIGITAL_EFUSE_REG_19, 0xFF }, { WCD937X_DIGITAL_EFUSE_REG_20, 0x0E }, - { WCD937X_DIGITAL_EFUSE_REG_21, 0x8F }, - { WCD937X_DIGITAL_EFUSE_REG_22, 0x16 }, - { WCD937X_DIGITAL_EFUSE_REG_23, 0x00 }, - { WCD937X_DIGITAL_EFUSE_REG_24, 0x00 }, + { WCD937X_DIGITAL_EFUSE_REG_21, 0x00 }, + { WCD937X_DIGITAL_EFUSE_REG_22, 0x00 }, + { WCD937X_DIGITAL_EFUSE_REG_23, 0xF8 }, + { WCD937X_DIGITAL_EFUSE_REG_24, 0x16 }, { WCD937X_DIGITAL_EFUSE_REG_25, 0x00 }, { WCD937X_DIGITAL_EFUSE_REG_26, 0x00 }, { WCD937X_DIGITAL_EFUSE_REG_27, 0x00 }, diff --git a/asoc/codecs/wcd937x/wcd937x-tables.c b/asoc/codecs/wcd937x/wcd937x-tables.c index 0a58c87a2c4c..3631044bdd0c 100644 --- a/asoc/codecs/wcd937x/wcd937x-tables.c +++ b/asoc/codecs/wcd937x/wcd937x-tables.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018 , The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 , The Linux Foundation. All rights reserved. */ #include @@ -318,9 +318,9 @@ const u8 wcd937x_reg_access[WCD937X_REG(WCD937X_REGISTERS_MAX_SIZE)] = { [WCD937X_REG(WCD937X_DIGITAL_CDC_REQ_CTL)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_CDC_AMIC_CTL)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_CDC_DMIC_CTL)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_CDC_DMIC0_CTL)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_CDC_DMIC1_CTL)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_CDC_DMIC2_CTL)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_CDC_DMIC3_CTL)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_EFUSE_CTL)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_EFUSE_PRG_CTL)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_EFUSE_TEST_CTL_0)] = RD_WR_REG, @@ -362,9 +362,8 @@ const u8 wcd937x_reg_access[WCD937X_REG(WCD937X_REGISTERS_MAX_SIZE)] = { [WCD937X_REG(WCD937X_DIGITAL_SWR_HM_TEST)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_RX0)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_RX1)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_RX2)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_TX)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_TX)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_TX0)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_TX1)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_PAD_INP_DIS_0)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_PAD_INP_DIS_1)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_DRIVE_STRENGTH_0)] = RD_WR_REG, @@ -388,36 +387,36 @@ const u8 wcd937x_reg_access[WCD937X_REG(WCD937X_REGISTERS_MAX_SIZE)] = { [WCD937X_REG(WCD937X_DIGITAL_SPARE_0)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_SPARE_1)] = RD_WR_REG, [WCD937X_REG(WCD937X_DIGITAL_SPARE_2)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_0)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_1)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_2)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_3)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_4)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_5)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_6)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_7)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_8)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_9)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_10)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_11)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_12)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_13)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_14)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_15)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_16)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_17)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_18)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_19)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_20)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_21)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_22)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_23)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_24)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_25)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_26)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_27)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_28)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_29)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_30)] = RD_WR_REG, - [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_31)] = RD_WR_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_0)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_1)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_2)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_3)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_4)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_5)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_6)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_7)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_8)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_9)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_10)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_11)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_12)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_13)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_14)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_15)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_16)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_17)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_18)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_19)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_20)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_21)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_22)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_23)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_24)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_25)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_26)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_27)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_28)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_29)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_30)] = RD_REG, + [WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_31)] = RD_REG, }; diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 004ce796c98a..69b406e08517 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -1024,17 +1024,17 @@ static int wcd937x_codec_enable_dmic(struct snd_soc_dapm_widget *w, case 0: case 1: dmic_clk_cnt = &(wcd937x->dmic_0_1_clk_cnt); - dmic_clk_reg = WCD937X_DIGITAL_CDC_DMIC0_CTL; + dmic_clk_reg = WCD937X_DIGITAL_CDC_DMIC1_CTL; break; case 2: case 3: dmic_clk_cnt = &(wcd937x->dmic_2_3_clk_cnt); - dmic_clk_reg = WCD937X_DIGITAL_CDC_DMIC1_CTL; + dmic_clk_reg = WCD937X_DIGITAL_CDC_DMIC2_CTL; break; case 4: case 5: dmic_clk_cnt = &(wcd937x->dmic_4_5_clk_cnt); - dmic_clk_reg = WCD937X_DIGITAL_CDC_DMIC2_CTL; + dmic_clk_reg = WCD937X_DIGITAL_CDC_DMIC3_CTL; break; default: dev_err(component->dev, "%s: Invalid DMIC Selection\n", @@ -2098,7 +2098,7 @@ static int wcd937x_soc_codec_probe(struct snd_soc_component *component) wcd937x->component = component; variant = (snd_soc_component_read32( - component, WCD937X_DIGITAL_EFUSE_REG_0) & 0x0E) >> 1; + component, WCD937X_DIGITAL_EFUSE_REG_0) & 0x1E) >> 1; wcd937x->variant = variant; wcd937x->fw_data = devm_kzalloc(component->dev, -- GitLab From 02a0f638af2dafb2d2261b1f2bc1e8bc43c1cd47 Mon Sep 17 00:00:00 2001 From: Dieter Luecking Date: Fri, 9 Nov 2018 10:17:32 +0100 Subject: [PATCH 0741/1645] asoc: csra66x0: Add support for 16ch audio playback To support 16 channel audio playback 8 codecs are needed. Update cluster device table to support this number of codecs. Change-Id: I1ab3283b3174357b8b6647662c4519e5dca4bb97 Signed-off-by: Dieter Luecking --- asoc/codecs/csra66x0/csra66x0.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/csra66x0/csra66x0.c b/asoc/codecs/csra66x0/csra66x0.c index 595e7ca8fa03..8126975cb569 100644 --- a/asoc/codecs/csra66x0/csra66x0.c +++ b/asoc/codecs/csra66x0/csra66x0.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -275,7 +275,9 @@ struct csra66x0_cluster_device csra_clust_dev_tbl[] = { {NULL, "CSRA_56"}, {NULL, "CSRA_78"}, {NULL, "CSRA_9A"}, - {NULL, "CSRA_BC"} + {NULL, "CSRA_BC"}, + {NULL, "CSRA_DE"}, + {NULL, "CSRA_F0"} }; #if IS_ENABLED(CONFIG_DEBUG_FS) -- GitLab From 0fc1535782c738c8a2e08f7cbbc1ffd78805f8e3 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Wed, 12 Dec 2018 14:17:46 -0800 Subject: [PATCH 0742/1645] ASoC: msm: update quat/quin tdm slot config/mapping Update QUAT and QUIN TDM slot configuration and mapping information for A2B support. Change-Id: I17a4019f961846477f880cb2a59bc4c8f4c2fe28 Signed-off-by: Derek Chen --- asoc/sa8155.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/asoc/sa8155.c b/asoc/sa8155.c index f5aa549516ec..fedb793ec895 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -199,7 +199,7 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ }, { /* QUAT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* RX_0 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ @@ -209,10 +209,10 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ }, { /* QUIN TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_3 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ @@ -253,7 +253,7 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ }, { /* QUAT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* TX_0 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ @@ -263,7 +263,7 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ }, { /* QUIN TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* TX_0 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ @@ -344,9 +344,9 @@ static struct tdm_slot_cfg tdm_slot[TDM_INTERFACE_MAX] = { /* TERT TDM */ {32, 8}, /* QUAT TDM */ - {32, 8}, + {32, 16}, /* QUIN TDM */ - {32, 8} + {32, 16} }; /***************************************************************************** @@ -402,7 +402,7 @@ static unsigned int tdm_rx_slot_offset {0xFFFF}, /* not used */ }, {/* QUAT TDM */ - {0xFFFF}, /* not used */ + {0, 4, 8, 12, 16, 20, 24, 28, 0xFFFF},/*AMP OUT*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -412,10 +412,10 @@ static unsigned int tdm_rx_slot_offset {0xFFFF}, /* not used */ }, {/* QUIN TDM */ - {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {0, 4, 0xFFFF},/*STEREO SPKR1*/ + {8, 12, 0xFFFF},/*STEREO SPKR2*/ + {16, 20, 0xFFFF},/*STEREO SPKR3*/ + {24, 28, 0xFFFF},/*STEREO SPKR4*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -456,7 +456,8 @@ static unsigned int tdm_tx_slot_offset {28, 0xFFFF}, }, {/* QUAT TDM */ - {0xFFFF}, /* not used */ + {0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*MIC ARR*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -466,7 +467,7 @@ static unsigned int tdm_tx_slot_offset {0xFFFF}, /* not used */ }, {/* QUIN TDM */ - {0xFFFF}, /* not used */ + {0, 4, 8, 12, 16, 20, 0xFFFF},/*EC/ANC REF*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ -- GitLab From ebcfca4e9a46b0f43e8d31030c82116b920da2f4 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 12 Dec 2018 09:29:15 +0530 Subject: [PATCH 0743/1645] asoc: codecs: mbhc: Detect cross connection for mono headsets Mono headsets have only one channel connected. Hence make cross connection decision based on the voltage result of alteast one channel showing cross connection. Change-Id: I22a4ea7e25d09e785e7141f4a74c2830fdff555e Signed-off-by: Ramprasad Katkam --- asoc/codecs/wcd-mbhc-adc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index d63c67ced291..4ab510c7e0ab 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -313,7 +313,7 @@ static int wcd_check_cross_conn(struct wcd_mbhc *mbhc) goto done; } - if (hphl_adc_res > 100 && hphr_adc_res > 100) { + if (hphl_adc_res > 100 || hphr_adc_res > 100) { plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; pr_debug("%s: Cross connection identified\n", __func__); } else { -- GitLab From c2d6c22d1d8f6d06169547229f811944bf36d212 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 30 Nov 2018 18:46:37 +0530 Subject: [PATCH 0744/1645] asoc: bolero: Add routing for rx echo reference Add mixer control and routing to enable echo reference for rx_macro. Change-Id: Ic1095eaa8024f2cb61722609daae94bc645b263b Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/rx-macro.c | 165 ++++++++++++++++++++++++++++++---- 1 file changed, 148 insertions(+), 17 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index ccde8712483d..637e9873999f 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -70,6 +70,10 @@ static const struct snd_kcontrol_new name##_mux = \ #define MAX_IMPED_PARAMS 6 +#define RX_MACRO_EC_MIX_TX0_MASK 0xf0 +#define RX_MACRO_EC_MIX_TX1_MASK 0x0f +#define RX_MACRO_EC_MIX_TX2_MASK 0x0f + struct wcd_imped_val { u32 imped_val; u8 index; @@ -192,6 +196,13 @@ enum { RX_MACRO_COMP_MAX }; +enum { + RX_MACRO_EC0_MUX = 0, + RX_MACRO_EC1_MUX, + RX_MACRO_EC2_MUX, + RX_MACRO_EC_MUX_MAX, +}; + enum { INTn_1_INP_SEL_ZERO = 0, INTn_1_INP_SEL_DEC0, @@ -299,6 +310,7 @@ enum { RX_MACRO_AIF2_PB, RX_MACRO_AIF3_PB, RX_MACRO_AIF4_PB, + RX_MACRO_AIF_ECHO, RX_MACRO_MAX_DAIS, }; @@ -382,10 +394,6 @@ static const char * const rx_sidetone_mix_text[] = { "ZERO", "SRC0", "SRC1", "SRC_SUM" }; -static const char * const rx_echo_mux_text[] = { - "ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2" -}; - static const char * const iir_inp_mux_text[] = { "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5" @@ -477,13 +485,6 @@ RX_MACRO_DAPM_ENUM(rx_int1_mix2_inp, BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4, RX_MACRO_DAPM_ENUM(rx_int2_mix2_inp, BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6, rx_sidetone_mix_text); -RX_MACRO_DAPM_ENUM(rx_mix_tx0, BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4, 4, - rx_echo_mux_text); -RX_MACRO_DAPM_ENUM(rx_mix_tx1, BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, - rx_echo_mux_text); -RX_MACRO_DAPM_ENUM(rx_mix_tx2, BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, - rx_echo_mux_text); - RX_MACRO_DAPM_ENUM(iir0_inp0, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0, 0, iir_inp_mux_text); RX_MACRO_DAPM_ENUM(iir0_inp1, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1, 0, @@ -535,6 +536,31 @@ RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx4, SND_SOC_NOPM, 0, rx_macro_mux_text, RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx5, SND_SOC_NOPM, 0, rx_macro_mux_text, rx_macro_mux_get, rx_macro_mux_put); +static const char * const rx_echo_mux_text[] = { + "ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2" +}; + +static const struct soc_enum rx_mix_tx2_mux_enum = + SOC_ENUM_SINGLE(BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5, 0, 4, + rx_echo_mux_text); + +static const struct snd_kcontrol_new rx_mix_tx2_mux = + SOC_DAPM_ENUM("RX MIX TX2_MUX Mux", rx_mix_tx2_mux_enum); + +static const struct soc_enum rx_mix_tx1_mux_enum = + SOC_ENUM_SINGLE(BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, 4, + rx_echo_mux_text); + +static const struct snd_kcontrol_new rx_mix_tx1_mux = + SOC_DAPM_ENUM("RX MIX TX1_MUX Mux", rx_mix_tx1_mux_enum); + +static const struct soc_enum rx_mix_tx0_mux_enum = + SOC_ENUM_SINGLE(BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4, 4, 4, + rx_echo_mux_text); + +static const struct snd_kcontrol_new rx_mix_tx0_mux = + SOC_DAPM_ENUM("RX MIX TX0_MUX Mux", rx_mix_tx0_mux_enum); + static struct snd_soc_dai_ops rx_macro_dai_ops = { .hw_params = rx_macro_hw_params, .get_channel_map = rx_macro_get_channel_map, @@ -597,6 +623,20 @@ static struct snd_soc_dai_driver rx_macro_dai[] = { }, .ops = &rx_macro_dai_ops, }, + { + .name = "rx_macro_echo", + .id = RX_MACRO_AIF_ECHO, + .capture = { + .stream_name = "RX_AIF_ECHO Capture", + .rates = RX_MACRO_ECHO_RATES, + .formats = RX_MACRO_ECHO_FORMATS, + .rate_max = 48000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 3, + }, + .ops = &rx_macro_dai_ops, + }, }; static int get_impedance_index(int imped) @@ -695,7 +735,7 @@ static bool rx_macro_get_data(struct snd_soc_component *component, if (!(*rx_priv)->component) { dev_err(component->dev, - "%s: tx_priv codec is not initialized!\n", func_name); + "%s: rx_priv component is not initialized!\n", func_name); return false; } @@ -963,7 +1003,7 @@ static int rx_macro_get_channel_map(struct snd_soc_dai *dai, struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; unsigned int temp = 0, ch_mask = 0; - u16 i = 0; + u16 val = 0, mask = 0, cnt = 0, i = 0; if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; @@ -982,6 +1022,26 @@ static int rx_macro_get_channel_map(struct snd_soc_dai *dai, *rx_slot = ch_mask; *rx_num = rx_priv->active_ch_cnt[dai->id]; break; + case RX_MACRO_AIF_ECHO: + val = snd_soc_component_read32(component, + BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4); + if (val & RX_MACRO_EC_MIX_TX0_MASK) { + mask |= 0x1; + cnt++; + } + if (val & RX_MACRO_EC_MIX_TX1_MASK) { + mask |= 0x2; + cnt++; + } + val = snd_soc_component_read32(component, + BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5); + if (val & RX_MACRO_EC_MIX_TX2_MASK) { + mask |= 0x4; + cnt++; + } + *tx_slot = mask; + *tx_num = cnt; + break; default: dev_err(rx_dev, "%s: Invalid AIF\n", __func__); break; @@ -2646,6 +2706,50 @@ static const struct snd_kcontrol_new rx_macro_snd_controls[] = { rx_macro_iir_band_audio_mixer_put), }; +static int rx_macro_enable_echo(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + u16 val = 0, ec_hq_reg = 0; + int ec_tx = 0; + + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + dev_dbg(rx_dev, "%s %d %s\n", __func__, event, w->name); + + val = snd_soc_component_read32(component, + BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4); + if (!(strcmp(w->name, "RX MIX TX0 MUX"))) + ec_tx = ((val & 0xf0) >> 0x4) - 1; + else if (!(strcmp(w->name, "RX MIX TX1 MUX"))) + ec_tx = (val & 0x0f) - 1; + + val = snd_soc_component_read32(component, + BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5); + if (!(strcmp(w->name, "RX MIX TX2 MUX"))) + ec_tx = (val & 0x0f) - 1; + + if (ec_tx < 0 || (ec_tx >= RX_MACRO_EC_MUX_MAX)) { + dev_err(rx_dev, "%s: EC mix control not set correctly\n", + __func__); + return -EINVAL; + } + ec_hq_reg = BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL + + 0x40 * ec_tx; + snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01); + ec_hq_reg = BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0 + + 0x40 * ec_tx; + /* default set to 48k */ + snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08); + + return 0; +} + static const struct snd_soc_dapm_widget rx_macro_dapm_widgets[] = { SND_SOC_DAPM_AIF_IN("RX AIF1 PB", "RX_MACRO_AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), @@ -2659,6 +2763,9 @@ static const struct snd_soc_dapm_widget rx_macro_dapm_widgets[] = { SND_SOC_DAPM_AIF_IN("RX AIF4 PB", "RX_MACRO_AIF4 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("RX AIF_ECHO", "RX_AIF_ECHO Capture", 0, + SND_SOC_NOPM, 0, 0), + RX_MACRO_DAPM_MUX("RX_MACRO RX0 MUX", RX_MACRO_RX0, rx_macro_rx0), RX_MACRO_DAPM_MUX("RX_MACRO RX1 MUX", RX_MACRO_RX1, rx_macro_rx1), RX_MACRO_DAPM_MUX("RX_MACRO RX2 MUX", RX_MACRO_RX2, rx_macro_rx2), @@ -2682,6 +2789,19 @@ static const struct snd_soc_dapm_widget rx_macro_dapm_widgets[] = { RX_MACRO_DAPM_MUX("IIR1 INP2 MUX", 0, iir1_inp2), RX_MACRO_DAPM_MUX("IIR1 INP3 MUX", 0, iir1_inp3), + SND_SOC_DAPM_MUX_E("RX MIX TX0 MUX", SND_SOC_NOPM, + RX_MACRO_EC0_MUX, 0, + &rx_mix_tx0_mux, rx_macro_enable_echo, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX MIX TX1 MUX", SND_SOC_NOPM, + RX_MACRO_EC1_MUX, 0, + &rx_mix_tx1_mux, rx_macro_enable_echo, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX MIX TX2 MUX", SND_SOC_NOPM, + RX_MACRO_EC2_MUX, 0, + &rx_mix_tx2_mux, rx_macro_enable_echo, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("IIR0", BOLERO_CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL, 4, 0, NULL, 0, rx_macro_set_iir_gain, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), @@ -2693,9 +2813,6 @@ static const struct snd_soc_dapm_widget rx_macro_dapm_widgets[] = { SND_SOC_DAPM_MIXER("SRC1", BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL, 4, 0, NULL, 0), - RX_MACRO_DAPM_MUX("RX MIX TX0 MUX", 0, rx_mix_tx0), - RX_MACRO_DAPM_MUX("RX MIX TX1 MUX", 0, rx_mix_tx1), - RX_MACRO_DAPM_MUX("RX MIX TX2 MUX", 0, rx_mix_tx2), RX_MACRO_DAPM_MUX("RX INT0 DEM MUX", 0, rx_int0_dem_inp), RX_MACRO_DAPM_MUX("RX INT1 DEM MUX", 0, rx_int1_dem_inp), @@ -2905,6 +3022,20 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP1"}, {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP2"}, + {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX0 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX1 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, + {"RX MIX TX2 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, + {"RX AIF_ECHO", NULL, "RX MIX TX0 MUX"}, + {"RX AIF_ECHO", NULL, "RX MIX TX1 MUX"}, + {"RX AIF_ECHO", NULL, "RX MIX TX2 MUX"}, + {"RX AIF_ECHO", NULL, "RX_MCLK"}, + /* Mixing path INT0 */ {"RX INT0_2 MUX", "RX0", "RX_RX0"}, {"RX INT0_2 MUX", "RX1", "RX_RX1"}, -- GitLab From 39ead2c1e84efab0616a14a1e2858010a6c151ed Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 14 Dec 2018 12:22:46 +0530 Subject: [PATCH 0745/1645] ASoC: bolero: Remove unwanted logs at bootup Correct name of widgets for tx macro from TX SWR_MIC to TX SWR_DMIC. Also assign codec pointer to rx_priv before calling rx_macro_init_bcl_pmic_reg. Change-Id: I268d79413c53bcd2d8e7a391859b71b7a7e3f64e Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/rx-macro.c | 3 +-- asoc/codecs/bolero/tx-macro.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 637e9873999f..dcef1267e04b 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -3384,9 +3384,8 @@ static int rx_macro_init(struct snd_soc_component *component) snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX2_RX_PATH_CFG3, 0x03, 0x02); - rx_macro_init_bcl_pmic_reg(component); - rx_priv->component = component; + rx_macro_init_bcl_pmic_reg(component); return 0; } diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 0430307c8dfb..339929863fff 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -1563,14 +1563,14 @@ static int tx_macro_init(struct snd_soc_component *component) snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC1"); snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC2"); snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC3"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC0"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC1"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC2"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC3"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC4"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC5"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC6"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC7"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC0"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC4"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC5"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC6"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC7"); snd_soc_dapm_sync(dapm); for (i = 0; i < NUM_DECIMATORS; i++) { -- GitLab From 83e6ee1c40c74fd1f3f2986a108a9498d0ec7da9 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 30 Nov 2018 18:58:31 +0530 Subject: [PATCH 0746/1645] asoc: sm6150: Add TX_CDC_DMA_TX_0 backend dailink TX_CDC_DMA_TX_0 supports three channels, therefore it can be used for rx_macro_echo. Add required backend dailink. Also remove AMIC4 from ignore_suspend as it is not used for talos. Change-Id: I74b7adca9fa4001866232c1a9173e865c2a169c4 Signed-off-by: Vatsal Bucha --- asoc/sm6150.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 02f8fc5eae12..c7dc1f21e062 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -7398,6 +7398,20 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { .ops = &msm_cdc_dma_be_ops, }, /* TX CDC DMA Backend DAI Links */ + { + .name = LPASS_BE_TX_CDC_DMA_TX_0, + .stream_name = "TX CDC DMA0 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45105", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "rx_macro_echo", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, { .name = LPASS_BE_TX_CDC_DMA_TX_3, .stream_name = "TX CDC DMA3 Capture", @@ -7953,7 +7967,6 @@ static int msm_aux_codec_init(struct snd_soc_component *component) snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); - snd_soc_dapm_ignore_suspend(dapm, "AMIC4"); snd_soc_dapm_sync(dapm); pdata = snd_soc_card_get_drvdata(component->card); -- GitLab From de79a06acf6cdbb7780fe68b39364f81d27c6172 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Wed, 5 Dec 2018 14:18:55 +0530 Subject: [PATCH 0747/1645] dsp: update EC reference port only if channels are configured ADM open is failed due to payload size not getting updated with ec reference size. Update EC reference port only if EC reference channels are configured. Change-Id: Ic2dd6a3cf805c1ea40d71d0b62b6e867167d169e Signed-off-by: Surendar Karka --- dsp/q6adm.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index d0b94177bce6..a01429b8e7e0 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -2943,9 +2943,18 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, open_v8.endpoint_id_2 = 0xFFFF; open_v8.endpoint_id_3 = 0xFFFF; - if (this_adm.ec_ref_rx && (path != ADM_PATH_PLAYBACK)) { - open_v8.endpoint_id_2 = this_adm.ec_ref_rx; - this_adm.ec_ref_rx = -1; + if ((this_adm.ec_ref_rx != -1) && + (path != ADM_PATH_PLAYBACK)) { + if (this_adm.num_ec_ref_rx_chans != 0) { + open_v8.endpoint_id_2 = + this_adm.ec_ref_rx; + this_adm.ec_ref_rx = -1; + } else { + pr_err("%s: EC channels not set %d\n", + __func__, + this_adm.num_ec_ref_rx_chans); + return -EINVAL; + } } open_v8.topology_id = topology; -- GitLab From be837353058297851ff6d67b384c5f56d3132c51 Mon Sep 17 00:00:00 2001 From: Aniket Kumar Lata Date: Wed, 20 Jun 2018 14:57:05 -0700 Subject: [PATCH 0748/1645] dsp: Add frame size control parameter for AAC encoder BT sink devices have a limitation on the packet sizes they can receive and handle from BT sources. AAC encoder can produce output frames which can vary in size based on content being encoded. If frame size exceeds MTU size of BT sink device, it will lead to incorrect decoding of frames in BT sink. Add a frame configuration parameter (MTU/Peak bitrate) for AAC encoder to solve this problem. Change-Id: Ia7795049e982400b0b3657b0b3a8990fc6920e38 Signed-off-by: Aniket Kumar Lata --- asoc/msm-dai-q6-v2.c | 6 +++--- dsp/q6afe.c | 34 +++++++++++++++++++++++++++++++++- include/dsp/apr_audio-v2.h | 28 ++++++++++++++++++++++++++-- 3 files changed, 62 insertions(+), 6 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 02e454e3939a..52bf313580da 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include @@ -2815,7 +2815,7 @@ static int msm_dai_q6_afe_enc_cfg_get(struct snd_kcontrol *kcontrol, case ENC_FMT_AAC_V2: memcpy(ucontrol->value.bytes.data + format_size, &dai_data->enc_config.data, - sizeof(struct asm_aac_enc_cfg_v2_t)); + sizeof(struct asm_aac_enc_cfg_t)); break; case ENC_FMT_APTX: memcpy(ucontrol->value.bytes.data + format_size, @@ -2878,7 +2878,7 @@ static int msm_dai_q6_afe_enc_cfg_put(struct snd_kcontrol *kcontrol, case ENC_FMT_AAC_V2: memcpy(&dai_data->enc_config.data, ucontrol->value.bytes.data + format_size, - sizeof(struct asm_aac_enc_cfg_v2_t)); + sizeof(struct asm_aac_enc_cfg_t)); break; case ENC_FMT_APTX: memcpy(&dai_data->enc_config.data, diff --git a/dsp/q6afe.c b/dsp/q6afe.c index f36f06f2e61e..b93a5e0a3636 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -3661,6 +3661,7 @@ static int q6afe_send_enc_config(u16 port_id, struct avs_enc_set_scrambler_param_t enc_set_scrambler_param; struct afe_enc_level_to_bitrate_map_param_t map_param; struct afe_enc_dec_imc_info_param_t imc_info_param; + struct asm_aac_frame_size_control_t frame_ctl_param; struct afe_port_media_type_t media_type; struct aptx_channel_mode_param_t channel_mode_param; struct param_hdr_v3 param_hdr; @@ -3675,6 +3676,7 @@ static int q6afe_send_enc_config(u16 port_id, memset(&enc_set_scrambler_param, 0, sizeof(enc_set_scrambler_param)); memset(&map_param, 0, sizeof(map_param)); memset(&imc_info_param, 0, sizeof(imc_info_param)); + memset(&frame_ctl_param, 0, sizeof(frame_ctl_param)); memset(&media_type, 0, sizeof(media_type)); memset(¶m_hdr, 0, sizeof(param_hdr)); @@ -3710,6 +3712,12 @@ static int q6afe_send_enc_config(u16 port_id, enc_blk_param.enc_cfg_blk_size = sizeof(union afe_enc_config_data) - sizeof(struct afe_abr_enc_cfg_t); + } else if (format == ASM_MEDIA_FMT_AAC_V2) { + param_hdr.param_size = sizeof(enc_blk_param) + - sizeof(struct asm_aac_frame_size_control_t); + enc_blk_param.enc_cfg_blk_size = + sizeof(enc_blk_param.enc_blk_config) + - sizeof(struct asm_aac_frame_size_control_t); } else { param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t); enc_blk_param.enc_cfg_blk_size = @@ -3729,6 +3737,30 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } + if (format == ASM_MEDIA_FMT_AAC_V2) { + uint32_t frame_size_ctl_value = enc_blk_param.enc_blk_config. + aac_config.frame_ctl.ctl_value; + if (frame_size_ctl_value > 0) { + param_hdr.param_id = + AFE_PARAM_ID_AAC_FRM_SIZE_CONTROL; + param_hdr.param_size = sizeof(frame_ctl_param); + frame_ctl_param.ctl_type = enc_blk_param. + enc_blk_config.aac_config.frame_ctl.ctl_type; + frame_ctl_param.ctl_value = frame_size_ctl_value; + pr_debug("%s: send AFE_PARAM_ID_AAC_FRM_SIZE_CONTROL\n", + __func__); + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &frame_ctl_param); + if (ret) { + pr_err("%s: AAC_FRM_SIZE_CONTROL failed %d\n", + __func__, ret); + goto exit; + } + } + } + if (format == ASM_MEDIA_FMT_APTX) { pr_debug("%s: sending AFE_PARAM_ID_APTX_SYNC_MODE to DSP", __func__); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 475027682f84..38f40a75350d 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ @@ -3932,6 +3932,12 @@ struct aptx_channel_mode_param_t { */ #define AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED 0x3 +/* + * Parameter to send frame control size + * to DSP for AAC encoder in AFE. + */ +#define AFE_PARAM_ID_AAC_FRM_SIZE_CONTROL 0x000132EA + /* * ID for AFE port module. This will be used to define port properties. * This module supports following parameter IDs: @@ -4102,6 +4108,23 @@ struct asm_aac_enc_cfg_v2_t { uint32_t sample_rate; } __packed; +/* Structure to control frame size of AAC encoded frames. */ +struct asm_aac_frame_size_control_t { + /* Type of frame size control: MTU_SIZE / PEAK_BIT_RATE*/ + uint32_t ctl_type; + /* + * Control value + * MTU_SIZE: MTU size in bytes + * PEAK_BIT_RATE: Peak bitrate in bits per second. + */ + uint32_t ctl_value; +} __packed; + +struct asm_aac_enc_cfg_t { + struct asm_aac_enc_cfg_v2_t aac_cfg; + struct asm_aac_frame_size_control_t frame_ctl; +} __packed; + /* FMT ID for apt-X Classic */ #define ASM_MEDIA_FMT_APTX 0x000131ff @@ -4413,7 +4436,7 @@ struct asm_aac_dec_cfg_v2_t { union afe_enc_config_data { struct asm_sbc_enc_cfg_t sbc_config; - struct asm_aac_enc_cfg_v2_t aac_config; + struct asm_aac_enc_cfg_t aac_config; struct asm_custom_enc_cfg_t custom_config; struct asm_celt_enc_cfg_t celt_config; struct asm_aptx_enc_cfg_t aptx_config; @@ -4642,6 +4665,7 @@ union afe_port_config { struct afe_param_id_tdm_cfg tdm; struct afe_param_id_usb_audio_cfg usb_audio; struct afe_param_id_aptx_sync_mode sync_mode_param; + struct asm_aac_frame_size_control_t frame_ctl_param; struct afe_enc_fmt_id_param_t enc_fmt; struct afe_port_media_type_t media_type; struct afe_enc_cfg_blk_param_t enc_blk_param; -- GitLab From a4c747b6d5484af4ea17e44fe7092b60a616fe9b Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Tue, 11 Dec 2018 19:15:53 +0530 Subject: [PATCH 0749/1645] soc: swr-mstr: Reset swr only during init or ssr Reset swr only during init or ssr-pdr scenarios. Do not reset swr during clock stop, which would result in bad state of master and cause error interrupts. Change-Id: I88e071921409a5b5797aeedb8e7cb57cb5d5bb9a Signed-off-by: Ramprasad Katkam --- asoc/codecs/bolero/rx-macro.c | 21 ++++++++++++++------- asoc/codecs/bolero/tx-macro.c | 16 ++++++++++++++-- asoc/codecs/bolero/wsa-macro.c | 15 ++++++++++++++- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index ccde8712483d..bec125cfd870 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -332,6 +332,7 @@ struct rx_macro_priv { u16 prim_int_users[INTERP_MAX]; int rx_mclk_users; int swr_clk_users; + bool reset_swr; int clsh_users; int rx_mclk_cnt; bool is_native_on; @@ -1183,6 +1184,8 @@ static int rx_macro_event_handler(struct snd_soc_component *component, break; case BOLERO_MACRO_EVT_SSR_UP: rx_priv->dev_up = true; + /* reset swr after ssr/pdr */ + rx_priv->reset_swr = true; /* enable&disable MCLK_MUX1 to reset GFMUX reg */ bolero_request_clock(rx_priv->dev, RX_MACRO, MCLK_MUX1, true); @@ -3088,15 +3091,18 @@ static int rx_swrm_clock(void *handle, bool enable) __func__); goto exit; } - regmap_update_bits(regmap, - BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, - 0x02, 0x02); + if (rx_priv->reset_swr) + regmap_update_bits(regmap, + BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, + 0x02, 0x02); regmap_update_bits(regmap, BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x01); - regmap_update_bits(regmap, - BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, - 0x02, 0x00); + if (rx_priv->reset_swr) + regmap_update_bits(regmap, + BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, + 0x02, 0x00); + rx_priv->reset_swr = false; msm_cdc_pinctrl_select_active_state( rx_priv->rx_swr_gpio_p); } @@ -3444,6 +3450,7 @@ static int rx_macro_probe(struct platform_device *pdev) return -ENOMEM; } rx_priv->rx_mclk_mode_muxsel = muxsel_io; + rx_priv->reset_swr = true; INIT_WORK(&rx_priv->rx_macro_add_child_devices_work, rx_macro_add_child_devices); rx_priv->swr_plat_data.handle = (void *) rx_priv; diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 0430307c8dfb..ca9515387de4 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -127,6 +127,7 @@ struct tx_macro_priv { bool dec_active[NUM_DECIMATORS]; int tx_mclk_users; int swr_clk_users; + bool reset_swr; struct clk *tx_core_clk; struct clk *tx_npl_clk; struct mutex mclk_lock; @@ -317,6 +318,8 @@ static int tx_macro_event_handler(struct snd_soc_component *component, SWR_DEVICE_DOWN, NULL); break; case BOLERO_MACRO_EVT_SSR_UP: + /* reset swr after ssr/pdr */ + tx_priv->reset_swr = true; swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, SWR_DEVICE_SSR_UP, NULL); @@ -1426,9 +1429,18 @@ static int tx_macro_swrm_clock(void *handle, bool enable) __func__); goto exit; } + if (tx_priv->reset_swr) + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, + 0x02, 0x02); regmap_update_bits(regmap, BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x01); + if (tx_priv->reset_swr) + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, + 0x02, 0x00); + tx_priv->reset_swr = false; regmap_update_bits(regmap, BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, 0x1C, 0x0C); @@ -1799,7 +1811,7 @@ static int tx_macro_probe(struct platform_device *pdev) sample_rate, tx_priv) == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED) return -EINVAL; } - + tx_priv->reset_swr = true; INIT_WORK(&tx_priv->tx_macro_add_child_devices_work, tx_macro_add_child_devices); tx_priv->swr_plat_data.handle = (void *) tx_priv; diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index d0222c5fa6ed..e431a77db1f9 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -192,6 +192,7 @@ struct wsa_macro_priv { u16 prim_int_users[WSA_MACRO_RX1 + 1]; u16 wsa_mclk_users; u16 swr_clk_users; + bool reset_swr; unsigned int vi_feed_value; struct mutex mclk_lock; struct mutex swr_clk_lock; @@ -929,6 +930,8 @@ static int wsa_macro_event_handler(struct snd_soc_component *component, SWR_DEVICE_DOWN, NULL); break; case BOLERO_MACRO_EVT_SSR_UP: + /* reset swr after ssr/pdr */ + wsa_priv->reset_swr = true; swrm_wcd_notify( wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, SWR_DEVICE_SSR_UP, NULL); @@ -2568,9 +2571,18 @@ static int wsa_swrm_clock(void *handle, bool enable) __func__); goto exit; } + if (wsa_priv->reset_swr) + regmap_update_bits(regmap, + BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, + 0x02, 0x02); regmap_update_bits(regmap, BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x01); + if (wsa_priv->reset_swr) + regmap_update_bits(regmap, + BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, + 0x02, 0x00); + wsa_priv->reset_swr = false; regmap_update_bits(regmap, BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 0x1C, 0x0C); @@ -2834,6 +2846,7 @@ static int wsa_macro_probe(struct platform_device *pdev) return -EINVAL; } wsa_priv->wsa_io_base = wsa_io_base; + wsa_priv->reset_swr = true; INIT_WORK(&wsa_priv->wsa_macro_add_child_devices_work, wsa_macro_add_child_devices); wsa_priv->swr_plat_data.handle = (void *) wsa_priv; -- GitLab From b4c7c680ef759d21e727dabf68f2797523836168 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 19 Dec 2018 18:58:36 +0530 Subject: [PATCH 0750/1645] soc: swr-mstr: switch to bank 0 before ssr/pdr Do bank switch to default bank during ssr/pdr as master is reset to default state. This avoids wrong state of swr master during pdr. Change-Id: I86a7bd53d471e9d864d25dcb84ad8fe12151cc0d Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index ddf04ab4c2d3..f2fa733e363b 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -493,9 +493,9 @@ static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data, dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x,wcmd_id: 0x%x, \ dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, cmd_id, swrm->wcmd_id,dev_addr, cmd_data); + swr_master_write(swrm, SWRM_CMD_FIFO_WR_CMD, val); /* wait for FIFO WR command to complete to avoid overflow */ usleep_range(250, 255); - swr_master_write(swrm, SWRM_CMD_FIFO_WR_CMD, val); if (cmd_id == 0xF) { /* * sleep for 10ms for MSM soundwire variant to allow broadcast @@ -2042,6 +2042,7 @@ static int swrm_runtime_resume(struct device *dev) if (swrm_clk_request(swrm, true)) goto exit; if (!swrm->clk_stop_mode0_supp || swrm->state == SWR_MSTR_SSR) { + enable_bank_switch(swrm, 0, SWR_ROW_50, SWR_MIN_COL); list_for_each_entry(swr_dev, &mstr->devices, dev_list) { ret = swr_device_up(swr_dev); if (ret) { @@ -2096,6 +2097,7 @@ static int swrm_runtime_suspend(struct device *dev) goto exit; } if (!swrm->clk_stop_mode0_supp || swrm->state == SWR_MSTR_SSR) { + enable_bank_switch(swrm, 0, SWR_ROW_50, SWR_MIN_COL); swrm_clk_pause(swrm); swr_master_write(swrm, SWRM_COMP_CFG_ADDR, 0x00); list_for_each_entry(swr_dev, &mstr->devices, dev_list) { -- GitLab From 44b7a9602b6f3efbe515278ede38c1f4cbb6fa36 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Thu, 20 Dec 2018 15:08:44 +0530 Subject: [PATCH 0751/1645] soc: swr-mstr: Hold suspend during hw wakeup interrupt Hold system suspend when hardware wakeup interrupt is received to resume soundwire master. Change-Id: I99a58aa7d28cfa514d72bacc8c6fc6e95fbe038a Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index f2fa733e363b..0d81239707b6 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1430,12 +1430,17 @@ static irqreturn_t swrm_wakeup_interrupt(int irq, void *dev) return ret; } mutex_unlock(&swrm->devlock); + if (unlikely(swrm_lock_sleep(swrm) == false)) { + dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__); + goto exit; + } if (swrm->wake_irq > 0) disable_irq_nosync(swrm->wake_irq); pm_runtime_get_sync(swrm->dev); pm_runtime_mark_last_busy(swrm->dev); pm_runtime_put_autosuspend(swrm->dev); - + swrm_unlock_sleep(swrm); +exit: return ret; } -- GitLab From 5ee54aee41b5536c4ce622fd764675eb8da09f4a Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 19 Dec 2018 18:56:00 +0530 Subject: [PATCH 0752/1645] asoc: bolero: Call swr device down before setting ssr down Invoke swr device down callback to set soundwire master to reset state before setting ssr down flag. This is to ensure master is reset to proper state after ssr/pdr. Change-Id: Ifb5548f603ac03b772006314f4723c0ac0176928 Signed-off-by: Ramprasad Katkam --- asoc/codecs/bolero/rx-macro.c | 4 ++-- asoc/codecs/bolero/tx-macro.c | 4 ++-- asoc/codecs/bolero/wsa-macro.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index bec125cfd870..1dd2559efa56 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1177,10 +1177,10 @@ static int rx_macro_event_handler(struct snd_soc_component *component, rx_priv->dev_up = false; swrm_wcd_notify( rx_priv->swr_ctrl_data[0].rx_swr_pdev, - SWR_DEVICE_SSR_DOWN, NULL); + SWR_DEVICE_DOWN, NULL); swrm_wcd_notify( rx_priv->swr_ctrl_data[0].rx_swr_pdev, - SWR_DEVICE_DOWN, NULL); + SWR_DEVICE_SSR_DOWN, NULL); break; case BOLERO_MACRO_EVT_SSR_UP: rx_priv->dev_up = true; diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index ca9515387de4..c24307134645 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -312,10 +312,10 @@ static int tx_macro_event_handler(struct snd_soc_component *component, case BOLERO_MACRO_EVT_SSR_DOWN: swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, - SWR_DEVICE_SSR_DOWN, NULL); + SWR_DEVICE_DOWN, NULL); swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, - SWR_DEVICE_DOWN, NULL); + SWR_DEVICE_SSR_DOWN, NULL); break; case BOLERO_MACRO_EVT_SSR_UP: /* reset swr after ssr/pdr */ diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index e431a77db1f9..85417bc3df33 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -924,10 +924,10 @@ static int wsa_macro_event_handler(struct snd_soc_component *component, case BOLERO_MACRO_EVT_SSR_DOWN: swrm_wcd_notify( wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, - SWR_DEVICE_SSR_DOWN, NULL); + SWR_DEVICE_DOWN, NULL); swrm_wcd_notify( wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, - SWR_DEVICE_DOWN, NULL); + SWR_DEVICE_SSR_DOWN, NULL); break; case BOLERO_MACRO_EVT_SSR_UP: /* reset swr after ssr/pdr */ -- GitLab From ce4f3d9b5905012ff99b69985ed91a2763211ad4 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 20 Dec 2018 20:24:33 +0530 Subject: [PATCH 0753/1645] asoc: codecs: Increase timeout for session close during SSR/PDR Userspace takes 10 seconds to close the session when pcm_start fails due to concurrency with PDR/SSR. Match the SSR timeout in va macro to user space session tear down delay. Change-Id: I1e0fb4bdb25a43cbe7c345a47c115410b964e6eb Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/va-macro.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index db078e2a6cdf..cee0e002a0f1 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -41,7 +41,7 @@ #define VA_MACRO_TX_DMIC_CLK_DIV_SHFT 0x01 #define BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS 40 -#define MAX_RETRY_ATTEMPTS 250 +#define MAX_RETRY_ATTEMPTS 500 static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); static int va_tx_unmute_delay = BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS; @@ -225,12 +225,15 @@ static int va_macro_event_handler(struct snd_soc_component *component, switch (event) { case BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET: while ((va_priv->va_mclk_users != 0) && (retry_cnt != 0)) { - dev_dbg(va_dev, "%s:retry_cnt: %d\n", + dev_dbg_ratelimited(va_dev, "%s:retry_cnt: %d\n", __func__, retry_cnt); /* - * loop and check every 20ms for va_mclk user count - * to get reset to 0 which ensures userspace teardown - * is done and SSR powerup seq can proceed. + * Userspace takes 10 seconds to close + * the session when pcm_start fails due to concurrency + * with PDR/SSR. Loop and check every 20ms till 10 + * seconds for va_mclk user count to get reset to 0 + * which ensures userspace teardown is done and SSR + * powerup seq can proceed. */ msleep(20); retry_cnt--; -- GitLab From a83ad850546e6f8e5959db4cee2971b5bf8ecb91 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Thu, 20 Dec 2018 17:09:28 -0800 Subject: [PATCH 0754/1645] asoc: msm-dai-q6-v2: add a new VA macro DMA TX CPU DAI VA macro in Kona has three DMA TX ports. Add a new VA DMA TX CPU DAI in the DSP DAI driver to use it on Kona. Change-Id: Ic144dbed1bd63af6f0150f854fdb74d57e156839 Signed-off-by: Xiaoyu Ye --- asoc/msm-dai-q6-v2.c | 25 +++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 3 +++ 2 files changed, 28 insertions(+) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 02e454e3939a..acca44360788 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -10654,6 +10654,31 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { .probe = msm_dai_q6_dai_cdc_dma_probe, .remove = msm_dai_q6_dai_cdc_dma_remove, }, + { + .capture = { + .stream_name = "VA CDC DMA2 Capture", + .aif_name = "VA_CDC_DMA_TX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .name = "VA_CDC_DMA_TX_2", + .ops = &msm_dai_q6_cdc_dma_ops, + .id = AFE_PORT_ID_VA_CODEC_DMA_TX_2, + .probe = msm_dai_q6_dai_cdc_dma_probe, + .remove = msm_dai_q6_dai_cdc_dma_remove, + }, { .playback = { .stream_name = "RX CDC DMA0 Playback", diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 475027682f84..f5f6da786b96 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1570,6 +1570,9 @@ struct adm_cmd_connect_afe_port_v5 { /* AFE VA Codec DMA Tx port 1 */ #define AFE_PORT_ID_VA_CODEC_DMA_TX_1 0xB023 +/* AFE VA Codec DMA Tx port 2 */ +#define AFE_PORT_ID_VA_CODEC_DMA_TX_2 0xB025 + /* AFE Rx Codec DMA Rx port 0 */ #define AFE_PORT_ID_RX_CODEC_DMA_RX_0 0xB030 -- GitLab From f439aedf1f486ecd4b4203c21f6ac02fc27a2684 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Wed, 2 Jan 2019 16:40:01 -0800 Subject: [PATCH 0755/1645] asoc: msm: routing: add support for VA macro DMA interface VA macro on Kona has three DMA TX ports. Add support routing for the third VA macro DMA TX port to add backend and the corresponding front ends. Change-Id: I07298045292443af1220d9b95f4cd7aee0b79c66 Signed-off-by: Xiaoyu Ye --- asoc/msm-pcm-routing-v2.c | 160 +++++++++++++++++++++++++++++++++++++- asoc/msm-pcm-routing-v2.h | 4 +- 2 files changed, 159 insertions(+), 5 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index d8d9f3eb6f44..7fd3589b6b07 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include @@ -109,6 +109,7 @@ enum { #define INT3_MI2S_TX_TEXT "INT3_MI2S_TX" #define VA_CDC_DMA_TX_0_TEXT "VA_CDC_DMA_TX_0" #define VA_CDC_DMA_TX_1_TEXT "VA_CDC_DMA_TX_1" +#define VA_CDC_DMA_TX_2_TEXT "VA_CDC_DMA_TX_2" #define TX_CDC_DMA_TX_3_TEXT "TX_CDC_DMA_TX_3" #define QUIN_TDM_TX_TEXT "QUIN_TDM_TX_0" @@ -119,7 +120,7 @@ static const char * const lsm_port_text[] = { SLIMBUS_3_TX_TEXT, SLIMBUS_4_TX_TEXT, SLIMBUS_5_TX_TEXT, TERT_MI2S_TX_TEXT, QUAT_MI2S_TX_TEXT, ADM_LSM_TX_TEXT, INT3_MI2S_TX_TEXT, VA_CDC_DMA_TX_0_TEXT, VA_CDC_DMA_TX_1_TEXT, - TX_CDC_DMA_TX_3_TEXT, QUIN_TDM_TX_TEXT + VA_CDC_DMA_TX_2_TEXT, TX_CDC_DMA_TX_3_TEXT, QUIN_TDM_TX_TEXT }; struct msm_pcm_route_bdai_pp_params { @@ -607,6 +608,8 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_VA_CDC_DMA_TX_0}, { AFE_PORT_ID_VA_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_VA_CDC_DMA_TX_1}, + { AFE_PORT_ID_VA_CODEC_DMA_TX_2, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_VA_CDC_DMA_TX_2}, { AFE_PORT_ID_RX_CODEC_DMA_RX_0, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_RX_CDC_DMA_RX_0}, { AFE_PORT_ID_TX_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0, @@ -2679,9 +2682,12 @@ static int msm_routing_lsm_port_put(struct snd_kcontrol *kcontrol, lsm_port = AFE_PORT_ID_VA_CODEC_DMA_TX_1; break; case 13: - lsm_port = AFE_PORT_ID_TX_CODEC_DMA_TX_3; + lsm_port = AFE_PORT_ID_VA_CODEC_DMA_TX_2; break; case 14: + lsm_port = AFE_PORT_ID_TX_CODEC_DMA_TX_3; + break; + case 15: lsm_port = AFE_PORT_ID_QUINARY_TDM_TX; break; default: @@ -3106,7 +3112,7 @@ static const char *const be_name[] = { "INT4_MI2S_RX", "INT4_MI2S_TX", "INT5_MI2S_RX", "INT5_MI2S_TX", "INT6_MI2S_RX", "INT6_MI2S_TX", "WSA_CDC_DMA_RX_0", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_RX_1", "WSA_CDC_DMA_TX_1", -"WSA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_1", +"WSA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_2", "RX_CDC_DMA_RX_0", "TX_CDC_DMA_TX_0", "RX_CDC_DMA_RX_1", "TX_CDC_DMA_TX_1", "RX_CDC_DMA_RX_2", "TX_CDC_DMA_TX_2", "RX_CDC_DMA_RX_3", "TX_CDC_DMA_TX_3", "RX_CDC_DMA_RX_4", "TX_CDC_DMA_TX_4", "RX_CDC_DMA_RX_5", "TX_CDC_DMA_TX_5", @@ -9531,6 +9537,10 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, @@ -9730,6 +9740,10 @@ static const struct snd_kcontrol_new mmul2_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, @@ -9929,6 +9943,10 @@ static const struct snd_kcontrol_new mmul3_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, @@ -10120,6 +10138,10 @@ static const struct snd_kcontrol_new mmul4_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, @@ -10335,6 +10357,10 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, @@ -10534,6 +10560,10 @@ static const struct snd_kcontrol_new mmul6_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, @@ -10733,6 +10763,10 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, @@ -10936,6 +10970,10 @@ static const struct snd_kcontrol_new mmul16_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, @@ -11085,6 +11123,10 @@ static const struct snd_kcontrol_new mmul9_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, @@ -11248,6 +11290,10 @@ static const struct snd_kcontrol_new mmul10_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, @@ -11356,6 +11402,10 @@ static const struct snd_kcontrol_new mmul17_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, @@ -11465,6 +11515,10 @@ static const struct snd_kcontrol_new mmul18_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, @@ -11570,6 +11624,10 @@ static const struct snd_kcontrol_new mmul19_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, @@ -11735,6 +11793,10 @@ static const struct snd_kcontrol_new mmul20_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, @@ -11882,6 +11944,10 @@ static const struct snd_kcontrol_new mmul21_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, @@ -12032,6 +12098,10 @@ static const struct snd_kcontrol_new mmul28_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, @@ -12137,6 +12207,10 @@ static const struct snd_kcontrol_new mmul29_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, @@ -13079,6 +13153,9 @@ MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -13156,6 +13233,9 @@ static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -13247,6 +13327,9 @@ static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_Voip", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_Voip", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -13352,6 +13435,10 @@ static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, @@ -13447,6 +13534,10 @@ static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, @@ -13542,6 +13633,10 @@ static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, @@ -13639,6 +13734,9 @@ static const struct snd_kcontrol_new tx_qchat_mixer_controls[] = { SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_QCHAT", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_QCHAT", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -16444,6 +16542,10 @@ static const struct snd_kcontrol_new lsm1_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, @@ -16496,6 +16598,10 @@ static const struct snd_kcontrol_new lsm2_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, @@ -16547,6 +16653,10 @@ static const struct snd_kcontrol_new lsm3_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, @@ -16598,6 +16708,10 @@ static const struct snd_kcontrol_new lsm4_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, @@ -16649,6 +16763,10 @@ static const struct snd_kcontrol_new lsm5_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, @@ -16700,6 +16818,10 @@ static const struct snd_kcontrol_new lsm6_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, @@ -16751,6 +16873,10 @@ static const struct snd_kcontrol_new lsm7_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, @@ -16802,6 +16928,10 @@ static const struct snd_kcontrol_new lsm8_mixer_controls[] = { MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, @@ -18919,6 +19049,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("VA_CDC_DMA_TX_1", "VA CDC DMA1 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VA_CDC_DMA_TX_2", "VA CDC DMA2 Capture", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("RX_CDC_DMA_RX_0", "RX CDC DMA0 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("TX_CDC_DMA_TX_0", "TX CDC DMA0 Capture", @@ -20906,6 +21038,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, @@ -20941,6 +21074,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, @@ -20976,6 +21110,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, @@ -21011,6 +21146,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, @@ -21046,6 +21182,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, @@ -21081,6 +21218,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, @@ -21116,6 +21254,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, @@ -21142,6 +21281,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, @@ -21198,6 +21338,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, @@ -21235,6 +21376,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, @@ -21288,6 +21430,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, @@ -21954,6 +22097,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM1 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"LSM1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM1 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"LSM1 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM1 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"LSM1_UL_HL", NULL, "LSM1 Mixer"}, @@ -21968,6 +22112,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM2 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"LSM2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM2 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"LSM2 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM2 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"LSM2_UL_HL", NULL, "LSM2 Mixer"}, @@ -21983,6 +22128,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"LSM3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM3 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"LSM3 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM3 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"LSM3_UL_HL", NULL, "LSM3 Mixer"}, @@ -21998,6 +22144,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM4 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"LSM4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM4 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"LSM4 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM4 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"LSM4_UL_HL", NULL, "LSM4 Mixer"}, @@ -22012,6 +22159,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"LSM5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM5 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"LSM5 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM5 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"LSM5_UL_HL", NULL, "LSM5 Mixer"}, @@ -22024,6 +22172,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"LSM6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM6 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"LSM6 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM6 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"LSM6_UL_HL", NULL, "LSM6 Mixer"}, @@ -22036,6 +22185,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM7 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"LSM7 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM7 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM7 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"LSM7 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM7 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"LSM7_UL_HL", NULL, "LSM7 Mixer"}, @@ -22048,6 +22198,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM8 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"LSM8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"LSM8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM8 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"LSM8 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM8 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"LSM8_UL_HL", NULL, "LSM8 Mixer"}, @@ -23029,6 +23180,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"WSA_CDC_DMA_TX_2", NULL, "BE_IN"}, {"VA_CDC_DMA_TX_0", NULL, "BE_IN"}, {"VA_CDC_DMA_TX_1", NULL, "BE_IN"}, + {"VA_CDC_DMA_TX_2", NULL, "BE_IN"}, {"TX_CDC_DMA_TX_0", NULL, "BE_IN"}, {"TX_CDC_DMA_TX_1", NULL, "BE_IN"}, {"TX_CDC_DMA_TX_2", NULL, "BE_IN"}, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 1691b365dfa2..9b663fffd822 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #ifndef _MSM_PCM_ROUTING_H #define _MSM_PCM_ROUTING_H @@ -194,6 +194,7 @@ #define LPASS_BE_WSA_CDC_DMA_TX_2 "WSA_CDC_DMA_TX_2" #define LPASS_BE_VA_CDC_DMA_TX_0 "VA_CDC_DMA_TX_0" #define LPASS_BE_VA_CDC_DMA_TX_1 "VA_CDC_DMA_TX_1" +#define LPASS_BE_VA_CDC_DMA_TX_2 "VA_CDC_DMA_TX_2" #define LPASS_BE_RX_CDC_DMA_RX_0 "RX_CDC_DMA_RX_0" #define LPASS_BE_RX_CDC_DMA_RX_1 "RX_CDC_DMA_RX_1" @@ -437,6 +438,7 @@ enum { MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, -- GitLab From 2228bf0b292b304caac0a973e5cc9e1d753a160a Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Wed, 12 Dec 2018 15:47:20 -0800 Subject: [PATCH 0756/1645] ASoC: msm: add VA Macro's BE DAI links for bolero Add BE DAI links of VA macro for bolero in Kona's machine driver. Change-Id: I230bf7227c5436b5a2e8fed956337f87fcc86a4e Signed-off-by: Xiaoyu Ye --- asoc/kona.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 128 insertions(+), 3 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index a312e6eac090..5e8ce6e5ce01 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ #include @@ -113,6 +113,9 @@ enum { TX_CDC_DMA_TX_0, TX_CDC_DMA_TX_3, TX_CDC_DMA_TX_4, + VA_CDC_DMA_TX_0, + VA_CDC_DMA_TX_1, + VA_CDC_DMA_TX_2, CDC_DMA_TX_MAX, }; @@ -321,6 +324,9 @@ static struct dev_config cdc_dma_tx_cfg[] = { [TX_CDC_DMA_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, [TX_CDC_DMA_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, [TX_CDC_DMA_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [VA_CDC_DMA_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, + [VA_CDC_DMA_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, + [VA_CDC_DMA_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, }; static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", @@ -408,6 +414,9 @@ static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_2_chs, cdc_dma_tx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_0_chs, cdc_dma_tx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_3_chs, cdc_dma_tx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_0_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_1_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_2_chs, cdc_dma_tx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_format, bit_format_text); @@ -420,6 +429,9 @@ static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_2_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_0_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_3_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_0_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_1_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_2_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_sample_rate, cdc_dma_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_sample_rate, @@ -446,6 +458,12 @@ static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_3_sample_rate, cdc_dma_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_sample_rate, cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_1_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_2_sample_rate, + cdc_dma_sample_rate_text); static bool is_initial_boot; static bool codec_reg_done; @@ -2003,6 +2021,15 @@ static int cdc_dma_get_port_idx(struct snd_kcontrol *kcontrol) else if (strnstr(kcontrol->id.name, "TX_CDC_DMA_TX_4", sizeof("TX_CDC_DMA_TX_4"))) idx = TX_CDC_DMA_TX_4; + else if (strnstr(kcontrol->id.name, "VA_CDC_DMA_TX_0", + sizeof("VA_CDC_DMA_TX_0"))) + idx = VA_CDC_DMA_TX_0; + else if (strnstr(kcontrol->id.name, "VA_CDC_DMA_TX_1", + sizeof("VA_CDC_DMA_TX_1"))) + idx = VA_CDC_DMA_TX_1; + else if (strnstr(kcontrol->id.name, "VA_CDC_DMA_TX_2", + sizeof("VA_CDC_DMA_TX_2"))) + idx = VA_CDC_DMA_TX_2; else { pr_err("%s: unsupported channel: %s\n", __func__, kcontrol->id.name); @@ -2516,6 +2543,15 @@ static int msm_cdc_dma_get_idx_from_beid(int32_t be_id) case MSM_BACKEND_DAI_TX_CDC_DMA_TX_4: idx = TX_CDC_DMA_TX_4; break; + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: + idx = VA_CDC_DMA_TX_0; + break; + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: + idx = VA_CDC_DMA_TX_1; + break; + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2: + idx = VA_CDC_DMA_TX_2; + break; default: idx = RX_CDC_DMA_RX_0; break; @@ -2551,6 +2587,12 @@ static const struct snd_kcontrol_new msm_int_snd_controls[] = { cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), SOC_ENUM_EXT("TX_CDC_DMA_TX_4 Channels", tx_cdc_dma_tx_4_chs, cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_0 Channels", va_cdc_dma_tx_0_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_1 Channels", va_cdc_dma_tx_1_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_2 Channels", va_cdc_dma_tx_2_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), SOC_ENUM_EXT("WSA_CDC_DMA_RX_0 Format", wsa_cdc_dma_rx_0_format, cdc_dma_rx_format_get, cdc_dma_rx_format_put), SOC_ENUM_EXT("WSA_CDC_DMA_RX_1 Format", wsa_cdc_dma_rx_1_format, @@ -2575,6 +2617,12 @@ static const struct snd_kcontrol_new msm_int_snd_controls[] = { cdc_dma_tx_format_get, cdc_dma_tx_format_put), SOC_ENUM_EXT("TX_CDC_DMA_TX_4 Format", tx_cdc_dma_tx_4_format, cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_0 Format", va_cdc_dma_tx_0_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_1 Format", va_cdc_dma_tx_1_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_2 Format", va_cdc_dma_tx_2_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), SOC_ENUM_EXT("WSA_CDC_DMA_RX_0 SampleRate", wsa_cdc_dma_rx_0_sample_rate, cdc_dma_rx_sample_rate_get, @@ -2627,6 +2675,18 @@ static const struct snd_kcontrol_new msm_int_snd_controls[] = { tx_cdc_dma_tx_4_sample_rate, cdc_dma_tx_sample_rate_get, cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_0 SampleRate", + va_cdc_dma_tx_0_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_1 SampleRate", + va_cdc_dma_tx_1_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_2 SampleRate", + va_cdc_dma_tx_2_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), }; static const struct snd_kcontrol_new msm_common_snd_controls[] = { @@ -2795,7 +2855,7 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - int rc = 0; + int idx, rc = 0; pr_debug("%s: format = %d, rate = %d\n", __func__, params_format(params), params_rate(params)); @@ -2969,6 +3029,16 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, mi2s_tx_cfg[TERT_MI2S].channels; break; + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2: + idx = msm_cdc_dma_get_idx_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + cdc_dma_tx_cfg[idx].bit_format); + rate->min = rate->max = cdc_dma_tx_cfg[idx].sample_rate; + channels->min = channels->max = cdc_dma_tx_cfg[idx].channels; + break; + default: rate->min = rate->max = SAMPLING_RATE_8KHZ; break; @@ -3143,6 +3213,9 @@ static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream, case MSM_BACKEND_DAI_TX_CDC_DMA_TX_0: case MSM_BACKEND_DAI_TX_CDC_DMA_TX_3: case MSM_BACKEND_DAI_TX_CDC_DMA_TX_4: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2: { ch_id = msm_cdc_dma_get_idx_from_beid(dai_link->id); pr_debug("%s: id %d tx_ch=%d\n", __func__, @@ -4585,6 +4658,51 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { }, }; +static struct snd_soc_dai_link msm_va_cdc_dma_be_dai_links[] = { + { + .name = LPASS_BE_VA_CDC_DMA_TX_0, + .stream_name = "VA CDC DMA0 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45089", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "va_macro_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_VA_CDC_DMA_TX_1, + .stream_name = "VA CDC DMA1 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45091", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "va_macro_tx2", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_VA_CDC_DMA_TX_2, + .stream_name = "VA CDC DMA2 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45093", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "va_macro_tx3", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, +}; + static struct snd_soc_dai_link msm_kona_dai_links[ ARRAY_SIZE(msm_common_dai_links) + ARRAY_SIZE(msm_bolero_fe_dai_links) + @@ -4593,7 +4711,8 @@ static struct snd_soc_dai_link msm_kona_dai_links[ ARRAY_SIZE(msm_mi2s_be_dai_links) + ARRAY_SIZE(msm_auxpcm_be_dai_links) + ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links) + - ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links)]; + ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links) + + ARRAY_SIZE(msm_va_cdc_dma_be_dai_links)]; static int msm_populate_dai_link_component_of_node( struct snd_soc_card *card) @@ -4840,6 +4959,12 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) total_links += ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links); + memcpy(msm_kona_dai_links + total_links, + msm_va_cdc_dma_be_dai_links, + sizeof(msm_va_cdc_dma_be_dai_links)); + total_links += + ARRAY_SIZE(msm_va_cdc_dma_be_dai_links); + rc = of_property_read_u32(dev->of_node, "qcom,mi2s-audio-intf", &mi2s_audio_intf); if (rc) { -- GitLab From 5efecda1cb0b2d2369842f408d7165525975fe9f Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Wed, 19 Dec 2018 20:09:31 -0800 Subject: [PATCH 0757/1645] asoc: bolero: add support to enable VA macro BE DAI on Kona VA HW macro supports three BE DAIs on Kona. Add support to enable the third one. Change-Id: I418a6a0bb1bcbc06fe71de0977d974432e1d6c22 Signed-off-by: Xiaoyu Ye --- asoc/codecs/bolero/va-macro.c | 55 ++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index db078e2a6cdf..2d2bc3b534a9 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -52,6 +52,7 @@ enum { VA_MACRO_AIF_INVALID = 0, VA_MACRO_AIF1_CAP, VA_MACRO_AIF2_CAP, + VA_MACRO_AIF3_CAP, VA_MACRO_MAX_DAIS, }; @@ -803,6 +804,7 @@ static int va_macro_get_channel_map(struct snd_soc_dai *dai, switch (dai->id) { case VA_MACRO_AIF1_CAP: case VA_MACRO_AIF2_CAP: + case VA_MACRO_AIF3_CAP: *tx_slot = va_priv->active_ch_mask[dai->id]; *tx_num = va_priv->active_ch_cnt[dai->id]; break; @@ -847,6 +849,20 @@ static struct snd_soc_dai_driver va_macro_dai[] = { }, .ops = &va_macro_dai_ops, }, + { + .name = "va_macro_tx3", + .id = VA_MACRO_AIF3_CAP, + .capture = { + .stream_name = "VA_AIF3 Capture", + .rates = VA_MACRO_RATES, + .formats = VA_MACRO_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &va_macro_dai_ops, + }, }; #define STRING(name) #name @@ -997,6 +1013,25 @@ static const struct snd_kcontrol_new va_aif2_cap_mixer[] = { va_macro_tx_mixer_get, va_macro_tx_mixer_put), }; +static const struct snd_kcontrol_new va_aif3_cap_mixer[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, VA_MACRO_DEC2, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, VA_MACRO_DEC3, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, VA_MACRO_DEC4, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, VA_MACRO_DEC5, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, VA_MACRO_DEC6, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, VA_MACRO_DEC7, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), +}; + static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("VA_AIF1 CAP", "VA_AIF1 Capture", 0, SND_SOC_NOPM, VA_MACRO_AIF1_CAP, 0), @@ -1004,6 +1039,9 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("VA_AIF2 CAP", "VA_AIF2 Capture", 0, SND_SOC_NOPM, VA_MACRO_AIF2_CAP, 0), + SND_SOC_DAPM_AIF_OUT("VA_AIF3 CAP", "VA_AIF3 Capture", 0, + SND_SOC_NOPM, VA_MACRO_AIF3_CAP, 0), + SND_SOC_DAPM_MIXER("VA_AIF1_CAP Mixer", SND_SOC_NOPM, VA_MACRO_AIF1_CAP, 0, va_aif1_cap_mixer, ARRAY_SIZE(va_aif1_cap_mixer)), @@ -1012,6 +1050,9 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = { VA_MACRO_AIF2_CAP, 0, va_aif2_cap_mixer, ARRAY_SIZE(va_aif2_cap_mixer)), + SND_SOC_DAPM_MIXER("VA_AIF3_CAP Mixer", SND_SOC_NOPM, + VA_MACRO_AIF3_CAP, 0, + va_aif3_cap_mixer, ARRAY_SIZE(va_aif3_cap_mixer)), VA_MACRO_DAPM_MUX("VA DMIC MUX0", 0, va_dmic0), VA_MACRO_DAPM_MUX("VA DMIC MUX1", 0, va_dmic1), @@ -1134,9 +1175,11 @@ static const struct snd_soc_dapm_widget va_macro_wod_dapm_widgets[] = { static const struct snd_soc_dapm_route va_audio_map[] = { {"VA_AIF1 CAP", NULL, "VA_MCLK"}, {"VA_AIF2 CAP", NULL, "VA_MCLK"}, + {"VA_AIF3 CAP", NULL, "VA_MCLK"}, {"VA_AIF1 CAP", NULL, "VA_AIF1_CAP Mixer"}, {"VA_AIF2 CAP", NULL, "VA_AIF2_CAP Mixer"}, + {"VA_AIF3 CAP", NULL, "VA_AIF3_CAP Mixer"}, {"VA_AIF1_CAP Mixer", "DEC0", "VA DEC0 MUX"}, {"VA_AIF1_CAP Mixer", "DEC1", "VA DEC1 MUX"}, @@ -1156,6 +1199,15 @@ static const struct snd_soc_dapm_route va_audio_map[] = { {"VA_AIF2_CAP Mixer", "DEC6", "VA DEC6 MUX"}, {"VA_AIF2_CAP Mixer", "DEC7", "VA DEC7 MUX"}, + {"VA_AIF3_CAP Mixer", "DEC0", "VA DEC0 MUX"}, + {"VA_AIF3_CAP Mixer", "DEC1", "VA DEC1 MUX"}, + {"VA_AIF3_CAP Mixer", "DEC2", "VA DEC2 MUX"}, + {"VA_AIF3_CAP Mixer", "DEC3", "VA DEC3 MUX"}, + {"VA_AIF3_CAP Mixer", "DEC4", "VA DEC4 MUX"}, + {"VA_AIF3_CAP Mixer", "DEC5", "VA DEC5 MUX"}, + {"VA_AIF3_CAP Mixer", "DEC6", "VA DEC6 MUX"}, + {"VA_AIF3_CAP Mixer", "DEC7", "VA DEC7 MUX"}, + {"VA DEC0 MUX", "MSM_DMIC", "VA DMIC MUX0"}, {"VA DMIC MUX0", "DMIC0", "VA DMIC0"}, {"VA DMIC MUX0", "DMIC1", "VA DMIC1"}, @@ -1488,6 +1540,7 @@ static int va_macro_init(struct snd_soc_component *component) snd_soc_dapm_ignore_suspend(dapm, "VA_AIF1 Capture"); snd_soc_dapm_ignore_suspend(dapm, "VA_AIF2 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "VA_AIF3 Capture"); snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC0"); snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC1"); snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC2"); -- GitLab From a2958a62057ac0b96a186c9036eb026aae6bd1cb Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 12 Dec 2018 19:24:33 +0530 Subject: [PATCH 0758/1645] asoc: wcd937x: stop mbhc during ssr down Stop mbhc operations during ssr down to cancel any pending detection sequences. Change-Id: I6aa8c61c2cc74fc08adf57c58673acaa753ac322 Signed-off-by: Ramprasad Katkam --- asoc/codecs/wcd937x/wcd937x-mbhc.c | 29 ++++++++++++++++++++++++++--- asoc/codecs/wcd937x/wcd937x-mbhc.h | 10 ++++++++-- asoc/codecs/wcd937x/wcd937x.c | 4 +++- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index 54d9f4595402..4ad8683a490c 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -974,6 +974,31 @@ void wcd937x_mbhc_hs_detect_exit(struct snd_soc_component *component) } EXPORT_SYMBOL(wcd937x_mbhc_hs_detect_exit); +/* + * wcd937x_mbhc_ssr_down: stop mbhc during + * wcd937x subsystem restart + * @mbhc: pointer to wcd937x_mbhc structure + * @component: handle to snd_soc_component * + */ +void wcd937x_mbhc_ssr_down(struct wcd937x_mbhc *mbhc, + struct snd_soc_component *component) +{ + struct wcd_mbhc *wcd_mbhc = NULL; + + if (!mbhc || !component) + return; + + wcd_mbhc = &mbhc->wcd_mbhc; + if (wcd_mbhc == NULL) { + dev_err(component->dev, "%s: wcd_mbhc is NULL\n", __func__); + return; + } + + wcd937x_mbhc_hs_detect_exit(component); + wcd_mbhc_deinit(wcd_mbhc); +} +EXPORT_SYMBOL(wcd937x_mbhc_ssr_down); + /* * wcd937x_mbhc_post_ssr_init: initialize mbhc for * wcd937x post subsystem restart @@ -997,8 +1022,6 @@ int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc, return -EINVAL; } - wcd937x_mbhc_hs_detect_exit(component); - wcd_mbhc_deinit(wcd_mbhc); snd_soc_component_update_bits(component, WCD937X_ANA_MBHC_MECH, 0x20, 0x20); ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb, &intr_ids, diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.h b/asoc/codecs/wcd937x/wcd937x-mbhc.h index 3c7495165996..43d16618956f 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.h +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #ifndef __WCD937X_MBHC_H__ #define __WCD937X_MBHC_H__ @@ -21,6 +21,8 @@ extern int wcd937x_mbhc_hs_detect(struct snd_soc_component *component, extern void wcd937x_mbhc_deinit(struct snd_soc_component *component); extern int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc, struct snd_soc_component *component); +extern void wcd937x_mbhc_ssr_down(struct wcd937x_mbhc *mbhc, + struct snd_soc_component *component); extern int wcd937x_mbhc_get_impedance(struct wcd937x_mbhc *wcd937x_mbhc, uint32_t *zl, uint32_t *zr); #else @@ -47,7 +49,11 @@ static inline int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc, { return 0; } - +static inline void wcd937x_mbhc_ssr_down(struct wcd937x_mbhc *mbhc, + struct snd_soc_component *component) +{ + return 0; +} static inline int wcd937x_mbhc_get_impedance(struct wcd937x_mbhc *wcd937x_mbhc, uint32_t *zl, uint32_t *zr) { diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 004ce796c98a..24b74c8ba4da 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -1422,6 +1422,8 @@ static int wcd937x_event_notify(struct notifier_block *block, 0x80, 0x00); break; case BOLERO_WCD_EVT_SSR_DOWN: + mbhc = &wcd937x->mbhc->wcd_mbhc; + wcd937x_mbhc_ssr_down(wcd937x->mbhc, component); wcd937x_reset_low(wcd937x->dev); break; case BOLERO_WCD_EVT_SSR_UP: -- GitLab From 8341eefc48b8abb227b3301f1c79b9415ac79bbd Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Thu, 3 Jan 2019 14:57:47 -0800 Subject: [PATCH 0759/1645] dsp: afe: add support for VA macro codec DMA interface VA macro on Kona has three TX codec DMA interface. The current AFE driver only supports two codec DMA interface. Add support to enable the third one in AFE driver. Change-Id: Ie0f6241ef37bc03ad9adb1c4fe82f82468caec25 Signed-off-by: Xiaoyu Ye --- dsp/q6afe.c | 8 +++++++- dsp/q6audio-v2.c | 8 +++++++- include/dsp/q6afe-v2.h | 11 ++++++----- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index f36f06f2e61e..32a3cf3e8b34 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -813,6 +813,7 @@ int afe_sizeof_cfg_cmd(u16 port_id) case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: case AFE_PORT_ID_VA_CODEC_DMA_TX_0: case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + case AFE_PORT_ID_VA_CODEC_DMA_TX_2: case AFE_PORT_ID_RX_CODEC_DMA_RX_0: case AFE_PORT_ID_TX_CODEC_DMA_TX_0: case AFE_PORT_ID_RX_CODEC_DMA_RX_1: @@ -4179,6 +4180,7 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: case AFE_PORT_ID_VA_CODEC_DMA_TX_0: case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + case AFE_PORT_ID_VA_CODEC_DMA_TX_2: case AFE_PORT_ID_RX_CODEC_DMA_RX_0: case AFE_PORT_ID_TX_CODEC_DMA_TX_0: case AFE_PORT_ID_RX_CODEC_DMA_RX_1: @@ -4629,6 +4631,8 @@ int afe_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_0; case AFE_PORT_ID_VA_CODEC_DMA_TX_1: return IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_1; + case AFE_PORT_ID_VA_CODEC_DMA_TX_2: + return IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_2; case AFE_PORT_ID_WSA_CODEC_DMA_RX_0: return IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_0; case AFE_PORT_ID_WSA_CODEC_DMA_TX_0: @@ -4827,6 +4831,7 @@ int afe_open(u16 port_id, case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: case AFE_PORT_ID_VA_CODEC_DMA_TX_0: case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + case AFE_PORT_ID_VA_CODEC_DMA_TX_2: case AFE_PORT_ID_RX_CODEC_DMA_RX_0: case AFE_PORT_ID_TX_CODEC_DMA_TX_0: case AFE_PORT_ID_RX_CODEC_DMA_RX_1: @@ -6802,6 +6807,7 @@ int afe_validate_port(u16 port_id) case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: case AFE_PORT_ID_VA_CODEC_DMA_TX_0: case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + case AFE_PORT_ID_VA_CODEC_DMA_TX_2: case AFE_PORT_ID_RX_CODEC_DMA_RX_0: case AFE_PORT_ID_TX_CODEC_DMA_TX_0: case AFE_PORT_ID_RX_CODEC_DMA_RX_1: diff --git a/dsp/q6audio-v2.c b/dsp/q6audio-v2.c index 29a99feb5ee9..f0b031cf0166 100644 --- a/dsp/q6audio-v2.c +++ b/dsp/q6audio-v2.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include @@ -317,6 +317,8 @@ int q6audio_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_0; case AFE_PORT_ID_VA_CODEC_DMA_TX_1: return IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_1; + case AFE_PORT_ID_VA_CODEC_DMA_TX_2: + return IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_2; case AFE_PORT_ID_RX_CODEC_DMA_RX_0: return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_0; case AFE_PORT_ID_TX_CODEC_DMA_TX_0: @@ -659,6 +661,8 @@ int q6audio_get_port_id(u16 port_id) return AFE_PORT_ID_VA_CODEC_DMA_TX_0; case AFE_PORT_ID_VA_CODEC_DMA_TX_1: return AFE_PORT_ID_VA_CODEC_DMA_TX_1; + case AFE_PORT_ID_VA_CODEC_DMA_TX_2: + return AFE_PORT_ID_VA_CODEC_DMA_TX_2; case AFE_PORT_ID_RX_CODEC_DMA_RX_0: return AFE_PORT_ID_RX_CODEC_DMA_RX_0; case AFE_PORT_ID_TX_CODEC_DMA_TX_0: @@ -850,6 +854,7 @@ int q6audio_is_digital_pcm_interface(u16 port_id) case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: case AFE_PORT_ID_VA_CODEC_DMA_TX_0: case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + case AFE_PORT_ID_VA_CODEC_DMA_TX_2: case AFE_PORT_ID_RX_CODEC_DMA_RX_0: case AFE_PORT_ID_TX_CODEC_DMA_TX_0: case AFE_PORT_ID_RX_CODEC_DMA_RX_1: @@ -1062,6 +1067,7 @@ int q6audio_validate_port(u16 port_id) case AFE_PORT_ID_WSA_CODEC_DMA_TX_2: case AFE_PORT_ID_VA_CODEC_DMA_TX_0: case AFE_PORT_ID_VA_CODEC_DMA_TX_1: + case AFE_PORT_ID_VA_CODEC_DMA_TX_2: case AFE_PORT_ID_RX_CODEC_DMA_RX_0: case AFE_PORT_ID_TX_CODEC_DMA_TX_0: case AFE_PORT_ID_RX_CODEC_DMA_RX_1: diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 9e7222f61301..158c3e99ce2e 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #ifndef __Q6AFE_V2_H__ #define __Q6AFE_V2_H__ @@ -226,7 +226,7 @@ enum { IDX_AFE_PORT_ID_QUINARY_TDM_TX_6, IDX_AFE_PORT_ID_QUINARY_TDM_RX_7, IDX_AFE_PORT_ID_QUINARY_TDM_TX_7, - /* IDX 161 to 181 */ + /* IDX 161 to 182 */ IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_0, IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_0, IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_1, @@ -234,6 +234,7 @@ enum { IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_2, IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_0, IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_1, + IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_2, IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_0, IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_0, IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_1, @@ -248,14 +249,14 @@ enum { IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_5, IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_6, IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_7, - /* IDX 182 to 184 */ + /* IDX 183 to 185 */ IDX_SECONDARY_SPDIF_RX, IDX_PRIMARY_SPDIF_TX, IDX_SECONDARY_SPDIF_TX, - /* IDX 185 to 186 */ + /* IDX 186 to 187 */ IDX_SLIMBUS_9_RX, IDX_SLIMBUS_9_TX, - /* IDX 187 -> 189 */ + /* IDX 188 -> 190 */ IDX_AFE_PORT_ID_SENARY_PCM_RX, IDX_AFE_PORT_ID_SENARY_PCM_TX, IDX_AFE_LOOPBACK_TX, -- GitLab From c87efeb82b65877fac36945075a88765cdf7bbcb Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 12 Dec 2018 19:26:19 +0530 Subject: [PATCH 0760/1645] soc: swr-mstr: Change timeout for clk disable during ssr MBHC operations may take around 200ms to get stopped during ssr. Match timeout for clock voting to be zero to allow any pending mbhc operation to exited. Change-Id: I82162e96595fb337f19192f58f1aa7792e8b0e90 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index ddf04ab4c2d3..dd9a5b4f1ff9 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2284,7 +2284,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) reinit_completion(&swrm->clk_off_complete); if (swrm->clk_ref_count && !wait_for_completion_timeout(&swrm->clk_off_complete, - msecs_to_jiffies(200))) + msecs_to_jiffies(500))) dev_err(swrm->dev, "%s: clock voting not zero\n", __func__); -- GitLab From 5eb13428f14bcd8b12fda6d4ee3ea4cdd3856793 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 5 Nov 2018 13:49:17 -0800 Subject: [PATCH 0761/1645] asoc: msm: add fsa switch functionality for kona Add fsa USB type C analog audio functionality and update codec function calls from machine driver. Change-Id: I493241d633d1f233930c714de08ad6ce8ece5b83 Signed-off-by: Karthikeyan Mani --- asoc/kona.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 127 insertions(+), 3 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index 5e8ce6e5ce01..802d2a65a9fa 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -28,7 +29,9 @@ #include "msm-pcm-routing-v2.h" #include "asoc/msm-cdc-pinctrl.h" #include "asoc/wcd-mbhc-v2.h" +#include "codecs/wcd938x/wcd938x-mbhc.h" #include "codecs/wsa881x.h" +#include "codecs/wcd938x/wcd938x.h" #include "codecs/bolero/bolero-cdc.h" #include #include "codecs/bolero/wsa-macro.h" @@ -52,6 +55,13 @@ #define SAMPLING_RATE_352P8KHZ 352800 #define SAMPLING_RATE_384KHZ 384000 +#define WCD9XXX_MBHC_DEF_RLOADS 5 +#define WCD9XXX_MBHC_DEF_BUTTONS 8 +#define CODEC_EXT_CLK_RATE 9600000 +#define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define DEV_NAME_STR_LEN 32 +#define WCD_MBHC_HS_V_MAX 1600 + #define TDM_CHANNEL_MAX 8 #define DEV_NAME_STR_LEN 32 @@ -130,6 +140,7 @@ struct msm_asoc_mach_data { struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ bool is_afe_config_done; + struct device_node *fsa_handle; }; struct tdm_port { @@ -475,6 +486,8 @@ static int dmic_2_3_gpio_cnt; static int dmic_4_5_gpio_cnt; static int msm_vi_feed_tx_ch = 2; +static void *def_wcd_mbhc_cal(void); + /* * Need to report LINEIN * if R/L channel impedance is larger than 5K ohm @@ -3047,6 +3060,56 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return rc; } +static bool msm_usbc_swap_gnd_mic(struct snd_soc_component *component, bool active) +{ + struct snd_soc_card *card = component->card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + + if (!pdata->fsa_handle) + return false; + + return fsa4480_switch_event(pdata->fsa_handle, FSA_MIC_GND_SWAP); +} + +static bool msm_swap_gnd_mic(struct snd_soc_component *component, bool active) +{ + int value = 0; + bool ret = false; + struct snd_soc_card *card; + struct msm_asoc_mach_data *pdata; + + if (!component) { + pr_err("%s component is NULL\n", __func__); + return false; + } + card = component->card; + pdata = snd_soc_card_get_drvdata(card); + + if (!pdata) + return false; + + if (wcd_mbhc_cfg.enable_usbc_analog) + return msm_usbc_swap_gnd_mic(component, active); + + /* if usbc is not defined, swap using us_euro_gpio_p */ + if (pdata->us_euro_gpio_p) { + value = msm_cdc_pinctrl_get_state( + pdata->us_euro_gpio_p); + if (value) + msm_cdc_pinctrl_select_sleep_state( + pdata->us_euro_gpio_p); + else + msm_cdc_pinctrl_select_active_state( + pdata->us_euro_gpio_p); + dev_dbg(component->dev, "%s: swap select switch %d to %d\n", + __func__, value, !value); + ret = true; + } + + return ret; +} + static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -3549,6 +3612,35 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) return ret; } +static void *def_wcd_mbhc_cal(void) +{ + void *wcd_mbhc_cal; + struct wcd_mbhc_btn_detect_cfg *btn_cfg; + u16 *btn_high; + + wcd_mbhc_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, + WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); + if (!wcd_mbhc_cal) + return NULL; + + WCD_MBHC_CAL_PLUG_TYPE_PTR(wcd_mbhc_cal)->v_hs_max = WCD_MBHC_HS_V_MAX; + WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal)->num_btn = WCD_MBHC_DEF_BUTTONS; + btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal); + btn_high = ((void *)&btn_cfg->_v_btn_low) + + (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); + + btn_high[0] = 75; + btn_high[1] = 150; + btn_high[2] = 237; + btn_high[3] = 500; + btn_high[4] = 500; + btn_high[5] = 500; + btn_high[6] = 500; + btn_high[7] = 500; + + return wcd_mbhc_cal; +} + /* Digital audio interface glue - connects codec <---> CPU */ static struct snd_soc_dai_link msm_common_dai_links[] = { /* FrontEnd DAI Links */ @@ -5093,6 +5185,7 @@ static int msm_aux_codec_init(struct snd_soc_component *component) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); int ret = 0; + void *mbhc_calibration; struct snd_info_entry *entry; struct snd_card *card = component->card->snd_card; struct msm_asoc_mach_data *pdata; @@ -5112,14 +5205,30 @@ static int msm_aux_codec_init(struct snd_soc_component *component) entry = snd_info_create_subdir(card->module, "codecs", card->proc_root); if (!entry) { - pr_err("%s: Cannot create codecs module entry\n", + dev_dbg(component->dev, "%s: Cannot create codecs module entry\n", __func__); ret = 0; - goto codec_root_err; + goto mbhc_cfg_cal; } pdata->codec_root = entry; } -codec_root_err: + wcd938x_info_create_codec_entry(pdata->codec_root, component); + +mbhc_cfg_cal: + mbhc_calibration = def_wcd_mbhc_cal(); + if (!mbhc_calibration) + return -ENOMEM; + wcd_mbhc_cfg.calibration = mbhc_calibration; + ret = wcd938x_mbhc_hs_detect(component, &wcd_mbhc_cfg); + if (ret) { + dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n", + __func__, ret); + goto err_hs_detect; + } + return 0; + +err_hs_detect: + kfree(mbhc_calibration); return ret; } @@ -5609,6 +5718,21 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "Unknown value, set to default\n"); } } + /* + * Parse US-Euro gpio info from DT. Report no error if us-euro + * entry is not found in DT file as some targets do not support + * US-Euro detection + */ + pdata->us_euro_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,us-euro-gpios", 0); + if (!pdata->us_euro_gpio_p) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,us-euro-gpios", pdev->dev.of_node->full_name); + } else { + dev_dbg(&pdev->dev, "%s detected\n", + "qcom,us-euro-gpios"); + wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; + } msm_i2s_auxpcm_init(pdev); if (strcmp(card->name, "kona-mtp-snd-card")) { -- GitLab From eaad2ede41a57e121114ef5c8a91d3dbfd93246f Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 26 Dec 2018 11:47:26 -0800 Subject: [PATCH 0762/1645] ASoC: msm: add external sound device dai's for kona Add BT and external display dai's and ops for kona. Change-Id: Ib2c2a5c5342de657f7c4b8ef04eed88242baa101 Signed-off-by: Karthikeyan Mani --- asoc/kona.c | 412 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 411 insertions(+), 1 deletion(-) diff --git a/asoc/kona.c b/asoc/kona.c index 802d2a65a9fa..bcc17736475f 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -71,6 +71,8 @@ #define WSA8810_NAME_1 "wsa881x.20170211" #define WSA8810_NAME_2 "wsa881x.20170212" +#define WCN_CDC_SLIM_RX_CH_MAX 2 +#define WCN_CDC_SLIM_TX_CH_MAX 2 enum { TDM_0 = 0, @@ -148,6 +150,11 @@ struct tdm_port { u32 channel; }; +enum { + EXT_DISP_RX_IDX_DP = 0, + EXT_DISP_RX_IDX_MAX, +}; + struct msm_wsa881x_dev_info { struct device_node *of_node; u32 index; @@ -164,6 +171,11 @@ struct dev_config { u32 channels; }; +/* Default configuration of external display BE */ +static struct dev_config ext_disp_rx_cfg[] = { + [EXT_DISP_RX_IDX_DP] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + static struct dev_config usb_rx_cfg = { .sample_rate = SAMPLING_RATE_48KHZ, .bit_format = SNDRV_PCM_FORMAT_S16_LE, @@ -376,6 +388,11 @@ static char const *cdc_dma_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_88P2", "KHZ_96", "KHZ_176P4", "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE", + "S24_3LE"}; +static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_32", "KHZ_44P1", + "KHZ_88P2", "KHZ_176P4"}; static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); @@ -475,6 +492,10 @@ static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_1_sample_rate, cdc_dma_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_2_sample_rate, cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, + ext_disp_sample_rate_text); static bool is_initial_boot; static bool codec_reg_done; @@ -898,6 +919,195 @@ static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, return 1; } +static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx = 0; + + if (strnstr(kcontrol->id.name, "Display Port RX", + sizeof("Display Port RX"))) { + idx = EXT_DISP_RX_IDX_DP; + } else { + pr_err("%s: unsupported BE: %s\n", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].bit_format) { + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 2: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int ext_disp_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.integer.value[0] = + ext_disp_rx_cfg[idx].channels - 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + + return 0; +} + +static int ext_disp_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ext_disp_rx_cfg[idx].channels = + ucontrol->value.integer.value[0] + 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + return 1; +} + +static int ext_disp_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].sample_rate) { + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 6; + break; + + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 4; + break; + + case SAMPLING_RATE_32KHZ: + sample_rate_val = 3; + break; + + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: ext_disp_rx[%d].sample_rate = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].sample_rate); + + return 0; +} + +static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 6: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 5: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 4: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_32KHZ; + break; + case 2: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, ext_disp_rx[%d].sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], idx, + ext_disp_rx_cfg[idx].sample_rate); + return 0; +} + static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2848,18 +3058,42 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { }; static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, + ext_disp_rx_ch_get, ext_disp_rx_ch_put), SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, + ext_disp_rx_format_get, ext_disp_rx_format_put), SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, aux_pcm_rx_sample_rate_get, aux_pcm_rx_sample_rate_put), SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, aux_pcm_tx_sample_rate_get, aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, + ext_disp_rx_sample_rate_get, + ext_disp_rx_sample_rate_put), }; +static int msm_ext_disp_get_idx_from_beid(int32_t be_id) +{ + int idx; + + switch (be_id) { + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = EXT_DISP_RX_IDX_DP; + break; + default: + pr_err("%s: Incorrect ext_disp BE id %d\n", __func__, be_id); + idx = -EINVAL; + break; + } + + return idx; +} + static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { @@ -2887,6 +3121,22 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = usb_tx_cfg.sample_rate; channels->min = channels->max = usb_tx_cfg.channels; break; + + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = msm_ext_disp_get_idx_from_beid(dai_link->id); + if (idx < 0) { + pr_err("%s: Incorrect ext disp idx %d\n", + __func__, idx); + rc = idx; + goto done; + } + + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + ext_disp_rx_cfg[idx].bit_format); + rate->min = rate->max = ext_disp_rx_cfg[idx].sample_rate; + channels->min = channels->max = ext_disp_rx_cfg[idx].channels; + break; + case MSM_BACKEND_DAI_AFE_PCM_RX: channels->min = channels->max = proxy_rx_cfg.channels; rate->min = rate->max = SAMPLING_RATE_48KHZ; @@ -3057,6 +3307,7 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; } +done: return rc; } @@ -3402,6 +3653,41 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) mutex_unlock(&mi2s_intf_conf[index].lock); } +static int msm_wcn_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + int ret = 0; + + dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret) { + dev_err(rtd->dev, + "%s: failed to get BTFM codec chan map\n, err:%d\n", + __func__, ret); + goto err; + } + + dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) BE id %d\n", + __func__, tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); + if (ret) + dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + +err: + return ret; +} + static struct snd_soc_ops kona_tdm_be_ops = { .hw_params = kona_tdm_snd_hw_params, }; @@ -3419,6 +3705,10 @@ static struct snd_soc_ops msm_cdc_dma_be_ops = { .hw_params = msm_snd_cdc_dma_hw_params, }; +static struct snd_soc_ops msm_wcn_ops = { + .hw_params = msm_wcn_hw_params, +}; + static int msm_dmic_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -3516,6 +3806,16 @@ static const struct snd_soc_dapm_widget msm_int_dapm_widgets[] = { SND_SOC_DAPM_MIC("Digital Mic5", msm_dmic_event), }; +static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) +{ + unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; + unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160}; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); +} + static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) { int ret = -EINVAL; @@ -4226,6 +4526,21 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, + { + .name = "Compress Capture", + .stream_name = "Compress9", + .cpu_dai_name = "MultiMedia17", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA17, + }, }; static struct snd_soc_dai_link msm_common_be_dai_links[] = { @@ -4432,6 +4747,77 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { }, }; +static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_7_RX, + .stream_name = "Slimbus7 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16398", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + /* BT codec driver determines capabilities based on + * dai name, bt codecdai name should always contains + * supported usecase information + */ + .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .init = &msm_wcn_init, + .ops = &msm_wcn_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_7_TX, + .stream_name = "Slimbus7 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16399", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_bt_sco_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link ext_disp_be_dai_link[] = { + /* DISP PORT BACK END DAI Link */ + { + .name = LPASS_BE_DISPLAY_PORT, + .stream_name = "Display Port Playback", + .cpu_dai_name = "msm-dai-q6-dp.24608", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-ext-disp-audio-codec-rx", + .codec_dai_name = "msm_dp_audio_codec_rx_dai", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* DISP PORT 1 BACK END DAI Link */ + { + .name = LPASS_BE_DISPLAY_PORT1, + .stream_name = "Display Port1 Playback", + .cpu_dai_name = "msm-dai-q6-dp.24608", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-ext-disp-audio-codec-rx", + .codec_dai_name = "msm_dp_audio_codec_rx1_dai", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { { .name = LPASS_BE_PRI_MI2S_RX, @@ -4804,7 +5190,9 @@ static struct snd_soc_dai_link msm_kona_dai_links[ ARRAY_SIZE(msm_auxpcm_be_dai_links) + ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links) + ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links) + - ARRAY_SIZE(msm_va_cdc_dma_be_dai_links)]; + ARRAY_SIZE(msm_va_cdc_dma_be_dai_links) + + ARRAY_SIZE(ext_disp_be_dai_link) + + ARRAY_SIZE(msm_wcn_be_dai_links)]; static int msm_populate_dai_link_component_of_node( struct snd_soc_card *card) @@ -5006,6 +5394,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) int rc = 0; u32 mi2s_audio_intf = 0; u32 auxpcm_audio_intf = 0; + u32 val = 0; const struct of_device_id *match; match = of_match_node(kona_asoc_machine_of_match, dev->of_node); @@ -5088,6 +5477,27 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) } } + rc = of_property_read_u32(dev->of_node, + "qcom,ext-disp-audio-rx", &val); + if (!rc && val) { + dev_dbg(dev, "%s(): ext disp audio support present\n", + __func__); + memcpy(msm_kona_dai_links + total_links, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + total_links += ARRAY_SIZE(ext_disp_be_dai_link); + } + + rc = of_property_read_u32(dev->of_node, "qcom,wcn-bt", &val); + if (!rc && val) { + dev_dbg(dev, "%s(): WCN BT support present\n", + __func__); + memcpy(msm_kona_dai_links + total_links, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + total_links += ARRAY_SIZE(msm_wcn_be_dai_links); + } + dailink = msm_kona_dai_links; } else if(!strcmp(match->data, "stub_codec")) { card = &snd_soc_card_stub_msm; -- GitLab From a27b0c32ea459d9359b3924942ec1a52b778fd90 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 3 Jan 2019 14:21:35 -0800 Subject: [PATCH 0763/1645] ASoC: codecs: qcrg update for TX paths Add qcrg updates for AMIC and DMIC register updates and modes. Change-Id: I7401b21cfffd2c40f456d985e2b3ea1988f4ba6c Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/internal.h | 4 +- asoc/codecs/wcd938x/wcd938x.c | 167 +++++++++++++++++++++++++++++++-- 2 files changed, 163 insertions(+), 8 deletions(-) diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index ea1ff234d00b..e1fea5c41a4a 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #ifndef _WCD938X_INTERNAL_H @@ -17,6 +17,7 @@ #define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50) #define MAX_PORT 8 #define MAX_CH_PER_PORT 8 +#define TX_ADC_MAX 4 enum { TX_HDR12 = 0, @@ -63,6 +64,7 @@ struct wcd938x_priv { struct wcd938x_mbhc *mbhc; u32 hph_mode; + u32 tx_mode[TX_ADC_MAX]; bool comp1_enable; bool comp2_enable; diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 87668313bd85..74c206430d4f 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -30,6 +30,27 @@ #define WCD938X_VERSION_1_0 1 #define WCD938X_VERSION_ENTRY_SIZE 32 +#define ADC_MODE_VAL_HIFI 0x01 +#define ADC_MODE_VAL_LO_HIF 0x02 +#define ADC_MODE_VAL_NORMAL 0x03 +#define ADC_MODE_VAL_LP 0x05 +#define ADC_MODE_VAL_ULP1 0x09 +#define ADC_MODE_VAL_ULP2 0x0B + +#define STRING(name) #name +#define WCD_DAPM_ENUM(name, reg, offset, text) \ +static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ +static const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_ENUM(STRING(name), name##_enum) + +#define WCD_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \ +static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ +static const struct snd_kcontrol_new name##_mux = \ + SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname) + +#define WCD_DAPM_MUX(name, shift, kctl) \ + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux) + enum { WCD9380 = 0, WCD9385, @@ -47,6 +68,16 @@ enum { HPH_PA_DELAY, }; +enum { + ADC_MODE_INVALID = 0, + ADC_MODE_HIFI, + ADC_MODE_LO_HIF, + ADC_MODE_NORMAL, + ADC_MODE_LP, + ADC_MODE_ULP1, + ADC_MODE_ULP2, +}; + static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); @@ -311,8 +342,6 @@ static int wcd938x_rx_clk_enable(struct snd_soc_component *component) struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); if (wcd938x->rx_clk_cnt == 0) { - snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x08, 0x08); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x01, 0x01); snd_soc_component_update_bits(component, @@ -945,17 +974,22 @@ static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w, case 0: case 1: dmic_clk_cnt = &(wcd938x->dmic_0_1_clk_cnt); - dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_CTL; + dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC1_CTL; break; case 2: case 3: dmic_clk_cnt = &(wcd938x->dmic_2_3_clk_cnt); - dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC1_CTL; + dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC2_CTL; break; case 4: case 5: dmic_clk_cnt = &(wcd938x->dmic_4_5_clk_cnt); - dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC2_CTL; + dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC3_CTL; + break; + case 6: + case 7: + dmic_clk_cnt = &(wcd938x->dmic_6_7_clk_cnt); + dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC4_CTL; break; default: dev_err(component->dev, "%s: Invalid DMIC Selection\n", @@ -969,6 +1003,9 @@ static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMU: snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x80); + /* enable clock scaling */ + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DMIC_CTL, 0x06, 0x06); snd_soc_component_update_bits(component, dmic_clk_reg, 0x07, 0x02); snd_soc_component_update_bits(component, @@ -1107,24 +1144,90 @@ static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w, return ret; } +static int wcd938x_get_adc_mode(int val) +{ + int ret = 0; + + switch (val) { + case ADC_MODE_INVALID: + ret = ADC_MODE_VAL_NORMAL; + break; + case ADC_MODE_HIFI: + ret = ADC_MODE_VAL_HIFI; + break; + case ADC_MODE_LO_HIF: + ret = ADC_MODE_VAL_LO_HIF; + break; + case ADC_MODE_NORMAL: + ret = ADC_MODE_VAL_NORMAL; + break; + case ADC_MODE_LP: + ret = ADC_MODE_VAL_LP; + break; + case ADC_MODE_ULP1: + ret = ADC_MODE_VAL_ULP1; + break; + case ADC_MODE_ULP2: + ret = ADC_MODE_VAL_ULP2; + break; + default: + ret = -EINVAL; + pr_err("%s: invalid ADC mode value %d\n", __func__, val); + break; + } + return ret; +} + static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event){ - + int mode; struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: + mode = wcd938x_get_adc_mode(wcd938x->tx_mode[w->shift]); + if (mode < 0) { + dev_info(component->dev, + "%s: invalid mode, setting to normal mode\n", + __func__); + mode = ADC_MODE_VAL_NORMAL; + } snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x80); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x08); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); + switch (w->shift) { + case 0: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1, 0x0F, + mode); + break; + case 1: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1, 0xF0, + mode << 4); + break; + case 2: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3, 0x0F, + mode); + break; + case 3: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3, 0xF0, + mode << 4); + break; + default: + break; + } wcd938x_tx_connect_port(component, ADC1 + (w->shift), true); break; case SND_SOC_DAPM_POST_PMD: @@ -1433,6 +1536,37 @@ static int wcd938x_codec_enable_micbias(struct snd_soc_dapm_widget *w, return __wcd938x_codec_enable_micbias(w, event); } +static int wcd938x_tx_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wcd938x->tx_mode[widget->shift]; + return 0; +} + +static int wcd938x_tx_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + u32 mode_val; + + mode_val = ucontrol->value.enumerated.item[0]; + + dev_dbg(component->dev, "%s: mode: %d\n", __func__, mode_val); + + wcd938x->tx_mode[widget->shift] = mode_val; + return 0; +} + static int wcd938x_rx_hph_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1605,6 +1739,20 @@ static int wcd938x_tx_hdr_put(struct snd_kcontrol *kcontrol, return 0; } +static const char * const tx_mode_mux_text[] = { + "ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP", + "ADC_ULP1", "ADC_ULP2", +}; + +WCD_DAPM_ENUM_EXT(tx0_mode, SND_SOC_NOPM, 0, tx_mode_mux_text, + wcd938x_tx_mode_get, wcd938x_tx_mode_put); +WCD_DAPM_ENUM_EXT(tx1_mode, SND_SOC_NOPM, 1, tx_mode_mux_text, + wcd938x_tx_mode_get, wcd938x_tx_mode_put); +WCD_DAPM_ENUM_EXT(tx2_mode, SND_SOC_NOPM, 2, tx_mode_mux_text, + wcd938x_tx_mode_get, wcd938x_tx_mode_put); +WCD_DAPM_ENUM_EXT(tx3_mode, SND_SOC_NOPM, 3, tx_mode_mux_text, + wcd938x_tx_mode_get, wcd938x_tx_mode_put); + static const char * const rx_hph_mode_mux_text[] = { "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI", "CLS_H_ULP", "CLS_AB_HIFI", @@ -1821,6 +1969,11 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = { SND_SOC_DAPM_MUX("ADC4 MUX", SND_SOC_NOPM, 0, 0, &tx_adc4_mux), + WCD_DAPM_MUX("TX0 MODE", 0, tx0_mode), + WCD_DAPM_MUX("TX1 MODE", 1, tx1_mode), + WCD_DAPM_MUX("TX2 MODE", 2, tx2_mode), + WCD_DAPM_MUX("TX3 MODE", 3, tx3_mode), + /*tx mixers*/ SND_SOC_DAPM_MIXER_E("ADC1_MIXER", SND_SOC_NOPM, 0, 0, adc1_switch, ARRAY_SIZE(adc1_switch), -- GitLab From b7fc921d89c6b4e7b3a491295ab4df666935afbe Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Thu, 3 Jan 2019 14:09:59 +0530 Subject: [PATCH 0764/1645] asoc: wcd937x: Clear Buck disable flag in PMU even if already up Buck disable flag, which is used to indicate if suspend can disable the buck, is not cleared during powerup if it is already enabled. This causes suspend to disable buck even during active usecase. Clear the buck disable flag when returning due to already enable. Change-Id: I5118b66492dff27965a587e1bc6b916d5c26b9fb Signed-off-by: Ramprasad Katkam --- asoc/codecs/wcd937x/wcd937x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index a6cde4dd44d6..156906966480 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1629,6 +1629,7 @@ static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, dev_dbg(component->dev, "%s: buck already in enabled state\n", __func__); + clear_bit(ALLOW_BUCK_DISABLE, &wcd937x->status_mask); return 0; } ret = msm_cdc_enable_ondemand_supply(wcd937x->dev, -- GitLab From 1ca5d397baf7791cd522e9019fc47177482eaa0e Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 27 Dec 2018 14:48:08 +0530 Subject: [PATCH 0765/1645] ASoC: wcd937x: Fix CnP when compander is disabled Pop noise is observed at teardown when compander is disabled. Allow proper delay after PA disable to resolve the pop. Change-Id: I15efa08f28bc1dd32e39b3ca1311b1e417199fd3 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index a6cde4dd44d6..ab610758b7b3 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -694,9 +694,22 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, blocking_notifier_call_chain(&wcd937x->mbhc->notifier, WCD_EVENT_PRE_HPHR_PA_OFF, &wcd937x->mbhc->wcd_mbhc); + set_bit(HPH_PA_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMD: - usleep_range(7000, 7010); + /* + * 7ms sleep is required after PA is disabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is required. + */ + if (test_bit(HPH_PA_DELAY, &wcd937x->status_mask)) { + if (!wcd937x->comp2_enable) + usleep_range(20000, 20100); + else + usleep_range(7000, 7100); + clear_bit(HPH_PA_DELAY, &wcd937x->status_mask); + } + snd_soc_component_update_bits(component, WCD937X_DIGITAL_PDM_WD_CTL1, 0x17, 0x00); blocking_notifier_call_chain(&wcd937x->mbhc->notifier, @@ -776,9 +789,22 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, blocking_notifier_call_chain(&wcd937x->mbhc->notifier, WCD_EVENT_PRE_HPHL_PA_OFF, &wcd937x->mbhc->wcd_mbhc); + set_bit(HPH_PA_DELAY, &wcd937x->status_mask); break; case SND_SOC_DAPM_POST_PMD: - usleep_range(7000, 7010); + /* + * 7ms sleep is required after PA is disabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is required. + */ + if (test_bit(HPH_PA_DELAY, &wcd937x->status_mask)) { + if (!wcd937x->comp1_enable) + usleep_range(20000, 20100); + else + usleep_range(7000, 7100); + clear_bit(HPH_PA_DELAY, &wcd937x->status_mask); + } + snd_soc_component_update_bits(component, WCD937X_DIGITAL_PDM_WD_CTL0, 0x17, 0x00); blocking_notifier_call_chain(&wcd937x->mbhc->notifier, -- GitLab From 3d87e08f9dfc42f143396300188df3f720629795 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 2 Jan 2019 09:31:57 +0800 Subject: [PATCH 0766/1645] ASoC: dsp: correct param_size assignment param_size value is not correctly assigned with roundup. Assign the return value of roundup to param_size. Change-Id: I92e42b4684d7be77a5fa82c8e8c90167f985f97d Signed-off-by: Meng Wang --- dsp/q6adm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index f905ef1ae65c..8f026235288e 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -515,7 +515,7 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, ch_mixer->input_channels[channel_index] + ch_mixer->input_channels[channel_index] * ch_mixer->output_channel); - roundup(param_size, 4); + param_size = roundup(param_size, 4); sz = sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v5) + sizeof(struct default_chmixer_param_id_coeff) + -- GitLab From 9cd3cb3766a0befefe5e7623a08e1bc843fcda08 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Thu, 11 Oct 2018 13:50:41 +0530 Subject: [PATCH 0767/1645] asoc: separate perfmode mode for source and sink Add support to configure perfmode for source and sink in transcode loopback. Change-Id: Iafb0934764139436bf9b71cd3e83cb28a1a7c4a8 Signed-off-by: Surendar Karka --- asoc/msm-transcode-loopback-q6-v2.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index 277ad3c44539..1b431ae06df8 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. */ #include @@ -58,7 +58,7 @@ struct msm_transcode_audio_effects { struct trans_loopback_pdata { struct snd_compr_stream *cstream[MSM_FRONTEND_DAI_MAX]; uint32_t master_gain; - int perf_mode; + int perf_mode[MSM_FRONTEND_DAI_MAX]; struct msm_transcode_audio_effects *audio_effects[MSM_FRONTEND_DAI_MAX]; }; @@ -66,6 +66,7 @@ struct loopback_stream { struct snd_compr_stream *cstream; uint32_t codec_format; bool start; + int perf_mode; }; enum loopback_session_state { @@ -461,6 +462,7 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, goto exit; } trans->sink.start = true; + trans->sink.perf_mode = pdata->perf_mode[rtd->dai_link->id]; } if (cstream->direction == SND_COMPRESS_CAPTURE) { @@ -486,6 +488,7 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, goto exit; } trans->source.start = true; + trans->source.perf_mode = pdata->perf_mode[rtd->dai_link->id]; } pr_debug("%s: trans->source.start %d trans->sink.start %d trans->source.cstream %pK trans->sink.cstream %pK trans->session_state %d\n", @@ -517,7 +520,7 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, pr_debug("%s: ASM client allocated, callback %pK\n", __func__, loopback_event_handler); trans->session_id = trans->audio_client->session; - trans->audio_client->perf_mode = pdata->perf_mode; + trans->audio_client->perf_mode = trans->sink.perf_mode; ret = q6asm_open_transcode_loopback(trans->audio_client, bit_width, trans->source.codec_format, @@ -543,13 +546,13 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, else msm_pcm_routing_reg_phy_stream( soc_pcm_tx->dai_link->id, - trans->audio_client->perf_mode, + trans->source.perf_mode, trans->session_id, SNDRV_PCM_STREAM_CAPTURE); /* Opening Rx ADM in LOW_LATENCY mode by default */ msm_pcm_routing_reg_phy_stream( soc_pcm_rx->dai_link->id, - trans->audio_client->perf_mode, + trans->sink.perf_mode, trans->session_id, SNDRV_PCM_STREAM_PLAYBACK); pr_debug("%s: Successfully opened ADM sessions\n", __func__); @@ -614,15 +617,16 @@ static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream, { switch (metadata->value[0]) { case SNDRV_COMPRESS_LEGACY_LATENCY_MODE: - pdata->perf_mode = LEGACY_PCM_MODE; + pdata->perf_mode[rtd->dai_link->id] = LEGACY_PCM_MODE; break; case SNDRV_COMPRESS_LOW_LATENCY_MODE: - pdata->perf_mode = LOW_LATENCY_PCM_MODE; + pdata->perf_mode[rtd->dai_link->id] = + LOW_LATENCY_PCM_MODE; break; default: pr_debug("%s: Unsupported latency mode %d, default to Legacy\n", __func__, metadata->value[0]); - pdata->perf_mode = LEGACY_PCM_MODE; + pdata->perf_mode[rtd->dai_link->id] = LEGACY_PCM_MODE; break; } break; @@ -1539,9 +1543,10 @@ static int msm_transcode_loopback_probe(struct snd_soc_component *component) if (!pdata) return -ENOMEM; - pdata->perf_mode = LOW_LATENCY_PCM_MODE; - for (i = 0; i < MSM_FRONTEND_DAI_MAX; i++) + for (i = 0; i < MSM_FRONTEND_DAI_MAX; i++) { pdata->audio_effects[i] = NULL; + pdata->perf_mode[i] = LOW_LATENCY_PCM_MODE; + } snd_soc_component_set_drvdata(component, pdata); return 0; -- GitLab From cbb6f02c959455930f12c5d0d5394abaa46aae70 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 26 Dec 2018 15:20:17 +0530 Subject: [PATCH 0768/1645] asoc: bolero: set bolero dev_up flag before macro notification When UP notification is sent to macros, the macros can try to do regcache sync for their regions. Set dev_up flag in bolero before sending UP event to macros to enable register access. Change-Id: Ic04cfef121e9be55e91bf8927da26f9ec249338e Signed-off-by: Ramprasad Katkam --- asoc/codecs/bolero/bolero-cdc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 14a0defeb97d..8092bb7cc533 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -615,6 +615,9 @@ static int bolero_ssr_enable(struct device *dev, void *data) BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET, 0x0); regcache_cache_only(priv->regmap, false); + mutex_lock(&priv->clk_lock); + priv->dev_up = true; + mutex_unlock(&priv->clk_lock); /* call ssr event for supported macros */ for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { if (!priv->macro_params[macro_idx].event_handler) @@ -623,9 +626,6 @@ static int bolero_ssr_enable(struct device *dev, void *data) priv->component, BOLERO_MACRO_EVT_SSR_UP, 0x0); } - mutex_lock(&priv->clk_lock); - priv->dev_up = true; - mutex_unlock(&priv->clk_lock); bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_SSR_UP); return 0; } -- GitLab From 452772abf97a290028c637abfe77c3d0f155e970 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Mon, 7 Jan 2019 17:30:36 +0530 Subject: [PATCH 0769/1645] asoc: bolero: Do not disable mclk in widget power down upon enable failure If mclk enable is failed during mclk widget power up event, it would still send a power down event for the widget during disable, which could disable the mclk voted by other client like soundwire. Do not disable mclk during power down if enable is failed during power up. Change-Id: If782b34f9ef414501590ed8cf681bbe58f1dda76 Signed-off-by: Ramprasad Katkam --- asoc/codecs/bolero/rx-macro.c | 8 +++++++- asoc/codecs/bolero/tx-macro.c | 8 +++++++- asoc/codecs/bolero/wsa-macro.c | 8 +++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index ec7390a0cbc5..4d9ccb43761c 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -344,6 +344,7 @@ struct rx_macro_priv { u16 prim_int_users[INTERP_MAX]; int rx_mclk_users; int swr_clk_users; + bool dapm_mclk_enable; bool reset_swr; int clsh_users; int rx_mclk_cnt; @@ -1152,9 +1153,14 @@ static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w, rx_priv->swr_ctrl_data[0].rx_swr_pdev, SWR_CLK_FREQ, &mclk_freq); ret = rx_macro_mclk_enable(rx_priv, 1, true); + if (ret) + rx_priv->dapm_mclk_enable = false; + else + rx_priv->dapm_mclk_enable = true; break; case SND_SOC_DAPM_POST_PMD: - ret = rx_macro_mclk_enable(rx_priv, 0, true); + if (rx_priv->dapm_mclk_enable) + ret = rx_macro_mclk_enable(rx_priv, 0, true); break; default: dev_err(rx_priv->dev, diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 4cbf0aaccbff..ec5616672210 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -127,6 +127,7 @@ struct tx_macro_priv { bool dec_active[NUM_DECIMATORS]; int tx_mclk_users; int swr_clk_users; + bool dapm_mclk_enable; bool reset_swr; struct clk *tx_core_clk; struct clk *tx_npl_clk; @@ -260,9 +261,14 @@ static int tx_macro_mclk_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: ret = tx_macro_mclk_enable(tx_priv, 1); + if (ret) + tx_priv->dapm_mclk_enable = false; + else + tx_priv->dapm_mclk_enable = true; break; case SND_SOC_DAPM_POST_PMD: - ret = tx_macro_mclk_enable(tx_priv, 0); + if (tx_priv->dapm_mclk_enable) + ret = tx_macro_mclk_enable(tx_priv, 0); break; default: dev_err(tx_priv->dev, diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 85417bc3df33..00d3d2c7782b 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -192,6 +192,7 @@ struct wsa_macro_priv { u16 prim_int_users[WSA_MACRO_RX1 + 1]; u16 wsa_mclk_users; u16 swr_clk_users; + bool dapm_mclk_enable; bool reset_swr; unsigned int vi_feed_value; struct mutex mclk_lock; @@ -870,9 +871,14 @@ static int wsa_macro_mclk_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: ret = wsa_macro_mclk_enable(wsa_priv, 1, true); + if (ret) + wsa_priv->dapm_mclk_enable = false; + else + wsa_priv->dapm_mclk_enable = true; break; case SND_SOC_DAPM_POST_PMD: - wsa_macro_mclk_enable(wsa_priv, 0, true); + if (wsa_priv->dapm_mclk_enable) + wsa_macro_mclk_enable(wsa_priv, 0, true); break; default: dev_err(wsa_priv->dev, -- GitLab From a60239e354d946d4f8b5b6cb325449cb02b3195f Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 10 Jan 2019 14:43:03 +0530 Subject: [PATCH 0770/1645] soc: soundwire: Add support for GPIO interrupt path In trinket target, interrupt for wakeup is provided via chip TLMM. Add required support to handle wakeup interrupt on SWR data line triggered over this TLMM line. Change-Id: I7fb6d7009a6271d54d0f11f99930b0d039f57129 Signed-off-by: Laxminath Kasam --- soc/swr-mstr-ctrl.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 74817af99597..2235934a727d 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include #include @@ -2168,17 +2170,28 @@ static int swrm_device_down(struct device *dev) int swrm_register_wake_irq(struct swr_mstr_ctrl *swrm) { int ret = 0; + int irq, dir_apps_irq; if (!swrm->ipc_wakeup) { - swrm->wake_irq = platform_get_irq_byname(swrm->pdev, - "swr_wake_irq"); - if (swrm->wake_irq < 0) { - dev_err(swrm->dev, - "%s() error getting wake irq handle: %d\n", - __func__, swrm->wake_irq); - return -EINVAL; + irq = of_get_named_gpio(swrm->dev->of_node, + "qcom,swr-wakeup-irq", 0); + if (gpio_is_valid(irq)) { + swrm->wake_irq = gpio_to_irq(irq); + if (swrm->wake_irq < 0) { + dev_err(swrm->dev, + "Unable to configure irq\n"); + return swrm->wake_irq; + } + } else { + dir_apps_irq = platform_get_irq_byname(swrm->pdev, + "swr_wake_irq"); + if (dir_apps_irq < 0) { + dev_err(swrm->dev, + "TLMM connect gpio not found\n"); + return -EINVAL; + } + swrm->wake_irq = dir_apps_irq; } - ret = request_threaded_irq(swrm->wake_irq, NULL, swrm_wakeup_interrupt, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, -- GitLab From defd81b1a54d4f515a6a02e5924b843322b08b2c Mon Sep 17 00:00:00 2001 From: Dhananjay Kumar Date: Tue, 11 Dec 2018 18:05:59 +0530 Subject: [PATCH 0771/1645] dsp: add support to set custom channel mixer coefficients Enhance Channel Mixer control for MultiMedia Frontends to get custom channel mixer coefficients from userspace and use it during device routings to control stream to device channel mappings. Change-Id: Ifedac25de5ae6bad1092b66ec405bba66a80f608 Signed-off-by: Cong Tang Signed-off-by: Dhananjay Kumar --- dsp/q6adm.c | 113 ++++++++++++----------------------------- dsp/q6asm.c | 14 +++-- include/dsp/q6adm-v2.h | 8 ++- include/dsp/q6asm-v2.h | 6 ++- 4 files changed, 56 insertions(+), 85 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index f905ef1ae65c..1851b9877357 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -141,6 +141,11 @@ void msm_dts_srs_release_lock(void) mutex_unlock(&dts_srs_lock); } +static int adm_arrange_mch_map_v8( + struct adm_device_endpoint_payload *ep_payload, + int path, + int channel_mode); + /** * adm_validate_and_get_port_index - * validate given port id @@ -488,9 +493,10 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, struct adm_cmd_set_pspd_mtmx_strtr_params_v5 *adm_params = NULL; struct param_hdr_v1 data_v5; int ret = 0, port_idx, sz = 0, param_size = 0; + struct adm_device_endpoint_payload ep_params = {0, 0, 0, {0}}; u16 *adm_pspd_params; u16 *ptr; - int index = 0; + int index = 0, i = 0, path_type = ADM_PATH_PLAYBACK; pr_debug("%s: port_id = %d\n", __func__, port_id); port_id = afe_convert_virtual_to_portid(port_id); @@ -515,7 +521,7 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, ch_mixer->input_channels[channel_index] + ch_mixer->input_channels[channel_index] * ch_mixer->output_channel); - roundup(param_size, 4); + param_size = roundup(param_size, 4); sz = sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v5) + sizeof(struct default_chmixer_param_id_coeff) + @@ -561,84 +567,31 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, adm_pspd_params[3] = ch_mixer->input_channels[channel_index]; index = 4; - if (ch_mixer->output_channel == 1) { - adm_pspd_params[index] = PCM_CHANNEL_FC; - } else if (ch_mixer->output_channel == 2) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - } else if (ch_mixer->output_channel == 3) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_FC; - } else if (ch_mixer->output_channel == 4) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_LS; - adm_pspd_params[index + 3] = PCM_CHANNEL_RS; - } else if (ch_mixer->output_channel == 5) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_FC; - adm_pspd_params[index + 3] = PCM_CHANNEL_LS; - adm_pspd_params[index + 4] = PCM_CHANNEL_RS; - } else if (ch_mixer->output_channel == 6) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_LFE; - adm_pspd_params[index + 3] = PCM_CHANNEL_FC; - adm_pspd_params[index + 4] = PCM_CHANNEL_LS; - adm_pspd_params[index + 5] = PCM_CHANNEL_RS; - } else if (ch_mixer->output_channel == 8) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_LFE; - adm_pspd_params[index + 3] = PCM_CHANNEL_FC; - adm_pspd_params[index + 4] = PCM_CHANNEL_LS; - adm_pspd_params[index + 5] = PCM_CHANNEL_RS; - adm_pspd_params[index + 6] = PCM_CHANNEL_LB; - adm_pspd_params[index + 7] = PCM_CHANNEL_RB; - } - - index = index + ch_mixer->output_channel; - if (ch_mixer->input_channels[channel_index] == 1) { - adm_pspd_params[index] = PCM_CHANNEL_FC; - } else if (ch_mixer->input_channels[channel_index] == 2) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - } else if (ch_mixer->input_channels[channel_index] == 3) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_FC; - } else if (ch_mixer->input_channels[channel_index] == 4) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_LS; - adm_pspd_params[index + 3] = PCM_CHANNEL_RS; - } else if (ch_mixer->input_channels[channel_index] == 5) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_FC; - adm_pspd_params[index + 3] = PCM_CHANNEL_LS; - adm_pspd_params[index + 4] = PCM_CHANNEL_RS; - } else if (ch_mixer->input_channels[channel_index] == 6) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_LFE; - adm_pspd_params[index + 3] = PCM_CHANNEL_FC; - adm_pspd_params[index + 4] = PCM_CHANNEL_LS; - adm_pspd_params[index + 5] = PCM_CHANNEL_RS; - } else if (ch_mixer->input_channels[channel_index] == 8) { - adm_pspd_params[index] = PCM_CHANNEL_FL; - adm_pspd_params[index + 1] = PCM_CHANNEL_FR; - adm_pspd_params[index + 2] = PCM_CHANNEL_LFE; - adm_pspd_params[index + 3] = PCM_CHANNEL_FC; - adm_pspd_params[index + 4] = PCM_CHANNEL_LS; - adm_pspd_params[index + 5] = PCM_CHANNEL_RS; - adm_pspd_params[index + 6] = PCM_CHANNEL_LB; - adm_pspd_params[index + 7] = PCM_CHANNEL_RB; - } - - index = index + ch_mixer->input_channels[channel_index]; + path_type = (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) ? + ADM_PATH_PLAYBACK : ADM_PATH_LIVE_REC; + + if (ch_mixer->override_out_ch_map) { + memcpy(&adm_pspd_params[index], &ch_mixer->out_ch_map, + ch_mixer->output_channel * sizeof(uint16_t)); + index += ch_mixer->output_channel; + } else { + ep_params.dev_num_channel = ch_mixer->output_channel; + adm_arrange_mch_map_v8(&ep_params, path_type, ep_params.dev_num_channel); + for (i = 0; i < ch_mixer->output_channel; i++) + adm_pspd_params[index++] = ep_params.dev_channel_mapping[i]; + } + + if (ch_mixer->override_in_ch_map) { + memcpy(&adm_pspd_params[index], &ch_mixer->in_ch_map, + ch_mixer->input_channel * sizeof(uint16_t)); + index += ch_mixer->input_channel; + } else { + ep_params.dev_num_channel = ch_mixer->input_channels[channel_index]; + adm_arrange_mch_map_v8(&ep_params, path_type, ep_params.dev_num_channel); + for (i = 0; i < ch_mixer->input_channels[channel_index]; i++) + adm_pspd_params[index++] = ep_params.dev_channel_mapping[i]; + } + ret = adm_populate_channel_weight(&adm_pspd_params[index], ch_mixer, channel_index); if (ret) { diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 5c9de064feed..1b10d62b4af8 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -114,8 +114,6 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir); static void q6asm_reset_buf_state(struct audio_client *ac); -static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, - bool use_back_flavor); void *q6asm_mmap_apr_reg(void); static int q6asm_is_valid_session(struct apr_client_data *data, void *priv); @@ -5420,7 +5418,16 @@ int q6asm_enc_cfg_blk_pcm_native(struct audio_client *ac, } EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_native); -static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, +/* + * q6asm_map_channels: + * Provide default asm channel mapping for given channel count. + * + * @channel_mapping: buffer pointer to write back channel maps. + * @channels: channel count for which channel map is required. + * @use_back_flavor: use back channels instead of surround channels. + * Returns 0 for success, -EINVAL for unsupported channel count. + */ +int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, bool use_back_flavor) { u8 *lchannel_mapping; @@ -5528,6 +5535,7 @@ static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, } return 0; } +EXPORT_SYMBOL(q6asm_map_channels); /** * q6asm_enable_sbrps - diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 3d60963a8493..b86175a002b4 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #ifndef __Q6_ADM_V2_H__ #define __Q6_ADM_V2_H__ @@ -77,6 +77,12 @@ struct msm_pcm_channel_mixer { bool enable; int rule; int channel_weight[ADM_MAX_CHANNELS][ADM_MAX_CHANNELS]; + int port_idx; + int input_channel; + uint16_t in_ch_map[ADM_MAX_CHANNELS]; + uint16_t out_ch_map[ADM_MAX_CHANNELS]; + bool override_in_ch_map; + bool override_out_ch_map; }; int srs_trumedia_open(int port_id, int copp_idx, __s32 srs_tech_id, diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index 4851a81ff023..1bb44b4a31d1 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #ifndef __Q6_ASM_V2_H__ #define __Q6_ASM_V2_H__ @@ -741,4 +741,8 @@ uint8_t q6asm_get_stream_id_from_token(uint32_t token); int q6asm_adjust_session_clock(struct audio_client *ac, uint32_t adjust_time_lsw, uint32_t adjust_time_msw); + +/* Provide default asm channel mapping for given channel count */ +int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, + bool use_back_flavor); #endif /* __Q6_ASM_H__ */ -- GitLab From 5141b172ce7cdece7e30f08703628474ff77b575 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 24 Dec 2018 20:04:15 +0530 Subject: [PATCH 0772/1645] ASoC: wcd937x: Enable and disable HPH OCP at PA to avoid CnP Enable HPHR and HPHL OCP after PA enable and disable it before PA disable to avoid CnP issues at teardown. Change-Id: Ic08a8862a7fb4f40ecc6060de6aa1eadc11f1c0f Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index ab610758b7b3..e5525d5801fa 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -131,10 +131,6 @@ static int wcd937x_init_reg(struct snd_soc_component *component) 0xFF, 0x3A); snd_soc_component_update_bits(component, WCD937X_RX_OCP_CTL, 0x0F, 0x02); - snd_soc_component_update_bits(component, WCD937X_HPH_R_TEST, - 0x01, 0x01); - snd_soc_component_update_bits(component, WCD937X_HPH_L_TEST, - 0x01, 0x01); return 0; } @@ -677,6 +673,8 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD937X_HPH_R_TEST, 0x01, 0x01); if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) snd_soc_component_update_bits(component, WCD937X_ANA_RX_SUPPLIES, @@ -687,6 +685,8 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, (WCD_RX2 << 0x10)); break; case SND_SOC_DAPM_PRE_PMD: + snd_soc_component_update_bits(component, + WCD937X_HPH_R_TEST, 0x01, 0x00); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -772,6 +772,8 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD937X_HPH_L_TEST, 0x01, 0x01); if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) snd_soc_component_update_bits(component, WCD937X_ANA_RX_SUPPLIES, @@ -782,6 +784,8 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, (WCD_RX1 << 0x10)); break; case SND_SOC_DAPM_PRE_PMD: + snd_soc_component_update_bits(component, + WCD937X_HPH_L_TEST, 0x01, 0x00); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, -- GitLab From 2e838e52fe918452eb2c3a4a697b27a3f921fb8f Mon Sep 17 00:00:00 2001 From: Tanya Dixit Date: Fri, 30 Nov 2018 17:09:17 +0530 Subject: [PATCH 0773/1645] asoc: codecs: Add support for setting ear gain ctl Add support for setting EAR PA gain directly using mixer control. Change-Id: Ifd9e31ed45d10b5ea0f9cf546806ef78ece9e181 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x.c | 61 +++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index e5525d5801fa..9d9f671c0bc5 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -910,6 +910,9 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD937X_DIGITAL_PDM_WD_CTL0, 0x17, 0x13); + if (!wcd937x->comp1_enable) + snd_soc_component_update_bits(component, + WCD937X_ANA_EAR_COMPANDER_CTL, 0x80, 0x80); break; case SND_SOC_DAPM_POST_PMU: usleep_range(6000, 6010); @@ -929,6 +932,9 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, (WCD_RX1 << 0x10 | 0x1)); break; case SND_SOC_DAPM_POST_PMD: + if (!wcd937x->comp1_enable) + snd_soc_component_update_bits(component, + WCD937X_ANA_EAR_COMPANDER_CTL, 0x80, 0x00); usleep_range(7000, 7010); wcd_cls_h_fsm(component, &wcd937x->clsh_info, WCD_CLSH_EVENT_POST_PA, @@ -1595,6 +1601,48 @@ static int wcd937x_rx_hph_mode_put(struct snd_kcontrol *kcontrol, return 0; } +static int wcd937x_ear_pa_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 ear_pa_gain = 0; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + + ear_pa_gain = snd_soc_component_read32(component, + WCD937X_ANA_EAR_COMPANDER_CTL); + + ear_pa_gain = (ear_pa_gain & 0x7C) >> 2; + + ucontrol->value.integer.value[0] = ear_pa_gain; + + dev_dbg(component->dev, "%s: ear_pa_gain = 0x%x\n", __func__, + ear_pa_gain); + + return 0; +} + +static int wcd937x_ear_pa_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 ear_pa_gain = 0; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + ear_pa_gain = ucontrol->value.integer.value[0] << 2; + + if (!wcd937x->comp1_enable) { + snd_soc_component_update_bits(component, + WCD937X_ANA_EAR_COMPANDER_CTL, + 0x7C, ear_pa_gain); + } + + return 0; +} + static int wcd937x_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1690,11 +1738,24 @@ static const char * const rx_hph_mode_mux_text[] = { "CLS_H_ULP", "CLS_AB_HIFI", }; +static const char * const wcd937x_ear_pa_gain_text[] = { + "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB", "G_0_DB", + "G_M1P5_DB", "G_M3_DB", "G_M4P5_DB", + "G_M6_DB", "G_7P5_DB", "G_M9_DB", + "G_M10P5_DB", "G_M12_DB", "G_M13P5_DB", + "G_M15_DB", "G_M16P5_DB", "G_M18_DB", +}; + static const struct soc_enum rx_hph_mode_mux_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text), rx_hph_mode_mux_text); +static SOC_ENUM_SINGLE_EXT_DECL(wcd937x_ear_pa_gain_enum, + wcd937x_ear_pa_gain_text); + static const struct snd_kcontrol_new wcd937x_snd_controls[] = { + SOC_ENUM_EXT("EAR PA GAIN", wcd937x_ear_pa_gain_enum, + wcd937x_ear_pa_gain_get, wcd937x_ear_pa_gain_put), SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum, wcd937x_rx_hph_mode_get, wcd937x_rx_hph_mode_put), SOC_SINGLE_EXT("HPHL_COMP Switch", SND_SOC_NOPM, 0, 1, 0, -- GitLab From 996c1bff0edcf4518c7cbc61ae174d0a36919b35 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 24 Jan 2019 11:24:20 -0800 Subject: [PATCH 0774/1645] ASoC: codecs: qcrg update for HPH and TX channel paths Add updates to HPH rdac gain control registers and tx channel register writes. Change-Id: I6c32f0f4ee049404c1648104c5e624eaee3a5817 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/wcd938x.c | 70 +++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 74c206430d4f..10a085b4298f 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -164,6 +164,17 @@ static int wcd938x_init_reg(struct snd_soc_component *component) 0x01, 0x01); snd_soc_component_update_bits(component, WCD938X_HPH_L_TEST, 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD938X_HPH_NEW_INT_RDAC_GAIN_CTL, + 0xF0, 0x00); + snd_soc_component_update_bits(component, + WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L_NEW, + 0x1F, 0x15); + snd_soc_component_update_bits(component, + WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R_NEW, + 0x1F, 0x15); + snd_soc_component_update_bits(component, WCD938X_HPH_REFBUFF_UHQA_CTL, + 0xC0, 0x80); return 0; } @@ -1240,11 +1251,52 @@ static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w, return 0; } +int wcd938x_tx_channel_config(struct snd_soc_component *component, + int channel, int mode) +{ + int reg = WCD938X_ANA_TX_CH2, mask = 0, val = 0; + int ret = 0; + + switch (channel) { + case 0: + reg = WCD938X_ANA_TX_CH2; + mask = 0x40; + break; + case 1: + reg = WCD938X_ANA_TX_CH2; + mask = 0x20; + break; + case 2: + reg = WCD938X_ANA_TX_CH4; + mask = 0x40; + break; + case 3: + reg = WCD938X_ANA_TX_CH4; + mask = 0x20; + break; + default: + pr_err("%s: Invalid channel num %d\n", __func__, channel); + ret = -EINVAL; + break; + } + + if (!mode) + val = 0x00; + else + val = mask; + + if (!ret) + snd_soc_component_update_bits(component, reg, mask, val); + + return ret; +} + static int wcd938x_enable_req(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + int ret = 0; dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -1255,20 +1307,14 @@ static int wcd938x_enable_req(struct snd_soc_dapm_widget *w, WCD938X_DIGITAL_CDC_REQ_CTL, 0x02, 0x02); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_REQ_CTL, 0x01, 0x00); - snd_soc_component_update_bits(component, - WCD938X_ANA_TX_CH2, 0x40, 0x40); - snd_soc_component_update_bits(component, - WCD938X_ANA_TX_CH2, 0x20, 0x20); + ret = wcd938x_tx_channel_config(component, w->shift, 1); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x30, 0x30); snd_soc_component_update_bits(component, WCD938X_ANA_TX_CH1, 0x80, 0x80); - snd_soc_component_update_bits(component, - WCD938X_ANA_TX_CH2, 0x40, 0x00); snd_soc_component_update_bits(component, WCD938X_ANA_TX_CH2, 0x80, 0x80); - snd_soc_component_update_bits(component, - WCD938X_ANA_TX_CH2, 0x20, 0x00); + ret |= wcd938x_tx_channel_config(component, w->shift, 0); break; case SND_SOC_DAPM_POST_PMD: snd_soc_component_update_bits(component, @@ -1283,7 +1329,7 @@ static int wcd938x_enable_req(struct snd_soc_dapm_widget *w, WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x00); break; }; - return 0; + return ret; } int wcd938x_micbias_control(struct snd_soc_component *component, @@ -1952,13 +1998,13 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = { SND_SOC_DAPM_MIXER_E("ADC1 REQ", SND_SOC_NOPM, 0, 0, NULL, 0, wcd938x_enable_req, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER_E("ADC2 REQ", SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_MIXER_E("ADC2 REQ", SND_SOC_NOPM, 1, 0, NULL, 0, wcd938x_enable_req, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER_E("ADC3 REQ", SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_MIXER_E("ADC3 REQ", SND_SOC_NOPM, 2, 0, NULL, 0, wcd938x_enable_req, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER_E("ADC4 REQ", SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_MIXER_E("ADC4 REQ", SND_SOC_NOPM, 3, 0, NULL, 0, wcd938x_enable_req, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), -- GitLab From 24efd2a62e81155c4499256dc345282ce769f872 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Wed, 12 Dec 2018 14:25:06 -0800 Subject: [PATCH 0775/1645] dsp: add dma map resource cmd Add a new API for mapping DMA resources that needs to be attached to existing SMMU SID. Change-Id: I7a513d24ea30a5ead318e856e4c5317743fd0021 Signed-off-by: Vikram Panduranga --- dsp/msm_audio_ion.c | 39 ++++++++++++++++++++++++++++++++++++- include/dsp/msm_audio_ion.h | 6 +++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index 95d4fd4e2bcf..eeea32d87be3 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. */ #include @@ -400,6 +400,43 @@ int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, } EXPORT_SYMBOL(msm_audio_ion_alloc); +/** + * msm_audio_ion_dma_map - + * Memory maps for a given DMA buffer + * + * @phys_addr: Physical address of DMA buffer to be mapped + * @iova_base: IOVA address of memory mapped DMA buffer + * @size: buffer size + * @dir: DMA direction + * Returns 0 on success or error on failure + */ +int msm_audio_ion_dma_map(dma_addr_t *phys_addr, dma_addr_t *iova_base, + u32 size, enum dma_data_direction dir) +{ + dma_addr_t iova; + struct device *cb_dev = msm_audio_ion_data.cb_dev; + + if (!phys_addr || !iova_base || !size) + return -EINVAL; + + iova = dma_map_resource(cb_dev, *phys_addr, size, + dir, 0); + if (dma_mapping_error(cb_dev, iova)) { + pr_err("%s: dma_mapping_error\n", __func__); + return -EIO; + } + pr_debug("%s: dma_mapping_success iova:0x%lx\n", __func__, + (unsigned long)iova); + if (msm_audio_ion_data.smmu_enabled) + /* Append the SMMU SID information to the IOVA address */ + iova |= msm_audio_ion_data.smmu_sid_bits; + + *iova_base = iova; + + return 0; +} +EXPORT_SYMBOL(msm_audio_ion_dma_map); + /** * msm_audio_ion_import- * Import ION buffer with given file descriptor diff --git a/include/dsp/msm_audio_ion.h b/include/dsp/msm_audio_ion.h index 09d590b52a31..9ac5ca30e080 100644 --- a/include/dsp/msm_audio_ion.h +++ b/include/dsp/msm_audio_ion.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2013-2015, 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2015, 2017-2019, The Linux Foundation. All rights reserved. */ #ifndef _LINUX_MSM_AUDIO_ION_H @@ -8,6 +8,7 @@ #include #include #include +#include enum { MSM_AUDIO_ION_INV_CACHES = 0, @@ -26,4 +27,7 @@ int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op); u32 msm_audio_populate_upper_32_bits(dma_addr_t pa); int msm_audio_ion_get_smmu_info(struct device **cb_dev, u64 *smmu_sid); + +int msm_audio_ion_dma_map(dma_addr_t *phys_addr, dma_addr_t *iova_base, + u32 size, enum dma_data_direction dir); #endif /* _LINUX_MSM_AUDIO_ION_H */ -- GitLab From 688a8670916aa9285724336723791f83ed78dad6 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 29 Jan 2019 13:43:33 +0800 Subject: [PATCH 0776/1645] asoc: Update file header to GPL-2.0-only Update file header to GPL-2.0-only. Change-Id: If16bf92f951c6d7521f56a3e9b91da2ca2ccf6f8 Signed-off-by: Meng Wang --- asoc/kona.c | 2 +- dsp/adsp-loader.c | 2 +- dsp/adsp_err.c | 2 +- dsp/adsp_err.h | 2 +- dsp/audio_cal_utils.c | 2 +- dsp/audio_calibration.c | 2 +- dsp/audio_notifier.c | 2 +- dsp/audio_pdr.c | 2 +- dsp/audio_pdr.h | 2 +- dsp/audio_slimslave.c | 2 +- dsp/audio_ssr.c | 2 +- dsp/audio_ssr.h | 2 +- dsp/avtimer.c | 2 +- dsp/msm-audio-event-notify.c | 2 +- dsp/msm-dts-srs-tm-config.c | 2 +- dsp/msm_audio_ion.c | 2 +- dsp/msm_mdf.c | 2 +- dsp/q6_init.c | 2 +- dsp/q6_init.h | 2 +- dsp/q6adm.c | 2 +- dsp/q6afe.c | 2 +- dsp/q6afecal-hwdep.c | 2 +- dsp/q6afecal-hwdep.h | 2 +- dsp/q6asm.c | 2 +- dsp/q6audio-v2.c | 2 +- dsp/q6common.c | 2 +- dsp/q6core.c | 2 +- dsp/q6lsm.c | 2 +- dsp/q6usm.c | 2 +- dsp/q6usm.h | 2 +- dsp/q6voice.c | 2 +- dsp/rtac.c | 2 +- dsp/usf.c | 2 +- dsp/usf.h | 2 +- dsp/usfcdev.c | 2 +- dsp/usfcdev.h | 2 +- 36 files changed, 36 insertions(+), 36 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index bcc17736475f..1c68a986c02f 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ diff --git a/dsp/adsp-loader.c b/dsp/adsp-loader.c index 725e3703c819..387850bd3670 100644 --- a/dsp/adsp-loader.c +++ b/dsp/adsp-loader.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2014, 2017-2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/adsp_err.c b/dsp/adsp_err.c index 1b30b2b40ae0..f2401569ccbe 100644 --- a/dsp/adsp_err.c +++ b/dsp/adsp_err.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. */ diff --git a/dsp/adsp_err.h b/dsp/adsp_err.h index 9b3c4c449e8a..8a0f6bf97748 100644 --- a/dsp/adsp_err.h +++ b/dsp/adsp_err.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. */ diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index 36068d3b949b..19c71fc55208 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/audio_calibration.c b/dsp/audio_calibration.c index 93bd352ad9b1..a5167be3cfaa 100644 --- a/dsp/audio_calibration.c +++ b/dsp/audio_calibration.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved. */ diff --git a/dsp/audio_notifier.c b/dsp/audio_notifier.c index cb23c4c523e0..56cfa31fa645 100644 --- a/dsp/audio_notifier.c +++ b/dsp/audio_notifier.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. */ diff --git a/dsp/audio_pdr.c b/dsp/audio_pdr.c index 509d5c81a77c..b9341dec1e52 100644 --- a/dsp/audio_pdr.c +++ b/dsp/audio_pdr.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. */ diff --git a/dsp/audio_pdr.h b/dsp/audio_pdr.h index 398d6871ce48..e563275ee5e3 100644 --- a/dsp/audio_pdr.h +++ b/dsp/audio_pdr.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/audio_slimslave.c b/dsp/audio_slimslave.c index 69cdf59db929..b09506a05f18 100644 --- a/dsp/audio_slimslave.c +++ b/dsp/audio_slimslave.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2013-2014, 2017-2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/audio_ssr.c b/dsp/audio_ssr.c index 8c27097085e4..9a9467ae73a2 100644 --- a/dsp/audio_ssr.c +++ b/dsp/audio_ssr.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016, The Linux Foundation. All rights reserved. */ diff --git a/dsp/audio_ssr.h b/dsp/audio_ssr.h index d633ffd9cac2..e79c59433d78 100644 --- a/dsp/audio_ssr.h +++ b/dsp/audio_ssr.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016, The Linux Foundation. All rights reserved. */ diff --git a/dsp/avtimer.c b/dsp/avtimer.c index ee73826cb329..29bfd24adc2b 100644 --- a/dsp/avtimer.c +++ b/dsp/avtimer.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2015, 2017-2018 The Linux Foundation. All rights reserved. */ diff --git a/dsp/msm-audio-event-notify.c b/dsp/msm-audio-event-notify.c index da3188c3656e..06b4d3eaa732 100644 --- a/dsp/msm-audio-event-notify.c +++ b/dsp/msm-audio-event-notify.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/msm-dts-srs-tm-config.c b/dsp/msm-dts-srs-tm-config.c index 81bb7941bd97..b507d02af7d9 100644 --- a/dsp/msm-dts-srs-tm-config.c +++ b/dsp/msm-dts-srs-tm-config.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2014, 2016-2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index eeea32d87be3..089376cb28e7 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. */ diff --git a/dsp/msm_mdf.c b/dsp/msm_mdf.c index 674dd748aafe..e3d87e32f381 100644 --- a/dsp/msm_mdf.c +++ b/dsp/msm_mdf.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/q6_init.c b/dsp/q6_init.c index bd8a2f86da4a..e97a49692c7d 100644 --- a/dsp/q6_init.c +++ b/dsp/q6_init.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017, The Linux Foundation. All rights reserved. */ diff --git a/dsp/q6_init.h b/dsp/q6_init.h index 21be5241ac68..bd4ba399a34e 100644 --- a/dsp/q6_init.h +++ b/dsp/q6_init.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 1851b9877357..688012f727d9 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 7f82e7c05a27..1b5c94d59a5f 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ diff --git a/dsp/q6afecal-hwdep.c b/dsp/q6afecal-hwdep.c index c399fa6d93d8..0a040749d5a4 100644 --- a/dsp/q6afecal-hwdep.c +++ b/dsp/q6afecal-hwdep.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015, 2017, The Linux Foundation. All rights reserved. */ diff --git a/dsp/q6afecal-hwdep.h b/dsp/q6afecal-hwdep.h index d48b80f82aa9..68c48b71088a 100644 --- a/dsp/q6afecal-hwdep.h +++ b/dsp/q6afecal-hwdep.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2014, 2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 1b10d62b4af8..300bdf2b4dd1 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ diff --git a/dsp/q6audio-v2.c b/dsp/q6audio-v2.c index f0b031cf0166..822fbb53b18b 100644 --- a/dsp/q6audio-v2.c +++ b/dsp/q6audio-v2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ diff --git a/dsp/q6common.c b/dsp/q6common.c index 0c5427de2d90..8270054e8ec3 100644 --- a/dsp/q6common.c +++ b/dsp/q6common.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/q6core.c b/dsp/q6core.c index 38551439637f..283f785f66f8 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 7e40ec44fba1..6af7f6953507 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2013-2019, Linux Foundation. All rights reserved. */ diff --git a/dsp/q6usm.c b/dsp/q6usm.c index 70ebc9fe5b2d..ce25c71e137f 100644 --- a/dsp/q6usm.c +++ b/dsp/q6usm.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/q6usm.h b/dsp/q6usm.h index 975b89606043..aa531b028495 100644 --- a/dsp/q6usm.h +++ b/dsp/q6usm.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2011-2014, 2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 95a153d4fa25..17746b1962fd 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. */ diff --git a/dsp/rtac.c b/dsp/rtac.c index 6e606d17edb4..37b7e49f9599 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ diff --git a/dsp/usf.c b/dsp/usf.c index c6850e5a52de..e408c7d70f5b 100644 --- a/dsp/usf.c +++ b/dsp/usf.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. */ diff --git a/dsp/usf.h b/dsp/usf.h index 5aeec06e2dac..b7e516d5920d 100644 --- a/dsp/usf.h +++ b/dsp/usf.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. */ diff --git a/dsp/usfcdev.c b/dsp/usfcdev.c index cab76612916c..d1ac4c0025b2 100644 --- a/dsp/usfcdev.c +++ b/dsp/usfcdev.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2013, 2016-2017 The Linux Foundation. All rights reserved. */ diff --git a/dsp/usfcdev.h b/dsp/usfcdev.h index dcde63b05d08..7b8bce7b3721 100644 --- a/dsp/usfcdev.h +++ b/dsp/usfcdev.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2012, The Linux Foundation. All rights reserved. */ -- GitLab From 2122732534face32314b6a47e4fa9d45e14a2e2e Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Fri, 25 Jan 2019 15:35:14 -0800 Subject: [PATCH 0777/1645] asoc: bolero: enable VA macro island mode MUX select on Kona VA macro is currently lacking capability to dynamically select island mode on Kona. Add support in VA macro driver to read MUX selection register from DT to enable dynamic island mode select. Change-Id: I5462265fffcc6d6bbb3ff6eead5f44f0b8909141 Signed-off-by: Xiaoyu Ye --- asoc/codecs/bolero/va-macro.c | 66 +++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 29381f78c165..e89042e17e85 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -107,7 +107,9 @@ struct va_macro_priv { s32 dmic_6_7_clk_cnt; u16 dmic_clk_div; u16 va_mclk_users; + u16 mclk_mux_sel; char __iomem *va_io_base; + char __iomem *va_island_mode_muxsel; struct regulator *micb_supply; u32 micb_voltage; u32 micb_current; @@ -139,7 +141,6 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, { struct regmap *regmap = dev_get_regmap(va_priv->dev->parent, NULL); int ret = 0; - u16 mclk_mux_sel = MCLK_MUX0; if (regmap == NULL) { dev_err(va_priv->dev, "%s: regmap is NULL\n", __func__); @@ -150,21 +151,11 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, __func__, mclk_enable, dapm, va_priv->va_mclk_users); mutex_lock(&va_priv->mclk_lock); - if (of_property_read_u16(va_priv->dev->of_node, - "qcom,va-clk-mux-select", &mclk_mux_sel)) - dev_dbg(va_priv->dev, - "%s: could not find %s entry in dt, use default\n", - __func__, "qcom,va-clk-mux-select"); - if (mclk_mux_sel != MCLK_MUX0 && mclk_mux_sel != MCLK_MUX1) { - dev_err(va_priv->dev, "%s: mclk_mux_sel: %d is invalid\n", - __func__, mclk_mux_sel); - return -EINVAL; - } - if (mclk_enable) { if (va_priv->va_mclk_users == 0) { ret = bolero_request_clock(va_priv->dev, - VA_MACRO, mclk_mux_sel, true); + VA_MACRO, + va_priv->mclk_mux_sel, true); if (ret < 0) { dev_err(va_priv->dev, "%s: va request clock en failed\n", @@ -205,7 +196,8 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x00); bolero_request_clock(va_priv->dev, - VA_MACRO, mclk_mux_sel, false); + VA_MACRO, + va_priv->mclk_mux_sel, false); } } exit: @@ -289,7 +281,11 @@ static int va_macro_mclk_ctrl(struct device *dev, bool enable) dev_err(dev, "%s:va mclk enable failed\n", __func__); goto exit; } + if (va_priv->mclk_mux_sel == MCLK_MUX1) + iowrite32(0x1, va_priv->va_island_mode_muxsel); } else { + if (va_priv->mclk_mux_sel == MCLK_MUX1) + iowrite32(0x0, va_priv->va_island_mode_muxsel); clk_disable_unprepare(va_priv->va_core_clk); } @@ -1611,8 +1607,9 @@ static int va_macro_probe(struct platform_device *pdev) { struct macro_ops ops; struct va_macro_priv *va_priv; - u32 va_base_addr, sample_rate = 0; + u32 va_base_addr, sample_rate = 0, island_sel = 0; char __iomem *va_io_base; + char __iomem *va_muxsel_io = NULL; struct clk *va_core_clk; bool va_without_decimation = false; const char *micb_supply_str = "va-vdd-micb-supply"; @@ -1621,6 +1618,7 @@ static int va_macro_probe(struct platform_device *pdev) const char *micb_current_str = "qcom,va-vdd-micb-current"; int ret = 0; const char *dmic_sample_rate = "qcom,va-dmic-sample-rate"; + u16 mclk_mux_sel = MCLK_MUX0; va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv), GFP_KERNEL); @@ -1658,6 +1656,44 @@ static int va_macro_probe(struct platform_device *pdev) return -EINVAL; } va_priv->va_io_base = va_io_base; + + ret = of_property_read_u16(va_priv->dev->of_node, + "qcom,va-clk-mux-select", &mclk_mux_sel); + if (ret) { + dev_dbg(&pdev->dev, + "%s: could not find %s entry in dt, use default\n", + __func__, "qcom,va-clk-mux-select"); + } else { + if (mclk_mux_sel != MCLK_MUX0 && mclk_mux_sel != MCLK_MUX1) { + dev_err(&pdev->dev, + "%s: mclk_mux_sel: %d is invalid\n", + __func__, mclk_mux_sel); + return -EINVAL; + } + } + va_priv->mclk_mux_sel = mclk_mux_sel; + + if (va_priv->mclk_mux_sel == MCLK_MUX1) { + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,va-island-mode-muxsel", + &island_sel); + if (ret) { + dev_err(&pdev->dev, + "%s: could not find %s entry in dt\n", + __func__, "qcom,va-island-mode-muxsel"); + return ret; + } else { + va_muxsel_io = devm_ioremap(&pdev->dev, + island_sel, 0x4); + if (!va_muxsel_io) { + dev_err(&pdev->dev, + "%s: ioremap failed for island_sel\n", + __func__); + return -ENOMEM; + } + } + va_priv->va_island_mode_muxsel = va_muxsel_io; + } /* Register MCLK for va macro */ va_core_clk = devm_clk_get(&pdev->dev, "va_core_clk"); if (IS_ERR(va_core_clk)) { -- GitLab From e2db205a11a1956a9fbc960386572aca998109d3 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Wed, 12 Dec 2018 14:38:28 -0800 Subject: [PATCH 0778/1645] dsp: add voice MHI driver Add voice MHI driver to support the following features - 1. Allocate and map mailbox memory needed for voice call packet exchange. 2. Send memory mapped addresses to ADSP. 3. Vote MHI host driver at start and stop of a voice call. Change-Id: I8ef8bc270acacab9b80bca7addccdf73bd572adf Signed-off-by: Vikram Panduranga --- dsp/Kbuild | 4 + dsp/q6_init.c | 6 +- dsp/q6_init.h | 18 +- dsp/voice_mhi.c | 613 ++++++++++++++++++++++++++++++++++++++++ include/dsp/voice_mhi.h | 24 ++ 5 files changed, 661 insertions(+), 4 deletions(-) create mode 100644 dsp/voice_mhi.c create mode 100644 include/dsp/voice_mhi.h diff --git a/dsp/Kbuild b/dsp/Kbuild index 11e87c2068eb..195502a7e210 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -124,6 +124,10 @@ ifdef CONFIG_MSM_MDF Q6_OBJS += msm_mdf.o endif +ifdef CONFIG_VOICE_MHI + Q6_OBJS += voice_mhi.o +endif + LINUX_INC += -Iinclude/linux INCS += $(COMMON_INC) \ diff --git a/dsp/q6_init.c b/dsp/q6_init.c index e97a49692c7d..1078c5761c2b 100644 --- a/dsp/q6_init.c +++ b/dsp/q6_init.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017, The Linux Foundation. All rights reserved. -*/ + * Copyright (c) 2017, 2019 The Linux Foundation. All rights reserved. + */ #include #include @@ -22,6 +22,7 @@ static int __init audio_q6_init(void) audio_slimslave_init(); avtimer_init(); msm_mdf_init(); + voice_mhi_init(); return 0; } @@ -40,6 +41,7 @@ static void __exit audio_q6_exit(void) rtac_exit(); audio_cal_exit(); adsp_err_exit(); + voice_mhi_exit(); } module_init(audio_q6_init); diff --git a/dsp/q6_init.h b/dsp/q6_init.h index bd4ba399a34e..e7ad19b074b5 100644 --- a/dsp/q6_init.h +++ b/dsp/q6_init.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. -*/ + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + */ #ifndef __Q6_INIT_H__ #define __Q6_INIT_H__ @@ -54,5 +54,19 @@ static inline void audio_slimslave_exit(void) { }; #endif +#ifdef CONFIG_VOICE_MHI +int voice_mhi_init(void); +void voice_mhi_exit(void); +#else +static inline int voice_mhi_init(void) +{ + return 0; +} + +static inline void voice_mhi_exit(void) +{ + return; +} +#endif #endif diff --git a/dsp/voice_mhi.c b/dsp/voice_mhi.c new file mode 100644 index 000000000000..f1534c69bf63 --- /dev/null +++ b/dsp/voice_mhi.c @@ -0,0 +1,613 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "adsp_err.h" + +#define VSS_IPKTEXG_CMD_SET_MAILBOX_MEMORY_CONFIG 0x0001333B + +#define VOICE_MHI_STATE_SET(a, b) ((a) |= (1UL<<(b))) +#define VOICE_MHI_STATE_RESET(a, b) ((a) &= ~(1UL<<(b))) +#define VOICE_MHI_STATE_CHECK(a, b) (1UL & (a >> b)) + +#define CMD_STATUS_SUCCESS 0 +#define CMD_STATUS_FAIL 1 +#define TIMEOUT_MS 500 +#define PORT_NUM 0x01 +#define PORT_MASK 0x03 +#define CONVERT_PORT_APR(x, y) (x << 8 | y) + +enum voice_states { + VOICE_MHI_INIT = 0, + VOICE_MHI_PROBED = VOICE_MHI_INIT, + VOICE_MHI_ADSP_UP, + VOICE_MHI_SDX_UP, + VOICE_MHI_INCALL +}; + +struct voice_mhi_addr { + dma_addr_t base; + uint32_t size; +}; + +struct voice_mhi_dev_info { + struct platform_device *pdev; + struct voice_mhi_addr phys_addr; + struct voice_mhi_addr iova_pcie; + struct voice_mhi_addr iova_adsp; +}; + +struct voice_mhi { + struct voice_mhi_dev_info dev_info; + struct mhi_device *mhi_dev; + uint32_t vote_count; + struct mutex mutex; + enum voice_states voice_mhi_state; + bool vote_enable; + bool pcie_enabled; + void *apr_mvm_handle; + struct work_struct voice_mhi_work_pcie; + struct work_struct voice_mhi_work_adsp; + wait_queue_head_t voice_mhi_wait; + u32 mvm_state; + u32 async_err; +}; + +struct vss_ipktexg_cmd_set_mailbox_memory_config_t { + struct apr_hdr hdr; + uint64_t mailbox_mem_address_adsp; + /* + * IOVA of mailbox memory for ADSP access + */ + uint64_t mailbox_mem_address_pcie; + /* + * IOVA of mailbox memory for PCIe access + */ + uint32_t mem_size; + /* + * Size of mailbox memory allocated + */ +} __packed; + +static struct voice_mhi voice_mhi_lcl; + +static int voice_mhi_pcie_up_callback(struct mhi_device *, + const struct mhi_device_id *); +static void voice_mhi_pcie_down_callback(struct mhi_device *); +static void voice_mhi_pcie_status_callback(struct mhi_device *, enum MHI_CB); +static int32_t voice_mhi_apr_callback(struct apr_client_data *data, void *priv); +static int voice_mhi_notifier_service_cb(struct notifier_block *nb, + unsigned long opcode, void *ptr); +static int voice_mhi_apr_register(void); + +static struct notifier_block voice_mhi_service_nb = { + .notifier_call = voice_mhi_notifier_service_cb, + .priority = -INT_MAX, +}; + +static const struct mhi_device_id voice_mhi_match_table[] = { + { .chan = "AUDIO_VOICE_0", .driver_data = 0 }, + {}, +}; + +static struct mhi_driver voice_mhi_driver = { + .id_table = voice_mhi_match_table, + .probe = voice_mhi_pcie_up_callback, + .remove = voice_mhi_pcie_down_callback, + .status_cb = voice_mhi_pcie_status_callback, + .driver = { + .name = "voice_mhi_audio", + .owner = THIS_MODULE, + }, +}; + +static int voice_mhi_notifier_service_cb(struct notifier_block *nb, + unsigned long opcode, void *ptr) +{ + pr_debug("%s: opcode 0x%lx\n", __func__, opcode); + + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + if (voice_mhi_lcl.apr_mvm_handle) { + apr_reset(voice_mhi_lcl.apr_mvm_handle); + voice_mhi_lcl.apr_mvm_handle = NULL; + VOICE_MHI_STATE_RESET(voice_mhi_lcl.voice_mhi_state, + VOICE_MHI_ADSP_UP); + } + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (!VOICE_MHI_STATE_CHECK(voice_mhi_lcl.voice_mhi_state, + VOICE_MHI_ADSP_UP)) { + VOICE_MHI_STATE_SET(voice_mhi_lcl.voice_mhi_state, + VOICE_MHI_ADSP_UP); + schedule_work(&voice_mhi_lcl.voice_mhi_work_adsp); + } + break; + default: + break; + } + + return NOTIFY_OK; + +} + +static int32_t voice_mhi_apr_callback(struct apr_client_data *data, void *priv) +{ + uint32_t *ptr1; + + if (data == NULL) { + pr_err("%s: data is NULL\n", __func__); + return -EINVAL; + } + + pr_debug("%s: Payload Length = %d, opcode=%x\n", __func__, + data->payload_size, data->opcode); + + switch (data->opcode) { + case APR_BASIC_RSP_RESULT: + if (data->payload_size < 2 * sizeof(uint32_t)) { + pr_err("%s: APR_BASIC_RSP_RESULT payload less than expected\n", + __func__); + return 0; + } + ptr1 = data->payload; + switch (ptr1[0]) { + case VSS_IPKTEXG_CMD_SET_MAILBOX_MEMORY_CONFIG: + pr_debug("%s: cmd VSS_IPKTEXG_CMD_SET_MAILBOX_MEMORY_CONFIG\n", + __func__); + voice_mhi_lcl.mvm_state = CMD_STATUS_SUCCESS; + voice_mhi_lcl.async_err = ptr1[1]; + wake_up(&voice_mhi_lcl.voice_mhi_wait); + break; + default: + pr_err("%s: Invalid cmd response 0x%x 0x%x\n", __func__, + ptr1[0], ptr1[1]); + break; + } + break; + case APR_RSP_ACCEPTED: + if (data->payload_size < sizeof(uint32_t)) { + pr_err("%s: APR_RSP_ACCEPTED payload less than expected\n", + __func__); + return 0; + } + ptr1 = data->payload; + if (ptr1[0]) + pr_debug("%s: APR_RSP_ACCEPTED for 0x%x:\n", + __func__, ptr1[0]); + break; + case RESET_EVENTS: + /* Should we handle here or audio notifier down? */ + if (voice_mhi_lcl.apr_mvm_handle) { + apr_reset(voice_mhi_lcl.apr_mvm_handle); + voice_mhi_lcl.apr_mvm_handle = NULL; + VOICE_MHI_STATE_RESET(voice_mhi_lcl.voice_mhi_state, + VOICE_MHI_ADSP_UP); + } + break; + default: + pr_err("%s: Invalid opcode %d\n", __func__, + data->opcode); + break; + + } + return 0; +} + +/** + * voice_mhi_start - + * Start vote for MHI/PCIe clock + * + * Returns 0 on success or error on failure + */ +int voice_mhi_start(void) +{ + int ret = 0; + + mutex_lock(&voice_mhi_lcl.mutex); + if (voice_mhi_lcl.pcie_enabled) { + if (!voice_mhi_lcl.mhi_dev) { + pr_err("%s: NULL device found\n", __func__); + ret = -EINVAL; + goto done; + } + if (voice_mhi_lcl.vote_count == 0) { + ret = mhi_device_get_sync(voice_mhi_lcl.mhi_dev); + if (ret) { + pr_err("%s: mhi_device_get_sync failed\n", + __func__); + ret = -EINVAL; + goto done; + } + } + pr_debug("%s: mhi_device_get_sync success\n", __func__); + voice_mhi_lcl.vote_count++; + } else { + /* PCIe not supported - return success*/ + goto done; + } +done: + mutex_unlock(&voice_mhi_lcl.mutex); + + return ret; +} +EXPORT_SYMBOL(voice_mhi_start); + +/** + * voice_mhi_end - + * End vote for MHI/PCIe clock + * + * Returns 0 on success or error on failure + */ +int voice_mhi_end(void) +{ + mutex_lock(&voice_mhi_lcl.mutex); + if (voice_mhi_lcl.pcie_enabled) { + if (!voice_mhi_lcl.mhi_dev || voice_mhi_lcl.vote_count == 0) { + pr_err("%s: NULL device found\n", __func__); + mutex_unlock(&voice_mhi_lcl.mutex); + return -EINVAL; + } + + if (voice_mhi_lcl.vote_count == 1) + mhi_device_put(voice_mhi_lcl.mhi_dev); + voice_mhi_lcl.vote_count--; + } + mutex_unlock(&voice_mhi_lcl.mutex); + + return 0; +} +EXPORT_SYMBOL(voice_mhi_end); + +static int voice_mhi_set_mailbox_memory_config(void) +{ + struct vss_ipktexg_cmd_set_mailbox_memory_config_t mb_memory_config; + int ret = 0; + void *apr_mvm; + + if (!voice_mhi_lcl.apr_mvm_handle) { + pr_err("%s: APR handle is NULL\n", __func__); + return -EINVAL; + } + + memset(&mb_memory_config, 0, sizeof(mb_memory_config)); + mb_memory_config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + mb_memory_config.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(mb_memory_config) - APR_HDR_SIZE); + pr_debug("%s: pkt size = %d\n", __func__, + mb_memory_config.hdr.pkt_size); + + mutex_lock(&voice_mhi_lcl.mutex); + apr_mvm = voice_mhi_lcl.apr_mvm_handle; + + /* + * Handle can be NULL as it is not tied to any session + */ + mb_memory_config.hdr.src_port = CONVERT_PORT_APR(PORT_NUM, PORT_MASK); + mb_memory_config.hdr.dest_port = 0; + mb_memory_config.hdr.token = 0; + mb_memory_config.hdr.opcode = VSS_IPKTEXG_CMD_SET_MAILBOX_MEMORY_CONFIG; + mb_memory_config.mailbox_mem_address_pcie = + voice_mhi_lcl.dev_info.iova_pcie.base; + mb_memory_config.mailbox_mem_address_adsp = + voice_mhi_lcl.dev_info.iova_adsp.base; + mb_memory_config.mem_size = voice_mhi_lcl.dev_info.iova_adsp.size; + voice_mhi_lcl.mvm_state = CMD_STATUS_FAIL; + voice_mhi_lcl.async_err = 0; + + ret = apr_send_pkt(apr_mvm, (uint32_t *) &mb_memory_config); + if (ret < 0) { + pr_err("%s: Set mailbox memory config failed ret = %d\n", + __func__, ret); + goto unlock; + } + + ret = wait_event_timeout(voice_mhi_lcl.voice_mhi_wait, + (voice_mhi_lcl.mvm_state == + CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -ETIME; + goto unlock; + } + if (voice_mhi_lcl.async_err > 0) { + pr_err("%s: DSP returned error[%d]\n", + __func__, voice_mhi_lcl.async_err); + ret = voice_mhi_lcl.async_err; + goto unlock; + } + ret = 0; +unlock: + mutex_unlock(&voice_mhi_lcl.mutex); + return ret; +} + +static void voice_mhi_map_pcie_and_send(struct work_struct *work) +{ + dma_addr_t iova, phys_addr; + struct device *md; + + mutex_lock(&voice_mhi_lcl.mutex); + if (voice_mhi_lcl.mhi_dev) { + md = &voice_mhi_lcl.mhi_dev->dev; + } else { + pr_err("%s: MHI device handle is NULL\n", __func__); + goto err; + } + + phys_addr = voice_mhi_lcl.dev_info.phys_addr.base; + if (md) { + iova = dma_map_resource(md->parent, phys_addr, PAGE_SIZE, + DMA_BIDIRECTIONAL, 0); + if (dma_mapping_error(md->parent, iova)) { + pr_err("%s: dma_mapping_error\n", __func__); + goto err; + } + pr_debug("%s: dma_mapping_success iova:0x%lx\n", + __func__, (unsigned long)iova); + voice_mhi_lcl.dev_info.iova_pcie.base = iova; + + if (q6core_is_adsp_ready()) { + if (VOICE_MHI_STATE_CHECK(voice_mhi_lcl.voice_mhi_state, + VOICE_MHI_SDX_UP)) { + mutex_unlock(&voice_mhi_lcl.mutex); + voice_mhi_set_mailbox_memory_config(); + return; + } + } + } + +err: + mutex_unlock(&voice_mhi_lcl.mutex); +} + +static void voice_mhi_register_apr_and_send(struct work_struct *work) +{ + int ret = 0; + + ret = voice_mhi_apr_register(); + if (ret) { + pr_err("%s: APR registration failed %d\n", __func__, ret); + return; + } + mutex_lock(&voice_mhi_lcl.mutex); + if (q6core_is_adsp_ready()) { + if (VOICE_MHI_STATE_CHECK(voice_mhi_lcl.voice_mhi_state, + VOICE_MHI_SDX_UP)) { + mutex_unlock(&voice_mhi_lcl.mutex); + voice_mhi_set_mailbox_memory_config(); + return; + } + } + mutex_unlock(&voice_mhi_lcl.mutex); +} + +static int voice_mhi_pcie_up_callback(struct mhi_device *voice_mhi_dev, + const struct mhi_device_id *id) +{ + + if ((!voice_mhi_dev) || (id != &voice_mhi_match_table[0])) { + pr_err("%s: Invalid device or table received\n", __func__); + return -EINVAL; + } + pr_debug("%s: MHI PCIe UP callback\n", __func__); + mutex_lock(&voice_mhi_lcl.mutex); + voice_mhi_lcl.mhi_dev = voice_mhi_dev; + VOICE_MHI_STATE_SET(voice_mhi_lcl.voice_mhi_state, VOICE_MHI_SDX_UP); + mutex_unlock(&voice_mhi_lcl.mutex); + schedule_work(&voice_mhi_lcl.voice_mhi_work_pcie); + return 0; +} + +static void voice_mhi_pcie_down_callback(struct mhi_device *voice_mhi_dev) +{ + dma_addr_t iova; + struct device *md; + + mutex_lock(&voice_mhi_lcl.mutex); + + if (voice_mhi_lcl.mhi_dev) + md = &voice_mhi_lcl.mhi_dev->dev; + + VOICE_MHI_STATE_RESET(voice_mhi_lcl.voice_mhi_state, VOICE_MHI_SDX_UP); + iova = voice_mhi_lcl.dev_info.iova_pcie.base; + + if (md) + dma_unmap_resource(md->parent, iova, PAGE_SIZE, + DMA_BIDIRECTIONAL, 0); + + voice_mhi_lcl.mhi_dev = NULL; + mutex_unlock(&voice_mhi_lcl.mutex); +} + +static void voice_mhi_pcie_status_callback(struct mhi_device *voice_mhi_dev, + enum MHI_CB mhi_cb) +{ + +} + +static int voice_mhi_apr_register(void) +{ + int ret = 0; + + mutex_lock(&voice_mhi_lcl.mutex); + voice_mhi_lcl.apr_mvm_handle = apr_register("ADSP", "MVM", + (apr_fn)voice_mhi_apr_callback, + CONVERT_PORT_APR(PORT_NUM, + PORT_MASK), + &voice_mhi_lcl); + if (voice_mhi_lcl.apr_mvm_handle == NULL) { + pr_err("%s: error in APR register\n", __func__); + ret = -ENODEV; + } + mutex_unlock(&voice_mhi_lcl.mutex); + + return ret; +} + +static int voice_mhi_probe(struct platform_device *pdev) +{ + int ret = 0; + struct device_node *node; + uint32_t mem_size = 0; + void *ptr; + dma_addr_t phys_addr, iova; + const __be32 *cell; + + pr_debug("%s:\n", __func__); + + INIT_WORK(&voice_mhi_lcl.voice_mhi_work_pcie, + voice_mhi_map_pcie_and_send); + INIT_WORK(&voice_mhi_lcl.voice_mhi_work_adsp, + voice_mhi_register_apr_and_send); + init_waitqueue_head(&voice_mhi_lcl.voice_mhi_wait); + + node = of_parse_phandle(pdev->dev.of_node, "memory-region", 0); + if (node) { + cell = of_get_property(node, "size", NULL); + if (cell) + mem_size = of_read_number(cell, 2); + else { + pr_err("%s: cell not found\n", __func__); + ret = -EINVAL; + goto done; + } + } else { + pr_err("%s: Node read failed\n", __func__); + ret = -EINVAL; + goto done; + } + + pr_debug("%s: mem_size = %d\n", __func__, mem_size); + + if (mem_size) { + ptr = dma_alloc_attrs(&pdev->dev, mem_size, &phys_addr, + GFP_KERNEL, DMA_ATTR_NO_KERNEL_MAPPING); + if (IS_ERR_OR_NULL(ptr)) { + pr_err("%s: Memory alloc failed\n", __func__); + ret = -ENOMEM; + goto done; + } else { + pr_debug("%s: Memory alloc success phys_addr:0x%lx\n", + __func__, (unsigned long)phys_addr); + } + + ret = msm_audio_ion_dma_map(&phys_addr, &iova, mem_size, + DMA_BIDIRECTIONAL); + if (ret) { + pr_err("%s: dma mapping failed %d\n", __func__, ret); + goto err_free; + } + pr_debug("%s: dma_mapping_success iova:0x%lx\n", + __func__, (unsigned long)iova); + + voice_mhi_lcl.dev_info.phys_addr.base = phys_addr; + voice_mhi_lcl.dev_info.iova_adsp.base = iova; + voice_mhi_lcl.dev_info.iova_adsp.size = mem_size; + VOICE_MHI_STATE_SET(voice_mhi_lcl.voice_mhi_state, + VOICE_MHI_ADSP_UP); + + ret = voice_mhi_apr_register(); + /* If fails register during audio notifier UP event */ + if (ret) + pr_err("%s: APR register failed %d\n", __func__, ret); + ret = mhi_driver_register(&voice_mhi_driver); + if (ret) { + pr_err("%s: mhi register failed %d\n", __func__, ret); + goto done; + } + + ret = audio_notifier_register("voice_mhi", + AUDIO_NOTIFIER_ADSP_DOMAIN, + &voice_mhi_service_nb); + if (ret < 0) + pr_err("%s: Audio notifier register failed ret = %d\n", + __func__, ret); + + mutex_lock(&voice_mhi_lcl.mutex); + voice_mhi_lcl.dev_info.pdev = pdev; + voice_mhi_lcl.pcie_enabled = true; + VOICE_MHI_STATE_SET(voice_mhi_lcl.voice_mhi_state, + VOICE_MHI_PROBED); + mutex_unlock(&voice_mhi_lcl.mutex); + } else { + pr_err("%s: Memory size can't be zero\n", __func__); + ret = -ENOMEM; + goto done; + } + +done: + return ret; +err_free: + dma_free_attrs(&pdev->dev, mem_size, ptr, phys_addr, + DMA_ATTR_NO_KERNEL_MAPPING); + return ret; + +} + +static int voice_mhi_remove(struct platform_device *pdev) +{ + if (voice_mhi_lcl.apr_mvm_handle) + apr_reset(voice_mhi_lcl.apr_mvm_handle); + mhi_driver_unregister(&voice_mhi_driver); + memset(&voice_mhi_lcl, 0, sizeof(voice_mhi_lcl)); + return 0; +} +static const struct of_device_id voice_mhi_of_match[] = { + { .compatible = "qcom,voice-mhi-audio", }, + {}, +}; +static struct platform_driver voice_mhi_platform_driver = { + .probe = voice_mhi_probe, + .remove = voice_mhi_remove, + .driver = { + .name = "voice_mhi_audio", + .owner = THIS_MODULE, + .of_match_table = voice_mhi_of_match, + } +}; + +int __init voice_mhi_init(void) +{ + int ret = 0; + + memset(&voice_mhi_lcl, 0, sizeof(voice_mhi_lcl)); + mutex_init(&voice_mhi_lcl.mutex); + + /* Add remaining init here */ + voice_mhi_lcl.pcie_enabled = false; + voice_mhi_lcl.voice_mhi_state = VOICE_MHI_INIT; + voice_mhi_lcl.vote_count = 0; + voice_mhi_lcl.apr_mvm_handle = NULL; + ret = platform_driver_register(&voice_mhi_platform_driver); + + return ret; +} + +void __exit voice_mhi_exit(void) +{ + mutex_destroy(&voice_mhi_lcl.mutex); + platform_driver_unregister(&voice_mhi_platform_driver); +} + +MODULE_DESCRIPTION("Voice MHI module"); +MODULE_LICENSE("GPL v2"); diff --git a/include/dsp/voice_mhi.h b/include/dsp/voice_mhi.h new file mode 100644 index 000000000000..7cde32ae6242 --- /dev/null +++ b/include/dsp/voice_mhi.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#ifndef __VOICE_MHI_H__ +#define __VOICE_MHI_H__ + +#ifdef CONFIG_VOICE_MHI +int voice_mhi_start(void); +int voice_mhi_end(void); +#else +static inline int voice_mhi_start(void) +{ + return 0; +} + +static inline int voice_mhi_end(void) +{ + return 0; +} +#endif + +#endif -- GitLab From 335304e701153bba6ed8b612a2cff970ef54d657 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Fri, 25 Jan 2019 11:18:42 -0800 Subject: [PATCH 0779/1645] dsp: config: Add configuration for voice mhi driver Add and enable configuration for voice mhi driver for kona target. Change-Id: I43c28fbe26a5429f1a30b056ff96a9815acb3aa4 Signed-off-by: Vikram Panduranga --- config/konaauto.conf | 1 + config/konaautoconf.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config/konaauto.conf b/config/konaauto.conf index 328b67f8bdb0..34e5dd9ccbdd 100644 --- a/config/konaauto.conf +++ b/config/konaauto.conf @@ -34,3 +34,4 @@ CONFIG_SND_SOC_WCD938X=m CONFIG_SND_SOC_WCD938X_SLAVE=m CONFIG_SND_SOC_KONA=m CONFIG_SND_EVENT=m +CONFIG_VOICE_MHI=m diff --git a/config/konaautoconf.h b/config/konaautoconf.h index 4e6da4a0bee1..49eb428c7f2f 100644 --- a/config/konaautoconf.h +++ b/config/konaautoconf.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #define CONFIG_PINCTRL_WCD 1 @@ -38,3 +38,4 @@ #define CONFIG_SND_SOC_WCD938X_SLAVE 1 #define CONFIG_SND_SOC_KONA 1 #define CONFIG_SND_EVENT 1 +#define CONFIG_VOICE_MHI 1 -- GitLab From 7dbdc9aa69434a3bd834c191dd0135e9306516d6 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Mon, 7 Jan 2019 18:42:48 -0800 Subject: [PATCH 0780/1645] dsp: q6voice: call voice MHI start/end APIs Whenever a voice call starts or ends q6voice shall call voice_MHI API to enable or disable MHI voting respectively. Change-Id: Ia1125fb96c67ff6fec2242bc2b482ef7017dfb7d Signed-off-by: Vikram Panduranga --- dsp/q6voice.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 17746b1962fd..bb2bbdfa2992 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -22,6 +22,7 @@ #include #include #include "adsp_err.h" +#include #define TIMEOUT_MS 300 @@ -6809,6 +6810,11 @@ int voc_end_voice_call(uint32_t session_id) voc_update_session_params(v); voice_destroy_mvm_cvs_session(v); + + ret = voice_mhi_end(); + if (ret < 0) + pr_debug("%s: voice_mhi_end failed! %d\n", + __func__, ret); v->voc_state = VOC_RELEASE; } else { pr_err("%s: Error: End voice called in state %d\n", @@ -7144,6 +7150,13 @@ int voc_start_voice_call(uint32_t session_id) __func__, ret); } + ret = voice_mhi_start(); + if (ret < 0) { + pr_debug("%s: voice_mhi_start failed! %d\n", + __func__, ret); + goto fail; + } + ret = voice_create_mvm_cvs_session(v); if (ret < 0) { pr_err("create mvm and cvs failed\n"); -- GitLab From 51f7fa7f56e789a21125cf21a88708b4c035a6ac Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Tue, 29 Jan 2019 17:16:33 -0800 Subject: [PATCH 0781/1645] dsp: voice_mhi: fix memory size before mapping Mailbox memory was mapped with incorrect memory size. Adding a fix to use the actual size while mapping. Change-Id: If9a478ca044f68bed8e0899dfb023545585272f2 Signed-off-by: Vikram Panduranga --- dsp/voice_mhi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dsp/voice_mhi.c b/dsp/voice_mhi.c index f1534c69bf63..7f9cbfbe09a0 100644 --- a/dsp/voice_mhi.c +++ b/dsp/voice_mhi.c @@ -344,6 +344,7 @@ static int voice_mhi_set_mailbox_memory_config(void) static void voice_mhi_map_pcie_and_send(struct work_struct *work) { dma_addr_t iova, phys_addr; + uint32_t mem_size; struct device *md; mutex_lock(&voice_mhi_lcl.mutex); @@ -355,8 +356,9 @@ static void voice_mhi_map_pcie_and_send(struct work_struct *work) } phys_addr = voice_mhi_lcl.dev_info.phys_addr.base; + mem_size = voice_mhi_lcl.dev_info.iova_pcie.size; if (md) { - iova = dma_map_resource(md->parent, phys_addr, PAGE_SIZE, + iova = dma_map_resource(md->parent, phys_addr, mem_size, DMA_BIDIRECTIONAL, 0); if (dma_mapping_error(md->parent, iova)) { pr_err("%s: dma_mapping_error\n", __func__); @@ -523,6 +525,7 @@ static int voice_mhi_probe(struct platform_device *pdev) voice_mhi_lcl.dev_info.phys_addr.base = phys_addr; voice_mhi_lcl.dev_info.iova_adsp.base = iova; voice_mhi_lcl.dev_info.iova_adsp.size = mem_size; + voice_mhi_lcl.dev_info.iova_pcie.size = mem_size; VOICE_MHI_STATE_SET(voice_mhi_lcl.voice_mhi_state, VOICE_MHI_ADSP_UP); -- GitLab From ff649f9d7392b649da16e52a4a686323c0cea0ab Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 31 Jan 2019 22:54:19 +0530 Subject: [PATCH 0782/1645] ASoC: bolero: Enable clock Fs generation in bolero codec Clock Fs generation registers are in always on domain but is needed for all the playback and capture usecases. Enable clock Fs generation in the boloero codec after the clock enablement. Change-Id: I3a9cf14660f871b26ec96ef8b3e245ba5dadeb78 Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/bolero-cdc.c | 42 +++++++++++++++++++++++++++++++++ asoc/codecs/bolero/internal.h | 1 + asoc/codecs/bolero/va-macro.c | 18 -------------- 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 8092bb7cc533..85fa9e61b1a4 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -464,6 +464,46 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) } EXPORT_SYMBOL(bolero_unregister_macro); +static void bolero_fs_gen_enable(struct bolero_priv *priv, bool enable) +{ + if (enable) { + if (++priv->clk_users == 1) { + mutex_unlock(&priv->clk_lock); + regmap_update_bits(priv->regmap, + BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + regmap_update_bits(priv->regmap, + BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); + regmap_update_bits(priv->regmap, + BOLERO_CDC_VA_TOP_CSR_TOP_CFG0, + 0x02, 0x02); + mutex_lock(&priv->clk_lock); + } + } else { + if (priv->clk_users <= 0) { + dev_err(priv->dev, + "%s:clock already disabled\n", + __func__); + priv->clk_users = 0; + return; + } + if (--priv->clk_users == 0) { + mutex_unlock(&priv->clk_lock); + regmap_update_bits(priv->regmap, + BOLERO_CDC_VA_TOP_CSR_TOP_CFG0, + 0x02, 0x00); + regmap_update_bits(priv->regmap, + BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x00); + regmap_update_bits(priv->regmap, + BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x00); + mutex_lock(&priv->clk_lock); + } + } +} + /** * bolero_request_clock - request for clock enable/disable * @@ -510,6 +550,7 @@ int bolero_request_clock(struct device *dev, u16 macro_id, macro_id, mclk_mux0_macro); goto err; } + bolero_fs_gen_enable(priv, enable); break; case MCLK_MUX1: mclk_mux1_macro = bolero_mclk_mux_tbl[macro_id][MCLK_MUX1]; @@ -527,6 +568,7 @@ int bolero_request_clock(struct device *dev, u16 macro_id, if (enable) goto err; } + bolero_fs_gen_enable(priv, enable); /* * need different return value as ret variable * is used to track mclk_mux0 enable success or fail diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 909333420897..1e5651bae920 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -73,6 +73,7 @@ struct bolero_priv { struct wcd_ctrl_platform_data plat_data; struct device *wcd_dev; struct blocking_notifier_head notifier; + int clk_users; }; struct regmap *bolero_regmap_init(struct device *dev, diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index e89042e17e85..f8df0b7722f2 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -166,15 +166,6 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, regcache_sync_region(regmap, VA_START_OFFSET, VA_MAX_OFFSET); - regmap_update_bits(regmap, - BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, - 0x01, 0x01); - regmap_update_bits(regmap, - BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, - 0x01, 0x01); - regmap_update_bits(regmap, - BOLERO_CDC_VA_TOP_CSR_TOP_CFG0, - 0x02, 0x02); } va_priv->va_mclk_users++; } else { @@ -186,15 +177,6 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, } va_priv->va_mclk_users--; if (va_priv->va_mclk_users == 0) { - regmap_update_bits(regmap, - BOLERO_CDC_VA_TOP_CSR_TOP_CFG0, - 0x02, 0x00); - regmap_update_bits(regmap, - BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, - 0x01, 0x00); - regmap_update_bits(regmap, - BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, - 0x01, 0x00); bolero_request_clock(va_priv->dev, VA_MACRO, va_priv->mclk_mux_sel, false); -- GitLab From 17875f5c718175a6acac0f51c9dbbb03293e2cc8 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 1 Feb 2019 22:50:19 +0530 Subject: [PATCH 0783/1645] ASoC:kona: Add soundwire DMIC port configuration on kona Add soundwire DMIC port configuration on kona. This change will enable audio capture from WCD938x codec DMICs. Change-Id: I5b9e9a65f5bc021d4b19a838c17b56b3cb9eb4eb Signed-off-by: Sudheer Papothi --- asoc/sm8250-port-config.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/sm8250-port-config.h b/asoc/sm8250-port-config.h index 0f8c3c1b0722..a29f1065fbed 100644 --- a/asoc/sm8250-port-config.h +++ b/asoc/sm8250-port-config.h @@ -43,9 +43,11 @@ static struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = { /* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */ static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = { + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},/* PCM OUT */ {1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX1 */ {1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, /* TX2 */ {3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX3 */ + {3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, /* TX4 */ }; static struct swr_mstr_port_map sm_port_map[] = { -- GitLab From c61592adb3f0519d2a4dd8b3a4687a78b8663d11 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 7 Feb 2019 14:33:42 -0800 Subject: [PATCH 0784/1645] asoc: codecs: wcd938x: match slave property to dt Match the rx/tx slave node property to that of in dt to add slave components. Change-Id: Id990dc0c85691c4af8b8adb7f9de26063559b7b8 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/wcd938x.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 10a085b4298f..55d4c7998648 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -2632,8 +2632,8 @@ struct wcd938x_pdata *wcd938x_populate_dt_data(struct device *dev) return NULL; } - pdata->rx_slave = of_parse_phandle(dev->of_node, "qcom,rx-swr-slave", 0); - pdata->tx_slave = of_parse_phandle(dev->of_node, "qcom,tx-swr-slave", 0); + pdata->rx_slave = of_parse_phandle(dev->of_node, "qcom,rx-slave", 0); + pdata->tx_slave = of_parse_phandle(dev->of_node, "qcom,tx-slave", 0); wcd938x_dt_parse_micbias_info(dev, &pdata->micbias); @@ -2755,7 +2755,7 @@ static int wcd938x_add_slave_components(struct device *dev, np = dev->of_node; - rx_node = of_parse_phandle(np, "qcom,rx-swr-slave", 0); + rx_node = of_parse_phandle(np, "qcom,rx-slave", 0); if (!rx_node) { dev_err(dev, "%s: Rx-slave node not defined\n", __func__); return -ENODEV; @@ -2766,7 +2766,7 @@ static int wcd938x_add_slave_components(struct device *dev, wcd938x_compare_of, rx_node); - tx_node = of_parse_phandle(np, "qcom,tx-swr-slave", 0); + tx_node = of_parse_phandle(np, "qcom,tx-slave", 0); if (!tx_node) { dev_err(dev, "%s: Tx-slave node not defined\n", __func__); return -ENODEV; -- GitLab From 634fa7593f0b96ba83578a3a0b3f7aeb709763e0 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 7 Feb 2019 14:51:17 -0800 Subject: [PATCH 0785/1645] asoc: codecs: bolero: add split codec check Add a check to see if split codec is present for the slaves being probed and add platform data to such slaves. Change-Id: I8b143c551a481b88dffc8763421d2aaa02c0012d Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/bolero-cdc.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 8092bb7cc533..32a34fd898de 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -825,7 +825,7 @@ static const struct snd_soc_component_driver bolero = { static void bolero_add_child_devices(struct work_struct *work) { struct bolero_priv *priv; - bool wcd937x_node = false; + bool split_codec = false; struct platform_device *pdev; struct device_node *node; int ret = 0, count = 0; @@ -849,9 +849,12 @@ static void bolero_add_child_devices(struct work_struct *work) priv->child_count = 0; for_each_available_child_of_node(priv->dev->of_node, node) { - wcd937x_node = false; - if (strnstr(node->name, "wcd937x", strlen("wcd937x")) != NULL) - wcd937x_node = true; + split_codec = false; + if (of_find_property(node, "qcom,split-codec", NULL)) { + split_codec = true; + dev_dbg(priv->dev, "%s: split codec slave exists\n", + __func__); + } strlcpy(plat_dev_name, node->name, (BOLERO_CDC_STRING_LEN - 1)); @@ -866,7 +869,7 @@ static void bolero_add_child_devices(struct work_struct *work) pdev->dev.parent = priv->dev; pdev->dev.of_node = node; - if (wcd937x_node) { + if (split_codec) { priv->dev->platform_data = platdata; priv->wcd_dev = &pdev->dev; } -- GitLab From c2acbee6020655e1c4fe27a9309a51a664ad10f1 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 12 Feb 2019 08:26:49 +0800 Subject: [PATCH 0786/1645] dsp: update copyright marking for q6afecal-hwdep and q6asm Copyright year 2018 for q6afecal-hwdep and third party copyright marking for q6asm are removed during updating file headers. Add them back. Change-Id: I0341116ca0cf82be8c3876534b98ad2c376b3531 Signed-off-by: Meng Wang --- dsp/q6afecal-hwdep.c | 2 +- dsp/q6asm.c | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/dsp/q6afecal-hwdep.c b/dsp/q6afecal-hwdep.c index 0a040749d5a4..810634f57b95 100644 --- a/dsp/q6afecal-hwdep.c +++ b/dsp/q6afecal-hwdep.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015, 2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2015, 2017 - 2018, The Linux Foundation. All rights reserved. */ #include #include diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 300bdf2b4dd1..acdd75903db8 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1,6 +1,17 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Author: Brian Swetland + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * */ #include #include -- GitLab From 6f6f9a387f96ed50120d01998e753307f4aa46fa Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 29 Jan 2019 11:16:30 -0800 Subject: [PATCH 0787/1645] ASoC: config: add config to compile lpi TLMM drivers for kona Add config to compile audio low power island TLMM drivers for kona. Change-Id: I35a06ba826c1835cc8129acf3591c9fcf0a19214 Signed-off-by: Karthikeyan Mani --- config/konaauto.conf | 1 + config/konaautoconf.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config/konaauto.conf b/config/konaauto.conf index 328b67f8bdb0..b28b84a2c338 100644 --- a/config/konaauto.conf +++ b/config/konaauto.conf @@ -1,3 +1,4 @@ +CONFIG_PINCTRL_LPI=m CONFIG_PINCTRL_WCD=m CONFIG_AUDIO_EXT_CLK=m CONFIG_SND_SOC_WCD9XXX_V2=m diff --git a/config/konaautoconf.h b/config/konaautoconf.h index 4e6da4a0bee1..4b43c61382b4 100644 --- a/config/konaautoconf.h +++ b/config/konaautoconf.h @@ -1,7 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ +#define CONFIG_PINCTRL_LPI 1 #define CONFIG_PINCTRL_WCD 1 #define CONFIG_AUDIO_EXT_CLK 1 #define CONFIG_SND_SOC_WCD9XXX_V2 1 -- GitLab From fd328a6b660a8c222d972d68c1619c024d0bde3f Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 29 Jan 2019 11:18:33 -0800 Subject: [PATCH 0788/1645] soc: enable compilation for audio lpi driver Enable compilation of audio low power island driver for kona. Change-Id: I28adb30aa64204609667cedc1df5b181aa609267 Signed-off-by: Karthikeyan Mani --- soc/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/Android.mk b/soc/Android.mk index 8ce2c7515f7a..26f18e67affd 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -44,7 +44,7 @@ KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) KBUILD_OPTIONS += $(AUDIO_SELECT) ########################################################### -ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_lpi.ko LOCAL_MODULE_KBUILD_NAME := pinctrl_lpi_dlkm.ko -- GitLab From 0a7307c1804f7733e87daf36d665352896aa77b4 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Fri, 8 Feb 2019 13:08:13 -0800 Subject: [PATCH 0789/1645] dsp: voice_mhi: reset vote count at modem restart MHI devote is not required when modem restarts during a voice call, which results in PCIe down notification. Hence, vote count is reset to zero when modem restart is received. Change-Id: Ia2a7bb98f21d5130520489c8f2d20a04d41f03b4 Signed-off-by: Vikram Panduranga --- dsp/voice_mhi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dsp/voice_mhi.c b/dsp/voice_mhi.c index 7f9cbfbe09a0..6c8a7fc46fe3 100644 --- a/dsp/voice_mhi.c +++ b/dsp/voice_mhi.c @@ -235,8 +235,11 @@ int voice_mhi_start(void) ret = -EINVAL; goto done; } + pr_debug("%s: mhi_device_get_sync success\n", __func__); + } else { + /* For DSDA, no additional voting is needed */ + pr_debug("%s: mhi is already voted\n", __func__); } - pr_debug("%s: mhi_device_get_sync success\n", __func__); voice_mhi_lcl.vote_count++; } else { /* PCIe not supported - return success*/ @@ -438,6 +441,7 @@ static void voice_mhi_pcie_down_callback(struct mhi_device *voice_mhi_dev) DMA_BIDIRECTIONAL, 0); voice_mhi_lcl.mhi_dev = NULL; + voice_mhi_lcl.vote_count = 0; mutex_unlock(&voice_mhi_lcl.mutex); } -- GitLab From 1efdee5fd5f5b1b39d3635dc32ea072ffa9d7b01 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 8 Feb 2019 11:11:47 -0800 Subject: [PATCH 0790/1645] asoc: codecs: make cdc pinctrl common to all core objects cdc pinctrl needs to be loaded for both v1 and v2 wcd core objects. Change-Id: I4742e96b54bbd481583a6d12fd32fddb63216077 Signed-off-by: Karthikeyan Mani --- asoc/codecs/Kbuild | 1 + include/asoc/core.h | 117 ++++++++++++++++++++++++++++++++++++- include/asoc/wcd9xxx-irq.h | 55 ++++++++++++++++- 3 files changed, 171 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index a4cbc45d7505..a40c75f47e0e 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -87,6 +87,7 @@ ifdef CONFIG_WCD9XXX_CODEC_CORE endif ifdef CONFIG_WCD9XXX_CODEC_CORE_V2 + CORE_OBJS += wcd9xxx-core-init.o CORE_OBJS += msm-cdc-pinctrl.o CORE_OBJS += msm-cdc-supply.o endif diff --git a/include/asoc/core.h b/include/asoc/core.h index 8acfa26d863d..e4f04138ce8a 100644 --- a/include/asoc/core.h +++ b/include/asoc/core.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. */ #ifndef __MFD_TABLA_CORE_H__ @@ -374,6 +374,7 @@ struct wcd9xxx_reg_val { int bytes; /* number of bytes to be written */ }; +#ifdef CONFIG_WCD9XXX_CODEC_CORE int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg); int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg, u8 val); @@ -429,4 +430,118 @@ static inline int __init wcd9xxx_irq_of_init(struct device_node *node, int wcd9xxx_init(void); void wcd9xxx_exit(void); +#else +int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg) +{ + return 0; +} +int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg, + u8 val) +{ + return 0; +} +int wcd9xxx_get_logical_addresses(u8 *pgd_la, u8 *inf_la) +{ + return 0; +} +int wcd9xxx_slim_write_repeat(struct wcd9xxx *wcd9xxx, unsigned short reg, + int bytes, void *src) +{ + return 0; +} +int wcd9xxx_slim_reserve_bw(struct wcd9xxx *wcd9xxx, + u32 bw_ops, bool commit) +{ + return 0; +} +int wcd9xxx_set_power_state(struct wcd9xxx *wcd9xxx, enum codec_power_states + cdc_power_state, enum wcd_power_regions pwr_region) +{ + return 0; +} +int wcd9xxx_get_current_power_state(struct wcd9xxx *wcd9xxx, + enum wcd_power_regions pwr_region) +{ + return 0; +} + +int wcd9xxx_page_write(struct wcd9xxx *wcd9xxx, unsigned short *reg) +{ + return 0; +} + +int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx, + struct wcd9xxx_reg_val *bulk_reg, + unsigned int size, bool interface) +{ + return 0; +} + +extern int wcd9xxx_core_res_init( + struct wcd9xxx_core_resource *wcd9xxx_core_res, + int num_irqs, int num_irq_regs, struct regmap *wcd_regmap) +{ + return 0; +} + +extern void wcd9xxx_core_res_deinit( + struct wcd9xxx_core_resource *wcd9xxx_core_res) +{ +} + +extern int wcd9xxx_core_res_suspend( + struct wcd9xxx_core_resource *wcd9xxx_core_res, + pm_message_t pmesg) +{ + return 0; +} + +extern int wcd9xxx_core_res_resume( + struct wcd9xxx_core_resource *wcd9xxx_core_res) +{ + return 0; +} + +extern int wcd9xxx_core_irq_init( + struct wcd9xxx_core_resource *wcd9xxx_core_res) +{ + return 0; +} +extern int wcd9xxx_assign_irq(struct wcd9xxx_core_resource *wcd9xxx_core_res, + unsigned int irq, + unsigned int irq_base) +{ + return 0; +} + +extern enum wcd9xxx_intf_status wcd9xxx_get_intf_type(void) +{ + return 0; +} +extern void wcd9xxx_set_intf_type(enum wcd9xxx_intf_status int_state) +{ +} + +extern enum wcd9xxx_pm_state wcd9xxx_pm_cmpxchg( + struct wcd9xxx_core_resource *wcd9xxx_core_res, + enum wcd9xxx_pm_state o, + enum wcd9xxx_pm_state n) +{ + return 0; +} +static inline int __init wcd9xxx_irq_of_init(struct device_node *node, + struct device_node *parent) +{ + return 0; +} + +int wcd9xxx_init(void) +{ + return 0; +} +void wcd9xxx_exit(void) +{ +} + +#endif #endif diff --git a/include/asoc/wcd9xxx-irq.h b/include/asoc/wcd9xxx-irq.h index 2c7e7ec6352f..ff286c4b589a 100644 --- a/include/asoc/wcd9xxx-irq.h +++ b/include/asoc/wcd9xxx-irq.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, 2019, The Linux Foundation. All rights reserved. */ #include @@ -7,6 +7,7 @@ #ifndef __MFD_WCD9XXX_IRQ_H #define __MFD_WCD9XXX_IRQ_H +#ifdef CONFIG_WCD9XXX_CODEC_CORE bool wcd9xxx_lock_sleep(struct wcd9xxx_core_resource *wcd9xxx_res); void wcd9xxx_unlock_sleep(struct wcd9xxx_core_resource *wcd9xxx_res); void wcd9xxx_nested_irq_lock(struct wcd9xxx_core_resource *wcd9xxx_res); @@ -26,4 +27,56 @@ int wcd9xxx_irq_init(struct wcd9xxx_core_resource *wcd9xxx_res); void wcd9xxx_irq_exit(struct wcd9xxx_core_resource *wcd9xxx_res); int wcd9xxx_irq_drv_init(void); void wcd9xxx_irq_drv_exit(void); +#else +bool wcd9xxx_lock_sleep(struct wcd9xxx_core_resource *wcd9xxx_res) +{ + return false; +} +void wcd9xxx_unlock_sleep(struct wcd9xxx_core_resource *wcd9xxx_res) +{ +} +void wcd9xxx_nested_irq_lock(struct wcd9xxx_core_resource *wcd9xxx_res) +{ +} +void wcd9xxx_nested_irq_unlock(struct wcd9xxx_core_resource *wcd9xxx_res) +{ +} +int wcd9xxx_request_irq(struct wcd9xxx_core_resource *wcd9xxx_res, int irq, + irq_handler_t handler, const char *name, void *data) +{ + return 0; +} + +void wcd9xxx_free_irq(struct wcd9xxx_core_resource *wcd9xxx_res, + int irq, void *data) +{ +} +void wcd9xxx_enable_irq(struct wcd9xxx_core_resource *wcd9xxx_res, int irq) +{ +} +void wcd9xxx_disable_irq(struct wcd9xxx_core_resource *wcd9xxx_res, + int irq) +{ +} +void wcd9xxx_disable_irq_sync(struct wcd9xxx_core_resource *wcd9xxx_res, + int irq) +{ +} + +int wcd9xxx_irq_init(struct wcd9xxx_core_resource *wcd9xxx_res) +{ + return 0; +} +void wcd9xxx_irq_exit(struct wcd9xxx_core_resource *wcd9xxx_res) +{ +} +int wcd9xxx_irq_drv_init(void) +{ + return 0; +} + +void wcd9xxx_irq_drv_exit(void) +{ +} +#endif #endif -- GitLab From fbdcab9e8db7ccd9c6dd75b0d7c6c3d2427cc47f Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 13 Feb 2019 17:15:15 -0800 Subject: [PATCH 0791/1645] asoc: codecs: wcd938x: enable micbias for capture Micbias needs tx bias clock bit to be enabled. Change-Id: I6a73d05eb9363c3dce267f6730c44b0442387365 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/wcd938x.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 10a085b4298f..c0f0d05f457f 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1397,12 +1397,16 @@ int wcd938x_micbias_control(struct snd_soc_component *component, WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0xE0, 0xE0); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_ANA_TX_CLK_CTL, 0x01, 0x01); snd_soc_component_update_bits(component, WCD938X_MICB1_TEST_CTL_2, 0x01, 0x01); snd_soc_component_update_bits(component, WCD938X_MICB2_TEST_CTL_2, 0x01, 0x01); snd_soc_component_update_bits(component, WCD938X_MICB3_TEST_CTL_2, 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD938X_MICB4_TEST_CTL_2, 0x01, 0x01); snd_soc_component_update_bits(component, micb_reg, 0xC0, 0x40); if (post_on_event) -- GitLab From 09b5461237c395c56c1f50ed9a35019b967bc831 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 15 Feb 2019 11:00:41 -0800 Subject: [PATCH 0792/1645] asoc: codecs: wcd938x: remove on demand vdd buck All codec supplies are treated as static supplies and do not require on demand supply. Change-Id: Idf54f65cc6089675e21a52ea49cdf46eae98f295 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/wcd938x.c | 61 ----------------------------------- 1 file changed, 61 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 10a085b4298f..00c3d4bbdce4 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1682,60 +1682,6 @@ static int wcd938x_set_compander(struct snd_kcontrol *kcontrol, return 0; } -static int wcd938x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_component *component = - snd_soc_dapm_to_component(w->dapm); - struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); - struct wcd938x_pdata *pdata = NULL; - int ret = 0; - - pdata = dev_get_platdata(wcd938x->dev); - - if (!pdata) { - dev_err(component->dev, "%s: pdata is NULL\n", __func__); - return -EINVAL; - } - - dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, - w->name, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - ret = msm_cdc_enable_ondemand_supply(wcd938x->dev, - wcd938x->supplies, - pdata->regulator, - pdata->num_supplies, - "cdc-vdd-buck"); - if (ret == -EINVAL) { - dev_err(component->dev, "%s: vdd buck is not enabled\n", - __func__); - return ret; - } - /* - * 200us sleep is required after LDO15 is enabled as per - * HW requirement - */ - usleep_range(200, 250); - break; - case SND_SOC_DAPM_POST_PMD: - ret = msm_cdc_disable_ondemand_supply(wcd938x->dev, - wcd938x->supplies, - pdata->regulator, - pdata->num_supplies, - "cdc-vdd-buck"); - if (ret == -EINVAL) { - dev_err(component->dev, "%s: vdd buck is not disabled\n", - __func__); - return 0; - } - break; - } - return 0; -} - static int wcd938x_tx_hdr_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2085,10 +2031,6 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY("VDD_BUCK", SND_SOC_NOPM, 0, 0, - wcd938x_codec_enable_vdd_buck, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY_S("CLS_H_PORT", 1, SND_SOC_NOPM, 0, 0, wcd938x_enable_clsh, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -2224,7 +2166,6 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = { {"DMIC8_OUTPUT", NULL, "DMIC8_MIXER"}, {"DMIC8_MIXER", "Switch", "DMIC8"}, - {"IN1_HPHL", NULL, "VDD_BUCK"}, {"IN1_HPHL", NULL, "CLS_H_PORT"}, {"RX1", NULL, "IN1_HPHL"}, {"RDAC1", NULL, "RX1"}, @@ -2232,7 +2173,6 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = { {"HPHL PGA", NULL, "HPHL_RDAC"}, {"HPHL", NULL, "HPHL PGA"}, - {"IN2_HPHR", NULL, "VDD_BUCK"}, {"IN2_HPHR", NULL, "CLS_H_PORT"}, {"RX2", NULL, "IN2_HPHR"}, {"RDAC2", NULL, "RX2"}, @@ -2240,7 +2180,6 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = { {"HPHR PGA", NULL, "HPHR_RDAC"}, {"HPHR", NULL, "HPHR PGA"}, - {"IN3_AUX", NULL, "VDD_BUCK"}, {"IN3_AUX", NULL, "CLS_H_PORT"}, {"RX3", NULL, "IN3_AUX"}, {"RDAC4", NULL, "RX3"}, -- GitLab From 1475b5915bc85ac5fc92e216c285e3fbb847a9d4 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 12 Feb 2019 21:27:58 -0800 Subject: [PATCH 0793/1645] asoc: codecs: bolero: update mic paths Add all combination of routes between adc and available mic paths. Change-Id: If5781509bdc667d94ca1ad991388a8d57af75b94 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/tx-macro.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index ec5616672210..b24721fea806 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -950,7 +950,7 @@ TX_MACRO_DAPM_ENUM_EXT(tx_dmic7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0, tx_macro_put_dec_enum); static const char * const smic_mux_text[] = { - "ZERO", "ADC0", "ADC1", "ADC2", "ADC3", + "ZERO", "ADC0", "ADC1", "ADC2", "ADC3", "ADC4", "SWR_DMIC0", "SWR_DMIC1", "SWR_DMIC2", "SWR_DMIC3", "SWR_DMIC4", "SWR_DMIC5", "SWR_DMIC6", "SWR_DMIC7" }; @@ -1096,6 +1096,7 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = { SND_SOC_DAPM_INPUT("TX SWR_ADC1"), SND_SOC_DAPM_INPUT("TX SWR_ADC2"), SND_SOC_DAPM_INPUT("TX SWR_ADC3"), + SND_SOC_DAPM_INPUT("TX SWR_ADC4"), SND_SOC_DAPM_INPUT("TX SWR_DMIC0"), SND_SOC_DAPM_INPUT("TX SWR_DMIC1"), SND_SOC_DAPM_INPUT("TX SWR_DMIC2"), @@ -1206,6 +1207,7 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX0", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX0", "ADC2", "TX SWR_ADC2"}, {"TX SMIC MUX0", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX0", "ADC4", "TX SWR_ADC4"}, {"TX SMIC MUX0", "SWR_DMIC0", "TX SWR_DMIC0"}, {"TX SMIC MUX0", "SWR_DMIC1", "TX SWR_DMIC1"}, {"TX SMIC MUX0", "SWR_DMIC2", "TX SWR_DMIC2"}, @@ -1230,6 +1232,7 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX1", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX1", "ADC2", "TX SWR_ADC2"}, {"TX SMIC MUX1", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX1", "ADC4", "TX SWR_ADC4"}, {"TX SMIC MUX1", "SWR_DMIC0", "TX SWR_DMIC0"}, {"TX SMIC MUX1", "SWR_DMIC1", "TX SWR_DMIC1"}, {"TX SMIC MUX1", "SWR_DMIC2", "TX SWR_DMIC2"}, @@ -1254,6 +1257,7 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX2", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX2", "ADC2", "TX SWR_ADC2"}, {"TX SMIC MUX2", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX2", "ADC4", "TX SWR_ADC4"}, {"TX SMIC MUX2", "SWR_DMIC0", "TX SWR_DMIC0"}, {"TX SMIC MUX2", "SWR_DMIC1", "TX SWR_DMIC1"}, {"TX SMIC MUX2", "SWR_DMIC2", "TX SWR_DMIC2"}, @@ -1278,6 +1282,7 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX3", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX3", "ADC2", "TX SWR_ADC2"}, {"TX SMIC MUX3", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX3", "ADC4", "TX SWR_ADC4"}, {"TX SMIC MUX3", "SWR_DMIC0", "TX SWR_DMIC0"}, {"TX SMIC MUX3", "SWR_DMIC1", "TX SWR_DMIC1"}, {"TX SMIC MUX3", "SWR_DMIC2", "TX SWR_DMIC2"}, @@ -1302,6 +1307,7 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX4", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX4", "ADC2", "TX SWR_ADC2"}, {"TX SMIC MUX4", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX4", "ADC4", "TX SWR_ADC4"}, {"TX SMIC MUX4", "SWR_DMIC0", "TX SWR_DMIC0"}, {"TX SMIC MUX4", "SWR_DMIC1", "TX SWR_DMIC1"}, {"TX SMIC MUX4", "SWR_DMIC2", "TX SWR_DMIC2"}, @@ -1326,6 +1332,7 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX5", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX5", "ADC2", "TX SWR_ADC2"}, {"TX SMIC MUX5", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX5", "ADC4", "TX SWR_ADC4"}, {"TX SMIC MUX5", "SWR_DMIC0", "TX SWR_DMIC0"}, {"TX SMIC MUX5", "SWR_DMIC1", "TX SWR_DMIC1"}, {"TX SMIC MUX5", "SWR_DMIC2", "TX SWR_DMIC2"}, @@ -1350,6 +1357,7 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX6", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX6", "ADC2", "TX SWR_ADC2"}, {"TX SMIC MUX6", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX6", "ADC4", "TX SWR_ADC4"}, {"TX SMIC MUX6", "SWR_DMIC0", "TX SWR_DMIC0"}, {"TX SMIC MUX6", "SWR_DMIC1", "TX SWR_DMIC1"}, {"TX SMIC MUX6", "SWR_DMIC2", "TX SWR_DMIC2"}, @@ -1374,6 +1382,7 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX7", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX7", "ADC2", "TX SWR_ADC2"}, {"TX SMIC MUX7", "ADC3", "TX SWR_ADC3"}, + {"TX SMIC MUX7", "ADC4", "TX SWR_ADC4"}, {"TX SMIC MUX7", "SWR_DMIC0", "TX SWR_DMIC0"}, {"TX SMIC MUX7", "SWR_DMIC1", "TX SWR_DMIC1"}, {"TX SMIC MUX7", "SWR_DMIC2", "TX SWR_DMIC2"}, @@ -1581,6 +1590,7 @@ static int tx_macro_init(struct snd_soc_component *component) snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC1"); snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC2"); snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC3"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC4"); snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC0"); snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC1"); snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC2"); -- GitLab From 92fccbfd8f2ee52f88f74c01c38003dbc9bae684 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 12 Feb 2019 21:33:01 -0800 Subject: [PATCH 0794/1645] asoc: codecs: wcd938x: update tx mode setting Change tx mode setting from dapm widget to kcontrol as it is not needed in codec route and only needed for updating mode value. Change-Id: I5d66b9a82b541b97f5c5789fe2e49d329c6952a8 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/wcd938x.c | 119 ++++++++++++++++++++++------------ 1 file changed, 79 insertions(+), 40 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 10a085b4298f..a8602c1c162e 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -37,20 +37,6 @@ #define ADC_MODE_VAL_ULP1 0x09 #define ADC_MODE_VAL_ULP2 0x0B -#define STRING(name) #name -#define WCD_DAPM_ENUM(name, reg, offset, text) \ -static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ -static const struct snd_kcontrol_new name##_mux = \ - SOC_DAPM_ENUM(STRING(name), name##_enum) - -#define WCD_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \ -static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \ -static const struct snd_kcontrol_new name##_mux = \ - SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname) - -#define WCD_DAPM_MUX(name, shift, kctl) \ - SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux) - enum { WCD9380 = 0, WCD9385, @@ -175,6 +161,8 @@ static int wcd938x_init_reg(struct snd_soc_component *component) 0x1F, 0x15); snd_soc_component_update_bits(component, WCD938X_HPH_REFBUFF_UHQA_CTL, 0xC0, 0x80); + snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_DMIC_CTL, + 0x02, 0x02); return 0; } @@ -1582,6 +1570,46 @@ static int wcd938x_codec_enable_micbias(struct snd_soc_dapm_widget *w, return __wcd938x_codec_enable_micbias(w, event); } +static inline int wcd938x_tx_path_get(const char *wname) +{ + int ret = 0; + unsigned int path_num; + char *widget_name = NULL; + char *w_name = NULL; + char *path_num_char = NULL; + char *path_name = NULL; + + widget_name = kstrndup(wname, 9, GFP_KERNEL); + if (!widget_name) + return -EINVAL; + + w_name = widget_name; + + path_name = strsep(&widget_name, " "); + if (!path_name) { + pr_err("%s: Invalid widget name = %s\n", + __func__, widget_name); + ret = -EINVAL; + goto err; + } + path_name = widget_name; + path_num_char = strpbrk(path_name, "0123"); + if (!path_num_char) { + pr_err("%s: tx path index not found\n", + __func__); + ret = -EINVAL; + goto err; + } + ret = kstrtouint(path_num_char, 10, &path_num); + if (ret < 0) + pr_err("%s: Invalid tx path = %s\n", + __func__, w_name); + +err: + kfree(w_name); + return ret; +} + static int wcd938x_tx_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1590,8 +1618,15 @@ static int wcd938x_tx_mode_get(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + u32 path = 0; + + if (!widget || !widget->name || !wcd938x || !component) + return -EINVAL; + + path = wcd938x_tx_path_get(widget->name); + + ucontrol->value.integer.value[0] = wcd938x->tx_mode[path]; - ucontrol->value.integer.value[0] = wcd938x->tx_mode[widget->shift]; return 0; } @@ -1604,12 +1639,18 @@ static int wcd938x_tx_mode_put(struct snd_kcontrol *kcontrol, snd_soc_kcontrol_component(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); u32 mode_val; + u32 path = 0; + + if (!widget || !widget->name || !wcd938x || !component) + return -EINVAL; + path = wcd938x_tx_path_get(widget->name); mode_val = ucontrol->value.enumerated.item[0]; dev_dbg(component->dev, "%s: mode: %d\n", __func__, mode_val); - wcd938x->tx_mode[widget->shift] = mode_val; + wcd938x->tx_mode[path] = mode_val; + return 0; } @@ -1790,14 +1831,9 @@ static const char * const tx_mode_mux_text[] = { "ADC_ULP1", "ADC_ULP2", }; -WCD_DAPM_ENUM_EXT(tx0_mode, SND_SOC_NOPM, 0, tx_mode_mux_text, - wcd938x_tx_mode_get, wcd938x_tx_mode_put); -WCD_DAPM_ENUM_EXT(tx1_mode, SND_SOC_NOPM, 1, tx_mode_mux_text, - wcd938x_tx_mode_get, wcd938x_tx_mode_put); -WCD_DAPM_ENUM_EXT(tx2_mode, SND_SOC_NOPM, 2, tx_mode_mux_text, - wcd938x_tx_mode_get, wcd938x_tx_mode_put); -WCD_DAPM_ENUM_EXT(tx3_mode, SND_SOC_NOPM, 3, tx_mode_mux_text, - wcd938x_tx_mode_get, wcd938x_tx_mode_put); +static const struct soc_enum tx_mode_mux_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tx_mode_mux_text), + tx_mode_mux_text); static const char * const rx_hph_mode_mux_text[] = { "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI", @@ -1812,6 +1848,15 @@ static const struct snd_kcontrol_new wcd938x_snd_controls[] = { SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum, wcd938x_rx_hph_mode_get, wcd938x_rx_hph_mode_put), + SOC_ENUM_EXT("TX0 MODE", tx_mode_mux_enum, + wcd938x_tx_mode_get, wcd938x_tx_mode_put), + SOC_ENUM_EXT("TX1 MODE", tx_mode_mux_enum, + wcd938x_tx_mode_get, wcd938x_tx_mode_put), + SOC_ENUM_EXT("TX2 MODE", tx_mode_mux_enum, + wcd938x_tx_mode_get, wcd938x_tx_mode_put), + SOC_ENUM_EXT("TX3 MODE", tx_mode_mux_enum, + wcd938x_tx_mode_get, wcd938x_tx_mode_put), + SOC_SINGLE_EXT("HPHL_COMP Switch", SND_SOC_NOPM, 0, 1, 0, wcd938x_get_compander, wcd938x_set_compander), SOC_SINGLE_EXT("HPHR_COMP Switch", SND_SOC_NOPM, 1, 1, 0, @@ -1961,37 +2006,37 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = { SND_SOC_DAPM_ADC_E("ADC1", NULL, SND_SOC_NOPM, 0, 0, wcd938x_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("ADC2", NULL, SND_SOC_NOPM, 0, 1, + SND_SOC_DAPM_ADC_E("ADC2", NULL, SND_SOC_NOPM, 1, 0, wcd938x_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("ADC3", NULL, SND_SOC_NOPM, 0, 2, + SND_SOC_DAPM_ADC_E("ADC3", NULL, SND_SOC_NOPM, 2, 0, wcd938x_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("ADC4", NULL, SND_SOC_NOPM, 0, 3, + SND_SOC_DAPM_ADC_E("ADC4", NULL, SND_SOC_NOPM, 3, 0, wcd938x_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0, wcd938x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 1, + SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 1, 0, wcd938x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 2, + SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 2, 0, wcd938x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 3, + SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 3, 0, wcd938x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 4, + SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 4, 0, wcd938x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 0, 5, + SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 5, 0, wcd938x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC7", NULL, SND_SOC_NOPM, 0, 6, + SND_SOC_DAPM_ADC_E("DMIC7", NULL, SND_SOC_NOPM, 6, 0, wcd938x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("DMIC8", NULL, SND_SOC_NOPM, 0, 7, + SND_SOC_DAPM_ADC_E("DMIC8", NULL, SND_SOC_NOPM, 7, 0, wcd938x_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -2014,12 +2059,6 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = { &tx_adc3_mux), SND_SOC_DAPM_MUX("ADC4 MUX", SND_SOC_NOPM, 0, 0, &tx_adc4_mux), - - WCD_DAPM_MUX("TX0 MODE", 0, tx0_mode), - WCD_DAPM_MUX("TX1 MODE", 1, tx1_mode), - WCD_DAPM_MUX("TX2 MODE", 2, tx2_mode), - WCD_DAPM_MUX("TX3 MODE", 3, tx3_mode), - /*tx mixers*/ SND_SOC_DAPM_MIXER_E("ADC1_MIXER", SND_SOC_NOPM, 0, 0, adc1_switch, ARRAY_SIZE(adc1_switch), -- GitLab From c0a8adf3658e5cfce6230c23a673161148def407 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 15 Feb 2019 17:25:36 -0800 Subject: [PATCH 0795/1645] asoc: codecs: wcd938x: disable pm runtime Soundwire master receives the pm runtime calls, so slave does not need to enable pm runtime. Change-Id: I3e09b9d1eee9bbfbe525fbf375bf938600f30064 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/wcd938x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 10a085b4298f..4fe033c65505 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -118,7 +118,7 @@ static struct regmap_irq_chip wcd938x_regmap_irq_chip = { .type_base = WCD938X_DIGITAL_INTR_LEVEL_0, .ack_base = WCD938X_DIGITAL_INTR_CLEAR_0, .use_ack = 1, - .runtime_pm = true, + .runtime_pm = false, .handle_post_irq = wcd938x_handle_post_irq, .irq_drv_data = NULL, }; -- GitLab From 1a111b965aa87292d9702140e78f7f53b4c33275 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 12 Feb 2019 21:35:31 -0800 Subject: [PATCH 0796/1645] asoc: msm: remove codec specific checks for kona Add dapm widget for all analog mics, remove bolero and mtp specific checks from probe. Change-Id: Ibaa81fb9a655c3d0f48b95d2e882b5fecf6adb73 Signed-off-by: Karthikeyan Mani --- asoc/kona.c | 142 +++++++++++++++++++++++++--------------------------- 1 file changed, 67 insertions(+), 75 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index 1c68a986c02f..b34b80afc18d 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -3798,6 +3798,7 @@ static const struct snd_soc_dapm_widget msm_int_dapm_widgets[] = { SND_SOC_DAPM_MIC("Analog Mic2", NULL), SND_SOC_DAPM_MIC("Analog Mic3", NULL), SND_SOC_DAPM_MIC("Analog Mic4", NULL), + SND_SOC_DAPM_MIC("Analog Mic5", NULL), SND_SOC_DAPM_MIC("Digital Mic0", msm_dmic_event), SND_SOC_DAPM_MIC("Digital Mic1", msm_dmic_event), SND_SOC_DAPM_MIC("Digital Mic2", msm_dmic_event), @@ -3863,6 +3864,7 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_ignore_suspend(dapm, "Analog Mic2"); snd_soc_dapm_ignore_suspend(dapm, "Analog Mic3"); snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic5"); snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK1 OUT"); snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK2 OUT"); @@ -5650,7 +5652,6 @@ static int msm_init_aux_dev(struct platform_device *pdev, u32 wsa_max_devs; u32 wsa_dev_cnt; u32 codec_aux_dev_cnt = 0; - u32 bolero_codec = 0; int i; struct msm_wsa881x_dev_info *wsa881x_dev_info; struct aux_codec_dev_info *aux_cdc_dev_info; @@ -5765,76 +5766,69 @@ static int msm_init_aux_dev(struct platform_device *pdev, __func__, found); codec_aux_dev: - ret = of_property_read_u32(pdev->dev.of_node, "qcom,bolero-codec", &bolero_codec); - if (ret) - dev_dbg(&pdev->dev, "%s: No DT match for bolero codec\n", __func__); - - if (bolero_codec) { - /* Get count of aux codec device phandles for this platform */ - codec_aux_dev_cnt = of_count_phandle_with_args( - pdev->dev.of_node, - "qcom,codec-aux-devs", NULL); - if (codec_aux_dev_cnt == -ENOENT) { - dev_warn(&pdev->dev, "%s: No aux codec defined in DT.\n", - __func__); - goto err; - } else if (codec_aux_dev_cnt <= 0) { + /* Get count of aux codec device phandles for this platform */ + codec_aux_dev_cnt = of_count_phandle_with_args( + pdev->dev.of_node, + "qcom,codec-aux-devs", NULL); + if (codec_aux_dev_cnt == -ENOENT) { + dev_warn(&pdev->dev, "%s: No aux codec defined in DT.\n", + __func__); + goto err; + } else if (codec_aux_dev_cnt <= 0) { + dev_err(&pdev->dev, + "%s: Error reading aux codec device from DT, dev_cnt=%d\n", + __func__, codec_aux_dev_cnt); + ret = -EINVAL; + goto err; + } + + /* + * Alloc mem to store phandle and index info of aux codec + * if already registered with ALSA core + */ + aux_cdc_dev_info = devm_kcalloc(&pdev->dev, codec_aux_dev_cnt, + sizeof(struct aux_codec_dev_info), + GFP_KERNEL); + if (!aux_cdc_dev_info) { + ret = -ENOMEM; + goto err; + } + + /* + * search and check whether all aux codecs are already + * registered with ALSA core or not. If found a node, store + * the node and the index in a local array of struct for later + * use. + */ + for (i = 0; i < codec_aux_dev_cnt; i++) { + aux_codec_of_node = of_parse_phandle(pdev->dev.of_node, + "qcom,codec-aux-devs", i); + if (unlikely(!aux_codec_of_node)) { + /* we should not be here */ dev_err(&pdev->dev, - "%s: Error reading aux codec device from DT, dev_cnt=%d\n", - __func__, codec_aux_dev_cnt); + "%s: aux codec dev node is not present\n", + __func__); ret = -EINVAL; goto err; } - - /* - * Alloc mem to store phandle and index info of aux codec - * if already registered with ALSA core - */ - aux_cdc_dev_info = devm_kcalloc(&pdev->dev, codec_aux_dev_cnt, - sizeof(struct aux_codec_dev_info), - GFP_KERNEL); - if (!aux_cdc_dev_info) { - ret = -ENOMEM; - goto err; - } - - /* - * search and check whether all aux codecs are already - * registered with ALSA core or not. If found a node, store - * the node and the index in a local array of struct for later - * use. - */ - for (i = 0; i < codec_aux_dev_cnt; i++) { - aux_codec_of_node = of_parse_phandle(pdev->dev.of_node, - "qcom,codec-aux-devs", i); - if (unlikely(!aux_codec_of_node)) { - /* we should not be here */ - dev_err(&pdev->dev, - "%s: aux codec dev node is not present\n", - __func__); - ret = -EINVAL; - goto err; - } - if (soc_find_component(aux_codec_of_node, NULL)) { - /* AUX codec registered with ALSA core */ - aux_cdc_dev_info[codecs_found].of_node = - aux_codec_of_node; - aux_cdc_dev_info[codecs_found].index = i; - codecs_found++; - } - } - - if (codecs_found < codec_aux_dev_cnt) { - dev_dbg(&pdev->dev, - "%s: failed to find %d components. Found only %d\n", - __func__, codec_aux_dev_cnt, codecs_found); - return -EPROBE_DEFER; + if (soc_find_component(aux_codec_of_node, NULL)) { + /* AUX codec registered with ALSA core */ + aux_cdc_dev_info[codecs_found].of_node = + aux_codec_of_node; + aux_cdc_dev_info[codecs_found].index = i; + codecs_found++; } - dev_info(&pdev->dev, - "%s: found %d AUX codecs registered with ALSA core\n", - __func__, codecs_found); + } + if (codecs_found < codec_aux_dev_cnt) { + dev_dbg(&pdev->dev, + "%s: failed to find %d components. Found only %d\n", + __func__, codec_aux_dev_cnt, codecs_found); + return -EPROBE_DEFER; } + dev_info(&pdev->dev, + "%s: found %d AUX codecs registered with ALSA core\n", + __func__, codecs_found); card->num_aux_devs = wsa_max_devs + codec_aux_dev_cnt; card->num_configs = wsa_max_devs + codec_aux_dev_cnt; @@ -6145,17 +6139,15 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) } msm_i2s_auxpcm_init(pdev); - if (strcmp(card->name, "kona-mtp-snd-card")) { - pdata->dmic01_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,cdc-dmic01-gpios", - 0); - pdata->dmic23_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,cdc-dmic23-gpios", - 0); - pdata->dmic45_gpio_p = of_parse_phandle(pdev->dev.of_node, - "qcom,cdc-dmic45-gpios", - 0); - } + pdata->dmic01_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-dmic01-gpios", + 0); + pdata->dmic23_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-dmic23-gpios", + 0); + pdata->dmic45_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-dmic45-gpios", + 0); ret = msm_audio_ssr_register(&pdev->dev); if (ret) -- GitLab From 574f494777d6a213365ea07273469b61a1014c07 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 18 Feb 2019 12:59:41 +0800 Subject: [PATCH 0797/1645] asoc: kona: update parameters for RX/TX backend Samplerate, channels and bit rate are not updated for MSM_BACKEND_DAI_WSA_CDC_DMA_RX_*, MSM_BACKEND_DAI_RX_CDC_DMA_RX_*, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_*, MSM_BACKEND_DAI_TX_CDC_DMA_TX_*. Add hw_params_fixup function for these BE DAIs. Change-Id: Ia21f1cf5742e3acc6549319dcedfde07233ed161 Signed-off-by: Meng Wang --- asoc/kona.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index b34b80afc18d..11983c1d1ddb 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -3292,18 +3292,43 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, mi2s_tx_cfg[TERT_MI2S].channels; break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0: + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_0: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_1: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_2: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_3: + idx = msm_cdc_dma_get_idx_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + cdc_dma_rx_cfg[idx].bit_format); + rate->min = rate->max = cdc_dma_rx_cfg[idx].sample_rate; + channels->min = channels->max = cdc_dma_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1: + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_0: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_3: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_4: case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2: idx = msm_cdc_dma_get_idx_from_beid(dai_link->id); param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, - cdc_dma_tx_cfg[idx].bit_format); + cdc_dma_tx_cfg[idx].bit_format); rate->min = rate->max = cdc_dma_tx_cfg[idx].sample_rate; channels->min = channels->max = cdc_dma_tx_cfg[idx].channels; break; - default: + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + SNDRV_PCM_FORMAT_S32_LE); rate->min = rate->max = SAMPLING_RATE_8KHZ; + channels->min = channels->max = msm_vi_feed_tx_ch; + break; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; break; } -- GitLab From 72cea1a23cae628c0e84d5ec7fa285155f48fbf7 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Mon, 21 Jan 2019 14:31:03 +0800 Subject: [PATCH 0798/1645] codecs: reduce error log rate Huge volume of log prints out at error. Reduce the redundant log. Change-Id: I761d5953614d039b7a725926c38adee1beeeec41 Signed-off-by: Xiaojun Sang --- dsp/codecs/audio_aac.c | 14 ++++++++++++-- dsp/codecs/audio_alac.c | 15 ++++++++++++--- dsp/codecs/audio_amrnb.c | 16 +++++++++++++--- dsp/codecs/audio_amrwbplus.c | 14 ++++++++++++-- dsp/codecs/audio_ape.c | 14 ++++++++++++-- dsp/codecs/audio_evrc.c | 14 ++++++++++++-- dsp/codecs/audio_g711alaw.c | 14 ++++++++++++-- dsp/codecs/audio_g711mlaw.c | 14 ++++++++++++-- dsp/codecs/audio_mp3.c | 14 ++++++++++++-- dsp/codecs/audio_multi_aac.c | 14 ++++++++++++-- dsp/codecs/audio_qcelp.c | 14 ++++++++++++-- dsp/codecs/audio_utils_aio.c | 16 +++++++++++++--- dsp/codecs/audio_wma.c | 14 ++++++++++++-- dsp/codecs/audio_wmapro.c | 14 ++++++++++++-- 14 files changed, 170 insertions(+), 31 deletions(-) diff --git a/dsp/codecs/audio_aac.c b/dsp/codecs/audio_aac.c index cf3d4484708d..32106e58546e 100644 --- a/dsp/codecs/audio_aac.c +++ b/dsp/codecs/audio_aac.c @@ -3,7 +3,17 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2010-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2019, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * */ #include @@ -383,7 +393,7 @@ static int audio_open(struct inode *inode, struct file *file) } rc = audio_aio_open(audio, file); if (rc < 0) { - pr_err("%s: audio_aio_open rc=%d\n", + pr_err_ratelimited("%s: audio_aio_open rc=%d\n", __func__, rc); goto fail; } diff --git a/dsp/codecs/audio_alac.c b/dsp/codecs/audio_alac.c index ea05d7100a4a..f7e09323dd97 100644 --- a/dsp/codecs/audio_alac.c +++ b/dsp/codecs/audio_alac.c @@ -1,6 +1,15 @@ // SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * */ #include @@ -290,7 +299,7 @@ static int audio_open(struct inode *inode, struct file *file) } rc = audio_aio_open(audio, file); if (rc < 0) { - pr_err("%s: audio_aio_open rc=%d\n", + pr_err_ratelimited("%s: audio_aio_open rc=%d\n", __func__, rc); goto fail; } diff --git a/dsp/codecs/audio_amrnb.c b/dsp/codecs/audio_amrnb.c index efec4d2d332b..ea6d02fcfbba 100644 --- a/dsp/codecs/audio_amrnb.c +++ b/dsp/codecs/audio_amrnb.c @@ -3,7 +3,17 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017, 2019 The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * */ #include @@ -137,7 +147,7 @@ static int audio_open(struct inode *inode, struct file *file) } rc = audio_aio_open(audio, file); if (rc < 0) { - pr_err("%s: audio_aio_open rc=%d\n", + pr_err_ratelimited("%s: audio_aio_open rc=%d\n", __func__, rc); goto fail; } @@ -178,7 +188,7 @@ static int audio_open(struct inode *inode, struct file *file) if (IS_ERR(audio->dentry)) pr_debug("debugfs_create_file failed\n"); #endif - pr_info("%s:amrnb decoder open success, session_id = %d\n", __func__, + pr_info_ratelimited("%s:amrnb decoder open success, session_id = %d\n", __func__, audio->ac->session); return rc; fail: diff --git a/dsp/codecs/audio_amrwbplus.c b/dsp/codecs/audio_amrwbplus.c index d06b054b3723..6cadab722aeb 100644 --- a/dsp/codecs/audio_amrwbplus.c +++ b/dsp/codecs/audio_amrwbplus.c @@ -3,7 +3,17 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2017, 2019 The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * */ #include #include @@ -313,7 +323,7 @@ static int audio_open(struct inode *inode, struct file *file) } rc = audio_aio_open(audio, file); if (rc < 0) { - pr_err("%s: audio_aio_open rc=%d\n", + pr_err_ratelimited("%s: audio_aio_open rc=%d\n", __func__, rc); goto fail; } diff --git a/dsp/codecs/audio_ape.c b/dsp/codecs/audio_ape.c index 219df404e543..1e12981524c4 100644 --- a/dsp/codecs/audio_ape.c +++ b/dsp/codecs/audio_ape.c @@ -1,5 +1,15 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * */ #include @@ -271,7 +281,7 @@ static int audio_open(struct inode *inode, struct file *file) } rc = audio_aio_open(audio, file); if (rc < 0) { - pr_err("%s: audio_aio_open rc=%d\n", + pr_err_ratelimited("%s: audio_aio_open rc=%d\n", __func__, rc); goto fail; } diff --git a/dsp/codecs/audio_evrc.c b/dsp/codecs/audio_evrc.c index c3bf9b8bedda..48d26525b0c3 100644 --- a/dsp/codecs/audio_evrc.c +++ b/dsp/codecs/audio_evrc.c @@ -3,7 +3,17 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017, 2019 The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * */ #include "audio_utils_aio.h" @@ -94,7 +104,7 @@ static int audio_open(struct inode *inode, struct file *file) } rc = audio_aio_open(audio, file); if (rc < 0) { - pr_err("%s: audio_aio_open rc=%d\n", + pr_err_ratelimited("%s: audio_aio_open rc=%d\n", __func__, rc); goto fail; } diff --git a/dsp/codecs/audio_g711alaw.c b/dsp/codecs/audio_g711alaw.c index 3dac27d50d19..b4a1d7ee5c5b 100644 --- a/dsp/codecs/audio_g711alaw.c +++ b/dsp/codecs/audio_g711alaw.c @@ -1,5 +1,15 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * */ #include @@ -245,7 +255,7 @@ static int audio_open(struct inode *inode, struct file *file) } rc = audio_aio_open(audio, file); if (rc < 0) { - pr_err("%s: audio_aio_open rc=%d\n", + pr_err_ratelimited("%s: audio_aio_open rc=%d\n", __func__, rc); goto fail; } diff --git a/dsp/codecs/audio_g711mlaw.c b/dsp/codecs/audio_g711mlaw.c index c0102d0d64d7..1cf8a9787040 100644 --- a/dsp/codecs/audio_g711mlaw.c +++ b/dsp/codecs/audio_g711mlaw.c @@ -1,5 +1,15 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * */ #include @@ -244,7 +254,7 @@ static int audio_open(struct inode *inode, struct file *file) } rc = audio_aio_open(audio, file); if (rc < 0) { - pr_err("%s: audio_aio_open rc=%d\n", + pr_err_ratelimited("%s: audio_aio_open rc=%d\n", __func__, rc); goto fail; } diff --git a/dsp/codecs/audio_mp3.c b/dsp/codecs/audio_mp3.c index 47446d3cc8b0..7228cba3a4e8 100644 --- a/dsp/codecs/audio_mp3.c +++ b/dsp/codecs/audio_mp3.c @@ -3,7 +3,17 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017, 2019 The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * */ #include "audio_utils_aio.h" @@ -96,7 +106,7 @@ static int audio_open(struct inode *inode, struct file *file) } rc = audio_aio_open(audio, file); if (rc < 0) { - pr_err("%s: audio_aio_open rc=%d\n", + pr_err_ratelimited("%s: audio_aio_open rc=%d\n", __func__, rc); goto fail; } diff --git a/dsp/codecs/audio_multi_aac.c b/dsp/codecs/audio_multi_aac.c index fc3f4924851f..2c88ebf4765b 100644 --- a/dsp/codecs/audio_multi_aac.c +++ b/dsp/codecs/audio_multi_aac.c @@ -3,7 +3,17 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * */ #include @@ -437,7 +447,7 @@ static int audio_open(struct inode *inode, struct file *file) } rc = audio_aio_open(audio, file); if (rc < 0) { - pr_err("%s: audio_aio_open rc=%d\n", + pr_err_ratelimited("%s: audio_aio_open rc=%d\n", __func__, rc); goto fail; } diff --git a/dsp/codecs/audio_qcelp.c b/dsp/codecs/audio_qcelp.c index fcf39f56b09c..7e88cfd1b45d 100644 --- a/dsp/codecs/audio_qcelp.c +++ b/dsp/codecs/audio_qcelp.c @@ -3,7 +3,17 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017, 2019 The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * */ #include "audio_utils_aio.h" @@ -101,7 +111,7 @@ static int audio_open(struct inode *inode, struct file *file) } rc = audio_aio_open(audio, file); if (rc < 0) { - pr_err("%s: audio_aio_open rc=%d\n", + pr_err_ratelimited("%s: audio_aio_open rc=%d\n", __func__, rc); goto fail; } diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c index eabf170a8cce..f22163567aa8 100644 --- a/dsp/codecs/audio_utils_aio.c +++ b/dsp/codecs/audio_utils_aio.c @@ -1,7 +1,17 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2019, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * */ #include @@ -1335,7 +1345,7 @@ int audio_aio_open(struct q6audio_aio *audio, struct file *file) audio->drv_ops.in_flush = audio_aio_async_in_flush; q6asm_set_io_mode(audio->ac, ASYNC_IO_MODE); } else { - pr_err("%s[%pK]:SIO interface not supported\n", + pr_err_ratelimited("%s[%pK]:SIO interface not supported\n", __func__, audio); rc = -EACCES; goto fail; @@ -1548,7 +1558,7 @@ static long audio_aio_shared_ioctl(struct file *file, unsigned int cmd, break; } default: - pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd); + pr_err_ratelimited("%s: Unknown ioctl cmd = %d", __func__, cmd); rc = -EINVAL; } return rc; diff --git a/dsp/codecs/audio_wma.c b/dsp/codecs/audio_wma.c index cdd23ff57b13..66c818d5cb1a 100644 --- a/dsp/codecs/audio_wma.c +++ b/dsp/codecs/audio_wma.c @@ -3,7 +3,17 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2019, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * */ #include @@ -253,7 +263,7 @@ static int audio_open(struct inode *inode, struct file *file) } rc = audio_aio_open(audio, file); if (rc < 0) { - pr_err("%s: audio_aio_open rc=%d\n", + pr_err_ratelimited("%s: audio_aio_open rc=%d\n", __func__, rc); goto fail; } diff --git a/dsp/codecs/audio_wmapro.c b/dsp/codecs/audio_wmapro.c index c0a27576b4d2..4fc331239584 100644 --- a/dsp/codecs/audio_wmapro.c +++ b/dsp/codecs/audio_wmapro.c @@ -3,7 +3,17 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2019, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * */ #include @@ -327,7 +337,7 @@ static int audio_open(struct inode *inode, struct file *file) rc = audio_aio_open(audio, file); if (rc < 0) { - pr_err("%s: audio_aio_open rc=%d\n", + pr_err_ratelimited("%s: audio_aio_open rc=%d\n", __func__, rc); goto fail; } -- GitLab From 8b0abba9d790ffbe6681ef98f0ccb952ffde530e Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Fri, 11 Jan 2019 19:35:54 +0530 Subject: [PATCH 0799/1645] dsp: Check ec ref rx port against AFE_PORT_INVALID ec ref rx port is defined as integer and it is set to 0xFFFF (AFE_PORT_INVALID) when ec controls are reset. Due to this the current check against -1 (0xFFFFFFFF) in adm open will always return true even after controls are reset. This leads to adm open failures in case no ec ref channels are set as part of record usecase. Avoid this by checking ec ref rx port against AFE_PORT_INVALID. Change-Id: I0d52bbe2a980d495933239315e6bba193a18567e Signed-off-by: Chaithanya Krishna Bacharaju --- dsp/q6adm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 688012f727d9..4946987861f2 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2895,8 +2895,9 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, open_v8.endpoint_id_2 = 0xFFFF; open_v8.endpoint_id_3 = 0xFFFF; - if ((this_adm.ec_ref_rx != -1) && - (path != ADM_PATH_PLAYBACK)) { + if (((this_adm.ec_ref_rx & AFE_PORT_INVALID) != + AFE_PORT_INVALID) && + (path != ADM_PATH_PLAYBACK)) { if (this_adm.num_ec_ref_rx_chans != 0) { open_v8.endpoint_id_2 = this_adm.ec_ref_rx; -- GitLab From 810e42a3549e828c41bf272a96c9c9fd280d860f Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Mon, 7 Jan 2019 17:53:34 +0530 Subject: [PATCH 0800/1645] asoc: Add routing controls for SLIM_1_TX Add routing controls for SLIM_1_TX for compress capture. Change-Id: I8d350ebc60cc081e7027352ddd77ebbb59294189 Signed-off-by: Samyak Jain --- asoc/msm-pcm-routing-v2.c | 75 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index c49a7579ef00..d5a19231e37b 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -9373,6 +9373,10 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, @@ -9791,6 +9795,10 @@ static const struct snd_kcontrol_new mmul3_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, @@ -9990,6 +9998,10 @@ static const struct snd_kcontrol_new mmul4_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, @@ -10185,6 +10197,10 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_FM_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, @@ -10412,6 +10428,10 @@ static const struct snd_kcontrol_new mmul6_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, @@ -10607,6 +10627,10 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, @@ -10814,6 +10838,10 @@ static const struct snd_kcontrol_new mmul16_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, @@ -11027,6 +11055,10 @@ static const struct snd_kcontrol_new mmul9_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, @@ -11170,6 +11202,10 @@ static const struct snd_kcontrol_new mmul10_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, @@ -11346,6 +11382,10 @@ static const struct snd_kcontrol_new mmul17_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, @@ -11455,6 +11495,10 @@ static const struct snd_kcontrol_new mmul18_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, @@ -11568,6 +11612,10 @@ static const struct snd_kcontrol_new mmul19_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, @@ -11991,6 +12039,10 @@ static const struct snd_kcontrol_new mmul27_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_6_TX, MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, @@ -12042,6 +12094,10 @@ static const struct snd_kcontrol_new mmul28_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -12151,6 +12207,10 @@ static const struct snd_kcontrol_new mmul29_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, @@ -20255,12 +20315,19 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"MultiMedia8 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, {"MultiMedia4 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia4 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia17 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia17 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia18 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia18 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia19 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia19 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia28 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia28 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia29 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia29 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia8 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia8 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia2 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia4 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia17 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -20282,9 +20349,13 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia29 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia8 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia3 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia5 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia10 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia10 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia16 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia16 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia5 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"MultiMedia5 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"MultiMedia5 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, @@ -20957,6 +21028,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia2 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia1 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"MultiMedia3 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, {"MultiMedia5 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, @@ -20987,6 +21059,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia2 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"MultiMedia6 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia6 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia6 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, @@ -21264,6 +21337,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia8 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia9 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia9 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"MultiMedia9 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, {"MultiMedia9 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, @@ -21388,6 +21462,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia21 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, {"MultiMedia27 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia27 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia27 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, {"MultiMedia27 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"MultiMedia27 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, -- GitLab From f016d3089f2db0472306f229069460b51b66b6fa Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 21 Jan 2019 10:35:53 +0800 Subject: [PATCH 0801/1645] asoc: update be_name and adm_programable_channel_mixer parameters Some new backends are added and update be_name for channel mixer. Update adm_programable_channel_mixer parameter to support record echo from RX. Change-Id: I628292112f558eca9301c67b36e6de41924f27d5 Signed-off-by: Meng Wang --- asoc/msm-pcm-routing-v2.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index c49a7579ef00..cbef55cd734f 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1537,7 +1537,7 @@ static int msm_pcm_routing_channel_mixer(int fe_id, bool perf_mode, fe_id, be_id, msm_bedais[be_id].channel, copp_idx); ret = adm_programable_channel_mixer( - msm_bedais[be_id].port_id, + get_port_id(msm_bedais[be_id].port_id), copp_idx, dspst_id, sess_type, channel_mixer + fe_id, i); } @@ -3104,20 +3104,21 @@ static const char *const be_name[] = { "QUIN_TDM_RX_2", "QUIN_TDM_TX_2", "QUIN_TDM_RX_3", "QUIN_TDM_TX_3", "QUIN_TDM_RX_4", "QUIN_TDM_TX_4", "QUIN_TDM_RX_5", "QUIN_TDM_TX_5", "QUIN_TDM_RX_6", "QUIN_TDM_TX_6", "QUIN_TDM_RX_7", "QUIN_TDM_TX_7", -"INT_BT_A2DP_RX", "USB_RX", "USB_TX", "DISPLAY_PORT_RX", "DISPLAY_PORT_RX1", -"TERT_AUXPCM_RX", "TERT_AUXPCM_TX", "QUAT_AUXPCM_RX", "QUAT_AUXPCM_TX", -"QUIN_AUXPCM_RX", "QUIN_AUXPCM_TX", -"INT0_MI2S_RX", "INT0_MI2S_TX", "INT1_MI2S_RX", "INT1_MI2S_TX", -"INT2_MI2S_RX", "INT2_MI2S_TX", "INT3_MI2S_RX", "INT3_MI2S_TX", -"INT4_MI2S_RX", "INT4_MI2S_TX", "INT5_MI2S_RX", "INT5_MI2S_TX", -"INT6_MI2S_RX", "INT6_MI2S_TX", "WSA_CDC_DMA_RX_0", -"WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_RX_1", "WSA_CDC_DMA_TX_1", +"INT_BT_A2DP_RX", "USB_RX", "USB_TX", "DISPLAY_PORT_RX", +"DISPLAY_PORT_RX1", "TERT_AUXPCM_RX", "TERT_AUXPCM_TX", "QUAT_AUXPCM_RX", +"QUAT_AUXPCM_TX", "QUIN_AUXPCM_RX", "QUIN_AUXPCM_TX", "INT0_MI2S_RX", +"INT0_MI2S_TX", "INT1_MI2S_RX", "INT1_MI2S_TX", "INT2_MI2S_RX", +"INT2_MI2S_TX", "INT3_MI2S_RX", "INT3_MI2S_TX", "INT4_MI2S_RX", +"INT4_MI2S_TX", "INT5_MI2S_RX", "INT5_MI2S_TX", "INT6_MI2S_RX", +"INT6_MI2S_TX", "SEN_AUXPCM_RX", "SEN_AUXPCM_TX", "SENARY_MI2S_RX", +"WSA_CDC_DMA_RX_0", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_RX_1","WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_2", "RX_CDC_DMA_RX_0", "TX_CDC_DMA_TX_0", "RX_CDC_DMA_RX_1", "TX_CDC_DMA_TX_1", "RX_CDC_DMA_RX_2", "TX_CDC_DMA_TX_2", "RX_CDC_DMA_RX_3", "TX_CDC_DMA_TX_3", "RX_CDC_DMA_RX_4", "TX_CDC_DMA_TX_4", "RX_CDC_DMA_RX_5", "TX_CDC_DMA_TX_5", "RX_CDC_DMA_RX_6", "RX_CDC_DMA_RX_7", "PRI_SPDIF_TX", "SEC_SPDIF_RX", "SEC_SPDIF_TX", +"SLIM_9_RX", "SLIM_9_TX", "AFE_LOOPBACK_TX" }; static SOC_ENUM_SINGLE_DECL(mm1_channel_mux, -- GitLab From 3c7524b6731765de777b8044f7308c2c63a4b873 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 11 Jan 2019 14:51:52 +0530 Subject: [PATCH 0802/1645] ASoC: sm6150: Enable moisture detection polling on Talos Enable polling when moisture is detected on Talos. Change-Id: Ice463c8bbbbd5de8b2b8c02cbce2543243b10703 Signed-off-by: Vatsal Bucha --- asoc/sm6150.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 55fe17875df8..4c86706a97a0 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -653,10 +653,11 @@ static struct wcd_mbhc_config wcd_mbhc_cfg = { .key_code[6] = 0, .key_code[7] = 0, .linein_th = 5000, - .moisture_en = true, + .moisture_en = false, .mbhc_micbias = MIC_BIAS_2, .anc_micbias = MIC_BIAS_2, .enable_anc_mic_detect = false, + .moisture_duty_cycle_en = true, }; static struct snd_soc_dapm_route wcd_audio_paths_tavil[] = { -- GitLab From 1bf124f9d9f77d343afd8c9fa8772111ab66df25 Mon Sep 17 00:00:00 2001 From: Dhananjay Kumar Date: Fri, 18 Jan 2019 17:22:04 +0530 Subject: [PATCH 0803/1645] asoc: msm-lsm-client: fix error logging for set session data failure Error logging from set session data is not reflecting actual reason of failure. Update error logging for this failure with correct info. Change-Id: I5009a8b17128f0093e16f75c0e212a9bfb1f1a2e Signed-off-by: Dhananjay Kumar --- asoc/msm-lsm-client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 6bf44c44ca04..379b5e5f6eb3 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -1050,7 +1050,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, if (ses_data_v2.app_id != LSM_VOICE_WAKEUP_APP_ID_V2) { dev_err(rtd->dev, "%s:Invalid App id %d for Listen client\n", - __func__, session_data.app_id); + __func__, ses_data_v2.app_id); rc = -EINVAL; break; } -- GitLab From 7aa2f97f6098f8bb68c651ead76d7d4a3487b23f Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 3 Jan 2019 12:08:29 +0530 Subject: [PATCH 0804/1645] ASoC: wcd937x: Enable surge protection for talos Enable surge protection feature for talos. Change-Id: If1a5e4d60a80f288825ee0e39645166f0cb9446f Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index ae286bdb7a37..beb4b177fd56 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -131,7 +131,9 @@ static int wcd937x_init_reg(struct snd_soc_component *component) 0xFF, 0x3A); snd_soc_component_update_bits(component, WCD937X_RX_OCP_CTL, 0x0F, 0x02); - + snd_soc_component_update_bits(component, + WCD937X_HPH_SURGE_HPHLR_SURGE_EN, + 0xFF, 0xD9); return 0; } @@ -1507,6 +1509,10 @@ static int wcd937x_event_notify(struct notifier_block *block, wcd937x_get_logical_addr(wcd937x->rx_swr_dev); regcache_mark_dirty(wcd937x->regmap); regcache_sync(wcd937x->regmap); + /* Enable surge protection */ + snd_soc_component_update_bits(component, + WCD937X_HPH_SURGE_HPHLR_SURGE_EN, + 0xFF, 0xD9); /* Initialize MBHC module */ mbhc = &wcd937x->mbhc->wcd_mbhc; ret = wcd937x_mbhc_post_ssr_init(wcd937x->mbhc, component); -- GitLab From 1529b55bb8c6369bc0669f3fec1ede4fb22f6a56 Mon Sep 17 00:00:00 2001 From: kunleiz Date: Thu, 24 Jan 2019 17:15:49 +0800 Subject: [PATCH 0805/1645] dsp: adm: change sample rate for FLUENCE_EF module FLUENCE_EF module in COPreP topology doesn't support 44.1Khz sample rate. Set sample rate to 16Khz for VPM_TX_DM_FLUENCE_EF_COPP_TOPOLOGY, which contains FLUENCE_EF module. Change-Id: I527da1a70cacba1014b2a706216172d12066b909 Signed-off-by: kunleiz --- dsp/q6adm.c | 8 +++++++- include/dsp/apr_audio-v2.h | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 688012f727d9..3c4782333271 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2784,8 +2784,14 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, if ((topology == VPM_TX_SM_ECNS_V2_COPP_TOPOLOGY) || (topology == VPM_TX_DM_FLUENCE_COPP_TOPOLOGY) || - (topology == VPM_TX_DM_RFECNS_COPP_TOPOLOGY)) + (topology == VPM_TX_DM_RFECNS_COPP_TOPOLOGY)|| + (topology == VPM_TX_DM_FLUENCE_EF_COPP_TOPOLOGY)) { + if ((rate != ADM_CMD_COPP_OPEN_SAMPLE_RATE_8K) && + (rate != ADM_CMD_COPP_OPEN_SAMPLE_RATE_16K) && + (rate != ADM_CMD_COPP_OPEN_SAMPLE_RATE_32K) && + (rate != ADM_CMD_COPP_OPEN_SAMPLE_RATE_48K)) rate = 16000; + } if (topology == VPM_TX_VOICE_SMECNS_V2_COPP_TOPOLOGY) channel_mode = 1; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 9daebe5a4113..4ca940e01b97 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -254,6 +254,9 @@ struct adm_cmd_matrix_map_routings_v5 { /* Sample rate is 16000 Hz.*/ #define ADM_CMD_COPP_OPEN_SAMPLE_RATE_16K 16000 +/* Sample rate is 32000 Hz.*/ +#define ADM_CMD_COPP_OPEN_SAMPLE_RATE_32K 32000 + /* Sample rate is 48000 Hz.*/ #define ADM_CMD_COPP_OPEN_SAMPLE_RATE_48K 48000 @@ -5082,6 +5085,7 @@ struct afe_param_id_lpass_core_shared_clk_cfg { #define VPM_TX_DM_RFECNS_COPP_TOPOLOGY 0x00010F86 #define ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX 0x10015002 #define ADM_CMD_COPP_OPEN_TOPOLOGY_ID_AUDIOSPHERE 0x10028000 +#define VPM_TX_DM_FLUENCE_EF_COPP_TOPOLOGY 0x10000005 /* Memory map regions command payload used by the * #ASM_CMD_SHARED_MEM_MAP_REGIONS ,#ADM_CMD_SHARED_MEM_MAP_REGIONS -- GitLab From e1728c5c3c59bfaa595daa26aa5ae98637555c9e Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 17 Jan 2019 17:24:55 +0530 Subject: [PATCH 0806/1645] ASoC: wcd-mbhc: Disable moisture_en when duty cycle is enabled Moisture Detection should be disabled at init if duty cycle is enabled. Change-Id: If398928a680174d981b9baefe02d9efd4e21766e Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd-mbhc-v2.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 6839203bd990..1159b1128a02 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -850,7 +850,7 @@ static bool wcd_mbhc_moisture_detect(struct wcd_mbhc *mbhc, bool detection_type) { bool ret = false; - if (!mbhc->mbhc_cfg->moisture_en || + if (!mbhc->mbhc_cfg->moisture_en && !mbhc->mbhc_cfg->moisture_duty_cycle_en) return ret; @@ -1342,9 +1342,15 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) else WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, 3); + /* Configure for moisture detection when duty cycle is not enabled. + * Otherwise disable moisture detection. + */ if (mbhc->mbhc_cfg->moisture_en && mbhc->mbhc_cb->mbhc_moisture_config && !mbhc->mbhc_cfg->moisture_duty_cycle_en) mbhc->mbhc_cb->mbhc_moisture_config(mbhc); + else if (mbhc->mbhc_cfg->moisture_duty_cycle_en && + mbhc->mbhc_cb->mbhc_moisture_detect_en) + mbhc->mbhc_cb->mbhc_moisture_detect_en(mbhc, false); /* * For USB analog we need to override the switch configuration. -- GitLab From 22533093130860d76c879047c45cb8e7433b2197 Mon Sep 17 00:00:00 2001 From: Josh Kirsch Date: Thu, 17 Jan 2019 16:01:08 -0800 Subject: [PATCH 0807/1645] audio-kernel: dsp: Add needed exports Add needed exports in q6afe. These are needed for sdxprairie drivers where LPASS provides the clock. Change-Id: Icd8256153523c8827ffd65eda1152ef9ad355119 Signed-off-by: Josh Kirsch --- dsp/q6afe.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 1b5c94d59a5f..1ba328230f4a 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -7282,7 +7281,16 @@ int afe_set_lpass_internal_digital_codec_clock(u16 port_id, return ret; } - +/** + * afe_enable_lpass_core_shared_clock - + * Configures the core clk on LPASS. + * Need on targets where lpass provides + * clocks + * @port_id: afe port id + * @enable: enable or disable clk + * + * Returns success or failure of call. + */ int afe_enable_lpass_core_shared_clock(u16 port_id, u32 enable) { struct afe_param_id_lpass_core_shared_clk_cfg clk_cfg; @@ -7321,7 +7329,16 @@ int afe_enable_lpass_core_shared_clock(u16 port_id, u32 enable) mutex_unlock(&this_afe.afe_cmd_lock); return ret; } +EXPORT_SYMBOL(afe_enable_lpass_core_shared_clock); +/** + * q6afe_check_osr_clk_freq - + * Gets supported OSR CLK frequencies + * + * @freq: frequency to check + * + * Returns success if freq is supported. + */ int q6afe_check_osr_clk_freq(u32 freq) { int ret = 0; @@ -7346,6 +7363,7 @@ int q6afe_check_osr_clk_freq(u32 freq) } return ret; } +EXPORT_SYMBOL(q6afe_check_osr_clk_freq); int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) { -- GitLab From 6ec6971e349dd368bc31ae30eb88625882098e1d Mon Sep 17 00:00:00 2001 From: Josh Kirsch Date: Thu, 10 Jan 2019 19:30:55 -0800 Subject: [PATCH 0808/1645] audio-kernel: asoc: ipc: add support for MDSP target Add support for MDSP based targets. Change-Id: Iac1402db89b321e85d4ccdb3863d697484c8251e Signed-off-by: Josh Kirsch --- ipc/apr_tal_rpmsg.c | 38 ++++++++++++++++++++++++++++++-------- ipc/apr_v3.c | 8 +++++++- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/ipc/apr_tal_rpmsg.c b/ipc/apr_tal_rpmsg.c index 723de56b9df8..c8830d1c25cc 100644 --- a/ipc/apr_tal_rpmsg.c +++ b/ipc/apr_tal_rpmsg.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. */ #include @@ -10,6 +10,7 @@ #include #include #include +#include enum apr_channel_state { APR_CH_DISCONNECTED, @@ -125,14 +126,13 @@ struct apr_svc_ch_dev *apr_tal_open(uint32_t clnt, uint32_t dest, uint32_t dl, int rc = 0; struct apr_svc_ch_dev *apr_ch = NULL; - if ((clnt != APR_CLIENT_AUDIO) || (dest != APR_DEST_QDSP6) || + if ((clnt != APR_CLIENT_AUDIO) || (dest >= APR_DEST_MAX) || (dl != APR_DL_SMD)) { pr_err("%s: Invalid params, clnt:%d, dest:%d, dl:%d\n", __func__, clnt, dest, dl); return NULL; } - - apr_ch = &apr_svc_ch[APR_DL_SMD][APR_DEST_QDSP6][APR_CLIENT_AUDIO]; + apr_ch = &apr_svc_ch[dl][dest][clnt]; mutex_lock(&apr_ch->m_lock); if (!apr_ch->handle) { rc = wait_event_timeout(apr_ch->wait, @@ -207,24 +207,46 @@ static int apr_tal_rpmsg_callback(struct rpmsg_device *rpdev, static int apr_tal_rpmsg_probe(struct rpmsg_device *rpdev) { struct apr_svc_ch_dev *apr_ch = NULL; + int ret = 0; + const char* dest; + + ret = of_property_read_string(rpdev->dev.parent->of_node, + "mbox-names", &dest); + + if(ret < 0){ + pr_err("%s no parent source pid found\n", __func__); + return -EINVAL; + } if (!strcmp(rpdev->id.name, "apr_audio_svc")) { dev_info(&rpdev->dev, "%s: Channel[%s] state[Up]\n", __func__, rpdev->id.name); - + } else { + dev_err(&rpdev->dev, "%s, Invalid Channel [%s]\n", + __func__, rpdev->id.name); + return -EINVAL; + } + if(strstr(dest, "adsp")) { apr_ch = &apr_svc_ch[APR_DL_SMD][APR_DEST_QDSP6][APR_CLIENT_AUDIO]; apr_ch->handle = rpdev; apr_ch->channel_state = APR_CH_CONNECTED; dev_set_drvdata(&rpdev->dev, apr_ch); wake_up(&apr_ch->wait); + } else if(strstr(dest, "mpss")) { + apr_ch = + &apr_svc_ch[APR_DL_SMD][APR_DEST_MODEM][APR_CLIENT_AUDIO]; + apr_ch->handle = rpdev; + apr_ch->channel_state = APR_CH_CONNECTED; + dev_set_drvdata(&rpdev->dev, apr_ch); + wake_up(&apr_ch->wait); } else { - dev_err(&rpdev->dev, "%s, Invalid Channel [%s]\n", - __func__, rpdev->id.name); + dev_err(&rpdev->dev, "%s, unsupported dest %s\n", + __func__, dest); return -EINVAL; } - return 0; + return ret; } static void apr_tal_rpmsg_remove(struct rpmsg_device *rpdev) diff --git a/ipc/apr_v3.c b/ipc/apr_v3.c index 7bf47749ef80..4160beee4836 100644 --- a/ipc/apr_v3.c +++ b/ipc/apr_v3.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, 2019 The Linux Foundation. All rights reserved. */ #include @@ -13,10 +13,16 @@ #define DEST_ID APR_DEST_MODEM +/** + * apr_get_subsys_state - get modem subsys status + * + * Returns apr_subsys_state + */ enum apr_subsys_state apr_get_subsys_state(void) { return apr_get_modem_state(); } +EXPORT_SYMBOL(apr_get_subsys_state); void apr_set_subsys_state(void) { -- GitLab From 94eb98b65968d2e3aaa5c97cef7f2166b89b7b01 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 25 Jan 2019 21:55:05 +0530 Subject: [PATCH 0809/1645] asoc: codecs: Add pm6125_divclk entry Add pm6125_divclk entry in pmi clock array to support tasha codec in trinket target. Change-Id: Ib2bacbeebb48d9b711abbc9f923a3b4b22cd7629 Signed-off-by: Aditya Bavanari --- asoc/codecs/audio-ext-clk-up.c | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index e86b30eed11a..6ed5ddd34f9e 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -194,6 +194,7 @@ static const char * const audio_ext_pmi_div_clk[] = { "qpnp_clkdiv_1", "pms405_div_clk1", "pm6150_div_clk1", + "pm6125_div_clk1", }; static int audio_ext_clk_dummy_prepare(struct clk_hw *hw) -- GitLab From 4a466532e4c3152f8a99159cc79df3678575c7f9 Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Mon, 21 Jan 2019 10:59:51 +0530 Subject: [PATCH 0810/1645] dsp: Add support for Aptx Adaptive decoder Add support for Aptx Adaptive decoder. Introduce flag to indicate ABR feedback decoder configuration to differentiate from regular decoder configuration. Change-Id: I272e0a9572a56e878f7ad1385514b3be7010145a Signed-off-by: Chaithanya Krishna Bacharaju --- dsp/q6afe.c | 57 ++++++++++++++++++++++++++++++++++---- include/dsp/apr_audio-v2.h | 16 +++++++++++ 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 1b5c94d59a5f..8743b56c5279 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -76,6 +75,11 @@ enum { Q6AFE_MSM_SPKR_FTM_MODE }; +enum { + APTX_AD_48 = 0, + APTX_AD_44_1 = 1 +}; + struct wlock { struct wakeup_source ws; }; @@ -3541,6 +3545,29 @@ static int q6afe_send_dec_config(u16 port_id, goto exit; } break; + case ASM_MEDIA_FMT_APTX_ADAPTIVE: + if (!cfg->abr_dec_cfg.is_abr_enabled) { + pr_debug("%s: sending aptx adaptive congestion buffer size to dsp\n", + __func__); + param_hdr.param_id = + AFE_DECODER_PARAM_ID_CONGESTION_BUFFER_SIZE; + param_hdr.param_size = + sizeof(struct avs_dec_congestion_buffer_param_t); + dec_buffer_id_param.version = 0; + dec_buffer_id_param.max_nr_buffers = 226; + dec_buffer_id_param.pre_buffer_size = 226; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &dec_buffer_id_param); + if (ret) { + pr_err("%s: aptx adaptive congestion buffer size for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + break; + } + /* fall through for abr enabled case */ default: pr_debug("%s:sending AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION to DSP payload\n", __func__); @@ -3561,7 +3588,7 @@ static int q6afe_send_dec_config(u16 port_id, break; } - pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __func__); + pr_debug("%s: Send AFE_API_VERSION_PORT_MEDIA_TYPE to DSP\n", __func__); param_hdr.module_id = AFE_MODULE_PORT; param_hdr.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE; param_hdr.param_size = sizeof(struct afe_port_media_type_t); @@ -3575,6 +3602,15 @@ static int q6afe_send_dec_config(u16 port_id, media_type.sample_rate = cfg->data.sbc_config.sample_rate; break; + case ASM_MEDIA_FMT_APTX_ADAPTIVE: + if (!cfg->abr_dec_cfg.is_abr_enabled) { + media_type.sample_rate = + (cfg->data.aptx_ad_config.sample_rate == APTX_AD_44_1) ? + AFE_PORT_SAMPLE_RATE_44_1K : + AFE_PORT_SAMPLE_RATE_48K; + break; + } + /* fall through for abr enabled case */ default: media_type.sample_rate = afe_config.slim_sch.sample_rate; @@ -3600,11 +3636,19 @@ static int q6afe_send_dec_config(u16 port_id, goto exit; } - if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2) { + if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 && + format != ASM_MEDIA_FMT_APTX_ADAPTIVE) { pr_debug("%s:Unsuppported dec format. Ignore AFE config %u\n", __func__, format); goto exit; } + + if (format == ASM_MEDIA_FMT_APTX_ADAPTIVE && + cfg->abr_dec_cfg.is_abr_enabled) { + pr_debug("%s: Ignore AFE config for abr case\n", __func__); + goto exit; + } + pr_debug("%s: sending AFE_DECODER_PARAM_ID_DEC_MEDIA_FMT to DSP payload\n", __func__); param_hdr.module_id = AFE_MODULE_ID_DECODER; @@ -3623,9 +3667,10 @@ static int q6afe_send_dec_config(u16 port_id, switch (cfg->format) { case ASM_MEDIA_FMT_AAC_V2: + case ASM_MEDIA_FMT_APTX_ADAPTIVE: param_hdr.param_size = sizeof(struct afe_dec_media_fmt_t); - pr_debug("%s:send AFE_DECODER_PARAM_ID DEC_MEDIA_FMT to DSP payload\n", + pr_debug("%s:send AVS_DECODER_PARAM_ID DEC_MEDIA_FMT to DSP payload\n", __func__); param_hdr.param_id = AVS_DECODER_PARAM_ID_DEC_MEDIA_FMT; dec_media_fmt.dec_media_config = cfg->data; @@ -3634,7 +3679,7 @@ static int q6afe_send_dec_config(u16 port_id, param_hdr, (u8 *) &dec_media_fmt); if (ret) { - pr_err("%s: AFE_DECODER_PARAM_ID DEC_MEDIA_FMT for port 0x%x failed %d\n", + pr_err("%s: AVS_DECODER_PARAM_ID DEC_MEDIA_FMT for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 9daebe5a4113..532742794127 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -2477,6 +2477,7 @@ struct afe_port_data_cmd_rt_proxy_port_read_v2 { #define AFE_MODULE_AUDIO_DEV_INTERFACE 0x0001020C #define AFE_PORT_SAMPLE_RATE_8K 8000 #define AFE_PORT_SAMPLE_RATE_16K 16000 +#define AFE_PORT_SAMPLE_RATE_44_1K 44100 #define AFE_PORT_SAMPLE_RATE_48K 48000 #define AFE_PORT_SAMPLE_RATE_96K 96000 #define AFE_PORT_SAMPLE_RATE_176P4K 176400 @@ -3795,6 +3796,7 @@ struct afe_imc_dec_enc_info { struct afe_abr_dec_cfg_t { struct afe_imc_dec_enc_info imc_info; + bool is_abr_enabled; } __packed; struct afe_abr_enc_cfg_t { @@ -4437,6 +4439,19 @@ struct asm_aac_dec_cfg_v2_t { */ } __packed; +/* + * Payload of the APTX AD decoder configuration parameters in the + * #ASM_MEDIA_FMT_APTX_ADAPTIVE media format. + */ +struct asm_aptx_ad_dec_cfg_t { + uint32_t sample_rate; + /* + * Number of samples per second. + * + * @values 0x0(48000Hz), 0x1(44100Hz) + */ +} __packed; + union afe_enc_config_data { struct asm_sbc_enc_cfg_t sbc_config; struct asm_aac_enc_cfg_t aac_config; @@ -4458,6 +4473,7 @@ union afe_dec_config_data { struct asm_sbc_dec_cfg_t sbc_config; struct asm_aac_dec_cfg_v2_t aac_config; struct asm_mp3_dec_cfg_t mp3_config; + struct asm_aptx_ad_dec_cfg_t aptx_ad_config; }; struct afe_dec_config { -- GitLab From cdde1800606f6a67b01dadad53e8fad06cc1fed1 Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Thu, 24 Jan 2019 13:38:42 +0530 Subject: [PATCH 0811/1645] asoc: Add support for Aptx Adaptive decoder Add support for Aptx Adaptive decoder. Introduce new get and put for ABR feedback decoder controls since same decoder config format is required to be passed by client in regular and feedback decoder configuration. Change-Id: I96d9daef2a0967788640c2efb5478119eeae48ab Signed-off-by: Chaithanya Krishna Bacharaju --- asoc/msm-dai-q6-v2.c | 87 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 13 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 10acd501a80d..c2be85b03245 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -3226,11 +3226,64 @@ static int msm_dai_q6_afe_dec_cfg_info(struct snd_kcontrol *kcontrol, return 0; } +static int msm_dai_q6_afe_feedback_dec_cfg_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + u32 format_size = 0; + + if (!dai_data) { + pr_err("%s: Invalid dai data\n", __func__); + return -EINVAL; + } + + format_size = sizeof(dai_data->dec_config.format); + memcpy(ucontrol->value.bytes.data, + &dai_data->dec_config.format, + format_size); + + pr_debug("%s: abr_dec_cfg for %d format\n", + __func__, dai_data->dec_config.format); + memcpy(ucontrol->value.bytes.data + format_size, + &dai_data->dec_config.abr_dec_cfg, + sizeof(struct afe_imc_dec_enc_info)); + + return 0; +} + +static int msm_dai_q6_afe_feedback_dec_cfg_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + u32 format_size = 0; + + if (!dai_data) { + pr_err("%s: Invalid dai data\n", __func__); + return -EINVAL; + } + + memset(&dai_data->dec_config, 0x0, + sizeof(struct afe_dec_config)); + format_size = sizeof(dai_data->dec_config.format); + memcpy(&dai_data->dec_config.format, + ucontrol->value.bytes.data, + format_size); + + pr_debug("%s: abr_dec_cfg for %d format\n", + __func__, dai_data->dec_config.format); + memcpy(&dai_data->dec_config.abr_dec_cfg, + ucontrol->value.bytes.data + format_size, + sizeof(struct afe_imc_dec_enc_info)); + dai_data->dec_config.abr_dec_cfg.is_abr_enabled = true; + return 0; +} + static int msm_dai_q6_afe_dec_cfg_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; u32 format_size = 0; + int ret = 0; if (!dai_data) { pr_err("%s: Invalid dai data\n", __func__); @@ -3247,20 +3300,23 @@ static int msm_dai_q6_afe_dec_cfg_get(struct snd_kcontrol *kcontrol, &dai_data->dec_config.data, sizeof(struct asm_aac_dec_cfg_v2_t)); break; + case DEC_FMT_APTX_ADAPTIVE: + memcpy(ucontrol->value.bytes.data + format_size, + &dai_data->dec_config.data, + sizeof(struct asm_aptx_ad_dec_cfg_t)); + break; case DEC_FMT_SBC: case DEC_FMT_MP3: /* No decoder specific data available */ break; default: - pr_debug("%s: Default decoder config for %d format: Expect abr_dec_cfg\n", + pr_err("%s: Invalid format %d\n", __func__, dai_data->dec_config.format); - memcpy(ucontrol->value.bytes.data + format_size, - &dai_data->dec_config.abr_dec_cfg, - sizeof(struct afe_abr_dec_cfg_t)); - + ret = -EINVAL; break; } - return 0; + + return ret; } static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol, @@ -3268,6 +3324,7 @@ static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol, { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; u32 format_size = 0; + int ret = 0; if (!dai_data) { pr_err("%s: Invalid dai data\n", __func__); @@ -3293,15 +3350,19 @@ static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol, ucontrol->value.bytes.data + format_size, sizeof(struct asm_sbc_dec_cfg_t)); break; + case DEC_FMT_APTX_ADAPTIVE: + memcpy(&dai_data->dec_config.data, + ucontrol->value.bytes.data + format_size, + sizeof(struct asm_aptx_ad_dec_cfg_t)); + break; default: - pr_debug("%s: Default decoder config for %d format: Expect abr_dec_cfg\n", + pr_err("%s: Invalid format %d\n", __func__, dai_data->dec_config.format); - memcpy(&dai_data->dec_config.abr_dec_cfg, - ucontrol->value.bytes.data + format_size, - sizeof(struct afe_abr_dec_cfg_t)); + ret = -EINVAL; break; } - return 0; + + return ret; } static const struct snd_kcontrol_new afe_dec_config_controls[] = { @@ -3311,8 +3372,8 @@ static const struct snd_kcontrol_new afe_dec_config_controls[] = { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "SLIM_7_TX Decoder Config", .info = msm_dai_q6_afe_dec_cfg_info, - .get = msm_dai_q6_afe_dec_cfg_get, - .put = msm_dai_q6_afe_dec_cfg_put, + .get = msm_dai_q6_afe_feedback_dec_cfg_get, + .put = msm_dai_q6_afe_feedback_dec_cfg_put, }, { .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | -- GitLab From a70027da2c020cd69534ec83686c3282854bb25a Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Mon, 26 Nov 2018 14:56:34 +0100 Subject: [PATCH 0812/1645] asoc: Add sources to dai links for concurrent audio record Add SEC_MI2S, PRI_SPDIF and SEC_SPDIF as source to dai links for concurrent audio recordings. Change-Id: I9c4a46fa4657222ce80b21fd4320715b8c89f36a Signed-off-by: Ralf Herz --- asoc/msm-pcm-routing-v2.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index c49a7579ef00..72bcebea08e0 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -11596,6 +11596,10 @@ static const struct snd_kcontrol_new mmul19_mixer_controls[] = { MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, @@ -12070,6 +12074,10 @@ static const struct snd_kcontrol_new mmul28_mixer_controls[] = { MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, @@ -12179,6 +12187,10 @@ static const struct snd_kcontrol_new mmul29_mixer_controls[] = { MSM_BACKEND_DAI_INCALL_RECORD_TX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, @@ -20270,6 +20282,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia29 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia8 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia18 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia19 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia28 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia29 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"MultiMedia17 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia18 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia19 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, @@ -20291,7 +20306,13 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia10 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"MultiMedia10 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, {"MultiMedia18 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia19 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia28 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia29 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia18 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia19 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia28 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia29 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, -- GitLab From 8bcc97c618be9277e81057cb22941fc3fb5495c2 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 7 Jan 2019 13:18:11 +0530 Subject: [PATCH 0813/1645] ASoC: rx-macro: Enable hph idle detect feature Headset Idle detect feature powers off PAs when there is no signal. Add widget to enable this feature for headset path. Change-Id: I4c88057b347e40317578b5eb014053c17d196b85 Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/rx-macro.c | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 4d9ccb43761c..535a33697625 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -453,6 +453,10 @@ static const struct snd_kcontrol_new rx_int2_1_vbat_mix_switch[] = { SOC_DAPM_SINGLE("RX AUX VBAT Enable", SND_SOC_NOPM, 0, 1, 0) }; +static const char * const hph_idle_detect_text[] = {"OFF", "ON"}; + +static SOC_ENUM_SINGLE_EXT_DECL(hph_idle_detect_enum, hph_idle_detect_text); + RX_MACRO_DAPM_ENUM(rx_int0_2, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, rx_int_mix_mux_text); RX_MACRO_DAPM_ENUM(rx_int1_2, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, @@ -1684,6 +1688,40 @@ static void rx_macro_hd2_control(struct snd_soc_component *component, } } +static int rx_macro_hph_idle_detect_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct rx_macro_priv *rx_priv = NULL; + struct device *rx_dev = NULL; + + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = + rx_priv->idle_det_cfg.hph_idle_detect_en; + + return 0; +} + +static int rx_macro_hph_idle_detect_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct rx_macro_priv *rx_priv = NULL; + struct device *rx_dev = NULL; + + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + rx_priv->idle_det_cfg.hph_idle_detect_en = + ucontrol->value.integer.value[0]; + + return 0; +} + static int rx_macro_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2611,6 +2649,9 @@ static const struct snd_kcontrol_new rx_macro_snd_controls[] = { SOC_SINGLE_EXT("RX_COMP2 Switch", SND_SOC_NOPM, RX_MACRO_COMP2, 1, 0, rx_macro_get_compander, rx_macro_set_compander), + SOC_ENUM_EXT("HPH Idle Detect", hph_idle_detect_enum, + rx_macro_hph_idle_detect_get, rx_macro_hph_idle_detect_put), + SOC_ENUM_EXT("RX_EAR Mode", rx_macro_ear_mode_enum, rx_macro_get_ear_mode, rx_macro_put_ear_mode), -- GitLab From cf353edbf22da6f59bada9bff53e1e45217cc7b7 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Tue, 15 Jan 2019 16:49:02 +0800 Subject: [PATCH 0814/1645] dsp: validate token before usage as array index Token from DSP might be invalid for array index. Validate the token before being used as array index. Change-Id: I9f47e1328d75d9f9acf7e85ddb452019b6eced0a Signed-off-by: Xiaojun Sang --- dsp/q6afe.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 1b5c94d59a5f..b1e0dee950d2 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -460,6 +460,15 @@ static void afe_notify_spdif_fmt_update(void *payload) schedule_work(&this_afe.afe_spdif_work); } +static bool afe_token_is_valid(uint32_t token) +{ + if (token >= AFE_MAX_PORTS) { + pr_err("%s: token %d is invalid.\n", __func__, token); + return false; + } + return true; +} + static int32_t afe_callback(struct apr_client_data *data, void *priv) { if (!data) { @@ -536,7 +545,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) data->payload_size)) return -EINVAL; } - wake_up(&this_afe.wait[data->token]); + if (afe_token_is_valid(data->token)) + wake_up(&this_afe.wait[data->token]); + else + return -EINVAL; } else if (data->opcode == AFE_EVENT_MBHC_DETECTION_SW_WA) { msm_aud_evt_notifier_call_chain(SWR_WAKE_IRQ_EVENT, NULL); } else if (data->payload_size) { @@ -572,7 +584,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) case AFE_SVC_CMD_SET_PARAM_V2: case AFE_PORT_CMD_MOD_EVENT_CFG: atomic_set(&this_afe.state, 0); - wake_up(&this_afe.wait[data->token]); + if (afe_token_is_valid(data->token)) + wake_up(&this_afe.wait[data->token]); + else + return -EINVAL; break; case AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER: break; @@ -584,7 +599,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) break; case AFE_CMD_ADD_TOPOLOGIES: atomic_set(&this_afe.state, 0); - wake_up(&this_afe.wait[data->token]); + if (afe_token_is_valid(data->token)) + wake_up(&this_afe.wait[data->token]); + else + return -EINVAL; pr_debug("%s: AFE_CMD_ADD_TOPOLOGIES cmd 0x%x\n", __func__, payload[1]); break; @@ -608,7 +626,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) return 0; } atomic_set(&this_afe.state, payload[1]); - wake_up(&this_afe.wait[data->token]); + if (afe_token_is_valid(data->token)) + wake_up(&this_afe.wait[data->token]); + else + return -EINVAL; break; case AFE_SVC_CMD_EVENT_CFG: atomic_set(&this_afe.state, payload[1]); @@ -632,7 +653,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) else this_afe.mmap_handle = payload[0]; atomic_set(&this_afe.state, 0); - wake_up(&this_afe.wait[data->token]); + if (afe_token_is_valid(data->token)) + wake_up(&this_afe.wait[data->token]); + else + return -EINVAL; } else if (data->opcode == AFE_EVENT_RT_PROXY_PORT_STATUS) { port_id = (uint16_t)(0x0000FFFF & payload[0]); } else if (data->opcode == AFE_PORT_MOD_EVENT) { -- GitLab From 664bd4aa8dc6550ef318c3be04a6704d3be96d39 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 21 Feb 2019 13:30:34 -0800 Subject: [PATCH 0815/1645] asoc: msm: register wake irq of Tx macro Register wakeup of TX macro with HW interrupt line through wakeup irq. Change-Id: I1120b6155ca88ce6e1f8dcc163fc86227d606a8b Signed-off-by: Karthikeyan Mani --- asoc/kona.c | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/kona.c b/asoc/kona.c index b34b80afc18d..e721a2381687 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -3908,6 +3908,7 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) pdata->codec_root = entry; } bolero_info_create_codec_entry(pdata->codec_root, component); + bolero_register_wake_irq(component, false); codec_reg_done = true; return 0; err: -- GitLab From d6c61bd617c75a4052d40993f7b9abb898abd019 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 23 Feb 2019 05:11:43 +0530 Subject: [PATCH 0816/1645] ASoC: wcd938x: Clear tx hold hpf after device path setup During capture path setup, tx path hpf is set to hold. Clear tx path hpf hold after device path setup. Change-Id: I3299fc5d84d6e86e23c9ef150c8770ef9d59a870 Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd938x/wcd938x.c | 38 ++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 8ebef1f87a9d..8a5622fe8811 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -49,6 +49,10 @@ enum { }; enum { + WCD_ADC1 = 0, + WCD_ADC2, + WCD_ADC3, + WCD_ADC4, ALLOW_BUCK_DISABLE, HPH_COMP_DELAY, HPH_PA_DELAY, @@ -1227,12 +1231,14 @@ static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w, default: break; } + set_bit(w->shift, &wcd938x->status_mask); wcd938x_tx_connect_port(component, ADC1 + (w->shift), true); break; case SND_SOC_DAPM_POST_PMD: wcd938x_tx_connect_port(component, ADC1 + (w->shift), false); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00); + clear_bit(w->shift, &wcd938x->status_mask); break; }; @@ -1469,8 +1475,6 @@ static int wcd938x_event_notify(struct notifier_block *block, void *data) { u16 event = (val & 0xffff); - u16 amic; - u16 mask = 0x40, reg = 0x0; int ret = 0; struct wcd938x_priv *wcd938x = dev_get_drvdata((struct device *)data); struct snd_soc_component *component = wcd938x->component; @@ -1478,16 +1482,26 @@ static int wcd938x_event_notify(struct notifier_block *block, switch (event) { case BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR: - amic = (val >> 0x10); - if (amic == 0x1 || amic == 0x2) - reg = WCD938X_ANA_TX_CH2; - else if (amic == 0x3) - reg = WCD938X_ANA_TX_CH4; - else - return 0; - if (amic == 0x2) - mask = 0x20; - snd_soc_component_update_bits(component, reg, mask, 0x00); + if (test_bit(WCD_ADC1, &wcd938x->status_mask)) { + snd_soc_component_update_bits(component, + WCD938X_ANA_TX_CH2, 0x40, 0x00); + clear_bit(WCD_ADC1, &wcd938x->status_mask); + } + if (test_bit(WCD_ADC2, &wcd938x->status_mask)) { + snd_soc_component_update_bits(component, + WCD938X_ANA_TX_CH2, 0x20, 0x00); + clear_bit(WCD_ADC2, &wcd938x->status_mask); + } + if (test_bit(WCD_ADC3, &wcd938x->status_mask)) { + snd_soc_component_update_bits(component, + WCD938X_ANA_TX_CH4, 0x40, 0x00); + clear_bit(WCD_ADC3, &wcd938x->status_mask); + } + if (test_bit(WCD_ADC4, &wcd938x->status_mask)) { + snd_soc_component_update_bits(component, + WCD938X_ANA_TX_CH4, 0x20, 0x00); + clear_bit(WCD_ADC4, &wcd938x->status_mask); + } break; case BOLERO_WCD_EVT_PA_OFF_PRE_SSR: snd_soc_component_update_bits(component, WCD938X_ANA_HPH, -- GitLab From a60b408c5acaa91004eb09e8ead61fecba001341 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 25 Feb 2019 17:02:23 +0800 Subject: [PATCH 0817/1645] asoc: kona: enable us/euro function for analog type-c headset mbhc_mbhc_cfg.swap_gnd_mic is not initialized for analog type-c headset on Kona which causes headset detection fails. When analog type-c headset function is enabled on device, initialize swap_gnd_mic to msm_usbc_swap_gnd_mic to resolve this issue. Change-Id: Ia8244e41cbfa7c8844b761ff129a7d2cced0dacf Signed-off-by: Meng Wang --- asoc/kona.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/asoc/kona.c b/asoc/kona.c index ef2fbee02167..d8c81fc6c962 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -6164,6 +6164,15 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; } + if (wcd_mbhc_cfg.enable_usbc_analog) + wcd_mbhc_cfg.swap_gnd_mic = msm_usbc_swap_gnd_mic; + + pdata->fsa_handle = of_parse_phandle(pdev->dev.of_node, + "fsa4480-i2c-handle", 0); + if (!pdata->fsa_handle) + dev_dbg(&pdev->dev, "property %s not detected in node %s\n", + "fsa4480-i2c-handle", pdev->dev.of_node->full_name); + msm_i2s_auxpcm_init(pdev); pdata->dmic01_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,cdc-dmic01-gpios", -- GitLab From 45e2e65529ad002614b876bc0ade4a203c198469 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 11 Jan 2019 20:18:55 +0530 Subject: [PATCH 0818/1645] asoc: sm6150: Add support for tasha snd card variants Add DAI links and sound card registration support for tasha sound card variants. Change-Id: If93dc1dae2f10f9ac6b8e2e80a9e38cadc14289b Signed-off-by: Aditya Bavanari --- asoc/sm6150.c | 690 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 651 insertions(+), 39 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 55fe17875df8..c59da4c09b76 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -29,6 +29,7 @@ #include "msm-pcm-routing-v2.h" #include #include "codecs/wcd934x/wcd934x.h" +#include "codecs/wcd9335.h" #include "codecs/wcd934x/wcd934x-mbhc.h" #include "codecs/wcd937x/wcd937x-mbhc.h" #include "codecs/wsa881x.h" @@ -204,6 +205,8 @@ struct msm_asoc_mach_data { struct snd_info_entry *codec_root; int usbc_en2_gpio; /* used by gpio driver API */ struct device_node *mi2s_gpio_p[MI2S_MAX]; /* used by pinctrl API */ + int hph_en1_gpio; + int hph_en0_gpio; struct device_node *dmic01_gpio_p; /* used by pinctrl API */ struct device_node *dmic23_gpio_p; /* used by pinctrl API */ struct device_node *us_euro_gpio_p; /* used by pinctrl API */ @@ -659,7 +662,7 @@ static struct wcd_mbhc_config wcd_mbhc_cfg = { .enable_anc_mic_detect = false, }; -static struct snd_soc_dapm_route wcd_audio_paths_tavil[] = { +static struct snd_soc_dapm_route wcd_audio_paths[] = { {"MIC BIAS1", NULL, "MCLK TX"}, {"MIC BIAS2", NULL, "MCLK TX"}, {"MIC BIAS3", NULL, "MCLK TX"}, @@ -3578,7 +3581,7 @@ static const struct snd_kcontrol_new msm_int_snd_controls[] = { cdc_dma_tx_sample_rate_put), }; -static const struct snd_kcontrol_new msm_tavil_snd_controls[] = { +static const struct snd_kcontrol_new msm_ext_snd_controls[] = { SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, slim_rx_ch_get, slim_rx_ch_put), SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs, @@ -3867,6 +3870,8 @@ static int msm_snd_enable_codec_ext_clk(struct snd_soc_component *component, if (!strcmp(component->name, "tavil_codec")) { ret = tavil_cdc_mclk_enable(component, enable); + } else if (!strcmp(dev_name(component->dev), "tasha_codec")) { + ret = tasha_cdc_mclk_enable(component, enable, dapm); } else { dev_err(component->dev, "%s: unknown codec to enable ext clk\n", __func__); @@ -3882,6 +3887,8 @@ static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_component *component, if (!strcmp(component->name, "tavil_codec")) { ret = tavil_cdc_mclk_tx_enable(component, enable); + } else if (!strcmp(dev_name(component->dev), "tasha_codec")) { + ret = tasha_cdc_mclk_tx_enable(component, enable, dapm); } else { dev_err(component->dev, "%s: unknown codec to enable TX ext clk\n", __func__); @@ -3961,7 +3968,7 @@ static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w, return 0; } -static const struct snd_soc_dapm_widget msm_dapm_widgets_tavil[] = { +static const struct snd_soc_dapm_widget msm_ext_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, msm_mclk_event, @@ -3972,12 +3979,19 @@ static const struct snd_soc_dapm_widget msm_dapm_widgets_tavil[] = { SND_SOC_DAPM_SPK("Lineout_1 amp", NULL), SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_3 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_4 amp", NULL), SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event), SND_SOC_DAPM_MIC("Handset Mic", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Secondary Mic", NULL), SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL), + SND_SOC_DAPM_MIC("Analog Mic4", NULL), SND_SOC_DAPM_MIC("Analog Mic5", NULL), + SND_SOC_DAPM_MIC("Analog Mic6", NULL), + SND_SOC_DAPM_MIC("Analog Mic7", NULL), + SND_SOC_DAPM_MIC("Analog Mic8", NULL), SND_SOC_DAPM_MIC("Digital Mic0", NULL), SND_SOC_DAPM_MIC("Digital Mic1", NULL), @@ -3985,6 +3999,7 @@ static const struct snd_soc_dapm_widget msm_dapm_widgets_tavil[] = { SND_SOC_DAPM_MIC("Digital Mic3", NULL), SND_SOC_DAPM_MIC("Digital Mic4", NULL), SND_SOC_DAPM_MIC("Digital Mic5", NULL), + SND_SOC_DAPM_MIC("Digital Mic6", NULL), }; static int msm_dmic_event(struct snd_soc_dapm_widget *w, @@ -4744,6 +4759,28 @@ static void msm_afe_clear_config(void) afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); } +static int msm_config_hph_en0_gpio(struct snd_soc_component *component, bool high) +{ + struct snd_soc_card *card = component->card; + struct msm_asoc_mach_data *pdata; + int val; + + if (!card) + return 0; + + pdata = snd_soc_card_get_drvdata(card); + if (!pdata || !gpio_is_valid(pdata->hph_en0_gpio)) + return 0; + + val = gpio_get_value_cansleep(pdata->hph_en0_gpio); + if ((!!val) == high) + return 0; + + gpio_direction_output(pdata->hph_en0_gpio, (int)high); + + return 1; +} + static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; @@ -4781,8 +4818,8 @@ static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) } dapm = snd_soc_component_get_dapm(component); - ret = snd_soc_add_component_controls(component, msm_tavil_snd_controls, - ARRAY_SIZE(msm_tavil_snd_controls)); + ret = snd_soc_add_component_controls(component, msm_ext_snd_controls, + ARRAY_SIZE(msm_ext_snd_controls)); if (ret < 0) { pr_err("%s: add_codec_controls failed, err %d\n", __func__, ret); @@ -4797,11 +4834,11 @@ static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) return ret; } - snd_soc_dapm_new_controls(dapm, msm_dapm_widgets_tavil, - ARRAY_SIZE(msm_dapm_widgets_tavil)); + snd_soc_dapm_new_controls(dapm, msm_ext_dapm_widgets, + ARRAY_SIZE(msm_ext_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, wcd_audio_paths_tavil, - ARRAY_SIZE(wcd_audio_paths_tavil)); + snd_soc_dapm_add_routes(dapm, wcd_audio_paths, + ARRAY_SIZE(wcd_audio_paths)); snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); @@ -4892,6 +4929,183 @@ static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) return ret; } +static int msm_audrx_tasha_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = 0; + void *config_data; + struct snd_soc_component *component = NULL; + struct snd_soc_dapm_context *dapm; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_component *aux_comp; + struct snd_card *card; + struct snd_info_entry *entry; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); + + /* Codec SLIMBUS configuration + * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13 + * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 + * TX14, TX15, TX16 + */ + unsigned int rx_ch[TASHA_RX_MAX] = {144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156}; + unsigned int tx_ch[TASHA_TX_MAX] = {128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143}; + + pr_info("%s: dev_name:%s\n", __func__, dev_name(cpu_dai->dev)); + + rtd->pmdown_time = 0; + + component = snd_soc_rtdcom_lookup(rtd, "tasha_codec"); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + dapm = snd_soc_component_get_dapm(component); + + ret = snd_soc_add_component_controls(component, msm_ext_snd_controls, + ARRAY_SIZE(msm_ext_snd_controls)); + if (ret < 0) { + pr_err("%s: add_component_controls failed, err %d\n", + __func__, ret); + return ret; + } + + ret = snd_soc_add_component_controls(component, msm_common_snd_controls, + ARRAY_SIZE(msm_common_snd_controls)); + if (ret < 0) { + pr_err("%s: add_component_controls failed, err %d\n", + __func__, ret); + return ret; + } + + snd_soc_dapm_new_controls(dapm, msm_ext_dapm_widgets, + ARRAY_SIZE(msm_ext_dapm_widgets)); + + snd_soc_dapm_add_routes(dapm, wcd_audio_paths, + ARRAY_SIZE(wcd_audio_paths)); + + snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp"); + snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp"); + snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp"); + snd_soc_dapm_enable_pin(dapm, "Lineout_4 amp"); + + snd_soc_dapm_ignore_suspend(dapm, "MADINPUT"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT"); + snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Secondary Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Lineout_1 amp"); + snd_soc_dapm_ignore_suspend(dapm, "Lineout_2 amp"); + snd_soc_dapm_ignore_suspend(dapm, "Lineout_3 amp"); + snd_soc_dapm_ignore_suspend(dapm, "Lineout_4 amp"); + snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic7"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic8"); + + snd_soc_dapm_ignore_suspend(dapm, "EAR"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC4"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC5"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC0"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC4"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC5"); + snd_soc_dapm_ignore_suspend(dapm, "ANC EAR"); + snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); + snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); + + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT1"); + snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT2"); + + snd_soc_dapm_sync(dapm); + + snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); + + msm_codec_fn.get_afe_config_fn = tasha_get_afe_config; + + ret = msm_afe_set_config(component); + if (ret) { + pr_err("%s: Failed to set AFE config %d\n", __func__, ret); + goto err; + } + pdata->is_afe_config_done = true; + + config_data = msm_codec_fn.get_afe_config_fn(component, + AFE_AANC_VERSION); + if (config_data) { + ret = afe_set_config(AFE_AANC_VERSION, config_data, 0); + if (ret) { + pr_err("%s: Failed to set aanc version %d\n", + __func__, ret); + goto err; + } + } + + /* + * Send speaker configuration only for WSA8810. + * Default configuration is for WSA8815. + */ + pr_debug("%s: Number of aux devices: %d\n", + __func__, rtd->card->num_aux_devs); + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->aux_comp_list)) { + aux_comp = list_first_entry(&rtd->card->aux_comp_list, + struct snd_soc_component, card_aux_list); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { + tasha_set_spkr_mode(component, SPKR_MODE_1); + tasha_set_spkr_gain_offset(component, + RX_GAIN_OFFSET_M1P5_DB); + } + } + + card = rtd->card->snd_card; + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto err; + } + pdata->codec_root = entry; + tasha_codec_info_create_codec_entry(pdata->codec_root, component); + tasha_mbhc_zdet_gpio_ctrl(msm_config_hph_en0_gpio, component); + + codec_reg_done = true; + return 0; +err: + return ret; +} + static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; @@ -5297,6 +5511,48 @@ static int msm_wcn_hw_params(struct snd_pcm_substream *substream, return ret; } +int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + int ret = 0; + u32 tx_ch[SLIM_MAX_TX_PORTS]; + u32 tx_ch_cnt = 0; + + if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) { + pr_err("%s: Invalid stream type %d\n", + __func__, substream->stream); + ret = -EINVAL; + goto end; + } + + pr_debug("%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, NULL, NULL); + if (ret < 0) { + pr_err("%s: failed to get codec chan map\n, err:%d\n", + __func__, ret); + goto end; + } + + pr_debug("%s: tx_ch_cnt(%d) id %d\n", + __func__, tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, 0, 0); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto end; + } +end: + return ret; +} + static int msm_get_port_id(int be_id) { int afe_port_id; @@ -5780,6 +6036,9 @@ static struct snd_soc_ops msm_wcn_ops = { .hw_params = msm_wcn_hw_params, }; +static struct snd_soc_ops msm_ext_cpe_ops = { + .hw_params = msm_snd_cpe_hw_params, +}; /* Digital audio interface glue - connects codec <---> CPU */ static struct snd_soc_dai_link msm_common_dai_links[] = { @@ -6382,7 +6641,6 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { }, }; - static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = { {/* hw:x,37 */ .name = LPASS_BE_SLIMBUS_4_TX, @@ -6513,6 +6771,96 @@ static struct snd_soc_dai_link msm_bolero_fe_dai_links[] = { }, }; +static struct snd_soc_dai_link msm_tasha_fe_dai_links[] = { + /* tasha_vifeedback for speaker protection */ + { + .name = LPASS_BE_SLIMBUS_4_TX, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_vifeedback", + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + }, + /* Ultrasound RX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Playback", + .stream_name = "SLIMBUS_2 Hostless Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx2", + .ignore_suspend = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .ignore_pmdown_time = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_slimbus_2_be_ops, + }, + /* Ultrasound TX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Capture", + .stream_name = "SLIMBUS_2 Hostless Capture", + .cpu_dai_name = "msm-dai-q6-dev.16389", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx2", + .ignore_suspend = 1, + .dpcm_capture = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_slimbus_2_be_ops, + }, + /* CPE LSM direct dai-link */ + { + .name = "CPE Listen service", + .stream_name = "CPE Listen Audio Service", + .cpu_dai_name = "msm-dai-slim", + .platform_name = "msm-cpe-lsm", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .dpcm_capture = 1, + .codec_dai_name = "tasha_mad1", + .codec_name = "tasha_codec", + .ops = &msm_ext_cpe_ops, + }, + { + .name = "SLIMBUS_6 Hostless Playback", + .stream_name = "SLIMBUS_6 Hostless", + .cpu_dai_name = "SLIMBUS6_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + /* CPE LSM EC PP direct dai-link */ + { + .name = "CPE Listen service ECPP", + .stream_name = "CPE Listen Audio Service ECPP", + .cpu_dai_name = "CPE_LSM_NOHOST", + .platform_name = "msm-cpe-lsm.3", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "tasha_cpe", + .codec_name = "tasha_codec", + }, +}; + static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { { .name = MSM_DAILINK_NAME(ASM Loopback), @@ -6998,6 +7346,165 @@ static struct snd_soc_dai_link msm_tavil_be_dai_links[] = { }, }; +static struct snd_soc_dai_link msm_tasha_be_dai_links[] = { + /* Backend DAI Links */ + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_tasha_init, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_1_RX, + .stream_name = "Slimbus1 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16386", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_1_TX, + .stream_name = "Slimbus1 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16387", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx3", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_RX, + .stream_name = "Slimbus3 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16390", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_TX, + .stream_name = "Slimbus3 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16391", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_4_RX, + .stream_name = "Slimbus4 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16392", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_5_RX, + .stream_name = "Slimbus5 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16394", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx3", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* MAD BE */ + { + .name = LPASS_BE_SLIMBUS_5_TX, + .stream_name = "Slimbus5 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16395", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mad1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_6_RX, + .stream_name = "Slimbus6 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16396", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx4", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { { .name = LPASS_BE_SLIMBUS_7_RX, @@ -7519,10 +8026,12 @@ static struct snd_soc_dai_link msm_sm6150_dai_links[ ARRAY_SIZE(msm_common_dai_links) + ARRAY_SIZE(msm_tavil_fe_dai_links) + ARRAY_SIZE(msm_bolero_fe_dai_links) + + ARRAY_SIZE(msm_tasha_fe_dai_links) + ARRAY_SIZE(msm_common_misc_fe_dai_links) + ARRAY_SIZE(msm_int_compress_capture_dai) + ARRAY_SIZE(msm_common_be_dai_links) + ARRAY_SIZE(msm_tavil_be_dai_links) + + ARRAY_SIZE(msm_tasha_be_dai_links) + ARRAY_SIZE(msm_wcn_be_dai_links) + ARRAY_SIZE(ext_disp_be_dai_link) + ARRAY_SIZE(msm_mi2s_be_dai_links) + @@ -7574,6 +8083,50 @@ static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) return ret; } +static int msm_snd_card_tasha_late_probe(struct snd_soc_card *card) +{ + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + struct snd_soc_component *component; + int ret = 0; + void *mbhc_calibration; + + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err_pcm_runtime; + } + + component = snd_soc_rtdcom_lookup(rtd, "tasha_codec"); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + ret = -EINVAL; + goto err_pcm_runtime; + } + + mbhc_calibration = def_wcd_mbhc_cal(); + if (!mbhc_calibration) { + ret = -ENOMEM; + goto err_mbhc_cal; + } + wcd_mbhc_cfg.calibration = mbhc_calibration; + ret = tasha_mbhc_hs_detect(component, &wcd_mbhc_cfg); + if (ret) { + dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", + __func__, ret); + goto err_hs_detect; + } + return 0; + +err_hs_detect: + kfree(mbhc_calibration); +err_mbhc_cal: +err_pcm_runtime: + return ret; +} static int msm_populate_dai_link_component_of_node( struct snd_soc_card *card) @@ -7667,8 +8220,8 @@ static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, "msm-stub-codec"); - ret = snd_soc_add_component_controls(component, msm_tavil_snd_controls, - ARRAY_SIZE(msm_tavil_snd_controls)); + ret = snd_soc_add_component_controls(component, msm_ext_snd_controls, + ARRAY_SIZE(msm_ext_snd_controls)); if (ret < 0) { dev_err(component->dev, "%s: add_codec_controls failed, err = %d\n", @@ -7798,6 +8351,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) u32 mi2s_audio_intf = 0, ext_disp_audio_intf = 0; u32 wcn_btfm_intf = 0; const struct of_device_id *match; + u32 tasha_codec = 0; match = of_match_node(sm6150_asoc_machine_of_match, dev->of_node); if (!match) { @@ -7822,22 +8376,33 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) rc = of_property_read_u32(dev->of_node, "qcom,tavil_codec", &tavil_codec); - if (rc) { + if (rc) dev_dbg(dev, "%s: No DT match for tavil codec\n", __func__); - } else { - if (tavil_codec) { - card->late_probe = - msm_snd_card_tavil_late_probe; - memcpy(msm_sm6150_dai_links + total_links, - msm_tavil_fe_dai_links, - sizeof(msm_tavil_fe_dai_links)); - total_links += - ARRAY_SIZE(msm_tavil_fe_dai_links); - } - } - if (!tavil_codec) { + rc = of_property_read_u32(dev->of_node, "qcom,tasha_codec", + &tasha_codec); + if (rc) + dev_dbg(dev, "%s: No DT match for tasha codec\n", + __func__); + + if (tavil_codec) { + card->late_probe = + msm_snd_card_tavil_late_probe; + memcpy(msm_sm6150_dai_links + total_links, + msm_tavil_fe_dai_links, + sizeof(msm_tavil_fe_dai_links)); + total_links += + ARRAY_SIZE(msm_tavil_fe_dai_links); + } else if (tasha_codec) { + card->late_probe = + msm_snd_card_tasha_late_probe; + memcpy(msm_sm6150_dai_links + total_links, + msm_tasha_fe_dai_links, + sizeof(msm_tasha_fe_dai_links)); + total_links += + ARRAY_SIZE(msm_tasha_fe_dai_links); + } else { memcpy(msm_sm6150_dai_links + total_links, msm_bolero_fe_dai_links, sizeof(msm_bolero_fe_dai_links)); @@ -7862,6 +8427,11 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) msm_tavil_be_dai_links, sizeof(msm_tavil_be_dai_links)); total_links += ARRAY_SIZE(msm_tavil_be_dai_links); + } else if (tasha_codec) { + memcpy(msm_sm6150_dai_links + total_links, + msm_tasha_be_dai_links, + sizeof(msm_tasha_be_dai_links)); + total_links += ARRAY_SIZE(msm_tasha_be_dai_links); } else { memcpy(msm_sm6150_dai_links + total_links, msm_wsa_cdc_dma_be_dai_links, @@ -8196,7 +8766,8 @@ static int msm_init_aux_dev(struct platform_device *pdev, __func__, found); codec_aux_dev: - if (strcmp(card->name, "sm6150-tavil-snd-card")) { + if (!strnstr(card->name, "tavil", sizeof("tavil")) && + !strnstr(card->name, "tasha", sizeof("tasha"))) { /* Get maximum aux codec device count for this platform */ ret = of_property_read_u32(pdev->dev.of_node, "qcom,codec-max-aux-devs", @@ -8431,7 +9002,8 @@ static int sm6150_ssr_enable(struct device *dev, void *data) goto err; } - if (!strcmp(card->name, "sm6150-tavil-snd-card")) { + if (strnstr(card->name, "tavil", sizeof("tavil")) || + strnstr(card->name, "tasha", sizeof("tasha"))) { pdata = snd_soc_card_get_drvdata(card); if (!pdata->is_afe_config_done) { const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; @@ -8481,13 +9053,41 @@ static void sm6150_ssr_disable(struct device *dev, void *data) dev_dbg(dev, "%s: setting snd_card to OFFLINE\n", __func__); snd_soc_card_change_online_state(card, 0); - if (!strcmp(card->name, "sm6150-tavil-snd-card")) { + if (strnstr(card->name, "tavil", sizeof("tavil")) || + strnstr(card->name, "tasha", sizeof("tasha"))) { pdata = snd_soc_card_get_drvdata(card); msm_afe_clear_config(); pdata->is_afe_config_done = false; } } +static int msm_ext_prepare_hifi(struct msm_asoc_mach_data *pdata) +{ + int ret = 0; + + if (gpio_is_valid(pdata->hph_en1_gpio)) { + pr_debug("%s: hph_en1_gpio request %d\n", __func__, + pdata->hph_en1_gpio); + ret = gpio_request(pdata->hph_en1_gpio, "hph_en1_gpio"); + if (ret) { + pr_err("%s: hph_en1_gpio request failed, ret:%d\n", + __func__, ret); + goto err; + } + } + if (gpio_is_valid(pdata->hph_en0_gpio)) { + pr_debug("%s: hph_en0_gpio request %d\n", __func__, + pdata->hph_en0_gpio); + ret = gpio_request(pdata->hph_en0_gpio, "hph_en0_gpio"); + if (ret) + pr_err("%s: hph_en0_gpio request failed, ret:%d\n", + __func__, ret); + } + +err: + return ret; +} + static const struct snd_event_ops sm6150_ssr_ops = { .enable = sm6150_ssr_enable, .disable = sm6150_ssr_disable, @@ -8589,20 +9189,31 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) } dev_info(&pdev->dev, "Sound card %s registered\n", card->name); - pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, + pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,hph-en1-gpio", 0); - if (!pdata->hph_en1_gpio_p) { - dev_dbg(&pdev->dev, "property %s not detected in node %s\n", - "qcom,hph-en1-gpio", - pdev->dev.of_node->full_name); + if (!gpio_is_valid(pdata->hph_en1_gpio)) + pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en1-gpio", 0); + if (!gpio_is_valid(pdata->hph_en1_gpio) && (!pdata->hph_en1_gpio_p)) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,hph-en1-gpio", pdev->dev.of_node->full_name); } - pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, + pdata->hph_en0_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,hph-en0-gpio", 0); - if (!pdata->hph_en0_gpio_p) { - dev_dbg(&pdev->dev, "property %s not detected in node %s\n", - "qcom,hph-en0-gpio", - pdev->dev.of_node->full_name); + if (!gpio_is_valid(pdata->hph_en0_gpio)) + pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en0-gpio", 0); + if (!gpio_is_valid(pdata->hph_en0_gpio) && (!pdata->hph_en0_gpio_p)) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,hph-en0-gpio", pdev->dev.of_node->full_name); + } + + ret = msm_ext_prepare_hifi(pdata); + if (ret) { + dev_dbg(&pdev->dev, "msm_ext_prepare_hifi failed (%d)\n", + ret); + ret = 0; } ret = of_property_read_string(pdev->dev.of_node, @@ -8669,7 +9280,8 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) } msm_i2s_auxpcm_init(pdev); - if (strcmp(card->name, "sm6150-tavil-snd-card")) { + if (!strnstr(card->name, "tavil", sizeof("tavil")) && + !strnstr(card->name, "tasha", sizeof("tasha"))) { pdata->dmic01_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,cdc-dmic01-gpios", 0); -- GitLab From 35e7ec72bb8c437e4287f0b940e06a4e3e24c9fa Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Fri, 18 Jan 2019 15:12:30 +0530 Subject: [PATCH 0819/1645] asoc: qcs405: enable lineout booster GPIO Activate lineout booster GPIO during starting lineout usecase and disable during shuttingdown the lineout usecase in qcs405. Change-Id: I83877e6a531efc4b571d9868f1b019af5d9b1b82 Signed-off-by: Mangesh Kunchamwar --- asoc/qcs405.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 6e4596fdad7e..4d60c6e98238 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -179,6 +179,7 @@ struct msm_asoc_mach_data { struct device_node *dmic_23_gpio_p; /* used by pinctrl API */ struct device_node *dmic_45_gpio_p; /* used by pinctrl API */ struct device_node *dmic_67_gpio_p; /* used by pinctrl API */ + struct device_node *lineout_booster_gpio_p; /* used by pinctrl API */ struct device_node *mi2s_gpio_p[MI2S_MAX]; /* used by pinctrl API */ int dmic_01_gpio_cnt; int dmic_23_gpio_cnt; @@ -3838,6 +3839,30 @@ static int msm_mclk_event(struct snd_soc_dapm_widget *w, return 0; } +static int msm_lineout_booster_ctrl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct snd_soc_card *card = component->card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + + pr_debug("%s: event = %d\n", __func__, event); + switch (event) { + case SND_SOC_DAPM_POST_PMU: + msm_cdc_pinctrl_select_active_state( + pdata->lineout_booster_gpio_p); + break; + case SND_SOC_DAPM_PRE_PMD: + msm_cdc_pinctrl_select_sleep_state( + pdata->lineout_booster_gpio_p); + break; + } + + return 0; +} + static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, @@ -3847,6 +3872,7 @@ static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0, msm_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SPK("lineout booster", msm_lineout_booster_ctrl_event), SND_SOC_DAPM_MIC("Analog Mic3", NULL), SND_SOC_DAPM_MIC("Analog Mic4", NULL), @@ -5047,7 +5073,6 @@ static int msm_snd_hw_params(struct snd_pcm_substream *substream, return ret; } - static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -8603,6 +8628,8 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) "qcom,cdc-dmic45-gpios", 0); pdata->dmic_67_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,cdc-dmic67-gpios", 0); + pdata->lineout_booster_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,lineout-booster-gpio", 0); pdata->mi2s_gpio_p[PRIM_MI2S] = of_parse_phandle(pdev->dev.of_node, "qcom,pri-mi2s-gpios", 0); -- GitLab From 054e70ec0ee6e82c2c253884db37d207790b8899 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 25 Jan 2019 19:34:16 +0530 Subject: [PATCH 0820/1645] asoc: sm6150: Fix logic in comparison of sound card name Use strlen instead of sizeof in strnstr operations to return the exact size of sound card name. Change-Id: Id579a41ed79d4443dac7dd2e709784e9dfa186ac Signed-off-by: Aditya Bavanari --- asoc/sm6150.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index c59da4c09b76..4e084e312f25 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -8766,8 +8766,8 @@ static int msm_init_aux_dev(struct platform_device *pdev, __func__, found); codec_aux_dev: - if (!strnstr(card->name, "tavil", sizeof("tavil")) && - !strnstr(card->name, "tasha", sizeof("tasha"))) { + if (!strnstr(card->name, "tavil", strlen(card->name)) && + !strnstr(card->name, "tasha", strlen(card->name))) { /* Get maximum aux codec device count for this platform */ ret = of_property_read_u32(pdev->dev.of_node, "qcom,codec-max-aux-devs", @@ -9002,8 +9002,8 @@ static int sm6150_ssr_enable(struct device *dev, void *data) goto err; } - if (strnstr(card->name, "tavil", sizeof("tavil")) || - strnstr(card->name, "tasha", sizeof("tasha"))) { + if (strnstr(card->name, "tavil", strlen(card->name)) || + strnstr(card->name, "tasha", strlen(card->name))) { pdata = snd_soc_card_get_drvdata(card); if (!pdata->is_afe_config_done) { const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; @@ -9053,8 +9053,8 @@ static void sm6150_ssr_disable(struct device *dev, void *data) dev_dbg(dev, "%s: setting snd_card to OFFLINE\n", __func__); snd_soc_card_change_online_state(card, 0); - if (strnstr(card->name, "tavil", sizeof("tavil")) || - strnstr(card->name, "tasha", sizeof("tasha"))) { + if (strnstr(card->name, "tavil", strlen(card->name)) || + strnstr(card->name, "tasha", strlen(card->name))) { pdata = snd_soc_card_get_drvdata(card); msm_afe_clear_config(); pdata->is_afe_config_done = false; @@ -9280,8 +9280,8 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) } msm_i2s_auxpcm_init(pdev); - if (!strnstr(card->name, "tavil", sizeof("tavil")) && - !strnstr(card->name, "tasha", sizeof("tasha"))) { + if (!strnstr(card->name, "tavil", strlen(card->name)) && + !strnstr(card->name, "tasha", strlen(card->name))) { pdata->dmic01_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,cdc-dmic01-gpios", 0); -- GitLab From 5b2d30fa263046a00116145e55a48773edc5725d Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 28 Jan 2019 20:17:32 +0530 Subject: [PATCH 0821/1645] asoc: sm6150: Correct codec_root entry creation logic Create codec root entry only if it is not created already in proc directory to avoid failures in codec version entry enumeration. Change-Id: I8c912be5fb0f229a3b5a088ebb5c0aeea06f67b2 Signed-off-by: Aditya Bavanari --- asoc/sm6150.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 4e084e312f25..96533faa9528 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -4912,15 +4912,17 @@ static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) } card = rtd->card->snd_card; - entry = snd_info_create_subdir(card->module, "codecs", - card->proc_root); - if (!entry) { - pr_debug("%s: Cannot create codecs module entry\n", - __func__); - ret = 0; - goto err; + if (!pdata->codec_root) { + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto err; + } + pdata->codec_root = entry; } - pdata->codec_root = entry; tavil_codec_info_create_codec_entry(pdata->codec_root, component); codec_reg_done = true; @@ -5088,15 +5090,17 @@ static int msm_audrx_tasha_init(struct snd_soc_pcm_runtime *rtd) } card = rtd->card->snd_card; - entry = snd_info_create_subdir(card->module, "codecs", - card->proc_root); - if (!entry) { - pr_debug("%s: Cannot create codecs module entry\n", - __func__); - ret = 0; - goto err; + if (!pdata->codec_root) { + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto err; + } + pdata->codec_root = entry; } - pdata->codec_root = entry; tasha_codec_info_create_codec_entry(pdata->codec_root, component); tasha_mbhc_zdet_gpio_ctrl(msm_config_hph_en0_gpio, component); -- GitLab From 6c0100f281bbcf8106e28f3d823ed0869e55d144 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Fri, 1 Feb 2019 17:55:06 -0800 Subject: [PATCH 0822/1645] dsp: codecs: fix range check for audio buffer copying The range checking for audio buffer copying in function "audio_in_write" is using the incorrect buffer size. Change it to the actual allocated audio buffer size. Change-Id: Icb9a9e9c3b3d3c6e55e7bad20b34f94784b82674 Signed-off-by: Xiaoyu Ye --- dsp/codecs/audio_utils.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dsp/codecs/audio_utils.c b/dsp/codecs/audio_utils.c index 1c44fcceb7f4..26e9b0b36044 100644 --- a/dsp/codecs/audio_utils.c +++ b/dsp/codecs/audio_utils.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2010-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2019, The Linux Foundation. All rights reserved. */ #include @@ -900,9 +900,8 @@ ssize_t audio_in_write(struct file *file, __func__, audio->ac->session); } } - xfer = (count > (audio->pcm_cfg.buffer_size)) ? - (audio->pcm_cfg.buffer_size) : count; + xfer = (count > size) ? size : count; if (copy_from_user(cpy_ptr, buf, xfer)) { rc = -EFAULT; break; -- GitLab From 2797084510a4fc6ddeba1b60e709be328fe086c5 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 26 Feb 2019 13:16:12 -0800 Subject: [PATCH 0823/1645] asoc: codecs: bolero: leave frame sync to default value Frame sync of bolero macros need to be at 4KHz default value. Change-Id: Ia5399a3c4bee7e0f74115e5ffcb1ed51cbd07639 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/tx-macro.c | 3 --- asoc/codecs/bolero/wsa-macro.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index b24721fea806..12123ecdd6f0 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1456,9 +1456,6 @@ static int tx_macro_swrm_clock(void *handle, bool enable) BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, 0x02, 0x00); tx_priv->reset_swr = false; - regmap_update_bits(regmap, - BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, - 0x1C, 0x0C); msm_cdc_pinctrl_select_active_state( tx_priv->tx_swr_gpio_p); } diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 00d3d2c7782b..3c684243f333 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -2589,9 +2589,6 @@ static int wsa_swrm_clock(void *handle, bool enable) BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 0x02, 0x00); wsa_priv->reset_swr = false; - regmap_update_bits(regmap, - BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, - 0x1C, 0x0C); msm_cdc_pinctrl_select_active_state( wsa_priv->wsa_swr_gpio_p); } -- GitLab From d19d0c5636255d919a55e29ea5f09e2db3eb4f56 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 23 Feb 2019 05:41:39 +0530 Subject: [PATCH 0824/1645] soc: soundwire: Handle interrupts based on soundwire version Some of the interrupt status bits of soundwire interrupt registers are different in different versions of soundwire. Change is to handle the interrupts based on soundwire version. Change-Id: Icac65c9986a3d5724da6343b4202931f04f57f25 Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 191 ++++++++++++++++++++++++++++++++++++++++++- soc/swrm_registers.h | 9 +- 2 files changed, 198 insertions(+), 2 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 2235934a727d..f9dbc24af097 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1415,6 +1415,195 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) return ret; } +static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) +{ + struct swr_mstr_ctrl *swrm = dev; + u32 value, intr_sts, intr_sts_masked; + u32 temp = 0; + u32 status, chg_sts, i; + u8 devnum = 0; + int ret = IRQ_HANDLED; + struct swr_device *swr_dev; + struct swr_master *mstr = &swrm->master; + + if (unlikely(swrm_lock_sleep(swrm) == false)) { + dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__); + return IRQ_NONE; + } + + mutex_lock(&swrm->reslock); + swrm_clk_request(swrm, true); + mutex_unlock(&swrm->reslock); + + intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); + intr_sts_masked = intr_sts & swrm->intr_mask; +handle_irq: + for (i = 0; i < SWRM_INTERRUPT_MAX; i++) { + value = intr_sts_masked & (1 << i); + if (!value) + continue; + + switch (value) { + case SWRM_INTERRUPT_STATUS_SLAVE_PEND_IRQ: + dev_dbg(swrm->dev, "%s: Trigger irq to slave device\n", + __func__); + status = swr_master_read(swrm, SWRM_MCP_SLV_STATUS); + ret = swrm_find_alert_slave(swrm, status, &devnum); + if (ret) { + dev_err_ratelimited(swrm->dev, + "%s: no slave alert found.spurious interrupt\n", + __func__); + break; + } + swrm_cmd_fifo_rd_cmd(swrm, &temp, devnum, 0x0, + SWRS_SCP_INT_STATUS_CLEAR_1, 1); + swrm_cmd_fifo_wr_cmd(swrm, 0x4, devnum, 0x0, + SWRS_SCP_INT_STATUS_CLEAR_1); + swrm_cmd_fifo_wr_cmd(swrm, 0x0, devnum, 0x0, + SWRS_SCP_INT_STATUS_CLEAR_1); + + + list_for_each_entry(swr_dev, &mstr->devices, dev_list) { + if (swr_dev->dev_num != devnum) + continue; + if (swr_dev->slave_irq) { + do { + handle_nested_irq( + irq_find_mapping( + swr_dev->slave_irq, 0)); + } while (swr_dev->slave_irq_pending); + } + + } + break; + case SWRM_INTERRUPT_STATUS_NEW_SLAVE_ATTACHED: + dev_dbg(swrm->dev, "%s: SWR new slave attached\n", + __func__); + break; + case SWRM_INTERRUPT_STATUS_CHANGE_ENUM_SLAVE_STATUS: + status = swr_master_read(swrm, SWRM_MCP_SLV_STATUS); + if (status == swrm->slave_status) { + dev_dbg(swrm->dev, + "%s: No change in slave status: %d\n", + __func__, status); + break; + } + chg_sts = swrm_check_slave_change_status(swrm, status, + &devnum); + switch (chg_sts) { + case SWR_NOT_PRESENT: + dev_dbg(swrm->dev, + "%s: device %d got detached\n", + __func__, devnum); + break; + case SWR_ATTACHED_OK: + dev_dbg(swrm->dev, + "%s: device %d got attached\n", + __func__, devnum); + /* enable host irq from slave device*/ + swrm_cmd_fifo_wr_cmd(swrm, 0xFF, devnum, 0x0, + SWRS_SCP_INT_STATUS_CLEAR_1); + swrm_cmd_fifo_wr_cmd(swrm, 0x4, devnum, 0x0, + SWRS_SCP_INT_STATUS_MASK_1); + + break; + case SWR_ALERT: + dev_dbg(swrm->dev, + "%s: device %d has pending interrupt\n", + __func__, devnum); + break; + } + break; + case SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET: + dev_err_ratelimited(swrm->dev, + "%s: SWR bus clsh detected\n", + __func__); + break; + case SWRM_INTERRUPT_STATUS_RD_FIFO_OVERFLOW: + dev_dbg(swrm->dev, "%s: SWR read FIFO overflow\n", + __func__); + break; + case SWRM_INTERRUPT_STATUS_RD_FIFO_UNDERFLOW: + dev_dbg(swrm->dev, "%s: SWR read FIFO underflow\n", + __func__); + break; + case SWRM_INTERRUPT_STATUS_WR_CMD_FIFO_OVERFLOW: + dev_dbg(swrm->dev, "%s: SWR write FIFO overflow\n", + __func__); + break; + case SWRM_INTERRUPT_STATUS_CMD_ERROR: + value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS); + dev_err_ratelimited(swrm->dev, + "%s: SWR CMD error, fifo status 0x%x, flushing fifo\n", + __func__, value); + swr_master_write(swrm, SWRM_CMD_FIFO_CMD, 0x1); + break; + case SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION: + dev_err_ratelimited(swrm->dev, + "%s: SWR Port collision detected\n", + __func__); + swrm->intr_mask &= ~SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION; + swr_master_write(swrm, + SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN, swrm->intr_mask); + break; + case SWRM_INTERRUPT_STATUS_READ_EN_RD_VALID_MISMATCH: + dev_dbg(swrm->dev, + "%s: SWR read enable valid mismatch\n", + __func__); + swrm->intr_mask &= + ~SWRM_INTERRUPT_STATUS_READ_EN_RD_VALID_MISMATCH; + swr_master_write(swrm, + SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN, swrm->intr_mask); + break; + case SWRM_INTERRUPT_STATUS_SPECIAL_CMD_ID_FINISHED: + complete(&swrm->broadcast); + dev_dbg(swrm->dev, "%s: SWR cmd id finished\n", + __func__); + break; + case SWRM_INTERRUPT_STATUS_AUTO_ENUM_FAILED_V2: + break; + case SWRM_INTERRUPT_STATUS_AUTO_ENUM_TABLE_IS_FULL_V2: + break; + case SWRM_INTERRUPT_STATUS_BUS_RESET_FINISHED_V2: + break; + case SWRM_INTERRUPT_STATUS_CLK_STOP_FINISHED_V2: + break; + case SWRM_INTERRUPT_STATUS_EXT_CLK_STOP_WAKEUP: + if (swrm->state == SWR_MSTR_UP) + dev_dbg(swrm->dev, + "%s:SWR Master is already up\n", + __func__); + else + dev_err_ratelimited(swrm->dev, + "%s: SWR wokeup during clock stop\n", + __func__); + break; + default: + dev_err_ratelimited(swrm->dev, + "%s: SWR unknown interrupt value: %d\n", + __func__, value); + ret = IRQ_NONE; + break; + } + } + swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, intr_sts); + swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, 0x0); + + intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); + intr_sts_masked = intr_sts & swrm->intr_mask; + + if (intr_sts_masked) { + dev_dbg(swrm->dev, "%s: new interrupt received\n", __func__); + goto handle_irq; + } + + mutex_lock(&swrm->reslock); + swrm_clk_request(swrm, false); + mutex_unlock(&swrm->reslock); + swrm_unlock_sleep(swrm); + return ret; +} + static irqreturn_t swrm_wakeup_interrupt(int irq, void *dev) { struct swr_mstr_ctrl *swrm = dev; @@ -1899,7 +2088,7 @@ static int swrm_probe(struct platform_device *pdev) } ret = request_threaded_irq(swrm->irq, NULL, - swr_mstr_interrupt, + swr_mstr_interrupt_v2, IRQF_TRIGGER_RISING | IRQF_ONESHOT, "swr_master_irq", swrm); if (ret) { diff --git a/soc/swrm_registers.h b/soc/swrm_registers.h index c53d37bc7c63..6f2544b17744 100644 --- a/soc/swrm_registers.h +++ b/soc/swrm_registers.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2015, 2018-2019 The Linux Foundation. All rights reserved. */ #ifndef _SWRM_REGISTERS_H @@ -49,6 +49,13 @@ #define SWRM_INTERRUPT_STATUS_CLK_STOP_FINISHED 0x8000 #define SWRM_INTERRUPT_STATUS_ERROR_PORT_TEST 0x10000 +#define SWRM_INTERRUPT_STATUS_AUTO_ENUM_FAILED_V2 0x800 +#define SWRM_INTERRUPT_STATUS_AUTO_ENUM_TABLE_IS_FULL_V2 0x1000 +#define SWRM_INTERRUPT_STATUS_BUS_RESET_FINISHED_V2 0x2000 +#define SWRM_INTERRUPT_STATUS_CLK_STOP_FINISHED_V2 0x4000 +#define SWRM_INTERRUPT_STATUS_ERROR_PORT_TEST_V2 0x8000 +#define SWRM_INTERRUPT_STATUS_EXT_CLK_STOP_WAKEUP 0x10000 + #define SWRM_INTERRUPT_MASK_ADDR (SWRM_BASE_ADDRESS+0x00000204) #define SWRM_INTERRUPT_MASK_RMSK 0x1FFFF -- GitLab From 3552462ec524404fcbbfa85aa5d17e334bbb7805 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Tue, 22 Jan 2019 11:13:09 -0800 Subject: [PATCH 0825/1645] dsp: adm: validate ADSP payload size before access Check the size of ADSP payload before accessing it. CRs-Fixed: 2380694 Change-Id: Ib0c0f0bf6c7f7cf659df0eb70a3f66cee580cb66 Signed-off-by: Vignesh Kulothungan --- dsp/q6adm.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 688012f727d9..7cc8e9b4cf0e 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -1317,12 +1317,22 @@ static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload, switch (opcode) { case ADM_CMDRSP_GET_PP_PARAMS_V5: struct_size = sizeof(struct adm_cmd_rsp_get_pp_params_v5); + if (payload_size < struct_size) { + pr_err("%s: payload size %d < expected size %d\n", + __func__, payload_size, struct_size); + break; + } v5_rsp = (struct adm_cmd_rsp_get_pp_params_v5 *) payload; data_size = v5_rsp->param_hdr.param_size; param_data = v5_rsp->param_data; break; case ADM_CMDRSP_GET_PP_PARAMS_V6: struct_size = sizeof(struct adm_cmd_rsp_get_pp_params_v6); + if (payload_size < struct_size) { + pr_err("%s: payload size %d < expected size %d\n", + __func__, payload_size, struct_size); + break; + } v6_rsp = (struct adm_cmd_rsp_get_pp_params_v6 *) payload; data_size = v6_rsp->param_hdr.param_size; param_data = v6_rsp->param_data; @@ -1518,6 +1528,11 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) return 0; } if (data->opcode == APR_BASIC_RSP_RESULT) { + if (data->payload_size < (2 * sizeof(uint32_t))) { + pr_err("%s: Invalid payload size %d\n", __func__, + data->payload_size); + return 0; + } pr_debug("%s: APR_BASIC_RSP_RESULT id 0x%x\n", __func__, payload[0]); if (payload[1] != 0) { @@ -1644,9 +1659,14 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) case ADM_CMDRSP_DEVICE_OPEN_V5: case ADM_CMDRSP_DEVICE_OPEN_V6: case ADM_CMDRSP_DEVICE_OPEN_V8: { - struct adm_cmd_rsp_device_open_v5 *open = - (struct adm_cmd_rsp_device_open_v5 *)data->payload; - + struct adm_cmd_rsp_device_open_v5 *open = NULL; + if (data->payload_size < + sizeof(struct adm_cmd_rsp_device_open_v5)) { + pr_err("%s: Invalid payload size %d\n", __func__, + data->payload_size); + return 0; + } + open = (struct adm_cmd_rsp_device_open_v5 *)data->payload; if (open->copp_id == INVALID_COPP_ID) { pr_err("%s: invalid coppid rxed %d\n", __func__, open->copp_id); -- GitLab From a34ba3f37270f3dad9029ba5badbad35a75a856b Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Thu, 17 Jan 2019 13:28:25 +0800 Subject: [PATCH 0826/1645] dsp: asm: validate payload size before access Payload size is not checked before payload access. Check size to avoid out-of-boundary memory access. Change-Id: Iaa39ee4ea5489bb5579e7b7d5dfada12d88c5809 Signed-off-by: Xiaojun Sang --- dsp/q6asm.c | 259 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 168 insertions(+), 91 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index acdd75903db8..680935098cc1 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1713,14 +1713,14 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) return 0; } - if (data->payload_size > sizeof(int)) { + if (data->payload_size >= 2 * sizeof(uint32_t)) { pr_debug("%s:ptr0[0x%x]ptr1[0x%x]opcode[0x%x] token[0x%x]payload_s[%d] src[%d] dest[%d]sid[%d]dir[%d]\n", __func__, payload[0], payload[1], data->opcode, data->token, data->payload_size, data->src_port, data->dest_port, asm_token._token.session_id, dir); pr_debug("%s:Payload = [0x%x] status[0x%x]\n", __func__, payload[0], payload[1]); - } else if (data->payload_size == sizeof(int)) { + } else if (data->payload_size == sizeof(uint32_t)) { pr_debug("%s:ptr0[0x%x]opcode[0x%x] token[0x%x]payload_s[%d] src[%d] dest[%d]sid[%d]dir[%d]\n", __func__, payload[0], data->opcode, data->token, data->payload_size, data->src_port, @@ -1734,7 +1734,7 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) case ASM_CMD_SHARED_MEM_MAP_REGIONS: case ASM_CMD_SHARED_MEM_UNMAP_REGIONS: case ASM_CMD_ADD_TOPOLOGIES: - if (payload[1] != 0) { + if (data->payload_size >= 2 * sizeof(uint32_t) && payload[1] != 0) { pr_err("%s: cmd = 0x%x returned error = 0x%x sid:%d\n", __func__, payload[0], payload[1], asm_token._token.session_id); @@ -1752,8 +1752,12 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) if (atomic_cmpxchg(&ac->mem_state, -1, 0) == -1) wake_up(&ac->mem_wait); - dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x]\n", + if (data->payload_size >= 2 * sizeof(uint32_t)) + dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x]\n", __func__, payload[0], payload[1]); + else + dev_vdbg(ac->dev, "%s: Payload size of %d is less than expected.\n", + __func__, data->payload_size); break; default: pr_debug("%s: command[0x%x] not expecting rsp\n", @@ -1782,8 +1786,13 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) break; } case ASM_CMD_SHARED_MEM_UNMAP_REGIONS:{ - pr_debug("%s: PL#0[0x%x]PL#1 [0x%x]\n", - __func__, payload[0], payload[1]); + if (data->payload_size >= 2 * sizeof(uint32_t)) + pr_debug("%s: PL#0[0x%x]PL#1 [0x%x]\n", + __func__, payload[0], payload[1]); + else + pr_debug("%s: Payload size of %d is less than expected.\n", + __func__, data->payload_size); + spin_lock_irqsave(&port->dsp_lock, dsp_flags); if (atomic_cmpxchg(&ac->mem_state, -1, 0) == -1) wake_up(&ac->mem_wait); @@ -1792,8 +1801,12 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) break; } default: - pr_debug("%s: command[0x%x]success [0x%x]\n", - __func__, payload[0], payload[1]); + if (data->payload_size >= 2 * sizeof(uint32_t)) + pr_debug("%s: command[0x%x]success [0x%x]\n", + __func__, payload[0], payload[1]); + else + pr_debug("%s: Payload size of %d is less than expected.\n", + __func__, data->payload_size); } if (ac->cb) ac->cb(data->opcode, data->token, @@ -1944,8 +1957,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) &(session[session_id].session_lock), flags); return -EINVAL; } - dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x] opcode 0x%x\n", - __func__, payload[0], payload[1], data->opcode); + if(data->payload_size >= 2 * sizeof(uint32_t)) + dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x] opcode 0x%x\n", + __func__, payload[0], payload[1], data->opcode); + else + dev_vdbg(ac->dev, "%s: Payload size of %d is less than expected.\n", + __func__, data->payload_size); } if (data->opcode == APR_BASIC_RSP_RESULT) { switch (payload[0]) { @@ -1991,32 +2008,37 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) case ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS: case ASM_STREAM_CMD_OPEN_READ_COMPRESSED: case ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED: - pr_debug("%s: session %d opcode 0x%x token 0x%x Payload = [0x%x] stat 0x%x src %d dest %d\n", - __func__, ac->session, - data->opcode, data->token, - payload[0], payload[1], - data->src_port, data->dest_port); - if (payload[1] != 0) { - pr_err("%s: cmd = 0x%x returned error = 0x%x\n", - __func__, payload[0], payload[1]); - if (wakeup_flag) { - if ((is_adsp_reg_event(payload[0]) >= - 0) || - (payload[0] == - ASM_STREAM_CMD_SET_PP_PARAMS_V2) || - (payload[0] == - ASM_STREAM_CMD_SET_PP_PARAMS_V3)) - atomic_set(&ac->cmd_state_pp, + if (data->payload_size >= 2 * sizeof(uint32_t)) { + pr_debug("%s: session %d opcode 0x%x token 0x%x Payload = [0x%x] stat 0x%x src %d dest %d\n", + __func__, ac->session, + data->opcode, data->token, + payload[0], payload[1], + data->src_port, data->dest_port); + if (payload[1] != 0) { + pr_err("%s: cmd = 0x%x returned error = 0x%x\n", + __func__, payload[0], payload[1]); + if (wakeup_flag) { + if ((is_adsp_reg_event(payload[0]) >= + 0) || + (payload[0] == + ASM_STREAM_CMD_SET_PP_PARAMS_V2) || + (payload[0] == + ASM_STREAM_CMD_SET_PP_PARAMS_V3)) + atomic_set(&ac->cmd_state_pp, payload[1]); - else - atomic_set(&ac->cmd_state, + else + atomic_set(&ac->cmd_state, payload[1]); - wake_up(&ac->cmd_wait); + wake_up(&ac->cmd_wait); + } + spin_unlock_irqrestore( + &(session[session_id].session_lock), + flags); + return 0; } - spin_unlock_irqrestore( - &(session[session_id].session_lock), - flags); - return 0; + } else { + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); } if ((is_adsp_reg_event(payload[0]) >= 0) || (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2) || @@ -2038,19 +2060,24 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) (uint32_t *)data->payload, ac->priv); break; case ASM_CMD_ADD_TOPOLOGIES: - pr_debug("%s:Payload = [0x%x]stat[0x%x]\n", - __func__, payload[0], payload[1]); - if (payload[1] != 0) { - pr_err("%s: cmd = 0x%x returned error = 0x%x\n", - __func__, payload[0], payload[1]); - if (wakeup_flag) { - atomic_set(&ac->mem_state, payload[1]); - wake_up(&ac->mem_wait); + if (data->payload_size >= 2 * sizeof(uint32_t)) { + pr_debug("%s:Payload = [0x%x]stat[0x%x]\n", + __func__, payload[0], payload[1]); + if (payload[1] != 0) { + pr_err("%s: cmd = 0x%x returned error = 0x%x\n", + __func__, payload[0], payload[1]); + if (wakeup_flag) { + atomic_set(&ac->mem_state, payload[1]); + wake_up(&ac->mem_wait); + } + spin_unlock_irqrestore( + &(session[session_id].session_lock), + flags); + return 0; } - spin_unlock_irqrestore( - &(session[session_id].session_lock), - flags); - return 0; + } else { + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); } if (atomic_read(&ac->mem_state) && wakeup_flag) { atomic_set(&ac->mem_state, 0); @@ -2061,8 +2088,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) (uint32_t *)data->payload, ac->priv); break; case ASM_DATA_EVENT_WATERMARK: { - pr_debug("%s: Watermark opcode[0x%x] status[0x%x]", - __func__, payload[0], payload[1]); + if (data->payload_size >= 2 * sizeof(uint32_t)) + pr_debug("%s: Watermark opcode[0x%x] status[0x%x]", + __func__, payload[0], payload[1]); + else + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); break; } case ASM_STREAM_CMD_GET_PP_PARAMS_V2: @@ -2074,11 +2105,16 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) /* error or malformed APR packet. Otherwise */ /* response will be returned as */ /* ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 */ - if (payload[1] != 0) { - pr_err("%s: ASM get param error = %d, resuming\n", - __func__, payload[1]); - rtac_make_asm_callback(ac->session, payload, - data->payload_size); + if (data->payload_size >= 2 * sizeof(uint32_t)) { + if (payload[1] != 0) { + pr_err("%s: ASM get param error = %d, resuming\n", + __func__, payload[1]); + rtac_make_asm_callback(ac->session, payload, + data->payload_size); + } + } else { + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); } break; case ASM_STREAM_CMD_REGISTER_PP_EVENTS: @@ -2086,11 +2122,16 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) __func__, ac->session, data->opcode, data->token, data->src_port, data->dest_port); - if (payload[1] != 0) - pr_err("%s: ASM get param error = %d, resuming\n", - __func__, payload[1]); - atomic_set(&ac->cmd_state_pp, payload[1]); - wake_up(&ac->cmd_wait); + if (data->payload_size >= 2 * sizeof(uint32_t)) { + if (payload[1] != 0) + pr_err("%s: ASM get param error = %d, resuming\n", + __func__, payload[1]); + atomic_set(&ac->cmd_state_pp, payload[1]); + wake_up(&ac->cmd_wait); + } else { + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); + } break; default: pr_debug("%s: command[0x%x] not expecting rsp\n", @@ -2106,10 +2147,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) switch (data->opcode) { case ASM_DATA_EVENT_WRITE_DONE_V2:{ struct audio_port_data *port = &ac->port[IN]; - - dev_vdbg(ac->dev, "%s: Rxed opcode[0x%x] status[0x%x] token[%d]", - __func__, payload[0], payload[1], - data->token); + if (data->payload_size >= 2 * sizeof(uint32_t)) + dev_vdbg(ac->dev, "%s: Rxed opcode[0x%x] status[0x%x] token[%d]", + __func__, payload[0], payload[1], + data->token); + else + dev_err(ac->dev, "%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); if (ac->io_mode & SYNC_IO_MODE) { if (port->buf == NULL) { pr_err("%s: Unexpected Write Done\n", @@ -2121,10 +2165,11 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) } spin_lock_irqsave(&port->dsp_lock, dsp_flags); buf_index = asm_token._token.buf_index; - if (lower_32_bits(port->buf[buf_index].phys) != - payload[0] || - msm_audio_populate_upper_32_bits( - port->buf[buf_index].phys) != payload[1]) { + if ( data->payload_size >= 2 * sizeof(uint32_t) && + (lower_32_bits(port->buf[buf_index].phys) != + payload[0] || + msm_audio_populate_upper_32_bits( + port->buf[buf_index].phys) != payload[1])) { pr_debug("%s: Expected addr %pK\n", __func__, &port->buf[buf_index].phys); pr_err("%s: rxedl[0x%x] rxedu [0x%x]\n", @@ -2159,14 +2204,25 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) } else if (generic_get_data) { generic_get_data->valid = 1; if (generic_get_data->is_inband) { - pr_debug("%s: payload[1] = 0x%x, payload[2]=0x%x, payload[3]=0x%x\n", - __func__, payload[1], payload[2], payload[3]); - generic_get_data->size_in_ints = payload[3]>>2; - for (i = 0; i < payload[3]>>2; i++) { - generic_get_data->ints[i] = - payload[4+i]; - pr_debug("%s: ASM callback val %i = %i\n", - __func__, i, payload[4+i]); + if (data->payload_size >= 4 * sizeof(uint32_t)) + pr_debug("%s: payload[1] = 0x%x, payload[2]=0x%x, payload[3]=0x%x\n", + __func__, payload[1], payload[2], payload[3]); + else + pr_err("%s: payload size of %x is less than expected.\n", + __func__, + data->payload_size); + + if (data->payload_size >= (4 + (payload[3]>>2)) * sizeof(uint32_t)) { + generic_get_data->size_in_ints = payload[3]>>2; + for (i = 0; i < payload[3]>>2; i++) { + generic_get_data->ints[i] = + payload[4+i]; + pr_debug("%s: ASM callback val %i = %i\n", + __func__, i, payload[4+i]); + } + } else { + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); } pr_debug("%s: callback size in ints = %i\n", __func__, @@ -2253,11 +2309,16 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) data->src_port, data->dest_port); break; case ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3: - dev_vdbg(ac->dev, "%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3, payload[0] = %d, payload[1] = %d, payload[2] = %d\n", - __func__, - payload[0], payload[1], payload[2]); - ac->time_stamp = (uint64_t)(((uint64_t)payload[2] << 32) | - payload[1]); + if (data->payload_size >= 3 * sizeof(uint32_t)) { + dev_vdbg(ac->dev, "%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3, payload[0] = %d, payload[1] = %d, payload[2] = %d\n", + __func__, + payload[0], payload[1], payload[2]); + ac->time_stamp = (uint64_t)(((uint64_t)payload[2] << 32) | + payload[1]); + } else { + dev_err(ac->dev, "%s: payload size of %x is less than expected.n", + __func__, data->payload_size); + } if (atomic_cmpxchg(&ac->time_flag, 1, 0)) wake_up(&ac->time_wait); break; @@ -2267,10 +2328,14 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) __func__, ac->session, data->opcode, data->token, data->src_port, data->dest_port); - pr_debug("%s: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, payload[0] = %d, payload[1] = %d, payload[2] = %d, payload[3] = %d\n", - __func__, - payload[0], payload[1], payload[2], - payload[3]); + if (data->payload_size >= 4 * sizeof(uint32_t)) + pr_debug("%s: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, payload[0] = %d, payload[1] = %d, payload[2] = %d, payload[3] = %d\n", + __func__, + payload[0], payload[1], payload[2], + payload[3]); + else + pr_debug("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); break; case ASM_SESSION_CMDRSP_GET_MTMX_STRTR_PARAMS_V2: q6asm_process_mtmx_get_param_rsp(ac, (void *) payload); @@ -2278,8 +2343,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) case ASM_STREAM_PP_EVENT: case ASM_STREAM_CMD_ENCDEC_EVENTS: case ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE: - pr_debug("%s: ASM_STREAM_EVENT payload[0][0x%x] payload[1][0x%x]", - __func__, payload[0], payload[1]); + if (data->payload_size >= 2 * sizeof(uint32_t)) + pr_debug("%s: ASM_STREAM_EVENT payload[0][0x%x] payload[1][0x%x]", + __func__, payload[0], payload[1]); + else + pr_debug("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); i = is_adsp_raise_event(data->opcode); if (i < 0) { spin_unlock_irqrestore( @@ -2318,16 +2387,24 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) &(session[session_id].session_lock), flags); return 0; case ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2: - pr_debug("%s: ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2 sesion %d status 0x%x msw %u lsw %u\n", - __func__, ac->session, payload[0], payload[2], - payload[1]); + if (data->payload_size >= 3 * sizeof(uint32_t)) + pr_debug("%s: ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2 sesion %d status 0x%x msw %u lsw %u\n", + __func__, ac->session, payload[0], payload[2], + payload[1]); + else + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); wake_up(&ac->cmd_wait); break; case ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2: - pr_debug("%s: ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2 session %d status 0x%x msw %u lsw %u\n", - __func__, ac->session, payload[0], payload[2], - payload[1]); - if (payload[0] == 0) { + if (data->payload_size >= 3 * sizeof(uint32_t)) + pr_debug("%s: ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2 session %d status 0x%x msw %u lsw %u\n", + __func__, ac->session, payload[0], payload[2], + payload[1]); + else + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); + if (payload[0] == 0 && data->payload_size >= 2 * sizeof(uint32_t)) { atomic_set(&ac->cmd_state, 0); /* ignore msw, as a delay that large shouldn't happen */ ac->path_delay = payload[1]; -- GitLab From 1c8aec0cfd1fb3ffebd079e120700cfe68f0b743 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 28 Jan 2019 18:54:56 +0530 Subject: [PATCH 0827/1645] dsp: q6usm: Check size of payload before access Check size of payload before access in q6usm_mmapcallback. Change-Id: Iff0672532c2ea40e7129237a92d8365d6b554cf2 Signed-off-by: Vatsal Bucha --- dsp/q6usm.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dsp/q6usm.c b/dsp/q6usm.c index ce25c71e137f..287d63c1ab8c 100644 --- a/dsp/q6usm.c +++ b/dsp/q6usm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -490,6 +490,11 @@ static int32_t q6usm_mmapcallback(struct apr_client_data *data, void *priv) uint32_t token; uint32_t *payload = data->payload; + if (data->payload_size < (2 * sizeof(uint32_t))) { + pr_err("%s: payload has invalid size[%d]\n", __func__, + data->payload_size); + return -EINVAL; + } pr_debug("%s: ptr0[0x%x]; ptr1[0x%x]; opcode[0x%x]\n", __func__, payload[0], payload[1], data->opcode); pr_debug("%s: token[0x%x]; payload_size[%d]; src[%d]; dest[%d];\n", -- GitLab From def212b8418ced1e198091ee674aae1f580afee2 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 28 Jan 2019 18:44:29 +0530 Subject: [PATCH 0828/1645] dsp: q6usm: Check size of payload before access Check size of payload array before access in q6usm_callback. Change-Id: Id0c85209a053f9dfdb53133aeb6b2510ecf18eb8 Signed-off-by: Vatsal Bucha --- dsp/q6usm.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dsp/q6usm.c b/dsp/q6usm.c index 287d63c1ab8c..70c3a6b7721a 100644 --- a/dsp/q6usm.c +++ b/dsp/q6usm.c @@ -556,6 +556,11 @@ static int32_t q6usm_callback(struct apr_client_data *data, void *priv) } if (data->opcode == APR_BASIC_RSP_RESULT) { + if (data->payload_size < (2 * sizeof(uint32_t))) { + pr_err("%s: payload has invalid size[%d]\n", __func__, + data->payload_size); + return -EINVAL; + } /* status field check */ if (payload[1]) { pr_err("%s: wrong response[%d] on cmd [%d]\n", @@ -619,6 +624,12 @@ static int32_t q6usm_callback(struct apr_client_data *data, void *priv) opcode = Q6USM_EVENT_READ_DONE; spin_lock_irqsave(&port->dsp_lock, dsp_flags); + if (data->payload_size < + (sizeof(uint32_t)*(READDONE_IDX_STATUS + 1))) { + pr_err("%s: Invalid payload size for READDONE[%d]\n", + __func__, data->payload_size); + return -EINVAL; + } if (payload[READDONE_IDX_STATUS]) { pr_err("%s: wrong READDONE[%d]; token[%d]\n", __func__, @@ -665,6 +676,12 @@ static int32_t q6usm_callback(struct apr_client_data *data, void *priv) struct us_port_data *port = &usc->port[IN]; opcode = Q6USM_EVENT_WRITE_DONE; + if (data->payload_size < + (sizeof(uint32_t)*(WRITEDONE_IDX_STATUS + 1))) { + pr_err("%s: Invalid payload size for WRITEDONE[%d]\n", + __func__, data->payload_size); + return -EINVAL; + } if (payload[WRITEDONE_IDX_STATUS]) { pr_err("%s: wrong WRITEDONE_IDX_STATUS[%d]\n", __func__, -- GitLab From 4ccf051bef861f7f9830dd3608026f5501e86956 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Thu, 17 Jan 2019 15:45:13 +0800 Subject: [PATCH 0829/1645] asoc: check payload length against structure size Payload length must exceed structure size. Otherwise, it may lead to out-of-boundary memory access. Change-Id: I090de5116ab04a4ca2b9c485e17617fe9e861ad5 Signed-off-by: Xiaojun Sang --- asoc/msm-qti-pp-config.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index 222a3a953236..74ad7d9f46cb 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include @@ -1172,6 +1172,13 @@ int msm_adsp_inform_mixer_ctl(struct snd_soc_pcm_runtime *rtd, } event_data = (struct msm_adsp_event_data *)payload; + if (event_data->payload_len < sizeof(struct msm_adsp_event_data)) { + pr_err("%s: event_data size of %x is less than expected.\n", + __func__, event_data->payload_len); + ret = -EINVAL; + goto done; + } + kctl->info(kctl, &kctl_info); if (event_data->payload_len > -- GitLab From 807f7e952140be196c75921a1f05910f7a2d38b2 Mon Sep 17 00:00:00 2001 From: Dhananjay Kumar Date: Tue, 11 Dec 2018 18:10:08 +0530 Subject: [PATCH 0830/1645] asoc: add support to set custom channel mixer coefficients Enhance Channel Mixer control for MultiMedia Frontends to get custom channel mixer coefficients from userspace and use it during device routings to control stream to device channel mappings. Change-Id: Icf950377dede46b097c8656174af5eb311bf719a Signed-off-by: Cong Tang Signed-off-by: Dhananjay Kumar --- asoc/msm-compress-q6-v2.c | 617 +++++++++++++++++++++++++++++++- asoc/msm-pcm-loopback-v2.c | 685 +++++++++++++++++++++++++++++++++++- asoc/msm-pcm-q6-v2.c | 702 +++++++++++++++++++++++++++++++++++++ asoc/msm-pcm-q6-v2.h | 4 +- asoc/msm-pcm-routing-v2.c | 178 ++++++++++ asoc/msm-pcm-routing-v2.h | 10 + 6 files changed, 2190 insertions(+), 6 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 2bde61af1057..4b77fbd6744e 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -101,6 +101,7 @@ struct msm_compr_pdata { struct msm_compr_dec_params *dec_params[MSM_FRONTEND_DAI_MAX]; struct msm_compr_ch_map *ch_map[MSM_FRONTEND_DAI_MAX]; bool is_in_use[MSM_FRONTEND_DAI_MAX]; + struct msm_pcm_channel_mixer *chmixer_pspd[MSM_FRONTEND_DAI_MM_SIZE]; }; struct msm_compr_audio { @@ -3711,6 +3712,7 @@ static int msm_compr_channel_map_put(struct snd_kcontrol *kcontrol, struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) snd_soc_component_get_drvdata(comp); int rc = 0, i; + struct msm_pcm_channel_mixer *chmixer_pspd = NULL; pr_debug("%s: fe_id- %llu\n", __func__, fe_id); @@ -3726,6 +3728,17 @@ static int msm_compr_channel_map_put(struct snd_kcontrol *kcontrol, for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) pdata->ch_map[fe_id]->channel_map[i] = (char)(ucontrol->value.integer.value[i]); + + /* update chmixer_pspd chmap cached with routing driver as well */ + chmixer_pspd = pdata->chmixer_pspd[fe_id]; + if (chmixer_pspd && chmixer_pspd->enable) { + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->in_ch_map[i] = + pdata->ch_map[fe_id]->channel_map[i]; + chmixer_pspd->override_in_ch_map = true; + msm_pcm_routing_set_channel_mixer_cfg(fe_id, + SESSION_TYPE_RX, chmixer_pspd); + } } else { pr_debug("%s: no memory for ch_map, default will be set\n", __func__); @@ -3971,10 +3984,11 @@ static int msm_compr_probe(struct snd_soc_component *component) const char *qdsp_version; pr_debug("%s\n", __func__); - pdata = (struct msm_compr_pdata *) - kzalloc(sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return -ENOMEM; + pdata = (struct msm_compr_pdata *) dev_get_drvdata(component->dev); + if (!pdata) { + pr_err("%s platform data not set\n", __func__); + return -EINVAL; + } snd_soc_component_set_drvdata(component, pdata); @@ -4640,6 +4654,580 @@ static int msm_compr_add_event_ack_cmd_control(struct snd_soc_pcm_runtime *rtd) return ret; } +static struct msm_pcm_channel_mixer *msm_compr_get_chmixer( + struct msm_compr_pdata *pdata, u64 fe_id) +{ + if (!pdata) { + pr_err("%s: missing pdata\n", __func__); + return NULL; + } + + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %llu\n", __func__, fe_id); + return NULL; + } + + return pdata->chmixer_pspd[fe_id]; +} + +static int msm_compr_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + int ret = 0, i = 0, stream_id = 0, be_id = 0; + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + struct snd_compr_stream *cstream = NULL; + struct msm_compr_audio *prtd = NULL; + struct msm_pcm_channel_mixer *chmixer_pspd = NULL; + u8 asm_ch_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8] = {0}; + bool reset_override_out_ch_map = false; + bool reset_override_in_ch_map = false; + + if ((session_type != SESSION_TYPE_TX) && + (session_type != SESSION_TYPE_RX)) { + pr_err("%s: invalid session type %d\n", __func__, session_type); + return -EINVAL; + } + + chmixer_pspd = msm_compr_get_chmixer(pdata, fe_id); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + chmixer_pspd->enable = ucontrol->value.integer.value[0]; + chmixer_pspd->rule = ucontrol->value.integer.value[1]; + chmixer_pspd->input_channel = ucontrol->value.integer.value[2]; + chmixer_pspd->output_channel = ucontrol->value.integer.value[3]; + chmixer_pspd->port_idx = ucontrol->value.integer.value[4]; + + if (chmixer_pspd->enable) { + if (session_type == SESSION_TYPE_RX && + !chmixer_pspd->override_in_ch_map) { + if (pdata->ch_map[fe_id]->set_ch_map) { + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->in_ch_map[i] = + pdata->ch_map[fe_id]->channel_map[i]; + } else { + q6asm_map_channels(asm_ch_map, + chmixer_pspd->input_channel, false); + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->in_ch_map[i] = asm_ch_map[i]; + } + chmixer_pspd->override_in_ch_map = true; + reset_override_in_ch_map = true; + } else if (session_type == SESSION_TYPE_TX && + !chmixer_pspd->override_out_ch_map) { + if (pdata->ch_map[fe_id]->set_ch_map) { + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->out_ch_map[i] = + pdata->ch_map[fe_id]->channel_map[i]; + } else { + q6asm_map_channels(asm_ch_map, + chmixer_pspd->output_channel, false); + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->out_ch_map[i] = asm_ch_map[i]; + } + chmixer_pspd->override_out_ch_map = true; + reset_override_out_ch_map = true; + } + } else { + chmixer_pspd->override_out_ch_map = false; + chmixer_pspd->override_in_ch_map = false; + } + + /* cache value and take effect during adm_open stage */ + msm_pcm_routing_set_channel_mixer_cfg(fe_id, + session_type, + chmixer_pspd); + + cstream = pdata->cstream[fe_id]; + if (chmixer_pspd->enable && cstream && cstream->runtime) { + prtd = cstream->runtime->private_data; + if (!prtd) { + pr_err("%s invalid prtd\n", __func__); + ret = -EINVAL; + goto done; + } + + if (prtd->audio_client) { + stream_id = prtd->audio_client->session; + be_id = chmixer_pspd->port_idx; + ret = msm_pcm_routing_set_channel_mixer_runtime(be_id, + stream_id, session_type, chmixer_pspd); + } + } + + if (reset_override_out_ch_map) + chmixer_pspd->override_out_ch_map = false; + if (reset_override_in_ch_map) + chmixer_pspd->override_in_ch_map = false; + +done: + return ret; +} + +static int msm_compr_channel_mixer_cfg_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_compr_get_chmixer(pdata, fe_id); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + ucontrol->value.integer.value[0] = chmixer_pspd->enable; + ucontrol->value.integer.value[1] = chmixer_pspd->rule; + ucontrol->value.integer.value[2] = chmixer_pspd->input_channel; + ucontrol->value.integer.value[3] = chmixer_pspd->output_channel; + ucontrol->value.integer.value[4] = chmixer_pspd->port_idx; + return 0; +} + +static int msm_compr_channel_mixer_output_map_ctl_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int i = 0; + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_compr_get_chmixer(pdata, fe_id); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + chmixer_pspd->override_out_ch_map = true; + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->out_ch_map[i] = + ucontrol->value.integer.value[i]; + + return 0; +} + +static int msm_compr_channel_mixer_output_map_ctl_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int i = 0; + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_compr_get_chmixer(pdata, fe_id); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + ucontrol->value.integer.value[i] = + chmixer_pspd->out_ch_map[i]; + return 0; +} + +static int msm_compr_channel_mixer_input_map_ctl_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int i = 0; + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_compr_get_chmixer(pdata, fe_id); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + chmixer_pspd->override_in_ch_map = true; + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->in_ch_map[i] = ucontrol->value.integer.value[i]; + + return 0; +} + +static int msm_compr_channel_mixer_input_map_ctl_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int i = 0; + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_compr_get_chmixer(pdata, fe_id); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + ucontrol->value.integer.value[i] = + chmixer_pspd->in_ch_map[i]; + return 0; +} + +static int msm_compr_channel_mixer_weight_ctl_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int channel = (kcontrol->private_value >> 16) & 0xFF; + int i = 0; + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_compr_get_chmixer(pdata, fe_id); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + if (channel <= 0 || channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: invalid channel number %d\n", __func__, channel); + return -EINVAL; + } + channel--; + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->channel_weight[channel][i] = + ucontrol->value.integer.value[i]; + return 0; +} + +static int msm_compr_channel_mixer_weight_ctl_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int channel = (kcontrol->private_value >> 16) & 0xFF; + struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(comp); + int i = 0; + struct msm_pcm_channel_mixer *chmixer_pspd; + + if (channel <= 0 || channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: invalid channel number %d\n", __func__, channel); + return -EINVAL; + } + channel--; + + chmixer_pspd = msm_compr_get_chmixer(pdata, fe_id); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + ucontrol->value.integer.value[i] = + chmixer_pspd->channel_weight[channel][i]; + return 0; +} + +static int msm_compr_add_platform_controls(struct snd_kcontrol_new *kctl, + struct snd_soc_pcm_runtime *rtd, const char *name_prefix, + const char *name_suffix, int session_type, int channels) +{ + int ret = -EINVAL; + char *mixer_name = NULL; + const char *deviceNo = "NN"; + const char *channelNo = "NN"; + int ctl_len = 0; + struct snd_soc_component *component = NULL; + + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + ctl_len = strlen(name_prefix) + 1 + strlen(deviceNo) + 1 + + strlen(channelNo) + 1 + strlen(name_suffix) + 1; + + mixer_name = kzalloc(ctl_len, GFP_KERNEL); + if (mixer_name == NULL) + return -ENOMEM; + + if (channels >= 0) { + snprintf(mixer_name, ctl_len, "%s %d %s %d", + name_prefix, rtd->pcm->device, name_suffix, channels); + kctl->private_value = (rtd->dai_link->id) | (channels << 16); + } else { + snprintf(mixer_name, ctl_len, "%s %d %s", + name_prefix, rtd->pcm->device, name_suffix); + kctl->private_value = (rtd->dai_link->id); + } + if (session_type != INVALID_SESSION) + kctl->private_value |= (session_type << 8); + + kctl->name = mixer_name; + ret = snd_soc_add_component_controls(component, kctl, 1); + kfree(mixer_name); + return ret; +} + +static int msm_compr_channel_mixer_output_map_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8; + /* Valid channel map value ranges from 1 to 64 */ + uinfo->value.integer.min = 1; + uinfo->value.integer.max = 64; + return 0; +} + +static int msm_compr_add_channel_mixer_output_map_controls( + struct snd_soc_pcm_runtime *rtd) +{ + const char *playback_mixer_ctl_name = "AudStr"; + const char *capture_mixer_ctl_name = "AudStr Capture"; + const char *suffix = "ChMixer Output Map"; + const char *mixer_ctl_name = NULL; + int ret = 0, session_type = INVALID_SESSION, channel = -1; + struct snd_kcontrol_new channel_mixer_output_map_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_compr_channel_mixer_output_map_info, + .put = msm_compr_channel_mixer_output_map_ctl_put, + .get = msm_compr_channel_mixer_output_map_ctl_get, + .private_value = 0, + }; + + mixer_ctl_name = rtd->compr->direction == SND_COMPRESS_PLAYBACK ? + playback_mixer_ctl_name : capture_mixer_ctl_name ; + ret = msm_compr_add_platform_controls(&channel_mixer_output_map_control, + rtd, mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) { + pr_err("%s: failed add platform ctl, err = %d\n", + __func__, ret); + } + + return ret; +} + +static int msm_compr_channel_mixer_input_map_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8; + /* Valid channel map value ranges from 1 to 64 */ + uinfo->value.integer.min = 1; + uinfo->value.integer.max = 64; + return 0; +} + +static int msm_compr_add_channel_mixer_input_map_controls( + struct snd_soc_pcm_runtime *rtd) +{ + const char *playback_mixer_ctl_name = "AudStr"; + const char *capture_mixer_ctl_name = "AudStr Capture"; + const char *suffix = "ChMixer Input Map"; + const char *mixer_ctl_name = NULL; + int ret = 0, session_type = INVALID_SESSION, channel = -1; + struct snd_kcontrol_new channel_mixer_input_map_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_compr_channel_mixer_input_map_info, + .put = msm_compr_channel_mixer_input_map_ctl_put, + .get = msm_compr_channel_mixer_input_map_ctl_get, + .private_value = 0, + }; + + mixer_ctl_name = rtd->compr->direction == SND_COMPRESS_PLAYBACK ? + playback_mixer_ctl_name : capture_mixer_ctl_name ; + ret = msm_compr_add_platform_controls(&channel_mixer_input_map_control, + rtd, mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) { + pr_err("%s: failed add platform ctl, err = %d\n", + __func__, ret); + } + + return ret; +} + +static int msm_compr_channel_mixer_cfg_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + /* five int values: enable, rule, in_channels, out_channels and port_id */ + uinfo->count = 5; + /* Valid range is all positive values to support above controls */ + uinfo->value.integer.min = 0; + uinfo->value.integer.max = INT_MAX; + return 0; +} + +static int msm_compr_add_channel_mixer_cfg_controls( + struct snd_soc_pcm_runtime *rtd) +{ + const char *playback_mixer_ctl_name = "AudStr"; + const char *capture_mixer_ctl_name = "AudStr Capture"; + const char *suffix = "ChMixer Cfg"; + const char *mixer_ctl_name = NULL; + int ret = 0, session_type = INVALID_SESSION, channel = -1; + struct snd_kcontrol_new channel_mixer_cfg_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_compr_channel_mixer_cfg_info, + .put = msm_compr_channel_mixer_cfg_ctl_put, + .get = msm_compr_channel_mixer_cfg_ctl_get, + .private_value = 0, + }; + + if (rtd->compr->direction == SND_COMPRESS_PLAYBACK) { + session_type = SESSION_TYPE_RX; + mixer_ctl_name = playback_mixer_ctl_name; + } else { + session_type = SESSION_TYPE_TX; + mixer_ctl_name = capture_mixer_ctl_name; + } + + ret = msm_compr_add_platform_controls(&channel_mixer_cfg_control, + rtd, mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) { + pr_err("%s: failed add platform ctl, err = %d\n", + __func__, ret); + } + + return ret; +} + +static int msm_compr_channel_mixer_weight_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8; + /* Valid range: 0 to 0x4000(Unity) gain weightage */ + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0x4000; + return 0; +} + +static int msm_compr_add_channel_mixer_weight_controls( + struct snd_soc_pcm_runtime *rtd, + int channel) +{ + const char *playback_mixer_ctl_name = "AudStr"; + const char *capture_mixer_ctl_name = "AudStr Capture"; + const char *suffix = "ChMixer Weight Ch"; + const char *mixer_ctl_name = NULL; + int ret = 0, session_type = INVALID_SESSION; + struct snd_kcontrol_new channel_mixer_weight_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_compr_channel_mixer_weight_info, + .put = msm_compr_channel_mixer_weight_ctl_put, + .get = msm_compr_channel_mixer_weight_ctl_get, + .private_value = 0, + }; + + mixer_ctl_name = rtd->compr->direction == SND_COMPRESS_PLAYBACK ? + playback_mixer_ctl_name : capture_mixer_ctl_name ; + ret = msm_compr_add_platform_controls(&channel_mixer_weight_control, + rtd, mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) { + pr_err("%s: failed add platform ctl, err = %d\n", + __func__, ret); + } + + return ret; +} + +static int msm_compr_add_channel_mixer_controls(struct snd_soc_pcm_runtime *rtd) +{ + int i, ret = 0; + struct msm_compr_pdata *pdata = NULL; + struct snd_soc_component *component = NULL; + + if (!rtd) { + pr_err("%s NULL rtd\n", __func__); + return -EINVAL; + } + + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + pdata = (struct msm_compr_pdata *) + snd_soc_component_get_drvdata(component); + if (!pdata) { + pr_err("%s: platform data not populated\n", __func__); + return -EINVAL; + } + + if (!pdata->chmixer_pspd[rtd->dai_link->id]) { + pdata->chmixer_pspd[rtd->dai_link->id] = + kzalloc(sizeof(struct msm_pcm_channel_mixer), GFP_KERNEL); + if (!pdata->chmixer_pspd[rtd->dai_link->id]) + return -ENOMEM; + } + + ret = msm_compr_add_channel_mixer_cfg_controls(rtd); + if (ret) { + pr_err("%s: pcm add channel mixer cfg controls failed:%d\n", + __func__, ret); + goto fail; + } + ret = msm_compr_add_channel_mixer_input_map_controls(rtd); + if (ret) { + pr_err("%s: pcm add channel mixer input map controls failed:%d\n", + __func__, ret); + goto fail; + } + ret = msm_compr_add_channel_mixer_output_map_controls(rtd); + if (ret) { + pr_err("%s: pcm add channel mixer output map controls failed:%d\n", + __func__, ret); + goto fail; + } + + for (i = 1; i <= PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) { + ret = msm_compr_add_channel_mixer_weight_controls(rtd, i); + if (ret) { + pr_err("%s: pcm add channel mixer weight controls failed:%d\n", + __func__, ret); + goto fail; + } + } + return 0; + +fail: + kfree(pdata->chmixer_pspd[rtd->dai_link->id]); + pdata->chmixer_pspd[rtd->dai_link->id] = NULL; + return ret; +} + static int msm_compr_new(struct snd_soc_pcm_runtime *rtd) { int rc; @@ -4690,6 +5278,10 @@ static int msm_compr_new(struct snd_soc_pcm_runtime *rtd) if (rc) pr_err("%s: Could not add Compr Channel Map Control\n", __func__); + rc = msm_compr_add_channel_mixer_controls(rtd); + if (rc) + pr_err("%s: Could not add Compr Channel Mixer Controls\n", + __func__); return 0; } @@ -4717,14 +5309,31 @@ static struct snd_soc_component_driver msm_soc_component = { static int msm_compr_dev_probe(struct platform_device *pdev) { + struct msm_compr_pdata *pdata = NULL; pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev)); + pdata = (struct msm_compr_pdata *) + kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + dev_set_drvdata(&pdev->dev, pdata); + return snd_soc_register_component(&pdev->dev, &msm_soc_component, NULL, 0); } static int msm_compr_remove(struct platform_device *pdev) { + int i = 0; + struct msm_compr_pdata *pdata = NULL; + + pdata = dev_get_drvdata(&pdev->dev); + if (pdata) { + for (i = 0; i < MSM_FRONTEND_DAI_MM_SIZE; i++) + kfree(pdata->chmixer_pspd[i]); + } + kfree(pdata); + snd_soc_unregister_component(&pdev->dev); return 0; } diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index b516634fd1b3..a68698438e40 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. */ #include @@ -64,6 +64,8 @@ static u32 hfp_tx_mute; struct msm_pcm_pdata { int perf_mode; + struct snd_pcm *pcm_device[MSM_FRONTEND_DAI_MM_SIZE]; + struct msm_pcm_channel_mixer *chmixer_pspd[MSM_FRONTEND_DAI_MM_SIZE][2]; }; static void stop_pcm(struct msm_pcm_loopback *pcm); @@ -734,6 +736,671 @@ static int msm_pcm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd) return 0; } +static struct msm_pcm_channel_mixer *msm_pcm_get_chmixer( + struct msm_pcm_pdata *pdata, + u64 fe_id, int session_type) +{ + if (!pdata) { + pr_err("%s: missing pdata\n", __func__); + return NULL; + } + + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %llu\n", __func__, fe_id); + return NULL; + } + + if ((session_type != SESSION_TYPE_TX) && + (session_type != SESSION_TYPE_RX)) { + pr_err("%s: invalid session type %d\n", __func__, session_type); + return NULL; + } + + return pdata->chmixer_pspd[fe_id][session_type]; +} + +static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + int ret = 0; + int stream_id = 0; + int be_id = 0, i = 0; + struct msm_pcm_loopback *prtd = NULL; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct msm_pcm_pdata *pdata = dev_get_drvdata(component->dev); + struct snd_pcm *pcm = NULL; + struct snd_pcm_substream *substream = NULL; + struct msm_pcm_channel_mixer *chmixer_pspd = NULL; + u8 asm_ch_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8] = {0}; + bool reset_override_out_ch_map = false; + bool reset_override_in_ch_map = false; + + pcm = pdata->pcm_device[fe_id]; + if (!pcm) { + pr_err("%s invalid pcm handle for fe_id %llu\n", + __func__, fe_id); + return -EINVAL; + } + + if (session_type == SESSION_TYPE_RX) + substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + else + substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; + if (!substream) { + pr_err("%s substream not found\n", __func__); + return -EINVAL; + } + + chmixer_pspd = msm_pcm_get_chmixer(pdata, fe_id, session_type); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + chmixer_pspd->enable = ucontrol->value.integer.value[0]; + chmixer_pspd->rule = ucontrol->value.integer.value[1]; + chmixer_pspd->input_channel = ucontrol->value.integer.value[2]; + chmixer_pspd->output_channel = ucontrol->value.integer.value[3]; + chmixer_pspd->port_idx = ucontrol->value.integer.value[4]; + + if (chmixer_pspd->enable) { + if (session_type == SESSION_TYPE_RX && + !chmixer_pspd->override_in_ch_map) { + q6asm_map_channels(asm_ch_map, + chmixer_pspd->input_channel, false); + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->in_ch_map[i] = asm_ch_map[i]; + chmixer_pspd->override_in_ch_map = true; + reset_override_in_ch_map = true; + } else if (session_type == SESSION_TYPE_TX && + !chmixer_pspd->override_out_ch_map) { + q6asm_map_channels(asm_ch_map, + chmixer_pspd->output_channel, false); + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->out_ch_map[i] = asm_ch_map[i]; + chmixer_pspd->override_out_ch_map = true; + reset_override_out_ch_map = true; + } + } else { + chmixer_pspd->override_out_ch_map = false; + chmixer_pspd->override_in_ch_map = false; + } + + /* cache value and take effect during adm_open stage */ + msm_pcm_routing_set_channel_mixer_cfg(fe_id, + session_type, + chmixer_pspd); + + if (chmixer_pspd->enable && substream->runtime) { + prtd = substream->runtime->private_data; + if (!prtd) { + pr_err("%s find invalid prtd fail\n", __func__); + ret = -EINVAL; + goto done; + } + + if (prtd->audio_client) { + stream_id = prtd->audio_client->session; + be_id = chmixer_pspd->port_idx; + msm_pcm_routing_set_channel_mixer_runtime(be_id, + stream_id, + session_type, + chmixer_pspd); + } + } + + if (reset_override_out_ch_map) + chmixer_pspd->override_out_ch_map = false; + if (reset_override_in_ch_map) + chmixer_pspd->override_in_ch_map = false; + +done: + return ret; +} + +static int msm_pcm_channel_mixer_cfg_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct msm_pcm_pdata *pdata = dev_get_drvdata(component->dev); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_pcm_get_chmixer(pdata, fe_id, session_type); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + ucontrol->value.integer.value[0] = chmixer_pspd->enable; + ucontrol->value.integer.value[1] = chmixer_pspd->rule; + ucontrol->value.integer.value[2] = chmixer_pspd->input_channel; + ucontrol->value.integer.value[3] = chmixer_pspd->output_channel; + ucontrol->value.integer.value[4] = chmixer_pspd->port_idx; + return 0; +} + +static int msm_pcm_channel_mixer_output_map_ctl_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + int i = 0; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct msm_pcm_pdata *pdata = dev_get_drvdata(component->dev); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_pcm_get_chmixer(pdata, fe_id, session_type); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + chmixer_pspd->override_out_ch_map = true; + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->out_ch_map[i] = + ucontrol->value.integer.value[i]; + + return 0; +} + +static int msm_pcm_channel_mixer_output_map_ctl_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + int i = 0; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct msm_pcm_pdata *pdata = dev_get_drvdata(component->dev); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_pcm_get_chmixer(pdata, fe_id, session_type); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + ucontrol->value.integer.value[i] = + chmixer_pspd->out_ch_map[i]; + return 0; +} + +static int msm_pcm_channel_mixer_input_map_ctl_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + int i = 0; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct msm_pcm_pdata *pdata = dev_get_drvdata(component->dev); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_pcm_get_chmixer(pdata, fe_id, session_type); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + chmixer_pspd->override_in_ch_map = true; + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->in_ch_map[i] = ucontrol->value.integer.value[i]; + + return 0; +} + +static int msm_pcm_channel_mixer_input_map_ctl_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + int i = 0; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct msm_pcm_pdata *pdata = dev_get_drvdata(component->dev); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_pcm_get_chmixer(pdata, fe_id, session_type); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + ucontrol->value.integer.value[i] = + chmixer_pspd->in_ch_map[i]; + return 0; +} + +static int msm_pcm_channel_mixer_weight_ctl_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + int channel = (kcontrol->private_value >> 16) & 0xFF; + int i = 0; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct msm_pcm_pdata *pdata = dev_get_drvdata(component->dev); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_pcm_get_chmixer(pdata, fe_id, session_type); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + if (channel <= 0 || channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: invalid channel number %d\n", __func__, channel); + return -EINVAL; + } + channel--; + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->channel_weight[channel][i] = + ucontrol->value.integer.value[i]; + return 0; +} + +static int msm_pcm_channel_mixer_weight_ctl_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + int channel = (kcontrol->private_value >> 16) & 0xFF; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct msm_pcm_pdata *pdata = dev_get_drvdata(component->dev); + int i = 0; + struct msm_pcm_channel_mixer *chmixer_pspd; + + if (channel <= 0 || channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: invalid channel number %d\n", __func__, channel); + return -EINVAL; + } + channel--; + + chmixer_pspd = msm_pcm_get_chmixer(pdata, fe_id, session_type); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + ucontrol->value.integer.value[i] = + chmixer_pspd->channel_weight[channel][i]; + return 0; +} + +static int msm_pcm_add_platform_controls(struct snd_kcontrol_new *kctl, + struct snd_soc_pcm_runtime *rtd, const char *name_prefix, + const char *name_suffix, int session_type, int channels) +{ + int ret = -EINVAL; + char *mixer_name = NULL; + struct snd_pcm *pcm = rtd->pcm; + const char *deviceNo = "NN"; + const char *channelNo = "NN"; + int ctl_len = 0; + struct snd_soc_component *component = NULL; + + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + ctl_len = strlen(name_prefix) + 1 + strlen(deviceNo) + 1 + + strlen(channelNo) + 1 + strlen(name_suffix) + 1; + + mixer_name = kzalloc(ctl_len, GFP_KERNEL); + if (mixer_name == NULL) + return -ENOMEM; + + if (channels >= 0) { + snprintf(mixer_name, ctl_len, "%s %d %s %d", + name_prefix, pcm->device, name_suffix, channels); + kctl->private_value = (rtd->dai_link->id) | (session_type << 8) | + (channels << 16); + } else { + snprintf(mixer_name, ctl_len, "%s %d %s", + name_prefix, pcm->device, name_suffix); + kctl->private_value = (rtd->dai_link->id) | (session_type << 8); + } + + kctl->name = mixer_name; + ret = snd_soc_add_component_controls(component, kctl, 1); + kfree(mixer_name); + return ret; +} + +static int msm_pcm_channel_mixer_output_map_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8; + /* Valid channel map value ranges from 1 to 64 */ + uinfo->value.integer.min = 1; + uinfo->value.integer.max = 64; + return 0; +} + +static int msm_pcm_add_channel_mixer_output_map_controls( + struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm *pcm = rtd->pcm; + const char *playback_mixer_ctl_name = "AudStr"; + const char *capture_mixer_ctl_name = "AudStr Capture"; + const char *suffix = "ChMixer Output Map"; + int session_type = 0, ret = 0, channel = -1; + struct snd_kcontrol_new channel_mixer_output_map_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_pcm_channel_mixer_output_map_info, + .put = msm_pcm_channel_mixer_output_map_ctl_put, + .get = msm_pcm_channel_mixer_output_map_ctl_get, + .private_value = 0, + }; + + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream != NULL) { + session_type = SESSION_TYPE_RX; + ret = msm_pcm_add_platform_controls(&channel_mixer_output_map_control, + rtd, playback_mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) + goto fail; + } + + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream != NULL) { + session_type = SESSION_TYPE_TX; + ret = msm_pcm_add_platform_controls(&channel_mixer_output_map_control, + rtd, capture_mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) + goto fail; + } + return 0; + +fail: + pr_err("%s: failed add platform ctl, err = %d\n", + __func__, ret); + + return ret; +} + +static int msm_pcm_channel_mixer_input_map_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8; + /* Valid channel map value ranges from 1 to 64 */ + uinfo->value.integer.min = 1; + uinfo->value.integer.max = 64; + return 0; +} + +static int msm_pcm_add_channel_mixer_input_map_controls( + struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm *pcm = rtd->pcm; + const char *playback_mixer_ctl_name = "AudStr"; + const char *capture_mixer_ctl_name = "AudStr Capture"; + const char *suffix = "ChMixer Input Map"; + int session_type = 0, ret = 0, channel = -1; + struct snd_kcontrol_new channel_mixer_input_map_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_pcm_channel_mixer_input_map_info, + .put = msm_pcm_channel_mixer_input_map_ctl_put, + .get = msm_pcm_channel_mixer_input_map_ctl_get, + .private_value = 0, + }; + + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream != NULL) { + session_type = SESSION_TYPE_RX; + ret = msm_pcm_add_platform_controls(&channel_mixer_input_map_control, + rtd, playback_mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) + goto fail; + } + + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream != NULL) { + session_type = SESSION_TYPE_TX; + ret = msm_pcm_add_platform_controls(&channel_mixer_input_map_control, + rtd, capture_mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) + goto fail; + } + return 0; + +fail: + pr_err("%s: failed add platform ctl, err = %d\n", + __func__, ret); + return ret; +} + +static int msm_pcm_channel_mixer_cfg_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + /* five int values: enable, rule, in_channels, out_channels and port_id */ + uinfo->count = 5; + /* Valid range is all positive values to support above controls */ + uinfo->value.integer.min = 0; + uinfo->value.integer.max = INT_MAX; + return 0; +} + +static int msm_pcm_add_channel_mixer_cfg_controls( + struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm *pcm = rtd->pcm; + const char *playback_mixer_ctl_name = "AudStr"; + const char *capture_mixer_ctl_name = "AudStr Capture"; + const char *suffix = "ChMixer Cfg"; + int session_type = 0, ret = 0, channel = -1; + struct msm_pcm_pdata *pdata = NULL; + struct snd_soc_component *component = NULL; + struct snd_kcontrol_new channel_mixer_cfg_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_pcm_channel_mixer_cfg_info, + .put = msm_pcm_channel_mixer_cfg_ctl_put, + .get = msm_pcm_channel_mixer_cfg_ctl_get, + .private_value = 0, + }; + + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + pdata = (struct msm_pcm_pdata *) + dev_get_drvdata(component->dev); + if (pdata == NULL) { + pr_err("%s: platform data not populated\n", __func__); + return -EINVAL; + } + + pdata->pcm_device[rtd->dai_link->id] = rtd->pcm; + + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream != NULL) { + session_type = SESSION_TYPE_RX; + ret = msm_pcm_add_platform_controls(&channel_mixer_cfg_control, + rtd, playback_mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) + goto fail; + } + + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream != NULL) { + session_type = SESSION_TYPE_TX; + ret = msm_pcm_add_platform_controls(&channel_mixer_cfg_control, + rtd, capture_mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) + goto fail; + } + return 0; + +fail: + pr_err("%s: failed add platform ctl, err = %d\n", + __func__, ret); + + return ret; +} + +static int msm_pcm_channel_mixer_weight_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8; + /* Valid range: 0 to 0x4000(Unity) gain weightage */ + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0x4000; + return 0; +} + +static int msm_pcm_add_channel_mixer_weight_controls( + struct snd_soc_pcm_runtime *rtd, + int channel) +{ + struct snd_pcm *pcm = rtd->pcm; + const char *playback_mixer_ctl_name = "AudStr"; + const char *capture_mixer_ctl_name = "AudStr Capture"; + const char *suffix = "ChMixer Weight Ch"; + int session_type = 0, ret = 0; + struct snd_kcontrol_new channel_mixer_weight_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_pcm_channel_mixer_weight_info, + .put = msm_pcm_channel_mixer_weight_ctl_put, + .get = msm_pcm_channel_mixer_weight_ctl_get, + .private_value = 0, + }; + + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream != NULL) { + session_type = SESSION_TYPE_RX; + ret = msm_pcm_add_platform_controls(&channel_mixer_weight_control, + rtd, playback_mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) + goto fail; + } + + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream != NULL) { + session_type = SESSION_TYPE_TX; + ret = msm_pcm_add_platform_controls(&channel_mixer_weight_control, + rtd, capture_mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) + goto fail; + } + return 0; + +fail: + pr_err("%s: failed add platform ctl, err = %d\n", + __func__, ret); + + return ret; +} + +static int msm_pcm_add_channel_mixer_controls(struct snd_soc_pcm_runtime *rtd) +{ + int i, ret = 0; + struct snd_pcm *pcm = NULL; + struct msm_pcm_pdata *pdata = NULL; + struct snd_soc_component *component = NULL; + + if (!rtd || !rtd->pcm) { + pr_err("%s invalid rtd or pcm\n", __func__); + return -EINVAL; + } + pcm = rtd->pcm; + + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + pdata = (struct msm_pcm_pdata *) + dev_get_drvdata(component->dev); + if (!pdata) { + pr_err("%s: platform data not populated\n", __func__); + return -EINVAL; + } + + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream && + !pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_RX]) { + pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_RX] = + kzalloc(sizeof(struct msm_pcm_channel_mixer), GFP_KERNEL); + if (!pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_RX]) { + ret = -ENOMEM; + goto fail; + } + } + + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream && + !pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_TX]) { + pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_TX] = + kzalloc(sizeof(struct msm_pcm_channel_mixer), GFP_KERNEL); + if (!pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_TX]) { + ret = -ENOMEM; + goto fail; + } + } + + ret = msm_pcm_add_channel_mixer_cfg_controls(rtd); + if (ret) { + pr_err("%s: pcm add channel mixer cfg controls failed:%d\n", + __func__, ret); + goto fail; + } + ret = msm_pcm_add_channel_mixer_input_map_controls(rtd); + if (ret) { + pr_err("%s: pcm add channel mixer input map controls failed:%d\n", + __func__, ret); + goto fail; + } + ret = msm_pcm_add_channel_mixer_output_map_controls(rtd); + if (ret) { + pr_err("%s: pcm add channel mixer output map controls failed:%d\n", + __func__, ret); + goto fail; + } + + for (i = 1; i <= PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) { + ret = msm_pcm_add_channel_mixer_weight_controls(rtd, i); + if (ret) { + pr_err("%s: pcm add channel mixer weight controls failed:%d\n", + __func__, ret); + goto fail; + } + } + return 0; + +fail: + kfree(pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_RX]); + kfree(pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_TX]); + pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_RX] = NULL; + pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_TX] = NULL; + + return ret; +} + static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd) { int ret = 0; @@ -747,6 +1414,11 @@ static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd) if (ret) pr_err("%s: pcm add app type controls failed:%d\n", __func__, ret); + + ret = msm_pcm_add_channel_mixer_controls(rtd); + if (ret) + pr_err("%s: pcm add channel mixer controls failed:%d\n", + __func__, ret); return ret; } @@ -797,6 +1469,17 @@ static int msm_pcm_probe(struct platform_device *pdev) static int msm_pcm_remove(struct platform_device *pdev) { + struct msm_pcm_pdata *pdata; + int i = 0; + + pdata = dev_get_drvdata(&pdev->dev); + if (pdata) { + for (i = 0; i < MSM_FRONTEND_DAI_MM_SIZE; i++) { + kfree(pdata->chmixer_pspd[i][SESSION_TYPE_RX]); + kfree(pdata->chmixer_pspd[i][SESSION_TYPE_TX]); + } + } + kfree(pdata); snd_soc_unregister_component(&pdev->dev); return 0; } diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 5886736286c5..bea58c9e07f1 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1601,6 +1601,11 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol, unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); struct snd_pcm_substream *substream; struct msm_audio *prtd; + struct snd_soc_pcm_runtime *rtd = NULL; + struct msm_plat_data *pdata = NULL; + struct msm_pcm_channel_mixer *chmixer_pspd = NULL; + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + u64 fe_id = 0; pr_debug("%s", __func__); substream = snd_pcm_chmap_substream(info, idx); @@ -1615,6 +1620,24 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol, for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) prtd->channel_map[i] = (char)(ucontrol->value.integer.value[i]); + + /* update chmixer_pspd chmap cached with routing driver as well */ + rtd = substream->private_data; + if (rtd) { + fe_id = rtd->dai_link->id; + pdata = (struct msm_plat_data *) + dev_get_drvdata(component->dev); + chmixer_pspd = pdata ? + pdata->chmixer_pspd[fe_id][SESSION_TYPE_RX] : NULL; + + if (chmixer_pspd && chmixer_pspd->enable) { + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->in_ch_map[i] = prtd->channel_map[i]; + chmixer_pspd->override_in_ch_map = true; + msm_pcm_routing_set_channel_mixer_cfg(fe_id, + SESSION_TYPE_RX, chmixer_pspd); + } + } } return 0; } @@ -1838,6 +1861,674 @@ static int msm_pcm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd) return 0; } +static struct msm_pcm_channel_mixer *msm_pcm_get_chmixer( + struct msm_plat_data *pdata, + u64 fe_id, int session_type) +{ + if (!pdata) { + pr_err("%s: missing pdata\n", __func__); + return NULL; + } + + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %llu\n", __func__, fe_id); + return NULL; + } + + if ((session_type != SESSION_TYPE_TX) && + (session_type != SESSION_TYPE_RX)) { + pr_err("%s: invalid session type %d\n", __func__, session_type); + return NULL; + } + + return pdata->chmixer_pspd[fe_id][session_type]; +} + +static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + int ret = 0; + int stream_id = 0; + int be_id = 0, i = 0; + struct msm_audio *prtd = NULL; + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct msm_plat_data *pdata = dev_get_drvdata(component->dev); + struct snd_pcm *pcm = NULL; + struct snd_pcm_substream *substream = NULL; + struct msm_pcm_channel_mixer *chmixer_pspd = NULL; + u8 asm_ch_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8] = {0}; + bool reset_override_out_ch_map = false; + bool reset_override_in_ch_map = false; + + pcm = pdata->pcm_device[fe_id]; + if (!pcm) { + pr_err("%s invalid pcm handle for fe_id %llu\n", + __func__, fe_id); + return -EINVAL; + } + + if (session_type == SESSION_TYPE_RX) + substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + else + substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; + if (!substream) { + pr_err("%s substream not found\n", __func__); + return -EINVAL; + } + + chmixer_pspd = msm_pcm_get_chmixer(pdata, fe_id, session_type); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + chmixer_pspd->enable = ucontrol->value.integer.value[0]; + chmixer_pspd->rule = ucontrol->value.integer.value[1]; + chmixer_pspd->input_channel = ucontrol->value.integer.value[2]; + chmixer_pspd->output_channel = ucontrol->value.integer.value[3]; + chmixer_pspd->port_idx = ucontrol->value.integer.value[4]; + + if (chmixer_pspd->enable) { + if (session_type == SESSION_TYPE_RX && + !chmixer_pspd->override_in_ch_map) { + if (pdata->ch_map[fe_id] && + pdata->ch_map[fe_id]->set_ch_map) { + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->in_ch_map[i] = + pdata->ch_map[fe_id]->channel_map[i]; + } else { + q6asm_map_channels(asm_ch_map, + chmixer_pspd->input_channel, false); + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->in_ch_map[i] = asm_ch_map[i]; + } + chmixer_pspd->override_in_ch_map = true; + reset_override_in_ch_map = true; + } else if (session_type == SESSION_TYPE_TX && + !chmixer_pspd->override_out_ch_map) { + if (pdata->ch_map[fe_id] && + pdata->ch_map[fe_id]->set_ch_map) { + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->out_ch_map[i] = + pdata->ch_map[fe_id]->channel_map[i]; + } else { + q6asm_map_channels(asm_ch_map, + chmixer_pspd->output_channel, false); + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->out_ch_map[i] = asm_ch_map[i]; + } + chmixer_pspd->override_out_ch_map = true; + reset_override_out_ch_map = true; + } + } else { + chmixer_pspd->override_out_ch_map = false; + chmixer_pspd->override_in_ch_map = false; + } + + /* cache value and take effect during adm_open stage */ + msm_pcm_routing_set_channel_mixer_cfg(fe_id, + session_type, + chmixer_pspd); + + if (chmixer_pspd->enable && substream->runtime) { + prtd = substream->runtime->private_data; + if (!prtd) { + pr_err("%s find invalid prtd fail\n", __func__); + ret = -EINVAL; + goto done; + } + + if (prtd->audio_client) { + stream_id = prtd->audio_client->session; + be_id = chmixer_pspd->port_idx; + msm_pcm_routing_set_channel_mixer_runtime(be_id, + stream_id, + session_type, + chmixer_pspd); + } + } + + if (reset_override_out_ch_map) + chmixer_pspd->override_out_ch_map = false; + if (reset_override_in_ch_map) + chmixer_pspd->override_in_ch_map = false; + +done: + return ret; +} + +static int msm_pcm_channel_mixer_cfg_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct msm_plat_data *pdata = dev_get_drvdata(component->dev); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_pcm_get_chmixer(pdata, fe_id, session_type); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + ucontrol->value.integer.value[0] = chmixer_pspd->enable; + ucontrol->value.integer.value[1] = chmixer_pspd->rule; + ucontrol->value.integer.value[2] = chmixer_pspd->input_channel; + ucontrol->value.integer.value[3] = chmixer_pspd->output_channel; + ucontrol->value.integer.value[4] = chmixer_pspd->port_idx; + return 0; +} + +static int msm_pcm_channel_mixer_output_map_ctl_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + int i = 0; + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct msm_plat_data *pdata = dev_get_drvdata(component->dev); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_pcm_get_chmixer(pdata, fe_id, session_type); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + chmixer_pspd->override_out_ch_map = true; + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->out_ch_map[i] = + ucontrol->value.integer.value[i]; + + return 0; +} + +static int msm_pcm_channel_mixer_output_map_ctl_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + int i = 0; + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct msm_plat_data *pdata = dev_get_drvdata(component->dev); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_pcm_get_chmixer(pdata, fe_id, session_type); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + ucontrol->value.integer.value[i] = + chmixer_pspd->out_ch_map[i]; + return 0; +} + +static int msm_pcm_channel_mixer_input_map_ctl_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + int i = 0; + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct msm_plat_data *pdata = dev_get_drvdata(component->dev); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_pcm_get_chmixer(pdata, fe_id, session_type); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + chmixer_pspd->override_in_ch_map = true; + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->in_ch_map[i] = ucontrol->value.integer.value[i]; + + return 0; +} + +static int msm_pcm_channel_mixer_input_map_ctl_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + int i = 0; + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct msm_plat_data *pdata = dev_get_drvdata(component->dev); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_pcm_get_chmixer(pdata, fe_id, session_type); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + ucontrol->value.integer.value[i] = + chmixer_pspd->in_ch_map[i]; + return 0; +} + +static int msm_pcm_channel_mixer_weight_ctl_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + int channel = (kcontrol->private_value >> 16) & 0xFF; + int i = 0; + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct msm_plat_data *pdata = dev_get_drvdata(component->dev); + struct msm_pcm_channel_mixer *chmixer_pspd; + + chmixer_pspd = msm_pcm_get_chmixer(pdata, fe_id, session_type); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + if (channel <= 0 || channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: invalid channel number %d\n", __func__, channel); + return -EINVAL; + } + channel--; + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->channel_weight[channel][i] = + ucontrol->value.integer.value[i]; + return 0; +} + +static int msm_pcm_channel_mixer_weight_ctl_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value & 0xFF; + int session_type = (kcontrol->private_value >> 8) & 0xFF; + int channel = (kcontrol->private_value >> 16) & 0xFF; + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct msm_plat_data *pdata = dev_get_drvdata(component->dev); + int i = 0; + struct msm_pcm_channel_mixer *chmixer_pspd; + + if (channel <= 0 || channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: invalid channel number %d\n", __func__, channel); + return -EINVAL; + } + channel--; + + chmixer_pspd = msm_pcm_get_chmixer(pdata, fe_id, session_type); + if (!chmixer_pspd) { + pr_err("%s: invalid chmixer_pspd in pdata", __func__); + return -EINVAL; + } + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + ucontrol->value.integer.value[i] = + chmixer_pspd->channel_weight[channel][i]; + return 0; +} + +static int msm_pcm_add_platform_controls(struct snd_kcontrol_new *kctl, + struct snd_soc_pcm_runtime *rtd, const char *name_prefix, + const char *name_suffix, int session_type, int channels) +{ + int ret = -EINVAL; + char *mixer_name = NULL; + struct snd_pcm *pcm = rtd->pcm; + const char *deviceNo = "NN"; + const char *channelNo = "NN"; + int ctl_len = 0; + struct snd_soc_component *component = NULL; + + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + ctl_len = strlen(name_prefix) + 1 + strlen(deviceNo) + 1 + + strlen(channelNo) + 1 + strlen(name_suffix) + 1; + + mixer_name = kzalloc(ctl_len, GFP_KERNEL); + if (mixer_name == NULL) + return -ENOMEM; + + if (channels >= 0) { + snprintf(mixer_name, ctl_len, "%s %d %s %d", + name_prefix, pcm->device, name_suffix, channels); + kctl->private_value = (rtd->dai_link->id) | (session_type << 8) | + (channels << 16); + } else { + snprintf(mixer_name, ctl_len, "%s %d %s", + name_prefix, pcm->device, name_suffix); + kctl->private_value = (rtd->dai_link->id) | (session_type << 8); + } + + kctl->name = mixer_name; + ret = snd_soc_add_component_controls(component, kctl, 1); + kfree(mixer_name); + return ret; +} + +static int msm_pcm_channel_mixer_output_map_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8; + /* Valid channel map value ranges from 1 to 64 */ + uinfo->value.integer.min = 1; + uinfo->value.integer.max = 64; + return 0; +} + +static int msm_pcm_add_channel_mixer_output_map_controls( + struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm *pcm = rtd->pcm; + const char *playback_mixer_ctl_name = "AudStr"; + const char *capture_mixer_ctl_name = "AudStr Capture"; + const char *suffix = "ChMixer Output Map"; + int session_type = 0, ret = 0, channel = -1; + struct snd_kcontrol_new channel_mixer_output_map_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_pcm_channel_mixer_output_map_info, + .put = msm_pcm_channel_mixer_output_map_ctl_put, + .get = msm_pcm_channel_mixer_output_map_ctl_get, + .private_value = 0, + }; + + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream != NULL) { + session_type = SESSION_TYPE_RX; + ret = msm_pcm_add_platform_controls(&channel_mixer_output_map_control, + rtd, playback_mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) + goto fail; + } + + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream != NULL) { + session_type = SESSION_TYPE_TX; + ret = msm_pcm_add_platform_controls(&channel_mixer_output_map_control, + rtd, capture_mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) + goto fail; + } + return 0; + +fail: + pr_err("%s: failed add platform ctl, err = %d\n", + __func__, ret); + return ret; +} + +static int msm_pcm_channel_mixer_input_map_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8; + /* Valid channel map value ranges from 1 to 64 */ + uinfo->value.integer.min = 1; + uinfo->value.integer.max = 64; + return 0; +} + +static int msm_pcm_add_channel_mixer_input_map_controls( + struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm *pcm = rtd->pcm; + const char *playback_mixer_ctl_name = "AudStr"; + const char *capture_mixer_ctl_name = "AudStr Capture"; + const char *suffix = "ChMixer Input Map"; + int session_type = 0, ret = 0, channel = -1; + struct snd_kcontrol_new channel_mixer_input_map_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_pcm_channel_mixer_input_map_info, + .put = msm_pcm_channel_mixer_input_map_ctl_put, + .get = msm_pcm_channel_mixer_input_map_ctl_get, + .private_value = 0, + }; + + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream != NULL) { + session_type = SESSION_TYPE_RX; + ret = msm_pcm_add_platform_controls(&channel_mixer_input_map_control, + rtd, playback_mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) + goto fail; + } + + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream != NULL) { + session_type = SESSION_TYPE_TX; + ret = msm_pcm_add_platform_controls(&channel_mixer_input_map_control, + rtd, capture_mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) + goto fail; + } + return 0; + +fail: + pr_err("%s: failed add platform ctl, err = %d\n", + __func__, ret); + + return ret; +} + +static int msm_pcm_channel_mixer_cfg_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + /* five int values: enable, rule, in_channels, out_channels and port_id */ + uinfo->count = 5; + /* Valid range is all positive values to support above controls */ + uinfo->value.integer.min = 0; + uinfo->value.integer.max = INT_MAX; + return 0; +} + +static int msm_pcm_add_channel_mixer_cfg_controls( + struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm *pcm = rtd->pcm; + const char *playback_mixer_ctl_name = "AudStr"; + const char *capture_mixer_ctl_name = "AudStr Capture"; + const char *suffix = "ChMixer Cfg"; + int session_type = 0, ret = 0, channel = -1; + struct msm_plat_data *pdata = NULL; + struct snd_soc_component *component = NULL; + struct snd_kcontrol_new channel_mixer_cfg_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_pcm_channel_mixer_cfg_info, + .put = msm_pcm_channel_mixer_cfg_ctl_put, + .get = msm_pcm_channel_mixer_cfg_ctl_get, + .private_value = 0, + }; + + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + pdata = (struct msm_plat_data *) + dev_get_drvdata(component->dev); + + pdata->pcm_device[rtd->dai_link->id] = rtd->pcm; + + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream != NULL) { + session_type = SESSION_TYPE_RX; + ret = msm_pcm_add_platform_controls(&channel_mixer_cfg_control, + rtd, playback_mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) + goto fail; + } + + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream != NULL) { + session_type = SESSION_TYPE_TX; + ret = msm_pcm_add_platform_controls(&channel_mixer_cfg_control, + rtd, capture_mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) + goto fail; + } + return 0; + +fail: + pr_err("%s: failed add platform ctl, err = %d\n", + __func__, ret); + + return ret; +} + +static int msm_pcm_channel_mixer_weight_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8; + /* Valid range: 0 to 0x4000(Unity) gain weightage */ + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0x4000; + return 0; +} + +static int msm_pcm_add_channel_mixer_weight_controls( + struct snd_soc_pcm_runtime *rtd, + int channel) +{ + struct snd_pcm *pcm = rtd->pcm; + const char *playback_mixer_ctl_name = "AudStr"; + const char *capture_mixer_ctl_name = "AudStr Capture"; + const char *suffix = "ChMixer Weight Ch"; + int session_type = 0, ret = 0; + struct snd_kcontrol_new channel_mixer_weight_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "?", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = msm_pcm_channel_mixer_weight_info, + .put = msm_pcm_channel_mixer_weight_ctl_put, + .get = msm_pcm_channel_mixer_weight_ctl_get, + .private_value = 0, + }; + + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream != NULL) { + session_type = SESSION_TYPE_RX; + ret = msm_pcm_add_platform_controls(&channel_mixer_weight_control, + rtd, playback_mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) + goto fail; + } + + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream != NULL) { + session_type = SESSION_TYPE_TX; + ret = msm_pcm_add_platform_controls(&channel_mixer_weight_control, + rtd, capture_mixer_ctl_name, suffix, session_type, channel); + if (ret < 0) + goto fail; + } + return 0; + +fail: + pr_err("%s: failed add platform ctl, err = %d\n", + __func__, ret); + + return ret; +} + +static int msm_pcm_add_channel_mixer_controls(struct snd_soc_pcm_runtime *rtd) +{ + int i, ret = 0; + struct snd_pcm *pcm = NULL; + struct msm_plat_data *pdata = NULL; + struct snd_soc_component *component = NULL; + + if (!rtd || !rtd->pcm) { + pr_err("%s invalid rtd or pcm\n", __func__); + return -EINVAL; + } + pcm = rtd->pcm; + + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + pdata = (struct msm_plat_data *) + dev_get_drvdata(component->dev); + if (!pdata) { + pr_err("%s: platform data not populated\n", __func__); + return -EINVAL; + } + + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream && + !pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_RX]) { + pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_RX] = + kzalloc(sizeof(struct msm_pcm_channel_mixer), GFP_KERNEL); + if (!pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_RX]) { + ret = -ENOMEM; + goto fail; + } + } + + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream && + !pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_TX]) { + pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_TX] = + kzalloc(sizeof(struct msm_pcm_channel_mixer), GFP_KERNEL); + if (!pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_TX]) { + ret = -ENOMEM; + goto fail; + } + } + + ret = msm_pcm_add_channel_mixer_cfg_controls(rtd); + if (ret) { + pr_err("%s: pcm add channel mixer cfg controls failed:%d\n", + __func__, ret); + goto fail; + } + ret = msm_pcm_add_channel_mixer_input_map_controls(rtd); + if (ret) { + pr_err("%s: pcm add channel mixer input map controls failed:%d\n", + __func__, ret); + goto fail; + } + ret = msm_pcm_add_channel_mixer_output_map_controls(rtd); + if (ret) { + pr_err("%s: pcm add channel mixer output map controls failed:%d\n", + __func__, ret); + goto fail; + } + + for (i = 1; i <= PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) { + ret = msm_pcm_add_channel_mixer_weight_controls(rtd, i); + if (ret) { + pr_err("%s: pcm add channel mixer weight controls failed:%d\n", + __func__, ret); + goto fail; + } + } + return 0; + +fail: + kfree(pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_RX]); + kfree(pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_TX]); + pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_RX] = NULL; + pdata->chmixer_pspd[rtd->dai_link->id][SESSION_TYPE_TX] = NULL; + + return ret; +} + static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd) { int ret = 0; @@ -1850,6 +2541,10 @@ static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd) if (ret) pr_err("%s: pcm add app type controls failed:%d\n", __func__, ret); + ret = msm_pcm_add_channel_mixer_controls(rtd); + if (ret) + pr_err("%s: pcm add channel mixer controls failed:%d\n", + __func__, ret); return ret; } @@ -1973,8 +2668,15 @@ static int msm_pcm_probe(struct platform_device *pdev) static int msm_pcm_remove(struct platform_device *pdev) { struct msm_plat_data *pdata; + int i = 0; pdata = dev_get_drvdata(&pdev->dev); + if (pdata) { + for (i = 0; i < MSM_FRONTEND_DAI_MM_SIZE; i++) { + kfree(pdata->chmixer_pspd[i][SESSION_TYPE_RX]); + kfree(pdata->chmixer_pspd[i][SESSION_TYPE_TX]); + } + } kfree(pdata); snd_soc_unregister_component(&pdev->dev); return 0; diff --git a/asoc/msm-pcm-q6-v2.h b/asoc/msm-pcm-q6-v2.h index 8699a4825ce5..62fcebd3cbe4 100644 --- a/asoc/msm-pcm-q6-v2.h +++ b/asoc/msm-pcm-q6-v2.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2017, 2019 The Linux Foundation. All rights reserved. */ #ifndef _MSM_PCM_H @@ -115,6 +115,8 @@ struct msm_plat_data { int perf_mode; struct snd_pcm *pcm; struct msm_pcm_ch_map *ch_map[MSM_FRONTEND_DAI_MAX]; + struct snd_pcm *pcm_device[MSM_FRONTEND_DAI_MM_SIZE]; + struct msm_pcm_channel_mixer *chmixer_pspd[MSM_FRONTEND_DAI_MM_SIZE][2]; }; struct msm_pcm_ch_map { diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 00f603e36e82..11a271881154 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -84,6 +84,11 @@ static int msm_ec_ref_port_id; #define WEIGHT_0_DB 0x4000 /* all the FEs which can support channel mixer */ static struct msm_pcm_channel_mixer channel_mixer[MSM_FRONTEND_DAI_MM_SIZE]; + +/* all the FES which can support channel mixer for bidirection */ +static struct msm_pcm_channel_mixer + channel_mixer_v2[MSM_FRONTEND_DAI_MM_SIZE][2]; + /* input BE for each FE */ static int channel_input[MSM_FRONTEND_DAI_MM_SIZE][ADM_MAX_CHANNELS]; @@ -928,6 +933,51 @@ int msm_pcm_routing_send_chmix_cfg(int fe_id, int ip_channel_cnt, } EXPORT_SYMBOL(msm_pcm_routing_send_chmix_cfg); +/** + * msm_pcm_routing_set_channel_mixer_cfg - cache channel mixer + * setting before use case start. + * + * @fe_id: frontend idx + * @type: stream direction type + * @params: parameters of channel mixer setting + * + * Return 0 for success + */ +int msm_pcm_routing_set_channel_mixer_cfg( + int fe_id, int type, + struct msm_pcm_channel_mixer *params) +{ + int i, j = 0; + + channel_mixer_v2[fe_id][type].enable = params->enable; + channel_mixer_v2[fe_id][type].rule = params->rule; + channel_mixer_v2[fe_id][type].input_channel = + params->input_channel; + channel_mixer_v2[fe_id][type].output_channel = + params->output_channel; + channel_mixer_v2[fe_id][type].port_idx = params->port_idx; + + for (i = 0; i < ADM_MAX_CHANNELS; i++) + channel_mixer_v2[fe_id][type].in_ch_map[i] = + params->in_ch_map[i]; + for (i = 0; i < ADM_MAX_CHANNELS; i++) + channel_mixer_v2[fe_id][type].out_ch_map[i] = + params->out_ch_map[i]; + + for (i = 0; i < ADM_MAX_CHANNELS; i++) + for (j = 0; j < ADM_MAX_CHANNELS; j++) + channel_mixer_v2[fe_id][type].channel_weight[i][j] = + params->channel_weight[i][j]; + + channel_mixer_v2[fe_id][type].override_in_ch_map = + params->override_in_ch_map; + channel_mixer_v2[fe_id][type].override_out_ch_map = + params->override_out_ch_map; + + return 0; +} +EXPORT_SYMBOL(msm_pcm_routing_set_channel_mixer_cfg); + int msm_pcm_routing_reg_stream_app_type_cfg( int fedai_id, int session_type, int be_id, struct msm_pcm_stream_app_type_cfg *cfg_data) @@ -1490,6 +1540,60 @@ static u32 msm_pcm_routing_get_voc_sessionid(u16 val) return session_id; } +static int msm_pcm_routing_channel_mixer_v2(int fe_id, bool perf_mode, + int dspst_id, int stream_type) +{ + int copp_idx = 0; + int sess_type = 0; + int j = 0, be_id = 0; + int ret = 0; + + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %d\n", __func__, fe_id); + return 0; + } + + if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) + sess_type = SESSION_TYPE_RX; + else + sess_type = SESSION_TYPE_TX; + + if (!(channel_mixer_v2[fe_id][sess_type].enable)) { + pr_debug("%s: channel mixer not enabled for FE %d direction %d\n", + __func__, fe_id, sess_type); + return 0; + } + + be_id = channel_mixer_v2[fe_id][sess_type].port_idx - 1; + channel_mixer_v2[fe_id][sess_type].input_channels[0] = + channel_mixer_v2[fe_id][sess_type].input_channel; + + pr_debug("%s sess type %d,fe_id %d,override in:%d out:%d,be active %d\n", + __func__, sess_type, fe_id, + channel_mixer_v2[fe_id][sess_type].override_in_ch_map, + channel_mixer_v2[fe_id][sess_type].override_out_ch_map, + msm_bedais[be_id].active); + + if ((msm_bedais[be_id].active) && + test_bit(fe_id, &msm_bedais[be_id].fe_sessions[0])) { + unsigned long copp = + session_copp_map[fe_id][sess_type][be_id]; + for (j = 0; j < MAX_COPPS_PER_PORT; j++) { + if (test_bit(j, &copp)) { + copp_idx = j; + break; + } + } + + ret = adm_programable_channel_mixer( + msm_bedais[be_id].port_id, + copp_idx, dspst_id, sess_type, + &channel_mixer_v2[fe_id][sess_type], 0); + } + + return ret; +} + static int msm_pcm_routing_channel_mixer(int fe_id, bool perf_mode, int dspst_id, int stream_type) { @@ -1498,6 +1602,14 @@ static int msm_pcm_routing_channel_mixer(int fe_id, bool perf_mode, int i = 0, j = 0, be_id; int ret = 0; + ret = msm_pcm_routing_channel_mixer_v2(fe_id, perf_mode, + dspst_id, stream_type); + if (ret) { + pr_err("%s channel mixer v2 cmd set failure%d\n", __func__, + fe_id); + return ret; + } + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { pr_err("%s: invalid FE %d\n", __func__, fe_id); return 0; @@ -1546,6 +1658,72 @@ static int msm_pcm_routing_channel_mixer(int fe_id, bool perf_mode, return ret; } +/** + * msm_pcm_routing_set_channel_mixer_runtime - apply channel mixer + * setting during runtime. + * + * @be_id: backend index + * @session_id: session index + * @session_type: session type + * @params: parameters for channel mixer + * + * Retuen: 0 for success, else error + */ +int msm_pcm_routing_set_channel_mixer_runtime(int be_id, int session_id, + int session_type, + struct msm_pcm_channel_mixer *params) +{ + int rc = 0; + int port_id, copp_idx = 0; + + be_id--; + if (be_id < 0 || be_id >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: invalid backend id %d\n", __func__, + be_id); + return -EINVAL; + } + + port_id = msm_bedais[be_id].port_id; + copp_idx = adm_get_default_copp_idx(port_id); + pr_debug("%s: port_id - %d, copp_idx %d session id - %d\n", + __func__, port_id, copp_idx, session_id); + + if ((params->input_channel < 0) || + (params->input_channel > ADM_MAX_CHANNELS)) { + pr_err("%s: invalid input channel %d\n", __func__, + params->input_channel); + return -EINVAL; + } + + if ((params->output_channel < 0) || + (params->output_channel > ADM_MAX_CHANNELS)) { + pr_err("%s: invalid output channel %d\n", __func__, + params->output_channel); + return -EINVAL; + } + + params->input_channels[0] = params->input_channel; + + pr_debug("%s sess type %d,override in:%d out:%d,be active %d\n", + __func__, session_type, + params->override_in_ch_map, + params->override_out_ch_map, + msm_bedais[be_id].active); + + rc = adm_programable_channel_mixer(port_id, + copp_idx, + session_id, + session_type, + params, + 0); + if (rc) { + pr_err("%s: send params failed rc=%d\n", __func__, rc); + rc = -EINVAL; + } + return rc; +} +EXPORT_SYMBOL(msm_pcm_routing_set_channel_mixer_runtime); + int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, int dspst_id, int stream_type) { diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 9b663fffd822..fc93059d3a3c 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -4,6 +4,7 @@ #ifndef _MSM_PCM_ROUTING_H #define _MSM_PCM_ROUTING_H #include +#include /* * These names are used by HAL to specify the BE. If any changes are @@ -594,4 +595,13 @@ int msm_pcm_routing_send_chmix_cfg(int fe_id, int ip_channel_cnt, int op_channel_cnt, int *ch_wght_coeff, int session_type, int stream_type); int msm_pcm_routing_get_pp_ch_cnt(int fe_id, int session_type); + +int msm_pcm_routing_set_channel_mixer_cfg( + int fe_id, int session_type, + struct msm_pcm_channel_mixer *params); + +int msm_pcm_routing_set_channel_mixer_runtime( + int be_id, int session_id, + int session_type, + struct msm_pcm_channel_mixer *params); #endif /*_MSM_PCM_H*/ -- GitLab From f2f68463a7cbd71fc78172d01c649683a73e5de8 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Wed, 30 Jan 2019 10:43:04 +0800 Subject: [PATCH 0831/1645] adm: undo echo reference rx value reset after open echo reference value reset after open leads to second SVA session without echo. Undo the value reset. Change-Id: Ie6ae357108beed0c8f034a3408c494475376e486 Signed-off-by: Xiaojun Sang --- dsp/q6adm.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 2a3a47f7992f..7b4b049e99f2 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2907,7 +2907,6 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, if (this_adm.num_ec_ref_rx_chans != 0) { open_v8.endpoint_id_2 = this_adm.ec_ref_rx; - this_adm.ec_ref_rx = -1; } else { pr_err("%s: EC channels not set %d\n", __func__, @@ -2951,7 +2950,6 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, if (this_adm.ec_ref_rx_bit_width != 0) { ep2_payload.bit_width = this_adm.ec_ref_rx_bit_width; - this_adm.ec_ref_rx_bit_width = 0; } else { ep2_payload.bit_width = bit_width; } @@ -2959,7 +2957,6 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, if (this_adm.ec_ref_rx_sampling_rate != 0) { ep2_payload.sample_rate = this_adm.ec_ref_rx_sampling_rate; - this_adm.ec_ref_rx_sampling_rate = 0; } else { ep2_payload.sample_rate = rate; } @@ -3029,7 +3026,6 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, if (this_adm.ec_ref_rx && (path != 1) && (afe_get_port_type(tmp_port) == MSM_AFE_PORT_TYPE_TX)) { open.endpoint_id_2 = this_adm.ec_ref_rx; - this_adm.ec_ref_rx = -1; } open.topology_id = topology; @@ -3061,12 +3057,10 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, open_v6.hdr.pkt_size = sizeof(open_v6); open_v6.dev_num_channel_eid2 = this_adm.num_ec_ref_rx_chans; - this_adm.num_ec_ref_rx_chans = 0; if (this_adm.ec_ref_rx_bit_width != 0) { open_v6.bit_width_eid2 = this_adm.ec_ref_rx_bit_width; - this_adm.ec_ref_rx_bit_width = 0; } else { open_v6.bit_width_eid2 = bit_width; } @@ -3074,7 +3068,6 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, if (this_adm.ec_ref_rx_sampling_rate != 0) { open_v6.sample_rate_eid2 = this_adm.ec_ref_rx_sampling_rate; - this_adm.ec_ref_rx_sampling_rate = 0; } else { open_v6.sample_rate_eid2 = rate; } -- GitLab From f2afc390ce10f14fd8ac03a74fe87fbbd28e4999 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 1 Mar 2019 00:51:56 +0530 Subject: [PATCH 0832/1645] ASoC: bolero: Check for valid handle before pm_runtime_resume Check for valid handle before pm_runtime_resume in bolero register read/write functions to avoid dereference. Change-Id: I34d567e7575202817f4fcda784d0f3df2ed77bde Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/bolero-cdc.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index f1283f3df204..a21b57beb58d 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -103,7 +103,8 @@ static int __bolero_reg_read(struct bolero_priv *priv, goto err; } - pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev); + if (priv->macro_params[VA_MACRO].dev) + pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev); current_mclk_mux_macro = priv->current_mclk_mux_macro[macro_id]; if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) { @@ -125,8 +126,10 @@ static int __bolero_reg_read(struct bolero_priv *priv, priv->macro_params[current_mclk_mux_macro].mclk_fn( priv->macro_params[current_mclk_mux_macro].dev, false); err: - pm_runtime_mark_last_busy(priv->macro_params[VA_MACRO].dev); - pm_runtime_put_autosuspend(priv->macro_params[VA_MACRO].dev); + if (priv->macro_params[VA_MACRO].dev) { + pm_runtime_mark_last_busy(priv->macro_params[VA_MACRO].dev); + pm_runtime_put_autosuspend(priv->macro_params[VA_MACRO].dev); + } mutex_unlock(&priv->clk_lock); return ret; } @@ -143,7 +146,8 @@ static int __bolero_reg_write(struct bolero_priv *priv, "%s: SSR in progress, exit\n", __func__); goto err; } - ret = pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev); + if (priv->macro_params[VA_MACRO].dev) + ret = pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev); current_mclk_mux_macro = priv->current_mclk_mux_macro[macro_id]; if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) { @@ -165,8 +169,10 @@ static int __bolero_reg_write(struct bolero_priv *priv, priv->macro_params[current_mclk_mux_macro].mclk_fn( priv->macro_params[current_mclk_mux_macro].dev, false); err: - pm_runtime_mark_last_busy(priv->macro_params[VA_MACRO].dev); - pm_runtime_put_autosuspend(priv->macro_params[VA_MACRO].dev); + if (priv->macro_params[VA_MACRO].dev) { + pm_runtime_mark_last_busy(priv->macro_params[VA_MACRO].dev); + pm_runtime_put_autosuspend(priv->macro_params[VA_MACRO].dev); + } mutex_unlock(&priv->clk_lock); return ret; } -- GitLab From b4347d50d40ecb2005fc1926ab5fb749b83a3932 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Thu, 28 Feb 2019 20:11:49 -0800 Subject: [PATCH 0833/1645] kona: move display port mixers to common block Move Display Port mixer controls to common mixer control array, so that those can be exercised for Kona sound card with Bolero/Traverso codecs. Change-Id: I4f27694b554fc9f1e2070fdf3056b3c8f71d57d3 Signed-off-by: Banajit Goswami --- asoc/kona.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index d8c81fc6c962..91099bff17c5 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -3055,26 +3055,26 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, + ext_disp_rx_ch_get, ext_disp_rx_ch_put), + SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, + ext_disp_rx_format_get, ext_disp_rx_format_put), + SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, + ext_disp_rx_sample_rate_get, + ext_disp_rx_sample_rate_put), }; static const struct snd_kcontrol_new msm_snd_controls[] = { - SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, - ext_disp_rx_ch_get, ext_disp_rx_ch_put), SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, - ext_disp_rx_format_get, ext_disp_rx_format_put), SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, aux_pcm_rx_sample_rate_get, aux_pcm_rx_sample_rate_put), SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, aux_pcm_tx_sample_rate_get, aux_pcm_tx_sample_rate_put), - SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, - ext_disp_rx_sample_rate_get, - ext_disp_rx_sample_rate_put), }; static int msm_ext_disp_get_idx_from_beid(int32_t be_id) -- GitLab From bbf7792327b6c1c6061633a15b9a4be2d41c661b Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Fri, 1 Mar 2019 13:24:14 +0800 Subject: [PATCH 0834/1645] asoc: routing: add widget connection for FM playback Add connection for RX_CDC_DMA_RX_0 and WSA_CDC_DMA_RX_0 to suppport FM playback. Change-Id: I406faecd089e063848e9e8b507b1e1a0d1c21454 Signed-off-by: Meng Wang --- asoc/msm-pcm-routing-v2.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 00f603e36e82..b1e91acd69f0 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -22883,11 +22883,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"WSA_CDC_DMA_RX_0 Port Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"WSA_CDC_DMA_RX_0 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"RX_CDC_DMA_RX_0 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"WSA_CDC_DMA_RX_0 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"RX_CDC_DMA_RX_0 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"WSA_CDC_DMA_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0 Port Mixer"}, + + {"RX_CDC_DMA_RX_0 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"RX_CDC_DMA_RX_0 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"RX_CDC_DMA_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0 Port Mixer"}, {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, -- GitLab From 197cb30bc975c8f197126673bda445c5b54e24cf Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Fri, 1 Mar 2019 13:54:38 +0800 Subject: [PATCH 0835/1645] asoc: kona: update pcm id for Kona FE Update correct PCM id for Kona FE. Change-Id: I5033f12ef587d8c476f0da7a73a1a35a037db035 Signed-off-by: Meng Wang --- asoc/kona.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index d8c81fc6c962..d177eef95604 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -4058,7 +4058,6 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA3, }, - /* Hostless PCM purpose */ {/* hw:x,5 */ .name = "MSM AFE-PCM RX", .stream_name = "AFE-PROXY RX", @@ -4099,6 +4098,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { /* this dainlink has playback support */ .id = MSM_FRONTEND_DAI_MULTIMEDIA4, }, + /* Hostless PCM purpose */ {/* hw:x,8 */ .name = "AUXPCM Hostless", .stream_name = "AUXPCM Hostless", @@ -4489,7 +4489,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { }; static struct snd_soc_dai_link msm_bolero_fe_dai_links[] = { - {/* hw:x,37 */ + {/* hw:x,32 */ .name = LPASS_BE_WSA_CDC_DMA_TX_0, .stream_name = "WSA CDC DMA0 Capture", .cpu_dai_name = "msm-dai-cdc-dma-dev.45057", @@ -4505,7 +4505,7 @@ static struct snd_soc_dai_link msm_bolero_fe_dai_links[] = { }; static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { - { + {/* hw:x,33 */ .name = MSM_DAILINK_NAME(ASM Loopback), .stream_name = "MultiMedia6", .cpu_dai_name = "MultiMedia6", @@ -4522,7 +4522,7 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA6, }, - { + {/* hw:x,34 */ .name = "USB Audio Hostless", .stream_name = "USB Audio Hostless", .cpu_dai_name = "USBAUDIO_HOSTLESS", @@ -4538,7 +4538,7 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, - { + {/* hw:x,35 */ .name = "SLIMBUS_7 Hostless", .stream_name = "SLIMBUS_7 Hostless", .cpu_dai_name = "SLIMBUS7_HOSTLESS", @@ -4554,7 +4554,7 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, - { + {/* hw:x,36 */ .name = "Compress Capture", .stream_name = "Compress9", .cpu_dai_name = "MultiMedia17", -- GitLab From 01f1ba49be4584ece170181fdc2b85fd881e389d Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 26 Feb 2019 18:48:15 -0800 Subject: [PATCH 0836/1645] asoc: codecs: bolero: enable gpio and clk in right sequence Enable soundwire gpio before enabling soundwire clock so that bus clash does not happen when interrupts are received. Change-Id: I40983b8837373f1ea7ac8fa6add7c56225ff0592 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/rx-macro.c | 8 +++++--- asoc/codecs/bolero/tx-macro.c | 8 +++++--- asoc/codecs/bolero/wsa-macro.c | 8 +++++--- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 535a33697625..035215275621 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -3262,8 +3262,12 @@ static int rx_swrm_clock(void *handle, bool enable) __func__, (enable ? "enable" : "disable")); if (enable) { if (rx_priv->swr_clk_users == 0) { + msm_cdc_pinctrl_select_active_state( + rx_priv->rx_swr_gpio_p); ret = rx_macro_mclk_enable(rx_priv, 1, true); if (ret < 0) { + msm_cdc_pinctrl_select_sleep_state( + rx_priv->rx_swr_gpio_p); dev_err(rx_priv->dev, "%s: rx request clock enable failed\n", __func__); @@ -3281,8 +3285,6 @@ static int rx_swrm_clock(void *handle, bool enable) BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, 0x02, 0x00); rx_priv->reset_swr = false; - msm_cdc_pinctrl_select_active_state( - rx_priv->rx_swr_gpio_p); } rx_priv->swr_clk_users++; } else { @@ -3298,9 +3300,9 @@ static int rx_swrm_clock(void *handle, bool enable) regmap_update_bits(regmap, BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x00); + rx_macro_mclk_enable(rx_priv, 0, true); msm_cdc_pinctrl_select_sleep_state( rx_priv->rx_swr_gpio_p); - rx_macro_mclk_enable(rx_priv, 0, true); } } dev_dbg(rx_priv->dev, "%s: swrm clock users %d\n", diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 12123ecdd6f0..58f3689276da 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1437,8 +1437,12 @@ static int tx_macro_swrm_clock(void *handle, bool enable) __func__, (enable ? "enable" : "disable")); if (enable) { if (tx_priv->swr_clk_users == 0) { + msm_cdc_pinctrl_select_active_state( + tx_priv->tx_swr_gpio_p); ret = tx_macro_mclk_enable(tx_priv, 1); if (ret < 0) { + msm_cdc_pinctrl_select_sleep_state( + tx_priv->tx_swr_gpio_p); dev_err(tx_priv->dev, "%s: request clock enable failed\n", __func__); @@ -1456,8 +1460,6 @@ static int tx_macro_swrm_clock(void *handle, bool enable) BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, 0x02, 0x00); tx_priv->reset_swr = false; - msm_cdc_pinctrl_select_active_state( - tx_priv->tx_swr_gpio_p); } tx_priv->swr_clk_users++; } else { @@ -1472,9 +1474,9 @@ static int tx_macro_swrm_clock(void *handle, bool enable) regmap_update_bits(regmap, BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x00); + tx_macro_mclk_enable(tx_priv, 0); msm_cdc_pinctrl_select_sleep_state( tx_priv->tx_swr_gpio_p); - tx_macro_mclk_enable(tx_priv, 0); } } dev_dbg(tx_priv->dev, "%s: swrm clock users %d\n", diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 3c684243f333..b0a4b1e0f42d 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -2570,8 +2570,12 @@ static int wsa_swrm_clock(void *handle, bool enable) __func__, (enable ? "enable" : "disable")); if (enable) { if (wsa_priv->swr_clk_users == 0) { + msm_cdc_pinctrl_select_active_state( + wsa_priv->wsa_swr_gpio_p); ret = wsa_macro_mclk_enable(wsa_priv, 1, true); if (ret < 0) { + msm_cdc_pinctrl_select_sleep_state( + wsa_priv->wsa_swr_gpio_p); dev_err(wsa_priv->dev, "%s: wsa request clock enable failed\n", __func__); @@ -2589,8 +2593,6 @@ static int wsa_swrm_clock(void *handle, bool enable) BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 0x02, 0x00); wsa_priv->reset_swr = false; - msm_cdc_pinctrl_select_active_state( - wsa_priv->wsa_swr_gpio_p); } wsa_priv->swr_clk_users++; } else { @@ -2605,9 +2607,9 @@ static int wsa_swrm_clock(void *handle, bool enable) regmap_update_bits(regmap, BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x00); + wsa_macro_mclk_enable(wsa_priv, 0, true); msm_cdc_pinctrl_select_sleep_state( wsa_priv->wsa_swr_gpio_p); - wsa_macro_mclk_enable(wsa_priv, 0, true); } } dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n", -- GitLab From 242c2b8c1a8bbe17c499ae54567ab68a1bf6d771 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 1 Mar 2019 18:43:10 -0800 Subject: [PATCH 0837/1645] asoc: msm: fix data port collisions for Kona Enable block packing mode so that soundwire offset2 parameter takes effect and the channels do not overlap. Change-Id: I9f5c04a8dfbaba87c3c949c7b4c739d0c1039e21 Signed-off-by: Karthikeyan Mani --- asoc/sm8250-port-config.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/asoc/sm8250-port-config.h b/asoc/sm8250-port-config.h index a29f1065fbed..0a33c5fb6f58 100644 --- a/asoc/sm8250-port-config.h +++ b/asoc/sm8250-port-config.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #ifndef _SM8250_PORT_CONFIG @@ -17,10 +17,10 @@ static struct port_params wsa_frame_params_default[SWR_MSTR_PORT_LEN] = { {7, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {31, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - {63, 12, 31, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {63, 12, 31, 0xFF, 0xFF, 0xFF, 0x1, 0xFF, 0xFF}, {7, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {31, 18, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, - {63, 13, 31, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {63, 13, 31, 0xFF, 0xFF, 0xFF, 0x1, 0xFF, 0xFF}, {15, 7, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {15, 10, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, }; -- GitLab From 39b70f5ff2dfe0f82fbe3e2dd62619a7224c2a71 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 20 Feb 2019 17:24:10 -0800 Subject: [PATCH 0838/1645] soc: pinctrl-lpi: add changes to support slew rate config Add changes to read slew rate from device tree table and set the same under set configs list. Change-Id: I0d7e950d67d34b63c5a6436bb4d10b08a80c2c58 Signed-off-by: Karthikeyan Mani --- soc/pinctrl-lpi.c | 177 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 134 insertions(+), 43 deletions(-) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index 4212816c05c5..bef9cba72285 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ #include @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -21,39 +22,45 @@ #include "core.h" #include "pinctrl-utils.h" -#define LPI_AUTO_SUSPEND_DELAY 100 /* delay in msec */ +#define LPI_AUTO_SUSPEND_DELAY 100 /* delay in msec */ -#define LPI_ADDRESS_SIZE 0x20000 +#define LPI_ADDRESS_SIZE 0x20000 +#define LPI_SLEW_ADDRESS_SIZE 0x1000 -#define LPI_GPIO_REG_VAL_CTL 0x00 -#define LPI_GPIO_REG_DIR_CTL 0x04 +#define LPI_GPIO_REG_VAL_CTL 0x00 +#define LPI_GPIO_REG_DIR_CTL 0x04 -#define LPI_GPIO_REG_PULL_SHIFT 0x0 -#define LPI_GPIO_REG_PULL_MASK 0x3 +#define LPI_SLEW_REG_VAL_CTL 0x00 +#define LPI_SLEW_RATE_MAX 0x03 +#define LPI_SLEW_BITS_SIZE 0x02 +#define LPI_SLEW_OFFSET_INVALID 0xFFFFFFFF -#define LPI_GPIO_REG_FUNCTION_SHIFT 0x2 -#define LPI_GPIO_REG_FUNCTION_MASK 0x3C +#define LPI_GPIO_REG_PULL_SHIFT 0x0 +#define LPI_GPIO_REG_PULL_MASK 0x3 -#define LPI_GPIO_REG_OUT_STRENGTH_SHIFT 0x6 -#define LPI_GPIO_REG_OUT_STRENGTH_MASK 0x1C0 +#define LPI_GPIO_REG_FUNCTION_SHIFT 0x2 +#define LPI_GPIO_REG_FUNCTION_MASK 0x3C -#define LPI_GPIO_REG_OE_SHIFT 0x9 -#define LPI_GPIO_REG_OE_MASK 0x200 +#define LPI_GPIO_REG_OUT_STRENGTH_SHIFT 0x6 +#define LPI_GPIO_REG_OUT_STRENGTH_MASK 0x1C0 -#define LPI_GPIO_REG_DIR_SHIFT 0x1 -#define LPI_GPIO_REG_DIR_MASK 0x2 +#define LPI_GPIO_REG_OE_SHIFT 0x9 +#define LPI_GPIO_REG_OE_MASK 0x200 -#define LPI_GPIO_BIAS_DISABLE 0x0 -#define LPI_GPIO_PULL_DOWN 0x1 -#define LPI_GPIO_KEEPER 0x2 -#define LPI_GPIO_PULL_UP 0x3 +#define LPI_GPIO_REG_DIR_SHIFT 0x1 +#define LPI_GPIO_REG_DIR_MASK 0x2 -#define LPI_GPIO_FUNC_GPIO "gpio" -#define LPI_GPIO_FUNC_FUNC1 "func1" -#define LPI_GPIO_FUNC_FUNC2 "func2" -#define LPI_GPIO_FUNC_FUNC3 "func3" -#define LPI_GPIO_FUNC_FUNC4 "func4" -#define LPI_GPIO_FUNC_FUNC5 "func5" +#define LPI_GPIO_BIAS_DISABLE 0x0 +#define LPI_GPIO_PULL_DOWN 0x1 +#define LPI_GPIO_KEEPER 0x2 +#define LPI_GPIO_PULL_UP 0x3 + +#define LPI_GPIO_FUNC_GPIO "gpio" +#define LPI_GPIO_FUNC_FUNC1 "func1" +#define LPI_GPIO_FUNC_FUNC2 "func2" +#define LPI_GPIO_FUNC_FUNC3 "func3" +#define LPI_GPIO_FUNC_FUNC4 "func4" +#define LPI_GPIO_FUNC_FUNC5 "func5" static bool lpi_dev_up; static struct device *lpi_dev; @@ -70,30 +77,39 @@ enum lpi_gpio_func_index { /** * struct lpi_gpio_pad - keep current GPIO settings - * @offset: Nth GPIO in supported GPIOs. + * @offset: stores one of gpio_offset or slew_offset at a given time. + * @gpio_offset: Nth GPIO in supported GPIOs. + * @slew_offset: Nth GPIO's position in slew register in supported GPIOs. * @output_enabled: Set to true if GPIO output logic is enabled. * @value: value of a pin - * @base: Address base of LPI GPIO PAD. + * @base: stores one of gpio_base or slew_base at a given time. + * @gpio_base: Address base of LPI GPIO PAD. + * @slew_base: Address base of LPI SLEW PAD. * @pullup: Constant current which flow through GPIO output buffer. * @strength: No, Low, Medium, High * @function: See lpi_gpio_functions[] */ struct lpi_gpio_pad { - u32 offset; - bool output_enabled; - bool value; - char __iomem *base; - unsigned int pullup; - unsigned int strength; - unsigned int function; + u32 offset; + u32 gpio_offset; + u32 slew_offset; + bool output_enabled; + bool value; + char __iomem *base; + char __iomem *gpio_base; + char __iomem *slew_base; + unsigned int pullup; + unsigned int strength; + unsigned int function; }; struct lpi_gpio_state { - struct device *dev; - struct pinctrl_dev *ctrl; - struct gpio_chip chip; - char __iomem *base; - struct clk *lpass_npa_rsc_island; + struct device *dev; + struct pinctrl_dev *ctrl; + struct gpio_chip chip; + char __iomem *base; + struct clk *lpass_npa_rsc_island; + struct mutex slew_access_lock; }; static const char *const lpi_gpio_groups[] = { @@ -106,6 +122,7 @@ static const char *const lpi_gpio_groups[] = { #define LPI_TLMM_MAX_PINS 100 static u32 lpi_offset[LPI_TLMM_MAX_PINS]; +static u32 lpi_slew_offset[LPI_TLMM_MAX_PINS]; static const char *const lpi_gpio_functions[] = { [LPI_GPIO_FUNC_INDEX_GPIO] = LPI_GPIO_FUNC_GPIO, @@ -272,7 +289,9 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int pin, { struct lpi_gpio_pad *pad; unsigned int param, arg; - int i, ret = 0, val; + int i, ret = 0; + volatile unsigned long val; + struct lpi_gpio_state *state = dev_get_drvdata(pctldev->dev); pad = pctldev->desc->pins[pin].drv_data; @@ -306,12 +325,44 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int pin, case PIN_CONFIG_DRIVE_STRENGTH: pad->strength = arg; break; + case PIN_CONFIG_SLEW_RATE: + if (pad->slew_base == NULL || + pad->slew_offset == LPI_SLEW_OFFSET_INVALID) { + dev_dbg(pctldev->dev, "%s: invalid slew settings for pin: %d\n", + __func__, pin); + goto set_gpio; + } + if (arg > LPI_SLEW_RATE_MAX) { + dev_err(pctldev->dev, "%s: invalid slew rate %u for pin: %d\n", + __func__, arg, pin); + goto set_gpio; + } + pad->base = pad->slew_base; + pad->offset = 0; + mutex_lock(&state->slew_access_lock); + val = lpi_gpio_read(pad, LPI_SLEW_REG_VAL_CTL); + pad->offset = pad->slew_offset; + for (i = 0; i < LPI_SLEW_BITS_SIZE; i++) { + if (arg & 0x01) + set_bit(pad->offset, &val); + else + clear_bit(pad->offset, &val); + pad->offset++; + arg = arg >> 1; + } + pad->offset = 0; + lpi_gpio_write(pad, LPI_SLEW_REG_VAL_CTL, val); + mutex_unlock(&state->slew_access_lock); + break; default: ret = -EINVAL; goto done; } } +set_gpio: + pad->base = pad->gpio_base; + pad->offset = pad->gpio_offset; val = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL); val &= ~(LPI_GPIO_REG_PULL_MASK | LPI_GPIO_REG_OUT_STRENGTH_MASK | LPI_GPIO_REG_OE_MASK); @@ -502,7 +553,8 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) struct lpi_gpio_state *state; int ret, npins, i; char __iomem *lpi_base; - u32 reg; + char __iomem *slew_base; + u32 reg, slew_reg; struct clk *lpass_npa_rsc_island = NULL; ret = of_property_read_u32(dev->of_node, "reg", ®); @@ -524,6 +576,16 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) return ret; } + ret = of_property_read_u32_array(dev->of_node, + "qcom,lpi-slew-offset-tbl", + lpi_slew_offset, npins); + if (ret < 0) { + for (i = 0; i < npins; i++) + lpi_slew_offset[i] = LPI_SLEW_OFFSET_INVALID; + dev_dbg(dev, "%s: error in reading lpi slew offset table: %d\n", + __func__, ret); + } + state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); if (!state) return -ENOMEM; @@ -532,6 +594,23 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) state->dev = &pdev->dev; + slew_reg = 0; + ret = of_property_read_u32(dev->of_node, "qcom,slew-reg", &slew_reg); + if (!ret) { + slew_base = devm_ioremap(dev, slew_reg, LPI_SLEW_ADDRESS_SIZE); + if (slew_base == NULL) { + dev_err(dev, + "%s devm_ioremap failed for slew rate reg\n", + __func__); + ret = -ENOMEM; + goto err_io; + } + } else { + slew_base = NULL; + dev_dbg(dev, "error in reading lpi slew register: %d\n", + __func__, ret); + } + pindesc = devm_kcalloc(dev, npins, sizeof(*pindesc), GFP_KERNEL); if (!pindesc) return -ENOMEM; @@ -566,8 +645,13 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) pindesc->number = i; pindesc->name = lpi_gpio_groups[i]; - pad->base = lpi_base; - pad->offset = lpi_offset[i]; + pad->gpio_base = lpi_base; + pad->slew_base = slew_base; + pad->base = pad->gpio_base; + + pad->gpio_offset = lpi_offset[i]; + pad->slew_offset = lpi_slew_offset[i]; + pad->offset = pad->gpio_offset; } state->chip = lpi_gpio_template; @@ -578,6 +662,8 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) state->chip.of_gpio_n_cells = 2; state->chip.can_sleep = false; + mutex_init(&state->slew_access_lock); + state->ctrl = devm_pinctrl_register(dev, pctrldesc, state); if (IS_ERR(state->ctrl)) return PTR_ERR(state->ctrl); @@ -636,18 +722,23 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) err_range: gpiochip_remove(&state->chip); err_chip: + mutex_destroy(&state->slew_access_lock); +err_io: return ret; } static int lpi_pinctrl_remove(struct platform_device *pdev) { struct lpi_gpio_state *state = platform_get_drvdata(pdev); + pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); snd_event_client_deregister(&pdev->dev); audio_notifier_deregister("lpi_tlmm"); gpiochip_remove(&state->chip); + mutex_destroy(&state->slew_access_lock); + return 0; } -- GitLab From f0de7569250d74907abf64e90554477d3104392e Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 4 Mar 2019 16:39:41 -0800 Subject: [PATCH 0839/1645] asoc: msm: fix FM hosteless capture Add pcm device for FM hostless capture that uses MI2S capture. Change-Id: I72c79aec1c8e093d7e9d045f4da675ca955ffe63 Signed-off-by: Karthikeyan Mani --- asoc/kona.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index d177eef95604..69353589f6da 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -4486,10 +4486,25 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, + {/* hw:x,32 */ + .name = "Tertiary MI2S TX_Hostless", + .stream_name = "Tertiary MI2S_TX Hostless Capture", + .cpu_dai_name = "TERT_MI2S_TX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, }; static struct snd_soc_dai_link msm_bolero_fe_dai_links[] = { - {/* hw:x,32 */ + {/* hw:x,33 */ .name = LPASS_BE_WSA_CDC_DMA_TX_0, .stream_name = "WSA CDC DMA0 Capture", .cpu_dai_name = "msm-dai-cdc-dma-dev.45057", @@ -4505,7 +4520,7 @@ static struct snd_soc_dai_link msm_bolero_fe_dai_links[] = { }; static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { - {/* hw:x,33 */ + {/* hw:x,34 */ .name = MSM_DAILINK_NAME(ASM Loopback), .stream_name = "MultiMedia6", .cpu_dai_name = "MultiMedia6", @@ -4522,7 +4537,7 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA6, }, - {/* hw:x,34 */ + {/* hw:x,35 */ .name = "USB Audio Hostless", .stream_name = "USB Audio Hostless", .cpu_dai_name = "USBAUDIO_HOSTLESS", @@ -4538,7 +4553,7 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, - {/* hw:x,35 */ + {/* hw:x,36 */ .name = "SLIMBUS_7 Hostless", .stream_name = "SLIMBUS_7 Hostless", .cpu_dai_name = "SLIMBUS7_HOSTLESS", @@ -4554,7 +4569,7 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, - {/* hw:x,36 */ + {/* hw:x,37 */ .name = "Compress Capture", .stream_name = "Compress9", .cpu_dai_name = "MultiMedia17", -- GitLab From 88aefa8368a11a10cbd868b7193ad7b22667a74b Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Thu, 13 Dec 2018 10:45:40 +0100 Subject: [PATCH 0840/1645] asoc: qcs405: Add devices for concurrent audio record Add dai links to allow for several concurrent audio recordings from SPDIF and HDMI interfaces on qcs405. Change-Id: I5f4a2fcf16538f71ad14b3389732366e8d8e718f Signed-off-by: Ralf Herz --- asoc/qcs405.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 4d60c6e98238..0bbe37bd9118 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -6508,8 +6508,8 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .codec_name = "snd-soc-dummy", }, { - .name = MSM_DAILINK_NAME(Compr Capture), - .stream_name = "Compr Capture", + .name = MSM_DAILINK_NAME(Compr Capture2), + .stream_name = "Compr Capture2", .cpu_dai_name = "MultiMedia18", .platform_name = "msm-compress-dsp", .dynamic = 1, @@ -6552,6 +6552,48 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA27, }, + { + .name = MSM_DAILINK_NAME(Compr Capture3), + .stream_name = "Compr Capture3", + .cpu_dai_name = "MultiMedia19", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA19, + }, + { + .name = MSM_DAILINK_NAME(Compr Capture4), + .stream_name = "Compr Capture4", + .cpu_dai_name = "MultiMedia28", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA28, + }, + { + .name = MSM_DAILINK_NAME(Compr Capture5), + .stream_name = "Compr Capture5", + .cpu_dai_name = "MultiMedia29", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA29, + }, }; static struct snd_soc_dai_link msm_common_be_dai_links[] = { -- GitLab From fb81b6e7960084d45578f4fa211643f5cb1f2315 Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Wed, 12 Dec 2018 10:36:11 +0100 Subject: [PATCH 0841/1645] dsp: Add new channel ID to mark unused channel map slots Allow to mark entries in a channel map as unused to prevent mixing other channels in that slot. Change-Id: I06f7de932dec4d30b2d6cfe04460d07ddad89049 Signed-off-by: Ralf Herz --- dsp/q6adm.c | 4 ++-- include/dsp/apr_audio-v2.h | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 51fee3443cfd..edba25fe66c8 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2677,7 +2677,7 @@ static int adm_arrange_mch_ep2_map_v8( ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB; ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB; ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_CS; - ep_payload->dev_channel_mapping[9] = PCM_CHANNELS; + ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TS; } else if (channel_mode == 12) { ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; @@ -2701,7 +2701,7 @@ static int adm_arrange_mch_ep2_map_v8( ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB; ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB; ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_CS; - ep_payload->dev_channel_mapping[9] = PCM_CHANNELS; + ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TS; ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_CVH; ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_MS; ep_payload->dev_channel_mapping[12] = PCM_CHANNEL_FLC; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 1e643e42d9eb..8e75dbe173b0 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -5416,7 +5416,7 @@ struct asm_softvolume_params { #define PCM_CHANNEL_RB 9 /* Top surround channel. */ -#define PCM_CHANNELS 10 +#define PCM_CHANNEL_TS 10 /* Center vertical height channel.*/ #define PCM_CHANNEL_CVH 11 @@ -5496,6 +5496,9 @@ struct asm_softvolume_params { /* Right side direct channel. */ #define PCM_CHANNEL_RSD 34 +/* Mark unused channel. */ +#define PCM_CHANNEL_UNUSED 47 + #define PCM_FORMAT_MAX_NUM_CHANNEL 8 #define PCM_FORMAT_MAX_CHANNELS_9 9 @@ -5625,7 +5628,7 @@ struct asm_multi_channel_pcm_fmt_blk_v2 { * - #PCM_CHANNEL_CS * - #PCM_CHANNEL_LB * - #PCM_CHANNEL_RB - * - #PCM_CHANNELS + * - #PCM_CHANNEL_TS * - #PCM_CHANNEL_CVH * - #PCM_CHANNEL_MS * - #PCM_CHANNEL_FLC @@ -9559,7 +9562,7 @@ struct asm_volume_ctrl_channeltype_gain_pair { * - #PCM_CHANNEL_CS * - #PCM_CHANNEL_LB * - #PCM_CHANNEL_RB - * - #PCM_CHANNELS + * - #PCM_CHANNEL_TS * - #PCM_CHANNEL_CVH * - #PCM_CHANNEL_MS * - #PCM_CHANNEL_FLC @@ -9631,7 +9634,7 @@ struct asm_volume_ctrl_channelype_mute_pair { * - #PCM_CHANNEL_CS * - #PCM_CHANNEL_LB * - #PCM_CHANNEL_RB - * - #PCM_CHANNELS + * - #PCM_CHANNEL_TS * - #PCM_CHANNEL_CVH * - #PCM_CHANNEL_MS * - #PCM_CHANNEL_FLC -- GitLab From 49c325c69f2a258fa0e9b75bfb234c75ef7491a9 Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Thu, 20 Dec 2018 11:23:22 +0100 Subject: [PATCH 0842/1645] asoc: Add new channel ID to mark unused channel map slots Allow to mark entries in a channel map as unused to prevent mixing other channels in that slot. Change-Id: Iefbfb861b796129211e929cb0ddb84041b9f57b0 Signed-off-by: Ralf Herz --- asoc/msm-compress-q6-v2.c | 4 ++-- asoc/msm-qti-pp-config.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 4b77fbd6744e..be10bc1690fc 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -4082,8 +4082,8 @@ static int msm_compr_channel_map_info(struct snd_kcontrol *kcontrol, uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8; uinfo->value.integer.min = 0; - /* See PCM_CHANNEL_RSD=34 in apr_audio-v2.h */ - uinfo->value.integer.max = 34; + /* See PCM_CHANNEL_UNUSED=47 in apr_audio-v2.h */ + uinfo->value.integer.max = 47; return 0; } diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index 222a3a953236..ee67e83aa91f 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include @@ -1406,7 +1406,7 @@ static const struct snd_kcontrol_new sec_auxpcm_lb_vol_mixer_controls[] = { }; static const struct snd_kcontrol_new multi_ch_channel_map_mixer_controls[] = { - SOC_SINGLE_MULTI_EXT("Playback Device Channel Map", SND_SOC_NOPM, 0, 34, + SOC_SINGLE_MULTI_EXT("Playback Device Channel Map", SND_SOC_NOPM, 0, 47, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, msm_qti_pp_get_channel_map_mixer, msm_qti_pp_put_channel_map_mixer), }; -- GitLab From 4bbc917e03a8b14f3f6e33d31e470600ee50f957 Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Mon, 26 Nov 2018 14:53:43 +0100 Subject: [PATCH 0843/1645] asoc: Add API for capture path channel cfg Add mixer_ctl to set multichannel configuration for capture path. Change-Id: Ibed2d459b8b3959322bd547fe9b7a3c270ef0550 Signed-off-by: Ralf Herz --- asoc/msm-qti-pp-config.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index ee67e83aa91f..27319603d06a 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -824,6 +824,32 @@ static int msm_qti_pp_put_channel_map_mixer(struct snd_kcontrol *kcontrol, return 0; } +static int msm_qti_pp_get_channel_map_capture(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8] = {0}; + int i; + + adm_get_multi_ch_map(channel_map, ADM_PATH_LIVE_REC); + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + ucontrol->value.integer.value[i] = + (unsigned int) channel_map[i]; + return 0; +} + +static int msm_qti_pp_put_channel_map_capture(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8]; + int i; + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + channel_map[i] = (char)(ucontrol->value.integer.value[i]); + adm_set_multi_ch_map(channel_map, ADM_PATH_LIVE_REC); + + return 0; +} + /* Audio Sphere functions */ static void msm_qti_pp_asphere_init_state(void) @@ -1411,6 +1437,12 @@ static const struct snd_kcontrol_new multi_ch_channel_map_mixer_controls[] = { msm_qti_pp_put_channel_map_mixer), }; +static const struct snd_kcontrol_new multi_ch_channel_map_capture_controls[] = { + SOC_SINGLE_MULTI_EXT("Capture Device Channel Map", SND_SOC_NOPM, 0, 47, + 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, msm_qti_pp_get_channel_map_capture, + msm_qti_pp_put_channel_map_capture), +}; + static const struct snd_kcontrol_new get_rms_controls[] = { SOC_SINGLE_EXT("Get RMS", SND_SOC_NOPM, 0, 0xFFFFFFFF, @@ -1607,6 +1639,11 @@ void msm_qti_pp_add_controls(struct snd_soc_component *component) snd_soc_add_component_controls(component, get_rms_controls, ARRAY_SIZE(get_rms_controls)); + snd_soc_add_component_controls(component, + multi_ch_channel_map_capture_controls, + ARRAY_SIZE(multi_ch_channel_map_capture_controls)); + + snd_soc_add_component_controls(component, eq_enable_mixer_controls, ARRAY_SIZE(eq_enable_mixer_controls)); -- GitLab From fba2a8270a3e64abe6483e6b44226779fd9c7632 Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Mon, 26 Nov 2018 14:59:40 +0100 Subject: [PATCH 0844/1645] dsp: Handle media fmt update events Handle media format update events from ADSP in case of DSP loopback. Change-Id: I4004759cc77a05f46106d359417f97f0326af19d Signed-off-by: Ralf Herz --- dsp/q6asm.c | 33 ++++++++++++++++++++++++++++++++- include/dsp/apr_audio-v2.h | 5 +++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 680935098cc1..934fc580affb 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -2342,10 +2342,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) break; case ASM_STREAM_PP_EVENT: case ASM_STREAM_CMD_ENCDEC_EVENTS: - case ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE: + case ASM_IEC_61937_MEDIA_FMT_EVENT: if (data->payload_size >= 2 * sizeof(uint32_t)) pr_debug("%s: ASM_STREAM_EVENT payload[0][0x%x] payload[1][0x%x]", __func__, payload[0], payload[1]); + else if (data->payload_size >= sizeof(uint32_t)) + pr_debug("%s: ASM_STREAM_EVENT payload[0][0x%x]", + __func__, payload[0]); else pr_debug("%s: payload size of %x is less than expected.\n", __func__, data->payload_size); @@ -2380,6 +2383,34 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) pp_event_package->payload_len = payload_size; memcpy((void *)pp_event_package->payload, data->payload, payload_size); + if ((data->opcode == ASM_IEC_61937_MEDIA_FMT_EVENT) && + (payload_size == 4)) { + switch (payload[0]) { + case ASM_MEDIA_FMT_AC3: + ((uint32_t *)pp_event_package->payload)[0] = + SND_AUDIOCODEC_AC3; + break; + case ASM_MEDIA_FMT_EAC3: + ((uint32_t *)pp_event_package->payload)[0] = + SND_AUDIOCODEC_EAC3; + break; + case ASM_MEDIA_FMT_DTS: + ((uint32_t *)pp_event_package->payload)[0] = + SND_AUDIOCODEC_DTS; + break; + case ASM_MEDIA_FMT_TRUEHD: + ((uint32_t *)pp_event_package->payload)[0] = + SND_AUDIOCODEC_TRUEHD; + break; + case ASM_MEDIA_FMT_AAC_V2: + ((uint32_t *)pp_event_package->payload)[0] = + SND_AUDIOCODEC_AAC; + break; + default: + pr_debug("%s: Event with unknown media_fmt 0x%x\n", + __func__, payload[0]); + } + } ac->cb(data->opcode, data->token, (void *)pp_event_package, ac->priv); kfree(pp_event_package); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 8e75dbe173b0..bceab12135c5 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -646,8 +646,9 @@ struct adm_cmd_set_pp_params { #define ASM_STREAM_CMD_REGISTER_PP_EVENTS 0x00013213 #define ASM_STREAM_PP_EVENT 0x00013214 -#define ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE 0x13333 -#define ASM_IEC_61937_MEDIA_FMT_EVENT 0x13334 +#define ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE 0x1321C +#define ASM_IEC_61937_MEDIA_FMT_EVENT 0x1321D + #define DSP_STREAM_CMD "ADSP Stream Cmd" #define DSP_STREAM_CALLBACK "ADSP Stream Callback Event" -- GitLab From e3fb995afa4eea3da0a3f95a9899a00b82c2ef57 Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Mon, 17 Dec 2018 14:04:10 +0100 Subject: [PATCH 0845/1645] asoc: Add TRUEHD format to list of codes Support TRUEHD coding format in TX path. Change-Id: Id93c42392b3be86419ddc4c1ae9639b1f3a797ef Signed-off-by: Ralf Herz --- asoc/msm-transcode-loopback-q6-v2.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index 1b431ae06df8..9980874c2197 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -178,10 +178,11 @@ static void populate_codec_list(struct msm_transcode_loopback *trans, if (cstream->direction == SND_COMPRESS_CAPTURE) { compr_cap.direction = SND_COMPRESS_CAPTURE; - compr_cap.num_codecs = 3; + compr_cap.num_codecs = 4; compr_cap.codecs[0] = SND_AUDIOCODEC_PCM; compr_cap.codecs[1] = SND_AUDIOCODEC_AC3; compr_cap.codecs[2] = SND_AUDIOCODEC_EAC3; + compr_cap.codecs[3] = SND_AUDIOCODEC_TRUEHD; memcpy(&trans->source_compr_cap, &compr_cap, sizeof(struct snd_compr_caps)); } @@ -482,6 +483,11 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, trans->source.codec_format = FORMAT_EAC3; break; + case SND_AUDIOCODEC_TRUEHD: + pr_debug("Source SND_AUDIOCODEC_TRUEHD\n"); + trans->source.codec_format = + FORMAT_TRUEHD; + break; default: pr_debug("%s: unknown source codec\n", __func__); ret = -EINVAL; -- GitLab From 341574f12b673f83bff9f0a6d35b5089d68a0cfb Mon Sep 17 00:00:00 2001 From: Salendarsingh Gaud Date: Tue, 26 Feb 2019 18:54:00 +0530 Subject: [PATCH 0846/1645] Initial Android target definition for lito. Initial Android target definition in kernel for lito Change-Id: I2257391a2265abb4b25c8d2a4ad8823b15cd795d --- Android.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Android.mk b/Android.mk index c10d1caf8c09..80334f680034 100644 --- a/Android.mk +++ b/Android.mk @@ -3,7 +3,7 @@ MY_LOCAL_PATH := $(call my-dir) UAPI_OUT := $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/include -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito),true) $(shell mkdir -p $(UAPI_OUT)/linux;) $(shell mkdir -p $(UAPI_OUT)/sound;) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers) @@ -39,7 +39,7 @@ $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codec include $(MY_LOCAL_PATH)/asoc/codecs/wcd937x/Android.mk endif -ifeq ($(call is-board-platform-in-list, kona),true) +ifeq ($(call is-board-platform-in-list, kona lito),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/bolero/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/bolero/Android.mk $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd938x/Module.symvers) -- GitLab From cdd68dbe724cb383ab7d1903102ae44827f80b74 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Thu, 10 Jan 2019 16:21:00 +0530 Subject: [PATCH 0847/1645] msm: vote for LPASS core while access LPASS registers When ADSP is in power collapse or island state, it would fail to access LPASS codec register.Vote for LPASS core to avoid LPASS power collapse with pmruntime approach while accessing LPASS registers & TLMM. Change-Id: I74d037e499fb6f1245b9a1bd1b0a77200608c27b Signed-off-by: Mangesh Kunchamwar --- asoc/codecs/audio-ext-clk-up.c | 81 +++++---------- asoc/codecs/bolero/bolero-cdc.c | 30 +++--- asoc/codecs/bolero/internal.h | 4 +- dsp/q6afe.c | 177 ++++++++++++++++++++++++++++++++ include/dsp/q6afe-v2.h | 38 +++++++ soc/pinctrl-lpi.c | 32 +++--- 6 files changed, 273 insertions(+), 89 deletions(-) diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index 6ed5ddd34f9e..0384e7122cef 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #include @@ -14,7 +14,6 @@ #include #include #include -#include #include "audio-ext-clk-up.h" enum { @@ -27,7 +26,7 @@ enum { AUDIO_EXT_CLK_LPASS5, AUDIO_EXT_CLK_LPASS6, AUDIO_EXT_CLK_LPASS7, - AUDIO_EXT_CLK_LPASS_NPA_RSC_ISLAND, + AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE, AUDIO_EXT_CLK_LPASS_MAX, AUDIO_EXT_CLK_EXTERNAL_PLL = AUDIO_EXT_CLK_LPASS_MAX, AUDIO_EXT_CLK_MAX, @@ -51,7 +50,7 @@ struct audio_ext_clk_priv { struct afe_clk_set clk_cfg; struct audio_ext_clk audio_clk; const char *clk_name; - uint32_t npa_rsc_client_handle; + uint32_t lpass_core_hwvote_client_handle; }; static inline struct audio_ext_clk_priv *to_audio_clk(struct clk_hw *hw) @@ -138,43 +137,37 @@ static u8 audio_ext_clk_get_parent(struct clk_hw *hw) return 0; } -static int lpass_npa_rsc_prepare(struct clk_hw *hw) +static int lpass_hw_vote_prepare(struct clk_hw *hw) { struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw); int ret; - if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS_NPA_RSC_ISLAND) && - (clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX)) { - if (q6core_get_avcs_api_version_per_service( - APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= AVCS_API_VERSION_V4) { - ret = q6core_request_island_transition( - clk_priv->npa_rsc_client_handle, false); - if (ret < 0) { - pr_err("%s q6core_request_island_transition failed %d\n", - __func__, ret); - return ret; - } + if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE) { + ret = afe_vote_lpass_core_hw(AFE_LPASS_CORE_HW_MACRO_BLOCK, + "LPASS_HW_MACRO", + &clk_priv->lpass_core_hwvote_client_handle); + if (ret < 0) { + pr_err("%s lpass core hw vote failed %d\n", + __func__, ret); + return ret; } } return 0; } -static void lpass_npa_rsc_unprepare(struct clk_hw *hw) +static void lpass_hw_vote_unprepare(struct clk_hw *hw) { struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw); int ret = 0; - if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS_NPA_RSC_ISLAND) && - (clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX)) { - if (q6core_get_avcs_api_version_per_service( - APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= AVCS_API_VERSION_V4) { - ret = q6core_request_island_transition( - clk_priv->npa_rsc_client_handle, true); - if (ret < 0) { - pr_err("%s q6core_request_island_transition failed %d\n", - __func__, ret); - } + if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE) { + ret = afe_unvote_lpass_core_hw( + AFE_LPASS_CORE_HW_MACRO_BLOCK, + clk_priv->lpass_core_hwvote_client_handle); + if (ret < 0) { + pr_err("%s lpass core hw vote failed %d\n", + __func__, ret); } } } @@ -185,9 +178,9 @@ static const struct clk_ops audio_ext_clk_ops = { .get_parent = audio_ext_clk_get_parent, }; -static const struct clk_ops lpass_npa_rsc_ops = { - .prepare = lpass_npa_rsc_prepare, - .unprepare = lpass_npa_rsc_unprepare, +static const struct clk_ops lpass_hw_vote_ops = { + .prepare = lpass_hw_vote_prepare, + .unprepare = lpass_hw_vote_unprepare, }; static const char * const audio_ext_pmi_div_clk[] = { @@ -322,8 +315,8 @@ static struct audio_ext_clk audio_clk_array[] = { .pnctrl_info = {NULL}, .fact = { .hw.init = &(struct clk_init_data){ - .name = "lpass_npa_rsc_island_clk", - .ops = &lpass_npa_rsc_ops, + .name = "lpass_hw_vote_clk", + .ops = &lpass_hw_vote_ops, }, }, }, @@ -539,35 +532,11 @@ static int audio_ref_clk_probe(struct platform_device *pdev) audio_put_pinctrl(pdev); return ret; } - - if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_NPA_RSC_ISLAND) { - if (q6core_get_avcs_api_version_per_service( - APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= AVCS_API_VERSION_V4) { - ret = q6core_create_lpass_npa_client( - AVCS_SLEEP_NODE_ISLAND_TRANSITION_RESOURCE_ID, - "lpass_npa_rsc_mgr", - &clk_priv->npa_rsc_client_handle); - if (ret) { - dev_err(&pdev->dev, "%s: q6core_create_lpass_npa_client is failed %d\n", - __func__, ret); - audio_put_pinctrl(pdev); - return ret; - } - } - } return 0; } static int audio_ref_clk_remove(struct platform_device *pdev) { - struct audio_ext_clk_priv *clk_priv = platform_get_drvdata(pdev); - - if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_NPA_RSC_ISLAND) { - if (q6core_get_avcs_api_version_per_service( - APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= AVCS_API_VERSION_V4) - q6core_destroy_lpass_npa_client( - clk_priv->npa_rsc_client_handle); - } audio_put_pinctrl(pdev); return 0; diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index a21b57beb58d..7bf629580901 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -949,7 +949,7 @@ static int bolero_probe(struct platform_device *pdev) struct bolero_priv *priv; u32 num_macros = 0; int ret; - struct clk *lpass_npa_rsc_island = NULL; + struct clk *lpass_core_hw_vote = NULL; priv = devm_kzalloc(&pdev->dev, sizeof(struct bolero_priv), GFP_KERNEL); @@ -998,16 +998,16 @@ static int bolero_probe(struct platform_device *pdev) bolero_add_child_devices); schedule_work(&priv->bolero_add_child_devices_work); - /* Register LPASS NPA resource */ - lpass_npa_rsc_island = devm_clk_get(&pdev->dev, "island_lpass_npa_rsc"); - if (IS_ERR(lpass_npa_rsc_island)) { - ret = PTR_ERR(lpass_npa_rsc_island); + /* Register LPASS core hw vote */ + lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote"); + if (IS_ERR(lpass_core_hw_vote)) { + ret = PTR_ERR(lpass_core_hw_vote); dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", - __func__, "island_lpass_npa_rsc", ret); - lpass_npa_rsc_island = NULL; + __func__, "lpass_core_hw_vote", ret); + lpass_core_hw_vote = NULL; ret = 0; } - priv->lpass_npa_rsc_island = lpass_npa_rsc_island; + priv->lpass_core_hw_vote = lpass_core_hw_vote; return 0; } @@ -1030,14 +1030,14 @@ int bolero_runtime_resume(struct device *dev) struct bolero_priv *priv = dev_get_drvdata(dev->parent); int ret = 0; - if (priv->lpass_npa_rsc_island == NULL) { - dev_dbg(dev, "%s: Invalid lpass npa rsc node\n", __func__); + if (priv->lpass_core_hw_vote == NULL) { + dev_dbg(dev, "%s: Invalid lpass core hw node\n", __func__); return 0; } - ret = clk_prepare_enable(priv->lpass_npa_rsc_island); + ret = clk_prepare_enable(priv->lpass_core_hw_vote); if (ret < 0) - dev_err(dev, "%s:lpass npa rsc island enable failed\n", + dev_err(dev, "%s:lpass core hw enable failed\n", __func__); pm_runtime_set_autosuspend_delay(priv->dev, BOLERO_AUTO_SUSPEND_DELAY); @@ -1050,10 +1050,10 @@ int bolero_runtime_suspend(struct device *dev) struct bolero_priv *priv = dev_get_drvdata(dev->parent); mutex_lock(&priv->clk_lock); - if (priv->lpass_npa_rsc_island != NULL) - clk_disable_unprepare(priv->lpass_npa_rsc_island); + if (priv->lpass_core_hw_vote != NULL) + clk_disable_unprepare(priv->lpass_core_hw_vote); else - dev_dbg(dev, "%s: Invalid lpass npa rsc node\n", + dev_dbg(dev, "%s: Invalid lpass core hw node\n", __func__); mutex_unlock(&priv->clk_lock); return 0; diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 1e5651bae920..2749b0b0d324 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #ifndef _BOLERO_INTERNAL_H @@ -57,7 +57,7 @@ struct bolero_priv { u16 current_mclk_mux_macro[MAX_MACRO]; struct work_struct bolero_add_child_devices_work; u32 version; - struct clk *lpass_npa_rsc_island; + struct clk *lpass_core_hw_vote; /* Entry for version info */ struct snd_info_entry *entry; diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 7f170ea441d8..62d4851f00ac 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -92,6 +92,9 @@ struct afe_ctl { atomic_t status; wait_queue_head_t wait[AFE_MAX_PORTS]; wait_queue_head_t wait_wakeup; + struct task_struct *task; + wait_queue_head_t lpass_core_hw_wait; + uint32_t lpass_hw_core_client_hdl; void (*tx_cb)(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv); void (*rx_cb)(uint32_t opcode, @@ -555,6 +558,16 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) return -EINVAL; } else if (data->opcode == AFE_EVENT_MBHC_DETECTION_SW_WA) { msm_aud_evt_notifier_call_chain(SWR_WAKE_IRQ_EVENT, NULL); + } else if (data->opcode == + AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST) { + uint32_t *payload = data->payload; + + pr_debug("%s: AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST handle %d\n", + __func__, payload[0]); + this_afe.lpass_hw_core_client_hdl = payload[0]; + atomic_set(&this_afe.state, 0); + atomic_set(&this_afe.status, 0); + wake_up(&this_afe.lpass_core_hw_wait); } else if (data->payload_size) { uint32_t *payload; uint16_t port_id = 0; @@ -635,6 +648,11 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) else return -EINVAL; break; + case AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST: + case AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST: + atomic_set(&this_afe.state, 0); + wake_up(&this_afe.lpass_core_hw_wait); + break; case AFE_SVC_CMD_EVENT_CFG: atomic_set(&this_afe.state, payload[1]); wake_up(&this_afe.wait_wakeup); @@ -8427,6 +8445,7 @@ int __init afe_init(void) init_waitqueue_head(&this_afe.wait[i]); } init_waitqueue_head(&this_afe.wait_wakeup); + init_waitqueue_head(&this_afe.lpass_core_hw_wait); wakeup_source_init(&wl.ws, "spkr-prot"); ret = afe_init_cal_data(); if (ret) @@ -8498,3 +8517,161 @@ int afe_cal_init_hwdep(void *card) return ret; } EXPORT_SYMBOL(afe_cal_init_hwdep); + +/* + * afe_vote_lpass_core_hw - + * Voting for lpass core hardware + * + * @hw_block_id: id of the hardware block + * @client_name: client name + * @client_handle: client handle + * + */ +int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name, + uint32_t *client_handle) +{ + struct afe_cmd_remote_lpass_core_hw_vote_request hw_vote_cfg; + struct afe_cmd_remote_lpass_core_hw_vote_request *cmd_ptr = + &hw_vote_cfg; + int ret = 0; + + if (!client_handle) { + pr_err("%s: Invalid client_handle\n", __func__); + return -EINVAL; + } + + if (!client_name) { + pr_err("%s: Invalid client_name\n", __func__); + *client_handle = 0; + return -EINVAL; + } + + mutex_lock(&this_afe.afe_cmd_lock); + + memset(cmd_ptr, 0, sizeof(hw_vote_cfg)); + + cmd_ptr->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cmd_ptr->hdr.pkt_size = sizeof(hw_vote_cfg); + cmd_ptr->hdr.src_port = 0; + cmd_ptr->hdr.dest_port = 0; + cmd_ptr->hdr.token = 0; + cmd_ptr->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST; + cmd_ptr->hw_block_id = hw_block_id; + strlcpy(cmd_ptr->client_name, client_name, + sizeof(cmd_ptr->client_name)); + + pr_debug("%s: lpass core hw vote opcode[0x%x] hw id[0x%x]\n", + __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id); + + *client_handle = 0; + atomic_set(&this_afe.status, 0); + atomic_set(&this_afe.state, 1); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) cmd_ptr); + if (ret < 0) { + pr_err("%s: lpass core hw vote failed %d\n", + __func__, ret); + goto done; + } + + ret = wait_event_timeout(this_afe.lpass_core_hw_wait, + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: timeout. waited for lpass core hw vote\n", + __func__); + ret = -ETIMEDOUT; + goto done; + } else { + /* set ret to 0 as no timeout happened */ + ret = 0; + } + + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: lpass core hw vote cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + goto done; + } + + *client_handle = this_afe.lpass_hw_core_client_hdl; + pr_debug("%s: lpass_hw_core_client_hdl %d\n", __func__, + this_afe.lpass_hw_core_client_hdl); +done: + mutex_unlock(&this_afe.afe_cmd_lock); + return ret; +} +EXPORT_SYMBOL(afe_vote_lpass_core_hw); + +/* + * afe_unvote_lpass_core_hw - + * unvoting for lpass core hardware + * + * @hw_block_id: id of the hardware block + * @client_handle: client handle + * + */ +int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle) +{ + struct afe_cmd_remote_lpass_core_hw_devote_request hw_vote_cfg; + struct afe_cmd_remote_lpass_core_hw_devote_request *cmd_ptr = + &hw_vote_cfg; + int ret = 0; + + mutex_lock(&this_afe.afe_cmd_lock); + + memset(cmd_ptr, 0, sizeof(hw_vote_cfg)); + + cmd_ptr->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cmd_ptr->hdr.pkt_size = sizeof(hw_vote_cfg); + cmd_ptr->hdr.src_port = 0; + cmd_ptr->hdr.dest_port = 0; + cmd_ptr->hdr.token = 0; + cmd_ptr->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST; + cmd_ptr->hw_block_id = hw_block_id; + cmd_ptr->client_handle = client_handle; + + pr_debug("%s: lpass core hw unvote opcode[0x%x] hw id[0x%x]\n", + __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id); + + atomic_set(&this_afe.status, 0); + atomic_set(&this_afe.state, 1); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) cmd_ptr); + if (ret < 0) { + pr_err("%s: lpass core hw devote failed %d\n", + __func__, ret); + goto done; + } + + ret = wait_event_timeout(this_afe.lpass_core_hw_wait, + (atomic_read(&this_afe.state) == 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: timeout. waited for lpass core hw devote\n", + __func__); + ret = -ETIMEDOUT; + goto done; + } else { + /* set ret to 0 as no timeout happened */ + ret = 0; + } + + if (atomic_read(&this_afe.status) > 0) { + pr_err("%s: lpass core hw devote cmd failed [%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&this_afe.status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.status)); + } + +done: + mutex_unlock(&this_afe.afe_cmd_lock); + return ret; +} +EXPORT_SYMBOL(afe_unvote_lpass_core_hw); + diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 158c3e99ce2e..413edc152af5 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -453,4 +453,42 @@ void afe_register_wakeup_irq_callback( void (*afe_cb_wakeup_irq)(void *handle)); int afe_get_doa_tracking_mon(u16 port_id, struct doa_tracking_mon_param *doa_tracking_data); + +#define AFE_LPASS_CORE_HW_BLOCK_ID_NONE 0 +#define AFE_LPASS_CORE_HW_BLOCK_ID_AVTIMER 2 +#define AFE_LPASS_CORE_HW_MACRO_BLOCK 3 + +/* Handles audio-video timer (avtimer) and BTSC vote requests from clients. + */ +#define AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST 0x000100f4 + +struct afe_cmd_remote_lpass_core_hw_vote_request { + struct apr_hdr hdr; + uint32_t hw_block_id; + /* ID of the hardware block. */ + char client_name[8]; + /* Name of the client. */ +} __packed; + +#define AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST 0x000100f5 + +struct afe_cmd_rsp_remote_lpass_core_hw_vote_request { + uint32_t client_handle; + /**< Handle of the client. */ +} __packed; + +#define AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST 0x000100f6 + +struct afe_cmd_remote_lpass_core_hw_devote_request { + struct apr_hdr hdr; + uint32_t hw_block_id; + /**< ID of the hardware block.*/ + + uint32_t client_handle; + /**< Handle of the client.*/ +} __packed; + +int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name, + uint32_t *client_handle); +int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle); #endif /* __Q6AFE_V2_H__ */ diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index bef9cba72285..3db22103f285 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -108,7 +108,7 @@ struct lpi_gpio_state { struct pinctrl_dev *ctrl; struct gpio_chip chip; char __iomem *base; - struct clk *lpass_npa_rsc_island; + struct clk *lpass_core_hw_vote; struct mutex slew_access_lock; }; @@ -555,7 +555,7 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) char __iomem *lpi_base; char __iomem *slew_base; u32 reg, slew_reg; - struct clk *lpass_npa_rsc_island = NULL; + struct clk *lpass_core_hw_vote = NULL; ret = of_property_read_u32(dev->of_node, "reg", ®); if (ret < 0) { @@ -699,16 +699,16 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) goto err_snd_evt; } - /* Register LPASS NPA resource */ - lpass_npa_rsc_island = devm_clk_get(&pdev->dev, "island_lpass_npa_rsc"); - if (IS_ERR(lpass_npa_rsc_island)) { - ret = PTR_ERR(lpass_npa_rsc_island); + /* Register LPASS core hw vote */ + lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote"); + if (IS_ERR(lpass_core_hw_vote)) { + ret = PTR_ERR(lpass_core_hw_vote); dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", - __func__, "island_lpass_npa_rsc", ret); - lpass_npa_rsc_island = NULL; + __func__, "lpass_core_hw_vote", ret); + lpass_core_hw_vote = NULL; ret = 0; } - state->lpass_npa_rsc_island = lpass_npa_rsc_island; + state->lpass_core_hw_vote = lpass_core_hw_vote; pm_runtime_set_autosuspend_delay(&pdev->dev, LPI_AUTO_SUSPEND_DELAY); pm_runtime_use_autosuspend(&pdev->dev); @@ -754,14 +754,14 @@ int lpi_pinctrl_runtime_resume(struct device *dev) struct lpi_gpio_state *state = dev_get_drvdata(dev); int ret = 0; - if (state->lpass_npa_rsc_island == NULL) { - dev_dbg(dev, "%s: Invalid lpass npa rsc node\n", __func__); + if (state->lpass_core_hw_vote == NULL) { + dev_dbg(dev, "%s: Invalid core hw node\n", __func__); return 0; } - ret = clk_prepare_enable(state->lpass_npa_rsc_island); + ret = clk_prepare_enable(state->lpass_core_hw_vote); if (ret < 0) { - dev_err(dev, "%s:lpass npa rsc island enable failed\n", + dev_err(dev, "%s:lpass core hw island enable failed\n", __func__); } pm_runtime_set_autosuspend_delay(dev, LPI_AUTO_SUSPEND_DELAY); @@ -772,11 +772,11 @@ int lpi_pinctrl_runtime_suspend(struct device *dev) { struct lpi_gpio_state *state = dev_get_drvdata(dev); - if (state->lpass_npa_rsc_island == NULL) { - dev_dbg(dev, "%s: Invalid lpass npa rsc node\n", __func__); + if (state->lpass_core_hw_vote == NULL) { + dev_dbg(dev, "%s: Invalid core hw node\n", __func__); return 0; } - clk_disable_unprepare(state->lpass_npa_rsc_island); + clk_disable_unprepare(state->lpass_core_hw_vote); return 0; } -- GitLab From eca1a399c4d4d372762ca512c6cf6b78c7d17fe4 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 15 Jan 2019 16:36:08 -0800 Subject: [PATCH 0848/1645] ipc: apr: check for packet size to header size comparison Check if packet size is large enough to hold the header. Change-Id: I7261f8111d8b5f4f7c181e469de248a732242d64 Signed-off-by: Karthikeyan Mani --- ipc/apr.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ipc/apr.c b/ipc/apr.c index ec05d3b15cdc..2e6d75f3eb6f 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -636,6 +636,12 @@ void apr_cb_func(void *buf, int len, void *priv) pr_err("APR: Wrong paket size\n"); return; } + + if (hdr->pkt_size < hdr_size) { + pr_err("APR: Packet size less than header size\n"); + return; + } + msg_type = hdr->hdr_field; msg_type = (msg_type >> 0x08) & 0x0003; if (msg_type >= APR_MSG_TYPE_MAX && msg_type != APR_BASIC_RSP_RESULT) { -- GitLab From a1351b945ffdd6e4de7bc049ec564ce7b7c78e41 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 7 Mar 2019 18:52:08 +0530 Subject: [PATCH 0849/1645] ASoC: codecs: Add support for soundwire clock for VA usecase Add support for soundwire clock for VA usecase. Change-Id: I1f56678ad36e4ae6c8dd458c0b7e96e847694050 Signed-off-by: Sudheer Papothi --- asoc/codecs/audio-ext-clk-up.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index 0384e7122cef..e6e68adf8895 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -27,6 +27,7 @@ enum { AUDIO_EXT_CLK_LPASS6, AUDIO_EXT_CLK_LPASS7, AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE, + AUDIO_EXT_CLK_LPASS8, AUDIO_EXT_CLK_LPASS_MAX, AUDIO_EXT_CLK_EXTERNAL_PLL = AUDIO_EXT_CLK_LPASS_MAX, AUDIO_EXT_CLK_MAX, @@ -320,6 +321,17 @@ static struct audio_ext_clk audio_clk_array[] = { }, }, }, + { + .pnctrl_info = {NULL}, + .fact = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "audio_lpass_mclk8", + .ops = &audio_ext_clk_ops, + }, + }, + }, { .pnctrl_info = {NULL}, .fact = { -- GitLab From 83a370dce7cd1bb3ad5c3e6be1b049b9e5430591 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Tue, 5 Mar 2019 16:15:21 -0800 Subject: [PATCH 0850/1645] asoc: kona: add back support for Slimbus 7 for BT use cases BT use cases on Kona target uses Slimbus 7 ports. Add back support for Slimbus 7 port for BT. Change-Id: Iaa5128738106fdafabe84831237947c3880de214 Signed-off-by: Banajit Goswami --- asoc/kona.c | 251 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) diff --git a/asoc/kona.c b/asoc/kona.c index 78d3f5ecf388..fd5c9a71250b 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -131,6 +131,15 @@ enum { CDC_DMA_TX_MAX, }; +enum { + SLIM_RX_7 = 0, + SLIM_RX_MAX, +}; +enum { + SLIM_TX_7 = 0, + SLIM_TX_MAX, +}; + struct msm_asoc_mach_data { struct snd_info_entry *codec_root; int usbc_en2_gpio; /* used by gpio driver API */ @@ -171,6 +180,15 @@ struct dev_config { u32 channels; }; +/* Default configuration of slimbus channels */ +static struct dev_config slim_rx_cfg[] = { + [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config slim_tx_cfg[] = { + [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + /* Default configuration of external display BE */ static struct dev_config ext_disp_rx_cfg[] = { [EXT_DISP_RX_IDX_DP] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, @@ -393,6 +411,15 @@ static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE", static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96", "KHZ_192", "KHZ_32", "KHZ_44P1", "KHZ_88P2", "KHZ_176P4"}; +static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; +static char const *bt_sample_rate_rx_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; +static char const *bt_sample_rate_tx_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); @@ -496,6 +523,9 @@ static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, ext_disp_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_rx, bt_sample_rate_rx_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_tx, bt_sample_rate_tx_text); static bool is_initial_boot; static bool codec_reg_done; @@ -2783,6 +2813,204 @@ static int msm_cdc_dma_get_idx_from_beid(int32_t be_id) return idx; } +static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* + * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) + * when used for BT_SCO use case. Return either Rx or Tx sample rate + * value. + */ + switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate = %d\n", __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n", + __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate, + slim_tx_cfg[SLIM_TX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_bt_sample_rate_rx_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate rx = %d\n", __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_rx_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rate: slim7_rx = %d, value = %d\n", + __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_bt_sample_rate_tx_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (slim_tx_cfg[SLIM_TX_7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate tx = %d\n", __func__, + slim_tx_cfg[SLIM_TX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_tx_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rate: slim7_tx = %d, value = %d\n", + __func__, + slim_tx_cfg[SLIM_TX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + static const struct snd_kcontrol_new msm_int_snd_controls[] = { SOC_ENUM_EXT("WSA_CDC_DMA_RX_0 Channels", wsa_cdc_dma_rx_0_chs, cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), @@ -3062,6 +3290,15 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, ext_disp_rx_sample_rate_get, ext_disp_rx_sample_rate_put), + SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), + SOC_ENUM_EXT("BT SampleRate RX", bt_sample_rate_rx, + msm_bt_sample_rate_rx_get, + msm_bt_sample_rate_rx_put), + SOC_ENUM_EXT("BT SampleRate TX", bt_sample_rate_tx, + msm_bt_sample_rate_tx_get, + msm_bt_sample_rate_tx_put), }; static const struct snd_kcontrol_new msm_snd_controls[] = { @@ -3327,6 +3564,20 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, channels->min = channels->max = msm_vi_feed_tx_ch; break; + case MSM_BACKEND_DAI_SLIMBUS_7_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[SLIM_RX_7].bit_format); + rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate; + channels->min = channels->max = + slim_rx_cfg[SLIM_RX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_7].channels; + break; + default: rate->min = rate->max = SAMPLING_RATE_48KHZ; break; -- GitLab From 4052afe2c75bd8c27dfe52e483a227ac45798391 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Fri, 8 Mar 2019 18:47:27 -0800 Subject: [PATCH 0851/1645] asoc: add support for assigning SLIMbus device ID dynamically SLIMbus device ID can be different for SLIMbus ports on different targets. Add support for dynamically assigning SLIMbus device ID at bootup time from device tree. Change-Id: I5a3b0812085ee53e8cd3bfac96eaaa939fda4106 Signed-off-by: Banajit Goswami --- asoc/msm-dai-q6-v2.c | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index c2be85b03245..ac238578c64e 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -2241,22 +2241,6 @@ static int msm_dai_q6_slim_bus_hw_params(struct snd_pcm_hw_params *params, dai_data->port_config.slim_sch.sample_rate = dai_data->rate; dai_data->port_config.slim_sch.num_channels = dai_data->channels; - switch (dai->id) { - case SLIMBUS_7_RX: - case SLIMBUS_7_TX: - case SLIMBUS_8_RX: - case SLIMBUS_8_TX: - case SLIMBUS_9_RX: - case SLIMBUS_9_TX: - dai_data->port_config.slim_sch.slimbus_dev_id = - AFE_SLIMBUS_DEVICE_2; - break; - default: - dai_data->port_config.slim_sch.slimbus_dev_id = - AFE_SLIMBUS_DEVICE_1; - break; - } - dev_dbg(dai->dev, "%s:slimbus_dev_id[%hu] bit_wd[%hu] format[%hu]\n" "num_channel %hu shared_ch_mapping[0] %hu\n" "slave_port_mapping[1] %hu slave_port_mapping[2] %hu\n" @@ -3509,6 +3493,31 @@ static const struct snd_kcontrol_new avd_drift_config_controls[] = { .get = msm_dai_q6_slim_rx_drift_get, }, }; + +static inline void msm_dai_q6_set_slim_dev_id(struct snd_soc_dai *dai) +{ + int rc = 0; + int slim_dev_id = 0; + const char *q6_slim_dev_id = "qcom,msm-dai-q6-slim-dev-id"; + struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + + dai_data->port_config.slim_sch.slimbus_dev_id = AFE_SLIMBUS_DEVICE_1; + + rc = of_property_read_u32(dai->dev->of_node, q6_slim_dev_id, + &slim_dev_id); + if (rc) { + dev_dbg(dai->dev, + "%s: missing %s in dt node\n", __func__, q6_slim_dev_id); + return; + } + + dev_dbg(dai->dev, "%s: slim_dev_id = %d\n", __func__, slim_dev_id); + + if (slim_dev_id >= AFE_SLIMBUS_DEVICE_1 && + slim_dev_id <= AFE_SLIMBUS_DEVICE_2) + dai_data->port_config.slim_sch.slimbus_dev_id = slim_dev_id; +} + static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) { struct msm_dai_q6_dai_data *dai_data; @@ -3532,6 +3541,9 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) msm_dai_q6_set_dai_id(dai); + if ((dai->id >= SLIMBUS_0_RX) && (dai->id <= SLIMBUS_9_TX)) + msm_dai_q6_set_slim_dev_id(dai); + switch (dai->id) { case SLIMBUS_4_TX: rc = snd_ctl_add(dai->component->card->snd_card, -- GitLab From 2a64e52662940dc9c22ba4d67dcac248121824b0 Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Mon, 4 Feb 2019 11:22:49 +0530 Subject: [PATCH 0852/1645] dsp: asm: Add check for num_channels before calling q6asm_map_channels Channel_mapping array size varies for different commands. Add check for num_channels before calling q6asm_map_channels. Change-Id: Iccbcfe82f716fc0ffe0a26b1779dcaa1c3cb805b Signed-off-by: Rohit kumar --- asoc/msm-compress-q6-v2.c | 10 +++++ asoc/msm-pcm-loopback-v2.c | 10 +++++ asoc/msm-pcm-q6-v2.c | 10 +++++ dsp/q6asm.c | 91 +++++++++++++++++++++++++++++++++++++- 4 files changed, 120 insertions(+), 1 deletion(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index be10bc1690fc..fb8fa6bf5ce1 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -4712,6 +4712,11 @@ static int msm_compr_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, chmixer_pspd->in_ch_map[i] = pdata->ch_map[fe_id]->channel_map[i]; } else { + if (chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: Invalid channel count %d\n", + __func__, chmixer_pspd->input_channel); + return -EINVAL; + } q6asm_map_channels(asm_ch_map, chmixer_pspd->input_channel, false); for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) @@ -4726,6 +4731,11 @@ static int msm_compr_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, chmixer_pspd->out_ch_map[i] = pdata->ch_map[fe_id]->channel_map[i]; } else { + if (chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: Invalid channel count %d\n", + __func__, chmixer_pspd->output_channel); + return -EINVAL; + } q6asm_map_channels(asm_ch_map, chmixer_pspd->output_channel, false); for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index a68698438e40..4834e81b6906 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -809,6 +809,11 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, if (chmixer_pspd->enable) { if (session_type == SESSION_TYPE_RX && !chmixer_pspd->override_in_ch_map) { + if (chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: Invalid channel count %d\n", + __func__, chmixer_pspd->input_channel); + return -EINVAL; + } q6asm_map_channels(asm_ch_map, chmixer_pspd->input_channel, false); for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) @@ -817,6 +822,11 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, reset_override_in_ch_map = true; } else if (session_type == SESSION_TYPE_TX && !chmixer_pspd->override_out_ch_map) { + if (chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: Invalid channel count %d\n", + __func__, chmixer_pspd->output_channel); + return -EINVAL; + } q6asm_map_channels(asm_ch_map, chmixer_pspd->output_channel, false); for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index bea58c9e07f1..71dbd0c987c4 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1939,6 +1939,11 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, chmixer_pspd->in_ch_map[i] = pdata->ch_map[fe_id]->channel_map[i]; } else { + if (chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: Invalid channel count %d\n", + __func__, chmixer_pspd->input_channel); + return -EINVAL; + } q6asm_map_channels(asm_ch_map, chmixer_pspd->input_channel, false); for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) @@ -1954,6 +1959,11 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, chmixer_pspd->out_ch_map[i] = pdata->ch_map[fe_id]->channel_map[i]; } else { + if (chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: Invalid channel count %d\n", + __func__, chmixer_pspd->output_channel); + return -EINVAL; + } q6asm_map_channels(asm_ch_map, chmixer_pspd->output_channel, false); for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 934fc580affb..ad6b7e01a68d 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -4265,6 +4265,12 @@ int q6asm_open_shared_io(struct audio_client *ac, return -EINVAL; } + if (config->channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, + config->channels); + return -EINVAL; + } + bufsz = config->bufsz; bufcnt = config->bufcnt; num_watermarks = 0; @@ -4664,6 +4670,11 @@ int q6asm_enc_cfg_blk_custom(struct audio_client *ac, custom_size = enc_generic->reserved[1]; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d] size[%d] res[2]=[%d] res[3]=[%d]\n", __func__, ac->session, custom_size, enc_generic->reserved[2], enc_generic->reserved[3]); @@ -4882,6 +4893,12 @@ int q6asm_set_encdec_chan_map(struct audio_client *ac, u8 *channel_mapping; int rc = 0; + if (num_channels > MAX_CHAN_MAP_CHANNELS) { + pr_err("%s: Invalid channel count %d\n", __func__, + num_channels); + return -EINVAL; + } + pr_debug("%s: Session %d, num_channels = %d\n", __func__, ac->session, num_channels); q6asm_add_hdr(ac, &chan_map.hdr, sizeof(chan_map), TRUE); @@ -4964,6 +4981,12 @@ static int q6asm_enc_cfg_blk_pcm_v5(struct audio_client *ac, goto fail_cmd; } + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -5066,6 +5089,12 @@ int q6asm_enc_cfg_blk_pcm_v4(struct audio_client *ac, goto fail_cmd; } + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -5166,6 +5195,12 @@ int q6asm_enc_cfg_blk_pcm_v3(struct audio_client *ac, goto fail_cmd; } + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -5263,6 +5298,11 @@ int q6asm_enc_cfg_blk_pcm_v2(struct audio_client *ac, return -EINVAL; } + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: Session %d, rate = %d, channels = %d\n", __func__, ac->session, rate, channels); @@ -5478,9 +5518,13 @@ int q6asm_enc_cfg_blk_pcm_native(struct audio_client *ac, struct asm_multi_channel_pcm_enc_cfg_v2 enc_cfg; u8 *channel_mapping; u32 frames_per_buf = 0; - int rc = 0; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: Session %d, rate = %d, channels = %d\n", __func__, ac->session, rate, channels); @@ -6098,6 +6142,11 @@ static int __q6asm_media_format_block_pcm(struct audio_client *ac, u8 *channel_mapping; int rc = 0; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]\n", __func__, ac->session, rate, channels); @@ -6181,6 +6230,11 @@ static int __q6asm_media_format_block_pcm_v3(struct audio_client *ac, u8 *channel_mapping; int rc; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -6265,6 +6319,11 @@ static int __q6asm_media_format_block_pcm_v4(struct audio_client *ac, u8 *channel_mapping; int rc; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -6352,6 +6411,11 @@ static int __q6asm_media_format_block_pcm_v5(struct audio_client *ac, u8 *channel_mapping; int rc; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -6604,6 +6668,11 @@ static int __q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac, u8 *channel_mapping; int rc = 0; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]\n", __func__, ac->session, rate, channels); @@ -6672,6 +6741,11 @@ static int __q6asm_media_format_block_multi_ch_pcm_v3(struct audio_client *ac, u8 *channel_mapping; int rc; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -6744,6 +6818,11 @@ static int __q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac, u8 *channel_mapping; int rc; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -6818,6 +6897,11 @@ static int __q6asm_media_format_block_multi_ch_pcm_v5(struct audio_client *ac, u8 *channel_mapping; int rc; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -7010,6 +7094,11 @@ int q6asm_media_format_block_gen_compr(struct audio_client *ac, u8 *channel_mapping; int rc = 0; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]\n", __func__, ac->session, rate, channels, bits_per_sample); -- GitLab From 52b8722a94c374f32b8357559d1ca65d87297a67 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Tue, 22 Jan 2019 10:31:21 -0800 Subject: [PATCH 0853/1645] dsp: asm: validate ADSP data size before access Check the size of ADSP payload before accessing it. Validate buffer index obtained from ADSP token before using it. CRs-Fixed: 2372302 Change-Id: I3f5e1b6f515935a10a8c59c324452be0a71f9473 Signed-off-by: Vignesh Kulothungan --- dsp/q6asm.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 934fc580affb..3783218c052c 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1950,9 +1950,10 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) data->dest_port); if ((data->opcode != ASM_DATA_EVENT_RENDERED_EOS) && (data->opcode != ASM_DATA_EVENT_EOS) && + (data->opcode != ASM_SESSION_EVENTX_OVERFLOW) && (data->opcode != ASM_SESSION_EVENT_RX_UNDERFLOW)) { - if (payload == NULL) { - pr_err("%s: payload is null\n", __func__); + if (payload == NULL || (data->payload_size < (2 * sizeof(uint32_t)))) { + pr_err("%s: payload is null or invalid size[%d]\n", __func__, data->payload_size); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return -EINVAL; @@ -2165,6 +2166,16 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) } spin_lock_irqsave(&port->dsp_lock, dsp_flags); buf_index = asm_token._token.buf_index; + if (buf_index < 0 || buf_index >= port->max_buf_cnt) { + pr_debug("%s: Invalid buffer index %u\n", + __func__, buf_index); + spin_unlock_irqrestore(&port->dsp_lock, + dsp_flags); + spin_unlock_irqrestore( + &(session[session_id].session_lock), + flags); + return -EINVAL; + } if ( data->payload_size >= 2 * sizeof(uint32_t) && (lower_32_bits(port->buf[buf_index].phys) != payload[0] || @@ -2267,6 +2278,16 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) } spin_lock_irqsave(&port->dsp_lock, dsp_flags); buf_index = asm_token._token.buf_index; + if (buf_index < 0 || buf_index >= port->max_buf_cnt) { + pr_debug("%s: Invalid buffer index %u\n", + __func__, buf_index); + spin_unlock_irqrestore(&port->dsp_lock, + dsp_flags); + spin_unlock_irqrestore( + &(session[session_id].session_lock), + flags); + return -EINVAL; + } port->buf[buf_index].used = 0; if (lower_32_bits(port->buf[buf_index].phys) != payload[READDONE_IDX_BUFADD_LSW] || -- GitLab From 350d51c06a794390c3b85f7731a759dc5abd4196 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 31 Jan 2019 17:29:16 +0530 Subject: [PATCH 0854/1645] asoc: sm6150: Remove zdet gpio callback for tasha variant Remove impedance detection gpio callback function for tasha variant as gpio control is not required for zdet. Change-Id: Ic038d11c078241ca438cdff756fd666f6106d509 Signed-off-by: Aditya Bavanari --- asoc/sm6150.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 84e05c8dcc39..11bb6115d0ed 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -4760,28 +4760,6 @@ static void msm_afe_clear_config(void) afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); } -static int msm_config_hph_en0_gpio(struct snd_soc_component *component, bool high) -{ - struct snd_soc_card *card = component->card; - struct msm_asoc_mach_data *pdata; - int val; - - if (!card) - return 0; - - pdata = snd_soc_card_get_drvdata(card); - if (!pdata || !gpio_is_valid(pdata->hph_en0_gpio)) - return 0; - - val = gpio_get_value_cansleep(pdata->hph_en0_gpio); - if ((!!val) == high) - return 0; - - gpio_direction_output(pdata->hph_en0_gpio, (int)high); - - return 1; -} - static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd) { int ret = 0; @@ -5103,7 +5081,6 @@ static int msm_audrx_tasha_init(struct snd_soc_pcm_runtime *rtd) pdata->codec_root = entry; } tasha_codec_info_create_codec_entry(pdata->codec_root, component); - tasha_mbhc_zdet_gpio_ctrl(msm_config_hph_en0_gpio, component); codec_reg_done = true; return 0; -- GitLab From 52bb6616c106c121f45e7123b7539ccf22a93467 Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Thu, 7 Feb 2019 13:42:46 +0530 Subject: [PATCH 0855/1645] asoc: msm-lsm-client: stop lab during lsm close Buffering is not stopped during lsm close due to which lab buffers can be queued during teardown of session. This leads to read being issued even after session close. Stop lab during close to avoid this. Use correct return value to indicate errors during lsm start and stop. Change-Id: I52fa33cebaa3ee6ae60eb2a60bb1e833f2a9d0d6 Signed-off-by: Chaithanya Krishna Bacharaju --- asoc/msm-lsm-client.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 379b5e5f6eb3..b101b377326d 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -1390,8 +1390,8 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, dev_dbg(rtd->dev, "%s: Starting LSM client session\n", __func__); if (!prtd->lsm_client->started) { - ret = q6lsm_start(prtd->lsm_client, true); - if (!ret) { + rc = q6lsm_start(prtd->lsm_client, true); + if (!rc) { prtd->lsm_client->started = true; dev_dbg(rtd->dev, "%s: LSM client session started\n", __func__); @@ -1407,19 +1407,19 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, if (prtd->lsm_client->lab_enable) { atomic_set(&prtd->read_abort, 1); if (prtd->lsm_client->lab_started) { - ret = q6lsm_stop_lab(prtd->lsm_client); - if (ret) + rc = q6lsm_stop_lab(prtd->lsm_client); + if (rc) dev_err(rtd->dev, - "%s: stop lab failed ret %d\n", - __func__, ret); + "%s: stop lab failed rc %d\n", + __func__, rc); prtd->lsm_client->lab_started = false; } } - ret = q6lsm_stop(prtd->lsm_client, true); - if (!ret) + rc = q6lsm_stop(prtd->lsm_client, true); + if (!rc) dev_dbg(rtd->dev, "%s: LSM client session stopped %d\n", - __func__, ret); + __func__, rc); prtd->lsm_client->started = false; } break; @@ -2593,6 +2593,25 @@ static int msm_lsm_close(struct snd_pcm_substream *substream) dev_dbg(rtd->dev, "%s\n", __func__); if (prtd->lsm_client->started) { + if (prtd->lsm_client->lab_enable) { + atomic_set(&prtd->read_abort, 1); + if (prtd->lsm_client->lab_started) { + ret = q6lsm_stop_lab(prtd->lsm_client); + if (ret) + dev_err(rtd->dev, + "%s: stop lab failed ret %d\n", + __func__, ret); + prtd->lsm_client->lab_started = false; + } + if (prtd->lsm_client->lab_buffer) { + ret = msm_lsm_lab_buffer_alloc(prtd, + LAB_BUFFER_DEALLOC); + if (ret) + dev_err(rtd->dev, + "%s: lab buffer dealloc failed ret %d\n", + __func__, ret); + } + } ret = q6lsm_stop(prtd->lsm_client, true); if (ret) dev_err(rtd->dev, -- GitLab From 430343928179d3c305350b4af3916bfbfe16e3a8 Mon Sep 17 00:00:00 2001 From: Dhananjay Kumar Date: Wed, 16 Jan 2019 21:57:58 +0530 Subject: [PATCH 0856/1645] dsp: add support to configure MFC in ec ref path Add support to process ec at channel count other than the playback channel count by providing ability to set downmixed channel count and downmixing weights to be used to downmix ec ref data obtained from playback path. These configs would be used to explicitly configure MFC module present in ec ref path, for usecases where ec processing cannot be done at playback channel count due to algorithmic or resource limitations. Change-Id: Iaa80a0f0da3697c55751b2201578252d6466d3b5 Signed-off-by: Dhananjay Kumar --- dsp/q6adm.c | 160 ++++++++++++++++++++++++++++++++++++- include/dsp/apr_audio-v2.h | 6 ++ include/dsp/q6adm-v2.h | 5 ++ 3 files changed, 170 insertions(+), 1 deletion(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index edba25fe66c8..f081065a6738 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -98,7 +98,9 @@ struct adm_ctl { int num_ec_ref_rx_chans; int ec_ref_rx_bit_width; int ec_ref_rx_sampling_rate; - + int num_ec_ref_rx_chans_downmixed; + uint16_t ec_ref_chmixer_weights[PCM_FORMAT_MAX_NUM_CHANNEL_V8] + [PCM_FORMAT_MAX_NUM_CHANNEL_V8]; int native_mode; }; @@ -2716,6 +2718,98 @@ static int adm_arrange_mch_ep2_map_v8( return rc; } + +static int adm_copp_set_ec_ref_mfc_cfg(int port_id, int copp_idx, + int sample_rate, int bps, + int in_channels, int out_channels) +{ + struct audproc_mfc_param_media_fmt mfc_cfg; + struct param_hdr_v3 param_hdr; + u16 *chmixer_params = NULL; + int rc = 0, i = 0, j = 0, param_index = 0, param_size = 0; + struct adm_device_endpoint_payload ep_payload = {0, 0, 0, {0}}; + + memset(&mfc_cfg, 0, sizeof(mfc_cfg)); + memset(&ep_payload, 0, sizeof(ep_payload)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AUDPROC_MODULE_ID_MFC_EC_REF; + param_hdr.instance_id = INSTANCE_ID_0; + + pr_debug("%s: port_id %d copp_idx %d SR %d, BW %d in_ch %d out_ch %d\n", + __func__, port_id, copp_idx, sample_rate, + bps, in_channels, out_channels); + + /* 1. Update Media Format */ + param_hdr.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; + param_hdr.param_size = sizeof(mfc_cfg); + + mfc_cfg.sampling_rate = sample_rate; + mfc_cfg.bits_per_sample = bps; + mfc_cfg.num_channels = out_channels; + + ep_payload.dev_num_channel = out_channels; + rc = adm_arrange_mch_ep2_map_v8(&ep_payload, out_channels); + if (rc < 0) { + pr_err("%s: unable to get map for out channels=%d\n", + __func__, out_channels); + return -EINVAL; + } + + for (i = 0; i < out_channels; i++) + mfc_cfg.channel_type[i] = (uint16_t) ep_payload.dev_channel_mapping[i]; + + + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, + param_hdr, (uint8_t *) &mfc_cfg); + if (rc) { + pr_err("%s: Failed to set media format, err %d\n", __func__, rc); + return rc; + } + + /* 2. Send Channel Mixer params */ + param_size = 2 * (4 + out_channels + in_channels + (out_channels * in_channels)); + param_size = round_up(param_size, 4); + param_hdr.param_id = DEFAULT_CHMIXER_PARAM_ID_COEFF; + param_hdr.param_size = param_size; + + pr_debug("%s: chmixer param sz = %d\n", __func__, param_size); + chmixer_params = kzalloc(param_size, GFP_KERNEL); + if (!chmixer_params) { + return -ENOMEM; + } + param_index = 2; /* param[0] and [1] represents chmixer rule(always 0) */ + chmixer_params[param_index++] = out_channels; + chmixer_params[param_index++] = in_channels; + + /* output channel map is same as one set in media format */ + for (i = 0; i < out_channels; i++) + chmixer_params[param_index++] = ep_payload.dev_channel_mapping[i]; + + /* input channel map should be same as one set for ep2 during copp open */ + ep_payload.dev_num_channel = in_channels; + rc = adm_arrange_mch_ep2_map_v8(&ep_payload, in_channels); + if (rc < 0) { + pr_err("%s: unable to get in channal map\n", __func__); + goto exit; + } + for (i = 0; i < in_channels; i++) + chmixer_params[param_index++] = ep_payload.dev_channel_mapping[i]; + + for (i = 0; i < out_channels; i++) + for (j = 0; j < in_channels; j++) + chmixer_params[param_index++] = this_adm.ec_ref_chmixer_weights[i][j]; + + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, + param_hdr, (uint8_t *) chmixer_params); + if (rc) + pr_err("%s: Failed to set chmixer params, err %d\n", __func__, rc); + +exit: + kfree(chmixer_params); + return rc; +} + /** * adm_open - * command to send ADM open @@ -2750,6 +2844,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, int tmp_port = q6audio_get_port_id(port_id); void *adm_params = NULL; int param_size; + int num_ec_ref_rx_chans = this_adm.num_ec_ref_rx_chans; pr_debug("%s:port %#x path:%d rate:%d mode:%d perf_mode:%d,topo_id %d\n", __func__, port_id, path, rate, channel_mode, perf_mode, @@ -3137,6 +3232,23 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, } } atomic_inc(&this_adm.copp.cnt[port_idx][copp_idx]); + + /* + * Configure MFC(in ec_ref path) if chmixing param is applicable and set. + * Except channels and channel maps the media format config for this module + * should match with the COPP(EP1) config values. + */ + if (path != ADM_PATH_PLAYBACK && + this_adm.num_ec_ref_rx_chans_downmixed != 0 && + num_ec_ref_rx_chans != this_adm.num_ec_ref_rx_chans_downmixed) { + ret = adm_copp_set_ec_ref_mfc_cfg(port_id, copp_idx, + rate, bit_width, num_ec_ref_rx_chans, + this_adm.num_ec_ref_rx_chans_downmixed); + this_adm.num_ec_ref_rx_chans_downmixed = 0; + if (ret) + pr_err("%s: set EC REF MFC cfg failed, err %d\n", __func__, ret); + } + return copp_idx; } EXPORT_SYMBOL(adm_open); @@ -3424,6 +3536,52 @@ void adm_num_ec_ref_rx_chans(int num_chans) } EXPORT_SYMBOL(adm_num_ec_ref_rx_chans); +/** + * adm_num_ec_rx_ref_chans_downmixed - + * Update EC ref num of channels(downmixed) to be fed to EC algo + * + */ +void adm_num_ec_ref_rx_chans_downmixed(int num_chans) +{ + this_adm.num_ec_ref_rx_chans_downmixed = num_chans; + pr_debug("%s: num_ec_ref_rx_chans_downmixed:%d\n", + __func__, this_adm.num_ec_ref_rx_chans_downmixed); +} +EXPORT_SYMBOL(adm_num_ec_ref_rx_chans_downmixed); + +/** + * adm_ec_ref_chmixer_weights - + * Update MFC(in ec ref) Channel Mixer Weights to be used + * for downmixing rx channels before feeding them to EC algo + * @out_channel_idx: index of output channel to which weightages are applicable + * @weights: pointer to array having input weightages + * @count: array sizeof pointer weights, max supported value is + * PCM_FORMAT_MAX_NUM_CHANNEL_V8 + * Returns 0 on success or error on failure + */ +int adm_ec_ref_chmixer_weights(int out_channel_idx, + uint16_t *weights, int count) +{ + int i = 0; + + if (weights == NULL || count <= 0 || out_channel_idx < 0 || + count > PCM_FORMAT_MAX_NUM_CHANNEL_V8 || + out_channel_idx >= PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: invalid weightages count(%d) ch_idx(%d)", + __func__, count, out_channel_idx); + return -EINVAL; + } + + for (i = 0; i < count; i++) { + this_adm.ec_ref_chmixer_weights[out_channel_idx][i] = weights[i]; + pr_debug("%s: out ch idx :%d, weight[%d] = %d\n", + __func__, out_channel_idx, i, weights[i]); + } + + return 0; +} +EXPORT_SYMBOL(adm_ec_ref_chmixer_weights); + /** * adm_ec_ref_rx_bit_width - * Update EC ref bit_width diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index bceab12135c5..d2cab24e6a51 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -843,6 +843,12 @@ struct audproc_softvolume_params { /* Param ID of Channel Mixer used by AUDPROC_MODULE_ID_MFC */ #define AUDPROC_CHMIXER_PARAM_ID_COEFF 0x00010342 +/* + * ID of the Media Format Converter (MFC) module present in EC REF COPP. + * This module supports the all param IDs supported by AUDPROC_MODULE_ID_MFC. + */ +#define AUDPROC_MODULE_ID_MFC_EC_REF 0x0001092C + struct adm_cmd_set_pp_params_v5 { struct apr_hdr hdr; diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index b86175a002b4..70dc2d094833 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -130,6 +130,11 @@ void adm_ec_ref_rx_id(int port_id); void adm_num_ec_ref_rx_chans(int num_chans); +void adm_num_ec_ref_rx_chans_downmixed(int num_chans); + +int adm_ec_ref_chmixer_weights(int out_channel_idx, + uint16_t *weights, int count); + void adm_ec_ref_rx_bit_width(int bit_width); void adm_ec_ref_rx_sampling_rate(int sampling_rate); -- GitLab From 242b5b060a91fbf3a9b666ba6c3fd3522433acde Mon Sep 17 00:00:00 2001 From: Dhananjay Kumar Date: Wed, 16 Jan 2019 22:45:12 +0530 Subject: [PATCH 0857/1645] asoc: add support to configure MFC in ec ref path Add support to process ec at channel count other than the playback channel count by providing ability to set downmixed channel count and downmixing weights to be used to downmix ec ref data obtained from playback path. These configs would be used to explicitly configure MFC module present in ec ref path, for usecases where ec processing cannot be done at playback channel count due to algorithmic or resource limitations. Also increase the ec ref channel count support to Sixteen from current max of Eight. Change-Id: I2297508aedd177580b1c9b2bed3c7c8421507629 Signed-off-by: Dhananjay Kumar --- asoc/msm-pcm-routing-v2.c | 62 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index dc403a5899aa..f913c58d39ee 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -70,6 +70,7 @@ static int lsm_port_index; static int slim0_rx_aanc_fb_port; static int msm_route_ec_ref_rx; static int msm_ec_ref_ch = 4; +static int msm_ec_ref_ch_downmixed = 4; static int msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S16_LE; static int msm_ec_ref_sampling_rate = 48000; static uint32_t voc_session_id = ALL_SESSION_VSID; @@ -3846,8 +3847,45 @@ static int msm_ec_ref_ch_put(struct snd_kcontrol *kcontrol, return 0; } +static int msm_ec_ref_ch_downmixed_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_ec_ref_ch_downmixed; + pr_debug("%s: msm_ec_ref_downmixed_ch = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_ec_ref_ch_downmixed_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_ec_ref_ch_downmixed = ucontrol->value.integer.value[0]; + pr_debug("%s: msm_ec_ref_downmixed_ch = %d\n", + __func__, msm_ec_ref_ch_downmixed); + adm_num_ec_ref_rx_chans_downmixed(msm_ec_ref_ch_downmixed); + return 0; +} + +static int msm_ec_ref_chmixer_weights_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int i = 0, ret = 0; + uint16_t weights[PCM_FORMAT_MAX_NUM_CHANNEL_V8] = {0}; + int out_channel_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + for (; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + weights[i] = ucontrol->value.integer.value[i]; + + ret = adm_ec_ref_chmixer_weights(out_channel_idx, + weights, PCM_FORMAT_MAX_NUM_CHANNEL_V8); + pr_debug("%s: ch_index = %d, ret = %d\n", __func__, out_channel_idx, ret); + return ret; +} + static const char *const ec_ref_ch_text[] = {"Zero", "One", "Two", "Three", - "Four", "Five", "Six", "Seven", "Eight"}; + "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", + "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen"}; static int msm_ec_ref_bit_format_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -3952,7 +3990,7 @@ static const char *const ec_ref_rate_text[] = {"0", "8000", "16000", "32000", "44100", "48000", "96000", "192000", "384000"}; static const struct soc_enum msm_route_ec_ref_params_enum[] = { - SOC_ENUM_SINGLE_EXT(9, ec_ref_ch_text), + SOC_ENUM_SINGLE_EXT(17, ec_ref_ch_text), SOC_ENUM_SINGLE_EXT(3, ec_ref_bit_format_text), SOC_ENUM_SINGLE_EXT(9, ec_ref_rate_text), }; @@ -3964,6 +4002,26 @@ static const struct snd_kcontrol_new ec_ref_param_controls[] = { msm_ec_ref_bit_format_get, msm_ec_ref_bit_format_put), SOC_ENUM_EXT("EC Reference SampleRate", msm_route_ec_ref_params_enum[2], msm_ec_ref_rate_get, msm_ec_ref_rate_put), + SOC_ENUM_EXT("EC Reference Downmixed Channels", msm_route_ec_ref_params_enum[0], + msm_ec_ref_ch_downmixed_get, msm_ec_ref_ch_downmixed_put), + SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch1", SND_SOC_NOPM, 0, + 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, + NULL, msm_ec_ref_chmixer_weights_put), + SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch2", SND_SOC_NOPM, 1, + 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, + NULL, msm_ec_ref_chmixer_weights_put), + SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch3", SND_SOC_NOPM, 2, + 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, + NULL, msm_ec_ref_chmixer_weights_put), + SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch4", SND_SOC_NOPM, 3, + 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, + NULL, msm_ec_ref_chmixer_weights_put), + SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch5", SND_SOC_NOPM, 4, + 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, + NULL, msm_ec_ref_chmixer_weights_put), + SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch6", SND_SOC_NOPM, 5, + 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, + NULL, msm_ec_ref_chmixer_weights_put), }; static int msm_routing_ec_ref_rx_get(struct snd_kcontrol *kcontrol, -- GitLab From 1e9062003025bbd0ef0a8c79aeb3de6367c64359 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 30 Jan 2019 14:16:34 +0530 Subject: [PATCH 0858/1645] soc: swr-mstr: Avoid redunant delay for wcd934x For codecs like tavil/tasha where the soundwire register access is through codec bridge, the soundwire bus latency is absorbed in slimbus io operations, hence do not require extra delay in soundwire driver for io operations. Change-Id: If77aa02f0c3c1755916b7a57776115d12e4f08bd Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index f9dbc24af097..8d82ff1ec775 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -448,11 +448,16 @@ static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, mutex_lock(&swrm->iolock); val = swrm_get_packed_reg_val(&swrm->rcmd_id, len, dev_addr, reg_addr); - /* wait for FIFO RD to complete to avoid overflow */ - usleep_range(100, 105); - swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val); - /* wait for FIFO RD CMD complete to avoid overflow */ - usleep_range(250, 255); + if (swrm->read) { + /* skip delay if read is handled in platform driver */ + swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val); + } else { + /* wait for FIFO RD to complete to avoid overflow */ + usleep_range(100, 105); + swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val); + /* wait for FIFO RD CMD complete to avoid overflow */ + usleep_range(250, 255); + } retry_read: *cmd_data = swr_master_read(swrm, SWRM_CMD_FIFO_RD_FIFO_ADDR); dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, rcmd_id: 0x%x, \ @@ -496,8 +501,12 @@ static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data, dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, cmd_id, swrm->wcmd_id,dev_addr, cmd_data); swr_master_write(swrm, SWRM_CMD_FIFO_WR_CMD, val); - /* wait for FIFO WR command to complete to avoid overflow */ - usleep_range(250, 255); + /* + * wait for FIFO WR command to complete to avoid overflow + * skip delay if write is handled in platform driver. + */ + if(!swrm->write) + usleep_range(250, 255); if (cmd_id == 0xF) { /* * sleep for 10ms for MSM soundwire variant to allow broadcast -- GitLab From d84669e428e821e6b231e391a754c7439638bd70 Mon Sep 17 00:00:00 2001 From: Nidhisha Dhananjayan Date: Wed, 20 Feb 2019 11:00:28 +0530 Subject: [PATCH 0859/1645] asoc: Stream_open issue fix for gapless playback msm_compr_trigger for next track is updated with q6asm_stream_open_write_v5 depending on the avcs_api_version. Change-Id: I6b3862a7b8e0480fffdcddc2ff0949cf5399d7a6 Signed-off-by: Nidhisha Dhananjayan --- asoc/msm-compress-q6-v2.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index be10bc1690fc..2ff472c99f48 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -2687,13 +2687,22 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd) pr_debug("%s: open_write stream_id %d bits_per_sample %d", __func__, stream_id, bits_per_sample); - rc = q6asm_stream_open_write_v4(prtd->audio_client, + + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= + ADSP_ASM_API_VERSION_V2) + rc = q6asm_stream_open_write_v5(prtd->audio_client, + prtd->codec, bits_per_sample, + stream_id, + prtd->gapless_state.use_dsp_gapless_mode); + else + rc = q6asm_stream_open_write_v4(prtd->audio_client, prtd->codec, bits_per_sample, stream_id, prtd->gapless_state.use_dsp_gapless_mode); if (rc < 0) { - pr_err("%s: Session out open failed for gapless\n", - __func__); + pr_err("%s: Session out open failed for gapless [%d]\n", + __func__, rc); break; } -- GitLab From d591f497ce2814dd6b7b3416b166c933c8ec5702 Mon Sep 17 00:00:00 2001 From: Tanya Dixit Date: Wed, 6 Feb 2019 14:06:48 +0530 Subject: [PATCH 0860/1645] dsp: q6voice: Check size of payload before access Check size of payload array before access in qdsp_mvm_callback. Change-Id: I81d945f963cfb4a3cb26155700b82880d891ec5e Signed-off-by: Vatsal Bucha --- dsp/q6voice.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index bb2bbdfa2992..99f2494172b0 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -7332,7 +7332,7 @@ EXPORT_SYMBOL(voc_config_vocoder); static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) { - uint32_t *ptr = NULL; + uint32_t *ptr = NULL, min_payload_size = 0; struct common_data *c = NULL; struct voice_data *v = NULL; struct vss_evt_voice_activity *voice_act_update = NULL; @@ -7400,7 +7400,7 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) } if (data->opcode == APR_BASIC_RSP_RESULT) { - if (data->payload_size) { + if (data->payload_size >= sizeof(ptr[0]) * 2) { ptr = data->payload; pr_debug("%x %x\n", ptr[0], ptr[1]); @@ -7470,7 +7470,13 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) } else if (data->opcode == VSS_IMEMORY_RSP_MAP) { pr_debug("%s, Revd VSS_IMEMORY_RSP_MAP response\n", __func__); - if (data->payload_size && data->token == VOIP_MEM_MAP_TOKEN) { + if (data->payload_size < sizeof(ptr[0])) { + pr_err("%s: payload has invalid size[%d]\n", __func__, + data->payload_size); + return -EINVAL; + } + + if (data->token == VOIP_MEM_MAP_TOKEN) { ptr = data->payload; if (ptr[0]) { v->shmem_info.mem_handle = ptr[0]; @@ -7537,10 +7543,13 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) pr_debug("%s: Received VSS_IVERSION_RSP_GET\n", __func__); if (data->payload_size) { + min_payload_size = min_t(u32, (int)data->payload_size, + CVD_VERSION_STRING_MAX_SIZE); version_rsp = (struct vss_iversion_rsp_get_t *)data->payload; memcpy(common.cvd_version, version_rsp->version, - CVD_VERSION_STRING_MAX_SIZE); + min_payload_size); + common.cvd_version[min_payload_size - 1] = '\0'; pr_debug("%s: CVD Version = %s\n", __func__, common.cvd_version); -- GitLab From c36b0b975240215d43527bf3f44a65afbf06ca88 Mon Sep 17 00:00:00 2001 From: Bhalchandra Gajare Date: Thu, 8 Mar 2018 17:57:38 -0800 Subject: [PATCH 0861/1645] uapi: wcd-spi-ac: add interface for client driver The wcd-spi-ac (access control) driver exposes character device to userspace to indicate information regarding WCD SPI usage. Add uapi header file with the commands and data expected by the character driver. Change-Id: I41dfc3181041c7e7a1bad8695fa723d3a965036b Signed-off-by: Bhalchandra Gajare --- include/uapi/linux/Kbuild | 1 + include/uapi/linux/wcd-spi-ac-params.h | 52 ++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 include/uapi/linux/wcd-spi-ac-params.h diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index f6af2bf8cca3..9b93abebc4b7 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -18,3 +18,4 @@ header-y += msm_audio_ape.h header-y += msm_audio_g711.h header-y += msm_audio_g711_dec.h header-y += mfd/ +header-y += wcd-spi-ac-params.h diff --git a/include/uapi/linux/wcd-spi-ac-params.h b/include/uapi/linux/wcd-spi-ac-params.h new file mode 100644 index 000000000000..e397bf215ab8 --- /dev/null +++ b/include/uapi/linux/wcd-spi-ac-params.h @@ -0,0 +1,52 @@ +#ifndef __UAPI_WCD_SPI_AC_PARAMS_H__ +#define __UAPI_WCD_SPI_AC_PARAMS_H__ + +#include + +#define WCD_SPI_AC_CMD_CONC_BEGIN 0x01 +#define WCD_SPI_AC_CMD_CONC_END 0x02 +#define WCD_SPI_AC_CMD_BUF_DATA 0x03 + +#define WCD_SPI_AC_MAX_BUFFERS 2 +#define WCD_SPI_AC_MAX_CH_PER_BUF 8 + +#define WCD_SPI_AC_CLIENT_CDEV_NAME "wcd-spi-ac-client" +#define WCD_SPI_AC_PROCFS_DIR_NAME "wcd-spi-ac" +#define WCD_SPI_AC_PROCFS_STATE_NAME "svc-state" + +/* + * wcd_spi_ac_buf_data: + * Buffer address for one buffer. Should have data + * for all the channels. If channels are unused, the + * value must be NULL. + * + * @addr: + * Address where each channel of the buffer starts. + */ +struct wcd_spi_ac_buf_data { + __u32 addr[WCD_SPI_AC_MAX_CH_PER_BUF]; +} __packed; + +/* + * wcd_spi_ac_write_cmd: + * Data sent to the driver's write interface should + * be packed in this format. + * + * @cmd_type: + * Indicates the type of command that is sent. Should + * be one of the valid commands defined with + * WCD_SPI_AC_CMD_* + * @payload: + * No payload for: + * WCD_SPI_AC_CMD_CONC_BEGIN + * WCD_SPI_AC_CMD_CONC_END + * Upto WCD_SPI_AC_MAX_BUFFERS of type + * struct wcd_spi_ac_buf_data for: + * WCD_SPI_AC_CMD_BUF_DATA + */ +struct wcd_spi_ac_write_cmd { + __u32 cmd_type; + __u8 payload[0]; +} __packed; + +#endif /* end of __UAPI_WCD_SPI_AC_PARAMS_H__ */ -- GitLab From be0391da6c89f86018e4fd73fee368627079d891 Mon Sep 17 00:00:00 2001 From: Tanya Dixit Date: Wed, 6 Feb 2019 13:47:17 +0530 Subject: [PATCH 0862/1645] dsp: q6voice: Check size of payload before access Check size of payload array before access in qdsp_cvp_callback. Change-Id: Ic5ea6686a1a09df75ddd5e6fdcdfbd74efff83d8 Signed-off-by: Tanya Dixit --- dsp/q6voice.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index bb2bbdfa2992..3e2460aa8b8b 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -7908,7 +7908,7 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv) } if (data->opcode == APR_BASIC_RSP_RESULT) { - if (data->payload_size) { + if (data->payload_size >= (2 * sizeof(uint32_t))) { ptr = data->payload; pr_debug("%x %x\n", ptr[0], ptr[1]); -- GitLab From f74e89bd893194cbdf5c96a912e14def6bb96895 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Mon, 8 Jan 2018 18:09:29 -0800 Subject: [PATCH 0863/1645] asoc: avoid excessive logging Excessive logging by pr_err() could cause audio thread to stuck in the printing session which results PD down notification timeout. This eventually can cause ADSP PDR failure. Fix this issue by using pr_err_ratelimited and dev_err_ratelimited to limit the number of error messages during the ADSP PDR. Change-Id: I68b617fef53ebd03ba79fd919bffd8c35e6eb048 Signed-off-by: Xiaoyu Ye --- asoc/msm-compress-q6-v2.c | 4 +--- dsp/q6asm.c | 9 +++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index be10bc1690fc..e741c2ddb33c 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -2788,12 +2788,10 @@ static int msm_compr_pointer(struct snd_compr_stream *cstream, rc = q6asm_get_session_time( prtd->audio_client, &prtd->marker_timestamp); if (rc < 0) { - pr_err("%s: Get Session Time return =%lld\n", - __func__, timestamp); if (atomic_read(&prtd->error)) return -ENETRESET; else - return -EAGAIN; + return rc; } } } else { diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 934fc580affb..948fc626314c 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -9644,16 +9644,17 @@ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) ac->session, mtmx_params.hdr.opcode); rc = apr_send_pkt(ac->apr, (uint32_t *) &mtmx_params); if (rc < 0) { - pr_err("%s: Commmand 0x%x failed %d\n", __func__, - mtmx_params.hdr.opcode, rc); - goto fail_cmd; + dev_err_ratelimited(ac->dev, "%s: Get Session Time failed %d\n", + __func__, rc); + return rc; } + rc = wait_event_timeout(ac->time_wait, (atomic_read(&ac->time_flag) == 0), msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout in getting session time from DSP\n", - __func__); + __func__); goto fail_cmd; } -- GitLab From 3c95e9c53bed2153e11d6dcb2b48131f3eb5cce3 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Tue, 26 Feb 2019 16:51:30 +0530 Subject: [PATCH 0864/1645] asoc: sa8155: support SSR handling for snd card status Add support for handling snd card status upon SERVICE_DOWN and SERVICE_UP callback for ADSP SSR. Change-Id: Ie753a0edc59ca10da8d9c23f9e6c7c6244a8e8a6 Signed-off-by: Rahul Sharma --- asoc/sa8155.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/asoc/sa8155.c b/asoc/sa8155.c index fedb793ec895..ec1c0d8752bc 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -691,6 +691,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); static bool is_initial_boot = true; +static struct platform_device *spdev; static struct afe_clk_set mi2s_clk[MI2S_MAX] = { { @@ -7099,6 +7100,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) goto err; } dev_info(&pdev->dev, "Sound card %s registered\n", card->name); + spdev = pdev; /* Parse pinctrl info from devicetree */ ret = msm_get_pinctrl(pdev); @@ -7165,10 +7167,22 @@ static struct platform_driver sa8155_dummy_asoc_machine_driver = { static int sa8155_notifier_service_cb(struct notifier_block *this, unsigned long opcode, void *ptr) { + struct snd_soc_card *card = NULL; + pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); switch (opcode) { case AUDIO_NOTIFIER_SERVICE_DOWN: + if (!spdev) + return -EINVAL; + card = platform_get_drvdata(spdev); + if (card == NULL){ + pr_err("%s: card is NULL\n",__func__); + return -EINVAL; + } else { + pr_debug("%s: setting snd_card to OFFLINE\n", __func__); + snd_soc_card_change_online_state(card, 0); + } break; case AUDIO_NOTIFIER_SERVICE_UP: if (is_initial_boot) { @@ -7176,11 +7190,20 @@ static int sa8155_notifier_service_cb(struct notifier_block *this, platform_device_register(&sa8155_dummy_asoc_machine_device); is_initial_boot = false; } + if (!spdev) + return -EINVAL; + card = platform_get_drvdata(spdev); + if (card == NULL){ + pr_err("%s: card is NULL\n",__func__); + return -EINVAL; + } else { + pr_debug("%s: setting snd_card to ONLINE\n", __func__); + snd_soc_card_change_online_state(card, 1); + } break; default: break; } - return NOTIFY_OK; } -- GitLab From 609be4509a798d884a062e309da1289197417630 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Mon, 4 Mar 2019 17:01:20 -0800 Subject: [PATCH 0865/1645] ASoC: msm: add machine drv as apr child node Automotive machine driver is a child node of apr so it will be re-probed upon ADSP UP event received in APR driver during boot up. Remove the dummy machine driver solution. Change-Id: I9ac3e26366a5b01869183e8b83e47049ec770c7c Signed-off-by: Derek Chen --- asoc/sa8155.c | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/asoc/sa8155.c b/asoc/sa8155.c index ec1c0d8752bc..dba116b5f417 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -7141,29 +7141,6 @@ static struct platform_driver sa8155_asoc_machine_driver = { .remove = msm_asoc_machine_remove, }; -static int dummy_asoc_machine_probe(struct platform_device *pdev) -{ - return 0; -} - -static int dummy_asoc_machine_remove(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_device sa8155_dummy_asoc_machine_device = { - .name = "sa8155-asoc-snd-dummy", -}; - -static struct platform_driver sa8155_dummy_asoc_machine_driver = { - .driver = { - .name = "sa8155-asoc-snd-dummy", - .owner = THIS_MODULE, - }, - .probe = dummy_asoc_machine_probe, - .remove = dummy_asoc_machine_remove, -}; - static int sa8155_notifier_service_cb(struct notifier_block *this, unsigned long opcode, void *ptr) { @@ -7186,9 +7163,8 @@ static int sa8155_notifier_service_cb(struct notifier_block *this, break; case AUDIO_NOTIFIER_SERVICE_UP: if (is_initial_boot) { - platform_driver_register(&sa8155_dummy_asoc_machine_driver); - platform_device_register(&sa8155_dummy_asoc_machine_device); is_initial_boot = false; + break; } if (!spdev) return -EINVAL; -- GitLab From 4728d6b2b5e591c86ae160a3edc86a14a76a645a Mon Sep 17 00:00:00 2001 From: Haynes Mathew George Date: Fri, 8 Jun 2018 17:26:24 -0700 Subject: [PATCH 0866/1645] asoc: Reorder list used in topology search Routing driver searches CAL_TYPE list for a matching topology and then searches the LSM_CAL_TYPE list if no entry is found in the first list. If it so happens that a capture type cal block is present in the CAL_TYPE list, it will be picked even though the correct entry is present in the LSM_CAL_TYPE list. Flip the order to give priority to LSM_CAL_TYPE list. We expect only LSM clients to populate this list and also enforce exact match for LSM clients. CRs-Fixed: 2250684 Change-Id: I2ab3481b43a5d8b059a20cb919ff097fc8cf2774 Signed-off-by: Haynes Mathew George --- asoc/msm-pcm-routing-v2.c | 69 +++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index dc403a5899aa..21368929d3a0 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1113,7 +1113,8 @@ static struct cal_block_data *msm_routing_find_topology_by_path(int path, static struct cal_block_data *msm_routing_find_topology(int path, int app_type, int acdb_id, - int cal_index) + int cal_index, + bool exact) { struct list_head *ptr, *next; struct cal_block_data *cal_block = NULL; @@ -1138,9 +1139,29 @@ static struct cal_block_data *msm_routing_find_topology(int path, return cal_block; } } - pr_debug("%s: Can't find topology for path %d, app %d, acdb_id %d defaulting to search by path\n", - __func__, path, app_type, acdb_id); - return msm_routing_find_topology_by_path(path, cal_index); + pr_debug("%s: Can't find topology for path %d, app %d, " + "acdb_id %d %s\n", __func__, path, app_type, acdb_id, + exact ? "fail" : "defaulting to search by path"); + return exact ? NULL : msm_routing_find_topology_by_path(path, + cal_index); +} + +static int msm_routing_find_topology_on_index(int session_type, int app_type, + int acdb_dev_id, int idx, + bool exact) +{ + int topology = -EINVAL; + struct cal_block_data *cal_block = NULL; + + mutex_lock(&cal_data[idx]->lock); + cal_block = msm_routing_find_topology(session_type, app_type, + acdb_dev_id, idx, exact); + if (cal_block != NULL) { + topology = ((struct audio_cal_info_adm_top *) + cal_block->cal_info)->topology; + } + mutex_unlock(&cal_data[idx]->lock); + return topology; } /* @@ -1152,7 +1173,6 @@ static int msm_routing_get_adm_topology(int fedai_id, int session_type, int be_id) { int topology = NULL_COPP_TOPOLOGY; - struct cal_block_data *cal_block = NULL; int app_type = 0, acdb_dev_id = 0; pr_debug("%s: fedai_id %d, session_type %d, be_id %d\n", @@ -1165,31 +1185,22 @@ static int msm_routing_get_adm_topology(int fedai_id, int session_type, acdb_dev_id = fe_dai_app_type_cfg[fedai_id][session_type][be_id].acdb_dev_id; - mutex_lock(&cal_data[ADM_TOPOLOGY_CAL_TYPE_IDX]->lock); - cal_block = msm_routing_find_topology(session_type, app_type, - acdb_dev_id, - ADM_TOPOLOGY_CAL_TYPE_IDX); - if (cal_block != NULL) { - topology = ((struct audio_cal_info_adm_top *) - cal_block->cal_info)->topology; - cal_utils_mark_cal_used(cal_block); - mutex_unlock(&cal_data[ADM_TOPOLOGY_CAL_TYPE_IDX]->lock); - } else { - mutex_unlock(&cal_data[ADM_TOPOLOGY_CAL_TYPE_IDX]->lock); - - pr_debug("%s: Check for LSM topology\n", __func__); - mutex_lock(&cal_data[ADM_LSM_TOPOLOGY_CAL_TYPE_IDX]->lock); - cal_block = msm_routing_find_topology(session_type, app_type, - acdb_dev_id, - ADM_LSM_TOPOLOGY_CAL_TYPE_IDX); - if (cal_block != NULL) { - topology = ((struct audio_cal_info_adm_top *) - cal_block->cal_info)->topology; - cal_utils_mark_cal_used(cal_block); - } - mutex_unlock(&cal_data[ADM_LSM_TOPOLOGY_CAL_TYPE_IDX]->lock); + pr_debug("%s: Check for exact LSM topology\n", __func__); + topology = msm_routing_find_topology_on_index(session_type, + app_type, + acdb_dev_id, + ADM_LSM_TOPOLOGY_CAL_TYPE_IDX, + true /*exact*/); + if (topology < 0) { + pr_debug("%s: Check for compatible topology\n", __func__); + topology = msm_routing_find_topology_on_index(session_type, + app_type, + acdb_dev_id, + ADM_TOPOLOGY_CAL_TYPE_IDX, + false /*exact*/); + if (topology < 0) + topology = NULL_COPP_TOPOLOGY; } - done: pr_debug("%s: Using topology %d\n", __func__, topology); return topology; -- GitLab From 0714ffdfcbb548a16e7e814faa7af59767c45d5f Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 5 Mar 2019 15:52:15 +0530 Subject: [PATCH 0867/1645] dsp: q6voice: Check size of shared memory buffer before access Check buffer size in qdsp_cvs_callback before access in ul_pkt. Change-Id: Ic19994b46086709231656ec747d2df988b7a512f Signed-off-by: Vatsal Bucha --- dsp/q6voice.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index bb2bbdfa2992..e1d465edebf8 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -7740,6 +7740,11 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv) cvs_voc_pkt = v->shmem_info.sh_buf.buf[1].data; if (cvs_voc_pkt != NULL && common.mvs_info.ul_cb != NULL) { + if (v->shmem_info.sh_buf.buf[1].size < + ((3 * sizeof(uint32_t)) + cvs_voc_pkt[2])) { + pr_err("%s: invalid voc pkt size\n", __func__); + return -EINVAL; + } /* cvs_voc_pkt[0] contains tx timestamp */ common.mvs_info.ul_cb((uint8_t *)&cvs_voc_pkt[3], cvs_voc_pkt[2], -- GitLab From 89cc889a4404eea6f11e856f456d6e4f679a0d40 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Tue, 29 May 2018 17:03:55 -0700 Subject: [PATCH 0868/1645] asoc: wcd-spi: use CMA memory for TX and RX buffer instead of kzalloc In wcd-spi driver, the kzalloc is used to allocate memory for TX and RX buffer. Those allocations are order4 or order5, which could fail on some kernels. To avoid potential memory allocation failure, the CMA region is used for those allocations by dma_alloc_coherent API. Change-Id: I0a4d6c6b5e0e47f96187563272e63c3a006e469f Signed-off-by: Xiaoyu Ye --- asoc/codecs/wcd-spi.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/asoc/codecs/wcd-spi.c b/asoc/codecs/wcd-spi.c index 35b0d93b468a..145c4df69055 100644 --- a/asoc/codecs/wcd-spi.c +++ b/asoc/codecs/wcd-spi.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ #include @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -152,6 +153,10 @@ struct wcd_spi_priv { /* Buffers to hold memory used for transfers */ void *tx_buf; void *rx_buf; + + /* DMA handles for transfer buffers */ + dma_addr_t tx_dma; + dma_addr_t rx_dma; }; enum xfer_request { @@ -1371,17 +1376,20 @@ static int wcd_spi_component_bind(struct device *dev, spi_message_add_tail(&wcd_spi->xfer2[1], &wcd_spi->msg2); /* Pre-allocate the buffers */ - wcd_spi->tx_buf = kzalloc(WCD_SPI_RW_MAX_BUF_SIZE, - GFP_KERNEL | GFP_DMA); + wcd_spi->tx_buf = dma_zalloc_coherent(&spi->dev, + WCD_SPI_RW_MAX_BUF_SIZE, + &wcd_spi->tx_dma, GFP_KERNEL); if (!wcd_spi->tx_buf) { ret = -ENOMEM; goto done; } - wcd_spi->rx_buf = kzalloc(WCD_SPI_RW_MAX_BUF_SIZE, - GFP_KERNEL | GFP_DMA); + wcd_spi->rx_buf = dma_zalloc_coherent(&spi->dev, + WCD_SPI_RW_MAX_BUF_SIZE, + &wcd_spi->rx_dma, GFP_KERNEL); if (!wcd_spi->rx_buf) { - kfree(wcd_spi->tx_buf); + dma_free_coherent(&spi->dev, WCD_SPI_RW_MAX_BUF_SIZE, + wcd_spi->tx_buf, wcd_spi->tx_dma); wcd_spi->tx_buf = NULL; ret = -ENOMEM; goto done; @@ -1408,8 +1416,10 @@ static void wcd_spi_component_unbind(struct device *dev, spi_transfer_del(&wcd_spi->xfer2[0]); spi_transfer_del(&wcd_spi->xfer2[1]); - kfree(wcd_spi->tx_buf); - kfree(wcd_spi->rx_buf); + dma_free_coherent(&spi->dev, WCD_SPI_RW_MAX_BUF_SIZE, + wcd_spi->tx_buf, wcd_spi->tx_dma); + dma_free_coherent(&spi->dev, WCD_SPI_RW_MAX_BUF_SIZE, + wcd_spi->rx_buf, wcd_spi->rx_dma); wcd_spi->tx_buf = NULL; wcd_spi->rx_buf = NULL; } @@ -1445,6 +1455,7 @@ static int wcd_spi_probe(struct spi_device *spi) mutex_init(&wcd_spi->xfer_mutex); INIT_DELAYED_WORK(&wcd_spi->clk_dwork, wcd_spi_clk_work); init_completion(&wcd_spi->resume_comp); + arch_setup_dma_ops(&spi->dev, 0, 0, NULL, true); wcd_spi->spi = spi; spi_set_drvdata(spi, wcd_spi); -- GitLab From 22ff651406662650662ef49f53ac8e677d0e3ce5 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 13 Mar 2019 16:05:14 +0800 Subject: [PATCH 0869/1645] asoc: uapi: Update LOCAL_ADDITIONAL_DEPENDENCIES Update LOCAL_ADDITIONAL_DEPENDENCIES to fix kernel header build dependency. Change-Id: I3eeb3b9e9e021b16b50d26851e284a843132eff7 Signed-off-by: Meng Wang --- include/uapi/Android.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/Android.mk b/include/uapi/Android.mk index b8c209adaa0e..f19a6c20337e 100644 --- a/include/uapi/Android.mk +++ b/include/uapi/Android.mk @@ -15,6 +15,7 @@ BUILD_ROOT_RELATIVE := ../../../../../../../ include $(CLEAR_VARS) LOCAL_MODULE := audio_kernel_headers LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_PREBUILT_INT_KERNEL) +LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr GEN := $(addprefix $(UAPI_OUT)/,$(AUDIO_KERNEL_HEADERS)) $(GEN): $(KERNEL_USR) -- GitLab From 3557d14ce8855d049b92f01fe919089a2d8977e6 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 13 Mar 2019 07:12:44 +0530 Subject: [PATCH 0870/1645] ASoC: wcd938x: Update routing for HDR recording Update audio routings for HDR recording on WCD938x codec for AMIC1 and AMIC5 paths. Change-Id: I67b93fe11c7a5b16ffd4bb8b58431be9dfba615e Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd938x/wcd938x.c | 89 +++++++++++++---------------------- 1 file changed, 32 insertions(+), 57 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 8a5622fe8811..fbc745ac3ae5 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1741,55 +1741,6 @@ static int wcd938x_set_compander(struct snd_kcontrol *kcontrol, return 0; } -static int wcd938x_tx_hdr_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = - snd_soc_kcontrol_component(kcontrol); - struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); - int hdr = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - - ucontrol->value.integer.value[0] = wcd938x->hdr_en[hdr]; - - return 0; -} - -static int wcd938x_tx_hdr_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = - snd_soc_kcontrol_component(kcontrol); - struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); - int hdr = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - int val = ucontrol->value.integer.value[0]; - u8 mask = 0; - - wcd938x->hdr_en[hdr] = val; - - switch(val) { - case TX_HDR12: - mask = (1 << 4); - val = (val << 4); - break; - case TX_HDR34: - mask = (1 << 3); - val = (val << 3); - break; - default: - dev_err(component->dev, "%s: unknown HDR input: %d\n", - __func__, hdr); - break; - } - - if (mask) - snd_soc_component_update_bits(component, - WCD938X_TX_NEW_AMIC_MUX_CFG, mask, val); - - return 0; -} - static const char * const tx_mode_mux_text[] = { "ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP", "ADC_ULP1", "ADC_ULP2", @@ -1826,12 +1777,6 @@ static const struct snd_kcontrol_new wcd938x_snd_controls[] = { SOC_SINGLE_EXT("HPHR_COMP Switch", SND_SOC_NOPM, 1, 1, 0, wcd938x_get_compander, wcd938x_set_compander), - SOC_SINGLE_EXT("TX HDR12", SND_SOC_NOPM, TX_HDR12, 1, 0, - wcd938x_tx_hdr_get, wcd938x_tx_hdr_put), - - SOC_SINGLE_EXT("TX HDR34", SND_SOC_NOPM, TX_HDR34, 1, 0, - wcd938x_tx_hdr_get, wcd938x_tx_hdr_put), - SOC_SINGLE_TLV("HPHL Volume", WCD938X_HPH_L_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("HPHR Volume", WCD938X_HPH_R_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("ADC1 Volume", WCD938X_ANA_TX_CH1, 0, 20, 0, @@ -1945,6 +1890,28 @@ static const char * const rdac3_mux_text[] = { "RX1", "RX3" }; +static const char * const hdr12_mux_text[] = { + "NO_HDR12", "HDR12" +}; + +static const struct soc_enum hdr12_enum = + SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 4, + ARRAY_SIZE(hdr12_mux_text), hdr12_mux_text); + +static const struct snd_kcontrol_new tx_hdr12_mux = + SOC_DAPM_ENUM("HDR12 MUX Mux", hdr12_enum); + +static const char * const hdr34_mux_text[] = { + "NO_HDR34", "HDR34" +}; + +static const struct soc_enum hdr34_enum = + SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 3, + ARRAY_SIZE(hdr34_mux_text), hdr34_mux_text); + +static const struct snd_kcontrol_new tx_hdr34_mux = + SOC_DAPM_ENUM("HDR34 MUX Mux", hdr34_enum); + static const struct soc_enum rdac3_enum = SOC_ENUM_SINGLE(WCD938X_DIGITAL_CDC_EAR_PATH_CTL, 0, ARRAY_SIZE(rdac3_mux_text), rdac3_mux_text); @@ -2023,6 +1990,10 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = { &tx_adc3_mux), SND_SOC_DAPM_MUX("ADC4 MUX", SND_SOC_NOPM, 0, 0, &tx_adc4_mux), + SND_SOC_DAPM_MUX("HDR12 MUX", SND_SOC_NOPM, 0, 0, + &tx_hdr12_mux), + SND_SOC_DAPM_MUX("HDR34 MUX", SND_SOC_NOPM, 0, 0, + &tx_hdr34_mux), /*tx mixers*/ SND_SOC_DAPM_MIXER_E("ADC1_MIXER", SND_SOC_NOPM, 0, 0, adc1_switch, ARRAY_SIZE(adc1_switch), @@ -2181,14 +2152,18 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = { {"ADC2_OUTPUT", NULL, "ADC2_MIXER"}, {"ADC2_MIXER", "Switch", "ADC2 REQ"}, {"ADC2 REQ", NULL, "ADC2"}, - {"ADC2", NULL, "ADC2 MUX"}, + {"ADC2", NULL, "HDR12 MUX"}, + {"HDR12 MUX", "NO_HDR12", "ADC2 MUX"}, + {"HDR12 MUX", "HDR12", "AMIC1"}, {"ADC2 MUX", "INP3", "AMIC3"}, {"ADC2 MUX", "INP2", "AMIC2"}, {"ADC3_OUTPUT", NULL, "ADC3_MIXER"}, {"ADC3_MIXER", "Switch", "ADC3 REQ"}, {"ADC3 REQ", NULL, "ADC3"}, - {"ADC3", NULL, "ADC3 MUX"}, + {"ADC3", NULL, "HDR34 MUX"}, + {"HDR34 MUX", "NO_HDR34", "ADC3 MUX"}, + {"HDR34 MUX", "HDR34", "AMIC5"}, {"ADC3 MUX", "INP4", "AMIC4"}, {"ADC3 MUX", "INP6", "AMIC6"}, -- GitLab From a6ecf498c184fe2dc8701fd069e37acb6ce264e2 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 20 Feb 2019 14:56:50 +0530 Subject: [PATCH 0871/1645] audio: uapi: Update v-validation get and set params Add v-validation feature support for set config for wait time and validation time and get param for status/vrms result of speaker. Change-Id: I1bd91fbe17113a21c881e1ec1c735c50a963a692 Signed-off-by: Laxminath Kasam --- include/uapi/linux/msm_audio_calibration.h | 66 +++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h index 9bd64aac8b53..35b596062247 100644 --- a/include/uapi/linux/msm_audio_calibration.h +++ b/include/uapi/linux/msm_audio_calibration.h @@ -294,9 +294,11 @@ enum msm_spkr_prot_states { MSM_SPKR_PROT_DISABLED, MSM_SPKR_PROT_NOT_CALIBRATED, MSM_SPKR_PROT_PRE_CALIBRATED, - MSM_SPKR_PROT_IN_FTM_MODE + MSM_SPKR_PROT_IN_FTM_MODE, + MSM_SPKR_PROT_IN_V_VALI_MODE }; #define MSM_SPKR_PROT_IN_FTM_MODE MSM_SPKR_PROT_IN_FTM_MODE +#define MSM_SPKR_PROT_IN_V_VALI_MODE MSM_SPKR_PROT_IN_V_VALI_MODE enum msm_spkr_count { SP_V2_SPKR_1, @@ -321,14 +323,37 @@ struct audio_cal_info_spk_prot_cfg { }; struct audio_cal_info_sp_th_vi_ftm_cfg { + /* + * mode should be first param, add new params later to this. + * we use this mode(first 4 bytes) to differentiate + * whether it is TH_VI FTM or v-validation. + */ + uint32_t mode; + /* + * 0 - normal running mode + * 1 - Calibration + * 2 - FTM mode + */ uint32_t wait_time[SP_V2_NUM_MAX_SPKRS]; uint32_t ftm_time[SP_V2_NUM_MAX_SPKRS]; +}; + +struct audio_cal_info_sp_th_vi_v_vali_cfg { + /* + * mode should be first param, add new params later to this. + * we use this mode(first 4 bytes) to differentiate + * whether it is TH_VI FTM or v-validation. + */ uint32_t mode; /* * 0 - normal running mode * 1 - Calibration * 2 - FTM mode + * 3 - V-Validation mode */ + uint32_t wait_time[SP_V2_NUM_MAX_SPKRS]; + uint32_t vali_time[SP_V2_NUM_MAX_SPKRS]; + }; struct audio_cal_info_sp_ex_vi_ftm_cfg { @@ -349,11 +374,28 @@ struct audio_cal_info_sp_ex_vi_param { }; struct audio_cal_info_sp_th_vi_param { + /* + * mode should be first param, add new params later to this. + * we use this mode(first 4 bytes) to differentiate + * whether it is TH_VI FTM or v-validation. + */ + uint32_t mode; int32_t r_dc_q24[SP_V2_NUM_MAX_SPKRS]; int32_t temp_q22[SP_V2_NUM_MAX_SPKRS]; int32_t status[SP_V2_NUM_MAX_SPKRS]; }; +struct audio_cal_info_sp_th_vi_v_vali_param { + /* + * mode should be first param, add new params later to this. + * we use this mode(first 4 bytes) to differentiate + * whether it is TH_VI FTM or v-validation. + */ + uint32_t mode; + uint32_t vrms_q24[SP_V2_NUM_MAX_SPKRS]; + int32_t status[SP_V2_NUM_MAX_SPKRS]; +}; + struct audio_cal_info_msm_spk_prot_status { int32_t r0[SP_V2_NUM_MAX_SPKRS]; int32_t status; @@ -589,6 +631,17 @@ struct audio_cal_sp_th_vi_ftm_cfg { struct audio_cal_type_sp_th_vi_ftm_cfg cal_type; }; +struct audio_cal_type_sp_th_vi_v_vali_cfg { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_sp_th_vi_v_vali_cfg cal_info; +}; + +struct audio_cal_sp_th_vi_v_vali_cfg { + struct audio_cal_header hdr; + struct audio_cal_type_sp_th_vi_v_vali_cfg cal_type; +}; + struct audio_cal_type_sp_ex_vi_ftm_cfg { struct audio_cal_type_header cal_hdr; struct audio_cal_data cal_data; @@ -731,6 +784,17 @@ struct audio_cal_sp_th_vi_param { struct audio_cal_header hdr; struct audio_cal_type_sp_th_vi_param cal_type; }; + +struct audio_cal_type_sp_th_vi_v_vali_param { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_sp_th_vi_v_vali_param cal_info; +}; + +struct audio_cal_sp_th_vi_v_vali_param { + struct audio_cal_header hdr; + struct audio_cal_type_sp_th_vi_v_vali_param cal_type; +}; struct audio_cal_type_sp_ex_vi_param { struct audio_cal_type_header cal_hdr; struct audio_cal_data cal_data; -- GitLab From 2e13d955062bbabf7cddc65554909441da7137a1 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 20 Feb 2019 15:05:39 +0530 Subject: [PATCH 0872/1645] dsp: q6afe: Add v-validation support for speaker With speaker protection in v-validation mode, speaker samples can be tested in early factory mode. Add support for v-validation feature from driver. Change-Id: I92493d6d2784cf4dd58021746bffe01180f89d23 Signed-off-by: Laxminath Kasam --- dsp/audio_cal_utils.c | 8 +- dsp/q6afe.c | 198 ++++++++++++++++++++++++++++++++++--- include/dsp/apr_audio-v2.h | 48 +++++++++ 3 files changed, 240 insertions(+), 14 deletions(-) diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index 19c71fc55208..7e243e88609b 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -16,6 +16,7 @@ static int unmap_memory(struct cal_type_data *cal_type, size_t get_cal_info_size(int32_t cal_type) { size_t size = 0; + size_t size1 = 0, size2 = 0; switch (cal_type) { case CVP_VOC_RX_TOPOLOGY_CAL_TYPE: @@ -93,8 +94,11 @@ size_t get_cal_info_size(int32_t cal_type) * Since get and set parameter structures are different in size * use the maximum size of get and set parameter structure */ - size = max(sizeof(struct audio_cal_info_sp_th_vi_ftm_cfg), + size1 = max(sizeof(struct audio_cal_info_sp_th_vi_ftm_cfg), sizeof(struct audio_cal_info_sp_th_vi_param)); + size2 = max(sizeof(struct audio_cal_info_sp_th_vi_v_vali_cfg), + sizeof(struct audio_cal_info_sp_th_vi_v_vali_param)); + size = max(size1, size2); break; case AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE: /* diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 62d4851f00ac..5000b9f46477 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -59,6 +59,16 @@ static char fbsp_state[MAX_FBSP_STATE][50] = { [FBSP_FAILED] = "failed" }; +enum v_vali_state { + V_VALI_FAILED, + V_VALI_SUCCESS, + V_VALI_INCORRECT_OP_MODE, + V_VALI_INACTIVE, + V_VALI_WARMUP, + V_VALI_IN_PROGRESS, + MAX_V_VALI_STATE +}; + enum { USE_CALIBRATED_R0TO, USE_SAFE_R0TO @@ -72,7 +82,8 @@ enum { enum { Q6AFE_MSM_SPKR_PROCESSING = 0, Q6AFE_MSM_SPKR_CALIBRATION, - Q6AFE_MSM_SPKR_FTM_MODE + Q6AFE_MSM_SPKR_FTM_MODE, + Q6AFE_MSM_SPKR_V_VALI_MODE }; enum { @@ -124,8 +135,10 @@ struct afe_ctl { struct audio_cal_info_spk_prot_cfg prot_cfg; struct afe_spkr_prot_calib_get_resp calib_data; struct audio_cal_info_sp_th_vi_ftm_cfg th_ftm_cfg; + struct audio_cal_info_sp_th_vi_v_vali_cfg v_vali_cfg; struct audio_cal_info_sp_ex_vi_ftm_cfg ex_ftm_cfg; struct afe_sp_th_vi_get_param_resp th_vi_resp; + struct afe_sp_th_vi_v_vali_get_param_resp th_vi_v_vali_resp; struct afe_sp_ex_vi_get_param_resp ex_vi_resp; struct afe_av_dev_drift_get_param_resp av_dev_drift_resp; struct afe_doa_tracking_mon_get_param_resp doa_tracking_mon_resp; @@ -364,6 +377,10 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, expected_size += sizeof(struct afe_sp_th_vi_ftm_params); data_dest = (u32 *) &this_afe.th_vi_resp; break; + case AFE_PARAM_ID_SP_V2_TH_VI_V_VALI_PARAMS: + expected_size += sizeof(struct afe_sp_th_vi_v_vali_params); + data_dest = (u32 *) &this_afe.th_vi_v_vali_resp; + break; case AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS: expected_size += sizeof(struct afe_sp_ex_vi_ftm_params); data_dest = (u32 *) &this_afe.ex_vi_resp; @@ -1606,10 +1623,12 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, break; /* * AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2 is same as - * AFE_PARAM_ID_SP_V2_TH_VI_MODE_CFG + * AFE_PARAM_ID_SP_V2_TH_VI_MODE_CFG. V_VALI_CFG uses + * same module TH_VI. */ case AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2: case AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG: + case AFE_PARAM_ID_SP_V2_TH_VI_V_VALI_CFG: param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; break; case AFE_PARAM_ID_SP_V2_EX_VI_MODE_CFG: @@ -1737,6 +1756,10 @@ static void afe_send_cal_spkr_prot_tx(int port_id) if (this_afe.th_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) afe_spk_config.vi_proc_cfg.operation_mode = Q6AFE_MSM_SPKR_FTM_MODE; + else if (this_afe.v_vali_cfg.mode == + MSM_SPKR_PROT_IN_V_VALI_MODE) + afe_spk_config.vi_proc_cfg.operation_mode = + Q6AFE_MSM_SPKR_V_VALI_MODE; afe_spk_config.vi_proc_cfg.minor_version = 1; afe_spk_config.vi_proc_cfg.r0_cali_q24[SP_V2_SPKR_1] = (uint32_t) this_afe.prot_cfg.r0[SP_V2_SPKR_1]; @@ -1789,6 +1812,25 @@ static void afe_send_cal_spkr_prot_tx(int port_id) &afe_spk_config)) pr_err("%s: th vi ftm cfg failed\n", __func__); this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; + } else if ((this_afe.v_vali_cfg.mode == + MSM_SPKR_PROT_IN_V_VALI_MODE) && + (this_afe.vi_tx_port == port_id)) { + afe_spk_config.th_vi_v_vali_cfg.minor_version = 1; + afe_spk_config.th_vi_v_vali_cfg.wait_time_ms[SP_V2_SPKR_1] = + this_afe.v_vali_cfg.wait_time[SP_V2_SPKR_1]; + afe_spk_config.th_vi_v_vali_cfg.wait_time_ms[SP_V2_SPKR_2] = + this_afe.v_vali_cfg.wait_time[SP_V2_SPKR_2]; + afe_spk_config.th_vi_v_vali_cfg.vali_time_ms[SP_V2_SPKR_1] = + this_afe.v_vali_cfg.vali_time[SP_V2_SPKR_1]; + afe_spk_config.th_vi_v_vali_cfg.vali_time_ms[SP_V2_SPKR_2] = + this_afe.v_vali_cfg.vali_time[SP_V2_SPKR_2]; + + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V2_TH_VI_V_VALI_CFG, + &afe_spk_config)) + pr_err("%s: th vi v-vali cfg failed\n", __func__); + + this_afe.v_vali_cfg.mode = MSM_SPKR_PROT_DISABLED; } mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); @@ -7453,6 +7495,46 @@ int q6afe_check_osr_clk_freq(u32 freq) } EXPORT_SYMBOL(q6afe_check_osr_clk_freq); +static int afe_get_sp_th_vi_v_vali_data( + struct afe_sp_th_vi_v_vali_get_param *th_vi_v_vali) +{ + struct param_hdr_v3 param_hdr; + int port = SLIMBUS_4_TX; + int ret = -EINVAL; + + if (!th_vi_v_vali) { + pr_err("%s: Invalid params\n", __func__); + goto done; + } + if (this_afe.vi_tx_port != -1) + port = this_afe.vi_tx_port; + + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_V2_TH_VI_V_VALI_PARAMS; + param_hdr.param_size = sizeof(struct afe_sp_th_vi_v_vali_params); + + ret = q6afe_get_params(port, NULL, ¶m_hdr); + if (ret) { + pr_err("%s: Failed to get TH VI V-Vali data\n", __func__); + goto done; + } + + th_vi_v_vali->pdata = param_hdr; + memcpy(&th_vi_v_vali->param, &this_afe.th_vi_v_vali_resp.param, + sizeof(this_afe.th_vi_v_vali_resp.param)); + pr_debug("%s: Vrms %d %d status %d %d\n", __func__, + th_vi_v_vali->param.vrms_q24[SP_V2_SPKR_1], + th_vi_v_vali->param.vrms_q24[SP_V2_SPKR_2], + th_vi_v_vali->param.status[SP_V2_SPKR_1], + th_vi_v_vali->param.status[SP_V2_SPKR_2]); + ret = 0; +done: + return ret; +} + int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) { struct param_hdr_v3 param_hdr; @@ -7952,21 +8034,57 @@ static int afe_get_cal_hw_delay(int32_t path, return ret; } +static int afe_set_cal_sp_th_vi_v_vali_cfg(int32_t cal_type, size_t data_size, + void *data) +{ + int ret = 0; + struct audio_cal_type_sp_th_vi_v_vali_cfg *cal_data = data; + + if (cal_data == NULL || data_size != sizeof(*cal_data)) + goto done; + + memcpy(&this_afe.v_vali_cfg, &cal_data->cal_info, + sizeof(this_afe.v_vali_cfg)); +done: + return ret; +} + static int afe_set_cal_sp_th_vi_ftm_cfg(int32_t cal_type, size_t data_size, void *data) { int ret = 0; struct audio_cal_type_sp_th_vi_ftm_cfg *cal_data = data; - if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL || - cal_data == NULL || - data_size != sizeof(*cal_data)) + if (cal_data == NULL || data_size != sizeof(*cal_data)) goto done; - pr_debug("%s: cal_type = %d\n", __func__, cal_type); - mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); memcpy(&this_afe.th_ftm_cfg, &cal_data->cal_info, sizeof(this_afe.th_ftm_cfg)); +done: + return ret; +} + +static int afe_set_cal_sp_th_vi_cfg(int32_t cal_type, size_t data_size, + void *data) +{ + int ret = 0; + struct audio_cal_type_sp_th_vi_ftm_cfg *cal_data = data; + uint32_t mode; + + if (cal_data == NULL || + this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL) + goto done; + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + mode = cal_data->cal_info.mode; + pr_debug("%s: cal_type = %d, mode = %d\n", __func__, cal_type, mode); + if (mode == MSM_SPKR_PROT_IN_FTM_MODE) { + ret = afe_set_cal_sp_th_vi_ftm_cfg(cal_type, + data_size, data); + } else if (mode == MSM_SPKR_PROT_IN_V_VALI_MODE) { + ret = afe_set_cal_sp_th_vi_v_vali_cfg(cal_type, + data_size, data); + } mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); done: return ret; @@ -8017,6 +8135,41 @@ static int afe_set_cal_fb_spkr_prot(int32_t cal_type, size_t data_size, return ret; } +static int afe_get_cal_sp_th_vi_v_vali_param(int32_t cal_type, size_t data_size, + void *data) +{ + int i, ret = 0; + struct audio_cal_type_sp_th_vi_v_vali_param *cal_data = data; + struct afe_sp_th_vi_v_vali_get_param th_vi_v_vali; + + if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL || + cal_data == NULL || + data_size != sizeof(*cal_data)) + goto done; + + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + cal_data->cal_info.status[i] = -EINVAL; + cal_data->cal_info.vrms_q24[i] = -1; + } + if (!afe_get_sp_th_vi_v_vali_data(&th_vi_v_vali)) { + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + pr_debug("%s: v-vali param status = %d\n", + __func__, th_vi_v_vali.param.status[i]); + if (th_vi_v_vali.param.status[i] == + V_VALI_IN_PROGRESS) { + cal_data->cal_info.status[i] = -EAGAIN; + } else if (th_vi_v_vali.param.status[i] == + V_VALI_SUCCESS) { + cal_data->cal_info.status[i] = V_VALI_SUCCESS; + cal_data->cal_info.vrms_q24[i] = + th_vi_v_vali.param.vrms_q24[i]; + } + } + } +done: + return ret; +} + static int afe_get_cal_sp_th_vi_ftm_param(int32_t cal_type, size_t data_size, void *data) { @@ -8024,13 +8177,11 @@ static int afe_get_cal_sp_th_vi_ftm_param(int32_t cal_type, size_t data_size, struct audio_cal_type_sp_th_vi_param *cal_data = data; struct afe_sp_th_vi_get_param th_vi; - pr_debug("%s: cal_type = %d\n", __func__, cal_type); if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL || cal_data == NULL || data_size != sizeof(*cal_data)) goto done; - mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { cal_data->cal_info.status[i] = -EINVAL; cal_data->cal_info.r_dc_q24[i] = -1; @@ -8051,11 +8202,34 @@ static int afe_get_cal_sp_th_vi_ftm_param(int32_t cal_type, size_t data_size, } } } - mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); done: return ret; } +static int afe_get_cal_sp_th_vi_param(int32_t cal_type, size_t data_size, + void *data) +{ + struct audio_cal_type_sp_th_vi_param *cal_data = data; + uint32_t mode; + int ret = 0; + + if (cal_data == NULL || + this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL) + return 0; + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + mode = cal_data->cal_info.mode; + pr_debug("%s: cal_type = %d,mode = %d\n", __func__, cal_type, mode); + if (mode == MSM_SPKR_PROT_IN_V_VALI_MODE) + ret = afe_get_cal_sp_th_vi_v_vali_param(cal_type, + data_size, data); + else + ret = afe_get_cal_sp_th_vi_ftm_param(cal_type, + data_size, data); + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + return ret; +} + static int afe_get_cal_sp_ex_vi_ftm_param(int32_t cal_type, size_t data_size, void *data) { @@ -8313,8 +8487,8 @@ static int afe_init_cal_data(void) cal_utils_match_buf_num} }, {{AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE, - {NULL, NULL, NULL, afe_set_cal_sp_th_vi_ftm_cfg, - afe_get_cal_sp_th_vi_ftm_param, NULL} }, + {NULL, NULL, NULL, afe_set_cal_sp_th_vi_cfg, + afe_get_cal_sp_th_vi_param, NULL} }, {NULL, NULL, cal_utils_match_buf_num} }, {{AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE, diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index d2cab24e6a51..3f50d1041180 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -10468,6 +10468,8 @@ struct asm_mode_vi_proc_cfg { #define AFE_PARAM_ID_SP_V2_TH_VI_MODE_CFG 0x0001026B #define AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG 0x0001029F #define AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS 0x000102A0 +#define AFE_PARAM_ID_SP_V2_TH_VI_V_VALI_CFG 0x000102BF +#define AFE_PARAM_ID_SP_V2_TH_VI_V_VALI_PARAMS 0x000102C0 struct afe_sp_th_vi_mode_cfg { uint32_t minor_version; @@ -10557,6 +10559,51 @@ struct afe_sp_th_vi_get_param_resp { struct afe_sp_th_vi_ftm_params param; } __packed; +struct afe_sp_th_vi_v_vali_cfg { + uint32_t minor_version; + uint32_t wait_time_ms[SP_V2_NUM_MAX_SPKR]; + /* + * Wait time to heat up speaker before collecting statistics + * for V validation mode in ms. + * values 100 to 1000 ms + */ + uint32_t vali_time_ms[SP_V2_NUM_MAX_SPKR]; + /* + * duration for which V VALIDATION statistics are collected in ms. + * values 1000 to 3000 ms + */ +} __packed; + +struct afe_sp_th_vi_v_vali_params { + uint32_t minor_version; + uint32_t vrms_q24[SP_V2_NUM_MAX_SPKR]; + /* + * Vrms value in q24 format + * values [0 33554432] Q24 (0 - 2Vrms) + */ + uint32_t status[SP_V2_NUM_MAX_SPKR]; + /* + * v-vali packet status + * 0 - Failed. + * 1 - Success. + * 2 - Incorrect operation mode.This status is returned + * when GET_PARAM is called in non v-vali Mode + * 3 - Inactive mode -- Port is not yet started. + * 4 - Wait state. wait_time_ms has not yet elapsed + * 5 - In progress state. ftm_time_ms has not yet elapsed. + */ +} __packed; + +struct afe_sp_th_vi_v_vali_get_param { + struct param_hdr_v3 pdata; + struct afe_sp_th_vi_v_vali_params param; +} __packed; + +struct afe_sp_th_vi_v_vali_get_param_resp { + uint32_t status; + struct param_hdr_v3 pdata; + struct afe_sp_th_vi_v_vali_params param; +} __packed; #define AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI 0x0001026F #define AFE_PARAM_ID_SP_V2_EX_VI_MODE_CFG 0x000102A1 @@ -10641,6 +10688,7 @@ union afe_spkr_prot_config { struct asm_mode_vi_proc_cfg mode_vi_proc_cfg; struct afe_sp_th_vi_mode_cfg th_vi_mode_cfg; struct afe_sp_th_vi_ftm_cfg th_vi_ftm_cfg; + struct afe_sp_th_vi_v_vali_cfg th_vi_v_vali_cfg; struct afe_sp_ex_vi_mode_cfg ex_vi_mode_cfg; struct afe_sp_ex_vi_ftm_cfg ex_vi_ftm_cfg; struct afe_sp_rx_limiter_th_param limiter_th_cfg; -- GitLab From 740b4839cbb3a6007ba6f3e4e0ebd676b020485f Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 24 Dec 2018 18:46:12 +0530 Subject: [PATCH 0873/1645] dsp: afe: Implement get param for excursion logging parameters Implement get param for AFE_PARAM_ID_SP_RX_TMAX_XMAX_LOGGING in order to get excursion params from DSP. Change-Id: I5129938c51c6f6ede9d4703d13be60d04d26f5e3 Signed-off-by: Aditya Bavanari --- dsp/q6afe.c | 57 ++++++++++++++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 28 +++++++++++++++++++ include/dsp/q6afe-v2.h | 3 ++ 3 files changed, 88 insertions(+) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 5000b9f46477..63057a08bd43 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -140,6 +140,7 @@ struct afe_ctl { struct afe_sp_th_vi_get_param_resp th_vi_resp; struct afe_sp_th_vi_v_vali_get_param_resp th_vi_v_vali_resp; struct afe_sp_ex_vi_get_param_resp ex_vi_resp; + struct afe_sp_rx_tmax_xmax_logging_resp xt_logging_resp; struct afe_av_dev_drift_get_param_resp av_dev_drift_resp; struct afe_doa_tracking_mon_get_param_resp doa_tracking_mon_resp; int vi_tx_port; @@ -385,6 +386,11 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, expected_size += sizeof(struct afe_sp_ex_vi_ftm_params); data_dest = (u32 *) &this_afe.ex_vi_resp; break; + case AFE_PARAM_ID_SP_RX_TMAX_XMAX_LOGGING: + expected_size += sizeof( + struct afe_sp_rx_tmax_xmax_logging_param); + data_dest = (u32 *) &this_afe.xt_logging_resp; + break; default: pr_err("%s: Unrecognized param ID %d\n", __func__, param_hdr.param_id); @@ -7620,6 +7626,57 @@ int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) return ret; } +/** + * afe_get_sp_rx_tmax_xmax_logging_data - + * command to get excursion logging data from DSP + * + * @xt_logging: excursion logging params + * @port: AFE port ID + * + * Returns 0 on success or error on failure + */ +int afe_get_sp_rx_tmax_xmax_logging_data( + struct afe_sp_rx_tmax_xmax_logging_param *xt_logging, + u16 port_id) +{ + struct param_hdr_v3 param_hdr; + int ret = -EINVAL; + + if (!xt_logging) { + pr_err("%s: Invalid params\n", __func__); + goto done; + } + + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_RX_TMAX_XMAX_LOGGING; + param_hdr.param_size = sizeof(struct afe_sp_rx_tmax_xmax_logging_param); + + ret = q6afe_get_params(port_id, NULL, ¶m_hdr); + if (ret < 0) { + pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", + __func__, port_id, param_hdr.param_id, ret); + goto done; + } + + memcpy(xt_logging, &this_afe.xt_logging_resp.param, + sizeof(this_afe.xt_logging_resp.param)); + pr_debug("%s: max_excursion %d %d count_exceeded_excursion %d %d max_temperature %d %d count_exceeded_temperature %d %d\n", + __func__, xt_logging->max_excursion[SP_V2_SPKR_1], + xt_logging->max_excursion[SP_V2_SPKR_2], + xt_logging->count_exceeded_excursion[SP_V2_SPKR_1], + xt_logging->count_exceeded_excursion[SP_V2_SPKR_2], + xt_logging->max_temperature[SP_V2_SPKR_1], + xt_logging->max_temperature[SP_V2_SPKR_2], + xt_logging->count_exceeded_temperature[SP_V2_SPKR_1], + xt_logging->count_exceeded_temperature[SP_V2_SPKR_2]); +done: + return ret; +} +EXPORT_SYMBOL(afe_get_sp_rx_tmax_xmax_logging_data); + /** * afe_get_av_dev_drift - * command to retrieve AV drift diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 3f50d1041180..62ff28b17ed0 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -10408,6 +10408,7 @@ struct cmd_set_topologies { #define AFE_PARAM_ID_SP_RX_LIMITER_TH 0x000102B1 #define AFE_PARAM_ID_FBSP_MODE_RX_CFG 0x0001021D #define AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG 0x00010260 +#define AFE_PARAM_ID_SP_RX_TMAX_XMAX_LOGGING 0x000102BC struct asm_fbsp_mode_rx_cfg { uint32_t minor_version; @@ -10665,6 +10666,33 @@ struct afe_sp_ex_vi_ftm_params { */ } __packed; +struct afe_sp_rx_tmax_xmax_logging_param { + /* + * Maximum excursion since the last grasp of xmax in mm. + */ + int32_t max_excursion[SP_V2_NUM_MAX_SPKR]; + /* + * Number of periods when the monitored excursion exceeds to and + * stays at Xmax during logging_count_period. + */ + uint32_t count_exceeded_excursion[SP_V2_NUM_MAX_SPKR]; + /* + * Maximum temperature since the last grasp of tmax in C. + */ + int32_t max_temperature[SP_V2_NUM_MAX_SPKR]; + /* + * Number of periods when the monitored temperature exceeds to and + * stays at Tmax during logging_count_period + */ + uint32_t count_exceeded_temperature[SP_V2_NUM_MAX_SPKR]; +} __packed; + +struct afe_sp_rx_tmax_xmax_logging_resp { + uint32_t status; + struct param_hdr_v3 pdata; + struct afe_sp_rx_tmax_xmax_logging_param param; +} __packed; + struct afe_sp_ex_vi_get_param { struct param_hdr_v3 pdata; struct afe_sp_ex_vi_ftm_params param; diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 413edc152af5..2319415917f2 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -446,6 +446,9 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, void afe_set_routing_callback(routing_cb cb); int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats, u16 port); +int afe_get_sp_rx_tmax_xmax_logging_data( + struct afe_sp_rx_tmax_xmax_logging_param *xt_logging, + u16 port_id); int afe_cal_init_hwdep(void *card); int afe_send_port_island_mode(u16 port_id); int afe_send_cmd_wakeup_register(void *handle, bool enable); -- GitLab From 828b3114fe7b9a9cf80ca45060366a55310c46a6 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 8 Mar 2019 00:37:47 +0530 Subject: [PATCH 0874/1645] ASoC: bolero: va-macro: Fix ioremap in va macro probe Update va-macro ioremap offset properly during probe. Change-Id: I3c4b1d6ba24b7935c3ba047059f72ed06bdafe4f Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/va-macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index f8df0b7722f2..a1e4f92dc589 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -1632,7 +1632,7 @@ static int va_macro_probe(struct platform_device *pdev) } va_io_base = devm_ioremap(&pdev->dev, va_base_addr, - VA_MAX_OFFSET); + VA_MACRO_MAX_OFFSET); if (!va_io_base) { dev_err(&pdev->dev, "%s: ioremap failed\n", __func__); return -EINVAL; -- GitLab From f16ed2f6c2f1006d872edd23a29ff89d680ee74d Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 13 Mar 2019 12:21:26 +0530 Subject: [PATCH 0875/1645] asoc: wcd938x: Disable EN_CUR_DET bit for receiver noise Disable EN_CUR_DET to fix receiver noise as per hardware specifications recommendation. Change-Id: Ib1ea1eecc3e0f2ffeeb5f41c344e51c903cd2300 Signed-off-by: Ramprasad Katkam Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd-clsh.c | 3 +++ asoc/codecs/wcd938x/wcd938x.c | 4 ++++ include/asoc/wcd9xxx_registers.h | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd-clsh.c b/asoc/codecs/wcd-clsh.c index fd30148b7026..0f403ac7a7e5 100644 --- a/asoc/codecs/wcd-clsh.c +++ b/asoc/codecs/wcd-clsh.c @@ -218,6 +218,9 @@ static void wcd_clsh_flyback_ctrl(struct snd_soc_component *component, /* enable/disable flyback */ if ((enable && (++clsh_d->flyback_users == 1)) || (!enable && (--clsh_d->flyback_users == 0))) { + snd_soc_component_update_bits(component, + WCD9XXX_FLYBACK_VNEG_CTRL_1, + 0xE0, 0xE0); snd_soc_component_update_bits(component, WCD9XXX_ANA_RX_SUPPLIES, (1 << 6), (enable << 6)); diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 8a5622fe8811..882feff26bf7 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -532,6 +532,8 @@ static int wcd938x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, WCD938X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x02); /* 5 msec delay as per HW requirement */ usleep_range(5000, 5010); + snd_soc_component_update_bits(component, WCD938X_FLYBACK_EN, + 0x04, 0x00); wcd_cls_h_fsm(component, &wcd938x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_EAR, @@ -824,6 +826,8 @@ static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_EAR, hph_mode); + snd_soc_component_update_bits(component, WCD938X_FLYBACK_EN, + 0x04, 0x04); break; }; return ret; diff --git a/include/asoc/wcd9xxx_registers.h b/include/asoc/wcd9xxx_registers.h index cf3c408dd3db..731b72f903ba 100644 --- a/include/asoc/wcd9xxx_registers.h +++ b/include/asoc/wcd9xxx_registers.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #ifndef _WCD9XXX_REGISTERS_H @@ -12,6 +12,7 @@ #define WCD9XXX_ANA_HPH (WCD9XXX_BASE_ADDRESS+0x009) #define WCD9XXX_CLASSH_MODE_2 (WCD9XXX_BASE_ADDRESS+0x098) #define WCD9XXX_CLASSH_MODE_3 (WCD9XXX_BASE_ADDRESS+0x099) +#define WCD9XXX_FLYBACK_VNEG_CTRL_1 (WCD9XXX_BASE_ADDRESS+0x0A5) #define WCD9XXX_FLYBACK_VNEG_CTRL_4 (WCD9XXX_BASE_ADDRESS+0x0A8) #define WCD9XXX_FLYBACK_VNEGDAC_CTRL_2 (WCD9XXX_BASE_ADDRESS+0x0AF) #define WCD9XXX_RX_BIAS_HPH_LOWPOWER (WCD9XXX_BASE_ADDRESS+0x0BF) -- GitLab From 36384ecca22f85d9d24632adf40c87a1d1fa745a Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 18 Feb 2019 21:57:19 +0530 Subject: [PATCH 0876/1645] dsp: get excursion logging at afe close for wsa and log data Trigger xt logging getparam at every playback close and store data. When app queries sys/class node, return stored values and reset to 0 for some params as per app requirement. Change-Id: Ice1a3e9a7e03062390f1c36184a971635e55d450 Signed-off-by: Laxminath Kasam --- asoc/msm-dai-q6-v2.c | 24 ++- dsp/Kbuild | 5 + dsp/q6_init.c | 2 + dsp/q6_init.h | 12 ++ dsp/q6afe.c | 56 +++++- dsp/sp_params.c | 424 ++++++++++++++++++++++++++++++++++++++++ include/dsp/q6afe-v2.h | 7 + include/dsp/sp_params.h | 19 ++ 8 files changed, 544 insertions(+), 5 deletions(-) create mode 100644 dsp/sp_params.c create mode 100644 include/dsp/sp_params.h diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index ac238578c64e..580335691b1a 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "msm-dai-q6-v2.h" #include @@ -10538,6 +10539,17 @@ static void msm_dai_q6_cdc_dma_shutdown(struct snd_pcm_substream *substream, clear_bit(STATUS_PORT_STARTED, dai_data->hwfree_status); } +/* all ports with same WSA requirement can use this digital mute API */ +static int msm_dai_q6_spk_digital_mute(struct snd_soc_dai *dai, + int mute) +{ + int port_id = dai->id; + + if (mute) + afe_get_sp_xt_logging_data(port_id); + + return 0; +} static struct snd_soc_dai_ops msm_dai_q6_cdc_dma_ops = { .prepare = msm_dai_q6_cdc_dma_prepare, @@ -10546,6 +10558,14 @@ static struct snd_soc_dai_ops msm_dai_q6_cdc_dma_ops = { .set_channel_map = msm_dai_q6_cdc_dma_set_channel_map, }; +static struct snd_soc_dai_ops msm_dai_q6_cdc_wsa_dma_ops = { + .prepare = msm_dai_q6_cdc_dma_prepare, + .hw_params = msm_dai_q6_cdc_dma_hw_params, + .shutdown = msm_dai_q6_cdc_dma_shutdown, + .set_channel_map = msm_dai_q6_cdc_dma_set_channel_map, + .digital_mute = msm_dai_q6_spk_digital_mute, +}; + static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { { .playback = { @@ -10568,7 +10588,7 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { .rate_max = 384000, }, .name = "WSA_CDC_DMA_RX_0", - .ops = &msm_dai_q6_cdc_dma_ops, + .ops = &msm_dai_q6_cdc_wsa_dma_ops, .id = AFE_PORT_ID_WSA_CODEC_DMA_RX_0, .probe = msm_dai_q6_dai_cdc_dma_probe, .remove = msm_dai_q6_dai_cdc_dma_remove, @@ -10620,7 +10640,7 @@ static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { .rate_max = 384000, }, .name = "WSA_CDC_DMA_RX_1", - .ops = &msm_dai_q6_cdc_dma_ops, + .ops = &msm_dai_q6_cdc_wsa_dma_ops, .id = AFE_PORT_ID_WSA_CODEC_DMA_RX_1, .probe = msm_dai_q6_dai_cdc_dma_probe, .remove = msm_dai_q6_dai_cdc_dma_remove, diff --git a/dsp/Kbuild b/dsp/Kbuild index 195502a7e210..daf0b303aa0e 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -91,11 +91,16 @@ ifdef CONFIG_SND_SOC_MSM_QDSP6V2_INTF Q6_OBJS += msm_audio_ion.o Q6_OBJS += avtimer.o Q6_OBJS += q6_init.o +endif +ifdef CONFIG_XT_LOGGING + Q6_OBJS += sp_params.o endif + ifdef CONFIG_WCD9XXX_CODEC_CORE Q6_OBJS += audio_slimslave.o endif + ifdef CONFIG_DTS_SRS_TM Q6_OBJS += msm-dts-srs-tm-config.o endif diff --git a/dsp/q6_init.c b/dsp/q6_init.c index 1078c5761c2b..fb18741d3838 100644 --- a/dsp/q6_init.c +++ b/dsp/q6_init.c @@ -14,6 +14,7 @@ static int __init audio_q6_init(void) rtac_init(); adm_init(); afe_init(); + spk_params_init(); q6asm_init(); q6lsm_init(); voice_init(); @@ -37,6 +38,7 @@ static void __exit audio_q6_exit(void) q6lsm_exit(); q6asm_exit(); afe_exit(); + spk_params_exit(); adm_exit(); rtac_exit(); audio_cal_exit(); diff --git a/dsp/q6_init.h b/dsp/q6_init.h index e7ad19b074b5..4df2e032700f 100644 --- a/dsp/q6_init.h +++ b/dsp/q6_init.h @@ -30,6 +30,18 @@ static inline void msm_mdf_exit(void) return; } #endif +#ifdef CONFIG_XT_LOGGING +int spk_params_init(void); +void spk_params_exit(void); +#else +static inline int spk_params_init(void) +{ + return 0; +} +static inline void spk_params_exit(void) +{ +} +#endif void avtimer_exit(void); void msm_audio_ion_exit(void); diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 63057a08bd43..3d5f5e8315c6 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -158,6 +158,9 @@ struct afe_ctl { struct vad_config vad_cfg[AFE_MAX_PORTS]; struct work_struct afe_dc_work; struct notifier_block event_notifier; + /* FTM spk params */ + uint32_t initial_cal; + uint32_t v_vali_flag; }; static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX]; @@ -179,6 +182,51 @@ static int afe_get_cal_hw_delay(int32_t path, struct audio_cal_hw_delay_entry *entry); static int remap_cal_data(struct cal_block_data *cal_block, int cal_index); +int afe_get_spk_initial_cal(void) +{ + return this_afe.initial_cal; +} + +void afe_get_spk_r0(int *spk_r0) +{ + uint16_t i = 0; + + for (; i < SP_V2_NUM_MAX_SPKRS; i++) + spk_r0[i] = this_afe.prot_cfg.r0[i]; +} + +void afe_get_spk_t0(int *spk_t0) +{ + uint16_t i = 0; + + for (; i < SP_V2_NUM_MAX_SPKRS; i++) + spk_t0[i] = this_afe.prot_cfg.t0[i]; +} + +int afe_get_spk_v_vali_flag(void) +{ + return this_afe.v_vali_flag; +} + +void afe_get_spk_v_vali_sts(int *spk_v_vali_sts) +{ + uint16_t i = 0; + + for (; i < SP_V2_NUM_MAX_SPKRS; i++) + spk_v_vali_sts[i] = + this_afe.th_vi_v_vali_resp.param.status[i]; +} + +void afe_set_spk_initial_cal(int initial_cal) +{ + this_afe.initial_cal = initial_cal; +} + +void afe_set_spk_v_vali_flag(int v_vali_flag) +{ + this_afe.v_vali_flag = v_vali_flag; +} + int afe_get_topology(int port_id) { int topology; @@ -7793,9 +7841,9 @@ int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) memcpy(&calib_resp->res_cfg, &this_afe.calib_data.res_cfg, sizeof(this_afe.calib_data.res_cfg)); pr_info("%s: state %s resistance %d %d\n", __func__, - fbsp_state[calib_resp->res_cfg.th_vi_ca_state], - calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_1], - calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_2]); + fbsp_state[calib_resp->res_cfg.th_vi_ca_state], + calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_1], + calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_2]); ret = 0; fail_cmd: return ret; @@ -8223,6 +8271,7 @@ static int afe_get_cal_sp_th_vi_v_vali_param(int32_t cal_type, size_t data_size, } } } + this_afe.v_vali_flag = 0; done: return ret; } @@ -8385,6 +8434,7 @@ static int afe_get_cal_fb_spkr_prot(int32_t cal_type, size_t data_size, cal_data->cal_info.r0[SP_V2_SPKR_1] = -1; cal_data->cal_info.r0[SP_V2_SPKR_2] = -1; } + this_afe.initial_cal = 0; mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); __pm_relax(&wl.ws); done: diff --git a/dsp/sp_params.c b/dsp/sp_params.c new file mode 100644 index 000000000000..ed6d2ebb05d5 --- /dev/null +++ b/dsp/sp_params.c @@ -0,0 +1,424 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* export or show spk params at /sys/class/spk_params/cal_data */ +#define SPK_PARAMS "spk_params" +#define CLASS_NAME "cal_data" +#define BUF_SZ 20 +#define Q27 (1<<27) +#define Q22 (1<<22) + +struct afe_spk_ctl { + struct class *p_class; + struct device *p_dev; + struct afe_sp_rx_tmax_xmax_logging_param xt_logging; + int32_t max_temperature_rd[SP_V2_NUM_MAX_SPKR]; +}; +struct afe_spk_ctl this_afe_spk; + +static ssize_t sp_count_exceeded_temperature_l_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t ret = 0; + + ret = snprintf(buf, BUF_SZ, "%d\n", + this_afe_spk.xt_logging.count_exceeded_temperature[SP_V2_SPKR_1]); + this_afe_spk.xt_logging.count_exceeded_temperature[SP_V2_SPKR_1] = 0; + return ret; +} +static DEVICE_ATTR(count_exceeded_temperature, 0644, + sp_count_exceeded_temperature_l_show, NULL); + +static ssize_t sp_count_exceeded_temperature_r_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t ret = 0; + + ret = snprintf(buf, BUF_SZ, "%d\n", + this_afe_spk.xt_logging.count_exceeded_temperature[SP_V2_SPKR_2]); + this_afe_spk.xt_logging.count_exceeded_temperature[SP_V2_SPKR_2] = 0; + return ret; +} +static DEVICE_ATTR(count_exceeded_temperature_r, 0644, + sp_count_exceeded_temperature_r_show, NULL); + +static ssize_t sp_count_exceeded_excursion_l_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t ret = 0; + + ret = snprintf(buf, BUF_SZ, "%d\n", + this_afe_spk.xt_logging.count_exceeded_excursion[SP_V2_SPKR_1]); + this_afe_spk.xt_logging.count_exceeded_excursion[SP_V2_SPKR_1] = 0; + return ret; +} +static DEVICE_ATTR(count_exceeded_excursion, 0644, + sp_count_exceeded_excursion_l_show, NULL); + +static ssize_t sp_count_exceeded_excursion_r_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t ret = 0; + + ret = snprintf(buf, BUF_SZ, "%d\n", + this_afe_spk.xt_logging.count_exceeded_excursion[SP_V2_SPKR_2]); + this_afe_spk.xt_logging.count_exceeded_excursion[SP_V2_SPKR_2] = 0; + return ret; +} +static DEVICE_ATTR(count_exceeded_excursion_r, 0644, + sp_count_exceeded_excursion_r_show, NULL); + +static ssize_t sp_max_excursion_l_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t ret = 0; + int32_t ex_val_frac; + float ex_val; + int32_t ex_q27 = this_afe_spk.xt_logging.max_excursion[SP_V2_SPKR_1]; + + ex_val = (ex_q27 * 1.0)/Q27; + ex_val_frac = ex_val * 100; + ret = snprintf(buf, BUF_SZ, "%d.%02d\n", 0, ex_val_frac); + this_afe_spk.xt_logging.max_excursion[SP_V2_SPKR_1] = 0; + return ret; +} +static DEVICE_ATTR(max_excursion, 0644, sp_max_excursion_l_show, NULL); + +static ssize_t sp_max_excursion_r_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t ret = 0; + int32_t ex_val_frac; + float ex_val; + int32_t ex_q27 = this_afe_spk.xt_logging.max_excursion[SP_V2_SPKR_2]; + + ex_val = (ex_q27 * 1.0)/Q27; + ex_val_frac = ex_val * 100; + ret = snprintf(buf, BUF_SZ, "%d.%02d\n", 0, ex_val_frac); + this_afe_spk.xt_logging.max_excursion[SP_V2_SPKR_2] = 0; + return ret; +} +static DEVICE_ATTR(max_excursion_r, 0644, sp_max_excursion_r_show, NULL); + +static ssize_t sp_max_temperature_l_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t ret = 0; + + ret = snprintf(buf, BUF_SZ, "%d\n", + this_afe_spk.xt_logging.max_temperature[SP_V2_SPKR_1]/Q22); + this_afe_spk.xt_logging.max_temperature[SP_V2_SPKR_1] = 0; + return ret; +} +static DEVICE_ATTR(max_temperature, 0644, sp_max_temperature_l_show, NULL); + +static ssize_t sp_max_temperature_r_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t ret = 0; + + ret = snprintf(buf, BUF_SZ, "%d\n", + this_afe_spk.xt_logging.max_temperature[SP_V2_SPKR_2]/Q22); + this_afe_spk.xt_logging.max_temperature[SP_V2_SPKR_2] = 0; + return ret; +} +static DEVICE_ATTR(max_temperature_r, 0644, sp_max_temperature_r_show, NULL); + +static ssize_t sp_max_temperature_rd_l_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, BUF_SZ, "%d\n", + this_afe_spk.max_temperature_rd[SP_V2_SPKR_1]/Q22); +} +static DEVICE_ATTR(max_temperature_rd, 0644, + sp_max_temperature_rd_l_show, NULL); + +static ssize_t sp_max_temperature_rd_r_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, BUF_SZ, "%d\n", + this_afe_spk.max_temperature_rd[SP_V2_SPKR_2]/Q22); +} +static DEVICE_ATTR(max_temperature_rd_r, 0644, + sp_max_temperature_rd_r_show, NULL); + +static ssize_t q6afe_initial_cal_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, BUF_SZ, "%d\n", afe_get_spk_initial_cal()); +} + +static ssize_t q6afe_initial_cal_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int initial_cal = 0; + + if (!kstrtou32(buf, 0, &initial_cal)) { + initial_cal = initial_cal > 0 ? 1 : 0; + if (initial_cal == afe_get_spk_initial_cal()) + dev_dbg(dev, "%s: same value already present\n", + __func__); + else + afe_set_spk_initial_cal(initial_cal); + } + return size; +} + +static DEVICE_ATTR(initial_cal, 0644, + q6afe_initial_cal_show, q6afe_initial_cal_store); + +static ssize_t q6afe_v_vali_flag_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, BUF_SZ, "%d\n", afe_get_spk_v_vali_flag()); +} + +static ssize_t q6afe_v_vali_flag_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int v_vali_flag = 0; + + if (!kstrtou32(buf, 0, &v_vali_flag)) { + v_vali_flag = v_vali_flag > 0 ? 1 : 0; + if (v_vali_flag == afe_get_spk_v_vali_flag()) + dev_dbg(dev, "%s: same value already present\n", + __func__); + else + afe_set_spk_v_vali_flag(v_vali_flag); + } + return size; +} + +static DEVICE_ATTR(v_vali_flag, 0644, + q6afe_v_vali_flag_show, q6afe_v_vali_flag_store); + +static ssize_t q6afe_spk_r0_l_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int r0[SP_V2_NUM_MAX_SPKRS]; + + afe_get_spk_r0(r0); + return snprintf(buf, BUF_SZ, "%d\n", r0[SP_V2_SPKR_1]); +} + +static DEVICE_ATTR(spk_r0, 0644, q6afe_spk_r0_l_show, NULL); + +static ssize_t q6afe_spk_t0_l_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int t0[SP_V2_NUM_MAX_SPKRS]; + + afe_get_spk_t0(t0); + return snprintf(buf, BUF_SZ, "%d\n", t0[SP_V2_SPKR_1]); +} + +static DEVICE_ATTR(spk_t0, 0644, q6afe_spk_t0_l_show, NULL); + +static ssize_t q6afe_spk_r0_r_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int r0[SP_V2_NUM_MAX_SPKRS]; + + afe_get_spk_r0(r0); + return snprintf(buf, BUF_SZ, "%d\n", r0[SP_V2_SPKR_2]); +} + +static DEVICE_ATTR(spk_r0_r, 0644, q6afe_spk_r0_r_show, NULL); + +static ssize_t q6afe_spk_t0_r_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int t0[SP_V2_NUM_MAX_SPKRS]; + + afe_get_spk_t0(t0); + return snprintf(buf, BUF_SZ, "%d\n", t0[SP_V2_SPKR_2]); +} + +static DEVICE_ATTR(spk_t0_r, 0644, q6afe_spk_t0_r_show, NULL); + +static ssize_t q6afe_spk_v_vali_l_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int v_vali_sts[SP_V2_NUM_MAX_SPKRS]; + + afe_get_spk_v_vali_sts(v_vali_sts); + return snprintf(buf, BUF_SZ, "%d\n", v_vali_sts[SP_V2_SPKR_1]); +} + +static DEVICE_ATTR(spk_v_vali_status, 0644, q6afe_spk_v_vali_l_show, NULL); + +static ssize_t q6afe_spk_v_vali_r_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int v_vali_sts[SP_V2_NUM_MAX_SPKRS]; + + afe_get_spk_v_vali_sts(v_vali_sts); + return snprintf(buf, BUF_SZ, "%d\n", v_vali_sts[SP_V2_SPKR_2]); +} + +static DEVICE_ATTR(spk_v_vali_r_status, 0644, q6afe_spk_v_vali_r_show, NULL); + +static struct attribute *afe_spk_cal_attr[] = { + &dev_attr_max_excursion.attr, + &dev_attr_max_excursion_r.attr, + &dev_attr_max_temperature.attr, + &dev_attr_max_temperature_r.attr, + &dev_attr_count_exceeded_excursion.attr, + &dev_attr_count_exceeded_excursion_r.attr, + &dev_attr_count_exceeded_temperature.attr, + &dev_attr_count_exceeded_temperature_r.attr, + &dev_attr_max_temperature_rd.attr, + &dev_attr_max_temperature_rd_r.attr, + &dev_attr_initial_cal.attr, + &dev_attr_spk_r0.attr, + &dev_attr_spk_t0.attr, + &dev_attr_spk_r0_r.attr, + &dev_attr_spk_t0_r.attr, + &dev_attr_v_vali_flag.attr, + &dev_attr_spk_v_vali_status.attr, + &dev_attr_spk_v_vali_r_status.attr, + NULL, +}; + +static struct attribute_group afe_spk_cal_attr_grp = { + .attrs = afe_spk_cal_attr, +}; + + +/** + * afe_get_sp_xt_logging_data - + * to get excursion logging data from DSP + * + * @port: AFE port ID + * + * Returns 0 on success or error on failure + */ +int afe_get_sp_xt_logging_data(u16 port_id) +{ + int ret = 0; + struct afe_sp_rx_tmax_xmax_logging_param xt_logging_data; + + ret = afe_get_sp_rx_tmax_xmax_logging_data(&xt_logging_data, port_id); + if (ret) { + pr_err("%s Excursion logging fail\n", __func__); + return ret; + } + /* storing max sp param value */ + if (this_afe_spk.xt_logging.max_temperature[SP_V2_SPKR_1] < + xt_logging_data.max_temperature[SP_V2_SPKR_1]) + this_afe_spk.xt_logging.max_temperature[SP_V2_SPKR_1] = + xt_logging_data.max_temperature[SP_V2_SPKR_1]; + + + if (this_afe_spk.xt_logging.max_temperature[SP_V2_SPKR_2] < + xt_logging_data.max_temperature[SP_V2_SPKR_2]) + this_afe_spk.xt_logging.max_temperature[SP_V2_SPKR_2] = + xt_logging_data.max_temperature[SP_V2_SPKR_2]; + + + /* update temp for max_temperature_rd node */ + if (this_afe_spk.max_temperature_rd[SP_V2_SPKR_1] < + xt_logging_data.max_temperature[SP_V2_SPKR_1]) + this_afe_spk.max_temperature_rd[SP_V2_SPKR_1] = + xt_logging_data.max_temperature[SP_V2_SPKR_1]; + + if (this_afe_spk.max_temperature_rd[SP_V2_SPKR_2] < + xt_logging_data.max_temperature[SP_V2_SPKR_2]) + this_afe_spk.max_temperature_rd[SP_V2_SPKR_2] = + xt_logging_data.max_temperature[SP_V2_SPKR_2]; + + + if (this_afe_spk.xt_logging.max_excursion[SP_V2_SPKR_1] < + xt_logging_data.max_excursion[SP_V2_SPKR_1]) + this_afe_spk.xt_logging.max_excursion[SP_V2_SPKR_1] = + xt_logging_data.max_excursion[SP_V2_SPKR_1]; + + if (this_afe_spk.xt_logging.max_excursion[SP_V2_SPKR_2] < + xt_logging_data.max_excursion[SP_V2_SPKR_2]) + this_afe_spk.xt_logging.max_excursion[SP_V2_SPKR_2] = + xt_logging_data.max_excursion[SP_V2_SPKR_2]; + + if (this_afe_spk.xt_logging.count_exceeded_temperature[SP_V2_SPKR_1] < + xt_logging_data.count_exceeded_temperature[SP_V2_SPKR_1]) + this_afe_spk.xt_logging.count_exceeded_temperature[SP_V2_SPKR_1] + += xt_logging_data.count_exceeded_temperature[SP_V2_SPKR_1]; + + if (this_afe_spk.xt_logging.count_exceeded_temperature[SP_V2_SPKR_2] < + xt_logging_data.count_exceeded_temperature[SP_V2_SPKR_2]) + this_afe_spk.xt_logging.count_exceeded_temperature[SP_V2_SPKR_2] + += xt_logging_data.count_exceeded_temperature[SP_V2_SPKR_2]; + + if (this_afe_spk.xt_logging.count_exceeded_excursion[SP_V2_SPKR_1] < + xt_logging_data.count_exceeded_excursion[SP_V2_SPKR_1]) + this_afe_spk.xt_logging.count_exceeded_excursion[SP_V2_SPKR_1] + += xt_logging_data.count_exceeded_excursion[SP_V2_SPKR_1]; + + if (this_afe_spk.xt_logging.count_exceeded_excursion[SP_V2_SPKR_2] < + xt_logging_data.count_exceeded_excursion[SP_V2_SPKR_2]) + this_afe_spk.xt_logging.count_exceeded_excursion[SP_V2_SPKR_2] + += xt_logging_data.count_exceeded_excursion[SP_V2_SPKR_2]; + + return ret; +} +EXPORT_SYMBOL(afe_get_sp_xt_logging_data); + +int __init spk_params_init(void) +{ + /* initialize xt param value with 0 */ + this_afe_spk.xt_logging.max_temperature[SP_V2_SPKR_1] = 0; + this_afe_spk.xt_logging.max_temperature[SP_V2_SPKR_2] = 0; + this_afe_spk.xt_logging.max_excursion[SP_V2_SPKR_1] = 0; + this_afe_spk.xt_logging.max_excursion[SP_V2_SPKR_2] = 0; + this_afe_spk.xt_logging.count_exceeded_temperature[SP_V2_SPKR_1] = 0; + this_afe_spk.xt_logging.count_exceeded_temperature[SP_V2_SPKR_2] = 0; + this_afe_spk.xt_logging.count_exceeded_excursion[SP_V2_SPKR_1] = 0; + this_afe_spk.xt_logging.count_exceeded_excursion[SP_V2_SPKR_2] = 0; + + this_afe_spk.p_class = class_create(THIS_MODULE, SPK_PARAMS); + if (this_afe_spk.p_class) { + this_afe_spk.p_dev = device_create(this_afe_spk.p_class, NULL, + 1, NULL, CLASS_NAME); + if (!IS_ERR(this_afe_spk.p_dev)) { + if (sysfs_create_group(&this_afe_spk.p_dev->kobj, + &afe_spk_cal_attr_grp)) + pr_err("%s: Failed to create sysfs group\n", + __func__); + } + } + return 0; +} + +void spk_params_exit(void) +{ + pr_debug("%s\n", __func__); +} diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 2319415917f2..c5b7e3e65292 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -494,4 +494,11 @@ struct afe_cmd_remote_lpass_core_hw_devote_request { int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name, uint32_t *client_handle); int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle); +int afe_get_spk_initial_cal(void); +void afe_get_spk_r0(int *spk_r0); +void afe_get_spk_t0(int *spk_t0); +int afe_get_spk_v_vali_flag(void); +void afe_get_spk_v_vali_sts(int *spk_v_vali_sts); +void afe_set_spk_initial_cal(int initial_cal); +void afe_set_spk_v_vali_flag(int v_vali_flag); #endif /* __Q6AFE_V2_H__ */ diff --git a/include/dsp/sp_params.h b/include/dsp/sp_params.h new file mode 100644 index 000000000000..ddc756ee8c9d --- /dev/null +++ b/include/dsp/sp_params.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#ifndef __SP_PARAMS_H__ +#define __SP_PARAMS_H__ + +#if IS_ENABLED(CONFIG_XT_LOGGING) +int afe_get_sp_xt_logging_data(u16 port_id); +#else +static inline int afe_get_sp_xt_logging_data(u16 port_id) +{ + return 0; +} +#endif + +#endif /* __SP_PARAMS_H__ */ + -- GitLab From baab9b123f469e75bd4364f9c88775f6fdb27f30 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Sun, 3 Feb 2019 22:15:21 +0530 Subject: [PATCH 0877/1645] asoc: wcd9335: Add support for SSR handling using SND event fwk Add support for SSR/PDR handling using SND event framework in tasha codec. Change-Id: Ief0bc7dc62d83635fdc905f1f385571e0e4b3190 Signed-off-by: Aditya Bavanari --- asoc/codecs/wcd9335.c | 67 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 22bc0e6aba69..c25ef464a0ca 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -13708,11 +13709,23 @@ static int tasha_device_down(struct wcd9xxx *wcd9xxx) component = (struct snd_soc_component *)(wcd9xxx->ssr_priv); priv = snd_soc_component_get_drvdata(component); + snd_event_notify(priv->dev->parent, SND_EVENT_DOWN); wcd_cpe_ssr_event(priv->cpe_core, WCD_CPE_BUS_DOWN_EVENT); - for (i = 0; i < priv->nr; i++) + + if (!priv->swr_ctrl_data) + return -EINVAL; + + for (i = 0; i < priv->nr; i++) { + if (is_snd_event_fwk_enabled()) + swrm_wcd_notify( + priv->swr_ctrl_data[i].swr_pdev, + SWR_DEVICE_SSR_DOWN, NULL); swrm_wcd_notify(priv->swr_ctrl_data[i].swr_pdev, SWR_DEVICE_DOWN, NULL); - snd_soc_card_change_online_state(component->card, 0); + } + + if (!is_snd_event_fwk_enabled()) + snd_soc_card_change_online_state(component->card, 0); for (count = 0; count < NUM_CODEC_DAIS; count++) priv->dai[count].bus_down_in_recovery = true; @@ -13747,7 +13760,8 @@ static int tasha_post_reset_cb(struct wcd9xxx *wcd9xxx) if (tasha->machine_codec_event_cb) tasha->machine_codec_event_cb(component, WCD9335_CODEC_EVENT_CODEC_UP); - snd_soc_card_change_online_state(component->card, 1); + if (!is_snd_event_fwk_enabled()) + snd_soc_card_change_online_state(component->card, 1); /* Class-H Init*/ wcd_clsh_init(&tasha->clsh_d); @@ -13807,9 +13821,21 @@ static int tasha_post_reset_cb(struct wcd9xxx *wcd9xxx) goto err; } + if (!tasha->swr_ctrl_data) { + ret = -EINVAL; + goto err; + } + + if (is_snd_event_fwk_enabled()) { + for (i = 0; i < tasha->nr; i++) + swrm_wcd_notify( + tasha->swr_ctrl_data[i].swr_pdev, + SWR_DEVICE_SSR_UP, NULL); + } + tasha_set_spkr_mode(component, tasha->spkr_mode); wcd_cpe_ssr_event(tasha->cpe_core, WCD_CPE_BUS_UP_EVENT); - + snd_event_notify(tasha->dev->parent, SND_EVENT_UP); err: mutex_unlock(&tasha->codec_mutex); return ret; @@ -13835,6 +13861,28 @@ static struct regulator *tasha_codec_find_ondemand_regulator( return NULL; } +static void tasha_ssr_disable(struct device *dev, void *data) +{ + struct wcd9xxx *wcd9xxx = dev_get_drvdata(dev); + struct tasha_priv *tasha; + struct snd_soc_component *component; + int count = 0; + + if (!wcd9xxx) { + dev_dbg(dev, "%s: wcd9xxx pointer NULL.\n", __func__); + return; + } + component = (struct snd_soc_component *)(wcd9xxx->ssr_priv); + tasha = snd_soc_component_get_drvdata(component); + + for (count = 0; count < NUM_CODEC_DAIS; count++) + tasha->dai[count].bus_down_in_recovery = true; +} + +static const struct snd_event_ops tasha_ssr_ops = { + .disable = tasha_ssr_disable, +}; + static int tasha_codec_probe(struct snd_soc_component *component) { struct wcd9xxx *control; @@ -14654,6 +14702,14 @@ static int tasha_probe(struct platform_device *pdev) tasha_update_reg_defaults(tasha); schedule_work(&tasha->tasha_add_child_devices_work); tasha_get_codec_ver(tasha); + ret = snd_event_client_register(pdev->dev.parent, &tasha_ssr_ops, NULL); + if (!ret) { + snd_event_notify(pdev->dev.parent, SND_EVENT_UP); + } else { + pr_err("%s: Registration with SND event fwk failed ret = %d\n", + __func__, ret); + ret = 0; + } dev_info(&pdev->dev, "%s: Tasha driver probe done\n", __func__); return ret; @@ -14682,6 +14738,7 @@ static int tasha_remove(struct platform_device *pdev) if (!tasha) return -EINVAL; + snd_event_client_deregister(pdev->dev.parent); for (count = 0; count < tasha->child_count && count < WCD9335_CHILD_DEVICES_MAX; count++) platform_device_unregister(tasha->pdev_child_devices[count]); -- GitLab From 13faf538b32ed00ee6bde18831a72973ff4a3d2c Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 13 Feb 2019 12:55:30 +0530 Subject: [PATCH 0878/1645] ASoC: wcd937x: Fix playback stop issue after SSR/PDR on special hs If we start playback on special hs after record is done and perform SSR/PDR then playback gets paused. This happens because ANA_TX_DIV2_CLK which needs to be enabled for special hs gets disabled after record is stopped. Maintain a count for ANA_DIV2_CLK to enable/disable it as required. Change-Id: Ic73475c83cb16e3c014f35b8d46ee22d2e7a2efd Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/internal.h | 2 ++ asoc/codecs/wcd937x/wcd937x.c | 32 +++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index 110425a8924e..b7bdfa22dd7d 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -83,6 +83,8 @@ struct wcd937x_priv { struct snd_info_entry *entry; struct snd_info_entry *version_entry; int ear_rx_path; + int ana_clk_count; + struct mutex ana_tx_clk_lock; }; struct wcd937x_micbias_setting { diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index beb4b177fd56..29c2774d29bf 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1267,12 +1267,17 @@ static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct wcd937x_priv *wcd937x = + snd_soc_component_get_drvdata(component); dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: + mutex_lock(&wcd937x->ana_tx_clk_lock); + wcd937x->ana_clk_count++; + mutex_unlock(&wcd937x->ana_tx_clk_lock); snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x80); snd_soc_component_update_bits(component, @@ -1296,6 +1301,8 @@ static int wcd937x_enable_req(struct snd_soc_dapm_widget *w, { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct wcd937x_priv *wcd937x = + snd_soc_component_get_drvdata(component); dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -1324,8 +1331,15 @@ static int wcd937x_enable_req(struct snd_soc_dapm_widget *w, WCD937X_ANA_TX_CH2, 0x80, 0x00); snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x10, 0x00); - snd_soc_component_update_bits(component, + mutex_lock(&wcd937x->ana_tx_clk_lock); + wcd937x->ana_clk_count--; + if (wcd937x->ana_clk_count <= 0) { + snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00); + wcd937x->ana_clk_count = 0; + } + + mutex_unlock(&wcd937x->ana_tx_clk_lock); snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x00); break; @@ -1389,6 +1403,9 @@ int wcd937x_micbias_control(struct snd_soc_component *component, break; case MICB_ENABLE: wcd937x->micb_ref[micb_index]++; + mutex_lock(&wcd937x->ana_tx_clk_lock); + wcd937x->ana_clk_count++; + mutex_unlock(&wcd937x->ana_tx_clk_lock); if (wcd937x->micb_ref[micb_index] == 1) { snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0xE0, 0xE0); @@ -1413,6 +1430,9 @@ int wcd937x_micbias_control(struct snd_soc_component *component, &wcd937x->mbhc->wcd_mbhc); break; case MICB_DISABLE: + mutex_lock(&wcd937x->ana_tx_clk_lock); + wcd937x->ana_clk_count--; + mutex_unlock(&wcd937x->ana_tx_clk_lock); if (wcd937x->micb_ref[micb_index] > 0) wcd937x->micb_ref[micb_index]--; if ((wcd937x->micb_ref[micb_index] == 0) && @@ -1433,6 +1453,14 @@ int wcd937x_micbias_control(struct snd_soc_component *component, post_off_event, &wcd937x->mbhc->wcd_mbhc); } + mutex_lock(&wcd937x->ana_tx_clk_lock); + if (wcd937x->ana_clk_count <= 0) { + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_ANA_CLK_CTL, + 0x10, 0x00); + wcd937x->ana_clk_count = 0; + } + mutex_unlock(&wcd937x->ana_tx_clk_lock); if (is_dapm && post_dapm_off && wcd937x->mbhc) blocking_notifier_call_chain( &wcd937x->mbhc->notifier, post_dapm_off, @@ -2757,6 +2785,7 @@ static int wcd937x_bind(struct device *dev) } mutex_init(&wcd937x->micb_lock); + mutex_init(&wcd937x->ana_tx_clk_lock); /* Request for watchdog interrupt */ wcd_request_irq(&wcd937x->irq_info, WCD937X_IRQ_HPHR_PDM_WD_INT, "HPHR PDM WD INT", wcd937x_wd_handle_irq, NULL); @@ -2793,6 +2822,7 @@ static void wcd937x_unbind(struct device *dev) snd_soc_unregister_component(dev); component_unbind_all(dev, wcd937x); mutex_destroy(&wcd937x->micb_lock); + mutex_destroy(&wcd937x->ana_tx_clk_lock); } static const struct of_device_id wcd937x_dt_match[] = { -- GitLab From 578740db71f8b27ed6e068d011a48602ccb75cf4 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 19 Mar 2019 14:25:02 +0800 Subject: [PATCH 0879/1645] asoc: wcd937x: Disable EN_CUR_DET bit for receiver noise Disable EN_CUR_DET to fix receiver noise as per hw team recommendation. Change-Id: Icbeea920d02279ff845072e54be1c449db7bd2da Signed-off-by: Meng Wang --- asoc/codecs/wcd937x/wcd937x.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index beb4b177fd56..0836bc0fa283 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -567,6 +567,8 @@ static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, WCD937X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x02); usleep_range(5000, 5010); + snd_soc_component_update_bits(component, WCD937X_FLYBACK_EN, + 0x04, 0x00); wcd_cls_h_fsm(component, &wcd937x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_EAR, @@ -942,6 +944,8 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_EAR, hph_mode); + snd_soc_component_update_bits(component, WCD937X_FLYBACK_EN, + 0x04, 0x04); if (wcd937x->ear_rx_path & EAR_RX_PATH_AUX) snd_soc_component_update_bits(component, WCD937X_DIGITAL_PDM_WD_CTL2, -- GitLab From 8a2a10415685da5eddc35d3b0163c4e742a4c4fc Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 21 Mar 2019 10:14:50 +0800 Subject: [PATCH 0880/1645] asoc: add NULL check before access pointer Add NULL check before access pointer to avoid dereference. Change-Id: I2c7408348a0acf1a3801a5869f62bae328858beb Signed-off-by: Meng Wang --- asoc/msm-compress-q6-v2.c | 29 +++++++++++++++++++++-------- asoc/msm-transcode-loopback-q6-v2.c | 16 ++++++++++++++++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index c48e2c288bdd..179a95e66f35 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -363,12 +363,17 @@ static int msm_compr_set_volume(struct snd_compr_stream *cstream, } rtd = cstream->private_data; prtd = cstream->runtime->private_data; - component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); - if (!rtd || !component || !prtd || !prtd->audio_client) { + if (!rtd || !prtd || !prtd->audio_client) { pr_err("%s: invalid rtd, prtd or audio client", __func__); return rc; } + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: invalid component\n", __func__); + return rc; + } + pdata = snd_soc_component_get_drvdata(component); if (prtd->compr_passthr != LEGACY_PCM) { @@ -1810,12 +1815,16 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream) } runtime = cstream->runtime; soc_prtd = cstream->private_data; - component = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); - if (!runtime || !soc_prtd || !component) { - pr_err("%s runtime or soc_prtd or component is null\n", + if (!runtime || !soc_prtd) { + pr_err("%s runtime or soc_prtd is null\n", __func__); return 0; } + component = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); + if (!component) { + pr_err("%s component is null\n", __func__); + return 0; + } prtd = runtime->private_data; if (!prtd) { pr_err("%s prtd is null\n", __func__); @@ -1913,12 +1922,16 @@ static int msm_compr_capture_free(struct snd_compr_stream *cstream) } runtime = cstream->runtime; soc_prtd = cstream->private_data; + if (!runtime || !soc_prtd) { + pr_err("%s runtime or soc_prtd is null\n", __func__); + return 0; + } component = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); - if (!runtime || !soc_prtd || !component) { - pr_err("%s runtime or soc_prtd or component is null\n", - __func__); + if (!component) { + pr_err("%s component is null\n", __func__); return 0; } + prtd = runtime->private_data; if (!prtd) { pr_err("%s prtd is null\n", __func__); diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index 9980874c2197..67bdc75a1647 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -435,7 +435,15 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, mutex_lock(&trans->lock); rtd = snd_pcm_substream_chip(cstream); + if (!rtd) { + pr_err("%s: rtd is NULL\n", __func__); + return -EINVAL; + } component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } pdata = snd_soc_component_get_drvdata(component); if (cstream->direction == SND_COMPRESS_PLAYBACK) { @@ -606,7 +614,15 @@ static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream, } rtd = snd_pcm_substream_chip(cstream); + if (!rtd) { + pr_err("%s: rtd is NULL\n", __func__); + return -EINVAL; + } component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } pdata = snd_soc_component_get_drvdata(component); prtd = cstream->runtime->private_data; -- GitLab From 764b2d2e8ed67b044506cf77234c3e48e01c08cb Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 21 Mar 2019 10:54:09 -0700 Subject: [PATCH 0881/1645] asoc: pcm: modify component extraction Component for channel map mixer control should be extracted from pcm runtime instead of kcontrol's private data, because kcontrol's private data in this case points to channel map info. CRs-Fixed: 2420279 Change-Id: Ibaeac4739b73a89d17f16cbacb1b5095d546968b Signed-off-by: Vignesh Kulothungan --- asoc/msm-pcm-q6-v2.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 71dbd0c987c4..a087dd822c04 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1604,7 +1604,7 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol, struct snd_soc_pcm_runtime *rtd = NULL; struct msm_plat_data *pdata = NULL; struct msm_pcm_channel_mixer *chmixer_pspd = NULL; - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_component *component = NULL; u64 fe_id = 0; pr_debug("%s", __func__); @@ -1624,18 +1624,21 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol, /* update chmixer_pspd chmap cached with routing driver as well */ rtd = substream->private_data; if (rtd) { - fe_id = rtd->dai_link->id; - pdata = (struct msm_plat_data *) - dev_get_drvdata(component->dev); - chmixer_pspd = pdata ? - pdata->chmixer_pspd[fe_id][SESSION_TYPE_RX] : NULL; - - if (chmixer_pspd && chmixer_pspd->enable) { - for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) - chmixer_pspd->in_ch_map[i] = prtd->channel_map[i]; - chmixer_pspd->override_in_ch_map = true; - msm_pcm_routing_set_channel_mixer_cfg(fe_id, - SESSION_TYPE_RX, chmixer_pspd); + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (component) { + fe_id = rtd->dai_link->id; + pdata = (struct msm_plat_data *) + dev_get_drvdata(component->dev); + chmixer_pspd = pdata ? + pdata->chmixer_pspd[fe_id][SESSION_TYPE_RX] : NULL; + + if (chmixer_pspd && chmixer_pspd->enable) { + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->in_ch_map[i] = prtd->channel_map[i]; + chmixer_pspd->override_in_ch_map = true; + msm_pcm_routing_set_channel_mixer_cfg(fe_id, + SESSION_TYPE_RX, chmixer_pspd); + } } } } -- GitLab From 3d4eec47ef29a0a448f3d788dd4953c743123670 Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Tue, 5 Mar 2019 15:06:48 +0530 Subject: [PATCH 0882/1645] asoc: codecs: bolero: Reduce hpf corner freq delay to 50ms Reduce hpf corner freq delay from 300ms to 50ms to avoid initial mute in recorded audio. Change-Id: Ibd6e7d60f836e866d73899d3f691c0e8070a3527 Signed-off-by: Mangesh Kunchamwar Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/tx-macro.c | 2 +- asoc/codecs/bolero/va-macro.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 58f3689276da..98ee1e72d611 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -691,7 +691,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, CF_MIN_3DB_150HZ) { schedule_delayed_work( &tx_priv->tx_hpf_work[decimator].dwork, - msecs_to_jiffies(300)); + msecs_to_jiffies(50)); snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x02); /* diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index f8df0b7722f2..61bfa9a88d28 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -595,7 +595,7 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, CF_MIN_3DB_150HZ) schedule_delayed_work( &va_priv->va_hpf_work[decimator].dwork, - msecs_to_jiffies(300)); + msecs_to_jiffies(50)); /* apply gain after decimator is enabled */ snd_soc_component_write(component, tx_gain_ctl_reg, snd_soc_component_read32(component, tx_gain_ctl_reg)); -- GitLab From 5670cbd6e38a11b840dc3fd7e9adc886589add33 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 21 Mar 2019 18:00:51 -0700 Subject: [PATCH 0883/1645] dsp: afe: get apr handle before sending apr pkt Make sure to get apr handle before sending a packet so that it does not end up with no handle to send the apr packet. Change-Id: Iaaebee3ddc6c83896e4cb9dc8149d310fc7d67f1 Signed-off-by: Karthikeyan Mani --- dsp/q6afe.c | 12 ++++++++++++ ipc/apr.c | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 3d5f5e8315c6..fd66571dffbb 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -8827,6 +8827,12 @@ int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name, return -EINVAL; } + ret = afe_q6_interface_prepare(); + if(ret) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + mutex_lock(&this_afe.afe_cmd_lock); memset(cmd_ptr, 0, sizeof(hw_vote_cfg)); @@ -8902,6 +8908,12 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle) &hw_vote_cfg; int ret = 0; + ret = afe_q6_interface_prepare(); + if(ret) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + mutex_lock(&this_afe.afe_cmd_lock); memset(cmd_ptr, 0, sizeof(hw_vote_cfg)); diff --git a/ipc/apr.c b/ipc/apr.c index 2e6d75f3eb6f..fbb1f32e6c18 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -364,7 +364,8 @@ int apr_send_pkt(void *handle, uint32_t *buf) unsigned long flags; if (!handle || !buf) { - pr_err("APR: Wrong parameters\n"); + pr_err("APR: Wrong parameters for %s\n", + !handle ? "handle" : "buf"); return -EINVAL; } if (svc->need_reset) { -- GitLab From 9e17da0005cf7c40e224dd4dd7de83e238c23d6f Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 21 Mar 2019 12:15:59 -0700 Subject: [PATCH 0884/1645] asoc: validate channel number before use Validate channel number before using it to index codec dma rx configuation array. CRs-Fixed: 2420338 Change-Id: I48109beedba2423158fa84dee0b9ccac340979b1 Signed-off-by: Vignesh Kulothungan --- asoc/kona.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index fd5c9a71250b..704951ccebf3 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -2297,7 +2297,7 @@ static int cdc_dma_rx_ch_get(struct snd_kcontrol *kcontrol, { int ch_num = cdc_dma_get_port_idx(kcontrol); - if (ch_num < 0) { + if (ch_num < 0 || ch_num >= CDC_DMA_RX_MAX) { pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); return ch_num; } @@ -2313,7 +2313,7 @@ static int cdc_dma_rx_ch_put(struct snd_kcontrol *kcontrol, { int ch_num = cdc_dma_get_port_idx(kcontrol); - if (ch_num < 0) { + if (ch_num < 0 || ch_num >= CDC_DMA_RX_MAX) { pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); return ch_num; } @@ -2330,7 +2330,7 @@ static int cdc_dma_rx_format_get(struct snd_kcontrol *kcontrol, { int ch_num = cdc_dma_get_port_idx(kcontrol); - if (ch_num < 0) { + if (ch_num < 0 || ch_num >= CDC_DMA_RX_MAX) { pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); return ch_num; } @@ -2363,7 +2363,7 @@ static int cdc_dma_rx_format_put(struct snd_kcontrol *kcontrol, int rc = 0; int ch_num = cdc_dma_get_port_idx(kcontrol); - if (ch_num < 0) { + if (ch_num < 0 || ch_num >= CDC_DMA_RX_MAX) { pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); return ch_num; } @@ -2498,7 +2498,7 @@ static int cdc_dma_rx_sample_rate_get(struct snd_kcontrol *kcontrol, { int ch_num = cdc_dma_get_port_idx(kcontrol); - if (ch_num < 0) { + if (ch_num < 0 || ch_num >= CDC_DMA_RX_MAX) { pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); return ch_num; } @@ -2516,7 +2516,7 @@ static int cdc_dma_rx_sample_rate_put(struct snd_kcontrol *kcontrol, { int ch_num = cdc_dma_get_port_idx(kcontrol); - if (ch_num < 0) { + if (ch_num < 0 || ch_num >= CDC_DMA_RX_MAX) { pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); return ch_num; } -- GitLab From e456c2ca4100831dfd189a74f1a3211306e1d5f5 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 5 Mar 2019 07:08:45 +0530 Subject: [PATCH 0885/1645] ASoC: boloero: Add DAPM widgets for soundwire clock Add DAPM widgets for soundwire clock on Tx path and VA path to enable the desired clock source based on the usecase. Change-Id: I48b04e63317cefd8bf12d58b002efb37087f8dc2 Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/tx-macro.c | 56 +++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 58f3689276da..6b6c52d15946 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -151,6 +151,8 @@ struct tx_macro_priv { struct platform_device *pdev_child_devices [TX_MACRO_CHILD_DEVICES_MAX]; int child_count; + int tx_swr_clk_cnt; + int va_swr_clk_cnt; }; static bool tx_macro_get_data(struct snd_soc_component *component, @@ -245,6 +247,44 @@ static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv, return ret; } +static int tx_macro_va_swr_clk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + if (SND_SOC_DAPM_EVENT_ON(event)) + ++tx_priv->va_swr_clk_cnt; + if (SND_SOC_DAPM_EVENT_OFF(event)) + --tx_priv->va_swr_clk_cnt; + + return 0; +} + +static int tx_macro_tx_swr_clk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + if (SND_SOC_DAPM_EVENT_ON(event)) + ++tx_priv->tx_swr_clk_cnt; + if (SND_SOC_DAPM_EVENT_OFF(event)) + --tx_priv->tx_swr_clk_cnt; + + return 0; +} + static int tx_macro_mclk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -1156,6 +1196,14 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0, tx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, + tx_macro_tx_swr_clk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, + tx_macro_va_swr_clk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; static const struct snd_soc_dapm_route tx_audio_map[] = { @@ -1203,6 +1251,7 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX DMIC MUX0", "DMIC7", "TX DMIC7"}, {"TX DEC0 MUX", "SWR_MIC", "TX SMIC MUX0"}, + {"TX SMIC MUX0", NULL, "TX_SWR_CLK"}, {"TX SMIC MUX0", "ADC0", "TX SWR_ADC0"}, {"TX SMIC MUX0", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX0", "ADC2", "TX SWR_ADC2"}, @@ -1228,6 +1277,7 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX DMIC MUX1", "DMIC7", "TX DMIC7"}, {"TX DEC1 MUX", "SWR_MIC", "TX SMIC MUX1"}, + {"TX SMIC MUX1", NULL, "TX_SWR_CLK"}, {"TX SMIC MUX1", "ADC0", "TX SWR_ADC0"}, {"TX SMIC MUX1", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX1", "ADC2", "TX SWR_ADC2"}, @@ -1253,6 +1303,7 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX DMIC MUX2", "DMIC7", "TX DMIC7"}, {"TX DEC2 MUX", "SWR_MIC", "TX SMIC MUX2"}, + {"TX SMIC MUX2", NULL, "TX_SWR_CLK"}, {"TX SMIC MUX2", "ADC0", "TX SWR_ADC0"}, {"TX SMIC MUX2", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX2", "ADC2", "TX SWR_ADC2"}, @@ -1278,6 +1329,7 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX DMIC MUX3", "DMIC7", "TX DMIC7"}, {"TX DEC3 MUX", "SWR_MIC", "TX SMIC MUX3"}, + {"TX SMIC MUX3", NULL, "TX_SWR_CLK"}, {"TX SMIC MUX3", "ADC0", "TX SWR_ADC0"}, {"TX SMIC MUX3", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX3", "ADC2", "TX SWR_ADC2"}, @@ -1303,6 +1355,7 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX DMIC MUX4", "DMIC7", "TX DMIC7"}, {"TX DEC4 MUX", "SWR_MIC", "TX SMIC MUX4"}, + {"TX SMIC MUX4", NULL, "TX_SWR_CLK"}, {"TX SMIC MUX4", "ADC0", "TX SWR_ADC0"}, {"TX SMIC MUX4", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX4", "ADC2", "TX SWR_ADC2"}, @@ -1328,6 +1381,7 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX DMIC MUX5", "DMIC7", "TX DMIC7"}, {"TX DEC5 MUX", "SWR_MIC", "TX SMIC MUX5"}, + {"TX SMIC MUX5", NULL, "TX_SWR_CLK"}, {"TX SMIC MUX5", "ADC0", "TX SWR_ADC0"}, {"TX SMIC MUX5", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX5", "ADC2", "TX SWR_ADC2"}, @@ -1353,6 +1407,7 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX DMIC MUX6", "DMIC7", "TX DMIC7"}, {"TX DEC6 MUX", "SWR_MIC", "TX SMIC MUX6"}, + {"TX SMIC MUX6", NULL, "TX_SWR_CLK"}, {"TX SMIC MUX6", "ADC0", "TX SWR_ADC0"}, {"TX SMIC MUX6", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX6", "ADC2", "TX SWR_ADC2"}, @@ -1378,6 +1433,7 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX DMIC MUX7", "DMIC7", "TX DMIC7"}, {"TX DEC7 MUX", "SWR_MIC", "TX SMIC MUX7"}, + {"TX SMIC MUX7", NULL, "TX_SWR_CLK"}, {"TX SMIC MUX7", "ADC0", "TX SWR_ADC0"}, {"TX SMIC MUX7", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX7", "ADC2", "TX SWR_ADC2"}, -- GitLab From 281bd20437e6c5da04fa972b3a57503010e3e82b Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 1 Apr 2019 18:12:06 +0800 Subject: [PATCH 0886/1645] asoc: wcd938x: stop mbhc during ssr down Stop mbhc operations during ssr down to cancel any pending detection sequences. Change-Id: Iff054cf8b3099959a1be561bd937057258f57b81 Signed-off-by: Meng Wang --- asoc/codecs/wcd938x/wcd938x-mbhc.c | 28 ++++++++++++++++++++++++++-- asoc/codecs/wcd938x/wcd938x-mbhc.h | 8 +++++++- asoc/codecs/wcd938x/wcd938x.c | 2 ++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x-mbhc.c b/asoc/codecs/wcd938x/wcd938x-mbhc.c index 6d9f500378bf..2516943ded62 100644 --- a/asoc/codecs/wcd938x/wcd938x-mbhc.c +++ b/asoc/codecs/wcd938x/wcd938x-mbhc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -956,6 +956,31 @@ void wcd938x_mbhc_hs_detect_exit(struct snd_soc_component *component) } EXPORT_SYMBOL(wcd938x_mbhc_hs_detect_exit); +/* + * wcd938x_mbhc_ssr_down: stop mbhc during + * wcd938x subsystem restart + * mbhc: pointer to wcd937x_mbhc structure + * component: handle to snd_soc_component * + */ +void wcd938x_mbhc_ssr_down(struct wcd938x_mbhc *mbhc, + struct snd_soc_component *component) +{ + struct wcd_mbhc *wcd_mbhc = NULL; + + if (!mbhc || !component) + return; + + wcd_mbhc = &mbhc->wcd_mbhc; + if (!wcd_mbhc) { + dev_err(component->dev, "%s: wcd_mbhc is NULL\n", __func__); + return; + } + + wcd938x_mbhc_hs_detect_exit(component); + wcd_mbhc_deinit(wcd_mbhc); +} +EXPORT_SYMBOL(wcd938x_mbhc_ssr_down); + /* * wcd938x_mbhc_post_ssr_init: initialize mbhc for * wcd938x post subsystem restart @@ -979,7 +1004,6 @@ int wcd938x_mbhc_post_ssr_init(struct wcd938x_mbhc *mbhc, return -EINVAL; } - wcd_mbhc_deinit(wcd_mbhc); ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb, &intr_ids, wcd_mbhc_registers, WCD938X_ZDET_SUPPORTED); if (ret) { diff --git a/asoc/codecs/wcd938x/wcd938x-mbhc.h b/asoc/codecs/wcd938x/wcd938x-mbhc.h index cf4c60e0ae6d..e33a92c20e00 100644 --- a/asoc/codecs/wcd938x/wcd938x-mbhc.h +++ b/asoc/codecs/wcd938x/wcd938x-mbhc.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #ifndef __WCD938X_MBHC_H__ #define __WCD938X_MBHC_H__ @@ -20,6 +20,8 @@ extern void wcd938x_mbhc_hs_detect_exit(struct snd_soc_component *component); extern int wcd938x_mbhc_hs_detect(struct snd_soc_component *component, struct wcd_mbhc_config *mbhc_cfg); extern void wcd938x_mbhc_deinit(struct snd_soc_component *component); +extern void wcd938x_mbhc_ssr_down(struct wcd938x_mbhc *mbhc, + struct snd_soc_component *component); extern int wcd938x_mbhc_post_ssr_init(struct wcd938x_mbhc *mbhc, struct snd_soc_component *component); extern int wcd938x_mbhc_get_impedance(struct wcd938x_mbhc *wcd938x_mbhc, @@ -43,6 +45,10 @@ static inline int wcd938x_mbhc_hs_detect(struct snd_soc_component *component, static inline void wcd938x_mbhc_deinit(struct snd_soc_component *component) { } +static inline void wcd938x_mbhc_ssr_down(struct wcd938x_mbhc *mbhc, + struct snd_soc_component *component) +{ +} static inline int wcd938x_mbhc_post_ssr_init(struct wcd938x_mbhc *mbhc, struct snd_soc_component *component) { diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 882feff26bf7..4e8ab32e9e17 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1516,6 +1516,8 @@ static int wcd938x_event_notify(struct notifier_block *block, 0x80, 0x00); break; case BOLERO_WCD_EVT_SSR_DOWN: + mbhc = &wcd938x->mbhc->wcd_mbhc; + wcd938x_mbhc_ssr_down(wcd938x->mbhc, component); wcd938x_reset_low(wcd938x->dev); break; case BOLERO_WCD_EVT_SSR_UP: -- GitLab From e59703ce4e01455a21436cd12de54a943fb661cb Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 12 Mar 2019 10:06:00 +0800 Subject: [PATCH 0887/1645] asoc: bolero: remove mutex_lock in bolero_runtime_suspend There can be deadlock between __bolero_reg_read/write and bolero_runtime_suspend. Remove the mutex_lock in bolero_runtime_suspend to avoid deadlock. Change-Id: I712b9f24adeddda8899b39f90291394965443163 Signed-off-by: Meng Wang --- asoc/codecs/bolero/bolero-cdc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 7bf629580901..217fa5f41d10 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -1049,13 +1049,11 @@ int bolero_runtime_suspend(struct device *dev) { struct bolero_priv *priv = dev_get_drvdata(dev->parent); - mutex_lock(&priv->clk_lock); if (priv->lpass_core_hw_vote != NULL) clk_disable_unprepare(priv->lpass_core_hw_vote); else dev_dbg(dev, "%s: Invalid lpass core hw node\n", __func__); - mutex_unlock(&priv->clk_lock); return 0; } EXPORT_SYMBOL(bolero_runtime_suspend); -- GitLab From df38c3eb18c0bda3c665bc19980d7f66414a7b3a Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 11 Mar 2019 17:10:23 +0530 Subject: [PATCH 0888/1645] soc: swr: Add wakeup source for swr device Voice call over headset does not disconnect on button press while device is in suspend state. This is because inband interrupt is not made wakeup capable. Make inband interrupt for swr tx as wakeup capable. Also add wakeup source for swr device. Change-Id: I5f2751672675bc8d62c4d2bfbbd651e640723d52 Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 23 ++++++++++++++++++++++- soc/swr-mstr-ctrl.h | 3 ++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 8d82ff1ec775..722501ab1f25 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2055,6 +2055,7 @@ static int swrm_probe(struct platform_device *pdev) swrm->slave_status = 0; swrm->num_rx_chs = 0; swrm->clk_ref_count = 0; + swrm->swr_irq_wakeup_capable = 0; swrm->mclk_freq = MCLK_FREQ; swrm->dev_up = true; swrm->state = SWR_MSTR_UP; @@ -2107,7 +2108,15 @@ static int swrm_probe(struct platform_device *pdev) } } - + /* Make inband tx interrupts as wakeup capable for slave irq */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,swr-mstr-irq-wakeup-capable", + &swrm->swr_irq_wakeup_capable); + if (ret) + dev_dbg(swrm->dev, "%s: swrm irq wakeup capable not defined\n", + __func__); + if (swrm->swr_irq_wakeup_capable) + irq_set_irq_wake(swrm->irq, 1); ret = swr_register_master(&swrm->master); if (ret) { dev_err(&pdev->dev, "%s: error adding swr master\n", __func__); @@ -2152,6 +2161,13 @@ static int swrm_probe(struct platform_device *pdev) (void *) "swrm_reg_dump", &swrm_debug_ops); } + + ret = device_init_wakeup(swrm->dev, true); + if (ret) { + dev_err(swrm->dev, "Device wakeup init failed: %d\n", ret); + goto err_irq_wakeup_fail; + } + pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_active(&pdev->dev); @@ -2163,6 +2179,8 @@ static int swrm_probe(struct platform_device *pdev) msm_aud_evt_register_client(&swrm->event_notifier); return 0; +err_irq_wakeup_fail: + device_init_wakeup(swrm->dev, false); err_mstr_fail: if (swrm->reg_irq) swrm->reg_irq(swrm->handle, swr_mstr_interrupt, @@ -2194,11 +2212,14 @@ static int swrm_remove(struct platform_device *pdev) free_irq(swrm->irq, swrm); else if (swrm->wake_irq > 0) free_irq(swrm->wake_irq, swrm); + if (swrm->swr_irq_wakeup_capable) + irq_set_irq_wake(swrm->irq, 0); cancel_work_sync(&swrm->wakeup_work); pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); swr_unregister_master(&swrm->master); msm_aud_evt_unregister_client(&swrm->event_notifier); + device_init_wakeup(swrm->dev, false); mutex_destroy(&swrm->mlock); mutex_destroy(&swrm->reslock); mutex_destroy(&swrm->iolock); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index fab66c39d26c..6ae3febfbce0 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #ifndef _SWR_WCD_CTRL_H @@ -155,6 +155,7 @@ struct swr_mstr_ctrl { u32 intr_mask; struct port_params **port_param; u8 num_usecase; + u32 swr_irq_wakeup_capable; }; #endif /* _SWR_WCD_CTRL_H */ -- GitLab From e8e53825d5781e3a90d66c93c16b83fea3c78b50 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 18 Mar 2019 10:49:50 +0800 Subject: [PATCH 0889/1645] asoc: kona: add afe loopback support in machine driver Add machine driver change for AFE RX to TX loopback. Change-Id: Icd77092867e93bd1da76b1ba22c61091a2d1c8f4 Signed-off-by: Meng Wang --- asoc/kona.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index fd5c9a71250b..170f1016b673 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -140,6 +140,10 @@ enum { SLIM_TX_MAX, }; +enum { + AFE_LOOPBACK_TX_IDX = 0, + AFE_LOOPBACK_TX_IDX_MAX, +}; struct msm_asoc_mach_data { struct snd_info_entry *codec_root; int usbc_en2_gpio; /* used by gpio driver API */ @@ -370,6 +374,10 @@ static struct dev_config cdc_dma_tx_cfg[] = { [VA_CDC_DMA_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, }; +static struct dev_config afe_loopback_tx_cfg[] = { + [AFE_LOOPBACK_TX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", "S32_LE"}; static char const *ch_text[] = {"Two", "Three", "Four", "Five", @@ -420,6 +428,7 @@ static char const *bt_sample_rate_rx_text[] = {"KHZ_8", "KHZ_16", static char const *bt_sample_rate_tx_text[] = {"KHZ_8", "KHZ_16", "KHZ_44P1", "KHZ_48", "KHZ_88P2", "KHZ_96"}; +static const char *const afe_loopback_tx_ch_text[] = {"One", "Two"}; static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); @@ -526,6 +535,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_rx, bt_sample_rate_rx_text); static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_tx, bt_sample_rate_tx_text); +static SOC_ENUM_SINGLE_EXT_DECL(afe_loopback_tx_chs, afe_loopback_tx_ch_text); static bool is_initial_boot; static bool codec_reg_done; @@ -808,6 +818,27 @@ static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol, usb_tx_cfg.sample_rate); return 0; } +static int afe_loopback_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: afe_loopback_tx_ch = %d\n", __func__, + afe_loopback_tx_cfg[0].channels); + ucontrol->value.enumerated.item[0] = + afe_loopback_tx_cfg[0].channels - 1; + + return 0; +} + +static int afe_loopback_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + afe_loopback_tx_cfg[0].channels = + ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: afe_loopback_tx_ch = %d\n", __func__, + afe_loopback_tx_cfg[0].channels); + + return 1; +} static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -3299,6 +3330,8 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("BT SampleRate TX", bt_sample_rate_tx, msm_bt_sample_rate_tx_get, msm_bt_sample_rate_tx_put), + SOC_ENUM_EXT("AFE_LOOPBACK_TX Channels", afe_loopback_tx_chs, + afe_loopback_tx_ch_get, afe_loopback_tx_ch_put), }; static const struct snd_kcontrol_new msm_snd_controls[] = { @@ -3339,7 +3372,7 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - int idx, rc = 0; + int idx = 0, rc = 0; pr_debug("%s: format = %d, rate = %d\n", __func__, params_format(params), params_rate(params)); @@ -3578,6 +3611,14 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, slim_tx_cfg[SLIM_TX_7].channels; break; + case MSM_BACKEND_DAI_AFE_LOOPBACK_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + afe_loopback_tx_cfg[idx].bit_format); + rate->min = rate->max = afe_loopback_tx_cfg[idx].sample_rate; + channels->min = channels->max = + afe_loopback_tx_cfg[idx].channels; + break; + default: rate->min = rate->max = SAMPLING_RATE_48KHZ; break; @@ -5475,6 +5516,23 @@ static struct snd_soc_dai_link msm_va_cdc_dma_be_dai_links[] = { }, }; +static struct snd_soc_dai_link msm_afe_rxtx_lb_be_dai_link[] = { + { + .name = LPASS_BE_AFE_LOOPBACK_TX, + .stream_name = "AFE Loopback Capture", + .cpu_dai_name = "msm-dai-q6-dev.24577", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + static struct snd_soc_dai_link msm_kona_dai_links[ ARRAY_SIZE(msm_common_dai_links) + ARRAY_SIZE(msm_bolero_fe_dai_links) + @@ -5486,7 +5544,8 @@ static struct snd_soc_dai_link msm_kona_dai_links[ ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links) + ARRAY_SIZE(msm_va_cdc_dma_be_dai_links) + ARRAY_SIZE(ext_disp_be_dai_link) + - ARRAY_SIZE(msm_wcn_be_dai_links)]; + ARRAY_SIZE(msm_wcn_be_dai_links) + + ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link)]; static int msm_populate_dai_link_component_of_node( struct snd_soc_card *card) @@ -5792,6 +5851,15 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) total_links += ARRAY_SIZE(msm_wcn_be_dai_links); } + rc = of_property_read_u32(dev->of_node, "qcom,afe-rxtx-lb", + &val); + if (!rc && val) { + memcpy(msm_kona_dai_links + total_links, + msm_afe_rxtx_lb_be_dai_link, + sizeof(msm_afe_rxtx_lb_be_dai_link)); + total_links += + ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link); + } dailink = msm_kona_dai_links; } else if(!strcmp(match->data, "stub_codec")) { card = &snd_soc_card_stub_msm; -- GitLab From 038cb2d3d877c4bd6cf6110dc44be382d39887f4 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 2 Apr 2019 15:28:11 +0530 Subject: [PATCH 0890/1645] dsp: q6usm: Release spinlock before return if invalid payload size Release spinlock in EVENT_READ_DONE before return if payload size is invalid. Change-Id: I0fe4f841ce73ecfc30fe70334e203443e5e2cb28 Signed-off-by: Vatsal Bucha --- dsp/q6usm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dsp/q6usm.c b/dsp/q6usm.c index 70c3a6b7721a..cd024fce8139 100644 --- a/dsp/q6usm.c +++ b/dsp/q6usm.c @@ -628,6 +628,8 @@ static int32_t q6usm_callback(struct apr_client_data *data, void *priv) (sizeof(uint32_t)*(READDONE_IDX_STATUS + 1))) { pr_err("%s: Invalid payload size for READDONE[%d]\n", __func__, data->payload_size); + spin_unlock_irqrestore(&port->dsp_lock, + dsp_flags); return -EINVAL; } if (payload[READDONE_IDX_STATUS]) { -- GitLab From 05588601ac94836495d6b343b4f87882d13435db Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 1 Apr 2019 12:07:14 -0700 Subject: [PATCH 0891/1645] asoc: wcd938x: Add default cases for port mapping Return error in case of wrong path being selected for port mapping and port params functions. Change-Id: I5d66a9cd32e9c8e6d8ebac0ea073b1a1762407b6 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/wcd938x-slave.c | 5 +++++ asoc/codecs/wcd938x/wcd938x.c | 14 +++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x-slave.c b/asoc/codecs/wcd938x/wcd938x-slave.c index b7c02306cb99..ec42b0d471ee 100644 --- a/asoc/codecs/wcd938x/wcd938x-slave.c +++ b/asoc/codecs/wcd938x/wcd938x-slave.c @@ -22,6 +22,11 @@ static int wcd938x_slave_bind(struct device *dev, uint8_t devnum = 0; struct swr_device *pdev = to_swr_device(dev); + if (!pdev) { + pr_err("%s: invalid swr device handle\n", __func__); + return -EINVAL; + } + ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum); if (ret) { dev_dbg(&pdev->dev, diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 882feff26bf7..0a20bfcf43e1 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -177,7 +177,7 @@ static int wcd938x_set_port_params(struct snd_soc_component *component, u8 *port_type, u8 path) { int i, j; - u8 num_ports; + u8 num_ports = 0; struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT]; struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); @@ -190,6 +190,10 @@ static int wcd938x_set_port_params(struct snd_soc_component *component, map = &wcd938x->tx_port_mapping; num_ports = wcd938x->num_tx_ports; break; + default: + dev_err(component->dev, "%s Invalid path selected %u\n", + __func__, path); + return -EINVAL; } for (i = 0; i <= num_ports; i++) { @@ -217,11 +221,11 @@ static int wcd938x_parse_port_mapping(struct device *dev, char *prop, u8 path) { u32 *dt_array, map_size, map_length; - u32 port_num, ch_mask, ch_rate, old_port_num = 0; + u32 port_num = 0, ch_mask, ch_rate, old_port_num = 0; u32 slave_port_type, master_port_type; u32 i, ch_iter = 0; int ret = 0; - u8 *num_ports; + u8 *num_ports = NULL; struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT]; struct wcd938x_priv *wcd938x = dev_get_drvdata(dev); @@ -234,6 +238,10 @@ static int wcd938x_parse_port_mapping(struct device *dev, map = &wcd938x->tx_port_mapping; num_ports = &wcd938x->num_tx_ports; break; + default: + dev_err(dev, "%s Invalid path selected %u\n", + __func__, path); + return -EINVAL; } if (!of_find_property(dev->of_node, prop, -- GitLab From d77def6c1fb50e6952d276a768b604f2e3ad7411 Mon Sep 17 00:00:00 2001 From: kunleiz Date: Mon, 4 Mar 2019 18:51:05 +0800 Subject: [PATCH 0892/1645] dsp: q6core: validate payload size before memory copy Payload size is not checked before memory copy. Check payload size to avoid out-of-boundary memory access. Change-Id: I07857564d4e8ce415df3810b25f0e9e17a60993d Signed-off-by: Kunlei Zhang --- dsp/q6core.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/dsp/q6core.c b/dsp/q6core.c index 283f785f66f8..3f15f10ecfdc 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -194,7 +194,7 @@ int q6core_send_uevent(struct audio_uevent_data *uevent_data, char *event) } EXPORT_SYMBOL(q6core_send_uevent); -static int parse_fwk_version_info(uint32_t *payload) +static int parse_fwk_version_info(uint32_t *payload, uint16_t payload_size) { size_t ver_size; int num_services; @@ -207,6 +207,11 @@ static int parse_fwk_version_info(uint32_t *payload) * Based on this info, we copy the payload into core * avcs version info structure. */ + if (payload_size < 5 * sizeof(uint32_t)) { + pr_err("%s: payload has invalid size %d\n", + __func__, payload_size); + return -EINVAL; + } num_services = payload[4]; if (num_services > VSS_MAX_AVCS_NUM_SERVICES) { pr_err("%s: num_services: %d greater than max services: %d\n", @@ -221,6 +226,12 @@ static int parse_fwk_version_info(uint32_t *payload) ver_size = sizeof(struct avcs_get_fwk_version) + num_services * sizeof(struct avs_svc_api_info); + if (payload_size < ver_size) { + pr_err("%s: payload has invalid size %d, expected size %zu\n", + __func__, payload_size, ver_size); + return -EINVAL; + } + q6core_lcl.q6core_avcs_ver_info.ver_info = kzalloc(ver_size, GFP_ATOMIC); if (q6core_lcl.q6core_avcs_ver_info.ver_info == NULL) @@ -257,6 +268,12 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) payload1 = data->payload; + if (data->payload_size < 2 * sizeof(uint32_t)) { + pr_err("%s: payload has invalid size %d\n", + __func__, data->payload_size); + return -EINVAL; + } + switch (payload1[0]) { case AVCS_CMD_SHARED_MEM_UNMAP_REGIONS: @@ -347,6 +364,11 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) break; } case AVCS_CMDRSP_SHARED_MEM_MAP_REGIONS: + if (data->payload_size < sizeof(uint32_t)) { + pr_err("%s: payload has invalid size %d\n", + __func__, data->payload_size); + return -EINVAL; + } payload1 = data->payload; pr_debug("%s: AVCS_CMDRSP_SHARED_MEM_MAP_REGIONS handle %d\n", __func__, payload1[0]); @@ -361,6 +383,11 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) } break; case AVCS_CMDRSP_CREATE_LPASS_NPA_CLIENT: + if (data->payload_size < 2 * sizeof(uint32_t)) { + pr_err("%s: payload has invalid size %d\n", + __func__, data->payload_size); + return -EINVAL; + } payload1 = data->payload; pr_debug("%s: AVCS_CMDRSP_CREATE_LPASS_NPA_CLIENT handle %d\n", __func__, payload1[1]); @@ -370,6 +397,11 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) wake_up(&q6core_lcl.lpass_npa_rsc_wait); break; case AVCS_CMDRSP_ADSP_EVENT_GET_STATE: + if (data->payload_size < sizeof(uint32_t)) { + pr_err("%s: payload has invalid size %d\n", + __func__, data->payload_size); + return -EINVAL; + } payload1 = data->payload; q6core_lcl.param = payload1[0]; pr_debug("%s: Received ADSP get state response 0x%x\n", @@ -380,6 +412,11 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) wake_up(&q6core_lcl.bus_bw_req_wait); break; case AVCS_CMDRSP_GET_LICENSE_VALIDATION_RESULT: + if (data->payload_size < sizeof(uint32_t)) { + pr_err("%s: payload has invalid size %d\n", + __func__, data->payload_size); + return -EINVAL; + } payload1 = data->payload; pr_debug("%s: cmd = LICENSE_VALIDATION_RESULT, result = 0x%x\n", __func__, payload1[0]); @@ -392,7 +429,7 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) pr_debug("%s: Received AVCS_CMDRSP_GET_FWK_VERSION\n", __func__); payload1 = data->payload; - ret = parse_fwk_version_info(payload1); + ret = parse_fwk_version_info(payload1, data->payload_size); if (ret < 0) { q6core_lcl.adsp_status = ret; pr_err("%s: Failed to parse payload:%d\n", -- GitLab From 4965b8d670f842cf12322602468f0df83bc75a00 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Sat, 16 Mar 2019 18:26:22 -0700 Subject: [PATCH 0893/1645] dsp: adm: modify adm callback payload size checks Validate payload size before accessing data from ADSP. Modify payload size checks to accommodate for variable payloads, payload size vary from size of one integer to many based on opcode and other variables. CRs-Fixed: 2380694 Change-Id: Ic5e0eb72441da8f29cf645968c9df09e7803701a Signed-off-by: Vignesh Kulothungan --- dsp/q6adm.c | 54 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index f081065a6738..8848b2290c4d 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -1510,7 +1510,7 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) } adm_callback_debug_print(data); - if (data->payload_size) { + if (data->payload_size >= sizeof(uint32_t)) { copp_idx = (data->token) & 0XFF; port_idx = ((data->token) >> 16) & 0xFF; client_id = ((data->token) >> 8) & 0xFF; @@ -1530,13 +1530,20 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) return 0; } if (data->opcode == APR_BASIC_RSP_RESULT) { - if (data->payload_size < (2 * sizeof(uint32_t))) { - pr_err("%s: Invalid payload size %d\n", __func__, - data->payload_size); - return 0; - } pr_debug("%s: APR_BASIC_RSP_RESULT id 0x%x\n", __func__, payload[0]); + + if (!((client_id != ADM_CLIENT_ID_SOURCE_TRACKING) && + ((payload[0] == ADM_CMD_SET_PP_PARAMS_V5) || + (payload[0] == ADM_CMD_SET_PP_PARAMS_V6)))) { + if (data->payload_size < + (2 * sizeof(uint32_t))) { + pr_err("%s: Invalid payload size %d\n", + __func__, data->payload_size); + return 0; + } + } + if (payload[1] != 0) { pr_err("%s: cmd = 0x%x returned error = 0x%x\n", __func__, payload[0], payload[1]); @@ -1718,21 +1725,28 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST_V2: pr_debug("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST\n", __func__); - num_modules = payload[1]; - pr_debug("%s: Num modules %d\n", __func__, num_modules); - if (payload[0]) { - pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST, error = %d\n", - __func__, payload[0]); - } else if (num_modules > MAX_MODULES_IN_TOPO) { - pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST invalid num modules received, num modules = %d\n", - __func__, num_modules); + if (data->payload_size >= (2 * sizeof(uint32_t))) { + num_modules = payload[1]; + pr_debug("%s: Num modules %d\n", __func__, + num_modules); + if (payload[0]) { + pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST, error = %d\n", + __func__, payload[0]); + } else if (num_modules > MAX_MODULES_IN_TOPO) { + pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST invalid num modules received, num modules = %d\n", + __func__, num_modules); + } else { + ret = adm_process_get_topo_list_response( + data->opcode, copp_idx, + num_modules, payload, + data->payload_size); + if (ret) + pr_err("%s: Failed to process get topo modules list response, error %d\n", + __func__, ret); + } } else { - ret = adm_process_get_topo_list_response( - data->opcode, copp_idx, num_modules, - payload, data->payload_size); - if (ret) - pr_err("%s: Failed to process get topo modules list response, error %d\n", - __func__, ret); + pr_err("%s: Invalid payload size %d\n", + __func__, data->payload_size); } atomic_set(&this_adm.copp.stat[port_idx][copp_idx], payload[0]); -- GitLab From 66d6fd1364243ab37b63147e6fc4807ed3d9f1e0 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 27 Mar 2019 17:34:48 +0530 Subject: [PATCH 0894/1645] soundwire: Vote for LPASS HW Core before soundwire register access Vote for LPASS HW core before soundwire register access to avoid register access violations. Change-Id: Ie7ff73bbab64825bf07736f11ef9685e732fc8ae Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 32 ++++++++++++++++++++++++++++++++ soc/swr-mstr-ctrl.h | 1 + 2 files changed, 33 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 8d82ff1ec775..26965a3ee973 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1441,6 +1441,8 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) } mutex_lock(&swrm->reslock); + if (swrm->lpass_core_hw_vote) + clk_prepare_enable(swrm->lpass_core_hw_vote); swrm_clk_request(swrm, true); mutex_unlock(&swrm->reslock); @@ -1608,6 +1610,8 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) mutex_lock(&swrm->reslock); swrm_clk_request(swrm, false); + if (swrm->lpass_core_hw_vote) + clk_disable_unprepare(swrm->lpass_core_hw_vote); mutex_unlock(&swrm->reslock); swrm_unlock_sleep(swrm); return ret; @@ -1897,6 +1901,7 @@ static int swrm_probe(struct platform_device *pdev) u32 i, num_ports, port_num, port_type, ch_mask; u32 *temp, map_size, map_length, ch_iter = 0, old_port_num = 0; int ret = 0; + struct clk *lpass_core_hw_vote = NULL; /* Allocate soundwire master driver structure */ swrm = devm_kzalloc(&pdev->dev, sizeof(struct swr_mstr_ctrl), @@ -2136,6 +2141,17 @@ static int swrm_probe(struct platform_device *pdev) if (pdev->dev.of_node) of_register_swr_devices(&swrm->master); + /* Register LPASS core hw vote */ + lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote"); + if (IS_ERR(lpass_core_hw_vote)) { + ret = PTR_ERR(lpass_core_hw_vote); + dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", + __func__, "lpass_core_hw_vote", ret); + lpass_core_hw_vote = NULL; + ret = 0; + } + swrm->lpass_core_hw_vote = lpass_core_hw_vote; + dbgswrm = swrm; debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0); if (!IS_ERR(debugfs_swrm_dent)) { @@ -2236,6 +2252,12 @@ static int swrm_runtime_resume(struct device *dev) __func__, swrm->state); mutex_lock(&swrm->reslock); + if (swrm->lpass_core_hw_vote) + ret = clk_prepare_enable(swrm->lpass_core_hw_vote); + if (ret < 0) + dev_err(dev, "%s:lpass core hw enable failed\n", + __func__); + if ((swrm->state == SWR_MSTR_DOWN) || (swrm->state == SWR_MSTR_SSR && swrm->dev_up)) { if (swrm->clk_stop_mode0_supp) { @@ -2272,6 +2294,8 @@ static int swrm_runtime_resume(struct device *dev) swrm->state = SWR_MSTR_UP; } exit: + if (swrm->lpass_core_hw_vote) + clk_disable_unprepare(swrm->lpass_core_hw_vote); pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer); mutex_unlock(&swrm->reslock); return ret; @@ -2292,6 +2316,12 @@ static int swrm_runtime_suspend(struct device *dev) mutex_lock(&swrm->force_down_lock); current_state = swrm->state; mutex_unlock(&swrm->force_down_lock); + if (swrm->lpass_core_hw_vote) + ret = clk_prepare_enable(swrm->lpass_core_hw_vote); + if (ret < 0) + dev_err(dev, "%s:lpass core hw enable failed\n", + __func__); + if ((current_state == SWR_MSTR_UP) || (current_state == SWR_MSTR_SSR)) { @@ -2337,6 +2367,8 @@ static int swrm_runtime_suspend(struct device *dev) if (current_state != SWR_MSTR_SSR) swrm->state = SWR_MSTR_DOWN; exit: + if (swrm->lpass_core_hw_vote) + clk_disable_unprepare(swrm->lpass_core_hw_vote); mutex_unlock(&swrm->reslock); return ret; } diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index fab66c39d26c..96aa048e0ecd 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -154,6 +154,7 @@ struct swr_mstr_ctrl { int wlock_holders; u32 intr_mask; struct port_params **port_param; + struct clk *lpass_core_hw_vote; u8 num_usecase; }; -- GitLab From 15e78317836571543b7c720952cda2aebb2c5748 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 30 Jan 2019 21:47:39 +0530 Subject: [PATCH 0895/1645] ASoC: wcd-mbhc: Remove hardcoding of hphl and gnd swh to NC for analog USBC Read hphl_swh and gnd_swh from dtsi instead of hardcoding to NC for every USBC target. Some platforms use NO switch. Change-Id: I3dca6c7450579e8feb5d80c1340495958683a026 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd-mbhc-v2.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 1159b1128a02..6a85c8232770 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -1358,9 +1358,6 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) * by an external source */ if (mbhc->mbhc_cfg->enable_usbc_analog) { - mbhc->hphl_swh = 0; - mbhc->gnd_swh = 0; - if (mbhc->mbhc_cb->hph_pull_up_control_v2) mbhc->mbhc_cb->hph_pull_up_control_v2(component, HS_PULLUP_I_OFF); -- GitLab From 5d45f4c865153ab4a52a42a9cc42bb899600e4ed Mon Sep 17 00:00:00 2001 From: Vidyakumar Athota Date: Sun, 10 Mar 2019 22:35:07 -0700 Subject: [PATCH 0896/1645] asoc: codecs: bolero: add clk resource manager driver Add Bolero clock resource manager driver to handle/manage bolero clocks for all the concurrency usecases like record + voice activation. Change-Id: I970a05d96fc9060b44bfe670d465f0b9d72cc53b Signed-off-by: Vidyakumar Athota --- asoc/codecs/bolero/Kbuild | 1 + asoc/codecs/bolero/bolero-cdc.c | 361 ++++++++-------- asoc/codecs/bolero/bolero-cdc.h | 27 +- asoc/codecs/bolero/bolero-clk-rsc.c | 613 ++++++++++++++++++++++++++++ asoc/codecs/bolero/bolero-clk-rsc.h | 42 ++ asoc/codecs/bolero/internal.h | 5 +- asoc/codecs/bolero/rx-macro.c | 129 +++--- asoc/codecs/bolero/tx-macro.c | 70 +--- asoc/codecs/bolero/va-macro.c | 110 ++--- asoc/codecs/bolero/wsa-macro.c | 83 ++-- 10 files changed, 964 insertions(+), 477 deletions(-) create mode 100644 asoc/codecs/bolero/bolero-clk-rsc.c create mode 100644 asoc/codecs/bolero/bolero-clk-rsc.h diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild index f01f523dcfb0..25d788170f4c 100644 --- a/asoc/codecs/bolero/Kbuild +++ b/asoc/codecs/bolero/Kbuild @@ -70,6 +70,7 @@ ifdef CONFIG_SND_SOC_BOLERO BOLERO_OBJS += bolero-cdc-utils.o BOLERO_OBJS += bolero-cdc-regmap.o BOLERO_OBJS += bolero-cdc-tables.o + BOLERO_OBJS += bolero-clk-rsc.o endif ifdef CONFIG_WSA_MACRO diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 217fa5f41d10..d805126b2254 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -16,6 +16,7 @@ #include #include "bolero-cdc.h" #include "internal.h" +#include "bolero-clk-rsc.h" #define DRV_NAME "bolero_codec" @@ -93,43 +94,44 @@ static void bolero_ahb_read_device(char __iomem *io_base, static int __bolero_reg_read(struct bolero_priv *priv, u16 macro_id, u16 reg, u8 *val) { - int ret = -EINVAL; - u16 current_mclk_mux_macro; + int ret = 0; mutex_lock(&priv->clk_lock); if (!priv->dev_up) { dev_dbg_ratelimited(priv->dev, "%s: SSR in progress, exit\n", __func__); - goto err; + ret = -EINVAL; + goto ssr_err; } if (priv->macro_params[VA_MACRO].dev) pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev); - current_mclk_mux_macro = - priv->current_mclk_mux_macro[macro_id]; - if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) { - dev_dbg_ratelimited(priv->dev, - "%s: mclk_fn not init for macro-id:%d, current_mclk_mux_macro:%d\n", - __func__, macro_id, current_mclk_mux_macro); - goto err; - } - ret = priv->macro_params[current_mclk_mux_macro].mclk_fn( - priv->macro_params[current_mclk_mux_macro].dev, true); - if (ret) { - dev_dbg_ratelimited(priv->dev, - "%s: clock enable failed for macro-id:%d, current_mclk_mux_macro:%d\n", - __func__, macro_id, current_mclk_mux_macro); + + /* Request Clk before register access */ + ret = bolero_clk_rsc_request_clock(priv->macro_params[macro_id].dev, + priv->macro_params[macro_id].default_clk_id, + priv->macro_params[macro_id].clk_id_req, + true); + if (ret < 0) { + dev_err_ratelimited(priv->dev, + "%s: Failed to enable clock, ret:%d\n", __func__, ret); goto err; } + bolero_ahb_read_device( priv->macro_params[macro_id].io_base, reg, val); - priv->macro_params[current_mclk_mux_macro].mclk_fn( - priv->macro_params[current_mclk_mux_macro].dev, false); + + bolero_clk_rsc_request_clock(priv->macro_params[macro_id].dev, + priv->macro_params[macro_id].default_clk_id, + priv->macro_params[macro_id].clk_id_req, + false); + err: if (priv->macro_params[VA_MACRO].dev) { pm_runtime_mark_last_busy(priv->macro_params[VA_MACRO].dev); pm_runtime_put_autosuspend(priv->macro_params[VA_MACRO].dev); } +ssr_err: mutex_unlock(&priv->clk_lock); return ret; } @@ -137,42 +139,43 @@ static int __bolero_reg_read(struct bolero_priv *priv, static int __bolero_reg_write(struct bolero_priv *priv, u16 macro_id, u16 reg, u8 val) { - int ret = -EINVAL; - u16 current_mclk_mux_macro; + int ret = 0; mutex_lock(&priv->clk_lock); if (!priv->dev_up) { dev_dbg_ratelimited(priv->dev, "%s: SSR in progress, exit\n", __func__); - goto err; + ret = -EINVAL; + goto ssr_err; } if (priv->macro_params[VA_MACRO].dev) - ret = pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev); - current_mclk_mux_macro = - priv->current_mclk_mux_macro[macro_id]; - if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) { - dev_dbg_ratelimited(priv->dev, - "%s: mclk_fn not init for macro-id:%d, current_mclk_mux_macro:%d\n", - __func__, macro_id, current_mclk_mux_macro); - goto err; - } - ret = priv->macro_params[current_mclk_mux_macro].mclk_fn( - priv->macro_params[current_mclk_mux_macro].dev, true); - if (ret) { - dev_dbg_ratelimited(priv->dev, - "%s: clock enable failed for macro-id:%d, current_mclk_mux_macro:%d\n", - __func__, macro_id, current_mclk_mux_macro); + pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev); + + /* Request Clk before register access */ + ret = bolero_clk_rsc_request_clock(priv->macro_params[macro_id].dev, + priv->macro_params[macro_id].default_clk_id, + priv->macro_params[macro_id].clk_id_req, + true); + if (ret < 0) { + dev_err_ratelimited(priv->dev, + "%s: Failed to enable clock, ret:%d\n", __func__, ret); goto err; } + bolero_ahb_write_device( - priv->macro_params[macro_id].io_base, reg, val); - priv->macro_params[current_mclk_mux_macro].mclk_fn( - priv->macro_params[current_mclk_mux_macro].dev, false); + priv->macro_params[macro_id].io_base, reg, val); + + bolero_clk_rsc_request_clock(priv->macro_params[macro_id].dev, + priv->macro_params[macro_id].default_clk_id, + priv->macro_params[macro_id].clk_id_req, + false); + err: if (priv->macro_params[VA_MACRO].dev) { pm_runtime_mark_last_busy(priv->macro_params[VA_MACRO].dev); pm_runtime_put_autosuspend(priv->macro_params[VA_MACRO].dev); } +ssr_err: mutex_unlock(&priv->clk_lock); return ret; } @@ -239,7 +242,7 @@ static void bolero_cdc_notifier_call(struct bolero_priv *priv, data, (void *)priv->wcd_dev); } -static bool bolero_is_valid_macro_dev(struct device *dev) +static bool bolero_is_valid_child_dev(struct device *dev) { if (of_device_is_compatible(dev->parent->of_node, "qcom,bolero-codec")) return true; @@ -326,6 +329,36 @@ struct device *bolero_get_device_ptr(struct device *dev, u16 macro_id) } EXPORT_SYMBOL(bolero_get_device_ptr); +/** + * bolero_get_rsc_clk_device_ptr - Get rsc clk device ptr + * + * @dev: bolero device ptr. + * + * Returns dev ptr on success or NULL on error. + */ +struct device *bolero_get_rsc_clk_device_ptr(struct device *dev) +{ + struct bolero_priv *priv; + + if (!dev) { + pr_err("%s: dev is null\n", __func__); + return NULL; + } + + if (!bolero_is_valid_codec_dev(dev)) { + pr_err("%s: invalid codec\n", __func__); + return NULL; + } + priv = dev_get_drvdata(dev); + if (!priv) { + dev_err(dev, "%s: priv is null\n", __func__); + return NULL; + } + + return priv->clk_dev; +} +EXPORT_SYMBOL(bolero_get_rsc_clk_device_ptr); + static int bolero_copy_dais_from_macro(struct bolero_priv *priv) { struct snd_soc_dai_driver *dai_ptr; @@ -355,6 +388,69 @@ static int bolero_copy_dais_from_macro(struct bolero_priv *priv) return 0; } +/** + * bolero_register_res_clk - Registers rsc clk driver to bolero + * + * @dev: rsc clk device ptr. + * @rsc_clk_cb: event handler callback for notifications like SSR + * + * Returns 0 on success or -EINVAL on error. + */ +int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t rsc_clk_cb) +{ + struct bolero_priv *priv; + + if (!dev || !rsc_clk_cb) { + pr_err("%s: dev or rsc_clk_cb is null\n", __func__); + return -EINVAL; + } + if (!bolero_is_valid_child_dev(dev)) { + dev_err(dev, "%s: child device :%pK not added yet\n", + __func__, dev); + return -EINVAL; + } + priv = dev_get_drvdata(dev->parent); + if (!priv) { + dev_err(dev, "%s: priv is null\n", __func__); + return -EINVAL; + } + + priv->clk_dev = dev; + priv->rsc_clk_cb = rsc_clk_cb; + + return 0; +} +EXPORT_SYMBOL(bolero_register_res_clk); + +/** + * bolero_unregister_res_clk - Unregisters rsc clk driver from bolero + * + * @dev: resource clk device ptr. + */ +void bolero_unregister_res_clk(struct device *dev) +{ + struct bolero_priv *priv; + + if (!dev) { + pr_err("%s: dev is NULL\n", __func__); + return; + } + if (!bolero_is_valid_child_dev(dev)) { + dev_err(dev, "%s: child device :%pK not added\n", + __func__, dev); + return; + } + priv = dev_get_drvdata(dev->parent); + if (!priv) { + dev_err(dev, "%s: priv is null\n", __func__); + return; + } + + priv->clk_dev = NULL; + priv->rsc_clk_cb = NULL; +} +EXPORT_SYMBOL(bolero_unregister_res_clk); + /** * bolero_register_macro - Registers macro to bolero * @@ -374,7 +470,7 @@ int bolero_register_macro(struct device *dev, u16 macro_id, pr_err("%s: dev or ops is null\n", __func__); return -EINVAL; } - if (!bolero_is_valid_macro_dev(dev)) { + if (!bolero_is_valid_child_dev(dev)) { dev_err(dev, "%s: child device for macro:%d not added yet\n", __func__, macro_id); return -EINVAL; @@ -385,12 +481,13 @@ int bolero_register_macro(struct device *dev, u16 macro_id, return -EINVAL; } + priv->macro_params[macro_id].clk_id_req = ops->clk_id_req; + priv->macro_params[macro_id].default_clk_id = ops->default_clk_id; priv->macro_params[macro_id].init = ops->init; priv->macro_params[macro_id].exit = ops->exit; priv->macro_params[macro_id].io_base = ops->io_base; priv->macro_params[macro_id].num_dais = ops->num_dais; priv->macro_params[macro_id].dai_ptr = ops->dai_ptr; - priv->macro_params[macro_id].mclk_fn = ops->mclk_fn; priv->macro_params[macro_id].event_handler = ops->event_handler; priv->macro_params[macro_id].set_port_map = ops->set_port_map; priv->macro_params[macro_id].dev = dev; @@ -441,7 +538,7 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) pr_err("%s: dev is null\n", __func__); return; } - if (!bolero_is_valid_macro_dev(dev)) { + if (!bolero_is_valid_child_dev(dev)) { dev_err(dev, "%s: macro:%d not in valid registered macro-list\n", __func__, macro_id); return; @@ -455,7 +552,6 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) priv->macro_params[macro_id].init = NULL; priv->macro_params[macro_id].num_dais = 0; priv->macro_params[macro_id].dai_ptr = NULL; - priv->macro_params[macro_id].mclk_fn = NULL; priv->macro_params[macro_id].event_handler = NULL; priv->macro_params[macro_id].dev = NULL; if (macro_id == TX_MACRO) @@ -470,150 +566,6 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) } EXPORT_SYMBOL(bolero_unregister_macro); -static void bolero_fs_gen_enable(struct bolero_priv *priv, bool enable) -{ - if (enable) { - if (++priv->clk_users == 1) { - mutex_unlock(&priv->clk_lock); - regmap_update_bits(priv->regmap, - BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, - 0x01, 0x01); - regmap_update_bits(priv->regmap, - BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, - 0x01, 0x01); - regmap_update_bits(priv->regmap, - BOLERO_CDC_VA_TOP_CSR_TOP_CFG0, - 0x02, 0x02); - mutex_lock(&priv->clk_lock); - } - } else { - if (priv->clk_users <= 0) { - dev_err(priv->dev, - "%s:clock already disabled\n", - __func__); - priv->clk_users = 0; - return; - } - if (--priv->clk_users == 0) { - mutex_unlock(&priv->clk_lock); - regmap_update_bits(priv->regmap, - BOLERO_CDC_VA_TOP_CSR_TOP_CFG0, - 0x02, 0x00); - regmap_update_bits(priv->regmap, - BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, - 0x01, 0x00); - regmap_update_bits(priv->regmap, - BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, - 0x01, 0x00); - mutex_lock(&priv->clk_lock); - } - } -} - -/** - * bolero_request_clock - request for clock enable/disable - * - * @dev: macro device ptr. - * @macro_id: ID of macro calling this API. - * @mclk_mux_id: MCLK_MUX ID. - * @enable: enable or disable clock flag - * - * Returns 0 on success or -EINVAL on error. - */ -int bolero_request_clock(struct device *dev, u16 macro_id, - enum mclk_mux mclk_mux_id, - bool enable) -{ - struct bolero_priv *priv; - u16 mclk_mux0_macro, mclk_mux1_macro; - int ret = 0, ret1 = 0; - - if (!dev) { - pr_err("%s: dev is null\n", __func__); - return -EINVAL; - } - if (!bolero_is_valid_macro_dev(dev)) { - dev_err(dev, "%s: macro:%d not in valid registered macro-list\n", - __func__, macro_id); - return -EINVAL; - } - priv = dev_get_drvdata(dev->parent); - if (!priv || (macro_id >= MAX_MACRO)) { - dev_err(dev, "%s: priv is null or invalid macro\n", __func__); - return -EINVAL; - } - mclk_mux0_macro = bolero_mclk_mux_tbl[macro_id][MCLK_MUX0]; - mutex_lock(&priv->clk_lock); - switch (mclk_mux_id) { - case MCLK_MUX0: - ret = priv->macro_params[mclk_mux0_macro].mclk_fn( - priv->macro_params[mclk_mux0_macro].dev, enable); - if (ret < 0) { - dev_err(dev, - "%s: MCLK_MUX0 %s failed for macro:%d, mclk_mux0_macro:%d\n", - __func__, - enable ? "enable" : "disable", - macro_id, mclk_mux0_macro); - goto err; - } - bolero_fs_gen_enable(priv, enable); - break; - case MCLK_MUX1: - mclk_mux1_macro = bolero_mclk_mux_tbl[macro_id][MCLK_MUX1]; - ret = priv->macro_params[mclk_mux0_macro].mclk_fn( - priv->macro_params[mclk_mux0_macro].dev, - true); - if (ret < 0) { - dev_err(dev, - "%s: MCLK_MUX0 en failed for macro:%d mclk_mux0_macro:%d\n", - __func__, macro_id, mclk_mux0_macro); - /* - * for disable case, need to proceed still for mclk_mux1 - * counter to decrement - */ - if (enable) - goto err; - } - bolero_fs_gen_enable(priv, enable); - /* - * need different return value as ret variable - * is used to track mclk_mux0 enable success or fail - */ - ret1 = priv->macro_params[mclk_mux1_macro].mclk_fn( - priv->macro_params[mclk_mux1_macro].dev, enable); - if (ret1 < 0) - dev_err(dev, - "%s: MCLK_MUX1 %s failed for macro:%d, mclk_mux1_macro:%d\n", - __func__, - enable ? "enable" : "disable", - macro_id, mclk_mux1_macro); - /* disable mclk_mux0 only if ret is success(0) */ - if (!ret) - priv->macro_params[mclk_mux0_macro].mclk_fn( - priv->macro_params[mclk_mux0_macro].dev, - false); - if (enable && ret1) - goto err; - break; - case MCLK_MUX_MAX: - default: - dev_err(dev, "%s: invalid mclk_mux_id: %d\n", - __func__, mclk_mux_id); - ret = -EINVAL; - goto err; - } - if (enable) - priv->current_mclk_mux_macro[macro_id] = - bolero_mclk_mux_tbl[macro_id][mclk_mux_id]; - else - priv->current_mclk_mux_macro[macro_id] = - bolero_mclk_mux_tbl[macro_id][MCLK_MUX0]; -err: - mutex_unlock(&priv->clk_lock); - return ret; -} -EXPORT_SYMBOL(bolero_request_clock); - static ssize_t bolero_version_read(struct snd_info_entry *entry, void *file_private_data, struct file *file, @@ -657,6 +609,9 @@ static int bolero_ssr_enable(struct device *dev, void *data) return 0; } + if (priv->rsc_clk_cb) + priv->rsc_clk_cb(priv->clk_dev, BOLERO_MACRO_EVT_SSR_UP); + if (priv->macro_params[VA_MACRO].event_handler) priv->macro_params[VA_MACRO].event_handler( priv->component, @@ -683,6 +638,9 @@ static void bolero_ssr_disable(struct device *dev, void *data) struct bolero_priv *priv = data; int macro_idx; + if (priv->rsc_clk_cb) + priv->rsc_clk_cb(priv->clk_dev, BOLERO_MACRO_EVT_SSR_DOWN); + bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_PA_OFF_PRE_SSR); regcache_cache_only(priv->regmap, true); @@ -1074,7 +1032,30 @@ static struct platform_driver bolero_drv = { .remove = bolero_remove, }; -module_platform_driver(bolero_drv); +static int bolero_drv_init(void) +{ + return platform_driver_register(&bolero_drv); +} + +static void bolero_drv_exit(void) +{ + platform_driver_unregister(&bolero_drv); +} + +static int __init bolero_init(void) +{ + bolero_drv_init(); + bolero_clk_rsc_mgr_init(); + return 0; +} +module_init(bolero_init); + +static void __exit bolero_exit(void) +{ + bolero_clk_rsc_mgr_exit(); + bolero_drv_exit(); +} +module_exit(bolero_exit); MODULE_DESCRIPTION("Bolero driver"); MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 524225e795dd..e533eb85731c 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #ifndef BOLERO_CDC_H @@ -54,16 +54,20 @@ struct macro_ops { int (*set_port_map)(struct snd_soc_component *component, u32 uc, u32 size, void *data); char __iomem *io_base; + u16 clk_id_req; + u16 default_clk_id; }; +typedef int (*rsc_clk_cb_t)(struct device *dev, u16 event); + #if IS_ENABLED(CONFIG_SND_SOC_BOLERO) +int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb); +void bolero_unregister_res_clk(struct device *dev); int bolero_register_macro(struct device *dev, u16 macro_id, struct macro_ops *ops); void bolero_unregister_macro(struct device *dev, u16 macro_id); struct device *bolero_get_device_ptr(struct device *dev, u16 macro_id); -int bolero_request_clock(struct device *dev, u16 macro_id, - enum mclk_mux mclk_mux_id, - bool enable); +struct device *bolero_get_rsc_clk_device_ptr(struct device *dev); int bolero_info_create_codec_entry( struct snd_info_entry *codec_root, struct snd_soc_component *component); @@ -73,6 +77,14 @@ int bolero_runtime_resume(struct device *dev); int bolero_runtime_suspend(struct device *dev); int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *data); #else +static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb) +{ + return 0; +} +static inline void bolero_unregister_res_clk(struct device *dev) +{ +} + static inline int bolero_register_macro(struct device *dev, u16 macro_id, struct macro_ops *ops) @@ -90,13 +102,6 @@ static inline struct device *bolero_get_device_ptr(struct device *dev, return NULL; } -static inline int bolero_request_clock(struct device *dev, u16 macro_id, - enum mclk_mux mclk_mux_id, - bool enable) -{ - return 0; -} - static int bolero_info_create_codec_entry( struct snd_info_entry *codec_root, struct snd_soc_component *component) diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c new file mode 100644 index 000000000000..03befde80a27 --- /dev/null +++ b/asoc/codecs/bolero/bolero-clk-rsc.c @@ -0,0 +1,613 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "bolero-cdc.h" +#include "bolero-clk-rsc.h" + +#define DRV_NAME "bolero-clk-rsc" +#define BOLERO_CLK_NAME_LENGTH 30 +#define NPL_CLK_OFFSET (TX_NPL_CLK - TX_CORE_CLK) + +static char clk_src_name[MAX_CLK][BOLERO_CLK_NAME_LENGTH] = { + "tx_core_clk", + "rx_core_clk", + "wsa_core_clk", + "va_core_clk", + "tx_npl_clk", + "rx_npl_clk", + "wsa_npl_clk", + "va_npl_clk", +}; + +struct bolero_clk_rsc { + struct device *dev; + struct mutex rsc_clk_lock; + struct clk *clk[MAX_CLK]; + int clk_cnt[MAX_CLK]; + int reg_seq_en_cnt; + int va_tx_clk_cnt; + bool dev_up; + u32 num_fs_reg; + u32 *fs_gen_seq; + int default_clk_id[MAX_CLK]; + struct regmap *regmap; + char __iomem *rx_clk_muxsel; + char __iomem *wsa_clk_muxsel; + char __iomem *va_clk_muxsel; +}; + +static int bolero_clk_rsc_cb(struct device *dev, u16 event) +{ + struct bolero_clk_rsc *priv; + + if (!dev) { + pr_err("%s: Invalid device pointer\n", + __func__); + return -EINVAL; + } + + priv = dev_get_drvdata(dev); + if (!priv) { + pr_err("%s: Invalid clk rsc priviate data\n", + __func__); + return -EINVAL; + } + + mutex_lock(&priv->rsc_clk_lock); + if (event == BOLERO_MACRO_EVT_SSR_UP) + priv->dev_up = true; + else if (event == BOLERO_MACRO_EVT_SSR_DOWN) + priv->dev_up = false; + mutex_unlock(&priv->rsc_clk_lock); + + return 0; +} + +static char __iomem *bolero_clk_rsc_get_clk_muxsel(struct bolero_clk_rsc *priv, + int clk_id) +{ + switch (clk_id) { + case RX_CORE_CLK: + return priv->rx_clk_muxsel; + case WSA_CORE_CLK: + return priv->wsa_clk_muxsel; + case VA_CORE_CLK: + return priv->va_clk_muxsel; + case TX_CORE_CLK: + default: + dev_err_ratelimited(priv->dev, "%s: Invalid case\n", __func__); + break; + } + + return NULL; +} + +static int bolero_clk_rsc_mux0_clk_request(struct bolero_clk_rsc *priv, + int clk_id, + bool enable) +{ + int ret = 0; + + if (enable) { + /* Enable Requested Core clk */ + if (priv->clk_cnt[clk_id] == 0) { + ret = clk_prepare_enable(priv->clk[clk_id]); + if (ret < 0) { + dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n", + __func__, clk_id); + goto done; + } + if (priv->clk[clk_id + NPL_CLK_OFFSET]) { + ret = clk_prepare_enable( + priv->clk[clk_id + NPL_CLK_OFFSET]); + if (ret < 0) { + dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n", + __func__, + clk_id + NPL_CLK_OFFSET); + goto err; + } + } + } + priv->clk_cnt[clk_id]++; + } else { + if (priv->clk_cnt[clk_id] <= 0) { + dev_err_ratelimited(priv->dev, "%s: clk_id: %d is already disabled\n", + __func__, clk_id); + priv->clk_cnt[clk_id] = 0; + goto done; + } + priv->clk_cnt[clk_id]--; + if (priv->clk_cnt[clk_id] == 0) { + if (priv->clk[clk_id + NPL_CLK_OFFSET]) + clk_disable_unprepare( + priv->clk[clk_id + NPL_CLK_OFFSET]); + clk_disable_unprepare(priv->clk[clk_id]); + } + } + return ret; + +err: + clk_disable_unprepare(priv->clk[clk_id]); +done: + return ret; +} + +static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv, + int clk_id, + bool enable) +{ + char __iomem *clk_muxsel = NULL; + int ret = 0; + int default_clk_id = priv->default_clk_id[clk_id]; + + clk_muxsel = bolero_clk_rsc_get_clk_muxsel(priv, clk_id); + if (!clk_muxsel) { + ret = -EINVAL; + goto done; + } + + if (enable) { + if (priv->clk_cnt[clk_id] == 0) { + ret = bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, + true); + if (ret < 0) + goto done; + + ret = clk_prepare_enable(priv->clk[clk_id]); + if (ret < 0) { + dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n", + __func__, clk_id); + goto err_clk; + } + if (priv->clk[clk_id + NPL_CLK_OFFSET]) { + ret = clk_prepare_enable( + priv->clk[clk_id + NPL_CLK_OFFSET]); + if (ret < 0) { + dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n", + __func__, + clk_id + NPL_CLK_OFFSET); + goto err_npl_clk; + } + } + iowrite32(0x1, clk_muxsel); + bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, + false); + } + priv->clk_cnt[clk_id]++; + } else { + if (priv->clk_cnt[clk_id] <= 0) { + dev_err_ratelimited(priv->dev, "%s: clk_id: %d is already disabled\n", + __func__, clk_id); + priv->clk_cnt[clk_id] = 0; + goto done; + } + priv->clk_cnt[clk_id]--; + if (priv->clk_cnt[clk_id] == 0) { + bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, + true); + + iowrite32(0x0, clk_muxsel); + if (priv->clk[clk_id + NPL_CLK_OFFSET]) + clk_disable_unprepare( + priv->clk[clk_id + NPL_CLK_OFFSET]); + clk_disable_unprepare(priv->clk[clk_id]); + + bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, + false); + } + } + return ret; + +err_npl_clk: + clk_disable_unprepare(priv->clk[clk_id]); + +err_clk: + bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, false); +done: + return ret; +} + +static int bolero_clk_rsc_check_and_update_va_clk(struct bolero_clk_rsc *priv, + bool mux_switch, + int clk_id, + bool enable) +{ + int ret = 0; + + if (enable) { + if (clk_id == VA_CORE_CLK && mux_switch) { + /* + * Handle the following usecase scenarios during enable + * 1. VA only, Active clk is VA_CORE_CLK + * 2. record -> record + VA, Active clk is TX_CORE_CLK + */ + if (priv->clk_cnt[TX_CORE_CLK] == 0) { + ret = bolero_clk_rsc_mux1_clk_request(priv, + VA_CORE_CLK, enable); + if (ret < 0) + goto err; + } else { + ret = bolero_clk_rsc_mux0_clk_request(priv, + TX_CORE_CLK, enable); + if (ret < 0) + goto err; + priv->va_tx_clk_cnt++; + } + } else if ((priv->clk_cnt[TX_CORE_CLK] > 0) && + (priv->clk_cnt[VA_CORE_CLK] > 0)) { + /* + * Handle following concurrency scenario during enable + * 1. VA-> Record+VA, Increment TX CLK and Disable VA + * 2. VA-> Playback+VA, Increment TX CLK and Disable VA + */ + while (priv->clk_cnt[VA_CORE_CLK] > 0) { + ret = bolero_clk_rsc_mux0_clk_request(priv, + TX_CORE_CLK, true); + if (ret < 0) + goto err; + + bolero_clk_rsc_mux1_clk_request(priv, + VA_CORE_CLK, false); + priv->va_tx_clk_cnt++; + } + } + } else { + if (clk_id == VA_CORE_CLK && mux_switch) { + /* + * Handle the following usecase scenarios during disable + * 1. VA only, disable VA_CORE_CLK + * 2. Record + VA -> Record, decrement TX CLK count + */ + if (priv->clk_cnt[VA_CORE_CLK]) { + bolero_clk_rsc_mux1_clk_request(priv, + VA_CORE_CLK, enable); + } else if (priv->va_tx_clk_cnt) { + bolero_clk_rsc_mux0_clk_request(priv, + TX_CORE_CLK, enable); + priv->va_tx_clk_cnt--; + } + } else if (priv->va_tx_clk_cnt == priv->clk_cnt[TX_CORE_CLK]) { + /* + * Handle the following usecase scenarios during disable + * Record+VA-> VA: enable VA CLK, decrement TX CLK count + */ + while (priv->va_tx_clk_cnt) { + ret = bolero_clk_rsc_mux1_clk_request(priv, + VA_CORE_CLK, true); + if (ret < 0) + goto err; + + bolero_clk_rsc_mux0_clk_request(priv, + TX_CORE_CLK, false); + priv->va_tx_clk_cnt--; + } + } + } + +err: + return ret; +} + +/** + * bolero_clk_rsc_fs_gen_request - request to enable/disable fs generation + * sequence + * + * @dev: Macro device pointer + * @enable: enable or disable flag + */ +void bolero_clk_rsc_fs_gen_request(struct device *dev, bool enable) +{ + int i; + struct regmap *regmap; + struct device *clk_dev = NULL; + struct bolero_clk_rsc *priv = NULL; + + if (!dev) { + pr_err("%s: dev is null %d\n", __func__); + return; + } + clk_dev = bolero_get_rsc_clk_device_ptr(dev->parent); + if (!clk_dev) { + pr_err("%s: Invalid rsc clk device\n", __func__); + return; + } + priv = dev_get_drvdata(clk_dev); + if (!priv) { + pr_err("%s: Invalid rsc clk priviate data\n", __func__); + return; + } + regmap = dev_get_regmap(priv->dev->parent, NULL); + if (enable) { + if (priv->reg_seq_en_cnt++ == 0) { + for (i = 0; i < (priv->num_fs_reg * 2); i += 2) { + dev_dbg(priv->dev, "%s: Register: %d, value: %d\n", + __func__, priv->fs_gen_seq[i], + priv->fs_gen_seq[i + 1]); + regmap_update_bits(regmap, + priv->fs_gen_seq[i], + priv->fs_gen_seq[i + 1], + priv->fs_gen_seq[i + 1]); + } + } + } else { + if (priv->reg_seq_en_cnt <= 0) { + dev_err_ratelimited(priv->dev, "%s: req_seq_cnt: %d is already disabled\n", + __func__, priv->reg_seq_en_cnt); + priv->reg_seq_en_cnt = 0; + return; + } + if (--priv->reg_seq_en_cnt == 0) { + for (i = ((priv->num_fs_reg - 1) * 2); i >= 0; i -= 2) { + dev_dbg(priv->dev, "%s: Register: %d, value: %d\n", + __func__, priv->fs_gen_seq[i], + priv->fs_gen_seq[i + 1]); + regmap_update_bits(regmap, priv->fs_gen_seq[i], + priv->fs_gen_seq[i + 1], 0x0); + } + } + } +} +EXPORT_SYMBOL(bolero_clk_rsc_fs_gen_request); + +/** + * bolero_clk_rsc_request_clock - request for clock to + * enable/disable + * + * @dev: Macro device pointer. + * @default_clk_id: mux0 Core clock ID input. + * @clk_id_req: Core clock ID requested to enable/disable + * @enable: enable or disable clock flag + * + * Returns 0 on success or -EINVAL on error. + */ +int bolero_clk_rsc_request_clock(struct device *dev, + int default_clk_id, + int clk_id_req, + bool enable) +{ + int ret = 0; + struct device *clk_dev = NULL; + struct bolero_clk_rsc *priv = NULL; + bool mux_switch = false; + + if (!dev) { + pr_err("%s: dev is null %d\n", __func__); + return -EINVAL; + } + if ((clk_id_req < 0 || clk_id_req >= MAX_CLK) && + (default_clk_id < 0 || default_clk_id >= MAX_CLK)) { + pr_err("%s: Invalid clk_id_req: %d or default_clk_id: %d\n", + __func__, clk_id_req, default_clk_id); + return -EINVAL; + } + clk_dev = bolero_get_rsc_clk_device_ptr(dev->parent); + if (!clk_dev) { + pr_err("%s: Invalid rsc clk device\n", __func__); + return -EINVAL; + } + priv = dev_get_drvdata(clk_dev); + if (!priv) { + pr_err("%s: Invalid rsc clk priviate data\n", __func__); + return -EINVAL; + } + + mutex_lock(&priv->rsc_clk_lock); + if (!priv->dev_up) { + dev_err_ratelimited(priv->dev, "%s: SSR is in progress..\n", + __func__); + ret = -EINVAL; + goto err; + } + priv->default_clk_id[clk_id_req] = default_clk_id; + if (default_clk_id != clk_id_req) + mux_switch = true; + + if (mux_switch) { + if (clk_id_req != VA_CORE_CLK) { + ret = bolero_clk_rsc_mux1_clk_request(priv, clk_id_req, + enable); + if (ret < 0) + goto err; + } + } else { + ret = bolero_clk_rsc_mux0_clk_request(priv, clk_id_req, enable); + if (ret < 0) + goto err; + } + + ret = bolero_clk_rsc_check_and_update_va_clk(priv, mux_switch, + clk_id_req, + enable); + if (ret < 0) + goto err; + + dev_dbg(priv->dev, "%s: clk_cnt: %d for requested clk: %d, enable: %d\n", + __func__, priv->clk_cnt[clk_id_req], clk_id_req, + enable); + + mutex_unlock(&priv->rsc_clk_lock); + + return 0; + +err: + mutex_unlock(&priv->rsc_clk_lock); + return ret; +} +EXPORT_SYMBOL(bolero_clk_rsc_request_clock); + + +static int bolero_clk_rsc_probe(struct platform_device *pdev) +{ + int ret = 0, fs_gen_size, i, j; + const char **clk_name_array; + int clk_cnt; + struct clk *clk; + struct bolero_clk_rsc *priv = NULL; + u32 muxsel = 0; + + priv = devm_kzalloc(&pdev->dev, sizeof(struct bolero_clk_rsc), + GFP_KERNEL); + if (!priv) + return -ENOMEM; + + /* Get clk fs gen sequence from device tree */ + if (!of_find_property(pdev->dev.of_node, "qcom,fs-gen-sequence", + &fs_gen_size)) { + dev_err(&pdev->dev, "%s: unable to find qcom,fs-gen-sequence property\n", + __func__); + ret = -EINVAL; + goto err; + } + priv->num_fs_reg = fs_gen_size/(2 * sizeof(u32)); + priv->fs_gen_seq = devm_kzalloc(&pdev->dev, fs_gen_size, GFP_KERNEL); + if (!priv->fs_gen_seq) { + ret = -ENOMEM; + goto err; + } + dev_dbg(&pdev->dev, "%s: num_fs_reg %d\n", __func__, priv->num_fs_reg); + /* Parse fs-gen-sequence */ + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,fs-gen-sequence", + priv->fs_gen_seq, + priv->num_fs_reg * 2); + if (ret < 0) { + dev_err(&pdev->dev, "%s: unable to parse fs-gen-sequence, ret = %d\n", + __func__, ret); + goto err; + } + + /* Get clk details from device tree */ + clk_cnt = of_property_count_strings(pdev->dev.of_node, "clock-names"); + if (clk_cnt <= 0 || clk_cnt > MAX_CLK) { + dev_err(&pdev->dev, "%s: Invalid number of clocks %d", + __func__, clk_cnt); + ret = -EINVAL; + goto err; + } + clk_name_array = devm_kzalloc(&pdev->dev, clk_cnt * sizeof(char *), + GFP_KERNEL); + + ret = of_property_read_string_array(pdev->dev.of_node, "clock-names", + clk_name_array, clk_cnt); + + for (i = 0; i < MAX_CLK; i++) { + priv->clk[i] = NULL; + for (j = 0; j < clk_cnt; j++) { + if (!strcmp(clk_src_name[i], clk_name_array[j])) { + clk = devm_clk_get(&pdev->dev, clk_src_name[i]); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + dev_err(&pdev->dev, "%s: clk get failed for %s with ret %d\n", + __func__, clk_src_name[i], ret); + goto err; + } + priv->clk[i] = clk; + dev_dbg(&pdev->dev, "%s: clk get success for clk name %s\n", + __func__, clk_src_name[i]); + } + } + } + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,rx_mclk_mode_muxsel", &muxsel); + if (ret) { + dev_dbg(&pdev->dev, "%s: could not find qcom,rx_mclk_mode_muxsel entry in dt\n", + __func__); + } else { + priv->rx_clk_muxsel = devm_ioremap(&pdev->dev, muxsel, 0x4); + if (!priv->rx_clk_muxsel) { + dev_err(&pdev->dev, "%s: ioremap failed for rx muxsel\n", + __func__); + return -ENOMEM; + } + } + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,wsa_mclk_mode_muxsel", &muxsel); + if (ret) { + dev_dbg(&pdev->dev, "%s: could not find qcom,wsa_mclk_mode_muxsel entry in dt\n", + __func__); + } else { + priv->wsa_clk_muxsel = devm_ioremap(&pdev->dev, muxsel, 0x4); + if (!priv->wsa_clk_muxsel) { + dev_err(&pdev->dev, "%s: ioremap failed for wsa muxsel\n", + __func__); + return -ENOMEM; + } + } + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,va_mclk_mode_muxsel", &muxsel); + if (ret) { + dev_dbg(&pdev->dev, "%s: could not find qcom,va_mclk_mode_muxsel entry in dt\n", + __func__); + } else { + priv->va_clk_muxsel = devm_ioremap(&pdev->dev, muxsel, 0x4); + if (!priv->va_clk_muxsel) { + dev_err(&pdev->dev, "%s: ioremap failed for va muxsel\n", + __func__); + return -ENOMEM; + } + } + + ret = bolero_register_res_clk(&pdev->dev, bolero_clk_rsc_cb); + if (ret < 0) { + dev_err(&pdev->dev, "%s: Failed to register cb %d", + __func__, ret); + goto err; + } + priv->dev = &pdev->dev; + priv->dev_up = true; + mutex_init(&priv->rsc_clk_lock); + dev_set_drvdata(&pdev->dev, priv); + +err: + return ret; +} + +static int bolero_clk_rsc_remove(struct platform_device *pdev) +{ + struct bolero_clk_rsc *priv = dev_get_drvdata(&pdev->dev); + + bolero_unregister_res_clk(&pdev->dev); + of_platform_depopulate(&pdev->dev); + if (!priv) + return -EINVAL; + mutex_destroy(&priv->rsc_clk_lock); + + return 0; +} + +static const struct of_device_id bolero_clk_rsc_dt_match[] = { + {.compatible = "qcom,bolero-clk-rsc-mngr"}, + {} +}; +MODULE_DEVICE_TABLE(of, bolero_clk_rsc_dt_match); + +static struct platform_driver bolero_clk_rsc_mgr = { + .driver = { + .name = "bolero-clk-rsc-mngr", + .owner = THIS_MODULE, + .of_match_table = bolero_clk_rsc_dt_match, + }, + .probe = bolero_clk_rsc_probe, + .remove = bolero_clk_rsc_remove, +}; + +int bolero_clk_rsc_mgr_init(void) +{ + return platform_driver_register(&bolero_clk_rsc_mgr); +} + +void bolero_clk_rsc_mgr_exit(void) +{ + platform_driver_unregister(&bolero_clk_rsc_mgr); +} +MODULE_DESCRIPTION("Bolero clock resource manager driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/bolero/bolero-clk-rsc.h b/asoc/codecs/bolero/bolero-clk-rsc.h new file mode 100644 index 000000000000..b378f73b34d4 --- /dev/null +++ b/asoc/codecs/bolero/bolero-clk-rsc.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#ifndef BOLERO_CLK_RSC_H +#define BOLERO_CLK_RSC_H + +#include +#include + +#if IS_ENABLED(CONFIG_SND_SOC_BOLERO) +int bolero_clk_rsc_mgr_init(void); +void bolero_clk_rsc_mgr_exit(void); +void bolero_clk_rsc_fs_gen_request(struct device *dev, + bool enable); +int bolero_clk_rsc_request_clock(struct device *dev, + int default_clk_id, + int clk_id_req, + bool enable); +#else +static inline void bolero_clk_rsc_fs_gen_request(struct device *dev, + bool enable) +{ +} +static inline int bolero_clk_rsc_mgr_init(void) +{ + return 0; +} +static inline void bolero_clk_rsc_mgr_exit(void) +{ +} +static inline int bolero_clk_rsc_request_clock(struct device *dev, + int default_clk_id, + int clk_id_req, + bool enable) +{ + return 0; +} + +#endif /* CONFIG_SND_SOC_BOLERO */ +#endif /* BOLERO_CLK_RSC_H */ diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 2749b0b0d324..734afbc06b51 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -7,7 +7,7 @@ #include "bolero-cdc-registers.h" -#define BOLERO_CDC_CHILD_DEVICES_MAX 5 +#define BOLERO_CDC_CHILD_DEVICES_MAX 6 /* from bolero to WCD events */ enum { @@ -73,7 +73,8 @@ struct bolero_priv { struct wcd_ctrl_platform_data plat_data; struct device *wcd_dev; struct blocking_notifier_head notifier; - int clk_users; + struct device *clk_dev; + rsc_clk_cb_t rsc_clk_cb; }; struct regmap *bolero_regmap_init(struct device *dev, diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 035215275621..0fc13eec41bf 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -18,6 +18,7 @@ #include #include "bolero-cdc.h" #include "bolero-cdc-registers.h" +#include "bolero-clk-rsc.h" #define RX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ @@ -331,8 +332,6 @@ enum { * @swr_plat_data: Soundwire platform data * @rx_macro_add_child_devices_work: work for adding child devices * @rx_swr_gpio_p: used by pinctrl API - * @rx_core_clk: MCLK for rx macro - * @rx_npl_clk: NPL clock for RX soundwire * @component: codec handle */ struct rx_macro_priv { @@ -353,15 +352,12 @@ struct rx_macro_priv { bool dev_up; bool hph_pwr_mode; bool hph_hd2_mode; - u16 mclk_mux; struct mutex mclk_lock; struct mutex swr_clk_lock; struct rx_swr_ctrl_data *swr_ctrl_data; struct rx_swr_ctrl_platform_data swr_plat_data; struct work_struct rx_macro_add_child_devices_work; struct device_node *rx_swr_gpio_p; - struct clk *rx_core_clk; - struct clk *rx_npl_clk; struct snd_soc_component *component; unsigned long active_ch_mask[RX_MACRO_MAX_DAIS]; unsigned long active_ch_cnt[RX_MACRO_MAX_DAIS]; @@ -378,6 +374,8 @@ struct rx_macro_priv { int is_softclip_on; int softclip_clk_users; struct rx_macro_bcl_pmic_params bcl_pmic_params; + u16 clk_id; + u16 default_clk_id; }; static struct snd_soc_dai_driver rx_macro_dai[]; @@ -1059,7 +1057,7 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, bool mclk_enable, bool dapm) { struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL); - int ret = 0, mclk_mux = MCLK_MUX0; + int ret = 0; if (regmap == NULL) { dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__); @@ -1073,16 +1071,19 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, if (mclk_enable) { if (rx_priv->rx_mclk_users == 0) { if (rx_priv->is_native_on) - mclk_mux = MCLK_MUX1; - ret = bolero_request_clock(rx_priv->dev, - RX_MACRO, mclk_mux, true); + rx_priv->clk_id = RX_CORE_CLK; + ret = bolero_clk_rsc_request_clock(rx_priv->dev, + rx_priv->default_clk_id, + rx_priv->clk_id, + true); if (ret < 0) { dev_err(rx_priv->dev, "%s: rx request clock enable failed\n", __func__); goto exit; } - rx_priv->mclk_mux = mclk_mux; + bolero_clk_rsc_fs_gen_request(rx_priv->dev, + true); regcache_mark_dirty(regmap); regcache_sync_region(regmap, RX_START_OFFSET, @@ -1113,10 +1114,13 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, regmap_update_bits(regmap, BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x00); - mclk_mux = rx_priv->mclk_mux; - bolero_request_clock(rx_priv->dev, - RX_MACRO, mclk_mux, false); - rx_priv->mclk_mux = MCLK_MUX0; + bolero_clk_rsc_fs_gen_request(rx_priv->dev, + false); + bolero_clk_rsc_request_clock(rx_priv->dev, + rx_priv->default_clk_id, + rx_priv->clk_id, + false); + rx_priv->clk_id = rx_priv->default_clk_id; } } exit: @@ -1142,9 +1146,9 @@ static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMU: /* if swr_clk_users > 0, call device down */ if (rx_priv->swr_clk_users > 0) { - if ((rx_priv->mclk_mux == MCLK_MUX0 && + if ((rx_priv->clk_id == rx_priv->default_clk_id && rx_priv->is_native_on) || - (rx_priv->mclk_mux == MCLK_MUX1 && + (rx_priv->clk_id == RX_CORE_CLK && !rx_priv->is_native_on)) { swrm_wcd_notify( rx_priv->swr_ctrl_data[0].rx_swr_pdev, @@ -1174,51 +1178,13 @@ static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w, return ret; } -static int rx_macro_mclk_ctrl(struct device *dev, bool enable) -{ - struct rx_macro_priv *rx_priv = dev_get_drvdata(dev); - int ret = 0; - - if (enable) { - ret = clk_prepare_enable(rx_priv->rx_core_clk); - if (ret < 0) { - dev_err(dev, "%s:rx mclk enable failed\n", __func__); - return ret; - } - ret = clk_prepare_enable(rx_priv->rx_npl_clk); - if (ret < 0) { - clk_disable_unprepare(rx_priv->rx_core_clk); - dev_err(dev, "%s:rx npl_clk enable failed\n", - __func__); - return ret; - } - if (rx_priv->rx_mclk_cnt++ == 0) { - if (rx_priv->dev_up) - iowrite32(0x1, rx_priv->rx_mclk_mode_muxsel); - } - } else { - if (rx_priv->rx_mclk_cnt <= 0) { - dev_dbg(dev, "%s:rx mclk already disabled\n", __func__); - rx_priv->rx_mclk_cnt = 0; - return 0; - } - if (--rx_priv->rx_mclk_cnt == 0) { - if (rx_priv->dev_up) - iowrite32(0x0, rx_priv->rx_mclk_mode_muxsel); - } - clk_disable_unprepare(rx_priv->rx_npl_clk); - clk_disable_unprepare(rx_priv->rx_core_clk); - } - - return 0; -} - static int rx_macro_event_handler(struct snd_soc_component *component, u16 event, u32 data) { u16 reg = 0, reg_mix = 0, rx_idx = 0, mute = 0x0, val = 0; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; + int ret = 0; if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) return -EINVAL; @@ -1256,17 +1222,25 @@ static int rx_macro_event_handler(struct snd_soc_component *component, rx_priv->dev_up = true; /* reset swr after ssr/pdr */ rx_priv->reset_swr = true; - /* enable&disable MCLK_MUX1 to reset GFMUX reg */ - bolero_request_clock(rx_priv->dev, - RX_MACRO, MCLK_MUX1, true); - bolero_request_clock(rx_priv->dev, - RX_MACRO, MCLK_MUX1, false); + /* enable&disable RX_CORE_CLK to reset GFMUX reg */ + ret = bolero_clk_rsc_request_clock(rx_priv->dev, + rx_priv->default_clk_id, + RX_CORE_CLK, true); + if (ret < 0) + dev_err_ratelimited(rx_priv->dev, + "%s, failed to enable clk, ret:%d\n", + __func__, ret); + else + bolero_clk_rsc_request_clock(rx_priv->dev, + rx_priv->default_clk_id, + RX_CORE_CLK, false); + swrm_wcd_notify( rx_priv->swr_ctrl_data[0].rx_swr_pdev, SWR_DEVICE_SSR_UP, NULL); break; } - return 0; + return ret; } static int rx_macro_find_playback_dai_id_for_port(int port_id, @@ -3573,7 +3547,6 @@ static void rx_macro_init_ops(struct macro_ops *ops, char __iomem *rx_io_base) ops->io_base = rx_io_base; ops->dai_ptr = rx_macro_dai; ops->num_dais = ARRAY_SIZE(rx_macro_dai); - ops->mclk_fn = rx_macro_mclk_ctrl; ops->event_handler = rx_macro_event_handler; ops->set_port_map = rx_macro_set_port_map; } @@ -3585,8 +3558,8 @@ static int rx_macro_probe(struct platform_device *pdev) u32 rx_base_addr = 0, muxsel = 0; char __iomem *rx_io_base = NULL, *muxsel_io = NULL; int ret = 0; - struct clk *rx_core_clk = NULL, *rx_npl_clk = NULL; u8 bcl_pmic_params[3]; + u32 default_clk_id = 0; rx_priv = devm_kzalloc(&pdev->dev, sizeof(struct rx_macro_priv), GFP_KERNEL); @@ -3608,6 +3581,13 @@ static int rx_macro_probe(struct platform_device *pdev) __func__, "reg"); return ret; } + ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id", + &default_clk_id); + if (ret) { + dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "qcom,default-clk-id"); + default_clk_id = RX_CORE_CLK; + } rx_priv->rx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,rx-swr-gpios", 0); if (!rx_priv->rx_swr_gpio_p) { @@ -3639,25 +3619,6 @@ static int rx_macro_probe(struct platform_device *pdev) rx_priv->swr_plat_data.clk = rx_swrm_clock; rx_priv->swr_plat_data.handle_irq = NULL; - /* Register MCLK for rx macro */ - rx_core_clk = devm_clk_get(&pdev->dev, "rx_core_clk"); - if (IS_ERR(rx_core_clk)) { - ret = PTR_ERR(rx_core_clk); - dev_err(&pdev->dev, "%s: clk get %s failed %d\n", - __func__, "rx_core_clk", ret); - return ret; - } - rx_priv->rx_core_clk = rx_core_clk; - /* Register npl clk for soundwire */ - rx_npl_clk = devm_clk_get(&pdev->dev, "rx_npl_clk"); - if (IS_ERR(rx_npl_clk)) { - ret = PTR_ERR(rx_npl_clk); - dev_err(&pdev->dev, "%s: clk get %s failed %d\n", - __func__, "rx_npl_clk", ret); - return ret; - } - rx_priv->rx_npl_clk = rx_npl_clk; - ret = of_property_read_u8_array(pdev->dev.of_node, "qcom,rx-bcl-pmic-params", bcl_pmic_params, sizeof(bcl_pmic_params)); @@ -3669,6 +3630,10 @@ static int rx_macro_probe(struct platform_device *pdev) rx_priv->bcl_pmic_params.sid = bcl_pmic_params[1]; rx_priv->bcl_pmic_params.ppid = bcl_pmic_params[2]; } + rx_priv->clk_id = default_clk_id; + rx_priv->default_clk_id = default_clk_id; + ops.clk_id_req = rx_priv->clk_id; + ops.default_clk_id = default_clk_id; dev_set_drvdata(&pdev->dev, rx_priv); mutex_init(&rx_priv->mclk_lock); diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 98ee1e72d611..32b85a94e865 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -16,6 +16,7 @@ #include #include "bolero-cdc.h" #include "bolero-cdc-registers.h" +#include "bolero-clk-rsc.h" #define TX_MACRO_MAX_OFFSET 0x1000 @@ -129,8 +130,6 @@ struct tx_macro_priv { int swr_clk_users; bool dapm_mclk_enable; bool reset_swr; - struct clk *tx_core_clk; - struct clk *tx_npl_clk; struct mutex mclk_lock; struct mutex swr_clk_lock; struct snd_soc_component *component; @@ -198,14 +197,18 @@ static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv, mutex_lock(&tx_priv->mclk_lock); if (mclk_enable) { if (tx_priv->tx_mclk_users == 0) { - ret = bolero_request_clock(tx_priv->dev, - TX_MACRO, MCLK_MUX0, true); + ret = bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + true); if (ret < 0) { dev_err(tx_priv->dev, "%s: request clock enable failed\n", __func__); goto exit; } + bolero_clk_rsc_fs_gen_request(tx_priv->dev, + true); regcache_mark_dirty(regmap); regcache_sync_region(regmap, TX_START_OFFSET, @@ -236,8 +239,13 @@ static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv, regmap_update_bits(regmap, BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x00); - bolero_request_clock(tx_priv->dev, - TX_MACRO, MCLK_MUX0, false); + bolero_clk_rsc_fs_gen_request(tx_priv->dev, + false); + + bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + false); } } exit: @@ -278,33 +286,6 @@ static int tx_macro_mclk_event(struct snd_soc_dapm_widget *w, return ret; } -static int tx_macro_mclk_ctrl(struct device *dev, bool enable) -{ - struct tx_macro_priv *tx_priv = dev_get_drvdata(dev); - int ret = 0; - - if (enable) { - ret = clk_prepare_enable(tx_priv->tx_core_clk); - if (ret < 0) { - dev_err(dev, "%s:tx mclk enable failed\n", __func__); - goto exit; - } - ret = clk_prepare_enable(tx_priv->tx_npl_clk); - if (ret < 0) { - dev_err(dev, "%s:tx npl_clk enable failed\n", - __func__); - clk_disable_unprepare(tx_priv->tx_core_clk); - goto exit; - } - } else { - clk_disable_unprepare(tx_priv->tx_npl_clk); - clk_disable_unprepare(tx_priv->tx_core_clk); - } - -exit: - return ret; -} - static int tx_macro_event_handler(struct snd_soc_component *component, u16 event, u32 data) { @@ -1769,7 +1750,6 @@ static void tx_macro_init_ops(struct macro_ops *ops, ops->io_base = tx_io_base; ops->dai_ptr = tx_macro_dai; ops->num_dais = ARRAY_SIZE(tx_macro_dai); - ops->mclk_fn = tx_macro_mclk_ctrl; ops->event_handler = tx_macro_event_handler; ops->reg_wake_irq = tx_macro_reg_wake_irq; ops->set_port_map = tx_macro_set_port_map; @@ -1781,7 +1761,6 @@ static int tx_macro_probe(struct platform_device *pdev) struct tx_macro_priv *tx_priv = NULL; u32 tx_base_addr = 0, sample_rate = 0; char __iomem *tx_io_base = NULL; - struct clk *tx_core_clk = NULL, *tx_npl_clk = NULL; int ret = 0; const char *dmic_sample_rate = "qcom,tx-dmic-sample-rate"; @@ -1835,34 +1814,19 @@ static int tx_macro_probe(struct platform_device *pdev) tx_priv->swr_plat_data.bulk_write = NULL; tx_priv->swr_plat_data.clk = tx_macro_swrm_clock; tx_priv->swr_plat_data.handle_irq = NULL; - /* Register MCLK for tx macro */ - tx_core_clk = devm_clk_get(&pdev->dev, "tx_core_clk"); - if (IS_ERR(tx_core_clk)) { - ret = PTR_ERR(tx_core_clk); - dev_err(&pdev->dev, "%s: clk get %s failed %d\n", - __func__, "tx_core_clk", ret); - return ret; - } - tx_priv->tx_core_clk = tx_core_clk; - /* Register npl clk for soundwire */ - tx_npl_clk = devm_clk_get(&pdev->dev, "tx_npl_clk"); - if (IS_ERR(tx_npl_clk)) { - ret = PTR_ERR(tx_npl_clk); - dev_err(&pdev->dev, "%s: clk get %s failed %d\n", - __func__, "tx_npl_clk", ret); - return ret; - } - tx_priv->tx_npl_clk = tx_npl_clk; mutex_init(&tx_priv->mclk_lock); mutex_init(&tx_priv->swr_clk_lock); tx_macro_init_ops(&ops, tx_io_base); + ops.clk_id_req = TX_CORE_CLK; + ops.default_clk_id = TX_CORE_CLK; ret = bolero_register_macro(&pdev->dev, TX_MACRO, &ops); if (ret) { dev_err(&pdev->dev, "%s: register macro failed\n", __func__); goto err_reg_macro; } + schedule_work(&tx_priv->tx_macro_add_child_devices_work); return 0; err_reg_macro: diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 8789fce4fb5d..217800adcaa3 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -15,6 +15,7 @@ #include #include "bolero-cdc.h" #include "bolero-cdc-registers.h" +#include "bolero-clk-rsc.h" /* pm runtime auto suspend timer in msecs */ #define VA_AUTO_SUSPEND_DELAY 100 /* delay in msec */ @@ -94,7 +95,6 @@ struct va_macro_priv { struct device *dev; bool dec_active[VA_MACRO_NUM_DECIMATORS]; bool va_without_decimation; - struct clk *va_core_clk; struct mutex mclk_lock; struct snd_soc_component *component; struct hpf_work va_hpf_work[VA_MACRO_NUM_DECIMATORS]; @@ -114,6 +114,8 @@ struct va_macro_priv { u32 micb_voltage; u32 micb_current; int micb_users; + u16 default_clk_id; + u16 clk_id; }; static bool va_macro_get_data(struct snd_soc_component *component, @@ -153,15 +155,18 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, mutex_lock(&va_priv->mclk_lock); if (mclk_enable) { if (va_priv->va_mclk_users == 0) { - ret = bolero_request_clock(va_priv->dev, - VA_MACRO, - va_priv->mclk_mux_sel, true); + ret = bolero_clk_rsc_request_clock(va_priv->dev, + va_priv->default_clk_id, + va_priv->clk_id, + true); if (ret < 0) { dev_err(va_priv->dev, "%s: va request clock en failed\n", __func__); goto exit; } + bolero_clk_rsc_fs_gen_request(va_priv->dev, + true); regcache_mark_dirty(regmap); regcache_sync_region(regmap, VA_START_OFFSET, @@ -177,9 +182,12 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, } va_priv->va_mclk_users--; if (va_priv->va_mclk_users == 0) { - bolero_request_clock(va_priv->dev, - VA_MACRO, - va_priv->mclk_mux_sel, false); + bolero_clk_rsc_fs_gen_request(va_priv->dev, + false); + bolero_clk_rsc_request_clock(va_priv->dev, + va_priv->default_clk_id, + va_priv->clk_id, + false); } } exit: @@ -252,29 +260,6 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, return ret; } -static int va_macro_mclk_ctrl(struct device *dev, bool enable) -{ - struct va_macro_priv *va_priv = dev_get_drvdata(dev); - int ret = 0; - - if (enable) { - ret = clk_prepare_enable(va_priv->va_core_clk); - if (ret < 0) { - dev_err(dev, "%s:va mclk enable failed\n", __func__); - goto exit; - } - if (va_priv->mclk_mux_sel == MCLK_MUX1) - iowrite32(0x1, va_priv->va_island_mode_muxsel); - } else { - if (va_priv->mclk_mux_sel == MCLK_MUX1) - iowrite32(0x0, va_priv->va_island_mode_muxsel); - clk_disable_unprepare(va_priv->va_core_clk); - } - -exit: - return ret; -} - static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) { struct delayed_work *hpf_delayed_work; @@ -1581,7 +1566,6 @@ static void va_macro_init_ops(struct macro_ops *ops, ops->init = va_macro_init; ops->exit = va_macro_deinit; ops->io_base = va_io_base; - ops->mclk_fn = va_macro_mclk_ctrl; ops->event_handler = va_macro_event_handler; } @@ -1589,10 +1573,8 @@ static int va_macro_probe(struct platform_device *pdev) { struct macro_ops ops; struct va_macro_priv *va_priv; - u32 va_base_addr, sample_rate = 0, island_sel = 0; + u32 va_base_addr, sample_rate = 0; char __iomem *va_io_base; - char __iomem *va_muxsel_io = NULL; - struct clk *va_core_clk; bool va_without_decimation = false; const char *micb_supply_str = "va-vdd-micb-supply"; const char *micb_supply_str1 = "va-vdd-micb"; @@ -1600,7 +1582,7 @@ static int va_macro_probe(struct platform_device *pdev) const char *micb_current_str = "qcom,va-vdd-micb-current"; int ret = 0; const char *dmic_sample_rate = "qcom,va-dmic-sample-rate"; - u16 mclk_mux_sel = MCLK_MUX0; + u32 default_clk_id = 0; va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv), GFP_KERNEL); @@ -1639,53 +1621,6 @@ static int va_macro_probe(struct platform_device *pdev) } va_priv->va_io_base = va_io_base; - ret = of_property_read_u16(va_priv->dev->of_node, - "qcom,va-clk-mux-select", &mclk_mux_sel); - if (ret) { - dev_dbg(&pdev->dev, - "%s: could not find %s entry in dt, use default\n", - __func__, "qcom,va-clk-mux-select"); - } else { - if (mclk_mux_sel != MCLK_MUX0 && mclk_mux_sel != MCLK_MUX1) { - dev_err(&pdev->dev, - "%s: mclk_mux_sel: %d is invalid\n", - __func__, mclk_mux_sel); - return -EINVAL; - } - } - va_priv->mclk_mux_sel = mclk_mux_sel; - - if (va_priv->mclk_mux_sel == MCLK_MUX1) { - ret = of_property_read_u32(pdev->dev.of_node, - "qcom,va-island-mode-muxsel", - &island_sel); - if (ret) { - dev_err(&pdev->dev, - "%s: could not find %s entry in dt\n", - __func__, "qcom,va-island-mode-muxsel"); - return ret; - } else { - va_muxsel_io = devm_ioremap(&pdev->dev, - island_sel, 0x4); - if (!va_muxsel_io) { - dev_err(&pdev->dev, - "%s: ioremap failed for island_sel\n", - __func__); - return -ENOMEM; - } - } - va_priv->va_island_mode_muxsel = va_muxsel_io; - } - /* Register MCLK for va macro */ - va_core_clk = devm_clk_get(&pdev->dev, "va_core_clk"); - if (IS_ERR(va_core_clk)) { - ret = PTR_ERR(va_core_clk); - dev_err(&pdev->dev, "%s: clk get %s failed\n", - __func__, "va_core_clk"); - return ret; - } - va_priv->va_core_clk = va_core_clk; - if (of_parse_phandle(pdev->dev.of_node, micb_supply_str, 0)) { va_priv->micb_supply = devm_regulator_get(&pdev->dev, micb_supply_str1); @@ -1717,10 +1652,21 @@ static int va_macro_probe(struct platform_device *pdev) return ret; } } + ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id", + &default_clk_id); + if (ret) { + dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "qcom,default-clk-id"); + default_clk_id = VA_CORE_CLK; + } + va_priv->clk_id = VA_CORE_CLK; + va_priv->default_clk_id = default_clk_id; mutex_init(&va_priv->mclk_lock); dev_set_drvdata(&pdev->dev, va_priv); va_macro_init_ops(&ops, va_io_base, va_without_decimation); + ops.clk_id_req = va_priv->default_clk_id; + ops.default_clk_id = va_priv->default_clk_id; ret = bolero_register_macro(&pdev->dev, VA_MACRO, &ops); if (ret < 0) { dev_err(&pdev->dev, "%s: register macro failed\n", __func__); diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index b0a4b1e0f42d..dd3f4feba4ae 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -17,6 +17,7 @@ #include "bolero-cdc.h" #include "bolero-cdc-registers.h" #include "wsa-macro.h" +#include "bolero-clk-rsc.h" #define WSA_MACRO_MAX_OFFSET 0x1000 @@ -175,8 +176,6 @@ enum { * @swr_plat_data: Soundwire platform data * @wsa_macro_add_child_devices_work: work for adding child devices * @wsa_swr_gpio_p: used by pinctrl API - * @wsa_core_clk: MCLK for wsa macro - * @wsa_npl_clk: NPL clock for WSA soundwire * @component: codec handle * @rx_0_count: RX0 interpolation users * @rx_1_count: RX1 interpolation users @@ -201,8 +200,6 @@ struct wsa_macro_priv { struct wsa_macro_swr_ctrl_platform_data swr_plat_data; struct work_struct wsa_macro_add_child_devices_work; struct device_node *wsa_swr_gpio_p; - struct clk *wsa_core_clk; - struct clk *wsa_npl_clk; struct snd_soc_component *component; int rx_0_count; int rx_1_count; @@ -219,6 +216,8 @@ struct wsa_macro_priv { int is_softclip_on[WSA_MACRO_SOFTCLIP_MAX]; int softclip_clk_users[WSA_MACRO_SOFTCLIP_MAX]; struct wsa_macro_bcl_pmic_params bcl_pmic_params; + char __iomem *mclk_mode_muxsel; + u16 default_clk_id; }; static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component, @@ -808,14 +807,18 @@ static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv, mutex_lock(&wsa_priv->mclk_lock); if (mclk_enable) { if (wsa_priv->wsa_mclk_users == 0) { - ret = bolero_request_clock(wsa_priv->dev, - WSA_MACRO, MCLK_MUX0, true); + ret = bolero_clk_rsc_request_clock(wsa_priv->dev, + wsa_priv->default_clk_id, + wsa_priv->default_clk_id, + true); if (ret < 0) { dev_err(wsa_priv->dev, "%s: wsa request clock enable failed\n", __func__); goto exit; } + bolero_clk_rsc_fs_gen_request(wsa_priv->dev, + true); regcache_mark_dirty(regmap); regcache_sync_region(regmap, WSA_START_OFFSET, @@ -846,8 +849,13 @@ static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv, regmap_update_bits(regmap, BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x00); - bolero_request_clock(wsa_priv->dev, - WSA_MACRO, MCLK_MUX0, false); + bolero_clk_rsc_fs_gen_request(wsa_priv->dev, + false); + + bolero_clk_rsc_request_clock(wsa_priv->dev, + wsa_priv->default_clk_id, + wsa_priv->default_clk_id, + false); } } exit: @@ -888,35 +896,6 @@ static int wsa_macro_mclk_event(struct snd_soc_dapm_widget *w, return ret; } -static int wsa_macro_mclk_ctrl(struct device *dev, bool enable) -{ - struct wsa_macro_priv *wsa_priv = dev_get_drvdata(dev); - int ret = 0; - - if (!wsa_priv) - return -EINVAL; - - if (enable) { - ret = clk_prepare_enable(wsa_priv->wsa_core_clk); - if (ret < 0) { - dev_err(dev, "%s:wsa mclk enable failed\n", __func__); - goto exit; - } - ret = clk_prepare_enable(wsa_priv->wsa_npl_clk); - if (ret < 0) { - dev_err(dev, "%s:wsa npl_clk enable failed\n", - __func__); - clk_disable_unprepare(wsa_priv->wsa_core_clk); - goto exit; - } - } else { - clk_disable_unprepare(wsa_priv->wsa_npl_clk); - clk_disable_unprepare(wsa_priv->wsa_core_clk); - } -exit: - return ret; -} - static int wsa_macro_event_handler(struct snd_soc_component *component, u16 event, u32 data) { @@ -2809,7 +2788,6 @@ static void wsa_macro_init_ops(struct macro_ops *ops, ops->io_base = wsa_io_base; ops->dai_ptr = wsa_macro_dai; ops->num_dais = ARRAY_SIZE(wsa_macro_dai); - ops->mclk_fn = wsa_macro_mclk_ctrl; ops->event_handler = wsa_macro_event_handler; ops->set_port_map = wsa_macro_set_port_map; } @@ -2818,10 +2796,9 @@ static int wsa_macro_probe(struct platform_device *pdev) { struct macro_ops ops; struct wsa_macro_priv *wsa_priv; - u32 wsa_base_addr; + u32 wsa_base_addr, default_clk_id; char __iomem *wsa_io_base; int ret = 0; - struct clk *wsa_core_clk, *wsa_npl_clk; u8 bcl_pmic_params[3]; wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv), @@ -2861,24 +2838,13 @@ static int wsa_macro_probe(struct platform_device *pdev) wsa_priv->swr_plat_data.clk = wsa_swrm_clock; wsa_priv->swr_plat_data.handle_irq = NULL; - /* Register MCLK for wsa macro */ - wsa_core_clk = devm_clk_get(&pdev->dev, "wsa_core_clk"); - if (IS_ERR(wsa_core_clk)) { - ret = PTR_ERR(wsa_core_clk); - dev_err(&pdev->dev, "%s: clk get %s failed\n", - __func__, "wsa_core_clk"); - return ret; - } - wsa_priv->wsa_core_clk = wsa_core_clk; - /* Register npl clk for soundwire */ - wsa_npl_clk = devm_clk_get(&pdev->dev, "wsa_npl_clk"); - if (IS_ERR(wsa_npl_clk)) { - ret = PTR_ERR(wsa_npl_clk); - dev_err(&pdev->dev, "%s: clk get %s failed\n", - __func__, "wsa_npl_clk"); - return ret; + ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id", + &default_clk_id); + if (ret) { + dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "qcom,mux0-clk-id"); + default_clk_id = WSA_CORE_CLK; } - wsa_priv->wsa_npl_clk = wsa_npl_clk; ret = of_property_read_u8_array(pdev->dev.of_node, "qcom,wsa-bcl-pmic-params", bcl_pmic_params, @@ -2891,11 +2857,14 @@ static int wsa_macro_probe(struct platform_device *pdev) wsa_priv->bcl_pmic_params.sid = bcl_pmic_params[1]; wsa_priv->bcl_pmic_params.ppid = bcl_pmic_params[2]; } + wsa_priv->default_clk_id = default_clk_id; dev_set_drvdata(&pdev->dev, wsa_priv); mutex_init(&wsa_priv->mclk_lock); mutex_init(&wsa_priv->swr_clk_lock); wsa_macro_init_ops(&ops, wsa_io_base); + ops.clk_id_req = wsa_priv->default_clk_id; + ops.default_clk_id = wsa_priv->default_clk_id; ret = bolero_register_macro(&pdev->dev, WSA_MACRO, &ops); if (ret < 0) { dev_err(&pdev->dev, "%s: register macro failed\n", __func__); -- GitLab From 7e2eb2118a916a097857a0ef1928918af7288807 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Wed, 27 Mar 2019 14:49:25 -0700 Subject: [PATCH 0897/1645] dsp: voice_mhi: initialize pointer to NULL Initialize pointer to NULL to avoid any access to uninitialized value in case of a failure. Change-Id: I81ecb76a30b481f57fd62448e954c227ffbc421f Signed-off-by: Vikram Panduranga --- dsp/voice_mhi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/voice_mhi.c b/dsp/voice_mhi.c index 6c8a7fc46fe3..87572efa7e76 100644 --- a/dsp/voice_mhi.c +++ b/dsp/voice_mhi.c @@ -426,7 +426,7 @@ static int voice_mhi_pcie_up_callback(struct mhi_device *voice_mhi_dev, static void voice_mhi_pcie_down_callback(struct mhi_device *voice_mhi_dev) { dma_addr_t iova; - struct device *md; + struct device *md = NULL; mutex_lock(&voice_mhi_lcl.mutex); -- GitLab From d5f41ba7f4f3c53e349f9c1f7b50e2622f271b9d Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 14 Mar 2019 13:40:35 -0700 Subject: [PATCH 0898/1645] dsp: Remove redundant payload size check Due to redundant payload checks, ASM get param requests in RTAC mode fail with timeout errors. Fix this by removing the redundant payload checks. CRs-Fixed: 2372302 Change-Id: If08ec942f3530e132b5980da579ea1766d21c52b Signed-off-by: Vignesh Kulothungan --- dsp/q6asm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 6681dcb27497..b27163f35883 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1952,8 +1952,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) (data->opcode != ASM_DATA_EVENT_EOS) && (data->opcode != ASM_SESSION_EVENTX_OVERFLOW) && (data->opcode != ASM_SESSION_EVENT_RX_UNDERFLOW)) { - if (payload == NULL || (data->payload_size < (2 * sizeof(uint32_t)))) { - pr_err("%s: payload is null or invalid size[%d]\n", __func__, data->payload_size); + if (payload == NULL) { + pr_err("%s: payload is null\n", __func__); spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return -EINVAL; -- GitLab From e826ba5129f0737d7ed3976077c2402cf25b4a98 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 30 Mar 2019 03:19:27 +0530 Subject: [PATCH 0899/1645] ASoC: bolero: Enable TX clock during VA path setup Enable TX clock during VA path setup for SVA usecase to make sure LPASS audio is in active state. Change-Id: Ic835905e48919e3c97ab2b82b43b90a146f4f32e Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/va-macro.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 217800adcaa3..a4f3c7d557ed 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -248,6 +248,10 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: ret = va_macro_mclk_enable(va_priv, 1, true); + ret = bolero_clk_rsc_request_clock(va_priv->dev, + va_priv->default_clk_id, + TX_CORE_CLK, + true); break; case SND_SOC_DAPM_POST_PMD: va_macro_mclk_enable(va_priv, 0, true); @@ -584,6 +588,10 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, /* apply gain after decimator is enabled */ snd_soc_component_write(component, tx_gain_ctl_reg, snd_soc_component_read32(component, tx_gain_ctl_reg)); + bolero_clk_rsc_request_clock(va_priv->dev, + va_priv->default_clk_id, + TX_CORE_CLK, + false); break; case SND_SOC_DAPM_PRE_PMD: hpf_cut_off_freq = -- GitLab From 864f84377959e3f326749340e22801439221967a Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Fri, 5 Apr 2019 11:04:10 -0700 Subject: [PATCH 0900/1645] asoc: codecs: add null check before access Add null check before accessing wcd938x private data. Change-Id: Ia2226202deccccbd07e6c0d501daaded2b7e72d8 Signed-off-by: Vignesh Kulothungan --- asoc/codecs/wcd938x/wcd938x.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 6412fd9876f8..96d9b98759ff 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1355,6 +1355,13 @@ int wcd938x_micbias_control(struct snd_soc_component *component, __func__, micb_index); return -EINVAL; } + + if (NULL == wcd938x) { + dev_err(component->dev, + "%s: wcd938x private data is NULL\n", __func__); + return -EINVAL; + } + switch (micb_num) { case MIC_BIAS_1: micb_reg = WCD938X_ANA_MICB1; -- GitLab From bb650fc65c475d720d902266656e8e3b68122806 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 10 Apr 2019 04:32:50 +0530 Subject: [PATCH 0901/1645] ASoC: wcd938x: Add support for wcd938x codec variants Add support for wcd938x codec variants. Changes detect the variant and enable the corresponding features supported by the codec variant. Change-Id: Ib990465b42b903174391bb87115af47431b862ec Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd938x/wcd938x.c | 50 +++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 6412fd9876f8..ed5609fbf157 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -39,8 +39,7 @@ enum { WCD9380 = 0, - WCD9385, - WCD9385FX, + WCD9385 = 5, }; enum { @@ -1755,6 +1754,14 @@ static int wcd938x_set_compander(struct snd_kcontrol *kcontrol, return 0; } +static const char * const tx_mode_mux_text_wcd9380[] = { + "ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP", +}; + +static const struct soc_enum tx_mode_mux_enum_wcd9380 = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tx_mode_mux_text_wcd9380), + tx_mode_mux_text_wcd9380); + static const char * const tx_mode_mux_text[] = { "ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP", "ADC_ULP1", "ADC_ULP2", @@ -1773,10 +1780,18 @@ static const struct soc_enum rx_hph_mode_mux_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text), rx_hph_mode_mux_text); -static const struct snd_kcontrol_new wcd938x_snd_controls[] = { - SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum, - wcd938x_rx_hph_mode_get, wcd938x_rx_hph_mode_put), +static const struct snd_kcontrol_new wcd9380_snd_controls[] = { + SOC_ENUM_EXT("TX0 MODE", tx_mode_mux_enum_wcd9380, + wcd938x_tx_mode_get, wcd938x_tx_mode_put), + SOC_ENUM_EXT("TX1 MODE", tx_mode_mux_enum_wcd9380, + wcd938x_tx_mode_get, wcd938x_tx_mode_put), + SOC_ENUM_EXT("TX2 MODE", tx_mode_mux_enum_wcd9380, + wcd938x_tx_mode_get, wcd938x_tx_mode_put), + SOC_ENUM_EXT("TX3 MODE", tx_mode_mux_enum_wcd9380, + wcd938x_tx_mode_get, wcd938x_tx_mode_put), +}; +static const struct snd_kcontrol_new wcd9385_snd_controls[] = { SOC_ENUM_EXT("TX0 MODE", tx_mode_mux_enum, wcd938x_tx_mode_get, wcd938x_tx_mode_put), SOC_ENUM_EXT("TX1 MODE", tx_mode_mux_enum, @@ -1785,6 +1800,11 @@ static const struct snd_kcontrol_new wcd938x_snd_controls[] = { wcd938x_tx_mode_get, wcd938x_tx_mode_put), SOC_ENUM_EXT("TX3 MODE", tx_mode_mux_enum, wcd938x_tx_mode_get, wcd938x_tx_mode_put), +}; + +static const struct snd_kcontrol_new wcd938x_snd_controls[] = { + SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum, + wcd938x_rx_hph_mode_get, wcd938x_rx_hph_mode_put), SOC_SINGLE_EXT("HPHL_COMP Switch", SND_SOC_NOPM, 0, 1, 0, wcd938x_get_compander, wcd938x_set_compander), @@ -2406,6 +2426,26 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) wcd_cls_h_init(&wcd938x->clsh_info); wcd938x_init_reg(component); + if (wcd938x->variant == WCD9380) { + ret = snd_soc_add_component_controls(component, wcd9380_snd_controls, + ARRAY_SIZE(wcd9380_snd_controls)); + if (ret < 0) { + dev_err(component->dev, + "%s: Failed to add snd ctrls for variant: %d\n", + __func__, wcd938x->variant); + goto err_hwdep; + } + } + if (wcd938x->variant == WCD9385) { + ret = snd_soc_add_component_controls(component, wcd9385_snd_controls, + ARRAY_SIZE(wcd9385_snd_controls)); + if (ret < 0) { + dev_err(component->dev, + "%s: Failed to add snd ctrls for variant: %d\n", + __func__, wcd938x->variant); + goto err_hwdep; + } + } wcd938x->version = WCD938X_VERSION_1_0; /* Register event notifier */ wcd938x->nblock.notifier_call = wcd938x_event_notify; -- GitLab From a7397947d35c5181f2ae9c8124b2fff98a50d971 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 19 Mar 2019 03:14:23 +0530 Subject: [PATCH 0902/1645] ASoC: bolero: Enable RCO for VA usecase Add support to enable RCO during VA usecase. Change-Id: Ic6b640f62a8a88b5d5b616fc05798917913356ed Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/tx-macro.c | 176 +++++++++++++++++++++++++++++----- 1 file changed, 153 insertions(+), 23 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index b7d7d37284fd..8ef47699f50e 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -110,6 +110,11 @@ enum { ANC_FB_TUNE1 }; +enum { + TX_MCLK, + VA_MCLK, +}; + struct tx_mute_work { struct tx_macro_priv *tx_priv; u32 decimator; @@ -152,6 +157,7 @@ struct tx_macro_priv { int child_count; int tx_swr_clk_cnt; int va_swr_clk_cnt; + int swr_clk_type; }; static bool tx_macro_get_data(struct snd_soc_component *component, @@ -1457,33 +1463,60 @@ static const struct snd_kcontrol_new tx_macro_snd_controls[] = { 0, -84, 40, digital_gain), }; -static int tx_macro_swrm_clock(void *handle, bool enable) +static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, + struct regmap *regmap, int clk_type, + bool enable) { - struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle; - struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL); int ret = 0; - if (regmap == NULL) { - dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__); - return -EINVAL; - } - - mutex_lock(&tx_priv->swr_clk_lock); + dev_dbg(tx_priv->dev, "%s: clock type %s, enable: %s\n", + __func__, (clk_type ? "VA_MCLK" : "TX_MCLK"), + (enable ? "enable" : "disable")); - dev_dbg(tx_priv->dev, "%s: swrm clock %s\n", - __func__, (enable ? "enable" : "disable")); if (enable) { if (tx_priv->swr_clk_users == 0) { msm_cdc_pinctrl_select_active_state( tx_priv->tx_swr_gpio_p); - ret = tx_macro_mclk_enable(tx_priv, 1); - if (ret < 0) { - msm_cdc_pinctrl_select_sleep_state( - tx_priv->tx_swr_gpio_p); - dev_err(tx_priv->dev, - "%s: request clock enable failed\n", - __func__); - goto exit; + + ret = bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + true); + if (clk_type == TX_MCLK) { + ret = tx_macro_mclk_enable(tx_priv, 1); + if (ret < 0) { + msm_cdc_pinctrl_select_sleep_state( + tx_priv->tx_swr_gpio_p); + dev_err_ratelimited(tx_priv->dev, + "%s: request clock enable failed\n", + __func__); + goto done; + } + } + if (clk_type == VA_MCLK) { + ret = bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + VA_CORE_CLK, + true); + if (ret < 0) { + msm_cdc_pinctrl_select_sleep_state( + tx_priv->tx_swr_gpio_p); + dev_err_ratelimited(tx_priv->dev, + "%s: swr request clk failed\n", + __func__); + goto done; + } + if (tx_priv->tx_mclk_users == 0) { + regmap_update_bits(regmap, + BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK, + 0x01, 0x01); + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); + } } if (tx_priv->reset_swr) regmap_update_bits(regmap, @@ -1496,29 +1529,126 @@ static int tx_macro_swrm_clock(void *handle, bool enable) regmap_update_bits(regmap, BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, 0x02, 0x00); + ret = bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + false); tx_priv->reset_swr = false; } tx_priv->swr_clk_users++; } else { if (tx_priv->swr_clk_users <= 0) { - dev_err(tx_priv->dev, + dev_err_ratelimited(tx_priv->dev, "tx swrm clock users already 0\n"); tx_priv->swr_clk_users = 0; - goto exit; + return 0; } tx_priv->swr_clk_users--; if (tx_priv->swr_clk_users == 0) { + ret = bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + true); regmap_update_bits(regmap, BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x00); - tx_macro_mclk_enable(tx_priv, 0); + if (clk_type == TX_MCLK) + tx_macro_mclk_enable(tx_priv, 0); + if (clk_type == VA_MCLK) { + if (tx_priv->tx_mclk_users == 0) { + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x00); + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x00); + } + ret = bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + VA_CORE_CLK, + false); + if (ret < 0) { + dev_err_ratelimited(tx_priv->dev, + "%s: swr request clk failed\n", + __func__); + goto done; + } + } + ret = bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + false); msm_cdc_pinctrl_select_sleep_state( tx_priv->tx_swr_gpio_p); } } + return 0; + +done: + bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + false); + return ret; +} + +static int tx_macro_swrm_clock(void *handle, bool enable) +{ + struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle; + struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL); + int ret = 0; + + if (regmap == NULL) { + dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__); + return -EINVAL; + } + + mutex_lock(&tx_priv->swr_clk_lock); + dev_dbg(tx_priv->dev, "%s: swrm clock %s\n", + __func__, (enable ? "enable" : "disable")); + + if (enable) { + /*For standalone VA usecase, enable VA macro clock */ + if (tx_priv->va_swr_clk_cnt && !tx_priv->tx_swr_clk_cnt + && (tx_priv->swr_clk_type == TX_MCLK)) { + ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap, + VA_MCLK, enable); + if (ret) + goto done; + tx_priv->swr_clk_type = VA_MCLK; + } else { + /* Disable VA MCLK if its already enabled */ + if (tx_priv->swr_clk_type == VA_MCLK) + tx_macro_tx_va_mclk_enable(tx_priv, + regmap, VA_MCLK, false); + ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap, + TX_MCLK, enable); + if (ret) + goto done; + tx_priv->swr_clk_type = TX_MCLK; + } + } else { + if (tx_priv->swr_clk_type == VA_MCLK) { + ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap, + VA_MCLK, enable); + if (ret) + goto done; + tx_priv->swr_clk_type = TX_MCLK; + } else { + ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap, + TX_MCLK, enable); + if (tx_priv->va_swr_clk_cnt) { + ret = tx_macro_tx_va_mclk_enable(tx_priv, + regmap, VA_MCLK, true); + if (ret) + goto done; + tx_priv->swr_clk_type = VA_MCLK; + } + } + } dev_dbg(tx_priv->dev, "%s: swrm clock users %d\n", __func__, tx_priv->swr_clk_users); -exit: +done: mutex_unlock(&tx_priv->swr_clk_lock); return ret; } -- GitLab From 7601cc6db66bc2471299f879b1727d37c40fc485 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 30 Mar 2019 03:00:52 +0530 Subject: [PATCH 0903/1645] ASoC: Bolero: Vote for LPASS HW core during register access Vote for LPASS HW core in soundwire clock request before soundwire register access to avoid LPASS going to sleep. Change-Id: I1e54ece19130cf6bd63fbf75a8a0716856c3b73e Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/rx-macro.c | 20 ++++++++++++++++++++ asoc/codecs/bolero/tx-macro.c | 28 ++++++++++++++++++++++++++-- asoc/codecs/bolero/wsa-macro.c | 21 +++++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 0fc13eec41bf..0edc64a72169 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -20,6 +21,7 @@ #include "bolero-cdc-registers.h" #include "bolero-clk-rsc.h" +#define AUTO_SUSPEND_DELAY 50 /* delay in msec */ #define RX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\ @@ -3235,6 +3237,7 @@ static int rx_swrm_clock(void *handle, bool enable) dev_dbg(rx_priv->dev, "%s: swrm clock %s\n", __func__, (enable ? "enable" : "disable")); if (enable) { + pm_runtime_get_sync(rx_priv->dev); if (rx_priv->swr_clk_users == 0) { msm_cdc_pinctrl_select_active_state( rx_priv->rx_swr_gpio_p); @@ -3260,6 +3263,8 @@ static int rx_swrm_clock(void *handle, bool enable) 0x02, 0x00); rx_priv->reset_swr = false; } + pm_runtime_mark_last_busy(rx_priv->dev); + pm_runtime_put_autosuspend(rx_priv->dev); rx_priv->swr_clk_users++; } else { if (rx_priv->swr_clk_users <= 0) { @@ -3647,6 +3652,10 @@ static int rx_macro_probe(struct platform_device *pdev) goto err_reg_macro; } schedule_work(&rx_priv->rx_macro_add_child_devices_work); + pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_enable(&pdev->dev); return 0; @@ -3670,6 +3679,8 @@ static int rx_macro_remove(struct platform_device *pdev) count < RX_MACRO_CHILD_DEVICES_MAX; count++) platform_device_unregister(rx_priv->pdev_child_devices[count]); + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); bolero_unregister_macro(&pdev->dev, RX_MACRO); mutex_destroy(&rx_priv->mclk_lock); mutex_destroy(&rx_priv->swr_clk_lock); @@ -3682,10 +3693,19 @@ static const struct of_device_id rx_macro_dt_match[] = { {} }; +static const struct dev_pm_ops bolero_dev_pm_ops = { + SET_RUNTIME_PM_OPS( + bolero_runtime_suspend, + bolero_runtime_resume, + NULL + ) +}; + static struct platform_driver rx_macro_driver = { .driver = { .name = "rx_macro", .owner = THIS_MODULE, + .pm = &bolero_dev_pm_ops, .of_match_table = rx_macro_dt_match, }, .probe = rx_macro_probe, diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 8ef47699f50e..49b7da573525 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +19,7 @@ #include "bolero-cdc-registers.h" #include "bolero-clk-rsc.h" +#define AUTO_SUSPEND_DELAY 50 /* delay in msec */ #define TX_MACRO_MAX_OFFSET 0x1000 #define NUM_DECIMATORS 8 @@ -1469,9 +1471,10 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, { int ret = 0; - dev_dbg(tx_priv->dev, "%s: clock type %s, enable: %s\n", + dev_dbg(tx_priv->dev, + "%s: clock type %s, enable: %s tx_mclk_users: %d\n", __func__, (clk_type ? "VA_MCLK" : "TX_MCLK"), - (enable ? "enable" : "disable")); + (enable ? "enable" : "disable"), tx_priv->tx_mclk_users); if (enable) { if (tx_priv->swr_clk_users == 0) { @@ -1518,6 +1521,8 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, 0x01, 0x01); } } + dev_dbg(tx_priv->dev, "%s: reset_swr: %d\n", + __func__, tx_priv->reset_swr); if (tx_priv->reset_swr) regmap_update_bits(regmap, BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, @@ -1608,6 +1613,7 @@ static int tx_macro_swrm_clock(void *handle, bool enable) __func__, (enable ? "enable" : "disable")); if (enable) { + pm_runtime_get_sync(tx_priv->dev); /*For standalone VA usecase, enable VA macro clock */ if (tx_priv->va_swr_clk_cnt && !tx_priv->tx_swr_clk_cnt && (tx_priv->swr_clk_type == TX_MCLK)) { @@ -1627,6 +1633,8 @@ static int tx_macro_swrm_clock(void *handle, bool enable) goto done; tx_priv->swr_clk_type = TX_MCLK; } + pm_runtime_mark_last_busy(tx_priv->dev); + pm_runtime_put_autosuspend(tx_priv->dev); } else { if (tx_priv->swr_clk_type == VA_MCLK) { ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap, @@ -2014,6 +2022,11 @@ static int tx_macro_probe(struct platform_device *pdev) } schedule_work(&tx_priv->tx_macro_add_child_devices_work); + pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_enable(&pdev->dev); + return 0; err_reg_macro: mutex_destroy(&tx_priv->mclk_lock); @@ -2036,6 +2049,8 @@ static int tx_macro_remove(struct platform_device *pdev) count < TX_MACRO_CHILD_DEVICES_MAX; count++) platform_device_unregister(tx_priv->pdev_child_devices[count]); + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); mutex_destroy(&tx_priv->mclk_lock); mutex_destroy(&tx_priv->swr_clk_lock); bolero_unregister_macro(&pdev->dev, TX_MACRO); @@ -2048,10 +2063,19 @@ static const struct of_device_id tx_macro_dt_match[] = { {} }; +static const struct dev_pm_ops bolero_dev_pm_ops = { + SET_RUNTIME_PM_OPS( + bolero_runtime_suspend, + bolero_runtime_resume, + NULL + ) +}; + static struct platform_driver tx_macro_driver = { .driver = { .name = "tx_macro", .owner = THIS_MODULE, + .pm = &bolero_dev_pm_ops, .of_match_table = tx_macro_dt_match, }, .probe = tx_macro_probe, diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index dd3f4feba4ae..c8a5e1d68291 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -19,6 +20,7 @@ #include "wsa-macro.h" #include "bolero-clk-rsc.h" +#define AUTO_SUSPEND_DELAY 50 /* delay in msec */ #define WSA_MACRO_MAX_OFFSET 0x1000 #define WSA_MACRO_RX_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ @@ -2548,6 +2550,7 @@ static int wsa_swrm_clock(void *handle, bool enable) dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n", __func__, (enable ? "enable" : "disable")); if (enable) { + pm_runtime_get_sync(wsa_priv->dev); if (wsa_priv->swr_clk_users == 0) { msm_cdc_pinctrl_select_active_state( wsa_priv->wsa_swr_gpio_p); @@ -2573,6 +2576,8 @@ static int wsa_swrm_clock(void *handle, bool enable) 0x02, 0x00); wsa_priv->reset_swr = false; } + pm_runtime_mark_last_busy(wsa_priv->dev); + pm_runtime_put_autosuspend(wsa_priv->dev); wsa_priv->swr_clk_users++; } else { if (wsa_priv->swr_clk_users <= 0) { @@ -2871,6 +2876,11 @@ static int wsa_macro_probe(struct platform_device *pdev) goto reg_macro_fail; } schedule_work(&wsa_priv->wsa_macro_add_child_devices_work); + pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_enable(&pdev->dev); + return ret; reg_macro_fail: mutex_destroy(&wsa_priv->mclk_lock); @@ -2892,6 +2902,8 @@ static int wsa_macro_remove(struct platform_device *pdev) count < WSA_MACRO_CHILD_DEVICES_MAX; count++) platform_device_unregister(wsa_priv->pdev_child_devices[count]); + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); bolero_unregister_macro(&pdev->dev, WSA_MACRO); mutex_destroy(&wsa_priv->mclk_lock); mutex_destroy(&wsa_priv->swr_clk_lock); @@ -2903,10 +2915,19 @@ static const struct of_device_id wsa_macro_dt_match[] = { {} }; +static const struct dev_pm_ops bolero_dev_pm_ops = { + SET_RUNTIME_PM_OPS( + bolero_runtime_suspend, + bolero_runtime_resume, + NULL + ) +}; + static struct platform_driver wsa_macro_driver = { .driver = { .name = "wsa_macro", .owner = THIS_MODULE, + .pm = &bolero_dev_pm_ops, .of_match_table = wsa_macro_dt_match, }, .probe = wsa_macro_probe, -- GitLab From 3325ee5475f4e318a8b647c19e429857e9cdcd9f Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 18 Jan 2019 16:50:58 -0800 Subject: [PATCH 0904/1645] dsp: afe: check for payload size before payload access Check if payload data is big enough before accessing the data in it. Change-Id: I939f205a8cebf6ef4859f81fae5429bca013d540 Signed-off-by: Karthikeyan Mani --- dsp/q6afe.c | 45 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index fd66571dffbb..0002d82a125c 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -400,6 +400,11 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, /* Set command specific details */ switch (opcode) { case AFE_PORT_CMDRSP_GET_PARAM_V2: + if (payload_size < (5 * sizeof(uint32_t))) { + pr_err("%s: Error: size %d is less than expected\n", + __func__, payload_size); + return -EINVAL; + } expected_size += sizeof(struct param_hdr_v1); param_hdr.module_id = payload[1]; param_hdr.instance_id = INSTANCE_ID_0; @@ -408,7 +413,17 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, data_start = &payload[4]; break; case AFE_PORT_CMDRSP_GET_PARAM_V3: + if (payload_size < (6 * sizeof(uint32_t))) { + pr_err("%s: Error: size %d is less than expected\n", + __func__, payload_size); + return -EINVAL; + } expected_size += sizeof(struct param_hdr_v3); + if (payload_size < expected_size) { + pr_err("%s: Error: size %d is less than expected\n", + __func__, payload_size); + return -EINVAL; + } memcpy(¶m_hdr, &payload[1], sizeof(struct param_hdr_v3)); data_start = &payload[5]; break; @@ -597,6 +612,7 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) { uint32_t *payload = data->payload; uint32_t param_id; + uint32_t param_id_pos = 0; if (!payload || (data->token >= AFE_MAX_PORTS)) { pr_err("%s: Error: size %d payload %pK token %d\n", @@ -605,9 +621,23 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) return -EINVAL; } - param_id = (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) ? - payload[3] : - payload[2]; + if (rtac_make_afe_callback(data->payload, + data->payload_size)) + return 0; + + if (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) + param_id_pos = 4; + else + param_id_pos = 3; + + if (data->payload_size >= param_id_pos * sizeof(uint32_t)) + param_id = payload[param_id_pos - 1]; + else { + pr_err("%s: Error: size %d is less than expected\n", + __func__, data->payload_size); + return -EINVAL; + } + if (param_id == AUDPROC_PARAM_ID_FFV_DOA_TRACKING_MONITOR) { doa_tracking_mon_afe_cb_handler(data->opcode, data->payload, data->payload_size); @@ -615,10 +645,6 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) av_dev_drift_afe_cb_handler(data->opcode, data->payload, data->payload_size); } else { - if (rtac_make_afe_callback(data->payload, - data->payload_size)) - return 0; - if (sp_make_afe_callback(data->opcode, data->payload, data->payload_size)) return -EINVAL; @@ -645,6 +671,11 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) payload = data->payload; if (data->opcode == APR_BASIC_RSP_RESULT) { + if (data->payload_size < (2 * sizeof(uint32_t))) { + pr_err("%s: Error: size %d is less than expected\n", + __func__, data->payload_size); + return -EINVAL; + } pr_debug("%s:opcode = 0x%x cmd = 0x%x status = 0x%x token=%d\n", __func__, data->opcode, payload[0], payload[1], data->token); -- GitLab From 6d8ecddd3cb076e4c5c59cc84f9439752a0d8584 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 11 Apr 2019 11:06:47 +0800 Subject: [PATCH 0905/1645] asoc: routing: set/clear FE/BE route for lsm Set/clear correct FE/BE route for LSM in LSM put funtion to avoid mixer control initial value is not set from userspace after audio server restart. Change-Id: Ic415bb51cbaf887c4ddacf9e7062ec28a36674e4 Signed-off-by: Meng Wang --- asoc/msm-pcm-routing-v2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 5a75609149d0..fc1649813b40 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1989,6 +1989,10 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) if (!route_check_fe_id_adm_support(val)) { /* ignore adm open if not supported for fe_id */ pr_debug("%s: No ADM support for fe id %d\n", __func__, val); + if (set) + set_bit(val, &msm_bedais[reg].fe_sessions[0]); + else + clear_bit(val, &msm_bedais[reg].fe_sessions[0]); return; } -- GitLab From 1a4dd6d9ac9632ab58de57d0b02ff34c74871b5b Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 2 Apr 2019 15:21:54 +0530 Subject: [PATCH 0906/1645] asoc: Fix aux path noise issue Observing noise on aux path playback. Update sequences on digital side and swr port params as per latest HW sequence recommendation. Change-Id: Ic07ec35b091985ef0146957ceca830bd1162e7ec Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 9 +++++++-- asoc/sm8250-port-config.h | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 0fc13eec41bf..290d9e07eee6 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1621,6 +1621,9 @@ static int rx_macro_config_classh(struct snd_soc_component *component, 0x40, 0x40); break; case INTERP_AUX: + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX2_RX_PATH_CFG0, + 0x08, 0x08); snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX2_RX_PATH_CFG0, 0x10, 0x10); @@ -2195,16 +2198,18 @@ static int rx_macro_enable_interp_clk(struct snd_soc_component *component, (interp_idx * RX_MACRO_RX_PATH_OFFSET); dsm_reg = BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL + (interp_idx * RX_MACRO_RX_PATH_OFFSET); + if (interp_idx == INTERP_AUX) + dsm_reg = BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL; rx_cfg2_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG2 + (interp_idx * RX_MACRO_RX_PATH_OFFSET); if (SND_SOC_DAPM_EVENT_ON(event)) { if (rx_priv->main_clk_users[interp_idx] == 0) { - snd_soc_component_update_bits(component, dsm_reg, - 0x01, 0x01); /* Main path PGA mute enable */ snd_soc_component_update_bits(component, main_reg, 0x10, 0x10); + snd_soc_component_update_bits(component, dsm_reg, + 0x01, 0x01); /* Clk enable */ snd_soc_component_update_bits(component, main_reg, 0x20, 0x20); diff --git a/asoc/sm8250-port-config.h b/asoc/sm8250-port-config.h index 0a33c5fb6f58..503d514ba6fa 100644 --- a/asoc/sm8250-port-config.h +++ b/asoc/sm8250-port-config.h @@ -29,7 +29,7 @@ static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = { {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1}, {31, 0, 0, 3, 6, 7, 0, 0xFF, 0}, {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0}, - {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0}, + {7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, {0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0}, }; -- GitLab From 16e535969ba0ddb07b93b3fd9e976d38678659d3 Mon Sep 17 00:00:00 2001 From: Kunlei Zhang Date: Wed, 23 Jan 2019 17:18:19 +0800 Subject: [PATCH 0907/1645] lsm: check payload size validity before using it as array index Payload size validity is not checked before using it in array index. Check payload size to avoid out-of-boundary memory. Change-Id: Ic0b06bb331fc1753ff7543bb218ab12d6a4a3ca8 Signed-off-by: Kunlei Zhang --- asoc/msm-lsm-client.c | 62 ++++++++++++++++++++++++++++++++++++------- dsp/q6lsm.c | 16 ++++++++--- include/dsp/q6lsm.h | 2 +- 3 files changed, 66 insertions(+), 14 deletions(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index b101b377326d..3a5707e0de8d 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -196,7 +196,8 @@ static int lsm_lab_buffer_sanity(struct lsm_priv *prtd, } static void lsm_event_handler(uint32_t opcode, uint32_t token, - uint32_t *payload, void *priv) + uint32_t *payload, uint16_t client_size, + void *priv) { unsigned long flags; struct lsm_priv *prtd = priv; @@ -279,15 +280,27 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, } case LSM_SESSION_EVENT_DETECTION_STATUS: + if (client_size < 3 * sizeof(uint8_t)) { + dev_err(rtd->dev, + "%s: client_size has invalid size[%d]\n", + __func__, client_size); + return; + } status = (uint16_t)((uint8_t *)payload)[0]; payload_size = (uint16_t)((uint8_t *)payload)[2]; index = 4; dev_dbg(rtd->dev, "%s: event detect status = %d payload size = %d\n", __func__, status, payload_size); - break; + break; case LSM_SESSION_EVENT_DETECTION_STATUS_V2: + if (client_size < 2 * sizeof(uint8_t)) { + dev_err(rtd->dev, + "%s: client_size has invalid size[%d]\n", + __func__, client_size); + return; + } status = (uint16_t)((uint8_t *)payload)[0]; payload_size = (uint16_t)((uint8_t *)payload)[1]; index = 2; @@ -297,6 +310,12 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, break; case LSM_SESSION_EVENT_DETECTION_STATUS_V3: + if (client_size < 2 * (sizeof(uint32_t) + sizeof(uint8_t))) { + dev_err(rtd->dev, + "%s: client_size has invalid size[%d]\n", + __func__, client_size); + return; + } event_ts_lsw = ((uint32_t *)payload)[0]; event_ts_msw = ((uint32_t *)payload)[1]; status = (uint16_t)((uint8_t *)payload)[8]; @@ -310,6 +329,13 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, case LSM_SESSION_DETECTION_ENGINE_GENERIC_EVENT: { struct snd_lsm_event_status *tmp; + if (client_size < 2 * sizeof(uint16_t)) { + dev_err(rtd->dev, + "%s: client_size has invalid size[%d]\n", + __func__, client_size); + return; + } + status = ((uint16_t *)payload)[0]; payload_size = ((uint16_t *)payload)[1]; @@ -332,8 +358,16 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, prtd->det_event = tmp; prtd->det_event->status = status; prtd->det_event->payload_size = payload_size; - memcpy(prtd->det_event->payload, &((uint8_t *)payload)[4], - payload_size); + if (client_size >= payload_size + 4) { + memcpy(prtd->det_event->payload, + &((uint8_t *)payload)[4], payload_size); + } else { + spin_unlock_irqrestore(&prtd->event_lock, flags); + dev_err(rtd->dev, + "%s: Failed to copy memory with invalid size = %d\n", + __func__, payload_size); + return; + } prtd->event_avail = 1; spin_unlock_irqrestore(&prtd->event_lock, flags); wake_up(&prtd->event_wait); @@ -375,12 +409,20 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, prtd->event_status->payload_size = payload_size; if (likely(prtd->event_status)) { - memcpy(prtd->event_status->payload, - &((uint8_t *)payload)[index], - payload_size); - prtd->event_avail = 1; - spin_unlock_irqrestore(&prtd->event_lock, flags); - wake_up(&prtd->event_wait); + if (client_size >= (payload_size + index)) { + memcpy(prtd->event_status->payload, + &((uint8_t *)payload)[index], + payload_size); + prtd->event_avail = 1; + spin_unlock_irqrestore(&prtd->event_lock, flags); + wake_up(&prtd->event_wait); + } else { + spin_unlock_irqrestore(&prtd->event_lock, flags); + dev_err(rtd->dev, + "%s: Failed to copy memory with invalid size = %d\n", + __func__, payload_size); + return; + } } else { spin_unlock_irqrestore(&prtd->event_lock, flags); dev_err(rtd->dev, diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 6af7f6953507..c87a70181938 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -153,7 +153,8 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) struct lsm_cmd_read_done read_done; token = data->token; - if (data->payload_size > sizeof(read_done)) { + if (data->payload_size > sizeof(read_done) || + data->payload_size < 6 * sizeof(payload[0])) { pr_err("%s: read done error payload size %d expected size %zd\n", __func__, data->payload_size, sizeof(read_done)); @@ -171,6 +172,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) if (client->cb) client->cb(data->opcode, data->token, (void *)&read_done, + sizeof(read_done), client->priv); return 0; } else if (data->opcode == APR_BASIC_RSP_RESULT) { @@ -198,6 +200,11 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) __func__, token, client->session); return -EINVAL; } + if (data->payload_size < 2 * sizeof(payload[0])) { + pr_err("%s: payload has invalid size[%d]\n", + __func__, data->payload_size); + return -EINVAL; + } client->cmd_err_code = payload[1]; if (client->cmd_err_code) pr_err("%s: cmd 0x%x failed status %d\n", @@ -218,7 +225,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) if (client->cb) client->cb(data->opcode, data->token, data->payload, - client->priv); + data->payload_size, client->priv); return 0; } @@ -1791,6 +1798,8 @@ static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv) "proc 0x%x SID 0x%x\n", __func__, data->opcode, data->reset_event, data->reset_proc, sid); + if (sid < LSM_MIN_SESSION_ID || sid > LSM_MAX_SESSION_ID) + pr_err("%s: Invalid session %d\n", __func__, sid); apr_reset(lsm_common.apr); lsm_common.apr = NULL; atomic_set(&lsm_common.apr_users, 0); @@ -1855,7 +1864,8 @@ static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv) } if (client->cb) client->cb(data->opcode, data->token, - data->payload, client->priv); + data->payload, data->payload_size, + client->priv); return 0; } diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h index 758bba0ec30e..e4a007f85356 100644 --- a/include/dsp/q6lsm.h +++ b/include/dsp/q6lsm.h @@ -21,7 +21,7 @@ #define LSM_API_VERSION_V3 3 typedef void (*lsm_app_cb)(uint32_t opcode, uint32_t token, - uint32_t *payload, void *priv); + uint32_t *payload, uint16_t client_size, void *priv); struct lsm_sound_model { dma_addr_t phys; -- GitLab From 9d7693030eef30c32cc5c650d16ddeca14669cbf Mon Sep 17 00:00:00 2001 From: Josh Kirsch Date: Tue, 10 Apr 2018 17:25:42 -0700 Subject: [PATCH 0908/1645] ASoC: msm: qdsp6v2: Add back dapm routes needed for SDA845 Add back dapm voice stub and voice stub 2 routes. Needed for SDA845. Change-Id: Iacf680461fe7e2364ec1333dcbb0a6c3b671c9aa Signed-off-by: Josh Kirsch --- asoc/msm-pcm-routing-v2.c | 76 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 5a75609149d0..e15eacc6a3e5 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -12618,6 +12618,14 @@ static const struct snd_kcontrol_new sec_mi2s_rx_voice_mixer_controls[] = { MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, @@ -12779,6 +12787,14 @@ static const struct snd_kcontrol_new mi2s_rx_voice_mixer_controls[] = { MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, @@ -12799,23 +12815,31 @@ static const struct snd_kcontrol_new mi2s_rx_voice_mixer_controls[] = { static const struct snd_kcontrol_new pri_mi2s_rx_voice_mixer_controls[] = { SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; @@ -12871,6 +12895,14 @@ static const struct snd_kcontrol_new tert_mi2s_rx_voice_mixer_controls[] = { MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, @@ -12894,6 +12926,14 @@ static const struct snd_kcontrol_new quat_mi2s_rx_voice_mixer_controls[] = { MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, @@ -12917,6 +12957,14 @@ static const struct snd_kcontrol_new quin_mi2s_rx_voice_mixer_controls[] = { MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, @@ -13838,6 +13886,10 @@ static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = { MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, @@ -22060,6 +22112,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"}, {"SEC_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, {"SEC_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"SEC_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"SEC_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, @@ -22159,6 +22213,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"HDMI", NULL, "HDMI_DL_HL"}, {"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, {"MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, @@ -22166,6 +22222,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"}, {"PRI_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, {"PRI_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"PRI_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"PRI_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, @@ -22187,6 +22245,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_Voice Mixer"}, {"TERT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, {"TERT_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"TERT_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"TERT_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, @@ -22194,12 +22254,16 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX_Voice Mixer"}, {"QUAT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, {"QUAT_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"QUAT_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"QUAT_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_Voice Mixer"}, {"QUIN_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, {"QUIN_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"QUIN_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"QUIN_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, @@ -23229,6 +23293,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoLTE Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, {"VoLTE Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"VoLTE Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"VoLTE Stub Tx Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"VOLTE_STUB_UL", NULL, "VoLTE Stub Tx Mixer"}, {"Voice2 Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, @@ -23242,6 +23307,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"Voice2 Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, {"Voice2 Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"Voice2 Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"Voice2 Stub Tx Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"VOICE2_STUB_UL", NULL, "Voice2 Stub Tx Mixer"}, {"STUB_RX Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, -- GitLab From 9d125879def9f494282f5d7fbfe0dd9bc97a2917 Mon Sep 17 00:00:00 2001 From: Deeraj Soman Date: Tue, 5 Feb 2019 16:19:56 +0530 Subject: [PATCH 0909/1645] asoc: Add support for compress perf mode Add support for compress perf mode so that clients can set the COMPRESSED_PERF_MODE_FLAG to invoke the perf mode in compress driver. Change-Id: Ia84b95e8566aeeaf654ed90c2ab19de46e708d4d Signed-off-by: Deeraj Soman --- asoc/msm-compress-q6-v2.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 179a95e66f35..ff6819da0b44 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -76,6 +76,10 @@ const DECLARE_TLV_DB_LINEAR(msm_compr_vol_gain, 0, #define SND_DEC_DDP_MAX_PARAMS 18 +#ifndef COMPRESSED_PERF_MODE_FLAG +#define COMPRESSED_PERF_MODE_FLAG 0 +#endif + struct msm_compr_gapless_state { bool set_next_stream_id; int32_t stream_opened[MAX_NUMBER_OF_STREAMS]; @@ -2037,6 +2041,11 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream, } } + if (params->codec.flags & COMPRESSED_PERF_MODE_FLAG) { + pr_debug("%s: setting perf mode = %d", __func__, LOW_LATENCY_PCM_MODE); + prtd->audio_client->perf_mode = LOW_LATENCY_PCM_MODE; + } + switch (params->codec.id) { case SND_AUDIOCODEC_PCM: { pr_debug("SND_AUDIOCODEC_PCM\n"); -- GitLab From 366670efa7f1868c268bc331e9ed41c245a91f9a Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 11 Mar 2019 14:59:56 +0530 Subject: [PATCH 0910/1645] dsp: remove float operations in excursion calculation Avoid float operation during excursion calculation since that impacts CPU performance. Maintain the same precision for 2 digit as per requirement for final value to print in sys/class node. Change-Id: I34d0f2e7b9eca499206ee9d30acf0d9121b0442e Signed-off-by: Laxminath Kasam --- dsp/sp_params.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/dsp/sp_params.c b/dsp/sp_params.c index ed6d2ebb05d5..c84f8c79da4b 100644 --- a/dsp/sp_params.c +++ b/dsp/sp_params.c @@ -15,8 +15,9 @@ #define SPK_PARAMS "spk_params" #define CLASS_NAME "cal_data" #define BUF_SZ 20 -#define Q27 (1<<27) #define Q22 (1<<22) +#define Q13 (1<<13) +#define Q7 (1<<7) struct afe_spk_ctl { struct class *p_class; @@ -88,11 +89,11 @@ static ssize_t sp_max_excursion_l_show(struct device *dev, { ssize_t ret = 0; int32_t ex_val_frac; - float ex_val; int32_t ex_q27 = this_afe_spk.xt_logging.max_excursion[SP_V2_SPKR_1]; - ex_val = (ex_q27 * 1.0)/Q27; - ex_val_frac = ex_val * 100; + ex_val_frac = ex_q27/Q13; + ex_val_frac = (ex_val_frac * 10000)/(Q7 * Q7); + ex_val_frac /= 100; ret = snprintf(buf, BUF_SZ, "%d.%02d\n", 0, ex_val_frac); this_afe_spk.xt_logging.max_excursion[SP_V2_SPKR_1] = 0; return ret; @@ -105,11 +106,11 @@ static ssize_t sp_max_excursion_r_show(struct device *dev, { ssize_t ret = 0; int32_t ex_val_frac; - float ex_val; int32_t ex_q27 = this_afe_spk.xt_logging.max_excursion[SP_V2_SPKR_2]; - ex_val = (ex_q27 * 1.0)/Q27; - ex_val_frac = ex_val * 100; + ex_val_frac = ex_q27/Q13; + ex_val_frac = (ex_val_frac * 10000)/(Q7 * Q7); + ex_val_frac /= 100; ret = snprintf(buf, BUF_SZ, "%d.%02d\n", 0, ex_val_frac); this_afe_spk.xt_logging.max_excursion[SP_V2_SPKR_2] = 0; return ret; -- GitLab From b91472bedb552eaa9fa3e80f9c4e22c13b6e727c Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Tue, 19 Feb 2019 19:35:55 +0530 Subject: [PATCH 0911/1645] ipc: apr: Handle ssr return code from glink Glink may receive ssr reset event before audio has received. Handle the ssr return code from glink as ssr reset event at apr. Change-Id: I62058ad56bece93cac52f26446e9c780cba3c633 Signed-off-by: Ramprasad Katkam --- ipc/apr.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ipc/apr.c b/ipc/apr.c index fbb1f32e6c18..f1dbc36d9d55 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -419,8 +419,13 @@ int apr_send_pkt(void *handle, uint32_t *buf) rc = -EINVAL; } } else { - pr_err("%s: Write APR pkt failed with error %d\n", + pr_err_ratelimited("%s: Write APR pkt failed with error %d\n", __func__, rc); + if (rc == -ECONNRESET) { + pr_err_ratelimited("%s: Received reset error from tal\n", + __func__); + rc = -ENETRESET; + } } spin_unlock_irqrestore(&svc->w_lock, flags); -- GitLab From 7311253f6f8d542693594bdffd0b1fd060793d09 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Wed, 20 Feb 2019 10:22:26 +0530 Subject: [PATCH 0912/1645] dsp: codecs: Remove error logging during ssr During SSR avoid printing some errors which could lead to excessive logging. Change-Id: I5f9e7e5f32bc3de87996838048514e16d59c97a6 Signed-off-by: Ramprasad Katkam --- dsp/codecs/audio_utils_aio.c | 2 +- dsp/q6asm.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c index f22163567aa8..62b9455dbdd3 100644 --- a/dsp/codecs/audio_utils_aio.c +++ b/dsp/codecs/audio_utils_aio.c @@ -1157,7 +1157,7 @@ static int audio_aio_async_read(struct q6audio_aio *audio, /* Write command will populate session_id as token */ buf_node->token = ac->session; rc = q6asm_async_read(ac, ¶m); - if (rc < 0) + if (rc < 0 && rc != -ENETRESET) pr_err_ratelimited("%s[%pK]:failed\n", __func__, audio); return rc; } diff --git a/dsp/q6asm.c b/dsp/q6asm.c index b27163f35883..a36a8e929e1d 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -9512,8 +9512,8 @@ int q6asm_async_read(struct audio_client *ac, } rc = apr_send_pkt(ac->apr, (uint32_t *) &read); - if (rc < 0) { - pr_err("%s: read op[0x%x]rc[%d]\n", __func__, + if (rc < 0 && rc != -ENETRESET) { + pr_err_ratelimited("%s: read op[0x%x]rc[%d]\n", __func__, read.hdr.opcode, rc); goto fail_cmd; } -- GitLab From 7bc942b64025b92574f140f27fee68b3cb27ddf5 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Fri, 22 Feb 2019 17:21:13 +0530 Subject: [PATCH 0913/1645] dsp: update error handling for Doa Tracking Monitor AFE callback payload response for param id FFV_DOA_TRACKING_MONITOR is not handled properly. This is resulting in 2sec of wait event timeout delay. Updating the state event and status event based on the payload response. This decreases hal load time by 2sec. Change-Id: If960ee14e264b3fe444463b47878d29aaee5e63f Signed-off-by: Surendar Karka --- dsp/q6afe.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 0002d82a125c..5f953ae7ab2d 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -345,6 +345,14 @@ static void doa_tracking_mon_afe_cb_handler(uint32_t opcode, uint32_t *payload, size_t expected_size = sizeof(u32) + sizeof(struct doa_tracking_mon_param); + if (payload[0]) { + atomic_set(&this_afe.status, payload[0]); + atomic_set(&this_afe.state, 0); + pr_err("%s: doa_tracking_mon_resp status: %d payload size %d\n", + __func__, payload[0], payload_size); + return; + } + switch (opcode) { case AFE_PORT_CMDRSP_GET_PARAM_V2: expected_size += sizeof(struct param_hdr_v1); @@ -378,13 +386,7 @@ static void doa_tracking_mon_afe_cb_handler(uint32_t opcode, uint32_t *payload, return; } - if (!this_afe.doa_tracking_mon_resp.status) { - atomic_set(&this_afe.state, 0); - } else { - pr_debug("%s: doa_tracking_mon_resp status: %d\n", __func__, - this_afe.doa_tracking_mon_resp.status); - atomic_set(&this_afe.state, -1); - } + atomic_set(&this_afe.state, 0); } static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, -- GitLab From d57aca081251c30afad417fc01c09f7f02bc681c Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Wed, 6 Mar 2019 17:03:08 +0800 Subject: [PATCH 0914/1645] ASoC: initialize queue head for compress capture Waitqueue head is not initialized at open stage. Future action may wake up uninitialized wait. Initialize them for compress capture. Change-Id: I142202783aa9b7b9334c1a9632a89cd1ba7f5005 Signed-off-by: Xiaojun Sang --- asoc/msm-compress-q6-v2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 179a95e66f35..a7b9ff24ca8d 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -1779,6 +1779,11 @@ static int msm_compr_capture_open(struct snd_compr_stream *cstream) atomic_set(&prtd->wait_on_close, 0); atomic_set(&prtd->error, 0); + init_waitqueue_head(&prtd->eos_wait); + init_waitqueue_head(&prtd->drain_wait); + init_waitqueue_head(&prtd->close_wait); + init_waitqueue_head(&prtd->wait_for_stream_avail); + runtime->private_data = prtd; return 0; -- GitLab From be50237438424be1d7dbc99524e624478d1e5e4f Mon Sep 17 00:00:00 2001 From: Md Mansoor Ahmed Date: Tue, 12 Mar 2019 11:13:11 +0530 Subject: [PATCH 0915/1645] dsp: Replace wall clock for KPI calculations Replace clock reference from wall clock to MONOTONIC. This is to avoid getting impacted when system time is set backwards or forwards (either through network or manually). Change-Id: I98625b033f689002c9334633cf3944608d5a77d3 Signed-off-by: Md Mansoor Ahmed --- dsp/q6asm.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index b27163f35883..7a7b857e0b06 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -389,6 +389,33 @@ static const struct file_operations audio_input_latency_debug_fops = { .write = audio_input_latency_dbgfs_write }; +/* + * get_monotonic_timeval - + * This method returns a structure in timeval + * format (sec,microsec) by using ktime kernel + * API to get time in nano secs and then converts + * it to timeval format + * + * ktime_get [nsec]-> ktime_to_timespec [sec,nsec]-> timeval[sec,usec] + * + * Returns struct timeval +*/ +static struct timeval get_monotonic_timeval(void) +{ + static struct timeval out_tval; + + /* Get time from monotonic clock in nanoseconds */ + ktime_t kTimeNsec = ktime_get(); + + /* Convert it to timespec format and later to timeval as expected by audio HAL */ + struct timespec temp_tspec = ktime_to_timespec(kTimeNsec); + + /* Time returned above is in sec,nanosec format, needs to convert to sec,microsec */ + out_tval.tv_usec = temp_tspec.tv_nsec/1000; + out_tval.tv_sec = temp_tspec.tv_sec; + return out_tval; +} + static void config_debug_fs_write_cb(void) { if (out_enable_flag) { @@ -396,7 +423,7 @@ static void config_debug_fs_write_cb(void) * out_cold_index */ if (out_cold_index != 1) { - do_gettimeofday(&out_cold_tv); + out_cold_tv = get_monotonic_timeval(); pr_debug("COLD: apr_send_pkt at %ld sec %ld microsec\n", out_cold_tv.tv_sec, out_cold_tv.tv_usec); @@ -421,7 +448,7 @@ static void config_debug_fs_read_cb(void) * Hence continuous input latency */ if (in_cont_index == 7) { - do_gettimeofday(&in_cont_tv); + in_cont_tv = get_monotonic_timeval(); pr_info("%s: read buffer at %ld sec %ld microsec\n", __func__, in_cont_tv.tv_sec, in_cont_tv.tv_usec); @@ -438,7 +465,7 @@ static void config_debug_fs_reset_index(void) static void config_debug_fs_run(void) { if (out_enable_flag) { - do_gettimeofday(&out_cold_tv); + out_cold_tv = get_monotonic_timeval(); pr_debug("%s: COLD apr_send_pkt at %ld sec %ld microsec\n", __func__, out_cold_tv.tv_sec, out_cold_tv.tv_usec); } @@ -453,7 +480,7 @@ static void config_debug_fs_write(struct audio_buffer *ab) */ if ((strcmp(((char *)ab->data), zero_pattern)) && (!strcmp(((char *)ab->data + 2), zero_pattern))) { - do_gettimeofday(&out_warm_tv); + out_warm_tv = get_monotonic_timeval(); pr_debug("%s: WARM:apr_send_pkt at %ld sec %ld microsec\n", __func__, out_warm_tv.tv_sec, @@ -465,7 +492,7 @@ static void config_debug_fs_write(struct audio_buffer *ab) */ else if ((!strcmp(((char *)ab->data), zero_pattern)) && (strcmp(((char *)ab->data + 2), zero_pattern))) { - do_gettimeofday(&out_cont_tv); + out_cont_tv = get_monotonic_timeval(); pr_debug("%s: CONT:apr_send_pkt at %ld sec %ld microsec\n", __func__, out_cont_tv.tv_sec, -- GitLab From b84eea37684d5cd7c1dbc29fa0f47c2148d7d09b Mon Sep 17 00:00:00 2001 From: Cong Tang Date: Tue, 26 Feb 2019 15:14:28 +0800 Subject: [PATCH 0916/1645] audio-driver: support tdm multi lane for sa8155 Support group tdm multi lane configuration for TDM interface. With valid lane mask tdm interface support delivery audio channels through different data lines. Change-Id: I63e8ba1106b89c6bcaca0a8359a1def696c334ad Signed-off-by: Cong Tang --- asoc/msm-dai-q6-v2.c | 51 +++++++++++++++++++++++++++++---- dsp/q6afe.c | 58 ++++++++++++++++++++++++++++++++++++-- include/dsp/apr_audio-v2.h | 33 ++++++++++++++++++++++ include/dsp/q6afe-v2.h | 3 +- 4 files changed, 136 insertions(+), 9 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 580335691b1a..336f9744aba8 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -272,6 +272,7 @@ struct msm_dai_q6_tdm_dai_data { struct afe_clk_set clk_set; /* hold LPASS clock config. */ union afe_port_group_config group_cfg; /* hold tdm group config */ struct afe_tdm_port_config port_cfg; /* hold tdm config */ + struct afe_param_id_tdm_lane_cfg lane_cfg; /* hold tdm lane config */ }; /* MI2S format field for AFE_PORT_CMD_I2S_CONFIG command @@ -337,6 +338,11 @@ static DEFINE_MUTEX(tdm_mutex); static atomic_t tdm_group_ref[IDX_GROUP_TDM_MAX]; +static struct afe_param_id_tdm_lane_cfg tdm_lane_cfg = { + AFE_GROUP_DEVICE_ID_QUINARY_TDM_RX, + 0x0, +}; + /* cache of group cfg per parent node */ static struct afe_param_id_group_device_tdm_cfg tdm_group_cfg = { AFE_API_VERSION_GROUP_DEVICE_TDM_CONFIG, @@ -6590,6 +6596,24 @@ static int msm_dai_tdm_q6_probe(struct platform_device *pdev) } else dev_dbg(&pdev->dev, "%s: clk attribute not found\n", __func__); + /* extract tdm lane cfg to static */ + tdm_lane_cfg.port_id = tdm_group_cfg.group_id; + tdm_lane_cfg.lane_mask = AFE_LANE_MASK_INVALID; + if (of_find_property(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-lane-mask", NULL)) { + rc = of_property_read_u16(pdev->dev.of_node, + "qcom,msm-cpudai-tdm-lane-mask", + &tdm_lane_cfg.lane_mask); + if (rc) { + dev_err(&pdev->dev, "%s: value for tdm lane mask not found %s\n", + __func__, "qcom,msm-cpudai-tdm-lane-mask"); + goto rtn; + } + dev_dbg(&pdev->dev, "%s: tdm lane mask from DT file %d\n", + __func__, tdm_lane_cfg.lane_mask); + } else + dev_dbg(&pdev->dev, "%s: tdm lane mask not found\n", __func__); + /* extract tdm clk src master/slave info into static */ rc = of_property_read_u32(pdev->dev.of_node, "qcom,msm-cpudai-tdm-clk-internal", @@ -7696,7 +7720,7 @@ static int msm_dai_q6_dai_tdm_remove(struct snd_soc_dai *dai) if (atomic_read(group_ref) == 0) { rc = afe_port_group_enable(group_id, - NULL, false); + NULL, false, NULL); if (rc < 0) { dev_err(dai->dev, "fail to disable AFE group 0x%x\n", group_id); @@ -8066,7 +8090,17 @@ static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream, * NOTE: group config is set to the same as slot config. */ tdm_group->bit_width = tdm_group->slot_width; - tdm_group->num_channels = tdm_group->nslots_per_frame; + + /* + * for multi lane scenario + * Total number of active channels = number of active lanes * number of active slots. + */ + if (dai_data->lane_cfg.lane_mask != AFE_LANE_MASK_INVALID) + tdm_group->num_channels = tdm_group->nslots_per_frame + * num_of_bits_set(dai_data->lane_cfg.lane_mask); + else + tdm_group->num_channels = tdm_group->nslots_per_frame; + tdm_group->sample_rate = dai_data->rate; pr_debug("%s: TDM GROUP:\n" @@ -8091,6 +8125,10 @@ static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream, tdm_group->port_id[5], tdm_group->port_id[6], tdm_group->port_id[7]); + pr_debug("%s: TDM GROUP ID 0x%x lane mask 0x%x:\n", + __func__, + tdm_group->group_id, + dai_data->lane_cfg.lane_mask); /* * update tdm config param @@ -8246,7 +8284,8 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream, */ if (dai_data->num_group_ports > 1) { rc = afe_port_group_enable(group_id, - &dai_data->group_cfg, true); + &dai_data->group_cfg, true, + &dai_data->lane_cfg); if (rc < 0) { dev_err(dai->dev, "%s: fail to enable AFE group 0x%x\n", @@ -8261,7 +8300,7 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream, if (rc < 0) { if (atomic_read(group_ref) == 0) { afe_port_group_enable(group_id, - NULL, false); + NULL, false, NULL); } if (msm_dai_q6_get_tdm_clk_ref(group_idx) == 0) { msm_dai_q6_tdm_set_clk(dai_data, @@ -8318,7 +8357,7 @@ static void msm_dai_q6_tdm_shutdown(struct snd_pcm_substream *substream, if (atomic_read(group_ref) == 0) { rc = afe_port_group_enable(group_id, - NULL, false); + NULL, false, NULL); if (rc < 0) { dev_err(dai->dev, "%s: fail to disable AFE group 0x%x\n", __func__, group_id); @@ -10223,7 +10262,7 @@ static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev) dai_data->group_cfg.tdm_cfg = tdm_group_cfg; /* copy static num group ports per parent node */ dai_data->num_group_ports = num_tdm_group_ports; - + dai_data->lane_cfg = tdm_lane_cfg; dev_set_drvdata(&pdev->dev, dai_data); diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 0002d82a125c..9f398bcc0f27 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -5422,6 +5422,53 @@ int afe_port_group_set_param(u16 group_id, return ret; } +/** + * afe_port_tdm_lane_config - + * to configure group TDM lane mask with specified configuration + * + * @group_id: AFE group id number + * @lane_cfg: TDM lane mask configutation + * + * Returns 0 on success or error value on failure. + */ +static int afe_port_tdm_lane_config(u16 group_id, + struct afe_param_id_tdm_lane_cfg *lane_cfg) +{ + struct param_hdr_v3 param_hdr; + int ret = 0; + + if (lane_cfg == NULL || + lane_cfg->lane_mask == AFE_LANE_MASK_INVALID) { + pr_debug("%s: lane cfg not supported for group id: 0x%x\n", + __func__, group_id); + return ret; + } + + pr_debug("%s: group id: 0x%x lane mask 0x%x\n", __func__, + group_id, lane_cfg->lane_mask); + + memset(¶m_hdr, 0, sizeof(param_hdr)); + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + param_hdr.module_id = AFE_MODULE_GROUP_DEVICE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_TDM_LANE_CONFIG; + param_hdr.param_size = sizeof(struct afe_param_id_tdm_lane_cfg); + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + (u8 *)lane_cfg); + if (ret) + pr_err("%s: AFE_PARAM_ID_TDM_LANE_CONFIG failed %d\n", + __func__, ret); + + return ret; +} + /** * afe_port_group_enable - * command to enable AFE port group @@ -5429,12 +5476,14 @@ int afe_port_group_set_param(u16 group_id, * @group_id: group ID for AFE port group * @afe_group_config: config for AFE group * @enable: flag to indicate enable or disable + * @lane_cfg: TDM lane mask configutation * * Returns 0 on success or error on failure */ int afe_port_group_enable(u16 group_id, union afe_port_group_config *afe_group_config, - u16 enable) + u16 enable, + struct afe_param_id_tdm_lane_cfg *lane_cfg) { struct afe_group_device_enable group_enable; struct param_hdr_v3 param_hdr; @@ -5458,6 +5507,12 @@ int afe_port_group_enable(u16 group_id, pr_err("%s: afe send failed %d\n", __func__, ret); return ret; } + ret = afe_port_tdm_lane_config(group_id, lane_cfg); + if (ret < 0) { + pr_err("%s: afe send lane config failed %d\n", + __func__, ret); + return ret; + } } param_hdr.module_id = AFE_MODULE_GROUP_DEVICE; @@ -8998,4 +9053,3 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle) return ret; } EXPORT_SYMBOL(afe_unvote_lpass_core_hw); - diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 62ff28b17ed0..01174925da9c 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1354,6 +1354,8 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_LOOPBACK_TX 0x6001 #define DISPLAY_PORT_RX 0x6020 +#define AFE_LANE_MASK_INVALID 0 + #define AFE_PORT_INVALID 0xFFFF #define SLIMBUS_INVALID AFE_PORT_INVALID @@ -12430,4 +12432,35 @@ struct afe_param_id_vad_cfg_t { #define AFE_PARAM_ID_VAD_CORE_CFG 0x000102BB +/** + * This parameter is should be used to configure the AFE TDM + * interface lane configuration. + * Regular TDM interface ports: + * This parameter ID must be used with module ID + * AFE_MODULE_AUDIO_DEV_INTERFACE and set using the AFE_PORT_CMD_SET_PARAM_V3 + * command for the AFE TDM interface port IDs. + * Group device TDM interface ports: + * This parameter ID must be used with module ID AFE_MODULE_GROUP_DEVICE + * and set using the AFE_SVC_CMD_SET_PARAM_V2 command for the AFE TDM group IDs. + */ +#define AFE_PARAM_ID_TDM_LANE_CONFIG 0x000102C1 + +/* Payload of the AFE_PARAM_ID_TDM_LANE_CONFIG parameter used by + * AFE_MODULE_AUDIO_DEV_INTERFACE. + */ +struct afe_param_id_tdm_lane_cfg { + uint16_t port_id; + /** ID of the TDM interface. + * For regular TDM interfaces value corresponds to valid port ID. + * For group devices TDM interface value corresponds to valid group device ID. + */ + + uint16_t lane_mask; + /** Position of the active lanes. Bits 0 to N correspond to lanes 0 to N. + * 1 to 2^N-1 When a bit is set, the corresponding lane is active. + * The number of active lanes can be inferred from the number of bits + * set in the mask. + */ +}; + #endif /*_APR_AUDIO_V2_H_ */ diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index c5b7e3e65292..1efcb50b5669 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -432,7 +432,8 @@ int afe_set_aanc_noise_level(int val); int afe_port_group_set_param(u16 group_id, union afe_port_group_config *afe_group_config); int afe_port_group_enable(u16 group_id, - union afe_port_group_config *afe_group_config, u16 enable); + union afe_port_group_config *afe_group_config, u16 enable, + struct afe_param_id_tdm_lane_cfg *lane_cfg); int afe_unmap_rtac_block(uint32_t *mem_map_handle); int afe_map_rtac_block(struct rtac_cal_block_data *cal_block); int afe_send_slot_mapping_cfg( -- GitLab From af708a82d11f762ceee49b2d519f63c835c9dc9a Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 8 Mar 2019 19:17:57 +0530 Subject: [PATCH 0917/1645] asoc: Fix invalid size pointer access in routing driver If data size is not greater than required size while getting topology in routing driver, it leads to invalid size pointer access. Add proper size check to avoid this. CRs-Fixed: 2384972 Change-Id: I8cd71a4ae866aca57c6d711cfd07e20c5edee3ae Signed-off-by: Aditya Bavanari --- asoc/msm-pcm-routing-v2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 5a75609149d0..cf294b830e00 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -23917,6 +23917,11 @@ static uint32_t msm_routing_get_topology(size_t data_size, void *data) uint32_t size = 0; /* Retrieve cal_info size from cal data*/ + if (data_size < sizeof(struct audio_cal_type_basic) + + sizeof(struct audio_cal_info_adm_top)) { + pr_err("%s: Invalid data size: %zd\n", __func__, data_size); + goto done; + } size = data_size - sizeof(struct audio_cal_type_basic); cal_info = kzalloc(size, GFP_KERNEL); -- GitLab From c77b19f586159540b9f323653b6a3d6aec912dfd Mon Sep 17 00:00:00 2001 From: Bhalchandra Gajare Date: Fri, 9 Mar 2018 17:22:33 -0800 Subject: [PATCH 0918/1645] soc: wcd-spi-ac: add wcd spi access control driver Add driver to perform WCD SPI bus arbitration between two masters. The two masters could reside on two different processors and QMI is used to arbitrate the bus access. This driver also exposes character driver interface to userspace to indicate use case start/stop, etc. Change-Id: I4f6fe6bb0bca524f10a34cf89149c6b2055b00e1 Signed-off-by: Bhalchandra Gajare --- include/soc/wcd-spi-ac.h | 44 ++ soc/Kbuild | 8 + soc/wcd-spi-ac.c | 998 +++++++++++++++++++++++++++++++++++++++ soc/wcd_spi_ctl_v01.c | 138 ++++++ soc/wcd_spi_ctl_v01.h | 71 +++ 5 files changed, 1259 insertions(+) create mode 100644 include/soc/wcd-spi-ac.h create mode 100644 soc/wcd-spi-ac.c create mode 100644 soc/wcd_spi_ctl_v01.c create mode 100644 soc/wcd_spi_ctl_v01.h diff --git a/include/soc/wcd-spi-ac.h b/include/soc/wcd-spi-ac.h new file mode 100644 index 000000000000..5131c49f3acd --- /dev/null +++ b/include/soc/wcd-spi-ac.h @@ -0,0 +1,44 @@ +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __WCD_SPI_AC_H__ +#define __WCD_SPI_AC_H__ + +#include +#include + +enum wcd_spi_acc_req { + WCD_SPI_ACCESS_REQUEST, + WCD_SPI_ACCESS_RELEASE, + WCD_SPI_ACCESS_MAX, +}; + +#define WCD_SPI_AC_DATA_TRANSFER BIT(0) +#define WCD_SPI_AC_CONCURRENCY BIT(1) +#define WCD_SPI_AC_REMOTE_DOWN BIT(2) +#define WCD_SPI_AC_SVC_OFFLINE BIT(3) +#define WCD_SPI_AC_UNINITIALIZED BIT(4) + +#if IS_ENABLED(CONFIG_WCD_SPI_AC) +int wcd_spi_access_ctl(struct device *dev, + enum wcd_spi_acc_req req, + u32 reason); +#else +int wcd_spi_access_ctl(struct device *dev, + enum wcd_spi_acc_req req, + u32 reason) +{ + return 0; +} +#endif /* end of CONFIG_WCD_SPI_AC */ + +#endif /* end of __WCD_SPI_AC_H__ */ diff --git a/soc/Kbuild b/soc/Kbuild index 12d99c3dc059..a37a6fb46d3c 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -101,6 +101,11 @@ ifdef CONFIG_SND_EVENT SND_EVENT_OBJS += snd_event.o endif +ifdef CONFIG_WCD_SPI_AC + WCD_SPI_ACC_CTL_OBJS += wcd-spi-ac.o + WCD_SPI_ACC_CTL_OBJS += wcd_spi_ctl_v01.o +endif + LINUX_INC += -Iinclude/linux INCS += $(COMMON_INC) \ @@ -159,5 +164,8 @@ obj-$(CONFIG_SOUNDWIRE_WCD_CTRL) += swr_ctrl_dlkm.o obj-$(CONFIG_SOUNDWIRE_MSTR_CTRL) += swr_ctrl_dlkm.o swr_ctrl_dlkm-y := $(SWR_CTRL_OBJS) +obj-$(CONFIG_WCD_SPI_AC) += wcd_spi_acc_ctl_dlkm.o +wcd_spi_acc_ctl_dlkm-y := $(WCD_SPI_ACC_CTL_OBJS) + # inject some build related information DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/soc/wcd-spi-ac.c b/soc/wcd-spi-ac.c new file mode 100644 index 000000000000..ee7a7a9ba57d --- /dev/null +++ b/soc/wcd-spi-ac.c @@ -0,0 +1,998 @@ +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wcd_spi_ctl_v01.h" + +#define WCD_SPI_AC_PFS_ENTRY_MAX_LEN 16 +#define WCD_SPI_AC_WRITE_CMD_MIN_SIZE \ + (sizeof(struct wcd_spi_ac_write_cmd)) +#define WCD_SPI_AC_WRITE_CMD_MAX_SIZE \ + (WCD_SPI_AC_WRITE_CMD_MIN_SIZE + \ + (WCD_SPI_AC_MAX_BUFFERS * \ + sizeof(struct wcd_spi_ac_buf_data))) + +#define WCD_SPI_AC_MUTEX_LOCK(dev, lock) \ +{ \ + dev_dbg(dev, "%s: mutex_lock(%s)\n", \ + __func__, __stringify_1(lock)); \ + mutex_lock(&lock); \ +} + +#define WCD_SPI_AC_MUTEX_UNLOCK(dev, lock) \ +{ \ + dev_dbg(dev, "%s: mutex_unlock(%s)\n", \ + __func__, __stringify_1(lock)); \ + mutex_unlock(&lock); \ +} + +/* + * All bits of status should be cleared for SPI access + * to be released. + */ +#define WCD_SPI_AC_STATUS_RELEASE_ACCESS 0x00 +#define WCD_SPI_AC_LOCAL_ACCESS 0x00 +#define WCD_SPI_AC_REMOTE_ACCESS 0x01 +#define WCD_SPI_CTL_INS_ID 0 +#define WCD_SPI_AC_QMI_TIMEOUT_MS 100 + +struct wcd_spi_ac_priv { + + /* Pointer to device for this driver */ + struct device *dev; + + /* Pointer to parent's device */ + struct device *parent; + + /* char dev related */ + struct class *cls; + struct device *chardev; + struct cdev cdev; + dev_t cdev_num; + + /* proc entry related */ + struct proc_dir_entry *pfs_root; + struct proc_dir_entry *pfs_status; + + /* service status related */ + u8 svc_offline; + u8 svc_offline_change; + wait_queue_head_t svc_poll_wait; + struct mutex status_lock; + + /* state maintenence related */ + u32 state; + struct mutex state_lock; + u8 current_access; + + /* qmi related */ + struct qmi_handle *qmi_hdl; + struct work_struct svc_arr_work; + struct work_struct svc_exit_work; + struct notifier_block nb; + struct mutex svc_lock; + struct workqueue_struct *qmi_wq; + struct work_struct recv_msg_work; +}; + + +static void wcd_spi_ac_status_change(struct wcd_spi_ac_priv *ac, + u8 online) +{ + WCD_SPI_AC_MUTEX_LOCK(ac->dev, ac->status_lock); + ac->svc_offline = !online; + /* Make sure the write is complete */ + wmb(); + xchg(&ac->svc_offline_change, 1); + wake_up_interruptible(&ac->svc_poll_wait); + dev_dbg(ac->dev, + "%s request %u offline %u off_change %u\n", + __func__, online, ac->svc_offline, + ac->svc_offline_change); + WCD_SPI_AC_MUTEX_UNLOCK(ac->dev, ac->status_lock); +} + +static int wcd_spi_ac_status_open(struct inode *inode, + struct file *file) +{ + struct wcd_spi_ac_priv *ac = PDE_DATA(inode); + + file->private_data = ac; + + return 0; +} + +static ssize_t wcd_spi_ac_status_read(struct file *file, + char __user *buffer, + size_t count, loff_t *offset) +{ + struct wcd_spi_ac_priv *ac; + char buf[WCD_SPI_AC_PFS_ENTRY_MAX_LEN]; + int len, ret; + u8 offline; + + ac = (struct wcd_spi_ac_priv *) file->private_data; + if (!ac) { + pr_err("%s: Invalid private data for status\n", + __func__); + return -EINVAL; + } + + WCD_SPI_AC_MUTEX_LOCK(ac->dev, ac->status_lock); + offline = ac->svc_offline; + /* Make sure the read is complete */ + rmb(); + dev_dbg(ac->dev, "%s: offline = %sline\n", + __func__, offline ? "off" : "on"); + len = snprintf(buf, sizeof(buf), "%s\n", + offline ? "OFFLINE" : "ONLINE"); + ret = simple_read_from_buffer(buffer, count, offset, buf, len); + WCD_SPI_AC_MUTEX_UNLOCK(ac->dev, ac->status_lock); + + return ret; +} + +static unsigned int wcd_spi_ac_status_poll(struct file *file, + poll_table *wait) +{ + struct wcd_spi_ac_priv *ac; + unsigned int ret = 0; + + ac = (struct wcd_spi_ac_priv *) file->private_data; + if (!ac) { + pr_err("%s: Invalid private data for status\n", + __func__); + return -EINVAL; + } + + dev_dbg(ac->dev, "%s: Poll wait, svc = %s\n", + __func__, ac->svc_offline ? "offline" : "online"); + poll_wait(file, &ac->svc_poll_wait, wait); + dev_dbg(ac->dev, "%s: Woken up Poll wait, svc = %s\n", + __func__, ac->svc_offline ? "offline" : "online"); + + WCD_SPI_AC_MUTEX_LOCK(ac->dev, ac->status_lock); + if (xchg(&ac->svc_offline_change, 0)) + ret = POLLIN | POLLPRI | POLLRDNORM; + dev_dbg(ac->dev, "%s: ret (%d) from poll_wait\n", + __func__, ret); + WCD_SPI_AC_MUTEX_UNLOCK(ac->dev, ac->status_lock); + + return ret; +} + +static const struct file_operations wcd_spi_ac_status_ops = { + .owner = THIS_MODULE, + .open = wcd_spi_ac_status_open, + .read = wcd_spi_ac_status_read, + .poll = wcd_spi_ac_status_poll, +}; + +static int wcd_spi_ac_procfs_init(struct wcd_spi_ac_priv *ac) +{ + int ret = 0; + + ac->pfs_root = proc_mkdir(WCD_SPI_AC_PROCFS_DIR_NAME, NULL); + if (!ac->pfs_root) { + dev_err(ac->dev, "%s: proc_mkdir failed\n", __func__); + return -EINVAL; + } + + ac->pfs_status = proc_create_data(WCD_SPI_AC_PROCFS_STATE_NAME, + 0444, ac->pfs_root, + &wcd_spi_ac_status_ops, + ac); + if (!ac->pfs_status) { + dev_err(ac->dev, "%s: proc_create_data failed\n", + __func__); + ret = -EINVAL; + goto rmdir_root; + } + + proc_set_size(ac->pfs_status, WCD_SPI_AC_PFS_ENTRY_MAX_LEN); + + return 0; + +rmdir_root: + proc_remove(ac->pfs_root); + return ret; +} + +static void wcd_spi_ac_procfs_deinit(struct wcd_spi_ac_priv *ac) +{ + proc_remove(ac->pfs_status); + proc_remove(ac->pfs_root); +} + +static int wcd_spi_ac_request_access(struct wcd_spi_ac_priv *ac, + bool is_svc_locked) +{ + struct wcd_spi_req_access_msg_v01 req; + struct wcd_spi_req_access_resp_v01 rsp; + struct msg_desc req_desc, rsp_desc; + int ret = 0; + + dev_dbg(ac->dev, "%s: is_svc_locked = %s\n", + __func__, is_svc_locked ? "true" : "false"); + + memset(&req, 0, sizeof(req)); + memset(&rsp, 0, sizeof(rsp)); + + req.reason_valid = 1; + req.reason = ac->state & 0x03; + + req_desc.max_msg_len = WCD_SPI_REQ_ACCESS_MSG_V01_MAX_MSG_LEN; + req_desc.msg_id = WCD_SPI_REQ_ACCESS_MSG_V01; + req_desc.ei_array = wcd_spi_req_access_msg_v01_ei; + + rsp_desc.max_msg_len = WCD_SPI_REQ_ACCESS_RESP_V01_MAX_MSG_LEN; + rsp_desc.msg_id = WCD_SPI_REQ_ACCESS_RESP_V01; + rsp_desc.ei_array = wcd_spi_req_access_resp_v01_ei; + + if (!is_svc_locked) + WCD_SPI_AC_MUTEX_LOCK(ac->dev, ac->svc_lock); + + ret = qmi_send_req_wait(ac->qmi_hdl, + &req_desc, &req, sizeof(req), + &rsp_desc, &rsp, sizeof(rsp), + WCD_SPI_AC_QMI_TIMEOUT_MS); + if (ret) { + dev_err(ac->dev, "%s: msg send failed %d\n", + __func__, ret); + goto done; + } + + if (rsp.resp.result != QMI_RESULT_SUCCESS_V01) { + ret = -EIO; + dev_err(ac->dev, "%s: qmi resp error %d\n", + __func__, rsp.resp.result); + } +done: + if (!is_svc_locked) + WCD_SPI_AC_MUTEX_UNLOCK(ac->dev, ac->svc_lock); + + return ret; +} + +static int wcd_spi_ac_release_access(struct wcd_spi_ac_priv *ac, + bool is_svc_locked) +{ + struct wcd_spi_rel_access_msg_v01 req; + struct wcd_spi_rel_access_resp_v01 rsp; + struct msg_desc req_desc, rsp_desc; + int ret = 0; + + dev_dbg(ac->dev, "%s: is_svc_locked = %s\n", + __func__, is_svc_locked ? "true" : "false"); + + memset(&req, 0, sizeof(req)); + memset(&rsp, 0, sizeof(rsp)); + + req_desc.max_msg_len = WCD_SPI_REL_ACCESS_MSG_V01_MAX_MSG_LEN; + req_desc.msg_id = WCD_SPI_REL_ACCESS_MSG_V01; + req_desc.ei_array = wcd_spi_rel_access_msg_v01_ei; + + rsp_desc.max_msg_len = WCD_SPI_REL_ACCESS_RESP_V01_MAX_MSG_LEN; + rsp_desc.msg_id = WCD_SPI_REL_ACCESS_RESP_V01; + rsp_desc.ei_array = wcd_spi_rel_access_resp_v01_ei; + + if (!is_svc_locked) + WCD_SPI_AC_MUTEX_LOCK(ac->dev, ac->svc_lock); + + ret = qmi_send_req_wait(ac->qmi_hdl, + &req_desc, &req, sizeof(req), + &rsp_desc, &rsp, sizeof(rsp), + WCD_SPI_AC_QMI_TIMEOUT_MS); + if (ret) { + dev_err(ac->dev, "%s: msg send failed %d\n", + __func__, ret); + goto done; + } + + if (rsp.resp.result != QMI_RESULT_SUCCESS_V01) { + ret = -EIO; + dev_err(ac->dev, "%s: qmi resp error %d\n", + __func__, rsp.resp.result); + } +done: + if (!is_svc_locked) + WCD_SPI_AC_MUTEX_UNLOCK(ac->dev, ac->svc_lock); + return ret; +} + +static int wcd_spi_ac_buf_msg( + struct wcd_spi_ac_priv *ac, + u8 *data, int data_sz) +{ + struct wcd_spi_ac_buf_data *buf_data; + struct wcd_spi_buff_msg_v01 req; + struct wcd_spi_buff_resp_v01 rsp; + struct msg_desc req_desc, rsp_desc; + int ret = 0; + + memset(&req, 0, sizeof(req)); + memset(&rsp, 0, sizeof(rsp)); + + buf_data = (struct wcd_spi_ac_buf_data *) data; + memcpy(req.buff_addr_1, buf_data, + sizeof(*buf_data)); + + if (data_sz - sizeof(*buf_data) != 0) { + req.buff_addr_2_valid = 1; + buf_data++; + memcpy(req.buff_addr_2, buf_data, + sizeof(*buf_data)); + } + + req_desc.max_msg_len = WCD_SPI_BUFF_MSG_V01_MAX_MSG_LEN; + req_desc.msg_id = WCD_SPI_BUFF_MSG_V01; + req_desc.ei_array = wcd_spi_buff_msg_v01_ei; + + rsp_desc.max_msg_len = WCD_SPI_BUFF_RESP_V01_MAX_MSG_LEN; + rsp_desc.msg_id = WCD_SPI_BUFF_RESP_V01; + rsp_desc.ei_array = wcd_spi_buff_resp_v01_ei; + + WCD_SPI_AC_MUTEX_LOCK(ac->dev, ac->svc_lock); + ret = qmi_send_req_wait(ac->qmi_hdl, + &req_desc, &req, sizeof(req), + &rsp_desc, &rsp, sizeof(rsp), + WCD_SPI_AC_QMI_TIMEOUT_MS); + + if (ret) { + dev_err(ac->dev, "%s: msg send failed %d\n", + __func__, ret); + goto done; + } + + if (rsp.resp.result != QMI_RESULT_SUCCESS_V01) { + ret = -EIO; + dev_err(ac->dev, "%s: qmi resp error %d\n", + __func__, rsp.resp.result); + } +done: + WCD_SPI_AC_MUTEX_UNLOCK(ac->dev, ac->svc_lock); + return ret; + +} + +/* + * wcd_spi_ac_set_sync: Sets the current status of the SPI + * bus and requests access if not + * already accesible. + * @ac: pointer to the drivers private data + * @value: value to be set in the status mask + * @is_svc_locked: flag to indicate if svc_lock is acquired by caller + */ +static int wcd_spi_ac_set_sync(struct wcd_spi_ac_priv *ac, + u32 value, bool is_svc_locked) +{ + int ret = 0; + + WCD_SPI_AC_MUTEX_LOCK(ac->dev, ac->state_lock); + ac->state |= value; + /* any non-zero state indicates us to request SPI access */ + wmb(); + dev_dbg(ac->dev, "%s: current state = 0x%x, current access 0x%x\n", + __func__, ac->state, ac->current_access); + if (ac->current_access == WCD_SPI_AC_REMOTE_ACCESS) { + dev_dbg(ac->dev, + "%s: requesting access, state = 0x%x\n", + __func__, ac->state); + ret = wcd_spi_ac_request_access(ac, is_svc_locked); + if (!ret) + ac->current_access = WCD_SPI_AC_LOCAL_ACCESS; + } + WCD_SPI_AC_MUTEX_UNLOCK(ac->dev, ac->state_lock); + + return ret; +} + +/* + * wcd_spi_ac_clear_sync: Clears the current status of the SPI + * bus and releases access if applicable + * @ac: pointer to the drivers private data + * @value: value to be cleared in the status mask + * @is_svc_locked: flag to indicate if svc_lock is acquired by caller + */ +static int wcd_spi_ac_clear_sync(struct wcd_spi_ac_priv *ac, + u32 value, bool is_svc_locked) +{ + int ret = 0; + + WCD_SPI_AC_MUTEX_LOCK(ac->dev, ac->state_lock); + ac->state &= ~(value); + /* make sure value is written before read */ + wmb(); + dev_dbg(ac->dev, "%s: current state = 0x%x, current access 0x%x\n", + __func__, ac->state, ac->current_access); + /* state should be zero to release SPI access */ + if (!ac->state && + ac->current_access == WCD_SPI_AC_LOCAL_ACCESS) { + dev_dbg(ac->dev, + "%s: releasing access, state = 0x%x\n", + __func__, ac->state); + ret = wcd_spi_ac_release_access(ac, is_svc_locked); + if (!ret) + ac->current_access = WCD_SPI_AC_REMOTE_ACCESS; + } + WCD_SPI_AC_MUTEX_UNLOCK(ac->dev, ac->state_lock); + + return ret; + +} + +/* + * wcd_spi_access_ctl: API to request/release the access + * to wcd-spi bus. + * @dev: handle to the wcd-spi-ac device + * @request: enum to indicate access request or access release + * @reason: reason for request/release. Must be one of the + * valid reasons. + * Returns success if the access handover was sucessful, + * negative error code otherwise. + */ +int wcd_spi_access_ctl(struct device *dev, + enum wcd_spi_acc_req request, + u32 reason) +{ + struct wcd_spi_ac_priv *ac; + int ret = 0; + + if (!dev) { + pr_err("%s: invalid device\n", __func__); + return -EINVAL; + } + + /* only data_transfer and remote_down are valid reasons */ + if (reason != WCD_SPI_AC_DATA_TRANSFER && + reason != WCD_SPI_AC_REMOTE_DOWN) { + pr_err("%s: Invalid reason 0x%x\n", + __func__, reason); + return -EINVAL; + } + + ac = (struct wcd_spi_ac_priv *) dev_get_drvdata(dev); + if (!ac) { + dev_err(dev, "%s: invalid driver data\n", __func__); + return -EINVAL; + } + + dev_dbg(dev, "%s: request = 0x%x, reason = 0x%x\n", + __func__, request, reason); + + switch (request) { + case WCD_SPI_ACCESS_REQUEST: + ret = wcd_spi_ac_set_sync(ac, reason, false); + if (ret) + dev_err(dev, "%s: set_sync(0x%x) failed %d\n", + __func__, reason, ret); + break; + case WCD_SPI_ACCESS_RELEASE: + ret = wcd_spi_ac_clear_sync(ac, reason, false); + if (ret) + dev_err(dev, "%s: clear_sync(0x%x) failed %d\n", + __func__, reason, ret); + break; + default: + dev_err(dev, "%s: invalid request 0x%x\n", + __func__, request); + break; + } + + return ret; +} +EXPORT_SYMBOL(wcd_spi_access_ctl); + +static int wcd_spi_ac_cdev_open(struct inode *inode, + struct file *file) +{ + struct wcd_spi_ac_priv *ac; + int ret = 0; + + ac = container_of(inode->i_cdev, struct wcd_spi_ac_priv, cdev); + if (!ac) { + pr_err("%s: Invalid private data\n", __func__); + return -EINVAL; + } + + WCD_SPI_AC_MUTEX_LOCK(ac->dev, ac->status_lock); + if (ac->svc_offline) { + dev_err(ac->dev, "%s: SVC is not online, cannot open driver\n", + __func__); + ret = -ENODEV; + goto done; + } + + file->private_data = ac; + +done: + WCD_SPI_AC_MUTEX_UNLOCK(ac->dev, ac->status_lock); + return ret; +} + +static ssize_t wcd_spi_ac_cdev_write(struct file *file, + const char __user *buf, + size_t count, + loff_t *ppos) +{ + struct wcd_spi_ac_priv *ac; + struct wcd_spi_ac_write_cmd *cmd_buf; + int ret = 0; + int data_sz; + + ac = (struct wcd_spi_ac_priv *) file->private_data; + if (!ac) { + pr_err("%s: Invalid private data\n", __func__); + return -EINVAL; + } + + if (count < WCD_SPI_AC_WRITE_CMD_MIN_SIZE || + count > WCD_SPI_AC_WRITE_CMD_MAX_SIZE) { + dev_err(ac->dev, "%s: Invalid write count %zd\n", + __func__, count); + return -EINVAL; + } + + cmd_buf = kzalloc(count, GFP_KERNEL); + if (!cmd_buf) + return -ENOMEM; + + if (get_user(cmd_buf->cmd_type, buf)) { + dev_err(ac->dev, "%s: get_user failed\n", __func__); + ret = -EFAULT; + goto free_cmd_buf; + } + + dev_dbg(ac->dev, "%s: write cmd type 0x%x\n", + __func__, cmd_buf->cmd_type); + + switch (cmd_buf->cmd_type) { + + case WCD_SPI_AC_CMD_CONC_BEGIN: + ret = wcd_spi_ac_set_sync(ac, WCD_SPI_AC_CONCURRENCY, false); + if (ret) { + dev_err(ac->dev, "%s: set_sync(CONC) fail %d\n", + __func__, ret); + goto free_cmd_buf; + } + + break; + + case WCD_SPI_AC_CMD_CONC_END: + ret = wcd_spi_ac_clear_sync(ac, WCD_SPI_AC_CONCURRENCY, false); + if (ret) { + dev_err(ac->dev, "%s: clear_sync(CONC) fail %d\n", + __func__, ret); + goto free_cmd_buf; + } + + break; + + case WCD_SPI_AC_CMD_BUF_DATA: + + /* Read the buffer details and send to service */ + data_sz = count - sizeof(cmd_buf->cmd_type); + + if (!data_sz || + (data_sz % sizeof(struct wcd_spi_ac_buf_data))) { + dev_err(ac->dev, "%s: size %d not multiple of %ld\n", + __func__, data_sz, + sizeof(struct wcd_spi_ac_buf_data)); + goto free_cmd_buf; + } + + if (data_sz / sizeof(struct wcd_spi_ac_buf_data) > + WCD_SPI_AC_MAX_BUFFERS) { + dev_err(ac->dev, "%s: invalid size %d\n", + __func__, data_sz); + goto free_cmd_buf; + } + + if (copy_from_user(cmd_buf->payload, + buf + sizeof(cmd_buf->cmd_type), + data_sz)) { + dev_err(ac->dev, "%s: copy_from_user failed\n", + __func__); + ret = -EFAULT; + goto free_cmd_buf; + } + + ret = wcd_spi_ac_buf_msg(ac, cmd_buf->payload, data_sz); + if (ret) { + dev_err(ac->dev, "%s: _buf_msg failed %d\n", + __func__, ret); + goto free_cmd_buf; + } + + ret = wcd_spi_ac_clear_sync(ac, WCD_SPI_AC_UNINITIALIZED, + false); + if (ret) { + dev_err(ac->dev, "%s: clear_sync 0x%lx failed %d\n", + __func__, WCD_SPI_AC_UNINITIALIZED, ret); + goto free_cmd_buf; + } + break; + default: + dev_err(ac->dev, "%s: Invalid cmd_type 0x%x\n", + __func__, cmd_buf->cmd_type); + ret = -EINVAL; + goto free_cmd_buf; + } + +free_cmd_buf: + + kfree(cmd_buf); + if (!ret) + ret = count; + + return ret; +} + +static int wcd_spi_ac_cdev_release(struct inode *inode, + struct file *file) +{ + struct wcd_spi_ac_priv *ac; + int ret = 0; + + ac = (struct wcd_spi_ac_priv *) file->private_data; + if (!ac) { + pr_err("%s: Invalid private data\n", __func__); + return -EINVAL; + } + + ret = wcd_spi_ac_set_sync(ac, WCD_SPI_AC_UNINITIALIZED, false); + if (ret) + dev_err(ac->dev, "%s: set_sync(UNINITIALIZED) failed %d\n", + __func__, ret); + return ret; +} + +static const struct file_operations wcd_spi_ac_cdev_fops = { + .owner = THIS_MODULE, + .open = wcd_spi_ac_cdev_open, + .write = wcd_spi_ac_cdev_write, + .release = wcd_spi_ac_cdev_release, +}; + +static int wcd_spi_ac_reg_chardev(struct wcd_spi_ac_priv *ac) +{ + int ret; + + ret = alloc_chrdev_region(&ac->cdev_num, 0, 1, + WCD_SPI_AC_CLIENT_CDEV_NAME); + if (ret) { + dev_err(ac->dev, "%s: alloc_chrdev_region failed %d\n", + __func__, ret); + return ret; + } + + ac->cls = class_create(THIS_MODULE, WCD_SPI_AC_CLIENT_CDEV_NAME); + if (IS_ERR(ac->cls)) { + ret = PTR_ERR(ac->cls); + dev_err(ac->dev, "%s: class_create failed %d\n", + __func__, ret); + goto unregister_chrdev; + } + + ac->chardev = device_create(ac->cls, NULL, ac->cdev_num, + NULL, WCD_SPI_AC_CLIENT_CDEV_NAME); + if (IS_ERR(ac->chardev)) { + ret = PTR_ERR(ac->chardev); + dev_err(ac->dev, "%s: device_create failed %d\n", + __func__, ret); + goto destroy_class; + } + + cdev_init(&ac->cdev, &wcd_spi_ac_cdev_fops); + ret = cdev_add(&ac->cdev, ac->cdev_num, 1); + if (ret) { + dev_err(ac->dev, "%s: cdev_add failed %d\n", + __func__, ret); + goto destroy_device; + } + + return 0; + +destroy_device: + device_destroy(ac->cls, ac->cdev_num); + +destroy_class: + class_destroy(ac->cls); + +unregister_chrdev: + unregister_chrdev_region(0, 1); + return ret; +} + +static int wcd_spi_ac_unreg_chardev(struct wcd_spi_ac_priv *ac) +{ + cdev_del(&ac->cdev); + device_destroy(ac->cls, ac->cdev_num); + class_destroy(ac->cls); + unregister_chrdev_region(0, 1); + + return 0; +} + +static void wcd_spi_ac_recv_msg(struct work_struct *work) +{ + struct wcd_spi_ac_priv *ac; + int rc = 0; + + ac = container_of(work, struct wcd_spi_ac_priv, + recv_msg_work); + if (!ac) { + pr_err("%s: Invalid private data\n", __func__); + return; + } + + do { + dev_dbg(ac->dev, "%s: msg received, rc = %d\n", + __func__, rc); + } while ((rc = qmi_recv_msg(ac->qmi_hdl)) == 0); + + if (rc != -ENOMSG) + dev_err(ac->dev, "%s: qmi_recv_msg failed %d\n", + __func__, rc); +} + +static void wcd_spi_ac_clnt_notify(struct qmi_handle *hdl, + enum qmi_event_type event, void *priv_data) +{ + struct wcd_spi_ac_priv *ac; + + if (!priv_data) { + pr_err("%s: Invalid private data\n", __func__); + return; + } + + ac = (struct wcd_spi_ac_priv *) priv_data; + + switch (event) { + case QMI_RECV_MSG: + queue_work(ac->qmi_wq, &ac->recv_msg_work); + break; + default: + break; + } +} + +static void wcd_spi_ac_svc_arrive(struct work_struct *work) +{ + struct wcd_spi_ac_priv *ac; + int ret; + + ac = container_of(work, struct wcd_spi_ac_priv, + svc_arr_work); + if (!ac) { + pr_err("%s: Invalid private data\n", + __func__); + return; + } + + WCD_SPI_AC_MUTEX_LOCK(ac->dev, ac->svc_lock); + ac->qmi_hdl = qmi_handle_create(wcd_spi_ac_clnt_notify, + ac); + if (!ac->qmi_hdl) { + dev_err(ac->dev, "%s: qmi_handle_create failed\n", + __func__); + goto done; + } + + ret = qmi_connect_to_service(ac->qmi_hdl, + WCD_SPI_CTL_SERVICE_ID_V01, + WCD_SPI_CTL_SERVICE_VERS_V01, + WCD_SPI_CTL_INS_ID); + if (ret) { + dev_err(ac->dev, "%s, cant connect to service, error %d\n", + __func__, ret); + qmi_handle_destroy(ac->qmi_hdl); + ac->qmi_hdl = NULL; + goto done; + } + + /* Mark service as online */ + wcd_spi_ac_status_change(ac, 1); + + /* + * update the state and clear the WCD_SPI_AC_SVC_OFFLINE + * bit to indicate that the service is now online. + */ + ret = wcd_spi_ac_clear_sync(ac, WCD_SPI_AC_SVC_OFFLINE, true); + if (ret) + dev_err(ac->dev, "%s: clear_sync(SVC_OFFLINE) failed %d\n", + __func__, ret); +done: + WCD_SPI_AC_MUTEX_UNLOCK(ac->dev, ac->svc_lock); + +} + +static void wcd_spi_ac_svc_exit(struct work_struct *work) +{ + struct wcd_spi_ac_priv *ac; + int ret = 0; + + ac = container_of(work, struct wcd_spi_ac_priv, + svc_exit_work); + if (!ac) { + pr_err("%s: Invalid private data\n", + __func__); + return; + } + + WCD_SPI_AC_MUTEX_LOCK(ac->dev, ac->svc_lock); + ret = wcd_spi_ac_set_sync(ac, WCD_SPI_AC_SVC_OFFLINE, true); + if (ret) + dev_err(ac->dev, "%s: set_sync(SVC_OFFLINE) failed %d\n", + __func__, ret); + qmi_handle_destroy(ac->qmi_hdl); + ac->qmi_hdl = NULL; + wcd_spi_ac_status_change(ac, 0); + WCD_SPI_AC_MUTEX_UNLOCK(ac->dev, ac->svc_lock); +} + +static int wcd_spi_ac_svc_event(struct notifier_block *this, + unsigned long event, + void *data) +{ + struct wcd_spi_ac_priv *ac; + + ac = container_of(this, struct wcd_spi_ac_priv, nb); + if (!ac) { + pr_err("%s: Invalid private data\n", __func__); + return -EINVAL; + } + + dev_dbg(ac->dev, "%s: event = 0x%lx", __func__, event); + + switch (event) { + case QMI_SERVER_ARRIVE: + schedule_work(&ac->svc_arr_work); + break; + case QMI_SERVER_EXIT: + schedule_work(&ac->svc_exit_work); + break; + default: + dev_err(ac->dev, "%s unhandled event %ld\n", + __func__, event); + break; + } + + return 0; +} + +static int wcd_spi_ac_probe(struct platform_device *pdev) +{ + struct wcd_spi_ac_priv *ac; + struct device *parent = pdev->dev.parent; + int ret = 0; + + ac = devm_kzalloc(&pdev->dev, sizeof(*ac), + GFP_KERNEL); + if (!ac) + return -ENOMEM; + + ac->dev = &pdev->dev; + ac->parent = parent; + + ret = wcd_spi_ac_reg_chardev(ac); + if (ret) + return ret; + + ret = wcd_spi_ac_procfs_init(ac); + if (ret) + goto unreg_chardev; + + mutex_init(&ac->status_lock); + mutex_init(&ac->state_lock); + mutex_init(&ac->svc_lock); + init_waitqueue_head(&ac->svc_poll_wait); + ac->svc_offline = 1; + ac->state = (WCD_SPI_AC_SVC_OFFLINE | + WCD_SPI_AC_UNINITIALIZED); + ac->current_access = WCD_SPI_AC_LOCAL_ACCESS; + + ac->nb.notifier_call = wcd_spi_ac_svc_event; + INIT_WORK(&ac->svc_arr_work, wcd_spi_ac_svc_arrive); + INIT_WORK(&ac->svc_exit_work, wcd_spi_ac_svc_exit); + INIT_WORK(&ac->recv_msg_work, wcd_spi_ac_recv_msg); + + ac->qmi_wq = create_singlethread_workqueue("qmi_wq"); + if (!ac->qmi_wq) { + dev_err(&pdev->dev, + "%s: create_singlethread_workqueue failed\n", + __func__); + goto deinit_procfs; + } + + dev_set_drvdata(&pdev->dev, ac); + + ret = qmi_svc_event_notifier_register( + WCD_SPI_CTL_SERVICE_ID_V01, + WCD_SPI_CTL_SERVICE_VERS_V01, + WCD_SPI_CTL_INS_ID, + &ac->nb); + if (ret) { + dev_err(&pdev->dev, + "%s: qmi_svc_event_notifier_register failed %d\n", + __func__, ret); + goto destroy_wq; + } + + return 0; + +destroy_wq: + destroy_workqueue(ac->qmi_wq); + dev_set_drvdata(&pdev->dev, NULL); +deinit_procfs: + wcd_spi_ac_procfs_deinit(ac); + mutex_destroy(&ac->status_lock); + mutex_destroy(&ac->state_lock); + mutex_destroy(&ac->svc_lock); +unreg_chardev: + wcd_spi_ac_unreg_chardev(ac); + return ret; +} + +static int wcd_spi_ac_remove(struct platform_device *pdev) +{ + struct wcd_spi_ac_priv *ac; + + ac = dev_get_drvdata(&pdev->dev); + qmi_svc_event_notifier_unregister( + WCD_SPI_CTL_SERVICE_ID_V01, + WCD_SPI_CTL_SERVICE_VERS_V01, + WCD_SPI_CTL_INS_ID, + &ac->nb); + if (ac->qmi_wq) + destroy_workqueue(ac->qmi_wq); + wcd_spi_ac_unreg_chardev(ac); + wcd_spi_ac_procfs_deinit(ac); + mutex_destroy(&ac->status_lock); + mutex_destroy(&ac->state_lock); + mutex_destroy(&ac->svc_lock); + + return 0; +} + +static const struct of_device_id wcd_spi_ac_of_match[] = { + { .compatible = "qcom,wcd-spi-ac" }, + { }, +}; + +MODULE_DEVICE_TABLE(of, wcd_spi_ac_of_match); + +static struct platform_driver wcd_spi_ac_driver = { + .driver = { + .name = "qcom,wcd-spi-ac", + .of_match_table = wcd_spi_ac_of_match, + }, + .probe = wcd_spi_ac_probe, + .remove = wcd_spi_ac_remove, +}; + +module_platform_driver(wcd_spi_ac_driver); + +MODULE_DESCRIPTION("WCD SPI access control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/soc/wcd_spi_ctl_v01.c b/soc/wcd_spi_ctl_v01.c new file mode 100644 index 000000000000..0e59ca3f23a7 --- /dev/null +++ b/soc/wcd_spi_ctl_v01.c @@ -0,0 +1,138 @@ +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include "wcd_spi_ctl_v01.h" + +struct elem_info wcd_spi_req_access_msg_v01_ei[] = { + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wcd_spi_req_access_msg_v01, + reason_valid), + }, + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(u64), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wcd_spi_req_access_msg_v01, + reason), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wcd_spi_req_access_resp_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct wcd_spi_req_access_resp_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wcd_spi_rel_access_msg_v01_ei[] = { + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wcd_spi_rel_access_resp_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct wcd_spi_rel_access_resp_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wcd_spi_buff_msg_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = WCD_SPI_BUFF_CHANNELS_MAX_V01, + .elem_size = sizeof(u32), + .is_array = STATIC_ARRAY, + .tlv_type = 0x01, + .offset = offsetof(struct wcd_spi_buff_msg_v01, + buff_addr_1), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wcd_spi_buff_msg_v01, + buff_addr_2_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = WCD_SPI_BUFF_CHANNELS_MAX_V01, + .elem_size = sizeof(u32), + .is_array = STATIC_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wcd_spi_buff_msg_v01, + buff_addr_2), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wcd_spi_buff_resp_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct wcd_spi_buff_resp_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; diff --git a/soc/wcd_spi_ctl_v01.h b/soc/wcd_spi_ctl_v01.h new file mode 100644 index 000000000000..dd9b1c3e5e24 --- /dev/null +++ b/soc/wcd_spi_ctl_v01.h @@ -0,0 +1,71 @@ +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef WCD_SPI_CTL_V01_H +#define WCD_SPI_CTL_V01_H + +#define WCD_SPI_CTL_SERVICE_ID_V01 0x421 +#define WCD_SPI_CTL_SERVICE_VERS_V01 0x01 + +#define WCD_SPI_BUFF_RESP_V01 0x0022 +#define WCD_SPI_REL_ACCESS_RESP_V01 0x0021 +#define WCD_SPI_REQ_ACCESS_MSG_V01 0x0020 +#define WCD_SPI_BUFF_MSG_V01 0x0022 +#define WCD_SPI_REL_ACCESS_MSG_V01 0x0021 +#define WCD_SPI_REQ_ACCESS_RESP_V01 0x0020 + +#define WCD_SPI_BUFF_CHANNELS_MAX_V01 0x08 + +#define WCD_SPI_REQ_DATA_TRANSFER_V01 ((u64)0x01ULL) +#define WCD_SPI_REQ_CONCURRENCY_V01 ((u64)0x02ULL) +#define WCD_SPI_REQ_REMOTE_DOWN_V01 ((u64)0x04ULL) + +struct wcd_spi_req_access_msg_v01 { + u8 reason_valid; + u64 reason; +}; +#define WCD_SPI_REQ_ACCESS_MSG_V01_MAX_MSG_LEN 11 +extern struct elem_info wcd_spi_req_access_msg_v01_ei[]; + +struct wcd_spi_req_access_resp_v01 { + struct qmi_response_type_v01 resp; +}; +#define WCD_SPI_REQ_ACCESS_RESP_V01_MAX_MSG_LEN 7 +extern struct elem_info wcd_spi_req_access_resp_v01_ei[]; + +struct wcd_spi_rel_access_msg_v01 { + char placeholder; +}; +#define WCD_SPI_REL_ACCESS_MSG_V01_MAX_MSG_LEN 0 +extern struct elem_info wcd_spi_rel_access_msg_v01_ei[]; + +struct wcd_spi_rel_access_resp_v01 { + struct qmi_response_type_v01 resp; +}; +#define WCD_SPI_REL_ACCESS_RESP_V01_MAX_MSG_LEN 7 +extern struct elem_info wcd_spi_rel_access_resp_v01_ei[]; + +struct wcd_spi_buff_msg_v01 { + u32 buff_addr_1[WCD_SPI_BUFF_CHANNELS_MAX_V01]; + u8 buff_addr_2_valid; + u32 buff_addr_2[WCD_SPI_BUFF_CHANNELS_MAX_V01]; +}; +#define WCD_SPI_BUFF_MSG_V01_MAX_MSG_LEN 70 +extern struct elem_info wcd_spi_buff_msg_v01_ei[]; + +struct wcd_spi_buff_resp_v01 { + struct qmi_response_type_v01 resp; +}; +#define WCD_SPI_BUFF_RESP_V01_MAX_MSG_LEN 7 +extern struct elem_info wcd_spi_buff_resp_v01_ei[]; + +#endif -- GitLab From c5f43a1eec4aa25caabc4a799340ea0ca496040e Mon Sep 17 00:00:00 2001 From: Bhalchandra Gajare Date: Mon, 19 Mar 2018 14:35:42 -0700 Subject: [PATCH 0919/1645] ASoC: wcd-spi: add SPI bus arbitration logic On some platforms, WCD SPI bus can be shared with other processors (ex: sensor processor). In such cases, there is need for software to arbitrate the bus control. Add functionality to perform SPI bus arbitration. Change-Id: I7df933f55ac5035a55173a04e74b74f7af1f7ece Signed-off-by: Bhalchandra Gajare --- asoc/codecs/wcd-spi.c | 92 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/asoc/codecs/wcd-spi.c b/asoc/codecs/wcd-spi.c index 145c4df69055..0173e151cbb8 100644 --- a/asoc/codecs/wcd-spi.c +++ b/asoc/codecs/wcd-spi.c @@ -14,8 +14,10 @@ #include #include #include +#include #include #include +#include #include "wcd-spi-registers.h" /* Byte manipulations */ @@ -157,6 +159,8 @@ struct wcd_spi_priv { /* DMA handles for transfer buffers */ dma_addr_t tx_dma; dma_addr_t rx_dma; + /* Handle to child (qmi client) device */ + struct device *ac_dev; }; enum xfer_request { @@ -567,6 +571,19 @@ static int wcd_spi_clk_enable(struct spi_device *spi) int ret; u32 rd_status = 0; + /* Get the SPI access first */ + if (wcd_spi->ac_dev) { + ret = wcd_spi_access_ctl(wcd_spi->ac_dev, + WCD_SPI_ACCESS_REQUEST, + WCD_SPI_AC_DATA_TRANSFER); + if (ret) { + dev_err(&spi->dev, + "%s: Can't get spi access, err = %d\n", + __func__, ret); + return ret; + } + } + ret = wcd_spi_cmd_nop(spi); if (ret < 0) { dev_err(&spi->dev, "%s: NOP1 failed, err = %d\n", @@ -620,6 +637,17 @@ static int wcd_spi_clk_disable(struct spi_device *spi) */ clear_bit(WCD_SPI_CLK_STATE_ENABLED, &wcd_spi->status_mask); + /* once the clock is released, SPI access can be released as well */ + if (wcd_spi->ac_dev) { + ret = wcd_spi_access_ctl(wcd_spi->ac_dev, + WCD_SPI_ACCESS_RELEASE, + WCD_SPI_AC_DATA_TRANSFER); + if (ret) + dev_err(&spi->dev, + "%s: SPI access release failed, err = %d\n", + __func__, ret); + } + return ret; } @@ -944,6 +972,18 @@ static int wdsp_spi_event_handler(struct device *dev, void *priv_data, __func__, event); switch (event) { + case WDSP_EVENT_PRE_SHUTDOWN: + if (wcd_spi->ac_dev) { + ret = wcd_spi_access_ctl(wcd_spi->ac_dev, + WCD_SPI_ACCESS_REQUEST, + WCD_SPI_AC_REMOTE_DOWN); + if (ret) + dev_err(&spi->dev, + "%s: request access failed %d\n", + __func__, ret); + } + break; + case WDSP_EVENT_POST_SHUTDOWN: cancel_delayed_work_sync(&wcd_spi->clk_dwork); WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); @@ -953,6 +993,18 @@ static int wdsp_spi_event_handler(struct device *dev, void *priv_data, WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); break; + case WDSP_EVENT_POST_BOOTUP: + if (wcd_spi->ac_dev) { + ret = wcd_spi_access_ctl(wcd_spi->ac_dev, + WCD_SPI_ACCESS_RELEASE, + WCD_SPI_AC_REMOTE_DOWN); + if (ret) + dev_err(&spi->dev, + "%s: release access failed %d\n", + __func__, ret); + } + break; + case WDSP_EVENT_PRE_DLOAD_CODE: case WDSP_EVENT_PRE_DLOAD_DATA: ret = wcd_spi_clk_ctrl(spi, WCD_SPI_CLK_ENABLE, @@ -1299,10 +1351,50 @@ static struct regmap_config wcd_spi_regmap_cfg = { .readable_reg = wcd_spi_is_readable_reg, }; +static int wcd_spi_add_ac_dev(struct device *dev, + struct device_node *node) +{ + struct spi_device *spi = to_spi_device(dev); + struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi); + struct platform_device *pdev; + int ret = 0; + + pdev = platform_device_alloc("wcd-spi-ac", -1); + if (IS_ERR_OR_NULL(pdev)) { + ret = PTR_ERR(pdev); + dev_err(dev, "%s: pdev alloc failed, ret = %d\n", + __func__, ret); + return ret; + } + + pdev->dev.parent = dev; + pdev->dev.of_node = node; + + ret = platform_device_add(pdev); + if (ret) { + dev_err(dev, "%s: pdev add failed, ret = %d\n", + __func__, ret); + goto dealloc_pdev; + } + + wcd_spi->ac_dev = &pdev->dev; + return 0; + +dealloc_pdev: + platform_device_put(pdev); + return ret; +} + static int wdsp_spi_init(struct device *dev, void *priv_data) { struct spi_device *spi = to_spi_device(dev); int ret; + struct device_node *node; + + for_each_child_of_node(dev->of_node, node) { + if (!strcmp(node->name, "wcd_spi_ac")) + wcd_spi_add_ac_dev(dev, node); + } ret = wcd_spi_init(spi); if (ret < 0) -- GitLab From 27baab0fb9f4b51906ffb1a597b0707d4480157f Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Wed, 13 Mar 2019 17:18:28 +0530 Subject: [PATCH 0920/1645] asoc: send VAD enable or disable Updates to send VAD enable or disable to AFE port. Send VAD and island configuration based on the ports on which these features are supported in Vipertooth machine. Change-Id: Ib3e6d46fed3bf9e822f350c9ec0dc629cd82547e Signed-off-by: Mangesh Kunchamwar --- asoc/msm-dai-q6-v2.c | 45 ------------ asoc/qcs405.c | 139 ++++++++++++++++++++++++++++++------- dsp/q6afe.c | 152 +++++++++++++++++++++++------------------ include/dsp/q6afe-v2.h | 4 ++ 4 files changed, 204 insertions(+), 136 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 580335691b1a..1c543d16b322 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -1083,17 +1083,6 @@ static int msm_dai_q6_auxpcm_prepare(struct snd_pcm_substream *substream, } afe_open(aux_dai_data->rx_pid, &dai_data->port_config, dai_data->rate); - if (q6core_get_avcs_api_version_per_service( - APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) { - /* - * send island mode config - * This should be the first configuration - */ - rc = afe_send_port_island_mode(aux_dai_data->tx_pid); - if (rc) - dev_err(dai->dev, "%s: afe send island mode failed %d\n", - __func__, rc); - } afe_open(aux_dai_data->tx_pid, &dai_data->port_config, dai_data->rate); goto exit; @@ -4977,18 +4966,6 @@ static int msm_dai_q6_mi2s_prepare(struct snd_pcm_substream *substream, dai->id, port_id, dai_data->channels, dai_data->rate); if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { - if (q6core_get_avcs_api_version_per_service( - APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) { - /* - * send island mode config. - * This should be the first configuration - */ - rc = afe_send_port_island_mode(port_id); - if (rc) - dev_err(dai->dev, "%s: afe send island mode failed %d\n", - __func__, rc); - } - /* PORT START should be set if prepare called * in active state. */ @@ -8212,17 +8189,6 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream, group_ref = &tdm_group_ref[group_idx]; if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { - if (q6core_get_avcs_api_version_per_service( - APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) { - /* - * send island mode config. - * This should be the first configuration - */ - rc = afe_send_port_island_mode(dai->id); - if (rc) - dev_err(dai->dev, "%s: afe send island mode failed %d\n", - __func__, rc); - } if (msm_dai_q6_get_tdm_clk_ref(group_idx) == 0) { /* TX and RX share the same clk. So enable the clk @@ -10488,17 +10454,6 @@ static int msm_dai_q6_cdc_dma_prepare(struct snd_pcm_substream *substream, int rc = 0; if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { - if (q6core_get_avcs_api_version_per_service( - APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) { - /* - * send island mode config. - * This should be the first configuration - */ - rc = afe_send_port_island_mode(dai->id); - if (rc) - pr_err("%s: afe send island mode failed %d\n", - __func__, rc); - } if ((dai->id == AFE_PORT_ID_WSA_CODEC_DMA_TX_0) && (dai_data->port_config.cdc_dma.data_format == 1)) dai_data->port_config.cdc_dma.data_format = diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 0bbe37bd9118..04557483aa1f 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -678,6 +678,60 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = { static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; +static int msm_island_vad_get_portid_from_beid(int32_t be_id, int *port_id) +{ + *port_id = 0xFFFF; + + switch (be_id) { + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: + *port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0; + break; + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + *port_id = AFE_PORT_ID_QUINARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUIN_TDM_TX_0: + *port_id = AFE_PORT_ID_QUINARY_TDM_TX; + break; + case MSM_BACKEND_DAI_QUIN_AUXPCM_TX: + *port_id = AFE_PORT_ID_QUINARY_PCM_TX; + break; + default: + return -EINVAL; + } + return 0; +} + +static int qcs405_send_island_vad_config(int32_t be_id) +{ + int rc = 0; + int port_id = 0xFFFF; + + rc = msm_island_vad_get_portid_from_beid(be_id, &port_id); + if (rc) { + pr_debug("%s: Invalid island interface\n", __func__); + } else { + /* + * send island mode config + * This should be the first configuration + */ + rc = afe_send_port_island_mode(port_id); + if (rc) { + pr_err("%s: afe send island mode failed %d\n", + __func__, rc); + return rc; + } + + rc = afe_send_port_vad_cfg_params(port_id); + if (rc) { + pr_err("%s: afe send vad config failed %d\n", + __func__, rc); + return rc; + } + } + + return 0; +} + static int slim_get_sample_rate_val(int sample_rate) { int sample_rate_val = 0; @@ -4048,29 +4102,6 @@ static int msm_slim_get_ch_from_beid(int32_t be_id) return ch_id; } -static int msm_vad_get_portid_from_beid(int32_t be_id, int *port_id) -{ - *port_id = 0xFFFF; - - switch (be_id) { - case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: - *port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0; - break; - case MSM_BACKEND_DAI_QUINARY_MI2S_TX: - *port_id = AFE_PORT_ID_QUINARY_MI2S_TX; - break; - case MSM_BACKEND_DAI_QUIN_TDM_TX_0: - *port_id = AFE_PORT_ID_QUINARY_TDM_TX; - break; - case MSM_BACKEND_DAI_QUIN_AUXPCM_TX: - *port_id = AFE_PORT_ID_QUINARY_PCM_TX; - break; - default: - return -EINVAL; - } - return 0; -} - static int msm_cdc_dma_get_idx_from_beid(int32_t be_id) { int idx = 0; @@ -5073,6 +5104,34 @@ static int msm_snd_hw_params(struct snd_pcm_substream *substream, return ret; } +static int msm_snd_auxpcm_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + ret = qcs405_send_island_vad_config(dai_link->id); + if (ret) { + pr_err("%s: send island/vad cfg failed, err = %d\n", + __func__, ret); + } + return ret; +} + +static int msm_snd_cdc_dma_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + ret = qcs405_send_island_vad_config(dai_link->id); + if (ret) { + pr_err("%s: send island/vad cfg failed, err = %d\n", + __func__, ret); + } + return ret; +} + static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -5499,6 +5558,7 @@ static int qcs405_tdm_snd_startup(struct snd_pcm_substream *substream) struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct snd_soc_dai_link *dai_link = rtd->dai_link; u32 tdm_mode = msm_get_tdm_mode(cpu_dai->id); if (tdm_mode >= TDM_INTERFACE_MAX) { @@ -5543,6 +5603,13 @@ static int qcs405_tdm_snd_startup(struct snd_pcm_substream *substream) } } + ret = qcs405_send_island_vad_config(dai_link->id); + if (ret) { + pr_err("%s: send island/vad cfg failed, err = %d\n", + __func__, ret); + return ret; + } + return ret; } @@ -5612,7 +5679,7 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - + struct snd_soc_dai_link *dai_link = rtd->dai_link; int index = cpu_dai->id; unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; struct snd_soc_card *card = rtd->card; @@ -5660,6 +5727,14 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) msm_cdc_pinctrl_select_active_state( pdata->mi2s_gpio_p[index]); } + + ret = qcs405_send_island_vad_config(dai_link->id); + if (ret) { + pr_err("%s: send island/vad cfg failed, err = %d\n", + __func__, ret); + return ret; + } + clk_off: if (ret < 0) msm_mi2s_set_sclk(substream, false); @@ -5835,7 +5910,11 @@ static struct snd_soc_ops msm_mi2s_be_ops = { .shutdown = msm_mi2s_snd_shutdown, }; +static struct snd_soc_ops msm_auxpcm_be_ops = { + .startup = msm_snd_auxpcm_startup, +}; static struct snd_soc_ops msm_cdc_dma_be_ops = { + .startup = msm_snd_cdc_dma_startup, .hw_params = msm_snd_cdc_dma_hw_params, }; @@ -7259,6 +7338,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_playback = 1, .id = MSM_BACKEND_DAI_AUXPCM_RX, .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_auxpcm_be_ops, .ignore_pmdown_time = 1, .ignore_suspend = 1, }, @@ -7273,6 +7353,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_AUXPCM_TX, .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_auxpcm_be_ops, .ignore_suspend = 1, }, /* Secondary AUX PCM Backend DAI Links */ @@ -7287,6 +7368,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_playback = 1, .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_auxpcm_be_ops, .ignore_pmdown_time = 1, .ignore_suspend = 1, }, @@ -7301,6 +7383,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_auxpcm_be_ops, .ignore_suspend = 1, }, /* Tertiary AUX PCM Backend DAI Links */ @@ -7315,6 +7398,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_playback = 1, .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_auxpcm_be_ops, .ignore_suspend = 1, }, { @@ -7328,6 +7412,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_auxpcm_be_ops, .ignore_suspend = 1, }, /* Quaternary AUX PCM Backend DAI Links */ @@ -7342,6 +7427,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_playback = 1, .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_auxpcm_be_ops, .ignore_pmdown_time = 1, .ignore_suspend = 1, }, @@ -7356,6 +7442,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_auxpcm_be_ops, .ignore_suspend = 1, }, /* Quinary AUX PCM Backend DAI Links */ @@ -7370,6 +7457,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_playback = 1, .id = MSM_BACKEND_DAI_QUIN_AUXPCM_RX, .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_auxpcm_be_ops, .ignore_pmdown_time = 1, .ignore_suspend = 1, }, @@ -7384,6 +7472,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX, .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_auxpcm_be_ops, .ignore_suspend = 1, }, }; @@ -7594,7 +7683,7 @@ static int msm_snd_vad_cfg_put(struct snd_kcontrol *kcontrol, pr_debug("%s: vad_enable=%d preroll_config=%d vad_intf=%d\n", __func__, vad_enable, preroll_config, vad_intf); - ret = msm_vad_get_portid_from_beid(vad_intf, &port_id); + ret = msm_island_vad_get_portid_from_beid(vad_intf, &port_id); if (ret) { pr_err("%s: Invalid vad interface\n", __func__); goto done; diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 0002d82a125c..c3ea8b6d8afa 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2248,6 +2248,13 @@ int afe_send_port_island_mode(u16 port_id) u32 island_mode = 0; int ret = 0; + if (!(q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4)) { + pr_debug("%s: AFE port[%d] API version is invalid!\n", + __func__, port_id); + return 0; + } + memset(&island_cfg, 0, sizeof(island_cfg)); memset(¶m_info, 0, sizeof(param_info)); @@ -2296,66 +2303,105 @@ static int afe_get_vad_preroll_cfg(u16 port_id, u32 *preroll_cfg) return ret; } -static int afe_send_port_vad_cfg_params(u16 port_id) +int afe_send_port_vad_cfg_params(u16 port_id) { struct afe_param_id_vad_cfg_t vad_cfg; + struct afe_mod_enable_param vad_enable; struct param_hdr_v3 param_info; u32 pre_roll_cfg = 0; struct firmware_cal *hwdep_cal = NULL; int ret = 0; + uint16_t port_index = 0; - memset(&vad_cfg, 0, sizeof(vad_cfg)); - memset(¶m_info, 0, sizeof(param_info)); - - ret = afe_get_vad_preroll_cfg(port_id, &pre_roll_cfg); - if (ret) { - pr_err("%s: AFE port[%d] get preroll cfg is invalid!\n", - __func__, port_id); - return ret; + if (!(q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4)) { + pr_err("%s: AFE port[%d]: AFE API version doesn't support VAD config\n", + __func__, port_id); + return 0; } - param_info.module_id = AFE_MODULE_VAD; - param_info.instance_id = INSTANCE_ID_0; - param_info.param_id = AFE_PARAM_ID_VAD_CFG; - param_info.param_size = sizeof(vad_cfg); - vad_cfg.vad_cfg_minor_version = AFE_API_VERSION_VAD_CFG; - vad_cfg.pre_roll_in_ms = pre_roll_cfg; + port_index = afe_get_port_index(port_id); - ret = q6afe_pack_and_set_param_in_band(port_id, - q6audio_get_port_index(port_id), - param_info, (u8 *) &vad_cfg); - if (ret) { - pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n", - __func__, port_id, ret); - return ret; - } + if (this_afe.vad_cfg[port_index].is_enable) { + memset(&vad_cfg, 0, sizeof(vad_cfg)); + memset(¶m_info, 0, sizeof(param_info)); - memset(¶m_info, 0, sizeof(param_info)); + ret = afe_get_vad_preroll_cfg(port_id, &pre_roll_cfg); + if (ret) { + pr_err("%s: AFE port[%d] get preroll cfg is invalid!\n", + __func__, port_id); + return ret; + } + param_info.module_id = AFE_MODULE_VAD; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = AFE_PARAM_ID_VAD_CFG; + param_info.param_size = sizeof(vad_cfg); - hwdep_cal = q6afecal_get_fw_cal(this_afe.fw_data, Q6AFE_VAD_CORE_CAL); - if (!hwdep_cal) { - pr_err("%s: error in retrieving vad core calibration", - __func__); - return -EINVAL; + vad_cfg.vad_cfg_minor_version = AFE_API_VERSION_VAD_CFG; + vad_cfg.pre_roll_in_ms = pre_roll_cfg; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_info, (u8 *) &vad_cfg); + if (ret) { + pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n", + __func__, port_id, ret); + return ret; + } + + memset(¶m_info, 0, sizeof(param_info)); + + hwdep_cal = q6afecal_get_fw_cal(this_afe.fw_data, + Q6AFE_VAD_CORE_CAL); + if (!hwdep_cal) { + pr_err("%s: error in retrieving vad core calibration", + __func__); + return -EINVAL; + } + + param_info.module_id = AFE_MODULE_VAD; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = AFE_PARAM_ID_VAD_CORE_CFG; + param_info.param_size = hwdep_cal->size; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_info, + (u8 *) hwdep_cal->data); + if (ret) { + pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n", + __func__, port_id, ret); + return ret; + } } - param_info.module_id = AFE_MODULE_VAD; - param_info.instance_id = INSTANCE_ID_0; - param_info.param_id = AFE_PARAM_ID_VAD_CORE_CFG; - param_info.param_size = hwdep_cal->size; + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V6) { + memset(&vad_enable, 0, sizeof(vad_enable)); + memset(¶m_info, 0, sizeof(param_info)); + param_info.module_id = AFE_MODULE_VAD; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = AFE_PARAM_ID_ENABLE; + param_info.param_size = sizeof(vad_enable); - ret = q6afe_pack_and_set_param_in_band(port_id, - q6audio_get_port_index(port_id), - param_info, (u8 *) hwdep_cal->data); - if (ret) { - pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n", - __func__, port_id, ret); - return ret; + port_index = afe_get_port_index(port_id); + vad_enable.enable = this_afe.vad_cfg[port_index].is_enable; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_info, (u8 *) &vad_enable); + if (ret) { + pr_err("%s: AFE set vad enable for port 0x%x failed %d\n", + __func__, port_id, ret); + return ret; + } } + pr_debug("%s: AFE set preroll cfg %d vad core cfg port 0x%x ret %d\n", __func__, pre_roll_cfg, port_id, ret); return ret; } +EXPORT_SYMBOL(afe_send_port_vad_cfg_params); static int remap_cal_data(struct cal_block_data *cal_block, int cal_index) { @@ -3390,19 +3436,6 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, port_index = afe_get_port_index(port_id); - if (q6core_get_avcs_api_version_per_service( - APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) { - /* send VAD configuration if enabled */ - if (this_afe.vad_cfg[port_index].is_enable) { - ret = afe_send_port_vad_cfg_params(port_id); - if (ret) { - pr_err("%s: afe send VAD config failed %d\n", - __func__, ret); - goto fail_cmd; - } - } - } - /* Also send the topology id here: */ if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) { /* One time call: only for first time */ @@ -4251,19 +4284,6 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, mutex_lock(&this_afe.afe_cmd_lock); port_index = afe_get_port_index(port_id); - if (q6core_get_avcs_api_version_per_service( - APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) { - /* send VAD configuration if is enabled */ - if (this_afe.vad_cfg[port_index].is_enable) { - ret = afe_send_port_vad_cfg_params(port_id); - if (ret) { - pr_err("%s: afe send VAD config failed %d\n", - __func__, ret); - goto fail_cmd; - } - } - } - /* Also send the topology id here: */ if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) { /* One time call: only for first time */ diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index c5b7e3e65292..275bfdfc306f 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -43,6 +43,9 @@ #define AFE_API_VERSION_V3 3 /* for VAD and Island mode */ #define AFE_API_VERSION_V4 4 +/* for VAD enable */ +#define AFE_API_VERSION_V6 6 + typedef int (*routing_cb)(int port); @@ -451,6 +454,7 @@ int afe_get_sp_rx_tmax_xmax_logging_data( u16 port_id); int afe_cal_init_hwdep(void *card); int afe_send_port_island_mode(u16 port_id); +int afe_send_port_vad_cfg_params(u16 port_id); int afe_send_cmd_wakeup_register(void *handle, bool enable); void afe_register_wakeup_irq_callback( void (*afe_cb_wakeup_irq)(void *handle)); -- GitLab From 2586a4b19568d7293956f49f2f763e0e92489901 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Mon, 18 Mar 2019 16:53:39 +0530 Subject: [PATCH 0921/1645] soc: swr-mstr: reset slave pending irq flag before every call Before every slave interrupt handler call, reset slave pending irq flag, so that if irq is halted it does not retain the old value. Change-Id: Ibde5dacf38e78ab19afb6f0e91ffac81f6c22813 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index bddf30a4e882..85e1d59dd5f9 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1308,6 +1308,7 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) continue; if (swr_dev->slave_irq) { do { + swr_dev->slave_irq_pending = 0; handle_nested_irq( irq_find_mapping( swr_dev->slave_irq, 0)); -- GitLab From 8a81c4a868357d41e56ce7af802180d2135a34bc Mon Sep 17 00:00:00 2001 From: pavanc Date: Wed, 6 Jun 2018 12:13:17 +0530 Subject: [PATCH 0922/1645] dsp: lsm: Initialize lock and condition before apr_register While allocating lsm client, lock and conditions are initialized after registering session with APR. There is a possibility of accessing uninitialized condition from q6lsm_callback when SSR is triggerred after the port specific apr is registered. Initialized lock, condition and state before registering session with APR to avoid invalid access. CRs-Fixed: 2230065 Change-Id: I48b6eb7670863c45b0539155592ea0b0a3c1bffc Signed-off-by: pavanc --- dsp/q6lsm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 6af7f6953507..73043f52e359 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -311,6 +311,11 @@ struct lsm_client *q6lsm_client_alloc(lsm_app_cb cb, void *priv) kfree(client); return NULL; } + + init_waitqueue_head(&client->cmd_wait); + mutex_init(&client->cmd_lock); + atomic_set(&client->cmd_state, CMD_STATE_CLEARED); + pr_debug("%s: Client Session %d\n", __func__, client->session); client->apr = apr_register("ADSP", "LSM", q6lsm_callback, ((client->session) << 8 | client->session), @@ -328,9 +333,6 @@ struct lsm_client *q6lsm_client_alloc(lsm_app_cb cb, void *priv) goto fail; } - init_waitqueue_head(&client->cmd_wait); - mutex_init(&client->cmd_lock); - atomic_set(&client->cmd_state, CMD_STATE_CLEARED); pr_debug("%s: New client allocated\n", __func__); return client; fail: -- GitLab From 86eb0ce59cdb38687ed5dc915f21a1ab19a69104 Mon Sep 17 00:00:00 2001 From: Haynes Mathew George Date: Fri, 6 Apr 2018 18:18:51 -0700 Subject: [PATCH 0923/1645] asoc: Expose mixer control to set noirq capture volume NOIRQ platform driver registers volume controls for playback with ALSA control module. Extend this for capture stream as well. CRs-Fixed: 2222250 Change-Id: I04a3bfe0a8f44b5cb7b8f24d05cf6d72dabf1fd9 Signed-off-by: Haynes Mathew George Signed-off-by: Karthikeyan Mani --- asoc/msm-pcm-q6-noirq.c | 21 +++++++++++++-------- asoc/msm-pcm-q6-v2.c | 18 +++++++++++------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index a317142b642e..34526145de9e 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -663,7 +663,7 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, { struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol); struct snd_pcm_substream *substream = - vol->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + vol->pcm->streams[vol->stream].substream; struct msm_audio *prtd; pr_debug("%s\n", __func__); @@ -687,7 +687,7 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, int rc = 0; struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol); struct snd_pcm_substream *substream = - vol->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + vol->pcm->streams[vol->stream].substream; struct msm_audio *prtd; int volume = ucontrol->value.integer.value[0]; @@ -708,15 +708,16 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, return rc; } -static int msm_pcm_add_volume_control(struct snd_soc_pcm_runtime *rtd) +static int msm_pcm_add_volume_control(struct snd_soc_pcm_runtime *rtd, + int stream) { int ret = 0; struct snd_pcm *pcm = rtd->pcm; struct snd_pcm_volume *volume_info; struct snd_kcontrol *kctl; - dev_dbg(rtd->dev, "%s, Volume control add\n", __func__); - ret = snd_pcm_add_volume_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, + dev_dbg(rtd->dev, "%s, volume control add\n", __func__); + ret = snd_pcm_add_volume_ctls(pcm, stream, NULL, 1, rtd->dai_link->id, &volume_info); if (ret < 0) { @@ -1223,12 +1224,16 @@ static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) pr_err("%s: Could not add pcm Channel Map Control\n", __func__); - ret = msm_pcm_add_volume_control(rtd); + ret = msm_pcm_add_volume_control(rtd, SNDRV_PCM_STREAM_PLAYBACK); if (ret) { - pr_err("%s: Could not add pcm Volume Control %d\n", + pr_err("%s: Could not add pcm playback volume Control %d\n", + __func__, ret); + } + ret = msm_pcm_add_volume_control(rtd, SNDRV_PCM_STREAM_CAPTURE); + if (ret) { + pr_err("%s: Could not add pcm capture volume Control %d\n", __func__, ret); } - ret = msm_pcm_add_fe_topology_control(rtd); if (ret) { pr_err("%s: Could not add pcm topology control %d\n", diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index a087dd822c04..b010010c831c 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1391,7 +1391,7 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, { struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol); struct snd_pcm_substream *substream = - vol->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + vol->pcm->streams[vol->stream].substream; struct msm_audio *prtd; pr_debug("%s\n", __func__); @@ -1415,7 +1415,7 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, int rc = 0; struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol); struct snd_pcm_substream *substream = - vol->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + vol->pcm->streams[vol->stream].substream; struct msm_audio *prtd; int volume = ucontrol->value.integer.value[0]; @@ -1436,15 +1436,16 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, return rc; } -static int msm_pcm_add_volume_control(struct snd_soc_pcm_runtime *rtd) +static int msm_pcm_add_volume_control(struct snd_soc_pcm_runtime *rtd, + int stream) { int ret = 0; struct snd_pcm *pcm = rtd->pcm; struct snd_pcm_volume *volume_info; struct snd_kcontrol *kctl; - dev_dbg(rtd->dev, "%s, Volume control add\n", __func__); - ret = snd_pcm_add_volume_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, + dev_dbg(rtd->dev, "%s, volume control add\n", __func__); + ret = snd_pcm_add_volume_ctls(pcm, stream, NULL, 1, rtd->dai_link->id, &volume_info); if (ret < 0) { @@ -2575,11 +2576,14 @@ static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = msm_pcm_add_volume_control(rtd); + ret = msm_pcm_add_volume_control(rtd, SNDRV_PCM_STREAM_PLAYBACK); + if (ret) + pr_err("%s: Could not add pcm Volume Control %d\n", + __func__, ret); + ret = msm_pcm_add_volume_control(rtd, SNDRV_PCM_STREAM_CAPTURE); if (ret) pr_err("%s: Could not add pcm Volume Control %d\n", __func__, ret); - ret = msm_pcm_add_compress_control(rtd); if (ret) pr_err("%s: Could not add pcm Compress Control %d\n", -- GitLab From d34b26d82138117c04d8a3960055fc59875aa004 Mon Sep 17 00:00:00 2001 From: Sachin Mohan Gadag Date: Mon, 16 Jul 2018 19:53:19 +0530 Subject: [PATCH 0924/1645] asoc: support source tracking with TDM interface Add mixer controls and port id for PRIMARY_TDM interface to support source tracking with TDM mics. CRs-Fixed: 2193330 Change-Id: I62fd250e0feb3fbc190fb63d1398fc3082506f47 Signed-off-by: Surendar karka --- asoc/msm-pcm-routing-v2.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 5a75609149d0..e4964e9a51c0 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -18088,6 +18088,9 @@ static int msm_audio_sound_focus_derive_port_id(struct snd_kcontrol *kcontrol, } else if (!strcmp(kcontrol->id.name + strlen(prefix), "QUIN_TDM_TX_0")) { *port_id = AFE_PORT_ID_QUINARY_TDM_TX; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "PRIMARY_TDM")) { + *port_id = AFE_PORT_ID_PRIMARY_TDM_TX; } else { pr_err("%s: mixer ctl name=%s, could not derive valid port id\n", __func__, kcontrol->id.name); @@ -18465,6 +18468,21 @@ static const struct snd_kcontrol_new msm_source_tracking_controls[] = { .info = msm_source_tracking_info, .get = msm_audio_source_tracking_get, }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx PRIMARY_TDM", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx PRIMARY_TDM", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_MIXER, -- GitLab From bdc425e0da0de92cde983e99b40f427e1c2e3c24 Mon Sep 17 00:00:00 2001 From: Bala Kishore Pati Date: Fri, 15 Jun 2018 17:38:40 +0530 Subject: [PATCH 0925/1645] asoc: msm: clean up bootup errors Fix errors shown during bootup to ensure robustness and enable cleaner bootup process. Change-Id: I6d705afc3dbed9ae34ab8473c6b4ae402f7a0df2 Signed-off-by: Bala Kishore Pati --- asoc/msm-pcm-routing-v2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 5a75609149d0..1141be02ffb6 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -13668,6 +13668,9 @@ static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_Voip", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3_Voip", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { -- GitLab From d76b6b3cebd48fd467c16bd366b35a4dc9ecd5ab Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 3 Apr 2019 19:34:51 +0530 Subject: [PATCH 0926/1645] ASoC: wcd937x: Fix mbhc detection failure after get logical address fails Get Logical Address failure comes after SSR during rigorous testing. This calls removal of swr master device attached. Once removal occurs further headset insertion/removal does not get detected. Do not remove swr master device attached to fix the issue. Change-Id: Iac78b4a12ef296566d082e75ac8905f73d6b2a47 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x.c | 1 - 1 file changed, 1 deletion(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 5e9994f0a8e0..fcc4e6fe4308 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1491,7 +1491,6 @@ static int wcd937x_get_logical_addr(struct swr_device *swr_dev) dev_err(&swr_dev->dev, "%s get devnum %d for dev addr %lx failed\n", __func__, devnum, swr_dev->addr); - swr_remove_device(swr_dev); return ret; } swr_dev->dev_num = devnum; -- GitLab From 1e349b853d8086e6b0d30e875853954fd2be9942 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 23 Feb 2018 16:34:40 +0530 Subject: [PATCH 0927/1645] asoc: add voice routing for QUAT and QUIN MI2S interfaces Add Tx mixer routes for Quaternary and Quinary MI2S to support voice call over these interfaces. CRs-Fixed: 2194204 Change-Id: I33b0c0528fbbfe8cf17ce3fe14dbf2230f05d860 Signed-off-by: Aditya Bavanari --- asoc/msm-pcm-routing-v2.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index e4964e9a51c0..f8b1bf2138db 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -13494,6 +13494,12 @@ MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { @@ -13574,6 +13580,12 @@ static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { @@ -22384,6 +22396,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_3_MMode1", "TX_CDC_DMA_TX_3"}, {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_4_MMode1", "TX_CDC_DMA_TX_4"}, {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_5_MMode1", "TX_CDC_DMA_TX_5"}, + {"VoiceMMode1_Tx Mixer", "QUAT_MI2S_TX_MMode1", "QUAT_MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "QUIN_MI2S_TX_MMode1", "QUIN_MI2S_TX"}, {"VOICEMMODE1_UL", NULL, "VoiceMMode1_Tx Mixer"}, {"VoiceMMode2_Tx Mixer", "PRI_TX_MMode2", "PRI_I2S_TX"}, @@ -22408,6 +22422,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_3_MMode2", "TX_CDC_DMA_TX_3"}, {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_4_MMode2", "TX_CDC_DMA_TX_4"}, {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_5_MMode2", "TX_CDC_DMA_TX_5"}, + {"VoiceMMode2_Tx Mixer", "QUAT_MI2S_TX_MMode2", "QUAT_MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "QUIN_MI2S_TX_MMode2", "QUIN_MI2S_TX"}, {"VOICEMMODE2_UL", NULL, "VoiceMMode2_Tx Mixer"}, {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"}, -- GitLab From 260b769735d348e129b1bad955db6e206b603000 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 8 Mar 2019 14:56:39 +0530 Subject: [PATCH 0928/1645] asoc: wcd934x: Fix TX HPF setting update In case TX HPF mixer ctl set to 150Hz, go bit register is not updated. Always update go bit along with setting 150Hz at TX enable sequence. CRs-Fixed: 2407902 Change-Id: I05b8a471cb2505d1ca5b290ea7ba35da5a534170 Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd934x/wcd934x.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 07bbcb39b7d4..f1c353699eb4 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -4687,20 +4687,18 @@ static int tavil_codec_enable_dec(struct snd_soc_dapm_widget *w, tavil->tx_hpf_work[decimator].hpf_cut_off_freq = hpf_cut_off_freq; - if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { - snd_soc_component_update_bits(component, dec_cfg_reg, - TX_HPF_CUT_OFF_FREQ_MASK, - CF_MIN_3DB_150HZ << 5); - snd_soc_component_update_bits(component, hpf_gate_reg, + snd_soc_component_update_bits(component, dec_cfg_reg, + TX_HPF_CUT_OFF_FREQ_MASK, + CF_MIN_3DB_150HZ << 5); + snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x02); - /* - * Minimum 1 clk cycle delay is required as per - * HW spec. - */ - usleep_range(1000, 1010); - snd_soc_component_update_bits(component, hpf_gate_reg, + /* + * Minimum 1 clk cycle delay is required as per + * HW spec. + */ + usleep_range(1000, 1010); + snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x00); - } /* schedule work queue to Remove Mute */ schedule_delayed_work(&tavil->tx_mute_dwork[decimator].dwork, msecs_to_jiffies(tx_unmute_delay)); -- GitLab From 37621b06ee1a74fcfcc6668ac5df79c17625169f Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Fri, 12 Jan 2018 13:17:59 +0800 Subject: [PATCH 0929/1645] ASoC: wcd-mbhc: correct special headset detection logic When detecting special headset, vref for special headset is set based on headset threshold reference 1800mv or based on regular micbias settings from device tree. Scale threshold reference as per the special headset micbias voltage. Change-Id: Ic4cc24e18efeb420b53a2154707c9399eb886181 Signed-off-by: Meng Wang --- asoc/codecs/wcd-mbhc-adc.c | 112 ++++++++++++++++++----------- asoc/codecs/wcd934x/wcd934x-mbhc.c | 11 ++- include/asoc/wcd-mbhc-v2.h | 3 +- 3 files changed, 83 insertions(+), 43 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index 4ab510c7e0ab..4a2c928a90a5 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -343,14 +343,66 @@ static int wcd_check_cross_conn(struct wcd_mbhc *mbhc) return (plug_type == MBHC_PLUG_TYPE_GND_MIC_SWAP) ? true : false; } +static int wcd_mbhc_adc_get_spl_hs_thres(struct wcd_mbhc *mbhc) +{ + int hs_threshold, micbias_mv; + + micbias_mv = wcd_mbhc_get_micbias(mbhc); + if (mbhc->hs_thr && mbhc->micb_mv != WCD_MBHC_ADC_MICBIAS_MV) { + if (mbhc->micb_mv == micbias_mv) + hs_threshold = mbhc->hs_thr; + else + hs_threshold = (mbhc->hs_thr * + micbias_mv) / mbhc->micb_mv; + } else { + hs_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV * + micbias_mv) / WCD_MBHC_ADC_MICBIAS_MV); + } + return hs_threshold; +} + +static int wcd_mbhc_adc_get_hs_thres(struct wcd_mbhc *mbhc) +{ + int hs_threshold, micbias_mv; + + micbias_mv = wcd_mbhc_get_micbias(mbhc); + if (mbhc->hs_thr) { + if (mbhc->micb_mv == micbias_mv) + hs_threshold = mbhc->hs_thr; + else + hs_threshold = (mbhc->hs_thr * + micbias_mv) / mbhc->micb_mv; + } else { + hs_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV * + micbias_mv) / WCD_MBHC_ADC_MICBIAS_MV); + } + return hs_threshold; +} + +static int wcd_mbhc_adc_get_hph_thres(struct wcd_mbhc *mbhc) +{ + int hph_threshold, micbias_mv; + + micbias_mv = wcd_mbhc_get_micbias(mbhc); + if (mbhc->hph_thr) { + if (mbhc->micb_mv == micbias_mv) + hph_threshold = mbhc->hph_thr; + else + hph_threshold = (mbhc->hph_thr * + micbias_mv) / mbhc->micb_mv; + } else { + hph_threshold = ((WCD_MBHC_ADC_HPH_THRESHOLD_MV * + micbias_mv) / WCD_MBHC_ADC_MICBIAS_MV); + } + return hph_threshold; +} + static bool wcd_mbhc_adc_check_for_spl_headset(struct wcd_mbhc *mbhc, int *spl_hs_cnt) { bool spl_hs = false; int output_mv = 0; int adc_threshold = 0, adc_hph_threshold = 0; - struct snd_soc_component *component = mbhc->component; - struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent); pr_debug("%s: enter\n", __func__); if (!mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) @@ -366,20 +418,8 @@ static bool wcd_mbhc_adc_check_for_spl_headset(struct wcd_mbhc *mbhc, * btn press/relesae for HEADSET type during correct work. */ output_mv = wcd_measure_adc_once(mbhc, MUX_CTL_IN2P); - - if (mbhc->hs_thr && - (pdata->micbias.micb2_mv != WCD_MBHC_ADC_MICBIAS_MV)) - adc_threshold = mbhc->hs_thr; - else - adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV * - wcd_mbhc_get_micbias(mbhc))/WCD_MBHC_ADC_MICBIAS_MV); - - if (mbhc->hph_thr) - adc_hph_threshold = mbhc->hph_thr; - else - adc_hph_threshold = ((WCD_MBHC_ADC_HPH_THRESHOLD_MV * - wcd_mbhc_get_micbias(mbhc))/ - WCD_MBHC_ADC_MICBIAS_MV); + adc_threshold = wcd_mbhc_adc_get_spl_hs_thres(mbhc); + adc_hph_threshold = wcd_mbhc_adc_get_hph_thres(mbhc); if (output_mv > adc_threshold || output_mv < adc_hph_threshold) { spl_hs = false; @@ -412,8 +452,6 @@ static bool wcd_is_special_headset(struct wcd_mbhc *mbhc) bool is_spl_hs = false; int output_mv = 0; int adc_threshold = 0; - struct snd_soc_component *component = mbhc->component; - struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent); /* * Increase micbias to 2.7V to detect headsets with @@ -433,13 +471,7 @@ static bool wcd_is_special_headset(struct wcd_mbhc *mbhc) return false; } } - if (mbhc->hs_thr && - (pdata->micbias.micb2_mv != WCD_MBHC_ADC_MICBIAS_MV)) - adc_threshold = mbhc->hs_thr; - else - adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV * - wcd_mbhc_get_micbias(mbhc)) / - WCD_MBHC_ADC_MICBIAS_MV); + adc_threshold = wcd_mbhc_adc_get_spl_hs_thres(mbhc); while (!is_spl_hs) { if (mbhc->hs_detect_work_stop) { @@ -573,15 +605,8 @@ static int wcd_mbhc_get_plug_from_adc(struct wcd_mbhc *mbhc, int adc_result) enum wcd_mbhc_plug_type plug_type = MBHC_PLUG_TYPE_INVALID; u32 hph_thr = 0, hs_thr = 0; - if (mbhc->hs_thr) - hs_thr = mbhc->hs_thr; - else - hs_thr = WCD_MBHC_ADC_HS_THRESHOLD_MV; - - if (mbhc->hph_thr) - hph_thr = mbhc->hph_thr; - else - hph_thr = WCD_MBHC_ADC_HPH_THRESHOLD_MV; + hs_thr = wcd_mbhc_adc_get_hs_thres(mbhc); + hph_thr = wcd_mbhc_adc_get_hph_thres(mbhc); if (adc_result < hph_thr) plug_type = MBHC_PLUG_TYPE_HEADPHONE; @@ -609,12 +634,16 @@ static void wcd_correct_swch_plug(struct work_struct *work) int output_mv = 0; int cross_conn; int try = 0; + int hs_threshold, micbias_mv; pr_debug("%s: enter\n", __func__); mbhc = container_of(work, struct wcd_mbhc, correct_plug_swch); component = mbhc->component; + micbias_mv = wcd_mbhc_get_micbias(mbhc); + hs_threshold = wcd_mbhc_adc_get_hs_thres(mbhc); + WCD_MBHC_RSC_LOCK(mbhc); /* Mask ADC COMPLETE interrupt */ wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, false); @@ -691,13 +720,15 @@ static void wcd_correct_swch_plug(struct work_struct *work) */ plug_type = wcd_mbhc_get_plug_from_adc(mbhc, output_mv); - if ((output_mv > WCD_MBHC_ADC_HS_THRESHOLD_MV) && + if ((output_mv > hs_threshold) && (spl_hs_count < WCD_MBHC_SPL_HS_CNT)) { spl_hs = wcd_mbhc_adc_check_for_spl_headset(mbhc, &spl_hs_count); + output_mv = wcd_measure_adc_once(mbhc, MUX_CTL_IN2P); if (spl_hs_count == WCD_MBHC_SPL_HS_CNT) { - output_mv = WCD_MBHC_ADC_HS_THRESHOLD_MV; + hs_threshold = (hs_threshold * + wcd_mbhc_get_micbias(mbhc)) / micbias_mv; spl_hs = true; mbhc->micbias_enable = true; } @@ -707,7 +738,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) is_pa_on = mbhc->mbhc_cb->hph_pa_on_status( mbhc->component); - if ((output_mv <= WCD_MBHC_ADC_HS_THRESHOLD_MV) && + if ((output_mv <= hs_threshold) && (!is_pa_on)) { /* Check for cross connection*/ ret = wcd_check_cross_conn(mbhc); @@ -761,7 +792,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) } } - if (output_mv > WCD_MBHC_ADC_HS_THRESHOLD_MV) { + if (output_mv > hs_threshold) { pr_debug("%s: cable is extension cable\n", __func__); plug_type = MBHC_PLUG_TYPE_HIGH_HPH; wrk_complete = true; @@ -926,9 +957,8 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) timeout = jiffies + msecs_to_jiffies(WCD_FAKE_REMOVAL_MIN_PERIOD_MS); - adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV * - wcd_mbhc_get_micbias(mbhc)) / - WCD_MBHC_ADC_MICBIAS_MV); + adc_threshold = wcd_mbhc_adc_get_hs_thres(mbhc); + do { retry++; /* diff --git a/asoc/codecs/wcd934x/wcd934x-mbhc.c b/asoc/codecs/wcd934x/wcd934x-mbhc.c index f00e4c0a9868..d777d8d56446 100644 --- a/asoc/codecs/wcd934x/wcd934x-mbhc.c +++ b/asoc/codecs/wcd934x/wcd934x-mbhc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -1102,6 +1102,7 @@ int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, struct wcd934x_mbhc *wcd934x_mbhc; struct wcd_mbhc *wcd_mbhc; int ret; + struct wcd9xxx_pdata *pdata; wcd934x_mbhc = devm_kzalloc(component->dev, sizeof(struct wcd934x_mbhc), GFP_KERNEL); @@ -1122,6 +1123,14 @@ int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, /* Setting default mbhc detection logic to ADC for Tavil */ wcd_mbhc->mbhc_detection_logic = WCD_DETECTION_ADC; + pdata = dev_get_platdata(component->dev->parent); + if (!pdata) { + dev_err(component->dev, "%s: pdata pointer is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + wcd_mbhc->micb_mv = pdata->micbias.micb2_mv; + ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb, &intr_ids, wcd_mbhc_registers, TAVIL_ZDET_SUPPORTED); diff --git a/include/asoc/wcd-mbhc-v2.h b/include/asoc/wcd-mbhc-v2.h index c98cdda944c9..9341e3d3c784 100644 --- a/include/asoc/wcd-mbhc-v2.h +++ b/include/asoc/wcd-mbhc-v2.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. */ #ifndef __WCD_MBHC_V2_H__ #define __WCD_MBHC_V2_H__ @@ -540,6 +540,7 @@ struct wcd_mbhc { bool gnd_swh; /*track GND switch NC / NO */ u32 hs_thr; u32 hph_thr; + u32 micb_mv; u32 swap_thr; u32 moist_vref; u32 moist_iref; -- GitLab From 85af5caae6a8d1869a165959a290e73451afc6d3 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 11 Mar 2019 14:33:22 +0530 Subject: [PATCH 0930/1645] asoc: sm6150: Fix to apply wsa8810 gain settings In trinket, wsa8810 variant show higher current. As wsa8815 settings applied for wsa8810 variant causing the issue. Update wsa aux codec matching logic in machine driver to apply proper gain settings for wsa8810 variant. CRs-Fixed: 2406074 Change-Id: I5916ae7ea8e91aad4e0be6486502f5fcd8a96ff3 Signed-off-by: Laxminath Kasam --- asoc/sm6150.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 11bb6115d0ed..6a6597ab875c 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -5150,14 +5150,16 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) __func__, rtd->card->num_aux_devs); if (rtd->card->num_aux_devs && !list_empty(&rtd->card->aux_comp_list)) { - aux_comp = list_first_entry(&rtd->card->aux_comp_list, - struct snd_soc_component, card_aux_list); - if (!strcmp(aux_comp->name, WSA8810_NAME_1) || - !strcmp(aux_comp->name, WSA8810_NAME_2)) { - wsa_macro_set_spkr_mode(component, - WSA_MACRO_SPKR_MODE_1); - wsa_macro_set_spkr_gain_offset(component, - WSA_MACRO_GAIN_OFFSET_M1P5_DB); + list_for_each_entry(aux_comp, &rtd->card->aux_comp_list, + card_aux_list) { + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { + wsa_macro_set_spkr_mode(component, + WSA_MACRO_SPKR_MODE_1); + wsa_macro_set_spkr_gain_offset(component, + WSA_MACRO_GAIN_OFFSET_M1P5_DB); + break; + } } } card = rtd->card->snd_card; -- GitLab From eb7519911f7656f9c7eacdb0c4f4a31fdafa0a65 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 13 Mar 2019 13:30:51 +0530 Subject: [PATCH 0931/1645] ASoC: wcd937x: update micbias noise filter resistance Update micbias noise filter resistance for better performance during audio capture. Change-Id: If80b967dd7f9bbf7e683c6da53a1aa93924c6877 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 5e9994f0a8e0..42b0b1988d91 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -134,6 +134,12 @@ static int wcd937x_init_reg(struct snd_soc_component *component) snd_soc_component_update_bits(component, WCD937X_HPH_SURGE_HPHLR_SURGE_EN, 0xFF, 0xD9); + snd_soc_component_update_bits(component, WCD937X_MICB1_TEST_CTL_1, + 0xFF, 0xFA); + snd_soc_component_update_bits(component, WCD937X_MICB2_TEST_CTL_1, + 0xFF, 0xFA); + snd_soc_component_update_bits(component, WCD937X_MICB3_TEST_CTL_1, + 0xFF, 0xFA); return 0; } -- GitLab From 1e9d40595fe3a15d580e8c73909cb87da753bfb8 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 25 Mar 2019 22:49:48 +0530 Subject: [PATCH 0932/1645] asoc: Add route from Voice to PRI_TDM interface Add dai-links in routing driver to support voice call over Primary TDM interface. Change-Id: I6dc53905b595d31979e0706718d857230f32497c Signed-off-by: Ashish Jain Signed-off-by: Chinkit Kumar,Kirti Kumar Parmar Signed-off-by: Sundara Vinayagam --- asoc/msm-pcm-routing-v2.c | 270 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 270 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index f8b1bf2138db..41f57166c579 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -13379,6 +13379,146 @@ static const struct snd_kcontrol_new rx_cdc_dma_rx_7_voice_mixer_controls[] = { msm_routing_put_voice_mixer), }; +static const struct snd_kcontrol_new pri_tdm_rx_0_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_1_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_2_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_3_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + static const struct snd_kcontrol_new stub_rx_mixer_controls[] = { SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_EXTPROC_RX, @@ -13500,6 +13640,9 @@ MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, SOC_DOUBLE_EXT("QUIN_MI2S_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX3_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { @@ -13586,6 +13729,9 @@ static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { SOC_DOUBLE_EXT("QUIN_MI2S_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX3_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { @@ -19840,6 +19986,22 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_NOPM, 0, 0, quin_mi2s_rx_voice_mixer_controls, ARRAY_SIZE(quin_mi2s_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_0_Voice Mixer", + SND_SOC_NOPM, 0, 0, + pri_tdm_rx_0_voice_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_0_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_1_Voice Mixer", + SND_SOC_NOPM, 0, 0, + pri_tdm_rx_1_voice_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_1_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_2_Voice Mixer", + SND_SOC_NOPM, 0, 0, + pri_tdm_rx_2_voice_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_2_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_3_Voice Mixer", + SND_SOC_NOPM, 0, 0, + pri_tdm_rx_3_voice_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_3_voice_mixer_controls)), SND_SOC_DAPM_MIXER("QUAT_TDM_RX_2_Voice Mixer", SND_SOC_NOPM, 0, 0, quat_tdm_rx_2_voice_mixer_controls, @@ -22235,6 +22397,62 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_Voice Mixer"}, + {"PRI_TDM_RX_0_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"PRI_TDM_RX_0_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_TDM_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0_Voice Mixer"}, + + {"PRI_TDM_RX_1_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"PRI_TDM_RX_1_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_TDM_RX_1_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1_Voice Mixer"}, + + {"PRI_TDM_RX_2_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"PRI_TDM_RX_2_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2_Voice Mixer"}, + + {"PRI_TDM_RX_3_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"PRI_TDM_RX_3_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_TDM_RX_3_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3_Voice Mixer"}, + {"QUAT_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_Voice Mixer"}, @@ -22373,6 +22591,55 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL28", NULL, "AUDIO_REF_EC_UL28 MUX"}, {"MM_UL29", NULL, "AUDIO_REF_EC_UL29 MUX"}, + {"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"}, + {"Voice_Tx Mixer", "PRI_MI2S_TX_Voice", "PRI_MI2S_TX"}, + {"Voice_Tx Mixer", "MI2S_TX_Voice", "MI2S_TX"}, + {"Voice_Tx Mixer", "TERT_MI2S_TX_Voice", "TERT_MI2S_TX"}, + {"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"}, + {"Voice_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice", "INT_BT_SCO_TX"}, + {"Voice_Tx Mixer", "AFE_PCM_TX_Voice", "PCM_TX"}, + {"Voice_Tx Mixer", "AUX_PCM_TX_Voice", "AUX_PCM_TX"}, + {"Voice_Tx Mixer", "SEC_AUX_PCM_TX_Voice", "SEC_AUX_PCM_TX"}, + {"Voice_Tx Mixer", "SEC_MI2S_TX_Voice", "SEC_MI2S_TX"}, + {"Voice_Tx Mixer", "PRI_TDM_TX_3_Voice", "PRI_TDM_TX_3"}, + {"CS-VOICE_UL1", NULL, "Voice_Tx Mixer"}, + + {"Voice2_Tx Mixer", "PRI_TX_Voice2", "PRI_I2S_TX"}, + {"Voice2_Tx Mixer", "PRI_MI2S_TX_Voice2", "PRI_MI2S_TX"}, + {"Voice2_Tx Mixer", "MI2S_TX_Voice2", "MI2S_TX"}, + {"Voice2_Tx Mixer", "TERT_MI2S_TX_Voice2", "TERT_MI2S_TX"}, + {"Voice2_Tx Mixer", "SLIM_0_TX_Voice2", "SLIMBUS_0_TX"}, + {"Voice2_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice2", "INT_BT_SCO_TX"}, + {"Voice2_Tx Mixer", "AFE_PCM_TX_Voice2", "PCM_TX"}, + {"Voice2_Tx Mixer", "AUX_PCM_TX_Voice2", "AUX_PCM_TX"}, + {"Voice2_Tx Mixer", "SEC_AUX_PCM_TX_Voice2", "SEC_AUX_PCM_TX"}, + {"Voice2_Tx Mixer", "PRI_TDM_TX_3_Voice2", "PRI_TDM_TX_3"}, + {"VOICE2_UL", NULL, "Voice2_Tx Mixer"}, + + {"VoLTE_Tx Mixer", "PRI_TX_VoLTE", "PRI_I2S_TX"}, + {"VoLTE_Tx Mixer", "SLIM_0_TX_VoLTE", "SLIMBUS_0_TX"}, + {"VoLTE_Tx Mixer", "INTERNAL_BT_SCO_TX_VoLTE", "INT_BT_SCO_TX"}, + {"VoLTE_Tx Mixer", "AFE_PCM_TX_VoLTE", "PCM_TX"}, + {"VoLTE_Tx Mixer", "AUX_PCM_TX_VoLTE", "AUX_PCM_TX"}, + {"VoLTE_Tx Mixer", "SEC_AUX_PCM_TX_VoLTE", "SEC_AUX_PCM_TX"}, + {"VoLTE_Tx Mixer", "MI2S_TX_VoLTE", "MI2S_TX"}, + {"VoLTE_Tx Mixer", "PRI_MI2S_TX_VoLTE", "PRI_MI2S_TX"}, + {"VoLTE_Tx Mixer", "TERT_MI2S_TX_VoLTE", "TERT_MI2S_TX"}, + {"VoLTE_Tx Mixer", "PRI_TDM_TX_3_VoLTE", "PRI_TDM_TX_3"}, + {"VoLTE_UL", NULL, "VoLTE_Tx Mixer"}, + + {"VoWLAN_Tx Mixer", "PRI_TX_VoWLAN", "PRI_I2S_TX"}, + {"VoWLAN_Tx Mixer", "SLIM_0_TX_VoWLAN", "SLIMBUS_0_TX"}, + {"VoWLAN_Tx Mixer", "INTERNAL_BT_SCO_TX_VoWLAN", "INT_BT_SCO_TX"}, + {"VoWLAN_Tx Mixer", "AFE_PCM_TX_VoWLAN", "PCM_TX"}, + {"VoWLAN_Tx Mixer", "AUX_PCM_TX_VoWLAN", "AUX_PCM_TX"}, + {"VoWLAN_Tx Mixer", "SEC_AUX_PCM_TX_VoWLAN", "SEC_AUX_PCM_TX"}, + {"VoWLAN_Tx Mixer", "MI2S_TX_VoWLAN", "MI2S_TX"}, + {"VoWLAN_Tx Mixer", "PRI_MI2S_TX_VoWLAN", "PRI_MI2S_TX"}, + {"VoWLAN_Tx Mixer", "TERT_MI2S_TX_VoWLAN", "TERT_MI2S_TX"}, + {"VoWLAN_Tx Mixer", "PRI_TDM_TX_3_VoWLAN", "PRI_TDM_TX_3"}, + {"VoWLAN_UL", NULL, "VoWLAN_Tx Mixer"}, + {"VoiceMMode1_Tx Mixer", "PRI_TX_MMode1", "PRI_I2S_TX"}, {"VoiceMMode1_Tx Mixer", "PRI_MI2S_TX_MMode1", "PRI_MI2S_TX"}, {"VoiceMMode1_Tx Mixer", "MI2S_TX_MMode1", "MI2S_TX"}, @@ -22398,6 +22665,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_5_MMode1", "TX_CDC_DMA_TX_5"}, {"VoiceMMode1_Tx Mixer", "QUAT_MI2S_TX_MMode1", "QUAT_MI2S_TX"}, {"VoiceMMode1_Tx Mixer", "QUIN_MI2S_TX_MMode1", "QUIN_MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "PRI_TDM_TX_3_MMode1", "PRI_TDM_TX_3"}, {"VOICEMMODE1_UL", NULL, "VoiceMMode1_Tx Mixer"}, {"VoiceMMode2_Tx Mixer", "PRI_TX_MMode2", "PRI_I2S_TX"}, @@ -22424,6 +22692,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_5_MMode2", "TX_CDC_DMA_TX_5"}, {"VoiceMMode2_Tx Mixer", "QUAT_MI2S_TX_MMode2", "QUAT_MI2S_TX"}, {"VoiceMMode2_Tx Mixer", "QUIN_MI2S_TX_MMode2", "QUIN_MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "PRI_TDM_TX_3_MMode2", "PRI_TDM_TX_3"}, {"VOICEMMODE2_UL", NULL, "VoiceMMode2_Tx Mixer"}, {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"}, @@ -22442,6 +22711,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"Voip_Tx Mixer", "QUAT_AUX_PCM_TX_Voip", "QUAT_AUX_PCM_TX"}, {"Voip_Tx Mixer", "QUIN_AUX_PCM_TX_Voip", "QUIN_AUX_PCM_TX"}, {"Voip_Tx Mixer", "PRI_MI2S_TX_Voip", "PRI_MI2S_TX"}, + {"Voip_Tx Mixer", "PRI_TDM_TX_3_Voip", "PRI_TDM_TX_3"}, {"VOIP_UL", NULL, "Voip_Tx Mixer"}, {"SLIMBUS_DL_HL", "Switch", "SLIM0_DL_HL"}, -- GitLab From f2a71b691be4c216645586cc5e8f994ab8319828 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 26 Mar 2019 16:14:40 +0530 Subject: [PATCH 0933/1645] ASoC: bolero: Add Kcontrol to enable digital mute for WSA Add Kcontrol to enable/disable digital mute for WSA RX0 and RX1. Change-Id: Ib9ee2b01f142fdce5dab92eafe9c4b0c5d65844a Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/wsa-macro.c | 79 ++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index c8a5e1d68291..d1ba34620e57 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -220,6 +220,7 @@ struct wsa_macro_priv { struct wsa_macro_bcl_pmic_params bcl_pmic_params; char __iomem *mclk_mode_muxsel; u16 default_clk_id; + int wsa_digital_mute_status[WSA_MACRO_RX_MAX]; }; static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component, @@ -1775,6 +1776,72 @@ static int wsa_macro_set_ec_hq(struct snd_kcontrol *kcontrol, return 0; } +static int wsa_macro_get_rx_mute_status(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + int wsa_rx_shift = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = + wsa_priv->wsa_digital_mute_status[wsa_rx_shift]; + return 0; +} + +static int wsa_macro_set_rx_mute_status(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + int value = ucontrol->value.integer.value[0]; + int wsa_rx_shift = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + switch (wsa_rx_shift) { + case 0: + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_RX0_RX_PATH_CTL, + 0x10, value << 4); + break; + case 1: + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_RX1_RX_PATH_CTL, + 0x10, value << 4); + break; + case 2: + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL, + 0x10, value << 4); + break; + case 3: + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL, + 0x10, value << 4); + break; + default: + pr_err("%s: invalid argument rx_shift = %d\n", __func__, + wsa_rx_shift); + return -EINVAL; + } + + dev_dbg(component->dev, "%s: WSA Digital Mute RX %d Enable %d\n", + __func__, wsa_rx_shift, value); + wsa_priv->wsa_digital_mute_status[wsa_rx_shift] = value; + return 0; +} + static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2102,6 +2169,18 @@ static const struct snd_kcontrol_new wsa_macro_snd_controls[] = { SOC_SINGLE_SX_TLV("WSA_RX1 Digital Volume", BOLERO_CDC_WSA_RX1_RX_VOL_CTL, 0, -84, 40, digital_gain), + SOC_SINGLE_EXT("WSA_RX0 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX0, 1, + 0, wsa_macro_get_rx_mute_status, + wsa_macro_set_rx_mute_status), + SOC_SINGLE_EXT("WSA_RX1 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX1, 1, + 0, wsa_macro_get_rx_mute_status, + wsa_macro_set_rx_mute_status), + SOC_SINGLE_EXT("WSA_RX0_MIX Digital Mute", SND_SOC_NOPM, + WSA_MACRO_RX_MIX0, 1, 0, wsa_macro_get_rx_mute_status, + wsa_macro_set_rx_mute_status), + SOC_SINGLE_EXT("WSA_RX1_MIX Digital Mute", SND_SOC_NOPM, + WSA_MACRO_RX_MIX1, 1, 0, wsa_macro_get_rx_mute_status, + wsa_macro_set_rx_mute_status), SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0, wsa_macro_get_compander, wsa_macro_set_compander), SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0, -- GitLab From d1db67cb058c464a6737f4c710c1d0a4cd94f5fb Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 17 Apr 2019 12:41:34 +0800 Subject: [PATCH 0934/1645] asoc: kona: add mixer control to set channel number for speaker protection Add mixer control to set channel number for speaker protection. Change-Id: I67527119a65758c77dbf9b1d26cc51f956702b5e Signed-off-by: Meng Wang --- asoc/kona.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/asoc/kona.c b/asoc/kona.c index 9508b95770dc..574c652464cd 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -378,6 +378,8 @@ static struct dev_config afe_loopback_tx_cfg[] = { [AFE_LOOPBACK_TX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; +static int msm_vi_feed_tx_ch = 2; +static const char *const vi_feed_ch_text[] = {"One", "Two"}; static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", "S32_LE"}; static char const *ch_text[] = {"Two", "Three", "Four", "Five", @@ -436,6 +438,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); @@ -545,7 +548,6 @@ static struct snd_soc_card snd_soc_card_kona_msm; static int dmic_0_1_gpio_cnt; static int dmic_2_3_gpio_cnt; static int dmic_4_5_gpio_cnt; -static int msm_vi_feed_tx_ch = 2; static void *def_wcd_mbhc_cal(void); @@ -980,6 +982,23 @@ static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, return 1; } +static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1; + pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch); + return 1; +} + static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol) { int idx = 0; @@ -3332,6 +3351,8 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { msm_bt_sample_rate_tx_put), SOC_ENUM_EXT("AFE_LOOPBACK_TX Channels", afe_loopback_tx_chs, afe_loopback_tx_ch_get, afe_loopback_tx_ch_put), + SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, + msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), }; static const struct snd_kcontrol_new msm_snd_controls[] = { -- GitLab From 40c749da4c9e3fbb70c321e1acee4e7d873ae230 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Tue, 9 Apr 2019 18:35:21 -0700 Subject: [PATCH 0935/1645] dsp: voice_mhi: use modified mhi sync/put api MHI APIs have been updated to support LPM. Move to newer API to make use of device LPM. Change-Id: I53bd3dff1b66d064091f21eb5f2a36ee77f965ed Signed-off-by: Vikram Panduranga --- dsp/voice_mhi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dsp/voice_mhi.c b/dsp/voice_mhi.c index 87572efa7e76..69942b24807c 100644 --- a/dsp/voice_mhi.c +++ b/dsp/voice_mhi.c @@ -228,7 +228,8 @@ int voice_mhi_start(void) goto done; } if (voice_mhi_lcl.vote_count == 0) { - ret = mhi_device_get_sync(voice_mhi_lcl.mhi_dev); + ret = mhi_device_get_sync(voice_mhi_lcl.mhi_dev, + MHI_VOTE_DEVICE); if (ret) { pr_err("%s: mhi_device_get_sync failed\n", __func__); @@ -269,7 +270,7 @@ int voice_mhi_end(void) } if (voice_mhi_lcl.vote_count == 1) - mhi_device_put(voice_mhi_lcl.mhi_dev); + mhi_device_put(voice_mhi_lcl.mhi_dev, MHI_VOTE_DEVICE); voice_mhi_lcl.vote_count--; } mutex_unlock(&voice_mhi_lcl.mutex); -- GitLab From 73ef46997a53989d876875ebe9ae4f1df5abd60f Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 1 Apr 2019 15:48:07 +0530 Subject: [PATCH 0936/1645] config: Add DLKM support for lito Add auto config files for lito to enable DLKM support. Change-Id: I78c950a92e11ffbf1487aa2bc37abe974ae5f180 Signed-off-by: Vatsal Bucha --- config/litoauto.conf | 37 +++++++++++++++++++++++++++++++++++++ config/litoautoconf.h | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 config/litoauto.conf create mode 100644 config/litoautoconf.h diff --git a/config/litoauto.conf b/config/litoauto.conf new file mode 100644 index 000000000000..8d49fb94290a --- /dev/null +++ b/config/litoauto.conf @@ -0,0 +1,37 @@ +CONFIG_PINCTRL_LPI=m +CONFIG_AUDIO_EXT_CLK=m +CONFIG_SND_SOC_WCD9XXX_V2=m +CONFIG_SND_SOC_WCD_MBHC=m +CONFIG_SND_SOC_WSA881X=m +CONFIG_WCD9XXX_CODEC_CORE_V2=m +CONFIG_MSM_CDC_PINCTRL=m +CONFIG_MSM_QDSP6V2_CODECS=m +CONFIG_MSM_ULTRASOUND=m +CONFIG_MSM_QDSP6_APRV2_RPMSG=m +CONFIG_MSM_ADSP_LOADER=m +CONFIG_REGMAP_SWR=m +CONFIG_MSM_QDSP6_SSR=m +CONFIG_MSM_QDSP6_PDR=m +CONFIG_MSM_QDSP6_NOTIFIER=m +CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +CONFIG_SOUNDWIRE=m +CONFIG_SOUNDWIRE_MSTR_CTRL=m +CONFIG_SND_SOC_QDSP6V2=m +CONFIG_SND_SOC_WCD_MBHC_ADC=m +CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m +CONFIG_QTI_PP=m +CONFIG_SND_HWDEP_ROUTING=m +CONFIG_SND_SOC_MSM_STUB=m +CONFIG_MSM_AVTIMER=m +CONFIG_SND_SOC_BOLERO=m +CONFIG_WSA_MACRO=m +CONFIG_VA_MACRO=m +CONFIG_RX_MACRO=m +CONFIG_TX_MACRO=m +CONFIG_SND_SOC_WCD_IRQ=m +CONFIG_SND_SOC_WCD938X=m +CONFIG_SND_SOC_WCD938X_SLAVE=m +CONFIG_SND_SOC_LITO=m +CONFIG_SND_EVENT=m +CONFIG_VOICE_MHI=m diff --git a/config/litoautoconf.h b/config/litoautoconf.h new file mode 100644 index 000000000000..6467c8f4e2a5 --- /dev/null +++ b/config/litoautoconf.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#define CONFIG_PINCTRL_LPI 1 +#define CONFIG_AUDIO_EXT_CLK 1 +#define CONFIG_SND_SOC_WCD9XXX_V2 1 +#define CONFIG_SND_SOC_WCD_MBHC 1 +#define CONFIG_SND_SOC_WSA881X 1 +#define CONFIG_WCD9XXX_CODEC_CORE_V2 1 +#define CONFIG_MSM_CDC_PINCTRL 1 +#define CONFIG_MSM_QDSP6V2_CODECS 1 +#define CONFIG_MSM_ULTRASOUND 1 +#define CONFIG_MSM_QDSP6_APRV2_RPMSG 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_MSM_ADSP_LOADER 1 +#define CONFIG_REGMAP_SWR 1 +#define CONFIG_MSM_QDSP6_SSR 1 +#define CONFIG_MSM_QDSP6_PDR 1 +#define CONFIG_MSM_QDSP6_NOTIFIER 1 +#define CONFIG_SND_SOC_MSM_HOSTLESS_PCM 1 +#define CONFIG_SOUNDWIRE 1 +#define CONFIG_SOUNDWIRE_MSTR_CTRL 1 +#define CONFIG_SND_SOC_WCD_MBHC_ADC 1 +#define CONFIG_SND_SOC_QDSP6V2 1 +#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 +#define CONFIG_QTI_PP 1 +#define CONFIG_SND_HWDEP_ROUTING 1 +#define CONFIG_SND_SOC_MSM_STUB 1 +#define CONFIG_MSM_AVTIMER 1 +#define CONFIG_SND_SOC_BOLERO 1 +#define CONFIG_WSA_MACRO 1 +#define CONFIG_VA_MACRO 1 +#define CONFIG_RX_MACRO 1 +#define CONFIG_TX_MACRO 1 +#define CONFIG_SND_SOC_WCD_IRQ 1 +#define CONFIG_SND_SOC_WCD938X 1 +#define CONFIG_SND_SOC_WCD938X_SLAVE 1 +#define CONFIG_SND_SOC_LITO 1 +#define CONFIG_SND_EVENT 1 +#define CONFIG_VOICE_MHI 1 -- GitLab From 8d786748c00c0b6707547109ed0ef3a470101b11 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Fri, 19 Apr 2019 10:32:02 -0700 Subject: [PATCH 0937/1645] ASoC: remove the usage of dev_set_name in msm-transcode-loopback Remove the invocation of function dev_set_name from the driver msm-transcode-loopback since it is not needed anymore. Change-Id: If47a053ccec35b913b6cb2456bbfcec91933b0bf Signed-off-by: Xiaoyu Ye --- asoc/msm-transcode-loopback-q6-v2.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index 67bdc75a1647..a311cc1e91fd 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -1594,10 +1594,7 @@ static struct snd_soc_component_driver msm_soc_component = { static int msm_transcode_dev_probe(struct platform_device *pdev) { - pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev)); - if (pdev->dev.of_node) - dev_set_name(&pdev->dev, "%s", "msm-transcode-loopback"); return snd_soc_register_component(&pdev->dev, &msm_soc_component, -- GitLab From d284ff1e0cf9ab53f4e7bae890bc16575e9df292 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 1 Apr 2019 15:34:50 +0530 Subject: [PATCH 0938/1645] Audio: Add lito target for audio-kernel Add lito target for audio-kernel modules. Change-Id: Ic8b43df74504950e4baad9701abeddcf8f30b420 Signed-off-by: Vatsal Bucha --- asoc/Android.mk | 7 ++++++- asoc/Kbuild | 12 ++++++++++++ asoc/codecs/Android.mk | 6 +++++- asoc/codecs/Kbuild | 5 +++++ asoc/codecs/bolero/Android.mk | 6 +++++- asoc/codecs/bolero/Kbuild | 5 +++++ asoc/codecs/wcd938x/Android.mk | 6 +++++- asoc/codecs/wcd938x/Kbuild | 5 +++++ dsp/Android.mk | 6 +++++- dsp/Kbuild | 5 +++++ dsp/codecs/Android.mk | 6 +++++- dsp/codecs/Kbuild | 5 +++++ ipc/Android.mk | 6 +++++- ipc/Kbuild | 5 +++++ soc/Android.mk | 10 +++++++--- soc/Kbuild | 5 +++++ 16 files changed, 90 insertions(+), 10 deletions(-) diff --git a/asoc/Android.mk b/asoc/Android.mk index db01167eba1e..ca2dffccc47c 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -23,9 +23,14 @@ TARGET := kona AUDIO_SELECT := CONFIG_SND_SOC_KONA=m endif +ifeq ($(call is-board-platform,lito),true) +TARGET := lito +AUDIO_SELECT := CONFIG_SND_SOC_LITO=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/Kbuild b/asoc/Kbuild index 945d554c7014..2b0696b05e58 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -34,6 +34,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h endif + ifeq ($(CONFIG_ARCH_LITO), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export @@ -94,6 +99,10 @@ ifdef CONFIG_SND_SOC_KONA MACHINE_OBJS += kona.o endif +ifdef CONFIG_SND_SOC_LITO + MACHINE_OBJS += kona.o +endif + ifdef CONFIG_SND_SOC_CPE CPE_LSM_OBJS += msm-cpe-lsm.o endif @@ -192,6 +201,9 @@ machine_dlkm-y := $(MACHINE_OBJS) obj-$(CONFIG_SND_SOC_KONA) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) +obj-$(CONFIG_SND_SOC_LITO) += machine_dlkm.o +machine_dlkm-y := $(MACHINE_OBJS) + obj-$(CONFIG_SND_SOC_CPE) += cpe_lsm_dlkm.o cpe_lsm_dlkm-y := $(CPE_LSM_OBJS) diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index b73b983ca01a..539bd55e91e7 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -19,9 +19,13 @@ ifeq ($(call is-board-platform,kona),true) AUDIO_SELECT := CONFIG_SND_SOC_KONA=m endif +ifeq ($(call is-board-platform,lito),true) +AUDIO_SELECT := CONFIG_SND_SOC_LITO=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index a40c75f47e0e..1d7142addba8 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -34,6 +34,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h endif + ifeq ($(CONFIG_ARCH_LITO), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/asoc/codecs/bolero/Android.mk b/asoc/codecs/bolero/Android.mk index d96d61645ef7..cf51a44f0bac 100644 --- a/asoc/codecs/bolero/Android.mk +++ b/asoc/codecs/bolero/Android.mk @@ -11,9 +11,13 @@ ifeq ($(call is-board-platform,kona),true) AUDIO_SELECT := CONFIG_SND_SOC_KONA=m endif +ifeq ($(call is-board-platform,lito),true) +AUDIO_SELECT := CONFIG_SND_SOC_LITO=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona lito),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild index 25d788170f4c..374b52894885 100644 --- a/asoc/codecs/bolero/Kbuild +++ b/asoc/codecs/bolero/Kbuild @@ -31,6 +31,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h endif + ifeq ($(CONFIG_ARCH_LITO), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf export diff --git a/asoc/codecs/wcd938x/Android.mk b/asoc/codecs/wcd938x/Android.mk index 81bb35670715..96fb6f569701 100644 --- a/asoc/codecs/wcd938x/Android.mk +++ b/asoc/codecs/wcd938x/Android.mk @@ -7,9 +7,13 @@ ifeq ($(call is-board-platform,kona),true) AUDIO_SELECT := CONFIG_SND_SOC_KONA=m endif +ifeq ($(call is-board-platform,lito),true) +AUDIO_SELECT := CONFIG_SND_SOC_LITO=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,kona),true) +ifeq ($(call is-board-platform-in-list,kona lito),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wcd938x/Kbuild b/asoc/codecs/wcd938x/Kbuild index 309089074f24..e301bd5dfb01 100644 --- a/asoc/codecs/wcd938x/Kbuild +++ b/asoc/codecs/wcd938x/Kbuild @@ -19,6 +19,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h endif + ifeq ($(CONFIG_ARCH_LITO), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif endif diff --git a/dsp/Android.mk b/dsp/Android.mk index ddaebe2d6168..42fd4cb8ea7b 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -15,9 +15,13 @@ ifeq ($(call is-board-platform, kona),true) AUDIO_SELECT := CONFIG_SND_SOC_KONA=m endif +ifeq ($(call is-board-platform, lito),true) +AUDIO_SELECT := CONFIG_SND_SOC_LITO=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/Kbuild b/dsp/Kbuild index daf0b303aa0e..cf9de150f494 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -29,6 +29,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h endif + ifeq ($(CONFIG_ARCH_LITO), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/dsp/codecs/Android.mk b/dsp/codecs/Android.mk index 25726ace8f31..65507176ceca 100644 --- a/dsp/codecs/Android.mk +++ b/dsp/codecs/Android.mk @@ -15,9 +15,13 @@ ifeq ($(call is-board-platform,kona),true) AUDIO_SELECT := CONFIG_SND_SOC_KONA=m endif +ifeq ($(call is-board-platform,lito),true) +AUDIO_SELECT := CONFIG_SND_SOC_LITO=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index c80cace5eec2..b4be4852ab40 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -29,6 +29,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h endif + ifeq ($(CONFIG_ARCH_LITO), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/ipc/Android.mk b/ipc/Android.mk index 066c5b801c91..800d8d4b8919 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -15,9 +15,13 @@ ifeq ($(call is-board-platform,kona),true) AUDIO_SELECT := CONFIG_SND_SOC_KONA=m endif +ifeq ($(call is-board-platform,lito),true) +AUDIO_SELECT := CONFIG_SND_SOC_LITO=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito),true) LOCAL_PATH := $(call my-dir) diff --git a/ipc/Kbuild b/ipc/Kbuild index 3577623d5a14..2da5fbd317f4 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -30,6 +30,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h endif + ifeq ($(CONFIG_ARCH_LITO), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/soc/Android.mk b/soc/Android.mk index 26f18e67affd..0698221db437 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -15,9 +15,13 @@ ifeq ($(call is-board-platform,kona),true) AUDIO_SELECT := CONFIG_SND_SOC_KONA=m endif +ifeq ($(call is-board-platform,lito),true) +AUDIO_SELECT := CONFIG_SND_SOC_LITO=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito),true) LOCAL_PATH := $(call my-dir) @@ -44,7 +48,7 @@ KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) KBUILD_OPTIONS += $(AUDIO_SELECT) ########################################################### -ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona lito),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_lpi.ko LOCAL_MODULE_KBUILD_NAME := pinctrl_lpi_dlkm.ko @@ -78,7 +82,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### -ifeq ($(call is-board-platform-in-list, $(MSMSTEPPE) kona),true) +ifeq ($(call is-board-platform-in-list, $(MSMSTEPPE) kona lito),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_snd_event.ko LOCAL_MODULE_KBUILD_NAME := snd_event_dlkm.ko diff --git a/soc/Kbuild b/soc/Kbuild index 12d99c3dc059..20134c29901b 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -24,6 +24,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h endif + ifeq ($(CONFIG_ARCH_LITO), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm6150auto.conf export -- GitLab From 55789b723999b251d93bf1b2e3794addf9e9c085 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 20 Apr 2019 00:55:42 +0530 Subject: [PATCH 0939/1645] ASoC: bolero: va-macro: Fix clock sequence during path enable Fix mismatch in TX clock count during three mic VA usecase. Change-Id: I5f86fc8bf4f379e14ed8e15376f918b622bc221f Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/va-macro.c | 50 ++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index a4f3c7d557ed..cdfe6c78538f 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -588,10 +588,6 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, /* apply gain after decimator is enabled */ snd_soc_component_write(component, tx_gain_ctl_reg, snd_soc_component_read32(component, tx_gain_ctl_reg)); - bolero_clk_rsc_request_clock(va_priv->dev, - va_priv->default_clk_id, - TX_CORE_CLK, - false); break; case SND_SOC_DAPM_PRE_PMD: hpf_cut_off_freq = @@ -632,6 +628,37 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, return 0; } +static int va_macro_enable_tx(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + int ret = 0; + + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) + return -EINVAL; + + dev_dbg(va_dev, "%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + ret = bolero_clk_rsc_request_clock(va_priv->dev, + va_priv->default_clk_id, + TX_CORE_CLK, + false); + break; + default: + dev_err(va_priv->dev, + "%s: invalid DAPM event %d\n", __func__, event); + ret = -EINVAL; + break; + } + + return ret; +} + static int va_macro_enable_micbias(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -1007,14 +1034,17 @@ static const struct snd_kcontrol_new va_aif3_cap_mixer[] = { }; static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = { - SND_SOC_DAPM_AIF_OUT("VA_AIF1 CAP", "VA_AIF1 Capture", 0, - SND_SOC_NOPM, VA_MACRO_AIF1_CAP, 0), + SND_SOC_DAPM_AIF_OUT_E("VA_AIF1 CAP", "VA_AIF1 Capture", 0, + SND_SOC_NOPM, VA_MACRO_AIF1_CAP, 0, + va_macro_enable_tx, SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_AIF_OUT("VA_AIF2 CAP", "VA_AIF2 Capture", 0, - SND_SOC_NOPM, VA_MACRO_AIF2_CAP, 0), + SND_SOC_DAPM_AIF_OUT_E("VA_AIF2 CAP", "VA_AIF2 Capture", 0, + SND_SOC_NOPM, VA_MACRO_AIF2_CAP, 0, + va_macro_enable_tx, SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_AIF_OUT("VA_AIF3 CAP", "VA_AIF3 Capture", 0, - SND_SOC_NOPM, VA_MACRO_AIF3_CAP, 0), + SND_SOC_DAPM_AIF_OUT_E("VA_AIF3 CAP", "VA_AIF3 Capture", 0, + SND_SOC_NOPM, VA_MACRO_AIF3_CAP, 0, + va_macro_enable_tx, SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_MIXER("VA_AIF1_CAP Mixer", SND_SOC_NOPM, VA_MACRO_AIF1_CAP, 0, -- GitLab From caa541d6883577a7a73d3c94c373e4643a0a9edc Mon Sep 17 00:00:00 2001 From: Zhou Song Date: Tue, 19 Feb 2019 18:37:47 +0800 Subject: [PATCH 0940/1645] asoc: dsp: add support for aptx adaptive speech Add support for speech codec which is similar to a2dp aptx adaptive. Change-Id: Ibfbcf086f009fdb561e26aaf92cefc92f1bd16ca Signed-off-by: Zhou Song --- asoc/msm-dai-q6-v2.c | 46 ++++++++++ asoc/msm-pcm-routing-v2.c | 38 +++++++++ dsp/q6afe.c | 169 ++++++++++++++++++++++++++++++------- include/dsp/apr_audio-v2.h | 67 +++++++++++++++ 4 files changed, 289 insertions(+), 31 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 580335691b1a..fd83b0e0395f 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -57,6 +57,8 @@ enum { ENC_FMT_APTX_ADAPTIVE = ASM_MEDIA_FMT_APTX_ADAPTIVE, DEC_FMT_APTX_ADAPTIVE = ASM_MEDIA_FMT_APTX_ADAPTIVE, DEC_FMT_MP3 = ASM_MEDIA_FMT_MP3, + ENC_FMT_APTX_AD_SPEECH = ASM_MEDIA_FMT_APTX_AD_SPEECH, + DEC_FMT_APTX_AD_SPEECH = ASM_MEDIA_FMT_APTX_AD_SPEECH, }; enum { @@ -2827,6 +2829,12 @@ static int msm_dai_q6_afe_enc_cfg_get(struct snd_kcontrol *kcontrol, &dai_data->enc_config.data, sizeof(struct asm_aptx_ad_enc_cfg_t)); break; + case ENC_FMT_APTX_AD_SPEECH: + memcpy(ucontrol->value.bytes.data + format_size, + &dai_data->enc_config.data, + sizeof(struct asm_aptx_ad_speech_enc_cfg_t)); + break; + default: pr_debug("%s: unknown format = %d\n", __func__, dai_data->enc_config.format); @@ -2890,6 +2898,12 @@ static int msm_dai_q6_afe_enc_cfg_put(struct snd_kcontrol *kcontrol, ucontrol->value.bytes.data + format_size, sizeof(struct asm_aptx_ad_enc_cfg_t)); break; + case ENC_FMT_APTX_AD_SPEECH: + memcpy(&dai_data->enc_config.data, + ucontrol->value.bytes.data + format_size, + sizeof(struct asm_aptx_ad_speech_enc_cfg_t)); + break; + default: pr_debug("%s: Ignore enc config for unknown format = %d\n", __func__, dai_data->enc_config.format); @@ -3216,6 +3230,7 @@ static int msm_dai_q6_afe_feedback_dec_cfg_get(struct snd_kcontrol *kcontrol, { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; u32 format_size = 0; + u32 abr_size = 0; if (!dai_data) { pr_err("%s: Invalid dai data\n", __func__); @@ -3229,10 +3244,25 @@ static int msm_dai_q6_afe_feedback_dec_cfg_get(struct snd_kcontrol *kcontrol, pr_debug("%s: abr_dec_cfg for %d format\n", __func__, dai_data->dec_config.format); + abr_size = sizeof(dai_data->dec_config.abr_dec_cfg.imc_info); memcpy(ucontrol->value.bytes.data + format_size, &dai_data->dec_config.abr_dec_cfg, sizeof(struct afe_imc_dec_enc_info)); + switch (dai_data->dec_config.format) { + case DEC_FMT_APTX_AD_SPEECH: + pr_debug("%s: afe_dec_cfg for %d format\n", + __func__, dai_data->dec_config.format); + memcpy(ucontrol->value.bytes.data + format_size + abr_size, + &dai_data->dec_config.data, + sizeof(struct asm_aptx_ad_speech_dec_cfg_t)); + break; + default: + pr_debug("%s: no afe_dec_cfg for format %d\n", + __func__, dai_data->dec_config.format); + break; + } + return 0; } @@ -3241,6 +3271,7 @@ static int msm_dai_q6_afe_feedback_dec_cfg_put(struct snd_kcontrol *kcontrol, { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; u32 format_size = 0; + u32 abr_size = 0; if (!dai_data) { pr_err("%s: Invalid dai data\n", __func__); @@ -3256,10 +3287,25 @@ static int msm_dai_q6_afe_feedback_dec_cfg_put(struct snd_kcontrol *kcontrol, pr_debug("%s: abr_dec_cfg for %d format\n", __func__, dai_data->dec_config.format); + abr_size = sizeof(dai_data->dec_config.abr_dec_cfg.imc_info); memcpy(&dai_data->dec_config.abr_dec_cfg, ucontrol->value.bytes.data + format_size, sizeof(struct afe_imc_dec_enc_info)); dai_data->dec_config.abr_dec_cfg.is_abr_enabled = true; + + switch (dai_data->dec_config.format) { + case DEC_FMT_APTX_AD_SPEECH: + pr_debug("%s: afe_dec_cfg for %d format\n", + __func__, dai_data->dec_config.format); + memcpy(&dai_data->dec_config.data, + ucontrol->value.bytes.data + format_size + abr_size, + sizeof(struct asm_aptx_ad_speech_dec_cfg_t)); + break; + default: + pr_debug("%s: no afe_dec_cfg for format %d\n", + __func__, dai_data->dec_config.format); + break; + } return 0; } diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 5a75609149d0..cf560381200d 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -57,6 +57,7 @@ static struct cal_type_data *cal_data[MAX_ROUTING_CAL_TYPES]; static int fm_switch_enable; static int hfp_switch_enable; static int a2dp_switch_enable; +static int sco_switch_enable; static int int0_mi2s_switch_enable; static int int4_mi2s_switch_enable; static int pri_mi2s_switch_enable; @@ -2555,6 +2556,34 @@ static int msm_routing_a2dp_switch_mixer_put(struct snd_kcontrol *kcontrol, return 1; } +static int msm_routing_sco_switch_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = sco_switch_enable; + pr_debug("%s: SCO Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_sco_switch_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: SCO Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + sco_switch_enable = ucontrol->value.integer.value[0]; + if (sco_switch_enable) + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, + 1, update); + else + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, + 0, update); + return 1; +} + static int msm_routing_get_int0_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -17367,6 +17396,11 @@ static const struct snd_kcontrol_new a2dp_slim7_switch_mixer_controls = 0, 1, 0, msm_routing_a2dp_switch_mixer_get, msm_routing_a2dp_switch_mixer_put); +static const struct snd_kcontrol_new sco_slim7_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_sco_switch_mixer_get, + msm_routing_sco_switch_mixer_put); + static const struct soc_enum lsm_port_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_port_text), lsm_port_text); @@ -19493,6 +19527,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &quat_mi2s_rx_switch_mixer_controls), SND_SOC_DAPM_SWITCH("QUIN_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, &quin_mi2s_rx_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SCO_SLIM7_DL_HL", SND_SOC_NOPM, 0, 0, + &sco_slim7_switch_mixer_controls), SND_SOC_DAPM_SWITCH("HFP_PRI_AUX_UL_HL", SND_SOC_NOPM, 0, 0, &hfp_pri_aux_switch_mixer_controls), SND_SOC_DAPM_SWITCH("HFP_AUX_UL_HL", SND_SOC_NOPM, 0, 0, @@ -22420,6 +22456,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_4_RX", NULL, "SLIMBUS4_DL_HL"}, {"SLIMBUS6_DL_HL", "Switch", "SLIM0_DL_HL"}, {"SLIMBUS_6_RX", NULL, "SLIMBUS6_DL_HL"}, + {"SCO_SLIM7_DL_HL", "Switch", "SLIM7_DL_HL"}, + {"SLIMBUS_7_RX", NULL, "SCO_SLIM7_DL_HL"}, {"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"}, {"SLIM1_UL_HL", NULL, "SLIMBUS_1_TX"}, {"SLIM3_UL_HL", NULL, "SLIMBUS_3_TX"}, diff --git a/dsp/q6afe.c b/dsp/q6afe.c index fd66571dffbb..1833e79adbce 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -91,6 +91,11 @@ enum { APTX_AD_44_1 = 1 }; +enum { + AFE_MATCHED_PORT_DISABLE, + AFE_MATCHED_PORT_ENABLE +}; + struct wlock { struct wakeup_source ws; }; @@ -3623,6 +3628,8 @@ static int q6afe_send_dec_config(u16 port_id, struct avs_dec_congestion_buffer_param_t dec_buffer_id_param; struct afe_enc_dec_imc_info_param_t imc_info_param; struct afe_port_media_type_t media_type; + struct afe_matched_port_t matched_port_param; + struct asm_aptx_ad_speech_mode_cfg_t speech_codec_init_param; struct param_hdr_v3 param_hdr; int ret; u32 dec_fmt; @@ -3631,6 +3638,8 @@ static int q6afe_send_dec_config(u16 port_id, memset(&dec_media_fmt, 0, sizeof(dec_media_fmt)); memset(&imc_info_param, 0, sizeof(imc_info_param)); memset(&media_type, 0, sizeof(media_type)); + memset(&matched_port_param, 0, sizeof(matched_port_param)); + memset(&speech_codec_init_param, 0, sizeof(speech_codec_init_param)); memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AFE_MODULE_ID_DECODER; @@ -3749,6 +3758,9 @@ static int q6afe_send_dec_config(u16 port_id, break; } /* fall through for abr enabled case */ + case ASM_MEDIA_FMT_APTX_AD_SPEECH: + media_type.sample_rate = AFE_PORT_SAMPLE_RATE_32K; + break; default: media_type.sample_rate = afe_config.slim_sch.sample_rate; @@ -3775,7 +3787,8 @@ static int q6afe_send_dec_config(u16 port_id, } if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 && - format != ASM_MEDIA_FMT_APTX_ADAPTIVE) { + format != ASM_MEDIA_FMT_APTX_ADAPTIVE && + format != ASM_MEDIA_FMT_APTX_AD_SPEECH) { pr_debug("%s:Unsuppported dec format. Ignore AFE config %u\n", __func__, format); goto exit; @@ -3786,6 +3799,24 @@ static int q6afe_send_dec_config(u16 port_id, pr_debug("%s: Ignore AFE config for abr case\n", __func__); goto exit; } + if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH) { + pr_debug("%s: sending AFE_PARAM_ID_RATE_MATCHED_PORT to DSP payload\n", + __func__); + param_hdr.param_id = AFE_PARAM_ID_RATE_MATCHED_PORT; + param_hdr.param_size = + sizeof(struct afe_matched_port_t); + matched_port_param.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE; + matched_port_param.enable = AFE_MATCHED_PORT_ENABLE; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &matched_port_param); + if (ret) { + pr_err("%s: AFE_PARAM_ID_RATE_MATCHED_PORT for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + } pr_debug("%s: sending AFE_DECODER_PARAM_ID_DEC_MEDIA_FMT to DSP payload\n", __func__); @@ -3822,6 +3853,26 @@ static int q6afe_send_dec_config(u16 port_id, goto exit; } break; + case ASM_MEDIA_FMT_APTX_AD_SPEECH: + param_hdr.param_size = + sizeof(struct asm_aptx_ad_speech_dec_cfg_t); + + pr_debug("%s: send AVS_DECODER_PARAM_ID_APTX_AD_SPEECH_DEC_INIT to DSP payload\n", + __func__); + param_hdr.param_id = + AVS_DECODER_PARAM_ID_APTX_AD_SPEECH_DEC_INIT; + speech_codec_init_param = + cfg->data.aptx_ad_speech_config.speech_mode; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &speech_codec_init_param); + if (ret) { + pr_err("%s: AVS_DECODER_PARAM_ID_APTX_ADAPTIVE_SPEECH_DEC_INIT for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + break; default: pr_debug("%s:No need to send DEC_MEDIA_FMT to DSP payload\n", __func__); @@ -3848,6 +3899,8 @@ static int q6afe_send_enc_config(u16 port_id, struct asm_aac_frame_size_control_t frame_ctl_param; struct afe_port_media_type_t media_type; struct aptx_channel_mode_param_t channel_mode_param; + struct afe_matched_port_t matched_port_param; + struct asm_aptx_ad_speech_mode_cfg_t speech_codec_init_param; struct param_hdr_v3 param_hdr; int ret; @@ -3862,12 +3915,15 @@ static int q6afe_send_enc_config(u16 port_id, memset(&imc_info_param, 0, sizeof(imc_info_param)); memset(&frame_ctl_param, 0, sizeof(frame_ctl_param)); memset(&media_type, 0, sizeof(media_type)); + memset(&matched_port_param, 0, sizeof(matched_port_param)); + memset(&speech_codec_init_param, 0, sizeof(speech_codec_init_param)); memset(¶m_hdr, 0, sizeof(param_hdr)); if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 && format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD && format != ASM_MEDIA_FMT_CELT && format != ASM_MEDIA_FMT_LDAC && - format != ASM_MEDIA_FMT_APTX_ADAPTIVE) { + format != ASM_MEDIA_FMT_APTX_ADAPTIVE && + format != ASM_MEDIA_FMT_APTX_AD_SPEECH) { pr_err("%s:Unsuppported enc format. Ignore AFE config\n", __func__); return 0; @@ -3902,6 +3958,9 @@ static int q6afe_send_enc_config(u16 port_id, enc_blk_param.enc_cfg_blk_size = sizeof(enc_blk_param.enc_blk_config) - sizeof(struct asm_aac_frame_size_control_t); + } else if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH) { + param_hdr.param_size = sizeof(struct afe_enc_aptx_ad_speech_cfg_blk_param_t); + enc_blk_param.enc_cfg_blk_size = sizeof(struct asm_custom_enc_cfg_t); } else { param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t); enc_blk_param.enc_cfg_blk_size = @@ -3983,6 +4042,24 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } } + if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH) { + pr_debug("%s: sending AVS_DECODER_PARAM_ID_APTX_AD_SPEECH_ENC_INIT to DSP\n", + __func__); + param_hdr.param_id = AVS_DECODER_PARAM_ID_APTX_AD_SPEECH_ENC_INIT; + param_hdr.param_size = + sizeof(struct asm_aptx_ad_speech_dec_cfg_t); + speech_codec_init_param = cfg->aptx_ad_speech_config.speech_mode; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &speech_codec_init_param); + if (ret) { + pr_err("%s: AFE_ID_APTX_ADAPTIVE_ENC_INIT for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + } + pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP\n", __func__); param_hdr.param_id = AFE_ENCODER_PARAM_ID_PACKETIZER_ID; @@ -3998,19 +4075,21 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } - pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING mode= %d to DSP payload\n", - __func__, scrambler_mode); - param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING; - param_hdr.param_size = sizeof(struct avs_enc_set_scrambler_param_t); - enc_set_scrambler_param.enable_scrambler = scrambler_mode; - ret = q6afe_pack_and_set_param_in_band(port_id, - q6audio_get_port_index(port_id), - param_hdr, - (u8 *) &enc_set_scrambler_param); - if (ret) { - pr_err("%s: AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING for port 0x%x failed %d\n", - __func__, port_id, ret); - goto exit; + if (format != ASM_MEDIA_FMT_APTX_AD_SPEECH) { + pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING mode= %d to DSP payload\n", + __func__, scrambler_mode); + param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING; + param_hdr.param_size = sizeof(struct avs_enc_set_scrambler_param_t); + enc_set_scrambler_param.enable_scrambler = scrambler_mode; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &enc_set_scrambler_param); + if (ret) { + pr_err("%s: AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } } if (format == ASM_MEDIA_FMT_APTX) { @@ -4032,22 +4111,25 @@ static int q6afe_send_enc_config(u16 port_id, if ((format == ASM_MEDIA_FMT_LDAC && cfg->ldac_config.abr_config.is_abr_enabled) || - format == ASM_MEDIA_FMT_APTX_ADAPTIVE) { - pr_debug("%s:sending AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP to DSP payload", - __func__); - param_hdr.param_id = AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP; - param_hdr.param_size = - sizeof(struct afe_enc_level_to_bitrate_map_param_t); - map_param.mapping_table = - cfg->ldac_config.abr_config.mapping_info; - ret = q6afe_pack_and_set_param_in_band(port_id, - q6audio_get_port_index(port_id), - param_hdr, - (u8 *) &map_param); - if (ret) { - pr_err("%s: AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP for port 0x%x failed %d\n", - __func__, port_id, ret); - goto exit; + format == ASM_MEDIA_FMT_APTX_ADAPTIVE || + format == ASM_MEDIA_FMT_APTX_AD_SPEECH) { + if (format != ASM_MEDIA_FMT_APTX_AD_SPEECH) { + pr_debug("%s:sending AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP to DSP payload", + __func__); + param_hdr.param_id = AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP; + param_hdr.param_size = + sizeof(struct afe_enc_level_to_bitrate_map_param_t); + map_param.mapping_table = + cfg->ldac_config.abr_config.mapping_info; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &map_param); + if (ret) { + pr_err("%s: AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } } pr_debug("%s: sending AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION to DSP payload", @@ -4059,6 +4141,9 @@ static int q6afe_send_enc_config(u16 port_id, if (format == ASM_MEDIA_FMT_APTX_ADAPTIVE) imc_info_param.imc_info = cfg->aptx_ad_config.abr_cfg.imc_info; + else if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH) + imc_info_param.imc_info = + cfg->aptx_ad_speech_config.imc_info; else imc_info_param.imc_info = cfg->ldac_config.abr_config.imc_info; @@ -4084,6 +4169,9 @@ static int q6afe_send_enc_config(u16 port_id, else if (format == ASM_MEDIA_FMT_APTX_ADAPTIVE) media_type.sample_rate = cfg->aptx_ad_config.custom_cfg.sample_rate; + else if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH) + media_type.sample_rate = + cfg->aptx_ad_speech_config.custom_cfg.sample_rate; else media_type.sample_rate = afe_config.slim_sch.sample_rate; @@ -4109,6 +4197,25 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } + if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH) { + pr_debug("%s: sending AFE_PARAM_ID_RATE_MATCHED_PORT to DSP payload", + __func__); + param_hdr.param_id = AFE_PARAM_ID_RATE_MATCHED_PORT; + param_hdr.param_size = + sizeof(struct afe_matched_port_t); + matched_port_param.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE; + matched_port_param.enable = AFE_MATCHED_PORT_ENABLE; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &matched_port_param); + if (ret) { + pr_err("%s: AFE_PARAM_ID_RATE_MATCHED_PORT for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + } + exit: return ret; } diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 62ff28b17ed0..35cd02104239 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -2487,6 +2487,7 @@ struct afe_port_data_cmd_rt_proxy_port_read_v2 { #define AFE_MODULE_AUDIO_DEV_INTERFACE 0x0001020C #define AFE_PORT_SAMPLE_RATE_8K 8000 #define AFE_PORT_SAMPLE_RATE_16K 16000 +#define AFE_PORT_SAMPLE_RATE_32K 32000 #define AFE_PORT_SAMPLE_RATE_44_1K 44100 #define AFE_PORT_SAMPLE_RATE_48K 48000 #define AFE_PORT_SAMPLE_RATE_96K 96000 @@ -3909,6 +3910,14 @@ struct afe_id_aptx_adaptive_enc_init */ #define AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION 0x0001323D +/* + * This is needed to be used only for SWB voice call use case. + * This is needed to be issued for each direction (RX AFE and TX AFE) + * along with AFE_PARAM_ID_PORT_MEDIA_TYPE + * (Issuing AF_PARAM_ID_RATE_MATCHED_PORT param alone is not useful). + */ +#define AFE_PARAM_ID_RATE_MATCHED_PORT 0x000102BE + /* * Purpose of IMC set up between encoder and decoder. * Communication instance and purpose together form the @@ -4149,6 +4158,9 @@ struct asm_aac_enc_cfg_t { /* FMT ID for apt-X Adaptive */ #define ASM_MEDIA_FMT_APTX_ADAPTIVE 0x00013204 +/* FMT ID for apt-X Adaptive speech */ +#define ASM_MEDIA_FMT_APTX_AD_SPEECH 0x00013208 + #define PCM_CHANNEL_L 1 #define PCM_CHANNEL_R 2 #define PCM_CHANNEL_C 3 @@ -4165,6 +4177,22 @@ struct asm_custom_enc_cfg_t { uint32_t custom_size; } __packed; +struct asm_aptx_ad_speech_mode_cfg_t +{ + uint32_t speech_mode; + /* + * speech mode of codec. + * + * @values 0x0(swb), 0x4(sswb) + */ + uint32_t swapping; + /* + * byte swapping of codec. + * + * @values 0x1, enable swapping + */ +} __packed; + struct asm_aptx_v2_enc_cfg_ext_t { /* * sync mode: 0x0 = stereo sync mode (default) @@ -4186,6 +4214,19 @@ struct asm_aptx_ad_enc_cfg_t struct afe_abr_enc_cfg_t abr_cfg; } __attribute__ ((packed)); +struct asm_aptx_ad_speech_enc_cfg_t +{ + struct asm_custom_enc_cfg_t custom_cfg; + struct afe_imc_dec_enc_info imc_info; + struct asm_aptx_ad_speech_mode_cfg_t speech_mode; +} __attribute__ ((packed)); + +struct afe_matched_port_t +{ + uint32_t minor_version; + uint32_t enable; +} __attribute__ ((packed)); + #define ASM_MEDIA_FMT_CELT 0x00013221 struct asm_celt_specific_enc_cfg_t { /* @@ -4462,6 +4503,10 @@ struct asm_aptx_ad_dec_cfg_t { */ } __packed; +struct asm_aptx_ad_speech_dec_cfg_t { + struct asm_aptx_ad_speech_mode_cfg_t speech_mode; +}; + union afe_enc_config_data { struct asm_sbc_enc_cfg_t sbc_config; struct asm_aac_enc_cfg_t aac_config; @@ -4470,6 +4515,7 @@ union afe_enc_config_data { struct asm_aptx_enc_cfg_t aptx_config; struct asm_ldac_enc_cfg_t ldac_config; struct asm_aptx_ad_enc_cfg_t aptx_ad_config; + struct asm_aptx_ad_speech_enc_cfg_t aptx_ad_speech_config; }; struct afe_enc_config { @@ -4484,6 +4530,7 @@ union afe_dec_config_data { struct asm_aac_dec_cfg_v2_t aac_config; struct asm_mp3_dec_cfg_t mp3_config; struct asm_aptx_ad_dec_cfg_t aptx_ad_config; + struct asm_aptx_ad_speech_dec_cfg_t aptx_ad_speech_config; }; struct afe_dec_config { @@ -4500,6 +4547,14 @@ struct afe_enc_cfg_blk_param_t { union afe_enc_config_data enc_blk_config; }; +struct afe_enc_aptx_ad_speech_cfg_blk_param_t { + uint32_t enc_cfg_blk_size; + /* + * Size of the encoder configuration block that follows this member + */ + struct asm_custom_enc_cfg_t custom_cfg; +}; + /* * Payload of the AVS_DECODER_PARAM_ID_DEC_MEDIA_FMT parameter used by * AVS_MODULE_ID_DECODER. @@ -4587,6 +4642,18 @@ struct avs_dec_congestion_buffer_param_t { */ #define AVS_DECODER_PARAM_ID_DEC_MEDIA_FMT 0x00013232 +/* + * ID of the parameter used by #AVS_MODULE_ID_DECODER to configure + * the decoder mode of adaptive speech and byte swap mode + */ +#define AVS_DECODER_PARAM_ID_APTX_AD_SPEECH_DEC_INIT 0x0001334D + +/* + * ID of the parameter used by #AVS_MODULE_ID_ENCODER to configure + * the encoder mode of adaptive speech and byte swap mode + */ +#define AVS_DECODER_PARAM_ID_APTX_AD_SPEECH_ENC_INIT 0x0001332B + /* ID of the parameter used by #AFE_MODULE_AUDIO_DEV_INTERFACE to configure * the island mode for a given AFE port. */ -- GitLab From 952f3d7864cf9ac7eb23e9ad4374742ffe89adc2 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Sun, 21 Apr 2019 10:33:07 -0700 Subject: [PATCH 0941/1645] Revert "dsp: voice_mhi: use modified mhi sync/put api" This reverts commit 40c749da4c9e3fbb70c321e1acee4e7d873ae230. This change needs a corresponding change in msm-4.19 which is not yet ready. Revert this change for now, until the dependency change is ready to be merged. Change-Id: I7ac030b03c01500e6061dbc6e5b4ad13385a0109 Signed-off-by: Banajit Goswami --- dsp/voice_mhi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dsp/voice_mhi.c b/dsp/voice_mhi.c index 69942b24807c..87572efa7e76 100644 --- a/dsp/voice_mhi.c +++ b/dsp/voice_mhi.c @@ -228,8 +228,7 @@ int voice_mhi_start(void) goto done; } if (voice_mhi_lcl.vote_count == 0) { - ret = mhi_device_get_sync(voice_mhi_lcl.mhi_dev, - MHI_VOTE_DEVICE); + ret = mhi_device_get_sync(voice_mhi_lcl.mhi_dev); if (ret) { pr_err("%s: mhi_device_get_sync failed\n", __func__); @@ -270,7 +269,7 @@ int voice_mhi_end(void) } if (voice_mhi_lcl.vote_count == 1) - mhi_device_put(voice_mhi_lcl.mhi_dev, MHI_VOTE_DEVICE); + mhi_device_put(voice_mhi_lcl.mhi_dev); voice_mhi_lcl.vote_count--; } mutex_unlock(&voice_mhi_lcl.mutex); -- GitLab From 23513e09734cd0a27c58d2f46e19af9eff2448e1 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 28 Feb 2019 11:06:41 +0530 Subject: [PATCH 0942/1645] dsp: Fix payload mismatch issue in AFE clock setting IID support is set from user space during boot up which can come in parallel with AFE set clock requests due to which param payload is set in difference with the actual set param command as per instance id support. Change-Id: I07e45fda0943cac814f25c16da930dfae5d209a6 Signed-off-by: Aditya Bavanari --- dsp/q6afe.c | 21 +++++++----- dsp/q6common.c | 73 +++++++++++++++++++++++++++++++++++++++++- include/dsp/q6common.h | 6 ++-- 3 files changed, 89 insertions(+), 11 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index c470ecf5091d..7b8bd8d6cb46 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1461,7 +1461,8 @@ static int q6afe_svc_set_params_v2(int index, struct mem_mapping_hdr *mem_hdr, } static int q6afe_svc_set_params(int index, struct mem_mapping_hdr *mem_hdr, - u8 *packed_param_data, u32 packed_data_size) + u8 *packed_param_data, u32 packed_data_size, + bool is_iid_supported) { int ret; @@ -1471,7 +1472,7 @@ static int q6afe_svc_set_params(int index, struct mem_mapping_hdr *mem_hdr, return ret; } - if (q6common_is_instance_id_supported()) + if (is_iid_supported) return q6afe_svc_set_params_v2(index, mem_hdr, packed_param_data, packed_data_size); @@ -1489,13 +1490,15 @@ static int q6afe_svc_pack_and_set_param_in_band(int index, u32 packed_data_size = sizeof(struct param_hdr_v3) + param_hdr.param_size; int ret = 0; + bool is_iid_supported = q6common_is_instance_id_supported(); packed_param_data = kzalloc(packed_data_size, GFP_KERNEL); if (!packed_param_data) return -ENOMEM; - ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, param_data, - &packed_data_size); + ret = q6common_pack_pp_params_v2(packed_param_data, ¶m_hdr, + param_data, &packed_data_size, + is_iid_supported); if (ret) { pr_err("%s: Failed to pack parameter header and data, error %d\n", __func__, ret); @@ -1503,7 +1506,7 @@ static int q6afe_svc_pack_and_set_param_in_band(int index, } ret = q6afe_svc_set_params(index, NULL, packed_param_data, - packed_data_size); + packed_data_size, is_iid_supported); done: kfree(packed_param_data); @@ -2590,6 +2593,7 @@ static int afe_send_codec_reg_config( struct param_hdr_v3 param_hdr; int idx = 0; int ret = -EINVAL; + bool is_iid_supported = q6common_is_instance_id_supported(); memset(¶m_hdr, 0, sizeof(param_hdr)); max_single_param = sizeof(struct param_hdr_v3) + @@ -2612,10 +2616,10 @@ static int afe_send_codec_reg_config( while (packed_data_size + max_single_param < max_data_size && idx < cdc_reg_cfg->num_registers) { - ret = q6common_pack_pp_params( + ret = q6common_pack_pp_params_v2( packed_param_data + packed_data_size, ¶m_hdr, (u8 *) &cdc_reg_cfg->reg_data[idx], - &single_param_size); + &single_param_size, is_iid_supported); if (ret) { pr_err("%s: Failed to pack parameters with error %d\n", __func__, ret); @@ -2626,7 +2630,8 @@ static int afe_send_codec_reg_config( } ret = q6afe_svc_set_params(IDX_GLOBAL_CFG, NULL, - packed_param_data, packed_data_size); + packed_param_data, packed_data_size, + is_iid_supported); if (ret) { pr_err("%s: AFE_PARAM_ID_CDC_REG_CFG failed %d\n", __func__, ret); diff --git a/dsp/q6common.c b/dsp/q6common.c index 8270054e8ec3..b5444b134732 100644 --- a/dsp/q6common.c +++ b/dsp/q6common.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. */ #include @@ -104,3 +104,74 @@ int q6common_pack_pp_params(u8 *dest, struct param_hdr_v3 *v3_hdr, return 0; } EXPORT_SYMBOL(q6common_pack_pp_params); + +/** + * q6common_pack_pp_params_v2 + * + * Populate params header based on instance ID support and pack + * it with payload. + * Instance ID support - + * yes - param_hdr_v3 + payload + * no - param_hdr_v1 + payload + * + * @dest: destination data pointer to be packed into + * @v3_hdr: param header v3 + * @param_data: param payload + * @total_size: total size of packed data (hdr + payload) + * @iid_supported: Instance ID supported or not + * + * Returns 0 on success or error on failure + */ +int q6common_pack_pp_params_v2(u8 *dest, struct param_hdr_v3 *v3_hdr, + u8 *param_data, u32 *total_size, + bool iid_supported) +{ + struct param_hdr_v1 *v1_hdr = NULL; + u32 packed_size = 0; + u32 param_size = 0; + + if (dest == NULL) { + pr_err("%s: Received NULL pointer for destination\n", __func__); + return -EINVAL; + } else if (v3_hdr == NULL) { + pr_err("%s: Received NULL pointer for header\n", __func__); + return -EINVAL; + } else if (total_size == NULL) { + pr_err("%s: Received NULL pointer for total size\n", __func__); + return -EINVAL; + } + + param_size = v3_hdr->param_size; + packed_size = iid_supported ? sizeof(struct param_hdr_v3) : + sizeof(struct param_hdr_v1); + + if (iid_supported) { + memcpy(dest, v3_hdr, packed_size); + } else { + v1_hdr = (struct param_hdr_v1 *) dest; + v1_hdr->module_id = v3_hdr->module_id; + v1_hdr->param_id = v3_hdr->param_id; + + if (param_size > U16_MAX) { + pr_err("%s: Invalid param size for V1 %d\n", __func__, + param_size); + return -EINVAL; + } + v1_hdr->param_size = param_size; + v1_hdr->reserved = 0; + } + + /* + * Make param_data optional for cases when there is no data + * present as in some set cases and all get cases. + */ + if (param_data != NULL) { + memcpy(dest + packed_size, param_data, param_size); + packed_size += param_size; + } + + *total_size = packed_size; + + return 0; +} +EXPORT_SYMBOL(q6common_pack_pp_params_v2); diff --git a/include/dsp/q6common.h b/include/dsp/q6common.h index c21ac5cc81c1..7250a138ed04 100644 --- a/include/dsp/q6common.h +++ b/include/dsp/q6common.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. */ #ifndef __Q6COMMON_H__ @@ -12,5 +12,7 @@ void q6common_update_instance_id_support(bool supported); bool q6common_is_instance_id_supported(void); int q6common_pack_pp_params(u8 *dest, struct param_hdr_v3 *v3_hdr, u8 *param_data, u32 *total_size); - +int q6common_pack_pp_params_v2(u8 *dest, struct param_hdr_v3 *v3_hdr, + u8 *param_data, u32 *total_size, + bool iid_supported); #endif /* __Q6COMMON_H__ */ -- GitLab From b9048cb1dd3f822dede0ee689e2729e9ba60a7b7 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Thu, 7 Mar 2019 14:54:13 -0500 Subject: [PATCH 0943/1645] ASoC: msm: add quat tdm tx_7 to rx_7 loopback Add Quaternary TDM TX 7 to RX 7 AFE loopback routing support. Signed-off-by: Derek Chen Change-Id: I0f6cf7cff1a0250f85f73f4ad63641b7364d4f7d --- asoc/msm-dai-fe.c | 4 +- asoc/msm-pcm-routing-v2.c | 18 ++++++++ asoc/sa8155.c | 94 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 109 insertions(+), 7 deletions(-) diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index c4976a48a7f4..6256e8a646e7 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -2026,7 +2026,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 48000, }, @@ -2042,7 +2042,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 48000, }, diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index f09d34970358..4ef0f9a94333 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -16398,6 +16398,14 @@ static const struct snd_kcontrol_new quat_tdm_rx_3_port_mixer_controls[] = { msm_routing_put_port_mixer), }; +static const struct snd_kcontrol_new quat_tdm_rx_7_port_mixer_controls[] = { + SOC_DOUBLE_EXT("QUAT_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_7, + MSM_BACKEND_DAI_QUAT_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + static const struct snd_kcontrol_new quin_tdm_rx_0_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_RX_0, @@ -20054,6 +20062,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUAT_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0, quat_tdm_rx_3_port_mixer_controls, ARRAY_SIZE(quat_tdm_rx_3_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_7 Port Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_7_port_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_7_port_mixer_controls)), SND_SOC_DAPM_MIXER("QUIN_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, quin_tdm_rx_0_port_mixer_controls, ARRAY_SIZE(quin_tdm_rx_0_port_mixer_controls)), @@ -22735,10 +22746,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_TX_1_UL_HL", NULL, "QUAT_TDM_TX_1"}, {"QUAT_TDM_TX_2_UL_HL", NULL, "QUAT_TDM_TX_2"}, {"QUAT_TDM_TX_3_UL_HL", NULL, "QUAT_TDM_TX_3"}, + {"QUAT_TDM_TX_7_UL_HL", NULL, "QUAT_TDM_TX_7"}, {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0_DL_HL"}, {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1_DL_HL"}, {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_DL_HL"}, {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3_DL_HL"}, + {"QUAT_TDM_RX_7", NULL, "QUAT_TDM_RX_7_DL_HL"}, {"QUIN_TDM_TX_0_UL_HL", NULL, "QUIN_TDM_TX_0"}, {"QUIN_TDM_TX_1_UL_HL", NULL, "QUIN_TDM_TX_1"}, {"QUIN_TDM_TX_2_UL_HL", NULL, "QUIN_TDM_TX_2"}, @@ -23103,6 +23116,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Port Mixer"}, + {"QUAT_TDM_RX_7 Port Mixer", "QUAT_TDM_TX_7", "QUAT_TDM_TX_7"}, + {"QUAT_TDM_RX_7", NULL, "QUAT_TDM_RX_7 Port Mixer"}, + {"QUIN_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"QUIN_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"QUIN_TDM_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, @@ -23524,6 +23540,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "QUAT_TDM_RX_1"}, {"BE_OUT", NULL, "QUAT_TDM_RX_2"}, {"BE_OUT", NULL, "QUAT_TDM_RX_3"}, + {"BE_OUT", NULL, "QUAT_TDM_RX_7"}, {"BE_OUT", NULL, "QUIN_TDM_RX_0"}, {"BE_OUT", NULL, "QUIN_TDM_RX_1"}, {"BE_OUT", NULL, "QUIN_TDM_RX_2"}, @@ -23608,6 +23625,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_TX_1", NULL, "BE_IN"}, {"QUAT_TDM_TX_2", NULL, "BE_IN"}, {"QUAT_TDM_TX_3", NULL, "BE_IN"}, + {"QUAT_TDM_TX_7", NULL, "BE_IN"}, {"AFE_LOOPBACK_TX", NULL, "BE_IN"}, {"QUIN_TDM_TX_0", NULL, "BE_IN"}, {"QUIN_TDM_TX_1", NULL, "BE_IN"}, diff --git a/asoc/sa8155.c b/asoc/sa8155.c index fedb793ec895..aef8a2646058 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -253,7 +253,7 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ }, { /* QUAT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 16}, /* TX_0 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ @@ -409,7 +409,7 @@ static unsigned int tdm_rx_slot_offset {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {28,0xFFFF}, }, {/* QUIN TDM */ {0, 4, 0xFFFF},/*STEREO SPKR1*/ @@ -464,7 +464,7 @@ static unsigned int tdm_tx_slot_offset {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {60,0xFFFF}, }, {/* QUIN TDM */ {0, 4, 8, 12, 16, 20, 0xFFFF},/*EC/ANC REF*/ @@ -525,7 +525,7 @@ static unsigned int tdm_rx_slot_offset_custom {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {0, 0xFFFF}, }, {/* QUIN TDM */ {0xFFFF}, /* not used */ @@ -579,7 +579,7 @@ static unsigned int tdm_tx_slot_offset_custom {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {0, 0xFFFF}, }, {/* QUIN TDM */ {0xFFFF}, /* not used */ @@ -4163,6 +4163,14 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_3].sample_rate; break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_7].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_7].sample_rate; + break; case AFE_PORT_ID_QUATERNARY_TDM_TX: channels->min = channels->max = tdm_tx_cfg[TDM_QUAT][TDM_0].channels; @@ -4195,6 +4203,14 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_3].sample_rate; break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_7].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_7].sample_rate; + break; case AFE_PORT_ID_QUINARY_TDM_RX: channels->min = channels->max = tdm_rx_cfg[TDM_QUIN][TDM_0].channels; @@ -4479,6 +4495,11 @@ static int sa8155_tdm_snd_hw_params(struct snd_pcm_substream *substream, slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_3]; break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_7]; + break; case AFE_PORT_ID_QUATERNARY_TDM_TX: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; @@ -4499,6 +4520,11 @@ static int sa8155_tdm_snd_hw_params(struct snd_pcm_substream *substream, slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_3]; break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_7]; + break; case AFE_PORT_ID_QUINARY_TDM_RX: slots = tdm_slot[TDM_QUIN].num; slot_width = tdm_slot[TDM_QUIN].width; @@ -5615,6 +5641,36 @@ static struct snd_soc_dai_link msm_auto_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, + { + .name = "Quaternary TDM RX 7 Hostless", + .stream_name = "Quaternary TDM RX 7 Hostless", + .cpu_dai_name = "QUAT_TDM_RX_7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Quaternary TDM TX 7 Hostless", + .stream_name = "Quaternary TDM TX 7 Hostless", + .cpu_dai_name = "QUAT_TDM_TX_7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, }; static struct snd_soc_dai_link msm_custom_fe_dai_links[] = { @@ -6377,6 +6433,20 @@ static struct snd_soc_dai_link msm_auto_be_dai_links[] = { .ops = &sa8155_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUAT_TDM_RX_7, + .stream_name = "Quaternary TDM7 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36926", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_7, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, { .name = LPASS_BE_QUAT_TDM_TX_1, .stream_name = "Quaternary TDM1 Capture", @@ -6419,6 +6489,20 @@ static struct snd_soc_dai_link msm_auto_be_dai_links[] = { .ops = &sa8155_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUAT_TDM_TX_7, + .stream_name = "Quaternary TDM7 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36927", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_7, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link ext_disp_be_dai_link[] = { -- GitLab From 7f6fc83bc9f122d507b739c4173d3c3c293c136d Mon Sep 17 00:00:00 2001 From: Mangesh Kunchamwar Date: Wed, 30 Jan 2019 16:24:49 +0530 Subject: [PATCH 0944/1645] asoc: codecs: enable dynamic RX & TX supplies for WCD9335 Enable and vote RX and TX supplies dynamically during respective usecases. Change-Id: I671c14b34ce0325e102d94083905329d473d4a78 Signed-off-by: Mangesh Kunchamwar Signed-off-by: Surendar Karka --- asoc/codecs/msm-cdc-supply.c | 32 +++++++++++++-- asoc/codecs/wcd9335.c | 47 ++++++++++++++++++---- asoc/codecs/wcd9335.h | 4 +- asoc/codecs/wcd9xxx-core.c | 75 +++++++++++++++++++++++++++++++---- asoc/codecs/wcd9xxx-utils.c | 10 ++++- include/asoc/core.h | 6 +++ include/asoc/msm-cdc-supply.h | 7 +++- include/asoc/pdata.h | 3 +- 8 files changed, 163 insertions(+), 21 deletions(-) diff --git a/asoc/codecs/msm-cdc-supply.c b/asoc/codecs/msm-cdc-supply.c index 04fd2de13887..220da9dc10f7 100644 --- a/asoc/codecs/msm-cdc-supply.c +++ b/asoc/codecs/msm-cdc-supply.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ #include @@ -357,7 +357,7 @@ EXPORT_SYMBOL(msm_cdc_enable_static_supplies); /* * msm_cdc_init_supplies: - * Initialize codec static supplies with regulator get + * Initialize codec static supplies * * @dev: pointer to codec device * @supplies: pointer to regulator bulk data @@ -370,6 +370,29 @@ int msm_cdc_init_supplies(struct device *dev, struct regulator_bulk_data **supplies, struct cdc_regulator *cdc_vreg, int num_supplies) +{ + return msm_cdc_init_supplies_v2(dev, supplies, cdc_vreg, + num_supplies, false); +} +EXPORT_SYMBOL(msm_cdc_init_supplies); + +/* + * msm_cdc_init_supplies_v2: + * Initialize codec static supplies. + * Initialize codec dynamic supplies based on vote_regulator_on_demand + * + * @dev: pointer to codec device + * @supplies: pointer to regulator bulk data + * @cdc_vreg: pointer to platform regulator data + * @num_supplies: number of supplies + * @vote_regulator_on_demand: initialize codec dynamic supplies at runtime + * + * Return error code if supply init is failed + */ +int msm_cdc_init_supplies_v2(struct device *dev, + struct regulator_bulk_data **supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies, u32 vote_regulator_on_demand) { struct regulator_bulk_data *vsup; int rc; @@ -413,6 +436,9 @@ int msm_cdc_init_supplies(struct device *dev, if (regulator_count_voltages(vsup[i].consumer) < 0) continue; + if (cdc_vreg[i].ondemand && vote_regulator_on_demand) + continue; + rc = regulator_set_voltage(vsup[i].consumer, cdc_vreg[i].min_uV, cdc_vreg[i].max_uV); @@ -437,7 +463,7 @@ int msm_cdc_init_supplies(struct device *dev, err_supply: return rc; } -EXPORT_SYMBOL(msm_cdc_init_supplies); +EXPORT_SYMBOL(msm_cdc_init_supplies_v2); /* * msm_cdc_get_power_supplies: diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index 22bc0e6aba69..40016c2a8fbe 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -151,6 +151,8 @@ MODULE_PARM_DESC(cpe_debug_mode, "boot cpe in debug mode"); static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = { "cdc-vdd-mic-bias", + "cdc-vdd-tx-h", + "cdc-vdd-rx-h" }; enum { @@ -5634,6 +5636,9 @@ static int tasha_codec_enable_on_demand_supply( snd_soc_dapm_to_component(w->dapm); struct tasha_priv *tasha = snd_soc_component_get_drvdata(component); struct on_demand_supply *supply; + struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; + struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent); + const char *supply_name; if (w->shift >= ON_DEMAND_SUPPLIES_MAX) { dev_err(component->dev, "%s: error index > MAX Demand supplies", @@ -5646,6 +5651,7 @@ static int tasha_codec_enable_on_demand_supply( __func__, on_demand_supply_name[w->shift], event); supply = &tasha->on_demand_list[w->shift]; + supply_name = on_demand_supply_name[w->shift]; WARN_ONCE(!supply->supply, "%s isn't defined\n", on_demand_supply_name[w->shift]); if (!supply->supply) { @@ -5656,6 +5662,15 @@ static int tasha_codec_enable_on_demand_supply( switch (event) { case SND_SOC_DAPM_PRE_PMU: + if (pdata->vote_regulator_on_demand) { + ret = wcd9xxx_vote_ondemand_regulator(wcd9xxx, pdata, + supply_name, + true); + if (ret) + dev_err(component->dev, "%s: Failed to vote %s\n", + __func__, + on_demand_supply_name[w->shift]); + } ret = regulator_enable(supply->supply); if (ret) dev_err(component->dev, "%s: Failed to enable %s\n", @@ -5668,6 +5683,15 @@ static int tasha_codec_enable_on_demand_supply( dev_err(component->dev, "%s: Failed to disable %s\n", __func__, on_demand_supply_name[w->shift]); + if (pdata->vote_regulator_on_demand) { + ret = wcd9xxx_vote_ondemand_regulator(wcd9xxx, pdata, + supply_name, + false); + if (ret) + dev_err(component->dev, "%s: Failed to unvote %s\n", + __func__, + on_demand_supply_name[w->shift]); + } break; default: break; @@ -11130,7 +11154,14 @@ static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY(DAPM_LDO_H_STANDALONE, SND_SOC_NOPM, 0, 0, tasha_codec_force_enable_ldo_h, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - + SND_SOC_DAPM_SUPPLY("tx regulator", SND_SOC_NOPM, + ON_DEMAND_TX_SUPPLY, 0, + tasha_codec_enable_on_demand_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("rx regulator", SND_SOC_NOPM, + ON_DEMAND_RX_SUPPLY, 0, + tasha_codec_enable_on_demand_supply, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MUX("ANC0 FB MUX", SND_SOC_NOPM, 0, 0, &anc0_fb_mux), SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux), @@ -13899,12 +13930,14 @@ static int tasha_codec_probe(struct snd_soc_component *component) goto err; } - supply = tasha_codec_find_ondemand_regulator(component, - on_demand_supply_name[ON_DEMAND_MICBIAS]); - if (supply) { - tasha->on_demand_list[ON_DEMAND_MICBIAS].supply = supply; - tasha->on_demand_list[ON_DEMAND_MICBIAS].ondemand_supply_count = - 0; + for (i = ON_DEMAND_MICBIAS; i < ON_DEMAND_SUPPLIES_MAX; i++) { + supply = tasha_codec_find_ondemand_regulator(component, + on_demand_supply_name[i]); + if (supply) { + tasha->on_demand_list[i].supply = supply; + tasha->on_demand_list[i].ondemand_supply_count = + 0; + } } tasha->fw_data = devm_kzalloc(component->dev, diff --git a/asoc/codecs/wcd9335.h b/asoc/codecs/wcd9335.h index 969ac6709370..707f2e96277c 100644 --- a/asoc/codecs/wcd9335.h +++ b/asoc/codecs/wcd9335.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #ifndef WCD9335_H #define WCD9335_H @@ -81,6 +81,8 @@ enum wcd9335_codec_event { enum tasha_on_demand_supply { ON_DEMAND_MICBIAS = 0, + ON_DEMAND_TX_SUPPLY, + ON_DEMAND_RX_SUPPLY, ON_DEMAND_SUPPLIES_MAX, }; diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index b0cb9c72e404..fd2e933520df 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. */ #include @@ -98,6 +98,65 @@ static int wcd9xxx_slim_device_down(struct slim_device *sldev); struct wcd9xxx_i2c wcd9xxx_modules[MAX_WCD9XXX_DEVICE]; +/* + * wcd9xxx_vote_ondemand_regulator: Initialize codec dynamic supplies + * + * @wcd9xxx: Pointer to wcd9xxx structure + * @wcd9xxx_pdata: Pointer to wcd9xxx_pdata structure + * @supply_name: supply parameter to initialize regulator + * @enable: flag to initialize/uninitialize supply + * + * Return error code if supply init is failed + */ +int wcd9xxx_vote_ondemand_regulator(struct wcd9xxx *wcd9xxx, + struct wcd9xxx_pdata *pdata, + const char *supply_name, + bool enable) +{ + int i, rc, index = -EINVAL; + + pr_debug("%s: enable %d\n", __func__, enable); + + for (i = 0; i < wcd9xxx->num_of_supplies; ++i) { + if (pdata->regulator[i].ondemand && + wcd9xxx->supplies[i].supply && + !strcmp(wcd9xxx->supplies[i].supply, supply_name)) { + index = i; + break; + } + } + + if (index < 0) { + pr_err("%s: no matching regulator found\n", __func__); + return -EINVAL; + } + + if (enable) { + rc = regulator_set_voltage(wcd9xxx->supplies[index].consumer, + pdata->regulator[index].min_uV, + pdata->regulator[index].max_uV); + if (rc) { + pr_err("%s: set regulator voltage failed for %s, err:%d\n", + __func__, supply_name, rc); + return rc; + } + rc = regulator_set_load(wcd9xxx->supplies[index].consumer, + pdata->regulator[index].optimum_uA); + if (rc < 0) { + pr_err("%s: set regulator optimum mode failed for %s, err:%d\n", + __func__, supply_name, rc); + return rc; + } + } else { + regulator_set_voltage(wcd9xxx->supplies[index].consumer, 0, + pdata->regulator[index].max_uV); + regulator_set_load(wcd9xxx->supplies[index].consumer, 0); + } + + return 0; +} +EXPORT_SYMBOL(wcd9xxx_vote_ondemand_regulator); + static int wcd9xxx_slim_multi_reg_write(struct wcd9xxx *wcd9xxx, const void *data, size_t count) { @@ -1069,9 +1128,10 @@ static int wcd9xxx_i2c_probe(struct i2c_client *client, wcd9xxx->mclk_rate = pdata->mclk_rate; wcd9xxx->num_of_supplies = pdata->num_supplies; - ret = msm_cdc_init_supplies(wcd9xxx->dev, &wcd9xxx->supplies, - pdata->regulator, - pdata->num_supplies); + ret = msm_cdc_init_supplies_v2(wcd9xxx->dev, &wcd9xxx->supplies, + pdata->regulator, + pdata->num_supplies, + pdata->vote_regulator_on_demand); if (!wcd9xxx->supplies) { dev_err(wcd9xxx->dev, "%s: Cannot init wcd supplies\n", __func__); @@ -1327,9 +1387,10 @@ static int wcd9xxx_slim_probe(struct slim_device *slim) } wcd9xxx->num_of_supplies = pdata->num_supplies; - ret = msm_cdc_init_supplies(&slim->dev, &wcd9xxx->supplies, - pdata->regulator, - pdata->num_supplies); + ret = msm_cdc_init_supplies_v2(&slim->dev, &wcd9xxx->supplies, + pdata->regulator, + pdata->num_supplies, + pdata->vote_regulator_on_demand); if (!wcd9xxx->supplies) { dev_err(wcd9xxx->dev, "%s: Cannot init wcd supplies\n", __func__); diff --git a/asoc/codecs/wcd9xxx-utils.c b/asoc/codecs/wcd9xxx-utils.c index 06968dca4b8f..face7118dfba 100644 --- a/asoc/codecs/wcd9xxx-utils.c +++ b/asoc/codecs/wcd9xxx-utils.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ #include @@ -414,6 +414,14 @@ struct wcd9xxx_pdata *wcd9xxx_populate_dt_data(struct device *dev) pdata->dmic_clk_drv = dmic_clk_drive; + rc = of_property_read_u32(dev->of_node, + "qcom,vote-dynamic-supply-on-demand", + &pdata->vote_regulator_on_demand); + if (rc) + dev_dbg(dev, "%s No entry for %s property in node %s\n", + __func__, "qcom,vote-dynamic-supply-on-demand", + dev->of_node->full_name); + return pdata; err_parse_dt_prop: diff --git a/include/asoc/core.h b/include/asoc/core.h index e4f04138ce8a..c6e544e3997f 100644 --- a/include/asoc/core.h +++ b/include/asoc/core.h @@ -10,6 +10,7 @@ #include #include #include +#include "pdata.h" #define WCD9XXX_MAX_IRQ_REGS 4 #define WCD9XXX_MAX_NUM_IRQS (WCD9XXX_MAX_IRQ_REGS * 8) @@ -394,6 +395,11 @@ int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx, struct wcd9xxx_reg_val *bulk_reg, unsigned int size, bool interface); +int wcd9xxx_vote_ondemand_regulator(struct wcd9xxx *wcd9xxx, + struct wcd9xxx_pdata *pdata, + const char *supply_name, + bool enable); + extern int wcd9xxx_core_res_init( struct wcd9xxx_core_resource *wcd9xxx_core_res, int num_irqs, int num_irq_regs, struct regmap *wcd_regmap); diff --git a/include/asoc/msm-cdc-supply.h b/include/asoc/msm-cdc-supply.h index 9801115c31b9..c6aacf6bd8e3 100644 --- a/include/asoc/msm-cdc-supply.h +++ b/include/asoc/msm-cdc-supply.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2016, 2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2016, 2018-2019 The Linux Foundation. All rights reserved. */ #ifndef __CODEC_POWER_SUPPLY_H__ @@ -45,4 +45,9 @@ extern int msm_cdc_init_supplies(struct device *dev, struct regulator_bulk_data **supplies, struct cdc_regulator *cdc_vreg, int num_supplies); +extern int msm_cdc_init_supplies_v2(struct device *dev, + struct regulator_bulk_data **supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies, + u32 vote_regulator_on_demand); #endif diff --git a/include/asoc/pdata.h b/include/asoc/pdata.h index d24d56aed3c8..41862d4bdc50 100644 --- a/include/asoc/pdata.h +++ b/include/asoc/pdata.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. */ #ifndef __MFD_WCD9XXX_PDATA_H__ @@ -193,6 +193,7 @@ struct wcd9xxx_pdata { u32 ecpp_dmic_sample_rate; u32 dmic_clk_drv; u16 use_pinctrl; + u32 vote_regulator_on_demand; }; #endif -- GitLab From 0b1748df54a79668ec47a0f90264127b1683a4e2 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 15 Mar 2019 13:33:02 +0530 Subject: [PATCH 0945/1645] soc: pinctrl-lpi: Disable core clock only if it is enabled Clock driver throws warning when clock disable is called without enable. Disable core clock only if the respective clock enable is successful to avoid this warning. Change-Id: I489647a444c9be326e5805c353385240c6c6d0fc Signed-off-by: Aditya Bavanari --- soc/pinctrl-lpi.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index 3db22103f285..4eee08623d6c 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -110,6 +110,7 @@ struct lpi_gpio_state { char __iomem *base; struct clk *lpass_core_hw_vote; struct mutex slew_access_lock; + bool core_hw_vote_status; }; static const char *const lpi_gpio_groups[] = { @@ -710,6 +711,7 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) } state->lpass_core_hw_vote = lpass_core_hw_vote; + state->core_hw_vote_status = false; pm_runtime_set_autosuspend_delay(&pdev->dev, LPI_AUTO_SUSPEND_DELAY); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); @@ -760,10 +762,12 @@ int lpi_pinctrl_runtime_resume(struct device *dev) } ret = clk_prepare_enable(state->lpass_core_hw_vote); - if (ret < 0) { + if (ret < 0) dev_err(dev, "%s:lpass core hw island enable failed\n", __func__); - } + else + state->core_hw_vote_status = true; + pm_runtime_set_autosuspend_delay(dev, LPI_AUTO_SUSPEND_DELAY); return 0; } @@ -776,7 +780,11 @@ int lpi_pinctrl_runtime_suspend(struct device *dev) dev_dbg(dev, "%s: Invalid core hw node\n", __func__); return 0; } - clk_disable_unprepare(state->lpass_core_hw_vote); + + if (state->core_hw_vote_status) { + clk_disable_unprepare(state->lpass_core_hw_vote); + state->core_hw_vote_status = false; + } return 0; } -- GitLab From f4a471de1a2502a90a231bda3661e1f6ed3d6c36 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 19 Feb 2019 17:57:12 +0530 Subject: [PATCH 0946/1645] asoc: codecs: Bail out from clock enable routine during SSR When SSR happens, use dev_up flag in codec to bail out from clock enablement routine. During interrupt processing if clock enable fails during SSR, exit isr routine without disabling clock. Change-Id: Ie2b56521daa70790d6ef53a06c7becc2ee8010a4 Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/bolero-cdc.c | 5 ++--- asoc/codecs/bolero/bolero-clk-rsc.c | 2 +- soc/swr-mstr-ctrl.c | 10 ++++++++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index d805126b2254..45e993684db1 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -638,15 +638,14 @@ static void bolero_ssr_disable(struct device *dev, void *data) struct bolero_priv *priv = data; int macro_idx; - if (priv->rsc_clk_cb) - priv->rsc_clk_cb(priv->clk_dev, BOLERO_MACRO_EVT_SSR_DOWN); - bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_PA_OFF_PRE_SSR); regcache_cache_only(priv->regmap, true); mutex_lock(&priv->clk_lock); priv->dev_up = false; mutex_unlock(&priv->clk_lock); + if (priv->rsc_clk_cb) + priv->rsc_clk_cb(priv->clk_dev, BOLERO_MACRO_EVT_SSR_DOWN); /* call ssr event for supported macros */ for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { if (!priv->macro_params[macro_idx].event_handler) diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c index 03befde80a27..617d8320af1e 100644 --- a/asoc/codecs/bolero/bolero-clk-rsc.c +++ b/asoc/codecs/bolero/bolero-clk-rsc.c @@ -401,7 +401,7 @@ int bolero_clk_rsc_request_clock(struct device *dev, } mutex_lock(&priv->rsc_clk_lock); - if (!priv->dev_up) { + if (!priv->dev_up && enable) { dev_err_ratelimited(priv->dev, "%s: SSR is in progress..\n", __func__); ret = -EINVAL; diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index bddf30a4e882..676e3c3cf39a 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -241,8 +241,10 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) mutex_lock(&swrm->clklock); if (enable) { - if (!swrm->dev_up) + if (!swrm->dev_up) { + ret = -ENODEV; goto exit; + } swrm->clk_ref_count++; if (swrm->clk_ref_count == 1) { ret = swrm->clk(swrm->handle, true); @@ -1274,7 +1276,10 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) } mutex_lock(&swrm->reslock); - swrm_clk_request(swrm, true); + if (swrm_clk_request(swrm, true)) { + mutex_unlock(&swrm->reslock); + goto exit; + } mutex_unlock(&swrm->reslock); intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); @@ -1420,6 +1425,7 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) mutex_lock(&swrm->reslock); swrm_clk_request(swrm, false); mutex_unlock(&swrm->reslock); +exit: swrm_unlock_sleep(swrm); return ret; } -- GitLab From 4025a25a2479fc343f6aa413b01a656665656386 Mon Sep 17 00:00:00 2001 From: David Ng Date: Fri, 26 Apr 2019 23:08:34 -0700 Subject: [PATCH 0947/1645] makefile: kona: remove make export instances Replace all kernel make export instances with export of specific variables. Depending on existing build environment, exporting all as environment variables and interaction with existing environment variable expansions can lead to undefined behavior. TODO: This change is restricted to kona flow to narrow impact. All remaining export need to be evaluated and fixed similarly via subsequent changes. Change-Id: I9114b88f7511d1b3f9b496b76fb6da9db97772b8 Signed-off-by: David Ng --- asoc/Kbuild | 1 - asoc/codecs/Kbuild | 1 - asoc/codecs/bolero/Kbuild | 1 - asoc/codecs/wcd938x/Kbuild | 1 - config/konaauto.conf | 76 +++++++++++++++++++------------------- dsp/Kbuild | 1 - dsp/codecs/Kbuild | 1 - ipc/Kbuild | 1 - soc/Kbuild | 1 - 9 files changed, 38 insertions(+), 46 deletions(-) diff --git a/asoc/Kbuild b/asoc/Kbuild index 2b0696b05e58..5ff12c61c14a 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -31,7 +31,6 @@ ifeq ($(KERNEL_BUILD), 0) endif ifeq ($(CONFIG_ARCH_KONA), y) include $(AUDIO_ROOT)/config/konaauto.conf - export INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h endif ifeq ($(CONFIG_ARCH_LITO), y) diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 1d7142addba8..df8657845f0d 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -31,7 +31,6 @@ ifeq ($(KERNEL_BUILD), 0) endif ifeq ($(CONFIG_ARCH_KONA), y) include $(AUDIO_ROOT)/config/konaauto.conf - export INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h endif ifeq ($(CONFIG_ARCH_LITO), y) diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild index 374b52894885..06883a3fbc8b 100644 --- a/asoc/codecs/bolero/Kbuild +++ b/asoc/codecs/bolero/Kbuild @@ -28,7 +28,6 @@ ifeq ($(KERNEL_BUILD), 0) endif ifeq ($(CONFIG_ARCH_KONA), y) include $(AUDIO_ROOT)/config/konaauto.conf - export INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h endif ifeq ($(CONFIG_ARCH_LITO), y) diff --git a/asoc/codecs/wcd938x/Kbuild b/asoc/codecs/wcd938x/Kbuild index e301bd5dfb01..3dfe142bcfc2 100644 --- a/asoc/codecs/wcd938x/Kbuild +++ b/asoc/codecs/wcd938x/Kbuild @@ -16,7 +16,6 @@ endif ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_KONA), y) include $(AUDIO_ROOT)/config/konaauto.conf - export INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h endif ifeq ($(CONFIG_ARCH_LITO), y) diff --git a/config/konaauto.conf b/config/konaauto.conf index 7b03dea339bf..03e054150385 100644 --- a/config/konaauto.conf +++ b/config/konaauto.conf @@ -1,38 +1,38 @@ -CONFIG_PINCTRL_LPI=m -CONFIG_PINCTRL_WCD=m -CONFIG_AUDIO_EXT_CLK=m -CONFIG_SND_SOC_WCD9XXX_V2=m -CONFIG_SND_SOC_WCD_MBHC=m -CONFIG_SND_SOC_WSA881X=m -CONFIG_WCD9XXX_CODEC_CORE_V2=m -CONFIG_MSM_CDC_PINCTRL=m -CONFIG_MSM_QDSP6V2_CODECS=m -CONFIG_MSM_ULTRASOUND=m -CONFIG_MSM_QDSP6_APRV2_RPMSG=m -CONFIG_MSM_ADSP_LOADER=m -CONFIG_REGMAP_SWR=m -CONFIG_MSM_QDSP6_SSR=m -CONFIG_MSM_QDSP6_PDR=m -CONFIG_MSM_QDSP6_NOTIFIER=m -CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m -CONFIG_SOUNDWIRE=m -CONFIG_SOUNDWIRE_MSTR_CTRL=m -CONFIG_SND_SOC_QDSP6V2=m -CONFIG_SND_SOC_WCD_MBHC_ADC=m -CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m -CONFIG_QTI_PP=m -CONFIG_SND_HWDEP_ROUTING=m -CONFIG_SND_SOC_MSM_STUB=m -CONFIG_MSM_AVTIMER=m -CONFIG_SND_SOC_BOLERO=m -CONFIG_WSA_MACRO=m -CONFIG_VA_MACRO=m -CONFIG_RX_MACRO=m -CONFIG_TX_MACRO=m -CONFIG_SND_SOC_WCD_IRQ=m -CONFIG_SND_SOC_WCD938X=m -CONFIG_SND_SOC_WCD938X_SLAVE=m -CONFIG_SND_SOC_KONA=m -CONFIG_SND_EVENT=m -CONFIG_VOICE_MHI=m +export CONFIG_PINCTRL_LPI=m +export CONFIG_PINCTRL_WCD=m +export CONFIG_AUDIO_EXT_CLK=m +export CONFIG_SND_SOC_WCD9XXX_V2=m +export CONFIG_SND_SOC_WCD_MBHC=m +export CONFIG_SND_SOC_WSA881X=m +export CONFIG_WCD9XXX_CODEC_CORE_V2=m +export CONFIG_MSM_CDC_PINCTRL=m +export CONFIG_MSM_QDSP6V2_CODECS=m +export CONFIG_MSM_ULTRASOUND=m +export CONFIG_MSM_QDSP6_APRV2_RPMSG=m +export CONFIG_MSM_ADSP_LOADER=m +export CONFIG_REGMAP_SWR=m +export CONFIG_MSM_QDSP6_SSR=m +export CONFIG_MSM_QDSP6_PDR=m +export CONFIG_MSM_QDSP6_NOTIFIER=m +export CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m +export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +export CONFIG_SOUNDWIRE=m +export CONFIG_SOUNDWIRE_MSTR_CTRL=m +export CONFIG_SND_SOC_QDSP6V2=m +export CONFIG_SND_SOC_WCD_MBHC_ADC=m +export CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m +export CONFIG_QTI_PP=m +export CONFIG_SND_HWDEP_ROUTING=m +export CONFIG_SND_SOC_MSM_STUB=m +export CONFIG_MSM_AVTIMER=m +export CONFIG_SND_SOC_BOLERO=m +export CONFIG_WSA_MACRO=m +export CONFIG_VA_MACRO=m +export CONFIG_RX_MACRO=m +export CONFIG_TX_MACRO=m +export CONFIG_SND_SOC_WCD_IRQ=m +export CONFIG_SND_SOC_WCD938X=m +export CONFIG_SND_SOC_WCD938X_SLAVE=m +export CONFIG_SND_SOC_KONA=m +export CONFIG_SND_EVENT=m +export CONFIG_VOICE_MHI=m diff --git a/dsp/Kbuild b/dsp/Kbuild index cf9de150f494..086924f5557c 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -26,7 +26,6 @@ ifeq ($(KERNEL_BUILD), 0) endif ifeq ($(CONFIG_ARCH_KONA), y) include $(AUDIO_ROOT)/config/konaauto.conf - export INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h endif ifeq ($(CONFIG_ARCH_LITO), y) diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index b4be4852ab40..d78675f54f98 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -26,7 +26,6 @@ ifeq ($(KERNEL_BUILD), 0) endif ifeq ($(CONFIG_ARCH_KONA), y) include $(AUDIO_ROOT)/config/konaauto.conf - export INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h endif ifeq ($(CONFIG_ARCH_LITO), y) diff --git a/ipc/Kbuild b/ipc/Kbuild index 2da5fbd317f4..fb0974e6a4b1 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -27,7 +27,6 @@ ifeq ($(KERNEL_BUILD), 0) endif ifeq ($(CONFIG_ARCH_KONA), y) include $(AUDIO_ROOT)/config/konaauto.conf - export INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h endif ifeq ($(CONFIG_ARCH_LITO), y) diff --git a/soc/Kbuild b/soc/Kbuild index f5f5c8b347aa..a1944a15fdec 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -21,7 +21,6 @@ ifeq ($(KERNEL_BUILD), 0) endif ifeq ($(CONFIG_ARCH_KONA), y) include $(AUDIO_ROOT)/config/konaauto.conf - export INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h endif ifeq ($(CONFIG_ARCH_LITO), y) -- GitLab From eb1d6887b1a5cd9d95d6bab9c63adc94081d879c Mon Sep 17 00:00:00 2001 From: Arun Mirpuri Date: Wed, 27 Feb 2019 19:20:49 -0800 Subject: [PATCH 0948/1645] dsp: add incall stereo capture Add support for incall stereo capture for voice uplink and downlink capture Change-Id: Id23448990170b8215f547073608cd6a998d479ae Signed-off-by: Arun Mirpuri --- asoc/msm-pcm-voice-v2.c | 46 ++++++++++++++++++++++++++++++-- dsp/q6voice.c | 59 +++++++++++++++++++++++++++++++++++++---- include/dsp/q6voice.h | 6 ++++- 3 files changed, 103 insertions(+), 8 deletions(-) diff --git a/asoc/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c index e4d34d1bf67f..ea476c153dc5 100644 --- a/asoc/msm-pcm-voice-v2.c +++ b/asoc/msm-pcm-voice-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include @@ -24,6 +24,9 @@ #define DRV_NAME "msm-pcm-voice-v2" +#define NUM_CHANNELS_MONO 1 +#define NUM_CHANNELS_STEREO 2 + static struct msm_voice voice_info[VOICE_SESSION_INDEX_MAX]; static struct snd_pcm_hardware msm_pcm_hardware = { @@ -616,6 +619,38 @@ static int msm_voice_topology_disable_put(struct snd_kcontrol *kcontrol, return ret; } +static int msm_voice_rec_config_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int voc_rec_config_channels = ucontrol->value.integer.value[0]; + + if (voc_rec_config_channels < NUM_CHANNELS_MONO || + voc_rec_config_channels > NUM_CHANNELS_STEREO) { + pr_err("%s: Invalid channel config (%d)\n", __func__, + voc_rec_config_channels); + ret = -EINVAL; + goto done; + } + voc_set_incall_capture_channel_config(voc_rec_config_channels); + +done: + pr_debug("%s: voc_rec_config_channels = %d, ret = %d\n", __func__, + voc_rec_config_channels, ret); + return ret; +} + +static int msm_voice_rec_config_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + ucontrol->value.integer.value[0] = + voc_get_incall_capture_channel_config(); + pr_debug("%s: rec_config_channels = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + static int msm_voice_cvd_version_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -678,6 +713,12 @@ static struct snd_kcontrol_new msm_voice_controls[] = { msm_voice_mbd_put), }; +static struct snd_kcontrol_new msm_voice_rec_config_controls[] = { + SOC_SINGLE_MULTI_EXT("Voc Rec Config", SND_SOC_NOPM, 0, + 2, 0, 1, msm_voice_rec_config_get, + msm_voice_rec_config_put), +}; + static const struct snd_pcm_ops msm_pcm_ops = { .open = msm_pcm_open, .hw_params = msm_pcm_hw_params, @@ -703,7 +744,8 @@ static int msm_pcm_voice_probe(struct snd_soc_component *component) { snd_soc_add_component_controls(component, msm_voice_controls, ARRAY_SIZE(msm_voice_controls)); - + snd_soc_add_component_controls(component, msm_voice_rec_config_controls, + ARRAY_SIZE(msm_voice_rec_config_controls)); return 0; } diff --git a/dsp/q6voice.c b/dsp/q6voice.c index e36e18b52797..131da554b978 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -98,7 +98,8 @@ static void voice_unload_topo_modules(void); static int voice_cvs_stop_playback(struct voice_data *v); static int voice_cvs_start_playback(struct voice_data *v); -static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode); +static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode, + uint32_t port_id); static int voice_cvs_stop_record(struct voice_data *v); static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv); @@ -4411,7 +4412,8 @@ static int voice_setup_vocproc(struct voice_data *v) /* Start in-call recording if this feature is enabled */ if (v->rec_info.rec_enable) - voice_cvs_start_record(v, v->rec_info.rec_mode); + voice_cvs_start_record(v, v->rec_info.rec_mode, + v->rec_info.port_id); if (v->dtmf_rx_detect_en) voice_send_dtmf_rx_detection_cmd(v, v->dtmf_rx_detect_en); @@ -5056,7 +5058,8 @@ static int voice_destroy_vocproc(struct voice_data *v) if (v->rec_info.rec_enable) { voice_cvs_start_record( &common.voice[VOC_PATH_PASSIVE], - v->rec_info.rec_mode); + v->rec_info.rec_mode, + v->rec_info.port_id); common.srvcc_rec_flag = true; pr_debug("%s: switch recording, srvcc_rec_flag %d\n", @@ -5565,7 +5568,8 @@ static int voice_send_vol_step_cmd(struct voice_data *v) return 0; } -static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode) +static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode, + uint32_t port_id) { int ret = 0; void *apr_cvs; @@ -5616,6 +5620,18 @@ static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode) VSS_IRECORD_TAP_POINT_STREAM_END; cvs_start_record.rec_mode.tx_tap_point = VSS_IRECORD_TAP_POINT_STREAM_END; + if (common.rec_channel_count == + NUM_CHANNELS_STEREO) { + /* + * if channel count is not stereo, + * then default port_id and mode + * (mono) will be used + */ + cvs_start_record.rec_mode.mode = + VSS_IRECORD_MODE_TX_RX_STEREO; + cvs_start_record.rec_mode.port_id = + port_id; + } } else { pr_err("%s: Invalid in-call rec_mode %d\n", __func__, rec_mode); @@ -5774,6 +5790,7 @@ int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id) mutex_lock(&v->lock); rec_mode = v->rec_info.rec_mode; + v->rec_info.port_id = port_id; rec_set = set; if (set) { if ((v->rec_route_state.ul_flag != 0) && @@ -5850,7 +5867,8 @@ int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id) if (cvs_handle != 0) { if (rec_set) - ret = voice_cvs_start_record(v, rec_mode); + ret = voice_cvs_start_record(v, rec_mode, + port_id); else ret = voice_cvs_stop_record(v); } @@ -6148,6 +6166,31 @@ int voc_disable_topology(uint32_t session_id, uint32_t disable) } EXPORT_SYMBOL(voc_disable_topology); +/** + * voc_set_incall_capture_channel_config - + * command to set channel count for record + * + * @channel_count: number of channels + * + */ +void voc_set_incall_capture_channel_config(int channel_count) +{ + common.rec_channel_count = channel_count; +} +EXPORT_SYMBOL(voc_set_incall_capture_channel_config); + +/** + * voc_get_incall_capture_channel_config - + * command to get channel count for record + * + * Returns number of channels configured for record + */ +int voc_get_incall_capture_channel_config(void) +{ + return common.rec_channel_count; +} +EXPORT_SYMBOL(voc_get_incall_capture_channel_config); + static int voice_set_packet_exchange_mode_and_config(uint32_t session_id, uint32_t mode) { @@ -9907,6 +9950,12 @@ int __init voice_init(void) /* Initialize Per-Vocoder Calibration flag */ common.is_per_vocoder_cal_enabled = false; + /* + * Initialize in call record channel config + * to mono + */ + common.rec_channel_count = NUM_CHANNELS_MONO; + mutex_init(&common.common_lock); common.uevent_data = kzalloc(sizeof(*(common.uevent_data)), GFP_KERNEL); diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index 1e6212491840..06f4dfe8901d 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #ifndef __QDSP6VOICE_H__ #define __QDSP6VOICE_H__ @@ -1768,6 +1768,7 @@ struct incall_rec_info { uint32_t rec_enable; uint32_t rec_mode; uint32_t recording; + uint32_t port_id; }; struct incall_music_info { @@ -1946,6 +1947,7 @@ struct common_data { bool sidetone_enable; bool mic_break_enable; struct audio_uevent_data *uevent_data; + int32_t rec_channel_count; }; struct voice_session_itr { @@ -2079,6 +2081,8 @@ int voc_disable_topology(uint32_t session_id, uint32_t disable); int voc_set_device_config(uint32_t session_id, uint8_t path_dir, struct media_format_info *finfo); uint32_t voice_get_topology(uint32_t topology_idx); +void voc_set_incall_capture_channel_config(int channel_count); +int voc_get_incall_capture_channel_config(void); int voice_set_topology_specific_info(struct voice_data *v, uint32_t topology_idx); int voc_set_sound_focus(struct sound_focus_param sound_focus_param); -- GitLab From 82b30ba7c49776013a1de4d56f1fe206e9a2dd50 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 17 Apr 2019 12:43:54 +0530 Subject: [PATCH 0949/1645] ASoC: Add dailink for lito btfm support As lito uses cherokee for btfm support which uses slimbus. Add respective dailink for wcn btfm support for lito. Also rename sm8250-port-config to kona-port-config. Change-Id: I86d771b5df76a4541b8bf17174c1181d9d94bb52 Signed-off-by: Vatsal Bucha --- ...m8250-port-config.h => kona-port-config.h} | 6 +- asoc/kona.c | 147 +++++++++++++++++- 2 files changed, 148 insertions(+), 5 deletions(-) rename asoc/{sm8250-port-config.h => kona-port-config.h} (95%) diff --git a/asoc/sm8250-port-config.h b/asoc/kona-port-config.h similarity index 95% rename from asoc/sm8250-port-config.h rename to asoc/kona-port-config.h index 503d514ba6fa..0f7379175302 100644 --- a/asoc/sm8250-port-config.h +++ b/asoc/kona-port-config.h @@ -3,8 +3,8 @@ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ -#ifndef _SM8250_PORT_CONFIG -#define _SM8250_PORT_CONFIG +#ifndef _KONA_PORT_CONFIG +#define _KONA_PORT_CONFIG #include @@ -57,4 +57,4 @@ static struct swr_mstr_port_map sm_port_map[] = { {WSA_MACRO, SWR_UC0, wsa_frame_params_default}, }; -#endif /* _SM8250_PORT_CONFIG */ +#endif /* _KONA_PORT_CONFIG */ diff --git a/asoc/kona.c b/asoc/kona.c index 574c652464cd..50a25b17ffe3 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -35,7 +35,7 @@ #include "codecs/bolero/bolero-cdc.h" #include #include "codecs/bolero/wsa-macro.h" -#include "sm8250-port-config.h" +#include "kona-port-config.h" #define DRV_NAME "kona-asoc-snd" #define __CHIPSET__ "KONA " @@ -73,6 +73,7 @@ #define WSA8810_NAME_2 "wsa881x.20170212" #define WCN_CDC_SLIM_RX_CH_MAX 2 #define WCN_CDC_SLIM_TX_CH_MAX 2 +#define WCN_CDC_SLIM_TX_CH_MAX_LITO 3 enum { TDM_0 = 0, @@ -137,6 +138,7 @@ enum { }; enum { SLIM_TX_7 = 0, + SLIM_TX_8, SLIM_TX_MAX, }; @@ -191,6 +193,7 @@ static struct dev_config slim_rx_cfg[] = { static struct dev_config slim_tx_cfg[] = { [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, }; /* Default configuration of external display BE */ @@ -3632,6 +3635,12 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, slim_tx_cfg[SLIM_TX_7].channels; break; + case MSM_BACKEND_DAI_SLIMBUS_8_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_8].channels; + break; + case MSM_BACKEND_DAI_AFE_LOOPBACK_TX: param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, afe_loopback_tx_cfg[idx].bit_format); @@ -3991,6 +4000,41 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) mutex_unlock(&mi2s_intf_conf[index].lock); } +static int msm_wcn_hw_params_lito(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX_LITO]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + int ret = 0; + + dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret) { + dev_err(rtd->dev, + "%s: failed to get BTFM codec chan map\n, err:%d\n", + __func__, ret); + goto err; + } + + dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) BE id %d\n", + __func__, tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); + if (ret) + dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + +err: + return ret; +} + static int msm_wcn_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -4047,6 +4091,10 @@ static struct snd_soc_ops msm_wcn_ops = { .hw_params = msm_wcn_hw_params, }; +static struct snd_soc_ops msm_wcn_ops_lito = { + .hw_params = msm_wcn_hw_params_lito, +}; + static int msm_dmic_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -4155,6 +4203,16 @@ static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) tx_ch, ARRAY_SIZE(rx_ch), rx_ch); } +static int msm_wcn_init_lito(struct snd_soc_pcm_runtime *rtd) +{ + unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; + unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX_LITO] = {159, 160, 161}; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); +} + static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) { int ret = -EINVAL; @@ -4897,6 +4955,22 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA17, }, + {/* hw:x,38 */ + .name = "SLIMBUS_8 Hostless", + .stream_name = "SLIMBUS_8 Hostless", + .cpu_dai_name = "SLIMBUS8_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, }; static struct snd_soc_dai_link msm_common_be_dai_links[] = { @@ -5141,6 +5215,58 @@ static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { }, }; +static struct snd_soc_dai_link msm_wcn_btfm_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_7_RX, + .stream_name = "Slimbus7 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16398", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + /* BT codec driver determines capabilities based on + * dai name, bt codecdai name should always contains + * supported usecase information + */ + .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .init = &msm_wcn_init_lito, + .ops = &msm_wcn_ops_lito, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_7_TX, + .stream_name = "Slimbus7 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16399", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_bt_sco_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_wcn_ops_lito, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_8_TX, + .stream_name = "Slimbus8 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16401", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_fm_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_8_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_wcn_ops_lito, + .ignore_suspend = 1, + }, +}; + static struct snd_soc_dai_link ext_disp_be_dai_link[] = { /* DISP PORT BACK END DAI Link */ { @@ -5566,7 +5692,8 @@ static struct snd_soc_dai_link msm_kona_dai_links[ ARRAY_SIZE(msm_va_cdc_dma_be_dai_links) + ARRAY_SIZE(ext_disp_be_dai_link) + ARRAY_SIZE(msm_wcn_be_dai_links) + - ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link)]; + ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link) + + ARRAY_SIZE(msm_wcn_btfm_be_dai_links)]; static int msm_populate_dai_link_component_of_node( struct snd_soc_card *card) @@ -5769,6 +5896,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) u32 mi2s_audio_intf = 0; u32 auxpcm_audio_intf = 0; u32 val = 0; + u32 wcn_btfm_intf = 0; const struct of_device_id *match; match = of_match_node(kona_asoc_machine_of_match, dev->of_node); @@ -5881,6 +6009,21 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) total_links += ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link); } + + rc = of_property_read_u32(dev->of_node, "qcom,wcn-btfm", + &wcn_btfm_intf); + if (rc) { + dev_dbg(dev, "%s: No DT match wcn btfm interface\n", + __func__); + } else { + if (wcn_btfm_intf) { + memcpy(msm_kona_dai_links + total_links, + msm_wcn_btfm_be_dai_links, + sizeof(msm_wcn_btfm_be_dai_links)); + total_links += + ARRAY_SIZE(msm_wcn_btfm_be_dai_links); + } + } dailink = msm_kona_dai_links; } else if(!strcmp(match->data, "stub_codec")) { card = &snd_soc_card_stub_msm; -- GitLab From 2054b690a909d01dec8f054210cacd88fe665ffe Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Fri, 1 Feb 2019 18:01:12 +0530 Subject: [PATCH 0950/1645] dsp: adm: Add support for port specific channel map Add multi channel map support per afe port. Change-Id: Ib032d1c81d918417f516131f11c500e4f6668b39 Signed-off-by: Rohit kumar Signed-off-by: Meng Wang --- dsp/q6adm.c | 80 ++++++++++++++++++++++++++++++++---------- include/dsp/q6adm-v2.h | 2 ++ 2 files changed, 64 insertions(+), 18 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 8848b2290c4d..8c8b61497d51 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -128,6 +128,8 @@ static struct adm_multi_ch_map multi_ch_maps[2] = { } }; +static struct adm_multi_ch_map port_channel_map[AFE_MAX_PORTS]; + static int adm_get_parameters[MAX_COPPS_PER_PORT * ADM_GET_PARAMETER_LENGTH]; static int adm_module_topo_list[MAX_COPPS_PER_PORT * ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH]; @@ -146,7 +148,8 @@ void msm_dts_srs_release_lock(void) static int adm_arrange_mch_map_v8( struct adm_device_endpoint_payload *ep_payload, int path, - int channel_mode); + int channel_mode, + int port_idx); /** * adm_validate_and_get_port_index - @@ -578,7 +581,8 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, index += ch_mixer->output_channel; } else { ep_params.dev_num_channel = ch_mixer->output_channel; - adm_arrange_mch_map_v8(&ep_params, path_type, ep_params.dev_num_channel); + adm_arrange_mch_map_v8(&ep_params, path_type, + ep_params.dev_num_channel, port_idx); for (i = 0; i < ch_mixer->output_channel; i++) adm_pspd_params[index++] = ep_params.dev_channel_mapping[i]; } @@ -589,7 +593,8 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, index += ch_mixer->input_channel; } else { ep_params.dev_num_channel = ch_mixer->input_channels[channel_index]; - adm_arrange_mch_map_v8(&ep_params, path_type, ep_params.dev_num_channel); + adm_arrange_mch_map_v8(&ep_params, path_type, + ep_params.dev_num_channel, port_idx); for (i = 0; i < ch_mixer->input_channels[channel_index]; i++) adm_pspd_params[index++] = ep_params.dev_channel_mapping[i]; } @@ -1302,6 +1307,31 @@ int adm_get_multi_ch_map(char *channel_map, int path) } EXPORT_SYMBOL(adm_get_multi_ch_map); +/** + * adm_set_port_multi_ch_map - + * Update port specific channel map info + * + * @channel_map: pointer with channel map info + * @port_id: port for which chmap is set + */ +void adm_set_port_multi_ch_map(char *channel_map, int port_id) +{ + int port_idx; + + port_id = q6audio_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + + if (port_idx < 0) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + return; + } + + memcpy(port_channel_map[port_idx].channel_mapping, channel_map, + PCM_FORMAT_MAX_NUM_CHANNEL_V8); + port_channel_map[port_idx].set_channel_map = true; +} +EXPORT_SYMBOL(adm_set_port_multi_ch_map); + static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload, u32 payload_size) { @@ -2380,7 +2410,7 @@ int adm_connect_afe_port(int mode, int session_id, int port_id) EXPORT_SYMBOL(adm_connect_afe_port); int adm_arrange_mch_map(struct adm_cmd_device_open_v5 *open, int path, - int channel_mode) + int channel_mode, int port_idx) { int rc = 0, idx; @@ -2398,10 +2428,18 @@ int adm_arrange_mch_map(struct adm_cmd_device_open_v5 *open, int path, default: goto non_mch_path; }; - if ((open->dev_num_channel > 2) && multi_ch_maps[idx].set_channel_map) { - memcpy(open->dev_channel_mapping, - multi_ch_maps[idx].channel_mapping, - PCM_FORMAT_MAX_NUM_CHANNEL); + + if ((open->dev_num_channel > 2) && + (port_channel_map[port_idx].set_channel_map || + multi_ch_maps[idx].set_channel_map)) { + if (port_channel_map[port_idx].set_channel_map) + memcpy(open->dev_channel_mapping, + port_channel_map[port_idx].channel_mapping, + PCM_FORMAT_MAX_NUM_CHANNEL); + else + memcpy(open->dev_channel_mapping, + multi_ch_maps[idx].channel_mapping, + PCM_FORMAT_MAX_NUM_CHANNEL); } else { if (channel_mode == 1) { open->dev_channel_mapping[0] = PCM_CHANNEL_FC; @@ -2515,8 +2553,7 @@ int adm_arrange_mch_ep2_map(struct adm_cmd_device_open_v6 *open_v6, static int adm_arrange_mch_map_v8( struct adm_device_endpoint_payload *ep_payload, - int path, - int channel_mode) + int path, int channel_mode, int port_idx) { int rc = 0, idx; @@ -2535,10 +2572,16 @@ static int adm_arrange_mch_map_v8( }; if ((ep_payload->dev_num_channel > 2) && - multi_ch_maps[idx].set_channel_map) { - memcpy(ep_payload->dev_channel_mapping, - multi_ch_maps[idx].channel_mapping, - PCM_FORMAT_MAX_NUM_CHANNEL_V8); + (port_channel_map[port_idx].set_channel_map || + multi_ch_maps[idx].set_channel_map)) { + if (port_channel_map[port_idx].set_channel_map) + memcpy(ep_payload->dev_channel_mapping, + port_channel_map[port_idx].channel_mapping, + PCM_FORMAT_MAX_NUM_CHANNEL_V8); + else + memcpy(ep_payload->dev_channel_mapping, + multi_ch_maps[idx].channel_mapping, + PCM_FORMAT_MAX_NUM_CHANNEL_V8); } else { if (channel_mode == 1) { ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FC; @@ -3052,7 +3095,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, ep1_payload.bit_width = bit_width; ep1_payload.sample_rate = rate; ret = adm_arrange_mch_map_v8(&ep1_payload, path, - channel_mode); + channel_mode, port_idx); if (ret) return ret; @@ -3165,8 +3208,8 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, (rate != ULL_SUPPORTED_SAMPLE_RATE)); open.sample_rate = rate; - ret = adm_arrange_mch_map(&open, path, channel_mode); - + ret = adm_arrange_mch_map(&open, path, channel_mode, + port_idx); if (ret) return ret; @@ -3314,7 +3357,7 @@ void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate) atomic_read(&this_adm.copp.channels[port_idx][copp_idx]); rc = adm_arrange_mch_map(&open, ADM_PATH_PLAYBACK, - mfc_cfg.num_channels); + mfc_cfg.num_channels, port_idx); if (rc < 0) { pr_err("%s: unable to get channal map\n", __func__); goto fail_cmd; @@ -3671,6 +3714,7 @@ int adm_close(int port_id, int perf_mode, int copp_idx) return -EINVAL; } + port_channel_map[port_idx].set_channel_map = false; if (this_adm.copp.adm_delay[port_idx][copp_idx] && perf_mode == LEGACY_PCM_MODE) { atomic_set(&this_adm.copp.adm_delay_stat[port_idx][copp_idx], diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 70dc2d094833..a48082b75cce 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -145,6 +145,8 @@ int adm_set_multi_ch_map(char *channel_map, int path); int adm_get_multi_ch_map(char *channel_map, int path); +void adm_set_port_multi_ch_map(char *channel_map, int port_id); + int adm_validate_and_get_port_index(int port_id); int adm_get_default_copp_idx(int port_id); -- GitLab From 63ffaa76d5443bf3c30a101dce44ce121554dd6a Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Fri, 1 Feb 2019 18:05:33 +0530 Subject: [PATCH 0951/1645] ASoC: Add mixer control to configure port specific channel map Add mixer control to configure multi channel map for each backend separately. Change-Id: Ie114fa38ee5ce47841cda4cd7f31349905f5c2c7 Signed-off-by: Rohit kumar --- asoc/msm-pcm-routing-v2.c | 30 ++++++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 7 ++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index d5bad0fd6661..758215b86e5a 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -24531,6 +24531,33 @@ static const struct snd_kcontrol_new aptx_dec_license_controls[] = { msm_aptx_dec_license_control_put), }; +static int msm_routing_put_port_chmap_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + uint8_t channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8]; + uint32_t be_idx = ucontrol->value.integer.value[0]; + int i; + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) { + channel_map[i] = (char)(ucontrol->value.integer.value[i + 1]); + if (channel_map[i] > PCM_MAX_CHMAP_ID) { + pr_err("%s: Invalid channel map %d\n", + __func__, channel_map[i]); + return -EINVAL; + } + } + adm_set_port_multi_ch_map(channel_map, msm_bedais[be_idx].port_id); + + return 0; +} + +static const struct snd_kcontrol_new port_multi_channel_map_mixer_controls[] = { + SOC_SINGLE_MULTI_EXT("Backend Device Channel Map", SND_SOC_NOPM, 0, + MSM_BACKEND_DAI_MAX, 0, + PCM_FORMAT_MAX_NUM_CHANNEL_V8 + 1, NULL, + msm_routing_put_port_chmap_mixer), +}; + static int msm_routing_be_dai_name_table_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -24769,6 +24796,9 @@ static int msm_routing_probe(struct snd_soc_component *component) snd_soc_add_component_controls( component, msm_routing_feature_support_mixer_controls, ARRAY_SIZE(msm_routing_feature_support_mixer_controls)); + snd_soc_add_component_controls(component, + port_multi_channel_map_mixer_controls, + ARRAY_SIZE(port_multi_channel_map_mixer_controls)); return 0; } diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index e7c132a69587..2167350b34cf 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -5569,12 +5569,17 @@ struct asm_softvolume_params { /* Left side direct channel. */ #define PCM_CHANNEL_LSD 33 -/* Right side direct channel. */ +/* Right side direct channel. Update PCM_MAX_CHMAP_ID when + * this list is extended. + */ #define PCM_CHANNEL_RSD 34 /* Mark unused channel. */ #define PCM_CHANNEL_UNUSED 47 +/* Max valid channel map index */ +#define PCM_MAX_CHMAP_ID PCM_CHANNEL_RSD + #define PCM_FORMAT_MAX_NUM_CHANNEL 8 #define PCM_FORMAT_MAX_CHANNELS_9 9 -- GitLab From f682acd01db5e5e95e584947c49892caa58f9f01 Mon Sep 17 00:00:00 2001 From: Dhananjay Kumar Date: Fri, 1 Mar 2019 17:07:10 +0530 Subject: [PATCH 0952/1645] asoc: update channels and channel maps usage in channel mixer Update channel mixer controls to use active channel maps. Update channel maps and channel mixer control to validate channels and frontend ids being used. Change-Id: Id5a8d9d0f262fbf64dcfeb67a8b2195fb0d126fa Signed-off-by: Dhananjay Kumar --- asoc/msm-compress-q6-v2.c | 32 +++++++---------- asoc/msm-pcm-q6-v2.c | 72 ++++++++++++++++----------------------- 2 files changed, 42 insertions(+), 62 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index a7b9ff24ca8d..458842b851c8 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -3741,7 +3741,7 @@ static int msm_compr_channel_map_put(struct snd_kcontrol *kcontrol, pr_debug("%s: fe_id- %llu\n", __func__, fe_id); - if (fe_id >= MSM_FRONTEND_DAI_MAX) { + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { pr_err("%s Received out of bounds fe_id %llu\n", __func__, fe_id); rc = -EINVAL; @@ -3783,7 +3783,7 @@ static int msm_compr_channel_map_get(struct snd_kcontrol *kcontrol, int rc = 0, i; pr_debug("%s: fe_id- %llu\n", __func__, fe_id); - if (fe_id >= MSM_FRONTEND_DAI_MAX) { + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { pr_err("%s: Received out of bounds fe_id %llu\n", __func__, fe_id); rc = -EINVAL; @@ -4729,6 +4729,16 @@ static int msm_compr_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, chmixer_pspd->output_channel = ucontrol->value.integer.value[3]; chmixer_pspd->port_idx = ucontrol->value.integer.value[4]; + if (chmixer_pspd->input_channel <= 0 || + chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8 || + chmixer_pspd->output_channel <= 0 || + chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: Invalid channels, in %d, out %d\n", + __func__, chmixer_pspd->input_channel, + chmixer_pspd->output_channel); + return -EINVAL; + } + if (chmixer_pspd->enable) { if (session_type == SESSION_TYPE_RX && !chmixer_pspd->override_in_ch_map) { @@ -4737,11 +4747,6 @@ static int msm_compr_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, chmixer_pspd->in_ch_map[i] = pdata->ch_map[fe_id]->channel_map[i]; } else { - if (chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { - pr_err("%s: Invalid channel count %d\n", - __func__, chmixer_pspd->input_channel); - return -EINVAL; - } q6asm_map_channels(asm_ch_map, chmixer_pspd->input_channel, false); for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) @@ -4756,11 +4761,6 @@ static int msm_compr_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, chmixer_pspd->out_ch_map[i] = pdata->ch_map[fe_id]->channel_map[i]; } else { - if (chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { - pr_err("%s: Invalid channel count %d\n", - __func__, chmixer_pspd->output_channel); - return -EINVAL; - } q6asm_map_channels(asm_ch_map, chmixer_pspd->output_channel, false); for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) @@ -4782,13 +4782,8 @@ static int msm_compr_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, cstream = pdata->cstream[fe_id]; if (chmixer_pspd->enable && cstream && cstream->runtime) { prtd = cstream->runtime->private_data; - if (!prtd) { - pr_err("%s invalid prtd\n", __func__); - ret = -EINVAL; - goto done; - } - if (prtd->audio_client) { + if (prtd && prtd->audio_client) { stream_id = prtd->audio_client->session; be_id = chmixer_pspd->port_idx; ret = msm_pcm_routing_set_channel_mixer_runtime(be_id, @@ -4801,7 +4796,6 @@ static int msm_compr_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, if (reset_override_in_ch_map) chmixer_pspd->override_in_ch_map = false; -done: return ret; } diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index b010010c831c..322bf661e171 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1934,20 +1934,24 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, chmixer_pspd->output_channel = ucontrol->value.integer.value[3]; chmixer_pspd->port_idx = ucontrol->value.integer.value[4]; - if (chmixer_pspd->enable) { + if (chmixer_pspd->input_channel <= 0 || + chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8 || + chmixer_pspd->output_channel <= 0 || + chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { + pr_err("%s: Invalid channels, in %d, out %d\n", + __func__, chmixer_pspd->input_channel, + chmixer_pspd->output_channel); + return -EINVAL; + } + + prtd = substream->runtime ? substream->runtime->private_data : NULL; + if (chmixer_pspd->enable && prtd) { if (session_type == SESSION_TYPE_RX && !chmixer_pspd->override_in_ch_map) { - if (pdata->ch_map[fe_id] && - pdata->ch_map[fe_id]->set_ch_map) { + if (prtd->set_channel_map) { for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) - chmixer_pspd->in_ch_map[i] = - pdata->ch_map[fe_id]->channel_map[i]; + chmixer_pspd->in_ch_map[i] = prtd->channel_map[i]; } else { - if (chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { - pr_err("%s: Invalid channel count %d\n", - __func__, chmixer_pspd->input_channel); - return -EINVAL; - } q6asm_map_channels(asm_ch_map, chmixer_pspd->input_channel, false); for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) @@ -1957,22 +1961,14 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, reset_override_in_ch_map = true; } else if (session_type == SESSION_TYPE_TX && !chmixer_pspd->override_out_ch_map) { - if (pdata->ch_map[fe_id] && - pdata->ch_map[fe_id]->set_ch_map) { - for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) - chmixer_pspd->out_ch_map[i] = - pdata->ch_map[fe_id]->channel_map[i]; - } else { - if (chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { - pr_err("%s: Invalid channel count %d\n", - __func__, chmixer_pspd->output_channel); - return -EINVAL; - } - q6asm_map_channels(asm_ch_map, - chmixer_pspd->output_channel, false); - for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) - chmixer_pspd->out_ch_map[i] = asm_ch_map[i]; - } + /* + * Channel map set in prtd is for plyback only, + * hence always use default for capture path. + */ + q6asm_map_channels(asm_ch_map, + chmixer_pspd->output_channel, false); + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) + chmixer_pspd->out_ch_map[i] = asm_ch_map[i]; chmixer_pspd->override_out_ch_map = true; reset_override_out_ch_map = true; } @@ -1986,22 +1982,13 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, session_type, chmixer_pspd); - if (chmixer_pspd->enable && substream->runtime) { - prtd = substream->runtime->private_data; - if (!prtd) { - pr_err("%s find invalid prtd fail\n", __func__); - ret = -EINVAL; - goto done; - } - - if (prtd->audio_client) { - stream_id = prtd->audio_client->session; - be_id = chmixer_pspd->port_idx; - msm_pcm_routing_set_channel_mixer_runtime(be_id, - stream_id, - session_type, - chmixer_pspd); - } + if (chmixer_pspd->enable && prtd && prtd->audio_client) { + stream_id = prtd->audio_client->session; + be_id = chmixer_pspd->port_idx; + msm_pcm_routing_set_channel_mixer_runtime(be_id, + stream_id, + session_type, + chmixer_pspd); } if (reset_override_out_ch_map) @@ -2009,7 +1996,6 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, if (reset_override_in_ch_map) chmixer_pspd->override_in_ch_map = false; -done: return ret; } -- GitLab From 79c90759481b30c23173e67d3d461c6135388b6b Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 23 Apr 2019 06:09:52 +0530 Subject: [PATCH 0953/1645] soundwire: Suppress errors due to unsupported slave functions Suppress the errors from the soundwire master runtime suspend and runtime resume, if the soundwire slave devices does not implement the functionality, that avoids pm runtime calling the runtime functions. Change-Id: I513a37f37e349a0c435295056df8625f284e13e6 Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index bddf30a4e882..17fc1c67cfa8 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2293,7 +2293,12 @@ static int swrm_runtime_resume(struct device *dev) enable_bank_switch(swrm, 0, SWR_ROW_50, SWR_MIN_COL); list_for_each_entry(swr_dev, &mstr->devices, dev_list) { ret = swr_device_up(swr_dev); - if (ret) { + if (ret == -ENODEV) { + dev_dbg(dev, + "%s slave device up not implemented\n", + __func__); + ret = 0; + } else if (ret) { dev_err(dev, "%s: failed to wakeup swr dev %d\n", __func__, swr_dev->dev_num); @@ -2358,7 +2363,12 @@ static int swrm_runtime_suspend(struct device *dev) swr_master_write(swrm, SWRM_COMP_CFG_ADDR, 0x00); list_for_each_entry(swr_dev, &mstr->devices, dev_list) { ret = swr_device_down(swr_dev); - if (ret) { + if (ret == -ENODEV) { + dev_dbg_ratelimited(dev, + "%s slave device down not implemented\n", + __func__); + ret = 0; + } else if (ret) { dev_err(dev, "%s: failed to shutdown swr dev %d\n", __func__, swr_dev->dev_num); -- GitLab From 9aca5b1f7a6aaad2ca4a7dbebfeef04ecd6ffbe2 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 1 May 2019 10:47:43 -0700 Subject: [PATCH 0954/1645] asoc: codecs: bolero: Add checks before accessing allocated pointer Add null checks to regmap allocation and kalloc failure cases. Change-Id: I81c35672e43db671b4626fb47d706919b6a3e7f6 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/bolero-clk-rsc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c index 03befde80a27..0e6faf012282 100644 --- a/asoc/codecs/bolero/bolero-clk-rsc.c +++ b/asoc/codecs/bolero/bolero-clk-rsc.c @@ -326,6 +326,10 @@ void bolero_clk_rsc_fs_gen_request(struct device *dev, bool enable) return; } regmap = dev_get_regmap(priv->dev->parent, NULL); + if (!regmap) { + pr_err("%s: regmap is null\n", __func__); + return; + } if (enable) { if (priv->reg_seq_en_cnt++ == 0) { for (i = 0; i < (priv->num_fs_reg * 2); i += 2) { @@ -495,6 +499,10 @@ static int bolero_clk_rsc_probe(struct platform_device *pdev) } clk_name_array = devm_kzalloc(&pdev->dev, clk_cnt * sizeof(char *), GFP_KERNEL); + if (!clk_name_array) { + ret = -ENOMEM; + goto err; + } ret = of_property_read_string_array(pdev->dev.of_node, "clock-names", clk_name_array, clk_cnt); -- GitLab From 09d510c6991556fdb556786566b4c497942a3b60 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 1 May 2019 15:31:52 -0700 Subject: [PATCH 0955/1645] asoc: codecs: wcd938x: Add boundary checks before accessing array Add null checks before pointer access and array boundary checks in tx mode function. Change-Id: I8c8b086b4aed4185b1d1aee68cc9e7c42da6ae27 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/wcd938x.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index ca20bc42dd6b..6241cf201a20 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1655,13 +1655,20 @@ static int wcd938x_tx_mode_get(struct snd_kcontrol *kcontrol, snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); - struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); - u32 path = 0; + struct wcd938x_priv *wcd938x = NULL; + int path = 0; - if (!widget || !widget->name || !wcd938x || !component) + if (!component) + return -EINVAL; + + wcd938x = snd_soc_component_get_drvdata(component); + + if (!widget || !widget->name || !wcd938x) return -EINVAL; path = wcd938x_tx_path_get(widget->name); + if (path < 0 || path >= TX_ADC_MAX) + return -EINVAL; ucontrol->value.integer.value[0] = wcd938x->tx_mode[path]; @@ -1675,14 +1682,22 @@ static int wcd938x_tx_mode_put(struct snd_kcontrol *kcontrol, snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); - struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + struct wcd938x_priv *wcd938x = NULL; u32 mode_val; - u32 path = 0; + int path = 0; - if (!widget || !widget->name || !wcd938x || !component) + if (!component) + return -EINVAL; + + wcd938x = snd_soc_component_get_drvdata(component); + + if (!widget || !widget->name || !wcd938x) return -EINVAL; path = wcd938x_tx_path_get(widget->name); + if (path < 0 || path >= TX_ADC_MAX) + return -EINVAL; + mode_val = ucontrol->value.enumerated.item[0]; dev_dbg(component->dev, "%s: mode: %d\n", __func__, mode_val); -- GitLab From cf0c734e84b7dcf995ddc0b08d9b1b57edc86a7c Mon Sep 17 00:00:00 2001 From: Bruce Levy Date: Thu, 2 May 2019 11:17:44 -0700 Subject: [PATCH 0956/1645] Revert "Revert "dsp: voice_mhi: use modified mhi sync/put api"" This reverts commit 952f3d7864cf9ac7eb23e9ad4374742ffe89adc2. This revert of a revert is needed for supporting PCIE changes. Change-Id: Ib12e4114355b15c52225ff000ed59fb1889aab4d --- dsp/voice_mhi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dsp/voice_mhi.c b/dsp/voice_mhi.c index 87572efa7e76..69942b24807c 100644 --- a/dsp/voice_mhi.c +++ b/dsp/voice_mhi.c @@ -228,7 +228,8 @@ int voice_mhi_start(void) goto done; } if (voice_mhi_lcl.vote_count == 0) { - ret = mhi_device_get_sync(voice_mhi_lcl.mhi_dev); + ret = mhi_device_get_sync(voice_mhi_lcl.mhi_dev, + MHI_VOTE_DEVICE); if (ret) { pr_err("%s: mhi_device_get_sync failed\n", __func__); @@ -269,7 +270,7 @@ int voice_mhi_end(void) } if (voice_mhi_lcl.vote_count == 1) - mhi_device_put(voice_mhi_lcl.mhi_dev); + mhi_device_put(voice_mhi_lcl.mhi_dev, MHI_VOTE_DEVICE); voice_mhi_lcl.vote_count--; } mutex_unlock(&voice_mhi_lcl.mutex); -- GitLab From 035c50b0bd5dcaac6a5f2da4dc91e360636c57c1 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 2 May 2019 13:35:01 -0700 Subject: [PATCH 0957/1645] soundwire: return error if vote for LPASS HW Core fails Before proceeding with handling soundwire interrupt check return value of vote for LPASS HW core and handle error scenarios. Change-Id: I0f19a5ddb0af82f33a8d004d008eda9baa40c036 Signed-off-by: Karthikeyan Mani --- soc/swr-mstr-ctrl.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index bddf30a4e882..bb3449467263 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1441,8 +1441,15 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) } mutex_lock(&swrm->reslock); - if (swrm->lpass_core_hw_vote) - clk_prepare_enable(swrm->lpass_core_hw_vote); + if (swrm->lpass_core_hw_vote) { + ret = clk_prepare_enable(swrm->lpass_core_hw_vote); + if (ret < 0) { + dev_err(dev, "%s:lpass core hw enable failed\n", + __func__); + ret = IRQ_NONE; + goto exit; + } + } swrm_clk_request(swrm, true); mutex_unlock(&swrm->reslock); @@ -1612,6 +1619,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) swrm_clk_request(swrm, false); if (swrm->lpass_core_hw_vote) clk_disable_unprepare(swrm->lpass_core_hw_vote); +exit: mutex_unlock(&swrm->reslock); swrm_unlock_sleep(swrm); return ret; -- GitLab From 3d61b368d7108b1687fd28445785b7d253fea9e7 Mon Sep 17 00:00:00 2001 From: Dhananjay Kumar Date: Fri, 1 Mar 2019 15:47:56 +0530 Subject: [PATCH 0958/1645] dsp: adm: add check for mfc channel count Add check for mfc channel count before issuing mfc media format command. Change-Id: I0541d6651ecfcc90562ec0d9a632d039e34658cf Signed-off-by: Dhananjay Kumar --- dsp/q6adm.c | 5 +++++ include/dsp/apr_audio-v2.h | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 8c8b61497d51..345123ffaa94 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2797,6 +2797,11 @@ static int adm_copp_set_ec_ref_mfc_cfg(int port_id, int copp_idx, __func__, port_id, copp_idx, sample_rate, bps, in_channels, out_channels); + if (out_channels <= 0 || out_channels > AUDPROC_MFC_OUT_CHANNELS_MAX) { + pr_err("%s: unsupported out channels=%d\n", __func__, out_channels); + return -EINVAL; + } + /* 1. Update Media Format */ param_hdr.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; param_hdr.param_size = sizeof(mfc_cfg); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index e7c132a69587..8bff49968d00 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -874,11 +874,14 @@ struct adm_cmd_set_pp_params_v5 { */ } __packed; +/* Maximum number of channels supported by MFC media fmt params */ +#define AUDPROC_MFC_OUT_CHANNELS_MAX 8 + struct audproc_mfc_param_media_fmt { uint32_t sampling_rate; uint16_t bits_per_sample; uint16_t num_channels; - uint16_t channel_type[8]; + uint16_t channel_type[AUDPROC_MFC_OUT_CHANNELS_MAX]; } __packed; struct audproc_volume_ctrl_master_gain { -- GitLab From 3bbd2ee907722d3077488ee402cf64f80d043538 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 30 Jan 2019 18:48:56 -0800 Subject: [PATCH 0959/1645] dsp: add senary MI2S and TDM port IDs Add MI2S/TDM AFE senary port IDs for Kona target. Change-Id: I8dafa4516c31040aad0bca30cfdc9acbdf460bf1 Signed-off-by: Karthikeyan Mani --- dsp/q6afe.c | 59 +++++++++++++++++++++ dsp/q6audio-v2.c | 102 +++++++++++++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 44 +++++++++++++++- include/dsp/q6afe-v2.h | 42 ++++++++++----- 4 files changed, 234 insertions(+), 13 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 4855c6a343e8..864159e1e2b1 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -911,6 +911,8 @@ int afe_sizeof_cfg_cmd(u16 port_id) case AFE_PORT_ID_QUATERNARY_MI2S_TX: case AFE_PORT_ID_QUINARY_MI2S_RX: case AFE_PORT_ID_QUINARY_MI2S_TX: + case AFE_PORT_ID_SENARY_MI2S_RX: + case AFE_PORT_ID_SENARY_MI2S_TX: ret_size = SIZEOF_CFG_CMD(afe_param_id_i2s_cfg); break; case HDMI_RX: @@ -4469,6 +4471,7 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, case AFE_PORT_ID_QUATERNARY_MI2S_TX: case AFE_PORT_ID_QUINARY_MI2S_RX: case AFE_PORT_ID_QUINARY_MI2S_TX: + case AFE_PORT_ID_SENARY_MI2S_RX: case AFE_PORT_ID_SENARY_MI2S_TX: case AFE_PORT_ID_INT0_MI2S_RX: case AFE_PORT_ID_INT0_MI2S_TX: @@ -4797,6 +4800,8 @@ int afe_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_QUINARY_MI2S_RX; case AFE_PORT_ID_QUINARY_MI2S_TX: return IDX_AFE_PORT_ID_QUINARY_MI2S_TX; + case AFE_PORT_ID_SENARY_MI2S_RX: + return IDX_AFE_PORT_ID_SENARY_MI2S_RX; case AFE_PORT_ID_SENARY_MI2S_TX: return IDX_AFE_PORT_ID_SENARY_MI2S_TX; case AFE_PORT_ID_PRIMARY_TDM_RX: @@ -4959,6 +4964,38 @@ int afe_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_QUINARY_TDM_RX_7; case AFE_PORT_ID_QUINARY_TDM_TX_7: return IDX_AFE_PORT_ID_QUINARY_TDM_TX_7; + case AFE_PORT_ID_SENARY_TDM_RX: + return IDX_AFE_PORT_ID_SENARY_TDM_RX_0; + case AFE_PORT_ID_SENARY_TDM_TX: + return IDX_AFE_PORT_ID_SENARY_TDM_TX_0; + case AFE_PORT_ID_SENARY_TDM_RX_1: + return IDX_AFE_PORT_ID_SENARY_TDM_RX_1; + case AFE_PORT_ID_SENARY_TDM_TX_1: + return IDX_AFE_PORT_ID_SENARY_TDM_TX_1; + case AFE_PORT_ID_SENARY_TDM_RX_2: + return IDX_AFE_PORT_ID_SENARY_TDM_RX_2; + case AFE_PORT_ID_SENARY_TDM_TX_2: + return IDX_AFE_PORT_ID_SENARY_TDM_TX_2; + case AFE_PORT_ID_SENARY_TDM_RX_3: + return IDX_AFE_PORT_ID_SENARY_TDM_RX_3; + case AFE_PORT_ID_SENARY_TDM_TX_3: + return IDX_AFE_PORT_ID_SENARY_TDM_TX_3; + case AFE_PORT_ID_SENARY_TDM_RX_4: + return IDX_AFE_PORT_ID_SENARY_TDM_RX_4; + case AFE_PORT_ID_SENARY_TDM_TX_4: + return IDX_AFE_PORT_ID_SENARY_TDM_TX_4; + case AFE_PORT_ID_SENARY_TDM_RX_5: + return IDX_AFE_PORT_ID_SENARY_TDM_RX_5; + case AFE_PORT_ID_SENARY_TDM_TX_5: + return IDX_AFE_PORT_ID_SENARY_TDM_TX_5; + case AFE_PORT_ID_SENARY_TDM_RX_6: + return IDX_AFE_PORT_ID_SENARY_TDM_RX_6; + case AFE_PORT_ID_SENARY_TDM_TX_6: + return IDX_AFE_PORT_ID_SENARY_TDM_TX_6; + case AFE_PORT_ID_SENARY_TDM_RX_7: + return IDX_AFE_PORT_ID_SENARY_TDM_RX_7; + case AFE_PORT_ID_SENARY_TDM_TX_7: + return IDX_AFE_PORT_ID_SENARY_TDM_TX_7; case AFE_PORT_ID_INT0_MI2S_RX: return IDX_AFE_PORT_ID_INT0_MI2S_RX; case AFE_PORT_ID_INT0_MI2S_TX: @@ -5146,6 +5183,7 @@ int afe_open(u16 port_id, case MI2S_TX: case AFE_PORT_ID_QUINARY_MI2S_RX: case AFE_PORT_ID_QUINARY_MI2S_TX: + case AFE_PORT_ID_SENARY_MI2S_RX: case AFE_PORT_ID_SENARY_MI2S_TX: cfg_type = AFE_PARAM_ID_I2S_CONFIG; break; @@ -5515,6 +5553,8 @@ int afe_port_group_set_param(u16 group_id, case AFE_GROUP_DEVICE_ID_QUATERNARY_TDM_TX: case AFE_GROUP_DEVICE_ID_QUINARY_TDM_RX: case AFE_GROUP_DEVICE_ID_QUINARY_TDM_TX: + case AFE_GROUP_DEVICE_ID_SENARY_TDM_RX: + case AFE_GROUP_DEVICE_ID_SENARY_TDM_TX: cfg_type = AFE_PARAM_ID_GROUP_DEVICE_TDM_CONFIG; break; default: @@ -7066,6 +7106,8 @@ int afe_validate_port(u16 port_id) case AFE_PORT_ID_QUATERNARY_PCM_TX: case AFE_PORT_ID_QUINARY_PCM_RX: case AFE_PORT_ID_QUINARY_PCM_TX: + case AFE_PORT_ID_SENARY_PCM_RX: + case AFE_PORT_ID_SENARY_PCM_TX: case SECONDARY_I2S_RX: case SECONDARY_I2S_TX: case MI2S_RX: @@ -7120,6 +7162,7 @@ int afe_validate_port(u16 port_id) case AFE_PORT_ID_TERTIARY_MI2S_TX: case AFE_PORT_ID_QUINARY_MI2S_RX: case AFE_PORT_ID_QUINARY_MI2S_TX: + case AFE_PORT_ID_SENARY_MI2S_RX: case AFE_PORT_ID_SENARY_MI2S_TX: case AFE_PORT_ID_PRIMARY_TDM_RX: case AFE_PORT_ID_PRIMARY_TDM_TX: @@ -7201,6 +7244,22 @@ int afe_validate_port(u16 port_id) case AFE_PORT_ID_QUINARY_TDM_TX_6: case AFE_PORT_ID_QUINARY_TDM_RX_7: case AFE_PORT_ID_QUINARY_TDM_TX_7: + case AFE_PORT_ID_SENARY_TDM_RX: + case AFE_PORT_ID_SENARY_TDM_TX: + case AFE_PORT_ID_SENARY_TDM_RX_1: + case AFE_PORT_ID_SENARY_TDM_TX_1: + case AFE_PORT_ID_SENARY_TDM_RX_2: + case AFE_PORT_ID_SENARY_TDM_TX_2: + case AFE_PORT_ID_SENARY_TDM_RX_3: + case AFE_PORT_ID_SENARY_TDM_TX_3: + case AFE_PORT_ID_SENARY_TDM_RX_4: + case AFE_PORT_ID_SENARY_TDM_TX_4: + case AFE_PORT_ID_SENARY_TDM_RX_5: + case AFE_PORT_ID_SENARY_TDM_TX_5: + case AFE_PORT_ID_SENARY_TDM_RX_6: + case AFE_PORT_ID_SENARY_TDM_TX_6: + case AFE_PORT_ID_SENARY_TDM_RX_7: + case AFE_PORT_ID_SENARY_TDM_TX_7: case AFE_PORT_ID_INT0_MI2S_RX: case AFE_PORT_ID_INT1_MI2S_RX: case AFE_PORT_ID_INT2_MI2S_RX: diff --git a/dsp/q6audio-v2.c b/dsp/q6audio-v2.c index 822fbb53b18b..8de60605f1be 100644 --- a/dsp/q6audio-v2.c +++ b/dsp/q6audio-v2.c @@ -269,6 +269,40 @@ int q6audio_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_QUINARY_TDM_RX_7; case AFE_PORT_ID_QUINARY_TDM_TX_7: return IDX_AFE_PORT_ID_QUINARY_TDM_TX_7; + case AFE_PORT_ID_SENARY_TDM_RX: + return IDX_AFE_PORT_ID_SENARY_TDM_RX_0; + case AFE_PORT_ID_SENARY_TDM_TX: + return IDX_AFE_PORT_ID_SENARY_TDM_TX_0; + case AFE_PORT_ID_SENARY_TDM_RX_1: + return IDX_AFE_PORT_ID_SENARY_TDM_RX_1; + case AFE_PORT_ID_SENARY_TDM_TX_1: + return IDX_AFE_PORT_ID_SENARY_TDM_TX_1; + case AFE_PORT_ID_SENARY_TDM_RX_2: + return IDX_AFE_PORT_ID_SENARY_TDM_RX_2; + case AFE_PORT_ID_SENARY_TDM_TX_2: + return IDX_AFE_PORT_ID_SENARY_TDM_TX_2; + case AFE_PORT_ID_SENARY_TDM_RX_3: + return IDX_AFE_PORT_ID_SENARY_TDM_RX_3; + case AFE_PORT_ID_SENARY_TDM_TX_3: + return IDX_AFE_PORT_ID_SENARY_TDM_TX_3; + case AFE_PORT_ID_SENARY_TDM_RX_4: + return IDX_AFE_PORT_ID_SENARY_TDM_RX_4; + case AFE_PORT_ID_SENARY_TDM_TX_4: + return IDX_AFE_PORT_ID_SENARY_TDM_TX_4; + case AFE_PORT_ID_SENARY_TDM_RX_5: + return IDX_AFE_PORT_ID_SENARY_TDM_RX_5; + case AFE_PORT_ID_SENARY_TDM_TX_5: + return IDX_AFE_PORT_ID_SENARY_TDM_TX_5; + case AFE_PORT_ID_SENARY_TDM_RX_6: + return IDX_AFE_PORT_ID_SENARY_TDM_RX_6; + case AFE_PORT_ID_SENARY_TDM_TX_6: + return IDX_AFE_PORT_ID_SENARY_TDM_TX_6; + case AFE_PORT_ID_SENARY_TDM_RX_7: + return IDX_AFE_PORT_ID_SENARY_TDM_RX_7; + case AFE_PORT_ID_SENARY_TDM_TX_7: + return IDX_AFE_PORT_ID_SENARY_TDM_TX_7; + case AFE_PORT_ID_SENARY_MI2S_RX: + return IDX_AFE_PORT_ID_SENARY_MI2S_RX; case AFE_PORT_ID_SENARY_MI2S_TX: return IDX_AFE_PORT_ID_SENARY_MI2S_TX; case AFE_PORT_ID_USB_RX: @@ -613,6 +647,40 @@ int q6audio_get_port_id(u16 port_id) return AFE_PORT_ID_QUINARY_TDM_RX_7; case AFE_PORT_ID_QUINARY_TDM_TX_7: return AFE_PORT_ID_QUINARY_TDM_TX_7; + case AFE_PORT_ID_SENARY_TDM_RX: + return AFE_PORT_ID_SENARY_TDM_RX; + case AFE_PORT_ID_SENARY_TDM_TX: + return AFE_PORT_ID_SENARY_TDM_TX; + case AFE_PORT_ID_SENARY_TDM_RX_1: + return AFE_PORT_ID_SENARY_TDM_RX_1; + case AFE_PORT_ID_SENARY_TDM_TX_1: + return AFE_PORT_ID_SENARY_TDM_TX_1; + case AFE_PORT_ID_SENARY_TDM_RX_2: + return AFE_PORT_ID_SENARY_TDM_RX_2; + case AFE_PORT_ID_SENARY_TDM_TX_2: + return AFE_PORT_ID_SENARY_TDM_TX_2; + case AFE_PORT_ID_SENARY_TDM_RX_3: + return AFE_PORT_ID_SENARY_TDM_RX_3; + case AFE_PORT_ID_SENARY_TDM_TX_3: + return AFE_PORT_ID_SENARY_TDM_TX_3; + case AFE_PORT_ID_SENARY_TDM_RX_4: + return AFE_PORT_ID_SENARY_TDM_RX_4; + case AFE_PORT_ID_SENARY_TDM_TX_4: + return AFE_PORT_ID_SENARY_TDM_TX_4; + case AFE_PORT_ID_SENARY_TDM_RX_5: + return AFE_PORT_ID_SENARY_TDM_RX_5; + case AFE_PORT_ID_SENARY_TDM_TX_5: + return AFE_PORT_ID_SENARY_TDM_TX_5; + case AFE_PORT_ID_SENARY_TDM_RX_6: + return AFE_PORT_ID_SENARY_TDM_RX_6; + case AFE_PORT_ID_SENARY_TDM_TX_6: + return AFE_PORT_ID_SENARY_TDM_TX_6; + case AFE_PORT_ID_SENARY_TDM_RX_7: + return AFE_PORT_ID_SENARY_TDM_RX_7; + case AFE_PORT_ID_SENARY_TDM_TX_7: + return AFE_PORT_ID_SENARY_TDM_TX_7; + case AFE_PORT_ID_SENARY_MI2S_RX: + return AFE_PORT_ID_SENARY_MI2S_RX; case AFE_PORT_ID_SENARY_MI2S_TX: return AFE_PORT_ID_SENARY_MI2S_TX; case AFE_PORT_ID_USB_RX: @@ -832,6 +900,23 @@ int q6audio_is_digital_pcm_interface(u16 port_id) case AFE_PORT_ID_QUINARY_TDM_TX_6: case AFE_PORT_ID_QUINARY_TDM_RX_7: case AFE_PORT_ID_QUINARY_TDM_TX_7: + case AFE_PORT_ID_SENARY_TDM_RX: + case AFE_PORT_ID_SENARY_TDM_TX: + case AFE_PORT_ID_SENARY_TDM_RX_1: + case AFE_PORT_ID_SENARY_TDM_TX_1: + case AFE_PORT_ID_SENARY_TDM_RX_2: + case AFE_PORT_ID_SENARY_TDM_TX_2: + case AFE_PORT_ID_SENARY_TDM_RX_3: + case AFE_PORT_ID_SENARY_TDM_TX_3: + case AFE_PORT_ID_SENARY_TDM_RX_4: + case AFE_PORT_ID_SENARY_TDM_TX_4: + case AFE_PORT_ID_SENARY_TDM_RX_5: + case AFE_PORT_ID_SENARY_TDM_TX_5: + case AFE_PORT_ID_SENARY_TDM_RX_6: + case AFE_PORT_ID_SENARY_TDM_TX_6: + case AFE_PORT_ID_SENARY_TDM_RX_7: + case AFE_PORT_ID_SENARY_TDM_TX_7: + case AFE_PORT_ID_SENARY_MI2S_RX: case AFE_PORT_ID_SENARY_MI2S_TX: case AFE_PORT_ID_INT0_MI2S_RX: case AFE_PORT_ID_INT0_MI2S_TX: @@ -1043,6 +1128,23 @@ int q6audio_validate_port(u16 port_id) case AFE_PORT_ID_QUINARY_TDM_TX_6: case AFE_PORT_ID_QUINARY_TDM_RX_7: case AFE_PORT_ID_QUINARY_TDM_TX_7: + case AFE_PORT_ID_SENARY_TDM_RX: + case AFE_PORT_ID_SENARY_TDM_TX: + case AFE_PORT_ID_SENARY_TDM_RX_1: + case AFE_PORT_ID_SENARY_TDM_TX_1: + case AFE_PORT_ID_SENARY_TDM_RX_2: + case AFE_PORT_ID_SENARY_TDM_TX_2: + case AFE_PORT_ID_SENARY_TDM_RX_3: + case AFE_PORT_ID_SENARY_TDM_TX_3: + case AFE_PORT_ID_SENARY_TDM_RX_4: + case AFE_PORT_ID_SENARY_TDM_TX_4: + case AFE_PORT_ID_SENARY_TDM_RX_5: + case AFE_PORT_ID_SENARY_TDM_TX_5: + case AFE_PORT_ID_SENARY_TDM_RX_6: + case AFE_PORT_ID_SENARY_TDM_TX_6: + case AFE_PORT_ID_SENARY_TDM_RX_7: + case AFE_PORT_ID_SENARY_TDM_TX_7: + case AFE_PORT_ID_SENARY_MI2S_RX: case AFE_PORT_ID_SENARY_MI2S_TX: case AFE_PORT_ID_USB_RX: case AFE_PORT_ID_USB_TX: diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index e7c132a69587..a68de41126d9 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1431,7 +1431,7 @@ struct adm_cmd_connect_afe_port_v5 { /* End of the range of port IDs for TDM devices. */ #define AFE_PORT_ID_TDM_PORT_RANGE_END \ - (AFE_PORT_ID_TDM_PORT_RANGE_START+0x50-1) + (AFE_PORT_ID_TDM_PORT_RANGE_START+0x60-1) /* Size of the range of port IDs for TDM ports. */ #define AFE_PORT_ID_TDM_PORT_RANGE_SIZE \ @@ -1827,6 +1827,40 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_PORT_ID_QUINARY_TDM_TX_7 \ (AFE_PORT_ID_QUINARY_TDM_TX + 0x0E) +#define AFE_PORT_ID_SENARY_TDM_RX \ + (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x50) +#define AFE_PORT_ID_SENARY_TDM_RX_1 \ + (AFE_PORT_ID_SENARY_TDM_RX + 0x02) +#define AFE_PORT_ID_SENARY_TDM_RX_2 \ + (AFE_PORT_ID_SENARY_TDM_RX + 0x04) +#define AFE_PORT_ID_SENARY_TDM_RX_3 \ + (AFE_PORT_ID_SENARY_TDM_RX + 0x06) +#define AFE_PORT_ID_SENARY_TDM_RX_4 \ + (AFE_PORT_ID_SENARY_TDM_RX + 0x08) +#define AFE_PORT_ID_SENARY_TDM_RX_5 \ + (AFE_PORT_ID_SENARY_TDM_RX + 0x0A) +#define AFE_PORT_ID_SENARY_TDM_RX_6 \ + (AFE_PORT_ID_SENARY_TDM_RX + 0x0C) +#define AFE_PORT_ID_SENARY_TDM_RX_7 \ + (AFE_PORT_ID_SENARY_TDM_RX + 0x0E) + +#define AFE_PORT_ID_SENARY_TDM_TX \ + (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x51) +#define AFE_PORT_ID_SENARY_TDM_TX_1 \ + (AFE_PORT_ID_SENARY_TDM_TX + 0x02) +#define AFE_PORT_ID_SENARY_TDM_TX_2 \ + (AFE_PORT_ID_SENARY_TDM_TX + 0x04) +#define AFE_PORT_ID_SENARY_TDM_TX_3 \ + (AFE_PORT_ID_SENARY_TDM_TX + 0x06) +#define AFE_PORT_ID_SENARY_TDM_TX_4 \ + (AFE_PORT_ID_SENARY_TDM_TX + 0x08) +#define AFE_PORT_ID_SENARY_TDM_TX_5 \ + (AFE_PORT_ID_SENARY_TDM_TX + 0x0A) +#define AFE_PORT_ID_SENARY_TDM_TX_6 \ + (AFE_PORT_ID_SENARY_TDM_TX + 0x0C) +#define AFE_PORT_ID_SENARY_TDM_TX_7 \ + (AFE_PORT_ID_SENARY_TDM_TX + 0x0E) + #define AFE_PORT_ID_INVALID 0xFFFF #define AAC_ENC_MODE_AAC_LC 0x02 @@ -11373,6 +11407,10 @@ enum afe_lpass_clk_mode { #define Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT 0x209 /** Clock ID for Quinary TDM OSR */ #define Q6AFE_LPASS_CLK_ID_QUIN_TDM_OSR 0x20A +/** Clock ID for Senary TDM IBIT */ +#define Q6AFE_LPASS_CLK_ID_SEN_TDM_IBIT 0x20B +/** Clock ID for Senary TDM EBIT */ +#define Q6AFE_LPASS_CLK_ID_SEN_TDM_EBIT 0x20C /* Clock ID for MCLK1 */ #define Q6AFE_LPASS_CLK_ID_MCLK_1 0x300 @@ -11765,6 +11803,10 @@ struct afe_group_device_group_cfg { (AFE_PORT_ID_QUINARY_TDM_RX + 0x100) #define AFE_GROUP_DEVICE_ID_QUINARY_TDM_TX \ (AFE_PORT_ID_QUINARY_TDM_TX + 0x100) +#define AFE_GROUP_DEVICE_ID_SENARY_TDM_RX \ + (AFE_PORT_ID_SENARY_TDM_RX + 0x100) +#define AFE_GROUP_DEVICE_ID_SENARY_TDM_TX \ + (AFE_PORT_ID_SENARY_TDM_TX + 0x100) /* ID of the parameter used by #AFE_MODULE_GROUP_DEVICE to configure the * group device. #AFE_SVC_CMD_SET_PARAM can use this parameter ID. diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 1efcb50b5669..c6563a99d89e 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -107,12 +107,13 @@ enum { IDX_PRIMARY_SPDIF_RX, IDX_GLOBAL_CFG, IDX_AUDIO_PORT_ID_I2S_RX, - /* IDX 50->53 */ + /* IDX 50->54 */ IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_SD1, IDX_AFE_PORT_ID_QUINARY_MI2S_RX, IDX_AFE_PORT_ID_QUINARY_MI2S_TX, + IDX_AFE_PORT_ID_SENARY_MI2S_RX, IDX_AFE_PORT_ID_SENARY_MI2S_TX, - /* IDX 54->117 */ + /* IDX 55->118 */ IDX_AFE_PORT_ID_PRIMARY_TDM_RX_0, IDX_AFE_PORT_ID_PRIMARY_TDM_TX_0, IDX_AFE_PORT_ID_PRIMARY_TDM_RX_1, @@ -177,22 +178,22 @@ enum { IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_6, IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_7, IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_7, - /* IDX 118->121 */ + /* IDX 119->122 */ IDX_SLIMBUS_7_RX, IDX_SLIMBUS_7_TX, IDX_SLIMBUS_8_RX, IDX_SLIMBUS_8_TX, - /* IDX 122-> 123 */ + /* IDX 123-> 124 */ IDX_AFE_PORT_ID_USB_RX, IDX_AFE_PORT_ID_USB_TX, - /* IDX 124 */ + /* IDX 125 */ IDX_DISPLAY_PORT_RX, - /* IDX 125-> 128 */ + /* IDX 126-> 129 */ IDX_AFE_PORT_ID_TERTIARY_PCM_RX, IDX_AFE_PORT_ID_TERTIARY_PCM_TX, IDX_AFE_PORT_ID_QUATERNARY_PCM_RX, IDX_AFE_PORT_ID_QUATERNARY_PCM_TX, - /* IDX 129-> 142 */ + /* IDX 130-> 143 */ IDX_AFE_PORT_ID_INT0_MI2S_RX, IDX_AFE_PORT_ID_INT0_MI2S_TX, IDX_AFE_PORT_ID_INT1_MI2S_RX, @@ -207,7 +208,7 @@ enum { IDX_AFE_PORT_ID_INT5_MI2S_TX, IDX_AFE_PORT_ID_INT6_MI2S_RX, IDX_AFE_PORT_ID_INT6_MI2S_TX, - /* IDX 143-> 160 */ + /* IDX 144-> 161 */ IDX_AFE_PORT_ID_QUINARY_PCM_RX, IDX_AFE_PORT_ID_QUINARY_PCM_TX, IDX_AFE_PORT_ID_QUINARY_TDM_RX_0, @@ -226,7 +227,7 @@ enum { IDX_AFE_PORT_ID_QUINARY_TDM_TX_6, IDX_AFE_PORT_ID_QUINARY_TDM_RX_7, IDX_AFE_PORT_ID_QUINARY_TDM_TX_7, - /* IDX 161 to 182 */ + /* IDX 162 to 183 */ IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_0, IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_0, IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_1, @@ -249,17 +250,34 @@ enum { IDX_AFE_PORT_ID_TX_CODEC_DMA_TX_5, IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_6, IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_7, - /* IDX 183 to 185 */ + /* IDX 184 to 186 */ IDX_SECONDARY_SPDIF_RX, IDX_PRIMARY_SPDIF_TX, IDX_SECONDARY_SPDIF_TX, - /* IDX 186 to 187 */ + /* IDX 187 to 188 */ IDX_SLIMBUS_9_RX, IDX_SLIMBUS_9_TX, - /* IDX 188 -> 190 */ + /* IDX 189 -> 191 */ IDX_AFE_PORT_ID_SENARY_PCM_RX, IDX_AFE_PORT_ID_SENARY_PCM_TX, IDX_AFE_LOOPBACK_TX, + /* IDX 192-> 207 */ + IDX_AFE_PORT_ID_SENARY_TDM_RX_0, + IDX_AFE_PORT_ID_SENARY_TDM_TX_0, + IDX_AFE_PORT_ID_SENARY_TDM_RX_1, + IDX_AFE_PORT_ID_SENARY_TDM_TX_1, + IDX_AFE_PORT_ID_SENARY_TDM_RX_2, + IDX_AFE_PORT_ID_SENARY_TDM_TX_2, + IDX_AFE_PORT_ID_SENARY_TDM_RX_3, + IDX_AFE_PORT_ID_SENARY_TDM_TX_3, + IDX_AFE_PORT_ID_SENARY_TDM_RX_4, + IDX_AFE_PORT_ID_SENARY_TDM_TX_4, + IDX_AFE_PORT_ID_SENARY_TDM_RX_5, + IDX_AFE_PORT_ID_SENARY_TDM_TX_5, + IDX_AFE_PORT_ID_SENARY_TDM_RX_6, + IDX_AFE_PORT_ID_SENARY_TDM_TX_6, + IDX_AFE_PORT_ID_SENARY_TDM_RX_7, + IDX_AFE_PORT_ID_SENARY_TDM_TX_7, AFE_MAX_PORTS }; -- GitLab From c37007527e452b5194387781604556b058675338 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 11 Mar 2019 18:33:53 -0700 Subject: [PATCH 0960/1645] asoc: msm: add support for senary interfaces in dai and routing driver Add support for dais and routing for Senary MI2S, AUXPCM and TDM interfaces. Change-Id: Ifa4a9c7163330a18d22d3a5c7d75fe99d189ba49 Signed-off-by: Karthikeyan Mani --- asoc/msm-dai-q6-v2.c | 678 +++- asoc/msm-pcm-routing-v2.c | 7233 ++++++++++++++++++++++++------------- asoc/msm-pcm-routing-v2.h | 32 + 3 files changed, 5515 insertions(+), 2428 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index d4f33c74a948..5cfb145ce856 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -26,6 +26,7 @@ #define MSM_DAI_TERT_AUXPCM_DT_DEV_ID 3 #define MSM_DAI_QUAT_AUXPCM_DT_DEV_ID 4 #define MSM_DAI_QUIN_AUXPCM_DT_DEV_ID 5 +#define MSM_DAI_SEN_AUXPCM_DT_DEV_ID 6 #define MSM_DAI_TWS_CHANNEL_MODE_ONE 1 #define MSM_DAI_TWS_CHANNEL_MODE_TWO 2 @@ -180,6 +181,22 @@ enum { IDX_QUINARY_TDM_TX_5, IDX_QUINARY_TDM_TX_6, IDX_QUINARY_TDM_TX_7, + IDX_SENARY_TDM_RX_0, + IDX_SENARY_TDM_RX_1, + IDX_SENARY_TDM_RX_2, + IDX_SENARY_TDM_RX_3, + IDX_SENARY_TDM_RX_4, + IDX_SENARY_TDM_RX_5, + IDX_SENARY_TDM_RX_6, + IDX_SENARY_TDM_RX_7, + IDX_SENARY_TDM_TX_0, + IDX_SENARY_TDM_TX_1, + IDX_SENARY_TDM_TX_2, + IDX_SENARY_TDM_TX_3, + IDX_SENARY_TDM_TX_4, + IDX_SENARY_TDM_TX_5, + IDX_SENARY_TDM_TX_6, + IDX_SENARY_TDM_TX_7, IDX_TDM_MAX, }; @@ -194,6 +211,8 @@ enum { IDX_GROUP_QUATERNARY_TDM_TX, IDX_GROUP_QUINARY_TDM_RX, IDX_GROUP_QUINARY_TDM_TX, + IDX_GROUP_SENARY_TDM_RX, + IDX_GROUP_SENARY_TDM_TX, IDX_GROUP_TDM_MAX, }; @@ -400,6 +419,10 @@ static int msm_dai_q6_get_tdm_clk_ref(u16 id) case IDX_GROUP_QUINARY_TDM_TX: return atomic_read(&tdm_group_ref[IDX_GROUP_QUINARY_TDM_RX]) + atomic_read(&tdm_group_ref[IDX_GROUP_QUINARY_TDM_TX]); + case IDX_GROUP_SENARY_TDM_RX: + case IDX_GROUP_SENARY_TDM_TX: + return atomic_read(&tdm_group_ref[IDX_GROUP_SENARY_TDM_RX]) + + atomic_read(&tdm_group_ref[IDX_GROUP_SENARY_TDM_TX]); default: return -EINVAL; } } @@ -507,6 +530,26 @@ int msm_dai_q6_get_group_idx(u16 id) case AFE_PORT_ID_QUINARY_TDM_TX_6: case AFE_PORT_ID_QUINARY_TDM_TX_7: return IDX_GROUP_QUINARY_TDM_TX; + case AFE_GROUP_DEVICE_ID_SENARY_TDM_RX: + case AFE_PORT_ID_SENARY_TDM_RX: + case AFE_PORT_ID_SENARY_TDM_RX_1: + case AFE_PORT_ID_SENARY_TDM_RX_2: + case AFE_PORT_ID_SENARY_TDM_RX_3: + case AFE_PORT_ID_SENARY_TDM_RX_4: + case AFE_PORT_ID_SENARY_TDM_RX_5: + case AFE_PORT_ID_SENARY_TDM_RX_6: + case AFE_PORT_ID_SENARY_TDM_RX_7: + return IDX_GROUP_SENARY_TDM_RX; + case AFE_GROUP_DEVICE_ID_SENARY_TDM_TX: + case AFE_PORT_ID_SENARY_TDM_TX: + case AFE_PORT_ID_SENARY_TDM_TX_1: + case AFE_PORT_ID_SENARY_TDM_TX_2: + case AFE_PORT_ID_SENARY_TDM_TX_3: + case AFE_PORT_ID_SENARY_TDM_TX_4: + case AFE_PORT_ID_SENARY_TDM_TX_5: + case AFE_PORT_ID_SENARY_TDM_TX_6: + case AFE_PORT_ID_SENARY_TDM_TX_7: + return IDX_GROUP_SENARY_TDM_TX; default: return -EINVAL; } } @@ -674,6 +717,38 @@ int msm_dai_q6_get_port_idx(u16 id) return IDX_QUINARY_TDM_RX_7; case AFE_PORT_ID_QUINARY_TDM_TX_7: return IDX_QUINARY_TDM_TX_7; + case AFE_PORT_ID_SENARY_TDM_RX: + return IDX_SENARY_TDM_RX_0; + case AFE_PORT_ID_SENARY_TDM_TX: + return IDX_SENARY_TDM_TX_0; + case AFE_PORT_ID_SENARY_TDM_RX_1: + return IDX_SENARY_TDM_RX_1; + case AFE_PORT_ID_SENARY_TDM_TX_1: + return IDX_SENARY_TDM_TX_1; + case AFE_PORT_ID_SENARY_TDM_RX_2: + return IDX_SENARY_TDM_RX_2; + case AFE_PORT_ID_SENARY_TDM_TX_2: + return IDX_SENARY_TDM_TX_2; + case AFE_PORT_ID_SENARY_TDM_RX_3: + return IDX_SENARY_TDM_RX_3; + case AFE_PORT_ID_SENARY_TDM_TX_3: + return IDX_SENARY_TDM_TX_3; + case AFE_PORT_ID_SENARY_TDM_RX_4: + return IDX_SENARY_TDM_RX_4; + case AFE_PORT_ID_SENARY_TDM_TX_4: + return IDX_SENARY_TDM_TX_4; + case AFE_PORT_ID_SENARY_TDM_RX_5: + return IDX_SENARY_TDM_RX_5; + case AFE_PORT_ID_SENARY_TDM_TX_5: + return IDX_SENARY_TDM_TX_5; + case AFE_PORT_ID_SENARY_TDM_RX_6: + return IDX_SENARY_TDM_RX_6; + case AFE_PORT_ID_SENARY_TDM_TX_6: + return IDX_SENARY_TDM_TX_6; + case AFE_PORT_ID_SENARY_TDM_RX_7: + return IDX_SENARY_TDM_RX_7; + case AFE_PORT_ID_SENARY_TDM_TX_7: + return IDX_SENARY_TDM_TX_7; default: return -EINVAL; } } @@ -1061,6 +1136,14 @@ static int msm_dai_q6_auxpcm_prepare(struct snd_pcm_substream *substream, aux_dai_data->clk_set.clk_id = Q6AFE_LPASS_CLK_ID_QUIN_PCM_EBIT; break; + case MSM_DAI_SEN_AUXPCM_DT_DEV_ID: + if (pcm_clk_rate) + aux_dai_data->clk_set.clk_id = + Q6AFE_LPASS_CLK_ID_SEN_PCM_IBIT; + else + aux_dai_data->clk_set.clk_id = + Q6AFE_LPASS_CLK_ID_SEN_PCM_EBIT; + break; default: dev_err(dai->dev, "%s: AUXPCM id: %d not supported\n", __func__, dai->id); @@ -1449,6 +1532,33 @@ static struct snd_soc_dai_driver msm_dai_q6_aux_pcm_dai[] = { .probe = msm_dai_q6_aux_pcm_probe, .remove = msm_dai_q6_dai_auxpcm_remove, }, + { + .playback = { + .stream_name = "Sen AUX PCM Playback", + .aif_name = "SEN_AUX_PCM_RX", + .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_max = 16000, + .rate_min = 8000, + }, + .capture = { + .stream_name = "Sen AUX PCM Capture", + .aif_name = "SEN_AUX_PCM_TX", + .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 1, + .rate_max = 16000, + .rate_min = 8000, + }, + .id = MSM_DAI_SEN_AUXPCM_DT_DEV_ID, + .name = "Sen AUX PCM", + .ops = &msm_dai_q6_auxpcm_ops, + .probe = msm_dai_q6_aux_pcm_probe, + .remove = msm_dai_q6_dai_auxpcm_remove, + }, }; static int msm_dai_q6_spdif_format_put(struct snd_kcontrol *kcontrol, @@ -4240,6 +4350,11 @@ static int msm_auxpcm_dev_probe(struct platform_device *pdev) dai_data->tx_pid = AFE_PORT_ID_QUINARY_PCM_TX; pdev->id = MSM_DAI_QUIN_AUXPCM_DT_DEV_ID; i = 4; + } else if (!strcmp(intf_name, "senary")) { + dai_data->rx_pid = AFE_PORT_ID_SENARY_PCM_RX; + dai_data->tx_pid = AFE_PORT_ID_SENARY_PCM_TX; + pdev->id = MSM_DAI_SEN_AUXPCM_DT_DEV_ID; + i = 5; } else { dev_err(&pdev->dev, "%s: invalid DT intf name %s\n", __func__, intf_name); @@ -4921,6 +5036,9 @@ static int msm_mi2s_get_port_id(u32 mi2s_id, int stream, u16 *port_id) case MSM_QUIN_MI2S: *port_id = AFE_PORT_ID_QUINARY_MI2S_RX; break; + case MSM_SENARY_MI2S: + *port_id = AFE_PORT_ID_SENARY_MI2S_RX; + break; case MSM_INT0_MI2S: *port_id = AFE_PORT_ID_INT0_MI2S_RX; break; @@ -5538,20 +5656,17 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { }, { .playback = { - .stream_name = "Secondary MI2S Playback SD1", - .aif_name = "SEC_MI2S_RX_SD1", + .stream_name = "Senary MI2S Playback", + .aif_name = "SEN_MI2S_RX", .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, .formats = SNDRV_PCM_FMTBIT_S16_LE, .rate_min = 8000, .rate_max = 48000, }, - .id = MSM_SEC_MI2S_SD1, - }, - { .capture = { - .stream_name = "Senary_mi2s Capture", - .aif_name = "SENARY_TX", + .stream_name = "Senary MI2S Capture", + .aif_name = "SENARY_MI2S_TX", .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, .formats = SNDRV_PCM_FMTBIT_S16_LE, @@ -5564,6 +5679,18 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .probe = msm_dai_q6_dai_mi2s_probe, .remove = msm_dai_q6_dai_mi2s_remove, }, + { + .playback = { + .stream_name = "Secondary MI2S Playback SD1", + .aif_name = "SEC_MI2S_RX_SD1", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 48000, + }, + .id = MSM_SEC_MI2S_SD1, + }, { .playback = { .stream_name = "INT0 MI2S Playback", @@ -6540,6 +6667,13 @@ static int msm_dai_q6_tdm_set_clk_param(u32 group_id, else clk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT; break; + case AFE_GROUP_DEVICE_ID_SENARY_TDM_RX: + case AFE_GROUP_DEVICE_ID_SENARY_TDM_TX: + if (mode) + clk_set->clk_id = Q6AFE_LPASS_CLK_ID_SEN_TDM_IBIT; + else + clk_set->clk_id = Q6AFE_LPASS_CLK_ID_SEN_TDM_EBIT; + break; default: return -EINVAL; } @@ -7061,6 +7195,54 @@ static const struct snd_kcontrol_new tdm_config_controls_data_format[] = { SOC_ENUM_EXT("QUIN_TDM_TX_7 Data Format", tdm_config_enum[0], msm_dai_q6_tdm_data_format_get, msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEN_TDM_RX_0 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEN_TDM_RX_1 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEN_TDM_RX_2 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEN_TDM_RX_3 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEN_TDM_RX_4 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEN_TDM_RX_5 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEN_TDM_RX_6 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEN_TDM_RX_7 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEN_TDM_TX_0 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEN_TDM_TX_1 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEN_TDM_TX_2 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEN_TDM_TX_3 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEN_TDM_TX_4 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEN_TDM_TX_5 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEN_TDM_TX_6 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), + SOC_ENUM_EXT("SEN_TDM_TX_7 Data Format", tdm_config_enum[0], + msm_dai_q6_tdm_data_format_get, + msm_dai_q6_tdm_data_format_put), }; static const struct snd_kcontrol_new tdm_config_controls_header_type[] = { @@ -7304,6 +7486,54 @@ static const struct snd_kcontrol_new tdm_config_controls_header_type[] = { SOC_ENUM_EXT("QUIN_TDM_TX_7 Header Type", tdm_config_enum[1], msm_dai_q6_tdm_header_type_get, msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEN_TDM_RX_0 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEN_TDM_RX_1 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEN_TDM_RX_2 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEN_TDM_RX_3 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEN_TDM_RX_4 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEN_TDM_RX_5 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEN_TDM_RX_6 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEN_TDM_RX_7 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEN_TDM_TX_0 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEN_TDM_TX_1 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEN_TDM_TX_2 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEN_TDM_TX_3 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEN_TDM_TX_4 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEN_TDM_TX_5 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEN_TDM_TX_6 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), + SOC_ENUM_EXT("SEN_TDM_TX_7 Header Type", tdm_config_enum[1], + msm_dai_q6_tdm_header_type_get, + msm_dai_q6_tdm_header_type_put), }; static const struct snd_kcontrol_new tdm_config_controls_header[] = { @@ -7627,6 +7857,70 @@ static const struct snd_kcontrol_new tdm_config_controls_header[] = { SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, msm_dai_q6_tdm_header_get, msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEN_TDM_RX_0 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEN_TDM_RX_1 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEN_TDM_RX_2 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEN_TDM_RX_3 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEN_TDM_RX_4 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEN_TDM_RX_5 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEN_TDM_RX_6 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEN_TDM_RX_7 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEN_TDM_TX_0 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEN_TDM_TX_1 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEN_TDM_TX_2 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEN_TDM_TX_3 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEN_TDM_TX_4 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEN_TDM_TX_5 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEN_TDM_TX_6 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), + SOC_SINGLE_MULTI_EXT("SEN_TDM_TX_7 Header", + SND_SOC_NOPM, 0, 0xFFFFFFFF, 0, 8, + msm_dai_q6_tdm_header_get, + msm_dai_q6_tdm_header_put), }; static int msm_dai_q6_tdm_set_clk( @@ -7871,6 +8165,14 @@ static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai, case AFE_PORT_ID_QUINARY_TDM_RX_5: case AFE_PORT_ID_QUINARY_TDM_RX_6: case AFE_PORT_ID_QUINARY_TDM_RX_7: + case AFE_PORT_ID_SENARY_TDM_RX: + case AFE_PORT_ID_SENARY_TDM_RX_1: + case AFE_PORT_ID_SENARY_TDM_RX_2: + case AFE_PORT_ID_SENARY_TDM_RX_3: + case AFE_PORT_ID_SENARY_TDM_RX_4: + case AFE_PORT_ID_SENARY_TDM_RX_5: + case AFE_PORT_ID_SENARY_TDM_RX_6: + case AFE_PORT_ID_SENARY_TDM_RX_7: tdm_group->nslots_per_frame = slots; tdm_group->slot_width = slot_width; tdm_group->slot_mask = rx_mask & cap_mask; @@ -7915,6 +8217,14 @@ static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai, case AFE_PORT_ID_QUINARY_TDM_TX_5: case AFE_PORT_ID_QUINARY_TDM_TX_6: case AFE_PORT_ID_QUINARY_TDM_TX_7: + case AFE_PORT_ID_SENARY_TDM_TX: + case AFE_PORT_ID_SENARY_TDM_TX_1: + case AFE_PORT_ID_SENARY_TDM_TX_2: + case AFE_PORT_ID_SENARY_TDM_TX_3: + case AFE_PORT_ID_SENARY_TDM_TX_4: + case AFE_PORT_ID_SENARY_TDM_TX_5: + case AFE_PORT_ID_SENARY_TDM_TX_6: + case AFE_PORT_ID_SENARY_TDM_TX_7: tdm_group->nslots_per_frame = slots; tdm_group->slot_width = slot_width; tdm_group->slot_mask = tx_mask & cap_mask; @@ -7935,7 +8245,7 @@ static int msm_dai_q6_tdm_set_sysclk(struct snd_soc_dai *dai, dev_get_drvdata(dai->dev); if ((dai->id >= AFE_PORT_ID_PRIMARY_TDM_RX) && - (dai->id <= AFE_PORT_ID_QUINARY_TDM_TX_7)) { + (dai->id <= AFE_PORT_ID_SENARY_TDM_TX_7)) { dai_data->clk_set.clk_freq_in_hz = freq; } else { dev_err(dai->dev, "%s: invalid dai id 0x%x\n", @@ -8002,6 +8312,14 @@ static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai, case AFE_PORT_ID_QUINARY_TDM_RX_5: case AFE_PORT_ID_QUINARY_TDM_RX_6: case AFE_PORT_ID_QUINARY_TDM_RX_7: + case AFE_PORT_ID_SENARY_TDM_RX: + case AFE_PORT_ID_SENARY_TDM_RX_1: + case AFE_PORT_ID_SENARY_TDM_RX_2: + case AFE_PORT_ID_SENARY_TDM_RX_3: + case AFE_PORT_ID_SENARY_TDM_RX_4: + case AFE_PORT_ID_SENARY_TDM_RX_5: + case AFE_PORT_ID_SENARY_TDM_RX_6: + case AFE_PORT_ID_SENARY_TDM_RX_7: if (!rx_slot) { dev_err(dai->dev, "%s: rx slot not found\n", __func__); return -EINVAL; @@ -8060,6 +8378,14 @@ static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai, case AFE_PORT_ID_QUINARY_TDM_TX_5: case AFE_PORT_ID_QUINARY_TDM_TX_6: case AFE_PORT_ID_QUINARY_TDM_TX_7: + case AFE_PORT_ID_SENARY_TDM_TX: + case AFE_PORT_ID_SENARY_TDM_TX_1: + case AFE_PORT_ID_SENARY_TDM_TX_2: + case AFE_PORT_ID_SENARY_TDM_TX_3: + case AFE_PORT_ID_SENARY_TDM_TX_4: + case AFE_PORT_ID_SENARY_TDM_TX_5: + case AFE_PORT_ID_SENARY_TDM_TX_6: + case AFE_PORT_ID_SENARY_TDM_TX_7: if (!tx_slot) { dev_err(dai->dev, "%s: tx slot not found\n", __func__); return -EINVAL; @@ -10117,6 +10443,342 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { .probe = msm_dai_q6_dai_tdm_probe, .remove = msm_dai_q6_dai_tdm_remove, }, + { + .playback = { + .stream_name = "Senary TDM0 Playback", + .aif_name = "SEN_TDM_RX_0", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .name = "SEN_TDM_RX_0", + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SENARY_TDM_RX, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Senary TDM1 Playback", + .aif_name = "SEN_TDM_RX_1", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .name = "SEN_TDM_RX_1", + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SENARY_TDM_RX_1, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Senary TDM2 Playback", + .aif_name = "SEN_TDM_RX_2", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .name = "SEN_TDM_RX_2", + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SENARY_TDM_RX_2, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Senary TDM3 Playback", + .aif_name = "SEN_TDM_RX_3", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .name = "SEN_TDM_RX_3", + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SENARY_TDM_RX_3, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Senary TDM4 Playback", + .aif_name = "SEN_TDM_RX_4", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .name = "SEN_TDM_RX_4", + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SENARY_TDM_RX_4, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Senary TDM5 Playback", + .aif_name = "SEN_TDM_RX_5", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .name = "SEN_TDM_RX_5", + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SENARY_TDM_RX_5, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Senary TDM6 Playback", + .aif_name = "SEN_TDM_RX_6", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .name = "SEN_TDM_RX_6", + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SENARY_TDM_RX_6, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .playback = { + .stream_name = "Senary TDM7 Playback", + .aif_name = "SEN_TDM_RX_7", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .name = "SEN_TDM_RX_7", + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SENARY_TDM_RX_7, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Senary TDM0 Capture", + .aif_name = "SEN_TDM_TX_0", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .name = "SEN_TDM_TX_0", + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SENARY_TDM_TX, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Senary TDM1 Capture", + .aif_name = "SEN_TDM_TX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .name = "SEN_TDM_TX_1", + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SENARY_TDM_TX_1, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Senary TDM2 Capture", + .aif_name = "SEN_TDM_TX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .name = "SEN_TDM_TX_2", + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SENARY_TDM_TX_2, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Senary TDM3 Capture", + .aif_name = "SEN_TDM_TX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .name = "SEN_TDM_TX_3", + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SENARY_TDM_TX_3, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Senary TDM4 Capture", + .aif_name = "SEN_TDM_TX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .name = "SEN_TDM_TX_4", + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SENARY_TDM_TX_4, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Senary TDM5 Capture", + .aif_name = "SEN_TDM_TX_5", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .name = "SEN_TDM_TX_5", + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SENARY_TDM_TX_5, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Senary TDM6 Capture", + .aif_name = "SEN_TDM_TX_6", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .name = "SEN_TDM_TX_6", + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SENARY_TDM_TX_6, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, + { + .capture = { + .stream_name = "Senary TDM7 Capture", + .aif_name = "SEN_TDM_TX_7", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 352800, + }, + .name = "SEN_TDM_TX_7", + .ops = &msm_dai_q6_tdm_ops, + .id = AFE_PORT_ID_SENARY_TDM_TX_7, + .probe = msm_dai_q6_dai_tdm_probe, + .remove = msm_dai_q6_dai_tdm_remove, + }, }; static const struct snd_soc_component_driver msm_q6_tdm_dai_component = { diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index d5bad0fd6661..9692678cc277 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -65,6 +65,7 @@ static int sec_mi2s_switch_enable; static int tert_mi2s_switch_enable; static int quat_mi2s_switch_enable; static int quin_mi2s_switch_enable; +static int sen_mi2s_switch_enable; static int fm_pcmrx_switch_enable; static int usb_switch_enable; static int lsm_port_index; @@ -545,6 +546,38 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_QUIN_TDM_RX_7}, { AFE_PORT_ID_QUINARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_QUIN_TDM_TX_7}, + { AFE_PORT_ID_SENARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_TDM_RX_0}, + { AFE_PORT_ID_SENARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_TDM_TX_0}, + { AFE_PORT_ID_SENARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_TDM_RX_1}, + { AFE_PORT_ID_SENARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_TDM_TX_1}, + { AFE_PORT_ID_SENARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_TDM_RX_2}, + { AFE_PORT_ID_SENARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_TDM_TX_2}, + { AFE_PORT_ID_SENARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_TDM_RX_3}, + { AFE_PORT_ID_SENARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_TDM_TX_3}, + { AFE_PORT_ID_SENARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_TDM_RX_4}, + { AFE_PORT_ID_SENARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_TDM_TX_4}, + { AFE_PORT_ID_SENARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_TDM_RX_5}, + { AFE_PORT_ID_SENARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_TDM_TX_5}, + { AFE_PORT_ID_SENARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_TDM_RX_6}, + { AFE_PORT_ID_SENARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_TDM_TX_6}, + { AFE_PORT_ID_SENARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_TDM_RX_7}, + { AFE_PORT_ID_SENARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEN_TDM_TX_7}, { INT_BT_A2DP_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_INT_BT_A2DP_RX}, { AFE_PORT_ID_USB_RX, 0, {0}, {0}, 0, 0, 0, 0, @@ -2818,6 +2851,36 @@ static int msm_routing_put_quin_mi2s_switch_mixer( return 1; } +static int msm_routing_get_sen_mi2s_switch_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = sen_mi2s_switch_enable; + pr_debug("%s: SEN MI2S Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_put_sen_mi2s_switch_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: SEN MI2S Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + if (ucontrol->value.integer.value[0]) + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, + update); + else + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, + update); + sen_mi2s_switch_enable = ucontrol->value.integer.value[0]; + return 1; +} + static int msm_routing_get_fm_pcmrx_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -3327,6 +3390,10 @@ static const char *const be_name[] = { "QUIN_TDM_RX_2", "QUIN_TDM_TX_2", "QUIN_TDM_RX_3", "QUIN_TDM_TX_3", "QUIN_TDM_RX_4", "QUIN_TDM_TX_4", "QUIN_TDM_RX_5", "QUIN_TDM_TX_5", "QUIN_TDM_RX_6", "QUIN_TDM_TX_6", "QUIN_TDM_RX_7", "QUIN_TDM_TX_7", +"SEN_TDM_RX_0", "SEN_TDM_TX_0", "SEN_TDM_RX_1", "SEN_TDM_TX_1", +"SEN_TDM_RX_2", "SEN_TDM_TX_2", "SEN_TDM_RX_3", "SEN_TDM_TX_3", +"SEN_TDM_RX_4", "SEN_TDM_TX_4", "SEN_TDM_RX_5", "SEN_TDM_TX_5", +"SEN_TDM_RX_6", "SEN_TDM_TX_6", "SEN_TDM_RX_7", "SEN_TDM_TX_7", "INT_BT_A2DP_RX", "USB_RX", "USB_TX", "DISPLAY_PORT_RX", "DISPLAY_PORT_RX1", "TERT_AUXPCM_RX", "TERT_AUXPCM_TX", "QUAT_AUXPCM_RX", "QUAT_AUXPCM_TX", "QUIN_AUXPCM_RX", "QUIN_AUXPCM_TX", "INT0_MI2S_RX", @@ -5322,6 +5389,98 @@ static const struct snd_kcontrol_new quinary_mi2s_rx_mixer_controls[] = { }; +static const struct snd_kcontrol_new senary_mi2s_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + +}; + static const struct snd_kcontrol_new tertiary_mi2s_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_RX, @@ -7759,6 +7918,78 @@ static const struct snd_kcontrol_new quin_auxpcm_rx_mixer_controls[] = { MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; + +static const struct snd_kcontrol_new sen_auxpcm_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_RX_0, @@ -9617,3109 +9848,3668 @@ static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = { msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new mmul1_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul2_mixer_controls[] = { - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, +static const struct snd_kcontrol_new sen_tdm_rx_0_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, +}; + +static const struct snd_kcontrol_new sen_tdm_tx_0_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, +}; + +static const struct snd_kcontrol_new sen_tdm_rx_1_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul3_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, +}; + +static const struct snd_kcontrol_new sen_tdm_rx_2_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, +}; + +static const struct snd_kcontrol_new sen_tdm_rx_3_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul1_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul4_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new mmul5_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), +static const struct snd_kcontrol_new mmul2_mixer_controls[] = { SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new mmul6_mixer_controls[] = { - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), +static const struct snd_kcontrol_new mmul3_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new mmul8_mixer_controls[] = { +static const struct snd_kcontrol_new mmul4_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new mmul16_mixer_controls[] = { +static const struct snd_kcontrol_new mmul5_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new mmul9_mixer_controls[] = { +static const struct snd_kcontrol_new mmul6_mixer_controls[] = { + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new mmul10_mixer_controls[] = { +static const struct snd_kcontrol_new mmul8_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new mmul17_mixer_controls[] = { + +static const struct snd_kcontrol_new mmul16_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul18_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new mmul19_mixer_controls[] = { +static const struct snd_kcontrol_new mmul9_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new mmul20_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, +static const struct snd_kcontrol_new mmul10_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; - -static const struct snd_kcontrol_new mmul21_mixer_controls[] = { - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, +static const struct snd_kcontrol_new mmul17_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new mmul27_mixer_controls[] = { +static const struct snd_kcontrol_new mmul18_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul28_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new mmul29_mixer_controls[] = { +static const struct snd_kcontrol_new mmul19_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new sec_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new slimbus_6_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, +static const struct snd_kcontrol_new mmul20_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul21_mixer_controls[] = { + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul27_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul28_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul29_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new sec_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new slimbus_6_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; @@ -13016,6 +13806,29 @@ static const struct snd_kcontrol_new quin_mi2s_rx_voice_mixer_controls[] = { msm_routing_put_voice_mixer), }; +static const struct snd_kcontrol_new sen_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = { SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, MSM_BACKEND_DAI_AFE_PCM_RX, @@ -13154,6 +13967,26 @@ MSM_BACKEND_DAI_QUIN_AUXPCM_RX, msm_routing_put_voice_mixer), }; +static const struct snd_kcontrol_new sen_aux_pcm_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = { SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, MSM_BACKEND_DAI_HDMI_RX, @@ -13666,6 +14499,9 @@ static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -13759,6 +14595,9 @@ static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -13856,6 +14695,10 @@ static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("PRI_MI2S_TX_Voip", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, @@ -13969,6 +14812,10 @@ static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, @@ -14060,6 +14907,10 @@ static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, @@ -14163,6 +15014,10 @@ static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, @@ -14266,6 +15121,10 @@ static const struct snd_kcontrol_new tx_qchat_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("MI2S_TX_QCHAT", SND_SOC_NOPM, MSM_BACKEND_DAI_MI2S_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, @@ -14344,6 +15203,10 @@ static const struct snd_kcontrol_new int0_mi2s_rx_port_mixer_controls[] = { MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT0_MI2S_RX, MSM_BACKEND_DAI_INT3_MI2S_TX, 1, 0, msm_routing_get_port_mixer, @@ -14391,6 +15254,10 @@ static const struct snd_kcontrol_new int4_mi2s_rx_port_mixer_controls[] = { MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_INT4_MI2S_RX, MSM_BACKEND_DAI_INT3_MI2S_TX, 1, 0, msm_routing_get_port_mixer, @@ -14497,6 +15364,10 @@ static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_QUIN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, @@ -14521,6 +15392,10 @@ static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, @@ -14545,6 +15420,10 @@ static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_QUINARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SENARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, @@ -14642,6 +15521,21 @@ static const struct snd_kcontrol_new quin_auxpcm_rx_port_mixer_controls[] = { msm_routing_put_port_mixer), }; +static const struct snd_kcontrol_new sen_auxpcm_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + static const struct snd_kcontrol_new sbus_1_rx_port_mixer_controls[] = { SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_1_RX, @@ -14767,2242 +15661,3181 @@ static const struct snd_kcontrol_new afe_pcm_rx_port_mixer_controls[] = { MSM_BACKEND_DAI_AFE_PCM_RX, MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), -}; - - -static const struct snd_kcontrol_new hdmi_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, +}; + + +static const struct snd_kcontrol_new hdmi_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new display_port_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new display_port_rx1_port_mixer_controls[] = { + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_i2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new primary_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new usb_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_USB_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quin_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sen_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new display_port_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new display_port_rx1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new sec_i2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), +static const struct snd_kcontrol_new pri_tdm_rx_0_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), +static const struct snd_kcontrol_new pri_tdm_rx_1_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new primary_mi2s_rx_port_mixer_controls[] = { +static const struct snd_kcontrol_new pri_tdm_rx_2_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new usb_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, - MSM_BACKEND_DAI_USB_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new quat_mi2s_rx_port_mixer_controls[] = { +static const struct snd_kcontrol_new pri_tdm_rx_3_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quin_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new pri_tdm_rx_0_port_mixer_controls[] = { +static const struct snd_kcontrol_new sec_tdm_rx_0_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new pri_tdm_rx_1_port_mixer_controls[] = { +static const struct snd_kcontrol_new sec_tdm_rx_1_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new pri_tdm_rx_2_port_mixer_controls[] = { +static const struct snd_kcontrol_new sec_tdm_rx_2_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new pri_tdm_rx_3_port_mixer_controls[] = { +static const struct snd_kcontrol_new sec_tdm_rx_3_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new sec_tdm_rx_0_port_mixer_controls[] = { +static const struct snd_kcontrol_new sec_tdm_rx_7_port_mixer_controls[] = { + SOC_DOUBLE_EXT("TERT_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_7, + MSM_BACKEND_DAI_TERT_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_0_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new sec_tdm_rx_1_port_mixer_controls[] = { +static const struct snd_kcontrol_new tert_tdm_rx_1_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new sec_tdm_rx_2_port_mixer_controls[] = { +static const struct snd_kcontrol_new tert_tdm_rx_2_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new sec_tdm_rx_3_port_mixer_controls[] = { +static const struct snd_kcontrol_new tert_tdm_rx_3_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_tdm_rx_7_port_mixer_controls[] = { - SOC_DOUBLE_EXT("TERT_TDM_TX_7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_7, - MSM_BACKEND_DAI_TERT_TDM_TX_7, 1, 0, + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new tert_tdm_rx_0_port_mixer_controls[] = { +static const struct snd_kcontrol_new quat_tdm_rx_0_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new tert_tdm_rx_1_port_mixer_controls[] = { +static const struct snd_kcontrol_new quat_tdm_rx_1_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new tert_tdm_rx_2_port_mixer_controls[] = { +static const struct snd_kcontrol_new quat_tdm_rx_2_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new tert_tdm_rx_3_port_mixer_controls[] = { +static const struct snd_kcontrol_new quat_tdm_rx_3_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new quat_tdm_rx_0_port_mixer_controls[] = { +static const struct snd_kcontrol_new quat_tdm_rx_7_port_mixer_controls[] = { + SOC_DOUBLE_EXT("QUAT_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_7, + MSM_BACKEND_DAI_QUAT_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_rx_0_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new quat_tdm_rx_1_port_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_rx_1_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new quat_tdm_rx_2_port_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_rx_2_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new quat_tdm_rx_3_port_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_rx_3_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quat_tdm_rx_7_port_mixer_controls[] = { - SOC_DOUBLE_EXT("QUAT_TDM_TX_7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_7, - MSM_BACKEND_DAI_QUAT_TDM_TX_7, 1, 0, + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new quin_tdm_rx_0_port_mixer_controls[] = { +static const struct snd_kcontrol_new sen_tdm_rx_0_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new quin_tdm_rx_1_port_mixer_controls[] = { +static const struct snd_kcontrol_new sen_tdm_rx_1_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_1, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new quin_tdm_rx_2_port_mixer_controls[] = { +static const struct snd_kcontrol_new sen_tdm_rx_2_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_2, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new quin_tdm_rx_3_port_mixer_controls[] = { +static const struct snd_kcontrol_new sen_tdm_rx_3_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_3, MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new tert_mi2s_rx_port_mixer_controls[] = { @@ -17026,6 +18859,10 @@ static const struct snd_kcontrol_new tert_mi2s_rx_port_mixer_controls[] = { MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, @@ -17057,6 +18894,10 @@ static const struct snd_kcontrol_new sec_mi2s_rx_port_mixer_controls[] = { MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, @@ -17591,6 +19432,11 @@ static const struct snd_kcontrol_new quin_mi2s_rx_switch_mixer_controls = 0, 1, 0, msm_routing_get_quin_mi2s_switch_mixer, msm_routing_put_quin_mi2s_switch_mixer); +static const struct snd_kcontrol_new sen_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_sen_mi2s_switch_mixer, + msm_routing_put_sen_mi2s_switch_mixer); + static const struct snd_kcontrol_new hfp_pri_aux_switch_mixer_controls = SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, 0, 1, 0, msm_routing_get_hfp_switch_mixer, @@ -19095,6 +20941,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_IN("QUIN_MI2S_DL_HL", "Quinary MI2S_RX Hostless Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_MI2S_DL_HL", + "Senary MI2S_RX Hostless Playback", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("AUXPCM_DL_HL", "AUXPCM_HOSTLESS Playback", 0, 0, 0, 0), @@ -19128,6 +20977,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("QUIN_MI2S_UL_HL", "Quinary MI2S_TX Hostless Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_MI2S_UL_HL", + "Senary MI2S_TX Hostless Capture", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_0_DL_HL", "Primary TDM0 Hostless Playback", @@ -19369,6 +21221,54 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_7_UL_HL", "Quinary TDM7 Hostless Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_0_DL_HL", + "Senary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_0_UL_HL", + "Senary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_1_DL_HL", + "Senary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_1_UL_HL", + "Senary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_2_DL_HL", + "Senary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_2_UL_HL", + "Senary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_3_DL_HL", + "Senary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_3_UL_HL", + "Senary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_4_DL_HL", + "Senary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_4_UL_HL", + "Senary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_5_DL_HL", + "Senary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_5_UL_HL", + "Senary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_6_DL_HL", + "Senary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_6_UL_HL", + "Senary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_7_DL_HL", + "Senary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_7_UL_HL", + "Senary TDM7 Hostless Capture", + 0, 0, 0, 0), /* LSM */ SND_SOC_DAPM_AIF_OUT("LSM1_UL_HL", "Listen 1 Audio Service Capture", @@ -19436,6 +21336,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("QUIN_MI2S_RX", "Quinary MI2S Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_MI2S_RX", "Senary MI2S Playback", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("MI2S_TX", "MI2S Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX", "Quaternary MI2S Capture", @@ -19632,6 +21534,38 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_7", "Quinary TDM7 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_0", "Senary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_0", "Senary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_1", "Senary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_1", "Senary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_2", "Senary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_2", "Senary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_3", "Senary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_3", "Senary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_4", "Senary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_4", "Senary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_5", "Senary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_5", "Senary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_6", "Senary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_6", "Senary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_7", "Senary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_7", "Senary TDM7 Capture", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("WSA_CDC_DMA_RX_0", "WSA CDC DMA0 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("WSA_CDC_DMA_TX_0", "WSA CDC DMA0 Capture", @@ -19713,6 +21647,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("QUIN_AUX_PCM_TX", "Quin AUX PCM Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_AUX_PCM_RX", "Sen AUX PCM Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_AUX_PCM_TX", "Sen AUX PCM Capture", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("VOICE_STUB_DL", "VOICE_STUB Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("VOICE_STUB_UL", "VOICE_STUB Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("VOICE2_STUB_DL", "VOICE2_STUB Playback", @@ -19772,6 +21710,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &quin_mi2s_rx_switch_mixer_controls), SND_SOC_DAPM_SWITCH("SCO_SLIM7_DL_HL", SND_SOC_NOPM, 0, 0, &sco_slim7_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SEN_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, + &sen_mi2s_rx_switch_mixer_controls), SND_SOC_DAPM_SWITCH("HFP_PRI_AUX_UL_HL", SND_SOC_NOPM, 0, 0, &hfp_pri_aux_switch_mixer_controls), SND_SOC_DAPM_SWITCH("HFP_AUX_UL_HL", SND_SOC_NOPM, 0, 0, @@ -19840,6 +21780,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUIN_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, quinary_mi2s_rx_mixer_controls, ARRAY_SIZE(quinary_mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + senary_mi2s_rx_mixer_controls, + ARRAY_SIZE(senary_mi2s_rx_mixer_controls)), SND_SOC_DAPM_MIXER("PRI_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, pri_tdm_rx_0_mixer_controls, ARRAY_SIZE(pri_tdm_rx_0_mixer_controls)), @@ -19918,6 +21861,21 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUIN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, quin_tdm_rx_3_mixer_controls, ARRAY_SIZE(quin_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_tx_0_mixer_controls, + ARRAY_SIZE(sen_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_rx_0_mixer_controls, + ARRAY_SIZE(sen_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_rx_1_mixer_controls, + ARRAY_SIZE(sen_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_rx_2_mixer_controls, + ARRAY_SIZE(sen_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_rx_3_mixer_controls, + ARRAY_SIZE(sen_tdm_rx_3_mixer_controls)), SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, wsa_cdc_dma_rx_0_mixer_controls, ARRAY_SIZE(wsa_cdc_dma_rx_0_mixer_controls)), @@ -19997,6 +21955,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUIN_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, quin_auxpcm_rx_mixer_controls, ARRAY_SIZE(quin_auxpcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_auxpcm_rx_mixer_controls, + ARRAY_SIZE(sen_auxpcm_rx_mixer_controls)), /* incall */ SND_SOC_DAPM_MIXER("Incall_Music Audio Mixer", SND_SOC_NOPM, 0, 0, incall_music_delivery_mixer_controls, @@ -20057,6 +22018,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_NOPM, 0, 0, quin_aux_pcm_rx_voice_mixer_controls, ARRAY_SIZE(quin_aux_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + sen_aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(sen_aux_pcm_rx_voice_mixer_controls)), SND_SOC_DAPM_MIXER("HDMI_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, hdmi_rx_voice_mixer_controls, @@ -20105,6 +22070,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_NOPM, 0, 0, pri_tdm_rx_3_voice_mixer_controls, ARRAY_SIZE(pri_tdm_rx_3_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_MI2S_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + sen_mi2s_rx_voice_mixer_controls, + ARRAY_SIZE(sen_mi2s_rx_voice_mixer_controls)), SND_SOC_DAPM_MIXER("QUAT_TDM_RX_2_Voice Mixer", SND_SOC_NOPM, 0, 0, quat_tdm_rx_2_voice_mixer_controls, @@ -20177,6 +22146,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUIN_AUXPCM_RX Port Mixer", SND_SOC_NOPM, 0, 0, quin_auxpcm_rx_port_mixer_controls, ARRAY_SIZE(quin_auxpcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_AUXPCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, sen_auxpcm_rx_port_mixer_controls, + ARRAY_SIZE(sen_auxpcm_rx_port_mixer_controls)), SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Port Mixer", SND_SOC_NOPM, 0, 0, sbus_1_rx_port_mixer_controls, ARRAY_SIZE(sbus_1_rx_port_mixer_controls)), @@ -20221,6 +22193,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUIN_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, quin_mi2s_rx_port_mixer_controls, ARRAY_SIZE(quin_mi2s_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, + sen_mi2s_rx_port_mixer_controls, + ARRAY_SIZE(sen_mi2s_rx_port_mixer_controls)), SND_SOC_DAPM_MIXER("PRI_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, pri_tdm_rx_0_port_mixer_controls, ARRAY_SIZE(pri_tdm_rx_0_port_mixer_controls)), @@ -20287,6 +22262,18 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUIN_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0, quin_tdm_rx_3_port_mixer_controls, ARRAY_SIZE(quin_tdm_rx_3_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_rx_0_port_mixer_controls, + ARRAY_SIZE(sen_tdm_rx_0_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_RX_1 Port Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_rx_1_port_mixer_controls, + ARRAY_SIZE(sen_tdm_rx_1_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_RX_2 Port Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_rx_2_port_mixer_controls, + ARRAY_SIZE(sen_tdm_rx_2_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_rx_3_port_mixer_controls, + ARRAY_SIZE(sen_tdm_rx_3_port_mixer_controls)), SND_SOC_DAPM_MIXER("INT0_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, int0_mi2s_rx_port_mixer_controls, ARRAY_SIZE(int0_mi2s_rx_port_mixer_controls)), @@ -21079,6 +23066,23 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX Audio Mixer"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX Audio Mixer"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, @@ -21576,6 +23580,104 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Audio Mixer"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEN_TDM_RX_0", NULL, "SEN_TDM_RX_0 Audio Mixer"}, + + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_TDM_TX_0", NULL, "SEN_TDM_TX_0 Audio Mixer"}, + + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEN_TDM_RX_1", NULL, "SEN_TDM_RX_1 Audio Mixer"}, + + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEN_TDM_RX_2", NULL, "SEN_TDM_RX_2 Audio Mixer"}, + + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEN_TDM_RX_3", NULL, "SEN_TDM_RX_3 Audio Mixer"}, + {"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"}, {"MultiMedia1 Mixer", "MI2S_TX", "MI2S_TX"}, {"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"}, @@ -21588,6 +23690,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia1 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"MultiMedia2 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia1 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, + {"MultiMedia2 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, {"MultiMedia1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia1 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, @@ -21618,6 +23722,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, {"MultiMedia3 Mixer", "QUIN_AUX_PCM_TX", "QUIN_AUX_PCM_TX"}, {"MultiMedia5 Mixer", "QUIN_AUX_PCM_TX", "QUIN_AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "SEN_AUXPCM_UL_TX", "SEN_AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "SEN_AUX_PCM_TX", "SEN_AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "SEN_AUX_PCM_TX", "SEN_AUX_PCM_TX"}, {"MultiMedia2 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia2 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, {"MultiMedia2 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, @@ -21651,6 +23758,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia6 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"MultiMedia6 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia6 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, {"MultiMedia1 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia1 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -21673,6 +23781,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia1 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia1 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia1 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia1 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia1 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia1 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, @@ -21709,6 +23821,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia2 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia2 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia2 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia2 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia2 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia2 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia2 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, @@ -21745,6 +23861,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia3 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia3 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia3 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia3 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia3 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia3 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia3 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, @@ -21781,6 +23901,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia4 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia4 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia4 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia4 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia4 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia4 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia4 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, @@ -21817,6 +23941,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia5 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia5 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia5 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia5 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia5 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia5 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, @@ -21853,6 +23981,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia6 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia6 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia6 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia6 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia6 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia6 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, @@ -21889,6 +24021,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia8 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia8 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia8 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia8 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia8 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia8 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, @@ -21917,6 +24053,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia9 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia9 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia9 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia9 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia9 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia9 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia9 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, @@ -21954,6 +24094,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia20 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia20 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia20 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia20 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, {"MultiMedia20 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia20 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, {"MultiMedia20 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, @@ -21974,6 +24115,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia20 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia20 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia20 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia20 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia20 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia20 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia20 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, @@ -22012,6 +24157,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia21 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"MultiMedia21 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia21 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia21 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia21 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia21 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia21 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, @@ -22038,6 +24187,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia27 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia27 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia27 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia27 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, {"MultiMedia27 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia27 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MultiMedia27 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, @@ -22345,6 +24495,24 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUX_PCM_RX Audio Mixer"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_AUX_PCM_RX", NULL, "SEN_AUX_PCM_RX Audio Mixer"}, + {"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"PRI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"PRI_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, @@ -22450,6 +24618,13 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUX_PCM_RX_Voice Mixer"}, + {"SEN_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SEN_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SEN_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SEN_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SEN_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SEN_AUX_PCM_RX", NULL, "SEN_AUX_PCM_RX_Voice Mixer"}, + {"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"}, {"HDMI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, {"HDMI_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, @@ -22571,6 +24746,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_3_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3_Voice Mixer"}, + {"SEN_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SEN_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SEN_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SEN_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX_Voice Mixer"}, + {"QUAT_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_Voice Mixer"}, @@ -22774,6 +24955,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode1_Tx Mixer", "TERT_AUX_PCM_TX_MMode1", "TERT_AUX_PCM_TX"}, {"VoiceMMode1_Tx Mixer", "QUAT_AUX_PCM_TX_MMode1", "QUAT_AUX_PCM_TX"}, {"VoiceMMode1_Tx Mixer", "QUIN_AUX_PCM_TX_MMode1", "QUIN_AUX_PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "SEN_AUX_PCM_TX_MMode1", "SEN_AUX_PCM_TX"}, {"VoiceMMode1_Tx Mixer", "QUAT_TDM_TX_0_MMode1", "QUAT_TDM_TX_0"}, {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_0_MMode1", "TX_CDC_DMA_TX_0"}, {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_1_MMode1", "TX_CDC_DMA_TX_1"}, @@ -22802,6 +24984,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode2_Tx Mixer", "TERT_AUX_PCM_TX_MMode2", "TERT_AUX_PCM_TX"}, {"VoiceMMode2_Tx Mixer", "QUAT_AUX_PCM_TX_MMode2", "QUAT_AUX_PCM_TX"}, {"VoiceMMode2_Tx Mixer", "QUIN_AUX_PCM_TX_MMode2", "QUIN_AUX_PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "SEN_AUX_PCM_TX_MMode2", "SEN_AUX_PCM_TX"}, {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_0_MMode2", "TX_CDC_DMA_TX_0"}, {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_1_MMode2", "TX_CDC_DMA_TX_1"}, {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_2_MMode2", "TX_CDC_DMA_TX_2"}, @@ -22828,6 +25011,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"Voip_Tx Mixer", "TERT_AUX_PCM_TX_Voip", "TERT_AUX_PCM_TX"}, {"Voip_Tx Mixer", "QUAT_AUX_PCM_TX_Voip", "QUAT_AUX_PCM_TX"}, {"Voip_Tx Mixer", "QUIN_AUX_PCM_TX_Voip", "QUIN_AUX_PCM_TX"}, + {"Voip_Tx Mixer", "SEN_AUX_PCM_TX_Voip", "SEN_AUX_PCM_TX"}, {"Voip_Tx Mixer", "PRI_MI2S_TX_Voip", "PRI_MI2S_TX"}, {"Voip_Tx Mixer", "PRI_TDM_TX_3_Voip", "PRI_TDM_TX_3"}, {"VOIP_UL", NULL, "Voip_Tx Mixer"}, @@ -22984,6 +25168,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QCHAT_Tx Mixer", "TERT_AUX_PCM_TX_QCHAT", "TERT_AUX_PCM_TX"}, {"QCHAT_Tx Mixer", "QUAT_AUX_PCM_TX_QCHAT", "QUAT_AUX_PCM_TX"}, {"QCHAT_Tx Mixer", "QUIN_AUX_PCM_TX_QCHAT", "QUIN_AUX_PCM_TX"}, + {"QCHAT_Tx Mixer", "SEN_AUX_PCM_TX_QCHAT", "SEN_AUX_PCM_TX"}, {"QCHAT_Tx Mixer", "MI2S_TX_QCHAT", "MI2S_TX"}, {"QCHAT_Tx Mixer", "PRI_MI2S_TX_QCHAT", "PRI_MI2S_TX"}, {"QCHAT_Tx Mixer", "TERT_MI2S_TX_QCHAT", "TERT_MI2S_TX"}, @@ -23029,6 +25214,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_DL_HL"}, {"QUIN_MI2S_RX_DL_HL", "Switch", "QUIN_MI2S_DL_HL"}, {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_DL_HL"}, + {"SEN_MI2S_RX_DL_HL", "Switch", "SEN_MI2S_DL_HL"}, + {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX_DL_HL"}, {"MI2S_UL_HL", NULL, "TERT_MI2S_TX"}, {"INT3_MI2S_UL_HL", NULL, "INT3_MI2S_TX"}, {"TERT_MI2S_UL_HL", NULL, "TERT_MI2S_TX"}, @@ -23084,6 +25271,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1_DL_HL"}, {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2_DL_HL"}, {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3_DL_HL"}, + {"SEN_TDM_TX_0_UL_HL", NULL, "SEN_TDM_TX_0"}, + {"SEN_TDM_TX_1_UL_HL", NULL, "SEN_TDM_TX_1"}, + {"SEN_TDM_TX_2_UL_HL", NULL, "SEN_TDM_TX_2"}, + {"SEN_TDM_TX_3_UL_HL", NULL, "SEN_TDM_TX_3"}, + {"SEN_TDM_RX_0", NULL, "SEN_TDM_RX_0_DL_HL"}, + {"SEN_TDM_RX_1", NULL, "SEN_TDM_RX_1_DL_HL"}, + {"SEN_TDM_RX_2", NULL, "SEN_TDM_RX_2_DL_HL"}, + {"SEN_TDM_RX_3", NULL, "SEN_TDM_RX_3_DL_HL"}, {"PRI_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"PRI_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, @@ -23105,6 +25300,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Port Mixer"}, {"PRI_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23127,6 +25326,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Port Mixer"}, {"PRI_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23149,6 +25352,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Port Mixer"}, {"PRI_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23171,6 +25378,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Port Mixer"}, {"SEC_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23193,6 +25404,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Port Mixer"}, {"SEC_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23215,6 +25430,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Port Mixer"}, {"SEC_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23237,6 +25456,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Port Mixer"}, {"SEC_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23259,6 +25482,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Port Mixer"}, {"SEC_TDM_RX_7 Port Mixer", "TERT_TDM_TX_7", "TERT_TDM_TX_7"}, @@ -23284,6 +25511,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Port Mixer"}, {"TERT_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23306,6 +25537,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Port Mixer"}, {"TERT_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23328,6 +25563,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Port Mixer"}, {"TERT_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23350,6 +25589,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Port Mixer"}, {"QUAT_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23372,6 +25615,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Port Mixer"}, {"QUAT_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23394,6 +25641,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Port Mixer"}, {"QUAT_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23416,6 +25667,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Port Mixer"}, {"QUAT_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23438,6 +25693,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Port Mixer"}, {"QUAT_TDM_RX_7 Port Mixer", "QUAT_TDM_TX_7", "QUAT_TDM_TX_7"}, @@ -23463,6 +25722,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0 Port Mixer"}, {"QUIN_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23485,6 +25748,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1 Port Mixer"}, {"QUIN_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23507,6 +25774,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2 Port Mixer"}, {"QUIN_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23529,13 +25800,106 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Port Mixer"}, + {"SEN_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEN_TDM_RX_0", NULL, "SEN_TDM_RX_0 Port Mixer"}, + + {"SEN_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEN_TDM_RX_1", NULL, "SEN_TDM_RX_1 Port Mixer"}, + + {"SEN_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEN_TDM_RX_2", NULL, "SEN_TDM_RX_2 Port Mixer"}, + + {"SEN_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEN_TDM_RX_3", NULL, "SEN_TDM_RX_3 Port Mixer"}, + {"INT0_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"INT0_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"INT0_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"INT0_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"INT0_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, {"INT0_MI2S_RX Port Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"INT0_MI2S_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"INT0_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, @@ -23549,6 +25913,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"INT4_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"INT4_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"INT4_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, {"INT4_MI2S_RX Port Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"INT4_MI2S_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"INT4_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, @@ -23579,12 +25944,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_0_RX Port Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, {"SLIMBUS_0_RX Port Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, {"SLIMBUS_0_RX Port Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SEN_AUXPCM_UL_TX", "SEN_AUX_PCM_TX"}, {"SLIMBUS_0_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"}, {"AFE_PCM_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, @@ -23635,6 +26002,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"Voice Stub Tx Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, {"Voice Stub Tx Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, {"Voice Stub Tx Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "SEN_AUXPCM_UL_TX", "SEN_AUX_PCM_TX"}, {"Voice Stub Tx Mixer", "MI2S_TX", "MI2S_TX"}, {"Voice Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"Voice Stub Tx Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, @@ -23751,6 +26119,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"PRI_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"PRI_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"PRI_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, {"PRI_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"PRI_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"PRI_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, @@ -23763,6 +26132,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"SEC_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"SEC_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"SEC_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, {"SEC_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"SEC_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"SEC_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, @@ -23774,6 +26144,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"TERT_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"TERT_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"TERT_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, {"TERT_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"TERT_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX Port Mixer"}, @@ -23783,6 +26154,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"QUAT_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"QUAT_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"SEN_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, {"QUAT_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"QUAT_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"QUAT_MI2S_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, @@ -23794,10 +26166,20 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"QUIN_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"QUIN_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"QUIN_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, {"QUIN_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"QUIN_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX Port Mixer"}, + {"SEN_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEN_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEN_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"SEN_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"SEN_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"SEN_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"SEN_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX Port Mixer"}, + /* Backend Enablement */ {"BE_OUT", NULL, "PRI_I2S_RX"}, @@ -23821,6 +26203,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "MI2S_RX"}, {"BE_OUT", NULL, "QUAT_MI2S_RX"}, {"BE_OUT", NULL, "QUIN_MI2S_RX"}, + {"BE_OUT", NULL, "SEN_MI2S_RX"}, {"BE_OUT", NULL, "TERT_MI2S_RX"}, {"BE_OUT", NULL, "SEC_MI2S_RX"}, {"BE_OUT", NULL, "SEC_MI2S_RX_SD1"}, @@ -23840,6 +26223,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "TERT_AUX_PCM_RX"}, {"BE_OUT", NULL, "QUAT_AUX_PCM_RX"}, {"BE_OUT", NULL, "QUIN_AUX_PCM_RX"}, + {"BE_OUT", NULL, "SEN_AUX_PCM_RX"}, {"BE_OUT", NULL, "INT_BT_SCO_RX"}, {"BE_OUT", NULL, "INT_FM_RX"}, {"BE_OUT", NULL, "PCM_RX"}, @@ -23869,6 +26253,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "QUIN_TDM_RX_1"}, {"BE_OUT", NULL, "QUIN_TDM_RX_2"}, {"BE_OUT", NULL, "QUIN_TDM_RX_3"}, + {"BE_OUT", NULL, "SEN_TDM_RX_0"}, + {"BE_OUT", NULL, "SEN_TDM_RX_1"}, + {"BE_OUT", NULL, "SEN_TDM_RX_2"}, + {"BE_OUT", NULL, "SEN_TDM_RX_3"}, {"BE_OUT", NULL, "WSA_CDC_DMA_RX_0"}, {"BE_OUT", NULL, "WSA_CDC_DMA_RX_1"}, {"BE_OUT", NULL, "RX_CDC_DMA_RX_0"}, @@ -23892,7 +26280,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"INT4_MI2S_TX", NULL, "BE_IN"}, {"INT5_MI2S_TX", NULL, "BE_IN"}, {"SEC_MI2S_TX", NULL, "BE_IN"}, - {"SENARY_MI2S_TX", NULL, "BE_IN" }, + {"SENARY_MI2S_TX", NULL, "BE_IN"}, {"SLIMBUS_0_TX", NULL, "BE_IN" }, {"SLIMBUS_1_TX", NULL, "BE_IN" }, {"SLIMBUS_3_TX", NULL, "BE_IN" }, @@ -23916,6 +26304,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_AUX_PCM_TX", NULL, "BE_IN"}, {"QUAT_AUX_PCM_TX", NULL, "BE_IN"}, {"QUIN_AUX_PCM_TX", NULL, "BE_IN"}, + {"SEN_AUX_PCM_TX", NULL, "BE_IN"}, {"INCALL_RECORD_TX", NULL, "BE_IN"}, {"INCALL_RECORD_RX", NULL, "BE_IN"}, {"SLIM0_RX_VI_FB_LCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"}, @@ -23955,6 +26344,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_TX_1", NULL, "BE_IN"}, {"QUIN_TDM_TX_2", NULL, "BE_IN"}, {"QUIN_TDM_TX_3", NULL, "BE_IN"}, + {"SEN_TDM_TX_0", NULL, "BE_IN"}, + {"SEN_TDM_TX_1", NULL, "BE_IN"}, + {"SEN_TDM_TX_2", NULL, "BE_IN"}, + {"SEN_TDM_TX_3", NULL, "BE_IN"}, {"WSA_CDC_DMA_TX_0", NULL, "BE_IN"}, {"WSA_CDC_DMA_TX_1", NULL, "BE_IN"}, {"WSA_CDC_DMA_TX_2", NULL, "BE_IN"}, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index fc93059d3a3c..07b975229d7b 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -162,6 +162,22 @@ #define LPASS_BE_QUIN_TDM_TX_6 "QUIN_TDM_TX_6" #define LPASS_BE_QUIN_TDM_RX_7 "QUIN_TDM_RX_7" #define LPASS_BE_QUIN_TDM_TX_7 "QUIN_TDM_TX_7" +#define LPASS_BE_SEN_TDM_RX_0 "SEN_TDM_RX_0" +#define LPASS_BE_SEN_TDM_TX_0 "SEN_TDM_TX_0" +#define LPASS_BE_SEN_TDM_RX_1 "SEN_TDM_RX_1" +#define LPASS_BE_SEN_TDM_TX_1 "SEN_TDM_TX_1" +#define LPASS_BE_SEN_TDM_RX_2 "SEN_TDM_RX_2" +#define LPASS_BE_SEN_TDM_TX_2 "SEN_TDM_TX_2" +#define LPASS_BE_SEN_TDM_RX_3 "SEN_TDM_RX_3" +#define LPASS_BE_SEN_TDM_TX_3 "SEN_TDM_TX_3" +#define LPASS_BE_SEN_TDM_RX_4 "SEN_TDM_RX_4" +#define LPASS_BE_SEN_TDM_TX_4 "SEN_TDM_TX_4" +#define LPASS_BE_SEN_TDM_RX_5 "SEN_TDM_RX_5" +#define LPASS_BE_SEN_TDM_TX_5 "SEN_TDM_TX_5" +#define LPASS_BE_SEN_TDM_RX_6 "SEN_TDM_RX_6" +#define LPASS_BE_SEN_TDM_TX_6 "SEN_TDM_TX_6" +#define LPASS_BE_SEN_TDM_RX_7 "SEN_TDM_RX_7" +#define LPASS_BE_SEN_TDM_TX_7 "SEN_TDM_TX_7" #define LPASS_BE_SLIMBUS_7_RX "SLIMBUS_7_RX" #define LPASS_BE_SLIMBUS_7_TX "SLIMBUS_7_TX" @@ -404,6 +420,22 @@ enum { MSM_BACKEND_DAI_QUIN_TDM_TX_6, MSM_BACKEND_DAI_QUIN_TDM_RX_7, MSM_BACKEND_DAI_QUIN_TDM_TX_7, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_4, + MSM_BACKEND_DAI_SEN_TDM_TX_4, + MSM_BACKEND_DAI_SEN_TDM_RX_5, + MSM_BACKEND_DAI_SEN_TDM_TX_5, + MSM_BACKEND_DAI_SEN_TDM_RX_6, + MSM_BACKEND_DAI_SEN_TDM_TX_6, + MSM_BACKEND_DAI_SEN_TDM_RX_7, + MSM_BACKEND_DAI_SEN_TDM_TX_7, MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_BACKEND_DAI_USB_RX, MSM_BACKEND_DAI_USB_TX, -- GitLab From 7d64c2a9d1514369794b36568edb376c913181a5 Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Fri, 8 Mar 2019 11:08:01 +0530 Subject: [PATCH 0961/1645] asoc: Add transcode loopback capture app type cfg controls Add app type config controls for transcode loopback capture node. This is required to configure CoPreP independently in loopback usecases. Change-Id: I79aa098b8b9d3ac4baf9291f8a25297a3ffef1bd Signed-off-by: Chaithanya Krishna Bacharaju --- asoc/msm-transcode-loopback-q6-v2.c | 83 +++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 3 deletions(-) diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index a311cc1e91fd..dc4103799c5b 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -901,6 +901,67 @@ static int msm_transcode_playback_app_type_cfg_get( return ret; } +static int msm_transcode_capture_app_type_cfg_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_BE_ID]; + struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000}; + int ret = 0; + + cfg_data.app_type = ucontrol->value.integer.value[ + APP_TYPE_CONFIG_IDX_APP_TYPE]; + cfg_data.acdb_dev_id = ucontrol->value.integer.value[ + APP_TYPE_CONFIG_IDX_ACDB_ID]; + if (ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_SAMPLE_RATE] != 0) + cfg_data.sample_rate = ucontrol->value.integer.value[ + APP_TYPE_CONFIG_IDX_SAMPLE_RATE]; + pr_debug("%s: fe_id %llu session_type %d be_id %d app_type %d acdb_dev_id %d sample_rate- %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type, + be_id, &cfg_data); + if (ret < 0) + pr_err("%s: register stream app type cfg failed, returned %d\n", + __func__, ret); + + return ret; +} + +static int msm_transcode_capture_app_type_cfg_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + int session_type = SESSION_TYPE_TX; + int be_id = 0; + struct msm_pcm_stream_app_type_cfg cfg_data = {0}; + int ret = 0; + + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type, + &be_id, &cfg_data); + if (ret < 0) { + pr_err("%s: get stream app type cfg failed, returned %d\n", + __func__, ret); + goto done; + } + + ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_APP_TYPE] = + cfg_data.app_type; + ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_ACDB_ID] = + cfg_data.acdb_dev_id; + ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_SAMPLE_RATE] = + cfg_data.sample_rate; + ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_BE_ID] = be_id; + pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n", + __func__, fe_id, session_type, be_id, + cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate); +done: + return ret; +} + static int msm_transcode_set_volume(struct snd_compr_stream *cstream, uint32_t master_gain) { @@ -1411,14 +1472,12 @@ static int msm_transcode_add_app_type_cfg_control( struct snd_soc_pcm_runtime *rtd) { struct snd_soc_component *component = NULL; - char mixer_str[32]; + char mixer_str[128]; struct snd_kcontrol_new fe_app_type_cfg_control[1] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .info = msm_transcode_app_type_cfg_info, - .put = msm_transcode_playback_app_type_cfg_put, - .get = msm_transcode_playback_app_type_cfg_get, .private_value = 0, } }; @@ -1447,6 +1506,23 @@ static int msm_transcode_add_app_type_cfg_control( fe_app_type_cfg_control[0].get = msm_transcode_playback_app_type_cfg_get; + pr_debug("Registering new mixer ctl %s", mixer_str); + snd_soc_add_component_controls(component, + fe_app_type_cfg_control, + ARRAY_SIZE(fe_app_type_cfg_control)); + } else if (rtd->compr->direction == SND_COMPRESS_CAPTURE) { + snprintf(mixer_str, sizeof(mixer_str), + "Audio Stream Capture %d App Type Cfg", + rtd->pcm->device); + + fe_app_type_cfg_control[0].name = mixer_str; + fe_app_type_cfg_control[0].private_value = rtd->dai_link->id; + + fe_app_type_cfg_control[0].put = + msm_transcode_capture_app_type_cfg_put; + fe_app_type_cfg_control[0].get = + msm_transcode_capture_app_type_cfg_get; + pr_debug("Registering new mixer ctl %s", mixer_str); snd_soc_add_component_controls(component, fe_app_type_cfg_control, @@ -1455,6 +1531,7 @@ static int msm_transcode_add_app_type_cfg_control( return 0; } + static int msm_transcode_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { -- GitLab From 9b0637b6bc4b7b21898b68bb8833e983275d15ee Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Fri, 19 Apr 2019 18:47:16 +0530 Subject: [PATCH 0962/1645] asoc: msm-lsm-client: Initialize started flag in open Initialize started flag in open instead of prepare since reset happens in close. This will also help stop already active LSM sessions even if prepare was called in between. Change-Id: Iad47f9459ceddefd582840313901d95d338e1147 Signed-off-by: Chaithanya Krishna Bacharaju --- asoc/msm-lsm-client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 3a5707e0de8d..080c08e55f6b 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -2483,6 +2483,7 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) return -ENOMEM; } prtd->lsm_client->opened = false; + prtd->lsm_client->started = false; prtd->lsm_client->session_state = IDLE; prtd->lsm_client->poll_enable = true; prtd->lsm_client->perf_mode = 0; @@ -2610,7 +2611,6 @@ static int msm_lsm_prepare(struct snd_pcm_substream *substream) } prtd->lsm_client->session_state = RUNNING; - prtd->lsm_client->started = false; runtime->private_data = prtd; return ret; } -- GitLab From e2c19049886c45237c004086a1a433ce828461f1 Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Wed, 3 Apr 2019 12:00:26 +0530 Subject: [PATCH 0963/1645] dsp: Add asm channel map support for 10channels Add asm channel map support for 10channels to support 10channel recording usecase. Change-Id: Ic939eabed893e9e56b17e62bc5100f2d6d51732f Signed-off-by: Chaithanya Krishna Bacharaju --- dsp/q6asm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 66eef6468777..b6173e27e1a7 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -5701,6 +5701,17 @@ int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, lchannel_mapping[5] = PCM_CHANNEL_RB; lchannel_mapping[6] = PCM_CHANNEL_LS; lchannel_mapping[7] = PCM_CHANNEL_RS; + } else if (channels == 10) { + lchannel_mapping[0] = PCM_CHANNEL_FL; + lchannel_mapping[1] = PCM_CHANNEL_FR; + lchannel_mapping[2] = PCM_CHANNEL_LFE; + lchannel_mapping[3] = PCM_CHANNEL_FC; + lchannel_mapping[4] = PCM_CHANNEL_LB; + lchannel_mapping[5] = PCM_CHANNEL_RB; + lchannel_mapping[6] = PCM_CHANNEL_LS; + lchannel_mapping[7] = PCM_CHANNEL_RS; + lchannel_mapping[8] = PCM_CHANNEL_TFL; + lchannel_mapping[9] = PCM_CHANNEL_TFR; } else if (channels == 12) { /* * Configured for 7.1.4 channel mapping -- GitLab From 4f798ababf69fbaf3b69472a7d85253fe368b669 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 8 May 2019 12:00:43 +0530 Subject: [PATCH 0964/1645] soc: Do not compile pinctrl_wcd for lito Lito uses pinctrl_lpi. Do not compile pinctrl_wcd for lito. Change-Id: I4befdc65769b592f0244556db64785b64b885223 Signed-off-by: Vatsal Bucha --- soc/Android.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/soc/Android.mk b/soc/Android.mk index 0698221db437..0bd740322fdc 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -58,6 +58,7 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk endif ########################################################### +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona), true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_wcd.ko LOCAL_MODULE_KBUILD_NAME := pinctrl_wcd_dlkm.ko @@ -65,6 +66,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk +endif ########################################################### include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_swr.ko -- GitLab From cf3b406a5f9f71fe0e7defcdae974bd11e564813 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 10 May 2019 10:48:43 +0530 Subject: [PATCH 0965/1645] ASoC: bolero: Fix issue in clock sequence during VA concurrency Fix issue in clock sequence when switching between VA clock to TX clock and viceversa during VA usecase. Change-Id: I4a7d423916b70b4b3c54d0d9a28b8ea874584525 Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/tx-macro.c | 191 ++++++++++++++++++---------------- 1 file changed, 104 insertions(+), 87 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 49b7da573525..288ded36df89 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -159,7 +159,8 @@ struct tx_macro_priv { int child_count; int tx_swr_clk_cnt; int va_swr_clk_cnt; - int swr_clk_type; + int va_clk_status; + int tx_clk_status; }; static bool tx_macro_get_data(struct snd_soc_component *component, @@ -1477,50 +1478,53 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, (enable ? "enable" : "disable"), tx_priv->tx_mclk_users); if (enable) { - if (tx_priv->swr_clk_users == 0) { + if (tx_priv->swr_clk_users == 0) msm_cdc_pinctrl_select_active_state( tx_priv->tx_swr_gpio_p); + ret = bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + true); + if (clk_type == TX_MCLK) { + ret = tx_macro_mclk_enable(tx_priv, 1); + if (ret < 0) { + if (tx_priv->swr_clk_users == 0) + msm_cdc_pinctrl_select_sleep_state( + tx_priv->tx_swr_gpio_p); + dev_err_ratelimited(tx_priv->dev, + "%s: request clock enable failed\n", + __func__); + goto done; + } + } + if (clk_type == VA_MCLK) { ret = bolero_clk_rsc_request_clock(tx_priv->dev, TX_CORE_CLK, - TX_CORE_CLK, + VA_CORE_CLK, true); - if (clk_type == TX_MCLK) { - ret = tx_macro_mclk_enable(tx_priv, 1); - if (ret < 0) { + if (ret < 0) { + if (tx_priv->swr_clk_users == 0) msm_cdc_pinctrl_select_sleep_state( tx_priv->tx_swr_gpio_p); - dev_err_ratelimited(tx_priv->dev, - "%s: request clock enable failed\n", - __func__); - goto done; - } + dev_err_ratelimited(tx_priv->dev, + "%s: swr request clk failed\n", + __func__); + goto done; } - if (clk_type == VA_MCLK) { - ret = bolero_clk_rsc_request_clock(tx_priv->dev, - TX_CORE_CLK, - VA_CORE_CLK, - true); - if (ret < 0) { - msm_cdc_pinctrl_select_sleep_state( - tx_priv->tx_swr_gpio_p); - dev_err_ratelimited(tx_priv->dev, - "%s: swr request clk failed\n", - __func__); - goto done; - } - if (tx_priv->tx_mclk_users == 0) { - regmap_update_bits(regmap, - BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK, - 0x01, 0x01); - regmap_update_bits(regmap, - BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, - 0x01, 0x01); - regmap_update_bits(regmap, - BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, - 0x01, 0x01); - } + if (tx_priv->tx_mclk_users == 0) { + regmap_update_bits(regmap, + BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK, + 0x01, 0x01); + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); } + } + if (tx_priv->swr_clk_users == 0) { dev_dbg(tx_priv->dev, "%s: reset_swr: %d\n", __func__, tx_priv->reset_swr); if (tx_priv->reset_swr) @@ -1534,12 +1538,12 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, regmap_update_bits(regmap, BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, 0x02, 0x00); - ret = bolero_clk_rsc_request_clock(tx_priv->dev, - TX_CORE_CLK, - TX_CORE_CLK, - false); tx_priv->reset_swr = false; } + ret = bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + false); tx_priv->swr_clk_users++; } else { if (tx_priv->swr_clk_users <= 0) { @@ -1548,44 +1552,44 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, tx_priv->swr_clk_users = 0; return 0; } + ret = bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + true); tx_priv->swr_clk_users--; - if (tx_priv->swr_clk_users == 0) { - ret = bolero_clk_rsc_request_clock(tx_priv->dev, - TX_CORE_CLK, - TX_CORE_CLK, - true); + if (tx_priv->swr_clk_users == 0) regmap_update_bits(regmap, BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x00); - if (clk_type == TX_MCLK) - tx_macro_mclk_enable(tx_priv, 0); - if (clk_type == VA_MCLK) { - if (tx_priv->tx_mclk_users == 0) { - regmap_update_bits(regmap, - BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, - 0x01, 0x00); - regmap_update_bits(regmap, - BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, - 0x01, 0x00); - } - ret = bolero_clk_rsc_request_clock(tx_priv->dev, - TX_CORE_CLK, - VA_CORE_CLK, - false); - if (ret < 0) { - dev_err_ratelimited(tx_priv->dev, - "%s: swr request clk failed\n", - __func__); - goto done; - } + if (clk_type == TX_MCLK) + tx_macro_mclk_enable(tx_priv, 0); + if (clk_type == VA_MCLK) { + if (tx_priv->tx_mclk_users == 0) { + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x00); + regmap_update_bits(regmap, + BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x00); } ret = bolero_clk_rsc_request_clock(tx_priv->dev, TX_CORE_CLK, - TX_CORE_CLK, + VA_CORE_CLK, false); + if (ret < 0) { + dev_err_ratelimited(tx_priv->dev, + "%s: swr request clk failed\n", + __func__); + goto done; + } + } + ret = bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + false); + if (tx_priv->swr_clk_users == 0) msm_cdc_pinctrl_select_sleep_state( tx_priv->tx_swr_gpio_p); - } } return 0; @@ -1609,53 +1613,66 @@ static int tx_macro_swrm_clock(void *handle, bool enable) } mutex_lock(&tx_priv->swr_clk_lock); - dev_dbg(tx_priv->dev, "%s: swrm clock %s\n", - __func__, (enable ? "enable" : "disable")); + dev_dbg(tx_priv->dev, + "%s: swrm clock %s tx_swr_clk_cnt: %d va_swr_clk_cnt: %d\n", + __func__, (enable ? "enable" : "disable"), + tx_priv->tx_swr_clk_cnt, tx_priv->va_swr_clk_cnt); if (enable) { pm_runtime_get_sync(tx_priv->dev); - /*For standalone VA usecase, enable VA macro clock */ - if (tx_priv->va_swr_clk_cnt && !tx_priv->tx_swr_clk_cnt - && (tx_priv->swr_clk_type == TX_MCLK)) { + if (tx_priv->va_swr_clk_cnt && !tx_priv->tx_swr_clk_cnt) { ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap, VA_MCLK, enable); if (ret) goto done; - tx_priv->swr_clk_type = VA_MCLK; + tx_priv->va_clk_status++; } else { - /* Disable VA MCLK if its already enabled */ - if (tx_priv->swr_clk_type == VA_MCLK) - tx_macro_tx_va_mclk_enable(tx_priv, - regmap, VA_MCLK, false); ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap, TX_MCLK, enable); if (ret) goto done; - tx_priv->swr_clk_type = TX_MCLK; + tx_priv->tx_clk_status++; } pm_runtime_mark_last_busy(tx_priv->dev); pm_runtime_put_autosuspend(tx_priv->dev); } else { - if (tx_priv->swr_clk_type == VA_MCLK) { + if (tx_priv->va_clk_status && !tx_priv->tx_clk_status) { ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap, VA_MCLK, enable); if (ret) goto done; - tx_priv->swr_clk_type = TX_MCLK; - } else { + --tx_priv->va_clk_status; + } else if (!tx_priv->va_clk_status && tx_priv->tx_clk_status) { ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap, TX_MCLK, enable); - if (tx_priv->va_swr_clk_cnt) { - ret = tx_macro_tx_va_mclk_enable(tx_priv, - regmap, VA_MCLK, true); + if (ret) + goto done; + --tx_priv->tx_clk_status; + } else if (tx_priv->va_clk_status && tx_priv->tx_clk_status) { + if (!tx_priv->va_swr_clk_cnt && tx_priv->tx_swr_clk_cnt) { + ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap, + VA_MCLK, enable); if (ret) goto done; - tx_priv->swr_clk_type = VA_MCLK; + --tx_priv->va_clk_status; + } else { + ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap, + TX_MCLK, enable); + if (ret) + goto done; + --tx_priv->tx_clk_status; } + + } else { + dev_dbg(tx_priv->dev, + "%s: Both clocks are disabled\n", __func__); } } - dev_dbg(tx_priv->dev, "%s: swrm clock users %d\n", - __func__, tx_priv->swr_clk_users); + + dev_dbg(tx_priv->dev, + "%s: swrm clock users %d tx_clk_sts_cnt: %d va_clk_sts_cnt: %d\n", + __func__, tx_priv->swr_clk_users, tx_priv->tx_clk_status, + tx_priv->va_clk_status); done: mutex_unlock(&tx_priv->swr_clk_lock); return ret; -- GitLab From 72753620d0fcb673e5d44cfb069b157cfa988dbf Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 23 Apr 2019 13:56:58 +0530 Subject: [PATCH 0966/1645] ASoC: wcd937x: Fix invalid memory access in wcd937x_suspend Invalid memory access happens in wcd937x_suspend if component bind for slave fails. This is because as part of component_unbind devres_release_group is called which removes every node from list and frees corresponding memory. This results in invalid memory access for wcd937x in wcd937x_suspend. Do kfree and set drvdata to NULL if component_bind fails to resolve the issue. Change-Id: Ia26eb36fe8b92ac0491b03d0d4a2b8def415148b Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index bde3a7e84faa..0c56a0a3330d 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -2601,7 +2601,7 @@ struct wcd937x_pdata *wcd937x_populate_dt_data(struct device *dev) { struct wcd937x_pdata *pdata = NULL; - pdata = devm_kzalloc(dev, sizeof(struct wcd937x_pdata), + pdata = kzalloc(sizeof(struct wcd937x_pdata), GFP_KERNEL); if (!pdata) return NULL; @@ -2665,7 +2665,7 @@ static int wcd937x_bind(struct device *dev) struct wcd937x_pdata *pdata = NULL; struct wcd_ctrl_platform_data *plat_data = NULL; - wcd937x = devm_kzalloc(dev, sizeof(struct wcd937x_priv), GFP_KERNEL); + wcd937x = kzalloc(sizeof(struct wcd937x_priv), GFP_KERNEL); if (!wcd937x) return -ENOMEM; @@ -2684,31 +2684,35 @@ static int wcd937x_bind(struct device *dev) if (!wcd937x->supplies) { dev_err(dev, "%s: Cannot init wcd supplies\n", __func__); - return ret; + goto err_bind_all; } plat_data = dev_get_platdata(dev->parent); if (!plat_data) { dev_err(dev, "%s: platform data from parent is NULL\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto err_bind_all; } wcd937x->handle = (void *)plat_data->handle; if (!wcd937x->handle) { dev_err(dev, "%s: handle is NULL\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto err_bind_all; } wcd937x->update_wcd_event = plat_data->update_wcd_event; if (!wcd937x->update_wcd_event) { dev_err(dev, "%s: update_wcd_event api is null!\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto err_bind_all; } wcd937x->register_notifier = plat_data->register_notifier; if (!wcd937x->register_notifier) { dev_err(dev, "%s: register_notifier api is null!\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto err_bind_all; } ret = msm_cdc_enable_static_supplies(dev, wcd937x->supplies, @@ -2717,7 +2721,7 @@ static int wcd937x_bind(struct device *dev) if (ret) { dev_err(dev, "%s: wcd static supply enable failed!\n", __func__); - return ret; + goto err_bind_all; } wcd937x_reset(dev); @@ -2733,7 +2737,7 @@ static int wcd937x_bind(struct device *dev) if (ret) { dev_err(dev, "%s: Slave bind failed, ret = %d\n", __func__, ret); - return ret; + goto err_bind_all; } ret = wcd937x_parse_port_mapping(dev, "qcom,rx_swr_ch_map", CODEC_RX); @@ -2820,18 +2824,26 @@ static int wcd937x_bind(struct device *dev) wcd_irq_exit(&wcd937x->irq_info, wcd937x->virq); err: component_unbind_all(dev, wcd937x); +err_bind_all: + dev_set_drvdata(dev, NULL); + kfree(pdata); + kfree(wcd937x); return ret; } static void wcd937x_unbind(struct device *dev) { struct wcd937x_priv *wcd937x = dev_get_drvdata(dev); + struct wcd937x_pdata *pdata = dev_get_platdata(wcd937x->dev); wcd_irq_exit(&wcd937x->irq_info, wcd937x->virq); snd_soc_unregister_component(dev); component_unbind_all(dev, wcd937x); mutex_destroy(&wcd937x->micb_lock); mutex_destroy(&wcd937x->ana_tx_clk_lock); + dev_set_drvdata(dev, NULL); + kfree(pdata); + kfree(wcd937x); } static const struct of_device_id wcd937x_dt_match[] = { @@ -2901,6 +2913,8 @@ static int wcd937x_probe(struct platform_device *pdev) static int wcd937x_remove(struct platform_device *pdev) { component_master_del(&pdev->dev, &wcd937x_comp_ops); + dev_set_drvdata(&pdev->dev, NULL); + return 0; } -- GitLab From cde71a9c9c0ce8b5f0a4c636a5a78eb23b82e747 Mon Sep 17 00:00:00 2001 From: Zhou Song Date: Wed, 20 Mar 2019 13:51:30 +0800 Subject: [PATCH 0967/1645] asoc: dsp: do extention to support aptx adaptive R2 Extend the encoder configuration to support aptx adaptive R2. Change-Id: I17d7adb62539d9f59222fd0c992424ba98395383 Signed-off-by: Zhou Song --- asoc/msm-dai-q6-v2.c | 9 +++++++++ include/dsp/apr_audio-v2.h | 3 +++ 2 files changed, 12 insertions(+) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index d4f33c74a948..5c920436ed88 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -3207,6 +3207,15 @@ static const struct snd_kcontrol_new afe_enc_config_controls[] = { .get = msm_dai_q6_afe_enc_cfg_get, .put = msm_dai_q6_afe_enc_cfg_put, }, + { + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_INACTIVE), + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "SLIM_7_RX APTX_AD Enc Cfg", + .info = msm_dai_q6_afe_enc_cfg_info, + .get = msm_dai_q6_afe_enc_cfg_get, + .put = msm_dai_q6_afe_enc_cfg_put, + }, SOC_ENUM_EXT("AFE Input Channels", afe_chs_enum[0], msm_dai_q6_afe_input_channel_get, msm_dai_q6_afe_input_channel_put), diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index e7c132a69587..b739ea0f9217 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -3852,6 +3852,9 @@ struct afe_id_aptx_adaptive_enc_init uint32_t min_sink_modeC; uint32_t max_sink_modeC; uint32_t mode; + uint32_t input_mode; + uint32_t fade_duration; + uint8_t sink_cap[11]; } __attribute__ ((packed)); /* -- GitLab From 845b66f42a87aa083b308f8eb0f2f83448e37e73 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Mon, 15 Apr 2019 15:44:28 -0700 Subject: [PATCH 0968/1645] asoc: msm-lsm-client: add support for shared buffer DAM module A new module called DAM is introduced to achieve common shared memory for SVA use cases in LPI. Add new mixer control interface to provide support for STHAL to configure the data that LSM gets from AFE to be either processed or unprocessed. Change-Id: I8556413257c6a2aee4739bcd89ffd130805af0c5 Signed-off-by: Xiaoyu Ye --- asoc/msm-lsm-client.c | 73 ++++++++++++++++++++++++++++++++++++++- dsp/q6lsm.c | 80 +++++++++++++++++++++++++++++++++++++++++++ include/dsp/q6lsm.h | 8 +++-- 3 files changed, 158 insertions(+), 3 deletions(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 3a5707e0de8d..ff77e90ed58e 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -2425,6 +2425,7 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct lsm_priv *prtd; + struct snd_soc_pcm_runtime *rtd = substream->private_data; int ret = 0; pr_debug("%s\n", __func__); @@ -2488,6 +2489,8 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) prtd->lsm_client->perf_mode = 0; prtd->lsm_client->event_mode = LSM_EVENT_NON_TIME_STAMP_MODE; prtd->lsm_client->event_type = LSM_DET_EVENT_TYPE_LEGACY; + prtd->lsm_client->fe_id = rtd->dai_link->id; + prtd->lsm_client->unprocessed_data = 0; return 0; } @@ -2958,13 +2961,81 @@ static int msm_lsm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd) return 0; } +static int msm_lsm_afe_data_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + uint16_t afe_data_format = 0; + int ret = 0; + + afe_data_format = ucontrol->value.integer.value[0]; + pr_debug("%s: afe data is %s\n", __func__, + afe_data_format ? "unprocessed" : "processed"); + + ret = q6lsm_set_afe_data_format(fe_id, afe_data_format); + if (ret) + pr_err("%s: q6lsm_set_afe_data_format failed, ret = %d\n", + __func__, ret); + + return ret; +} + +static int msm_lsm_afe_data_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u64 fe_id = kcontrol->private_value; + uint16_t afe_data_format = 0; + int ret = 0; + + q6lsm_get_afe_data_format(fe_id, &afe_data_format); + ucontrol->value.integer.value[0] = afe_data_format; + pr_debug("%s: afe data is %s\n", __func__, + afe_data_format ? "unprocessed" : "processed"); + + return ret; +} + +static int msm_lsm_add_afe_data_controls(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_pcm *pcm = rtd->pcm; + struct snd_pcm_usr *afe_data_info; + struct snd_kcontrol *kctl; + const char *mixer_ctl_name = "Listen Stream"; + const char *deviceNo = "NN"; + const char *suffix = "Unprocessed Data"; + int ctl_len, ret = 0; + + ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 + + strlen(suffix) + 1; + pr_debug("%s: Adding Listen afe data cntrls\n", __func__); + ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE, + NULL, 1, ctl_len, rtd->dai_link->id, + &afe_data_info); + if (ret < 0) { + pr_err("%s: Adding Listen afe data cntrls failed: %d\n", + __func__, ret); + return ret; + } + kctl = afe_data_info->kctl; + snprintf(kctl->id.name, ctl_len, "%s %d %s", + mixer_ctl_name, rtd->pcm->device, suffix); + kctl->put = msm_lsm_afe_data_ctl_put; + kctl->get = msm_lsm_afe_data_ctl_get; + + return 0; +} + static int msm_lsm_add_controls(struct snd_soc_pcm_runtime *rtd) { int ret = 0; ret = msm_lsm_add_app_type_controls(rtd); if (ret) - pr_err("%s, add app type controls failed:%d\n", __func__, ret); + pr_err("%s, add app type controls failed:%d\n", __func__, ret); + + ret = msm_lsm_add_afe_data_controls(rtd); + if (ret) + pr_err("%s, add afe data controls failed:%d\n", __func__, ret); return ret; } diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 96671ec60c99..d55dfc313c39 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -89,6 +89,13 @@ static int q6lsm_memory_map_regions(struct lsm_client *client, static int q6lsm_memory_unmap_regions(struct lsm_client *client, uint32_t handle); +struct lsm_client_afe_data { + uint64_t fe_id; + uint16_t unprocessed_data; +}; + +static struct lsm_client_afe_data lsm_client_afe_data[LSM_MAX_SESSION_ID + 1]; + static int q6lsm_get_session_id_from_lsm_client(struct lsm_client *client) { int n; @@ -255,6 +262,8 @@ static void q6lsm_session_free(struct lsm_client *client) pr_debug("%s: Freeing session ID %d\n", __func__, client->session); spin_lock_irqsave(&lsm_session_lock, flags); lsm_session[client->session] = NULL; + lsm_client_afe_data[client->session].fe_id = 0; + lsm_client_afe_data[client->session].unprocessed_data = 0; spin_unlock_irqrestore(&lsm_session_lock, flags); client->session = LSM_INVALID_SESSION_ID; } @@ -1062,6 +1071,72 @@ int get_lsm_port(void) return lsm_afe_port; } +/** + * q6lsm_set_afe_data_format - + * command to set afe data format + * + * @fe_id: FrontEnd DAI link ID + * @afe_data_format: afe data format + * + * Returns 0 on success or -EINVAL on failure + */ +int q6lsm_set_afe_data_format(uint64_t fe_id, uint16_t afe_data_format) +{ + int n = 0; + + if (0 != afe_data_format && 1 != afe_data_format) + goto done; + + pr_debug("%s: afe data is %s\n", __func__, + afe_data_format ? "unprocessed" : "processed"); + + for (n = LSM_MIN_SESSION_ID; n <= LSM_MAX_SESSION_ID; n++) { + if (0 == lsm_client_afe_data[n].fe_id) { + lsm_client_afe_data[n].fe_id = fe_id; + lsm_client_afe_data[n].unprocessed_data = + afe_data_format; + pr_debug("%s: session ID is %d, fe_id is %d\n", + __func__, n, fe_id); + return 0; + } + } + + pr_err("%s: all lsm sessions are taken\n", __func__); +done: + return -EINVAL; +} +EXPORT_SYMBOL(q6lsm_set_afe_data_format); + +/** + * q6lsm_get_afe_data_format - + * command to get afe data format + * + * @fe_id: FrontEnd DAI link ID + * @afe_data_format: afe data format + * + */ +void q6lsm_get_afe_data_format(uint64_t fe_id, uint16_t *afe_data_format) +{ + int n = 0; + + if (NULL == afe_data_format) { + pr_err("%s: Pointer afe_data_format is NULL\n", __func__); + return; + } + + for (n = LSM_MIN_SESSION_ID; n <= LSM_MAX_SESSION_ID; n++) { + if (fe_id == lsm_client_afe_data[n].fe_id) { + *afe_data_format = + lsm_client_afe_data[n].unprocessed_data; + pr_debug("%s: session: %d, fe_id: %d, afe data: %s\n", + __func__, n, fe_id, + *afe_data_format ? "unprocessed" : "processed"); + return; + } + } +} +EXPORT_SYMBOL(q6lsm_get_afe_data_format); + /** * q6lsm_set_port_connected - * command to set LSM port connected @@ -1092,14 +1167,19 @@ int q6lsm_set_port_connected(struct lsm_client *client) connectport_hdr.param_size = sizeof(connect_port); client->connect_to_port = get_lsm_port(); + if (ADM_LSM_PORT_ID != client->connect_to_port) + q6lsm_get_afe_data_format(client->fe_id, + &client->unprocessed_data); connect_port.minor_version = QLSM_PARAM_ID_MINOR_VERSION; connect_port.port_id = client->connect_to_port; + connect_port.unprocessed_data = client->unprocessed_data; rc = q6lsm_pack_and_set_params(client, &connectport_hdr, (uint8_t *) &connect_port, set_param_opcode); if (rc) pr_err("%s: Failed set_params, rc %d\n", __func__, rc); + return rc; } EXPORT_SYMBOL(q6lsm_set_port_connected); diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h index e4a007f85356..af43cdd4cbf3 100644 --- a/include/dsp/q6lsm.h +++ b/include/dsp/q6lsm.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. */ #ifndef __Q6LSM_H__ #define __Q6LSM_H__ @@ -102,6 +102,8 @@ struct lsm_client { uint32_t event_type; uint32_t num_stages; struct lsm_stage_config stage_cfg[LSM_MAX_STAGES_PER_SESSION]; + uint64_t fe_id; + uint16_t unprocessed_data; }; struct lsm_stream_cmd_open_tx { @@ -159,7 +161,7 @@ struct lsm_param_connect_to_port { uint32_t minor_version; /* AFE port id that receives voice wake up data */ uint16_t port_id; - uint16_t reserved; + uint16_t unprocessed_data; } __packed; struct lsm_param_poll_enable { @@ -295,4 +297,6 @@ int q6lsm_set_media_fmt_v2_params(struct lsm_client *client); int q6lsm_lab_out_ch_cfg(struct lsm_client *client, u8 *ch_map, struct lsm_params_info_v2 *p_info); bool q6lsm_adsp_supports_multi_stage_detection(void); +int q6lsm_set_afe_data_format(uint64_t fe_id, uint16_t afe_data_format); +void q6lsm_get_afe_data_format(uint64_t fe_id, uint16_t *afe_data_format); #endif /* __Q6LSM_H__ */ -- GitLab From 3fc2d77434f8a3acda6658a618c1aa0e7ba72294 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 11 May 2019 14:11:29 +0530 Subject: [PATCH 0969/1645] ASoC: Kona: Add ignore suspend for Digital Mic4 and Digital Mic5 Add ignore suspend for digital mic4 and digital mic5 to avoid suspend during system suspend. Change-Id: I13d70510e56835867ee7a56a6af9bf223a64b751 Signed-off-by: Sudheer Papothi --- asoc/kona.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/kona.c b/asoc/kona.c index 50a25b17ffe3..a47a3886c44c 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -4255,6 +4255,8 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); snd_soc_dapm_ignore_suspend(dapm, "Analog Mic1"); snd_soc_dapm_ignore_suspend(dapm, "Analog Mic2"); -- GitLab From c141ca9e3da36fd2b39d557d90770320413cb9e0 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 13 May 2019 14:40:55 -0700 Subject: [PATCH 0970/1645] asoc: codecs: bolero: Reset power mode register at teardown Reset the compander power mode register to default value upon teardown sequence, so that at next startup use case it has proper power value. Change-Id: I851e8a62a910d7018ac74e93abee47a615b3e50c Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/rx-macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index e43fa6231f9e..3d2397cfeb8d 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -2177,7 +2177,7 @@ static void rx_macro_hphdelay_lutbypass(struct snd_soc_component *component, snd_soc_component_update_bits(component, hph_lut_bypass_reg, 0x80, 0x00); snd_soc_component_update_bits(component, hph_comp_ctrl7, - 0x20, 0x0); + 0x20, 0x20); } } -- GitLab From 8e14752f35b289bfa2e84c5e18f1586bf8e9892e Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 13 May 2019 15:14:46 -0700 Subject: [PATCH 0971/1645] audio-kernel: Add support to compile statically on Kona Add include and source paths to support compilation of audio drivers into kernel image on Kona. Change-Id: I41b5ef7e5d20d517193e8295a61035a28692cb32 Signed-off-by: Karthikeyan Mani --- Makefile | 8 ++++++++ asoc/codecs/Kbuild | 2 ++ 2 files changed, 10 insertions(+) diff --git a/Makefile b/Makefile index d9d093bde49d..8daa4601fa74 100644 --- a/Makefile +++ b/Makefile @@ -11,10 +11,14 @@ ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(srctree)/techpack/audio/config/sm8150auto.conf export endif +ifeq ($(CONFIG_ARCH_KONA), y) +include $(srctree)/techpack/audio/config/konaauto.conf +endif # Use USERINCLUDE when you must reference the UAPI directories only. USERINCLUDE += \ -I$(srctree)/techpack/audio/include/uapi \ + -I$(srctree)/techpack/audio/include # Use LINUXINCLUDE when you must reference the include/ directory. # Needed to be compatible with the O= option @@ -34,6 +38,10 @@ ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) LINUXINCLUDE += \ -include $(srctree)/techpack/audio/config/sm8150autoconf.h endif +ifeq ($(CONFIG_ARCH_KONA), y) +LINUXINCLUDE += \ + -include $(srctree)/techpack/audio/config/konaautoconf.h +endif obj-y += soc/ obj-y += dsp/ diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index df8657845f0d..e18a40b57d3f 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -196,6 +196,8 @@ endif ifeq ($(KERNEL_BUILD), 1) obj-y += wcd934x/ obj-y += wcd937x/ + obj-y += wcd938x/ + obj-y += bolero/ endif # Module information used by KBuild framework obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd_core_dlkm.o -- GitLab From 150c909ba3dffac2b907af6fb3cebb424eeff1df Mon Sep 17 00:00:00 2001 From: Timothy Sham Date: Sat, 16 Feb 2019 02:13:59 -0500 Subject: [PATCH 0972/1645] ipc: add audio apr virtualization support Add support for virtualized APR frontend driver for audio. Virtualized APR frontend driver resides in guest VM and supports all legacy APR APIs. It will rely on MSM_HAB to communicate with APR backend driver, which resides in physical VM, where legacy SMD is utilized for communication between APPS and ADSP. Change-Id: I1df70a76defec17a45db93f3707c35e4fa796bc0 Signed-off-by: Timothy Sham --- include/ipc/apr.h | 6 +- include/ipc/aprv2_vm.h | 108 +++ ipc/Kbuild | 6 + ipc/apr_vm.c | 1477 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1596 insertions(+), 1 deletion(-) create mode 100644 include/ipc/aprv2_vm.h create mode 100644 ipc/apr_vm.c diff --git a/include/ipc/apr.h b/include/ipc/apr.h index 79d87dc0f8a3..7aecee265530 100644 --- a/include/ipc/apr.h +++ b/include/ipc/apr.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2017, 2019, The Linux Foundation. All rights reserved. */ #ifndef __APR_H_ #define __APR_H_ @@ -129,6 +129,10 @@ struct apr_svc { struct mutex m_lock; spinlock_t w_lock; uint8_t pkt_owner; +#ifdef CONFIG_MSM_QDSP6_APRV2_VM + uint16_t vm_dest_svc; + uint32_t vm_handle; +#endif }; struct apr_client { diff --git a/include/ipc/aprv2_vm.h b/include/ipc/aprv2_vm.h new file mode 100644 index 000000000000..ce61c1a2b2f3 --- /dev/null +++ b/include/ipc/aprv2_vm.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. + */ +#ifndef __APRV2_VM_H__ +#define __APRV2_VM_H__ + +#define APRV2_VM_MAX_DNS_SIZE (31) + /* Includes NULL character. */ +#define APRV2_VM_PKT_SERVICE_ID_MASK (0x00FF) + /* Bitmask of the service ID field. */ + +/* Packet Structure Definition */ +struct aprv2_vm_packet_t { + uint32_t header; + uint16_t src_addr; + uint16_t src_port; + uint16_t dst_addr; + uint16_t dst_port; + uint32_t token; + uint32_t opcode; +}; + +/** + * In order to send command/event via MM HAB, the following buffer + * format shall be followed, where the buffer is provided to the + * HAB send API. + * |-----cmd_id or evt_id -----| <- 32 bit, e.g. APRV2_VM_CMDID_REGISTER + * |-----cmd payload ----------| e.g. aprv2_vm_cmd_register_t + * | ... | + * + * In order to receive a command response or event ack, the following + * buffer format shall be followed, where the buffer is provided to + * the HAB receive API. + * |-----cmd response ---------| e.g. aprv2_vm_cmd_register_rsp_t + * | ... | + */ + +/* Registers a service with the backend APR driver. */ +#define APRV2_VM_CMDID_REGISTER (0x00000001) + +struct aprv2_vm_cmd_register_t { + uint32_t name_size; + /**< The service name string size in bytes. */ + char name[APRV2_VM_MAX_DNS_SIZE]; + /**< + * The service name string to register. + * + * A NULL name means the service does not have a name. + */ + uint16_t addr; + /**< + * The address to register. + * + * A zero value means to auto-generate a free dynamic address. + * A non-zero value means to directly use the statically assigned address. + */ +}; + +struct aprv2_vm_cmd_register_rsp_t { + int32_t status; + /**< The status of registration. */ + uint32_t handle; + /**< The registered service handle. */ + uint16_t addr; + /**< The actual registered address. */ +}; + +#define APRV2_VM_CMDID_DEREGISTER (0x00000002) + +struct aprv2_vm_cmd_deregister_t { + uint32_t handle; + /**< The registered service handle. */ +}; + +struct aprv2_vm_cmd_deregister_rsp_t { + int32_t status; + /**< The status of de-registration. */ +}; + +#define APRV2_VM_CMDID_ASYNC_SEND (0x00000003) + +struct aprv2_vm_cmd_async_send_t { + uint32_t handle; + /**< The registered service handle. */ + struct aprv2_vm_packet_t pkt_header; + /**< The packet header. */ + /* The apr packet payload follows */ +}; + +struct aprv2_vm_cmd_async_send_rsp_t { + int32_t status; + /**< The status of send. */ +}; + +#define APRV2_VM_EVT_RX_PKT_AVAILABLE (0x00000004) + +struct aprv2_vm_evt_rx_pkt_available_t { + struct aprv2_vm_packet_t pkt_header; + /**< The packet header. */ + /* The apr packet payload follows */ +}; + +struct aprv2_vm_ack_rx_pkt_available_t { + int32_t status; +}; + +#endif /* __APRV2_VM_H__ */ diff --git a/ipc/Kbuild b/ipc/Kbuild index fb0974e6a4b1..5ab0131b493b 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -89,6 +89,11 @@ APRV_GLINK += apr_v3.o APRV_GLINK += apr_tal_rpmsg.o endif +ifdef CONFIG_MSM_QDSP6_APRV2_VM +APRV_GLINK += apr_vm.o +APRV_GLINK += apr_v2.o +endif + ifdef CONFIG_WCD_DSP_GLINK WDSP_GLINK += wcd-dsp-glink.o endif @@ -147,6 +152,7 @@ endif # Module information used by KBuild framework obj-$(CONFIG_MSM_QDSP6_APRV2_RPMSG) += apr_dlkm.o obj-$(CONFIG_MSM_QDSP6_APRV3_RPMSG) += apr_dlkm.o +obj-$(CONFIG_MSM_QDSP6_APRV2_VM) += apr_dlkm.o apr_dlkm-y := $(APRV_GLINK) obj-$(CONFIG_WCD_DSP_GLINK) += wglink_dlkm.o diff --git a/ipc/apr_vm.c b/ipc/apr_vm.c new file mode 100644 index 000000000000..f94e3a22db64 --- /dev/null +++ b/ipc/apr_vm.c @@ -0,0 +1,1477 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2010-2014, 2016-2019 The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define APR_PKT_IPC_LOG_PAGE_CNT 2 +#define APR_VM_CB_THREAD_NAME "apr_vm_cb_thread" +#define APR_TX_BUF_SIZE 4096 +#define APR_RX_BUF_SIZE 4096 + +static struct apr_q6 q6; +static struct apr_client client[APR_DEST_MAX][APR_CLIENT_MAX]; +static void *apr_pkt_ctx; +static wait_queue_head_t modem_wait; +static bool is_modem_up; +static char *subsys_name = NULL; +/* Subsystem restart: QDSP6 data, functions */ +static struct workqueue_struct *apr_reset_workqueue; +static void apr_reset_deregister(struct work_struct *work); +static void dispatch_event(unsigned long code, uint16_t proc); +struct apr_reset_work { + void *handle; + struct work_struct work; +}; + +struct apr_chld_device { + struct platform_device *pdev; + struct list_head node; +}; + +struct apr_private { + struct device *dev; + spinlock_t apr_lock; + bool is_initial_boot; + struct work_struct add_chld_dev_work; +}; + +static struct apr_private *apr_priv; +static bool apr_cf_debug; + +#ifdef CONFIG_DEBUG_FS +static struct dentry *debugfs_apr_debug; +static ssize_t apr_debug_write(struct file *filp, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + char cmd; + + if (copy_from_user(&cmd, ubuf, 1)) + return -EFAULT; + + apr_cf_debug = (cmd == '1') ? true : false; + + return cnt; +} + +static const struct file_operations apr_debug_ops = { + .write = apr_debug_write, +}; +#endif + +#define APR_PKT_INFO(x...) \ +do { \ + if (apr_pkt_ctx) \ + ipc_log_string(apr_pkt_ctx, ": "x); \ +} while (0) + +/* hab handle */ +static uint32_t hab_handle_tx; +static uint32_t hab_handle_rx; +static char apr_tx_buf[APR_TX_BUF_SIZE]; +static char apr_rx_buf[APR_RX_BUF_SIZE]; +static spinlock_t hab_tx_lock; + +/* apr callback thread task */ +static struct task_struct *apr_vm_cb_thread_task; +static int pid; + + +struct apr_svc_table { + char name[64]; + int idx; + int id; + int dest_svc; + int client_id; + int handle; +}; + +/* + * src svc should be assigned dynamically through apr registration: + * 1. replace with a proper string name for registration. + * e.g. "qcom.apps.lnx." + name + * 2. register apr BE, retrieve dynamic src svc address, + * apr handle and store in svc tbl. + */ + +static struct mutex m_lock_tbl_qdsp6; + +static struct apr_svc_table svc_tbl_qdsp6[] = { + { + .name = "AFE", + .idx = 0, + .id = 0, + .dest_svc = APR_SVC_AFE, + .client_id = APR_CLIENT_AUDIO, + .handle = 0, + }, + { + .name = "ASM", + .idx = 1, + .id = 0, + .dest_svc = APR_SVC_ASM, + .client_id = APR_CLIENT_AUDIO, + .handle = 0, + }, + { + .name = "ADM", + .idx = 2, + .id = 0, + .dest_svc = APR_SVC_ADM, + .client_id = APR_CLIENT_AUDIO, + .handle = 0, + }, + { + .name = "CORE", + .idx = 3, + .id = 0, + .dest_svc = APR_SVC_ADSP_CORE, + .client_id = APR_CLIENT_AUDIO, + .handle = 0, + }, + { + .name = "TEST", + .idx = 4, + .id = 0, + .dest_svc = APR_SVC_TEST_CLIENT, + .client_id = APR_CLIENT_AUDIO, + .handle = 0, + }, + { + .name = "MVM", + .idx = 5, + .id = 0, + .dest_svc = APR_SVC_ADSP_MVM, + .client_id = APR_CLIENT_AUDIO, + .handle = 0, + }, + { + .name = "CVS", + .idx = 6, + .id = 0, + .dest_svc = APR_SVC_ADSP_CVS, + .client_id = APR_CLIENT_AUDIO, + .handle = 0, + }, + { + .name = "CVP", + .idx = 7, + .id = 0, + .dest_svc = APR_SVC_ADSP_CVP, + .client_id = APR_CLIENT_AUDIO, + .handle = 0, + }, + { + .name = "USM", + .idx = 8, + .id = 0, + .dest_svc = APR_SVC_USM, + .client_id = APR_CLIENT_AUDIO, + .handle = 0, + }, + { + .name = "VIDC", + .idx = 9, + .id = 0, + .dest_svc = APR_SVC_VIDC, + .handle = 0, + }, + { + .name = "LSM", + .idx = 10, + .id = 0, + .dest_svc = APR_SVC_LSM, + .client_id = APR_CLIENT_AUDIO, + .handle = 0, + }, +}; + +static struct mutex m_lock_tbl_voice; + +static struct apr_svc_table svc_tbl_voice[] = { + { + .name = "VSM", + .idx = 0, + .id = 0, + .dest_svc = APR_SVC_VSM, + .client_id = APR_CLIENT_VOICE, + .handle = 0, + }, + { + .name = "VPM", + .idx = 1, + .id = 0, + .dest_svc = APR_SVC_VPM, + .client_id = APR_CLIENT_VOICE, + .handle = 0, + }, + { + .name = "MVS", + .idx = 2, + .id = 0, + .dest_svc = APR_SVC_MVS, + .client_id = APR_CLIENT_VOICE, + .handle = 0, + }, + { + .name = "MVM", + .idx = 3, + .id = 0, + .dest_svc = APR_SVC_MVM, + .client_id = APR_CLIENT_VOICE, + .handle = 0, + }, + { + .name = "CVS", + .idx = 4, + .id = 0, + .dest_svc = APR_SVC_CVS, + .client_id = APR_CLIENT_VOICE, + .handle = 0, + }, + { + .name = "CVP", + .idx = 5, + .id = 0, + .dest_svc = APR_SVC_CVP, + .client_id = APR_CLIENT_VOICE, + .handle = 0, + }, + { + .name = "SRD", + .idx = 6, + .id = 0, + .dest_svc = APR_SVC_SRD, + .client_id = APR_CLIENT_VOICE, + .handle = 0, + }, + { + .name = "TEST", + .idx = 7, + .id = 0, + .dest_svc = APR_SVC_TEST_CLIENT, + .client_id = APR_CLIENT_VOICE, + .handle = 0, + }, +}; + +/** + * apr_get_modem_state: + * + * Returns current modem load status + * + */ +enum apr_subsys_state apr_get_modem_state(void) +{ + return atomic_read(&q6.modem_state); +} +EXPORT_SYMBOL(apr_get_modem_state); + +/** + * apr_set_modem_state - Update modem load status. + * + * @state: State to update modem load status + * + */ +void apr_set_modem_state(enum apr_subsys_state state) +{ + atomic_set(&q6.modem_state, state); +} +EXPORT_SYMBOL(apr_set_modem_state); + +enum apr_subsys_state apr_cmpxchg_modem_state(enum apr_subsys_state prev, + enum apr_subsys_state new) +{ + return atomic_cmpxchg(&q6.modem_state, prev, new); +} + +static void apr_modem_down(unsigned long opcode) +{ + apr_set_modem_state(APR_SUBSYS_DOWN); + dispatch_event(opcode, APR_DEST_MODEM); +} + +static void apr_modem_up(void) +{ + if (apr_cmpxchg_modem_state(APR_SUBSYS_DOWN, APR_SUBSYS_UP) == + APR_SUBSYS_DOWN) + wake_up(&modem_wait); + is_modem_up = 1; +} + +enum apr_subsys_state apr_get_q6_state(void) +{ + return atomic_read(&q6.q6_state); +} +EXPORT_SYMBOL(apr_get_q6_state); + +int apr_set_q6_state(enum apr_subsys_state state) +{ + pr_debug("%s: setting adsp state %d\n", __func__, state); + if (state < APR_SUBSYS_DOWN || state > APR_SUBSYS_LOADED) + return -EINVAL; + atomic_set(&q6.q6_state, state); + return 0; +} +EXPORT_SYMBOL(apr_set_q6_state); + +static void apr_ssr_disable(struct device *dev, void *data) +{ + apr_set_q6_state(APR_SUBSYS_DOWN); +} + +static const struct snd_event_ops apr_ssr_ops = { + .disable = apr_ssr_disable, +}; + +static void apr_adsp_down(unsigned long opcode) +{ + pr_info("%s: Q6 is Down\n", __func__); + snd_event_notify(apr_priv->dev, SND_EVENT_DOWN); + apr_set_q6_state(APR_SUBSYS_DOWN); + dispatch_event(opcode, APR_DEST_QDSP6); +} + +static void apr_add_child_devices(struct work_struct *work) +{ + int ret; + + ret = of_platform_populate(apr_priv->dev->of_node, + NULL, NULL, apr_priv->dev); + if (ret) + dev_err(apr_priv->dev, "%s: failed to add child nodes, ret=%d\n", + __func__, ret); +} + +static void apr_adsp_up(void) +{ + pr_info("%s: Q6 is Up\n", __func__); + apr_set_q6_state(APR_SUBSYS_LOADED); + + spin_lock(&apr_priv->apr_lock); + if (apr_priv->is_initial_boot) + schedule_work(&apr_priv->add_chld_dev_work); + spin_unlock(&apr_priv->apr_lock); + snd_event_notify(apr_priv->dev, SND_EVENT_UP); +} + +int apr_load_adsp_image(void) +{ + int rc = 0; + + mutex_lock(&q6.lock); + if (apr_get_q6_state() == APR_SUBSYS_UP) { + q6.pil = subsystem_get("adsp"); + if (IS_ERR(q6.pil)) { + rc = PTR_ERR(q6.pil); + pr_err("APR: Unable to load q6 image, error:%d\n", rc); + } else { + apr_set_q6_state(APR_SUBSYS_LOADED); + pr_debug("APR: Image is loaded, stated\n"); + } + } else if (apr_get_q6_state() == APR_SUBSYS_LOADED) { + pr_debug("APR: q6 image already loaded\n"); + } else { + pr_debug("APR: cannot load state %d\n", apr_get_q6_state()); + } + mutex_unlock(&q6.lock); + return rc; +} + +struct apr_client *apr_get_client(int dest_id, int client_id) +{ + return &client[dest_id][client_id]; +} + +static int apr_vm_nb_receive(int32_t handle, void *dest_buff, + uint32_t *size_bytes, uint32_t timeout) +{ + int rc; + uint32_t dest_buff_bytes = *size_bytes; + unsigned long delay = jiffies + (HZ / 2); + + do { + *size_bytes = dest_buff_bytes; + rc = habmm_socket_recv(handle, + dest_buff, + size_bytes, + timeout, + HABMM_SOCKET_RECV_FLAGS_NON_BLOCKING); + } while (time_before(jiffies, delay) && (rc == -EAGAIN) && + (*size_bytes == 0)); + + return rc; +} + +static int apr_vm_cb_process_evt(char *buf, int len) +{ + struct apr_client_data data = {0,}; + struct apr_client *apr_client; + struct apr_svc *c_svc; + struct apr_hdr *hdr; + uint16_t hdr_size; + uint16_t msg_type; + uint16_t ver; + uint16_t src; + uint16_t svc; + uint16_t clnt; + int i; + int temp_port = 0; + uint32_t *ptr; + uint32_t evt_id; + + pr_debug("APR: len = %d\n", len); + ptr = (uint32_t *)buf; + pr_debug("\n*****************\n"); + for (i = 0; i < len/4; i++) + pr_debug("%x ", ptr[i]); + pr_debug("\n"); + pr_debug("\n*****************\n"); + + if (!buf || len <= APR_HDR_SIZE + sizeof(uint32_t)) { + pr_err("APR: Improper apr pkt received: %p %d\n", buf, len); + return -EINVAL; + } + + evt_id = *((int32_t *)buf); + if (evt_id != APRV2_VM_EVT_RX_PKT_AVAILABLE) { + pr_err("APR: Wrong evt id: %d\n", evt_id); + return -EINVAL; + } + hdr = (struct apr_hdr *)(buf + sizeof(uint32_t)); + + ver = hdr->hdr_field; + ver = (ver & 0x000F); + if (ver > APR_PKT_VER + 1) { + pr_err("APR: Wrong version: %d\n", ver); + return -EINVAL; + } + + hdr_size = hdr->hdr_field; + hdr_size = ((hdr_size & 0x00F0) >> 0x4) * 4; + if (hdr_size < APR_HDR_SIZE) { + pr_err("APR: Wrong hdr size:%d\n", hdr_size); + return -EINVAL; + } + + if (hdr->pkt_size < APR_HDR_SIZE) { + pr_err("APR: Wrong paket size\n"); + return -EINVAL; + } + + msg_type = hdr->hdr_field; + msg_type = (msg_type >> 0x08) & 0x0003; + if (msg_type >= APR_MSG_TYPE_MAX && msg_type != APR_BASIC_RSP_RESULT) { + pr_err("APR: Wrong message type: %d\n", msg_type); + return -EINVAL; + } + + /* + * dest_svc is dynamic created by apr service + * no need to check the range of dest_svc + */ + if (hdr->src_domain >= APR_DOMAIN_MAX || + hdr->dest_domain >= APR_DOMAIN_MAX || + hdr->src_svc >= APR_SVC_MAX) { + pr_err("APR: Wrong APR header\n"); + return -EINVAL; + } + + svc = hdr->dest_svc; + if (hdr->src_domain == APR_DOMAIN_MODEM) + clnt = APR_CLIENT_VOICE; + else if (hdr->src_domain == APR_DOMAIN_ADSP) + clnt = APR_CLIENT_AUDIO; + else { + pr_err("APR: Pkt from wrong source: %d\n", hdr->src_domain); + return -EINVAL; + } + + src = apr_get_data_src(hdr); + if (src == APR_DEST_MAX) + return -EINVAL; + + pr_debug("src =%d clnt = %d\n", src, clnt); + apr_client = &client[src][clnt]; + for (i = 0; i < APR_SVC_MAX; i++) + if (apr_client->svc[i].id == svc) { + pr_debug("svc_id = %d\n", apr_client->svc[i].id); + c_svc = &apr_client->svc[i]; + break; + } + + if (i == APR_SVC_MAX) { + pr_err("APR: service is not registered\n"); + return -ENXIO; + } + + pr_debug("svc_idx = %d\n", i); + pr_debug("%x %x %x %p %p\n", c_svc->id, c_svc->dest_id, + c_svc->client_id, c_svc->fn, c_svc->priv); + + data.payload_size = hdr->pkt_size - hdr_size; + data.opcode = hdr->opcode; + data.src = src; + data.src_port = hdr->src_port; + data.dest_port = hdr->dest_port; + data.token = hdr->token; + data.msg_type = msg_type; + if (data.payload_size > 0) + data.payload = (char *)hdr + hdr_size; + + if (unlikely(apr_cf_debug)) { + if (hdr->opcode == APR_BASIC_RSP_RESULT && data.payload) { + uint32_t *ptr = data.payload; + + APR_PKT_INFO( + "Rx: src_addr[0x%X] dest_addr[0x%X] opcode[0x%X] token[0x%X] rc[0x%X]", + (hdr->src_domain << 8) | hdr->src_svc, + (hdr->dest_domain << 8) | hdr->dest_svc, + hdr->opcode, hdr->token, ptr[1]); + } else { + APR_PKT_INFO( + "Rx: src_addr[0x%X] dest_addr[0x%X] opcode[0x%X] token[0x%X]", + (hdr->src_domain << 8) | hdr->src_svc, + (hdr->dest_domain << 8) | hdr->dest_svc, hdr->opcode, + hdr->token); + } + } + + temp_port = ((data.dest_port >> 8) * 8) + (data.dest_port & 0xFF); + pr_debug("port = %d t_port = %d\n", data.src_port, temp_port); + if (((temp_port >= 0) && (temp_port < APR_MAX_PORTS)) + && (c_svc->port_cnt && c_svc->port_fn[temp_port])) + c_svc->port_fn[temp_port](&data, c_svc->port_priv[temp_port]); + else if (c_svc->fn) + c_svc->fn(&data, c_svc->priv); + else + pr_err("APR: Rxed a packet for NULL callback\n"); + + return 0; +} + +static int apr_vm_cb_thread(void *data) +{ + uint32_t apr_rx_buf_len; + struct aprv2_vm_ack_rx_pkt_available_t apr_ack; + unsigned long delay = jiffies + (HZ / 2); + int status = 0; + int ret = 0; + + while (1) { + do { + apr_rx_buf_len = sizeof(apr_rx_buf); + ret = habmm_socket_recv(hab_handle_rx, + (void *)&apr_rx_buf, + &apr_rx_buf_len, + 0xFFFFFFFF, + 0); + } while (time_before(jiffies, delay) && (ret == -EINTR) && + (apr_rx_buf_len == 0)); + if (ret) { + pr_err("%s: habmm_socket_recv failed %d\n", + __func__, ret); + break; + } + + status = apr_vm_cb_process_evt(apr_rx_buf, apr_rx_buf_len); + + apr_ack.status = status; + ret = habmm_socket_send(hab_handle_rx, + (void *)&apr_ack, + sizeof(apr_ack), + 0); + if (ret) { + pr_err("%s: habmm_socket_send failed %d\n", + __func__, ret); + /* TODO: break if send failed ? */ + break; + } + } + + return ret; +} + +static int apr_vm_get_svc(const char *svc_name, int domain_id, int *client_id, + int *svc_idx, int *svc_id, int *dest_svc, int *handle) +{ + int i; + int size; + struct apr_svc_table *tbl; + struct mutex *lock; + struct aprv2_vm_cmd_register_rsp_t apr_rsp; + uint32_t apr_len; + int ret = 0; + struct { + uint32_t cmd_id; + struct aprv2_vm_cmd_register_t reg_cmd; + } tx_data; + + if (domain_id == APR_DOMAIN_ADSP) { + tbl = svc_tbl_qdsp6; + size = ARRAY_SIZE(svc_tbl_qdsp6); + lock = &m_lock_tbl_qdsp6; + } else { + tbl = svc_tbl_voice; + size = ARRAY_SIZE(svc_tbl_voice); + lock = &m_lock_tbl_voice; + } + + mutex_lock(lock); + for (i = 0; i < size; i++) { + if (!strcmp(svc_name, tbl[i].name)) { + *client_id = tbl[i].client_id; + *svc_idx = tbl[i].idx; + if (!tbl[i].id && !tbl[i].handle) { + /* need to register a new service */ + memset((void *) &tx_data, 0, sizeof(tx_data)); + + apr_len = sizeof(tx_data); + tx_data.cmd_id = APRV2_VM_CMDID_REGISTER; + tx_data.reg_cmd.name_size = snprintf( + tx_data.reg_cmd.name, + APRV2_VM_MAX_DNS_SIZE, + "qcom.apps.lnx.%s", + svc_name); + tx_data.reg_cmd.addr = 0; + ret = habmm_socket_send(hab_handle_tx, + (void *) &tx_data, + apr_len, + 0); + if (ret) { + pr_err("%s: habmm_socket_send failed %d\n", + __func__, ret); + mutex_unlock(lock); + return ret; + } + /* wait for response */ + apr_len = sizeof(apr_rsp); + ret = apr_vm_nb_receive(hab_handle_tx, + (void *)&apr_rsp, + &apr_len, + 0xFFFFFFFF); + if (ret) { + pr_err("%s: apr_vm_nb_receive failed %d\n", + __func__, ret); + mutex_unlock(lock); + return ret; + } + if (apr_rsp.status) { + pr_err("%s: apr_vm_nb_receive status %d\n", + __func__, apr_rsp.status); + ret = apr_rsp.status; + mutex_unlock(lock); + return ret; + } + /* update svc table */ + tbl[i].handle = apr_rsp.handle; + tbl[i].id = apr_rsp.addr & + APRV2_VM_PKT_SERVICE_ID_MASK; + } + *svc_id = tbl[i].id; + *dest_svc = tbl[i].dest_svc; + *handle = tbl[i].handle; + break; + } + } + mutex_unlock(lock); + + pr_debug("%s: svc_name = %s client_id = %d domain_id = %d\n", + __func__, svc_name, *client_id, domain_id); + pr_debug("%s: src_svc = %d dest_svc = %d handle = %d\n", + __func__, *svc_id, *dest_svc, *handle); + + if (i == size) { + pr_err("%s: APR: Wrong svc name %s\n", __func__, svc_name); + ret = -EINVAL; + } + + return ret; +} + +static int apr_vm_rel_svc(int domain_id, int svc_id, int handle) +{ + int i; + int size; + struct apr_svc_table *tbl; + struct mutex *lock; + struct aprv2_vm_cmd_deregister_rsp_t apr_rsp; + uint32_t apr_len; + int ret = 0; + struct { + uint32_t cmd_id; + struct aprv2_vm_cmd_deregister_t dereg_cmd; + } tx_data; + + if (domain_id == APR_DOMAIN_ADSP) { + tbl = svc_tbl_qdsp6; + size = ARRAY_SIZE(svc_tbl_qdsp6); + lock = &m_lock_tbl_qdsp6; + } else { + tbl = svc_tbl_voice; + size = ARRAY_SIZE(svc_tbl_voice); + lock = &m_lock_tbl_voice; + } + + mutex_lock(lock); + for (i = 0; i < size; i++) { + if (tbl[i].id == svc_id && tbl[i].handle == handle) { + /* need to deregister a service */ + memset((void *) &tx_data, 0, sizeof(tx_data)); + + apr_len = sizeof(tx_data); + tx_data.cmd_id = APRV2_VM_CMDID_DEREGISTER; + tx_data.dereg_cmd.handle = handle; + ret = habmm_socket_send(hab_handle_tx, + (void *) &tx_data, + apr_len, + 0); + if (ret) + pr_err("%s: habmm_socket_send failed %d\n", + __func__, ret); + /* + * TODO: if send failed, should not wait for recv. + * should clear regardless? + */ + /* wait for response */ + apr_len = sizeof(apr_rsp); + ret = apr_vm_nb_receive(hab_handle_tx, + (void *)&apr_rsp, + &apr_len, + 0xFFFFFFFF); + if (ret) + pr_err("%s: apr_vm_nb_receive failed %d\n", + __func__, ret); + if (apr_rsp.status) { + pr_err("%s: apr_vm_nb_receive status %d\n", + __func__, apr_rsp.status); + ret = apr_rsp.status; + } + /* clear svc table */ + tbl[i].handle = 0; + tbl[i].id = 0; + break; + } + } + mutex_unlock(lock); + + if (i == size) { + pr_err("%s: APR: Wrong svc id %d handle %d\n", + __func__, svc_id, handle); + ret = -EINVAL; + } + + return ret; +} + +static void apr_vm_set_subsys_state(void) +{ + /* set default subsys state in vm env. + * Both q6 and modem should be in LOADED state, + * since vm boots up at late stage after pm. + */ + apr_set_q6_state(APR_SUBSYS_LOADED); + apr_set_modem_state(APR_SUBSYS_LOADED); + + spin_lock(&apr_priv->apr_lock); + if (apr_priv->is_initial_boot) + schedule_work(&apr_priv->add_chld_dev_work); + spin_unlock(&apr_priv->apr_lock); + snd_event_notify(apr_priv->dev, SND_EVENT_UP); +} + +/** + * apr_send_pkt - Clients call to send packet + * to destination processor. + * + * @handle: APR service handle + * @buf: payload to send to destination processor. + * + * Returns Bytes(>0)pkt_size on success or error on failure. + */ +int apr_send_pkt(void *handle, uint32_t *buf) +{ + struct apr_svc *svc = handle; + struct apr_hdr *hdr; + unsigned long flags; + uint32_t *cmd_id = (uint32_t *)apr_tx_buf; + struct aprv2_vm_cmd_async_send_t *apr_send = + (struct aprv2_vm_cmd_async_send_t *)(apr_tx_buf + + sizeof(uint32_t)); + uint32_t apr_send_len; + struct aprv2_vm_cmd_async_send_rsp_t apr_rsp; + uint32_t apr_rsp_len; + int ret = 0; + + if (!handle || !buf) { + pr_err("APR: Wrong parameters\n"); + return -EINVAL; + } + if (svc->need_reset) { + pr_err("apr: send_pkt service need reset\n"); + return -ENETRESET; + } + + if ((svc->dest_id == APR_DEST_QDSP6) && + (apr_get_q6_state() != APR_SUBSYS_LOADED)) { + pr_err("%s: Still dsp is not Up\n", __func__); + return -ENETRESET; + } else if ((svc->dest_id == APR_DEST_MODEM) && + (apr_get_modem_state() == APR_SUBSYS_DOWN)) { + pr_err("apr: Still Modem is not Up\n"); + return -ENETRESET; + } + + spin_lock_irqsave(&svc->w_lock, flags); + if (!svc->id || !svc->vm_handle) { + pr_err("APR: Still service is not yet opened\n"); + ret = -EINVAL; + goto done; + } + hdr = (struct apr_hdr *)buf; + + hdr->src_domain = APR_DOMAIN_APPS; + hdr->src_svc = svc->id; + hdr->dest_domain = svc->dest_domain; + hdr->dest_svc = svc->vm_dest_svc; + + if (unlikely(apr_cf_debug)) { + APR_PKT_INFO( + "Tx: src_addr[0x%X] dest_addr[0x%X] opcode[0x%X] token[0x%X]", + (hdr->src_domain << 8) | hdr->src_svc, + (hdr->dest_domain << 8) | hdr->dest_svc, hdr->opcode, + hdr->token); + } + + memset((void *)&apr_tx_buf, 0, sizeof(apr_tx_buf)); + /* pkt_size + cmd_id + handle */ + apr_send_len = hdr->pkt_size + sizeof(uint32_t) * 2; + *cmd_id = APRV2_VM_CMDID_ASYNC_SEND; + apr_send->handle = svc->vm_handle; + + /* safe check */ + if (hdr->pkt_size > APR_TX_BUF_SIZE - (sizeof(uint32_t) * 2)) { + pr_err("APR: Wrong pkt size %d\n", hdr->pkt_size); + ret = -ENOMEM; + goto done; + } + memcpy(&apr_send->pkt_header, buf, hdr->pkt_size); + + ret = habmm_socket_send(hab_handle_tx, + (void *)&apr_tx_buf, + apr_send_len, + 0); + if (ret) { + pr_err("%s: habmm_socket_send failed %d\n", + __func__, ret); + goto done; + } + /* wait for response */ + apr_rsp_len = sizeof(apr_rsp); + ret = apr_vm_nb_receive(hab_handle_tx, + (void *)&apr_rsp, + &apr_rsp_len, + 0xFFFFFFFF); + if (ret) { + pr_err("%s: apr_vm_nb_receive failed %d\n", + __func__, ret); + goto done; + } + if (apr_rsp.status) { + pr_err("%s: apr_vm_nb_receive status %d\n", + __func__, apr_rsp.status); + /* should translate status properly */ + ret = -ECOMM; + goto done; + } + + /* upon successful send, return packet size */ + ret = hdr->pkt_size; + +done: + spin_unlock_irqrestore(&svc->w_lock, flags); + return ret; +} +EXPORT_SYMBOL(apr_send_pkt); + +/** + * apr_register - Clients call to register + * to APR. + * + * @dest: destination processor + * @svc_name: name of service to register as + * @svc_fn: callback function to trigger when response + * ack or packets received from destination processor. + * @src_port: Port number within a service + * @priv: private data of client, passed back in cb fn. + * + * Returns apr_svc handle on success or NULL on failure. + */ +struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn, + uint32_t src_port, void *priv) +{ + struct apr_client *clnt; + int client_id = 0; + int svc_idx = 0; + int svc_id = 0; + int dest_id = 0; + int domain_id = 0; + int temp_port = 0; + struct apr_svc *svc = NULL; + int rc = 0; + bool can_open_channel = true; + int dest_svc = 0; + int handle = 0; + + if (!dest || !svc_name || !svc_fn) + return NULL; + + if (!strcmp(dest, "ADSP")) + domain_id = APR_DOMAIN_ADSP; + else if (!strcmp(dest, "MODEM")) { + /* Don't request for SMD channels if destination is MODEM, + * as these channels are no longer used and these clients + * are to listen only for MODEM SSR events + */ + can_open_channel = false; + domain_id = APR_DOMAIN_MODEM; + } else { + pr_err("APR: wrong destination\n"); + goto done; + } + + dest_id = apr_get_dest_id(dest); + + if (dest_id == APR_DEST_QDSP6) { + if (apr_get_q6_state() != APR_SUBSYS_LOADED) { + pr_err("%s: adsp not up\n", __func__); + return NULL; + } + pr_debug("%s: adsp Up\n", __func__); + } else if (dest_id == APR_DEST_MODEM) { + if (apr_get_modem_state() == APR_SUBSYS_DOWN) { + if (is_modem_up) { + pr_err("%s: modem shutdown due to SSR, ret", + __func__); + return NULL; + } + pr_debug("%s: Wait for modem to bootup\n", __func__); + rc = wait_event_interruptible_timeout(modem_wait, + (apr_get_modem_state() == APR_SUBSYS_UP), + (1 * HZ)); + if (rc == 0) { + pr_err("%s: Modem is not Up\n", __func__); + return NULL; + } + } + pr_debug("%s: modem Up\n", __func__); + } + + if (apr_vm_get_svc(svc_name, domain_id, &client_id, &svc_idx, &svc_id, + &dest_svc, &handle)) { + pr_err("%s: apr_vm_get_svc failed\n", __func__); + goto done; + } + + clnt = &client[dest_id][client_id]; + svc = &clnt->svc[svc_idx]; + mutex_lock(&svc->m_lock); + clnt->id = client_id; + if (svc->need_reset) { + mutex_unlock(&svc->m_lock); + pr_err("APR: Service needs reset\n"); + svc = NULL; + goto done; + } + svc->id = svc_id; + svc->vm_dest_svc = dest_svc; + svc->dest_id = dest_id; + svc->client_id = client_id; + svc->dest_domain = domain_id; + svc->pkt_owner = APR_PKT_OWNER_DRIVER; + svc->vm_handle = handle; + + if (src_port != 0xFFFFFFFF) { + temp_port = ((src_port >> 8) * 8) + (src_port & 0xFF); + pr_debug("port = %d t_port = %d\n", src_port, temp_port); + if (temp_port >= APR_MAX_PORTS || temp_port < 0) { + pr_err("APR: temp_port out of bounds\n"); + mutex_unlock(&svc->m_lock); + return NULL; + } + if (!svc->port_cnt && !svc->svc_cnt) + clnt->svc_cnt++; + svc->port_cnt++; + svc->port_fn[temp_port] = svc_fn; + svc->port_priv[temp_port] = priv; + } else { + if (!svc->fn) { + if (!svc->port_cnt && !svc->svc_cnt) + clnt->svc_cnt++; + svc->fn = svc_fn; + if (svc->port_cnt) + svc->svc_cnt++; + svc->priv = priv; + } + } + + mutex_unlock(&svc->m_lock); +done: + return svc; +} +EXPORT_SYMBOL(apr_register); + +static void apr_reset_deregister(struct work_struct *work) +{ + struct apr_svc *handle = NULL; + struct apr_reset_work *apr_reset = + container_of(work, struct apr_reset_work, work); + + handle = apr_reset->handle; + pr_debug("%s:handle[%pK]\n", __func__, handle); + apr_deregister(handle); + kfree(apr_reset); +} + +/** + * apr_start_rx_rt - Clients call to vote for thread + * priority upgrade whenever needed. + * + * @handle: APR service handle + * + * Returns 0 on success or error otherwise. + */ +int apr_start_rx_rt(void *handle) +{ + int rc = 0; + return rc; +} +EXPORT_SYMBOL(apr_start_rx_rt); + +/** + * apr_end_rx_rt - Clients call to unvote for thread + * priority upgrade (perviously voted with + * apr_start_rx_rt()). + * + * @handle: APR service handle + * + * Returns 0 on success or error otherwise. + */ +int apr_end_rx_rt(void *handle) +{ + int rc = 0; + return rc; +} +EXPORT_SYMBOL(apr_end_rx_rt); + + +/** + * apr_deregister - Clients call to de-register + * from APR. + * + * @handle: APR service handle to de-register + * + * Returns 0 on success or -EINVAL on error. + */ +int apr_deregister(void *handle) +{ + struct apr_svc *svc = handle; + struct apr_client *clnt; + uint16_t dest_id; + uint16_t client_id; + + if (!handle) + return -EINVAL; + + mutex_lock(&svc->m_lock); + dest_id = svc->dest_id; + client_id = svc->client_id; + clnt = &client[dest_id][client_id]; + + if (svc->port_cnt > 0 || svc->svc_cnt > 0) { + if (svc->port_cnt) + svc->port_cnt--; + else if (svc->svc_cnt) + svc->svc_cnt--; + if (!svc->port_cnt && !svc->svc_cnt) { + client[dest_id][client_id].svc_cnt--; + svc->need_reset = 0x0; + } + } else if (client[dest_id][client_id].svc_cnt > 0) { + client[dest_id][client_id].svc_cnt--; + if (!client[dest_id][client_id].svc_cnt) { + svc->need_reset = 0x0; + pr_debug("%s: service is reset %p\n", __func__, svc); + } + } + + if (!svc->port_cnt && !svc->svc_cnt) { + if (apr_vm_rel_svc(svc->dest_domain, svc->id, svc->vm_handle)) + pr_err("%s: apr_vm_rel_svc failed\n", __func__); + svc->priv = NULL; + svc->id = 0; + svc->vm_dest_svc = 0; + svc->fn = NULL; + svc->dest_id = 0; + svc->client_id = 0; + svc->need_reset = 0x0; + svc->vm_handle = 0; + } + mutex_unlock(&svc->m_lock); + + return 0; +} +EXPORT_SYMBOL(apr_deregister); + +/** + * apr_reset - sets up workqueue to de-register + * the given APR service handle. + * + * @handle: APR service handle + * + */ +void apr_reset(void *handle) +{ + struct apr_reset_work *apr_reset_worker = NULL; + + if (!handle) + return; + pr_debug("%s: handle[%pK]\n", __func__, handle); + + if (apr_reset_workqueue == NULL) { + pr_err("%s: apr_reset_workqueue is NULL\n", __func__); + return; + } + + apr_reset_worker = kzalloc(sizeof(struct apr_reset_work), + GFP_ATOMIC); + + if (apr_reset_worker == NULL) { + pr_err("%s: mem failure\n", __func__); + return; + } + + apr_reset_worker->handle = handle; + INIT_WORK(&apr_reset_worker->work, apr_reset_deregister); + queue_work(apr_reset_workqueue, &apr_reset_worker->work); +} +EXPORT_SYMBOL(apr_reset); + +/* Dispatch the Reset events to Modem and audio clients */ +static void dispatch_event(unsigned long code, uint16_t proc) +{ + struct apr_client *apr_client; + struct apr_client_data data; + struct apr_svc *svc; + uint16_t clnt; + int i, j; + + memset(&data, 0, sizeof(data)); + data.opcode = RESET_EVENTS; + data.reset_event = code; + + /* Service domain can be different from the processor */ + data.reset_proc = apr_get_reset_domain(proc); + + clnt = APR_CLIENT_AUDIO; + apr_client = &client[proc][clnt]; + for (i = 0; i < APR_SVC_MAX; i++) { + mutex_lock(&apr_client->svc[i].m_lock); + if (apr_client->svc[i].fn) { + apr_client->svc[i].need_reset = 0x1; + apr_client->svc[i].fn(&data, apr_client->svc[i].priv); + } + if (apr_client->svc[i].port_cnt) { + svc = &(apr_client->svc[i]); + svc->need_reset = 0x1; + for (j = 0; j < APR_MAX_PORTS; j++) + if (svc->port_fn[j]) + svc->port_fn[j](&data, + svc->port_priv[j]); + } + mutex_unlock(&apr_client->svc[i].m_lock); + } + + clnt = APR_CLIENT_VOICE; + apr_client = &client[proc][clnt]; + for (i = 0; i < APR_SVC_MAX; i++) { + mutex_lock(&apr_client->svc[i].m_lock); + if (apr_client->svc[i].fn) { + apr_client->svc[i].need_reset = 0x1; + apr_client->svc[i].fn(&data, apr_client->svc[i].priv); + } + if (apr_client->svc[i].port_cnt) { + svc = &(apr_client->svc[i]); + svc->need_reset = 0x1; + for (j = 0; j < APR_MAX_PORTS; j++) + if (svc->port_fn[j]) + svc->port_fn[j](&data, + svc->port_priv[j]); + } + mutex_unlock(&apr_client->svc[i].m_lock); + } +} + +static int apr_notifier_service_cb(struct notifier_block *this, + unsigned long opcode, void *data) +{ + struct audio_notifier_cb_data *cb_data = data; + + if (cb_data == NULL) { + pr_err("%s: Callback data is NULL!\n", __func__); + goto done; + } + + pr_debug("%s: Service opcode 0x%lx, domain %d\n", + __func__, opcode, cb_data->domain); + + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + /* + * Use flag to ignore down notifications during + * initial boot. There is no benefit from error + * recovery notifications during initial boot + * up since everything is expected to be down. + */ + spin_lock(&apr_priv->apr_lock); + if (apr_priv->is_initial_boot) { + spin_unlock(&apr_priv->apr_lock); + break; + } + spin_unlock(&apr_priv->apr_lock); + if (cb_data->domain == AUDIO_NOTIFIER_MODEM_DOMAIN) + apr_modem_down(opcode); + else + apr_adsp_down(opcode); + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (cb_data->domain == AUDIO_NOTIFIER_MODEM_DOMAIN) + apr_modem_up(); + else + apr_adsp_up(); + spin_lock(&apr_priv->apr_lock); + apr_priv->is_initial_boot = false; + spin_unlock(&apr_priv->apr_lock); + break; + default: + break; + } +done: + return NOTIFY_OK; +} + +static struct notifier_block adsp_service_nb = { + .notifier_call = apr_notifier_service_cb, + .priority = 0, +}; + +static struct notifier_block modem_service_nb = { + .notifier_call = apr_notifier_service_cb, + .priority = 0, +}; + +#ifdef CONFIG_DEBUG_FS +static int __init apr_debug_init(void) +{ + debugfs_apr_debug = debugfs_create_file("msm_apr_debug", + S_IFREG | 0444, NULL, NULL, + &apr_debug_ops); + return 0; +} +#else +static int __init apr_debug_init(void) +( + return 0; +) +#endif + +static void apr_cleanup(void) +{ + int i, j, k; + + of_platform_depopulate(apr_priv->dev); + subsys_notif_deregister(subsys_name); + if (apr_reset_workqueue) { + flush_workqueue(apr_reset_workqueue); + destroy_workqueue(apr_reset_workqueue); + } + mutex_destroy(&q6.lock); + for (i = 0; i < APR_DEST_MAX; i++) { + for (j = 0; j < APR_CLIENT_MAX; j++) { + mutex_destroy(&client[i][j].m_lock); + for (k = 0; k < APR_SVC_MAX; k++) + mutex_destroy(&client[i][j].svc[k].m_lock); + } + } + debugfs_remove(debugfs_apr_debug); +} + +static int apr_probe(struct platform_device *pdev) +{ + int i, j, k, ret = 0; + + init_waitqueue_head(&modem_wait); + + apr_priv = devm_kzalloc(&pdev->dev, sizeof(*apr_priv), GFP_KERNEL); + if (!apr_priv) + return -ENOMEM; + + apr_priv->dev = &pdev->dev; + spin_lock_init(&apr_priv->apr_lock); + INIT_WORK(&apr_priv->add_chld_dev_work, apr_add_child_devices); + + /* open apr channel tx and rx, store as global */ + ret = habmm_socket_open(&hab_handle_tx, + MM_AUD_1, + 0xFFFFFFFF, + HABMM_SOCKET_OPEN_FLAGS_SINGLE_BE_SINGLE_FE); + if (ret) { + pr_err("%s: habmm_socket_open tx failed %d\n", __func__, ret); + return ret; + } + spin_lock_init(&hab_tx_lock); + + ret = habmm_socket_open(&hab_handle_rx, + MM_AUD_2, + 0xFFFFFFFF, + HABMM_SOCKET_OPEN_FLAGS_SINGLE_BE_SINGLE_FE); + if (ret) { + pr_err("%s: habmm_socket_open rx failed %d\n", __func__, ret); + habmm_socket_close(hab_handle_tx); + return ret; + } + pr_info("%s: hab_handle_tx %x hab_handle_rx %x\n", + __func__, hab_handle_tx, hab_handle_rx); + + /* create apr ch rx cb thread */ + apr_vm_cb_thread_task = kthread_run(apr_vm_cb_thread, + NULL, + APR_VM_CB_THREAD_NAME); + if (IS_ERR(apr_vm_cb_thread_task)) { + ret = PTR_ERR(apr_vm_cb_thread_task); + pr_err("%s: kthread_run failed %d\n", __func__, ret); + habmm_socket_close(hab_handle_tx); + habmm_socket_close(hab_handle_rx); + return ret; + } + pid = apr_vm_cb_thread_task->pid; + pr_info("%s: apr_vm_cb_thread started pid %d\n", + __func__, pid); + + for (i = 0; i < APR_DEST_MAX; i++) + for (j = 0; j < APR_CLIENT_MAX; j++) { + mutex_init(&client[i][j].m_lock); + for (k = 0; k < APR_SVC_MAX; k++) { + mutex_init(&client[i][j].svc[k].m_lock); + spin_lock_init(&client[i][j].svc[k].w_lock); + } + } + spin_lock(&apr_priv->apr_lock); + apr_priv->is_initial_boot = true; + spin_unlock(&apr_priv->apr_lock); + apr_vm_set_subsys_state(); + mutex_init(&q6.lock); + apr_reset_workqueue = create_singlethread_workqueue("apr_driver"); + if (!apr_reset_workqueue) { + habmm_socket_close(hab_handle_tx); + habmm_socket_close(hab_handle_rx); + kthread_stop(apr_vm_cb_thread_task); + apr_priv = NULL; + return -ENOMEM; + } + + apr_pkt_ctx = ipc_log_context_create(APR_PKT_IPC_LOG_PAGE_CNT, + "apr", 0); + if (!apr_pkt_ctx) + pr_err("%s: Unable to create ipc log context\n", __func__); + + ret = of_property_read_string(pdev->dev.of_node, + "qcom,subsys-name", + (const char **)(&subsys_name)); + if (ret) { + pr_err("%s: missing subsys-name entry in dt node\n", __func__); + return -EINVAL; + } + + if (!strcmp(subsys_name, "apr_adsp")) { + subsys_notif_register("apr_adsp", + AUDIO_NOTIFIER_ADSP_DOMAIN, + &adsp_service_nb); + } else if (!strcmp(subsys_name, "apr_modem")) { + subsys_notif_register("apr_modem", + AUDIO_NOTIFIER_MODEM_DOMAIN, + &modem_service_nb); + } else { + pr_err("%s: invalid subsys-name %s\n", __func__, subsys_name); + return -EINVAL; + } + + ret = snd_event_client_register(&pdev->dev, &apr_ssr_ops, NULL); + if (ret) { + pr_err("%s: Registration with SND event fwk failed ret = %d\n", + __func__, ret); + ret = 0; + } + + return apr_debug_init(); +} + +static int apr_remove(struct platform_device *pdev) +{ + habmm_socket_close(hab_handle_tx); + habmm_socket_close(hab_handle_rx); + kthread_stop(apr_vm_cb_thread_task); + snd_event_client_deregister(&pdev->dev); + apr_cleanup(); + apr_priv = NULL; + return 0; +} + +static const struct of_device_id apr_machine_of_match[] = { + { .compatible = "qcom,msm-audio-apr", }, + {}, +}; + +static struct platform_driver apr_driver = { + .probe = apr_probe, + .remove = apr_remove, + .driver = { + .name = "audio_apr", + .owner = THIS_MODULE, + .of_match_table = apr_machine_of_match, + } +}; + +module_platform_driver(apr_driver); + +MODULE_DESCRIPTION("APR DRIVER"); +MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(of, apr_machine_of_match); -- GitLab From 49cbca051c4b5e96665c97bb2498060c84bead4a Mon Sep 17 00:00:00 2001 From: Timothy Sham Date: Sat, 16 Feb 2019 02:33:47 -0500 Subject: [PATCH 0973/1645] dsp: add audio ion virtualization support Add support for virtualized ION frontend driver for audio. Virtualized ION driver currently is designed to extract physical memory through hypervisor abstracted ion layer, which can be shared between APPS and ADSP directly. Change-Id: I3c664ec3c3a99ce092da6ee103a3b2de4073664f Signed-off-by: Timothy Sham --- dsp/Kbuild | 27 + dsp/msm_audio_ion_vm.c | 880 +++++++++++++++++++++++++++ include/dsp/msm-audio-event-notify.h | 5 +- 3 files changed, 910 insertions(+), 2 deletions(-) create mode 100644 dsp/msm_audio_ion_vm.c diff --git a/dsp/Kbuild b/dsp/Kbuild index 086924f5557c..7d683b35f923 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -48,6 +48,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h endif + ifeq ($(CONFIG_QTI_GVM), y) + include $(AUDIO_ROOT)/config/gvmauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h + endif endif @@ -97,6 +102,25 @@ ifdef CONFIG_SND_SOC_MSM_QDSP6V2_INTF Q6_OBJS += q6_init.o endif +ifdef CONFIG_SND_SOC_MSM_QDSP6V2_VM + Q6_OBJS += msm-audio-event-notify.o + Q6_OBJS += audio_calibration.o + Q6_OBJS += audio_cal_utils.o + Q6_OBJS += q6adm.o + Q6_OBJS += q6afe.o + Q6_OBJS += q6asm.o + Q6_OBJS += q6audio-v2.o + Q6_OBJS += q6voice.o + Q6_OBJS += q6core.o + Q6_OBJS += q6common.o + Q6_OBJS += rtac.o + Q6_OBJS += q6lsm.o + Q6_OBJS += adsp_err.o + Q6_OBJS += msm_audio_ion_vm.o + Q6_OBJS += avtimer.o + Q6_OBJS += q6_init.o +endif + ifdef CONFIG_XT_LOGGING Q6_OBJS += sp_params.o endif @@ -192,6 +216,9 @@ endif obj-$(CONFIG_SND_SOC_MSM_QDSP6V2_INTF) += q6_dlkm.o q6_dlkm-y := $(Q6_OBJS) +obj-$(CONFIG_SND_SOC_MSM_QDSP6V2_VM) += q6_dlkm.o +q6_dlkm-y := $(Q6_OBJS) + obj-$(CONFIG_MSM_ULTRASOUND) += usf_dlkm.o usf_dlkm-y := $(USF_OBJS) diff --git a/dsp/msm_audio_ion_vm.c b/dsp/msm_audio_ion_vm.c new file mode 100644 index 000000000000..cd3122e6bfdc --- /dev/null +++ b/dsp/msm_audio_ion_vm.c @@ -0,0 +1,880 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MSM_AUDIO_ION_PROBED (1 << 0) + +#define MSM_AUDIO_ION_PHYS_ADDR(alloc_data) \ + alloc_data->table->sgl->dma_address + +#define MSM_AUDIO_SMMU_VM_CMD_MAP 0x00000001 +#define MSM_AUDIO_SMMU_VM_CMD_UNMAP 0x00000002 +#define MSM_AUDIO_SMMU_VM_HAB_MINOR_ID 1 + +struct msm_audio_ion_private { + bool smmu_enabled; + struct device *cb_dev; + u8 device_status; + struct list_head alloc_list; + struct mutex list_mutex; +}; + +struct msm_audio_alloc_data { + size_t len; + void *vaddr; + struct dma_buf *dma_buf; + struct dma_buf_attachment *attach; + struct sg_table *table; + struct list_head list; + u32 export_id; +}; + +struct msm_audio_smmu_vm_map_cmd { + int cmd_id; + u32 export_id; + u32 buf_size; +}; + +struct msm_audio_smmu_vm_map_cmd_rsp { + int status; + u64 addr; +}; + +struct msm_audio_smmu_vm_unmap_cmd { + int cmd_id; + u32 export_id; +}; + +struct msm_audio_smmu_vm_unmap_cmd_rsp { + int status; +}; + +static struct msm_audio_ion_private msm_audio_ion_data = {0,}; +static u32 msm_audio_ion_hab_handle; + +static void msm_audio_ion_add_allocation( + struct msm_audio_ion_private *msm_audio_ion_data, + struct msm_audio_alloc_data *alloc_data) +{ + /* + * Since these APIs can be invoked by multiple + * clients, there is need to make sure the list + * of allocations is always protected + */ + mutex_lock(&(msm_audio_ion_data->list_mutex)); + list_add_tail(&(alloc_data->list), + &(msm_audio_ion_data->alloc_list)); + mutex_unlock(&(msm_audio_ion_data->list_mutex)); +} + +static int msm_audio_dma_buf_map(struct dma_buf *dma_buf, + dma_addr_t *addr, size_t *len) +{ + + struct msm_audio_alloc_data *alloc_data; + struct device *cb_dev; + unsigned long ionflag = 0; + int rc = 0; + + cb_dev = msm_audio_ion_data.cb_dev; + + /* Data required per buffer mapping */ + alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL); + if (!alloc_data) + return -ENOMEM; + + alloc_data->dma_buf = dma_buf; + alloc_data->len = dma_buf->size; + *len = dma_buf->size; + + /* Attach the dma_buf to context bank device */ + alloc_data->attach = dma_buf_attach(alloc_data->dma_buf, + cb_dev); + if (IS_ERR(alloc_data->attach)) { + rc = PTR_ERR(alloc_data->attach); + dev_err(cb_dev, + "%s: Fail to attach dma_buf to CB, rc = %d\n", + __func__, rc); + goto free_alloc_data; + } + + /* For uncached buffers, avoid cache maintanance */ + rc = dma_buf_get_flags(alloc_data->dma_buf, &ionflag); + if (rc) { + dev_err(cb_dev, "%s: dma_buf_get_flags failed: %d\n", + __func__, rc); + goto detach_dma_buf; + } + + if (!(ionflag & ION_FLAG_CACHED)) + alloc_data->attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC; + + /* + * Get the scatter-gather list. + * There is no info as this is a write buffer or + * read buffer, hence the request is bi-directional + * to accommodate both read and write mappings. + */ + alloc_data->table = dma_buf_map_attachment(alloc_data->attach, + DMA_BIDIRECTIONAL); + if (IS_ERR(alloc_data->table)) { + rc = PTR_ERR(alloc_data->table); + dev_err(cb_dev, + "%s: Fail to map attachment, rc = %d\n", + __func__, rc); + goto detach_dma_buf; + } + + /* physical address from mapping */ + *addr = MSM_AUDIO_ION_PHYS_ADDR(alloc_data); + + msm_audio_ion_add_allocation(&msm_audio_ion_data, + alloc_data); + return rc; + +detach_dma_buf: + dma_buf_detach(alloc_data->dma_buf, + alloc_data->attach); +free_alloc_data: + kfree(alloc_data); + + return rc; +} + +static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf) +{ + int rc = 0; + struct msm_audio_alloc_data *alloc_data = NULL; + struct list_head *ptr, *next; + struct device *cb_dev = msm_audio_ion_data.cb_dev; + bool found = false; + + /* + * Though list_for_each_safe is delete safe, lock + * should be explicitly acquired to avoid race condition + * on adding elements to the list. + */ + mutex_lock(&(msm_audio_ion_data.list_mutex)); + list_for_each_safe(ptr, next, + &(msm_audio_ion_data.alloc_list)) { + + alloc_data = list_entry(ptr, struct msm_audio_alloc_data, + list); + + if (alloc_data->dma_buf == dma_buf) { + found = true; + dma_buf_unmap_attachment(alloc_data->attach, + alloc_data->table, + DMA_BIDIRECTIONAL); + + dma_buf_detach(alloc_data->dma_buf, + alloc_data->attach); + + dma_buf_put(alloc_data->dma_buf); + + list_del(&(alloc_data->list)); + kfree(alloc_data); + break; + } + } + mutex_unlock(&(msm_audio_ion_data.list_mutex)); + + if (!found) { + dev_err(cb_dev, + "%s: cannot find allocation, dma_buf %pK", + __func__, dma_buf); + rc = -EINVAL; + } + + return rc; +} + +static int msm_audio_ion_smmu_map(struct dma_buf *dma_buf, + dma_addr_t *paddr, size_t *len) +{ + int rc; + u32 export_id; + u32 cmd_rsp_size; + bool found = false; + bool exported = false; + struct msm_audio_smmu_vm_map_cmd smmu_map_cmd; + struct msm_audio_smmu_vm_map_cmd_rsp cmd_rsp; + struct msm_audio_alloc_data *alloc_data = NULL; + unsigned long delay = jiffies + (HZ / 2); + void *vaddr; + + *len = dma_buf->size; + + mutex_lock(&(msm_audio_ion_data.list_mutex)); + list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list), + list) { + if (alloc_data->dma_buf == dma_buf) { + found = true; + vaddr = alloc_data->vaddr; + + /* Export the buffer to physical VM */ + rc = habmm_export(msm_audio_ion_hab_handle, vaddr, *len, + &export_id, 0); + if (rc) { + pr_err("%s: habmm_export failed vaddr = %pK, len = %zd, rc = %d\n", + __func__, vaddr, *len, rc); + goto err; + } + + exported = true; + smmu_map_cmd.cmd_id = MSM_AUDIO_SMMU_VM_CMD_MAP; + smmu_map_cmd.export_id = export_id; + smmu_map_cmd.buf_size = *len; + + rc = habmm_socket_send(msm_audio_ion_hab_handle, + (void *)&smmu_map_cmd, sizeof(smmu_map_cmd), 0); + if (rc) { + pr_err("%s: habmm_socket_send failed %d\n", + __func__, rc); + goto err; + } + + do { + cmd_rsp_size = sizeof(cmd_rsp); + rc = habmm_socket_recv(msm_audio_ion_hab_handle, + (void *)&cmd_rsp, + &cmd_rsp_size, + 0xFFFFFFFF, + 0); + } while (time_before(jiffies, delay) && (rc == -EINTR) && + (cmd_rsp_size == 0)); + if (rc) { + pr_err("%s: habmm_socket_recv failed %d\n", + __func__, rc); + goto err; + } + + if (cmd_rsp_size != sizeof(cmd_rsp)) { + pr_err("%s: invalid size for cmd rsp %u, expected %zu\n", + __func__, cmd_rsp_size, sizeof(cmd_rsp)); + rc = -EIO; + goto err; + } + + if (cmd_rsp.status) { + pr_err("%s: SMMU map command failed %d\n", + __func__, cmd_rsp.status); + rc = cmd_rsp.status; + goto err; + } + + *paddr = (dma_addr_t)cmd_rsp.addr; + alloc_data->export_id = export_id; + break; + } + } + mutex_unlock(&(msm_audio_ion_data.list_mutex)); + + if (!found) { + pr_err("%s: cannot find allocation, dma_buf %pK", __func__, dma_buf); + return -EINVAL; + } + + return 0; + +err: + if (exported) + (void)habmm_unexport(msm_audio_ion_hab_handle, export_id, 0); + + mutex_unlock(&(msm_audio_ion_data.list_mutex)); + return rc; +} + +static int msm_audio_ion_smmu_unmap(struct dma_buf *dma_buf) +{ + int rc; + bool found = false; + u32 cmd_rsp_size; + struct msm_audio_smmu_vm_unmap_cmd smmu_unmap_cmd; + struct msm_audio_smmu_vm_unmap_cmd_rsp cmd_rsp; + struct msm_audio_alloc_data *alloc_data, *next; + unsigned long delay = jiffies + (HZ / 2); + + /* + * Though list_for_each_entry_safe is delete safe, lock + * should be explicitly acquired to avoid race condition + * on adding elements to the list. + */ + mutex_lock(&(msm_audio_ion_data.list_mutex)); + list_for_each_entry_safe(alloc_data, next, + &(msm_audio_ion_data.alloc_list), list) { + + if (alloc_data->dma_buf == dma_buf) { + found = true; + smmu_unmap_cmd.cmd_id = MSM_AUDIO_SMMU_VM_CMD_UNMAP; + smmu_unmap_cmd.export_id = alloc_data->export_id; + + rc = habmm_socket_send(msm_audio_ion_hab_handle, + (void *)&smmu_unmap_cmd, + sizeof(smmu_unmap_cmd), 0); + if (rc) { + pr_err("%s: habmm_socket_send failed %d\n", + __func__, rc); + goto err; + } + + do { + cmd_rsp_size = sizeof(cmd_rsp); + rc = habmm_socket_recv(msm_audio_ion_hab_handle, + (void *)&cmd_rsp, + &cmd_rsp_size, + 0xFFFFFFFF, + 0); + } while (time_before(jiffies, delay) && + (rc == -EINTR) && (cmd_rsp_size == 0)); + if (rc) { + pr_err("%s: habmm_socket_recv failed %d\n", + __func__, rc); + goto err; + } + + if (cmd_rsp_size != sizeof(cmd_rsp)) { + pr_err("%s: invalid size for cmd rsp %u\n", + __func__, cmd_rsp_size); + rc = -EIO; + goto err; + } + + if (cmd_rsp.status) { + pr_err("%s: SMMU unmap command failed %d\n", + __func__, cmd_rsp.status); + rc = cmd_rsp.status; + goto err; + } + + rc = habmm_unexport(msm_audio_ion_hab_handle, + alloc_data->export_id, 0xFFFFFFFF); + if (rc) { + pr_err("%s: habmm_unexport failed export_id = %d, rc = %d\n", + __func__, alloc_data->export_id, rc); + } + + break; + } + } + mutex_unlock(&(msm_audio_ion_data.list_mutex)); + + if (!found) { + pr_err("%s: cannot find allocation, dma_buf %pK\n", __func__, dma_buf); + rc = -EINVAL; + } + + return rc; + +err: + if (found) { + (void)habmm_unexport(msm_audio_ion_hab_handle, + alloc_data->export_id, 0xFFFFFFFF); + list_del(&(alloc_data->list)); + kfree(alloc_data); + } + + mutex_unlock(&(msm_audio_ion_data.list_mutex)); + return rc; +} + +static int msm_audio_ion_get_phys(struct dma_buf *dma_buf, + dma_addr_t *addr, size_t *len) +{ + int rc = 0; + + rc = msm_audio_dma_buf_map(dma_buf, addr, len); + if (rc) { + pr_err("%s: failed to map DMA buf, err = %d\n", + __func__, rc); + goto err; + } + + pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc); +err: + return rc; +} + +static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf) +{ + int rc = 0; + void *addr = NULL; + struct msm_audio_alloc_data *alloc_data = NULL; + + rc = dma_buf_begin_cpu_access(dma_buf, DMA_BIDIRECTIONAL); + if (rc) { + pr_err("%s: kmap dma_buf_begin_cpu_access fail\n", __func__); + goto exit; + } + + addr = dma_buf_vmap(dma_buf); + if (!addr) { + pr_err("%s: kernel mapping of dma_buf failed\n", + __func__); + goto exit; + } + + /* + * TBD: remove the below section once new API + * for mapping kernel virtual address is available. + */ + mutex_lock(&(msm_audio_ion_data.list_mutex)); + list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list), + list) { + if (alloc_data->dma_buf == dma_buf) { + alloc_data->vaddr = addr; + break; + } + } + mutex_unlock(&(msm_audio_ion_data.list_mutex)); + +exit: + return addr; +} + +static int msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf) +{ + int rc = 0; + void *vaddr = NULL; + struct msm_audio_alloc_data *alloc_data = NULL; + struct device *cb_dev = msm_audio_ion_data.cb_dev; + + /* + * TBD: remove the below section once new API + * for unmapping kernel virtual address is available. + */ + mutex_lock(&(msm_audio_ion_data.list_mutex)); + list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list), + list) { + if (alloc_data->dma_buf == dma_buf) { + vaddr = alloc_data->vaddr; + break; + } + } + mutex_unlock(&(msm_audio_ion_data.list_mutex)); + + if (!vaddr) { + dev_err(cb_dev, + "%s: cannot find allocation for dma_buf %pK", + __func__, dma_buf); + rc = -EINVAL; + goto err; + } + + dma_buf_vunmap(dma_buf, vaddr); + + rc = dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL); + if (rc) { + dev_err(cb_dev, "%s: kmap dma_buf_end_cpu_access fail\n", + __func__); + goto err; + } + +err: + return rc; +} + +static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr, + size_t *plen, void **vaddr) +{ + int rc = 0; + + rc = msm_audio_ion_get_phys(dma_buf, paddr, plen); + if (rc) { + pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", + __func__, rc); + goto err; + } + + *vaddr = msm_audio_ion_map_kernel(dma_buf); + if (IS_ERR_OR_NULL(*vaddr)) { + pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); + rc = -ENOMEM; + goto err; + } + + if (msm_audio_ion_data.smmu_enabled) { + rc = msm_audio_ion_smmu_map(dma_buf, paddr, plen); + if (rc) { + pr_err("%s: failed to do smmu map, err = %d\n", + __func__, rc); + goto err; + } + } +err: + return rc; +} + +/** + * msm_audio_ion_alloc - + * Allocs ION memory for given client name + * + * @dma_buf: dma_buf for the ION memory + * @bufsz: buffer size + * @paddr: Physical address to be assigned with allocated region + * @plen: length of allocated region to be assigned + * vaddr: virtual address to be assigned + * + * Returns 0 on success or error on failure + */ +int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, + dma_addr_t *paddr, size_t *plen, void **vaddr) +{ + int rc = -EINVAL; + unsigned long err_ion_ptr = 0; + + if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { + pr_debug("%s:probe is not done, deferred\n", __func__); + return -EPROBE_DEFER; + } + if (!dma_buf || !paddr || !vaddr || !bufsz || !plen) { + pr_err("%s: Invalid params\n", __func__); + return -EINVAL; + } + + if (msm_audio_ion_data.smmu_enabled == true) { + pr_debug("%s: system heap is used\n", __func__); + *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_HEAP_ID), 0); + } else { + pr_debug("%s: audio heap is used\n", __func__); + *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_AUDIO_HEAP_ID), 0); + } + if (IS_ERR_OR_NULL((void *)(*dma_buf))) { + if (IS_ERR((void *)(*dma_buf))) + err_ion_ptr = PTR_ERR((int *)(*dma_buf)); + pr_err("%s: ION alloc fail err ptr=%ld, smmu_enabled=%d\n", + __func__, err_ion_ptr, msm_audio_ion_data.smmu_enabled); + rc = -ENOMEM; + goto err; + } + + rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr); + if (rc) { + pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc); + goto err_dma_buf; + } + pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, + *vaddr, bufsz); + + memset(*vaddr, 0, bufsz); + + return rc; + +err_dma_buf: + dma_buf_put(*dma_buf); +err: + return rc; +} +EXPORT_SYMBOL(msm_audio_ion_alloc); + +/** + * msm_audio_ion_import- + * Import ION buffer with given file descriptor + * + * @dma_buf: dma_buf for the ION memory + * @fd: file descriptor for the ION memory + * @ionflag: flags associated with ION buffer + * @bufsz: buffer size + * @paddr: Physical address to be assigned with allocated region + * @plen: length of allocated region to be assigned + * vaddr: virtual address to be assigned + * + * Returns 0 on success or error on failure + */ +int msm_audio_ion_import(struct dma_buf **dma_buf, int fd, + unsigned long *ionflag, size_t bufsz, + dma_addr_t *paddr, size_t *plen, void **vaddr) +{ + int rc = 0; + + if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) { + pr_debug("%s: probe is not done, deferred\n", __func__); + return -EPROBE_DEFER; + } + + if (!dma_buf || !paddr || !vaddr || !plen) { + pr_err("%s: Invalid params\n", __func__); + return -EINVAL; + } + + /* bufsz should be 0 and fd shouldn't be 0 as of now */ + *dma_buf = dma_buf_get(fd); + pr_debug("%s: dma_buf =%pK, fd=%d\n", __func__, *dma_buf, fd); + if (IS_ERR_OR_NULL((void *)(*dma_buf))) { + pr_err("%s: dma_buf_get failed\n", __func__); + rc = -EINVAL; + goto err; + } + + if (ionflag != NULL) { + rc = dma_buf_get_flags(*dma_buf, ionflag); + if (rc) { + pr_err("%s: could not get flags for the dma_buf\n", + __func__); + goto err_ion_flag; + } + } + + rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr); + if (rc) { + pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc); + goto err_ion_flag; + } + pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, + *vaddr, bufsz); + + return 0; + +err_ion_flag: + dma_buf_put(*dma_buf); +err: + *dma_buf = NULL; + return rc; +} +EXPORT_SYMBOL(msm_audio_ion_import); + +/** + * msm_audio_ion_free - + * fress ION memory for given client and handle + * + * @dma_buf: dma_buf for the ION memory + * + * Returns 0 on success or error on failure + */ +int msm_audio_ion_free(struct dma_buf *dma_buf) +{ + int ret = 0; + + if (!dma_buf) { + pr_err("%s: dma_buf invalid\n", __func__); + return -EINVAL; + } + + ret = msm_audio_ion_unmap_kernel(dma_buf); + if (ret) + return ret; + + if (msm_audio_ion_data.smmu_enabled) { + ret = msm_audio_ion_smmu_unmap(dma_buf); + if (ret) + pr_err("%s: smmu unmap failed with ret %d\n", + __func__, ret); + } + + msm_audio_dma_buf_unmap(dma_buf); + + return 0; +} +EXPORT_SYMBOL(msm_audio_ion_free); + +/** + * msm_audio_ion_mmap - + * Audio ION memory map + * + * @abuff: audio buf pointer + * @vma: virtual mem area + * + * Returns 0 on success or error on failure + */ +int msm_audio_ion_mmap(struct audio_buffer *abuff, + struct vm_area_struct *vma) +{ + struct msm_audio_alloc_data *alloc_data = NULL; + struct sg_table *table; + unsigned long addr = vma->vm_start; + unsigned long offset = vma->vm_pgoff * PAGE_SIZE; + struct scatterlist *sg; + unsigned int i; + struct page *page; + int ret = 0; + bool found = false; + struct device *cb_dev = msm_audio_ion_data.cb_dev; + + mutex_lock(&(msm_audio_ion_data.list_mutex)); + list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list), + list) { + if (alloc_data->dma_buf == abuff->dma_buf) { + found = true; + table = alloc_data->table; + break; + } + } + mutex_unlock(&(msm_audio_ion_data.list_mutex)); + + if (!found) { + dev_err(cb_dev, + "%s: cannot find allocation, dma_buf %pK", + __func__, abuff->dma_buf); + return -EINVAL; + } + /* uncached */ + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + + /* We need to check if a page is associated with this sg list because: + * If the allocation came from a carveout we currently don't have + * pages associated with carved out memory. This might change in the + * future and we can remove this check and the else statement. + */ + page = sg_page(table->sgl); + if (page) { + pr_debug("%s: page is NOT null\n", __func__); + for_each_sg(table->sgl, sg, table->nents, i) { + unsigned long remainder = vma->vm_end - addr; + unsigned long len = sg->length; + + page = sg_page(sg); + + if (offset >= len) { + offset -= len; + continue; + } else if (offset) { + page += offset / PAGE_SIZE; + len -= offset; + offset = 0; + } + len = min(len, remainder); + pr_debug("vma=%pK, addr=%x len=%ld vm_start=%x vm_end=%x vm_page_prot=%lu\n", + vma, (unsigned int)addr, len, + (unsigned int)vma->vm_start, + (unsigned int)vma->vm_end, + (unsigned long)pgprot_val(vma->vm_page_prot)); + remap_pfn_range(vma, addr, page_to_pfn(page), len, + vma->vm_page_prot); + addr += len; + if (addr >= vma->vm_end) + return 0; + } + } else { + pr_debug("%s: page is NULL\n", __func__); + ret = -EINVAL; + } + + return ret; +} +EXPORT_SYMBOL(msm_audio_ion_mmap); + +/** + * msm_audio_populate_upper_32_bits - + * retrieve upper 32bits of 64bit address + * + * @pa: 64bit physical address + * + */ +u32 msm_audio_populate_upper_32_bits(dma_addr_t pa) +{ + return upper_32_bits(pa); +} +EXPORT_SYMBOL(msm_audio_populate_upper_32_bits); + +static const struct of_device_id msm_audio_ion_dt_match[] = { + { .compatible = "qcom,msm-audio-ion" }, + { } +}; +MODULE_DEVICE_TABLE(of, msm_audio_ion_dt_match); + +static int msm_audio_ion_probe(struct platform_device *pdev) +{ + int rc = 0; + const char *msm_audio_ion_dt = "qcom,smmu-enabled"; + bool smmu_enabled; + struct device *dev = &pdev->dev; + + if (dev->of_node == NULL) { + dev_err(dev, + "%s: device tree is not found\n", + __func__); + msm_audio_ion_data.smmu_enabled = 0; + return 0; + } + + smmu_enabled = of_property_read_bool(dev->of_node, + msm_audio_ion_dt); + msm_audio_ion_data.smmu_enabled = smmu_enabled; + + if (!smmu_enabled) { + dev_dbg(dev, "%s: SMMU is Disabled\n", __func__); + goto exit; + } + + rc = habmm_socket_open(&msm_audio_ion_hab_handle, + HAB_MMID_CREATE(MM_AUD_3, + MSM_AUDIO_SMMU_VM_HAB_MINOR_ID), + 0xFFFFFFFF, + HABMM_SOCKET_OPEN_FLAGS_SINGLE_BE_SINGLE_FE); + if (rc) { + dev_err(dev, "%s: habmm_socket_open failed %d\n", + __func__, rc); + return rc; + } + + dev_info(dev, "%s: msm_audio_ion_hab_handle %x\n", + __func__, msm_audio_ion_hab_handle); + + INIT_LIST_HEAD(&msm_audio_ion_data.alloc_list); + mutex_init(&(msm_audio_ion_data.list_mutex)); + +exit: + if (!rc) + msm_audio_ion_data.device_status |= MSM_AUDIO_ION_PROBED; + + msm_audio_ion_data.cb_dev = dev; + + return rc; +} + +static int msm_audio_ion_remove(struct platform_device *pdev) +{ + if (msm_audio_ion_data.smmu_enabled) { + if (msm_audio_ion_hab_handle) + habmm_socket_close(msm_audio_ion_hab_handle); + + mutex_destroy(&(msm_audio_ion_data.list_mutex)); + } + msm_audio_ion_data.smmu_enabled = 0; + msm_audio_ion_data.device_status = 0; + return 0; +} + +static struct platform_driver msm_audio_ion_driver = { + .driver = { + .name = "msm-audio-ion", + .owner = THIS_MODULE, + .of_match_table = msm_audio_ion_dt_match, + }, + .probe = msm_audio_ion_probe, + .remove = msm_audio_ion_remove, +}; + +int __init msm_audio_ion_init(void) +{ + return platform_driver_register(&msm_audio_ion_driver); +} + +void msm_audio_ion_exit(void) +{ + platform_driver_unregister(&msm_audio_ion_driver); +} + +MODULE_DESCRIPTION("MSM Audio ION VM module"); +MODULE_LICENSE("GPL v2"); diff --git a/include/dsp/msm-audio-event-notify.h b/include/dsp/msm-audio-event-notify.h index c730d315894f..8c515e2d8a9e 100644 --- a/include/dsp/msm-audio-event-notify.h +++ b/include/dsp/msm-audio-event-notify.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #ifndef __MSM_AUDIO_EVENT_NOTIFY_H_ @@ -8,7 +8,8 @@ #include -#if IS_ENABLED(CONFIG_SND_SOC_MSM_QDSP6V2_INTF) +#if (IS_ENABLED(CONFIG_SND_SOC_MSM_QDSP6V2_INTF) || \ + IS_ENABLED(CONFIG_SND_SOC_MSM_QDSP6V2_VM)) int msm_aud_evt_register_client(struct notifier_block *nb); int msm_aud_evt_unregister_client(struct notifier_block *nb); int msm_aud_evt_notifier_call_chain(unsigned long val, void *v); -- GitLab From d74f72b86d0180dff707d0850b6ca72cb5973bf2 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 14 May 2019 15:33:05 +0800 Subject: [PATCH 0974/1645] asoc: update missed file header to SPDX update missed file header to SPDX. Change-Id: I694c45965473d00d5a577df1cd2074becbc51372 Signed-off-by: Meng Wang --- dsp/codecs/audio_alac.c | 10 ---------- dsp/codecs/audio_ape.c | 10 ---------- dsp/codecs/audio_g711alaw.c | 10 ---------- dsp/codecs/audio_g711mlaw.c | 10 ---------- include/soc/wcd-spi-ac.h | 10 +--------- soc/wcd-spi-ac.c | 10 +--------- soc/wcd_spi_ctl_v01.c | 11 +---------- soc/wcd_spi_ctl_v01.h | 11 +---------- 8 files changed, 4 insertions(+), 78 deletions(-) diff --git a/dsp/codecs/audio_alac.c b/dsp/codecs/audio_alac.c index f7e09323dd97..a3e473f7082e 100644 --- a/dsp/codecs/audio_alac.c +++ b/dsp/codecs/audio_alac.c @@ -1,15 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/audio_ape.c b/dsp/codecs/audio_ape.c index 1e12981524c4..319828bd5465 100644 --- a/dsp/codecs/audio_ape.c +++ b/dsp/codecs/audio_ape.c @@ -1,15 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/audio_g711alaw.c b/dsp/codecs/audio_g711alaw.c index b4a1d7ee5c5b..27d7fe0b35dd 100644 --- a/dsp/codecs/audio_g711alaw.c +++ b/dsp/codecs/audio_g711alaw.c @@ -1,15 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/dsp/codecs/audio_g711mlaw.c b/dsp/codecs/audio_g711mlaw.c index 1cf8a9787040..57c7f1ae7e09 100644 --- a/dsp/codecs/audio_g711mlaw.c +++ b/dsp/codecs/audio_g711mlaw.c @@ -1,15 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include diff --git a/include/soc/wcd-spi-ac.h b/include/soc/wcd-spi-ac.h index 5131c49f3acd..e07d235e9ca1 100644 --- a/include/soc/wcd-spi-ac.h +++ b/include/soc/wcd-spi-ac.h @@ -1,13 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __WCD_SPI_AC_H__ diff --git a/soc/wcd-spi-ac.c b/soc/wcd-spi-ac.c index ee7a7a9ba57d..87bdbb2cc5bd 100644 --- a/soc/wcd-spi-ac.c +++ b/soc/wcd-spi-ac.c @@ -1,13 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/soc/wcd_spi_ctl_v01.c b/soc/wcd_spi_ctl_v01.c index 0e59ca3f23a7..a803fd0dcdbf 100644 --- a/soc/wcd_spi_ctl_v01.c +++ b/soc/wcd_spi_ctl_v01.c @@ -1,14 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include #include diff --git a/soc/wcd_spi_ctl_v01.h b/soc/wcd_spi_ctl_v01.h index dd9b1c3e5e24..683caa4166d7 100644 --- a/soc/wcd_spi_ctl_v01.h +++ b/soc/wcd_spi_ctl_v01.h @@ -1,14 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #ifndef WCD_SPI_CTL_V01_H #define WCD_SPI_CTL_V01_H -- GitLab From 166ccaeb1e87085b7c02122cd80e93ac1113d82a Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Thu, 25 Apr 2019 10:39:52 +0530 Subject: [PATCH 0975/1645] asoc: Add control to set AFE Tx loopback port AFE TX loopback is used to capture playback data from RX port and use it for echo reference. Add new control to configure Rx port to read data from in this case. Existing control was re-using EC Ref rx port control and can lead to far end configuration in undesired cases. Extend existing MultiMedia1 Output Channel control to support 10channels. Change-Id: I98f11d315e97d761ac2c8f8bf3ef387568c85082 Signed-off-by: Chaithanya Krishna Bacharaju --- asoc/msm-pcm-routing-v2.c | 356 +++++++++++++++++++++++--------------- 1 file changed, 214 insertions(+), 142 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index d5bad0fd6661..f3795be8524c 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -82,6 +82,8 @@ static bool swap_ch; static int aanc_level; static int num_app_cfg_types; static int msm_ec_ref_port_id; +static int afe_loopback_tx_port_index; +static int afe_loopback_tx_port_id = -1; #define WEIGHT_0_DB 0x4000 /* all the FEs which can support channel mixer */ @@ -857,7 +859,20 @@ static int msm_pcm_routing_get_lsm_app_type_idx(int app_type) static int get_port_id(int port_id) { - return (port_id == AFE_LOOPBACK_TX ? msm_ec_ref_port_id : port_id); + int ret = port_id; + + if (port_id == AFE_LOOPBACK_TX) { + /* + * Return afe_loopback_tx_port_id if set. Else return + * msm_ec_ref_port_id to maintain backward compatibility. + */ + if (afe_loopback_tx_port_id != -1) + ret = afe_loopback_tx_port_id; + else + ret = msm_ec_ref_port_id; + } + + return ret; } static bool is_mm_lsm_fe_id(int fe_id) @@ -3611,7 +3626,7 @@ static const struct snd_kcontrol_new channel_mixer_controls[] = { msm_pcm_put_channel_rule_index), SOC_SINGLE_EXT("MultiMedia1 Channels", SND_SOC_NOPM, - MSM_FRONTEND_DAI_MULTIMEDIA1, 8, 0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 10, 0, msm_pcm_get_out_chs, msm_pcm_put_out_chs), SOC_SINGLE_EXT("MultiMedia2 Channels", SND_SOC_NOPM, @@ -3753,6 +3768,26 @@ static const struct snd_kcontrol_new channel_mixer_controls[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Output Channel9", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1, .rshift = 8,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Output Channel10", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1, .rshift = 9,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .name = "MultiMedia2 Output Channel1", .info = msm_pcm_channel_weight_info, .get = msm_pcm_channel_weight_get, @@ -4030,227 +4065,200 @@ static int msm_ec_ref_rate_put(struct snd_kcontrol *kcontrol, return 0; } -static const char *const ec_ref_rate_text[] = {"0", "8000", "16000", - "32000", "44100", "48000", "96000", "192000", "384000"}; - -static const struct soc_enum msm_route_ec_ref_params_enum[] = { - SOC_ENUM_SINGLE_EXT(17, ec_ref_ch_text), - SOC_ENUM_SINGLE_EXT(3, ec_ref_bit_format_text), - SOC_ENUM_SINGLE_EXT(9, ec_ref_rate_text), -}; - -static const struct snd_kcontrol_new ec_ref_param_controls[] = { - SOC_ENUM_EXT("EC Reference Channels", msm_route_ec_ref_params_enum[0], - msm_ec_ref_ch_get, msm_ec_ref_ch_put), - SOC_ENUM_EXT("EC Reference Bit Format", msm_route_ec_ref_params_enum[1], - msm_ec_ref_bit_format_get, msm_ec_ref_bit_format_put), - SOC_ENUM_EXT("EC Reference SampleRate", msm_route_ec_ref_params_enum[2], - msm_ec_ref_rate_get, msm_ec_ref_rate_put), - SOC_ENUM_EXT("EC Reference Downmixed Channels", msm_route_ec_ref_params_enum[0], - msm_ec_ref_ch_downmixed_get, msm_ec_ref_ch_downmixed_put), - SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch1", SND_SOC_NOPM, 0, - 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, - NULL, msm_ec_ref_chmixer_weights_put), - SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch2", SND_SOC_NOPM, 1, - 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, - NULL, msm_ec_ref_chmixer_weights_put), - SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch3", SND_SOC_NOPM, 2, - 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, - NULL, msm_ec_ref_chmixer_weights_put), - SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch4", SND_SOC_NOPM, 3, - 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, - NULL, msm_ec_ref_chmixer_weights_put), - SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch5", SND_SOC_NOPM, 4, - 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, - NULL, msm_ec_ref_chmixer_weights_put), - SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch6", SND_SOC_NOPM, 5, - 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, - NULL, msm_ec_ref_chmixer_weights_put), -}; - -static int msm_routing_ec_ref_rx_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s: ec_ref_rx = %d", __func__, msm_route_ec_ref_rx); - mutex_lock(&routing_lock); - ucontrol->value.integer.value[0] = msm_route_ec_ref_rx; - mutex_unlock(&routing_lock); - return 0; -} - -static int msm_routing_ec_ref_rx_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int get_ec_ref_port_id(int value, int *index) { - int ec_ref_port_id; - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - struct snd_soc_dapm_update *update = NULL; - + int port_id; - mutex_lock(&routing_lock); - switch (ucontrol->value.integer.value[0]) { + switch (value) { case 0: - msm_route_ec_ref_rx = 0; - ec_ref_port_id = AFE_PORT_INVALID; + *index = 0; + port_id = AFE_PORT_INVALID; break; case 1: - msm_route_ec_ref_rx = 1; - ec_ref_port_id = SLIMBUS_0_RX; + *index = 1; + port_id = SLIMBUS_0_RX; break; case 2: - msm_route_ec_ref_rx = 2; - ec_ref_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; + *index = 2; + port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; break; case 3: - msm_route_ec_ref_rx = 3; - ec_ref_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; + *index = 3; + port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; break; case 4: - msm_route_ec_ref_rx = 4; - ec_ref_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; + *index = 4; + port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; break; case 5: - msm_route_ec_ref_rx = 5; - ec_ref_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + *index = 5; + port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; break; case 6: - msm_route_ec_ref_rx = 6; - ec_ref_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + *index = 6; + port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; break; case 7: - msm_route_ec_ref_rx = 7; - ec_ref_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; + *index = 7; + port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; break; case 9: - msm_route_ec_ref_rx = 9; - ec_ref_port_id = SLIMBUS_5_RX; + *index = 9; + port_id = SLIMBUS_5_RX; break; case 10: - msm_route_ec_ref_rx = 10; - ec_ref_port_id = SLIMBUS_1_TX; + *index = 10; + port_id = SLIMBUS_1_TX; break; case 11: - msm_route_ec_ref_rx = 11; - ec_ref_port_id = AFE_PORT_ID_QUATERNARY_TDM_TX_1; + *index = 11; + port_id = AFE_PORT_ID_QUATERNARY_TDM_TX_1; break; case 12: - msm_route_ec_ref_rx = 12; - ec_ref_port_id = AFE_PORT_ID_QUATERNARY_TDM_RX; + *index = 12; + port_id = AFE_PORT_ID_QUATERNARY_TDM_RX; break; case 13: - msm_route_ec_ref_rx = 13; - ec_ref_port_id = AFE_PORT_ID_QUATERNARY_TDM_RX_1; + *index = 13; + port_id = AFE_PORT_ID_QUATERNARY_TDM_RX_1; break; case 14: - msm_route_ec_ref_rx = 14; - ec_ref_port_id = AFE_PORT_ID_QUATERNARY_TDM_RX_2; + *index = 14; + port_id = AFE_PORT_ID_QUATERNARY_TDM_RX_2; break; case 15: - msm_route_ec_ref_rx = 15; - ec_ref_port_id = SLIMBUS_6_RX; + *index = 15; + port_id = SLIMBUS_6_RX; break; case 16: - msm_route_ec_ref_rx = 16; - ec_ref_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; + *index = 16; + port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; break; case 17: - msm_route_ec_ref_rx = 17; - ec_ref_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; + *index = 17; + port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; break; case 18: - msm_route_ec_ref_rx = 18; - ec_ref_port_id = AFE_PORT_ID_TERTIARY_TDM_TX; + *index = 18; + port_id = AFE_PORT_ID_TERTIARY_TDM_TX; break; case 19: - msm_route_ec_ref_rx = 19; - ec_ref_port_id = AFE_PORT_ID_USB_RX; + *index = 19; + port_id = AFE_PORT_ID_USB_RX; break; case 20: - msm_route_ec_ref_rx = 20; - ec_ref_port_id = AFE_PORT_ID_INT0_MI2S_RX; + *index = 20; + port_id = AFE_PORT_ID_INT0_MI2S_RX; break; case 21: - msm_route_ec_ref_rx = 21; - ec_ref_port_id = AFE_PORT_ID_INT4_MI2S_RX; + *index = 21; + port_id = AFE_PORT_ID_INT4_MI2S_RX; break; case 22: - msm_route_ec_ref_rx = 22; - ec_ref_port_id = AFE_PORT_ID_INT3_MI2S_TX; + *index = 22; + port_id = AFE_PORT_ID_INT3_MI2S_TX; break; case 23: - msm_route_ec_ref_rx = 23; - ec_ref_port_id = AFE_PORT_ID_HDMI_OVER_DP_RX; + *index = 23; + port_id = AFE_PORT_ID_HDMI_OVER_DP_RX; break; case 24: - msm_route_ec_ref_rx = 24; - ec_ref_port_id = AFE_PORT_ID_WSA_CODEC_DMA_RX_0; + *index = 24; + port_id = AFE_PORT_ID_WSA_CODEC_DMA_RX_0; break; case 25: - msm_route_ec_ref_rx = 25; - ec_ref_port_id = AFE_PORT_ID_WSA_CODEC_DMA_RX_1; + *index = 25; + port_id = AFE_PORT_ID_WSA_CODEC_DMA_RX_1; break; case 26: - msm_route_ec_ref_rx = 26; - ec_ref_port_id = AFE_PORT_ID_WSA_CODEC_DMA_TX_0; + *index = 26; + port_id = AFE_PORT_ID_WSA_CODEC_DMA_TX_0; break; case 27: - msm_route_ec_ref_rx = 27; - ec_ref_port_id = AFE_PORT_ID_WSA_CODEC_DMA_TX_1; + *index = 27; + port_id = AFE_PORT_ID_WSA_CODEC_DMA_TX_1; break; case 28: - msm_route_ec_ref_rx = 28; - ec_ref_port_id = AFE_PORT_ID_WSA_CODEC_DMA_TX_2; + *index = 28; + port_id = AFE_PORT_ID_WSA_CODEC_DMA_TX_2; break; case 29: - msm_route_ec_ref_rx = 29; - ec_ref_port_id = SLIMBUS_7_RX; + *index = 29; + port_id = SLIMBUS_7_RX; break; case 30: - msm_route_ec_ref_rx = 30; - ec_ref_port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_0; + *index = 30; + port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_0; break; case 31: - msm_route_ec_ref_rx = 31; - ec_ref_port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_1; + *index = 31; + port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_1; break; case 32: - msm_route_ec_ref_rx = 32; - ec_ref_port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_2; + *index = 32; + port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_2; break; case 33: - msm_route_ec_ref_rx = 33; - ec_ref_port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_3; + *index = 33; + port_id = AFE_PORT_ID_RX_CODEC_DMA_RX_3; break; case 34: - msm_route_ec_ref_rx = 34; - ec_ref_port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_0; + *index = 34; + port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_0; break; case 35: - msm_route_ec_ref_rx = 35; - ec_ref_port_id = AFE_PORT_ID_TERTIARY_TDM_RX_2; + *index = 35; + port_id = AFE_PORT_ID_TERTIARY_TDM_RX_2; break; case 36: - msm_route_ec_ref_rx = 36; - ec_ref_port_id = AFE_PORT_ID_SECONDARY_TDM_TX; + *index = 36; + port_id = AFE_PORT_ID_SECONDARY_TDM_TX; break; default: - msm_route_ec_ref_rx = 0; /* NONE */ - pr_err("%s EC ref rx %ld not valid\n", - __func__, ucontrol->value.integer.value[0]); - ec_ref_port_id = AFE_PORT_INVALID; + *index = 0; /* NONE */ + pr_err("%s: Invalid value %d\n", __func__, value); + port_id = AFE_PORT_INVALID; break; } - msm_ec_ref_port_id = ec_ref_port_id; - adm_ec_ref_rx_id(ec_ref_port_id); - pr_debug("%s: msm_route_ec_ref_rx = %d\n", - __func__, msm_route_ec_ref_rx); + + return port_id; +} + +static int msm_routing_afe_lb_tx_port_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: port index = %d", __func__, afe_loopback_tx_port_index); + mutex_lock(&routing_lock); + ucontrol->value.integer.value[0] = afe_loopback_tx_port_index; mutex_unlock(&routing_lock); - snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, - msm_route_ec_ref_rx, e, update); + + return 0; +} + +static int msm_routing_afe_lb_tx_port_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int value = ucontrol->value.integer.value[0]; + + mutex_lock(&routing_lock); + afe_loopback_tx_port_id = get_ec_ref_port_id(value, + &afe_loopback_tx_port_index); + pr_debug("%s: afe_loopback_tx_port_index = %d\n", + __func__, afe_loopback_tx_port_index); + mutex_unlock(&routing_lock); + return 0; } +static const char *const ec_ref_rate_text[] = {"0", "8000", "16000", + "32000", "44100", "48000", "96000", "192000", "384000"}; + +static const struct soc_enum msm_route_ec_ref_params_enum[] = { + SOC_ENUM_SINGLE_EXT(17, ec_ref_ch_text), + SOC_ENUM_SINGLE_EXT(3, ec_ref_bit_format_text), + SOC_ENUM_SINGLE_EXT(9, ec_ref_rate_text), +}; + static const char *const ec_ref_rx[] = { "None", "SLIM_RX", "I2S_RX", "PRI_MI2S_TX", "SEC_MI2S_TX", "TERT_MI2S_TX", "QUAT_MI2S_TX", "SEC_I2S_RX", "PROXY_RX", @@ -4268,6 +4276,70 @@ static const struct soc_enum msm_route_ec_ref_rx_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ec_ref_rx), ec_ref_rx), }; +static const struct snd_kcontrol_new ec_ref_param_controls[] = { + SOC_ENUM_EXT("EC Reference Channels", msm_route_ec_ref_params_enum[0], + msm_ec_ref_ch_get, msm_ec_ref_ch_put), + SOC_ENUM_EXT("EC Reference Bit Format", msm_route_ec_ref_params_enum[1], + msm_ec_ref_bit_format_get, msm_ec_ref_bit_format_put), + SOC_ENUM_EXT("EC Reference SampleRate", msm_route_ec_ref_params_enum[2], + msm_ec_ref_rate_get, msm_ec_ref_rate_put), + SOC_ENUM_EXT("EC Reference Downmixed Channels", + msm_route_ec_ref_params_enum[0], + msm_ec_ref_ch_downmixed_get, msm_ec_ref_ch_downmixed_put), + SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch1", SND_SOC_NOPM, + 0, 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, NULL, + msm_ec_ref_chmixer_weights_put), + SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch2", SND_SOC_NOPM, + 1, 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, NULL, + msm_ec_ref_chmixer_weights_put), + SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch3", SND_SOC_NOPM, + 2, 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, NULL, + msm_ec_ref_chmixer_weights_put), + SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch4", SND_SOC_NOPM, + 3, 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, NULL, + msm_ec_ref_chmixer_weights_put), + SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch5", SND_SOC_NOPM, + 4, 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, NULL, + msm_ec_ref_chmixer_weights_put), + SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch6", SND_SOC_NOPM, + 5, 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, NULL, + msm_ec_ref_chmixer_weights_put), + SOC_ENUM_EXT("AFE_LOOPBACK_TX Port", msm_route_ec_ref_rx_enum[0], + msm_routing_afe_lb_tx_port_get, msm_routing_afe_lb_tx_port_put), +}; + +static int msm_routing_ec_ref_rx_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: ec_ref_rx = %d", __func__, msm_route_ec_ref_rx); + mutex_lock(&routing_lock); + ucontrol->value.integer.value[0] = msm_route_ec_ref_rx; + mutex_unlock(&routing_lock); + + return 0; +} + +static int msm_routing_ec_ref_rx_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int value = ucontrol->value.integer.value[0]; + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_dapm_update *update = NULL; + + mutex_lock(&routing_lock); + msm_ec_ref_port_id = get_ec_ref_port_id(value, &msm_route_ec_ref_rx); + adm_ec_ref_rx_id(msm_ec_ref_port_id); + pr_debug("%s: msm_route_ec_ref_rx = %d\n", + __func__, msm_route_ec_ref_rx); + mutex_unlock(&routing_lock); + + snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, + msm_route_ec_ref_rx, e, update); + return 0; +} + static const struct snd_kcontrol_new ext_ec_ref_mux_ul1 = SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL1 MUX Mux", msm_route_ec_ref_rx_enum[0], -- GitLab From 5074a712ab6e288ff364a3e0fe0bfa7b1bc965b0 Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Thu, 25 Apr 2019 10:52:29 +0530 Subject: [PATCH 0976/1645] asoc: qcs405: Add AFE Tx loopback controls AFE Tx loopback is used to capture playback data from Rx port and use it for echo reference. Add controls to configure capture backend channels, sample rate and format. Change-Id: I68bd89461f3f37870a6d946fb03fe4124ee2fa6f Signed-off-by: Chaithanya Krishna Bacharaju --- asoc/qcs405.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 04557483aa1f..554779d4c1c7 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -440,6 +440,12 @@ static struct dev_config aux_pcm_tx_cfg[] = { [SEN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; +static struct dev_config afe_lb_tx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + static int msm_vi_feed_tx_ch = 2; static const char *const slim_rx_ch_text[] = {"One", "Two"}; static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four", @@ -602,6 +608,10 @@ static SOC_ENUM_SINGLE_EXT_DECL(spdif_rx_chs, spdif_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(spdif_tx_chs, spdif_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(spdif_rx_format, spdif_bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(spdif_tx_format, spdif_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(afe_lb_tx_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(afe_lb_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(afe_lb_tx_sample_rate, + cdc_dma_sample_rate_text); static struct platform_device *spdev; @@ -3444,6 +3454,184 @@ static int msm_spdif_tx_format_put(struct snd_kcontrol *kcontrol, return 0; } +static int afe_lb_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: afe_lb_tx_ch = %d\n", __func__, + afe_lb_tx_cfg.channels); + ucontrol->value.integer.value[0] = afe_lb_tx_cfg.channels - 1; + return 0; +} + +static int afe_lb_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + afe_lb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: afe_lb_tx_ch = %d\n", __func__, afe_lb_tx_cfg.channels); + return 0; +} + +static int afe_lb_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (afe_lb_tx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + default: + sample_rate_val = 6; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: afe_lb_tx_sample_rate = %d\n", __func__, + afe_lb_tx_cfg.sample_rate); + return 0; +} + +static int afe_lb_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, afe_lb_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + afe_lb_tx_cfg.sample_rate); + return 0; +} + +static int afe_lb_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (afe_lb_tx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: afe_lb_tx_format = %d, ucontrol value = %ld\n", + __func__, afe_lb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int afe_lb_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 3: + afe_lb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + afe_lb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + afe_lb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + afe_lb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + + pr_debug("%s: afe_lb_tx_format = %d, ucontrol value = %ld\n", + __func__, afe_lb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + static const struct snd_kcontrol_new msm_snd_sb_controls[] = { SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, slim_rx_ch_get, slim_rx_ch_put), @@ -3826,6 +4014,13 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_spdif_rx_format_get, msm_spdif_rx_format_put), SOC_ENUM_EXT("SEC_SPDIF_TX Format", spdif_tx_format, msm_spdif_tx_format_get, msm_spdif_tx_format_put), + SOC_ENUM_EXT("AFE_LOOPBACK_TX Channels", afe_lb_tx_chs, + afe_lb_tx_ch_get, afe_lb_tx_ch_put), + SOC_ENUM_EXT("AFE_LOOPBACK_TX Format", afe_lb_tx_format, + afe_lb_tx_format_get, afe_lb_tx_format_put), + SOC_ENUM_EXT("AFE_LOOPBACK_TX SampleRate", afe_lb_tx_sample_rate, + afe_lb_tx_sample_rate_get, + afe_lb_tx_sample_rate_put), }; static int msm_snd_enable_codec_ext_clk(struct snd_soc_component *component, @@ -4610,6 +4805,13 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, spdif_tx_cfg[SEC_SPDIF_TX].channels; break; + case MSM_BACKEND_DAI_AFE_LOOPBACK_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + afe_lb_tx_cfg.bit_format); + rate->min = rate->max = afe_lb_tx_cfg.sample_rate; + channels->min = channels->max = afe_lb_tx_cfg.channels; + break; + default: rate->min = rate->max = SAMPLING_RATE_48KHZ; break; @@ -7630,6 +7832,7 @@ static struct snd_soc_dai_link msm_afe_rxtx_lb_be_dai_link[] = { .no_pcm = 1, .dpcm_capture = 1, .id = MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_pmdown_time = 1, .ignore_suspend = 1, }, -- GitLab From 53fbc925c91c8ed1373c9611040f0e117c28e005 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 26 Apr 2019 14:38:29 +0530 Subject: [PATCH 0977/1645] asoc: Ratelimit error logs to avoid excessive logging Ratelimit error logs of boundary check conditions in audio effects driver to avoid excessive logging. CRs-Fixed: 2426159 Change-Id: Iaf10eee281389773a21340997e3ffbe88c6e79f6 Signed-off-by: Aditya Bavanari --- asoc/msm-audio-effects-q6-v2.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/asoc/msm-audio-effects-q6-v2.c b/asoc/msm-audio-effects-q6-v2.c index 7ab6db4d3f30..bdb00592f12c 100644 --- a/asoc/msm-audio-effects-q6-v2.c +++ b/asoc/msm-audio-effects-q6-v2.c @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. */ #include +#include #include #include #include @@ -15,7 +16,8 @@ #define GET_NEXT(ptr, upper_limit, rc) \ ({ \ if (((ptr) + 1) > (upper_limit)) { \ - pr_err("%s: param list out of boundary\n", __func__); \ + pr_err_ratelimited("%s: param list out of boundary\n", \ + __func__); \ (rc) = -EINVAL; \ } \ ((rc) == 0) ? *(ptr)++ : -EINVAL; \ @@ -24,7 +26,8 @@ #define CHECK_PARAM_LEN(len, max_len, tag, rc) \ do { \ if ((len) > (max_len)) { \ - pr_err("%s: params length overflows\n", (tag)); \ + pr_err_ratelimited("%s: params length overflows\n", \ + (tag)); \ (rc) = -EINVAL; \ } \ } while (0) @@ -244,7 +247,8 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, param_data = (u8 *) &virtualizer->gain_adjust; break; default: - pr_err("%s: Invalid command to set config\n", __func__); + pr_err_ratelimited("%s: Invalid command to set config\n", + __func__); continue; } if (rc) @@ -678,7 +682,8 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, param_data = (u8 *) &reverb->density; break; default: - pr_err("%s: Invalid command to set config\n", __func__); + pr_err_ratelimited("%s: Invalid command to set config\n", + __func__); continue; } if (rc) @@ -831,7 +836,8 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, param_data = (u8 *) &bass_boost->strength; break; default: - pr_err("%s: Invalid command to set config\n", __func__); + pr_err_ratelimited("%s: Invalid command to set config\n", + __func__); continue; } if (rc) @@ -956,7 +962,8 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, param_data = (u8 *) values; break; default: - pr_err("%s: Invalid command to set config\n", __func__); + pr_err_ratelimited("%s: Invalid command to set config\n", + __func__); continue; } if (rc) @@ -1214,7 +1221,8 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, param_data = (u8 *) &eq->freq_millihertz; break; default: - pr_err("%s: Invalid command to set config\n", __func__); + pr_err_ratelimited("%s: Invalid command to set config\n", + __func__); continue; } if (rc) @@ -1335,7 +1343,7 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, "VOLUME/VOLUME2_GAIN_MASTER", rc); break; default: - pr_err("%s: Invalid command id: %d to set config\n", + pr_err_ratelimited("%s: Invalid command id: %d to set config\n", __func__, command_id); continue; } -- GitLab From 14efed6eb7b595a044e5dbbee08801a8e8f9fe2f Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Thu, 7 Mar 2019 13:16:50 +0530 Subject: [PATCH 0978/1645] asoc: Ratelimit error logs Ratelimit error logs to avoid excessive logging during ssr/pdr. Change-Id: Icdc9823cef5b070ed70cdd002bb3cd00d482a869 Signed-off-by: Ramprasad Katkam --- asoc/codecs/audio-ext-clk-up.c | 4 ++-- asoc/codecs/bolero/tx-macro.c | 2 +- asoc/codecs/bolero/wsa-macro.c | 4 ++-- dsp/q6afe.c | 4 ++-- soc/swr-mstr-ctrl.c | 4 +++- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index e6e68adf8895..6bdf00ffb66f 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -70,7 +70,7 @@ static int audio_ext_clk_prepare(struct clk_hw *hw) clk_priv->clk_cfg.enable = 1; ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg); if (ret < 0) { - pr_err("%s afe_set_digital_codec_core_clock failed\n", + pr_err_ratelimited("%s afe_set_digital_codec_core_clock failed\n", __func__); return ret; } @@ -112,7 +112,7 @@ static void audio_ext_clk_unprepare(struct clk_hw *hw) clk_priv->clk_cfg.enable = 0; ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg); if (ret < 0) - pr_err("%s: afe_set_lpass_clk_cfg failed, ret = %d\n", + pr_err_ratelimited("%s: afe_set_lpass_clk_cfg failed, ret = %d\n", __func__, ret); } diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 49b7da573525..51930eed4034 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -212,7 +212,7 @@ static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv, TX_CORE_CLK, true); if (ret < 0) { - dev_err(tx_priv->dev, + dev_err_ratelimited(tx_priv->dev, "%s: request clock enable failed\n", __func__); goto exit; diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index d1ba34620e57..68f1cb98efb7 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -815,7 +815,7 @@ static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv, wsa_priv->default_clk_id, true); if (ret < 0) { - dev_err(wsa_priv->dev, + dev_err_ratelimited(wsa_priv->dev, "%s: wsa request clock enable failed\n", __func__); goto exit; @@ -2637,7 +2637,7 @@ static int wsa_swrm_clock(void *handle, bool enable) if (ret < 0) { msm_cdc_pinctrl_select_sleep_state( wsa_priv->wsa_swr_gpio_p); - dev_err(wsa_priv->dev, + dev_err_ratelimited(wsa_priv->dev, "%s: wsa request clock enable failed\n", __func__); goto exit; diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 7a510be5c06c..23d30bc4f2a1 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -7578,7 +7578,7 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg) ret = afe_q6_interface_prepare(); if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + pr_err_ratelimited("%s: Q6 interface prepare failed %d\n", __func__, ret); return ret; } @@ -7599,7 +7599,7 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg) ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr, (u8 *) cfg); if (ret < 0) - pr_err("%s: AFE clk cfg failed with ret %d\n", + pr_err_ratelimited("%s: AFE clk cfg failed with ret %d\n", __func__, ret); mutex_unlock(&this_afe.afe_cmd_lock); diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index c9cccf6d480c..5bab95f8863a 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -249,7 +249,7 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) if (swrm->clk_ref_count == 1) { ret = swrm->clk(swrm->handle, true); if (ret) { - dev_err(swrm->dev, + dev_err_ratelimited(swrm->dev, "%s: clock enable req failed", __func__); --swrm->clk_ref_count; @@ -1277,6 +1277,8 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) mutex_lock(&swrm->reslock); if (swrm_clk_request(swrm, true)) { + dev_err_ratelimited(swrm->dev, "%s:clk request failed\n", + __func__); mutex_unlock(&swrm->reslock); goto exit; } -- GitLab From 70df516a6000107dd914bb0d9cffebfba41659e6 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 14 May 2019 17:33:40 -0700 Subject: [PATCH 0979/1645] asoc: codecs: bolero: Add adc1 condition to tx hold callback TX hold callback returns without making a callback to external codec if the ADC with number one is called. Add the condition for the missing ADC to make the callback for ADC1. Change-Id: Iec480b40cfbe199fbe06151abd99d9ad6aaf9c9d Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/bolero-cdc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 45e993684db1..e67dc7924ff7 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -287,6 +287,8 @@ void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n) event = BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR; if (adc_n == BOLERO_ADC0) amic = 0x1; + else if (adc_n == BOLERO_ADC1) + amic = 0x2; else if (adc_n == BOLERO_ADC2) amic = 0x2; else if (adc_n == BOLERO_ADC3) -- GitLab From c3d8c9f2c3cd78e1fdb83e4a1b00a9476c10be36 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 15 May 2019 15:19:56 -0700 Subject: [PATCH 0980/1645] asoc: codecs: wcd938x: Read and store mic bias value Mic bias value is needed in case of special headset detection logic and the same needs to be read and stored from device tree to be used by mbhc driver. Change-Id: I11c8ac6b0abc7ba04b6750c59405794bc768dc42 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/wcd938x-mbhc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/asoc/codecs/wcd938x/wcd938x-mbhc.c b/asoc/codecs/wcd938x/wcd938x-mbhc.c index 2516943ded62..b9bbdaeb54c2 100644 --- a/asoc/codecs/wcd938x/wcd938x-mbhc.c +++ b/asoc/codecs/wcd938x/wcd938x-mbhc.c @@ -1032,6 +1032,7 @@ int wcd938x_mbhc_init(struct wcd938x_mbhc **mbhc, struct wcd938x_mbhc *wcd938x_mbhc = NULL; struct wcd_mbhc *wcd_mbhc = NULL; int ret = 0; + struct wcd938x_pdata *pdata; if (!component) { pr_err("%s: component is NULL\n", __func__); @@ -1055,6 +1056,15 @@ int wcd938x_mbhc_init(struct wcd938x_mbhc **mbhc, /* Setting default mbhc detection logic to ADC */ wcd_mbhc->mbhc_detection_logic = WCD_DETECTION_ADC; + pdata = dev_get_platdata(component->dev); + if (!pdata) { + dev_err(component->dev, "%s: pdata pointer is NULL\n", + __func__); + ret = -EINVAL; + goto err; + } + wcd_mbhc->micb_mv = pdata->micbias.micb2_mv; + ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb, &intr_ids, wcd_mbhc_registers, WCD938X_ZDET_SUPPORTED); -- GitLab From 090de46cadea8b6de77d0d53c4ca8bce33fd3304 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 13 May 2019 15:21:54 -0700 Subject: [PATCH 0981/1645] asoc: codecs: Add inline keyword to all stub functions Add inline keyword to stub functions to compile them inline when the corresponding feature config is disabled. Change-Id: I933d508fc0fd5c2ad8daa26be7d39eea2a3434b9 Signed-off-by: Karthikeyan Mani --- include/asoc/core.h | 40 ++++++++++++++++++++-------------------- include/soc/snd_event.h | 4 ++-- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/include/asoc/core.h b/include/asoc/core.h index c6e544e3997f..67c97d627d55 100644 --- a/include/asoc/core.h +++ b/include/asoc/core.h @@ -437,98 +437,98 @@ static inline int __init wcd9xxx_irq_of_init(struct device_node *node, int wcd9xxx_init(void); void wcd9xxx_exit(void); #else -int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg) +static inline int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg) { return 0; } -int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg, +static inline int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg, u8 val) { return 0; } -int wcd9xxx_get_logical_addresses(u8 *pgd_la, u8 *inf_la) +static inline int wcd9xxx_get_logical_addresses(u8 *pgd_la, u8 *inf_la) { return 0; } -int wcd9xxx_slim_write_repeat(struct wcd9xxx *wcd9xxx, unsigned short reg, +static inline int wcd9xxx_slim_write_repeat(struct wcd9xxx *wcd9xxx, unsigned short reg, int bytes, void *src) { return 0; } -int wcd9xxx_slim_reserve_bw(struct wcd9xxx *wcd9xxx, +static inline int wcd9xxx_slim_reserve_bw(struct wcd9xxx *wcd9xxx, u32 bw_ops, bool commit) { return 0; } -int wcd9xxx_set_power_state(struct wcd9xxx *wcd9xxx, enum codec_power_states +static inline int wcd9xxx_set_power_state(struct wcd9xxx *wcd9xxx, enum codec_power_states cdc_power_state, enum wcd_power_regions pwr_region) { return 0; } -int wcd9xxx_get_current_power_state(struct wcd9xxx *wcd9xxx, +static inline int wcd9xxx_get_current_power_state(struct wcd9xxx *wcd9xxx, enum wcd_power_regions pwr_region) { return 0; } -int wcd9xxx_page_write(struct wcd9xxx *wcd9xxx, unsigned short *reg) +static inline int wcd9xxx_page_write(struct wcd9xxx *wcd9xxx, unsigned short *reg) { return 0; } -int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx, +static inline int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx, struct wcd9xxx_reg_val *bulk_reg, unsigned int size, bool interface) { return 0; } -extern int wcd9xxx_core_res_init( +static inline int wcd9xxx_core_res_init( struct wcd9xxx_core_resource *wcd9xxx_core_res, int num_irqs, int num_irq_regs, struct regmap *wcd_regmap) { return 0; } -extern void wcd9xxx_core_res_deinit( +static inline void wcd9xxx_core_res_deinit( struct wcd9xxx_core_resource *wcd9xxx_core_res) { } -extern int wcd9xxx_core_res_suspend( +static inline int wcd9xxx_core_res_suspend( struct wcd9xxx_core_resource *wcd9xxx_core_res, pm_message_t pmesg) { return 0; } -extern int wcd9xxx_core_res_resume( +static inline int wcd9xxx_core_res_resume( struct wcd9xxx_core_resource *wcd9xxx_core_res) { return 0; } -extern int wcd9xxx_core_irq_init( +static inline int wcd9xxx_core_irq_init( struct wcd9xxx_core_resource *wcd9xxx_core_res) { return 0; } -extern int wcd9xxx_assign_irq(struct wcd9xxx_core_resource *wcd9xxx_core_res, +static inline int wcd9xxx_assign_irq(struct wcd9xxx_core_resource *wcd9xxx_core_res, unsigned int irq, unsigned int irq_base) { return 0; } -extern enum wcd9xxx_intf_status wcd9xxx_get_intf_type(void) +static inline enum wcd9xxx_intf_status wcd9xxx_get_intf_type(void) { return 0; } -extern void wcd9xxx_set_intf_type(enum wcd9xxx_intf_status int_state) +static inline void wcd9xxx_set_intf_type(enum wcd9xxx_intf_status int_state) { } -extern enum wcd9xxx_pm_state wcd9xxx_pm_cmpxchg( +static inline enum wcd9xxx_pm_state wcd9xxx_pm_cmpxchg( struct wcd9xxx_core_resource *wcd9xxx_core_res, enum wcd9xxx_pm_state o, enum wcd9xxx_pm_state n) @@ -541,11 +541,11 @@ static inline int __init wcd9xxx_irq_of_init(struct device_node *node, return 0; } -int wcd9xxx_init(void) +static inline int wcd9xxx_init(void) { return 0; } -void wcd9xxx_exit(void) +static inline void wcd9xxx_exit(void) { } diff --git a/include/soc/snd_event.h b/include/soc/snd_event.h index ec92a68a5112..6561afad45bf 100644 --- a/include/soc/snd_event.h +++ b/include/soc/snd_event.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #ifndef _SND_EVENT_H_ @@ -33,7 +33,7 @@ int snd_event_notify(struct device *dev, unsigned int state); void snd_event_mstr_add_client(struct snd_event_clients **snd_clients, int (*compare)(struct device *, void *), void *data); -inline bool is_snd_event_fwk_enabled(void) +static inline bool is_snd_event_fwk_enabled(void) { return 1; } -- GitLab From 1572b9f03f4b46390ba047cf1ca791536fd710df Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 16 May 2019 14:56:31 -0700 Subject: [PATCH 0982/1645] asoc: routing: clean up bootup errors Fix errors shown during bootup to enable cleaner bootup process. CRs-Fixed: 2455248 Change-Id: I239d366674cc33276deda8dc61e1daa102a49ca7 Signed-off-by: Vignesh Kulothungan --- asoc/msm-pcm-routing-v2.c | 74 +++------------------------------------ 1 file changed, 4 insertions(+), 70 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index d5bad0fd6661..f70c234e08be 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -13721,7 +13721,7 @@ MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, SOC_DOUBLE_EXT("QUIN_MI2S_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX3_MMode1", SND_SOC_NOPM, + SOC_DOUBLE_EXT("PRI_TDM_TX_3_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; @@ -13810,8 +13810,8 @@ static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { SOC_DOUBLE_EXT("QUIN_MI2S_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX3_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE1, + SOC_DOUBLE_EXT("PRI_TDM_TX_3_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; @@ -22515,11 +22515,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_Voice Mixer"}, - {"PRI_TDM_RX_0_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"PRI_TDM_RX_0_Voice Mixer", "Voice2", "VOICE2_DL"}, {"PRI_TDM_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_TDM_RX_0_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"PRI_TDM_RX_0_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"PRI_TDM_RX_0_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"PRI_TDM_RX_0_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, {"PRI_TDM_RX_0_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, @@ -22529,11 +22525,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0_Voice Mixer"}, - {"PRI_TDM_RX_1_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"PRI_TDM_RX_1_Voice Mixer", "Voice2", "VOICE2_DL"}, {"PRI_TDM_RX_1_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_TDM_RX_1_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"PRI_TDM_RX_1_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"PRI_TDM_RX_1_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"PRI_TDM_RX_1_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, {"PRI_TDM_RX_1_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, @@ -22543,11 +22535,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_1_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1_Voice Mixer"}, - {"PRI_TDM_RX_2_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"PRI_TDM_RX_2_Voice Mixer", "Voice2", "VOICE2_DL"}, {"PRI_TDM_RX_2_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_TDM_RX_2_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"PRI_TDM_RX_2_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"PRI_TDM_RX_2_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"PRI_TDM_RX_2_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, {"PRI_TDM_RX_2_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, @@ -22557,11 +22545,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_2_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2_Voice Mixer"}, - {"PRI_TDM_RX_3_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, - {"PRI_TDM_RX_3_Voice Mixer", "Voice2", "VOICE2_DL"}, {"PRI_TDM_RX_3_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_TDM_RX_3_Voice Mixer", "VoLTE", "VoLTE_DL"}, - {"PRI_TDM_RX_3_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, {"PRI_TDM_RX_3_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"PRI_TDM_RX_3_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, {"PRI_TDM_RX_3_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, @@ -22709,55 +22693,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL28", NULL, "AUDIO_REF_EC_UL28 MUX"}, {"MM_UL29", NULL, "AUDIO_REF_EC_UL29 MUX"}, - {"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"}, - {"Voice_Tx Mixer", "PRI_MI2S_TX_Voice", "PRI_MI2S_TX"}, - {"Voice_Tx Mixer", "MI2S_TX_Voice", "MI2S_TX"}, - {"Voice_Tx Mixer", "TERT_MI2S_TX_Voice", "TERT_MI2S_TX"}, - {"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"}, - {"Voice_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice", "INT_BT_SCO_TX"}, - {"Voice_Tx Mixer", "AFE_PCM_TX_Voice", "PCM_TX"}, - {"Voice_Tx Mixer", "AUX_PCM_TX_Voice", "AUX_PCM_TX"}, - {"Voice_Tx Mixer", "SEC_AUX_PCM_TX_Voice", "SEC_AUX_PCM_TX"}, - {"Voice_Tx Mixer", "SEC_MI2S_TX_Voice", "SEC_MI2S_TX"}, - {"Voice_Tx Mixer", "PRI_TDM_TX_3_Voice", "PRI_TDM_TX_3"}, - {"CS-VOICE_UL1", NULL, "Voice_Tx Mixer"}, - - {"Voice2_Tx Mixer", "PRI_TX_Voice2", "PRI_I2S_TX"}, - {"Voice2_Tx Mixer", "PRI_MI2S_TX_Voice2", "PRI_MI2S_TX"}, - {"Voice2_Tx Mixer", "MI2S_TX_Voice2", "MI2S_TX"}, - {"Voice2_Tx Mixer", "TERT_MI2S_TX_Voice2", "TERT_MI2S_TX"}, - {"Voice2_Tx Mixer", "SLIM_0_TX_Voice2", "SLIMBUS_0_TX"}, - {"Voice2_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice2", "INT_BT_SCO_TX"}, - {"Voice2_Tx Mixer", "AFE_PCM_TX_Voice2", "PCM_TX"}, - {"Voice2_Tx Mixer", "AUX_PCM_TX_Voice2", "AUX_PCM_TX"}, - {"Voice2_Tx Mixer", "SEC_AUX_PCM_TX_Voice2", "SEC_AUX_PCM_TX"}, - {"Voice2_Tx Mixer", "PRI_TDM_TX_3_Voice2", "PRI_TDM_TX_3"}, - {"VOICE2_UL", NULL, "Voice2_Tx Mixer"}, - - {"VoLTE_Tx Mixer", "PRI_TX_VoLTE", "PRI_I2S_TX"}, - {"VoLTE_Tx Mixer", "SLIM_0_TX_VoLTE", "SLIMBUS_0_TX"}, - {"VoLTE_Tx Mixer", "INTERNAL_BT_SCO_TX_VoLTE", "INT_BT_SCO_TX"}, - {"VoLTE_Tx Mixer", "AFE_PCM_TX_VoLTE", "PCM_TX"}, - {"VoLTE_Tx Mixer", "AUX_PCM_TX_VoLTE", "AUX_PCM_TX"}, - {"VoLTE_Tx Mixer", "SEC_AUX_PCM_TX_VoLTE", "SEC_AUX_PCM_TX"}, - {"VoLTE_Tx Mixer", "MI2S_TX_VoLTE", "MI2S_TX"}, - {"VoLTE_Tx Mixer", "PRI_MI2S_TX_VoLTE", "PRI_MI2S_TX"}, - {"VoLTE_Tx Mixer", "TERT_MI2S_TX_VoLTE", "TERT_MI2S_TX"}, - {"VoLTE_Tx Mixer", "PRI_TDM_TX_3_VoLTE", "PRI_TDM_TX_3"}, - {"VoLTE_UL", NULL, "VoLTE_Tx Mixer"}, - - {"VoWLAN_Tx Mixer", "PRI_TX_VoWLAN", "PRI_I2S_TX"}, - {"VoWLAN_Tx Mixer", "SLIM_0_TX_VoWLAN", "SLIMBUS_0_TX"}, - {"VoWLAN_Tx Mixer", "INTERNAL_BT_SCO_TX_VoWLAN", "INT_BT_SCO_TX"}, - {"VoWLAN_Tx Mixer", "AFE_PCM_TX_VoWLAN", "PCM_TX"}, - {"VoWLAN_Tx Mixer", "AUX_PCM_TX_VoWLAN", "AUX_PCM_TX"}, - {"VoWLAN_Tx Mixer", "SEC_AUX_PCM_TX_VoWLAN", "SEC_AUX_PCM_TX"}, - {"VoWLAN_Tx Mixer", "MI2S_TX_VoWLAN", "MI2S_TX"}, - {"VoWLAN_Tx Mixer", "PRI_MI2S_TX_VoWLAN", "PRI_MI2S_TX"}, - {"VoWLAN_Tx Mixer", "TERT_MI2S_TX_VoWLAN", "TERT_MI2S_TX"}, - {"VoWLAN_Tx Mixer", "PRI_TDM_TX_3_VoWLAN", "PRI_TDM_TX_3"}, - {"VoWLAN_UL", NULL, "VoWLAN_Tx Mixer"}, - {"VoiceMMode1_Tx Mixer", "PRI_TX_MMode1", "PRI_I2S_TX"}, {"VoiceMMode1_Tx Mixer", "PRI_MI2S_TX_MMode1", "PRI_MI2S_TX"}, {"VoiceMMode1_Tx Mixer", "MI2S_TX_MMode1", "MI2S_TX"}, @@ -22810,7 +22745,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_5_MMode2", "TX_CDC_DMA_TX_5"}, {"VoiceMMode2_Tx Mixer", "QUAT_MI2S_TX_MMode2", "QUAT_MI2S_TX"}, {"VoiceMMode2_Tx Mixer", "QUIN_MI2S_TX_MMode2", "QUIN_MI2S_TX"}, - {"VoiceMMode1_Tx Mixer", "PRI_TDM_TX_3_MMode2", "PRI_TDM_TX_3"}, + {"VoiceMMode2_Tx Mixer", "PRI_TDM_TX_3_MMode2", "PRI_TDM_TX_3"}, {"VOICEMMODE2_UL", NULL, "VoiceMMode2_Tx Mixer"}, {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"}, @@ -23658,7 +23593,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoLTE Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, {"VoLTE Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"VoLTE Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"VoLTE Stub Tx Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"VOLTE_STUB_UL", NULL, "VoLTE Stub Tx Mixer"}, {"Voice2 Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, -- GitLab From 53cd13a1ab325e0f4efb766d6e51a6c36dfef157 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Fri, 29 Jun 2018 15:14:37 +0800 Subject: [PATCH 0983/1645] ASoC: hide bind/unbind in sysfs Exposure of driver bind/unbind to userspace via sysfs may lead to unexpected behavior. Hide bind and unbind by driver attribute. Change-Id: I20d6ee653bcc16af15d6368664aaf240c6645cd0 Signed-off-by: Xiaojun Sang --- asoc/codecs/audio-ext-clk-up.c | 1 + asoc/codecs/audio-ext-clk.c | 3 ++- asoc/codecs/bolero/bolero-cdc.c | 1 + asoc/codecs/bolero/bolero-clk-rsc.c | 1 + asoc/codecs/bolero/rx-macro.c | 1 + asoc/codecs/bolero/tx-macro.c | 1 + asoc/codecs/bolero/va-macro.c | 1 + asoc/codecs/bolero/wsa-macro.c | 1 + asoc/codecs/msm-cdc-pinctrl.c | 3 ++- asoc/codecs/msm_hdmi_codec_rx.c | 3 ++- asoc/codecs/msm_stub.c | 3 ++- asoc/codecs/wcd-dsp-mgr.c | 3 ++- asoc/codecs/wcd9335.c | 1 + asoc/codecs/wcd934x/wcd934x.c | 1 + asoc/codecs/wcd937x/wcd937x.c | 1 + asoc/codecs/wcd938x/wcd938x.c | 1 + asoc/codecs/wcd9xxx-irq.c | 3 ++- asoc/kona.c | 1 + asoc/msm-compress-q6-v2.c | 1 + asoc/msm-cpe-lsm.c | 3 ++- asoc/msm-dai-fe.c | 3 ++- asoc/msm-dai-q6-hdmi-v2.c | 3 ++- asoc/msm-dai-q6-v2.c | 10 ++++++++++ asoc/msm-dai-stub-v2.c | 4 +++- asoc/msm-lsm-client.c | 1 + asoc/msm-pcm-afe-v2.c | 1 + asoc/msm-pcm-dtmf-v2.c | 3 ++- asoc/msm-pcm-host-voice-v2.c | 3 ++- asoc/msm-pcm-hostless.c | 3 ++- asoc/msm-pcm-loopback-v2.c | 1 + asoc/msm-pcm-q6-noirq.c | 3 ++- asoc/msm-pcm-q6-v2.c | 1 + asoc/msm-pcm-routing-v2.c | 1 + asoc/msm-pcm-voice-v2.c | 1 + asoc/msm-pcm-voip-v2.c | 3 ++- asoc/msm-transcode-loopback-q6-v2.c | 1 + asoc/qcs405.c | 1 + asoc/sa8155.c | 3 ++- asoc/sm6150.c | 1 + asoc/sm8150.c | 3 ++- dsp/adsp-loader.c | 3 ++- dsp/avtimer.c | 3 ++- dsp/msm_audio_ion.c | 1 + dsp/msm_mdf.c | 3 ++- dsp/q6core.c | 1 + dsp/voice_mhi.c | 1 + ipc/apr.c | 1 + ipc/wcd-dsp-glink.c | 3 ++- soc/pinctrl-lpi.c | 1 + soc/pinctrl-wcd.c | 3 ++- soc/swr-mstr-ctrl.c | 1 + soc/swr-wcd-ctrl.c | 3 ++- soc/wcd-spi-ac.c | 1 + 53 files changed, 86 insertions(+), 23 deletions(-) diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index e6e68adf8895..fcdf5dc76076 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -565,6 +565,7 @@ static struct platform_driver audio_ref_clk_driver = { .name = "audio-ref-clk", .owner = THIS_MODULE, .of_match_table = audio_ref_clk_match, + .suppress_bind_attrs = true, }, .probe = audio_ref_clk_probe, .remove = audio_ref_clk_remove, diff --git a/asoc/codecs/audio-ext-clk.c b/asoc/codecs/audio-ext-clk.c index 07556ee59086..adcd7a6ee6b0 100644 --- a/asoc/codecs/audio-ext-clk.c +++ b/asoc/codecs/audio-ext-clk.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, 2019 The Linux Foundation. All rights reserved. */ #include @@ -321,6 +321,7 @@ static struct platform_driver audio_ref_clk_driver = { .name = "audio-ref-clk", .owner = THIS_MODULE, .of_match_table = audio_ref_clk_match, + .suppress_bind_attrs = true, }, .probe = audio_ref_clk_probe, .remove = audio_ref_clk_remove, diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 45e993684db1..7afef8beb7fb 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -1026,6 +1026,7 @@ static struct platform_driver bolero_drv = { .name = "bolero-codec", .owner = THIS_MODULE, .of_match_table = bolero_dt_match, + .suppress_bind_attrs = true, }, .probe = bolero_probe, .remove = bolero_remove, diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c index 6742562bf951..82f387926e4f 100644 --- a/asoc/codecs/bolero/bolero-clk-rsc.c +++ b/asoc/codecs/bolero/bolero-clk-rsc.c @@ -603,6 +603,7 @@ static struct platform_driver bolero_clk_rsc_mgr = { .name = "bolero-clk-rsc-mngr", .owner = THIS_MODULE, .of_match_table = bolero_clk_rsc_dt_match, + .suppress_bind_attrs = true, }, .probe = bolero_clk_rsc_probe, .remove = bolero_clk_rsc_remove, diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index e43fa6231f9e..7def494800f3 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -3712,6 +3712,7 @@ static struct platform_driver rx_macro_driver = { .owner = THIS_MODULE, .pm = &bolero_dev_pm_ops, .of_match_table = rx_macro_dt_match, + .suppress_bind_attrs = true, }, .probe = rx_macro_probe, .remove = rx_macro_remove, diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 49b7da573525..177bab4bdb10 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -2077,6 +2077,7 @@ static struct platform_driver tx_macro_driver = { .owner = THIS_MODULE, .pm = &bolero_dev_pm_ops, .of_match_table = tx_macro_dt_match, + .suppress_bind_attrs = true, }, .probe = tx_macro_probe, .remove = tx_macro_remove, diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index cdfe6c78538f..3bba403a96ba 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -1756,6 +1756,7 @@ static struct platform_driver va_macro_driver = { .owner = THIS_MODULE, .pm = &bolero_dev_pm_ops, .of_match_table = va_macro_dt_match, + .suppress_bind_attrs = true, }, .probe = va_macro_probe, .remove = va_macro_remove, diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index d1ba34620e57..cc5b8f2e8aa1 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -3008,6 +3008,7 @@ static struct platform_driver wsa_macro_driver = { .owner = THIS_MODULE, .pm = &bolero_dev_pm_ops, .of_match_table = wsa_macro_dt_match, + .suppress_bind_attrs = true, }, .probe = wsa_macro_probe, .remove = wsa_macro_remove, diff --git a/asoc/codecs/msm-cdc-pinctrl.c b/asoc/codecs/msm-cdc-pinctrl.c index b626e5721dfb..8ed0c8ebf50d 100644 --- a/asoc/codecs/msm-cdc-pinctrl.c +++ b/asoc/codecs/msm-cdc-pinctrl.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ #include @@ -233,6 +233,7 @@ static struct platform_driver msm_cdc_pinctrl_driver = { .name = "msm-cdc-pinctrl", .owner = THIS_MODULE, .of_match_table = msm_cdc_pinctrl_match, + .suppress_bind_attrs = true, }, .probe = msm_cdc_pinctrl_probe, .remove = msm_cdc_pinctrl_remove, diff --git a/asoc/codecs/msm_hdmi_codec_rx.c b/asoc/codecs/msm_hdmi_codec_rx.c index 0c142f1fd6b2..534959811422 100644 --- a/asoc/codecs/msm_hdmi_codec_rx.c +++ b/asoc/codecs/msm_hdmi_codec_rx.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -698,6 +698,7 @@ static struct platform_driver msm_ext_disp_audio_codec_rx_driver = { .name = "msm-ext-disp-audio-codec-rx", .owner = THIS_MODULE, .of_match_table = msm_ext_disp_audio_codec_rx_dt_match, + .suppress_bind_attrs = true, }, .probe = msm_ext_disp_audio_codec_rx_plat_probe, .remove = msm_ext_disp_audio_codec_rx_plat_remove, diff --git a/asoc/codecs/msm_stub.c b/asoc/codecs/msm_stub.c index a754c49ee383..cf91f2a6de1b 100644 --- a/asoc/codecs/msm_stub.c +++ b/asoc/codecs/msm_stub.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2011-2014, 2017-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2017-2019 The Linux Foundation. All rights reserved. */ #include #include @@ -63,6 +63,7 @@ static struct platform_driver msm_stub_driver = { .name = "msm-stub-codec", .owner = THIS_MODULE, .of_match_table = msm_stub_codec_dt_match, + .suppress_bind_attrs = true, }, .probe = msm_stub_dev_probe, .remove = msm_stub_dev_remove, diff --git a/asoc/codecs/wcd-dsp-mgr.c b/asoc/codecs/wcd-dsp-mgr.c index e0070e659e64..a6acc2da62ad 100644 --- a/asoc/codecs/wcd-dsp-mgr.c +++ b/asoc/codecs/wcd-dsp-mgr.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -1306,6 +1306,7 @@ static struct platform_driver wdsp_mgr_driver = { .name = "wcd-dsp-mgr", .owner = THIS_MODULE, .of_match_table = of_match_ptr(wdsp_mgr_dt_match), + .suppress_bind_attrs = true, }, .probe = wdsp_mgr_probe, .remove = wdsp_mgr_remove, diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c index e501a350c457..009e614d0eac 100644 --- a/asoc/codecs/wcd9335.c +++ b/asoc/codecs/wcd9335.c @@ -14796,6 +14796,7 @@ static struct platform_driver tasha_codec_driver = { #ifdef CONFIG_PM .pm = &tasha_pm_ops, #endif + .suppress_bind_attrs = true, }, }; diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index f1c353699eb4..ea928f022d3d 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -11471,6 +11471,7 @@ static struct platform_driver tavil_codec_driver = { #ifdef CONFIG_PM .pm = &tavil_pm_ops, #endif + .suppress_bind_attrs = true, }, }; diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index bde3a7e84faa..ce2b492dc8a3 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -2923,6 +2923,7 @@ static struct platform_driver wcd937x_codec_driver = { #ifdef CONFIG_PM_SLEEP .pm = &wcd937x_dev_pm_ops, #endif + .suppress_bind_attrs = true, }, }; diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 6241cf201a20..4ded2d2de04d 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -2973,6 +2973,7 @@ static struct platform_driver wcd938x_codec_driver = { #ifdef CONFIG_PM_SLEEP .pm = &wcd938x_dev_pm_ops, #endif + .suppress_bind_attrs = true, }, }; diff --git a/asoc/codecs/wcd9xxx-irq.c b/asoc/codecs/wcd9xxx-irq.c index b748bb2e9171..c1efba4c69f6 100644 --- a/asoc/codecs/wcd9xxx-irq.c +++ b/asoc/codecs/wcd9xxx-irq.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -878,6 +878,7 @@ static struct platform_driver wcd9xxx_irq_driver = { .name = "wcd9xxx_intc", .owner = THIS_MODULE, .of_match_table = of_match_ptr(of_match), + .suppress_bind_attrs = true, }, }; diff --git a/asoc/kona.c b/asoc/kona.c index 50a25b17ffe3..84d79fe59289 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -6712,6 +6712,7 @@ static struct platform_driver kona_asoc_machine_driver = { .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = kona_asoc_machine_of_match, + .suppress_bind_attrs = true, }, .probe = msm_asoc_machine_probe, .remove = msm_asoc_machine_remove, diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index f358e457814f..d9e0927bc034 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -5387,6 +5387,7 @@ static struct platform_driver msm_compr_driver = { .name = "msm-compress-dsp", .owner = THIS_MODULE, .of_match_table = msm_compr_dt_match, + .suppress_bind_attrs = true, }, .probe = msm_compr_dev_probe, .remove = msm_compr_remove, diff --git a/asoc/msm-cpe-lsm.c b/asoc/msm-cpe-lsm.c index b1a6fe30c19f..7765554cb3d9 100644 --- a/asoc/msm-cpe-lsm.c +++ b/asoc/msm-cpe-lsm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. */ #include @@ -3331,6 +3331,7 @@ static struct platform_driver msm_cpe_lsm_driver = { .name = "msm-cpe-lsm", .owner = THIS_MODULE, .of_match_table = of_match_ptr(msm_cpe_lsm_dt_match), + .suppress_bind_attrs = true, }, .probe = msm_cpe_lsm_probe, .remove = msm_cpe_lsm_remove, diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index 6256e8a646e7..f53b3a6a5b0f 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ @@ -2765,6 +2765,7 @@ static struct platform_driver msm_fe_dai_driver = { .name = "msm-dai-fe", .owner = THIS_MODULE, .of_match_table = msm_dai_fe_dt_match, + .suppress_bind_attrs = true, }, }; diff --git a/asoc/msm-dai-q6-hdmi-v2.c b/asoc/msm-dai-q6-hdmi-v2.c index 32add91326f1..fb50eba63625 100644 --- a/asoc/msm-dai-q6-hdmi-v2.c +++ b/asoc/msm-dai-q6-hdmi-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include @@ -586,6 +586,7 @@ static struct platform_driver msm_dai_q6_hdmi_driver = { .name = "msm-dai-q6-hdmi", .owner = THIS_MODULE, .of_match_table = msm_dai_q6_hdmi_dt_match, + .suppress_bind_attrs = true, }, }; diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 1a82d65a2650..009df8c5e66d 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -4300,6 +4300,7 @@ static struct platform_driver msm_auxpcm_dev_driver = { .name = "msm-auxpcm-dev", .owner = THIS_MODULE, .of_match_table = msm_auxpcm_dev_dt_match, + .suppress_bind_attrs = true, }, }; @@ -6317,6 +6318,7 @@ static struct platform_driver msm_dai_q6_dev = { .name = "msm-dai-q6-dev", .owner = THIS_MODULE, .of_match_table = msm_dai_q6_dev_dt_match, + .suppress_bind_attrs = true, }, }; @@ -6354,6 +6356,7 @@ static struct platform_driver msm_dai_q6 = { .name = "msm-dai-q6", .owner = THIS_MODULE, .of_match_table = msm_dai_q6_dt_match, + .suppress_bind_attrs = true, }, }; @@ -6389,6 +6392,7 @@ static struct platform_driver msm_dai_mi2s_q6 = { .name = "msm-dai-mi2s", .owner = THIS_MODULE, .of_match_table = msm_dai_mi2s_dt_match, + .suppress_bind_attrs = true, }, }; @@ -6406,6 +6410,7 @@ static struct platform_driver msm_dai_q6_mi2s_driver = { .name = "msm-dai-q6-mi2s", .owner = THIS_MODULE, .of_match_table = msm_dai_q6_mi2s_dev_dt_match, + .suppress_bind_attrs = true, }, }; @@ -6475,6 +6480,7 @@ static struct platform_driver msm_dai_q6_spdif_driver = { .name = "msm-dai-q6-spdif", .owner = THIS_MODULE, .of_match_table = msm_dai_q6_spdif_dt_match, + .suppress_bind_attrs = true, }, }; @@ -6699,6 +6705,7 @@ static struct platform_driver msm_dai_tdm_q6 = { .name = "msm-dai-tdm", .owner = THIS_MODULE, .of_match_table = msm_dai_tdm_dt_match, + .suppress_bind_attrs = true, }, }; @@ -10331,6 +10338,7 @@ static struct platform_driver msm_dai_q6_tdm_driver = { .name = "msm-dai-q6-tdm", .owner = THIS_MODULE, .of_match_table = msm_dai_q6_tdm_dev_dt_match, + .suppress_bind_attrs = true, }, }; @@ -11234,6 +11242,7 @@ static struct platform_driver msm_dai_q6_cdc_dma_driver = { .name = "msm-dai-cdc-dma-dev", .owner = THIS_MODULE, .of_match_table = msm_dai_q6_cdc_dma_dev_dt_match, + .suppress_bind_attrs = true, }, }; @@ -11271,6 +11280,7 @@ static struct platform_driver msm_dai_cdc_dma_q6 = { .name = "msm-dai-cdc-dma", .owner = THIS_MODULE, .of_match_table = msm_dai_cdc_dma_dt_match, + .suppress_bind_attrs = true, }, }; diff --git a/asoc/msm-dai-stub-v2.c b/asoc/msm-dai-stub-v2.c index 7e7d4e4a1334..55701566be15 100644 --- a/asoc/msm-dai-stub-v2.c +++ b/asoc/msm-dai-stub-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2017, 2019 The Linux Foundation. All rights reserved. */ #include #include @@ -302,6 +302,7 @@ static struct platform_driver msm_dai_stub_dev = { .name = "msm-dai-stub-dev", .owner = THIS_MODULE, .of_match_table = msm_dai_stub_dev_dt_match, + .suppress_bind_attrs = true, }, }; @@ -343,6 +344,7 @@ static struct platform_driver msm_dai_stub_driver = { .name = "msm-dai-stub", .owner = THIS_MODULE, .of_match_table = msm_dai_stub_dt_match, + .suppress_bind_attrs = true, }, }; diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 3a5707e0de8d..a87f7f882077 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -3033,6 +3033,7 @@ static struct platform_driver msm_lsm_driver = { .name = "msm-lsm-client", .owner = THIS_MODULE, .of_match_table = of_match_ptr(msm_lsm_client_dt_match), + .suppress_bind_attrs = true, }, .probe = msm_lsm_probe, .remove = msm_lsm_remove, diff --git a/asoc/msm-pcm-afe-v2.c b/asoc/msm-pcm-afe-v2.c index 3db81db1133f..8494fcb201b9 100644 --- a/asoc/msm-pcm-afe-v2.c +++ b/asoc/msm-pcm-afe-v2.c @@ -896,6 +896,7 @@ static struct platform_driver msm_afe_driver = { .name = "msm-pcm-afe", .owner = THIS_MODULE, .of_match_table = msm_pcm_afe_dt_match, + .suppress_bind_attrs = true, }, .probe = msm_afe_probe, .remove = msm_afe_remove, diff --git a/asoc/msm-pcm-dtmf-v2.c b/asoc/msm-pcm-dtmf-v2.c index 58ae5fa6920f..7f79471bf086 100644 --- a/asoc/msm-pcm-dtmf-v2.c +++ b/asoc/msm-pcm-dtmf-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2013-2014, 2017-2018 The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2017-2019 The Linux Foundation. All rights reserved. */ #include @@ -567,6 +567,7 @@ static struct platform_driver msm_pcm_driver = { .name = "msm-pcm-dtmf", .owner = THIS_MODULE, .of_match_table = msm_pcm_dtmf_dt_match, + .suppress_bind_attrs = true, }, .probe = msm_pcm_probe, .remove = msm_pcm_remove, diff --git a/asoc/msm-pcm-host-voice-v2.c b/asoc/msm-pcm-host-voice-v2.c index 49e9591120b5..41c3982dd343 100644 --- a/asoc/msm-pcm-host-voice-v2.c +++ b/asoc/msm-pcm-host-voice-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. */ #include @@ -1477,6 +1477,7 @@ static struct platform_driver msm_pcm_driver = { .name = "msm-voice-host-pcm", .owner = THIS_MODULE, .of_match_table = msm_voice_host_pcm_dt_match, + .suppress_bind_attrs = true, }, .probe = msm_pcm_probe, .remove = msm_pcm_remove, diff --git a/asoc/msm-pcm-hostless.c b/asoc/msm-pcm-hostless.c index 3109b72d9538..63c5db85fe42 100644 --- a/asoc/msm-pcm-hostless.c +++ b/asoc/msm-pcm-hostless.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2011-2014, 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2017-2019 The Linux Foundation. All rights reserved. */ #include @@ -56,6 +56,7 @@ static struct platform_driver msm_pcm_hostless_driver = { .name = "msm-pcm-hostless", .owner = THIS_MODULE, .of_match_table = msm_pcm_hostless_dt_match, + .suppress_bind_attrs = true, }, .probe = msm_pcm_hostless_probe, .remove = msm_pcm_hostless_remove, diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index 4834e81b6906..07cf20b6ed82 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -1504,6 +1504,7 @@ static struct platform_driver msm_pcm_driver = { .name = "msm-pcm-loopback", .owner = THIS_MODULE, .of_match_table = msm_pcm_loopback_dt_match, + .suppress_bind_attrs = true, }, .probe = msm_pcm_probe, .remove = msm_pcm_remove, diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index 34526145de9e..b33eba3fc76a 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ #include @@ -1340,6 +1340,7 @@ static struct platform_driver msm_pcm_driver_noirq = { .name = "msm-pcm-dsp-noirq", .owner = THIS_MODULE, .of_match_table = msm_pcm_noirq_dt_match, + .suppress_bind_attrs = true, }, .probe = msm_pcm_probe, .remove = msm_pcm_remove, diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 322bf661e171..fc9b33209ee9 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -2695,6 +2695,7 @@ static struct platform_driver msm_pcm_driver = { .name = "msm-pcm-dsp", .owner = THIS_MODULE, .of_match_table = msm_pcm_dt_match, + .suppress_bind_attrs = true, }, .probe = msm_pcm_probe, .remove = msm_pcm_remove, diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index d5bad0fd6661..a69391f54f71 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -24817,6 +24817,7 @@ static struct platform_driver msm_routing_pcm_driver = { .name = "msm-pcm-routing", .owner = THIS_MODULE, .of_match_table = msm_pcm_routing_dt_match, + .suppress_bind_attrs = true, }, .probe = msm_routing_pcm_probe, .remove = msm_routing_pcm_remove, diff --git a/asoc/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c index ea476c153dc5..f8acc30ab86e 100644 --- a/asoc/msm-pcm-voice-v2.c +++ b/asoc/msm-pcm-voice-v2.c @@ -812,6 +812,7 @@ static struct platform_driver msm_pcm_driver = { .name = "msm-pcm-voice", .owner = THIS_MODULE, .of_match_table = msm_voice_dt_match, + .suppress_bind_attrs = true, }, .probe = msm_pcm_probe, .remove = msm_pcm_remove, diff --git a/asoc/msm-pcm-voip-v2.c b/asoc/msm-pcm-voip-v2.c index 3bfa4d6cb0e3..e2ad13b4cc6c 100644 --- a/asoc/msm-pcm-voip-v2.c +++ b/asoc/msm-pcm-voip-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include @@ -1670,6 +1670,7 @@ static struct platform_driver msm_pcm_driver = { .name = "msm-voip-dsp", .owner = THIS_MODULE, .of_match_table = msm_voip_dt_match, + .suppress_bind_attrs = true, }, .probe = msm_pcm_probe, .remove = msm_pcm_remove, diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index dc4103799c5b..5d572f11585c 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -1695,6 +1695,7 @@ static struct platform_driver msm_transcode_loopback_driver = { .name = "msm-transcode-loopback", .owner = THIS_MODULE, .of_match_table = msm_transcode_loopback_dt_match, + .suppress_bind_attrs = true, }, .probe = msm_transcode_dev_probe, .remove = msm_transcode_remove, diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 04557483aa1f..aae7302ec009 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -8843,6 +8843,7 @@ static struct platform_driver qcs405_asoc_machine_driver = { .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = qcs405_asoc_machine_of_match, + .suppress_bind_attrs = true, }, .probe = msm_asoc_machine_probe, .remove = msm_asoc_machine_remove, diff --git a/asoc/sa8155.c b/asoc/sa8155.c index 6dba20609c58..e01b2315d514 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. */ /* * Copyright 2011, The Android Open Source Project @@ -7220,6 +7220,7 @@ static struct platform_driver sa8155_asoc_machine_driver = { .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = sa8155_asoc_machine_of_match, + .suppress_bind_attrs = true, }, .probe = msm_asoc_machine_probe, .remove = msm_asoc_machine_remove, diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 6a6597ab875c..49902c875b36 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -9297,6 +9297,7 @@ static struct platform_driver sm6150_asoc_machine_driver = { .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = sm6150_asoc_machine_of_match, + .suppress_bind_attrs = true, }, .probe = msm_asoc_machine_probe, .remove = msm_asoc_machine_remove, diff --git a/asoc/sm8150.c b/asoc/sm8150.c index aad476575948..3b95ce553233 100644 --- a/asoc/sm8150.c +++ b/asoc/sm8150.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ #include @@ -7245,6 +7245,7 @@ static struct platform_driver sm8150_asoc_machine_driver = { .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = sm8150_asoc_machine_of_match, + .suppress_bind_attrs = true, }, .probe = msm_asoc_machine_probe, .remove = msm_asoc_machine_remove, diff --git a/dsp/adsp-loader.c b/dsp/adsp-loader.c index 387850bd3670..881e3604e7de 100644 --- a/dsp/adsp-loader.c +++ b/dsp/adsp-loader.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2014, 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014, 2017-2019, The Linux Foundation. All rights reserved. */ #include @@ -333,6 +333,7 @@ static struct platform_driver adsp_loader_driver = { .name = "adsp-loader", .owner = THIS_MODULE, .of_match_table = adsp_loader_dt_match, + .suppress_bind_attrs = true, }, .probe = adsp_loader_probe, .remove = adsp_loader_remove, diff --git a/dsp/avtimer.c b/dsp/avtimer.c index 29bfd24adc2b..554f030409f1 100644 --- a/dsp/avtimer.c +++ b/dsp/avtimer.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2015, 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2015, 2017-2019 The Linux Foundation. All rights reserved. */ #include @@ -536,6 +536,7 @@ static struct platform_driver dev_avtimer_driver = { .driver = { .name = "dev_avtimer", .of_match_table = avtimer_machine_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index 089376cb28e7..a2f5127be118 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -806,6 +806,7 @@ static struct platform_driver msm_audio_ion_driver = { .name = "msm-audio-ion", .owner = THIS_MODULE, .of_match_table = msm_audio_ion_dt_match, + .suppress_bind_attrs = true, }, .probe = msm_audio_ion_probe, .remove = msm_audio_ion_remove, diff --git a/dsp/msm_mdf.c b/dsp/msm_mdf.c index e3d87e32f381..19232d5ae49b 100644 --- a/dsp/msm_mdf.c +++ b/dsp/msm_mdf.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include #include @@ -694,6 +694,7 @@ static struct platform_driver msm_mdf_driver = { .name = "msm-mdf", .owner = THIS_MODULE, .of_match_table = msm_mdf_match_table, + .suppress_bind_attrs = true, }, }; diff --git a/dsp/q6core.c b/dsp/q6core.c index 3f15f10ecfdc..43f6e25d4c0c 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -1907,6 +1907,7 @@ static struct platform_driver q6core_driver = { .name = "q6core_audio", .owner = THIS_MODULE, .of_match_table = q6core_of_match, + .suppress_bind_attrs = true, } }; diff --git a/dsp/voice_mhi.c b/dsp/voice_mhi.c index 69942b24807c..34f5eb924d67 100644 --- a/dsp/voice_mhi.c +++ b/dsp/voice_mhi.c @@ -591,6 +591,7 @@ static struct platform_driver voice_mhi_platform_driver = { .name = "voice_mhi_audio", .owner = THIS_MODULE, .of_match_table = voice_mhi_of_match, + .suppress_bind_attrs = true, } }; diff --git a/ipc/apr.c b/ipc/apr.c index f1dbc36d9d55..0ea269454035 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -1235,6 +1235,7 @@ static struct platform_driver apr_driver = { .name = "audio_apr", .owner = THIS_MODULE, .of_match_table = apr_machine_of_match, + .suppress_bind_attrs = true, } }; diff --git a/ipc/wcd-dsp-glink.c b/ipc/wcd-dsp-glink.c index 8cfcba93f9f4..a6eb044ff262 100644 --- a/ipc/wcd-dsp-glink.c +++ b/ipc/wcd-dsp-glink.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ #include @@ -755,6 +755,7 @@ static struct platform_driver wdsp_glink_driver = { .name = WDSP_GLINK_DRIVER_NAME, .owner = THIS_MODULE, .of_match_table = wdsp_glink_of_match, + .suppress_bind_attrs = true, }, }; diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index 4eee08623d6c..c2342617af66 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -801,6 +801,7 @@ static struct platform_driver lpi_pinctrl_driver = { .name = "qcom-lpi-pinctrl", .pm = &lpi_pinctrl_dev_pm_ops, .of_match_table = lpi_pinctrl_of_match, + .suppress_bind_attrs = true, }, .probe = lpi_pinctrl_probe, .remove = lpi_pinctrl_remove, diff --git a/soc/pinctrl-wcd.c b/soc/pinctrl-wcd.c index d02fdc0839c2..437563f0a8a0 100644 --- a/soc/pinctrl-wcd.c +++ b/soc/pinctrl-wcd.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, 2019, The Linux Foundation. All rights reserved. */ #include @@ -416,6 +416,7 @@ static struct platform_driver wcd_pinctrl_driver = { .driver = { .name = "qcom-wcd-pinctrl", .of_match_table = wcd_pinctrl_of_match, + .suppress_bind_attrs = true, }, .probe = wcd_pinctrl_probe, .remove = wcd_pinctrl_remove, diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index c9cccf6d480c..8a9c065df759 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2921,6 +2921,7 @@ static struct platform_driver swr_mstr_driver = { .owner = THIS_MODULE, .pm = &swrm_dev_pm_ops, .of_match_table = swrm_dt_match, + .suppress_bind_attrs = true, }, }; diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c index 13e5fa81c53a..f38085f24b0d 100644 --- a/soc/swr-wcd-ctrl.c +++ b/soc/swr-wcd-ctrl.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #include @@ -1929,6 +1929,7 @@ static struct platform_driver swr_mstr_driver = { .owner = THIS_MODULE, .pm = &swrm_dev_pm_ops, .of_match_table = swrm_dt_match, + .suppress_bind_attrs = true, }, }; diff --git a/soc/wcd-spi-ac.c b/soc/wcd-spi-ac.c index ee7a7a9ba57d..bfba40142eff 100644 --- a/soc/wcd-spi-ac.c +++ b/soc/wcd-spi-ac.c @@ -987,6 +987,7 @@ static struct platform_driver wcd_spi_ac_driver = { .driver = { .name = "qcom,wcd-spi-ac", .of_match_table = wcd_spi_ac_of_match, + .suppress_bind_attrs = true, }, .probe = wcd_spi_ac_probe, .remove = wcd_spi_ac_remove, -- GitLab From ffbdc9fe0f29df5d58c5da850871556df3d1ad4e Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Fri, 17 May 2019 15:02:39 -0700 Subject: [PATCH 0984/1645] asoc: Kona: add support to send island mode config for VA usecase Currently audio driver doesn't send island mode config to ADSP to set the LPI mode, which causes ADSP to remain in Non-LPI mode. Fix it by adding support in Kona machine driver to send island mode config for VA usecase. Change-Id: I2294950055cb74a1a9d3ee630e74f63eb6435e7b Signed-off-by: Xiaoyu Ye --- asoc/kona.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/asoc/kona.c b/asoc/kona.c index 50a25b17ffe3..18b6bd6b08ee 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -2205,6 +2205,15 @@ static int msm_get_port_id(int be_id) case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; break; + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: + afe_port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0; + break; + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: + afe_port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_1; + break; + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2: + afe_port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_2; + break; default: pr_err("%s: Invalid BE id: %d\n", __func__, be_id); afe_port_id = -EINVAL; @@ -3388,6 +3397,30 @@ static int msm_ext_disp_get_idx_from_beid(int32_t be_id) return idx; } +static int kona_send_island_va_config(int32_t be_id) +{ + int rc = 0; + int port_id = 0xFFFF; + + port_id = msm_get_port_id(be_id); + if (port_id < 0) { + pr_err("%s: Invalid island interface, be_id: %d\n", + __func__, be_id); + rc = -EINVAL; + } else { + /* + * send island mode config + * This should be the first configuration + */ + rc = afe_send_port_island_mode(port_id); + if (rc) + pr_err("%s: afe send island mode failed %d\n", + __func__, rc); + } + + return rc; +} + static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { @@ -3812,6 +3845,26 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream, return ret; } +static int msm_snd_cdc_dma_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + switch (dai_link->id) { + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2: + ret = kona_send_island_va_config(dai_link->id); + if (ret) + pr_err("%s: send island va cfg failed, err: %d\n", + __func__, ret); + break; + } + + return ret; +} + static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -4084,6 +4137,7 @@ static struct snd_soc_ops msm_fe_qos_ops = { }; static struct snd_soc_ops msm_cdc_dma_be_ops = { + .startup = msm_snd_cdc_dma_startup, .hw_params = msm_snd_cdc_dma_hw_params, }; -- GitLab From ddca68611f938aa45ca2bab888ce2b0d040b6435 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 21 May 2019 09:31:44 +0800 Subject: [PATCH 0985/1645] asoc: add ignore_suspend for all BEs, BE_OUT and BE_IN During suspend on new kernel, FE/BE path would tear down and pinctrl for related component would be deactived. On kona, FM is connected to TERT MI2S and during suepend, pinctrl for TERT MI2S would be sleep state and FM has no sound. Add ignore_suspend for all BEs, BE_OUT and BE_IN to avoid tearing FE/BE path during device suspend. Change-Id: I8868f35d6c418987ffe287d64a3f5ae3d1abf1c1 Signed-off-by: Meng Wang --- asoc/msm-dai-q6-v2.c | 2 ++ asoc/msm-pcm-routing-v2.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 1a82d65a2650..4b85be2eb738 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -727,6 +727,7 @@ static int msm_dai_q6_dai_add_route(struct snd_soc_dai *dai) dev_dbg(dai->dev, "%s: src %s sink %s\n", __func__, intercon.source, intercon.sink); snd_soc_dapm_add_routes(dapm, &intercon, 1); + snd_soc_dapm_ignore_suspend(dapm, intercon.sink); } if (dai->driver->capture.stream_name && dai->driver->capture.aif_name) { @@ -737,6 +738,7 @@ static int msm_dai_q6_dai_add_route(struct snd_soc_dai *dai) dev_dbg(dai->dev, "%s: src %s sink %s\n", __func__, intercon.source, intercon.sink); snd_soc_dapm_add_routes(dapm, &intercon, 1); + snd_soc_dapm_ignore_suspend(dapm, intercon.source); } return 0; } diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index f3795be8524c..474a8ddd95aa 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -24774,6 +24774,8 @@ static int msm_routing_probe(struct snd_soc_component *component) { snd_soc_dapm_new_controls(&component->dapm, msm_qdsp6_widgets, ARRAY_SIZE(msm_qdsp6_widgets)); + snd_soc_dapm_ignore_suspend(&component->dapm, "BE_OUT"); + snd_soc_dapm_ignore_suspend(&component->dapm, "BE_IN"); snd_soc_dapm_add_routes(&component->dapm, intercon, ARRAY_SIZE(intercon)); -- GitLab From a070ce5bc81a74ecf137ce04fd6b1c2c054bb436 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Mon, 19 Nov 2018 15:45:27 +0530 Subject: [PATCH 0986/1645] asoc: Add machine driver changes for sa6155 Add machine driver interface for 615x to support dynamic loading of kernel module. Change-Id: I5691c2730d31390d6f6b4ce30794182421dc1861 Signed-off-by: Rahul Sharma --- asoc/Kbuild | 2 ++ asoc/machine_615x_init.c | 36 ++++++++++++++++++++++++++++++++++++ asoc/machine_615x_init.h | 23 +++++++++++++++++++++++ asoc/sm6150.c | 13 ++++++++++++- 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 asoc/machine_615x_init.c create mode 100644 asoc/machine_615x_init.h diff --git a/asoc/Kbuild b/asoc/Kbuild index 5ff12c61c14a..afbda8ba4e43 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -86,6 +86,8 @@ endif # for SM6150 sound card driver ifdef CONFIG_SND_SOC_SM6150 MACHINE_OBJS += sm6150.o + MACHINE_OBJS += sa8155.o + MACHINE_OBJS += machine_615x_init.o endif # for qcs405 sound card driver diff --git a/asoc/machine_615x_init.c b/asoc/machine_615x_init.c new file mode 100644 index 000000000000..cf5013826bc8 --- /dev/null +++ b/asoc/machine_615x_init.c @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2018, The Linux Foundation. All rights reserved. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 and +* only version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +*/ + +#include +#include +#include "machine_615x_init.h" + +static int __init audio_machine_615x_init(void) +{ + sm6150_init(); + sa8155_init(); + return 0; +} + +static void audio_machine_615x_exit(void) +{ + sm6150_exit(); + sa8155_exit(); +} + +module_init(audio_machine_615x_init); +module_exit(audio_machine_615x_exit); + +MODULE_DESCRIPTION("Audio Machine 615X Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/machine_615x_init.h b/asoc/machine_615x_init.h new file mode 100644 index 000000000000..36565e46bb10 --- /dev/null +++ b/asoc/machine_615x_init.h @@ -0,0 +1,23 @@ +/* +* Copyright (c) 2018, The Linux Foundation. All rights reserved. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 and +* only version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +*/ + +#ifndef __MACHINE_615X_INIT_H__ +#define __MACHINE_615X_INIT_H__ +int sm6150_init(void); +int sa8155_init(void); + +void sm6150_exit(void); +void sa8155_exit(void); +#endif + diff --git a/asoc/sm6150.c b/asoc/sm6150.c index 49902c875b36..e41fe49caeaf 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -9302,7 +9302,18 @@ static struct platform_driver sm6150_asoc_machine_driver = { .probe = msm_asoc_machine_probe, .remove = msm_asoc_machine_remove, }; -module_platform_driver(sm6150_asoc_machine_driver); + +int __init sm6150_init(void) +{ + pr_debug("%s\n", __func__); + return platform_driver_register(&sm6150_asoc_machine_driver); +} + +void sm6150_exit(void) +{ + pr_debug("%s\n", __func__); + platform_driver_unregister(&sm6150_asoc_machine_driver); +} MODULE_DESCRIPTION("ALSA SoC SM6150 Machine driver"); MODULE_LICENSE("GPL v2"); -- GitLab From fce04f75637f2323fdf754e8899fc2eca0844250 Mon Sep 17 00:00:00 2001 From: Weiyin Jiang Date: Thu, 23 May 2019 02:07:35 +0800 Subject: [PATCH 0987/1645] asoc: fix offload PBE failure in sending calibration to lpass PBE values are misinterpreted when transferring from userspace to kernel via mixer ctl interface. Config values have to be copied one by one rather than copying through continuous memory. CRs-Fixed: 2458428 Change-Id: I375498f0f511d21bd14873cc9394305acbc25e50 Signed-off-by: Weiyin Jiang --- asoc/msm-audio-effects-q6-v2.c | 68 +++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/asoc/msm-audio-effects-q6-v2.c b/asoc/msm-audio-effects-q6-v2.c index bdb00592f12c..3605a752c33c 100644 --- a/asoc/msm-audio-effects-q6-v2.c +++ b/asoc/msm-audio-effects-q6-v2.c @@ -890,6 +890,9 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, struct param_hdr_v3 param_hdr; u8 *param_data = NULL; u32 packed_data_size = 0; + int32_t *p_coeffs = NULL; + uint32_t lpf_len = 0, hpf_len = 0, bpf_len = 0; + uint32_t bsf_len = 0, tsf_len = 0, total_coeffs_len = 0; pr_debug("%s\n", __func__); if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { @@ -949,8 +952,71 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, rc = -EINVAL; goto invalid_config; } + + pbe->config.real_bass_mix = + GET_NEXT(values, param_max_offset, rc); + pbe->config.bass_color_control = + GET_NEXT(values, param_max_offset, rc); + pbe->config.main_chain_delay = + GET_NEXT(values, param_max_offset, rc); + pbe->config.xover_filter_order = + GET_NEXT(values, param_max_offset, rc); + pbe->config.bandpass_filter_order = + GET_NEXT(values, param_max_offset, rc); + pbe->config.drc_delay = + GET_NEXT(values, param_max_offset, rc); + pbe->config.rms_tav = + GET_NEXT(values, param_max_offset, rc); + pbe->config.exp_threshold = + GET_NEXT(values, param_max_offset, rc); + pbe->config.exp_slope = + GET_NEXT(values, param_max_offset, rc); + pbe->config.comp_threshold = + GET_NEXT(values, param_max_offset, rc); + pbe->config.comp_slope = + GET_NEXT(values, param_max_offset, rc); + pbe->config.makeup_gain = + GET_NEXT(values, param_max_offset, rc); + pbe->config.comp_attack = + GET_NEXT(values, param_max_offset, rc); + pbe->config.comp_release = + GET_NEXT(values, param_max_offset, rc); + pbe->config.exp_attack = + GET_NEXT(values, param_max_offset, rc); + pbe->config.exp_release = + GET_NEXT(values, param_max_offset, rc); + pbe->config.limiter_bass_threshold = + GET_NEXT(values, param_max_offset, rc); + pbe->config.limiter_high_threshold = + GET_NEXT(values, param_max_offset, rc); + pbe->config.limiter_bass_makeup_gain = + GET_NEXT(values, param_max_offset, rc); + pbe->config.limiter_high_makeup_gain = + GET_NEXT(values, param_max_offset, rc); + pbe->config.limiter_bass_gc = + GET_NEXT(values, param_max_offset, rc); + pbe->config.limiter_high_gc = + GET_NEXT(values, param_max_offset, rc); + pbe->config.limiter_delay = + GET_NEXT(values, param_max_offset, rc); + pbe->config.reserved = + GET_NEXT(values, param_max_offset, rc); + + p_coeffs = &pbe->config.p1LowPassCoeffs[0]; + lpf_len = (pbe->config.xover_filter_order == 3) ? 10 : 5; + hpf_len = (pbe->config.xover_filter_order == 3) ? 10 : 5; + bpf_len = pbe->config.bandpass_filter_order * 5; + bsf_len = 5; + tsf_len = 5; + total_coeffs_len = lpf_len + hpf_len + bpf_len + bsf_len + tsf_len; + + for (i = 0; i < total_coeffs_len; i++) { + *p_coeffs++ = GET_NEXT(values, param_max_offset, rc); + } + if (command_config_state != CONFIG_SET) break; + max_params_length = params_length + COMMAND_IID_PAYLOAD_SZ + length; CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, @@ -959,7 +1025,7 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, break; param_hdr.param_id = AUDPROC_PARAM_ID_PBE_PARAM_CONFIG; param_hdr.param_size = length; - param_data = (u8 *) values; + param_data = (u8 *) &pbe->config; break; default: pr_err_ratelimited("%s: Invalid command to set config\n", -- GitLab From 979b7c981469d46c268bd49629b966f7761a5668 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Fri, 17 May 2019 15:31:21 +0530 Subject: [PATCH 0988/1645] soc: swr-mstr: skip port disable when master is down skip port disable when master is already down to avoid queuing commands to master which is already down due to ssr/pdr. Change-Id: I7fadc479784feb0fd8afa229599eb217bb579ea2 Signed-off-by: Ramprasad Katkam --- soc/swr-mstr-ctrl.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index e6559bdf0dd6..a12ed9f2c030 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -984,6 +984,26 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) mutex_lock(&swrm->mlock); + /* + * During disable if master is already down, which implies an ssr/pdr + * scenario, just mark ports as disabled and exit + */ + if (swrm->state == SWR_MSTR_SSR && !enable) { + if (!test_bit(DISABLE_PENDING, &swrm->port_req_pending)) { + dev_dbg(swrm->dev, "%s:No pending disconn port req\n", + __func__); + goto exit; + } + clear_bit(DISABLE_PENDING, &swrm->port_req_pending); + swrm_cleanup_disabled_port_reqs(master); + if (!swrm_is_port_en(master)) { + dev_dbg(&master->dev, "%s: pm_runtime auto suspend triggered\n", + __func__); + pm_runtime_mark_last_busy(swrm->dev); + pm_runtime_put_autosuspend(swrm->dev); + } + goto exit; + } bank = get_inactive_bank_num(swrm); if (enable) { -- GitLab From 12dcf64d6fdfaf595ef01fb30837192091030160 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 29 Jan 2019 11:21:15 -0800 Subject: [PATCH 0989/1645] ASoC: msm: add lpi support for tdm/mi2s For TDM/MI2S/AUXPCM, add lpi gpio support for kona. Change-Id: Ie23caaaa0243c84dfc8a6ee0e3e0e002bf0c18d8 Signed-off-by: Karthikeyan Mani --- asoc/kona.c | 973 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 963 insertions(+), 10 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index d754bc57d461..be944d3e2ffa 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -91,6 +91,9 @@ enum { TDM_PRI = 0, TDM_SEC, TDM_TERT, + TDM_QUAT, + TDM_QUIN, + TDM_SEN, TDM_INTERFACE_MAX, }; @@ -98,6 +101,9 @@ enum { PRIM_AUX_PCM = 0, SEC_AUX_PCM, TERT_AUX_PCM, + QUAT_AUX_PCM, + QUIN_AUX_PCM, + SEN_AUX_PCM, AUX_PCM_MAX, }; @@ -105,6 +111,9 @@ enum { PRIM_MI2S = 0, SEC_MI2S, TERT_MI2S, + QUAT_MI2S, + QUIN_MI2S, + SEN_MI2S, MI2S_MAX, }; @@ -152,6 +161,8 @@ struct msm_asoc_mach_data { struct device_node *dmic01_gpio_p; /* used by pinctrl API */ struct device_node *dmic23_gpio_p; /* used by pinctrl API */ struct device_node *dmic45_gpio_p; /* used by pinctrl API */ + struct device_node *mi2s_gpio_p[MI2S_MAX]; /* used by pinctrl API */ + atomic_t mi2s_gpio_ref_count[MI2S_MAX]; /* used by pinctrl API */ struct device_node *us_euro_gpio_p; /* used by pinctrl API */ struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */ struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ @@ -244,6 +255,30 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = { Q6AFE_LPASS_CLK_ROOT_DEFAULT, 0, }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, }; struct mi2s_conf { @@ -292,6 +327,36 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUIN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* SEN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, }; static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { @@ -325,6 +390,36 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUIN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* SEN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, }; /* Default configuration of AUX PCM channels */ @@ -332,12 +427,18 @@ static struct dev_config aux_pcm_rx_cfg[] = { [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; static struct dev_config aux_pcm_tx_cfg[] = { [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; /* Default configuration of MI2S channels */ @@ -345,12 +446,18 @@ static struct dev_config mi2s_rx_cfg[] = { [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SEN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, }; static struct dev_config mi2s_tx_cfg[] = { [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; /* Default configuration of Codec DMA Interface RX */ @@ -452,25 +559,43 @@ static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sen_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sen_aux_pcm_tx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_rx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_tx_sample_rate, mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_chs, cdc_dma_rx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_chs, cdc_dma_rx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_chs, cdc_dma_rx_ch_text); @@ -1224,6 +1349,15 @@ static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, } else if (strnstr(kcontrol->id.name, "TERT", sizeof(kcontrol->id.name))) { port->mode = TDM_TERT; + } else if (strnstr(kcontrol->id.name, "QUAT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_QUAT; + } else if (strnstr(kcontrol->id.name, "QUIN", + sizeof(kcontrol->id.name))) { + port->mode = TDM_QUIN; + } else if (strnstr(kcontrol->id.name, "SEN", + sizeof(kcontrol->id.name))) { + port->mode = TDM_SEN; } else { pr_err("%s: unsupported mode in: %s\n", __func__, kcontrol->id.name); @@ -1637,6 +1771,15 @@ static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) } else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", sizeof("TERT_AUX_PCM"))) { idx = TERT_AUX_PCM; + } else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", + sizeof("QUAT_AUX_PCM"))) { + idx = QUAT_AUX_PCM; + } else if (strnstr(kcontrol->id.name, "QUIN_AUX_PCM", + sizeof("QUIN_AUX_PCM"))) { + idx = QUIN_AUX_PCM; + } else if (strnstr(kcontrol->id.name, "SEN_AUX_PCM", + sizeof("SEN_AUX_PCM"))) { + idx = SEN_AUX_PCM; } else { pr_err("%s: unsupported port: %s\n", __func__, kcontrol->id.name); @@ -1883,6 +2026,15 @@ static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) } else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", sizeof("TERT_MI2S_RX"))) { idx = TERT_MI2S; + } else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", + sizeof("QUAT_MI2S_RX"))) { + idx = QUAT_MI2S; + } else if (strnstr(kcontrol->id.name, "QUIN_MI2S_RX", + sizeof("QUIN_MI2S_RX"))) { + idx = QUIN_MI2S; + } else if (strnstr(kcontrol->id.name, "SEN_MI2S_RX", + sizeof("SEN_MI2S_RX"))) { + idx = SEN_MI2S; } else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", sizeof("PRIM_MI2S_TX"))) { idx = PRIM_MI2S; @@ -1892,6 +2044,15 @@ static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) } else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", sizeof("TERT_MI2S_TX"))) { idx = TERT_MI2S; + } else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", + sizeof("QUAT_MI2S_TX"))) { + idx = QUAT_MI2S; + } else if (strnstr(kcontrol->id.name, "QUIN_MI2S_TX", + sizeof("QUIN_MI2S_TX"))) { + idx = QUIN_MI2S; + } else if (strnstr(kcontrol->id.name, "SEN_MI2S_TX", + sizeof("SEN_MI2S_TX"))) { + idx = SEN_MI2S; } else { pr_err("%s: unsupported channel: %s\n", __func__, kcontrol->id.name); @@ -2205,6 +2366,24 @@ static int msm_get_port_id(int be_id) case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUINARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUINARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUINARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_SENARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_SENARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_SENARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_SENARY_MI2S_TX; + break; case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: afe_port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0; break; @@ -3218,6 +3397,15 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, tdm_rx_sample_rate_get, tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEN_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, tdm_tx_sample_rate_get, tdm_tx_sample_rate_put), @@ -3227,6 +3415,15 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, tdm_tx_sample_rate_get, tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEN_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, aux_pcm_rx_sample_rate_get, aux_pcm_rx_sample_rate_put), @@ -3236,6 +3433,15 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, aux_pcm_rx_sample_rate_get, aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_RX SampleRate", quin_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("SEN_AUX_PCM_RX SampleRate", sen_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, aux_pcm_tx_sample_rate_get, aux_pcm_tx_sample_rate_put), @@ -3245,6 +3451,15 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, aux_pcm_tx_sample_rate_get, aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_TX SampleRate", quin_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("SEN_AUX_PCM_TX SampleRate", sen_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, mi2s_rx_sample_rate_get, mi2s_rx_sample_rate_put), @@ -3254,6 +3469,15 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, mi2s_rx_sample_rate_get, mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_MI2S_RX SampleRate", quin_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("SEN_MI2S_RX SampleRate", sen_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, mi2s_tx_sample_rate_get, mi2s_tx_sample_rate_put), @@ -3263,6 +3487,15 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, mi2s_tx_sample_rate_get, mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_MI2S_TX SampleRate", quin_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("SEN_MI2S_TX SampleRate", sen_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, usb_audio_rx_format_get, usb_audio_rx_format_put), SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, @@ -3276,6 +3509,15 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, tdm_rx_format_get, tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEN_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, tdm_tx_format_get, tdm_tx_format_put), @@ -3285,30 +3527,63 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, tdm_tx_format_get, tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEN_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format, msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format, msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("SEN_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format, msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format, msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("SEN_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format, msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), SOC_ENUM_EXT("TERT_MI2S_RX Format", mi2s_rx_format, msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("QUIN_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("SEN_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), SOC_ENUM_EXT("SEC_MI2S_TX Format", mi2s_tx_format, msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), SOC_ENUM_EXT("TERT_MI2S_TX Format", mi2s_tx_format, msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("QUIN_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("SEN_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, usb_audio_rx_ch_get, usb_audio_rx_ch_put), SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, @@ -3324,6 +3599,15 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, tdm_rx_ch_get, tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEN_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, tdm_tx_ch_get, tdm_tx_ch_put), @@ -3333,18 +3617,39 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, tdm_tx_ch_get, tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEN_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUIN_MI2S_RX Channels", quin_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("SEN_MI2S_RX Channels", sen_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUIN_MI2S_TX Channels", quin_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("SEN_MI2S_TX Channels", sen_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, ext_disp_rx_ch_get, ext_disp_rx_ch_put), SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, @@ -3517,6 +3822,54 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; break; + case MSM_BACKEND_DAI_QUAT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUIN_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUIN_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEN_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEN][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEN][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEN_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEN][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_SEN][TDM_0].sample_rate; + break; + case MSM_BACKEND_DAI_AUXPCM_RX: param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format); @@ -3571,6 +3924,60 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, aux_pcm_tx_cfg[TERT_AUX_PCM].channels; break; + case MSM_BACKEND_DAI_QUAT_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[QUAT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[QUAT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUIN_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[QUIN_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[QUIN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUIN_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUIN_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[QUIN_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[QUIN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUIN_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEN_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[SEN_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[SEN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[SEN_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEN_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[SEN_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[SEN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[SEN_AUX_PCM].channels; + break; + case MSM_BACKEND_DAI_PRI_MI2S_RX: param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, mi2s_rx_cfg[PRIM_MI2S].bit_format); @@ -3619,6 +4026,54 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, mi2s_tx_cfg[TERT_MI2S].channels; break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUAT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUAT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUINARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUIN_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[QUIN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUIN_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUIN_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[QUIN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUIN_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SENARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[SEN_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[SEN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[SEN_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SENARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[SEN_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[SEN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[SEN_MI2S].channels; + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0: case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1: case MSM_BACKEND_DAI_RX_CDC_DMA_RX_0: @@ -3765,6 +4220,15 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream, case AFE_PORT_ID_TERTIARY_TDM_RX: slots = tdm_rx_cfg[TDM_TERT][TDM_0].channels; break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + break; + case AFE_PORT_ID_QUINARY_TDM_RX: + slots = tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + break; + case AFE_PORT_ID_SENARY_TDM_RX: + slots = tdm_rx_cfg[TDM_SEN][TDM_0].channels; + break; case AFE_PORT_ID_PRIMARY_TDM_TX: slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels; break; @@ -3774,6 +4238,15 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream, case AFE_PORT_ID_TERTIARY_TDM_TX: slots = tdm_tx_cfg[TDM_TERT][TDM_0].channels; break; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + break; + case AFE_PORT_ID_QUINARY_TDM_TX: + slots = tdm_tx_cfg[TDM_QUIN][TDM_0].channels; + break; + case AFE_PORT_ID_SENARY_TDM_TX: + slots = tdm_tx_cfg[TDM_SEN][TDM_0].channels; + break; default: pr_err("%s: dai id 0x%x not supported\n", @@ -3845,18 +4318,179 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream, return ret; } -static int msm_snd_cdc_dma_startup(struct snd_pcm_substream *substream) +static int msm_get_tdm_mode(u32 port_id) { - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai_link *dai_link = rtd->dai_link; + int tdm_mode; - switch (dai_link->id) { - case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: - case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: - case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2: - ret = kona_send_island_va_config(dai_link->id); - if (ret) + switch (port_id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_TX: + tdm_mode = TDM_PRI; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_TX: + tdm_mode = TDM_SEC; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_TX: + tdm_mode = TDM_TERT; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + tdm_mode = TDM_QUAT; + break; + case AFE_PORT_ID_QUINARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_TX: + tdm_mode = TDM_QUIN; + break; + case AFE_PORT_ID_SENARY_TDM_RX: + case AFE_PORT_ID_SENARY_TDM_TX: + tdm_mode = TDM_SEN; + break; + default: + pr_err("%s: Invalid port id: %d\n", __func__, port_id); + tdm_mode = -EINVAL; + } + return tdm_mode; +} + +static int kona_tdm_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + int tdm_mode = msm_get_tdm_mode(cpu_dai->id); + + if (tdm_mode >= TDM_INTERFACE_MAX || tdm_mode < 0) { + ret = -EINVAL; + pr_err("%s: Invalid TDM interface %d\n", + __func__, ret); + return ret; + } + + if (pdata->mi2s_gpio_p[tdm_mode]) { + if (atomic_read(&(pdata->mi2s_gpio_ref_count[tdm_mode])) + == 0) { + ret = msm_cdc_pinctrl_select_active_state( + pdata->mi2s_gpio_p[tdm_mode]); + if (ret) { + pr_err("%s: TDM GPIO pinctrl set active failed with %d\n", + __func__, ret); + goto done; + } + } + atomic_inc(&(pdata->mi2s_gpio_ref_count[tdm_mode])); + } + +done: + return ret; +} + +static void kona_tdm_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + int tdm_mode = msm_get_tdm_mode(cpu_dai->id); + + if (tdm_mode >= TDM_INTERFACE_MAX || tdm_mode < 0) { + ret = -EINVAL; + pr_err("%s: Invalid TDM interface %d\n", + __func__, ret); + return; + } + + if (pdata->mi2s_gpio_p[tdm_mode]) { + atomic_dec(&(pdata->mi2s_gpio_ref_count[tdm_mode])); + if (atomic_read(&(pdata->mi2s_gpio_ref_count[tdm_mode])) + == 0) { + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->mi2s_gpio_p[tdm_mode]); + if (ret) + pr_err("%s: TDM GPIO pinctrl set sleep failed with %d\n", + __func__, ret); + } + } +} + +static int kona_aux_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + u32 aux_mode = cpu_dai->id - 1; + + if (aux_mode >= AUX_PCM_MAX) { + ret = -EINVAL; + pr_err("%s: Invalid AUX interface %d\n", + __func__, ret); + return ret; + } + + if (pdata->mi2s_gpio_p[aux_mode]) { + if (atomic_read(&(pdata->mi2s_gpio_ref_count[aux_mode])) + == 0) { + ret = msm_cdc_pinctrl_select_active_state( + pdata->mi2s_gpio_p[aux_mode]); + if (ret) { + pr_err("%s: AUX GPIO pinctrl set active failed with %d\n", + __func__, ret); + goto done; + } + } + atomic_inc(&(pdata->mi2s_gpio_ref_count[aux_mode])); + } + +done: + return ret; +} + +static void kona_aux_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + u32 aux_mode = cpu_dai->id - 1; + + if (aux_mode >= AUX_PCM_MAX) { + pr_err("%s: Invalid AUX interface %d\n", + __func__, ret); + return; + } + + if (pdata->mi2s_gpio_p[aux_mode]) { + atomic_dec(&(pdata->mi2s_gpio_ref_count[aux_mode])); + if (atomic_read(&(pdata->mi2s_gpio_ref_count[aux_mode])) + == 0) { + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->mi2s_gpio_p[aux_mode]); + if (ret) + pr_err("%s: AUX GPIO pinctrl set sleep failed with %d\n", + __func__, ret); + } + } +} + +static int msm_snd_cdc_dma_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + switch (dai_link->id) { + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2: + ret = kona_send_island_va_config(dai_link->id); + if (ret) pr_err("%s: send island va cfg failed, err: %d\n", __func__, ret); break; @@ -3979,6 +4613,8 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int index = cpu_dai->id; unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); dev_dbg(rtd->card->dev, "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", @@ -4018,6 +4654,19 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) __func__, index, ret); goto clk_off; } + if (pdata->mi2s_gpio_p[index]) { + if (atomic_read(&(pdata->mi2s_gpio_ref_count[index])) + == 0) { + ret = msm_cdc_pinctrl_select_active_state( + pdata->mi2s_gpio_p[index]); + if (ret) { + pr_err("%s: MI2S GPIO pinctrl set active failed with %d\n", + __func__, ret); + goto clk_off; + } + } + atomic_inc(&(pdata->mi2s_gpio_ref_count[index])); + } } clk_off: if (ret < 0) @@ -4035,6 +4684,8 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; int index = rtd->cpu_dai->id; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); @@ -4045,6 +4696,18 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) mutex_lock(&mi2s_intf_conf[index].lock); if (--mi2s_intf_conf[index].ref_cnt == 0) { + if (pdata->mi2s_gpio_p[index]) { + atomic_dec(&(pdata->mi2s_gpio_ref_count[index])); + if (atomic_read(&(pdata->mi2s_gpio_ref_count[index])) + == 0) { + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->mi2s_gpio_p[index]); + if (ret) + pr_err("%s: MI2S GPIO pinctrl set sleep failed with %d\n", + __func__, ret); + } + } + ret = msm_mi2s_set_sclk(substream, false); if (ret < 0) pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", @@ -4123,8 +4786,15 @@ static int msm_wcn_hw_params(struct snd_pcm_substream *substream, return ret; } +static struct snd_soc_ops kona_aux_be_ops = { + .startup = kona_aux_snd_startup, + .shutdown = kona_aux_snd_shutdown +}; + static struct snd_soc_ops kona_tdm_be_ops = { .hw_params = kona_tdm_snd_hw_params, + .startup = kona_tdm_snd_startup, + .shutdown = kona_tdm_snd_shutdown }; static struct snd_soc_ops msm_mi2s_be_ops = { @@ -5231,6 +5901,93 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .ops = &kona_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUAT_TDM_RX_0, + .stream_name = "Quaternary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36912", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_0, + .stream_name = "Quaternary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36913", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_TDM_RX_0, + .stream_name = "Quinary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36928", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_TDM_TX_0, + .stream_name = "Quinary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36929", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEN_TDM_RX_0, + .stream_name = "Senary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36944", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEN_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEN_TDM_TX_0, + .stream_name = "Senary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36945", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEN_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_tdm_be_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { @@ -5444,6 +6201,93 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX, + .stream_name = "Quaternary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_RX, + .stream_name = "Quinary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_TX, + .stream_name = "Quinary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SENARY_MI2S_RX, + .stream_name = "Senary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SENARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SENARY_MI2S_TX, + .stream_name = "Senary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SENARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { @@ -5459,6 +6303,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_playback = 1, .id = MSM_BACKEND_DAI_AUXPCM_RX, .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_aux_be_ops, .ignore_pmdown_time = 1, .ignore_suspend = 1, }, @@ -5473,6 +6318,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_AUXPCM_TX, .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_aux_be_ops, .ignore_suspend = 1, }, /* Secondary AUX PCM Backend DAI Links */ @@ -5487,6 +6333,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_playback = 1, .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_aux_be_ops, .ignore_pmdown_time = 1, .ignore_suspend = 1, }, @@ -5501,6 +6348,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_aux_be_ops, .ignore_suspend = 1, }, /* Tertiary AUX PCM Backend DAI Links */ @@ -5515,6 +6363,7 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_playback = 1, .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_aux_be_ops, .ignore_suspend = 1, }, { @@ -5528,6 +6377,94 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { .dpcm_capture = 1, .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_aux_be_ops, + .ignore_suspend = 1, + }, + /* Quaternary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUAT_AUXPCM_RX, + .stream_name = "Quat AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_aux_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_AUXPCM_TX, + .stream_name = "Quat AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_aux_be_ops, + .ignore_suspend = 1, + }, + /* Quinary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUIN_AUXPCM_RX, + .stream_name = "Quin AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_aux_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_AUXPCM_TX, + .stream_name = "Quin AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_aux_be_ops, + .ignore_suspend = 1, + }, + /* Senary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_SEN_AUXPCM_RX, + .stream_name = "Sen AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.6", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEN_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_aux_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEN_AUXPCM_TX, + .stream_name = "Sen AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.6", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEN_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &kona_aux_be_ops, .ignore_suspend = 1, }, }; @@ -6605,6 +7542,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) struct msm_asoc_mach_data *pdata = NULL; const char *mbhc_audio_jack_type = NULL; int ret = 0; + uint index = 0; if (!pdev->dev.of_node) { dev_err(&pdev->dev, "%s: No platform supplied from device tree\n", __func__); @@ -6738,6 +7676,21 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) "qcom,cdc-dmic45-gpios", 0); + pdata->mi2s_gpio_p[PRIM_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,pri-mi2s-gpios", 0); + pdata->mi2s_gpio_p[SEC_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,sec-mi2s-gpios", 0); + pdata->mi2s_gpio_p[TERT_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,tert-mi2s-gpios", 0); + pdata->mi2s_gpio_p[QUAT_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,quat-mi2s-gpios", 0); + pdata->mi2s_gpio_p[QUIN_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,quin-mi2s-gpios", 0); + pdata->mi2s_gpio_p[SEN_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,sen-mi2s-gpios", 0); + for (index = PRIM_MI2S; index < MI2S_MAX; index++) + atomic_set(&(pdata->mi2s_gpio_ref_count[index]), 0); + ret = msm_audio_ssr_register(&pdev->dev); if (ret) pr_err("%s: Registration with SND event FWK failed ret = %d\n", -- GitLab From f68219039a57eff75037a571a15a1310531e44f0 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 21 May 2019 17:31:24 -0700 Subject: [PATCH 0990/1645] soc: swr: Release resource lock when not needed Resource lock should not be held while doing bank switch as bank switch requires interrupt handling which needs access to the resource lock. Change-Id: Ic17178c7e6f16a7db91da6577ed2ce70c9c9f084 Signed-off-by: Karthikeyan Mani --- soc/swr-mstr-ctrl.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index e6559bdf0dd6..45781c76f4ae 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2289,11 +2289,14 @@ static int swrm_runtime_resume(struct device *dev) __func__, swrm->state); mutex_lock(&swrm->reslock); - if (swrm->lpass_core_hw_vote) + if (swrm->lpass_core_hw_vote) { ret = clk_prepare_enable(swrm->lpass_core_hw_vote); - if (ret < 0) + if (ret < 0) { dev_err(dev, "%s:lpass core hw enable failed\n", __func__); + ret = 0; + } + } if ((swrm->state == SWR_MSTR_DOWN) || (swrm->state == SWR_MSTR_SSR && swrm->dev_up)) { @@ -2306,7 +2309,6 @@ static int swrm_runtime_resume(struct device *dev) if (swrm_clk_request(swrm, true)) goto exit; if (!swrm->clk_stop_mode0_supp || swrm->state == SWR_MSTR_SSR) { - enable_bank_switch(swrm, 0, SWR_ROW_50, SWR_MIN_COL); list_for_each_entry(swr_dev, &mstr->devices, dev_list) { ret = swr_device_up(swr_dev); if (ret == -ENODEV) { @@ -2327,7 +2329,11 @@ static int swrm_runtime_resume(struct device *dev) swrm_master_init(swrm); swrm_cmd_fifo_wr_cmd(swrm, 0x4, 0xF, 0x0, SWRS_SCP_INT_STATUS_MASK_1); - + if (swrm->state == SWR_MSTR_SSR) { + mutex_unlock(&swrm->reslock); + enable_bank_switch(swrm, 0, SWR_ROW_50, SWR_MIN_COL); + mutex_lock(&swrm->reslock); + } } else { /*wake up from clock stop*/ swr_master_write(swrm, SWRM_MCP_BUS_CTRL_ADDR, 0x2); @@ -2358,11 +2364,14 @@ static int swrm_runtime_suspend(struct device *dev) mutex_lock(&swrm->force_down_lock); current_state = swrm->state; mutex_unlock(&swrm->force_down_lock); - if (swrm->lpass_core_hw_vote) + if (swrm->lpass_core_hw_vote) { ret = clk_prepare_enable(swrm->lpass_core_hw_vote); - if (ret < 0) + if (ret < 0) { dev_err(dev, "%s:lpass core hw enable failed\n", __func__); + ret = 0; + } + } if ((current_state == SWR_MSTR_UP) || (current_state == SWR_MSTR_SSR)) { -- GitLab From ff2733c0eb630657c05640f12c0dc6a457dc50b9 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 17 May 2019 01:49:27 +0530 Subject: [PATCH 0991/1645] ASoC: Kona: Avoid static route between cpu and codec dai Currently ASoC core creates a static route b/w playback/capture widgets of cpu and codec dai if they are part of the same dai-link. However this will cause codec path to get powered up first followed by the backend dai start during device switch use-case where the front-end is not closed, leading to audio playback failure if either bit-width or sample rate is different. Set the dynamic bit of backend dai dailink to update the backend parameters before codec path setup. Change-Id: Ic80755a5672849f527d5d696d31174a62997aca2 Signed-off-by: Sudheer Papothi --- asoc/kona.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/kona.c b/asoc/kona.c index 50a25b17ffe3..ce0c56d1f8c3 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -5068,6 +5068,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .platform_name = "msm-pcm-routing", .codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-rx", + .dynamic_be = 1, .no_pcm = 1, .dpcm_playback = 1, .id = MSM_BACKEND_DAI_USB_RX, @@ -5534,6 +5535,7 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { .platform_name = "msm-pcm-routing", .codec_name = "bolero_codec", .codec_dai_name = "rx_macro_rx1", + .dynamic_be = 1, .no_pcm = 1, .dpcm_playback = 1, .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, @@ -5549,6 +5551,7 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { .platform_name = "msm-pcm-routing", .codec_name = "bolero_codec", .codec_dai_name = "rx_macro_rx2", + .dynamic_be = 1, .no_pcm = 1, .dpcm_playback = 1, .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, @@ -5564,6 +5567,7 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { .platform_name = "msm-pcm-routing", .codec_name = "bolero_codec", .codec_dai_name = "rx_macro_rx3", + .dynamic_be = 1, .no_pcm = 1, .dpcm_playback = 1, .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, @@ -5579,6 +5583,7 @@ static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { .platform_name = "msm-pcm-routing", .codec_name = "bolero_codec", .codec_dai_name = "rx_macro_rx4", + .dynamic_be = 1, .no_pcm = 1, .dpcm_playback = 1, .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, -- GitLab From 69b55c855b29674e90e62c6e0848cf1778adff49 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 29 May 2019 11:04:29 +0800 Subject: [PATCH 0992/1645] asoc: bolero: do not disable tx macro clk during SSR/PDR Do not disable tx macro clk when it's not enabled during SSR/PDR to avoid clk count mismatch. Change-Id: I69a59cff9cb57ef3dea366c73629c3eddcb19abe Signed-off-by: Meng Wang --- asoc/codecs/bolero/tx-macro.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 288ded36df89..a61bd03c6d9e 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1470,7 +1470,7 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, struct regmap *regmap, int clk_type, bool enable) { - int ret = 0; + int ret = 0, clk_tx_ret = 0; dev_dbg(tx_priv->dev, "%s: clock type %s, enable: %s tx_mclk_users: %d\n", @@ -1482,7 +1482,7 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, msm_cdc_pinctrl_select_active_state( tx_priv->tx_swr_gpio_p); - ret = bolero_clk_rsc_request_clock(tx_priv->dev, + clk_tx_ret = bolero_clk_rsc_request_clock(tx_priv->dev, TX_CORE_CLK, TX_CORE_CLK, true); @@ -1540,7 +1540,8 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, 0x02, 0x00); tx_priv->reset_swr = false; } - ret = bolero_clk_rsc_request_clock(tx_priv->dev, + if (!clk_tx_ret) + ret = bolero_clk_rsc_request_clock(tx_priv->dev, TX_CORE_CLK, TX_CORE_CLK, false); @@ -1552,7 +1553,7 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, tx_priv->swr_clk_users = 0; return 0; } - ret = bolero_clk_rsc_request_clock(tx_priv->dev, + clk_tx_ret = bolero_clk_rsc_request_clock(tx_priv->dev, TX_CORE_CLK, TX_CORE_CLK, true); @@ -1583,7 +1584,8 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, goto done; } } - ret = bolero_clk_rsc_request_clock(tx_priv->dev, + if (!clk_tx_ret) + ret = bolero_clk_rsc_request_clock(tx_priv->dev, TX_CORE_CLK, TX_CORE_CLK, false); @@ -1594,7 +1596,8 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, return 0; done: - bolero_clk_rsc_request_clock(tx_priv->dev, + if (!clk_tx_ret) + bolero_clk_rsc_request_clock(tx_priv->dev, TX_CORE_CLK, TX_CORE_CLK, false); -- GitLab From efbe46a1c5c774fd02bb11f74cd56a0e38102448 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 29 May 2019 11:07:33 +0800 Subject: [PATCH 0993/1645] asoc: wcd938x: reinit registers after SSR Reinit wcd registers after SSR. Change-Id: I5a8f22e4f76ffd8b279d1513eaa2f50973e3408c Signed-off-by: Meng Wang --- asoc/codecs/wcd938x/wcd938x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 4ded2d2de04d..bf285052f7df 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1538,6 +1538,7 @@ static int wcd938x_event_notify(struct notifier_block *block, wcd938x_reset(wcd938x->dev); wcd938x_get_logical_addr(wcd938x->tx_swr_dev); wcd938x_get_logical_addr(wcd938x->rx_swr_dev); + wcd938x_init_reg(component); regcache_mark_dirty(wcd938x->regmap); regcache_sync(wcd938x->regmap); /* Initialize MBHC module */ @@ -2860,6 +2861,7 @@ static int wcd938x_probe(struct platform_device *pdev) return -ENOMEM; dev_set_drvdata(dev, wcd938x); + wcd938x->dev = dev; pdata = wcd938x_populate_dt_data(dev); if (!pdata) { -- GitLab From 0c5f346bf7a7ea35c9132689b2af133d56bf6646 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Wed, 22 May 2019 11:53:08 -0700 Subject: [PATCH 0994/1645] asoc: fix silence data during concurrent capture Remove static definition of size and index variables, which are unique to each capture session. Static defintion of index variable may incorrectly copy data from wrong memory offset. This might inject silence/clutter in data copied to audio HAL. CRs-Fixed: 2457887 Change-Id: I7b2f48d21545655ddaa13566ab4ea87a1cbd7424 Signed-off-by: Vignesh Kulothungan --- asoc/msm-pcm-q6-v2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index fc9b33209ee9..3b20ecc84570 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -950,8 +950,8 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, int xfer; char *bufptr; void *data = NULL; - static uint32_t idx; - static uint32_t size; + uint32_t idx = 0; + uint32_t size = 0; uint32_t offset = 0; struct snd_pcm_runtime *runtime = substream->runtime; struct msm_audio *prtd = substream->runtime->private_data; -- GitLab From 10de3937987f89ee5ed1855dbb790dc16372a957 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 15 Apr 2019 11:46:57 -0700 Subject: [PATCH 0995/1645] asoc: codecs: bolero: do not limit boost levels Boost level max setting can be left to default and not needed to be limited to any value. Change-Id: Iab5073cedd6e69bb4311af9af54ff409d8bfd24c Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/wsa-macro.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index e26b4cbb09d1..f41392df4c1e 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -1946,9 +1946,7 @@ static int wsa_macro_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol, dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); bst_state_max = ucontrol->value.integer.value[0] << 2; - snd_soc_component_update_bits(component, - BOLERO_CDC_WSA_BOOST0_BOOST_CTL, - 0x0c, bst_state_max); + /* bolero does not need to limit the boost levels */ return 0; } @@ -1980,9 +1978,7 @@ static int wsa_macro_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol, dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); bst_state_max = ucontrol->value.integer.value[0] << 2; - snd_soc_component_update_bits(component, - BOLERO_CDC_WSA_BOOST1_BOOST_CTL, - 0x0c, bst_state_max); + /* bolero does not need to limit the boost levels */ return 0; } -- GitLab From 930d9751a1eb4e8e7e44eb847bbd6e560d3c586f Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 30 May 2019 17:14:23 +0800 Subject: [PATCH 0996/1645] asoc: bolero: restore all codec registers after SSR Some bolero codec registers are not correctly restored after SSR and causes DMICs on bolero don't work. Add this change to restore all bolero codec registers after SSR. Change-Id: I3666a77f802f62452a0e0de4859f48a0f9e5cbb1 Signed-off-by: Meng Wang --- asoc/codecs/bolero/bolero-cdc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index fc940c88cf97..d4719412d852 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -623,6 +623,8 @@ static int bolero_ssr_enable(struct device *dev, void *data) mutex_lock(&priv->clk_lock); priv->dev_up = true; mutex_unlock(&priv->clk_lock); + regcache_mark_dirty(priv->regmap); + regcache_sync(priv->regmap); /* call ssr event for supported macros */ for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { if (!priv->macro_params[macro_idx].event_handler) -- GitLab From ba445bfe2d6d339514875f90bfed363512fa1a95 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 16 Apr 2019 05:05:55 +0530 Subject: [PATCH 0997/1645] ASoC: codecs: Add support for LPASS Audio HW vote Add support for LPASS Audio HW vote needed for low power AMIC VA usecase. Change-Id: If6642d418dbf2cc9773fbd0ec0fe35c30afac140 Signed-off-by: Sudheer Papothi --- asoc/codecs/audio-ext-clk-up.c | 32 +++++++++ asoc/codecs/bolero/bolero-cdc.c | 28 ++++++++ asoc/codecs/bolero/internal.h | 1 + asoc/codecs/bolero/va-macro.c | 117 ++++++++++++++++++++++++++++++-- include/dsp/q6afe-v2.h | 1 + 5 files changed, 172 insertions(+), 7 deletions(-) diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index 3f622d6af22b..632f6744b245 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -28,6 +28,7 @@ enum { AUDIO_EXT_CLK_LPASS7, AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE, AUDIO_EXT_CLK_LPASS8, + AUDIO_EXT_CLK_LPASS_AUDIO_HW_VOTE, AUDIO_EXT_CLK_LPASS_MAX, AUDIO_EXT_CLK_EXTERNAL_PLL = AUDIO_EXT_CLK_LPASS_MAX, AUDIO_EXT_CLK_MAX, @@ -52,6 +53,7 @@ struct audio_ext_clk_priv { struct audio_ext_clk audio_clk; const char *clk_name; uint32_t lpass_core_hwvote_client_handle; + uint32_t lpass_audio_hwvote_client_handle; }; static inline struct audio_ext_clk_priv *to_audio_clk(struct clk_hw *hw) @@ -154,6 +156,17 @@ static int lpass_hw_vote_prepare(struct clk_hw *hw) } } + if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_AUDIO_HW_VOTE) { + ret = afe_vote_lpass_core_hw(AFE_LPASS_CORE_HW_DCODEC_BLOCK, + "LPASS_HW_DCODEC", + &clk_priv->lpass_audio_hwvote_client_handle); + if (ret < 0) { + pr_err("%s lpass audio hw vote failed %d\n", + __func__, ret); + return ret; + } + } + return 0; } @@ -171,6 +184,16 @@ static void lpass_hw_vote_unprepare(struct clk_hw *hw) __func__, ret); } } + + if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_AUDIO_HW_VOTE) { + ret = afe_unvote_lpass_core_hw( + AFE_LPASS_CORE_HW_DCODEC_BLOCK, + clk_priv->lpass_audio_hwvote_client_handle); + if (ret < 0) { + pr_err("%s lpass audio hw unvote failed %d\n", + __func__, ret); + } + } } static const struct clk_ops audio_ext_clk_ops = { @@ -332,6 +355,15 @@ static struct audio_ext_clk audio_clk_array[] = { }, }, }, + { + .pnctrl_info = {NULL}, + .fact = { + .hw.init = &(struct clk_init_data){ + .name = "lpass_audio_hw_vote_clk", + .ops = &lpass_hw_vote_ops, + }, + }, + }, { .pnctrl_info = {NULL}, .fact = { diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index fc940c88cf97..cee08dcdbd57 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -909,6 +909,7 @@ static int bolero_probe(struct platform_device *pdev) u32 num_macros = 0; int ret; struct clk *lpass_core_hw_vote = NULL; + struct clk *lpass_audio_hw_vote = NULL; priv = devm_kzalloc(&pdev->dev, sizeof(struct bolero_priv), GFP_KERNEL); @@ -968,6 +969,17 @@ static int bolero_probe(struct platform_device *pdev) } priv->lpass_core_hw_vote = lpass_core_hw_vote; + /* Register LPASS audio hw vote */ + lpass_audio_hw_vote = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote"); + if (IS_ERR(lpass_audio_hw_vote)) { + ret = PTR_ERR(lpass_audio_hw_vote); + dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", + __func__, "lpass_audio_hw_vote", ret); + lpass_audio_hw_vote = NULL; + ret = 0; + } + priv->lpass_audio_hw_vote = lpass_audio_hw_vote; + return 0; } @@ -999,6 +1011,16 @@ int bolero_runtime_resume(struct device *dev) dev_err(dev, "%s:lpass core hw enable failed\n", __func__); + if (priv->lpass_audio_hw_vote == NULL) { + dev_dbg(dev, "%s: Invalid lpass audio hw node\n", __func__); + return 0; + } + + ret = clk_prepare_enable(priv->lpass_audio_hw_vote); + if (ret < 0) + dev_err(dev, "%s:lpass audio hw enable failed\n", + __func__); + pm_runtime_set_autosuspend_delay(priv->dev, BOLERO_AUTO_SUSPEND_DELAY); return 0; } @@ -1013,6 +1035,12 @@ int bolero_runtime_suspend(struct device *dev) else dev_dbg(dev, "%s: Invalid lpass core hw node\n", __func__); + + if (priv->lpass_audio_hw_vote != NULL) + clk_disable_unprepare(priv->lpass_audio_hw_vote); + else + dev_dbg(dev, "%s: Invalid lpass audio hw node\n", + __func__); return 0; } EXPORT_SYMBOL(bolero_runtime_suspend); diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 734afbc06b51..d07c5b1fd690 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -58,6 +58,7 @@ struct bolero_priv { struct work_struct bolero_add_child_devices_work; u32 version; struct clk *lpass_core_hw_vote; + struct clk *lpass_audio_hw_vote; /* Entry for version info */ struct snd_info_entry *entry; diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 3bba403a96ba..ba9c7f12b0d3 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -40,6 +40,8 @@ #define VA_MACRO_TX_PATH_OFFSET 0x80 #define VA_MACRO_TX_DMIC_CLK_DIV_MASK 0x0E #define VA_MACRO_TX_DMIC_CLK_DIV_SHFT 0x01 +#define VA_MACRO_SWR_MIC_MUX_SEL_MASK 0xF +#define VA_MACRO_ADC_MUX_CFG_OFFSET 0x2 #define BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS 40 #define MAX_RETRY_ATTEMPTS 500 @@ -78,6 +80,11 @@ enum { VA_MACRO_CLK_DIV_16, }; +enum { + MSM_DMIC, + SWR_MIC, +}; + struct va_mute_work { struct va_macro_priv *va_priv; u32 decimator; @@ -95,6 +102,7 @@ struct va_macro_priv { struct device *dev; bool dec_active[VA_MACRO_NUM_DECIMATORS]; bool va_without_decimation; + struct clk *lpass_audio_hw_vote; struct mutex mclk_lock; struct snd_soc_component *component; struct hpf_work va_hpf_work[VA_MACRO_NUM_DECIMATORS]; @@ -232,6 +240,41 @@ static int va_macro_event_handler(struct snd_soc_component *component, return 0; } +static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + int ret = 0; + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) + return -EINVAL; + + dev_dbg(va_dev, "%s: event = %d\n", __func__, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (va_priv->lpass_audio_hw_vote) { + ret = clk_prepare_enable(va_priv->lpass_audio_hw_vote); + if (ret) + dev_err(va_dev, + "%s: lpass audio hw enable failed\n", + __func__); + } + break; + case SND_SOC_DAPM_POST_PMD: + if (va_priv->lpass_audio_hw_vote) + clk_disable_unprepare(va_priv->lpass_audio_hw_vote); + break; + default: + dev_err(va_priv->dev, + "%s: invalid DAPM event %d\n", __func__, event); + ret = -EINVAL; + } + return ret; +} + static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -254,6 +297,10 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, true); break; case SND_SOC_DAPM_POST_PMD: + bolero_clk_rsc_request_clock(va_priv->dev, + va_priv->default_clk_id, + TX_CORE_CLK, + false); va_macro_mclk_enable(va_priv, 0, true); break; default: @@ -272,6 +319,7 @@ static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) struct snd_soc_component *component; u16 dec_cfg_reg, hpf_gate_reg; u8 hpf_cut_off_freq; + u16 adc_mux_reg = 0, adc_n = 0, adc_reg = 0; hpf_delayed_work = to_delayed_work(work); hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); @@ -287,6 +335,19 @@ static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) dev_dbg(va_priv->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", __func__, hpf_work->decimator, hpf_cut_off_freq); + adc_mux_reg = BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1 + + VA_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator; + if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) { + adc_reg = BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0 + + VA_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator; + adc_n = snd_soc_component_read32(component, adc_reg) & + VA_MACRO_SWR_MIC_MUX_SEL_MASK; + if (adc_n >= BOLERO_ADC_MAX) + goto va_hpf_set; + /* analog mic clear TX hold */ + bolero_clear_amic_tx_hold(component->dev, adc_n); + } +va_hpf_set: snd_soc_component_update_bits(component, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, hpf_cut_off_freq << 5); @@ -366,10 +427,23 @@ static int va_macro_put_dec_enum(struct snd_kcontrol *kcontrol, __func__, e->reg); return -EINVAL; } - /* DMIC selected */ - if (val != 0) - snd_soc_component_update_bits(component, mic_sel_reg, - 1 << 7, 1 << 7); + if (strnstr(widget->name, "SMIC", strlen(widget->name))) { + if (val != 0) { + if (val < 5) + snd_soc_component_update_bits(component, + mic_sel_reg, + 1 << 7, 0x0 << 7); + else + snd_soc_component_update_bits(component, + mic_sel_reg, + 1 << 7, 0x1 << 7); + } + } else { + /* DMIC selected */ + if (val != 0) + snd_soc_component_update_bits(component, mic_sel_reg, + 1 << 7, 1 << 7); + } return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); } @@ -649,6 +723,12 @@ static int va_macro_enable_tx(struct snd_soc_dapm_widget *w, TX_CORE_CLK, false); break; + case SND_SOC_DAPM_PRE_PMD: + ret = bolero_clk_rsc_request_clock(va_priv->dev, + va_priv->default_clk_id, + TX_CORE_CLK, + true); + break; default: dev_err(va_priv->dev, "%s: invalid DAPM event %d\n", __func__, event); @@ -1036,15 +1116,18 @@ static const struct snd_kcontrol_new va_aif3_cap_mixer[] = { static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT_E("VA_AIF1 CAP", "VA_AIF1 Capture", 0, SND_SOC_NOPM, VA_MACRO_AIF1_CAP, 0, - va_macro_enable_tx, SND_SOC_DAPM_POST_PMU), + va_macro_enable_tx, SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_AIF_OUT_E("VA_AIF2 CAP", "VA_AIF2 Capture", 0, SND_SOC_NOPM, VA_MACRO_AIF2_CAP, 0, - va_macro_enable_tx, SND_SOC_DAPM_POST_PMU), + va_macro_enable_tx, SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_AIF_OUT_E("VA_AIF3 CAP", "VA_AIF3 Capture", 0, SND_SOC_NOPM, VA_MACRO_AIF3_CAP, 0, - va_macro_enable_tx, SND_SOC_DAPM_POST_PMU), + va_macro_enable_tx, SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_MIXER("VA_AIF1_CAP Mixer", SND_SOC_NOPM, VA_MACRO_AIF1_CAP, 0, @@ -1165,6 +1248,10 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0, + va_macro_swr_pwr_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0, va_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -1403,6 +1490,11 @@ static const struct snd_soc_dapm_route va_audio_map[] = { {"VA SMIC MUX7", "SWR_DMIC5", "VA SWR_MIC5"}, {"VA SMIC MUX7", "SWR_DMIC6", "VA SWR_MIC6"}, {"VA SMIC MUX7", "SWR_DMIC7", "VA SWR_MIC7"}, + + {"VA SWR_ADC0", NULL, "VA_SWR_PWR"}, + {"VA SWR_ADC1", NULL, "VA_SWR_PWR"}, + {"VA SWR_ADC2", NULL, "VA_SWR_PWR"}, + {"VA SWR_ADC3", NULL, "VA_SWR_PWR"}, }; static const struct snd_kcontrol_new va_macro_snd_controls[] = { @@ -1621,6 +1713,7 @@ static int va_macro_probe(struct platform_device *pdev) int ret = 0; const char *dmic_sample_rate = "qcom,va-dmic-sample-rate"; u32 default_clk_id = 0; + struct clk *lpass_audio_hw_vote = NULL; va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv), GFP_KERNEL); @@ -1659,6 +1752,16 @@ static int va_macro_probe(struct platform_device *pdev) } va_priv->va_io_base = va_io_base; + lpass_audio_hw_vote = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote"); + if (IS_ERR(lpass_audio_hw_vote)) { + ret = PTR_ERR(lpass_audio_hw_vote); + dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", + __func__, "lpass_audio_hw_vote", ret); + lpass_audio_hw_vote = NULL; + ret = 0; + } + va_priv->lpass_audio_hw_vote = lpass_audio_hw_vote; + if (of_parse_phandle(pdev->dev.of_node, micb_supply_str, 0)) { va_priv->micb_supply = devm_regulator_get(&pdev->dev, micb_supply_str1); diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 323ca1ea6b47..89155015eda7 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -483,6 +483,7 @@ int afe_get_doa_tracking_mon(u16 port_id, #define AFE_LPASS_CORE_HW_BLOCK_ID_NONE 0 #define AFE_LPASS_CORE_HW_BLOCK_ID_AVTIMER 2 #define AFE_LPASS_CORE_HW_MACRO_BLOCK 3 +#define AFE_LPASS_CORE_HW_DCODEC_BLOCK 4 /* Handles audio-video timer (avtimer) and BTSC vote requests from clients. */ -- GitLab From 02bee73b77181f2e4d7a215bfa036d99328b9951 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Thu, 20 Dec 2018 18:48:34 +0530 Subject: [PATCH 0998/1645] asoc: adding machine driver for sa6155 add separate machine driver for sa6155 and necessary interface changes. Change-Id: Ie9e498c3e3ccb99af01458f7604f822a11c54e67 Signed-off-by: Rahul Sharma --- asoc/Kbuild | 2 +- asoc/machine_615x_init.c | 6 +- asoc/machine_615x_init.h | 6 +- asoc/sa6155.c | 7132 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 7139 insertions(+), 7 deletions(-) create mode 100644 asoc/sa6155.c diff --git a/asoc/Kbuild b/asoc/Kbuild index afbda8ba4e43..bf6b58300fbc 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -86,7 +86,7 @@ endif # for SM6150 sound card driver ifdef CONFIG_SND_SOC_SM6150 MACHINE_OBJS += sm6150.o - MACHINE_OBJS += sa8155.o + MACHINE_OBJS += sa6155.o MACHINE_OBJS += machine_615x_init.o endif diff --git a/asoc/machine_615x_init.c b/asoc/machine_615x_init.c index cf5013826bc8..4f5fd1bc72c7 100644 --- a/asoc/machine_615x_init.c +++ b/asoc/machine_615x_init.c @@ -1,5 +1,5 @@ /* -* Copyright (c) 2018, The Linux Foundation. All rights reserved. +* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -19,14 +19,14 @@ static int __init audio_machine_615x_init(void) { sm6150_init(); - sa8155_init(); + sa6155_init(); return 0; } static void audio_machine_615x_exit(void) { sm6150_exit(); - sa8155_exit(); + sa6155_exit(); } module_init(audio_machine_615x_init); diff --git a/asoc/machine_615x_init.h b/asoc/machine_615x_init.h index 36565e46bb10..ac7374d97668 100644 --- a/asoc/machine_615x_init.h +++ b/asoc/machine_615x_init.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2018, The Linux Foundation. All rights reserved. +* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -15,9 +15,9 @@ #ifndef __MACHINE_615X_INIT_H__ #define __MACHINE_615X_INIT_H__ int sm6150_init(void); -int sa8155_init(void); +int sa6155_init(void); void sm6150_exit(void); -void sa8155_exit(void); +void sa6155_exit(void); #endif diff --git a/asoc/sa6155.c b/asoc/sa6155.c new file mode 100644 index 000000000000..68117e56b7c1 --- /dev/null +++ b/asoc/sa6155.c @@ -0,0 +1,7132 @@ +/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +/* + * Copyright 2011, The Android Open Source Project + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Android Open Source Project nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "device_event.h" +#include "msm-pcm-routing-v2.h" + +#define DRV_NAME "sa6155-asoc-snd" + +#define __CHIPSET__ "SA6155 " +#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) + +#define DEV_NAME_STR_LEN 32 + +#define SAMPLING_RATE_8KHZ 8000 +#define SAMPLING_RATE_11P025KHZ 11025 +#define SAMPLING_RATE_16KHZ 16000 +#define SAMPLING_RATE_22P05KHZ 22050 +#define SAMPLING_RATE_32KHZ 32000 +#define SAMPLING_RATE_44P1KHZ 44100 +#define SAMPLING_RATE_48KHZ 48000 +#define SAMPLING_RATE_88P2KHZ 88200 +#define SAMPLING_RATE_96KHZ 96000 +#define SAMPLING_RATE_176P4KHZ 176400 +#define SAMPLING_RATE_192KHZ 192000 +#define SAMPLING_RATE_352P8KHZ 352800 +#define SAMPLING_RATE_384KHZ 384000 + +#define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ + +enum { + PRIM_MI2S = 0, + SEC_MI2S, + TERT_MI2S, + QUAT_MI2S, + QUIN_MI2S, + MI2S_MAX, +}; + +enum { + PRIM_AUX_PCM = 0, + SEC_AUX_PCM, + TERT_AUX_PCM, + QUAT_AUX_PCM, + QUIN_AUX_PCM, + AUX_PCM_MAX, +}; + +struct mi2s_conf { + struct mutex lock; + u32 ref_cnt; + u32 msm_is_mi2s_master; +}; + +static u32 mi2s_ebit_clk[MI2S_MAX] = { + Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT +}; + +struct dev_config { + u32 sample_rate; + u32 bit_format; + u32 channels; +}; + +enum { + DP_RX_IDX = 0, + EXT_DISP_RX_IDX_MAX, +}; + +enum pinctrl_pin_state { + STATE_DISABLE = 0, /* All pins are in sleep state */ + STATE_MI2S_ACTIVE, /* I2S = active, TDM = sleep */ + STATE_TDM_ACTIVE, /* I2S = sleep, TDM = active */ +}; + +struct msm_pinctrl_info { + struct pinctrl *pinctrl; + struct pinctrl_state *mi2s_disable; + struct pinctrl_state *tdm_disable; + struct pinctrl_state *mi2s_active; + struct pinctrl_state *tdm_active; + enum pinctrl_pin_state curr_state; +}; + +struct msm_asoc_mach_data { + struct msm_pinctrl_info pinctrl_info; +}; + +static const char *const pin_states[] = {"sleep", "i2s-active", + "tdm-active"}; + +enum { + TDM_0 = 0, + TDM_1, + TDM_2, + TDM_3, + TDM_4, + TDM_5, + TDM_6, + TDM_7, + TDM_PORT_MAX, +}; + +enum { + TDM_PRI = 0, + TDM_SEC, + TDM_TERT, + TDM_QUAT, + TDM_QUIN, + TDM_INTERFACE_MAX, +}; + +struct tdm_port { + u32 mode; + u32 channel; +}; + +/* TDM default config */ +static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUIN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + } +}; + +/* TDM default config */ +static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 4}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUIN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + } +}; + +/* Default configuration of external display BE */ +static struct dev_config ext_disp_rx_cfg[] = { + [DP_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config usb_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +static struct dev_config usb_tx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 1, +}; + +static struct dev_config proxy_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +/* Default configuration of MI2S channels */ +static struct dev_config mi2s_rx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config mi2s_tx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_rx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_tx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +/* TDM default slot config */ +struct tdm_slot_cfg { + u32 width; + u32 num; +}; + +static struct tdm_slot_cfg tdm_slot[TDM_INTERFACE_MAX] = { + /* PRI TDM */ + {32, 8}, + /* SEC TDM */ + {32, 8}, + /* TERT TDM */ + {32, 8}, + /* QUAT TDM */ + {32, 8}, + /* QUIN TDM */ + {32, 8} +}; + +/***************************************************************************** +* TO BE UPDATED: Codec/Platform specific tdm slot table +*****************************************************************************/ +static struct tdm_slot_cfg tdm_slot_custom[TDM_INTERFACE_MAX] = { + /* PRI TDM */ + {16, 16}, + /* SEC TDM */ + {16, 16}, + /* TERT TDM */ + {16, 16}, + /* QUAT TDM */ + {16, 16}, + /* QUIN TDM */ + {16, 16} +}; + + +/* TDM default slot offset config */ +#define TDM_SLOT_OFFSET_MAX 32 + +static unsigned int tdm_rx_slot_offset + [TDM_INTERFACE_MAX][TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { + {/* PRI TDM */ + {0, 4, 0xFFFF}, + {8, 12, 0xFFFF}, + {16, 20, 0xFFFF}, + {24, 28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* SEC TDM */ + {0, 4, 0xFFFF}, + {8, 12, 0xFFFF}, + {16, 20, 0xFFFF}, + {24, 28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* TERT TDM */ + {0, 4, 8, 12, 16, 20, 0xFFFF}, + {24, 0xFFFF}, + {28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUAT TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUIN TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + } +}; + +static unsigned int tdm_tx_slot_offset + [TDM_INTERFACE_MAX][TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { + {/* PRI TDM */ + {0, 4, 0xFFFF}, + {8, 12, 0xFFFF}, + {16, 20, 0xFFFF}, + {24, 28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* SEC TDM */ + {0, 4, 8, 12, 16, 20, 0xFFFF}, + {24, 0xFFFF}, + {28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* TERT TDM */ + {0, 4, 8, 12, 0xFFFF}, + {16, 20, 0xFFFF}, + {24, 28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUAT TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUIN TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + } +}; + +/***************************************************************************** +* NOTE: +* Each entry represents the slot offset array of one backend tdm device +* valid offset represents the starting offset in byte for the channel +* use 0xFFFF for end or unused slot offset entry. +*****************************************************************************/ +static unsigned int tdm_rx_slot_offset_custom + [TDM_INTERFACE_MAX][TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { + {/* PRI TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* SEC TDM */ + {0, 2, 0xFFFF}, + {4, 0xFFFF}, + {6, 0xFFFF}, + {8, 0xFFFF}, + {10, 0xFFFF}, + {12, 14, 16, 18, 20, 22, 24, 26, 0xFFFF}, + {28, 30, 0xFFFF}, + {0xFFFF}, /* not used */ + }, + {/* TERT TDM */ + {0, 2, 0xFFFF}, + {4, 6, 8, 10, 12, 14, 16, 18, 0xFFFF}, + {20, 22, 24, 26, 28, 30, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUAT TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUIN TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + } +}; + +static unsigned int tdm_tx_slot_offset_custom + [TDM_INTERFACE_MAX][TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { + {/* PRI TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* SEC TDM */ + {0, 2, 0xFFFF}, + {4, 6, 8, 10, 12, 14, 16, 18, 0xFFFF}, + {20, 22, 24, 26, 28, 30, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* TERT TDM */ + {0, 2, 4, 6, 8, 10, 12, 0xFFFF}, + {14, 16, 0xFFFF}, + {18, 20, 22, 24, 26, 28, 30, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUAT TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUIN TDM */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + } +}; + + +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; +static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE", + "S24_3LE"}; +static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *ch_text[] = {"Two", "Three", "Four", "Five", + "Six", "Seven", "Eight"}; +static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_32", "KHZ_44P1", + "KHZ_88P2", "KHZ_176P4"}; +static char const *tdm_ch_text[] = { + "One", "Two", "Three", "Four", + "Five", "Six", "Seven", "Eight", + "Nine", "Ten", "Eleven", "Twelve", + "Thirteen", "Fourteen", "Fifteen", "Sixteen", + "Seventeen", "Eighteen", "Nineteen", "Twenty", + "TwentyOne", "TwentyTwo", "TwentyThree", "TwentyFour", + "TwentyFive", "TwentySix", "TwentySeven", "TwentyEight", + "TwentyNine", "Thirty", "ThirtyOne", "ThirtyTwo"}; +static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; +static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", + "KHZ_48", "KHZ_176P4", + "KHZ_352P8"}; +static const char *const tdm_slot_num_text[] = {"One", "Two", "Four", + "Eight", "Sixteen", "ThirtyTwo"}; +static const char *const tdm_slot_width_text[] = {"16", "24", "32"}; +static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; +static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_16", + "KHZ_22P05", "KHZ_32", "KHZ_44P1", + "KHZ_48", "KHZ_96", "KHZ_192"}; +static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static const char *const qos_text[] = {"Disable", "Enable"}; + +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, + ext_disp_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_slot_num, tdm_slot_num_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_slot_width, tdm_slot_width_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); + +static bool is_initial_boot = true; + +static struct afe_clk_set mi2s_clk[MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + } + +}; + +static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; + +static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, + usb_rx_cfg.channels); + ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1; + return 0; +} + +static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels); + return 1; +} + +static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_rx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__, + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_rx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_rx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_rx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_rx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, + usb_tx_cfg.channels); + ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1; + return 0; +} + +static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels); + return 1; +} + +static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_tx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + default: + sample_rate_val = 6; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__, + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_tx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_tx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_tx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_tx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx = 0; + + if (strnstr(kcontrol->id.name, "Display Port RX", + sizeof("Display Port RX"))) { + idx = DP_RX_IDX; + } else { + pr_err("%s: unsupported BE: %s\n", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].bit_format) { + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 2: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int ext_disp_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.integer.value[0] = + ext_disp_rx_cfg[idx].channels - 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + + return 0; +} + +static int ext_disp_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ext_disp_rx_cfg[idx].channels = + ucontrol->value.integer.value[0] + 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + return 1; +} + +static int ext_disp_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].sample_rate) { + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 6; + break; + + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 4; + break; + + case SAMPLING_RATE_32KHZ: + sample_rate_val = 3; + break; + + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: ext_disp_rx[%d].sample_rate = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].sample_rate); + + return 0; +} + +static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 6: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 5: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 4: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_32KHZ; + break; + case 2: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, ext_disp_rx[%d].sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], idx, + ext_disp_rx_cfg[idx].sample_rate); + return 0; +} + +static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2; + + return 0; +} + +static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2; + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + + return 1; +} + +static int tdm_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int aux_pcm_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 0: + default: + sample_rate = SAMPLING_RATE_8KHZ; + break; + } + return sample_rate; +} + +static int tdm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 5; + break; + default: + sample_rate_val = 3; + break; + } + return sample_rate_val; +} + +static int aux_pcm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + return sample_rate_val; +} + +static int tdm_get_mode(struct snd_kcontrol *kcontrol) +{ + int mode = TDM_PRI; + + if (strnstr(kcontrol->id.name, "PRI", + sizeof(kcontrol->id.name))) { + mode = TDM_PRI; + } else if (strnstr(kcontrol->id.name, "SEC", + sizeof(kcontrol->id.name))) { + mode = TDM_SEC; + } else if (strnstr(kcontrol->id.name, "TERT", + sizeof(kcontrol->id.name))) { + mode = TDM_TERT; + } else if (strnstr(kcontrol->id.name, "QUAT", + sizeof(kcontrol->id.name))) { + mode = TDM_QUAT; + } else if (strnstr(kcontrol->id.name, "QUIN", + sizeof(kcontrol->id.name))) { + mode = TDM_QUIN; + } else { + pr_err("%s: unsupported mode in: %s", + __func__, kcontrol->id.name); + mode = -EINVAL; + } + + return mode; +} + +static int tdm_get_channel(struct snd_kcontrol *kcontrol) +{ + int channel = TDM_0; + + if (strnstr(kcontrol->id.name, "RX_0", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_0", + sizeof(kcontrol->id.name))) { + channel = TDM_0; + } else if (strnstr(kcontrol->id.name, "RX_1", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_1", + sizeof(kcontrol->id.name))) { + channel = TDM_1; + } else if (strnstr(kcontrol->id.name, "RX_2", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_2", + sizeof(kcontrol->id.name))) { + channel = TDM_2; + } else if (strnstr(kcontrol->id.name, "RX_3", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_3", + sizeof(kcontrol->id.name))) { + channel = TDM_3; + } else if (strnstr(kcontrol->id.name, "RX_4", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_4", + sizeof(kcontrol->id.name))) { + channel = TDM_4; + } else if (strnstr(kcontrol->id.name, "RX_5", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_5", + sizeof(kcontrol->id.name))) { + channel = TDM_5; + } else if (strnstr(kcontrol->id.name, "RX_6", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_6", + sizeof(kcontrol->id.name))) { + channel = TDM_6; + } else if (strnstr(kcontrol->id.name, "RX_7", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_7", + sizeof(kcontrol->id.name))) { + channel = TDM_7; + } else { + pr_err("%s: unsupported channel in: %s", + __func__, kcontrol->id.name); + channel = -EINVAL; + } + + return channel; +} + +static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, + struct tdm_port *port) +{ + if (port) { + port->mode = tdm_get_mode(kcontrol); + if (port->mode < 0) + return port->mode; + + port->channel = tdm_get_channel(kcontrol); + if (port->channel < 0) + return port->channel; + } else { + return -EINVAL; + } + return 0; +} + +static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_rx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_tx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_get_format(int value) +{ + int format = 0; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int tdm_get_format_val(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 2; + break; + default: + value = 0; + break; + } + return value; +} + +static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_rx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_tx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + + ucontrol->value.enumerated.item[0] = + tdm_rx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = + tdm_tx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int tdm_get_slot_num_val(int slot_num) +{ + int slot_num_val = 0; + + switch (slot_num) { + case 1: + slot_num_val = 0; + break; + case 2: + slot_num_val = 1; + break; + case 4: + slot_num_val = 2; + break; + case 8: + slot_num_val = 3; + break; + case 16: + slot_num_val = 4; + break; + case 32: + slot_num_val = 5; + break; + default: + slot_num_val = 5; + break; + } + return slot_num_val; +} + +static int tdm_slot_num_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int mode = tdm_get_mode(kcontrol); + + if (mode < 0) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + return mode; + } + + ucontrol->value.enumerated.item[0] = + tdm_get_slot_num_val(tdm_slot[mode].num); + + pr_debug("%s: mode = %d, tdm_slot_num = %d, item = %d\n", __func__, + mode, tdm_slot[mode].num, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int tdm_get_slot_num(int value) +{ + int slot_num = 0; + + switch (value) { + case 0: + slot_num = 1; + break; + case 1: + slot_num = 2; + break; + case 2: + slot_num = 4; + break; + case 3: + slot_num = 8; + break; + case 4: + slot_num = 16; + break; + case 5: + slot_num = 32; + break; + default: + slot_num = 8; + break; + } + return slot_num; +} + +static int tdm_slot_num_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int mode = tdm_get_mode(kcontrol); + + if (mode < 0) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + return mode; + } + + tdm_slot[mode].num = + tdm_get_slot_num(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: mode = %d, tdm_slot_num = %d, item = %d\n", __func__, + mode, tdm_slot[mode].num, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int tdm_get_slot_width_val(int slot_width) +{ + int slot_width_val = 2; + + switch (slot_width) { + case 16: + slot_width_val = 0; + break; + case 24: + slot_width_val = 1; + break; + case 32: + slot_width_val = 2; + break; + default: + slot_width_val = 2; + break; + } + return slot_width_val; +} + +static int tdm_slot_width_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int mode = tdm_get_mode(kcontrol); + + if (mode < 0) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + return mode; + } + + ucontrol->value.enumerated.item[0] = + tdm_get_slot_width_val(tdm_slot[mode].width); + + pr_debug("%s: mode = %d, tdm_slot_width = %d, item = %d\n", __func__, + mode, tdm_slot[mode].width, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int tdm_get_slot_width(int value) +{ + int slot_width = 32; + + switch (value) { + case 0: + slot_width = 16; + break; + case 1: + slot_width = 24; + break; + case 2: + slot_width = 32; + break; + default: + slot_width = 32; + break; + } + return slot_width; +} + +static int tdm_slot_width_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int mode = tdm_get_mode(kcontrol); + + if (mode < 0) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + return mode; + } + + tdm_slot[mode].width = + tdm_get_slot_width(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: mode = %d, tdm_slot_width = %d, item = %d\n", __func__, + mode, tdm_slot[mode].width, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int tdm_rx_slot_mapping_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int *slot_offset; + int i; + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + slot_offset = tdm_rx_slot_offset[port.mode][port.channel]; + pr_debug("%s: mode = %d, channel = %d\n", + __func__, port.mode, port.channel); + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + ucontrol->value.integer.value[i] = slot_offset[i]; + pr_debug("%s: offset %d, value %d\n", + __func__, i, slot_offset[i]); + } + } + return ret; +} + +static int tdm_rx_slot_mapping_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int *slot_offset; + int i; + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + slot_offset = tdm_rx_slot_offset[port.mode][port.channel]; + pr_debug("%s: mode = %d, channel = %d\n", + __func__, port.mode, port.channel); + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + slot_offset[i] = ucontrol->value.integer.value[i]; + pr_debug("%s: offset %d, value %d\n", + __func__, i, slot_offset[i]); + } + } + return ret; +} + +static int tdm_tx_slot_mapping_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int *slot_offset; + int i; + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + slot_offset = tdm_tx_slot_offset[port.mode][port.channel]; + pr_debug("%s: mode = %d, channel = %d\n", + __func__, port.mode, port.channel); + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + ucontrol->value.integer.value[i] = slot_offset[i]; + pr_debug("%s: offset %d, value %d\n", + __func__, i, slot_offset[i]); + } + } + return ret; +} + +static int tdm_tx_slot_mapping_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int *slot_offset; + int i; + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + slot_offset = tdm_tx_slot_offset[port.mode][port.channel]; + pr_debug("%s: mode = %d, channel = %d\n", + __func__, port.mode, port.channel); + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + slot_offset[i] = ucontrol->value.integer.value[i]; + pr_debug("%s: offset %d, value %d\n", + __func__, i, slot_offset[i]); + } + } + return ret; +} + +static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", + sizeof("PRIM_AUX_PCM"))) + idx = PRIM_AUX_PCM; + else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM", + sizeof("SEC_AUX_PCM"))) + idx = SEC_AUX_PCM; + else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", + sizeof("TERT_AUX_PCM"))) + idx = TERT_AUX_PCM; + else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", + sizeof("QUAT_AUX_PCM"))) + idx = QUAT_AUX_PCM; + else if (strnstr(kcontrol->id.name, "QUIN_AUX_PCM", + sizeof("QUIN_AUX_PCM"))) + idx = QUIN_AUX_PCM; + else { + pr_err("%s: unsupported port: %s\n", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX", + sizeof("PRIM_MI2S_RX"))) + idx = PRIM_MI2S; + else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX", + sizeof("SEC_MI2S_RX"))) + idx = SEC_MI2S; + else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", + sizeof("TERT_MI2S_RX"))) + idx = TERT_MI2S; + else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", + sizeof("QUAT_MI2S_RX"))) + idx = QUAT_MI2S; + else if (strnstr(kcontrol->id.name, "QUIN_MI2S_RX", + sizeof("QUIN_MI2S_RX"))) + idx = QUIN_MI2S; + else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", + sizeof("PRIM_MI2S_TX"))) + idx = PRIM_MI2S; + else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX", + sizeof("SEC_MI2S_TX"))) + idx = SEC_MI2S; + else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", + sizeof("TERT_MI2S_TX"))) + idx = TERT_MI2S; + else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", + sizeof("QUAT_MI2S_TX"))) + idx = QUAT_MI2S; + else if (strnstr(kcontrol->id.name, "QUIN_MI2S_TX", + sizeof("QUIN_MI2S_TX"))) + idx = QUIN_MI2S; + else { + pr_err("%s: unsupported channel: %s\n", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int mi2s_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + default: + sample_rate_val = 6; + break; + } + return sample_rate_val; +} + +static int mi2s_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_192KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int mi2s_auxpcm_get_format(int value) +{ + int format; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int mi2s_auxpcm_get_format_value(int format) +{ + int value; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + value = 2; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 3; + break; + default: + value = 0; + break; + } + return value; +} + +static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(mi2s_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(mi2s_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(aux_pcm_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(aux_pcm_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, + usb_audio_rx_ch_get, usb_audio_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, + usb_audio_tx_ch_get, usb_audio_tx_ch_put), + SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, + ext_disp_rx_ch_get, ext_disp_rx_ch_put), + SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, + proxy_rx_ch_get, proxy_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, + usb_audio_rx_format_get, usb_audio_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, + usb_audio_tx_format_get, usb_audio_tx_format_put), + SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, + ext_disp_rx_format_get, ext_disp_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, + usb_audio_rx_sample_rate_get, + usb_audio_rx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, + usb_audio_tx_sample_rate_get, + usb_audio_tx_sample_rate_put), + SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, + ext_disp_rx_sample_rate_get, + ext_disp_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_1 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_2 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_3 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_1 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_2 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_3 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_1 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_2 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_3 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_1 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_2 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_3 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_RX_1 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_RX_2 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_RX_3 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_1 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_2 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_3 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_1 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_2 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_3 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_1 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_2 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_3 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_1 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_2 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_3 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_1 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_2 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_3 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_1 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_2 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_3 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_1 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_2 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_3 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_1 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_2 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_3 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_4 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_1 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_2 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_3 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_1 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_2 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_3 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_4 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_1 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_2 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_3 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_1 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_2 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_3 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_4 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_1 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_2 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_3 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_1 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_2 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_3 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_1 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_2 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_3 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_1 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_2 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_3 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_1 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_2 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_3 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_1 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_2 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_3 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_1 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_2 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_3 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_RX_1 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_RX_2 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_RX_3 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_TX_1 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_TX_2 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_TX_3 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_1 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_2 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_3 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_1 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_2 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_3 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_RX_1 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_RX_2 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_RX_3 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_TX_1 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_TX_2 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_TX_3 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRI_TDM SlotNumber", tdm_slot_num, + tdm_slot_num_get, tdm_slot_num_put), + SOC_ENUM_EXT("PRI_TDM SlotWidth", tdm_slot_width, + tdm_slot_width_get, tdm_slot_width_put), + SOC_ENUM_EXT("SEC_TDM SlotNumber", tdm_slot_num, + tdm_slot_num_get, tdm_slot_num_put), + SOC_ENUM_EXT("SEC_TDM SlotWidth", tdm_slot_width, + tdm_slot_width_get, tdm_slot_width_put), + SOC_ENUM_EXT("TERT_TDM SlotNumber", tdm_slot_num, + tdm_slot_num_get, tdm_slot_num_put), + SOC_ENUM_EXT("TERT_TDM SlotWidth", tdm_slot_width, + tdm_slot_width_get, tdm_slot_width_put), + SOC_ENUM_EXT("QUAT_TDM SlotNumber", tdm_slot_num, + tdm_slot_num_get, tdm_slot_num_put), + SOC_ENUM_EXT("QUAT_TDM SlotWidth", tdm_slot_width, + tdm_slot_width_get, tdm_slot_width_put), + SOC_ENUM_EXT("QUIN_TDM SlotNumber", tdm_slot_num, + tdm_slot_num_get, tdm_slot_num_put), + SOC_ENUM_EXT("QUIN_TDM SlotWidth", tdm_slot_width, + tdm_slot_width_get, tdm_slot_width_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_4 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_RX SampleRate", quin_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_TX SampleRate", quin_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_MI2S_RX SampleRate", quin_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_MI2S_TX SampleRate", quin_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUIN_MI2S_RX Channels", quin_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUIN_MI2S_TX Channels", quin_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("SEC_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("TERT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("TERT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("QUIN_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("QUIN_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), +}; + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, + int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, + unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +static int msm_ext_disp_get_idx_from_beid(int32_t be_id) +{ + int idx; + + switch (be_id) { + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = DP_RX_IDX; + break; + default: + pr_err("%s: Incorrect ext_disp BE id %d\n", __func__, be_id); + idx = -EINVAL; + break; + } + + return idx; +} + +static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int rc = 0; + int idx; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->id) { + case MSM_BACKEND_DAI_USB_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_rx_cfg.bit_format); + rate->min = rate->max = usb_rx_cfg.sample_rate; + channels->min = channels->max = usb_rx_cfg.channels; + break; + + case MSM_BACKEND_DAI_USB_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_tx_cfg.bit_format); + rate->min = rate->max = usb_tx_cfg.sample_rate; + channels->min = channels->max = usb_tx_cfg.channels; + break; + + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = msm_ext_disp_get_idx_from_beid(dai_link->id); + if (idx < 0) { + pr_err("%s: Incorrect ext disp idx %d\n", + __func__, idx); + rc = idx; + goto done; + } + + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + ext_disp_rx_cfg[idx].bit_format); + rate->min = rate->max = ext_disp_rx_cfg[idx].sample_rate; + channels->min = channels->max = ext_disp_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_AFE_PCM_RX: + channels->min = channels->max = proxy_rx_cfg.channels; + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + + case MSM_BACKEND_DAI_PRI_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_PRI_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUIN_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUIN_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + + + case MSM_BACKEND_DAI_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[PRIM_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[SEC_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[SEC_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[TERT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[TERT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[QUAT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[QUAT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUIN_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[QUIN_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[QUIN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUIN_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUIN_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[QUIN_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[QUIN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUIN_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUAT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUAT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUINARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUIN_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[QUIN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUIN_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUIN_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[QUIN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUIN_MI2S].channels; + break; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + +done: + return rc; +} + +static int msm_get_port_id(int be_id) +{ + int afe_port_id; + + switch (be_id) { + case MSM_BACKEND_DAI_PRI_MI2S_RX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_PRI_MI2S_TX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUINARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUINARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUINARY_MI2S_TX; + break; + default: + pr_err("%s: Invalid BE id: %d\n", __func__, be_id); + afe_port_id = -EINVAL; + } + + return afe_port_id; +} + +static u32 get_mi2s_bits_per_sample(u32 bit_format) +{ + u32 bit_per_sample; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + case SNDRV_PCM_FORMAT_S24_LE: + bit_per_sample = 32; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bit_per_sample = 16; + break; + } + + return bit_per_sample; +} + +static void update_mi2s_clk_val(int dai_id, int stream) +{ + u32 bit_per_sample; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } else { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } +} + +static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int port_id = 0; + int index = cpu_dai->id; + + port_id = msm_get_port_id(rtd->dai_link->id); + if (port_id < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto err; + } + + if (enable) { + update_mi2s_clk_val(index, substream->stream); + dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, + mi2s_clk[index].clk_freq_in_hz); + } + + mi2s_clk[index].enable = enable; + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_clk[index]); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed for port 0x%x , err:%d\n", + __func__, port_id, ret); + goto err; + } + +err: + return ret; +} + +#ifdef ENABLE_PINCTRL +static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, + enum pinctrl_pin_state new_state) +{ + int ret = 0; + int curr_state = 0; + + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + if (pinctrl_info->pinctrl == NULL) { + pr_err("%s: pinctrl_info->pinctrl is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + curr_state = pinctrl_info->curr_state; + pinctrl_info->curr_state = new_state; + pr_debug("%s: curr_state = %s new_state = %s\n", __func__, + pin_states[curr_state], pin_states[pinctrl_info->curr_state]); + + if (curr_state == pinctrl_info->curr_state) { + pr_debug("%s: Already in same state\n", __func__); + goto err; + } + + if (curr_state != STATE_DISABLE && + pinctrl_info->curr_state != STATE_DISABLE) { + pr_debug("%s: state already active cannot switch\n", __func__); + ret = -EIO; + goto err; + } + + switch (pinctrl_info->curr_state) { + case STATE_MI2S_ACTIVE: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_active); + if (ret) { + pr_err("%s: MI2S state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + case STATE_TDM_ACTIVE: + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->tdm_active); + if (ret) { + pr_err("%s: TDM state select failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + case STATE_DISABLE: + if (curr_state == STATE_MI2S_ACTIVE) { + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_disable); + } else { + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->tdm_disable); + } + if (ret) { + pr_err("%s: state disable failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + break; + default: + pr_err("%s: TLMM pin state is invalid\n", __func__); + return -EINVAL; + } + +err: + return ret; +} + +static void msm_release_pinctrl(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + if (pinctrl_info->pinctrl) { + devm_pinctrl_put(pinctrl_info->pinctrl); + pinctrl_info->pinctrl = NULL; + } +} + +static int msm_get_pinctrl(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = NULL; + struct pinctrl *pinctrl; + int ret = 0; + + pinctrl_info = &pdata->pinctrl_info; + + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl_info is NULL\n", __func__); + return -EINVAL; + } + + pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR_OR_NULL(pinctrl)) { + pr_err("%s: Unable to get pinctrl handle\n", __func__); + return -EINVAL; + } + pinctrl_info->pinctrl = pinctrl; + + /* get all the states handles from Device Tree */ + pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl, + "quat_mi2s_disable"); + if (IS_ERR(pinctrl_info->mi2s_disable)) { + pr_err("%s: could not get mi2s_disable pinstate\n", __func__); + goto err; + } + pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl, + "quat_mi2s_enable"); + if (IS_ERR(pinctrl_info->mi2s_active)) { + pr_err("%s: could not get mi2s_active pinstate\n", __func__); + goto err; + } + pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl, + "quat_tdm_disable"); + if (IS_ERR(pinctrl_info->tdm_disable)) { + pr_err("%s: could not get tdm_disable pinstate\n", __func__); + goto err; + } + pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl, + "quat_tdm_enable"); + if (IS_ERR(pinctrl_info->tdm_active)) { + pr_err("%s: could not get tdm_active pinstate\n", + __func__); + goto err; + } + /* Reset the TLMM pins to a default state */ + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->mi2s_disable); + if (ret != 0) { + pr_err("%s: Disable TLMM pins failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + pinctrl_info->curr_state = STATE_DISABLE; + + return 0; + +err: + devm_pinctrl_put(pinctrl); + pinctrl_info->pinctrl = NULL; + return -EINVAL; +} +#else +static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, + enum pinctrl_pin_state new_state) +{ + return 0; +} + +static void msm_release_pinctrl(struct platform_device *pdev) +{ + return; +} + +static int msm_get_pinctrl(struct platform_device *pdev) +{ + return 0; +} +#endif + +static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_1].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_PRI][TDM_1].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_2].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_PRI][TDM_2].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_3].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_PRI][TDM_3].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_1].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_PRI][TDM_1].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_2].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_PRI][TDM_2].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_3].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_PRI][TDM_3].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_1].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_1].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_2].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_2].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_3].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_3].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_1].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_SEC][TDM_1].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_2].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_SEC][TDM_2].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_3].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_SEC][TDM_3].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_1].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_1].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_2].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_2].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_3].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_3].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_4].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_4].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_4].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_1].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_1].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_2].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_2].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_3].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_3].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_1].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_1].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_2].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_2].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_3].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_3].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_1].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_1].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_2].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_2].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_3].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_3].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_RX: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_1: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_1].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_1].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_2: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_2].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_2].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_3: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_3].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_3].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_TX: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_1: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_1].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_1].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_2: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_2].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_2].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_3: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_3].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_3].sample_rate; + break; + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n", + __func__, cpu_dai->id, channels->max, rate->max, + params_format(params)); + + return 0; +} + +static unsigned int tdm_param_set_slot_mask(int slots) +{ + unsigned int slot_mask = 0; + int i = 0; + + if ((slots <= 0) || (slots > 32)) { + pr_err("%s: invalid slot number %d\n", __func__, slots); + return -EINVAL; + } + + for (i = 0; i < slots ; i++) + slot_mask |= 1 << i; + return slot_mask; +} + +static int sa6155_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + int channels, slot_width, slots, rate, format; + unsigned int slot_mask; + unsigned int *slot_offset; + int offset_channels = 0; + int i; + int clk_freq; + + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + + channels = params_channels(params); + if (channels < 1 || channels > 32) { + pr_err("%s: invalid param channels %d\n", + __func__, channels); + return -EINVAL; + } + + format = params_format(params); + if (format != SNDRV_PCM_FORMAT_S32_LE && + format != SNDRV_PCM_FORMAT_S24_LE && + format != SNDRV_PCM_FORMAT_S16_LE) { + /* + * Up to 8 channel HW configuration should + * use 32 bit slot width for max support of + * stream bit width. (slot_width > bit_width) + */ + pr_err("%s: invalid param format 0x%x\n", + __func__, format); + return -EINVAL; + } + + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_0]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_1]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_2]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_3]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_0]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_1]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_2]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_3]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_0]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_1]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_2]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_3]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_0]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_1]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_2]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_3]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_0]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_1]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_2]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_3]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_4]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_0]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_1]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_2]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_3]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_0]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_1]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_2]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_3]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_0]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_1]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_2]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_3]; + break; + case AFE_PORT_ID_QUINARY_TDM_RX: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_0]; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_1: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_1]; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_2: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_2]; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_3: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_3]; + break; + case AFE_PORT_ID_QUINARY_TDM_TX: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_0]; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_1: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_1]; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_2: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_2]; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_3: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_3]; + break; + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) + offset_channels++; + else + break; + } + + if (offset_channels == 0) { + pr_err("%s: invalid offset_channels %d\n", + __func__, offset_channels); + return -EINVAL; + } + + if (channels > offset_channels) { + pr_err("%s: channels %d exceed offset_channels %d\n", + __func__, channels, offset_channels); + return -EINVAL; + } + + slot_mask = tdm_param_set_slot_mask(slots); + if (!slot_mask) { + pr_err("%s: invalid slot_mask 0x%x\n", + __func__, slot_mask); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + 0, NULL, channels, slot_offset); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + channels, slot_offset, 0, NULL); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } else { + ret = -EINVAL; + pr_err("%s: invalid use case, err:%d\n", + __func__, ret); + goto end; + } + + rate = params_rate(params); + clk_freq = rate * slot_width * slots; + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, clk_freq, SND_SOC_CLOCK_OUT); + if (ret < 0) + pr_err("%s: failed to set tdm clk, err:%d\n", + __func__, ret); + +end: + return ret; +} + +static int sa6155_tdm_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || + (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { + ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); + if (ret) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret); + } + + return ret; +} + +static void sa6155_tdm_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || + (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { + ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); + if (ret) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret); + } +} + +static struct snd_soc_ops sa6155_tdm_be_ops = { + .hw_params = sa6155_tdm_snd_hw_params, + .startup = sa6155_tdm_snd_startup, + .shutdown = sa6155_tdm_snd_shutdown +}; + +static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) +{ + cpumask_t mask; + + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + + cpumask_clear(&mask); + cpumask_set_cpu(1, &mask); /* affine to core 1 */ + cpumask_set_cpu(2, &mask); /* affine to core 2 */ + cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); + + substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; + + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + MSM_LL_QOS_VALUE); + return 0; +} + +static struct snd_soc_ops msm_fe_qos_ops = { + .prepare = msm_fe_qos_prepare, +}; + +static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int index = cpu_dai->id; + unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret_pinctrl = 0; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + if (index < PRIM_MI2S || index >= MI2S_MAX) { + ret = -EINVAL; + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto err; + } + /* + * Mutex protection in case the same MI2S + * interface using for both TX and RX so + * that the same clock won't be enable twice. + */ + mutex_lock(&mi2s_intf_conf[index].lock); + if (++mi2s_intf_conf[index].ref_cnt == 1) { + /* Check if msm needs to provide the clock to the interface */ + if (!mi2s_intf_conf[index].msm_is_mi2s_master) { + mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; + fmt = SND_SOC_DAIFMT_CBM_CFM; + } + ret = msm_mi2s_set_sclk(substream, true); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed to enable MI2S clock, err:%d\n", + __func__, ret); + goto clean_up; + } + + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) { + pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n", + __func__, index, ret); + goto clk_off; + } + if (index == QUAT_MI2S) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_MI2S_ACTIVE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } + } +clk_off: + if (ret < 0) + msm_mi2s_set_sclk(substream, false); +clean_up: + if (ret < 0) + mi2s_intf_conf[index].ref_cnt--; + mutex_unlock(&mi2s_intf_conf[index].lock); +err: + return ret; +} + +static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int index = rtd->cpu_dai->id; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + int ret_pinctrl = 0; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + if (index < PRIM_MI2S || index >= MI2S_MAX) { + pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); + return; + } + + mutex_lock(&mi2s_intf_conf[index].lock); + if (--mi2s_intf_conf[index].ref_cnt == 0) { + ret = msm_mi2s_set_sclk(substream, false); + if (ret < 0) + pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", + __func__, index, ret); + if (index == QUAT_MI2S) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_DISABLE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } + } + mutex_unlock(&mi2s_intf_conf[index].lock); +} + +static struct snd_soc_ops msm_mi2s_be_ops = { + .startup = msm_mi2s_snd_startup, + .shutdown = msm_mi2s_snd_shutdown, +}; + + +/* Digital audio interface glue - connects codec <---> CPU */ +static struct snd_soc_dai_link msm_common_dai_links[] = { + /* FrontEnd DAI Links */ + { + .name = MSM_DAILINK_NAME(Media1), + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, + { + .name = MSM_DAILINK_NAME(Media2), + .stream_name = "MultiMedia2", + .cpu_dai_name = "MultiMedia2", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, + }, + { + .name = "VoiceMMode1", + .stream_name = "VoiceMMode1", + .cpu_dai_name = "VoiceMMode1", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE1, + }, + { + .name = "MSM VoIP", + .stream_name = "VoIP", + .cpu_dai_name = "VoIP", + .platform_name = "msm-voip-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_VOIP, + }, + { + .name = MSM_DAILINK_NAME(ULL), + .stream_name = "MultiMedia3", + .cpu_dai_name = "MultiMedia3", + .platform_name = "msm-pcm-dsp.2", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA3, + }, + /* - SLIMBUS_0 Hostless */ + { + .name = "MSM AFE-PCM RX", + .stream_name = "AFE-PROXY RX", + .cpu_dai_name = "msm-dai-q6-dev.241", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .platform_name = "msm-pcm-afe", + .dpcm_playback = 1, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + }, + { + .name = "MSM AFE-PCM TX", + .stream_name = "AFE-PROXY TX", + .cpu_dai_name = "msm-dai-q6-dev.240", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .platform_name = "msm-pcm-afe", + .dpcm_capture = 1, + .ignore_suspend = 1, + }, + { + .name = MSM_DAILINK_NAME(Compress1), + .stream_name = "Compress1", + .cpu_dai_name = "MultiMedia4", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA4, + }, + /* Hostless PCM purpose */ + { + .name = "AUXPCM Hostless", + .stream_name = "AUXPCM Hostless", + .cpu_dai_name = "AUXPCM_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + /* - SLIMBUS_1 Hostless */ + /* - SLIMBUS_3 Hostless */ + /* - SLIMBUS_4 Hostless */ + { + .name = MSM_DAILINK_NAME(LowLatency), + .stream_name = "MultiMedia5", + .cpu_dai_name = "MultiMedia5", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .ops = &msm_fe_qos_ops, + }, + { + .name = "Listen 1 Audio Service", + .stream_name = "Listen 1 Audio Service", + .cpu_dai_name = "LSM1", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM1, + }, + /* Multiple Tunnel instances */ + { + .name = MSM_DAILINK_NAME(Compress2), + .stream_name = "Compress2", + .cpu_dai_name = "MultiMedia7", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA7, + }, + { + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", + .cpu_dai_name = "MultiMedia10", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA10, + }, + { + .name = MSM_DAILINK_NAME(ULL_NOIRQ), + .stream_name = "MM_NOIRQ", + .cpu_dai_name = "MultiMedia8", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + .ops = &msm_fe_qos_ops, + }, + /* HDMI Hostless */ + { + .name = "HDMI_RX_HOSTLESS", + .stream_name = "HDMI_RX_HOSTLESS", + .cpu_dai_name = "HDMI_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "VoiceMMode2", + .stream_name = "VoiceMMode2", + .cpu_dai_name = "VoiceMMode2", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE2, + }, + /* LSM FE */ + { + .name = "Listen 2 Audio Service", + .stream_name = "Listen 2 Audio Service", + .cpu_dai_name = "LSM2", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM2, + }, + { + .name = "Listen 3 Audio Service", + .stream_name = "Listen 3 Audio Service", + .cpu_dai_name = "LSM3", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM3, + }, + { + .name = "Listen 4 Audio Service", + .stream_name = "Listen 4 Audio Service", + .cpu_dai_name = "LSM4", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM4, + }, + { + .name = "Listen 5 Audio Service", + .stream_name = "Listen 5 Audio Service", + .cpu_dai_name = "LSM5", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM5, + }, + { + .name = "Listen 6 Audio Service", + .stream_name = "Listen 6 Audio Service", + .cpu_dai_name = "LSM6", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM6, + }, + { + .name = "Listen 7 Audio Service", + .stream_name = "Listen 7 Audio Service", + .cpu_dai_name = "LSM7", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM7, + }, + { + .name = "Listen 8 Audio Service", + .stream_name = "Listen 8 Audio Service", + .cpu_dai_name = "LSM8", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM8, + }, + /* - Multimedia9 */ + { + .name = MSM_DAILINK_NAME(Compress4), + .stream_name = "Compress4", + .cpu_dai_name = "MultiMedia11", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA11, + }, + { + .name = MSM_DAILINK_NAME(Compress5), + .stream_name = "Compress5", + .cpu_dai_name = "MultiMedia12", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA12, + }, + { + .name = MSM_DAILINK_NAME(Compress6), + .stream_name = "Compress6", + .cpu_dai_name = "MultiMedia13", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA13, + }, + { + .name = MSM_DAILINK_NAME(Compress7), + .stream_name = "Compress7", + .cpu_dai_name = "MultiMedia14", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA14, + }, + { + .name = MSM_DAILINK_NAME(Compress8), + .stream_name = "Compress8", + .cpu_dai_name = "MultiMedia15", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA15, + }, + { + .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), + .stream_name = "MM_NOIRQ_2", + .cpu_dai_name = "MultiMedia16", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA16, + }, + /* - SLIMBUS_8 Hostless */ + /* - Slimbus4 Capture */ + /* - SLIMBUS_2 Hostless Playback */ + /* - SLIMBUS_2 Hostless Capture */ + /* HFP TX */ + { + .name = MSM_DAILINK_NAME(ASM Loopback), + .stream_name = "MultiMedia6", + .cpu_dai_name = "MultiMedia6", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA6, + }, + { + .name = "USB Audio Hostless", + .stream_name = "USB Audio Hostless", + .cpu_dai_name = "USBAUDIO_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + /* - SLIMBUS_7 Hostless */ + { + .name = "Compress Capture", + .stream_name = "Compress9", + .cpu_dai_name = "MultiMedia17", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA17, + }, +}; + +static struct snd_soc_dai_link msm_auto_fe_dai_links[] = { + { + .name = "INT_HFP_BT Hostless", + .stream_name = "INT_HFP_BT Hostless", + .cpu_dai_name = "INT_HFP_BT_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + /* Low latency ASM loopback for ICC */ + { + .name = MSM_DAILINK_NAME(LowLatency Loopback), + .stream_name = "MultiMedia9", + .cpu_dai_name = "MultiMedia9", + .platform_name = "msm-pcm-loopback.1", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA9, + }, + { + .name = "Tertiary MI2S TX_Hostless", + .stream_name = "Tertiary MI2S_TX Hostless Capture", + .cpu_dai_name = "TERT_MI2S_TX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = MSM_DAILINK_NAME(Media20), + .stream_name = "MultiMedia20", + .cpu_dai_name = "MultiMedia20", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA20, + }, + { + .name = MSM_DAILINK_NAME(HFP RX), + .stream_name = "MultiMedia21", + .cpu_dai_name = "MultiMedia21", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA21, + }, + /* TDM Hostless */ + { + .name = "Primary TDM RX 0 Hostless", + .stream_name = "Primary TDM RX 0 Hostless", + .cpu_dai_name = "PRI_TDM_RX_0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Primary TDM TX 0 Hostless", + .stream_name = "Primary TDM TX 0 Hostless", + .cpu_dai_name = "PRI_TDM_TX_0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Secondary TDM RX 0 Hostless", + .stream_name = "Secondary TDM RX 0 Hostless", + .cpu_dai_name = "SEC_TDM_RX_0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Secondary TDM TX 0 Hostless", + .stream_name = "Secondary TDM TX 0 Hostless", + .cpu_dai_name = "SEC_TDM_TX_0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Tertiary TDM RX 0 Hostless", + .stream_name = "Tertiary TDM RX 0 Hostless", + .cpu_dai_name = "TERT_TDM_RX_0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Tertiary TDM TX 0 Hostless", + .stream_name = "Tertiary TDM TX 0 Hostless", + .cpu_dai_name = "TERT_TDM_TX_0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Quaternary TDM RX 0 Hostless", + .stream_name = "Quaternary TDM RX 0 Hostless", + .cpu_dai_name = "QUAT_TDM_RX_0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Quaternary TDM TX 0 Hostless", + .stream_name = "Quaternary TDM TX 0 Hostless", + .cpu_dai_name = "QUAT_TDM_TX_0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Quaternary MI2S_RX Hostless Playback", + .stream_name = "Quaternary MI2S_RX Hostless Playback", + .cpu_dai_name = "QUAT_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Secondary MI2S_TX Hostless Capture", + .stream_name = "Secondary MI2S_TX Hostless Capture", + .cpu_dai_name = "SEC_MI2S_TX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "DTMF RX Hostless", + .stream_name = "DTMF RX Hostless", + .cpu_dai_name = "DTMF_RX_HOSTLESS", + .platform_name = "msm-pcm-dtmf", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_DTMF_RX, + } +}; + +static struct snd_soc_dai_link msm_custom_fe_dai_links[] = { + /* FrontEnd DAI Links */ + { + .name = MSM_DAILINK_NAME(Media1), + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1, + .ops = &msm_fe_qos_ops, + }, + { + .name = MSM_DAILINK_NAME(Media2), + .stream_name = "MultiMedia2", + .cpu_dai_name = "MultiMedia2", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, + .ops = &msm_fe_qos_ops, + }, + { + .name = MSM_DAILINK_NAME(Media3), + .stream_name = "MultiMedia3", + .cpu_dai_name = "MultiMedia3", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA3, + .ops = &msm_fe_qos_ops, + }, + { + .name = MSM_DAILINK_NAME(Media5), + .stream_name = "MultiMedia5", + .cpu_dai_name = "MultiMedia5", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .ops = &msm_fe_qos_ops, + }, + { + .name = MSM_DAILINK_NAME(Media6), + .stream_name = "MultiMedia6", + .cpu_dai_name = "MultiMedia6", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA6, + .ops = &msm_fe_qos_ops, + }, + { + .name = MSM_DAILINK_NAME(Media8), + .stream_name = "MultiMedia8", + .cpu_dai_name = "MultiMedia8", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + .ops = &msm_fe_qos_ops, + }, + { + .name = MSM_DAILINK_NAME(Media9), + .stream_name = "MultiMedia9", + .cpu_dai_name = "MultiMedia9", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA9, + .ops = &msm_fe_qos_ops, + }, + { + .name = "INT_HFP_BT Hostless", + .stream_name = "INT_HFP_BT Hostless", + .cpu_dai_name = "INT_HFP_BT_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "AUXPCM Hostless", + .stream_name = "AUXPCM Hostless", + .cpu_dai_name = "AUXPCM_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = MSM_DAILINK_NAME(Media20), + .stream_name = "MultiMedia20", + .cpu_dai_name = "MultiMedia20", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA20, + }, +}; + +static struct snd_soc_dai_link msm_common_be_dai_links[] = { + /* Backend AFE DAI Links */ + { + .name = LPASS_BE_AFE_PCM_RX, + .stream_name = "AFE Playback", + .cpu_dai_name = "msm-dai-q6-dev.224", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AFE_PCM_TX, + .stream_name = "AFE Capture", + .cpu_dai_name = "msm-dai-q6-dev.225", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Uplink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_TX, + .stream_name = "Voice Uplink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32772", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Downlink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_RX, + .stream_name = "Voice Downlink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32771", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music BACK END DAI Link */ + { + .name = LPASS_BE_VOICE_PLAYBACK_TX, + .stream_name = "Voice Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32773", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + /* Incall Music 2 BACK END DAI Link */ + { + .name = LPASS_BE_VOICE2_PLAYBACK_TX, + .stream_name = "Voice2 Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32770", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_RX, + .stream_name = "USB Audio Playback", + .cpu_dai_name = "msm-dai-q6-dev.28672", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_USB_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_TX, + .stream_name = "USB Audio Capture", + .cpu_dai_name = "msm-dai-q6-dev.28673", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_USB_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_0, + .stream_name = "Primary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36864", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_0, + .stream_name = "Primary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36865", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_0, + .stream_name = "Secondary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36880", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_0, + .stream_name = "Secondary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36881", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_0, + .stream_name = "Tertiary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36896", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_0, + .stream_name = "Tertiary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36897", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_0, + .stream_name = "Quaternary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36912", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_0, + .stream_name = "Quaternary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36913", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_auto_be_dai_links[] = { + /* Backend DAI Links */ + { + .name = LPASS_BE_PRI_TDM_RX_1, + .stream_name = "Primary TDM1 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36866", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_2, + .stream_name = "Primary TDM2 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36868", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_3, + .stream_name = "Primary TDM3 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36870", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_1, + .stream_name = "Primary TDM1 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36867", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_2, + .stream_name = "Primary TDM2 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36869", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_3, + .stream_name = "Primary TDM3 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36871", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_1, + .stream_name = "Secondary TDM1 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36882", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_2, + .stream_name = "Secondary TDM2 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36884", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_3, + .stream_name = "Secondary TDM3 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36886", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_1, + .stream_name = "Secondary TDM1 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36883", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_2, + .stream_name = "Secondary TDM2 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36885", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_3, + .stream_name = "Secondary TDM3 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36887", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_1, + .stream_name = "Tertiary TDM1 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36898", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_2, + .stream_name = "Tertiary TDM2 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36900", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_3, + .stream_name = "Tertiary TDM3 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36902", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_4, + .stream_name = "Tertiary TDM4 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36904", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_4, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_1, + .stream_name = "Tertiary TDM1 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36899", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_2, + .stream_name = "Tertiary TDM2 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36901", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_3, + .stream_name = "Tertiary TDM3 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36903", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_1, + .stream_name = "Quaternary TDM1 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36914", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_2, + .stream_name = "Quaternary TDM2 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36916", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_3, + .stream_name = "Quaternary TDM3 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36918", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_1, + .stream_name = "Quaternary TDM1 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36915", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_2, + .stream_name = "Quaternary TDM2 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36917", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_3, + .stream_name = "Quaternary TDM3 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36919", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link ext_disp_be_dai_link[] = { + /* DISP PORT BACK END DAI Link */ + { + .name = LPASS_BE_DISPLAY_PORT, + .stream_name = "Display Port Playback", + .cpu_dai_name = "msm-dai-q6-dp.24608", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-ext-disp-audio-codec-rx", + .codec_dai_name = "msm_dp_audio_codec_rx_dai", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { + { + .name = LPASS_BE_PRI_MI2S_RX, + .stream_name = "Primary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_MI2S_TX, + .stream_name = "Primary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX, + .stream_name = "Secondary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX, + .stream_name = "Secondary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX, + .stream_name = "Tertiary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX, + .stream_name = "Tertiary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX, + .stream_name = "Quaternary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_RX, + .stream_name = "Quinary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_TX, + .stream_name = "Quinary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { + /* Primary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_AUXPCM_RX, + .stream_name = "AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AUXPCM_TX, + .stream_name = "AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Secondary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_SEC_AUXPCM_RX, + .stream_name = "Sec AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_AUXPCM_TX, + .stream_name = "Sec AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Tertiary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_TERT_AUXPCM_RX, + .stream_name = "Tert AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_AUXPCM_TX, + .stream_name = "Tert AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Quaternary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUAT_AUXPCM_RX, + .stream_name = "Quat AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_AUXPCM_TX, + .stream_name = "Quat AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Quinary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUIN_AUXPCM_RX, + .stream_name = "Quin AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_AUXPCM_TX, + .stream_name = "Quin AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_auto_dai_links[ + ARRAY_SIZE(msm_common_dai_links) + + ARRAY_SIZE(msm_auto_fe_dai_links) + + ARRAY_SIZE(msm_common_be_dai_links) + + ARRAY_SIZE(msm_auto_be_dai_links) + + ARRAY_SIZE(ext_disp_be_dai_link) + + ARRAY_SIZE(msm_mi2s_be_dai_links) + + ARRAY_SIZE(msm_auxpcm_be_dai_links)]; + +static struct snd_soc_dai_link msm_auto_custom_dai_links[ + ARRAY_SIZE(msm_custom_fe_dai_links) + + ARRAY_SIZE(msm_auto_fe_dai_links) + + ARRAY_SIZE(msm_common_be_dai_links) + + ARRAY_SIZE(msm_auto_be_dai_links) + + ARRAY_SIZE(ext_disp_be_dai_link) + + ARRAY_SIZE(msm_mi2s_be_dai_links) + + ARRAY_SIZE(msm_auxpcm_be_dai_links)]; + +struct snd_soc_card snd_soc_card_auto_msm = { + .name = "sa6155-adp-star-snd-card", +}; + +struct snd_soc_card snd_soc_card_auto_custom_msm = { + .name = "sa6155-custom-snd-card", +}; + +static int msm_populate_dai_link_component_of_node( + struct snd_soc_card *card) +{ + int i, index, ret = 0; + struct device *cdev = card->dev; + struct snd_soc_dai_link *dai_link = card->dai_link; + struct device_node *np; + + if (!cdev) { + pr_err("%s: Sound card device memory NULL\n", __func__); + return -ENODEV; + } + + for (i = 0; i < card->num_links; i++) { + if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) + continue; + + /* populate platform_of_node for snd card dai links */ + if (dai_link[i].platform_name && + !dai_link[i].platform_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-platform-names", + dai_link[i].platform_name); + if (index < 0) { + pr_err("%s: No match found for platform name: %s\n", + __func__, dai_link[i].platform_name); + ret = index; + goto err; + } + np = of_parse_phandle(cdev->of_node, "asoc-platform", + index); + if (!np) { + pr_err("%s: retrieving phandle for platform %s, index %d failed\n", + __func__, dai_link[i].platform_name, + index); + ret = -ENODEV; + goto err; + } + dai_link[i].platform_of_node = np; + dai_link[i].platform_name = NULL; + } + + /* populate cpu_of_node for snd card dai links */ + if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-cpu-names", + dai_link[i].cpu_dai_name); + if (index >= 0) { + np = of_parse_phandle(cdev->of_node, "asoc-cpu", + index); + if (!np) { + pr_err("%s: retrieving phandle for cpu dai %s failed\n", + __func__, + dai_link[i].cpu_dai_name); + ret = -ENODEV; + goto err; + } + dai_link[i].cpu_of_node = np; + dai_link[i].cpu_dai_name = NULL; + } + } + + /* populate codec_of_node for snd card dai links */ + if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-codec-names", + dai_link[i].codec_name); + if (index < 0) + continue; + np = of_parse_phandle(cdev->of_node, "asoc-codec", + index); + if (!np) { + pr_err("%s: retrieving phandle for codec %s failed\n", + __func__, dai_link[i].codec_name); + ret = -ENODEV; + goto err; + } + dai_link[i].codec_of_node = np; + dai_link[i].codec_name = NULL; + } + } + +err: + return ret; +} + +static const struct of_device_id sa6155_asoc_machine_of_match[] = { + { .compatible = "qcom,sa6155-asoc-snd-adp-star", + .data = "adp_star_codec"}, + { .compatible = "qcom,sa6155-asoc-snd-custom", + .data = "custom_codec"}, + {}, +}; + +static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) +{ + struct snd_soc_card *card = NULL; + struct snd_soc_dai_link *dailink; + int len_1, len_2, len_3; + int total_links; + const struct of_device_id *match; + + match = of_match_node(sa6155_asoc_machine_of_match, dev->of_node); + if (!match) { + dev_err(dev, "%s: No DT match found for sound card\n", + __func__); + return NULL; + } + + if (!strcmp(match->data, "adp_star_codec")) { + card = &snd_soc_card_auto_msm; + len_1 = ARRAY_SIZE(msm_common_dai_links); + len_2 = len_1 + ARRAY_SIZE(msm_auto_fe_dai_links); + len_3 = len_2 + ARRAY_SIZE(msm_common_be_dai_links); + total_links = len_3 + ARRAY_SIZE(msm_auto_be_dai_links); + memcpy(msm_auto_dai_links, + msm_common_dai_links, + sizeof(msm_common_dai_links)); + memcpy(msm_auto_dai_links + len_1, + msm_auto_fe_dai_links, + sizeof(msm_auto_fe_dai_links)); + memcpy(msm_auto_dai_links + len_2, + msm_common_be_dai_links, + sizeof(msm_common_be_dai_links)); + memcpy(msm_auto_dai_links + len_3, + msm_auto_be_dai_links, + sizeof(msm_auto_be_dai_links)); + + if (of_property_read_bool(dev->of_node, + "qcom,ext-disp-audio-rx")) { + dev_dbg(dev, "%s(): ext disp audio support present\n", + __func__); + memcpy(msm_auto_dai_links + total_links, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + total_links += ARRAY_SIZE(ext_disp_be_dai_link); + } + if (of_property_read_bool(dev->of_node, + "qcom,mi2s-audio-intf")) { + memcpy(msm_auto_dai_links + total_links, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,auxpcm-audio-intf")) { + memcpy(msm_auto_dai_links + total_links, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + + dailink = msm_auto_dai_links; + } else if (!strcmp(match->data, "custom_codec")) { + card = &snd_soc_card_auto_custom_msm; + len_1 = ARRAY_SIZE(msm_custom_fe_dai_links); + len_2 = len_1 + ARRAY_SIZE(msm_auto_fe_dai_links); + len_3 = len_2 + ARRAY_SIZE(msm_common_be_dai_links); + total_links = len_3 + ARRAY_SIZE(msm_auto_be_dai_links); + memcpy(msm_auto_custom_dai_links, + msm_custom_fe_dai_links, + sizeof(msm_custom_fe_dai_links)); + memcpy(msm_auto_custom_dai_links + len_1, + msm_auto_fe_dai_links, + sizeof(msm_auto_fe_dai_links)); + memcpy(msm_auto_custom_dai_links + len_2, + msm_common_be_dai_links, + sizeof(msm_common_be_dai_links)); + memcpy(msm_auto_custom_dai_links + len_3, + msm_auto_be_dai_links, + sizeof(msm_auto_be_dai_links)); + + if (of_property_read_bool(dev->of_node, + "qcom,ext-disp-audio-rx")) { + dev_dbg(dev, "%s(): ext disp audio support present\n", + __func__); + memcpy(msm_auto_custom_dai_links + total_links, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + total_links += ARRAY_SIZE(ext_disp_be_dai_link); + } + if (of_property_read_bool(dev->of_node, + "qcom,mi2s-audio-intf")) { + memcpy(msm_auto_custom_dai_links + total_links, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + total_links += ARRAY_SIZE(msm_mi2s_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,auxpcm-audio-intf")) { + memcpy(msm_auto_custom_dai_links + total_links, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + dailink = msm_auto_custom_dai_links; + } else { + dev_err(dev, "%s: Codec not supported\n", + __func__); + return NULL; + } + + if (card) { + card->dai_link = dailink; + card->num_links = total_links; + } + + return card; +} + +/***************************************************************************** +* TO BE UPDATED: Codec/Platform specific tdm slot and offset table selection +*****************************************************************************/ +static int msm_tdm_init(struct device *dev) +{ + const struct of_device_id *match; + + match = of_match_node(sa6155_asoc_machine_of_match, dev->of_node); + if (!match) { + dev_err(dev, "%s: No DT match found for sound card\n", + __func__); + return -EINVAL; + } + + if (!strcmp(match->data, "custom_codec")) { + dev_dbg(dev, "%s: custom tdm configuration\n", __func__); + + memcpy(tdm_rx_slot_offset, + tdm_rx_slot_offset_custom, + sizeof(tdm_rx_slot_offset_custom)); + memcpy(tdm_tx_slot_offset, + tdm_tx_slot_offset_custom, + sizeof(tdm_tx_slot_offset_custom)); + memcpy(tdm_slot, + tdm_slot_custom, + sizeof(tdm_slot_custom)); + } else { + dev_dbg(dev, "%s: default tdm configuration\n", __func__); + } + + return 0; +} + +static void msm_i2s_auxpcm_init(struct platform_device *pdev) +{ + int count; + u32 mi2s_master_slave[MI2S_MAX]; + int ret; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_init(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-master", + mi2s_master_slave, MI2S_MAX); + if (ret) { + dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n", + __func__); + } else { + for (count = 0; count < MI2S_MAX; count++) { + mi2s_intf_conf[count].msm_is_mi2s_master = + mi2s_master_slave[count]; + } + } +} + +static void msm_i2s_auxpcm_deinit(void) +{ + int count; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_destroy(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + mi2s_intf_conf[count].msm_is_mi2s_master = 0; + } +} +static int msm_asoc_machine_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card; + struct msm_asoc_mach_data *pdata; + int ret; + enum apr_subsys_state q6_state; + + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, "No platform supplied from device tree\n"); + return -EINVAL; + } + + q6_state = apr_get_q6_state(); + if (q6_state == APR_SUBSYS_DOWN) { + dev_dbg(&pdev->dev, "deferring %s, adsp_state %d\n", + __func__, q6_state); + return -EPROBE_DEFER; + } + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct msm_asoc_mach_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + card = populate_snd_card_dailinks(&pdev->dev); + if (!card) { + dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); + ret = -EINVAL; + goto err; + } + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, pdata); + + ret = snd_soc_of_parse_card_name(card, "qcom,model"); + if (ret) { + dev_err(&pdev->dev, "parse card name failed, err:%d\n", + ret); + goto err; + } + + ret = msm_populate_dai_link_component_of_node(card); + if (ret) { + ret = -EPROBE_DEFER; + goto err; + } + + /* Populate controls of snd card */ + card->controls = msm_snd_controls; + card->num_controls = ARRAY_SIZE(msm_snd_controls); + + ret = msm_tdm_init(&pdev->dev); + if (ret) { + ret = -EPROBE_DEFER; + goto err; + } + + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret == -EPROBE_DEFER) { + goto err; + } else if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); + goto err; + } + dev_info(&pdev->dev, "Sound card %s registered\n", card->name); + + /* Parse pinctrl info from devicetree */ + ret = msm_get_pinctrl(pdev); + if (!ret) { + pr_debug("%s: pinctrl parsing successful\n", __func__); + } else { + dev_dbg(&pdev->dev, + "%s: Parsing pinctrl failed with %d. Cannot use Ports\n", + __func__, ret); + ret = 0; + } + + msm_i2s_auxpcm_init(pdev); + + return 0; +err: + msm_release_pinctrl(pdev); + devm_kfree(&pdev->dev, pdata); + return ret; +} + +static int msm_asoc_machine_remove(struct platform_device *pdev) +{ + msm_i2s_auxpcm_deinit(); + + msm_release_pinctrl(pdev); + return 0; +} + +static struct platform_driver sa6155_asoc_machine_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = sa6155_asoc_machine_of_match, + }, + .probe = msm_asoc_machine_probe, + .remove = msm_asoc_machine_remove, +}; + +static int dummy_asoc_machine_probe(struct platform_device *pdev) +{ + return 0; +} + +static int dummy_asoc_machine_remove(struct platform_device *pdev) +{ + return 0; +} + +static struct platform_device sa6155_dummy_asoc_machine_device = { + .name = "sa6155-asoc-snd-dummy", +}; + +static struct platform_driver sa6155_dummy_asoc_machine_driver = { + .driver = { + .name = "sa6155-asoc-snd-dummy", + .owner = THIS_MODULE, + }, + .probe = dummy_asoc_machine_probe, + .remove = dummy_asoc_machine_remove, +}; + +static int sa6155_notifier_service_cb(struct notifier_block *this, + unsigned long opcode, void *ptr) +{ + pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); + + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (is_initial_boot) { + platform_driver_register(&sa6155_dummy_asoc_machine_driver); + platform_device_register(&sa6155_dummy_asoc_machine_device); + is_initial_boot = false; + } + break; + default: + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block service_nb = { + .notifier_call = sa6155_notifier_service_cb, + .priority = -INT_MAX, +}; + +int __init sa6155_init(void) +{ + pr_debug("%s\n", __func__); + audio_notifier_register("sa6155", AUDIO_NOTIFIER_ADSP_DOMAIN, + &service_nb); + return platform_driver_register(&sa6155_asoc_machine_driver); +} + +void sa6155_exit(void) +{ + pr_debug("%s\n", __func__); + platform_driver_unregister(&sa6155_asoc_machine_driver); + audio_notifier_deregister("sa6155"); +} + +MODULE_DESCRIPTION("ALSA SoC msm"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, sa6155_asoc_machine_of_match); -- GitLab From 85ab414c7b29d92385b293fe4b21e639cdfcf068 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 29 May 2019 15:42:53 +0530 Subject: [PATCH 0999/1645] ASoC: configs: Disable voice_mhi for lito Lito doesn't use voice mhi. Disable required config for the same. Change-Id: Icecac8fc445260542eac7ebc2f0fc64c918c853a Signed-off-by: Vatsal Bucha --- config/litoauto.conf | 1 - config/litoautoconf.h | 1 - 2 files changed, 2 deletions(-) diff --git a/config/litoauto.conf b/config/litoauto.conf index 8d49fb94290a..0bbe4f742e9a 100644 --- a/config/litoauto.conf +++ b/config/litoauto.conf @@ -34,4 +34,3 @@ CONFIG_SND_SOC_WCD938X=m CONFIG_SND_SOC_WCD938X_SLAVE=m CONFIG_SND_SOC_LITO=m CONFIG_SND_EVENT=m -CONFIG_VOICE_MHI=m diff --git a/config/litoautoconf.h b/config/litoautoconf.h index 6467c8f4e2a5..2d19f2dab9ab 100644 --- a/config/litoautoconf.h +++ b/config/litoautoconf.h @@ -38,4 +38,3 @@ #define CONFIG_SND_SOC_WCD938X_SLAVE 1 #define CONFIG_SND_SOC_LITO 1 #define CONFIG_SND_EVENT 1 -#define CONFIG_VOICE_MHI 1 -- GitLab From 4e7401aff9f3697c633e70291ff98db44a2851b6 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 3 Jun 2019 10:34:12 -0700 Subject: [PATCH 1000/1645] soundwire: exit from pm function for LPASS HW Core fails Before proceeding with handling soundwire pm functions check return value of vote for LPASS HW core and handle error scenarios. Change-Id: I4f48c93919a75ebbb072123a12306137118699d0 Signed-off-by: Karthikeyan Mani --- soc/swr-mstr-ctrl.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 45781c76f4ae..23d12c1f04d3 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2282,6 +2282,7 @@ static int swrm_runtime_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); int ret = 0; + bool clk_err = false; struct swr_master *mstr = &swrm->master; struct swr_device *swr_dev; @@ -2295,6 +2296,7 @@ static int swrm_runtime_resume(struct device *dev) dev_err(dev, "%s:lpass core hw enable failed\n", __func__); ret = 0; + clk_err = true; } } @@ -2342,7 +2344,7 @@ static int swrm_runtime_resume(struct device *dev) swrm->state = SWR_MSTR_UP; } exit: - if (swrm->lpass_core_hw_vote) + if (swrm->lpass_core_hw_vote && !clk_err) clk_disable_unprepare(swrm->lpass_core_hw_vote); pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer); mutex_unlock(&swrm->reslock); @@ -2354,6 +2356,7 @@ static int swrm_runtime_suspend(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); int ret = 0; + bool clk_err = false; struct swr_master *mstr = &swrm->master; struct swr_device *swr_dev; int current_state = 0; @@ -2370,6 +2373,7 @@ static int swrm_runtime_suspend(struct device *dev) dev_err(dev, "%s:lpass core hw enable failed\n", __func__); ret = 0; + clk_err = true; } } @@ -2423,7 +2427,7 @@ static int swrm_runtime_suspend(struct device *dev) if (current_state != SWR_MSTR_SSR) swrm->state = SWR_MSTR_DOWN; exit: - if (swrm->lpass_core_hw_vote) + if (swrm->lpass_core_hw_vote && !clk_err) clk_disable_unprepare(swrm->lpass_core_hw_vote); mutex_unlock(&swrm->reslock); return ret; -- GitLab From fcf3cc05fbaadedef19c5fadf5ee16685d6d292e Mon Sep 17 00:00:00 2001 From: Weiyin Jiang Date: Tue, 4 Jun 2019 07:02:29 +0800 Subject: [PATCH 1001/1645] dsp: rtac: use accurate stream id during rtac asm apr call Hard coded stream id fails rtac call for subsequential gapless stream which uses stream id other than default value. To get/set rtac for gapless session successfully, we need to update the stream_id as a part of asm apr header with correct value populated from asm session table. Change-Id: If4afd73b4cf11bf91730a58ae6dff03efb04519d Signed-off-by: Weiyin Jiang --- dsp/q6asm.c | 20 ++++++++++++++++++++ dsp/rtac.c | 12 ++++++++++-- include/dsp/q6asm-v2.h | 1 + 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 66eef6468777..f2c7cfc7d46d 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -10820,6 +10820,26 @@ int q6asm_get_apr_service_id(int session_id) return ((struct apr_svc *)(session[session_id].ac)->apr)->id; } +uint8_t q6asm_get_asm_stream_id(int session_id) +{ + uint8_t stream_id = 1; + pr_debug("%s:\n", __func__); + + if (session_id <= 0 || session_id > ASM_ACTIVE_STREAMS_ALLOWED) { + pr_err("%s: invalid session_id = %d\n", __func__, session_id); + goto done; + } + if (session[session_id].ac == NULL) { + pr_err("%s: session not created for session id = %d\n", + __func__, session_id); + goto done; + } + stream_id = (session[session_id].ac)->stream_id; + +done: + return stream_id; +} + int q6asm_get_asm_topology(int session_id) { int topology = -EINVAL; diff --git a/dsp/rtac.c b/dsp/rtac.c index 37b7e49f9599..7c7137e58cfb 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -985,6 +985,7 @@ int send_rtac_asm_apr(void *buf, u32 opcode) u32 user_buf_size = 0; u32 bytes_returned = 0; u32 session_id = 0; + u8 stream_id = 0; u32 payload_size; u32 data_size = 0; struct apr_hdr asm_params; @@ -1044,6 +1045,13 @@ int send_rtac_asm_apr(void *buf, u32 opcode) goto err; } + stream_id = q6asm_get_asm_stream_id(session_id); + if ((stream_id != 1) && (stream_id != 2)) { + pr_err("%s: Invalid stream id %u\n", __func__, stream_id); + result = -EINVAL; + goto err; + } + switch (opcode) { case ASM_STREAM_CMD_SET_PP_PARAMS_V2: case ASM_STREAM_CMD_SET_PP_PARAMS_V3: @@ -1103,10 +1111,10 @@ int send_rtac_asm_apr(void *buf, u32 opcode) payload_size); asm_params.src_svc = q6asm_get_apr_service_id(session_id); asm_params.src_domain = APR_DOMAIN_APPS; - asm_params.src_port = (session_id << 8) | 0x0001; + asm_params.src_port = (session_id << 8) | stream_id; asm_params.dest_svc = APR_SVC_ASM; asm_params.dest_domain = APR_DOMAIN_ADSP; - asm_params.dest_port = (session_id << 8) | 0x0001; + asm_params.dest_port = (session_id << 8) | stream_id; asm_params.token = session_id; asm_params.opcode = opcode; diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index 1bb44b4a31d1..de7e31b9eebd 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -711,6 +711,7 @@ int q6asm_send_meta_data(struct audio_client *ac, uint32_t initial_samples, int q6asm_stream_send_meta_data(struct audio_client *ac, uint32_t stream_id, uint32_t initial_samples, uint32_t trailing_samples); +uint8_t q6asm_get_asm_stream_id(int session_id); int q6asm_get_asm_topology(int session_id); int q6asm_get_asm_app_type(int session_id); -- GitLab From 3590b312baa2b59d57536719e4a3610f1d1ebbc2 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 4 Jun 2019 23:51:30 +0530 Subject: [PATCH 1002/1645] soc: soundwire: reduce the auto suspend delay to one second Existing delay for soundwire to auto suspend is 3 secs. Reduce the delay to 1 sec to improve the power numbers. Change-Id: I0c13439567eb73b80897f4cf1bbcfb1eded94a9c Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 45781c76f4ae..1cbe1badf984 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -33,7 +33,7 @@ #define SWRM_DSD_PARAMS_PORT 4 #define SWR_BROADCAST_CMD_ID 0x0F -#define SWR_AUTO_SUSPEND_DELAY 3 /* delay in sec */ +#define SWR_AUTO_SUSPEND_DELAY 1 /* delay in sec */ #define SWR_DEV_ID_MASK 0xFFFFFFFFFFFF #define SWR_REG_VAL_PACK(data, dev, id, reg) \ ((reg) | ((id) << 16) | ((dev) << 20) | ((data) << 24)) -- GitLab From bb5e0e9d93a33ed90214c7c5edf9e578d67cecaf Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 5 Jun 2019 15:24:39 +0800 Subject: [PATCH 1003/1645] asoc: kona: Fix to apply wsa8810 gain settings Update wsa aux codec matching logic in machine driver to apply proper gain settings for wsa8810 variant. Add null check for aux component name to avoid dereference. Change-Id: Ie332f8e37a2d6b7a250fe299df91fa9cf9d7636b Signed-off-by: Meng Wang --- asoc/kona.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index be944d3e2ffa..075446e24cce 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -5003,16 +5003,17 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) __func__, rtd->card->num_aux_devs); if (rtd->card->num_aux_devs && !list_empty(&rtd->card->component_dev_list)) { - aux_comp = list_first_entry( - &rtd->card->component_dev_list, - struct snd_soc_component, - card_aux_list); - if (!strcmp(aux_comp->name, WSA8810_NAME_1) || - !strcmp(aux_comp->name, WSA8810_NAME_2)) { - wsa_macro_set_spkr_mode(component, + list_for_each_entry(aux_comp, + &rtd->card->aux_comp_list, + card_aux_list) { + if (aux_comp->name != NULL && ( + !strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2))) { + wsa_macro_set_spkr_mode(component, WSA_MACRO_SPKR_MODE_1); - wsa_macro_set_spkr_gain_offset(component, - WSA_MACRO_GAIN_OFFSET_M1P5_DB); + wsa_macro_set_spkr_gain_offset(component, + WSA_MACRO_GAIN_OFFSET_M1P5_DB); + } } bolero_set_port_map(component, ARRAY_SIZE(sm_port_map), sm_port_map); -- GitLab From 8ef0cc2ed434a33f86567179cfe429f508e071f2 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 8 May 2019 15:12:56 +0800 Subject: [PATCH 1004/1645] asoc: bolero: reset all clks after SSR/PDR After SSR/PDR, the lpass clocks will be in off state. Force restart clocks after SSR/PDR, if enabled before SSR/PDR, to reenable the clocks. Change-Id: I3d850d92bdc6324aa7a64a83a9066f388a85c7f7 Signed-off-by: Meng Wang --- asoc/codecs/bolero/bolero-cdc.c | 11 +++---- asoc/codecs/bolero/bolero-cdc.h | 1 + asoc/codecs/bolero/bolero-clk-rsc.c | 46 +++++++++++++++++++++++++++++ asoc/codecs/bolero/bolero-clk-rsc.h | 6 +++- asoc/codecs/bolero/rx-macro.c | 3 ++ asoc/codecs/bolero/tx-macro.c | 3 ++ asoc/codecs/bolero/va-macro.c | 3 ++ asoc/codecs/bolero/wsa-macro.c | 3 ++ 8 files changed, 70 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index cee08dcdbd57..2a2f7852d0df 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -614,11 +614,12 @@ static int bolero_ssr_enable(struct device *dev, void *data) if (priv->rsc_clk_cb) priv->rsc_clk_cb(priv->clk_dev, BOLERO_MACRO_EVT_SSR_UP); - if (priv->macro_params[VA_MACRO].event_handler) - priv->macro_params[VA_MACRO].event_handler( - priv->component, - BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET, 0x0); - + for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { + if (priv->macro_params[macro_idx].event_handler) + priv->macro_params[macro_idx].event_handler( + priv->component, + BOLERO_MACRO_EVT_CLK_RESET, 0x0); + } regcache_cache_only(priv->regmap, false); mutex_lock(&priv->clk_lock); priv->dev_up = true; diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index e533eb85731c..3bb82b97f2b1 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -38,6 +38,7 @@ enum { BOLERO_MACRO_EVT_SSR_DOWN, BOLERO_MACRO_EVT_SSR_UP, BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET, + BOLERO_MACRO_EVT_CLK_RESET, BOLERO_MACRO_EVT_REG_WAKE_IRQ }; diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c index 82f387926e4f..d325d76adc03 100644 --- a/asoc/codecs/bolero/bolero-clk-rsc.c +++ b/asoc/codecs/bolero/bolero-clk-rsc.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "bolero-cdc.h" #include "bolero-clk-rsc.h" @@ -91,6 +92,51 @@ static char __iomem *bolero_clk_rsc_get_clk_muxsel(struct bolero_clk_rsc *priv, return NULL; } +int bolero_rsc_clk_reset(struct device *dev, int clk_id) +{ + struct device *clk_dev = NULL; + struct bolero_clk_rsc *priv = NULL; + int count = 0; + + if (!dev) { + pr_err("%s: dev is null %d\n", __func__); + return -EINVAL; + } + + if (clk_id < 0 || clk_id >= MAX_CLK - NPL_CLK_OFFSET) { + pr_err("%s: Invalid clk_id: %d\n", + __func__, clk_id); + return -EINVAL; + } + + clk_dev = bolero_get_rsc_clk_device_ptr(dev->parent); + if (!clk_dev) { + pr_err("%s: Invalid rsc clk device\n", __func__); + return -EINVAL; + } + + priv = dev_get_drvdata(clk_dev); + if (!priv) { + pr_err("%s: Invalid rsc clk priviate data\n", __func__); + return -EINVAL; + } + mutex_lock(&priv->rsc_clk_lock); + while (__clk_is_enabled(priv->clk[clk_id])) { + clk_disable_unprepare(priv->clk[clk_id + NPL_CLK_OFFSET]); + clk_disable_unprepare(priv->clk[clk_id]); + count++; + } + dev_dbg(priv->dev, + "%s: clock reset after ssr, count %d\n", __func__, count); + while (count--) { + clk_prepare_enable(priv->clk[clk_id]); + clk_prepare_enable(priv->clk[clk_id + NPL_CLK_OFFSET]); + } + mutex_unlock(&priv->rsc_clk_lock); + return 0; +} +EXPORT_SYMBOL(bolero_rsc_clk_reset); + static int bolero_clk_rsc_mux0_clk_request(struct bolero_clk_rsc *priv, int clk_id, bool enable) diff --git a/asoc/codecs/bolero/bolero-clk-rsc.h b/asoc/codecs/bolero/bolero-clk-rsc.h index b378f73b34d4..fc3c02f602f3 100644 --- a/asoc/codecs/bolero/bolero-clk-rsc.h +++ b/asoc/codecs/bolero/bolero-clk-rsc.h @@ -18,6 +18,7 @@ int bolero_clk_rsc_request_clock(struct device *dev, int default_clk_id, int clk_id_req, bool enable); +int bolero_rsc_clk_reset(struct device *dev, int clk_id); #else static inline void bolero_clk_rsc_fs_gen_request(struct device *dev, bool enable) @@ -37,6 +38,9 @@ static inline int bolero_clk_rsc_request_clock(struct device *dev, { return 0; } - +static inline int bolero_rsc_clk_reset(struct device *dev, int clk_id) +{ + return 0; +} #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CLK_RSC_H */ diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 0be5c4e9a495..8702dba68444 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1241,6 +1241,9 @@ static int rx_macro_event_handler(struct snd_soc_component *component, rx_priv->swr_ctrl_data[0].rx_swr_pdev, SWR_DEVICE_SSR_UP, NULL); break; + case BOLERO_MACRO_EVT_CLK_RESET: + bolero_rsc_clk_reset(rx_dev, RX_CORE_CLK); + break; } return ret; } diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index cb3aa59e4cb1..20606f68beab 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -360,6 +360,9 @@ static int tx_macro_event_handler(struct snd_soc_component *component, tx_priv->swr_ctrl_data[0].tx_swr_pdev, SWR_DEVICE_SSR_UP, NULL); break; + case BOLERO_MACRO_EVT_CLK_RESET: + bolero_rsc_clk_reset(tx_dev, TX_CORE_CLK); + break; } return 0; } diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index ba9c7f12b0d3..a94ca7701203 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -234,6 +234,9 @@ static int va_macro_event_handler(struct snd_soc_component *component, "%s: va_mclk_users is non-zero still, audio SSR fail!!\n", __func__); break; + case BOLERO_MACRO_EVT_CLK_RESET: + bolero_rsc_clk_reset(va_dev, VA_CORE_CLK); + break; default: break; } diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index f41392df4c1e..5b07cbd9915a 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -924,6 +924,9 @@ static int wsa_macro_event_handler(struct snd_soc_component *component, wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, SWR_DEVICE_SSR_UP, NULL); break; + case BOLERO_MACRO_EVT_CLK_RESET: + bolero_rsc_clk_reset(wsa_dev, WSA_CORE_CLK); + break; } return 0; } -- GitLab From c63ec8cd8f6358f48a4fbc6b3a1d1e674ca423ba Mon Sep 17 00:00:00 2001 From: Zhou Song Date: Mon, 3 Jun 2019 19:21:20 +0800 Subject: [PATCH 1005/1645] asoc: dsp: add missing mixer for 'TWS Channel Mode' 'TWS Channel Mode' is missed due to afe_enc_config_controls size changed. Change-Id: Id6a08a7b360364bc94a6786f967ccc191666cefe Signed-off-by: Zhou Song --- asoc/msm-dai-q6-v2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index ed6af11ea718..35ebff4c3152 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -3737,6 +3737,9 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&afe_enc_config_controls[4], dai)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&afe_enc_config_controls[5], + dai)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&avd_drift_config_controls[2], dai)); -- GitLab From 324b4956566ce97bb070fea7e431117e8fe81a52 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 11 Jun 2019 04:14:51 +0530 Subject: [PATCH 1006/1645] ASoC: bolero: Remove unused audio map routings in bolero Remove unused audio map routing from bolero codec to avoid index mismatch for mic path enablement. Change-Id: I09365f54ac5906df9568c78db902000a2dd790eb Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/tx-macro.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index bb3f9c6a26af..4e0d3a7fb63e 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -979,9 +979,9 @@ TX_MACRO_DAPM_ENUM_EXT(tx_dmic7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0, tx_macro_put_dec_enum); static const char * const smic_mux_text[] = { - "ZERO", "ADC0", "ADC1", "ADC2", "ADC3", "ADC4", - "SWR_DMIC0", "SWR_DMIC1", "SWR_DMIC2", "SWR_DMIC3", - "SWR_DMIC4", "SWR_DMIC5", "SWR_DMIC6", "SWR_DMIC7" + "ZERO", "ADC0", "ADC1", "ADC2", "ADC3", "SWR_DMIC0", + "SWR_DMIC1", "SWR_DMIC2", "SWR_DMIC3", "SWR_DMIC4", + "SWR_DMIC5", "SWR_DMIC6", "SWR_DMIC7" }; TX_MACRO_DAPM_ENUM_EXT(tx_smic0, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0, @@ -1125,7 +1125,6 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = { SND_SOC_DAPM_INPUT("TX SWR_ADC1"), SND_SOC_DAPM_INPUT("TX SWR_ADC2"), SND_SOC_DAPM_INPUT("TX SWR_ADC3"), - SND_SOC_DAPM_INPUT("TX SWR_ADC4"), SND_SOC_DAPM_INPUT("TX SWR_DMIC0"), SND_SOC_DAPM_INPUT("TX SWR_DMIC1"), SND_SOC_DAPM_INPUT("TX SWR_DMIC2"), @@ -1245,7 +1244,6 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX0", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX0", "ADC2", "TX SWR_ADC2"}, {"TX SMIC MUX0", "ADC3", "TX SWR_ADC3"}, - {"TX SMIC MUX0", "ADC4", "TX SWR_ADC4"}, {"TX SMIC MUX0", "SWR_DMIC0", "TX SWR_DMIC0"}, {"TX SMIC MUX0", "SWR_DMIC1", "TX SWR_DMIC1"}, {"TX SMIC MUX0", "SWR_DMIC2", "TX SWR_DMIC2"}, @@ -1271,7 +1269,6 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX1", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX1", "ADC2", "TX SWR_ADC2"}, {"TX SMIC MUX1", "ADC3", "TX SWR_ADC3"}, - {"TX SMIC MUX1", "ADC4", "TX SWR_ADC4"}, {"TX SMIC MUX1", "SWR_DMIC0", "TX SWR_DMIC0"}, {"TX SMIC MUX1", "SWR_DMIC1", "TX SWR_DMIC1"}, {"TX SMIC MUX1", "SWR_DMIC2", "TX SWR_DMIC2"}, @@ -1297,7 +1294,6 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX2", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX2", "ADC2", "TX SWR_ADC2"}, {"TX SMIC MUX2", "ADC3", "TX SWR_ADC3"}, - {"TX SMIC MUX2", "ADC4", "TX SWR_ADC4"}, {"TX SMIC MUX2", "SWR_DMIC0", "TX SWR_DMIC0"}, {"TX SMIC MUX2", "SWR_DMIC1", "TX SWR_DMIC1"}, {"TX SMIC MUX2", "SWR_DMIC2", "TX SWR_DMIC2"}, @@ -1323,7 +1319,6 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX3", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX3", "ADC2", "TX SWR_ADC2"}, {"TX SMIC MUX3", "ADC3", "TX SWR_ADC3"}, - {"TX SMIC MUX3", "ADC4", "TX SWR_ADC4"}, {"TX SMIC MUX3", "SWR_DMIC0", "TX SWR_DMIC0"}, {"TX SMIC MUX3", "SWR_DMIC1", "TX SWR_DMIC1"}, {"TX SMIC MUX3", "SWR_DMIC2", "TX SWR_DMIC2"}, @@ -1349,7 +1344,6 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX4", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX4", "ADC2", "TX SWR_ADC2"}, {"TX SMIC MUX4", "ADC3", "TX SWR_ADC3"}, - {"TX SMIC MUX4", "ADC4", "TX SWR_ADC4"}, {"TX SMIC MUX4", "SWR_DMIC0", "TX SWR_DMIC0"}, {"TX SMIC MUX4", "SWR_DMIC1", "TX SWR_DMIC1"}, {"TX SMIC MUX4", "SWR_DMIC2", "TX SWR_DMIC2"}, @@ -1375,7 +1369,6 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX5", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX5", "ADC2", "TX SWR_ADC2"}, {"TX SMIC MUX5", "ADC3", "TX SWR_ADC3"}, - {"TX SMIC MUX5", "ADC4", "TX SWR_ADC4"}, {"TX SMIC MUX5", "SWR_DMIC0", "TX SWR_DMIC0"}, {"TX SMIC MUX5", "SWR_DMIC1", "TX SWR_DMIC1"}, {"TX SMIC MUX5", "SWR_DMIC2", "TX SWR_DMIC2"}, @@ -1401,7 +1394,6 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX6", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX6", "ADC2", "TX SWR_ADC2"}, {"TX SMIC MUX6", "ADC3", "TX SWR_ADC3"}, - {"TX SMIC MUX6", "ADC4", "TX SWR_ADC4"}, {"TX SMIC MUX6", "SWR_DMIC0", "TX SWR_DMIC0"}, {"TX SMIC MUX6", "SWR_DMIC1", "TX SWR_DMIC1"}, {"TX SMIC MUX6", "SWR_DMIC2", "TX SWR_DMIC2"}, @@ -1427,7 +1419,6 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX7", "ADC1", "TX SWR_ADC1"}, {"TX SMIC MUX7", "ADC2", "TX SWR_ADC2"}, {"TX SMIC MUX7", "ADC3", "TX SWR_ADC3"}, - {"TX SMIC MUX7", "ADC4", "TX SWR_ADC4"}, {"TX SMIC MUX7", "SWR_DMIC0", "TX SWR_DMIC0"}, {"TX SMIC MUX7", "SWR_DMIC1", "TX SWR_DMIC1"}, {"TX SMIC MUX7", "SWR_DMIC2", "TX SWR_DMIC2"}, @@ -1764,7 +1755,6 @@ static int tx_macro_init(struct snd_soc_component *component) snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC1"); snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC2"); snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC3"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC4"); snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC0"); snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC1"); snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC2"); -- GitLab From 776bf8e63e04f2e3d10ac8831420ab0ddcd83985 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 11 Jun 2019 04:20:41 +0530 Subject: [PATCH 1007/1645] ASoC: wcd938x: Update DMIC enable sequence on WCD938x Update DMIC enable sequence on WCD938x codec to support audio capture on WCD DMICs. Change-Id: I432bbc3a89ad6cbf968fa6474b9bbeb4924e2791 Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd938x/wcd938x.c | 74 ++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 4ded2d2de04d..604d12d16a8b 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -961,49 +961,51 @@ static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); - u16 dmic_clk_reg; + u16 dmic_clk_reg, dmic_clk_en_reg; s32 *dmic_clk_cnt; - unsigned int dmic; - char *wname; - int ret = 0; - - wname = strpbrk(w->name, "012345"); - - if (!wname) { - dev_err(component->dev, "%s: widget not found\n", __func__); - return -EINVAL; - } - - ret = kstrtouint(wname, 10, &dmic); - if (ret < 0) { - dev_err(component->dev, "%s: Invalid DMIC line on the codec\n", - __func__); - return -EINVAL; - } + u8 dmic_ctl_shift = 0; + u8 dmic_clk_shift = 0; + u8 dmic_clk_mask = 0; dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); - switch (dmic) { + switch (w->shift) { case 0: case 1: dmic_clk_cnt = &(wcd938x->dmic_0_1_clk_cnt); - dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC1_CTL; + dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_1_2; + dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC1_CTL; + dmic_clk_mask = 0x0F; + dmic_clk_shift = 0x00; + dmic_ctl_shift = 0x00; break; case 2: case 3: dmic_clk_cnt = &(wcd938x->dmic_2_3_clk_cnt); - dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC2_CTL; + dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_1_2; + dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC2_CTL; + dmic_clk_mask = 0xF0; + dmic_clk_shift = 0x04; + dmic_ctl_shift = 0x01; break; case 4: case 5: dmic_clk_cnt = &(wcd938x->dmic_4_5_clk_cnt); - dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC3_CTL; + dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_3_4; + dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC3_CTL; + dmic_clk_mask = 0x0F; + dmic_clk_shift = 0x00; + dmic_ctl_shift = 0x02; break; case 6: case 7: dmic_clk_cnt = &(wcd938x->dmic_6_7_clk_cnt); - dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC4_CTL; + dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_3_4; + dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC4_CTL; + dmic_clk_mask = 0xF0; + dmic_clk_shift = 0x04; + dmic_ctl_shift = 0x03; break; default: dev_err(component->dev, "%s: Invalid DMIC Selection\n", @@ -1011,27 +1013,35 @@ static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w, return -EINVAL; }; dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", - __func__, event, dmic, *dmic_clk_cnt); + __func__, event, (w->shift +1), *dmic_clk_cnt); switch (event) { case SND_SOC_DAPM_PRE_PMU: snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x80); - /* enable clock scaling */ + WCD938X_DIGITAL_CDC_AMIC_CTL, + (0x01 << dmic_ctl_shift), 0x00); + /* 250us sleep as per HW requirement */ + usleep_range(250, 260); + /* Setting DMIC clock rate to 2.4MHz */ snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_DMIC_CTL, 0x06, 0x06); + dmic_clk_reg, dmic_clk_mask, + (0x03 << dmic_clk_shift)); snd_soc_component_update_bits(component, - dmic_clk_reg, 0x07, 0x02); - snd_soc_component_update_bits(component, - dmic_clk_reg, 0x08, 0x08); + dmic_clk_en_reg, 0x08, 0x08); + /* enable clock scaling */ snd_soc_component_update_bits(component, - dmic_clk_reg, 0x70, 0x20); + WCD938X_DIGITAL_CDC_DMIC_CTL, 0x06, 0x06); wcd938x_tx_connect_port(component, DMIC0 + (w->shift), true); break; case SND_SOC_DAPM_POST_PMD: wcd938x_tx_connect_port(component, DMIC0 + (w->shift), false); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_AMIC_CTL, + (0x01 << dmic_ctl_shift), + (0x01 << dmic_ctl_shift)); + snd_soc_component_update_bits(component, + dmic_clk_en_reg, 0x08, 0x00); break; - }; return 0; } -- GitLab From 3bd80a59b2e4ef10a1638a9b6f57b232a6136b7a Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 4 Jun 2019 23:40:16 -0700 Subject: [PATCH 1008/1645] asoc: codecs: add support to disable soundwire devices Add changes to support disabling of soundwire devices so that soundwire pins can be freed for other purposes if needed. Change-Id: Iae14d43c2c3d5380347be4c3b443c209b2612a97 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/rx-macro.c | 57 ++++++++++++++++++++---------- asoc/codecs/bolero/tx-macro.c | 53 +++++++++++++++++++--------- asoc/codecs/bolero/wsa-macro.c | 64 ++++++++++++++++++++++------------ 3 files changed, 116 insertions(+), 58 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 0be5c4e9a495..bcb7c6b4dd37 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -764,9 +764,10 @@ static int rx_macro_set_port_map(struct snd_soc_component *component, port_cfg.size = size; port_cfg.params = data; - ret = swrm_wcd_notify( - rx_priv->swr_ctrl_data[0].rx_swr_pdev, - SWR_SET_PORT_MAP, &port_cfg); + if (rx_priv->swr_ctrl_data) + ret = swrm_wcd_notify( + rx_priv->swr_ctrl_data[0].rx_swr_pdev, + SWR_SET_PORT_MAP, &port_cfg); return ret; } @@ -1152,16 +1153,18 @@ static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w, rx_priv->is_native_on) || (rx_priv->clk_id == RX_CORE_CLK && !rx_priv->is_native_on)) { - swrm_wcd_notify( - rx_priv->swr_ctrl_data[0].rx_swr_pdev, - SWR_DEVICE_DOWN, NULL); + if (rx_priv->swr_ctrl_data) + swrm_wcd_notify( + rx_priv->swr_ctrl_data[0].rx_swr_pdev, + SWR_DEVICE_DOWN, NULL); } } if (rx_priv->is_native_on) mclk_freq = MCLK_FREQ_NATIVE; - swrm_wcd_notify( - rx_priv->swr_ctrl_data[0].rx_swr_pdev, - SWR_CLK_FREQ, &mclk_freq); + if (rx_priv->swr_ctrl_data) + swrm_wcd_notify( + rx_priv->swr_ctrl_data[0].rx_swr_pdev, + SWR_CLK_FREQ, &mclk_freq); ret = rx_macro_mclk_enable(rx_priv, 1, true); if (ret) rx_priv->dapm_mclk_enable = false; @@ -1213,12 +1216,14 @@ static int rx_macro_event_handler(struct snd_soc_component *component, break; case BOLERO_MACRO_EVT_SSR_DOWN: rx_priv->dev_up = false; - swrm_wcd_notify( - rx_priv->swr_ctrl_data[0].rx_swr_pdev, - SWR_DEVICE_DOWN, NULL); - swrm_wcd_notify( - rx_priv->swr_ctrl_data[0].rx_swr_pdev, - SWR_DEVICE_SSR_DOWN, NULL); + if (rx_priv->swr_ctrl_data) { + swrm_wcd_notify( + rx_priv->swr_ctrl_data[0].rx_swr_pdev, + SWR_DEVICE_DOWN, NULL); + swrm_wcd_notify( + rx_priv->swr_ctrl_data[0].rx_swr_pdev, + SWR_DEVICE_SSR_DOWN, NULL); + } break; case BOLERO_MACRO_EVT_SSR_UP: rx_priv->dev_up = true; @@ -1237,9 +1242,10 @@ static int rx_macro_event_handler(struct snd_soc_component *component, rx_priv->default_clk_id, RX_CORE_CLK, false); - swrm_wcd_notify( - rx_priv->swr_ctrl_data[0].rx_swr_pdev, - SWR_DEVICE_SSR_UP, NULL); + if (rx_priv->swr_ctrl_data) + swrm_wcd_notify( + rx_priv->swr_ctrl_data[0].rx_swr_pdev, + SWR_DEVICE_SSR_UP, NULL); break; } return ret; @@ -3570,6 +3576,8 @@ static int rx_macro_probe(struct platform_device *pdev) int ret = 0; u8 bcl_pmic_params[3]; u32 default_clk_id = 0; + u32 is_used_rx_swr_gpio = 1; + const char *is_used_rx_swr_gpio_dt = "qcom,is-used-swr-gpio"; rx_priv = devm_kzalloc(&pdev->dev, sizeof(struct rx_macro_priv), GFP_KERNEL); @@ -3598,9 +3606,20 @@ static int rx_macro_probe(struct platform_device *pdev) __func__, "qcom,default-clk-id"); default_clk_id = RX_CORE_CLK; } + if (of_find_property(pdev->dev.of_node, is_used_rx_swr_gpio_dt, + NULL)) { + ret = of_property_read_u32(pdev->dev.of_node, + is_used_rx_swr_gpio_dt, + &is_used_rx_swr_gpio); + if (ret) { + dev_err(&pdev->dev, "%s: error reading %s in dt\n", + __func__, is_used_rx_swr_gpio_dt); + is_used_rx_swr_gpio = 1; + } + } rx_priv->rx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,rx-swr-gpios", 0); - if (!rx_priv->rx_swr_gpio_p) { + if (!rx_priv->rx_swr_gpio_p && is_used_rx_swr_gpio) { dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n", __func__); return -EINVAL; diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index cb3aa59e4cb1..63e900e660ce 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -346,19 +346,22 @@ static int tx_macro_event_handler(struct snd_soc_component *component, switch (event) { case BOLERO_MACRO_EVT_SSR_DOWN: - swrm_wcd_notify( - tx_priv->swr_ctrl_data[0].tx_swr_pdev, - SWR_DEVICE_DOWN, NULL); - swrm_wcd_notify( - tx_priv->swr_ctrl_data[0].tx_swr_pdev, - SWR_DEVICE_SSR_DOWN, NULL); + if (tx_priv->swr_ctrl_data) { + swrm_wcd_notify( + tx_priv->swr_ctrl_data[0].tx_swr_pdev, + SWR_DEVICE_DOWN, NULL); + swrm_wcd_notify( + tx_priv->swr_ctrl_data[0].tx_swr_pdev, + SWR_DEVICE_SSR_DOWN, NULL); + } break; case BOLERO_MACRO_EVT_SSR_UP: /* reset swr after ssr/pdr */ tx_priv->reset_swr = true; - swrm_wcd_notify( - tx_priv->swr_ctrl_data[0].tx_swr_pdev, - SWR_DEVICE_SSR_UP, NULL); + if (tx_priv->swr_ctrl_data) + swrm_wcd_notify( + tx_priv->swr_ctrl_data[0].tx_swr_pdev, + SWR_DEVICE_SSR_UP, NULL); break; } return 0; @@ -375,9 +378,10 @@ static int tx_macro_reg_wake_irq(struct snd_soc_component *component, if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; - ret = swrm_wcd_notify( - tx_priv->swr_ctrl_data[0].tx_swr_pdev, - SWR_REGISTER_WAKE_IRQ, &ipc_wakeup); + if (tx_priv->swr_ctrl_data) + ret = swrm_wcd_notify( + tx_priv->swr_ctrl_data[0].tx_swr_pdev, + SWR_REGISTER_WAKE_IRQ, &ipc_wakeup); return ret; } @@ -1948,9 +1952,10 @@ static int tx_macro_set_port_map(struct snd_soc_component *component, port_cfg.size = size; port_cfg.params = data; - ret = swrm_wcd_notify( - tx_priv->swr_ctrl_data[0].tx_swr_pdev, - SWR_SET_PORT_MAP, &port_cfg); + if (tx_priv->swr_ctrl_data) + ret = swrm_wcd_notify( + tx_priv->swr_ctrl_data[0].tx_swr_pdev, + SWR_SET_PORT_MAP, &port_cfg); return ret; } @@ -1977,6 +1982,8 @@ static int tx_macro_probe(struct platform_device *pdev) char __iomem *tx_io_base = NULL; int ret = 0; const char *dmic_sample_rate = "qcom,tx-dmic-sample-rate"; + u32 is_used_tx_swr_gpio = 1; + const char *is_used_tx_swr_gpio_dt = "qcom,is-used-swr-gpio"; tx_priv = devm_kzalloc(&pdev->dev, sizeof(struct tx_macro_priv), GFP_KERNEL); @@ -1993,9 +2000,20 @@ static int tx_macro_probe(struct platform_device *pdev) return ret; } dev_set_drvdata(&pdev->dev, tx_priv); + if (of_find_property(pdev->dev.of_node, is_used_tx_swr_gpio_dt, + NULL)) { + ret = of_property_read_u32(pdev->dev.of_node, + is_used_tx_swr_gpio_dt, + &is_used_tx_swr_gpio); + if (ret) { + dev_err(&pdev->dev, "%s: error reading %s in dt\n", + __func__, is_used_tx_swr_gpio_dt); + is_used_tx_swr_gpio = 1; + } + } tx_priv->tx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,tx-swr-gpios", 0); - if (!tx_priv->tx_swr_gpio_p) { + if (!tx_priv->tx_swr_gpio_p && is_used_tx_swr_gpio) { dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n", __func__); return -EINVAL; @@ -2064,7 +2082,8 @@ static int tx_macro_remove(struct platform_device *pdev) if (!tx_priv) return -EINVAL; - kfree(tx_priv->swr_ctrl_data); + if (tx_priv->swr_ctrl_data) + kfree(tx_priv->swr_ctrl_data); for (count = 0; count < tx_priv->child_count && count < TX_MACRO_CHILD_DEVICES_MAX; count++) platform_device_unregister(tx_priv->pdev_child_devices[count]); diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index f41392df4c1e..08e2960bca1e 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -473,9 +473,10 @@ static int wsa_macro_set_port_map(struct snd_soc_component *component, port_cfg.size = size; port_cfg.params = data; - ret = swrm_wcd_notify( - wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, - SWR_SET_PORT_MAP, &port_cfg); + if (wsa_priv->swr_ctrl_data) + ret = swrm_wcd_notify( + wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, + SWR_SET_PORT_MAP, &port_cfg); return ret; } @@ -910,19 +911,22 @@ static int wsa_macro_event_handler(struct snd_soc_component *component, switch (event) { case BOLERO_MACRO_EVT_SSR_DOWN: - swrm_wcd_notify( - wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, - SWR_DEVICE_DOWN, NULL); - swrm_wcd_notify( - wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, - SWR_DEVICE_SSR_DOWN, NULL); + if (wsa_priv->swr_ctrl_data) { + swrm_wcd_notify( + wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, + SWR_DEVICE_DOWN, NULL); + swrm_wcd_notify( + wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, + SWR_DEVICE_SSR_DOWN, NULL); + } break; case BOLERO_MACRO_EVT_SSR_UP: /* reset swr after ssr/pdr */ wsa_priv->reset_swr = true; - swrm_wcd_notify( - wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, - SWR_DEVICE_SSR_UP, NULL); + if (wsa_priv->swr_ctrl_data) + swrm_wcd_notify( + wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, + SWR_DEVICE_SSR_UP, NULL); break; } return 0; @@ -1135,12 +1139,14 @@ static int wsa_macro_enable_swr(struct snd_soc_dapm_widget *w, wsa_priv->rx_1_count++; ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count; - swrm_wcd_notify( - wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, - SWR_DEVICE_UP, NULL); - swrm_wcd_notify( - wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, - SWR_SET_NUM_RX_CH, &ch_cnt); + if (wsa_priv->swr_ctrl_data) { + swrm_wcd_notify( + wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, + SWR_DEVICE_UP, NULL); + swrm_wcd_notify( + wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, + SWR_SET_NUM_RX_CH, &ch_cnt); + } break; case SND_SOC_DAPM_POST_PMD: if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) && @@ -1151,9 +1157,10 @@ static int wsa_macro_enable_swr(struct snd_soc_dapm_widget *w, wsa_priv->rx_1_count--; ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count; - swrm_wcd_notify( - wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, - SWR_SET_NUM_RX_CH, &ch_cnt); + if (wsa_priv->swr_ctrl_data) + swrm_wcd_notify( + wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, + SWR_SET_NUM_RX_CH, &ch_cnt); break; } dev_dbg(wsa_priv->dev, "%s: current swr ch cnt: %d\n", @@ -2880,6 +2887,8 @@ static int wsa_macro_probe(struct platform_device *pdev) char __iomem *wsa_io_base; int ret = 0; u8 bcl_pmic_params[3]; + u32 is_used_wsa_swr_gpio = 1; + const char *is_used_wsa_swr_gpio_dt = "qcom,is-used-swr-gpio"; wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv), GFP_KERNEL); @@ -2894,9 +2903,20 @@ static int wsa_macro_probe(struct platform_device *pdev) __func__, "reg"); return ret; } + if (of_find_property(pdev->dev.of_node, is_used_wsa_swr_gpio_dt, + NULL)) { + ret = of_property_read_u32(pdev->dev.of_node, + is_used_wsa_swr_gpio_dt, + &is_used_wsa_swr_gpio); + if (ret) { + dev_err(&pdev->dev, "%s: error reading %s in dt\n", + __func__, is_used_wsa_swr_gpio_dt); + is_used_wsa_swr_gpio = 1; + } + } wsa_priv->wsa_swr_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,wsa-swr-gpios", 0); - if (!wsa_priv->wsa_swr_gpio_p) { + if (!wsa_priv->wsa_swr_gpio_p && is_used_wsa_swr_gpio) { dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n", __func__); return -EINVAL; -- GitLab From 8db822a26111e41a079b4d5e9d7642fe2e3f6095 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 11 Jun 2019 10:46:48 +0800 Subject: [PATCH 1009/1645] asoc: bolero: remove extra semi-colon to avoid compile error Remove extra semi-colon from wsa_macro_set_spkr_gain_offset to avoid compile error when wsa-macro is disabled. Change-Id: Ic94e78822639d70a365c714ad7dd0b2091de8179 Signed-off-by: Meng Wang --- asoc/codecs/bolero/wsa-macro.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/wsa-macro.h b/asoc/codecs/bolero/wsa-macro.h index a4dc77f8f87a..fa5147631a44 100644 --- a/asoc/codecs/bolero/wsa-macro.h +++ b/asoc/codecs/bolero/wsa-macro.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #ifndef WSA_MACRO_H #define WSA_MACRO_H @@ -33,7 +33,7 @@ static inline int wsa_macro_set_spkr_mode(struct snd_soc_component *component, } static inline int wsa_macro_set_spkr_gain_offset( struct snd_soc_component *component, - int offset); + int offset) { return 0; } -- GitLab From a8f9dc90d8a1d864f761df39cb66e3b4da5074f9 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 18 Apr 2019 16:43:08 +0530 Subject: [PATCH 1010/1645] ASoC: mbhc: Fix left channel getting disabled in hs_rem_irq In wcd_mbhc_adc_hs_rem_irq when hph_on bit is set both left and right channel should get enabled. But we enable left channel first, disable left ch and enable right channel. Fix this to enable both left and right channel. Change-Id: Ia50c55a0ed68e01359ef0a9c76eba6901a04e17c Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd-mbhc-adc.c | 5 +---- asoc/codecs/wcd-mbhc-legacy.c | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index 4a2c928a90a5..4de19de467c1 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -987,8 +987,6 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) if (mbhc->mbhc_cb->hph_pa_on_status) if (mbhc->mbhc_cb->hph_pa_on_status(mbhc->component)) { hphpa_on = true; - WCD_MBHC_REG_UPDATE_BITS( - WCD_MBHC_HPHL_PA_EN, 0); WCD_MBHC_REG_UPDATE_BITS( WCD_MBHC_HPH_PA_EN, 0); } @@ -1033,8 +1031,7 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) if (hphpa_on) { hphpa_on = false; - WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_PA_EN, 1); - WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPH_PA_EN, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPH_PA_EN, 3); } } exit: diff --git a/asoc/codecs/wcd-mbhc-legacy.c b/asoc/codecs/wcd-mbhc-legacy.c index b266da699bc2..49884ebd89bd 100644 --- a/asoc/codecs/wcd-mbhc-legacy.c +++ b/asoc/codecs/wcd-mbhc-legacy.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, 2019, The Linux Foundation. All rights reserved. */ #include #include @@ -916,7 +916,7 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) if (hphpa_on) { hphpa_on = false; WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_PA_EN, 1); - WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPH_PA_EN, 1); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHR_PA_EN, 1); } hphl_trigerred = 0; mic_trigerred = 0; -- GitLab From 7f609a3ca0638a546a9f6548e94d8fa60f177091 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 17 May 2019 16:59:53 -0700 Subject: [PATCH 1011/1645] asoc: codecs: Add support for class ab low power modes Add codec enable and disable sequences for class ab low power modes. Change-Id: If5b54075985c2d4d1a24423c03e78bee119862bc Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd-clsh.c | 12 +++++++++--- include/asoc/wcd-clsh.h | 4 +++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/wcd-clsh.c b/asoc/codecs/wcd-clsh.c index 0f403ac7a7e5..bda389381101 100644 --- a/asoc/codecs/wcd-clsh.c +++ b/asoc/codecs/wcd-clsh.c @@ -34,6 +34,10 @@ static const char *mode_to_str(int mode) return WCD_CLSH_STRINGIFY(CLS_AB); case CLS_AB_HIFI: return WCD_CLSH_STRINGIFY(CLS_AB_HIFI); + case CLS_AB_LP: + return WCD_CLSH_STRINGIFY(CLS_AB_LP); + case CLS_AB_LOHIFI: + return WCD_CLSH_STRINGIFY(CLS_AB_LOHIFI); default: return WCD_CLSH_STRINGIFY(CLS_H_INVALID); }; @@ -107,7 +111,7 @@ static inline void wcd_clsh_set_buck_mode(struct snd_soc_component *component, int mode) { if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || - mode == CLS_AB_HIFI) + mode == CLS_AB_HIFI || mode == CLS_AB_LOHIFI) snd_soc_component_update_bits(component, WCD9XXX_ANA_RX_SUPPLIES, 0x08, 0x08); /* set to HIFI */ @@ -122,7 +126,7 @@ static inline void wcd_clsh_set_flyback_mode( int mode) { if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI || - mode == CLS_AB_HIFI) { + mode == CLS_AB_HIFI || mode == CLS_AB_LOHIFI) { snd_soc_component_update_bits(component, WCD9XXX_ANA_RX_SUPPLIES, 0x04, 0x04); @@ -154,7 +158,7 @@ static inline void wcd_clsh_force_iq_ctl(struct snd_soc_component *component, snd_soc_component_update_bits(component, WCD9XXX_CLASSH_MODE_2, 0xFF, 0x1C); - if (mode == CLS_H_LOHIFI) { + if (mode == CLS_H_LOHIFI || mode == CLS_AB_LOHIFI) { snd_soc_component_update_bits(component, WCD9XXX_HPH_NEW_INT_PA_MISC2, 0x20, 0x20); @@ -258,6 +262,8 @@ static void wcd_clsh_set_hph_mode(struct snd_soc_component *component, break; case CLS_H_LP: case CLS_H_LOHIFI: + case CLS_AB_LP: + case CLS_AB_LOHIFI: val = 0x04; break; default: diff --git a/include/asoc/wcd-clsh.h b/include/asoc/wcd-clsh.h index 64250e1b6323..c8e49fd0b904 100644 --- a/include/asoc/wcd-clsh.h +++ b/include/asoc/wcd-clsh.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #ifndef _WCD_CLSH @@ -62,6 +62,8 @@ enum { CLS_H_LOHIFI, /* LoHIFI */ CLS_H_ULP, /* Ultra Low power */ CLS_AB_HIFI, /* Class-AB */ + CLS_AB_LP, /* Class-AB Low Power */ + CLS_AB_LOHIFI, /* Class-AB Low HIFI */ CLS_NONE, /* None of the above modes */ }; -- GitLab From 31231c306d5a5c3f8e873834c229163f159fea6a Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 16 May 2019 15:57:53 -0700 Subject: [PATCH 1012/1645] ASoC: codecs: update for AUX, ear and HPH paths Add updates to AUX control registers and headphone and ear path power mode registers. Change-Id: I7a6b0f23a28a6ab9189c946a78a2f376937d7509 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/internal.h | 1 + asoc/codecs/wcd938x/wcd938x.c | 51 ++++++++++++++++++++++++++-------- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index e1fea5c41a4a..99d8575fe29f 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -94,6 +94,7 @@ struct wcd938x_priv { /* Entry for version info */ struct snd_info_entry *entry; struct snd_info_entry *version_entry; + int flyback_cur_det_disable; }; struct wcd938x_micbias_setting { diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index bf285052f7df..ee5079b224d3 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -166,6 +166,12 @@ static int wcd938x_init_reg(struct snd_soc_component *component) 0xC0, 0x80); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_DMIC_CTL, 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_ULP, + 0xFF, 0x14); + snd_soc_component_update_bits(component, + WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_ULP, + 0x1F, 0x08); return 0; } @@ -364,6 +370,8 @@ static int wcd938x_rx_clk_enable(struct snd_soc_component *component) WCD938X_DIGITAL_CDC_RX2_CTL, 0x40, 0x00); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD938X_AUX_AUXPA, 0x10, 0x10); } wcd938x->rx_clk_cnt++; @@ -539,8 +547,11 @@ static int wcd938x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, WCD938X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x02); /* 5 msec delay as per HW requirement */ usleep_range(5000, 5010); - snd_soc_component_update_bits(component, WCD938X_FLYBACK_EN, - 0x04, 0x00); + if (wcd938x->flyback_cur_det_disable == 0) + snd_soc_component_update_bits(component, + WCD938X_FLYBACK_EN, + 0x04, 0x00); + wcd938x->flyback_cur_det_disable++; wcd_cls_h_fsm(component, &wcd938x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_EAR, @@ -573,13 +584,17 @@ static int wcd938x_codec_aux_dac_event(struct snd_soc_dapm_widget *w, WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x04, 0x04); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_AUX_GAIN_CTL, 0x01, 0x01); + if (wcd938x->flyback_cur_det_disable == 0) + snd_soc_component_update_bits(component, + WCD938X_FLYBACK_EN, + 0x04, 0x00); + wcd938x->flyback_cur_det_disable++; wcd_cls_h_fsm(component, &wcd938x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_AUX, wcd938x->hph_mode); break; case SND_SOC_DAPM_POST_PMD: - wcd938x_rx_clk_disable(component); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x04, 0x00); break; @@ -630,7 +645,8 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, } snd_soc_component_update_bits(component, WCD938X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02); - if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) + if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI || + hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI) snd_soc_component_update_bits(component, WCD938X_ANA_RX_SUPPLIES, 0x02, 0x02); if (wcd938x->update_wcd_event) @@ -706,7 +722,8 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, } snd_soc_component_update_bits(component, WCD938X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02); - if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) + if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI || + hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI) snd_soc_component_update_bits(component, WCD938X_ANA_RX_SUPPLIES, 0x02, 0x02); if (wcd938x->update_wcd_event) @@ -762,10 +779,11 @@ static int wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: /* 1 msec delay as per HW requirement */ usleep_range(1000, 1010); - if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) + if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI || + hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI) snd_soc_component_update_bits(component, WCD938X_ANA_RX_SUPPLIES, - 0x20, 0x20); + 0x02, 0x02); if (wcd938x->update_wcd_event) wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -784,6 +802,12 @@ static int wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_AUX, hph_mode); + + wcd938x->flyback_cur_det_disable--; + if (wcd938x->flyback_cur_det_disable == 0) + snd_soc_component_update_bits(component, + WCD938X_FLYBACK_EN, + 0x04, 0x04); break; }; return ret; @@ -811,7 +835,8 @@ static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: /* 6 msec delay as per HW requirement */ usleep_range(6000, 6010); - if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) + if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI || + hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI) snd_soc_component_update_bits(component, WCD938X_ANA_RX_SUPPLIES, 0x02, 0x02); @@ -833,8 +858,12 @@ static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_EAR, hph_mode); - snd_soc_component_update_bits(component, WCD938X_FLYBACK_EN, - 0x04, 0x04); + + wcd938x->flyback_cur_det_disable--; + if (wcd938x->flyback_cur_det_disable == 0) + snd_soc_component_update_bits(component, + WCD938X_FLYBACK_EN, + 0x04, 0x04); break; }; return ret; @@ -1796,7 +1825,7 @@ static const struct soc_enum tx_mode_mux_enum = static const char * const rx_hph_mode_mux_text[] = { "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI", - "CLS_H_ULP", "CLS_AB_HIFI", + "CLS_H_ULP", "CLS_AB_HIFI", "CLS_AB_LP", "CLS_AB_LOHIFI", }; static const struct soc_enum rx_hph_mode_mux_enum = -- GitLab From 17bea6ec6fc040a666a71d776ca5507e3f38a5ef Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 15 May 2019 15:14:51 -0700 Subject: [PATCH 1013/1645] asoc: wcd938x: Enable watchdog interrupt Handle PDM watchdog interrupt. Enable watchdog before analog PA is enabled and disable it after analog PA is disabled so as to prevent false alarms. Change-Id: Id45dee1a150c471d1bb29b9bfed9f416b8454a5f Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/internal.h | 1 + asoc/codecs/wcd938x/wcd938x.c | 55 ++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index 99d8575fe29f..87bea0431860 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -95,6 +95,7 @@ struct wcd938x_priv { struct snd_info_entry *entry; struct snd_info_entry *version_entry; int flyback_cur_det_disable; + int ear_rx_path; }; struct wcd938x_micbias_setting { diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index ee5079b224d3..0a3bfab5959e 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -29,6 +29,7 @@ #define WCD938X_VERSION_1_0 1 #define WCD938X_VERSION_ENTRY_SIZE 32 +#define EAR_RX_PATH_AUX 1 #define ADC_MODE_VAL_HIFI 0x01 #define ADC_MODE_VAL_LO_HIF 0x02 @@ -629,6 +630,8 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, /* 100 usec delay as per HW requirement */ usleep_range(100, 110); set_bit(HPH_PA_DELAY, &wcd938x->status_mask); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_PDM_WD_CTL1, 0x17, 0x13); break; case SND_SOC_DAPM_POST_PMU: /* @@ -666,6 +669,8 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMD: /* 7 msec delay as per HW requirement */ usleep_range(7000, 7010); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_PDM_WD_CTL1, 0x17, 0x00); blocking_notifier_call_chain(&wcd938x->mbhc->notifier, WCD_EVENT_POST_HPHR_PA_OFF, &wcd938x->mbhc->wcd_mbhc); @@ -706,6 +711,8 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, /* 100 usec delay as per HW requirement */ usleep_range(100, 110); set_bit(HPH_PA_DELAY, &wcd938x->status_mask); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_PDM_WD_CTL0, 0x17, 0x13); break; case SND_SOC_DAPM_POST_PMU: /* @@ -743,6 +750,8 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMD: /* 7 msec delay as per HW requirement */ usleep_range(7000, 7010); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_PDM_WD_CTL0, 0x17, 0x00); blocking_notifier_call_chain(&wcd938x->mbhc->notifier, WCD_EVENT_POST_HPHL_PA_OFF, &wcd938x->mbhc->wcd_mbhc); @@ -775,6 +784,8 @@ static int wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, ret = swr_slvdev_datapath_control(wcd938x->rx_swr_dev, wcd938x->rx_swr_dev->dev_num, true); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_PDM_WD_CTL2, 0x05, 0x05); break; case SND_SOC_DAPM_POST_PMU: /* 1 msec delay as per HW requirement */ @@ -798,6 +809,8 @@ static int wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMD: /* 1 msec delay as per HW requirement */ usleep_range(1000, 1010); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_PDM_WD_CTL2, 0x05, 0x00); wcd_cls_h_fsm(component, &wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_AUX, @@ -831,6 +844,21 @@ static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, ret = swr_slvdev_datapath_control(wcd938x->rx_swr_dev, wcd938x->rx_swr_dev->dev_num, true); + /* + * Enable watchdog interrupt for HPHL or AUX + * depending on mux value + */ + wcd938x->ear_rx_path = + snd_soc_component_read32( + component, WCD938X_DIGITAL_CDC_EAR_PATH_CTL); + if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_PDM_WD_CTL2, + 0x05, 0x05); + else + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_PDM_WD_CTL0, + 0x17, 0x13); break; case SND_SOC_DAPM_POST_PMU: /* 6 msec delay as per HW requirement */ @@ -854,6 +882,14 @@ static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMD: /* 7 msec delay as per HW requirement */ usleep_range(7000, 7010); + if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_PDM_WD_CTL2, + 0x05, 0x00); + else + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_PDM_WD_CTL0, + 0x17, 0x00); wcd_cls_h_fsm(component, &wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_EAR, @@ -2717,6 +2753,13 @@ struct wcd938x_pdata *wcd938x_populate_dt_data(struct device *dev) return pdata; } +static irqreturn_t wcd938x_wd_handle_irq(int irq, void *data) +{ + pr_err_ratelimited("%s: Watchdog interrupt for irq =%d triggered\n", + __func__, irq); + return IRQ_HANDLED; +} + static int wcd938x_bind(struct device *dev) { int ret = 0, i = 0; @@ -2780,6 +2823,18 @@ static int wcd938x_bind(struct device *dev) } wcd938x->tx_swr_dev->slave_irq = wcd938x->virq; + /* Request for watchdog interrupt */ + wcd_request_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHR_PDM_WD_INT, + "HPHR PDM WD INT", wcd938x_wd_handle_irq, NULL); + wcd_request_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHL_PDM_WD_INT, + "HPHL PDM WD INT", wcd938x_wd_handle_irq, NULL); + wcd_request_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT, + "AUX PDM WD INT", wcd938x_wd_handle_irq, NULL); + /* Enable watchdog interrupt for HPH and AUX */ + wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHR_PDM_WD_INT); + wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHL_PDM_WD_INT); + wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT); + ret = snd_soc_register_component(dev, &soc_codec_dev_wcd938x, NULL, 0); if (ret) { -- GitLab From 9e013b2d5a75531444d4e0a9160a476a63dd8a4f Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 29 May 2019 13:52:34 -0700 Subject: [PATCH 1014/1645] asoc: codecs: wcd938x: Fix volatile register function Fix the volatile register function to return false if the registers are not volatile so that the reads will happen from cache and this improves read timing. Change-Id: I73149be3855be09a71ad61a6f3143038a7ba029b Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/wcd938x-regmap.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x-regmap.c b/asoc/codecs/wcd938x/wcd938x-regmap.c index a06f97532d8d..6f59258331a0 100644 --- a/asoc/codecs/wcd938x/wcd938x-regmap.c +++ b/asoc/codecs/wcd938x/wcd938x-regmap.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -494,8 +494,10 @@ static bool wcd938x_volatile_register(struct device *dev, unsigned int reg) { if(reg <= WCD938X_BASE_ADDRESS) return 0; - return (wcd938x_reg_access[WCD938X_REG(reg)] & RD_REG) - & ~(wcd938x_reg_access[WCD938X_REG(reg)] & WR_REG); + if ((wcd938x_reg_access[WCD938X_REG(reg)] & RD_REG) + && !(wcd938x_reg_access[WCD938X_REG(reg)] & WR_REG)) + return true; + return false; } struct regmap_config wcd938x_regmap_config = { -- GitLab From 3dd19d0b73ea68522c64ef101639ef480748073b Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 6 Jun 2019 14:10:53 -0700 Subject: [PATCH 1015/1645] asoc: wcd938x: initialize micb lock mutex Micb lock which is used to synchronize micbias control api is not initialized causing spin lock errors. Initialize the mutex to avoid the issue. Change-Id: I98c50fec8e8531333de643a85433d3e5973bfd14 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/wcd938x.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index bf285052f7df..5141b3b0d957 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -2923,9 +2923,10 @@ static int wcd938x_probe(struct platform_device *pdev) goto err; } + mutex_init(&wcd938x->micb_lock); ret = wcd938x_add_slave_components(dev, &match); if (ret) - goto err; + goto err_lock_init; wcd938x_reset(dev); @@ -2934,13 +2935,19 @@ static int wcd938x_probe(struct platform_device *pdev) return component_master_add_with_match(dev, &wcd938x_comp_ops, match); +err_lock_init: + mutex_destroy(&wcd938x->micb_lock); err: return ret; } static int wcd938x_remove(struct platform_device *pdev) { + struct wcd938x_priv *wcd938x = NULL; + + wcd938x = platform_get_drvdata(pdev); component_master_del(&pdev->dev, &wcd938x_comp_ops); + mutex_destroy(&wcd938x->micb_lock); dev_set_drvdata(&pdev->dev, NULL); return 0; -- GitLab From 326536d1d679bebaf00cd0fa9aa36c74868145fa Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 3 Jun 2019 13:29:43 -0700 Subject: [PATCH 1016/1645] asoc: codecs: defer probe if soundwire pin is not ready Defer codec macro probes if soundwire pins are not ready to be accessed yet during boot up. Change-Id: I20173e49043a076d73cdbb811863afbff87d4a3b Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/rx-macro.c | 6 ++++++ asoc/codecs/bolero/tx-macro.c | 6 ++++++ asoc/codecs/bolero/wsa-macro.c | 6 ++++++ asoc/codecs/msm-cdc-pinctrl.c | 5 +++-- include/asoc/msm-cdc-pinctrl.h | 6 +++--- 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 0be5c4e9a495..f72aa1deca08 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -3605,6 +3605,12 @@ static int rx_macro_probe(struct platform_device *pdev) __func__); return -EINVAL; } + if (msm_cdc_pinctrl_get_state(rx_priv->rx_swr_gpio_p) < 0) { + dev_err(&pdev->dev, "%s: failed to get swr pin state\n", + __func__); + return -EPROBE_DEFER; + } + rx_io_base = devm_ioremap(&pdev->dev, rx_base_addr, RX_MACRO_MAX_OFFSET); if (!rx_io_base) { diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index cb3aa59e4cb1..fb04d7469ee7 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -2000,6 +2000,12 @@ static int tx_macro_probe(struct platform_device *pdev) __func__); return -EINVAL; } + if (msm_cdc_pinctrl_get_state(tx_priv->tx_swr_gpio_p) < 0) { + dev_err(&pdev->dev, "%s: failed to get swr pin state\n", + __func__); + return -EPROBE_DEFER; + } + tx_io_base = devm_ioremap(&pdev->dev, tx_base_addr, TX_MACRO_MAX_OFFSET); if (!tx_io_base) { diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index f41392df4c1e..4fac4c652506 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -2901,6 +2901,12 @@ static int wsa_macro_probe(struct platform_device *pdev) __func__); return -EINVAL; } + if (msm_cdc_pinctrl_get_state(wsa_priv->wsa_swr_gpio_p) < 0) { + dev_err(&pdev->dev, "%s: failed to get swr pin state\n", + __func__); + return -EPROBE_DEFER; + } + wsa_io_base = devm_ioremap(&pdev->dev, wsa_base_addr, WSA_MACRO_MAX_OFFSET); if (!wsa_io_base) { diff --git a/asoc/codecs/msm-cdc-pinctrl.c b/asoc/codecs/msm-cdc-pinctrl.c index 8ed0c8ebf50d..0dadb7489aa5 100644 --- a/asoc/codecs/msm-cdc-pinctrl.c +++ b/asoc/codecs/msm-cdc-pinctrl.c @@ -122,9 +122,10 @@ EXPORT_SYMBOL(msm_cdc_pinctrl_select_active_state); * msm_cdc_pinctrl_get_state: get curren pinctrl state * @np: pointer to struct device_node * - * Returns 0 for sleep state, 1 for active state + * Returns 0 for sleep state, 1 for active state, + * error code for failure */ -bool msm_cdc_pinctrl_get_state(struct device_node *np) +int msm_cdc_pinctrl_get_state(struct device_node *np) { struct msm_cdc_pinctrl_info *gpio_data; diff --git a/include/asoc/msm-cdc-pinctrl.h b/include/asoc/msm-cdc-pinctrl.h index 4024d90becde..73022ab46ef1 100644 --- a/include/asoc/msm-cdc-pinctrl.h +++ b/include/asoc/msm-cdc-pinctrl.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ #ifndef __MFD_CDC_PINCTRL_H_ @@ -11,7 +11,7 @@ #if IS_ENABLED(CONFIG_MSM_CDC_PINCTRL) extern int msm_cdc_pinctrl_select_sleep_state(struct device_node *np); extern int msm_cdc_pinctrl_select_active_state(struct device_node *np); -extern bool msm_cdc_pinctrl_get_state(struct device_node *np); +extern int msm_cdc_pinctrl_get_state(struct device_node *np); extern int msm_cdc_get_gpio_state(struct device_node *np); int msm_cdc_pinctrl_drv_init(void); void msm_cdc_pinctrl_drv_exit(void); @@ -36,7 +36,7 @@ int msm_cdc_pinctrl_drv_init(void) void msm_cdc_pinctrl_drv_exit(void) { } -bool msm_cdc_pinctrl_get_state(struct device_node *np) +int msm_cdc_pinctrl_get_state(struct device_node *np) { return true; } -- GitLab From 1a0f9980315563c29505b3e948402dbfc11d9b7d Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 6 Jun 2019 14:23:06 -0700 Subject: [PATCH 1017/1645] soc: soundwire: check for valid pointer before dereference Check if the swr pointer obtained is not NULL before dereferencing it. Change-Id: I119141e5fd0b365789f8295d7b43867ede29dd8c Signed-off-by: Karthikeyan Mani --- soc/soundwire.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/soc/soundwire.c b/soc/soundwire.c index 23e373a1f453..72a94ace1482 100644 --- a/soc/soundwire.c +++ b/soc/soundwire.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #include @@ -998,10 +998,14 @@ static int swr_device_match(struct device *dev, struct device_driver *driver) if (!drv) return -EINVAL; - if (dev->type == &swr_dev_type) + if (dev->type == &swr_dev_type) { swr_dev = to_swr_device(dev); - else + if (!swr_dev) + return -EINVAL; + } else { return 0; + } + if (drv->id_table) return swr_match(drv->id_table, swr_dev) != NULL; -- GitLab From 3dd8fdf8a51a312491122bd11356260694528e49 Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Thu, 2 May 2019 12:14:37 +0530 Subject: [PATCH 1018/1645] dsp: Define channel map for 14channels Define channel map for channel count 14 for adm and asm to support capture usecases for this configuration. Change-Id: Ieb43dafd05f88bf34fa512fd7268258163e9ac92 Signed-off-by: Chaithanya Krishna Bacharaju --- dsp/q6adm.c | 15 +++++++++++++++ dsp/q6asm.c | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 8c8b61497d51..a039e3d17688 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2651,6 +2651,21 @@ static int adm_arrange_mch_map_v8( ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TFR; ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_TSL; ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_TSR; + } else if (channel_mode == 14) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC; + ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LB; + ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RB; + ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RS; + ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_TFL; + ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TFR; + ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_TSL; + ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_TSR; + ep_payload->dev_channel_mapping[12] = PCM_CHANNEL_FLC; + ep_payload->dev_channel_mapping[13] = PCM_CHANNEL_FRC; } else if (channel_mode == 16) { ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; diff --git a/dsp/q6asm.c b/dsp/q6asm.c index b6173e27e1a7..c30340952862 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -5729,6 +5729,21 @@ int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, lchannel_mapping[9] = PCM_CHANNEL_TFR; lchannel_mapping[10] = PCM_CHANNEL_TSL; lchannel_mapping[11] = PCM_CHANNEL_TSR; + } else if (channels == 14) { + lchannel_mapping[0] = PCM_CHANNEL_FL; + lchannel_mapping[1] = PCM_CHANNEL_FR; + lchannel_mapping[2] = PCM_CHANNEL_LFE; + lchannel_mapping[3] = PCM_CHANNEL_FC; + lchannel_mapping[4] = PCM_CHANNEL_LB; + lchannel_mapping[5] = PCM_CHANNEL_RB; + lchannel_mapping[6] = PCM_CHANNEL_LS; + lchannel_mapping[7] = PCM_CHANNEL_RS; + lchannel_mapping[8] = PCM_CHANNEL_TFL; + lchannel_mapping[9] = PCM_CHANNEL_TFR; + lchannel_mapping[10] = PCM_CHANNEL_TSL; + lchannel_mapping[11] = PCM_CHANNEL_TSR; + lchannel_mapping[12] = PCM_CHANNEL_FLC; + lchannel_mapping[13] = PCM_CHANNEL_FRC; } else if (channels == 16) { /* * Configured for 7.1.8 channel mapping -- GitLab From 467f2c9c7bccc40452512b7d3e2e65df3a47c911 Mon Sep 17 00:00:00 2001 From: Suprith Malligere Shankaregowda Date: Fri, 19 Apr 2019 19:35:41 +0530 Subject: [PATCH 1019/1645] ASoC: Add mixer control path for AFE loopback for Voice Call Add mixer control for AFE loopback for External Modem based Voice call support. Change-Id: I379187b9b013a9c97cce3eab6a5a254e102d5ef2 Signed-off-by: Suprith Malligere Shankaregowda --- asoc/msm-pcm-routing-v2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 77d1077f81c5..7663ae37dda1 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -15527,6 +15527,10 @@ static const struct snd_kcontrol_new aux_pcm_rx_port_mixer_controls[] = { MSM_BACKEND_DAI_AUXPCM_RX, MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sec_auxpcm_rx_port_mixer_controls[] = { @@ -25976,6 +25980,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUX_PCM_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"AUX_PCM_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, {"AUX_PCM_RX Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"AUX_PCM_RX Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"AUX_PCM_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"AUX_PCM_RX", NULL, "AUX_PCM_RX Port Mixer"}, -- GitLab From e13704c69973c31f152333c4b37ac9f8d03c2404 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 22 Apr 2019 18:34:23 +0530 Subject: [PATCH 1020/1645] soc: Handle system suspend for LPI pinctrl System suspend is not handled in lpi pinctrl driver. Register to system ops to release lpass hw vote before apps suspend. CRs-Fixed: 2439988 Change-Id: I334a993ead5d2abec5286fb5812d67b795d03f3c Signed-off-by: Laxminath Kasam --- soc/pinctrl-lpi.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index c2342617af66..ff9e9406c438 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -788,7 +788,44 @@ int lpi_pinctrl_runtime_suspend(struct device *dev) return 0; } +int lpi_pinctrl_suspend(struct device *dev) +{ + int ret = 0; + + dev_dbg(dev, "%s: system suspend\n", __func__); + + if ((!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev))) { + ret = lpi_pinctrl_runtime_suspend(dev); + if (!ret) { + /* + * Synchronize runtime-pm and system-pm states: + * At this point, we are already suspended. If + * runtime-pm still thinks its active, then + * make sure its status is in sync with HW + * status. The three below calls let the + * runtime-pm know that we are suspended + * already without re-invoking the suspend + * callback + */ + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + pm_runtime_enable(dev); + } + } + + return ret; +} + +int lpi_pinctrl_resume(struct device *dev) +{ + return 0; +} + static const struct dev_pm_ops lpi_pinctrl_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS( + lpi_pinctrl_suspend, + lpi_pinctrl_resume + ) SET_RUNTIME_PM_OPS( lpi_pinctrl_runtime_suspend, lpi_pinctrl_runtime_resume, -- GitLab From a840a230aab4041c4a42ac679ba18393b92f688b Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Fri, 3 May 2019 13:47:37 +0530 Subject: [PATCH 1021/1645] asoc: qcs405: Extend cdc dma tx channel count enum to 16 Extend cdc dma rx channel count enum values to 16 from 8 to support 16channel capture usecases. Change-Id: If5498dded543f72c4fafceee3ddbe3217b08d258 Signed-off-by: Chaithanya Krishna Bacharaju --- asoc/qcs405.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 9ad07da3f24d..8793882869ef 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -490,8 +490,8 @@ static const char *const qos_text[] = {"Disable", "Enable"}; static const char *const cdc_dma_rx_ch_text[] = {"One", "Two"}; static const char *const cdc_dma_tx_ch_text[] = {"One", "Two", "Three", "Four", - "Five", "Six", "Seven", - "Eight"}; + "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", + "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen"}; static char const *cdc_dma_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_16", "KHZ_22P05", "KHZ_32", "KHZ_44P1", "KHZ_48", -- GitLab From 6790e92830b97af2e88ff4c90baccbf68378ee2a Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Fri, 3 May 2019 13:41:00 +0530 Subject: [PATCH 1022/1645] asoc: routing: Extend MultiMedia1 channel controls to support 14channels Extend existing MultiMedia1 Output Channel and MultiMedia1 Channels controls to support upto 14channels. Change-Id: Idaa15f7b30139695d7738599f669944ac837c036 Signed-off-by: Chaithanya Krishna Bacharaju --- asoc/msm-pcm-routing-v2.c | 42 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 77d1077f81c5..f35ac7ec3efb 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -3693,7 +3693,7 @@ static const struct snd_kcontrol_new channel_mixer_controls[] = { msm_pcm_put_channel_rule_index), SOC_SINGLE_EXT("MultiMedia1 Channels", SND_SOC_NOPM, - MSM_FRONTEND_DAI_MULTIMEDIA1, 10, 0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 14, 0, msm_pcm_get_out_chs, msm_pcm_put_out_chs), SOC_SINGLE_EXT("MultiMedia2 Channels", SND_SOC_NOPM, @@ -3855,6 +3855,46 @@ static const struct snd_kcontrol_new channel_mixer_controls[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Output Channel11", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1, .rshift = 10,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Output Channel12", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1, .rshift = 11,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Output Channel13", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1, .rshift = 12,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Output Channel14", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1, .rshift = 13,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .name = "MultiMedia2 Output Channel1", .info = msm_pcm_channel_weight_info, .get = msm_pcm_channel_weight_get, -- GitLab From de1ce572ce6109131c7c8107fbdcdd372db77537 Mon Sep 17 00:00:00 2001 From: Dhananjay Kumar Date: Tue, 9 Apr 2019 19:26:41 +0530 Subject: [PATCH 1023/1645] asoc: udpate qcs405 compress playback dai ops Currently only Compress2 stream is using hw params as async ops and hence the startup latency and setup sequence varies for this usecase as compared to other compress playback streams. Update qcs405 compress playback dai ops to mark hw params as async for all compress playback FE dai entries, so that all compressed playback streams have uniform latency and setup sequence. Change-Id: Iac965b0ca1c059c49b9b0a985f70df7d382f7446 Signed-off-by: Dhananjay Kumar --- asoc/qcs405.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 9ad07da3f24d..3d18873f5319 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -6390,6 +6390,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .cpu_dai_name = "MultiMedia7", .platform_name = "msm-compress-dsp", .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, .dpcm_playback = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, @@ -6597,6 +6598,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .cpu_dai_name = "MultiMedia11", .platform_name = "msm-compress-dsp", .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, .dpcm_playback = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, @@ -6613,6 +6615,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .cpu_dai_name = "MultiMedia12", .platform_name = "msm-compress-dsp", .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, .dpcm_playback = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, @@ -6629,6 +6632,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .cpu_dai_name = "MultiMedia13", .platform_name = "msm-compress-dsp", .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, .dpcm_playback = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, @@ -6645,6 +6649,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .cpu_dai_name = "MultiMedia14", .platform_name = "msm-compress-dsp", .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, .dpcm_playback = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, @@ -6661,6 +6666,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .cpu_dai_name = "MultiMedia15", .platform_name = "msm-compress-dsp", .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, .dpcm_playback = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, -- GitLab From 25e77dd11185a70ebfc30849e8e0ad0be8de1a8a Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Thu, 9 May 2019 14:33:45 +0530 Subject: [PATCH 1024/1645] asoc: add support to set ADM channels for SLIM_9_TX port In split A2DP sink ADM channels is set to mono based on BE config. Add support to set ADM channels based on decoder config received from BT IPC library. Change-Id: I3925b805593871d420f4cfd3ce4b87adb0e03272 Signed-off-by: Surendar Karka --- asoc/msm-pcm-routing-v2.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 77d1077f81c5..ddcc3458b657 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -3138,7 +3138,7 @@ static int msm_routing_lsm_func_put(struct snd_kcontrol *kcontrol, static const char *const adm_override_chs_text[] = {"Zero", "One", "Two"}; -static SOC_ENUM_SINGLE_EXT_DECL(slim_7_rx_adm_override_chs, +static SOC_ENUM_SINGLE_EXT_DECL(adm_override_chs, adm_override_chs_text); static int msm_routing_adm_get_backend_idx(struct snd_kcontrol *kcontrol) @@ -3147,6 +3147,8 @@ static int msm_routing_adm_get_backend_idx(struct snd_kcontrol *kcontrol) if (strnstr(kcontrol->id.name, "SLIM7_RX", sizeof("SLIM7_RX"))) { backend_id = MSM_BACKEND_DAI_SLIMBUS_7_RX; + } else if (strnstr(kcontrol->id.name, "SLIM9_TX", sizeof("SLIM9_TX"))) { + backend_id = MSM_BACKEND_DAI_SLIMBUS_9_TX; } else { pr_err("%s: unsupported backend id: %s", __func__, kcontrol->id.name); @@ -3155,6 +3157,7 @@ static int msm_routing_adm_get_backend_idx(struct snd_kcontrol *kcontrol) return backend_id; } + static int msm_routing_adm_channel_config_get( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -3193,7 +3196,10 @@ static int msm_routing_adm_channel_config_put( } static const struct snd_kcontrol_new adm_channel_config_controls[] = { - SOC_ENUM_EXT("SLIM7_RX ADM Channels", slim_7_rx_adm_override_chs, + SOC_ENUM_EXT("SLIM7_RX ADM Channels", adm_override_chs, + msm_routing_adm_channel_config_get, + msm_routing_adm_channel_config_put), + SOC_ENUM_EXT("SLIM9_TX ADM Channels", adm_override_chs, msm_routing_adm_channel_config_get, msm_routing_adm_channel_config_put), }; -- GitLab From e48fb2b1d91a90eeb1d522424e8d9167940d9e3b Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Wed, 8 May 2019 13:02:08 +0530 Subject: [PATCH 1025/1645] asoc: routing: Add controls to set custom matrix channel mapping Add controls to set custom matrix output channel mapping to override default channel mapping. Change-Id: If50c839c7828528cdb2b1ab18a36204c9406b3e9 Signed-off-by: Chaithanya Krishna Bacharaju --- asoc/msm-pcm-routing-v2.c | 122 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 77d1077f81c5..633e41077077 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -3666,6 +3666,67 @@ static int msm_pcm_channel_weight_get(struct snd_kcontrol *kcontrol, return 0; } +static int msm_pcm_channel_output_map_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8; + /* Valid channel map value ranges from 1 to 64 */ + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 64; + + return 0; +} + +static int msm_pcm_channel_output_map_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u16 fe_id = 0; + int i, ch_map; + + fe_id = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %d\n", __func__, fe_id); + return -EINVAL; + } + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; ++i) { + ch_map = ucontrol->value.integer.value[i]; + channel_mixer[fe_id].out_ch_map[i] = ch_map; + pr_debug("%s: FE_ID %d, channel %d channel map %d\n", + __func__, fe_id, i, channel_mixer[fe_id].out_ch_map[i]); + } + + /* Make override_out_ch_map false if ch map is reset */ + if (channel_mixer[fe_id].out_ch_map[0] == 0) + channel_mixer[fe_id].override_out_ch_map = false; + else + channel_mixer[fe_id].override_out_ch_map = true; + + return 0; +} + +static int msm_pcm_channel_output_map_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u16 fe_id = 0; + int i; + + fe_id = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %d\n", __func__, fe_id); + return -EINVAL; + } + + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; ++i) + ucontrol->value.integer.value[i] = + channel_mixer[fe_id].out_ch_map[i]; + + return 0; +} + static const struct snd_kcontrol_new channel_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia1 Channel Rule", SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA1, 8, 0, @@ -3974,7 +4035,68 @@ static const struct snd_kcontrol_new channel_mixer_controls[] = { .put = msm_pcm_channel_input_be_put, .private_value = (unsigned long)&(mm1_ch8_enum) }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia2 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA2,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia3 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA3,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia4 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA4,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia5 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA5,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia6 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA6,} + }, }; + static int msm_ec_ref_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { -- GitLab From 2f81be27d8e30cf71e49d33a1cc3d49c1d21ed4d Mon Sep 17 00:00:00 2001 From: Erin Yan Date: Mon, 29 Apr 2019 13:42:57 +0800 Subject: [PATCH 1026/1645] asoc: adapt channel mixer usage to tinymix Tinymix set the array value of the mixer control one by one. The channel number validation check here will cause failure in tinymix. Allow 0 value here is fine because the parameters will be checked before they are set at runtime. Change-Id: I49c23f84aa081550434696dde96d2800e90390fb Signed-off-by: Erin Yan --- asoc/msm-compress-q6-v2.c | 6 +++--- asoc/msm-pcm-q6-v2.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index d9e0927bc034..a3618caa5e73 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -4738,9 +4738,9 @@ static int msm_compr_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, chmixer_pspd->output_channel = ucontrol->value.integer.value[3]; chmixer_pspd->port_idx = ucontrol->value.integer.value[4]; - if (chmixer_pspd->input_channel <= 0 || + if (chmixer_pspd->input_channel < 0 || chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8 || - chmixer_pspd->output_channel <= 0 || + chmixer_pspd->output_channel < 0 || chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { pr_err("%s: Invalid channels, in %d, out %d\n", __func__, chmixer_pspd->input_channel, @@ -4795,7 +4795,7 @@ static int msm_compr_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, if (prtd && prtd->audio_client) { stream_id = prtd->audio_client->session; be_id = chmixer_pspd->port_idx; - ret = msm_pcm_routing_set_channel_mixer_runtime(be_id, + msm_pcm_routing_set_channel_mixer_runtime(be_id, stream_id, session_type, chmixer_pspd); } } diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 3b20ecc84570..af158432630f 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1934,9 +1934,9 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, chmixer_pspd->output_channel = ucontrol->value.integer.value[3]; chmixer_pspd->port_idx = ucontrol->value.integer.value[4]; - if (chmixer_pspd->input_channel <= 0 || + if (chmixer_pspd->input_channel < 0 || chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8 || - chmixer_pspd->output_channel <= 0 || + chmixer_pspd->output_channel < 0 || chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) { pr_err("%s: Invalid channels, in %d, out %d\n", __func__, chmixer_pspd->input_channel, -- GitLab From 0e2cda8fabffef51f066d3ff774275cecae6e2c5 Mon Sep 17 00:00:00 2001 From: Faiz Nabi Kuchay Date: Tue, 28 May 2019 10:59:24 +0530 Subject: [PATCH 1027/1645] asoc: Enable digital_mute to support excursion logging Enable digital_mute for SLIMBUS_0_RX to support excursion logging feature. Change-Id: Icc64f5fdf245c4239683872ff65a1f2fa6dc88e2 Signed-off-by: Faiz Nabi Kuchay --- asoc/msm-dai-q6-v2.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 35ebff4c3152..2b77c8437e4e 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -2717,6 +2717,18 @@ static int msm_dai_q6_set_channel_map(struct snd_soc_dai *dai, return rc; } +/* all ports with excursion logging requirement can use this digital_mute api */ +static int msm_dai_q6_spk_digital_mute(struct snd_soc_dai *dai, + int mute) +{ + int port_id = dai->id; + + if (mute) + afe_get_sp_xt_logging_data(port_id); + + return 0; +} + static struct snd_soc_dai_ops msm_dai_q6_ops = { .prepare = msm_dai_q6_prepare, .hw_params = msm_dai_q6_hw_params, @@ -2725,6 +2737,15 @@ static struct snd_soc_dai_ops msm_dai_q6_ops = { .set_channel_map = msm_dai_q6_set_channel_map, }; +static struct snd_soc_dai_ops msm_dai_slimbus_0_rx_ops = { + .prepare = msm_dai_q6_prepare, + .hw_params = msm_dai_q6_hw_params, + .shutdown = msm_dai_q6_shutdown, + .set_fmt = msm_dai_q6_set_fmt, + .set_channel_map = msm_dai_q6_set_channel_map, + .digital_mute = msm_dai_q6_spk_digital_mute, +}; + static int msm_dai_q6_cal_info_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -4445,7 +4466,7 @@ static struct snd_soc_dai_driver msm_dai_q6_slimbus_rx_dai[] = { .rate_min = 8000, .rate_max = 384000, }, - .ops = &msm_dai_q6_ops, + .ops = &msm_dai_slimbus_0_rx_ops, .id = SLIMBUS_0_RX, .probe = msm_dai_q6_dai_probe, .remove = msm_dai_q6_dai_remove, @@ -11263,18 +11284,6 @@ static void msm_dai_q6_cdc_dma_shutdown(struct snd_pcm_substream *substream, clear_bit(STATUS_PORT_STARTED, dai_data->hwfree_status); } -/* all ports with same WSA requirement can use this digital mute API */ -static int msm_dai_q6_spk_digital_mute(struct snd_soc_dai *dai, - int mute) -{ - int port_id = dai->id; - - if (mute) - afe_get_sp_xt_logging_data(port_id); - - return 0; -} - static struct snd_soc_dai_ops msm_dai_q6_cdc_dma_ops = { .prepare = msm_dai_q6_cdc_dma_prepare, .hw_params = msm_dai_q6_cdc_dma_hw_params, -- GitLab From 48b8811c2f800598a20dbc2cd69a894f1a7dbae2 Mon Sep 17 00:00:00 2001 From: Dhanalakshmi Siddani Date: Fri, 31 May 2019 17:52:52 +0530 Subject: [PATCH 1028/1645] asoc: Update max channels for TDM ports Update max channels supported for TDM ports from 8 to 16. Change-Id: I3d3b42983fff22e0102b9eb2aaca1a5698820605 Signed-off-by: Dhanalakshmi Siddani --- asoc/msm-dai-q6-v2.c | 160 +++++++++++++++++++++---------------------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 35ebff4c3152..0c812b564843 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -8761,7 +8761,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -8782,7 +8782,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -8803,7 +8803,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -8824,7 +8824,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -8845,7 +8845,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -8866,7 +8866,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -8887,7 +8887,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -8908,7 +8908,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -8929,7 +8929,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -8950,7 +8950,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -8971,7 +8971,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -8992,7 +8992,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9013,7 +9013,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9034,7 +9034,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9055,7 +9055,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9076,7 +9076,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9097,7 +9097,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9118,7 +9118,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9139,7 +9139,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9160,7 +9160,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9181,7 +9181,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9202,7 +9202,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9223,7 +9223,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9244,7 +9244,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9265,7 +9265,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9286,7 +9286,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9307,7 +9307,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9328,7 +9328,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9349,7 +9349,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9370,7 +9370,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9391,7 +9391,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9412,7 +9412,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9433,7 +9433,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9454,7 +9454,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9475,7 +9475,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9496,7 +9496,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9517,7 +9517,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9538,7 +9538,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9559,7 +9559,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9580,7 +9580,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9601,7 +9601,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9622,7 +9622,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9643,7 +9643,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9664,7 +9664,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9685,7 +9685,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9706,7 +9706,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9727,7 +9727,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9748,7 +9748,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9769,7 +9769,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9790,7 +9790,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9811,7 +9811,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9832,7 +9832,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9853,7 +9853,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9874,7 +9874,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9895,7 +9895,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9916,7 +9916,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9937,7 +9937,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9958,7 +9958,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -9979,7 +9979,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10000,7 +10000,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10021,7 +10021,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10042,7 +10042,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10063,7 +10063,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10084,7 +10084,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10105,7 +10105,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10126,7 +10126,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10147,7 +10147,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10168,7 +10168,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10189,7 +10189,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10210,7 +10210,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10231,7 +10231,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10252,7 +10252,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10273,7 +10273,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10294,7 +10294,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10315,7 +10315,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10336,7 +10336,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10357,7 +10357,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10378,7 +10378,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10399,7 +10399,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, @@ -10420,7 +10420,7 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 16, .rate_min = 8000, .rate_max = 352800, }, -- GitLab From d92c7df9d0375186f8306b4bde0d28bf035f3bcf Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 28 May 2019 10:34:56 +0530 Subject: [PATCH 1029/1645] asoc: sm6150: Fix MCLK enable/disable sequence in MI2S slave mode Set enable/disable flag properly before sending the clk request to ADSP in MI2S slave mode. Change-Id: I4a145b1765b19b2eb708a52a35b51032f540fb2d Signed-off-by: Aditya Bavanari --- asoc/sm6150.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/sm6150.c b/asoc/sm6150.c index e41fe49caeaf..d9c0eae55590 100644 --- a/asoc/sm6150.c +++ b/asoc/sm6150.c @@ -5928,6 +5928,7 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) if (mi2s_intf_conf[index].msm_is_ext_mclk) { pr_debug("%s: Enabling mclk, clk_freq_in_hz = %u\n", __func__, mi2s_mclk[index].clk_freq_in_hz); + mi2s_mclk[index].enable = 1; ret = afe_set_lpass_clock_v2(port_id, &mi2s_mclk[index]); if (ret < 0) { @@ -5935,7 +5936,6 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) __func__, ret); goto clk_off; } - mi2s_mclk[index].enable = 1; } if (pdata->mi2s_gpio_p[index]) msm_cdc_pinctrl_select_active_state( @@ -5988,12 +5988,12 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) if (mi2s_intf_conf[index].msm_is_ext_mclk) { pr_debug("%s: Disabling mclk, clk_freq_in_hz = %u\n", __func__, mi2s_mclk[index].clk_freq_in_hz); + mi2s_mclk[index].enable = 0; ret = afe_set_lpass_clock_v2(port_id, &mi2s_mclk[index]); if (ret < 0) pr_err("%s: mclk disable failed for MCLK (%d); ret=%d\n", __func__, index, ret); - mi2s_mclk[index].enable = 0; } } mutex_unlock(&mi2s_intf_conf[index].lock); -- GitLab From 0016db19a7f89e47338fba49cdf1f4da441329e6 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 11 Jun 2019 04:42:38 +0530 Subject: [PATCH 1030/1645] soc: soundwire: Add support to dump bulk register writes Add support to dump soundwire bulk register writes to analyze port configuration on both soundwire master and soundwire slave devices. Change-Id: Ie02b2a0ba40aa5a0b4243022e439e1b545688143 Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 194e976689fd..d646cc7858a4 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -232,6 +232,16 @@ static const struct file_operations swrm_debug_ops = { .read = swrm_debug_read, }; +static void swrm_reg_dump(struct swr_mstr_ctrl *swrm, + u32 *reg, u32 *val, int len, const char* func) +{ + int i = 0; + + for (i = 0; i < len; i++) + dev_dbg(swrm->dev, "%s: reg = 0x%x val = 0x%x\n", + func, reg[i], val[i]); +} + static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) { int ret = 0; @@ -941,6 +951,7 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank) mport->ch_en = mport->req_ch; } + swrm_reg_dump(swrm, reg, val, len, __func__); swr_master_bulk_write(swrm, reg, val, len); } -- GitLab From 6d8bda3545fdf2698af669761eb9c74a282eb027 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Sun, 16 Jun 2019 23:53:09 -0700 Subject: [PATCH 1031/1645] asoc: msm-lsm-client: reset app type configs at msm_lsm_close Currently lsm client driver doesn't reset app type configs at the end of a session, which causes the previous lsm session's acdb_dev_id to be cached and reused in the new lsm sessions. Fix this by resetting app type configs at msm_lsm_close to set acdb_dev_id to 0. Change-Id: I2c51201291beb1d4baa4d57c0d5c1ef9777a85ed Signed-off-by: Xiaoyu Ye --- asoc/msm-lsm-client.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index f886b4b78872..5bc897d9e594 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -2624,7 +2624,10 @@ static int msm_lsm_close(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct lsm_priv *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd; + struct msm_pcm_stream_app_type_cfg cfg_data = {0}; int ret = 0; + int be_id = 0; + int fe_id = 0; if (!substream->private_data) { pr_err("%s: Invalid private_data", __func__); @@ -2690,6 +2693,37 @@ static int msm_lsm_close(struct snd_pcm_substream *substream) q6lsm_close(prtd->lsm_client); prtd->lsm_client->opened = false; } + + fe_id = prtd->lsm_client->fe_id; + ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, SESSION_TYPE_TX, + &be_id, &cfg_data); + if (ret < 0) + dev_dbg(rtd->dev, + "%s: get stream app type cfg failed, err = %d\n", + __func__, ret); + /* + * be_id will be 0 in case of LSM directly connects to AFE due to + * last_be_id_configured[fedai_id][session_type] has not been updated. + * And then the cfg_data from wrong combination would be reset without + * this if check. We reset only if app_type, acdb_dev_id, and sample_rate + * are valid. + */ + if (!cfg_data.app_type && + !cfg_data.acdb_dev_id && !cfg_data.sample_rate) { + dev_dbg(rtd->dev, "%s: no need to reset app type configs\n", + __func__); + } else { + memset(&cfg_data, 0, sizeof(cfg_data)); + ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, + SESSION_TYPE_TX, + be_id, + &cfg_data); + if (ret < 0) + dev_dbg(rtd->dev, + "%s: set stream app type cfg failed, err = %d\n", + __func__, ret); + } + q6lsm_client_free(prtd->lsm_client); spin_lock_irqsave(&prtd->event_lock, flags); -- GitLab From d6d524d6781bd14f67e8d6a2034ac6824cca27e1 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 19 Jun 2019 02:31:11 +0530 Subject: [PATCH 1032/1645] ASoC: Kona: Make addition of aux codec as optional Check for aux codec count and avoid aux codec registration if the count is zero. Change-Id: I540dcc8f14f138b8bd673d88ab7e033779a90843 Signed-off-by: Sudheer Papothi --- asoc/kona.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/asoc/kona.c b/asoc/kona.c index be944d3e2ffa..ead791e8823c 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -7168,6 +7168,7 @@ static int msm_init_aux_dev(struct platform_device *pdev, struct device_node *aux_codec_of_node; u32 wsa_max_devs; u32 wsa_dev_cnt; + u32 codec_max_aux_devs = 0; u32 codec_aux_dev_cnt = 0; int i; struct msm_wsa881x_dev_info *wsa881x_dev_info; @@ -7283,6 +7284,24 @@ static int msm_init_aux_dev(struct platform_device *pdev, __func__, found); codec_aux_dev: + /* Get maximum aux codec device count for this platform */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,codec-max-aux-devs", + &codec_max_aux_devs); + if (ret) { + dev_err(&pdev->dev, + "%s: codec-max-aux-devs property missing in DT %s, ret = %d\n", + __func__, pdev->dev.of_node->full_name, ret); + codec_max_aux_devs = 0; + goto aux_dev_register; + } + if (codec_max_aux_devs == 0) { + dev_dbg(&pdev->dev, + "%s: Max aux codec devices is 0 for this target?\n", + __func__); + goto aux_dev_register; + } + /* Get count of aux codec device phandles for this platform */ codec_aux_dev_cnt = of_count_phandle_with_args( pdev->dev.of_node, @@ -7299,6 +7318,19 @@ static int msm_init_aux_dev(struct platform_device *pdev, goto err; } + /* + * Expect total phandles count to be NOT less than maximum possible + * AUX device count. However, if it is less, then assign same value to + * max count as well. + */ + if (codec_aux_dev_cnt < codec_max_aux_devs) { + dev_dbg(&pdev->dev, + "%s: codec_max_aux_devs = %d cannot exceed codec_aux_dev_cnt = %d\n", + __func__, codec_max_aux_devs, + codec_aux_dev_cnt); + codec_max_aux_devs = codec_aux_dev_cnt; + } + /* * Alloc mem to store phandle and index info of aux codec * if already registered with ALSA core @@ -7347,6 +7379,7 @@ static int msm_init_aux_dev(struct platform_device *pdev, "%s: found %d AUX codecs registered with ALSA core\n", __func__, codecs_found); +aux_dev_register: card->num_aux_devs = wsa_max_devs + codec_aux_dev_cnt; card->num_configs = wsa_max_devs + codec_aux_dev_cnt; -- GitLab From 6208d04bd4277d9354727146a014b9b882822bfa Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Wed, 19 Jun 2019 13:57:19 -0700 Subject: [PATCH 1033/1645] ASoC: msm: enable tdm pinctrl config on 8155 machine Enable dynamic TDM pinctrl configuration based on CPU DAI activity on auto 8155 machine drv. Change-Id: I31ada624f043653018624cdae0542c76dcc1a9a1 Signed-off-by: Derek Chen --- asoc/sa8155.c | 548 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 350 insertions(+), 198 deletions(-) diff --git a/asoc/sa8155.c b/asoc/sa8155.c index e01b2315d514..88fc7166ee30 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -119,26 +119,24 @@ enum { }; enum pinctrl_pin_state { - STATE_DISABLE = 0, /* All pins are in sleep state */ - STATE_MI2S_ACTIVE, /* IS2 = active, TDM = sleep */ - STATE_TDM_ACTIVE, /* IS2 = sleep, TDM = active */ + STATE_SLEEP = 0, /* All pins are in sleep state */ + STATE_ACTIVE, /* TDM = active */ }; struct msm_pinctrl_info { struct pinctrl *pinctrl; - struct pinctrl_state *mi2s_disable; - struct pinctrl_state *tdm_disable; - struct pinctrl_state *mi2s_active; - struct pinctrl_state *tdm_active; + struct pinctrl_state *sleep; + struct pinctrl_state *active; enum pinctrl_pin_state curr_state; }; -struct msm_asoc_mach_data { - struct msm_pinctrl_info pinctrl_info; -}; +static const char *const pin_states[] = {"sleep", "active"}; -static const char *const pin_states[] = {"sleep", "i2s-active", - "tdm-active"}; +static const char *const tdm_gpio_phandle[] = {"qcom,pri-tdm-gpios", + "qcom,sec-tdm-gpios", + "qcom,tert-tdm-gpios", + "qcom,quat-tdm-gpios", + "qcom,quin-tdm-gpios"}; enum { TDM_0 = 0, @@ -166,6 +164,11 @@ struct tdm_port { u32 channel; }; +struct tdm_conf { + struct mutex lock; + u32 ref_cnt; +}; + /* TDM default config */ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { { /* PRI TDM */ @@ -610,7 +613,7 @@ static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_192", "KHZ_352P8", "KHZ_384"}; static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96", "KHZ_192", "KHZ_32", "KHZ_44P1", - "KHZ_88P2", "KHZ_176P4" }; + "KHZ_88P2", "KHZ_176P4"}; static char const *tdm_ch_text[] = { "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", @@ -737,7 +740,11 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = { }; -static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; +struct msm_asoc_mach_data { + struct msm_pinctrl_info pinctrl_info[TDM_INTERFACE_MAX]; + struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; + struct tdm_conf tdm_intf_conf[TDM_INTERFACE_MAX]; +}; static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1099,13 +1106,13 @@ static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol) { - int idx; + int idx = 0; if (strnstr(kcontrol->id.name, "Display Port RX", sizeof("Display Port RX"))) { idx = DP_RX_IDX; } else { - pr_err("%s: unsupported BE: %s", + pr_err("%s: unsupported BE: %s\n", __func__, kcontrol->id.name); idx = -EINVAL; } @@ -1384,7 +1391,7 @@ static int tdm_get_sample_rate_val(int sample_rate) static int aux_pcm_get_sample_rate_val(int sample_rate) { - int sample_rate_val; + int sample_rate_val = 0; switch (sample_rate) { case SAMPLING_RATE_16KHZ: @@ -1400,7 +1407,7 @@ static int aux_pcm_get_sample_rate_val(int sample_rate) static int tdm_get_mode(struct snd_kcontrol *kcontrol) { - int mode; + int mode = -EINVAL; if (strnstr(kcontrol->id.name, "PRI", sizeof(kcontrol->id.name))) { @@ -1428,7 +1435,7 @@ static int tdm_get_mode(struct snd_kcontrol *kcontrol) static int tdm_get_channel(struct snd_kcontrol *kcontrol) { - int channel; + int channel = -EINVAL; if (strnstr(kcontrol->id.name, "RX_0", sizeof(kcontrol->id.name)) || @@ -1502,7 +1509,7 @@ static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( @@ -1522,7 +1529,7 @@ static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { tdm_rx_cfg[port.mode][port.channel].sample_rate = @@ -1562,7 +1569,7 @@ static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { tdm_tx_cfg[port.mode][port.channel].sample_rate = @@ -1624,7 +1631,7 @@ static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { ucontrol->value.enumerated.item[0] = tdm_get_format_val( @@ -1644,7 +1651,7 @@ static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { tdm_rx_cfg[port.mode][port.channel].bit_format = @@ -1664,7 +1671,7 @@ static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { ucontrol->value.enumerated.item[0] = tdm_get_format_val( @@ -1684,7 +1691,7 @@ static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { tdm_tx_cfg[port.mode][port.channel].bit_format = @@ -1704,7 +1711,7 @@ static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { @@ -1725,7 +1732,7 @@ static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { tdm_rx_cfg[port.mode][port.channel].channels = @@ -1745,7 +1752,7 @@ static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { ucontrol->value.enumerated.item[0] = @@ -1765,7 +1772,7 @@ static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { tdm_tx_cfg[port.mode][port.channel].channels = @@ -1780,7 +1787,7 @@ static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, static int tdm_get_slot_num_val(int slot_num) { - int slot_num_val; + int slot_num_val = 0; switch (slot_num) { case 1: @@ -1814,7 +1821,7 @@ static int tdm_slot_num_get(struct snd_kcontrol *kcontrol, int mode = tdm_get_mode(kcontrol); if (mode < 0) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); return mode; } @@ -1831,7 +1838,7 @@ static int tdm_slot_num_get(struct snd_kcontrol *kcontrol, static int tdm_get_slot_num(int value) { - int slot_num; + int slot_num = 0; switch (value) { case 0: @@ -1865,7 +1872,7 @@ static int tdm_slot_num_put(struct snd_kcontrol *kcontrol, int mode = tdm_get_mode(kcontrol); if (mode < 0) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); return mode; } @@ -1882,7 +1889,7 @@ static int tdm_slot_num_put(struct snd_kcontrol *kcontrol, static int tdm_get_slot_width_val(int slot_width) { - int slot_width_val; + int slot_width_val = 2; switch (slot_width) { case 16: @@ -1907,7 +1914,7 @@ static int tdm_slot_width_get(struct snd_kcontrol *kcontrol, int mode = tdm_get_mode(kcontrol); if (mode < 0) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); return mode; } @@ -1924,7 +1931,7 @@ static int tdm_slot_width_get(struct snd_kcontrol *kcontrol, static int tdm_get_slot_width(int value) { - int slot_width; + int slot_width = 32; switch (value) { case 0: @@ -1949,7 +1956,7 @@ static int tdm_slot_width_put(struct snd_kcontrol *kcontrol, int mode = tdm_get_mode(kcontrol); if (mode < 0) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); return mode; } @@ -1973,7 +1980,7 @@ static int tdm_rx_slot_mapping_get(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { slot_offset = tdm_rx_slot_offset[port.mode][port.channel]; @@ -1997,7 +2004,7 @@ static int tdm_rx_slot_mapping_put(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { slot_offset = tdm_rx_slot_offset[port.mode][port.channel]; @@ -2021,7 +2028,7 @@ static int tdm_tx_slot_mapping_get(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { slot_offset = tdm_tx_slot_offset[port.mode][port.channel]; @@ -2045,7 +2052,7 @@ static int tdm_tx_slot_mapping_put(struct snd_kcontrol *kcontrol, int ret = tdm_get_port_idx(kcontrol, &port); if (ret) { - pr_err("%s: unsupported control: %s", + pr_err("%s: unsupported control: %s\n", __func__, kcontrol->id.name); } else { slot_offset = tdm_tx_slot_offset[port.mode][port.channel]; @@ -2080,7 +2087,7 @@ static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) sizeof("QUIN_AUX_PCM"))) idx = QUIN_AUX_PCM; else { - pr_err("%s: unsupported port: %s", + pr_err("%s: unsupported port: %s\n", __func__, kcontrol->id.name); idx = -EINVAL; } @@ -2195,7 +2202,7 @@ static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) sizeof("QUIN_MI2S_TX"))) idx = QUIN_MI2S; else { - pr_err("%s: unsupported channel: %s", + pr_err("%s: unsupported channel: %s\n", __func__, kcontrol->id.name); idx = -EINVAL; } @@ -3729,7 +3736,6 @@ static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) return ret; } -#ifdef ENABLE_PINCTRL static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, enum pinctrl_pin_state new_state) { @@ -3737,13 +3743,13 @@ static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, int curr_state = 0; if (pinctrl_info == NULL) { - pr_err("%s: pinctrl_info is NULL\n", __func__); + pr_err("%s: pinctrl info is NULL\n", __func__); ret = -EINVAL; goto err; } if (pinctrl_info->pinctrl == NULL) { - pr_err("%s: pinctrl_info->pinctrl is NULL\n", __func__); + pr_err("%s: pinctrl handle is NULL\n", __func__); ret = -EINVAL; goto err; } @@ -3754,55 +3760,40 @@ static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, pin_states[curr_state], pin_states[pinctrl_info->curr_state]); if (curr_state == pinctrl_info->curr_state) { - pr_debug("%s: Already in same state\n", __func__); + pr_debug("%s: pin already in same state\n", __func__); goto err; } - if (curr_state != STATE_DISABLE && - pinctrl_info->curr_state != STATE_DISABLE) { - pr_debug("%s: state already active cannot switch\n", __func__); + if (curr_state != STATE_SLEEP && + pinctrl_info->curr_state != STATE_SLEEP) { + pr_debug("%s: pin state is already active, cannot switch\n", __func__); ret = -EIO; goto err; } switch (pinctrl_info->curr_state) { - case STATE_MI2S_ACTIVE: + case STATE_ACTIVE: ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_active); + pinctrl_info->active); if (ret) { - pr_err("%s: MI2S state select failed with %d\n", + pr_err("%s: state select to active failed with %d\n", __func__, ret); ret = -EIO; goto err; } break; - case STATE_TDM_ACTIVE: + case STATE_SLEEP: ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->tdm_active); - if (ret) { - pr_err("%s: TDM state select failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - break; - case STATE_DISABLE: - if (curr_state == STATE_MI2S_ACTIVE) { - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_disable); - } else { - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->tdm_disable); - } + pinctrl_info->sleep); if (ret) { - pr_err("%s: state disable failed with %d\n", + pr_err("%s: state select to sleep failed with %d\n", __func__, ret); ret = -EIO; goto err; } break; default: - pr_err("%s: TLMM pin state is invalid\n", __func__); + pr_err("%s: pin state is invalid\n", __func__); return -EINVAL; } @@ -3814,11 +3805,17 @@ static void msm_release_pinctrl(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + struct msm_pinctrl_info *pinctrl_info = NULL; + int i; - if (pinctrl_info->pinctrl) { - devm_pinctrl_put(pinctrl_info->pinctrl); - pinctrl_info->pinctrl = NULL; + for (i = TDM_PRI; i < TDM_INTERFACE_MAX; i++) { + pinctrl_info = &pdata->pinctrl_info[i]; + if (pinctrl_info == NULL) + continue; + if (pinctrl_info->pinctrl) { + devm_pinctrl_put(pinctrl_info->pinctrl); + pinctrl_info->pinctrl = NULL; + } } } @@ -3827,84 +3824,172 @@ static int msm_get_pinctrl(struct platform_device *pdev) struct snd_soc_card *card = platform_get_drvdata(pdev); struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); struct msm_pinctrl_info *pinctrl_info = NULL; - struct pinctrl *pinctrl; - int ret; + struct pinctrl *pinctrl = NULL; + int i, j; + struct device_node *np = NULL; + struct platform_device *pdev_np = NULL; + int ret = 0; - pinctrl_info = &pdata->pinctrl_info; + for (i = TDM_PRI; i < TDM_INTERFACE_MAX; i++) { + np = of_parse_phandle(pdev->dev.of_node, + tdm_gpio_phandle[i], 0); + if (!np) { + pr_debug("%s: device node %s is null\n", + __func__, tdm_gpio_phandle[i]); + continue; + } - if (pinctrl_info == NULL) { - pr_err("%s: pinctrl_info is NULL\n", __func__); - return -EINVAL; - } + pdev_np = of_find_device_by_node(np); + if (!pdev_np) { + pr_err("%s: platform device not found\n", __func__); + continue; + } - pinctrl = devm_pinctrl_get(&pdev->dev); - if (IS_ERR_OR_NULL(pinctrl)) { - pr_err("%s: Unable to get pinctrl handle\n", __func__); - return -EINVAL; - } - pinctrl_info->pinctrl = pinctrl; + pinctrl_info = &pdata->pinctrl_info[i]; + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl info is null\n", __func__); + continue; + } - /* get all the states handles from Device Tree */ - pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl, - "quat_mi2s_disable"); - if (IS_ERR(pinctrl_info->mi2s_disable)) { - pr_err("%s: could not get mi2s_disable pinstate\n", __func__); - goto err; - } - pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl, - "quat_mi2s_enable"); - if (IS_ERR(pinctrl_info->mi2s_active)) { - pr_err("%s: could not get mi2s_active pinstate\n", __func__); - goto err; - } - pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl, - "quat_tdm_disable"); - if (IS_ERR(pinctrl_info->tdm_disable)) { - pr_err("%s: could not get tdm_disable pinstate\n", __func__); - goto err; - } - pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl, - "quat_tdm_enable"); - if (IS_ERR(pinctrl_info->tdm_active)) { - pr_err("%s: could not get tdm_active pinstate\n", - __func__); - goto err; - } - /* Reset the TLMM pins to a default state */ - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_disable); - if (ret != 0) { - pr_err("%s: Disable TLMM pins failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - pinctrl_info->curr_state = STATE_DISABLE; + pinctrl = devm_pinctrl_get(&pdev_np->dev); + if (IS_ERR_OR_NULL(pinctrl)) { + pr_err("%s: fail to get pinctrl handle\n", __func__); + goto err; + } + pinctrl_info->pinctrl = pinctrl; + /* get all the states handles from Device Tree */ + pinctrl_info->sleep = pinctrl_lookup_state(pinctrl, + "sleep"); + if (IS_ERR(pinctrl_info->sleep)) { + pr_err("%s: could not get sleep pin state\n", __func__); + goto err; + } + pinctrl_info->active = pinctrl_lookup_state(pinctrl, + "default"); + if (IS_ERR(pinctrl_info->active)) { + pr_err("%s: could not get active pin state\n", + __func__); + goto err; + } + + /* Reset the TLMM pins to a sleep state */ + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->sleep); + if (ret != 0) { + pr_err("%s: set pin state to sleep failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + pinctrl_info->curr_state = STATE_SLEEP; + } return 0; err: - devm_pinctrl_put(pinctrl); - pinctrl_info->pinctrl = NULL; + for (j = i; j >= 0; j--) { + pinctrl_info = &pdata->pinctrl_info[j]; + if (pinctrl_info == NULL) + continue; + if (pinctrl_info->pinctrl) { + devm_pinctrl_put(pinctrl_info->pinctrl); + pinctrl_info->pinctrl = NULL; + } + } return -EINVAL; } -#else -static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, - enum pinctrl_pin_state new_state) -{ - return 0; -} - -static void msm_release_pinctrl(struct platform_device *pdev) -{ - return; -} -static int msm_get_pinctrl(struct platform_device *pdev) +static int msm_tdm_get_intf_idx(u16 id) { - return 0; + switch (id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + return TDM_PRI; + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + case AFE_PORT_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + return TDM_SEC; + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + case AFE_PORT_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + return TDM_TERT; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + return TDM_QUAT; + case AFE_PORT_ID_QUINARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_RX_1: + case AFE_PORT_ID_QUINARY_TDM_RX_2: + case AFE_PORT_ID_QUINARY_TDM_RX_3: + case AFE_PORT_ID_QUINARY_TDM_RX_4: + case AFE_PORT_ID_QUINARY_TDM_RX_5: + case AFE_PORT_ID_QUINARY_TDM_RX_6: + case AFE_PORT_ID_QUINARY_TDM_RX_7: + case AFE_PORT_ID_QUINARY_TDM_TX: + case AFE_PORT_ID_QUINARY_TDM_TX_1: + case AFE_PORT_ID_QUINARY_TDM_TX_2: + case AFE_PORT_ID_QUINARY_TDM_TX_3: + case AFE_PORT_ID_QUINARY_TDM_TX_4: + case AFE_PORT_ID_QUINARY_TDM_TX_5: + case AFE_PORT_ID_QUINARY_TDM_TX_6: + case AFE_PORT_ID_QUINARY_TDM_TX_7: + return TDM_QUIN; + default: return -EINVAL; + } } -#endif static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) @@ -4640,10 +4725,9 @@ static int sa8155_tdm_snd_hw_params(struct snd_pcm_substream *substream, rate = params_rate(params); clk_freq = rate * slot_width * slots; ret = snd_soc_dai_set_sysclk(cpu_dai, 0, clk_freq, SND_SOC_CLOCK_OUT); - if (ret < 0) { + if (ret < 0) pr_err("%s: failed to set tdm clk, err:%d\n", __func__, ret); - } end: return ret; @@ -4656,37 +4740,76 @@ static int sa8155_tdm_snd_startup(struct snd_pcm_substream *substream) struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + struct msm_pinctrl_info *pinctrl_info = NULL; + struct tdm_conf *intf_conf = NULL; + int ret_pinctrl = 0; + int index; - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || - (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { - ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); - if (ret) + pr_debug("%s: substream = %s, stream = %d, dai name = %s, dai id = %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + index = msm_tdm_get_intf_idx(cpu_dai->id); + if (index < 0) { + ret = -EINVAL; + pr_err("%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto err; + } + + /* + * Mutex protection in case the same TDM + * interface using for both TX and RX so + * that the same clock won't be enable twice. + */ + intf_conf = &pdata->tdm_intf_conf[index]; + mutex_lock(&intf_conf->lock); + if (++intf_conf->ref_cnt == 1) { + pinctrl_info = &pdata->pinctrl_info[index]; + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_ACTIVE); + if (ret_pinctrl) pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret); + __func__, ret_pinctrl); } + mutex_unlock(&intf_conf->lock); +err: return ret; } static void sa8155_tdm_snd_shutdown(struct snd_pcm_substream *substream) { - int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + struct msm_pinctrl_info *pinctrl_info = NULL; + struct tdm_conf *intf_conf = NULL; + int ret_pinctrl = 0; + int index; + + pr_debug("%s: substream = %s, stream = %d\n", __func__, + substream->name, substream->stream); - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || - (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { - ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); - if (ret) + index = msm_tdm_get_intf_idx(cpu_dai->id); + if (index < 0) { + pr_err("%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + return; + } + + intf_conf = &pdata->tdm_intf_conf[index]; + mutex_lock(&intf_conf->lock); + if (--intf_conf->ref_cnt == 0) { + pinctrl_info = &pdata->pinctrl_info[index]; + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_SLEEP); + if (ret_pinctrl) pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret); + __func__, ret_pinctrl); } + mutex_unlock(&intf_conf->lock); } static struct snd_soc_ops sa8155_tdm_be_ops = { @@ -4728,7 +4851,8 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + struct msm_pinctrl_info *pinctrl_info = NULL; + struct mi2s_conf *intf_conf = NULL; int ret_pinctrl = 0; dev_dbg(rtd->card->dev, @@ -4748,10 +4872,11 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) * interface using for both TX and RX so * that the same clock won't be enable twice. */ - mutex_lock(&mi2s_intf_conf[index].lock); - if (++mi2s_intf_conf[index].ref_cnt == 1) { + intf_conf = &pdata->mi2s_intf_conf[index]; + mutex_lock(&intf_conf->lock); + if (++intf_conf->ref_cnt == 1) { /* Check if msm needs to provide the clock to the interface */ - if (!mi2s_intf_conf[index].msm_is_mi2s_master) { + if (!intf_conf->msm_is_mi2s_master) { mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; fmt = SND_SOC_DAIFMT_CBM_CFM; } @@ -4769,21 +4894,21 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) __func__, index, ret); goto clk_off; } - if (index == QUAT_MI2S) { - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_MI2S_ACTIVE); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); - } + + pinctrl_info = &pdata->pinctrl_info[index]; + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_ACTIVE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); } clk_off: if (ret < 0) msm_mi2s_set_sclk(substream, false); clean_up: if (ret < 0) - mi2s_intf_conf[index].ref_cnt--; - mutex_unlock(&mi2s_intf_conf[index].lock); + intf_conf->ref_cnt--; + mutex_unlock(&intf_conf->lock); err: return ret; } @@ -4795,7 +4920,8 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) int index = rtd->cpu_dai->id; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + struct msm_pinctrl_info *pinctrl_info = NULL; + struct mi2s_conf *intf_conf = NULL; int ret_pinctrl = 0; pr_debug("%s(): substream = %s stream = %d\n", __func__, @@ -4805,21 +4931,22 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) return; } - mutex_lock(&mi2s_intf_conf[index].lock); - if (--mi2s_intf_conf[index].ref_cnt == 0) { + intf_conf = &pdata->mi2s_intf_conf[index]; + mutex_lock(&intf_conf->lock); + if (--intf_conf->ref_cnt == 0) { ret = msm_mi2s_set_sclk(substream, false); if (ret < 0) pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", __func__, index, ret); - if (index == QUAT_MI2S) { - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_DISABLE); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); - } + + pinctrl_info = &pdata->pinctrl_info[index]; + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_SLEEP); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); } - mutex_unlock(&mi2s_intf_conf[index].lock); + mutex_unlock(&intf_conf->lock); } static struct snd_soc_ops msm_mi2s_be_ops = { @@ -7053,19 +7180,22 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) /***************************************************************************** * TO BE UPDATED: Codec/Platform specific tdm slot and offset table selection *****************************************************************************/ -static int msm_tdm_init(struct device *dev) +static int msm_tdm_init(struct platform_device *pdev) { + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); const struct of_device_id *match; + int count; - match = of_match_node(sa8155_asoc_machine_of_match, dev->of_node); + match = of_match_node(sa8155_asoc_machine_of_match, pdev->dev.of_node); if (!match) { - dev_err(dev, "%s: No DT match found for sound card\n", + dev_err(&pdev->dev, "%s: No DT match found for sound card\n", __func__); return -EINVAL; } if (!strcmp(match->data, "custom_codec")) { - dev_dbg(dev, "%s: custom tdm configuration\n", __func__); + dev_dbg(&pdev->dev, "%s: custom tdm configuration\n", __func__); memcpy(tdm_rx_slot_offset, tdm_rx_slot_offset_custom, @@ -7077,21 +7207,40 @@ static int msm_tdm_init(struct device *dev) tdm_slot_custom, sizeof(tdm_slot_custom)); } else { - dev_dbg(dev, "%s: default tdm configuration\n", __func__); + dev_dbg(&pdev->dev, "%s: default tdm configuration\n", __func__); + } + + for (count = 0; count < TDM_INTERFACE_MAX; count++) { + mutex_init(&pdata->tdm_intf_conf[count].lock); + pdata->tdm_intf_conf[count].ref_cnt = 0; } return 0; } +static void msm_tdm_deinit(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + int count; + + for (count = 0; count < TDM_INTERFACE_MAX; count++) { + mutex_destroy(&pdata->tdm_intf_conf[count].lock); + pdata->tdm_intf_conf[count].ref_cnt = 0; + } +} + static void msm_i2s_auxpcm_init(struct platform_device *pdev) { + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); int count; u32 mi2s_master_slave[MI2S_MAX]; int ret; for (count = 0; count < MI2S_MAX; count++) { - mutex_init(&mi2s_intf_conf[count].lock); - mi2s_intf_conf[count].ref_cnt = 0; + mutex_init(&pdata->mi2s_intf_conf[count].lock); + pdata->mi2s_intf_conf[count].ref_cnt = 0; } ret = of_property_read_u32_array(pdev->dev.of_node, @@ -7102,20 +7251,22 @@ static void msm_i2s_auxpcm_init(struct platform_device *pdev) __func__); } else { for (count = 0; count < MI2S_MAX; count++) { - mi2s_intf_conf[count].msm_is_mi2s_master = + pdata->mi2s_intf_conf[count].msm_is_mi2s_master = mi2s_master_slave[count]; } } } -static void msm_i2s_auxpcm_deinit(void) +static void msm_i2s_auxpcm_deinit(struct platform_device *pdev) { + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); int count; for (count = 0; count < MI2S_MAX; count++) { - mutex_destroy(&mi2s_intf_conf[count].lock); - mi2s_intf_conf[count].ref_cnt = 0; - mi2s_intf_conf[count].msm_is_mi2s_master = 0; + mutex_destroy(&pdata->mi2s_intf_conf[count].lock); + pdata->mi2s_intf_conf[count].ref_cnt = 0; + pdata->mi2s_intf_conf[count].msm_is_mi2s_master = 0; } } static int msm_asoc_machine_probe(struct platform_device *pdev) @@ -7169,7 +7320,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) card->controls = msm_snd_controls; card->num_controls = ARRAY_SIZE(msm_snd_controls); - ret = msm_tdm_init(&pdev->dev); + ret = msm_tdm_init(pdev); if (ret) { ret = -EPROBE_DEFER; goto err; @@ -7192,7 +7343,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) pr_debug("%s: pinctrl parsing successful\n", __func__); } else { dev_dbg(&pdev->dev, - "%s: Parsing pinctrl failed with %d. Cannot use Ports\n", + "%s: pinctrl parsing failed with %d\n", __func__, ret); ret = 0; } @@ -7208,7 +7359,8 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) static int msm_asoc_machine_remove(struct platform_device *pdev) { - msm_i2s_auxpcm_deinit(); + msm_i2s_auxpcm_deinit(pdev); + msm_tdm_deinit(pdev); msm_release_pinctrl(pdev); return 0; -- GitLab From 51181d078ee1067ad0bc143e1d7c859e6d833a8b Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Fri, 12 Apr 2019 17:03:01 +0530 Subject: [PATCH 1034/1645] ASoC: msm: add slot offset for QUAT and QUIN TDM add channel slot offset for QUAT and QUIN TDM and add backend dai links for QUIN TDMs. Signed-off-by: Rahul Sharma Change-Id: I3f67e33d0b7ea69a000f74363b7b0dc54c50d94c --- asoc/sa6155.c | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/asoc/sa6155.c b/asoc/sa6155.c index 68117e56b7c1..0cd29ac97ba9 100644 --- a/asoc/sa6155.c +++ b/asoc/sa6155.c @@ -410,7 +410,7 @@ static unsigned int tdm_rx_slot_offset {0xFFFF}, /* not used */ }, {/* QUAT TDM */ - {0xFFFF}, /* not used */ + {0, 4, 8, 12, 16, 20, 24, 28, 0xFFFF},/*AMP OUT*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -420,10 +420,10 @@ static unsigned int tdm_rx_slot_offset {0xFFFF}, /* not used */ }, {/* QUIN TDM */ - {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {0, 4, 0xFFFF}, /* not used */ + {8, 12, 0xFFFF}, /* not used */ + {16, 20, 0xFFFF}, /* not used */ + {24, 28, 0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -464,7 +464,8 @@ static unsigned int tdm_tx_slot_offset {0xFFFF}, /* not used */ }, {/* QUAT TDM */ - {0xFFFF}, /* not used */ + {0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*MIC ARR*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -474,7 +475,7 @@ static unsigned int tdm_tx_slot_offset {0xFFFF}, /* not used */ }, {/* QUIN TDM */ - {0xFFFF}, /* not used */ + {0, 4, 8, 12, 16, 20, 0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -5987,6 +5988,35 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .ops = &sa6155_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUIN_TDM_RX_0, + .stream_name = "Quinary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36928", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_TDM_TX_0, + .stream_name = "Quinary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36929", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link msm_auto_be_dai_links[] = { -- GitLab From 1fa4e0449ca1518d80f4c6aebddd7d057961e216 Mon Sep 17 00:00:00 2001 From: Cong Tang Date: Mon, 17 Dec 2018 19:45:55 +0800 Subject: [PATCH 1035/1645] audio-driver: Update build files for LA automotive enable conditional build for audio driver modules for LA automotive. Change-Id: Ifb18ea6f8af531a99e29904c2245424657b42df7 Signed-off-by: Cong Tang --- Android.mk | 9 ++++++++- asoc/Android.mk | 4 ++++ asoc/Kbuild | 21 +++++++++++++++++---- asoc/codecs/Android.mk | 18 ++++++++++++------ asoc/codecs/Kbuild | 12 +++++++++--- asoc/machine_815x_init.c | 4 +--- asoc/machine_815x_init.h | 4 +--- asoc/sa8155.c | 3 +++ config/sa8155auto.conf | 14 ++++++++++++++ config/sa8155autoconf.h | 18 ++++++++++++++++++ dsp/Android.mk | 22 ++++++++++++++-------- dsp/Kbuild | 12 +++++++++--- ipc/Android.mk | 6 ++++++ ipc/Kbuild | 12 +++++++++--- 14 files changed, 125 insertions(+), 34 deletions(-) create mode 100644 config/sa8155auto.conf create mode 100644 config/sa8155autoconf.h diff --git a/Android.mk b/Android.mk index 80334f680034..d1fdc7324849 100644 --- a/Android.mk +++ b/Android.mk @@ -17,20 +17,27 @@ include $(MY_LOCAL_PATH)/include/uapi/Android.mk include $(MY_LOCAL_PATH)/ipc/Android.mk include $(MY_LOCAL_PATH)/dsp/Android.mk include $(MY_LOCAL_PATH)/dsp/codecs/Android.mk -include $(MY_LOCAL_PATH)/soc/Android.mk include $(MY_LOCAL_PATH)/asoc/Android.mk include $(MY_LOCAL_PATH)/asoc/codecs/Android.mk endif ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk endif +endif + +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) +include $(MY_LOCAL_PATH)/soc/Android.mk +endif ifeq ($(call is-board-platform-in-list,msmnile),true) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/aqt1000/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/aqt1000/Android.mk endif +endif ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/bolero/Module.symvers) diff --git a/asoc/Android.mk b/asoc/Android.mk index ca2dffccc47c..1293f5f2fa30 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -5,8 +5,12 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) TARGET := msmnile +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) +AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m +else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif +endif ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) TARGET := talos diff --git a/asoc/Kbuild b/asoc/Kbuild index bf6b58300fbc..4890912a1a28 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -15,9 +15,15 @@ endif ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SM8150), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + ifdef CONFIG_SND_SOC_SA8155 + include $(AUDIO_ROOT)/config/sa8155auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h + else + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif endif ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm6150auto.conf @@ -78,7 +84,6 @@ COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) # for SM8150 sound card driver ifdef CONFIG_SND_SOC_SM8150 - MACHINE_OBJS += sa8155.o MACHINE_OBJS += sm8150.o MACHINE_OBJS += machine_815x_init.o endif @@ -104,6 +109,11 @@ ifdef CONFIG_SND_SOC_LITO MACHINE_OBJS += kona.o endif +# for sa8155 sound card driver +ifdef CONFIG_SND_SOC_SA8155 + MACHINE_OBJS += sa8155.o +endif + ifdef CONFIG_SND_SOC_CPE CPE_LSM_OBJS += msm-cpe-lsm.o endif @@ -205,6 +215,9 @@ machine_dlkm-y := $(MACHINE_OBJS) obj-$(CONFIG_SND_SOC_LITO) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) +obj-$(CONFIG_SND_SOC_SA8155) += machine_dlkm.o +machine_dlkm-y := $(MACHINE_OBJS) + obj-$(CONFIG_SND_SOC_CPE) += cpe_lsm_dlkm.o cpe_lsm_dlkm-y := $(CPE_LSM_OBJS) diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index 539bd55e91e7..145da097dd7a 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -4,8 +4,12 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) +AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m +else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif +endif ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m @@ -52,6 +56,7 @@ KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) KBUILD_OPTIONS += $(AUDIO_SELECT) ########################################################### +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd_core.ko LOCAL_MODULE_KBUILD_NAME := wcd_core_dlkm.ko @@ -107,21 +112,22 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### include $(CLEAR_VARS) -LOCAL_MODULE := $(AUDIO_CHIPSET)_stub.ko -LOCAL_MODULE_KBUILD_NAME := stub_dlkm.ko +LOCAL_MODULE := $(AUDIO_CHIPSET)_mbhc.ko +LOCAL_MODULE_KBUILD_NAME := mbhc_dlkm.ko LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk -########################################################### +endif +############################################################ include $(CLEAR_VARS) -LOCAL_MODULE := $(AUDIO_CHIPSET)_mbhc.ko -LOCAL_MODULE_KBUILD_NAME := mbhc_dlkm.ko +LOCAL_MODULE := $(AUDIO_CHIPSET)_stub.ko +LOCAL_MODULE_KBUILD_NAME := stub_dlkm.ko LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk -########################################################### +########################################################## include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_hdmi.ko LOCAL_MODULE_KBUILD_NAME := hdmi_dlkm.ko diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index e18a40b57d3f..d8d52b344186 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -15,9 +15,15 @@ endif ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SM8150), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + ifdef CONFIG_SND_SOC_SA8155 + include $(AUDIO_ROOT)/config/sa8155auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h + else + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif endif ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm6150auto.conf diff --git a/asoc/machine_815x_init.c b/asoc/machine_815x_init.c index cf8fbed4bf86..dfbf0a7bfbdc 100644 --- a/asoc/machine_815x_init.c +++ b/asoc/machine_815x_init.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. */ #include @@ -10,14 +10,12 @@ static int __init audio_machine_815x_init(void) { sm8150_init(); - sa8155_init(); return 0; } static void audio_machine_815x_exit(void) { sm8150_exit(); - sa8155_exit(); } module_init(audio_machine_815x_init); diff --git a/asoc/machine_815x_init.h b/asoc/machine_815x_init.h index 8ff46101898c..91a399778873 100644 --- a/asoc/machine_815x_init.h +++ b/asoc/machine_815x_init.h @@ -1,14 +1,12 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* -Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. */ #ifndef __MACHINE_815X_INIT_H__ #define __MACHINE_815X_INIT_H__ int sm8150_init(void); -int sa8155_init(void); void sm8150_exit(void); -void sa8155_exit(void); #endif diff --git a/asoc/sa8155.c b/asoc/sa8155.c index e01b2315d514..a3bbbdb09f33 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -7288,6 +7288,9 @@ void sa8155_exit(void) audio_notifier_deregister("sa8155"); } +module_init(sa8155_init); +module_exit(sa8155_exit); + MODULE_DESCRIPTION("ALSA SoC msm"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:" DRV_NAME); diff --git a/config/sa8155auto.conf b/config/sa8155auto.conf new file mode 100644 index 000000000000..e551f77f19dd --- /dev/null +++ b/config/sa8155auto.conf @@ -0,0 +1,14 @@ +CONFIG_MSM_QDSP6_APRV2_RPMSG=m +CONFIG_MSM_QDSP6_SSR=m +CONFIG_MSM_ADSP_LOADER=m +CONFIG_MSM_QDSP6_NOTIFIER=m +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +CONFIG_SND_SOC_QDSP6V2=m +CONFIG_QTI_PP=m +CONFIG_SND_HWDEP_ROUTING=m +CONFIG_DTS_EAGLE=m +CONFIG_DOLBY_DS2=m +CONFIG_DOLBY_LICENSE=m +CONFIG_SND_SOC_MSM_STUB=m +CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m +CONFIG_MSM_QDSP6V2_CODECS=m diff --git a/config/sa8155autoconf.h b/config/sa8155autoconf.h new file mode 100644 index 000000000000..3f9eda2c910e --- /dev/null +++ b/config/sa8155autoconf.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#define CONFIG_MSM_QDSP6_APRV2_RPMSG 1 +#define CONFIG_MSM_QDSP6_SSR 1 +#define CONFIG_MSM_ADSP_LOADER 1 +#define CONFIG_MSM_QDSP6_NOTIFIER 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_SND_SOC_QDSP6V2 1 +#define CONFIG_QTI_PP 1 +#define CONFIG_SND_HWDEP_ROUTING 1 +#define CONFIG_DTS_EAGLE 1 +#define CONFIG_DOLBY_DS2 1 +#define CONFIG_DOLBY_LICENSE 1 +#define CONFIG_SND_SOC_MSM_STUB 1 +#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 +#define CONFIG_MSM_QDSP6V2_CODECS 1 diff --git a/dsp/Android.mk b/dsp/Android.mk index 42fd4cb8ea7b..20f346317ebc 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -4,8 +4,12 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) +AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m +else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif +endif ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m @@ -57,29 +61,30 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### include $(CLEAR_VARS) -LOCAL_MODULE := $(AUDIO_CHIPSET)_usf.ko -LOCAL_MODULE_KBUILD_NAME := usf_dlkm.ko +LOCAL_MODULE := $(AUDIO_CHIPSET)_adsp_loader.ko +LOCAL_MODULE_KBUILD_NAME := adsp_loader_dlkm.ko LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### include $(CLEAR_VARS) -LOCAL_MODULE := $(AUDIO_CHIPSET)_adsp_loader.ko -LOCAL_MODULE_KBUILD_NAME := adsp_loader_dlkm.ko +LOCAL_MODULE := $(AUDIO_CHIPSET)_q6_notifier.ko +LOCAL_MODULE_KBUILD_NAME := q6_notifier_dlkm.ko LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk -########################################################### +############################################################ +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) include $(CLEAR_VARS) -LOCAL_MODULE := $(AUDIO_CHIPSET)_q6_notifier.ko -LOCAL_MODULE_KBUILD_NAME := q6_notifier_dlkm.ko +LOCAL_MODULE := $(AUDIO_CHIPSET)_usf.ko +LOCAL_MODULE_KBUILD_NAME := usf_dlkm.ko LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk -########################################################### +########################################################## include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_q6_pdr.ko LOCAL_MODULE_KBUILD_NAME := q6_pdr_dlkm.ko @@ -87,6 +92,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk +endif ########################################################### ########################################################### diff --git a/dsp/Kbuild b/dsp/Kbuild index 7d683b35f923..cd826c530f40 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -34,9 +34,15 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + ifdef CONFIG_SND_SOC_SA8155 + include $(AUDIO_ROOT)/config/sa8155auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h + else + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf diff --git a/ipc/Android.mk b/ipc/Android.mk index 800d8d4b8919..e3374eadc02b 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -4,8 +4,12 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) +AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m +else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif +endif ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m @@ -57,6 +61,7 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wglink.ko LOCAL_MODULE_KBUILD_NAME := wglink_dlkm.ko @@ -65,6 +70,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk endif +endif ########################################################### endif # DLKM check diff --git a/ipc/Kbuild b/ipc/Kbuild index 5ab0131b493b..30afc60c6cfd 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -35,9 +35,15 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + ifdef CONFIG_SND_SOC_SA8155 + include $(AUDIO_ROOT)/config/sa8155auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h + else + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif endif ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf -- GitLab From fe8dee2aa22a257bbde8e8e59a0b20490336158d Mon Sep 17 00:00:00 2001 From: Cong Tang Date: Thu, 10 Jan 2019 18:36:55 +0800 Subject: [PATCH 1036/1645] audio-driver: update Makefile.am for LV update Makefile.am for automotive LV audio driver build. Change-Id: I1ad1a3de85fdb09818b8c1774919872b619dd0fd Signed-off-by: Cong Tang --- Makefile.am | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Makefile.am b/Makefile.am index 7ee55c0d236c..b705366b6c23 100644 --- a/Makefile.am +++ b/Makefile.am @@ -37,6 +37,14 @@ obj-m += asoc/codecs/bolero/ obj-m += asoc/codecs/wcd937x/ endif +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155)) +obj-m := ipc/ +obj-m += dsp/ +obj-m += asoc/ +obj-m += asoc/codecs/ +KBUILD_OPTIONS += CONFIG_SND_SOC_SA8155=m +endif + all: $(shell rm -fr $(shell pwd)/soc/core.h) $(shell ln -s $(KERNEL_SRC)/drivers/pinctrl/core.h $(shell pwd)/soc/core.h) -- GitLab From 8e1a34cacd72cfea3afa12c24b626d0cf68ed9c3 Mon Sep 17 00:00:00 2001 From: Han Lu Date: Mon, 7 Jan 2019 16:41:01 +0800 Subject: [PATCH 1037/1645] asoc: sa8155: Add Quinary TDM backend DAI link Add backend DAI to support basic playback and record via Quinary TDM port. Change-Id: Ia23411fc57da011f9d9c12db17bd64d1a24a06b8 Signed-off-by: Han Lu --- asoc/sa8155.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/asoc/sa8155.c b/asoc/sa8155.c index e01b2315d514..672daf12d701 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -6094,6 +6094,35 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .ops = &sa8155_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUIN_TDM_RX_0, + .stream_name = "Quinary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36928", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_TDM_TX_0, + .stream_name = "Quinary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36929", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link msm_auto_be_dai_links[] = { -- GitLab From 5f0a52cccdf71f81f882c53c442591bdc40b4b65 Mon Sep 17 00:00:00 2001 From: Timothy Sham Date: Mon, 11 Mar 2019 12:17:06 -0400 Subject: [PATCH 1038/1645] audio-driver: dsp: Adapt to non sys heap support for GVM Adapt to non sys heap support for SMMU FE driver on GVM of automotive. Change-Id: I67f5ca511cea1a7a5c1615868b5b2d74e6b22dac Signed-off-by: Timothy Sham --- dsp/msm_audio_ion_vm.c | 313 ++++++++++++++++++++++++----------------- 1 file changed, 184 insertions(+), 129 deletions(-) diff --git a/dsp/msm_audio_ion_vm.c b/dsp/msm_audio_ion_vm.c index cd3122e6bfdc..aba015091d5e 100644 --- a/dsp/msm_audio_ion_vm.c +++ b/dsp/msm_audio_ion_vm.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,7 @@ #include #include #include +#include #include #define MSM_AUDIO_ION_PROBED (1 << 0) @@ -32,6 +34,11 @@ #define MSM_AUDIO_SMMU_VM_CMD_UNMAP 0x00000002 #define MSM_AUDIO_SMMU_VM_HAB_MINOR_ID 1 +enum msm_audio_mem_type{ + MSM_AUDIO_MEM_TYPE_ION, + MSM_AUDIO_MEM_TYPE_DMA, +}; + struct msm_audio_ion_private { bool smmu_enabled; struct device *cb_dev; @@ -43,10 +50,12 @@ struct msm_audio_ion_private { struct msm_audio_alloc_data { size_t len; void *vaddr; - struct dma_buf *dma_buf; + void *handle; struct dma_buf_attachment *attach; struct sg_table *table; struct list_head list; + dma_addr_t *paddr; + enum msm_audio_mem_type type; u32 export_id; }; @@ -88,7 +97,30 @@ static void msm_audio_ion_add_allocation( mutex_unlock(&(msm_audio_ion_data->list_mutex)); } -static int msm_audio_dma_buf_map(struct dma_buf *dma_buf, +static int msm_audio_dma_buf_map(void *handle, void *vaddr, + dma_addr_t *paddr, + size_t *len) +{ + struct msm_audio_alloc_data *alloc_data; + + /* Data required per buffer mapping */ + alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL); + if (!alloc_data) + return -ENOMEM; + + alloc_data->handle = handle; + alloc_data->len = *len; + alloc_data->vaddr = vaddr; + alloc_data->paddr = paddr; + alloc_data->type = MSM_AUDIO_MEM_TYPE_DMA; + + msm_audio_ion_add_allocation(&msm_audio_ion_data, + alloc_data); + + return 0; +} + +static int msm_audio_ion_dma_buf_map(struct dma_buf *dma_buf, dma_addr_t *addr, size_t *len) { @@ -104,13 +136,13 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf, if (!alloc_data) return -ENOMEM; - alloc_data->dma_buf = dma_buf; + alloc_data->handle = (void*)dma_buf; alloc_data->len = dma_buf->size; + alloc_data->type = MSM_AUDIO_MEM_TYPE_ION; *len = dma_buf->size; /* Attach the dma_buf to context bank device */ - alloc_data->attach = dma_buf_attach(alloc_data->dma_buf, - cb_dev); + alloc_data->attach = dma_buf_attach(dma_buf, cb_dev); if (IS_ERR(alloc_data->attach)) { rc = PTR_ERR(alloc_data->attach); dev_err(cb_dev, @@ -120,7 +152,7 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf, } /* For uncached buffers, avoid cache maintanance */ - rc = dma_buf_get_flags(alloc_data->dma_buf, &ionflag); + rc = dma_buf_get_flags(dma_buf, &ionflag); if (rc) { dev_err(cb_dev, "%s: dma_buf_get_flags failed: %d\n", __func__, rc); @@ -148,21 +180,46 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf, /* physical address from mapping */ *addr = MSM_AUDIO_ION_PHYS_ADDR(alloc_data); - + alloc_data->paddr = addr; msm_audio_ion_add_allocation(&msm_audio_ion_data, alloc_data); return rc; detach_dma_buf: - dma_buf_detach(alloc_data->dma_buf, - alloc_data->attach); + dma_buf_detach(dma_buf, alloc_data->attach); free_alloc_data: kfree(alloc_data); return rc; } -static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf) +static int msm_audio_ion_unmap_kernel(void *vaddr, void *handle) +{ + int rc = 0; + struct device *cb_dev = msm_audio_ion_data.cb_dev; + + if (!vaddr) { + dev_err(cb_dev, + "%s: cannot find allocation for handle %pK\n", + __func__, handle); + rc = -EINVAL; + goto err; + } + + dma_buf_vunmap((struct dma_buf*)handle, vaddr); + + rc = dma_buf_end_cpu_access((struct dma_buf*)handle, DMA_BIDIRECTIONAL); + if (rc) { + dev_err(cb_dev, "%s: kmap dma_buf_end_cpu_access fail\n", + __func__); + goto err; + } + +err: + return rc; +} + +static int msm_audio_dma_buf_unmap(void *handle) { int rc = 0; struct msm_audio_alloc_data *alloc_data = NULL; @@ -176,41 +233,68 @@ static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf) * on adding elements to the list. */ mutex_lock(&(msm_audio_ion_data.list_mutex)); - list_for_each_safe(ptr, next, - &(msm_audio_ion_data.alloc_list)) { + list_for_each_safe(ptr, next, &(msm_audio_ion_data.alloc_list)) { + + alloc_data = list_entry(ptr, struct msm_audio_alloc_data, list); + if(alloc_data->type == MSM_AUDIO_MEM_TYPE_ION) { + if (alloc_data->handle == handle) { + rc = msm_audio_ion_unmap_kernel( + alloc_data->vaddr, + handle); + if(rc) { + pr_err("%s: Unable to unmap ion mem rc: %d\n", + __func__, rc); + mutex_unlock(&(msm_audio_ion_data.list_mutex)); + return rc; + } - alloc_data = list_entry(ptr, struct msm_audio_alloc_data, - list); + found = true; + dma_buf_unmap_attachment(alloc_data->attach, + alloc_data->table, + DMA_BIDIRECTIONAL); - if (alloc_data->dma_buf == dma_buf) { - found = true; - dma_buf_unmap_attachment(alloc_data->attach, - alloc_data->table, - DMA_BIDIRECTIONAL); + dma_buf_detach((struct dma_buf*) + alloc_data->handle, + alloc_data->attach); - dma_buf_detach(alloc_data->dma_buf, - alloc_data->attach); + dma_buf_put((struct dma_buf*) + alloc_data->handle); - dma_buf_put(alloc_data->dma_buf); + list_del(&(alloc_data->list)); + kfree(alloc_data); + break; + } + } else { + alloc_data = list_entry(ptr, + struct msm_audio_alloc_data, + list); - list_del(&(alloc_data->list)); - kfree(alloc_data); - break; + if (alloc_data->handle == handle) { + found = true; + + dma_free_coherent(cb_dev, alloc_data->len, + alloc_data->vaddr, + *(alloc_data->paddr)); + + list_del(&(alloc_data->list)); + kfree(alloc_data); + break; + } } } mutex_unlock(&(msm_audio_ion_data.list_mutex)); if (!found) { dev_err(cb_dev, - "%s: cannot find allocation, dma_buf %pK", - __func__, dma_buf); + "%s: cannot find allocation, handle %pK", + __func__, handle); rc = -EINVAL; } return rc; } -static int msm_audio_ion_smmu_map(struct dma_buf *dma_buf, +static int msm_audio_ion_smmu_map(void *handle, dma_addr_t *paddr, size_t *len) { int rc; @@ -224,12 +308,12 @@ static int msm_audio_ion_smmu_map(struct dma_buf *dma_buf, unsigned long delay = jiffies + (HZ / 2); void *vaddr; - *len = dma_buf->size; + *len = ((struct dma_buf*)handle)->size; mutex_lock(&(msm_audio_ion_data.list_mutex)); list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list), list) { - if (alloc_data->dma_buf == dma_buf) { + if (alloc_data->handle == handle) { found = true; vaddr = alloc_data->vaddr; @@ -292,7 +376,7 @@ static int msm_audio_ion_smmu_map(struct dma_buf *dma_buf, mutex_unlock(&(msm_audio_ion_data.list_mutex)); if (!found) { - pr_err("%s: cannot find allocation, dma_buf %pK", __func__, dma_buf); + pr_err("%s: cannot find allocation, handle %pK\n", __func__, handle); return -EINVAL; } @@ -306,7 +390,7 @@ static int msm_audio_ion_smmu_map(struct dma_buf *dma_buf, return rc; } -static int msm_audio_ion_smmu_unmap(struct dma_buf *dma_buf) +static int msm_audio_ion_smmu_unmap(void *handle) { int rc; bool found = false; @@ -325,7 +409,7 @@ static int msm_audio_ion_smmu_unmap(struct dma_buf *dma_buf) list_for_each_entry_safe(alloc_data, next, &(msm_audio_ion_data.alloc_list), list) { - if (alloc_data->dma_buf == dma_buf) { + if (alloc_data->handle == handle) { found = true; smmu_unmap_cmd.cmd_id = MSM_AUDIO_SMMU_VM_CMD_UNMAP; smmu_unmap_cmd.export_id = alloc_data->export_id; @@ -381,7 +465,7 @@ static int msm_audio_ion_smmu_unmap(struct dma_buf *dma_buf) mutex_unlock(&(msm_audio_ion_data.list_mutex)); if (!found) { - pr_err("%s: cannot find allocation, dma_buf %pK\n", __func__, dma_buf); + pr_err("%s: cannot find allocation, handle %pK\n", __func__, handle); rc = -EINVAL; } @@ -404,31 +488,32 @@ static int msm_audio_ion_get_phys(struct dma_buf *dma_buf, { int rc = 0; - rc = msm_audio_dma_buf_map(dma_buf, addr, len); + rc = msm_audio_ion_dma_buf_map(dma_buf, addr, len); if (rc) { pr_err("%s: failed to map DMA buf, err = %d\n", __func__, rc); goto err; } - pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc); + pr_debug("phys=%pK, len=%zd, rc=%d\n", addr, *len, rc); err: return rc; } -static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf) +static void *msm_audio_ion_map_kernel(void *handle) { int rc = 0; void *addr = NULL; struct msm_audio_alloc_data *alloc_data = NULL; - rc = dma_buf_begin_cpu_access(dma_buf, DMA_BIDIRECTIONAL); + rc = dma_buf_begin_cpu_access((struct dma_buf*)handle, + DMA_BIDIRECTIONAL); if (rc) { pr_err("%s: kmap dma_buf_begin_cpu_access fail\n", __func__); goto exit; } - addr = dma_buf_vmap(dma_buf); + addr = dma_buf_vmap((struct dma_buf*)handle); if (!addr) { pr_err("%s: kernel mapping of dma_buf failed\n", __func__); @@ -442,7 +527,7 @@ static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf) mutex_lock(&(msm_audio_ion_data.list_mutex)); list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list), list) { - if (alloc_data->dma_buf == dma_buf) { + if (alloc_data->handle == handle) { alloc_data->vaddr = addr; break; } @@ -453,61 +538,19 @@ static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf) return addr; } -static int msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf) -{ - int rc = 0; - void *vaddr = NULL; - struct msm_audio_alloc_data *alloc_data = NULL; - struct device *cb_dev = msm_audio_ion_data.cb_dev; - - /* - * TBD: remove the below section once new API - * for unmapping kernel virtual address is available. - */ - mutex_lock(&(msm_audio_ion_data.list_mutex)); - list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list), - list) { - if (alloc_data->dma_buf == dma_buf) { - vaddr = alloc_data->vaddr; - break; - } - } - mutex_unlock(&(msm_audio_ion_data.list_mutex)); - - if (!vaddr) { - dev_err(cb_dev, - "%s: cannot find allocation for dma_buf %pK", - __func__, dma_buf); - rc = -EINVAL; - goto err; - } - - dma_buf_vunmap(dma_buf, vaddr); - - rc = dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL); - if (rc) { - dev_err(cb_dev, "%s: kmap dma_buf_end_cpu_access fail\n", - __func__); - goto err; - } - -err: - return rc; -} - -static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr, +static int msm_audio_ion_map_buf(void *handle, dma_addr_t *paddr, size_t *plen, void **vaddr) { int rc = 0; - rc = msm_audio_ion_get_phys(dma_buf, paddr, plen); + rc = msm_audio_ion_get_phys((struct dma_buf*) handle, paddr, plen); if (rc) { pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", __func__, rc); goto err; } - *vaddr = msm_audio_ion_map_kernel(dma_buf); + *vaddr = msm_audio_ion_map_kernel(handle); if (IS_ERR_OR_NULL(*vaddr)) { pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); rc = -ENOMEM; @@ -515,7 +558,7 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr, } if (msm_audio_ion_data.smmu_enabled) { - rc = msm_audio_ion_smmu_map(dma_buf, paddr, plen); + rc = msm_audio_ion_smmu_map(handle, paddr, plen); if (rc) { pr_err("%s: failed to do smmu map, err = %d\n", __func__, rc); @@ -530,7 +573,8 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr, * msm_audio_ion_alloc - * Allocs ION memory for given client name * - * @dma_buf: dma_buf for the ION memory + * @handle: generic handle to the memory allocation + * dma_buf for the system heap memory. vaddr for audio heap memory. * @bufsz: buffer size * @paddr: Physical address to be assigned with allocated region * @plen: length of allocated region to be assigned @@ -538,7 +582,7 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr, * * Returns 0 on success or error on failure */ -int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, +int msm_audio_ion_alloc(void **handle, size_t bufsz, dma_addr_t *paddr, size_t *plen, void **vaddr) { int rc = -EINVAL; @@ -548,31 +592,49 @@ int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, pr_debug("%s:probe is not done, deferred\n", __func__); return -EPROBE_DEFER; } - if (!dma_buf || !paddr || !vaddr || !bufsz || !plen) { + if (!handle || !paddr || !vaddr || !bufsz || !plen) { pr_err("%s: Invalid params\n", __func__); return -EINVAL; } if (msm_audio_ion_data.smmu_enabled == true) { pr_debug("%s: system heap is used\n", __func__); - *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_HEAP_ID), 0); + *handle = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_HEAP_ID), 0); } else { pr_debug("%s: audio heap is used\n", __func__); - *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_AUDIO_HEAP_ID), 0); + *vaddr = *handle = dma_alloc_coherent( + msm_audio_ion_data.cb_dev, + bufsz, paddr, GFP_KERNEL); + if(*vaddr != NULL) { + pr_err("%s: vaddr = %pK, size=%zd\n", __func__, *vaddr, + bufsz); + rc = 0; + } } - if (IS_ERR_OR_NULL((void *)(*dma_buf))) { - if (IS_ERR((void *)(*dma_buf))) - err_ion_ptr = PTR_ERR((int *)(*dma_buf)); + if (IS_ERR_OR_NULL((void *)(*handle))) { + if (IS_ERR((void *)(*handle))) + err_ion_ptr = PTR_ERR((int *)(*handle)); pr_err("%s: ION alloc fail err ptr=%ld, smmu_enabled=%d\n", __func__, err_ion_ptr, msm_audio_ion_data.smmu_enabled); rc = -ENOMEM; goto err; } - - rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr); - if (rc) { - pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc); - goto err_dma_buf; + if (msm_audio_ion_data.smmu_enabled) { + rc = msm_audio_ion_map_buf(*handle, paddr, plen, vaddr); + if (rc) { + pr_err("%s: failed to map ION buf, rc = %d\n", __func__, + rc); + dma_buf_put((struct dma_buf*) *handle); + } + } else { + rc = msm_audio_dma_buf_map(*handle, *vaddr, paddr, + &bufsz); + if (rc) { + pr_err("%s: failed to map ION buf, rc = %d\n", __func__, + rc); + dma_free_coherent(msm_audio_ion_data.cb_dev, + bufsz, vaddr, *paddr); + } } pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, *vaddr, bufsz); @@ -580,9 +642,6 @@ int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, memset(*vaddr, 0, bufsz); return rc; - -err_dma_buf: - dma_buf_put(*dma_buf); err: return rc; } @@ -592,7 +651,8 @@ EXPORT_SYMBOL(msm_audio_ion_alloc); * msm_audio_ion_import- * Import ION buffer with given file descriptor * - * @dma_buf: dma_buf for the ION memory + * @handle: generic handle to the memory allocation + * dma_buf for the system heap memory. vaddr for audio heap memory. * @fd: file descriptor for the ION memory * @ionflag: flags associated with ION buffer * @bufsz: buffer size @@ -602,7 +662,7 @@ EXPORT_SYMBOL(msm_audio_ion_alloc); * * Returns 0 on success or error on failure */ -int msm_audio_ion_import(struct dma_buf **dma_buf, int fd, +int msm_audio_ion_import(void **handle, int fd, unsigned long *ionflag, size_t bufsz, dma_addr_t *paddr, size_t *plen, void **vaddr) { @@ -613,22 +673,22 @@ int msm_audio_ion_import(struct dma_buf **dma_buf, int fd, return -EPROBE_DEFER; } - if (!dma_buf || !paddr || !vaddr || !plen) { + if (!handle || !paddr || !vaddr || !plen) { pr_err("%s: Invalid params\n", __func__); return -EINVAL; } /* bufsz should be 0 and fd shouldn't be 0 as of now */ - *dma_buf = dma_buf_get(fd); - pr_debug("%s: dma_buf =%pK, fd=%d\n", __func__, *dma_buf, fd); - if (IS_ERR_OR_NULL((void *)(*dma_buf))) { + *handle = dma_buf_get(fd); + pr_debug("%s: handle =%pK, fd=%d\n", __func__, *handle, fd); + if (IS_ERR_OR_NULL((void *)(*handle))) { pr_err("%s: dma_buf_get failed\n", __func__); rc = -EINVAL; goto err; } if (ionflag != NULL) { - rc = dma_buf_get_flags(*dma_buf, ionflag); + rc = dma_buf_get_flags((struct dma_buf*)*handle, ionflag); if (rc) { pr_err("%s: could not get flags for the dma_buf\n", __func__); @@ -636,7 +696,7 @@ int msm_audio_ion_import(struct dma_buf **dma_buf, int fd, } } - rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr); + rc = msm_audio_ion_map_buf(*handle, paddr, plen, vaddr); if (rc) { pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc); goto err_ion_flag; @@ -647,9 +707,9 @@ int msm_audio_ion_import(struct dma_buf **dma_buf, int fd, return 0; err_ion_flag: - dma_buf_put(*dma_buf); + dma_buf_put((struct dma_buf*) *handle); err: - *dma_buf = NULL; + *handle = NULL; return rc; } EXPORT_SYMBOL(msm_audio_ion_import); @@ -658,31 +718,28 @@ EXPORT_SYMBOL(msm_audio_ion_import); * msm_audio_ion_free - * fress ION memory for given client and handle * - * @dma_buf: dma_buf for the ION memory + * @handle: generic handle to the memory allocation + * dma_buf for the system heap memory. vaddr for audio heap memory. * * Returns 0 on success or error on failure */ -int msm_audio_ion_free(struct dma_buf *dma_buf) +int msm_audio_ion_free(void *handle) { int ret = 0; - if (!dma_buf) { - pr_err("%s: dma_buf invalid\n", __func__); + if (!handle) { + pr_err("%s: handle invalid\n", __func__); return -EINVAL; } - ret = msm_audio_ion_unmap_kernel(dma_buf); - if (ret) - return ret; - if (msm_audio_ion_data.smmu_enabled) { - ret = msm_audio_ion_smmu_unmap(dma_buf); + ret = msm_audio_ion_smmu_unmap(handle); if (ret) pr_err("%s: smmu unmap failed with ret %d\n", __func__, ret); } - msm_audio_dma_buf_unmap(dma_buf); + msm_audio_dma_buf_unmap(handle); return 0; } @@ -714,7 +771,7 @@ int msm_audio_ion_mmap(struct audio_buffer *abuff, mutex_lock(&(msm_audio_ion_data.list_mutex)); list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list), list) { - if (alloc_data->dma_buf == abuff->dma_buf) { + if (alloc_data->handle == abuff->mem_handle) { found = true; table = alloc_data->table; break; @@ -725,7 +782,7 @@ int msm_audio_ion_mmap(struct audio_buffer *abuff, if (!found) { dev_err(cb_dev, "%s: cannot find allocation, dma_buf %pK", - __func__, abuff->dma_buf); + __func__, abuff->mem_handle); return -EINVAL; } /* uncached */ @@ -831,14 +888,13 @@ static int msm_audio_ion_probe(struct platform_device *pdev) dev_info(dev, "%s: msm_audio_ion_hab_handle %x\n", __func__, msm_audio_ion_hab_handle); - INIT_LIST_HEAD(&msm_audio_ion_data.alloc_list); - mutex_init(&(msm_audio_ion_data.list_mutex)); - exit: if (!rc) msm_audio_ion_data.device_status |= MSM_AUDIO_ION_PROBED; msm_audio_ion_data.cb_dev = dev; + INIT_LIST_HEAD(&msm_audio_ion_data.alloc_list); + mutex_init(&(msm_audio_ion_data.list_mutex)); return rc; } @@ -848,11 +904,10 @@ static int msm_audio_ion_remove(struct platform_device *pdev) if (msm_audio_ion_data.smmu_enabled) { if (msm_audio_ion_hab_handle) habmm_socket_close(msm_audio_ion_hab_handle); - - mutex_destroy(&(msm_audio_ion_data.list_mutex)); } msm_audio_ion_data.smmu_enabled = 0; msm_audio_ion_data.device_status = 0; + mutex_destroy(&(msm_audio_ion_data.list_mutex)); return 0; } -- GitLab From 296867b4164049f87e18d5cbf64ada966efd7211 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 20 Jun 2019 09:24:09 +0530 Subject: [PATCH 1039/1645] ASoC: bolero: tx-macro: Update VA macro clock sequence Update VA macro clock sequence for headset detection during voice activation usecase to avoid soundwire bus clash interrupts. Change-Id: Ic004d43aef9c8a9003b3028c122e6fb6a06fa58d Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/tx-macro.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index c6cd78c23c30..af81fe588c73 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1519,6 +1519,8 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, __func__); goto done; } + bolero_clk_rsc_fs_gen_request(tx_priv->dev, + true); if (tx_priv->tx_mclk_users == 0) { regmap_update_bits(regmap, BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK, @@ -1580,6 +1582,8 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x00); } + bolero_clk_rsc_fs_gen_request(tx_priv->dev, + false); ret = bolero_clk_rsc_request_clock(tx_priv->dev, TX_CORE_CLK, VA_CORE_CLK, @@ -2072,6 +2076,7 @@ static int tx_macro_probe(struct platform_device *pdev) pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); + pm_suspend_ignore_children(&pdev->dev, true); pm_runtime_enable(&pdev->dev); return 0; -- GitLab From 9584db3c2d9b5244b5fdf42ec38f934fff96c1b9 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 21 Jun 2019 13:03:02 +0530 Subject: [PATCH 1040/1645] asoc: codecs: Fix NULL pointer dereference in wcd9xxx slim probe When slim device is NULL or pdata allocation fails in wcd9xxx slim probe, devm_kfree uses slim device leading to a NULL pointer dereference. Fix this by returning from probe in these scenarios. Change-Id: I232661d8ba0320469bc4486e7dd82713e9b53d73 Signed-off-by: Aditya Bavanari --- asoc/codecs/wcd9xxx-core.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index fd2e933520df..0665ba695d39 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -1284,19 +1284,15 @@ static int wcd9xxx_slim_probe(struct slim_device *slim) int ret = 0; int intf_type; + if (!slim) + return -EINVAL; + intf_type = wcd9xxx_get_intf_type(); wcd9xxx = devm_kzalloc(&slim->dev, sizeof(struct wcd9xxx), GFP_KERNEL); - if (!wcd9xxx) { - ret = -ENOMEM; - goto err; - } - - if (!slim) { - ret = -EINVAL; - goto err; - } + if (!wcd9xxx) + return -ENOMEM; if (intf_type == WCD9XXX_INTERFACE_TYPE_I2C) { dev_dbg(&slim->dev, "%s:Codec is detected in I2C mode\n", -- GitLab From 8aacfcf7abe5dbfa36841216fe4dd5e166bdada3 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 21 Jun 2019 15:56:39 +0530 Subject: [PATCH 1041/1645] asoc: codecs: Fix out of bounds access in register show functions In register show functions, when snprintf returns a negative value out of bounds access occurs while copying the data to user. Add return value check on snprintf before copy_to_user to fix this. Change-Id: I1eb793721c653bf6d1fbd10f4cea3436ffe6f519 Signed-off-by: Aditya Bavanari --- asoc/codecs/wcd9xxx-core.c | 5 +++++ asoc/codecs/wsa881x.c | 8 +++++++- soc/swr-wcd-ctrl.c | 6 ++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index fd2e933520df..9e92ae087fc4 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -709,6 +709,11 @@ static ssize_t wcd9xxx_slimslave_reg_show(char __user *ubuf, size_t count, reg_val = wcd9xxx_interface_reg_read(debugCodec, i); len = snprintf(tmp_buf, sizeof(tmp_buf), "0x%.3x: 0x%.2x\n", i, reg_val); + if (len < 0) { + pr_err("%s: fail to fill the buffer\n", __func__); + total = -EFAULT; + goto copy_err; + } if ((total + len) >= count - 1) break; diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index f98de2e19373..2871ad351206 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -105,7 +105,7 @@ struct wsa881x_priv { #define SWR_SLV_MAX_REG_ADDR 0x390 #define SWR_SLV_START_REG_ADDR 0x40 -#define SWR_SLV_MAX_BUF_LEN 20 +#define SWR_SLV_MAX_BUF_LEN 25 #define BYTES_PER_LINE 12 #define SWR_SLV_RD_BUF_LEN 8 #define SWR_SLV_WR_BUF_LEN 32 @@ -393,6 +393,12 @@ static ssize_t wsa881x_swrslave_reg_show(char __user *ubuf, size_t count, i, ®_val, 1); len = snprintf(tmp_buf, 25, "0x%.3x: 0x%.2x\n", i, (reg_val & 0xFF)); + if (len < 0) { + pr_err("%s: fail to fill the buffer\n", __func__); + total = -EFAULT; + goto copy_err; + } + if ((total + len) >= count - 1) break; if (copy_to_user((ubuf + total), tmp_buf, len)) { diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c index f38085f24b0d..66409f8cec91 100644 --- a/soc/swr-wcd-ctrl.c +++ b/soc/swr-wcd-ctrl.c @@ -265,6 +265,12 @@ static ssize_t swrm_reg_show(char __user *ubuf, size_t count, i <= SWR_MSTR_MAX_REG_ADDR; i += 4) { reg_val = dbgswrm->read(dbgswrm->handle, i); len = snprintf(tmp_buf, 25, "0x%.3x: 0x%.2x\n", i, reg_val); + if (len < 0) { + pr_err("%s: fail to fill the buffer\n", __func__); + total = -EFAULT; + goto copy_err; + } + if ((total + len) >= count - 1) break; if (copy_to_user((ubuf + total), tmp_buf, len)) { -- GitLab From c14c27a7c6e864683e888b69050e245906bf935c Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 21 Jun 2019 14:11:34 -0700 Subject: [PATCH 1042/1645] asoc: codecs: bolero: add compander soft reset event Add compander soft reset event that can be requested from a slave codec to reset at power down to reduce click and pop noise. Change-Id: I2f6ff182e258e02979166b0e76b6a1d439b1cf87 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/bolero-cdc.c | 6 ++++++ asoc/codecs/bolero/bolero-cdc.h | 3 ++- asoc/codecs/bolero/internal.h | 1 + asoc/codecs/bolero/rx-macro.c | 15 +++++++++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index bc795cfee060..c0c51ca5826b 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -208,6 +208,12 @@ static int bolero_cdc_update_wcd_event(void *handle, u16 event, u32 data) priv->component, BOLERO_MACRO_EVT_IMPED_FALSE, data); break; + case WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST: + if (priv->macro_params[RX_MACRO].event_handler) + priv->macro_params[RX_MACRO].event_handler( + priv->component, + BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST, data); + break; default: dev_err(priv->dev, "%s: Invalid event %d trigger from wcd\n", __func__, event); diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 3bb82b97f2b1..362b521849af 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -39,7 +39,8 @@ enum { BOLERO_MACRO_EVT_SSR_UP, BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET, BOLERO_MACRO_EVT_CLK_RESET, - BOLERO_MACRO_EVT_REG_WAKE_IRQ + BOLERO_MACRO_EVT_REG_WAKE_IRQ, + BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST }; struct macro_ops { diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index d07c5b1fd690..21c96520c4ee 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -29,6 +29,7 @@ enum { WCD_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */ WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */ WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */ + WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST, }; struct wcd_ctrl_platform_data { diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 285324d9ad9a..b888e45940db 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1208,6 +1208,17 @@ static int rx_macro_event_handler(struct snd_soc_component *component, snd_soc_component_update_bits(component, reg_mix, 0x10, val); break; + case BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST: + rx_idx = data >> 0x10; + if (rx_idx == INTERP_AUX) + goto done; + reg = BOLERO_CDC_RX_COMPANDER0_CTL0 + + (rx_idx * RX_MACRO_COMP_OFFSET); + snd_soc_component_update_bits(component, reg, + 0x20, 0x20); + snd_soc_component_update_bits(component, reg, + 0x20, 0x00); + break; case BOLERO_MACRO_EVT_IMPED_TRUE: rx_macro_wcd_clsh_imped_config(component, data, true); break; @@ -1251,6 +1262,7 @@ static int rx_macro_event_handler(struct snd_soc_component *component, bolero_rsc_clk_reset(rx_dev, RX_CORE_CLK); break; } +done: return ret; } @@ -2248,6 +2260,9 @@ static int rx_macro_enable_interp_clk(struct snd_soc_component *component, rx_priv->main_clk_users[interp_idx]--; if (rx_priv->main_clk_users[interp_idx] <= 0) { rx_priv->main_clk_users[interp_idx] = 0; + /* Main path PGA mute enable */ + snd_soc_component_update_bits(component, main_reg, + 0x10, 0x10); /* Clk Disable */ snd_soc_component_update_bits(component, dsm_reg, 0x01, 0x00); -- GitLab From 384addde09c350bba491ea5e0c5ac7e7a215c1a8 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 14 Jun 2019 02:26:52 +0530 Subject: [PATCH 1043/1645] soc: soundwire: request lpass core and audio votes Soundwire requires lpass core and lpass audio core to be enabled to receive interrupts and soundwire register read/writes. Change enables lpass core and lpass audio core in interrrupt service routine and during register read/writes. Change-Id: I56da2fc6efe7dfb1a7d59937b123b3972f633448 Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 157 +++++++++++++++++++++++++++++++++++--------- soc/swr-mstr-ctrl.h | 3 + 2 files changed, 128 insertions(+), 32 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 6d1858bf69ca..f5e503efd1dd 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -65,6 +65,12 @@ enum { ENABLE_PENDING, DISABLE_PENDING }; + +enum { + LPASS_HW_CORE, + LPASS_AUDIO_CORE, +}; + #define TRUE 1 #define FALSE 0 @@ -242,6 +248,41 @@ static void swrm_reg_dump(struct swr_mstr_ctrl *swrm, func, reg[i], val[i]); } +static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm, + int core_type, bool enable) +{ + int ret = 0; + + if (core_type == LPASS_HW_CORE) { + if (swrm->lpass_core_hw_vote) { + if (enable) { + ret = + clk_prepare_enable(swrm->lpass_core_hw_vote); + if (ret < 0) + dev_err(swrm->dev, + "%s:lpass core hw enable failed\n", + __func__); + } else + clk_disable_unprepare(swrm->lpass_core_hw_vote); + } + } + if (core_type == LPASS_AUDIO_CORE) { + if (swrm->lpass_core_audio) { + if (enable) { + ret = + clk_prepare_enable(swrm->lpass_core_audio); + if (ret < 0) + dev_err(swrm->dev, + "%s:lpass audio hw enable failed\n", + __func__); + } else + clk_disable_unprepare(swrm->lpass_core_audio); + } + } + + return ret; +} + static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) { int ret = 0; @@ -1480,14 +1521,13 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) } mutex_lock(&swrm->reslock); - if (swrm->lpass_core_hw_vote) { - ret = clk_prepare_enable(swrm->lpass_core_hw_vote); - if (ret < 0) { - dev_err(dev, "%s:lpass core hw enable failed\n", - __func__); - ret = IRQ_NONE; - goto exit; - } + if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) { + ret = IRQ_NONE; + goto exit; + } + if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { + ret = IRQ_NONE; + goto exit; } swrm_clk_request(swrm, true); mutex_unlock(&swrm->reslock); @@ -1656,8 +1696,8 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) mutex_lock(&swrm->reslock); swrm_clk_request(swrm, false); - if (swrm->lpass_core_hw_vote) - clk_disable_unprepare(swrm->lpass_core_hw_vote); + swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); + swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); exit: mutex_unlock(&swrm->reslock); swrm_unlock_sleep(swrm); @@ -1811,6 +1851,20 @@ static void swrm_device_wakeup_vote(struct swr_master *mstr) dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__); return; } + if (++swrm->hw_core_clk_en == 1) + if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) { + dev_err(swrm->dev, "%s:lpass core hw enable failed\n", + __func__); + --swrm->hw_core_clk_en; + } + if ( ++swrm->aud_core_clk_en == 1) + if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { + dev_err(swrm->dev, "%s:lpass audio hw enable failed\n", + __func__); + --swrm->aud_core_clk_en; + } + dev_dbg(swrm->dev, "%s: hw_clk_en: %d audio_core_clk_en: %d\n", + __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); pm_runtime_get_sync(swrm->dev); } @@ -1825,6 +1879,21 @@ static void swrm_device_wakeup_unvote(struct swr_master *mstr) } pm_runtime_mark_last_busy(swrm->dev); pm_runtime_put_autosuspend(swrm->dev); + dev_dbg(swrm->dev, "%s: hw_clk_en: %d audio_core_clk_en: %d\n", + __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); + + --swrm->aud_core_clk_en; + if (swrm->aud_core_clk_en < 0) + swrm->aud_core_clk_en = 0; + else if (swrm->aud_core_clk_en == 0) + swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); + + --swrm->hw_core_clk_en; + if (swrm->hw_core_clk_en < 0) + swrm->hw_core_clk_en = 0; + else if (swrm->hw_core_clk_en == 0) + swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); + swrm_unlock_sleep(swrm); } @@ -1949,6 +2018,7 @@ static int swrm_probe(struct platform_device *pdev) u32 *temp, map_size, map_length, ch_iter = 0, old_port_num = 0; int ret = 0; struct clk *lpass_core_hw_vote = NULL; + struct clk *lpass_core_audio = NULL; /* Allocate soundwire master driver structure */ swrm = devm_kzalloc(&pdev->dev, sizeof(struct swr_mstr_ctrl), @@ -2208,6 +2278,17 @@ static int swrm_probe(struct platform_device *pdev) } swrm->lpass_core_hw_vote = lpass_core_hw_vote; + /* Register LPASS audio core vote */ + lpass_core_audio = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote"); + if (IS_ERR(lpass_core_audio)) { + ret = PTR_ERR(lpass_core_audio); + dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", + __func__, "lpass_core_audio", ret); + lpass_core_audio = NULL; + ret = 0; + } + swrm->lpass_core_audio = lpass_core_audio; + dbgswrm = swrm; debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0); if (!IS_ERR(debugfs_swrm_dent)) { @@ -2313,7 +2394,8 @@ static int swrm_runtime_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); int ret = 0; - bool clk_err = false; + bool hw_core_err = false; + bool aud_core_err = false; struct swr_master *mstr = &swrm->master; struct swr_device *swr_dev; @@ -2321,14 +2403,15 @@ static int swrm_runtime_resume(struct device *dev) __func__, swrm->state); mutex_lock(&swrm->reslock); - if (swrm->lpass_core_hw_vote) { - ret = clk_prepare_enable(swrm->lpass_core_hw_vote); - if (ret < 0) { - dev_err(dev, "%s:lpass core hw enable failed\n", - __func__); - ret = 0; - clk_err = true; - } + if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) { + dev_err(dev, "%s:lpass core hw enable failed\n", + __func__); + hw_core_err = true; + } + if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { + dev_err(dev, "%s:lpass audio hw enable failed\n", + __func__); + aud_core_err = true; } if ((swrm->state == SWR_MSTR_DOWN) || @@ -2375,10 +2458,13 @@ static int swrm_runtime_resume(struct device *dev) swrm->state = SWR_MSTR_UP; } exit: - if (swrm->lpass_core_hw_vote && !clk_err) - clk_disable_unprepare(swrm->lpass_core_hw_vote); + if (!aud_core_err) + swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); + if (!hw_core_err) + swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer); mutex_unlock(&swrm->reslock); + return ret; } @@ -2387,7 +2473,8 @@ static int swrm_runtime_suspend(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); int ret = 0; - bool clk_err = false; + bool hw_core_err = false; + bool aud_core_err = false; struct swr_master *mstr = &swrm->master; struct swr_device *swr_dev; int current_state = 0; @@ -2398,14 +2485,16 @@ static int swrm_runtime_suspend(struct device *dev) mutex_lock(&swrm->force_down_lock); current_state = swrm->state; mutex_unlock(&swrm->force_down_lock); - if (swrm->lpass_core_hw_vote) { - ret = clk_prepare_enable(swrm->lpass_core_hw_vote); - if (ret < 0) { - dev_err(dev, "%s:lpass core hw enable failed\n", - __func__); - ret = 0; - clk_err = true; - } + + if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) { + dev_err(dev, "%s:lpass core hw enable failed\n", + __func__); + hw_core_err = true; + } + if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { + dev_err(dev, "%s:lpass audio hw enable failed\n", + __func__); + aud_core_err = true; } if ((current_state == SWR_MSTR_UP) || @@ -2436,9 +2525,11 @@ static int swrm_runtime_suspend(struct device *dev) } } } else { + mutex_unlock(&swrm->reslock); /* clock stop sequence */ swrm_cmd_fifo_wr_cmd(swrm, 0x2, 0xF, 0xF, SWRS_SCP_CONTROL); + mutex_lock(&swrm->reslock); usleep_range(100, 105); } swrm_clk_request(swrm, false); @@ -2458,8 +2549,10 @@ static int swrm_runtime_suspend(struct device *dev) if (current_state != SWR_MSTR_SSR) swrm->state = SWR_MSTR_DOWN; exit: - if (swrm->lpass_core_hw_vote && !clk_err) - clk_disable_unprepare(swrm->lpass_core_hw_vote); + if (!aud_core_err) + swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); + if (!hw_core_err) + swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); mutex_unlock(&swrm->reslock); return ret; } diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 4a48571e90ab..e05ede258dc9 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -155,8 +155,11 @@ struct swr_mstr_ctrl { u32 intr_mask; struct port_params **port_param; struct clk *lpass_core_hw_vote; + struct clk *lpass_core_audio; u8 num_usecase; u32 swr_irq_wakeup_capable; + int hw_core_clk_en; + int aud_core_clk_en; }; #endif /* _SWR_WCD_CTRL_H */ -- GitLab From 6a9cb8b6bdf604adbd8784147065821c2467ccf7 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Mon, 10 Jun 2019 23:47:06 +0530 Subject: [PATCH 1044/1645] asoc: wcd938x: wakeup device during headset detection Use soundwire device wakeup API to wakeup soundwire master during headset plug detection. Change-Id: Icddd558df382146bb2989926d2e92e627b5a844f Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd938x/wcd938x-mbhc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/codecs/wcd938x/wcd938x-mbhc.c b/asoc/codecs/wcd938x/wcd938x-mbhc.c index b9bbdaeb54c2..08a2b228df3a 100644 --- a/asoc/codecs/wcd938x/wcd938x-mbhc.c +++ b/asoc/codecs/wcd938x/wcd938x-mbhc.c @@ -239,6 +239,11 @@ static void wcd938x_mbhc_program_btn_thr(struct snd_soc_component *component, static bool wcd938x_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock) { + struct snd_soc_component *component = mbhc->component; + struct wcd938x_priv *wcd938x = dev_get_drvdata(component->dev); + + wcd938x->wakeup((void*)wcd938x, lock); + return true; } -- GitLab From 4a6979f60ed7a5394d75c0a49c1754ce29057880 Mon Sep 17 00:00:00 2001 From: Timothy Sham Date: Tue, 19 Feb 2019 12:36:06 -0500 Subject: [PATCH 1045/1645] audio-driver: Update build files for auto LA-GVM enable conditional build for audio driver modules for automotive LA GVM. Change-Id: I058f3e6ca557f8ca6d02e33e80f6c190b1a2a29e Signed-off-by: Timothy Sham --- Android.mk | 6 +++--- asoc/Android.mk | 2 +- asoc/Kbuild | 5 +++++ asoc/codecs/Android.mk | 4 ++-- asoc/codecs/Kbuild | 5 +++++ config/gvmauto.conf | 13 +++++++++++++ config/gvmautoconf.h | 25 +++++++++++++++++++++++++ dsp/Android.mk | 4 ++-- dsp/codecs/Kbuild | 5 +++++ ipc/Android.mk | 4 ++-- ipc/Kbuild | 5 +++++ 11 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 config/gvmauto.conf create mode 100644 config/gvmautoconf.h diff --git a/Android.mk b/Android.mk index d1fdc7324849..41f14b30a59c 100644 --- a/Android.mk +++ b/Android.mk @@ -22,18 +22,18 @@ include $(MY_LOCAL_PATH)/asoc/codecs/Android.mk endif ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk endif endif -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) include $(MY_LOCAL_PATH)/soc/Android.mk endif ifeq ($(call is-board-platform-in-list,msmnile),true) -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/aqt1000/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/aqt1000/Android.mk endif diff --git a/asoc/Android.mk b/asoc/Android.mk index 1293f5f2fa30..1fb172a5d92c 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -5,7 +5,7 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) TARGET := msmnile -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m diff --git a/asoc/Kbuild b/asoc/Kbuild index 4890912a1a28..00a6a445c325 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -54,6 +54,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h endif + ifeq ($(CONFIG_QTI_GVM), y) + include $(AUDIO_ROOT)/config/gvmauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h + endif endif # As per target team, build is done as follows: diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index 145da097dd7a..9e58936febe8 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -4,7 +4,7 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m @@ -56,7 +56,7 @@ KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) KBUILD_OPTIONS += $(AUDIO_SELECT) ########################################################### -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd_core.ko LOCAL_MODULE_KBUILD_NAME := wcd_core_dlkm.ko diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index d8d52b344186..4cda710fc8ef 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -54,6 +54,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h endif + ifeq ($(CONFIG_QTI_GVM), y) + include $(AUDIO_ROOT)/config/gvmauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h + endif endif # As per target team, build is done as follows: diff --git a/config/gvmauto.conf b/config/gvmauto.conf new file mode 100644 index 000000000000..82ad8da925de --- /dev/null +++ b/config/gvmauto.conf @@ -0,0 +1,13 @@ +CONFIG_MSM_QDSP6_APRV2_VM=m +CONFIG_MSM_QDSP6_SSR=m +CONFIG_MSM_ADSP_LOADER=m +CONFIG_MSM_QDSP6_NOTIFIER=m +CONFIG_SND_SOC_MSM_QDSP6V2_VM=m +CONFIG_SND_SOC_QDSP6V2=m +CONFIG_QTI_PP=m +CONFIG_SND_HWDEP_ROUTING=m +CONFIG_DTS_EAGLE=m +CONFIG_DOLBY_DS2=m +CONFIG_DOLBY_LICENSE=m +CONFIG_SND_SOC_MSM_STUB=m +CONFIG_MSM_QDSP6V2_CODECS=m diff --git a/config/gvmautoconf.h b/config/gvmautoconf.h new file mode 100644 index 000000000000..af389b625d72 --- /dev/null +++ b/config/gvmautoconf.h @@ -0,0 +1,25 @@ +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define CONFIG_MSM_QDSP6_APRV2_VM 1 +#define CONFIG_MSM_ADSP_LOADER 1 +#define CONFIG_MSM_QDSP6_SSR 1 +#define CONFIG_MSM_QDSP6_NOTIFIER 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_VM 1 +#define CONFIG_SND_SOC_QDSP6V2 1 +#define CONFIG_QTI_PP 1 +#define CONFIG_SND_HWDEP_ROUTING 1 +#define CONFIG_DTS_EAGLE 1 +#define CONFIG_DOLBY_DS2 1 +#define CONFIG_DOLBY_LICENSE 1 +#define CONFIG_SND_SOC_MSM_STUB 1 +#define CONFIG_MSM_QDSP6V2_CODECS 1 diff --git a/dsp/Android.mk b/dsp/Android.mk index 20f346317ebc..9119ea434292 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -4,7 +4,7 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m @@ -76,7 +76,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ############################################################ -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_usf.ko LOCAL_MODULE_KBUILD_NAME := usf_dlkm.ko diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index d78675f54f98..888492ddc0e7 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -48,6 +48,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h endif + ifeq ($(CONFIG_QTI_GVM), y) + include $(AUDIO_ROOT)/config/gvmauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h + endif endif # As per target team, build is done as follows: diff --git a/ipc/Android.mk b/ipc/Android.mk index e3374eadc02b..4c582f02e336 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -4,7 +4,7 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m @@ -61,7 +61,7 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au)) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wglink.ko LOCAL_MODULE_KBUILD_NAME := wglink_dlkm.ko diff --git a/ipc/Kbuild b/ipc/Kbuild index 30afc60c6cfd..6a5c08bac37c 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -55,6 +55,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif + ifeq ($(CONFIG_QTI_GVM), y) + include $(AUDIO_ROOT)/config/gvmauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h + endif endif # As per target team, build is done as follows: -- GitLab From 3c259b5e62d902b1dd31f75631d97a30a518b156 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 26 Jun 2019 11:01:38 +0530 Subject: [PATCH 1046/1645] dsp: Add size check for afe set and get functions In afe_get_cal_sp_th_vi_param and afe_set_cal_sp_th_vi_cfg functions, data size check is not present which might lead to out of bounds access. Add size checks to fix the same. Change-Id: I99eca6065e6f5a050527f1bfce2bfcba28123b53 Signed-off-by: Aditya Bavanari --- dsp/q6afe.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 0fe38885f7c9..e65fabe14b08 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -8456,6 +8456,7 @@ static int afe_set_cal_sp_th_vi_cfg(int32_t cal_type, size_t data_size, uint32_t mode; if (cal_data == NULL || + data_size != sizeof(*cal_data) || this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL) goto done; @@ -8599,6 +8600,7 @@ static int afe_get_cal_sp_th_vi_param(int32_t cal_type, size_t data_size, int ret = 0; if (cal_data == NULL || + data_size != sizeof(*cal_data) || this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL) return 0; -- GitLab From 431b1c5d9b2d327e3fae3b73871a447ac98ff594 Mon Sep 17 00:00:00 2001 From: Weiyin Jiang Date: Tue, 25 Jun 2019 23:05:14 +0800 Subject: [PATCH 1047/1645] asoc: ignore enable commands if state already matches Break without setting rc to error code causes param_id=0 sent to certain effect module in adsp, If enable flag state for the module is same as the requested state, ignore the command and continue with next command to avoid sending param_id=0 to ADSP. CRs-Fixed: 2478482 Change-Id: I6cddf6f5156562d2c5d6aa6163881992bfa55eeb Signed-off-by: Weiyin Jiang --- asoc/msm-audio-effects-q6-v2.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/asoc/msm-audio-effects-q6-v2.c b/asoc/msm-audio-effects-q6-v2.c index 3605a752c33c..db3bd87ebc0e 100644 --- a/asoc/msm-audio-effects-q6-v2.c +++ b/asoc/msm-audio-effects-q6-v2.c @@ -161,7 +161,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, pr_debug("%s:VIRT ENABLE prev:%d, new:%d\n", __func__, prev_enable_flag, virtualizer->enable_flag); if (prev_enable_flag == virtualizer->enable_flag) - break; + continue; max_params_length = params_length + COMMAND_IID_PAYLOAD_SZ + VIRTUALIZER_ENABLE_PARAM_SZ; @@ -340,7 +340,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, pr_debug("%s:REVERB_ENABLE prev:%d,new:%d\n", __func__, prev_enable_flag, reverb->enable_flag); if (prev_enable_flag == reverb->enable_flag) - break; + continue; max_params_length = params_length + COMMAND_IID_PAYLOAD_SZ + REVERB_ENABLE_PARAM_SZ; @@ -776,7 +776,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, __func__, prev_enable_flag, bass_boost->enable_flag); if (prev_enable_flag == bass_boost->enable_flag) - break; + continue; max_params_length = params_length + COMMAND_IID_PAYLOAD_SZ + BASS_BOOST_ENABLE_PARAM_SZ; @@ -931,7 +931,7 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, pbe->enable_flag = GET_NEXT(values, param_max_offset, rc); if (prev_enable_flag == pbe->enable_flag) - break; + continue; max_params_length = params_length + COMMAND_IID_PAYLOAD_SZ + PBE_ENABLE_PARAM_SZ; @@ -1125,7 +1125,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, pr_debug("%s: EQ_ENABLE prev:%d new:%d\n", __func__, prev_enable_flag, eq->enable_flag); if (prev_enable_flag == eq->enable_flag) - break; + continue; max_params_length = params_length + COMMAND_IID_PAYLOAD_SZ + EQ_ENABLE_PARAM_SZ; -- GitLab From 809482351aa9deee6073f70e5715d43d1ef99c5e Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Mon, 11 Mar 2019 09:12:22 -0400 Subject: [PATCH 1048/1645] audio-driver: configs: Add HDMI Codec for GVM Add HDMI Codec module in GVM for auto, to keep consistent with BoardConfig. Change-Id: Iba3b0ac1722797a8481ee1a6f857876814ab54ac Signed-off-by: Timothy Sham --- config/gvmauto.conf | 1 + config/gvmautoconf.h | 1 + 2 files changed, 2 insertions(+) diff --git a/config/gvmauto.conf b/config/gvmauto.conf index 82ad8da925de..9af768597696 100644 --- a/config/gvmauto.conf +++ b/config/gvmauto.conf @@ -10,4 +10,5 @@ CONFIG_DTS_EAGLE=m CONFIG_DOLBY_DS2=m CONFIG_DOLBY_LICENSE=m CONFIG_SND_SOC_MSM_STUB=m +CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m CONFIG_MSM_QDSP6V2_CODECS=m diff --git a/config/gvmautoconf.h b/config/gvmautoconf.h index af389b625d72..0826a9ee9f9c 100644 --- a/config/gvmautoconf.h +++ b/config/gvmautoconf.h @@ -22,4 +22,5 @@ #define CONFIG_DOLBY_DS2 1 #define CONFIG_DOLBY_LICENSE 1 #define CONFIG_SND_SOC_MSM_STUB 1 +#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 #define CONFIG_MSM_QDSP6V2_CODECS 1 -- GitLab From b9d7807f4e49436939136935bd9a4c5916738724 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 21 Jun 2019 14:15:23 -0700 Subject: [PATCH 1049/1645] asoc: codecs: Change TX tuning and reduce RX click and pop Update TX requantizer gain coefficients to center gain errors around zero. To reduce click and pop on audio playback enable reference buffers of headphone path in hifi mode and then put it to the usecase specific power mode. Change-Id: I0013d6258d5e5a8c92fd0f951d1d89e5906b2faf Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd-clsh.c | 10 +- asoc/codecs/wcd938x/internal.h | 1 + asoc/codecs/wcd938x/wcd938x.c | 163 ++++++++++++++++++++++++++------- include/asoc/wcd-clsh.h | 11 ++- 4 files changed, 148 insertions(+), 37 deletions(-) diff --git a/asoc/codecs/wcd-clsh.c b/asoc/codecs/wcd-clsh.c index bda389381101..8306fa53d91e 100644 --- a/asoc/codecs/wcd-clsh.c +++ b/asoc/codecs/wcd-clsh.c @@ -243,7 +243,14 @@ static void wcd_clsh_flyback_ctrl(struct snd_soc_component *component, __func__, clsh_d->flyback_users, enable, mode_to_str(mode)); } -static void wcd_clsh_set_hph_mode(struct snd_soc_component *component, +/* + * Function: wcd_clsh_set_hph_mode + * Params: soc component, hph mode class + * Description: + * This function updates class H mode configuration based on + * the input mode. + */ +void wcd_clsh_set_hph_mode(struct snd_soc_component *component, int mode) { u8 val = 0; @@ -273,6 +280,7 @@ static void wcd_clsh_set_hph_mode(struct snd_soc_component *component, snd_soc_component_update_bits(component, WCD9XXX_ANA_HPH, 0x0C, val); } +EXPORT_SYMBOL(wcd_clsh_set_hph_mode); static void wcd_clsh_set_flyback_current(struct snd_soc_component *component, int mode) diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index 87bea0431860..a54394446bd3 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -144,6 +144,7 @@ enum { WCD_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */ WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */ WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */ + WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST, }; enum { diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 3a6c895a65d7..8113ab4204f2 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -173,6 +173,16 @@ static int wcd938x_init_reg(struct snd_soc_component *component) snd_soc_component_update_bits(component, WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_ULP, 0x1F, 0x08); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_TX_REQ_FB_CTL_0, 0xFF, 0x55); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_TX_REQ_FB_CTL_1, 0xFF, 0x44); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_TX_REQ_FB_CTL_2, 0xFF, 0x11); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_TX_REQ_FB_CTL_3, 0xFF, 0x00); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_TX_REQ_FB_CTL_4, 0xFF, 0x00); return 0; } @@ -618,6 +628,10 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX2 << 0x10 | 0x1)); ret = swr_slvdev_datapath_control(wcd938x->rx_swr_dev, wcd938x->rx_swr_dev->dev_num, true); @@ -625,8 +639,10 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_HPHR, hph_mode); + wcd_clsh_set_hph_mode(component, CLS_H_HIFI); snd_soc_component_update_bits(component, WCD938X_ANA_HPH, 0x10, 0x10); + wcd_clsh_set_hph_mode(component, hph_mode); /* 100 usec delay as per HW requirement */ usleep_range(100, 110); set_bit(HPH_PA_DELAY, &wcd938x->status_mask); @@ -656,26 +672,61 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX2 << 0x10)); + wcd_enable_irq(&wcd938x->irq_info, + WCD938X_IRQ_HPHR_PDM_WD_INT); break; case SND_SOC_DAPM_PRE_PMD: + wcd_disable_irq(&wcd938x->irq_info, + WCD938X_IRQ_HPHR_PDM_WD_INT); if (wcd938x->update_wcd_event) wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX2 << 0x10 | 0x1)); + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST, + (WCD_RX2 << 0x10)); + /* 7 msec delay as per HW requirement */ + usleep_range(7000, 7100); + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX2 << 0x10 | 0x0)); + /* 20 msec delay as per HW requirement */ + usleep_range(21000, 21100); + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX2 << 0x10 | 0x1)); + snd_soc_component_update_bits(component, WCD938X_ANA_HPH, + 0x40, 0x00); blocking_notifier_call_chain(&wcd938x->mbhc->notifier, WCD_EVENT_PRE_HPHR_PA_OFF, &wcd938x->mbhc->wcd_mbhc); + set_bit(HPH_PA_DELAY, &wcd938x->status_mask); break; case SND_SOC_DAPM_POST_PMD: - /* 7 msec delay as per HW requirement */ - usleep_range(7000, 7010); - snd_soc_component_update_bits(component, - WCD938X_DIGITAL_PDM_WD_CTL1, 0x17, 0x00); + /* + * 7ms sleep is required if compander is enabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is required. + */ + if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) { + if (!wcd938x->comp2_enable) + usleep_range(20000, 20100); + else + usleep_range(7000, 7100); + clear_bit(HPH_PA_DELAY, &wcd938x->status_mask); + } blocking_notifier_call_chain(&wcd938x->mbhc->notifier, WCD_EVENT_POST_HPHR_PA_OFF, &wcd938x->mbhc->wcd_mbhc); snd_soc_component_update_bits(component, WCD938X_ANA_HPH, 0x10, 0x00); + /* 20 msec delay as per HW requirement */ + usleep_range(20000, 20100); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_PDM_WD_CTL1, 0x17, 0x00); wcd_cls_h_fsm(component, &wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_HPHR, @@ -699,6 +750,10 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10 | 0x01)); ret = swr_slvdev_datapath_control(wcd938x->rx_swr_dev, wcd938x->rx_swr_dev->dev_num, true); @@ -706,8 +761,10 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_HPHL, hph_mode); + wcd_clsh_set_hph_mode(component, CLS_H_HIFI); snd_soc_component_update_bits(component, WCD938X_ANA_HPH, 0x20, 0x20); + wcd_clsh_set_hph_mode(component, hph_mode); /* 100 usec delay as per HW requirement */ usleep_range(100, 110); set_bit(HPH_PA_DELAY, &wcd938x->status_mask); @@ -737,26 +794,61 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX1 << 0x10)); + wcd_enable_irq(&wcd938x->irq_info, + WCD938X_IRQ_HPHL_PDM_WD_INT); break; case SND_SOC_DAPM_PRE_PMD: + wcd_disable_irq(&wcd938x->irq_info, + WCD938X_IRQ_HPHL_PDM_WD_INT); if (wcd938x->update_wcd_event) wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX1 << 0x10 | 0x1)); + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST, + (WCD_RX1 << 0x10)); + /* 7 msec delay as per HW requirement */ + usleep_range(7000, 7100); + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10 | 0x0)); + /* 20 msec delay as per HW requirement */ + usleep_range(21000, 21100); + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10 | 0x1)); + snd_soc_component_update_bits(component, WCD938X_ANA_HPH, + 0x80, 0x00); blocking_notifier_call_chain(&wcd938x->mbhc->notifier, WCD_EVENT_PRE_HPHL_PA_OFF, &wcd938x->mbhc->wcd_mbhc); + set_bit(HPH_PA_DELAY, &wcd938x->status_mask); break; case SND_SOC_DAPM_POST_PMD: - /* 7 msec delay as per HW requirement */ - usleep_range(7000, 7010); - snd_soc_component_update_bits(component, - WCD938X_DIGITAL_PDM_WD_CTL0, 0x17, 0x00); + /* + * 7ms sleep is required if compander is enabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is required. + */ + if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) { + if (!wcd938x->comp1_enable) + usleep_range(21000, 21100); + else + usleep_range(7000, 7100); + clear_bit(HPH_PA_DELAY, &wcd938x->status_mask); + } blocking_notifier_call_chain(&wcd938x->mbhc->notifier, WCD_EVENT_POST_HPHL_PA_OFF, &wcd938x->mbhc->wcd_mbhc); snd_soc_component_update_bits(component, WCD938X_ANA_HPH, 0x20, 0x00); + /* 20 msec delay as per HW requirement */ + usleep_range(21000, 21100); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_PDM_WD_CTL0, 0x17, 0x00); wcd_cls_h_fsm(component, &wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_HPHL, @@ -799,8 +891,11 @@ static int wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX3 << 0x10)); + wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT); break; case SND_SOC_DAPM_PRE_PMD: + wcd_disable_irq(&wcd938x->irq_info, + WCD938X_IRQ_AUX_PDM_WD_INT); if (wcd938x->update_wcd_event) wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -1684,10 +1779,10 @@ static int wcd938x_codec_enable_micbias(struct snd_soc_dapm_widget *w, return __wcd938x_codec_enable_micbias(w, event); } -static inline int wcd938x_tx_path_get(const char *wname) +static inline int wcd938x_tx_path_get(const char *wname, + unsigned int *path_num) { int ret = 0; - unsigned int path_num; char *widget_name = NULL; char *w_name = NULL; char *path_num_char = NULL; @@ -1706,7 +1801,6 @@ static inline int wcd938x_tx_path_get(const char *wname) ret = -EINVAL; goto err; } - path_name = widget_name; path_num_char = strpbrk(path_name, "0123"); if (!path_num_char) { pr_err("%s: tx path index not found\n", @@ -1714,7 +1808,7 @@ static inline int wcd938x_tx_path_get(const char *wname) ret = -EINVAL; goto err; } - ret = kstrtouint(path_num_char, 10, &path_num); + ret = kstrtouint(path_num_char, 10, path_num); if (ret < 0) pr_err("%s: Invalid tx path = %s\n", __func__, w_name); @@ -1727,24 +1821,23 @@ static inline int wcd938x_tx_path_get(const char *wname) static int wcd938x_tx_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct wcd938x_priv *wcd938x = NULL; - int path = 0; + int ret = 0; + unsigned int path = 0; if (!component) return -EINVAL; wcd938x = snd_soc_component_get_drvdata(component); - if (!widget || !widget->name || !wcd938x) + if (!wcd938x) return -EINVAL; - path = wcd938x_tx_path_get(widget->name); - if (path < 0 || path >= TX_ADC_MAX) - return -EINVAL; + ret = wcd938x_tx_path_get(kcontrol->id.name, &path); + if (ret < 0) + return ret; ucontrol->value.integer.value[0] = wcd938x->tx_mode[path]; @@ -1754,25 +1847,24 @@ static int wcd938x_tx_mode_get(struct snd_kcontrol *kcontrol, static int wcd938x_tx_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct wcd938x_priv *wcd938x = NULL; u32 mode_val; - int path = 0; + unsigned int path = 0; + int ret = 0; if (!component) return -EINVAL; wcd938x = snd_soc_component_get_drvdata(component); - if (!widget || !widget->name || !wcd938x) + if (!wcd938x) return -EINVAL; - path = wcd938x_tx_path_get(widget->name); - if (path < 0 || path >= TX_ADC_MAX) - return -EINVAL; + ret = wcd938x_tx_path_get(kcontrol->id.name, &path); + if (ret) + return ret; mode_val = ucontrol->value.enumerated.item[0]; @@ -2199,19 +2291,19 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = { SND_SOC_DAPM_PGA_E("EAR PGA", WCD938X_ANA_EAR, 7, 0, NULL, 0, wcd938x_codec_enable_ear_pa, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PGA_E("AUX PGA", WCD938X_AUX_AUXPA, 7, 0, NULL, 0, wcd938x_codec_enable_aux_pa, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PGA_E("HPHL PGA", WCD938X_ANA_HPH, 7, 0, NULL, 0, wcd938x_codec_enable_hphl_pa, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PGA_E("HPHR PGA", WCD938X_ANA_HPH, 6, 0, NULL, 0, wcd938x_codec_enable_hphr_pa, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_DAC_E("RDAC1", NULL, SND_SOC_NOPM, 0, 0, wcd938x_codec_hphl_dac_event, @@ -2840,10 +2932,10 @@ static int wcd938x_bind(struct device *dev) "HPHL PDM WD INT", wcd938x_wd_handle_irq, NULL); wcd_request_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT, "AUX PDM WD INT", wcd938x_wd_handle_irq, NULL); - /* Enable watchdog interrupt for HPH and AUX */ - wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHR_PDM_WD_INT); - wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHL_PDM_WD_INT); - wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT); + /* Disable watchdog interrupt for HPH and AUX */ + wcd_disable_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHR_PDM_WD_INT); + wcd_disable_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHL_PDM_WD_INT); + wcd_disable_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT); ret = snd_soc_register_component(dev, &soc_codec_dev_wcd938x, NULL, 0); @@ -2865,6 +2957,9 @@ static void wcd938x_unbind(struct device *dev) { struct wcd938x_priv *wcd938x = dev_get_drvdata(dev); + wcd_free_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHR_PDM_WD_INT, NULL); + wcd_free_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHL_PDM_WD_INT, NULL); + wcd_free_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT, NULL); wcd_irq_exit(&wcd938x->irq_info, wcd938x->virq); snd_soc_unregister_component(dev); component_unbind_all(dev, wcd938x); diff --git a/include/asoc/wcd-clsh.h b/include/asoc/wcd-clsh.h index c8e49fd0b904..96d35b672b28 100644 --- a/include/asoc/wcd-clsh.h +++ b/include/asoc/wcd-clsh.h @@ -82,15 +82,22 @@ extern void wcd_cls_h_fsm(struct snd_soc_component *component, int int_mode); extern void wcd_cls_h_init(struct wcd_clsh_cdc_info *clsh); +extern void wcd_clsh_set_hph_mode(struct snd_soc_component *component, + int mode); #else -extern void wcd_cls_h_fsm(struct snd_soc_component *component, +static inline void wcd_cls_h_fsm(struct snd_soc_component *component, struct wcd_clsh_cdc_info *cdc_clsh_d, u8 clsh_event, u8 req_state, int int_mode) { } -extern void wcd_cls_h_init(struct wcd_clsh_cdc_info *clsh) +static inline extern void wcd_cls_h_init(struct wcd_clsh_cdc_info *clsh) +{ +} + +static inline extern void wcd_clsh_set_hph_mode(struct snd_soc_component *component, + int mode) { } #endif /* CONFIG_SND_SOC_WCD9XXX_V2 */ -- GitLab From bd9302482324e4846f708615d5272d4a3661a15a Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 25 Jun 2019 09:39:48 +0800 Subject: [PATCH 1050/1645] asoc: bolero: check if clock is enabled before accessing register Reset GFMUX reg for va-macro and wsa-macro when adsp is up after SSR. And check if clock is enabled before accessing register to avoid kernel panic. Change-Id: Idce9695be552cab0e8e389cf72eeb7a67a754bf9 Signed-off-by: Meng Wang --- asoc/codecs/bolero/bolero-clk-rsc.c | 13 ++++++++----- asoc/codecs/bolero/va-macro.c | 14 ++++++++++++++ asoc/codecs/bolero/wsa-macro.c | 13 +++++++++++++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c index d325d76adc03..4940f67a8a38 100644 --- a/asoc/codecs/bolero/bolero-clk-rsc.c +++ b/asoc/codecs/bolero/bolero-clk-rsc.c @@ -238,17 +238,20 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv, } priv->clk_cnt[clk_id]--; if (priv->clk_cnt[clk_id] == 0) { - bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, - true); + ret = bolero_clk_rsc_mux0_clk_request(priv, + default_clk_id, true); + + if (!ret) + iowrite32(0x0, clk_muxsel); - iowrite32(0x0, clk_muxsel); if (priv->clk[clk_id + NPL_CLK_OFFSET]) clk_disable_unprepare( priv->clk[clk_id + NPL_CLK_OFFSET]); clk_disable_unprepare(priv->clk[clk_id]); - bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, - false); + if (!ret) + bolero_clk_rsc_mux0_clk_request(priv, + default_clk_id, false); } } return ret; diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index a94ca7701203..bb3a325c4574 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -209,6 +209,7 @@ static int va_macro_event_handler(struct snd_soc_component *component, struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; int retry_cnt = MAX_RETRY_ATTEMPTS; + int ret = 0; if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; @@ -234,6 +235,19 @@ static int va_macro_event_handler(struct snd_soc_component *component, "%s: va_mclk_users is non-zero still, audio SSR fail!!\n", __func__); break; + case BOLERO_MACRO_EVT_SSR_UP: + /* enable&disable VA_CORE_CLK to reset GFMUX reg */ + ret = bolero_clk_rsc_request_clock(va_priv->dev, + va_priv->default_clk_id, + VA_CORE_CLK, true); + if (ret < 0) + dev_err_ratelimited(va_priv->dev, + "%s, failed to enable clk, ret:%d\n", + __func__, ret); + else + bolero_clk_rsc_request_clock(va_priv->dev, + va_priv->default_clk_id, + VA_CORE_CLK, false); case BOLERO_MACRO_EVT_CLK_RESET: bolero_rsc_clk_reset(va_dev, VA_CORE_CLK); break; diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 3ca5d4c1d55c..53ab2e719748 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -905,6 +905,7 @@ static int wsa_macro_event_handler(struct snd_soc_component *component, { struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; + int ret = 0; if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; @@ -923,6 +924,18 @@ static int wsa_macro_event_handler(struct snd_soc_component *component, case BOLERO_MACRO_EVT_SSR_UP: /* reset swr after ssr/pdr */ wsa_priv->reset_swr = true; + /* enable&disable WSA_CORE_CLK to reset GFMUX reg */ + ret = bolero_clk_rsc_request_clock(wsa_priv->dev, + wsa_priv->default_clk_id, + WSA_CORE_CLK, true); + if (ret < 0) + dev_err_ratelimited(wsa_priv->dev, + "%s, failed to enable clk, ret:%d\n", + __func__, ret); + else + bolero_clk_rsc_request_clock(wsa_priv->dev, + wsa_priv->default_clk_id, + WSA_CORE_CLK, false); if (wsa_priv->swr_ctrl_data) swrm_wcd_notify( wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, -- GitLab From d874e514eae0ba453f81b41124b33d9d37b463b7 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 25 Jun 2019 16:27:55 -0700 Subject: [PATCH 1051/1645] asoc: codecs: wcd938x: Remove hifi modes for wcd9380 wcd9380 codec version does not support hifi modes. Remove the support for the same for platforms with that codec version. Change-Id: If43bcc41c3fe2955907a148351b7a7aebf37699f Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/wcd938x.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 8113ab4204f2..998623845d18 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1896,11 +1896,19 @@ static int wcd938x_rx_hph_mode_put(struct snd_kcontrol *kcontrol, dev_dbg(component->dev, "%s: mode: %d\n", __func__, mode_val); - if (mode_val == 0) { + if (wcd938x->variant == WCD9380) { + if (mode_val == CLS_H_HIFI || mode_val == CLS_AB_HIFI) { + dev_info(component->dev, + "%s:Invalid HPH Mode, default to CLS_H_ULP\n", + __func__); + mode_val = CLS_H_ULP; + } + } + if (mode_val == CLS_H_NORMAL) { dev_info(component->dev, "%s:Invalid HPH Mode, default to class_AB\n", __func__); - mode_val = 3; /* enum will be updated later */ + mode_val = CLS_H_ULP; } wcd938x->hph_mode = mode_val; return 0; @@ -1961,6 +1969,16 @@ static const struct soc_enum tx_mode_mux_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tx_mode_mux_text), tx_mode_mux_text); +static const char * const rx_hph_mode_mux_text_wcd9380[] = { + "CLS_H_INVALID", "CLS_H_INVALID_1", "CLS_H_LP", "CLS_AB", + "CLS_H_LOHIFI", "CLS_H_ULP", "CLS_H_INVALID_2", "CLS_AB_LP", + "CLS_AB_LOHIFI", +}; + +static const struct soc_enum rx_hph_mode_mux_enum_wcd9380 = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text_wcd9380), + rx_hph_mode_mux_text_wcd9380); + static const char * const rx_hph_mode_mux_text[] = { "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI", "CLS_H_ULP", "CLS_AB_HIFI", "CLS_AB_LP", "CLS_AB_LOHIFI", @@ -1971,6 +1989,9 @@ static const struct soc_enum rx_hph_mode_mux_enum = rx_hph_mode_mux_text); static const struct snd_kcontrol_new wcd9380_snd_controls[] = { + SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum_wcd9380, + wcd938x_rx_hph_mode_get, wcd938x_rx_hph_mode_put), + SOC_ENUM_EXT("TX0 MODE", tx_mode_mux_enum_wcd9380, wcd938x_tx_mode_get, wcd938x_tx_mode_put), SOC_ENUM_EXT("TX1 MODE", tx_mode_mux_enum_wcd9380, @@ -1982,6 +2003,9 @@ static const struct snd_kcontrol_new wcd9380_snd_controls[] = { }; static const struct snd_kcontrol_new wcd9385_snd_controls[] = { + SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum, + wcd938x_rx_hph_mode_get, wcd938x_rx_hph_mode_put), + SOC_ENUM_EXT("TX0 MODE", tx_mode_mux_enum, wcd938x_tx_mode_get, wcd938x_tx_mode_put), SOC_ENUM_EXT("TX1 MODE", tx_mode_mux_enum, @@ -1993,9 +2017,6 @@ static const struct snd_kcontrol_new wcd9385_snd_controls[] = { }; static const struct snd_kcontrol_new wcd938x_snd_controls[] = { - SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum, - wcd938x_rx_hph_mode_get, wcd938x_rx_hph_mode_put), - SOC_SINGLE_EXT("HPHL_COMP Switch", SND_SOC_NOPM, 0, 1, 0, wcd938x_get_compander, wcd938x_set_compander), SOC_SINGLE_EXT("HPHR_COMP Switch", SND_SOC_NOPM, 1, 1, 0, -- GitLab From 8c60bb5664acdf6cef299b3e0301f5b02d7b818b Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 19 Jun 2019 15:49:06 +0800 Subject: [PATCH 1052/1645] soc: soundwire: update log type for soundwire Update pr_err to dev_err to indicate which device has clock mismatch. Change-Id: Icf842ed63aa0a01ace0ff461f8c05194a0e25f92 Signed-off-by: Meng Wang --- soc/swr-mstr-ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index f5e503efd1dd..30c1f14c416f 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -311,7 +311,7 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) complete(&swrm->clk_off_complete); } if (swrm->clk_ref_count < 0) { - pr_err("%s: swrm clk count mismatch\n", __func__); + dev_err(swrm->dev, "%s: swrm clk count mismatch\n", __func__); swrm->clk_ref_count = 0; } -- GitLab From 4b489349e161ef0f1722845faa8ba245477d1f3a Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 19 Jun 2019 13:50:13 +0800 Subject: [PATCH 1053/1645] soc: lpi: check if vote clk is enabled before accessing LPI GPIO HW vote clock may fail to get enabled. Check if hw vote clk is enabled in lpi_gpio_read and lpi_gpio_write to avoid kernel panic. Change-Id: I077e5c61058d9d90be98ff3a0c0834049ad7e584 Signed-off-by: Meng Wang --- soc/pinctrl-lpi.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index ff9e9406c438..15c32253668a 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -136,7 +136,8 @@ static const char *const lpi_gpio_functions[] = { static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr) { - int ret; + int ret = 0; + struct lpi_gpio_state *state = dev_get_drvdata(lpi_dev); if (!lpi_dev_up) { pr_err_ratelimited("%s: ADSP is down due to SSR, return\n", @@ -144,11 +145,18 @@ static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr) return 0; } pm_runtime_get_sync(lpi_dev); + if (!state->core_hw_vote_status) { + pr_err_ratelimited("%s: core hw vote clk is not enabled\n", + __func__); + ret = -EINVAL; + goto err; + } ret = ioread32(pad->base + pad->offset + addr); if (ret < 0) pr_err("%s: read 0x%x failed\n", __func__, addr); +err: pm_runtime_mark_last_busy(lpi_dev); pm_runtime_put_autosuspend(lpi_dev); return ret; @@ -157,18 +165,27 @@ static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr) static int lpi_gpio_write(struct lpi_gpio_pad *pad, unsigned int addr, unsigned int val) { + struct lpi_gpio_state *state = dev_get_drvdata(lpi_dev); + int ret = 0; + if (!lpi_dev_up) { pr_err_ratelimited("%s: ADSP is down due to SSR, return\n", - __func__); + __func__); return 0; } pm_runtime_get_sync(lpi_dev); + if (!state->core_hw_vote_status) { + pr_err_ratelimited("%s: core hw vote clk is not enabled\n", + __func__); + ret = -EINVAL; + goto err; + } iowrite32(val, pad->base + pad->offset + addr); - +err: pm_runtime_mark_last_busy(lpi_dev); pm_runtime_put_autosuspend(lpi_dev); - return 0; + return ret; } static int lpi_gpio_get_groups_count(struct pinctrl_dev *pctldev) -- GitLab From e8367cbe5d59e579ca67d9e5f97545e98ef8d2d3 Mon Sep 17 00:00:00 2001 From: Sachin Mohan Gadag Date: Thu, 27 Jun 2019 20:15:41 +0530 Subject: [PATCH 1054/1645] Makefile: Fix Extraneous text after `ifeq' directive - Remove extra brace in ifeq check. Change-Id: I3a96f6244304fbac48ebc3d569ca725a38697cad --- Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index b705366b6c23..55f77878933b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,7 +14,7 @@ AUDIO_KERNEL_HEADERS_PATH3 = $(shell ls ./include/uapi/sound/*.h) ifeq ($(TARGET_SUPPORT),qcs40x) KBUILD_OPTIONS += CONFIG_ARCH_QCS405=y endif -ifeq ($(TARGET_SUPPORT), sdmsteppe)) +ifeq ($(TARGET_SUPPORT), sdmsteppe) KBUILD_OPTIONS += CONFIG_ARCH_SM6150=y endif @@ -32,7 +32,7 @@ obj-m += asoc/codecs/bolero/ obj-m += asoc/codecs/csra66x0/ obj-m += asoc/codecs/ep92/ endif -ifeq ($(TARGET_SUPPORT), sdmsteppe)) +ifeq ($(TARGET_SUPPORT), sdmsteppe) obj-m += asoc/codecs/bolero/ obj-m += asoc/codecs/wcd937x/ endif -- GitLab From ab07f12b3a8b055370004b71d87854840a3c8d6e Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Thu, 27 Jun 2019 13:57:57 +0800 Subject: [PATCH 1055/1645] dsp: ion: unmap DMA buffer after kernel ion map failure DMA buffer does not unmap after kernel ion map failure. It leads to unexpected vaddr and memory leak. Change-Id: I363dd9178a0bcbca601180bfd0a7bd7ef2430d3e Signed-off-by: Xiaojun Sang --- dsp/msm_audio_ion.c | 10 ++++------ dsp/msm_audio_ion_vm.c | 6 +++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index a2f5127be118..566f8bf1b80b 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -316,6 +316,7 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr, if (rc) { pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", __func__, rc); + dma_buf_put(dma_buf); goto err; } @@ -323,6 +324,7 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr, if (IS_ERR_OR_NULL(*vaddr)) { pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); rc = -ENOMEM; + msm_audio_dma_buf_unmap(dma_buf); goto err; } @@ -384,17 +386,13 @@ int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz, rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr); if (rc) { pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc); - goto err_dma_buf; + goto err; } pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, *vaddr, bufsz); memset(*vaddr, 0, bufsz); - return rc; - -err_dma_buf: - dma_buf_put(*dma_buf); err: return rc; } @@ -488,7 +486,7 @@ int msm_audio_ion_import(struct dma_buf **dma_buf, int fd, rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr); if (rc) { pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc); - goto err_ion_flag; + goto err; } pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, *vaddr, bufsz); diff --git a/dsp/msm_audio_ion_vm.c b/dsp/msm_audio_ion_vm.c index aba015091d5e..fc6039a6bee5 100644 --- a/dsp/msm_audio_ion_vm.c +++ b/dsp/msm_audio_ion_vm.c @@ -547,6 +547,7 @@ static int msm_audio_ion_map_buf(void *handle, dma_addr_t *paddr, if (rc) { pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", __func__, rc); + dma_buf_put(dma_buf); goto err; } @@ -554,6 +555,7 @@ static int msm_audio_ion_map_buf(void *handle, dma_addr_t *paddr, if (IS_ERR_OR_NULL(*vaddr)) { pr_err("%s: ION memory mapping for AUDIO failed\n", __func__); rc = -ENOMEM; + msm_audio_dma_buf_unmap(dma_buf); goto err; } @@ -624,7 +626,6 @@ int msm_audio_ion_alloc(void **handle, size_t bufsz, if (rc) { pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc); - dma_buf_put((struct dma_buf*) *handle); } } else { rc = msm_audio_dma_buf_map(*handle, *vaddr, paddr, @@ -641,7 +642,6 @@ int msm_audio_ion_alloc(void **handle, size_t bufsz, memset(*vaddr, 0, bufsz); - return rc; err: return rc; } @@ -699,7 +699,7 @@ int msm_audio_ion_import(void **handle, int fd, rc = msm_audio_ion_map_buf(*handle, paddr, plen, vaddr); if (rc) { pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc); - goto err_ion_flag; + goto err; } pr_debug("%s: mapped address = %pK, size=%zd\n", __func__, *vaddr, bufsz); -- GitLab From ea4ace171f43f4c2a69f6c1de1e9e00a08411f98 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 25 Jun 2019 17:28:59 +0800 Subject: [PATCH 1056/1645] soc: lpi: force lpi runtime suspend during adsp ssr During adsp SSR, lpi runtime suspend is not called and hw vote clks are not reset. Force LPI runtime suspend during adsp SSR to avoid kernel panic. Change-Id: I153c5826a282d7beb175a41a55e2d6bf5907eb62 Signed-off-by: Meng Wang --- soc/pinctrl-lpi.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index ff9e9406c438..c4e998558808 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -111,6 +111,7 @@ struct lpi_gpio_state { struct clk *lpass_core_hw_vote; struct mutex slew_access_lock; bool core_hw_vote_status; + struct mutex core_hw_vote_lock; }; static const char *const lpi_gpio_groups[] = { @@ -134,6 +135,8 @@ static const char *const lpi_gpio_functions[] = { [LPI_GPIO_FUNC_INDEX_FUNC5] = LPI_GPIO_FUNC_FUNC5, }; +int lpi_pinctrl_runtime_suspend(struct device *dev); + static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr) { int ret; @@ -464,7 +467,11 @@ static struct notifier_block service_nb = { static void lpi_pinctrl_ssr_disable(struct device *dev, void *data) { + struct lpi_gpio_state *state = dev_get_drvdata(dev); + lpi_dev_up = false; + if (state->core_hw_vote_status) + lpi_pinctrl_runtime_suspend(dev); } static const struct snd_event_ops lpi_pinctrl_ssr_ops = { @@ -664,6 +671,7 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) state->chip.can_sleep = false; mutex_init(&state->slew_access_lock); + mutex_init(&state->core_hw_vote_lock); state->ctrl = devm_pinctrl_register(dev, pctrldesc, state); if (IS_ERR(state->ctrl)) @@ -724,6 +732,7 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) err_range: gpiochip_remove(&state->chip); err_chip: + mutex_destroy(&state->core_hw_vote_lock); mutex_destroy(&state->slew_access_lock); err_io: return ret; @@ -739,6 +748,7 @@ static int lpi_pinctrl_remove(struct platform_device *pdev) snd_event_client_deregister(&pdev->dev); audio_notifier_deregister("lpi_tlmm"); gpiochip_remove(&state->chip); + mutex_destroy(&state->core_hw_vote_lock); mutex_destroy(&state->slew_access_lock); return 0; @@ -761,6 +771,7 @@ int lpi_pinctrl_runtime_resume(struct device *dev) return 0; } + mutex_lock(&state->core_hw_vote_lock); ret = clk_prepare_enable(state->lpass_core_hw_vote); if (ret < 0) dev_err(dev, "%s:lpass core hw island enable failed\n", @@ -769,6 +780,7 @@ int lpi_pinctrl_runtime_resume(struct device *dev) state->core_hw_vote_status = true; pm_runtime_set_autosuspend_delay(dev, LPI_AUTO_SUSPEND_DELAY); + mutex_unlock(&state->core_hw_vote_lock); return 0; } @@ -781,10 +793,12 @@ int lpi_pinctrl_runtime_suspend(struct device *dev) return 0; } + mutex_lock(&state->core_hw_vote_lock); if (state->core_hw_vote_status) { clk_disable_unprepare(state->lpass_core_hw_vote); state->core_hw_vote_status = false; } + mutex_unlock(&state->core_hw_vote_lock); return 0; } -- GitLab From bf1fe8fbadafa1be4ba0bf09aa310215d72abaeb Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 26 Jun 2019 15:39:41 +0800 Subject: [PATCH 1057/1645] asoc: bolero: force bolero runtime suspend during adsp ssr During adsp SSR, bolero runtime suspend is not called and hw vote clks are not reset. Force bolero runtime suspend during adsp SSR to avoid kernel panic. Change-Id: Iff5983ef07f77ecc7f3f344948c013906b4bad60 Signed-off-by: Meng Wang --- asoc/codecs/bolero/rx-macro.c | 2 ++ asoc/codecs/bolero/tx-macro.c | 2 ++ asoc/codecs/bolero/va-macro.c | 4 ++++ asoc/codecs/bolero/wsa-macro.c | 2 ++ 4 files changed, 10 insertions(+) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 285324d9ad9a..ed820ab7ad62 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1224,6 +1224,8 @@ static int rx_macro_event_handler(struct snd_soc_component *component, rx_priv->swr_ctrl_data[0].rx_swr_pdev, SWR_DEVICE_SSR_DOWN, NULL); } + if (!pm_runtime_status_suspended(rx_dev)) + bolero_runtime_suspend(rx_dev); break; case BOLERO_MACRO_EVT_SSR_UP: rx_priv->dev_up = true; diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 908fb3f402fc..bc5b056b03ec 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -354,6 +354,8 @@ static int tx_macro_event_handler(struct snd_soc_component *component, tx_priv->swr_ctrl_data[0].tx_swr_pdev, SWR_DEVICE_SSR_DOWN, NULL); } + if (!pm_runtime_status_suspended(tx_dev)) + bolero_runtime_suspend(tx_dev); break; case BOLERO_MACRO_EVT_SSR_UP: /* reset swr after ssr/pdr */ diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index a94ca7701203..e96d357b9808 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -237,6 +237,10 @@ static int va_macro_event_handler(struct snd_soc_component *component, case BOLERO_MACRO_EVT_CLK_RESET: bolero_rsc_clk_reset(va_dev, VA_CORE_CLK); break; + case BOLERO_MACRO_EVT_SSR_DOWN: + if (!pm_runtime_status_suspended(va_dev)) + bolero_runtime_suspend(va_dev); + break; default: break; } diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 3ca5d4c1d55c..fe5811da4b03 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -919,6 +919,8 @@ static int wsa_macro_event_handler(struct snd_soc_component *component, wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, SWR_DEVICE_SSR_DOWN, NULL); } + if (!pm_runtime_status_suspended(wsa_dev)) + bolero_runtime_suspend(wsa_dev); break; case BOLERO_MACRO_EVT_SSR_UP: /* reset swr after ssr/pdr */ -- GitLab From 36a5eb40be58777e5cc9a68c46bb7991d4e0a07a Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 27 Mar 2019 19:15:03 +0530 Subject: [PATCH 1058/1645] asoc: Use dma_buf_get along with dma_buf_fd Use dma_buf_get along with dma_buf_fd on the obtained fd in order to increment the reference count and avoid use after free on fd when it is freed from userspace. CRs-Fixed: 2419587 Change-Id: I57e1396234eebb60224ed58182cca80888e94a9e Signed-off-by: Aditya Bavanari --- asoc/msm-pcm-q6-noirq.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index b33eba3fc76a..5b978311b0ff 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -445,6 +445,8 @@ static int msm_pcm_mmap_fd(struct snd_pcm_substream *substream, struct audio_port_data *apd; struct audio_buffer *ab; int dir = -1; + struct dma_buf *buf = NULL; + int rc = 0; if (!substream->runtime) { pr_err("%s substream runtime not found\n", __func__); @@ -471,12 +473,25 @@ static int msm_pcm_mmap_fd(struct snd_pcm_substream *substream, * used to call dma_buf_fd internally. */ mmap_fd->fd = dma_buf_fd(ab->dma_buf, O_CLOEXEC); - if (mmap_fd->fd >= 0) { - mmap_fd->dir = dir; - mmap_fd->actual_size = ab->actual_size; - mmap_fd->size = ab->size; + if (mmap_fd->fd < 0) { + pr_err("%s: dma_buf_fd failed, fd:%d\n", + __func__, mmap_fd->fd); + rc = -EFAULT; + goto buf_fd_fail; + } + mmap_fd->dir = dir; + mmap_fd->actual_size = ab->actual_size; + mmap_fd->size = ab->size; + + buf = dma_buf_get(mmap_fd->fd); + if (IS_ERR_OR_NULL(buf)) { + pr_err("%s: dma_buf_get failed, fd:%d\n", + __func__, mmap_fd->fd); + rc = -EINVAL; } - return mmap_fd->fd < 0 ? -EFAULT : 0; + +buf_fd_fail: + return rc; } static int msm_pcm_ioctl(struct snd_pcm_substream *substream, -- GitLab From e0b9234773c66f09281f40866339df9bb2ab39de Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Mon, 1 Jul 2019 10:07:20 +0200 Subject: [PATCH 1059/1645] dsp: Fix open params for read_compr in IEC61937 mode The read compressed in IEC61937 mode doesn't unpack data to frames, but data flow still requires frames_per_buf to be set to nonzero value. Change-Id: Idb09219c57d7790cb90df62c97baf3ef0e9d8a2f Signed-off-by: Ralf Herz --- dsp/q6asm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 29d8064f6565..79ac3c947fac 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -3085,6 +3085,7 @@ int q6asm_open_read_compressed(struct audio_client *ac, uint32_t format, */ if (format == FORMAT_IEC61937) { open.mode_flags = 0x1; + open.frames_per_buf = 1; pr_debug("%s: Flag 1 IEC61937 output\n", __func__); } else { open.mode_flags = 0; -- GitLab From b778846e50b7f89ef90092f5d454bc73c651c514 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 2 Jul 2019 20:08:14 +0530 Subject: [PATCH 1060/1645] dsp: Remove param_size from pkt_size of apr header As param_size is included in apr header pkt_size, out of bounds access occurs in glink. Remove the param size addition to fix this issue. CRs-Fixed: 2472208 Change-Id: If8b34aeacd3bc9ba67ac9276eb1a8ebf0933f9f9 Signed-off-by: Aditya Bavanari --- dsp/q6afe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 0fe38885f7c9..56b50ef00c45 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1292,7 +1292,7 @@ static int q6afe_get_params_v2(u16 port_id, int index, afe_get_param.apr_hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - afe_get_param.apr_hdr.pkt_size = sizeof(afe_get_param) + param_size; + afe_get_param.apr_hdr.pkt_size = sizeof(afe_get_param); afe_get_param.apr_hdr.src_port = 0; afe_get_param.apr_hdr.dest_port = 0; afe_get_param.apr_hdr.token = index; -- GitLab From 3e11dbd71ed3c34c55c02e95d8316a9f6c6d45d1 Mon Sep 17 00:00:00 2001 From: Romed Schur Date: Thu, 4 Jul 2019 10:03:57 +0200 Subject: [PATCH 1061/1645] asoc: qcs405: Add DSD over PCM support for csra66x0 codec Enable DSD over PCM stereo support of QCS405 and csra66x0 codec. Change-Id: Iedc8231d6e19f4959f525395e8b0ebc69746d879 Signed-off-by: Romed Schur --- asoc/qcs405.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 15fff2aa53f8..089930ecebb0 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -480,7 +480,8 @@ static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_16", "KHZ_22P05", "KHZ_32", "KHZ_44P1", - "KHZ_48", "KHZ_96", "KHZ_192", "KHZ_384"}; + "KHZ_48", "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; static const char *const mi2s_ch_text[] = { "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", @@ -2724,15 +2725,24 @@ static int mi2s_get_sample_rate_val(int sample_rate) case SAMPLING_RATE_48KHZ: sample_rate_val = 6; break; - case SAMPLING_RATE_96KHZ: + case SAMPLING_RATE_88P2KHZ: sample_rate_val = 7; break; - case SAMPLING_RATE_192KHZ: + case SAMPLING_RATE_96KHZ: sample_rate_val = 8; break; - case SAMPLING_RATE_384KHZ: + case SAMPLING_RATE_176P4KHZ: sample_rate_val = 9; break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; default: sample_rate_val = 6; break; @@ -2767,12 +2777,21 @@ static int mi2s_get_sample_rate(int value) sample_rate = SAMPLING_RATE_48KHZ; break; case 7: - sample_rate = SAMPLING_RATE_96KHZ; + sample_rate = SAMPLING_RATE_88P2KHZ; break; case 8: - sample_rate = SAMPLING_RATE_192KHZ; + sample_rate = SAMPLING_RATE_96KHZ; break; case 9: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 10: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 11: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 12: sample_rate = SAMPLING_RATE_384KHZ; break; default: -- GitLab From b0fe92c09f7341e45fa660433ab41ae855330f61 Mon Sep 17 00:00:00 2001 From: Romed Schur Date: Thu, 4 Jul 2019 11:22:59 +0200 Subject: [PATCH 1062/1645] asoc: Add DSD over PCM support for csra66x0 codec Configuration added to support stereo DSD over PCM for csra66x0 codec via I2S interface. Change-Id: Ibed333e44961a9eb87ef69bfb1e302f5837357d9 Signed-off-by: Romed Schur --- asoc/msm-dai-q6-v2.c | 11 +++++++++-- include/dsp/apr_audio-v2.h | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index f09d9e1c56eb..7cb2c0b258c4 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -301,12 +301,19 @@ struct msm_dai_q6_tdm_dai_data { * 1: non-linear PCM * 2: PCM data in IEC 60968 container * 3: compressed data in IEC 60958 container + * 9: DSD over PCM (DoP) with marker byte */ static const char *const mi2s_format[] = { "LPCM", "Compr", "LPCM-60958", - "Compr-60958" + "Compr-60958", + "NA4", + "NA5", + "NA6", + "NA7", + "NA8", + "DSD_DOP_W_MARKER" }; static const char *const mi2s_vi_feed_mono[] = { @@ -315,7 +322,7 @@ static const char *const mi2s_vi_feed_mono[] = { }; static const struct soc_enum mi2s_config_enum[] = { - SOC_ENUM_SINGLE_EXT(4, mi2s_format), + SOC_ENUM_SINGLE_EXT(10, mi2s_format), SOC_ENUM_SINGLE_EXT(2, mi2s_vi_feed_mono), }; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index a90cb05bcd6f..3468ca778f7d 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -2539,6 +2539,7 @@ struct afe_port_data_cmd_rt_proxy_port_read_v2 { #define AFE_NON_LINEAR_DATA_PACKED_60958 0x3 #define AFE_GENERIC_COMPRESSED 0x8 #define AFE_LINEAR_PCM_DATA_PACKED_16BIT 0X6 +#define AFE_DSD_DOP_W_MARKER_DATA 0x9 /* This param id is used to configure I2S interface */ #define AFE_PARAM_ID_I2S_CONFIG 0x0001020D @@ -2643,6 +2644,7 @@ struct afe_param_id_i2s_cfg { * - #NON_LINEAR_DATA * - #LINEAR_PCM_DATA_PACKED_IN_60958 * - #NON_LINEAR_DATA_PACKED_IN_60958 + * - #AFE_DSD_DOP_W_MARKER_DATA */ u16 reserved; /* This field must be set to zero. */ -- GitLab From 38d66474e116ad607fdb48b2fd20ed433d87dbfe Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Fri, 29 Mar 2019 18:08:07 +0530 Subject: [PATCH 1063/1645] audio-kernel: add support to query presentation position from DSP Add support to query presentation position from DSP in system time domain. Change-Id: I42b4d234ddc256f93c01defbe2c74872a2a2cf3e Signed-off-by: Surendar Karka --- asoc/msm-compress-q6-v2.c | 56 ++++++++++++++--- asoc/msm-pcm-q6-v2.c | 97 +++++++++++++++++++++++++++++- dsp/avtimer.c | 55 +++++++++++++++++ dsp/q6asm.c | 52 ++++++++++++---- include/dsp/q6asm-v2.h | 11 +++- include/dsp/q6core.h | 1 + include/uapi/sound/devdep_params.h | 8 +++ 7 files changed, 256 insertions(+), 24 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index a3618caa5e73..6be0b163d545 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -3153,13 +3153,18 @@ static int msm_compr_get_metadata(struct snd_compr_stream *cstream, struct msm_compr_audio *prtd; struct audio_client *ac; int ret = -EINVAL; + uint64_t ses_time = 0, frames = 0, abs_time = 0; + uint64_t *val = NULL; + int64_t av_offset = 0; + int32_t clock_id = -EINVAL; pr_debug("%s\n", __func__); if (!metadata || !cstream || !cstream->runtime) return ret; - if (metadata->key != SNDRV_COMPRESS_PATH_DELAY) { + if (metadata->key != SNDRV_COMPRESS_PATH_DELAY && + metadata->key != SNDRV_COMPRESS_DSP_POSITION) { pr_err("%s, unsupported key %d\n", __func__, metadata->key); return ret; } @@ -3170,17 +3175,50 @@ static int msm_compr_get_metadata(struct snd_compr_stream *cstream, return ret; } - ac = prtd->audio_client; - ret = q6asm_get_path_delay(prtd->audio_client); - if (ret) { - pr_err("%s: get_path_delay failed, ret=%d\n", __func__, ret); - return ret; - } + switch (metadata->key) { + case SNDRV_COMPRESS_PATH_DELAY: + ac = prtd->audio_client; + ret = q6asm_get_path_delay(prtd->audio_client); + if (ret) { + pr_err("%s: get_path_delay failed, ret=%d\n", + __func__, ret); + return ret; + } - pr_debug("%s, path delay(in us) %u\n", __func__, ac->path_delay); + pr_debug("%s, path delay(in us) %u\n", __func__, + ac->path_delay); + metadata->value[0] = ac->path_delay; + break; + case SNDRV_COMPRESS_DSP_POSITION: + clock_id = metadata->value[0]; + pr_debug("%s, clock_id %d\n", __func__, clock_id); + ret = q6asm_get_session_time_v2(prtd->audio_client, + &ses_time, &abs_time); + if (ret) { + pr_err("%s: q6asm_get_session_time_v2 failed, ret=%d\n", + __func__, ret); + return ret; + } + frames = div64_u64((ses_time * prtd->sample_rate), 1000000); - metadata->value[0] = ac->path_delay; + ret = avcs_core_query_timer_offset(&av_offset, clock_id); + if (ret) { + pr_err("%s: avcs query failed, ret=%d\n", + __func__, ret); + return ret; + } + val = (uint64_t *) &metadata->value[1]; + val[0] = frames; + val[1] = abs_time + av_offset; + pr_debug("%s, vals frames %lld, time %lld, avoff %lld, abst %lld, sess_time %llu sr %d\n", + __func__, val[0], val[1], av_offset, abs_time, + ses_time, prtd->sample_rate); + break; + default: + pr_err("%s, unsupported key %d\n", __func__, metadata->key); + break; + } return ret; } diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index af158432630f..678badc363ef 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -1156,12 +1157,106 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream, return 0; } +static int msm_pcm_ioctl(struct snd_pcm_substream *substream, + unsigned int cmd, void __user *arg) +{ + struct msm_audio *prtd = NULL; + struct snd_soc_pcm_runtime *rtd = NULL; + uint64_t ses_time = 0, abs_time = 0; + int64_t av_offset = 0; + int32_t clock_id = -EINVAL; + int rc = 0; + struct snd_pcm_prsnt_position userarg; + + if (!substream || !substream->private_data) { + pr_err("%s: Invalid %s\n", __func__, + (!substream) ? "substream" : "private_data"); + return -EINVAL; + } + + if (!substream->runtime) { + pr_err("%s substream runtime not found\n", __func__); + return -EINVAL; + } + + prtd = substream->runtime->private_data; + if (!prtd) { + pr_err("%s prtd is null.\n", __func__); + return -EINVAL; + } + + rtd = substream->private_data; + + switch (cmd) { + case SNDRV_PCM_IOCTL_DSP_POSITION: + dev_dbg(rtd->dev, "%s: SNDRV_PCM_DSP_POSITION", __func__); + if (!arg) { + dev_err(rtd->dev, "%s: Invalid params DSP_POSITION\n", + __func__); + rc = -EINVAL; + goto done; + } + memset(&userarg, 0, sizeof(userarg)); + if (copy_from_user(&userarg, arg, sizeof(userarg))) { + dev_err(rtd->dev, "%s: err copyuser DSP_POSITION\n", + __func__); + rc = -EFAULT; + goto done; + } + clock_id = userarg.clock_id; + rc = q6asm_get_session_time_v2(prtd->audio_client, &ses_time, + &abs_time); + if (rc) { + pr_err("%s: q6asm_get_session_time_v2 failed, rc=%d\n", + __func__, rc); + goto done; + } + userarg.frames = div64_u64((ses_time * prtd->samp_rate), + 1000000); + + rc = avcs_core_query_timer_offset(&av_offset, clock_id); + if (rc) { + pr_err("%s: avcs offset query failed, rc=%d\n", + __func__, rc); + goto done; + } + + userarg.timestamp = abs_time + av_offset; + if (copy_to_user(arg, &userarg, sizeof(userarg))) { + dev_err(rtd->dev, "%s: err copy to user DSP_POSITION\n", + __func__); + rc = -EFAULT; + goto done; + } + pr_debug("%s, vals f %lld, t %lld, avoff %lld, abst %lld, sess_time %llu sr %d\n", + __func__, userarg.frames, userarg.timestamp, + av_offset, abs_time, ses_time, prtd->samp_rate); + break; + default: + rc = snd_pcm_lib_ioctl(substream, cmd, arg); + break; + } +done: + return rc; +} + +#ifdef CONFIG_COMPAT +static int msm_pcm_compat_ioctl(struct snd_pcm_substream *substream, + unsigned int cmd, void __user *arg) +{ + return msm_pcm_ioctl(substream, cmd, arg); +} +#else +#define msm_pcm_compat_ioctl NULL +#endif + static const struct snd_pcm_ops msm_pcm_ops = { .open = msm_pcm_open, .copy_user = msm_pcm_copy, .hw_params = msm_pcm_hw_params, .close = msm_pcm_close, - .ioctl = snd_pcm_lib_ioctl, + .ioctl = msm_pcm_ioctl, + .compat_ioctl = msm_pcm_compat_ioctl, .prepare = msm_pcm_prepare, .trigger = msm_pcm_trigger, .pointer = msm_pcm_pointer, diff --git a/dsp/avtimer.c b/dsp/avtimer.c index 554f030409f1..8d9402c91730 100644 --- a/dsp/avtimer.c +++ b/dsp/avtimer.c @@ -309,6 +309,61 @@ int avcs_core_query_timer(uint64_t *avtimer_tick) } EXPORT_SYMBOL(avcs_core_query_timer); +/* + * avcs_core_query_timer_offset: + * derive offset between system clock & avtimer clock + * + * @ avoffset: offset between system clock & avtimer clock + * @ clock_id: clock id to get the system time + * + */ +int avcs_core_query_timer_offset(int64_t *av_offset, int32_t clock_id) +{ + uint32_t avtimer_msw = 0, avtimer_lsw = 0; + uint64_t avtimer_tick_temp, avtimer_tick, sys_time = 0; + struct timespec ts; + + if ((avtimer.p_avtimer_lsw == NULL) || + (avtimer.p_avtimer_msw == NULL)) { + return -EINVAL; + } + + memset(&ts, 0, sizeof(struct timespec)); + avtimer_lsw = ioread32(avtimer.p_avtimer_lsw); + avtimer_msw = ioread32(avtimer.p_avtimer_msw); + + switch (clock_id) { + case CLOCK_MONOTONIC_RAW: + getrawmonotonic(&ts); + break; + case CLOCK_BOOTTIME: + get_monotonic_boottime(&ts); + break; + case CLOCK_MONOTONIC: + ktime_get_ts(&ts); + break; + case CLOCK_REALTIME: + ktime_get_real_ts(&ts); + break; + default: + pr_debug("%s: unsupported clock id %d\n", __func__, clock_id); + return -EINVAL; + } + + sys_time = ts.tv_sec * 1000000LL + div64_u64(ts.tv_nsec, 1000); + avtimer_tick_temp = (uint64_t)((uint64_t)avtimer_msw << 32) | + avtimer_lsw; + + avtimer_tick = mul_u64_u32_div(avtimer_tick_temp, avtimer.clk_mult, + avtimer.clk_div); + *av_offset = sys_time - avtimer_tick; + pr_debug("%s: sys_time: %llu, offset %lld, avtimer tick %lld\n", + __func__, sys_time, *av_offset, avtimer_tick); + + return 0; +} +EXPORT_SYMBOL(avcs_core_query_timer_offset); + #if IS_ENABLED(CONFIG_AVTIMER_LEGACY) static void avcs_set_isp_fptr(bool enable) { diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 29d8064f6565..41a131947831 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1868,12 +1868,20 @@ static void q6asm_process_mtmx_get_param_rsp(struct audio_client *ac, switch (cmdrsp->param_info.param_id) { case ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3: time = &cmdrsp->param_data.session_time; - dev_vdbg(ac->dev, "%s: GET_TIME_V3, time_lsw=%x, time_msw=%x\n", + dev_vdbg(ac->dev, "%s: GET_TIME_V3, time_lsw=%x, time_msw=%x, abs l %x, m %x\n", __func__, time->session_time_lsw, - time->session_time_msw); - ac->time_stamp = (uint64_t)(((uint64_t) + time->session_time_msw, + time->absolute_time_lsw, + time->absolute_time_msw); + ac->dsp_ts.abs_time_stamp = (uint64_t)(((uint64_t) + time->absolute_time_msw << 32) | + time->absolute_time_lsw); + ac->dsp_ts.time_stamp = (uint64_t)(((uint64_t) time->session_time_msw << 32) | time->session_time_lsw); + ac->dsp_ts.last_time_stamp = (uint64_t)(((uint64_t) + time->time_stamp_msw << 32) | + time->time_stamp_lsw); if (time->flags & ASM_SESSION_MTMX_STRTR_PARAM_STIME_TSTMP_FLG_BMASK) dev_warn_ratelimited(ac->dev, @@ -2361,8 +2369,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) dev_vdbg(ac->dev, "%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3, payload[0] = %d, payload[1] = %d, payload[2] = %d\n", __func__, payload[0], payload[1], payload[2]); - ac->time_stamp = (uint64_t)(((uint64_t)payload[2] << 32) | - payload[1]); + ac->dsp_ts.time_stamp = + (uint64_t)(((uint64_t)payload[2] << 32) | + payload[1]); } else { dev_err(ac->dev, "%s: payload size of %x is less than expected.n", __func__, data->payload_size); @@ -9761,15 +9770,17 @@ int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts, EXPORT_SYMBOL(q6asm_write_nolock); /** - * q6asm_get_session_time - + * q6asm_get_session_time_v2 - * command to retrieve timestamp info * * @ac: Audio client handle - * @tstamp: pointer to fill with timestamp info + * @ses_time: pointer to fill with session timestamp info + * @abs_time: pointer to fill with AVS timestamp info * * Returns 0 on success or error on failure */ -int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) +int q6asm_get_session_time_v2(struct audio_client *ac, uint64_t *ses_time, + uint64_t *abs_time) { struct asm_mtmx_strtr_get_params mtmx_params; int rc; @@ -9782,8 +9793,8 @@ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) pr_err("%s: AC APR handle NULL\n", __func__); return -EINVAL; } - if (tstamp == NULL) { - pr_err("%s: tstamp NULL\n", __func__); + if (ses_time == NULL) { + pr_err("%s: tstamp args are NULL\n", __func__); return -EINVAL; } @@ -9821,12 +9832,29 @@ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) goto fail_cmd; } - *tstamp = ac->time_stamp; + *ses_time = ac->dsp_ts.time_stamp; + if (abs_time != NULL) + *abs_time = ac->dsp_ts.abs_time_stamp; return 0; fail_cmd: return -EINVAL; } +EXPORT_SYMBOL(q6asm_get_session_time_v2); + +/** + * q6asm_get_session_time - + * command to retrieve timestamp info + * + * @ac: Audio client handle + * @tstamp: pointer to fill with timestamp info + * + * Returns 0 on success or error on failure + */ +int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) +{ + return q6asm_get_session_time_v2(ac, tstamp, NULL); +} EXPORT_SYMBOL(q6asm_get_session_time); /** @@ -9878,7 +9906,7 @@ int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp) goto fail_cmd; } - *tstamp = ac->time_stamp; + *tstamp = ac->dsp_ts.time_stamp; return 0; fail_cmd: diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index de7e31b9eebd..5db8fde22ad9 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -207,6 +207,12 @@ struct shared_io_config { uint32_t bufcnt; }; +struct dsp_timestamp { + uint64_t time_stamp; + uint64_t abs_time_stamp; + uint64_t last_time_stamp; +}; + struct audio_client { int session; app_cb cb; @@ -218,7 +224,7 @@ struct audio_client { atomic_t mem_state; void *priv; uint32_t io_mode; - uint64_t time_stamp; + struct dsp_timestamp dsp_ts; struct apr_svc *apr; struct apr_svc *mmap_apr; struct apr_svc *apr2; @@ -683,7 +689,8 @@ int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, int q6asm_set_mute(struct audio_client *ac, int muteflag); int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp); - +int q6asm_get_session_time_v2(struct audio_client *ac, uint64_t *ses_time, + uint64_t *abs_time); int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp); int q6asm_send_stream_cmd(struct audio_client *ac, diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index 61bede7f99d1..8bac34a7ed5a 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -17,6 +17,7 @@ bool q6core_is_adsp_ready(void); +int avcs_core_query_timer_offset(int64_t *av_offset, int32_t clock_id); int q6core_get_service_version(uint32_t service_id, struct avcs_fwk_ver_info *ver_info, size_t size); diff --git a/include/uapi/sound/devdep_params.h b/include/uapi/sound/devdep_params.h index 66a9cacfcab9..abdf10636f4d 100644 --- a/include/uapi/sound/devdep_params.h +++ b/include/uapi/sound/devdep_params.h @@ -61,6 +61,14 @@ struct snd_pcm_mmap_fd { int32_t actual_size; }; +struct snd_pcm_prsnt_position { + uint64_t timestamp; + uint64_t frames; + int32_t clock_id; +}; + #define SNDRV_PCM_IOCTL_MMAP_DATA_FD _IOWR('U', 0xd2, struct snd_pcm_mmap_fd) +#define SNDRV_PCM_IOCTL_DSP_POSITION\ + _IOWR('U', 0xd3, struct snd_pcm_prsnt_position) #endif -- GitLab From d974cf93b1e81b1efff224b82b2a780714605ba9 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Tue, 11 Jun 2019 16:34:09 -0700 Subject: [PATCH 1064/1645] asoc: codecs: wcd938x: add support for micbias pull up mode Add support to use micbias pull up mode for SVA DMIC use cases to lower power consumption. Change-Id: I5d87b604bb3e588ffec0ae321a55d340c89274fc Signed-off-by: Xiaoyu Ye --- asoc/codecs/wcd938x/wcd938x.c | 64 +++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 8113ab4204f2..8a02d6f81f07 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1779,6 +1779,52 @@ static int wcd938x_codec_enable_micbias(struct snd_soc_dapm_widget *w, return __wcd938x_codec_enable_micbias(w, event); } +static int __wcd938x_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w, + int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + int micb_num; + + dev_dbg(component->dev, "%s: wname: %s, event: %d\n", + __func__, w->name, event); + + if (strnstr(w->name, "VA MIC BIAS1", sizeof("VA MIC BIAS1"))) + micb_num = MIC_BIAS_1; + else if (strnstr(w->name, "VA MIC BIAS2", sizeof("VA MIC BIAS2"))) + micb_num = MIC_BIAS_2; + else if (strnstr(w->name, "VA MIC BIAS3", sizeof("VA MIC BIAS3"))) + micb_num = MIC_BIAS_3; + else if (strnstr(w->name, "VA MIC BIAS4", sizeof("VA MIC BIAS4"))) + micb_num = MIC_BIAS_4; + else + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd938x_micbias_control(component, micb_num, + MICB_PULLUP_ENABLE, true); + break; + case SND_SOC_DAPM_POST_PMU: + /* 1 msec delay as per HW requirement */ + usleep_range(1000, 1100); + break; + case SND_SOC_DAPM_POST_PMD: + wcd938x_micbias_control(component, micb_num, + MICB_PULLUP_DISABLE, true); + break; + }; + + return 0; + +} + +static int wcd938x_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + return __wcd938x_codec_enable_micbias_pullup(w, event); +} + static inline int wcd938x_tx_path_get(const char *wname, unsigned int *path_num) { @@ -2364,6 +2410,24 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("AUX"), SND_SOC_DAPM_OUTPUT("HPHL"), SND_SOC_DAPM_OUTPUT("HPHR"), + + /* micbias pull up widgets*/ + SND_SOC_DAPM_MICBIAS_E("VA MIC BIAS1", SND_SOC_NOPM, 0, 0, + wcd938x_codec_enable_micbias_pullup, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("VA MIC BIAS2", SND_SOC_NOPM, 0, 0, + wcd938x_codec_enable_micbias_pullup, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("VA MIC BIAS3", SND_SOC_NOPM, 0, 0, + wcd938x_codec_enable_micbias_pullup, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("VA MIC BIAS4", SND_SOC_NOPM, 0, 0, + wcd938x_codec_enable_micbias_pullup, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), }; static const struct snd_soc_dapm_route wcd938x_audio_map[] = { -- GitLab From 75fbc2d27dc033cd859d96efdb111f54436ccf4b Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 8 Jul 2019 11:59:32 +0530 Subject: [PATCH 1065/1645] asoc: codecs: wcd937x: Read and store mic bias value Mic bias value is needed in case of special headset detection logic and the same needs to be read and stored from device tree to be used by mbhc driver. Change-Id: I0b120b8bb130a4d101c97e118395a11e74c921af Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x-mbhc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index 4ad8683a490c..5ac7245a0f34 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -1051,6 +1051,7 @@ int wcd937x_mbhc_init(struct wcd937x_mbhc **mbhc, { struct wcd937x_mbhc *wcd937x_mbhc = NULL; struct wcd_mbhc *wcd_mbhc = NULL; + struct wcd937x_pdata *pdata; int ret = 0; if (!component) { @@ -1076,6 +1077,15 @@ int wcd937x_mbhc_init(struct wcd937x_mbhc **mbhc, /* Setting default mbhc detection logic to ADC */ wcd_mbhc->mbhc_detection_logic = WCD_DETECTION_ADC; + pdata = dev_get_platdata(component->dev); + if (!pdata) { + dev_err(component->dev, "%s: pdata pointer is NULL\n", + __func__); + ret = -EINVAL; + goto err; + } + wcd_mbhc->micb_mv = pdata->micbias.micb2_mv; + ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb, &intr_ids, wcd_mbhc_registers, WCD937X_ZDET_SUPPORTED); -- GitLab From d37e02049c339dba532d7f369b444e1dbcffb19c Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 8 Jul 2019 18:30:19 +0530 Subject: [PATCH 1066/1645] asoc: codecs: Add variant entry support for wcd937x and wcd938x Add variant entry support for wcd937x and wcd938x codecs to differentiate between wcd9370/80 and wcd9375/85 variants. Change-Id: Ife20d14462a0b0968e0458471af3823872592e10 Signed-off-by: Aditya Bavanari --- asoc/codecs/wcd937x/internal.h | 2 ++ asoc/codecs/wcd937x/wcd937x.c | 57 ++++++++++++++++++++++++++++++++- asoc/codecs/wcd938x/internal.h | 1 + asoc/codecs/wcd938x/wcd938x.c | 58 +++++++++++++++++++++++++++++++++- 4 files changed, 116 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index b7bdfa22dd7d..cd11c858b413 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -82,6 +82,8 @@ struct wcd937x_priv { /* Entry for version info */ struct snd_info_entry *entry; struct snd_info_entry *version_entry; + /*Entry for Variant info*/ + struct snd_info_entry *variant_entry; int ear_rx_path; int ana_clk_count; struct mutex ana_tx_clk_lock; diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index e89d9a9179ad..d4f3d1f7119e 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -29,6 +29,7 @@ #define WCD9370_VARIANT 0 #define WCD9375_VARIANT 5 +#define WCD937X_VARIANT_ENTRY_SIZE 32 #define NUM_SWRS_DT_PARAMS 5 @@ -2200,12 +2201,46 @@ static struct snd_info_entry_ops wcd937x_info_ops = { .read = wcd937x_version_read, }; +static ssize_t wcd937x_variant_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, size_t count, + loff_t pos) +{ + struct wcd937x_priv *priv; + char buffer[WCD937X_VARIANT_ENTRY_SIZE]; + int len = 0; + + priv = (struct wcd937x_priv *) entry->private_data; + if (!priv) { + pr_err("%s: wcd937x priv is null\n", __func__); + return -EINVAL; + } + + switch (priv->variant) { + case WCD9370_VARIANT: + len = snprintf(buffer, sizeof(buffer), "WCD9370\n"); + break; + case WCD9375_VARIANT: + len = snprintf(buffer, sizeof(buffer), "WCD9375\n"); + break; + default: + len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + } + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops wcd937x_variant_ops = { + .read = wcd937x_variant_read, +}; + /* * wcd937x_info_create_codec_entry - creates wcd937x module * @codec_root: The parent directory * @component: component instance * - * Creates wcd937x module and version entry under the given + * Creates wcd937x module, variant and version entry under the given * parent directory. * * Return: 0 on success or negative error code on failure. @@ -2214,6 +2249,7 @@ int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root, struct snd_soc_component *component) { struct snd_info_entry *version_entry; + struct snd_info_entry *variant_entry; struct wcd937x_priv *priv; struct snd_soc_card *card; @@ -2254,6 +2290,25 @@ int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root, } priv->version_entry = version_entry; + variant_entry = snd_info_create_card_entry(card->snd_card, + "variant", + priv->entry); + if (!variant_entry) { + dev_dbg(codec->dev, "%s: failed to create wcd937x variant entry\n", + __func__); + return -ENOMEM; + } + + variant_entry->private_data = priv; + variant_entry->size = WCD937X_VARIANT_ENTRY_SIZE; + variant_entry->content = SNDRV_INFO_CONTENT_DATA; + variant_entry->c.ops = &wcd937x_variant_ops; + + if (snd_info_register(variant_entry) < 0) { + snd_info_free_entry(variant_entry); + return -ENOMEM; + } + priv->variant_entry = variant_entry; return 0; } EXPORT_SYMBOL(wcd937x_info_create_codec_entry); diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index a54394446bd3..2a474054f570 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -94,6 +94,7 @@ struct wcd938x_priv { /* Entry for version info */ struct snd_info_entry *entry; struct snd_info_entry *version_entry; + struct snd_info_entry *variant_entry; int flyback_cur_det_disable; int ear_rx_path; }; diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 8113ab4204f2..864a11179e22 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -26,6 +26,7 @@ #define WCD938X_DRV_NAME "wcd938x_codec" #define NUM_SWRS_DT_PARAMS 5 +#define WCD938X_VARIANT_ENTRY_SIZE 32 #define WCD938X_VERSION_1_0 1 #define WCD938X_VERSION_ENTRY_SIZE 32 @@ -2482,12 +2483,46 @@ static struct snd_info_entry_ops wcd938x_info_ops = { .read = wcd938x_version_read, }; +static ssize_t wcd938x_variant_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, size_t count, + loff_t pos) +{ + struct wcd938x_priv *priv; + char buffer[WCD938X_VARIANT_ENTRY_SIZE]; + int len = 0; + + priv = (struct wcd938x_priv *) entry->private_data; + if (!priv) { + pr_err("%s: wcd938x priv is null\n", __func__); + return -EINVAL; + } + + switch (priv->variant) { + case WCD9380: + len = snprintf(buffer, sizeof(buffer), "WCD9380\n"); + break; + case WCD9385: + len = snprintf(buffer, sizeof(buffer), "WCD9385\n"); + break; + default: + len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + } + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops wcd938x_variant_ops = { + .read = wcd938x_variant_read, +}; + /* * wcd938x_info_create_codec_entry - creates wcd938x module * @codec_root: The parent directory * @component: component instance * - * Creates wcd938x module and version entry under the given + * Creates wcd938x module, variant and version entry under the given * parent directory. * * Return: 0 on success or negative error code on failure. @@ -2496,6 +2531,7 @@ int wcd938x_info_create_codec_entry(struct snd_info_entry *codec_root, struct snd_soc_component *component) { struct snd_info_entry *version_entry; + struct snd_info_entry *variant_entry; struct wcd938x_priv *priv; struct snd_soc_card *card; @@ -2536,6 +2572,26 @@ int wcd938x_info_create_codec_entry(struct snd_info_entry *codec_root, } priv->version_entry = version_entry; + variant_entry = snd_info_create_card_entry(card->snd_card, + "variant", + priv->entry); + if (!variant_entry) { + dev_dbg(component->dev, "%s: failed to create wcd938x variant entry\n", + __func__); + return -ENOMEM; + } + + variant_entry->private_data = priv; + variant_entry->size = WCD938X_VARIANT_ENTRY_SIZE; + variant_entry->content = SNDRV_INFO_CONTENT_DATA; + variant_entry->c.ops = &wcd938x_variant_ops; + + if (snd_info_register(variant_entry) < 0) { + snd_info_free_entry(variant_entry); + return -ENOMEM; + } + priv->variant_entry = variant_entry; + return 0; } EXPORT_SYMBOL(wcd938x_info_create_codec_entry); -- GitLab From 9fb7c8c43eefc5f44725049995a38337da10b8f6 Mon Sep 17 00:00:00 2001 From: Dieter Luecking Date: Wed, 6 Mar 2019 13:31:09 +0100 Subject: [PATCH 1067/1645] dsp: Revert featurization of 32 channel support in DSP Remove the dependency on dedicated config flag for the use of new API versions in ASM and ADM open commands. Dependency is now on ADSP service version only. Change-Id: I2e7bcec675bafb9ad9e2a10df4ccc1e52bb72c92 Signed-off-by: Dieter Luecking --- asoc/msm-pcm-q6-v2.c | 12 ++++-------- dsp/q6adm.c | 3 +-- include/dsp/q6core.h | 14 +------------- 3 files changed, 6 insertions(+), 23 deletions(-) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index af158432630f..b20ec9a23677 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -390,8 +390,7 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) } else { if ((q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= - ADSP_ASM_API_VERSION_V2) && - q6core_use_Q6_32ch_support()) + ADSP_ASM_API_VERSION_V2)) ret = q6asm_open_write_v5(prtd->audio_client, fmt_type, bits_per_sample); else @@ -439,8 +438,7 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) if ((q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= - ADSP_ASM_API_VERSION_V2) && - q6core_use_Q6_32ch_support()) { + ADSP_ASM_API_VERSION_V2)) { ret = q6asm_media_format_block_multi_ch_pcm_v5( prtd->audio_client, runtime->rate, @@ -523,8 +521,7 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) if ((q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= - ADSP_ASM_API_VERSION_V2) && - q6core_use_Q6_32ch_support()) + ADSP_ASM_API_VERSION_V2)) ret = q6asm_open_read_v5(prtd->audio_client, FORMAT_LINEAR_PCM, bits_per_sample, false, ENC_CFG_ID_NONE); @@ -601,8 +598,7 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) if ((q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= - ADSP_ASM_API_VERSION_V2) && - q6core_use_Q6_32ch_support()) + ADSP_ASM_API_VERSION_V2)) ret = q6asm_enc_cfg_blk_pcm_format_support_v5( prtd->audio_client, prtd->samp_rate, diff --git a/dsp/q6adm.c b/dsp/q6adm.c index a265b7be2494..06cb558a85f3 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -3062,8 +3062,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, if ((q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ADM_V) >= - ADSP_ADM_API_VERSION_V3) && - q6core_use_Q6_32ch_support()) { + ADSP_ADM_API_VERSION_V3)) { memset(&open_v8, 0, sizeof(open_v8)); memset(&ep1_payload, 0, sizeof(ep1_payload)); memset(&ep2_payload, 0, sizeof(ep2_payload)); diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index 61bede7f99d1..61fe6ba95fa9 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #ifndef __Q6CORE_H__ @@ -306,16 +306,4 @@ int q6core_destroy_lpass_npa_client(uint32_t client_handle); int q6core_request_island_transition(uint32_t client_handle, uint32_t island_allow_mode); -#if IS_ENABLED(CONFIG_USE_Q6_32CH_SUPPORT) -static inline bool q6core_use_Q6_32ch_support(void) -{ - return true; -} -#else -static inline bool q6core_use_Q6_32ch_support(void) -{ - return false; -} -#endif - #endif /* __Q6CORE_H__ */ -- GitLab From 7911af7024cd89ac39018cb0f75760a680858f1b Mon Sep 17 00:00:00 2001 From: Dieter Luecking Date: Wed, 6 Mar 2019 13:33:22 +0100 Subject: [PATCH 1068/1645] config: Revert featurization of 32 channel support in DSP Remove the dependency on dedicated config flag for the use of new API versions in ASM and ADM open commands. Dependency is now on ADSP service version only. Change-Id: I884e04fb6a3c8808e7874aa04967db0c3ca083c1 Signed-off-by: Dieter Luecking --- config/qcs405auto.conf | 1 - config/qcs405autoconf.h | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/config/qcs405auto.conf b/config/qcs405auto.conf index afa8140b6e04..61620ebb6d39 100644 --- a/config/qcs405auto.conf +++ b/config/qcs405auto.conf @@ -36,4 +36,3 @@ CONFIG_SND_SOC_MSM_STUB=m CONFIG_MSM_AVTIMER=m CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m CONFIG_SND_SOC_EP92=m -CONFIG_USE_Q6_32CH_SUPPORT=m diff --git a/config/qcs405autoconf.h b/config/qcs405autoconf.h index 0a2e2865aa48..04f1e10fd414 100644 --- a/config/qcs405autoconf.h +++ b/config/qcs405autoconf.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #define CONFIG_PINCTRL_LPI 1 @@ -40,4 +40,3 @@ #define CONFIG_MSM_AVTIMER 1 #define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 #define CONFIG_SND_SOC_EP92 1 -#define CONFIG_USE_Q6_32CH_SUPPORT 1 -- GitLab From dc9e8c20063e0d247810b90f06cfe6424b562cc5 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Mon, 13 May 2019 14:46:15 +0800 Subject: [PATCH 1069/1645] ASoC: enable dynamic FFECNS effect control Add interface for userspace to control FFECNS effect. Change-Id: I78010899e6c193726a79d74e86f13a1546106eff Signed-off-by: Xiaojun Sang --- asoc/msm-qti-pp-config.c | 48 +++++++++++++++++++++++++++++++++ dsp/q6adm.c | 54 ++++++++++++++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 8 ++++++ include/dsp/q6adm-v2.h | 2 ++ 4 files changed, 112 insertions(+) diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index 48a784ed8b5c..d2da56e94423 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -73,6 +73,7 @@ static const DECLARE_TLV_DB_LINEAR(sec_auxpcm_lb_vol_gain, 0, INT_RX_VOL_MAX_STEPS); static int msm_multichannel_ec_primary_mic_ch; +static int msm_ffecns_effect; static void msm_qti_pp_send_eq_values_(int eq_idx) { @@ -1364,6 +1365,50 @@ static const struct snd_kcontrol_new msm_multichannel_ec_controls[] = { msm_multichannel_ec_primary_mic_ch_put), }; +static char const *ffecns_effect_text[] = {"NO_EFFECT", "EC_ONLY", "NS_ONLY", "ECNS"}; + +static int msm_ffecns_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = -EINVAL; + + if (ucontrol->value.integer.value[0] < 0 || + ucontrol->value.integer.value[0] >= ARRAY_SIZE(ffecns_effect_text)) { + pr_err("%s: invalid ffecns effect value %ld\n", + __func__, ucontrol->value.integer.value[0]); + return -EINVAL; + } + + msm_ffecns_effect = ucontrol->value.integer.value[0]; + + pr_debug("%s: set %s for ffecns\n", __func__, + ffecns_effect_text[msm_ffecns_effect]); + + ret = adm_set_ffecns_effect(msm_ffecns_effect); + if (ret) + pr_err("%s: failed to set %s for ffecns\n", + __func__, ffecns_effect_text[msm_ffecns_effect]); + + return ret; +} + +static int msm_ffecns_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_ffecns_effect; + pr_debug("%s: ffecns effect = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static SOC_ENUM_SINGLE_EXT_DECL(ffecns_effect_enum, ffecns_effect_text); + +static const struct snd_kcontrol_new ec_ffecns_controls[] = { + SOC_ENUM_EXT("FFECNS Effect", ffecns_effect_enum, + msm_ffecns_get, msm_ffecns_put), +}; + static const struct snd_kcontrol_new int_fm_vol_mixer_controls[] = { SOC_SINGLE_EXT_TLV("Internal FM RX Volume", SND_SOC_NOPM, 0, INT_RX_VOL_GAIN, 0, msm_qti_pp_get_fm_vol_mixer, @@ -1668,5 +1713,8 @@ void msm_qti_pp_add_controls(struct snd_soc_component *component) snd_soc_add_component_controls(component, dsp_bit_width_controls, ARRAY_SIZE(dsp_bit_width_controls)); + + snd_soc_add_component_controls(component, ec_ffecns_controls, + ARRAY_SIZE(ec_ffecns_controls)); } #endif /* CONFIG_QTI_PP */ diff --git a/dsp/q6adm.c b/dsp/q6adm.c index a265b7be2494..29bf67fdc0d2 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -101,6 +101,7 @@ struct adm_ctl { int num_ec_ref_rx_chans_downmixed; uint16_t ec_ref_chmixer_weights[PCM_FORMAT_MAX_NUM_CHANNEL_V8] [PCM_FORMAT_MAX_NUM_CHANNEL_V8]; + int ffecns_port_id; int native_mode; }; @@ -2985,6 +2986,12 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, rate = 16000; } + if (topology == FFECNS_TOPOLOGY) { + this_adm.ffecns_port_id = port_id; + pr_debug("%s: ffecns port id =%x\n", __func__, + this_adm.ffecns_port_id); + } + if (topology == VPM_TX_VOICE_SMECNS_V2_COPP_TOPOLOGY) channel_mode = 1; @@ -3842,6 +3849,10 @@ int adm_close(int port_id, int perf_mode, int copp_idx) pr_debug("%s: remove adm device from rtac\n", __func__); rtac_remove_adm_device(port_id, copp_id); } + + if (port_id == this_adm.ffecns_port_id) + this_adm.ffecns_port_id = -1; + return 0; } EXPORT_SYMBOL(adm_close); @@ -4442,6 +4453,48 @@ int adm_send_set_multichannel_ec_primary_mic_ch(int port_id, int copp_idx, } EXPORT_SYMBOL(adm_send_set_multichannel_ec_primary_mic_ch); +/** + * adm_set_ffecns_effect - + * command to set effect for ffecns module + * + * @effect: effect payload + * + * Returns 0 on success or error on failure + */ +int adm_set_ffecns_effect(int effect) +{ + struct ffecns_effect ffecns_params; + struct param_hdr_v3 param_hdr; + int rc = 0; + int copp_idx = 0; + + copp_idx = adm_get_default_copp_idx(this_adm.ffecns_port_id); + if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { + pr_err("%s, no active copp to query rms copp_idx:%d\n", + __func__, copp_idx); + return -EINVAL; + } + + memset(&ffecns_params, 0, sizeof(ffecns_params)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = FFECNS_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = FLUENCE_CMN_GLOBAL_EFFECT_PARAM_ID; + param_hdr.param_size = sizeof(ffecns_params); + + ffecns_params.payload = effect; + + rc = adm_pack_and_set_one_pp_param(this_adm.ffecns_port_id, copp_idx, + param_hdr, (uint8_t *) &ffecns_params); + if (rc) + pr_err("%s: Failed to set ffecns effect, err %d\n", + __func__, rc); + + return rc; +} +EXPORT_SYMBOL(adm_set_ffecns_effect); + /** * adm_param_enable - * command to send params to ADM for given module @@ -5296,6 +5349,7 @@ int __init adm_init(void) int i = 0, j; this_adm.ec_ref_rx = -1; + this_adm.ffecns_port_id = -1; init_waitqueue_head(&this_adm.matrix_map_wait); init_waitqueue_head(&this_adm.adm_wait); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index a90cb05bcd6f..68c491ff2666 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -12524,6 +12524,14 @@ struct admx_sec_primary_mic_ch { uint16_t reserved1; } __packed; +#define FFECNS_MODULE_ID 0x00010952 +#define FLUENCE_CMN_GLOBAL_EFFECT_PARAM_ID 0x00010EAF +#define FFECNS_TOPOLOGY 0X10028003 + +struct ffecns_effect { + uint32_t payload; +}; + /** ID of the Voice Activity Detection (VAD) module, which is used to * configure AFE VAD. */ diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index a48082b75cce..894bca40c816 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -178,6 +178,8 @@ int adm_set_mic_gain(int port_id, int copp_idx, int volume); int adm_send_set_multichannel_ec_primary_mic_ch(int port_id, int copp_idx, int primary_mic_ch); +int adm_set_ffecns_effect(int effect); + int adm_param_enable(int port_id, int copp_idx, int module_id, int enable); int adm_param_enable_v2(int port_id, int copp_idx, -- GitLab From 5478daae2935ce31625437fd5a40756a5a8cc67f Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 30 Nov 2018 19:19:18 +0530 Subject: [PATCH 1070/1645] dsp: sleep before sending q6core ready query After PDR, audio avs services still are initializing state. Avoid sending q6core command after PD up event immediately, wait for sometime before sending the q6core ready command. Change-Id: Ibee38db9ee1a30b7852da3d08cac7b0d06371733 Signed-off-by: Laxminath Kasam --- dsp/q6core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dsp/q6core.c b/dsp/q6core.c index 43f6e25d4c0c..68fe9e5fb749 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -1795,6 +1795,8 @@ static int q6core_is_avs_up(int32_t *avs_state) timeout = jiffies + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + /* sleep for 100ms before querying AVS up */ + msleep(100); do { adsp_ready = q6core_is_adsp_ready(); pr_debug("%s: ADSP Audio is %s\n", __func__, -- GitLab From 1d965295d4058d8c71fcd60c59cd8f6eb0c60a22 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 8 Jul 2019 18:47:08 +0530 Subject: [PATCH 1071/1645] asoc: wcd938x: Reset mbhc detection type after ssr During headset playback if we trigger SSR, headset removal is not detected. This is because after recovery mbhc driver expects a new detection event as the driver is reinitialized. Reset detection type to insertion to retrigger a hw interrupt for mbhc driver. Change-Id: Ibf6663f46e7485f5ff5c5968a71c88e59a4728e7 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd938x/wcd938x-mbhc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/asoc/codecs/wcd938x/wcd938x-mbhc.c b/asoc/codecs/wcd938x/wcd938x-mbhc.c index 08a2b228df3a..47ebb072fd18 100644 --- a/asoc/codecs/wcd938x/wcd938x-mbhc.c +++ b/asoc/codecs/wcd938x/wcd938x-mbhc.c @@ -1009,6 +1009,9 @@ int wcd938x_mbhc_post_ssr_init(struct wcd938x_mbhc *mbhc, return -EINVAL; } + /* Reset detection type to insertion after SSR recovery */ + snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_MECH, + 0x20, 0x20); ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb, &intr_ids, wcd_mbhc_registers, WCD938X_ZDET_SUPPORTED); if (ret) { -- GitLab From b06327374c0611c88227ffdf0caef1fa7d9bf1b4 Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Mon, 24 Jun 2019 15:29:32 +0530 Subject: [PATCH 1072/1645] asoc: qcs405: Add new dailink for compress capture Add new dailink for compress capture to support additional record usecase. Change-Id: I7244d2e749c398140205d82d88958ce97d4c8764 Signed-off-by: Chaithanya Krishna Bacharaju --- asoc/qcs405.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 15fff2aa53f8..bc513637d37b 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -6881,6 +6881,21 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA29, }, + { + .name = MSM_DAILINK_NAME(Compr Capture6), + .stream_name = "Compr Capture6", + .cpu_dai_name = "MultiMedia30", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA30, + }, }; static struct snd_soc_dai_link msm_common_be_dai_links[] = { -- GitLab From 757f0d29a21f71d1e18040ff45fa40f6382e46bf Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Fri, 21 Jun 2019 13:10:22 +0530 Subject: [PATCH 1073/1645] dsp: Reset ec ref port id after use Reset ec ref port id to invalid port after use to ensure it is not picked for other adm sessions. Change-Id: I802326122ad6dc63c7f2df16169da3f50559202f Signed-off-by: Chaithanya Krishna Bacharaju --- dsp/q6adm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index a265b7be2494..1723bb20b58c 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -3099,6 +3099,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, if (this_adm.num_ec_ref_rx_chans != 0) { open_v8.endpoint_id_2 = this_adm.ec_ref_rx; + this_adm.ec_ref_rx = AFE_PORT_INVALID; } else { pr_err("%s: EC channels not set %d\n", __func__, -- GitLab From cf5a58f1172b558cdf76b203b9950ca84097b407 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 10 Jul 2019 12:58:39 +0530 Subject: [PATCH 1074/1645] ASoC: wcd937x: Disable hph OCP on talos OCP is resulting in mute issues during audio playback. Talos has surge protection enabled in hw. Thus OCP can be disabled for talos. Change-Id: I5a7fe54ae9e77af65dd9e017b4001f2fac3cfdd4 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index e89d9a9179ad..08eb36996c0c 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -127,10 +127,6 @@ static int wcd937x_init_reg(struct snd_soc_component *component) usleep_range(10000, 10010); snd_soc_component_update_bits(component, WCD937X_ANA_BIAS, 0x40, 0x00); - snd_soc_component_update_bits(component, WCD937X_HPH_OCP_CTL, - 0xFF, 0x3A); - snd_soc_component_update_bits(component, WCD937X_RX_OCP_CTL, - 0x0F, 0x02); snd_soc_component_update_bits(component, WCD937X_HPH_SURGE_HPHLR_SURGE_EN, 0xFF, 0xD9); @@ -683,8 +679,6 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02); - snd_soc_component_update_bits(component, - WCD937X_HPH_R_TEST, 0x01, 0x01); if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) snd_soc_component_update_bits(component, WCD937X_ANA_RX_SUPPLIES, @@ -695,8 +689,6 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, (WCD_RX2 << 0x10)); break; case SND_SOC_DAPM_PRE_PMD: - snd_soc_component_update_bits(component, - WCD937X_HPH_R_TEST, 0x01, 0x00); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -782,8 +774,6 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_HPH_TIMER1, 0x02, 0x02); - snd_soc_component_update_bits(component, - WCD937X_HPH_L_TEST, 0x01, 0x01); if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI) snd_soc_component_update_bits(component, WCD937X_ANA_RX_SUPPLIES, @@ -794,8 +784,6 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, (WCD_RX1 << 0x10)); break; case SND_SOC_DAPM_PRE_PMD: - snd_soc_component_update_bits(component, - WCD937X_HPH_L_TEST, 0x01, 0x00); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, -- GitLab From aecce31ce85182a9114e2eaea6b2ffde031138bc Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 10 Jul 2019 15:36:09 +0530 Subject: [PATCH 1075/1645] ASoC: wcd938x: Disable hph OCP on traverso OCP is resulting in mute issues during audio playback. Traverso has surge protection enabled in hw. Thus OCP can be disabled for traverso. Change-Id: I5af745e9c1fb41640317a406adff59bcde81c37e Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd938x/wcd938x.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 8113ab4204f2..d8022cb0691c 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -146,14 +146,6 @@ static int wcd938x_init_reg(struct snd_soc_component *component) /* 10 msec delay as per HW requirement */ usleep_range(10000, 10010); snd_soc_component_update_bits(component, WCD938X_ANA_BIAS, 0x40, 0x00); - snd_soc_component_update_bits(component, WCD938X_HPH_OCP_CTL, - 0xFF, 0x3A); - snd_soc_component_update_bits(component, WCD938X_RX_OCP_CTL, - 0x0F, 0x02); - snd_soc_component_update_bits(component, WCD938X_HPH_R_TEST, - 0x01, 0x01); - snd_soc_component_update_bits(component, WCD938X_HPH_L_TEST, - 0x01, 0x01); snd_soc_component_update_bits(component, WCD938X_HPH_NEW_INT_RDAC_GAIN_CTL, 0xF0, 0x00); -- GitLab From b2bfcfc756fc9afd4ea036a042c8b9cf2e73c44c Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 10 Jul 2019 21:59:02 +0530 Subject: [PATCH 1076/1645] ASoC: Kona: Add support for moisture detection Add support for moisture detection with duty cycle on WCD938x codec. Change-Id: I1e5ceb39f031ea7f7efdd38706845b71b093a479 Signed-off-by: Sudheer Papothi --- asoc/kona.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/asoc/kona.c b/asoc/kona.c index ee239e460e29..a8a64b216cc2 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -699,10 +699,11 @@ static struct wcd_mbhc_config wcd_mbhc_cfg = { .key_code[6] = 0, .key_code[7] = 0, .linein_th = 5000, - .moisture_en = true, + .moisture_en = false, .mbhc_micbias = MIC_BIAS_2, .anc_micbias = MIC_BIAS_2, .enable_anc_mic_detect = false, + .moisture_duty_cycle_en = true, }; static inline int param_is_mask(int p) -- GitLab From dc3f7e4680e1158cebf4a6314b4f030c6be82a12 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 11 Jul 2019 20:42:11 +0530 Subject: [PATCH 1077/1645] dsp: voice: Add support for CVD version 2.4 CVD version update is needed to support a new modem feature. Add support for CVD version 2.4 in internal version mapping table. Change-Id: I26627e3c88b424acca8f85696dd58d7ce2e944d9 Signed-off-by: Aditya Bavanari --- dsp/q6voice.c | 1 + include/dsp/q6voice.h | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 131da554b978..6de668684319 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -51,6 +51,7 @@ struct cvd_version_table cvd_version_table_mapping[CVD_INT_VERSION_MAX] = { {CVD_VERSION_2_1, CVD_INT_VERSION_2_1}, {CVD_VERSION_2_2, CVD_INT_VERSION_2_2}, {CVD_VERSION_2_3, CVD_INT_VERSION_2_3}, + {CVD_VERSION_2_4, CVD_INT_VERSION_2_4}, }; static struct common_data common; diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index 06f4dfe8901d..2edfbe215fd7 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -37,13 +37,15 @@ #define CVD_VERSION_2_1 "2.1" #define CVD_VERSION_2_2 "2.2" #define CVD_VERSION_2_3 "2.3" +#define CVD_VERSION_2_4 "2.4" #define CVD_INT_VERSION_DEFAULT 0 #define CVD_INT_VERSION_0_0 1 #define CVD_INT_VERSION_2_1 2 #define CVD_INT_VERSION_2_2 3 #define CVD_INT_VERSION_2_3 4 -#define CVD_INT_VERSION_LAST CVD_INT_VERSION_2_3 +#define CVD_INT_VERSION_2_4 5 +#define CVD_INT_VERSION_LAST CVD_INT_VERSION_2_4 #define CVD_INT_VERSION_MAX (CVD_INT_VERSION_LAST + 1) struct cvd_version_table { -- GitLab From eafed6ac4b22154e46f6fde9945f1ccbc5d4a8ec Mon Sep 17 00:00:00 2001 From: Arun Mirpuri Date: Thu, 11 Jul 2019 16:33:19 -0700 Subject: [PATCH 1078/1645] asoc: Add support for soft volume for mmap playback Send command for soft volume config during pcm prepare of mmap no irq stream Change-Id: Iacd4c95633d53ccfe78e8abb11baeedd8b854f26 Signed-off-by: Arun Mirpuri --- asoc/msm-pcm-q6-noirq.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index 5b978311b0ff..6d1d30ddb8a2 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -600,13 +600,26 @@ static int msm_pcm_mmap(struct snd_pcm_substream *substream, static int msm_pcm_prepare(struct snd_pcm_substream *substream) { + int rc = 0; struct snd_pcm_runtime *runtime = substream->runtime; struct msm_audio *prtd = runtime->private_data; + struct asm_softvolume_params softvol = { + .period = SOFT_VOLUME_PERIOD, + .step = SOFT_VOLUME_STEP, + .rampingcurve = SOFT_VOLUME_CURVE_LINEAR, + }; if (!prtd || !prtd->mmap_flag) return -EIO; - return 0; + if (prtd->audio_client) { + rc = q6asm_set_softvolume_v2(prtd->audio_client, + &softvol, SOFT_VOLUME_INSTANCE_1); + if (rc < 0) + pr_err("%s: Send SoftVolume command failed rc=%d\n", + __func__, rc); + } + return rc; } static int msm_pcm_close(struct snd_pcm_substream *substream) -- GitLab From d5338db59ada894f74fa39c370a5c7379478ce65 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 13 Jul 2019 13:01:06 +0530 Subject: [PATCH 1079/1645] ASoC: wcd938x: Enable LDOH in headphone path Add support to enable LDOH in headphone path when equalizer hardware installed on the device. Change-Id: Ia575544650e5d03404fc77e3c2a9db729a2997a5 Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd938x/internal.h | 2 +- asoc/codecs/wcd938x/wcd938x.c | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index a54394446bd3..abea69e81aa0 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -67,7 +67,7 @@ struct wcd938x_priv { u32 tx_mode[TX_ADC_MAX]; bool comp1_enable; bool comp2_enable; - + bool ldoh; struct irq_domain *virq; struct wcd_irq_info irq_info; u32 rx_clk_cnt; diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 8113ab4204f2..e1c466a4f19d 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -628,6 +628,10 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + if (wcd938x->ldoh) + snd_soc_component_update_bits(component, + WCD938X_LDOH_MODE, + 0x80, 0x80); if (wcd938x->update_wcd_event) wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -731,6 +735,10 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_HPHR, hph_mode); + if (wcd938x->ldoh) + snd_soc_component_update_bits(component, + WCD938X_LDOH_MODE, + 0x80, 0x00); break; }; return ret; @@ -750,6 +758,10 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + if (wcd938x->ldoh) + snd_soc_component_update_bits(component, + WCD938X_LDOH_MODE, + 0x80, 0x80); if (wcd938x->update_wcd_event) wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -853,6 +865,10 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_HPHL, hph_mode); + if (wcd938x->ldoh) + snd_soc_component_update_bits(component, + WCD938X_LDOH_MODE, + 0x80, 0x00); break; }; return ret; @@ -1944,6 +1960,30 @@ static int wcd938x_set_compander(struct snd_kcontrol *kcontrol, return 0; } +static int wcd938x_ldoh_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wcd938x->ldoh; + + return 0; +} + +static int wcd938x_ldoh_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + wcd938x->ldoh = ucontrol->value.integer.value[0]; + + return 0; +} + static const char * const tx_mode_mux_text_wcd9380[] = { "ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP", }; @@ -2001,6 +2041,9 @@ static const struct snd_kcontrol_new wcd938x_snd_controls[] = { SOC_SINGLE_EXT("HPHR_COMP Switch", SND_SOC_NOPM, 1, 1, 0, wcd938x_get_compander, wcd938x_set_compander), + SOC_SINGLE_EXT("LDOH Enable", SND_SOC_NOPM, 0, 1, 0, + wcd938x_ldoh_get, wcd938x_ldoh_put), + SOC_SINGLE_TLV("HPHL Volume", WCD938X_HPH_L_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("HPHR Volume", WCD938X_HPH_R_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("ADC1 Volume", WCD938X_ANA_TX_CH1, 0, 20, 0, -- GitLab From 61b2de686e9fe57570863b4619f23bd965cd7b71 Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Thu, 20 Jun 2019 11:40:17 +0530 Subject: [PATCH 1080/1645] asoc: routing: Add support to use compress path for ec ref loopback Add support to use compress path for mic and ec reference data capture in single stream. Extend PSPD controls for compress frontend ids. Update compress driver to use latest ADSP APIs if available. Change-Id: Icbf9def07cb0a01542fb3b5cd77e74ab53aec683 Signed-off-by: Chaithanya Krishna Bacharaju --- asoc/msm-compress-q6-v2.c | 25 +- asoc/msm-pcm-routing-v2.c | 913 +++++++++++++++++++++++++++++++++++--- 2 files changed, 864 insertions(+), 74 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index a3618caa5e73..0a4bc060e520 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -1534,9 +1534,16 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream) prtd->codec, bits_per_sample, true, enc_cfg_id); } else { - ret = q6asm_open_read_v4(prtd->audio_client, - prtd->codec, - bits_per_sample, false, enc_cfg_id); + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= + ADSP_ASM_API_VERSION_V2) + ret = q6asm_open_read_v5(prtd->audio_client, + prtd->codec, bits_per_sample, + false, enc_cfg_id); + else + ret = q6asm_open_read_v4(prtd->audio_client, + prtd->codec, bits_per_sample, + false, enc_cfg_id); } if (ret < 0) { pr_err("%s: q6asm_open_read failed:%d\n", @@ -1607,7 +1614,17 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream) prtd->num_channels, prtd->codec, (void *)&prtd->codec_param.codec.options.generic); } else if (prtd->compr_passthr == LEGACY_PCM) { - ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client, + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= + ADSP_ASM_API_VERSION_V2) + ret = q6asm_enc_cfg_blk_pcm_format_support_v5( + prtd->audio_client, + prtd->sample_rate, prtd->num_channels, + bits_per_sample, sample_word_size, + ASM_LITTLE_ENDIAN, DEFAULT_QF); + else + ret = q6asm_enc_cfg_blk_pcm_format_support_v4( + prtd->audio_client, prtd->sample_rate, prtd->num_channels, bits_per_sample, sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 4ec63e38adb6..f1afd538965d 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -3440,6 +3440,14 @@ static SOC_ENUM_SINGLE_DECL(mm3_channel_mux, SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA3, ch_mixer); static SOC_ENUM_SINGLE_DECL(mm4_channel_mux, SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA4, ch_mixer); +static SOC_ENUM_SINGLE_DECL(mm18_channel_mux, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA18, ch_mixer); +static SOC_ENUM_SINGLE_DECL(mm19_channel_mux, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA19, ch_mixer); +static SOC_ENUM_SINGLE_DECL(mm28_channel_mux, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA28, ch_mixer); +static SOC_ENUM_SINGLE_DECL(mm29_channel_mux, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA29, ch_mixer); static SOC_ENUM_DOUBLE_DECL(mm1_ch1_enum, SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA1, 0, be_name); @@ -3457,6 +3465,22 @@ static SOC_ENUM_DOUBLE_DECL(mm1_ch7_enum, SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA1, 6, be_name); static SOC_ENUM_DOUBLE_DECL(mm1_ch8_enum, SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA1, 7, be_name); +static SOC_ENUM_DOUBLE_DECL(mm18_ch1_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA18, 0, be_name); +static SOC_ENUM_DOUBLE_DECL(mm18_ch2_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, be_name); +static SOC_ENUM_DOUBLE_DECL(mm19_ch1_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA19, 0, be_name); +static SOC_ENUM_DOUBLE_DECL(mm19_ch2_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, be_name); +static SOC_ENUM_DOUBLE_DECL(mm28_ch1_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA28, 0, be_name); +static SOC_ENUM_DOUBLE_DECL(mm28_ch2_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, be_name); +static SOC_ENUM_DOUBLE_DECL(mm29_ch1_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA29, 0, be_name); +static SOC_ENUM_DOUBLE_DECL(mm29_ch2_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, be_name); static int msm_pcm_get_ctl_enum_info(struct snd_ctl_elem_info *uinfo, unsigned int channels, @@ -3758,6 +3782,22 @@ static const struct snd_kcontrol_new channel_mixer_controls[] = { MSM_FRONTEND_DAI_MULTIMEDIA6, 8, 0, msm_pcm_get_channel_rule_index, msm_pcm_put_channel_rule_index), + SOC_SINGLE_EXT("MultiMedia18 Channel Rule", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA18, 8, 0, + msm_pcm_get_channel_rule_index, + msm_pcm_put_channel_rule_index), + SOC_SINGLE_EXT("MultiMedia19 Channel Rule", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA19, 8, 0, + msm_pcm_get_channel_rule_index, + msm_pcm_put_channel_rule_index), + SOC_SINGLE_EXT("MultiMedia28 Channel Rule", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA28, 8, 0, + msm_pcm_get_channel_rule_index, + msm_pcm_put_channel_rule_index), + SOC_SINGLE_EXT("MultiMedia29 Channel Rule", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA29, 8, 0, + msm_pcm_get_channel_rule_index, + msm_pcm_put_channel_rule_index), SOC_SINGLE_EXT("MultiMedia1 Channels", SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA1, 14, 0, @@ -3783,6 +3823,22 @@ static const struct snd_kcontrol_new channel_mixer_controls[] = { MSM_FRONTEND_DAI_MULTIMEDIA6, 8, 0, msm_pcm_get_out_chs, msm_pcm_put_out_chs), + SOC_SINGLE_EXT("MultiMedia18 Channels", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA18, 14, 0, + msm_pcm_get_out_chs, + msm_pcm_put_out_chs), + SOC_SINGLE_EXT("MultiMedia19 Channels", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA19, 14, 0, + msm_pcm_get_out_chs, + msm_pcm_put_out_chs), + SOC_SINGLE_EXT("MultiMedia28 Channels", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA28, 14, 0, + msm_pcm_get_out_chs, + msm_pcm_put_out_chs), + SOC_SINGLE_EXT("MultiMedia29 Channels", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA29, 14, 0, + msm_pcm_get_out_chs, + msm_pcm_put_out_chs), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, @@ -3822,6 +3878,42 @@ static const struct snd_kcontrol_new channel_mixer_controls[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia18 Channel Mixer", + .info = msm_pcm_channel_mixer_info, + .get = msm_pcm_channel_mixer_get, + .put = msm_pcm_channel_mixer_put, + .private_value = (unsigned long)&(mm18_channel_mux) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Channel Mixer", + .info = msm_pcm_channel_mixer_info, + .get = msm_pcm_channel_mixer_get, + .put = msm_pcm_channel_mixer_put, + .private_value = (unsigned long)&(mm19_channel_mux) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Channel Mixer", + .info = msm_pcm_channel_mixer_info, + .get = msm_pcm_channel_mixer_get, + .put = msm_pcm_channel_mixer_put, + .private_value = (unsigned long)&(mm28_channel_mux) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Channel Mixer", + .info = msm_pcm_channel_mixer_info, + .get = msm_pcm_channel_mixer_get, + .put = msm_pcm_channel_mixer_put, + .private_value = (unsigned long)&(mm29_channel_mux) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .name = "MultiMedia1 Output Channel1", .info = msm_pcm_channel_weight_info, .get = msm_pcm_channel_weight_get, @@ -4012,134 +4104,806 @@ static const struct snd_kcontrol_new channel_mixer_controls[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .name = "MultiMedia1 Channel1", - .info = msm_pcm_channel_input_be_info, - .get = msm_pcm_channel_input_be_get, - .put = msm_pcm_channel_input_be_put, - .private_value = (unsigned long)&(mm1_ch1_enum) + .name = "MultiMedia18 Output Channel1", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA18, .rshift = 0,} }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .name = "MultiMedia1 Channel2", - .info = msm_pcm_channel_input_be_info, - .get = msm_pcm_channel_input_be_get, - .put = msm_pcm_channel_input_be_put, - .private_value = (unsigned long)&(mm1_ch2_enum) + .name = "MultiMedia18 Output Channel2", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA18, .rshift = 1, } }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .name = "MultiMedia1 Channel3", - .info = msm_pcm_channel_input_be_info, - .get = msm_pcm_channel_input_be_get, - .put = msm_pcm_channel_input_be_put, - .private_value = (unsigned long)&(mm1_ch3_enum) + .name = "MultiMedia18 Output Channel3", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA18, .rshift = 2,} }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .name = "MultiMedia1 Channel4", - .info = msm_pcm_channel_input_be_info, - .get = msm_pcm_channel_input_be_get, - .put = msm_pcm_channel_input_be_put, - .private_value = (unsigned long)&(mm1_ch4_enum) + .name = "MultiMedia18 Output Channel4", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA18, .rshift = 3,} }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .name = "MultiMedia1 Channel5", - .info = msm_pcm_channel_input_be_info, - .get = msm_pcm_channel_input_be_get, - .put = msm_pcm_channel_input_be_put, - .private_value = (unsigned long)&(mm1_ch5_enum) + .name = "MultiMedia18 Output Channel5", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA18, .rshift = 4,} }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .name = "MultiMedia1 Channel6", - .info = msm_pcm_channel_input_be_info, - .get = msm_pcm_channel_input_be_get, - .put = msm_pcm_channel_input_be_put, - .private_value = (unsigned long)&(mm1_ch6_enum) + .name = "MultiMedia18 Output Channel6", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA18, .rshift = 5,} }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .name = "MultiMedia1 Channel7", - .info = msm_pcm_channel_input_be_info, - .get = msm_pcm_channel_input_be_get, - .put = msm_pcm_channel_input_be_put, - .private_value = (unsigned long)&(mm1_ch7_enum) + .name = "MultiMedia18 Output Channel7", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA18, .rshift = 6,} }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .name = "MultiMedia1 Channel8", - .info = msm_pcm_channel_input_be_info, - .get = msm_pcm_channel_input_be_get, - .put = msm_pcm_channel_input_be_put, - .private_value = (unsigned long)&(mm1_ch8_enum) + .name = "MultiMedia18 Output Channel8", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA18, .rshift = 7,} }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .name = "MultiMedia1 Output Channel Map", - .info = msm_pcm_channel_output_map_info, - .get = msm_pcm_channel_output_map_get, - .put = msm_pcm_channel_output_map_put, + .name = "MultiMedia18 Output Channel9", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, .private_value = (unsigned long)&(struct soc_multi_mixer_control) - { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1,} + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA18, .rshift = 8,} }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .name = "MultiMedia2 Output Channel Map", - .info = msm_pcm_channel_output_map_info, - .get = msm_pcm_channel_output_map_get, - .put = msm_pcm_channel_output_map_put, + .name = "MultiMedia18 Output Channel10", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, .private_value = (unsigned long)&(struct soc_multi_mixer_control) - { .shift = MSM_FRONTEND_DAI_MULTIMEDIA2,} + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA18, .rshift = 9,} }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .name = "MultiMedia3 Output Channel Map", - .info = msm_pcm_channel_output_map_info, - .get = msm_pcm_channel_output_map_get, - .put = msm_pcm_channel_output_map_put, + .name = "MultiMedia18 Output Channel11", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, .private_value = (unsigned long)&(struct soc_multi_mixer_control) - { .shift = MSM_FRONTEND_DAI_MULTIMEDIA3,} + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA18, .rshift = 10,} }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .name = "MultiMedia4 Output Channel Map", - .info = msm_pcm_channel_output_map_info, - .get = msm_pcm_channel_output_map_get, - .put = msm_pcm_channel_output_map_put, + .name = "MultiMedia18 Output Channel12", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, .private_value = (unsigned long)&(struct soc_multi_mixer_control) - { .shift = MSM_FRONTEND_DAI_MULTIMEDIA4,} + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA18, .rshift = 11,} }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .name = "MultiMedia5 Output Channel Map", - .info = msm_pcm_channel_output_map_info, - .get = msm_pcm_channel_output_map_get, - .put = msm_pcm_channel_output_map_put, + .name = "MultiMedia18 Output Channel13", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, .private_value = (unsigned long)&(struct soc_multi_mixer_control) - { .shift = MSM_FRONTEND_DAI_MULTIMEDIA5,} + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA18, .rshift = 12,} }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .name = "MultiMedia6 Output Channel Map", - .info = msm_pcm_channel_output_map_info, - .get = msm_pcm_channel_output_map_get, - .put = msm_pcm_channel_output_map_put, + .name = "MultiMedia18 Output Channel14", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, .private_value = (unsigned long)&(struct soc_multi_mixer_control) - { .shift = MSM_FRONTEND_DAI_MULTIMEDIA6,} + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA18, .rshift = 13,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Output Channel1", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA19, .rshift = 0,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Output Channel2", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA19, .rshift = 1, } + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Output Channel3", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA19, .rshift = 2,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Output Channel4", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA19, .rshift = 3,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Output Channel5", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA19, .rshift = 4,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Output Channel6", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA19, .rshift = 5,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Output Channel7", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA19, .rshift = 6,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Output Channel8", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA19, .rshift = 7,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Output Channel9", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA19, .rshift = 8,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Output Channel10", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA19, .rshift = 9,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Output Channel11", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA19, .rshift = 10,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Output Channel12", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA19, .rshift = 11,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Output Channel13", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA19, .rshift = 12,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Output Channel14", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA19, .rshift = 13,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Output Channel1", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA28, .rshift = 0,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Output Channel2", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA28, .rshift = 1, } + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Output Channel3", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA28, .rshift = 2,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Output Channel4", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA28, .rshift = 3,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Output Channel5", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA28, .rshift = 4,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Output Channel6", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA28, .rshift = 5,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Output Channel7", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA28, .rshift = 6,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Output Channel8", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA28, .rshift = 7,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Output Channel9", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA28, .rshift = 8,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Output Channel10", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA28, .rshift = 9,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Output Channel11", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA28, .rshift = 10,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Output Channel12", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA28, .rshift = 11,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Output Channel13", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA28, .rshift = 12,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Output Channel14", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA28, .rshift = 13,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Output Channel1", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA29, .rshift = 0,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Output Channel2", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA29, .rshift = 1, } + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Output Channel3", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA29, .rshift = 2,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Output Channel4", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA29, .rshift = 3,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Output Channel5", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA29, .rshift = 4,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Output Channel6", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA29, .rshift = 5,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Output Channel7", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA29, .rshift = 6,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Output Channel8", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA29, .rshift = 7,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Output Channel9", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA29, .rshift = 8,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Output Channel10", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA29, .rshift = 9,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Output Channel11", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA29, .rshift = 10,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Output Channel12", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA29, .rshift = 11,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Output Channel13", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA29, .rshift = 12,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Output Channel14", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA29, .rshift = 13,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel1", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm1_ch1_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel2", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm1_ch2_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel3", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm1_ch3_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel4", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm1_ch4_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel5", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm1_ch5_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel6", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm1_ch6_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel7", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm1_ch7_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Channel8", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm1_ch8_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia18 Channel1", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm18_ch1_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia18 Channel2", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm18_ch2_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Channel1", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm19_ch1_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Channel2", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm19_ch2_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Channel1", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm28_ch1_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Channel2", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm28_ch2_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Channel1", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm29_ch1_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Channel2", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm29_ch2_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia1 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA1,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia2 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA2,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia3 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA3,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia4 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA4,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia5 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA5,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia6 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA6,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia18 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA18,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia19 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA19,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia28 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA28,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia29 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA29,} }, }; @@ -23247,6 +24011,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, {"PRI_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, {"PRI_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, {"PRI_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, {"PRI_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, {"PRI_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, @@ -24492,6 +25257,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia18 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia18 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia18 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, @@ -24500,6 +25267,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia19 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia19 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia19 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, @@ -24508,6 +25277,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia28 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia28 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia28 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, @@ -24516,6 +25287,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, {"MultiMedia29 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia29 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia29 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, -- GitLab From 7aadfb6d31d39cf85659949d6684ee904b048865 Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Mon, 24 Jun 2019 16:05:14 +0530 Subject: [PATCH 1081/1645] asoc: add new compress capture FE dai Add new compress capture FE dai to support additional capture usecase. Extend PSPD controls for new FE id. Change-Id: Iae0473d6b71eed0658bba8f70ffc469b66782053 Signed-off-by: Chaithanya Krishna Bacharaju --- asoc/msm-dai-fe.c | 19 ++ asoc/msm-pcm-routing-v2.c | 408 +++++++++++++++++++++++++++++++++++++- asoc/msm-pcm-routing-v2.h | 5 +- 3 files changed, 429 insertions(+), 3 deletions(-) diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index f53b3a6a5b0f..d3e55811ebca 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -2736,6 +2736,25 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "MultiMedia29", .probe = fe_dai_probe, }, + { + .capture = { + .stream_name = "MultiMedia30 Capture", + .aif_name = "MM_UL30", + .rates = (SNDRV_PCM_RATE_8000_192000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE), + .channels_min = 1, + .channels_max = 32, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia30", + .probe = fe_dai_probe, + }, }; static int msm_fe_dai_dev_probe(struct platform_device *pdev) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index f1afd538965d..1b79917b8d0f 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -769,6 +769,9 @@ static struct msm_pcm_routing_fdai_data {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA29 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, + /* MULTIMEDIA30 */ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* VOIP */ @@ -3448,6 +3451,8 @@ static SOC_ENUM_SINGLE_DECL(mm28_channel_mux, SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA28, ch_mixer); static SOC_ENUM_SINGLE_DECL(mm29_channel_mux, SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA29, ch_mixer); +static SOC_ENUM_SINGLE_DECL(mm30_channel_mux, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA30, ch_mixer); static SOC_ENUM_DOUBLE_DECL(mm1_ch1_enum, SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA1, 0, be_name); @@ -3481,6 +3486,10 @@ static SOC_ENUM_DOUBLE_DECL(mm29_ch1_enum, SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA29, 0, be_name); static SOC_ENUM_DOUBLE_DECL(mm29_ch2_enum, SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, be_name); +static SOC_ENUM_DOUBLE_DECL(mm30_ch1_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA30, 0, be_name); +static SOC_ENUM_DOUBLE_DECL(mm30_ch2_enum, + SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA30, 1, be_name); static int msm_pcm_get_ctl_enum_info(struct snd_ctl_elem_info *uinfo, unsigned int channels, @@ -3798,6 +3807,10 @@ static const struct snd_kcontrol_new channel_mixer_controls[] = { MSM_FRONTEND_DAI_MULTIMEDIA29, 8, 0, msm_pcm_get_channel_rule_index, msm_pcm_put_channel_rule_index), + SOC_SINGLE_EXT("MultiMedia30 Channel Rule", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA30, 8, 0, + msm_pcm_get_channel_rule_index, + msm_pcm_put_channel_rule_index), SOC_SINGLE_EXT("MultiMedia1 Channels", SND_SOC_NOPM, MSM_FRONTEND_DAI_MULTIMEDIA1, 14, 0, @@ -3839,6 +3852,10 @@ static const struct snd_kcontrol_new channel_mixer_controls[] = { MSM_FRONTEND_DAI_MULTIMEDIA29, 14, 0, msm_pcm_get_out_chs, msm_pcm_put_out_chs), + SOC_SINGLE_EXT("MultiMedia30 Channels", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA30, 14, 0, + msm_pcm_get_out_chs, + msm_pcm_put_out_chs), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, @@ -3914,6 +3931,15 @@ static const struct snd_kcontrol_new channel_mixer_controls[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Channel Mixer", + .info = msm_pcm_channel_mixer_info, + .get = msm_pcm_channel_mixer_get, + .put = msm_pcm_channel_mixer_put, + .private_value = (unsigned long)&(mm30_channel_mux) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .name = "MultiMedia1 Output Channel1", .info = msm_pcm_channel_weight_info, .get = msm_pcm_channel_weight_get, @@ -4664,6 +4690,146 @@ static const struct snd_kcontrol_new channel_mixer_controls[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Output Channel1", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA30, .rshift = 0,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Output Channel2", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA30, .rshift = 1, } + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Output Channel3", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA30, .rshift = 2,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Output Channel4", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA30, .rshift = 3,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Output Channel5", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA30, .rshift = 4,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Output Channel6", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA30, .rshift = 5,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Output Channel7", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA30, .rshift = 6,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Output Channel8", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA30, .rshift = 7,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Output Channel9", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA30, .rshift = 8,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Output Channel10", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA30, .rshift = 9,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Output Channel11", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA30, .rshift = 10,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Output Channel12", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA30, .rshift = 11,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Output Channel13", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA30, .rshift = 12,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Output Channel14", + .info = msm_pcm_channel_weight_info, + .get = msm_pcm_channel_weight_get, + .put = msm_pcm_channel_weight_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA30, .rshift = 13,} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .name = "MultiMedia1 Channel1", .info = msm_pcm_channel_input_be_info, .get = msm_pcm_channel_input_be_get, @@ -4808,6 +4974,24 @@ static const struct snd_kcontrol_new channel_mixer_controls[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Channel1", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm30_ch1_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Channel2", + .info = msm_pcm_channel_input_be_info, + .get = msm_pcm_channel_input_be_get, + .put = msm_pcm_channel_input_be_put, + .private_value = (unsigned long)&(mm30_ch2_enum) + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .name = "MultiMedia1 Output Channel Map", .info = msm_pcm_channel_output_map_info, .get = msm_pcm_channel_output_map_get, @@ -4905,6 +5089,16 @@ static const struct snd_kcontrol_new channel_mixer_controls[] = { .private_value = (unsigned long)&(struct soc_multi_mixer_control) { .shift = MSM_FRONTEND_DAI_MULTIMEDIA29,} }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .name = "MultiMedia30 Output Channel Map", + .info = msm_pcm_channel_output_map_info, + .get = msm_pcm_channel_output_map_get, + .put = msm_pcm_channel_output_map_put, + .private_value = (unsigned long)&(struct soc_multi_mixer_control) + { .shift = MSM_FRONTEND_DAI_MULTIMEDIA30,} + }, }; static int msm_ec_ref_ch_get(struct snd_kcontrol *kcontrol, @@ -5591,6 +5785,10 @@ static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = { @@ -5682,6 +5880,10 @@ static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_spdif_rx_mixer_controls[] = { @@ -5773,6 +5975,10 @@ static const struct snd_kcontrol_new pri_spdif_rx_mixer_controls[] = { MSM_BACKEND_DAI_PRI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_spdif_rx_mixer_controls[] = { @@ -5864,6 +6070,10 @@ static const struct snd_kcontrol_new sec_spdif_rx_mixer_controls[] = { MSM_BACKEND_DAI_SEC_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new slimbus_2_rx_mixer_controls[] = { @@ -6026,6 +6236,10 @@ static const struct snd_kcontrol_new slimbus_5_rx_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = { @@ -6117,6 +6331,10 @@ static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = { @@ -6208,6 +6426,10 @@ static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = { @@ -6299,6 +6521,10 @@ static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quinary_mi2s_rx_mixer_controls[] = { @@ -6390,6 +6616,10 @@ static const struct snd_kcontrol_new quinary_mi2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; @@ -6566,6 +6796,10 @@ static const struct snd_kcontrol_new tertiary_mi2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new secondary_mi2s_rx2_mixer_controls[] = { @@ -6664,6 +6898,10 @@ static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = { @@ -6755,6 +6993,10 @@ static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; @@ -6981,6 +7223,10 @@ static const struct snd_kcontrol_new hdmi_mixer_controls[] = { MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new display_port_mixer_controls[] = { @@ -8265,6 +8511,10 @@ static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = { MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new int_bt_a2dp_rx_mixer_controls[] = { @@ -8427,6 +8677,10 @@ static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = { MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = { @@ -8518,6 +8772,10 @@ static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = { MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = { @@ -8613,6 +8871,10 @@ static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = { MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = { @@ -8708,6 +8970,10 @@ static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = { MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_auxpcm_rx_mixer_controls[] = { @@ -14215,7 +14481,7 @@ static const struct snd_kcontrol_new mmul28_mixer_controls[] = { msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, @@ -14402,6 +14668,119 @@ static const struct snd_kcontrol_new mmul29_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new mmul30_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_I2S_RX, @@ -21868,6 +22247,7 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("MM_UL27", "MultiMedia27 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL28", "MultiMedia28 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL29", "MultiMedia29 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL30", "MultiMedia30 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("VOICEMMODE1_DL", "VoiceMMode1 Playback", 0, 0, 0, 0), @@ -22950,6 +23330,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { mmul28_mixer_controls, ARRAY_SIZE(mmul28_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia29 Mixer", SND_SOC_NOPM, 0, 0, mmul29_mixer_controls, ARRAY_SIZE(mmul29_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia30 Mixer", SND_SOC_NOPM, 0, 0, + mmul30_mixer_controls, ARRAY_SIZE(mmul30_mixer_controls)), SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)), SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, @@ -23879,6 +24261,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia28 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia29 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia29 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia30 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia30 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia8 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia8 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia2 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -23888,21 +24272,25 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia19 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia28 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia29 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia30 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia8 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia18 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"MultiMedia19 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"MultiMedia28 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"MultiMedia29 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia30 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"MultiMedia17 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia18 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia19 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia28 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia29 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia30 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia17 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia18 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia19 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia28 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia29 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia30 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia8 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia3 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, @@ -23921,10 +24309,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia19 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia28 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia29 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia30 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, {"MultiMedia18 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MultiMedia19 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MultiMedia28 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MultiMedia29 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia30 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, @@ -24762,6 +25152,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia19 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia28 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia29 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia30 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia6 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"MultiMedia6 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, @@ -25290,6 +25681,16 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia29 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, {"MultiMedia29 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia30 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia30 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia30 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, @@ -25373,6 +25774,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia19 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia28 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia29 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia30 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia5 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia8 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia16 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, @@ -25384,6 +25786,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia19 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia28 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia29 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia30 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia5 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia6 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia8 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, @@ -25397,6 +25800,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia19 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia28 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia29 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia30 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia5 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia8 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia16 Mixer", "AFE_PCM_TX", "PCM_TX"}, @@ -25419,6 +25823,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL27", NULL, "MultiMedia27 Mixer"}, {"MM_UL28", NULL, "MultiMedia28 Mixer"}, {"MM_UL29", NULL, "MultiMedia29 Mixer"}, + {"MM_UL30", NULL, "MultiMedia30 Mixer"}, {"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, @@ -25890,6 +26295,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL19", NULL, "AUDIO_REF_EC_UL19 MUX"}, {"MM_UL28", NULL, "AUDIO_REF_EC_UL28 MUX"}, {"MM_UL29", NULL, "AUDIO_REF_EC_UL29 MUX"}, + {"MM_UL30", NULL, "AUDIO_REF_EC_UL30 MUX"}, {"VoiceMMode1_Tx Mixer", "PRI_TX_MMode1", "PRI_I2S_TX"}, {"VoiceMMode1_Tx Mixer", "PRI_MI2S_TX_MMode1", "PRI_MI2S_TX"}, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 07b975229d7b..bbfe509410e1 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -260,6 +260,7 @@ enum { MSM_FRONTEND_DAI_MULTIMEDIA27, MSM_FRONTEND_DAI_MULTIMEDIA28, MSM_FRONTEND_DAI_MULTIMEDIA29, + MSM_FRONTEND_DAI_MULTIMEDIA30, MSM_FRONTEND_DAI_VOIP, MSM_FRONTEND_DAI_AFE_RX, MSM_FRONTEND_DAI_AFE_TX, @@ -281,8 +282,8 @@ enum { MSM_FRONTEND_DAI_MAX, }; -#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA29 + 1) -#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA29 +#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA30 + 1) +#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA30 enum { MSM_BACKEND_DAI_PRI_I2S_RX = 0, -- GitLab From ac555db98e98490769b35fefd031391286dd6cc5 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 9 Jul 2019 12:11:23 -0700 Subject: [PATCH 1082/1645] asoc: codecs: bolero: Keep track of lpass core votes Unvote lpass audio and hw votes from bolero suspend only if the voting was done from the corresponding resume function. Change-Id: I299b8e5639efe2883980abc5d0904733fbdc5a77 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/bolero-cdc.c | 60 ++++++++++++++++++++++++--------- asoc/codecs/bolero/internal.h | 3 ++ 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index c0c51ca5826b..8db452930ef1 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -960,9 +960,13 @@ static int bolero_probe(struct platform_device *pdev) priv->plat_data.update_wcd_event = bolero_cdc_update_wcd_event; priv->plat_data.register_notifier = bolero_cdc_register_notifier; + priv->core_hw_vote_count = 0; + priv->core_audio_vote_count = 0; + dev_set_drvdata(&pdev->dev, priv); mutex_init(&priv->io_lock); mutex_init(&priv->clk_lock); + mutex_init(&priv->vote_lock); INIT_WORK(&priv->bolero_add_child_devices_work, bolero_add_child_devices); schedule_work(&priv->bolero_add_child_devices_work); @@ -1002,6 +1006,7 @@ static int bolero_remove(struct platform_device *pdev) of_platform_depopulate(&pdev->dev); mutex_destroy(&priv->io_lock); mutex_destroy(&priv->clk_lock); + mutex_destroy(&priv->vote_lock); return 0; } @@ -1015,21 +1020,35 @@ int bolero_runtime_resume(struct device *dev) return 0; } - ret = clk_prepare_enable(priv->lpass_core_hw_vote); - if (ret < 0) - dev_err(dev, "%s:lpass core hw enable failed\n", - __func__); + mutex_lock(&priv->vote_lock); + if (priv->core_hw_vote_count == 0) { + ret = clk_prepare_enable(priv->lpass_core_hw_vote); + if (ret < 0) { + dev_err(dev, "%s:lpass core hw enable failed\n", + __func__); + goto audio_vote; + } + } + priv->core_hw_vote_count++; +audio_vote: if (priv->lpass_audio_hw_vote == NULL) { dev_dbg(dev, "%s: Invalid lpass audio hw node\n", __func__); - return 0; + goto done; } - ret = clk_prepare_enable(priv->lpass_audio_hw_vote); - if (ret < 0) - dev_err(dev, "%s:lpass audio hw enable failed\n", - __func__); + if (priv->core_audio_vote_count == 0) { + ret = clk_prepare_enable(priv->lpass_audio_hw_vote); + if (ret < 0) { + dev_err(dev, "%s:lpass audio hw enable failed\n", + __func__); + goto done; + } + } + priv->core_audio_vote_count++; +done: + mutex_unlock(&priv->vote_lock); pm_runtime_set_autosuspend_delay(priv->dev, BOLERO_AUTO_SUSPEND_DELAY); return 0; } @@ -1039,17 +1058,28 @@ int bolero_runtime_suspend(struct device *dev) { struct bolero_priv *priv = dev_get_drvdata(dev->parent); - if (priv->lpass_core_hw_vote != NULL) - clk_disable_unprepare(priv->lpass_core_hw_vote); - else + mutex_lock(&priv->vote_lock); + if (priv->lpass_core_hw_vote != NULL) { + if (--priv->core_hw_vote_count == 0) + clk_disable_unprepare(priv->lpass_core_hw_vote); + if (priv->core_hw_vote_count < 0) + priv->core_hw_vote_count = 0; + } else { dev_dbg(dev, "%s: Invalid lpass core hw node\n", __func__); + } - if (priv->lpass_audio_hw_vote != NULL) - clk_disable_unprepare(priv->lpass_audio_hw_vote); - else + if (priv->lpass_audio_hw_vote != NULL) { + if (--priv->core_audio_vote_count == 0) + clk_disable_unprepare(priv->lpass_audio_hw_vote); + if (priv->core_audio_vote_count < 0) + priv->core_audio_vote_count = 0; + } else { dev_dbg(dev, "%s: Invalid lpass audio hw node\n", __func__); + } + + mutex_unlock(&priv->vote_lock); return 0; } EXPORT_SYMBOL(bolero_runtime_suspend); diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 21c96520c4ee..d353a2d21b78 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -46,6 +46,7 @@ struct bolero_priv { struct regmap *regmap; struct mutex io_lock; struct mutex clk_lock; + struct mutex vote_lock; bool va_without_decimation; bool macros_supported[MAX_MACRO]; bool dev_up; @@ -60,6 +61,8 @@ struct bolero_priv { u32 version; struct clk *lpass_core_hw_vote; struct clk *lpass_audio_hw_vote; + int core_hw_vote_count; + int core_audio_vote_count; /* Entry for version info */ struct snd_info_entry *entry; -- GitLab From fd90ac4b16edfbcf8625a8cc5b06c326a79de5be Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 10 Jul 2019 11:04:56 +0530 Subject: [PATCH 1083/1645] soc: pinctrl-lpi: Protect core_hw_vote status with lock During SSR and lpi gpio read/write use cases, core_hw_vote status flag might be checked and modified in parallel. Protect the core_hw_vote status with mutex lock to avoid any race conditions. Change-Id: I313908dfa72430cc49d7d11e6ce8c1bb7af0a1c3 Signed-off-by: Aditya Bavanari --- soc/pinctrl-lpi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index d990f9cb081b..e11ba6e2be96 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -148,6 +148,7 @@ static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr) return 0; } pm_runtime_get_sync(lpi_dev); + mutex_lock(&state->core_hw_vote_lock); if (!state->core_hw_vote_status) { pr_err_ratelimited("%s: core hw vote clk is not enabled\n", __func__); @@ -160,6 +161,7 @@ static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr) pr_err("%s: read 0x%x failed\n", __func__, addr); err: + mutex_unlock(&state->core_hw_vote_lock); pm_runtime_mark_last_busy(lpi_dev); pm_runtime_put_autosuspend(lpi_dev); return ret; @@ -177,6 +179,7 @@ static int lpi_gpio_write(struct lpi_gpio_pad *pad, unsigned int addr, return 0; } pm_runtime_get_sync(lpi_dev); + mutex_lock(&state->core_hw_vote_lock); if (!state->core_hw_vote_status) { pr_err_ratelimited("%s: core hw vote clk is not enabled\n", __func__); @@ -186,6 +189,7 @@ static int lpi_gpio_write(struct lpi_gpio_pad *pad, unsigned int addr, iowrite32(val, pad->base + pad->offset + addr); err: + mutex_unlock(&state->core_hw_vote_lock); pm_runtime_mark_last_busy(lpi_dev); pm_runtime_put_autosuspend(lpi_dev); return ret; @@ -484,11 +488,8 @@ static struct notifier_block service_nb = { static void lpi_pinctrl_ssr_disable(struct device *dev, void *data) { - struct lpi_gpio_state *state = dev_get_drvdata(dev); - lpi_dev_up = false; - if (state->core_hw_vote_status) - lpi_pinctrl_runtime_suspend(dev); + lpi_pinctrl_runtime_suspend(dev); } static const struct snd_event_ops lpi_pinctrl_ssr_ops = { -- GitLab From bd1e4dfdbeb261fad74419d3ae4d18395453eb34 Mon Sep 17 00:00:00 2001 From: Faiz Nabi Kuchay Date: Tue, 16 Jul 2019 13:26:28 +0530 Subject: [PATCH 1084/1645] asoc: codecs: Increase size of proc_name Increase size of proc_name to prevent buffer overflow in snprintf function. Change-Id: I183d2762d2d60c4b40969b1ddce9b4d5588e7051 Signed-off-by: Faiz Nabi Kuchay --- asoc/codecs/wcd_cpe_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd_cpe_core.c b/asoc/codecs/wcd_cpe_core.c index 2ef4ae61e11e..4c776d199266 100644 --- a/asoc/codecs/wcd_cpe_core.c +++ b/asoc/codecs/wcd_cpe_core.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. */ #include @@ -52,7 +52,7 @@ mutex_unlock(lock); \ } -#define WCD_CPE_STATE_MAX_LEN 11 +#define WCD_CPE_STATE_MAX_LEN 32 #define CPE_OFFLINE_WAIT_TIMEOUT (2 * HZ) #define CPE_READY_WAIT_TIMEOUT (3 * HZ) #define WCD_CPE_SYSFS_DIR_MAX_LENGTH 32 -- GitLab From 07d5afc4cb215c4fc18765a994c3eaebb234fa23 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 17 Jul 2019 06:25:45 +0530 Subject: [PATCH 1085/1645] soc: soundwire: Enable soundwire slave host irq soundwire slave devices gets reset resulting in setting host irq to default state. Enable soundwire slave host irq to process slave interrupts. Change-Id: I49c3482a22b89fe2a28768edcf7d1e19ba0b978f Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 30c1f14c416f..65f10ba7865a 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1308,6 +1308,26 @@ static int swrm_find_alert_slave(struct swr_mstr_ctrl *swrm, return -EINVAL; } +static void swrm_enable_slave_irq(struct swr_mstr_ctrl *swrm) +{ + int i; + int status = 0; + + status = swr_master_read(swrm, SWRM_MCP_SLV_STATUS); + if (!status) { + dev_dbg_ratelimited(swrm->dev, "%s: slaves status is 0x%x\n", + __func__, status); + return; + } + dev_dbg(swrm->dev, "%s: slave status: 0x%x\n", __func__, status); + for (i = 0; i < (swrm->master.num_dev + 1); i++) { + if (status & SWRM_MCP_SLV_STATUS_MASK) + swrm_cmd_fifo_wr_cmd(swrm, 0x4, i, 0x0, + SWRS_SCP_INT_STATUS_MASK_1); + status >>= 2; + } +} + static int swrm_check_slave_change_status(struct swr_mstr_ctrl *swrm, int status, u8 *devnum) { @@ -1674,6 +1694,12 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) dev_err_ratelimited(swrm->dev, "%s: SWR wokeup during clock stop\n", __func__); + /* It might be possible the slave device gets reset + * and slave interrupt gets missed. So re-enable + * Host IRQ and process slave pending + * interrupts, if any. + */ + swrm_enable_slave_irq(swrm); break; default: dev_err_ratelimited(swrm->dev, @@ -1690,7 +1716,8 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) intr_sts_masked = intr_sts & swrm->intr_mask; if (intr_sts_masked) { - dev_dbg(swrm->dev, "%s: new interrupt received\n", __func__); + dev_dbg(swrm->dev, "%s: new interrupt received 0x%x\n", + __func__, intr_sts_masked); goto handle_irq; } -- GitLab From 278e543a32d42157e2dd95ba3ee3fe16d0a08ea4 Mon Sep 17 00:00:00 2001 From: Dieter Luecking Date: Fri, 15 Mar 2019 11:49:45 +0100 Subject: [PATCH 1086/1645] asoc: csra66x0: Disable volume ramping in codec CSRA66x0 codec enables internal volume ramping on power up. This leads to missing audio at beginning of playback. Disable feature on codec init. Change-Id: Ib3085cd06eeb2797bee4e74d8e34e5d0b0fa535f Signed-off-by: Dieter Luecking --- asoc/codecs/csra66x0/csra66x0.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/asoc/codecs/csra66x0/csra66x0.c b/asoc/codecs/csra66x0/csra66x0.c index 4b650bf580ea..e0e702f565b3 100644 --- a/asoc/codecs/csra66x0/csra66x0.c +++ b/asoc/codecs/csra66x0/csra66x0.c @@ -754,6 +754,9 @@ static int csra66x0_init(struct csra66x0_priv *csra66x0) snd_soc_component_write(component, CSRA66X0_CH2_VOLUME_1_FA, SPK_VOLUME_M20DB_MSB); + /* disable volume ramping */ + snd_soc_component_write(component, CSRA66X0_VOLUME_CONFIG_FA, 0x27); + snd_soc_component_write(component, CSRA66X0_DEAD_TIME_CTRL, 0x0); snd_soc_component_write(component, CSRA66X0_DEAD_TIME_THRESHOLD_0, 0xE7); -- GitLab From 01a86d28951e400e9b80ca9468da063790234882 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 11 Jul 2019 16:36:46 +0530 Subject: [PATCH 1087/1645] ASoC: codec: Disable surge protection before impedance detection If surge protection is enabled, it interferes with HPHL and does not give proper impedance for high impedance cable. Disable surge protection before impedance detection and enable it again after impedance detection on wcd937x and wcd938x. Change-Id: I13840b0ba9fd9ce16b90f42dcd1a25ffb928b504 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x-mbhc.c | 9 +++++++++ asoc/codecs/wcd938x/wcd938x-mbhc.c | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index 4ad8683a490c..cec70e7ff302 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -547,6 +547,12 @@ static void wcd937x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MBHC_MECH, 0x01, 0x00); + /* Disable surge protection before impedance detection. + * This is done to give correct value for high impedance. + */ + regmap_update_bits(wcd937x->regmap, + WCD937X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0x00); + /* First get impedance on Left */ d1 = d1_a[1]; zdet_param_ptr = &zdet_param[1]; @@ -663,6 +669,9 @@ static void wcd937x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, mbhc->hph_type = WCD_MBHC_HPH_MONO; } + /* Enable surge protection again after impedance detection */ + regmap_update_bits(wcd937x->regmap, + WCD937X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0xC0); zdet_complete: snd_soc_component_write(component, WCD937X_ANA_MBHC_BTN5, reg0); snd_soc_component_write(component, WCD937X_ANA_MBHC_BTN6, reg1); diff --git a/asoc/codecs/wcd938x/wcd938x-mbhc.c b/asoc/codecs/wcd938x/wcd938x-mbhc.c index 08a2b228df3a..9c49755935f9 100644 --- a/asoc/codecs/wcd938x/wcd938x-mbhc.c +++ b/asoc/codecs/wcd938x/wcd938x-mbhc.c @@ -547,6 +547,12 @@ static void wcd938x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MBHC_MECH, 0x01, 0x00); + /* Disable surge protection before impedance detection. + * This is done to give correct value for high impedance. + */ + regmap_update_bits(wcd938x->regmap, + WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0x00); + /* First get impedance on Left */ d1 = d1_a[1]; zdet_param_ptr = &zdet_param[1]; @@ -656,6 +662,9 @@ static void wcd938x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, mbhc->hph_type = WCD_MBHC_HPH_MONO; } + /* Enable surge protection again after impedance detection */ + regmap_update_bits(wcd938x->regmap, + WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0xC0); zdet_complete: snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN5, reg0); snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN6, reg1); -- GitLab From 149008c89bebe019015e0acf5fe5314cd0591652 Mon Sep 17 00:00:00 2001 From: Arun Mirpuri Date: Wed, 17 Jul 2019 17:49:49 -0700 Subject: [PATCH 1088/1645] asoc: add PMQoS request during MMAP session pcm_prepare Add PMQoS request during MMAP session pcm_prepare to affine to cores 1 and 2 and also set PMQoS latency to 300 us to avoid LPM to go to deep sleep state on these 2 cores Signed-off-by: Arun Mirpuri Change-Id: Ie92ef6e4038b2ac0ba2edaf5acabaf28090b2c67 --- asoc/kona.c | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/kona.c b/asoc/kona.c index a8a64b216cc2..7754a8dc7d98 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -5553,6 +5553,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .ignore_pmdown_time = 1, /* this dainlink has playback support */ .id = MSM_FRONTEND_DAI_MULTIMEDIA16, + .ops = &msm_fe_qos_ops, }, {/* hw:x,30 */ .name = "CDC_DMA Hostless", -- GitLab From 549d11d4fe24af10cd7d892ce6448d92bafa8131 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 18 Jul 2019 13:44:17 +0530 Subject: [PATCH 1089/1645] asoc: codecs: Update on support for WCD938x DMICs WCD938x codec can support upto 8 DMICs. Fix driver to enable support for these DMICs over soundwire. Change-Id: I82b9c7c6f56271c03acee3a966dbaa4fefb62102 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/tx-macro.c | 20 ++++++++++++++++++-- asoc/codecs/bolero/va-macro.c | 21 ++++++++++++++++++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index bc5b056b03ec..2b830995b8e3 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -470,6 +470,12 @@ static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol, struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val = 0; u16 mic_sel_reg = 0; + u16 dmic_clk_reg = 0; + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) + return -EINVAL; val = ucontrol->value.enumerated.item[0]; if (val > e->items - 1) @@ -510,14 +516,24 @@ static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol, } if (strnstr(widget->name, "SMIC", strlen(widget->name))) { if (val != 0) { - if (val < 5) + if (val < 5) { snd_soc_component_update_bits(component, mic_sel_reg, 1 << 7, 0x0 << 7); - else + } else { snd_soc_component_update_bits(component, mic_sel_reg, 1 << 7, 0x1 << 7); + snd_soc_component_update_bits(component, + BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, + 0x80, 0x00); + dmic_clk_reg = + BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL + + ((val - 5)/2) * 4; + snd_soc_component_update_bits(component, + dmic_clk_reg, + 0x0E, tx_priv->dmic_clk_div << 0x1); + } } } else { /* DMIC selected */ diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 8e5abaa3c7d4..70ff6909e43f 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -409,7 +409,12 @@ static int va_macro_put_dec_enum(struct snd_kcontrol *kcontrol, snd_soc_dapm_to_component(widget->dapm); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val; - u16 mic_sel_reg; + u16 mic_sel_reg, dmic_clk_reg; + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) + return -EINVAL; val = ucontrol->value.enumerated.item[0]; if (val > e->items - 1) @@ -450,14 +455,24 @@ static int va_macro_put_dec_enum(struct snd_kcontrol *kcontrol, } if (strnstr(widget->name, "SMIC", strlen(widget->name))) { if (val != 0) { - if (val < 5) + if (val < 5) { snd_soc_component_update_bits(component, mic_sel_reg, 1 << 7, 0x0 << 7); - else + } else { snd_soc_component_update_bits(component, mic_sel_reg, 1 << 7, 0x1 << 7); + snd_soc_component_update_bits(component, + BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, + 0x80, 0x00); + dmic_clk_reg = + BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL + + ((val - 5)/2) * 4; + snd_soc_component_update_bits(component, + dmic_clk_reg, + 0x0E, va_priv->dmic_clk_div << 0x1); + } } } else { /* DMIC selected */ -- GitLab From d3f16750c4eacb0638c94b7baaf7e7da8ebedbcc Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 18 Jul 2019 13:46:00 +0530 Subject: [PATCH 1090/1645] asoc: codecs: Update dmic2 support on WCD938x As DMIC2 is muxed on same channel with MBHC on soundwire port3 of WCD938x codec, need to set selection bit for DMIC2 during recording usecase over it. Change-Id: Ice9b92eb964af25e47db4b3d8d25db07a82a9bf2 Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd938x/wcd938x.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 8a02d6f81f07..252da0a9236a 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1126,6 +1126,7 @@ static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w, u8 dmic_ctl_shift = 0; u8 dmic_clk_shift = 0; u8 dmic_clk_mask = 0; + u16 dmic2_left_en = 0; dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -1141,6 +1142,7 @@ static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w, dmic_ctl_shift = 0x00; break; case 2: + dmic2_left_en = WCD938X_DIGITAL_CDC_DMIC2_CTL; case 3: dmic_clk_cnt = &(wcd938x->dmic_2_3_clk_cnt); dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_1_2; @@ -1182,6 +1184,9 @@ static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w, (0x01 << dmic_ctl_shift), 0x00); /* 250us sleep as per HW requirement */ usleep_range(250, 260); + if (dmic2_left_en) + snd_soc_component_update_bits(component, + dmic2_left_en, 0x80, 0x80); /* Setting DMIC clock rate to 2.4MHz */ snd_soc_component_update_bits(component, dmic_clk_reg, dmic_clk_mask, @@ -1199,6 +1204,9 @@ static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w, WCD938X_DIGITAL_CDC_AMIC_CTL, (0x01 << dmic_ctl_shift), (0x01 << dmic_ctl_shift)); + if (dmic2_left_en) + snd_soc_component_update_bits(component, + dmic2_left_en, 0x80, 0x00); snd_soc_component_update_bits(component, dmic_clk_en_reg, 0x08, 0x00); break; -- GitLab From db79e5fabcd06c886be0f82d5af3e45661bcb9fa Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 18 Jul 2019 13:47:57 +0530 Subject: [PATCH 1091/1645] asoc: kona: Add digital mic7/8 support on WCD938x WCD938x supports upto 8 DMICs over soundwire. Update entries for digital mic7/8 in widgets table. Change-Id: If791d88b1145e798de46b9409a48210da8499ad1 Signed-off-by: Laxminath Kasam --- asoc/kona.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asoc/kona.c b/asoc/kona.c index ee239e460e29..63ee94869d59 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -4915,6 +4915,8 @@ static const struct snd_soc_dapm_widget msm_int_dapm_widgets[] = { SND_SOC_DAPM_MIC("Digital Mic3", msm_dmic_event), SND_SOC_DAPM_MIC("Digital Mic4", msm_dmic_event), SND_SOC_DAPM_MIC("Digital Mic5", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic6", NULL), + SND_SOC_DAPM_MIC("Digital Mic7", NULL), }; static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) @@ -4981,6 +4983,8 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic6"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic7"); snd_soc_dapm_ignore_suspend(dapm, "Analog Mic1"); snd_soc_dapm_ignore_suspend(dapm, "Analog Mic2"); -- GitLab From 311bd67be03749509274f13a9d6f82e52ee67a9d Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 6 Jun 2019 13:40:55 -0700 Subject: [PATCH 1092/1645] asoc: codecs: Add multi input support for display audio mixers Add multi input support such that display audio mixer controls can update both control ID and stream ID to support display audio multi streaming. Change-Id: Ief8fe852585a31fbe5871ce8ecc1057d6891e2b7 Signed-off-by: Karthikeyan Mani Signed-off-by: Vignesh Kulothungan --- asoc/codecs/msm_hdmi_codec_rx.c | 76 +++++++++++++++++++++++++++++---- asoc/msm-dai-q6-hdmi-v2.c | 22 +++++++++- 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/asoc/codecs/msm_hdmi_codec_rx.c b/asoc/codecs/msm_hdmi_codec_rx.c index 534959811422..04117c8366b2 100644 --- a/asoc/codecs/msm_hdmi_codec_rx.c +++ b/asoc/codecs/msm_hdmi_codec_rx.c @@ -32,6 +32,11 @@ msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, \ &codec_info) +enum { + DP_CONTROLLER0 = 0, + DP_CONTROLLER_MAX, +}; + enum { DP_STREAM0 = 0, DP_STREAM1, @@ -295,6 +300,38 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, return rc; } +static int msm_ext_disp_audio_device_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct msm_ext_disp_audio_codec_rx_data *codec_data; + int rc = 0; + int dai_id = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + if (dai_id < 0 || dai_id > DP_DAI2) { + dev_err(component->dev, + "%s: invalid dai id: %d\n", __func__, dai_id); + rc = -EINVAL; + goto done; + } + + codec_data = snd_soc_component_get_drvdata(component); + if (!codec_data) { + dev_err(component->dev, + "%s: codec_data or ops acknowledge() is NULL\n", + __func__); + rc = -EINVAL; + goto done; + } + ucontrol->value.integer.value[0] = codec_data->ctl[dai_id]; + ucontrol->value.integer.value[1] = codec_data->stream[dai_id]; + +done: + return rc; +} + static int msm_ext_disp_audio_device_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -302,7 +339,15 @@ static int msm_ext_disp_audio_device_set(struct snd_kcontrol *kcontrol, snd_soc_kcontrol_component(kcontrol); struct msm_ext_disp_audio_codec_rx_data *codec_data; int rc = 0; - int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l; + int dai_id = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + if (dai_id < 0 || dai_id > DP_DAI2) { + dev_err(component->dev, + "%s: invalid dai id: %d\n", __func__, dai_id); + rc = -EINVAL; + goto done; + } codec_data = snd_soc_component_get_drvdata(component); if (!codec_data) { @@ -313,9 +358,20 @@ static int msm_ext_disp_audio_device_set(struct snd_kcontrol *kcontrol, goto done; } + if ((ucontrol->value.integer.value[0] > (DP_CONTROLLER_MAX - 1)) || + (ucontrol->value.integer.value[1] > (DP_STREAM_MAX - 1)) || + (ucontrol->value.integer.value[0] < 0) || + (ucontrol->value.integer.value[1] < 0)) { + dev_err(component->dev, + "%s: DP audio control index invalid\n", + __func__); + rc = -EINVAL; + goto done; + } + mutex_lock(&codec_data->dp_ops_lock); - codec_data->ctl[dai_id] = ucontrol->value.enumerated.item[0]; - codec_data->stream[dai_id] = ucontrol->value.enumerated.item[1]; + codec_data->ctl[dai_id] = ucontrol->value.integer.value[0]; + codec_data->stream[dai_id] = ucontrol->value.integer.value[1]; mutex_unlock(&codec_data->dp_ops_lock); done: @@ -363,12 +419,14 @@ static const struct snd_kcontrol_new msm_ext_disp_codec_rx_controls[] = { ext_disp_audio_ack_state1, NULL, msm_ext_disp_audio_ack_set), - SOC_SINGLE_EXT("External Display Audio Device", - SND_SOC_NOPM, DP_DAI1, DP_STREAM_MAX, 0, - NULL, msm_ext_disp_audio_device_set), - SOC_SINGLE_EXT("External Display1 Audio Device", - SND_SOC_NOPM, DP_DAI2, DP_STREAM_MAX, 0, - NULL, msm_ext_disp_audio_device_set), + SOC_SINGLE_MULTI_EXT("External Display Audio Device", + SND_SOC_NOPM, DP_DAI1, DP_STREAM_MAX - 1, 0, 2, + msm_ext_disp_audio_device_get, + msm_ext_disp_audio_device_set), + SOC_SINGLE_MULTI_EXT("External Display1 Audio Device", + SND_SOC_NOPM, DP_DAI2, DP_STREAM_MAX - 1, 0, 2, + msm_ext_disp_audio_device_get, + msm_ext_disp_audio_device_set), }; static int msm_ext_disp_audio_codec_rx_dai_startup( diff --git a/asoc/msm-dai-q6-hdmi-v2.c b/asoc/msm-dai-q6-hdmi-v2.c index fb50eba63625..80164f325e5d 100644 --- a/asoc/msm-dai-q6-hdmi-v2.c +++ b/asoc/msm-dai-q6-hdmi-v2.c @@ -19,6 +19,18 @@ #define HDMI_RX_CA_MAX 0x32 +enum { + DP_CONTROLLER0 = 0, + DP_CONTROLLER1, + DP_CONTROLLER_MAX, +}; + +enum { + DP_STREAM0 = 0, + DP_STREAM1, + DP_STREAM_MAX, +}; + enum { STATUS_PORT_STARTED, /* track if AFE port has started */ STATUS_MAX @@ -84,6 +96,14 @@ static int msm_dai_q6_ext_disp_device_idx_put(struct snd_kcontrol *kcontrol, return -EINVAL; } + if ((ucontrol->value.integer.value[0] > (DP_CONTROLLER_MAX - 1)) || + (ucontrol->value.integer.value[1] > (DP_STREAM_MAX - 1)) || + (ucontrol->value.integer.value[0] < 0) || + (ucontrol->value.integer.value[1] < 0)) { + pr_err("%s: DP control index invalid\n", __func__); + return -EINVAL; + } + dai_data->ctl_idx = ucontrol->value.integer.value[0]; dai_data->stream_idx = ucontrol->value.integer.value[1]; pr_debug("%s: DP ctl id %d stream id %d\n", __func__, @@ -219,7 +239,7 @@ static const struct snd_kcontrol_new display_port_config_controls[] = { msm_dai_q6_ext_disp_ca_get, msm_dai_q6_ext_disp_ca_put), SOC_SINGLE_MULTI_EXT("Display Port RX DEVICE IDX", SND_SOC_NOPM, 0, - 1, 0, 1, + 1, 0, 2, msm_dai_q6_ext_disp_device_idx_get, msm_dai_q6_ext_disp_device_idx_put), { -- GitLab From f53de7f9fb98f4236ab7aed20960a74702cb966e Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Sun, 3 Mar 2019 22:30:47 +0530 Subject: [PATCH 1093/1645] audio-driver: Update build files for sa6155 Enable conditional build for audio driver modules specific to sa6155. Change-Id: I58701a907242afcfe230623ff42b47c001e3d5f4 Signed-off-by: Rahul Sharma --- Android.mk | 6 +++++- asoc/Android.mk | 4 ++++ asoc/Kbuild | 21 +++++++++++++++++---- asoc/codecs/Android.mk | 14 +++++++++----- asoc/codecs/Kbuild | 12 +++++++++--- asoc/machine_615x_init.c | 2 -- asoc/machine_615x_init.h | 2 -- asoc/sa6155.c | 3 +++ config/sa6155auto.conf | 16 ++++++++++++++++ config/sa6155autoconf.h | 28 ++++++++++++++++++++++++++++ dsp/Android.mk | 17 ++++++++++------- dsp/Kbuild | 12 +++++++++--- ipc/Android.mk | 8 ++++++-- ipc/Kbuild | 12 +++++++++--- soc/Android.mk | 2 +- 15 files changed, 126 insertions(+), 33 deletions(-) create mode 100644 config/sa6155auto.conf create mode 100644 config/sa6155autoconf.h diff --git a/Android.mk b/Android.mk index 41f14b30a59c..835c670b73ab 100644 --- a/Android.mk +++ b/Android.mk @@ -22,9 +22,11 @@ include $(MY_LOCAL_PATH)/asoc/codecs/Android.mk endif ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au sm6150_au msmnile_gvmq)) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers) +include $(MY_LOCAL_PATH)/soc/Android.mk endif endif @@ -40,11 +42,13 @@ endif endif ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), sm6150_au)) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/bolero/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/bolero/Android.mk $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd937x/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wcd937x/Android.mk endif +endif ifeq ($(call is-board-platform-in-list, kona lito),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/bolero/Module.symvers) diff --git a/asoc/Android.mk b/asoc/Android.mk index 1fb172a5d92c..8a2a0cc1f4a6 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -14,8 +14,12 @@ endif ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) TARGET := talos +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), sm6150_au)) +AUDIO_SELECT := CONFIG_SND_SOC_SA6155=m +else AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif +endif ifeq ($(call is-board-platform,$(TRINKET)),true) TARGET := trinket diff --git a/asoc/Kbuild b/asoc/Kbuild index 00a6a445c325..9ca09b7a336b 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -26,9 +26,15 @@ ifeq ($(KERNEL_BUILD), 0) endif endif ifeq ($(CONFIG_ARCH_SM6150), y) - include $(AUDIO_ROOT)/config/sm6150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + ifdef CONFIG_SND_SOC_SA6155 + include $(AUDIO_ROOT)/config/sa6155auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sa6155autoconf.h + else + include $(AUDIO_ROOT)/config/sm6150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + endif endif ifeq ($(CONFIG_ARCH_TRINKET), y) include $(AUDIO_ROOT)/config/sm6150auto.conf @@ -96,10 +102,14 @@ endif # for SM6150 sound card driver ifdef CONFIG_SND_SOC_SM6150 MACHINE_OBJS += sm6150.o - MACHINE_OBJS += sa6155.o MACHINE_OBJS += machine_615x_init.o endif +# For sa6155 sound card driver +ifdef CONFIG_SND_SOC_SA6155 + MACHINE_OBJS += sa6155.o +endif + # for qcs405 sound card driver ifdef CONFIG_SND_SOC_QCS405 MACHINE_OBJS += qcs405.o @@ -211,6 +221,9 @@ machine_dlkm-y := $(MACHINE_OBJS) obj-$(CONFIG_SND_SOC_SM6150) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) +obj-$(CONFIG_SND_SOC_SA6155) += machine_dlkm.o +machine_dlkm-y := $(MACHINE_OBJS) + obj-$(CONFIG_SND_SOC_QCS405) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index 9e58936febe8..077410ccd2aa 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -12,8 +12,12 @@ endif endif ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), sm6150_au)) +AUDIO_SELECT := CONFIG_SND_SOC_SA6155=m +else AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif +endif ifeq ($(call is-board-platform,$(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m @@ -54,9 +58,9 @@ KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) KBUILD_OPTIONS += MODNAME=wcd_core_dlkm KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) KBUILD_OPTIONS += $(AUDIO_SELECT) - +# Target specific build ########################################################### -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au sm6150_au msmnile_gvmq)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd_core.ko LOCAL_MODULE_KBUILD_NAME := wcd_core_dlkm.ko @@ -118,8 +122,8 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk -endif -############################################################ +endif # target specific build +########################################################### include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_stub.ko LOCAL_MODULE_KBUILD_NAME := stub_dlkm.ko @@ -127,7 +131,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk -########################################################## +########################################################### include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_hdmi.ko LOCAL_MODULE_KBUILD_NAME := hdmi_dlkm.ko diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 4cda710fc8ef..9b2aae3817ff 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -26,9 +26,15 @@ ifeq ($(KERNEL_BUILD), 0) endif endif ifeq ($(CONFIG_ARCH_SM6150), y) - include $(AUDIO_ROOT)/config/sm6150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + ifdef CONFIG_SND_SOC_SA6155 + include $(AUDIO_ROOT)/config/sa6155auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sa6155autoconf.h + else + include $(AUDIO_ROOT)/config/sm6150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + endif endif ifeq ($(CONFIG_ARCH_TRINKET), y) include $(AUDIO_ROOT)/config/sm6150auto.conf diff --git a/asoc/machine_615x_init.c b/asoc/machine_615x_init.c index 4f5fd1bc72c7..d49ca5d70834 100644 --- a/asoc/machine_615x_init.c +++ b/asoc/machine_615x_init.c @@ -19,14 +19,12 @@ static int __init audio_machine_615x_init(void) { sm6150_init(); - sa6155_init(); return 0; } static void audio_machine_615x_exit(void) { sm6150_exit(); - sa6155_exit(); } module_init(audio_machine_615x_init); diff --git a/asoc/machine_615x_init.h b/asoc/machine_615x_init.h index ac7374d97668..e20d9f865f6a 100644 --- a/asoc/machine_615x_init.h +++ b/asoc/machine_615x_init.h @@ -15,9 +15,7 @@ #ifndef __MACHINE_615X_INIT_H__ #define __MACHINE_615X_INIT_H__ int sm6150_init(void); -int sa6155_init(void); void sm6150_exit(void); -void sa6155_exit(void); #endif diff --git a/asoc/sa6155.c b/asoc/sa6155.c index 0cd29ac97ba9..73217fa3f5ee 100644 --- a/asoc/sa6155.c +++ b/asoc/sa6155.c @@ -7156,6 +7156,9 @@ void sa6155_exit(void) audio_notifier_deregister("sa6155"); } +module_init(sa6155_init); +module_exit(sa6155_exit); + MODULE_DESCRIPTION("ALSA SoC msm"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:" DRV_NAME); diff --git a/config/sa6155auto.conf b/config/sa6155auto.conf new file mode 100644 index 000000000000..85190d1ec1bf --- /dev/null +++ b/config/sa6155auto.conf @@ -0,0 +1,16 @@ +CONFIG_MSM_QDSP6_APRV2_RPMSG=m +CONFIG_MSM_QDSP6_SSR=m +CONFIG_MSM_ADSP_LOADER=m +CONFIG_MSM_QDSP6_NOTIFIER=m +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +CONFIG_QTI_PP=m +CONFIG_SND_HWDEP_ROUTING=m +CONFIG_DTS_EAGLE=m +CONFIG_DOLBY_DS2=m +CONFIG_DOLBY_LICENSE=m +CONFIG_SND_SOC_MSM_STUB=m +CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m +CONFIG_MSM_QDSP6V2_CODECS=m +CONFIG_SND_SOC_QDSP6V2=m +CONFIG_SND_SOC_SA6155=m +CONFIG_SOUNDWIRE_MSTR_CTRL=m diff --git a/config/sa6155autoconf.h b/config/sa6155autoconf.h new file mode 100644 index 000000000000..312fbd0f91b7 --- /dev/null +++ b/config/sa6155autoconf.h @@ -0,0 +1,28 @@ +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define CONFIG_MSM_QDSP6_APRV2_RPMSG 1 +#define CONFIG_MSM_QDSP6_SSR 1 +#define CONFIG_MSM_ADSP_LOADER 1 +#define CONFIG_MSM_QDSP6_NOTIFIER 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_QTI_PP 1 +#define CONFIG_SND_HWDEP_ROUTING 1 +#define CONFIG_DTS_EAGLE 1 +#define CONFIG_DOLBY_DS2 1 +#define CONFIG_DOLBY_LICENSE 1 +#define CONFIG_SND_SOC_MSM_STUB 1 +#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 +#define CONFIG_MSM_QDSP6V2_CODECS 1 +#define CONFIG_SND_SOC_QDSP6V2 1 +#define CONFIG_SND_SOC_SA6155 1 +#define CONFIG_SOUNDWIRE_MSTR_CTRL 1 diff --git a/dsp/Android.mk b/dsp/Android.mk index 9119ea434292..fe4d9f69ea75 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -11,9 +11,13 @@ AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif endif -ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), sm6150_au)) +AUDIO_SELECT := CONFIG_SND_SOC_SA6155=m +else AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif +endif ifeq ($(call is-board-platform, kona),true) AUDIO_SELECT := CONFIG_SND_SOC_KONA=m @@ -75,8 +79,9 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk -############################################################ -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) +########################################################### +# target specific build +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au sm6150_au msmnile_gvmq)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_usf.ko LOCAL_MODULE_KBUILD_NAME := usf_dlkm.ko @@ -84,7 +89,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk -########################################################## +########################################################### include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_q6_pdr.ko LOCAL_MODULE_KBUILD_NAME := q6_pdr_dlkm.ko @@ -92,9 +97,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk -endif -########################################################### ########################################################### - +endif # target specific build endif # DLKM check endif # supported target check diff --git a/dsp/Kbuild b/dsp/Kbuild index cd826c530f40..9ab89668d7e4 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -15,9 +15,15 @@ endif ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SM6150), y) - include $(AUDIO_ROOT)/config/sm6150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + ifdef CONFIG_SND_SOC_SA6155 + include $(AUDIO_ROOT)/config/sa6155auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sa6155autoconf.h + else + include $(AUDIO_ROOT)/config/sm6150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + endif endif ifeq ($(CONFIG_ARCH_TRINKET), y) include $(AUDIO_ROOT)/config/sm6150auto.conf diff --git a/ipc/Android.mk b/ipc/Android.mk index 4c582f02e336..2ab38b765304 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -11,9 +11,13 @@ AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif endif -ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), sm6150_au)) +AUDIO_SELECT := CONFIG_SND_SOC_SA6155=m +else AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif +endif ifeq ($(call is-board-platform,kona),true) AUDIO_SELECT := CONFIG_SND_SOC_KONA=m @@ -61,7 +65,7 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au sm6150_au msmnile_gvmq)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wglink.ko LOCAL_MODULE_KBUILD_NAME := wglink_dlkm.ko diff --git a/ipc/Kbuild b/ipc/Kbuild index 6a5c08bac37c..fa8776143219 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -16,9 +16,15 @@ endif ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SM6150), y) - include $(AUDIO_ROOT)/config/sm6150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + ifdef CONFIG_SND_SOC_SA6155 + include $(AUDIO_ROOT)/config/sa6155auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sa6155autoconf.h + else + include $(AUDIO_ROOT)/config/sm6150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + endif endif ifeq ($(CONFIG_ARCH_TRINKET), y) include $(AUDIO_ROOT)/config/sm6150auto.conf diff --git a/soc/Android.mk b/soc/Android.mk index 0bd740322fdc..8698a56a204b 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -7,7 +7,7 @@ ifeq ($(call is-board-platform,msmnile),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif -ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif -- GitLab From 04a6cfa44e48b98cbc1d4ee2419f50356b99be72 Mon Sep 17 00:00:00 2001 From: Cong Tang Date: Tue, 26 Feb 2019 15:08:55 +0800 Subject: [PATCH 1094/1645] audio-driver: update to support 32 channels update asm/adm/afe drivers to support 32 channels. Change-Id: Ia231eb6a0fb545569f0f8e1f2442432d761866e9 Signed-off-by: Cong Tang --- asoc/msm-dai-fe.c | 72 ++++++------ asoc/msm-dai-q6-v2.c | 219 ++++++++++++++++++++++++++++--------- dsp/q6adm.c | 66 +++++++++++ dsp/q6afe.c | 41 ++++++- dsp/q6asm.c | 33 ++++++ include/dsp/apr_audio-v2.h | 56 +++++++++- 6 files changed, 395 insertions(+), 92 deletions(-) diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index f53b3a6a5b0f..fa2ab990fbcb 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -91,7 +91,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 16, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -105,7 +105,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 16, + .channels_max = 32, .rate_min = 8000, .rate_max = 48000, }, @@ -124,7 +124,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -138,7 +138,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 48000, }, @@ -184,7 +184,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 6, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -198,7 +198,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 48000, }, @@ -217,7 +217,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -237,7 +237,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -251,7 +251,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 48000, }, @@ -270,7 +270,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -284,7 +284,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 48000, }, @@ -303,7 +303,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 16, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -323,7 +323,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -337,7 +337,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 48000, }, @@ -2140,7 +2140,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -2151,7 +2151,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_RATE_KNOT), .formats = SNDRV_PCM_FMTBIT_S16_LE, .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 48000, }, @@ -2332,7 +2332,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -2364,7 +2364,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -2384,7 +2384,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -2404,7 +2404,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -2424,7 +2424,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -2444,7 +2444,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -2464,7 +2464,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -2478,7 +2478,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 48000, }, @@ -2546,7 +2546,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 192000, }, @@ -2565,7 +2565,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 192000, }, @@ -2584,7 +2584,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 192000, }, @@ -2604,7 +2604,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 384000, }, @@ -2618,7 +2618,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 48000, }, @@ -2630,16 +2630,16 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .playback = { .stream_name = "MultiMedia21 Playback", .aif_name = "MM_DL21", - .rates = (SNDRV_PCM_RATE_8000_384000| + .rates = (SNDRV_PCM_RATE_8000_384000 | SNDRV_PCM_RATE_KNOT), .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, - .rate_min = 8000, - .rate_max = 384000, + .channels_max = 32, + .rate_min = 8000, + .rate_max = 384000, }, .capture = { .stream_name = "MultiMedia21 Capture", @@ -2651,7 +2651,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 48000, }, @@ -2708,7 +2708,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 192000, }, @@ -2727,7 +2727,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE), .channels_min = 1, - .channels_max = 8, + .channels_max = 32, .rate_min = 8000, .rate_max = 192000, }, diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 7cb2c0b258c4..6a30f3e9fb60 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -8144,6 +8144,9 @@ static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai, case 16: cap_mask = 0xFFFF; break; + case 32: + cap_mask = 0xFFFFFFFF; + break; default: dev_err(dai->dev, "%s: invalid slots %d\n", __func__, slots); @@ -8293,6 +8296,8 @@ static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai, dev_get_drvdata(dai->dev); struct afe_param_id_slot_mapping_cfg *slot_mapping = &dai_data->port_cfg.slot_mapping; + struct afe_param_id_slot_mapping_cfg_v2 *slot_mapping_v2 = + &dai_data->port_cfg.slot_mapping_v2; int i = 0; dev_dbg(dai->dev, "%s: dai id = 0x%x\n", __func__, dai->id); @@ -8346,23 +8351,49 @@ static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai, case AFE_PORT_ID_SENARY_TDM_RX_5: case AFE_PORT_ID_SENARY_TDM_RX_6: case AFE_PORT_ID_SENARY_TDM_RX_7: - if (!rx_slot) { - dev_err(dai->dev, "%s: rx slot not found\n", __func__); - return -EINVAL; - } - if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) { - dev_err(dai->dev, "%s: invalid rx num %d\n", __func__, - rx_num); - return -EINVAL; - } + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V3) { + if (!rx_slot) { + dev_err(dai->dev, "%s: rx slot not found\n", + __func__); + return -EINVAL; + } + if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT_V2) { + dev_err(dai->dev, "%s: invalid rx num %d\n", + __func__, + rx_num); + return -EINVAL; + } - for (i = 0; i < rx_num; i++) - slot_mapping->offset[i] = rx_slot[i]; - for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++) - slot_mapping->offset[i] = - AFE_SLOT_MAPPING_OFFSET_INVALID; + for (i = 0; i < rx_num; i++) + slot_mapping_v2->offset[i] = rx_slot[i]; + for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT_V2; + i++) + slot_mapping_v2->offset[i] = + AFE_SLOT_MAPPING_OFFSET_INVALID; - slot_mapping->num_channel = rx_num; + slot_mapping_v2->num_channel = rx_num; + } else { + if (!rx_slot) { + dev_err(dai->dev, "%s: rx slot not found\n", + __func__); + return -EINVAL; + } + if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) { + dev_err(dai->dev, "%s: invalid rx num %d\n", + __func__, + rx_num); + return -EINVAL; + } + + for (i = 0; i < rx_num; i++) + slot_mapping->offset[i] = rx_slot[i]; + for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++) + slot_mapping->offset[i] = + AFE_SLOT_MAPPING_OFFSET_INVALID; + + slot_mapping->num_channel = rx_num; + } break; case AFE_PORT_ID_PRIMARY_TDM_TX: case AFE_PORT_ID_PRIMARY_TDM_TX_1: @@ -8412,23 +8443,49 @@ static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai, case AFE_PORT_ID_SENARY_TDM_TX_5: case AFE_PORT_ID_SENARY_TDM_TX_6: case AFE_PORT_ID_SENARY_TDM_TX_7: - if (!tx_slot) { - dev_err(dai->dev, "%s: tx slot not found\n", __func__); - return -EINVAL; - } - if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) { - dev_err(dai->dev, "%s: invalid tx num %d\n", __func__, - tx_num); - return -EINVAL; - } + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V3) { + if (!tx_slot) { + dev_err(dai->dev, "%s: tx slot not found\n", + __func__); + return -EINVAL; + } + if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT_V2) { + dev_err(dai->dev, "%s: invalid tx num %d\n", + __func__, + tx_num); + return -EINVAL; + } + + for (i = 0; i < tx_num; i++) + slot_mapping_v2->offset[i] = tx_slot[i]; + for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT_V2; + i++) + slot_mapping_v2->offset[i] = + AFE_SLOT_MAPPING_OFFSET_INVALID; + + slot_mapping_v2->num_channel = tx_num; + } else { + if (!tx_slot) { + dev_err(dai->dev, "%s: tx slot not found\n", + __func__); + return -EINVAL; + } + if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) { + dev_err(dai->dev, "%s: invalid tx num %d\n", + __func__, + tx_num); + return -EINVAL; + } - for (i = 0; i < tx_num; i++) - slot_mapping->offset[i] = tx_slot[i]; - for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++) - slot_mapping->offset[i] = - AFE_SLOT_MAPPING_OFFSET_INVALID; + for (i = 0; i < tx_num; i++) + slot_mapping->offset[i] = tx_slot[i]; + for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++) + slot_mapping->offset[i] = + AFE_SLOT_MAPPING_OFFSET_INVALID; - slot_mapping->num_channel = tx_num; + slot_mapping->num_channel = tx_num; + } break; default: dev_err(dai->dev, "%s: invalid dai id 0x%x\n", @@ -8452,6 +8509,8 @@ static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream, &dai_data->port_cfg.tdm; struct afe_param_id_slot_mapping_cfg *slot_mapping = &dai_data->port_cfg.slot_mapping; + struct afe_param_id_slot_mapping_cfg_v2 *slot_mapping_v2 = + &dai_data->port_cfg.slot_mapping_v2; struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header = &dai_data->port_cfg.custom_tdm_header; @@ -8459,7 +8518,7 @@ static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream, __func__, dev_name(dai->dev)); if ((params_channels(params) == 0) || - (params_channels(params) > 8)) { + (params_channels(params) > 32)) { dev_err(dai->dev, "%s: invalid param channels %d\n", __func__, params_channels(params)); return -EINVAL; @@ -8561,32 +8620,88 @@ static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream, tdm->ctrl_data_out_enable, tdm->ctrl_invert_sync_pulse, tdm->ctrl_sync_data_delay); + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V3) { + /* + * update slot mapping v2 config param + * NOTE: channels/rate/bitwidth are per stream property + */ + slot_mapping_v2->bitwidth = dai_data->bitwidth; - /* - * update slot mapping config param - * NOTE: channels/rate/bitwidth are per stream property - */ - slot_mapping->bitwidth = dai_data->bitwidth; - - pr_debug("%s: SLOT MAPPING:\n" + pr_debug("%s: SLOT MAPPING_V2:\n" "num_channel=%d bitwidth=%d data_align=0x%x\n", __func__, - slot_mapping->num_channel, - slot_mapping->bitwidth, - slot_mapping->data_align_type); - pr_debug("%s: SLOT MAPPING:\n" + slot_mapping_v2->num_channel, + slot_mapping_v2->bitwidth, + slot_mapping_v2->data_align_type); + pr_debug("%s: SLOT MAPPING V2:\n" "offset[0]=0x%x offset[1]=0x%x offset[2]=0x%x offset[3]=0x%x\n" - "offset[4]=0x%x offset[5]=0x%x offset[6]=0x%x offset[7]=0x%x\n", + "offset[4]=0x%x offset[5]=0x%x offset[6]=0x%x offset[7]=0x%x\n" + "offset[8]=0x%x offset[9]=0x%x offset[10]=0x%x offset[11]=0x%x\n" + "offset[12]=0x%x offset[13]=0x%x offset[14]=0x%x offset[15]=0x%x\n" + "offset[16]=0x%x offset[17]=0x%x offset[18]=0x%x offset[19]=0x%x\n" + "offset[20]=0x%x offset[21]=0x%x offset[22]=0x%x offset[23]=0x%x\n" + "offset[24]=0x%x offset[25]=0x%x offset[26]=0x%x offset[27]=0x%x\n" + "offset[28]=0x%x offset[29]=0x%x offset[30]=0x%x offset[31]=0x%x\n", __func__, - slot_mapping->offset[0], - slot_mapping->offset[1], - slot_mapping->offset[2], - slot_mapping->offset[3], - slot_mapping->offset[4], - slot_mapping->offset[5], - slot_mapping->offset[6], - slot_mapping->offset[7]); + slot_mapping_v2->offset[0], + slot_mapping_v2->offset[1], + slot_mapping_v2->offset[2], + slot_mapping_v2->offset[3], + slot_mapping_v2->offset[4], + slot_mapping_v2->offset[5], + slot_mapping_v2->offset[6], + slot_mapping_v2->offset[7], + slot_mapping_v2->offset[8], + slot_mapping_v2->offset[9], + slot_mapping_v2->offset[10], + slot_mapping_v2->offset[11], + slot_mapping_v2->offset[12], + slot_mapping_v2->offset[13], + slot_mapping_v2->offset[14], + slot_mapping_v2->offset[15], + slot_mapping_v2->offset[16], + slot_mapping_v2->offset[17], + slot_mapping_v2->offset[18], + slot_mapping_v2->offset[19], + slot_mapping_v2->offset[20], + slot_mapping_v2->offset[21], + slot_mapping_v2->offset[22], + slot_mapping_v2->offset[23], + slot_mapping_v2->offset[24], + slot_mapping_v2->offset[25], + slot_mapping_v2->offset[26], + slot_mapping_v2->offset[27], + slot_mapping_v2->offset[28], + slot_mapping_v2->offset[29], + slot_mapping_v2->offset[30], + slot_mapping_v2->offset[31]); + } else { + /* + * update slot mapping config param + * NOTE: channels/rate/bitwidth are per stream property + */ + slot_mapping->bitwidth = dai_data->bitwidth; + pr_debug("%s: SLOT MAPPING:\n" + "num_channel=%d bitwidth=%d data_align=0x%x\n", + __func__, + slot_mapping->num_channel, + slot_mapping->bitwidth, + slot_mapping->data_align_type); + pr_debug("%s: SLOT MAPPING:\n" + "offset[0]=0x%x offset[1]=0x%x offset[2]=0x%x offset[3]=0x%x\n" + "offset[4]=0x%x offset[5]=0x%x offset[6]=0x%x offset[7]=0x%x\n", + __func__, + slot_mapping->offset[0], + slot_mapping->offset[1], + slot_mapping->offset[2], + slot_mapping->offset[3], + slot_mapping->offset[4], + slot_mapping->offset[5], + slot_mapping->offset[6], + slot_mapping->offset[7]); + } /* * update custom header config param * NOTE: channels/rate/bitwidth are per playback stream property. @@ -10922,6 +11037,8 @@ static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev) /* TDM SLOT MAPPING CFG -- set default */ dai_data->port_cfg.slot_mapping.minor_version = AFE_API_VERSION_SLOT_MAPPING_CONFIG; + dai_data->port_cfg.slot_mapping_v2.minor_version = + AFE_API_VERSION_SLOT_MAPPING_CONFIG_V2; /* CUSTOM TDM HEADER CFG */ custom_tdm_header = &dai_data->port_cfg.custom_tdm_header; diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 29bf67fdc0d2..f23c1a0f5c40 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2684,6 +2684,39 @@ static int adm_arrange_mch_map_v8( ep_payload->dev_channel_mapping[13] = PCM_CHANNEL_FRC; ep_payload->dev_channel_mapping[14] = PCM_CHANNEL_RLC; ep_payload->dev_channel_mapping[15] = PCM_CHANNEL_RRC; + } else if (channel_mode == 32) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC; + ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS; + ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB; + ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB; + ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_CS; + ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TS; + ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_CVH; + ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_MS; + ep_payload->dev_channel_mapping[12] = PCM_CHANNEL_FLC; + ep_payload->dev_channel_mapping[13] = PCM_CHANNEL_FRC; + ep_payload->dev_channel_mapping[14] = PCM_CHANNEL_RLC; + ep_payload->dev_channel_mapping[15] = PCM_CHANNEL_RRC; + ep_payload->dev_channel_mapping[16] = PCM_CHANNEL_LFE2; + ep_payload->dev_channel_mapping[17] = PCM_CHANNEL_SL; + ep_payload->dev_channel_mapping[18] = PCM_CHANNEL_SR; + ep_payload->dev_channel_mapping[19] = PCM_CHANNEL_TFL; + ep_payload->dev_channel_mapping[20] = PCM_CHANNEL_TFR; + ep_payload->dev_channel_mapping[21] = PCM_CHANNEL_TC; + ep_payload->dev_channel_mapping[22] = PCM_CHANNEL_TBL; + ep_payload->dev_channel_mapping[23] = PCM_CHANNEL_TBR; + ep_payload->dev_channel_mapping[24] = PCM_CHANNEL_TSL; + ep_payload->dev_channel_mapping[25] = PCM_CHANNEL_TSR; + ep_payload->dev_channel_mapping[26] = PCM_CHANNEL_TBC; + ep_payload->dev_channel_mapping[27] = PCM_CHANNEL_BFC; + ep_payload->dev_channel_mapping[28] = PCM_CHANNEL_BFL; + ep_payload->dev_channel_mapping[29] = PCM_CHANNEL_BFR; + ep_payload->dev_channel_mapping[30] = PCM_CHANNEL_LW; + ep_payload->dev_channel_mapping[31] = PCM_CHANNEL_RW; } else { pr_err("%s: invalid num_chan %d\n", __func__, channel_mode); @@ -2783,6 +2816,39 @@ static int adm_arrange_mch_ep2_map_v8( ep_payload->dev_channel_mapping[13] = PCM_CHANNEL_FRC; ep_payload->dev_channel_mapping[14] = PCM_CHANNEL_RLC; ep_payload->dev_channel_mapping[15] = PCM_CHANNEL_RRC; + } else if (channel_mode == 32) { + ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL; + ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR; + ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE; + ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC; + ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS; + ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS; + ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB; + ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB; + ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_CS; + ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TS; + ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_CVH; + ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_MS; + ep_payload->dev_channel_mapping[12] = PCM_CHANNEL_FLC; + ep_payload->dev_channel_mapping[13] = PCM_CHANNEL_FRC; + ep_payload->dev_channel_mapping[14] = PCM_CHANNEL_RLC; + ep_payload->dev_channel_mapping[15] = PCM_CHANNEL_RRC; + ep_payload->dev_channel_mapping[16] = PCM_CHANNEL_LFE2; + ep_payload->dev_channel_mapping[17] = PCM_CHANNEL_SL; + ep_payload->dev_channel_mapping[18] = PCM_CHANNEL_SR; + ep_payload->dev_channel_mapping[19] = PCM_CHANNEL_TFL; + ep_payload->dev_channel_mapping[20] = PCM_CHANNEL_TFR; + ep_payload->dev_channel_mapping[21] = PCM_CHANNEL_TC; + ep_payload->dev_channel_mapping[22] = PCM_CHANNEL_TBL; + ep_payload->dev_channel_mapping[23] = PCM_CHANNEL_TBR; + ep_payload->dev_channel_mapping[24] = PCM_CHANNEL_TSL; + ep_payload->dev_channel_mapping[25] = PCM_CHANNEL_TSR; + ep_payload->dev_channel_mapping[26] = PCM_CHANNEL_TBC; + ep_payload->dev_channel_mapping[27] = PCM_CHANNEL_BFC; + ep_payload->dev_channel_mapping[28] = PCM_CHANNEL_BFL; + ep_payload->dev_channel_mapping[29] = PCM_CHANNEL_BFR; + ep_payload->dev_channel_mapping[30] = PCM_CHANNEL_LW; + ep_payload->dev_channel_mapping[31] = PCM_CHANNEL_RW; } else { pr_err("%s: invalid num_chan %d\n", __func__, channel_mode); diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 6f4aece5fba9..da87fb87be75 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -3364,6 +3364,36 @@ int afe_send_slot_mapping_cfg( return ret; } +int afe_send_slot_mapping_cfg_v2( + struct afe_param_id_slot_mapping_cfg_v2 *slot_mapping_cfg, + u16 port_id) +{ + struct param_hdr_v3 param_hdr; + int ret = 0; + + if (!slot_mapping_cfg) { + pr_err("%s: Error, no configuration data\n", __func__); + return -EINVAL; + } + + pr_debug("%s: port id: 0x%x\n", __func__, port_id); + + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_TDM; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG; + param_hdr.param_size = sizeof(struct afe_param_id_slot_mapping_cfg_v2); + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) slot_mapping_cfg); + if (ret < 0) + pr_err("%s: AFE send slot mapping for port 0x%x failed ret = %d\n", + __func__, port_id, ret); + return ret; +} + int afe_send_custom_tdm_header_cfg( struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header_cfg, u16 port_id) @@ -3503,8 +3533,15 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, goto fail_cmd; } - ret = afe_send_slot_mapping_cfg(&tdm_port->slot_mapping, - port_id); + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V3) + ret = afe_send_slot_mapping_cfg_v2( + &tdm_port->slot_mapping_v2, port_id); + else + ret = afe_send_slot_mapping_cfg( + &tdm_port->slot_mapping, + port_id); + if (ret < 0) { pr_err("%s: afe send failed %d\n", __func__, ret); goto fail_cmd; diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 79ac3c947fac..7934d2a1e086 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -5766,6 +5766,39 @@ int q6asm_map_channels(u8 *channel_mapping, uint32_t channels, lchannel_mapping[13] = PCM_CHANNEL_FRC; lchannel_mapping[14] = PCM_CHANNEL_RLC; lchannel_mapping[15] = PCM_CHANNEL_RRC; + } else if (channels == 32) { + lchannel_mapping[0] = PCM_CHANNEL_FL; + lchannel_mapping[1] = PCM_CHANNEL_FR; + lchannel_mapping[2] = PCM_CHANNEL_LFE; + lchannel_mapping[3] = PCM_CHANNEL_FC; + lchannel_mapping[4] = PCM_CHANNEL_LS; + lchannel_mapping[5] = PCM_CHANNEL_RS; + lchannel_mapping[6] = PCM_CHANNEL_LB; + lchannel_mapping[7] = PCM_CHANNEL_RB; + lchannel_mapping[8] = PCM_CHANNEL_CS; + lchannel_mapping[9] = PCM_CHANNEL_TS; + lchannel_mapping[10] = PCM_CHANNEL_CVH; + lchannel_mapping[11] = PCM_CHANNEL_MS; + lchannel_mapping[12] = PCM_CHANNEL_FLC; + lchannel_mapping[13] = PCM_CHANNEL_FRC; + lchannel_mapping[14] = PCM_CHANNEL_RLC; + lchannel_mapping[15] = PCM_CHANNEL_RRC; + lchannel_mapping[16] = PCM_CHANNEL_LFE2; + lchannel_mapping[17] = PCM_CHANNEL_SL; + lchannel_mapping[18] = PCM_CHANNEL_SR; + lchannel_mapping[19] = PCM_CHANNEL_TFL; + lchannel_mapping[20] = PCM_CHANNEL_TFR; + lchannel_mapping[21] = PCM_CHANNEL_TC; + lchannel_mapping[22] = PCM_CHANNEL_TBL; + lchannel_mapping[23] = PCM_CHANNEL_TBR; + lchannel_mapping[24] = PCM_CHANNEL_TSL; + lchannel_mapping[25] = PCM_CHANNEL_TSR; + lchannel_mapping[26] = PCM_CHANNEL_TBC; + lchannel_mapping[27] = PCM_CHANNEL_BFC; + lchannel_mapping[28] = PCM_CHANNEL_BFL; + lchannel_mapping[29] = PCM_CHANNEL_BFR; + lchannel_mapping[30] = PCM_CHANNEL_LW; + lchannel_mapping[31] = PCM_CHANNEL_RW; } else { pr_err("%s: ERROR.unsupported num_ch = %u\n", __func__, channels); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 99b9a4560652..cfac0659b5a3 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -3191,6 +3191,8 @@ struct afe_param_id_internal_bt_fm_cfg { #define AFE_PORT_MAX_AUDIO_CHAN_CNT 0x8 +#define AFE_PORT_MAX_AUDIO_CHAN_CNT_V2 0x20 + /* Payload of the #AFE_PORT_CMD_SLIMBUS_CONFIG command's SLIMbus * port configuration parameter. */ @@ -3649,6 +3651,10 @@ struct afe_param_id_tdm_cfg { */ #define AFE_API_VERSION_SLOT_MAPPING_CONFIG 0x1 +/** Version information used to handle future additions to slot mapping +* configuration support 32 channels. +*/ +#define AFE_API_VERSION_SLOT_MAPPING_CONFIG_V2 0x2 /* Data align type */ #define AFE_SLOT_MAPPING_DATA_ALIGN_MSB 0 #define AFE_SLOT_MAPPING_DATA_ALIGN_LSB 1 @@ -3698,9 +3704,52 @@ struct afe_param_id_slot_mapping_cfg { */ } __packed; -/* ID of the parameter used by #AFE_MODULE_TDM to configure - * the customer TDM header. #AFE_PORT_CMD_SET_PARAM can use this parameter ID. - */ +/* Payload of the AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG_V2 +* command's TDM configuration parameter. +*/ +struct afe_param_id_slot_mapping_cfg_v2 { + u32 minor_version; + /**< Minor version used for tracking TDM slot configuration. + * @values #AFE_API_VERSION_TDM_SLOT_CONFIG + */ + + u16 num_channel; + /**< number of channel of the audio sample. + * @values 1, 2, 4, 6, 8, 16, 32 @tablebulletend + */ + + u16 bitwidth; + /**< Slot bit width for each channel + * @values 16, 24, 32 + */ + + u32 data_align_type; + /**< indicate how data packed from slot_offset for 32 slot bit width + * in case of sample bit width is 24. + * @values + * #AFE_SLOT_MAPPING_DATA_ALIGN_MSB + * #AFE_SLOT_MAPPING_DATA_ALIGN_LSB + */ + + u16 offset[AFE_PORT_MAX_AUDIO_CHAN_CNT_V2]; + /**< Array of the slot mapping start offset in bytes for this frame. + * The bytes is counted from 0. The 0 is mapped to the 1st byte + * in or out of the digital serial data line this sub-frame belong to. + * slot_offset[] setting is per-channel based. + * The max num of channel supported is 8. + * The valid offset value must always be continuly placed in + * from index 0. + * Set offset as AFE_SLOT_MAPPING_OFFSET_INVALID for not used arrays. + * If "slot_bitwidth_per_channel" is 32 and "sample_bitwidth" is 24, + * "data_align_type" is used to indicate how 24 bit sample data in + * aligning with 32 bit slot width per-channel. + * @values, in byte + */ +} __packed; + +/** ID of the parameter used by #AFE_MODULE_TDM to configure + the customer TDM header. #AFE_PORT_CMD_SET_PARAM can use this parameter ID. +*/ #define AFE_PARAM_ID_CUSTOM_TDM_HEADER_CONFIG 0x00010298 /* Version information used to handle future additions to custom TDM header @@ -3768,6 +3817,7 @@ struct afe_param_id_custom_tdm_header_cfg { struct afe_tdm_port_config { struct afe_param_id_tdm_cfg tdm; struct afe_param_id_slot_mapping_cfg slot_mapping; + struct afe_param_id_slot_mapping_cfg_v2 slot_mapping_v2; struct afe_param_id_custom_tdm_header_cfg custom_tdm_header; } __packed; -- GitLab From c8940293bfc99c77f302af2fedc866e93fa15785 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Thu, 14 Mar 2019 10:26:41 -0700 Subject: [PATCH 1095/1645] ASoC: msm: use snd event fwk for ssr on auto platform Switch to use SND event FWK for SSR handling instead of audio notifier on automotive platform. Change-Id: I8d0b1ac8f09417a8b33a8e8141f7ae06e1195f54 Signed-off-by: Derek Chen --- Android.mk | 5 +- asoc/sa8155.c | 132 ++++++++++++++++++++++++---------------- config/gvmauto.conf | 1 + config/gvmautoconf.h | 1 + config/sa8155auto.conf | 1 + config/sa8155autoconf.h | 1 + soc/Android.mk | 10 ++- soc/Kbuild | 17 +++++- 8 files changed, 106 insertions(+), 62 deletions(-) diff --git a/Android.mk b/Android.mk index 835c670b73ab..722c3ce3b5a7 100644 --- a/Android.mk +++ b/Android.mk @@ -17,6 +17,7 @@ include $(MY_LOCAL_PATH)/include/uapi/Android.mk include $(MY_LOCAL_PATH)/ipc/Android.mk include $(MY_LOCAL_PATH)/dsp/Android.mk include $(MY_LOCAL_PATH)/dsp/codecs/Android.mk +include $(MY_LOCAL_PATH)/soc/Android.mk include $(MY_LOCAL_PATH)/asoc/Android.mk include $(MY_LOCAL_PATH)/asoc/codecs/Android.mk endif @@ -30,10 +31,6 @@ include $(MY_LOCAL_PATH)/soc/Android.mk endif endif -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) -include $(MY_LOCAL_PATH)/soc/Android.mk -endif - ifeq ($(call is-board-platform-in-list,msmnile),true) ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/aqt1000/Module.symvers) diff --git a/asoc/sa8155.c b/asoc/sa8155.c index 26b744b9a891..b655572f04b7 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -693,9 +694,6 @@ static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); -static bool is_initial_boot = true; -static struct platform_device *spdev; - static struct afe_clk_set mi2s_clk[MI2S_MAX] = { { AFE_API_VERSION_I2S_CONFIG, @@ -7298,6 +7296,78 @@ static void msm_i2s_auxpcm_deinit(struct platform_device *pdev) pdata->mi2s_intf_conf[count].msm_is_mi2s_master = 0; } } + +static int sa8155_ssr_enable(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct snd_soc_card *card = platform_get_drvdata(pdev); + int ret = 0; + + if (!card) { + dev_err(dev, "%s: card is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + dev_dbg(dev, "%s: setting snd_card to ONLINE\n", __func__); + snd_soc_card_change_online_state(card, 1); + +err: + return ret; +} + +static void sa8155_ssr_disable(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct snd_soc_card *card = platform_get_drvdata(pdev); + + if (!card) { + dev_err(dev, "%s: card is NULL\n", __func__); + return; + } + + dev_dbg(dev, "%s: setting snd_card to OFFLINE\n", __func__); + snd_soc_card_change_online_state(card, 0); +} + +static const struct snd_event_ops sa8155_ssr_ops = { + .enable = sa8155_ssr_enable, + .disable = sa8155_ssr_disable, +}; + +static int msm_audio_ssr_compare(struct device *dev, void *data) +{ + struct device_node *node = data; + + dev_dbg(dev, "%s: dev->of_node = 0x%p, node = 0x%p\n", + __func__, dev->of_node, node); + return (dev->of_node && dev->of_node == node); +} + +static int msm_audio_ssr_register(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct snd_event_clients *ssr_clients = NULL; + struct device_node *node; + int ret; + int i; + + for (i = 0; ; i++) { + node = of_parse_phandle(np, "qcom,msm_audio_ssr_devs", i); + if (!node) + break; + snd_event_mstr_add_client(&ssr_clients, + msm_audio_ssr_compare, node); + } + + ret = snd_event_master_register(dev, &sa8155_ssr_ops, + ssr_clients, NULL); + if (!ret) + snd_event_notify(dev, SND_EVENT_UP); + + return ret; +} + static int msm_asoc_machine_probe(struct platform_device *pdev) { struct snd_soc_card *card; @@ -7364,7 +7434,6 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) goto err; } dev_info(&pdev->dev, "Sound card %s registered\n", card->name); - spdev = pdev; /* Parse pinctrl info from devicetree */ ret = msm_get_pinctrl(pdev); @@ -7379,6 +7448,11 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) msm_i2s_auxpcm_init(pdev); + ret = msm_audio_ssr_register(&pdev->dev); + if (ret) + pr_err("%s: Registration with SND event FWK failed ret = %d\n", + __func__, ret); + return 0; err: msm_release_pinctrl(pdev); @@ -7407,58 +7481,9 @@ static struct platform_driver sa8155_asoc_machine_driver = { .remove = msm_asoc_machine_remove, }; -static int sa8155_notifier_service_cb(struct notifier_block *this, - unsigned long opcode, void *ptr) -{ - struct snd_soc_card *card = NULL; - - pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); - - switch (opcode) { - case AUDIO_NOTIFIER_SERVICE_DOWN: - if (!spdev) - return -EINVAL; - card = platform_get_drvdata(spdev); - if (card == NULL){ - pr_err("%s: card is NULL\n",__func__); - return -EINVAL; - } else { - pr_debug("%s: setting snd_card to OFFLINE\n", __func__); - snd_soc_card_change_online_state(card, 0); - } - break; - case AUDIO_NOTIFIER_SERVICE_UP: - if (is_initial_boot) { - is_initial_boot = false; - break; - } - if (!spdev) - return -EINVAL; - card = platform_get_drvdata(spdev); - if (card == NULL){ - pr_err("%s: card is NULL\n",__func__); - return -EINVAL; - } else { - pr_debug("%s: setting snd_card to ONLINE\n", __func__); - snd_soc_card_change_online_state(card, 1); - } - break; - default: - break; - } - return NOTIFY_OK; -} - -static struct notifier_block service_nb = { - .notifier_call = sa8155_notifier_service_cb, - .priority = -INT_MAX, -}; - int __init sa8155_init(void) { pr_debug("%s\n", __func__); - audio_notifier_register("sa8155", AUDIO_NOTIFIER_ADSP_DOMAIN, - &service_nb); return platform_driver_register(&sa8155_asoc_machine_driver); } @@ -7466,7 +7491,6 @@ void sa8155_exit(void) { pr_debug("%s\n", __func__); platform_driver_unregister(&sa8155_asoc_machine_driver); - audio_notifier_deregister("sa8155"); } module_init(sa8155_init); diff --git a/config/gvmauto.conf b/config/gvmauto.conf index 9af768597696..35b70b9f5e46 100644 --- a/config/gvmauto.conf +++ b/config/gvmauto.conf @@ -12,3 +12,4 @@ CONFIG_DOLBY_LICENSE=m CONFIG_SND_SOC_MSM_STUB=m CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m CONFIG_MSM_QDSP6V2_CODECS=m +CONFIG_SND_EVENT=m diff --git a/config/gvmautoconf.h b/config/gvmautoconf.h index 0826a9ee9f9c..84a8f1df7c6f 100644 --- a/config/gvmautoconf.h +++ b/config/gvmautoconf.h @@ -24,3 +24,4 @@ #define CONFIG_SND_SOC_MSM_STUB 1 #define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 #define CONFIG_MSM_QDSP6V2_CODECS 1 +#define CONFIG_SND_EVENT 1 diff --git a/config/sa8155auto.conf b/config/sa8155auto.conf index e551f77f19dd..bf5b9cdae15a 100644 --- a/config/sa8155auto.conf +++ b/config/sa8155auto.conf @@ -12,3 +12,4 @@ CONFIG_DOLBY_LICENSE=m CONFIG_SND_SOC_MSM_STUB=m CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m CONFIG_MSM_QDSP6V2_CODECS=m +CONFIG_SND_EVENT=m diff --git a/config/sa8155autoconf.h b/config/sa8155autoconf.h index 3f9eda2c910e..167451639a1e 100644 --- a/config/sa8155autoconf.h +++ b/config/sa8155autoconf.h @@ -16,3 +16,4 @@ #define CONFIG_SND_SOC_MSM_STUB 1 #define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 #define CONFIG_MSM_QDSP6V2_CODECS 1 +#define CONFIG_SND_EVENT 1 diff --git a/soc/Android.mk b/soc/Android.mk index 8698a56a204b..969c38f63346 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -4,8 +4,12 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) +AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m +else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif +endif ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m @@ -68,6 +72,7 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk endif ########################################################### +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_swr.ko LOCAL_MODULE_KBUILD_NAME := swr_dlkm.ko @@ -83,8 +88,10 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk +endif ########################################################### -ifeq ($(call is-board-platform-in-list, $(MSMSTEPPE) kona lito),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) kona lito),true) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_snd_event.ko LOCAL_MODULE_KBUILD_NAME := snd_event_dlkm.ko @@ -93,6 +100,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk endif +endif ########################################################### endif # DLKM check diff --git a/soc/Kbuild b/soc/Kbuild index a1944a15fdec..3e7af12214c7 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -15,9 +15,15 @@ endif ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SM8150), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + ifdef CONFIG_SND_SOC_SA8155 + include $(AUDIO_ROOT)/config/sa8155auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h + else + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif endif ifeq ($(CONFIG_ARCH_KONA), y) include $(AUDIO_ROOT)/config/konaauto.conf @@ -48,6 +54,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h endif + ifeq ($(CONFIG_QTI_GVM), y) + include $(AUDIO_ROOT)/config/gvmauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h + endif endif # As per target team, build is done as follows: -- GitLab From 300664fe834af0c1108378c6797b5091155afd84 Mon Sep 17 00:00:00 2001 From: Erin Yan Date: Tue, 14 May 2019 10:42:31 +0800 Subject: [PATCH 1096/1645] asoc: sa6155: support SSR handling for snd card status Use SND event FWK for SSR handling. Change snd card status upon SERVICE_DOWN and SERVICE_UP callback when adsp subsystem restart happen. Change-Id: I333e2343e0670f53d40764ce86094c73c836c5c4 Signed-off-by: Erin Yan --- asoc/sa6155.c | 133 +++++++++++++++++++++++----------------- config/sa6155auto.conf | 1 + config/sa6155autoconf.h | 1 + soc/Android.mk | 10 ++- soc/Kbuild | 12 +++- 5 files changed, 98 insertions(+), 59 deletions(-) diff --git a/asoc/sa6155.c b/asoc/sa6155.c index 73217fa3f5ee..8b1df6610a39 100644 --- a/asoc/sa6155.c +++ b/asoc/sa6155.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -697,8 +698,6 @@ static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); -static bool is_initial_boot = true; - static struct afe_clk_set mi2s_clk[MI2S_MAX] = { { AFE_API_VERSION_I2S_CONFIG, @@ -6985,6 +6984,78 @@ static void msm_i2s_auxpcm_deinit(void) mi2s_intf_conf[count].msm_is_mi2s_master = 0; } } + +static int sa6155_ssr_enable(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct snd_soc_card *card = platform_get_drvdata(pdev); + int ret = 0; + + if (!card) { + dev_err(dev, "%s: card is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + dev_info(dev, "%s: setting snd_card to ONLINE\n", __func__); + snd_soc_card_change_online_state(card, 1); + +err: + return ret; +} + +static void sa6155_ssr_disable(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct snd_soc_card *card = platform_get_drvdata(pdev); + + if (!card) { + dev_err(dev, "%s: card is NULL\n", __func__); + return; + } + + dev_info(dev, "%s: setting snd_card to OFFLINE\n", __func__); + snd_soc_card_change_online_state(card, 0); +} + +static const struct snd_event_ops sa6155_ssr_ops = { + .enable = sa6155_ssr_enable, + .disable = sa6155_ssr_disable, +}; + +static int msm_audio_ssr_compare(struct device *dev, void *data) +{ + struct device_node *node = data; + + dev_dbg(dev, "%s: dev->of_node = 0x%p, node = 0x%p\n", + __func__, dev->of_node, node); + return (dev->of_node && dev->of_node == node); +} + +static int msm_audio_ssr_register(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct snd_event_clients *ssr_clients = NULL; + struct device_node *node; + int ret; + int i; + + for (i = 0; ; i++) { + node = of_parse_phandle(np, "qcom,msm_audio_ssr_devs", i); + if (!node) + break; + snd_event_mstr_add_client(&ssr_clients, + msm_audio_ssr_compare, node); + } + + ret = snd_event_master_register(dev, &sa6155_ssr_ops, + ssr_clients, NULL); + if (!ret) + snd_event_notify(dev, SND_EVENT_UP); + + return ret; +} + static int msm_asoc_machine_probe(struct platform_device *pdev) { struct snd_soc_card *card; @@ -7065,6 +7136,11 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) msm_i2s_auxpcm_init(pdev); + ret = msm_audio_ssr_register(&pdev->dev); + if (ret) + pr_err("%s: Registration with SND event FWK failed ret = %d\n", + __func__, ret); + return 0; err: msm_release_pinctrl(pdev); @@ -7091,61 +7167,9 @@ static struct platform_driver sa6155_asoc_machine_driver = { .remove = msm_asoc_machine_remove, }; -static int dummy_asoc_machine_probe(struct platform_device *pdev) -{ - return 0; -} - -static int dummy_asoc_machine_remove(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_device sa6155_dummy_asoc_machine_device = { - .name = "sa6155-asoc-snd-dummy", -}; - -static struct platform_driver sa6155_dummy_asoc_machine_driver = { - .driver = { - .name = "sa6155-asoc-snd-dummy", - .owner = THIS_MODULE, - }, - .probe = dummy_asoc_machine_probe, - .remove = dummy_asoc_machine_remove, -}; - -static int sa6155_notifier_service_cb(struct notifier_block *this, - unsigned long opcode, void *ptr) -{ - pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); - - switch (opcode) { - case AUDIO_NOTIFIER_SERVICE_DOWN: - break; - case AUDIO_NOTIFIER_SERVICE_UP: - if (is_initial_boot) { - platform_driver_register(&sa6155_dummy_asoc_machine_driver); - platform_device_register(&sa6155_dummy_asoc_machine_device); - is_initial_boot = false; - } - break; - default: - break; - } - - return NOTIFY_OK; -} - -static struct notifier_block service_nb = { - .notifier_call = sa6155_notifier_service_cb, - .priority = -INT_MAX, -}; - int __init sa6155_init(void) { pr_debug("%s\n", __func__); - audio_notifier_register("sa6155", AUDIO_NOTIFIER_ADSP_DOMAIN, - &service_nb); return platform_driver_register(&sa6155_asoc_machine_driver); } @@ -7153,7 +7177,6 @@ void sa6155_exit(void) { pr_debug("%s\n", __func__); platform_driver_unregister(&sa6155_asoc_machine_driver); - audio_notifier_deregister("sa6155"); } module_init(sa6155_init); diff --git a/config/sa6155auto.conf b/config/sa6155auto.conf index 85190d1ec1bf..4dbbb0b35f70 100644 --- a/config/sa6155auto.conf +++ b/config/sa6155auto.conf @@ -14,3 +14,4 @@ CONFIG_MSM_QDSP6V2_CODECS=m CONFIG_SND_SOC_QDSP6V2=m CONFIG_SND_SOC_SA6155=m CONFIG_SOUNDWIRE_MSTR_CTRL=m +CONFIG_SND_EVENT=m diff --git a/config/sa6155autoconf.h b/config/sa6155autoconf.h index 312fbd0f91b7..e5c9b3353b62 100644 --- a/config/sa6155autoconf.h +++ b/config/sa6155autoconf.h @@ -26,3 +26,4 @@ #define CONFIG_SND_SOC_QDSP6V2 1 #define CONFIG_SND_SOC_SA6155 1 #define CONFIG_SOUNDWIRE_MSTR_CTRL 1 +#define CONFIG_SND_EVENT 1 diff --git a/soc/Android.mk b/soc/Android.mk index 969c38f63346..58d325477c3b 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -12,8 +12,12 @@ endif endif ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), sm6150_au)) +AUDIO_SELECT := CONFIG_SND_SOC_SA6155=m +else AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif +endif ifeq ($(call is-board-platform,kona),true) AUDIO_SELECT := CONFIG_SND_SOC_KONA=m @@ -53,6 +57,7 @@ KBUILD_OPTIONS += $(AUDIO_SELECT) ########################################################### ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona lito),true) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), sm6150_au)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_lpi.ko LOCAL_MODULE_KBUILD_NAME := pinctrl_lpi_dlkm.ko @@ -61,8 +66,10 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk endif +endif ########################################################### ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona), true) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), sm6150_au)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_wcd.ko LOCAL_MODULE_KBUILD_NAME := pinctrl_wcd_dlkm.ko @@ -71,8 +78,9 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk endif +endif ########################################################### -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq sm6150_au)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_swr.ko LOCAL_MODULE_KBUILD_NAME := swr_dlkm.ko diff --git a/soc/Kbuild b/soc/Kbuild index 3e7af12214c7..0daf3cd7220d 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -35,9 +35,15 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_SM6150), y) - include $(AUDIO_ROOT)/config/sm6150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + ifdef CONFIG_SND_SOC_SA6155 + include $(AUDIO_ROOT)/config/sa6155auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sa6155autoconf.h + else + include $(AUDIO_ROOT)/config/sm6150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h + endif endif ifeq ($(CONFIG_ARCH_TRINKET), y) include $(AUDIO_ROOT)/config/sm6150auto.conf -- GitLab From a79ba90bd8a2647d4a3d62188a5aa6cf6fb5b5e2 Mon Sep 17 00:00:00 2001 From: Xianbin Zhu Date: Sat, 2 Mar 2019 18:41:10 +0800 Subject: [PATCH 1097/1645] ASoC: msm: add boot marker for sa8155 automotive add marker in audio driver for start-up time measurement. Change-Id: Ibb63f6b40651646a8f16ef0cf391899f37e67eaf Signed-off-by: Xianbin Zhu --- asoc/sa8155.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/asoc/sa8155.c b/asoc/sa8155.c index b655572f04b7..54d65a31fbcd 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "device_event.h" #include "msm-pcm-routing-v2.h" @@ -7374,6 +7375,12 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) struct msm_asoc_mach_data *pdata; int ret; enum apr_subsys_state q6_state; + static int first_probe = 1; + + if (first_probe) { + place_marker("M - DRIVER Audio Init"); + first_probe = 0; + } if (!pdev->dev.of_node) { dev_err(&pdev->dev, "No platform supplied from device tree\n"); @@ -7453,6 +7460,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) pr_err("%s: Registration with SND event FWK failed ret = %d\n", __func__, ret); + place_marker("M - DRIVER Audio Ready"); return 0; err: msm_release_pinctrl(pdev); -- GitLab From f691f80fe89cb0663a78b95fda9f453e92c8a45c Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Tue, 9 Apr 2019 16:36:44 -0700 Subject: [PATCH 1098/1645] ASoC: msm: print dev info msg when snd card status change Print device info message when sound card status change. Change-Id: I0be73755f1ec0f71abf1fd5f99f129998ef79806 Signed-off-by: Derek Chen --- asoc/sa8155.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/sa8155.c b/asoc/sa8155.c index b655572f04b7..d239cb9e0683 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -7309,7 +7309,7 @@ static int sa8155_ssr_enable(struct device *dev, void *data) goto err; } - dev_dbg(dev, "%s: setting snd_card to ONLINE\n", __func__); + dev_info(dev, "%s: setting snd_card to ONLINE\n", __func__); snd_soc_card_change_online_state(card, 1); err: @@ -7326,7 +7326,7 @@ static void sa8155_ssr_disable(struct device *dev, void *data) return; } - dev_dbg(dev, "%s: setting snd_card to OFFLINE\n", __func__); + dev_info(dev, "%s: setting snd_card to OFFLINE\n", __func__); snd_soc_card_change_online_state(card, 0); } -- GitLab From 6938b83aeeb3556cb8d897eab05ce82ee735ae91 Mon Sep 17 00:00:00 2001 From: Cong Tang Date: Thu, 18 Apr 2019 09:18:29 +0800 Subject: [PATCH 1099/1645] ASoC: msm: fix apr_dlkm load error for sa8155 lv fix apr_dlkm module loading failure issue due to missing event module. Change-Id: Iafd71de99b47ce2e4afa4f52bd710127c028f924 Signed-off-by: Cong Tang --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index 55f77878933b..0a0f0035c2b8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -42,6 +42,7 @@ obj-m := ipc/ obj-m += dsp/ obj-m += asoc/ obj-m += asoc/codecs/ +obj-m += soc/ KBUILD_OPTIONS += CONFIG_SND_SOC_SA8155=m endif -- GitLab From 4f4ebc9228e227181733dc45cb85df7945bf4e6c Mon Sep 17 00:00:00 2001 From: King Tam Date: Tue, 28 May 2019 11:49:56 -0400 Subject: [PATCH 1100/1645] dsp: ion_vm: adapt to new interfaces Add new interfaces stub functions for Dolby security change, since ion_vm share the same header file with ion. Change-Id: Iaac5931a9c97eafe1a8cc5980ac70b9a62288faa Signed-off-by: King Tam --- dsp/msm_audio_ion_vm.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/dsp/msm_audio_ion_vm.c b/dsp/msm_audio_ion_vm.c index fc6039a6bee5..f9635b3328d1 100644 --- a/dsp/msm_audio_ion_vm.c +++ b/dsp/msm_audio_ion_vm.c @@ -647,6 +647,31 @@ int msm_audio_ion_alloc(void **handle, size_t bufsz, } EXPORT_SYMBOL(msm_audio_ion_alloc); +int msm_audio_ion_phys_free(void *handle, + dma_addr_t *paddr, + size_t *pa_len, + u8 assign_type, + int id, + int key) +{ + handle = NULL; + return 0; +} +EXPORT_SYMBOL(msm_audio_ion_phys_free); + +int msm_audio_ion_phys_assign(void **handle, int fd, + dma_addr_t *paddr, size_t *pa_len, u8 assign_type, int id) +{ + *handle = NULL; + return 0; +} +EXPORT_SYMBOL(msm_audio_ion_phys_assign); + +bool msm_audio_is_hypervisor_supported(void) +{ + return false; +} +EXPORT_SYMBOL(msm_audio_is_hypervisor_supported); /** * msm_audio_ion_import- * Import ION buffer with given file descriptor -- GitLab From 2479acceb05a33e10fdf8d9546911ac21ee6995c Mon Sep 17 00:00:00 2001 From: Guodong Hu Date: Fri, 24 May 2019 10:15:33 +0800 Subject: [PATCH 1101/1645] audiodlkm: modify audiodlkm to parse amixer command correctly 0xFFFFFFFF will be parsed as -1. But as the fourth parameter of SOC_SINGLE_MULTI_EXT(), it denotes 'xmax' and should be larger than the sixth parameter. 0x7FFFFFFF works fine in this function. Change-Id: Ie20437f5e1993dac337f52026343383a98db7f5e Signed-off-by: Guodong Hu --- asoc/msm-pcm-routing-v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index f1afd538965d..bbab0e09af3b 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -20773,7 +20773,7 @@ static int msm_routing_put_app_type_gain_control(struct snd_kcontrol *kcontrol, static const struct snd_kcontrol_new app_type_cfg_controls[] = { SOC_SINGLE_MULTI_EXT("App Type Config", SND_SOC_NOPM, 0, - 0xFFFFFFFF, 0, 128, msm_routing_get_app_type_cfg_control, + 0x7FFFFFFF, 0, 128, msm_routing_get_app_type_cfg_control, msm_routing_put_app_type_cfg_control), SOC_SINGLE_MULTI_EXT("App Type Gain", SND_SOC_NOPM, 0, 0x2000, 0, 4, NULL, msm_routing_put_app_type_gain_control) -- GitLab From 0150b83ef6c09c81e663f881ae0f603894ff4846 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Wed, 5 Jun 2019 18:46:29 +0530 Subject: [PATCH 1102/1645] ASoC: msm: update tdm slot and dai link for 6155 machine Change QUAT_TDM slot config to take effect of the proper clock rate. Update the TDM DAI links with SEC/TERT/QUAT hostless frontends and backends. Change-Id: I210d3ee7c5032f59bb0799f6a3bfbcd5dc773e4d Signed-off-by: Nagarjuna Paladugu Signed-off-by: Derek Chen --- asoc/sa6155.c | 212 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 190 insertions(+), 22 deletions(-) diff --git a/asoc/sa6155.c b/asoc/sa6155.c index 8b1df6610a39..2e243e8577d5 100644 --- a/asoc/sa6155.c +++ b/asoc/sa6155.c @@ -208,7 +208,7 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ }, { /* QUAT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* RX_0 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ @@ -262,7 +262,7 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ }, { /* QUAT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 16}, /* TX_0 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ @@ -353,7 +353,7 @@ static struct tdm_slot_cfg tdm_slot[TDM_INTERFACE_MAX] = { /* TERT TDM */ {32, 8}, /* QUAT TDM */ - {32, 8}, + {32, 16}, /* QUIN TDM */ {32, 8} }; @@ -398,7 +398,7 @@ static unsigned int tdm_rx_slot_offset {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {28, 0xFFFF}, }, {/* TERT TDM */ {0, 4, 8, 12, 16, 20, 0xFFFF}, @@ -418,13 +418,13 @@ static unsigned int tdm_rx_slot_offset {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {28,0xFFFF}, }, {/* QUIN TDM */ - {0, 4, 0xFFFF}, /* not used */ - {8, 12, 0xFFFF}, /* not used */ - {16, 20, 0xFFFF}, /* not used */ - {24, 28, 0xFFFF}, /* not used */ + {0, 4, 0xFFFF},/*STEREO SPKR1*/ + {8, 12, 0xFFFF},/*STEREO SPKR2*/ + {16, 20, 0xFFFF},/*STEREO SPKR3*/ + {24, 28, 0xFFFF},/*STEREO SPKR4*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -462,21 +462,21 @@ static unsigned int tdm_tx_slot_offset {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {28, 0xFFFF}, }, {/* QUAT TDM */ {0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*MIC ARR*/ - {0xFFFF}, /* not used */ + 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*MIC ARR*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ + {60,0xFFFF}, }, {/* QUIN TDM */ - {0, 4, 8, 12, 16, 20, 0xFFFF}, /* not used */ + {0, 4, 8, 12, 16, 20, 0xFFFF},/*EC/ANC REF*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -488,6 +488,7 @@ static unsigned int tdm_tx_slot_offset }; /***************************************************************************** +* TO BE UPDATED: Codec/Platform specific tdm slot offset table * NOTE: * Each entry represents the slot offset array of one backend tdm device * valid offset represents the starting offset in byte for the channel @@ -513,7 +514,7 @@ static unsigned int tdm_rx_slot_offset_custom {10, 0xFFFF}, {12, 14, 16, 18, 20, 22, 24, 26, 0xFFFF}, {28, 30, 0xFFFF}, - {0xFFFF}, /* not used */ + {30, 0xFFFF}, }, {/* TERT TDM */ {0, 2, 0xFFFF}, @@ -533,7 +534,7 @@ static unsigned int tdm_rx_slot_offset_custom {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {0, 0xFFFF}, }, {/* QUIN TDM */ {0xFFFF}, /* not used */ @@ -577,7 +578,7 @@ static unsigned int tdm_tx_slot_offset_custom {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {30, 0xFFFF}, }, {/* QUAT TDM */ {0xFFFF}, /* not used */ @@ -587,7 +588,7 @@ static unsigned int tdm_tx_slot_offset_custom {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {0, 0xFFFF}, }, {/* QUIN TDM */ {0xFFFF}, /* not used */ @@ -1405,7 +1406,7 @@ static int aux_pcm_get_sample_rate_val(int sample_rate) static int tdm_get_mode(struct snd_kcontrol *kcontrol) { - int mode = TDM_PRI; + int mode = -EINVAL; if (strnstr(kcontrol->id.name, "PRI", sizeof(kcontrol->id.name))) { @@ -1433,7 +1434,7 @@ static int tdm_get_mode(struct snd_kcontrol *kcontrol) static int tdm_get_channel(struct snd_kcontrol *kcontrol) { - int channel = TDM_0; + int channel = -EINVAL; if (strnstr(kcontrol->id.name, "RX_0", sizeof(kcontrol->id.name)) || @@ -1495,9 +1496,8 @@ static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, port->channel = tdm_get_channel(kcontrol); if (port->channel < 0) return port->channel; - } else { + } else return -EINVAL; - } return 0; } @@ -4018,6 +4018,14 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_3].sample_rate; break; + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_7].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_7].sample_rate; + break; case AFE_PORT_ID_SECONDARY_TDM_TX: channels->min = channels->max = tdm_tx_cfg[TDM_SEC][TDM_0].channels; @@ -4122,6 +4130,14 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_3].sample_rate; break; + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_7].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_7].sample_rate; + break; case AFE_PORT_ID_QUATERNARY_TDM_RX: channels->min = channels->max = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; @@ -4154,6 +4170,14 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_3].sample_rate; break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_7].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_7].sample_rate; + break; case AFE_PORT_ID_QUATERNARY_TDM_TX: channels->min = channels->max = tdm_tx_cfg[TDM_QUAT][TDM_0].channels; @@ -4186,6 +4210,14 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_3].sample_rate; break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_7].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_7].sample_rate; + break; case AFE_PORT_ID_QUINARY_TDM_RX: channels->min = channels->max = tdm_rx_cfg[TDM_QUIN][TDM_0].channels; @@ -4375,6 +4407,11 @@ static int sa6155_tdm_snd_hw_params(struct snd_pcm_substream *substream, slot_width = tdm_slot[TDM_SEC].width; slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_3]; break; + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_7]; + break; case AFE_PORT_ID_SECONDARY_TDM_TX: slots = tdm_slot[TDM_SEC].num; slot_width = tdm_slot[TDM_SEC].width; @@ -4440,6 +4477,11 @@ static int sa6155_tdm_snd_hw_params(struct snd_pcm_substream *substream, slot_width = tdm_slot[TDM_TERT].width; slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_3]; break; + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_7]; + break; case AFE_PORT_ID_QUATERNARY_TDM_RX: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; @@ -4460,6 +4502,11 @@ static int sa6155_tdm_snd_hw_params(struct snd_pcm_substream *substream, slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_3]; break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_7]; + break; case AFE_PORT_ID_QUATERNARY_TDM_TX: slots = tdm_slot[TDM_QUAT].num; slot_width = tdm_slot[TDM_QUAT].width; @@ -4480,6 +4527,11 @@ static int sa6155_tdm_snd_hw_params(struct snd_pcm_substream *substream, slot_width = tdm_slot[TDM_QUAT].width; slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_3]; break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_7]; + break; case AFE_PORT_ID_QUINARY_TDM_RX: slots = tdm_slot[TDM_QUIN].num; slot_width = tdm_slot[TDM_QUIN].width; @@ -5564,7 +5616,67 @@ static struct snd_soc_dai_link msm_auto_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .id = MSM_FRONTEND_DAI_DTMF_RX, - } + }, + { + .name = "Secondary TDM RX 7 Hostless", + .stream_name = "Secondary TDM RX 7 Hostless", + .cpu_dai_name = "SEC_TDM_RX_7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Tertiary TDM TX 7 Hostless", + .stream_name = "Tertiary TDM TX 7 Hostless", + .cpu_dai_name = "TERT_TDM_TX_7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Quaternary TDM RX 7 Hostless", + .stream_name = "Quaternary TDM RX 7 Hostless", + .cpu_dai_name = "QUAT_TDM_RX_7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Quaternary TDM TX 7 Hostless", + .stream_name = "Quaternary TDM TX 7 Hostless", + .cpu_dai_name = "QUAT_TDM_TX_7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, }; static struct snd_soc_dai_link msm_custom_fe_dai_links[] = { @@ -6146,6 +6258,20 @@ static struct snd_soc_dai_link msm_auto_be_dai_links[] = { .ops = &sa6155_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_SEC_TDM_RX_7, + .stream_name = "Secondary TDM7 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36894", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_7, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, { .name = LPASS_BE_SEC_TDM_TX_1, .stream_name = "Secondary TDM1 Capture", @@ -6286,6 +6412,20 @@ static struct snd_soc_dai_link msm_auto_be_dai_links[] = { .ops = &sa6155_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_TERT_TDM_TX_7, + .stream_name = "Tertiary TDM7 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36911", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_7, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, { .name = LPASS_BE_QUAT_TDM_RX_1, .stream_name = "Quaternary TDM1 Playback", @@ -6328,6 +6468,20 @@ static struct snd_soc_dai_link msm_auto_be_dai_links[] = { .ops = &sa6155_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUAT_TDM_RX_7, + .stream_name = "Quaternary TDM7 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36926", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_7, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, { .name = LPASS_BE_QUAT_TDM_TX_1, .stream_name = "Quaternary TDM1 Capture", @@ -6370,6 +6524,20 @@ static struct snd_soc_dai_link msm_auto_be_dai_links[] = { .ops = &sa6155_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUAT_TDM_TX_7, + .stream_name = "Quaternary TDM7 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36927", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_7, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link ext_disp_be_dai_link[] = { -- GitLab From 7bb78319e0f8705b1a0e1016aaf5421e22e59192 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Tue, 18 Jun 2019 00:36:55 -0700 Subject: [PATCH 1103/1645] ASoC: msm: enable tdm pinctrl config on 6155 machine Enable dynamic TDM pinctrl configuration based on CPU DAI activity on auto 6155 machine drv. Change-Id: I4550b0e098d450d3ac29c162630c2450d42ac384 Signed-off-by: Derek Chen --- asoc/sa6155.c | 481 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 317 insertions(+), 164 deletions(-) diff --git a/asoc/sa6155.c b/asoc/sa6155.c index 2e243e8577d5..ab4e8428451c 100644 --- a/asoc/sa6155.c +++ b/asoc/sa6155.c @@ -128,26 +128,24 @@ enum { }; enum pinctrl_pin_state { - STATE_DISABLE = 0, /* All pins are in sleep state */ - STATE_MI2S_ACTIVE, /* I2S = active, TDM = sleep */ - STATE_TDM_ACTIVE, /* I2S = sleep, TDM = active */ + STATE_SLEEP = 0, /* All pins are in sleep state */ + STATE_ACTIVE, /* TDM = active */ }; struct msm_pinctrl_info { struct pinctrl *pinctrl; - struct pinctrl_state *mi2s_disable; - struct pinctrl_state *tdm_disable; - struct pinctrl_state *mi2s_active; - struct pinctrl_state *tdm_active; + struct pinctrl_state *sleep; + struct pinctrl_state *active; enum pinctrl_pin_state curr_state; }; -struct msm_asoc_mach_data { - struct msm_pinctrl_info pinctrl_info; -}; +static const char *const pin_states[] = {"sleep", "active"}; -static const char *const pin_states[] = {"sleep", "i2s-active", - "tdm-active"}; +static const char *const tdm_gpio_phandle[] = {"qcom,pri-tdm-gpios", + "qcom,sec-tdm-gpios", + "qcom,tert-tdm-gpios", + "qcom,quat-tdm-gpios", + "qcom,quin-tdm-gpios"}; enum { TDM_0 = 0, @@ -175,6 +173,11 @@ struct tdm_port { u32 channel; }; +struct tdm_conf { + struct mutex lock; + u32 ref_cnt; +}; + /* TDM default config */ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { { /* PRI TDM */ @@ -743,7 +746,11 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = { }; -static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; +struct msm_asoc_mach_data { + struct msm_pinctrl_info pinctrl_info[TDM_INTERFACE_MAX]; + struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; + struct tdm_conf tdm_intf_conf[TDM_INTERFACE_MAX]; +}; static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -3735,7 +3742,6 @@ static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) return ret; } -#ifdef ENABLE_PINCTRL static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, enum pinctrl_pin_state new_state) { @@ -3743,13 +3749,13 @@ static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, int curr_state = 0; if (pinctrl_info == NULL) { - pr_err("%s: pinctrl_info is NULL\n", __func__); + pr_err("%s: pinctrl info is NULL\n", __func__); ret = -EINVAL; goto err; } if (pinctrl_info->pinctrl == NULL) { - pr_err("%s: pinctrl_info->pinctrl is NULL\n", __func__); + pr_err("%s: pinctrl handle is NULL\n", __func__); ret = -EINVAL; goto err; } @@ -3760,55 +3766,40 @@ static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, pin_states[curr_state], pin_states[pinctrl_info->curr_state]); if (curr_state == pinctrl_info->curr_state) { - pr_debug("%s: Already in same state\n", __func__); + pr_debug("%s: pin already in same state\n", __func__); goto err; } - if (curr_state != STATE_DISABLE && - pinctrl_info->curr_state != STATE_DISABLE) { - pr_debug("%s: state already active cannot switch\n", __func__); + if (curr_state != STATE_SLEEP && + pinctrl_info->curr_state != STATE_SLEEP) { + pr_debug("%s: pin state is already active, cannot switch\n", __func__); ret = -EIO; goto err; } switch (pinctrl_info->curr_state) { - case STATE_MI2S_ACTIVE: + case STATE_ACTIVE: ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_active); + pinctrl_info->active); if (ret) { - pr_err("%s: MI2S state select failed with %d\n", + pr_err("%s: state select to active failed with %d\n", __func__, ret); ret = -EIO; goto err; } break; - case STATE_TDM_ACTIVE: + case STATE_SLEEP: ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->tdm_active); - if (ret) { - pr_err("%s: TDM state select failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - break; - case STATE_DISABLE: - if (curr_state == STATE_MI2S_ACTIVE) { - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_disable); - } else { - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->tdm_disable); - } + pinctrl_info->sleep); if (ret) { - pr_err("%s: state disable failed with %d\n", + pr_err("%s: state select to sleep failed with %d\n", __func__, ret); ret = -EIO; goto err; } break; default: - pr_err("%s: TLMM pin state is invalid\n", __func__); + pr_err("%s: pin state is invalid\n", __func__); return -EINVAL; } @@ -3820,11 +3811,17 @@ static void msm_release_pinctrl(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + struct msm_pinctrl_info *pinctrl_info = NULL; + int i; - if (pinctrl_info->pinctrl) { - devm_pinctrl_put(pinctrl_info->pinctrl); - pinctrl_info->pinctrl = NULL; + for (i = TDM_PRI; i < TDM_INTERFACE_MAX; i++) { + pinctrl_info = &pdata->pinctrl_info[i]; + if (pinctrl_info == NULL) + continue; + if (pinctrl_info->pinctrl) { + devm_pinctrl_put(pinctrl_info->pinctrl); + pinctrl_info->pinctrl = NULL; + } } } @@ -3833,84 +3830,172 @@ static int msm_get_pinctrl(struct platform_device *pdev) struct snd_soc_card *card = platform_get_drvdata(pdev); struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); struct msm_pinctrl_info *pinctrl_info = NULL; - struct pinctrl *pinctrl; + struct pinctrl *pinctrl = NULL; + int i, j; + struct device_node *np = NULL; + struct platform_device *pdev_np = NULL; int ret = 0; - pinctrl_info = &pdata->pinctrl_info; + for (i = TDM_PRI; i < TDM_INTERFACE_MAX; i++) { + np = of_parse_phandle(pdev->dev.of_node, + tdm_gpio_phandle[i], 0); + if (!np) { + pr_debug("%s: device node %s is null\n", + __func__, tdm_gpio_phandle[i]); + continue; + } - if (pinctrl_info == NULL) { - pr_err("%s: pinctrl_info is NULL\n", __func__); - return -EINVAL; - } + pdev_np = of_find_device_by_node(np); + if (!pdev_np) { + pr_err("%s: platform device not found\n", __func__); + continue; + } - pinctrl = devm_pinctrl_get(&pdev->dev); - if (IS_ERR_OR_NULL(pinctrl)) { - pr_err("%s: Unable to get pinctrl handle\n", __func__); - return -EINVAL; - } - pinctrl_info->pinctrl = pinctrl; + pinctrl_info = &pdata->pinctrl_info[i]; + if (pinctrl_info == NULL) { + pr_err("%s: pinctrl info is null\n", __func__); + continue; + } - /* get all the states handles from Device Tree */ - pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl, - "quat_mi2s_disable"); - if (IS_ERR(pinctrl_info->mi2s_disable)) { - pr_err("%s: could not get mi2s_disable pinstate\n", __func__); - goto err; - } - pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl, - "quat_mi2s_enable"); - if (IS_ERR(pinctrl_info->mi2s_active)) { - pr_err("%s: could not get mi2s_active pinstate\n", __func__); - goto err; - } - pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl, - "quat_tdm_disable"); - if (IS_ERR(pinctrl_info->tdm_disable)) { - pr_err("%s: could not get tdm_disable pinstate\n", __func__); - goto err; - } - pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl, - "quat_tdm_enable"); - if (IS_ERR(pinctrl_info->tdm_active)) { - pr_err("%s: could not get tdm_active pinstate\n", - __func__); - goto err; - } - /* Reset the TLMM pins to a default state */ - ret = pinctrl_select_state(pinctrl_info->pinctrl, - pinctrl_info->mi2s_disable); - if (ret != 0) { - pr_err("%s: Disable TLMM pins failed with %d\n", - __func__, ret); - ret = -EIO; - goto err; - } - pinctrl_info->curr_state = STATE_DISABLE; + pinctrl = devm_pinctrl_get(&pdev_np->dev); + if (IS_ERR_OR_NULL(pinctrl)) { + pr_err("%s: fail to get pinctrl handle\n", __func__); + goto err; + } + pinctrl_info->pinctrl = pinctrl; + /* get all the states handles from Device Tree */ + pinctrl_info->sleep = pinctrl_lookup_state(pinctrl, + "sleep"); + if (IS_ERR(pinctrl_info->sleep)) { + pr_err("%s: could not get sleep pin state\n", __func__); + goto err; + } + pinctrl_info->active = pinctrl_lookup_state(pinctrl, + "default"); + if (IS_ERR(pinctrl_info->active)) { + pr_err("%s: could not get active pin state\n", + __func__); + goto err; + } + + /* Reset the TLMM pins to a sleep state */ + ret = pinctrl_select_state(pinctrl_info->pinctrl, + pinctrl_info->sleep); + if (ret != 0) { + pr_err("%s: set pin state to sleep failed with %d\n", + __func__, ret); + ret = -EIO; + goto err; + } + pinctrl_info->curr_state = STATE_SLEEP; + } return 0; err: - devm_pinctrl_put(pinctrl); - pinctrl_info->pinctrl = NULL; + for (j = i; j >= 0; j--) { + pinctrl_info = &pdata->pinctrl_info[j]; + if (pinctrl_info == NULL) + continue; + if (pinctrl_info->pinctrl) { + devm_pinctrl_put(pinctrl_info->pinctrl); + pinctrl_info->pinctrl = NULL; + } + } return -EINVAL; } -#else -static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info, - enum pinctrl_pin_state new_state) -{ - return 0; -} -static void msm_release_pinctrl(struct platform_device *pdev) +static int msm_tdm_get_intf_idx(u16 id) { - return; -} - -static int msm_get_pinctrl(struct platform_device *pdev) -{ - return 0; + switch (id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + return TDM_PRI; + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + case AFE_PORT_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + return TDM_SEC; + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + case AFE_PORT_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + return TDM_TERT; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + return TDM_QUAT; + case AFE_PORT_ID_QUINARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_RX_1: + case AFE_PORT_ID_QUINARY_TDM_RX_2: + case AFE_PORT_ID_QUINARY_TDM_RX_3: + case AFE_PORT_ID_QUINARY_TDM_RX_4: + case AFE_PORT_ID_QUINARY_TDM_RX_5: + case AFE_PORT_ID_QUINARY_TDM_RX_6: + case AFE_PORT_ID_QUINARY_TDM_RX_7: + case AFE_PORT_ID_QUINARY_TDM_TX: + case AFE_PORT_ID_QUINARY_TDM_TX_1: + case AFE_PORT_ID_QUINARY_TDM_TX_2: + case AFE_PORT_ID_QUINARY_TDM_TX_3: + case AFE_PORT_ID_QUINARY_TDM_TX_4: + case AFE_PORT_ID_QUINARY_TDM_TX_5: + case AFE_PORT_ID_QUINARY_TDM_TX_6: + case AFE_PORT_ID_QUINARY_TDM_TX_7: + return TDM_QUIN; + default: return -EINVAL; + } } -#endif static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) @@ -4661,37 +4746,76 @@ static int sa6155_tdm_snd_startup(struct snd_pcm_substream *substream) struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + struct msm_pinctrl_info *pinctrl_info = NULL; + struct tdm_conf *intf_conf = NULL; + int ret_pinctrl = 0; + int index; + + pr_debug("%s: substream = %s, stream = %d, dai name = %s, dai id = %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + index = msm_tdm_get_intf_idx(cpu_dai->id); + if (index < 0) { + ret = -EINVAL; + pr_err("%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto err; + } - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || - (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { - ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE); - if (ret) + /* + * Mutex protection in case the same TDM + * interface using for both TX and RX so + * that the same clock won't be enable twice. + */ + intf_conf = &pdata->tdm_intf_conf[index]; + mutex_lock(&intf_conf->lock); + if (++intf_conf->ref_cnt == 1) { + pinctrl_info = &pdata->pinctrl_info[index]; + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_ACTIVE); + if (ret_pinctrl) pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret); + __func__, ret_pinctrl); } + mutex_unlock(&intf_conf->lock); +err: return ret; } static void sa6155_tdm_snd_shutdown(struct snd_pcm_substream *substream) { - int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + struct msm_pinctrl_info *pinctrl_info = NULL; + struct tdm_conf *intf_conf = NULL; + int ret_pinctrl = 0; + int index; - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) || - (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) { - ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE); - if (ret) + pr_debug("%s: substream = %s, stream = %d\n", __func__, + substream->name, substream->stream); + + index = msm_tdm_get_intf_idx(cpu_dai->id); + if (index < 0) { + pr_err("%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + return; + } + + intf_conf = &pdata->tdm_intf_conf[index]; + mutex_lock(&intf_conf->lock); + if (--intf_conf->ref_cnt == 0) { + pinctrl_info = &pdata->pinctrl_info[index]; + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_SLEEP); + if (ret_pinctrl) pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret); + __func__, ret_pinctrl); } + mutex_unlock(&intf_conf->lock); } static struct snd_soc_ops sa6155_tdm_be_ops = { @@ -4733,7 +4857,8 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + struct msm_pinctrl_info *pinctrl_info = NULL; + struct mi2s_conf *intf_conf = NULL; int ret_pinctrl = 0; dev_dbg(rtd->card->dev, @@ -4753,10 +4878,11 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) * interface using for both TX and RX so * that the same clock won't be enable twice. */ - mutex_lock(&mi2s_intf_conf[index].lock); - if (++mi2s_intf_conf[index].ref_cnt == 1) { + intf_conf = &pdata->mi2s_intf_conf[index]; + mutex_lock(&intf_conf->lock); + if (++intf_conf->ref_cnt == 1) { /* Check if msm needs to provide the clock to the interface */ - if (!mi2s_intf_conf[index].msm_is_mi2s_master) { + if (!intf_conf->msm_is_mi2s_master) { mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; fmt = SND_SOC_DAIFMT_CBM_CFM; } @@ -4774,21 +4900,21 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) __func__, index, ret); goto clk_off; } - if (index == QUAT_MI2S) { - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_MI2S_ACTIVE); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); - } + + pinctrl_info = &pdata->pinctrl_info[index]; + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_ACTIVE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); } clk_off: if (ret < 0) msm_mi2s_set_sclk(substream, false); clean_up: if (ret < 0) - mi2s_intf_conf[index].ref_cnt--; - mutex_unlock(&mi2s_intf_conf[index].lock); + intf_conf->ref_cnt--; + mutex_unlock(&intf_conf->lock); err: return ret; } @@ -4800,7 +4926,8 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) int index = rtd->cpu_dai->id; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info; + struct msm_pinctrl_info *pinctrl_info = NULL; + struct mi2s_conf *intf_conf = NULL; int ret_pinctrl = 0; pr_debug("%s(): substream = %s stream = %d\n", __func__, @@ -4810,21 +4937,22 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) return; } - mutex_lock(&mi2s_intf_conf[index].lock); - if (--mi2s_intf_conf[index].ref_cnt == 0) { + intf_conf = &pdata->mi2s_intf_conf[index]; + mutex_lock(&intf_conf->lock); + if (--intf_conf->ref_cnt == 0) { ret = msm_mi2s_set_sclk(substream, false); if (ret < 0) pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", __func__, index, ret); - if (index == QUAT_MI2S) { - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_DISABLE); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); - } + + pinctrl_info = &pdata->pinctrl_info[index]; + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_SLEEP); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); } - mutex_unlock(&mi2s_intf_conf[index].lock); + mutex_unlock(&intf_conf->lock); } static struct snd_soc_ops msm_mi2s_be_ops = { @@ -7087,19 +7215,22 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) /***************************************************************************** * TO BE UPDATED: Codec/Platform specific tdm slot and offset table selection *****************************************************************************/ -static int msm_tdm_init(struct device *dev) +static int msm_tdm_init(struct platform_device *pdev) { + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); const struct of_device_id *match; + int count; - match = of_match_node(sa6155_asoc_machine_of_match, dev->of_node); + match = of_match_node(sa6155_asoc_machine_of_match, pdev->dev.of_node); if (!match) { - dev_err(dev, "%s: No DT match found for sound card\n", + dev_err(&pdev->dev, "%s: No DT match found for sound card\n", __func__); return -EINVAL; } if (!strcmp(match->data, "custom_codec")) { - dev_dbg(dev, "%s: custom tdm configuration\n", __func__); + dev_dbg(&pdev->dev, "%s: custom tdm configuration\n", __func__); memcpy(tdm_rx_slot_offset, tdm_rx_slot_offset_custom, @@ -7111,21 +7242,40 @@ static int msm_tdm_init(struct device *dev) tdm_slot_custom, sizeof(tdm_slot_custom)); } else { - dev_dbg(dev, "%s: default tdm configuration\n", __func__); + dev_dbg(&pdev->dev, "%s: default tdm configuration\n", __func__); + } + + for (count = 0; count < TDM_INTERFACE_MAX; count++) { + mutex_init(&pdata->tdm_intf_conf[count].lock); + pdata->tdm_intf_conf[count].ref_cnt = 0; } return 0; } +static void msm_tdm_deinit(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + int count; + + for (count = 0; count < TDM_INTERFACE_MAX; count++) { + mutex_destroy(&pdata->tdm_intf_conf[count].lock); + pdata->tdm_intf_conf[count].ref_cnt = 0; + } +} + static void msm_i2s_auxpcm_init(struct platform_device *pdev) { + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); int count; u32 mi2s_master_slave[MI2S_MAX]; int ret; for (count = 0; count < MI2S_MAX; count++) { - mutex_init(&mi2s_intf_conf[count].lock); - mi2s_intf_conf[count].ref_cnt = 0; + mutex_init(&pdata->mi2s_intf_conf[count].lock); + pdata->mi2s_intf_conf[count].ref_cnt = 0; } ret = of_property_read_u32_array(pdev->dev.of_node, @@ -7136,20 +7286,22 @@ static void msm_i2s_auxpcm_init(struct platform_device *pdev) __func__); } else { for (count = 0; count < MI2S_MAX; count++) { - mi2s_intf_conf[count].msm_is_mi2s_master = + pdata->mi2s_intf_conf[count].msm_is_mi2s_master = mi2s_master_slave[count]; } } } -static void msm_i2s_auxpcm_deinit(void) +static void msm_i2s_auxpcm_deinit(struct platform_device *pdev) { + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); int count; for (count = 0; count < MI2S_MAX; count++) { - mutex_destroy(&mi2s_intf_conf[count].lock); - mi2s_intf_conf[count].ref_cnt = 0; - mi2s_intf_conf[count].msm_is_mi2s_master = 0; + mutex_destroy(&pdata->mi2s_intf_conf[count].lock); + pdata->mi2s_intf_conf[count].ref_cnt = 0; + pdata->mi2s_intf_conf[count].msm_is_mi2s_master = 0; } } @@ -7275,7 +7427,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) card->controls = msm_snd_controls; card->num_controls = ARRAY_SIZE(msm_snd_controls); - ret = msm_tdm_init(&pdev->dev); + ret = msm_tdm_init(pdev); if (ret) { ret = -EPROBE_DEFER; goto err; @@ -7297,7 +7449,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) pr_debug("%s: pinctrl parsing successful\n", __func__); } else { dev_dbg(&pdev->dev, - "%s: Parsing pinctrl failed with %d. Cannot use Ports\n", + "%s: pinctrl parsing failed with %d\n", __func__, ret); ret = 0; } @@ -7318,7 +7470,8 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) static int msm_asoc_machine_remove(struct platform_device *pdev) { - msm_i2s_auxpcm_deinit(); + msm_i2s_auxpcm_deinit(pdev); + msm_tdm_deinit(pdev); msm_release_pinctrl(pdev); return 0; -- GitLab From 478838340916bb87e04c62d42cae644951174570 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Tue, 25 Jun 2019 13:40:25 -0700 Subject: [PATCH 1104/1645] ASoC: sa6155: add quin tdm dai links and update pinctrl Add Quinary TDM TX 7 to RX 7 AFE loopback routing support for SA6155. Enable pinctrl configuration only for TERT/QUAT/ QUIN TDM interfaces. SEC TDM intf is not used. Change-Id: Ia80436722a929ad7d072a97c7007683b528993d8 Signed-off-by: Derek Chen --- asoc/sa6155.c | 132 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 111 insertions(+), 21 deletions(-) diff --git a/asoc/sa6155.c b/asoc/sa6155.c index ab4e8428451c..269bb815fe78 100644 --- a/asoc/sa6155.c +++ b/asoc/sa6155.c @@ -221,10 +221,10 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ }, { /* QUIN TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_3 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ @@ -275,7 +275,7 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ }, { /* QUIN TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* TX_0 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ @@ -431,7 +431,7 @@ static unsigned int tdm_rx_slot_offset {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {28, 0xFFFF}, } }; @@ -486,7 +486,7 @@ static unsigned int tdm_tx_slot_offset {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {20, 0xFFFF}, } }; @@ -547,7 +547,7 @@ static unsigned int tdm_rx_slot_offset_custom {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {0, 0xFFFF}, } }; @@ -601,7 +601,7 @@ static unsigned int tdm_tx_slot_offset_custom {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {0, 0xFFFF}, } }; @@ -4335,6 +4335,14 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_3].sample_rate; break; + case AFE_PORT_ID_QUINARY_TDM_RX_7: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_7].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_7].sample_rate; + break; case AFE_PORT_ID_QUINARY_TDM_TX: channels->min = channels->max = tdm_tx_cfg[TDM_QUIN][TDM_0].channels; @@ -4367,6 +4375,14 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = tdm_tx_cfg[TDM_QUIN][TDM_3].sample_rate; break; + case AFE_PORT_ID_QUINARY_TDM_TX_7: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_7].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_7].sample_rate; + break; default: pr_err("%s: dai id 0x%x not supported\n", __func__, cpu_dai->id); @@ -4637,6 +4653,11 @@ static int sa6155_tdm_snd_hw_params(struct snd_pcm_substream *substream, slot_width = tdm_slot[TDM_QUIN].width; slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_3]; break; + case AFE_PORT_ID_QUINARY_TDM_RX_7: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_7]; + break; case AFE_PORT_ID_QUINARY_TDM_TX: slots = tdm_slot[TDM_QUIN].num; slot_width = tdm_slot[TDM_QUIN].width; @@ -4657,6 +4678,11 @@ static int sa6155_tdm_snd_hw_params(struct snd_pcm_substream *substream, slot_width = tdm_slot[TDM_QUIN].width; slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_3]; break; + case AFE_PORT_ID_QUINARY_TDM_TX_7: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_7]; + break; default: pr_err("%s: dai id 0x%x not supported\n", __func__, cpu_dai->id); @@ -4771,12 +4797,15 @@ static int sa6155_tdm_snd_startup(struct snd_pcm_substream *substream) intf_conf = &pdata->tdm_intf_conf[index]; mutex_lock(&intf_conf->lock); if (++intf_conf->ref_cnt == 1) { - pinctrl_info = &pdata->pinctrl_info[index]; - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_ACTIVE); - if (ret_pinctrl) - pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); + if (index == TDM_TERT || index == TDM_QUAT || + index == TDM_QUIN) { + pinctrl_info = &pdata->pinctrl_info[index]; + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_ACTIVE); + if (ret_pinctrl) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } } mutex_unlock(&intf_conf->lock); @@ -4808,12 +4837,15 @@ static void sa6155_tdm_snd_shutdown(struct snd_pcm_substream *substream) intf_conf = &pdata->tdm_intf_conf[index]; mutex_lock(&intf_conf->lock); if (--intf_conf->ref_cnt == 0) { - pinctrl_info = &pdata->pinctrl_info[index]; - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_SLEEP); - if (ret_pinctrl) - pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); + if (index == TDM_TERT || index == TDM_QUAT || + index == TDM_QUIN) { + pinctrl_info = &pdata->pinctrl_info[index]; + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_SLEEP); + if (ret_pinctrl) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } } mutex_unlock(&intf_conf->lock); } @@ -5805,6 +5837,36 @@ static struct snd_soc_dai_link msm_auto_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, + { + .name = "Quinary TDM RX 7 Hostless", + .stream_name = "Quinary TDM RX 7 Hostless", + .cpu_dai_name = "QUIN_TDM_RX_7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Quinary TDM TX 7 Hostless", + .stream_name = "Quinary TDM TX 7 Hostless", + .cpu_dai_name = "QUIN_TDM_TX_7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, }; static struct snd_soc_dai_link msm_custom_fe_dai_links[] = { @@ -6666,6 +6728,34 @@ static struct snd_soc_dai_link msm_auto_be_dai_links[] = { .ops = &sa6155_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUIN_TDM_RX_7, + .stream_name = "Quinary TDM7 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36942", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_RX_7, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_TDM_TX_7, + .stream_name = "Quinary TDM7 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36943", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_TX_7, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa6155_tdm_be_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link ext_disp_be_dai_link[] = { -- GitLab From 583e3bf1c666cf0d7d404e638f976f2b635144a1 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Mon, 15 Apr 2019 18:01:45 -0700 Subject: [PATCH 1105/1645] ASoC: msm: Add audio support for sdmshrike on auto platform Add audio support for sdmshrike on automotive platform. Change-Id: I39c70fd7ed66124827f55b7a6e0a834cf735d301 Signed-off-by: Derek Chen --- Android.mk | 4 ++-- asoc/Android.mk | 2 +- asoc/Kbuild | 12 +++++++++--- dsp/Android.mk | 4 ++-- dsp/Kbuild | 12 +++++++++--- ipc/Android.mk | 4 ++-- ipc/Kbuild | 12 +++++++++--- soc/Android.mk | 4 ++-- soc/Kbuild | 12 +++++++++--- 9 files changed, 45 insertions(+), 21 deletions(-) diff --git a/Android.mk b/Android.mk index 722c3ce3b5a7..3394a3217bd2 100644 --- a/Android.mk +++ b/Android.mk @@ -23,7 +23,7 @@ include $(MY_LOCAL_PATH)/asoc/codecs/Android.mk endif ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au sm6150_au msmnile_gvmq)) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au sm6150_au msmnile_gvmq sdmshrike_au)) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers) @@ -32,7 +32,7 @@ endif endif ifeq ($(call is-board-platform-in-list,msmnile),true) -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq sdmshrike_au)) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/aqt1000/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/aqt1000/Android.mk endif diff --git a/asoc/Android.mk b/asoc/Android.mk index 8a2a0cc1f4a6..95ba1d8e67cf 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -5,7 +5,7 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) TARGET := msmnile -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq sdmshrike_au)) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m diff --git a/asoc/Kbuild b/asoc/Kbuild index 9ca09b7a336b..281749c863a6 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -51,9 +51,15 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + ifdef CONFIG_SND_SOC_SA8155 + include $(AUDIO_ROOT)/config/sa8155auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h + else + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif endif ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf diff --git a/dsp/Android.mk b/dsp/Android.mk index fe4d9f69ea75..d88b345ddd90 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -4,7 +4,7 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq sdmshrike_au)) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m @@ -81,7 +81,7 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### # target specific build -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au sm6150_au msmnile_gvmq)) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au sm6150_au msmnile_gvmq sdmshrike_au)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_usf.ko LOCAL_MODULE_KBUILD_NAME := usf_dlkm.ko diff --git a/dsp/Kbuild b/dsp/Kbuild index 9ab89668d7e4..a68d10d42eea 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -51,9 +51,15 @@ ifeq ($(KERNEL_BUILD), 0) endif endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + ifdef CONFIG_SND_SOC_SA8155 + include $(AUDIO_ROOT)/config/sa8155auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h + else + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif endif ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf diff --git a/ipc/Android.mk b/ipc/Android.mk index 2ab38b765304..224308efef0f 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -4,7 +4,7 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq sdmshrike_au)) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m @@ -65,7 +65,7 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au sm6150_au msmnile_gvmq)) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au sm6150_au msmnile_gvmq sdmshrike_au)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wglink.ko LOCAL_MODULE_KBUILD_NAME := wglink_dlkm.ko diff --git a/ipc/Kbuild b/ipc/Kbuild index fa8776143219..d61270adfd69 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -57,9 +57,15 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + ifdef CONFIG_SND_SOC_SA8155 + include $(AUDIO_ROOT)/config/sa8155auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h + else + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif endif ifeq ($(CONFIG_QTI_GVM), y) include $(AUDIO_ROOT)/config/gvmauto.conf diff --git a/soc/Android.mk b/soc/Android.mk index 58d325477c3b..ea1e6164911d 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -4,7 +4,7 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) +ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq sdmshrike_au)) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m @@ -80,7 +80,7 @@ include $(DLKM_DIR)/AndroidKernelModule.mk endif endif ########################################################### -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq sm6150_au)) +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq sm6150_au sdmshrike_au)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_swr.ko LOCAL_MODULE_KBUILD_NAME := swr_dlkm.ko diff --git a/soc/Kbuild b/soc/Kbuild index 0daf3cd7220d..26b3fa779079 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -51,9 +51,15 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) - include $(AUDIO_ROOT)/config/sm8150auto.conf - export - INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + ifdef CONFIG_SND_SOC_SA8155 + include $(AUDIO_ROOT)/config/sa8155auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h + else + include $(AUDIO_ROOT)/config/sm8150auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h + endif endif ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf -- GitLab From e780bb9ce6e331c450f127da667e29a30877d253 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Thu, 13 Jun 2019 16:59:36 -0700 Subject: [PATCH 1106/1645] ASoC: msm: update makefiles for auto platform support Update makefiles to use TARGET_BOARD_AUTO instead of TARGET_PRODUCT for automotive platform support. Change-Id: Ic688e8b13ba9c4b6f100c1acec50940053895d3d Signed-off-by: Derek Chen --- Android.mk | 6 +++--- asoc/Android.mk | 4 ++-- asoc/codecs/Android.mk | 6 +++--- dsp/Android.mk | 6 +++--- ipc/Android.mk | 6 +++--- soc/Android.mk | 10 +++++----- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Android.mk b/Android.mk index 3394a3217bd2..68b56a932857 100644 --- a/Android.mk +++ b/Android.mk @@ -23,7 +23,7 @@ include $(MY_LOCAL_PATH)/asoc/codecs/Android.mk endif ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au sm6150_au msmnile_gvmq sdmshrike_au)) +ifneq ($(TARGET_BOARD_AUTO),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers) @@ -32,14 +32,14 @@ endif endif ifeq ($(call is-board-platform-in-list,msmnile),true) -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq sdmshrike_au)) +ifneq ($(TARGET_BOARD_AUTO),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/aqt1000/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/aqt1000/Android.mk endif endif ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), sm6150_au)) +ifneq ($(TARGET_BOARD_AUTO),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/bolero/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/bolero/Android.mk $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd937x/Module.symvers) diff --git a/asoc/Android.mk b/asoc/Android.mk index 95ba1d8e67cf..fc7bde642b74 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -5,7 +5,7 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) TARGET := msmnile -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq sdmshrike_au)) +ifeq ($(TARGET_BOARD_AUTO),true) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m @@ -14,7 +14,7 @@ endif ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) TARGET := talos -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), sm6150_au)) +ifeq ($(TARGET_BOARD_AUTO),true) AUDIO_SELECT := CONFIG_SND_SOC_SA6155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index 077410ccd2aa..6603e51c0d25 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -4,7 +4,7 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq)) +ifeq ($(TARGET_BOARD_AUTO),true) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m @@ -12,7 +12,7 @@ endif endif ifeq ($(call is-board-platform,$(MSMSTEPPE)),true) -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), sm6150_au)) +ifeq ($(TARGET_BOARD_AUTO),true) AUDIO_SELECT := CONFIG_SND_SOC_SA6155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m @@ -60,7 +60,7 @@ KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) KBUILD_OPTIONS += $(AUDIO_SELECT) # Target specific build ########################################################### -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au sm6150_au msmnile_gvmq)) +ifneq ($(TARGET_BOARD_AUTO),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd_core.ko LOCAL_MODULE_KBUILD_NAME := wcd_core_dlkm.ko diff --git a/dsp/Android.mk b/dsp/Android.mk index d88b345ddd90..e0dc0a0ccd07 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -4,7 +4,7 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq sdmshrike_au)) +ifeq ($(TARGET_BOARD_AUTO),true) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m @@ -12,7 +12,7 @@ endif endif ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), sm6150_au)) +ifeq ($(TARGET_BOARD_AUTO),true) AUDIO_SELECT := CONFIG_SND_SOC_SA6155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m @@ -81,7 +81,7 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### # target specific build -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au sm6150_au msmnile_gvmq sdmshrike_au)) +ifneq ($(TARGET_BOARD_AUTO),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_usf.ko LOCAL_MODULE_KBUILD_NAME := usf_dlkm.ko diff --git a/ipc/Android.mk b/ipc/Android.mk index 224308efef0f..ce1a7bb487f9 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -4,7 +4,7 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq sdmshrike_au)) +ifeq ($(TARGET_BOARD_AUTO),true) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m @@ -12,7 +12,7 @@ endif endif ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), sm6150_au)) +ifeq ($(TARGET_BOARD_AUTO),true) AUDIO_SELECT := CONFIG_SND_SOC_SA6155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m @@ -65,7 +65,7 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au sm6150_au msmnile_gvmq sdmshrike_au)) +ifneq ($(TARGET_BOARD_AUTO),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wglink.ko LOCAL_MODULE_KBUILD_NAME := wglink_dlkm.ko diff --git a/soc/Android.mk b/soc/Android.mk index ea1e6164911d..be9c34d703ac 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -4,7 +4,7 @@ # Check if this driver needs be built for current target ifeq ($(call is-board-platform,msmnile),true) -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq sdmshrike_au)) +ifeq ($(TARGET_BOARD_AUTO),true) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m @@ -12,7 +12,7 @@ endif endif ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) -ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), sm6150_au)) +ifeq ($(TARGET_BOARD_AUTO),true) AUDIO_SELECT := CONFIG_SND_SOC_SA6155=m else AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m @@ -57,7 +57,7 @@ KBUILD_OPTIONS += $(AUDIO_SELECT) ########################################################### ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona lito),true) -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), sm6150_au)) +ifneq ($(TARGET_BOARD_AUTO),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_lpi.ko LOCAL_MODULE_KBUILD_NAME := pinctrl_lpi_dlkm.ko @@ -69,7 +69,7 @@ endif endif ########################################################### ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona), true) -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), sm6150_au)) +ifneq ($(TARGET_BOARD_AUTO),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_wcd.ko LOCAL_MODULE_KBUILD_NAME := pinctrl_wcd_dlkm.ko @@ -80,7 +80,7 @@ include $(DLKM_DIR)/AndroidKernelModule.mk endif endif ########################################################### -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq sm6150_au sdmshrike_au)) +ifneq ($(TARGET_BOARD_AUTO),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_swr.ko LOCAL_MODULE_KBUILD_NAME := swr_dlkm.ko -- GitLab From 7b6c5884b1a5d3c5edcfd1b95339c4bf0ec2e94d Mon Sep 17 00:00:00 2001 From: Han Lu Date: Sun, 9 Jun 2019 16:03:21 +0800 Subject: [PATCH 1107/1645] ASoC: msm: add quin tdm tx_7 to rx_7 loopback Add Quinary TDM TX 7 to RX 7 AFE loopback routing support. Change-Id: I7d7ac5dc677d2a742b913f4b123274c3a689dfed Signed-off-by: Han Lu --- asoc/msm-dai-fe.c | 32 ++++++++++++++++++++++++++++++++ asoc/msm-pcm-routing-v2.c | 17 +++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index f53b3a6a5b0f..c4cdd17d1d60 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -2050,6 +2050,38 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "QUAT_TDM_RX_7_HOSTLESS", .probe = fe_dai_probe, }, + { + .capture = { + .stream_name = "Quinary TDM7 Hostless Capture", + .aif_name = "QUIN_TDM_TX_7_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 16, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUIN_TDM_TX_7_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Quinary TDM7 Hostless Playback", + .aif_name = "QUIN_TDM_RX_7_DL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 16, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUIN_TDM_RX_7_HOSTLESS", + .probe = fe_dai_probe, + }, { .playback = { .stream_name = "DTMF_RX_HOSTLESS Playback", diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 4ec63e38adb6..7baff1f0b2bb 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -19082,6 +19082,14 @@ static const struct snd_kcontrol_new sen_tdm_rx_3_port_mixer_controls[] = { msm_routing_put_port_mixer), }; +static const struct snd_kcontrol_new quin_tdm_rx_7_port_mixer_controls[] = { + SOC_DOUBLE_EXT("QUIN_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_7, + MSM_BACKEND_DAI_QUIN_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + static const struct snd_kcontrol_new tert_mi2s_rx_port_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_RX, @@ -22506,6 +22514,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUIN_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0, quin_tdm_rx_3_port_mixer_controls, ARRAY_SIZE(quin_tdm_rx_3_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_7 Port Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_7_port_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_7_port_mixer_controls)), SND_SOC_DAPM_MIXER("SEN_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, sen_tdm_rx_0_port_mixer_controls, ARRAY_SIZE(sen_tdm_rx_0_port_mixer_controls)), @@ -25446,10 +25457,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_TX_1_UL_HL", NULL, "QUIN_TDM_TX_1"}, {"QUIN_TDM_TX_2_UL_HL", NULL, "QUIN_TDM_TX_2"}, {"QUIN_TDM_TX_3_UL_HL", NULL, "QUIN_TDM_TX_3"}, + {"QUIN_TDM_TX_7_UL_HL", NULL, "QUIN_TDM_TX_7"}, {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0_DL_HL"}, {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1_DL_HL"}, {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2_DL_HL"}, {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3_DL_HL"}, + {"QUIN_TDM_RX_7", NULL, "QUIN_TDM_RX_7_DL_HL"}, {"SEN_TDM_TX_0_UL_HL", NULL, "SEN_TDM_TX_0"}, {"SEN_TDM_TX_1_UL_HL", NULL, "SEN_TDM_TX_1"}, {"SEN_TDM_TX_2_UL_HL", NULL, "SEN_TDM_TX_2"}, @@ -25984,6 +25997,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Port Mixer"}, + {"QUIN_TDM_RX_7 Port Mixer", "QUIN_TDM_TX_7", "QUIN_TDM_TX_7"}, + {"QUIN_TDM_RX_7", NULL, "QUIN_TDM_RX_7 Port Mixer"}, {"SEN_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"SEN_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, @@ -26432,6 +26447,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "QUIN_TDM_RX_1"}, {"BE_OUT", NULL, "QUIN_TDM_RX_2"}, {"BE_OUT", NULL, "QUIN_TDM_RX_3"}, + {"BE_OUT", NULL, "QUIN_TDM_RX_7"}, {"BE_OUT", NULL, "SEN_TDM_RX_0"}, {"BE_OUT", NULL, "SEN_TDM_RX_1"}, {"BE_OUT", NULL, "SEN_TDM_RX_2"}, @@ -26523,6 +26539,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_TX_1", NULL, "BE_IN"}, {"QUIN_TDM_TX_2", NULL, "BE_IN"}, {"QUIN_TDM_TX_3", NULL, "BE_IN"}, + {"QUIN_TDM_TX_7", NULL, "BE_IN"}, {"SEN_TDM_TX_0", NULL, "BE_IN"}, {"SEN_TDM_TX_1", NULL, "BE_IN"}, {"SEN_TDM_TX_2", NULL, "BE_IN"}, -- GitLab From 6bd4088d76cfd7ab0ab79994a41a8bf6da60eab1 Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Tue, 16 Jul 2019 11:07:14 +0530 Subject: [PATCH 1108/1645] dsp: adm: Obtain path type from session type In programable channel mixer, path type is derived based on afe port id. Due to this, wrong path type is obtained in case of loopback usecase where Rx port is used to capture ec ref signals. This leads to wrong channel map being set in channel mixer. Instead use session type to obtain path type. Change-Id: I5292ed5eed1366ac28d72e4ca0815ab62e91fa60 Signed-off-by: Chaithanya Krishna Bacharaju --- dsp/q6adm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 29bf67fdc0d2..160814075333 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -42,6 +42,8 @@ #define DS2_ADM_COPP_TOPOLOGY_ID 0xFFFFFFFF #endif +#define SESSION_TYPE_RX 0 + /* ENUM for adm_status */ enum adm_cal_status { ADM_STATUS_CALIBRATION_REQUIRED = 0, @@ -573,7 +575,7 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, adm_pspd_params[3] = ch_mixer->input_channels[channel_index]; index = 4; - path_type = (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) ? + path_type = (session_type == SESSION_TYPE_RX) ? ADM_PATH_PLAYBACK : ADM_PATH_LIVE_REC; if (ch_mixer->override_out_ch_map) { -- GitLab From 1b99e47834d061675cd528816404fb3be460205a Mon Sep 17 00:00:00 2001 From: Han Lu Date: Sun, 9 Jun 2019 16:03:21 +0800 Subject: [PATCH 1109/1645] ASoC: sa8155: add quin tdm tx_7 to rx_7 loopback Add Quinary TDM TX 7 to RX 7 AFE loopback routing support for SA8155. Change-Id: I1e1858c9069277101ed6d826d0fca988dc4b276b Signed-off-by: Han Lu --- asoc/sa8155.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 4 deletions(-) diff --git a/asoc/sa8155.c b/asoc/sa8155.c index 26b744b9a891..907df324e86d 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -422,7 +422,7 @@ static unsigned int tdm_rx_slot_offset {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {28, 0xFFFF}, } }; @@ -477,7 +477,7 @@ static unsigned int tdm_tx_slot_offset {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {20, 0xFFFF}, } }; @@ -538,7 +538,7 @@ static unsigned int tdm_rx_slot_offset_custom {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {0, 0xFFFF}, } }; @@ -592,7 +592,7 @@ static unsigned int tdm_tx_slot_offset_custom {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {0, 0xFFFF}, } }; @@ -4329,6 +4329,14 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_3].sample_rate; break; + case AFE_PORT_ID_QUINARY_TDM_RX_7: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_7].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_7].sample_rate; + break; case AFE_PORT_ID_QUINARY_TDM_TX: channels->min = channels->max = tdm_tx_cfg[TDM_QUIN][TDM_0].channels; @@ -4361,6 +4369,14 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = tdm_tx_cfg[TDM_QUIN][TDM_3].sample_rate; break; + case AFE_PORT_ID_QUINARY_TDM_TX_7: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_7].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_7].sample_rate; + break; default: pr_err("%s: dai id 0x%x not supported\n", __func__, cpu_dai->id); @@ -4631,6 +4647,11 @@ static int sa8155_tdm_snd_hw_params(struct snd_pcm_substream *substream, slot_width = tdm_slot[TDM_QUIN].width; slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_3]; break; + case AFE_PORT_ID_QUINARY_TDM_RX_7: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_7]; + break; case AFE_PORT_ID_QUINARY_TDM_TX: slots = tdm_slot[TDM_QUIN].num; slot_width = tdm_slot[TDM_QUIN].width; @@ -4651,6 +4672,11 @@ static int sa8155_tdm_snd_hw_params(struct snd_pcm_substream *substream, slot_width = tdm_slot[TDM_QUIN].width; slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_3]; break; + case AFE_PORT_ID_QUINARY_TDM_TX_7: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_7]; + break; default: pr_err("%s: dai id 0x%x not supported\n", __func__, cpu_dai->id); @@ -5799,6 +5825,36 @@ static struct snd_soc_dai_link msm_auto_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, + { + .name = "Quinary TDM RX 7 Hostless", + .stream_name = "Quinary TDM RX 7 Hostless", + .cpu_dai_name = "QUIN_TDM_RX_7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Quinary TDM TX 7 Hostless", + .stream_name = "Quinary TDM TX 7 Hostless", + .cpu_dai_name = "QUIN_TDM_TX_7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, }; static struct snd_soc_dai_link msm_custom_fe_dai_links[] = { @@ -6660,6 +6716,34 @@ static struct snd_soc_dai_link msm_auto_be_dai_links[] = { .ops = &sa8155_tdm_be_ops, .ignore_suspend = 1, }, + { + .name = LPASS_BE_QUIN_TDM_RX_7, + .stream_name = "Quinary TDM7 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36942", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_RX_7, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_TDM_TX_7, + .stream_name = "Quinary TDM7 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36943", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_TX_7, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &sa8155_tdm_be_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link ext_disp_be_dai_link[] = { -- GitLab From 875812d38554aa29cab9d8b2e538d845360ec9bf Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 5 Jul 2019 17:07:27 +0530 Subject: [PATCH 1110/1645] ASoC: wcd937x: Fix spurious interrupts for wcd937x Enabling watchdog interrupt during bind causes spurious interrupts. Disable interrupts during bind and enable during path setup to fix this. Also enable and disable interrupt for ear pa for wcd938x. Change-Id: I4a9526d7b0a63f5325cec6dfe7a4e302ae76fc40 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x.c | 30 ++++++++++++++++++++++++++---- asoc/codecs/wcd938x/wcd938x.c | 12 ++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index ef9b20abc606..1c583ed49ee9 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -688,8 +688,12 @@ static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX2 << 0x10)); + wcd_enable_irq(&wcd937x->irq_info, + WCD937X_IRQ_HPHR_PDM_WD_INT); break; case SND_SOC_DAPM_PRE_PMD: + wcd_disable_irq(&wcd937x->irq_info, + WCD937X_IRQ_HPHR_PDM_WD_INT); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -783,8 +787,12 @@ static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX1 << 0x10)); + wcd_enable_irq(&wcd937x->irq_info, + WCD937X_IRQ_HPHL_PDM_WD_INT); break; case SND_SOC_DAPM_PRE_PMD: + wcd_disable_irq(&wcd937x->irq_info, + WCD937X_IRQ_HPHL_PDM_WD_INT); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -855,8 +863,10 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX3 << 0x10)); + wcd_enable_irq(&wcd937x->irq_info, WCD937X_IRQ_AUX_PDM_WD_INT); break; case SND_SOC_DAPM_PRE_PMD: + wcd_disable_irq(&wcd937x->irq_info, WCD937X_IRQ_AUX_PDM_WD_INT); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -923,8 +933,20 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX1 << 0x10)); + if (wcd937x->ear_rx_path & EAR_RX_PATH_AUX) + wcd_enable_irq(&wcd937x->irq_info, + WCD937X_IRQ_AUX_PDM_WD_INT); + else + wcd_enable_irq(&wcd937x->irq_info, + WCD937X_IRQ_HPHL_PDM_WD_INT); break; case SND_SOC_DAPM_PRE_PMD: + if (wcd937x->ear_rx_path & EAR_RX_PATH_AUX) + wcd_disable_irq(&wcd937x->irq_info, + WCD937X_IRQ_AUX_PDM_WD_INT); + else + wcd_disable_irq(&wcd937x->irq_info, + WCD937X_IRQ_HPHL_PDM_WD_INT); if (wcd937x->update_wcd_event) wcd937x->update_wcd_event(wcd937x->handle, WCD_BOLERO_EVT_RX_MUTE, @@ -2849,10 +2871,10 @@ static int wcd937x_bind(struct device *dev) "HPHL PDM WD INT", wcd937x_wd_handle_irq, NULL); wcd_request_irq(&wcd937x->irq_info, WCD937X_IRQ_AUX_PDM_WD_INT, "AUX PDM WD INT", wcd937x_wd_handle_irq, NULL); - /* Enable watchdog interrupt for HPH and AUX */ - wcd_enable_irq(&wcd937x->irq_info, WCD937X_IRQ_HPHR_PDM_WD_INT); - wcd_enable_irq(&wcd937x->irq_info, WCD937X_IRQ_HPHL_PDM_WD_INT); - wcd_enable_irq(&wcd937x->irq_info, WCD937X_IRQ_AUX_PDM_WD_INT); + /* Disable watchdog interrupt for HPH and AUX */ + wcd_disable_irq(&wcd937x->irq_info, WCD937X_IRQ_HPHR_PDM_WD_INT); + wcd_disable_irq(&wcd937x->irq_info, WCD937X_IRQ_HPHL_PDM_WD_INT); + wcd_disable_irq(&wcd937x->irq_info, WCD937X_IRQ_AUX_PDM_WD_INT); ret = snd_soc_register_component(dev, &soc_codec_dev_wcd937x, NULL, 0); diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index f3a31cae8624..aa89ab896752 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -960,8 +960,20 @@ static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX1 << 0x10)); + if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) + wcd_enable_irq(&wcd938x->irq_info, + WCD938X_IRQ_AUX_PDM_WD_INT); + else + wcd_enable_irq(&wcd938x->irq_info, + WCD938X_IRQ_HPHL_PDM_WD_INT); break; case SND_SOC_DAPM_PRE_PMD: + if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) + wcd_disable_irq(&wcd938x->irq_info, + WCD938X_IRQ_AUX_PDM_WD_INT); + else + wcd_disable_irq(&wcd938x->irq_info, + WCD938X_IRQ_HPHL_PDM_WD_INT); if (wcd938x->update_wcd_event) wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_MUTE, -- GitLab From f3bb8188ef0d1e71bf036c5caf05e328ffff4437 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 11 Jul 2019 14:38:54 -0700 Subject: [PATCH 1111/1645] asoc: codecs: bolero: add headphones equalizer dai Add a dai to get capture data which can be used for headphones equalizer purpose. Change-Id: Idc29faa54810be8cb2564c5c771c59ccf981a458 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/tx-macro.c | 53 +++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index bc5b056b03ec..08c185380350 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -82,6 +82,7 @@ enum { TX_MACRO_AIF_INVALID = 0, TX_MACRO_AIF1_CAP, TX_MACRO_AIF2_CAP, + TX_MACRO_AIF3_CAP, TX_MACRO_MAX_DAIS }; @@ -869,6 +870,7 @@ static int tx_macro_get_channel_map(struct snd_soc_dai *dai, switch (dai->id) { case TX_MACRO_AIF1_CAP: case TX_MACRO_AIF2_CAP: + case TX_MACRO_AIF3_CAP: *tx_slot = tx_priv->active_ch_mask[dai->id]; *tx_num = tx_priv->active_ch_cnt[dai->id]; break; @@ -913,6 +915,20 @@ static struct snd_soc_dai_driver tx_macro_dai[] = { }, .ops = &tx_macro_dai_ops, }, + { + .name = "tx_macro_tx3", + .id = TX_MACRO_AIF3_CAP, + .capture = { + .stream_name = "TX_AIF3 Capture", + .rates = TX_MACRO_RATES, + .formats = TX_MACRO_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 8, + }, + .ops = &tx_macro_dai_ops, + }, }; #define STRING(name) #name @@ -1064,6 +1080,25 @@ static const struct snd_kcontrol_new tx_aif2_cap_mixer[] = { tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), }; +static const struct snd_kcontrol_new tx_aif3_cap_mixer[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), +}; + static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0, SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0), @@ -1071,12 +1106,18 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("TX_AIF2 CAP", "TX_AIF2 Capture", 0, SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0), + SND_SOC_DAPM_AIF_OUT("TX_AIF3 CAP", "TX_AIF3 Capture", 0, + SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0), + SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0, tx_aif1_cap_mixer, ARRAY_SIZE(tx_aif1_cap_mixer)), SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0, tx_aif2_cap_mixer, ARRAY_SIZE(tx_aif2_cap_mixer)), + SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0, + tx_aif3_cap_mixer, ARRAY_SIZE(tx_aif3_cap_mixer)), + TX_MACRO_DAPM_MUX("TX DMIC MUX0", 0, tx_dmic0), TX_MACRO_DAPM_MUX("TX DMIC MUX1", 0, tx_dmic1), @@ -1207,9 +1248,11 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = { static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX_AIF1 CAP", NULL, "TX_MCLK"}, {"TX_AIF2 CAP", NULL, "TX_MCLK"}, + {"TX_AIF3 CAP", NULL, "TX_MCLK"}, {"TX_AIF1 CAP", NULL, "TX_AIF1_CAP Mixer"}, {"TX_AIF2 CAP", NULL, "TX_AIF2_CAP Mixer"}, + {"TX_AIF3 CAP", NULL, "TX_AIF3_CAP Mixer"}, {"TX_AIF1_CAP Mixer", "DEC0", "TX DEC0 MUX"}, {"TX_AIF1_CAP Mixer", "DEC1", "TX DEC1 MUX"}, @@ -1229,6 +1272,15 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX_AIF2_CAP Mixer", "DEC6", "TX DEC6 MUX"}, {"TX_AIF2_CAP Mixer", "DEC7", "TX DEC7 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC0", "TX DEC0 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC1", "TX DEC1 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC2", "TX DEC2 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC3", "TX DEC3 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC4", "TX DEC4 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC5", "TX DEC5 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC6", "TX DEC6 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC7", "TX DEC7 MUX"}, + {"TX DEC0 MUX", NULL, "TX_MCLK"}, {"TX DEC1 MUX", NULL, "TX_MCLK"}, {"TX DEC2 MUX", NULL, "TX_MCLK"}, @@ -1784,6 +1836,7 @@ static int tx_macro_init(struct snd_soc_component *component) snd_soc_dapm_ignore_suspend(dapm, "TX_AIF1 Capture"); snd_soc_dapm_ignore_suspend(dapm, "TX_AIF2 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "TX_AIF3 Capture"); snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC0"); snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC1"); snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC2"); -- GitLab From 2176abc150789e84721ccd2cb79bce246e3eb939 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 11 Jul 2019 14:41:05 -0700 Subject: [PATCH 1112/1645] asoc: kona: add headphones equalizer dai link Add a dai link to get capture data from codec which can be used for headphones equalizer purpose. Change-Id: I65181e2991a14cf7bccbe8c738b0d782f6b185b2 Signed-off-by: Karthikeyan Mani --- asoc/kona.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/asoc/kona.c b/asoc/kona.c index a8a64b216cc2..2c7671be1f28 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -5699,6 +5699,19 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, + {/* hw:x,39 */ + .name = LPASS_BE_TX_CDC_DMA_TX_5, + .stream_name = "TX CDC DMA5 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45115", + .platform_name = "msm-pcm-hostless", + .codec_name = "bolero_codec", + .codec_dai_name = "tx_macro_tx3", + .id = MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_cdc_dma_be_ops, + }, }; static struct snd_soc_dai_link msm_common_be_dai_links[] = { -- GitLab From 06f43418bfba8fdb09d250a05831543c5b501556 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 9 Jul 2019 03:32:54 +0530 Subject: [PATCH 1113/1645] soc: soundwire: Avoid wakeup after clock pause Unlock mutex for soundwire bank switch to process the interrupt before clock pause and request for clock switch to switch the soundwire clock source. Change-Id: Idea4306a0e326864431e7cf956044383bf1790db Signed-off-by: Sudheer Papothi --- include/soc/swr-wcd.h | 3 +- soc/swr-mstr-ctrl.c | 85 +++++++++++++++++++++++++++++++------------ 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/include/soc/swr-wcd.h b/include/soc/swr-wcd.h index ad129c832700..25c5339b3195 100644 --- a/include/soc/swr-wcd.h +++ b/include/soc/swr-wcd.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2015, 2017-2019 The Linux Foundation. All rights reserved. */ #ifndef _LINUX_SWR_WCD_H @@ -21,6 +21,7 @@ enum { SWR_DEVICE_SSR_UP, SWR_REGISTER_WAKE_IRQ, SWR_SET_PORT_MAP, + SWR_REQ_CLK_SWITCH, }; struct swr_mstr_port { diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 30c1f14c416f..acc42a55a194 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1527,13 +1527,15 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) } if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { ret = IRQ_NONE; - goto exit; + goto err_audio_hw_vote; } swrm_clk_request(swrm, true); mutex_unlock(&swrm->reslock); intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); intr_sts_masked = intr_sts & swrm->intr_mask; + + dev_dbg(swrm->dev, "%s: status: 0x%x \n", __func__, intr_sts_masked); handle_irq: for (i = 0; i < SWRM_INTERRUPT_MAX; i++) { value = intr_sts_masked & (1 << i); @@ -1690,13 +1692,16 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) intr_sts_masked = intr_sts & swrm->intr_mask; if (intr_sts_masked) { - dev_dbg(swrm->dev, "%s: new interrupt received\n", __func__); + dev_dbg(swrm->dev, "%s: new interrupt received 0x%x\n", + __func__, intr_sts_masked); goto handle_irq; } mutex_lock(&swrm->reslock); swrm_clk_request(swrm, false); swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); + +err_audio_hw_vote: swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); exit: mutex_unlock(&swrm->reslock); @@ -2203,6 +2208,28 @@ static int swrm_probe(struct platform_device *pdev) for (i = 0 ; i < SWR_MSTR_PORT_LEN; i++) INIT_LIST_HEAD(&swrm->mport_cfg[i].port_req_list); + /* Register LPASS core hw vote */ + lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote"); + if (IS_ERR(lpass_core_hw_vote)) { + ret = PTR_ERR(lpass_core_hw_vote); + dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", + __func__, "lpass_core_hw_vote", ret); + lpass_core_hw_vote = NULL; + ret = 0; + } + swrm->lpass_core_hw_vote = lpass_core_hw_vote; + + /* Register LPASS audio core vote */ + lpass_core_audio = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote"); + if (IS_ERR(lpass_core_audio)) { + ret = PTR_ERR(lpass_core_audio); + dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", + __func__, "lpass_core_audio", ret); + lpass_core_audio = NULL; + ret = 0; + } + swrm->lpass_core_audio = lpass_core_audio; + if (swrm->reg_irq) { ret = swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, SWR_IRQ_REGISTER); @@ -2267,28 +2294,6 @@ static int swrm_probe(struct platform_device *pdev) if (pdev->dev.of_node) of_register_swr_devices(&swrm->master); - /* Register LPASS core hw vote */ - lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote"); - if (IS_ERR(lpass_core_hw_vote)) { - ret = PTR_ERR(lpass_core_hw_vote); - dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", - __func__, "lpass_core_hw_vote", ret); - lpass_core_hw_vote = NULL; - ret = 0; - } - swrm->lpass_core_hw_vote = lpass_core_hw_vote; - - /* Register LPASS audio core vote */ - lpass_core_audio = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote"); - if (IS_ERR(lpass_core_audio)) { - ret = PTR_ERR(lpass_core_audio); - dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", - __func__, "lpass_core_audio", ret); - lpass_core_audio = NULL; - ret = 0; - } - swrm->lpass_core_audio = lpass_core_audio; - dbgswrm = swrm; debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0); if (!IS_ERR(debugfs_swrm_dent)) { @@ -2507,7 +2512,9 @@ static int swrm_runtime_suspend(struct device *dev) goto exit; } if (!swrm->clk_stop_mode0_supp || swrm->state == SWR_MSTR_SSR) { + mutex_unlock(&swrm->reslock); enable_bank_switch(swrm, 0, SWR_ROW_50, SWR_MIN_COL); + mutex_lock(&swrm->reslock); swrm_clk_pause(swrm); swr_master_write(swrm, SWRM_COMP_CFG_ADDR, 0x00); list_for_each_entry(swr_dev, &mstr->devices, dev_list) { @@ -2558,6 +2565,25 @@ static int swrm_runtime_suspend(struct device *dev) } #endif /* CONFIG_PM */ +static int swrm_device_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); + int ret = 0; + + dev_dbg(dev, "%s: swrm state: %d\n", __func__, swrm->state); + if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) { + ret = swrm_runtime_suspend(dev); + if (!ret) { + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + pm_runtime_enable(dev); + } + } + + return 0; +} + static int swrm_device_down(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -2694,6 +2720,17 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) mstr = &swrm->master; switch (id) { + case SWR_REQ_CLK_SWITCH: + /* This will put soundwire in clock stop mode and disable the + * clocks, if there is no active usecase running, so that the + * next activity on soundwire will request clock from new clock + * source. + */ + mutex_lock(&swrm->mlock); + if (swrm->state == SWR_MSTR_UP) + swrm_device_suspend(&pdev->dev); + mutex_unlock(&swrm->mlock); + break; case SWR_CLK_FREQ: if (!data) { dev_err(swrm->dev, "%s: data is NULL\n", __func__); -- GitLab From 380e08eeac628195c7fb6c171b689e4513316752 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 7 Jun 2019 15:53:21 +0530 Subject: [PATCH 1114/1645] dsp: adsp-loader: load adsp based on nvmem idx Load different adsp images based on nvmem property of sku variants. Read fw image name mapped to nvmem property's value and load it based on sku variant. Change-Id: I99ffe171ec8c42c0ee9e148f171c557353d72910 Signed-off-by: Aditya Bavanari --- dsp/adsp-loader.c | 107 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 101 insertions(+), 6 deletions(-) diff --git a/dsp/adsp-loader.c b/dsp/adsp-loader.c index 881e3604e7de..ef9d92db7535 100644 --- a/dsp/adsp-loader.c +++ b/dsp/adsp-loader.c @@ -13,13 +13,16 @@ #include #include #include - +#include +#include #include #define Q6_PIL_GET_DELAY_MS 100 #define BOOT_CMD 1 #define SSR_RESET_CMD 1 #define IMAGE_UNLOAD_CMD 0 +#define MAX_FW_IMAGES 4 +#define ADSP_FW_NAME_MAX_LENGTH 5 static ssize_t adsp_boot_store(struct kobject *kobj, struct kobj_attribute *attr, @@ -33,6 +36,7 @@ struct adsp_loader_private { void *pil_h; struct kobject *boot_adsp_obj; struct attribute_group *attr_group; + char *adsp_fw_name; }; static struct kobj_attribute adsp_boot_attribute = @@ -55,7 +59,6 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work) { struct platform_device *pdev = adsp_private; struct adsp_loader_private *priv = NULL; - const char *adsp_dt = "qcom,adsp-state"; int rc = 0; u32 adsp_state; @@ -118,6 +121,7 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work) dev_dbg(&pdev->dev, "%s: Q6/MDSP image is loaded\n", __func__); return; } + load_adsp: { adsp_state = apr_get_q6_state(); @@ -128,8 +132,16 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work) " %s: Private data get failed\n", __func__); goto fail; } + if (!priv->adsp_fw_name) { + dev_dbg(&pdev->dev, "%s: Load default ADSP\n", + __func__); + priv->pil_h = subsystem_get("adsp"); + } else { + dev_dbg(&pdev->dev, "%s: Load ADSP with fw name %s\n", + __func__, priv->adsp_fw_name); + priv->pil_h = subsystem_get_with_fwname("adsp", priv->adsp_fw_name); + } - priv->pil_h = subsystem_get("adsp"); if (IS_ERR(priv->pil_h)) { dev_err(&pdev->dev, "%s: pil get failed,\n", __func__); @@ -310,16 +322,99 @@ static int adsp_loader_remove(struct platform_device *pdev) static int adsp_loader_probe(struct platform_device *pdev) { - int ret = adsp_loader_init_sysfs(pdev); - + struct adsp_loader_private *priv = NULL; + struct nvmem_cell *cell; + ssize_t len; + u32 *buf; + const char **adsp_fw_name_array = NULL; + int adsp_fw_cnt; + u32* adsp_fw_bit_values = NULL; + int i; + u32 adsp_var_idx; + int ret = 0; + + ret = adsp_loader_init_sysfs(pdev); if (ret != 0) { dev_err(&pdev->dev, "%s: Error in initing sysfs\n", __func__); return ret; } - INIT_WORK(&adsp_ldr_work, adsp_load_fw); + priv = platform_get_drvdata(pdev); + /* get adsp variant idx */ + cell = nvmem_cell_get(&pdev->dev, "adsp_variant"); + if (IS_ERR_OR_NULL(cell)) { + dev_dbg(&pdev->dev, "%s: FAILED to get nvmem cell \n", __func__); + goto wqueue; + } + buf = nvmem_cell_read(cell, &len); + nvmem_cell_put(cell); + if (IS_ERR_OR_NULL(buf)) { + dev_dbg(&pdev->dev, "%s: FAILED to read nvmem cell \n", __func__); + goto wqueue; + } + adsp_var_idx = (*buf); + kfree(buf); + + /* Get count of fw images */ + adsp_fw_cnt = of_property_count_strings(pdev->dev.of_node, + "adsp-fw-names"); + if (adsp_fw_cnt <= 0 || adsp_fw_cnt > MAX_FW_IMAGES) { + dev_dbg(&pdev->dev, "%s: Invalid number of fw images %d", + __func__, adsp_fw_cnt); + goto wqueue; + } + + adsp_fw_bit_values = devm_kzalloc(&pdev->dev, + adsp_fw_cnt * sizeof(u32), GFP_KERNEL); + if (!adsp_fw_bit_values) + goto wqueue; + + /* Read bit values corresponding to each firmware image entry */ + ret = of_property_read_u32_array(pdev->dev.of_node, + "adsp-fw-bit-values", + adsp_fw_bit_values, + adsp_fw_cnt); + if (ret) { + dev_dbg(&pdev->dev, "%s: unable to read fw-bit-values\n", + __func__); + goto wqueue; + } + adsp_fw_name_array = devm_kzalloc(&pdev->dev, + adsp_fw_cnt * sizeof(char *), GFP_KERNEL); + if (!adsp_fw_name_array) + goto wqueue; + + /* Read ADSP firmware image names */ + ret = of_property_read_string_array(pdev->dev.of_node, + "adsp-fw-names", + adsp_fw_name_array, + adsp_fw_cnt); + if (ret < 0) { + dev_dbg(&pdev->dev, "%s: unable to read fw-names\n", + __func__); + goto wqueue; + } + + for (i = 0; i < adsp_fw_cnt; i++) { + if (adsp_fw_bit_values[i] == adsp_var_idx) { + priv->adsp_fw_name = devm_kzalloc(&pdev->dev, + ADSP_FW_NAME_MAX_LENGTH, GFP_KERNEL); + if (!priv->adsp_fw_name) + goto wqueue; + strlcpy(priv->adsp_fw_name, adsp_fw_name_array[i], + sizeof(priv->adsp_fw_name)); + break; + } + } +wqueue: + INIT_WORK(&adsp_ldr_work, adsp_load_fw); + if (adsp_fw_bit_values) + devm_kfree(&pdev->dev, adsp_fw_bit_values); + if (adsp_fw_name_array) + devm_kfree(&pdev->dev, adsp_fw_name_array); return 0; + } static const struct of_device_id adsp_loader_dt_match[] = { -- GitLab From 93b9262f701d48f96e77a2333a71fdb3141fc8cf Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 24 Jul 2019 14:45:19 +0800 Subject: [PATCH 1115/1645] asoc: routing: add routings for SEC MI2S TX Add routings for SEC_MI2S_TX and Voicecall/VOIP to reduce audio log during bootup. Change-Id: I368ab9782f14ccf99114994fe6c2dd42fee5d59a Signed-off-by: Meng Wang --- asoc/msm-pcm-routing-v2.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index f1afd538965d..57c0ed4e30b8 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -15509,6 +15509,9 @@ static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -15526,7 +15529,7 @@ static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("QUAT_TDM_TX_0_MMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, @@ -15605,6 +15608,9 @@ static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_MI2S_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -15707,6 +15713,10 @@ static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), SOC_DOUBLE_EXT("TERT_MI2S_TX_Voip", SND_SOC_NOPM, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, @@ -25894,6 +25904,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode1_Tx Mixer", "PRI_TX_MMode1", "PRI_I2S_TX"}, {"VoiceMMode1_Tx Mixer", "PRI_MI2S_TX_MMode1", "PRI_MI2S_TX"}, {"VoiceMMode1_Tx Mixer", "MI2S_TX_MMode1", "MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "SEC_MI2S_TX_MMode1", "SEC_MI2S_TX"}, {"VoiceMMode1_Tx Mixer", "TERT_MI2S_TX_MMode1", "TERT_MI2S_TX"}, {"VoiceMMode1_Tx Mixer", "INT3_MI2S_TX_MMode1", "INT3_MI2S_TX"}, {"VoiceMMode1_Tx Mixer", "SLIM_0_TX_MMode1", "SLIMBUS_0_TX"}, @@ -25922,6 +25933,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode2_Tx Mixer", "PRI_TX_MMode2", "PRI_I2S_TX"}, {"VoiceMMode2_Tx Mixer", "PRI_MI2S_TX_MMode2", "PRI_MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "SEC_MI2S_TX_MMode2", "SEC_MI2S_TX"}, {"VoiceMMode2_Tx Mixer", "MI2S_TX_MMode2", "MI2S_TX"}, {"VoiceMMode2_Tx Mixer", "TERT_MI2S_TX_MMode2", "TERT_MI2S_TX"}, {"VoiceMMode2_Tx Mixer", "INT3_MI2S_TX_MMode2", "INT3_MI2S_TX"}, @@ -25950,6 +25962,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"}, {"Voip_Tx Mixer", "MI2S_TX_Voip", "MI2S_TX"}, + {"Voip_Tx Mixer", "SEC_MI2S_TX_Voip", "SEC_MI2S_TX"}, {"Voip_Tx Mixer", "TERT_MI2S_TX_Voip", "TERT_MI2S_TX"}, {"Voip_Tx Mixer", "INT3_MI2S_TX_Voip", "INT3_MI2S_TX"}, {"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"}, -- GitLab From 48003fde1ab2f3bdf6276b02a3d78823ff073f4a Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 17 Jul 2019 16:25:08 +0530 Subject: [PATCH 1116/1645] ASoC: wcd-mbhc: Fix high impedance lineout detected as headphone issue During playback if lineout is inserted it is detected as lineout then changed to headphone. This is because we do not compute impedance again as pa is on. Force jack to be detected as lineout based on initial detection to resolve the issue. Change-Id: I243c324dcd251596db97aeef07b8535986550650 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd-mbhc-v2.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 6a85c8232770..624b59af069e 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -655,7 +655,6 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, SND_JACK_LINEOUT | SND_JACK_ANC_HEADPHONE | SND_JACK_UNSUPPORTED); - mbhc->force_linein = false; } if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET && @@ -714,6 +713,25 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, } } + /* Do not calculate impedance again for lineout + * as during playback pa is on and impedance values + * will not be correct resulting in lineout detected + * as headphone. + */ + if ((is_pa_on) && mbhc->force_linein == true) { + jack_type = SND_JACK_LINEOUT; + mbhc->current_plug = MBHC_PLUG_TYPE_HIGH_HPH; + if (mbhc->hph_status) { + mbhc->hph_status &= ~(SND_JACK_HEADSET | + SND_JACK_LINEOUT | + SND_JACK_UNSUPPORTED); + wcd_mbhc_jack_report(mbhc, + &mbhc->headset_jack, + mbhc->hph_status, + WCD_MBHC_JACK_MASK); + } + } + mbhc->hph_status |= jack_type; pr_debug("%s: Reporting insertion %d(%x)\n", __func__, -- GitLab From 6cc7f52a6def45a332438209a9ee6804fa515a32 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 28 Jun 2019 11:04:03 +0530 Subject: [PATCH 1117/1645] ASoC: bolero: tx-macro: Fix clock sequence for headset SVA Fix soundwire clock sequence for headset SVA usecase to avoid tx clock voting during low power SVA usecase. Change-Id: I9613eee6a0b66560fa1108b4887af71507d345e7 Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/bolero-cdc.c | 39 +++++++++++++++++++++++++++++++-- asoc/codecs/bolero/bolero-cdc.h | 8 +++++++ asoc/codecs/bolero/tx-macro.c | 31 ++++++++++++++++++++++++++ asoc/codecs/bolero/va-macro.c | 10 +++++++-- 4 files changed, 84 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index c0c51ca5826b..b7de34698375 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -501,8 +501,10 @@ int bolero_register_macro(struct device *dev, u16 macro_id, priv->macro_params[macro_id].dev = dev; priv->current_mclk_mux_macro[macro_id] = bolero_mclk_mux_tbl[macro_id][MCLK_MUX0]; - if (macro_id == TX_MACRO) + if (macro_id == TX_MACRO) { priv->macro_params[macro_id].reg_wake_irq = ops->reg_wake_irq; + priv->macro_params[macro_id].clk_switch = ops->clk_switch; + } priv->num_dais += ops->num_dais; priv->num_macros_registered++; @@ -562,8 +564,10 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) priv->macro_params[macro_id].dai_ptr = NULL; priv->macro_params[macro_id].event_handler = NULL; priv->macro_params[macro_id].dev = NULL; - if (macro_id == TX_MACRO) + if (macro_id == TX_MACRO) { priv->macro_params[macro_id].reg_wake_irq = NULL; + priv->macro_params[macro_id].clk_switch = NULL; + } priv->num_dais -= priv->macro_params[macro_id].num_dais; priv->num_macros_registered--; @@ -768,6 +772,37 @@ int bolero_register_wake_irq(struct snd_soc_component *component, } EXPORT_SYMBOL(bolero_register_wake_irq); +/** + * bolero_tx_clk_switch - Switch tx macro clock + * + * @component: pointer to codec component instance. + * + * Returns 0 on success or -EINVAL on error. + */ +int bolero_tx_clk_switch(struct snd_soc_component *component) +{ + struct bolero_priv *priv = NULL; + int ret = 0; + + if (!component) + return -EINVAL; + + priv = snd_soc_component_get_drvdata(component); + if (!priv) + return -EINVAL; + + if (!bolero_is_valid_codec_dev(priv->dev)) { + dev_err(component->dev, "%s: invalid codec\n", __func__); + return -EINVAL; + } + + if (priv->macro_params[TX_MACRO].clk_switch) + ret = priv->macro_params[TX_MACRO].clk_switch(component); + + return ret; +} +EXPORT_SYMBOL(bolero_tx_clk_switch); + static int bolero_soc_codec_probe(struct snd_soc_component *component) { struct bolero_priv *priv = dev_get_drvdata(component->dev); diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 362b521849af..7e8ec83266b6 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -55,6 +55,7 @@ struct macro_ops { int (*reg_wake_irq)(struct snd_soc_component *component, u32 data); int (*set_port_map)(struct snd_soc_component *component, u32 uc, u32 size, void *data); + int (*clk_switch)(struct snd_soc_component *component); char __iomem *io_base; u16 clk_id_req; u16 default_clk_id; @@ -78,6 +79,7 @@ void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n); int bolero_runtime_resume(struct device *dev); int bolero_runtime_suspend(struct device *dev); int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *data); +int bolero_tx_clk_switch(struct snd_soc_component *component); #else static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb) { @@ -136,5 +138,11 @@ static inline int bolero_set_port_map(struct snd_soc_component *component, { return 0; } + +static inline int bolero_tx_clk_switch(struct snd_soc_component *component) +{ + return 0; +} + #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index bc5b056b03ec..6bb113044890 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1608,6 +1608,36 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, return ret; } +static int tx_macro_clk_switch(struct snd_soc_component *component) +{ + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + int ret = 0; + + if (!component) + return -EINVAL; + + tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO); + if (!tx_dev) { + dev_err(component->dev, + "%s: null device for macro!\n", __func__); + return -EINVAL; + } + tx_priv = dev_get_drvdata(tx_dev); + if (!tx_priv) { + dev_err(component->dev, + "%s: priv is null for macro!\n", __func__); + return -EINVAL; + } + if (tx_priv->swr_ctrl_data) { + ret = swrm_wcd_notify( + tx_priv->swr_ctrl_data[0].tx_swr_pdev, + SWR_REQ_CLK_SWITCH, NULL); + } + + return ret; +} + static int tx_macro_swrm_clock(void *handle, bool enable) { struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle; @@ -1971,6 +2001,7 @@ static void tx_macro_init_ops(struct macro_ops *ops, ops->event_handler = tx_macro_event_handler; ops->reg_wake_irq = tx_macro_reg_wake_irq; ops->set_port_map = tx_macro_set_port_map; + ops->clk_switch = tx_macro_clk_switch; } static int tx_macro_probe(struct platform_device *pdev) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 8e5abaa3c7d4..d4dd4e6e6188 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -283,8 +283,14 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, "%s: lpass audio hw enable failed\n", __func__); } + if (!ret) + if (bolero_tx_clk_switch(component)) + dev_dbg(va_dev, "%s: clock switch failed\n", + __func__); break; case SND_SOC_DAPM_POST_PMD: + if (bolero_tx_clk_switch(component)) + dev_dbg(va_dev, "%s: clock switch failed\n",__func__); if (va_priv->lpass_audio_hw_vote) clk_disable_unprepare(va_priv->lpass_audio_hw_vote); break; @@ -311,18 +317,18 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, dev_dbg(va_dev, "%s: event = %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - ret = va_macro_mclk_enable(va_priv, 1, true); ret = bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, TX_CORE_CLK, true); + ret = va_macro_mclk_enable(va_priv, 1, true); break; case SND_SOC_DAPM_POST_PMD: + va_macro_mclk_enable(va_priv, 0, true); bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, TX_CORE_CLK, false); - va_macro_mclk_enable(va_priv, 0, true); break; default: dev_err(va_priv->dev, -- GitLab From 55a43129295f354267471097a1a0e11b936cf8b2 Mon Sep 17 00:00:00 2001 From: "P.V. Phani Kumar" Date: Sat, 20 Jul 2019 16:20:33 +0530 Subject: [PATCH 1118/1645] Initial target enablement changes for bengal. Change-Id: I7296e39fcedd9ecec5bb788ac3706b297ac8d6d7 --- Android.mk | 4 ++-- asoc/Android.mk | 2 +- asoc/codecs/Android.mk | 2 +- asoc/codecs/bolero/Android.mk | 2 +- asoc/codecs/wcd938x/Android.mk | 2 +- dsp/Android.mk | 2 +- dsp/codecs/Android.mk | 2 +- ipc/Android.mk | 2 +- soc/Android.mk | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Android.mk b/Android.mk index 41f14b30a59c..d9c5089be06c 100644 --- a/Android.mk +++ b/Android.mk @@ -3,7 +3,7 @@ MY_LOCAL_PATH := $(call my-dir) UAPI_OUT := $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/include -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal),true) $(shell mkdir -p $(UAPI_OUT)/linux;) $(shell mkdir -p $(UAPI_OUT)/sound;) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers) @@ -46,7 +46,7 @@ $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codec include $(MY_LOCAL_PATH)/asoc/codecs/wcd937x/Android.mk endif -ifeq ($(call is-board-platform-in-list, kona lito),true) +ifeq ($(call is-board-platform-in-list, kona lito bengal),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/bolero/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/bolero/Android.mk $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd938x/Module.symvers) diff --git a/asoc/Android.mk b/asoc/Android.mk index 1fb172a5d92c..0d582115d321 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -34,7 +34,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index 9e58936febe8..a3b7e15278a1 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -29,7 +29,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/bolero/Android.mk b/asoc/codecs/bolero/Android.mk index cf51a44f0bac..9d1274f8e6dc 100644 --- a/asoc/codecs/bolero/Android.mk +++ b/asoc/codecs/bolero/Android.mk @@ -17,7 +17,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona lito),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona lito bengal),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wcd938x/Android.mk b/asoc/codecs/wcd938x/Android.mk index 96fb6f569701..49aa2d43f5b3 100644 --- a/asoc/codecs/wcd938x/Android.mk +++ b/asoc/codecs/wcd938x/Android.mk @@ -13,7 +13,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,kona lito),true) +ifeq ($(call is-board-platform-in-list,kona lito bengal),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/Android.mk b/dsp/Android.mk index 9119ea434292..ac79abab1fc4 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -25,7 +25,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/codecs/Android.mk b/dsp/codecs/Android.mk index 65507176ceca..2a4482e68f03 100644 --- a/dsp/codecs/Android.mk +++ b/dsp/codecs/Android.mk @@ -21,7 +21,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal),true) LOCAL_PATH := $(call my-dir) diff --git a/ipc/Android.mk b/ipc/Android.mk index 4c582f02e336..7a2325fd0072 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -25,7 +25,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal),true) LOCAL_PATH := $(call my-dir) diff --git a/soc/Android.mk b/soc/Android.mk index 0bd740322fdc..90ccda1b5309 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -21,7 +21,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal),true) LOCAL_PATH := $(call my-dir) -- GitLab From 765eaabf249c3cbb79ee7a9abc06ae149a86c608 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 18 Jul 2019 16:27:01 -0700 Subject: [PATCH 1119/1645] asoc: codecs: bolero: enable button click suppression block Enable bcs block for recording use cases to reduce glitches caused by button events or plug removal events on the record path. Change-Id: I7a8556178a196c03009cdc487aff5424d5e1787a Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/tx-macro.c | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index bc5b056b03ec..100d7e02efa5 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -161,6 +161,7 @@ struct tx_macro_priv { int va_swr_clk_cnt; int va_clk_status; int tx_clk_status; + bool bcs_enable; }; static bool tx_macro_get_data(struct snd_soc_component *component, @@ -583,6 +584,38 @@ static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, return 0; } +static int tx_macro_get_bcs(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tx_macro_priv *tx_priv = NULL; + struct device *tx_dev = NULL; + + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = tx_priv->bcs_enable; + + return 0; +} + +static int tx_macro_set_bcs(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tx_macro_priv *tx_priv = NULL; + struct device *tx_dev = NULL; + int value = ucontrol->value.integer.value[0]; + + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + tx_priv->bcs_enable = value; + + return 0; +} static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -744,6 +777,12 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, snd_soc_component_write(component, tx_gain_ctl_reg, snd_soc_component_read32(component, tx_gain_ctl_reg)); + if (tx_priv->bcs_enable) { + snd_soc_component_update_bits(component, dec_cfg_reg, + 0x01, 0x01); + snd_soc_component_update_bits(component, + BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x40); + } break; case SND_SOC_DAPM_PRE_PMD: hpf_cut_off_freq = @@ -778,6 +817,12 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, 0x20, 0x00); snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x00); + if (tx_priv->bcs_enable) { + snd_soc_component_update_bits(component, dec_cfg_reg, + 0x01, 0x00); + snd_soc_component_update_bits(component, + BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x00); + } break; } return 0; @@ -1464,6 +1509,9 @@ static const struct snd_kcontrol_new tx_macro_snd_controls[] = { SOC_SINGLE_SX_TLV("TX_DEC7 Volume", BOLERO_CDC_TX7_TX_VOL_CTL, 0, -84, 40, digital_gain), + + SOC_SINGLE_EXT("DEC0_BCS Switch", SND_SOC_NOPM, 0, 1, 0, + tx_macro_get_bcs, tx_macro_set_bcs), }; static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, @@ -1813,6 +1861,8 @@ static int tx_macro_init(struct snd_soc_component *component) } tx_priv->component = component; + snd_soc_component_update_bits(component, + BOLERO_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x0E); return 0; } -- GitLab From ec3bb4045ce118290d764f1ecdf34ae926994666 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 18 Jul 2019 16:31:30 -0700 Subject: [PATCH 1120/1645] asoc: codecs: enable bcs port for headset record Enable button click suppression port to send mbhc events over the port to reduce glitches caused by button events or plug removal events on the record path. Change-Id: I3f913ab1287f06afe6b5fc95da626f7c78ab448f Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd937x/wcd937x.c | 12 ++++++++++++ asoc/codecs/wcd938x/wcd938x.c | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index ef9b20abc606..39bce8d09925 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -46,6 +46,7 @@ enum { ALLOW_BUCK_DISABLE, HPH_COMP_DELAY, HPH_PA_DELAY, + AMIC2_BCS_ENABLE, }; static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); @@ -1283,10 +1284,21 @@ static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x08); snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); + /* Enable BCS for Headset mic */ + if (w->shift == 1 && !(snd_soc_component_read32(component, + WCD937X_TX_NEW_TX_CH2_SEL) & 0x80)) { + wcd937x_tx_connect_port(codec, MBHC, true); + set_bit(AMIC2_BCS_ENABLE, &wcd937x->status_mask); + } wcd937x_tx_connect_port(component, ADC1 + (w->shift), true); break; case SND_SOC_DAPM_POST_PMD: wcd937x_tx_connect_port(component, ADC1 + (w->shift), false); + if (w->shift == 1 && + test_bit(AMIC2_BCS_ENABLE, &wcd937x->status_mask)) { + wcd937x_tx_connect_port(codec, MBHC, false); + clear_bit(AMIC2_BCS_ENABLE, &wcd937x->status_mask); + } snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00); break; diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index a5c4c94b2262..ab93e08468f8 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -57,6 +57,7 @@ enum { ALLOW_BUCK_DISABLE, HPH_COMP_DELAY, HPH_PA_DELAY, + AMIC2_BCS_ENABLE, }; enum { @@ -1406,10 +1407,21 @@ static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w, break; } set_bit(w->shift, &wcd938x->status_mask); + /* Enable BCS for Headset mic */ + if (w->shift == 1 && !(snd_soc_component_read32(component, + WCD938X_TX_NEW_AMIC_MUX_CFG) & 0x80)) { + wcd938x_tx_connect_port(component, MBHC, true); + set_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask); + } wcd938x_tx_connect_port(component, ADC1 + (w->shift), true); break; case SND_SOC_DAPM_POST_PMD: wcd938x_tx_connect_port(component, ADC1 + (w->shift), false); + if (w->shift == 1 && + test_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask)) { + wcd938x_tx_connect_port(component, MBHC, false); + clear_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask); + } snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00); clear_bit(w->shift, &wcd938x->status_mask); -- GitLab From 25175a9c42ffa91614f2a455d5394aaadd0835d9 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 24 Jul 2019 12:48:18 +0530 Subject: [PATCH 1121/1645] ASoC: Add delay before impedance detection for wcd937x and wcd938x 1ms delay is needed for impedance detection after disabling hph surge. Add delay for wcd937x and wcd938x. Change-Id: I515fa0ca66562c91cb4aacb87cb7394122aa1c10 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x-mbhc.c | 2 ++ asoc/codecs/wcd938x/wcd938x-mbhc.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index cec70e7ff302..72ca24936fef 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -552,6 +552,8 @@ static void wcd937x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, */ regmap_update_bits(wcd937x->regmap, WCD937X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0x00); + /* 1ms delay needed after disable surge protection */ + usleep_range(1000, 1010); /* First get impedance on Left */ d1 = d1_a[1]; diff --git a/asoc/codecs/wcd938x/wcd938x-mbhc.c b/asoc/codecs/wcd938x/wcd938x-mbhc.c index 9c49755935f9..f93e9b90ac15 100644 --- a/asoc/codecs/wcd938x/wcd938x-mbhc.c +++ b/asoc/codecs/wcd938x/wcd938x-mbhc.c @@ -552,6 +552,8 @@ static void wcd938x_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, */ regmap_update_bits(wcd938x->regmap, WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0x00); + /* 1ms delay needed after disable surge protection */ + usleep_range(1000, 1010); /* First get impedance on Left */ d1 = d1_a[1]; -- GitLab From 8269fcd509f8194f61aa241368992f166c1eb5bd Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 24 Jul 2019 20:03:50 -0700 Subject: [PATCH 1122/1645] asoc: codecs: wcd938x: remove delays in headphone power down Delays in headphone power down path can be removed and without any click and pop issues. This way it reduces headphone power down time. Change-Id: Iedfbbee7d2be27cc5dfc62c9def72e7be81d7eaf Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/wcd938x.c | 58 +++++++++++++++-------------------- 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index a5c4c94b2262..4d659ba0cfe4 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -669,28 +669,25 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, WCD938X_IRQ_HPHR_PDM_WD_INT); break; case SND_SOC_DAPM_PRE_PMD: - wcd_disable_irq(&wcd938x->irq_info, - WCD938X_IRQ_HPHR_PDM_WD_INT); if (wcd938x->update_wcd_event) wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX2 << 0x10 | 0x1)); - if (wcd938x->update_wcd_event) + wcd_disable_irq(&wcd938x->irq_info, + WCD938X_IRQ_HPHR_PDM_WD_INT); + if (wcd938x->update_wcd_event && wcd938x->comp2_enable) wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST, (WCD_RX2 << 0x10)); - /* 7 msec delay as per HW requirement */ - usleep_range(7000, 7100); - if (wcd938x->update_wcd_event) - wcd938x->update_wcd_event(wcd938x->handle, - WCD_BOLERO_EVT_RX_MUTE, - (WCD_RX2 << 0x10 | 0x0)); - /* 20 msec delay as per HW requirement */ - usleep_range(21000, 21100); - if (wcd938x->update_wcd_event) - wcd938x->update_wcd_event(wcd938x->handle, - WCD_BOLERO_EVT_RX_MUTE, - (WCD_RX2 << 0x10 | 0x1)); + /* + * 7ms sleep is required if compander is enabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is required. + */ + if (!wcd938x->comp2_enable) + usleep_range(20000, 20100); + else + usleep_range(7000, 7100); snd_soc_component_update_bits(component, WCD938X_ANA_HPH, 0x40, 0x00); blocking_notifier_call_chain(&wcd938x->mbhc->notifier, @@ -716,8 +713,6 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, &wcd938x->mbhc->wcd_mbhc); snd_soc_component_update_bits(component, WCD938X_ANA_HPH, 0x10, 0x00); - /* 20 msec delay as per HW requirement */ - usleep_range(20000, 20100); snd_soc_component_update_bits(component, WCD938X_DIGITAL_PDM_WD_CTL1, 0x17, 0x00); wcd_cls_h_fsm(component, &wcd938x->clsh_info, @@ -791,28 +786,25 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, WCD938X_IRQ_HPHL_PDM_WD_INT); break; case SND_SOC_DAPM_PRE_PMD: - wcd_disable_irq(&wcd938x->irq_info, - WCD938X_IRQ_HPHL_PDM_WD_INT); if (wcd938x->update_wcd_event) wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX1 << 0x10 | 0x1)); - if (wcd938x->update_wcd_event) + wcd_disable_irq(&wcd938x->irq_info, + WCD938X_IRQ_HPHL_PDM_WD_INT); + if (wcd938x->update_wcd_event && wcd938x->comp1_enable) wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST, (WCD_RX1 << 0x10)); - /* 7 msec delay as per HW requirement */ - usleep_range(7000, 7100); - if (wcd938x->update_wcd_event) - wcd938x->update_wcd_event(wcd938x->handle, - WCD_BOLERO_EVT_RX_MUTE, - (WCD_RX1 << 0x10 | 0x0)); - /* 20 msec delay as per HW requirement */ - usleep_range(21000, 21100); - if (wcd938x->update_wcd_event) - wcd938x->update_wcd_event(wcd938x->handle, - WCD_BOLERO_EVT_RX_MUTE, - (WCD_RX1 << 0x10 | 0x1)); + /* + * 7ms sleep is required if compander is enabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is required. + */ + if (!wcd938x->comp1_enable) + usleep_range(20000, 20100); + else + usleep_range(7000, 7100); snd_soc_component_update_bits(component, WCD938X_ANA_HPH, 0x80, 0x00); blocking_notifier_call_chain(&wcd938x->mbhc->notifier, @@ -838,8 +830,6 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, &wcd938x->mbhc->wcd_mbhc); snd_soc_component_update_bits(component, WCD938X_ANA_HPH, 0x20, 0x00); - /* 20 msec delay as per HW requirement */ - usleep_range(21000, 21100); snd_soc_component_update_bits(component, WCD938X_DIGITAL_PDM_WD_CTL0, 0x17, 0x00); wcd_cls_h_fsm(component, &wcd938x->clsh_info, -- GitLab From 6bd895ef4b86dbb7aa910b8bb71eb56ea482a44f Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 26 Jul 2019 15:34:50 -0700 Subject: [PATCH 1123/1645] asoc: codecs: bolero: increase hpf cut off frequency time Increase hpf corner cut off frequency call back time to sustain 150Hz cut off for a longer time to avoid DC noise coming to the decimators during a record session. Change-Id: I5aa4f4c38a5dfd84655995217fdfc1708713c178 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/tx-macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index bc5b056b03ec..8cb50c3e8ebd 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -730,7 +730,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, CF_MIN_3DB_150HZ) { schedule_delayed_work( &tx_priv->tx_hpf_work[decimator].dwork, - msecs_to_jiffies(50)); + msecs_to_jiffies(300)); snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x02); /* -- GitLab From f86a355548694f86453e0518ad83b10771a2199b Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 11 Jul 2019 15:46:25 -0700 Subject: [PATCH 1124/1645] asoc: add multi stream support for display port Add support to share a common display afe port between two pcm streams. Add mixer controls to set/get format, channels, sample rate and configure controller/stream for display port 1. Change-Id: Ie8fb95d57fba129e623c7513ec92dd800b5ea80b Signed-off-by: Vignesh Kulothungan --- asoc/codecs/msm_hdmi_codec_rx.c | 152 ++++++++++++++++++++++---------- asoc/kona.c | 20 ++++- asoc/msm-dai-q6-hdmi-v2.c | 93 ++++++++++++++++--- asoc/msm-dai-q6-v2.h | 5 +- asoc/msm-pcm-routing-v2.c | 1 + 5 files changed, 206 insertions(+), 65 deletions(-) diff --git a/asoc/codecs/msm_hdmi_codec_rx.c b/asoc/codecs/msm_hdmi_codec_rx.c index 04117c8366b2..8d2507e461e7 100644 --- a/asoc/codecs/msm_hdmi_codec_rx.c +++ b/asoc/codecs/msm_hdmi_codec_rx.c @@ -43,8 +43,12 @@ enum { DP_STREAM_MAX, }; +/* + * Dai id cannot be zero, if component has more than one dai and dai id + * is used to differentiate between them + */ enum { - DP_DAI1 = 0, + DP_DAI1 = 1, DP_DAI2, HDMI_DAI, DP_DAI_MAX, @@ -54,16 +58,16 @@ static const char *const ext_disp_audio_type_text[] = {"None", "HDMI", "DP"}; static const char *const ext_disp_audio_ack_text[] = {"Disconnect", "Connect", "Ack_Enable"}; -SOC_EXT_DISP_AUDIO_TYPE(0); -SOC_EXT_DISP_AUDIO_ACK_STATE(0); SOC_EXT_DISP_AUDIO_TYPE(1); SOC_EXT_DISP_AUDIO_ACK_STATE(1); +SOC_EXT_DISP_AUDIO_TYPE(2); +SOC_EXT_DISP_AUDIO_ACK_STATE(2); struct msm_ext_disp_audio_codec_rx_data { struct platform_device *ext_disp_core_pdev; struct msm_ext_disp_audio_codec_ops ext_disp_ops; - int cable_status; struct mutex dp_ops_lock; + int cable_status[DP_DAI_MAX]; int stream[DP_DAI_MAX]; int ctl[DP_DAI_MAX]; }; @@ -80,25 +84,25 @@ static int msm_ext_disp_edid_ctl_info(struct snd_kcontrol *kcontrol, int dai_id = kcontrol->private_value; codec_data = snd_soc_component_get_drvdata(component); - if (!codec_data) { dev_err(component->dev, "%s: codec_data is NULL\n", __func__); return -EINVAL; } + dev_dbg(component->dev, "%s: DP ctl id %d Stream id %d\n", __func__, + codec_data->ctl[dai_id], codec_data->stream[dai_id]); + + mutex_lock(&codec_data->dp_ops_lock); + SWITCH_DP_CODEC(codec_info, codec_data, dai_id); if (!codec_data->ext_disp_ops.get_audio_edid_blk) { dev_dbg(component->dev, "%s: get_audio_edid_blk() is NULL\n", __func__); uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; uinfo->count = 0; - return 0; + mutex_unlock(&codec_data->dp_ops_lock); + return -EINVAL; } - dev_dbg(component->dev, "%s: DP ctl id %d Stream id %d\n", __func__, - codec_data->ctl[dai_id], codec_data->stream[dai_id]); - - mutex_lock(&codec_data->dp_ops_lock); - SWITCH_DP_CODEC(codec_info, codec_data, dai_id); rc = codec_data->ext_disp_ops.get_audio_edid_blk( codec_data->ext_disp_core_pdev, &edid_blk); mutex_unlock(&codec_data->dp_ops_lock); @@ -124,8 +128,8 @@ static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol, int dai_id = kcontrol->private_value; codec_data = snd_soc_component_get_drvdata(component); - if (!codec_data || !codec_data->ext_disp_ops.get_audio_edid_blk) { - dev_err(component->dev, "%s: codec_data or get_audio_edid_blk() is NULL\n", + if (!codec_data) { + dev_err(component->dev, "%s: codec_data is NULL\n", __func__); return -EINVAL; } @@ -135,6 +139,13 @@ static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol, mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai_id); + if (!codec_data->ext_disp_ops.get_audio_edid_blk) { + dev_err(component->dev, "%s: codec_data or get_audio_edid_blk() is NULL\n", + __func__); + mutex_unlock(&codec_data->dp_ops_lock); + return -EINVAL; + } + rc = codec_data->ext_disp_ops.get_audio_edid_blk( codec_data->ext_disp_core_pdev, &edid_blk); mutex_unlock(&codec_data->dp_ops_lock); @@ -177,10 +188,8 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l; codec_data = snd_soc_component_get_drvdata(component); - if (!codec_data || - !codec_data->ext_disp_ops.get_audio_edid_blk || - !codec_data->ext_disp_ops.get_intf_id) { - dev_err(component->dev, "%s: codec_data, get_audio_edid_blk() or get_intf_id is NULL\n", + if (!codec_data) { + dev_err(component->dev, "%s: codec_data is NULL\n", __func__); return -EINVAL; } @@ -190,6 +199,15 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai_id); + + if (!codec_data->ext_disp_ops.get_audio_edid_blk || + !codec_data->ext_disp_ops.get_intf_id) { + dev_err(component->dev, "%s: get_audio_edid_blk() or get_intf_id is NULL\n", + __func__); + rc = -EINVAL; + goto cable_err; + } + cable_state = codec_data->ext_disp_ops.cable_status( codec_data->ext_disp_core_pdev, 1); if (cable_state < 0) { @@ -199,7 +217,7 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, goto cable_err; } - codec_data->cable_status = cable_state; + codec_data->cable_status[dai_id] = cable_state; if (cable_state == EXT_DISPLAY_CABLE_DISCONNECT) { dev_err(component->dev, "%s: Display cable disconnected\n", __func__); @@ -254,18 +272,27 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l; codec_data = snd_soc_component_get_drvdata(component); - if (!codec_data || - !codec_data->ext_disp_ops.acknowledge) { + if (!codec_data) { dev_err(component->dev, - "%s: codec_data or ops acknowledge() is NULL\n", + "%s: codec_data is NULL\n", __func__); - rc = -EINVAL; - goto done; + return -EINVAL; } dev_dbg(component->dev, "%s: DP ctl id %d Stream id %d\n", __func__, codec_data->ctl[dai_id], codec_data->stream[dai_id]); + mutex_lock(&codec_data->dp_ops_lock); + SWITCH_DP_CODEC(codec_info, codec_data, dai_id); + + if (!codec_data->ext_disp_ops.acknowledge) { + dev_err(component->dev, + "%s: codec_data ops acknowledge() is NULL\n", + __func__); + rc = -EINVAL; + goto err; + } + switch (ucontrol->value.enumerated.item[0]) { case 0: ack_state = AUD_EXT_DISP_ACK_DISCONNECT; @@ -281,13 +308,11 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, dev_err(component->dev, "%s: invalid value %d for mixer ctl\n", __func__, ucontrol->value.enumerated.item[0]); - goto done; + goto err; } dev_dbg(component->dev, "%s: control %d, ack set value 0x%x\n", __func__, ucontrol->value.enumerated.item[0], ack_state); - mutex_lock(&codec_data->dp_ops_lock); - SWITCH_DP_CODEC(codec_info, codec_data, dai_id); rc = codec_data->ext_disp_ops.acknowledge( codec_data->ext_disp_core_pdev, ack_state); mutex_unlock(&codec_data->dp_ops_lock); @@ -295,8 +320,10 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, dev_err(component->dev, "%s: error from acknowledge(), err:%d\n", __func__, rc); } + return rc; -done: +err: + mutex_unlock(&codec_data->dp_ops_lock); return rc; } @@ -407,16 +434,16 @@ static const struct snd_kcontrol_new msm_ext_disp_codec_rx_controls[] = { .private_value = DP_DAI2, }, SOC_ENUM_EXT("External Display Type", - ext_disp_audio_type0, + ext_disp_audio_type1, msm_ext_disp_audio_type_get, NULL), SOC_ENUM_EXT("External Display1 Type", - ext_disp_audio_type1, + ext_disp_audio_type2, msm_ext_disp_audio_type_get, NULL), SOC_ENUM_EXT("External Display Audio Ack", - ext_disp_audio_ack_state0, + ext_disp_audio_ack_state1, NULL, msm_ext_disp_audio_ack_set), SOC_ENUM_EXT("External Display1 Audio Ack", - ext_disp_audio_ack_state1, + ext_disp_audio_ack_state2, NULL, msm_ext_disp_audio_ack_set), SOC_SINGLE_MULTI_EXT("External Display Audio Device", @@ -438,8 +465,8 @@ static int msm_ext_disp_audio_codec_rx_dai_startup( struct msm_ext_disp_audio_codec_rx_data *codec_data = dev_get_drvdata(dai->component->dev); - if (!codec_data || !codec_data->ext_disp_ops.cable_status) { - dev_err(dai->dev, "%s() codec_data or cable_status is null\n", + if (!codec_data) { + dev_err(dai->dev, "%s() codec_data is null\n", __func__); return -EINVAL; } @@ -450,19 +477,27 @@ static int msm_ext_disp_audio_codec_rx_dai_startup( mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai->id); - codec_data->cable_status = + + if (!codec_data->ext_disp_ops.cable_status) { + dev_err(dai->dev, "%s() cable_status is null\n", + __func__); + mutex_unlock(&codec_data->dp_ops_lock); + return -EINVAL; + } + + codec_data->cable_status[dai->id] = codec_data->ext_disp_ops.cable_status( codec_data->ext_disp_core_pdev, 1); mutex_unlock(&codec_data->dp_ops_lock); - if (codec_data->cable_status < 0) { + if (codec_data->cable_status[dai->id] < 0) { dev_err(dai->dev, "%s() ext disp core is not ready (ret val = %d)\n", - __func__, codec_data->cable_status); - ret = codec_data->cable_status; - } else if (!codec_data->cable_status) { + __func__, codec_data->cable_status[dai->id]); + ret = codec_data->cable_status[dai->id]; + } else if (!codec_data->cable_status[dai->id]) { dev_err(dai->dev, "%s() ext disp cable is not connected (ret val = %d)\n", - __func__, codec_data->cable_status); + __func__, codec_data->cable_status[dai->id]); ret = -ENODEV; } @@ -485,8 +520,8 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params( struct msm_ext_disp_audio_codec_rx_data *codec_data = dev_get_drvdata(dai->component->dev); - if (!codec_data || !codec_data->ext_disp_ops.audio_info_setup) { - dev_err(dai->dev, "%s: codec_data or audio_info_setup is null\n", + if (!codec_data) { + dev_err(dai->dev, "%s() codec_data is null\n", __func__); return -EINVAL; } @@ -495,15 +530,26 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params( __func__, codec_data->ctl[dai->id], codec_data->stream[dai->id]); - if (codec_data->cable_status < 0) { + mutex_lock(&codec_data->dp_ops_lock); + SWITCH_DP_CODEC(codec_info, codec_data, dai->id); + + if (!codec_data->ext_disp_ops.audio_info_setup) { + dev_err(dai->dev, "%s: audio_info_setup is null\n", + __func__); + mutex_unlock(&codec_data->dp_ops_lock); + return -EINVAL; + } + mutex_unlock(&codec_data->dp_ops_lock); + + if (codec_data->cable_status[dai->id] < 0) { dev_err_ratelimited(dai->dev, "%s() ext disp core is not ready (ret val = %d)\n", - __func__, codec_data->cable_status); - return codec_data->cable_status; - } else if (!codec_data->cable_status) { + __func__, codec_data->cable_status[dai->id]); + return codec_data->cable_status[dai->id]; + } else if (!codec_data->cable_status[dai->id]) { dev_err_ratelimited(dai->dev, "%s() ext disp cable is not connected (ret val = %d)\n", - __func__, codec_data->cable_status); + __func__, codec_data->cable_status[dai->id]); return -ENODEV; } @@ -576,9 +622,8 @@ static void msm_ext_disp_audio_codec_rx_dai_shutdown( struct msm_ext_disp_audio_codec_rx_data *codec_data = dev_get_drvdata(dai->component->dev); - if (!codec_data || !codec_data->ext_disp_ops.teardown_done || - !codec_data->ext_disp_ops.cable_status) { - dev_err(dai->dev, "%s: codec data or teardown_done or cable_status is null\n", + if (!codec_data) { + dev_err(dai->dev, "%s() codec_data is null\n", __func__); return; } @@ -589,6 +634,15 @@ static void msm_ext_disp_audio_codec_rx_dai_shutdown( mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai->id); + + if (!codec_data->ext_disp_ops.teardown_done || + !codec_data->ext_disp_ops.cable_status) { + dev_err(dai->dev, "%s: teardown_done or cable_status is null\n", + __func__); + mutex_unlock(&codec_data->dp_ops_lock); + return; + } + rc = codec_data->ext_disp_ops.cable_status( codec_data->ext_disp_core_pdev, 0); if (rc < 0) { diff --git a/asoc/kona.c b/asoc/kona.c index bd9dc28ab677..6b825a8a617e 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -178,6 +178,7 @@ struct tdm_port { enum { EXT_DISP_RX_IDX_DP = 0, + EXT_DISP_RX_IDX_DP1, EXT_DISP_RX_IDX_MAX, }; @@ -210,6 +211,7 @@ static struct dev_config slim_tx_cfg[] = { /* Default configuration of external display BE */ static struct dev_config ext_disp_rx_cfg[] = { [EXT_DISP_RX_IDX_DP] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [EXT_DISP_RX_IDX_DP1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, }; static struct dev_config usb_rx_cfg = { @@ -1135,6 +1137,9 @@ static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol) if (strnstr(kcontrol->id.name, "Display Port RX", sizeof("Display Port RX"))) { idx = EXT_DISP_RX_IDX_DP; + } else if (strnstr(kcontrol->id.name, "Display Port1 RX", + sizeof("Display Port1 RX"))) { + idx = EXT_DISP_RX_IDX_DP1; } else { pr_err("%s: unsupported BE: %s\n", __func__, kcontrol->id.name); @@ -3658,6 +3663,13 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, ext_disp_rx_sample_rate_get, ext_disp_rx_sample_rate_put), + SOC_ENUM_EXT("Display Port1 RX Channels", ext_disp_rx_chs, + ext_disp_rx_ch_get, ext_disp_rx_ch_put), + SOC_ENUM_EXT("Display Port1 RX Bit Format", ext_disp_rx_format, + ext_disp_rx_format_get, ext_disp_rx_format_put), + SOC_ENUM_EXT("Display Port1 RX SampleRate", ext_disp_rx_sample_rate, + ext_disp_rx_sample_rate_get, + ext_disp_rx_sample_rate_put), SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, msm_bt_sample_rate_get, msm_bt_sample_rate_put), @@ -3694,6 +3706,9 @@ static int msm_ext_disp_get_idx_from_beid(int32_t be_id) case MSM_BACKEND_DAI_DISPLAY_PORT_RX: idx = EXT_DISP_RX_IDX_DP; break; + case MSM_BACKEND_DAI_DISPLAY_PORT_RX_1: + idx = EXT_DISP_RX_IDX_DP1; + break; default: pr_err("%s: Incorrect ext_disp BE id %d\n", __func__, be_id); idx = -EINVAL; @@ -3756,6 +3771,7 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + case MSM_BACKEND_DAI_DISPLAY_PORT_RX_1: idx = msm_ext_disp_get_idx_from_beid(dai_link->id); if (idx < 0) { pr_err("%s: Incorrect ext disp idx %d\n", @@ -6106,7 +6122,7 @@ static struct snd_soc_dai_link ext_disp_be_dai_link[] = { { .name = LPASS_BE_DISPLAY_PORT, .stream_name = "Display Port Playback", - .cpu_dai_name = "msm-dai-q6-dp.24608", + .cpu_dai_name = "msm-dai-q6-dp.0", .platform_name = "msm-pcm-routing", .codec_name = "msm-ext-disp-audio-codec-rx", .codec_dai_name = "msm_dp_audio_codec_rx_dai", @@ -6121,7 +6137,7 @@ static struct snd_soc_dai_link ext_disp_be_dai_link[] = { { .name = LPASS_BE_DISPLAY_PORT1, .stream_name = "Display Port1 Playback", - .cpu_dai_name = "msm-dai-q6-dp.24608", + .cpu_dai_name = "msm-dai-q6-dp.1", .platform_name = "msm-pcm-routing", .codec_name = "msm-ext-disp-audio-codec-rx", .codec_dai_name = "msm_dp_audio_codec_rx1_dai", diff --git a/asoc/msm-dai-q6-hdmi-v2.c b/asoc/msm-dai-q6-hdmi-v2.c index 80164f325e5d..664169bd8bf2 100644 --- a/asoc/msm-dai-q6-hdmi-v2.c +++ b/asoc/msm-dai-q6-hdmi-v2.c @@ -51,6 +51,15 @@ struct msm_dai_q6_hdmi_dai_data { union afe_port_config port_config; }; +static int get_port_id(int dai_id) +{ + /* Currently, display devices share a common AFE port */ + if (dai_id != HDMI_RX) + return DISPLAY_PORT_RX; + + return dai_id; +} + static int msm_dai_q6_ext_disp_format_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -198,10 +207,10 @@ static int msm_dai_q6_ext_disp_drift_get(struct snd_kcontrol *kcontrol, } memset(&timing_stats, 0, sizeof(struct afe_param_id_dev_timing_stats)); - ret = afe_get_av_dev_drift(&timing_stats, dai->id); + ret = afe_get_av_dev_drift(&timing_stats, get_port_id(dai->id)); if (ret) { pr_err("%s: Error getting AFE Drift for port %d, err=%d\n", - __func__, dai->id, ret); + __func__, get_port_id(dai->id), ret); ret = -EINVAL; goto done; @@ -249,6 +258,24 @@ static const struct snd_kcontrol_new display_port_config_controls[] = { .info = msm_dai_q6_ext_disp_drift_info, .get = msm_dai_q6_ext_disp_drift_get, }, + SOC_ENUM_EXT("Display Port1 RX Format", hdmi_config_enum[0], + msm_dai_q6_ext_disp_format_get, + msm_dai_q6_ext_disp_format_put), + SOC_SINGLE_MULTI_EXT("Display Port1 RX CA", SND_SOC_NOPM, 0, + HDMI_RX_CA_MAX, 0, 1, + msm_dai_q6_ext_disp_ca_get, + msm_dai_q6_ext_disp_ca_put), + SOC_SINGLE_MULTI_EXT("Display Port1 RX DEVICE IDX", SND_SOC_NOPM, 0, + 1, 0, 2, + msm_dai_q6_ext_disp_device_idx_get, + msm_dai_q6_ext_disp_device_idx_put), + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "DISPLAY_PORT1 DRIFT", + .info = msm_dai_q6_ext_disp_drift_info, + .get = msm_dai_q6_ext_disp_drift_get, + }, }; /* Current implementation assumes hw_param is called once @@ -329,7 +356,7 @@ static void msm_dai_q6_hdmi_shutdown(struct snd_pcm_substream *substream, return; } - rc = afe_close(dai->id); /* can block */ + rc = afe_close(get_port_id(dai->id)); /* can block */ if (rc < 0) dev_err(dai->dev, "fail to close AFE port\n"); @@ -351,8 +378,7 @@ static int msm_dai_q6_hdmi_prepare(struct snd_pcm_substream *substream, dai_data->ca.ca; if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { - - rc = afe_set_display_stream(dai->id, dai_data->stream_idx, + rc = afe_set_display_stream(get_port_id(dai->id), dai_data->stream_idx, dai_data->ctl_idx); if (rc < 0) { dev_err(dai->dev, "fail to set AFE ctl, stream ID params %x\n", @@ -363,11 +389,11 @@ static int msm_dai_q6_hdmi_prepare(struct snd_pcm_substream *substream, } } - rc = afe_port_start(dai->id, &dai_data->port_config, + rc = afe_port_start(get_port_id(dai->id), &dai_data->port_config, dai_data->rate); if (rc < 0) dev_err(dai->dev, "fail to open AFE port %x\n", - dai->id); + get_port_id(dai->id)); else set_bit(STATUS_PORT_STARTED, dai_data->status_mask); @@ -422,7 +448,7 @@ static int msm_dai_q6_hdmi_dai_probe(struct snd_soc_dai *dai) kcontrol = &hdmi_config_controls[2]; rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(kcontrol, dai)); - } else if (dai->driver->id == DISPLAY_PORT_RX) { + } else if (dai->driver->id == MSM_DISPLAY_PORT) { kcontrol = &display_port_config_controls[0]; rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(kcontrol, dai_data)); @@ -438,6 +464,22 @@ static int msm_dai_q6_hdmi_dai_probe(struct snd_soc_dai *dai) kcontrol = &display_port_config_controls[3]; rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(kcontrol, dai)); + } else if (dai->driver->id == MSM_DISPLAY_PORT1) { + kcontrol = &display_port_config_controls[4]; + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(kcontrol, dai_data)); + + kcontrol = &display_port_config_controls[5]; + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(kcontrol, dai_data)); + + kcontrol = &display_port_config_controls[6]; + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(kcontrol, dai_data)); + + kcontrol = &display_port_config_controls[7]; + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(kcontrol, dai)); } else { dev_err(dai->dev, "%s: Invalid id:%d\n", __func__, dai->driver->id); @@ -482,7 +524,7 @@ static int msm_dai_q6_hdmi_dai_remove(struct snd_soc_dai *dai) /* If AFE port is still up, close it */ if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { - rc = afe_close(dai->id); /* can block */ + rc = afe_close(get_port_id(dai->id)); /* can block */ if (rc < 0) dev_err(dai->dev, "fail to close AFE port\n"); @@ -539,7 +581,28 @@ static struct snd_soc_dai_driver msm_dai_q6_display_port_rx_dai[] = { .rate_min = 48000, }, .ops = &msm_dai_q6_hdmi_ops, - .id = DISPLAY_PORT_RX, + .id = MSM_DISPLAY_PORT, + .probe = msm_dai_q6_hdmi_dai_probe, + .remove = msm_dai_q6_hdmi_dai_remove, + }, + { + .playback = { + .stream_name = "Display Port1 Playback", + .aif_name = "DISPLAY_PORT1", + .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .channels_min = 2, + .channels_max = 8, + .rate_max = 192000, + .rate_min = 48000, + }, + .ops = &msm_dai_q6_hdmi_ops, + .id = MSM_DISPLAY_PORT1, .probe = msm_dai_q6_hdmi_dai_probe, .remove = msm_dai_q6_hdmi_dai_remove, }, @@ -573,11 +636,15 @@ static int msm_dai_q6_hdmi_dev_probe(struct platform_device *pdev) &msm_dai_hdmi_q6_component, &msm_dai_q6_hdmi_hdmi_rx_dai, 1); break; - case DISPLAY_PORT_RX: + case MSM_DISPLAY_PORT: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_hdmi_q6_component, + &msm_dai_q6_display_port_rx_dai[0], 1); + break; + case MSM_DISPLAY_PORT1: rc = snd_soc_register_component(&pdev->dev, &msm_dai_hdmi_q6_component, - &msm_dai_q6_display_port_rx_dai[0], - ARRAY_SIZE(msm_dai_q6_display_port_rx_dai)); + &msm_dai_q6_display_port_rx_dai[1], 1); break; default: dev_err(&pdev->dev, "invalid device ID %d\n", pdev->id); diff --git a/asoc/msm-dai-q6-v2.h b/asoc/msm-dai-q6-v2.h index 950ecd2e91c7..b65e4e11d8be 100644 --- a/asoc/msm-dai-q6-v2.h +++ b/asoc/msm-dai-q6-v2.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, 2019 The Linux Foundation. All rights reserved. */ #ifndef __MSM_DAI_Q6_PDATA_H__ @@ -35,6 +35,9 @@ #define MSM_MI2S_MIN MSM_PRIM_MI2S #define MSM_MI2S_MAX MSM_INT6_MI2S +#define MSM_DISPLAY_PORT 0 +#define MSM_DISPLAY_PORT1 1 + struct msm_dai_auxpcm_config { u16 mode; u16 sync; diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index def95cef868e..d4cde4fd0fda 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -5459,6 +5459,7 @@ static const char *const ec_ref_rx[] = { "None", "SLIM_RX", "I2S_RX", "QUAT_TDM_RX_0", "QUAT_TDM_RX_1", "QUAT_TDM_RX_2", "SLIM_6_RX", "TERT_MI2S_RX", "QUAT_MI2S_RX", "TERT_TDM_TX_0", "USB_AUDIO_RX", "INT0_MI2S_RX", "INT4_MI2S_RX", "INT3_MI2S_TX", "DISPLAY_PORT", + "DISPLAY_PORT1", "WSA_CDC_DMA_RX_0", "WSA_CDC_DMA_RX_1", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_2", "SLIM_7_RX", "RX_CDC_DMA_RX_0", "RX_CDC_DMA_RX_1", "RX_CDC_DMA_RX_2", -- GitLab From 728c5cc45bee208c6cd3b69c82e49afe1e0e1b83 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Wed, 26 Jun 2019 14:21:52 -0700 Subject: [PATCH 1125/1645] ASoC: msm: add quat/quin tdm rx 7 routing support Add Quinary and Quaternary TDM RX 7 AFE loopback routing support. Change-Id: I39acbba68e2c05dab27d36be95469bcc30484ed3 Signed-off-by: Derek Chen --- asoc/msm-pcm-routing-v2.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 7baff1f0b2bb..f508cf5ea16d 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -18096,6 +18096,11 @@ static const struct snd_kcontrol_new quat_tdm_rx_7_port_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_TX_7, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_7, + MSM_BACKEND_DAI_QUIN_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_0_port_mixer_controls[] = { @@ -19083,6 +19088,16 @@ static const struct snd_kcontrol_new sen_tdm_rx_3_port_mixer_controls[] = { }; static const struct snd_kcontrol_new quin_tdm_rx_7_port_mixer_controls[] = { + SOC_DOUBLE_EXT("TERT_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_7, + MSM_BACKEND_DAI_TERT_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_7, + MSM_BACKEND_DAI_QUAT_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_DOUBLE_EXT("QUIN_TDM_TX_7", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_RX_7, MSM_BACKEND_DAI_QUIN_TDM_TX_7, 1, 0, @@ -25892,6 +25907,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Port Mixer"}, {"QUAT_TDM_RX_7 Port Mixer", "QUAT_TDM_TX_7", "QUAT_TDM_TX_7"}, + {"QUAT_TDM_RX_7 Port Mixer", "QUIN_TDM_TX_7", "QUIN_TDM_TX_7"}, {"QUAT_TDM_RX_7", NULL, "QUAT_TDM_RX_7 Port Mixer"}, {"QUIN_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -25997,6 +26013,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Port Mixer"}, + + {"QUIN_TDM_RX_7 Port Mixer", "TERT_TDM_TX_7", "TERT_TDM_TX_7"}, + {"QUIN_TDM_RX_7 Port Mixer", "QUAT_TDM_TX_7", "QUAT_TDM_TX_7"}, {"QUIN_TDM_RX_7 Port Mixer", "QUIN_TDM_TX_7", "QUIN_TDM_TX_7"}, {"QUIN_TDM_RX_7", NULL, "QUIN_TDM_RX_7 Port Mixer"}, -- GitLab From d76c27409988936def541c6cfd6ec0cc8ef95358 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 30 Jul 2019 05:09:58 +0530 Subject: [PATCH 1126/1645] ASoC: wcd938x: Fix micbias droop on WCD938x codec Fix micbias droop on WCD938x codec. Change-Id: I8df99dea118750134570c372fc153db9873f8827 Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd938x/wcd938x.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index f3a31cae8624..81fdca0603fa 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -176,6 +176,14 @@ static int wcd938x_init_reg(struct snd_soc_component *component) WCD938X_DIGITAL_TX_REQ_FB_CTL_3, 0xFF, 0x00); snd_soc_component_update_bits(component, WCD938X_DIGITAL_TX_REQ_FB_CTL_4, 0xFF, 0x00); + snd_soc_component_update_bits(component, + WCD938X_MICB1_TEST_CTL_1, 0xE0, 0xE0); + snd_soc_component_update_bits(component, + WCD938X_MICB2_TEST_CTL_1, 0xE0, 0xE0); + snd_soc_component_update_bits(component, + WCD938X_MICB3_TEST_CTL_1, 0xE0, 0xE0); + snd_soc_component_update_bits(component, + WCD938X_MICB4_TEST_CTL_1, 0xE0, 0xE0); return 0; } -- GitLab From f4d2412b31ae63e5268af047f233c1d54e47d1e4 Mon Sep 17 00:00:00 2001 From: Asish Bhattacharya Date: Tue, 30 Jul 2019 12:39:15 +0530 Subject: [PATCH 1127/1645] asoc: Add support for MultiMedia2 TX Add MultiMedia2 support for SEC_AUXPCM_TX. Change-Id: I4a653b3049ce790f314198a1e5ec7a65baa7ed5f Signed-off-by: Asish Bhattacharya --- asoc/msm-pcm-routing-v2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index def95cef868e..13ee0801f95b 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -11981,6 +11981,10 @@ static const struct snd_kcontrol_new mmul2_mixer_controls[] = { MSM_BACKEND_DAI_AFE_LOOPBACK_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul3_mixer_controls[] = { @@ -25114,6 +25118,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"MultiMedia10 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, {"MultiMedia1 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia2 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia3 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia5 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia10 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, -- GitLab From 3edeac14779c9e9a5a605dffebb754d19302cde0 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 30 Jul 2019 13:54:13 -0700 Subject: [PATCH 1128/1645] asoc: codecs: wcd938x: cleanup TX recording sequence Cleanup TX ADC recording path sequence to remove any legacy register writes which is not required anymore. Change-Id: I204280b1631b11fc275f765a2454bda4cec01b18 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/wcd938x.c | 107 +++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 47 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index ab93e08468f8..f2baead7cf96 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1359,7 +1359,6 @@ static int wcd938x_get_adc_mode(int val) static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event){ - int mode; struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); @@ -1369,43 +1368,10 @@ static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - mode = wcd938x_get_adc_mode(wcd938x->tx_mode[w->shift]); - if (mode < 0) { - dev_info(component->dev, - "%s: invalid mode, setting to normal mode\n", - __func__); - mode = ADC_MODE_VAL_NORMAL; - } - snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x80); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x08); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); - switch (w->shift) { - case 0: - snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1, 0x0F, - mode); - break; - case 1: - snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1, 0xF0, - mode << 4); - break; - case 2: - snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3, 0x0F, - mode); - break; - case 3: - snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3, 0xF0, - mode << 4); - break; - default: - break; - } set_bit(w->shift, &wcd938x->status_mask); /* Enable BCS for Headset mic */ if (w->shift == 1 && !(snd_soc_component_read32(component, @@ -1476,7 +1442,9 @@ static int wcd938x_enable_req(struct snd_soc_dapm_widget *w, { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + int mode; int ret = 0; + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -1488,25 +1456,70 @@ static int wcd938x_enable_req(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_REQ_CTL, 0x01, 0x00); ret = wcd938x_tx_channel_config(component, w->shift, 1); - snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x30, 0x30); - snd_soc_component_update_bits(component, - WCD938X_ANA_TX_CH1, 0x80, 0x80); - snd_soc_component_update_bits(component, - WCD938X_ANA_TX_CH2, 0x80, 0x80); + mode = wcd938x_get_adc_mode(wcd938x->tx_mode[w->shift]); + if (mode < 0) { + dev_info(component->dev, + "%s: invalid mode, setting to normal mode\n", + __func__); + mode = ADC_MODE_VAL_NORMAL; + } + switch (w->shift) { + case 0: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1, 0x0F, + mode); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x10, 0x10); + break; + case 1: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1, 0xF0, + mode << 4); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x20, 0x20); + break; + case 2: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3, 0x0F, + mode); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x40, 0x40); + break; + case 3: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3, 0xF0, + mode << 4); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x80); + break; + default: + break; + } ret |= wcd938x_tx_channel_config(component, w->shift, 0); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_component_update_bits(component, - WCD938X_ANA_TX_CH1, 0x80, 0x00); - snd_soc_component_update_bits(component, - WCD938X_ANA_TX_CH2, 0x80, 0x00); - snd_soc_component_update_bits(component, + switch (w->shift) { + case 0: + snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x10, 0x00); + break; + case 1: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x20, 0x00); + break; + case 2: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x40, 0x00); + break; + case 3: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x00); + break; + default: + break; + } snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00); - snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x00); break; }; return ret; -- GitLab From fdda2d8146a78db641208808a12a035128ae6c00 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 31 Jul 2019 21:26:30 +0530 Subject: [PATCH 1129/1645] audio-kernel: Update Kbuild support for bengal Update config file to pick for bengal in Kbuild files. Change-Id: Ic86e22204bbc16ca751eceb0391e38b4a60ac8b5 Signed-off-by: Laxminath Kasam --- asoc/Kbuild | 5 +++++ asoc/codecs/Kbuild | 5 +++++ asoc/codecs/bolero/Kbuild | 5 +++++ asoc/codecs/wcd938x/Kbuild | 5 +++++ dsp/Kbuild | 5 +++++ dsp/codecs/Kbuild | 5 +++++ ipc/Kbuild | 5 +++++ soc/Kbuild | 5 +++++ 8 files changed, 40 insertions(+) diff --git a/asoc/Kbuild b/asoc/Kbuild index 9ca09b7a336b..73dedfcabbbb 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -50,6 +50,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif + ifeq ($(CONFIG_ARCH_BENGAL), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 9b2aae3817ff..b8abfc4ca897 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -50,6 +50,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif + ifeq ($(CONFIG_ARCH_BENGAL), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild index 06883a3fbc8b..e6517f8a6bd9 100644 --- a/asoc/codecs/bolero/Kbuild +++ b/asoc/codecs/bolero/Kbuild @@ -35,6 +35,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif + ifeq ($(CONFIG_ARCH_BENGAL), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf export diff --git a/asoc/codecs/wcd938x/Kbuild b/asoc/codecs/wcd938x/Kbuild index 3dfe142bcfc2..99d71953dff2 100644 --- a/asoc/codecs/wcd938x/Kbuild +++ b/asoc/codecs/wcd938x/Kbuild @@ -23,6 +23,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif + ifeq ($(CONFIG_ARCH_BENGAL), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif endif diff --git a/dsp/Kbuild b/dsp/Kbuild index 9ab89668d7e4..2ce402f8cddf 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -39,6 +39,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif + ifeq ($(CONFIG_ARCH_BENGAL), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) ifdef CONFIG_SND_SOC_SA8155 include $(AUDIO_ROOT)/config/sa8155auto.conf diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 888492ddc0e7..3bdcd7d2a988 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -33,6 +33,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif + ifeq ($(CONFIG_ARCH_BENGAL), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf export diff --git a/ipc/Kbuild b/ipc/Kbuild index fa8776143219..76d9e84175a5 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -40,6 +40,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif + ifeq ($(CONFIG_ARCH_BENGAL), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif ifeq ($(CONFIG_ARCH_SM8150), y) ifdef CONFIG_SND_SOC_SA8155 include $(AUDIO_ROOT)/config/sa8155auto.conf diff --git a/soc/Kbuild b/soc/Kbuild index a1944a15fdec..644e5bdd2022 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -28,6 +28,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif + ifeq ($(CONFIG_ARCH_BENGAL), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm6150auto.conf export -- GitLab From 478379fad0fa38d36e7f5a39a1c0fb0d752efd93 Mon Sep 17 00:00:00 2001 From: Kunlei Zhang Date: Thu, 1 Aug 2019 17:05:33 +0800 Subject: [PATCH 1130/1645] asoc: msm: add support for compress-voip in routing driver Add support for compress-voip in cdc dma rx and tx. Change-Id: I6ae9152830c55f8d1a4269144274c8c56708d369 Signed-off-by: Kunlei Zhang --- asoc/msm-pcm-routing-v2.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 1afa9ef47e79..45d6a507be52 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -24943,10 +24943,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_Voice Mixer"}, + {"WSA_CDC_DMA_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, {"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0_Voice Mixer"}, + {"RX_CDC_DMA_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0_Voice Mixer"}, @@ -25153,6 +25155,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"Voip_Tx Mixer", "SEN_AUX_PCM_TX_Voip", "SEN_AUX_PCM_TX"}, {"Voip_Tx Mixer", "PRI_MI2S_TX_Voip", "PRI_MI2S_TX"}, {"Voip_Tx Mixer", "PRI_TDM_TX_3_Voip", "PRI_TDM_TX_3"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_0_Voip", "TX_CDC_DMA_TX_0"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_1_Voip", "TX_CDC_DMA_TX_1"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_2_Voip", "TX_CDC_DMA_TX_2"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_3_Voip", "TX_CDC_DMA_TX_3"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_4_Voip", "TX_CDC_DMA_TX_4"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_5_Voip", "TX_CDC_DMA_TX_5"}, {"VOIP_UL", NULL, "Voip_Tx Mixer"}, {"SLIMBUS_DL_HL", "Switch", "SLIM0_DL_HL"}, -- GitLab From 30a1c046b4aacc3e70063474b7b26f4f0bda8cb8 Mon Sep 17 00:00:00 2001 From: Vijayakumar Badiger Date: Thu, 20 Jun 2019 15:19:12 -0700 Subject: [PATCH 1131/1645] ASoC: Preliminary Android target definition for sdmshrike Add target definition support for sdmshrike. Change-Id: Ic87588d7aa9e14d2893bc1d6172cb35c34f6ede2 Signed-off-by: Derek Chen --- Android.mk | 6 +++--- asoc/Android.mk | 4 ++-- asoc/codecs/Android.mk | 6 +++--- dsp/Android.mk | 4 ++-- dsp/codecs/Android.mk | 4 ++-- ipc/Android.mk | 6 +++--- soc/Android.mk | 6 +++--- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Android.mk b/Android.mk index 6cdcdb5fbd55..feead0106a6c 100644 --- a/Android.mk +++ b/Android.mk @@ -3,7 +3,7 @@ MY_LOCAL_PATH := $(call my-dir) UAPI_OUT := $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/include -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) $(shell mkdir -p $(UAPI_OUT)/linux;) $(shell mkdir -p $(UAPI_OUT)/sound;) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers) @@ -22,7 +22,7 @@ include $(MY_LOCAL_PATH)/asoc/Android.mk include $(MY_LOCAL_PATH)/asoc/codecs/Android.mk endif -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) sdmshrike),true) ifneq ($(TARGET_BOARD_AUTO),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk @@ -31,7 +31,7 @@ include $(MY_LOCAL_PATH)/soc/Android.mk endif endif -ifeq ($(call is-board-platform-in-list,msmnile),true) +ifeq ($(call is-board-platform-in-list,msmnile sdmshrike),true) ifneq ($(TARGET_BOARD_AUTO),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/aqt1000/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/aqt1000/Android.mk diff --git a/asoc/Android.mk b/asoc/Android.mk index 09d946ddd9b8..4431f887e0a3 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -3,7 +3,7 @@ # Assume no targets will be supported # Check if this driver needs be built for current target -ifeq ($(call is-board-platform,msmnile),true) +ifeq ($(call is-board-platform-in-list,msmnile sdmshrike),true) TARGET := msmnile ifeq ($(TARGET_BOARD_AUTO),true) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m @@ -38,7 +38,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index 140980993edd..fb00efb70163 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -3,7 +3,7 @@ # Assume no targets will be supported # Check if this driver needs be built for current target -ifeq ($(call is-board-platform,msmnile),true) +ifeq ($(call is-board-platform-in-list,msmnile sdmshrike),true) ifeq ($(TARGET_BOARD_AUTO),true) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else @@ -33,7 +33,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) LOCAL_PATH := $(call my-dir) @@ -87,7 +87,7 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk endif ########################################################### -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) sdmshrike),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd_spi.ko LOCAL_MODULE_KBUILD_NAME := wcd_spi_dlkm.ko diff --git a/dsp/Android.mk b/dsp/Android.mk index 392752dabcb7..df13d3d5d968 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -3,7 +3,7 @@ # Assume no targets will be supported # Check if this driver needs be built for current target -ifeq ($(call is-board-platform,msmnile),true) +ifeq ($(call is-board-platform-in-list,msmnile sdmshrike),true) ifeq ($(TARGET_BOARD_AUTO),true) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else @@ -29,7 +29,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/codecs/Android.mk b/dsp/codecs/Android.mk index 2a4482e68f03..3d122f614600 100644 --- a/dsp/codecs/Android.mk +++ b/dsp/codecs/Android.mk @@ -3,7 +3,7 @@ # Assume no targets will be supported # Check if this driver needs be built for current target -ifeq ($(call is-board-platform,msmnile),true) +ifeq ($(call is-board-platform-in-list,msmnile sdmshrike),true) AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m endif @@ -21,7 +21,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) LOCAL_PATH := $(call my-dir) diff --git a/ipc/Android.mk b/ipc/Android.mk index d48c86e14ff2..62d78d06e61b 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -3,7 +3,7 @@ # Assume no targets will be supported # Check if this driver needs be built for current target -ifeq ($(call is-board-platform,msmnile),true) +ifeq ($(call is-board-platform-in-list,msmnile sdmshrike),true) ifeq ($(TARGET_BOARD_AUTO),true) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else @@ -29,7 +29,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) LOCAL_PATH := $(call my-dir) @@ -64,7 +64,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) sdmshrike),true) ifneq ($(TARGET_BOARD_AUTO),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wglink.ko diff --git a/soc/Android.mk b/soc/Android.mk index 5c2bef7ee88c..21d3d0a0ac6b 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -3,7 +3,7 @@ # Assume no targets will be supported # Check if this driver needs be built for current target -ifeq ($(call is-board-platform,msmnile),true) +ifeq ($(call is-board-platform-in-list,msmnile sdmshrike),true) ifeq ($(TARGET_BOARD_AUTO),true) AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m else @@ -29,7 +29,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) LOCAL_PATH := $(call my-dir) @@ -98,7 +98,7 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk endif ########################################################### -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) kona lito),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) kona lito sdmshrike),true) ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_snd_event.ko -- GitLab From 628c995972b82e365aec53531a9efe00525b8ef7 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Fri, 3 May 2019 17:14:09 +0530 Subject: [PATCH 1132/1645] ASoC: Add place markers to machine driver Add place markers in probe call of machine driver for measuring boot kpi values. Change-Id: Ib23a64685f5ae5fb04d40db70f7c6376ad27db7b Signed-off-by: Nagarjuna Paladugu --- asoc/sa6155.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/asoc/sa6155.c b/asoc/sa6155.c index 269bb815fe78..55f92271e7fd 100644 --- a/asoc/sa6155.c +++ b/asoc/sa6155.c @@ -57,6 +57,7 @@ #include #include #include +#include #include "device_event.h" #include "msm-pcm-routing-v2.h" @@ -7472,7 +7473,12 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) struct msm_asoc_mach_data *pdata; int ret; enum apr_subsys_state q6_state; + static int first_probe = 1; + if (first_probe) { + place_marker("M - DRIVER Audio Init"); + first_probe = 0; + } if (!pdev->dev.of_node) { dev_err(&pdev->dev, "No platform supplied from device tree\n"); return -EINVAL; @@ -7551,6 +7557,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) pr_err("%s: Registration with SND event FWK failed ret = %d\n", __func__, ret); + place_marker("M - DRIVER Audio Ready"); return 0; err: msm_release_pinctrl(pdev); -- GitLab From b097d92faf4dc070bc94d4fec892b0a36976b14f Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Wed, 31 Jul 2019 17:28:02 -0700 Subject: [PATCH 1133/1645] ASoC: add multimedia22 frontend and routing Add Multimedia22 frontend for pcm playback and capture support. Add routing for Multimedia22 to TDM backends. Change-Id: Id7d7d7d400c64791d54a4ad5033ce74d8f168e90 Signed-off-by: Derek Chen --- asoc/msm-dai-fe.c | 33 ++++++ asoc/msm-pcm-routing-v2.c | 217 ++++++++++++++++++++++++++++++++++++++ asoc/msm-pcm-routing-v2.h | 1 + 3 files changed, 251 insertions(+) diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index 100f4d746741..ba77a0731960 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -2691,6 +2691,39 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "MultiMedia21", .probe = fe_dai_probe, }, + { + .playback = { + .stream_name = "MultiMedia22 Playback", + .aif_name = "MM_DL22", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 32, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "MultiMedia22 Capture", + .aif_name = "MM_UL22", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 32, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .name = "MultiMedia22", + .probe = fe_dai_probe, + }, { .playback = { .stream_name = "MultiMedia26 Playback", diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 854774a0f121..c98a0da52bc1 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -757,6 +757,9 @@ static struct msm_pcm_routing_fdai_data {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA21 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, + /* MULTIMEDIA22 */ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA26 */ @@ -9330,6 +9333,10 @@ static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = { @@ -9401,6 +9408,10 @@ static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = { @@ -9472,6 +9483,10 @@ static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = { @@ -9543,6 +9558,10 @@ static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_tx_0_mixer_controls[] = { @@ -9681,6 +9700,10 @@ static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = { @@ -9752,6 +9775,10 @@ static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = { @@ -9823,6 +9850,10 @@ static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = { @@ -9894,6 +9925,10 @@ static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_tx_0_mixer_controls[] = { @@ -10032,6 +10067,10 @@ static const struct snd_kcontrol_new tert_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_tx_0_mixer_controls[] = { @@ -10170,6 +10209,10 @@ static const struct snd_kcontrol_new tert_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = { @@ -10241,6 +10284,10 @@ static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = { @@ -10312,6 +10359,10 @@ static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = { @@ -10383,6 +10434,10 @@ static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = { @@ -10458,6 +10513,10 @@ static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_tx_0_mixer_controls[] = { @@ -10600,6 +10659,10 @@ static const struct snd_kcontrol_new quat_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = { @@ -10675,6 +10738,10 @@ static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = { @@ -10750,6 +10817,10 @@ static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_0_mixer_controls[] = { @@ -10825,6 +10896,10 @@ static const struct snd_kcontrol_new quin_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_tx_0_mixer_controls[] = { @@ -10967,6 +11042,10 @@ static const struct snd_kcontrol_new quin_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = { @@ -11042,6 +11121,10 @@ static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = { @@ -11117,6 +11200,10 @@ static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sen_tdm_rx_0_mixer_controls[] = { @@ -14376,6 +14463,89 @@ static const struct snd_kcontrol_new mmul21_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new mmul22_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new mmul27_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, @@ -22261,6 +22431,7 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_IN("MM_DL16", "MultiMedia16 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("MM_DL20", "MultiMedia20 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("MM_DL21", "MultiMedia21 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL22", "MultiMedia22 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("MM_DL26", "MultiMedia26 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0), @@ -22278,6 +22449,7 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("MM_UL19", "MultiMedia19 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL20", "MultiMedia20 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL21", "MultiMedia21 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL22", "MultiMedia22 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL27", "MultiMedia27 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL28", "MultiMedia28 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL29", "MultiMedia29 Capture", 0, 0, 0, 0), @@ -23358,6 +23530,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { mmul20_mixer_controls, ARRAY_SIZE(mmul20_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia21 Mixer", SND_SOC_NOPM, 0, 0, mmul21_mixer_controls, ARRAY_SIZE(mmul21_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia22 Mixer", SND_SOC_NOPM, 0, 0, + mmul22_mixer_controls, ARRAY_SIZE(mmul22_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia27 Mixer", SND_SOC_NOPM, 0, 0, mmul27_mixer_controls, ARRAY_SIZE(mmul27_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia28 Mixer", SND_SOC_NOPM, 0, 0, @@ -24536,6 +24710,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Audio Mixer"}, {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24555,6 +24730,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Audio Mixer"}, {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24574,6 +24750,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Audio Mixer"}, {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24593,6 +24770,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Audio Mixer"}, {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24630,6 +24808,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Audio Mixer"}, {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24649,6 +24828,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Audio Mixer"}, {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24668,6 +24848,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Audio Mixer"}, {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24687,6 +24868,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Audio Mixer"}, {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24724,6 +24906,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Audio Mixer"}, {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24761,6 +24944,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Audio Mixer"}, {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24780,6 +24964,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Audio Mixer"}, {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24799,6 +24984,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Audio Mixer"}, {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24818,6 +25004,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"TERT_TDM_RX_4", NULL, "TERT_TDM_RX_4 Audio Mixer"}, {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24838,6 +25025,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Audio Mixer"}, {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24876,6 +25064,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Audio Mixer"}, {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24896,6 +25085,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Audio Mixer"}, {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24916,6 +25106,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Audio Mixer"}, {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24936,6 +25127,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0 Audio Mixer"}, {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24974,6 +25166,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1 Audio Mixer"}, {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -24994,6 +25187,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2 Audio Mixer"}, {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25014,6 +25208,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Audio Mixer"}, {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25614,6 +25809,27 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia21 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, {"MultiMedia21 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia22 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia22 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia22 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia22 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia22 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia22 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia22 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia22 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia22 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia22 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia22 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia22 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia22 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia22 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia22 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia22 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia22 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia22 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia22 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia22 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia27 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia27 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia27 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, @@ -25857,6 +26073,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL19", NULL, "MultiMedia19 Mixer"}, {"MM_UL20", NULL, "MultiMedia20 Mixer"}, {"MM_UL21", NULL, "MultiMedia21 Mixer"}, + {"MM_UL22", NULL, "MultiMedia22 Mixer"}, {"MM_UL27", NULL, "MultiMedia27 Mixer"}, {"MM_UL28", NULL, "MultiMedia28 Mixer"}, {"MM_UL29", NULL, "MultiMedia29 Mixer"}, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index bbfe509410e1..c9544cb316d6 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -256,6 +256,7 @@ enum { MSM_FRONTEND_DAI_MULTIMEDIA19, MSM_FRONTEND_DAI_MULTIMEDIA20, MSM_FRONTEND_DAI_MULTIMEDIA21, + MSM_FRONTEND_DAI_MULTIMEDIA22, MSM_FRONTEND_DAI_MULTIMEDIA26, MSM_FRONTEND_DAI_MULTIMEDIA27, MSM_FRONTEND_DAI_MULTIMEDIA28, -- GitLab From 7e3391bd8e3a320bfddb981ad669722066fe9a6d Mon Sep 17 00:00:00 2001 From: Asish Bhattacharya Date: Sun, 30 Jun 2019 19:57:09 +0530 Subject: [PATCH 1134/1645] ASoC: compr: add amrwbplus offload support support for AMR codec in compress driver path. Change-Id: Ife1d82caddf87a904f8c8b0402fc79f05a8289d1 Signed-off-by: Asish Bhattacharya --- asoc/msm-compress-q6-v2.c | 45 +++++++++++++++++++++++++++++++++++++++ dsp/q6asm.c | 9 ++++++++ 2 files changed, 54 insertions(+) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 4f58f351b352..f8a980887438 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -978,6 +978,7 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, struct asm_ape_cfg ape_cfg; struct asm_dsd_cfg dsd_cfg; struct aptx_dec_bt_addr_cfg aptx_cfg; + struct asm_amrwbplus_cfg amrwbplus_cfg; union snd_codec_options *codec_options; int ret = 0; @@ -1266,6 +1267,26 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, __func__, ret); } break; + case FORMAT_AMRNB: + pr_debug("SND_AUDIOCODEC_AMR\n"); + /* no media format block needed */ + break; + case FORMAT_AMRWB: + pr_debug("SND_AUDIOCODEC_AMRWB\n"); + /* no media format block needed */ + break; + case FORMAT_AMR_WB_PLUS: + pr_debug("SND_AUDIOCODEC_AMRWBPLUS\n"); + memset(&amrwbplus_cfg, 0x0, sizeof(struct asm_amrwbplus_cfg)); + amrwbplus_cfg.amr_frame_fmt = + codec_options->amrwbplus.bit_stream_fmt; + ret = q6asm_media_format_block_amrwbplus( + prtd->audio_client, + &amrwbplus_cfg); + if (ret < 0) + pr_err("%s: CMD AMRWBPLUS Format block failed ret %d\n", + __func__, ret); + break; default: pr_debug("%s, unsupported format, skip", __func__); break; @@ -2193,6 +2214,24 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream, break; } + case SND_AUDIOCODEC_AMR: { + pr_debug("%s:SND_AUDIOCODEC_AMR\n", __func__); + prtd->codec = FORMAT_AMRNB; + break; + } + + case SND_AUDIOCODEC_AMRWB: { + pr_debug("%s:SND_AUDIOCODEC_AMRWB\n", __func__); + prtd->codec = FORMAT_AMRWB; + break; + } + + case SND_AUDIOCODEC_AMRWBPLUS: { + pr_debug("%s:SND_AUDIOCODEC_AMRWBPLUS\n", __func__); + prtd->codec = FORMAT_AMR_WB_PLUS; + break; + } + default: pr_err("codec not supported, id =%d\n", params->codec.id); return -EINVAL; @@ -3267,6 +3306,9 @@ static int msm_compr_set_next_track_param(struct snd_compr_stream *cstream, case FORMAT_VORBIS: case FORMAT_ALAC: case FORMAT_APE: + case FORMAT_AMRNB: + case FORMAT_AMRWB: + case FORMAT_AMR_WB_PLUS: memcpy(&(prtd->gapless_state.codec_options), codec_options, sizeof(union snd_codec_options)); @@ -3641,6 +3683,9 @@ static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol, case FORMAT_TRUEHD: case FORMAT_IEC61937: case FORMAT_APTX: + case FORMAT_AMRNB: + case FORMAT_AMRWB: + case FORMAT_AMR_WB_PLUS: pr_debug("%s: no runtime parameters for codec: %d\n", __func__, prtd->codec); break; diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 475e04577b28..fdcf5f02d893 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -3542,6 +3542,15 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format, case FORMAT_WMA_V10PRO: open.dec_fmt_id = ASM_MEDIA_FMT_WMA_V10PRO_V2; break; + case FORMAT_AMRNB: + open.dec_fmt_id = ASM_MEDIA_FMT_AMRNB_FS; + break; + case FORMAT_AMRWB: + open.dec_fmt_id = ASM_MEDIA_FMT_AMRWB_FS; + break; + case FORMAT_AMR_WB_PLUS: + open.dec_fmt_id = ASM_MEDIA_FMT_AMR_WB_PLUS_V2; + break; case FORMAT_MP3: open.dec_fmt_id = ASM_MEDIA_FMT_MP3; break; -- GitLab From 2d92777e26ae1047fb46fe33d71f0fc9be7e684f Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 8 Jul 2019 19:21:22 +0530 Subject: [PATCH 1135/1645] asoc: Add xt logging disable mixer control Add xt logging disable mixer control in order to differentiate whether excursion logging data needs to be sent or not for the use case. This is required for the cases where same backend is used for multiple devices and xt logging data needs to be logged only for a particular device. Change-Id: I2cec67ddc18cbd63c5bc678eba77ea96b9a13963 Signed-off-by: Aditya Bavanari --- asoc/msm-dai-q6-v2.c | 52 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 6a30f3e9fb60..6d5fb51fde0a 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -231,6 +231,7 @@ struct msm_dai_q6_dai_data { struct afe_dec_config dec_config; union afe_port_config port_config; u16 vi_feed_mono; + u32 xt_logging_disable; }; struct msm_dai_q6_spdif_dai_data { @@ -345,6 +346,15 @@ static const struct soc_enum sb_config_enum[] = { SOC_ENUM_SINGLE_EXT(3, sb_format), }; +static const char * const xt_logging_disable_text[] = { + "FALSE", + "TRUE", +}; + +static const struct soc_enum xt_logging_disable_enum[] = { + SOC_ENUM_SINGLE_EXT(2, xt_logging_disable_text), +}; + static const char *const tdm_data_format[] = { "LPCM", "Compr", @@ -2729,8 +2739,9 @@ static int msm_dai_q6_spk_digital_mute(struct snd_soc_dai *dai, int mute) { int port_id = dai->id; + struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); - if (mute) + if (mute && !dai_data->xt_logging_disable) afe_get_sp_xt_logging_data(port_id); return 0; @@ -2777,6 +2788,27 @@ static int msm_dai_q6_cal_info_get(struct snd_kcontrol *kcontrol, return 0; } +static int msm_dai_q6_xt_logging_disable_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + dai_data->xt_logging_disable = ucontrol->value.integer.value[0]; + pr_debug("%s: setting xt logging disable to %d\n", + __func__, dai_data->xt_logging_disable); + + return 0; +} + +static int msm_dai_q6_xt_logging_disable_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + ucontrol->value.integer.value[0] = dai_data->xt_logging_disable; + return 0; +} + static int msm_dai_q6_sb_format_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -3630,7 +3662,10 @@ static const struct snd_kcontrol_new sb_config_controls[] = { msm_dai_q6_cal_info_put), SOC_ENUM_EXT("SLIM_2_RX Format", sb_config_enum[0], msm_dai_q6_sb_format_get, - msm_dai_q6_sb_format_put) + msm_dai_q6_sb_format_put), + SOC_ENUM_EXT("SLIM_0_RX XTLoggingDisable", xt_logging_disable_enum[0], + msm_dai_q6_xt_logging_disable_get, + msm_dai_q6_xt_logging_disable_put), }; static const struct snd_kcontrol_new rt_proxy_config_controls[] = { @@ -3821,6 +3856,9 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&avd_drift_config_controls[0], dai)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&sb_config_controls[3], + dai_data)); break; case SLIMBUS_6_RX: rc = snd_ctl_add(dai->component->card->snd_card, @@ -11183,10 +11221,15 @@ static int msm_dai_q6_cdc_dma_format_get(struct snd_kcontrol *kcontrol, dai_data->port_config.cdc_dma.data_format; return 0; } + static const struct snd_kcontrol_new cdc_dma_config_controls[] = { SOC_ENUM_EXT("WSA_CDC_DMA_0 TX Format", cdc_dma_config_enum[0], msm_dai_q6_cdc_dma_format_get, msm_dai_q6_cdc_dma_format_put), + SOC_ENUM_EXT("WSA_CDC_DMA_0 RX XTLoggingDisable", + xt_logging_disable_enum[0], + msm_dai_q6_xt_logging_disable_get, + msm_dai_q6_xt_logging_disable_put), }; /* SOC probe for codec DMA interface */ @@ -11213,6 +11256,11 @@ static int msm_dai_q6_dai_cdc_dma_probe(struct snd_soc_dai *dai) snd_ctl_new1(&cdc_dma_config_controls[0], dai_data)); break; + case AFE_PORT_ID_WSA_CODEC_DMA_RX_0: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&cdc_dma_config_controls[1], + dai_data)); + break; default: break; } -- GitLab From 6c052da6c1d8fab0f586ca810753b57a52a7934c Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Wed, 31 Jul 2019 17:30:46 -0700 Subject: [PATCH 1136/1645] ASoC: msm: add multimedia22 frontend in dai link Add Multimedia22 frontend in DAI link for automotive machine driver. Change-Id: I1d07c92f330f2c2a2b7dc4708021a5b6b0aa046e Signed-off-by: Derek Chen --- asoc/sa6155.c | 17 +++++++++++++++++ asoc/sa8155.c | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/asoc/sa6155.c b/asoc/sa6155.c index 269bb815fe78..f7c6d381b4f9 100644 --- a/asoc/sa6155.c +++ b/asoc/sa6155.c @@ -5867,6 +5867,23 @@ static struct snd_soc_dai_link msm_auto_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, + { + .name = MSM_DAILINK_NAME(Media22), + .stream_name = "MultiMedia22", + .cpu_dai_name = "MultiMedia22", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA22 + }, }; static struct snd_soc_dai_link msm_custom_fe_dai_links[] = { diff --git a/asoc/sa8155.c b/asoc/sa8155.c index 054083d1fd97..228f43088604 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -5854,6 +5854,23 @@ static struct snd_soc_dai_link msm_auto_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, + { + .name = MSM_DAILINK_NAME(Media22), + .stream_name = "MultiMedia22", + .cpu_dai_name = "MultiMedia22", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA22 + }, }; static struct snd_soc_dai_link msm_custom_fe_dai_links[] = { -- GitLab From 450ee1b712f606e5a876792e8b2cd5bfad7be8b6 Mon Sep 17 00:00:00 2001 From: Zhou Song Date: Fri, 2 Aug 2019 11:06:01 +0800 Subject: [PATCH 1137/1645] dsp: q6afe: add tws mono switch for aptx adaptive encoder Add support to switch tws channel mode for aptx adaptive encoder. Change-Id: Ife4170be56b152d34758a1cfd20fa4ec203742db Signed-off-by: Zhou Song --- asoc/msm-dai-q6-v2.c | 12 +++++++++--- dsp/q6afe.c | 14 ++++++++++++-- include/dsp/apr_audio-v2.h | 2 ++ include/dsp/q6afe-v2.h | 2 +- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 7cb2c0b258c4..d8b37078b609 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -3123,14 +3123,20 @@ static int msm_dai_q6_tws_channel_mode_put(struct snd_kcontrol *kcontrol, struct snd_soc_dai *dai = kcontrol->private_data; struct msm_dai_q6_dai_data *dai_data = NULL; int ret = 0; + u32 format = 0; if (dai) dai_data = dev_get_drvdata(dai->dev); - if (dai_data && (dai_data->enc_config.format == ENC_FMT_APTX)) { + if (dai_data) + format = dai_data->enc_config.format; + else + goto exit; + + if (format == ENC_FMT_APTX || format == ENC_FMT_APTX_ADAPTIVE) { if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { - ret = afe_set_tws_channel_mode(dai->id, - ucontrol->value.integer.value[0]); + ret = afe_set_tws_channel_mode(format, + dai->id, ucontrol->value.integer.value[0]); if (ret < 0) { pr_err("%s: channel mode setting failed for TWS\n", __func__); diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 6f4aece5fba9..803068b1af37 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -4293,18 +4293,28 @@ static int q6afe_send_enc_config(u16 port_id, return ret; } -int afe_set_tws_channel_mode(u16 port_id, u32 channel_mode) +int afe_set_tws_channel_mode(u32 format, u16 port_id, u32 channel_mode) { struct aptx_channel_mode_param_t channel_mode_param; struct param_hdr_v3 param_info; int ret = 0; + u32 param_id = 0; + + if (format == ASM_MEDIA_FMT_APTX) { + param_id = CAPI_V2_PARAM_ID_APTX_ENC_SWITCH_TO_MONO; + } else if (format == ASM_MEDIA_FMT_APTX_ADAPTIVE) { + param_id = CAPI_V2_PARAM_ID_APTX_AD_ENC_SWITCH_TO_MONO; + } else { + pr_err("%s: Not supported format 0x%x\n", __func__, format); + return -EINVAL; + } memset(¶m_info, 0, sizeof(param_info)); memset(&channel_mode_param, 0, sizeof(channel_mode_param)); param_info.module_id = AFE_MODULE_ID_ENCODER; param_info.instance_id = INSTANCE_ID_0; - param_info.param_id = CAPI_V2_PARAM_ID_APTX_ENC_SWITCH_TO_MONO; + param_info.param_id = param_id; param_info.param_size = sizeof(channel_mode_param); channel_mode_param.channel_mode = channel_mode; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 99b9a4560652..24382644e9be 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -3985,6 +3985,8 @@ struct afe_id_aptx_adaptive_enc_init #define CAPI_V2_PARAM_ID_APTX_ENC_SWITCH_TO_MONO 0x0001332A +#define CAPI_V2_PARAM_ID_APTX_AD_ENC_SWITCH_TO_MONO 0x00013354 + struct aptx_channel_mode_param_t { u32 channel_mode; } __packed; diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 89155015eda7..9504ad6fb1b9 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -389,7 +389,7 @@ void afe_set_island_mode_cfg(u16 port_id, u32 enable_flag); void afe_get_island_mode_cfg(u16 port_id, u32 *enable_flag); int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate); -int afe_set_tws_channel_mode(u16 port_id, u32 channel_mode); +int afe_set_tws_channel_mode(u32 foramt, u16 port_id, u32 channel_mode); int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, struct afe_enc_config *enc_config, -- GitLab From 597695312d391eaceaf7e6b7f523a0f606796c80 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Mon, 5 Aug 2019 16:02:32 +0530 Subject: [PATCH 1138/1645] asoc: add support for custom channel map In a stream we need to add support for downmixed stereo channel along with the left and right channels. Add custom channel map to support downmixed stereo channels. Change-Id: Icb7fa226a6f07ee4f7d00b8f55fe578c27719c86 Signed-off-by: Surendar Karka --- asoc/msm-compress-q6-v2.c | 4 ++-- include/dsp/apr_audio-v2.h | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 4f58f351b352..75b217f13bea 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -4171,8 +4171,8 @@ static int msm_compr_channel_map_info(struct snd_kcontrol *kcontrol, uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8; uinfo->value.integer.min = 0; - /* See PCM_CHANNEL_UNUSED=47 in apr_audio-v2.h */ - uinfo->value.integer.max = 47; + /* See PCM_MAX_CHANNEL_MAP in apr_audio-v2.h */ + uinfo->value.integer.max = PCM_MAX_CHANNEL_MAP; return 0; } diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index cfac0659b5a3..22557b7cda0d 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -5669,6 +5669,24 @@ struct asm_softvolume_params { /* Mark unused channel. */ #define PCM_CHANNEL_UNUSED 47 +#define PCM_CUSTOM_CHANNEL_MAP_1 48 +#define PCM_CUSTOM_CHANNEL_MAP_2 49 +#define PCM_CUSTOM_CHANNEL_MAP_3 50 +#define PCM_CUSTOM_CHANNEL_MAP_4 51 +#define PCM_CUSTOM_CHANNEL_MAP_5 52 +#define PCM_CUSTOM_CHANNEL_MAP_6 53 +#define PCM_CUSTOM_CHANNEL_MAP_7 54 +#define PCM_CUSTOM_CHANNEL_MAP_8 55 +#define PCM_CUSTOM_CHANNEL_MAP_9 56 +#define PCM_CUSTOM_CHANNEL_MAP_10 57 +#define PCM_CUSTOM_CHANNEL_MAP_11 58 +#define PCM_CUSTOM_CHANNEL_MAP_12 59 +#define PCM_CUSTOM_CHANNEL_MAP_13 60 +#define PCM_CUSTOM_CHANNEL_MAP_14 61 +#define PCM_CUSTOM_CHANNEL_MAP_15 62 +#define PCM_CUSTOM_CHANNEL_MAP_16 63 +#define PCM_MAX_CHANNEL_MAP 63 + /* Max valid channel map index */ #define PCM_MAX_CHMAP_ID PCM_CHANNEL_RSD -- GitLab From 124ec09342e5ac2b10792e3a5a65a17bfeeb24af Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 1 Aug 2019 10:21:08 +0530 Subject: [PATCH 1139/1645] ASoC: msm-cdc-pinctrl: Add support to control wakeup capable gpios Some clock and data gpios are also treated as wakeup source capable interrupts. Add support to control the wakeup capability based on the usecase. Change-Id: I32a12f004afbf04f82e40be62747b0af8836be82 Signed-off-by: Sudheer Papothi --- asoc/codecs/msm-cdc-pinctrl.c | 33 +++++++++++++++++++++++++++++++++ include/asoc/msm-cdc-pinctrl.h | 7 +++++++ 2 files changed, 40 insertions(+) diff --git a/asoc/codecs/msm-cdc-pinctrl.c b/asoc/codecs/msm-cdc-pinctrl.c index 0dadb7489aa5..c611345fa70a 100644 --- a/asoc/codecs/msm-cdc-pinctrl.c +++ b/asoc/codecs/msm-cdc-pinctrl.c @@ -11,6 +11,7 @@ #include #include #include +#include #include struct msm_cdc_pinctrl_info { @@ -19,6 +20,8 @@ struct msm_cdc_pinctrl_info { struct pinctrl_state *pinctrl_sleep; int gpio; bool state; + u32 tlmm_gpio; + bool wakeup_capable; }; static struct msm_cdc_pinctrl_info *msm_cdc_pinctrl_get_gpiodata( @@ -137,10 +140,34 @@ int msm_cdc_pinctrl_get_state(struct device_node *np) } EXPORT_SYMBOL(msm_cdc_pinctrl_get_state); +/* + * msm_cdc_pinctrl_set_wakeup_capable: Set a pinctrl to wakeup capable + * @np: pointer to struct device_node + * @enable: wakeup capable when set to true + * + * Returns 0 for success and error code for failure + */ +int msm_cdc_pinctrl_set_wakeup_capable(struct device_node *np, bool enable) +{ + struct msm_cdc_pinctrl_info *gpio_data; + int ret = 0; + + gpio_data = msm_cdc_pinctrl_get_gpiodata(np); + if (!gpio_data) + return -EINVAL; + + if (gpio_data->wakeup_capable) + ret = msm_gpio_mpm_wake_set(gpio_data->tlmm_gpio, enable); + + return ret; +} +EXPORT_SYMBOL(msm_cdc_pinctrl_set_wakeup_capable); + static int msm_cdc_pinctrl_probe(struct platform_device *pdev) { int ret = 0; struct msm_cdc_pinctrl_info *gpio_data; + u32 tlmm_gpio = 0; gpio_data = devm_kzalloc(&pdev->dev, sizeof(struct msm_cdc_pinctrl_info), @@ -183,6 +210,12 @@ static int msm_cdc_pinctrl_probe(struct platform_device *pdev) __func__, ret); } + if (!of_property_read_u32(pdev->dev.of_node, "qcom,tlmm-gpio", + &tlmm_gpio)) { + gpio_data->wakeup_capable = true; + gpio_data->tlmm_gpio = tlmm_gpio; + } + gpio_data->gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,cdc-rst-n-gpio", 0); if (gpio_is_valid(gpio_data->gpio)) { diff --git a/include/asoc/msm-cdc-pinctrl.h b/include/asoc/msm-cdc-pinctrl.h index 73022ab46ef1..89fe699ccb88 100644 --- a/include/asoc/msm-cdc-pinctrl.h +++ b/include/asoc/msm-cdc-pinctrl.h @@ -13,6 +13,8 @@ extern int msm_cdc_pinctrl_select_sleep_state(struct device_node *np); extern int msm_cdc_pinctrl_select_active_state(struct device_node *np); extern int msm_cdc_pinctrl_get_state(struct device_node *np); extern int msm_cdc_get_gpio_state(struct device_node *np); +extern int msm_cdc_pinctrl_set_wakeup_capable(struct device_node *np, + bool enable); int msm_cdc_pinctrl_drv_init(void); void msm_cdc_pinctrl_drv_exit(void); @@ -40,6 +42,11 @@ int msm_cdc_pinctrl_get_state(struct device_node *np) { return true; } +static int msm_cdc_pinctrl_set_wakeup_capable(struct device_node *np, + bool enable) +{ + return 0; +} #endif #endif -- GitLab From c51afbc5222d2857c0a85f9673bd742fcd7f4421 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 1 Aug 2019 10:25:32 +0530 Subject: [PATCH 1140/1645] ASoC: Kona: Disable wakeup capability for DMIC45 clock gpio DMIC45 clock gpio generates dmic clock on the gpio line when the audio capture starts on DMIC4 or DMIC5. But the same gpio is also an wakeup capable interrupt source. So, during audio capture usecase, GIC receives interrupts continuously as clock gpio toggles. Disable wakeup capability for DMIC45 clock gpio to avoid interrupt generation to GIC during the audio capture usecase. Change-Id: I7793455fd1034a5d391c6a163ca776c6ed0c9b89 Signed-off-by: Sudheer Papothi --- asoc/kona.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/kona.c b/asoc/kona.c index bd9dc28ab677..f25787db9a0b 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -7733,6 +7733,8 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) pdata->dmic45_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,cdc-dmic45-gpios", 0); + if (pdata->dmic45_gpio_p) + msm_cdc_pinctrl_set_wakeup_capable(pdata->dmic45_gpio_p, false); pdata->mi2s_gpio_p[PRIM_MI2S] = of_parse_phandle(pdev->dev.of_node, "qcom,pri-mi2s-gpios", 0); -- GitLab From 72ee264c0cf50dbec464b9afdd4c9c8d39c916ee Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 8 Aug 2019 05:15:17 +0530 Subject: [PATCH 1141/1645] SoC: soundwire: Add support to register for event listener Add support to register/deregister for event listener to listen to headset interrupt events during low power island mode. Change-Id: I9d05261003ef9e4783e03b3acb529c864c07cbec Signed-off-by: Sudheer Papothi --- include/soc/swr-wcd.h | 2 ++ soc/swr-mstr-ctrl.c | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/include/soc/swr-wcd.h b/include/soc/swr-wcd.h index 25c5339b3195..4ec509442858 100644 --- a/include/soc/swr-wcd.h +++ b/include/soc/swr-wcd.h @@ -22,6 +22,8 @@ enum { SWR_REGISTER_WAKE_IRQ, SWR_SET_PORT_MAP, SWR_REQ_CLK_SWITCH, + SWR_REGISTER_WAKEUP, + SWR_DEREGISTER_WAKEUP, }; struct swr_mstr_port { diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index f184e1bccfcb..36523743adce 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2871,6 +2871,14 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) mutex_unlock(&swrm->mlock); } break; + case SWR_REGISTER_WAKEUP: + msm_aud_evt_blocking_notifier_call_chain( + SWR_WAKE_IRQ_REGISTER, (void *)swrm); + break; + case SWR_DEREGISTER_WAKEUP: + msm_aud_evt_blocking_notifier_call_chain( + SWR_WAKE_IRQ_DEREGISTER, (void *)swrm); + break; case SWR_SET_PORT_MAP: if (!data) { dev_err(swrm->dev, "%s: data is NULL for id=%d\n", -- GitLab From 06a4c648f0c2c5e291dcdf7792f7ba8c9dbd20a5 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 8 Aug 2019 05:17:46 +0530 Subject: [PATCH 1142/1645] ASoC: Add support for event listener from the codec During low power island mode, register to event listener to process soundwire inband interrupts from the soundwire master driver. Change-Id: Ib15f5ec59ea19010dbb8f9744de76bfc2ca7eebb Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/bolero-cdc.c | 38 +++++++++++++++++++++++++++++++++ asoc/codecs/bolero/bolero-cdc.h | 10 +++++++++ asoc/codecs/bolero/tx-macro.c | 37 ++++++++++++++++++++++++++++++++ asoc/codecs/bolero/va-macro.c | 2 ++ 4 files changed, 87 insertions(+) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 6f81dab723a6..abb88bef4517 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -504,6 +504,8 @@ int bolero_register_macro(struct device *dev, u16 macro_id, if (macro_id == TX_MACRO) { priv->macro_params[macro_id].reg_wake_irq = ops->reg_wake_irq; priv->macro_params[macro_id].clk_switch = ops->clk_switch; + priv->macro_params[macro_id].reg_evt_listener = + ops->reg_evt_listener; } priv->num_dais += ops->num_dais; @@ -567,6 +569,7 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) if (macro_id == TX_MACRO) { priv->macro_params[macro_id].reg_wake_irq = NULL; priv->macro_params[macro_id].clk_switch = NULL; + priv->macro_params[macro_id].reg_evt_listener = NULL; } priv->num_dais -= priv->macro_params[macro_id].num_dais; @@ -803,6 +806,41 @@ int bolero_tx_clk_switch(struct snd_soc_component *component) } EXPORT_SYMBOL(bolero_tx_clk_switch); +/** + * bolero_register_event_listener - Register/Deregister to event listener + * + * @component: pointer to codec component instance. + * @enable: when set to 1 registers to event listener otherwise, derigisters + * from the event listener + * + * Returns 0 on success or -EINVAL on error. + */ +int bolero_register_event_listener(struct snd_soc_component *component, + bool enable) +{ + struct bolero_priv *priv = NULL; + int ret = 0; + + if (!component) + return -EINVAL; + + priv = snd_soc_component_get_drvdata(component); + if (!priv) + return -EINVAL; + + if (!bolero_is_valid_codec_dev(priv->dev)) { + dev_err(component->dev, "%s: invalid codec\n", __func__); + return -EINVAL; + } + + if (priv->macro_params[TX_MACRO].reg_evt_listener) + ret = priv->macro_params[TX_MACRO].reg_evt_listener(component, + enable); + + return ret; +} +EXPORT_SYMBOL(bolero_register_event_listener); + static int bolero_soc_codec_probe(struct snd_soc_component *component) { struct bolero_priv *priv = dev_get_drvdata(component->dev); diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 7e8ec83266b6..8a74e79f542e 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -56,6 +56,7 @@ struct macro_ops { int (*set_port_map)(struct snd_soc_component *component, u32 uc, u32 size, void *data); int (*clk_switch)(struct snd_soc_component *component); + int (*reg_evt_listener)(struct snd_soc_component *component, bool en); char __iomem *io_base; u16 clk_id_req; u16 default_clk_id; @@ -80,6 +81,8 @@ int bolero_runtime_resume(struct device *dev); int bolero_runtime_suspend(struct device *dev); int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *data); int bolero_tx_clk_switch(struct snd_soc_component *component); +int bolero_register_event_listener(struct snd_soc_component *component, + bool enable); #else static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb) { @@ -144,5 +147,12 @@ static inline int bolero_tx_clk_switch(struct snd_soc_component *component) return 0; } +static inline int bolero_register_event_listener( + struct snd_soc_component *component, + bool enable) +{ + return 0; +} + #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index db1129c8321b..67b3287f2548 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1582,6 +1582,42 @@ static const struct snd_kcontrol_new tx_macro_snd_controls[] = { tx_macro_get_bcs, tx_macro_set_bcs), }; +static int tx_macro_register_event_listener(struct snd_soc_component *component, + bool enable) +{ + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + int ret = 0; + + if (!component) + return -EINVAL; + + tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO); + if (!tx_dev) { + dev_err(component->dev, + "%s: null device for macro!\n", __func__); + return -EINVAL; + } + tx_priv = dev_get_drvdata(tx_dev); + if (!tx_priv) { + dev_err(component->dev, + "%s: priv is null for macro!\n", __func__); + return -EINVAL; + } + if (tx_priv->swr_ctrl_data) { + if (enable) + ret = swrm_wcd_notify( + tx_priv->swr_ctrl_data[0].tx_swr_pdev, + SWR_REGISTER_WAKEUP, NULL); + else + ret = swrm_wcd_notify( + tx_priv->swr_ctrl_data[0].tx_swr_pdev, + SWR_DEREGISTER_WAKEUP, NULL); + } + + return ret; +} + static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, struct regmap *regmap, int clk_type, bool enable) @@ -2121,6 +2157,7 @@ static void tx_macro_init_ops(struct macro_ops *ops, ops->reg_wake_irq = tx_macro_reg_wake_irq; ops->set_port_map = tx_macro_set_port_map; ops->clk_switch = tx_macro_clk_switch; + ops->reg_evt_listener = tx_macro_register_event_listener; } static int tx_macro_probe(struct platform_device *pdev) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 3c625a5a9ef9..8ed3d1c07449 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -287,8 +287,10 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, if (bolero_tx_clk_switch(component)) dev_dbg(va_dev, "%s: clock switch failed\n", __func__); + bolero_register_event_listener(component, true); break; case SND_SOC_DAPM_POST_PMD: + bolero_register_event_listener(component, false); if (bolero_tx_clk_switch(component)) dev_dbg(va_dev, "%s: clock switch failed\n",__func__); if (va_priv->lpass_audio_hw_vote) -- GitLab From a5b505aa6d7939df03a1bdf3779beb1d3f9953d5 Mon Sep 17 00:00:00 2001 From: Guodong Hu Date: Wed, 3 Jul 2019 17:22:06 +0800 Subject: [PATCH 1143/1645] audiodlkm: make sa8155 and sa6155 utilize the same obj-option Make the sa8155 sa8155ivi and sa6155 utilize the same obj-option. But distinguish the kbuild-option. Change-Id: I7ff7c7d30670cb4abb42d46f3632136539a9b82e Signed-off-by: Guodong Hu --- Makefile.am | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) mode change 100644 => 100755 Makefile.am diff --git a/Makefile.am b/Makefile.am old mode 100644 new mode 100755 index 0a0f0035c2b8..59b82cabf49d --- a/Makefile.am +++ b/Makefile.am @@ -37,14 +37,19 @@ obj-m += asoc/codecs/bolero/ obj-m += asoc/codecs/wcd937x/ endif -ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155)) +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155 sa8155ivi sa6155)) obj-m := ipc/ obj-m += dsp/ obj-m += asoc/ obj-m += asoc/codecs/ obj-m += soc/ +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155 sa8155ivi)) KBUILD_OPTIONS += CONFIG_SND_SOC_SA8155=m endif +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa6155)) +KBUILD_OPTIONS += CONFIG_SND_SOC_SA6155=m +endif +endif all: $(shell rm -fr $(shell pwd)/soc/core.h) -- GitLab From 1fc900df43176b086a1c32f1f583059089dac33f Mon Sep 17 00:00:00 2001 From: Guodong Hu Date: Fri, 28 Jun 2019 15:47:05 +0800 Subject: [PATCH 1144/1645] audiodlkm: modify makefile to generate header files Modify the makefile to generate header files in the work-shared dir, which are needed by acdbrtac.bb. Change-Id: I69a94f0e5913855add4fc9ff79aa1849218e5b8e Signed-off-by: Guodong Hu --- Makefile.am | 6 ++++++ 1 file changed, 6 insertions(+) mode change 100644 => 100755 Makefile.am diff --git a/Makefile.am b/Makefile.am old mode 100644 new mode 100755 index 0a0f0035c2b8..d26de38329f1 --- a/Makefile.am +++ b/Makefile.am @@ -60,6 +60,12 @@ all: $(shell cd $(KERNEL_BINARY_DIR) && $(KERNEL_SRC)/scripts/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ $(notdir $(AUDIO_KERNEL_HEADERS_PATH1))) $(shell cd $(KERNEL_BINARY_DIR) && $(KERNEL_SRC)/scripts/headers_install.sh $(UAPI_OUT)/linux/mfd/wcd9xxx/ $(AUDIO_ROOT)/include/uapi/linux/mfd/wcd9xxx/ $(notdir $(AUDIO_KERNEL_HEADERS_PATH2))) $(shell cd $(KERNEL_BINARY_DIR) && $(KERNEL_SRC)/scripts/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ $(notdir $(AUDIO_KERNEL_HEADERS_PATH3))) + $(shell mkdir $(KERNEL_BINARY_DIR)/usr/include/sound) + $(shell mkdir $(KERNEL_BINARY_DIR)/usr/include/linux/mfd) + $(shell mkdir $(KERNEL_BINARY_DIR)/usr/include/linux/mfd/wcd9xxx) + $(shell cd $(KERNEL_BINARY_DIR) && $(KERNEL_SRC)/scripts/headers_install.sh $(KERNEL_BINARY_DIR)/usr/include/linux/ $(AUDIO_ROOT)/include/uapi/linux/ $(notdir $(AUDIO_KERNEL_HEADERS_PATH1))) + $(shell cd $(KERNEL_BINARY_DIR) && $(KERNEL_SRC)/scripts/headers_install.sh $(KERNEL_BINARY_DIR)/usr/include/linux/mfd/wcd9xxx/ $(AUDIO_ROOT)/include/uapi/linux/mfd/wcd9xxx/ $(notdir $(AUDIO_KERNEL_HEADERS_PATH2))) + $(shell cd $(KERNEL_BINARY_DIR) && $(KERNEL_SRC)/scripts/headers_install.sh $(KERNEL_BINARY_DIR)/usr/include/sound/ $(AUDIO_ROOT)/include/uapi/sound/ $(notdir $(AUDIO_KERNEL_HEADERS_PATH3))) $(MAKE) -C $(KERNEL_SRC) M=$(shell pwd) modules $(KBUILD_OPTIONS) modules_install: -- GitLab From 50ef13eca627cf44ad28e9946680b114930b41af Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 9 Aug 2019 15:14:43 +0530 Subject: [PATCH 1145/1645] asoc: codecs: Fix LPI TLMM GPIO invalid access issue Runtime suspend gets called multiple times during SSR scenarios leading to clock count mismatch. Add logic to prevent this in all macros and pinctrl lpi driver. Change-Id: I380631c1db8cd7d94a8909affd8c96c87f24817c Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/rx-macro.c | 11 +++++- asoc/codecs/bolero/tx-macro.c | 12 +++++- asoc/codecs/bolero/va-macro.c | 11 +++++- asoc/codecs/bolero/wsa-macro.c | 11 +++++- soc/pinctrl-lpi.c | 68 +++++++++++++++++----------------- 5 files changed, 71 insertions(+), 42 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 0137c9f52bdb..03dea2093639 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1235,8 +1235,15 @@ static int rx_macro_event_handler(struct snd_soc_component *component, rx_priv->swr_ctrl_data[0].rx_swr_pdev, SWR_DEVICE_SSR_DOWN, NULL); } - if (!pm_runtime_status_suspended(rx_dev)) - bolero_runtime_suspend(rx_dev); + if ((!pm_runtime_enabled(rx_dev) || + !pm_runtime_suspended(rx_dev))) { + ret = bolero_runtime_suspend(rx_dev); + if (!ret) { + pm_runtime_disable(rx_dev); + pm_runtime_set_suspended(rx_dev); + pm_runtime_enable(rx_dev); + } + } break; case BOLERO_MACRO_EVT_SSR_UP: rx_priv->dev_up = true; diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index db1129c8321b..fda01e1304f5 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -342,6 +342,7 @@ static int tx_macro_event_handler(struct snd_soc_component *component, { struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; + int ret = 0; if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; @@ -356,8 +357,15 @@ static int tx_macro_event_handler(struct snd_soc_component *component, tx_priv->swr_ctrl_data[0].tx_swr_pdev, SWR_DEVICE_SSR_DOWN, NULL); } - if (!pm_runtime_status_suspended(tx_dev)) - bolero_runtime_suspend(tx_dev); + if ((!pm_runtime_enabled(tx_dev) || + !pm_runtime_suspended(tx_dev))) { + ret = bolero_runtime_suspend(tx_dev); + if (!ret) { + pm_runtime_disable(tx_dev); + pm_runtime_set_suspended(tx_dev); + pm_runtime_enable(tx_dev); + } + } break; case BOLERO_MACRO_EVT_SSR_UP: /* reset swr after ssr/pdr */ diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 3c625a5a9ef9..4c1631942a36 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -252,8 +252,15 @@ static int va_macro_event_handler(struct snd_soc_component *component, bolero_rsc_clk_reset(va_dev, VA_CORE_CLK); break; case BOLERO_MACRO_EVT_SSR_DOWN: - if (!pm_runtime_status_suspended(va_dev)) - bolero_runtime_suspend(va_dev); + if ((!pm_runtime_enabled(va_dev) || + !pm_runtime_suspended(va_dev))) { + ret = bolero_runtime_suspend(va_dev); + if (!ret) { + pm_runtime_disable(va_dev); + pm_runtime_set_suspended(va_dev); + pm_runtime_enable(va_dev); + } + } break; default: break; diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index d7f9478b5bd6..928aec0d5e0d 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -920,8 +920,15 @@ static int wsa_macro_event_handler(struct snd_soc_component *component, wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, SWR_DEVICE_SSR_DOWN, NULL); } - if (!pm_runtime_status_suspended(wsa_dev)) - bolero_runtime_suspend(wsa_dev); + if ((!pm_runtime_enabled(wsa_dev) || + !pm_runtime_suspended(wsa_dev))) { + ret = bolero_runtime_suspend(wsa_dev); + if (!ret) { + pm_runtime_disable(wsa_dev); + pm_runtime_set_suspended(wsa_dev); + pm_runtime_enable(wsa_dev); + } + } break; case BOLERO_MACRO_EVT_SSR_UP: /* reset swr after ssr/pdr */ diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index e11ba6e2be96..157e2c54a17b 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -481,6 +481,39 @@ static int lpi_notifier_service_cb(struct notifier_block *this, return NOTIFY_OK; } +int lpi_pinctrl_suspend(struct device *dev) +{ + int ret = 0; + + dev_dbg(dev, "%s: system suspend\n", __func__); + + if ((!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev))) { + ret = lpi_pinctrl_runtime_suspend(dev); + if (!ret) { + /* + * Synchronize runtime-pm and system-pm states: + * At this point, we are already suspended. If + * runtime-pm still thinks its active, then + * make sure its status is in sync with HW + * status. The three below calls let the + * runtime-pm know that we are suspended + * already without re-invoking the suspend + * callback + */ + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + pm_runtime_enable(dev); + } + } + + return ret; +} + +int lpi_pinctrl_resume(struct device *dev) +{ + return 0; +} + static struct notifier_block service_nb = { .notifier_call = lpi_notifier_service_cb, .priority = -INT_MAX, @@ -489,7 +522,7 @@ static struct notifier_block service_nb = { static void lpi_pinctrl_ssr_disable(struct device *dev, void *data) { lpi_dev_up = false; - lpi_pinctrl_runtime_suspend(dev); + lpi_pinctrl_suspend(dev); } static const struct snd_event_ops lpi_pinctrl_ssr_ops = { @@ -820,39 +853,6 @@ int lpi_pinctrl_runtime_suspend(struct device *dev) return 0; } -int lpi_pinctrl_suspend(struct device *dev) -{ - int ret = 0; - - dev_dbg(dev, "%s: system suspend\n", __func__); - - if ((!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev))) { - ret = lpi_pinctrl_runtime_suspend(dev); - if (!ret) { - /* - * Synchronize runtime-pm and system-pm states: - * At this point, we are already suspended. If - * runtime-pm still thinks its active, then - * make sure its status is in sync with HW - * status. The three below calls let the - * runtime-pm know that we are suspended - * already without re-invoking the suspend - * callback - */ - pm_runtime_disable(dev); - pm_runtime_set_suspended(dev); - pm_runtime_enable(dev); - } - } - - return ret; -} - -int lpi_pinctrl_resume(struct device *dev) -{ - return 0; -} - static const struct dev_pm_ops lpi_pinctrl_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS( lpi_pinctrl_suspend, -- GitLab From 63b193fcd045e1a6713594f60b806cb4e3cb12ce Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 12 Aug 2019 11:56:55 +0530 Subject: [PATCH 1146/1645] soc: swr-mstr: Fix headset detection after pdr Sometimes, headset is not detected after pdr during music playback. This is because enable_irq does not get called as master remains in suspend state. Decrease auto suspend timer to 1 to fix the issue. Change-Id: I8cea3e74487977af801dccac7e4f873831c26264 Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index f184e1bccfcb..d1b8ebf2b479 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2453,8 +2453,14 @@ static int swrm_runtime_resume(struct device *dev) SWR_WAKE_IRQ_DEREGISTER, (void *)swrm); } - if (swrm_clk_request(swrm, true)) + if (swrm_clk_request(swrm, true)) { + /* + * Set autosuspend timer to 1 for + * master to enter into suspend. + */ + auto_suspend_timer = 1; goto exit; + } if (!swrm->clk_stop_mode0_supp || swrm->state == SWR_MSTR_SSR) { list_for_each_entry(swr_dev, &mstr->devices, dev_list) { ret = swr_device_up(swr_dev); @@ -2494,6 +2500,7 @@ static int swrm_runtime_resume(struct device *dev) if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer); + auto_suspend_timer = SWR_AUTO_SUSPEND_DELAY * 1000; mutex_unlock(&swrm->reslock); return ret; -- GitLab From 2e85a546346f07595d856fb905821b26dc5e5957 Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Fri, 26 Apr 2019 18:28:31 +0530 Subject: [PATCH 1147/1645] soc: swr: avoid SSR state when switching between 44.1 and 48k family Avoid SSR state, and do only clock-stop-resume to reset master when switching between 44.1 and 48k to avoid redundant re-enumeration. Change-Id: Iaa955c4ceb75f30c68106468676ddb2551537de4 Signed-off-by: Ramprasad Katkam --- asoc/codecs/bolero/rx-macro.c | 12 ------------ soc/swr-mstr-ctrl.c | 20 +++++++++++--------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 0137c9f52bdb..e620df12c46c 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1147,18 +1147,6 @@ static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w, dev_dbg(rx_dev, "%s: event = %d\n", __func__, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - /* if swr_clk_users > 0, call device down */ - if (rx_priv->swr_clk_users > 0) { - if ((rx_priv->clk_id == rx_priv->default_clk_id && - rx_priv->is_native_on) || - (rx_priv->clk_id == RX_CORE_CLK && - !rx_priv->is_native_on)) { - if (rx_priv->swr_ctrl_data) - swrm_wcd_notify( - rx_priv->swr_ctrl_data[0].rx_swr_pdev, - SWR_DEVICE_DOWN, NULL); - } - } if (rx_priv->is_native_on) mclk_freq = MCLK_FREQ_NATIVE; if (rx_priv->swr_ctrl_data) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index f184e1bccfcb..c6206537fefc 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2474,6 +2474,8 @@ static int swrm_runtime_resume(struct device *dev) swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01); swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01); swrm_master_init(swrm); + /* wait for hw enumeration to complete */ + usleep_range(100, 105); swrm_cmd_fifo_wr_cmd(swrm, 0x4, 0xF, 0x0, SWRS_SCP_INT_STATUS_MASK_1); if (swrm->state == SWR_MSTR_SSR) { @@ -2614,22 +2616,14 @@ static int swrm_device_down(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); - int ret = 0; dev_dbg(dev, "%s: swrm state: %d\n", __func__, swrm->state); mutex_lock(&swrm->force_down_lock); swrm->state = SWR_MSTR_SSR; mutex_unlock(&swrm->force_down_lock); - if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) { - ret = swrm_runtime_suspend(dev); - if (!ret) { - pm_runtime_disable(dev); - pm_runtime_set_suspended(dev); - pm_runtime_enable(dev); - } - } + swrm_device_suspend(dev); return 0; } @@ -2763,6 +2757,14 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) ret = -EINVAL; } else { mutex_lock(&swrm->mlock); + if (swrm->mclk_freq != *(int *)data) { + dev_dbg(swrm->dev, "%s: freq change: force mstr down\n", __func__); + if (swrm->state == SWR_MSTR_DOWN) + dev_dbg(swrm->dev, "%s:SWR master is already Down:%d\n", + __func__, swrm->state); + else + swrm_device_suspend(&pdev->dev); + } swrm->mclk_freq = *(int *)data; mutex_unlock(&swrm->mlock); } -- GitLab From a442b0e3a2065227b35ae31d0436ded02f6cae71 Mon Sep 17 00:00:00 2001 From: Chaithanya Krishna Bacharaju Date: Fri, 9 Aug 2019 15:49:03 +0530 Subject: [PATCH 1148/1645] dsp: update DOA param id values Direction of Arrival param ids are modified in ADSP Fluence Version9 as currently used params overlap with CVD range values. Update DOA param id values to avoid mismatch. Change-Id: I70c779c5a7fc3da3ccdf3ddcd988a20a4908ca81 Signed-off-by: Chaithanya Krishna Bacharaju --- include/dsp/apr_audio-v2.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 43f55e2283ef..6002bc999822 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -12568,8 +12568,8 @@ struct afe_doa_tracking_mon_get_param_resp { #define AUDPROC_MODULE_ID_FFECNS 0x00010952 #define AUDPROC_MODULE_ID_FFNS 0x00010962 -#define AUDPROC_PARAM_ID_FFV_DOA_TRACKING_PARAM 0x11003 -#define AUDPROC_PARAM_ID_FFV_DOA_TRACKING_MONITOR 0x11004 +#define AUDPROC_PARAM_ID_FFV_DOA_TRACKING_PARAM 0x0001097C +#define AUDPROC_PARAM_ID_FFV_DOA_TRACKING_MONITOR 0x0001097D struct admx_sec_primary_mic_ch { uint16_t version; -- GitLab From 12d02689527f4e22470e62d39520ff813b450416 Mon Sep 17 00:00:00 2001 From: Guodong Hu Date: Mon, 29 Jul 2019 14:19:40 +0800 Subject: [PATCH 1149/1645] audiodlkm: support target SA8195 from audio side Make SA8195 utilize the same build option as SA8155. Change-Id: Id1e0f889b907d234c31c31f8730617ea2038b7a7 Signed-off-by: Guodong Hu --- Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100755 => 100644 Makefile.am diff --git a/Makefile.am b/Makefile.am old mode 100755 new mode 100644 index de9790f3c666..f57d4b5f5441 --- a/Makefile.am +++ b/Makefile.am @@ -37,13 +37,13 @@ obj-m += asoc/codecs/bolero/ obj-m += asoc/codecs/wcd937x/ endif -ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155 sa8155ivi sa6155)) +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155 sa8155ivi sa6155 sa8195)) obj-m := ipc/ obj-m += dsp/ obj-m += asoc/ obj-m += asoc/codecs/ obj-m += soc/ -ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155 sa8155ivi)) +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155 sa8155ivi sa8195)) KBUILD_OPTIONS += CONFIG_SND_SOC_SA8155=m endif ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa6155)) -- GitLab From a1670ee8bd185fda5a1d7b340a24fc15fc83795e Mon Sep 17 00:00:00 2001 From: Han Lu Date: Thu, 25 Jul 2019 10:13:20 +0800 Subject: [PATCH 1150/1645] asoc: msm: Add machine qtiquingvm Add qtiquingvm as sa8155 LV GVM machine type. Change-Id: Ica72a568a317763da5114d7ce1b92b776c7d6588 Signed-off-by: Han Lu --- Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index f57d4b5f5441..9d263f2b8f98 100644 --- a/Makefile.am +++ b/Makefile.am @@ -37,13 +37,13 @@ obj-m += asoc/codecs/bolero/ obj-m += asoc/codecs/wcd937x/ endif -ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155 sa8155ivi sa6155 sa8195)) +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155 sa8155ivi sa6155 sa8195 qtiquingvm)) obj-m := ipc/ obj-m += dsp/ obj-m += asoc/ obj-m += asoc/codecs/ obj-m += soc/ -ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155 sa8155ivi sa8195)) +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155 sa8155ivi sa8195 qtiquingvm)) KBUILD_OPTIONS += CONFIG_SND_SOC_SA8155=m endif ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa6155)) -- GitLab From 88c75963a478202b81a5c8c5e8920730fa38e85c Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 3 Aug 2019 04:06:46 +0530 Subject: [PATCH 1151/1645] ASoC: wcd938x: Update mibias configuration on WCD938x Apply micbias configuration from device tree for WCD938x for Kona target. Change-Id: I45a47eb54f9fffb88259ba7e69633e3d3ebcb6a4 Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd938x/wcd938x.c | 53 +++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index eecaccae46d6..e168d3004746 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -2759,6 +2759,40 @@ int wcd938x_info_create_codec_entry(struct snd_info_entry *codec_root, } EXPORT_SYMBOL(wcd938x_info_create_codec_entry); +static int wcd938x_set_micbias_data(struct wcd938x_priv *wcd938x, + struct wcd938x_pdata *pdata) +{ + int vout_ctl_1 = 0, vout_ctl_2 = 0, vout_ctl_3 = 0, vout_ctl_4 = 0; + int rc = 0; + + if (!pdata) { + dev_err(wcd938x->dev, "%s: NULL pdata\n", __func__); + return -ENODEV; + } + + /* set micbias voltage */ + vout_ctl_1 = wcd938x_get_micb_vout_ctl_val(pdata->micbias.micb1_mv); + vout_ctl_2 = wcd938x_get_micb_vout_ctl_val(pdata->micbias.micb2_mv); + vout_ctl_3 = wcd938x_get_micb_vout_ctl_val(pdata->micbias.micb3_mv); + vout_ctl_4 = wcd938x_get_micb_vout_ctl_val(pdata->micbias.micb4_mv); + if (vout_ctl_1 < 0 || vout_ctl_2 < 0 || vout_ctl_3 < 0 || + vout_ctl_4 < 0) { + rc = -EINVAL; + goto done; + } + regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB1, 0x3F, + vout_ctl_1); + regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB2, 0x3F, + vout_ctl_2); + regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB3, 0x3F, + vout_ctl_3); + regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB4, 0x3F, + vout_ctl_4); + +done: + return rc; +} + static int wcd938x_soc_codec_probe(struct snd_soc_component *component) { struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); @@ -3006,6 +3040,19 @@ static void wcd938x_dt_parse_micbias_info(struct device *dev, dev_info(dev, "%s: Micbias3 DT property not found\n", __func__); } + + /* MB4 */ + if (of_find_property(dev->of_node, "qcom,cdc-micbias4-mv", + NULL)) { + rc = wcd938x_read_of_property_u32(dev, + "qcom,cdc-micbias4-mv", + &prop_val); + if (!rc) + mb->micb4_mv = prop_val; + } else { + dev_info(dev, "%s: Micbias4 DT property not found\n", + __func__); + } } static int wcd938x_reset_low(struct device *dev) @@ -3144,6 +3191,12 @@ static int wcd938x_bind(struct device *dev) } wcd938x->tx_swr_dev->slave_irq = wcd938x->virq; + ret = wcd938x_set_micbias_data(wcd938x, pdata); + if (ret < 0) { + dev_err(dev, "%s: bad micbias pdata\n", __func__); + goto err_irq; + } + /* Request for watchdog interrupt */ wcd_request_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHR_PDM_WD_INT, "HPHR PDM WD INT", wcd938x_wd_handle_irq, NULL); -- GitLab From c001b153fca5beef4dadebcbc2b97e78dfd4e2b7 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Fri, 19 Jul 2019 10:17:55 -0700 Subject: [PATCH 1152/1645] ASoC: wcd938x: add support to retrieve codec variant Machine driver requires a mechanism to know the codec variant to limit supported configurations respective to that codec. Add a function to return the wcd938x codec variant. CRs-Fixed: 2488322 Change-Id: I16631cccb3abd32c933389e110e5b5a6b762a0e2 Signed-off-by: Vignesh Kulothungan --- asoc/codecs/wcd938x/wcd938x.c | 30 +++++++++++++++++++++++++----- asoc/codecs/wcd938x/wcd938x.h | 12 +++++++++++- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index eecaccae46d6..f89a2aaf5601 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -23,6 +23,7 @@ #include "internal.h" #include "wcd938x-registers.h" +#include "wcd938x.h" #define WCD938X_DRV_NAME "wcd938x_codec" #define NUM_SWRS_DT_PARAMS 5 @@ -39,11 +40,6 @@ #define ADC_MODE_VAL_ULP1 0x09 #define ADC_MODE_VAL_ULP2 0x0B -enum { - WCD9380 = 0, - WCD9385 = 5, -}; - enum { CODEC_TX = 0, CODEC_RX, @@ -2680,6 +2676,30 @@ static struct snd_info_entry_ops wcd938x_variant_ops = { .read = wcd938x_variant_read, }; +/* + * wcd938x_get_codec_variant + * @component: component instance + * + * Return: codec variant or -EINVAL in error. + */ +int wcd938x_get_codec_variant(struct snd_soc_component *component) +{ + struct wcd938x_priv *priv = NULL; + + if (!component) + return -EINVAL; + + priv = snd_soc_component_get_drvdata(component); + if (!priv) { + dev_err(component->dev, + "%s:wcd938x not probed\n", __func__); + return 0; + } + + return priv->variant; +} +EXPORT_SYMBOL(wcd938x_get_codec_variant); + /* * wcd938x_info_create_codec_entry - creates wcd938x module * @codec_root: The parent directory diff --git a/asoc/codecs/wcd938x/wcd938x.h b/asoc/codecs/wcd938x/wcd938x.h index 12b5f1a12686..e695f062f388 100644 --- a/asoc/codecs/wcd938x/wcd938x.h +++ b/asoc/codecs/wcd938x/wcd938x.h @@ -1,19 +1,29 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #ifndef _WCD938X_H #define _WCD938X_H +enum { + WCD9380 = 0, + WCD9385 = 5, +}; + #ifdef CONFIG_SND_SOC_WCD938X extern int wcd938x_info_create_codec_entry(struct snd_info_entry *codec_root, struct snd_soc_component *component); +extern int wcd938x_get_codec_variant(struct snd_soc_component *component); #else extern int wcd938x_info_create_codec_entry(struct snd_info_entry *codec_root, struct snd_soc_component *component) { return 0; } +extern int wcd938x_get_codec_variant(struct snd_soc_component *component) +{ + return 0; +} #endif /* CONFIG_SND_SOC_WCD938X */ #endif /* _WCD938X_H */ -- GitLab From 406c2bf91d1b0f02996677fa4ebdc467ae440edf Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Fri, 19 Jul 2019 10:17:55 -0700 Subject: [PATCH 1153/1645] ASoC: Kona: limit sample rate and format support based on codec Add support to limit sample rate and format support based on codec variant. Register mixer controls based on the codec limitation. Change-Id: I8055d2862798e183669e99b472ffc03b6cedd8ca Signed-off-by: Vignesh Kulothungan --- asoc/kona.c | 169 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 124 insertions(+), 45 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index 6b825a8a617e..f0bd6fbe3f7e 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -494,6 +494,7 @@ static int msm_vi_feed_tx_ch = 2; static const char *const vi_feed_ch_text[] = {"One", "Two"}; static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", "S32_LE"}; +static char const *cdc80_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"}; static char const *ch_text[] = {"Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", @@ -528,6 +529,11 @@ static char const *cdc_dma_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_88P2", "KHZ_96", "KHZ_176P4", "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static char const *cdc80_dma_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", + "KHZ_176P4", "KHZ_192"}; static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"}; static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96", @@ -616,11 +622,6 @@ static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_1_chs, cdc_dma_tx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_2_chs, cdc_dma_tx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_format, bit_format_text); -static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_1_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_2_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_0_format, bit_format_text); @@ -633,16 +634,6 @@ static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_sample_rate, cdc_dma_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_sample_rate, cdc_dma_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_sample_rate, - cdc_dma_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_sample_rate, - cdc_dma_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_sample_rate, - cdc_dma_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_sample_rate, - cdc_dma_sample_rate_text); -static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_sample_rate, - cdc_dma_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_0_sample_rate, cdc_dma_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_1_sample_rate, @@ -661,6 +652,40 @@ static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_1_sample_rate, cdc_dma_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_2_sample_rate, cdc_dma_sample_rate_text); + +/* WCD9380 */ +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc80_dma_rx_0_format, cdc80_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc80_dma_rx_1_format, cdc80_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc80_dma_rx_2_format, cdc80_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc80_dma_rx_3_format, cdc80_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc80_dma_rx_5_format, cdc80_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc80_dma_rx_0_sample_rate, + cdc80_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc80_dma_rx_1_sample_rate, + cdc80_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc80_dma_rx_2_sample_rate, + cdc80_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc80_dma_rx_3_sample_rate, + cdc80_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc80_dma_rx_5_sample_rate, + cdc80_dma_sample_rate_text); +/* WCD9385 */ +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc85_dma_rx_0_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc85_dma_rx_1_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc85_dma_rx_2_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc85_dma_rx_3_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc85_dma_rx_5_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc85_dma_rx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc85_dma_rx_1_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc85_dma_rx_2_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc85_dma_rx_3_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc85_dma_rx_5_sample_rate, + cdc_dma_sample_rate_text); + static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, @@ -3295,16 +3320,6 @@ static const struct snd_kcontrol_new msm_int_snd_controls[] = { cdc_dma_rx_format_get, cdc_dma_rx_format_put), SOC_ENUM_EXT("WSA_CDC_DMA_RX_1 Format", wsa_cdc_dma_rx_1_format, cdc_dma_rx_format_get, cdc_dma_rx_format_put), - SOC_ENUM_EXT("RX_CDC_DMA_RX_0 Format", rx_cdc_dma_rx_0_format, - cdc_dma_rx_format_get, cdc_dma_rx_format_put), - SOC_ENUM_EXT("RX_CDC_DMA_RX_1 Format", rx_cdc_dma_rx_1_format, - cdc_dma_rx_format_get, cdc_dma_rx_format_put), - SOC_ENUM_EXT("RX_CDC_DMA_RX_2 Format", rx_cdc_dma_rx_2_format, - cdc_dma_rx_format_get, cdc_dma_rx_format_put), - SOC_ENUM_EXT("RX_CDC_DMA_RX_3 Format", rx_cdc_dma_rx_3_format, - cdc_dma_rx_format_get, cdc_dma_rx_format_put), - SOC_ENUM_EXT("RX_CDC_DMA_RX_5 Format", rx_cdc_dma_rx_5_format, - cdc_dma_rx_format_get, cdc_dma_rx_format_put), SOC_ENUM_EXT("WSA_CDC_DMA_TX_1 Format", wsa_cdc_dma_tx_1_format, cdc_dma_tx_format_get, cdc_dma_tx_format_put), SOC_ENUM_EXT("WSA_CDC_DMA_TX_2 Format", wsa_cdc_dma_tx_2_format, @@ -3329,26 +3344,6 @@ static const struct snd_kcontrol_new msm_int_snd_controls[] = { wsa_cdc_dma_rx_1_sample_rate, cdc_dma_rx_sample_rate_get, cdc_dma_rx_sample_rate_put), - SOC_ENUM_EXT("RX_CDC_DMA_RX_0 SampleRate", - rx_cdc_dma_rx_0_sample_rate, - cdc_dma_rx_sample_rate_get, - cdc_dma_rx_sample_rate_put), - SOC_ENUM_EXT("RX_CDC_DMA_RX_1 SampleRate", - rx_cdc_dma_rx_1_sample_rate, - cdc_dma_rx_sample_rate_get, - cdc_dma_rx_sample_rate_put), - SOC_ENUM_EXT("RX_CDC_DMA_RX_2 SampleRate", - rx_cdc_dma_rx_2_sample_rate, - cdc_dma_rx_sample_rate_get, - cdc_dma_rx_sample_rate_put), - SOC_ENUM_EXT("RX_CDC_DMA_RX_3 SampleRate", - rx_cdc_dma_rx_3_sample_rate, - cdc_dma_rx_sample_rate_get, - cdc_dma_rx_sample_rate_put), - SOC_ENUM_EXT("RX_CDC_DMA_RX_5 SampleRate", - rx_cdc_dma_rx_5_sample_rate, - cdc_dma_rx_sample_rate_get, - cdc_dma_rx_sample_rate_put), SOC_ENUM_EXT("WSA_CDC_DMA_TX_0 SampleRate", wsa_cdc_dma_tx_0_sample_rate, cdc_dma_tx_sample_rate_get, @@ -3387,6 +3382,72 @@ static const struct snd_kcontrol_new msm_int_snd_controls[] = { cdc_dma_tx_sample_rate_put), }; +static const struct snd_kcontrol_new msm_int_wcd9380_snd_controls[] = { + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 Format", rx_cdc80_dma_rx_0_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 Format", rx_cdc80_dma_rx_1_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 Format", rx_cdc80_dma_rx_2_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 Format", rx_cdc80_dma_rx_3_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 Format", rx_cdc80_dma_rx_5_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 SampleRate", + rx_cdc80_dma_rx_0_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 SampleRate", + rx_cdc80_dma_rx_1_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 SampleRate", + rx_cdc80_dma_rx_2_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 SampleRate", + rx_cdc80_dma_rx_3_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 SampleRate", + rx_cdc80_dma_rx_5_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), +}; + +static const struct snd_kcontrol_new msm_int_wcd9385_snd_controls[] = { + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 Format", rx_cdc85_dma_rx_0_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 Format", rx_cdc85_dma_rx_1_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 Format", rx_cdc85_dma_rx_2_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 Format", rx_cdc85_dma_rx_3_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 Format", rx_cdc85_dma_rx_5_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 SampleRate", + rx_cdc85_dma_rx_0_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 SampleRate", + rx_cdc85_dma_rx_1_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 SampleRate", + rx_cdc85_dma_rx_2_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 SampleRate", + rx_cdc85_dma_rx_3_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 SampleRate", + rx_cdc85_dma_rx_5_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), +}; + static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, usb_audio_rx_sample_rate_get, @@ -7155,6 +7216,7 @@ static int msm_aux_codec_init(struct snd_soc_component *component) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); int ret = 0; + int codec_variant = -1; void *mbhc_calibration; struct snd_info_entry *entry; struct snd_card *card = component->card->snd_card; @@ -7184,6 +7246,23 @@ static int msm_aux_codec_init(struct snd_soc_component *component) } wcd938x_info_create_codec_entry(pdata->codec_root, component); + codec_variant = wcd938x_get_codec_variant(component); + dev_dbg(component->dev, "%s: variant %d\n", __func__, codec_variant); + if (codec_variant == WCD9380) + ret = snd_soc_add_component_controls(component, + msm_int_wcd9380_snd_controls, + ARRAY_SIZE(msm_int_wcd9380_snd_controls)); + else if (codec_variant == WCD9385) + ret = snd_soc_add_component_controls(component, + msm_int_wcd9385_snd_controls, + ARRAY_SIZE(msm_int_wcd9385_snd_controls)); + + if (ret < 0) { + dev_err(component->dev, "%s: add codec specific snd controls failed: %d\n", + __func__, ret); + return ret; + } + mbhc_cfg_cal: mbhc_calibration = def_wcd_mbhc_cal(); if (!mbhc_calibration) -- GitLab From 5d52dd8613ae70d7bd3f4155e13d00d9b0ed655e Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 15 Aug 2019 16:58:08 -0700 Subject: [PATCH 1154/1645] soc: swr-mstr: Reduce swr register write sleep timings Reduce swr bulk write and swr command fifo write sleeps to reach coldstart latency numbers. Change-Id: I52f2868a488e167b0a0f617b6af3e79cbf6f7eea Signed-off-by: Karthikeyan Mani --- soc/swr-mstr-ctrl.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index f184e1bccfcb..f16f1d837744 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -397,7 +397,11 @@ static int swr_master_bulk_write(struct swr_mstr_ctrl *swrm, u32 *reg_addr, mutex_lock(&swrm->iolock); for (i = 0; i < length; i++) { /* wait for FIFO WR command to complete to avoid overflow */ - usleep_range(100, 105); + /* + * Reduce sleep from 100us to 10us to meet KPIs + * This still meets the hardware spec + */ + usleep_range(10, 12); swr_master_write(swrm, reg_addr[i], val[i]); } mutex_unlock(&swrm->iolock); @@ -559,7 +563,7 @@ static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data, * skip delay if write is handled in platform driver. */ if(!swrm->write) - usleep_range(250, 255); + usleep_range(150, 155); if (cmd_id == 0xF) { /* * sleep for 10ms for MSM soundwire variant to allow broadcast -- GitLab From d5ab1f48b2d09b253ee44bf04962cf79e7edacab Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 14 Aug 2019 17:33:36 +0530 Subject: [PATCH 1155/1645] asoc: codecs: wcd934x: Add NULL checks for mbhc Add NULL checks for mbhc in tavil driver to avoid NULL pointer dereferences when MBHC is not supported. Change-Id: I43bfd062af6048486256f744bd028b27fedc7f53 Signed-off-by: Aditya Bavanari --- asoc/codecs/wcd934x/wcd934x.c | 85 ++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index ea928f022d3d..50c83fa76b1a 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -2377,9 +2377,10 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_PRE_PMD: tavil_ocp_control(component, false); - blocking_notifier_call_chain(&tavil->mbhc->notifier, - WCD_EVENT_PRE_HPHR_PA_OFF, - &tavil->mbhc->wcd_mbhc); + if (tavil->mbhc) + blocking_notifier_call_chain(&tavil->mbhc->notifier, + WCD_EVENT_PRE_HPHR_PA_OFF, + &tavil->mbhc->wcd_mbhc); /* Enable DSD Mute before PA disable */ if (dsd_conf && (snd_soc_component_read32(component, @@ -2409,9 +2410,10 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, else usleep_range(5000, 5100); tavil_codec_override(component, tavil->hph_mode, event); - blocking_notifier_call_chain(&tavil->mbhc->notifier, - WCD_EVENT_POST_HPHR_PA_OFF, - &tavil->mbhc->wcd_mbhc); + if (tavil->mbhc) + blocking_notifier_call_chain(&tavil->mbhc->notifier, + WCD_EVENT_POST_HPHR_PA_OFF, + &tavil->mbhc->wcd_mbhc); if (TAVIL_IS_1_0(tavil->wcd9xxx)) snd_soc_component_update_bits(component, WCD934X_HPH_REFBUFF_LP_CTL, @@ -2554,9 +2556,10 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_PRE_PMD: tavil_ocp_control(component, false); - blocking_notifier_call_chain(&tavil->mbhc->notifier, - WCD_EVENT_PRE_HPHL_PA_OFF, - &tavil->mbhc->wcd_mbhc); + if (tavil->mbhc) + blocking_notifier_call_chain(&tavil->mbhc->notifier, + WCD_EVENT_PRE_HPHL_PA_OFF, + &tavil->mbhc->wcd_mbhc); /* Enable DSD Mute before PA disable */ if (dsd_conf && (snd_soc_component_read32(component, @@ -2588,9 +2591,10 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, else usleep_range(5000, 5100); tavil_codec_override(component, tavil->hph_mode, event); - blocking_notifier_call_chain(&tavil->mbhc->notifier, - WCD_EVENT_POST_HPHL_PA_OFF, - &tavil->mbhc->wcd_mbhc); + if (tavil->mbhc) + blocking_notifier_call_chain(&tavil->mbhc->notifier, + WCD_EVENT_POST_HPHL_PA_OFF, + &tavil->mbhc->wcd_mbhc); if (TAVIL_IS_1_0(tavil->wcd9xxx)) snd_soc_component_update_bits(component, WCD934X_HPH_REFBUFF_LP_CTL, @@ -5436,9 +5440,10 @@ static void tavil_codec_hph_reg_recover(struct tavil_priv *tavil, int i; unsigned int reg; - blocking_notifier_call_chain(&tavil->mbhc->notifier, - WCD_EVENT_OCP_OFF, - &tavil->mbhc->wcd_mbhc); + if (tavil->mbhc) + blocking_notifier_call_chain(&tavil->mbhc->notifier, + WCD_EVENT_OCP_OFF, + &tavil->mbhc->wcd_mbhc); if (pa_status & 0xC0) goto pa_en_restore; @@ -5548,11 +5553,13 @@ static void tavil_codec_hph_reg_recover(struct tavil_priv *tavil, } end: - tavil->mbhc->is_hph_recover = true; - blocking_notifier_call_chain( - &tavil->mbhc->notifier, - WCD_EVENT_OCP_ON, - &tavil->mbhc->wcd_mbhc); + if (tavil->mbhc) { + tavil->mbhc->is_hph_recover = true; + blocking_notifier_call_chain( + &tavil->mbhc->notifier, + WCD_EVENT_OCP_ON, + &tavil->mbhc->wcd_mbhc); + } } static int tavil_codec_reset_hph_registers(struct snd_soc_dapm_widget *w, @@ -5596,7 +5603,8 @@ static int tavil_codec_reset_hph_registers(struct snd_soc_dapm_widget *w, } else { dev_dbg(component->dev, "%s: cache and hw reg are same\n", __func__); - tavil->mbhc->is_hph_recover = false; + if (tavil->mbhc) + tavil->mbhc->is_hph_recover = false; } break; default: @@ -10292,7 +10300,8 @@ static int tavil_device_down(struct wcd9xxx *wcd9xxx) priv->dai[count].bus_down_in_recovery = true; snd_event_notify(priv->dev->parent, SND_EVENT_DOWN); - priv->mbhc->wcd_mbhc.deinit_in_progress = true; + if (priv->mbhc) + priv->mbhc->wcd_mbhc.deinit_in_progress = true; if (delayed_work_pending(&priv->spk_anc_dwork.dwork)) cancel_delayed_work(&priv->spk_anc_dwork.dwork); for (decimator = 0; decimator < WCD934X_NUM_DECIMATORS; decimator++) { @@ -10307,11 +10316,14 @@ static int tavil_device_down(struct wcd9xxx *wcd9xxx) } if (delayed_work_pending(&priv->power_gate_work)) cancel_delayed_work_sync(&priv->power_gate_work); - if (delayed_work_pending(&priv->mbhc->wcd_mbhc.mbhc_btn_dwork)) { - ret = cancel_delayed_work(&priv->mbhc->wcd_mbhc.mbhc_btn_dwork); - if (ret) - priv->mbhc->wcd_mbhc.mbhc_cb->lock_sleep - (&priv->mbhc->wcd_mbhc, false); + if (priv->mbhc) { + if (delayed_work_pending(&priv->mbhc->wcd_mbhc.mbhc_btn_dwork)) { + ret = cancel_delayed_work( + &priv->mbhc->wcd_mbhc.mbhc_btn_dwork); + if (ret) + priv->mbhc->wcd_mbhc.mbhc_cb->lock_sleep + (&priv->mbhc->wcd_mbhc, false); + } } if (priv->swr.ctrl_data) { @@ -10397,16 +10409,17 @@ static int tavil_post_reset_cb(struct wcd9xxx *wcd9xxx) dev_err(component->dev, "%s: invalid pdata\n", __func__); /* Initialize MBHC module */ - mbhc = &tavil->mbhc->wcd_mbhc; - ret = tavil_mbhc_post_ssr_init(tavil->mbhc, component); - if (ret) { - dev_err(component->dev, "%s: mbhc initialization failed\n", - __func__); - goto done; - } else { - tavil_mbhc_hs_detect(component, mbhc->mbhc_cfg); + if (tavil->mbhc) { + mbhc = &tavil->mbhc->wcd_mbhc; + ret = tavil_mbhc_post_ssr_init(tavil->mbhc, component); + if (ret) { + dev_err(component->dev, "%s: mbhc initialization failed\n", + __func__); + goto done; + } else { + tavil_mbhc_hs_detect(component, mbhc->mbhc_cfg); + } } - /* DSD initialization */ ret = tavil_dsd_post_ssr_init(tavil->dsd_config); if (ret) -- GitLab From 5d8f35764957b493acf09387564189c63082ae9a Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 31 Jul 2019 14:23:37 +0530 Subject: [PATCH 1156/1645] asoc: codecs: wcd937x: Update amic4 over adc3 recording Update AMIC4 over adc3 for wcd9375 as per HW sequences. Change-Id: Ie7c3713bee67d32cb7fba042848f52bcded8f4b0 Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd937x/wcd937x.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index fe0c65cfed52..2a7857a4e277 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1349,19 +1349,25 @@ static int wcd937x_enable_req(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD937X_ANA_TX_CH2, 0x40, 0x40); snd_soc_component_update_bits(component, - WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x30, 0x30); + WCD937X_ANA_TX_CH3_HPF, 0x40, 0x40); + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x70, 0x70); snd_soc_component_update_bits(component, WCD937X_ANA_TX_CH1, 0x80, 0x80); snd_soc_component_update_bits(component, WCD937X_ANA_TX_CH2, 0x40, 0x00); snd_soc_component_update_bits(component, WCD937X_ANA_TX_CH2, 0x80, 0x80); + snd_soc_component_update_bits(component, + WCD937X_ANA_TX_CH3, 0x80, 0x80); break; case SND_SOC_DAPM_POST_PMD: snd_soc_component_update_bits(component, WCD937X_ANA_TX_CH1, 0x80, 0x00); snd_soc_component_update_bits(component, WCD937X_ANA_TX_CH2, 0x80, 0x00); + snd_soc_component_update_bits(component, + WCD937X_ANA_TX_CH3, 0x80, 0x00); snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x10, 0x00); mutex_lock(&wcd937x->ana_tx_clk_lock); -- GitLab From fa73f15146f5c392fc4d1a0b1cac56733c4f2286 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Fri, 16 Aug 2019 21:34:23 -0700 Subject: [PATCH 1157/1645] ASoC: qdsp6v2: increase RTAC_MAX_ACTIVE_DEVICES to 6 To support up to 6 audio paths activated with different devices, increase RTAC_MAX_ACTIVE_DEVICES from 4 to 6. Change-Id: I16c1247b2b2bafdc646d412a75192494bf0e2b95 Signed-off-by: Derek Chen --- include/dsp/rtac.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dsp/rtac.h b/include/dsp/rtac.h index 1b4541cfa37c..7b047a34a95b 100644 --- a/include/dsp/rtac.h +++ b/include/dsp/rtac.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2011, 2013-2015, 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2013-2015, 2017-2019, The Linux Foundation. All rights reserved. */ #ifndef __RTAC_H__ @@ -13,7 +13,7 @@ #define RTAC_CVS 1 #define RTAC_VOICE_MODES 2 -#define RTAC_MAX_ACTIVE_DEVICES 4 +#define RTAC_MAX_ACTIVE_DEVICES 6 #define RTAC_MAX_ACTIVE_POPP 8 #define DEFAULT_APP_TYPE 0x00011130 -- GitLab From c0f75b77270d5e4bc37ad960390158ec0897f8b1 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 16 Jul 2019 06:04:10 +0530 Subject: [PATCH 1158/1645] ASoC: bolero: check for port validation before configuration Check for valid port before mux configuration. Change-Id: Iaa32925f0c23305a2a3cedd0e476372aac380e0c Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/rx-macro.c | 18 ++++++++++++++---- asoc/codecs/bolero/wsa-macro.c | 19 +++++++++++++++---- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 03dea2093639..1fe591f86997 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1810,14 +1810,23 @@ static int rx_macro_mux_put(struct snd_kcontrol *kcontrol, dev_err(rx_dev, "%s:AIF reset already\n", __func__); return 0; } + if (aif_rst > RX_MACRO_AIF4_PB) { + dev_err(rx_dev, "%s: Invalid AIF reset\n", __func__); + return 0; + } } rx_priv->rx_port_value[widget->shift] = rx_port_value; + dev_dbg(rx_dev, "%s: mux input: %d, mux output: %d, aif_rst: %d\n", + __func__, rx_port_value, widget->shift, aif_rst); + switch (rx_port_value) { case 0: - clear_bit(widget->shift, - &rx_priv->active_ch_mask[aif_rst]); - rx_priv->active_ch_cnt[aif_rst]--; + if (rx_priv->active_ch_cnt[aif_rst]) { + clear_bit(widget->shift, + &rx_priv->active_ch_mask[aif_rst]); + rx_priv->active_ch_cnt[aif_rst]--; + } break; case 1: case 2: @@ -1829,7 +1838,8 @@ static int rx_macro_mux_put(struct snd_kcontrol *kcontrol, break; default: dev_err(component->dev, - "%s:Invalid AIF_ID for RX_MACRO MUX\n", __func__); + "%s:Invalid AIF_ID for RX_MACRO MUX %d\n", + __func__, rx_port_value); goto err; } diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 928aec0d5e0d..dd12ad237362 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -2057,6 +2057,10 @@ static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol, dev_err(wsa_dev, "%s: AIF reset already\n", __func__); return 0; } + if (aif_rst >= WSA_MACRO_RX_MAX) { + dev_err(wsa_dev, "%s: Invalid AIF reset\n", __func__); + return 0; + } } wsa_priv->rx_port_value[widget->shift] = rx_port_value; @@ -2064,11 +2068,17 @@ static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol, if (widget->shift >= WSA_MACRO_RX_MIX) bit_input %= WSA_MACRO_RX_MIX; + dev_dbg(wsa_dev, + "%s: mux input: %d, mux output: %d, bit: %d\n", + __func__, rx_port_value, widget->shift, bit_input); + switch (rx_port_value) { case 0: - clear_bit(bit_input, - &wsa_priv->active_ch_mask[aif_rst]); - wsa_priv->active_ch_cnt[aif_rst]--; + if (wsa_priv->active_ch_cnt[aif_rst]) { + clear_bit(bit_input, + &wsa_priv->active_ch_mask[aif_rst]); + wsa_priv->active_ch_cnt[aif_rst]--; + } break; case 1: case 2: @@ -2078,7 +2088,8 @@ static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol, break; default: dev_err(wsa_dev, - "%s: Invalid AIF_ID for WSA RX MUX\n", __func__); + "%s: Invalid AIF_ID for WSA RX MUX %d\n", + __func__, rx_port_value); return -EINVAL; } -- GitLab From b06682d3e5ebefa13011fb620f919431f980bc5f Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Mon, 5 Aug 2019 16:08:41 +0530 Subject: [PATCH 1159/1645] dsp: increase maximum active streams count DSP supports maximum fifteen active streams. Increase active stream count to fifteen. Change-Id: I1312ece8cc8bf8040b728718edfb9b5c7ad48b33 --- dsp/q6asm.c | 2 +- include/dsp/q6asm-v2.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 475e04577b28..37ea0d07cdcb 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1581,7 +1581,7 @@ int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir, __func__, ac->session, bufsz, bufcnt); - if (ac->session <= 0 || ac->session > 8) { + if (ac->session <= 0 || ac->session > ASM_ACTIVE_STREAMS_ALLOWED) { pr_err("%s: Session ID is invalid, session = %d\n", __func__, ac->session); goto fail; diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index 5db8fde22ad9..5ad8fb0f6abe 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -95,7 +95,7 @@ #define SOFT_PAUSE_ENABLE 1 #define SOFT_PAUSE_DISABLE 0 -#define ASM_ACTIVE_STREAMS_ALLOWED 0x8 +#define ASM_ACTIVE_STREAMS_ALLOWED 0xF /* Control session is used for mapping calibration memory */ #define ASM_CONTROL_SESSION (ASM_ACTIVE_STREAMS_ALLOWED + 1) -- GitLab From 757b75448954e79baf78de56f882b5d1b8618cca Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Mon, 19 Aug 2019 15:14:37 -0700 Subject: [PATCH 1160/1645] ASoC: routing: update echo reference index for dp Add display port 1 to the end of echo reference rx array. This avoids shifting the existing ports and their index mapping. Add a new switch case to return the echo reference port id for display port 1. CRs-Fixed: 2511612 Change-Id: I2ba9cf5e9c9fc687d429a04f40a32231c0913f5e Signed-off-by: Vignesh Kulothungan --- asoc/msm-pcm-routing-v2.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index ffd09e889be5..f9bd2daceac5 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -5410,6 +5410,10 @@ static int get_ec_ref_port_id(int value, int *index) *index = 36; port_id = AFE_PORT_ID_SECONDARY_TDM_TX; break; + case 37: + *index = 37; + port_id = AFE_PORT_ID_HDMI_OVER_DP_RX; + break; default: *index = 0; /* NONE */ pr_err("%s: Invalid value %d\n", __func__, value); @@ -5450,9 +5454,10 @@ static const char *const ec_ref_rate_text[] = {"0", "8000", "16000", "32000", "44100", "48000", "96000", "192000", "384000"}; static const struct soc_enum msm_route_ec_ref_params_enum[] = { - SOC_ENUM_SINGLE_EXT(17, ec_ref_ch_text), - SOC_ENUM_SINGLE_EXT(3, ec_ref_bit_format_text), - SOC_ENUM_SINGLE_EXT(9, ec_ref_rate_text), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ec_ref_ch_text), ec_ref_ch_text), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ec_ref_bit_format_text), + ec_ref_bit_format_text), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ec_ref_rate_text), ec_ref_rate_text), }; static const char *const ec_ref_rx[] = { "None", "SLIM_RX", "I2S_RX", @@ -5462,11 +5467,11 @@ static const char *const ec_ref_rx[] = { "None", "SLIM_RX", "I2S_RX", "QUAT_TDM_RX_0", "QUAT_TDM_RX_1", "QUAT_TDM_RX_2", "SLIM_6_RX", "TERT_MI2S_RX", "QUAT_MI2S_RX", "TERT_TDM_TX_0", "USB_AUDIO_RX", "INT0_MI2S_RX", "INT4_MI2S_RX", "INT3_MI2S_TX", "DISPLAY_PORT", - "DISPLAY_PORT1", "WSA_CDC_DMA_RX_0", "WSA_CDC_DMA_RX_1", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_2", "SLIM_7_RX", "RX_CDC_DMA_RX_0", "RX_CDC_DMA_RX_1", "RX_CDC_DMA_RX_2", "RX_CDC_DMA_RX_3", "TX_CDC_DMA_TX_0", "TERT_TDM_RX_2", "SEC_TDM_TX_0", + "DISPLAY_PORT1", }; static const struct soc_enum msm_route_ec_ref_rx_enum[] = { -- GitLab From 18129b1c6d08158c9776ff8717cd3ef630222cbd Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 3 Jul 2019 17:22:20 +0530 Subject: [PATCH 1161/1645] asoc: Update the senary MI2S interface port id index Update the senary MI2S interface port id index to 5 as it uses this device ID. Change-Id: I7fc3040b35e1f3250b519b8c74fbbece5a2866bc Signed-off-by: Aditya Bavanari --- asoc/msm-dai-q6-v2.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/msm-dai-q6-v2.h b/asoc/msm-dai-q6-v2.h index b65e4e11d8be..d4d4dd8ba941 100644 --- a/asoc/msm-dai-q6-v2.h +++ b/asoc/msm-dai-q6-v2.h @@ -23,8 +23,8 @@ #define MSM_TERT_MI2S 2 #define MSM_QUAT_MI2S 3 #define MSM_QUIN_MI2S 4 -#define MSM_SEC_MI2S_SD1 5 -#define MSM_SENARY_MI2S 6 +#define MSM_SENARY_MI2S 5 +#define MSM_SEC_MI2S_SD1 6 #define MSM_INT0_MI2S 7 #define MSM_INT1_MI2S 8 #define MSM_INT2_MI2S 9 -- GitLab From 75ea1b8ade22cf035cf22974d12e78541eb7d97d Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 6 Aug 2019 13:42:54 -0700 Subject: [PATCH 1162/1645] asoc: codecs: bolero: load hph filter coefficients On hph playback usecase with compander enabled, load hph filter coefficients to better center gain errors. Change-Id: I3ce50d6e7b9a10255df8084adb0566d8bf9b47c7 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/rx-macro.c | 114 ++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 322d1de2aea6..c1d9013d6232 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -77,6 +77,8 @@ static const struct snd_kcontrol_new name##_mux = \ #define RX_MACRO_EC_MIX_TX1_MASK 0x0f #define RX_MACRO_EC_MIX_TX2_MASK 0x0f +#define COMP_MAX_COEFF 25 + struct wcd_imped_val { u32 imped_val; u8 index; @@ -95,6 +97,75 @@ static const struct wcd_imped_val imped_index[] = { {13, 9}, }; +struct comp_coeff_val { + u8 lsb; + u8 msb; +}; + +enum { + HPH_ULP, + HPH_LOHIFI, + HPH_MODE_MAX, +}; + +static const struct comp_coeff_val + comp_coeff_table [HPH_MODE_MAX][COMP_MAX_COEFF] = { + { + {0x40, 0x00}, + {0x4C, 0x00}, + {0x5A, 0x00}, + {0x6B, 0x00}, + {0x7F, 0x00}, + {0x97, 0x00}, + {0xB3, 0x00}, + {0xD5, 0x00}, + {0xFD, 0x00}, + {0x2D, 0x01}, + {0x66, 0x01}, + {0xA7, 0x01}, + {0xF8, 0x01}, + {0x57, 0x02}, + {0xC7, 0x02}, + {0x4B, 0x03}, + {0xE9, 0x03}, + {0xA3, 0x04}, + {0x7D, 0x05}, + {0x90, 0x06}, + {0xD1, 0x07}, + {0x49, 0x09}, + {0x00, 0x0B}, + {0x01, 0x0D}, + {0x59, 0x0F}, + }, + { + {0x40, 0x00}, + {0x4C, 0x00}, + {0x5A, 0x00}, + {0x6B, 0x00}, + {0x80, 0x00}, + {0x98, 0x00}, + {0xB4, 0x00}, + {0xD5, 0x00}, + {0xFE, 0x00}, + {0x2E, 0x01}, + {0x66, 0x01}, + {0xA9, 0x01}, + {0xF8, 0x01}, + {0x56, 0x02}, + {0xC4, 0x02}, + {0x4F, 0x03}, + {0xF0, 0x03}, + {0xAE, 0x04}, + {0x8B, 0x05}, + {0x8E, 0x06}, + {0xBC, 0x07}, + {0x56, 0x09}, + {0x0F, 0x0B}, + {0x13, 0x0D}, + {0x6F, 0x0F}, + }, +}; + struct rx_macro_reg_mask_val { u16 reg; u8 mask; @@ -1526,6 +1597,47 @@ static int rx_macro_config_compander(struct snd_soc_component *component, return 0; } +static int rx_macro_load_compander_coeff(struct snd_soc_component *component, + struct rx_macro_priv *rx_priv, + int interp_n, int event) +{ + int comp = 0; + u16 comp_coeff_lsb_reg = 0, comp_coeff_msb_reg = 0; + int i = 0; + int hph_pwr_mode = HPH_LOHIFI; + + if (!rx_priv->comp_enabled[comp]) + return 0; + + if (interp_n == INTERP_HPHL) { + comp_coeff_lsb_reg = BOLERO_CDC_RX_TOP_HPHL_COMP_WR_LSB; + comp_coeff_msb_reg = BOLERO_CDC_RX_TOP_HPHL_COMP_WR_MSB; + } else if (interp_n == INTERP_HPHR) { + comp_coeff_lsb_reg = BOLERO_CDC_RX_TOP_HPHR_COMP_WR_LSB; + comp_coeff_msb_reg = BOLERO_CDC_RX_TOP_HPHR_COMP_WR_MSB; + } else { + /* compander coefficients are loaded only for hph path */ + return 0; + } + + comp = interp_n; + hph_pwr_mode = rx_priv->hph_pwr_mode; + dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n", + __func__, event, comp + 1, rx_priv->comp_enabled[comp]); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Load Compander Coeff */ + for (i = 0; i < COMP_MAX_COEFF; i++) { + snd_soc_component_write(component, comp_coeff_lsb_reg, + comp_coeff_table[hph_pwr_mode][i].lsb); + snd_soc_component_write(component, comp_coeff_msb_reg, + comp_coeff_table[hph_pwr_mode][i].msb); + } + } + + return 0; +} + static void rx_macro_enable_softclip_clk(struct snd_soc_component *component, struct rx_macro_priv *rx_priv, bool enable) @@ -2235,6 +2347,8 @@ static int rx_macro_enable_interp_clk(struct snd_soc_component *component, 0x20, 0x20); snd_soc_component_update_bits(component, rx_cfg2_reg, 0x03, 0x03); + rx_macro_load_compander_coeff(component, rx_priv, + interp_idx, event); rx_macro_idle_detect_control(component, rx_priv, interp_idx, event); if (rx_priv->hph_hd2_mode) -- GitLab From 1dcd5a3ab4de2796e02b92cff329c479240bf78b Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 22 Aug 2019 14:37:13 -0700 Subject: [PATCH 1163/1645] asoc: codec: bolero: add adc mode control Add enum mixer control to support changing adc mode bits for different power modes in recording use case. Change-Id: I9a0287b7b32285d39e65f98b5518dedd3a24af94 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/tx-macro.c | 124 ++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index fda01e1304f5..8c32043c479e 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -41,6 +41,7 @@ #define TX_MACRO_TX_PATH_OFFSET 0x80 #define TX_MACRO_SWR_MIC_MUX_SEL_MASK 0xF #define TX_MACRO_ADC_MUX_CFG_OFFSET 0x2 +#define TX_MACRO_ADC_MODE_CFG0_SHIFT 1 #define TX_MACRO_TX_UNMUTE_DELAY_MS 40 @@ -163,6 +164,7 @@ struct tx_macro_priv { int va_clk_status; int tx_clk_status; bool bcs_enable; + int dec_mode[NUM_DECIMATORS]; }; static bool tx_macro_get_data(struct snd_soc_component *component, @@ -609,6 +611,91 @@ static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, return 0; } + +static inline int tx_macro_path_get(const char *wname, + unsigned int *path_num) +{ + int ret = 0; + char *widget_name = NULL; + char *w_name = NULL; + char *path_num_char = NULL; + char *path_name = NULL; + + widget_name = kstrndup(wname, 10, GFP_KERNEL); + if (!widget_name) + return -EINVAL; + + w_name = widget_name; + + path_name = strsep(&widget_name, " "); + if (!path_name) { + pr_err("%s: Invalid widget name = %s\n", + __func__, widget_name); + ret = -EINVAL; + goto err; + } + path_num_char = strpbrk(path_name, "01234567"); + if (!path_num_char) { + pr_err("%s: tx path index not found\n", + __func__); + ret = -EINVAL; + goto err; + } + ret = kstrtouint(path_num_char, 10, path_num); + if (ret < 0) + pr_err("%s: Invalid tx path = %s\n", + __func__, w_name); + +err: + kfree(w_name); + return ret; +} + +static int tx_macro_dec_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tx_macro_priv *tx_priv = NULL; + struct device *tx_dev = NULL; + int ret = 0; + int path = 0; + + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + ret = tx_macro_path_get(kcontrol->id.name, &path); + if (ret) + return ret; + + ucontrol->value.integer.value[0] = tx_priv->dec_mode[path]; + + return 0; +} + +static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tx_macro_priv *tx_priv = NULL; + struct device *tx_dev = NULL; + int value = ucontrol->value.integer.value[0]; + int ret = 0; + int path = 0; + + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + ret = tx_macro_path_get(kcontrol->id.name, &path); + if (ret) + return ret; + + tx_priv->dec_mode[path] = value; + + return 0; +} + static int tx_macro_get_bcs(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -759,6 +846,9 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + snd_soc_component_update_bits(component, + dec_cfg_reg, 0x06, tx_priv->dec_mode[decimator] << + TX_MACRO_ADC_MODE_CFG0_SHIFT); /* Enable TX PGA Mute */ snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x10); @@ -840,6 +930,8 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMD: snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x20, 0x00); + snd_soc_component_update_bits(component, + dec_cfg_reg, 0x06, 0x00); snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x00); if (tx_priv->bcs_enable) { @@ -1111,6 +1203,14 @@ TX_MACRO_DAPM_ENUM_EXT(tx_smic7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0, smic_mux_text, snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +static const char * const dec_mode_mux_text[] = { + "ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF", +}; + +static const struct soc_enum dec_mode_mux_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text); + static const struct snd_kcontrol_new tx_aif1_cap_mixer[] = { SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0, tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), @@ -1586,6 +1686,30 @@ static const struct snd_kcontrol_new tx_macro_snd_controls[] = { BOLERO_CDC_TX7_TX_VOL_CTL, 0, -84, 40, digital_gain), + SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum, + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC1 MODE", dec_mode_mux_enum, + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC2 MODE", dec_mode_mux_enum, + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC3 MODE", dec_mode_mux_enum, + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC4 MODE", dec_mode_mux_enum, + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC5 MODE", dec_mode_mux_enum, + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC6 MODE", dec_mode_mux_enum, + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC7 MODE", dec_mode_mux_enum, + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + SOC_SINGLE_EXT("DEC0_BCS Switch", SND_SOC_NOPM, 0, 1, 0, tx_macro_get_bcs, tx_macro_set_bcs), }; -- GitLab From 43c0abd0c04b019d4fd5a5c1078e7e94f8fd4470 Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Fri, 26 Jul 2019 15:12:48 +0200 Subject: [PATCH 1164/1645] dsp: Add support for META MI2S ports QCS405 can group data lines of several MI2S interfaces. This feature is used with new META MI2S ports. Change-Id: I0d8c2de742e04d7348e40e1026b1640c3f987479 Signed-off-by: Ralf Herz --- dsp/q6afe.c | 18 +++++++ dsp/q6audio-v2.c | 12 +++++ include/dsp/apr_audio-v2.h | 102 +++++++++++++++++++++++++++++++++++-- include/dsp/q6afe-v2.h | 3 ++ 4 files changed, 131 insertions(+), 4 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 20ff03974313..9709772ab88b 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -915,6 +915,10 @@ int afe_sizeof_cfg_cmd(u16 port_id) case AFE_PORT_ID_SENARY_MI2S_TX: ret_size = SIZEOF_CFG_CMD(afe_param_id_i2s_cfg); break; + case AFE_PORT_ID_PRIMARY_META_MI2S_RX: + case AFE_PORT_ID_SECONDARY_META_MI2S_RX: + ret_size = SIZEOF_CFG_CMD(afe_param_id_meta_i2s_cfg); + break; case HDMI_RX: case DISPLAY_PORT_RX: ret_size = @@ -4556,6 +4560,10 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, case AFE_PORT_ID_INT6_MI2S_TX: cfg_type = AFE_PARAM_ID_I2S_CONFIG; break; + case AFE_PORT_ID_PRIMARY_META_MI2S_RX: + case AFE_PORT_ID_SECONDARY_META_MI2S_RX: + cfg_type = AFE_PARAM_ID_META_I2S_CONFIG; + break; case HDMI_RX: case DISPLAY_PORT_RX: cfg_type = AFE_PARAM_ID_HDMI_CONFIG; @@ -5091,6 +5099,10 @@ int afe_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_INT6_MI2S_RX; case AFE_PORT_ID_INT6_MI2S_TX: return IDX_AFE_PORT_ID_INT6_MI2S_TX; + case AFE_PORT_ID_PRIMARY_META_MI2S_RX: + return IDX_AFE_PORT_ID_PRIMARY_META_MI2S_RX; + case AFE_PORT_ID_SECONDARY_META_MI2S_RX: + return IDX_AFE_PORT_ID_SECONDARY_META_MI2S_RX; case AFE_PORT_ID_VA_CODEC_DMA_TX_0: return IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_0; case AFE_PORT_ID_VA_CODEC_DMA_TX_1: @@ -5254,6 +5266,10 @@ int afe_open(u16 port_id, case AFE_PORT_ID_SENARY_MI2S_TX: cfg_type = AFE_PARAM_ID_I2S_CONFIG; break; + case AFE_PORT_ID_PRIMARY_META_MI2S_RX: + case AFE_PORT_ID_SECONDARY_META_MI2S_RX: + cfg_type = AFE_PARAM_ID_META_I2S_CONFIG; + break; case HDMI_RX: case DISPLAY_PORT_RX: cfg_type = AFE_PARAM_ID_HDMI_CONFIG; @@ -7231,6 +7247,8 @@ int afe_validate_port(u16 port_id) case AFE_PORT_ID_QUINARY_MI2S_TX: case AFE_PORT_ID_SENARY_MI2S_RX: case AFE_PORT_ID_SENARY_MI2S_TX: + case AFE_PORT_ID_PRIMARY_META_MI2S_RX: + case AFE_PORT_ID_SECONDARY_META_MI2S_RX: case AFE_PORT_ID_PRIMARY_TDM_RX: case AFE_PORT_ID_PRIMARY_TDM_TX: case AFE_PORT_ID_PRIMARY_TDM_RX_1: diff --git a/dsp/q6audio-v2.c b/dsp/q6audio-v2.c index 8de60605f1be..68b373629a18 100644 --- a/dsp/q6audio-v2.c +++ b/dsp/q6audio-v2.c @@ -337,6 +337,10 @@ int q6audio_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_INT6_MI2S_RX; case AFE_PORT_ID_INT6_MI2S_TX: return IDX_AFE_PORT_ID_INT6_MI2S_TX; + case AFE_PORT_ID_PRIMARY_META_MI2S_RX: + return IDX_AFE_PORT_ID_PRIMARY_META_MI2S_RX; + case AFE_PORT_ID_SECONDARY_META_MI2S_RX: + return IDX_AFE_PORT_ID_SECONDARY_META_MI2S_RX; case AFE_PORT_ID_WSA_CODEC_DMA_RX_0: return IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_0; case AFE_PORT_ID_WSA_CODEC_DMA_TX_0: @@ -487,6 +491,10 @@ int q6audio_get_port_id(u16 port_id) return AUDIO_PORT_ID_I2S_RX; case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1: return AFE_PORT_ID_SECONDARY_MI2S_RX_SD1; + case AFE_PORT_ID_PRIMARY_META_MI2S_RX: + return AFE_PORT_ID_PRIMARY_META_MI2S_RX; + case AFE_PORT_ID_SECONDARY_META_MI2S_RX: + return AFE_PORT_ID_SECONDARY_META_MI2S_RX; case AFE_PORT_ID_PRIMARY_TDM_RX: return AFE_PORT_ID_PRIMARY_TDM_RX; case AFE_PORT_ID_PRIMARY_TDM_TX: @@ -820,6 +828,8 @@ int q6audio_is_digital_pcm_interface(u16 port_id) case AFE_PORT_ID_SECONDARY_MI2S_TX: case AUDIO_PORT_ID_I2S_RX: case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1: + case AFE_PORT_ID_PRIMARY_META_MI2S_RX: + case AFE_PORT_ID_SECONDARY_META_MI2S_RX: case AFE_PORT_ID_PRIMARY_TDM_RX: case AFE_PORT_ID_PRIMARY_TDM_TX: case AFE_PORT_ID_PRIMARY_TDM_RX_1: @@ -1048,6 +1058,8 @@ int q6audio_validate_port(u16 port_id) case AFE_PORT_ID_QUINARY_MI2S_RX: case AFE_PORT_ID_QUINARY_MI2S_TX: case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1: + case AFE_PORT_ID_PRIMARY_META_MI2S_RX: + case AFE_PORT_ID_SECONDARY_META_MI2S_RX: case AFE_PORT_ID_PRIMARY_TDM_RX: case AFE_PORT_ID_PRIMARY_TDM_TX: case AFE_PORT_ID_PRIMARY_TDM_RX_1: diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index a9a552e1abe9..0fcc76ae842a 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1505,6 +1505,9 @@ struct adm_cmd_connect_afe_port_v5 { /* ID of the senary auxiliary PCM Tx port. */ #define AFE_PORT_ID_SENARY_PCM_TX 0x103F +#define AFE_PORT_ID_PRIMARY_META_MI2S_RX 0x1300 +#define AFE_PORT_ID_SECONDARY_META_MI2S_RX 0x1302 + #define AFE_PORT_ID_PRIMARY_SPDIF_RX 0x5000 #define AFE_PORT_ID_PRIMARY_SPDIF_TX 0x5001 #define AFE_PORT_ID_SECONDARY_SPDIF_RX 0x5002 @@ -2650,6 +2653,98 @@ struct afe_param_id_i2s_cfg { /* This field must be set to zero. */ } __packed; +/* This param id is used to configure META I2S interface */ +#define AFE_PARAM_ID_META_I2S_CONFIG 0x000102C5 +#define AFE_API_VERSION_META_I2S_CONFIG 0x1 +#define MAX_NUM_I2S_META_PORT_MEMBER_PORTS 4 + +/* Payload of the #AFE_PARAM_ID_META_I2S_CONFIG + * command's (I2S configuration + * parameter). + */ +struct afe_param_id_meta_i2s_cfg { + u32 minor_version; +/* Minor version used for tracking the version of the I2S + * configuration interface. + * Supported values: #AFE_API_VERSION_META_I2S_CONFIG + */ + + u16 bit_width; +/* Bit width of the sample. + * Supported values: 16, 24 + */ + + u16 ws_src; +/* Word select source: internal or external. + * Supported values: + * - #AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL + * - #AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL + */ + + u32 sample_rate; +/* Sampling rate of the port. + * Supported values: + * - #AFE_PORT_SAMPLE_RATE_8K + * - #AFE_PORT_SAMPLE_RATE_16K + * - #AFE_PORT_SAMPLE_RATE_48K + * - #AFE_PORT_SAMPLE_RATE_96K + * - #AFE_PORT_SAMPLE_RATE_192K + */ + + u16 member_port_id[MAX_NUM_I2S_META_PORT_MEMBER_PORTS]; +/* Array of member port IDs in this meta device. + * Supported values: + * - #AFE_PORT_ID_PRIMARY_MI2S_RX + * - #AFE_PORT_ID_SECONDARY_MI2S_RX + * - #AFE_PORT_ID_TERTIARY_MI2S_RX + * - #AFE_PORT_ID_QUATERNY_MI2S_RX + * - #AFE_PORT_ID_INVALID + * + * Fill these values from index 0. Set unused index to AFE_PORT_ID_INVALID. + * + * Note: + * the first member port will act as WS master in case + * meta port ws_src is configured as AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL. + * In all other cases member ports will act as slave. + * This must be considered when HLOS enables the interface clocks + */ + + u16 member_port_channel_mode[MAX_NUM_I2S_META_PORT_MEMBER_PORTS]; +/* I2S lines and multichannel operation per member port. + * The sequence matches the sequence in member_port_id, + * value will be ignored if member port is set to AFE_PORT_ID_INVALID + * + * Supported values: + * - #AFE_PORT_I2S_SD0 + * - #AFE_PORT_I2S_SD1 + * - #AFE_PORT_I2S_SD2 + * - #AFE_PORT_I2S_SD3 + * - #AFE_PORT_I2S_QUAD01 + * - #AFE_PORT_I2S_QUAD23 + * - #AFE_PORT_I2S_6CHS + * - #AFE_PORT_I2S_8CHS + * - #AFE_PORT_I2S_10CHS + * - #AFE_PORT_I2S_12CHS + * - #AFE_PORT_I2S_14CHS + * - #AFE_PORT_I2S_16CHS + * - #AFE_PORT_I2S_SD4 + * - #AFE_PORT_I2S_SD5 + * - #AFE_PORT_I2S_SD6 + * - #AFE_PORT_I2S_SD7 + * - #AFE_PORT_I2S_QUAD45 + * - #AFE_PORT_I2S_QUAD67 + * - #AFE_PORT_I2S_8CHS_2 + */ + + u16 data_format; +/* data format + * Supported values: + * - #LINEAR_PCM_DATA + */ + u16 reserved; + /* This field must be set to zero. */ +} __packed; + /* * This param id is used to configure PCM interface */ @@ -4846,6 +4941,7 @@ struct afe_param_id_cdc_dma_cfg_t { union afe_port_config { struct afe_param_id_pcm_cfg pcm; struct afe_param_id_i2s_cfg i2s; + struct afe_param_id_meta_i2s_cfg meta_i2s; struct afe_param_id_hdmi_multi_chan_audio_cfg hdmi_multi_ch; struct afe_param_id_slimbus_cfg slim_sch; struct afe_param_id_rt_proxy_port_cfg rtproxy; @@ -5663,9 +5759,7 @@ struct asm_softvolume_params { /* Left side direct channel. */ #define PCM_CHANNEL_LSD 33 -/* Right side direct channel. Update PCM_MAX_CHMAP_ID when - * this list is extended. - */ +/* Right side direct channel. */ #define PCM_CHANNEL_RSD 34 /* Mark unused channel. */ @@ -5690,7 +5784,7 @@ struct asm_softvolume_params { #define PCM_MAX_CHANNEL_MAP 63 /* Max valid channel map index */ -#define PCM_MAX_CHMAP_ID PCM_CHANNEL_RSD +#define PCM_MAX_CHMAP_ID PCM_MAX_CHANNEL_MAP #define PCM_FORMAT_MAX_NUM_CHANNEL 8 #define PCM_FORMAT_MAX_CHANNELS_9 9 diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 9504ad6fb1b9..d1b4f3ccedfd 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -281,6 +281,9 @@ enum { IDX_AFE_PORT_ID_SENARY_TDM_TX_6, IDX_AFE_PORT_ID_SENARY_TDM_RX_7, IDX_AFE_PORT_ID_SENARY_TDM_TX_7, + /* IDX 208-> 209 */ + IDX_AFE_PORT_ID_PRIMARY_META_MI2S_RX, + IDX_AFE_PORT_ID_SECONDARY_META_MI2S_RX, AFE_MAX_PORTS }; -- GitLab From 2e285bf25d018dc9b304a9090bb443305c4065b3 Mon Sep 17 00:00:00 2001 From: Ajit Pandey Date: Mon, 26 Aug 2019 16:06:51 +0530 Subject: [PATCH 1165/1645] dsp: avtimer: validate payload size before memory copy Check payload size to avoid out-of-boundary memory access before attemptimg memory read. Change-Id: I94723b526449aacfe7b2fe30990fb77cdd15c5da Signed-off-by: Ajit Pandey --- dsp/avtimer.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dsp/avtimer.c b/dsp/avtimer.c index 8d9402c91730..39b5268ef78e 100644 --- a/dsp/avtimer.c +++ b/dsp/avtimer.c @@ -89,6 +89,13 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) } payload1 = data->payload; + + if (data->payload_size < 2 * sizeof(uint32_t)) { + pr_err("%s: payload has invalid size %d\n", + __func__, data->payload_size); + return -EINVAL; + } + switch (payload1[0]) { case AVCS_CMD_REMOTE_AVTIMER_RELEASE_REQUEST: pr_debug("%s: Cmd = TIMER RELEASE status[0x%x]\n", @@ -114,6 +121,11 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) } case AVCS_CMD_RSP_REMOTE_AVTIMER_VOTE_REQUEST: + if (data->payload_size < sizeof(uint32_t)) { + pr_err("%s: payload has invalid size %d\n", + __func__, data->payload_size); + return -EINVAL; + } payload1 = data->payload; pr_debug("%s: RSP_REMOTE_AVTIMER_VOTE_REQUEST handle %x\n", __func__, payload1[0]); -- GitLab From 594cedb3dd310e46037751f25e2d2604b2a25651 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 15 Aug 2019 15:30:24 +0530 Subject: [PATCH 1166/1645] ASoC: codecs: Use resource managed function calls during irq exit wcd_init_irq uses resource managed irq addition. Similarly, use resource managed irq deletion in wcd_irq_exit. Change-Id: I67c702c1d2fbec0c7fd496672fae03a82cb63048 Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd-irq.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd-irq.c b/asoc/codecs/wcd-irq.c index 3c8e777ec859..d4890a6dd6a4 100644 --- a/asoc/codecs/wcd-irq.c +++ b/asoc/codecs/wcd-irq.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -178,7 +178,8 @@ int wcd_irq_exit(struct wcd_irq_info *irq_info, struct irq_domain *virq) return -EINVAL; } - regmap_del_irq_chip(irq_find_mapping(virq, 0), irq_info->irq_chip); + devm_regmap_del_irq_chip(irq_info->dev, irq_find_mapping(virq, 0), + irq_info->irq_chip); return 0; } -- GitLab From 6b01d100ee0cc91b797a7ffb1d45090cd2d955d4 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 27 Aug 2019 15:14:25 +0530 Subject: [PATCH 1167/1645] asoc: codecs: bolero: audio HM voting only supported on bengal On bengal target, audio HM voting is only applicable. Update bolero driver to make audio HM vote if audio core handle is not present. Change-Id: I9abaf42c04aa8f1b89d9c08e628ab142ce99151a Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 6f81dab723a6..f3f338686274 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -1050,12 +1050,12 @@ int bolero_runtime_resume(struct device *dev) struct bolero_priv *priv = dev_get_drvdata(dev->parent); int ret = 0; + mutex_lock(&priv->vote_lock); if (priv->lpass_core_hw_vote == NULL) { dev_dbg(dev, "%s: Invalid lpass core hw node\n", __func__); - return 0; + goto audio_vote; } - mutex_lock(&priv->vote_lock); if (priv->core_hw_vote_count == 0) { ret = clk_prepare_enable(priv->lpass_core_hw_vote); if (ret < 0) { -- GitLab From 9f599b4a78c8f798fab8655641cfd74e42fdaef0 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 27 Aug 2019 22:18:41 +0530 Subject: [PATCH 1168/1645] soc: Fix out of bounds access in register show function In register show function, when snprintf returns a negative value out of bounds access occurs while copying the data to user. Add return value check on snprintf before copy_to_user to fix this. Change-Id: I96bfa64b1603c966852c1d4d4a12651664f17aed Signed-off-by: Aditya Bavanari --- soc/swr-mstr-ctrl.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index c4deb20014ea..b42cd5f49437 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -144,6 +144,11 @@ static ssize_t swrm_reg_show(char __user *ubuf, size_t count, i <= SWR_MSTR_MAX_REG_ADDR; i += 4) { reg_val = dbgswrm->read(dbgswrm->handle, i); len = snprintf(tmp_buf, 25, "0x%.3x: 0x%.2x\n", i, reg_val); + if (len < 0) { + pr_err("%s: fail to fill the buffer\n", __func__); + total = -EFAULT; + goto copy_err; + } if ((total + len) >= count - 1) break; if (copy_to_user((ubuf + total), tmp_buf, len)) { -- GitLab From cf16dedb1f058b9cc72a316d718363889c17346a Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Tue, 23 Jul 2019 15:55:48 +0200 Subject: [PATCH 1169/1645] asoc: codecs: No I2C activity when EP92 is inactive Only trigger periodic I2C telegrams when EP92 is in logical power on state. Rely on EP92 interrupt to notice state change when in power off state. Fix arc_enable write operation. Change-Id: Id36f90379280ca5c60984e2ed507844418a612d7 Signed-off-by: Ralf Herz --- asoc/codecs/ep92/ep92.c | 171 ++++++++++++++++++++++++++++++++++------ 1 file changed, 148 insertions(+), 23 deletions(-) diff --git a/asoc/codecs/ep92/ep92.c b/asoc/codecs/ep92/ep92.c index 06d29ff8207f..4d481039ffda 100644 --- a/asoc/codecs/ep92/ep92.c +++ b/asoc/codecs/ep92/ep92.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -25,6 +25,7 @@ #define EP92_POLL_INTERVAL_OFF_MSEC 200 #define EP92_POLL_INTERVAL_ON_MSEC 20 +#define EP92_POLL_RUNOUT_MSEC 5000 #define EP92_SYSFS_ENTRY_MAX_LEN 64 #define EP92_HYST_CNT 5 @@ -68,6 +69,9 @@ struct ep92_pdata { struct timer_list timer; struct work_struct read_status_worker; int irq; + int poll_trig; + int poll_rem; + int force_inactive; int hyst_tx_plug; int hyst_link_on0; @@ -648,10 +652,8 @@ static int ep92_probe(struct snd_soc_component *component) ep92_init(component, ep92); /* start polling when codec is registered */ - if (ep92->irq == 0) { - mod_timer(&ep92->timer, jiffies + - msecs_to_jiffies(EP92_POLL_INTERVAL_OFF_MSEC)); - } + mod_timer(&ep92->timer, jiffies + + msecs_to_jiffies(EP92_POLL_INTERVAL_OFF_MSEC)); return 0; } @@ -690,6 +692,9 @@ void ep92_read_status(struct work_struct *work) if (component == NULL) return; + if (ep92->force_inactive) + return; + /* check ADO_CHF that is set when audio format has changed */ val = snd_soc_component_read32(component, EP92_BI_GENERAL_INFO_1); if (val == 0xff) { @@ -724,6 +729,10 @@ static irqreturn_t ep92_irq(int irq, void *data) dev_dbg(component->dev, "ep92_interrupt\n"); + ep92->poll_trig = 1; + mod_timer(&ep92->timer, jiffies + + msecs_to_jiffies(EP92_POLL_INTERVAL_ON_MSEC)); + schedule_work(&ep92->read_status_worker); return IRQ_HANDLED; @@ -732,14 +741,45 @@ static irqreturn_t ep92_irq(int irq, void *data) void ep92_poll_status(struct timer_list *t) { struct ep92_pdata *ep92 = from_timer(ep92, t, timer); - u32 poll_msec; + struct snd_soc_component *component = ep92->component; - if ((ep92->gc.ctl & EP92_GC_POWER_MASK) == 0) - poll_msec = EP92_POLL_INTERVAL_OFF_MSEC; - else - poll_msec = EP92_POLL_INTERVAL_ON_MSEC; + if (ep92->force_inactive) + return; - mod_timer(&ep92->timer, jiffies + msecs_to_jiffies(poll_msec)); + /* if no IRQ is configured, always keep on polling */ + if (ep92->irq == 0) + ep92->poll_rem = EP92_POLL_RUNOUT_MSEC; + + /* on interrupt, start polling for some time */ + if (ep92->poll_trig) { + if (ep92->poll_rem == 0) + dev_info(component->dev, "status checking activated\n"); + + ep92->poll_trig = 0; + ep92->poll_rem = EP92_POLL_RUNOUT_MSEC; + } + + /* + * If power_on == 0, poll only until poll_rem reaches zero and stop. + * This allows to system to go to low power sleep mode. + * Otherwise (power_on == 1) always re-arm timer to keep on polling. + */ + if ((ep92->gc.ctl & EP92_GC_POWER_MASK) == 0) { + if (ep92->poll_rem) { + mod_timer(&ep92->timer, jiffies + + msecs_to_jiffies(EP92_POLL_INTERVAL_OFF_MSEC)); + if (ep92->poll_rem > EP92_POLL_INTERVAL_OFF_MSEC) { + ep92->poll_rem -= EP92_POLL_INTERVAL_OFF_MSEC; + } else { + dev_info(component->dev, "status checking stopped\n"); + ep92->poll_rem = 0; + } + } + } else { + ep92->poll_rem = EP92_POLL_RUNOUT_MSEC; + mod_timer(&ep92->timer, jiffies + + msecs_to_jiffies(EP92_POLL_INTERVAL_ON_MSEC)); + } schedule_work(&ep92->read_status_worker); } @@ -1162,6 +1202,11 @@ static ssize_t ep92_sysfs_wta_power(struct device *dev, ep92->gc.ctl &= ~EP92_GC_POWER_MASK; ep92->gc.ctl |= (val << EP92_GC_POWER_SHIFT) & EP92_GC_POWER_MASK; + if (val == 1) { + ep92->poll_trig = 1; + mod_timer(&ep92->timer, jiffies + + msecs_to_jiffies(EP92_POLL_INTERVAL_ON_MSEC)); + } rc = strnlen(buf, EP92_SYSFS_ENTRY_MAX_LEN); end: return rc; @@ -1321,12 +1366,12 @@ static ssize_t ep92_sysfs_wta_arc_enable(struct device *dev, } reg = snd_soc_component_read32(ep92->component, EP92_GENERAL_CONTROL_0); - reg &= ~EP92_GC_AUDIO_PATH_MASK; - reg |= (val << EP92_GC_AUDIO_PATH_SHIFT) & EP92_GC_AUDIO_PATH_MASK; + reg &= ~EP92_GC_ARC_EN_MASK; + reg |= (val << EP92_GC_ARC_EN_SHIFT) & EP92_GC_ARC_EN_MASK; snd_soc_component_write(ep92->component, EP92_GENERAL_CONTROL_0, reg); - ep92->gc.ctl &= ~EP92_GC_AUDIO_PATH_MASK; - ep92->gc.ctl |= (val << EP92_GC_AUDIO_PATH_SHIFT) & - EP92_GC_AUDIO_PATH_MASK; + ep92->gc.ctl &= ~EP92_GC_ARC_EN_MASK; + ep92->gc.ctl |= (val << EP92_GC_ARC_EN_SHIFT) & + EP92_GC_ARC_EN_MASK; rc = strnlen(buf, EP92_SYSFS_ENTRY_MAX_LEN); end: @@ -1440,6 +1485,83 @@ static ssize_t ep92_sysfs_wta_cec_volume(struct device *dev, return rc; } +static ssize_t ep92_sysfs_rda_runout(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; + } + + val = ep92->poll_rem; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_rda_force_inactive(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; + } + + val = ep92->force_inactive; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_wta_force_inactive(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int val, rc; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; + } + + rc = kstrtoint(buf, 10, &val); + if (rc) { + dev_err(dev, "%s: kstrtoint failed. rc=%d\n", __func__, rc); + goto end; + } + if ((val < 0) || (val > 1)) { + dev_err(dev, "%s: value out of range.\n", __func__); + rc = -EINVAL; + goto end; + } + + if (val == 0) { + ep92->force_inactive = 0; + ep92->poll_trig = 1; + mod_timer(&ep92->timer, jiffies + + msecs_to_jiffies(EP92_POLL_INTERVAL_ON_MSEC)); + } else { + ep92->force_inactive = 1; + ep92->poll_rem = 0; + } + + rc = strnlen(buf, EP92_SYSFS_ENTRY_MAX_LEN); +end: + return rc; +} + static DEVICE_ATTR(chipid, 0444, ep92_sysfs_rda_chipid, NULL); static DEVICE_ATTR(version, 0444, ep92_sysfs_rda_version, NULL); static DEVICE_ATTR(audio_state, 0444, ep92_sysfs_rda_audio_state, NULL); @@ -1467,6 +1589,9 @@ static DEVICE_ATTR(cec_mute, 0644, ep92_sysfs_rda_cec_mute, ep92_sysfs_wta_cec_mute); static DEVICE_ATTR(cec_volume, 0644, ep92_sysfs_rda_cec_volume, ep92_sysfs_wta_cec_volume); +static DEVICE_ATTR(runout, 0444, ep92_sysfs_rda_runout, NULL); +static DEVICE_ATTR(force_inactive, 0644, ep92_sysfs_rda_force_inactive, + ep92_sysfs_wta_force_inactive); static struct attribute *ep92_fs_attrs[] = { &dev_attr_chipid.attr, @@ -1490,6 +1615,8 @@ static struct attribute *ep92_fs_attrs[] = { &dev_attr_arc_enable.attr, &dev_attr_cec_mute.attr, &dev_attr_cec_volume.attr, + &dev_attr_runout.attr, + &dev_attr_force_inactive.attr, NULL, }; @@ -1552,9 +1679,9 @@ static int ep92_i2c_probe(struct i2c_client *client, ep92->irq = 0; } } - /* poll status if IRQ is not configured */ - if (ep92->irq == 0) - timer_setup(&ep92->timer, ep92_poll_status, 0); + /* prepare timer */ + timer_setup(&ep92->timer, ep92_poll_status, 0); + ep92->poll_rem = EP92_POLL_RUNOUT_MSEC; #if IS_ENABLED(CONFIG_DEBUG_FS) /* debugfs interface */ @@ -1610,8 +1737,7 @@ static int ep92_i2c_probe(struct i2c_client *client, err_sysfs: snd_soc_unregister_component(&client->dev); err_reg: - if (ep92->irq == 0) - del_timer(&ep92->timer); + del_timer(&ep92->timer); return ret; } @@ -1622,8 +1748,7 @@ static int ep92_i2c_remove(struct i2c_client *client) ep92 = i2c_get_clientdata(client); if (ep92) { - if (ep92->irq == 0) - del_timer(&ep92->timer); + del_timer(&ep92->timer); #if IS_ENABLED(CONFIG_DEBUG_FS) debugfs_remove_recursive(ep92->debugfs_dir); -- GitLab From 05441f67891232c7fc6de1980099b10d4ff9e094 Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Fri, 26 Jul 2019 11:17:02 +0200 Subject: [PATCH 1170/1645] asoc: codecs: Add ep92 pre-emphasis status Provide pre-emphasis status in sysfs node that was received in channel status bits. Change-Id: Ice6f69806c993e2235b5ecb89dfc4028c03e02b8 Signed-off-by: Ralf Herz --- asoc/codecs/ep92/ep92.c | 46 ++++++++++++++++++++++++++++++++++------- asoc/codecs/ep92/ep92.h | 4 +++- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/asoc/codecs/ep92/ep92.c b/asoc/codecs/ep92/ep92.c index 4d481039ffda..607707044152 100644 --- a/asoc/codecs/ep92/ep92.c +++ b/asoc/codecs/ep92/ep92.c @@ -564,15 +564,23 @@ static void ep92_read_audio_info(struct snd_soc_component *component, send_uevent = true; } + old = ep92->ai.cs[0]; + ep92->ai.cs[0] = snd_soc_component_read32(component, + EP92_AUDIO_INFO_CHANNEL_STATUS_0); + if (ep92->ai.cs[0] == 0xff) { + dev_dbg(component->dev, "ep92 EP92_AUDIO_INFO_CHANNEL_STATUS_0 read 0xff\n"); + ep92->ai.cs[0] = old; + } + change = ep92->ai.cs[0] ^ old; + if (change & EP92_AI_PREEMPH_MASK) { + dev_dbg(component->dev, "ep92 preemph changed to %d\n", + (ep92->ai.cs[0] & EP92_AI_PREEMPH_MASK) >> + EP92_AI_PREEMPH_SHIFT); + send_uevent = true; + } + new_mode = ep92->old_mode; if (ep92->ai.audio_status & EP92_AI_STD_ADO_MASK) { - old = ep92->ai.cs[0]; - ep92->ai.cs[0] = snd_soc_component_read32(component, - EP92_AUDIO_INFO_CHANNEL_STATUS_0); - if (ep92->ai.cs[0] == 0xff) { - dev_dbg(component->dev, "ep92 EP92_AUDIO_INFO_CHANNEL_STATUS_0 read 0xff\n"); - ep92->ai.cs[0] = old; - } if (ep92->ai.cs[0] & EP92_AI_NPCM_MASK) new_mode = 1; /* Compr */ else @@ -973,7 +981,7 @@ static ssize_t ep92_sysfs_rda_audio_ch_alloc(struct device *dev, return ret; } -static ssize_t ep92_sysfs_rda_avmute(struct device *dev, +static ssize_t ep92_sysfs_rda_audio_preemph(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t ret; @@ -985,6 +993,26 @@ static ssize_t ep92_sysfs_rda_avmute(struct device *dev, return -ENODEV; } + val = (ep92->ai.cs[0] & EP92_AI_PREEMPH_MASK) >> + EP92_AI_PREEMPH_SHIFT; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); + + return ret; +} + +static ssize_t ep92_sysfs_rda_avmute(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92 || !ep92->component) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; + } val = (ep92->ai.system_status_0 >> EP92_AI_AVMUTE_SHIFT) & EP92_2CHOICE_MASK; @@ -1570,6 +1598,7 @@ static DEVICE_ATTR(audio_rate, 0444, ep92_sysfs_rda_audio_rate, NULL); static DEVICE_ATTR(audio_layout, 0444, ep92_sysfs_rda_audio_layout, NULL); static DEVICE_ATTR(audio_ch_count, 0444, ep92_sysfs_rda_audio_ch_count, NULL); static DEVICE_ATTR(audio_ch_alloc, 0444, ep92_sysfs_rda_audio_ch_alloc, NULL); +static DEVICE_ATTR(audio_preemph, 0444, ep92_sysfs_rda_audio_preemph, NULL); static DEVICE_ATTR(audio_avmute, 0444, ep92_sysfs_rda_avmute, NULL); static DEVICE_ATTR(link_on0, 0444, ep92_sysfs_rda_link_on0, NULL); static DEVICE_ATTR(link_on1, 0444, ep92_sysfs_rda_link_on1, NULL); @@ -1602,6 +1631,7 @@ static struct attribute *ep92_fs_attrs[] = { &dev_attr_audio_layout.attr, &dev_attr_audio_ch_count.attr, &dev_attr_audio_ch_alloc.attr, + &dev_attr_audio_preemph.attr, &dev_attr_audio_avmute.attr, &dev_attr_link_on0.attr, &dev_attr_link_on1.attr, diff --git a/asoc/codecs/ep92/ep92.h b/asoc/codecs/ep92/ep92.h index bfc8d8000d87..18cb0105f56c 100644 --- a/asoc/codecs/ep92/ep92.h +++ b/asoc/codecs/ep92/ep92.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #ifndef __EP92_H__ @@ -171,6 +171,8 @@ static struct reg_default ep92_reg_defaults[] = { #define EP92_AI_STD_ADO_MASK 0x08 #define EP92_AI_RATE_MASK 0x07 #define EP92_AI_NPCM_MASK 0x02 +#define EP92_AI_PREEMPH_SHIFT 3 +#define EP92_AI_PREEMPH_MASK 0x38 #define EP92_AI_CH_COUNT_MASK 0x07 #define EP92_AI_CH_ALLOC_MASK 0xff -- GitLab From 2725174a505a41903d18588b7119e185c01acc0c Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Mon, 24 Jun 2019 17:31:03 +0200 Subject: [PATCH 1171/1645] asoc: Add sysfs node for spdif pre-emphase status Provide pre-emphasis status in sysfs node that was received in spdif channel status bits. Change-Id: Ie25dd67920e2d73f74328d6ce96180d392f3d771 Signed-off-by: Ralf Herz --- asoc/msm-dai-q6-v2.c | 53 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 7cb2c0b258c4..08a96b474de4 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -35,6 +35,9 @@ #define CHANNEL_STATUS_SIZE 24 #define CHANNEL_STATUS_MASK_INIT 0x0 #define CHANNEL_STATUS_MASK 0x4 +#define PREEMPH_MASK 0x38 +#define PREEMPH_SHIFT 3 +#define GET_PREEMPH(b) ((b & PREEMPH_MASK) >> PREEMPH_SHIFT) #define AFE_API_VERSION_CLOCK_SET 1 #define MSM_DAI_SYSFS_ENTRY_MAX_LEN 64 @@ -1718,22 +1721,41 @@ static void msm_dai_q6_spdif_process_event(uint32_t opcode, uint32_t token, { struct msm_dai_q6_spdif_event_msg *evt; struct msm_dai_q6_spdif_dai_data *dai_data; + int preemph_old = 0; + int preemph_new = 0; evt = (struct msm_dai_q6_spdif_event_msg *)payload; dai_data = (struct msm_dai_q6_spdif_dai_data *)private_data; - pr_debug("%s: old state %d, fmt %d, rate %d\n", + preemph_old = GET_PREEMPH(dai_data->fmt_event.channel_status[0]); + preemph_new = GET_PREEMPH(evt->fmt_event.channel_status[0]); + + pr_debug("%s: old state %d, fmt %d, rate %d, preemph %d\n", __func__, dai_data->fmt_event.status, dai_data->fmt_event.data_format, - dai_data->fmt_event.sample_rate); - pr_debug("%s: new state %d, fmt %d, rate %d\n", + dai_data->fmt_event.sample_rate, + preemph_old); + pr_debug("%s: new state %d, fmt %d, rate %d, preemph %d\n", __func__, evt->fmt_event.status, evt->fmt_event.data_format, - evt->fmt_event.sample_rate); + evt->fmt_event.sample_rate, + preemph_new); dai_data->fmt_event.status = evt->fmt_event.status; dai_data->fmt_event.data_format = evt->fmt_event.data_format; dai_data->fmt_event.sample_rate = evt->fmt_event.sample_rate; + dai_data->fmt_event.channel_status[0] = + evt->fmt_event.channel_status[0]; + dai_data->fmt_event.channel_status[1] = + evt->fmt_event.channel_status[1]; + dai_data->fmt_event.channel_status[2] = + evt->fmt_event.channel_status[2]; + dai_data->fmt_event.channel_status[3] = + evt->fmt_event.channel_status[3]; + dai_data->fmt_event.channel_status[4] = + evt->fmt_event.channel_status[4]; + dai_data->fmt_event.channel_status[5] = + evt->fmt_event.channel_status[5]; } static int msm_dai_q6_spdif_hw_params(struct snd_pcm_substream *substream, @@ -1877,17 +1899,40 @@ static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_rate(struct device *dev, return ret; } +static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_preemph(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dev); + int preemph = 0; + + if (!dai_data) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + preemph = GET_PREEMPH(dai_data->fmt_event.channel_status[0]); + + ret = snprintf(buf, MSM_DAI_SYSFS_ENTRY_MAX_LEN, "%d\n", preemph); + pr_debug("%s: '%d'\n", __func__, preemph); + + return ret; +} + static DEVICE_ATTR(audio_state, 0444, msm_dai_q6_spdif_sysfs_rda_audio_state, NULL); static DEVICE_ATTR(audio_format, 0444, msm_dai_q6_spdif_sysfs_rda_audio_format, NULL); static DEVICE_ATTR(audio_rate, 0444, msm_dai_q6_spdif_sysfs_rda_audio_rate, NULL); +static DEVICE_ATTR(audio_preemph, 0444, + msm_dai_q6_spdif_sysfs_rda_audio_preemph, NULL); static struct attribute *msm_dai_q6_spdif_fs_attrs[] = { &dev_attr_audio_state.attr, &dev_attr_audio_format.attr, &dev_attr_audio_rate.attr, + &dev_attr_audio_preemph.attr, NULL, }; static struct attribute_group msm_dai_q6_spdif_fs_attrs_group = { -- GitLab From 52ae6581d76103f7509cada26faf3a8f6215aa0a Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 8 Aug 2019 18:00:35 +0530 Subject: [PATCH 1172/1645] asoc: codecs: bolero: Fix L/R swap issue on bolero RX Left and right channel content can get swapped in new cdc_dma interface. DMA interfaces underrun results in Channels being swapped. This issue is a side effect current SW setup for RX path: 1. HLOS Setup WCD Analog Path, Bolero CODEC. CODEC would drive Fs to LPASS DMAs requesting for PCM samples. 2. DSP setup RX Buffers in Memory : 3. DSP Configures RD DMAs and DMA RXTX CODEC interface (Enable CODEC DMA interface buffer and Enable DMA LPASS_RXTX_LPAIF_RDDMA_CTL0.ENABLE and LPASS_RXTX_LPAIF_RDDMA_CODEC_INTF0.ENABLE If CODEC Fs, aligns with DMA interface being enabled there is an underrun as DMA interface pingpong buffer is empty. This results in channels being swapped. Proposed work around while keeping current SW setup order. Provide a workaround to Keep Fs disabled until DMAs and CODEC DMA interface are enabled and HW could prefetch all buffers. SW would keep existing setup order: 1. HLOS Setup WCD Analog Path, Bolero CODEC. CODEC would drive Fs to LPASS DMAs requesting for PCM samples. 2. DSP setup RX Buffers in Memory : 3. DSP Configures DMAs and DMA CODEC interface (Enable CODEC DMA interface buffer and Enable DMA LPASS_RXTX_LPAIF_RDDMA_CTL0.ENABLE and LPASS_RXTX_LPAIF_RDDMA_CODEC_INTF0.ENABLE) 4. Enable Fs Set #LPASS_RX_CDC_RX0_RX_PATH_CTL. CLK_EN to ONE Change-Id: I7916667f5d857464cc7d77b51da307ab234cc7bb Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 120 ++++++++++++++++++++++++----- asoc/codecs/bolero/wsa-macro.c | 134 +++++++++++++++++++++++++++++++-- 2 files changed, 227 insertions(+), 27 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index c6a9d3dd62fb..98754bf91820 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -280,6 +280,7 @@ static int rx_macro_hw_params(struct snd_pcm_substream *substream, static int rx_macro_get_channel_map(struct snd_soc_dai *dai, unsigned int *tx_num, unsigned int *tx_slot, unsigned int *rx_num, unsigned int *rx_slot); +static int rx_macro_digital_mute(struct snd_soc_dai *dai, int mute); static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); static int rx_macro_mux_get(struct snd_kcontrol *kcontrol, @@ -570,6 +571,7 @@ static const struct snd_kcontrol_new rx_mix_tx0_mux = static struct snd_soc_dai_ops rx_macro_dai_ops = { .hw_params = rx_macro_hw_params, .get_channel_map = rx_macro_get_channel_map, + .digital_mute = rx_macro_digital_mute, }; static struct snd_soc_dai_driver rx_macro_dai[] = { @@ -844,9 +846,9 @@ static int rx_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, component, int_mux_cfg0); int_mux_cfg1_val = snd_soc_component_read32( component, int_mux_cfg1); - inp0_sel = int_mux_cfg0_val & 0x07; - inp1_sel = (int_mux_cfg0_val >> 4) & 0x038; - inp2_sel = (int_mux_cfg1_val >> 4) & 0x038; + inp0_sel = int_mux_cfg0_val & 0x0F; + inp1_sel = (int_mux_cfg0_val >> 4) & 0x0F; + inp2_sel = (int_mux_cfg1_val >> 4) & 0x0F; if ((inp0_sel == int_1_mix1_inp) || (inp1_sel == int_1_mix1_inp) || (inp2_sel == int_1_mix1_inp)) { @@ -897,7 +899,7 @@ static int rx_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, for (j = 0; j < INTERP_MAX; j++) { int_mux_cfg1_val = snd_soc_component_read32( component, int_mux_cfg1) & - 0x07; + 0x0F; if (int_mux_cfg1_val == int_2_inp) { int_fs_reg = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL + 0x80 * j; @@ -1056,6 +1058,57 @@ static int rx_macro_get_channel_map(struct snd_soc_dai *dai, return 0; } +static int rx_macro_digital_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_component *component = dai->component; + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + uint16_t j = 0, reg = 0, mix_reg = 0, dsm_reg = 0; + u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0; + u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0; + + if (mute) + return 0; + + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + switch (dai->id) { + case RX_MACRO_AIF1_PB: + case RX_MACRO_AIF2_PB: + case RX_MACRO_AIF3_PB: + case RX_MACRO_AIF4_PB: + for (j = 0; j < INTERP_MAX; j++) { + reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + + (j * RX_MACRO_RX_PATH_OFFSET); + mix_reg = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL + + (j * RX_MACRO_RX_PATH_OFFSET); + dsm_reg = BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL + + (j * RX_MACRO_RX_PATH_OFFSET); + if (j == INTERP_AUX) + dsm_reg = BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL; + int_mux_cfg0 = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0 + j * 8; + int_mux_cfg1 = int_mux_cfg0 + 4; + int_mux_cfg0_val = snd_soc_component_read32(component, + int_mux_cfg0); + int_mux_cfg1_val = snd_soc_component_read32(component, + int_mux_cfg1); + if (snd_soc_component_read32(component, dsm_reg) & 0x01) { + if (int_mux_cfg0_val || (int_mux_cfg1_val & 0xF0)) + snd_soc_component_update_bits(component, + reg, 0x20, 0x20); + if (int_mux_cfg1_val & 0x0F) + snd_soc_component_update_bits(component, + mix_reg, 0x20, 0x20); + } + } + break; + default: + break; + } + return 0; +} + static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, bool mclk_enable, bool dapm) { @@ -1412,8 +1465,6 @@ static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w, rx_macro_set_idle_detect_thr(component, rx_priv, w->shift, INTERP_MIX_PATH); rx_macro_enable_interp_clk(component, event, w->shift); - /* Clk enable */ - snd_soc_component_update_bits(component, mix_reg, 0x20, 0x20); break; case SND_SOC_DAPM_POST_PMU: snd_soc_component_write(component, gain_reg, @@ -1432,6 +1483,42 @@ static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w, return 0; } +static bool rx_macro_adie_lb(struct snd_soc_component *component, + int interp_idx) +{ + u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0; + u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0; + u8 int_n_inp0 = 0, int_n_inp1 = 0, int_n_inp2 = 0; + + int_mux_cfg0 = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8; + int_mux_cfg1 = int_mux_cfg0 + 4; + int_mux_cfg0_val = snd_soc_component_read32(component, int_mux_cfg0); + int_mux_cfg1_val = snd_soc_component_read32(component, int_mux_cfg1); + + int_n_inp0 = int_mux_cfg0_val & 0x0F; + if (int_n_inp0 == INTn_1_INP_SEL_DEC0 || + int_n_inp0 == INTn_1_INP_SEL_DEC1 || + int_n_inp0 == INTn_1_INP_SEL_IIR0 || + int_n_inp0 == INTn_1_INP_SEL_IIR1) + return true; + + int_n_inp1 = int_mux_cfg0_val >> 4; + if (int_n_inp1 == INTn_1_INP_SEL_DEC0 || + int_n_inp1 == INTn_1_INP_SEL_DEC1 || + int_n_inp1 == INTn_1_INP_SEL_IIR0 || + int_n_inp1 == INTn_1_INP_SEL_IIR1) + return true; + + int_n_inp2 = int_mux_cfg1_val >> 4; + if (int_n_inp2 == INTn_1_INP_SEL_DEC0 || + int_n_inp2 == INTn_1_INP_SEL_DEC1 || + int_n_inp2 == INTn_1_INP_SEL_IIR0 || + int_n_inp2 == INTn_1_INP_SEL_IIR1) + return true; + + return false; +} + static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -1464,6 +1551,9 @@ static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w, rx_macro_set_idle_detect_thr(component, rx_priv, w->shift, INTERP_MAIN_PATH); rx_macro_enable_interp_clk(component, event, w->shift); + if (rx_macro_adie_lb(component, w->shift)) + snd_soc_component_update_bits(component, + reg, 0x20, 0x20); break; case SND_SOC_DAPM_POST_PMU: snd_soc_component_write(component, gain_reg, @@ -2240,9 +2330,6 @@ static int rx_macro_enable_interp_clk(struct snd_soc_component *component, 0x10, 0x10); snd_soc_component_update_bits(component, dsm_reg, 0x01, 0x01); - /* Clk enable */ - snd_soc_component_update_bits(component, main_reg, - 0x20, 0x20); snd_soc_component_update_bits(component, rx_cfg2_reg, 0x03, 0x03); rx_macro_idle_detect_control(component, rx_priv, @@ -2313,17 +2400,21 @@ static int rx_macro_enable_rx_path_clk(struct snd_soc_dapm_widget *w, { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - u16 sidetone_reg = 0; + u16 sidetone_reg = 0, fs_reg = 0; dev_dbg(component->dev, "%s %d %d\n", __func__, event, w->shift); sidetone_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG1 + RX_MACRO_RX_PATH_OFFSET * (w->shift); + fs_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + + RX_MACRO_RX_PATH_OFFSET * (w->shift); switch (event) { case SND_SOC_DAPM_PRE_PMU: rx_macro_enable_interp_clk(component, event, w->shift); snd_soc_component_update_bits(component, sidetone_reg, 0x10, 0x10); + snd_soc_component_update_bits(component, fs_reg, + 0x20, 0x20); break; case SND_SOC_DAPM_POST_PMD: snd_soc_component_update_bits(component, sidetone_reg, @@ -3432,15 +3523,6 @@ static int rx_macro_init(struct snd_soc_component *component) snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC3_INP"); snd_soc_dapm_sync(dapm); - snd_soc_component_update_bits(component, - BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL, - 0x01, 0x01); - snd_soc_component_update_bits(component, - BOLERO_CDC_RX_RX1_RX_PATH_DSM_CTL, - 0x01, 0x01); - snd_soc_component_update_bits(component, - BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL, - 0x01, 0x01); snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX0_RX_PATH_SEC7, 0x07, 0x02); snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX1_RX_PATH_SEC7, diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index dd12ad237362..623b64b0e5ec 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -88,6 +88,16 @@ enum { WSA_MACRO_SOFTCLIP_MAX }; +enum { + INTn_1_INP_SEL_ZERO = 0, + INTn_1_INP_SEL_RX0, + INTn_1_INP_SEL_RX1, + INTn_1_INP_SEL_RX2, + INTn_1_INP_SEL_RX3, + INTn_1_INP_SEL_DEC0, + INTn_1_INP_SEL_DEC1, +}; + struct interp_sample_rate { int sample_rate; int rate_val; @@ -129,6 +139,7 @@ static int wsa_macro_hw_params(struct snd_pcm_substream *substream, static int wsa_macro_get_channel_map(struct snd_soc_dai *dai, unsigned int *tx_num, unsigned int *tx_slot, unsigned int *rx_num, unsigned int *rx_slot); +static int wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute); /* Hold instance to soundwire platform device */ struct wsa_macro_swr_ctrl_data { struct platform_device *wsa_swr_pdev; @@ -358,6 +369,7 @@ static const struct snd_kcontrol_new rx_mix_ec1_mux = static struct snd_soc_dai_ops wsa_macro_dai_ops = { .hw_params = wsa_macro_hw_params, .get_channel_map = wsa_macro_get_channel_map, + .digital_mute = wsa_macro_digital_mute, }; static struct snd_soc_dai_driver wsa_macro_dai[] = { @@ -794,6 +806,53 @@ static int wsa_macro_get_channel_map(struct snd_soc_dai *dai, return 0; } +static int wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_component *component = dai->component; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + uint16_t j = 0, reg = 0, mix_reg = 0, dsm_reg = 0; + u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0; + u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0; + + if (mute) + return 0; + + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + switch (dai->id) { + case WSA_MACRO_AIF1_PB: + case WSA_MACRO_AIF_MIX1_PB: + for (j = 0; j < NUM_INTERPOLATORS; j++) { + reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL + + (j * WSA_MACRO_RX_PATH_OFFSET); + mix_reg = BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL + + (j * WSA_MACRO_RX_PATH_OFFSET); + dsm_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL + + (j * WSA_MACRO_RX_PATH_OFFSET) + + WSA_MACRO_RX_PATH_DSMDEM_OFFSET; + int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + j * 8; + int_mux_cfg1 = int_mux_cfg0 + 4; + int_mux_cfg0_val = snd_soc_component_read32(component, + int_mux_cfg0); + int_mux_cfg1_val = snd_soc_component_read32(component, + int_mux_cfg1); + if (snd_soc_component_read32(component, dsm_reg) & 0x01) { + if (int_mux_cfg0_val || (int_mux_cfg1_val & 0x38)) + snd_soc_component_update_bits(component, reg, + 0x20, 0x20); + if (int_mux_cfg1_val & 0x07) + snd_soc_component_update_bits(component, + mix_reg, 0x20, 0x20); + } + } + break; + default: + break; + } + return 0; +} static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv, bool mclk_enable, bool dapm) { @@ -1102,6 +1161,8 @@ static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w, snd_soc_component_write(component, gain_reg, val); break; case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, + w->reg, 0x20, 0x00); break; } @@ -1323,6 +1384,58 @@ static int wsa_macro_config_softclip(struct snd_soc_component *component, return 0; } +static bool wsa_macro_adie_lb(struct snd_soc_component *component, + int interp_idx) +{ + u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0; + u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0; + u8 int_n_inp0 = 0, int_n_inp1 = 0, int_n_inp2 = 0; + + int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8; + int_mux_cfg1 = int_mux_cfg0 + 4; + int_mux_cfg0_val = snd_soc_component_read32(component, int_mux_cfg0); + int_mux_cfg1_val = snd_soc_component_read32(component, int_mux_cfg1); + + int_n_inp0 = int_mux_cfg0_val & 0x0F; + if (int_n_inp0 == INTn_1_INP_SEL_DEC0 || + int_n_inp0 == INTn_1_INP_SEL_DEC1) + return true; + + int_n_inp1 = int_mux_cfg0_val >> 4; + if (int_n_inp1 == INTn_1_INP_SEL_DEC0 || + int_n_inp1 == INTn_1_INP_SEL_DEC1) + return true; + + int_n_inp2 = int_mux_cfg1_val >> 4; + if (int_n_inp2 == INTn_1_INP_SEL_DEC0 || + int_n_inp2 == INTn_1_INP_SEL_DEC1) + return true; + + return false; +} + +static int wsa_macro_enable_main_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + u16 reg = 0; + + reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL + + WSA_MACRO_RX_PATH_OFFSET * w->shift; + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (wsa_macro_adie_lb(component, w->shift)) + snd_soc_component_update_bits(component, + reg, 0x20, 0x20); + break; + default: + break; + } + return 0; +} + static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind) { u16 prim_int_reg = 0; @@ -1370,8 +1483,6 @@ static int wsa_macro_enable_prim_interpolator( snd_soc_component_update_bits(component, prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET, 0x1, 0x1); - snd_soc_component_update_bits(component, prim_int_reg, - 1 << 0x5, 1 << 0x5); } if ((reg != prim_int_reg) && ((snd_soc_component_read32( @@ -1384,6 +1495,9 @@ static int wsa_macro_enable_prim_interpolator( if (wsa_priv->prim_int_users[ind] == 0) { snd_soc_component_update_bits(component, prim_int_reg, 1 << 0x5, 0 << 0x5); + snd_soc_component_update_bits(component, + prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET, + 0x1, 0x0); snd_soc_component_update_bits(component, prim_int_reg, 0x40, 0x40); snd_soc_component_update_bits(component, prim_int_reg, @@ -2382,8 +2496,8 @@ static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = { SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0, &rx0_prim_inp2_mux, wsa_macro_enable_swr, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, 0, 0, - &rx0_mix_mux, wsa_macro_enable_mix_path, + SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL, + 0, 0, &rx0_mix_mux, wsa_macro_enable_mix_path, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0, &rx1_prim_inp0_mux, wsa_macro_enable_swr, @@ -2394,11 +2508,15 @@ static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = { SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0, &rx1_prim_inp2_mux, wsa_macro_enable_swr, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, 0, 0, - &rx1_mix_mux, wsa_macro_enable_mix_path, + SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL, + 0, 0, &rx1_mix_mux, wsa_macro_enable_mix_path, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("WSA_RX INT1 MIX", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER_E("WSA_RX INT0 MIX", SND_SOC_NOPM, + 0, 0, NULL, 0, wsa_macro_enable_main_path, + SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_MIXER_E("WSA_RX INT1 MIX", SND_SOC_NOPM, + 1, 0, NULL, 0, wsa_macro_enable_main_path, + SND_SOC_DAPM_PRE_PMU), SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), -- GitLab From 2139a7d17885270e9646eb7f3ad7570c6f0e1d3e Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Wed, 7 Aug 2019 12:07:20 -0700 Subject: [PATCH 1173/1645] ASoc: Kona: Add support for group AFE Add support to configure TDM slots. Add support to set tdm slot mask. CRs-Fixed: 2493194 Change-Id: I39cc7f2aee5acb28ea500076ff5026a033350b60 Signed-off-by: Vignesh Kulothungan --- asoc/kona.c | 293 +++++++++++++++++++++++++++++++++++-------- asoc/msm-dai-q6-v2.c | 35 +++++- 2 files changed, 276 insertions(+), 52 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index d91627b8b688..41a4ac6cdddb 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -75,6 +75,12 @@ #define WCN_CDC_SLIM_TX_CH_MAX 2 #define WCN_CDC_SLIM_TX_CH_MAX_LITO 3 +enum { + RX_PATH = 0, + TX_PATH, + MAX_PATH, +}; + enum { TDM_0 = 0, TDM_1, @@ -87,6 +93,9 @@ enum { TDM_PORT_MAX, }; +#define TDM_MAX_SLOTS 8 +#define TDM_SLOT_WIDTH_BITS 32 + enum { TDM_PRI = 0, TDM_SEC, @@ -176,6 +185,10 @@ struct tdm_port { u32 channel; }; +struct tdm_dev_config { + unsigned int tdm_slot_offset[TDM_MAX_SLOTS]; +}; + enum { EXT_DISP_RX_IDX_DP = 0, EXT_DISP_RX_IDX_DP1, @@ -462,6 +475,153 @@ static struct dev_config mi2s_tx_cfg[] = { [SEN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; +static struct tdm_dev_config pri_tdm_dev_config[MAX_PATH][TDM_PORT_MAX] = { + { /* PRI TDM */ + { {0, 4, 0xFFFF} }, /* RX_0 */ + { {8, 12, 0xFFFF} }, /* RX_1 */ + { {16, 20, 0xFFFF} }, /* RX_2 */ + { {24, 28, 0xFFFF} }, /* RX_3 */ + { {0xFFFF} }, /* RX_4 */ + { {0xFFFF} }, /* RX_5 */ + { {0xFFFF} }, /* RX_6 */ + { {0xFFFF} }, /* RX_7 */ + }, + { + { {0, 4, 8, 12, 0xFFFF} }, /* TX_0 */ + { {8, 12, 0xFFFF} }, /* TX_1 */ + { {16, 20, 0xFFFF} }, /* TX_2 */ + { {24, 28, 0xFFFF} }, /* TX_3 */ + { {0xFFFF} }, /* TX_4 */ + { {0xFFFF} }, /* TX_5 */ + { {0xFFFF} }, /* TX_6 */ + { {0xFFFF} }, /* TX_7 */ + }, +}; + +static struct tdm_dev_config sec_tdm_dev_config[MAX_PATH][TDM_PORT_MAX] = { + { /* SEC TDM */ + { {0, 4, 0xFFFF} }, /* RX_0 */ + { {8, 12, 0xFFFF} }, /* RX_1 */ + { {16, 20, 0xFFFF} }, /* RX_2 */ + { {24, 28, 0xFFFF} }, /* RX_3 */ + { {0xFFFF} }, /* RX_4 */ + { {0xFFFF} }, /* RX_5 */ + { {0xFFFF} }, /* RX_6 */ + { {0xFFFF} }, /* RX_7 */ + }, + { + { {0, 4, 0xFFFF} }, /* TX_0 */ + { {8, 12, 0xFFFF} }, /* TX_1 */ + { {16, 20, 0xFFFF} }, /* TX_2 */ + { {24, 28, 0xFFFF} }, /* TX_3 */ + { {0xFFFF} }, /* TX_4 */ + { {0xFFFF} }, /* TX_5 */ + { {0xFFFF} }, /* TX_6 */ + { {0xFFFF} }, /* TX_7 */ + }, +}; + +static struct tdm_dev_config tert_tdm_dev_config[MAX_PATH][TDM_PORT_MAX] = { + { /* TERT TDM */ + { {0, 4, 0xFFFF} }, /* RX_0 */ + { {8, 12, 0xFFFF} }, /* RX_1 */ + { {16, 20, 0xFFFF} }, /* RX_2 */ + { {24, 28, 0xFFFF} }, /* RX_3 */ + { {0xFFFF} }, /* RX_4 */ + { {0xFFFF} }, /* RX_5 */ + { {0xFFFF} }, /* RX_6 */ + { {0xFFFF} }, /* RX_7 */ + }, + { + { {0, 4, 0xFFFF} }, /* TX_0 */ + { {8, 12, 0xFFFF} }, /* TX_1 */ + { {16, 20, 0xFFFF} }, /* TX_2 */ + { {24, 28, 0xFFFF} }, /* TX_3 */ + { {0xFFFF} }, /* TX_4 */ + { {0xFFFF} }, /* TX_5 */ + { {0xFFFF} }, /* TX_6 */ + { {0xFFFF} }, /* TX_7 */ + }, +}; + +static struct tdm_dev_config quat_tdm_dev_config[MAX_PATH][TDM_PORT_MAX] = { + { /* QUAT TDM */ + { {0, 4, 0xFFFF} }, /* RX_0 */ + { {8, 12, 0xFFFF} }, /* RX_1 */ + { {16, 20, 0xFFFF} }, /* RX_2 */ + { {24, 28, 0xFFFF} }, /* RX_3 */ + { {0xFFFF} }, /* RX_4 */ + { {0xFFFF} }, /* RX_5 */ + { {0xFFFF} }, /* RX_6 */ + { {0xFFFF} }, /* RX_7 */ + }, + { + { {0, 4, 0xFFFF} }, /* TX_0 */ + { {8, 12, 0xFFFF} }, /* TX_1 */ + { {16, 20, 0xFFFF} }, /* TX_2 */ + { {24, 28, 0xFFFF} }, /* TX_3 */ + { {0xFFFF} }, /* TX_4 */ + { {0xFFFF} }, /* TX_5 */ + { {0xFFFF} }, /* TX_6 */ + { {0xFFFF} }, /* TX_7 */ + }, +}; + +static struct tdm_dev_config quin_tdm_dev_config[MAX_PATH][TDM_PORT_MAX] = { + { /* QUIN TDM */ + { {0, 4, 0xFFFF} }, /* RX_0 */ + { {8, 12, 0xFFFF} }, /* RX_1 */ + { {16, 20, 0xFFFF} }, /* RX_2 */ + { {24, 28, 0xFFFF} }, /* RX_3 */ + { {0xFFFF} }, /* RX_4 */ + { {0xFFFF} }, /* RX_5 */ + { {0xFFFF} }, /* RX_6 */ + { {0xFFFF} }, /* RX_7 */ + }, + { + { {0, 4, 0xFFFF} }, /* TX_0 */ + { {8, 12, 0xFFFF} }, /* TX_1 */ + { {16, 20, 0xFFFF} }, /* TX_2 */ + { {24, 28, 0xFFFF} }, /* TX_3 */ + { {0xFFFF} }, /* TX_4 */ + { {0xFFFF} }, /* TX_5 */ + { {0xFFFF} }, /* TX_6 */ + { {0xFFFF} }, /* TX_7 */ + }, +}; + +static struct tdm_dev_config sen_tdm_dev_config[MAX_PATH][TDM_PORT_MAX] = { + { /* SEN TDM */ + { {0, 4, 0xFFFF} }, /* RX_0 */ + { {8, 12, 0xFFFF} }, /* RX_1 */ + { {16, 20, 0xFFFF} }, /* RX_2 */ + { {24, 28, 0xFFFF} }, /* RX_3 */ + { {0xFFFF} }, /* RX_4 */ + { {0xFFFF} }, /* RX_5 */ + { {0xFFFF} }, /* RX_6 */ + { {0xFFFF} }, /* RX_7 */ + }, + { + { {0, 4, 0xFFFF} }, /* TX_0 */ + { {8, 12, 0xFFFF} }, /* TX_1 */ + { {16, 20, 0xFFFF} }, /* TX_2 */ + { {24, 28, 0xFFFF} }, /* TX_3 */ + { {0xFFFF} }, /* TX_4 */ + { {0xFFFF} }, /* TX_5 */ + { {0xFFFF} }, /* TX_6 */ + { {0xFFFF} }, /* TX_7 */ + }, +}; + +static void *tdm_cfg[TDM_INTERFACE_MAX] = { + pri_tdm_dev_config, + sec_tdm_dev_config, + tert_tdm_dev_config, + quat_tdm_dev_config, + quin_tdm_dev_config, + sen_tdm_dev_config, +}; + /* Default configuration of Codec DMA Interface RX */ static struct dev_config cdc_dma_rx_cfg[] = { [WSA_CDC_DMA_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, @@ -1789,6 +1949,45 @@ static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, return ret; } +static int tdm_slot_map_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int slot_index = 0; + int interface = ucontrol->value.integer.value[0]; + int channel = ucontrol->value.integer.value[1]; + unsigned int offset_val = 0; + unsigned int *slot_offset = NULL; + struct tdm_dev_config *config = NULL; + + if (interface < 0 || interface >= (TDM_INTERFACE_MAX * MAX_PATH)) { + pr_err("%s: incorrect interface = %d\n", __func__, interface); + return -EINVAL; + } + if (channel < 0 || channel >= TDM_PORT_MAX) { + pr_err("%s: incorrect channel = %d\n", __func__, channel); + return -EINVAL; + } + + pr_debug("%s: interface = %d, channel = %d\n", __func__, + interface, channel); + + config = ((struct tdm_dev_config *) tdm_cfg[interface / MAX_PATH]) + + ((interface % MAX_PATH) * TDM_PORT_MAX) + channel; + slot_offset = config->tdm_slot_offset; + + for (slot_index = 0; slot_index < TDM_MAX_SLOTS; slot_index++) { + offset_val = ucontrol->value.integer.value[MAX_PATH + + slot_index]; + /* Offset value can only be 0, 4, 8, ..28 */ + if (offset_val % 4 == 0 && offset_val <= 28) + slot_offset[slot_index] = offset_val; + pr_debug("%s: slot offset[%d] = %d\n", __func__, + slot_index, slot_offset[slot_index]); + } + + return 0; +} + static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) { int idx = 0; @@ -3744,6 +3943,8 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { afe_loopback_tx_ch_get, afe_loopback_tx_ch_put), SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), + SOC_SINGLE_MULTI_EXT("TDM Slot Map", SND_SOC_NOPM, 0, 255, 0, + TDM_MAX_SLOTS + MAX_PATH, NULL, tdm_slot_map_put), }; static const struct snd_kcontrol_new msm_snd_controls[] = { @@ -3813,8 +4014,9 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); int idx = 0, rc = 0; - pr_debug("%s: format = %d, rate = %d\n", - __func__, params_format(params), params_rate(params)); + pr_debug("%s: dai_id= %d, format = %d, rate = %d\n", + __func__, dai_link->id, params_format(params), + params_rate(params)); switch (dai_link->id) { case MSM_BACKEND_DAI_USB_RX: @@ -4280,65 +4482,51 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret = 0; - int slot_width = 32; - int channels, slots; + int slot_width = TDM_SLOT_WIDTH_BITS; + int channels, slots = TDM_MAX_SLOTS; unsigned int slot_mask, rate, clk_freq; - unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; + unsigned int *slot_offset; + struct tdm_dev_config *config; + unsigned int path_dir = 0, interface = 0, channel_interface = 0; pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); - /* currently only supporting TDM_RX_0 and TDM_TX_0 */ - switch (cpu_dai->id) { - case AFE_PORT_ID_PRIMARY_TDM_RX: - slots = tdm_rx_cfg[TDM_PRI][TDM_0].channels; - break; - case AFE_PORT_ID_SECONDARY_TDM_RX: - slots = tdm_rx_cfg[TDM_SEC][TDM_0].channels; - break; - case AFE_PORT_ID_TERTIARY_TDM_RX: - slots = tdm_rx_cfg[TDM_TERT][TDM_0].channels; - break; - case AFE_PORT_ID_QUATERNARY_TDM_RX: - slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; - break; - case AFE_PORT_ID_QUINARY_TDM_RX: - slots = tdm_rx_cfg[TDM_QUIN][TDM_0].channels; - break; - case AFE_PORT_ID_SENARY_TDM_RX: - slots = tdm_rx_cfg[TDM_SEN][TDM_0].channels; - break; - case AFE_PORT_ID_PRIMARY_TDM_TX: - slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels; - break; - case AFE_PORT_ID_SECONDARY_TDM_TX: - slots = tdm_tx_cfg[TDM_SEC][TDM_0].channels; - break; - case AFE_PORT_ID_TERTIARY_TDM_TX: - slots = tdm_tx_cfg[TDM_TERT][TDM_0].channels; - break; - case AFE_PORT_ID_QUATERNARY_TDM_TX: - slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels; - break; - case AFE_PORT_ID_QUINARY_TDM_TX: - slots = tdm_tx_cfg[TDM_QUIN][TDM_0].channels; - break; - case AFE_PORT_ID_SENARY_TDM_TX: - slots = tdm_tx_cfg[TDM_SEN][TDM_0].channels; - break; - - default: + if (cpu_dai->id < AFE_PORT_ID_TDM_PORT_RANGE_START) { pr_err("%s: dai id 0x%x not supported\n", __func__, cpu_dai->id); return -EINVAL; } + /* RX or TX */ + path_dir = cpu_dai->id % MAX_PATH; + + /* PRI, SEC, TERT, QUAT, QUIN, ... */ + interface = (cpu_dai->id - AFE_PORT_ID_TDM_PORT_RANGE_START) + / (MAX_PATH * TDM_PORT_MAX); + + /* 0, 1, 2, .. 7 */ + channel_interface = + ((cpu_dai->id - AFE_PORT_ID_TDM_PORT_RANGE_START) / MAX_PATH) + % TDM_PORT_MAX; + + pr_debug("%s: path dir: %u, interface %u, channel interface %u\n", + __func__, path_dir, interface, channel_interface); + + config = ((struct tdm_dev_config *) tdm_cfg[interface]) + + (path_dir * TDM_PORT_MAX) + channel_interface; + slot_offset = config->tdm_slot_offset; + + if (path_dir) + channels = tdm_tx_cfg[interface][channel_interface].channels; + else + channels = tdm_rx_cfg[interface][channel_interface].channels; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { /*2 slot config - bits 0 and 1 set for the first two slots */ slot_mask = 0x0000FFFF >> (16 - slots); - channels = slots; - pr_debug("%s: tdm rx slot_width %d slots %d\n", - __func__, slot_width, slots); + pr_debug("%s: tdm rx slot_width %d slots %d slot_mask %x\n", + __func__, slot_width, slots, slot_mask); ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, slots, slot_width); @@ -4348,6 +4536,8 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream, goto end; } + pr_debug("%s: tdm rx channels: %d\n", __func__, channels); + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, channels, slot_offset); if (ret < 0) { @@ -4358,10 +4548,9 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream, } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { /*2 slot config - bits 0 and 1 set for the first two slots */ slot_mask = 0x0000FFFF >> (16 - slots); - channels = slots; - pr_debug("%s: tdm tx slot_width %d slots %d\n", - __func__, slot_width, slots); + pr_debug("%s: tdm tx slot_width %d slots %d slot_mask %x\n", + __func__, slot_width, slots, slot_mask); ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, slots, slot_width); @@ -4371,6 +4560,8 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream, goto end; } + pr_debug("%s: tdm tx channels: %d\n", __func__, channels); + ret = snd_soc_dai_set_channel_map(cpu_dai, channels, slot_offset, 0, NULL); if (ret < 0) { diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index c6f61e4937ea..3fcd9795acaf 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -8540,6 +8540,37 @@ static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai, return rc; } +static unsigned int tdm_param_set_slot_mask(u16 *slot_offset, int slot_width, + int slots_per_frame) +{ + unsigned int i = 0; + unsigned int slot_index = 0; + unsigned long slot_mask = 0; + unsigned int slot_width_bytes = slot_width / 8; + + if (slot_width_bytes == 0) { + pr_err("%s: slot width is zero\n", __func__); + return slot_mask; + } + + for (i = 0; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++) { + if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) { + slot_index = slot_offset[i] / slot_width_bytes; + if (slot_index < slots_per_frame) + set_bit(slot_index, &slot_mask); + else { + pr_err("%s: invalid slot map setting\n", + __func__); + return 0; + } + } else { + break; + } + } + + return slot_mask; +} + static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -8644,7 +8675,9 @@ static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream, */ tdm->nslots_per_frame = tdm_group->nslots_per_frame; tdm->slot_width = tdm_group->slot_width; - tdm->slot_mask = tdm_group->slot_mask; + tdm->slot_mask = tdm_param_set_slot_mask(slot_mapping->offset, + tdm_group->slot_width, + tdm_group->nslots_per_frame); pr_debug("%s: TDM:\n" "num_channels=%d sample_rate=%d bit_width=%d\n" -- GitLab From 29e071318d3a57b8decc09b6b3920297bb90d53b Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Fri, 26 Jul 2019 15:15:21 +0200 Subject: [PATCH 1174/1645] asoc: Add support for META MI2S ports QCS405 can group data lines of several MI2S interfaces. Add backend dai links for new META MI2S ports. Change-Id: I9fc5ff06b61ffc2e085c5f05a75111b63ceeeb68 Signed-off-by: Ralf Herz --- asoc/msm-dai-q6-v2.c | 726 ++++++++++++++++++++++++++++++++++++++ asoc/msm-dai-q6-v2.h | 12 + asoc/msm-pcm-routing-v2.c | 238 ++++++++++++- asoc/msm-pcm-routing-v2.h | 5 + asoc/msm-qti-pp-config.c | 10 +- 5 files changed, 986 insertions(+), 5 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index c6f61e4937ea..2578f5d84123 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -261,6 +261,17 @@ struct msm_dai_q6_mi2s_dai_data { struct msm_dai_q6_mi2s_dai_config rx_dai; }; +struct msm_dai_q6_meta_mi2s_dai_data { + DECLARE_BITMAP(status_mask, STATUS_MAX); + u16 num_member_ports; + u16 member_port_id[MAX_NUM_I2S_META_PORT_MEMBER_PORTS]; + u16 channel_mode[MAX_NUM_I2S_META_PORT_MEMBER_PORTS]; + u32 rate; + u32 channels; + u32 bitwidth; + union afe_port_config port_config; +}; + struct msm_dai_q6_cdc_dma_dai_data { DECLARE_BITMAP(status_mask, STATUS_MAX); DECLARE_BITMAP(hwfree_status, STATUS_MAX); @@ -6096,6 +6107,42 @@ static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr, return -EINVAL; } +static u16 msm_dai_q6_mi2s_get_num_channels(u16 config) +{ + switch (config) { + case AFE_PORT_I2S_SD0: + case AFE_PORT_I2S_SD1: + case AFE_PORT_I2S_SD2: + case AFE_PORT_I2S_SD3: + case AFE_PORT_I2S_SD4: + case AFE_PORT_I2S_SD5: + case AFE_PORT_I2S_SD6: + case AFE_PORT_I2S_SD7: + return 2; + case AFE_PORT_I2S_QUAD01: + case AFE_PORT_I2S_QUAD23: + case AFE_PORT_I2S_QUAD45: + case AFE_PORT_I2S_QUAD67: + return 4; + case AFE_PORT_I2S_6CHS: + return 6; + case AFE_PORT_I2S_8CHS: + case AFE_PORT_I2S_8CHS_2: + return 8; + case AFE_PORT_I2S_10CHS: + return 10; + case AFE_PORT_I2S_12CHS: + return 12; + case AFE_PORT_I2S_14CHS: + return 14; + case AFE_PORT_I2S_16CHS: + return 16; + default: + pr_err("%s: invalid config\n", __func__); + return 0; + } +} + static int msm_dai_q6_mi2s_platform_data_validation( struct platform_device *pdev, struct snd_soc_dai_driver *dai_driver) { @@ -6261,6 +6308,657 @@ static int msm_dai_q6_mi2s_dev_remove(struct platform_device *pdev) return 0; } +static int msm_dai_q6_dai_meta_mi2s_probe(struct snd_soc_dai *dai) +{ + struct msm_meta_mi2s_pdata *meta_mi2s_pdata = + (struct msm_meta_mi2s_pdata *) dai->dev->platform_data; + int rc = 0; + + dai->id = meta_mi2s_pdata->intf_id; + rc = msm_dai_q6_dai_add_route(dai); + return rc; +} + +static int msm_dai_q6_dai_meta_mi2s_remove(struct snd_soc_dai *dai) +{ + return 0; +} + +static int msm_dai_q6_meta_mi2s_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + return 0; +} + +static int msm_meta_mi2s_get_port_id(u32 mi2s_id, int stream, u16 *port_id) +{ + int ret = 0; + + switch (stream) { + case SNDRV_PCM_STREAM_PLAYBACK: + switch (mi2s_id) { + case MSM_PRIM_META_MI2S: + *port_id = AFE_PORT_ID_PRIMARY_META_MI2S_RX; + break; + case MSM_SEC_META_MI2S: + *port_id = AFE_PORT_ID_SECONDARY_META_MI2S_RX; + break; + default: + pr_err("%s: playback err id 0x%x\n", + __func__, mi2s_id); + ret = -1; + break; + } + break; + + case SNDRV_PCM_STREAM_CAPTURE: + switch (mi2s_id) { + default: + pr_err("%s: capture err id 0x%x\n", __func__, mi2s_id); + ret = -1; + break; + } + break; + + default: + pr_err("%s: default err %d\n", __func__, stream); + ret = -1; + break; + } + pr_debug("%s: port_id = 0x%x\n", __func__, *port_id); + return ret; +} + +static int msm_dai_q6_meta_mi2s_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_meta_mi2s_dai_data *dai_data = + dev_get_drvdata(dai->dev); + u16 port_id = 0; + int rc = 0; + + if (msm_meta_mi2s_get_port_id(dai->id, substream->stream, + &port_id) != 0) { + dev_err(dai->dev, "%s: Invalid Port ID 0x%x\n", + __func__, port_id); + return -EINVAL; + } + + dev_dbg(dai->dev, "%s: dai id %d, afe port id = 0x%x\n" + "dai_data->channels = %u sample_rate = %u\n", __func__, + dai->id, port_id, dai_data->channels, dai_data->rate); + + if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + /* PORT START should be set if prepare called + * in active state. + */ + rc = afe_port_start(port_id, &dai_data->port_config, + dai_data->rate); + if (rc < 0) + dev_err(dai->dev, "fail to open AFE port 0x%x\n", + dai->id); + else + set_bit(STATUS_PORT_STARTED, + dai_data->status_mask); + } + + return rc; +} + +static int msm_dai_q6_meta_mi2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_meta_mi2s_dai_data *dai_data = + dev_get_drvdata(dai->dev); + struct afe_param_id_meta_i2s_cfg *port_cfg = + &dai_data->port_config.meta_i2s; + int idx = 0; + u16 port_channels = 0; + u16 channels_left = 0; + + dai_data->channels = params_channels(params); + channels_left = dai_data->channels; + + /* map requested channels to channels that member ports provide */ + for (idx = 0; idx < dai_data->num_member_ports; idx++) { + port_channels = msm_dai_q6_mi2s_get_num_channels( + dai_data->channel_mode[idx]); + + if (channels_left >= port_channels) { + port_cfg->member_port_id[idx] = + dai_data->member_port_id[idx]; + port_cfg->member_port_channel_mode[idx] = + dai_data->channel_mode[idx]; + channels_left -= port_channels; + } else { + switch (channels_left) { + case 15: + case 16: + switch (dai_data->channel_mode[idx]) { + case AFE_PORT_I2S_16CHS: + port_cfg->member_port_channel_mode[idx] + = AFE_PORT_I2S_16CHS; + break; + default: + goto error_invalid_data; + }; + break; + case 13: + case 14: + switch (dai_data->channel_mode[idx]) { + case AFE_PORT_I2S_14CHS: + case AFE_PORT_I2S_16CHS: + port_cfg->member_port_channel_mode[idx] + = AFE_PORT_I2S_14CHS; + break; + default: + goto error_invalid_data; + }; + break; + case 11: + case 12: + switch (dai_data->channel_mode[idx]) { + case AFE_PORT_I2S_12CHS: + case AFE_PORT_I2S_14CHS: + case AFE_PORT_I2S_16CHS: + port_cfg->member_port_channel_mode[idx] + = AFE_PORT_I2S_12CHS; + break; + default: + goto error_invalid_data; + }; + break; + case 9: + case 10: + switch (dai_data->channel_mode[idx]) { + case AFE_PORT_I2S_10CHS: + case AFE_PORT_I2S_12CHS: + case AFE_PORT_I2S_14CHS: + case AFE_PORT_I2S_16CHS: + port_cfg->member_port_channel_mode[idx] + = AFE_PORT_I2S_10CHS; + break; + default: + goto error_invalid_data; + }; + break; + case 8: + case 7: + switch (dai_data->channel_mode[idx]) { + case AFE_PORT_I2S_8CHS: + case AFE_PORT_I2S_10CHS: + case AFE_PORT_I2S_12CHS: + case AFE_PORT_I2S_14CHS: + case AFE_PORT_I2S_16CHS: + port_cfg->member_port_channel_mode[idx] + = AFE_PORT_I2S_8CHS; + break; + case AFE_PORT_I2S_8CHS_2: + port_cfg->member_port_channel_mode[idx] + = AFE_PORT_I2S_8CHS_2; + break; + default: + goto error_invalid_data; + }; + break; + case 6: + case 5: + switch (dai_data->channel_mode[idx]) { + case AFE_PORT_I2S_6CHS: + case AFE_PORT_I2S_8CHS: + case AFE_PORT_I2S_10CHS: + case AFE_PORT_I2S_12CHS: + case AFE_PORT_I2S_14CHS: + case AFE_PORT_I2S_16CHS: + port_cfg->member_port_channel_mode[idx] + = AFE_PORT_I2S_6CHS; + break; + default: + goto error_invalid_data; + }; + break; + case 4: + case 3: + switch (dai_data->channel_mode[idx]) { + case AFE_PORT_I2S_SD0: + case AFE_PORT_I2S_SD1: + case AFE_PORT_I2S_SD2: + case AFE_PORT_I2S_SD3: + case AFE_PORT_I2S_SD4: + case AFE_PORT_I2S_SD5: + case AFE_PORT_I2S_SD6: + case AFE_PORT_I2S_SD7: + goto error_invalid_data; + case AFE_PORT_I2S_QUAD01: + case AFE_PORT_I2S_QUAD23: + case AFE_PORT_I2S_QUAD45: + case AFE_PORT_I2S_QUAD67: + port_cfg->member_port_channel_mode[idx] + = dai_data->channel_mode[idx]; + break; + case AFE_PORT_I2S_8CHS_2: + port_cfg->member_port_channel_mode[idx] + = AFE_PORT_I2S_QUAD45; + break; + default: + port_cfg->member_port_channel_mode[idx] + = AFE_PORT_I2S_QUAD01; + }; + break; + case 2: + case 1: + if (dai_data->channel_mode[idx] < + AFE_PORT_I2S_SD0) + goto error_invalid_data; + switch (dai_data->channel_mode[idx]) { + case AFE_PORT_I2S_SD0: + case AFE_PORT_I2S_SD1: + case AFE_PORT_I2S_SD2: + case AFE_PORT_I2S_SD3: + case AFE_PORT_I2S_SD4: + case AFE_PORT_I2S_SD5: + case AFE_PORT_I2S_SD6: + case AFE_PORT_I2S_SD7: + port_cfg->member_port_channel_mode[idx] + = dai_data->channel_mode[idx]; + break; + case AFE_PORT_I2S_QUAD01: + case AFE_PORT_I2S_6CHS: + case AFE_PORT_I2S_8CHS: + case AFE_PORT_I2S_10CHS: + case AFE_PORT_I2S_12CHS: + case AFE_PORT_I2S_14CHS: + case AFE_PORT_I2S_16CHS: + port_cfg->member_port_channel_mode[idx] + = AFE_PORT_I2S_SD0; + break; + case AFE_PORT_I2S_QUAD23: + port_cfg->member_port_channel_mode[idx] + = AFE_PORT_I2S_SD2; + break; + case AFE_PORT_I2S_QUAD45: + case AFE_PORT_I2S_8CHS_2: + port_cfg->member_port_channel_mode[idx] + = AFE_PORT_I2S_SD4; + break; + case AFE_PORT_I2S_QUAD67: + port_cfg->member_port_channel_mode[idx] + = AFE_PORT_I2S_SD6; + break; + } + break; + case 0: + port_cfg->member_port_channel_mode[idx] = 0; + } + if (port_cfg->member_port_channel_mode[idx] == 0) { + port_cfg->member_port_id[idx] = + AFE_PORT_ID_INVALID; + } else { + port_cfg->member_port_id[idx] = + dai_data->member_port_id[idx]; + channels_left -= + msm_dai_q6_mi2s_get_num_channels( + port_cfg->member_port_channel_mode[idx]); + } + } + } + + if (channels_left > 0) { + pr_err("%s: too many channels %d\n", + __func__, dai_data->channels); + return -EINVAL; + } + + dai_data->rate = params_rate(params); + port_cfg->sample_rate = dai_data->rate; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + case SNDRV_PCM_FORMAT_SPECIAL: + port_cfg->bit_width = 16; + dai_data->bitwidth = 16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + port_cfg->bit_width = 24; + dai_data->bitwidth = 24; + break; + default: + pr_err("%s: format %d\n", + __func__, params_format(params)); + return -EINVAL; + } + + port_cfg->minor_version = AFE_API_VERSION_META_I2S_CONFIG; + port_cfg->data_format = AFE_LINEAR_PCM_DATA; + + dev_dbg(dai->dev, "%s: dai id %d dai_data->channels = %d\n" + "bit_width = %hu ws_src = 0x%x sample_rate = %u\n" + "member_ports 0x%x 0x%x 0x%x 0x%x\n" + "sd_lines 0x%x 0x%x 0x%x 0x%x\n", + __func__, dai->id, dai_data->channels, + port_cfg->bit_width, port_cfg->ws_src, port_cfg->sample_rate, + port_cfg->member_port_id[0], + port_cfg->member_port_id[1], + port_cfg->member_port_id[2], + port_cfg->member_port_id[3], + port_cfg->member_port_channel_mode[0], + port_cfg->member_port_channel_mode[1], + port_cfg->member_port_channel_mode[2], + port_cfg->member_port_channel_mode[3]); + return 0; + +error_invalid_data: + pr_err("%s: error when assigning member port %d channels (channels_left %d)\n", + __func__, idx, channels_left); + return -EINVAL; +} + +static int msm_dai_q6_meta_mi2s_set_fmt(struct snd_soc_dai *dai, + unsigned int fmt) +{ + struct msm_dai_q6_meta_mi2s_dai_data *dai_data = + dev_get_drvdata(dai->dev); + + if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + dev_err(dai->dev, "%s: err chg meta i2s mode while dai running", + __func__); + return -EPERM; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + dai_data->port_config.meta_i2s.ws_src = 1; + break; + case SND_SOC_DAIFMT_CBM_CFM: + dai_data->port_config.meta_i2s.ws_src = 0; + break; + default: + pr_err("%s: fmt %d\n", + __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK); + return -EINVAL; + } + + return 0; +} + +static void msm_dai_q6_meta_mi2s_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_meta_mi2s_dai_data *dai_data = + dev_get_drvdata(dai->dev); + u16 port_id = 0; + int rc = 0; + + if (msm_meta_mi2s_get_port_id(dai->id, substream->stream, + &port_id) != 0) { + dev_err(dai->dev, "%s: Invalid Port ID 0x%x\n", + __func__, port_id); + } + + dev_dbg(dai->dev, "%s: closing afe port id = 0x%x\n", + __func__, port_id); + + if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + rc = afe_close(port_id); + if (rc < 0) + dev_err(dai->dev, "fail to close AFE port\n"); + clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); + } +} + +static struct snd_soc_dai_ops msm_dai_q6_meta_mi2s_ops = { + .startup = msm_dai_q6_meta_mi2s_startup, + .prepare = msm_dai_q6_meta_mi2s_prepare, + .hw_params = msm_dai_q6_meta_mi2s_hw_params, + .set_fmt = msm_dai_q6_meta_mi2s_set_fmt, + .shutdown = msm_dai_q6_meta_mi2s_shutdown, +}; + +/* Channel min and max are initialized base on platform data */ +static struct snd_soc_dai_driver msm_dai_q6_meta_mi2s_dai[] = { + { + .playback = { + .stream_name = "Primary META MI2S Playback", + .aif_name = "PRI_META_MI2S_RX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_dai_q6_meta_mi2s_ops, + .name = "Primary META MI2S", + .id = AFE_PORT_ID_PRIMARY_META_MI2S_RX, + .probe = msm_dai_q6_dai_meta_mi2s_probe, + .remove = msm_dai_q6_dai_meta_mi2s_remove, + }, + { + .playback = { + .stream_name = "Secondary META MI2S Playback", + .aif_name = "SEC_META_MI2S_RX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_meta_mi2s_ops, + .name = "Secondary META MI2S", + .id = AFE_PORT_ID_SECONDARY_META_MI2S_RX, + .probe = msm_dai_q6_dai_meta_mi2s_probe, + .remove = msm_dai_q6_dai_meta_mi2s_remove, + }, +}; + +static int msm_dai_q6_meta_mi2s_platform_data_validation( + struct platform_device *pdev, struct snd_soc_dai_driver *dai_driver) +{ + struct msm_dai_q6_meta_mi2s_dai_data *dai_data = + dev_get_drvdata(&pdev->dev); + struct msm_meta_mi2s_pdata *meta_mi2s_pdata = + (struct msm_meta_mi2s_pdata *) pdev->dev.platform_data; + int rc = 0; + int idx = 0; + u16 channel_mode = 0; + unsigned int ch_cnt = 0; + unsigned int ch_cnt_sum = 0; + struct afe_param_id_meta_i2s_cfg *port_cfg = + &dai_data->port_config.meta_i2s; + + if (meta_mi2s_pdata == NULL) { + pr_err("%s: meta_mi2s_pdata NULL", __func__); + return -EINVAL; + } + + dai_data->num_member_ports = meta_mi2s_pdata->num_member_ports; + for (idx = 0; idx < meta_mi2s_pdata->num_member_ports; idx++) { + rc = msm_dai_q6_mi2s_get_lineconfig( + meta_mi2s_pdata->sd_lines[idx], + &channel_mode, + &ch_cnt); + if (rc < 0) { + dev_err(&pdev->dev, "invalid META MI2S RX sd line config\n"); + goto rtn; + } + if (ch_cnt) { + msm_mi2s_get_port_id(meta_mi2s_pdata->member_port[idx], + SNDRV_PCM_STREAM_PLAYBACK, + &dai_data->member_port_id[idx]); + dai_data->channel_mode[idx] = channel_mode; + port_cfg->member_port_id[idx] = + dai_data->member_port_id[idx]; + port_cfg->member_port_channel_mode[idx] = channel_mode; + } + ch_cnt_sum += ch_cnt; + } + + if (ch_cnt_sum) { + dai_driver->playback.channels_min = 1; + dai_driver->playback.channels_max = ch_cnt_sum << 1; + } else { + dai_driver->playback.channels_min = 0; + dai_driver->playback.channels_max = 0; + } + + dev_dbg(&pdev->dev, "%s: sdline 0x%x 0x%x 0x%x 0x%x\n", __func__, + dai_data->channel_mode[0], dai_data->channel_mode[1], + dai_data->channel_mode[2], dai_data->channel_mode[3]); + dev_dbg(&pdev->dev, "%s: playback ch_max %d\n", + __func__, dai_driver->playback.channels_max); +rtn: + return rc; +} + +static const struct snd_soc_component_driver msm_q6_meta_mi2s_dai_component = { + .name = "msm-dai-q6-meta-mi2s", +}; + +static int msm_dai_q6_meta_mi2s_dev_probe(struct platform_device *pdev) +{ + struct msm_dai_q6_meta_mi2s_dai_data *dai_data; + const char *q6_meta_mi2s_dev_id = "qcom,msm-dai-q6-meta-mi2s-dev-id"; + u32 dev_id = 0; + u32 meta_mi2s_intf = 0; + struct msm_meta_mi2s_pdata *meta_mi2s_pdata; + int rc; + + rc = of_property_read_u32(pdev->dev.of_node, q6_meta_mi2s_dev_id, + &dev_id); + if (rc) { + dev_err(&pdev->dev, + "%s: missing %s in dt node\n", __func__, + q6_meta_mi2s_dev_id); + goto rtn; + } + + dev_dbg(&pdev->dev, "dev name %s dev id 0x%x\n", dev_name(&pdev->dev), + dev_id); + + switch (dev_id) { + case AFE_PORT_ID_PRIMARY_META_MI2S_RX: + meta_mi2s_intf = 0; + break; + case AFE_PORT_ID_SECONDARY_META_MI2S_RX: + meta_mi2s_intf = 1; + break; + default: + dev_err(&pdev->dev, + "%s: Invalid META MI2S ID 0x%x from Device Tree\n", + __func__, dev_id); + rc = -ENXIO; + goto rtn; + } + + pdev->id = dev_id; + + meta_mi2s_pdata = kzalloc(sizeof(struct msm_meta_mi2s_pdata), + GFP_KERNEL); + if (!meta_mi2s_pdata) { + rc = -ENOMEM; + goto rtn; + } + + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-mi2s-num-members", + &meta_mi2s_pdata->num_member_ports); + if (rc) { + dev_err(&pdev->dev, "%s: invalid num from DT file %s\n", + __func__, "qcom,msm-mi2s-num-members"); + goto free_pdata; + } + + if (meta_mi2s_pdata->num_member_ports > + MAX_NUM_I2S_META_PORT_MEMBER_PORTS) { + dev_err(&pdev->dev, "%s: num-members %d too large from DT file\n", + __func__, meta_mi2s_pdata->num_member_ports); + goto free_pdata; + } + + rc = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-member-id", + meta_mi2s_pdata->member_port, + meta_mi2s_pdata->num_member_ports); + if (rc) { + dev_err(&pdev->dev, "%s: member-id from DT file %s\n", + __func__, "qcom,msm-mi2s-member-id"); + goto free_pdata; + } + + rc = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-rx-lines", + meta_mi2s_pdata->sd_lines, + meta_mi2s_pdata->num_member_ports); + if (rc) { + dev_err(&pdev->dev, "%s: Rx line from DT file %s\n", + __func__, "qcom,msm-mi2s-rx-lines"); + goto free_pdata; + } + + dev_dbg(&pdev->dev, "dev name %s num-members=%d\n", + dev_name(&pdev->dev), meta_mi2s_pdata->num_member_ports); + dev_dbg(&pdev->dev, "member array (%d, %d, %d, %d)\n", + meta_mi2s_pdata->member_port[0], + meta_mi2s_pdata->member_port[1], + meta_mi2s_pdata->member_port[2], + meta_mi2s_pdata->member_port[3]); + dev_dbg(&pdev->dev, "sd-lines array (0x%x, 0x%x, 0x%x, 0x%x)\n", + meta_mi2s_pdata->sd_lines[0], + meta_mi2s_pdata->sd_lines[1], + meta_mi2s_pdata->sd_lines[2], + meta_mi2s_pdata->sd_lines[3]); + + meta_mi2s_pdata->intf_id = meta_mi2s_intf; + + dai_data = kzalloc(sizeof(struct msm_dai_q6_meta_mi2s_dai_data), + GFP_KERNEL); + if (!dai_data) { + rc = -ENOMEM; + goto free_pdata; + } else + dev_set_drvdata(&pdev->dev, dai_data); + + pdev->dev.platform_data = meta_mi2s_pdata; + + rc = msm_dai_q6_meta_mi2s_platform_data_validation(pdev, + &msm_dai_q6_meta_mi2s_dai[meta_mi2s_intf]); + if (rc < 0) + goto free_dai_data; + + rc = snd_soc_register_component(&pdev->dev, + &msm_q6_meta_mi2s_dai_component, + &msm_dai_q6_meta_mi2s_dai[meta_mi2s_intf], 1); + if (rc < 0) + goto err_register; + return 0; + +err_register: + dev_err(&pdev->dev, "fail to %s\n", __func__); +free_dai_data: + kfree(dai_data); +free_pdata: + kfree(meta_mi2s_pdata); +rtn: + return rc; +} + +static int msm_dai_q6_meta_mi2s_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_component(&pdev->dev); + return 0; +} + static const struct snd_soc_component_driver msm_dai_q6_component = { .name = "msm-dai-q6-dev", }; @@ -6627,6 +7325,24 @@ static struct platform_driver msm_dai_q6_mi2s_driver = { }, }; +static const struct of_device_id msm_dai_q6_meta_mi2s_dev_dt_match[] = { + { .compatible = "qcom,msm-dai-q6-meta-mi2s", }, + { } +}; + +MODULE_DEVICE_TABLE(of, msm_dai_q6_meta_mi2s_dev_dt_match); + +static struct platform_driver msm_dai_q6_meta_mi2s_driver = { + .probe = msm_dai_q6_meta_mi2s_dev_probe, + .remove = msm_dai_q6_meta_mi2s_dev_remove, + .driver = { + .name = "msm-dai-q6-meta-mi2s", + .owner = THIS_MODULE, + .of_match_table = msm_dai_q6_meta_mi2s_dev_dt_match, + .suppress_bind_attrs = true, + }, +}; + static int msm_dai_q6_spdif_dev_probe(struct platform_device *pdev) { int rc, id; @@ -12175,6 +12891,13 @@ int __init msm_dai_q6_init(void) goto dai_q6_mi2s_drv_fail; } + rc = platform_driver_register(&msm_dai_q6_meta_mi2s_driver); + if (rc) { + pr_err("%s: fail to register dai META MI2S dev drv\n", + __func__); + goto dai_q6_meta_mi2s_drv_fail; + } + rc = platform_driver_register(&msm_dai_mi2s_q6); if (rc) { pr_err("%s: fail to register dai MI2S\n", __func__); @@ -12224,6 +12947,8 @@ int __init msm_dai_q6_init(void) dai_spdif_q6_fail: platform_driver_unregister(&msm_dai_mi2s_q6); dai_mi2s_q6_fail: + platform_driver_unregister(&msm_dai_q6_meta_mi2s_driver); +dai_q6_meta_mi2s_drv_fail: platform_driver_unregister(&msm_dai_q6_mi2s_driver); dai_q6_mi2s_drv_fail: platform_driver_unregister(&msm_dai_q6_dev); @@ -12243,6 +12968,7 @@ void msm_dai_q6_exit(void) platform_driver_unregister(&msm_dai_q6_tdm_driver); platform_driver_unregister(&msm_dai_q6_spdif_driver); platform_driver_unregister(&msm_dai_mi2s_q6); + platform_driver_unregister(&msm_dai_q6_meta_mi2s_driver); platform_driver_unregister(&msm_dai_q6_mi2s_driver); platform_driver_unregister(&msm_dai_q6_dev); platform_driver_unregister(&msm_dai_q6); diff --git a/asoc/msm-dai-q6-v2.h b/asoc/msm-dai-q6-v2.h index b65e4e11d8be..a4aafc55aaf1 100644 --- a/asoc/msm-dai-q6-v2.h +++ b/asoc/msm-dai-q6-v2.h @@ -38,6 +38,11 @@ #define MSM_DISPLAY_PORT 0 #define MSM_DISPLAY_PORT1 1 +#define MSM_PRIM_META_MI2S 0 +#define MSM_SEC_META_MI2S 1 +#define MSM_META_MI2S_MIN MSM_PRIM_META_MI2S +#define MSM_META_MI2S_MAX MSM_SEC_META_MI2S + struct msm_dai_auxpcm_config { u16 mode; u16 sync; @@ -60,6 +65,13 @@ struct msm_mi2s_pdata { u16 intf_id; }; +struct msm_meta_mi2s_pdata { + u32 num_member_ports; + u32 member_port[MAX_NUM_I2S_META_PORT_MEMBER_PORTS]; + u32 sd_lines[MAX_NUM_I2S_META_PORT_MEMBER_PORTS]; + u16 intf_id; +}; + struct msm_i2s_data { u32 capability; /* RX or TX */ u16 sd_lines; diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index ffd09e889be5..09121e9d8434 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -689,6 +689,10 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { { SLIMBUS_9_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_9_RX}, { SLIMBUS_9_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_9_TX}, { AFE_LOOPBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_AFE_LOOPBACK_TX}, + { AFE_PORT_ID_PRIMARY_META_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_PRI_META_MI2S_RX}, + { AFE_PORT_ID_SECONDARY_META_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, + LPASS_BE_SEC_META_MI2S_RX}, }; /* Track ASM playback & capture sessions of DAI @@ -3435,7 +3439,8 @@ static const char *const be_name[] = { "RX_CDC_DMA_RX_4", "TX_CDC_DMA_TX_4", "RX_CDC_DMA_RX_5", "TX_CDC_DMA_TX_5", "RX_CDC_DMA_RX_6", "RX_CDC_DMA_RX_7", "PRI_SPDIF_TX", "SEC_SPDIF_RX", "SEC_SPDIF_TX", -"SLIM_9_RX", "SLIM_9_TX", "AFE_LOOPBACK_TX" +"SLIM_9_RX", "SLIM_9_TX", "AFE_LOOPBACK_TX", "PRI_META_MI2S_RX", +"SEC_META_MI2S_RX" }; static SOC_ENUM_SINGLE_DECL(mm1_channel_mux, @@ -7138,6 +7143,189 @@ static const struct snd_kcontrol_new int4_mi2s_rx_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new pri_meta_mi2s_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + +}; + +static const struct snd_kcontrol_new sec_meta_mi2s_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new hdmi_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, MSM_BACKEND_DAI_HDMI_RX, @@ -23164,6 +23352,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_7", "Senary TDM7 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_META_MI2S_RX", "Primary META MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_META_MI2S_RX", "Secondary META MI2S Playback", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("WSA_CDC_DMA_RX_0", "WSA CDC DMA0 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("WSA_CDC_DMA_TX_0", "WSA CDC DMA0 Capture", @@ -23474,6 +23666,12 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("SEN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, sen_tdm_rx_3_mixer_controls, ARRAY_SIZE(sen_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_META_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_meta_mi2s_rx_mixer_controls, + ARRAY_SIZE(pri_meta_mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_META_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_meta_mi2s_rx_mixer_controls, + ARRAY_SIZE(sec_meta_mi2s_rx_mixer_controls)), SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, wsa_cdc_dma_rx_0_mixer_controls, ARRAY_SIZE(wsa_cdc_dma_rx_0_mixer_controls)), @@ -24697,6 +24895,44 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEN_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX Audio Mixer"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"PRI_META_MI2S_RX", NULL, "PRI_META_MI2S_RX Audio Mixer"}, + + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SEC_META_MI2S_RX", NULL, "SEC_META_MI2S_RX Audio Mixer"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index c9544cb316d6..aca00bbfccfd 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -81,6 +81,9 @@ #define LPASS_BE_SENARY_MI2S_TX "SENARY_MI2S_TX" #define LPASS_BE_SENARY_MI2S_RX "SENARY_MI2S_RX" +#define LPASS_BE_PRI_META_MI2S_RX "PRI_META_MI2S_RX" +#define LPASS_BE_SEC_META_MI2S_RX "SEC_META_MI2S_RX" + #define LPASS_BE_PRI_TDM_RX_0 "PRI_TDM_RX_0" #define LPASS_BE_PRI_TDM_TX_0 "PRI_TDM_TX_0" #define LPASS_BE_PRI_TDM_RX_1 "PRI_TDM_RX_1" @@ -494,6 +497,8 @@ enum { MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_BACKEND_DAI_SLIMBUS_9_TX, MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_BACKEND_DAI_PRI_META_MI2S_RX, + MSM_BACKEND_DAI_SEC_META_MI2S_RX, MSM_BACKEND_DAI_MAX, }; diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index d2da56e94423..89386c49807e 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -1484,14 +1484,16 @@ static const struct snd_kcontrol_new sec_auxpcm_lb_vol_mixer_controls[] = { }; static const struct snd_kcontrol_new multi_ch_channel_map_mixer_controls[] = { - SOC_SINGLE_MULTI_EXT("Playback Device Channel Map", SND_SOC_NOPM, 0, 47, - 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, msm_qti_pp_get_channel_map_mixer, + SOC_SINGLE_MULTI_EXT("Playback Device Channel Map", SND_SOC_NOPM, + 0, PCM_MAX_CHMAP_ID, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, + msm_qti_pp_get_channel_map_mixer, msm_qti_pp_put_channel_map_mixer), }; static const struct snd_kcontrol_new multi_ch_channel_map_capture_controls[] = { - SOC_SINGLE_MULTI_EXT("Capture Device Channel Map", SND_SOC_NOPM, 0, 47, - 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, msm_qti_pp_get_channel_map_capture, + SOC_SINGLE_MULTI_EXT("Capture Device Channel Map", SND_SOC_NOPM, + 0, PCM_MAX_CHMAP_ID, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, + msm_qti_pp_get_channel_map_capture, msm_qti_pp_put_channel_map_capture), }; -- GitLab From afaec2af1416483f38fa20a071d2c8a488206498 Mon Sep 17 00:00:00 2001 From: Ralf Herz Date: Fri, 26 Jul 2019 15:16:53 +0200 Subject: [PATCH 1175/1645] asoc: qcs405: Add support for META MI2S ports QCS405 can group data lines of several MI2S interfaces. This feature is used with new META MI2S ports. Change-Id: Iffc72a5aae1da8a0620ad988fdc570e5ed493956 Signed-off-by: Ralf Herz --- asoc/qcs405.c | 511 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 510 insertions(+), 1 deletion(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index cadcd405cb9a..36fbfad5c3ed 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -105,6 +105,12 @@ enum { MI2S_MAX, }; +enum { + PRIM_META_MI2S = 0, + SEC_META_MI2S, + META_MI2S_MAX, +}; + enum { PRIM_AUX_PCM = 0, SEC_AUX_PCM, @@ -157,6 +163,12 @@ static u32 mi2s_ebit_clk[MI2S_MAX] = { Q6AFE_LPASS_CLK_ID_SEN_MI2S_EBIT }; +struct meta_mi2s_conf { + u32 num_member_ports; + u32 member_port[MAX_NUM_I2S_META_PORT_MEMBER_PORTS]; + bool clk_enable[MAX_NUM_I2S_META_PORT_MEMBER_PORTS]; +}; + struct dev_config { u32 sample_rate; u32 bit_format; @@ -402,6 +414,11 @@ static struct dev_config mi2s_rx_cfg[] = { [SEN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, }; +static struct dev_config meta_mi2s_rx_cfg[] = { + [PRIM_META_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SEC_META_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + /* Default configuration of SPDIF channels */ static struct dev_config spdif_rx_cfg[] = { [PRIM_SPDIF_RX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, @@ -487,6 +504,14 @@ static const char *const mi2s_ch_text[] = { "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen" }; +static const char *const meta_mi2s_ch_text[] = { + "One", "Two", "Three", "Four", "Five", "Six", "Seven", + "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", + "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", + "Nineteen", "Twenty", "TwentyOne", "TwentyTwo", "TwentyThree", + "TwentyFour", "TwentyFive", "TwentySix", "TwentySeven", + "TwentyEight", "TwentyNine", "Thirty", "ThirtyOne", "ThirtyTwo" +}; static const char *const qos_text[] = {"Disable", "Enable"}; static const char *const cdc_dma_rx_ch_text[] = {"One", "Two"}; @@ -576,6 +601,12 @@ static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_meta_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_meta_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_meta_mi2s_rx_chs, meta_mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_meta_mi2s_rx_chs, meta_mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_meta_mi2s_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_meta_mi2s_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_chs, cdc_dma_rx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_chs, cdc_dma_rx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_0_chs, cdc_dma_tx_ch_text); @@ -689,6 +720,8 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = { static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; +static struct meta_mi2s_conf meta_mi2s_intf_conf[META_MI2S_MAX]; + static int msm_island_vad_get_portid_from_beid(int32_t be_id, int *port_id) { *port_id = 0xFFFF; @@ -3070,6 +3103,143 @@ static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol, return 0; } +static int msm_meta_mi2s_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx = 0; + + if (strnstr(kcontrol->id.name, "PRIM_META_MI2S_RX", + sizeof("PRIM_META_MI2S_RX"))) { + idx = PRIM_META_MI2S; + } else if (strnstr(kcontrol->id.name, "SEC_META_MI2S_RX", + sizeof("SEC_META_MI2S_RX"))) { + idx = SEC_META_MI2S; + } else { + pr_err("%s: unsupported port: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int msm_meta_mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = msm_meta_mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(meta_mi2s_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, meta_mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_meta_mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = msm_meta_mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + meta_mi2s_rx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, meta_mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_meta_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = msm_meta_mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = meta_mi2s_rx_cfg[idx].channels - 1; + + pr_debug("%s: meta_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, meta_mi2s_rx_cfg[idx].channels); + + return 0; +} + +static int msm_meta_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = msm_meta_mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + meta_mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: meta_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, meta_mi2s_rx_cfg[idx].channels); + + return 1; +} + +static int msm_meta_mi2s_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = msm_meta_mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(meta_mi2s_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, meta_mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_meta_mi2s_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_asoc_mach_data *pdata = NULL; + struct snd_soc_card *card = NULL; + int idx = msm_meta_mi2s_get_port_idx(kcontrol); + + card = kcontrol->private_data; + pdata = snd_soc_card_get_drvdata(card); + + if (idx < 0) + return idx; + + /* check for PRIM_META_MI2S and CSRAx to allow 24bit BE config only */ + if ((idx == PRIM_META_MI2S) && pdata->codec_is_csra) { + meta_mi2s_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; + pr_debug("%s: Keeping default format idx[%d]_rx_format = %d, item = %d\n", + __func__, idx, meta_mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + } else { + meta_mi2s_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format( + ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, meta_mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + } + + return 0; +} + static int msm_aux_pcm_rx_format_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -3979,6 +4149,26 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), SOC_ENUM_EXT("SEN_MI2S_TX Format", mi2s_tx_format, msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("PRIM_META_MI2S_RX SampleRate", + prim_meta_mi2s_rx_sample_rate, + msm_meta_mi2s_rx_sample_rate_get, + msm_meta_mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_META_MI2S_RX SampleRate", + sec_meta_mi2s_rx_sample_rate, + msm_meta_mi2s_rx_sample_rate_get, + msm_meta_mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_META_MI2S_RX Channels", prim_meta_mi2s_rx_chs, + msm_meta_mi2s_rx_ch_get, + msm_meta_mi2s_rx_ch_put), + SOC_ENUM_EXT("SEC_META_MI2S_RX Channels", sec_meta_mi2s_rx_chs, + msm_meta_mi2s_rx_ch_get, + msm_meta_mi2s_rx_ch_put), + SOC_ENUM_EXT("PRIM_META_MI2S_RX Format", mi2s_rx_format, + msm_meta_mi2s_rx_format_get, + msm_meta_mi2s_rx_format_put), + SOC_ENUM_EXT("SEC_META_MI2S_RX Format", mi2s_rx_format, + msm_meta_mi2s_rx_format_get, + msm_meta_mi2s_rx_format_put), SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, @@ -4761,6 +4951,25 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, channels->min = channels->max = mi2s_tx_cfg[SEN_MI2S].channels; break; + + case MSM_BACKEND_DAI_PRI_META_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + meta_mi2s_rx_cfg[PRIM_META_MI2S].bit_format); + rate->min = rate->max = + meta_mi2s_rx_cfg[PRIM_META_MI2S].sample_rate; + channels->min = channels->max = + meta_mi2s_rx_cfg[PRIM_META_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SEC_META_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + meta_mi2s_rx_cfg[SEC_META_MI2S].bit_format); + rate->min = rate->max = + meta_mi2s_rx_cfg[SEC_META_MI2S].sample_rate; + channels->min = channels->max = + meta_mi2s_rx_cfg[SEC_META_MI2S].channels; + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0: case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1: idx = msm_cdc_dma_get_idx_from_beid(dai_link->id); @@ -5996,6 +6205,172 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) mutex_unlock(&mi2s_intf_conf[index].lock); } +static int msm_meta_mi2s_set_sclk(struct snd_pcm_substream *substream, + int member_id, bool enable) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int be_id = 0; + int port_id = 0; + int index = cpu_dai->id; + u32 bit_per_sample = 0; + + switch (member_id) { + case PRIM_MI2S: + be_id = MSM_BACKEND_DAI_PRI_MI2S_RX; + break; + case SEC_MI2S: + be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX; + break; + case TERT_MI2S: + be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX; + break; + case QUAT_MI2S: + be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX; + break; + default: + dev_err(rtd->card->dev, "%s: Invalid member_id\n", __func__); + ret = -EINVAL; + goto err; + } + + port_id = msm_get_port_id(be_id); + if (port_id < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto err; + } + + if (enable) { + bit_per_sample = + get_mi2s_bits_per_sample( + meta_mi2s_rx_cfg[index].bit_format); + mi2s_clk[member_id].clk_freq_in_hz = + meta_mi2s_rx_cfg[index].sample_rate * 2 * + bit_per_sample; + + dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, + mi2s_clk[member_id].clk_freq_in_hz); + } + + mi2s_clk[member_id].enable = enable; + ret = afe_set_lpass_clock_v2(port_id, &mi2s_clk[member_id]); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed for port 0x%x , err:%d\n", + __func__, port_id, ret); + goto err; + } + +err: + return ret; +} + +static int msm_meta_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + int i = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int index = cpu_dai->id; + int member_port = 0; + unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + if (index < PRIM_META_MI2S || index >= META_MI2S_MAX) { + ret = -EINVAL; + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto err; + } + + for (i = 0; i < meta_mi2s_intf_conf[index].num_member_ports; i++) { + member_port = meta_mi2s_intf_conf[index].member_port[i]; + + if (!mi2s_intf_conf[member_port].msm_is_mi2s_master) { + mi2s_clk[member_port].clk_id = + mi2s_ebit_clk[member_port]; + fmt = SND_SOC_DAIFMT_CBM_CFM; + } + + ret = msm_meta_mi2s_set_sclk(substream, member_port, true); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed to enable MI2S clock, err:%d\n", + __func__, ret); + goto clk_off; + } + meta_mi2s_intf_conf[index].clk_enable[i] = true; + + if (i == 0) { + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) { + pr_err("%s: set fmt cpu dai failed for META_MI2S (%d), err:%d\n", + __func__, index, ret); + goto clk_off; + } + } + if (pdata->mi2s_gpio_p[member_port]) + msm_cdc_pinctrl_select_active_state( + pdata->mi2s_gpio_p[member_port]); + } + return 0; + +clk_off: + for (i = 0; i < meta_mi2s_intf_conf[index].num_member_ports; i++) { + member_port = meta_mi2s_intf_conf[index].member_port[i]; + if (pdata->mi2s_gpio_p[member_port]) + msm_cdc_pinctrl_select_sleep_state( + pdata->mi2s_gpio_p[member_port]); + + if (meta_mi2s_intf_conf[index].clk_enable[i]) { + msm_meta_mi2s_set_sclk(substream, member_port, false); + meta_mi2s_intf_conf[index].clk_enable[i] = false; + } + } +err: + return ret; +} + +static void msm_meta_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret = 0; + int i = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int index = rtd->cpu_dai->id; + int member_port = 0; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + if (index < PRIM_MI2S || index >= MI2S_MAX) { + pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); + return; + } + + for (i = 0; i < meta_mi2s_intf_conf[index].num_member_ports; i++) { + member_port = meta_mi2s_intf_conf[index].member_port[i]; + + if (pdata->mi2s_gpio_p[member_port]) + msm_cdc_pinctrl_select_sleep_state( + pdata->mi2s_gpio_p[member_port]); + + ret = msm_meta_mi2s_set_sclk(substream, member_port, false); + if (ret < 0) + pr_err("%s:clock disable failed for META MI2S (%d); ret=%d\n", + __func__, index, ret); + } +} + static int msm_spdif_set_clk(struct snd_pcm_substream *substream, bool enable) { int ret = 0; @@ -6131,6 +6506,11 @@ static struct snd_soc_ops msm_mi2s_be_ops = { .shutdown = msm_mi2s_snd_shutdown, }; +static struct snd_soc_ops msm_meta_mi2s_be_ops = { + .startup = msm_meta_mi2s_snd_startup, + .shutdown = msm_meta_mi2s_snd_shutdown, +}; + static struct snd_soc_ops msm_auxpcm_be_ops = { .startup = msm_snd_auxpcm_startup, }; @@ -7567,6 +7947,39 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { }; +static struct snd_soc_dai_link msm_meta_mi2s_be_dai_links[] = { + { + .name = LPASS_BE_PRI_META_MI2S_RX, + .stream_name = "Primary META MI2S Playback", + .cpu_dai_name = "msm-dai-q6-meta-mi2s.4864", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_META_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_meta_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_META_MI2S_RX, + .stream_name = "Secondary META MI2S Playback", + .cpu_dai_name = "msm-dai-q6-meta-mi2s.4866", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_META_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_meta_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, +}; + static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { /* Primary AUX PCM Backend DAI Links */ { @@ -7885,6 +8298,7 @@ static struct snd_soc_dai_link msm_qcs405_dai_links[ ARRAY_SIZE(msm_tasha_be_dai_links) + ARRAY_SIZE(msm_wcn_be_dai_links) + ARRAY_SIZE(msm_mi2s_be_dai_links) + + ARRAY_SIZE(msm_meta_mi2s_be_dai_links) + ARRAY_SIZE(msm_auxpcm_be_dai_links) + ARRAY_SIZE(msm_va_cdc_dma_be_dai_links) + ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links) + @@ -8140,7 +8554,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) uint32_t tasha_codec = 0, auxpcm_audio_intf = 0; uint32_t va_bolero_codec = 0, wsa_bolero_codec = 0, mi2s_audio_intf = 0; uint32_t spdif_audio_intf = 0, wcn_audio_intf = 0; - uint32_t afe_loopback_intf = 0; + uint32_t afe_loopback_intf = 0, meta_mi2s_intf = 0; const struct of_device_id *match; char __iomem *spdif_cfg, *spdif_pin_ctl; int rc = 0; @@ -8248,6 +8662,22 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) ARRAY_SIZE(msm_mi2s_be_dai_links); } } + + rc = of_property_read_u32(dev->of_node, "qcom,meta-mi2s-intf", + &meta_mi2s_intf); + if (rc) { + dev_dbg(dev, "%s: No DT match META-MI2S interface\n", + __func__); + } else { + if (meta_mi2s_intf) { + memcpy(msm_qcs405_dai_links + total_links, + msm_meta_mi2s_be_dai_links, + sizeof(msm_meta_mi2s_be_dai_links)); + total_links += + ARRAY_SIZE(msm_meta_mi2s_be_dai_links); + } + } + rc = of_property_read_u32(dev->of_node, "qcom,auxpcm-audio-intf", &auxpcm_audio_intf); @@ -8807,6 +9237,81 @@ static void msm_i2s_auxpcm_deinit(void) } } +static void msm_meta_mi2s_init(struct platform_device *pdev) +{ + int rc = 0; + int i = 0; + int index = 0; + bool parse_of = false; + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct snd_soc_dai_link *dai_link = card->dai_link; + + dev_dbg(&pdev->dev, "%s: read from DT\n", __func__); + + for (index = 0; index < META_MI2S_MAX; index++) { + meta_mi2s_intf_conf[index].num_member_ports = 0; + meta_mi2s_intf_conf[index].member_port[0] = 0; + meta_mi2s_intf_conf[index].member_port[1] = 0; + meta_mi2s_intf_conf[index].member_port[2] = 0; + meta_mi2s_intf_conf[index].member_port[3] = 0; + meta_mi2s_intf_conf[index].clk_enable[0] = false; + meta_mi2s_intf_conf[index].clk_enable[1] = false; + meta_mi2s_intf_conf[index].clk_enable[2] = false; + meta_mi2s_intf_conf[index].clk_enable[3] = false; + } + + /* get member port info to set matching clocks for involved ports */ + for (i = 0; i < card->num_links; i++) { + if (dai_link[i].id == MSM_BACKEND_DAI_PRI_META_MI2S_RX) { + parse_of = true; + index = PRIM_META_MI2S; + } else if (dai_link[i].id == MSM_BACKEND_DAI_SEC_META_MI2S_RX) { + parse_of = true; + index = SEC_META_MI2S; + } else { + parse_of = false; + } + if (parse_of && dai_link[i].cpu_of_node) { + rc = of_property_read_u32(dai_link[i].cpu_of_node, + "qcom,msm-mi2s-num-members", + &meta_mi2s_intf_conf[index].num_member_ports); + if (rc) { + dev_err(&pdev->dev, "%s: invalid num from DT file %s\n", + __func__, "qcom,msm-mi2s-num-members"); + } + + if (meta_mi2s_intf_conf[index].num_member_ports > + MAX_NUM_I2S_META_PORT_MEMBER_PORTS) { + dev_err(&pdev->dev, "%s: num-members %d too large from DT file\n", + __func__, + meta_mi2s_intf_conf[index].num_member_ports); + } + + if (meta_mi2s_intf_conf[index].num_member_ports > 0) { + rc = of_property_read_u32_array( + dai_link[i].cpu_of_node, + "qcom,msm-mi2s-member-id", + meta_mi2s_intf_conf[index].member_port, + meta_mi2s_intf_conf[index].num_member_ports); + if (rc) { + dev_err(&pdev->dev, "%s: member-id from DT file %s\n", + __func__, + "qcom,msm-mi2s-member-id"); + } + } + + dev_dbg(&pdev->dev, "dev name %s num-members=%d\n", + dev_name(&pdev->dev), + meta_mi2s_intf_conf[index].num_member_ports); + dev_dbg(&pdev->dev, "member array (%d, %d, %d, %d)\n", + meta_mi2s_intf_conf[index].member_port[0], + meta_mi2s_intf_conf[index].member_port[1], + meta_mi2s_intf_conf[index].member_port[2], + meta_mi2s_intf_conf[index].member_port[3]); + } + } +} + static int msm_scan_i2c_addr(struct platform_device *pdev, uint32_t busnum, uint32_t addr) { @@ -8984,6 +9489,8 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) if (val) { pdata->codec_is_csra = true; mi2s_rx_cfg[PRIM_MI2S].bit_format = SNDRV_PCM_FORMAT_S24_LE; + meta_mi2s_rx_cfg[PRIM_META_MI2S].bit_format = + SNDRV_PCM_FORMAT_S24_LE; ret = msm_init_csra_dev(pdev, card); if (ret) goto err; @@ -9065,6 +9572,8 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) msm_i2s_auxpcm_init(pdev); + msm_meta_mi2s_init(pdev); + is_initial_boot = true; return 0; err: -- GitLab From b6ef9e0377bbaf6a342ea230b6349b3fb6ff4d34 Mon Sep 17 00:00:00 2001 From: Ramlal Karra Date: Wed, 14 Aug 2019 17:53:29 +0530 Subject: [PATCH 1176/1645] asoc: Add HiFi Filter support in driver Open adm with 32 bit-width when HiFi Filter control is set Change-Id: I2c4c4c732b15b26b42d8169ae4c945356bf2bfa6 Signed-off-by: Ramlal Karra --- asoc/msm-pcm-routing-v2.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 854774a0f121..abbb5bd566d6 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -80,6 +80,7 @@ static int msm_route_ext_ec_ref; static bool is_custom_stereo_on; static bool is_ds2_on; static bool swap_ch; +static bool hifi_filter_enabled; static int aanc_level; static int num_app_cfg_types; static int msm_ec_ref_port_id; @@ -1517,6 +1518,9 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, topology = COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY; pr_debug("%s: Before adm open topology %d\n", __func__, topology); + if (hifi_filter_enabled) + bit_width = msm_routing_get_bit_width( + SNDRV_PCM_FORMAT_S32_LE); copp_idx = adm_open(port_id, path_type, sample_rate, @@ -1862,6 +1866,9 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, topology = msm_routing_get_adm_topology(fedai_id, session_type, i); + if (hifi_filter_enabled) + bits_per_sample = msm_routing_get_bit_width( + SNDRV_PCM_FORMAT_S32_LE); copp_idx = adm_open(port_id, path_type, sample_rate, channels, topology, perf_mode, bits_per_sample, @@ -2129,6 +2136,9 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) reg); acdb_dev_id = fe_dai_app_type_cfg[val][session_type][reg].acdb_dev_id; + if (hifi_filter_enabled) + bits_per_sample = msm_routing_get_bit_width( + SNDRV_PCM_FORMAT_S32_LE); copp_idx = adm_open(port_id, path_type, sample_rate, channels, topology, fdai->perf_mode, bits_per_sample, @@ -21379,6 +21389,28 @@ static const struct snd_kcontrol_new use_ds1_or_ds2_controls[] = { msm_routing_put_use_ds1_or_ds2_control), }; +static int msm_routing_get_hifi_filter_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = hifi_filter_enabled; + return 0; +} + +static int msm_routing_put_hifi_filter_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + hifi_filter_enabled = ucontrol->value.integer.value[0]; + return 0; +} + +static const struct snd_kcontrol_new hifi_filter_controls[] = { + SOC_SINGLE_EXT("HiFi Filter", SND_SOC_NOPM, 0, + 1, 0, msm_routing_get_hifi_filter_control, + msm_routing_put_hifi_filter_control), +}; + int msm_routing_get_rms_value_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int rc = 0; @@ -27979,6 +28011,9 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) || (fdai->passthr_mode == COMPRESSED_PASSTHROUGH_IEC61937)) topology = COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY; + if (hifi_filter_enabled) + bits_per_sample = msm_routing_get_bit_width( + SNDRV_PCM_FORMAT_S32_LE); copp_idx = adm_open(port_id, path_type, sample_rate, channels, topology, fdai->perf_mode, bits_per_sample, @@ -28578,6 +28613,10 @@ static int msm_routing_probe(struct snd_soc_component *component) use_ds1_or_ds2_controls, ARRAY_SIZE(use_ds1_or_ds2_controls)); + snd_soc_add_component_controls(component, + hifi_filter_controls, + ARRAY_SIZE(hifi_filter_controls)); + snd_soc_add_component_controls(component, device_pp_params_mixer_controls, ARRAY_SIZE(device_pp_params_mixer_controls)); -- GitLab From 818d4e9b7ff277c7936c31e3b8dfd8814d95cce2 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 26 Aug 2019 16:49:28 +0800 Subject: [PATCH 1177/1645] dsp: lsm: adjust mutex_lock to avoid deadlock When dispatch_event in apr and q6lsm_client_free in q6lsm are running concurrently, there may be deadlock between session_lock in lsm and svc->m_lock in apr. Adjust session_lock in q6lsm_client_free to avoid deadlock. Change-Id: I26eb788d4c17af78272dd1f717717e865dfbd0ac Signed-off-by: Meng Wang --- dsp/q6lsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index d55dfc313c39..d27bbac68e88 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -372,9 +372,9 @@ void q6lsm_client_free(struct lsm_client *client) pr_err("%s: Invalid Session %d\n", __func__, client->session); return; } - mutex_lock(&session_lock); apr_deregister(client->apr); client->mmap_apr = NULL; + mutex_lock(&session_lock); q6lsm_session_free(client); q6lsm_mmap_apr_dereg(); mutex_destroy(&client->cmd_lock); -- GitLab From 96c842a2611f9002ccec911f2d42f2535b06d761 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 29 Aug 2019 12:11:21 +0530 Subject: [PATCH 1178/1645] SoC: soundwire: Update debug soundwire master read/write functions Replace debug read/write register functions with swr_master_read/swr_master_write to support different interfaces to access soundwire registers. Change-Id: I377bb927ee769a18c0179045953a521d0a83057f Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 205 +++++++++++++++++++++++++++----------------- soc/swr-mstr-ctrl.h | 19 ++++ 2 files changed, 147 insertions(+), 77 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index c4deb20014ea..6386bd7f1e1b 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -18,8 +18,6 @@ #include #include #include -#include -#include #include #include #include @@ -77,30 +75,19 @@ enum { #define SWRM_MAX_PORT_REG 120 #define SWRM_MAX_INIT_REG 11 -#define SWR_MSTR_MAX_REG_ADDR 0x1740 -#define SWR_MSTR_START_REG_ADDR 0x00 -#define SWR_MSTR_MAX_BUF_LEN 32 -#define BYTES_PER_LINE 12 -#define SWR_MSTR_RD_BUF_LEN 8 -#define SWR_MSTR_WR_BUF_LEN 32 - #define MAX_FIFO_RD_FAIL_RETRY 3 -static struct swr_mstr_ctrl *dbgswrm; -static struct dentry *debugfs_swrm_dent; -static struct dentry *debugfs_peek; -static struct dentry *debugfs_poke; -static struct dentry *debugfs_reg_dump; -static unsigned int read_data; - static bool swrm_lock_sleep(struct swr_mstr_ctrl *swrm); static void swrm_unlock_sleep(struct swr_mstr_ctrl *swrm); +static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr); +static void swr_master_write(struct swr_mstr_ctrl *swrm, u16 reg_addr, u32 val); static bool swrm_is_msm_variant(int val) { return (val == SWRM_VERSION_1_3); } +#ifdef CONFIG_DEBUG_FS static int swrm_debug_open(struct inode *inode, struct file *file) { file->private_data = inode->i_private; @@ -130,19 +117,26 @@ static int get_parameters(char *buf, u32 *param1, int num_of_par) return 0; } -static ssize_t swrm_reg_show(char __user *ubuf, size_t count, - loff_t *ppos) +static ssize_t swrm_reg_show(struct swr_mstr_ctrl *swrm, char __user *ubuf, + size_t count, loff_t *ppos) { int i, reg_val, len; ssize_t total = 0; char tmp_buf[SWR_MSTR_MAX_BUF_LEN]; + int rem = 0; if (!ubuf || !ppos) return 0; - for (i = (((int) *ppos / BYTES_PER_LINE) + SWR_MSTR_START_REG_ADDR); - i <= SWR_MSTR_MAX_REG_ADDR; i += 4) { - reg_val = dbgswrm->read(dbgswrm->handle, i); + i = ((int) *ppos + SWR_MSTR_START_REG_ADDR); + rem = i%4; + + if (rem) + i = (i - rem); + + for (; i <= SWR_MSTR_MAX_REG_ADDR; i += 4) { + usleep_range(100, 150); + reg_val = swr_master_read(swrm, i); len = snprintf(tmp_buf, 25, "0x%.3x: 0x%.2x\n", i, reg_val); if ((total + len) >= count - 1) break; @@ -159,85 +153,142 @@ static ssize_t swrm_reg_show(char __user *ubuf, size_t count, return total; } +static ssize_t swrm_debug_reg_dump(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct swr_mstr_ctrl *swrm; + + if (!count || !file || !ppos || !ubuf) + return -EINVAL; + + swrm = file->private_data; + if (!swrm) + return -EINVAL; + + if (*ppos < 0) + return -EINVAL; + + return swrm_reg_show(swrm, ubuf, count, ppos); +} + static ssize_t swrm_debug_read(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { char lbuf[SWR_MSTR_RD_BUF_LEN]; - char *access_str; - ssize_t ret_cnt; + struct swr_mstr_ctrl *swrm = NULL; if (!count || !file || !ppos || !ubuf) return -EINVAL; - access_str = file->private_data; + swrm = file->private_data; + if (!swrm) + return -EINVAL; + if (*ppos < 0) return -EINVAL; - if (!strcmp(access_str, "swrm_peek")) { - snprintf(lbuf, sizeof(lbuf), "0x%x\n", read_data); - ret_cnt = simple_read_from_buffer(ubuf, count, ppos, lbuf, + snprintf(lbuf, sizeof(lbuf), "0x%x\n", swrm->read_data); + + return simple_read_from_buffer(ubuf, count, ppos, lbuf, strnlen(lbuf, 7)); - } else if (!strcmp(access_str, "swrm_reg_dump")) { - ret_cnt = swrm_reg_show(ubuf, count, ppos); - } else { - pr_err("%s: %s not permitted to read\n", __func__, access_str); - ret_cnt = -EPERM; - } - return ret_cnt; } -static ssize_t swrm_debug_write(struct file *filp, - const char __user *ubuf, size_t cnt, loff_t *ppos) +static ssize_t swrm_debug_peek_write(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos) +{ + char lbuf[SWR_MSTR_RD_BUF_LEN]; + int rc; + u32 param[5]; + struct swr_mstr_ctrl *swrm = NULL; + + if (!count || !file || !ppos || !ubuf) + return -EINVAL; + + swrm = file->private_data; + if (!swrm) + return -EINVAL; + + if (*ppos < 0) + return -EINVAL; + + if (count > sizeof(lbuf) - 1) + return -EINVAL; + + rc = copy_from_user(lbuf, ubuf, count); + if (rc) + return -EFAULT; + + lbuf[count] = '\0'; + rc = get_parameters(lbuf, param, 1); + if ((param[0] <= SWR_MSTR_MAX_REG_ADDR) && (rc == 0)) + swrm->read_data = swr_master_read(swrm, param[0]); + else + rc = -EINVAL; + + if (rc == 0) + rc = count; + else + dev_err(swrm->dev, "%s: rc = %d\n", __func__, rc); + + return rc; +} + +static ssize_t swrm_debug_write(struct file *file, + const char __user *ubuf, size_t count, loff_t *ppos) { char lbuf[SWR_MSTR_WR_BUF_LEN]; int rc; u32 param[5]; - char *access_str; + struct swr_mstr_ctrl *swrm; - if (!filp || !ppos || !ubuf) + if (!file || !ppos || !ubuf) return -EINVAL; - access_str = filp->private_data; - if (cnt > sizeof(lbuf) - 1) + swrm = file->private_data; + if (!swrm) + return -EINVAL; + + if (count > sizeof(lbuf) - 1) return -EINVAL; - rc = copy_from_user(lbuf, ubuf, cnt); + rc = copy_from_user(lbuf, ubuf, count); if (rc) return -EFAULT; - lbuf[cnt] = '\0'; - if (!strcmp(access_str, "swrm_poke")) { - /* write */ - rc = get_parameters(lbuf, param, 2); - if ((param[0] <= SWR_MSTR_MAX_REG_ADDR) && - (param[1] <= 0xFFFFFFFF) && - (rc == 0)) - rc = dbgswrm->write(dbgswrm->handle, param[0], - param[1]); - else - rc = -EINVAL; - } else if (!strcmp(access_str, "swrm_peek")) { - /* read */ - rc = get_parameters(lbuf, param, 1); - if ((param[0] <= SWR_MSTR_MAX_REG_ADDR) && (rc == 0)) - read_data = dbgswrm->read(dbgswrm->handle, param[0]); - else - rc = -EINVAL; - } + lbuf[count] = '\0'; + rc = get_parameters(lbuf, param, 2); + if ((param[0] <= SWR_MSTR_MAX_REG_ADDR) && + (param[1] <= 0xFFFFFFFF) && + (rc == 0)) + swr_master_write(swrm, param[0], param[1]); + else + rc = -EINVAL; + if (rc == 0) - rc = cnt; + rc = count; else pr_err("%s: rc = %d\n", __func__, rc); return rc; } -static const struct file_operations swrm_debug_ops = { +static const struct file_operations swrm_debug_read_ops = { .open = swrm_debug_open, - .write = swrm_debug_write, + .write = swrm_debug_peek_write, .read = swrm_debug_read, }; +static const struct file_operations swrm_debug_write_ops = { + .open = swrm_debug_open, + .write = swrm_debug_write, +}; + +static const struct file_operations swrm_debug_dump_ops = { + .open = swrm_debug_open, + .read = swrm_debug_reg_dump, +}; +#endif + static void swrm_reg_dump(struct swr_mstr_ctrl *swrm, u32 *reg, u32 *val, int len, const char* func) { @@ -2320,23 +2371,23 @@ static int swrm_probe(struct platform_device *pdev) if (pdev->dev.of_node) of_register_swr_devices(&swrm->master); - dbgswrm = swrm; - debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0); - if (!IS_ERR(debugfs_swrm_dent)) { - debugfs_peek = debugfs_create_file("swrm_peek", - S_IFREG | 0444, debugfs_swrm_dent, - (void *) "swrm_peek", &swrm_debug_ops); +#ifdef CONFIG_DEBUG_FS + swrm->debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0); + if (!IS_ERR(swrm->debugfs_swrm_dent)) { + swrm->debugfs_peek = debugfs_create_file("swrm_peek", + S_IFREG | 0444, swrm->debugfs_swrm_dent, + (void *) swrm, &swrm_debug_read_ops); - debugfs_poke = debugfs_create_file("swrm_poke", - S_IFREG | 0444, debugfs_swrm_dent, - (void *) "swrm_poke", &swrm_debug_ops); + swrm->debugfs_poke = debugfs_create_file("swrm_poke", + S_IFREG | 0444, swrm->debugfs_swrm_dent, + (void *) swrm, &swrm_debug_write_ops); - debugfs_reg_dump = debugfs_create_file("swrm_reg_dump", - S_IFREG | 0444, debugfs_swrm_dent, - (void *) "swrm_reg_dump", - &swrm_debug_ops); + swrm->debugfs_reg_dump = debugfs_create_file("swrm_reg_dump", + S_IFREG | 0444, swrm->debugfs_swrm_dent, + (void *) swrm, + &swrm_debug_dump_ops); } - +#endif ret = device_init_wakeup(swrm->dev, true); if (ret) { dev_err(swrm->dev, "Device wakeup init failed: %d\n", ret); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index e05ede258dc9..ba220784655a 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -11,6 +11,18 @@ #include #include +#ifdef CONFIG_DEBUG_FS +#include +#include + +#define SWR_MSTR_MAX_REG_ADDR 0x1740 +#define SWR_MSTR_START_REG_ADDR 0x00 +#define SWR_MSTR_MAX_BUF_LEN 32 +#define BYTES_PER_LINE 12 +#define SWR_MSTR_RD_BUF_LEN 8 +#define SWR_MSTR_WR_BUF_LEN 32 +#endif + #define SWR_ROW_48 0 #define SWR_ROW_50 1 #define SWR_ROW_64 2 @@ -160,6 +172,13 @@ struct swr_mstr_ctrl { u32 swr_irq_wakeup_capable; int hw_core_clk_en; int aud_core_clk_en; +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_swrm_dent; + struct dentry *debugfs_peek; + struct dentry *debugfs_poke; + struct dentry *debugfs_reg_dump; + unsigned int read_data; +#endif }; #endif /* _SWR_WCD_CTRL_H */ -- GitLab From 17f051657412cfe22b6a4e2efb5c7f74097d935a Mon Sep 17 00:00:00 2001 From: Ramprasad Katkam Date: Mon, 15 Apr 2019 18:37:10 +0530 Subject: [PATCH 1179/1645] asoc: check subsys state in FE instead of q6 state audio can use adsp or modem. Hence check apr subsys state commonly instead of adsp or modem. Change-Id: Ice70ab23797ec5f940e1bda3fa1b2d84c196fc56 Signed-off-by: Ramprasad Katkam --- asoc/msm-compress-q6-v2.c | 15 +++++++++++++++ asoc/msm-pcm-q6-noirq.c | 6 ++++++ asoc/msm-pcm-q6-v2.c | 8 ++++++++ asoc/msm-transcode-loopback-q6-v2.c | 7 +++++++ 4 files changed, 36 insertions(+) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 75b217f13bea..49050c4d1287 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -1640,6 +1640,7 @@ static int msm_compr_playback_open(struct snd_compr_stream *cstream) struct snd_soc_component *component = NULL; struct msm_compr_audio *prtd = NULL; struct msm_compr_pdata *pdata = NULL; + enum apr_subsys_state subsys_state; pr_debug("%s\n", __func__); component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); @@ -1653,6 +1654,13 @@ static int msm_compr_playback_open(struct snd_compr_stream *cstream) __func__, rtd->dai_link->cpu_dai_name, -EBUSY); return -EBUSY; } + + subsys_state = apr_get_subsys_state(); + if (subsys_state == APR_SUBSYS_DOWN) { + pr_debug("%s: adsp is down\n", __func__); + return -ENETRESET; + } + prtd = kzalloc(sizeof(struct msm_compr_audio), GFP_KERNEL); if (prtd == NULL) { pr_err("Failed to allocate memory for msm_compr_audio\n"); @@ -1747,6 +1755,7 @@ static int msm_compr_capture_open(struct snd_compr_stream *cstream) struct snd_soc_component *component = NULL; struct msm_compr_audio *prtd; struct msm_compr_pdata *pdata = NULL; + enum apr_subsys_state subsys_state; pr_debug("%s\n", __func__); component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); @@ -1759,6 +1768,12 @@ static int msm_compr_capture_open(struct snd_compr_stream *cstream) pr_err("%s: pdata is NULL\n", __func__); return -EINVAL; } + + subsys_state = apr_get_subsys_state(); + if (subsys_state == APR_SUBSYS_DOWN) { + pr_debug("%s: adsp is down\n", __func__); + return -ENETRESET; + } prtd = kzalloc(sizeof(struct msm_compr_audio), GFP_KERNEL); if (!prtd) { pr_err("Failed to allocate memory for msm_compr_audio\n"); diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index 6d1d30ddb8a2..cd69d776d142 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -181,7 +181,13 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct msm_audio *prtd; int ret = 0; + enum apr_subsys_state subsys_state; + subsys_state = apr_get_subsys_state(); + if (subsys_state == APR_SUBSYS_DOWN) { + pr_debug("%s: adsp is down\n", __func__); + return -ENETRESET; + } prtd = kzalloc(sizeof(struct msm_audio), GFP_KERNEL); if (prtd == NULL) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 88ce6bb769d3..6525dd03106f 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -676,6 +676,7 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); struct msm_audio *prtd; struct msm_plat_data *pdata; + enum apr_subsys_state subsys_state; int ret = 0; if (!component) { @@ -689,6 +690,13 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) pr_err("%s: platform data not populated\n", __func__); return -EINVAL; } + + subsys_state = apr_get_subsys_state(); + if (subsys_state == APR_SUBSYS_DOWN) { + pr_debug("%s: adsp is down\n", __func__); + return -ENETRESET; + } + prtd = kzalloc(sizeof(struct msm_audio), GFP_KERNEL); if (prtd == NULL) return -ENOMEM; diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index 5d572f11585c..df48f5a57adc 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -426,12 +426,19 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, struct trans_loopback_pdata *pdata; uint32_t bit_width = 16; int ret = 0; + enum apr_subsys_state subsys_state; if (trans == NULL) { pr_err("%s: Invalid param\n", __func__); return -EINVAL; } + subsys_state = apr_get_subsys_state(); + if (subsys_state == APR_SUBSYS_DOWN) { + pr_debug("%s: adsp is down\n", __func__); + return -ENETRESET; + } + mutex_lock(&trans->lock); rtd = snd_pcm_substream_chip(cstream); -- GitLab From d083a83b6ebccc918b955e640f95c7d724929bd8 Mon Sep 17 00:00:00 2001 From: Cong Tang Date: Tue, 27 Aug 2019 16:21:06 +0530 Subject: [PATCH 1180/1645] ASoC: msm: Loopback Driver Reg Stream in Prepare Stage Move the msm_pcm_routing_reg_phy_stream() to prepare stage. Then it allows to set channel mixer configuration pre usecase start. Change-Id: I1811c4d9bcbdd2bb1ee425044407a2c61e794a9a Signed-off-by: Cong Tang Signed-off-by: Viraja Kommaraju --- asoc/msm-pcm-loopback-v2.c | 39 ++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index 07cf20b6ed82..70c94e43d5aa 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -252,7 +252,6 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) struct msm_pcm_loopback *pcm = NULL; int ret = 0; uint16_t bits_per_sample = 16; - struct msm_pcm_routing_evt event; struct asm_session_mtmx_strtr_param_window_v2_t asm_mtmx_strtr_window; uint32_t param_id; struct msm_pcm_pdata *pdata; @@ -279,10 +278,6 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) dev_dbg(component->dev, "%s: pcm out open: %d,%d\n", __func__, pcm->instance, substream->stream); if (pcm->instance == 2) { - struct snd_soc_pcm_runtime *soc_pcm_rx = - pcm->playback_substream->private_data; - struct snd_soc_pcm_runtime *soc_pcm_tx = - pcm->capture_substream->private_data; if (pcm->audio_client != NULL) stop_pcm(pcm); @@ -314,15 +309,6 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) mutex_unlock(&pcm->lock); return -ENOMEM; } - event.event_func = msm_pcm_route_event_handler; - event.priv_data = (void *) pcm; - msm_pcm_routing_reg_phy_stream(soc_pcm_tx->dai_link->id, - pcm->audio_client->perf_mode, - pcm->session_id, pcm->capture_substream->stream); - msm_pcm_routing_reg_phy_stream_v2(soc_pcm_rx->dai_link->id, - pcm->audio_client->perf_mode, - pcm->session_id, pcm->playback_substream->stream, - event); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { pcm->playback_substream = substream; ret = pcm_loopback_set_volume(pcm, pcm->volume); @@ -442,7 +428,9 @@ static int msm_pcm_prepare(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + struct msm_pcm_routing_evt event; + memset(&event, 0, sizeof(event)); if (!component) { pr_err("%s: component is NULL\n", __func__); return -EINVAL; @@ -452,6 +440,12 @@ static int msm_pcm_prepare(struct snd_pcm_substream *substream) dev_dbg(component->dev, "%s: ASM loopback stream:%d\n", __func__, substream->stream); + + if (pcm->playback_start && pcm->capture_start) { + mutex_unlock(&pcm->lock); + return ret; + } + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (!pcm->playback_start) pcm->playback_start = 1; @@ -459,6 +453,23 @@ static int msm_pcm_prepare(struct snd_pcm_substream *substream) if (!pcm->capture_start) pcm->capture_start = 1; } + + if (pcm->playback_start && pcm->capture_start) { + struct snd_soc_pcm_runtime *soc_pcm_rx = + pcm->playback_substream->private_data; + struct snd_soc_pcm_runtime *soc_pcm_tx = + pcm->capture_substream->private_data; + event.event_func = msm_pcm_route_event_handler; + event.priv_data = (void *) pcm; + msm_pcm_routing_reg_phy_stream(soc_pcm_tx->dai_link->id, + pcm->audio_client->perf_mode, + pcm->session_id, pcm->capture_substream->stream); + msm_pcm_routing_reg_phy_stream_v2(soc_pcm_rx->dai_link->id, + pcm->audio_client->perf_mode, + pcm->session_id, pcm->playback_substream->stream, + event); + } + mutex_unlock(&pcm->lock); return ret; -- GitLab From fae3404de2c4e0ad0975edef12acd996692ab76e Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 3 Sep 2019 17:12:59 +0800 Subject: [PATCH 1181/1645] dsp: lsm: check for mem_map_handle Sometimes adsp may fail to allocate memory for SVA calibration data and add check if mem_map_handle is assigned with valid non-zero handle to avoid panic. Change-Id: Icad722edc52906e63d581aafa02b42b8518ebca6 Signed-off-by: Meng Wang --- dsp/q6lsm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index d55dfc313c39..2fe4f5f4e225 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -446,6 +446,8 @@ static int q6lsm_apr_send_pkt(struct lsm_client *client, void *handle, if (wait) mutex_unlock(&lsm_common.apr_lock); + if (mmap_p && *mmap_p == 0) + ret = -ENOMEM; pr_debug("%s: leave ret %d\n", __func__, ret); return ret; } -- GitLab From b5cf45832696953488308daeaececa2e348b8043 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 4 Sep 2019 09:22:07 +0800 Subject: [PATCH 1182/1645] asoc: hdmi: return 0 when get_audio_edid_blk is NULL when get_audio_edid_blk is NULL, msm_ext_disp_edid_ctl_info returns error value. And it would cause tinymix doesn't have full mix cmd list. Return 0 instead to avoid such issue. Change-Id: Ic13067483b373fa4a81b663ece3d3e4a18ea8a87 Signed-off-by: Meng Wang --- asoc/codecs/msm_hdmi_codec_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/msm_hdmi_codec_rx.c b/asoc/codecs/msm_hdmi_codec_rx.c index 8d2507e461e7..5144b923b03e 100644 --- a/asoc/codecs/msm_hdmi_codec_rx.c +++ b/asoc/codecs/msm_hdmi_codec_rx.c @@ -100,7 +100,7 @@ static int msm_ext_disp_edid_ctl_info(struct snd_kcontrol *kcontrol, uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; uinfo->count = 0; mutex_unlock(&codec_data->dp_ops_lock); - return -EINVAL; + return 0; } rc = codec_data->ext_disp_ops.get_audio_edid_blk( -- GitLab From b6556116f91f961f49ec889884c970cd82a61016 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 5 Sep 2019 20:37:05 +0530 Subject: [PATCH 1183/1645] asoc: Fix out of bounds access in xt logging disable functions Extract dai data from codec dma dai instead of generic dma dai structure in xt logging disable get and put functions to fix out of bounds access. Use separate callback functions for slimbus and codec dma dais. Change-Id: Ic72640518cb255fa09563e99576d508c7cc21a7b Signed-off-by: Aditya Bavanari --- asoc/msm-dai-q6-v2.c | 53 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index ab3445abd5c7..d0d348071ad7 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -282,6 +282,7 @@ struct msm_dai_q6_cdc_dma_dai_data { u32 channels; u32 bitwidth; u32 is_island_dai; + u32 xt_logging_disable; union afe_port_config port_config; }; @@ -2844,24 +2845,54 @@ static int msm_dai_q6_cal_info_get(struct snd_kcontrol *kcontrol, return 0; } -static int msm_dai_q6_xt_logging_disable_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int msm_dai_q6_cdc_dma_xt_logging_disable_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_cdc_dma_dai_data *dai_data = kcontrol->private_data; + + if (dai_data) { + dai_data->xt_logging_disable = ucontrol->value.integer.value[0]; + pr_debug("%s: setting xt logging disable to %d\n", + __func__, dai_data->xt_logging_disable); + } + + return 0; +} + +static int msm_dai_q6_cdc_dma_xt_logging_disable_get( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_cdc_dma_dai_data *dai_data = kcontrol->private_data; + + if (dai_data) + ucontrol->value.integer.value[0] = dai_data->xt_logging_disable; + return 0; +} + +static int msm_dai_q6_sb_xt_logging_disable_put( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; - dai_data->xt_logging_disable = ucontrol->value.integer.value[0]; - pr_debug("%s: setting xt logging disable to %d\n", - __func__, dai_data->xt_logging_disable); + if (dai_data) { + dai_data->xt_logging_disable = ucontrol->value.integer.value[0]; + pr_debug("%s: setting xt logging disable to %d\n", + __func__, dai_data->xt_logging_disable); + } return 0; } -static int msm_dai_q6_xt_logging_disable_get(struct snd_kcontrol *kcontrol, +static int msm_dai_q6_sb_xt_logging_disable_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; - ucontrol->value.integer.value[0] = dai_data->xt_logging_disable; + if (dai_data) + ucontrol->value.integer.value[0] = dai_data->xt_logging_disable; return 0; } @@ -3726,8 +3757,8 @@ static const struct snd_kcontrol_new sb_config_controls[] = { msm_dai_q6_sb_format_get, msm_dai_q6_sb_format_put), SOC_ENUM_EXT("SLIM_0_RX XTLoggingDisable", xt_logging_disable_enum[0], - msm_dai_q6_xt_logging_disable_get, - msm_dai_q6_xt_logging_disable_put), + msm_dai_q6_sb_xt_logging_disable_get, + msm_dai_q6_sb_xt_logging_disable_put), }; static const struct snd_kcontrol_new rt_proxy_config_controls[] = { @@ -11995,8 +12026,8 @@ static const struct snd_kcontrol_new cdc_dma_config_controls[] = { msm_dai_q6_cdc_dma_format_put), SOC_ENUM_EXT("WSA_CDC_DMA_0 RX XTLoggingDisable", xt_logging_disable_enum[0], - msm_dai_q6_xt_logging_disable_get, - msm_dai_q6_xt_logging_disable_put), + msm_dai_q6_cdc_dma_xt_logging_disable_get, + msm_dai_q6_cdc_dma_xt_logging_disable_put), }; /* SOC probe for codec DMA interface */ -- GitLab From 8ebb07308a3215268f6074e382c608ff37d61dd2 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 3 Sep 2019 14:11:25 +0530 Subject: [PATCH 1184/1645] asoc: codecs: wcd938x: Enable EAR over INT2 chain INT2 chain drives AUX output to WCD. EAR DAC on WCD can take input from HPHL/AUX chains. Add register sequence updates to support EAR DAC over AUX chain path also based on mixer setting. Change-Id: I71db6c02f4579e3beba2816c1cfa5a492d91d702 Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd938x/wcd938x.c | 43 ++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index f89a2aaf5601..d008973d133b 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -548,12 +548,26 @@ static int wcd938x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: wcd938x_rx_clk_enable(component); - snd_soc_component_update_bits(component, + wcd938x->ear_rx_path = + snd_soc_component_read32( + component, WCD938X_DIGITAL_CDC_EAR_PATH_CTL); + if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) { + snd_soc_component_update_bits(component, + WCD938X_EAR_EAR_DAC_CON, 0x80, 0x00); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_AUX_GAIN_CTL, 0x01, 0x01); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x04, 0x04); + snd_soc_component_update_bits(component, + WCD938X_ANA_EAR_COMPANDER_CTL, 0x80, 0x80); + } else { + snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_HPH_GAIN_CTL, 0x04, 0x04); - snd_soc_component_update_bits(component, + snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x01); - snd_soc_component_update_bits(component, + snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x02); + } /* 5 msec delay as per HW requirement */ usleep_range(5000, 5010); if (wcd938x->flyback_cur_det_disable == 0) @@ -567,6 +581,14 @@ static int wcd938x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, wcd938x->hph_mode); break; case SND_SOC_DAPM_POST_PMD: + if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) { + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_AUX_GAIN_CTL, 0x01, 0x00); + } + snd_soc_component_update_bits(component, + WCD938X_ANA_EAR_COMPANDER_CTL, 0x80, 0x00); + snd_soc_component_update_bits(component, + WCD938X_EAR_EAR_DAC_CON, 0x80, 0x80); break; }; return 0; @@ -967,16 +989,21 @@ static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD938X_ANA_RX_SUPPLIES, 0x02, 0x02); - if (wcd938x->update_wcd_event) - wcd938x->update_wcd_event(wcd938x->handle, + if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) { + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_MUTE, - (WCD_RX1 << 0x10)); - if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) + (WCD_RX3 << 0x10)); wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT); - else + } else { + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10)); wcd_enable_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHL_PDM_WD_INT); + } break; case SND_SOC_DAPM_PRE_PMD: if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) -- GitLab From c893cd2e0d77b6b24f57dbf4d79b5ad521975f50 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 9 Sep 2019 09:27:45 +0800 Subject: [PATCH 1185/1645] dsp: lsm: add apr NULL check in apr deregister During SSR, q6lsm_mmapcallback could happen before q6lsm_mmap_apr_dereg. q6lsm_common.apr and q6lsm_common.apr_users are cleared in q6lsm_mmapcallback. Add apr NULL check in q6lsm_mmap_apr_dereg before accessing q6lsm_common.apr_users. Change-Id: Ia0ff57b3fff0a0e4f26b836a8a15324406af1a14 Signed-off-by: Meng Wang --- dsp/q6lsm.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index d27bbac68e88..07f47e519a6d 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -285,12 +285,15 @@ static void *q6lsm_mmap_apr_reg(void) static int q6lsm_mmap_apr_dereg(void) { - if (atomic_read(&lsm_common.apr_users) <= 0) { - WARN("%s: APR common port already closed\n", __func__); - } else { - if (atomic_dec_return(&lsm_common.apr_users) == 0) { - apr_deregister(lsm_common.apr); - pr_debug("%s: APR De-Register common port\n", __func__); + if (lsm_common.apr) { + if (atomic_read(&lsm_common.apr_users) <= 0) { + WARN("%s: APR common port already closed\n", __func__); + } else { + if (atomic_dec_return(&lsm_common.apr_users) == 0) { + apr_deregister(lsm_common.apr); + pr_debug("%s: APR De-Register common port\n", + __func__); + } } } return 0; -- GitLab From f8adb5f3c3e243d6feedf7ae36e5e698f65282cd Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 9 Aug 2019 21:47:33 +0530 Subject: [PATCH 1186/1645] asoc: codecs: bolero: Update mixing path and channel mask for RX path RX_CDC_DMA_RX0/1/2/3 ports drives RX0/RX1, RX2/RX3, RX4 and RX5 channels on bolero rx-macro. Update channel mask as per these mapping and return to channel map accordingly. Change-Id: I2e66e601b5137ebc513527827332bbb7cde0acb3 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 32 +++++++++++++++++++++++----- asoc/codecs/bolero/wsa-macro.c | 39 +++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 98754bf91820..d3370f04329e 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -849,9 +849,9 @@ static int rx_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, inp0_sel = int_mux_cfg0_val & 0x0F; inp1_sel = (int_mux_cfg0_val >> 4) & 0x0F; inp2_sel = (int_mux_cfg1_val >> 4) & 0x0F; - if ((inp0_sel == int_1_mix1_inp) || - (inp1_sel == int_1_mix1_inp) || - (inp2_sel == int_1_mix1_inp)) { + if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || + (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || + (inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) { int_fs_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + 0x80 * j; pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_1\n", @@ -900,7 +900,8 @@ static int rx_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, int_mux_cfg1_val = snd_soc_component_read32( component, int_mux_cfg1) & 0x0F; - if (int_mux_cfg1_val == int_2_inp) { + if (int_mux_cfg1_val == int_2_inp + + INTn_2_INP_SEL_RX0) { int_fs_reg = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL + 0x80 * j; pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_2\n", @@ -1028,8 +1029,26 @@ static int rx_macro_get_channel_map(struct snd_soc_dai *dai, if (++i == RX_MACRO_MAX_DMA_CH_PER_PORT) break; } + /* + * CDC_DMA_RX_0 port drives RX0/RX1 -- ch_mask 0x1/0x2/0x3 + * CDC_DMA_RX_1 port drives RX2/RX3 -- ch_mask 0x1/0x2/0x3 + * CDC_DMA_RX_2 port drives RX4 -- ch_mask 0x1 + * CDC_DMA_RX_3 port drives RX5 -- ch_mask 0x1 + * AIFn can pair to any CDC_DMA_RX_n port. + * In general, below convention is used:: + * CDC_DMA_RX_0(AIF1)/CDC_DMA_RX_1(AIF2)/ + * CDC_DMA_RX_2(AIF3)/CDC_DMA_RX_3(AIF4) + * Above is reflected in machine driver BE dailink + */ + if (ch_mask & 0x0C) + ch_mask = ch_mask >> 2; + if ((ch_mask & 0x10) || (ch_mask & 0x20)) + ch_mask = 0x1; *rx_slot = ch_mask; *rx_num = rx_priv->active_ch_cnt[dai->id]; + dev_dbg(rx_priv->dev, + "%s: dai->id:%d, ch_mask:0x%x, active_ch_cnt:%d active_mask: 0x%x\n", + __func__, dai->id, *rx_slot, *rx_num, rx_priv->active_ch_mask[dai->id]); break; case RX_MACRO_AIF_ECHO: val = snd_soc_component_read32(component, @@ -1097,9 +1116,12 @@ static int rx_macro_digital_mute(struct snd_soc_dai *dai, int mute) if (int_mux_cfg0_val || (int_mux_cfg1_val & 0xF0)) snd_soc_component_update_bits(component, reg, 0x20, 0x20); - if (int_mux_cfg1_val & 0x0F) + if (int_mux_cfg1_val & 0x0F) { + snd_soc_component_update_bits(component, + reg, 0x20, 0x20); snd_soc_component_update_bits(component, mix_reg, 0x20, 0x20); + } } } break; diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 623b64b0e5ec..39f331b04c0c 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -54,6 +54,7 @@ #define WSA_MACRO_EC_MIX_TX0_MASK 0x03 #define WSA_MACRO_EC_MIX_TX1_MASK 0x18 +#define WSA_MACRO_MAX_DMA_CH_PER_PORT 0x2 enum { WSA_MACRO_RX0 = 0, @@ -98,6 +99,14 @@ enum { INTn_1_INP_SEL_DEC1, }; +enum { + INTn_2_INP_SEL_ZERO = 0, + INTn_2_INP_SEL_RX0, + INTn_2_INP_SEL_RX1, + INTn_2_INP_SEL_RX2, + INTn_2_INP_SEL_RX3, +}; + struct interp_sample_rate { int sample_rate; int rate_val; @@ -614,9 +623,9 @@ static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, inp2_sel = (int_mux_cfg1_val >> WSA_MACRO_MUX_INP_SHFT) & WSA_MACRO_MUX_INP_MASK2; - if ((inp0_sel == int_1_mix1_inp) || - (inp1_sel == int_1_mix1_inp) || - (inp2_sel == int_1_mix1_inp)) { + if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || + (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || + (inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) { int_fs_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL + WSA_MACRO_RX_PATH_OFFSET * j; dev_dbg(wsa_dev, @@ -670,7 +679,8 @@ static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, int_mux_cfg1_val = snd_soc_component_read32(component, int_mux_cfg1) & WSA_MACRO_MUX_INP_MASK1; - if (int_mux_cfg1_val == int_2_inp) { + if (int_mux_cfg1_val == int_2_inp + + INTn_2_INP_SEL_RX0) { int_fs_reg = BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL + WSA_MACRO_RX_PATH_OFFSET * j; @@ -766,7 +776,7 @@ static int wsa_macro_get_channel_map(struct snd_soc_dai *dai, struct snd_soc_component *component = dai->component; struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; - u16 val = 0, mask = 0, cnt = 0; + u16 val = 0, mask = 0, cnt = 0, temp = 0; if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; @@ -782,8 +792,16 @@ static int wsa_macro_get_channel_map(struct snd_soc_dai *dai, break; case WSA_MACRO_AIF1_PB: case WSA_MACRO_AIF_MIX1_PB: - *rx_slot = wsa_priv->active_ch_mask[dai->id]; - *rx_num = wsa_priv->active_ch_cnt[dai->id]; + for_each_set_bit(temp, &wsa_priv->active_ch_mask[dai->id], + WSA_MACRO_RX_MAX) { + mask |= (1 << temp); + if (++cnt == WSA_MACRO_MAX_DMA_CH_PER_PORT) + break; + } + if (mask & 0x0C) + mask = mask >> 0x2; + *rx_slot = mask; + *rx_num = cnt; break; case WSA_MACRO_AIF_ECHO: val = snd_soc_component_read32(component, @@ -842,9 +860,12 @@ static int wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute) if (int_mux_cfg0_val || (int_mux_cfg1_val & 0x38)) snd_soc_component_update_bits(component, reg, 0x20, 0x20); - if (int_mux_cfg1_val & 0x07) + if (int_mux_cfg1_val & 0x07) { + snd_soc_component_update_bits(component, reg, + 0x20, 0x20); snd_soc_component_update_bits(component, mix_reg, 0x20, 0x20); + } } } break; @@ -2179,8 +2200,6 @@ static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol, wsa_priv->rx_port_value[widget->shift] = rx_port_value; bit_input = widget->shift; - if (widget->shift >= WSA_MACRO_RX_MIX) - bit_input %= WSA_MACRO_RX_MIX; dev_dbg(wsa_dev, "%s: mux input: %d, mux output: %d, bit: %d\n", -- GitLab From b44e4551b11908f4d109745ba41aa44a56c0bd17 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 9 Sep 2019 23:06:04 -0700 Subject: [PATCH 1187/1645] asoc: codecs: bolero: Do not return error for unused gpio If soundwire gpio is not used, then no need to return error if not able to get gpio data. Change-Id: I97705b49d3b01f99b7a4e91190a15ffb211d32f2 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/rx-macro.c | 3 ++- asoc/codecs/bolero/tx-macro.c | 3 ++- asoc/codecs/bolero/wsa-macro.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 52598ef704a6..cc80adfe8bba 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -3763,7 +3763,8 @@ static int rx_macro_probe(struct platform_device *pdev) __func__); return -EINVAL; } - if (msm_cdc_pinctrl_get_state(rx_priv->rx_swr_gpio_p) < 0) { + if (msm_cdc_pinctrl_get_state(rx_priv->rx_swr_gpio_p) < 0 && + is_used_rx_swr_gpio) { dev_err(&pdev->dev, "%s: failed to get swr pin state\n", __func__); return -EPROBE_DEFER; diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 8c32043c479e..ba93c5ed53eb 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -2299,7 +2299,8 @@ static int tx_macro_probe(struct platform_device *pdev) __func__); return -EINVAL; } - if (msm_cdc_pinctrl_get_state(tx_priv->tx_swr_gpio_p) < 0) { + if (msm_cdc_pinctrl_get_state(tx_priv->tx_swr_gpio_p) < 0 && + is_used_tx_swr_gpio) { dev_err(&pdev->dev, "%s: failed to get swr pin state\n", __func__); return -EPROBE_DEFER; diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index dd12ad237362..a1dcdda41e08 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -2957,7 +2957,8 @@ static int wsa_macro_probe(struct platform_device *pdev) __func__); return -EINVAL; } - if (msm_cdc_pinctrl_get_state(wsa_priv->wsa_swr_gpio_p) < 0) { + if (msm_cdc_pinctrl_get_state(wsa_priv->wsa_swr_gpio_p) < 0 && + is_used_wsa_swr_gpio) { dev_err(&pdev->dev, "%s: failed to get swr pin state\n", __func__); return -EPROBE_DEFER; -- GitLab From 9e4d72554ae3d653a0b13bee99ffab9cc826018d Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 10 Sep 2019 15:13:39 -0700 Subject: [PATCH 1188/1645] asoc: msm: Add support for updated tdm slot map cfg version Slot map of tdm now has multiple versions and they need to be supported to configure the afe parameters as per the version used. Change-Id: I63490e08afcf17444fd884e08f771a7dcf108c66 Signed-off-by: Karthikeyan Mani --- asoc/msm-dai-q6-v2.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 3fcd9795acaf..8e2fcb4ff4b2 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -8541,19 +8541,24 @@ static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai, } static unsigned int tdm_param_set_slot_mask(u16 *slot_offset, int slot_width, - int slots_per_frame) + int slots_per_frame) { unsigned int i = 0; unsigned int slot_index = 0; unsigned long slot_mask = 0; unsigned int slot_width_bytes = slot_width / 8; + unsigned int channel_count = AFE_PORT_MAX_AUDIO_CHAN_CNT; + + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V3) + channel_count = AFE_PORT_MAX_AUDIO_CHAN_CNT_V2; if (slot_width_bytes == 0) { pr_err("%s: slot width is zero\n", __func__); return slot_mask; } - for (i = 0; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++) { + for (i = 0; i < channel_count; i++) { if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) { slot_index = slot_offset[i] / slot_width_bytes; if (slot_index < slots_per_frame) @@ -8675,9 +8680,16 @@ static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream, */ tdm->nslots_per_frame = tdm_group->nslots_per_frame; tdm->slot_width = tdm_group->slot_width; - tdm->slot_mask = tdm_param_set_slot_mask(slot_mapping->offset, - tdm_group->slot_width, - tdm_group->nslots_per_frame); + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V3) + tdm->slot_mask = tdm_param_set_slot_mask( + slot_mapping_v2->offset, + tdm_group->slot_width, + tdm_group->nslots_per_frame); + else + tdm->slot_mask = tdm_param_set_slot_mask(slot_mapping->offset, + tdm_group->slot_width, + tdm_group->nslots_per_frame); pr_debug("%s: TDM:\n" "num_channels=%d sample_rate=%d bit_width=%d\n" -- GitLab From 925413eba524b456b6ea6910a225566f6b4cc68b Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 10 Sep 2019 16:57:28 -0700 Subject: [PATCH 1189/1645] asoc: msm: Add primary tdm tx line in echo reference Add primary tdm interface in echo reference list so that it can be used for any echo reference use case. Change-Id: Id1621240fc28e0e1b505f5e46c426df0b91c416e Signed-off-by: Karthikeyan Mani --- asoc/msm-pcm-routing-v2.c | 7 ++++++- asoc/msm-pcm-routing-v2.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index f5e9896795a6..2d525eda6c4a 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -5682,6 +5682,9 @@ static int msm_routing_ext_ec_put(struct snd_kcontrol *kcontrol, case EXT_EC_REF_SLIM_1_TX: ext_ec_ref_port_id = SLIMBUS_1_TX; break; + case EXT_EC_REF_PRI_TDM_TX: + ext_ec_ref_port_id = AFE_PORT_ID_PRIMARY_TDM_TX; + break; case EXT_EC_REF_SEC_TDM_TX: ext_ec_ref_port_id = AFE_PORT_ID_SECONDARY_TDM_TX; break; @@ -5709,7 +5712,8 @@ static int msm_routing_ext_ec_put(struct snd_kcontrol *kcontrol, static const char * const ext_ec_ref_rx[] = {"NONE", "PRI_MI2S_TX", "SEC_MI2S_TX", "TERT_MI2S_TX", "QUAT_MI2S_TX", "QUIN_MI2S_TX", - "SLIM_1_TX", "SEC_TDM_TX"}; + "SLIM_1_TX", "PRI_TDM_TX", + "SEC_TDM_TX"}; static const struct soc_enum msm_route_ext_ec_ref_rx_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ext_ec_ref_rx), ext_ec_ref_rx), @@ -26709,6 +26713,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VOC_EXT_EC MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"VOC_EXT_EC MUX", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"VOC_EXT_EC MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"VOC_EXT_EC MUX", "PRI_TDM_TX", "PRI_TDM_TX_0"}, {"VOC_EXT_EC MUX", "SEC_TDM_TX", "SEC_TDM_TX_0"}, {"VOIP_UL", NULL, "VOC_EXT_EC MUX"}, {"VOICEMMODE1_UL", NULL, "VOC_EXT_EC MUX"}, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index aca00bbfccfd..8003d913f4f6 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -516,6 +516,7 @@ enum { EXT_EC_REF_QUAT_MI2S_TX, EXT_EC_REF_QUIN_MI2S_TX, EXT_EC_REF_SLIM_1_TX, + EXT_EC_REF_PRI_TDM_TX, EXT_EC_REF_SEC_TDM_TX, }; -- GitLab From cd339694c5d9e720d73cecd057837b0a3a497b62 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 11 Sep 2019 12:17:11 +0530 Subject: [PATCH 1190/1645] ASoC: wcd-mbhc: Remove max impedance limit for lineout detection Max limit of 60k ohms was set for cable to be detected as lineout to fix headset detected as lineout issue on legacy targets. This was because of large impedance detected for headset. This is not applicable for adc based targets as headset is detected based on mic adc voltage. Remove max impedance limit for lineout detection. Change-Id: If73bbe2cd78d04d1fcb359a3e5ed5cd69f3ab9f0 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd-mbhc-v2.c | 6 ++---- include/asoc/wcd-mbhc-v2.h | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 624b59af069e..01544aab9c43 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -691,10 +691,8 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, &mbhc->zl, &mbhc->zr); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, fsm_en); - if ((mbhc->zl > mbhc->mbhc_cfg->linein_th && - mbhc->zl < MAX_IMPED) && - (mbhc->zr > mbhc->mbhc_cfg->linein_th && - mbhc->zr < MAX_IMPED) && + if ((mbhc->zl > mbhc->mbhc_cfg->linein_th) && + (mbhc->zr > mbhc->mbhc_cfg->linein_th) && (jack_type == SND_JACK_HEADPHONE)) { jack_type = SND_JACK_LINEOUT; mbhc->force_linein = true; diff --git a/include/asoc/wcd-mbhc-v2.h b/include/asoc/wcd-mbhc-v2.h index 9341e3d3c784..1f9d64e3ba23 100644 --- a/include/asoc/wcd-mbhc-v2.h +++ b/include/asoc/wcd-mbhc-v2.h @@ -140,7 +140,6 @@ do { \ #define FW_READ_ATTEMPTS 15 #define FW_READ_TIMEOUT 4000000 #define FAKE_REM_RETRY_ATTEMPTS 3 -#define MAX_IMPED 60000 #define WCD_MBHC_BTN_PRESS_COMPL_TIMEOUT_MS 50 #define ANC_DETECT_RETRY_CNT 7 -- GitLab From 8d40a0634791a896592bca13b31ee12709c096c7 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 5 Sep 2019 16:44:49 -0700 Subject: [PATCH 1191/1645] asoc: codecs: Add core vote functionality for soundwire Add callback to vote for core votes that the soundwire master can use while doing a clock request. Check for pinctrl function errors and in case of any failures return from clock enable with an error. Change-Id: Ic5c200d7179a1e3a9695955d8711358cd7618bd1 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/rx-macro.c | 39 +++++++++++++++++++++++-- asoc/codecs/bolero/tx-macro.c | 53 ++++++++++++++++++++++++++++++---- asoc/codecs/bolero/wsa-macro.c | 42 +++++++++++++++++++++++++-- 3 files changed, 123 insertions(+), 11 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 9ac846f45922..ead897129d41 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -372,6 +372,7 @@ struct rx_swr_ctrl_platform_data { int (*write)(void *handle, int reg, int val); int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); int (*clk)(void *handle, bool enable); + int (*core_vote)(void *handle, bool enable); int (*handle_irq)(void *handle, irqreturn_t (*swrm_irq_handler)(int irq, void *data), @@ -3462,6 +3463,23 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { {"RX INT2 MIX2 INP", "SRC1", "SRC1"}, }; +static int rx_macro_core_vote(void *handle, bool enable) +{ + struct rx_macro_priv *rx_priv = (struct rx_macro_priv *) handle; + + if (rx_priv == NULL) { + pr_err("%s: rx priv data is NULL\n", __func__); + return -EINVAL; + } + if (enable) { + pm_runtime_get_sync(rx_priv->dev); + pm_runtime_put_autosuspend(rx_priv->dev); + pm_runtime_mark_last_busy(rx_priv->dev); + } + + return 0; +} + static int rx_swrm_clock(void *handle, bool enable) { struct rx_macro_priv *rx_priv = (struct rx_macro_priv *) handle; @@ -3480,8 +3498,16 @@ static int rx_swrm_clock(void *handle, bool enable) if (enable) { pm_runtime_get_sync(rx_priv->dev); if (rx_priv->swr_clk_users == 0) { - msm_cdc_pinctrl_select_active_state( + ret = msm_cdc_pinctrl_select_active_state( rx_priv->rx_swr_gpio_p); + if (ret < 0) { + dev_err(rx_priv->dev, + "%s: rx swr pinctrl enable failed\n", + __func__); + pm_runtime_mark_last_busy(rx_priv->dev); + pm_runtime_put_autosuspend(rx_priv->dev); + goto exit; + } ret = rx_macro_mclk_enable(rx_priv, 1, true); if (ret < 0) { msm_cdc_pinctrl_select_sleep_state( @@ -3489,6 +3515,8 @@ static int rx_swrm_clock(void *handle, bool enable) dev_err(rx_priv->dev, "%s: rx request clock enable failed\n", __func__); + pm_runtime_mark_last_busy(rx_priv->dev); + pm_runtime_put_autosuspend(rx_priv->dev); goto exit; } if (rx_priv->reset_swr) @@ -3521,8 +3549,14 @@ static int rx_swrm_clock(void *handle, bool enable) BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x00); rx_macro_mclk_enable(rx_priv, 0, true); - msm_cdc_pinctrl_select_sleep_state( + ret = msm_cdc_pinctrl_select_sleep_state( rx_priv->rx_swr_gpio_p); + if (ret < 0) { + dev_err(rx_priv->dev, + "%s: rx swr pinctrl disable failed\n", + __func__); + goto exit; + } } } dev_dbg(rx_priv->dev, "%s: swrm clock users %d\n", @@ -3873,6 +3907,7 @@ static int rx_macro_probe(struct platform_device *pdev) rx_priv->swr_plat_data.write = NULL; rx_priv->swr_plat_data.bulk_write = NULL; rx_priv->swr_plat_data.clk = rx_swrm_clock; + rx_priv->swr_plat_data.core_vote = rx_macro_core_vote; rx_priv->swr_plat_data.handle_irq = NULL; ret = of_property_read_u8_array(pdev->dev.of_node, diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 8c32043c479e..9dcb7f082df5 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -72,6 +72,7 @@ struct tx_macro_swr_ctrl_platform_data { int (*write)(void *handle, int reg, int val); int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); int (*clk)(void *handle, bool enable); + int (*core_vote)(void *handle, bool enable); int (*handle_irq)(void *handle, irqreturn_t (*swrm_irq_handler)(int irq, void *data), @@ -1726,9 +1727,16 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, (enable ? "enable" : "disable"), tx_priv->tx_mclk_users); if (enable) { - if (tx_priv->swr_clk_users == 0) - msm_cdc_pinctrl_select_active_state( + if (tx_priv->swr_clk_users == 0) { + ret = msm_cdc_pinctrl_select_active_state( tx_priv->tx_swr_gpio_p); + if (ret < 0) { + dev_err_ratelimited(tx_priv->dev, + "%s: tx swr pinctrl enable failed\n", + __func__); + goto exit; + } + } clk_tx_ret = bolero_clk_rsc_request_clock(tx_priv->dev, TX_CORE_CLK, @@ -1841,9 +1849,16 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, TX_CORE_CLK, TX_CORE_CLK, false); - if (tx_priv->swr_clk_users == 0) - msm_cdc_pinctrl_select_sleep_state( + if (tx_priv->swr_clk_users == 0) { + ret = msm_cdc_pinctrl_select_sleep_state( tx_priv->tx_swr_gpio_p); + if (ret < 0) { + dev_err_ratelimited(tx_priv->dev, + "%s: tx swr pinctrl disable failed\n", + __func__); + goto exit; + } + } } return 0; @@ -1853,6 +1868,7 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, TX_CORE_CLK, TX_CORE_CLK, false); +exit: return ret; } @@ -1886,6 +1902,24 @@ static int tx_macro_clk_switch(struct snd_soc_component *component) return ret; } +static int tx_macro_core_vote(void *handle, bool enable) +{ + struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle; + int ret = 0; + + if (tx_priv == NULL) { + pr_err("%s: tx priv data is NULL\n", __func__); + return -EINVAL; + } + if (enable) { + pm_runtime_get_sync(tx_priv->dev); + pm_runtime_put_autosuspend(tx_priv->dev); + pm_runtime_mark_last_busy(tx_priv->dev); + } + + return ret; +} + static int tx_macro_swrm_clock(void *handle, bool enable) { struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle; @@ -1908,14 +1942,20 @@ static int tx_macro_swrm_clock(void *handle, bool enable) if (tx_priv->va_swr_clk_cnt && !tx_priv->tx_swr_clk_cnt) { ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap, VA_MCLK, enable); - if (ret) + if (ret) { + pm_runtime_mark_last_busy(tx_priv->dev); + pm_runtime_put_autosuspend(tx_priv->dev); goto done; + } tx_priv->va_clk_status++; } else { ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap, TX_MCLK, enable); - if (ret) + if (ret) { + pm_runtime_mark_last_busy(tx_priv->dev); + pm_runtime_put_autosuspend(tx_priv->dev); goto done; + } tx_priv->tx_clk_status++; } pm_runtime_mark_last_busy(tx_priv->dev); @@ -2332,6 +2372,7 @@ static int tx_macro_probe(struct platform_device *pdev) tx_priv->swr_plat_data.write = NULL; tx_priv->swr_plat_data.bulk_write = NULL; tx_priv->swr_plat_data.clk = tx_macro_swrm_clock; + tx_priv->swr_plat_data.core_vote = tx_macro_core_vote; tx_priv->swr_plat_data.handle_irq = NULL; mutex_init(&tx_priv->mclk_lock); diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 623b64b0e5ec..4747a9678599 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -151,6 +151,7 @@ struct wsa_macro_swr_ctrl_platform_data { int (*write)(void *handle, int reg, int val); int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); int (*clk)(void *handle, bool enable); + int (*core_vote)(void *handle, bool enable); int (*handle_irq)(void *handle, irqreturn_t (*swrm_irq_handler)(int irq, void *data), @@ -2770,6 +2771,24 @@ static void wsa_macro_init_reg(struct snd_soc_component *component) wsa_macro_init_bcl_pmic_reg(component); } +static int wsa_macro_core_vote(void *handle, bool enable) +{ + struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle; + int ret = 0; + + if (wsa_priv == NULL) { + pr_err("%s: wsa priv data is NULL\n", __func__); + return -EINVAL; + } + if (enable) { + pm_runtime_get_sync(wsa_priv->dev); + pm_runtime_put_autosuspend(wsa_priv->dev); + pm_runtime_mark_last_busy(wsa_priv->dev); + } + + return ret; +} + static int wsa_swrm_clock(void *handle, bool enable) { struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle; @@ -2788,8 +2807,16 @@ static int wsa_swrm_clock(void *handle, bool enable) if (enable) { pm_runtime_get_sync(wsa_priv->dev); if (wsa_priv->swr_clk_users == 0) { - msm_cdc_pinctrl_select_active_state( + ret = msm_cdc_pinctrl_select_active_state( wsa_priv->wsa_swr_gpio_p); + if (ret < 0) { + dev_err_ratelimited(wsa_priv->dev, + "%s: wsa swr pinctrl enable failed\n", + __func__); + pm_runtime_mark_last_busy(wsa_priv->dev); + pm_runtime_put_autosuspend(wsa_priv->dev); + goto exit; + } ret = wsa_macro_mclk_enable(wsa_priv, 1, true); if (ret < 0) { msm_cdc_pinctrl_select_sleep_state( @@ -2797,6 +2824,8 @@ static int wsa_swrm_clock(void *handle, bool enable) dev_err_ratelimited(wsa_priv->dev, "%s: wsa request clock enable failed\n", __func__); + pm_runtime_mark_last_busy(wsa_priv->dev); + pm_runtime_put_autosuspend(wsa_priv->dev); goto exit; } if (wsa_priv->reset_swr) @@ -2812,9 +2841,9 @@ static int wsa_swrm_clock(void *handle, bool enable) 0x02, 0x00); wsa_priv->reset_swr = false; } + wsa_priv->swr_clk_users++; pm_runtime_mark_last_busy(wsa_priv->dev); pm_runtime_put_autosuspend(wsa_priv->dev); - wsa_priv->swr_clk_users++; } else { if (wsa_priv->swr_clk_users <= 0) { dev_err(wsa_priv->dev, "%s: clock already disabled\n", @@ -2828,8 +2857,14 @@ static int wsa_swrm_clock(void *handle, bool enable) BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x00); wsa_macro_mclk_enable(wsa_priv, 0, true); - msm_cdc_pinctrl_select_sleep_state( + ret = msm_cdc_pinctrl_select_sleep_state( wsa_priv->wsa_swr_gpio_p); + if (ret < 0) { + dev_err_ratelimited(wsa_priv->dev, + "%s: wsa swr pinctrl disable failed\n", + __func__); + goto exit; + } } } dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n", @@ -3096,6 +3131,7 @@ static int wsa_macro_probe(struct platform_device *pdev) wsa_priv->swr_plat_data.write = NULL; wsa_priv->swr_plat_data.bulk_write = NULL; wsa_priv->swr_plat_data.clk = wsa_swrm_clock; + wsa_priv->swr_plat_data.core_vote = wsa_macro_core_vote; wsa_priv->swr_plat_data.handle_irq = NULL; ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id", -- GitLab From 1d750fe50f8cb12a7a5e5aeeea84a5bda6fbf5e0 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 6 Sep 2019 14:36:09 -0700 Subject: [PATCH 1192/1645] soc: swr-mstr: Vote for core vote before clock request For soundwire devices, if core vote function is available, do a core vote before doing a clock request. This way we retain any hardware votes needed before doing a read or write. Change-Id: If29b5f102be4f2d60e6d71cae70ac43e3fdaa00c Signed-off-by: Karthikeyan Mani --- soc/swr-mstr-ctrl.c | 17 ++++++++++++++++- soc/swr-mstr-ctrl.h | 2 ++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 9ad849e866d0..bd4f56acc8e2 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -301,6 +301,15 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) ret = -ENODEV; goto exit; } + if (swrm->core_vote) { + ret = swrm->core_vote(swrm->handle, true); + if (ret) { + dev_err_ratelimited(swrm->dev, + "%s: clock enable req failed", + __func__); + goto exit; + } + } swrm->clk_ref_count++; if (swrm->clk_ref_count == 1) { ret = swrm->clk(swrm->handle, true); @@ -2123,6 +2132,7 @@ static int swrm_probe(struct platform_device *pdev) swrm->swrm_base_reg, SWRM_MAX_REGISTER); } + swrm->core_vote = pdata->core_vote; swrm->clk = pdata->clk; if (!swrm->clk) { dev_err(&pdev->dev, "%s: swrm->clk is NULL\n", @@ -2584,7 +2594,12 @@ static int swrm_runtime_suspend(struct device *dev) mutex_lock(&swrm->reslock); usleep_range(100, 105); } - swrm_clk_request(swrm, false); + ret = swrm_clk_request(swrm, false); + if (ret) { + dev_err(dev, "%s: swrmn clk failed\n", __func__); + ret = 0; + goto exit; + } if (swrm->clk_stop_mode0_supp) { if (swrm->wake_irq > 0) { diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index e05ede258dc9..24bca1b047c7 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -91,6 +91,7 @@ struct swr_ctrl_platform_data { int (*write)(void *handle, int reg, int val); int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); int (*clk)(void *handle, bool enable); + int (*core_vote)(void *handle, bool enable); int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq, void *data), void *swr_handle, int type); }; @@ -120,6 +121,7 @@ struct swr_mstr_ctrl { int (*write)(void *handle, int reg, int val); int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); int (*clk)(void *handle, bool enable); + int (*core_vote)(void *handle, bool enable); int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq, void *data), void *swr_handle, int type); int irq; -- GitLab From 5f59d6c904451c573624166d5594bfeb99dfd363 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 6 Sep 2019 14:44:53 -0700 Subject: [PATCH 1193/1645] soc: pinctrl-lpi: Suspend sooner if resume fails If PM runtime resume fails, hardware vote will not happen until it is suspended. So in error scenarios set for a lesser suspend delay so that voting can happen sooner. Change-Id: Ia4175535e45ec291292b8d8656146826ffd05a26 Signed-off-by: Karthikeyan Mani --- soc/pinctrl-lpi.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index 157e2c54a17b..3aff320ceea1 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -23,6 +23,7 @@ #include "pinctrl-utils.h" #define LPI_AUTO_SUSPEND_DELAY 100 /* delay in msec */ +#define LPI_AUTO_SUSPEND_DELAY_ERROR 1 /* delay in msec */ #define LPI_ADDRESS_SIZE 0x20000 #define LPI_SLEW_ADDRESS_SIZE 0x1000 @@ -824,13 +825,19 @@ int lpi_pinctrl_runtime_resume(struct device *dev) mutex_lock(&state->core_hw_vote_lock); ret = clk_prepare_enable(state->lpass_core_hw_vote); - if (ret < 0) + if (ret < 0) { + pm_runtime_set_autosuspend_delay(dev, + LPI_AUTO_SUSPEND_DELAY_ERROR); dev_err(dev, "%s:lpass core hw island enable failed\n", __func__); - else + goto exit; + } else { state->core_hw_vote_status = true; + } pm_runtime_set_autosuspend_delay(dev, LPI_AUTO_SUSPEND_DELAY); + +exit: mutex_unlock(&state->core_hw_vote_lock); return 0; } -- GitLab From 1253c36aea0de741d5c76f52e84380b2bfe0f7b7 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 26 Aug 2019 11:17:45 -0700 Subject: [PATCH 1194/1645] asoc: codecs: bolero: Add support to disable aux hpf Add a mixer control which can allow for aux hpf to be either enabled or disabled based on its switch settings. Change-Id: Ie300c89e1e2f3669846d6bab250b7f4da4a7632a Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/rx-macro.c | 79 ++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 9ac846f45922..9a226c38f198 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -446,6 +446,7 @@ struct rx_macro_priv { [RX_MACRO_CHILD_DEVICES_MAX]; int child_count; int is_softclip_on; + int is_aux_hpf_on; int softclip_clk_users; struct rx_macro_bcl_pmic_params bcl_pmic_params; u16 clk_id; @@ -1774,6 +1775,30 @@ static int rx_macro_config_softclip(struct snd_soc_component *component, return 0; } +static int rx_macro_config_aux_hpf(struct snd_soc_component *component, + struct rx_macro_priv *rx_priv, + int event) +{ + dev_dbg(component->dev, "%s: event %d, enabled %d\n", + __func__, event, rx_priv->is_aux_hpf_on); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Update Aux HPF control */ + if (!rx_priv->is_aux_hpf_on) + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX2_RX_PATH_CFG1, 0x04, 0x00); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + /* Reset to default (HPF=ON) */ + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX2_RX_PATH_CFG1, 0x04, 0x04); + } + + return 0; +} + + static inline void rx_macro_enable_clsh_block(struct rx_macro_priv *rx_priv, bool enable) { @@ -2208,6 +2233,45 @@ static int rx_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol, return 0; } +static int rx_macro_aux_hpf_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = rx_priv->is_aux_hpf_on; + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int rx_macro_aux_hpf_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct device *rx_dev = NULL; + struct rx_macro_priv *rx_priv = NULL; + + if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__)) + return -EINVAL; + + rx_priv->is_aux_hpf_on = ucontrol->value.integer.value[0]; + + dev_dbg(component->dev, "%s: aux hpf enable = %d\n", __func__, + rx_priv->is_aux_hpf_on); + + return 0; +} + + static int rx_macro_enable_vbat(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -2455,9 +2519,12 @@ static int rx_macro_enable_interp_clk(struct snd_soc_component *component, interp_idx, event); rx_macro_config_compander(component, rx_priv, interp_idx, event); - if (interp_idx == INTERP_AUX) + if (interp_idx == INTERP_AUX) { rx_macro_config_softclip(component, rx_priv, event); + rx_macro_config_aux_hpf(component, rx_priv, + event); + } rx_macro_config_classh(component, rx_priv, interp_idx, event); } @@ -2490,9 +2557,12 @@ static int rx_macro_enable_interp_clk(struct snd_soc_component *component, interp_idx, event); rx_macro_config_compander(component, rx_priv, interp_idx, event); - if (interp_idx == INTERP_AUX) + if (interp_idx == INTERP_AUX) { rx_macro_config_softclip(component, rx_priv, event); + rx_macro_config_aux_hpf(component, rx_priv, + event); + } rx_macro_hphdelay_lutbypass(component, rx_priv, interp_idx, event); if (rx_priv->hph_hd2_mode) @@ -2884,6 +2954,9 @@ static const struct snd_kcontrol_new rx_macro_snd_controls[] = { SOC_SINGLE_EXT("RX_Softclip Enable", SND_SOC_NOPM, 0, 1, 0, rx_macro_soft_clip_enable_get, rx_macro_soft_clip_enable_put), + SOC_SINGLE_EXT("AUX_HPF Enable", SND_SOC_NOPM, 0, 1, 0, + rx_macro_aux_hpf_mode_get, + rx_macro_aux_hpf_mode_put), SOC_SINGLE_SX_TLV("IIR0 INP0 Volume", BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40, @@ -3891,6 +3964,8 @@ static int rx_macro_probe(struct platform_device *pdev) ops.clk_id_req = rx_priv->clk_id; ops.default_clk_id = default_clk_id; + rx_priv->is_aux_hpf_on = 1; + dev_set_drvdata(&pdev->dev, rx_priv); mutex_init(&rx_priv->mclk_lock); mutex_init(&rx_priv->swr_clk_lock); -- GitLab From 504064bad0af34e65070def9d96b9c3102d03ee4 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 7 Aug 2019 03:19:10 +0530 Subject: [PATCH 1195/1645] ASoC: wcd938x: Update soundwire slave clock rate on WCD938x Update soundwire slave clock rate based on power mode on WCD938x codec for better power numbers. Change-Id: I6719d7eab7562bf4fe45b3e11fbae6e0a629f9b1 Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd938x/internal.h | 2 ++ asoc/codecs/wcd938x/wcd938x.c | 56 ++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index 2c67ff80f6eb..8c2ff0df610b 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -11,6 +11,8 @@ #include #include "wcd938x-mbhc.h" +#define SWR_SCP_CONTROL 0x44 +#define SWR_SCP_HOST_CLK_DIV2_CTL_BANK 0xE0 #define WCD938X_MAX_MICBIAS 4 /* Convert from vout ctl to micbias voltage in mV */ diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 036f97ad8793..dc4a0fb17259 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -25,6 +25,7 @@ #include "wcd938x-registers.h" #include "wcd938x.h" + #define WCD938X_DRV_NAME "wcd938x_codec" #define NUM_SWRS_DT_PARAMS 5 #define WCD938X_VARIANT_ENTRY_SIZE 32 @@ -126,6 +127,45 @@ static int wcd938x_handle_post_irq(void *data) return IRQ_HANDLED; } +static int wcd938x_swr_slv_get_current_bank(struct swr_device *dev, u8 devnum) +{ + int ret = 0; + int bank = 0; + + ret = swr_read(dev, devnum, SWR_SCP_CONTROL, &bank, 1); + if (ret) + return -EINVAL; + + return ((bank & 0x40) ? 1: 0); +} + +static int wcd938x_swr_slv_set_host_clk_div2(struct swr_device *dev, + u8 devnum, int bank) +{ + u8 val = (bank ? 1 : 0); + + return (swr_write(dev, devnum, + (SWR_SCP_HOST_CLK_DIV2_CTL_BANK + (0x10 * bank)), &val)); +} + +static int wcd938x_set_swr_clk_rate(struct snd_soc_component *component, + int mode, int bank) +{ + u8 mask = (bank ? 0xF0 : 0x0F); + u8 val = 0; + + if ((mode == ADC_MODE_ULP1) || (mode == ADC_MODE_ULP2)) + val = (bank ? 0x60 : 0x06); + else + val = 0x00; + + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_SWR_TX_CLK_RATE, + mask, val); + + return 0; +} + static int wcd938x_init_reg(struct snd_soc_component *component) { snd_soc_component_update_bits(component, WCD938X_SLEEP_CTL, 0x0E, 0x0E); @@ -1335,17 +1375,33 @@ static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w, snd_soc_dapm_to_component(w->dapm); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); int ret = 0; + int bank = 0; + int mode = 0; + bank = wcd938x_swr_slv_get_current_bank(wcd938x->tx_swr_dev, + wcd938x->tx_swr_dev->dev_num); + wcd938x_swr_slv_set_host_clk_div2(wcd938x->tx_swr_dev, + wcd938x->tx_swr_dev->dev_num, bank); switch (event) { case SND_SOC_DAPM_PRE_PMU: ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev, wcd938x->tx_swr_dev->dev_num, true); + if (test_bit(WCD_ADC1, &wcd938x->status_mask)) + mode |= wcd938x->tx_mode[WCD_ADC1]; + if (test_bit(WCD_ADC2, &wcd938x->status_mask)) + mode |= wcd938x->tx_mode[WCD_ADC2]; + if (test_bit(WCD_ADC3, &wcd938x->status_mask)) + mode |= wcd938x->tx_mode[WCD_ADC3]; + if (test_bit(WCD_ADC4, &wcd938x->status_mask)) + mode |= wcd938x->tx_mode[WCD_ADC4]; + wcd938x_set_swr_clk_rate(component, mode, bank); break; case SND_SOC_DAPM_POST_PMD: ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev, wcd938x->tx_swr_dev->dev_num, false); + wcd938x_set_swr_clk_rate(component, ADC_MODE_INVALID, bank); break; }; -- GitLab From 72fef48d6ba6e1362fea7aafbf65028aa95ec73e Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 30 Aug 2019 11:00:20 +0530 Subject: [PATCH 1196/1645] ASoC: bolero: Update init registers for tx and rx paths Update init registers for tx and rx paths in an array. Change-Id: I2738af7639ffec05b5c93e86a2a3f4cf7ccb36fe Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/rx-macro.c | 27 +++++++++++++++------------ asoc/codecs/bolero/tx-macro.c | 18 ++++++++++++++++-- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 9ac846f45922..f522851707ec 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -3532,6 +3532,15 @@ static int rx_swrm_clock(void *handle, bool enable) return ret; } +static const struct rx_macro_reg_mask_val rx_macro_reg_init[] = { + {BOLERO_CDC_RX_RX0_RX_PATH_SEC7, 0x07, 0x02}, + {BOLERO_CDC_RX_RX1_RX_PATH_SEC7, 0x07, 0x02}, + {BOLERO_CDC_RX_RX2_RX_PATH_SEC7, 0x07, 0x02}, + {BOLERO_CDC_RX_RX0_RX_PATH_CFG3, 0x03, 0x02}, + {BOLERO_CDC_RX_RX1_RX_PATH_CFG3, 0x03, 0x02}, + {BOLERO_CDC_RX_RX2_RX_PATH_CFG3, 0x03, 0x02}, +}; + static void rx_macro_init_bcl_pmic_reg(struct snd_soc_component *component) { struct device *rx_dev = NULL; @@ -3586,6 +3595,7 @@ static int rx_macro_init(struct snd_soc_component *component) int ret = 0; struct device *rx_dev = NULL; struct rx_macro_priv *rx_priv = NULL; + int i; rx_dev = bolero_get_device_ptr(component->dev, RX_MACRO); if (!rx_dev) { @@ -3637,18 +3647,11 @@ static int rx_macro_init(struct snd_soc_component *component) snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC3_INP"); snd_soc_dapm_sync(dapm); - snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX0_RX_PATH_SEC7, - 0x07, 0x02); - snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX1_RX_PATH_SEC7, - 0x07, 0x02); - snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX2_RX_PATH_SEC7, - 0x07, 0x02); - snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX0_RX_PATH_CFG3, - 0x03, 0x02); - snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX1_RX_PATH_CFG3, - 0x03, 0x02); - snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX2_RX_PATH_CFG3, - 0x03, 0x02); + for (i = 0; i < ARRAY_SIZE(rx_macro_reg_init); i++) + snd_soc_component_update_bits(component, + rx_macro_reg_init[i].reg, + rx_macro_reg_init[i].mask, + rx_macro_reg_init[i].val); rx_priv->component = component; rx_macro_init_bcl_pmic_reg(component); diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 8c32043c479e..45afd304dc81 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -119,6 +119,12 @@ enum { VA_MCLK, }; +struct tx_macro_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + struct tx_mute_work { struct tx_macro_priv *tx_priv; u32 decimator; @@ -2013,6 +2019,10 @@ static int tx_macro_validate_dmic_sample_rate(u32 dmic_sample_rate, return dmic_sample_rate; } +static const struct tx_macro_reg_mask_val tx_macro_reg_init[] = { + {BOLERO_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x0E}, +}; + static int tx_macro_init(struct snd_soc_component *component) { struct snd_soc_dapm_context *dapm = @@ -2092,8 +2102,12 @@ static int tx_macro_init(struct snd_soc_component *component) } tx_priv->component = component; - snd_soc_component_update_bits(component, - BOLERO_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x0E); + for (i = 0; i < ARRAY_SIZE(tx_macro_reg_init); i++) + snd_soc_component_update_bits(component, + tx_macro_reg_init[i].reg, + tx_macro_reg_init[i].mask, + tx_macro_reg_init[i].val); + return 0; } -- GitLab From af3faf2ae3db2bfeb0cc40a269da93887f23907c Mon Sep 17 00:00:00 2001 From: Yunfei Zhang Date: Sun, 15 Sep 2019 15:50:39 +0800 Subject: [PATCH 1197/1645] dsp: adm: use default rate for unsupported sample rates Some ECNS topologies can't support sample rate of 48KHZ, reset it to 16KHZ for such use cases. Change-Id: I5d0457feb2e74929546746fd4b184f2d7e065fbb Signed-off-by: Yunfei Zhang --- dsp/q6adm.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 6dbbbc0000d9..b161df90aec7 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -3044,14 +3044,19 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, } if ((topology == VPM_TX_SM_ECNS_V2_COPP_TOPOLOGY) || - (topology == VPM_TX_DM_FLUENCE_COPP_TOPOLOGY) || - (topology == VPM_TX_DM_RFECNS_COPP_TOPOLOGY)|| (topology == VPM_TX_DM_FLUENCE_EF_COPP_TOPOLOGY)) { if ((rate != ADM_CMD_COPP_OPEN_SAMPLE_RATE_8K) && (rate != ADM_CMD_COPP_OPEN_SAMPLE_RATE_16K) && (rate != ADM_CMD_COPP_OPEN_SAMPLE_RATE_32K) && (rate != ADM_CMD_COPP_OPEN_SAMPLE_RATE_48K)) - rate = 16000; + rate = 16000; + } + if ((topology == VPM_TX_DM_FLUENCE_COPP_TOPOLOGY) || + (topology == VPM_TX_DM_RFECNS_COPP_TOPOLOGY)) { + if ((rate != ADM_CMD_COPP_OPEN_SAMPLE_RATE_8K) && + (rate != ADM_CMD_COPP_OPEN_SAMPLE_RATE_16K) && + (rate != ADM_CMD_COPP_OPEN_SAMPLE_RATE_32K)) + rate = 16000; } if (topology == FFECNS_TOPOLOGY) { -- GitLab From 248ce5678f4ea4318bed67b0c028dbb462b4f7fc Mon Sep 17 00:00:00 2001 From: Ajit Pandey Date: Fri, 6 Sep 2019 10:51:02 +0530 Subject: [PATCH 1198/1645] asoc: msm-routing: Fix array out of bounds issue. It seems there is out of bound access chances for lsm_app_type_cfg array within msm_routing_get_lsm_app_type_cfg_control() callback. Added case check to return invalid value if user tries to exceed maximum allocated size of array to avoid it. Change-Id: Ied86e6c9a957255c55bb126a09741fbde429be32 Signed-off-by: Ajit Pandey --- asoc/msm-pcm-routing-v2.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index f5e9896795a6..ed622dfcc7ba 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -21699,16 +21699,16 @@ static int msm_routing_put_lsm_app_type_cfg_control( kcontrol->private_value)->shift; int i = 0, j; - num_app_cfg_types = ucontrol->value.integer.value[i++]; - memset(lsm_app_type_cfg, 0, MAX_APP_TYPES* - sizeof(struct msm_pcm_routing_app_type_data)); - - if (num_app_cfg_types > MAX_APP_TYPES) { + if (ucontrol->value.integer.value[0] > MAX_APP_TYPES) { pr_err("%s: number of app types exceed the max supported\n", __func__); return -EINVAL; } + num_app_cfg_types = ucontrol->value.integer.value[i++]; + memset(lsm_app_type_cfg, 0, MAX_APP_TYPES* + sizeof(struct msm_pcm_routing_app_type_data)); + for (j = 0; j < num_app_cfg_types; j++) { lsm_app_type_cfg[j].app_type = ucontrol->value.integer.value[i++]; -- GitLab From fa018867ef71189b0134dea9ce1b8be0ddbda771 Mon Sep 17 00:00:00 2001 From: Ajit Pandey Date: Wed, 4 Sep 2019 14:34:00 +0530 Subject: [PATCH 1199/1645] asoc: msm-compress: Add lock in controls _put() and _get() callback Few mixer controls _put and _get methods uses runtime private data that can be freed by close() callback in parallel threads leading to issue. Added global mutex lock in such methods to avoid runtime concurrency around such data. Change-Id: Ie542c64a4f1e50fd9547ebb9f65df2b7b0c21a0e Signed-off-by: Ajit Pandey --- asoc/msm-compress-q6-v2.c | 77 +++++++++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 16 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 8933dbd29112..4347bec26ed6 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +107,7 @@ struct msm_compr_pdata { struct msm_compr_ch_map *ch_map[MSM_FRONTEND_DAI_MAX]; bool is_in_use[MSM_FRONTEND_DAI_MAX]; struct msm_pcm_channel_mixer *chmixer_pspd[MSM_FRONTEND_DAI_MM_SIZE]; + struct mutex lock; }; struct msm_compr_audio { @@ -1941,6 +1943,7 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream) } spin_unlock_irqrestore(&prtd->lock, flags); + mutex_lock(&pdata->lock); pdata->cstream[soc_prtd->dai_link->id] = NULL; if (cstream->direction == SND_COMPRESS_PLAYBACK) { msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->id, @@ -1962,6 +1965,7 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream) pdata->is_in_use[soc_prtd->dai_link->id] = false; kfree(prtd); runtime->private_data = NULL; + mutex_unlock(&pdata->lock); return 0; } @@ -2018,6 +2022,7 @@ static int msm_compr_capture_free(struct snd_compr_stream *cstream) } spin_unlock_irqrestore(&prtd->lock, flags); + mutex_lock(&pdata->lock); pdata->cstream[soc_prtd->dai_link->id] = NULL; msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->id, SNDRV_PCM_STREAM_CAPTURE); @@ -2028,6 +2033,7 @@ static int msm_compr_capture_free(struct snd_compr_stream *cstream) kfree(prtd); runtime->private_data = NULL; + mutex_unlock(&pdata->lock); return 0; } @@ -3406,6 +3412,7 @@ static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol, struct snd_compr_stream *cstream = NULL; struct msm_compr_audio *prtd = NULL; long *values = &(ucontrol->value.integer.value[0]); + int ret = 0; int effects_module; pr_debug("%s\n", __func__); @@ -3414,21 +3421,25 @@ static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol, __func__, fe_id); return -EINVAL; } + + mutex_lock(&pdata->lock); cstream = pdata->cstream[fe_id]; audio_effects = pdata->audio_effects[fe_id]; if (!cstream || !audio_effects) { pr_err("%s: stream or effects inactive\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto done; } prtd = cstream->runtime->private_data; if (!prtd) { pr_err("%s: cannot set audio effects\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto done; } if (prtd->compr_passthr != LEGACY_PCM) { pr_debug("%s: No effects for compr_type[%d]\n", __func__, prtd->compr_passthr); - return 0; + goto done; } pr_debug("%s: Effects supported for compr_type[%d]\n", __func__, prtd->compr_passthr); @@ -3489,9 +3500,11 @@ static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol, break; default: pr_err("%s Invalid effects config module\n", __func__); - return -EINVAL; + ret = -EINVAL; } - return 0; +done: + mutex_unlock(&pdata->lock); + return ret; } static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol, @@ -3503,6 +3516,7 @@ static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol, snd_soc_component_get_drvdata(comp); struct msm_compr_audio_effects *audio_effects = NULL; struct snd_compr_stream *cstream = NULL; + int ret = 0; struct msm_compr_audio *prtd = NULL; pr_debug("%s\n", __func__); @@ -3511,19 +3525,23 @@ static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol, __func__, fe_id); return -EINVAL; } + + mutex_lock(&pdata->lock); cstream = pdata->cstream[fe_id]; audio_effects = pdata->audio_effects[fe_id]; if (!cstream || !audio_effects) { pr_debug("%s: stream or effects inactive\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto done; } prtd = cstream->runtime->private_data; if (!prtd) { pr_err("%s: cannot set audio effects\n", __func__); - return -EINVAL; + ret = -EINVAL; } - - return 0; +done: + mutex_unlock(&pdata->lock); + return ret; } static int msm_compr_query_audio_effect_put(struct snd_kcontrol *kcontrol, @@ -3536,6 +3554,7 @@ static int msm_compr_query_audio_effect_put(struct snd_kcontrol *kcontrol, struct msm_compr_audio_effects *audio_effects = NULL; struct snd_compr_stream *cstream = NULL; struct msm_compr_audio *prtd = NULL; + int ret = 0; long *values = &(ucontrol->value.integer.value[0]); if (fe_id >= MSM_FRONTEND_DAI_MAX) { @@ -3543,28 +3562,37 @@ static int msm_compr_query_audio_effect_put(struct snd_kcontrol *kcontrol, __func__, fe_id); return -EINVAL; } + + mutex_lock(&pdata->lock); + cstream = pdata->cstream[fe_id]; audio_effects = pdata->audio_effects[fe_id]; if (!cstream || !audio_effects) { pr_err("%s: stream or effects inactive\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto done; } prtd = cstream->runtime->private_data; if (!prtd) { pr_err("%s: cannot set audio effects\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto done; } if (prtd->compr_passthr != LEGACY_PCM) { pr_err("%s: No effects for compr_type[%d]\n", __func__, prtd->compr_passthr); - return -EPERM; + ret = -EPERM; + goto done; } audio_effects->query.mod_id = (u32)*values++; audio_effects->query.parm_id = (u32)*values++; audio_effects->query.size = (u32)*values++; audio_effects->query.offset = (u32)*values++; audio_effects->query.device = (u32)*values++; - return 0; + +done: + mutex_unlock(&pdata->lock); + return ret; } static int msm_compr_query_audio_effect_get(struct snd_kcontrol *kcontrol, @@ -3577,6 +3605,7 @@ static int msm_compr_query_audio_effect_get(struct snd_kcontrol *kcontrol, struct msm_compr_audio_effects *audio_effects = NULL; struct snd_compr_stream *cstream = NULL; struct msm_compr_audio *prtd = NULL; + int ret = 0; long *values = &(ucontrol->value.integer.value[0]); if (fe_id >= MSM_FRONTEND_DAI_MAX) { @@ -3584,23 +3613,29 @@ static int msm_compr_query_audio_effect_get(struct snd_kcontrol *kcontrol, __func__, fe_id); return -EINVAL; } + + mutex_lock(&pdata->lock); cstream = pdata->cstream[fe_id]; audio_effects = pdata->audio_effects[fe_id]; if (!cstream || !audio_effects) { pr_debug("%s: stream or effects inactive\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto done; } prtd = cstream->runtime->private_data; if (!prtd) { pr_err("%s: cannot set audio effects\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto done; } values[0] = (long)audio_effects->query.mod_id; values[1] = (long)audio_effects->query.parm_id; values[2] = (long)audio_effects->query.size; values[3] = (long)audio_effects->query.offset; values[4] = (long)audio_effects->query.device; - return 0; +done: + mutex_unlock(&pdata->lock); + return ret; } static int msm_compr_send_dec_params(struct snd_compr_stream *cstream, @@ -3686,6 +3721,7 @@ static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol, goto end; } + mutex_lock(&pdata->lock); switch (prtd->codec) { case FORMAT_MP3: case FORMAT_MPEG4_AAC: @@ -3737,6 +3773,7 @@ static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol, } end: pr_debug("%s: ret %d\n", __func__, rc); + mutex_unlock(&pdata->lock); return rc; } @@ -3956,6 +3993,7 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, goto done; } + mutex_lock(&pdata->lock); if (prtd->audio_client == NULL) { pr_err("%s: audio_client is null\n", __func__); ret = -EINVAL; @@ -3984,6 +4022,7 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, pr_err("%s: failed to send stream event cmd, err = %d\n", __func__, ret); done: + mutex_unlock(&pdata->lock); return ret; } @@ -4020,6 +4059,7 @@ static int msm_compr_ion_fd_map_put(struct snd_kcontrol *kcontrol, goto done; } + mutex_lock(&pdata->lock); if (prtd->audio_client == NULL) { pr_err("%s: audio_client is null\n", __func__); ret = -EINVAL; @@ -4031,6 +4071,7 @@ static int msm_compr_ion_fd_map_put(struct snd_kcontrol *kcontrol, if (ret < 0) pr_err("%s: failed to register ion fd\n", __func__); done: + mutex_unlock(&pdata->lock); return ret; } @@ -4053,6 +4094,7 @@ static int msm_compr_rtic_event_ack_put(struct snd_kcontrol *kcontrol, goto done; } + mutex_lock(&pdata->lock); cstream = pdata->cstream[fe_id]; if (cstream == NULL) { pr_err("%s cstream is null\n", __func__); @@ -4090,6 +4132,7 @@ static int msm_compr_rtic_event_ack_put(struct snd_kcontrol *kcontrol, pr_err("%s: failed to send rtic event ack, err = %d\n", __func__, ret); done: + mutex_unlock(&pdata->lock); return ret; } @@ -5469,6 +5512,7 @@ static int msm_compr_dev_probe(struct platform_device *pdev) kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; + mutex_init(&pdata->lock); dev_set_drvdata(&pdev->dev, pdata); return snd_soc_register_component(&pdev->dev, @@ -5485,6 +5529,7 @@ static int msm_compr_remove(struct platform_device *pdev) for (i = 0; i < MSM_FRONTEND_DAI_MM_SIZE; i++) kfree(pdata->chmixer_pspd[i]); } + mutex_destroy(&pdata->lock); kfree(pdata); snd_soc_unregister_component(&pdev->dev); -- GitLab From 168173ee6d782aa08e760b3e882b1de45f6e73d3 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 16 Sep 2019 12:59:43 +0530 Subject: [PATCH 1200/1645] asoc: kona: Update LPI GPIO wakeup disable for all DMICs Disable wakeup capability for all DMIC GPIOs. Change-Id: I7c8c5f653e565b8f8b6f40005051aab3f27ccc76 Signed-off-by: Laxminath Kasam --- asoc/kona.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asoc/kona.c b/asoc/kona.c index d91627b8b688..dcef02864843 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -7828,6 +7828,10 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) pdata->dmic45_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,cdc-dmic45-gpios", 0); + if (pdata->dmic01_gpio_p) + msm_cdc_pinctrl_set_wakeup_capable(pdata->dmic01_gpio_p, false); + if (pdata->dmic23_gpio_p) + msm_cdc_pinctrl_set_wakeup_capable(pdata->dmic23_gpio_p, false); if (pdata->dmic45_gpio_p) msm_cdc_pinctrl_set_wakeup_capable(pdata->dmic45_gpio_p, false); -- GitLab From c39ed80b7cf957e4ce8abdc63788452a30aa174d Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 16 Sep 2019 13:05:53 +0530 Subject: [PATCH 1201/1645] asoc: cdc-pinctrl: Update to disable MPM wakeup for multiple gpios Under same pinctrl node, there are multiple gpios that require MPM wakeup to be disabled. Update driver logic to support disable of multiple gpios under same node. Change-Id: I3a07e5d7621da4cd03b46d96ca5cec18958f1ebd Signed-off-by: Laxminath Kasam --- asoc/codecs/msm-cdc-pinctrl.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/asoc/codecs/msm-cdc-pinctrl.c b/asoc/codecs/msm-cdc-pinctrl.c index c611345fa70a..a10a68173362 100644 --- a/asoc/codecs/msm-cdc-pinctrl.c +++ b/asoc/codecs/msm-cdc-pinctrl.c @@ -14,13 +14,16 @@ #include #include +#define MAX_GPIOS 16 + struct msm_cdc_pinctrl_info { struct pinctrl *pinctrl; struct pinctrl_state *pinctrl_active; struct pinctrl_state *pinctrl_sleep; int gpio; bool state; - u32 tlmm_gpio; + u32 tlmm_gpio[MAX_GPIOS]; + u32 count; bool wakeup_capable; }; @@ -151,14 +154,21 @@ int msm_cdc_pinctrl_set_wakeup_capable(struct device_node *np, bool enable) { struct msm_cdc_pinctrl_info *gpio_data; int ret = 0; + u32 i = 0; gpio_data = msm_cdc_pinctrl_get_gpiodata(np); if (!gpio_data) return -EINVAL; - if (gpio_data->wakeup_capable) - ret = msm_gpio_mpm_wake_set(gpio_data->tlmm_gpio, enable); - + if (gpio_data->wakeup_capable) { + for (i = 0; i < gpio_data->count; i++) { + ret = msm_gpio_mpm_wake_set(gpio_data->tlmm_gpio[i], + enable); + if (ret < 0) + goto exit; + } + } +exit: return ret; } EXPORT_SYMBOL(msm_cdc_pinctrl_set_wakeup_capable); @@ -167,7 +177,9 @@ static int msm_cdc_pinctrl_probe(struct platform_device *pdev) { int ret = 0; struct msm_cdc_pinctrl_info *gpio_data; - u32 tlmm_gpio = 0; + u32 tlmm_gpio[MAX_GPIOS] = {0}; + u32 i = 0; + int count = 0; gpio_data = devm_kzalloc(&pdev->dev, sizeof(struct msm_cdc_pinctrl_info), @@ -210,12 +222,19 @@ static int msm_cdc_pinctrl_probe(struct platform_device *pdev) __func__, ret); } - if (!of_property_read_u32(pdev->dev.of_node, "qcom,tlmm-gpio", - &tlmm_gpio)) { + + count = of_property_count_u32_elems(pdev->dev.of_node, "qcom,tlmm-gpio"); + if (count <= 0) + goto cdc_rst; + if (!of_property_read_u32_array(pdev->dev.of_node, "qcom,tlmm-gpio", + tlmm_gpio, count)) { gpio_data->wakeup_capable = true; - gpio_data->tlmm_gpio = tlmm_gpio; + for (i = 0; i < count; i++) + gpio_data->tlmm_gpio[i] = tlmm_gpio[i]; + gpio_data->count = count; } +cdc_rst: gpio_data->gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,cdc-rst-n-gpio", 0); if (gpio_is_valid(gpio_data->gpio)) { -- GitLab From 71e0b484a17e034f9a877646b2f06d37d73ea630 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 11 Sep 2019 14:51:20 +0530 Subject: [PATCH 1202/1645] ASoC: Add support for tx data lane3 for lito v2 Lito has three data lanes for tx swr. As gpio support for swr tx data3 is present for lito v2, enable data lane for lito v2. Change-Id: I56faee1974f59e0a506fc74f2dadb95a52071907 Signed-off-by: Vatsal Bucha --- asoc/kona-port-config.h | 16 ++++++++++++++++ asoc/kona.c | 18 ++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/asoc/kona-port-config.h b/asoc/kona-port-config.h index 0f7379175302..723c94a7dde3 100644 --- a/asoc/kona-port-config.h +++ b/asoc/kona-port-config.h @@ -50,6 +50,15 @@ static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = { {3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, /* TX4 */ }; +/* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */ +static struct port_params tx_frame_params_v2[SWR_MSTR_PORT_LEN] = { + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},/* PCM OUT */ + {1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, /* TX1 */ + {1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2}, /* TX2 */ + {3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX3 */ + {3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2}, /* TX4 */ +}; + static struct swr_mstr_port_map sm_port_map[] = { {TX_MACRO, SWR_UC0, tx_frame_params_default}, {RX_MACRO, SWR_UC0, rx_frame_params_default}, @@ -57,4 +66,11 @@ static struct swr_mstr_port_map sm_port_map[] = { {WSA_MACRO, SWR_UC0, wsa_frame_params_default}, }; +static struct swr_mstr_port_map sm_port_map_v2[] = { + {TX_MACRO, SWR_UC0, tx_frame_params_v2}, + {RX_MACRO, SWR_UC0, rx_frame_params_default}, + {RX_MACRO, SWR_UC1, rx_frame_params_dsd}, + {WSA_MACRO, SWR_UC0, wsa_frame_params_default}, +}; + #endif /* _KONA_PORT_CONFIG */ diff --git a/asoc/kona.c b/asoc/kona.c index 41a4ac6cdddb..995a2b86b2ac 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -167,6 +167,7 @@ enum { struct msm_asoc_mach_data { struct snd_info_entry *codec_root; int usbc_en2_gpio; /* used by gpio driver API */ + int lito_v2_enabled; struct device_node *dmic01_gpio_p; /* used by pinctrl API */ struct device_node *dmic23_gpio_p; /* used by pinctrl API */ struct device_node *dmic45_gpio_p; /* used by pinctrl API */ @@ -5288,8 +5289,17 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) WSA_MACRO_GAIN_OFFSET_M1P5_DB); } } - bolero_set_port_map(component, ARRAY_SIZE(sm_port_map), - sm_port_map); + if (pdata->lito_v2_enabled) { + /* + * Enable tx data line3 for saipan version v2 amd + * write corresponding lpi register. + */ + bolero_set_port_map(component, ARRAY_SIZE(sm_port_map_v2), + sm_port_map_v2); + } else { + bolero_set_port_map(component, ARRAY_SIZE(sm_port_map), + sm_port_map); + } } card = rtd->card->snd_card; if (!pdata->codec_root) { @@ -7898,6 +7908,10 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) if (!pdata) return -ENOMEM; + of_property_read_u32(pdev->dev.of_node, + "qcom,lito-is-v2-enabled", + &pdata->lito_v2_enabled); + card = populate_snd_card_dailinks(&pdev->dev); if (!card) { dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); -- GitLab From 2f151367ce8312ce7122494d003f140912740b4d Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 16 Sep 2019 17:56:06 +0530 Subject: [PATCH 1203/1645] asoc: codecs: wcd937x: Fix compile error Use proper dev handle in print to avoid compile error. Change-Id: Ieca116199ec4c86f2ee8c1698285fff0ecababbf Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd937x/wcd937x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index fe0c65cfed52..fa2a8037029b 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -2316,7 +2316,8 @@ int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root, "variant", priv->entry); if (!variant_entry) { - dev_dbg(codec->dev, "%s: failed to create wcd937x variant entry\n", + dev_dbg(component->dev, + "%s: failed to create wcd937x variant entry\n", __func__); return -ENOMEM; } -- GitLab From bc3f1e5ac7b292a3851a9229f57097e721f2ed9d Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 17 Sep 2019 04:03:10 +0530 Subject: [PATCH 1204/1645] ASoC: tx-macro: Disable wakeup source for soundwire tx data gpio soundwire tx data gpio is wakeup source capable. Disable the interrupt capable during voice activation usecase to let the device enter into power collapse during voice activation usecase on headset. Change-Id: I64a0b5da249dd3da37310fb80909a0ac5fefae54 Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/tx-macro.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 67b3287f2548..f058c2ab255e 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1605,14 +1605,19 @@ static int tx_macro_register_event_listener(struct snd_soc_component *component, return -EINVAL; } if (tx_priv->swr_ctrl_data) { - if (enable) + if (enable) { ret = swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, SWR_REGISTER_WAKEUP, NULL); - else + msm_cdc_pinctrl_set_wakeup_capable( + tx_priv->tx_swr_gpio_p, false); + } else { + msm_cdc_pinctrl_set_wakeup_capable( + tx_priv->tx_swr_gpio_p, true); ret = swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, SWR_DEREGISTER_WAKEUP, NULL); + } } return ret; -- GitLab From edc65200d0aa9b489892c88d2b2ebf7510242d70 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 29 Aug 2019 15:00:22 +0530 Subject: [PATCH 1205/1645] ASoC: wcd938x: Add debug support for WCD938x soundwire slave Add debug support for WCD938x soundwire slave register access. Change-Id: I5984a04cf144e7e858addc5cd060e0ec1264f2a6 Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd938x/wcd938x-slave.c | 297 +++++++++++++++++++++++++++- 1 file changed, 296 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd938x/wcd938x-slave.c b/asoc/codecs/wcd938x/wcd938x-slave.c index ec42b0d471ee..d56cebb2b364 100644 --- a/asoc/codecs/wcd938x/wcd938x-slave.c +++ b/asoc/codecs/wcd938x/wcd938x-slave.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -11,10 +11,267 @@ #include #include +#ifdef CONFIG_DEBUG_FS +#include +#include + +#define SWR_SLV_MAX_REG_ADDR 0x2009 +#define SWR_SLV_START_REG_ADDR 0x40 +#define SWR_SLV_MAX_BUF_LEN 20 +#define BYTES_PER_LINE 12 +#define SWR_SLV_RD_BUF_LEN 8 +#define SWR_SLV_WR_BUF_LEN 32 +#define SWR_SLV_MAX_DEVICES 2 +#endif /* CONFIG_DEBUG_FS */ + struct wcd938x_slave_priv { struct swr_device *swr_slave; +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_wcd938x_dent; + struct dentry *debugfs_peek; + struct dentry *debugfs_poke; + struct dentry *debugfs_reg_dump; + unsigned int read_data; +#endif }; +#ifdef CONFIG_DEBUG_FS +static int codec_debug_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static int get_parameters(char *buf, u32 *param1, int num_of_par) +{ + char *token = NULL; + int base = 0, cnt = 0; + + token = strsep(&buf, " "); + for (cnt = 0; cnt < num_of_par; cnt++) { + if (token) { + if ((token[1] == 'x') || (token[1] == 'X')) + base = 16; + else + base = 10; + + if (kstrtou32(token, base, ¶m1[cnt]) != 0) + return -EINVAL; + + token = strsep(&buf, " "); + } else { + return -EINVAL; + } + } + return 0; +} + +static bool is_swr_slv_reg_readable(int reg) +{ + int ret = true; + + if (((reg > 0x46) && (reg < 0x4A)) || + ((reg > 0x4A) && (reg < 0x50)) || + ((reg > 0x55) && (reg < 0xD0)) || + ((reg > 0xD0) && (reg < 0xE0)) || + ((reg > 0xE0) && (reg < 0xF0)) || + ((reg > 0xF0) && (reg < 0x100)) || + ((reg > 0x105) && (reg < 0x120)) || + ((reg > 0x205) && (reg < 0x220)) || + ((reg > 0x305) && (reg < 0x320)) || + ((reg > 0x405) && (reg < 0x420)) || + ((reg > 0x128) && (reg < 0x130)) || + ((reg > 0x228) && (reg < 0x230)) || + ((reg > 0x328) && (reg < 0x330)) || + ((reg > 0x428) && (reg < 0x430)) || + ((reg > 0x138) && (reg < 0x205)) || + ((reg > 0x238) && (reg < 0x305)) || + ((reg > 0x338) && (reg < 0x405)) || + ((reg > 0x405) && (reg < 0xF00)) || + ((reg > 0xF05) && (reg < 0xF20)) || + ((reg > 0xF25) && (reg < 0xF30)) || + ((reg > 0xF35) && (reg < 0x2000))) + ret = false; + + return ret; +} + +static ssize_t wcd938x_swrslave_reg_show(struct swr_device *pdev, + char __user *ubuf, + size_t count, loff_t *ppos) +{ + int i, reg_val, len; + ssize_t total = 0; + char tmp_buf[SWR_SLV_MAX_BUF_LEN]; + + if (!ubuf || !ppos) + return 0; + + for (i = (((int) *ppos/BYTES_PER_LINE) + SWR_SLV_START_REG_ADDR); + i <= SWR_SLV_MAX_REG_ADDR; i++) { + if (!is_swr_slv_reg_readable(i)) + continue; + swr_read(pdev, pdev->dev_num, i, ®_val, 1); + len = snprintf(tmp_buf, 25, "0x%.3x: 0x%.2x\n", i, + (reg_val & 0xFF)); + if ((total + len) >= count - 1) + break; + if (copy_to_user((ubuf + total), tmp_buf, len)) { + pr_err("%s: fail to copy reg dump\n", __func__); + total = -EFAULT; + goto copy_err; + } + total += len; + *ppos += len; + } + +copy_err: + *ppos = SWR_SLV_MAX_REG_ADDR * BYTES_PER_LINE; + return total; +} + +static ssize_t codec_debug_dump(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct swr_device *pdev; + + if (!count || !file || !ppos || !ubuf) + return -EINVAL; + + pdev = file->private_data; + if (!pdev) + return -EINVAL; + + if (*ppos < 0) + return -EINVAL; + + return wcd938x_swrslave_reg_show(pdev, ubuf, count, ppos); +} + +static ssize_t codec_debug_read(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + char lbuf[SWR_SLV_RD_BUF_LEN]; + struct swr_device *pdev = NULL; + struct wcd938x_slave_priv *wcd938x_slave = NULL; + + if (!count || !file || !ppos || !ubuf) + return -EINVAL; + + pdev = file->private_data; + if (!pdev) + return -EINVAL; + + wcd938x_slave = swr_get_dev_data(pdev); + if (!wcd938x_slave) + return -EINVAL; + + if (*ppos < 0) + return -EINVAL; + + snprintf(lbuf, sizeof(lbuf), "0x%x\n", + (wcd938x_slave->read_data & 0xFF)); + + return simple_read_from_buffer(ubuf, count, ppos, lbuf, + strnlen(lbuf, 7)); +} + +static ssize_t codec_debug_peek_write(struct file *file, + const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char lbuf[SWR_SLV_WR_BUF_LEN]; + int rc = 0; + u32 param[5]; + struct swr_device *pdev = NULL; + struct wcd938x_slave_priv *wcd938x_slave = NULL; + + if (!cnt || !file || !ppos || !ubuf) + return -EINVAL; + + pdev = file->private_data; + if (!pdev) + return -EINVAL; + + wcd938x_slave = swr_get_dev_data(pdev); + if (!wcd938x_slave) + return -EINVAL; + + if (*ppos < 0) + return -EINVAL; + + if (cnt > sizeof(lbuf) - 1) + return -EINVAL; + + rc = copy_from_user(lbuf, ubuf, cnt); + if (rc) + return -EFAULT; + + lbuf[cnt] = '\0'; + rc = get_parameters(lbuf, param, 1); + if (!((param[0] <= SWR_SLV_MAX_REG_ADDR) && (rc == 0))) + return -EINVAL; + swr_read(pdev, pdev->dev_num, param[0], &wcd938x_slave->read_data, 1); + if (rc == 0) + rc = cnt; + else + pr_err("%s: rc = %d\n", __func__, rc); + + return rc; +} + +static ssize_t codec_debug_write(struct file *file, + const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char lbuf[SWR_SLV_WR_BUF_LEN]; + int rc = 0; + u32 param[5]; + struct swr_device *pdev; + + if (!file || !ppos || !ubuf) + return -EINVAL; + + pdev = file->private_data; + if (!pdev) + return -EINVAL; + + if (cnt > sizeof(lbuf) - 1) + return -EINVAL; + + rc = copy_from_user(lbuf, ubuf, cnt); + if (rc) + return -EFAULT; + + lbuf[cnt] = '\0'; + rc = get_parameters(lbuf, param, 2); + if (!((param[0] <= SWR_SLV_MAX_REG_ADDR) && + (param[1] <= 0xFF) && (rc == 0))) + return -EINVAL; + swr_write(pdev, pdev->dev_num, param[0], ¶m[1]); + if (rc == 0) + rc = cnt; + else + pr_err("%s: rc = %d\n", __func__, rc); + + return rc; +} + +static const struct file_operations codec_debug_write_ops = { + .open = codec_debug_open, + .write = codec_debug_write, +}; + +static const struct file_operations codec_debug_read_ops = { + .open = codec_debug_open, + .read = codec_debug_read, + .write = codec_debug_peek_write, +}; + +static const struct file_operations codec_debug_dump_ops = { + .open = codec_debug_open, + .read = codec_debug_dump, +}; +#endif + static int wcd938x_slave_bind(struct device *dev, struct device *master, void *data) { @@ -82,11 +339,49 @@ static int wcd938x_swr_probe(struct swr_device *pdev) wcd938x_slave->swr_slave = pdev; +#ifdef CONFIG_DEBUG_FS + if (!wcd938x_slave->debugfs_wcd938x_dent) { + wcd938x_slave->debugfs_wcd938x_dent = debugfs_create_dir( + dev_name(&pdev->dev), 0); + if (!IS_ERR(wcd938x_slave->debugfs_wcd938x_dent)) { + wcd938x_slave->debugfs_peek = + debugfs_create_file("swrslave_peek", + S_IFREG | 0444, + wcd938x_slave->debugfs_wcd938x_dent, + (void *) pdev, + &codec_debug_read_ops); + + wcd938x_slave->debugfs_poke = + debugfs_create_file("swrslave_poke", + S_IFREG | 0444, + wcd938x_slave->debugfs_wcd938x_dent, + (void *) pdev, + &codec_debug_write_ops); + + wcd938x_slave->debugfs_reg_dump = + debugfs_create_file( + "swrslave_reg_dump", + S_IFREG | 0444, + wcd938x_slave->debugfs_wcd938x_dent, + (void *) pdev, + &codec_debug_dump_ops); + } + } +#endif + return component_add(&pdev->dev, &wcd938x_slave_comp_ops); } static int wcd938x_swr_remove(struct swr_device *pdev) { +#ifdef CONFIG_DEBUG_FS + struct wcd938x_slave_priv *wcd938x_slave = swr_get_dev_data(pdev); + + if (wcd938x_slave) { + debugfs_remove_recursive(wcd938x_slave->debugfs_wcd938x_dent); + wcd938x_slave->debugfs_wcd938x_dent = NULL; + } +#endif component_del(&pdev->dev, &wcd938x_slave_comp_ops); swr_set_dev_data(pdev, NULL); swr_remove_device(pdev); -- GitLab From a557d960dd3751934cf5fe739e4962cc5e3f12e1 Mon Sep 17 00:00:00 2001 From: Ajit Pandey Date: Thu, 5 Sep 2019 16:26:01 +0530 Subject: [PATCH 1206/1645] asoc: msm-pcm: Added lock in controls _put() and _get() callback There is race condition around private data used in put() and get() of few mixer ctls with close() callback. Added global mutex lock and code changes to protect such critical section by accessing such lock. Change-Id: Ic160b0c7c29d0ea5d517b3bacc53828d8d61e085 Signed-off-by: Ajit Pandey --- asoc/msm-pcm-q6-v2.c | 122 ++++++++++++++++++++++++++++++++++++------- asoc/msm-pcm-q6-v2.h | 1 + 2 files changed, 105 insertions(+), 18 deletions(-) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 6525dd03106f..7197ad634b5b 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -897,19 +898,25 @@ static int msm_pcm_playback_close(struct snd_pcm_substream *substream) pr_debug("%s: cmd_pending 0x%lx\n", __func__, prtd->cmd_pending); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + pdata = (struct msm_plat_data *) dev_get_drvdata(component->dev); + if (!pdata) { + pr_err("%s: platform data is NULL\n", __func__); + return -EINVAL; + } + + mutex_lock(&pdata->lock); if (prtd->audio_client) { dir = IN; - if (!component) { - pr_err("%s: component is NULL\n", __func__); - return -EINVAL; - } /* * Unvote to downgrade the Rx thread priority from * RT Thread for Low-Latency use case. */ - pdata = (struct msm_plat_data *) - dev_get_drvdata(component->dev); if (pdata) { if (pdata->perf_mode == LOW_LATENCY_PCM_MODE) apr_end_rx_rt(prtd->audio_client->apr); @@ -943,7 +950,7 @@ static int msm_pcm_playback_close(struct snd_pcm_substream *substream) msm_adsp_clean_mixer_ctl_pp_event_queue(soc_prtd); kfree(prtd); runtime->private_data = NULL; - + mutex_unlock(&pdata->lock); return 0; } @@ -1035,9 +1042,25 @@ static int msm_pcm_capture_close(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; struct msm_audio *prtd = runtime->private_data; + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); + struct msm_plat_data *pdata; int dir = OUT; pr_debug("%s\n", __func__); + + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + pdata = (struct msm_plat_data *) dev_get_drvdata(component->dev); + if (!pdata) { + pr_err("%s: platform data is NULL\n", __func__); + return -EINVAL; + } + + mutex_lock(&pdata->lock); if (prtd->audio_client) { q6asm_cmd(prtd->audio_client, CMD_CLOSE); q6asm_audio_client_buf_free_contiguous(dir, @@ -1049,7 +1072,7 @@ static int msm_pcm_capture_close(struct snd_pcm_substream *substream) SNDRV_PCM_STREAM_CAPTURE); kfree(prtd); runtime->private_data = NULL; - + mutex_unlock(&pdata->lock); return 0; } @@ -1316,6 +1339,7 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, goto done; } + mutex_lock(&pdata->lock); event_data = (struct msm_adsp_event_data *)ucontrol->value.bytes.data; if ((event_data->event_type < ADSP_STREAM_PP_EVENT) || (event_data->event_type >= ADSP_STREAM_EVENT_MAX)) { @@ -1338,6 +1362,7 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, pr_err("%s: failed to send stream event cmd, err = %d\n", __func__, ret); done: + mutex_unlock(&pdata->lock); return ret; } @@ -1513,25 +1538,46 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, { int rc = 0; struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol); + struct msm_plat_data *pdata = NULL; struct snd_pcm_substream *substream = vol->pcm->streams[vol->stream].substream; + struct snd_soc_pcm_runtime *soc_prtd = NULL; + struct snd_soc_component *component = NULL; struct msm_audio *prtd; int volume = ucontrol->value.integer.value[0]; pr_debug("%s: volume : 0x%x\n", __func__, volume); if (!substream) { - pr_err("%s substream not found\n", __func__); + pr_err("%s: substream not found\n", __func__); return -ENODEV; } - if (!substream->runtime) { - pr_err("%s substream runtime not found\n", __func__); + + soc_prtd = substream->private_data; + if (!substream->runtime || !soc_prtd) { + pr_err("%s: substream runtime or private_data not found\n", + __func__); return 0; } + + component = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + pdata = (struct msm_plat_data *) dev_get_drvdata(component->dev); + if (!pdata) { + pr_err("%s: pdata not found\n", __func__); + return -ENODEV; + } + + mutex_lock(&pdata->lock); prtd = substream->runtime->private_data; if (prtd) { rc = msm_pcm_set_volume(prtd, volume); prtd->volume = volume; } + mutex_unlock(&pdata->lock); return rc; } @@ -1711,9 +1757,27 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol, substream = snd_pcm_chmap_substream(info, idx); if (!substream) return -ENODEV; - if (!substream->runtime) + + rtd = substream->private_data; + if (rtd) { + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (component) { + pdata = (struct msm_plat_data *) + dev_get_drvdata(component->dev); + if (!pdata) { + pr_err("%s: pdata not found\n", __func__); + return -ENODEV; + } + } else { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + } + + if (!substream->runtime || !rtd) return 0; + mutex_lock(&pdata->lock); prtd = substream->runtime->private_data; if (prtd) { prtd->set_channel_map = true; @@ -1722,13 +1786,9 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol, (char)(ucontrol->value.integer.value[i]); /* update chmixer_pspd chmap cached with routing driver as well */ - rtd = substream->private_data; if (rtd) { - component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); if (component) { fe_id = rtd->dai_link->id; - pdata = (struct msm_plat_data *) - dev_get_drvdata(component->dev); chmixer_pspd = pdata ? pdata->chmixer_pspd[fe_id][SESSION_TYPE_RX] : NULL; @@ -1742,6 +1802,7 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol, } } } + mutex_unlock(&pdata->lock); return 0; } @@ -1753,16 +1814,37 @@ static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol, unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); struct snd_pcm_substream *substream; struct msm_audio *prtd; + struct snd_soc_pcm_runtime *rtd = NULL; + struct msm_plat_data *pdata = NULL; + struct snd_soc_component *component = NULL; pr_debug("%s", __func__); substream = snd_pcm_chmap_substream(info, idx); if (!substream) return -ENODEV; + + rtd = substream->private_data; + if (rtd) { + component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); + if (component) { + pdata = (struct msm_plat_data *) + dev_get_drvdata(component->dev); + if (!pdata) { + pr_err("%s: pdata not found\n", __func__); + return -ENODEV; + } + } else { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + } + memset(ucontrol->value.integer.value, 0, sizeof(ucontrol->value.integer.value)); - if (!substream->runtime) + if (!substream->runtime || !rtd) return 0; /* no channels set */ + mutex_lock(&pdata->lock); prtd = substream->runtime->private_data; if (prtd && prtd->set_channel_map == true) { @@ -1774,6 +1856,7 @@ static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[i] = 0; } + mutex_unlock(&pdata->lock); return 0; } @@ -2043,6 +2126,7 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, return -EINVAL; } + mutex_lock(&pdata->lock); prtd = substream->runtime ? substream->runtime->private_data : NULL; if (chmixer_pspd->enable && prtd) { if (session_type == SESSION_TYPE_RX && @@ -2095,6 +2179,7 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, if (reset_override_in_ch_map) chmixer_pspd->override_in_ch_map = false; + mutex_unlock(&pdata->lock); return ret; } @@ -2756,7 +2841,7 @@ static int msm_pcm_probe(struct platform_device *pdev) } else { pdata->perf_mode = LEGACY_PCM_MODE; } - + mutex_init(&pdata->lock); dev_set_drvdata(&pdev->dev, pdata); @@ -2779,6 +2864,7 @@ static int msm_pcm_remove(struct platform_device *pdev) kfree(pdata->chmixer_pspd[i][SESSION_TYPE_TX]); } } + mutex_destroy(&pdata->lock); kfree(pdata); snd_soc_unregister_component(&pdev->dev); return 0; diff --git a/asoc/msm-pcm-q6-v2.h b/asoc/msm-pcm-q6-v2.h index 62fcebd3cbe4..6498f07fb4ed 100644 --- a/asoc/msm-pcm-q6-v2.h +++ b/asoc/msm-pcm-q6-v2.h @@ -117,6 +117,7 @@ struct msm_plat_data { struct msm_pcm_ch_map *ch_map[MSM_FRONTEND_DAI_MAX]; struct snd_pcm *pcm_device[MSM_FRONTEND_DAI_MM_SIZE]; struct msm_pcm_channel_mixer *chmixer_pspd[MSM_FRONTEND_DAI_MM_SIZE][2]; + struct mutex lock; }; struct msm_pcm_ch_map { -- GitLab From 1ebf9cc5069d39574a053961b13f2d7ffc4ab047 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Fri, 13 Sep 2019 17:40:56 +0530 Subject: [PATCH 1207/1645] asoc: qcs405: add ignore_suspend for lineout booster Apps is not able to enter into power suspend mode. Adding lineout booster widget to ignore suspend Change-Id: I220ff46465e0ad3d2b6852933e00331c055a26d6 Signed-off-by: Surendar Karka --- asoc/qcs405.c | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 36fbfad5c3ed..18dfb82207be 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -5272,6 +5272,7 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2"); snd_soc_dapm_ignore_suspend(dapm, "Analog Mic3"); snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4"); + snd_soc_dapm_ignore_suspend(dapm, "lineout booster"); snd_soc_dapm_sync(dapm); -- GitLab From 126be656930c3f0b5938bae8512d704409fa03d9 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 11 Sep 2019 11:32:55 +0530 Subject: [PATCH 1208/1645] ASoC: bolero: Fix audio mute during first 4-5 seconds in headset record Audio mute is observed if record is started as soon as headset is inserted. This is because hold time after button release is set as 800ms causing the delay. Change hold time to 200ms to fix this issue. Change-Id: I98028fca3412a3d47ad8e5154f25ff1726426955 Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/tx-macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 45afd304dc81..0451ddd4a1b4 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -2020,7 +2020,7 @@ static int tx_macro_validate_dmic_sample_rate(u32 dmic_sample_rate, } static const struct tx_macro_reg_mask_val tx_macro_reg_init[] = { - {BOLERO_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x0E}, + {BOLERO_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x02}, }; static int tx_macro_init(struct snd_soc_component *component) -- GitLab From 156a57fbb521d995ab150a64a152c5ddbfd3e211 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 18 Sep 2019 20:42:10 +0530 Subject: [PATCH 1209/1645] dsp: avtimer: Add adsp ready check before accessing avtimer registers Add adsp ready check before accessing avtimer registers in order to avoid NOC errors on these registers during SSR/PDR usecases while querying offset. Change-Id: I9246302f01906ab35095c76f729ea082b9756cc5 Signed-off-by: Aditya Bavanari --- dsp/avtimer.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dsp/avtimer.c b/dsp/avtimer.c index 39b5268ef78e..ad5e13af3f8d 100644 --- a/dsp/avtimer.c +++ b/dsp/avtimer.c @@ -335,6 +335,11 @@ int avcs_core_query_timer_offset(int64_t *av_offset, int32_t clock_id) uint64_t avtimer_tick_temp, avtimer_tick, sys_time = 0; struct timespec ts; + if (!atomic_read(&avtimer.adsp_ready)) { + pr_debug("%s:In SSR, return\n", __func__); + return -ENETRESET; + } + if ((avtimer.p_avtimer_lsw == NULL) || (avtimer.p_avtimer_msw == NULL)) { return -EINVAL; -- GitLab From 13485b7fe100a65db1e11fd7cd87922185afcde5 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 5 Aug 2019 17:51:14 -0700 Subject: [PATCH 1210/1645] asoc: codecs: wsa881x: turn off PA at ssr Register for a callback for ssr notification and turn off PA at pre-ssr to protect speaker from any turning off damage during ssr. Change-Id: I286d9bdcbcba9561424a8f0d4a1e99a8492caf08 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wsa881x.c | 88 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index 2871ad351206..daafcdc7f32d 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #include @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -101,6 +102,29 @@ struct wsa881x_priv { struct delayed_work ocp_ctl_work; struct device_node *wsa_rst_np; int pa_mute; + struct device_node *bolero_np; + struct platform_device* bolero_dev; + struct notifier_block bolero_nblock; + void *handle; + int (*register_notifier)(void *handle, + struct notifier_block *nblock, + bool enable); +}; + +/* from bolero to WSA events */ +enum { + BOLERO_WSA_EVT_TX_CH_HOLD_CLEAR = 1, + BOLERO_WSA_EVT_PA_OFF_PRE_SSR, + BOLERO_WSA_EVT_SSR_DOWN, + BOLERO_WSA_EVT_SSR_UP, +}; + +struct wsa_ctrl_platform_data { + void *handle; + int (*update_wsa_event)(void *handle, u16 event, u32 data); + int (*register_notifier)(void *handle, + struct notifier_block *nblock, + bool enable); }; #define SWR_SLV_MAX_REG_ADDR 0x390 @@ -1338,12 +1362,39 @@ static int wsa881x_gpio_init(struct swr_device *pdev) return ret; } +static int wsa881x_event_notify(struct notifier_block *nb, + unsigned long val, void *ptr) +{ + u16 event = (val & 0xffff); + struct wsa881x_priv *wsa881x = container_of(nb, struct wsa881x_priv, + bolero_nblock); + + if (!wsa881x) + return -EINVAL; + + switch (event) { + case BOLERO_WSA_EVT_PA_OFF_PRE_SSR: + snd_soc_component_update_bits(wsa881x->component, + WSA881X_SPKR_DRV_GAIN, + 0xF0, 0xC0); + snd_soc_component_update_bits(wsa881x->component, + WSA881X_SPKR_DRV_EN, + 0x80, 0x00); + break; + default: + break; + } + + return 0; +} + static int wsa881x_swr_probe(struct swr_device *pdev) { int ret = 0; struct wsa881x_priv *wsa881x; u8 devnum = 0; bool pin_state_current = false; + struct wsa_ctrl_platform_data *plat_data = NULL; wsa881x = devm_kzalloc(&pdev->dev, sizeof(struct wsa881x_priv), GFP_KERNEL); @@ -1435,6 +1486,37 @@ static int wsa881x_swr_probe(struct swr_device *pdev) __func__); goto dev_err; } + + wsa881x->bolero_np = of_parse_phandle(pdev->dev.of_node, + "qcom,bolero-handle", 0); + if (wsa881x->bolero_np) { + wsa881x->bolero_dev = + of_find_device_by_node(wsa881x->bolero_np); + if (wsa881x->bolero_dev) { + plat_data = dev_get_platdata(&wsa881x->bolero_dev->dev); + if (plat_data) { + wsa881x->bolero_nblock.notifier_call = + wsa881x_event_notify; + if (plat_data->register_notifier) + plat_data->register_notifier( + plat_data->handle, + &wsa881x->bolero_nblock, + true); + wsa881x->register_notifier = + plat_data->register_notifier; + wsa881x->handle = plat_data->handle; + } else { + dev_err(&pdev->dev, "%s: plat data not found\n", + __func__); + } + } else { + dev_err(&pdev->dev, "%s: bolero dev not found\n", + __func__); + } + } else { + dev_info(&pdev->dev, "%s: bolero node not found\n", __func__); + } + mutex_init(&wsa881x->res_lock); mutex_init(&wsa881x->temp_lock); @@ -1457,6 +1539,10 @@ static int wsa881x_swr_remove(struct swr_device *pdev) dev_err(&pdev->dev, "%s: wsa881x is NULL\n", __func__); return -EINVAL; } + + if (wsa881x->register_notifier) + wsa881x->register_notifier(wsa881x->handle, + &wsa881x->bolero_nblock, false); debugfs_remove_recursive(debugfs_wsa881x_dent); debugfs_wsa881x_dent = NULL; mutex_destroy(&wsa881x->res_lock); -- GitLab From 069df14aa0d5ed1c2a0180922e0220c41b87f9be Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 17 Sep 2019 23:43:34 +0530 Subject: [PATCH 1211/1645] asoc: codecs: Fix pop issue on WSA cold start Observe pop if FS clock is turned on at end of powerup sequence. Ensure WSA PA is turned on after FS clock to avoid pop. Change-Id: Ic1214d361e77db252b7a90a89fc99c69f51e270b Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc.c | 23 +++++++++++++++++++++++ asoc/codecs/bolero/bolero-cdc.h | 4 ++++ asoc/codecs/bolero/internal.h | 1 + asoc/codecs/bolero/wsa-macro.c | 11 ++++++++++- asoc/codecs/wsa881x.c | 16 +++++++++++++++- 5 files changed, 53 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index abb88bef4517..76c9d4064276 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -581,6 +581,29 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) } EXPORT_SYMBOL(bolero_unregister_macro); +void bolero_wsa_pa_on(struct device *dev) +{ + struct bolero_priv *priv; + + if (!dev) { + pr_err("%s: dev is null\n", __func__); + return; + } + if (!bolero_is_valid_child_dev(dev)) { + dev_err(dev, "%s: not a valid child dev\n", + __func__); + return; + } + priv = dev_get_drvdata(dev->parent); + if (!priv) { + dev_err(dev, "%s: priv is null\n", __func__); + return; + } + + bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_PA_ON_POST_FSCLK); +} +EXPORT_SYMBOL(bolero_wsa_pa_on); + static ssize_t bolero_version_read(struct snd_info_entry *entry, void *file_private_data, struct file *file, diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 8a74e79f542e..957389cea2d0 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -83,6 +83,7 @@ int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *dat int bolero_tx_clk_switch(struct snd_soc_component *component); int bolero_register_event_listener(struct snd_soc_component *component, bool enable); +void bolero_wsa_pa_on(struct device *dev); #else static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb) { @@ -154,5 +155,8 @@ static inline int bolero_register_event_listener( return 0; } +static void bolero_wsa_pa_on(struct device *dev) +{ +} #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index d353a2d21b78..d3f689467446 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -15,6 +15,7 @@ enum { BOLERO_WCD_EVT_PA_OFF_PRE_SSR, BOLERO_WCD_EVT_SSR_DOWN, BOLERO_WCD_EVT_SSR_UP, + BOLERO_WCD_EVT_PA_ON_POST_FSCLK, }; enum { diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 4747a9678599..3c145b0ead47 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -848,6 +848,7 @@ static int wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute) mix_reg, 0x20, 0x20); } } + bolero_wsa_pa_on(wsa_dev); break; default: break; @@ -1422,14 +1423,22 @@ static int wsa_macro_enable_main_path(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); u16 reg = 0; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL + WSA_MACRO_RX_PATH_OFFSET * w->shift; switch (event) { case SND_SOC_DAPM_PRE_PMU: - if (wsa_macro_adie_lb(component, w->shift)) + if (wsa_macro_adie_lb(component, w->shift)) { snd_soc_component_update_bits(component, reg, 0x20, 0x20); + bolero_wsa_pa_on(wsa_dev); + } break; default: break; diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index daafcdc7f32d..966fa8a2081b 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -117,6 +117,7 @@ enum { BOLERO_WSA_EVT_PA_OFF_PRE_SSR, BOLERO_WSA_EVT_SSR_DOWN, BOLERO_WSA_EVT_SSR_UP, + BOLERO_WSA_EVT_PA_ON_POST_FSCLK, }; struct wsa_ctrl_platform_data { @@ -1030,6 +1031,10 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMU: + if (!wsa881x->bolero_dev) + snd_soc_component_update_bits(component, + WSA881X_SPKR_DRV_EN, + 0x80, 0x80); if (!wsa881x->comp_enable) { max_gain = wsa881x->pa_gain; /* @@ -1063,6 +1068,9 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, wsa881x->swr_slave->dev_num); break; case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, + WSA881X_SPKR_DRV_EN, + 0x80, 0x00); if (wsa881x->visense_enable) { wsa881x_visense_adc_ctrl(component, DISABLE); wsa881x_visense_txfe_ctrl(component, DISABLE, @@ -1088,7 +1096,7 @@ static const struct snd_soc_dapm_widget wsa881x_dapm_widgets[] = { wsa881x_rdac_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("SPKR PGA", WSA881X_SPKR_DRV_EN, 7, 0, NULL, 0, + SND_SOC_DAPM_PGA_E("SPKR PGA", SND_SOC_NOPM, 0, 0, NULL, 0, wsa881x_spkr_pa_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), @@ -1381,6 +1389,12 @@ static int wsa881x_event_notify(struct notifier_block *nb, WSA881X_SPKR_DRV_EN, 0x80, 0x00); break; + case BOLERO_WSA_EVT_PA_ON_POST_FSCLK: + if ((snd_soc_component_read32(wsa881x->component, + WSA881X_SPKR_DAC_CTL) & 0x80) == 0x80) + snd_soc_component_update_bits(wsa881x->component, + WSA881X_SPKR_DRV_EN, + 0x80, 0x80); default: break; } -- GitLab From e50b500f6ea8a7d8a5abbd1022d3a996453f1830 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 19 Sep 2019 14:32:20 +0530 Subject: [PATCH 1212/1645] ASoc: swr-mstr: Avoid changing auto suspend timer value in runtime resume Changing auto suspend timer to default value without checking module params is causing audio touch tone to hold CX out of power collapse longer. Instead set another variable to change autosuspend delay during swr clk request failed. Change-Id: Ia85c4ebeea020221c8f385006543a95c69d9124e Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index ead3c9baaa8c..3bf59e9ed8f5 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -40,6 +40,8 @@ #define SWR_HSTOP_MAX_VAL 0xF #define SWR_HSTART_MIN_VAL 0x0 +#define ERR_AUTO_SUSPEND_TIMER_VAL 0x1 + #define SWRM_INTERRUPT_STATUS_MASK 0x1FDFD /* pm runtime auto suspend timer in msecs */ static int auto_suspend_timer = SWR_AUTO_SUSPEND_DELAY * 1000; @@ -2496,6 +2498,7 @@ static int swrm_runtime_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); int ret = 0; + bool swrm_clk_req_err = false; bool hw_core_err = false; bool aud_core_err = false; struct swr_master *mstr = &swrm->master; @@ -2529,7 +2532,7 @@ static int swrm_runtime_resume(struct device *dev) * Set autosuspend timer to 1 for * master to enter into suspend. */ - auto_suspend_timer = 1; + swrm_clk_req_err = true; goto exit; } if (!swrm->clk_stop_mode0_supp || swrm->state == SWR_MSTR_SSR) { @@ -2572,8 +2575,12 @@ static int swrm_runtime_resume(struct device *dev) swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); - pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer); - auto_suspend_timer = SWR_AUTO_SUSPEND_DELAY * 1000; + if (swrm_clk_req_err) + pm_runtime_set_autosuspend_delay(&pdev->dev, + ERR_AUTO_SUSPEND_TIMER_VAL); + else + pm_runtime_set_autosuspend_delay(&pdev->dev, + auto_suspend_timer); mutex_unlock(&swrm->reslock); return ret; -- GitLab From ade1444dd565d4a96e3cb2cb434be98cd5c8eaeb Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 19 Sep 2019 18:39:21 +0530 Subject: [PATCH 1213/1645] asoc: codecs: Add HPH and EAR concurrency state in class-h driver Update the class-h driver state machine to allow HPH and EAR concurrency. Change-Id: I5e227bdc87929b61fef78956f3a4eba4a686873e Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd-clsh.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/asoc/codecs/wcd-clsh.c b/asoc/codecs/wcd-clsh.c index 8306fa53d91e..73dc1f8ef087 100644 --- a/asoc/codecs/wcd-clsh.c +++ b/asoc/codecs/wcd-clsh.c @@ -482,6 +482,9 @@ static bool wcd_clsh_is_state_valid(u8 state) case WCD_CLSH_STATE_HPHR_AUX: case WCD_CLSH_STATE_HPH_ST_AUX: case WCD_CLSH_STATE_EAR_AUX: + case WCD_CLSH_STATE_HPHL_EAR: + case WCD_CLSH_STATE_HPHR_EAR: + case WCD_CLSH_STATE_HPH_ST_EAR: return true; default: return false; -- GitLab From e25b02a5e16c8d435646e06d03e7dd05d3259752 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 19 Sep 2019 18:43:59 +0530 Subject: [PATCH 1214/1645] asoc: codecs: wcd938x: Fix HPHL mute when ear path teardown Update mute for RX chain related to AUX (INT2) when tearing down ear path driven by AUX. Change-Id: I0ab2630bb681e8dc800c99245b1cd68120290c2b Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd938x/wcd938x.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 8ef3fdb45716..03be417d5be1 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1046,16 +1046,21 @@ static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, } break; case SND_SOC_DAPM_PRE_PMD: - if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) + if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) { wcd_disable_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT); - else + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX3 << 0x10 | 0x1)); + } else { wcd_disable_irq(&wcd938x->irq_info, WCD938X_IRQ_HPHL_PDM_WD_INT); - if (wcd938x->update_wcd_event) - wcd938x->update_wcd_event(wcd938x->handle, + if (wcd938x->update_wcd_event) + wcd938x->update_wcd_event(wcd938x->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX1 << 0x10 | 0x1)); + } break; case SND_SOC_DAPM_POST_PMD: /* 7 msec delay as per HW requirement */ -- GitLab From 92bf3feadb3d3bf35a08f986b4e787f41ee88ec0 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 20 Sep 2019 00:45:33 +0530 Subject: [PATCH 1215/1645] ASoC: wcd938x: Update wcd938x initialization sequence Update wcd938x codec initialization sequence as per hardware requirement. Change-Id: I17989e3f159d106eb9de6b1b8f660a647962539c Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd938x/wcd938x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 8ef3fdb45716..4bd37c33f047 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -221,6 +221,8 @@ static int wcd938x_init_reg(struct snd_soc_component *component) WCD938X_MICB3_TEST_CTL_1, 0xE0, 0xE0); snd_soc_component_update_bits(component, WCD938X_MICB4_TEST_CTL_1, 0xE0, 0xE0); + snd_soc_component_update_bits(component, + WCD938X_TX_3_4_TEST_BLK_EN2, 0x01, 0x00); return 0; } -- GitLab From 0eef9ab635c2f359ebe724c58a5cf3bf063895ac Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 20 Sep 2019 11:57:55 -0700 Subject: [PATCH 1216/1645] asoc: codec: bolero: keep internal track of TX votes TX clock is needed for setting up or tearing down VA path. while voting and unvoting for TX clock, keep track of the votes to unvote only if it was voted from VA widgets. Change-Id: Ia013517ed8d932ed3a5242bb7d052c1ee314fdbe Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/va-macro.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index ca3d95a9e0a0..b7d6fe06df35 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -124,6 +124,7 @@ struct va_macro_priv { int micb_users; u16 default_clk_id; u16 clk_id; + int tx_clk_status; }; static bool va_macro_get_data(struct snd_soc_component *component, @@ -330,14 +331,19 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, va_priv->default_clk_id, TX_CORE_CLK, true); + if (!ret) + va_priv->tx_clk_status++; ret = va_macro_mclk_enable(va_priv, 1, true); break; case SND_SOC_DAPM_POST_PMD: va_macro_mclk_enable(va_priv, 0, true); - bolero_clk_rsc_request_clock(va_priv->dev, + if (va_priv->tx_clk_status > 0) { + bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, TX_CORE_CLK, false); + va_priv->tx_clk_status--; + } break; default: dev_err(va_priv->dev, @@ -769,16 +775,21 @@ static int va_macro_enable_tx(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMU: - ret = bolero_clk_rsc_request_clock(va_priv->dev, + if (va_priv->tx_clk_status > 0) { + ret = bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, TX_CORE_CLK, false); + va_priv->tx_clk_status--; + } break; case SND_SOC_DAPM_PRE_PMD: ret = bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, TX_CORE_CLK, true); + if (!ret) + va_priv->tx_clk_status++; break; default: dev_err(va_priv->dev, -- GitLab From ff83a9e205c4445ae4239aca21b9d922db7ddf44 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 24 Sep 2019 00:33:42 +0530 Subject: [PATCH 1217/1645] dsp: Change condition for cal_data for v_vali_param V-Validation is not working due to different size for cal_data and data_size. This is expected as same callbacks are used for ftm and v validation. Change condition to ensure data_size is less than or equal to size of cal_data. Change-Id: I78b4e6778de9cfa5f95830fc6d48b84e608ba3a5 Signed-off-by: Vatsal Bucha --- dsp/q6afe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 9709772ab88b..8120536b916b 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -8521,7 +8521,7 @@ static int afe_set_cal_sp_th_vi_cfg(int32_t cal_type, size_t data_size, uint32_t mode; if (cal_data == NULL || - data_size != sizeof(*cal_data) || + data_size > sizeof(*cal_data) || this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL) goto done; @@ -8665,7 +8665,7 @@ static int afe_get_cal_sp_th_vi_param(int32_t cal_type, size_t data_size, int ret = 0; if (cal_data == NULL || - data_size != sizeof(*cal_data) || + data_size > sizeof(*cal_data) || this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL) return 0; -- GitLab From 8cf03d44ad2cc49fc458eeb7fee7911f2d98d750 Mon Sep 17 00:00:00 2001 From: Jhansi Konathala Date: Tue, 20 Aug 2019 19:27:39 +0530 Subject: [PATCH 1218/1645] ASoC: Add DTMF support for Audio usecase Add support to route DTMF source AFE port to any other RX port. this support is already present during voice call. This change adds t same support during audio usecase. Change-Id: I78fa1049e04de6d7af535929beac209f4c8bc1c6 Signed-off-by: Jhansi Konathala --- asoc/msm-pcm-routing-v2.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 921bca2315b8..972dedf1701e 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -2046,7 +2046,13 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set); - if (!is_mm_lsm_fe_id(val)) { + if (val == MSM_FRONTEND_DAI_DTMF_RX && + afe_get_port_type(msm_bedais[reg].port_id) == + MSM_AFE_PORT_TYPE_RX) { + pr_debug("%s(): set=%d port id=0x%x for dtmf generation\n", + __func__, set, msm_bedais[reg].port_id); + afe_set_dtmf_gen_rx_portid(msm_bedais[reg].port_id, set); + } else if (!is_mm_lsm_fe_id(val)) { /* recheck FE ID in the mixer control defined in this file */ pr_err("%s: bad MM ID\n", __func__); return; @@ -7025,7 +7031,10 @@ static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new int0_mi2s_rx_mixer_controls[] = { @@ -24865,6 +24874,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, {"PRI_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Audio Mixer"}, + {"PRI_MI2S_RX Audio Mixer", "DTMF", "DTMF_DL_HL"}, {"INT0_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"INT0_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, -- GitLab From 4bee1db04908e6e49a4db768b2fa8eda5b692864 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 18 Sep 2019 17:58:41 -0700 Subject: [PATCH 1219/1645] soc: swr-mstr: exit irq handler if clock req fails exit irq handler gracefully if soundwire clock request fails, so that soundwire registers are not accessed without clock. Change-Id: Ic2c9162e49901c7d5c876115f386d0a5a00fd691 Signed-off-by: Karthikeyan Mani --- soc/swr-mstr-ctrl.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 3bf59e9ed8f5..44d245d6dfb2 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1607,6 +1607,12 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) struct swr_device *swr_dev; struct swr_master *mstr = &swrm->master; + if (!swrm->dev_up || swrm->state == SWR_MSTR_SSR) { + complete(&swrm->broadcast); + dev_dbg(swrm->dev, "%s swrm is not up\n", __func__); + return IRQ_NONE; + } + if (unlikely(swrm_lock_sleep(swrm) == false)) { dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__); return IRQ_NONE; @@ -1621,7 +1627,12 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) ret = IRQ_NONE; goto err_audio_hw_vote; } - swrm_clk_request(swrm, true); + ret = swrm_clk_request(swrm, true); + if (ret) { + dev_err(dev, "%s: swrm clk failed\n", __func__); + ret = IRQ_NONE; + goto err_audio_core_vote; + } mutex_unlock(&swrm->reslock); intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); @@ -1797,6 +1808,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) mutex_lock(&swrm->reslock); swrm_clk_request(swrm, false); +err_audio_core_vote: swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); err_audio_hw_vote: -- GitLab From 7af16b8364876c66f4923319b282960161226b44 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 24 Sep 2019 12:15:09 -0700 Subject: [PATCH 1220/1645] asoc: codecs: wcd938x: check for device up before writes During SSR, codec device will be down and wait till receiving up notification before doing any register reads or writes. Change-Id: I0e2967990bfc9d0d780d4c7e666a4c31159e70ce Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/internal.h | 1 + asoc/codecs/wcd938x/wcd938x.c | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index 8c2ff0df610b..098a60dac88c 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -99,6 +99,7 @@ struct wcd938x_priv { struct snd_info_entry *variant_entry; int flyback_cur_det_disable; int ear_rx_path; + bool dev_up; }; struct wcd938x_micbias_setting { diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 4bd37c33f047..2980c3766d9b 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1650,6 +1650,7 @@ int wcd938x_micbias_control(struct snd_soc_component *component, int pre_off_event = 0, post_off_event = 0; int post_on_event = 0, post_dapm_off = 0; int post_dapm_on = 0; + int ret = 0; if ((micb_index < 0) || (micb_index > WCD938X_MAX_MICBIAS - 1)) { dev_err(component->dev, @@ -1691,6 +1692,12 @@ int wcd938x_micbias_control(struct snd_soc_component *component, switch (req) { case MICB_PULLUP_ENABLE: + if (!wcd938x->dev_up) { + dev_dbg(component->dev, "%s: enable req %d wcd device down\n", + __func__, req); + ret = -ENODEV; + goto done; + } wcd938x->pullup_ref[micb_index]++; if ((wcd938x->pullup_ref[micb_index] == 1) && (wcd938x->micb_ref[micb_index] == 0)) @@ -1700,12 +1707,24 @@ int wcd938x_micbias_control(struct snd_soc_component *component, case MICB_PULLUP_DISABLE: if (wcd938x->pullup_ref[micb_index] > 0) wcd938x->pullup_ref[micb_index]--; + if (!wcd938x->dev_up) { + dev_dbg(component->dev, "%s: enable req %d wcd device down\n", + __func__, req); + ret = -ENODEV; + goto done; + } if ((wcd938x->pullup_ref[micb_index] == 0) && (wcd938x->micb_ref[micb_index] == 0)) snd_soc_component_update_bits(component, micb_reg, 0xC0, 0x00); break; case MICB_ENABLE: + if (!wcd938x->dev_up) { + dev_dbg(component->dev, "%s: enable req %d wcd device down\n", + __func__, req); + ret = -ENODEV; + goto done; + } wcd938x->micb_ref[micb_index]++; if (wcd938x->micb_ref[micb_index] == 1) { snd_soc_component_update_bits(component, @@ -1738,6 +1757,12 @@ int wcd938x_micbias_control(struct snd_soc_component *component, case MICB_DISABLE: if (wcd938x->micb_ref[micb_index] > 0) wcd938x->micb_ref[micb_index]--; + if (!wcd938x->dev_up) { + dev_dbg(component->dev, "%s: enable req %d wcd device down\n", + __func__, req); + ret = -ENODEV; + goto done; + } if ((wcd938x->micb_ref[micb_index] == 0) && (wcd938x->pullup_ref[micb_index] > 0)) snd_soc_component_update_bits(component, micb_reg, @@ -1768,9 +1793,10 @@ int wcd938x_micbias_control(struct snd_soc_component *component, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", __func__, micb_num, wcd938x->micb_ref[micb_index], wcd938x->pullup_ref[micb_index]); - mutex_unlock(&wcd938x->micb_lock); - return 0; +done: + mutex_unlock(&wcd938x->micb_lock); + return ret; } EXPORT_SYMBOL(wcd938x_micbias_control); @@ -1833,6 +1859,7 @@ static int wcd938x_event_notify(struct notifier_block *block, 0x80, 0x00); break; case BOLERO_WCD_EVT_SSR_DOWN: + wcd938x->dev_up = false; mbhc = &wcd938x->mbhc->wcd_mbhc; wcd938x_mbhc_ssr_down(wcd938x->mbhc, component); wcd938x_reset_low(wcd938x->dev); @@ -1853,6 +1880,7 @@ static int wcd938x_event_notify(struct notifier_block *block, } else { wcd938x_mbhc_hs_detect(component, mbhc->mbhc_cfg); } + wcd938x->dev_up = true; break; case BOLERO_WCD_EVT_CLK_NOTIFY: snd_soc_component_update_bits(component, @@ -3008,6 +3036,7 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) return ret; } } + wcd938x->dev_up = true; return ret; err_hwdep: -- GitLab From e6c06ae348412ea6313c0bc629a305ae8aa40275 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 26 Sep 2019 15:05:08 +0530 Subject: [PATCH 1221/1645] asoc: codecs: wcd937x: restore clear_ack setting for wcd937x For wcd937x interrupts, need to set clear_ack explicitly for regmap irq to clear the interrupt. Change-Id: Ieffc20db0665fa82fe088337fbdf8b518191be3d Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd937x/wcd937x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 7a618c519192..1799599a84bf 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -88,6 +88,7 @@ static struct regmap_irq_chip wcd937x_regmap_irq_chip = { .mask_base = WCD937X_DIGITAL_INTR_MASK_0, .ack_base = WCD937X_DIGITAL_INTR_CLEAR_0, .use_ack = 1, + .clear_ack = 1, .type_base = WCD937X_DIGITAL_INTR_LEVEL_0, .runtime_pm = false, .handle_post_irq = wcd937x_handle_post_irq, -- GitLab From 45e51d1685976abdd66df2ffc55638802742545a Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 16 Sep 2019 15:47:25 +0530 Subject: [PATCH 1222/1645] soc: pinctrl-lpi: Enable gpio for swr tx data3 for lito v2 Lito swr has three data lines for tx. Third data line is on different lpi gpio from other data lines for tx. Enable corresponding gpio. Change-Id: I3213897766e3b38d3d04ca85410c8ca674efcfc6 Signed-off-by: Vatsal Bucha --- soc/pinctrl-lpi.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index 3aff320ceea1..ba3912919851 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -86,6 +86,7 @@ enum lpi_gpio_func_index { * @base: stores one of gpio_base or slew_base at a given time. * @gpio_base: Address base of LPI GPIO PAD. * @slew_base: Address base of LPI SLEW PAD. + * @lpi_slew_reg: Address for lpi slew reg. * @pullup: Constant current which flow through GPIO output buffer. * @strength: No, Low, Medium, High * @function: See lpi_gpio_functions[] @@ -99,6 +100,7 @@ struct lpi_gpio_pad { char __iomem *base; char __iomem *gpio_base; char __iomem *slew_base; + char __iomem *lpi_slew_reg; unsigned int pullup; unsigned int strength; unsigned int function; @@ -126,6 +128,7 @@ static const char *const lpi_gpio_groups[] = { #define LPI_TLMM_MAX_PINS 100 static u32 lpi_offset[LPI_TLMM_MAX_PINS]; static u32 lpi_slew_offset[LPI_TLMM_MAX_PINS]; +static u32 lpi_slew_base[LPI_TLMM_MAX_PINS]; static const char *const lpi_gpio_functions[] = { [LPI_GPIO_FUNC_INDEX_GPIO] = LPI_GPIO_FUNC_GPIO, @@ -366,6 +369,12 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int pin, pad->base = pad->slew_base; pad->offset = 0; mutex_lock(&state->slew_access_lock); + if (pad->lpi_slew_reg != NULL) { + pad->base = pad->lpi_slew_reg; + lpi_gpio_write(pad, LPI_SLEW_REG_VAL_CTL, arg); + pad->base = pad->slew_base; + goto slew_exit; + } val = lpi_gpio_read(pad, LPI_SLEW_REG_VAL_CTL); pad->offset = pad->slew_offset; for (i = 0; i < LPI_SLEW_BITS_SIZE; i++) { @@ -378,6 +387,7 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int pin, } pad->offset = 0; lpi_gpio_write(pad, LPI_SLEW_REG_VAL_CTL, val); +slew_exit: mutex_unlock(&state->slew_access_lock); break; default: @@ -646,6 +656,16 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) __func__, ret); } + ret = of_property_read_u32_array(dev->of_node, + "qcom,lpi-slew-base-tbl", + lpi_slew_base, npins); + if (ret < 0) { + for (i = 0; i < npins; i++) + lpi_slew_base[i] = LPI_SLEW_OFFSET_INVALID; + dev_dbg(dev, "%s: error in reading lpi slew table: %d\n", + __func__, ret); + } + state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); if (!state) return -ENOMEM; @@ -712,6 +732,11 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) pad->gpio_offset = lpi_offset[i]; pad->slew_offset = lpi_slew_offset[i]; pad->offset = pad->gpio_offset; + pad->lpi_slew_reg = NULL; + if ((lpi_slew_base[i] != LPI_SLEW_OFFSET_INVALID) && + lpi_slew_base[i]) + pad->lpi_slew_reg = devm_ioremap(dev, + lpi_slew_base[i], 0x4); } state->chip = lpi_gpio_template; -- GitLab From 72066d3ab6b76ae0361663d211b9f2a02ebdb44f Mon Sep 17 00:00:00 2001 From: Ajit Pandey Date: Fri, 27 Sep 2019 17:50:34 +0530 Subject: [PATCH 1223/1645] dsp: adsp-loader: Support dynamic size for array priv->adsp_fw_name. Current implementation allocates fixed size for array priv->adsp_fw_name but this may result in out of bound access if source adsp_fw_name_array dts property size exceed this fixed size. This patch fixes this issue by allocating priv->adsp_fw_name array with dynamic size of source array. Also fixes bytes copied in strlcpy. Change-Id: Iea031952224672c34eb7245996687985e18ef8be Signed-off-by: Ajit Pandey --- dsp/adsp-loader.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dsp/adsp-loader.c b/dsp/adsp-loader.c index ef9d92db7535..aec90f539b57 100644 --- a/dsp/adsp-loader.c +++ b/dsp/adsp-loader.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -22,7 +23,6 @@ #define SSR_RESET_CMD 1 #define IMAGE_UNLOAD_CMD 0 #define MAX_FW_IMAGES 4 -#define ADSP_FW_NAME_MAX_LENGTH 5 static ssize_t adsp_boot_store(struct kobject *kobj, struct kobj_attribute *attr, @@ -330,6 +330,7 @@ static int adsp_loader_probe(struct platform_device *pdev) int adsp_fw_cnt; u32* adsp_fw_bit_values = NULL; int i; + int fw_name_size; u32 adsp_var_idx; int ret = 0; @@ -398,12 +399,14 @@ static int adsp_loader_probe(struct platform_device *pdev) for (i = 0; i < adsp_fw_cnt; i++) { if (adsp_fw_bit_values[i] == adsp_var_idx) { + fw_name_size = strlen(adsp_fw_name_array[i]) + 1; priv->adsp_fw_name = devm_kzalloc(&pdev->dev, - ADSP_FW_NAME_MAX_LENGTH, GFP_KERNEL); + fw_name_size, + GFP_KERNEL); if (!priv->adsp_fw_name) goto wqueue; strlcpy(priv->adsp_fw_name, adsp_fw_name_array[i], - sizeof(priv->adsp_fw_name)); + fw_name_size); break; } } -- GitLab From 80b063e8d94b021263663ffa1f1e678c5cacde3f Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 27 Sep 2019 14:03:05 -0700 Subject: [PATCH 1224/1645] asoc: codecs: wcd938x: limit buffer copy to max buffer size Check for max buffer size before filling the buffer and add error handling for cases where buffer copy fails. Change-Id: I0eede1e5baf63c35c65a704c8bf53c85fe49892e Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/wcd938x-slave.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x-slave.c b/asoc/codecs/wcd938x/wcd938x-slave.c index d56cebb2b364..75cc7839c6d4 100644 --- a/asoc/codecs/wcd938x/wcd938x-slave.c +++ b/asoc/codecs/wcd938x/wcd938x-slave.c @@ -112,9 +112,9 @@ static ssize_t wcd938x_swrslave_reg_show(struct swr_device *pdev, if (!is_swr_slv_reg_readable(i)) continue; swr_read(pdev, pdev->dev_num, i, ®_val, 1); - len = snprintf(tmp_buf, 25, "0x%.3x: 0x%.2x\n", i, + len = snprintf(tmp_buf, sizeof(tmp_buf), "0x%.3x: 0x%.2x\n", i, (reg_val & 0xFF)); - if ((total + len) >= count - 1) + if (((total + len) >= count - 1) || (len < 0)) break; if (copy_to_user((ubuf + total), tmp_buf, len)) { pr_err("%s: fail to copy reg dump\n", __func__); -- GitLab From 6db89c7dc3ded1fbfc7ed2fea8b4648cfadad11d Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Tue, 24 Sep 2019 14:51:22 +0530 Subject: [PATCH 1225/1645] asoc: Add support for Hifi resampler check with bitwidth and sample_rate The check for bitwidht and sample rate along with hifi enable is to ensure not to open speaker at 32bit in combo usecase of speaker and Hifi-headphone. Change-Id: I4d1e5f357a74424c28d11d17a9fdfdd9309adec3 --- asoc/msm-pcm-routing-v2.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 921bca2315b8..0563d8c8016e 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1423,7 +1423,7 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, int num_copps = 0; struct route_payload payload; u32 channels, sample_rate; - u16 bit_width = 16; + u16 bit_width = 16, be_bit_width; bool is_lsm; pr_debug("%s:fe_id[%d] perf_mode[%d] id[%d] stream_type[%d] passt[%d]", @@ -1525,7 +1525,12 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, topology = COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY; pr_debug("%s: Before adm open topology %d\n", __func__, topology); - if (hifi_filter_enabled) + + be_bit_width = msm_routing_get_bit_width( + msm_bedais[i].format); + if (hifi_filter_enabled && (msm_bedais[i].sample_rate + == 384000 || msm_bedais[i].sample_rate == + 352800) && be_bit_width == 32) bit_width = msm_routing_get_bit_width( SNDRV_PCM_FORMAT_S32_LE); @@ -1805,7 +1810,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, int i, j, session_type, path_type, port_type, topology, num_copps = 0; struct route_payload payload; u32 channels, sample_rate; - uint16_t bits_per_sample = 16; + uint16_t bits_per_sample = 16, be_bit_width; uint32_t passthr_mode = LEGACY_PCM; int ret = 0; @@ -1873,7 +1878,12 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, topology = msm_routing_get_adm_topology(fedai_id, session_type, i); - if (hifi_filter_enabled) + be_bit_width = msm_routing_get_bit_width( + msm_bedais[i].format); + + if (hifi_filter_enabled && (msm_bedais[i].sample_rate == + 384000 ||msm_bedais[i].sample_rate == 352800) + && be_bit_width == 32) bits_per_sample = msm_routing_get_bit_width( SNDRV_PCM_FORMAT_S32_LE); copp_idx = adm_open(port_id, path_type, @@ -2039,7 +2049,7 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) { int session_type, path_type, topology; u32 channels, sample_rate; - uint16_t bits_per_sample = 16; + uint16_t bits_per_sample = 16, be_bit_width; struct msm_pcm_routing_fdai_data *fdai; uint32_t passthr_mode; bool is_lsm; @@ -2143,7 +2153,12 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) reg); acdb_dev_id = fe_dai_app_type_cfg[val][session_type][reg].acdb_dev_id; - if (hifi_filter_enabled) + + be_bit_width = msm_routing_get_bit_width( + msm_bedais[reg].format); + if (hifi_filter_enabled && (msm_bedais[reg].sample_rate + == 384000 ||msm_bedais[reg].sample_rate == + 352800) && be_bit_width == 32) bits_per_sample = msm_routing_get_bit_width( SNDRV_PCM_FORMAT_S32_LE); copp_idx = adm_open(port_id, path_type, @@ -28379,7 +28394,7 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) int session_type = INVALID_SESSION; struct msm_pcm_routing_bdai_data *bedai; u32 channels, sample_rate; - uint16_t bits_per_sample = 16, voc_path_type; + uint16_t bits_per_sample = 16, voc_path_type, be_bit_width; struct msm_pcm_routing_fdai_data *fdai; u32 session_id; struct media_format_info voc_be_media_format; @@ -28487,7 +28502,12 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) || (fdai->passthr_mode == COMPRESSED_PASSTHROUGH_IEC61937)) topology = COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY; - if (hifi_filter_enabled) + be_bit_width = msm_routing_get_bit_width( + bedai->format); + + if (hifi_filter_enabled && (bedai->sample_rate == 384000 + || bedai->sample_rate == 352800) && + be_bit_width == 32) bits_per_sample = msm_routing_get_bit_width( SNDRV_PCM_FORMAT_S32_LE); copp_idx = adm_open(port_id, path_type, -- GitLab From e0eca370e8b5ed8d9ef0f5969079f6744cc8d107 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 3 Oct 2019 19:34:45 +0530 Subject: [PATCH 1226/1645] asoc: add routing for RX_CDC_DMA_RX_1 to connect for hostless FE Add routing connection for RX_CDC_DMA_RX_1 backend to frontend CDC_DMA hostless for supporting FM on speaker over AUX. Change-Id: I14e4344fb6cc943ced4402d323ff6e04448806c4 Signed-off-by: Laxminath Kasam --- asoc/msm-pcm-routing-v2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 921bca2315b8..9f73dad5c6ce 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -26944,6 +26944,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"CDC_DMA_UL_HL", NULL, "VA_CDC_DMA_TX_0"}, {"RX_CDC_DMA_RX_0_DL_HL", "Switch", "CDC_DMA_DL_HL"}, {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0_DL_HL"}, + {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_0_DL_HL"}, {"TX3_CDC_DMA_UL_HL", NULL, "TX_CDC_DMA_TX_3"}, {"LSM1 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, {"LSM1 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, -- GitLab From 135b9f0b0c829ae34ff24045e1b9b7bd6cf58903 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 3 Oct 2019 11:52:41 +0530 Subject: [PATCH 1227/1645] asoc: codecs: wcd938x: Add support for setting ear gain ctl Add support for setting EAR PA gain directly using mixer control. Change-Id: I3667d8f26dc648e44d12c42be0940210763e08d5 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd938x/wcd938x.c | 62 +++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 2980c3766d9b..e1cdf29e790f 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1022,6 +1022,9 @@ static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD938X_DIGITAL_PDM_WD_CTL0, 0x17, 0x13); + if (!wcd938x->comp1_enable) + snd_soc_component_update_bits(component, + WCD938X_ANA_EAR_COMPANDER_CTL, 0x80, 0x80); break; case SND_SOC_DAPM_POST_PMU: /* 6 msec delay as per HW requirement */ @@ -1060,6 +1063,9 @@ static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, (WCD_RX1 << 0x10 | 0x1)); break; case SND_SOC_DAPM_POST_PMD: + if (!wcd938x->comp1_enable) + snd_soc_component_update_bits(component, + WCD938X_ANA_EAR_COMPANDER_CTL, 0x80, 0x00); /* 7 msec delay as per HW requirement */ usleep_range(7000, 7010); if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) @@ -2121,6 +2127,48 @@ static int wcd938x_rx_hph_mode_put(struct snd_kcontrol *kcontrol, return 0; } +static int wcd938x_ear_pa_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 ear_pa_gain = 0; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + + ear_pa_gain = snd_soc_component_read32(component, + WCD938X_ANA_EAR_COMPANDER_CTL); + + ear_pa_gain = (ear_pa_gain & 0x7C) >> 2; + + ucontrol->value.integer.value[0] = ear_pa_gain; + + dev_dbg(component->dev, "%s: ear_pa_gain = 0x%x\n", __func__, + ear_pa_gain); + + return 0; +} + +static int wcd938x_ear_pa_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 ear_pa_gain = 0; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + ear_pa_gain = ucontrol->value.integer.value[0] << 2; + + if (!wcd938x->comp1_enable) { + snd_soc_component_update_bits(component, + WCD938X_ANA_EAR_COMPANDER_CTL, + 0x7C, ear_pa_gain); + } + + return 0; +} + static int wcd938x_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2206,10 +2254,21 @@ static const char * const rx_hph_mode_mux_text_wcd9380[] = { "CLS_AB_LOHIFI", }; +static const char * const wcd938x_ear_pa_gain_text[] = { + "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB", "G_0_DB", + "G_M1P5_DB", "G_M3_DB", "G_M4P5_DB", + "G_M6_DB", "G_7P5_DB", "G_M9_DB", + "G_M10P5_DB", "G_M12_DB", "G_M13P5_DB", + "G_M15_DB", "G_M16P5_DB", "G_M18_DB", +}; + static const struct soc_enum rx_hph_mode_mux_enum_wcd9380 = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text_wcd9380), rx_hph_mode_mux_text_wcd9380); +static SOC_ENUM_SINGLE_EXT_DECL(wcd938x_ear_pa_gain_enum, + wcd938x_ear_pa_gain_text); + static const char * const rx_hph_mode_mux_text[] = { "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI", "CLS_H_ULP", "CLS_AB_HIFI", "CLS_AB_LP", "CLS_AB_LOHIFI", @@ -2220,6 +2279,9 @@ static const struct soc_enum rx_hph_mode_mux_enum = rx_hph_mode_mux_text); static const struct snd_kcontrol_new wcd9380_snd_controls[] = { + SOC_ENUM_EXT("EAR PA GAIN", wcd938x_ear_pa_gain_enum, + wcd938x_ear_pa_gain_get, wcd938x_ear_pa_gain_put), + SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum_wcd9380, wcd938x_rx_hph_mode_get, wcd938x_rx_hph_mode_put), -- GitLab From 81a54a220ee9bd6bae4360eef5f63d10071b1ec6 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 20 Sep 2019 00:23:59 +0530 Subject: [PATCH 1228/1645] dsp: Reset core hw vote client handle in SSR Reset core hw vote client handle in SSR use cases and do not unvote when the client handle is 0. This is to clean up the client ids in SSR in order to avoid unusual client deregistrations. Change-Id: Id0cee50f7ca27e29db6134b7a70ae75334e0d765 Signed-off-by: Aditya Bavanari --- dsp/q6afe.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 8120536b916b..c30415a6b278 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -596,6 +596,11 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) rtac_set_afe_handle(this_afe.apr); } + /* Reset the core client handle in SSR/PDR use cases */ + mutex_lock(&this_afe.afe_cmd_lock); + this_afe.lpass_hw_core_client_hdl = 0; + mutex_unlock(&this_afe.afe_cmd_lock); + /* * Pass reset events to proxy driver, if cb is registered */ @@ -9058,6 +9063,7 @@ int __init afe_init(void) this_afe.mmap_handle = 0; this_afe.vi_tx_port = -1; this_afe.vi_rx_port = -1; + this_afe.lpass_hw_core_client_hdl = 0; this_afe.prot_cfg.mode = MSM_SPKR_PROT_DISABLED; this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; @@ -9262,6 +9268,11 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle) mutex_lock(&this_afe.afe_cmd_lock); + if (!this_afe.lpass_hw_core_client_hdl) { + pr_debug("%s: SSR in progress, return\n", __func__); + goto done; + } + memset(cmd_ptr, 0, sizeof(hw_vote_cfg)); cmd_ptr->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, @@ -9278,6 +9289,12 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle) pr_debug("%s: lpass core hw unvote opcode[0x%x] hw id[0x%x]\n", __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id); + if (cmd_ptr->client_handle <= 0) { + pr_err("%s: invalid client handle\n", __func__); + ret = -EINVAL; + goto done; + } + atomic_set(&this_afe.status, 0); atomic_set(&this_afe.state, 1); ret = apr_send_pkt(this_afe.apr, (uint32_t *) cmd_ptr); -- GitLab From 4ccd4b4e747245c379c817ef7da2de254ff02c8b Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 27 Aug 2019 14:38:20 +0530 Subject: [PATCH 1229/1645] soc: pinctrl-lpi: Add support for audio HM voting for bengal On bengal target, audio core voting is not applicable. Add support for audio HM voting in pinctrl-lpi driver. Change-Id: I8661c981896c14899ca4d85f77507b417700b987 Signed-off-by: Laxminath Kasam --- soc/pinctrl-lpi.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index 3aff320ceea1..4fc4cee6ea79 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -110,6 +110,7 @@ struct lpi_gpio_state { struct gpio_chip chip; char __iomem *base; struct clk *lpass_core_hw_vote; + struct clk *lpass_audio_hw_vote; struct mutex slew_access_lock; bool core_hw_vote_status; struct mutex core_hw_vote_lock; @@ -616,6 +617,7 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) char __iomem *slew_base; u32 reg, slew_reg; struct clk *lpass_core_hw_vote = NULL; + struct clk *lpass_audio_hw_vote = NULL; ret = of_property_read_u32(dev->of_node, "reg", ®); if (ret < 0) { @@ -771,6 +773,17 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) } state->lpass_core_hw_vote = lpass_core_hw_vote; + /* Register LPASS audio hw vote */ + lpass_audio_hw_vote = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote"); + if (IS_ERR(lpass_audio_hw_vote)) { + ret = PTR_ERR(lpass_audio_hw_vote); + dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", + __func__, "lpass_audio_hw_vote", ret); + lpass_audio_hw_vote = NULL; + ret = 0; + } + state->lpass_audio_hw_vote = lpass_audio_hw_vote; + state->core_hw_vote_status = false; pm_runtime_set_autosuspend_delay(&pdev->dev, LPI_AUTO_SUSPEND_DELAY); pm_runtime_use_autosuspend(&pdev->dev); @@ -817,14 +830,19 @@ int lpi_pinctrl_runtime_resume(struct device *dev) { struct lpi_gpio_state *state = dev_get_drvdata(dev); int ret = 0; + struct clk *hw_vote = state->lpass_core_hw_vote; if (state->lpass_core_hw_vote == NULL) { dev_dbg(dev, "%s: Invalid core hw node\n", __func__); - return 0; + if (state->lpass_audio_hw_vote == NULL) { + dev_dbg(dev, "%s: Invalid audio hw node\n", __func__); + return 0; + } + hw_vote = state->lpass_audio_hw_vote; } mutex_lock(&state->core_hw_vote_lock); - ret = clk_prepare_enable(state->lpass_core_hw_vote); + ret = clk_prepare_enable(hw_vote); if (ret < 0) { pm_runtime_set_autosuspend_delay(dev, LPI_AUTO_SUSPEND_DELAY_ERROR); @@ -845,15 +863,20 @@ int lpi_pinctrl_runtime_resume(struct device *dev) int lpi_pinctrl_runtime_suspend(struct device *dev) { struct lpi_gpio_state *state = dev_get_drvdata(dev); + struct clk *hw_vote = state->lpass_core_hw_vote; if (state->lpass_core_hw_vote == NULL) { dev_dbg(dev, "%s: Invalid core hw node\n", __func__); - return 0; + if (state->lpass_audio_hw_vote == NULL) { + dev_dbg(dev, "%s: Invalid audio hw node\n", __func__); + return 0; + } + hw_vote = state->lpass_audio_hw_vote; } mutex_lock(&state->core_hw_vote_lock); if (state->core_hw_vote_status) { - clk_disable_unprepare(state->lpass_core_hw_vote); + clk_disable_unprepare(hw_vote); state->core_hw_vote_status = false; } mutex_unlock(&state->core_hw_vote_lock); -- GitLab From 3d209514a9c6e28d60be1095e89493e9c8ab9c69 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Thu, 3 Oct 2019 13:51:53 -0700 Subject: [PATCH 1230/1645] asoc: codecs: bolero: ignore children for pm suspend Allow bolero macro's child devices to pm enable irrespective of state of their parents. Change-Id: Ie615ea2db097760de75682b5881f71a37a735fa2 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/rx-macro.c | 1 + asoc/codecs/bolero/wsa-macro.c | 1 + 2 files changed, 2 insertions(+) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 9af15226efc3..cf412b765e25 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -3966,6 +3966,7 @@ static int rx_macro_probe(struct platform_device *pdev) pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); + pm_suspend_ignore_children(&pdev->dev, true); pm_runtime_enable(&pdev->dev); return 0; diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index dfca96894e0b..4e4c81329821 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -3198,6 +3198,7 @@ static int wsa_macro_probe(struct platform_device *pdev) pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); + pm_suspend_ignore_children(&pdev->dev, true); pm_runtime_enable(&pdev->dev); return ret; -- GitLab From daf7d7af99f1f820104287a9cee758d581f41201 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 27 Sep 2019 17:51:45 -0700 Subject: [PATCH 1231/1645] dsp: afe: call get params with afe cmd lock held If get params is called without afe cmd lock, it leads to race conditions with other callers calling afe_apr_send_pkt and the status values read back are getting overwritten wrongly by the callers that call without lock. Change-Id: I5af4d7bbbe01357dd9b6ae8efbe1831401003508 Signed-off-by: Karthikeyan Mani --- dsp/q6afe.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 8120536b916b..7612628de553 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -7907,6 +7907,7 @@ static int afe_get_sp_th_vi_v_vali_data( if (this_afe.vi_tx_port != -1) port = this_afe.vi_tx_port; + mutex_lock(&this_afe.afe_cmd_lock); memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; @@ -7917,7 +7918,7 @@ static int afe_get_sp_th_vi_v_vali_data( ret = q6afe_get_params(port, NULL, ¶m_hdr); if (ret) { pr_err("%s: Failed to get TH VI V-Vali data\n", __func__); - goto done; + goto get_params_fail; } th_vi_v_vali->pdata = param_hdr; @@ -7929,6 +7930,8 @@ static int afe_get_sp_th_vi_v_vali_data( th_vi_v_vali->param.status[SP_V2_SPKR_1], th_vi_v_vali->param.status[SP_V2_SPKR_2]); ret = 0; +get_params_fail: + mutex_unlock(&this_afe.afe_cmd_lock); done: return ret; } @@ -7946,6 +7949,7 @@ int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) if (this_afe.vi_tx_port != -1) port = this_afe.vi_tx_port; + mutex_lock(&this_afe.afe_cmd_lock); memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; @@ -7956,7 +7960,7 @@ int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) ret = q6afe_get_params(port, NULL, ¶m_hdr); if (ret) { pr_err("%s: Failed to get TH VI FTM data\n", __func__); - goto done; + goto get_params_fail; } th_vi->pdata = param_hdr; @@ -7970,6 +7974,8 @@ int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) th_vi->param.status[SP_V2_SPKR_1], th_vi->param.status[SP_V2_SPKR_2]); ret = 0; +get_params_fail: + mutex_unlock(&this_afe.afe_cmd_lock); done: return ret; } @@ -7987,6 +7993,7 @@ int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) if (this_afe.vi_tx_port != -1) port = this_afe.vi_tx_port; + mutex_lock(&this_afe.afe_cmd_lock); memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; @@ -7998,7 +8005,7 @@ int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) if (ret < 0) { pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", __func__, port, param_hdr.param_id, ret); - goto done; + goto get_params_fail; } ex_vi->pdata = param_hdr; @@ -8014,6 +8021,8 @@ int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) ex_vi->param.status[SP_V2_SPKR_1], ex_vi->param.status[SP_V2_SPKR_2]); ret = 0; +get_params_fail: + mutex_unlock(&this_afe.afe_cmd_lock); done: return ret; } @@ -8039,6 +8048,7 @@ int afe_get_sp_rx_tmax_xmax_logging_data( goto done; } + mutex_lock(&this_afe.afe_cmd_lock); memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; @@ -8050,7 +8060,7 @@ int afe_get_sp_rx_tmax_xmax_logging_data( if (ret < 0) { pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", __func__, port_id, param_hdr.param_id, ret); - goto done; + goto get_params_fail; } memcpy(xt_logging, &this_afe.xt_logging_resp.param, @@ -8064,6 +8074,8 @@ int afe_get_sp_rx_tmax_xmax_logging_data( xt_logging->max_temperature[SP_V2_SPKR_2], xt_logging->count_exceeded_temperature[SP_V2_SPKR_1], xt_logging->count_exceeded_temperature[SP_V2_SPKR_2]); +get_params_fail: + mutex_unlock(&this_afe.afe_cmd_lock); done: return ret; } @@ -8089,6 +8101,7 @@ int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats, goto exit; } + mutex_lock(&this_afe.afe_cmd_lock); memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; param_hdr.instance_id = INSTANCE_ID_0; @@ -8099,12 +8112,14 @@ int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats, if (ret < 0) { pr_err("%s: get param port 0x%x param id[0x%x] failed %d\n", __func__, port, param_hdr.param_id, ret); - goto exit; + goto get_params_fail; } memcpy(timing_stats, &this_afe.av_dev_drift_resp.timing_stats, param_hdr.param_size); ret = 0; +get_params_fail: + mutex_unlock(&this_afe.afe_cmd_lock); exit: return ret; } @@ -8130,6 +8145,7 @@ int afe_get_doa_tracking_mon(u16 port, goto exit; } + mutex_lock(&this_afe.afe_cmd_lock); memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AUDPROC_MODULE_ID_FFNS; param_hdr.instance_id = INSTANCE_ID_0; @@ -8140,7 +8156,7 @@ int afe_get_doa_tracking_mon(u16 port, if (ret < 0) { pr_err("%s: get param port 0x%x param id[0x%x] failed %d\n", __func__, port, param_hdr.param_id, ret); - goto exit; + goto get_params_fail; } memcpy(doa_tracking_data, &this_afe.doa_tracking_mon_resp.doa, @@ -8152,6 +8168,8 @@ int afe_get_doa_tracking_mon(u16 port, __func__, i, doa_tracking_data->interf_angle_L16[i]); } +get_params_fail: + mutex_unlock(&this_afe.afe_cmd_lock); exit: return ret; } @@ -8170,6 +8188,7 @@ int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) if (this_afe.vi_tx_port != -1) port = this_afe.vi_tx_port; + mutex_lock(&this_afe.afe_cmd_lock); memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2; param_hdr.instance_id = INSTANCE_ID_0; @@ -8180,7 +8199,7 @@ int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) if (ret < 0) { pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", __func__, port, param_hdr.param_id, ret); - goto fail_cmd; + goto get_params_fail; } memcpy(&calib_resp->res_cfg, &this_afe.calib_data.res_cfg, sizeof(this_afe.calib_data.res_cfg)); @@ -8189,6 +8208,8 @@ int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_1], calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_2]); ret = 0; +get_params_fail: + mutex_unlock(&this_afe.afe_cmd_lock); fail_cmd: return ret; } -- GitLab From 1a9d750c9bfc805aee65bfbd9e2c25b3f1b85a8c Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 23 Sep 2019 21:00:20 -0700 Subject: [PATCH 1232/1645] asoc: kona: vote audio dcodec for mi2s fractional sample rate To enable clock for mi2s running over fractional sample rate, vote for audio dcodec lpass clock. Change-Id: Ib8cff3ee0c61f23a4d8d163debea78dfb3a367a9 Signed-off-by: Karthikeyan Mani --- asoc/kona.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 120 insertions(+), 5 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index c98de7aa100c..1df6d34e2cad 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -55,6 +55,14 @@ #define SAMPLING_RATE_352P8KHZ 352800 #define SAMPLING_RATE_384KHZ 384000 +#define IS_FRACTIONAL(x) \ +((x == SAMPLING_RATE_11P025KHZ) || (x == SAMPLING_RATE_22P05KHZ) || \ +(x == SAMPLING_RATE_44P1KHZ) || (x == SAMPLING_RATE_88P2KHZ) || \ +(x == SAMPLING_RATE_176P4KHZ) || (x == SAMPLING_RATE_352P8KHZ)) + +#define IS_MSM_INTERFACE_MI2S(x) \ +((x == PRIM_MI2S) || (x == SEC_MI2S) || (x == TERT_MI2S)) + #define WCD9XXX_MBHC_DEF_RLOADS 5 #define WCD9XXX_MBHC_DEF_BUTTONS 8 #define CODEC_EXT_CLK_RATE 9600000 @@ -179,6 +187,8 @@ struct msm_asoc_mach_data { struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ bool is_afe_config_done; struct device_node *fsa_handle; + struct clk *lpass_audio_hw_vote; + int core_audio_vote_count; }; struct tdm_port { @@ -675,7 +685,9 @@ static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_16", "KHZ_22P05", "KHZ_32", "KHZ_44P1", - "KHZ_48", "KHZ_96", "KHZ_192"}; + "KHZ_48", "KHZ_88P2", "KHZ_96", + "KHZ_176P4", "KHZ_192","KHZ_352P8", + "KHZ_384"}; static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; @@ -2320,11 +2332,23 @@ static int mi2s_get_sample_rate(int value) sample_rate = SAMPLING_RATE_48KHZ; break; case 7: - sample_rate = SAMPLING_RATE_96KHZ; + sample_rate = SAMPLING_RATE_88P2KHZ; break; case 8: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 9: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 10: sample_rate = SAMPLING_RATE_192KHZ; break; + case 11: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 12: + sample_rate = SAMPLING_RATE_384KHZ; + break; default: sample_rate = SAMPLING_RATE_48KHZ; break; @@ -2358,12 +2382,24 @@ static int mi2s_get_sample_rate_val(int sample_rate) case SAMPLING_RATE_48KHZ: sample_rate_val = 6; break; - case SAMPLING_RATE_96KHZ: + case SAMPLING_RATE_88P2KHZ: sample_rate_val = 7; break; - case SAMPLING_RATE_192KHZ: + case SAMPLING_RATE_96KHZ: sample_rate_val = 8; break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; default: sample_rate_val = 6; break; @@ -4876,6 +4912,39 @@ static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) return 0; } +void mi2s_disable_audio_vote(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int index = cpu_dai->id; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + int sample_rate = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + sample_rate = mi2s_rx_cfg[index].sample_rate; + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + sample_rate = mi2s_tx_cfg[index].sample_rate; + } else { + pr_err("%s: invalid stream %d\n", __func__, substream->stream); + return; + } + + if (IS_MSM_INTERFACE_MI2S(index) && IS_FRACTIONAL(sample_rate)) { + if (pdata->lpass_audio_hw_vote != NULL) { + if (--pdata->core_audio_vote_count == 0) { + clk_disable_unprepare( + pdata->lpass_audio_hw_vote); + } else if (pdata->core_audio_vote_count < 0) { + pr_err("%s: audio vote mismatch\n", __func__); + pdata->core_audio_vote_count = 0; + } + } else { + pr_err("%s: Invalid lpass audio hw node\n", __func__); + } + } +} + static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) { int ret = 0; @@ -4885,6 +4954,7 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + int sample_rate = 0; dev_dbg(rtd->card->dev, "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", @@ -4904,6 +4974,34 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) * that the same clock won't be enable twice. */ mutex_lock(&mi2s_intf_conf[index].lock); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + sample_rate = mi2s_rx_cfg[index].sample_rate; + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + sample_rate = mi2s_tx_cfg[index].sample_rate; + } else { + pr_err("%s: invalid stream %d\n", __func__, substream->stream); + ret = -EINVAL; + goto vote_err; + } + + if (IS_MSM_INTERFACE_MI2S(index) && IS_FRACTIONAL(sample_rate)) { + if (pdata->lpass_audio_hw_vote == NULL) { + dev_err(rtd->card->dev, "%s: Invalid lpass audio hw node\n", + __func__); + ret = -EINVAL; + goto vote_err; + } + if (pdata->core_audio_vote_count == 0) { + ret = clk_prepare_enable(pdata->lpass_audio_hw_vote); + if (ret < 0) { + dev_err(rtd->card->dev, "%s: audio vote error\n", + __func__); + goto vote_err; + } + } + pdata->core_audio_vote_count++; + } + if (++mi2s_intf_conf[index].ref_cnt == 1) { /* Check if msm needs to provide the clock to the interface */ if (!mi2s_intf_conf[index].msm_is_mi2s_master) { @@ -4942,8 +5040,11 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) if (ret < 0) msm_mi2s_set_sclk(substream, false); clean_up: - if (ret < 0) + if (ret < 0) { mi2s_intf_conf[index].ref_cnt--; + mi2s_disable_audio_vote(substream); + } +vote_err: mutex_unlock(&mi2s_intf_conf[index].lock); err: return ret; @@ -4983,6 +5084,7 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", __func__, index, ret); } + mi2s_disable_audio_vote(substream); mutex_unlock(&mi2s_intf_conf[index].lock); } @@ -7897,6 +7999,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) const char *mbhc_audio_jack_type = NULL; int ret = 0; uint index = 0; + struct clk *lpass_audio_hw_vote = NULL; if (!pdev->dev.of_node) { dev_err(&pdev->dev, "%s: No platform supplied from device tree\n", __func__); @@ -8055,6 +8158,18 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) for (index = PRIM_MI2S; index < MI2S_MAX; index++) atomic_set(&(pdata->mi2s_gpio_ref_count[index]), 0); + /* Register LPASS audio hw vote */ + lpass_audio_hw_vote = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote"); + if (IS_ERR(lpass_audio_hw_vote)) { + ret = PTR_ERR(lpass_audio_hw_vote); + dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", + __func__, "lpass_audio_hw_vote", ret); + lpass_audio_hw_vote = NULL; + ret = 0; + } + pdata->lpass_audio_hw_vote = lpass_audio_hw_vote; + pdata->core_audio_vote_count = 0; + ret = msm_audio_ssr_register(&pdev->dev); if (ret) pr_err("%s: Registration with SND event FWK failed ret = %d\n", -- GitLab From ab093ac1b38b2f447fd4ccb716622ae25b6d2e86 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 7 Oct 2019 19:02:01 -0700 Subject: [PATCH 1233/1645] asoc: msm: Add 32bit support for mi2s Add support to handle 32 bit mi2s use cases in dai driver hw params. Change-Id: Id4b709f95fab8aaf8f7b63ae416b6da1ab213c89 Signed-off-by: Karthikeyan Mani --- asoc/msm-dai-q6-v2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 1b15444b2e7f..3ccc7040a4aa 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -5510,6 +5510,10 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream, dai_data->port_config.i2s.bit_width = 24; dai_data->bitwidth = 24; break; + case SNDRV_PCM_FORMAT_S32_LE: + dai_data->port_config.i2s.bit_width = 32; + dai_data->bitwidth = 32; + break; default: pr_err("%s: format %d\n", __func__, params_format(params)); -- GitLab From 768fe50c7e862098db6559edc469b3702da80827 Mon Sep 17 00:00:00 2001 From: Zhou Song Date: Tue, 8 Oct 2019 13:22:19 +0800 Subject: [PATCH 1234/1645] asoc: dsp: move ctl "SLIM_7_RX APTX_AD Enc Cfg" to the bottom Move this control definition to the bottom of the array, this is to avoid changing the index of existing controls. Change-Id: Id42dd908370b671cc7293f6c0af4adf3c025e1cc Signed-off-by: Zhou Song --- asoc/msm-dai-q6-v2.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 1b15444b2e7f..12fbf354629e 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -3461,15 +3461,6 @@ static const struct snd_kcontrol_new afe_enc_config_controls[] = { .get = msm_dai_q6_afe_enc_cfg_get, .put = msm_dai_q6_afe_enc_cfg_put, }, - { - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_INACTIVE), - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "SLIM_7_RX APTX_AD Enc Cfg", - .info = msm_dai_q6_afe_enc_cfg_info, - .get = msm_dai_q6_afe_enc_cfg_get, - .put = msm_dai_q6_afe_enc_cfg_put, - }, SOC_ENUM_EXT("AFE Input Channels", afe_chs_enum[0], msm_dai_q6_afe_input_channel_get, msm_dai_q6_afe_input_channel_put), @@ -3482,7 +3473,16 @@ static const struct snd_kcontrol_new afe_enc_config_controls[] = { msm_dai_q6_afe_scrambler_mode_put), SOC_ENUM_EXT("TWS Channel Mode", tws_chs_mode_enum[0], msm_dai_q6_tws_channel_mode_get, - msm_dai_q6_tws_channel_mode_put) + msm_dai_q6_tws_channel_mode_put), + { + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_INACTIVE), + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "SLIM_7_RX APTX_AD Enc Cfg", + .info = msm_dai_q6_afe_enc_cfg_info, + .get = msm_dai_q6_afe_enc_cfg_get, + .put = msm_dai_q6_afe_enc_cfg_put, + } }; static int msm_dai_q6_afe_dec_cfg_info(struct snd_kcontrol *kcontrol, @@ -3895,7 +3895,7 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) dai)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&afe_enc_config_controls[5], - dai)); + dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&avd_drift_config_controls[2], dai)); -- GitLab From 144659b943973b6fe91e0def813b86e50f190d73 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 2 Oct 2019 17:29:57 -0700 Subject: [PATCH 1235/1645] asoc: codecs: bolero: toggle zero gate for first hpf update Instead of disabling hpf zero gate in hpf callback, disable it while setting the inital cut off frequency itself to not have any glitches. Change-Id: I932aa0b2d68c2e8afd5cddd3d5fe17cbc98a5afb Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/tx-macro.c | 10 +++++++--- asoc/codecs/bolero/va-macro.c | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 45e0a80a309a..4c4661059f95 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -450,10 +450,10 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) snd_soc_component_update_bits(component, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, hpf_cut_off_freq << 5); - snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x02); + snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x02); /* Minimum 1 clk cycle delay is required as per HW spec */ usleep_range(1000, 1010); - snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x01); + snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x00); } static void tx_macro_mute_update_callback(struct work_struct *work) @@ -865,6 +865,10 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, tx_vol_ctl_reg, 0x20, 0x20); snd_soc_component_update_bits(component, hpf_gate_reg, 0x01, 0x00); + /* + * Minimum 1 clk cycle delay is required as per HW spec + */ + usleep_range(1000, 1010); hpf_cut_off_freq = ( snd_soc_component_read32(component, dec_cfg_reg) & @@ -887,7 +891,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, &tx_priv->tx_hpf_work[decimator].dwork, msecs_to_jiffies(300)); snd_soc_component_update_bits(component, - hpf_gate_reg, 0x02, 0x02); + hpf_gate_reg, 0x03, 0x03); /* * Minimum 1 clk cycle delay is required as per HW spec */ diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index b7d6fe06df35..167788ce8f0d 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -393,10 +393,10 @@ static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) snd_soc_component_update_bits(component, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, hpf_cut_off_freq << 5); - snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x02); + snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x02); /* Minimum 1 clk cycle delay is required as per HW spec */ usleep_range(1000, 1010); - snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x01); + snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x00); } static void va_macro_mute_update_callback(struct work_struct *work) @@ -688,6 +688,10 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, tx_vol_ctl_reg, 0x20, 0x20); snd_soc_component_update_bits(component, hpf_gate_reg, 0x01, 0x00); + /* + * Minimum 1 clk cycle delay is required as per HW spec + */ + usleep_range(1000, 1010); hpf_cut_off_freq = (snd_soc_component_read32( component, dec_cfg_reg) & @@ -700,7 +704,7 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, TX_HPF_CUT_OFF_FREQ_MASK, CF_MIN_3DB_150HZ << 5); snd_soc_component_update_bits(component, - hpf_gate_reg, 0x02, 0x02); + hpf_gate_reg, 0x03, 0x03); /* * Minimum 1 clk cycle delay is required as per HW spec */ -- GitLab From 29a4c3c9d0af96891846c1b294f36ed11fbd1e4b Mon Sep 17 00:00:00 2001 From: Jhansi Konathala Date: Wed, 25 Sep 2019 16:21:16 +0530 Subject: [PATCH 1236/1645] ASoc: Fix for dtmf tone play issue Fix the data corruption happening because of misaligned datatypes so that DTMF can be played for more than 32767 seconds. Change-Id: I199d6d10e9f184665d8f03a2265d0bcd8ae16590 Signed-off-by: Jhansi Konathala --- asoc/msm-pcm-dtmf-v2.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-dtmf-v2.c b/asoc/msm-pcm-dtmf-v2.c index 7f79471bf086..3dc7a26a54c8 100644 --- a/asoc/msm-pcm-dtmf-v2.c +++ b/asoc/msm-pcm-dtmf-v2.c @@ -20,6 +20,8 @@ #define DRV_NAME "msm-pcm-dtmf-v2" +#define DTMF_MAX_DURATION 65535 + enum { DTMF_IN_RX, DTMF_IN_TX, @@ -94,8 +96,12 @@ static int msm_dtmf_rx_generate_put(struct snd_kcontrol *kcontrol, int64_t duration = ucontrol->value.integer.value[2]; uint16_t gain = ucontrol->value.integer.value[3]; - pr_debug("%s: low_freq=%d high_freq=%d duration=%d gain=%d\n", + pr_debug("%s: low_freq=%d high_freq=%d duration=%lld gain=%d\n", __func__, low_freq, high_freq, (int)duration, gain); + + if (duration == DTMF_MAX_DURATION) + duration = -1; + afe_dtmf_generate_rx(duration, high_freq, low_freq, gain); return 0; } -- GitLab From ae52c9925284716968d19732916c2b9e821ef224 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 26 Aug 2019 15:01:15 +0530 Subject: [PATCH 1237/1645] asoc: bengal: Add new machine driver for bengal target Add support for new machine driver for bengal target. Change-Id: Iffb189136e0ec0ae42d375d112227d4237e4b502 Signed-off-by: Laxminath Kasam --- asoc/bengal-port-config.h | 45 + asoc/bengal.c | 6607 +++++++++++++++++++++++++++++++++++++ 2 files changed, 6652 insertions(+) create mode 100644 asoc/bengal-port-config.h create mode 100644 asoc/bengal.c diff --git a/asoc/bengal-port-config.h b/asoc/bengal-port-config.h new file mode 100644 index 000000000000..99899632c17a --- /dev/null +++ b/asoc/bengal-port-config.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef _BENGAL_PORT_CONFIG +#define _BENGAL_PORT_CONFIG + +#include + +/* + * Add port configuration in the format + *{ si, off1, off2, hstart, hstop, wd_len, bp_mode, bgp_ctrl, lane_ctrl} + */ + +static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = { + {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1}, + {31, 0, 0, 3, 6, 7, 0, 0xFF, 0}, + {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0}, + {7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, + {0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0}, +}; + +static struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = { + {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1}, + {31, 0, 0, 3, 6, 7, 0, 0xFF, 0}, + {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0}, + {7, 9, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0}, + {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 3, 0}, +}; + +/* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */ +static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = { + {1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX1 */ + {1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, /* TX2 */ + {3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX3 */ +}; + +static struct swr_mstr_port_map sm_port_map[] = { + {TX_MACRO, SWR_UC0, tx_frame_params_default}, + {RX_MACRO, SWR_UC0, rx_frame_params_default}, + {RX_MACRO, SWR_UC1, rx_frame_params_dsd}, +}; + +#endif /* _BENGAL_PORT_CONFIG */ diff --git a/asoc/bengal.c b/asoc/bengal.c new file mode 100644 index 000000000000..21287b408f92 --- /dev/null +++ b/asoc/bengal.c @@ -0,0 +1,6607 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "device_event.h" +#include "msm-pcm-routing-v2.h" +#include "asoc/msm-cdc-pinctrl.h" +#include "asoc/wcd-mbhc-v2.h" +#include "codecs/wcd937x/wcd937x-mbhc.h" +#include "codecs/wsa881x-analog.h" +#include "codecs/wcd937x/wcd937x.h" +#include "codecs/bolero/bolero-cdc.h" +#include +#include "bengal-port-config.h" + +#define DRV_NAME "bengal-asoc-snd" +#define __CHIPSET__ "BENGAL " +#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) + +#define SAMPLING_RATE_8KHZ 8000 +#define SAMPLING_RATE_11P025KHZ 11025 +#define SAMPLING_RATE_16KHZ 16000 +#define SAMPLING_RATE_22P05KHZ 22050 +#define SAMPLING_RATE_32KHZ 32000 +#define SAMPLING_RATE_44P1KHZ 44100 +#define SAMPLING_RATE_48KHZ 48000 +#define SAMPLING_RATE_88P2KHZ 88200 +#define SAMPLING_RATE_96KHZ 96000 +#define SAMPLING_RATE_176P4KHZ 176400 +#define SAMPLING_RATE_192KHZ 192000 +#define SAMPLING_RATE_352P8KHZ 352800 +#define SAMPLING_RATE_384KHZ 384000 + +#define WCD9XXX_MBHC_DEF_RLOADS 5 +#define WCD9XXX_MBHC_DEF_BUTTONS 8 +#define CODEC_EXT_CLK_RATE 9600000 +#define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define DEV_NAME_STR_LEN 32 +#define WCD_MBHC_HS_V_MAX 1600 + +#define TDM_CHANNEL_MAX 8 +#define DEV_NAME_STR_LEN 32 + +/* time in us to ensure LPM doesn't go in C3/C4 */ +#define MSM_LL_QOS_VALUE 300 + +#define ADSP_STATE_READY_TIMEOUT_MS 3000 + +#define WCN_CDC_SLIM_RX_CH_MAX 2 +#define WCN_CDC_SLIM_TX_CH_MAX 3 + +enum { + TDM_0 = 0, + TDM_1, + TDM_2, + TDM_3, + TDM_4, + TDM_5, + TDM_6, + TDM_7, + TDM_PORT_MAX, +}; + +enum { + TDM_PRI = 0, + TDM_SEC, + TDM_TERT, + TDM_QUAT, + TDM_INTERFACE_MAX, +}; + +enum { + PRIM_AUX_PCM = 0, + SEC_AUX_PCM, + TERT_AUX_PCM, + QUAT_AUX_PCM, + AUX_PCM_MAX, +}; + +enum { + PRIM_MI2S = 0, + SEC_MI2S, + TERT_MI2S, + QUAT_MI2S, + MI2S_MAX, +}; + +enum { + RX_CDC_DMA_RX_0 = 0, + RX_CDC_DMA_RX_1, + RX_CDC_DMA_RX_2, + RX_CDC_DMA_RX_3, + RX_CDC_DMA_RX_5, + CDC_DMA_RX_MAX, +}; + +enum { + TX_CDC_DMA_TX_0 = 0, + TX_CDC_DMA_TX_3, + TX_CDC_DMA_TX_4, + VA_CDC_DMA_TX_0, + VA_CDC_DMA_TX_1, + VA_CDC_DMA_TX_2, + CDC_DMA_TX_MAX, +}; + +enum { + SLIM_RX_7 = 0, + SLIM_RX_MAX, +}; + +enum { + SLIM_TX_7 = 0, + SLIM_TX_8, + SLIM_TX_MAX, +}; + +enum { + AFE_LOOPBACK_TX_IDX = 0, + AFE_LOOPBACK_TX_IDX_MAX, +}; +struct msm_asoc_mach_data { + struct snd_info_entry *codec_root; + int usbc_en2_gpio; /* used by gpio driver API */ + struct device_node *dmic01_gpio_p; /* used by pinctrl API */ + struct device_node *dmic23_gpio_p; /* used by pinctrl API */ + struct device_node *mi2s_gpio_p[MI2S_MAX]; /* used by pinctrl API */ + atomic_t mi2s_gpio_ref_count[MI2S_MAX]; /* used by pinctrl API */ + struct device_node *us_euro_gpio_p; /* used by pinctrl API */ + struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */ + struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ + struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ + bool is_afe_config_done; + struct device_node *fsa_handle; +}; + +struct tdm_port { + u32 mode; + u32 channel; +}; + +enum { + EXT_DISP_RX_IDX_DP = 0, + EXT_DISP_RX_IDX_DP1, + EXT_DISP_RX_IDX_MAX, +}; + +struct msm_wsa881x_dev_info { + struct device_node *of_node; + u32 index; +}; + +struct aux_codec_dev_info { + struct device_node *of_node; + u32 index; +}; + +struct dev_config { + u32 sample_rate; + u32 bit_format; + u32 channels; +}; + +/* Default configuration of slimbus channels */ +static struct dev_config slim_rx_cfg[] = { + [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config slim_tx_cfg[] = { + [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config usb_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +static struct dev_config usb_tx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 1, +}; + +static struct dev_config proxy_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +static struct afe_clk_set mi2s_clk[MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, +}; + +struct mi2s_conf { + struct mutex lock; + u32 ref_cnt; + u32 msm_is_mi2s_master; +}; + +static u32 mi2s_ebit_clk[MI2S_MAX] = { + Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT, +}; + +static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; + +/* Default configuration of TDM channels */ +static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, +}; + +static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, +}; + +/* Default configuration of AUX PCM channels */ +static struct dev_config aux_pcm_rx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_tx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +/* Default configuration of MI2S channels */ +static struct dev_config mi2s_rx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config mi2s_tx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +/* Default configuration of Codec DMA Interface RX */ +static struct dev_config cdc_dma_rx_cfg[] = { + [RX_CDC_DMA_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [RX_CDC_DMA_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [RX_CDC_DMA_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [RX_CDC_DMA_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [RX_CDC_DMA_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +/* Default configuration of Codec DMA Interface TX */ +static struct dev_config cdc_dma_tx_cfg[] = { + [TX_CDC_DMA_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TX_CDC_DMA_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TX_CDC_DMA_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [VA_CDC_DMA_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, + [VA_CDC_DMA_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, + [VA_CDC_DMA_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, +}; + +static struct dev_config afe_loopback_tx_cfg[] = { + [AFE_LOOPBACK_TX_IDX] = { + SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static int msm_vi_feed_tx_ch = 2; +static const char *const vi_feed_ch_text[] = {"One", "Two"}; +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; +static char const *ch_text[] = {"Two", "Three", "Four", "Five", + "Six", "Seven", "Eight"}; +static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", + "KHZ_48", "KHZ_176P4", + "KHZ_352P8"}; +static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; +static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", "Eight"}; +static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; +static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_16", + "KHZ_22P05", "KHZ_32", "KHZ_44P1", + "KHZ_48", "KHZ_96", "KHZ_192"}; +static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; + +static const char *const cdc_dma_rx_ch_text[] = {"One", "Two"}; +static const char *const cdc_dma_tx_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *cdc_dma_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", + "KHZ_176P4", "KHZ_192", + "KHZ_352P8", "KHZ_384"}; +static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; +static char const *bt_sample_rate_rx_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; +static char const *bt_sample_rate_tx_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; +static const char *const afe_loopback_tx_ch_text[] = {"One", "Two"}; + +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_chs, cdc_dma_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_0_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_3_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_0_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_1_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_2_chs, cdc_dma_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_0_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_3_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_0_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_1_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_2_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_3_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tx_cdc_dma_tx_4_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_1_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(va_cdc_dma_tx_2_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_rx, bt_sample_rate_rx_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_tx, bt_sample_rate_tx_text); +static SOC_ENUM_SINGLE_EXT_DECL(afe_loopback_tx_chs, afe_loopback_tx_ch_text); + +static bool is_initial_boot; +static bool codec_reg_done; +static struct snd_soc_aux_dev *msm_aux_dev; +static struct snd_soc_codec_conf *msm_codec_conf; +static struct snd_soc_card snd_soc_card_bengal_msm; +static int dmic_0_1_gpio_cnt; +static int dmic_2_3_gpio_cnt; + +static void *def_wcd_mbhc_cal(void); + +/* + * Need to report LINEIN + * if R/L channel impedance is larger than 5K ohm + */ +static struct wcd_mbhc_config wcd_mbhc_cfg = { + .read_fw_bin = false, + .calibration = NULL, + .detect_extn_cable = true, + .mono_stero_detection = false, + .swap_gnd_mic = NULL, + .hs_ext_micbias = true, + .key_code[0] = KEY_MEDIA, + .key_code[1] = KEY_VOICECOMMAND, + .key_code[2] = KEY_VOLUMEUP, + .key_code[3] = KEY_VOLUMEDOWN, + .key_code[4] = 0, + .key_code[5] = 0, + .key_code[6] = 0, + .key_code[7] = 0, + .linein_th = 5000, + .moisture_en = false, + .mbhc_micbias = MIC_BIAS_2, + .anc_micbias = MIC_BIAS_2, + .enable_anc_mic_detect = false, + .moisture_duty_cycle_en = true, +}; + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, + int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, + unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val = 0; + + switch (usb_rx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__, + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_rx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_rx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_rx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val = 0; + + switch (usb_tx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + default: + sample_rate_val = 6; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__, + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 12: + usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + usb_tx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + usb_tx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + usb_tx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_tx_cfg.sample_rate); + return 0; +} +static int afe_loopback_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: afe_loopback_tx_ch = %d\n", __func__, + afe_loopback_tx_cfg[0].channels); + ucontrol->value.enumerated.item[0] = + afe_loopback_tx_cfg[0].channels - 1; + + return 0; +} + +static int afe_loopback_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + afe_loopback_tx_cfg[0].channels = + ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: afe_loopback_tx_ch = %d\n", __func__, + afe_loopback_tx_cfg[0].channels); + + return 1; +} + +static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_rx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_tx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, + usb_rx_cfg.channels); + ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1; + return 0; +} + +static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels); + return 1; +} + +static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, + usb_tx_cfg.channels); + ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1; + return 0; +} + +static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels); + return 1; +} + +static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1; + pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch); + return 1; +} + +static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2; + + return 0; +} + +static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2; + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + + return 1; +} + +static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, + struct tdm_port *port) +{ + if (port) { + if (strnstr(kcontrol->id.name, "PRI", + sizeof(kcontrol->id.name))) { + port->mode = TDM_PRI; + } else if (strnstr(kcontrol->id.name, "SEC", + sizeof(kcontrol->id.name))) { + port->mode = TDM_SEC; + } else if (strnstr(kcontrol->id.name, "TERT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_TERT; + } else if (strnstr(kcontrol->id.name, "QUAT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_QUAT; + } else { + pr_err("%s: unsupported mode in: %s\n", + __func__, kcontrol->id.name); + return -EINVAL; + } + + if (strnstr(kcontrol->id.name, "RX_0", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_0", + sizeof(kcontrol->id.name))) { + port->channel = TDM_0; + } else if (strnstr(kcontrol->id.name, "RX_1", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_1", + sizeof(kcontrol->id.name))) { + port->channel = TDM_1; + } else if (strnstr(kcontrol->id.name, "RX_2", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_2", + sizeof(kcontrol->id.name))) { + port->channel = TDM_2; + } else if (strnstr(kcontrol->id.name, "RX_3", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_3", + sizeof(kcontrol->id.name))) { + port->channel = TDM_3; + } else if (strnstr(kcontrol->id.name, "RX_4", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_4", + sizeof(kcontrol->id.name))) { + port->channel = TDM_4; + } else if (strnstr(kcontrol->id.name, "RX_5", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_5", + sizeof(kcontrol->id.name))) { + port->channel = TDM_5; + } else if (strnstr(kcontrol->id.name, "RX_6", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_6", + sizeof(kcontrol->id.name))) { + port->channel = TDM_6; + } else if (strnstr(kcontrol->id.name, "RX_7", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_7", + sizeof(kcontrol->id.name))) { + port->channel = TDM_7; + } else { + pr_err("%s: unsupported channel in: %s\n", + __func__, kcontrol->id.name); + return -EINVAL; + } + } else { + return -EINVAL; + } + return 0; +} + +static int tdm_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int tdm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 5; + break; + default: + sample_rate_val = 3; + break; + } + return sample_rate_val; +} + +static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_rx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_tx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_get_format(int value) +{ + int format = 0; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int tdm_get_format_val(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 2; + break; + default: + value = 0; + break; + } + return value; +} + +static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_rx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_tx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + + ucontrol->value.enumerated.item[0] = + tdm_rx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = + tdm_tx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx = 0; + + if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", + sizeof("PRIM_AUX_PCM"))) { + idx = PRIM_AUX_PCM; + } else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM", + sizeof("SEC_AUX_PCM"))) { + idx = SEC_AUX_PCM; + } else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", + sizeof("TERT_AUX_PCM"))) { + idx = TERT_AUX_PCM; + } else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", + sizeof("QUAT_AUX_PCM"))) { + idx = QUAT_AUX_PCM; + } else { + pr_err("%s: unsupported port: %s\n", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int aux_pcm_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 0: + default: + sample_rate = SAMPLING_RATE_8KHZ; + break; + } + return sample_rate; +} + +static int aux_pcm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + return sample_rate_val; +} + +static int mi2s_auxpcm_get_format(int value) +{ + int format = 0; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int mi2s_auxpcm_get_format_value(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + value = 2; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 3; + break; + default: + value = 0; + break; + } + return value; +} + +static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(aux_pcm_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(aux_pcm_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx = 0; + + if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX", + sizeof("PRIM_MI2S_RX"))) { + idx = PRIM_MI2S; + } else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX", + sizeof("SEC_MI2S_RX"))) { + idx = SEC_MI2S; + } else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", + sizeof("TERT_MI2S_RX"))) { + idx = TERT_MI2S; + } else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", + sizeof("QUAT_MI2S_RX"))) { + idx = QUAT_MI2S; + } else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", + sizeof("PRIM_MI2S_TX"))) { + idx = PRIM_MI2S; + } else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX", + sizeof("SEC_MI2S_TX"))) { + idx = SEC_MI2S; + } else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", + sizeof("TERT_MI2S_TX"))) { + idx = TERT_MI2S; + } else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", + sizeof("QUAT_MI2S_TX"))) { + idx = QUAT_MI2S; + } else { + pr_err("%s: unsupported channel: %s\n", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int mi2s_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_192KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int mi2s_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + default: + sample_rate_val = 6; + break; + } + return sample_rate_val; +} + +static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(mi2s_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_auxpcm_get_format_value(mi2s_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].bit_format = + mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} +static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + + return 1; +} + +static int msm_get_port_id(int be_id) +{ + int afe_port_id = 0; + + switch (be_id) { + case MSM_BACKEND_DAI_PRI_MI2S_RX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_PRI_MI2S_TX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: + afe_port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0; + break; + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: + afe_port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_1; + break; + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2: + afe_port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_2; + break; + default: + pr_err("%s: Invalid BE id: %d\n", __func__, be_id); + afe_port_id = -EINVAL; + } + + return afe_port_id; +} + +static u32 get_mi2s_bits_per_sample(u32 bit_format) +{ + u32 bit_per_sample = 0; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + case SNDRV_PCM_FORMAT_S24_LE: + bit_per_sample = 32; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bit_per_sample = 16; + break; + } + + return bit_per_sample; +} + +static void update_mi2s_clk_val(int dai_id, int stream) +{ + u32 bit_per_sample = 0; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } else { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } +} + +static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int port_id = 0; + int index = cpu_dai->id; + + port_id = msm_get_port_id(rtd->dai_link->id); + if (port_id < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto err; + } + + if (enable) { + update_mi2s_clk_val(index, substream->stream); + dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, + mi2s_clk[index].clk_freq_in_hz); + } + + mi2s_clk[index].enable = enable; + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_clk[index]); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed for port 0x%x , err:%d\n", + __func__, port_id, ret); + goto err; + } + +err: + return ret; +} + +static int cdc_dma_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx = 0; + + if (strnstr(kcontrol->id.name, "RX_CDC_DMA_RX_0", + sizeof("RX_CDC_DMA_RX_0"))) + idx = RX_CDC_DMA_RX_0; + else if (strnstr(kcontrol->id.name, "RX_CDC_DMA_RX_1", + sizeof("RX_CDC_DMA_RX_1"))) + idx = RX_CDC_DMA_RX_1; + else if (strnstr(kcontrol->id.name, "RX_CDC_DMA_RX_2", + sizeof("RX_CDC_DMA_RX_2"))) + idx = RX_CDC_DMA_RX_2; + else if (strnstr(kcontrol->id.name, "RX_CDC_DMA_RX_3", + sizeof("RX_CDC_DMA_RX_3"))) + idx = RX_CDC_DMA_RX_3; + else if (strnstr(kcontrol->id.name, "RX_CDC_DMA_RX_5", + sizeof("RX_CDC_DMA_RX_5"))) + idx = RX_CDC_DMA_RX_5; + else if (strnstr(kcontrol->id.name, "TX_CDC_DMA_TX_0", + sizeof("TX_CDC_DMA_TX_0"))) + idx = TX_CDC_DMA_TX_0; + else if (strnstr(kcontrol->id.name, "TX_CDC_DMA_TX_3", + sizeof("TX_CDC_DMA_TX_3"))) + idx = TX_CDC_DMA_TX_3; + else if (strnstr(kcontrol->id.name, "TX_CDC_DMA_TX_4", + sizeof("TX_CDC_DMA_TX_4"))) + idx = TX_CDC_DMA_TX_4; + else if (strnstr(kcontrol->id.name, "VA_CDC_DMA_TX_0", + sizeof("VA_CDC_DMA_TX_0"))) + idx = VA_CDC_DMA_TX_0; + else if (strnstr(kcontrol->id.name, "VA_CDC_DMA_TX_1", + sizeof("VA_CDC_DMA_TX_1"))) + idx = VA_CDC_DMA_TX_1; + else if (strnstr(kcontrol->id.name, "VA_CDC_DMA_TX_2", + sizeof("VA_CDC_DMA_TX_2"))) + idx = VA_CDC_DMA_TX_2; + else { + pr_err("%s: unsupported channel: %s\n", + __func__, kcontrol->id.name); + return -EINVAL; + } + + return idx; +} + +static int cdc_dma_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0 || ch_num >= CDC_DMA_RX_MAX) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + pr_debug("%s: cdc_dma_rx_ch = %d\n", __func__, + cdc_dma_rx_cfg[ch_num].channels - 1); + ucontrol->value.integer.value[0] = cdc_dma_rx_cfg[ch_num].channels - 1; + return 0; +} + +static int cdc_dma_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0 || ch_num >= CDC_DMA_RX_MAX) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + cdc_dma_rx_cfg[ch_num].channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: cdc_dma_rx_ch = %d\n", __func__, + cdc_dma_rx_cfg[ch_num].channels); + return 1; +} + +static int cdc_dma_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0 || ch_num >= CDC_DMA_RX_MAX) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + switch (cdc_dma_rx_cfg[ch_num].bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: cdc_dma_rx_format = %d, ucontrol value = %ld\n", + __func__, cdc_dma_rx_cfg[ch_num].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int cdc_dma_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0 || ch_num >= CDC_DMA_RX_MAX) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + switch (ucontrol->value.integer.value[0]) { + case 3: + cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + cdc_dma_rx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: cdc_dma_rx_format = %d, ucontrol value = %ld\n", + __func__, cdc_dma_rx_cfg[ch_num].bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + + +static int cdc_dma_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + default: + sample_rate_val = 6; + break; + } + return sample_rate_val; +} + +static int cdc_dma_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 9: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 10: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 11: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 12: + sample_rate = SAMPLING_RATE_384KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int cdc_dma_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0 || ch_num >= CDC_DMA_RX_MAX) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + ucontrol->value.enumerated.item[0] = + cdc_dma_get_sample_rate_val(cdc_dma_rx_cfg[ch_num].sample_rate); + + pr_debug("%s: cdc_dma_rx_sample_rate = %d\n", __func__, + cdc_dma_rx_cfg[ch_num].sample_rate); + return 0; +} + +static int cdc_dma_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0 || ch_num >= CDC_DMA_RX_MAX) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + cdc_dma_rx_cfg[ch_num].sample_rate = + cdc_dma_get_sample_rate(ucontrol->value.enumerated.item[0]); + + + pr_debug("%s: control value = %d, cdc_dma_rx_sample_rate = %d\n", + __func__, ucontrol->value.enumerated.item[0], + cdc_dma_rx_cfg[ch_num].sample_rate); + return 0; +} + +static int cdc_dma_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + pr_debug("%s: cdc_dma_tx_ch = %d\n", __func__, + cdc_dma_tx_cfg[ch_num].channels); + ucontrol->value.integer.value[0] = cdc_dma_tx_cfg[ch_num].channels - 1; + return 0; +} + +static int cdc_dma_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + cdc_dma_tx_cfg[ch_num].channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: cdc_dma_tx_ch = %d\n", __func__, + cdc_dma_tx_cfg[ch_num].channels); + return 1; +} + +static int cdc_dma_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + switch (cdc_dma_tx_cfg[ch_num].sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 12; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 11; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 10; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + default: + sample_rate_val = 6; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: cdc_dma_tx_sample_rate = %d\n", __func__, + cdc_dma_tx_cfg[ch_num].sample_rate); + return 0; +} + +static int cdc_dma_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + switch (ucontrol->value.integer.value[0]) { + case 12: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_384KHZ; + break; + case 11: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + cdc_dma_tx_cfg[ch_num].sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, cdc_dma_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + cdc_dma_tx_cfg[ch_num].sample_rate); + return 0; +} + +static int cdc_dma_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + switch (cdc_dma_tx_cfg[ch_num].bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: cdc_dma_tx_format = %d, ucontrol value = %ld\n", + __func__, cdc_dma_tx_cfg[ch_num].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int cdc_dma_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + int ch_num = cdc_dma_get_port_idx(kcontrol); + + if (ch_num < 0) { + pr_err("%s: ch_num: %d is invalid\n", __func__, ch_num); + return ch_num; + } + + switch (ucontrol->value.integer.value[0]) { + case 3: + cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + cdc_dma_tx_cfg[ch_num].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: cdc_dma_tx_format = %d, ucontrol value = %ld\n", + __func__, cdc_dma_tx_cfg[ch_num].bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int msm_cdc_dma_get_idx_from_beid(int32_t be_id) +{ + int idx = 0; + + switch (be_id) { + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_0: + idx = RX_CDC_DMA_RX_0; + break; + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_1: + idx = RX_CDC_DMA_RX_1; + break; + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_2: + idx = RX_CDC_DMA_RX_2; + break; + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_3: + idx = RX_CDC_DMA_RX_3; + break; + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_5: + idx = RX_CDC_DMA_RX_5; + break; + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_0: + idx = TX_CDC_DMA_TX_0; + break; + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_3: + idx = TX_CDC_DMA_TX_3; + break; + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_4: + idx = TX_CDC_DMA_TX_4; + break; + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: + idx = VA_CDC_DMA_TX_0; + break; + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: + idx = VA_CDC_DMA_TX_1; + break; + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2: + idx = VA_CDC_DMA_TX_2; + break; + default: + idx = RX_CDC_DMA_RX_0; + break; + } + + return idx; +} + +static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* + * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) + * when used for BT_SCO use case. Return either Rx or Tx sample rate + * value. + */ + switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate = %d\n", __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n", + __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate, + slim_tx_cfg[SLIM_TX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_bt_sample_rate_rx_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate rx = %d\n", __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_rx_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rate: slim7_rx = %d, value = %d\n", + __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_bt_sample_rate_tx_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (slim_tx_cfg[SLIM_TX_7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate tx = %d\n", __func__, + slim_tx_cfg[SLIM_TX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_tx_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rate: slim7_tx = %d, value = %d\n", + __func__, + slim_tx_cfg[SLIM_TX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static const struct snd_kcontrol_new msm_int_snd_controls[] = { + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 Channels", rx_cdc_dma_rx_0_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 Channels", rx_cdc_dma_rx_1_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 Channels", rx_cdc_dma_rx_2_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 Channels", rx_cdc_dma_rx_3_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 Channels", rx_cdc_dma_rx_5_chs, + cdc_dma_rx_ch_get, cdc_dma_rx_ch_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_0 Channels", tx_cdc_dma_tx_0_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_3 Channels", tx_cdc_dma_tx_3_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_4 Channels", tx_cdc_dma_tx_4_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_0 Channels", va_cdc_dma_tx_0_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_1 Channels", va_cdc_dma_tx_1_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_2 Channels", va_cdc_dma_tx_2_chs, + cdc_dma_tx_ch_get, cdc_dma_tx_ch_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 Format", rx_cdc_dma_rx_0_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 Format", rx_cdc_dma_rx_1_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 Format", rx_cdc_dma_rx_2_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 Format", rx_cdc_dma_rx_3_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 Format", rx_cdc_dma_rx_5_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_0 Format", tx_cdc_dma_tx_0_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_3 Format", tx_cdc_dma_tx_3_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_4 Format", tx_cdc_dma_tx_4_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_0 Format", va_cdc_dma_tx_0_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_1 Format", va_cdc_dma_tx_1_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_2 Format", va_cdc_dma_tx_2_format, + cdc_dma_tx_format_get, cdc_dma_tx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 SampleRate", + rx_cdc_dma_rx_0_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 SampleRate", + rx_cdc_dma_rx_1_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 SampleRate", + rx_cdc_dma_rx_2_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 SampleRate", + rx_cdc_dma_rx_3_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 SampleRate", + rx_cdc_dma_rx_5_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_0 SampleRate", + tx_cdc_dma_tx_0_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_3 SampleRate", + tx_cdc_dma_tx_3_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("TX_CDC_DMA_TX_4 SampleRate", + tx_cdc_dma_tx_4_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_0 SampleRate", + va_cdc_dma_tx_0_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_1 SampleRate", + va_cdc_dma_tx_1_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), + SOC_ENUM_EXT("VA_CDC_DMA_TX_2 SampleRate", + va_cdc_dma_tx_2_sample_rate, + cdc_dma_tx_sample_rate_get, + cdc_dma_tx_sample_rate_put), +}; + +static const struct snd_kcontrol_new msm_common_snd_controls[] = { + SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, + usb_audio_rx_sample_rate_get, + usb_audio_rx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, + usb_audio_tx_sample_rate_get, + usb_audio_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, + usb_audio_rx_format_get, usb_audio_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, + usb_audio_tx_format_get, usb_audio_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("TERT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Format", mi2s_rx_format, + msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("SEC_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("TERT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Format", mi2s_tx_format, + msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), + SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, + usb_audio_rx_ch_get, usb_audio_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, + usb_audio_tx_ch_get, usb_audio_tx_ch_put), + SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, + proxy_rx_ch_get, proxy_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), + SOC_ENUM_EXT("BT SampleRate RX", bt_sample_rate_rx, + msm_bt_sample_rate_rx_get, + msm_bt_sample_rate_rx_put), + SOC_ENUM_EXT("BT SampleRate TX", bt_sample_rate_tx, + msm_bt_sample_rate_tx_get, + msm_bt_sample_rate_tx_put), + SOC_ENUM_EXT("AFE_LOOPBACK_TX Channels", afe_loopback_tx_chs, + afe_loopback_tx_ch_get, afe_loopback_tx_ch_put), + SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, + msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), +}; + +static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), +}; + +static int bengal_send_island_va_config(int32_t be_id) +{ + int rc = 0; + int port_id = 0xFFFF; + + port_id = msm_get_port_id(be_id); + if (port_id < 0) { + pr_err("%s: Invalid island interface, be_id: %d\n", + __func__, be_id); + rc = -EINVAL; + } else { + /* + * send island mode config + * This should be the first configuration + */ + rc = afe_send_port_island_mode(port_id); + if (rc) + pr_err("%s: afe send island mode failed %d\n", + __func__, rc); + } + + return rc; +} + +static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int idx = 0; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->id) { + case MSM_BACKEND_DAI_USB_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_rx_cfg.bit_format); + rate->min = rate->max = usb_rx_cfg.sample_rate; + channels->min = channels->max = usb_rx_cfg.channels; + break; + + case MSM_BACKEND_DAI_USB_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_tx_cfg.bit_format); + rate->min = rate->max = usb_tx_cfg.sample_rate; + channels->min = channels->max = usb_tx_cfg.channels; + break; + + case MSM_BACKEND_DAI_AFE_PCM_RX: + channels->min = channels->max = proxy_rx_cfg.channels; + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + + case MSM_BACKEND_DAI_PRI_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_PRI_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[PRIM_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[SEC_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[SEC_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[TERT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[TERT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_rx_cfg[QUAT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + aux_pcm_tx_cfg[QUAT_AUX_PCM].bit_format); + rate->min = rate->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[PRIM_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[PRIM_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[SEC_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[SEC_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[TERT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[TERT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUAT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUAT_MI2S].bit_format); + rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUAT_MI2S].channels; + break; + + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_0: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_1: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_2: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_3: + idx = msm_cdc_dma_get_idx_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + cdc_dma_rx_cfg[idx].bit_format); + rate->min = rate->max = cdc_dma_rx_cfg[idx].sample_rate; + channels->min = channels->max = cdc_dma_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_0: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_3: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_4: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2: + idx = msm_cdc_dma_get_idx_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + cdc_dma_tx_cfg[idx].bit_format); + rate->min = rate->max = cdc_dma_tx_cfg[idx].sample_rate; + channels->min = channels->max = cdc_dma_tx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[SLIM_RX_7].bit_format); + rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate; + channels->min = channels->max = + slim_rx_cfg[SLIM_RX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_8_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_8].channels; + break; + + case MSM_BACKEND_DAI_AFE_LOOPBACK_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + afe_loopback_tx_cfg[idx].bit_format); + rate->min = rate->max = afe_loopback_tx_cfg[idx].sample_rate; + channels->min = channels->max = + afe_loopback_tx_cfg[idx].channels; + break; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + + return 0; +} + +static bool msm_usbc_swap_gnd_mic(struct snd_soc_component *component, + bool active) +{ + struct snd_soc_card *card = component->card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + + if (!pdata->fsa_handle) + return false; + + return fsa4480_switch_event(pdata->fsa_handle, FSA_MIC_GND_SWAP); +} + +static bool msm_swap_gnd_mic(struct snd_soc_component *component, bool active) +{ + int value = 0; + bool ret = false; + struct snd_soc_card *card; + struct msm_asoc_mach_data *pdata; + + if (!component) { + pr_err("%s component is NULL\n", __func__); + return false; + } + card = component->card; + pdata = snd_soc_card_get_drvdata(card); + + if (!pdata) + return false; + + if (wcd_mbhc_cfg.enable_usbc_analog) + return msm_usbc_swap_gnd_mic(component, active); + + /* if usbc is not defined, swap using us_euro_gpio_p */ + if (pdata->us_euro_gpio_p) { + value = msm_cdc_pinctrl_get_state( + pdata->us_euro_gpio_p); + if (value) + msm_cdc_pinctrl_select_sleep_state( + pdata->us_euro_gpio_p); + else + msm_cdc_pinctrl_select_active_state( + pdata->us_euro_gpio_p); + dev_dbg(component->dev, "%s: swap select switch %d to %d\n", + __func__, value, !value); + ret = true; + } + + return ret; +} + +static int bengal_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + int slot_width = 32; + int channels, slots; + unsigned int slot_mask, rate, clk_freq; + unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; + + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + slots = tdm_rx_cfg[TDM_PRI][TDM_0].channels; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + slots = tdm_rx_cfg[TDM_SEC][TDM_0].channels; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + slots = tdm_rx_cfg[TDM_TERT][TDM_0].channels; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX: + slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX: + slots = tdm_tx_cfg[TDM_SEC][TDM_0].channels; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX: + slots = tdm_tx_cfg[TDM_TERT][TDM_0].channels; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + break; + + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + /*2 slot config - bits 0 and 1 set for the first two slots */ + slot_mask = 0x0000FFFF >> (16 - slots); + channels = slots; + + pr_debug("%s: tdm rx slot_width %d slots %d\n", + __func__, slot_width, slots); + + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm rx slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + 0, NULL, channels, slot_offset); + if (ret < 0) { + pr_err("%s: failed to set tdm rx channel map, err:%d\n", + __func__, ret); + goto end; + } + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + /*2 slot config - bits 0 and 1 set for the first two slots */ + slot_mask = 0x0000FFFF >> (16 - slots); + channels = slots; + + pr_debug("%s: tdm tx slot_width %d slots %d\n", + __func__, slot_width, slots); + + ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm tx slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, + channels, slot_offset, 0, NULL); + if (ret < 0) { + pr_err("%s: failed to set tdm tx channel map, err:%d\n", + __func__, ret); + goto end; + } + } else { + ret = -EINVAL; + pr_err("%s: invalid use case, err:%d\n", + __func__, ret); + goto end; + } + + rate = params_rate(params); + clk_freq = rate * slot_width * slots; + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, clk_freq, SND_SOC_CLOCK_OUT); + if (ret < 0) + pr_err("%s: failed to set tdm clk, err:%d\n", + __func__, ret); + +end: + return ret; +} + +static int msm_get_tdm_mode(u32 port_id) +{ + int tdm_mode; + + switch (port_id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_TX: + tdm_mode = TDM_PRI; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_TX: + tdm_mode = TDM_SEC; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_TX: + tdm_mode = TDM_TERT; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + tdm_mode = TDM_QUAT; + break; + default: + pr_err("%s: Invalid port id: %d\n", __func__, port_id); + tdm_mode = -EINVAL; + } + return tdm_mode; +} + +static int bengal_tdm_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + int tdm_mode = msm_get_tdm_mode(cpu_dai->id); + + if (tdm_mode >= TDM_INTERFACE_MAX || tdm_mode < 0) { + ret = -EINVAL; + pr_err("%s: Invalid TDM interface %d\n", + __func__, ret); + return ret; + } + + if (pdata->mi2s_gpio_p[tdm_mode]) { + if (atomic_read(&(pdata->mi2s_gpio_ref_count[tdm_mode])) + == 0) { + ret = msm_cdc_pinctrl_select_active_state( + pdata->mi2s_gpio_p[tdm_mode]); + if (ret) { + pr_err("%s: TDM GPIO pinctrl set active failed with %d\n", + __func__, ret); + goto done; + } + } + atomic_inc(&(pdata->mi2s_gpio_ref_count[tdm_mode])); + } + +done: + return ret; +} + +static void bengal_tdm_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + int tdm_mode = msm_get_tdm_mode(cpu_dai->id); + + if (tdm_mode >= TDM_INTERFACE_MAX || tdm_mode < 0) { + ret = -EINVAL; + pr_err("%s: Invalid TDM interface %d\n", + __func__, ret); + return; + } + + if (pdata->mi2s_gpio_p[tdm_mode]) { + atomic_dec(&(pdata->mi2s_gpio_ref_count[tdm_mode])); + if (atomic_read(&(pdata->mi2s_gpio_ref_count[tdm_mode])) + == 0) { + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->mi2s_gpio_p[tdm_mode]); + if (ret) + pr_err("%s: TDM GPIO pinctrl set sleep failed with %d\n", + __func__, ret); + } + } +} + +static int bengal_aux_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + u32 aux_mode = cpu_dai->id - 1; + + if (aux_mode >= AUX_PCM_MAX) { + ret = -EINVAL; + pr_err("%s: Invalid AUX interface %d\n", + __func__, ret); + return ret; + } + + if (pdata->mi2s_gpio_p[aux_mode]) { + if (atomic_read(&(pdata->mi2s_gpio_ref_count[aux_mode])) + == 0) { + ret = msm_cdc_pinctrl_select_active_state( + pdata->mi2s_gpio_p[aux_mode]); + if (ret) { + pr_err("%s: AUX GPIO pinctrl set active failed with %d\n", + __func__, ret); + goto done; + } + } + atomic_inc(&(pdata->mi2s_gpio_ref_count[aux_mode])); + } + +done: + return ret; +} + +static void bengal_aux_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + u32 aux_mode = cpu_dai->id - 1; + + if (aux_mode >= AUX_PCM_MAX) { + pr_err("%s: Invalid AUX interface %d\n", + __func__, ret); + return; + } + + if (pdata->mi2s_gpio_p[aux_mode]) { + atomic_dec(&(pdata->mi2s_gpio_ref_count[aux_mode])); + if (atomic_read(&(pdata->mi2s_gpio_ref_count[aux_mode])) + == 0) { + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->mi2s_gpio_p[aux_mode]); + if (ret) + pr_err("%s: AUX GPIO pinctrl set sleep failed with %d\n", + __func__, ret); + } + } +} + +static int msm_snd_cdc_dma_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + switch (dai_link->id) { + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2: + ret = bengal_send_island_va_config(dai_link->id); + if (ret) + pr_err("%s: send island va cfg failed, err: %d\n", + __func__, ret); + break; + } + + return ret; +} + +static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + int ret = 0; + u32 rx_ch_cdc_dma, tx_ch_cdc_dma; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + u32 user_set_tx_ch = 0; + u32 user_set_rx_ch = 0; + u32 ch_id; + + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, &tx_ch_cdc_dma, &rx_ch_cnt, + &rx_ch_cdc_dma); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + switch (dai_link->id) { + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_0: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_1: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_2: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_3: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_4: + case MSM_BACKEND_DAI_RX_CDC_DMA_RX_5: + { + ch_id = msm_cdc_dma_get_idx_from_beid(dai_link->id); + pr_debug("%s: id %d rx_ch=%d\n", __func__, + ch_id, cdc_dma_rx_cfg[ch_id].channels); + user_set_rx_ch = cdc_dma_rx_cfg[ch_id].channels; + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + user_set_rx_ch, &rx_ch_cdc_dma); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + + } + break; + } + } else { + switch (dai_link->id) { + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_0: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_3: + case MSM_BACKEND_DAI_TX_CDC_DMA_TX_4: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: + case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2: + { + ch_id = msm_cdc_dma_get_idx_from_beid(dai_link->id); + pr_debug("%s: id %d tx_ch=%d\n", __func__, + ch_id, cdc_dma_tx_cfg[ch_id].channels); + user_set_tx_ch = cdc_dma_tx_cfg[ch_id].channels; + } + break; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, user_set_tx_ch, + &tx_ch_cdc_dma, 0, 0); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err; + } + } + +err: + return ret; +} + +static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) +{ + cpumask_t mask; + + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + + cpumask_clear(&mask); + cpumask_set_cpu(1, &mask); /* affine to core 1 */ + cpumask_set_cpu(2, &mask); /* affine to core 2 */ + cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); + + substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; + + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + MSM_LL_QOS_VALUE); + return 0; +} + +static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int index = cpu_dai->id; + unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + if (index < PRIM_MI2S || index >= MI2S_MAX) { + ret = -EINVAL; + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto err; + } + /* + * Mutex protection in case the same MI2S + * interface using for both TX and RX so + * that the same clock won't be enable twice. + */ + mutex_lock(&mi2s_intf_conf[index].lock); + if (++mi2s_intf_conf[index].ref_cnt == 1) { + /* Check if msm needs to provide the clock to the interface */ + if (!mi2s_intf_conf[index].msm_is_mi2s_master) { + mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; + fmt = SND_SOC_DAIFMT_CBM_CFM; + } + ret = msm_mi2s_set_sclk(substream, true); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed to enable MI2S clock, err:%d\n", + __func__, ret); + goto clean_up; + } + + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) { + pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n", + __func__, index, ret); + goto clk_off; + } + if (pdata->mi2s_gpio_p[index]) { + if (atomic_read(&(pdata->mi2s_gpio_ref_count[index])) + == 0) { + ret = msm_cdc_pinctrl_select_active_state( + pdata->mi2s_gpio_p[index]); + if (ret) { + pr_err("%s: MI2S GPIO pinctrl set active failed with %d\n", + __func__, ret); + goto clk_off; + } + } + atomic_inc(&(pdata->mi2s_gpio_ref_count[index])); + } + } +clk_off: + if (ret < 0) + msm_mi2s_set_sclk(substream, false); +clean_up: + if (ret < 0) + mi2s_intf_conf[index].ref_cnt--; + mutex_unlock(&mi2s_intf_conf[index].lock); +err: + return ret; +} + +static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int index = rtd->cpu_dai->id; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + if (index < PRIM_MI2S || index >= MI2S_MAX) { + pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); + return; + } + + mutex_lock(&mi2s_intf_conf[index].lock); + if (--mi2s_intf_conf[index].ref_cnt == 0) { + if (pdata->mi2s_gpio_p[index]) { + atomic_dec(&(pdata->mi2s_gpio_ref_count[index])); + if (atomic_read(&(pdata->mi2s_gpio_ref_count[index])) + == 0) { + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->mi2s_gpio_p[index]); + if (ret) + pr_err("%s: MI2S GPIO pinctrl set sleep failed with %d\n", + __func__, ret); + } + } + + ret = msm_mi2s_set_sclk(substream, false); + if (ret < 0) + pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", + __func__, index, ret); + } + mutex_unlock(&mi2s_intf_conf[index].lock); +} + +static int msm_wcn_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + int ret = 0; + + dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret) { + dev_err(rtd->dev, + "%s: failed to get BTFM codec chan map\n, err:%d\n", + __func__, ret); + goto err; + } + + dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) BE id %d\n", + __func__, tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); + if (ret) + dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + +err: + return ret; +} + +static struct snd_soc_ops bengal_aux_be_ops = { + .startup = bengal_aux_snd_startup, + .shutdown = bengal_aux_snd_shutdown +}; + +static struct snd_soc_ops bengal_tdm_be_ops = { + .hw_params = bengal_tdm_snd_hw_params, + .startup = bengal_tdm_snd_startup, + .shutdown = bengal_tdm_snd_shutdown +}; + +static struct snd_soc_ops msm_mi2s_be_ops = { + .startup = msm_mi2s_snd_startup, + .shutdown = msm_mi2s_snd_shutdown, +}; + +static struct snd_soc_ops msm_fe_qos_ops = { + .prepare = msm_fe_qos_prepare, +}; + +static struct snd_soc_ops msm_cdc_dma_be_ops = { + .startup = msm_snd_cdc_dma_startup, + .hw_params = msm_snd_cdc_dma_hw_params, +}; + +static struct snd_soc_ops msm_wcn_ops = { + .hw_params = msm_wcn_hw_params, +}; + +static int msm_dmic_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct msm_asoc_mach_data *pdata = NULL; + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + int ret = 0; + u32 dmic_idx; + int *dmic_gpio_cnt; + struct device_node *dmic_gpio; + char *wname; + + wname = strpbrk(w->name, "0123"); + if (!wname) { + dev_err(component->dev, "%s: widget not found\n", __func__); + return -EINVAL; + } + + ret = kstrtouint(wname, 10, &dmic_idx); + if (ret < 0) { + dev_err(component->dev, "%s: Invalid DMIC line on the codec\n", + __func__); + return -EINVAL; + } + + pdata = snd_soc_card_get_drvdata(component->card); + + switch (dmic_idx) { + case 0: + case 1: + dmic_gpio_cnt = &dmic_0_1_gpio_cnt; + dmic_gpio = pdata->dmic01_gpio_p; + break; + case 2: + case 3: + dmic_gpio_cnt = &dmic_2_3_gpio_cnt; + dmic_gpio = pdata->dmic23_gpio_p; + break; + default: + dev_err(component->dev, "%s: Invalid DMIC Selection\n", + __func__); + return -EINVAL; + } + + dev_dbg(component->dev, "%s: event %d DMIC%d dmic_gpio_cnt %d\n", + __func__, event, dmic_idx, *dmic_gpio_cnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + (*dmic_gpio_cnt)++; + if (*dmic_gpio_cnt == 1) { + ret = msm_cdc_pinctrl_select_active_state( + dmic_gpio); + if (ret < 0) { + pr_err("%s: gpio set cannot be activated %sd", + __func__, "dmic_gpio"); + return ret; + } + } + + break; + case SND_SOC_DAPM_POST_PMD: + (*dmic_gpio_cnt)--; + if (*dmic_gpio_cnt == 0) { + ret = msm_cdc_pinctrl_select_sleep_state( + dmic_gpio); + if (ret < 0) { + pr_err("%s: gpio set cannot be de-activated %sd", + __func__, "dmic_gpio"); + return ret; + } + } + break; + default: + pr_err("%s: invalid DAPM event %d\n", __func__, event); + return -EINVAL; + } + return 0; +} + +static const struct snd_soc_dapm_widget msm_int_dapm_widgets[] = { + SND_SOC_DAPM_MIC("Analog Mic1", NULL), + SND_SOC_DAPM_MIC("Analog Mic2", NULL), + SND_SOC_DAPM_MIC("Analog Mic3", NULL), + SND_SOC_DAPM_MIC("Analog Mic4", NULL), + SND_SOC_DAPM_MIC("Digital Mic0", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic1", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic2", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic3", msm_dmic_event), +}; + +static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) +{ + unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; + unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); +} + +static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = -EINVAL; + struct snd_soc_component *component; + struct snd_soc_dapm_context *dapm; + struct snd_card *card; + struct snd_info_entry *entry; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); + + component = snd_soc_rtdcom_lookup(rtd, "bolero_codec"); + if (!component) { + pr_err("%s: could not find component for bolero_codec\n", + __func__); + return ret; + } + + dapm = snd_soc_component_get_dapm(component); + + ret = snd_soc_add_component_controls(component, msm_int_snd_controls, + ARRAY_SIZE(msm_int_snd_controls)); + if (ret < 0) { + pr_err("%s: add_component_controls failed: %d\n", + __func__, ret); + return ret; + } + ret = snd_soc_add_component_controls(component, msm_common_snd_controls, + ARRAY_SIZE(msm_common_snd_controls)); + if (ret < 0) { + pr_err("%s: add common snd controls failed: %d\n", + __func__, ret); + return ret; + } + + snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets, + ARRAY_SIZE(msm_int_dapm_widgets)); + + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); + + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic2"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic3"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4"); + + snd_soc_dapm_sync(dapm); + + bolero_set_port_map(component, ARRAY_SIZE(sm_port_map), + sm_port_map); + card = rtd->card->snd_card; + if (!pdata->codec_root) { + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto err; + } + pdata->codec_root = entry; + } + bolero_info_create_codec_entry(pdata->codec_root, component); + bolero_register_wake_irq(component, false); + codec_reg_done = true; + return 0; +err: + return ret; +} + +static void *def_wcd_mbhc_cal(void) +{ + void *wcd_mbhc_cal; + struct wcd_mbhc_btn_detect_cfg *btn_cfg; + u16 *btn_high; + + wcd_mbhc_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, + WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); + if (!wcd_mbhc_cal) + return NULL; + + WCD_MBHC_CAL_PLUG_TYPE_PTR(wcd_mbhc_cal)->v_hs_max = WCD_MBHC_HS_V_MAX; + WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal)->num_btn = WCD_MBHC_DEF_BUTTONS; + btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal); + btn_high = ((void *)&btn_cfg->_v_btn_low) + + (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); + + btn_high[0] = 75; + btn_high[1] = 150; + btn_high[2] = 237; + btn_high[3] = 500; + btn_high[4] = 500; + btn_high[5] = 500; + btn_high[6] = 500; + btn_high[7] = 500; + + return wcd_mbhc_cal; +} + +/* Digital audio interface glue - connects codec <---> CPU */ +static struct snd_soc_dai_link msm_common_dai_links[] = { + /* FrontEnd DAI Links */ + {/* hw:x,0 */ + .name = MSM_DAILINK_NAME(Media1), + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, + {/* hw:x,1 */ + .name = MSM_DAILINK_NAME(Media2), + .stream_name = "MultiMedia2", + .cpu_dai_name = "MultiMedia2", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, + }, + {/* hw:x,2 */ + .name = "VoiceMMode1", + .stream_name = "VoiceMMode1", + .cpu_dai_name = "VoiceMMode1", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE1, + }, + {/* hw:x,3 */ + .name = "MSM VoIP", + .stream_name = "VoIP", + .cpu_dai_name = "VoIP", + .platform_name = "msm-voip-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_VOIP, + }, + {/* hw:x,4 */ + .name = MSM_DAILINK_NAME(ULL), + .stream_name = "MultiMedia3", + .cpu_dai_name = "MultiMedia3", + .platform_name = "msm-pcm-dsp.2", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA3, + }, + {/* hw:x,5 */ + .name = "MSM AFE-PCM RX", + .stream_name = "AFE-PROXY RX", + .cpu_dai_name = "msm-dai-q6-dev.241", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .platform_name = "msm-pcm-afe", + .dpcm_playback = 1, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + }, + {/* hw:x,6 */ + .name = "MSM AFE-PCM TX", + .stream_name = "AFE-PROXY TX", + .cpu_dai_name = "msm-dai-q6-dev.240", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .platform_name = "msm-pcm-afe", + .dpcm_capture = 1, + .ignore_suspend = 1, + }, + {/* hw:x,7 */ + .name = MSM_DAILINK_NAME(Compress1), + .stream_name = "Compress1", + .cpu_dai_name = "MultiMedia4", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA4, + }, + /* Hostless PCM purpose */ + {/* hw:x,8 */ + .name = "AUXPCM Hostless", + .stream_name = "AUXPCM Hostless", + .cpu_dai_name = "AUXPCM_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,9 */ + .name = MSM_DAILINK_NAME(LowLatency), + .stream_name = "MultiMedia5", + .cpu_dai_name = "MultiMedia5", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .ops = &msm_fe_qos_ops, + }, + {/* hw:x,10 */ + .name = "Listen 1 Audio Service", + .stream_name = "Listen 1 Audio Service", + .cpu_dai_name = "LSM1", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM1, + }, + /* Multiple Tunnel instances */ + {/* hw:x,11 */ + .name = MSM_DAILINK_NAME(Compress2), + .stream_name = "Compress2", + .cpu_dai_name = "MultiMedia7", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA7, + }, + {/* hw:x,12 */ + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", + .cpu_dai_name = "MultiMedia10", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA10, + }, + {/* hw:x,13 */ + .name = MSM_DAILINK_NAME(ULL_NOIRQ), + .stream_name = "MM_NOIRQ", + .cpu_dai_name = "MultiMedia8", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + .ops = &msm_fe_qos_ops, + }, + /* HDMI Hostless */ + {/* hw:x,14 */ + .name = "HDMI_RX_HOSTLESS", + .stream_name = "HDMI_RX_HOSTLESS", + .cpu_dai_name = "HDMI_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,15 */ + .name = "VoiceMMode2", + .stream_name = "VoiceMMode2", + .cpu_dai_name = "VoiceMMode2", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE2, + }, + /* LSM FE */ + {/* hw:x,16 */ + .name = "Listen 2 Audio Service", + .stream_name = "Listen 2 Audio Service", + .cpu_dai_name = "LSM2", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM2, + }, + {/* hw:x,17 */ + .name = "Listen 3 Audio Service", + .stream_name = "Listen 3 Audio Service", + .cpu_dai_name = "LSM3", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM3, + }, + {/* hw:x,18 */ + .name = "Listen 4 Audio Service", + .stream_name = "Listen 4 Audio Service", + .cpu_dai_name = "LSM4", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM4, + }, + {/* hw:x,19 */ + .name = "Listen 5 Audio Service", + .stream_name = "Listen 5 Audio Service", + .cpu_dai_name = "LSM5", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM5, + }, + {/* hw:x,20 */ + .name = "Listen 6 Audio Service", + .stream_name = "Listen 6 Audio Service", + .cpu_dai_name = "LSM6", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM6, + }, + {/* hw:x,21 */ + .name = "Listen 7 Audio Service", + .stream_name = "Listen 7 Audio Service", + .cpu_dai_name = "LSM7", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM7, + }, + {/* hw:x,22 */ + .name = "Listen 8 Audio Service", + .stream_name = "Listen 8 Audio Service", + .cpu_dai_name = "LSM8", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = { SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM8, + }, + {/* hw:x,23 */ + .name = MSM_DAILINK_NAME(Media9), + .stream_name = "MultiMedia9", + .cpu_dai_name = "MultiMedia9", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA9, + }, + {/* hw:x,24 */ + .name = MSM_DAILINK_NAME(Compress4), + .stream_name = "Compress4", + .cpu_dai_name = "MultiMedia11", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA11, + }, + {/* hw:x,25 */ + .name = MSM_DAILINK_NAME(Compress5), + .stream_name = "Compress5", + .cpu_dai_name = "MultiMedia12", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA12, + }, + {/* hw:x,26 */ + .name = MSM_DAILINK_NAME(Compress6), + .stream_name = "Compress6", + .cpu_dai_name = "MultiMedia13", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA13, + }, + {/* hw:x,27 */ + .name = MSM_DAILINK_NAME(Compress7), + .stream_name = "Compress7", + .cpu_dai_name = "MultiMedia14", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA14, + }, + {/* hw:x,28 */ + .name = MSM_DAILINK_NAME(Compress8), + .stream_name = "Compress8", + .cpu_dai_name = "MultiMedia15", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA15, + }, + {/* hw:x,29 */ + .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), + .stream_name = "MM_NOIRQ_2", + .cpu_dai_name = "MultiMedia16", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dainlink has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA16, + .ops = &msm_fe_qos_ops, + }, + {/* hw:x,30 */ + .name = "CDC_DMA Hostless", + .stream_name = "CDC_DMA Hostless", + .cpu_dai_name = "CDC_DMA_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,31 */ + .name = "TX3_CDC_DMA Hostless", + .stream_name = "TX3_CDC_DMA Hostless", + .cpu_dai_name = "TX3_CDC_DMA_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,32 */ + .name = "Tertiary MI2S TX_Hostless", + .stream_name = "Tertiary MI2S_TX Hostless Capture", + .cpu_dai_name = "TERT_MI2S_TX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +}; + +static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { + {/* hw:x,34 */ + .name = MSM_DAILINK_NAME(ASM Loopback), + .stream_name = "MultiMedia6", + .cpu_dai_name = "MultiMedia6", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA6, + }, + {/* hw:x,35 */ + .name = "USB Audio Hostless", + .stream_name = "USB Audio Hostless", + .cpu_dai_name = "USBAUDIO_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,36 */ + .name = "SLIMBUS_7 Hostless", + .stream_name = "SLIMBUS_7 Hostless", + .cpu_dai_name = "SLIMBUS7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,37 */ + .name = "Compress Capture", + .stream_name = "Compress9", + .cpu_dai_name = "MultiMedia17", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA17, + }, + {/* hw:x,38 */ + .name = "SLIMBUS_8 Hostless", + .stream_name = "SLIMBUS_8 Hostless", + .cpu_dai_name = "SLIMBUS8_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,39 */ + .name = LPASS_BE_TX_CDC_DMA_TX_5, + .stream_name = "TX CDC DMA5 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45115", + .platform_name = "msm-pcm-hostless", + .codec_name = "bolero_codec", + .codec_dai_name = "tx_macro_tx3", + .id = MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_cdc_dma_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_common_be_dai_links[] = { + /* Backend AFE DAI Links */ + { + .name = LPASS_BE_AFE_PCM_RX, + .stream_name = "AFE Playback", + .cpu_dai_name = "msm-dai-q6-dev.224", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AFE_PCM_TX, + .stream_name = "AFE Capture", + .cpu_dai_name = "msm-dai-q6-dev.225", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Uplink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_TX, + .stream_name = "Voice Uplink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32772", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Downlink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_RX, + .stream_name = "Voice Downlink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32771", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music BACK END DAI Link */ + { + .name = LPASS_BE_VOICE_PLAYBACK_TX, + .stream_name = "Voice Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32773", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + /* Incall Music 2 BACK END DAI Link */ + { + .name = LPASS_BE_VOICE2_PLAYBACK_TX, + .stream_name = "Voice2 Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32770", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_RX, + .stream_name = "USB Audio Playback", + .cpu_dai_name = "msm-dai-q6-dev.28672", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .dynamic_be = 1, + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_USB_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_TX, + .stream_name = "USB Audio Capture", + .cpu_dai_name = "msm-dai-q6-dev.28673", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_USB_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_0, + .stream_name = "Primary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36864", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &bengal_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_0, + .stream_name = "Primary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36865", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &bengal_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_0, + .stream_name = "Secondary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36880", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &bengal_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_0, + .stream_name = "Secondary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36881", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &bengal_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_0, + .stream_name = "Tertiary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36896", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &bengal_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_0, + .stream_name = "Tertiary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36897", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &bengal_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_0, + .stream_name = "Quaternary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36912", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &bengal_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_0, + .stream_name = "Quaternary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36913", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &bengal_tdm_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_wcn_btfm_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_7_RX, + .stream_name = "Slimbus7 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16398", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + /* BT codec driver determines capabilities based on + * dai name, bt codecdai name should always contains + * supported usecase information + */ + .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .init = &msm_wcn_init, + .ops = &msm_wcn_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_7_TX, + .stream_name = "Slimbus7 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16399", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_bt_sco_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_8_TX, + .stream_name = "Slimbus8 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16401", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_fm_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_8_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { + { + .name = LPASS_BE_PRI_MI2S_RX, + .stream_name = "Primary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_MI2S_TX, + .stream_name = "Primary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX, + .stream_name = "Secondary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX, + .stream_name = "Secondary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX, + .stream_name = "Tertiary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX, + .stream_name = "Tertiary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX, + .stream_name = "Quaternary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { + /* Primary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_AUXPCM_RX, + .stream_name = "AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &bengal_aux_be_ops, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AUXPCM_TX, + .stream_name = "AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &bengal_aux_be_ops, + .ignore_suspend = 1, + }, + /* Secondary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_SEC_AUXPCM_RX, + .stream_name = "Sec AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &bengal_aux_be_ops, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_AUXPCM_TX, + .stream_name = "Sec AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &bengal_aux_be_ops, + .ignore_suspend = 1, + }, + /* Tertiary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_TERT_AUXPCM_RX, + .stream_name = "Tert AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &bengal_aux_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_AUXPCM_TX, + .stream_name = "Tert AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &bengal_aux_be_ops, + .ignore_suspend = 1, + }, + /* Quaternary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUAT_AUXPCM_RX, + .stream_name = "Quat AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &bengal_aux_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_AUXPCM_TX, + .stream_name = "Quat AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ops = &bengal_aux_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = { + /* RX CDC DMA Backend DAI Links */ + { + .name = LPASS_BE_RX_CDC_DMA_RX_0, + .stream_name = "RX CDC DMA0 Playback", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45104", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "rx_macro_rx1", + .dynamic_be = 1, + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_RX_CDC_DMA_RX_1, + .stream_name = "RX CDC DMA1 Playback", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45106", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "rx_macro_rx2", + .dynamic_be = 1, + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_RX_CDC_DMA_RX_2, + .stream_name = "RX CDC DMA2 Playback", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45108", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "rx_macro_rx3", + .dynamic_be = 1, + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_RX_CDC_DMA_RX_3, + .stream_name = "RX CDC DMA3 Playback", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45110", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "rx_macro_rx4", + .dynamic_be = 1, + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + /* TX CDC DMA Backend DAI Links */ + { + .name = LPASS_BE_TX_CDC_DMA_TX_3, + .stream_name = "TX CDC DMA3 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45111", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "tx_macro_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_TX_CDC_DMA_TX_4, + .stream_name = "TX CDC DMA4 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45113", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "tx_macro_tx2", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_va_cdc_dma_be_dai_links[] = { + { + .name = LPASS_BE_VA_CDC_DMA_TX_0, + .stream_name = "VA CDC DMA0 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45089", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "va_macro_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .init = &msm_int_audrx_init, + .id = MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_VA_CDC_DMA_TX_1, + .stream_name = "VA CDC DMA1 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45091", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "va_macro_tx2", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, + { + .name = LPASS_BE_VA_CDC_DMA_TX_2, + .stream_name = "VA CDC DMA2 Capture", + .cpu_dai_name = "msm-dai-cdc-dma-dev.45093", + .platform_name = "msm-pcm-routing", + .codec_name = "bolero_codec", + .codec_dai_name = "va_macro_tx3", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_cdc_dma_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_afe_rxtx_lb_be_dai_link[] = { + { + .name = LPASS_BE_AFE_LOOPBACK_TX, + .stream_name = "AFE Loopback Capture", + .cpu_dai_name = "msm-dai-q6-dev.24577", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_bengal_dai_links[ + ARRAY_SIZE(msm_common_dai_links) + + ARRAY_SIZE(msm_common_misc_fe_dai_links) + + ARRAY_SIZE(msm_common_be_dai_links) + + ARRAY_SIZE(msm_mi2s_be_dai_links) + + ARRAY_SIZE(msm_auxpcm_be_dai_links) + + ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links) + + ARRAY_SIZE(msm_va_cdc_dma_be_dai_links) + + ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link) + + ARRAY_SIZE(msm_wcn_btfm_be_dai_links)]; + +static int msm_populate_dai_link_component_of_node( + struct snd_soc_card *card) +{ + int i, index, ret = 0; + struct device *cdev = card->dev; + struct snd_soc_dai_link *dai_link = card->dai_link; + struct device_node *np; + + if (!cdev) { + dev_err(cdev, "%s: Sound card device memory NULL\n", __func__); + return -ENODEV; + } + + for (i = 0; i < card->num_links; i++) { + if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) + continue; + + /* populate platform_of_node for snd card dai links */ + if (dai_link[i].platform_name && + !dai_link[i].platform_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-platform-names", + dai_link[i].platform_name); + if (index < 0) { + dev_err(cdev, + "%s: No match found for platform name: %s\n", + __func__, dai_link[i].platform_name); + ret = index; + goto err; + } + np = of_parse_phandle(cdev->of_node, "asoc-platform", + index); + if (!np) { + dev_err(cdev, + "%s: retrieving phandle for platform %s, index %d failed\n", + __func__, dai_link[i].platform_name, + index); + ret = -ENODEV; + goto err; + } + dai_link[i].platform_of_node = np; + dai_link[i].platform_name = NULL; + } + + /* populate cpu_of_node for snd card dai links */ + if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-cpu-names", + dai_link[i].cpu_dai_name); + if (index >= 0) { + np = of_parse_phandle(cdev->of_node, "asoc-cpu", + index); + if (!np) { + dev_err(cdev, + "%s: retrieving phandle for cpu dai %s failed\n", + __func__, + dai_link[i].cpu_dai_name); + ret = -ENODEV; + goto err; + } + dai_link[i].cpu_of_node = np; + dai_link[i].cpu_dai_name = NULL; + } + } + + /* populate codec_of_node for snd card dai links */ + if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-codec-names", + dai_link[i].codec_name); + if (index < 0) + continue; + np = of_parse_phandle(cdev->of_node, "asoc-codec", + index); + if (!np) { + dev_err(cdev, + "%s: retrieving phandle for codec %s failed\n", + __func__, dai_link[i].codec_name); + ret = -ENODEV; + goto err; + } + dai_link[i].codec_of_node = np; + dai_link[i].codec_name = NULL; + } + } + +err: + return ret; +} + +static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret = -EINVAL; + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(rtd, "msm-stub-codec"); + + if (!component) { + pr_err("* %s: No match for msm-stub-codec component\n", + __func__); + return ret; + } + + ret = snd_soc_add_component_controls(component, msm_snd_controls, + ARRAY_SIZE(msm_snd_controls)); + if (ret < 0) { + dev_err(component->dev, + "%s: add_codec_controls failed, err = %d\n", + __func__, ret); + return ret; + } + + return ret; +} + +static int msm_snd_stub_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + return 0; +} + +static struct snd_soc_ops msm_stub_be_ops = { + .hw_params = msm_snd_stub_hw_params, +}; + +struct snd_soc_card snd_soc_card_stub_msm = { + .name = "bengal-stub-snd-card", +}; + +static struct snd_soc_dai_link msm_stub_fe_dai_links[] = { + /* FrontEnd DAI Links */ + { + .name = "MSMSTUB Media1", + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, +}; + +static struct snd_soc_dai_link msm_stub_be_dai_links[] = { + /* Backend DAI Links */ + { + .name = LPASS_BE_AUXPCM_RX, + .stream_name = "AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AUXPCM_RX, + .init = &msm_audrx_stub_init, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_stub_be_ops, + }, + { + .name = LPASS_BE_AUXPCM_TX, + .stream_name = "AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AUXPCM_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_stub_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_stub_dai_links[ + ARRAY_SIZE(msm_stub_fe_dai_links) + + ARRAY_SIZE(msm_stub_be_dai_links)]; + +static const struct of_device_id bengal_asoc_machine_of_match[] = { + { .compatible = "qcom,bengal-asoc-snd", + .data = "codec"}, + { .compatible = "qcom,bengal-asoc-snd-stub", + .data = "stub_codec"}, + {}, +}; + +static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) +{ + struct snd_soc_card *card = NULL; + struct snd_soc_dai_link *dailink = NULL; + int len_1 = 0; + int len_2 = 0; + int total_links = 0; + int rc = 0; + u32 mi2s_audio_intf = 0; + u32 auxpcm_audio_intf = 0; + u32 val = 0; + u32 wcn_btfm_intf = 0; + const struct of_device_id *match; + + match = of_match_node(bengal_asoc_machine_of_match, dev->of_node); + if (!match) { + dev_err(dev, "%s: No DT match found for sound card\n", + __func__); + return NULL; + } + + if (!strcmp(match->data, "codec")) { + card = &snd_soc_card_bengal_msm; + + memcpy(msm_bengal_dai_links + total_links, + msm_common_dai_links, + sizeof(msm_common_dai_links)); + total_links += ARRAY_SIZE(msm_common_dai_links); + + memcpy(msm_bengal_dai_links + total_links, + msm_common_misc_fe_dai_links, + sizeof(msm_common_misc_fe_dai_links)); + total_links += ARRAY_SIZE(msm_common_misc_fe_dai_links); + + memcpy(msm_bengal_dai_links + total_links, + msm_common_be_dai_links, + sizeof(msm_common_be_dai_links)); + total_links += ARRAY_SIZE(msm_common_be_dai_links); + + memcpy(msm_bengal_dai_links + total_links, + msm_rx_tx_cdc_dma_be_dai_links, + sizeof(msm_rx_tx_cdc_dma_be_dai_links)); + total_links += + ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links); + + memcpy(msm_bengal_dai_links + total_links, + msm_va_cdc_dma_be_dai_links, + sizeof(msm_va_cdc_dma_be_dai_links)); + total_links += + ARRAY_SIZE(msm_va_cdc_dma_be_dai_links); + + rc = of_property_read_u32(dev->of_node, "qcom,mi2s-audio-intf", + &mi2s_audio_intf); + if (rc) { + dev_dbg(dev, "%s: No DT match MI2S audio interface\n", + __func__); + } else { + if (mi2s_audio_intf) { + memcpy(msm_bengal_dai_links + total_links, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + total_links += + ARRAY_SIZE(msm_mi2s_be_dai_links); + } + } + + rc = of_property_read_u32(dev->of_node, + "qcom,auxpcm-audio-intf", + &auxpcm_audio_intf); + if (rc) { + dev_dbg(dev, "%s: No DT match Aux PCM interface\n", + __func__); + } else { + if (auxpcm_audio_intf) { + memcpy(msm_bengal_dai_links + total_links, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + total_links += + ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + } + + rc = of_property_read_u32(dev->of_node, "qcom,afe-rxtx-lb", + &val); + if (!rc && val) { + memcpy(msm_bengal_dai_links + total_links, + msm_afe_rxtx_lb_be_dai_link, + sizeof(msm_afe_rxtx_lb_be_dai_link)); + total_links += + ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link); + } + + rc = of_property_read_u32(dev->of_node, "qcom,wcn-btfm", + &wcn_btfm_intf); + if (rc) { + dev_dbg(dev, "%s: No DT match wcn btfm interface\n", + __func__); + } else { + if (wcn_btfm_intf) { + memcpy(msm_bengal_dai_links + total_links, + msm_wcn_btfm_be_dai_links, + sizeof(msm_wcn_btfm_be_dai_links)); + total_links += + ARRAY_SIZE(msm_wcn_btfm_be_dai_links); + } + } + dailink = msm_bengal_dai_links; + } else if (!strcmp(match->data, "stub_codec")) { + card = &snd_soc_card_stub_msm; + len_1 = ARRAY_SIZE(msm_stub_fe_dai_links); + len_2 = len_1 + ARRAY_SIZE(msm_stub_be_dai_links); + + memcpy(msm_stub_dai_links, + msm_stub_fe_dai_links, + sizeof(msm_stub_fe_dai_links)); + memcpy(msm_stub_dai_links + len_1, + msm_stub_be_dai_links, + sizeof(msm_stub_be_dai_links)); + + dailink = msm_stub_dai_links; + total_links = len_2; + } + + if (card) { + card->dai_link = dailink; + card->num_links = total_links; + } + + return card; +} + +static int msm_aux_codec_init(struct snd_soc_component *component) +{ + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); + int ret = 0; + void *mbhc_calibration; + struct snd_info_entry *entry; + struct snd_card *card = component->card->snd_card; + struct msm_asoc_mach_data *pdata; + + snd_soc_dapm_ignore_suspend(dapm, "EAR"); + snd_soc_dapm_ignore_suspend(dapm, "AUX"); + snd_soc_dapm_ignore_suspend(dapm, "HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC4"); + snd_soc_dapm_sync(dapm); + + pdata = snd_soc_card_get_drvdata(component->card); + if (!pdata->codec_root) { + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + dev_dbg(component->dev, "%s: Cannot create codecs module entry\n", + __func__); + ret = 0; + goto mbhc_cfg_cal; + } + pdata->codec_root = entry; + } + wcd937x_info_create_codec_entry(pdata->codec_root, component); + +mbhc_cfg_cal: + mbhc_calibration = def_wcd_mbhc_cal(); + if (!mbhc_calibration) + return -ENOMEM; + wcd_mbhc_cfg.calibration = mbhc_calibration; + ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg); + if (ret) { + dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n", + __func__, ret); + goto err_hs_detect; + } + return 0; + +err_hs_detect: + kfree(mbhc_calibration); + return ret; +} + +static int msm_init_aux_dev(struct platform_device *pdev, + struct snd_soc_card *card) +{ + struct device_node *wsa_of_node; + struct device_node *aux_codec_of_node; + u32 wsa_max_devs; + u32 wsa_dev_cnt; + u32 codec_max_aux_devs = 0; + u32 codec_aux_dev_cnt = 0; + int i; + struct msm_wsa881x_dev_info *wsa881x_dev_info; + struct aux_codec_dev_info *aux_cdc_dev_info; + const char *auxdev_name_prefix[1]; + char *dev_name_str = NULL; + int found = 0; + int codecs_found = 0; + int ret = 0; + + /* Get maximum WSA device count for this platform */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,wsa-max-devs", &wsa_max_devs); + if (ret) { + dev_info(&pdev->dev, + "%s: wsa-max-devs property missing in DT %s, ret = %d\n", + __func__, pdev->dev.of_node->full_name, ret); + wsa_max_devs = 0; + goto codec_aux_dev; + } + if (wsa_max_devs == 0) { + dev_warn(&pdev->dev, + "%s: Max WSA devices is 0 for this target?\n", + __func__); + goto codec_aux_dev; + } + + /* Get count of WSA device phandles for this platform */ + wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node, + "qcom,wsa-devs", NULL); + if (wsa_dev_cnt == -ENOENT) { + dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n", + __func__); + goto err; + } else if (wsa_dev_cnt <= 0) { + dev_err(&pdev->dev, + "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n", + __func__, wsa_dev_cnt); + ret = -EINVAL; + goto err; + } + + /* + * Expect total phandles count to be NOT less than maximum possible + * WSA count. However, if it is less, then assign same value to + * max count as well. + */ + if (wsa_dev_cnt < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n", + __func__, wsa_max_devs, wsa_dev_cnt); + wsa_max_devs = wsa_dev_cnt; + } + + /* Make sure prefix string passed for each WSA device */ + ret = of_property_count_strings(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix"); + if (ret != wsa_dev_cnt) { + dev_err(&pdev->dev, + "%s: expecting %d wsa prefix. Defined only %d in DT\n", + __func__, wsa_dev_cnt, ret); + ret = -EINVAL; + goto err; + } + + /* + * Alloc mem to store phandle and index info of WSA device, if already + * registered with ALSA core + */ + wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs, + sizeof(struct msm_wsa881x_dev_info), + GFP_KERNEL); + if (!wsa881x_dev_info) { + ret = -ENOMEM; + goto err; + } + + /* + * search and check whether all WSA devices are already + * registered with ALSA core or not. If found a node, store + * the node and the index in a local array of struct for later + * use. + */ + for (i = 0; i < wsa_dev_cnt; i++) { + wsa_of_node = of_parse_phandle(pdev->dev.of_node, + "qcom,wsa-devs", i); + if (unlikely(!wsa_of_node)) { + /* we should not be here */ + dev_err(&pdev->dev, + "%s: wsa dev node is not present\n", + __func__); + ret = -EINVAL; + goto err; + } + if (soc_find_component(wsa_of_node, NULL)) { + /* WSA device registered with ALSA core */ + wsa881x_dev_info[found].of_node = wsa_of_node; + wsa881x_dev_info[found].index = i; + found++; + if (found == wsa_max_devs) + break; + } + } + + if (found < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: failed to find %d components. Found only %d\n", + __func__, wsa_max_devs, found); + return -EPROBE_DEFER; + } + dev_info(&pdev->dev, + "%s: found %d wsa881x devices registered with ALSA core\n", + __func__, found); + +codec_aux_dev: + /* Get maximum aux codec device count for this platform */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,codec-max-aux-devs", + &codec_max_aux_devs); + if (ret) { + dev_err(&pdev->dev, + "%s: codec-max-aux-devs property missing in DT %s, ret = %d\n", + __func__, pdev->dev.of_node->full_name, ret); + codec_max_aux_devs = 0; + goto aux_dev_register; + } + if (codec_max_aux_devs == 0) { + dev_dbg(&pdev->dev, + "%s: Max aux codec devices is 0 for this target?\n", + __func__); + goto aux_dev_register; + } + + /* Get count of aux codec device phandles for this platform */ + codec_aux_dev_cnt = of_count_phandle_with_args( + pdev->dev.of_node, + "qcom,codec-aux-devs", NULL); + if (codec_aux_dev_cnt == -ENOENT) { + dev_warn(&pdev->dev, "%s: No aux codec defined in DT.\n", + __func__); + goto err; + } else if (codec_aux_dev_cnt <= 0) { + dev_err(&pdev->dev, + "%s: Error reading aux codec device from DT, dev_cnt=%d\n", + __func__, codec_aux_dev_cnt); + ret = -EINVAL; + goto err; + } + + /* + * Expect total phandles count to be NOT less than maximum possible + * AUX device count. However, if it is less, then assign same value to + * max count as well. + */ + if (codec_aux_dev_cnt < codec_max_aux_devs) { + dev_dbg(&pdev->dev, + "%s: codec_max_aux_devs = %d cannot exceed codec_aux_dev_cnt = %d\n", + __func__, codec_max_aux_devs, + codec_aux_dev_cnt); + codec_max_aux_devs = codec_aux_dev_cnt; + } + + /* + * Alloc mem to store phandle and index info of aux codec + * if already registered with ALSA core + */ + aux_cdc_dev_info = devm_kcalloc(&pdev->dev, codec_aux_dev_cnt, + sizeof(struct aux_codec_dev_info), + GFP_KERNEL); + if (!aux_cdc_dev_info) { + ret = -ENOMEM; + goto err; + } + + /* + * search and check whether all aux codecs are already + * registered with ALSA core or not. If found a node, store + * the node and the index in a local array of struct for later + * use. + */ + for (i = 0; i < codec_aux_dev_cnt; i++) { + aux_codec_of_node = of_parse_phandle(pdev->dev.of_node, + "qcom,codec-aux-devs", i); + if (unlikely(!aux_codec_of_node)) { + /* we should not be here */ + dev_err(&pdev->dev, + "%s: aux codec dev node is not present\n", + __func__); + ret = -EINVAL; + goto err; + } + if (soc_find_component(aux_codec_of_node, NULL)) { + /* AUX codec registered with ALSA core */ + aux_cdc_dev_info[codecs_found].of_node = + aux_codec_of_node; + aux_cdc_dev_info[codecs_found].index = i; + codecs_found++; + } + } + + if (codecs_found < codec_aux_dev_cnt) { + dev_dbg(&pdev->dev, + "%s: failed to find %d components. Found only %d\n", + __func__, codec_aux_dev_cnt, codecs_found); + return -EPROBE_DEFER; + } + dev_info(&pdev->dev, + "%s: found %d AUX codecs registered with ALSA core\n", + __func__, codecs_found); + +aux_dev_register: + card->num_aux_devs = wsa_max_devs + codec_aux_dev_cnt; + card->num_configs = wsa_max_devs + codec_aux_dev_cnt; + + /* Alloc array of AUX devs struct */ + msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_aux_dev), + GFP_KERNEL); + if (!msm_aux_dev) { + ret = -ENOMEM; + goto err; + } + + /* Alloc array of codec conf struct */ + msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_configs, + sizeof(struct snd_soc_codec_conf), + GFP_KERNEL); + if (!msm_codec_conf) { + ret = -ENOMEM; + goto err; + } + + for (i = 0; i < wsa_max_devs; i++) { + dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN, + GFP_KERNEL); + if (!dev_name_str) { + ret = -ENOMEM; + goto err; + } + + ret = of_property_read_string_index(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix", + wsa881x_dev_info[i].index, + auxdev_name_prefix); + if (ret) { + dev_err(&pdev->dev, + "%s: failed to read wsa aux dev prefix, ret = %d\n", + __func__, ret); + ret = -EINVAL; + goto err; + } + + snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i); + msm_aux_dev[i].name = dev_name_str; + msm_aux_dev[i].codec_name = NULL; + msm_aux_dev[i].codec_of_node = + wsa881x_dev_info[i].of_node; + msm_aux_dev[i].init = NULL; + msm_codec_conf[i].dev_name = NULL; + msm_codec_conf[i].name_prefix = auxdev_name_prefix[0]; + msm_codec_conf[i].of_node = + wsa881x_dev_info[i].of_node; + } + + for (i = 0; i < codec_aux_dev_cnt; i++) { + msm_aux_dev[wsa_max_devs + i].name = NULL; + msm_aux_dev[wsa_max_devs + i].codec_name = NULL; + msm_aux_dev[wsa_max_devs + i].codec_of_node = + aux_cdc_dev_info[i].of_node; + msm_aux_dev[wsa_max_devs + i].init = msm_aux_codec_init; + msm_codec_conf[wsa_max_devs + i].dev_name = NULL; + msm_codec_conf[wsa_max_devs + i].name_prefix = + NULL; + msm_codec_conf[wsa_max_devs + i].of_node = + aux_cdc_dev_info[i].of_node; + } + + card->codec_conf = msm_codec_conf; + card->aux_dev = msm_aux_dev; +err: + return ret; +} + +static void msm_i2s_auxpcm_init(struct platform_device *pdev) +{ + int count = 0; + u32 mi2s_master_slave[MI2S_MAX]; + int ret = 0; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_init(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-master", + mi2s_master_slave, MI2S_MAX); + if (ret) { + dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n", + __func__); + } else { + for (count = 0; count < MI2S_MAX; count++) { + mi2s_intf_conf[count].msm_is_mi2s_master = + mi2s_master_slave[count]; + } + } +} + +static void msm_i2s_auxpcm_deinit(void) +{ + int count = 0; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_destroy(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + mi2s_intf_conf[count].msm_is_mi2s_master = 0; + } +} + +static int bengal_ssr_enable(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct snd_soc_card *card = platform_get_drvdata(pdev); + int ret = 0; + + if (!card) { + dev_err(dev, "%s: card is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + if (!strcmp(card->name, "bengal-stub-snd-card")) { + /* TODO */ + dev_dbg(dev, "%s: TODO\n", __func__); + } + + snd_soc_card_change_online_state(card, 1); + dev_dbg(dev, "%s: setting snd_card to ONLINE\n", __func__); + +err: + return ret; +} + +static void bengal_ssr_disable(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct snd_soc_card *card = platform_get_drvdata(pdev); + + if (!card) { + dev_err(dev, "%s: card is NULL\n", __func__); + return; + } + + dev_dbg(dev, "%s: setting snd_card to OFFLINE\n", __func__); + snd_soc_card_change_online_state(card, 0); + + if (!strcmp(card->name, "bengal-stub-snd-card")) { + /* TODO */ + dev_dbg(dev, "%s: TODO\n", __func__); + } +} + +static const struct snd_event_ops bengal_ssr_ops = { + .enable = bengal_ssr_enable, + .disable = bengal_ssr_disable, +}; + +static int msm_audio_ssr_compare(struct device *dev, void *data) +{ + struct device_node *node = data; + + dev_dbg(dev, "%s: dev->of_node = 0x%p, node = 0x%p\n", + __func__, dev->of_node, node); + return (dev->of_node && dev->of_node == node); +} + +static int msm_audio_ssr_register(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct snd_event_clients *ssr_clients = NULL; + struct device_node *node = NULL; + int ret = 0; + int i = 0; + + for (i = 0; ; i++) { + node = of_parse_phandle(np, "qcom,msm_audio_ssr_devs", i); + if (!node) + break; + snd_event_mstr_add_client(&ssr_clients, + msm_audio_ssr_compare, node); + } + + ret = snd_event_master_register(dev, &bengal_ssr_ops, + ssr_clients, NULL); + if (!ret) + snd_event_notify(dev, SND_EVENT_UP); + + return ret; +} + +static int msm_asoc_machine_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = NULL; + struct msm_asoc_mach_data *pdata = NULL; + const char *mbhc_audio_jack_type = NULL; + int ret = 0; + uint index = 0; + + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, + "%s: No platform supplied from device tree\n", + __func__); + return -EINVAL; + } + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct msm_asoc_mach_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + card = populate_snd_card_dailinks(&pdev->dev); + if (!card) { + dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); + ret = -EINVAL; + goto err; + } + + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, pdata); + + ret = snd_soc_of_parse_card_name(card, "qcom,model"); + if (ret) { + dev_err(&pdev->dev, "%s: parse card name failed, err:%d\n", + __func__, ret); + goto err; + } + + ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing"); + if (ret) { + dev_err(&pdev->dev, "%s: parse audio routing failed, err:%d\n", + __func__, ret); + goto err; + } + + ret = msm_populate_dai_link_component_of_node(card); + if (ret) { + ret = -EPROBE_DEFER; + goto err; + } + + ret = msm_init_aux_dev(pdev, card); + if (ret) + goto err; + + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret == -EPROBE_DEFER) { + if (codec_reg_done) + ret = -EINVAL; + goto err; + } else if (ret) { + dev_err(&pdev->dev, "%s: snd_soc_register_card failed (%d)\n", + __func__, ret); + goto err; + } + dev_info(&pdev->dev, "%s: Sound card %s registered\n", + __func__, card->name); + + pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en1-gpio", 0); + if (!pdata->hph_en1_gpio_p) { + dev_dbg(&pdev->dev, "%s: property %s not detected in node %s\n", + __func__, "qcom,hph-en1-gpio", + pdev->dev.of_node->full_name); + } + + pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en0-gpio", 0); + if (!pdata->hph_en0_gpio_p) { + dev_dbg(&pdev->dev, "%s: property %s not detected in node %s\n", + __func__, "qcom,hph-en0-gpio", + pdev->dev.of_node->full_name); + } + + ret = of_property_read_string(pdev->dev.of_node, + "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type); + if (ret) { + dev_dbg(&pdev->dev, "%s: Looking up %s property in node %s failed\n", + __func__, "qcom,mbhc-audio-jack-type", + pdev->dev.of_node->full_name); + dev_dbg(&pdev->dev, "Jack type properties set to default\n"); + } else { + if (!strcmp(mbhc_audio_jack_type, "4-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = false; + dev_dbg(&pdev->dev, "This hardware has 4 pole jack"); + } else if (!strcmp(mbhc_audio_jack_type, "5-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = true; + dev_dbg(&pdev->dev, "This hardware has 5 pole jack"); + } else if (!strcmp(mbhc_audio_jack_type, "6-pole-jack")) { + wcd_mbhc_cfg.enable_anc_mic_detect = true; + dev_dbg(&pdev->dev, "This hardware has 6 pole jack"); + } else { + wcd_mbhc_cfg.enable_anc_mic_detect = false; + dev_dbg(&pdev->dev, "Unknown value, set to default\n"); + } + } + /* + * Parse US-Euro gpio info from DT. Report no error if us-euro + * entry is not found in DT file as some targets do not support + * US-Euro detection + */ + pdata->us_euro_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,us-euro-gpios", 0); + if (!pdata->us_euro_gpio_p) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,us-euro-gpios", pdev->dev.of_node->full_name); + } else { + dev_dbg(&pdev->dev, "%s detected\n", + "qcom,us-euro-gpios"); + wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; + } + + if (wcd_mbhc_cfg.enable_usbc_analog) + wcd_mbhc_cfg.swap_gnd_mic = msm_usbc_swap_gnd_mic; + + pdata->fsa_handle = of_parse_phandle(pdev->dev.of_node, + "fsa4480-i2c-handle", 0); + if (!pdata->fsa_handle) + dev_dbg(&pdev->dev, "property %s not detected in node %s\n", + "fsa4480-i2c-handle", pdev->dev.of_node->full_name); + + msm_i2s_auxpcm_init(pdev); + pdata->dmic01_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-dmic01-gpios", + 0); + pdata->dmic23_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-dmic23-gpios", + 0); + + pdata->mi2s_gpio_p[PRIM_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,pri-mi2s-gpios", 0); + pdata->mi2s_gpio_p[SEC_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,sec-mi2s-gpios", 0); + pdata->mi2s_gpio_p[TERT_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,tert-mi2s-gpios", 0); + pdata->mi2s_gpio_p[QUAT_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,quat-mi2s-gpios", 0); + for (index = PRIM_MI2S; index < MI2S_MAX; index++) + atomic_set(&(pdata->mi2s_gpio_ref_count[index]), 0); + + ret = msm_audio_ssr_register(&pdev->dev); + if (ret) + pr_err("%s: Registration with SND event FWK failed ret = %d\n", + __func__, ret); + + is_initial_boot = true; + + return 0; +err: + devm_kfree(&pdev->dev, pdata); + return ret; +} + +static int msm_asoc_machine_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_event_master_deregister(&pdev->dev); + snd_soc_unregister_card(card); + msm_i2s_auxpcm_deinit(); + + return 0; +} + +static struct platform_driver bengal_asoc_machine_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = bengal_asoc_machine_of_match, + .suppress_bind_attrs = true, + }, + .probe = msm_asoc_machine_probe, + .remove = msm_asoc_machine_remove, +}; +module_platform_driver(bengal_asoc_machine_driver); + +MODULE_DESCRIPTION("ALSA SoC msm"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, bengal_asoc_machine_of_match); -- GitLab From 9e78ef8743912f8520082f2006460f0c8316e5e3 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 1 Jul 2019 12:31:45 +0530 Subject: [PATCH 1238/1645] asoc: codecs: restore wsa analog driver files Add support back for wsa analog codec driver files. Change-Id: I7ef6ad050b068ec8c0f0275089d670c92234686d Signed-off-by: Laxminath Kasam --- asoc/codecs/wsa881x-analog.c | 1543 ++++++++++++++++++++++++ asoc/codecs/wsa881x-analog.h | 43 + asoc/codecs/wsa881x-registers-analog.h | 199 +++ asoc/codecs/wsa881x-regmap-analog.c | 491 ++++++++ asoc/codecs/wsa881x-tables-analog.c | 163 +++ 5 files changed, 2439 insertions(+) create mode 100644 asoc/codecs/wsa881x-analog.c create mode 100644 asoc/codecs/wsa881x-analog.h create mode 100644 asoc/codecs/wsa881x-registers-analog.h create mode 100644 asoc/codecs/wsa881x-regmap-analog.c create mode 100644 asoc/codecs/wsa881x-tables-analog.c diff --git a/asoc/codecs/wsa881x-analog.c b/asoc/codecs/wsa881x-analog.c new file mode 100644 index 000000000000..23ab5c9b55cc --- /dev/null +++ b/asoc/codecs/wsa881x-analog.c @@ -0,0 +1,1543 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015-2016, 2018-2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wsa881x-analog.h" +#include "wsa881x-temp-sensor.h" + +#define SPK_GAIN_12DB 4 +#define WIDGET_NAME_MAX_SIZE 80 + +/* + * Private data Structure for wsa881x. All parameters related to + * WSA881X codec needs to be defined here. + */ +struct wsa881x_pdata { + struct regmap *regmap[2]; + struct i2c_client *client[2]; + struct snd_soc_component *component; + + /* track wsa881x status during probe */ + int status; + bool boost_enable; + bool visense_enable; + int spk_pa_gain; + struct i2c_msg xfer_msg[2]; + struct mutex xfer_lock; + bool regmap_flag; + bool wsa_active; + int index; + struct wsa881x_tz_priv tz_pdata; + struct clk *wsa_mclk; + int bg_cnt; + int clk_cnt; + int enable_cnt; + int version; + struct mutex bg_lock; + struct mutex res_lock; + struct delayed_work ocp_ctl_work; + struct device_node *wsa_vi_gpio_p; + struct device_node *wsa_clk_gpio_p; + struct device_node *wsa_reset_gpio_p; +}; + +enum { + WSA881X_STATUS_PROBING, + WSA881X_STATUS_I2C, +}; + +#define WSA881X_OCP_CTL_TIMER_SEC 2 +#define WSA881X_OCP_CTL_TEMP_CELSIUS 25 +#define WSA881X_OCP_CTL_POLL_TIMER_SEC 60 + +static int wsa881x_ocp_poll_timer_sec = WSA881X_OCP_CTL_POLL_TIMER_SEC; +module_param(wsa881x_ocp_poll_timer_sec, int, 0664); +MODULE_PARM_DESC(wsa881x_ocp_poll_timer_sec, "timer for ocp ctl polling"); + +static int32_t wsa881x_resource_acquire(struct snd_soc_component *component, + bool enable); + +const char *wsa_tz_names[] = {"wsa881x.0e", "wsa881x.0f"}; + +struct wsa881x_pdata wsa_pdata[MAX_WSA881X_DEVICE]; + +static bool pinctrl_init; + +static int wsa881x_populate_dt_pdata(struct device *dev, int wsa881x_index); +static int wsa881x_reset(struct wsa881x_pdata *pdata, bool enable); +static int wsa881x_startup(struct wsa881x_pdata *pdata); +static int wsa881x_shutdown(struct wsa881x_pdata *pdata); + +static int delay_array_msec[] = {10, 20, 30, 40, 50}; + +static int wsa881x_i2c_addr = -1; +static int wsa881x_probing_count; +static int wsa881x_presence_count; + +static const char * const wsa881x_spk_pa_gain_text[] = { +"POS_13P5_DB", "POS_12_DB", "POS_10P5_DB", "POS_9_DB", "POS_7P5_DB", +"POS_6_DB", "POS_4P5_DB", "POS_3_DB", "POS_1P5_DB", "POS_0_DB"}; + +static const struct soc_enum wsa881x_spk_pa_gain_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa881x_spk_pa_gain_text), + wsa881x_spk_pa_gain_text), +}; + +static int wsa881x_spk_pa_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wsa881x->spk_pa_gain; + + dev_dbg(component->dev, "%s: spk_pa_gain = %ld\n", __func__, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int wsa881x_spk_pa_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + + if (ucontrol->value.integer.value[0] < 0 || + ucontrol->value.integer.value[0] > 0xC) { + dev_err(component->dev, "%s: Unsupported gain val %ld\n", + __func__, ucontrol->value.integer.value[0]); + return -EINVAL; + } + wsa881x->spk_pa_gain = ucontrol->value.integer.value[0]; + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int get_i2c_wsa881x_device_index(u16 reg) +{ + u16 mask = 0x0f00; + int value = 0; + + value = ((reg & mask) >> 8) & 0x000f; + + switch (value) { + case 0: + return 0; + case 1: + return 1; + default: + break; + } + return -EINVAL; +} + +static int wsa881x_i2c_write_device(struct wsa881x_pdata *wsa881x, + unsigned int reg, unsigned int val) +{ + int i = 0, rc = 0; + int wsa881x_index; + struct i2c_msg *msg; + int ret = 0; + int bytes = 1; + u8 reg_addr = 0; + u8 data[2]; + + wsa881x_index = get_i2c_wsa881x_device_index(reg); + if (wsa881x_index < 0) { + pr_err_ratelimited("%s:invalid register to write\n", __func__); + return -EINVAL; + } + if (wsa881x->regmap_flag) { + rc = regmap_write(wsa881x->regmap[wsa881x_index], reg, val); + for (i = 0; rc && i < ARRAY_SIZE(delay_array_msec); i++) { + pr_err_ratelimited("Failed writing reg=%u-retry(%d)\n", + reg, i); + /* retry after delay of increasing order */ + msleep(delay_array_msec[i]); + rc = regmap_write(wsa881x->regmap[wsa881x_index], + reg, val); + } + if (rc) + pr_err_ratelimited("Failed writing reg=%u rc=%d\n", + reg, rc); + else + pr_debug("write success register = %x val = %x\n", + reg, val); + } else { + reg_addr = (u8)reg; + msg = &wsa881x->xfer_msg[0]; + msg->addr = wsa881x->client[wsa881x_index]->addr; + msg->len = bytes + 1; + msg->flags = 0; + data[0] = reg; + data[1] = (u8)val; + msg->buf = data; + ret = i2c_transfer(wsa881x->client[wsa881x_index]->adapter, + wsa881x->xfer_msg, 1); + /* Try again if the write fails */ + if (ret != 1) { + ret = i2c_transfer( + wsa881x->client[wsa881x_index]->adapter, + wsa881x->xfer_msg, 1); + if (ret != 1) { + pr_err_ratelimited("failed to write the device\n"); + return ret; + } + } + pr_debug("write success reg = %x val = %x\n", reg, data[1]); + } + return rc; +} + +static int wsa881x_i2c_read_device(struct wsa881x_pdata *wsa881x, + unsigned int reg) +{ + int wsa881x_index; + int i = 0, rc = 0; + unsigned int val; + struct i2c_msg *msg; + int ret = 0; + u8 reg_addr = 0; + u8 dest[5] = {0}; + + wsa881x_index = get_i2c_wsa881x_device_index(reg); + if (wsa881x_index < 0) { + pr_err_ratelimited("%s:invalid register to read\n", __func__); + return -EINVAL; + } + if (wsa881x->regmap_flag) { + rc = regmap_read(wsa881x->regmap[wsa881x_index], reg, &val); + for (i = 0; rc && i < ARRAY_SIZE(delay_array_msec); i++) { + pr_err_ratelimited("Failed reading reg=%u - retry(%d)\n", + reg, i); + /* retry after delay of increasing order */ + msleep(delay_array_msec[i]); + rc = regmap_read(wsa881x->regmap[wsa881x_index], + reg, &val); + } + if (rc) { + pr_err_ratelimited("Failed reading reg=%u rc=%d\n", + reg, rc); + return rc; + } + pr_debug("read success reg = %x val = %x\n", + reg, val); + } else { + reg_addr = (u8)reg; + msg = &wsa881x->xfer_msg[0]; + msg->addr = wsa881x->client[wsa881x_index]->addr; + msg->len = 1; + msg->flags = 0; + msg->buf = ®_addr; + + msg = &wsa881x->xfer_msg[1]; + msg->addr = wsa881x->client[wsa881x_index]->addr; + msg->len = 1; + msg->flags = I2C_M_RD; + msg->buf = dest; + ret = i2c_transfer(wsa881x->client[wsa881x_index]->adapter, + wsa881x->xfer_msg, 2); + + /* Try again if read fails first time */ + if (ret != 2) { + ret = i2c_transfer( + wsa881x->client[wsa881x_index]->adapter, + wsa881x->xfer_msg, 2); + if (ret != 2) { + pr_err_ratelimited("failed to read wsa register:%d\n", + reg); + return ret; + } + } + val = dest[0]; + } + return val; +} + +static unsigned int wsa881x_i2c_read(struct snd_soc_component *component, + unsigned int reg) +{ + struct wsa881x_pdata *wsa881x; + int wsa881x_index; + + if (component == NULL) { + pr_err_ratelimited("%s: invalid component\n", __func__); + return -EINVAL; + } + wsa881x = snd_soc_component_get_drvdata(component); + if (!wsa881x->wsa_active) + return 0; + + wsa881x_index = get_i2c_wsa881x_device_index(reg); + if (wsa881x_index < 0) { + pr_err_ratelimited("%s:invalid register to read\n", __func__); + return -EINVAL; + } + return wsa881x_i2c_read_device(wsa881x, reg); +} + +static int wsa881x_i2c_write(struct snd_soc_component *component, + unsigned int reg, + unsigned int val) +{ + struct wsa881x_pdata *wsa881x; + int wsa881x_index; + + if (component == NULL) { + pr_err_ratelimited("%s: invalid component\n", __func__); + return -EINVAL; + } + wsa881x = snd_soc_component_get_drvdata(component); + if (!wsa881x->wsa_active) + return 0; + + wsa881x_index = get_i2c_wsa881x_device_index(reg); + if (wsa881x_index < 0) { + pr_err_ratelimited("%s:invalid register to read\n", __func__); + return -EINVAL; + } + return wsa881x_i2c_write_device(wsa881x, reg, val); +} + +static int wsa881x_i2c_get_client_index(struct i2c_client *client, + int *wsa881x_index) +{ + int ret = 0; + + switch (client->addr) { + case WSA881X_I2C_SPK0_SLAVE0_ADDR: + case WSA881X_I2C_SPK0_SLAVE1_ADDR: + *wsa881x_index = WSA881X_I2C_SPK0_SLAVE0; + break; + case WSA881X_I2C_SPK1_SLAVE0_ADDR: + case WSA881X_I2C_SPK1_SLAVE1_ADDR: + *wsa881x_index = WSA881X_I2C_SPK1_SLAVE0; + break; + default: + ret = -EINVAL; + break; + } + return ret; +} + +static int wsa881x_boost_ctrl(struct snd_soc_component *component, bool enable) +{ + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + + + pr_debug("%s: enable:%d\n", __func__, enable); + if (enable) { + if (!WSA881X_IS_2_0(wsa881x->version)) { + snd_soc_component_update_bits(component, + WSA881X_ANA_CTL, 0x01, 0x01); + snd_soc_component_update_bits(component, + WSA881X_ANA_CTL, 0x04, 0x04); + snd_soc_component_update_bits(component, + WSA881X_BOOST_PS_CTL, + 0x40, 0x00); + snd_soc_component_update_bits(component, + WSA881X_BOOST_PRESET_OUT1, + 0xF0, 0xB0); + snd_soc_component_update_bits(component, + WSA881X_BOOST_ZX_CTL, + 0x20, 0x00); + snd_soc_component_update_bits(component, + WSA881X_BOOST_EN_CTL, + 0x80, 0x80); + } else { + snd_soc_component_update_bits(component, + WSA881X_BOOST_LOOP_STABILITY, + 0x03, 0x03); + snd_soc_component_update_bits(component, + WSA881X_BOOST_MISC2_CTL, + 0xFF, 0x14); + snd_soc_component_update_bits(component, + WSA881X_BOOST_START_CTL, + 0x80, 0x80); + snd_soc_component_update_bits(component, + WSA881X_BOOST_START_CTL, + 0x03, 0x00); + snd_soc_component_update_bits(component, + WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, + 0x0C, 0x04); + snd_soc_component_update_bits(component, + WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, + 0x03, 0x00); + snd_soc_component_update_bits(component, + WSA881X_BOOST_PRESET_OUT1, + 0xF0, 0x70); + snd_soc_component_update_bits(component, + WSA881X_ANA_CTL, 0x03, 0x01); + snd_soc_component_update_bits(component, + WSA881X_SPKR_DRV_EN, + 0x08, 0x08); + snd_soc_component_update_bits(component, + WSA881X_ANA_CTL, 0x04, 0x04); + snd_soc_component_update_bits(component, + WSA881X_BOOST_CURRENT_LIMIT, + 0x0F, 0x08); + snd_soc_component_update_bits(component, + WSA881X_BOOST_EN_CTL, + 0x80, 0x80); + } + /* For WSA8810, start-up time is 1500us as per qcrg sequence */ + usleep_range(1500, 1510); + } else { + /* ENSURE: Class-D amp is shutdown. CLK is still on */ + snd_soc_component_update_bits(component, + WSA881X_BOOST_EN_CTL, 0x80, 0x00); + /* boost settle time is 1500us as per qcrg sequence */ + usleep_range(1500, 1510); + } + return 0; +} + +static int wsa881x_visense_txfe_ctrl(struct snd_soc_component *component, + bool enable, + u8 isense1_gain, u8 isense2_gain, + u8 vsense_gain) +{ + u8 value = 0; + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + + pr_debug("%s: enable:%d\n", __func__, enable); + + if (enable) { + if (WSA881X_IS_2_0(wsa881x->version)) { + snd_soc_component_update_bits(component, + WSA881X_OTP_REG_28, + 0x3F, 0x3A); + snd_soc_component_update_bits(component, + WSA881X_BONGO_RESRV_REG1, + 0xFF, 0xB2); + snd_soc_component_update_bits(component, + WSA881X_BONGO_RESRV_REG2, + 0xFF, 0x05); + } + snd_soc_component_update_bits(component, + WSA881X_SPKR_PROT_FE_VSENSE_VCM, + 0x08, 0x00); + if (WSA881X_IS_2_0(wsa881x->version)) { + snd_soc_component_update_bits(component, + WSA881X_SPKR_PROT_ATEST2, + 0x1C, 0x04); + } else { + snd_soc_component_update_bits(component, + WSA881X_SPKR_PROT_ATEST2, + 0x08, 0x08); + snd_soc_component_update_bits(component, + WSA881X_SPKR_PROT_ATEST2, + 0x02, 0x02); + } + value = ((isense2_gain << 6) | (isense1_gain << 4) | + (vsense_gain << 3)); + snd_soc_component_update_bits(component, + WSA881X_SPKR_PROT_FE_GAIN, + 0xF8, value); + snd_soc_component_update_bits(component, + WSA881X_SPKR_PROT_FE_GAIN, + 0x01, 0x01); + } else { + if (WSA881X_IS_2_0(wsa881x->version)) + snd_soc_component_update_bits(component, + WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x10, 0x10); + else + snd_soc_component_update_bits(component, + WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x08, 0x08); + /* + * 200us sleep is needed after visense txfe disable as per + * HW requirement. + */ + usleep_range(200, 210); + + snd_soc_component_update_bits(component, + WSA881X_SPKR_PROT_FE_GAIN, + 0x01, 0x00); + } + return 0; +} + +static int wsa881x_visense_adc_ctrl(struct snd_soc_component *component, + bool enable) +{ + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + + pr_debug("%s: enable:%d\n", __func__, enable); + if (enable) { + if (!WSA881X_IS_2_0(wsa881x->version)) + snd_soc_component_update_bits(component, + WSA881X_ADC_SEL_IBIAS, + 0x70, 0x40); + snd_soc_component_update_bits(component, + WSA881X_ADC_EN_SEL_IBIAS, + 0x07, 0x04); + snd_soc_component_update_bits(component, + WSA881X_ADC_EN_MODU_V, 0x80, 0x80); + snd_soc_component_update_bits(component, + WSA881X_ADC_EN_MODU_I, 0x80, 0x80); + } else { + /* Ensure: Speaker Protection has been stopped */ + snd_soc_component_update_bits(component, + WSA881X_ADC_EN_MODU_V, 0x80, 0x00); + snd_soc_component_update_bits(component, + WSA881X_ADC_EN_MODU_I, 0x80, 0x00); + } + + return 0; +} + +static void wsa881x_bandgap_ctrl(struct snd_soc_component *component, + bool enable) +{ + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: enable:%d, bg_count:%d\n", __func__, + enable, wsa881x->bg_cnt); + mutex_lock(&wsa881x->bg_lock); + if (enable) { + ++wsa881x->bg_cnt; + if (wsa881x->bg_cnt == 1) { + snd_soc_component_update_bits(component, + WSA881X_TEMP_OP, 0x08, 0x08); + /* 400usec sleep is needed as per HW requirement */ + usleep_range(400, 410); + snd_soc_component_update_bits(component, + WSA881X_TEMP_OP, 0x04, 0x04); + } + } else { + --wsa881x->bg_cnt; + if (wsa881x->bg_cnt <= 0) { + WARN_ON(wsa881x->bg_cnt < 0); + wsa881x->bg_cnt = 0; + snd_soc_component_update_bits(component, + WSA881X_TEMP_OP, 0x04, 0x00); + snd_soc_component_update_bits(component, + WSA881X_TEMP_OP, 0x08, 0x00); + } + } + mutex_unlock(&wsa881x->bg_lock); +} + +static void wsa881x_clk_ctrl(struct snd_soc_component *component, bool enable) +{ + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s:ss enable:%d, clk_count:%d\n", __func__, + enable, wsa881x->clk_cnt); + mutex_lock(&wsa881x->res_lock); + if (enable) { + ++wsa881x->clk_cnt; + if (wsa881x->clk_cnt == 1) { + snd_soc_component_write(component, + WSA881X_CDC_RST_CTL, 0x02); + snd_soc_component_write(component, + WSA881X_CDC_RST_CTL, 0x03); + snd_soc_component_write(component, + WSA881X_CLOCK_CONFIG, 0x01); + + snd_soc_component_write(component, + WSA881X_CDC_DIG_CLK_CTL, 0x01); + snd_soc_component_write(component, + WSA881X_CDC_ANA_CLK_CTL, 0x01); + + } + } else { + --wsa881x->clk_cnt; + if (wsa881x->clk_cnt <= 0) { + WARN_ON(wsa881x->clk_cnt < 0); + wsa881x->clk_cnt = 0; + snd_soc_component_write(component, + WSA881X_CDC_ANA_CLK_CTL, 0x00); + snd_soc_component_write(component, + WSA881X_CDC_DIG_CLK_CTL, 0x00); + if (WSA881X_IS_2_0(wsa881x->version)) + snd_soc_component_update_bits(component, + WSA881X_CDC_TOP_CLK_CTL, 0x01, 0x00); + } + } + mutex_unlock(&wsa881x->res_lock); +} + +static int wsa881x_rdac_ctrl(struct snd_soc_component *component, bool enable) +{ + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + + pr_debug("%s: enable:%d\n", __func__, enable); + if (enable) { + snd_soc_component_update_bits(component, + WSA881X_ANA_CTL, 0x08, 0x00); + snd_soc_component_update_bits(component, + WSA881X_SPKR_DRV_GAIN, 0x08, 0x08); + snd_soc_component_update_bits(component, + WSA881X_SPKR_DAC_CTL, 0x20, 0x20); + snd_soc_component_update_bits(component, + WSA881X_SPKR_DAC_CTL, 0x20, 0x00); + snd_soc_component_update_bits(component, + WSA881X_SPKR_DAC_CTL, 0x40, 0x40); + snd_soc_component_update_bits(component, + WSA881X_SPKR_DAC_CTL, 0x80, 0x80); + if (WSA881X_IS_2_0(wsa881x->version)) { + snd_soc_component_update_bits(component, + WSA881X_SPKR_BIAS_CAL, 0x01, 0x01); + snd_soc_component_update_bits(component, + WSA881X_SPKR_OCP_CTL, 0x30, 0x30); + snd_soc_component_update_bits(component, + WSA881X_SPKR_OCP_CTL, 0x0C, 0x00); + } + snd_soc_component_update_bits(component, + WSA881X_SPKR_DRV_GAIN, 0xF0, 0x40); + snd_soc_component_update_bits(component, + WSA881X_SPKR_MISC_CTL1, 0x01, 0x01); + } else { + /* Ensure class-D amp is off */ + snd_soc_component_update_bits(component, + WSA881X_SPKR_DAC_CTL, 0x80, 0x00); + } + return 0; +} + +static int wsa881x_spkr_pa_ctrl(struct snd_soc_component *component, + bool enable) +{ + int ret = 0; + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + + pr_debug("%s: enable:%d\n", __func__, enable); + if (enable) { + /* + * Ensure: Boost is enabled and stable, Analog input is up + * and outputting silence + */ + if (!WSA881X_IS_2_0(wsa881x->version)) { + snd_soc_component_update_bits(component, + WSA881X_ADC_EN_DET_TEST_I, + 0xFF, 0x01); + snd_soc_component_update_bits(component, + WSA881X_ADC_EN_MODU_V, + 0x02, 0x02); + snd_soc_component_update_bits(component, + WSA881X_ADC_EN_DET_TEST_V, + 0xFF, 0x10); + snd_soc_component_update_bits(component, + WSA881X_SPKR_PWRSTG_DBG, + 0xA0, 0xA0); + snd_soc_component_update_bits(component, + WSA881X_SPKR_DRV_EN, + 0x80, 0x80); + usleep_range(700, 710); + snd_soc_component_update_bits(component, + WSA881X_SPKR_PWRSTG_DBG, + 0x00, 0x00); + snd_soc_component_update_bits(component, + WSA881X_ADC_EN_DET_TEST_V, + 0xFF, 0x00); + snd_soc_component_update_bits(component, + WSA881X_ADC_EN_MODU_V, + 0x02, 0x00); + snd_soc_component_update_bits(component, + WSA881X_ADC_EN_DET_TEST_I, + 0xFF, 0x00); + } else + snd_soc_component_update_bits(component, + WSA881X_SPKR_DRV_EN, 0x80, 0x80); + /* add 1000us delay as per qcrg */ + usleep_range(1000, 1010); + snd_soc_component_update_bits(component, + WSA881X_SPKR_DRV_EN, 0x01, 0x01); + if (WSA881X_IS_2_0(wsa881x->version)) + snd_soc_component_update_bits(component, + WSA881X_SPKR_BIAS_CAL, + 0x01, 0x00); + usleep_range(1000, 1010); + snd_soc_component_update_bits(component, + WSA881X_SPKR_DRV_GAIN, + 0xF0, (wsa881x->spk_pa_gain << 4)); + if (wsa881x->visense_enable) { + ret = msm_cdc_pinctrl_select_active_state( + wsa881x->wsa_vi_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be activated %s\n", + __func__, "wsa_vi"); + return ret; + } + wsa881x_visense_txfe_ctrl(component, true, + 0x00, 0x01, 0x00); + wsa881x_visense_adc_ctrl(component, true); + } + } else { + /* + * Ensure: Boost is still on, Stream from Analog input and + * Speaker Protection has been stopped and input is at 0V + */ + if (WSA881X_IS_2_0(wsa881x->version)) { + snd_soc_component_update_bits(component, + WSA881X_SPKR_BIAS_CAL, + 0x01, 0x01); + usleep_range(1000, 1010); + snd_soc_component_update_bits(component, + WSA881X_SPKR_BIAS_CAL, + 0x01, 0x00); + msleep(20); + snd_soc_component_update_bits(component, + WSA881X_ANA_CTL, 0x03, 0x00); + usleep_range(200, 210); + } + snd_soc_component_update_bits(component, + WSA881X_SPKR_DRV_EN, 0x80, 0x00); + } + return 0; +} + +static int wsa881x_get_boost(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wsa881x->boost_enable; + return 0; +} + +static int wsa881x_set_boost(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + int value = ucontrol->value.integer.value[0]; + + dev_dbg(component->dev, "%s: Boost enable current %d, new %d\n", + __func__, wsa881x->boost_enable, value); + wsa881x->boost_enable = value; + return 0; +} + +static int wsa881x_get_visense(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wsa881x->visense_enable; + return 0; +} + +static int wsa881x_set_visense(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + int value = ucontrol->value.integer.value[0]; + + dev_dbg(component->dev, "%s: VIsense enable current %d, new %d\n", + __func__, wsa881x->visense_enable, value); + wsa881x->visense_enable = value; + return 0; +} + +static const struct snd_kcontrol_new wsa881x_snd_controls[] = { + SOC_SINGLE_EXT("BOOST Switch", SND_SOC_NOPM, 0, 1, 0, + wsa881x_get_boost, wsa881x_set_boost), + + SOC_SINGLE_EXT("VISENSE Switch", SND_SOC_NOPM, 0, 1, 0, + wsa881x_get_visense, wsa881x_set_visense), + + SOC_ENUM_EXT("WSA_SPK PA Gain", wsa881x_spk_pa_gain_enum[0], + wsa881x_spk_pa_gain_get, wsa881x_spk_pa_gain_put), +}; + +static const char * const rdac_text[] = { + "ZERO", "Switch", +}; + +static const struct soc_enum rdac_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(rdac_text), rdac_text); + +static const struct snd_kcontrol_new rdac_mux[] = { + SOC_DAPM_ENUM("RDAC", rdac_enum) +}; + +static int wsa881x_rdac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + int ret = 0; + + dev_dbg(component->dev, "%s: %s %d boost %d visense %d\n", + __func__, w->name, event, + wsa881x->boost_enable, wsa881x->visense_enable); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = wsa881x_startup(wsa881x); + if (ret) { + pr_err("%s: wsa startup failed ret: %d", __func__, ret); + return ret; + } + wsa881x_clk_ctrl(component, true); + snd_soc_component_update_bits(component, + WSA881X_SPKR_DAC_CTL, 0x02, 0x02); + if (!WSA881X_IS_2_0(wsa881x->version)) + snd_soc_component_update_bits(component, + WSA881X_BIAS_REF_CTRL, + 0x0F, 0x08); + wsa881x_bandgap_ctrl(component, true); + if (!WSA881X_IS_2_0(wsa881x->version)) + snd_soc_component_update_bits(component, + WSA881X_SPKR_BBM_CTL, + 0x02, 0x02); + snd_soc_component_update_bits(component, + WSA881X_SPKR_MISC_CTL1, 0xC0, 0x80); + snd_soc_component_update_bits(component, + WSA881X_SPKR_MISC_CTL1, 0x06, 0x06); + if (!WSA881X_IS_2_0(wsa881x->version)) { + snd_soc_component_update_bits(component, + WSA881X_SPKR_MISC_CTL2, + 0x04, 0x04); + snd_soc_component_update_bits(component, + WSA881X_SPKR_BIAS_INT, + 0x09, 0x09); + } + snd_soc_component_update_bits(component, + WSA881X_SPKR_PA_INT, 0xF0, 0x20); + if (WSA881X_IS_2_0(wsa881x->version)) + snd_soc_component_update_bits(component, + WSA881X_SPKR_PA_INT, + 0x0E, 0x0E); + if (wsa881x->boost_enable) + wsa881x_boost_ctrl(component, true); + break; + case SND_SOC_DAPM_POST_PMU: + wsa881x_rdac_ctrl(component, true); + break; + case SND_SOC_DAPM_PRE_PMD: + wsa881x_rdac_ctrl(component, false); + if (wsa881x->visense_enable) { + wsa881x_visense_adc_ctrl(component, false); + wsa881x_visense_txfe_ctrl(component, false, + 0x00, 0x01, 0x00); + ret = msm_cdc_pinctrl_select_sleep_state( + wsa881x->wsa_vi_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be suspended %s\n", + __func__, "wsa_vi"); + return ret; + } + } + break; + case SND_SOC_DAPM_POST_PMD: + if (wsa881x->boost_enable) + wsa881x_boost_ctrl(component, false); + wsa881x_clk_ctrl(component, false); + wsa881x_bandgap_ctrl(component, false); + ret = wsa881x_shutdown(wsa881x); + if (ret < 0) { + pr_err("%s: wsa shutdown failed ret: %d", + __func__, ret); + return ret; + } + break; + default: + pr_err("%s: invalid event:%d\n", __func__, event); + return -EINVAL; + } + return 0; +} + +static void wsa881x_ocp_ctl_work(struct work_struct *work) +{ + struct wsa881x_pdata *wsa881x; + struct delayed_work *dwork; + struct snd_soc_component *component; + int temp_val; + + dwork = to_delayed_work(work); + wsa881x = container_of(dwork, struct wsa881x_pdata, ocp_ctl_work); + + if (!wsa881x) + return; + + component = wsa881x->component; + wsa881x_get_temp(wsa881x->tz_pdata.tz_dev, &temp_val); + dev_dbg(component->dev, " temp = %d\n", temp_val); + + if (temp_val <= WSA881X_OCP_CTL_TEMP_CELSIUS) + snd_soc_component_update_bits(component, + WSA881X_SPKR_OCP_CTL, 0xC0, 0x00); + else + snd_soc_component_update_bits(component, + WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0); + + schedule_delayed_work(&wsa881x->ocp_ctl_work, + msecs_to_jiffies(wsa881x_ocp_poll_timer_sec * 1000)); +} + +static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + + pr_debug("%s: %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_component_update_bits(component, + WSA881X_SPKR_OCP_CTL, 0xC0, 0x80); + break; + case SND_SOC_DAPM_POST_PMU: + wsa881x_spkr_pa_ctrl(component, true); + schedule_delayed_work(&wsa881x->ocp_ctl_work, + msecs_to_jiffies(WSA881X_OCP_CTL_TIMER_SEC * 1000)); + break; + case SND_SOC_DAPM_PRE_PMD: + wsa881x_spkr_pa_ctrl(component, false); + break; + case SND_SOC_DAPM_POST_PMD: + cancel_delayed_work_sync(&wsa881x->ocp_ctl_work); + snd_soc_component_update_bits(component, + WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0); + break; + default: + pr_err("%s: invalid event:%d\n", __func__, event); + return -EINVAL; + } + return 0; +} + +static const struct snd_soc_dapm_widget wsa881x_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("WSA_IN"), + + SND_SOC_DAPM_DAC_E("RDAC Analog", NULL, SND_SOC_NOPM, 0, 0, + wsa881x_rdac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("WSA_RDAC", SND_SOC_NOPM, 0, 0, + rdac_mux), + + SND_SOC_DAPM_PGA_S("WSA_SPKR PGA", 1, SND_SOC_NOPM, 0, 0, + wsa881x_spkr_pa_event, + SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_OUTPUT("WSA_SPKR"), +}; + +static const struct snd_soc_dapm_route wsa881x_audio_map[] = { + {"WSA_RDAC", "Switch", "WSA_IN"}, + {"RDAC Analog", NULL, "WSA_RDAC"}, + {"WSA_SPKR PGA", NULL, "RDAC Analog"}, + {"WSA_SPKR", NULL, "WSA_SPKR PGA"}, +}; + + +static int wsa881x_startup(struct wsa881x_pdata *pdata) +{ + int ret = 0; + + pr_debug("%s(): wsa startup, enable_cnt:%d\n", __func__, + pdata->enable_cnt); + + if (pdata->enable_cnt++ > 0) + return 0; + ret = msm_cdc_pinctrl_select_active_state(pdata->wsa_clk_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be activated %s\n", + __func__, "wsa_clk"); + return ret; + } + ret = clk_prepare_enable(pdata->wsa_mclk); + if (ret) { + pr_err("%s: WSA MCLK enable failed\n", + __func__); + return ret; + } + ret = wsa881x_reset(pdata, true); + return ret; +} + +static int wsa881x_shutdown(struct wsa881x_pdata *pdata) +{ + int ret = 0; + + pr_debug("%s(): wsa shutdown, enable_cnt:%d\n", __func__, + pdata->enable_cnt); + if (--pdata->enable_cnt > 0) + return 0; + ret = wsa881x_reset(pdata, false); + if (ret) { + pr_err("%s: wsa reset failed suspend %d\n", + __func__, ret); + return ret; + } + + clk_disable_unprepare(pdata->wsa_mclk); + + ret = msm_cdc_pinctrl_select_sleep_state(pdata->wsa_clk_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be suspended %s\n", + __func__, "wsa_clk"); + return ret; + } + + return 0; +} + +static int32_t wsa881x_resource_acquire(struct snd_soc_component *component, + bool enable) +{ + int ret = 0; + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + + if (enable) { + ret = wsa881x_startup(wsa881x); + if (ret < 0) { + dev_err_ratelimited(component->dev, + "%s: failed to startup\n", __func__); + return ret; + } + } + wsa881x_clk_ctrl(component, enable); + wsa881x_bandgap_ctrl(component, enable); + if (!enable) { + ret = wsa881x_shutdown(wsa881x); + if (ret < 0) + dev_err_ratelimited(component->dev, + "%s: failed to shutdown\n", __func__); + } + return ret; +} + +static int32_t wsa881x_temp_reg_read(struct snd_soc_component *component, + struct wsa_temp_register *wsa_temp_reg) +{ + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + int ret = 0; + + if (!wsa881x) { + dev_err(component->dev, "%s: wsa881x is NULL\n", __func__); + return -EINVAL; + } + ret = wsa881x_resource_acquire(component, true); + if (ret) { + dev_err_ratelimited(component->dev, + "%s: resource acquire fail\n", __func__); + return ret; + } + + if (WSA881X_IS_2_0(wsa881x->version)) { + snd_soc_component_update_bits(component, + WSA881X_TADC_VALUE_CTL, 0x01, 0x00); + wsa_temp_reg->dmeas_msb = + snd_soc_component_read32(component, + WSA881X_TEMP_MSB); + wsa_temp_reg->dmeas_lsb = + snd_soc_component_read32(component, + WSA881X_TEMP_LSB); + snd_soc_component_update_bits(component, + WSA881X_TADC_VALUE_CTL, 0x01, 0x01); + } else { + wsa_temp_reg->dmeas_msb = snd_soc_component_read32(component, + WSA881X_TEMP_DOUT_MSB); + wsa_temp_reg->dmeas_lsb = snd_soc_component_read32(component, + WSA881X_TEMP_DOUT_LSB); + } + wsa_temp_reg->d1_msb = snd_soc_component_read32(component, + WSA881X_OTP_REG_1); + wsa_temp_reg->d1_lsb = snd_soc_component_read32(component, + WSA881X_OTP_REG_2); + wsa_temp_reg->d2_msb = snd_soc_component_read32(component, + WSA881X_OTP_REG_3); + wsa_temp_reg->d2_lsb = snd_soc_component_read32(component, + WSA881X_OTP_REG_4); + + ret = wsa881x_resource_acquire(component, false); + if (ret) + dev_err_ratelimited(component->dev, + "%s: resource release fail\n", __func__); + + return ret; +} + +static int wsa881x_probe(struct snd_soc_component *component) +{ + struct i2c_client *client; + int ret = 0; + int wsa881x_index = 0; + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); + char *widget_name = NULL; + struct snd_soc_card *card = component->card; + struct snd_soc_codec_conf *codec_conf = card->codec_conf; + + client = dev_get_drvdata(component->dev); + ret = wsa881x_i2c_get_client_index(client, &wsa881x_index); + if (ret != 0) { + dev_err(&client->dev, "%s: I2C get codec I2C\n" + "client failed\n", __func__); + return ret; + } + mutex_init(&wsa_pdata[wsa881x_index].bg_lock); + mutex_init(&wsa_pdata[wsa881x_index].res_lock); + snprintf(wsa_pdata[wsa881x_index].tz_pdata.name, 100, "%s", + wsa_tz_names[wsa881x_index]); + wsa_pdata[wsa881x_index].component = component; + wsa_pdata[wsa881x_index].spk_pa_gain = SPK_GAIN_12DB; + wsa_pdata[wsa881x_index].component = component; + wsa_pdata[wsa881x_index].tz_pdata.component = component; + wsa_pdata[wsa881x_index].tz_pdata.wsa_temp_reg_read = + wsa881x_temp_reg_read; + snd_soc_component_set_drvdata(component, &wsa_pdata[wsa881x_index]); + wsa881x_init_thermal(&wsa_pdata[wsa881x_index].tz_pdata); + INIT_DELAYED_WORK(&wsa_pdata[wsa881x_index].ocp_ctl_work, + wsa881x_ocp_ctl_work); + + if (codec_conf->name_prefix) { + widget_name = kcalloc(WIDGET_NAME_MAX_SIZE, sizeof(char), + GFP_KERNEL); + if (!widget_name) + return -ENOMEM; + + snprintf(widget_name, WIDGET_NAME_MAX_SIZE, + "%s WSA_SPKR", codec_conf->name_prefix); + snd_soc_dapm_ignore_suspend(dapm, widget_name); + snprintf(widget_name, WIDGET_NAME_MAX_SIZE, + "%s WSA_IN", codec_conf->name_prefix); + snd_soc_dapm_ignore_suspend(dapm, widget_name); + kfree(widget_name); + } else { + snd_soc_dapm_ignore_suspend(dapm, "WSA_SPKR"); + snd_soc_dapm_ignore_suspend(dapm, "WSA_IN"); + } + + snd_soc_dapm_sync(dapm); + + return 0; +} + +static void wsa881x_remove(struct snd_soc_component *component) +{ + struct wsa881x_pdata *wsa881x = + snd_soc_component_get_drvdata(component); + + if (wsa881x->tz_pdata.tz_dev) + wsa881x_deinit_thermal(wsa881x->tz_pdata.tz_dev); + + mutex_destroy(&wsa881x->bg_lock); + mutex_destroy(&wsa881x->res_lock); +} + +static const struct snd_soc_component_driver soc_component_dev_wsa881x = { + .probe = wsa881x_probe, + .remove = wsa881x_remove, + + .read = wsa881x_i2c_read, + .write = wsa881x_i2c_write, + + .controls = wsa881x_snd_controls, + .num_controls = ARRAY_SIZE(wsa881x_snd_controls), + .dapm_widgets = wsa881x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wsa881x_dapm_widgets), + .dapm_routes = wsa881x_audio_map, + .num_dapm_routes = ARRAY_SIZE(wsa881x_audio_map), +}; + +static int wsa881x_reset(struct wsa881x_pdata *pdata, bool enable) +{ + int ret = 0; + + /* + * shutdown the GPIOs WSA_EN, WSA_MCLK, regulators + * and restore defaults in soc cache when shutdown. + * Enable regulators, GPIOs WSA_MCLK, WSA_EN when powerup. + */ + if (enable) { + if (pdata->wsa_active) + return 0; + ret = msm_cdc_pinctrl_select_active_state( + pdata->wsa_reset_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be activated %s\n", + __func__, "wsa_reset"); + return ret; + } + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->wsa_reset_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be suspended(powerup) %s\n", + __func__, "wsa_reset"); + return ret; + } + ret = msm_cdc_pinctrl_select_active_state( + pdata->wsa_reset_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be activated %s\n", + __func__, "wsa_reset"); + return ret; + } + pdata->wsa_active = true; + } else { + if (!pdata->wsa_active) + return 0; + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->wsa_reset_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be suspended %s\n", + __func__, "wsa_reset"); + return ret; + } + pdata->wsa_active = false; + } + return ret; +} + +int wsa881x_get_client_index(void) +{ + return wsa881x_i2c_addr; +} +EXPORT_SYMBOL(wsa881x_get_client_index); + +int wsa881x_get_probing_count(void) +{ + return wsa881x_probing_count; +} +EXPORT_SYMBOL(wsa881x_get_probing_count); + +int wsa881x_get_presence_count(void) +{ + return wsa881x_presence_count; +} +EXPORT_SYMBOL(wsa881x_get_presence_count); + +static int check_wsa881x_presence(struct i2c_client *client) +{ + int ret = 0; + int wsa881x_index = 0; + + ret = wsa881x_i2c_get_client_index(client, &wsa881x_index); + if (ret != 0) { + dev_err(&client->dev, "%s: I2C get codec I2C\n" + "client failed\n", __func__); + return ret; + } + ret = wsa881x_i2c_read_device(&wsa_pdata[wsa881x_index], + WSA881X_CDC_RST_CTL); + if (ret < 0) { + dev_err(&client->dev, "failed to read wsa881x with addr %x\n", + client->addr); + return ret; + } + ret = wsa881x_i2c_write_device(&wsa_pdata[wsa881x_index], + WSA881X_CDC_RST_CTL, 0x01); + if (ret < 0) { + dev_err(&client->dev, "failed write addr %x reg:0x5 val:0x1\n", + client->addr); + return ret; + } + /* allow 20ms before trigger next write to verify wsa881x presence */ + msleep(20); + ret = wsa881x_i2c_write_device(&wsa_pdata[wsa881x_index], + WSA881X_CDC_RST_CTL, 0x00); + if (ret < 0) { + dev_err(&client->dev, "failed write addr %x reg:0x5 val:0x0\n", + client->addr); + return ret; + } + return ret; +} + +static int wsa881x_populate_dt_pdata(struct device *dev, int wsa881x_index) +{ + int ret = 0; + struct wsa881x_pdata *pdata = &wsa_pdata[wsa881x_index]; + + /* reading the gpio configurations from dtsi file */ + pdata->wsa_vi_gpio_p = of_parse_phandle(dev->of_node, + "qcom,wsa-analog-vi-gpio", 0); + pdata->wsa_clk_gpio_p = of_parse_phandle(dev->of_node, + "qcom,wsa-analog-clk-gpio", 0); + pdata->wsa_reset_gpio_p = of_parse_phandle(dev->of_node, + "qcom,wsa-analog-reset-gpio", 0); + pinctrl_init = true; + return ret; +} + +static int wsa881x_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret = 0; + int wsa881x_index = 0; + struct wsa881x_pdata *pdata = NULL; + struct clk *wsa_mclk = NULL; + + ret = wsa881x_i2c_get_client_index(client, &wsa881x_index); + if (ret != 0) { + dev_err(&client->dev, "%s: I2C get codec I2C\n" + "client failed\n", __func__); + return ret; + } + + pdata = &wsa_pdata[wsa881x_index]; + if ((client->addr == WSA881X_I2C_SPK0_SLAVE1_ADDR || + client->addr == WSA881X_I2C_SPK1_SLAVE1_ADDR) && + (pdata->status == WSA881X_STATUS_PROBING)) { + wsa881x_probing_count++; + return ret; + } + + if (pdata->status == WSA881X_STATUS_I2C) { + dev_dbg(&client->dev, "%s:probe for other slaves\n" + "devices of codec I2C slave Addr = %x\n", + __func__, client->addr); + dev_dbg(&client->dev, "%s:wsa_idx = %d SLAVE = %d\n", + __func__, wsa881x_index, WSA881X_ANALOG_SLAVE); + pdata->regmap[WSA881X_ANALOG_SLAVE] = + devm_regmap_init_i2c( + client, + &wsa881x_ana_regmap_config[WSA881X_ANALOG_SLAVE]); + regcache_cache_bypass(pdata->regmap[WSA881X_ANALOG_SLAVE], + true); + if (IS_ERR(pdata->regmap[WSA881X_ANALOG_SLAVE])) { + ret = PTR_ERR(pdata->regmap[WSA881X_ANALOG_SLAVE]); + dev_err(&client->dev, + "%s: regmap_init failed %d\n", + __func__, ret); + } + client->dev.platform_data = pdata; + i2c_set_clientdata(client, pdata); + pdata->client[WSA881X_ANALOG_SLAVE] = client; + if (pdata->version == WSA881X_2_0) + wsa881x_update_regmap_2_0( + pdata->regmap[WSA881X_ANALOG_SLAVE], + WSA881X_ANALOG_SLAVE); + + wsa881x_probing_count++; + return ret; + } else if (pdata->status == WSA881X_STATUS_PROBING) { + pdata->index = wsa881x_index; + if (client->dev.of_node) { + dev_dbg(&client->dev, "%s:Platform data\n" + "from device tree\n", __func__); + ret = wsa881x_populate_dt_pdata( + &client->dev, wsa881x_index); + if (ret < 0) { + dev_err(&client->dev, + "%s: Fail to obtain pdata from device tree\n", + __func__); + ret = -EINVAL; + goto err; + } + client->dev.platform_data = pdata; + } else { + dev_dbg(&client->dev, "%s:Platform data from\n" + "board file\n", __func__); + pdata = client->dev.platform_data; + } + if (!pdata) { + dev_dbg(&client->dev, "no platform data?\n"); + ret = -EINVAL; + goto err; + } + dev_set_drvdata(&client->dev, client); + + pdata->regmap[WSA881X_DIGITAL_SLAVE] = + devm_regmap_init_i2c( + client, + &wsa881x_ana_regmap_config[WSA881X_DIGITAL_SLAVE]); + regcache_cache_bypass(pdata->regmap[WSA881X_DIGITAL_SLAVE], + true); + if (IS_ERR(pdata->regmap[WSA881X_DIGITAL_SLAVE])) { + ret = PTR_ERR(pdata->regmap[WSA881X_DIGITAL_SLAVE]); + dev_err(&client->dev, "%s: regmap_init failed %d\n", + __func__, ret); + goto err; + } + wsa_mclk = devm_clk_get(&client->dev, "wsa_mclk"); + if (IS_ERR(wsa_mclk)) { + ret = PTR_ERR(wsa_mclk); + dev_dbg(&client->dev, "%s: clk get %s failed %d\n", + __func__, "wsa_mclk", ret); + wsa_mclk = NULL; + ret = 0; + } + pdata->wsa_mclk = wsa_mclk; + + /* bus reset sequence */ + ret = wsa881x_reset(pdata, true); + if (ret < 0) { + wsa881x_probing_count++; + dev_err(&client->dev, "%s: WSA enable Failed %d\n", + __func__, ret); + goto err; + } + pdata->client[WSA881X_DIGITAL_SLAVE] = client; + pdata->regmap_flag = true; + ret = check_wsa881x_presence(client); + if (ret < 0) { + dev_err(&client->dev, + "failed to ping wsa with addr:%x, ret = %d\n", + client->addr, ret); + wsa881x_probing_count++; + goto err1; + } + pdata->version = wsa881x_i2c_read_device(pdata, + WSA881X_CHIP_ID1); + pr_debug("%s: wsa881x version: %d\n", __func__, pdata->version); + if (pdata->version == WSA881X_2_0) { + wsa881x_update_reg_defaults_2_0(); + wsa881x_update_regmap_2_0( + pdata->regmap[WSA881X_DIGITAL_SLAVE], + WSA881X_DIGITAL_SLAVE); + } + wsa881x_presence_count++; + wsa881x_probing_count++; + ret = snd_soc_register_component(&client->dev, + &soc_component_dev_wsa881x, + NULL, 0); + if (ret < 0) + goto err1; + pdata->status = WSA881X_STATUS_I2C; + } +err1: + wsa881x_reset(pdata, false); +err: + return 0; +} + +static int wsa881x_i2c_remove(struct i2c_client *client) +{ + struct wsa881x_pdata *wsa881x = client->dev.platform_data; + + snd_soc_unregister_component(&client->dev); + i2c_set_clientdata(client, NULL); + kfree(wsa881x); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int wsa881x_i2c_suspend(struct device *dev) +{ + pr_debug("%s: system suspend\n", __func__); + return 0; +} + +static int wsa881x_i2c_resume(struct device *dev) +{ + pr_debug("%s: system resume\n", __func__); + return 0; +} + +static const struct dev_pm_ops wsa881x_i2c_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(wsa881x_i2c_suspend, wsa881x_i2c_resume) +}; +#endif /* CONFIG_PM_SLEEP */ + +static const struct i2c_device_id wsa881x_i2c_id[] = { + {"wsa881x-i2c-dev", WSA881X_I2C_SPK0_SLAVE0_ADDR}, + {"wsa881x-i2c-dev", WSA881X_I2C_SPK0_SLAVE1_ADDR}, + {"wsa881x-i2c-dev", WSA881X_I2C_SPK1_SLAVE0_ADDR}, + {"wsa881x-i2c-dev", WSA881X_I2C_SPK1_SLAVE1_ADDR}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, wsa881x_i2c_id); + + +static const struct of_device_id msm_match_table[] = { + {.compatible = "qcom,wsa881x-i2c-codec"}, + {} +}; +MODULE_DEVICE_TABLE(of, msm_match_table); + +static struct i2c_driver wsa881x_codec_driver = { + .driver = { + .name = "wsa881x-i2c-codec", + .owner = THIS_MODULE, + .probe_type = PROBE_PREFER_ASYNCHRONOUS, +#ifdef CONFIG_PM_SLEEP + .pm = &wsa881x_i2c_pm_ops, +#endif + .of_match_table = msm_match_table, + }, + .id_table = wsa881x_i2c_id, + .probe = wsa881x_i2c_probe, + .remove = wsa881x_i2c_remove, +}; + +static int __init wsa881x_codec_init(void) +{ + int i = 0; + + for (i = 0; i < MAX_WSA881X_DEVICE; i++) + wsa_pdata[i].status = WSA881X_STATUS_PROBING; + return i2c_add_driver(&wsa881x_codec_driver); +} +module_init(wsa881x_codec_init); + +static void __exit wsa881x_codec_exit(void) +{ + i2c_del_driver(&wsa881x_codec_driver); +} + +module_exit(wsa881x_codec_exit); + +MODULE_DESCRIPTION("WSA881x Codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/wsa881x-analog.h b/asoc/codecs/wsa881x-analog.h new file mode 100644 index 000000000000..0aa86a97b185 --- /dev/null +++ b/asoc/codecs/wsa881x-analog.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2015, 2018-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef _WSA881X_H +#define _WSA881X_H + +#include +#include "wsa881x-registers-analog.h" +#include + +#define WSA881X_I2C_SPK0_SLAVE0_ADDR 0x0E +#define WSA881X_I2C_SPK0_SLAVE1_ADDR 0x44 +#define WSA881X_I2C_SPK1_SLAVE0_ADDR 0x0F +#define WSA881X_I2C_SPK1_SLAVE1_ADDR 0x45 + +#define WSA881X_I2C_SPK0_SLAVE0 0 +#define WSA881X_I2C_SPK1_SLAVE0 1 +#define MAX_WSA881X_DEVICE 2 +#define WSA881X_DIGITAL_SLAVE 0 +#define WSA881X_ANALOG_SLAVE 1 + +enum { + WSA881X_1_X = 0, + WSA881X_2_0, +}; + +#define WSA881X_IS_2_0(ver) \ + ((ver == WSA881X_2_0) ? 1 : 0) + +extern const u8 wsa881x_ana_reg_readable[WSA881X_CACHE_SIZE]; +extern struct reg_default wsa881x_ana_reg_defaults[WSA881X_CACHE_SIZE]; +extern struct regmap_config wsa881x_ana_regmap_config[2]; +int wsa881x_get_client_index(void); +int wsa881x_get_probing_count(void); +int wsa881x_get_presence_count(void); +int wsa881x_set_mclk_callback( + int (*enable_mclk_callback)(struct snd_soc_card *, bool)); +void wsa881x_update_reg_defaults_2_0(void); +void wsa881x_update_regmap_2_0(struct regmap *regmap, int flag); + +#endif /* _WSA881X_H */ diff --git a/asoc/codecs/wsa881x-registers-analog.h b/asoc/codecs/wsa881x-registers-analog.h new file mode 100644 index 000000000000..2f24023cddd9 --- /dev/null +++ b/asoc/codecs/wsa881x-registers-analog.h @@ -0,0 +1,199 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2015, 2018-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef WSA881X_REGISTERS_H +#define WSA881X_REGISTERS_H + +#define WSA881X_DIGITAL_BASE 0x0000 +#define WSA881X_ANALOG_BASE 0x0100 + +#define WSA881X_CHIP_ID0 (WSA881X_DIGITAL_BASE+0x0000) +#define WSA881X_CHIP_ID1 (WSA881X_DIGITAL_BASE+0x0001) +#define WSA881X_CHIP_ID2 (WSA881X_DIGITAL_BASE+0x0002) +#define WSA881X_CHIP_ID3 (WSA881X_DIGITAL_BASE+0x0003) +#define WSA881X_BUS_ID (WSA881X_DIGITAL_BASE+0x0004) +#define WSA881X_CDC_RST_CTL (WSA881X_DIGITAL_BASE+0x0005) +#define WSA881X_CDC_TOP_CLK_CTL (WSA881X_DIGITAL_BASE+0x0006) +#define WSA881X_CDC_ANA_CLK_CTL (WSA881X_DIGITAL_BASE+0x0007) +#define WSA881X_CDC_DIG_CLK_CTL (WSA881X_DIGITAL_BASE+0x0008) +#define WSA881X_CLOCK_CONFIG (WSA881X_DIGITAL_BASE+0x0009) +#define WSA881X_ANA_CTL (WSA881X_DIGITAL_BASE+0x000A) +#define WSA881X_SWR_RESET_EN (WSA881X_DIGITAL_BASE+0x000B) +#define WSA881X_RESET_CTL (WSA881X_DIGITAL_BASE+0x000C) +#define WSA881X_TADC_VALUE_CTL (WSA881X_DIGITAL_BASE+0x000F) +#define WSA881X_TEMP_DETECT_CTL (WSA881X_DIGITAL_BASE+0x0010) +#define WSA881X_TEMP_MSB (WSA881X_DIGITAL_BASE+0x0011) +#define WSA881X_TEMP_LSB (WSA881X_DIGITAL_BASE+0x0012) +#define WSA881X_TEMP_CONFIG0 (WSA881X_DIGITAL_BASE+0x0013) +#define WSA881X_TEMP_CONFIG1 (WSA881X_DIGITAL_BASE+0x0014) +#define WSA881X_CDC_CLIP_CTL (WSA881X_DIGITAL_BASE+0x0015) +#define WSA881X_SDM_PDM9_LSB (WSA881X_DIGITAL_BASE+0x0016) +#define WSA881X_SDM_PDM9_MSB (WSA881X_DIGITAL_BASE+0x0017) +#define WSA881X_CDC_RX_CTL (WSA881X_DIGITAL_BASE+0x0018) +#define WSA881X_DEM_BYPASS_DATA0 (WSA881X_DIGITAL_BASE+0x0019) +#define WSA881X_DEM_BYPASS_DATA1 (WSA881X_DIGITAL_BASE+0x001A) +#define WSA881X_DEM_BYPASS_DATA2 (WSA881X_DIGITAL_BASE+0x001B) +#define WSA881X_DEM_BYPASS_DATA3 (WSA881X_DIGITAL_BASE+0x001C) +#define WSA881X_OTP_CTRL0 (WSA881X_DIGITAL_BASE+0x001D) +#define WSA881X_OTP_CTRL1 (WSA881X_DIGITAL_BASE+0x001E) +#define WSA881X_HDRIVE_CTL_GROUP1 (WSA881X_DIGITAL_BASE+0x001F) +#define WSA881X_INTR_MODE (WSA881X_DIGITAL_BASE+0x0020) +#define WSA881X_INTR_MASK (WSA881X_DIGITAL_BASE+0x0021) +#define WSA881X_INTR_STATUS (WSA881X_DIGITAL_BASE+0x0022) +#define WSA881X_INTR_CLEAR (WSA881X_DIGITAL_BASE+0x0023) +#define WSA881X_INTR_LEVEL (WSA881X_DIGITAL_BASE+0x0024) +#define WSA881X_INTR_SET (WSA881X_DIGITAL_BASE+0x0025) +#define WSA881X_INTR_TEST (WSA881X_DIGITAL_BASE+0x0026) +#define WSA881X_PDM_TEST_MODE (WSA881X_DIGITAL_BASE+0x0030) +#define WSA881X_ATE_TEST_MODE (WSA881X_DIGITAL_BASE+0x0031) +#define WSA881X_PIN_CTL_MODE (WSA881X_DIGITAL_BASE+0x0032) +#define WSA881X_PIN_CTL_OE (WSA881X_DIGITAL_BASE+0x0033) +#define WSA881X_PIN_WDATA_IOPAD (WSA881X_DIGITAL_BASE+0x0034) +#define WSA881X_PIN_STATUS (WSA881X_DIGITAL_BASE+0x0035) +#define WSA881X_DIG_DEBUG_MODE (WSA881X_DIGITAL_BASE+0x0037) +#define WSA881X_DIG_DEBUG_SEL (WSA881X_DIGITAL_BASE+0x0038) +#define WSA881X_DIG_DEBUG_EN (WSA881X_DIGITAL_BASE+0x0039) +#define WSA881X_SWR_HM_TEST1 (WSA881X_DIGITAL_BASE+0x003B) +#define WSA881X_SWR_HM_TEST2 (WSA881X_DIGITAL_BASE+0x003C) +#define WSA881X_TEMP_DETECT_DBG_CTL (WSA881X_DIGITAL_BASE+0x003D) +#define WSA881X_TEMP_DEBUG_MSB (WSA881X_DIGITAL_BASE+0x003E) +#define WSA881X_TEMP_DEBUG_LSB (WSA881X_DIGITAL_BASE+0x003F) +#define WSA881X_SAMPLE_EDGE_SEL (WSA881X_DIGITAL_BASE+0x0044) +#define WSA881X_IOPAD_CTL (WSA881X_DIGITAL_BASE+0x0045) +#define WSA881X_SPARE_0 (WSA881X_DIGITAL_BASE+0x0050) +#define WSA881X_SPARE_1 (WSA881X_DIGITAL_BASE+0x0051) +#define WSA881X_SPARE_2 (WSA881X_DIGITAL_BASE+0x0052) +#define WSA881X_OTP_REG_0 (WSA881X_DIGITAL_BASE+0x0080) +#define WSA881X_OTP_REG_1 (WSA881X_DIGITAL_BASE+0x0081) +#define WSA881X_OTP_REG_2 (WSA881X_DIGITAL_BASE+0x0082) +#define WSA881X_OTP_REG_3 (WSA881X_DIGITAL_BASE+0x0083) +#define WSA881X_OTP_REG_4 (WSA881X_DIGITAL_BASE+0x0084) +#define WSA881X_OTP_REG_5 (WSA881X_DIGITAL_BASE+0x0085) +#define WSA881X_OTP_REG_6 (WSA881X_DIGITAL_BASE+0x0086) +#define WSA881X_OTP_REG_7 (WSA881X_DIGITAL_BASE+0x0087) +#define WSA881X_OTP_REG_8 (WSA881X_DIGITAL_BASE+0x0088) +#define WSA881X_OTP_REG_9 (WSA881X_DIGITAL_BASE+0x0089) +#define WSA881X_OTP_REG_10 (WSA881X_DIGITAL_BASE+0x008A) +#define WSA881X_OTP_REG_11 (WSA881X_DIGITAL_BASE+0x008B) +#define WSA881X_OTP_REG_12 (WSA881X_DIGITAL_BASE+0x008C) +#define WSA881X_OTP_REG_13 (WSA881X_DIGITAL_BASE+0x008D) +#define WSA881X_OTP_REG_14 (WSA881X_DIGITAL_BASE+0x008E) +#define WSA881X_OTP_REG_15 (WSA881X_DIGITAL_BASE+0x008F) +#define WSA881X_OTP_REG_16 (WSA881X_DIGITAL_BASE+0x0090) +#define WSA881X_OTP_REG_17 (WSA881X_DIGITAL_BASE+0x0091) +#define WSA881X_OTP_REG_18 (WSA881X_DIGITAL_BASE+0x0092) +#define WSA881X_OTP_REG_19 (WSA881X_DIGITAL_BASE+0x0093) +#define WSA881X_OTP_REG_20 (WSA881X_DIGITAL_BASE+0x0094) +#define WSA881X_OTP_REG_21 (WSA881X_DIGITAL_BASE+0x0095) +#define WSA881X_OTP_REG_22 (WSA881X_DIGITAL_BASE+0x0096) +#define WSA881X_OTP_REG_23 (WSA881X_DIGITAL_BASE+0x0097) +#define WSA881X_OTP_REG_24 (WSA881X_DIGITAL_BASE+0x0098) +#define WSA881X_OTP_REG_25 (WSA881X_DIGITAL_BASE+0x0099) +#define WSA881X_OTP_REG_26 (WSA881X_DIGITAL_BASE+0x009A) +#define WSA881X_OTP_REG_27 (WSA881X_DIGITAL_BASE+0x009B) +#define WSA881X_OTP_REG_28 (WSA881X_DIGITAL_BASE+0x009C) +#define WSA881X_OTP_REG_29 (WSA881X_DIGITAL_BASE+0x009D) +#define WSA881X_OTP_REG_30 (WSA881X_DIGITAL_BASE+0x009E) +#define WSA881X_OTP_REG_31 (WSA881X_DIGITAL_BASE+0x009F) +#define WSA881X_OTP_REG_32 (WSA881X_DIGITAL_BASE+0x00A0) +#define WSA881X_OTP_REG_33 (WSA881X_DIGITAL_BASE+0x00A1) +#define WSA881X_OTP_REG_34 (WSA881X_DIGITAL_BASE+0x00A2) +#define WSA881X_OTP_REG_35 (WSA881X_DIGITAL_BASE+0x00A3) +#define WSA881X_OTP_REG_36 (WSA881X_DIGITAL_BASE+0x00A4) +#define WSA881X_OTP_REG_37 (WSA881X_DIGITAL_BASE+0x00A5) +#define WSA881X_OTP_REG_38 (WSA881X_DIGITAL_BASE+0x00A6) +#define WSA881X_OTP_REG_39 (WSA881X_DIGITAL_BASE+0x00A7) +#define WSA881X_OTP_REG_40 (WSA881X_DIGITAL_BASE+0x00A8) +#define WSA881X_OTP_REG_41 (WSA881X_DIGITAL_BASE+0x00A9) +#define WSA881X_OTP_REG_42 (WSA881X_DIGITAL_BASE+0x00AA) +#define WSA881X_OTP_REG_43 (WSA881X_DIGITAL_BASE+0x00AB) +#define WSA881X_OTP_REG_44 (WSA881X_DIGITAL_BASE+0x00AC) +#define WSA881X_OTP_REG_45 (WSA881X_DIGITAL_BASE+0x00AD) +#define WSA881X_OTP_REG_46 (WSA881X_DIGITAL_BASE+0x00AE) +#define WSA881X_OTP_REG_47 (WSA881X_DIGITAL_BASE+0x00AF) +#define WSA881X_OTP_REG_48 (WSA881X_DIGITAL_BASE+0x00B0) +#define WSA881X_OTP_REG_49 (WSA881X_DIGITAL_BASE+0x00B1) +#define WSA881X_OTP_REG_50 (WSA881X_DIGITAL_BASE+0x00B2) +#define WSA881X_OTP_REG_51 (WSA881X_DIGITAL_BASE+0x00B3) +#define WSA881X_OTP_REG_52 (WSA881X_DIGITAL_BASE+0x00B4) +#define WSA881X_OTP_REG_53 (WSA881X_DIGITAL_BASE+0x00B5) +#define WSA881X_OTP_REG_54 (WSA881X_DIGITAL_BASE+0x00B6) +#define WSA881X_OTP_REG_55 (WSA881X_DIGITAL_BASE+0x00B7) +#define WSA881X_OTP_REG_56 (WSA881X_DIGITAL_BASE+0x00B8) +#define WSA881X_OTP_REG_57 (WSA881X_DIGITAL_BASE+0x00B9) +#define WSA881X_OTP_REG_58 (WSA881X_DIGITAL_BASE+0x00BA) +#define WSA881X_OTP_REG_59 (WSA881X_DIGITAL_BASE+0x00BB) +#define WSA881X_OTP_REG_60 (WSA881X_DIGITAL_BASE+0x00BC) +#define WSA881X_OTP_REG_61 (WSA881X_DIGITAL_BASE+0x00BD) +#define WSA881X_OTP_REG_62 (WSA881X_DIGITAL_BASE+0x00BE) +#define WSA881X_OTP_REG_63 (WSA881X_DIGITAL_BASE+0x00BF) +/* Analog Register address space */ +#define WSA881X_BIAS_REF_CTRL (WSA881X_ANALOG_BASE+0x0000) +#define WSA881X_BIAS_TEST (WSA881X_ANALOG_BASE+0x0001) +#define WSA881X_BIAS_BIAS (WSA881X_ANALOG_BASE+0x0002) +#define WSA881X_TEMP_OP (WSA881X_ANALOG_BASE+0x0003) +#define WSA881X_TEMP_IREF_CTRL (WSA881X_ANALOG_BASE+0x0004) +#define WSA881X_TEMP_ISENS_CTRL (WSA881X_ANALOG_BASE+0x0005) +#define WSA881X_TEMP_CLK_CTRL (WSA881X_ANALOG_BASE+0x0006) +#define WSA881X_TEMP_TEST (WSA881X_ANALOG_BASE+0x0007) +#define WSA881X_TEMP_BIAS (WSA881X_ANALOG_BASE+0x0008) +#define WSA881X_TEMP_ADC_CTRL (WSA881X_ANALOG_BASE+0x0009) +#define WSA881X_TEMP_DOUT_MSB (WSA881X_ANALOG_BASE+0x000A) +#define WSA881X_TEMP_DOUT_LSB (WSA881X_ANALOG_BASE+0x000B) +#define WSA881X_ADC_EN_MODU_V (WSA881X_ANALOG_BASE+0x0010) +#define WSA881X_ADC_EN_MODU_I (WSA881X_ANALOG_BASE+0x0011) +#define WSA881X_ADC_EN_DET_TEST_V (WSA881X_ANALOG_BASE+0x0012) +#define WSA881X_ADC_EN_DET_TEST_I (WSA881X_ANALOG_BASE+0x0013) +#define WSA881X_ADC_SEL_IBIAS (WSA881X_ANALOG_BASE+0x0014) +#define WSA881X_ADC_EN_SEL_IBIAS (WSA881X_ANALOG_BASE+0x0015) +#define WSA881X_SPKR_DRV_EN (WSA881X_ANALOG_BASE+0x001A) +#define WSA881X_SPKR_DRV_GAIN (WSA881X_ANALOG_BASE+0x001B) +#define WSA881X_SPKR_DAC_CTL (WSA881X_ANALOG_BASE+0x001C) +#define WSA881X_SPKR_DRV_DBG (WSA881X_ANALOG_BASE+0x001D) +#define WSA881X_SPKR_PWRSTG_DBG (WSA881X_ANALOG_BASE+0x001E) +#define WSA881X_SPKR_OCP_CTL (WSA881X_ANALOG_BASE+0x001F) +#define WSA881X_SPKR_CLIP_CTL (WSA881X_ANALOG_BASE+0x0020) +#define WSA881X_SPKR_BBM_CTL (WSA881X_ANALOG_BASE+0x0021) +#define WSA881X_SPKR_MISC_CTL1 (WSA881X_ANALOG_BASE+0x0022) +#define WSA881X_SPKR_MISC_CTL2 (WSA881X_ANALOG_BASE+0x0023) +#define WSA881X_SPKR_BIAS_INT (WSA881X_ANALOG_BASE+0x0024) +#define WSA881X_SPKR_PA_INT (WSA881X_ANALOG_BASE+0x0025) +#define WSA881X_SPKR_BIAS_CAL (WSA881X_ANALOG_BASE+0x0026) +#define WSA881X_SPKR_BIAS_PSRR (WSA881X_ANALOG_BASE+0x0027) +#define WSA881X_SPKR_STATUS1 (WSA881X_ANALOG_BASE+0x0028) +#define WSA881X_SPKR_STATUS2 (WSA881X_ANALOG_BASE+0x0029) +#define WSA881X_BOOST_EN_CTL (WSA881X_ANALOG_BASE+0x002A) +#define WSA881X_BOOST_CURRENT_LIMIT (WSA881X_ANALOG_BASE+0x002B) +#define WSA881X_BOOST_PS_CTL (WSA881X_ANALOG_BASE+0x002C) +#define WSA881X_BOOST_PRESET_OUT1 (WSA881X_ANALOG_BASE+0x002D) +#define WSA881X_BOOST_PRESET_OUT2 (WSA881X_ANALOG_BASE+0x002E) +#define WSA881X_BOOST_FORCE_OUT (WSA881X_ANALOG_BASE+0x002F) +#define WSA881X_BOOST_LDO_PROG (WSA881X_ANALOG_BASE+0x0030) +#define WSA881X_BOOST_SLOPE_COMP_ISENSE_FB (WSA881X_ANALOG_BASE+0x0031) +#define WSA881X_BOOST_RON_CTL (WSA881X_ANALOG_BASE+0x0032) +#define WSA881X_BOOST_LOOP_STABILITY (WSA881X_ANALOG_BASE+0x0033) +#define WSA881X_BOOST_ZX_CTL (WSA881X_ANALOG_BASE+0x0034) +#define WSA881X_BOOST_START_CTL (WSA881X_ANALOG_BASE+0x0035) +#define WSA881X_BOOST_MISC1_CTL (WSA881X_ANALOG_BASE+0x0036) +#define WSA881X_BOOST_MISC2_CTL (WSA881X_ANALOG_BASE+0x0037) +#define WSA881X_BOOST_MISC3_CTL (WSA881X_ANALOG_BASE+0x0038) +#define WSA881X_BOOST_ATEST_CTL (WSA881X_ANALOG_BASE+0x0039) +#define WSA881X_SPKR_PROT_FE_GAIN (WSA881X_ANALOG_BASE+0x003A) +#define WSA881X_SPKR_PROT_FE_CM_LDO_SET (WSA881X_ANALOG_BASE+0x003B) +#define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1 (WSA881X_ANALOG_BASE+0x003C) +#define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2 (WSA881X_ANALOG_BASE+0x003D) +#define WSA881X_SPKR_PROT_ATEST1 (WSA881X_ANALOG_BASE+0x003E) +#define WSA881X_SPKR_PROT_ATEST2 (WSA881X_ANALOG_BASE+0x003F) +#define WSA881X_SPKR_PROT_FE_VSENSE_VCM (WSA881X_ANALOG_BASE+0x0040) +#define WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1 (WSA881X_ANALOG_BASE+0x0041) +#define WSA881X_BONGO_RESRV_REG1 (WSA881X_ANALOG_BASE+0x0042) +#define WSA881X_BONGO_RESRV_REG2 (WSA881X_ANALOG_BASE+0x0043) +#define WSA881X_SPKR_PROT_SAR (WSA881X_ANALOG_BASE+0x0044) +#define WSA881X_SPKR_STATUS3 (WSA881X_ANALOG_BASE+0x0045) + +#define WSA881X_NUM_REGISTERS (WSA881X_SPKR_STATUS3+1) +#define WSA881X_MAX_REGISTER (WSA881X_NUM_REGISTERS-1) +#define WSA881X_CACHE_SIZE WSA881X_NUM_REGISTERS +#endif /* WSA881X_REGISTERS_H */ diff --git a/asoc/codecs/wsa881x-regmap-analog.c b/asoc/codecs/wsa881x-regmap-analog.c new file mode 100644 index 000000000000..7353057bfdc0 --- /dev/null +++ b/asoc/codecs/wsa881x-regmap-analog.c @@ -0,0 +1,491 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015, 2018-2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include "wsa881x-registers-analog.h" +#include "wsa881x-analog.h" + +struct reg_default wsa881x_ana_reg_defaults[] = { + {WSA881X_CHIP_ID0, 0x00}, + {WSA881X_CHIP_ID1, 0x00}, + {WSA881X_CHIP_ID2, 0x00}, + {WSA881X_CHIP_ID3, 0x02}, + {WSA881X_BUS_ID, 0x00}, + {WSA881X_CDC_RST_CTL, 0x00}, + {WSA881X_CDC_TOP_CLK_CTL, 0x03}, + {WSA881X_CDC_ANA_CLK_CTL, 0x00}, + {WSA881X_CDC_DIG_CLK_CTL, 0x00}, + {WSA881X_CLOCK_CONFIG, 0x00}, + {WSA881X_ANA_CTL, 0x08}, + {WSA881X_SWR_RESET_EN, 0x00}, + {WSA881X_TEMP_DETECT_CTL, 0x01}, + {WSA881X_TEMP_MSB, 0x00}, + {WSA881X_TEMP_LSB, 0x00}, + {WSA881X_TEMP_CONFIG0, 0x00}, + {WSA881X_TEMP_CONFIG1, 0x00}, + {WSA881X_CDC_CLIP_CTL, 0x03}, + {WSA881X_SDM_PDM9_LSB, 0x00}, + {WSA881X_SDM_PDM9_MSB, 0x00}, + {WSA881X_CDC_RX_CTL, 0x7E}, + {WSA881X_DEM_BYPASS_DATA0, 0x00}, + {WSA881X_DEM_BYPASS_DATA1, 0x00}, + {WSA881X_DEM_BYPASS_DATA2, 0x00}, + {WSA881X_DEM_BYPASS_DATA3, 0x00}, + {WSA881X_OTP_CTRL0, 0x00}, + {WSA881X_OTP_CTRL1, 0x00}, + {WSA881X_HDRIVE_CTL_GROUP1, 0x00}, + {WSA881X_INTR_MODE, 0x00}, + {WSA881X_INTR_MASK, 0x1F}, + {WSA881X_INTR_STATUS, 0x00}, + {WSA881X_INTR_CLEAR, 0x00}, + {WSA881X_INTR_LEVEL, 0x00}, + {WSA881X_INTR_SET, 0x00}, + {WSA881X_INTR_TEST, 0x00}, + {WSA881X_PDM_TEST_MODE, 0x00}, + {WSA881X_ATE_TEST_MODE, 0x00}, + {WSA881X_PIN_CTL_MODE, 0x00}, + {WSA881X_PIN_CTL_OE, 0x00}, + {WSA881X_PIN_WDATA_IOPAD, 0x00}, + {WSA881X_PIN_STATUS, 0x00}, + {WSA881X_DIG_DEBUG_MODE, 0x00}, + {WSA881X_DIG_DEBUG_SEL, 0x00}, + {WSA881X_DIG_DEBUG_EN, 0x00}, + {WSA881X_SWR_HM_TEST1, 0x08}, + {WSA881X_SWR_HM_TEST2, 0x00}, + {WSA881X_TEMP_DETECT_DBG_CTL, 0x00}, + {WSA881X_TEMP_DEBUG_MSB, 0x00}, + {WSA881X_TEMP_DEBUG_LSB, 0x00}, + {WSA881X_SAMPLE_EDGE_SEL, 0x0C}, + {WSA881X_SPARE_0, 0x00}, + {WSA881X_SPARE_1, 0x00}, + {WSA881X_SPARE_2, 0x00}, + {WSA881X_OTP_REG_0, 0x01}, + {WSA881X_OTP_REG_1, 0xFF}, + {WSA881X_OTP_REG_2, 0xC0}, + {WSA881X_OTP_REG_3, 0xFF}, + {WSA881X_OTP_REG_4, 0xC0}, + {WSA881X_OTP_REG_5, 0xFF}, + {WSA881X_OTP_REG_6, 0xFF}, + {WSA881X_OTP_REG_7, 0xFF}, + {WSA881X_OTP_REG_8, 0xFF}, + {WSA881X_OTP_REG_9, 0xFF}, + {WSA881X_OTP_REG_10, 0xFF}, + {WSA881X_OTP_REG_11, 0xFF}, + {WSA881X_OTP_REG_12, 0xFF}, + {WSA881X_OTP_REG_13, 0xFF}, + {WSA881X_OTP_REG_14, 0xFF}, + {WSA881X_OTP_REG_15, 0xFF}, + {WSA881X_OTP_REG_16, 0xFF}, + {WSA881X_OTP_REG_17, 0xFF}, + {WSA881X_OTP_REG_18, 0xFF}, + {WSA881X_OTP_REG_19, 0xFF}, + {WSA881X_OTP_REG_20, 0xFF}, + {WSA881X_OTP_REG_21, 0xFF}, + {WSA881X_OTP_REG_22, 0xFF}, + {WSA881X_OTP_REG_23, 0xFF}, + {WSA881X_OTP_REG_24, 0x03}, + {WSA881X_OTP_REG_25, 0x01}, + {WSA881X_OTP_REG_26, 0x03}, + {WSA881X_OTP_REG_27, 0x11}, + {WSA881X_OTP_REG_28, 0xFF}, + {WSA881X_OTP_REG_29, 0xFF}, + {WSA881X_OTP_REG_30, 0xFF}, + {WSA881X_OTP_REG_31, 0xFF}, + {WSA881X_OTP_REG_63, 0x40}, + /* WSA881x Analog registers */ + {WSA881X_BIAS_REF_CTRL, 0x6C}, + {WSA881X_BIAS_TEST, 0x16}, + {WSA881X_BIAS_BIAS, 0xF0}, + {WSA881X_TEMP_OP, 0x00}, + {WSA881X_TEMP_IREF_CTRL, 0x56}, + {WSA881X_TEMP_ISENS_CTRL, 0x47}, + {WSA881X_TEMP_CLK_CTRL, 0x87}, + {WSA881X_TEMP_TEST, 0x00}, + {WSA881X_TEMP_BIAS, 0x51}, + {WSA881X_TEMP_ADC_CTRL, 0x00}, + {WSA881X_TEMP_DOUT_MSB, 0x00}, + {WSA881X_TEMP_DOUT_LSB, 0x00}, + {WSA881X_ADC_EN_MODU_V, 0x00}, + {WSA881X_ADC_EN_MODU_I, 0x00}, + {WSA881X_ADC_EN_DET_TEST_V, 0x00}, + {WSA881X_ADC_EN_DET_TEST_I, 0x00}, + {WSA881X_ADC_SEL_IBIAS, 0x25}, + {WSA881X_ADC_EN_SEL_IBIAS, 0x10}, + {WSA881X_SPKR_DRV_EN, 0x74}, + {WSA881X_SPKR_DRV_GAIN, 0x01}, + {WSA881X_SPKR_DAC_CTL, 0x40}, + {WSA881X_SPKR_DRV_DBG, 0x15}, + {WSA881X_SPKR_PWRSTG_DBG, 0x00}, + {WSA881X_SPKR_OCP_CTL, 0xD4}, + {WSA881X_SPKR_CLIP_CTL, 0x90}, + {WSA881X_SPKR_BBM_CTL, 0x00}, + {WSA881X_SPKR_MISC_CTL1, 0x80}, + {WSA881X_SPKR_MISC_CTL2, 0x00}, + {WSA881X_SPKR_BIAS_INT, 0x56}, + {WSA881X_SPKR_PA_INT, 0x54}, + {WSA881X_SPKR_BIAS_CAL, 0xAC}, + {WSA881X_SPKR_BIAS_PSRR, 0x54}, + {WSA881X_SPKR_STATUS1, 0x00}, + {WSA881X_SPKR_STATUS2, 0x00}, + {WSA881X_BOOST_EN_CTL, 0x18}, + {WSA881X_BOOST_CURRENT_LIMIT, 0x7A}, + {WSA881X_BOOST_PS_CTL, 0xC0}, + {WSA881X_BOOST_PRESET_OUT1, 0x77}, + {WSA881X_BOOST_PRESET_OUT2, 0x70}, + {WSA881X_BOOST_FORCE_OUT, 0x0E}, + {WSA881X_BOOST_LDO_PROG, 0x16}, + {WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, 0x71}, + {WSA881X_BOOST_RON_CTL, 0x0F}, + {WSA881X_BOOST_LOOP_STABILITY, 0xAD}, + {WSA881X_BOOST_ZX_CTL, 0x34}, + {WSA881X_BOOST_START_CTL, 0x23}, + {WSA881X_BOOST_MISC1_CTL, 0x80}, + {WSA881X_BOOST_MISC2_CTL, 0x00}, + {WSA881X_BOOST_MISC3_CTL, 0x00}, + {WSA881X_BOOST_ATEST_CTL, 0x00}, + {WSA881X_SPKR_PROT_FE_GAIN, 0x46}, + {WSA881X_SPKR_PROT_FE_CM_LDO_SET, 0x3B}, + {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1, 0x8D}, + {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2, 0x8D}, + {WSA881X_SPKR_PROT_ATEST1, 0x01}, + {WSA881X_SPKR_PROT_ATEST2, 0x00}, + {WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x8D}, + {WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1, 0x4D}, + {WSA881X_BONGO_RESRV_REG1, 0x00}, + {WSA881X_BONGO_RESRV_REG2, 0x00}, + {WSA881X_SPKR_PROT_SAR, 0x00}, + {WSA881X_SPKR_STATUS3, 0x00}, +}; + +struct reg_default wsa881x_ana_reg_defaults_0[] = { + {WSA881X_CHIP_ID0, 0x00}, + {WSA881X_CHIP_ID1, 0x00}, + {WSA881X_CHIP_ID2, 0x00}, + {WSA881X_CHIP_ID3, 0x02}, + {WSA881X_BUS_ID, 0x00}, + {WSA881X_CDC_RST_CTL, 0x00}, + {WSA881X_CDC_TOP_CLK_CTL, 0x03}, + {WSA881X_CDC_ANA_CLK_CTL, 0x00}, + {WSA881X_CDC_DIG_CLK_CTL, 0x00}, + {WSA881X_CLOCK_CONFIG, 0x00}, + {WSA881X_ANA_CTL, 0x08}, + {WSA881X_SWR_RESET_EN, 0x00}, + {WSA881X_TEMP_DETECT_CTL, 0x01}, + {WSA881X_TEMP_MSB, 0x00}, + {WSA881X_TEMP_LSB, 0x00}, + {WSA881X_TEMP_CONFIG0, 0x00}, + {WSA881X_TEMP_CONFIG1, 0x00}, + {WSA881X_CDC_CLIP_CTL, 0x03}, + {WSA881X_SDM_PDM9_LSB, 0x00}, + {WSA881X_SDM_PDM9_MSB, 0x00}, + {WSA881X_CDC_RX_CTL, 0x7E}, + {WSA881X_DEM_BYPASS_DATA0, 0x00}, + {WSA881X_DEM_BYPASS_DATA1, 0x00}, + {WSA881X_DEM_BYPASS_DATA2, 0x00}, + {WSA881X_DEM_BYPASS_DATA3, 0x00}, + {WSA881X_OTP_CTRL0, 0x00}, + {WSA881X_OTP_CTRL1, 0x00}, + {WSA881X_HDRIVE_CTL_GROUP1, 0x00}, + {WSA881X_INTR_MODE, 0x00}, + {WSA881X_INTR_MASK, 0x1F}, + {WSA881X_INTR_STATUS, 0x00}, + {WSA881X_INTR_CLEAR, 0x00}, + {WSA881X_INTR_LEVEL, 0x00}, + {WSA881X_INTR_SET, 0x00}, + {WSA881X_INTR_TEST, 0x00}, + {WSA881X_PDM_TEST_MODE, 0x00}, + {WSA881X_ATE_TEST_MODE, 0x00}, + {WSA881X_PIN_CTL_MODE, 0x00}, + {WSA881X_PIN_CTL_OE, 0x00}, + {WSA881X_PIN_WDATA_IOPAD, 0x00}, + {WSA881X_PIN_STATUS, 0x00}, + {WSA881X_DIG_DEBUG_MODE, 0x00}, + {WSA881X_DIG_DEBUG_SEL, 0x00}, + {WSA881X_DIG_DEBUG_EN, 0x00}, + {WSA881X_SWR_HM_TEST1, 0x08}, + {WSA881X_SWR_HM_TEST2, 0x00}, + {WSA881X_TEMP_DETECT_DBG_CTL, 0x00}, + {WSA881X_TEMP_DEBUG_MSB, 0x00}, + {WSA881X_TEMP_DEBUG_LSB, 0x00}, + {WSA881X_SAMPLE_EDGE_SEL, 0x0C}, + {WSA881X_SPARE_0, 0x00}, + {WSA881X_SPARE_1, 0x00}, + {WSA881X_SPARE_2, 0x00}, + {WSA881X_OTP_REG_0, 0x01}, + {WSA881X_OTP_REG_1, 0xFF}, + {WSA881X_OTP_REG_2, 0xC0}, + {WSA881X_OTP_REG_3, 0xFF}, + {WSA881X_OTP_REG_4, 0xC0}, + {WSA881X_OTP_REG_5, 0xFF}, + {WSA881X_OTP_REG_6, 0xFF}, + {WSA881X_OTP_REG_7, 0xFF}, + {WSA881X_OTP_REG_8, 0xFF}, + {WSA881X_OTP_REG_9, 0xFF}, + {WSA881X_OTP_REG_10, 0xFF}, + {WSA881X_OTP_REG_11, 0xFF}, + {WSA881X_OTP_REG_12, 0xFF}, + {WSA881X_OTP_REG_13, 0xFF}, + {WSA881X_OTP_REG_14, 0xFF}, + {WSA881X_OTP_REG_15, 0xFF}, + {WSA881X_OTP_REG_16, 0xFF}, + {WSA881X_OTP_REG_17, 0xFF}, + {WSA881X_OTP_REG_18, 0xFF}, + {WSA881X_OTP_REG_19, 0xFF}, + {WSA881X_OTP_REG_20, 0xFF}, + {WSA881X_OTP_REG_21, 0xFF}, + {WSA881X_OTP_REG_22, 0xFF}, + {WSA881X_OTP_REG_23, 0xFF}, + {WSA881X_OTP_REG_24, 0x03}, + {WSA881X_OTP_REG_25, 0x01}, + {WSA881X_OTP_REG_26, 0x03}, + {WSA881X_OTP_REG_27, 0x11}, + {WSA881X_OTP_REG_28, 0xFF}, + {WSA881X_OTP_REG_29, 0xFF}, + {WSA881X_OTP_REG_30, 0xFF}, + {WSA881X_OTP_REG_31, 0xFF}, + {WSA881X_OTP_REG_63, 0x40}, +}; + +struct reg_default wsa881x_ana_reg_defaults_1[] = { + {WSA881X_BIAS_REF_CTRL - WSA881X_ANALOG_BASE, 0x6C}, + {WSA881X_BIAS_TEST - WSA881X_ANALOG_BASE, 0x16}, + {WSA881X_BIAS_BIAS - WSA881X_ANALOG_BASE, 0xF0}, + {WSA881X_TEMP_OP - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_TEMP_IREF_CTRL - WSA881X_ANALOG_BASE, 0x56}, + {WSA881X_TEMP_ISENS_CTRL - WSA881X_ANALOG_BASE, 0x47}, + {WSA881X_TEMP_CLK_CTRL - WSA881X_ANALOG_BASE, 0x87}, + {WSA881X_TEMP_TEST - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_TEMP_BIAS - WSA881X_ANALOG_BASE, 0x51}, + {WSA881X_TEMP_ADC_CTRL - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_TEMP_DOUT_MSB - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_TEMP_DOUT_LSB - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_ADC_EN_MODU_V - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_ADC_EN_MODU_I - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_ADC_EN_DET_TEST_V - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_ADC_EN_DET_TEST_I - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_ADC_SEL_IBIAS - WSA881X_ANALOG_BASE, 0x25}, + {WSA881X_ADC_EN_SEL_IBIAS - WSA881X_ANALOG_BASE, 0x10}, + {WSA881X_SPKR_DRV_EN - WSA881X_ANALOG_BASE, 0x74}, + {WSA881X_SPKR_DRV_GAIN - WSA881X_ANALOG_BASE, 0x01}, + {WSA881X_SPKR_DAC_CTL - WSA881X_ANALOG_BASE, 0x40}, + {WSA881X_SPKR_DRV_DBG - WSA881X_ANALOG_BASE, 0x15}, + {WSA881X_SPKR_PWRSTG_DBG - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_SPKR_OCP_CTL - WSA881X_ANALOG_BASE, 0xD4}, + {WSA881X_SPKR_CLIP_CTL - WSA881X_ANALOG_BASE, 0x90}, + {WSA881X_SPKR_BBM_CTL - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_SPKR_MISC_CTL1 - WSA881X_ANALOG_BASE, 0x80}, + {WSA881X_SPKR_MISC_CTL2 - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_SPKR_BIAS_INT - WSA881X_ANALOG_BASE, 0x56}, + {WSA881X_SPKR_PA_INT - WSA881X_ANALOG_BASE, 0x54}, + {WSA881X_SPKR_BIAS_CAL - WSA881X_ANALOG_BASE, 0xAC}, + {WSA881X_SPKR_BIAS_PSRR - WSA881X_ANALOG_BASE, 0x54}, + {WSA881X_SPKR_STATUS1 - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_SPKR_STATUS2 - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_BOOST_EN_CTL - WSA881X_ANALOG_BASE, 0x18}, + {WSA881X_BOOST_CURRENT_LIMIT - WSA881X_ANALOG_BASE, 0x7A}, + {WSA881X_BOOST_PS_CTL - WSA881X_ANALOG_BASE, 0xC0}, + {WSA881X_BOOST_PRESET_OUT1 - WSA881X_ANALOG_BASE, 0x77}, + {WSA881X_BOOST_PRESET_OUT2 - WSA881X_ANALOG_BASE, 0x70}, + {WSA881X_BOOST_FORCE_OUT - WSA881X_ANALOG_BASE, 0x0E}, + {WSA881X_BOOST_LDO_PROG - WSA881X_ANALOG_BASE, 0x16}, + {WSA881X_BOOST_SLOPE_COMP_ISENSE_FB - WSA881X_ANALOG_BASE, 0x71}, + {WSA881X_BOOST_RON_CTL - WSA881X_ANALOG_BASE, 0x0F}, + {WSA881X_BOOST_LOOP_STABILITY - WSA881X_ANALOG_BASE, 0xAD}, + {WSA881X_BOOST_ZX_CTL - WSA881X_ANALOG_BASE, 0x34}, + {WSA881X_BOOST_START_CTL - WSA881X_ANALOG_BASE, 0x23}, + {WSA881X_BOOST_MISC1_CTL - WSA881X_ANALOG_BASE, 0x80}, + {WSA881X_BOOST_MISC2_CTL - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_BOOST_MISC3_CTL - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_BOOST_ATEST_CTL - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_SPKR_PROT_FE_GAIN - WSA881X_ANALOG_BASE, 0x46}, + {WSA881X_SPKR_PROT_FE_CM_LDO_SET - WSA881X_ANALOG_BASE, 0x3B}, + {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1 - WSA881X_ANALOG_BASE, 0x8D}, + {WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2 - WSA881X_ANALOG_BASE, 0x8D}, + {WSA881X_SPKR_PROT_ATEST1 - WSA881X_ANALOG_BASE, 0x01}, + {WSA881X_SPKR_PROT_ATEST2 - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_SPKR_PROT_FE_VSENSE_VCM - WSA881X_ANALOG_BASE, 0x8D}, + {WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1 - WSA881X_ANALOG_BASE, 0x4D}, + {WSA881X_BONGO_RESRV_REG1 - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_BONGO_RESRV_REG2 - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_SPKR_PROT_SAR - WSA881X_ANALOG_BASE, 0x00}, + {WSA881X_SPKR_STATUS3 - WSA881X_ANALOG_BASE, 0x00}, +}; + +static const struct reg_sequence wsa881x_rev_2_0_dig[] = { + {WSA881X_RESET_CTL, 0x00}, + {WSA881X_TADC_VALUE_CTL, 0x01}, + {WSA881X_INTR_MASK, 0x1B}, + {WSA881X_IOPAD_CTL, 0x00}, + {WSA881X_OTP_REG_28, 0x3F}, + {WSA881X_OTP_REG_29, 0x3F}, + {WSA881X_OTP_REG_30, 0x01}, + {WSA881X_OTP_REG_31, 0x01}, +}; + +static const struct reg_sequence wsa881x_rev_2_0_ana[] = { + {WSA881X_TEMP_ADC_CTRL, 0x03}, + {WSA881X_ADC_SEL_IBIAS, 0x45}, + {WSA881X_SPKR_DRV_GAIN, 0xC1}, + {WSA881X_SPKR_DAC_CTL, 0x42}, + {WSA881X_SPKR_BBM_CTL, 0x02}, + {WSA881X_SPKR_MISC_CTL1, 0x40}, + {WSA881X_SPKR_MISC_CTL2, 0x07}, + {WSA881X_SPKR_BIAS_INT, 0x5F}, + {WSA881X_SPKR_BIAS_PSRR, 0x44}, + {WSA881X_BOOST_PS_CTL, 0xA0}, + {WSA881X_BOOST_PRESET_OUT1, 0xB7}, + {WSA881X_BOOST_LOOP_STABILITY, 0x8D}, + {WSA881X_SPKR_PROT_ATEST2, 0x02}, + {WSA881X_BONGO_RESRV_REG1, 0x5E}, + {WSA881X_BONGO_RESRV_REG2, 0x07}, +}; + +struct reg_default wsa881x_rev_2_0_regmap_ana[] = { + {WSA881X_TEMP_ADC_CTRL - WSA881X_ANALOG_BASE, 0x03}, + {WSA881X_ADC_SEL_IBIAS - WSA881X_ANALOG_BASE, 0x45}, + {WSA881X_SPKR_DRV_GAIN - WSA881X_ANALOG_BASE, 0xC1}, + {WSA881X_SPKR_DAC_CTL - WSA881X_ANALOG_BASE, 0x42}, + {WSA881X_SPKR_BBM_CTL - WSA881X_ANALOG_BASE, 0x02}, + {WSA881X_SPKR_MISC_CTL1 - WSA881X_ANALOG_BASE, 0x40}, + {WSA881X_SPKR_MISC_CTL2 - WSA881X_ANALOG_BASE, 0x07}, + {WSA881X_SPKR_BIAS_INT - WSA881X_ANALOG_BASE, 0x5F}, + {WSA881X_SPKR_BIAS_PSRR - WSA881X_ANALOG_BASE, 0x44}, + {WSA881X_BOOST_PS_CTL - WSA881X_ANALOG_BASE, 0xA0}, + {WSA881X_BOOST_PRESET_OUT1 - WSA881X_ANALOG_BASE, 0xB7}, + {WSA881X_BOOST_LOOP_STABILITY - WSA881X_ANALOG_BASE, 0x8D}, + {WSA881X_SPKR_PROT_ATEST2 - WSA881X_ANALOG_BASE, 0x02}, + {WSA881X_BONGO_RESRV_REG1 - WSA881X_ANALOG_BASE, 0x5E}, + {WSA881X_BONGO_RESRV_REG2 - WSA881X_ANALOG_BASE, 0x07}, +}; + +/** + * wsa881x_update_reg_defaults_2_0 - update default values of regs for v2.0 + * + * wsa881x v2.0 has different default values for certain analog and digital + * registers compared to v1.x. Therefore, update the values of these registers + * with the values from tables defined above for v2.0. + */ +void wsa881x_update_reg_defaults_2_0(void) +{ + int i, j; + + for (i = 0; i < ARRAY_SIZE(wsa881x_rev_2_0_dig); i++) { + for (j = 0; j < ARRAY_SIZE(wsa881x_ana_reg_defaults); j++) + if (wsa881x_ana_reg_defaults[j].reg == + wsa881x_rev_2_0_dig[i].reg) + wsa881x_ana_reg_defaults[j].def = + wsa881x_rev_2_0_dig[i].def; + } + for (i = 0; i < ARRAY_SIZE(wsa881x_rev_2_0_ana); i++) { + for (j = 0; j < ARRAY_SIZE(wsa881x_ana_reg_defaults); j++) + if (wsa881x_ana_reg_defaults[j].reg == + wsa881x_rev_2_0_ana[i].reg) + wsa881x_ana_reg_defaults[j].def = + wsa881x_rev_2_0_ana[i].def; + } +} +EXPORT_SYMBOL(wsa881x_update_reg_defaults_2_0); + +/** + * wsa881x_update_regmap_2_0 - update regmap framework with new tables + * @regmap: pointer to wsa881x regmap structure + * @flag: indicates digital or analog wsa881x slave + * + * wsa881x v2.0 has some new registers for both analog and digital slaves. + * Update the regmap framework with all the new registers. + */ +void wsa881x_update_regmap_2_0(struct regmap *regmap, int flag) +{ + u16 ret = 0; + + switch (flag) { + case WSA881X_DIGITAL_SLAVE: + ret = regmap_register_patch(regmap, wsa881x_rev_2_0_dig, + ARRAY_SIZE(wsa881x_rev_2_0_dig)); + break; + case WSA881X_ANALOG_SLAVE: + ret = regmap_register_patch(regmap, wsa881x_rev_2_0_ana, + ARRAY_SIZE(wsa881x_rev_2_0_ana)); + break; + default: + pr_debug("%s: unknown version", __func__); + ret = -EINVAL; + break; + } + if (ret) + pr_err("%s: Failed to update regmap defaults ret= %d\n", + __func__, ret); +} +EXPORT_SYMBOL(wsa881x_update_regmap_2_0); + +static bool wsa881x_readable_register(struct device *dev, unsigned int reg) +{ + return wsa881x_ana_reg_readable[reg]; +} + +static bool wsa881x_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WSA881X_CHIP_ID0: + case WSA881X_CHIP_ID1: + case WSA881X_CHIP_ID2: + case WSA881X_CHIP_ID3: + case WSA881X_BUS_ID: + case WSA881X_TEMP_MSB: + case WSA881X_TEMP_LSB: + case WSA881X_SDM_PDM9_LSB: + case WSA881X_SDM_PDM9_MSB: + case WSA881X_OTP_REG_0: + case WSA881X_OTP_REG_1: + case WSA881X_OTP_REG_2: + case WSA881X_OTP_REG_3: + case WSA881X_OTP_REG_4: + case WSA881X_OTP_REG_5: + case WSA881X_OTP_REG_31: + case WSA881X_TEMP_DOUT_MSB: + case WSA881X_TEMP_DOUT_LSB: + case WSA881X_TEMP_OP: + case WSA881X_OTP_CTRL1: + case WSA881X_INTR_STATUS: + case WSA881X_ATE_TEST_MODE: + case WSA881X_PIN_STATUS: + case WSA881X_SWR_HM_TEST2: + case WSA881X_SPKR_STATUS1: + case WSA881X_SPKR_STATUS2: + case WSA881X_SPKR_STATUS3: + case WSA881X_SPKR_PROT_SAR: + return true; + default: + return false; + } +} + +struct regmap_config wsa881x_ana_regmap_config[] = { +{ + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_NONE, + .reg_defaults = wsa881x_ana_reg_defaults_0, + .num_reg_defaults = ARRAY_SIZE(wsa881x_ana_reg_defaults_0), + .max_register = WSA881X_MAX_REGISTER, + .volatile_reg = wsa881x_volatile_register, + .readable_reg = wsa881x_readable_register, + .reg_format_endian = REGMAP_ENDIAN_NATIVE, + .val_format_endian = REGMAP_ENDIAN_NATIVE, +}, +{ + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_NONE, + .reg_defaults = wsa881x_ana_reg_defaults_1, + .num_reg_defaults = ARRAY_SIZE(wsa881x_ana_reg_defaults_1), + .max_register = WSA881X_MAX_REGISTER, + .volatile_reg = wsa881x_volatile_register, + .readable_reg = wsa881x_readable_register, + .reg_format_endian = REGMAP_ENDIAN_NATIVE, + .val_format_endian = REGMAP_ENDIAN_NATIVE, +} +}; diff --git a/asoc/codecs/wsa881x-tables-analog.c b/asoc/codecs/wsa881x-tables-analog.c new file mode 100644 index 000000000000..bbc6b9051e05 --- /dev/null +++ b/asoc/codecs/wsa881x-tables-analog.c @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015, 2018-2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include "wsa881x-registers-analog.h" + +const u8 wsa881x_ana_reg_readable[WSA881X_CACHE_SIZE] = { + [WSA881X_CHIP_ID0] = 1, + [WSA881X_CHIP_ID1] = 1, + [WSA881X_CHIP_ID2] = 1, + [WSA881X_CHIP_ID3] = 1, + [WSA881X_BUS_ID] = 1, + [WSA881X_CDC_RST_CTL] = 1, + [WSA881X_CDC_TOP_CLK_CTL] = 1, + [WSA881X_CDC_ANA_CLK_CTL] = 1, + [WSA881X_CDC_DIG_CLK_CTL] = 1, + [WSA881X_CLOCK_CONFIG] = 1, + [WSA881X_ANA_CTL] = 1, + [WSA881X_SWR_RESET_EN] = 1, + [WSA881X_RESET_CTL] = 1, + [WSA881X_TADC_VALUE_CTL] = 1, + [WSA881X_TEMP_DETECT_CTL] = 1, + [WSA881X_TEMP_MSB] = 1, + [WSA881X_TEMP_LSB] = 1, + [WSA881X_TEMP_CONFIG0] = 1, + [WSA881X_TEMP_CONFIG1] = 1, + [WSA881X_CDC_CLIP_CTL] = 1, + [WSA881X_SDM_PDM9_LSB] = 1, + [WSA881X_SDM_PDM9_MSB] = 1, + [WSA881X_CDC_RX_CTL] = 1, + [WSA881X_DEM_BYPASS_DATA0] = 1, + [WSA881X_DEM_BYPASS_DATA1] = 1, + [WSA881X_DEM_BYPASS_DATA2] = 1, + [WSA881X_DEM_BYPASS_DATA3] = 1, + [WSA881X_OTP_CTRL0] = 1, + [WSA881X_OTP_CTRL1] = 1, + [WSA881X_HDRIVE_CTL_GROUP1] = 1, + [WSA881X_INTR_MODE] = 1, + [WSA881X_INTR_MASK] = 1, + [WSA881X_INTR_STATUS] = 1, + [WSA881X_INTR_CLEAR] = 1, + [WSA881X_INTR_LEVEL] = 1, + [WSA881X_INTR_SET] = 1, + [WSA881X_INTR_TEST] = 1, + [WSA881X_PDM_TEST_MODE] = 1, + [WSA881X_ATE_TEST_MODE] = 1, + [WSA881X_PIN_CTL_MODE] = 1, + [WSA881X_PIN_CTL_OE] = 1, + [WSA881X_PIN_WDATA_IOPAD] = 1, + [WSA881X_PIN_STATUS] = 1, + [WSA881X_DIG_DEBUG_MODE] = 1, + [WSA881X_DIG_DEBUG_SEL] = 1, + [WSA881X_DIG_DEBUG_EN] = 1, + [WSA881X_SWR_HM_TEST1] = 1, + [WSA881X_SWR_HM_TEST2] = 1, + [WSA881X_TEMP_DETECT_DBG_CTL] = 1, + [WSA881X_TEMP_DEBUG_MSB] = 1, + [WSA881X_TEMP_DEBUG_LSB] = 1, + [WSA881X_SAMPLE_EDGE_SEL] = 1, + [WSA881X_IOPAD_CTL] = 1, + [WSA881X_SPARE_0] = 1, + [WSA881X_SPARE_1] = 1, + [WSA881X_SPARE_2] = 1, + [WSA881X_OTP_REG_0] = 1, + [WSA881X_OTP_REG_1] = 1, + [WSA881X_OTP_REG_2] = 1, + [WSA881X_OTP_REG_3] = 1, + [WSA881X_OTP_REG_4] = 1, + [WSA881X_OTP_REG_5] = 1, + [WSA881X_OTP_REG_6] = 1, + [WSA881X_OTP_REG_7] = 1, + [WSA881X_OTP_REG_8] = 1, + [WSA881X_OTP_REG_9] = 1, + [WSA881X_OTP_REG_10] = 1, + [WSA881X_OTP_REG_11] = 1, + [WSA881X_OTP_REG_12] = 1, + [WSA881X_OTP_REG_13] = 1, + [WSA881X_OTP_REG_14] = 1, + [WSA881X_OTP_REG_15] = 1, + [WSA881X_OTP_REG_16] = 1, + [WSA881X_OTP_REG_17] = 1, + [WSA881X_OTP_REG_18] = 1, + [WSA881X_OTP_REG_19] = 1, + [WSA881X_OTP_REG_20] = 1, + [WSA881X_OTP_REG_21] = 1, + [WSA881X_OTP_REG_22] = 1, + [WSA881X_OTP_REG_23] = 1, + [WSA881X_OTP_REG_24] = 1, + [WSA881X_OTP_REG_25] = 1, + [WSA881X_OTP_REG_26] = 1, + [WSA881X_OTP_REG_27] = 1, + [WSA881X_OTP_REG_28] = 1, + [WSA881X_OTP_REG_29] = 1, + [WSA881X_OTP_REG_30] = 1, + [WSA881X_OTP_REG_31] = 1, + [WSA881X_OTP_REG_63] = 1, + /* Analog Registers */ + [WSA881X_BIAS_REF_CTRL] = 1, + [WSA881X_BIAS_TEST] = 1, + [WSA881X_BIAS_BIAS] = 1, + [WSA881X_TEMP_OP] = 1, + [WSA881X_TEMP_IREF_CTRL] = 1, + [WSA881X_TEMP_ISENS_CTRL] = 1, + [WSA881X_TEMP_CLK_CTRL] = 1, + [WSA881X_TEMP_TEST] = 1, + [WSA881X_TEMP_BIAS] = 1, + [WSA881X_TEMP_ADC_CTRL] = 1, + [WSA881X_TEMP_DOUT_MSB] = 1, + [WSA881X_TEMP_DOUT_LSB] = 1, + [WSA881X_ADC_EN_MODU_V] = 1, + [WSA881X_ADC_EN_MODU_I] = 1, + [WSA881X_ADC_EN_DET_TEST_V] = 1, + [WSA881X_ADC_EN_DET_TEST_I] = 1, + [WSA881X_ADC_SEL_IBIAS] = 1, + [WSA881X_ADC_EN_SEL_IBIAS] = 1, + [WSA881X_SPKR_DRV_EN] = 1, + [WSA881X_SPKR_DRV_GAIN] = 1, + [WSA881X_SPKR_DAC_CTL] = 1, + [WSA881X_SPKR_DRV_DBG] = 1, + [WSA881X_SPKR_PWRSTG_DBG] = 1, + [WSA881X_SPKR_OCP_CTL] = 1, + [WSA881X_SPKR_CLIP_CTL] = 1, + [WSA881X_SPKR_BBM_CTL] = 1, + [WSA881X_SPKR_MISC_CTL1] = 1, + [WSA881X_SPKR_MISC_CTL2] = 1, + [WSA881X_SPKR_BIAS_INT] = 1, + [WSA881X_SPKR_PA_INT] = 1, + [WSA881X_SPKR_BIAS_CAL] = 1, + [WSA881X_SPKR_BIAS_PSRR] = 1, + [WSA881X_SPKR_STATUS1] = 1, + [WSA881X_SPKR_STATUS2] = 1, + [WSA881X_BOOST_EN_CTL] = 1, + [WSA881X_BOOST_CURRENT_LIMIT] = 1, + [WSA881X_BOOST_PS_CTL] = 1, + [WSA881X_BOOST_PRESET_OUT1] = 1, + [WSA881X_BOOST_PRESET_OUT2] = 1, + [WSA881X_BOOST_FORCE_OUT] = 1, + [WSA881X_BOOST_LDO_PROG] = 1, + [WSA881X_BOOST_SLOPE_COMP_ISENSE_FB] = 1, + [WSA881X_BOOST_RON_CTL] = 1, + [WSA881X_BOOST_LOOP_STABILITY] = 1, + [WSA881X_BOOST_ZX_CTL] = 1, + [WSA881X_BOOST_START_CTL] = 1, + [WSA881X_BOOST_MISC1_CTL] = 1, + [WSA881X_BOOST_MISC2_CTL] = 1, + [WSA881X_BOOST_MISC3_CTL] = 1, + [WSA881X_BOOST_ATEST_CTL] = 1, + [WSA881X_SPKR_PROT_FE_GAIN] = 1, + [WSA881X_SPKR_PROT_FE_CM_LDO_SET] = 1, + [WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1] = 1, + [WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2] = 1, + [WSA881X_SPKR_PROT_ATEST1] = 1, + [WSA881X_SPKR_PROT_ATEST2] = 1, + [WSA881X_SPKR_PROT_FE_VSENSE_VCM] = 1, + [WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1] = 1, + [WSA881X_BONGO_RESRV_REG1] = 1, + [WSA881X_BONGO_RESRV_REG2] = 1, + [WSA881X_SPKR_PROT_SAR] = 1, + [WSA881X_SPKR_STATUS3] = 1, +}; -- GitLab From c7bfab97063f3ebdf5ffa2bdd594edb872ad42e0 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 27 Aug 2019 16:19:14 +0530 Subject: [PATCH 1239/1645] soc: soundwire: Update hctl gate setting for SWR version 1.6 In soundwire version 1.6, hw_ctl gating is required to address HW limitation as SW workaround to get SWR functionality working. Change-Id: Ia0939b1271f5400319217433de658a55a05ca404 Signed-off-by: Laxminath Kasam --- soc/swr-mstr-ctrl.c | 18 ++++++++++++++++-- soc/swr-mstr-ctrl.h | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 44d245d6dfb2..599644f966c3 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2022,6 +2022,7 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) u8 retry_cmd_num = 3; u32 reg[SWRM_MAX_INIT_REG]; u32 value[SWRM_MAX_INIT_REG]; + u32 temp = 0; int len = 0; /* Clear Rows and Cols */ @@ -2075,11 +2076,20 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) * For SWR master version 1.5.1, continue * execute on command ignore. */ - if (swrm->version == SWRM_VERSION_1_5_1) + /* Execute it for versions >= 1.5.1 */ + if (swrm->version >= SWRM_VERSION_1_5_1) swr_master_write(swrm, SWRM_CMD_FIFO_CFG_ADDR, (swr_master_read(swrm, SWRM_CMD_FIFO_CFG_ADDR) | 0x80000000)); + /* SW workaround to gate hw_ctl for SWR version >=1.6 */ + if (swrm->version >= SWRM_VERSION_1_6) { + if (swrm->swrm_hctl_reg) { + temp = ioread32(swrm->swrm_hctl_reg); + temp &= 0xFFFFFFFD; + iowrite32(temp, swrm->swrm_hctl_reg); + } + } return ret; } @@ -2129,7 +2139,7 @@ static int swrm_probe(struct platform_device *pdev) { struct swr_mstr_ctrl *swrm; struct swr_ctrl_platform_data *pdata; - u32 i, num_ports, port_num, port_type, ch_mask; + u32 i, num_ports, port_num, port_type, ch_mask, swrm_hctl_reg = 0; u32 *temp, map_size, map_length, ch_iter = 0, old_port_num = 0; int ret = 0; struct clk *lpass_core_hw_vote = NULL; @@ -2198,6 +2208,10 @@ static int swrm_probe(struct platform_device *pdev) } swrm->core_vote = pdata->core_vote; + if (!(of_property_read_u32(pdev->dev.of_node, + "qcom,swrm-hctl-reg", &swrm_hctl_reg))) + swrm->swrm_hctl_reg = devm_ioremap(&pdev->dev, + swrm_hctl_reg, 0x4); swrm->clk = pdata->clk; if (!swrm->clk) { dev_err(&pdev->dev, "%s: swrm->clk is NULL\n", diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 321e84f3007d..43bf227601b6 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -38,6 +38,7 @@ #define SWRM_VERSION_1_3 0x01040000 #define SWRM_VERSION_1_5 0x01050000 #define SWRM_VERSION_1_5_1 0x01050001 +#define SWRM_VERSION_1_6 0x01060000 #define SWR_MAX_CH_PER_PORT 8 @@ -125,6 +126,7 @@ struct swr_mstr_ctrl { struct mutex pm_lock; u32 swrm_base_reg; char __iomem *swrm_dig_base; + char __iomem *swrm_hctl_reg; u8 rcmd_id; u8 wcmd_id; u32 master_id; -- GitLab From 56c0d0927d3d9962d3159751dbed3ce1c6c3ac36 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Wed, 9 Oct 2019 21:57:42 -0700 Subject: [PATCH 1240/1645] dsp: lsm: don't print physical address of invalid lsm client pointer Function q6lsm_get_session_id_from_lsm_client will print out the physical address of a lsm client pointer in error message when it fails to find the matching lsm client. This is not needed because the address information is redundant and might cause potential issue when a lsm client is already invalid. Change-Id: If8c38b566c839c4b45d98e79802d0fd6efb5bdb9 Signed-off-by: Xiaoyu Ye --- dsp/q6lsm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 9c5bf3d30dee..bb52d6761960 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -104,8 +104,7 @@ static int q6lsm_get_session_id_from_lsm_client(struct lsm_client *client) if (lsm_session[n] == client) return n; } - pr_err("%s: cannot find matching lsm client. client = %pa\n", - __func__, client); + pr_err("%s: cannot find matching lsm client.\n", __func__); return LSM_INVALID_SESSION_ID; } -- GitLab From d577af909c4d073030d1ba2f86cebcbf9546fc8d Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 3 Oct 2019 21:09:19 +0530 Subject: [PATCH 1241/1645] asoc: codecs: Check for core votes count before accessing registers Check for core votes count before accessing swrm registers to avoid NOC errors. Change-Id: I5689d6a6db0886ed4cc791738a28290f3d953412 Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/bolero-cdc.c | 15 +++++++++++++++ asoc/codecs/bolero/bolero-cdc.h | 6 ++++++ asoc/codecs/bolero/rx-macro.c | 5 ++++- asoc/codecs/bolero/tx-macro.c | 6 ++++-- asoc/codecs/bolero/wsa-macro.c | 6 ++++-- 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 76c9d4064276..4fe18e221229 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -1180,6 +1180,21 @@ int bolero_runtime_suspend(struct device *dev) } EXPORT_SYMBOL(bolero_runtime_suspend); +bool bolero_check_core_votes(struct device *dev) +{ + struct bolero_priv *priv = dev_get_drvdata(dev->parent); + bool ret = true; + + mutex_lock(&priv->vote_lock); + if ((priv->lpass_core_hw_vote && !priv->core_hw_vote_count) || + (priv->lpass_audio_hw_vote && !priv->core_audio_vote_count)) + ret = false; + mutex_unlock(&priv->vote_lock); + + return ret; +} +EXPORT_SYMBOL(bolero_check_core_votes); + static const struct of_device_id bolero_dt_match[] = { {.compatible = "qcom,bolero-codec"}, {} diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 957389cea2d0..f104f88a34bb 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -84,6 +84,7 @@ int bolero_tx_clk_switch(struct snd_soc_component *component); int bolero_register_event_listener(struct snd_soc_component *component, bool enable); void bolero_wsa_pa_on(struct device *dev); +bool bolero_check_core_votes(struct device *dev); #else static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb) { @@ -158,5 +159,10 @@ static inline int bolero_register_event_listener( static void bolero_wsa_pa_on(struct device *dev) { } + +static inline bool bolero_check_core_votes(struct device *dev) +{ + return false; +} #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 9af15226efc3..e6ee4df40c33 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -3499,7 +3499,10 @@ static int rx_macro_core_vote(void *handle, bool enable) pm_runtime_mark_last_busy(rx_priv->dev); } - return 0; + if (bolero_check_core_votes(rx_priv->dev)) + return 0; + else + return -EINVAL; } static int rx_swrm_clock(void *handle, bool enable) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 45e0a80a309a..d5ec25c0ec50 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1952,7 +1952,6 @@ static int tx_macro_clk_switch(struct snd_soc_component *component) static int tx_macro_core_vote(void *handle, bool enable) { struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle; - int ret = 0; if (tx_priv == NULL) { pr_err("%s: tx priv data is NULL\n", __func__); @@ -1964,7 +1963,10 @@ static int tx_macro_core_vote(void *handle, bool enable) pm_runtime_mark_last_busy(tx_priv->dev); } - return ret; + if (bolero_check_core_votes(tx_priv->dev)) + return 0; + else + return -EINVAL; } static int tx_macro_swrm_clock(void *handle, bool enable) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index dfca96894e0b..c046bd5b368f 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -2802,7 +2802,6 @@ static void wsa_macro_init_reg(struct snd_soc_component *component) static int wsa_macro_core_vote(void *handle, bool enable) { struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle; - int ret = 0; if (wsa_priv == NULL) { pr_err("%s: wsa priv data is NULL\n", __func__); @@ -2814,7 +2813,10 @@ static int wsa_macro_core_vote(void *handle, bool enable) pm_runtime_mark_last_busy(wsa_priv->dev); } - return ret; + if (bolero_check_core_votes(wsa_priv->dev)) + return 0; + else + return -EINVAL; } static int wsa_swrm_clock(void *handle, bool enable) -- GitLab From af0a66b78a587c5968dcb7630c28538d91653400 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Mon, 9 Sep 2019 09:52:21 +0530 Subject: [PATCH 1242/1645] ASoC: wsa883x: Add support for wsa883x speaker amplifer WSA883x is a speaker amplifier with soundwire interface and enumerates as soundwire slave. WSA883x supports audio playback on speakers and has temperature sensors for better speaker protection and enhanced boost control support. Add software driver support to enable WSA883x speaker amplifier. Change-Id: Ib9cf2eebdda5ce331154bc786f059c5757f34fa2 Signed-off-by: Sudheer Papothi --- asoc/codecs/wsa883x/Android.mk | 49 + asoc/codecs/wsa883x/Kbuild | 103 ++ asoc/codecs/wsa883x/internal.h | 113 ++ asoc/codecs/wsa883x/wsa883x-registers.h | 376 +++++++ asoc/codecs/wsa883x/wsa883x-regmap.c | 393 +++++++ asoc/codecs/wsa883x/wsa883x-tables.c | 350 ++++++ asoc/codecs/wsa883x/wsa883x-temp-sensor.c | 187 ++++ asoc/codecs/wsa883x/wsa883x-temp-sensor.h | 35 + asoc/codecs/wsa883x/wsa883x.c | 1176 +++++++++++++++++++++ asoc/codecs/wsa883x/wsa883x.h | 41 + 10 files changed, 2823 insertions(+) create mode 100644 asoc/codecs/wsa883x/Android.mk create mode 100644 asoc/codecs/wsa883x/Kbuild create mode 100644 asoc/codecs/wsa883x/internal.h create mode 100644 asoc/codecs/wsa883x/wsa883x-registers.h create mode 100644 asoc/codecs/wsa883x/wsa883x-regmap.c create mode 100644 asoc/codecs/wsa883x/wsa883x-tables.c create mode 100644 asoc/codecs/wsa883x/wsa883x-temp-sensor.c create mode 100644 asoc/codecs/wsa883x/wsa883x-temp-sensor.h create mode 100644 asoc/codecs/wsa883x/wsa883x.c create mode 100644 asoc/codecs/wsa883x/wsa883x.h diff --git a/asoc/codecs/wsa883x/Android.mk b/asoc/codecs/wsa883x/Android.mk new file mode 100644 index 000000000000..66056e8c442b --- /dev/null +++ b/asoc/codecs/wsa883x/Android.mk @@ -0,0 +1,49 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,lahaina),true) +AUDIO_SELECT := CONFIG_SND_SOC_LAHAINA=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,lahaina),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=wsa883x_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_wsa883x.ko +LOCAL_MODULE_KBUILD_NAME := wsa883x_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/asoc/codecs/wsa883x/Kbuild b/asoc/codecs/wsa883x/Kbuild new file mode 100644 index 000000000000..4eb844af518b --- /dev/null +++ b/asoc/codecs/wsa883x/Kbuild @@ -0,0 +1,103 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + +ifeq ($(KERNEL_BUILD), 1) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.19 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) + ifeq ($(CONFIG_ARCH_LAHAINA), y) + include $(AUDIO_ROOT)/config/lahainaauto.conf + INCS += -include $(AUDIO_ROOT)/config/lahainaautoconf.h + endif +endif + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ WSA883X ############ + +# for WSA883X Codec +ifdef CONFIG_SND_SOC_WSA883X + WSA883X_OBJS += wsa883x.o + WSA883X_OBJS += wsa883x-regmap.o + WSA883X_OBJS += wsa883x-tables.o + WSA883X_OBJS += wsa883x-temp-sensor.o +endif + +LINUX_INC += -Iinclude/linux + +INCS += $(COMMON_INC) \ + $(UAPI_INC) + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +ifeq ($(KERNEL_BUILD), 0) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_WSA883X) += wsa883x_dlkm.o +wsa883x_dlkm-y := $(WSA883X_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/wsa883x/internal.h b/asoc/codecs/wsa883x/internal.h new file mode 100644 index 000000000000..3f99f780659c --- /dev/null +++ b/asoc/codecs/wsa883x/internal.h @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#ifndef WSA883X_INTERNAL_H +#define WSA883X_INTERNAL_H + +#include "wsa883x.h" +#include "wsa883x-registers.h" + +#ifdef CONFIG_DEBUG_FS +#include +#include + +#define SWR_SLV_MAX_REG_ADDR 0x2009 +#define SWR_SLV_START_REG_ADDR 0x40 +#define SWR_SLV_MAX_BUF_LEN 20 +#define BYTES_PER_LINE 12 +#define SWR_SLV_RD_BUF_LEN 8 +#define SWR_SLV_WR_BUF_LEN 32 +#define SWR_SLV_MAX_DEVICES 2 +#endif /* CONFIG_DEBUG_FS */ + +#define WSA883X_DRV_NAME "wsa883x-codec" +#define WSA883X_NUM_RETRY 5 + +#define WSA883X_VERSION_ENTRY_SIZE 27 + +enum { + G_18DB = 0, + G_16P5DB, + G_15DB, + G_13P5DB, + G_12DB, + G_10P5DB, + G_9DB, + G_7P5DB, + G_6DB, + G_4P5DB, + G_3DB, + G_1P5DB, + G_0DB, +}; + +enum { + DISABLE = 0, + ENABLE, +}; + +enum { + SWR_DAC_PORT, + SWR_COMP_PORT, + SWR_BOOST_PORT, + SWR_VISENSE_PORT, +}; + +struct swr_port { + u8 port_id; + u8 ch_mask; + u32 ch_rate; + u8 num_ch; + u8 port_type; +}; + +enum { + WSA883X_DEV_DOWN, + WSA883X_DEV_UP, + WSA883X_DEV_READY, +}; + +extern struct regmap_config wsa883x_regmap_config; + +/* + * Private data Structure for wsa883x. All parameters related to + * WSA883X codec needs to be defined here. + */ +struct wsa883x_priv { + struct regmap *regmap; + struct device *dev; + struct swr_device *swr_slave; + struct snd_soc_component *component; + bool comp_enable; + bool boost_enable; + bool visense_enable; + u8 pa_gain; + struct swr_port port[WSA883X_MAX_SWR_PORTS]; + int pd_gpio; + struct wsa883x_tz_priv tz_pdata; + int bg_cnt; + int clk_cnt; + int version; + struct mutex bg_lock; + struct mutex res_lock; + struct mutex temp_lock; + struct snd_info_entry *entry; + struct snd_info_entry *version_entry; + int state; + struct delayed_work ocp_ctl_work; + struct device_node *wsa_rst_np; + int pa_mute; +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_dent; + struct dentry *debugfs_peek; + struct dentry *debugfs_poke; + struct dentry *debugfs_reg_dump; + unsigned int read_data; +#endif +}; + +static int32_t wsa883x_resource_acquire(struct snd_soc_component *component, + bool enable); +#endif /* WSA883X_INTERNAL_H */ diff --git a/asoc/codecs/wsa883x/wsa883x-registers.h b/asoc/codecs/wsa883x/wsa883x-registers.h new file mode 100644 index 000000000000..7e518d2fd04b --- /dev/null +++ b/asoc/codecs/wsa883x/wsa883x-registers.h @@ -0,0 +1,376 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved. + */ + +#ifndef WSA883X_REGISTERS_H +#define WSA883X_REGISTERS_H + +#define WSA883X_BASE 0x3000 +#define WSA883X_REG(reg) (reg - WSA883X_BASE) + +enum { + REG_NO_ACCESS, + RD_REG, + WR_REG, + RD_WR_REG, +}; + +#define WSA883X_ANA_BG_TSADC_BASE (WSA883X_BASE+0x00000000) +#define WSA883X_REF_CTRL (WSA883X_ANA_BG_TSADC_BASE+0x0000) +#define WSA883X_TEST_CTL_0 (WSA883X_ANA_BG_TSADC_BASE+0x0001) +#define WSA883X_BIAS_0 (WSA883X_ANA_BG_TSADC_BASE+0x0002) +#define WSA883X_OP_CTL (WSA883X_ANA_BG_TSADC_BASE+0x0003) +#define WSA883X_IREF_CTL (WSA883X_ANA_BG_TSADC_BASE+0x0004) +#define WSA883X_ISENS_CTL (WSA883X_ANA_BG_TSADC_BASE+0x0005) +#define WSA883X_CLK_CTL (WSA883X_ANA_BG_TSADC_BASE+0x0006) +#define WSA883X_TEST_CTL_1 (WSA883X_ANA_BG_TSADC_BASE+0x0007) +#define WSA883X_BIAS_1 (WSA883X_ANA_BG_TSADC_BASE+0x0008) +#define WSA883X_ADC_CTL (WSA883X_ANA_BG_TSADC_BASE+0x0009) +#define WSA883X_DOUT_MSB (WSA883X_ANA_BG_TSADC_BASE+0x000A) +#define WSA883X_DOUT_LSB (WSA883X_ANA_BG_TSADC_BASE+0x000B) +#define WSA883X_VBAT_SNS (WSA883X_ANA_BG_TSADC_BASE+0x000C) +#define WSA883X_ITRIM_CODE (WSA883X_ANA_BG_TSADC_BASE+0x000D) + +#define WSA883X_ANA_IVSENSE_BASE (WSA883X_BASE+0x0000000F) +#define WSA883X_EN (WSA883X_ANA_IVSENSE_BASE+0x0000) +#define WSA883X_OVERRIDE1 (WSA883X_ANA_IVSENSE_BASE+0x0001) +#define WSA883X_OVERRIDE2 (WSA883X_ANA_IVSENSE_BASE+0x0002) +#define WSA883X_VSENSE1 (WSA883X_ANA_IVSENSE_BASE+0x0003) +#define WSA883X_ISENSE1 (WSA883X_ANA_IVSENSE_BASE+0x0004) +#define WSA883X_ISENSE2 (WSA883X_ANA_IVSENSE_BASE+0x0005) +#define WSA883X_ISENSE_CAL (WSA883X_ANA_IVSENSE_BASE+0x0006) +#define WSA883X_MISC (WSA883X_ANA_IVSENSE_BASE+0x0007) +#define WSA883X_ADC_0 (WSA883X_ANA_IVSENSE_BASE+0x0008) +#define WSA883X_ADC_1 (WSA883X_ANA_IVSENSE_BASE+0x0009) +#define WSA883X_ADC_2 (WSA883X_ANA_IVSENSE_BASE+0x000A) +#define WSA883X_ADC_3 (WSA883X_ANA_IVSENSE_BASE+0x000B) +#define WSA883X_ADC_4 (WSA883X_ANA_IVSENSE_BASE+0x000C) +#define WSA883X_ADC_5 (WSA883X_ANA_IVSENSE_BASE+0x000D) +#define WSA883X_ADC_6 (WSA883X_ANA_IVSENSE_BASE+0x000E) +#define WSA883X_ADC_7 (WSA883X_ANA_IVSENSE_BASE+0x000F) +#define WSA883X_STATUS (WSA883X_ANA_IVSENSE_BASE+0x0010) + +#define WSA883X_ANA_SPK_TOP_BASE (WSA883X_BASE+0x00000025) +#define WSA883X_DAC_CTRL_REG (WSA883X_ANA_SPK_TOP_BASE+0x0000) +#define WSA883X_DAC_EN_DEBUG_REG (WSA883X_ANA_SPK_TOP_BASE+0x0001) +#define WSA883X_DAC_OPAMP_BIAS1_REG (WSA883X_ANA_SPK_TOP_BASE+0x0002) +#define WSA883X_DAC_OPAMP_BIAS2_REG (WSA883X_ANA_SPK_TOP_BASE+0x0003) +#define WSA883X_DAC_VCM_CTRL_REG (WSA883X_ANA_SPK_TOP_BASE+0x0004) +#define WSA883X_DAC_VOLTAGE_CTRL_REG (WSA883X_ANA_SPK_TOP_BASE+0x0005) +#define WSA883X_ATEST1_REG (WSA883X_ANA_SPK_TOP_BASE+0x0006) +#define WSA883X_ATEST2_REG (WSA883X_ANA_SPK_TOP_BASE+0x0007) +#define WSA883X_SPKR_TOP_BIAS_REG1 (WSA883X_ANA_SPK_TOP_BASE+0x0008) +#define WSA883X_SPKR_TOP_BIAS_REG2 (WSA883X_ANA_SPK_TOP_BASE+0x0009) +#define WSA883X_SPKR_TOP_BIAS_REG3 (WSA883X_ANA_SPK_TOP_BASE+0x000A) +#define WSA883X_SPKR_TOP_BIAS_REG4 (WSA883X_ANA_SPK_TOP_BASE+0x000B) +#define WSA883X_SPKR_CLIP_DET_REG (WSA883X_ANA_SPK_TOP_BASE+0x000C) +#define WSA883X_SPKR_DRV_LF_BLK_EN (WSA883X_ANA_SPK_TOP_BASE+0x000D) +#define WSA883X_SPKR_DRV_LF_EN (WSA883X_ANA_SPK_TOP_BASE+0x000E) +#define WSA883X_SPKR_DRV_LF_MASK_DCC_CTL (WSA883X_ANA_SPK_TOP_BASE+0x000F) +#define WSA883X_SPKR_DRV_LF_MISC_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0010) +#define WSA883X_SPKR_DRV_LF_REG_GAIN (WSA883X_ANA_SPK_TOP_BASE+0x0011) +#define WSA883X_SPKR_DRV_LF_OS_CAL_CTL1 (WSA883X_ANA_SPK_TOP_BASE+0x0012) +#define WSA883X_SPKR_DRV_LF_OS_CAL_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0013) +#define WSA883X_SPKR_PWM_CLK_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0014) +#define WSA883X_SPKR_PDRV_HS_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0015) +#define WSA883X_SPKR_PDRV_LS_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0016) +#define WSA883X_SPKR_PWRSTG_DBG (WSA883X_ANA_SPK_TOP_BASE+0x0017) +#define WSA883X_SPKR_OCP_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0018) +#define WSA883X_SPKR_BBM_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0019) +#define WSA883X_PA_STATUS0 (WSA883X_ANA_SPK_TOP_BASE+0x001A) +#define WSA883X_PA_STATUS1 (WSA883X_ANA_SPK_TOP_BASE+0x001B) +#define WSA883X_PA_STATUS2 (WSA883X_ANA_SPK_TOP_BASE+0x001C) + +#define WSA883X_ANA_BOOST_BASE (WSA883X_BASE+0x00000045) +#define WSA883X_EN_CTRL (WSA883X_ANA_BOOST_BASE+0x0000) +#define WSA883X_CURRENT_LIMIT (WSA883X_ANA_BOOST_BASE+0x0001) +#define WSA883X_IBIAS1 (WSA883X_ANA_BOOST_BASE+0x0002) +#define WSA883X_IBIAS2 (WSA883X_ANA_BOOST_BASE+0x0003) +#define WSA883X_IBIAS3 (WSA883X_ANA_BOOST_BASE+0x0004) +#define WSA883X_LDO_PROG (WSA883X_ANA_BOOST_BASE+0x0005) +#define WSA883X_STABILITY_CTRL1 (WSA883X_ANA_BOOST_BASE+0x0006) +#define WSA883X_STABILITY_CTRL2 (WSA883X_ANA_BOOST_BASE+0x0007) +#define WSA883X_PWRSTAGE_CTRL1 (WSA883X_ANA_BOOST_BASE+0x0008) +#define WSA883X_PWRSTAGE_CTRL2 (WSA883X_ANA_BOOST_BASE+0x0009) +#define WSA883X_UVLO (WSA883X_ANA_BOOST_BASE+0x000A) +#define WSA883X_SEQUENCE_CTRL (WSA883X_ANA_BOOST_BASE+0x000B) +#define WSA883X_ZX_CTRL_1 (WSA883X_ANA_BOOST_BASE+0x000C) +#define WSA883X_ZX_CTRL_2 (WSA883X_ANA_BOOST_BASE+0x000D) +#define WSA883X_MISC1 (WSA883X_ANA_BOOST_BASE+0x000E) +#define WSA883X_MISC2 (WSA883X_ANA_BOOST_BASE+0x000F) +#define WSA883X_GMAMP_SUP1 (WSA883X_ANA_BOOST_BASE+0x0010) +#define WSA883X_PWRSTAGE_CTRL3 (WSA883X_ANA_BOOST_BASE+0x0011) +#define WSA883X_PRSTAGE_CTRL4 (WSA883X_ANA_BOOST_BASE+0x0012) +#define WSA883X_SPARE1 (WSA883X_ANA_BOOST_BASE+0x0013) + +#define WSA883X_ANA_PON_LDOL_BASE (WSA883X_BASE+0x00000059) +#define WSA883X_PON_CTL_0 (WSA883X_ANA_PON_LDOL_BASE+0x0000) +#define WSA883X_PON_CLT_1 (WSA883X_ANA_PON_LDOL_BASE+0x0001) +#define WSA883X_PON_CTL_2 (WSA883X_ANA_PON_LDOL_BASE+0x0002) +#define WSA883X_PON_CTL_3 (WSA883X_ANA_PON_LDOL_BASE+0x0003) +#define WSA883X_PON_CTL_4 (WSA883X_ANA_PON_LDOL_BASE+0x0004) +#define WSA883X_CKWD_CTL_0 (WSA883X_ANA_PON_LDOL_BASE+0x0005) +#define WSA883X_CKWD_CTL_1 (WSA883X_ANA_PON_LDOL_BASE+0x0006) +#define WSA883X_CKWD_CTL_2 (WSA883X_ANA_PON_LDOL_BASE+0x0007) +#define WSA883X_CKSK_CTL_0 (WSA883X_ANA_PON_LDOL_BASE+0x0008) +#define WSA883X_TEST_0 (WSA883X_ANA_PON_LDOL_BASE+0x0009) +#define WSA883X_TEST_1 (WSA883X_ANA_PON_LDOL_BASE+0x000A) +#define WSA883X_STATUS_0 (WSA883X_ANA_PON_LDOL_BASE+0x000B) +#define WSA883X_STATUS_1 (WSA883X_ANA_PON_LDOL_BASE+0x000C) + +#define WSA883X_DIG_CTRL_BASE (WSA883X_BASE+0x00000400) +#define WSA883X_PAGE_REGISTER (WSA883X_DIG_CTRL_BASE+0x0000) +#define WSA883X_CHIP_ID0 (WSA883X_DIG_CTRL_BASE+0x0001) +#define WSA883X_CHIP_ID1 (WSA883X_DIG_CTRL_BASE+0x0002) +#define WSA883X_CHIP_ID2 (WSA883X_DIG_CTRL_BASE+0x0003) +#define WSA883X_CHIP_ID3 (WSA883X_DIG_CTRL_BASE+0x0004) +#define WSA883X_BUS_ID (WSA883X_DIG_CTRL_BASE+0x0005) +#define WSA883X_CDC_RST_CTL (WSA883X_DIG_CTRL_BASE+0x0006) +#define WSA883X_TOP_CLK_CFG (WSA883X_DIG_CTRL_BASE+0x0007) +#define WSA883X_CDC_PATH_MODE (WSA883X_DIG_CTRL_BASE+0x0008) +#define WSA883X_CDC_CLK_CTL (WSA883X_DIG_CTRL_BASE+0x0009) +#define WSA883X_SWR_RESET_EN (WSA883X_DIG_CTRL_BASE+0x000A) +#define WSA883X_PA_FSM_CTL (WSA883X_DIG_CTRL_BASE+0x0010) +#define WSA883X_PA_FSM_TIMER0 (WSA883X_DIG_CTRL_BASE+0x0011) +#define WSA883X_PA_FSM_TIMER1 (WSA883X_DIG_CTRL_BASE+0x0012) +#define WSA883X_PA_FSM_STA (WSA883X_DIG_CTRL_BASE+0x0013) +#define WSA883X_PA_FSM_ERR_COND (WSA883X_DIG_CTRL_BASE+0x0014) +#define WSA883X_PA_FSM_MSK (WSA883X_DIG_CTRL_BASE+0x0015) +#define WSA883X_PA_FSM_BYP (WSA883X_DIG_CTRL_BASE+0x0016) +#define WSA883X_TADC_VALUE_CTL (WSA883X_DIG_CTRL_BASE+0x0020) +#define WSA883X_TEMP_DETECT_CTL (WSA883X_DIG_CTRL_BASE+0x0021) +#define WSA883X_TEMP_MSB (WSA883X_DIG_CTRL_BASE+0x0022) +#define WSA883X_TEMP_LSB (WSA883X_DIG_CTRL_BASE+0x0023) +#define WSA883X_TEMP_CONFIG0 (WSA883X_DIG_CTRL_BASE+0x0024) +#define WSA883X_TEMP_CONFIG1 (WSA883X_DIG_CTRL_BASE+0x0025) +#define WSA883X_VBAT_ADC_FLT_CTL (WSA883X_DIG_CTRL_BASE+0x0026) +#define WSA883X_VBAT_DIN_MSB (WSA883X_DIG_CTRL_BASE+0x0027) +#define WSA883X_VBAT_DIN_LSB (WSA883X_DIG_CTRL_BASE+0x0028) +#define WSA883X_VBAT_DOUT (WSA883X_DIG_CTRL_BASE+0x0029) +#define WSA883X_SDM_PDM9_LSB (WSA883X_DIG_CTRL_BASE+0x002A) +#define WSA883X_SDM_PDM9_MSB (WSA883X_DIG_CTRL_BASE+0x002B) +#define WSA883X_CDC_RX_CTL (WSA883X_DIG_CTRL_BASE+0x0030) +#define WSA883X_CDC_SPK_DSM_A1_0 (WSA883X_DIG_CTRL_BASE+0x0031) +#define WSA883X_CDC_SPK_DSM_A1_1 (WSA883X_DIG_CTRL_BASE+0x0032) +#define WSA883X_CDC_SPK_DSM_A2_0 (WSA883X_DIG_CTRL_BASE+0x0033) +#define WSA883X_CDC_SPK_DSM_A2_1 (WSA883X_DIG_CTRL_BASE+0x0034) +#define WSA883X_CDC_SPK_DSM_A3_0 (WSA883X_DIG_CTRL_BASE+0x0035) +#define WSA883X_CDC_SPK_DSM_A3_1 (WSA883X_DIG_CTRL_BASE+0x0036) +#define WSA883X_CDC_SPK_DSM_A4_0 (WSA883X_DIG_CTRL_BASE+0x0037) +#define WSA883X_CDC_SPK_DSM_A4_1 (WSA883X_DIG_CTRL_BASE+0x0038) +#define WSA883X_CDC_SPK_DSM_A5_0 (WSA883X_DIG_CTRL_BASE+0x0039) +#define WSA883X_CDC_SPK_DSM_A5_1 (WSA883X_DIG_CTRL_BASE+0x003A) +#define WSA883X_CDC_SPK_DSM_A6_0 (WSA883X_DIG_CTRL_BASE+0x003B) +#define WSA883X_CDC_SPK_DSM_A7_0 (WSA883X_DIG_CTRL_BASE+0x003C) +#define WSA883X_CDC_SPK_DSM_C_0 (WSA883X_DIG_CTRL_BASE+0x003D) +#define WSA883X_CDC_SPK_DSM_C_1 (WSA883X_DIG_CTRL_BASE+0x003E) +#define WSA883X_CDC_SPK_DSM_C_2 (WSA883X_DIG_CTRL_BASE+0x003F) +#define WSA883X_CDC_SPK_DSM_C_3 (WSA883X_DIG_CTRL_BASE+0x0040) +#define WSA883X_CDC_SPK_DSM_R1 (WSA883X_DIG_CTRL_BASE+0x0041) +#define WSA883X_CDC_SPK_DSM_R2 (WSA883X_DIG_CTRL_BASE+0x0042) +#define WSA883X_CDC_SPK_DSM_R3 (WSA883X_DIG_CTRL_BASE+0x0043) +#define WSA883X_CDC_SPK_DSM_R4 (WSA883X_DIG_CTRL_BASE+0x0044) +#define WSA883X_CDC_SPK_DSM_R5 (WSA883X_DIG_CTRL_BASE+0x0045) +#define WSA883X_CDC_SPK_DSM_R6 (WSA883X_DIG_CTRL_BASE+0x0046) +#define WSA883X_CDC_SPK_DSM_R7 (WSA883X_DIG_CTRL_BASE+0x0047) +#define WSA883X_CDC_SPK_GAIN_PDM_0 (WSA883X_DIG_CTRL_BASE+0x0048) +#define WSA883X_CDC_SPK_GAIN_PDM_1 (WSA883X_DIG_CTRL_BASE+0x0049) +#define WSA883X_CDC_SPK_GAIN_PDM_2 (WSA883X_DIG_CTRL_BASE+0x004A) +#define WSA883X_PDM_WD_CTL (WSA883X_DIG_CTRL_BASE+0x004B) +#define WSA883X_DEM_BYPASS_DATA0 (WSA883X_DIG_CTRL_BASE+0x004C) +#define WSA883X_DEM_BYPASS_DATA1 (WSA883X_DIG_CTRL_BASE+0x004D) +#define WSA883X_DEM_BYPASS_DATA2 (WSA883X_DIG_CTRL_BASE+0x004E) +#define WSA883X_DEM_BYPASS_DATA3 (WSA883X_DIG_CTRL_BASE+0x004F) +#define WSA883X_WAVG_CTL (WSA883X_DIG_CTRL_BASE+0x0050) +#define WSA883X_WAVG_LRA_PER_0 (WSA883X_DIG_CTRL_BASE+0x0051) +#define WSA883X_WAVG_LRA_PER_1 (WSA883X_DIG_CTRL_BASE+0x0052) +#define WSA883X_WAVG_DELTA_THETA_0 (WSA883X_DIG_CTRL_BASE+0x0053) +#define WSA883X_WAVG_DELTA_THETA_1 (WSA883X_DIG_CTRL_BASE+0x0054) +#define WSA883X_WAVG_DIRECT_AMP_0 (WSA883X_DIG_CTRL_BASE+0x0055) +#define WSA883X_WAVG_DIRECT_AMP_1 (WSA883X_DIG_CTRL_BASE+0x0056) +#define WSA883X_WAVG_PTRN_AMP0_0 (WSA883X_DIG_CTRL_BASE+0x0057) +#define WSA883X_WAVG_PTRN_AMP0_1 (WSA883X_DIG_CTRL_BASE+0x0058) +#define WSA883X_WAVG_PTRN_AMP1_0 (WSA883X_DIG_CTRL_BASE+0x0059) +#define WSA883X_WAVG_PTRN_AMP1_1 (WSA883X_DIG_CTRL_BASE+0x005A) +#define WSA883X_WAVG_PTRN_AMP2_0 (WSA883X_DIG_CTRL_BASE+0x005B) +#define WSA883X_WAVG_PTRN_AMP2_1 (WSA883X_DIG_CTRL_BASE+0x005C) +#define WSA883X_WAVG_PTRN_AMP3_0 (WSA883X_DIG_CTRL_BASE+0x005D) +#define WSA883X_WAVG_PTRN_AMP3_1 (WSA883X_DIG_CTRL_BASE+0x005E) +#define WSA883X_WAVG_PTRN_AMP4_0 (WSA883X_DIG_CTRL_BASE+0x005F) +#define WSA883X_WAVG_PTRN_AMP4_1 (WSA883X_DIG_CTRL_BASE+0x0060) +#define WSA883X_WAVG_PTRN_AMP5_0 (WSA883X_DIG_CTRL_BASE+0x0061) +#define WSA883X_WAVG_PTRN_AMP5_1 (WSA883X_DIG_CTRL_BASE+0x0062) +#define WSA883X_WAVG_PTRN_AMP6_0 (WSA883X_DIG_CTRL_BASE+0x0063) +#define WSA883X_WAVG_PTRN_AMP6_1 (WSA883X_DIG_CTRL_BASE+0x0064) +#define WSA883X_WAVG_PTRN_AMP7_0 (WSA883X_DIG_CTRL_BASE+0x0065) +#define WSA883X_WAVG_PTRN_AMP7_1 (WSA883X_DIG_CTRL_BASE+0x0066) +#define WSA883X_WAVG_PER_0_1 (WSA883X_DIG_CTRL_BASE+0x0067) +#define WSA883X_WAVG_PER_2_3 (WSA883X_DIG_CTRL_BASE+0x0068) +#define WSA883X_WAVG_PER_4_5 (WSA883X_DIG_CTRL_BASE+0x0069) +#define WSA883X_WAVG_PER_6_7 (WSA883X_DIG_CTRL_BASE+0x006A) +#define WSA883X_DRE_CTL_0 (WSA883X_DIG_CTRL_BASE+0x006C) +#define WSA883X_DRE_CTL_1 (WSA883X_DIG_CTRL_BASE+0x006D) +#define WSA883X_CLSH_CTL_0 (WSA883X_DIG_CTRL_BASE+0x0070) +#define WSA883X_CLSH_CTL_1 (WSA883X_DIG_CTRL_BASE+0x0071) +#define WSA883X_CLSH_V_HD_PA (WSA883X_DIG_CTRL_BASE+0x0072) +#define WSA883X_CLSH_V_PA_MIN (WSA883X_DIG_CTRL_BASE+0x0073) +#define WSA883X_CLSH_OVRD_VAL (WSA883X_DIG_CTRL_BASE+0x0074) +#define WSA883X_CLSH_HARD_MAX (WSA883X_DIG_CTRL_BASE+0x0075) +#define WSA883X_CLSH_SOFT_MAX (WSA883X_DIG_CTRL_BASE+0x0076) +#define WSA883X_CLSH_SIG_DP (WSA883X_DIG_CTRL_BASE+0x0077) +#define WSA883X_TAGC_CTL (WSA883X_DIG_CTRL_BASE+0x0078) +#define WSA883X_TAGC_TIME (WSA883X_DIG_CTRL_BASE+0x0079) +#define WSA883X_TAGC_E2E_GAIN (WSA883X_DIG_CTRL_BASE+0x007A) +#define WSA883X_TAGC_FORCE_VAL (WSA883X_DIG_CTRL_BASE+0x007B) +#define WSA883X_VAGC_CTL (WSA883X_DIG_CTRL_BASE+0x007C) +#define WSA883X_VAGC_TIME (WSA883X_DIG_CTRL_BASE+0x007D) +#define WSA883X_VAGC_ATTN_LVL_1_2 (WSA883X_DIG_CTRL_BASE+0x007E) +#define WSA883X_VAGC_ATTN_LVL_3 (WSA883X_DIG_CTRL_BASE+0x007F) +#define WSA883X_INTR_MODE (WSA883X_DIG_CTRL_BASE+0x0080) +#define WSA883X_INTR_MASK0 (WSA883X_DIG_CTRL_BASE+0x0081) +#define WSA883X_INTR_MASK1 (WSA883X_DIG_CTRL_BASE+0x0082) +#define WSA883X_INTR_STATUS0 (WSA883X_DIG_CTRL_BASE+0x0083) +#define WSA883X_INTR_STATUS1 (WSA883X_DIG_CTRL_BASE+0x0084) +#define WSA883X_INTR_CLEAR0 (WSA883X_DIG_CTRL_BASE+0x0085) +#define WSA883X_INTR_CLEAR1 (WSA883X_DIG_CTRL_BASE+0x0086) +#define WSA883X_INTR_LEVEL0 (WSA883X_DIG_CTRL_BASE+0x0087) +#define WSA883X_INTR_LEVEL1 (WSA883X_DIG_CTRL_BASE+0x0088) +#define WSA883X_INTR_SET0 (WSA883X_DIG_CTRL_BASE+0x0089) +#define WSA883X_INTR_SET1 (WSA883X_DIG_CTRL_BASE+0x008A) +#define WSA883X_INTR_TEST0 (WSA883X_DIG_CTRL_BASE+0x008B) +#define WSA883X_INTR_TEST1 (WSA883X_DIG_CTRL_BASE+0x008C) +#define WSA883X_OTP_CTRL0 (WSA883X_DIG_CTRL_BASE+0x0090) +#define WSA883X_OTP_CTRL1 (WSA883X_DIG_CTRL_BASE+0x0091) +#define WSA883X_HDRIVE_CTL_GROUP1 (WSA883X_DIG_CTRL_BASE+0x0092) +#define WSA883X_PIN_CTL (WSA883X_DIG_CTRL_BASE+0x0093) +#define WSA883X_PIN_CTL_OE (WSA883X_DIG_CTRL_BASE+0x0094) +#define WSA883X_PIN_WDATA_IOPAD (WSA883X_DIG_CTRL_BASE+0x0095) +#define WSA883X_PIN_STATUS (WSA883X_DIG_CTRL_BASE+0x0096) +#define WSA883X_I2C_SLAVE_CTL (WSA883X_DIG_CTRL_BASE+0x0097) +#define WSA883X_PDM_TEST_MODE (WSA883X_DIG_CTRL_BASE+0x00A0) +#define WSA883X_ATE_TEST_MODE (WSA883X_DIG_CTRL_BASE+0x00A1) +#define WSA883X_DRE_TEST (WSA883X_DIG_CTRL_BASE+0x00A2) +#define WSA883X_DIG_DEBUG_MODE (WSA883X_DIG_CTRL_BASE+0x00A3) +#define WSA883X_DIG_DEBUG_SEL (WSA883X_DIG_CTRL_BASE+0x00A4) +#define WSA883X_DIG_DEBUG_EN (WSA883X_DIG_CTRL_BASE+0x00A5) +#define WSA883X_SWR_HM_TEST0 (WSA883X_DIG_CTRL_BASE+0x00A6) +#define WSA883X_SWR_HM_TEST1 (WSA883X_DIG_CTRL_BASE+0x00A7) +#define WSA883X_SWR_PAD_CTL (WSA883X_DIG_CTRL_BASE+0x00A8) +#define WSA883X_TEMP_DETECT_DBG_CTL (WSA883X_DIG_CTRL_BASE+0x00A9) +#define WSA883X_TEMP_DEBUG_MSB (WSA883X_DIG_CTRL_BASE+0x00AA) +#define WSA883X_TEMP_DEBUG_LSB (WSA883X_DIG_CTRL_BASE+0x00AB) +#define WSA883X_SAMPLE_EDGE_SEL (WSA883X_DIG_CTRL_BASE+0x00AC) +#define WSA883X_TEST_MODE_CTL (WSA883X_DIG_CTRL_BASE+0x00AD) +#define WSA883X_IOPAD_CTL (WSA883X_DIG_CTRL_BASE+0x00AE) +#define WSA883X_SPARE_0 (WSA883X_DIG_CTRL_BASE+0x00B0) +#define WSA883X_SPARE_1 (WSA883X_DIG_CTRL_BASE+0x00B1) +#define WSA883X_SPARE_2 (WSA883X_DIG_CTRL_BASE+0x00B2) +#define WSA883X_SCODE (WSA883X_DIG_CTRL_BASE+0x00C0) + +#define WSA883X_DIG_TRIM_BASE (WSA883X_BASE+0x00000500) +#define WSA883X_PAGE_REGISTER (WSA883X_DIG_TRIM_BASE+0x0000) +#define WSA883X_OTP_REG_0 (WSA883X_DIG_TRIM_BASE+0x0080) +#define WSA883X_OTP_REG_1 (WSA883X_DIG_TRIM_BASE+0x0081) +#define WSA883X_OTP_REG_2 (WSA883X_DIG_TRIM_BASE+0x0082) +#define WSA883X_OTP_REG_3 (WSA883X_DIG_TRIM_BASE+0x0083) +#define WSA883X_OTP_REG_4 (WSA883X_DIG_TRIM_BASE+0x0084) +#define WSA883X_OTP_REG_5 (WSA883X_DIG_TRIM_BASE+0x0085) +#define WSA883X_OTP_REG_6 (WSA883X_DIG_TRIM_BASE+0x0086) +#define WSA883X_OTP_REG_7 (WSA883X_DIG_TRIM_BASE+0x0087) +#define WSA883X_OTP_REG_8 (WSA883X_DIG_TRIM_BASE+0x0088) +#define WSA883X_OTP_REG_9 (WSA883X_DIG_TRIM_BASE+0x0089) +#define WSA883X_OTP_REG_10 (WSA883X_DIG_TRIM_BASE+0x008A) +#define WSA883X_OTP_REG_11 (WSA883X_DIG_TRIM_BASE+0x008B) +#define WSA883X_OTP_REG_12 (WSA883X_DIG_TRIM_BASE+0x008C) +#define WSA883X_OTP_REG_13 (WSA883X_DIG_TRIM_BASE+0x008D) +#define WSA883X_OTP_REG_14 (WSA883X_DIG_TRIM_BASE+0x008E) +#define WSA883X_OTP_REG_15 (WSA883X_DIG_TRIM_BASE+0x008F) +#define WSA883X_OTP_REG_16 (WSA883X_DIG_TRIM_BASE+0x0090) +#define WSA883X_OTP_REG_17 (WSA883X_DIG_TRIM_BASE+0x0091) +#define WSA883X_OTP_REG_18 (WSA883X_DIG_TRIM_BASE+0x0092) +#define WSA883X_OTP_REG_19 (WSA883X_DIG_TRIM_BASE+0x0093) +#define WSA883X_OTP_REG_20 (WSA883X_DIG_TRIM_BASE+0x0094) +#define WSA883X_OTP_REG_21 (WSA883X_DIG_TRIM_BASE+0x0095) +#define WSA883X_OTP_REG_22 (WSA883X_DIG_TRIM_BASE+0x0096) +#define WSA883X_OTP_REG_23 (WSA883X_DIG_TRIM_BASE+0x0097) +#define WSA883X_OTP_REG_24 (WSA883X_DIG_TRIM_BASE+0x0098) +#define WSA883X_OTP_REG_25 (WSA883X_DIG_TRIM_BASE+0x0099) +#define WSA883X_OTP_REG_26 (WSA883X_DIG_TRIM_BASE+0x009A) +#define WSA883X_OTP_REG_27 (WSA883X_DIG_TRIM_BASE+0x009B) +#define WSA883X_OTP_REG_28 (WSA883X_DIG_TRIM_BASE+0x009C) +#define WSA883X_OTP_REG_29 (WSA883X_DIG_TRIM_BASE+0x009D) +#define WSA883X_OTP_REG_30 (WSA883X_DIG_TRIM_BASE+0x009E) +#define WSA883X_OTP_REG_31 (WSA883X_DIG_TRIM_BASE+0x009F) +#define WSA883X_OTP_REG_SCODE (WSA883X_DIG_TRIM_BASE+0x00A0) +#define WSA883X_OTP_REG_63 (WSA883X_DIG_TRIM_BASE+0x00BF) + +#define WSA883X_DIG_EMEM_BASE (WSA883X_BASE+0x000005C0) +#define WSA883X_EMEM_0 (WSA883X_DIG_EMEM_BASE+0x0000) +#define WSA883X_EMEM_1 (WSA883X_DIG_EMEM_BASE+0x0001) +#define WSA883X_EMEM_2 (WSA883X_DIG_EMEM_BASE+0x0002) +#define WSA883X_EMEM_3 (WSA883X_DIG_EMEM_BASE+0x0003) +#define WSA883X_EMEM_4 (WSA883X_DIG_EMEM_BASE+0x0004) +#define WSA883X_EMEM_5 (WSA883X_DIG_EMEM_BASE+0x0005) +#define WSA883X_EMEM_6 (WSA883X_DIG_EMEM_BASE+0x0006) +#define WSA883X_EMEM_7 (WSA883X_DIG_EMEM_BASE+0x0007) +#define WSA883X_EMEM_8 (WSA883X_DIG_EMEM_BASE+0x0008) +#define WSA883X_EMEM_9 (WSA883X_DIG_EMEM_BASE+0x0009) +#define WSA883X_EMEM_10 (WSA883X_DIG_EMEM_BASE+0x000A) +#define WSA883X_EMEM_11 (WSA883X_DIG_EMEM_BASE+0x000B) +#define WSA883X_EMEM_12 (WSA883X_DIG_EMEM_BASE+0x000C) +#define WSA883X_EMEM_13 (WSA883X_DIG_EMEM_BASE+0x000D) +#define WSA883X_EMEM_14 (WSA883X_DIG_EMEM_BASE+0x000E) +#define WSA883X_EMEM_15 (WSA883X_DIG_EMEM_BASE+0x000F) +#define WSA883X_EMEM_16 (WSA883X_DIG_EMEM_BASE+0x0010) +#define WSA883X_EMEM_17 (WSA883X_DIG_EMEM_BASE+0x0011) +#define WSA883X_EMEM_18 (WSA883X_DIG_EMEM_BASE+0x0012) +#define WSA883X_EMEM_19 (WSA883X_DIG_EMEM_BASE+0x0013) +#define WSA883X_EMEM_20 (WSA883X_DIG_EMEM_BASE+0x0014) +#define WSA883X_EMEM_21 (WSA883X_DIG_EMEM_BASE+0x0015) +#define WSA883X_EMEM_22 (WSA883X_DIG_EMEM_BASE+0x0016) +#define WSA883X_EMEM_23 (WSA883X_DIG_EMEM_BASE+0x0017) +#define WSA883X_EMEM_24 (WSA883X_DIG_EMEM_BASE+0x0018) +#define WSA883X_EMEM_25 (WSA883X_DIG_EMEM_BASE+0x0019) +#define WSA883X_EMEM_26 (WSA883X_DIG_EMEM_BASE+0x001A) +#define WSA883X_EMEM_27 (WSA883X_DIG_EMEM_BASE+0x001B) +#define WSA883X_EMEM_28 (WSA883X_DIG_EMEM_BASE+0x001C) +#define WSA883X_EMEM_29 (WSA883X_DIG_EMEM_BASE+0x001D) +#define WSA883X_EMEM_30 (WSA883X_DIG_EMEM_BASE+0x001E) +#define WSA883X_EMEM_31 (WSA883X_DIG_EMEM_BASE+0x001F) +#define WSA883X_EMEM_32 (WSA883X_DIG_EMEM_BASE+0x0020) +#define WSA883X_EMEM_33 (WSA883X_DIG_EMEM_BASE+0x0021) +#define WSA883X_EMEM_34 (WSA883X_DIG_EMEM_BASE+0x0022) +#define WSA883X_EMEM_35 (WSA883X_DIG_EMEM_BASE+0x0023) +#define WSA883X_EMEM_36 (WSA883X_DIG_EMEM_BASE+0x0024) +#define WSA883X_EMEM_37 (WSA883X_DIG_EMEM_BASE+0x0025) +#define WSA883X_EMEM_38 (WSA883X_DIG_EMEM_BASE+0x0026) +#define WSA883X_EMEM_39 (WSA883X_DIG_EMEM_BASE+0x0027) +#define WSA883X_EMEM_40 (WSA883X_DIG_EMEM_BASE+0x0028) +#define WSA883X_EMEM_41 (WSA883X_DIG_EMEM_BASE+0x0029) +#define WSA883X_EMEM_42 (WSA883X_DIG_EMEM_BASE+0x002A) +#define WSA883X_EMEM_43 (WSA883X_DIG_EMEM_BASE+0x002B) +#define WSA883X_EMEM_44 (WSA883X_DIG_EMEM_BASE+0x002C) +#define WSA883X_EMEM_45 (WSA883X_DIG_EMEM_BASE+0x002D) +#define WSA883X_EMEM_46 (WSA883X_DIG_EMEM_BASE+0x002E) +#define WSA883X_EMEM_47 (WSA883X_DIG_EMEM_BASE+0x002F) +#define WSA883X_EMEM_48 (WSA883X_DIG_EMEM_BASE+0x0030) +#define WSA883X_EMEM_49 (WSA883X_DIG_EMEM_BASE+0x0031) +#define WSA883X_EMEM_50 (WSA883X_DIG_EMEM_BASE+0x0032) +#define WSA883X_EMEM_51 (WSA883X_DIG_EMEM_BASE+0x0033) +#define WSA883X_EMEM_52 (WSA883X_DIG_EMEM_BASE+0x0034) +#define WSA883X_EMEM_53 (WSA883X_DIG_EMEM_BASE+0x0035) +#define WSA883X_EMEM_54 (WSA883X_DIG_EMEM_BASE+0x0036) +#define WSA883X_EMEM_55 (WSA883X_DIG_EMEM_BASE+0x0037) +#define WSA883X_EMEM_56 (WSA883X_DIG_EMEM_BASE+0x0038) +#define WSA883X_EMEM_57 (WSA883X_DIG_EMEM_BASE+0x0039) +#define WSA883X_EMEM_58 (WSA883X_DIG_EMEM_BASE+0x003A) +#define WSA883X_EMEM_59 (WSA883X_DIG_EMEM_BASE+0x003B) +#define WSA883X_EMEM_60 (WSA883X_DIG_EMEM_BASE+0x003C) +#define WSA883X_EMEM_61 (WSA883X_DIG_EMEM_BASE+0x003D) +#define WSA883X_EMEM_62 (WSA883X_DIG_EMEM_BASE+0x003E) +#define WSA883X_EMEM_63 (WSA883X_DIG_EMEM_BASE+0x003F) + +#define WSA883X_NUM_REGISTERS (WSA883X_EMEM_63+1) +#define WSA883X_MAX_REGISTER (WSA883X_NUM_REGISTERS-1) + +#endif /* WSA883X_REGISTERS_H */ diff --git a/asoc/codecs/wsa883x/wsa883x-regmap.c b/asoc/codecs/wsa883x/wsa883x-regmap.c new file mode 100644 index 000000000000..8394e9c73e72 --- /dev/null +++ b/asoc/codecs/wsa883x/wsa883x-regmap.c @@ -0,0 +1,393 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015-2016, 2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include "wsa883x-registers.h" +#include "wsa883x.h" + +extern const u8 wsa883x_reg_access[WSA883X_NUM_REGISTERS]; + +static struct reg_default wsa883x_defaults[] = { + {WSA883X_REF_CTRL, 0x6C}, + {WSA883X_TEST_CTL_0, 0x06}, + {WSA883X_BIAS_0, 0xD2}, + {WSA883X_OP_CTL, 0xE0}, + {WSA883X_IREF_CTL, 0x58}, + {WSA883X_ISENS_CTL, 0x47}, + {WSA883X_CLK_CTL, 0x87}, + {WSA883X_TEST_CTL_1, 0x00}, + {WSA883X_BIAS_1, 0x51}, + {WSA883X_ADC_CTL, 0x03}, + {WSA883X_DOUT_MSB, 0x00}, + {WSA883X_DOUT_LSB, 0x00}, + {WSA883X_VBAT_SNS, 0x00}, + {WSA883X_ITRIM_CODE, 0x1F}, + {WSA883X_EN, 0x00}, + {WSA883X_OVERRIDE1, 0x00}, + {WSA883X_OVERRIDE2, 0x08}, + {WSA883X_VSENSE1, 0xD3}, + {WSA883X_ISENSE1, 0xD4}, + {WSA883X_ISENSE2, 0x20}, + {WSA883X_ISENSE_CAL, 0x00}, + {WSA883X_MISC, 0x00}, + {WSA883X_ADC_0, 0x00}, + {WSA883X_ADC_1, 0x00}, + {WSA883X_ADC_2, 0x00}, + {WSA883X_ADC_3, 0x00}, + {WSA883X_ADC_4, 0x45}, + {WSA883X_ADC_5, 0x20}, + {WSA883X_ADC_6, 0x10}, + {WSA883X_ADC_7, 0x00}, + {WSA883X_STATUS, 0x00}, + {WSA883X_DAC_CTRL_REG, 0x41}, + {WSA883X_DAC_EN_DEBUG_REG, 0x00}, + {WSA883X_DAC_OPAMP_BIAS1_REG, 0x48}, + {WSA883X_DAC_OPAMP_BIAS2_REG, 0x48}, + {WSA883X_DAC_VCM_CTRL_REG, 0x0B}, + {WSA883X_DAC_VOLTAGE_CTRL_REG, 0x05}, + {WSA883X_ATEST1_REG, 0x00}, + {WSA883X_ATEST2_REG, 0x00}, + {WSA883X_SPKR_TOP_BIAS_REG1, 0x4A}, + {WSA883X_SPKR_TOP_BIAS_REG2, 0x65}, + {WSA883X_SPKR_TOP_BIAS_REG3, 0x55}, + {WSA883X_SPKR_TOP_BIAS_REG4, 0xA9}, + {WSA883X_SPKR_CLIP_DET_REG, 0x00}, + {WSA883X_SPKR_DRV_LF_BLK_EN, 0x0F}, + {WSA883X_SPKR_DRV_LF_EN, 0x0A}, + {WSA883X_SPKR_DRV_LF_MASK_DCC_CTL, 0x00}, + {WSA883X_SPKR_DRV_LF_MISC_CTL, 0x32}, + {WSA883X_SPKR_DRV_LF_REG_GAIN, 0x00}, + {WSA883X_SPKR_DRV_LF_OS_CAL_CTL1, 0x90}, + {WSA883X_SPKR_DRV_LF_OS_CAL_CTL, 0x00}, + {WSA883X_SPKR_PWM_CLK_CTL, 0x00}, + {WSA883X_SPKR_PDRV_HS_CTL, 0x50}, + {WSA883X_SPKR_PDRV_LS_CTL, 0x48}, + {WSA883X_SPKR_PWRSTG_DBG, 0x00}, + {WSA883X_SPKR_OCP_CTL, 0x00}, + {WSA883X_SPKR_BBM_CTL, 0x90}, + {WSA883X_PA_STATUS0, 0x00}, + {WSA883X_PA_STATUS1, 0x00}, + {WSA883X_PA_STATUS2, 0x00}, + {WSA883X_EN_CTRL, 0x54}, + {WSA883X_CURRENT_LIMIT, 0x90}, + {WSA883X_IBIAS1, 0x00}, + {WSA883X_IBIAS2, 0x00}, + {WSA883X_IBIAS3, 0x00}, + {WSA883X_LDO_PROG, 0x2A}, + {WSA883X_STABILITY_CTRL1, 0x8E}, + {WSA883X_STABILITY_CTRL2, 0x00}, + {WSA883X_PWRSTAGE_CTRL1, 0x00}, + {WSA883X_PWRSTAGE_CTRL2, 0x40}, + {WSA883X_UVLO, 0xE9}, + {WSA883X_SEQUENCE_CTRL, 0x11}, + {WSA883X_ZX_CTRL_1, 0xF0}, + {WSA883X_ZX_CTRL_2, 0x06}, + {WSA883X_MISC1, 0x02}, + {WSA883X_MISC2, 0x81}, + {WSA883X_GMAMP_SUP1, 0x84}, + {WSA883X_PWRSTAGE_CTRL3, 0x14}, + {WSA883X_PRSTAGE_CTRL4, 0x5F}, + {WSA883X_SPARE1, 0x00}, + {WSA883X_PON_CTL_0, 0xE3}, + {WSA883X_PON_CLT_1, 0x70}, + {WSA883X_PON_CTL_2, 0x00}, + {WSA883X_PON_CTL_3, 0x00}, + {WSA883X_PON_CTL_4, 0x00}, + {WSA883X_CKWD_CTL_0, 0x34}, + {WSA883X_CKWD_CTL_1, 0x80}, + {WSA883X_CKWD_CTL_2, 0x00}, + {WSA883X_CKSK_CTL_0, 0x0A}, + {WSA883X_TEST_0, 0x00}, + {WSA883X_TEST_1, 0x00}, + {WSA883X_STATUS_0, 0x00}, + {WSA883X_STATUS_1, 0x00}, + {WSA883X_PAGE_REGISTER, 0x00}, + {WSA883X_CHIP_ID0, 0x00}, + {WSA883X_CHIP_ID1, 0x00}, + {WSA883X_CHIP_ID2, 0x02}, + {WSA883X_CHIP_ID3, 0x02}, + {WSA883X_BUS_ID, 0x00}, + {WSA883X_CDC_RST_CTL, 0x01}, + {WSA883X_TOP_CLK_CFG, 0x00}, + {WSA883X_CDC_PATH_MODE, 0x00}, + {WSA883X_CDC_CLK_CTL, 0xFF}, + {WSA883X_SWR_RESET_EN, 0x00}, + {WSA883X_PA_FSM_CTL, 0x00}, + {WSA883X_PA_FSM_TIMER0, 0x80}, + {WSA883X_PA_FSM_TIMER1, 0x80}, + {WSA883X_PA_FSM_STA, 0x00}, + {WSA883X_PA_FSM_ERR_COND, 0x00}, + {WSA883X_PA_FSM_MSK, 0x00}, + {WSA883X_PA_FSM_BYP, 0x00}, + {WSA883X_TADC_VALUE_CTL, 0x03}, + {WSA883X_TEMP_DETECT_CTL, 0x01}, + {WSA883X_TEMP_MSB, 0x00}, + {WSA883X_TEMP_LSB, 0x00}, + {WSA883X_TEMP_CONFIG0, 0x00}, + {WSA883X_TEMP_CONFIG1, 0x00}, + {WSA883X_VBAT_ADC_FLT_CTL, 0x00}, + {WSA883X_VBAT_DIN_MSB, 0x00}, + {WSA883X_VBAT_DIN_LSB, 0x00}, + {WSA883X_VBAT_DOUT, 0x00}, + {WSA883X_SDM_PDM9_LSB, 0x00}, + {WSA883X_SDM_PDM9_MSB, 0x00}, + {WSA883X_CDC_RX_CTL, 0xFE}, + {WSA883X_CDC_SPK_DSM_A1_0, 0x00}, + {WSA883X_CDC_SPK_DSM_A1_1, 0x01}, + {WSA883X_CDC_SPK_DSM_A2_0, 0x96}, + {WSA883X_CDC_SPK_DSM_A2_1, 0x09}, + {WSA883X_CDC_SPK_DSM_A3_0, 0xAB}, + {WSA883X_CDC_SPK_DSM_A3_1, 0x05}, + {WSA883X_CDC_SPK_DSM_A4_0, 0x1C}, + {WSA883X_CDC_SPK_DSM_A4_1, 0x02}, + {WSA883X_CDC_SPK_DSM_A5_0, 0x17}, + {WSA883X_CDC_SPK_DSM_A5_1, 0x02}, + {WSA883X_CDC_SPK_DSM_A6_0, 0xAA}, + {WSA883X_CDC_SPK_DSM_A7_0, 0xE3}, + {WSA883X_CDC_SPK_DSM_C_0, 0x69}, + {WSA883X_CDC_SPK_DSM_C_1, 0x54}, + {WSA883X_CDC_SPK_DSM_C_2, 0x02}, + {WSA883X_CDC_SPK_DSM_C_3, 0x15}, + {WSA883X_CDC_SPK_DSM_R1, 0xA4}, + {WSA883X_CDC_SPK_DSM_R2, 0xB5}, + {WSA883X_CDC_SPK_DSM_R3, 0x86}, + {WSA883X_CDC_SPK_DSM_R4, 0x85}, + {WSA883X_CDC_SPK_DSM_R5, 0xAA}, + {WSA883X_CDC_SPK_DSM_R6, 0xE2}, + {WSA883X_CDC_SPK_DSM_R7, 0x62}, + {WSA883X_CDC_SPK_GAIN_PDM_0, 0x00}, + {WSA883X_CDC_SPK_GAIN_PDM_1, 0xFC}, + {WSA883X_CDC_SPK_GAIN_PDM_2, 0x05}, + {WSA883X_PDM_WD_CTL, 0x00}, + {WSA883X_DEM_BYPASS_DATA0, 0x00}, + {WSA883X_DEM_BYPASS_DATA1, 0x00}, + {WSA883X_DEM_BYPASS_DATA2, 0x00}, + {WSA883X_DEM_BYPASS_DATA3, 0x00}, + {WSA883X_WAVG_CTL, 0x06}, + {WSA883X_WAVG_LRA_PER_0, 0xD1}, + {WSA883X_WAVG_LRA_PER_1, 0x00}, + {WSA883X_WAVG_DELTA_THETA_0, 0xE6}, + {WSA883X_WAVG_DELTA_THETA_1, 0x04}, + {WSA883X_WAVG_DIRECT_AMP_0, 0x50}, + {WSA883X_WAVG_DIRECT_AMP_1, 0x00}, + {WSA883X_WAVG_PTRN_AMP0_0, 0x50}, + {WSA883X_WAVG_PTRN_AMP0_1, 0x00}, + {WSA883X_WAVG_PTRN_AMP1_0, 0x50}, + {WSA883X_WAVG_PTRN_AMP1_1, 0x00}, + {WSA883X_WAVG_PTRN_AMP2_0, 0x50}, + {WSA883X_WAVG_PTRN_AMP2_1, 0x00}, + {WSA883X_WAVG_PTRN_AMP3_0, 0x50}, + {WSA883X_WAVG_PTRN_AMP3_1, 0x00}, + {WSA883X_WAVG_PTRN_AMP4_0, 0x50}, + {WSA883X_WAVG_PTRN_AMP4_1, 0x00}, + {WSA883X_WAVG_PTRN_AMP5_0, 0x50}, + {WSA883X_WAVG_PTRN_AMP5_1, 0x00}, + {WSA883X_WAVG_PTRN_AMP6_0, 0x50}, + {WSA883X_WAVG_PTRN_AMP6_1, 0x00}, + {WSA883X_WAVG_PTRN_AMP7_0, 0x50}, + {WSA883X_WAVG_PTRN_AMP7_1, 0x00}, + {WSA883X_WAVG_PER_0_1, 0x88}, + {WSA883X_WAVG_PER_2_3, 0x88}, + {WSA883X_WAVG_PER_4_5, 0x88}, + {WSA883X_WAVG_PER_6_7, 0x88}, + {WSA883X_DRE_CTL_0, 0x30}, + {WSA883X_DRE_CTL_1, 0x20}, + {WSA883X_CLSH_CTL_0, 0x37}, + {WSA883X_CLSH_CTL_1, 0x81}, + {WSA883X_CLSH_V_HD_PA, 0x0F}, + {WSA883X_CLSH_V_PA_MIN, 0x00}, + {WSA883X_CLSH_OVRD_VAL, 0x00}, + {WSA883X_CLSH_HARD_MAX, 0xFF}, + {WSA883X_CLSH_SOFT_MAX, 0xFF}, + {WSA883X_CLSH_SIG_DP, 0x00}, + {WSA883X_TAGC_CTL, 0x10}, + {WSA883X_TAGC_TIME, 0x20}, + {WSA883X_TAGC_E2E_GAIN, 0x02}, + {WSA883X_TAGC_FORCE_VAL, 0x00}, + {WSA883X_VAGC_CTL, 0x00}, + {WSA883X_VAGC_TIME, 0x08}, + {WSA883X_VAGC_ATTN_LVL_1_2, 0x21}, + {WSA883X_VAGC_ATTN_LVL_3, 0x03}, + {WSA883X_INTR_MODE, 0x00}, + {WSA883X_INTR_MASK0, 0x1B}, + {WSA883X_INTR_MASK1, 0x03}, + {WSA883X_INTR_STATUS0, 0x00}, + {WSA883X_INTR_STATUS1, 0x00}, + {WSA883X_INTR_CLEAR0, 0x00}, + {WSA883X_INTR_CLEAR1, 0x03}, + {WSA883X_INTR_LEVEL0, 0x00}, + {WSA883X_INTR_LEVEL1, 0x03}, + {WSA883X_INTR_SET0, 0x00}, + {WSA883X_INTR_SET1, 0x03}, + {WSA883X_INTR_TEST0, 0x00}, + {WSA883X_INTR_TEST1, 0x03}, + {WSA883X_OTP_CTRL0, 0x00}, + {WSA883X_OTP_CTRL1, 0x00}, + {WSA883X_HDRIVE_CTL_GROUP1, 0x00}, + {WSA883X_PIN_CTL, 0x04}, + {WSA883X_PIN_CTL_OE, 0x00}, + {WSA883X_PIN_WDATA_IOPAD, 0x00}, + {WSA883X_PIN_STATUS, 0x00}, + {WSA883X_I2C_SLAVE_CTL, 0x00}, + {WSA883X_PDM_TEST_MODE, 0x00}, + {WSA883X_ATE_TEST_MODE, 0x00}, + {WSA883X_DRE_TEST, 0x00}, + {WSA883X_DIG_DEBUG_MODE, 0x00}, + {WSA883X_DIG_DEBUG_SEL, 0x00}, + {WSA883X_DIG_DEBUG_EN, 0x00}, + {WSA883X_SWR_HM_TEST0, 0x08}, + {WSA883X_SWR_HM_TEST1, 0x00}, + {WSA883X_SWR_PAD_CTL, 0x45}, + {WSA883X_TEMP_DETECT_DBG_CTL, 0x00}, + {WSA883X_TEMP_DEBUG_MSB, 0x00}, + {WSA883X_TEMP_DEBUG_LSB, 0x00}, + {WSA883X_SAMPLE_EDGE_SEL, 0x7F}, + {WSA883X_TEST_MODE_CTL, 0x00}, + {WSA883X_IOPAD_CTL, 0x00}, + {WSA883X_SPARE_0, 0x00}, + {WSA883X_SPARE_1, 0x00}, + {WSA883X_SPARE_2, 0x00}, + {WSA883X_SCODE, 0x00}, + {WSA883X_PAGE_REGISTER, 0x00}, + {WSA883X_OTP_REG_0, 0x01}, + {WSA883X_OTP_REG_1, 0xFF}, + {WSA883X_OTP_REG_2, 0xC0}, + {WSA883X_OTP_REG_3, 0xFF}, + {WSA883X_OTP_REG_4, 0xC0}, + {WSA883X_OTP_REG_5, 0xFF}, + {WSA883X_OTP_REG_6, 0xFF}, + {WSA883X_OTP_REG_7, 0xFF}, + {WSA883X_OTP_REG_8, 0xFF}, + {WSA883X_OTP_REG_9, 0xFF}, + {WSA883X_OTP_REG_10, 0xFF}, + {WSA883X_OTP_REG_11, 0xFF}, + {WSA883X_OTP_REG_12, 0xFF}, + {WSA883X_OTP_REG_13, 0xFF}, + {WSA883X_OTP_REG_14, 0xFF}, + {WSA883X_OTP_REG_15, 0xFF}, + {WSA883X_OTP_REG_16, 0xFF}, + {WSA883X_OTP_REG_17, 0xFF}, + {WSA883X_OTP_REG_18, 0xFF}, + {WSA883X_OTP_REG_19, 0xFF}, + {WSA883X_OTP_REG_20, 0xFF}, + {WSA883X_OTP_REG_21, 0xFF}, + {WSA883X_OTP_REG_22, 0xFF}, + {WSA883X_OTP_REG_23, 0xFF}, + {WSA883X_OTP_REG_24, 0x03}, + {WSA883X_OTP_REG_25, 0x01}, + {WSA883X_OTP_REG_26, 0x03}, + {WSA883X_OTP_REG_27, 0x11}, + {WSA883X_OTP_REG_28, 0x3F}, + {WSA883X_OTP_REG_29, 0x3F}, + {WSA883X_OTP_REG_30, 0x01}, + {WSA883X_OTP_REG_31, 0x01}, + {WSA883X_OTP_REG_SCODE, 0x00}, + {WSA883X_OTP_REG_63, 0x40}, + {WSA883X_EMEM_0, 0x00}, + {WSA883X_EMEM_1, 0x00}, + {WSA883X_EMEM_2, 0x00}, + {WSA883X_EMEM_3, 0x00}, + {WSA883X_EMEM_4, 0x00}, + {WSA883X_EMEM_5, 0x00}, + {WSA883X_EMEM_6, 0x00}, + {WSA883X_EMEM_7, 0x00}, + {WSA883X_EMEM_8, 0x00}, + {WSA883X_EMEM_9, 0x00}, + {WSA883X_EMEM_10, 0x00}, + {WSA883X_EMEM_11, 0x00}, + {WSA883X_EMEM_12, 0x00}, + {WSA883X_EMEM_13, 0x00}, + {WSA883X_EMEM_14, 0x00}, + {WSA883X_EMEM_15, 0x00}, + {WSA883X_EMEM_16, 0x00}, + {WSA883X_EMEM_17, 0x00}, + {WSA883X_EMEM_18, 0x00}, + {WSA883X_EMEM_19, 0x00}, + {WSA883X_EMEM_20, 0x00}, + {WSA883X_EMEM_21, 0x00}, + {WSA883X_EMEM_22, 0x00}, + {WSA883X_EMEM_23, 0x00}, + {WSA883X_EMEM_24, 0x00}, + {WSA883X_EMEM_25, 0x00}, + {WSA883X_EMEM_26, 0x00}, + {WSA883X_EMEM_27, 0x00}, + {WSA883X_EMEM_28, 0x00}, + {WSA883X_EMEM_29, 0x00}, + {WSA883X_EMEM_30, 0x00}, + {WSA883X_EMEM_31, 0x00}, + {WSA883X_EMEM_32, 0x00}, + {WSA883X_EMEM_33, 0x00}, + {WSA883X_EMEM_34, 0x00}, + {WSA883X_EMEM_35, 0x00}, + {WSA883X_EMEM_36, 0x00}, + {WSA883X_EMEM_37, 0x00}, + {WSA883X_EMEM_38, 0x00}, + {WSA883X_EMEM_39, 0x00}, + {WSA883X_EMEM_40, 0x00}, + {WSA883X_EMEM_41, 0x00}, + {WSA883X_EMEM_42, 0x00}, + {WSA883X_EMEM_43, 0x00}, + {WSA883X_EMEM_44, 0x00}, + {WSA883X_EMEM_45, 0x00}, + {WSA883X_EMEM_46, 0x00}, + {WSA883X_EMEM_47, 0x00}, + {WSA883X_EMEM_48, 0x00}, + {WSA883X_EMEM_49, 0x00}, + {WSA883X_EMEM_50, 0x00}, + {WSA883X_EMEM_51, 0x00}, + {WSA883X_EMEM_52, 0x00}, + {WSA883X_EMEM_53, 0x00}, + {WSA883X_EMEM_54, 0x00}, + {WSA883X_EMEM_55, 0x00}, + {WSA883X_EMEM_56, 0x00}, + {WSA883X_EMEM_57, 0x00}, + {WSA883X_EMEM_58, 0x00}, + {WSA883X_EMEM_59, 0x00}, + {WSA883X_EMEM_60, 0x00}, + {WSA883X_EMEM_61, 0x00}, + {WSA883X_EMEM_62, 0x00}, + {WSA883X_EMEM_63, 0x00}, +}; + +static bool wsa883x_readable_register(struct device *dev, unsigned int reg) +{ + if (reg <= WSA883X_BASE) + return 0; + + return wsa883x_reg_access[WSA883X_REG(reg)] & RD_REG; +} + +static bool wsa883x_writeable_register(struct device *dev, unsigned int reg) +{ + if (reg <= WSA883X_BASE) + return 0; + + return wsa883x_reg_access[WSA883X_REG(reg)] & WR_REG; +} + +static bool wsa883x_volatile_register(struct device *dev, unsigned int reg) +{ + if (reg <= WSA883X_BASE) + return 0; + + return ((wsa883x_reg_access[WSA883X_REG(reg)] & RD_REG) && + !(wsa883x_reg_access[WSA883X_REG(reg)] & WR_REG)); +} + +struct regmap_config wsa881x_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wsa883x_defaults, + .num_reg_defaults = ARRAY_SIZE(wsa883x_defaults), + .max_register = WSA883X_MAX_REGISTER, + .volatile_reg = wsa883x_volatile_register, + .readable_reg = wsa883x_readable_register, + .writeable_reg = wsa883x_writeable_register, + .reg_format_endian = REGMAP_ENDIAN_NATIVE, + .val_format_endian = REGMAP_ENDIAN_NATIVE, + .can_multi_write = true, +}; diff --git a/asoc/codecs/wsa883x/wsa883x-tables.c b/asoc/codecs/wsa883x/wsa883x-tables.c new file mode 100644 index 000000000000..16b0a880a7ec --- /dev/null +++ b/asoc/codecs/wsa883x/wsa883x-tables.c @@ -0,0 +1,350 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include "wsa883x-registers.h" + +const u8 wsa883x_reg_readable[WSA883X_NUM_REGISTERS] = { + [WSA883X_REG(WSA883X_REF_CTRL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TEST_CTL_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_BIAS_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OP_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_IREF_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ISENS_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CLK_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TEST_CTL_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_BIAS_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ADC_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_DOUT_MSB)] = RD_REG, + [WSA883X_REG(WSA883X_DOUT_LSB)] = RD_REG, + [WSA883X_REG(WSA883X_VBAT_SNS)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ITRIM_CODE)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EN)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OVERRIDE1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OVERRIDE2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_VSENSE1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ISENSE1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ISENSE2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ISENSE_CAL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_MISC)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ADC_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ADC_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ADC_2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ADC_3)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ADC_4)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ADC_5)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ADC_6)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ADC_7)] = RD_WR_REG, + [WSA883X_REG(WSA883X_STATUS)] = RD_REG, + [WSA883X_REG(WSA883X_DAC_CTRL_REG)] = RD_WR_REG, + [WSA883X_REG(WSA883X_DAC_EN_DEBUG_REG)] = RD_WR_REG, + [WSA883X_REG(WSA883X_DAC_OPAMP_BIAS1_REG)] = RD_WR_REG, + [WSA883X_REG(WSA883X_DAC_OPAMP_BIAS2_REG)] = RD_WR_REG, + [WSA883X_REG(WSA883X_DAC_VCM_CTRL_REG)] = RD_WR_REG, + [WSA883X_REG(WSA883X_DAC_VOLTAGE_CTRL_REG)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ATEST1_REG)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ATEST2_REG)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_TOP_BIAS_REG1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_TOP_BIAS_REG2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_TOP_BIAS_REG3)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_TOP_BIAS_REG4)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_CLIP_DET_REG)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_DRV_LF_BLK_EN)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_DRV_LF_EN)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_DRV_LF_MASK_DCC_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_DRV_LF_MISC_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_DRV_LF_REG_GAIN)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_DRV_LF_OS_CAL_CTL1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_DRV_LF_OS_CAL_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_PWM_CLK_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_PDRV_HS_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_PDRV_LS_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_PWRSTG_DBG)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_OCP_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_BBM_CTL)] = RD_REG, + [WSA883X_REG(WSA883X_PA_STATUS0)] = RD_REG, + [WSA883X_REG(WSA883X_PA_STATUS1)] = RD_REG, + [WSA883X_REG(WSA883X_PA_STATUS2)] = RD_REG, + [WSA883X_REG(WSA883X_EN_CTRL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CURRENT_LIMIT)] = RD_WR_REG, + [WSA883X_REG(WSA883X_IBIAS1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_IBIAS2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_IBIAS3)] = RD_WR_REG, + [WSA883X_REG(WSA883X_LDO_PROG)] = RD_WR_REG, + [WSA883X_REG(WSA883X_STABILITY_CTRL1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_STABILITY_CTRL2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PWRSTAGE_CTRL1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PWRSTAGE_CTRL2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_UVLO)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SEQUENCE_CTRL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ZX_CTRL_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ZX_CTRL_2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_MISC1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_MISC2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_GMAMP_SUP1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PWRSTAGE_CTRL3)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PRSTAGE_CTRL4)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPARE1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PON_CTL_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PON_CLT_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PON_CTL_2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PON_CTL_3)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PON_CTL_4)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CKWD_CTL_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CKWD_CTL_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CKWD_CTL_2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CKSK_CTL_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TEST_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TEST_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_STATUS_0)] = RD_REG, + [WSA883X_REG(WSA883X_STATUS_1)] = RD_REG, + [WSA883X_REG(WSA883X_PAGE_REGISTER)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CHIP_ID0)] = RD_REG, + [WSA883X_REG(WSA883X_CHIP_ID1)] = RD_REG, + [WSA883X_REG(WSA883X_CHIP_ID2)] = RD_REG, + [WSA883X_REG(WSA883X_CHIP_ID3)] = RD_REG, + [WSA883X_REG(WSA883X_BUS_ID)] = RD_REG, + [WSA883X_REG(WSA883X_CDC_RST_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TOP_CLK_CFG)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_PATH_MODE)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_CLK_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SWR_RESET_EN)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PA_FSM_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PA_FSM_TIMER0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PA_FSM_TIMER1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PA_FSM_STA)] = RD_REG, + [WSA883X_REG(WSA883X_PA_FSM_ERR_COND)] = RD_REG, + [WSA883X_REG(WSA883X_PA_FSM_MSK)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PA_FSM_BYP)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TADC_VALUE_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TEMP_DETECT_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TEMP_MSB)] = RD_REG, + [WSA883X_REG(WSA883X_TEMP_LSB)] = RD_REG, + [WSA883X_REG(WSA883X_TEMP_CONFIG0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TEMP_CONFIG1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_VBAT_ADC_FLT_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_VBAT_DIN_MSB)] = RD_REG, + [WSA883X_REG(WSA883X_VBAT_DIN_LSB)] = RD_REG, + [WSA883X_REG(WSA883X_VBAT_DOUT)] = RD_REG, + [WSA883X_REG(WSA883X_SDM_PDM9_LSB)] = RD_REG, + [WSA883X_REG(WSA883X_SDM_PDM9_MSB)] = RD_REG, + [WSA883X_REG(WSA883X_CDC_RX_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_A1_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_A1_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_A2_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_A2_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_A3_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_A3_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_A4_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_A4_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_A5_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_A5_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_A6_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_A7_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_C_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_C_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_C_2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_C_3)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_R1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_R2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_R3)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_R4)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_R5)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_R6)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_DSM_R7)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_GAIN_PDM_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_GAIN_PDM_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CDC_SPK_GAIN_PDM_2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PDM_WD_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_DEM_BYPASS_DATA0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_DEM_BYPASS_DATA1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_DEM_BYPASS_DATA2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_DEM_BYPASS_DATA3)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_LRA_PER_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_LRA_PER_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_DELTA_THETA_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_DELTA_THETA_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_DIRECT_AMP_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_DIRECT_AMP_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PTRN_AMP0_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PTRN_AMP0_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PTRN_AMP1_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PTRN_AMP1_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PTRN_AMP2_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PTRN_AMP2_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PTRN_AMP3_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PTRN_AMP3_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PTRN_AMP4_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PTRN_AMP4_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PTRN_AMP5_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PTRN_AMP5_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PTRN_AMP6_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PTRN_AMP6_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PTRN_AMP7_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PTRN_AMP7_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PER_0_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PER_2_3)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PER_4_5)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_PER_6_7)] = RD_WR_REG, + [WSA883X_REG(WSA883X_DRE_CTL_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_DRE_CTL_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CLSH_CTL_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CLSH_CTL_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CLSH_V_HD_PA)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CLSH_V_PA_MIN)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CLSH_OVRD_VAL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CLSH_HARD_MAX)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CLSH_SOFT_MAX)] = RD_WR_REG, + [WSA883X_REG(WSA883X_CLSH_SIG_DP)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TAGC_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TAGC_TIME)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TAGC_E2E_GAIN)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TAGC_FORCE_VAL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_VAGC_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_VAGC_TIME)] = RD_WR_REG, + [WSA883X_REG(WSA883X_VAGC_ATTN_LVL_1_2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_VAGC_ATTN_LVL_3)] = RD_WR_REG, + [WSA883X_REG(WSA883X_INTR_MODE)] = RD_WR_REG, + [WSA883X_REG(WSA883X_INTR_MASK0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_INTR_MASK1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_INTR_STATUS0)] = RD_REG, + [WSA883X_REG(WSA883X_INTR_STATUS1)] = RD_REG, + [WSA883X_REG(WSA883X_INTR_CLEAR0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_INTR_CLEAR1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_INTR_LEVEL0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_INTR_LEVEL1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_INTR_SET0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_INTR_SET1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_INTR_TEST0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_INTR_TEST1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_CTRL0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_CTRL1)] = RD_REG, + [WSA883X_REG(WSA883X_HDRIVE_CTL_GROUP1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PIN_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PIN_CTL_OE)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PIN_WDATA_IOPAD)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PIN_STATUS)] = RD_REG, + [WSA883X_REG(WSA883X_I2C_SLAVE_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PDM_TEST_MODE)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ATE_TEST_MODE)] = RD_REG, + [WSA883X_REG(WSA883X_DRE_TEST)] = RD_WR_REG, + [WSA883X_REG(WSA883X_DIG_DEBUG_MODE)] = RD_WR_REG, + [WSA883X_REG(WSA883X_DIG_DEBUG_SEL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_DIG_DEBUG_EN)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SWR_HM_TEST0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SWR_HM_TEST1)] = RD_REG, + [WSA883X_REG(WSA883X_SWR_PAD_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TEMP_DETECT_DBG_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TEMP_DEBUG_MSB)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TEMP_DEBUG_LSB)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SAMPLE_EDGE_SEL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TEST_MODE_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_IOPAD_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPARE_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPARE_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPARE_2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SCODE)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PAGE_REGISTER)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_3)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_4)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_5)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_6)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_7)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_8)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_9)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_10)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_11)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_12)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_13)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_14)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_15)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_16)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_17)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_18)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_19)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_20)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_21)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_22)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_23)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_24)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_25)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_26)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_27)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_28)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_29)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_30)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_31)] = RD_REG, + [WSA883X_REG(WSA883X_OTP_REG_SCODE)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_63)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_2)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_3)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_4)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_5)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_6)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_7)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_8)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_9)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_10)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_11)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_12)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_13)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_14)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_15)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_16)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_17)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_18)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_19)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_20)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_21)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_22)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_23)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_24)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_25)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_26)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_27)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_28)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_29)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_30)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_31)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_32)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_33)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_34)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_35)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_36)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_37)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_38)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_39)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_40)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_41)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_42)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_43)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_44)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_45)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_46)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_47)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_48)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_49)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_50)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_51)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_52)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_53)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_54)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_55)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_56)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_57)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_58)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_59)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_60)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_61)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_62)] = RD_WR_REG, + [WSA883X_REG(WSA883X_EMEM_63)] = RD_WR_REG, +}; diff --git a/asoc/codecs/wsa883x/wsa883x-temp-sensor.c b/asoc/codecs/wsa883x/wsa883x-temp-sensor.c new file mode 100644 index 000000000000..a328c758215a --- /dev/null +++ b/asoc/codecs/wsa883x/wsa883x-temp-sensor.c @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (c) 2015, 2017-2019 The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "wsa883x-temp-sensor.h" + +#define T1_TEMP -10 +#define T2_TEMP 150 +#define LOW_TEMP_THRESHOLD 5 +#define HIGH_TEMP_THRESHOLD 45 +#define TEMP_INVALID 0xFFFF +#define WSA883X_TEMP_RETRY 3 +/* + * wsa883x_get_temp - get wsa temperature + * @thermal: thermal zone device + * @temp: temperature value + * + * Get the temperature of wsa883x. + * + * Return: 0 on success or negative error code on failure. + */ +int wsa883x_get_temp(struct thermal_zone_device *thermal, + int *temp) +{ + struct wsa883x_tz_priv *pdata; + struct snd_soc_component *component; + struct wsa_temp_register reg; + int dmeas, d1, d2; + int ret = 0; + int temp_val; + int t1 = T1_TEMP; + int t2 = T2_TEMP; + u8 retry = WSA883X_TEMP_RETRY; + + if (!thermal) + return -EINVAL; + + if (thermal->devdata) { + pdata = thermal->devdata; + if (pdata->component) { + component = pdata->component; + } else { + pr_err("%s: codec is NULL\n", __func__); + return -EINVAL; + } + } else { + pr_err("%s: pdata is NULL\n", __func__); + return -EINVAL; + } + if (atomic_cmpxchg(&pdata->is_suspend_spk, 1, 0)) { + /* + * get_temp query happens as part of POST_PM_SUSPEND + * from thermal core. To avoid calls to slimbus + * as part of this thermal query, return default temp + * and reset the suspend flag. + */ + if (!pdata->t0_init) { + if (temp) + *temp = pdata->curr_temp; + return 0; + } + } + +temp_retry: + if (pdata->wsa_temp_reg_read) { + ret = pdata->wsa_temp_reg_read(component, ®); + if (ret) { + pr_err("%s: temp read failed: %d, current temp: %d\n", + __func__, ret, pdata->curr_temp); + if (temp) + *temp = pdata->curr_temp; + return 0; + } + } else { + pr_err("%s: wsa_temp_reg_read is NULL\n", __func__); + return -EINVAL; + } + /* + * Temperature register values are expected to be in the + * following range. + * d1_msb = 68 - 92 and d1_lsb = 0, 64, 128, 192 + * d2_msb = 185 -218 and d2_lsb = 0, 64, 128, 192 + */ + if ((reg.d1_msb < 68 || reg.d1_msb > 92) || + (!(reg.d1_lsb == 0 || reg.d1_lsb == 64 || reg.d1_lsb == 128 || + reg.d1_lsb == 192)) || + (reg.d2_msb < 185 || reg.d2_msb > 218) || + (!(reg.d2_lsb == 0 || reg.d2_lsb == 64 || reg.d2_lsb == 128 || + reg.d2_lsb == 192))) { + printk_ratelimited("%s: Temperature registers[%d %d %d %d] are out of range\n", + __func__, reg.d1_msb, reg.d1_lsb, reg.d2_msb, + reg.d2_lsb); + } + dmeas = ((reg.dmeas_msb << 0x8) | reg.dmeas_lsb) >> 0x6; + d1 = ((reg.d1_msb << 0x8) | reg.d1_lsb) >> 0x6; + d2 = ((reg.d2_msb << 0x8) | reg.d2_lsb) >> 0x6; + + if (d1 == d2) + temp_val = TEMP_INVALID; + else + temp_val = t1 + (((dmeas - d1) * (t2 - t1))/(d2 - d1)); + + if (temp_val <= LOW_TEMP_THRESHOLD || + temp_val >= HIGH_TEMP_THRESHOLD) { + pr_debug("%s: T0: %d is out of range[%d, %d]\n", __func__, + temp_val, LOW_TEMP_THRESHOLD, HIGH_TEMP_THRESHOLD); + if (retry--) { + msleep(20); + goto temp_retry; + } + } + pdata->curr_temp = temp_val; + + if (temp) + *temp = temp_val; + pr_debug("%s: t0 measured: %d dmeas = %d, d1 = %d, d2 = %d\n", + __func__, temp_val, dmeas, d1, d2); + return ret; +} +EXPORT_SYMBOL(wsa883x_get_temp); + +static struct thermal_zone_device_ops wsa883x_thermal_ops = { + .get_temp = wsa883x_get_temp, +}; + + +static int wsa883x_pm_notify(struct notifier_block *nb, + unsigned long mode, void *_unused) +{ + struct wsa883x_tz_priv *pdata = + container_of(nb, struct wsa883x_tz_priv, pm_nb); + + switch (mode) { + case PM_SUSPEND_PREPARE: + atomic_set(&pdata->is_suspend_spk, 1); + break; + default: + break; + } + return 0; +} + +int wsa883x_init_thermal(struct wsa883x_tz_priv *tz_pdata) +{ + struct thermal_zone_device *tz_dev; + + if (tz_pdata == NULL) { + pr_err("%s: thermal pdata is NULL\n", __func__); + return -EINVAL; + } + /* Register with the thermal zone */ + tz_dev = thermal_zone_device_register(tz_pdata->name, + 0, 0, tz_pdata, + &wsa883x_thermal_ops, NULL, 0, 0); + if (IS_ERR(tz_dev)) { + pr_err("%s: thermal device register failed.\n", __func__); + return -EINVAL; + } + tz_pdata->tz_dev = tz_dev; + tz_pdata->pm_nb.notifier_call = wsa883x_pm_notify; + register_pm_notifier(&tz_pdata->pm_nb); + atomic_set(&tz_pdata->is_suspend_spk, 0); + + return 0; +} +EXPORT_SYMBOL(wsa883x_init_thermal); + +void wsa883x_deinit_thermal(struct thermal_zone_device *tz_dev) +{ + struct wsa883x_tz_priv *pdata; + + if (tz_dev && tz_dev->devdata) { + pdata = tz_dev->devdata; + if (pdata) + unregister_pm_notifier(&pdata->pm_nb); + } + if (tz_dev) + thermal_zone_device_unregister(tz_dev); +} +EXPORT_SYMBOL(wsa883x_deinit_thermal); diff --git a/asoc/codecs/wsa883x/wsa883x-temp-sensor.h b/asoc/codecs/wsa883x/wsa883x-temp-sensor.h new file mode 100644 index 000000000000..5a8c38747b6a --- /dev/null +++ b/asoc/codecs/wsa883x/wsa883x-temp-sensor.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2015, 2018-2019, The Linux Foundation. All rights reserved. + */ +#ifndef WSA883X_TEMP_SENSOR_H +#define WSA883X_TEMP_SENSOR_H + +#include +#include + +struct wsa_temp_register { + u8 d1_msb; + u8 d1_lsb; + u8 d2_msb; + u8 d2_lsb; + u8 dmeas_msb; + u8 dmeas_lsb; +}; +typedef int32_t (*wsa_temp_register_read)(struct snd_soc_component *component, + struct wsa_temp_register *wsa_temp_reg); +struct wsa883x_tz_priv { + struct thermal_zone_device *tz_dev; + struct snd_soc_component *component; + struct wsa_temp_register *wsa_temp_reg; + char name[80]; + wsa_temp_register_read wsa_temp_reg_read; + struct notifier_block pm_nb; + atomic_t is_suspend_spk; + int t0_init; + int curr_temp; +}; + +int wsa883x_get_temp(struct thermal_zone_device *tz_dev, int *temp); +int wsa883x_init_thermal(struct wsa883x_tz_priv *tz_pdata); +void wsa883x_deinit_thermal(struct thermal_zone_device *tz_dev); +#endif diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c new file mode 100644 index 000000000000..988196e23798 --- /dev/null +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -0,0 +1,1176 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wsa883x.h" +#include "wsa883x-temp-sensor.h" +#include "internal.h" + +#ifdef CONFIG_DEBUG_FS +static int codec_debug_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static int get_parameters(char *buf, u32 *param1, int num_of_par) +{ + char *token; + int base, cnt; + + token = strsep(&buf, " "); + for (cnt = 0; cnt < num_of_par; cnt++) { + if (token) { + if ((token[1] == 'x') || (token[1] == 'X')) + base = 16; + else + base = 10; + + if (kstrtou32(token, base, ¶m1[cnt]) != 0) + return -EINVAL; + + token = strsep(&buf, " "); + } else { + return -EINVAL; + } + } + return 0; +} + +static bool is_swr_slave_reg_readable(int reg) +{ + int ret = true; + + if (((reg > 0x46) && (reg < 0x4A)) || + ((reg > 0x4A) && (reg < 0x50)) || + ((reg > 0x55) && (reg < 0xD0)) || + ((reg > 0xD0) && (reg < 0xE0)) || + ((reg > 0xE0) && (reg < 0xF0)) || + ((reg > 0xF0) && (reg < 0x100)) || + ((reg > 0x105) && (reg < 0x120)) || + ((reg > 0x205) && (reg < 0x220)) || + ((reg > 0x305) && (reg < 0x320)) || + ((reg > 0x405) && (reg < 0x420)) || + ((reg > 0x128) && (reg < 0x130)) || + ((reg > 0x228) && (reg < 0x230)) || + ((reg > 0x328) && (reg < 0x330)) || + ((reg > 0x428) && (reg < 0x430)) || + ((reg > 0x138) && (reg < 0x205)) || + ((reg > 0x238) && (reg < 0x305)) || + ((reg > 0x338) && (reg < 0x405)) || + ((reg > 0x405) && (reg < 0xF00)) || + ((reg > 0xF05) && (reg < 0xF20)) || + ((reg > 0xF25) && (reg < 0xF30)) || + ((reg > 0xF35) && (reg < 0x2000))) + ret = false; + + return ret; +} + +static ssize_t swr_slave_reg_show(struct swr_device *pdev, char __user *ubuf, + size_t count, loff_t *ppos) +{ + int i, reg_val, len; + ssize_t total = 0; + char tmp_buf[SWR_SLV_MAX_BUF_LEN]; + + if (!ubuf || !ppos) + return 0; + + for (i = (((int) *ppos/BYTES_PER_LINE) + SWR_SLV_START_REG_ADDR); + i <= SWR_SLV_MAX_REG_ADDR; i++) { + if (!is_swr_slave_reg_readable(i)) + continue; + swr_read(pdev, pdev->dev_num, i, ®_val, 1); + len = snprintf(tmp_buf, 25, "0x%.3x: 0x%.2x\n", i, + (reg_val & 0xFF)); + if ((total + len) >= count - 1) + break; + if (copy_to_user((ubuf + total), tmp_buf, len)) { + pr_err("%s: fail to copy reg dump\n", __func__); + total = -EFAULT; + goto copy_err; + } + total += len; + *ppos += len; + } + +copy_err: + *ppos = SWR_SLV_MAX_REG_ADDR * BYTES_PER_LINE; + return total; +} + +static ssize_t codec_debug_dump(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct swr_device *pdev; + + if (!count || !file || !ppos || !ubuf) + return -EINVAL; + + pdev = file->private_data; + if (!pdev) + return -EINVAL; + + if (*ppos < 0) + return -EINVAL; + + return swr_slave_reg_show(pdev, ubuf, count, ppos); +} + +static ssize_t codec_debug_read(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + char lbuf[SWR_SLV_RD_BUF_LEN]; + struct swr_device *pdev = NULL; + struct wsa883x_priv *wsa883x = NULL; + + if (!count || !file || !ppos || !ubuf) + return -EINVAL; + + pdev = file->private_data; + if (!pdev) + return -EINVAL; + + wsa883x = swr_get_dev_data(pdev); + if (!wsa883x) + return -EINVAL; + + if (*ppos < 0) + return -EINVAL; + + snprintf(lbuf, sizeof(lbuf), "0x%x\n", + (wsa883x->read_data & 0xFF)); + + return simple_read_from_buffer(ubuf, count, ppos, lbuf, + strnlen(lbuf, 7)); +} + +static ssize_t codec_debug_peek_write(struct file *file, + const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char lbuf[SWR_SLV_WR_BUF_LEN]; + int rc = 0; + u32 param[5]; + struct swr_device *pdev = NULL; + struct wsa883x_priv *wsa883x = NULL; + + if (!cnt || !file || !ppos || !ubuf) + return -EINVAL; + + pdev = file->private_data; + if (!pdev) + return -EINVAL; + + wsa883x = swr_get_dev_data(pdev); + if (!wsa883x) + return -EINVAL; + + if (*ppos < 0) + return -EINVAL; + + if (cnt > sizeof(lbuf) - 1) + return -EINVAL; + + rc = copy_from_user(lbuf, ubuf, cnt); + if (rc) + return -EFAULT; + + lbuf[cnt] = '\0'; + rc = get_parameters(lbuf, param, 1); + if (!((param[0] <= SWR_SLV_MAX_REG_ADDR) && (rc == 0))) + return -EINVAL; + swr_read(pdev, pdev->dev_num, param[0], &wsa883x->read_data, 1); + if (rc == 0) + rc = cnt; + else + pr_err("%s: rc = %d\n", __func__, rc); + + return rc; +} + +static ssize_t codec_debug_write(struct file *file, + const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char lbuf[SWR_SLV_WR_BUF_LEN]; + int rc = 0; + u32 param[5]; + struct swr_device *pdev; + + if (!file || !ppos || !ubuf) + return -EINVAL; + + pdev = file->private_data; + if (!pdev) + return -EINVAL; + + if (cnt > sizeof(lbuf) - 1) + return -EINVAL; + + rc = copy_from_user(lbuf, ubuf, cnt); + if (rc) + return -EFAULT; + + lbuf[cnt] = '\0'; + rc = get_parameters(lbuf, param, 2); + if (!((param[0] <= SWR_SLV_MAX_REG_ADDR) && + (param[1] <= 0xFF) && (rc == 0))) + return -EINVAL; + swr_write(pdev, pdev->dev_num, param[0], ¶m[1]); + if (rc == 0) + rc = cnt; + else + pr_err("%s: rc = %d\n", __func__, rc); + + return rc; +} + +static const struct file_operations codec_debug_write_ops = { + .open = codec_debug_open, + .write = codec_debug_write, +}; + +static const struct file_operations codec_debug_read_ops = { + .open = codec_debug_open, + .read = codec_debug_read, + .write = codec_debug_peek_write, +}; + +static const struct file_operations codec_debug_dump_ops = { + .open = codec_debug_open, + .read = codec_debug_dump, +}; +#endif + +static const char * const wsa_pa_gain_text[] = { + "G_18_DB", "G_16P5_DB", "G_15_DB", "G_13P5_DB", "G_12_DB", "G_10P5_DB", + "G_9_DB", "G_7P5_DB", "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB", + "G_0_DB" +}; + +static const struct soc_enum wsa_pa_gain_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa_pa_gain_text), wsa_pa_gain_text); + +static int wsa_pa_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wsa883x->pa_gain; + + dev_dbg(component->dev, "%s: PA gain = 0x%x\n", __func__, + wsa883x->pa_gain); + + return 0; +} + +static int wsa_pa_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + wsa883x->pa_gain = ucontrol->value.integer.value[0]; + + return 0; +} + +static int wsa883x_get_mute(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wsa883x->pa_mute; + + return 0; +} + +static int wsa883x_set_mute(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + int value = ucontrol->value.integer.value[0]; + + dev_dbg(component->dev, "%s: mute current %d, new %d\n", + __func__, wsa883x->pa_mute, value); + + wsa883x->pa_mute = value; + + return 0; +} + +static int wsa883x_get_t0_init(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + struct wsa883x_tz_priv *pdata = &wsa883x->tz_pdata; + + ucontrol->value.integer.value[0] = pdata->t0_init; + dev_dbg(component->dev, "%s: t0 init %d\n", __func__, pdata->t0_init); + + return 0; +} + +static int wsa883x_set_t0_init(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + struct wsa883x_tz_priv *pdata = &wsa883x->tz_pdata; + + pdata->t0_init = ucontrol->value.integer.value[0]; + dev_dbg(component->dev, "%s: t0 init %d\n", __func__, pdata->t0_init); + + return 0; +} + +static const struct snd_kcontrol_new wsa_snd_controls[] = { + SOC_ENUM_EXT("WSA PA Gain", wsa_pa_gain_enum, + wsa_pa_gain_get, wsa_pa_gain_put), + SOC_SINGLE_EXT("WSA PA Mute", SND_SOC_NOPM, 0, 1, 0, + wsa883x_get_mute, wsa883x_set_mute), + SOC_SINGLE_EXT("WSA T0 Init", SND_SOC_NOPM, 0, 1, 0, + wsa883x_get_t0_init, wsa883x_set_t0_init), +}; + +static ssize_t wsa883x_codec_version_read(struct snd_info_entry *entry, + void *file_private_data, struct file *file, + char __user *buf, size_t count, loff_t pos) +{ + struct wsa883x_priv *wsa883x; + char buffer[WSA883X_VERSION_ENTRY_SIZE]; + int len = 0; + + wsa883x = (struct wsa883x_priv *) entry->private_data; + if (!wsa883x) { + pr_err("%s: wsa883x priv is null\n", __func__); + return -EINVAL; + } + + len = snprintf(buffer, sizeof(buffer), "WSA883X-SOUNDWIRE_1_0\n"); + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops wsa883x_codec_info_ops = { + .read = wsa883x_codec_version_read, +}; + +/* + * wsa883x_codec_info_create_codec_entry - creates wsa883x module + * @codec_root: The parent directory + * @component: Codec instance + * + * Creates wsa883x module and version entry under the given + * parent directory. + * + * Return: 0 on success or negative error code on failure. + */ +int wsa883x_codec_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_component *component) +{ + struct snd_info_entry *version_entry; + struct wsa883x_priv *wsa883x; + struct snd_soc_card *card; + char name[80]; + + if (!codec_root || !component) + return -EINVAL; + + wsa883x = snd_soc_component_get_drvdata(component); + card = component->card; + snprintf(name, sizeof(name), "%s.%x", "wsa883x", + (u32)wsa883x->swr_slave->addr); + + wsa883x->entry = snd_info_create_subdir(codec_root->module, + (const char *)name, + codec_root); + if (!wsa883x->entry) { + dev_dbg(component->dev, "%s: failed to create wsa883x entry\n", + __func__); + return -ENOMEM; + } + + version_entry = snd_info_create_card_entry(card->snd_card, + "version", + wsa883x->entry); + if (!version_entry) { + dev_dbg(component->dev, "%s: failed to create wsa883x version entry\n", + __func__); + return -ENOMEM; + } + + version_entry->private_data = wsa883x; + version_entry->size = WSA883X_VERSION_ENTRY_SIZE; + version_entry->content = SNDRV_INFO_CONTENT_DATA; + version_entry->c.ops = &wsa883x_codec_info_ops; + + if (snd_info_register(version_entry) < 0) { + snd_info_free_entry(version_entry); + return -ENOMEM; + } + wsa883x->version_entry = version_entry; + + return 0; +} +EXPORT_SYMBOL(wsa883x_codec_info_create_codec_entry); + +static void wsa883x_regcache_sync(struct wsa883x_priv *wsa883x) +{ + mutex_lock(&wsa883x->res_lock); + if (wsa883x->state != WSA883X_DEV_READY) { + regcache_mark_dirty(wsa883x->regmap); + regcache_sync(wsa883x->regmap); + wsa883x->state = WSA883X_DEV_READY; + } + mutex_unlock(&wsa883x->res_lock); +} + +static int wsa883x_visense_txfe_ctrl(struct snd_soc_component *component, + bool enable, u8 isense1_gain, + u8 isense2_gain, u8 vsense_gain) +{ + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, + "%s: enable:%d, isense1 gain: %d, isense2 gain: %d, vsense_gain %d\n", + __func__, enable, isense1_gain, isense2_gain, vsense_gain); + + return 0; +} + +static int wsa883x_visense_adc_ctrl(struct snd_soc_component *component, + bool enable) +{ + + dev_dbg(component->dev, "%s: enable:%d\n", __func__, enable); + + return 0; +} + +static void wsa883x_bandgap_ctrl(struct snd_soc_component *component, + bool enable) +{ + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: enable:%d, bg_count:%d\n", __func__, + enable, wsa883x->bg_cnt); + mutex_lock(&wsa883x->bg_lock); + if (enable) { + ++wsa883x->bg_cnt; + if (wsa883x->bg_cnt == 1) { + snd_soc_component_update_bits(component, + WSA883X_OP_CTL, + 0x08, 0x08); + } + } else { + --wsa883x->bg_cnt; + if (wsa883x->bg_cnt <= 0) { + WARN_ON(wsa883x->bg_cnt < 0); + wsa883x->bg_cnt = 0; + snd_soc_component_update_bits(component, + WSA883X_OP_CTL, 0x08, 0x00); + } + } + mutex_unlock(&wsa883x->bg_lock); +} + +static void wsa883x_clk_ctrl(struct snd_soc_component *component, bool enable) +{ + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: enable:%d, clk_count:%d\n", __func__, + enable, wsa883x->clk_cnt); + mutex_lock(&wsa883x->res_lock); + if (enable) { + ++wsa883x->clk_cnt; + if (wsa883x->clk_cnt == 1) { + snd_soc_component_write(component, + WSA883X_CDC_CLK_CTL, 0x01); + snd_soc_component_write(component, + WSA883X_CLK_CTL, 0x01); + } + } else { + --wsa883x->clk_cnt; + if (wsa883x->clk_cnt <= 0) { + WARN_ON(wsa883x->clk_cnt < 0); + wsa883x->clk_cnt = 0; + snd_soc_component_write(component, + WSA883X_CDC_CLK_CTL, 0x00); + snd_soc_component_write(component, + WSA883X_CLK_CTL, 0x00); + } + } + mutex_unlock(&wsa883x->res_lock); +} + +static int wsa883x_get_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wsa883x->comp_enable; + return 0; +} + +static int wsa883x_set_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + int value = ucontrol->value.integer.value[0]; + + dev_dbg(component->dev, "%s: Compander enable current %d, new %d\n", + __func__, wsa883x->comp_enable, value); + wsa883x->comp_enable = value; + return 0; +} + +static int wsa883x_get_visense(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wsa883x->visense_enable; + return 0; +} + +static int wsa883x_set_visense(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + int value = ucontrol->value.integer.value[0]; + + dev_dbg(component->dev, "%s: VIsense enable current %d, new %d\n", + __func__, wsa883x->visense_enable, value); + wsa883x->visense_enable = value; + return 0; +} + +static const struct snd_kcontrol_new wsa883x_snd_controls[] = { + SOC_SINGLE_EXT("COMP Switch", SND_SOC_NOPM, 0, 1, 0, + wsa883x_get_compander, wsa883x_set_compander), + + SOC_SINGLE_EXT("VISENSE Switch", SND_SOC_NOPM, 0, 1, 0, + wsa883x_get_visense, wsa883x_set_visense), +}; + +static const struct snd_kcontrol_new swr_dac_port[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static int wsa883x_set_port(struct snd_soc_component *component, int port_idx, + u8 *port_id, u8 *num_ch, u8 *ch_mask, u32 *ch_rate, + u8 *port_type) +{ + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + *port_id = wsa883x->port[port_idx].port_id; + *num_ch = wsa883x->port[port_idx].num_ch; + *ch_mask = wsa883x->port[port_idx].ch_mask; + *ch_rate = wsa883x->port[port_idx].ch_rate; + *port_type = wsa883x->port[port_idx].port_type; + return 0; +} + +static int wsa883x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + u8 port_id[WSA883X_MAX_SWR_PORTS]; + u8 num_ch[WSA883X_MAX_SWR_PORTS]; + u8 ch_mask[WSA883X_MAX_SWR_PORTS]; + u32 ch_rate[WSA883X_MAX_SWR_PORTS]; + u8 port_type[WSA883X_MAX_SWR_PORTS]; + u8 num_port = 0; + + dev_dbg(component->dev, "%s: event %d name %s\n", __func__, + event, w->name); + if (wsa883x == NULL) + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wsa883x_set_port(component, SWR_DAC_PORT, + &port_id[num_port], &num_ch[num_port], + &ch_mask[num_port], &ch_rate[num_port], + &port_type[num_port]); + ++num_port; + + if (wsa883x->comp_enable) { + wsa883x_set_port(component, SWR_COMP_PORT, + &port_id[num_port], &num_ch[num_port], + &ch_mask[num_port], &ch_rate[num_port], + &port_type[num_port]); + ++num_port; + } + if (wsa883x->visense_enable) { + wsa883x_set_port(component, SWR_VISENSE_PORT, + &port_id[num_port], &num_ch[num_port], + &ch_mask[num_port], &ch_rate[num_port], + &port_type[num_port]); + ++num_port; + } + swr_connect_port(wsa883x->swr_slave, &port_id[0], num_port, + &ch_mask[0], &ch_rate[0], &num_ch[0], + &port_type[0]); + break; + case SND_SOC_DAPM_POST_PMU: + break; + case SND_SOC_DAPM_PRE_PMD: + break; + case SND_SOC_DAPM_POST_PMD: + wsa883x_set_port(component, SWR_DAC_PORT, + &port_id[num_port], &num_ch[num_port], + &ch_mask[num_port], &ch_rate[num_port], + &port_type[num_port]); + ++num_port; + + if (wsa883x->comp_enable) { + wsa883x_set_port(component, SWR_COMP_PORT, + &port_id[num_port], &num_ch[num_port], + &ch_mask[num_port], &ch_rate[num_port], + &port_type[num_port]); + ++num_port; + } + if (wsa883x->visense_enable) { + wsa883x_set_port(component, SWR_VISENSE_PORT, + &port_id[num_port], &num_ch[num_port], + &ch_mask[num_port], &ch_rate[num_port], + &port_type[num_port]); + ++num_port; + } + swr_disconnect_port(wsa883x->swr_slave, &port_id[0], num_port, + &ch_mask[0], &port_type[0]); + break; + default: + break; + } + return 0; +} + +static int wsa883x_rdac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: %s event: %d visense %d\n", __func__, + w->name, event, wsa883x->visense_enable); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mutex_lock(&wsa883x->temp_lock); + wsa883x_resource_acquire(component, ENABLE); + mutex_unlock(&wsa883x->temp_lock); + break; + case SND_SOC_DAPM_POST_PMD: + swr_slvdev_datapath_control(wsa883x->swr_slave, + wsa883x->swr_slave->dev_num, + false); + mutex_lock(&wsa883x->temp_lock); + wsa883x_resource_acquire(component, DISABLE); + mutex_unlock(&wsa883x->temp_lock); + break; + } + return 0; +} + +static int wsa883x_ramp_pa_gain(struct snd_soc_component *component, + int min_gain, int max_gain, int udelay) +{ + int val; + + for (val = min_gain; max_gain <= val; val--) { + snd_soc_component_update_bits(component, WSA883X_SPKR_DRV_GAIN, + 0xF0, val << 4); + /* + * 1ms delay is needed for every step change in gain as per + * HW requirement. + */ + usleep_range(udelay, udelay + 10); + } + return 0; +} + +static int wsa883x_spkr_pa_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + int min_gain, max_gain; + + dev_dbg(component->dev, "%s: %s %d\n", __func__, w->name, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + swr_slvdev_datapath_control(wsa883x->swr_slave, + wsa883x->swr_slave->dev_num, + true); + /* Set register mode if compander is not enabled */ + if (!wsa883x->comp_enable) + snd_soc_component_update_bits(component, + WSA883X_SPKR_DRV_GAIN, + 0x08, 0x08); + else + snd_soc_component_update_bits(component, + WSA883X_SPKR_DRV_GAIN, + 0x08, 0x00); + + break; + case SND_SOC_DAPM_POST_PMU: + if (!wsa883x->comp_enable) { + max_gain = wsa883x->pa_gain; + /* + * Gain has to set incrementally in 4 steps + * as per HW sequence + */ + if (max_gain > G_4P5DB) + min_gain = G_0DB; + else + min_gain = max_gain + 3; + /* + * 1ms delay is needed before change in gain + * as per HW requirement. + */ + usleep_range(1000, 1010); + wsa883x_ramp_pa_gain(component, min_gain, max_gain, + 1000); + } + if (wsa883x->visense_enable) { + wsa883x_visense_txfe_ctrl(component, ENABLE, + 0x00, 0x03, 0x01); + wsa883x_visense_adc_ctrl(component, ENABLE); + } + /* Force remove group */ + swr_remove_from_group(wsa883x->swr_slave, + wsa883x->swr_slave->dev_num); + break; + case SND_SOC_DAPM_POST_PMD: + if (wsa883x->visense_enable) { + wsa883x_visense_adc_ctrl(component, DISABLE); + wsa883x_visense_txfe_ctrl(component, DISABLE, + 0x00, 0x01, 0x01); + } + break; + } + return 0; +} + +static const struct snd_soc_dapm_widget wsa883x_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("IN"), + + SND_SOC_DAPM_MIXER_E("SWR DAC_Port", SND_SOC_NOPM, 0, 0, swr_dac_port, + ARRAY_SIZE(swr_dac_port), wsa883x_enable_swr_dac_port, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_DAC_E("RDAC", NULL, WSA883X_SPKR_DAC_CTL, 7, 0, + wsa883x_rdac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_PGA_E("SPKR PGA", WSA883X_SPKR_DRV_EN, 7, 0, NULL, 0, + wsa883x_spkr_pa_event, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_OUTPUT("SPKR"), +}; + +static const struct snd_soc_dapm_route wsa883x_audio_map[] = { + {"SWR DAC_Port", "Switch", "IN"}, + {"RDAC", NULL, "SWR DAC_Port"}, + {"SPKR PGA", NULL, "RDAC"}, + {"SPKR", NULL, "SPKR PGA"}, +}; + +int wsa883x_set_channel_map(struct snd_soc_component *component, u8 *port, + u8 num_port, unsigned int *ch_mask, + unsigned int *ch_rate, u8 *port_type) +{ + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + int i; + + if (!port || !ch_mask || !ch_rate || + (num_port > WSA883X_MAX_SWR_PORTS)) { + dev_err(component->dev, + "%s: Invalid port=%pK, ch_mask=%pK, ch_rate=%pK\n", + __func__, port, ch_mask, ch_rate); + return -EINVAL; + } + for (i = 0; i < num_port; i++) { + wsa883x->port[i].port_id = port[i]; + wsa883x->port[i].ch_mask = ch_mask[i]; + wsa883x->port[i].ch_rate = ch_rate[i]; + wsa883x->port[i].num_ch = __sw_hweight8(ch_mask[i]); + if (port_type) + wsa883x->port[i].port_type = port_type[i]; + } + + return 0; +} +EXPORT_SYMBOL(wsa883x_set_channel_map); + +static void wsa883x_init(struct snd_soc_component *component) +{ + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + if (!wsa883x) + return; + +} + +static int32_t wsa883x_resource_acquire(struct snd_soc_component *component, + bool enable) +{ + wsa883x_clk_ctrl(component, enable); + wsa883x_bandgap_ctrl(component, enable); + return 0; +} + +static int32_t wsa883x_temp_reg_read(struct snd_soc_component *component, + struct wsa_temp_register *wsa_temp_reg) +{ + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + struct swr_device *dev; + u8 retry = WSA883X_NUM_RETRY; + u8 devnum = 0; + + if (!wsa883x) { + dev_err(component->dev, "%s: wsa883x is NULL\n", __func__); + return -EINVAL; + } + dev = wsa883x->swr_slave; + if (dev && (wsa883x->state == WSA883X_DEV_DOWN)) { + while (swr_get_logical_dev_num(dev, dev->addr, &devnum) && + retry--) { + /* Retry after 1 msec delay */ + usleep_range(1000, 1100); + } + if (retry == 0) { + dev_err(component->dev, + "%s get devnum %d for dev addr %lx failed\n", + __func__, devnum, dev->addr); + return -EINVAL; + } + } + wsa883x_regcache_sync(wsa883x); + mutex_lock(&wsa883x->temp_lock); + wsa883x_resource_acquire(component, ENABLE); + + snd_soc_component_update_bits(component, WSA883X_TADC_VALUE_CTL, + 0x01, 0x00); + wsa_temp_reg->dmeas_msb = snd_soc_component_read32( + component, WSA883X_TEMP_MSB); + wsa_temp_reg->dmeas_lsb = snd_soc_component_read32( + component, WSA883X_TEMP_LSB); + snd_soc_component_update_bits(component, WSA883X_TADC_VALUE_CTL, + 0x01, 0x01); + wsa_temp_reg->d1_msb = snd_soc_component_read32( + component, WSA883X_OTP_REG_1); + wsa_temp_reg->d1_lsb = snd_soc_component_read32( + component, WSA883X_OTP_REG_2); + wsa_temp_reg->d2_msb = snd_soc_component_read32( + component, WSA883X_OTP_REG_3); + wsa_temp_reg->d2_lsb = snd_soc_component_read32( + component, WSA883X_OTP_REG_4); + + wsa883x_resource_acquire(component, DISABLE); + mutex_unlock(&wsa883x->temp_lock); + + return 0; +} + +static int wsa883x_codec_probe(struct snd_soc_component *component) +{ + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + struct swr_device *dev; + + if (!wsa883x) + return -EINVAL; + snd_soc_component_init_regmap(component, wsa883x->regmap); + + dev = wsa883x->swr_slave; + wsa883x->component = component; + mutex_init(&wsa883x->bg_lock); + wsa883x_init(component); + snprintf(wsa883x->tz_pdata.name, sizeof(wsa883x->tz_pdata.name), + "%s.%x", "wsatz", (u8)dev->addr); + wsa883x->bg_cnt = 0; + wsa883x->clk_cnt = 0; + wsa883x->tz_pdata.component = component; + wsa883x->tz_pdata.wsa_temp_reg_read = wsa883x_temp_reg_read; + wsa883x_init_thermal(&wsa883x->tz_pdata); + snd_soc_add_component_controls(component, wsa_snd_controls, + ARRAY_SIZE(wsa_snd_controls)); + return 0; +} + +static void wsa883x_codec_remove(struct snd_soc_component *component) +{ + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + if (wsa883x->tz_pdata.tz_dev) + wsa883x_deinit_thermal(wsa883x->tz_pdata.tz_dev); + mutex_destroy(&wsa883x->bg_lock); + + return; +} + +static const struct snd_soc_component_driver soc_codec_dev_wsa883x = { + .name = DRV_NAME, + .probe = wsa883x_codec_probe, + .remove = wsa883x_codec_remove, + .controls = wsa883x_snd_controls, + .num_controls = ARRAY_SIZE(wsa883x_snd_controls), + .dapm_widgets = wsa883x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wsa883x_dapm_widgets), + .dapm_routes = wsa883x_audio_map, + .num_dapm_routes = ARRAY_SIZE(wsa883x_audio_map), +}; + +static int wsa883x_gpio_ctrl(struct wsa883x_priv *wsa883x, bool enable) +{ + int ret = 0; + + if (enable) + ret = msm_cdc_pinctrl_select_active_state( + wsa883x->wsa_rst_np); + else + ret = msm_cdc_pinctrl_select_sleep_state( + wsa883x->wsa_rst_np); + if (ret != 0) + dev_err(wsa883x->dev, + "%s: Failed to turn state %d; ret=%d\n", + __func__, enable, ret); + + return ret; +} + +static int wsa883x_swr_probe(struct swr_device *pdev) +{ + int ret = 0; + struct wsa883x_priv *wsa883x; + u8 devnum = 0; + bool pin_state_current = false; + + wsa883x = devm_kzalloc(&pdev->dev, sizeof(struct wsa883x_priv), + GFP_KERNEL); + if (!wsa883x) + return -ENOMEM; + + wsa883x->wsa_rst_np = of_parse_phandle(pdev->dev.of_node, + "qcom,spkr-sd-n-node", 0); + if (!wsa883x->wsa_rst_np) { + dev_dbg(&pdev->dev, "%s: pinctrl not defined\n", __func__); + goto err; + } + swr_set_dev_data(pdev, wsa883x); + wsa883x->swr_slave = pdev; + pin_state_current = msm_cdc_pinctrl_get_state(wsa883x->wsa_rst_np); + wsa883x_gpio_ctrl(wsa883x, true); + /* + * Add 5msec delay to provide sufficient time for + * soundwire auto enumeration of slave devices as + * as per HW requirement. + */ + usleep_range(5000, 5010); + ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum); + if (ret) { + dev_dbg(&pdev->dev, + "%s get devnum %d for dev addr %lx failed\n", + __func__, devnum, pdev->addr); + goto dev_err; + } + pdev->dev_num = devnum; + + wsa883x->regmap = devm_regmap_init_swr(pdev, + &wsa883x_regmap_config); + if (IS_ERR(wsa883x->regmap)) { + ret = PTR_ERR(wsa883x->regmap); + dev_err(&pdev->dev, "%s: regmap_init failed %d\n", + __func__, ret); + goto dev_err; + } + + ret = snd_soc_register_component(&pdev->dev, &soc_codec_dev_wsa883x, + NULL, 0); + if (ret) { + dev_err(&pdev->dev, "%s: Codec registration failed\n", + __func__); + goto dev_err; + } + mutex_init(&wsa883x->res_lock); + mutex_init(&wsa883x->temp_lock); + wsa883x->state = WSA883X_DEV_UP; + +#ifdef CONFIG_DEBUG_FS + if (!wcd938x->debugfs_dent) { + wcd938x->debugfs_dent = debugfs_create_dir( + dev_name(&pdev->dev), 0); + if (!IS_ERR(wcd938x->debugfs_dent)) { + wcd938x->debugfs_peek = + debugfs_create_file("swrslave_peek", + S_IFREG | 0444, + wcd938x->debugfs_dent, + (void *) pdev, + &codec_debug_read_ops); + + wcd938x->debugfs_poke = + debugfs_create_file("swrslave_poke", + S_IFREG | 0444, + wcd938x->debugfs_dent, + (void *) pdev, + &codec_debug_write_ops); + + wcd938x->debugfs_reg_dump = + debugfs_create_file( + "swrslave_reg_dump", + S_IFREG | 0444, + wcd938x->debugfs_dent, + (void *) pdev, + &codec_debug_dump_ops); + } +} +#endif + + return 0; + +dev_err: + if (pin_state_current == false) + wsa883x_gpio_ctrl(wsa883x, false); + swr_remove_device(pdev); +err: + return ret; +} + +static int wsa883x_swr_remove(struct swr_device *pdev) +{ + struct wsa883x_priv *wsa883x; + + wsa883x = swr_get_dev_data(pdev); + if (!wsa883x) { + dev_err(&pdev->dev, "%s: wsa883x is NULL\n", __func__); + return -EINVAL; + } +#ifdef CONFIG_DEBUG_FS + debugfs_remove_recursive(wsa883x->debugfs_dent); + wsa883x->debugfs_dent = NULL; +#endif + mutex_destroy(&wsa883x->res_lock); + mutex_destroy(&wsa883x->temp_lock); + snd_soc_unregister_component(&pdev->dev); + if (wsa883x->pd_gpio) + gpio_free(wsa883x->pd_gpio); + swr_set_dev_data(pdev, NULL); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int wsa883x_swr_suspend(struct device *dev) +{ + dev_dbg(dev, "%s: system suspend\n", __func__); + return 0; +} + +static int wsa883x_swr_resume(struct device *dev) +{ + struct wsa883x_priv *wsa883x = swr_get_dev_data(to_swr_device(dev)); + + if (!wsa883x) { + dev_err(dev, "%s: wsa883x private data is NULL\n", __func__); + return -EINVAL; + } + dev_dbg(dev, "%s: system resume\n", __func__); + return 0; +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops wsa883x_swr_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(wsa883x_swr_suspend, wsa883x_swr_resume) +}; + +static const struct swr_device_id wsa883x_swr_id[] = { + {"wsa883x", 0}, + {} +}; + +static const struct of_device_id wsa883x_swr_dt_match[] = { + { + .compatible = "qcom,wsa883x", + }, + {} +}; + +static struct swr_driver wsa883x_swr_driver = { + .driver = { + .name = "wsa883x", + .owner = THIS_MODULE, + .pm = &wsa883x_swr_pm_ops, + .of_match_table = wsa883x_swr_dt_match, + }, + .probe = wsa883x_swr_probe, + .remove = wsa883x_swr_remove, + .id_table = wsa883x_swr_id, +}; + +static int __init wsa883x_swr_init(void) +{ + return swr_driver_register(&wsa883x_swr_driver); +} + +static void __exit wsa883x_swr_exit(void) +{ + swr_driver_unregister(&wsa883x_swr_driver); +} + +module_init(wsa883x_swr_init); +module_exit(wsa883x_swr_exit); + +MODULE_DESCRIPTION("WSA883x codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/wsa883x/wsa883x.h b/asoc/codecs/wsa883x/wsa883x.h new file mode 100644 index 000000000000..e080134eb016 --- /dev/null +++ b/asoc/codecs/wsa883x/wsa883x.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef _WSA883X_H +#define _WSA883X_H + +#include +#include +#include +#include "wsa883x-registers.h" + +#define WSA883X_MAX_SWR_PORTS 4 + +#if IS_ENABLED(CONFIG_SND_SOC_WSA883X) +int wsa883x_set_channel_map(struct snd_soc_component *component, + u8 *port, u8 num_port, unsigned int *ch_mask, + unsigned int *ch_rate, u8 *port_type); + + +int wsa883x_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_component *component); +#else +static int wsa883x_set_channel_map(struct snd_soc_component *component, + u8 *port, u8 num_port, unsigned int *ch_mask, + unsigned int *ch_rate, u8 *port_type) +{ + return 0; +} + +static int wsa883x_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_component *component) +{ + return 0; +} + +#endif + +#endif /* _WSA883X_H */ -- GitLab From f8be8bdcf1758d2e53792039b504702a8ee6ae33 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 1 Oct 2019 00:54:57 +0530 Subject: [PATCH 1243/1645] asoc: codecs: Make compander write coefficients as volatile Make HPHL and HPHR compander write coefficients as volatile registers in order to avoid cache operations on these registers to fix audio glitch issues in headset playback. Change-Id: If5a2019debdda3c50cc5cf1135dff2ad0e5a49a2 Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/bolero-cdc-regmap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/bolero-cdc-regmap.c b/asoc/codecs/bolero/bolero-cdc-regmap.c index a0ecd83565c5..037f9aa96878 100644 --- a/asoc/codecs/bolero/bolero-cdc-regmap.c +++ b/asoc/codecs/bolero/bolero-cdc-regmap.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #include @@ -809,9 +809,13 @@ static bool bolero_is_volatile_register(struct device *dev, case BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB: case BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FIFO: case BOLERO_CDC_RX_TOP_HPHL_COMP_RD_LSB: + case BOLERO_CDC_RX_TOP_HPHL_COMP_WR_LSB: case BOLERO_CDC_RX_TOP_HPHL_COMP_RD_MSB: + case BOLERO_CDC_RX_TOP_HPHL_COMP_WR_MSB: case BOLERO_CDC_RX_TOP_HPHR_COMP_RD_LSB: + case BOLERO_CDC_RX_TOP_HPHR_COMP_WR_LSB: case BOLERO_CDC_RX_TOP_HPHR_COMP_RD_MSB: + case BOLERO_CDC_RX_TOP_HPHR_COMP_WR_MSB: case BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG2: case BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG2: case BOLERO_CDC_RX_BCL_VBAT_GAIN_MON_VAL: -- GitLab From cfc65e8257edd4691865cb440d706a47936f052a Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 3 Oct 2019 22:34:23 +0530 Subject: [PATCH 1244/1645] asoc: codecs: Vote for codec core and NPL clocks before regcache_sync Vote for codec core and NPL clocks before regcache_sync to avoid unclocked access of bolero registers. Unvote once the regcache sync is done. Change-Id: Iae45f487113c55318f33cd1950e2d6b64bcd945a Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/bolero-cdc.c | 4 +++ asoc/codecs/bolero/bolero-clk-rsc.c | 43 +++++++++++++++++++++++++++++ asoc/codecs/bolero/bolero-clk-rsc.h | 6 ++++ 3 files changed, 53 insertions(+) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 76c9d4064276..7591f05af197 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -661,7 +661,11 @@ static int bolero_ssr_enable(struct device *dev, void *data) priv->dev_up = true; mutex_unlock(&priv->clk_lock); regcache_mark_dirty(priv->regmap); + bolero_clk_rsc_enable_all_clocks(priv->clk_dev, true); regcache_sync(priv->regmap); + /* Add a 100usec sleep to ensure last register write is done */ + usleep_range(100,110); + bolero_clk_rsc_enable_all_clocks(priv->clk_dev, false); /* call ssr event for supported macros */ for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { if (!priv->macro_params[macro_idx].event_handler) diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c index 4940f67a8a38..b80a2671253e 100644 --- a/asoc/codecs/bolero/bolero-clk-rsc.c +++ b/asoc/codecs/bolero/bolero-clk-rsc.c @@ -137,6 +137,49 @@ int bolero_rsc_clk_reset(struct device *dev, int clk_id) } EXPORT_SYMBOL(bolero_rsc_clk_reset); +void bolero_clk_rsc_enable_all_clocks(struct device *dev, bool enable) +{ + struct device *clk_dev = NULL; + struct bolero_clk_rsc *priv = NULL; + int i = 0; + + if (!dev) { + pr_err("%s: dev is null %d\n", __func__); + return; + } + + clk_dev = bolero_get_rsc_clk_device_ptr(dev->parent); + if (!clk_dev) { + pr_err("%s: Invalid rsc clk device\n", __func__); + return; + } + + priv = dev_get_drvdata(clk_dev); + if (!priv) { + pr_err("%s: Invalid rsc clk private data\n", __func__); + return; + } + mutex_lock(&priv->rsc_clk_lock); + for (i = 0; i < MAX_CLK - NPL_CLK_OFFSET; i++) { + if (enable) { + if (priv->clk[i]) + clk_prepare_enable(priv->clk[i]); + if (priv->clk[i + NPL_CLK_OFFSET]) + clk_prepare_enable( + priv->clk[i + NPL_CLK_OFFSET]); + } else { + if (priv->clk[i + NPL_CLK_OFFSET]) + clk_disable_unprepare( + priv->clk[i + NPL_CLK_OFFSET]); + if (priv->clk[i]) + clk_disable_unprepare(priv->clk[i]); + } + } + mutex_unlock(&priv->rsc_clk_lock); + return; +} +EXPORT_SYMBOL(bolero_clk_rsc_enable_all_clocks); + static int bolero_clk_rsc_mux0_clk_request(struct bolero_clk_rsc *priv, int clk_id, bool enable) diff --git a/asoc/codecs/bolero/bolero-clk-rsc.h b/asoc/codecs/bolero/bolero-clk-rsc.h index fc3c02f602f3..cc8ee395ba4d 100644 --- a/asoc/codecs/bolero/bolero-clk-rsc.h +++ b/asoc/codecs/bolero/bolero-clk-rsc.h @@ -19,6 +19,7 @@ int bolero_clk_rsc_request_clock(struct device *dev, int clk_id_req, bool enable); int bolero_rsc_clk_reset(struct device *dev, int clk_id); +void bolero_clk_rsc_enable_all_clocks(struct device *dev, bool enable); #else static inline void bolero_clk_rsc_fs_gen_request(struct device *dev, bool enable) @@ -42,5 +43,10 @@ static inline int bolero_rsc_clk_reset(struct device *dev, int clk_id) { return 0; } +static inline void bolero_clk_rsc_enable_all_clocks(struct device *dev, + bool enable) +{ + return; +} #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CLK_RSC_H */ -- GitLab From 57e66c02514aa82cfe8c4a36b19e40d062e55504 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Sat, 12 Oct 2019 23:31:17 +0530 Subject: [PATCH 1245/1645] asoc: wcd937x: Fix compile error in wcd937x codec driver Update codec to component param for 4.19 kernel compatible. Change-Id: Ia08283de4b01b45a6cd96c7f488f55bb0d4a5a53 Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd937x/wcd937x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 7a618c519192..31768efa04a4 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1309,7 +1309,7 @@ static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w, /* Enable BCS for Headset mic */ if (w->shift == 1 && !(snd_soc_component_read32(component, WCD937X_TX_NEW_TX_CH2_SEL) & 0x80)) { - wcd937x_tx_connect_port(codec, MBHC, true); + wcd937x_tx_connect_port(component, MBHC, true); set_bit(AMIC2_BCS_ENABLE, &wcd937x->status_mask); } wcd937x_tx_connect_port(component, ADC1 + (w->shift), true); @@ -1318,7 +1318,7 @@ static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w, wcd937x_tx_connect_port(component, ADC1 + (w->shift), false); if (w->shift == 1 && test_bit(AMIC2_BCS_ENABLE, &wcd937x->status_mask)) { - wcd937x_tx_connect_port(codec, MBHC, false); + wcd937x_tx_connect_port(component, MBHC, false); clear_bit(AMIC2_BCS_ENABLE, &wcd937x->status_mask); } snd_soc_component_update_bits(component, -- GitLab From 00f60bae1e675a12c4179203001d4a70b99fb87a Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 4 Oct 2019 09:37:07 +0530 Subject: [PATCH 1246/1645] bengal: enable compile of required modules Update compile of required modules for bengal target. Change-Id: If4d512b7270cc811a05524caac5292234a0ac437 Signed-off-by: Laxminath Kasam --- Android.mk | 4 ++-- asoc/Android.mk | 5 +++++ asoc/Kbuild | 12 +++++++++-- asoc/codecs/Android.mk | 18 ++++++++++++++++ asoc/codecs/Kbuild | 13 ++++++++++-- asoc/codecs/bolero/Android.mk | 6 ++++++ asoc/codecs/bolero/Kbuild | 4 ++-- asoc/codecs/wcd937x/Android.mk | 6 +++++- asoc/codecs/wcd937x/Kbuild | 5 +++++ asoc/codecs/wcd938x/Android.mk | 2 +- asoc/codecs/wcd938x/Kbuild | 5 ----- config/bengalauto.conf | 34 ++++++++++++++++++++++++++++++ config/bengalautoconf.h | 38 ++++++++++++++++++++++++++++++++++ dsp/Android.mk | 4 ++++ dsp/Kbuild | 4 ++-- dsp/codecs/Android.mk | 4 ++++ dsp/codecs/Kbuild | 4 ++-- ipc/Android.mk | 4 ++++ ipc/Kbuild | 4 ++-- soc/Android.mk | 8 +++++-- soc/Kbuild | 4 ++-- 21 files changed, 163 insertions(+), 25 deletions(-) create mode 100644 config/bengalauto.conf create mode 100644 config/bengalautoconf.h diff --git a/Android.mk b/Android.mk index feead0106a6c..cac738852a87 100644 --- a/Android.mk +++ b/Android.mk @@ -38,7 +38,7 @@ include $(MY_LOCAL_PATH)/asoc/codecs/aqt1000/Android.mk endif endif -ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) bengal),true) ifneq ($(TARGET_BOARD_AUTO),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/bolero/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/bolero/Android.mk @@ -47,7 +47,7 @@ include $(MY_LOCAL_PATH)/asoc/codecs/wcd937x/Android.mk endif endif -ifeq ($(call is-board-platform-in-list, kona lito bengal),true) +ifeq ($(call is-board-platform-in-list, kona lito),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/bolero/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/bolero/Android.mk $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd938x/Module.symvers) diff --git a/asoc/Android.mk b/asoc/Android.mk index 4431f887e0a3..4ce1fa77d4ab 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -36,6 +36,11 @@ TARGET := lito AUDIO_SELECT := CONFIG_SND_SOC_LITO=m endif +ifeq ($(call is-board-platform,bengal),true) +TARGET := bengal +AUDIO_SELECT := CONFIG_SND_SOC_BENGAL=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) diff --git a/asoc/Kbuild b/asoc/Kbuild index 9e455a99314a..137fd60f8841 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -51,9 +51,9 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_BENGAL), y) - include $(AUDIO_ROOT)/config/litoauto.conf + include $(AUDIO_ROOT)/config/bengalauto.conf export - INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) ifdef CONFIG_SND_SOC_SA8155 @@ -135,6 +135,11 @@ ifdef CONFIG_SND_SOC_LITO MACHINE_OBJS += kona.o endif +# for BENGAL sound card driver +ifdef CONFIG_SND_SOC_BENGAL + MACHINE_OBJS += bengal.o +endif + # for sa8155 sound card driver ifdef CONFIG_SND_SOC_SA8155 MACHINE_OBJS += sa8155.o @@ -244,6 +249,9 @@ machine_dlkm-y := $(MACHINE_OBJS) obj-$(CONFIG_SND_SOC_LITO) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) +obj-$(CONFIG_SND_SOC_BENGAL) += machine_dlkm.o +machine_dlkm-y := $(MACHINE_OBJS) + obj-$(CONFIG_SND_SOC_SA8155) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index fb00efb70163..da39e8c8139d 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -31,6 +31,10 @@ ifeq ($(call is-board-platform,lito),true) AUDIO_SELECT := CONFIG_SND_SOC_LITO=m endif +ifeq ($(call is-board-platform,bengal),true) +AUDIO_SELECT := CONFIG_SND_SOC_BENGAL=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) @@ -107,6 +111,7 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk endif ########################################################### +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), bengal)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wsa881x.ko LOCAL_MODULE_KBUILD_NAME := wsa881x_dlkm.ko @@ -114,6 +119,17 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk +endif +########################################################### +ifeq ($(call is-board-platform-in-list, bengal),true) +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_wsa881x_analog.ko +LOCAL_MODULE_KBUILD_NAME := wsa881x_analog_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +endif ########################################################### include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_mbhc.ko @@ -132,6 +148,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### +ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), bengal)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_hdmi.ko LOCAL_MODULE_KBUILD_NAME := hdmi_dlkm.ko @@ -139,6 +156,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk +endif ########################################################### endif # DLKM check diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index b8abfc4ca897..1ce059ec7012 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -51,9 +51,9 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_BENGAL), y) - include $(AUDIO_ROOT)/config/litoauto.conf + include $(AUDIO_ROOT)/config/bengalauto.conf export - INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf @@ -143,6 +143,12 @@ ifdef CONFIG_SND_SOC_WSA881X WSA881X_OBJS += wsa881x-temp-sensor.o endif +ifdef CONFIG_SND_SOC_WSA881X_ANALOG + WSA881X_ANALOG_OBJS += wsa881x-analog.o + WSA881X_ANALOG_OBJS += wsa881x-tables-analog.o + WSA881X_ANALOG_OBJS += wsa881x-regmap-analog.o + WSA881X_ANALOG_OBJS += wsa881x-temp-sensor.o +endif ifdef CONFIG_SND_SOC_MSM_STUB STUB_OBJS += msm_stub.o endif @@ -235,6 +241,9 @@ wcd9335_dlkm-y := $(WCD9335_OBJS) obj-$(CONFIG_SND_SOC_WSA881X) += wsa881x_dlkm.o wsa881x_dlkm-y := $(WSA881X_OBJS) +obj-$(CONFIG_SND_SOC_WSA881X_ANALOG) += wsa881x_analog_dlkm.o +wsa881x_analog_dlkm-y := $(WSA881X_ANALOG_OBJS) + obj-$(CONFIG_SND_SOC_MSM_STUB) += stub_dlkm.o stub_dlkm-y := $(STUB_OBJS) diff --git a/asoc/codecs/bolero/Android.mk b/asoc/codecs/bolero/Android.mk index 9d1274f8e6dc..5764412ed006 100644 --- a/asoc/codecs/bolero/Android.mk +++ b/asoc/codecs/bolero/Android.mk @@ -15,6 +15,10 @@ ifeq ($(call is-board-platform,lito),true) AUDIO_SELECT := CONFIG_SND_SOC_LITO=m endif +ifeq ($(call is-board-platform,bengal),true) +AUDIO_SELECT := CONFIG_SND_SOC_BENGAL=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona lito bengal),true) @@ -52,6 +56,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona lito),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wsa_macro.ko LOCAL_MODULE_KBUILD_NAME := wsa_macro_dlkm.ko @@ -59,6 +64,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk +endif ########################################################### include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_va_macro.ko diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild index e6517f8a6bd9..15e5dc576da3 100644 --- a/asoc/codecs/bolero/Kbuild +++ b/asoc/codecs/bolero/Kbuild @@ -36,9 +36,9 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_BENGAL), y) - include $(AUDIO_ROOT)/config/litoauto.conf + include $(AUDIO_ROOT)/config/bengalauto.conf export - INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf diff --git a/asoc/codecs/wcd937x/Android.mk b/asoc/codecs/wcd937x/Android.mk index cbd087733d06..4168dd1b1eef 100644 --- a/asoc/codecs/wcd937x/Android.mk +++ b/asoc/codecs/wcd937x/Android.mk @@ -7,9 +7,13 @@ ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif +ifeq ($(call is-board-platform,bengal),true) +AUDIO_SELECT := CONFIG_SND_SOC_BENGAL=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) bengal),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wcd937x/Kbuild b/asoc/codecs/wcd937x/Kbuild index b8db20277d70..e353e8a37d67 100644 --- a/asoc/codecs/wcd937x/Kbuild +++ b/asoc/codecs/wcd937x/Kbuild @@ -26,6 +26,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif + ifeq ($(CONFIG_ARCH_BENGAL), y) + include $(AUDIO_ROOT)/config/bengalauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h + endif endif # As per target team, build is done as follows: diff --git a/asoc/codecs/wcd938x/Android.mk b/asoc/codecs/wcd938x/Android.mk index 49aa2d43f5b3..96fb6f569701 100644 --- a/asoc/codecs/wcd938x/Android.mk +++ b/asoc/codecs/wcd938x/Android.mk @@ -13,7 +13,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,kona lito bengal),true) +ifeq ($(call is-board-platform-in-list,kona lito),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wcd938x/Kbuild b/asoc/codecs/wcd938x/Kbuild index 99d71953dff2..3dfe142bcfc2 100644 --- a/asoc/codecs/wcd938x/Kbuild +++ b/asoc/codecs/wcd938x/Kbuild @@ -23,11 +23,6 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif - ifeq ($(CONFIG_ARCH_BENGAL), y) - include $(AUDIO_ROOT)/config/litoauto.conf - export - INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h - endif endif diff --git a/config/bengalauto.conf b/config/bengalauto.conf new file mode 100644 index 000000000000..d6fdadd7a5f3 --- /dev/null +++ b/config/bengalauto.conf @@ -0,0 +1,34 @@ +CONFIG_PINCTRL_LPI=m +CONFIG_AUDIO_EXT_CLK=m +CONFIG_SND_SOC_WCD9XXX_V2=m +CONFIG_SND_SOC_WCD_MBHC=m +CONFIG_SND_SOC_WSA881X_ANALOG=m +CONFIG_WCD9XXX_CODEC_CORE_V2=m +CONFIG_MSM_CDC_PINCTRL=m +CONFIG_MSM_QDSP6V2_CODECS=m +CONFIG_MSM_ULTRASOUND=m +CONFIG_MSM_QDSP6_APRV2_RPMSG=m +CONFIG_MSM_ADSP_LOADER=m +CONFIG_REGMAP_SWR=m +CONFIG_MSM_QDSP6_SSR=m +CONFIG_MSM_QDSP6_PDR=m +CONFIG_MSM_QDSP6_NOTIFIER=m +CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +CONFIG_SOUNDWIRE=m +CONFIG_SOUNDWIRE_MSTR_CTRL=m +CONFIG_SND_SOC_QDSP6V2=m +CONFIG_SND_SOC_WCD_MBHC_ADC=m +CONFIG_QTI_PP=m +CONFIG_SND_HWDEP_ROUTING=m +CONFIG_SND_SOC_MSM_STUB=m +CONFIG_MSM_AVTIMER=m +CONFIG_SND_SOC_BOLERO=m +CONFIG_VA_MACRO=m +CONFIG_RX_MACRO=m +CONFIG_TX_MACRO=m +CONFIG_SND_SOC_WCD_IRQ=m +CONFIG_SND_SOC_WCD937X=m +CONFIG_SND_SOC_WCD937X_SLAVE=m +CONFIG_SND_SOC_BENGAL=m +CONFIG_SND_EVENT=m diff --git a/config/bengalautoconf.h b/config/bengalautoconf.h new file mode 100644 index 000000000000..90d3e3c52448 --- /dev/null +++ b/config/bengalautoconf.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#define CONFIG_PINCTRL_LPI 1 +#define CONFIG_AUDIO_EXT_CLK 1 +#define CONFIG_SND_SOC_WCD9XXX_V2 1 +#define CONFIG_SND_SOC_WCD_MBHC 1 +#define CONFIG_SND_SOC_WSA881X_ANALOG 1 +#define CONFIG_WCD9XXX_CODEC_CORE_V2 1 +#define CONFIG_MSM_CDC_PINCTRL 1 +#define CONFIG_MSM_QDSP6V2_CODECS 1 +#define CONFIG_MSM_ULTRASOUND 1 +#define CONFIG_MSM_QDSP6_APRV2_RPMSG 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_MSM_ADSP_LOADER 1 +#define CONFIG_REGMAP_SWR 1 +#define CONFIG_MSM_QDSP6_SSR 1 +#define CONFIG_MSM_QDSP6_PDR 1 +#define CONFIG_MSM_QDSP6_NOTIFIER 1 +#define CONFIG_SND_SOC_MSM_HOSTLESS_PCM 1 +#define CONFIG_SOUNDWIRE 1 +#define CONFIG_SOUNDWIRE_MSTR_CTRL 1 +#define CONFIG_SND_SOC_WCD_MBHC_ADC 1 +#define CONFIG_SND_SOC_QDSP6V2 1 +#define CONFIG_QTI_PP 1 +#define CONFIG_SND_HWDEP_ROUTING 1 +#define CONFIG_SND_SOC_MSM_STUB 1 +#define CONFIG_MSM_AVTIMER 1 +#define CONFIG_SND_SOC_BOLERO 1 +#define CONFIG_VA_MACRO 1 +#define CONFIG_RX_MACRO 1 +#define CONFIG_TX_MACRO 1 +#define CONFIG_SND_SOC_WCD_IRQ 1 +#define CONFIG_SND_SOC_WCD937X 1 +#define CONFIG_SND_SOC_WCD937X_SLAVE 1 +#define CONFIG_SND_SOC_BENGAL 1 +#define CONFIG_SND_EVENT 1 diff --git a/dsp/Android.mk b/dsp/Android.mk index df13d3d5d968..c5ab3ff51ab6 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -27,6 +27,10 @@ ifeq ($(call is-board-platform, lito),true) AUDIO_SELECT := CONFIG_SND_SOC_LITO=m endif +ifeq ($(call is-board-platform, bengal),true) +AUDIO_SELECT := CONFIG_SND_SOC_BENGAL=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) diff --git a/dsp/Kbuild b/dsp/Kbuild index 81f80940399b..006de44589f2 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -40,9 +40,9 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_BENGAL), y) - include $(AUDIO_ROOT)/config/litoauto.conf + include $(AUDIO_ROOT)/config/bengalauto.conf export - INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) ifdef CONFIG_SND_SOC_SA8155 diff --git a/dsp/codecs/Android.mk b/dsp/codecs/Android.mk index 3d122f614600..59a1603cb19e 100644 --- a/dsp/codecs/Android.mk +++ b/dsp/codecs/Android.mk @@ -19,6 +19,10 @@ ifeq ($(call is-board-platform,lito),true) AUDIO_SELECT := CONFIG_SND_SOC_LITO=m endif +ifeq ($(call is-board-platform,bengal),true) +AUDIO_SELECT := CONFIG_SND_SOC_BENGAL=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 3bdcd7d2a988..8709901de96b 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -34,9 +34,9 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_BENGAL), y) - include $(AUDIO_ROOT)/config/litoauto.conf + include $(AUDIO_ROOT)/config/bengalauto.conf export - INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf diff --git a/ipc/Android.mk b/ipc/Android.mk index 62d78d06e61b..3238a791e15e 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -27,6 +27,10 @@ ifeq ($(call is-board-platform,lito),true) AUDIO_SELECT := CONFIG_SND_SOC_LITO=m endif +ifeq ($(call is-board-platform,bengal),true) +AUDIO_SELECT := CONFIG_SND_SOC_BENGAL=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) diff --git a/ipc/Kbuild b/ipc/Kbuild index bb63b6f18689..bbea67396ed4 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -41,9 +41,9 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_BENGAL), y) - include $(AUDIO_ROOT)/config/litoauto.conf + include $(AUDIO_ROOT)/config/bengalauto.conf export - INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) ifdef CONFIG_SND_SOC_SA8155 diff --git a/soc/Android.mk b/soc/Android.mk index 21d3d0a0ac6b..9ed83d4d468e 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -27,6 +27,10 @@ ifeq ($(call is-board-platform,lito),true) AUDIO_SELECT := CONFIG_SND_SOC_LITO=m endif +ifeq ($(call is-board-platform,bengal),true) +AUDIO_SELECT := CONFIG_SND_SOC_BENGAL=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) @@ -56,7 +60,7 @@ KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) KBUILD_OPTIONS += $(AUDIO_SELECT) ########################################################### -ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona lito),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona lito bengal),true) ifneq ($(TARGET_BOARD_AUTO),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_lpi.ko @@ -98,7 +102,7 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk endif ########################################################### -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) kona lito sdmshrike),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) kona lito bengal sdmshrike),true) ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile)) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_snd_event.ko diff --git a/soc/Kbuild b/soc/Kbuild index 83bb243a5f81..9e32c429fa2b 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -35,9 +35,9 @@ ifeq ($(KERNEL_BUILD), 0) INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_BENGAL), y) - include $(AUDIO_ROOT)/config/litoauto.conf + include $(AUDIO_ROOT)/config/bengalauto.conf export - INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif ifeq ($(CONFIG_ARCH_SM6150), y) ifdef CONFIG_SND_SOC_SA6155 -- GitLab From 3d89d5356bc83ce74f9a68808e19c09cf6dd9290 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 9 Oct 2019 23:18:03 +0530 Subject: [PATCH 1247/1645] asoc: codecs: Add wakeup register update for chip register Update cdc-pinctrl driver to handle wakeup control provided in any spare chip register. Change-Id: Iaa413d4b78e0c9841e40d01d0b891da34ff79de2 Signed-off-by: Laxminath Kasam --- asoc/codecs/msm-cdc-pinctrl.c | 41 ++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/msm-cdc-pinctrl.c b/asoc/codecs/msm-cdc-pinctrl.c index a10a68173362..cb7a52bc301d 100644 --- a/asoc/codecs/msm-cdc-pinctrl.c +++ b/asoc/codecs/msm-cdc-pinctrl.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -23,8 +24,12 @@ struct msm_cdc_pinctrl_info { int gpio; bool state; u32 tlmm_gpio[MAX_GPIOS]; + char __iomem *chip_wakeup_register[MAX_GPIOS]; + u32 chip_wakeup_maskbit[MAX_GPIOS]; u32 count; + u32 wakeup_reg_count; bool wakeup_capable; + bool chip_wakeup_reg; }; static struct msm_cdc_pinctrl_info *msm_cdc_pinctrl_get_gpiodata( @@ -154,7 +159,7 @@ int msm_cdc_pinctrl_set_wakeup_capable(struct device_node *np, bool enable) { struct msm_cdc_pinctrl_info *gpio_data; int ret = 0; - u32 i = 0; + u32 i = 0, temp = 0; gpio_data = msm_cdc_pinctrl_get_gpiodata(np); if (!gpio_data) @@ -168,6 +173,18 @@ int msm_cdc_pinctrl_set_wakeup_capable(struct device_node *np, bool enable) goto exit; } } + if (gpio_data->chip_wakeup_reg) { + for (i = 0; i < gpio_data->wakeup_reg_count; i++) { + temp = ioread32(gpio_data->chip_wakeup_register[i]); + if (enable) + temp |= (1 << + gpio_data->chip_wakeup_maskbit[i]); + else + temp &= ~(1 << + gpio_data->chip_wakeup_maskbit[i]); + iowrite32(temp, gpio_data->chip_wakeup_register[i]); + } + } exit: return ret; } @@ -178,6 +195,7 @@ static int msm_cdc_pinctrl_probe(struct platform_device *pdev) int ret = 0; struct msm_cdc_pinctrl_info *gpio_data; u32 tlmm_gpio[MAX_GPIOS] = {0}; + u32 chip_wakeup_reg[MAX_GPIOS] = {0}; u32 i = 0; int count = 0; @@ -223,6 +241,27 @@ static int msm_cdc_pinctrl_probe(struct platform_device *pdev) } + count = of_property_count_u32_elems(pdev->dev.of_node, "qcom,chip-wakeup-reg"); + if (count <= 0) + goto cdc_tlmm_gpio; + if (!of_property_read_u32_array(pdev->dev.of_node, "qcom,chip-wakeup-reg", + chip_wakeup_reg, count)) { + if (of_property_read_u32_array(pdev->dev.of_node, + "qcom,chip-wakeup-maskbit", + gpio_data->chip_wakeup_maskbit, count)) { + dev_err(&pdev->dev, + "chip-wakeup-maskbit needed if chip-wakeup-reg is defined!\n"); + goto cdc_tlmm_gpio; + } + gpio_data->chip_wakeup_reg = true; + for (i = 0; i < count; i++) { + gpio_data->chip_wakeup_register[i] = + devm_ioremap(&pdev->dev, chip_wakeup_reg[i], 0x4); + } + gpio_data->wakeup_reg_count = count; + } + +cdc_tlmm_gpio: count = of_property_count_u32_elems(pdev->dev.of_node, "qcom,tlmm-gpio"); if (count <= 0) goto cdc_rst; -- GitLab From 2b4cbd8cdaa9442f859b7fa233e2a204e4a52c8d Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Tue, 30 Apr 2019 13:31:25 +0530 Subject: [PATCH 1248/1645] asoc: Add check for valid backend index Add check for valid backend index in msm_routing_put_port_chmap_mixer. Change-Id: I8cda2313a38aaacc5255b47321ccfd0d573e1cfb Signed-off-by: Rohit kumar --- asoc/msm-pcm-routing-v2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 0563d8c8016e..6e8d74b7e43b 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -28870,6 +28870,11 @@ static int msm_routing_put_port_chmap_mixer(struct snd_kcontrol *kcontrol, uint32_t be_idx = ucontrol->value.integer.value[0]; int i; + if (be_idx >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: Invalid Backend index %d\n", __func__, be_idx); + return -EINVAL; + } + for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) { channel_map[i] = (char)(ucontrol->value.integer.value[i + 1]); if (channel_map[i] > PCM_MAX_CHMAP_ID) { -- GitLab From 386df4e611f2d43747bfefa5e87caccabf85e9d1 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Fri, 11 Oct 2019 18:23:16 +0530 Subject: [PATCH 1249/1645] soc: soundwire: Add delay to over come race condition Switch b/w 44.1Khz to 48Khz and vice versa,mux switch on HPH path is unable to take place.Add sufficient delay to happen clock release. Change-Id: I80c40772c03bbbd3a57a4e6de270de4779f882a7 Signed-off-by: Prasad Kumpatla --- soc/swr-mstr-ctrl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index ead3c9baaa8c..e1ec36f0597a 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2847,6 +2847,12 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) __func__, swrm->state); else swrm_device_suspend(&pdev->dev); + /* + * add delay to ensure clk release happen + * if interrupt triggered for clk stop, + * wait for it to exit + */ + usleep_range(10000, 10500); } swrm->mclk_freq = *(int *)data; mutex_unlock(&swrm->mlock); -- GitLab From 2ef0c88aec9a0a2b5a9a9383174738d0409b5622 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Fri, 4 Oct 2019 15:11:10 +0530 Subject: [PATCH 1250/1645] asoc: msm-pcm: Add mutex lock to protect prvt data Add mutex lock to protect private data in _put() and _get() calls Change-Id: I92f5a6515b6d1c4ad650a7dcf22a0a231a84dd30 Signed-off-by: Prasad Kumpatla --- asoc/msm-pcm-loopback-v2.c | 18 +++++++--- asoc/msm-pcm-q6-noirq.c | 73 +++++++++++++++++++++++++++++++++++--- asoc/msm-pcm-q6-v2.c | 33 ++++++++++++++--- 3 files changed, 111 insertions(+), 13 deletions(-) diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index 70c94e43d5aa..19fe1903881f 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -132,7 +132,7 @@ static int msm_loopback_session_mute_put(struct snd_kcontrol *kcontrol, ret = -EINVAL; goto done; } - + mutex_lock(&loopback_session_lock); pr_debug("%s: mute=%d\n", __func__, mute); hfp_tx_mute = mute; for (n = 0; n < LOOPBACK_SESSION_MAX; n++) { @@ -145,6 +145,7 @@ static int msm_loopback_session_mute_put(struct snd_kcontrol *kcontrol, pr_err("%s: Send mute command failed rc=%d\n", __func__, ret); } + mutex_unlock(&loopback_session_lock); done: return ret; } @@ -347,6 +348,8 @@ static void stop_pcm(struct msm_pcm_loopback *pcm) if (pcm->audio_client == NULL) return; + + mutex_lock(&loopback_session_lock); q6asm_cmd(pcm->audio_client, CMD_CLOSE); if (pcm->playback_substream != NULL) { @@ -361,6 +364,7 @@ static void stop_pcm(struct msm_pcm_loopback *pcm) } q6asm_audio_client_free(pcm->audio_client); pcm->audio_client = NULL; + mutex_unlock(&loopback_session_lock); } static int msm_pcm_close(struct snd_pcm_substream *substream) @@ -537,13 +541,15 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, rc = -ENODEV; goto exit; } + mutex_lock(&loopback_session_lock); prtd = substream->runtime->private_data; if (!prtd) { rc = -ENODEV; + mutex_unlock(&loopback_session_lock); goto exit; } rc = pcm_loopback_set_volume(prtd, volume); - + mutex_unlock(&loopback_session_lock); exit: return rc; } @@ -563,13 +569,15 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, rc = -ENODEV; goto exit; } + mutex_lock(&loopback_session_lock); prtd = substream->runtime->private_data; if (!prtd) { rc = -ENODEV; + mutex_unlock(&loopback_session_lock); goto exit; } ucontrol->value.integer.value[0] = prtd->volume; - + mutex_unlock(&loopback_session_lock); exit: return rc; } @@ -855,11 +863,13 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, session_type, chmixer_pspd); + mutex_lock(&loopback_session_lock); if (chmixer_pspd->enable && substream->runtime) { prtd = substream->runtime->private_data; if (!prtd) { pr_err("%s find invalid prtd fail\n", __func__); ret = -EINVAL; + mutex_unlock(&loopback_session_lock); goto done; } @@ -872,7 +882,7 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, chmixer_pspd); } } - + mutex_unlock(&loopback_session_lock); if (reset_override_out_ch_map) chmixer_pspd->override_out_ch_map = false; if (reset_override_in_ch_map) diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index cd69d776d142..12a1f12b359b 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -630,6 +631,8 @@ static int msm_pcm_prepare(struct snd_pcm_substream *substream) static int msm_pcm_close(struct snd_pcm_substream *substream) { + struct msm_plat_data *pdata = NULL; + struct snd_soc_component *component = NULL; struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; struct msm_audio *prtd = runtime->private_data; @@ -638,6 +641,25 @@ static int msm_pcm_close(struct snd_pcm_substream *substream) int dir = 0; int ret = 0; + if (!soc_prtd) { + pr_debug("%s private_data not found\n", + __func__); + return 0; + } + + component = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + pdata = (struct msm_plat_data *) dev_get_drvdata(component->dev); + if (!pdata) { + pr_err("%s: pdata not found\n", __func__); + return -ENODEV; + } + + mutex_lock(&pdata->lock); if (ac) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) dir = IN; @@ -672,6 +694,7 @@ static int msm_pcm_close(struct snd_pcm_substream *substream) SNDRV_PCM_STREAM_CAPTURE); kfree(prtd); runtime->private_data = NULL; + mutex_unlock(&pdata->lock); return 0; } @@ -696,8 +719,11 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol); + struct msm_plat_data *pdata = NULL; struct snd_pcm_substream *substream = vol->pcm->streams[vol->stream].substream; + struct snd_soc_pcm_runtime *soc_prtd = NULL; + struct snd_soc_component *component = NULL; struct msm_audio *prtd; pr_debug("%s\n", __func__); @@ -705,13 +731,29 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, pr_err("%s substream not found\n", __func__); return -ENODEV; } - if (!substream->runtime) { - pr_debug("%s substream runtime not found\n", __func__); + soc_prtd = substream->private_data; + if (!substream->runtime || !soc_prtd) { + pr_debug("%s substream runtime or private_data not found\n", + __func__); return 0; } + + component = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + pdata = (struct msm_plat_data *) dev_get_drvdata(component->dev); + if (!pdata) { + pr_err("%s: pdata not found\n", __func__); + return -ENODEV; + } + mutex_lock(&pdata->lock); prtd = substream->runtime->private_data; if (prtd) ucontrol->value.integer.value[0] = prtd->volume; + mutex_unlock(&pdata->lock); return 0; } @@ -720,8 +762,11 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, { int rc = 0; struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol); + struct msm_plat_data *pdata = NULL; struct snd_pcm_substream *substream = vol->pcm->streams[vol->stream].substream; + struct snd_soc_pcm_runtime *soc_prtd = NULL; + struct snd_soc_component *component = NULL; struct msm_audio *prtd; int volume = ucontrol->value.integer.value[0]; @@ -730,15 +775,32 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, pr_err("%s substream not found\n", __func__); return -ENODEV; } - if (!substream->runtime) { - pr_err("%s substream runtime not found\n", __func__); + soc_prtd = substream->private_data; + if (!substream->runtime || !soc_prtd) { + pr_err("%s substream runtime or private_data not found\n", + __func__); return 0; } + + component = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + pdata = (struct msm_plat_data *) dev_get_drvdata(component->dev); + if (!pdata) { + pr_err("%s: pdata not found\n", __func__); + return -ENODEV; + } + + mutex_lock(&pdata->lock); prtd = substream->runtime->private_data; if (prtd) { rc = msm_pcm_set_volume(prtd, volume); prtd->volume = volume; } + mutex_unlock(&pdata->lock); return rc; } @@ -1338,6 +1400,8 @@ static int msm_pcm_probe(struct platform_device *pdev) pdata->perf_mode = perf_mode; + mutex_init(&pdata->lock); + dev_set_drvdata(&pdev->dev, pdata); dev_dbg(&pdev->dev, "%s: dev name %s\n", @@ -1359,6 +1423,7 @@ static int msm_pcm_remove(struct platform_device *pdev) dev_dbg(&pdev->dev, "Pull mode remove\n"); pdata = dev_get_drvdata(&pdev->dev); + mutex_destroy(&pdata->lock); devm_kfree(&pdev->dev, pdata); snd_soc_unregister_component(&pdev->dev); return 0; diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 7197ad634b5b..5626d49b4648 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1309,10 +1309,10 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, pdata = dev_get_drvdata(component->dev); if (!pdata) { pr_err("%s pdata is NULL\n", __func__); - ret = -ENODEV; - goto done; + return -ENODEV; } + mutex_lock(&pdata->lock); substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; if (!substream) { pr_err("%s substream not found\n", __func__); @@ -1339,7 +1339,6 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, goto done; } - mutex_lock(&pdata->lock); event_data = (struct msm_adsp_event_data *)ucontrol->value.bytes.data; if ((event_data->event_type < ADSP_STREAM_PP_EVENT) || (event_data->event_type >= ADSP_STREAM_EVENT_MAX)) { @@ -1514,8 +1513,11 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol); + struct msm_plat_data *pdata = NULL; struct snd_pcm_substream *substream = vol->pcm->streams[vol->stream].substream; + struct snd_soc_pcm_runtime *soc_prtd = NULL; + struct snd_soc_component *component = NULL; struct msm_audio *prtd; pr_debug("%s\n", __func__); @@ -1523,13 +1525,30 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, pr_err("%s substream not found\n", __func__); return -ENODEV; } - if (!substream->runtime) { - pr_debug("%s substream runtime not found\n", __func__); + soc_prtd = substream->private_data; + if (!substream->runtime || !soc_prtd) { + pr_debug("%s substream runtime or private_data not found\n", + __func__); return 0; } + + component = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + pdata = (struct msm_plat_data *) dev_get_drvdata(component->dev); + if (!pdata) { + pr_err("%s: pdata not found\n", __func__); + return -ENODEV; + } + + mutex_lock(&pdata->lock); prtd = substream->runtime->private_data; if (prtd) ucontrol->value.integer.value[0] = prtd->volume; + mutex_unlock(&pdata->lock); return 0; } @@ -1635,9 +1654,11 @@ static int msm_pcm_compress_ctl_get(struct snd_kcontrol *kcontrol, pr_debug("%s substream runtime not found\n", __func__); return 0; } + mutex_lock(&pdata->lock); prtd = substream->runtime->private_data; if (prtd) ucontrol->value.integer.value[0] = prtd->compress_enable; + mutex_unlock(&pdata->lock); return 0; } @@ -1665,12 +1686,14 @@ static int msm_pcm_compress_ctl_put(struct snd_kcontrol *kcontrol, pr_err("%s substream runtime not found\n", __func__); return 0; } + mutex_lock(&pdata->lock); prtd = substream->runtime->private_data; if (prtd) { pr_debug("%s: setting compress flag to 0x%x\n", __func__, compress); prtd->compress_enable = compress; } + mutex_unlock(&pdata->lock); return rc; } -- GitLab From a801ad8fd789077d77580f59c2504d98d5d92de2 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 15 Oct 2019 11:19:11 +0800 Subject: [PATCH 1251/1645] dsp: lsm: move lsm_common deregister out of mutex_lock When dispatch_event in apr and q6lsm_client_free in q6lsm are running concurrently, there may be deadlock between session_lock in lsm and svc->m_lock in apr for lsm_common. Move lsm_common mmap apr deregister out of mutex_lock to avoid deadlock. Change-Id: I7c96ba12834bd4a7c8e5ca1b78d798578678b251 Signed-off-by: Meng Wang --- dsp/q6lsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 9c5bf3d30dee..5c97dcf5a6e0 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -376,10 +376,10 @@ void q6lsm_client_free(struct lsm_client *client) return; } apr_deregister(client->apr); + q6lsm_mmap_apr_dereg(); client->mmap_apr = NULL; mutex_lock(&session_lock); q6lsm_session_free(client); - q6lsm_mmap_apr_dereg(); mutex_destroy(&client->cmd_lock); kfree(client); client = NULL; -- GitLab From d06525fa6853fe6faff8e4bf9b8355b80abccdd4 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 14 Oct 2019 23:14:12 +0530 Subject: [PATCH 1252/1645] ASoC: Fix audio distortion issue during headset record Audio is distorted during first 3 secs on headset record while doing device switch from dmic to headset mic. Disable BCS before slow insertion detection and enable it afterwards to resolve the issue. Change-Id: Ie5bc4b5292e5f69066760cab44d78989a74f13f4 Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/bolero-cdc.c | 6 ++++++ asoc/codecs/bolero/bolero-cdc.h | 3 ++- asoc/codecs/bolero/internal.h | 1 + asoc/codecs/bolero/tx-macro.c | 19 +++++++++++++++++-- asoc/codecs/wcd-mbhc-adc.c | 11 +++++++++++ asoc/codecs/wcd938x/internal.h | 4 ++++ asoc/codecs/wcd938x/wcd938x-mbhc.c | 10 ++++++++++ asoc/codecs/wcd938x/wcd938x.c | 15 +++++++++++++++ include/asoc/wcd-mbhc-v2.h | 2 ++ 9 files changed, 68 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index feb0082eea67..e56127ce4f8c 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -214,6 +214,12 @@ static int bolero_cdc_update_wcd_event(void *handle, u16 event, u32 data) priv->component, BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST, data); break; + case WCD_BOLERO_EVT_BCS_CLK_OFF: + if (priv->macro_params[TX_MACRO].event_handler) + priv->macro_params[TX_MACRO].event_handler( + priv->component, + BOLERO_MACRO_EVT_BCS_CLK_OFF, data); + break; default: dev_err(priv->dev, "%s: Invalid event %d trigger from wcd\n", __func__, event); diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index f104f88a34bb..fe02ad0d4ccf 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -40,7 +40,8 @@ enum { BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET, BOLERO_MACRO_EVT_CLK_RESET, BOLERO_MACRO_EVT_REG_WAKE_IRQ, - BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST + BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST, + BOLERO_MACRO_EVT_BCS_CLK_OFF }; struct macro_ops { diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index d3f689467446..ba89832e86b5 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -31,6 +31,7 @@ enum { WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */ WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */ WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST, + WCD_BOLERO_EVT_BCS_CLK_OFF, }; struct wcd_ctrl_platform_data { diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index ca88bfa1582a..73ce9d254aee 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -172,6 +172,8 @@ struct tx_macro_priv { int tx_clk_status; bool bcs_enable; int dec_mode[NUM_DECIMATORS]; + bool bcs_clk_en; + bool hs_slow_insert_complete; }; static bool tx_macro_get_data(struct snd_soc_component *component, @@ -387,6 +389,15 @@ static int tx_macro_event_handler(struct snd_soc_component *component, case BOLERO_MACRO_EVT_CLK_RESET: bolero_rsc_clk_reset(tx_dev, TX_CORE_CLK); break; + case BOLERO_MACRO_EVT_BCS_CLK_OFF: + if (tx_priv->bcs_clk_en) + snd_soc_component_update_bits(component, + BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, data << 6); + if (data) + tx_priv->hs_slow_insert_complete = true; + else + tx_priv->hs_slow_insert_complete = false; + break; } return 0; } @@ -902,8 +913,11 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, if (tx_priv->bcs_enable) { snd_soc_component_update_bits(component, dec_cfg_reg, 0x01, 0x01); - snd_soc_component_update_bits(component, - BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x40); + tx_priv->bcs_clk_en = true; + if (tx_priv->hs_slow_insert_complete) + snd_soc_component_update_bits(component, + BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, + 0x40); } break; case SND_SOC_DAPM_PRE_PMD: @@ -946,6 +960,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, 0x01, 0x00); snd_soc_component_update_bits(component, BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x00); + tx_priv->bcs_clk_en = false; } break; } diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index 4de19de467c1..9652d11dea33 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -689,6 +689,13 @@ static void wcd_correct_swch_plug(struct work_struct *work) } correct_plug_type: + /* + * Callback to disable BCS slow insertion detection + */ + if (plug_type == MBHC_PLUG_TYPE_HEADSET || + plug_type == MBHC_PLUG_TYPE_HEADPHONE) + mbhc->mbhc_cb->bcs_enable(mbhc, false); + timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS); while (!time_after(jiffies, timeout)) { if (mbhc->hs_detect_work_stop) { @@ -833,6 +840,10 @@ static void wcd_correct_swch_plug(struct work_struct *work) wrk_complete = false; } } + if ((plug_type == MBHC_PLUG_TYPE_HEADSET || + plug_type == MBHC_PLUG_TYPE_HEADPHONE)) + mbhc->mbhc_cb->bcs_enable(mbhc, true); + if (!wrk_complete) { /* * If plug_tye is headset, we might have already reported either diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index 098a60dac88c..46d61a00db9d 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -149,6 +149,7 @@ enum { WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */ WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */ WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST, + WCD_BOLERO_EVT_BCS_CLK_OFF, }; enum { @@ -182,6 +183,9 @@ enum { extern struct wcd938x_mbhc *wcd938x_soc_get_mbhc( struct snd_soc_component *component); +extern void wcd938x_disable_bcs_before_slow_insert( + struct snd_soc_component *component, + bool bcs_disable); extern int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component *component, int volt, int micb_num); extern int wcd938x_get_micb_vout_ctl_val(u32 micb_mv); diff --git a/asoc/codecs/wcd938x/wcd938x-mbhc.c b/asoc/codecs/wcd938x/wcd938x-mbhc.c index 27566ee85b53..0687de6475e1 100644 --- a/asoc/codecs/wcd938x/wcd938x-mbhc.c +++ b/asoc/codecs/wcd938x/wcd938x-mbhc.c @@ -803,6 +803,15 @@ static void wcd938x_mbhc_moisture_polling_ctrl(struct wcd_mbhc *mbhc, 0x04, (enable << 2)); } +static void wcd938x_mbhc_bcs_enable(struct wcd_mbhc *mbhc, + bool bcs_enable) +{ + if (bcs_enable) + wcd938x_disable_bcs_before_slow_insert(mbhc->component, false); + else + wcd938x_disable_bcs_before_slow_insert(mbhc->component, true); +} + static const struct wcd_mbhc_cb mbhc_cb = { .request_irq = wcd938x_mbhc_request_irq, .irq_control = wcd938x_mbhc_irq_control, @@ -827,6 +836,7 @@ static const struct wcd_mbhc_cb mbhc_cb = { .mbhc_get_moisture_status = wcd938x_mbhc_get_moisture_status, .mbhc_moisture_polling_ctrl = wcd938x_mbhc_moisture_polling_ctrl, .mbhc_moisture_detect_en = wcd938x_mbhc_moisture_detect_en, + .bcs_enable = wcd938x_mbhc_bcs_enable, }; static int wcd938x_get_hph_type(struct snd_kcontrol *kcontrol, diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 04954d9f9d75..0355ea6f345b 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1523,6 +1523,21 @@ static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w, return 0; } +void wcd938x_disable_bcs_before_slow_insert(struct snd_soc_component *component, + bool bcs_disable) +{ + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + if (wcd938x->update_wcd_event) { + if (bcs_disable) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_BCS_CLK_OFF, 0); + else + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_BCS_CLK_OFF, 1); + } +} + int wcd938x_tx_channel_config(struct snd_soc_component *component, int channel, int mode) { diff --git a/include/asoc/wcd-mbhc-v2.h b/include/asoc/wcd-mbhc-v2.h index 1f9d64e3ba23..f3ee72824380 100644 --- a/include/asoc/wcd-mbhc-v2.h +++ b/include/asoc/wcd-mbhc-v2.h @@ -451,6 +451,8 @@ struct wcd_mbhc_register { }; struct wcd_mbhc_cb { + void (*bcs_enable) + (struct wcd_mbhc *mbhc, bool bcs_enable); int (*enable_mb_source)(struct wcd_mbhc *mbhc, bool turn_on); void (*trim_btn_reg)(struct snd_soc_component *component); void (*compute_impedance)(struct wcd_mbhc *mbhc, -- GitLab From f3437da295347c4e2c8f1b3fd7373889ee798c94 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 15 Oct 2019 11:28:42 -0700 Subject: [PATCH 1253/1645] asoc: msm-dai: Add senary mi2s format control Add control for configuring senary mi2s format. Change-Id: Id885ca991b6752cc6568f156add9107f7c894dda Signed-off-by: Karthikeyan Mani --- asoc/msm-dai-q6-v2.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index 1b15444b2e7f..61e01e2001a9 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -5014,6 +5014,9 @@ static const struct snd_kcontrol_new mi2s_config_controls[] = { SOC_ENUM_EXT("QUIN MI2S RX Format", mi2s_config_enum[0], msm_dai_q6_mi2s_format_get, msm_dai_q6_mi2s_format_put), + SOC_ENUM_EXT("SENARY MI2S RX Format", mi2s_config_enum[0], + msm_dai_q6_mi2s_format_get, + msm_dai_q6_mi2s_format_put), SOC_ENUM_EXT("PRI MI2S TX Format", mi2s_config_enum[0], msm_dai_q6_mi2s_format_get, msm_dai_q6_mi2s_format_put), @@ -5068,6 +5071,8 @@ static int msm_dai_q6_dai_mi2s_probe(struct snd_soc_dai *dai) ctrl = &mi2s_config_controls[3]; if (dai->id == MSM_QUIN_MI2S) ctrl = &mi2s_config_controls[4]; + if (dai->id == MSM_SENARY_MI2S) + ctrl = &mi2s_config_controls[5]; } if (ctrl) { @@ -5084,19 +5089,19 @@ static int msm_dai_q6_dai_mi2s_probe(struct snd_soc_dai *dai) ctrl = NULL; if (mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.channel_mode) { if (dai->id == MSM_PRIM_MI2S) - ctrl = &mi2s_config_controls[5]; - if (dai->id == MSM_SEC_MI2S) ctrl = &mi2s_config_controls[6]; - if (dai->id == MSM_TERT_MI2S) + if (dai->id == MSM_SEC_MI2S) ctrl = &mi2s_config_controls[7]; - if (dai->id == MSM_QUAT_MI2S) + if (dai->id == MSM_TERT_MI2S) ctrl = &mi2s_config_controls[8]; - if (dai->id == MSM_QUIN_MI2S) + if (dai->id == MSM_QUAT_MI2S) ctrl = &mi2s_config_controls[9]; - if (dai->id == MSM_SENARY_MI2S) + if (dai->id == MSM_QUIN_MI2S) ctrl = &mi2s_config_controls[10]; - if (dai->id == MSM_INT5_MI2S) + if (dai->id == MSM_SENARY_MI2S) ctrl = &mi2s_config_controls[11]; + if (dai->id == MSM_INT5_MI2S) + ctrl = &mi2s_config_controls[12]; } if (ctrl) { -- GitLab From 2b85d8e050c3c9e39f4efe9be04b1161f9351af0 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 16 Oct 2019 11:18:49 +0530 Subject: [PATCH 1254/1645] asoc: wsa881x-analog: Defer wsa probe until mclk node available Update wsa analog driver to defer probe until mclk node is available. Change-Id: I8c1e9dc8fe014ebd9845cf8e9fc759106bd3ffff Signed-off-by: Laxminath Kasam --- asoc/codecs/wsa881x-analog.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/asoc/codecs/wsa881x-analog.c b/asoc/codecs/wsa881x-analog.c index 23ab5c9b55cc..c6b40669b343 100644 --- a/asoc/codecs/wsa881x-analog.c +++ b/asoc/codecs/wsa881x-analog.c @@ -1340,7 +1340,7 @@ static int wsa881x_i2c_probe(struct i2c_client *client, client->addr == WSA881X_I2C_SPK1_SLAVE1_ADDR) && (pdata->status == WSA881X_STATUS_PROBING)) { wsa881x_probing_count++; - return ret; + return -EPROBE_DEFER; } if (pdata->status == WSA881X_STATUS_I2C) { @@ -1396,6 +1396,15 @@ static int wsa881x_i2c_probe(struct i2c_client *client, ret = -EINVAL; goto err; } + wsa_mclk = devm_clk_get(&client->dev, "wsa_mclk"); + if (IS_ERR(wsa_mclk)) { + ret = PTR_ERR(wsa_mclk); + dev_dbg(&client->dev, "%s: clk get %s failed %d\n", + __func__, "wsa_mclk", ret); + wsa_mclk = NULL; + goto err; + } + pdata->wsa_mclk = wsa_mclk; dev_set_drvdata(&client->dev, client); pdata->regmap[WSA881X_DIGITAL_SLAVE] = @@ -1410,15 +1419,6 @@ static int wsa881x_i2c_probe(struct i2c_client *client, __func__, ret); goto err; } - wsa_mclk = devm_clk_get(&client->dev, "wsa_mclk"); - if (IS_ERR(wsa_mclk)) { - ret = PTR_ERR(wsa_mclk); - dev_dbg(&client->dev, "%s: clk get %s failed %d\n", - __func__, "wsa_mclk", ret); - wsa_mclk = NULL; - ret = 0; - } - pdata->wsa_mclk = wsa_mclk; /* bus reset sequence */ ret = wsa881x_reset(pdata, true); @@ -1459,7 +1459,7 @@ static int wsa881x_i2c_probe(struct i2c_client *client, err1: wsa881x_reset(pdata, false); err: - return 0; + return ret; } static int wsa881x_i2c_remove(struct i2c_client *client) -- GitLab From 117ebd09329ed8dfd9cfea6f8c8308af6a3f0cd1 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 9 Oct 2019 17:43:20 +0800 Subject: [PATCH 1255/1645] soc: swr-mstr: remove soundwire state check in interrupt handler when triggering SSR during speaker playback and insert headset, headset insertion/removal IRQ don't reach soundwire master side. Remove soundwire state check in interrupt handler to resolve headset detection issue. Change-Id: If6ff9aaaab9513f713d6106913dfccbc0e75e385 Signed-off-by: Meng Wang --- soc/swr-mstr-ctrl.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 599644f966c3..7ec72de51edf 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1607,12 +1607,6 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) struct swr_device *swr_dev; struct swr_master *mstr = &swrm->master; - if (!swrm->dev_up || swrm->state == SWR_MSTR_SSR) { - complete(&swrm->broadcast); - dev_dbg(swrm->dev, "%s swrm is not up\n", __func__); - return IRQ_NONE; - } - if (unlikely(swrm_lock_sleep(swrm) == false)) { dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__); return IRQ_NONE; -- GitLab From 2b0c995899a8967e90596e11dfbe1dc0b91ce047 Mon Sep 17 00:00:00 2001 From: Vikram Panduranga Date: Mon, 14 Oct 2019 12:44:25 -0700 Subject: [PATCH 1256/1645] asoc: msm-pcm: move null ptr check after lock Null pointer for runtime is checked before acquiring the lock. By the time, it acquires lock and tries to access private data runtime may be removed which can lead to null ptr dereference. Change-Id: I86ca89bd7dbd765c040bab2a292f62c2d3164140 Signed-off-by: Vikram Panduranga --- asoc/msm-pcm-q6-v2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 5626d49b4648..60e84cb7dd2d 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1797,11 +1797,11 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol, } } - if (!substream->runtime || !rtd) + if (!rtd) return 0; mutex_lock(&pdata->lock); - prtd = substream->runtime->private_data; + prtd = substream->runtime ? substream->runtime->private_data : NULL; if (prtd) { prtd->set_channel_map = true; for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) @@ -1864,11 +1864,11 @@ static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol, memset(ucontrol->value.integer.value, 0, sizeof(ucontrol->value.integer.value)); - if (!substream->runtime || !rtd) + if (!rtd) return 0; /* no channels set */ mutex_lock(&pdata->lock); - prtd = substream->runtime->private_data; + prtd = substream->runtime ? substream->runtime->private_data : NULL; if (prtd && prtd->set_channel_map == true) { for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) -- GitLab From a267a11e945b01e789b75366d4729abd77bd1d5a Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 18 Oct 2019 12:40:47 +0530 Subject: [PATCH 1257/1645] ASoC: wcd938x: Disable ADC mode for tx at power down after record ADC mode for tx 0,1,2,3 is not disabled at power down after record causing noise during next headset record. Disable ADC mode to resolve noise. Change-Id: I0a98b06318b55cfce20c6a90fecd71d83dce28c5 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd938x/wcd938x.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 04954d9f9d75..aa3d62321104 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1626,18 +1626,30 @@ static int wcd938x_enable_req(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMD: switch (w->shift) { case 0: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1, 0x0F, + 0x00); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x10, 0x00); break; case 1: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1, 0xF0, + 0x00); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x20, 0x00); break; case 2: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3, 0x0F, + 0x00); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x40, 0x00); break; case 3: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3, 0xF0, + 0x00); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x00); break; -- GitLab From 9d6160b373e931c13d91d4c627b93d0028b5ceb3 Mon Sep 17 00:00:00 2001 From: Ajit Pandey Date: Thu, 28 Mar 2019 19:36:36 +0530 Subject: [PATCH 1258/1645] dsp: q6voice: Reset dma_buf pointer to NULL in case of failure In case of voice_alloc_rtac_mem_map_table() failure no memory get allocated for rtac but dma_buf pointer might get corrupted and may point to some unmapped memory region. Since we are only doing NULL pointer check for dma_buf in method is_rtac_memory_allocated() we need to reset such pointer to NULL in failure case. Change-Id: I5e81adad4e302620757375f87fa15344e07dccf8 Signed-off-by: Ajit Pandey --- dsp/q6voice.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 6de668684319..3db75d02c54f 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -3852,6 +3852,7 @@ int voc_map_rtac_block(struct rtac_cal_block_data *cal_block) &cal_block->cal_data.paddr, cal_block->map_data.map_size); + common.rtac_mem_map_table.dma_buf = NULL; goto done_unlock; } } -- GitLab From b2a024a1d10bfbabf3d929daa95a9186973f623b Mon Sep 17 00:00:00 2001 From: Anurag Chouhan Date: Wed, 9 Oct 2019 11:39:08 +0530 Subject: [PATCH 1259/1645] AsoC: Add mixer controls for incall music delivery Add mixer controls for incall music delivery. CRs-Fixed: 2533113 Change-Id: Ie3180e16820627fbf3196281b0e8bdd91174e3b6 Signed-off-by: Anurag Chouhan --- asoc/msm-pcm-routing-v2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 79ddd89f33d9..8093b447f535 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -7607,6 +7607,10 @@ static const struct snd_kcontrol_new incall_music_delivery_mixer_controls[] = { MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, @@ -24614,6 +24618,7 @@ static const struct snd_soc_dapm_route intercon[] = { /* incall */ {"Incall_Music Audio Mixer", "MultiMedia1", "MM_DL1"}, {"Incall_Music Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"Incall_Music Audio Mixer", "MultiMedia4", "MM_DL4"}, {"Incall_Music Audio Mixer", "MultiMedia5", "MM_DL5"}, {"Incall_Music Audio Mixer", "MultiMedia9", "MM_DL9"}, {"VOICE_PLAYBACK_TX", NULL, "Incall_Music Audio Mixer"}, -- GitLab From d7ee50cc8e02605951c03ce2dbecfdbb341c7721 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 10 Oct 2019 12:35:11 +0530 Subject: [PATCH 1260/1645] asoc: codecs: Avoid spi data transfer during suspend SPI data transfer can happen during suspend due to race conditions leading to NOC issues. Synchronize data transfer and suspend to fix this issue. Change-Id: Ia5b4d0d16d9bf4fa4a4b73e3509a7d04b45d843f Signed-off-by: Aditya Bavanari --- asoc/codecs/wcd-spi.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd-spi.c b/asoc/codecs/wcd-spi.c index 0173e151cbb8..4c7a85338ed4 100644 --- a/asoc/codecs/wcd-spi.c +++ b/asoc/codecs/wcd-spi.c @@ -815,6 +815,15 @@ static int __wcd_spi_data_xfer(struct spi_device *spi, return -EINVAL; } + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex); + if (wcd_spi_is_suspended(wcd_spi)) { + dev_dbg(&spi->dev, + "%s: SPI suspended, cannot perform transfer\n", + __func__); + ret = -EIO; + goto done; + } + WCD_SPI_MUTEX_LOCK(spi, wcd_spi->xfer_mutex); if (msg->len == WCD_SPI_WORD_BYTE_CNT) { if (xfer_req == WCD_SPI_XFER_WRITE) @@ -827,7 +836,8 @@ static int __wcd_spi_data_xfer(struct spi_device *spi, ret = wcd_spi_transfer_split(spi, msg, xfer_req); } WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->xfer_mutex); - +done: + WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex); return ret; } -- GitLab From 35955cb60ff0a63b9946ec9f08f80f454afa7faa Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 20 Sep 2019 13:58:34 -0700 Subject: [PATCH 1261/1645] asoc: codecs: bolero: do not perform soft reset In event handler for soft reset, do not perform soft resetting of the compander as this is not the recommended sequence. Compander config needs to be done only in interpolator enable function. Change-Id: I9bb1d493860adc924252827594219618f16309b0 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/rx-macro.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index ec71d4a777c8..ffcd734091df 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1350,10 +1350,8 @@ static int rx_macro_event_handler(struct snd_soc_component *component, goto done; reg = BOLERO_CDC_RX_COMPANDER0_CTL0 + (rx_idx * RX_MACRO_COMP_OFFSET); - snd_soc_component_update_bits(component, reg, - 0x20, 0x20); - snd_soc_component_update_bits(component, reg, - 0x20, 0x00); + snd_soc_component_write(component, reg, + snd_soc_component_read32(component, reg)); break; case BOLERO_MACRO_EVT_IMPED_TRUE: rx_macro_wcd_clsh_imped_config(component, data, true); -- GitLab From fc40b33b24116352df3d9922bb1afb41794b6e96 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 22 Oct 2019 11:07:07 +0530 Subject: [PATCH 1262/1645] ASoC: wcd-mbhc: Fix null pointer dereference for mbhc IRQ data pointer is corrupted due to slimbus NGD errors. This may happen as IRQ will be received from slimbus. Check for mbhc null pointer before dereferencing to avoid crash. Change-Id: I142ee535c6d643b53063b57c0f45414aff8b6304 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd-mbhc-v2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 01544aab9c43..ed98deb628e5 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -1055,6 +1055,10 @@ static irqreturn_t wcd_mbhc_mech_plug_detect_irq(int irq, void *data) struct wcd_mbhc *mbhc = data; pr_debug("%s: enter\n", __func__); + if (mbhc == NULL) { + pr_err("%s: NULL irq data\n", __func__); + return IRQ_NONE; + } if (unlikely((mbhc->mbhc_cb->lock_sleep(mbhc, true)) == false)) { pr_warn("%s: failed to hold suspend\n", __func__); r = IRQ_NONE; -- GitLab From 82aee8f928373230c0552253a255ca92bfa326f5 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 14 Oct 2019 23:56:01 +0530 Subject: [PATCH 1263/1645] ASoC: Add routing for quin tdm tx and voice controls Add routing for quin tdm tx 0 to 3 and voice controls. Change-Id: I39cb30e4a8eac556059aa156675e9afddd00f890 Signed-off-by: Vatsal Bucha --- asoc/msm-pcm-routing-v2.c | 224 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 79ddd89f33d9..be9b415fe700 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -11191,6 +11191,73 @@ static const struct snd_kcontrol_new quin_tdm_tx_0_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new quin_tdm_tx_1_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new quin_tdm_rx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_RX_1, @@ -11270,6 +11337,73 @@ static const struct snd_kcontrol_new quin_tdm_rx_1_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new quin_tdm_tx_2_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_RX_2, @@ -11349,6 +11483,73 @@ static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new quin_tdm_tx_3_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, MSM_BACKEND_DAI_QUIN_TDM_RX_3, @@ -15843,6 +16044,13 @@ static const struct snd_kcontrol_new quat_tdm_rx_2_voice_mixer_controls[] = { msm_routing_put_voice_mixer), }; +static const struct snd_kcontrol_new quin_tdm_rx_2_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_voice_mixer_controls[] = { SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, @@ -23701,12 +23909,21 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QUIN_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, quin_tdm_rx_1_mixer_controls, ARRAY_SIZE(quin_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_TX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_tx_1_mixer_controls, + ARRAY_SIZE(quin_tdm_tx_1_mixer_controls)), SND_SOC_DAPM_MIXER("QUIN_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, quin_tdm_rx_2_mixer_controls, ARRAY_SIZE(quin_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_TX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_tx_2_mixer_controls, + ARRAY_SIZE(quin_tdm_tx_2_mixer_controls)), SND_SOC_DAPM_MIXER("QUIN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, quin_tdm_rx_3_mixer_controls, ARRAY_SIZE(quin_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_TX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_tx_3_mixer_controls, + ARRAY_SIZE(quin_tdm_tx_3_mixer_controls)), SND_SOC_DAPM_MIXER("SEN_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, sen_tdm_tx_0_mixer_controls, ARRAY_SIZE(sen_tdm_tx_0_mixer_controls)), @@ -23934,6 +24151,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_NOPM, 0, 0, quat_tdm_rx_2_voice_mixer_controls, ARRAY_SIZE(quat_tdm_rx_2_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_2_Voice Mixer", + SND_SOC_NOPM, 0, 0, + quin_tdm_rx_2_voice_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_2_voice_mixer_controls)), SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0_Voice Mixer", SND_SOC_NOPM, 0, 0, wsa_cdc_dma_rx_0_voice_mixer_controls, @@ -26712,6 +26933,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_Voice Mixer"}, + {"QUIN_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2_Voice Mixer"}, + {"WSA_CDC_DMA_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, {"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, -- GitLab From f1623021b1ce1a710bf939c42ef536a203382d29 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 11 Oct 2019 18:20:19 +0530 Subject: [PATCH 1264/1645] asoc: bolero: Update version query for bolero 2.1 Expose API from bolero driver to retrieve version info by macro drivers. Update bolero driver to get version from dtsi. Change-Id: Idc3735721de90ee4f74319537b17a530d3c125a6 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc-utils.c | 18 ++---- asoc/codecs/bolero/bolero-cdc.c | 91 +++++++++++++++++++++------ asoc/codecs/bolero/bolero-cdc.h | 12 ++++ 3 files changed, 89 insertions(+), 32 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc-utils.c b/asoc/codecs/bolero/bolero-cdc-utils.c index b2fd15325b1c..f2e4ec47f967 100644 --- a/asoc/codecs/bolero/bolero-cdc-utils.c +++ b/asoc/codecs/bolero/bolero-cdc-utils.c @@ -68,12 +68,9 @@ static int regmap_bus_read(void *context, const void *reg, size_t reg_size, reg_p = (u16 *)reg; macro_id = bolero_get_macro_id(priv->va_without_decimation, reg_p[0]); - if (macro_id < 0 || !priv->macros_supported[macro_id]) { - dev_err_ratelimited(dev, - "%s: Unsupported macro %d or reg 0x%x is invalid\n", - __func__, macro_id, reg_p[0]); - return ret; - } + if (macro_id < 0 || !priv->macros_supported[macro_id]) + return 0; + mutex_lock(&priv->io_lock); for (i = 0; i < val_size; i++) { __reg = (reg_p[0] + i * 4) - macro_id_base_offset[macro_id]; @@ -121,12 +118,9 @@ static int regmap_bus_gather_write(void *context, reg_p = (u16 *)reg; macro_id = bolero_get_macro_id(priv->va_without_decimation, reg_p[0]); - if (macro_id < 0 || !priv->macros_supported[macro_id]) { - dev_err_ratelimited(dev, - "%s: Unsupported macro-id %d or reg 0x%x is invalid\n", - __func__, macro_id, reg_p[0]); - return ret; - } + if (macro_id < 0 || !priv->macros_supported[macro_id]) + return 0; + mutex_lock(&priv->io_lock); for (i = 0; i < val_size; i++) { __reg = (reg_p[0] + i * 4) - macro_id_base_offset[macro_id]; diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index fdf0445ebfb7..da3cb2b96ffe 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -20,9 +20,6 @@ #define DRV_NAME "bolero_codec" -#define BOLERO_VERSION_1_0 0x0001 -#define BOLERO_VERSION_1_1 0x0002 -#define BOLERO_VERSION_1_2 0x0003 #define BOLERO_VERSION_ENTRY_SIZE 32 #define BOLERO_CDC_STRING_LEN 80 @@ -507,11 +504,17 @@ int bolero_register_macro(struct device *dev, u16 macro_id, priv->macro_params[macro_id].reg_evt_listener = ops->reg_evt_listener; } - + if (priv->version == BOLERO_VERSION_2_1) { + if (macro_id == VA_MACRO) + priv->macro_params[macro_id].reg_wake_irq = + ops->reg_wake_irq; + } priv->num_dais += ops->num_dais; priv->num_macros_registered++; priv->macros_supported[macro_id] = true; + dev_dbg(dev, "%s: register macro successful:%d\n", macro_id); + if (priv->num_macros_registered == priv->num_macros) { ret = bolero_copy_dais_from_macro(priv); if (ret < 0) { @@ -604,6 +607,28 @@ void bolero_wsa_pa_on(struct device *dev) } EXPORT_SYMBOL(bolero_wsa_pa_on); +int bolero_get_version(struct device *dev) +{ + struct bolero_priv *priv; + + if (!dev) { + pr_err("%s: dev is null\n", __func__); + return -EINVAL; + } + if (!bolero_is_valid_child_dev(dev)) { + dev_err(dev, "%s: child device for macro not added yet\n", + __func__); + return -EINVAL; + } + priv = dev_get_drvdata(dev->parent); + if (!priv) { + dev_err(dev, "%s: priv is null\n", __func__); + return -EINVAL; + } + return priv->version; +} +EXPORT_SYMBOL(bolero_get_version); + static ssize_t bolero_version_read(struct snd_info_entry *entry, void *file_private_data, struct file *file, @@ -630,6 +655,9 @@ static ssize_t bolero_version_read(struct snd_info_entry *entry, case BOLERO_VERSION_1_2: len = snprintf(buffer, sizeof(buffer), "BOLERO_1_2\n"); break; + case BOLERO_VERSION_2_1: + len = snprintf(buffer, sizeof(buffer), "BOLERO_2_1\n"); + break; default: len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); } @@ -794,9 +822,15 @@ int bolero_register_wake_irq(struct snd_soc_component *component, return -EINVAL; } - if (priv->macro_params[TX_MACRO].reg_wake_irq) - priv->macro_params[TX_MACRO].reg_wake_irq( - component, ipc_wakeup); + if (priv->version == BOLERO_VERSION_2_1) { + if (priv->macro_params[VA_MACRO].reg_wake_irq) + priv->macro_params[VA_MACRO].reg_wake_irq( + component, ipc_wakeup); + } else { + if (priv->macro_params[TX_MACRO].reg_wake_irq) + priv->macro_params[TX_MACRO].reg_wake_irq( + component, ipc_wakeup); + } return 0; } @@ -875,6 +909,29 @@ static int bolero_soc_codec_probe(struct snd_soc_component *component) snd_soc_component_init_regmap(component, priv->regmap); + if (!priv->version) { + /* + * In order for the ADIE RTC to differentiate between targets + * version info is used. + * Assign 1.0 for target with only one macro + * Assign 1.1 for target with two macros + * Assign 1.2 for target with more than two macros + */ + if (priv->num_macros_registered == 1) + priv->version = BOLERO_VERSION_1_0; + else if (priv->num_macros_registered == 2) + priv->version = BOLERO_VERSION_1_1; + else if (priv->num_macros_registered > 2) + priv->version = BOLERO_VERSION_1_2; + } + + /* Assign bolero version 2.1 for bolero 2.1 */ + if ((snd_soc_component_read32(component, + BOLERO_CDC_VA_TOP_CSR_CORE_ID_0) == 0x2) && + (snd_soc_component_read32(component, + BOLERO_CDC_VA_TOP_CSR_CORE_ID_1) == 0xE)) + priv->version = BOLERO_VERSION_2_1; + /* call init for supported macros */ for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { if (priv->macro_params[macro_idx].init) { @@ -888,19 +945,6 @@ static int bolero_soc_codec_probe(struct snd_soc_component *component) } } priv->component = component; - /* - * In order for the ADIE RTC to differentiate between targets - * version info is used. - * Assign 1.0 for target with only one macro - * Assign 1.1 for target with two macros - * Assign 1.2 for target with more than two macros - */ - if (priv->num_macros_registered == 1) - priv->version = BOLERO_VERSION_1_0; - else if (priv->num_macros_registered == 2) - priv->version = BOLERO_VERSION_1_1; - else if (priv->num_macros_registered > 2) - priv->version = BOLERO_VERSION_1_2; ret = snd_event_client_register(priv->dev, &bolero_ssr_ops, priv); if (!ret) { @@ -1044,6 +1088,13 @@ static int bolero_probe(struct platform_device *pdev) if (priv->va_without_decimation) bolero_reg_access[VA_MACRO] = bolero_va_top_reg_access; + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,bolero-version", &priv->version); + if (ret) { + dev_dbg(&pdev->dev, "%s:bolero version not specified\n", + __func__); + ret = 0; + } priv->dev = &pdev->dev; priv->dev_up = true; priv->initial_boot = true; diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index f104f88a34bb..c15e01264d62 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -8,6 +8,12 @@ #include #include +#define BOLERO_VERSION_1_0 0x0001 +#define BOLERO_VERSION_1_1 0x0002 +#define BOLERO_VERSION_1_2 0x0003 +#define BOLERO_VERSION_2_0 0x0004 +#define BOLERO_VERSION_2_1 0x0005 + enum { START_MACRO, TX_MACRO = START_MACRO, @@ -85,6 +91,7 @@ int bolero_register_event_listener(struct snd_soc_component *component, bool enable); void bolero_wsa_pa_on(struct device *dev); bool bolero_check_core_votes(struct device *dev); +int bolero_get_version(struct device *dev); #else static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb) { @@ -164,5 +171,10 @@ static inline bool bolero_check_core_votes(struct device *dev) { return false; } + +static int bolero_get_version(struct device *dev) +{ + return 0; +} #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ -- GitLab From 4651dcbbb093c7335e3b3b5f03d040829d5718bf Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 10 Oct 2019 23:45:21 +0530 Subject: [PATCH 1265/1645] asoc: codecs: Update VA/TX controls based on bolero version Update route map, dapm widgets, snd controls for VA and TX macros based on bolero version. Change-Id: I6f517f2c243624d44601192295c50838c7ee0e05 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/tx-macro.c | 673 ++++++++++++++++++++++++++++++++-- asoc/codecs/bolero/va-macro.c | 503 +++++++++++++++++++++++-- 2 files changed, 1126 insertions(+), 50 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index ca88bfa1582a..70f269b252e6 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -160,6 +160,7 @@ struct tx_macro_priv { s32 dmic_4_5_clk_cnt; s32 dmic_6_7_clk_cnt; u16 dmic_clk_div; + u32 version; unsigned long active_ch_mask[TX_MACRO_MAX_DAIS]; unsigned long active_ch_cnt[TX_MACRO_MAX_DAIS]; char __iomem *tx_io_base; @@ -1210,6 +1211,44 @@ TX_MACRO_DAPM_ENUM_EXT(tx_smic7, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0, smic_mux_text, snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); +static const char * const smic_mux_text_v2[] = { + "ZERO", "SWR_MIC0", "SWR_MIC1", "SWR_MIC2", "SWR_MIC3", + "SWR_MIC4", "SWR_MIC5", "SWR_MIC6", "SWR_MIC7", + "SWR_MIC8", "SWR_MIC9", "SWR_MIC10", "SWR_MIC11" +}; + +TX_MACRO_DAPM_ENUM_EXT(tx_smic0_v2, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0, + 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic1_v2, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0, + 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic2_v2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0, + 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic3_v2, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0, + 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic4_v3, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0, + 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic5_v3, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0, + 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic6_v3, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0, + 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + +TX_MACRO_DAPM_ENUM_EXT(tx_smic7_v3, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0, + 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, + tx_macro_put_dec_enum); + static const char * const dec_mode_mux_text[] = { "ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF", }; @@ -1275,6 +1314,205 @@ static const struct snd_kcontrol_new tx_aif3_cap_mixer[] = { tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), }; +static const struct snd_kcontrol_new tx_aif1_cap_mixer_v2[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), +}; + +static const struct snd_kcontrol_new tx_aif2_cap_mixer_v2[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), +}; + +static const struct snd_kcontrol_new tx_aif3_cap_mixer_v2[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0, + tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), +}; + +static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_common[] = { + SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0, + SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0), + + SND_SOC_DAPM_AIF_OUT("TX_AIF2 CAP", "TX_AIF2 Capture", 0, + SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0), + + SND_SOC_DAPM_AIF_OUT("TX_AIF3 CAP", "TX_AIF3 Capture", 0, + SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0), + + TX_MACRO_DAPM_MUX("TX DMIC MUX0", 0, tx_dmic0), + TX_MACRO_DAPM_MUX("TX DMIC MUX1", 0, tx_dmic1), + TX_MACRO_DAPM_MUX("TX DMIC MUX2", 0, tx_dmic2), + TX_MACRO_DAPM_MUX("TX DMIC MUX3", 0, tx_dmic3), + + TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0_v2), + TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1_v2), + TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2_v2), + TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3_v2), + + SND_SOC_DAPM_MICBIAS_E("TX MIC BIAS1", SND_SOC_NOPM, 0, 0, + tx_macro_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("TX DMIC0", NULL, SND_SOC_NOPM, 0, 0, + tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("TX DMIC1", NULL, SND_SOC_NOPM, 0, 0, + tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("TX DMIC2", NULL, SND_SOC_NOPM, 0, 0, + tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("TX DMIC3", NULL, SND_SOC_NOPM, 0, 0, + tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("TX DMIC4", NULL, SND_SOC_NOPM, 0, 0, + tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("TX DMIC5", NULL, SND_SOC_NOPM, 0, 0, + tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("TX DMIC6", NULL, SND_SOC_NOPM, 0, 0, + tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("TX DMIC7", NULL, SND_SOC_NOPM, 0, 0, + tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_INPUT("TX SWR_MIC0"), + SND_SOC_DAPM_INPUT("TX SWR_MIC1"), + SND_SOC_DAPM_INPUT("TX SWR_MIC2"), + SND_SOC_DAPM_INPUT("TX SWR_MIC3"), + SND_SOC_DAPM_INPUT("TX SWR_MIC4"), + SND_SOC_DAPM_INPUT("TX SWR_MIC5"), + SND_SOC_DAPM_INPUT("TX SWR_MIC6"), + SND_SOC_DAPM_INPUT("TX SWR_MIC7"), + SND_SOC_DAPM_INPUT("TX SWR_MIC8"), + SND_SOC_DAPM_INPUT("TX SWR_MIC9"), + SND_SOC_DAPM_INPUT("TX SWR_MIC10"), + SND_SOC_DAPM_INPUT("TX SWR_MIC11"), + + SND_SOC_DAPM_MUX_E("TX DEC0 MUX", SND_SOC_NOPM, + TX_MACRO_DEC0, 0, + &tx_dec0_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC1 MUX", SND_SOC_NOPM, + TX_MACRO_DEC1, 0, + &tx_dec1_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC2 MUX", SND_SOC_NOPM, + TX_MACRO_DEC2, 0, + &tx_dec2_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC3 MUX", SND_SOC_NOPM, + TX_MACRO_DEC3, 0, + &tx_dec3_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0, + tx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v2[] = { + SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM, + TX_MACRO_AIF1_CAP, 0, + tx_aif1_cap_mixer_v2, ARRAY_SIZE(tx_aif1_cap_mixer_v2)), + + SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM, + TX_MACRO_AIF2_CAP, 0, + tx_aif2_cap_mixer_v2, ARRAY_SIZE(tx_aif2_cap_mixer_v2)), + + SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM, + TX_MACRO_AIF3_CAP, 0, + tx_aif3_cap_mixer_v2, ARRAY_SIZE(tx_aif3_cap_mixer_v2)), + + SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, + tx_macro_tx_swr_clk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v3[] = { + SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM, + TX_MACRO_AIF1_CAP, 0, + tx_aif1_cap_mixer, ARRAY_SIZE(tx_aif1_cap_mixer)), + + SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM, + TX_MACRO_AIF2_CAP, 0, + tx_aif2_cap_mixer, ARRAY_SIZE(tx_aif2_cap_mixer)), + + SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM, + TX_MACRO_AIF3_CAP, 0, + tx_aif3_cap_mixer, ARRAY_SIZE(tx_aif3_cap_mixer)), + + TX_MACRO_DAPM_MUX("TX DMIC MUX4", 0, tx_dmic4), + TX_MACRO_DAPM_MUX("TX DMIC MUX5", 0, tx_dmic5), + TX_MACRO_DAPM_MUX("TX DMIC MUX6", 0, tx_dmic6), + TX_MACRO_DAPM_MUX("TX DMIC MUX7", 0, tx_dmic7), + + TX_MACRO_DAPM_MUX("TX SMIC MUX4", 0, tx_smic4_v3), + TX_MACRO_DAPM_MUX("TX SMIC MUX5", 0, tx_smic5_v3), + TX_MACRO_DAPM_MUX("TX SMIC MUX6", 0, tx_smic6_v3), + TX_MACRO_DAPM_MUX("TX SMIC MUX7", 0, tx_smic7_v3), + + SND_SOC_DAPM_MUX_E("TX DEC4 MUX", SND_SOC_NOPM, + TX_MACRO_DEC4, 0, + &tx_dec4_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC5 MUX", SND_SOC_NOPM, + TX_MACRO_DEC5, 0, + &tx_dec5_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC6 MUX", SND_SOC_NOPM, + TX_MACRO_DEC6, 0, + &tx_dec6_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("TX DEC7 MUX", SND_SOC_NOPM, + TX_MACRO_DEC7, 0, + &tx_dec7_mux, tx_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, + tx_macro_va_swr_clk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0, SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0), @@ -1421,6 +1659,250 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; +static const struct snd_soc_dapm_route tx_audio_map_common[] = { + {"TX_AIF1 CAP", NULL, "TX_MCLK"}, + {"TX_AIF2 CAP", NULL, "TX_MCLK"}, + {"TX_AIF3 CAP", NULL, "TX_MCLK"}, + + {"TX_AIF1 CAP", NULL, "TX_AIF1_CAP Mixer"}, + {"TX_AIF2 CAP", NULL, "TX_AIF2_CAP Mixer"}, + {"TX_AIF3 CAP", NULL, "TX_AIF3_CAP Mixer"}, + + {"TX_AIF1_CAP Mixer", "DEC0", "TX DEC0 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC1", "TX DEC1 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC2", "TX DEC2 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC3", "TX DEC3 MUX"}, + + {"TX_AIF2_CAP Mixer", "DEC0", "TX DEC0 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC1", "TX DEC1 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC2", "TX DEC2 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC3", "TX DEC3 MUX"}, + + {"TX_AIF3_CAP Mixer", "DEC0", "TX DEC0 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC1", "TX DEC1 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC2", "TX DEC2 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC3", "TX DEC3 MUX"}, + + {"TX DEC0 MUX", NULL, "TX_MCLK"}, + {"TX DEC1 MUX", NULL, "TX_MCLK"}, + {"TX DEC2 MUX", NULL, "TX_MCLK"}, + {"TX DEC3 MUX", NULL, "TX_MCLK"}, + + {"TX DEC0 MUX", "MSM_DMIC", "TX DMIC MUX0"}, + {"TX DMIC MUX0", "DMIC0", "TX DMIC0"}, + {"TX DMIC MUX0", "DMIC1", "TX DMIC1"}, + {"TX DMIC MUX0", "DMIC2", "TX DMIC2"}, + {"TX DMIC MUX0", "DMIC3", "TX DMIC3"}, + {"TX DMIC MUX0", "DMIC4", "TX DMIC4"}, + {"TX DMIC MUX0", "DMIC5", "TX DMIC5"}, + {"TX DMIC MUX0", "DMIC6", "TX DMIC6"}, + {"TX DMIC MUX0", "DMIC7", "TX DMIC7"}, + + {"TX DEC0 MUX", "SWR_MIC", "TX SMIC MUX0"}, + {"TX SMIC MUX0", "SWR_MIC0", "TX SWR_MIC0"}, + {"TX SMIC MUX0", "SWR_MIC1", "TX SWR_MIC1"}, + {"TX SMIC MUX0", "SWR_MIC2", "TX SWR_MIC2"}, + {"TX SMIC MUX0", "SWR_MIC3", "TX SWR_MIC3"}, + {"TX SMIC MUX0", "SWR_MIC4", "TX SWR_MIC4"}, + {"TX SMIC MUX0", "SWR_MIC5", "TX SWR_MIC5"}, + {"TX SMIC MUX0", "SWR_MIC6", "TX SWR_MIC6"}, + {"TX SMIC MUX0", "SWR_MIC7", "TX SWR_MIC7"}, + {"TX SMIC MUX0", "SWR_MIC8", "TX SWR_MIC8"}, + {"TX SMIC MUX0", "SWR_MIC9", "TX SWR_MIC9"}, + {"TX SMIC MUX0", "SWR_MIC10", "TX SWR_MIC10"}, + {"TX SMIC MUX0", "SWR_MIC11", "TX SWR_MIC11"}, + + {"TX DEC1 MUX", "MSM_DMIC", "TX DMIC MUX1"}, + {"TX DMIC MUX1", "DMIC0", "TX DMIC0"}, + {"TX DMIC MUX1", "DMIC1", "TX DMIC1"}, + {"TX DMIC MUX1", "DMIC2", "TX DMIC2"}, + {"TX DMIC MUX1", "DMIC3", "TX DMIC3"}, + {"TX DMIC MUX1", "DMIC4", "TX DMIC4"}, + {"TX DMIC MUX1", "DMIC5", "TX DMIC5"}, + {"TX DMIC MUX1", "DMIC6", "TX DMIC6"}, + {"TX DMIC MUX1", "DMIC7", "TX DMIC7"}, + + {"TX DEC1 MUX", "SWR_MIC", "TX SMIC MUX1"}, + {"TX SMIC MUX1", "SWR_MIC0", "TX SWR_MIC0"}, + {"TX SMIC MUX1", "SWR_MIC1", "TX SWR_MIC1"}, + {"TX SMIC MUX1", "SWR_MIC2", "TX SWR_MIC2"}, + {"TX SMIC MUX1", "SWR_MIC3", "TX SWR_MIC3"}, + {"TX SMIC MUX1", "SWR_MIC4", "TX SWR_MIC4"}, + {"TX SMIC MUX1", "SWR_MIC5", "TX SWR_MIC5"}, + {"TX SMIC MUX1", "SWR_MIC6", "TX SWR_MIC6"}, + {"TX SMIC MUX1", "SWR_MIC7", "TX SWR_MIC7"}, + {"TX SMIC MUX1", "SWR_MIC8", "TX SWR_MIC8"}, + {"TX SMIC MUX1", "SWR_MIC9", "TX SWR_MIC9"}, + {"TX SMIC MUX1", "SWR_MIC10", "TX SWR_MIC10"}, + {"TX SMIC MUX1", "SWR_MIC11", "TX SWR_MIC11"}, + + {"TX DEC2 MUX", "MSM_DMIC", "TX DMIC MUX2"}, + {"TX DMIC MUX2", "DMIC0", "TX DMIC0"}, + {"TX DMIC MUX2", "DMIC1", "TX DMIC1"}, + {"TX DMIC MUX2", "DMIC2", "TX DMIC2"}, + {"TX DMIC MUX2", "DMIC3", "TX DMIC3"}, + {"TX DMIC MUX2", "DMIC4", "TX DMIC4"}, + {"TX DMIC MUX2", "DMIC5", "TX DMIC5"}, + {"TX DMIC MUX2", "DMIC6", "TX DMIC6"}, + {"TX DMIC MUX2", "DMIC7", "TX DMIC7"}, + + {"TX DEC2 MUX", "SWR_MIC", "TX SMIC MUX2"}, + {"TX SMIC MUX2", "SWR_MIC0", "TX SWR_MIC0"}, + {"TX SMIC MUX2", "SWR_MIC1", "TX SWR_MIC1"}, + {"TX SMIC MUX2", "SWR_MIC2", "TX SWR_MIC2"}, + {"TX SMIC MUX2", "SWR_MIC3", "TX SWR_MIC3"}, + {"TX SMIC MUX2", "SWR_MIC4", "TX SWR_MIC4"}, + {"TX SMIC MUX2", "SWR_MIC5", "TX SWR_MIC5"}, + {"TX SMIC MUX2", "SWR_MIC6", "TX SWR_MIC6"}, + {"TX SMIC MUX2", "SWR_MIC7", "TX SWR_MIC7"}, + {"TX SMIC MUX2", "SWR_MIC8", "TX SWR_MIC8"}, + {"TX SMIC MUX2", "SWR_MIC9", "TX SWR_MIC9"}, + {"TX SMIC MUX2", "SWR_MIC10", "TX SWR_MIC10"}, + {"TX SMIC MUX2", "SWR_MIC11", "TX SWR_MIC11"}, + + {"TX DEC3 MUX", "MSM_DMIC", "TX DMIC MUX3"}, + {"TX DMIC MUX3", "DMIC0", "TX DMIC0"}, + {"TX DMIC MUX3", "DMIC1", "TX DMIC1"}, + {"TX DMIC MUX3", "DMIC2", "TX DMIC2"}, + {"TX DMIC MUX3", "DMIC3", "TX DMIC3"}, + {"TX DMIC MUX3", "DMIC4", "TX DMIC4"}, + {"TX DMIC MUX3", "DMIC5", "TX DMIC5"}, + {"TX DMIC MUX3", "DMIC6", "TX DMIC6"}, + {"TX DMIC MUX3", "DMIC7", "TX DMIC7"}, + + {"TX DEC3 MUX", "SWR_MIC", "TX SMIC MUX3"}, + {"TX SMIC MUX3", "SWR_MIC0", "TX SWR_MIC0"}, + {"TX SMIC MUX3", "SWR_MIC1", "TX SWR_MIC1"}, + {"TX SMIC MUX3", "SWR_MIC2", "TX SWR_MIC2"}, + {"TX SMIC MUX3", "SWR_MIC3", "TX SWR_MIC3"}, + {"TX SMIC MUX3", "SWR_MIC4", "TX SWR_MIC4"}, + {"TX SMIC MUX3", "SWR_MIC5", "TX SWR_MIC5"}, + {"TX SMIC MUX3", "SWR_MIC6", "TX SWR_MIC6"}, + {"TX SMIC MUX3", "SWR_MIC7", "TX SWR_MIC7"}, + {"TX SMIC MUX3", "SWR_MIC8", "TX SWR_MIC8"}, + {"TX SMIC MUX3", "SWR_MIC9", "TX SWR_MIC9"}, + {"TX SMIC MUX3", "SWR_MIC10", "TX SWR_MIC10"}, + {"TX SMIC MUX3", "SWR_MIC11", "TX SWR_MIC11"}, +}; + +static const struct snd_soc_dapm_route tx_audio_map_v3[] = { + {"TX_AIF1_CAP Mixer", "DEC4", "TX DEC4 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC5", "TX DEC5 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC6", "TX DEC6 MUX"}, + {"TX_AIF1_CAP Mixer", "DEC7", "TX DEC7 MUX"}, + + {"TX_AIF2_CAP Mixer", "DEC4", "TX DEC4 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC5", "TX DEC5 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC6", "TX DEC6 MUX"}, + {"TX_AIF2_CAP Mixer", "DEC7", "TX DEC7 MUX"}, + + {"TX_AIF3_CAP Mixer", "DEC4", "TX DEC4 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC5", "TX DEC5 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC6", "TX DEC6 MUX"}, + {"TX_AIF3_CAP Mixer", "DEC7", "TX DEC7 MUX"}, + + {"TX DEC4 MUX", NULL, "TX_MCLK"}, + {"TX DEC5 MUX", NULL, "TX_MCLK"}, + {"TX DEC6 MUX", NULL, "TX_MCLK"}, + {"TX DEC7 MUX", NULL, "TX_MCLK"}, + + {"TX DEC4 MUX", "MSM_DMIC", "TX DMIC MUX4"}, + {"TX DMIC MUX4", "DMIC0", "TX DMIC0"}, + {"TX DMIC MUX4", "DMIC1", "TX DMIC1"}, + {"TX DMIC MUX4", "DMIC2", "TX DMIC2"}, + {"TX DMIC MUX4", "DMIC3", "TX DMIC3"}, + {"TX DMIC MUX4", "DMIC4", "TX DMIC4"}, + {"TX DMIC MUX4", "DMIC5", "TX DMIC5"}, + {"TX DMIC MUX4", "DMIC6", "TX DMIC6"}, + {"TX DMIC MUX4", "DMIC7", "TX DMIC7"}, + + {"TX DEC4 MUX", "SWR_MIC", "TX SMIC MUX4"}, + {"TX SMIC MUX4", "SWR_MIC0", "TX SWR_MIC0"}, + {"TX SMIC MUX4", "SWR_MIC1", "TX SWR_MIC1"}, + {"TX SMIC MUX4", "SWR_MIC2", "TX SWR_MIC2"}, + {"TX SMIC MUX4", "SWR_MIC3", "TX SWR_MIC3"}, + {"TX SMIC MUX4", "SWR_MIC4", "TX SWR_MIC4"}, + {"TX SMIC MUX4", "SWR_MIC5", "TX SWR_MIC5"}, + {"TX SMIC MUX4", "SWR_MIC6", "TX SWR_MIC6"}, + {"TX SMIC MUX4", "SWR_MIC7", "TX SWR_MIC7"}, + {"TX SMIC MUX4", "SWR_MIC8", "TX SWR_MIC8"}, + {"TX SMIC MUX4", "SWR_MIC9", "TX SWR_MIC9"}, + {"TX SMIC MUX4", "SWR_MIC10", "TX SWR_MIC10"}, + {"TX SMIC MUX4", "SWR_MIC11", "TX SWR_MIC11"}, + + {"TX DEC5 MUX", "MSM_DMIC", "TX DMIC MUX5"}, + {"TX DMIC MUX5", "DMIC0", "TX DMIC0"}, + {"TX DMIC MUX5", "DMIC1", "TX DMIC1"}, + {"TX DMIC MUX5", "DMIC2", "TX DMIC2"}, + {"TX DMIC MUX5", "DMIC3", "TX DMIC3"}, + {"TX DMIC MUX5", "DMIC4", "TX DMIC4"}, + {"TX DMIC MUX5", "DMIC5", "TX DMIC5"}, + {"TX DMIC MUX5", "DMIC6", "TX DMIC6"}, + {"TX DMIC MUX5", "DMIC7", "TX DMIC7"}, + + {"TX DEC5 MUX", "SWR_MIC", "TX SMIC MUX5"}, + {"TX SMIC MUX5", "SWR_MIC0", "TX SWR_MIC0"}, + {"TX SMIC MUX5", "SWR_MIC1", "TX SWR_MIC1"}, + {"TX SMIC MUX5", "SWR_MIC2", "TX SWR_MIC2"}, + {"TX SMIC MUX5", "SWR_MIC3", "TX SWR_MIC3"}, + {"TX SMIC MUX5", "SWR_MIC4", "TX SWR_MIC4"}, + {"TX SMIC MUX5", "SWR_MIC5", "TX SWR_MIC5"}, + {"TX SMIC MUX5", "SWR_MIC6", "TX SWR_MIC6"}, + {"TX SMIC MUX5", "SWR_MIC7", "TX SWR_MIC7"}, + {"TX SMIC MUX5", "SWR_MIC8", "TX SWR_MIC8"}, + {"TX SMIC MUX5", "SWR_MIC9", "TX SWR_MIC9"}, + {"TX SMIC MUX5", "SWR_MIC10", "TX SWR_MIC10"}, + {"TX SMIC MUX5", "SWR_MIC11", "TX SWR_MIC11"}, + + {"TX DEC6 MUX", "MSM_DMIC", "TX DMIC MUX6"}, + {"TX DMIC MUX6", "DMIC0", "TX DMIC0"}, + {"TX DMIC MUX6", "DMIC1", "TX DMIC1"}, + {"TX DMIC MUX6", "DMIC2", "TX DMIC2"}, + {"TX DMIC MUX6", "DMIC3", "TX DMIC3"}, + {"TX DMIC MUX6", "DMIC4", "TX DMIC4"}, + {"TX DMIC MUX6", "DMIC5", "TX DMIC5"}, + {"TX DMIC MUX6", "DMIC6", "TX DMIC6"}, + {"TX DMIC MUX6", "DMIC7", "TX DMIC7"}, + + {"TX DEC6 MUX", "SWR_MIC", "TX SMIC MUX6"}, + {"TX SMIC MUX6", "SWR_MIC0", "TX SWR_MIC0"}, + {"TX SMIC MUX6", "SWR_MIC1", "TX SWR_MIC1"}, + {"TX SMIC MUX6", "SWR_MIC2", "TX SWR_MIC2"}, + {"TX SMIC MUX6", "SWR_MIC3", "TX SWR_MIC3"}, + {"TX SMIC MUX6", "SWR_MIC4", "TX SWR_MIC4"}, + {"TX SMIC MUX6", "SWR_MIC5", "TX SWR_MIC5"}, + {"TX SMIC MUX6", "SWR_MIC6", "TX SWR_MIC6"}, + {"TX SMIC MUX6", "SWR_MIC7", "TX SWR_MIC7"}, + {"TX SMIC MUX6", "SWR_MIC8", "TX SWR_MIC8"}, + {"TX SMIC MUX6", "SWR_MIC9", "TX SWR_MIC9"}, + {"TX SMIC MUX6", "SWR_MIC10", "TX SWR_MIC10"}, + {"TX SMIC MUX6", "SWR_MIC11", "TX SWR_MIC11"}, + + {"TX DEC7 MUX", "MSM_DMIC", "TX DMIC MUX7"}, + {"TX DMIC MUX7", "DMIC0", "TX DMIC0"}, + {"TX DMIC MUX7", "DMIC1", "TX DMIC1"}, + {"TX DMIC MUX7", "DMIC2", "TX DMIC2"}, + {"TX DMIC MUX7", "DMIC3", "TX DMIC3"}, + {"TX DMIC MUX7", "DMIC4", "TX DMIC4"}, + {"TX DMIC MUX7", "DMIC5", "TX DMIC5"}, + {"TX DMIC MUX7", "DMIC6", "TX DMIC6"}, + {"TX DMIC MUX7", "DMIC7", "TX DMIC7"}, + + {"TX DEC7 MUX", "SWR_MIC", "TX SMIC MUX7"}, + {"TX SMIC MUX7", "SWR_MIC0", "TX SWR_MIC0"}, + {"TX SMIC MUX7", "SWR_MIC1", "TX SWR_MIC1"}, + {"TX SMIC MUX7", "SWR_MIC2", "TX SWR_MIC2"}, + {"TX SMIC MUX7", "SWR_MIC3", "TX SWR_MIC3"}, + {"TX SMIC MUX7", "SWR_MIC4", "TX SWR_MIC4"}, + {"TX SMIC MUX7", "SWR_MIC5", "TX SWR_MIC5"}, + {"TX SMIC MUX7", "SWR_MIC6", "TX SWR_MIC6"}, + {"TX SMIC MUX7", "SWR_MIC7", "TX SWR_MIC7"}, + {"TX SMIC MUX7", "SWR_MIC8", "TX SWR_MIC8"}, + {"TX SMIC MUX7", "SWR_MIC9", "TX SWR_MIC9"}, + {"TX SMIC MUX7", "SWR_MIC10", "TX SWR_MIC10"}, + {"TX SMIC MUX7", "SWR_MIC11", "TX SWR_MIC11"}, +}; + static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX_AIF1 CAP", NULL, "TX_MCLK"}, {"TX_AIF2 CAP", NULL, "TX_MCLK"}, @@ -1667,6 +2149,63 @@ static const struct snd_soc_dapm_route tx_audio_map[] = { {"TX SMIC MUX7", "SWR_DMIC7", "TX SWR_DMIC7"}, }; +static const struct snd_kcontrol_new tx_macro_snd_controls_common[] = { + SOC_SINGLE_SX_TLV("TX_DEC0 Volume", + BOLERO_CDC_TX0_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("TX_DEC1 Volume", + BOLERO_CDC_TX1_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("TX_DEC2 Volume", + BOLERO_CDC_TX2_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("TX_DEC3 Volume", + BOLERO_CDC_TX3_TX_VOL_CTL, + 0, -84, 40, digital_gain), + + SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum, + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC1 MODE", dec_mode_mux_enum, + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC2 MODE", dec_mode_mux_enum, + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC3 MODE", dec_mode_mux_enum, + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_SINGLE_EXT("DEC0_BCS Switch", SND_SOC_NOPM, 0, 1, 0, + tx_macro_get_bcs, tx_macro_set_bcs), +}; + +static const struct snd_kcontrol_new tx_macro_snd_controls_v3[] = { + SOC_SINGLE_SX_TLV("TX_DEC4 Volume", + BOLERO_CDC_TX4_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("TX_DEC5 Volume", + BOLERO_CDC_TX5_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("TX_DEC6 Volume", + BOLERO_CDC_TX6_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("TX_DEC7 Volume", + BOLERO_CDC_TX7_TX_VOL_CTL, + 0, -84, 40, digital_gain), + + SOC_ENUM_EXT("DEC4 MODE", dec_mode_mux_enum, + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC5 MODE", dec_mode_mux_enum, + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC6 MODE", dec_mode_mux_enum, + tx_macro_dec_mode_get, tx_macro_dec_mode_put), + + SOC_ENUM_EXT("DEC7 MODE", dec_mode_mux_enum, + tx_macro_dec_mode_get, tx_macro_dec_mode_put), +}; + static const struct snd_kcontrol_new tx_macro_snd_controls[] = { SOC_SINGLE_SX_TLV("TX_DEC0 Volume", BOLERO_CDC_TX0_TX_VOL_CTL, @@ -2126,18 +2665,65 @@ static int tx_macro_init(struct snd_soc_component *component) "%s: priv is null for macro!\n", __func__); return -EINVAL; } - ret = snd_soc_dapm_new_controls(dapm, tx_macro_dapm_widgets, + tx_priv->version = bolero_get_version(tx_dev); + if (tx_priv->version >= BOLERO_VERSION_2_0) { + ret = snd_soc_dapm_new_controls(dapm, + tx_macro_dapm_widgets_common, + ARRAY_SIZE(tx_macro_dapm_widgets_common)); + if (ret < 0) { + dev_err(tx_dev, "%s: Failed to add controls\n", + __func__); + return ret; + } + if (tx_priv->version == BOLERO_VERSION_2_1) + ret = snd_soc_dapm_new_controls(dapm, + tx_macro_dapm_widgets_v2, + ARRAY_SIZE(tx_macro_dapm_widgets_v2)); + else if (tx_priv->version == BOLERO_VERSION_2_0) + ret = snd_soc_dapm_new_controls(dapm, + tx_macro_dapm_widgets_v3, + ARRAY_SIZE(tx_macro_dapm_widgets_v3)); + if (ret < 0) { + dev_err(tx_dev, "%s: Failed to add controls\n", + __func__); + return ret; + } + } else { + ret = snd_soc_dapm_new_controls(dapm, tx_macro_dapm_widgets, ARRAY_SIZE(tx_macro_dapm_widgets)); - if (ret < 0) { - dev_err(tx_dev, "%s: Failed to add controls\n", __func__); - return ret; + if (ret < 0) { + dev_err(tx_dev, "%s: Failed to add controls\n", + __func__); + return ret; + } } - ret = snd_soc_dapm_add_routes(dapm, tx_audio_map, + if (tx_priv->version >= BOLERO_VERSION_2_0) { + ret = snd_soc_dapm_add_routes(dapm, + tx_audio_map_common, + ARRAY_SIZE(tx_audio_map_common)); + if (ret < 0) { + dev_err(tx_dev, "%s: Failed to add routes\n", + __func__); + return ret; + } + if (tx_priv->version == BOLERO_VERSION_2_0) + ret = snd_soc_dapm_add_routes(dapm, + tx_audio_map_v3, + ARRAY_SIZE(tx_audio_map_v3)); + if (ret < 0) { + dev_err(tx_dev, "%s: Failed to add routes\n", + __func__); + return ret; + } + } else { + ret = snd_soc_dapm_add_routes(dapm, tx_audio_map, ARRAY_SIZE(tx_audio_map)); - if (ret < 0) { - dev_err(tx_dev, "%s: Failed to add routes\n", __func__); - return ret; + if (ret < 0) { + dev_err(tx_dev, "%s: Failed to add routes\n", + __func__); + return ret; + } } ret = snd_soc_dapm_new_widgets(dapm->card); @@ -2146,28 +2732,65 @@ static int tx_macro_init(struct snd_soc_component *component) return ret; } - ret = snd_soc_add_component_controls(component, tx_macro_snd_controls, - ARRAY_SIZE(tx_macro_snd_controls)); - if (ret < 0) { - dev_err(tx_dev, "%s: Failed to add snd_ctls\n", __func__); - return ret; + if (tx_priv->version >= BOLERO_VERSION_2_0) { + ret = snd_soc_add_component_controls(component, + tx_macro_snd_controls_common, + ARRAY_SIZE(tx_macro_snd_controls_common)); + if (ret < 0) { + dev_err(tx_dev, "%s: Failed to add snd_ctls\n", + __func__); + return ret; + } + if (tx_priv->version == BOLERO_VERSION_2_0) + ret = snd_soc_add_component_controls(component, + tx_macro_snd_controls_v3, + ARRAY_SIZE(tx_macro_snd_controls_v3)); + if (ret < 0) { + dev_err(tx_dev, "%s: Failed to add snd_ctls\n", + __func__); + return ret; + } + } else { + ret = snd_soc_add_component_controls(component, + tx_macro_snd_controls, + ARRAY_SIZE(tx_macro_snd_controls)); + if (ret < 0) { + dev_err(tx_dev, "%s: Failed to add snd_ctls\n", + __func__); + return ret; + } } snd_soc_dapm_ignore_suspend(dapm, "TX_AIF1 Capture"); snd_soc_dapm_ignore_suspend(dapm, "TX_AIF2 Capture"); snd_soc_dapm_ignore_suspend(dapm, "TX_AIF3 Capture"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC0"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC1"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC2"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC3"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC0"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC1"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC2"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC3"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC4"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC5"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC6"); - snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC7"); + if (tx_priv->version >= BOLERO_VERSION_2_0) { + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC0"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC1"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC2"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC3"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC4"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC5"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC6"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC7"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC8"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC9"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC10"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC11"); + } else { + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC0"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC1"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC2"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC3"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC0"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC4"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC5"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC6"); + snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC7"); + } snd_soc_dapm_sync(dapm); for (i = 0; i < NUM_DECIMATORS; i++) { diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index b7d6fe06df35..75f6328d3397 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -121,6 +121,7 @@ struct va_macro_priv { struct regulator *micb_supply; u32 micb_voltage; u32 micb_current; + u32 version; int micb_users; u16 default_clk_id; u16 clk_id; @@ -1118,6 +1119,28 @@ VA_MACRO_DAPM_ENUM_EXT(va_smic7, BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG0, 0, smic_mux_text, snd_soc_dapm_get_enum_double, va_macro_put_dec_enum); +static const char * const smic_mux_text_v2[] = { + "ZERO", "SWR_MIC0", "SWR_MIC1", "SWR_MIC2", "SWR_MIC3", + "SWR_MIC4", "SWR_MIC5", "SWR_MIC6", "SWR_MIC7", + "SWR_MIC8", "SWR_MIC9", "SWR_MIC10", "SWR_MIC11" +}; + +VA_MACRO_DAPM_ENUM_EXT(va_smic0_v2, BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0, + 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_smic1_v2, BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG0, + 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_smic2_v3, BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG0, + 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + +VA_MACRO_DAPM_ENUM_EXT(va_smic3_v3, BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG0, + 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double, + va_macro_put_dec_enum); + static const struct snd_kcontrol_new va_aif1_cap_mixer[] = { SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0, va_macro_tx_mixer_get, va_macro_tx_mixer_put), @@ -1175,6 +1198,194 @@ static const struct snd_kcontrol_new va_aif3_cap_mixer[] = { va_macro_tx_mixer_get, va_macro_tx_mixer_put), }; +static const struct snd_kcontrol_new va_aif1_cap_mixer_v2[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), +}; + +static const struct snd_kcontrol_new va_aif2_cap_mixer_v2[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), +}; + +static const struct snd_kcontrol_new va_aif3_cap_mixer_v2[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), +}; + +static const struct snd_kcontrol_new va_aif1_cap_mixer_v3[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, VA_MACRO_DEC2, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, VA_MACRO_DEC3, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), +}; + +static const struct snd_kcontrol_new va_aif2_cap_mixer_v3[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, VA_MACRO_DEC2, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, VA_MACRO_DEC3, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), +}; + +static const struct snd_kcontrol_new va_aif3_cap_mixer_v3[] = { + SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, VA_MACRO_DEC2, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), + SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, VA_MACRO_DEC3, 1, 0, + va_macro_tx_mixer_get, va_macro_tx_mixer_put), +}; + +static const struct snd_soc_dapm_widget va_macro_dapm_widgets_common[] = { + SND_SOC_DAPM_AIF_OUT_E("VA_AIF1 CAP", "VA_AIF1 Capture", 0, + SND_SOC_NOPM, VA_MACRO_AIF1_CAP, 0, + va_macro_enable_tx, SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_AIF_OUT_E("VA_AIF2 CAP", "VA_AIF2 Capture", 0, + SND_SOC_NOPM, VA_MACRO_AIF2_CAP, 0, + va_macro_enable_tx, SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_AIF_OUT_E("VA_AIF3 CAP", "VA_AIF3 Capture", 0, + SND_SOC_NOPM, VA_MACRO_AIF3_CAP, 0, + va_macro_enable_tx, SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD), + + VA_MACRO_DAPM_MUX("VA DMIC MUX0", 0, va_dmic0), + VA_MACRO_DAPM_MUX("VA DMIC MUX1", 0, va_dmic1), + + VA_MACRO_DAPM_MUX("VA SMIC MUX0", 0, va_smic0_v2), + VA_MACRO_DAPM_MUX("VA SMIC MUX1", 0, va_smic1_v2), + + SND_SOC_DAPM_INPUT("VA SWR_MIC0"), + SND_SOC_DAPM_INPUT("VA SWR_MIC1"), + SND_SOC_DAPM_INPUT("VA SWR_MIC2"), + SND_SOC_DAPM_INPUT("VA SWR_MIC3"), + SND_SOC_DAPM_INPUT("VA SWR_MIC4"), + SND_SOC_DAPM_INPUT("VA SWR_MIC5"), + SND_SOC_DAPM_INPUT("VA SWR_MIC6"), + SND_SOC_DAPM_INPUT("VA SWR_MIC7"), + SND_SOC_DAPM_INPUT("VA SWR_MIC8"), + SND_SOC_DAPM_INPUT("VA SWR_MIC9"), + SND_SOC_DAPM_INPUT("VA SWR_MIC10"), + SND_SOC_DAPM_INPUT("VA SWR_MIC11"), + + SND_SOC_DAPM_MICBIAS_E("VA MIC BIAS1", SND_SOC_NOPM, 0, 0, + va_macro_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("VA DMIC0", NULL, SND_SOC_NOPM, 0, 0, + va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("VA DMIC1", NULL, SND_SOC_NOPM, 0, 0, + va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("VA DMIC2", NULL, SND_SOC_NOPM, 0, 0, + va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("VA DMIC3", NULL, SND_SOC_NOPM, 0, 0, + va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("VA DMIC4", NULL, SND_SOC_NOPM, 0, 0, + va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("VA DMIC5", NULL, SND_SOC_NOPM, 0, 0, + va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("VA DMIC6", NULL, SND_SOC_NOPM, 0, 0, + va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("VA DMIC7", NULL, SND_SOC_NOPM, 0, 0, + va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("VA DEC0 MUX", SND_SOC_NOPM, VA_MACRO_DEC0, 0, + &va_dec0_mux, va_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("VA DEC1 MUX", SND_SOC_NOPM, VA_MACRO_DEC1, 0, + &va_dec1_mux, va_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0, + va_macro_mclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v2[] = { + SND_SOC_DAPM_MIXER("VA_AIF1_CAP Mixer", SND_SOC_NOPM, + VA_MACRO_AIF1_CAP, 0, + va_aif1_cap_mixer_v2, ARRAY_SIZE(va_aif1_cap_mixer_v2)), + + SND_SOC_DAPM_MIXER("VA_AIF2_CAP Mixer", SND_SOC_NOPM, + VA_MACRO_AIF2_CAP, 0, + va_aif2_cap_mixer_v2, ARRAY_SIZE(va_aif2_cap_mixer_v2)), + + SND_SOC_DAPM_MIXER("VA_AIF3_CAP Mixer", SND_SOC_NOPM, + VA_MACRO_AIF3_CAP, 0, + va_aif3_cap_mixer_v2, ARRAY_SIZE(va_aif3_cap_mixer_v2)), +}; + +static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v3[] = { + SND_SOC_DAPM_MIXER("VA_AIF1_CAP Mixer", SND_SOC_NOPM, + VA_MACRO_AIF1_CAP, 0, + va_aif1_cap_mixer_v3, ARRAY_SIZE(va_aif1_cap_mixer_v3)), + + SND_SOC_DAPM_MIXER("VA_AIF2_CAP Mixer", SND_SOC_NOPM, + VA_MACRO_AIF2_CAP, 0, + va_aif2_cap_mixer_v3, ARRAY_SIZE(va_aif2_cap_mixer_v3)), + + SND_SOC_DAPM_MIXER("VA_AIF3_CAP Mixer", SND_SOC_NOPM, + VA_MACRO_AIF3_CAP, 0, + va_aif3_cap_mixer_v3, ARRAY_SIZE(va_aif3_cap_mixer_v3)), + + VA_MACRO_DAPM_MUX("VA DMIC MUX2", 0, va_dmic2), + VA_MACRO_DAPM_MUX("VA DMIC MUX3", 0, va_dmic3), + + VA_MACRO_DAPM_MUX("VA SMIC MUX2", 0, va_smic2_v3), + VA_MACRO_DAPM_MUX("VA SMIC MUX3", 0, va_smic3_v3), + + SND_SOC_DAPM_MUX_E("VA DEC2 MUX", SND_SOC_NOPM, VA_MACRO_DEC2, 0, + &va_dec2_mux, va_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("VA DEC3 MUX", SND_SOC_NOPM, VA_MACRO_DEC3, 0, + &va_dec3_mux, va_macro_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0, + va_macro_swr_pwr_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT_E("VA_AIF1 CAP", "VA_AIF1 Capture", 0, SND_SOC_NOPM, VA_MACRO_AIF1_CAP, 0, @@ -1325,6 +1536,146 @@ static const struct snd_soc_dapm_widget va_macro_wod_dapm_widgets[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; +static const struct snd_soc_dapm_route va_audio_map_common[] = { + {"VA_AIF1 CAP", NULL, "VA_MCLK"}, + {"VA_AIF2 CAP", NULL, "VA_MCLK"}, + {"VA_AIF3 CAP", NULL, "VA_MCLK"}, + + {"VA_AIF1 CAP", NULL, "VA_AIF1_CAP Mixer"}, + {"VA_AIF2 CAP", NULL, "VA_AIF2_CAP Mixer"}, + {"VA_AIF3 CAP", NULL, "VA_AIF3_CAP Mixer"}, + + {"VA_AIF1_CAP Mixer", "DEC0", "VA DEC0 MUX"}, + {"VA_AIF1_CAP Mixer", "DEC1", "VA DEC1 MUX"}, + + {"VA_AIF2_CAP Mixer", "DEC0", "VA DEC0 MUX"}, + {"VA_AIF2_CAP Mixer", "DEC1", "VA DEC1 MUX"}, + + {"VA_AIF3_CAP Mixer", "DEC0", "VA DEC0 MUX"}, + {"VA_AIF3_CAP Mixer", "DEC1", "VA DEC1 MUX"}, + + {"VA DEC0 MUX", "MSM_DMIC", "VA DMIC MUX0"}, + {"VA DMIC MUX0", "DMIC0", "VA DMIC0"}, + {"VA DMIC MUX0", "DMIC1", "VA DMIC1"}, + {"VA DMIC MUX0", "DMIC2", "VA DMIC2"}, + {"VA DMIC MUX0", "DMIC3", "VA DMIC3"}, + {"VA DMIC MUX0", "DMIC4", "VA DMIC4"}, + {"VA DMIC MUX0", "DMIC5", "VA DMIC5"}, + {"VA DMIC MUX0", "DMIC6", "VA DMIC6"}, + {"VA DMIC MUX0", "DMIC7", "VA DMIC7"}, + + {"VA DEC0 MUX", "SWR_MIC", "VA SMIC MUX0"}, + {"VA SMIC MUX0", "SWR_MIC0", "VA SWR_MIC0"}, + {"VA SMIC MUX0", "SWR_MIC1", "VA SWR_MIC1"}, + {"VA SMIC MUX0", "SWR_MIC2", "VA SWR_MIC2"}, + {"VA SMIC MUX0", "SWR_MIC3", "VA SWR_MIC3"}, + {"VA SMIC MUX0", "SWR_MIC4", "VA SWR_MIC4"}, + {"VA SMIC MUX0", "SWR_MIC5", "VA SWR_MIC5"}, + {"VA SMIC MUX0", "SWR_MIC6", "VA SWR_MIC6"}, + {"VA SMIC MUX0", "SWR_MIC7", "VA SWR_MIC7"}, + {"VA SMIC MUX0", "SWR_MIC8", "VA SWR_MIC8"}, + {"VA SMIC MUX0", "SWR_MIC9", "VA SWR_MIC9"}, + {"VA SMIC MUX0", "SWR_MIC10", "VA SWR_MIC10"}, + {"VA SMIC MUX0", "SWR_MIC11", "VA SWR_MIC11"}, + + {"VA DEC1 MUX", "MSM_DMIC", "VA DMIC MUX1"}, + {"VA DMIC MUX1", "DMIC0", "VA DMIC0"}, + {"VA DMIC MUX1", "DMIC1", "VA DMIC1"}, + {"VA DMIC MUX1", "DMIC2", "VA DMIC2"}, + {"VA DMIC MUX1", "DMIC3", "VA DMIC3"}, + {"VA DMIC MUX1", "DMIC4", "VA DMIC4"}, + {"VA DMIC MUX1", "DMIC5", "VA DMIC5"}, + {"VA DMIC MUX1", "DMIC6", "VA DMIC6"}, + {"VA DMIC MUX1", "DMIC7", "VA DMIC7"}, + + {"VA DEC1 MUX", "SWR_MIC", "VA SMIC MUX1"}, + {"VA SMIC MUX1", "SWR_MIC0", "VA SWR_MIC0"}, + {"VA SMIC MUX1", "SWR_MIC1", "VA SWR_MIC1"}, + {"VA SMIC MUX1", "SWR_MIC2", "VA SWR_MIC2"}, + {"VA SMIC MUX1", "SWR_MIC3", "VA SWR_MIC3"}, + {"VA SMIC MUX1", "SWR_MIC4", "VA SWR_MIC4"}, + {"VA SMIC MUX1", "SWR_MIC5", "VA SWR_MIC5"}, + {"VA SMIC MUX1", "SWR_MIC6", "VA SWR_MIC6"}, + {"VA SMIC MUX1", "SWR_MIC7", "VA SWR_MIC7"}, + {"VA SMIC MUX1", "SWR_MIC8", "VA SWR_MIC8"}, + {"VA SMIC MUX1", "SWR_MIC9", "VA SWR_MIC9"}, + {"VA SMIC MUX1", "SWR_MIC10", "VA SWR_MIC10"}, + {"VA SMIC MUX1", "SWR_MIC11", "VA SWR_MIC11"}, + + {"VA SWR_MIC0", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC1", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC2", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC3", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC4", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC5", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC6", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC7", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC8", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC9", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC10", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC11", NULL, "VA_SWR_PWR"}, + +}; + +static const struct snd_soc_dapm_route va_audio_map_v3[] = { + {"VA_AIF1_CAP Mixer", "DEC2", "VA DEC2 MUX"}, + {"VA_AIF1_CAP Mixer", "DEC3", "VA DEC3 MUX"}, + + {"VA_AIF2_CAP Mixer", "DEC2", "VA DEC2 MUX"}, + {"VA_AIF2_CAP Mixer", "DEC3", "VA DEC3 MUX"}, + + {"VA_AIF3_CAP Mixer", "DEC2", "VA DEC2 MUX"}, + {"VA_AIF3_CAP Mixer", "DEC3", "VA DEC3 MUX"}, + + {"VA DEC2 MUX", "MSM_DMIC", "VA DMIC MUX2"}, + {"VA DMIC MUX2", "DMIC0", "VA DMIC0"}, + {"VA DMIC MUX2", "DMIC1", "VA DMIC1"}, + {"VA DMIC MUX2", "DMIC2", "VA DMIC2"}, + {"VA DMIC MUX2", "DMIC3", "VA DMIC3"}, + {"VA DMIC MUX2", "DMIC4", "VA DMIC4"}, + {"VA DMIC MUX2", "DMIC5", "VA DMIC5"}, + {"VA DMIC MUX2", "DMIC6", "VA DMIC6"}, + {"VA DMIC MUX2", "DMIC7", "VA DMIC7"}, + + {"VA DEC2 MUX", "SWR_MIC", "VA SMIC MUX2"}, + {"VA SMIC MUX2", "SWR_MIC0", "VA SWR_MIC0"}, + {"VA SMIC MUX2", "SWR_MIC1", "VA SWR_MIC1"}, + {"VA SMIC MUX2", "SWR_MIC2", "VA SWR_MIC2"}, + {"VA SMIC MUX2", "SWR_MIC3", "VA SWR_MIC3"}, + {"VA SMIC MUX2", "SWR_MIC4", "VA SWR_MIC4"}, + {"VA SMIC MUX2", "SWR_MIC5", "VA SWR_MIC5"}, + {"VA SMIC MUX2", "SWR_MIC6", "VA SWR_MIC6"}, + {"VA SMIC MUX2", "SWR_MIC7", "VA SWR_MIC7"}, + {"VA SMIC MUX2", "SWR_MIC8", "VA SWR_MIC8"}, + {"VA SMIC MUX2", "SWR_MIC9", "VA SWR_MIC9"}, + {"VA SMIC MUX2", "SWR_MIC10", "VA SWR_MIC10"}, + {"VA SMIC MUX2", "SWR_MIC11", "VA SWR_MIC11"}, + + {"VA DEC3 MUX", "MSM_DMIC", "VA DMIC MUX3"}, + {"VA DMIC MUX3", "DMIC0", "VA DMIC0"}, + {"VA DMIC MUX3", "DMIC1", "VA DMIC1"}, + {"VA DMIC MUX3", "DMIC2", "VA DMIC2"}, + {"VA DMIC MUX3", "DMIC3", "VA DMIC3"}, + {"VA DMIC MUX3", "DMIC4", "VA DMIC4"}, + {"VA DMIC MUX3", "DMIC5", "VA DMIC5"}, + {"VA DMIC MUX3", "DMIC6", "VA DMIC6"}, + {"VA DMIC MUX3", "DMIC7", "VA DMIC7"}, + + {"VA DEC3 MUX", "SWR_MIC", "VA SMIC MUX3"}, + {"VA SMIC MUX3", "SWR_MIC0", "VA SWR_MIC0"}, + {"VA SMIC MUX3", "SWR_MIC1", "VA SWR_MIC1"}, + {"VA SMIC MUX3", "SWR_MIC2", "VA SWR_MIC2"}, + {"VA SMIC MUX3", "SWR_MIC3", "VA SWR_MIC3"}, + {"VA SMIC MUX3", "SWR_MIC4", "VA SWR_MIC4"}, + {"VA SMIC MUX3", "SWR_MIC5", "VA SWR_MIC5"}, + {"VA SMIC MUX3", "SWR_MIC6", "VA SWR_MIC6"}, + {"VA SMIC MUX3", "SWR_MIC7", "VA SWR_MIC7"}, + {"VA SMIC MUX3", "SWR_MIC8", "VA SWR_MIC8"}, + {"VA SMIC MUX3", "SWR_MIC9", "VA SWR_MIC9"}, + {"VA SMIC MUX3", "SWR_MIC10", "VA SWR_MIC10"}, + {"VA SMIC MUX3", "SWR_MIC11", "VA SWR_MIC11"}, +}; + static const struct snd_soc_dapm_route va_audio_map[] = { {"VA_AIF1 CAP", NULL, "VA_MCLK"}, {"VA_AIF2 CAP", NULL, "VA_MCLK"}, @@ -1586,6 +1937,24 @@ static const struct snd_kcontrol_new va_macro_snd_controls[] = { 0, -84, 40, digital_gain), }; +static const struct snd_kcontrol_new va_macro_snd_controls_common[] = { + SOC_SINGLE_SX_TLV("VA_DEC0 Volume", + BOLERO_CDC_VA_TX0_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("VA_DEC1 Volume", + BOLERO_CDC_VA_TX1_TX_VOL_CTL, + 0, -84, 40, digital_gain), +}; + +static const struct snd_kcontrol_new va_macro_snd_controls_v3[] = { + SOC_SINGLE_SX_TLV("VA_DEC2 Volume", + BOLERO_CDC_VA_TX2_TX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("VA_DEC3 Volume", + BOLERO_CDC_VA_TX3_TX_VOL_CTL, + 0, -84, 40, digital_gain), +}; + static int va_macro_validate_dmic_sample_rate(u32 dmic_sample_rate, struct va_macro_priv *va_priv) { @@ -1670,18 +2039,65 @@ static int va_macro_init(struct snd_soc_component *component) return 0; } - ret = snd_soc_dapm_new_controls(dapm, va_macro_dapm_widgets, + va_priv->version = bolero_get_version(va_dev); + if (va_priv->version >= BOLERO_VERSION_2_0) { + ret = snd_soc_dapm_new_controls(dapm, + va_macro_dapm_widgets_common, + ARRAY_SIZE(va_macro_dapm_widgets_common)); + if (ret < 0) { + dev_err(va_dev, "%s: Failed to add controls\n", + __func__); + return ret; + } + if (va_priv->version == BOLERO_VERSION_2_1) + ret = snd_soc_dapm_new_controls(dapm, + va_macro_dapm_widgets_v2, + ARRAY_SIZE(va_macro_dapm_widgets_v2)); + else if (va_priv->version == BOLERO_VERSION_2_0) + ret = snd_soc_dapm_new_controls(dapm, + va_macro_dapm_widgets_v3, + ARRAY_SIZE(va_macro_dapm_widgets_v3)); + if (ret < 0) { + dev_err(va_dev, "%s: Failed to add controls\n", + __func__); + return ret; + } + } else { + ret = snd_soc_dapm_new_controls(dapm, va_macro_dapm_widgets, ARRAY_SIZE(va_macro_dapm_widgets)); - if (ret < 0) { - dev_err(va_dev, "%s: Failed to add controls\n", __func__); - return ret; + if (ret < 0) { + dev_err(va_dev, "%s: Failed to add controls\n", + __func__); + return ret; + } } - ret = snd_soc_dapm_add_routes(dapm, va_audio_map, + if (va_priv->version >= BOLERO_VERSION_2_0) { + ret = snd_soc_dapm_add_routes(dapm, + va_audio_map_common, + ARRAY_SIZE(va_audio_map_common)); + if (ret < 0) { + dev_err(va_dev, "%s: Failed to add routes\n", + __func__); + return ret; + } + if (va_priv->version == BOLERO_VERSION_2_0) + ret = snd_soc_dapm_add_routes(dapm, + va_audio_map_v3, + ARRAY_SIZE(va_audio_map_v3)); + if (ret < 0) { + dev_err(va_dev, "%s: Failed to add routes\n", + __func__); + return ret; + } + } else { + ret = snd_soc_dapm_add_routes(dapm, va_audio_map, ARRAY_SIZE(va_audio_map)); - if (ret < 0) { - dev_err(va_dev, "%s: Failed to add routes\n", __func__); - return ret; + if (ret < 0) { + dev_err(va_dev, "%s: Failed to add routes\n", + __func__); + return ret; + } } ret = snd_soc_dapm_new_widgets(dapm->card); @@ -1689,28 +2105,65 @@ static int va_macro_init(struct snd_soc_component *component) dev_err(va_dev, "%s: Failed to add widgets\n", __func__); return ret; } - ret = snd_soc_add_component_controls(component, va_macro_snd_controls, - ARRAY_SIZE(va_macro_snd_controls)); - if (ret < 0) { - dev_err(va_dev, "%s: Failed to add snd_ctls\n", __func__); - return ret; + if (va_priv->version >= BOLERO_VERSION_2_0) { + ret = snd_soc_add_component_controls(component, + va_macro_snd_controls_common, + ARRAY_SIZE(va_macro_snd_controls_common)); + if (ret < 0) { + dev_err(va_dev, "%s: Failed to add snd_ctls\n", + __func__); + return ret; + } + if (va_priv->version == BOLERO_VERSION_2_0) + ret = snd_soc_add_component_controls(component, + va_macro_snd_controls_v3, + ARRAY_SIZE(va_macro_snd_controls_v3)); + if (ret < 0) { + dev_err(va_dev, "%s: Failed to add snd_ctls\n", + __func__); + return ret; + } + } else { + ret = snd_soc_add_component_controls(component, + va_macro_snd_controls, + ARRAY_SIZE(va_macro_snd_controls)); + if (ret < 0) { + dev_err(va_dev, "%s: Failed to add snd_ctls\n", + __func__); + return ret; + } } snd_soc_dapm_ignore_suspend(dapm, "VA_AIF1 Capture"); snd_soc_dapm_ignore_suspend(dapm, "VA_AIF2 Capture"); snd_soc_dapm_ignore_suspend(dapm, "VA_AIF3 Capture"); - snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC0"); - snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC1"); - snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC2"); - snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC3"); - snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC0"); - snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC1"); - snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC2"); - snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC3"); - snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC4"); - snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC5"); - snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC6"); - snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC7"); + if (va_priv->version >= BOLERO_VERSION_2_0) { + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC0"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC1"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC2"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC3"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC4"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC5"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC6"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC7"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC8"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC9"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC10"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC11"); + } else { + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC0"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC1"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC2"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC3"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC0"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC1"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC2"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC3"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC4"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC5"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC6"); + snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC7"); + } snd_soc_dapm_sync(dapm); for (i = 0; i < VA_MACRO_NUM_DECIMATORS; i++) { -- GitLab From 2e13d64340eef69b5bfa72e5e451fbef3228d1a6 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Sat, 12 Oct 2019 01:36:30 +0530 Subject: [PATCH 1266/1645] asoc: bolero: Update SWR TX moved to AO region In bengal target, SWR TX moved to AO region. Update SWR TX as child of VA macro and handle respective SWR register/clock sequences from VA macro. Change-Id: I6b632ce56a885f2ccc8516840b0e5d270fe0b2c0 Signed-off-by: Laxminath Kasam --- asoc/bengal-port-config.h | 2 +- asoc/codecs/bolero/bolero-cdc-registers.h | 1 + asoc/codecs/bolero/bolero-cdc-regmap.c | 1 + asoc/codecs/bolero/bolero-cdc-tables.c | 2 + asoc/codecs/bolero/tx-macro.c | 50 +- asoc/codecs/bolero/va-macro.c | 541 ++++++++++++++++++++++ 6 files changed, 575 insertions(+), 22 deletions(-) diff --git a/asoc/bengal-port-config.h b/asoc/bengal-port-config.h index 99899632c17a..4ac7e10c0d42 100644 --- a/asoc/bengal-port-config.h +++ b/asoc/bengal-port-config.h @@ -37,7 +37,7 @@ static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = { }; static struct swr_mstr_port_map sm_port_map[] = { - {TX_MACRO, SWR_UC0, tx_frame_params_default}, + {VA_MACRO, SWR_UC0, tx_frame_params_default}, {RX_MACRO, SWR_UC0, rx_frame_params_default}, {RX_MACRO, SWR_UC1, rx_frame_params_dsd}, }; diff --git a/asoc/codecs/bolero/bolero-cdc-registers.h b/asoc/codecs/bolero/bolero-cdc-registers.h index 99890cc9fb9d..c59bb866147e 100644 --- a/asoc/codecs/bolero/bolero-cdc-registers.h +++ b/asoc/codecs/bolero/bolero-cdc-registers.h @@ -696,6 +696,7 @@ #define BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL (VA_START_OFFSET + 0x0000) #define BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL \ (VA_START_OFFSET + 0x0004) +#define BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL (VA_START_OFFSET + 0x0008) #define BOLERO_CDC_VA_TOP_CSR_TOP_CFG0 (VA_START_OFFSET + 0x0080) #define BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL (VA_START_OFFSET + 0x0084) #define BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL (VA_START_OFFSET + 0x0088) diff --git a/asoc/codecs/bolero/bolero-cdc-regmap.c b/asoc/codecs/bolero/bolero-cdc-regmap.c index 037f9aa96878..90829665e01a 100644 --- a/asoc/codecs/bolero/bolero-cdc-regmap.c +++ b/asoc/codecs/bolero/bolero-cdc-regmap.c @@ -609,6 +609,7 @@ static const struct reg_default bolero_defaults[] = { /* VA macro */ { BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, 0x00}, { BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00}, + { BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL, 0x00}, { BOLERO_CDC_VA_TOP_CSR_TOP_CFG0, 0x00}, { BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL, 0x00}, { BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL, 0x00}, diff --git a/asoc/codecs/bolero/bolero-cdc-tables.c b/asoc/codecs/bolero/bolero-cdc-tables.c index 529876336897..81639b39b395 100644 --- a/asoc/codecs/bolero/bolero-cdc-tables.c +++ b/asoc/codecs/bolero/bolero-cdc-tables.c @@ -442,6 +442,7 @@ u8 bolero_rx_reg_access[BOLERO_CDC_RX_MACRO_MAX] = { u8 bolero_va_reg_access[BOLERO_CDC_VA_MACRO_MAX] = { [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG, [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG, [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TOP_CFG0)] = RD_WR_REG, [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL)] = RD_WR_REG, [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL)] = RD_WR_REG, @@ -567,6 +568,7 @@ u8 bolero_va_reg_access[BOLERO_CDC_VA_MACRO_MAX] = { u8 bolero_va_top_reg_access[BOLERO_CDC_VA_MACRO_TOP_MAX] = { [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG, [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG, [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TOP_CFG0)] = RD_WR_REG, [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL)] = RD_WR_REG, [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL)] = RD_WR_REG, diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 70f269b252e6..3ed92a6f917f 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -161,6 +161,7 @@ struct tx_macro_priv { s32 dmic_6_7_clk_cnt; u16 dmic_clk_div; u32 version; + u32 is_used_tx_swr_gpio; unsigned long active_ch_mask[TX_MACRO_MAX_DAIS]; unsigned long active_ch_cnt[TX_MACRO_MAX_DAIS]; char __iomem *tx_io_base; @@ -3046,19 +3047,21 @@ static int tx_macro_probe(struct platform_device *pdev) sample_rate, tx_priv) == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED) return -EINVAL; } - tx_priv->reset_swr = true; - INIT_WORK(&tx_priv->tx_macro_add_child_devices_work, - tx_macro_add_child_devices); - tx_priv->swr_plat_data.handle = (void *) tx_priv; - tx_priv->swr_plat_data.read = NULL; - tx_priv->swr_plat_data.write = NULL; - tx_priv->swr_plat_data.bulk_write = NULL; - tx_priv->swr_plat_data.clk = tx_macro_swrm_clock; - tx_priv->swr_plat_data.core_vote = tx_macro_core_vote; - tx_priv->swr_plat_data.handle_irq = NULL; - + if (is_used_tx_swr_gpio) { + tx_priv->reset_swr = true; + INIT_WORK(&tx_priv->tx_macro_add_child_devices_work, + tx_macro_add_child_devices); + tx_priv->swr_plat_data.handle = (void *) tx_priv; + tx_priv->swr_plat_data.read = NULL; + tx_priv->swr_plat_data.write = NULL; + tx_priv->swr_plat_data.bulk_write = NULL; + tx_priv->swr_plat_data.clk = tx_macro_swrm_clock; + tx_priv->swr_plat_data.core_vote = tx_macro_core_vote; + tx_priv->swr_plat_data.handle_irq = NULL; + mutex_init(&tx_priv->swr_clk_lock); + } + tx_priv->is_used_tx_swr_gpio = is_used_tx_swr_gpio; mutex_init(&tx_priv->mclk_lock); - mutex_init(&tx_priv->swr_clk_lock); tx_macro_init_ops(&ops, tx_io_base); ops.clk_id_req = TX_CORE_CLK; ops.default_clk_id = TX_CORE_CLK; @@ -3068,8 +3071,8 @@ static int tx_macro_probe(struct platform_device *pdev) "%s: register macro failed\n", __func__); goto err_reg_macro; } - - schedule_work(&tx_priv->tx_macro_add_child_devices_work); + if (is_used_tx_swr_gpio) + schedule_work(&tx_priv->tx_macro_add_child_devices_work); pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); @@ -3079,7 +3082,8 @@ static int tx_macro_probe(struct platform_device *pdev) return 0; err_reg_macro: mutex_destroy(&tx_priv->mclk_lock); - mutex_destroy(&tx_priv->swr_clk_lock); + if (is_used_tx_swr_gpio) + mutex_destroy(&tx_priv->swr_clk_lock); return ret; } @@ -3093,16 +3097,20 @@ static int tx_macro_remove(struct platform_device *pdev) if (!tx_priv) return -EINVAL; - if (tx_priv->swr_ctrl_data) - kfree(tx_priv->swr_ctrl_data); - for (count = 0; count < tx_priv->child_count && - count < TX_MACRO_CHILD_DEVICES_MAX; count++) - platform_device_unregister(tx_priv->pdev_child_devices[count]); + if (tx_priv->is_used_tx_swr_gpio) { + if (tx_priv->swr_ctrl_data) + kfree(tx_priv->swr_ctrl_data); + for (count = 0; count < tx_priv->child_count && + count < TX_MACRO_CHILD_DEVICES_MAX; count++) + platform_device_unregister( + tx_priv->pdev_child_devices[count]); + } pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); mutex_destroy(&tx_priv->mclk_lock); - mutex_destroy(&tx_priv->swr_clk_lock); + if (tx_priv->is_used_tx_swr_gpio) + mutex_destroy(&tx_priv->swr_clk_lock); bolero_unregister_macro(&pdev->dev, TX_MACRO); return 0; } diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 75f6328d3397..2150d286a509 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -13,6 +13,9 @@ #include #include #include +#include +#include +#include #include "bolero-cdc.h" #include "bolero-cdc-registers.h" #include "bolero-clk-rsc.h" @@ -46,6 +49,9 @@ #define BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS 40 #define MAX_RETRY_ATTEMPTS 500 +#define VA_MACRO_SWR_STRING_LEN 80 +#define VA_MACRO_CHILD_DEVICES_MAX 3 + static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); static int va_tx_unmute_delay = BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS; module_param(va_tx_unmute_delay, int, 0664); @@ -85,6 +91,11 @@ enum { SWR_MIC, }; +enum { + TX_MCLK, + VA_MCLK, +}; + struct va_mute_work { struct va_macro_priv *va_priv; u32 decimator; @@ -98,12 +109,31 @@ struct hpf_work { struct delayed_work dwork; }; +/* Hold instance to soundwire platform device */ +struct va_macro_swr_ctrl_data { + struct platform_device *va_swr_pdev; +}; + +struct va_macro_swr_ctrl_platform_data { + void *handle; /* holds codec private data */ + int (*read)(void *handle, int reg); + int (*write)(void *handle, int reg, int val); + int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); + int (*clk)(void *handle, bool enable); + int (*handle_irq)(void *handle, + irqreturn_t (*swrm_irq_handler)(int irq, + void *data), + void *swrm_handle, + int action); +}; + struct va_macro_priv { struct device *dev; bool dec_active[VA_MACRO_NUM_DECIMATORS]; bool va_without_decimation; struct clk *lpass_audio_hw_vote; struct mutex mclk_lock; + struct mutex swr_clk_lock; struct snd_soc_component *component; struct hpf_work va_hpf_work[VA_MACRO_NUM_DECIMATORS]; struct va_mute_work va_mute_dwork[VA_MACRO_NUM_DECIMATORS]; @@ -115,16 +145,29 @@ struct va_macro_priv { s32 dmic_6_7_clk_cnt; u16 dmic_clk_div; u16 va_mclk_users; + int swr_clk_users; + bool reset_swr; + struct device_node *va_swr_gpio_p; + struct va_macro_swr_ctrl_data *swr_ctrl_data; + struct va_macro_swr_ctrl_platform_data swr_plat_data; + struct work_struct va_macro_add_child_devices_work; + int child_count; u16 mclk_mux_sel; char __iomem *va_io_base; char __iomem *va_island_mode_muxsel; + struct platform_device *pdev_child_devices + [VA_MACRO_CHILD_DEVICES_MAX]; struct regulator *micb_supply; u32 micb_voltage; u32 micb_current; u32 version; + u32 is_used_va_swr_gpio; int micb_users; u16 default_clk_id; u16 clk_id; + int tx_swr_clk_cnt; + int va_swr_clk_cnt; + int va_clk_status; int tx_clk_status; }; @@ -250,10 +293,25 @@ static int va_macro_event_handler(struct snd_soc_component *component, bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, VA_CORE_CLK, false); + /* reset swr after ssr/pdr */ + va_priv->reset_swr = true; + if (va_priv->swr_ctrl_data) + swrm_wcd_notify( + va_priv->swr_ctrl_data[0].va_swr_pdev, + SWR_DEVICE_SSR_UP, NULL); + break; case BOLERO_MACRO_EVT_CLK_RESET: bolero_rsc_clk_reset(va_dev, VA_CORE_CLK); break; case BOLERO_MACRO_EVT_SSR_DOWN: + if (va_priv->swr_ctrl_data) { + swrm_wcd_notify( + va_priv->swr_ctrl_data[0].va_swr_pdev, + SWR_DEVICE_DOWN, NULL); + swrm_wcd_notify( + va_priv->swr_ctrl_data[0].va_swr_pdev, + SWR_DEVICE_SSR_DOWN, NULL); + } if ((!pm_runtime_enabled(va_dev) || !pm_runtime_suspended(va_dev))) { ret = bolero_runtime_suspend(va_dev); @@ -270,6 +328,54 @@ static int va_macro_event_handler(struct snd_soc_component *component, return 0; } +static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + int ret = 0; + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) + return -EINVAL; + + dev_dbg(va_dev, "%s: event = %d\n", __func__, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + va_priv->va_swr_clk_cnt++; + if (va_priv->swr_ctrl_data) { + ret = swrm_wcd_notify( + va_priv->swr_ctrl_data[0].va_swr_pdev, + SWR_REQ_CLK_SWITCH, NULL); + if (ret) + dev_dbg(va_dev, "%s: clock switch failed\n", + __func__); + } + msm_cdc_pinctrl_set_wakeup_capable( + va_priv->va_swr_gpio_p, false); + break; + case SND_SOC_DAPM_POST_PMD: + msm_cdc_pinctrl_set_wakeup_capable( + va_priv->va_swr_gpio_p, true); + if (va_priv->swr_ctrl_data) { + ret = swrm_wcd_notify( + va_priv->swr_ctrl_data[0].va_swr_pdev, + SWR_REQ_CLK_SWITCH, NULL); + if (ret) + dev_dbg(va_dev, "%s: clock switch failed\n", + __func__); + } + va_priv->va_swr_clk_cnt--; + break; + default: + dev_err(va_priv->dev, + "%s: invalid DAPM event %d\n", __func__, event); + ret = -EINVAL; + } + return ret; +} + static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -313,6 +419,25 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, return ret; } +static int va_macro_tx_swr_clk_event_v2(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) + return -EINVAL; + + if (SND_SOC_DAPM_EVENT_ON(event)) + ++va_priv->tx_swr_clk_cnt; + if (SND_SOC_DAPM_EVENT_OFF(event)) + --va_priv->tx_swr_clk_cnt; + + return 0; +} + static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -354,6 +479,204 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, return ret; } +static int va_macro_tx_va_mclk_enable(struct va_macro_priv *va_priv, + struct regmap *regmap, int clk_type, + bool enable) +{ + int ret = 0, clk_tx_ret = 0; + + dev_dbg(va_priv->dev, + "%s: clock type %s, enable: %s tx_mclk_users: %d\n", + __func__, (clk_type ? "VA_MCLK" : "TX_MCLK"), + (enable ? "enable" : "disable"), va_priv->va_mclk_users); + + if (enable) { + if (va_priv->swr_clk_users == 0) + msm_cdc_pinctrl_select_active_state( + va_priv->va_swr_gpio_p); + clk_tx_ret = bolero_clk_rsc_request_clock(va_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + true); + if (clk_type == TX_MCLK) { + ret = bolero_clk_rsc_request_clock(va_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + true); + if (ret < 0) { + if (va_priv->swr_clk_users == 0) + msm_cdc_pinctrl_select_sleep_state( + va_priv->va_swr_gpio_p); + dev_err_ratelimited(va_priv->dev, + "%s: swr request clk failed\n", + __func__); + goto done; + } + bolero_clk_rsc_fs_gen_request(va_priv->dev, + true); + } + if (clk_type == VA_MCLK) { + ret = va_macro_mclk_enable(va_priv, 1, true); + if (ret < 0) { + if (va_priv->swr_clk_users == 0) + msm_cdc_pinctrl_select_sleep_state( + va_priv->va_swr_gpio_p); + dev_err_ratelimited(va_priv->dev, + "%s: request clock enable failed\n", + __func__); + goto done; + } + } + if (va_priv->swr_clk_users == 0) { + dev_dbg(va_priv->dev, "%s: reset_swr: %d\n", + __func__, va_priv->reset_swr); + if (va_priv->reset_swr) + regmap_update_bits(regmap, + BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL, + 0x02, 0x02); + regmap_update_bits(regmap, + BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x01); + if (va_priv->reset_swr) + regmap_update_bits(regmap, + BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL, + 0x02, 0x00); + va_priv->reset_swr = false; + } + if (!clk_tx_ret) + ret = bolero_clk_rsc_request_clock(va_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + false); + va_priv->swr_clk_users++; + } else { + if (va_priv->swr_clk_users <= 0) { + dev_err_ratelimited(va_priv->dev, + "va swrm clock users already 0\n"); + va_priv->swr_clk_users = 0; + return 0; + } + clk_tx_ret = bolero_clk_rsc_request_clock(va_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + true); + va_priv->swr_clk_users--; + if (va_priv->swr_clk_users == 0) + regmap_update_bits(regmap, + BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x00); + if (clk_type == VA_MCLK) + va_macro_mclk_enable(va_priv, 0, true); + if (clk_type == TX_MCLK) { + bolero_clk_rsc_fs_gen_request(va_priv->dev, + false); + ret = bolero_clk_rsc_request_clock(va_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + false); + if (ret < 0) { + dev_err_ratelimited(va_priv->dev, + "%s: swr request clk failed\n", + __func__); + goto done; + } + } + if (!clk_tx_ret) + ret = bolero_clk_rsc_request_clock(va_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + false); + if (va_priv->swr_clk_users == 0) + msm_cdc_pinctrl_select_sleep_state( + va_priv->va_swr_gpio_p); + } + return 0; + +done: + if (!clk_tx_ret) + bolero_clk_rsc_request_clock(va_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + false); + return ret; +} + +static int va_macro_swrm_clock(void *handle, bool enable) +{ + struct va_macro_priv *va_priv = (struct va_macro_priv *) handle; + struct regmap *regmap = dev_get_regmap(va_priv->dev->parent, NULL); + int ret = 0; + + if (regmap == NULL) { + dev_err(va_priv->dev, "%s: regmap is NULL\n", __func__); + return -EINVAL; + } + + mutex_lock(&va_priv->swr_clk_lock); + dev_dbg(va_priv->dev, + "%s: swrm clock %s tx_swr_clk_cnt: %d va_swr_clk_cnt: %d\n", + __func__, (enable ? "enable" : "disable"), + va_priv->tx_swr_clk_cnt, va_priv->va_swr_clk_cnt); + + if (enable) { + pm_runtime_get_sync(va_priv->dev); + if (va_priv->va_swr_clk_cnt && !va_priv->tx_swr_clk_cnt) { + ret = va_macro_tx_va_mclk_enable(va_priv, regmap, + VA_MCLK, enable); + if (ret) + goto done; + va_priv->va_clk_status++; + } else { + ret = va_macro_tx_va_mclk_enable(va_priv, regmap, + TX_MCLK, enable); + if (ret) + goto done; + va_priv->tx_clk_status++; + } + pm_runtime_mark_last_busy(va_priv->dev); + pm_runtime_put_autosuspend(va_priv->dev); + } else { + if (va_priv->va_clk_status && !va_priv->tx_clk_status) { + ret = va_macro_tx_va_mclk_enable(va_priv, regmap, + VA_MCLK, enable); + if (ret) + goto done; + --va_priv->va_clk_status; + } else if (!va_priv->va_clk_status && va_priv->tx_clk_status) { + ret = va_macro_tx_va_mclk_enable(va_priv, regmap, + TX_MCLK, enable); + if (ret) + goto done; + --va_priv->tx_clk_status; + } else if (va_priv->va_clk_status && va_priv->tx_clk_status) { + if (!va_priv->va_swr_clk_cnt && va_priv->tx_swr_clk_cnt) { + ret = va_macro_tx_va_mclk_enable(va_priv, regmap, + VA_MCLK, enable); + if (ret) + goto done; + --va_priv->va_clk_status; + } else { + ret = va_macro_tx_va_mclk_enable(va_priv, regmap, + TX_MCLK, enable); + if (ret) + goto done; + --va_priv->tx_clk_status; + } + + } else { + dev_dbg(va_priv->dev, + "%s: Both clocks are disabled\n", __func__); + } + } + dev_dbg(va_priv->dev, + "%s: swrm clock users %d tx_clk_sts_cnt: %d va_clk_sts_cnt: %d\n", + __func__, va_priv->swr_clk_users, va_priv->tx_clk_status, + va_priv->va_clk_status); +done: + mutex_unlock(&va_priv->swr_clk_lock); + return ret; +} + static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) { struct delayed_work *hpf_delayed_work; @@ -1350,6 +1673,14 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v2[] = { SND_SOC_DAPM_MIXER("VA_AIF3_CAP Mixer", SND_SOC_NOPM, VA_MACRO_AIF3_CAP, 0, va_aif3_cap_mixer_v2, ARRAY_SIZE(va_aif3_cap_mixer_v2)), + + SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0, + va_macro_swr_pwr_event_v2, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("VA_TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, + va_macro_tx_swr_clk_event_v2, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v3[] = { @@ -2196,6 +2527,156 @@ static int va_macro_deinit(struct snd_soc_component *component) return 0; } +static void va_macro_add_child_devices(struct work_struct *work) +{ + struct va_macro_priv *va_priv = NULL; + struct platform_device *pdev = NULL; + struct device_node *node = NULL; + struct va_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp = NULL; + int ret = 0; + u16 count = 0, ctrl_num = 0; + struct va_macro_swr_ctrl_platform_data *platdata = NULL; + char plat_dev_name[VA_MACRO_SWR_STRING_LEN] = ""; + bool va_swr_master_node = false; + + va_priv = container_of(work, struct va_macro_priv, + va_macro_add_child_devices_work); + if (!va_priv) { + pr_err("%s: Memory for va_priv does not exist\n", + __func__); + return; + } + + if (!va_priv->dev) { + pr_err("%s: VA dev does not exist\n", __func__); + return; + } + + if (!va_priv->dev->of_node) { + dev_err(va_priv->dev, + "%s: DT node for va_priv does not exist\n", __func__); + return; + } + + platdata = &va_priv->swr_plat_data; + va_priv->child_count = 0; + + for_each_available_child_of_node(va_priv->dev->of_node, node) { + va_swr_master_node = false; + if (strnstr(node->name, "va_swr_master", + strlen("va_swr_master")) != NULL) + va_swr_master_node = true; + + if (va_swr_master_node) + strlcpy(plat_dev_name, "va_swr_ctrl", + (VA_MACRO_SWR_STRING_LEN - 1)); + else + strlcpy(plat_dev_name, node->name, + (VA_MACRO_SWR_STRING_LEN - 1)); + + pdev = platform_device_alloc(plat_dev_name, -1); + if (!pdev) { + dev_err(va_priv->dev, "%s: pdev memory alloc failed\n", + __func__); + ret = -ENOMEM; + goto err; + } + pdev->dev.parent = va_priv->dev; + pdev->dev.of_node = node; + + if (va_swr_master_node) { + ret = platform_device_add_data(pdev, platdata, + sizeof(*platdata)); + if (ret) { + dev_err(&pdev->dev, + "%s: cannot add plat data ctrl:%d\n", + __func__, ctrl_num); + goto fail_pdev_add; + } + } + + ret = platform_device_add(pdev); + if (ret) { + dev_err(&pdev->dev, + "%s: Cannot add platform device\n", + __func__); + goto fail_pdev_add; + } + + if (va_swr_master_node) { + temp = krealloc(swr_ctrl_data, + (ctrl_num + 1) * sizeof( + struct va_macro_swr_ctrl_data), + GFP_KERNEL); + if (!temp) { + ret = -ENOMEM; + goto fail_pdev_add; + } + swr_ctrl_data = temp; + swr_ctrl_data[ctrl_num].va_swr_pdev = pdev; + ctrl_num++; + dev_dbg(&pdev->dev, + "%s: Added soundwire ctrl device(s)\n", + __func__); + va_priv->swr_ctrl_data = swr_ctrl_data; + } + if (va_priv->child_count < VA_MACRO_CHILD_DEVICES_MAX) + va_priv->pdev_child_devices[ + va_priv->child_count++] = pdev; + else + goto err; + } + return; +fail_pdev_add: + for (count = 0; count < va_priv->child_count; count++) + platform_device_put(va_priv->pdev_child_devices[count]); +err: + return; +} + +static int va_macro_set_port_map(struct snd_soc_component *component, + u32 usecase, u32 size, void *data) +{ + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + struct swrm_port_config port_cfg; + int ret = 0; + + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) + return -EINVAL; + + memset(&port_cfg, 0, sizeof(port_cfg)); + port_cfg.uc = usecase; + port_cfg.size = size; + port_cfg.params = data; + + if (va_priv->swr_ctrl_data) + ret = swrm_wcd_notify( + va_priv->swr_ctrl_data[0].va_swr_pdev, + SWR_SET_PORT_MAP, &port_cfg); + + return ret; +} + +static int va_macro_reg_wake_irq(struct snd_soc_component *component, + u32 data) +{ + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + u32 ipc_wakeup = data; + int ret = 0; + + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) + return -EINVAL; + + if (va_priv->swr_ctrl_data) + ret = swrm_wcd_notify( + va_priv->swr_ctrl_data[0].va_swr_pdev, + SWR_REGISTER_WAKE_IRQ, &ipc_wakeup); + + return ret; +} + static void va_macro_init_ops(struct macro_ops *ops, char __iomem *va_io_base, bool va_without_decimation) @@ -2212,6 +2693,8 @@ static void va_macro_init_ops(struct macro_ops *ops, ops->exit = va_macro_deinit; ops->io_base = va_io_base; ops->event_handler = va_macro_event_handler; + ops->set_port_map = va_macro_set_port_map; + ops->reg_wake_irq = va_macro_reg_wake_irq; } static int va_macro_probe(struct platform_device *pdev) @@ -2229,6 +2712,8 @@ static int va_macro_probe(struct platform_device *pdev) const char *dmic_sample_rate = "qcom,va-dmic-sample-rate"; u32 default_clk_id = 0; struct clk *lpass_audio_hw_vote = NULL; + u32 is_used_va_swr_gpio = 0; + const char *is_used_va_swr_gpio_dt = "qcom,is-used-swr-gpio"; va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv), GFP_KERNEL); @@ -2259,6 +2744,31 @@ static int va_macro_probe(struct platform_device *pdev) return -EINVAL; } + if (of_find_property(pdev->dev.of_node, is_used_va_swr_gpio_dt, + NULL)) { + ret = of_property_read_u32(pdev->dev.of_node, + is_used_va_swr_gpio_dt, + &is_used_va_swr_gpio); + if (ret) { + dev_err(&pdev->dev, "%s: error reading %s in dt\n", + __func__, is_used_va_swr_gpio_dt); + is_used_va_swr_gpio = 0; + } + } + va_priv->va_swr_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,va-swr-gpios", 0); + if (!va_priv->va_swr_gpio_p && is_used_va_swr_gpio) { + dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n", + __func__); + return -EINVAL; + } + if ((msm_cdc_pinctrl_get_state(va_priv->va_swr_gpio_p) < 0) && + is_used_va_swr_gpio) { + dev_err(&pdev->dev, "%s: failed to get swr pin state\n", + __func__); + return -EPROBE_DEFER; + } + va_io_base = devm_ioremap(&pdev->dev, va_base_addr, VA_MACRO_MAX_OFFSET); if (!va_io_base) { @@ -2318,6 +2828,20 @@ static int va_macro_probe(struct platform_device *pdev) va_priv->clk_id = VA_CORE_CLK; va_priv->default_clk_id = default_clk_id; + if (is_used_va_swr_gpio) { + va_priv->reset_swr = true; + INIT_WORK(&va_priv->va_macro_add_child_devices_work, + va_macro_add_child_devices); + va_priv->swr_plat_data.handle = (void *) va_priv; + va_priv->swr_plat_data.read = NULL; + va_priv->swr_plat_data.write = NULL; + va_priv->swr_plat_data.bulk_write = NULL; + va_priv->swr_plat_data.clk = va_macro_swrm_clock; + va_priv->swr_plat_data.handle_irq = NULL; + mutex_init(&va_priv->swr_clk_lock); + } + va_priv->is_used_va_swr_gpio = is_used_va_swr_gpio; + mutex_init(&va_priv->mclk_lock); dev_set_drvdata(&pdev->dev, va_priv); va_macro_init_ops(&ops, va_io_base, va_without_decimation); @@ -2328,29 +2852,46 @@ static int va_macro_probe(struct platform_device *pdev) dev_err(&pdev->dev, "%s: register macro failed\n", __func__); goto reg_macro_fail; } + if (is_used_va_swr_gpio) + schedule_work(&va_priv->va_macro_add_child_devices_work); pm_runtime_set_autosuspend_delay(&pdev->dev, VA_AUTO_SUSPEND_DELAY); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); + pm_suspend_ignore_children(&pdev->dev, true); pm_runtime_enable(&pdev->dev); return ret; reg_macro_fail: mutex_destroy(&va_priv->mclk_lock); + if (is_used_va_swr_gpio) + mutex_destroy(&va_priv->swr_clk_lock); return ret; } static int va_macro_remove(struct platform_device *pdev) { struct va_macro_priv *va_priv; + int count = 0; va_priv = dev_get_drvdata(&pdev->dev); if (!va_priv) return -EINVAL; + if (va_priv->is_used_va_swr_gpio) { + if (va_priv->swr_ctrl_data) + kfree(va_priv->swr_ctrl_data); + for (count = 0; count < va_priv->child_count && + count < VA_MACRO_CHILD_DEVICES_MAX; count++) + platform_device_unregister( + va_priv->pdev_child_devices[count]); + } + pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); bolero_unregister_macro(&pdev->dev, VA_MACRO); mutex_destroy(&va_priv->mclk_lock); + if (va_priv->is_used_va_swr_gpio) + mutex_destroy(&va_priv->swr_clk_lock); return 0; } -- GitLab From 42658f4480b5f4458b5341f00f98737922142506 Mon Sep 17 00:00:00 2001 From: Guodong Hu Date: Mon, 14 Oct 2019 17:16:45 +0800 Subject: [PATCH 1267/1645] asoc: fix audiodlkm compile error on sa8195 perf * To fix a compile error in sa8195 perf image: uninitialized variable in wcd_cpe_core.c. Change-Id: I2aac81068299202509eebcb854c53348451c522b Signed-off-by: Guodong Hu --- asoc/codecs/wcd_cpe_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/codecs/wcd_cpe_core.c b/asoc/codecs/wcd_cpe_core.c index 4c776d199266..5b5291f8a603 100644 --- a/asoc/codecs/wcd_cpe_core.c +++ b/asoc/codecs/wcd_cpe_core.c @@ -2896,6 +2896,7 @@ static int wcd_cpe_send_param_snd_model(struct wcd_cpe_core *core, struct cmi_obm_msg obm_msg; struct cpe_param_data *param_d; + memset(&obm_msg, 0, sizeof(obm_msg)); ret = fill_cmi_header(&obm_msg.hdr, session->id, CMI_CPE_LSM_SERVICE_ID, 0, 20, -- GitLab From 6bb56f382badff58db1f6440d8006990061a7aaa Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 23 Oct 2019 17:29:29 +0530 Subject: [PATCH 1268/1645] dsp: Fix NOC error from lpass on accessing LPASS_AVTIMER_LSB avcs_core_query_timer_offset can be called from external ioctl while avtimer clk count is 0. This can result in a NOC while reading avtimer register. Reset adsp_ready if avtimer clk count is 0 to resolve the issue. Change-Id: I3d088c306f4895a2fee68f2ac95ea6ad96094ea1 Signed-off-by: Vatsal Bucha --- dsp/avtimer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dsp/avtimer.c b/dsp/avtimer.c index ad5e13af3f8d..e1d032d53661 100644 --- a/dsp/avtimer.c +++ b/dsp/avtimer.c @@ -271,6 +271,7 @@ int avcs_core_disable_power_collapse(int enable) rc = avcs_core_disable_avtimer( avtimer.timer_handle); avtimer.timer_handle = 0; + atomic_set(&avtimer.adsp_ready, 0); } } } -- GitLab From 9adf04cadba995fc313382cd62bbb1cfb21be014 Mon Sep 17 00:00:00 2001 From: Ajit Pandey Date: Thu, 24 Oct 2019 13:45:11 +0530 Subject: [PATCH 1269/1645] asoc: msm-compress: Replace goto with return in case of invalid value In case of invalid values in _put() callback return directly to avoid deadlock issue with mutex unlocking in goto label. Change-Id: Ib0623e26dd83b96cd6ec315f515098b8ea0b2dd2 Signed-off-by: Ajit Pandey --- asoc/msm-compress-q6-v2.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 4347bec26ed6..67b559091b94 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -3702,8 +3702,7 @@ static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol, if (fe_id >= MSM_FRONTEND_DAI_MAX) { pr_err("%s Received out of bounds fe_id %lu\n", __func__, fe_id); - rc = -EINVAL; - goto end; + return -EINVAL; } cstream = pdata->cstream[fe_id]; @@ -3711,14 +3710,12 @@ static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol, if (!cstream || !dec_params) { pr_err("%s: stream or dec_params inactive\n", __func__); - rc = -EINVAL; - goto end; + return -EINVAL; } prtd = cstream->runtime->private_data; if (!prtd) { pr_err("%s: cannot set dec_params\n", __func__); - rc = -EINVAL; - goto end; + return -EINVAL; } mutex_lock(&pdata->lock); @@ -3975,22 +3972,19 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, if (fe_id >= MSM_FRONTEND_DAI_MAX) { pr_err("%s Received invalid fe_id %lu\n", __func__, fe_id); - ret = -EINVAL; - goto done; + return -EINVAL; } cstream = pdata->cstream[fe_id]; if (cstream == NULL) { pr_err("%s cstream is null\n", __func__); - ret = -EINVAL; - goto done; + return -EINVAL; } prtd = cstream->runtime->private_data; if (!prtd) { pr_err("%s: prtd is null\n", __func__); - ret = -EINVAL; - goto done; + return -EINVAL; } mutex_lock(&pdata->lock); @@ -4041,22 +4035,19 @@ static int msm_compr_ion_fd_map_put(struct snd_kcontrol *kcontrol, if (fe_id >= MSM_FRONTEND_DAI_MAX) { pr_err("%s Received out of bounds invalid fe_id %lu\n", __func__, fe_id); - ret = -EINVAL; - goto done; + return -EINVAL; } cstream = pdata->cstream[fe_id]; if (cstream == NULL) { pr_err("%s cstream is null\n", __func__); - ret = -EINVAL; - goto done; + return -EINVAL; } prtd = cstream->runtime->private_data; if (!prtd) { pr_err("%s: prtd is null\n", __func__); - ret = -EINVAL; - goto done; + return -EINVAL; } mutex_lock(&pdata->lock); @@ -4090,8 +4081,7 @@ static int msm_compr_rtic_event_ack_put(struct snd_kcontrol *kcontrol, if (fe_id >= MSM_FRONTEND_DAI_MAX) { pr_err("%s Received invalid fe_id %lu\n", __func__, fe_id); - ret = -EINVAL; - goto done; + return -EINVAL; } mutex_lock(&pdata->lock); -- GitLab From 9810a5cc9232745231445e21c5a6298ce12f6fbe Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Sun, 20 Oct 2019 23:05:14 -0700 Subject: [PATCH 1270/1645] asoc: codecs: bolero: suspend swr at VA use case switch While switching from a VA use case, suspend the soundwire immediately so that if the next use case switches clock soundwire will also be reset. Change-Id: I18b65a01bc02329e9a53de93c0ccfb621c95a1f4 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/va-macro.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index b7d6fe06df35..782c00e1d04c 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -336,6 +336,8 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, ret = va_macro_mclk_enable(va_priv, 1, true); break; case SND_SOC_DAPM_POST_PMD: + if (bolero_tx_clk_switch(component)) + dev_dbg(va_dev, "%s: clock switch failed\n",__func__); va_macro_mclk_enable(va_priv, 0, true); if (va_priv->tx_clk_status > 0) { bolero_clk_rsc_request_clock(va_priv->dev, @@ -775,6 +777,8 @@ static int va_macro_enable_tx(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMU: + if (bolero_tx_clk_switch(component)) + dev_dbg(va_dev, "%s: clock switch failed\n",__func__); if (va_priv->tx_clk_status > 0) { ret = bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, -- GitLab From ac0ae1c2987606089ee1f030d9b1665001bc923c Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 17 Oct 2019 05:38:40 +0530 Subject: [PATCH 1271/1645] soc: soundwire: change ssp period based on frame shape Change SSP period based on soundwire bus clock rate and frame shape to avoid any synchronization issues. Change-Id: I376958c6b92eca28b857c4c7c9948b1e56818657 Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 48 +++++++++++++++++++++++++++++++++++++++++---- soc/swr-mstr-ctrl.h | 1 + 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 44d245d6dfb2..614a2be3117d 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -25,6 +25,7 @@ #include "swrm_registers.h" #include "swr-mstr-ctrl.h" +#define SWRM_FRAME_SYNC_SEL 4000 /* 4KHz */ #define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700 #define SWRM_SYS_SUSPEND_WAIT 1 @@ -43,6 +44,13 @@ #define ERR_AUTO_SUSPEND_TIMER_VAL 0x1 #define SWRM_INTERRUPT_STATUS_MASK 0x1FDFD + +#define SWRM_ROW_48 48 +#define SWRM_ROW_50 50 +#define SWRM_ROW_64 64 +#define SWRM_COL_02 02 +#define SWRM_COL_16 16 + /* pm runtime auto suspend timer in msecs */ static int auto_suspend_timer = SWR_AUTO_SUSPEND_DELAY * 1000; module_param(auto_suspend_timer, int, 0664); @@ -341,6 +349,16 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm, return ret; } +static int swrm_get_ssp_period(struct swr_mstr_ctrl *swrm, + int row, int col, + int frame_sync) +{ + if (!swrm || !row || !col || !frame_sync) + return 1; + + return ((swrm->bus_clk * 2) / ((row * col) * frame_sync)); +} + static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) { int ret = 0; @@ -591,6 +609,10 @@ static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, if (retry_attempt < MAX_FIFO_RD_FAIL_RETRY) { /* wait 500 us before retry on fifo read failure */ usleep_range(500, 505); + if (retry_attempt == (MAX_FIFO_RD_FAIL_RETRY - 1)) { + swr_master_write(swrm, SWRM_CMD_FIFO_CMD, 0x1); + swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val); + } retry_attempt++; goto retry_read; } else { @@ -1093,7 +1115,9 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) { u8 bank; u32 value, n_row, n_col; + u32 row = 0, col = 0; int ret; + u8 ssp_period = 0; struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK | SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK | @@ -1162,30 +1186,39 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) if (enable) { /* set col = 16 */ n_col = SWR_MAX_COL; + col = SWRM_COL_16; } else { /* * Do not change to col = 2 if there are still active ports */ - if (!master->num_port) + if (!master->num_port) { n_col = SWR_MIN_COL; - else + col = SWRM_COL_02; + } else { n_col = SWR_MAX_COL; + col = SWRM_COL_16; + } } /* Use default 50 * x, frame shape. Change based on mclk */ if (swrm->mclk_freq == MCLK_FREQ_NATIVE) { dev_dbg(swrm->dev, "setting 64 x %d frameshape\n", n_col ? 16 : 2); n_row = SWR_ROW_64; + row = SWRM_ROW_64; } else { dev_dbg(swrm->dev, "setting 50 x %d frameshape\n", n_col ? 16 : 2); n_row = SWR_ROW_50; + row = SWRM_ROW_50; } + ssp_period = swrm_get_ssp_period(swrm, row, col, SWRM_FRAME_SYNC_SEL); + dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period); + value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank)); value &= (~mask); value |= ((n_row << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | (n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) | - (0 << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT)); + ((ssp_period - 1) << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT)); swr_master_write(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value); dev_dbg(swrm->dev, "%s: regaddr: 0x%x, value: 0x%x\n", __func__, @@ -1732,6 +1765,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) case SWRM_INTERRUPT_STATUS_WR_CMD_FIFO_OVERFLOW: dev_dbg(swrm->dev, "%s: SWR write FIFO overflow\n", __func__); + swr_master_write(swrm, SWRM_CMD_FIFO_CMD, 0x1); break; case SWRM_INTERRUPT_STATUS_CMD_ERROR: value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS); @@ -2024,10 +2058,14 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) u32 value[SWRM_MAX_INIT_REG]; int len = 0; + ssp_period = swrm_get_ssp_period(swrm, SWRM_ROW_50, + SWRM_COL_02, SWRM_FRAME_SYNC_SEL); + dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period); + /* Clear Rows and Cols */ val = ((row_ctrl << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | (col_ctrl << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) | - (ssp_period << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT)); + ((ssp_period - 1) << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT)); reg[len] = SWRM_MCP_FRAME_CTRL_BANK_ADDR(0); value[len++] = val; @@ -2295,6 +2333,7 @@ static int swrm_probe(struct platform_device *pdev) swrm->clk_ref_count = 0; swrm->swr_irq_wakeup_capable = 0; swrm->mclk_freq = MCLK_FREQ; + swrm->bus_clk = MCLK_FREQ; swrm->dev_up = true; swrm->state = SWR_MSTR_UP; swrm->ipc_wakeup = false; @@ -2868,6 +2907,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) swrm_device_suspend(&pdev->dev); } swrm->mclk_freq = *(int *)data; + swrm->bus_clk = swrm->mclk_freq; mutex_unlock(&swrm->mlock); } break; diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 321e84f3007d..399efa3eb025 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -140,6 +140,7 @@ struct swr_mstr_ctrl { int wake_irq; int version; int mclk_freq; + int bus_clk; u32 num_dev; int slave_status; struct swrm_mports mport_cfg[SWR_MAX_MSTR_PORT_NUM]; -- GitLab From 7b663b23b2d8932fb51aa2a433cb597594a0e91e Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 22 Oct 2019 11:39:10 +0530 Subject: [PATCH 1272/1645] ASoC: wcd-mbhc: Fix headset insert not detected after moisture config Headset insertion is not detected after moisture is configured and then removed. This is because during moisture_detect GND_DET_EN is configured irrespective of whether it is enabled or not. Add a check before enabling gnd_det_en. Also as moisture_en is disabled and duty cycle is enabled change check during removal to disable threshold and polling. Change-Id: Iee9d79b38b228e78d1509d59e92d37f1328f079e Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd-mbhc-v2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 01544aab9c43..e332acd6f9ee 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -883,7 +883,8 @@ static bool wcd_mbhc_moisture_detect(struct wcd_mbhc *mbhc, bool detection_type) detection_type); ret = true; WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1); - WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_GND_DET_EN, 1); + if (mbhc->mbhc_cfg->gnd_det_en) + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_GND_DET_EN, 1); } else { mbhc->mbhc_cb->mbhc_moisture_polling_ctrl(mbhc, false); mbhc->mbhc_cb->mbhc_moisture_detect_en(mbhc, false); @@ -1023,7 +1024,7 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) mbhc->component, false); } - if (mbhc->mbhc_cfg->moisture_en && + if (mbhc->mbhc_cfg->moisture_en || mbhc->mbhc_cfg->moisture_duty_cycle_en) { if (mbhc->mbhc_cb->mbhc_moisture_polling_ctrl) mbhc->mbhc_cb->mbhc_moisture_polling_ctrl(mbhc, -- GitLab From 6420f70b2d4db7ab2af9d537eff00c91eec05f15 Mon Sep 17 00:00:00 2001 From: Meghana Reddy Mula Date: Tue, 10 Sep 2019 17:14:32 +0530 Subject: [PATCH 1273/1645] dsp: Add new mixer control to reset ecns Add support for mixer control to enable/disable ecns module for voice call. Change-Id: I085411c4a6394d27880f8055b3348c1eb5f2b6ff Signed-off-by: Meghana Reddy Mula --- dsp/q6voice.c | 129 ++++++++++++++++++++++++++++++++++++++++++ include/dsp/q6voice.h | 54 ++++++++++++++++++ 2 files changed, 183 insertions(+) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 3db75d02c54f..77a08ee6fff8 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -110,6 +110,10 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv); static int voice_send_set_pp_enable_cmd( struct voice_data *v, struct module_instance_info mod_inst_info, int enable); + +static int voice_send_cvp_ecns_enable_cmd(struct voice_data *v, + uint32_t module_id, int enable); + static int is_cal_memory_allocated(void); static bool is_cvd_version_queried(void); static int is_voip_memory_allocated(void); @@ -1544,6 +1548,124 @@ static int voice_send_tty_mode_cmd(struct voice_data *v) return ret; } +static int voice_send_cvp_ecns_enable_cmd(struct voice_data *v, + uint32_t module_id, int enable) +{ + int ret; + struct cvp_set_channel_ecns_cmd_v2 cvp_set_ch_ecns_cmd; + void *apr_cvp; + u16 cvp_handle; + struct vss_icommon_param_data_ecns_t *cvp_config_param_data = + &cvp_set_ch_ecns_cmd. + cvp_set_ecns.param_data; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + apr_cvp = common.apr_q6_cvp; + + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + cvp_handle = voice_get_cvp_handle(v); + memset(&cvp_set_ch_ecns_cmd, 0, + sizeof(cvp_set_ch_ecns_cmd)); + + cvp_set_ch_ecns_cmd.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_set_ch_ecns_cmd.hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_set_ch_ecns_cmd) - APR_HDR_SIZE); + cvp_set_ch_ecns_cmd.hdr.src_svc = 0; + cvp_set_ch_ecns_cmd.hdr.src_domain = APR_DOMAIN_APPS; + cvp_set_ch_ecns_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_set_ch_ecns_cmd.hdr.dest_svc = 0; + cvp_set_ch_ecns_cmd.hdr.dest_domain = APR_DOMAIN_ADSP; + cvp_set_ch_ecns_cmd.hdr.dest_port = cvp_handle; + cvp_set_ch_ecns_cmd.hdr.token = 0; + cvp_set_ch_ecns_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2; + cvp_set_ch_ecns_cmd.cvp_set_ecns.mem_size = + sizeof(struct vss_icommon_param_data_ecns_t); + + cvp_config_param_data->module_id = module_id; + cvp_config_param_data->param_id = VOICE_PARAM_MOD_ENABLE; + cvp_config_param_data->param_size = MOD_ENABLE_PARAM_LEN; + cvp_config_param_data->reserved = 0; + cvp_config_param_data->enable = enable; + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *)&cvp_set_ch_ecns_cmd); + + if (ret < 0) { + pr_err("%s: Failed to send VSS_ICOMMON_CMD_SET_PARAM_V2 %d\n", + __func__, ret); + goto done; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s] handle = %d\n", __func__, + adsp_err_get_err_str(v->async_err), cvp_handle); + ret = adsp_err_get_lnx_err_code(v->async_err); + goto done; + } + ret = 0; +done: + return ret; +} + +/** + * voc_set_ecns_enable - + * Command to set ECNS for voice module + * + * @session_id: voice session ID to send this command + * @module_id: voice module id + * @enable: enable/disable flag + * + * Returns 0 on success or error on failure + */ +int voc_set_ecns_enable(uint32_t session_id, uint32_t module_id, + uint32_t enable) +{ + struct voice_data *v = voice_get_session(session_id); + int ret = 0; + + if (v == NULL) { + pr_err("%s: invalid session_id 0x%x\n", __func__, session_id); + return -EINVAL; + } + mutex_lock(&v->lock); + v->ecns_enable = enable; + v->ecns_module_id = module_id; + + if (is_voc_state_active(v->voc_state)) + ret = voice_send_cvp_ecns_enable_cmd(v, + v->ecns_module_id, v->ecns_enable); + + mutex_unlock(&v->lock); + + return ret; +} +EXPORT_SYMBOL(voc_set_ecns_enable); + static int voice_send_set_pp_enable_cmd( struct voice_data *v, struct module_instance_info mod_inst_info, int enable) @@ -4420,6 +4542,10 @@ static int voice_setup_vocproc(struct voice_data *v) if (v->dtmf_rx_detect_en) voice_send_dtmf_rx_detection_cmd(v, v->dtmf_rx_detect_en); + if (v->ecns_enable) + voice_send_cvp_ecns_enable_cmd(v, v->ecns_module_id, + v->ecns_enable); + if (v->hd_enable) voice_send_hd_cmd(v, v->hd_enable); @@ -5076,6 +5202,9 @@ static int voice_destroy_vocproc(struct voice_data *v) if (v->dtmf_rx_detect_en) voice_send_dtmf_rx_detection_cmd(v, 0); + if (v->ecns_enable) + voice_send_cvp_ecns_enable_cmd(v, v->ecns_module_id, 0); + /* detach VOCPROC and wait for response from mvm */ mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index 2edfbe215fd7..35ace4eed388 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -312,6 +312,21 @@ struct vss_icommon_param_data_ch_mixer_v2_t { struct vss_param_channel_mixer_info_t ch_mixer_info; } __packed; +struct vss_icommon_param_data_ecns_t { + /* Valid ID of the module. */ + uint32_t module_id; + /* Valid ID of the parameter. */ + uint32_t param_id; + /* + * Data size of the structure relating to the param_id/module_id + * combination in uint8_t bytes. + */ + uint16_t param_size; + /* This field must be set to zero. */ + uint16_t reserved; + uint32_t enable; +} __packed; + struct vss_icommon_cmd_set_param_ch_mixer_v2_t { /* * Pointer to the unique identifier for an address (physical/virtual). @@ -338,6 +353,33 @@ struct vss_icommon_cmd_set_param_ch_mixer_v2_t { struct vss_icommon_param_data_ch_mixer_v2_t param_data; } __packed; + +struct vss_icommon_cmd_set_ecns_enable_t { + /* + * Pointer to the unique identifier for an address (physical/virtual). + * + * If the parameter data payload is within the message payload + * (in-band), set this field to 0. The parameter data begins at the + * specified data payload address. + * + * If the parameter data is out-of-band, this field is the handle to + * the physical address in the shared memory that holds the parameter + * data. + */ + uint32_t mem_handle; + /* + * Location of the parameter data payload. + * + * The payload is an array of vss_icommon_param_data_t. If the + * mem_handle is 0, this field is ignored. + */ + uint64_t mem_address; + /* Size of the parameter data payload in bytes. */ + uint32_t mem_size; + + struct vss_icommon_param_data_ecns_t param_data; +} __packed; + struct vss_icommon_param_data_mfc_config_v2_t { /* Valid ID of the module. */ uint32_t module_id; @@ -809,6 +851,7 @@ struct vss_evt_voice_activity { #define MODULE_ID_VOICE_MODULE_ST 0x00010EE3 #define VOICE_PARAM_MOD_ENABLE 0x00010E00 +#define MOD_ENABLE_PARAM_LEN 4 #define VSS_IPLAYBACK_CMD_START 0x000112BD /* Start in-call music delivery on the Tx voice path. */ @@ -1679,6 +1722,11 @@ struct cvp_set_vp3_data_cmd { struct apr_hdr hdr; } __packed; +struct cvp_set_channel_ecns_cmd_v2 { + struct apr_hdr hdr; + struct vss_icommon_cmd_set_ecns_enable_t cvp_set_ecns; +} __packed; + struct cvp_set_rx_volume_index_cmd { struct apr_hdr hdr; struct vss_ivocproc_cmd_set_volume_index_t cvp_set_vol_idx; @@ -1894,6 +1942,10 @@ struct voice_data { bool mic_break_status; struct work_struct voice_mic_break_work; + + uint32_t ecns_enable; + uint32_t ecns_module_id; + }; #define MAX_VOC_SESSIONS 8 @@ -2042,6 +2094,8 @@ int voc_get_rx_device_mute(uint32_t session_id); int voc_set_route_flag(uint32_t session_id, uint8_t path_dir, uint8_t set); uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir); bool voc_get_mbd_enable(void); +int voc_set_ecns_enable(uint32_t session_id, uint32_t module_id, + uint32_t enable); uint8_t voc_set_mbd_enable(bool enable); int voc_enable_dtmf_rx_detection(uint32_t session_id, uint32_t enable); void voc_disable_dtmf_det_on_active_sessions(void); -- GitLab From 58b05be4ab29f8c2be5b83601611db34a77f505a Mon Sep 17 00:00:00 2001 From: Meghana Reddy Mula Date: Tue, 10 Sep 2019 17:15:24 +0530 Subject: [PATCH 1274/1645] asoc: Add new mixer control to reset ecns Add support for mixer control to enable/disable ecns module for voice call. Change-Id: Icd046e936b0ae0db577e46e139b4f060e0cc7462 Signed-off-by: Meghana Reddy Mula --- asoc/msm-pcm-voice-v2.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/asoc/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c index f8acc30ab86e..5a25b3e860bd 100644 --- a/asoc/msm-pcm-voice-v2.c +++ b/asoc/msm-pcm-voice-v2.c @@ -582,6 +582,20 @@ static int msm_voice_slowtalk_put(struct snd_kcontrol *kcontrol, return 0; } +static int msm_voice_ecns_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + uint32_t enable = ucontrol->value.integer.value[0]; + uint32_t session_id = ucontrol->value.integer.value[1]; + uint32_t module_id = ucontrol->value.integer.value[2]; + + pr_debug("%s: ecns enable=%d session_id=%#x\n", __func__, enable, + session_id); + voc_set_ecns_enable(session_id, module_id, enable); + + return 0; +} + static int msm_voice_hd_voice_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -695,6 +709,8 @@ static struct snd_kcontrol_new msm_voice_controls[] = { msm_voice_tty_mode_put), SOC_SINGLE_MULTI_EXT("Slowtalk Enable", SND_SOC_NOPM, 0, VSID_MAX, 0, 2, NULL, msm_voice_slowtalk_put), + SOC_SINGLE_MULTI_EXT("Voice ECNS Enable", SND_SOC_NOPM, 0, VSID_MAX, 0, 3, + NULL, msm_voice_ecns_put), SOC_SINGLE_MULTI_EXT("Voice Topology Disable", SND_SOC_NOPM, 0, VSID_MAX, 0, 2, NULL, msm_voice_topology_disable_put), -- GitLab From 395166b04b5c93d8f2b507c0c30b09ea1df2c246 Mon Sep 17 00:00:00 2001 From: Guodong Hu Date: Thu, 10 Oct 2019 16:56:28 +0800 Subject: [PATCH 1275/1645] asoc/dsp: add tert_tdm_tx_0 port for lsm support Add backend port: TERT_TDM_TX_0 to support "LSM Mixer", "LSM Port" and "LSM Function" mixer controls. Change-Id: I86d83ba96ee79bbffef4aee2f31a6d16eb09d78f Signed-off-by: Guodong Hu --- asoc/msm-pcm-routing-v2.c | 77 +++++++++++++++++++++++++++++++++------ dsp/q6afe.c | 6 ++- 2 files changed, 70 insertions(+), 13 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 03cd0813d6bf..b3c1d94f6da2 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -123,6 +123,7 @@ enum { #define VA_CDC_DMA_TX_2_TEXT "VA_CDC_DMA_TX_2" #define TX_CDC_DMA_TX_3_TEXT "TX_CDC_DMA_TX_3" #define QUIN_TDM_TX_TEXT "QUIN_TDM_TX_0" +#define TERT_TDM_TX_TEXT "TERT_TDM_TX_0" #define LSM_FUNCTION_TEXT "LSM Function" static const char * const lsm_port_text[] = { @@ -131,7 +132,8 @@ static const char * const lsm_port_text[] = { SLIMBUS_3_TX_TEXT, SLIMBUS_4_TX_TEXT, SLIMBUS_5_TX_TEXT, TERT_MI2S_TX_TEXT, QUAT_MI2S_TX_TEXT, ADM_LSM_TX_TEXT, INT3_MI2S_TX_TEXT, VA_CDC_DMA_TX_0_TEXT, VA_CDC_DMA_TX_1_TEXT, - VA_CDC_DMA_TX_2_TEXT, TX_CDC_DMA_TX_3_TEXT, QUIN_TDM_TX_TEXT + VA_CDC_DMA_TX_2_TEXT, TX_CDC_DMA_TX_3_TEXT, QUIN_TDM_TX_TEXT, + TERT_TDM_TX_TEXT }; struct msm_pcm_route_bdai_pp_params { @@ -3032,6 +3034,9 @@ static int msm_routing_lsm_port_put(struct snd_kcontrol *kcontrol, case 15: lsm_port = AFE_PORT_ID_QUINARY_TDM_TX; break; + case 16: + lsm_port = AFE_PORT_ID_TERTIARY_TDM_TX; + break; default: pr_err("Default lsm port"); break; @@ -3049,7 +3054,7 @@ static int msm_routing_lsm_func_get(struct snd_kcontrol *kcontrol, u16 port_id; enum afe_mad_type mad_type; - pr_debug("%s: enter\n", __func__); + pr_debug("%s: id name %s\n", __func__, kcontrol->id.name); for (i = 0; i < ARRAY_SIZE(lsm_port_text); i++) if (!strnstr(kcontrol->id.name, lsm_port_text[i], strlen(lsm_port_text[i]))) @@ -3076,14 +3081,18 @@ static int msm_routing_lsm_func_get(struct snd_kcontrol *kcontrol, strlen(lsm_port_text[10]))) port_id = AFE_PORT_ID_INT3_MI2S_TX; - if (strnstr(kcontrol->id.name, lsm_port_text[13], - strlen(lsm_port_text[13]))) - port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3; - if (strnstr(kcontrol->id.name, lsm_port_text[14], strlen(lsm_port_text[14]))) + port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3; + + if (strnstr(kcontrol->id.name, lsm_port_text[15], + strlen(lsm_port_text[15]))) port_id = AFE_PORT_ID_QUINARY_TDM_TX; + if (strnstr(kcontrol->id.name, lsm_port_text[16], + strlen(lsm_port_text[16]))) + port_id = AFE_PORT_ID_TERTIARY_TDM_TX; + mad_type = afe_port_get_mad_type(port_id); pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, mad_type); @@ -3117,7 +3126,7 @@ static int msm_routing_lsm_func_put(struct snd_kcontrol *kcontrol, u16 port_id; enum afe_mad_type mad_type; - pr_debug("%s: enter\n", __func__); + pr_debug("%s: id name %s\n", __func__, kcontrol->id.name); for (i = 0; i < ARRAY_SIZE(lsm_port_text); i++) if (strnstr(kcontrol->id.name, lsm_port_text[i], strlen(lsm_port_text[i]))) @@ -3164,14 +3173,18 @@ static int msm_routing_lsm_func_put(struct snd_kcontrol *kcontrol, strlen(lsm_port_text[10]))) port_id = AFE_PORT_ID_INT3_MI2S_TX; - if (strnstr(kcontrol->id.name, lsm_port_text[13], - strlen(lsm_port_text[13]))) - port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3; - if (strnstr(kcontrol->id.name, lsm_port_text[14], strlen(lsm_port_text[14]))) + port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3; + + if (strnstr(kcontrol->id.name, lsm_port_text[15], + strlen(lsm_port_text[15]))) port_id = AFE_PORT_ID_QUINARY_TDM_TX; + if (strnstr(kcontrol->id.name, lsm_port_text[16], + strlen(lsm_port_text[16]))) + port_id = AFE_PORT_ID_TERTIARY_TDM_TX; + pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, mad_type); return afe_port_set_mad_type(port_id, mad_type); @@ -20799,6 +20812,10 @@ static const struct snd_kcontrol_new lsm1_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm2_mixer_controls[] = { @@ -20855,6 +20872,10 @@ static const struct snd_kcontrol_new lsm2_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm3_mixer_controls[] = { @@ -20910,6 +20931,10 @@ static const struct snd_kcontrol_new lsm3_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm4_mixer_controls[] = { @@ -20965,6 +20990,10 @@ static const struct snd_kcontrol_new lsm4_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm5_mixer_controls[] = { @@ -21020,6 +21049,10 @@ static const struct snd_kcontrol_new lsm5_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm6_mixer_controls[] = { @@ -21075,6 +21108,10 @@ static const struct snd_kcontrol_new lsm6_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm7_mixer_controls[] = { @@ -21130,6 +21167,10 @@ static const struct snd_kcontrol_new lsm7_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new lsm8_mixer_controls[] = { @@ -21185,6 +21226,10 @@ static const struct snd_kcontrol_new lsm8_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), }; static const struct snd_kcontrol_new slim_fm_switch_mixer_controls = @@ -21335,6 +21380,8 @@ static const struct snd_kcontrol_new lsm_controls[] = { msm_routing_lsm_func_get, msm_routing_lsm_func_put), SOC_ENUM_EXT(QUIN_TDM_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(TERT_TDM_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), /* kcontrol of lsm_port */ SOC_ENUM_EXT("LSM1 Port", lsm_port_enum, msm_routing_lsm_port_get, @@ -26989,6 +27036,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM1 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"LSM1 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM1 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM1 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"LSM1_UL_HL", NULL, "LSM1 Mixer"}, {"LSM2 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -27004,6 +27052,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM2 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"LSM2 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM2 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM2 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"LSM2_UL_HL", NULL, "LSM2 Mixer"}, @@ -27020,6 +27069,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM3 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"LSM3 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM3 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM3 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"LSM3_UL_HL", NULL, "LSM3 Mixer"}, @@ -27036,6 +27086,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM4 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"LSM4 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM4 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM4 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"LSM4_UL_HL", NULL, "LSM4 Mixer"}, {"LSM5 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -27051,6 +27102,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM5 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"LSM5 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM5 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM5 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"LSM5_UL_HL", NULL, "LSM5 Mixer"}, {"LSM6 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -27064,6 +27116,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM6 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"LSM6 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM6 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM6 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"LSM6_UL_HL", NULL, "LSM6 Mixer"}, {"LSM7 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -27077,6 +27130,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM7 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"LSM7 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM7 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM7 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"LSM7_UL_HL", NULL, "LSM7 Mixer"}, {"LSM8 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, @@ -27090,6 +27144,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LSM8 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, {"LSM8 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"LSM8 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM8 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"LSM8_UL_HL", NULL, "LSM8 Mixer"}, diff --git a/dsp/q6afe.c b/dsp/q6afe.c index ccc91cfbeb89..6111832bbaee 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2897,7 +2897,8 @@ int afe_port_set_mad_type(u16 port_id, enum afe_mad_type mad_type) if (port_id == AFE_PORT_ID_TERTIARY_MI2S_TX || port_id == AFE_PORT_ID_INT3_MI2S_TX || - port_id == AFE_PORT_ID_TX_CODEC_DMA_TX_3) { + port_id == AFE_PORT_ID_TX_CODEC_DMA_TX_3 || + port_id == AFE_PORT_ID_TERTIARY_TDM_TX) { mad_type = MAD_SW_AUDIO; return 0; } @@ -2926,7 +2927,8 @@ enum afe_mad_type afe_port_get_mad_type(u16 port_id) if (port_id == AFE_PORT_ID_TERTIARY_MI2S_TX || port_id == AFE_PORT_ID_INT3_MI2S_TX || - port_id == AFE_PORT_ID_TX_CODEC_DMA_TX_3) + port_id == AFE_PORT_ID_TX_CODEC_DMA_TX_3 || + port_id == AFE_PORT_ID_TERTIARY_TDM_TX) return MAD_SW_AUDIO; i = port_id - SLIMBUS_0_RX; -- GitLab From 4bb899878875af238cbb1d648759920ed7e3ff7f Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Tue, 1 Oct 2019 13:51:11 +0530 Subject: [PATCH 1276/1645] asoc: update number of channel only for default channel map Volume setting on the custom channel map is failed as use default channel map is always set to true. Use default channel map from runtime data and update number of channels only if custom channel map is not set. Change-Id: I2326b52687144a584f85ab3db8a2930f8fa5c3ea Signed-off-by: Surendar Karka --- asoc/msm-compress-q6-v2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 4347bec26ed6..45602990ac61 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -408,8 +408,8 @@ static int msm_compr_set_volume(struct snd_compr_stream *cstream, gain_list[0] = volume_l; gain_list[1] = volume_r; gain_list[2] = volume_l; - num_channels = 3; - use_default = true; + if (use_default) + num_channels = 3; rc = q6asm_set_multich_gain(prtd->audio_client, num_channels, gain_list, chmap, use_default); } -- GitLab From 8e9a0aecdd687b2a76e72eae00b3149323001dcc Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 19 Oct 2019 12:01:33 +0530 Subject: [PATCH 1277/1645] ASoC: wsa883x: Update dapm path sequence Update dapm path sequence for speaker amplifier. Change-Id: Ia5fcd7d4574d990ef42e6b3e16b3ddd81841d4bc Signed-off-by: Sudheer Papothi --- asoc/codecs/wsa883x/internal.h | 20 +- asoc/codecs/wsa883x/wsa883x.c | 467 +++++++++++++++------------------ 2 files changed, 209 insertions(+), 278 deletions(-) diff --git a/asoc/codecs/wsa883x/internal.h b/asoc/codecs/wsa883x/internal.h index 3f99f780659c..3f24712ff447 100644 --- a/asoc/codecs/wsa883x/internal.h +++ b/asoc/codecs/wsa883x/internal.h @@ -63,12 +63,6 @@ struct swr_port { u8 port_type; }; -enum { - WSA883X_DEV_DOWN, - WSA883X_DEV_UP, - WSA883X_DEV_READY, -}; - extern struct regmap_config wsa883x_regmap_config; /* @@ -81,24 +75,18 @@ struct wsa883x_priv { struct swr_device *swr_slave; struct snd_soc_component *component; bool comp_enable; - bool boost_enable; bool visense_enable; - u8 pa_gain; + bool ext_vdd_spk; struct swr_port port[WSA883X_MAX_SWR_PORTS]; int pd_gpio; - struct wsa883x_tz_priv tz_pdata; - int bg_cnt; - int clk_cnt; - int version; - struct mutex bg_lock; + int global_pa_cnt; + int dev_mode; struct mutex res_lock; - struct mutex temp_lock; struct snd_info_entry *entry; struct snd_info_entry *version_entry; - int state; - struct delayed_work ocp_ctl_work; struct device_node *wsa_rst_np; int pa_mute; + int curr_temp; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_dent; struct dentry *debugfs_peek; diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 988196e23798..cbf955960ce4 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -26,9 +26,33 @@ #include #include #include "wsa883x.h" -#include "wsa883x-temp-sensor.h" #include "internal.h" +#define T1_TEMP -10 +#define T2_TEMP 150 +#define LOW_TEMP_THRESHOLD 5 +#define HIGH_TEMP_THRESHOLD 45 +#define TEMP_INVALID 0xFFFF +#define WSA883X_TEMP_RETRY 3 + +enum { + WSA_4OHMS =4, + WSA_8OHMS = 8, + WSA_16OHMS = 16, + WSA_32OHMS = 32, +}; + +struct wsa_temp_register { + u8 d1_msb; + u8 d1_lsb; + u8 d2_msb; + u8 d2_lsb; + u8 dmeas_msb; + u8 dmeas_lsb; +}; + +static int wsa883x_get_temperature(struct snd_soc_component *component, + int *temp); #ifdef CONFIG_DEBUG_FS static int codec_debug_open(struct inode *inode, struct file *file) { @@ -265,6 +289,43 @@ static const struct file_operations codec_debug_dump_ops = { }; #endif +static const char * const wsa_dev_mode_text[] = { + "speaker", "receiver", "ultrasound" +}; + +static const struct soc_enum wsa_dev_mode_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa_dev_mode_text), wsa_dev_mode_text); + +static int wsa_dev_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wsa883x->dev_mode; + + dev_dbg(component->dev, "%s: mode = 0x%x\n", __func__, + wsa883x->dev_mode); + + return 0; +} + +static int wsa_dev_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + wsa883x->dev_mode = ucontrol->value.integer.value[0]; + + return 0; +} + static const char * const wsa_pa_gain_text[] = { "G_18_DB", "G_16P5_DB", "G_15_DB", "G_13P5_DB", "G_12_DB", "G_10P5_DB", "G_9_DB", "G_7P5_DB", "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB", @@ -332,43 +393,19 @@ static int wsa883x_set_mute(struct snd_kcontrol *kcontrol, return 0; } -static int wsa883x_get_t0_init(struct snd_kcontrol *kcontrol, +static int wsa_get_temp(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); - struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); - struct wsa883x_tz_priv *pdata = &wsa883x->tz_pdata; + int temp = 0; - ucontrol->value.integer.value[0] = pdata->t0_init; - dev_dbg(component->dev, "%s: t0 init %d\n", __func__, pdata->t0_init); + wsa883x_get_temperature(component, &temp); + ucontrol->value.integer.value[0] = temp; return 0; } -static int wsa883x_set_t0_init(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = - snd_soc_kcontrol_component(kcontrol); - struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); - struct wsa883x_tz_priv *pdata = &wsa883x->tz_pdata; - - pdata->t0_init = ucontrol->value.integer.value[0]; - dev_dbg(component->dev, "%s: t0 init %d\n", __func__, pdata->t0_init); - - return 0; -} - -static const struct snd_kcontrol_new wsa_snd_controls[] = { - SOC_ENUM_EXT("WSA PA Gain", wsa_pa_gain_enum, - wsa_pa_gain_get, wsa_pa_gain_put), - SOC_SINGLE_EXT("WSA PA Mute", SND_SOC_NOPM, 0, 1, 0, - wsa883x_get_mute, wsa883x_set_mute), - SOC_SINGLE_EXT("WSA T0 Init", SND_SOC_NOPM, 0, 1, 0, - wsa883x_get_t0_init, wsa883x_set_t0_init), -}; - static ssize_t wsa883x_codec_version_read(struct snd_info_entry *entry, void *file_private_data, struct file *file, char __user *buf, size_t count, loff_t pos) @@ -454,89 +491,8 @@ EXPORT_SYMBOL(wsa883x_codec_info_create_codec_entry); static void wsa883x_regcache_sync(struct wsa883x_priv *wsa883x) { mutex_lock(&wsa883x->res_lock); - if (wsa883x->state != WSA883X_DEV_READY) { - regcache_mark_dirty(wsa883x->regmap); - regcache_sync(wsa883x->regmap); - wsa883x->state = WSA883X_DEV_READY; - } - mutex_unlock(&wsa883x->res_lock); -} - -static int wsa883x_visense_txfe_ctrl(struct snd_soc_component *component, - bool enable, u8 isense1_gain, - u8 isense2_gain, u8 vsense_gain) -{ - struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); - - dev_dbg(component->dev, - "%s: enable:%d, isense1 gain: %d, isense2 gain: %d, vsense_gain %d\n", - __func__, enable, isense1_gain, isense2_gain, vsense_gain); - - return 0; -} - -static int wsa883x_visense_adc_ctrl(struct snd_soc_component *component, - bool enable) -{ - - dev_dbg(component->dev, "%s: enable:%d\n", __func__, enable); - - return 0; -} - -static void wsa883x_bandgap_ctrl(struct snd_soc_component *component, - bool enable) -{ - struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); - - dev_dbg(component->dev, "%s: enable:%d, bg_count:%d\n", __func__, - enable, wsa883x->bg_cnt); - mutex_lock(&wsa883x->bg_lock); - if (enable) { - ++wsa883x->bg_cnt; - if (wsa883x->bg_cnt == 1) { - snd_soc_component_update_bits(component, - WSA883X_OP_CTL, - 0x08, 0x08); - } - } else { - --wsa883x->bg_cnt; - if (wsa883x->bg_cnt <= 0) { - WARN_ON(wsa883x->bg_cnt < 0); - wsa883x->bg_cnt = 0; - snd_soc_component_update_bits(component, - WSA883X_OP_CTL, 0x08, 0x00); - } - } - mutex_unlock(&wsa883x->bg_lock); -} - -static void wsa883x_clk_ctrl(struct snd_soc_component *component, bool enable) -{ - struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); - - dev_dbg(component->dev, "%s: enable:%d, clk_count:%d\n", __func__, - enable, wsa883x->clk_cnt); - mutex_lock(&wsa883x->res_lock); - if (enable) { - ++wsa883x->clk_cnt; - if (wsa883x->clk_cnt == 1) { - snd_soc_component_write(component, - WSA883X_CDC_CLK_CTL, 0x01); - snd_soc_component_write(component, - WSA883X_CLK_CTL, 0x01); - } - } else { - --wsa883x->clk_cnt; - if (wsa883x->clk_cnt <= 0) { - WARN_ON(wsa883x->clk_cnt < 0); - wsa883x->clk_cnt = 0; - snd_soc_component_write(component, - WSA883X_CDC_CLK_CTL, 0x00); - snd_soc_component_write(component, - WSA883X_CLK_CTL, 0x00); - } - } + regcache_mark_dirty(wsa883x->regmap); + regcache_sync(wsa883x->regmap); mutex_unlock(&wsa883x->res_lock); } @@ -590,12 +546,54 @@ static int wsa883x_set_visense(struct snd_kcontrol *kcontrol, return 0; } +static int wsa883x_get_ext_vdd_spk(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wsa883x->ext_vdd_spk; + + return 0; +} + +static int wsa883x_put_ext_vdd_spk(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + int value = ucontrol->value.integer.value[0]; + + dev_dbg(component->dev, "%s: Ext VDD SPK enable current %d, new %d\n", + __func__, wsa883x->ext_vdd_spk, value); + wsa883x->ext_vdd_spk = value; + + return 0; +} + static const struct snd_kcontrol_new wsa883x_snd_controls[] = { + SOC_ENUM_EXT("WSA PA Gain", wsa_pa_gain_enum, + wsa_pa_gain_get, wsa_pa_gain_put), + + SOC_SINGLE_EXT("WSA PA Mute", SND_SOC_NOPM, 0, 1, 0, + wsa883x_get_mute, wsa883x_set_mute), + + SOC_SINGLE_EXT("WSA Temp", SND_SOC_NOPM, 0, 1, 0, + wsa_get_temp, NULL), + + SOC_ENUM_EXT("WSA MODE", wsa_dev_mode_enum, + wsa_dev_mode_get, wsa_dev_mode_put), + SOC_SINGLE_EXT("COMP Switch", SND_SOC_NOPM, 0, 1, 0, wsa883x_get_compander, wsa883x_set_compander), SOC_SINGLE_EXT("VISENSE Switch", SND_SOC_NOPM, 0, 1, 0, wsa883x_get_visense, wsa883x_set_visense), + + SOC_SINGLE_EXT("External VDD_SPK", SND_SOC_NOPM, 0, 1, 0, + wsa883x_get_ext_vdd_spk, wsa883x_put_ext_vdd_spk), }; static const struct snd_kcontrol_new swr_dac_port[] = { @@ -661,8 +659,14 @@ static int wsa883x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, &port_type[0]); break; case SND_SOC_DAPM_POST_PMU: + swr_slvdev_datapath_control(wsa883x->swr_slave, + wsa883x->swr_slave->dev_num, + true); break; case SND_SOC_DAPM_PRE_PMD: + swr_slvdev_datapath_control(wsa883x->swr_slave, + wsa883x->swr_slave->dev_num, + false); break; case SND_SOC_DAPM_POST_PMD: wsa883x_set_port(component, SWR_DAC_PORT, @@ -694,52 +698,7 @@ static int wsa883x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, return 0; } -static int wsa883x_rdac_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_component *component = - snd_soc_dapm_to_component(w->dapm); - struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); - - dev_dbg(component->dev, "%s: %s event: %d visense %d\n", __func__, - w->name, event, wsa883x->visense_enable); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - mutex_lock(&wsa883x->temp_lock); - wsa883x_resource_acquire(component, ENABLE); - mutex_unlock(&wsa883x->temp_lock); - break; - case SND_SOC_DAPM_POST_PMD: - swr_slvdev_datapath_control(wsa883x->swr_slave, - wsa883x->swr_slave->dev_num, - false); - mutex_lock(&wsa883x->temp_lock); - wsa883x_resource_acquire(component, DISABLE); - mutex_unlock(&wsa883x->temp_lock); - break; - } - return 0; -} - -static int wsa883x_ramp_pa_gain(struct snd_soc_component *component, - int min_gain, int max_gain, int udelay) -{ - int val; - - for (val = min_gain; max_gain <= val; val--) { - snd_soc_component_update_bits(component, WSA883X_SPKR_DRV_GAIN, - 0xF0, val << 4); - /* - * 1ms delay is needed for every step change in gain as per - * HW requirement. - */ - usleep_range(udelay, udelay + 10); - } - return 0; -} - -static int wsa883x_spkr_pa_event(struct snd_soc_dapm_widget *w, +static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = @@ -750,54 +709,16 @@ static int wsa883x_spkr_pa_event(struct snd_soc_dapm_widget *w, dev_dbg(component->dev, "%s: %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_PRE_PMU: - swr_slvdev_datapath_control(wsa883x->swr_slave, - wsa883x->swr_slave->dev_num, - true); - /* Set register mode if compander is not enabled */ - if (!wsa883x->comp_enable) - snd_soc_component_update_bits(component, - WSA883X_SPKR_DRV_GAIN, - 0x08, 0x08); - else - snd_soc_component_update_bits(component, - WSA883X_SPKR_DRV_GAIN, - 0x08, 0x00); - + /* TODO Vote for Global PA */ break; + case SND_SOC_DAPM_POST_PMU: - if (!wsa883x->comp_enable) { - max_gain = wsa883x->pa_gain; - /* - * Gain has to set incrementally in 4 steps - * as per HW sequence - */ - if (max_gain > G_4P5DB) - min_gain = G_0DB; - else - min_gain = max_gain + 3; - /* - * 1ms delay is needed before change in gain - * as per HW requirement. - */ - usleep_range(1000, 1010); - wsa883x_ramp_pa_gain(component, min_gain, max_gain, - 1000); - } - if (wsa883x->visense_enable) { - wsa883x_visense_txfe_ctrl(component, ENABLE, - 0x00, 0x03, 0x01); - wsa883x_visense_adc_ctrl(component, ENABLE); - } /* Force remove group */ swr_remove_from_group(wsa883x->swr_slave, wsa883x->swr_slave->dev_num); break; case SND_SOC_DAPM_POST_PMD: - if (wsa883x->visense_enable) { - wsa883x_visense_adc_ctrl(component, DISABLE); - wsa883x_visense_txfe_ctrl(component, DISABLE, - 0x00, 0x01, 0x01); - } + /* TODO Unvote for Global PA */ break; } return 0; @@ -805,28 +726,17 @@ static int wsa883x_spkr_pa_event(struct snd_soc_dapm_widget *w, static const struct snd_soc_dapm_widget wsa883x_dapm_widgets[] = { SND_SOC_DAPM_INPUT("IN"), - SND_SOC_DAPM_MIXER_E("SWR DAC_Port", SND_SOC_NOPM, 0, 0, swr_dac_port, ARRAY_SIZE(swr_dac_port), wsa883x_enable_swr_dac_port, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_DAC_E("RDAC", NULL, WSA883X_SPKR_DAC_CTL, 7, 0, - wsa883x_rdac_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_PGA_E("SPKR PGA", WSA883X_SPKR_DRV_EN, 7, 0, NULL, 0, - wsa883x_spkr_pa_event, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_OUTPUT("SPKR"), + SND_SOC_DAPM_SPK("SPKR", wsa883x_spkr_event), }; static const struct snd_soc_dapm_route wsa883x_audio_map[] = { {"SWR DAC_Port", "Switch", "IN"}, - {"RDAC", NULL, "SWR DAC_Port"}, - {"SPKR PGA", NULL, "RDAC"}, - {"SPKR", NULL, "SPKR PGA"}, + {"SPKR", NULL, "SWR DAC_Port"}, }; int wsa883x_set_channel_map(struct snd_soc_component *component, u8 *port, @@ -856,7 +766,7 @@ int wsa883x_set_channel_map(struct snd_soc_component *component, u8 *port, } EXPORT_SYMBOL(wsa883x_set_channel_map); -static void wsa883x_init(struct snd_soc_component *component) +static void wsa883x_codec_init(struct snd_soc_component *component) { struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); @@ -865,44 +775,19 @@ static void wsa883x_init(struct snd_soc_component *component) } -static int32_t wsa883x_resource_acquire(struct snd_soc_component *component, - bool enable) -{ - wsa883x_clk_ctrl(component, enable); - wsa883x_bandgap_ctrl(component, enable); - return 0; -} - static int32_t wsa883x_temp_reg_read(struct snd_soc_component *component, struct wsa_temp_register *wsa_temp_reg) { struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); - struct swr_device *dev; - u8 retry = WSA883X_NUM_RETRY; - u8 devnum = 0; if (!wsa883x) { dev_err(component->dev, "%s: wsa883x is NULL\n", __func__); return -EINVAL; } - dev = wsa883x->swr_slave; - if (dev && (wsa883x->state == WSA883X_DEV_DOWN)) { - while (swr_get_logical_dev_num(dev, dev->addr, &devnum) && - retry--) { - /* Retry after 1 msec delay */ - usleep_range(1000, 1100); - } - if (retry == 0) { - dev_err(component->dev, - "%s get devnum %d for dev addr %lx failed\n", - __func__, devnum, dev->addr); - return -EINVAL; - } - } - wsa883x_regcache_sync(wsa883x); - mutex_lock(&wsa883x->temp_lock); - wsa883x_resource_acquire(component, ENABLE); + mutex_lock(&wsa883x->res_lock); + + /* TODO Vote for global PA */ snd_soc_component_update_bits(component, WSA883X_TADC_VALUE_CTL, 0x01, 0x00); wsa_temp_reg->dmeas_msb = snd_soc_component_read32( @@ -920,12 +805,82 @@ static int32_t wsa883x_temp_reg_read(struct snd_soc_component *component, wsa_temp_reg->d2_lsb = snd_soc_component_read32( component, WSA883X_OTP_REG_4); - wsa883x_resource_acquire(component, DISABLE); - mutex_unlock(&wsa883x->temp_lock); + /* TODO Unvote for global PA */ + mutex_unlock(&wsa883x->res_lock); return 0; } +static int wsa883x_get_temperature(struct snd_soc_component *component, + int *temp) +{ + struct snd_soc_component *component; + struct wsa_temp_register reg; + int dmeas, d1, d2; + int ret = 0; + int temp_val = 0; + int t1 = T1_TEMP; + int t2 = T2_TEMP; + u8 retry = WSA883X_TEMP_RETRY; + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + if (!wsa883x) + return -EINVAL; + + do { + ret = wsa883x_temp_reg_read(component, ®) + if (ret) { + pr_err("%s: temp read failed: %d, current temp: %d\n", + __func__, ret, wsa883x->curr_temp); + if (temp) + *temp = wsa883x->curr_temp; + return 0; + } + /* + * Temperature register values are expected to be in the + * following range. + * d1_msb = 68 - 92 and d1_lsb = 0, 64, 128, 192 + * d2_msb = 185 -218 and d2_lsb = 0, 64, 128, 192 + */ + if ((reg.d1_msb < 68 || reg.d1_msb > 92) || + (!(reg.d1_lsb == 0 || reg.d1_lsb == 64 || reg.d1_lsb == 128 || + reg.d1_lsb == 192)) || + (reg.d2_msb < 185 || reg.d2_msb > 218) || + (!(reg.d2_lsb == 0 || reg.d2_lsb == 64 || reg.d2_lsb == 128 || + reg.d2_lsb == 192))) { + printk_ratelimited("%s: Temperature registers[%d %d %d %d] are out of range\n", + __func__, reg.d1_msb, reg.d1_lsb, reg.d2_msb, + reg.d2_lsb); + } + dmeas = ((reg.dmeas_msb << 0x8) | reg.dmeas_lsb) >> 0x6; + d1 = ((reg.d1_msb << 0x8) | reg.d1_lsb) >> 0x6; + d2 = ((reg.d2_msb << 0x8) | reg.d2_lsb) >> 0x6; + + if (d1 == d2) + temp_val = TEMP_INVALID; + else + temp_val = t1 + (((dmeas - d1) * (t2 - t1))/(d2 - d1)); + + if (temp_val <= LOW_TEMP_THRESHOLD || + temp_val >= HIGH_TEMP_THRESHOLD) { + pr_debug("%s: T0: %d is out of range[%d, %d]\n", __func__, + temp_val, LOW_TEMP_THRESHOLD, HIGH_TEMP_THRESHOLD); + if (retry--) + msleep(10); + } else { + break; + } + } while (retry); + + wsa883x->curr_temp = temp_val; + if (temp) + *temp = temp_val; + pr_debug("%s: t0 measured: %d dmeas = %d, d1 = %d, d2 = %d\n", + __func__, temp_val, dmeas, d1, d2); + + return ret; +} + static int wsa883x_codec_probe(struct snd_soc_component *component) { struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); @@ -937,17 +892,9 @@ static int wsa883x_codec_probe(struct snd_soc_component *component) dev = wsa883x->swr_slave; wsa883x->component = component; - mutex_init(&wsa883x->bg_lock); - wsa883x_init(component); - snprintf(wsa883x->tz_pdata.name, sizeof(wsa883x->tz_pdata.name), - "%s.%x", "wsatz", (u8)dev->addr); - wsa883x->bg_cnt = 0; - wsa883x->clk_cnt = 0; - wsa883x->tz_pdata.component = component; - wsa883x->tz_pdata.wsa_temp_reg_read = wsa883x_temp_reg_read; - wsa883x_init_thermal(&wsa883x->tz_pdata); - snd_soc_add_component_controls(component, wsa_snd_controls, - ARRAY_SIZE(wsa_snd_controls)); + wsa883x_codec_init(component); + wsa883x->global_pa_cnt = 0; + return 0; } @@ -955,9 +902,10 @@ static void wsa883x_codec_remove(struct snd_soc_component *component) { struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); - if (wsa883x->tz_pdata.tz_dev) - wsa883x_deinit_thermal(wsa883x->tz_pdata.tz_dev); - mutex_destroy(&wsa883x->bg_lock); + if (!wsa883x) + return; + + snd_soc_component_exit_regmap(component); return; } @@ -1046,8 +994,6 @@ static int wsa883x_swr_probe(struct swr_device *pdev) goto dev_err; } mutex_init(&wsa883x->res_lock); - mutex_init(&wsa883x->temp_lock); - wsa883x->state = WSA883X_DEV_UP; #ifdef CONFIG_DEBUG_FS if (!wcd938x->debugfs_dent) { @@ -1103,10 +1049,7 @@ static int wsa883x_swr_remove(struct swr_device *pdev) wsa883x->debugfs_dent = NULL; #endif mutex_destroy(&wsa883x->res_lock); - mutex_destroy(&wsa883x->temp_lock); snd_soc_unregister_component(&pdev->dev); - if (wsa883x->pd_gpio) - gpio_free(wsa883x->pd_gpio); swr_set_dev_data(pdev, NULL); return 0; } -- GitLab From 6f4285c583fce52f4e0c949cebdb715df617b4af Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Tue, 29 Oct 2019 16:17:00 -0700 Subject: [PATCH 1278/1645] ASoC: add echo ref support for SEN MI2S Add SEN_MI2S_RX to echo_ref_rx so it can be used for Audio EC reference. CRs-Fixed: 2553377 Change-Id: Id326c6f80b0553bd1031b2c4a641d6bc716d03a7 Signed-off-by: Vignesh Kulothungan --- asoc/msm-pcm-routing-v2.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index c47a6c9452c8..8bbf48b957cd 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -5450,6 +5450,10 @@ static int get_ec_ref_port_id(int value, int *index) *index = 37; port_id = AFE_PORT_ID_HDMI_OVER_DP_RX; break; + case 38: + *index = 38; + port_id = AFE_PORT_ID_SENARY_MI2S_RX; + break; default: *index = 0; /* NONE */ pr_err("%s: Invalid value %d\n", __func__, value); @@ -5507,7 +5511,7 @@ static const char *const ec_ref_rx[] = { "None", "SLIM_RX", "I2S_RX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_2", "SLIM_7_RX", "RX_CDC_DMA_RX_0", "RX_CDC_DMA_RX_1", "RX_CDC_DMA_RX_2", "RX_CDC_DMA_RX_3", "TX_CDC_DMA_TX_0", "TERT_TDM_RX_2", "SEC_TDM_TX_0", - "DISPLAY_PORT1", + "DISPLAY_PORT1", "SEN_MI2S_RX", }; static const struct soc_enum msm_route_ec_ref_rx_enum[] = { -- GitLab From 1a58793f4a4afc28d4ed145f00a07272a4ff60be Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 1 Nov 2019 12:18:39 +0530 Subject: [PATCH 1279/1645] asoc: codecs: CSR access requires AHB clock from bolero 1.1 From bolero 1.1, Bolero and SWR CSR moving to AHB clock and no need to enable other macro RCG clocks. Change-Id: I6663196a88dbf07868d6426bdda98f33e42004d1 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc.c | 36 ++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index dde471972335..ac8d69376692 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -104,21 +104,25 @@ static int __bolero_reg_read(struct bolero_priv *priv, if (priv->macro_params[VA_MACRO].dev) pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev); - /* Request Clk before register access */ - ret = bolero_clk_rsc_request_clock(priv->macro_params[macro_id].dev, + if (priv->version < BOLERO_VERSION_2_0) { + /* Request Clk before register access */ + ret = bolero_clk_rsc_request_clock(priv->macro_params[macro_id].dev, priv->macro_params[macro_id].default_clk_id, priv->macro_params[macro_id].clk_id_req, true); - if (ret < 0) { - dev_err_ratelimited(priv->dev, - "%s: Failed to enable clock, ret:%d\n", __func__, ret); - goto err; + if (ret < 0) { + dev_err_ratelimited(priv->dev, + "%s: Failed to enable clock, ret:%d\n", + __func__, ret); + goto err; + } } bolero_ahb_read_device( priv->macro_params[macro_id].io_base, reg, val); - bolero_clk_rsc_request_clock(priv->macro_params[macro_id].dev, + if (priv->version < BOLERO_VERSION_2_0) + bolero_clk_rsc_request_clock(priv->macro_params[macro_id].dev, priv->macro_params[macro_id].default_clk_id, priv->macro_params[macro_id].clk_id_req, false); @@ -148,21 +152,25 @@ static int __bolero_reg_write(struct bolero_priv *priv, if (priv->macro_params[VA_MACRO].dev) pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev); - /* Request Clk before register access */ - ret = bolero_clk_rsc_request_clock(priv->macro_params[macro_id].dev, + if (priv->version < BOLERO_VERSION_2_0) { + /* Request Clk before register access */ + ret = bolero_clk_rsc_request_clock(priv->macro_params[macro_id].dev, priv->macro_params[macro_id].default_clk_id, priv->macro_params[macro_id].clk_id_req, true); - if (ret < 0) { - dev_err_ratelimited(priv->dev, - "%s: Failed to enable clock, ret:%d\n", __func__, ret); - goto err; + if (ret < 0) { + dev_err_ratelimited(priv->dev, + "%s: Failed to enable clock, ret:%d\n", + __func__, ret); + goto err; + } } bolero_ahb_write_device( priv->macro_params[macro_id].io_base, reg, val); - bolero_clk_rsc_request_clock(priv->macro_params[macro_id].dev, + if (priv->version < BOLERO_VERSION_2_0) + bolero_clk_rsc_request_clock(priv->macro_params[macro_id].dev, priv->macro_params[macro_id].default_clk_id, priv->macro_params[macro_id].clk_id_req, false); -- GitLab From dcf2ab2380fcd3e906236e84d7a62a440b6761ef Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 1 Nov 2019 15:33:47 +0530 Subject: [PATCH 1280/1645] asoc: routing: Add route controls for RX_CDC_DMA_RX_1 Add controls required for RX_CDC_DMA_RX_1 used for AUX speaker path in bengal target. Change-Id: Ia7ec59b19960e3c3f3a844406671303f72787bc1 Signed-off-by: Laxminath Kasam --- asoc/msm-pcm-routing-v2.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index c47a6c9452c8..829ae9f3f7f7 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -17334,6 +17334,25 @@ static const struct snd_kcontrol_new rx_cdc_dma_rx_0_port_mixer_controls[] = { }; +static const struct snd_kcontrol_new rx_cdc_dma_rx_1_port_mixer_controls[] = { + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_RX, @@ -24176,6 +24195,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_NOPM, 0, 0, rx_cdc_dma_rx_0_voice_mixer_controls, ARRAY_SIZE(rx_cdc_dma_rx_0_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_1_Voice Mixer", + SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_1_voice_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_1_voice_mixer_controls)), SND_SOC_DAPM_MIXER("Voip_Tx Mixer", SND_SOC_NOPM, 0, 0, tx_voip_mixer_controls, ARRAY_SIZE(tx_voip_mixer_controls)), @@ -24379,6 +24402,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, rx_cdc_dma_rx_0_port_mixer_controls, ARRAY_SIZE(rx_cdc_dma_rx_0_port_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_1 Port Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_1_port_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_1_port_mixer_controls)), SND_SOC_DAPM_MIXER("QCHAT_Tx Mixer", SND_SOC_NOPM, 0, 0, tx_qchat_mixer_controls, ARRAY_SIZE(tx_qchat_mixer_controls)), @@ -26961,6 +26987,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0_Voice Mixer"}, + {"RX_CDC_DMA_RX_1_Voice Mixer", "Voip", "VOIP_DL"}, + {"RX_CDC_DMA_RX_1_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"RX_CDC_DMA_RX_1_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1_Voice Mixer"}, + {"VOC_EXT_EC MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"VOC_EXT_EC MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"VOC_EXT_EC MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, @@ -28102,6 +28133,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"RX_CDC_DMA_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0 Port Mixer"}, + {"RX_CDC_DMA_RX_1 Port Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"RX_CDC_DMA_RX_1 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"RX_CDC_DMA_RX_1 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"RX_CDC_DMA_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1 Port Mixer"}, + {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"SLIMBUS_0_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, -- GitLab From a9675d1a5d76efae5d63f97632ea6fba45b81e24 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 23 Oct 2019 12:32:29 +0530 Subject: [PATCH 1281/1645] ASoC: wcd937x: Fix audio distortion issue during headset record Audio is distorted during first 3 secs on headset record while doing device switch from dmic to headset mic. Disable BCS before slow insertion detection and enable it afterwards to resolve the issue. Change-Id: Icb18a0b5decb0c0bd9959bce7cced70a27566d41 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/internal.h | 4 ++++ asoc/codecs/wcd937x/wcd937x-mbhc.c | 10 ++++++++++ asoc/codecs/wcd937x/wcd937x.c | 15 +++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index cd11c858b413..faf011860448 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -133,6 +133,7 @@ enum { WCD_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */ WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */ WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */ + WCD_BOLERO_EVT_BCS_CLK_OFF, }; enum { @@ -164,6 +165,9 @@ enum { WCD937X_NUM_IRQS, }; +extern void wcd937x_disable_bcs_before_slow_insert( + struct snd_soc_component *component, + bool bcs_disable); extern struct wcd937x_mbhc *wcd937x_soc_get_mbhc( struct snd_soc_component *component); extern int wcd937x_mbhc_micb_adjust_voltage(struct snd_soc_component *component, diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.c b/asoc/codecs/wcd937x/wcd937x-mbhc.c index 2159cabe7120..039f5118bed1 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.c +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.c @@ -810,6 +810,15 @@ static void wcd937x_mbhc_moisture_polling_ctrl(struct wcd_mbhc *mbhc, 0x04, (enable << 2)); } +static void wcd937x_mbhc_bcs_enable(struct wcd_mbhc *mbhc, + bool bcs_enable) +{ + if (bcs_enable) + wcd937x_disable_bcs_before_slow_insert(mbhc->component, false); + else + wcd937x_disable_bcs_before_slow_insert(mbhc->component, true); +} + static const struct wcd_mbhc_cb mbhc_cb = { .request_irq = wcd937x_mbhc_request_irq, .irq_control = wcd937x_mbhc_irq_control, @@ -834,6 +843,7 @@ static const struct wcd_mbhc_cb mbhc_cb = { .mbhc_get_moisture_status = wcd937x_mbhc_get_moisture_status, .mbhc_moisture_polling_ctrl = wcd937x_mbhc_moisture_polling_ctrl, .mbhc_moisture_detect_en = wcd937x_mbhc_moisture_detect_en, + .bcs_enable = wcd937x_mbhc_bcs_enable, }; static int wcd937x_get_hph_type(struct snd_kcontrol *kcontrol, diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 94e59d98dd7d..6a6caf1376db 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1517,6 +1517,21 @@ int wcd937x_micbias_control(struct snd_soc_component *component, } EXPORT_SYMBOL(wcd937x_micbias_control); +void wcd937x_disable_bcs_before_slow_insert(struct snd_soc_component *component, + bool bcs_disable) +{ + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); + + if (wcd937x->update_wcd_event) { + if (bcs_disable) + wcd937x->update_wcd_event(wcd937x->handle, + WCD_BOLERO_EVT_BCS_CLK_OFF, 0); + else + wcd937x->update_wcd_event(wcd937x->handle, + WCD_BOLERO_EVT_BCS_CLK_OFF, 1); + } +} + static int wcd937x_get_logical_addr(struct swr_device *swr_dev) { int ret = 0; -- GitLab From 91850713f55407c7f7ee0104205e6dcfbeabcd85 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Mon, 4 Nov 2019 15:17:15 -0800 Subject: [PATCH 1282/1645] asoc: codecs: bolero: Do not process ssr disable if already down If codec receives ssr disable notification when already in disabled state do not have to process it. This makes sure codec register access are not done when not necessary. Change-Id: Iafc2b03d7c707c46c69ca995d36119929c34c222 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/bolero-cdc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index dde471972335..59e3d4378dc2 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -717,6 +717,12 @@ static void bolero_ssr_disable(struct device *dev, void *data) struct bolero_priv *priv = data; int macro_idx; + if (!priv->dev_up) { + dev_err_ratelimited(priv->dev, + "%s: already disabled\n", __func__); + return; + } + bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_PA_OFF_PRE_SSR); regcache_cache_only(priv->regmap, true); -- GitLab From d6b629414cd4a5d11f8223b450c17169ea9a7c0f Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 5 Nov 2019 12:38:20 +0530 Subject: [PATCH 1283/1645] asoc: wsa881x: Update break after post_fs event Update missing break after post_fs event handling. Change-Id: I50894d21445c501366298e8ee8f1f66b854ac44f Signed-off-by: Laxminath Kasam --- asoc/codecs/wsa881x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index 966fa8a2081b..fc4f12387be1 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -1395,6 +1395,7 @@ static int wsa881x_event_notify(struct notifier_block *nb, snd_soc_component_update_bits(wsa881x->component, WSA881X_SPKR_DRV_EN, 0x80, 0x80); + break; default: break; } -- GitLab From 688db8aa066e748302a16be33fe5bb822abd978a Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 5 Nov 2019 13:11:30 +0530 Subject: [PATCH 1284/1645] dsp: q6afe: Update lpass hw votes to maintain separate handles lpass client handle variable stores latest lpass hw vote. During PDR, core hw vote release proceed to call unvote for stale handle since above variable is set to non-zero as part of audio hm vote. Maintain separate handles for respective lpass hw votes inorder to fix this. Change-Id: I432ce38b253ce6d18a25f9845fa694912718c74f Signed-off-by: Laxminath Kasam --- dsp/q6afe.c | 22 ++++++++++++++-------- include/dsp/q6afe-v2.h | 12 ++++++++---- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 6111832bbaee..7297a1ed08bf 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -110,7 +110,7 @@ struct afe_ctl { wait_queue_head_t wait_wakeup; struct task_struct *task; wait_queue_head_t lpass_core_hw_wait; - uint32_t lpass_hw_core_client_hdl; + uint32_t lpass_hw_core_client_hdl[AFE_LPASS_CORE_HW_VOTE_MAX]; void (*tx_cb)(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv); void (*rx_cb)(uint32_t opcode, @@ -571,6 +571,8 @@ static bool afe_token_is_valid(uint32_t token) static int32_t afe_callback(struct apr_client_data *data, void *priv) { + uint16_t i = 0; + if (!data) { pr_err("%s: Invalid param data\n", __func__); return -EINVAL; @@ -598,7 +600,8 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) /* Reset the core client handle in SSR/PDR use cases */ mutex_lock(&this_afe.afe_cmd_lock); - this_afe.lpass_hw_core_client_hdl = 0; + for (i = 0; i < AFE_LPASS_CORE_HW_VOTE_MAX; i++) + this_afe.lpass_hw_core_client_hdl[i] = 0; mutex_unlock(&this_afe.afe_cmd_lock); /* @@ -673,7 +676,9 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) pr_debug("%s: AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST handle %d\n", __func__, payload[0]); - this_afe.lpass_hw_core_client_hdl = payload[0]; + if (data->token < AFE_LPASS_CORE_HW_VOTE_MAX) + this_afe.lpass_hw_core_client_hdl[data->token] = + payload[0]; atomic_set(&this_afe.state, 0); atomic_set(&this_afe.status, 0); wake_up(&this_afe.lpass_core_hw_wait); @@ -9086,7 +9091,8 @@ int __init afe_init(void) this_afe.mmap_handle = 0; this_afe.vi_tx_port = -1; this_afe.vi_rx_port = -1; - this_afe.lpass_hw_core_client_hdl = 0; + for (i = 0; i < AFE_LPASS_CORE_HW_VOTE_MAX; i++) + this_afe.lpass_hw_core_client_hdl[i] = 0; this_afe.prot_cfg.mode = MSM_SPKR_PROT_DISABLED; this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; @@ -9218,7 +9224,7 @@ int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name, cmd_ptr->hdr.pkt_size = sizeof(hw_vote_cfg); cmd_ptr->hdr.src_port = 0; cmd_ptr->hdr.dest_port = 0; - cmd_ptr->hdr.token = 0; + cmd_ptr->hdr.token = hw_block_id; cmd_ptr->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST; cmd_ptr->hw_block_id = hw_block_id; strlcpy(cmd_ptr->client_name, client_name, @@ -9259,9 +9265,9 @@ int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name, goto done; } - *client_handle = this_afe.lpass_hw_core_client_hdl; + *client_handle = this_afe.lpass_hw_core_client_hdl[hw_block_id]; pr_debug("%s: lpass_hw_core_client_hdl %d\n", __func__, - this_afe.lpass_hw_core_client_hdl); + this_afe.lpass_hw_core_client_hdl[hw_block_id]); done: mutex_unlock(&this_afe.afe_cmd_lock); return ret; @@ -9291,7 +9297,7 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle) mutex_lock(&this_afe.afe_cmd_lock); - if (!this_afe.lpass_hw_core_client_hdl) { + if (!this_afe.lpass_hw_core_client_hdl[hw_block_id]) { pr_debug("%s: SSR in progress, return\n", __func__); goto done; } diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index d1b4f3ccedfd..9e1a0b2f44fb 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -483,10 +483,14 @@ void afe_register_wakeup_irq_callback( int afe_get_doa_tracking_mon(u16 port_id, struct doa_tracking_mon_param *doa_tracking_data); -#define AFE_LPASS_CORE_HW_BLOCK_ID_NONE 0 -#define AFE_LPASS_CORE_HW_BLOCK_ID_AVTIMER 2 -#define AFE_LPASS_CORE_HW_MACRO_BLOCK 3 -#define AFE_LPASS_CORE_HW_DCODEC_BLOCK 4 +enum { + AFE_LPASS_CORE_HW_BLOCK_ID_NONE, + AFE_LPASS_CORE_HW_RSVD, + AFE_LPASS_CORE_HW_BLOCK_ID_AVTIMER, + AFE_LPASS_CORE_HW_MACRO_BLOCK, + AFE_LPASS_CORE_HW_DCODEC_BLOCK, + AFE_LPASS_CORE_HW_VOTE_MAX +}; /* Handles audio-video timer (avtimer) and BTSC vote requests from clients. */ -- GitLab From b03e82dedac5cb6f021181293c700d175e6da890 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 5 Nov 2019 13:35:01 +0530 Subject: [PATCH 1285/1645] asoc: bolero: Update tx swr clk widget for bolero 2.0 TX_SWR_CLK widget is not needed for bolero 2.1. Update it to retain for bolero 2.0. Change-Id: I2b38fb807460ca31d1e968e0eb69a24ce46a531e Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/tx-macro.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index d27a5cf9f039..7a8497139cb5 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1475,10 +1475,6 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v2[] = { SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0, tx_aif3_cap_mixer_v2, ARRAY_SIZE(tx_aif3_cap_mixer_v2)), - - SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, - tx_macro_tx_swr_clk_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v3[] = { @@ -1528,6 +1524,10 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v3[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, + tx_macro_tx_swr_clk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, tx_macro_va_swr_clk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -1921,6 +1921,15 @@ static const struct snd_soc_dapm_route tx_audio_map_v3[] = { {"TX SMIC MUX7", "SWR_MIC9", "TX SWR_MIC9"}, {"TX SMIC MUX7", "SWR_MIC10", "TX SWR_MIC10"}, {"TX SMIC MUX7", "SWR_MIC11", "TX SWR_MIC11"}, + + {"TX SMIC MUX0", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX1", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX2", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX3", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX4", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX5", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX6", NULL, "TX_SWR_CLK"}, + {"TX SMIC MUX7", NULL, "TX_SWR_CLK"}, }; static const struct snd_soc_dapm_route tx_audio_map[] = { -- GitLab From 23360532688736c94578c87a54703c12769ada75 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 5 Nov 2019 17:22:07 +0530 Subject: [PATCH 1286/1645] asoc: codecs: wcd937x: Update micbias pull up widgets Add micbias pullup widgets required for VA usecase. Change-Id: I3f2d0ce3d409297fb5e2bf0468258aaee9365293 Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd937x/wcd937x.c | 59 +++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 94e59d98dd7d..9c32d0a79fa0 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1642,6 +1642,51 @@ static int wcd937x_codec_enable_micbias(struct snd_soc_dapm_widget *w, return __wcd937x_codec_enable_micbias(w, event); } +static int __wcd937x_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + int micb_num; + + dev_dbg(component->dev, "%s: wname: %s, event: %d\n", + __func__, w->name, event); + + if (strnstr(w->name, "VA MIC BIAS1", sizeof("VA MIC BIAS1"))) + micb_num = MIC_BIAS_1; + else if (strnstr(w->name, "VA MIC BIAS2", sizeof("VA MIC BIAS2"))) + micb_num = MIC_BIAS_2; + else if (strnstr(w->name, "VA MIC BIAS3", sizeof("VA MIC BIAS3"))) + micb_num = MIC_BIAS_3; + else + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wcd937x_micbias_control(component, micb_num, + MICB_PULLUP_ENABLE, true); + break; + case SND_SOC_DAPM_POST_PMU: + /* 1 msec delay as per HW requirement */ + usleep_range(1000, 1100); + break; + case SND_SOC_DAPM_POST_PMD: + wcd937x_micbias_control(component, micb_num, + MICB_PULLUP_DISABLE, true); + break; + }; + + return 0; + +} + +static int wcd937x_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + return __wcd937x_codec_enable_micbias_pullup(w, event); +} + static int wcd937x_rx_hph_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2052,6 +2097,20 @@ static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("HPHL"), SND_SOC_DAPM_OUTPUT("HPHR"), + /* micbias pull up widgets*/ + SND_SOC_DAPM_MICBIAS_E("VA MIC BIAS1", SND_SOC_NOPM, 0, 0, + wcd937x_codec_enable_micbias_pullup, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("VA MIC BIAS2", SND_SOC_NOPM, 0, 0, + wcd937x_codec_enable_micbias_pullup, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("VA MIC BIAS3", SND_SOC_NOPM, 0, 0, + wcd937x_codec_enable_micbias_pullup, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + }; static const struct snd_soc_dapm_widget wcd9375_dapm_widgets[] = { -- GitLab From 5b1458d315f6cad0f32611ca3af19e3b0871f0c9 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 5 Nov 2019 18:32:22 +0530 Subject: [PATCH 1287/1645] asoc: codecs: fix compile error for bengal_32 For bengal_32 local compile fails. Update the condition check in make to avoid compile of wsa and hdmi modules for bengal, bengal_32. Change-Id: I90db0a36b4c435874137d312545e3757f335fa78 Signed-off-by: Laxminath Kasam --- asoc/codecs/Android.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index da39e8c8139d..5e3114e479f6 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -111,7 +111,7 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk endif ########################################################### -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), bengal)) +ifneq ($(call is-board-platform-in-list, bengal),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wsa881x.ko LOCAL_MODULE_KBUILD_NAME := wsa881x_dlkm.ko @@ -148,7 +148,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### -ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), bengal)) +ifneq ($(call is-board-platform-in-list, bengal),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_hdmi.ko LOCAL_MODULE_KBUILD_NAME := hdmi_dlkm.ko -- GitLab From c9431f11117b8389e09b03577254667d2cdaccd9 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Mon, 4 Nov 2019 19:14:35 +0530 Subject: [PATCH 1288/1645] asoc: codecs: register notifier for all bolero codec variants Playback on speaker is getting mute due to notifier not getting registered. Register notifier for all bolero codecs variants to enable WSA PA. Change-Id: Id13a533af7096f50de2e1a654393c579a81af953 Signed-off-by: Surendar Karka --- asoc/codecs/bolero/bolero-cdc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index dde471972335..863ad59ec5a4 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -1035,10 +1035,9 @@ static void bolero_add_child_devices(struct work_struct *work) pdev->dev.parent = priv->dev; pdev->dev.of_node = node; - if (split_codec) { - priv->dev->platform_data = platdata; + priv->dev->platform_data = platdata; + if (split_codec) priv->wcd_dev = &pdev->dev; - } ret = platform_device_add(pdev); if (ret) { -- GitLab From 0f73819a4ddf6f3791c3780bf0cc909b20ac2814 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 6 Nov 2019 13:00:46 +0530 Subject: [PATCH 1289/1645] asoc: codecs: Update default value for chip wakeup regs For chip wakeup registers used as interrupt mask, set default value provided via dtsi. Change-Id: Ie080006cb7a92e8745636c97a67b8e09ab977832 Signed-off-by: Laxminath Kasam --- asoc/codecs/msm-cdc-pinctrl.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/msm-cdc-pinctrl.c b/asoc/codecs/msm-cdc-pinctrl.c index cb7a52bc301d..5c6ca495faed 100644 --- a/asoc/codecs/msm-cdc-pinctrl.c +++ b/asoc/codecs/msm-cdc-pinctrl.c @@ -196,7 +196,8 @@ static int msm_cdc_pinctrl_probe(struct platform_device *pdev) struct msm_cdc_pinctrl_info *gpio_data; u32 tlmm_gpio[MAX_GPIOS] = {0}; u32 chip_wakeup_reg[MAX_GPIOS] = {0}; - u32 i = 0; + u32 chip_wakeup_default_val[MAX_GPIOS] = {0}; + u32 i = 0, temp = 0; int count = 0; gpio_data = devm_kzalloc(&pdev->dev, @@ -258,6 +259,20 @@ static int msm_cdc_pinctrl_probe(struct platform_device *pdev) gpio_data->chip_wakeup_register[i] = devm_ioremap(&pdev->dev, chip_wakeup_reg[i], 0x4); } + if (of_property_read_u32_array(pdev->dev.of_node, + "qcom,chip-wakeup-default-val", + chip_wakeup_default_val, count)) { + for (i = 0; i < count; i++) { + temp = ioread32(gpio_data->chip_wakeup_register[i]); + if (chip_wakeup_default_val[i]) + temp |= (1 << + gpio_data->chip_wakeup_maskbit[i]); + else + temp &= ~(1 << + gpio_data->chip_wakeup_maskbit[i]); + iowrite32(temp, gpio_data->chip_wakeup_register[i]); + } + } gpio_data->wakeup_reg_count = count; } -- GitLab From e1dc0d79011e467762d4e3f4da06c573388efbba Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 5 Nov 2019 21:19:45 +0530 Subject: [PATCH 1290/1645] asoc: bengal: Use dtsi property for VA, RX-TX macros dailinks Append dailinks for VA and RX-TX macros based on dtsi property. Change-Id: Ib1f4520cd569546e5954d9295b8455f89a3212ca Signed-off-by: Laxminath Kasam --- asoc/bengal.c | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/asoc/bengal.c b/asoc/bengal.c index 21287b408f92..c500a178f350 100644 --- a/asoc/bengal.c +++ b/asoc/bengal.c @@ -5833,6 +5833,8 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) int rc = 0; u32 mi2s_audio_intf = 0; u32 auxpcm_audio_intf = 0; + u32 rxtx_bolero_codec = 0; + u32 va_bolero_codec = 0; u32 val = 0; u32 wcn_btfm_intf = 0; const struct of_device_id *match; @@ -5862,17 +5864,37 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) sizeof(msm_common_be_dai_links)); total_links += ARRAY_SIZE(msm_common_be_dai_links); - memcpy(msm_bengal_dai_links + total_links, - msm_rx_tx_cdc_dma_be_dai_links, - sizeof(msm_rx_tx_cdc_dma_be_dai_links)); - total_links += - ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links); + rc = of_property_read_u32(dev->of_node, + "qcom,rxtx-bolero-codec", + &rxtx_bolero_codec); + if (rc) { + dev_dbg(dev, "%s: No DT match RXTX Macro codec\n", + __func__); + } else { + if (rxtx_bolero_codec) { + memcpy(msm_bengal_dai_links + total_links, + msm_rx_tx_cdc_dma_be_dai_links, + sizeof(msm_rx_tx_cdc_dma_be_dai_links)); + total_links += + ARRAY_SIZE( + msm_rx_tx_cdc_dma_be_dai_links); + } + } - memcpy(msm_bengal_dai_links + total_links, - msm_va_cdc_dma_be_dai_links, - sizeof(msm_va_cdc_dma_be_dai_links)); - total_links += - ARRAY_SIZE(msm_va_cdc_dma_be_dai_links); + rc = of_property_read_u32(dev->of_node, "qcom,va-bolero-codec", + &va_bolero_codec); + if (rc) { + dev_dbg(dev, "%s: No DT match VA Macro codec\n", + __func__); + } else { + if (va_bolero_codec) { + memcpy(msm_bengal_dai_links + total_links, + msm_va_cdc_dma_be_dai_links, + sizeof(msm_va_cdc_dma_be_dai_links)); + total_links += + ARRAY_SIZE(msm_va_cdc_dma_be_dai_links); + } + } rc = of_property_read_u32(dev->of_node, "qcom,mi2s-audio-intf", &mi2s_audio_intf); -- GitLab From f5ec84824d50d3450ebb94dad00376f388ea74b0 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 28 Feb 2018 17:05:09 +0530 Subject: [PATCH 1291/1645] dsp: fix MFC config param payload alignment issue MFC set param failed in DSP due to payload mismatch and stereo echo reference doesn't work. Channel type parameter in MFC config payload is an array of uint16_t, but it is assumed as an array of uint8_t while copying from device structure. Fix this by copying the channel type one by one instead of using memcpy. CRs-Fixed: 2197468 Change-Id: I4b6959e8db56743ac98da75ddc3aa8f56964b4ca Signed-off-by: Aditya Bavanari --- dsp/q6voice.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 77a08ee6fff8..e0491f1c703a 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -4297,6 +4297,7 @@ static int voice_send_cvp_mfc_config_v2(struct voice_data *v) struct cvp_set_mfc_config_cmd_v2 cvp_set_mfc_config_cmd; void *apr_cvp; u16 cvp_handle; + uint8_t ch_idx; struct vss_icommon_param_data_mfc_config_v2_t *cvp_config_param_data = &cvp_set_mfc_config_cmd.cvp_set_mfc_param_v2.param_data; struct vss_param_mfc_config_info_t *mfc_config_info = @@ -4345,9 +4346,15 @@ static int voice_send_cvp_mfc_config_v2(struct voice_data *v) mfc_config_info->num_channels = v->dev_rx.no_of_channels; mfc_config_info->bits_per_sample = 16; mfc_config_info->sample_rate = v->dev_rx.sample_rate; - memcpy(&mfc_config_info->channel_type, - v->dev_rx.channel_mapping, - VSS_NUM_CHANNELS_MAX * sizeof(uint8_t)); + + /* + * Do not use memcpy here as channel_type in mfc_config structure is a + * uint16_t array while channel_mapping array of device is of uint8_t + */ + for (ch_idx = 0; ch_idx < VSS_NUM_CHANNELS_MAX; ch_idx++) { + mfc_config_info->channel_type[ch_idx] = + v->dev_rx.channel_mapping[ch_idx]; + } v->cvp_state = CMD_STATUS_FAIL; v->async_err = 0; -- GitLab From e229197566f3f292c466c3c3fbbbacbcfc8d8343 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 8 Nov 2019 14:51:59 +0530 Subject: [PATCH 1292/1645] soc: soundwire: Handle command response sequence In soundwire version 1.6 as AHB HCLK and MCLK are decoupled, need to wait for clock stop entry and exit scenarios to execute before any further transactions. Keep monitor on COMP status accordingly. Change-Id: I03204526d7dd634a79193b55c6744edca8664d93 Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 33 +++++++++++++++++++++++++++++++++ soc/swrm_registers.h | 1 + 2 files changed, 34 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 008801fae779..c90e6b491b90 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -44,6 +44,7 @@ #define ERR_AUTO_SUSPEND_TIMER_VAL 0x1 #define SWRM_INTERRUPT_STATUS_MASK 0x1FDFD +#define SWRM_LINK_STATUS_RETRY_CNT 0x5 #define SWRM_ROW_48 48 #define SWRM_ROW_50 50 @@ -494,6 +495,31 @@ static int swr_master_bulk_write(struct swr_mstr_ctrl *swrm, u32 *reg_addr, return 0; } +static bool swrm_check_link_status(struct swr_mstr_ctrl *swrm, bool active) +{ + int retry = SWRM_LINK_STATUS_RETRY_CNT; + int ret = false; + int status = active ? 0x1 : 0x0; + + if ((swrm->version <= SWRM_VERSION_1_5_1)) + return true; + + do { + if (swr_master_read(swrm, SWRM_COMP_STATUS) & status) { + ret = true; + break; + } + retry--; + usleep_range(500, 510); + } while (retry); + + if (retry == 0) + dev_err(swrm->dev, "%s: link status not %s\n", __func__, + active ? "connected" : "disconnected"); + + return ret; +} + static bool swrm_is_port_en(struct swr_master *mstr) { return !!(mstr->num_port); @@ -1795,6 +1821,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) case SWRM_INTERRUPT_STATUS_AUTO_ENUM_TABLE_IS_FULL_V2: break; case SWRM_INTERRUPT_STATUS_BUS_RESET_FINISHED_V2: + swrm_check_link_status(swrm, 0x1); break; case SWRM_INTERRUPT_STATUS_CLK_STOP_FINISHED_V2: break; @@ -2615,6 +2642,8 @@ static int swrm_runtime_resume(struct device *dev) swrm_master_init(swrm); /* wait for hw enumeration to complete */ usleep_range(100, 105); + if (!swrm_check_link_status(swrm, 0x1)) + goto exit; swrm_cmd_fifo_wr_cmd(swrm, 0x4, 0xF, 0x0, SWRS_SCP_INT_STATUS_MASK_1); if (swrm->state == SWR_MSTR_SSR) { @@ -2626,6 +2655,8 @@ static int swrm_runtime_resume(struct device *dev) /*wake up from clock stop*/ swr_master_write(swrm, SWRM_MCP_BUS_CTRL_ADDR, 0x2); usleep_range(100, 105); + if (!swrm_check_link_status(swrm, 0x1)) + goto exit; } swrm->state = SWR_MSTR_UP; } @@ -2726,6 +2757,8 @@ static int swrm_runtime_suspend(struct device *dev) SWR_WAKE_IRQ_REGISTER, (void *)swrm); swrm->ipc_wakeup_triggered = false; } + if (!swrm_check_link_status(swrm, 0x0)) + goto exit; } } diff --git a/soc/swrm_registers.h b/soc/swrm_registers.h index 6f2544b17744..63fe4ca744c4 100644 --- a/soc/swrm_registers.h +++ b/soc/swrm_registers.h @@ -17,6 +17,7 @@ #define SWRM_COMP_CFG_ENABLE_SHFT 0x0 #define SWRM_COMP_SW_RESET (SWRM_BASE_ADDRESS+0x00000008) +#define SWRM_COMP_STATUS (SWRM_BASE_ADDRESS+0x00000014) #define SWRM_COMP_PARAMS (SWRM_BASE_ADDRESS+0x100) #define SWRM_COMP_PARAMS_DOUT_PORTS_MASK 0x0000001F -- GitLab From 8e7a8d481b7368e223a24e0f541e82497db1a485 Mon Sep 17 00:00:00 2001 From: Zhou Song Date: Mon, 11 Nov 2019 18:15:07 +0800 Subject: [PATCH 1293/1645] asoc: add new path for in call recording Add path for routing in call uplink and downlink to MultiMedia9. Change-Id: Id43519ca3cd31aafc0f88a1c2428b3ddc7cc1f93 Signed-off-by: Zhou Song --- asoc/msm-pcm-routing-v2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 79ddd89f33d9..125e29b6a3a4 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -24707,9 +24707,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, {"MultiMedia4 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, {"MultiMedia8 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, + {"MultiMedia9 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, {"MultiMedia1 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, {"MultiMedia4 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, {"MultiMedia8 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, + {"MultiMedia9 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, {"MultiMedia1 Mixer", "SLIM_4_TX", "SLIMBUS_4_TX"}, {"MultiMedia1 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, {"MultiMedia1 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, -- GitLab From afd3e12fbe08374dd0c60f27aea34a6102f4789a Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Thu, 31 Oct 2019 10:55:40 +0530 Subject: [PATCH 1294/1645] asoc: update open read call based on ASM version compress read is failing as the encoder config format support is to v5. Update the open read call to V5 based on ASM version. Change-Id: I5b74da5719172d31fb488bcd8081c6d0495d3905 --- asoc/msm-compress-q6-v2.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 4347bec26ed6..5d2e2de32f20 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -1503,6 +1503,7 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream) struct audio_client *ac = prtd->audio_client; uint32_t stream_index; uint32_t enc_cfg_id = ENC_CFG_ID_NONE; + bool compress_ts = false; switch (prtd->codec_param.codec.format) { case SNDRV_PCM_FORMAT_S24_LE: @@ -1552,22 +1553,19 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream) return ret; } } else { - if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG) { + if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG) + compress_ts = true; + + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= + ADSP_ASM_API_VERSION_V2) + ret = q6asm_open_read_v5(prtd->audio_client, + prtd->codec, bits_per_sample, + compress_ts, enc_cfg_id); + else ret = q6asm_open_read_v4(prtd->audio_client, - prtd->codec, - bits_per_sample, true, enc_cfg_id); - } else { - if (q6core_get_avcs_api_version_per_service( - APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= - ADSP_ASM_API_VERSION_V2) - ret = q6asm_open_read_v5(prtd->audio_client, - prtd->codec, bits_per_sample, - false, enc_cfg_id); - else - ret = q6asm_open_read_v4(prtd->audio_client, - prtd->codec, bits_per_sample, - false, enc_cfg_id); - } + prtd->codec, bits_per_sample, + compress_ts, enc_cfg_id); if (ret < 0) { pr_err("%s: q6asm_open_read failed:%d\n", __func__, ret); -- GitLab From fbd95edd79d781431483119840829bad675e1d73 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 5 Nov 2019 22:07:06 +0530 Subject: [PATCH 1295/1645] asoc: bolero: Add va/tx macro registers for bolero 2.1 Update VA/TX macro registers for bolero 2.1 Change-Id: I6be9632407c85a36bc746c65b34a52812548ad2a Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc-registers.h | 7 +- asoc/codecs/bolero/bolero-cdc-regmap.c | 4 + asoc/codecs/bolero/bolero-cdc-tables.c | 216 ++++++++++++++++++++++ asoc/codecs/bolero/bolero-cdc.c | 7 + asoc/codecs/bolero/internal.h | 3 + asoc/codecs/bolero/tx-macro.c | 7 + 6 files changed, 243 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/bolero-cdc-registers.h b/asoc/codecs/bolero/bolero-cdc-registers.h index c59bb866147e..e68e3148a566 100644 --- a/asoc/codecs/bolero/bolero-cdc-registers.h +++ b/asoc/codecs/bolero/bolero-cdc-registers.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ #ifndef _BOLERO_CDC_REGISTERS_H @@ -716,6 +716,11 @@ #define BOLERO_CDC_VA_MACRO_TOP_MAX 0x34 /* 0x0CC/4 = 0x33 + 1 = 0x34 */ +#define BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL0 (VA_START_OFFSET + 0x00D0) +#define BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL1 (VA_START_OFFSET + 0x00D4) +#define BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL2 (VA_START_OFFSET + 0x00D8) +#define BOLERO_CDC_VA_TOP_CSR_SWR_CTRL (VA_START_OFFSET + 0x00DC) + #define BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0 (VA_START_OFFSET + 0x0100) #define BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1 (VA_START_OFFSET + 0x0104) #define BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG0 (VA_START_OFFSET + 0x0108) diff --git a/asoc/codecs/bolero/bolero-cdc-regmap.c b/asoc/codecs/bolero/bolero-cdc-regmap.c index 90829665e01a..77f5420dc48f 100644 --- a/asoc/codecs/bolero/bolero-cdc-regmap.c +++ b/asoc/codecs/bolero/bolero-cdc-regmap.c @@ -625,6 +625,10 @@ static const struct reg_default bolero_defaults[] = { { BOLERO_CDC_VA_TOP_CSR_CORE_ID_1, 0x00}, { BOLERO_CDC_VA_TOP_CSR_CORE_ID_2, 0x00}, { BOLERO_CDC_VA_TOP_CSR_CORE_ID_3, 0x00}, + { BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL0, 0xEE}, + { BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL1, 0xEE}, + { BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL2, 0xEE}, + { BOLERO_CDC_VA_TOP_CSR_SWR_CTRL, 0x06}, /* VA core */ { BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0, 0x00}, diff --git a/asoc/codecs/bolero/bolero-cdc-tables.c b/asoc/codecs/bolero/bolero-cdc-tables.c index 81639b39b395..5d0d353566cb 100644 --- a/asoc/codecs/bolero/bolero-cdc-tables.c +++ b/asoc/codecs/bolero/bolero-cdc-tables.c @@ -149,6 +149,96 @@ u8 bolero_tx_reg_access[BOLERO_CDC_TX_MACRO_MAX] = { [BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_SEC6)] = RD_WR_REG, }; +u8 bolero_tx_reg_access_v2[BOLERO_CDC_TX_MACRO_MAX] = { + [BOLERO_REG(BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_TOP_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_ANC_CFG)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_CTRL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_DEBUG_BUS)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_DEBUG_EN)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_TX_I2S_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_I2S_CLK)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_I2S_RESET)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_DMIC1_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_DMIC2_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_DMIC3_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_AMIC0_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_AMIC1_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_CLK_RESET_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_MODE_1_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_MODE_2_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_FF_SHIFT)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_FB_SHIFT)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_LPF_FF_A_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_LPF_FF_B_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_LPF_FB_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_SMLPF_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_DCFLT_SHIFT_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_IIR_ADAPT_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_IIR_COEFF_1_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_IIR_COEFF_2_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_FF_A_GAIN_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_FF_B_GAIN_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_ANC0_FB_GAIN_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC7)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC6)] = RD_WR_REG, +}; + u8 bolero_rx_reg_access[BOLERO_CDC_RX_MACRO_MAX] = { [BOLERO_REG(BOLERO_CDC_RX_TOP_TOP_CFG0)] = RD_WR_REG, [BOLERO_REG(BOLERO_CDC_RX_TOP_SWR_CTRL)] = RD_WR_REG, @@ -581,6 +671,132 @@ u8 bolero_va_top_reg_access[BOLERO_CDC_VA_MACRO_TOP_MAX] = { [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_3)] = RD_REG, }; +u8 bolero_va_reg_access_v2[BOLERO_CDC_VA_MACRO_MAX] = { + [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TOP_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC_CFG)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DEBUG_BUS)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DEBUG_EN)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TX_I2S_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_I2S_CLK)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_I2S_RESET)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_0)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_1)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_2)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_3)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_SWR_CTRL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC7)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC6)] = RD_WR_REG, +}; + +u8 bolero_va_reg_access_v3[BOLERO_CDC_VA_MACRO_MAX] = { + [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TOP_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC_CFG)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DEBUG_BUS)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DEBUG_EN)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TX_I2S_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_I2S_CLK)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_I2S_RESET)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_0)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_1)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_2)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_3)] = RD_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_SWR_CTRL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC7)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC6)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_CFG0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_CFG1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_VOL_CTL)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC0)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC1)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC2)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC3)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC4)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC5)] = RD_WR_REG, + [BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC6)] = RD_WR_REG, +}; + u8 bolero_wsa_reg_access[BOLERO_CDC_WSA_MACRO_MAX] = { [BOLERO_REG(BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG, [BOLERO_REG(BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG, diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index dde471972335..48d305f27270 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -1101,6 +1101,13 @@ static int bolero_probe(struct platform_device *pdev) __func__); ret = 0; } + if (priv->version == BOLERO_VERSION_2_1) { + bolero_reg_access[TX_MACRO] = bolero_tx_reg_access_v2; + bolero_reg_access[VA_MACRO] = bolero_va_reg_access_v2; + } else if (priv->version == BOLERO_VERSION_2_0) { + bolero_reg_access[VA_MACRO] = bolero_va_reg_access_v3; + } + priv->dev = &pdev->dev; priv->dev_up = true; priv->initial_boot = true; diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index ba89832e86b5..d18568b0eb16 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -91,6 +91,9 @@ int bolero_get_macro_id(bool va_no_dec_flag, u16 reg); extern const struct regmap_config bolero_regmap_config; extern u8 *bolero_reg_access[MAX_MACRO]; extern u8 bolero_va_top_reg_access[BOLERO_CDC_VA_MACRO_TOP_MAX]; +extern u8 bolero_va_reg_access_v2[BOLERO_CDC_VA_MACRO_MAX]; +extern u8 bolero_va_reg_access_v3[BOLERO_CDC_VA_MACRO_MAX]; +extern u8 bolero_tx_reg_access_v2[BOLERO_CDC_TX_MACRO_MAX]; extern const u16 macro_id_base_offset[MAX_MACRO]; #endif diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index d27a5cf9f039..dabf4c149d8a 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -2834,6 +2834,13 @@ static int tx_macro_init(struct snd_soc_component *component) tx_macro_reg_init[i].mask, tx_macro_reg_init[i].val); + if (tx_priv->version == BOLERO_VERSION_2_1) + snd_soc_component_update_bits(component, + BOLERO_CDC_VA_TOP_CSR_SWR_CTRL, 0xF0, 0xA0); + else if (tx_priv->version == BOLERO_VERSION_2_0) + snd_soc_component_update_bits(component, + BOLERO_CDC_TX_TOP_CSR_SWR_CTRL, 0xF0, 0xA0); + return 0; } -- GitLab From d3478b29f0c4ed6d10a6215c4270d88a43b0c073 Mon Sep 17 00:00:00 2001 From: Viraja Kommaraju Date: Mon, 4 Nov 2019 20:38:23 +0530 Subject: [PATCH 1296/1645] ASoC: msm: Add support for MultiMedia23 Add MultiMedia23 fe_dais, routing controls, mixer controls support for early audio feature. Change-Id: I2bb0eb6f161e11c289dc55b9d3993a8089875aa6 Signed-off-by: Viraja Kommaraju --- asoc/msm-dai-fe.c | 33 ++++++ asoc/msm-pcm-routing-v2.c | 242 ++++++++++++++++++++++++++++++++++++++ asoc/msm-pcm-routing-v2.h | 1 + asoc/sa6155.c | 17 +++ 4 files changed, 293 insertions(+) diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index ba77a0731960..2025be91a119 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -2724,6 +2724,39 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "MultiMedia22", .probe = fe_dai_probe, }, + { + .playback = { + .stream_name = "MultiMedia23 Playback", + .aif_name = "MM_DL23", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 32, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "MultiMedia23 Capture", + .aif_name = "MM_UL23", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 32, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .name = "MultiMedia23", + .probe = fe_dai_probe, + }, { .playback = { .stream_name = "MultiMedia26 Playback", diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 0c03c1ec6172..93577727677b 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -767,6 +767,9 @@ static struct msm_pcm_routing_fdai_data {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA22 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, + /* MULTIMEDIA23 */ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA26 */ @@ -9585,6 +9588,10 @@ static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = { @@ -9660,6 +9667,10 @@ static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = { @@ -9735,6 +9746,10 @@ static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = { @@ -9810,6 +9825,10 @@ static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_tx_0_mixer_controls[] = { @@ -9877,6 +9896,10 @@ static const struct snd_kcontrol_new pri_tdm_tx_0_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = { @@ -9952,6 +9975,10 @@ static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = { @@ -10027,6 +10054,10 @@ static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = { @@ -10102,6 +10133,10 @@ static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = { @@ -10177,6 +10212,10 @@ static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_tx_0_mixer_controls[] = { @@ -10244,6 +10283,10 @@ static const struct snd_kcontrol_new sec_tdm_tx_0_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_0_mixer_controls[] = { @@ -10319,6 +10362,10 @@ static const struct snd_kcontrol_new tert_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_tx_0_mixer_controls[] = { @@ -10386,6 +10433,10 @@ static const struct snd_kcontrol_new tert_tdm_tx_0_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_1_mixer_controls[] = { @@ -10461,6 +10512,10 @@ static const struct snd_kcontrol_new tert_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = { @@ -10536,6 +10591,10 @@ static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = { @@ -10611,6 +10670,10 @@ static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = { @@ -10686,6 +10749,10 @@ static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = { @@ -10765,6 +10832,10 @@ static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_tx_0_mixer_controls[] = { @@ -10832,6 +10903,10 @@ static const struct snd_kcontrol_new quat_tdm_tx_0_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_1_mixer_controls[] = { @@ -10911,6 +10986,10 @@ static const struct snd_kcontrol_new quat_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = { @@ -10990,6 +11069,10 @@ static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = { @@ -11069,6 +11152,10 @@ static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_0_mixer_controls[] = { @@ -11148,6 +11235,10 @@ static const struct snd_kcontrol_new quin_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_tx_0_mixer_controls[] = { @@ -11215,6 +11306,10 @@ static const struct snd_kcontrol_new quin_tdm_tx_0_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_tx_1_mixer_controls[] = { @@ -11428,6 +11523,10 @@ static const struct snd_kcontrol_new quin_tdm_tx_2_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = { @@ -11507,6 +11606,10 @@ static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_tx_3_mixer_controls[] = { @@ -11653,6 +11756,10 @@ static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sen_tdm_rx_0_mixer_controls[] = { @@ -14999,6 +15106,89 @@ static const struct snd_kcontrol_new mmul22_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new mmul23_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new mmul27_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, @@ -22967,6 +23157,7 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_IN("MM_DL20", "MultiMedia20 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("MM_DL21", "MultiMedia21 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("MM_DL22", "MultiMedia22 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL23", "MultiMedia23 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("MM_DL26", "MultiMedia26 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0), @@ -22985,6 +23176,7 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("MM_UL20", "MultiMedia20 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL21", "MultiMedia21 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL22", "MultiMedia22 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL23", "MultiMedia23 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL27", "MultiMedia27 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL28", "MultiMedia28 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL29", "MultiMedia29 Capture", 0, 0, 0, 0), @@ -24086,6 +24278,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { mmul21_mixer_controls, ARRAY_SIZE(mmul21_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia22 Mixer", SND_SOC_NOPM, 0, 0, mmul22_mixer_controls, ARRAY_SIZE(mmul22_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia23 Mixer", SND_SOC_NOPM, 0, 0, + mmul23_mixer_controls, ARRAY_SIZE(mmul23_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia27 Mixer", SND_SOC_NOPM, 0, 0, mmul27_mixer_controls, ARRAY_SIZE(mmul27_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia28 Mixer", SND_SOC_NOPM, 0, 0, @@ -25316,6 +25510,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Audio Mixer"}, {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25336,6 +25531,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Audio Mixer"}, {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25356,6 +25552,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Audio Mixer"}, {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25376,6 +25573,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Audio Mixer"}, {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25394,6 +25592,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"PRI_TDM_TX_0", NULL, "PRI_TDM_TX_0 Audio Mixer"}, {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25414,6 +25613,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Audio Mixer"}, {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25434,6 +25634,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Audio Mixer"}, {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25454,6 +25655,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Audio Mixer"}, {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25474,6 +25676,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Audio Mixer"}, {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25492,6 +25695,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"SEC_TDM_TX_0", NULL, "SEC_TDM_TX_0 Audio Mixer"}, {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25512,6 +25716,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Audio Mixer"}, {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25530,6 +25735,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"TERT_TDM_TX_0", NULL, "TERT_TDM_TX_0 Audio Mixer"}, {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25550,6 +25756,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Audio Mixer"}, {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25570,6 +25777,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Audio Mixer"}, {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25590,6 +25798,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Audio Mixer"}, {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25610,6 +25819,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"TERT_TDM_RX_4", NULL, "TERT_TDM_RX_4 Audio Mixer"}, {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25631,6 +25841,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Audio Mixer"}, {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25649,6 +25860,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"QUAT_TDM_TX_0", NULL, "QUAT_TDM_TX_0 Audio Mixer"}, {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25670,6 +25882,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Audio Mixer"}, {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25691,6 +25904,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Audio Mixer"}, {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25712,6 +25926,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Audio Mixer"}, {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25733,6 +25948,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0 Audio Mixer"}, {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25751,6 +25967,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"QUIN_TDM_TX_0", NULL, "QUIN_TDM_TX_0 Audio Mixer"}, {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25772,6 +25989,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1 Audio Mixer"}, {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25793,6 +26011,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2 Audio Mixer"}, {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25814,6 +26033,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Audio Mixer"}, {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -26436,6 +26656,27 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia22 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia22 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia23 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia23 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia23 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia23 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia23 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia23 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia23 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia23 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia23 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia23 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia23 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia23 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia23 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia23 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia23 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia23 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia23 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia23 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia23 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia23 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia27 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia27 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia27 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, @@ -26680,6 +26921,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL20", NULL, "MultiMedia20 Mixer"}, {"MM_UL21", NULL, "MultiMedia21 Mixer"}, {"MM_UL22", NULL, "MultiMedia22 Mixer"}, + {"MM_UL23", NULL, "MultiMedia23 Mixer"}, {"MM_UL27", NULL, "MultiMedia27 Mixer"}, {"MM_UL28", NULL, "MultiMedia28 Mixer"}, {"MM_UL29", NULL, "MultiMedia29 Mixer"}, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 8003d913f4f6..9c74c32ffbd5 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -260,6 +260,7 @@ enum { MSM_FRONTEND_DAI_MULTIMEDIA20, MSM_FRONTEND_DAI_MULTIMEDIA21, MSM_FRONTEND_DAI_MULTIMEDIA22, + MSM_FRONTEND_DAI_MULTIMEDIA23, MSM_FRONTEND_DAI_MULTIMEDIA26, MSM_FRONTEND_DAI_MULTIMEDIA27, MSM_FRONTEND_DAI_MULTIMEDIA28, diff --git a/asoc/sa6155.c b/asoc/sa6155.c index 73b95b2cef8b..2c237400199b 100644 --- a/asoc/sa6155.c +++ b/asoc/sa6155.c @@ -5885,6 +5885,23 @@ static struct snd_soc_dai_link msm_auto_fe_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA22 }, + { + .name = MSM_DAILINK_NAME(Media23), + .stream_name = "MultiMedia23", + .cpu_dai_name = "MultiMedia23", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA23 + }, }; static struct snd_soc_dai_link msm_custom_fe_dai_links[] = { -- GitLab From 54fe9be4494dd8e67b7644c7bd8ee91f4c6ff3ee Mon Sep 17 00:00:00 2001 From: Faiz Nabi Kuchay Date: Fri, 15 Nov 2019 15:09:37 +0530 Subject: [PATCH 1297/1645] asoc: codecs: Add NULL check before calling bcs_enable callback function Add NULL check before calling bcs_enable callback function. Change-Id: Ic2d65534710d71c074c55d67da3e8a9793bab637 Signed-off-by: Faiz Nabi Kuchay --- asoc/codecs/wcd-mbhc-adc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index 9652d11dea33..0635d5468056 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -694,7 +694,8 @@ static void wcd_correct_swch_plug(struct work_struct *work) */ if (plug_type == MBHC_PLUG_TYPE_HEADSET || plug_type == MBHC_PLUG_TYPE_HEADPHONE) - mbhc->mbhc_cb->bcs_enable(mbhc, false); + if (mbhc->mbhc_cb->bcs_enable) + mbhc->mbhc_cb->bcs_enable(mbhc, false); timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS); while (!time_after(jiffies, timeout)) { @@ -842,7 +843,8 @@ static void wcd_correct_swch_plug(struct work_struct *work) } if ((plug_type == MBHC_PLUG_TYPE_HEADSET || plug_type == MBHC_PLUG_TYPE_HEADPHONE)) - mbhc->mbhc_cb->bcs_enable(mbhc, true); + if (mbhc->mbhc_cb->bcs_enable) + mbhc->mbhc_cb->bcs_enable(mbhc, true); if (!wrk_complete) { /* -- GitLab From cef55160ebdd81e75d29dbc1200c8027cf6841eb Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 9 Nov 2019 03:22:31 +0530 Subject: [PATCH 1298/1645] ASoC: rx-macro: Update rx droop based on sampling rate Update rx droop based on sampling rate to avoid change in gains between different sampling rates. Change-Id: Icb2b0bc51a61395c2ee96f63c29555614fe9e505 Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/rx-macro.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 924771a12597..07b7b30c1105 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1667,7 +1667,9 @@ static int rx_macro_config_compander(struct snd_soc_component *component, int interp_n, int event) { int comp = 0; - u16 comp_ctl0_reg = 0, rx_path_cfg0_reg = 0; + u16 comp_ctl0_reg = 0, rx_path_cfg0_reg = 0, rx_path_cfg3_reg = 0; + u16 rx0_path_ctl_reg = 0; + u8 pcm_rate = 0, val = 0; /* AUX does not have compander */ if (interp_n == INTERP_AUX) @@ -1684,6 +1686,20 @@ static int rx_macro_config_compander(struct snd_soc_component *component, (comp * RX_MACRO_COMP_OFFSET); rx_path_cfg0_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0 + (comp * RX_MACRO_RX_PATH_OFFSET); + rx_path_cfg3_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG3 + + (comp * RX_MACRO_RX_PATH_OFFSET); + rx0_path_ctl_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + + (comp * RX_MACRO_RX_PATH_OFFSET); + pcm_rate = (snd_soc_component_read32(component, rx0_path_ctl_reg) + & 0x0F); + if (pcm_rate < 0x06) + val = 0x03; + else if (pcm_rate < 0x08) + val = 0x01; + else if (pcm_rate < 0x0B) + val = 0x02; + else + val = 0x00; if (SND_SOC_DAPM_EVENT_ON(event)) { /* Enable Compander Clock */ @@ -1695,6 +1711,8 @@ static int rx_macro_config_compander(struct snd_soc_component *component, 0x02, 0x00); snd_soc_component_update_bits(component, rx_path_cfg0_reg, 0x02, 0x02); + snd_soc_component_update_bits(component, rx_path_cfg3_reg, + 0x03, val); } if (SND_SOC_DAPM_EVENT_OFF(event)) { @@ -1706,6 +1724,8 @@ static int rx_macro_config_compander(struct snd_soc_component *component, 0x01, 0x00); snd_soc_component_update_bits(component, comp_ctl0_reg, 0x04, 0x00); + snd_soc_component_update_bits(component, rx_path_cfg3_reg, + 0x03, 0x03); } return 0; -- GitLab From 921b8657cabcf40a73a7830cced8525370cc69d3 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 3 Oct 2019 02:13:32 +0530 Subject: [PATCH 1299/1645] soc: soundwire: Update soundwire register access sequence Update soundwire register access sequence based on the hardware version. Change-Id: I6dbdd884f87b62fce4e9f7074c6ccdcdac8456b8 Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 78 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 008801fae779..88ee4832c815 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -314,6 +314,11 @@ static void swrm_reg_dump(struct swr_mstr_ctrl *swrm, func, reg[i], val[i]); } +static bool is_swr_clk_needed(struct swr_mstr_ctrl *swrm) +{ + return ((swrm->version <= SWRM_VERSION_1_5_1) ? true : false); +} + static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm, int core_type, bool enable) { @@ -359,6 +364,30 @@ static int swrm_get_ssp_period(struct swr_mstr_ctrl *swrm, return ((swrm->bus_clk * 2) / ((row * col) * frame_sync)); } +static int swrm_core_vote_request(struct swr_mstr_ctrl *swrm) +{ + int ret = 0; + + if (!swrm->handle) + return -EINVAL; + + mutex_lock(&swrm->clklock); + if (!swrm->dev_up) { + ret = -ENODEV; + goto exit; + } + if (swrm->core_vote) { + ret = swrm->core_vote(swrm->handle, true); + if (ret) + dev_err_ratelimited(swrm->dev, + "%s: core vote request failed\n", __func__); + } +exit: + mutex_unlock(&swrm->clklock); + + return ret; +} + static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) { int ret = 0; @@ -372,13 +401,15 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) ret = -ENODEV; goto exit; } - if (swrm->core_vote) { - ret = swrm->core_vote(swrm->handle, true); - if (ret) { - dev_err_ratelimited(swrm->dev, - "%s: clock enable req failed", - __func__); - goto exit; + if (is_swr_clk_needed(swrm)) { + if (swrm->core_vote) { + ret = swrm->core_vote(swrm->handle, true); + if (ret) { + dev_err_ratelimited(swrm->dev, + "%s: core vote request failed\n", + __func__); + goto exit; + } } } swrm->clk_ref_count++; @@ -415,14 +446,21 @@ static int swrm_ahb_write(struct swr_mstr_ctrl *swrm, if (!swrm->dev_up) goto err; - ret = swrm_clk_request(swrm, TRUE); - if (ret) { - dev_err_ratelimited(swrm->dev, "%s: clock request failed\n", - __func__); + if (is_swr_clk_needed(swrm)) { + ret = swrm_clk_request(swrm, TRUE); + if (ret) { + dev_err_ratelimited(swrm->dev, + "%s: clock request failed\n", + __func__); + goto err; + } + } else if (swrm_core_vote_request(swrm)) { goto err; } + iowrite32(temp, swrm->swrm_dig_base + reg); - swrm_clk_request(swrm, FALSE); + if (is_swr_clk_needed(swrm)) + swrm_clk_request(swrm, FALSE); err: mutex_unlock(&swrm->devlock); return ret; @@ -438,15 +476,21 @@ static int swrm_ahb_read(struct swr_mstr_ctrl *swrm, if (!swrm->dev_up) goto err; - ret = swrm_clk_request(swrm, TRUE); - if (ret) { - dev_err_ratelimited(swrm->dev, "%s: clock request failed\n", - __func__); + if (is_swr_clk_needed(swrm)) { + ret = swrm_clk_request(swrm, TRUE); + if (ret) { + dev_err_ratelimited(swrm->dev, "%s: clock request failed\n", + __func__); + goto err; + } + } else if (swrm_core_vote_request(swrm)) { goto err; } + temp = ioread32(swrm->swrm_dig_base + reg); *value = temp; - swrm_clk_request(swrm, FALSE); + if (is_swr_clk_needed(swrm)) + swrm_clk_request(swrm, FALSE); err: mutex_unlock(&swrm->devlock); return ret; -- GitLab From 09819e980c3f7df188fb8ae7730386cf43428027 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 18 Nov 2019 14:38:11 +0530 Subject: [PATCH 1300/1645] soc: soundwire: Update comp status check for SWR version 1.6 Check comp status based on active and inactive request and return once status met. Change-Id: I75669558875d8ab6fc23a02c888e6083e15aee08 Signed-off-by: Laxminath Kasam --- soc/swr-mstr-ctrl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index c90e6b491b90..2ab70f3e02a1 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -500,12 +500,15 @@ static bool swrm_check_link_status(struct swr_mstr_ctrl *swrm, bool active) int retry = SWRM_LINK_STATUS_RETRY_CNT; int ret = false; int status = active ? 0x1 : 0x0; + int comp_sts = 0x0; if ((swrm->version <= SWRM_VERSION_1_5_1)) return true; do { - if (swr_master_read(swrm, SWRM_COMP_STATUS) & status) { + comp_sts = swr_master_read(swrm, SWRM_COMP_STATUS) & 0x01; + /* check comp status and status requested met */ + if ((comp_sts && status) || (!comp_sts && !status)) { ret = true; break; } -- GitLab From 8bcaeab611af3978a505e7097b0fd34ed4d87425 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 31 Oct 2019 11:45:36 +0530 Subject: [PATCH 1301/1645] soc: swr-mstr: Fix unbalanced enable for wakeup irq Enable IRQ for wakeup is called multiple times resulting in throttling. This is because irq is not disabled after enablement. Disable wakeup irq in runtime resume to fix the issue. Also add check so that irq is not disabled more than once. Change-Id: Ib5b7493298beb3ca4bcf78b2adbd7d4ac9ce6111 Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 45 +++++++++++++++++++++++++++++++++++++++++---- soc/swr-mstr-ctrl.h | 1 + 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index c90e6b491b90..8dcf1f652448 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1883,10 +1883,21 @@ static irqreturn_t swrm_wakeup_interrupt(int irq, void *dev) pr_err("%s: swrm or dev is null\n", __func__); return IRQ_NONE; } + mutex_lock(&swrm->devlock); if (!swrm->dev_up) { - if (swrm->wake_irq > 0) - disable_irq_nosync(swrm->wake_irq); + if (swrm->wake_irq > 0) { + if (unlikely(!irq_get_irq_data(swrm->wake_irq))) { + pr_err("%s: irq data is NULL\n", __func__); + mutex_unlock(&swrm->devlock); + return IRQ_NONE; + } + mutex_lock(&swrm->irq_lock); + if (!irqd_irq_disabled( + irq_get_irq_data(swrm->wake_irq))) + disable_irq_nosync(swrm->wake_irq); + mutex_unlock(&swrm->irq_lock); + } mutex_unlock(&swrm->devlock); return ret; } @@ -1895,8 +1906,17 @@ static irqreturn_t swrm_wakeup_interrupt(int irq, void *dev) dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__); goto exit; } - if (swrm->wake_irq > 0) - disable_irq_nosync(swrm->wake_irq); + if (swrm->wake_irq > 0) { + if (unlikely(!irq_get_irq_data(swrm->wake_irq))) { + pr_err("%s: irq data is NULL\n", __func__); + return IRQ_NONE; + } + mutex_lock(&swrm->irq_lock); + if (!irqd_irq_disabled( + irq_get_irq_data(swrm->wake_irq))) + disable_irq_nosync(swrm->wake_irq); + mutex_unlock(&swrm->irq_lock); + } pm_runtime_get_sync(swrm->dev); pm_runtime_mark_last_busy(swrm->dev); pm_runtime_put_autosuspend(swrm->dev); @@ -2376,6 +2396,7 @@ static int swrm_probe(struct platform_device *pdev) init_completion(&swrm->reset); init_completion(&swrm->broadcast); init_completion(&swrm->clk_off_complete); + mutex_init(&swrm->irq_lock); mutex_init(&swrm->mlock); mutex_init(&swrm->reslock); mutex_init(&swrm->force_down_lock); @@ -2522,6 +2543,7 @@ static int swrm_probe(struct platform_device *pdev) else if (swrm->irq) free_irq(swrm->irq, swrm); err_irq_fail: + mutex_destroy(&swrm->irq_lock); mutex_destroy(&swrm->mlock); mutex_destroy(&swrm->reslock); mutex_destroy(&swrm->force_down_lock); @@ -2554,6 +2576,7 @@ static int swrm_remove(struct platform_device *pdev) swr_unregister_master(&swrm->master); msm_aud_evt_unregister_client(&swrm->event_notifier); device_init_wakeup(swrm->dev, false); + mutex_destroy(&swrm->irq_lock); mutex_destroy(&swrm->mlock); mutex_destroy(&swrm->reslock); mutex_destroy(&swrm->iolock); @@ -2608,6 +2631,20 @@ static int swrm_runtime_resume(struct device *dev) if ((swrm->state == SWR_MSTR_DOWN) || (swrm->state == SWR_MSTR_SSR && swrm->dev_up)) { if (swrm->clk_stop_mode0_supp) { + if (swrm->wake_irq > 0) { + if (unlikely(!irq_get_irq_data + (swrm->wake_irq))) { + pr_err("%s: irq data is NULL\n", + __func__); + mutex_unlock(&swrm->reslock); + return IRQ_NONE; + } + mutex_lock(&swrm->irq_lock); + if (!irqd_irq_disabled( + irq_get_irq_data(swrm->wake_irq))) + disable_irq_nosync(swrm->wake_irq); + mutex_unlock(&swrm->irq_lock); + } if (swrm->ipc_wakeup) msm_aud_evt_blocking_notifier_call_chain( SWR_WAKE_IRQ_DEREGISTER, (void *)swrm); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index b07a80db6102..654dd0e7036c 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -124,6 +124,7 @@ struct swr_mstr_ctrl { struct mutex mlock; struct mutex reslock; struct mutex pm_lock; + struct mutex irq_lock; u32 swrm_base_reg; char __iomem *swrm_dig_base; char __iomem *swrm_hctl_reg; -- GitLab From 55fa597e30f0c661d779925b4aabd243209778cc Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 28 Sep 2019 02:50:27 +0530 Subject: [PATCH 1302/1645] soc: soundwire: Avoid bus clash during clock stop Mask bus clash interrupt before clock stop mode to avoid misfire of the interrupt. Clear and enable the interrupt after clock is enabled. Change-Id: I494073a668d298eef466c0f10ab202c3c69f9968 Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 8dcf1f652448..39d323d18a2d 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2691,6 +2691,14 @@ static int swrm_runtime_resume(struct device *dev) } else { /*wake up from clock stop*/ swr_master_write(swrm, SWRM_MCP_BUS_CTRL_ADDR, 0x2); + /* clear and enable bus clash interrupt */ + swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, 0x08); + swrm->intr_mask |= 0x08; + swr_master_write(swrm, SWRM_INTERRUPT_MASK_ADDR, + swrm->intr_mask); + swr_master_write(swrm, + SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN, + swrm->intr_mask); usleep_range(100, 105); if (!swrm_check_link_status(swrm, 0x1)) goto exit; @@ -2772,6 +2780,13 @@ static int swrm_runtime_suspend(struct device *dev) } } } else { + /* Mask bus clash interrupt */ + swrm->intr_mask &= ~((u32)0x08); + swr_master_write(swrm, SWRM_INTERRUPT_MASK_ADDR, + swrm->intr_mask); + swr_master_write(swrm, + SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN, + swrm->intr_mask); mutex_unlock(&swrm->reslock); /* clock stop sequence */ swrm_cmd_fifo_wr_cmd(swrm, 0x2, 0xF, 0xF, -- GitLab From 42adadc24fb2a370d0ceee2208630a3c51d231e5 Mon Sep 17 00:00:00 2001 From: Harshal Ahire Date: Fri, 15 Nov 2019 15:52:50 +0530 Subject: [PATCH 1303/1645] asoc: codecs: avoid crash after diconnecting DP cable Fix the null pointer access of DP callback functions. Change-Id: If4cc48a2471c2cbd1c46ea49cffaa01315673bde Signed-off-by: Harshal Ahire --- asoc/codecs/msm_hdmi_codec_rx.c | 37 ++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/asoc/codecs/msm_hdmi_codec_rx.c b/asoc/codecs/msm_hdmi_codec_rx.c index 5144b923b03e..1588c567675a 100644 --- a/asoc/codecs/msm_hdmi_codec_rx.c +++ b/asoc/codecs/msm_hdmi_codec_rx.c @@ -29,8 +29,6 @@ codec_info.type = EXT_DISPLAY_TYPE_DP; \ codec_info.ctrl_id = codec_data->ctl[dai_id]; \ codec_info.stream_id = codec_data->stream[dai_id]; \ - msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, \ - &codec_info) enum { DP_CONTROLLER0 = 0, @@ -94,7 +92,9 @@ static int msm_ext_disp_edid_ctl_info(struct snd_kcontrol *kcontrol, mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai_id); - if (!codec_data->ext_disp_ops.get_audio_edid_blk) { + rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, + &codec_info); + if (!codec_data->ext_disp_ops.get_audio_edid_blk || rc) { dev_dbg(component->dev, "%s: get_audio_edid_blk() is NULL\n", __func__); uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; @@ -139,7 +139,9 @@ static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol, mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai_id); - if (!codec_data->ext_disp_ops.get_audio_edid_blk) { + rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, + &codec_info); + if (!codec_data->ext_disp_ops.get_audio_edid_blk || rc) { dev_err(component->dev, "%s: codec_data or get_audio_edid_blk() is NULL\n", __func__); mutex_unlock(&codec_data->dp_ops_lock); @@ -199,9 +201,11 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai_id); + rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, + &codec_info); if (!codec_data->ext_disp_ops.get_audio_edid_blk || - !codec_data->ext_disp_ops.get_intf_id) { + !codec_data->ext_disp_ops.get_intf_id || rc) { dev_err(component->dev, "%s: get_audio_edid_blk() or get_intf_id is NULL\n", __func__); rc = -EINVAL; @@ -284,8 +288,10 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai_id); + rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, + &codec_info); - if (!codec_data->ext_disp_ops.acknowledge) { + if (!codec_data->ext_disp_ops.acknowledge || rc) { dev_err(component->dev, "%s: codec_data ops acknowledge() is NULL\n", __func__); @@ -460,7 +466,7 @@ static int msm_ext_disp_audio_codec_rx_dai_startup( struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - int ret = 0; + int ret = 0, rc = 0; struct msm_ext_disp_codec_id codec_info; struct msm_ext_disp_audio_codec_rx_data *codec_data = dev_get_drvdata(dai->component->dev); @@ -477,8 +483,10 @@ static int msm_ext_disp_audio_codec_rx_dai_startup( mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai->id); + rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, + &codec_info); - if (!codec_data->ext_disp_ops.cable_status) { + if (!codec_data->ext_disp_ops.cable_status || rc) { dev_err(dai->dev, "%s() cable_status is null\n", __func__); mutex_unlock(&codec_data->dp_ops_lock); @@ -532,8 +540,10 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params( mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai->id); + rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, + &codec_info); - if (!codec_data->ext_disp_ops.audio_info_setup) { + if (!codec_data->ext_disp_ops.audio_info_setup || rc) { dev_err(dai->dev, "%s: audio_info_setup is null\n", __func__); mutex_unlock(&codec_data->dp_ops_lock); @@ -600,8 +610,13 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params( mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai->id); + rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, + &codec_info); + if (rc) + goto end; rc = codec_data->ext_disp_ops.audio_info_setup( codec_data->ext_disp_core_pdev, &audio_setup_params); +end: mutex_unlock(&codec_data->dp_ops_lock); if (rc < 0) { dev_err_ratelimited(dai->dev, @@ -634,9 +649,11 @@ static void msm_ext_disp_audio_codec_rx_dai_shutdown( mutex_lock(&codec_data->dp_ops_lock); SWITCH_DP_CODEC(codec_info, codec_data, dai->id); + rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, + &codec_info); if (!codec_data->ext_disp_ops.teardown_done || - !codec_data->ext_disp_ops.cable_status) { + !codec_data->ext_disp_ops.cable_status || rc) { dev_err(dai->dev, "%s: teardown_done or cable_status is null\n", __func__); mutex_unlock(&codec_data->dp_ops_lock); -- GitLab From edbc522254b7c542a2af9228efe20080f86119ae Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 22 Oct 2019 07:00:22 +0530 Subject: [PATCH 1304/1645] ASoC: wsa883x: Add support for interrupt handling and variant Add support to handle wsa883x codec interrupts and runtime detection of wsa883x variant. Change-Id: I06fc113a390c04e890062761cff8ae7436acb662 Signed-off-by: Sudheer Papothi --- asoc/codecs/wsa883x/internal.h | 4 +- asoc/codecs/wsa883x/wsa883x.c | 206 +++++++++++++++++++++++++++++++-- 2 files changed, 199 insertions(+), 11 deletions(-) diff --git a/asoc/codecs/wsa883x/internal.h b/asoc/codecs/wsa883x/internal.h index 3f24712ff447..509fc8370866 100644 --- a/asoc/codecs/wsa883x/internal.h +++ b/asoc/codecs/wsa883x/internal.h @@ -78,7 +78,6 @@ struct wsa883x_priv { bool visense_enable; bool ext_vdd_spk; struct swr_port port[WSA883X_MAX_SWR_PORTS]; - int pd_gpio; int global_pa_cnt; int dev_mode; struct mutex res_lock; @@ -87,6 +86,9 @@ struct wsa883x_priv { struct device_node *wsa_rst_np; int pa_mute; int curr_temp; + int variant; + struct irq_domain *virq; + struct wcd_irq_info irq_info; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_dent; struct dentry *debugfs_peek; diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index cbf955960ce4..7869a2b01ff6 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -53,6 +53,51 @@ struct wsa_temp_register { static int wsa883x_get_temperature(struct snd_soc_component *component, int *temp); +enum { + WSA8830 = 0, + WSA8835, +}; + +enum { + WSA883X_IRQ_INT_SAF2WAR = 0, + WSA883X_IRQ_INT_WAR2SAF, + WSA883X_IRQ_INT_DISABLE, + WSA883X_IRQ_INT_OCP, + WSA883X_IRQ_INT_CLIP, + WSA883X_IRQ_INT_PDM_WD, + WSA883X_IRQ_INT_CLK_WD, + WSA883X_IRQ_INT_INTR_PIN, + WSA883X_IRQ_INT_UVLO, + WSA883X_IRQ_INT_PA_ON_ERR, +}; + +static const struct regmap_irq wsa883x_irqs[WSA883X_NUM_IRQS] = { + REGMAP_IRQ_REG(WSA883X_IRQ_INT_SAF2WAR, 0, 0x01), + REGMAP_IRQ_REG(WSA883X_IRQ_INT_WAR2SAF, 0, 0x02), + REGMAP_IRQ_REG(WSA883X_IRQ_INT_DISABLE, 0, 0x04), + REGMAP_IRQ_REG(WSA883X_IRQ_INT_OCP, 0, 0x08), + REGMAP_IRQ_REG(WSA883X_IRQ_INT_CLIP, 0, 0x10), + REGMAP_IRQ_REG(WSA883X_IRQ_INT_PDM_WD, 0, 0x20), + REGMAP_IRQ_REG(WSA883X_IRQ_INT_CLK_WD, 0, 0x40), + REGMAP_IRQ_REG(WSA883X_IRQ_INT_INTR_PIN, 0, 0x80), + REGMAP_IRQ_REG(WSA883X_IRQ_INT_UVLO, 1, 0x01), + REGMAP_IRQ_REG(WSA883X_IRQ_INT_PA_ON_ERR, 1, 0x02), +}; + +static struct regmap_irq_chip wsa883x_regmap_irq_chip = { + .name = "wsa883x", + .irqs = wsa883x_irqs, + .num_irqs = ARRAY_SIZE(wsa883x_irqs), + .num_regs = 2, + .status_base = WSA883X_INTR_STATUS0, + .mask_base = WSA883X_INTR_MASK0, + .type_base = WSA883X_INTR_LEVEL0, + .ack_base = WSA883X_INTR_CLEAR0, + .use_ack = 1, + .runtime_pm = false, + .irq_drv_data = NULL, +}; + #ifdef CONFIG_DEBUG_FS static int codec_debug_open(struct inode *inode, struct file *file) { @@ -289,6 +334,76 @@ static const struct file_operations codec_debug_dump_ops = { }; #endif +static irqreturn_t wsa883x_saf2war_handle_irq(int irq, void *data) +{ + pr_err_ratelimited("%s: interrupt for irq =%d triggered\n", + __func__, irq); + return IRQ_HANDLED; +} + +static irqreturn_t wsa883x_war2saf_handle_irq(int irq, void *data) +{ + pr_err_ratelimited("%s: interrupt for irq =%d triggered\n", + __func__, irq); + return IRQ_HANDLED; +} + +static irqreturn_t wsa883x_otp_handle_irq(int irq, void *data) +{ + pr_err_ratelimited("%s: interrupt for irq =%d triggered\n", + __func__, irq); + return IRQ_HANDLED; +} + +static irqreturn_t wsa883x_ocp_handle_irq(int irq, void *data) +{ + pr_err_ratelimited("%s: interrupt for irq =%d triggered\n", + __func__, irq); + return IRQ_HANDLED; +} + +static irqreturn_t wsa883x_clip_handle_irq(int irq, void *data) +{ + pr_err_ratelimited("%s: interrupt for irq =%d triggered\n", + __func__, irq); + return IRQ_HANDLED; +} + +static irqreturn_t wsa883x_pdm_wd_handle_irq(int irq, void *data) +{ + pr_err_ratelimited("%s: interrupt for irq =%d triggered\n", + __func__, irq); + return IRQ_HANDLED; +} + +static irqreturn_t wsa883x_clk_wd_handle_irq(int irq, void *data) +{ + pr_err_ratelimited("%s: interrupt for irq =%d triggered\n", + __func__, irq); + return IRQ_HANDLED; +} + +static irqreturn_t wsa883x_ext_int_handle_irq(int irq, void *data) +{ + pr_err_ratelimited("%s: interrupt for irq =%d triggered\n", + __func__, irq); + return IRQ_HANDLED; +} + +static irqreturn_t wsa883x_uvlo_handle_irq(int irq, void *data) +{ + pr_err_ratelimited("%s: interrupt for irq =%d triggered\n", + __func__, irq); + return IRQ_HANDLED; +} + +static irqreturn_t wsa883x_pa_on_err_handle_irq(int irq, void *data) +{ + pr_err_ratelimited("%s: interrupt for irq =%d triggered\n", + __func__, irq); + return IRQ_HANDLED; +} + static const char * const wsa_dev_mode_text[] = { "speaker", "receiver", "ultrasound" }; @@ -986,39 +1101,87 @@ static int wsa883x_swr_probe(struct swr_device *pdev) goto dev_err; } + /* Set all interrupts as edge triggered */ + for (i = 0; i < wsa883x_regmap_irq_chip.num_regs; i++) + regmap_write(wsa883x->regmap, (WSA883X_INTR_LEVEL0 + i), 0); + + wsa883x_regmap_irq_chip.irq_drv_data = wsa883x; + wsa883x->irq_info.wcd_regmap_irq_chip = &wsa883x_regmap_irq_chip; + wsa883x->irq_info.codec_name = "WSA883X"; + wsa883x->irq_info.regmap = wsa883x->regmap; + wsa883x->irq_info.dev = dev; + ret = wcd_irq_init(&wsa883x->irq_info, &wsa883x->virq); + + if (ret) { + dev_err(wsa883x->dev, "%s: IRQ init failed: %d\n", + __func__, ret); + goto dev_err; + } + + wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_SAF2WAR, + "WSA SAF2WAR", wsa883x_saf2war_handle_irq, NULL); + + wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_WAR2SAF, + "WSA WAR2SAF", wsa883x_war2saf_handle_irq, NULL); + + wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_DISABLE, + "WSA OTP", wsa883x_otp_handle_irq, NULL); + + wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_OCP, + "WSA OCP", wsa883x_ocp_handle_irq, NULL); + + wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_CLIP, + "WSA CLIP", wsa883x_clip_handle_irq, NULL); + + wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD, + "WSA PDM WD", wsa883x_pdm_wd_handle_irq, NULL); + + wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_CLK_WD, + "WSA CLK WD", wsa883x_clk_wd_handle_irq, NULL); + + wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_INTR_PIN, + "WSA EXT INT", wsa883x_ext_int_handle_irq, NULL); + + /* Under Voltage Lock out (UVLO) interrupt handle */ + wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_UVLO, + "WSA UVLO", wsa883x_uvlo_handle_irq, NULL); + + wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR, + "WSA PA ERR", wsa883x_pa_on_err_handle_irq, NULL); + ret = snd_soc_register_component(&pdev->dev, &soc_codec_dev_wsa883x, NULL, 0); if (ret) { dev_err(&pdev->dev, "%s: Codec registration failed\n", __func__); - goto dev_err; + goto err_irq; } mutex_init(&wsa883x->res_lock); #ifdef CONFIG_DEBUG_FS - if (!wcd938x->debugfs_dent) { - wcd938x->debugfs_dent = debugfs_create_dir( + if (!wsa883x->debugfs_dent) { + wsa883x->debugfs_dent = debugfs_create_dir( dev_name(&pdev->dev), 0); - if (!IS_ERR(wcd938x->debugfs_dent)) { - wcd938x->debugfs_peek = + if (!IS_ERR(wsa883x->debugfs_dent)) { + wsa883x->debugfs_peek = debugfs_create_file("swrslave_peek", S_IFREG | 0444, - wcd938x->debugfs_dent, + wsa883x->debugfs_dent, (void *) pdev, &codec_debug_read_ops); - wcd938x->debugfs_poke = + wsa883x->debugfs_poke = debugfs_create_file("swrslave_poke", S_IFREG | 0444, - wcd938x->debugfs_dent, + wsa883x->debugfs_dent, (void *) pdev, &codec_debug_write_ops); - wcd938x->debugfs_reg_dump = + wsa883x->debugfs_reg_dump = debugfs_create_file( "swrslave_reg_dump", S_IFREG | 0444, - wcd938x->debugfs_dent, + wsa883x->debugfs_dent, (void *) pdev, &codec_debug_dump_ops); } @@ -1027,6 +1190,18 @@ static int wsa883x_swr_probe(struct swr_device *pdev) return 0; +err_irq: + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_SAF2WAR, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_WAR2SAF, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_DISABLE, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_OCP, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_CLIP, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_CLK_WD, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_INTR_PIN, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_UVLO, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR, NULL); + wcd_irq_exit(&wsa883x->irq_info, wsa883x->virq); dev_err: if (pin_state_current == false) wsa883x_gpio_ctrl(wsa883x, false); @@ -1044,6 +1219,17 @@ static int wsa883x_swr_remove(struct swr_device *pdev) dev_err(&pdev->dev, "%s: wsa883x is NULL\n", __func__); return -EINVAL; } + + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_SAF2WAR, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_WAR2SAF, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_DISABLE, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_OCP, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_CLIP, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_CLK_WD, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_INTR_PIN, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_UVLO, NULL); + wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR, NULL); #ifdef CONFIG_DEBUG_FS debugfs_remove_recursive(wsa883x->debugfs_dent); wsa883x->debugfs_dent = NULL; -- GitLab From a6f808f1c8a602934c956308c3e41265d626edae Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 5 Nov 2019 05:22:45 +0530 Subject: [PATCH 1305/1645] ASoC: wsa883x: Add support for subsystem restart When subsystem restart triggers, reset the wsa883x codec. Change-Id: I2378281efbd601241b8ea36379db54727896a6e2 Signed-off-by: Sudheer Papothi --- asoc/codecs/wsa883x/internal.h | 20 +++++++++++ asoc/codecs/wsa883x/wsa883x.c | 62 ++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/asoc/codecs/wsa883x/internal.h b/asoc/codecs/wsa883x/internal.h index 509fc8370866..2384043fb21b 100644 --- a/asoc/codecs/wsa883x/internal.h +++ b/asoc/codecs/wsa883x/internal.h @@ -55,6 +55,20 @@ enum { SWR_VISENSE_PORT, }; +enum { + BOLERO_WSA_EVT_TX_CH_HOLD_CLEAR = 1, + BOLERO_WSA_EVT_PA_OFF_PRE_SSR, + BOLERO_WSA_EVT_SSR_DOWN, + BOLERO_WSA_EVT_SSR_UP, +}; + +struct wsa_ctrl_platform_data { + void *handle, + int (*update_wsa_event)(void *handle, u16 event, u32 data); + int (*register_notifier)(void *handle, struct notifer_block *nblock, + bool enable); +}; + struct swr_port { u8 port_id; u8 ch_mask; @@ -96,6 +110,12 @@ struct wsa883x_priv { struct dentry *debugfs_reg_dump; unsigned int read_data; #endif + struct device_node *parent_np; + struct platform_device *parent_dev; + struct notifier_block parent_nblock; + void *handle; + int (*register_notifier)(void *handle, + struct notifier_block *nblock, bool enable); }; static int32_t wsa883x_resource_acquire(struct snd_soc_component *component, diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 7869a2b01ff6..08f6858f73ab 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -1055,12 +1055,39 @@ static int wsa883x_gpio_ctrl(struct wsa883x_priv *wsa883x, bool enable) return ret; } +static int wsa883x_event_notify(struct notifier_block *nb, + unsigned long val, void *ptr) +{ + u16 event = (val & 0xffff); + struct wsa883x_priv *wsa883x = container_of(nb, struct wsa883x_priv, + parent_nblock); + + if (!wsa883x) + return -EINVAL; + + switch (event) { + case BOLERO_WSA_EVT_PA_OFF_PRE_SSR: + snd_soc_component_update_bits(wsa883x->component, + WSA883X_SPKR_DRV_GAIN, + 0xF0, 0xC0); + snd_soc_component_update_bits(wsa883x->component, + WSA883X_SPKR_DRV_EN, + 0x80, 0x00); + break; + default: + break; + } + + return 0; +} + static int wsa883x_swr_probe(struct swr_device *pdev) { int ret = 0; struct wsa883x_priv *wsa883x; u8 devnum = 0; bool pin_state_current = false; + struct wsa_ctrl_platform_data *plat_data = NULL; wsa883x = devm_kzalloc(&pdev->dev, sizeof(struct wsa883x_priv), GFP_KERNEL); @@ -1156,6 +1183,37 @@ static int wsa883x_swr_probe(struct swr_device *pdev) __func__); goto err_irq; } + + wsa883x->parent_np = of_parse_phandle(pdev->dev.of_node, + "qcom,bolero-handle", 0); + if (wsa883x->parent_np) { + wsa883x->parent_dev = + of_find_device_by_node(wsa883x->parent_np); + if (wsa883x->parent_dev) { + plat_data = dev_get_platdata(&wsa883x->parent_dev->dev); + if (plat_data) { + wsa883x->parent_nblock.notifier_call = + wsa883x_event_notify; + if (plat_data->register_notifier) + plat_data->register_notifier( + plat_data->handle, + &wsa883x->parent_nblock, + true); + wsa883x->register_notifier = + plat_data->register_notifier; + wsa883x->handle = plat_data->handle; + } else { + dev_err(&pdev->dev, "%s: plat data not found\n", + __func__); + } + } else { + dev_err(&pdev->dev, "%s: parent dev not found\n", + __func__); + } + } else { + dev_info(&pdev->dev, "%s: parent node not found\n", __func__); + } + mutex_init(&wsa883x->res_lock); #ifdef CONFIG_DEBUG_FS @@ -1230,6 +1288,10 @@ static int wsa883x_swr_remove(struct swr_device *pdev) wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_INTR_PIN, NULL); wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_UVLO, NULL); wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR, NULL); + + if (wsa883x->register_notifier) + wsa883x->register_notifier(wsa883x->handle, + &wsa883x->parent_nblock, false); #ifdef CONFIG_DEBUG_FS debugfs_remove_recursive(wsa883x->debugfs_dent); wsa883x->debugfs_dent = NULL; -- GitLab From 00732f4306b4a48dc76b86f212317749288d4f24 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 19 Nov 2019 17:26:16 -0800 Subject: [PATCH 1306/1645] asoc: msm-pcm-routing: Add missing mi2s connections to mmul5 Quat Quin and Sen connections are added to multimedia5 mixer widget. Change-Id: I5a32c7a8950ae1d6fb9d2f3189f54e3d95b633e1 Signed-off-by: Karthikeyan Mani --- asoc/msm-pcm-routing-v2.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 9cddca06503f..1efc1dbaf270 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -13135,6 +13135,14 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = { MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, @@ -25997,12 +26005,15 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia28 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia29 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia30 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia6 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"MultiMedia6 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia6 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"MultiMedia6 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia5 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"MultiMedia6 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, + {"MultiMedia5 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, {"MultiMedia1 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia1 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, -- GitLab From 44cedb8f7dfa0413a02bc6d9992a45424945f915 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 20 Nov 2019 17:37:23 +0530 Subject: [PATCH 1307/1645] soc: soundwire: Set slave host_irq interrupt mask for all slaves On receive of change enum slave status interrupt, update slave host_irq bit for all attached slave dev_nums. Change-Id: Idaad7a73a7ba9ab271f3fb6974f8d09df3f957b8 Signed-off-by: Laxminath Kasam --- soc/swr-mstr-ctrl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index c90e6b491b90..55334b620235 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1737,6 +1737,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) break; case SWRM_INTERRUPT_STATUS_CHANGE_ENUM_SLAVE_STATUS: status = swr_master_read(swrm, SWRM_MCP_SLV_STATUS); + swrm_enable_slave_irq(swrm); if (status == swrm->slave_status) { dev_dbg(swrm->dev, "%s: No change in slave status: %d\n", -- GitLab From 9a37b81cd426af5ccee0b031e4ac506edf51ed09 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 20 Nov 2019 17:45:10 +0530 Subject: [PATCH 1308/1645] asoc: wcd938x: Fix swr get logical addr fail during SSR During SSR, sometimes swr get logical addr fails. Add sufficient delay after reset and retry logic for get logical addr. Change-Id: I2a932e99896e0055f3b35f9b251008612f43b79f Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd938x/wcd938x.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index ae88d7ce5386..3db8fc5a9733 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -41,6 +41,8 @@ #define ADC_MODE_VAL_ULP1 0x09 #define ADC_MODE_VAL_ULP2 0x0B +#define NUM_ATTEMPTS 5 + enum { CODEC_TX = 0, CODEC_RX, @@ -1842,15 +1844,18 @@ static int wcd938x_get_logical_addr(struct swr_device *swr_dev) { int ret = 0; uint8_t devnum = 0; + int num_retry = NUM_ATTEMPTS; - ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum); - if (ret) { - dev_err(&swr_dev->dev, - "%s get devnum %d for dev addr %lx failed\n", - __func__, devnum, swr_dev->addr); - swr_remove_device(swr_dev); - return ret; - } + do { + ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum); + if (ret) { + dev_err(&swr_dev->dev, + "%s get devnum %d for dev addr %lx failed\n", + __func__, devnum, swr_dev->addr); + /* retry after 1ms */ + usleep_range(1000, 1010); + } + } while (ret && --num_retry); swr_dev->dev_num = devnum; return 0; } @@ -1904,8 +1909,12 @@ static int wcd938x_event_notify(struct notifier_block *block, break; case BOLERO_WCD_EVT_SSR_UP: wcd938x_reset(wcd938x->dev); + /* allow reset to take effect */ + usleep_range(10000, 10010); + wcd938x_get_logical_addr(wcd938x->tx_swr_dev); wcd938x_get_logical_addr(wcd938x->rx_swr_dev); + wcd938x_init_reg(component); regcache_mark_dirty(wcd938x->regmap); regcache_sync(wcd938x->regmap); -- GitLab From 8a8b12b2456b97e8bbdd6dc060964f8fc0c4da7a Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 15 Nov 2019 23:06:41 +0530 Subject: [PATCH 1309/1645] soc: soundwire: Update ssp period for fractional sample rates Frame sync for fractional sample rates is different. Update ssp period based on frame sync of fractional sample rate for synchronization of the data channels. Change-Id: I25eaa5195abcdfad54cfed09beb0abe5aff2499a Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 46 +++++++++++++++++++++++++++++++++++++++++++-- soc/swr-mstr-ctrl.h | 2 +- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 2682c454dfee..0f8e68793816 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -26,6 +26,7 @@ #include "swr-mstr-ctrl.h" #define SWRM_FRAME_SYNC_SEL 4000 /* 4KHz */ +#define SWRM_FRAME_SYNC_SEL_NATIVE 3675 /* 3.675KHz */ #define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700 #define SWRM_SYS_SUSPEND_WAIT 1 @@ -882,6 +883,39 @@ static void enable_bank_switch(struct swr_mstr_ctrl *swrm, u8 bank, SWRS_SCP_FRAME_CTRL_BANK(bank)); } +static void swrm_switch_frame_shape(struct swr_mstr_ctrl *swrm, int mclk_freq) +{ + u8 bank; + u32 n_row, n_col; + u32 value = 0; + u32 row = 0, col = 0; + u8 ssp_period = 0; + int frame_sync = SWRM_FRAME_SYNC_SEL; + + if (mclk_freq == MCLK_FREQ_NATIVE) { + n_col = SWR_MAX_COL; + col = SWRM_COL_16; + n_row = SWR_ROW_64; + row = SWRM_ROW_64; + frame_sync = SWRM_FRAME_SYNC_SEL_NATIVE; + } else { + n_col = SWR_MIN_COL; + col = SWRM_COL_02; + n_row = SWR_ROW_50; + row = SWRM_ROW_50; + frame_sync = SWRM_FRAME_SYNC_SEL; + } + + bank = get_inactive_bank_num(swrm); + ssp_period = swrm_get_ssp_period(swrm, row, col, frame_sync); + dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period); + value = ((n_row << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | + (n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) | + ((ssp_period - 1) << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT)); + swr_master_write(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value); + enable_bank_switch(swrm, bank, n_row, n_col); +} + static struct swr_port_info *swrm_get_port_req(struct swrm_mports *mport, u8 slv_port, u8 dev_num) { @@ -1196,6 +1230,7 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK | SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_BMSK); u8 inactive_bank; + int frame_sync = SWRM_FRAME_SYNC_SEL; if (!swrm) { pr_err("%s: swrm is null\n", __func__); @@ -1278,13 +1313,15 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) n_col ? 16 : 2); n_row = SWR_ROW_64; row = SWRM_ROW_64; + frame_sync = SWRM_FRAME_SYNC_SEL_NATIVE; } else { dev_dbg(swrm->dev, "setting 50 x %d frameshape\n", n_col ? 16 : 2); n_row = SWR_ROW_50; row = SWRM_ROW_50; + frame_sync = SWRM_FRAME_SYNC_SEL; } - ssp_period = swrm_get_ssp_period(swrm, row, col, SWRM_FRAME_SYNC_SEL); + ssp_period = swrm_get_ssp_period(swrm, row, col, frame_sync); dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period); value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank)); @@ -2991,8 +3028,13 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) if (swrm->state == SWR_MSTR_DOWN) dev_dbg(swrm->dev, "%s:SWR master is already Down:%d\n", __func__, swrm->state); - else + else { + swrm->mclk_freq = *(int *)data; + swrm->bus_clk = swrm->mclk_freq; + swrm_switch_frame_shape(swrm, + swrm->bus_clk); swrm_device_suspend(&pdev->dev); + } /* * add delay to ensure clk release happen * if interrupt triggered for clk stop, diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index b07a80db6102..ab277721097b 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -25,7 +25,7 @@ #define SWR_ROW_48 0 #define SWR_ROW_50 1 -#define SWR_ROW_64 2 +#define SWR_ROW_64 3 #define SWR_MAX_COL 7 /* Cols = 16 */ #define SWR_MIN_COL 0 /* Cols = 2 */ -- GitLab From cafe073cf10a0bd64133279de39b71160d9549bf Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 20 Nov 2019 17:31:58 +0530 Subject: [PATCH 1310/1645] soc: soundwire: Update check link status for master init After master init sets COMP_CFG, wait for soundwire link status to be connected for SWR version 1.6. Update wait for soundwire link disconnect for all masters. Change-Id: I0c0b34f225f88f1b3838b0aa653b57b2c7c0cc40 Signed-off-by: Laxminath Kasam --- soc/swr-mstr-ctrl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index c90e6b491b90..6332e325fd7d 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2131,6 +2131,12 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) swr_master_bulk_write(swrm, reg, value, len); + if (!swrm_check_link_status(swrm, 0x1)) { + dev_err(swrm->dev, + "%s: swr link failed to connect\n", + __func__); + return -EINVAL; + } /* * For SWR master version 1.5.1, continue * execute on command ignore. @@ -2742,6 +2748,8 @@ static int swrm_runtime_suspend(struct device *dev) mutex_lock(&swrm->reslock); usleep_range(100, 105); } + if (!swrm_check_link_status(swrm, 0x0)) + goto exit; ret = swrm_clk_request(swrm, false); if (ret) { dev_err(dev, "%s: swrmn clk failed\n", __func__); @@ -2757,8 +2765,6 @@ static int swrm_runtime_suspend(struct device *dev) SWR_WAKE_IRQ_REGISTER, (void *)swrm); swrm->ipc_wakeup_triggered = false; } - if (!swrm_check_link_status(swrm, 0x0)) - goto exit; } } -- GitLab From c6974d0dadc2262a79841ba022e6a9ccf6985039 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 22 Nov 2019 15:18:47 +0530 Subject: [PATCH 1311/1645] asoc: bengal: Update comments with proper PCM ID info Update PCM ID with correct values in comments. Change-Id: Ie456481aa57f0adebb20921d8d0f0d25c7b714e0 Signed-off-by: Laxminath Kasam --- asoc/bengal.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/asoc/bengal.c b/asoc/bengal.c index c500a178f350..d60698d3b2ab 100644 --- a/asoc/bengal.c +++ b/asoc/bengal.c @@ -4835,7 +4835,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { }; static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { - {/* hw:x,34 */ + {/* hw:x,33 */ .name = MSM_DAILINK_NAME(ASM Loopback), .stream_name = "MultiMedia6", .cpu_dai_name = "MultiMedia6", @@ -4852,7 +4852,7 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA6, }, - {/* hw:x,35 */ + {/* hw:x,34 */ .name = "USB Audio Hostless", .stream_name = "USB Audio Hostless", .cpu_dai_name = "USBAUDIO_HOSTLESS", @@ -4868,7 +4868,7 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, - {/* hw:x,36 */ + {/* hw:x,35 */ .name = "SLIMBUS_7 Hostless", .stream_name = "SLIMBUS_7 Hostless", .cpu_dai_name = "SLIMBUS7_HOSTLESS", @@ -4884,7 +4884,7 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, - {/* hw:x,37 */ + {/* hw:x,36 */ .name = "Compress Capture", .stream_name = "Compress9", .cpu_dai_name = "MultiMedia17", @@ -4899,7 +4899,7 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA17, }, - {/* hw:x,38 */ + {/* hw:x,37 */ .name = "SLIMBUS_8 Hostless", .stream_name = "SLIMBUS_8 Hostless", .cpu_dai_name = "SLIMBUS8_HOSTLESS", @@ -4915,7 +4915,7 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, - {/* hw:x,39 */ + {/* hw:x,38 */ .name = LPASS_BE_TX_CDC_DMA_TX_5, .stream_name = "TX CDC DMA5 Capture", .cpu_dai_name = "msm-dai-cdc-dma-dev.45115", -- GitLab From 2d71d6d099817cb2e28d069026c2c4f04452f370 Mon Sep 17 00:00:00 2001 From: Ajit Pandey Date: Wed, 6 Nov 2019 11:42:42 +0530 Subject: [PATCH 1312/1645] dsp: adsp-loader: Add check around bytes read from nvmem cell nvmem_cell_read() return no of bytes read in 'len' variable and allocates similiar bytes of memory for buffer. Copy only these number of bytes from buf to avoid out of bounds issues. Change-Id: I712e5058d15deba939b6a743fcf5bff33ac51f84 Signed-off-by: Ajit Pandey --- dsp/adsp-loader.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dsp/adsp-loader.c b/dsp/adsp-loader.c index aec90f539b57..8316f003bcd4 100644 --- a/dsp/adsp-loader.c +++ b/dsp/adsp-loader.c @@ -324,14 +324,14 @@ static int adsp_loader_probe(struct platform_device *pdev) { struct adsp_loader_private *priv = NULL; struct nvmem_cell *cell; - ssize_t len; + size_t len; u32 *buf; const char **adsp_fw_name_array = NULL; int adsp_fw_cnt; u32* adsp_fw_bit_values = NULL; int i; int fw_name_size; - u32 adsp_var_idx; + u32 adsp_var_idx = 0; int ret = 0; ret = adsp_loader_init_sysfs(pdev); @@ -349,11 +349,11 @@ static int adsp_loader_probe(struct platform_device *pdev) } buf = nvmem_cell_read(cell, &len); nvmem_cell_put(cell); - if (IS_ERR_OR_NULL(buf)) { + if (IS_ERR_OR_NULL(buf) || len <= 0 || len > sizeof(u32)) { dev_dbg(&pdev->dev, "%s: FAILED to read nvmem cell \n", __func__); goto wqueue; } - adsp_var_idx = (*buf); + memcpy(&adsp_var_idx, buf, len); kfree(buf); /* Get count of fw images */ -- GitLab From 0fdd8a1fdeb984b9dff8497cdbf2bf61cea76a06 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Sat, 23 Nov 2019 22:49:46 -0800 Subject: [PATCH 1313/1645] ASoC: msm: add routing from MM21 to QUAT MI2S RX Add routing from Multimedia21 frontend to QUAT MI2S RX backend. Change-Id: I94484d1a0d2cdbc99174215417b0c33a5852ea8f Signed-off-by: Derek Chen --- asoc/msm-pcm-routing-v2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 9cddca06503f..7103dcd6a776 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -6575,6 +6575,10 @@ static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = { MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, @@ -25133,6 +25137,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, {"QUAT_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, {"QUAT_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUAT_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX Audio Mixer"}, -- GitLab From 021f8805a1e16a3ef8ba9a352105243b236e6336 Mon Sep 17 00:00:00 2001 From: Harshal Ahire Date: Sun, 24 Nov 2019 17:44:39 +0530 Subject: [PATCH 1314/1645] asoc: codecs: update VA_MACRO core voting Update entry for core voting in VA_MACRO. Change-Id: Iecc1035e04b9cd0f69e33e93643294ba879da63b Signed-off-by: Harshal Ahire --- asoc/codecs/bolero/va-macro.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index c5f0ef9c0373..14bf965ab676 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -119,6 +119,7 @@ struct va_macro_swr_ctrl_platform_data { int (*read)(void *handle, int reg); int (*write)(void *handle, int reg, int val); int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); + int (*core_vote)(void *handle, bool enable); int (*clk)(void *handle, bool enable); int (*handle_irq)(void *handle, irqreturn_t (*swrm_irq_handler)(int irq, @@ -603,6 +604,26 @@ static int va_macro_tx_va_mclk_enable(struct va_macro_priv *va_priv, return ret; } +static int va_macro_core_vote(void *handle, bool enable) +{ + struct va_macro_priv *va_priv = (struct va_macro_priv *) handle; + + if (va_priv == NULL) { + pr_err("%s: va priv data is NULL\n", __func__); + return -EINVAL; + } + if (enable) { + pm_runtime_get_sync(va_priv->dev); + pm_runtime_put_autosuspend(va_priv->dev); + pm_runtime_mark_last_busy(va_priv->dev); + } + + if (bolero_check_core_votes(va_priv->dev)) + return 0; + else + return -EINVAL; +} + static int va_macro_swrm_clock(void *handle, bool enable) { struct va_macro_priv *va_priv = (struct va_macro_priv *) handle; @@ -2845,6 +2866,7 @@ static int va_macro_probe(struct platform_device *pdev) va_priv->swr_plat_data.write = NULL; va_priv->swr_plat_data.bulk_write = NULL; va_priv->swr_plat_data.clk = va_macro_swrm_clock; + va_priv->swr_plat_data.core_vote = va_macro_core_vote; va_priv->swr_plat_data.handle_irq = NULL; mutex_init(&va_priv->swr_clk_lock); } -- GitLab From 6b5e14d72dd49eba5189b6ef76e94845dab1bbdb Mon Sep 17 00:00:00 2001 From: Harshal Ahire Date: Wed, 20 Nov 2019 21:17:26 +0530 Subject: [PATCH 1315/1645] dsp: Add cmd locks to fix synchronization issues Add mutex locks in q6core_send_get_avcs_fwk_ver_cmd() and q6core_map_mdf_shared_memory() functions to fix command-response synchronization issues in race conditions. Change-Id: Ibdf6788b51965bd37245c611683102c600ca8eb4 Signed-off-by: Harshal Ahire --- dsp/q6core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dsp/q6core.c b/dsp/q6core.c index 68fe9e5fb749..15c00bdec764 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -502,6 +502,7 @@ static int q6core_send_get_avcs_fwk_ver_cmd(void) struct apr_hdr avcs_ver_cmd; int ret; + mutex_lock(&q6core_lcl.cmd_lock); avcs_ver_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); @@ -548,6 +549,7 @@ static int q6core_send_get_avcs_fwk_ver_cmd(void) ret = 0; done: + mutex_unlock(&q6core_lcl.cmd_lock); return ret; } @@ -1428,14 +1430,16 @@ int q6core_map_mdf_shared_memory(uint32_t map_handle, uint64_t *buf_add, int i = 0; int cmd_size = 0; + mutex_lock(&q6core_lcl.cmd_lock); cmd_size = sizeof(struct avs_cmd_map_mdf_shared_memory) + sizeof(struct avs_shared_map_region_payload) * bufcnt; mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL); - if (mmap_region_cmd == NULL) + if (mmap_region_cmd == NULL) { + mutex_unlock(&q6core_lcl.cmd_lock); return -ENOMEM; - + } mmap_regions = (struct avs_cmd_map_mdf_shared_memory *)mmap_region_cmd; mmap_regions->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), @@ -1502,6 +1506,7 @@ int q6core_map_mdf_shared_memory(uint32_t map_handle, uint64_t *buf_add, done: kfree(mmap_region_cmd); + mutex_unlock(&q6core_lcl.cmd_lock); return ret; } -- GitLab From b58c0716e4b3292ff597ad366947c25df84b0972 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Wed, 20 Nov 2019 11:08:43 -0800 Subject: [PATCH 1316/1645] dsp: lsm: remove the size checking for sound model Currently q6lsm driver only allows buffer to be allocated for SVA sound model with size larger than 512 byte in function q6lsm_snd_model_buf_alloc.This causes issue when a valid SVA sound model is smaller than 512 byte. Since there is no restriction in ADSP for sound model size, remove this size checking to allow sound models with smaller size. Change-Id: I716dc8c0e1a4e3189cd334ef692ff07f3e4635db Signed-off-by: Xiaoyu Ye --- dsp/q6lsm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index d5c8e7ef70d1..8df449e499e7 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -28,7 +28,6 @@ #include "adsp_err.h" #define APR_TIMEOUT (HZ) -#define LSM_ALIGN_BOUNDARY 512 #define LSM_SAMPLE_RATE 16000 #define QLSM_PARAM_ID_MINOR_VERSION 1 #define QLSM_PARAM_ID_MINOR_VERSION_2 2 @@ -1973,7 +1972,7 @@ int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len, size_t total_mem = 0; struct lsm_sound_model *sm = NULL; - if (!client || len <= LSM_ALIGN_BOUNDARY) + if (!client) return rc; pr_debug("%s:Snd Model len = %zd, stage idx %d\n", -- GitLab From 9366ce6e8b1e5a5f52347ad8c6b7ee0400bf928c Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Wed, 6 Nov 2019 11:43:36 -0800 Subject: [PATCH 1317/1645] asoc: codecs: bolero: add delay after toggling hpf gate Add delay after toggling hpf gate to reduce noise levels while starting recording use case. Change-Id: I1a7b1b0a339abb3642ca8420753e9d07023acf89 Signed-off-by: Karthikeyan Mani --- asoc/codecs/bolero/tx-macro.c | 6 ++++++ asoc/codecs/bolero/va-macro.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 31745d60d5e8..13faf84109ca 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -911,6 +911,12 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, usleep_range(1000, 1010); snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x00); + snd_soc_component_update_bits(component, + hpf_gate_reg, 0x01, 0x01); + /* + * 6ms delay is required as per HW spec + */ + usleep_range(6000, 6010); } /* apply gain after decimator is enabled */ snd_soc_component_write(component, tx_gain_ctl_reg, diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index c5f0ef9c0373..e78b1da463b2 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -1037,6 +1037,12 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, usleep_range(1000, 1010); snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x00); + snd_soc_component_update_bits(component, + hpf_gate_reg, 0x01, 0x01); + /* + * 6ms delay is required as per HW spec + */ + usleep_range(6000, 6010); } /* schedule work queue to Remove Mute */ schedule_delayed_work(&va_priv->va_mute_dwork[decimator].dwork, -- GitLab From affb8790c5fdf61e296e66f3bc5c3c676045215a Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 26 Nov 2019 16:04:17 +0530 Subject: [PATCH 1318/1645] asoc: codecs: Enable interrupt mask at bootup Update chip wakeup enable mask at bootup for headset detection on bengal. Change-Id: Ic16bbb4dccf1a84140696ac47b340c407f5b41d5 Signed-off-by: Laxminath Kasam --- asoc/codecs/msm-cdc-pinctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/msm-cdc-pinctrl.c b/asoc/codecs/msm-cdc-pinctrl.c index 5c6ca495faed..62e9bfa26344 100644 --- a/asoc/codecs/msm-cdc-pinctrl.c +++ b/asoc/codecs/msm-cdc-pinctrl.c @@ -259,7 +259,7 @@ static int msm_cdc_pinctrl_probe(struct platform_device *pdev) gpio_data->chip_wakeup_register[i] = devm_ioremap(&pdev->dev, chip_wakeup_reg[i], 0x4); } - if (of_property_read_u32_array(pdev->dev.of_node, + if (!of_property_read_u32_array(pdev->dev.of_node, "qcom,chip-wakeup-default-val", chip_wakeup_default_val, count)) { for (i = 0; i < count; i++) { -- GitLab From 4696fffa8c7ff28f81fcdb19be808c072b615718 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 26 Nov 2019 16:07:11 +0530 Subject: [PATCH 1319/1645] asoc: Audio bringup changes for bengal Update change for audio playback and record to work on bengal target with wcd937x codec. Change-Id: I2f781e2132b018995f30f4192efd08732196cd28 Signed-off-by: Laxminath Kasam --- asoc/bengal-port-config.h | 6 +++--- asoc/codecs/bolero/va-macro.c | 11 ++++++++++- asoc/codecs/wcd937x/wcd937x.c | 1 + soc/swr-mstr-ctrl.c | 2 +- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/asoc/bengal-port-config.h b/asoc/bengal-port-config.h index 4ac7e10c0d42..a20a6d54487e 100644 --- a/asoc/bengal-port-config.h +++ b/asoc/bengal-port-config.h @@ -31,9 +31,9 @@ static struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = { /* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */ static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = { - {1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX1 */ - {1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, /* TX2 */ - {3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX3 */ + {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX1 */ + {3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX2 */ + {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX3 */ }; static struct swr_mstr_port_map sm_port_map[] = { diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 14bf965ab676..e2e13e412341 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -119,8 +119,8 @@ struct va_macro_swr_ctrl_platform_data { int (*read)(void *handle, int reg); int (*write)(void *handle, int reg, int val); int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); - int (*core_vote)(void *handle, bool enable); int (*clk)(void *handle, bool enable); + int (*core_vote)(void *handle, bool enable); int (*handle_irq)(void *handle, irqreturn_t (*swrm_irq_handler)(int irq, void *data), @@ -2541,6 +2541,15 @@ static int va_macro_init(struct snd_soc_component *component) } va_priv->component = component; + if (va_priv->version == BOLERO_VERSION_2_1) { + snd_soc_component_update_bits(component, + BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL0, 0xEE, 0xCC); + snd_soc_component_update_bits(component, + BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL1, 0xEE, 0xCC); + snd_soc_component_update_bits(component, + BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL2, 0xEE, 0xCC); + } + return 0; } diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 21325aeb2c97..78dcdb1c5148 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -2462,6 +2462,7 @@ static int wcd937x_soc_codec_probe(struct snd_soc_component *component) return -EINVAL; wcd937x->component = component; + snd_soc_component_init_regmap(component, wcd937x->regmap); variant = (snd_soc_component_read32( component, WCD937X_DIGITAL_EFUSE_REG_0) & 0x1E) >> 1; wcd937x->variant = variant; diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 242a51201bfe..6eacf22b6911 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2538,6 +2538,7 @@ static int swrm_probe(struct platform_device *pdev) swr_master_add_boarddevices(&swrm->master); mutex_lock(&swrm->mlock); swrm_clk_request(swrm, true); + swrm->version = swr_master_read(swrm, SWRM_COMP_HW_VERSION); ret = swrm_master_init(swrm); if (ret < 0) { dev_err(&pdev->dev, @@ -2546,7 +2547,6 @@ static int swrm_probe(struct platform_device *pdev) mutex_unlock(&swrm->mlock); goto err_mstr_fail; } - swrm->version = swr_master_read(swrm, SWRM_COMP_HW_VERSION); mutex_unlock(&swrm->mlock); INIT_WORK(&swrm->wakeup_work, swrm_wakeup_work); -- GitLab From bbce3836f130ab200c1a7983559866025acc7329 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Wed, 27 Nov 2019 15:21:56 -0800 Subject: [PATCH 1320/1645] ASoC: msm: set pinctrl if available on auto machine Set pinctrl only if available for respective TDM or MI2S interface on auto machine driver. Change-Id: I2b9a43f4958a6ad9ed086a77a65cb6dc67cc36a3 Signed-off-by: Derek Chen --- asoc/sa6155.c | 48 ++++++++++++++++++++++++++++-------------------- asoc/sa8155.c | 48 ++++++++++++++++++++++++++++-------------------- 2 files changed, 56 insertions(+), 40 deletions(-) diff --git a/asoc/sa6155.c b/asoc/sa6155.c index 73b95b2cef8b..86602553bf65 100644 --- a/asoc/sa6155.c +++ b/asoc/sa6155.c @@ -4801,11 +4801,13 @@ static int sa6155_tdm_snd_startup(struct snd_pcm_substream *substream) if (index == TDM_TERT || index == TDM_QUAT || index == TDM_QUIN) { pinctrl_info = &pdata->pinctrl_info[index]; - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_ACTIVE); - if (ret_pinctrl) - pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); + if (pinctrl_info->pinctrl) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_ACTIVE); + if (ret_pinctrl) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } } } mutex_unlock(&intf_conf->lock); @@ -4841,11 +4843,13 @@ static void sa6155_tdm_snd_shutdown(struct snd_pcm_substream *substream) if (index == TDM_TERT || index == TDM_QUAT || index == TDM_QUIN) { pinctrl_info = &pdata->pinctrl_info[index]; - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_SLEEP); - if (ret_pinctrl) - pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); + if (pinctrl_info->pinctrl) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_SLEEP); + if (ret_pinctrl) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } } } mutex_unlock(&intf_conf->lock); @@ -4935,11 +4939,13 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) } pinctrl_info = &pdata->pinctrl_info[index]; - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_ACTIVE); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); + if (pinctrl_info->pinctrl) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_ACTIVE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } } clk_off: if (ret < 0) @@ -4979,11 +4985,13 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) __func__, index, ret); pinctrl_info = &pdata->pinctrl_info[index]; - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_SLEEP); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); + if (pinctrl_info->pinctrl) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_SLEEP); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } } mutex_unlock(&intf_conf->lock); } diff --git a/asoc/sa8155.c b/asoc/sa8155.c index 228f43088604..2939fc2a587b 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -4791,11 +4791,13 @@ static int sa8155_tdm_snd_startup(struct snd_pcm_substream *substream) mutex_lock(&intf_conf->lock); if (++intf_conf->ref_cnt == 1) { pinctrl_info = &pdata->pinctrl_info[index]; - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_ACTIVE); - if (ret_pinctrl) - pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); + if (pinctrl_info->pinctrl) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_ACTIVE); + if (ret_pinctrl) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } } mutex_unlock(&intf_conf->lock); @@ -4828,11 +4830,13 @@ static void sa8155_tdm_snd_shutdown(struct snd_pcm_substream *substream) mutex_lock(&intf_conf->lock); if (--intf_conf->ref_cnt == 0) { pinctrl_info = &pdata->pinctrl_info[index]; - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_SLEEP); - if (ret_pinctrl) - pr_err("%s: TDM TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); + if (pinctrl_info->pinctrl) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_SLEEP); + if (ret_pinctrl) + pr_err("%s: TDM TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } } mutex_unlock(&intf_conf->lock); } @@ -4921,11 +4925,13 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) } pinctrl_info = &pdata->pinctrl_info[index]; - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_ACTIVE); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); + if (pinctrl_info->pinctrl) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_ACTIVE); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } } clk_off: if (ret < 0) @@ -4965,11 +4971,13 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) __func__, index, ret); pinctrl_info = &pdata->pinctrl_info[index]; - ret_pinctrl = msm_set_pinctrl(pinctrl_info, - STATE_SLEEP); - if (ret_pinctrl) - pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", - __func__, ret_pinctrl); + if (pinctrl_info->pinctrl) { + ret_pinctrl = msm_set_pinctrl(pinctrl_info, + STATE_SLEEP); + if (ret_pinctrl) + pr_err("%s: MI2S TLMM pinctrl set failed with %d\n", + __func__, ret_pinctrl); + } } mutex_unlock(&intf_conf->lock); } -- GitLab From 7b51a258a123b94c0d1425be2e28a2593c1f1400 Mon Sep 17 00:00:00 2001 From: Weiyin Jiang Date: Tue, 26 Nov 2019 03:33:12 +0800 Subject: [PATCH 1321/1645] ASoC: compr: wake up drain only if it's the last buffer There's a corner case where there're pause and resume operations in the middle of last full buffer drain. Waking up drain without checking against the real byte available violates the assumption only one partial buffer in the last write. The solution is to just resume the write pipe if there's more than one fragment pending. CRs-Fixed: 2536883 Change-Id: Id24c63bad774ec916942b8f94ddaa396d2560517 Signed-off-by: Weiyin Jiang --- asoc/msm-compress-q6-v2.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index c0452922c828..cfb560bda941 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -825,15 +825,23 @@ static void compr_event_handler(uint32_t opcode, * RESUME */ if ((prtd->copied_total == prtd->bytes_sent) && - atomic_read(&prtd->drain)) { - pr_debug("RUN ack, wake up & continue pending drain\n"); - - if (prtd->last_buffer) - prtd->last_buffer = 0; - - prtd->drain_ready = 1; - wake_up(&prtd->drain_wait); - atomic_set(&prtd->drain, 0); + atomic_read(&prtd->drain)) { + bytes_available = prtd->bytes_received - prtd->copied_total; + if (bytes_available < cstream->runtime->fragment_size) { + pr_debug("%s: RUN ack, wake up & continue pending drain\n", + __func__); + + if (prtd->last_buffer) + prtd->last_buffer = 0; + + prtd->drain_ready = 1; + wake_up(&prtd->drain_wait); + atomic_set(&prtd->drain, 0); + } else if (atomic_read(&prtd->xrun)) { + pr_debug("%s: RUN ack, continue write cycle\n", __func__); + atomic_set(&prtd->xrun, 0); + msm_compr_send_buffer(prtd); + } } spin_unlock_irqrestore(&prtd->lock, flags); -- GitLab From 1cbefc9365922cd436699b7767c3fec9fd0c994c Mon Sep 17 00:00:00 2001 From: Harshal Ahire Date: Wed, 20 Nov 2019 14:54:42 +0530 Subject: [PATCH 1322/1645] asoc: add routing control for Multimedia17 with Slim7 TX Add routing control for Multimedia17 with Slim7 TX. Change-Id: I6d21f2a5e2a1923c64d82726e951c2c5bd40eabc Signed-off-by: Harshal Ahire --- asoc/msm-pcm-routing-v2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index f3831e9fbdc0..a133606b203e 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -14441,6 +14441,10 @@ static const struct snd_kcontrol_new mmul17_mixer_controls[] = { MSM_BACKEND_DAI_AFE_LOOPBACK_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul18_mixer_controls[] = { @@ -25230,6 +25234,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia4 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia17 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia17 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia17 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"MultiMedia18 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia18 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia19 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, -- GitLab From d7df12367f4d31412363d3419ba43178a0729e64 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Fri, 29 Nov 2019 19:39:17 +0530 Subject: [PATCH 1323/1645] asoc: set format param mask for SLIM_7_TX backend Enable format mask for SLIM_7_TX backend to fix hardware params setting failure. Change-Id: I141bbed3d4272eb4e7d93027082d705f949a502f Signed-off-by: Prasad Kumpatla --- asoc/kona.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/kona.c b/asoc/kona.c index 1df6d34e2cad..bbb790983ae1 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -4435,6 +4435,8 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; case MSM_BACKEND_DAI_SLIMBUS_7_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[SLIM_TX_7].bit_format); rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate; channels->min = channels->max = slim_tx_cfg[SLIM_TX_7].channels; -- GitLab From e1a5f9735200016eca86e51e1cc76f5e11692c31 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 3 Dec 2019 00:57:24 +0530 Subject: [PATCH 1324/1645] asoc: routing: Fix CDC_DMA_RX_1 routing to SLIM_8_TX for loopback For loopback of CDC_DMA_RX_1 port to slim_8_tx, add proper switch control. Change-Id: I58353c8cc43ac96d39a810b8e471458111f57319 Signed-off-by: Laxminath Kasam --- asoc/msm-pcm-routing-v2.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index faa2b0662ceb..2488a7582cf0 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -21687,6 +21687,11 @@ static const struct snd_kcontrol_new cdc_dma_rx_switch_mixer_controls = 0, 1, 0, msm_routing_get_switch_mixer, msm_routing_put_switch_mixer); +static const struct snd_kcontrol_new cdc_dma_rx_1_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + static const struct snd_kcontrol_new slim6_fm_switch_mixer_controls = SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, 0, 1, 0, msm_routing_get_switch_mixer, @@ -24061,6 +24066,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &cdc_dma_wsa_switch_mixer_controls), SND_SOC_DAPM_SWITCH("RX_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, &cdc_dma_rx_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("RX_CDC_DMA_RX_1_DL_HL", SND_SOC_NOPM, 0, 0, + &cdc_dma_rx_1_switch_mixer_controls), /* Mixer definitions */ SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0, @@ -27529,7 +27536,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"CDC_DMA_UL_HL", NULL, "VA_CDC_DMA_TX_0"}, {"RX_CDC_DMA_RX_0_DL_HL", "Switch", "CDC_DMA_DL_HL"}, {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0_DL_HL"}, - {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_0_DL_HL"}, + {"RX_CDC_DMA_RX_1_DL_HL", "Switch", "CDC_DMA_DL_HL"}, + {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1_DL_HL"}, {"TX3_CDC_DMA_UL_HL", NULL, "TX_CDC_DMA_TX_3"}, {"LSM1 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, {"LSM1 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, -- GitLab From 03eeaf15cd1792e19108a0e4405fb73abd397618 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 3 Dec 2019 05:59:31 +0530 Subject: [PATCH 1325/1645] ASoC: bolero: Update the sequence for native audio playback Update the clock sequence for native audio playback to avoid any distortion or change in gain during native audio playback usecase. Change-Id: Ia9aaa63f3e476b49a07d49b794f4120ed55bac47 Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/rx-macro.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index ffcd734091df..7844ee6afe6e 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1245,6 +1245,9 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, regmap_update_bits(regmap, BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, 0x02, 0x02); + regmap_update_bits(regmap, + BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x02, 0x00); regmap_update_bits(regmap, BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x01); @@ -1262,6 +1265,12 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, regmap_update_bits(regmap, BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x00); + regmap_update_bits(regmap, + BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x02, 0x02); + regmap_update_bits(regmap, + BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, + 0x02, 0x00); regmap_update_bits(regmap, BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x00); -- GitLab From d6546e3044d5ea7b8d7f55337c791c06e9bdc25f Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 29 Oct 2019 17:24:59 +0530 Subject: [PATCH 1326/1645] dsp: Synchronize afe apr send pkt commands Synchronize afe apr send pkt commands to avoid the state variable modification for multiple commands sent in parallel. Use the common interface afe_apr_send_pkt to send the apr pkt. Change-Id: I17a573a28e227cce882c3330887ae2756ca4addb Signed-off-by: Aditya Bavanari --- dsp/q6afe.c | 229 +++++++++++----------------------------------------- 1 file changed, 46 insertions(+), 183 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 7297a1ed08bf..b65cc98f912d 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -153,6 +153,7 @@ struct afe_ctl { uint32_t afe_sample_rates[AFE_MAX_PORTS]; struct aanc_data aanc_info; struct mutex afe_cmd_lock; + struct mutex afe_apr_lock; int set_custom_topology; int dev_acdb_id[AFE_MAX_PORTS]; routing_cb rt_cb; @@ -1053,6 +1054,7 @@ static int afe_apr_send_pkt(void *data, wait_queue_head_t *wait) { int ret; + mutex_lock(&this_afe.afe_apr_lock); if (wait) atomic_set(&this_afe.state, 1); atomic_set(&this_afe.status, 0); @@ -1063,6 +1065,8 @@ static int afe_apr_send_pkt(void *data, wait_queue_head_t *wait) (atomic_read(&this_afe.state) == 0), msecs_to_jiffies(2 * TIMEOUT_MS)); if (!ret) { + pr_err_ratelimited("%s: request timedout\n", + __func__); ret = -ETIMEDOUT; } else if (atomic_read(&this_afe.status) > 0) { pr_err("%s: DSP returned error[%s]\n", __func__, @@ -1083,6 +1087,7 @@ static int afe_apr_send_pkt(void *data, wait_queue_head_t *wait) } pr_debug("%s: leave %d\n", __func__, ret); + mutex_unlock(&this_afe.afe_apr_lock); return ret; } @@ -1807,34 +1812,7 @@ static int afe_spkr_prot_reg_event_cfg(u16 port_id) config->num_events = num_events; config->version = 1; memcpy(config->payload, &pl, sizeof(pl)); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) config); - if (ret < 0) { - pr_err("%s: port = 0x%x failed %d\n", - __func__, port_id, ret); - goto fail_cmd; - } - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_idx; - } - ret = 0; -fail_cmd: - pr_debug("%s: config.opcode 0x%x status %d\n", - __func__, config->hdr.opcode, ret); + ret = afe_apr_send_pkt((uint32_t *) config, &this_afe.wait[index]); fail_idx: kfree(config); @@ -3315,34 +3293,7 @@ int afe_spdif_reg_event_cfg(u16 port_id, u16 reg_flag, config->num_events = num_events; config->version = 1; memcpy(config->payload, &pl, sizeof(pl)); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) config); - if (ret < 0) { - pr_err("%s: port = 0x%x failed %d\n", - __func__, port_id, ret); - goto fail_cmd; - } - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_idx; - } - ret = 0; -fail_cmd: - pr_debug("%s: config.opcode 0x%x status %d\n", - __func__, config->hdr.opcode, ret); + ret = afe_apr_send_pkt((uint32_t *) config, &this_afe.wait[index]); fail_idx: kfree(config); @@ -6061,39 +6012,10 @@ int afe_cmd_memory_map(phys_addr_t dma_addr_p, u32 dma_buf_sz) pr_debug("%s: dma_addr_p 0x%pK , size %d\n", __func__, &dma_addr_p, dma_buf_sz); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); this_afe.mmap_handle = 0; - ret = apr_send_pkt(this_afe.apr, (uint32_t *) mmap_region_cmd); - if (ret < 0) { - pr_err("%s: AFE memory map cmd failed %d\n", - __func__, ret); - ret = -EINVAL; - goto fail_cmd; - } - - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } - - kfree(mmap_region_cmd); - return 0; -fail_cmd: + ret = afe_apr_send_pkt((uint32_t *) mmap_region_cmd, + &this_afe.wait[index]); kfree(mmap_region_cmd); - pr_err("%s: fail_cmd\n", __func__); return ret; } @@ -6508,10 +6430,19 @@ int afe_rt_proxy_port_write(phys_addr_t buf_addr_p, afecmd_wr.available_bytes = bytes; afecmd_wr.reserved = 0; - ret = afe_apr_send_pkt(&afecmd_wr, NULL); - if (ret) + /* + * Do not call afe_apr_send_pkt() here as it acquires + * a mutex lock inside and this function gets called in + * interrupt context leading to scheduler crash + */ + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) &afecmd_wr); + if (ret < 0) { pr_err("%s: AFE rtproxy write to port 0x%x failed %d\n", - __func__, afecmd_wr.port_id, ret); + __func__, afecmd_wr.port_id, ret); + ret = -EINVAL; + } + return ret; } @@ -6555,10 +6486,19 @@ int afe_rt_proxy_port_read(phys_addr_t buf_addr_p, afecmd_rd.available_bytes = bytes; afecmd_rd.mem_map_handle = mem_map_handle; - ret = afe_apr_send_pkt(&afecmd_rd, NULL); - if (ret) + /* + * Do not call afe_apr_send_pkt() here as it acquires + * a mutex lock inside and this function gets called in + * interrupt context leading to scheduler crash + */ + atomic_set(&this_afe.status, 0); + ret = apr_send_pkt(this_afe.apr, (uint32_t *) &afecmd_rd); + if (ret < 0) { pr_err("%s: AFE rtproxy read cmd to port 0x%x failed %d\n", - __func__, afecmd_rd.port_id, ret); + __func__, afecmd_rd.port_id, ret); + ret = -EINVAL; + } + return ret; } EXPORT_SYMBOL(afe_rt_proxy_port_read); @@ -6802,15 +6742,6 @@ int afe_dtmf_generate_rx(int64_t duration_in_ms, cmd_dtmf.num_ports = 1; cmd_dtmf.port_ids = q6audio_get_port_id(this_afe.dtmf_gen_rx_portid); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &cmd_dtmf); - if (ret < 0) { - pr_err("%s: AFE DTMF failed for num_ports:%d ids:0x%x\n", - __func__, cmd_dtmf.num_ports, cmd_dtmf.port_ids); - ret = -EINVAL; - goto fail_cmd; - } index = q6audio_get_port_index(this_afe.dtmf_gen_rx_portid); if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: AFE port index[%d] invalid!\n", @@ -6818,24 +6749,9 @@ int afe_dtmf_generate_rx(int64_t duration_in_ms, ret = -EINVAL; goto fail_cmd; } - ret = wait_event_timeout(this_afe.wait[index], - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } - return 0; - + ret = afe_apr_send_pkt((uint32_t *) &cmd_dtmf, + &this_afe.wait[index]); + return ret; fail_cmd: pr_err("%s: failed %d\n", __func__, ret); return ret; @@ -9097,6 +9013,7 @@ int __init afe_init(void) this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; mutex_init(&this_afe.afe_cmd_lock); + mutex_init(&this_afe.afe_apr_lock); for (i = 0; i < AFE_MAX_PORTS; i++) { this_afe.afe_cal_mode[i] = AFE_CAL_MODE_DEFAULT; this_afe.afe_sample_rates[i] = 0; @@ -9151,6 +9068,7 @@ void afe_exit(void) config_debug_fs_exit(); mutex_destroy(&this_afe.afe_cmd_lock); + mutex_destroy(&this_afe.afe_apr_lock); wakeup_source_trash(&wl.ws); } @@ -9234,41 +9152,14 @@ int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name, __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id); *client_handle = 0; - atomic_set(&this_afe.status, 0); - atomic_set(&this_afe.state, 1); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) cmd_ptr); - if (ret < 0) { - pr_err("%s: lpass core hw vote failed %d\n", - __func__, ret); - goto done; + ret = afe_apr_send_pkt((uint32_t *) cmd_ptr, + &this_afe.lpass_core_hw_wait); + if (ret == 0) { + *client_handle = this_afe.lpass_hw_core_client_hdl[hw_block_id]; + pr_debug("%s: lpass_hw_core_client_hdl %d\n", __func__, + this_afe.lpass_hw_core_client_hdl[hw_block_id]); } - ret = wait_event_timeout(this_afe.lpass_core_hw_wait, - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: timeout. waited for lpass core hw vote\n", - __func__); - ret = -ETIMEDOUT; - goto done; - } else { - /* set ret to 0 as no timeout happened */ - ret = 0; - } - - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: lpass core hw vote cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto done; - } - - *client_handle = this_afe.lpass_hw_core_client_hdl[hw_block_id]; - pr_debug("%s: lpass_hw_core_client_hdl %d\n", __func__, - this_afe.lpass_hw_core_client_hdl[hw_block_id]); -done: mutex_unlock(&this_afe.afe_cmd_lock); return ret; } @@ -9324,36 +9215,8 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle) goto done; } - atomic_set(&this_afe.status, 0); - atomic_set(&this_afe.state, 1); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) cmd_ptr); - if (ret < 0) { - pr_err("%s: lpass core hw devote failed %d\n", - __func__, ret); - goto done; - } - - ret = wait_event_timeout(this_afe.lpass_core_hw_wait, - (atomic_read(&this_afe.state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: timeout. waited for lpass core hw devote\n", - __func__); - ret = -ETIMEDOUT; - goto done; - } else { - /* set ret to 0 as no timeout happened */ - ret = 0; - } - - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: lpass core hw devote cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - } - + ret = afe_apr_send_pkt((uint32_t *) cmd_ptr, + &this_afe.lpass_core_hw_wait); done: mutex_unlock(&this_afe.afe_cmd_lock); return ret; -- GitLab From 696b14bfa267788903ce17bbd1775915d2b751a4 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 3 Dec 2019 22:07:34 +0530 Subject: [PATCH 1327/1645] asoc: Audio bringup changes for bengal Audio bringup fixes for bengal target. Change-Id: Ic79c478fe3c6b80eeb48aa2bcf1887c8dd8f5edc Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 18 ++++++++++++++++++ asoc/codecs/bolero/tx-macro.c | 4 ++-- asoc/codecs/wcd937x/internal.h | 1 + soc/swr-mstr-ctrl.c | 9 ++++++--- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index a9ec81a89418..8349dea5a014 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -3326,6 +3326,8 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { {"RX INT0_1 MIX1 INP0", "RX5", "RX_RX5"}, {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"}, {"RX INT0_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT0_1 MIX1 INP0", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT0_1 MIX1 INP0", "DEC1", "RX_TX DEC1_INP"}, {"RX INT0_1 MIX1 INP1", "RX0", "RX_RX0"}, {"RX INT0_1 MIX1 INP1", "RX1", "RX_RX1"}, {"RX INT0_1 MIX1 INP1", "RX2", "RX_RX2"}, @@ -3334,6 +3336,8 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { {"RX INT0_1 MIX1 INP1", "RX5", "RX_RX5"}, {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"}, {"RX INT0_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT0_1 MIX1 INP1", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT0_1 MIX1 INP1", "DEC1", "RX_TX DEC1_INP"}, {"RX INT0_1 MIX1 INP2", "RX0", "RX_RX0"}, {"RX INT0_1 MIX1 INP2", "RX1", "RX_RX1"}, {"RX INT0_1 MIX1 INP2", "RX2", "RX_RX2"}, @@ -3342,6 +3346,8 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { {"RX INT0_1 MIX1 INP2", "RX5", "RX_RX5"}, {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"}, {"RX INT0_1 MIX1 INP2", "IIR1", "IIR1"}, + {"RX INT0_1 MIX1 INP2", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT0_1 MIX1 INP2", "DEC1", "RX_TX DEC1_INP"}, {"RX INT1_1 MIX1 INP0", "RX0", "RX_RX0"}, {"RX INT1_1 MIX1 INP0", "RX1", "RX_RX1"}, @@ -3351,6 +3357,8 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { {"RX INT1_1 MIX1 INP0", "RX5", "RX_RX5"}, {"RX INT1_1 MIX1 INP0", "IIR0", "IIR0"}, {"RX INT1_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT1_1 MIX1 INP0", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT1_1 MIX1 INP0", "DEC1", "RX_TX DEC1_INP"}, {"RX INT1_1 MIX1 INP1", "RX0", "RX_RX0"}, {"RX INT1_1 MIX1 INP1", "RX1", "RX_RX1"}, {"RX INT1_1 MIX1 INP1", "RX2", "RX_RX2"}, @@ -3359,6 +3367,8 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { {"RX INT1_1 MIX1 INP1", "RX5", "RX_RX5"}, {"RX INT1_1 MIX1 INP1", "IIR0", "IIR0"}, {"RX INT1_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT1_1 MIX1 INP1", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT1_1 MIX1 INP1", "DEC1", "RX_TX DEC1_INP"}, {"RX INT1_1 MIX1 INP2", "RX0", "RX_RX0"}, {"RX INT1_1 MIX1 INP2", "RX1", "RX_RX1"}, {"RX INT1_1 MIX1 INP2", "RX2", "RX_RX2"}, @@ -3367,6 +3377,8 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { {"RX INT1_1 MIX1 INP2", "RX5", "RX_RX5"}, {"RX INT1_1 MIX1 INP2", "IIR0", "IIR0"}, {"RX INT1_1 MIX1 INP2", "IIR1", "IIR1"}, + {"RX INT1_1 MIX1 INP2", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT1_1 MIX1 INP2", "DEC1", "RX_TX DEC1_INP"}, {"RX INT2_1 MIX1 INP0", "RX0", "RX_RX0"}, {"RX INT2_1 MIX1 INP0", "RX1", "RX_RX1"}, @@ -3376,6 +3388,8 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { {"RX INT2_1 MIX1 INP0", "RX5", "RX_RX5"}, {"RX INT2_1 MIX1 INP0", "IIR0", "IIR0"}, {"RX INT2_1 MIX1 INP0", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP0", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT2_1 MIX1 INP0", "DEC1", "RX_TX DEC1_INP"}, {"RX INT2_1 MIX1 INP1", "RX0", "RX_RX0"}, {"RX INT2_1 MIX1 INP1", "RX1", "RX_RX1"}, {"RX INT2_1 MIX1 INP1", "RX2", "RX_RX2"}, @@ -3384,6 +3398,8 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { {"RX INT2_1 MIX1 INP1", "RX5", "RX_RX5"}, {"RX INT2_1 MIX1 INP1", "IIR0", "IIR0"}, {"RX INT2_1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP1", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT2_1 MIX1 INP1", "DEC1", "RX_TX DEC1_INP"}, {"RX INT2_1 MIX1 INP2", "RX0", "RX_RX0"}, {"RX INT2_1 MIX1 INP2", "RX1", "RX_RX1"}, {"RX INT2_1 MIX1 INP2", "RX2", "RX_RX2"}, @@ -3392,6 +3408,8 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { {"RX INT2_1 MIX1 INP2", "RX5", "RX_RX5"}, {"RX INT2_1 MIX1 INP2", "IIR0", "IIR0"}, {"RX INT2_1 MIX1 INP2", "IIR1", "IIR1"}, + {"RX INT2_1 MIX1 INP2", "DEC0", "RX_TX DEC0_INP"}, + {"RX INT2_1 MIX1 INP2", "DEC1", "RX_TX DEC1_INP"}, {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"}, {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"}, diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 31745d60d5e8..6513a497a3b5 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -2845,10 +2845,10 @@ static int tx_macro_init(struct snd_soc_component *component) if (tx_priv->version == BOLERO_VERSION_2_1) snd_soc_component_update_bits(component, - BOLERO_CDC_VA_TOP_CSR_SWR_CTRL, 0xF0, 0xA0); + BOLERO_CDC_VA_TOP_CSR_SWR_CTRL, 0x0F, 0x0A); else if (tx_priv->version == BOLERO_VERSION_2_0) snd_soc_component_update_bits(component, - BOLERO_CDC_TX_TOP_CSR_SWR_CTRL, 0xF0, 0xA0); + BOLERO_CDC_TX_TOP_CSR_SWR_CTRL, 0x0F, 0x0A); return 0; } diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index faf011860448..381634caf9da 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -133,6 +133,7 @@ enum { WCD_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */ WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */ WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */ + WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST, WCD_BOLERO_EVT_BCS_CLK_OFF, }; diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 6eacf22b6911..86df1c3a724b 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2734,7 +2734,8 @@ static int swrm_runtime_resume(struct device *dev) /* wait for hw enumeration to complete */ usleep_range(100, 105); if (!swrm_check_link_status(swrm, 0x1)) - goto exit; + dev_dbg(dev, "%s:failed in connecting, ssr?\n", + __func__); swrm_cmd_fifo_wr_cmd(swrm, 0x4, 0xF, 0x0, SWRS_SCP_INT_STATUS_MASK_1); if (swrm->state == SWR_MSTR_SSR) { @@ -2755,7 +2756,8 @@ static int swrm_runtime_resume(struct device *dev) swrm->intr_mask); usleep_range(100, 105); if (!swrm_check_link_status(swrm, 0x1)) - goto exit; + dev_dbg(dev, "%s:failed in connecting, ssr?\n", + __func__); } swrm->state = SWR_MSTR_UP; } @@ -2849,7 +2851,8 @@ static int swrm_runtime_suspend(struct device *dev) usleep_range(100, 105); } if (!swrm_check_link_status(swrm, 0x0)) - goto exit; + dev_dbg(dev, "%s:failed in disconnecting, ssr?\n", + __func__); ret = swrm_clk_request(swrm, false); if (ret) { dev_err(dev, "%s: swrmn clk failed\n", __func__); -- GitLab From 4ff8084a36f09a68fc3f3dcbbec6ed0b59241c9f Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 28 Oct 2019 15:31:00 +0800 Subject: [PATCH 1328/1645] asoc: bolero: add mixer control for LPI enable flag Add mixer control for LPI enable flag. The listener should only be registered for LPI SVA session. Change-Id: I01e4b0868e3333e1fc60f86444b1cf1c77e25cb7 Signed-off-by: Meng Wang --- asoc/codecs/bolero/va-macro.c | 49 +++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index e2e13e412341..3e9ff12c9c8d 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -170,6 +170,8 @@ struct va_macro_priv { int va_swr_clk_cnt; int va_clk_status; int tx_clk_status; + bool lpi_enable; + bool register_event_listener; }; static bool va_macro_get_data(struct snd_soc_component *component, @@ -403,10 +405,16 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, if (bolero_tx_clk_switch(component)) dev_dbg(va_dev, "%s: clock switch failed\n", __func__); - bolero_register_event_listener(component, true); + if (va_priv->lpi_enable) { + bolero_register_event_listener(component, true); + va_priv->register_event_listener = true; + } break; case SND_SOC_DAPM_POST_PMD: - bolero_register_event_listener(component, false); + if (va_priv->register_event_listener) { + va_priv->register_event_listener = false; + bolero_register_event_listener(component, false); + } if (bolero_tx_clk_switch(component)) dev_dbg(va_dev, "%s: clock switch failed\n",__func__); if (va_priv->lpass_audio_hw_vote) @@ -852,6 +860,38 @@ static int va_macro_put_dec_enum(struct snd_kcontrol *kcontrol, return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); } +static int va_macro_lpi_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = va_priv->lpi_enable; + + return 0; +} + +static int va_macro_lpi_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) + return -EINVAL; + + va_priv->lpi_enable = ucontrol->value.integer.value[0]; + + return 0; +} + static int va_macro_tx_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2295,6 +2335,8 @@ static const struct snd_kcontrol_new va_macro_snd_controls[] = { SOC_SINGLE_SX_TLV("VA_DEC7 Volume", BOLERO_CDC_VA_TX7_TX_VOL_CTL, 0, -84, 40, digital_gain), + SOC_SINGLE_EXT("LPI Enable", 0, 0, 1, 0, + va_macro_lpi_get, va_macro_lpi_put), }; static const struct snd_kcontrol_new va_macro_snd_controls_common[] = { @@ -2386,6 +2428,9 @@ static int va_macro_init(struct snd_soc_component *component) return -EINVAL; } + va_priv->lpi_enable = false; + va_priv->register_event_listener = false; + if (va_priv->va_without_decimation) { ret = snd_soc_dapm_new_controls(dapm, va_macro_wod_dapm_widgets, ARRAY_SIZE(va_macro_wod_dapm_widgets)); -- GitLab From d4c151d76e8b5e48232c0cd19b38e33f81274aeb Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Wed, 4 Dec 2019 13:39:40 +0530 Subject: [PATCH 1329/1645] dsp: codecs: fix error check for q6audio aio Fix error check for q6audio audio pointer to avoid Null pointer dereference. Change-Id: Icf30cf2f670c07f3118132e378fa43256ddec530 Signed-off-by: Prasad Kumpatla --- dsp/codecs/q6audio_v2_aio.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dsp/codecs/q6audio_v2_aio.c b/dsp/codecs/q6audio_v2_aio.c index 4cb46365b12c..a6f7836d8134 100644 --- a/dsp/codecs/q6audio_v2_aio.c +++ b/dsp/codecs/q6audio_v2_aio.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. */ #include @@ -43,6 +43,10 @@ void audio_aio_cb(uint32_t opcode, uint32_t token, struct q6audio_aio *audio = (struct q6audio_aio *)priv; union msm_audio_event_payload e_payload; + if (audio == NULL) { + pr_err("%s: failed to get q6audio value\n", __func__); + return; + } switch (opcode) { case ASM_DATA_EVENT_WRITE_DONE_V2: pr_debug("%s[%pK]:ASM_DATA_EVENT_WRITE_DONE token = 0x%x\n", -- GitLab From ef20c8c2d503b28a8e0c44986375bd71b9746fdc Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 6 Dec 2019 14:48:29 +0530 Subject: [PATCH 1330/1645] asoc: wcd937x: Avoid clk disable at aux dac Clock disable at aux dac event is not needed as rx3 widget already disables it. Change-Id: I67feec194cdae5c6d84efcde0a2931ba8f8440dd Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd937x/wcd937x.c | 1 - 1 file changed, 1 deletion(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 78dcdb1c5148..e962067ed22d 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -623,7 +623,6 @@ static int wcd937x_codec_aux_dac_event(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: - wcd937x_rx_clk_disable(component); snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x04, 0x00); -- GitLab From f504f7e2aaa63f29632e9baa23c78a4a5273dcf5 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 6 Dec 2019 19:13:13 +0530 Subject: [PATCH 1331/1645] soc: soundwire: Fix type of swr addr to support 32bit arch for 32bit arch based builds, soundwire logical address fails when compare with dtsi value (64bit). Update addr type of soundwire slave addr to u64. Change-Id: Ifda388ca66350a2bc898484cddecbbcab4d3ece4 Signed-off-by: Laxminath Kasam --- include/soc/soundwire.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/soc/soundwire.h b/include/soc/soundwire.h index 655b53ef604c..bb71a357366e 100644 --- a/include/soc/soundwire.h +++ b/include/soc/soundwire.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #ifndef _LINUX_SOUNDWIRE_H @@ -200,7 +200,7 @@ struct swr_device { struct list_head dev_list; u8 dev_num; struct device dev; - unsigned long addr; + u64 addr; u8 group_id; struct irq_domain *slave_irq; bool slave_irq_pending; -- GitLab From efd65f122496cc26b5946c446dc5adce0be34e6d Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 6 Dec 2019 18:07:02 +0530 Subject: [PATCH 1332/1645] ASoC: bolero: Fix voice activation not working on SWR MICs Voice Activation is not working from second time on SWR MICs. Make tx macro registers related to SWR MIC as volatile to resolve the issue. Change-Id: Iac52af37d32b53ada193d855949b345da0e47d9c Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/bolero-cdc-regmap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asoc/codecs/bolero/bolero-cdc-regmap.c b/asoc/codecs/bolero/bolero-cdc-regmap.c index 77f5420dc48f..b1a263fb008f 100644 --- a/asoc/codecs/bolero/bolero-cdc-regmap.c +++ b/asoc/codecs/bolero/bolero-cdc-regmap.c @@ -797,6 +797,10 @@ static bool bolero_is_volatile_register(struct device *dev, case BOLERO_CDC_VA_TOP_CSR_CORE_ID_1: case BOLERO_CDC_VA_TOP_CSR_CORE_ID_2: case BOLERO_CDC_VA_TOP_CSR_CORE_ID_3: + case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL: + case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC1_CTL: + case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC2_CTL: + case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC3_CTL: case BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_MON_VAL: case BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_ST: case BOLERO_CDC_WSA_INTR_CTRL_PIN1_STATUS0: -- GitLab From ee5d037b2158192b1e2e83e55cda098a1ea1098a Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Fri, 6 Dec 2019 16:08:14 +0530 Subject: [PATCH 1333/1645] asoc: bengal: set format param mask for SLIM_7_TX backend Enable format mask for SLIM_7_TX backend to fix hardware params setting failure on bengal target. Change-Id: I00d7f8a2613c4b396196222e7e6256f896d58cc6 Signed-off-by: Prasad Kumpatla --- asoc/bengal.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/bengal.c b/asoc/bengal.c index d60698d3b2ab..49415d8291ae 100644 --- a/asoc/bengal.c +++ b/asoc/bengal.c @@ -3465,6 +3465,8 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; case MSM_BACKEND_DAI_SLIMBUS_7_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[SLIM_TX_7].bit_format); rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate; channels->min = channels->max = slim_tx_cfg[SLIM_TX_7].channels; -- GitLab From 7100fb8474f827eb028e801d8db904d1fddc224b Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 6 Dec 2019 19:49:01 +0530 Subject: [PATCH 1334/1645] asoc: codecs: Synchronize fs gen sequence updates Synchronize the bolero fs gen sequence updates in order to avoid race conditions. Change-Id: Idb95dcf1d5f5f4d24ab507ccd221d399a6b5a021 Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/bolero-clk-rsc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c index b80a2671253e..b8ed6641633c 100644 --- a/asoc/codecs/bolero/bolero-clk-rsc.c +++ b/asoc/codecs/bolero/bolero-clk-rsc.c @@ -32,6 +32,7 @@ static char clk_src_name[MAX_CLK][BOLERO_CLK_NAME_LENGTH] = { struct bolero_clk_rsc { struct device *dev; struct mutex rsc_clk_lock; + struct mutex fs_gen_lock; struct clk *clk[MAX_CLK]; int clk_cnt[MAX_CLK]; int reg_seq_en_cnt; @@ -422,6 +423,7 @@ void bolero_clk_rsc_fs_gen_request(struct device *dev, bool enable) pr_err("%s: regmap is null\n", __func__); return; } + mutex_lock(&priv->fs_gen_lock); if (enable) { if (priv->reg_seq_en_cnt++ == 0) { for (i = 0; i < (priv->num_fs_reg * 2); i += 2) { @@ -439,6 +441,7 @@ void bolero_clk_rsc_fs_gen_request(struct device *dev, bool enable) dev_err_ratelimited(priv->dev, "%s: req_seq_cnt: %d is already disabled\n", __func__, priv->reg_seq_en_cnt); priv->reg_seq_en_cnt = 0; + mutex_unlock(&priv->fs_gen_lock); return; } if (--priv->reg_seq_en_cnt == 0) { @@ -451,6 +454,7 @@ void bolero_clk_rsc_fs_gen_request(struct device *dev, bool enable) } } } + mutex_unlock(&priv->fs_gen_lock); } EXPORT_SYMBOL(bolero_clk_rsc_fs_gen_request); @@ -665,6 +669,7 @@ static int bolero_clk_rsc_probe(struct platform_device *pdev) priv->dev = &pdev->dev; priv->dev_up = true; mutex_init(&priv->rsc_clk_lock); + mutex_init(&priv->fs_gen_lock); dev_set_drvdata(&pdev->dev, priv); err: @@ -680,6 +685,7 @@ static int bolero_clk_rsc_remove(struct platform_device *pdev) if (!priv) return -EINVAL; mutex_destroy(&priv->rsc_clk_lock); + mutex_destroy(&priv->fs_gen_lock); return 0; } -- GitLab From 9eacb9674173e46b6b2d5aca11b47e4521e31f8c Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 19 Nov 2019 09:16:55 +0800 Subject: [PATCH 1335/1645] dsp: afe: add new clk state and lock for codec clk cmds There's some race condition when sending afe cmds between USB playback and codec clk enablement. Add new clk_state, clk_status and clk lock to resolve the race condition. Change-Id: I2ccc77c20a274b797129b8b674c026ef003353d4 Signed-off-by: Meng Wang --- dsp/q6afe.c | 224 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 196 insertions(+), 28 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index b65cc98f912d..75ce5b004e55 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -23,6 +23,7 @@ #include "q6afecal-hwdep.h" #define WAKELOCK_TIMEOUT 5000 +#define AFE_CLK_TOKEN 1024 enum { AFE_COMMON_RX_CAL = 0, AFE_COMMON_TX_CAL, @@ -106,8 +107,11 @@ struct afe_ctl { void *apr; atomic_t state; atomic_t status; + atomic_t clk_state; + atomic_t clk_status; wait_queue_head_t wait[AFE_MAX_PORTS]; wait_queue_head_t wait_wakeup; + wait_queue_head_t clk_wait; struct task_struct *task; wait_queue_head_t lpass_core_hw_wait; uint32_t lpass_hw_core_client_hdl[AFE_LPASS_CORE_HW_VOTE_MAX]; @@ -154,6 +158,7 @@ struct afe_ctl { struct aanc_data aanc_info; struct mutex afe_cmd_lock; struct mutex afe_apr_lock; + struct mutex afe_clk_lock; int set_custom_topology; int dev_acdb_id[AFE_MAX_PORTS]; routing_cb rt_cb; @@ -680,8 +685,8 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) if (data->token < AFE_LPASS_CORE_HW_VOTE_MAX) this_afe.lpass_hw_core_client_hdl[data->token] = payload[0]; - atomic_set(&this_afe.state, 0); - atomic_set(&this_afe.status, 0); + atomic_set(&this_afe.clk_state, 0); + atomic_set(&this_afe.clk_status, 0); wake_up(&this_afe.lpass_core_hw_wait); } else if (data->payload_size) { uint32_t *payload; @@ -720,11 +725,16 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) case AFE_SVC_CMD_SET_PARAM: case AFE_SVC_CMD_SET_PARAM_V2: case AFE_PORT_CMD_MOD_EVENT_CFG: - atomic_set(&this_afe.state, 0); - if (afe_token_is_valid(data->token)) - wake_up(&this_afe.wait[data->token]); - else - return -EINVAL; + if(data->token == AFE_CLK_TOKEN) { + atomic_set(&this_afe.clk_state, 0); + wake_up(&this_afe.clk_wait); + } else { + atomic_set(&this_afe.state, 0); + if (afe_token_is_valid(data->token)) + wake_up(&this_afe.wait[data->token]); + else + return -EINVAL; + } break; case AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER: break; @@ -770,7 +780,7 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) break; case AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST: case AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST: - atomic_set(&this_afe.state, 0); + atomic_set(&this_afe.clk_state, 0); wake_up(&this_afe.lpass_core_hw_wait); break; case AFE_SVC_CMD_EVENT_CFG: @@ -1090,6 +1100,46 @@ static int afe_apr_send_pkt(void *data, wait_queue_head_t *wait) mutex_unlock(&this_afe.afe_apr_lock); return ret; } +/* + * afe_apr_send_clk_pkt : returns 0 on success, negative otherwise. + */ +static int afe_apr_send_clk_pkt(void *data, wait_queue_head_t *wait) +{ + int ret; + + if (wait) + atomic_set(&this_afe.clk_state, 1); + atomic_set(&this_afe.clk_status, 0); + ret = apr_send_pkt(this_afe.apr, data); + if (ret > 0) { + if (wait) { + ret = wait_event_timeout(*wait, + (atomic_read(&this_afe.clk_state) == 0), + msecs_to_jiffies(2 * TIMEOUT_MS)); + if (!ret) { + pr_err("%s: timeout\n", __func__); + ret = -ETIMEDOUT; + } else if (atomic_read(&this_afe.clk_status) > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(atomic_read( + &this_afe.clk_status))); + ret = adsp_err_get_lnx_err_code( + atomic_read(&this_afe.clk_status)); + } else { + ret = 0; + } + } else { + ret = 0; + } + } else if (ret == 0) { + pr_err("%s: packet not transmitted\n", __func__); + /* apr_send_pkt can return 0 when nothing is transmitted */ + ret = -EINVAL; + } + + pr_debug("%s: leave %d\n", __func__, ret); + return ret; +} /* This function shouldn't be called directly. Instead call q6afe_set_params. */ static int q6afe_set_params_v2(u16 port_id, int index, @@ -1486,6 +1536,122 @@ static int q6afe_svc_set_params_v2(int index, struct mem_mapping_hdr *mem_hdr, return rc; } +/* + * This function shouldn't be called directly. Instead call + * q6afe_clk_set_params. + */ +static int q6afe_clk_set_params_v1(int index, struct mem_mapping_hdr *mem_hdr, + u8 *packed_param_data, u32 packed_data_size) +{ + struct afe_svc_cmd_set_param_v1 *svc_set_param = NULL; + uint32_t size = sizeof(struct afe_svc_cmd_set_param_v1); + int rc = 0; + + if (packed_param_data != NULL) + size += packed_data_size; + svc_set_param = kzalloc(size, GFP_KERNEL); + if (svc_set_param == NULL) + return -ENOMEM; + + svc_set_param->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + svc_set_param->apr_hdr.pkt_size = size; + svc_set_param->apr_hdr.src_port = 0; + svc_set_param->apr_hdr.dest_port = 0; + svc_set_param->apr_hdr.token = AFE_CLK_TOKEN; + svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM; + svc_set_param->payload_size = packed_data_size; + + if (mem_hdr != NULL) { + /* Out of band case. */ + svc_set_param->mem_hdr = *mem_hdr; + } else if (packed_param_data != NULL) { + /* In band case. */ + memcpy(&svc_set_param->param_data, packed_param_data, + packed_data_size); + } else { + pr_err("%s: Both memory header and param data are NULL\n", + __func__); + rc = -EINVAL; + goto done; + } + + rc = afe_apr_send_clk_pkt(svc_set_param, &this_afe.clk_wait); +done: + kfree(svc_set_param); + return rc; +} + +/* + * This function shouldn't be called directly. Instead call + * q6afe_clk_set_params. + */ +static int q6afe_clk_set_params_v2(int index, struct mem_mapping_hdr *mem_hdr, + u8 *packed_param_data, u32 packed_data_size) +{ + struct afe_svc_cmd_set_param_v2 *svc_set_param = NULL; + uint16_t size = sizeof(struct afe_svc_cmd_set_param_v2); + int rc = 0; + + if (packed_param_data != NULL) + size += packed_data_size; + svc_set_param = kzalloc(size, GFP_KERNEL); + if (svc_set_param == NULL) + return -ENOMEM; + + svc_set_param->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + svc_set_param->apr_hdr.pkt_size = size; + svc_set_param->apr_hdr.src_port = 0; + svc_set_param->apr_hdr.dest_port = 0; + svc_set_param->apr_hdr.token = AFE_CLK_TOKEN; + svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM_V2; + svc_set_param->payload_size = packed_data_size; + + if (mem_hdr != NULL) { + /* Out of band case. */ + svc_set_param->mem_hdr = *mem_hdr; + } else if (packed_param_data != NULL) { + /* In band case. */ + memcpy(&svc_set_param->param_data, packed_param_data, + packed_data_size); + } else { + pr_err("%s: Both memory header and param data are NULL\n", + __func__); + rc = -EINVAL; + goto done; + } + + rc = afe_apr_send_clk_pkt(svc_set_param, &this_afe.clk_wait); +done: + kfree(svc_set_param); + return rc; +} + +static int q6afe_clk_set_params(int index, struct mem_mapping_hdr *mem_hdr, + u8 *packed_param_data, u32 packed_data_size, + bool is_iid_supported) +{ + int ret; + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + if (is_iid_supported) + return q6afe_clk_set_params_v2(index, mem_hdr, + packed_param_data, + packed_data_size); + else + return q6afe_clk_set_params_v1(index, mem_hdr, + packed_param_data, + packed_data_size); +} + static int q6afe_svc_set_params(int index, struct mem_mapping_hdr *mem_hdr, u8 *packed_param_data, u32 packed_data_size, bool is_iid_supported) @@ -1530,9 +1696,12 @@ static int q6afe_svc_pack_and_set_param_in_band(int index, __func__, ret); goto done; } - - ret = q6afe_svc_set_params(index, NULL, packed_param_data, - packed_data_size, is_iid_supported); + if (param_hdr.module_id == AFE_MODULE_CLOCK_SET) + ret = q6afe_clk_set_params(index, NULL, packed_param_data, + packed_data_size, is_iid_supported); + else + ret = q6afe_svc_set_params(index, NULL, packed_param_data, + packed_data_size, is_iid_supported); done: kfree(packed_param_data); @@ -7628,13 +7797,7 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg) memset(¶m_hdr, 0, sizeof(param_hdr)); - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err_ratelimited("%s: Q6 interface prepare failed %d\n", __func__, ret); - return ret; - } - - mutex_lock(&this_afe.afe_cmd_lock); + mutex_lock(&this_afe.afe_clk_lock); param_hdr.module_id = AFE_MODULE_CLOCK_SET; param_hdr.instance_id = INSTANCE_ID_0; param_hdr.param_id = AFE_PARAM_ID_CLOCK_SET; @@ -7654,7 +7817,7 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg) pr_err_ratelimited("%s: AFE clk cfg failed with ret %d\n", __func__, ret); - mutex_unlock(&this_afe.afe_cmd_lock); + mutex_unlock(&this_afe.afe_clk_lock); return ret; } EXPORT_SYMBOL(afe_set_lpass_clk_cfg); @@ -9001,6 +9164,8 @@ int __init afe_init(void) atomic_set(&this_afe.state, 0); atomic_set(&this_afe.status, 0); + atomic_set(&this_afe.clk_state, 0); + atomic_set(&this_afe.clk_status, 0); atomic_set(&this_afe.mem_map_cal_index, -1); this_afe.apr = NULL; this_afe.dtmf_gen_rx_portid = -1; @@ -9014,6 +9179,7 @@ int __init afe_init(void) this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; mutex_init(&this_afe.afe_cmd_lock); mutex_init(&this_afe.afe_apr_lock); + mutex_init(&this_afe.afe_clk_lock); for (i = 0; i < AFE_MAX_PORTS; i++) { this_afe.afe_cal_mode[i] = AFE_CAL_MODE_DEFAULT; this_afe.afe_sample_rates[i] = 0; @@ -9025,6 +9191,7 @@ int __init afe_init(void) } init_waitqueue_head(&this_afe.wait_wakeup); init_waitqueue_head(&this_afe.lpass_core_hw_wait); + init_waitqueue_head(&this_afe.clk_wait); wakeup_source_init(&wl.ws, "spkr-prot"); ret = afe_init_cal_data(); if (ret) @@ -9069,6 +9236,7 @@ void afe_exit(void) config_debug_fs_exit(); mutex_destroy(&this_afe.afe_cmd_lock); mutex_destroy(&this_afe.afe_apr_lock); + mutex_destroy(&this_afe.afe_clk_lock); wakeup_source_trash(&wl.ws); } @@ -9132,7 +9300,7 @@ int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name, return ret; } - mutex_lock(&this_afe.afe_cmd_lock); + mutex_lock(&this_afe.afe_clk_lock); memset(cmd_ptr, 0, sizeof(hw_vote_cfg)); @@ -9152,15 +9320,15 @@ int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name, __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id); *client_handle = 0; - ret = afe_apr_send_pkt((uint32_t *) cmd_ptr, - &this_afe.lpass_core_hw_wait); + + ret = afe_apr_send_clk_pkt((uint32_t *)cmd_ptr, + &this_afe.lpass_core_hw_wait); if (ret == 0) { *client_handle = this_afe.lpass_hw_core_client_hdl[hw_block_id]; pr_debug("%s: lpass_hw_core_client_hdl %d\n", __func__, this_afe.lpass_hw_core_client_hdl[hw_block_id]); } - - mutex_unlock(&this_afe.afe_cmd_lock); + mutex_unlock(&this_afe.afe_clk_lock); return ret; } EXPORT_SYMBOL(afe_vote_lpass_core_hw); @@ -9186,7 +9354,7 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle) return ret; } - mutex_lock(&this_afe.afe_cmd_lock); + mutex_lock(&this_afe.afe_clk_lock); if (!this_afe.lpass_hw_core_client_hdl[hw_block_id]) { pr_debug("%s: SSR in progress, return\n", __func__); @@ -9215,10 +9383,10 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle) goto done; } - ret = afe_apr_send_pkt((uint32_t *) cmd_ptr, - &this_afe.lpass_core_hw_wait); + ret = afe_apr_send_clk_pkt((uint32_t *)cmd_ptr, + &this_afe.lpass_core_hw_wait); done: - mutex_unlock(&this_afe.afe_cmd_lock); + mutex_unlock(&this_afe.afe_clk_lock); return ret; } EXPORT_SYMBOL(afe_unvote_lpass_core_hw); -- GitLab From d50a581e04800f6f365b879a95bb237092c6b7ad Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 21 Nov 2019 07:24:42 +0530 Subject: [PATCH 1336/1645] ASoC: bolero: Add concurrency support on audio capture path During voice activation and audio capture concurrency usecase, there is no common reference count for DMIC clock enablement, results into mute when one usecase tears down. Change enables a common reference count in bolero codec driver between voice activation usecase and audio capture usecase to avoid mute during VA and audio capture concurrency. Change-Id: I424c941178d7e9ff91288a50ba27605b2b9d3abe Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/bolero-cdc.c | 128 ++++++++++++++++++++++++++++++++ asoc/codecs/bolero/bolero-cdc.h | 27 +++++++ asoc/codecs/bolero/internal.h | 8 ++ asoc/codecs/bolero/tx-macro.c | 71 ++++-------------- asoc/codecs/bolero/va-macro.c | 81 +++++--------------- 5 files changed, 199 insertions(+), 116 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index fb182a266ac4..52e155291ef3 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -470,6 +470,129 @@ void bolero_unregister_res_clk(struct device *dev) } EXPORT_SYMBOL(bolero_unregister_res_clk); +static u8 bolero_dmic_clk_div_get(struct snd_soc_component *component, + int mode) +{ + struct bolero_priv* priv = snd_soc_component_get_drvdata(component); + int macro = (mode ? VA_MACRO : TX_MACRO); + int ret = 0; + + if (priv->macro_params[macro].clk_div_get) { + ret = priv->macro_params[macro].clk_div_get(component); + if (ret > 0) + return ret; + } + + return 1; +} + +int bolero_dmic_clk_enable(struct snd_soc_component *component, + u32 dmic, u32 tx_mode, bool enable) +{ + struct bolero_priv* priv = snd_soc_component_get_drvdata(component); + u8 dmic_clk_en = 0x01; + u16 dmic_clk_reg = 0; + s32 *dmic_clk_cnt = NULL; + u8 *dmic_clk_div = NULL; + u8 freq_change_mask = 0; + u8 clk_div = 0; + + dev_dbg(component->dev, "%s: enable: %d, tx_mode:%d, dmic: %d\n", + __func__, enable, tx_mode, dmic); + + switch (dmic) { + case 0: + case 1: + dmic_clk_cnt = &(priv->dmic_0_1_clk_cnt); + dmic_clk_div = &(priv->dmic_0_1_clk_div); + dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL; + freq_change_mask = 0x01; + break; + case 2: + case 3: + dmic_clk_cnt = &(priv->dmic_2_3_clk_cnt); + dmic_clk_div = &(priv->dmic_2_3_clk_div); + dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL; + freq_change_mask = 0x02; + break; + case 4: + case 5: + dmic_clk_cnt = &(priv->dmic_4_5_clk_cnt); + dmic_clk_div = &(priv->dmic_4_5_clk_div); + dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL; + freq_change_mask = 0x04; + break; + case 6: + case 7: + dmic_clk_cnt = &(priv->dmic_6_7_clk_cnt); + dmic_clk_div = &(priv->dmic_6_7_clk_div); + dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL; + freq_change_mask = 0x08; + break; + default: + dev_err(component->dev, "%s: Invalid DMIC Selection\n", + __func__); + return -EINVAL; + } + dev_dbg(component->dev, "%s: DMIC%d dmic_clk_cnt %d\n", + __func__, dmic, *dmic_clk_cnt); + if (enable) { + clk_div = bolero_dmic_clk_div_get(component, tx_mode); + (*dmic_clk_cnt)++; + if (*dmic_clk_cnt == 1) { + snd_soc_component_update_bits(component, + BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, + 0x80, 0x00); + snd_soc_component_update_bits(component, dmic_clk_reg, + 0x0E, clk_div << 0x1); + snd_soc_component_update_bits(component, dmic_clk_reg, + dmic_clk_en, dmic_clk_en); + } else { + if (*dmic_clk_div > clk_div) { + snd_soc_component_update_bits(component, + BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, + freq_change_mask, freq_change_mask); + snd_soc_component_update_bits(component, dmic_clk_reg, + 0x0E, clk_div << 0x1); + snd_soc_component_update_bits(component, + BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, + freq_change_mask, 0x00); + } else { + clk_div = *dmic_clk_div; + } + } + *dmic_clk_div = clk_div; + } else { + (*dmic_clk_cnt)--; + if (*dmic_clk_cnt == 0) { + snd_soc_component_update_bits(component, dmic_clk_reg, + dmic_clk_en, 0); + clk_div = 0; + snd_soc_component_update_bits(component, dmic_clk_reg, + 0x0E, clk_div << 0x1); + } else { + clk_div = bolero_dmic_clk_div_get(component, tx_mode); + if (*dmic_clk_div > clk_div) { + clk_div = bolero_dmic_clk_div_get(component, !tx_mode); + snd_soc_component_update_bits(component, + BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, + freq_change_mask, freq_change_mask); + snd_soc_component_update_bits(component, dmic_clk_reg, + 0x0E, clk_div << 0x1); + snd_soc_component_update_bits(component, + BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, + freq_change_mask, 0x00); + } else { + clk_div = *dmic_clk_div; + } + } + *dmic_clk_div = clk_div; + } + + return 0; +} +EXPORT_SYMBOL(bolero_dmic_clk_enable); + /** * bolero_register_macro - Registers macro to bolero * @@ -518,6 +641,9 @@ int bolero_register_macro(struct device *dev, u16 macro_id, priv->macro_params[macro_id].reg_evt_listener = ops->reg_evt_listener; } + if (macro_id == TX_MACRO || macro_id == VA_MACRO) + priv->macro_params[macro_id].clk_div_get = ops->clk_div_get; + if (priv->version == BOLERO_VERSION_2_1) { if (macro_id == VA_MACRO) priv->macro_params[macro_id].reg_wake_irq = @@ -588,6 +714,8 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) priv->macro_params[macro_id].clk_switch = NULL; priv->macro_params[macro_id].reg_evt_listener = NULL; } + if (macro_id == TX_MACRO || macro_id == VA_MACRO) + priv->macro_params[macro_id].clk_div_get = NULL; priv->num_dais -= priv->macro_params[macro_id].num_dais; priv->num_macros_registered--; diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 2ec4617447bd..ed437dd4318e 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -50,6 +50,24 @@ enum { BOLERO_MACRO_EVT_BCS_CLK_OFF }; +enum { + DMIC_TX = 0, + DMIC_VA = 1, + +}; + +enum { + DMIC0 = 0, + DMIC1, + DMIC2, + DMIC3, + DMIC4, + DMIC5, + DMIC6, + DMIC7, + DMIC_MAX +}; + struct macro_ops { int (*init)(struct snd_soc_component *component); int (*exit)(struct snd_soc_component *component); @@ -63,6 +81,7 @@ struct macro_ops { int (*set_port_map)(struct snd_soc_component *component, u32 uc, u32 size, void *data); int (*clk_switch)(struct snd_soc_component *component); + int (*clk_div_get)(struct snd_soc_component *component); int (*reg_evt_listener)(struct snd_soc_component *component, bool en); char __iomem *io_base; u16 clk_id_req; @@ -93,6 +112,8 @@ int bolero_register_event_listener(struct snd_soc_component *component, void bolero_wsa_pa_on(struct device *dev); bool bolero_check_core_votes(struct device *dev); int bolero_get_version(struct device *dev); +int bolero_dmic_clk_enable(struct snd_soc_component *component, + u32 dmic, u32 tx_mode, bool enable); #else static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb) { @@ -177,5 +198,11 @@ static int bolero_get_version(struct device *dev) { return 0; } + +static int bolero_dmic_clk_enable(struct snd_soc_component *component, + u32 dmic, u32 tx_mode, bool enable) +{ + return 0; +} #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index d18568b0eb16..5b3dd4978024 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -82,6 +82,14 @@ struct bolero_priv { struct blocking_notifier_head notifier; struct device *clk_dev; rsc_clk_cb_t rsc_clk_cb; + s32 dmic_0_1_clk_cnt; + s32 dmic_2_3_clk_cnt; + s32 dmic_4_5_clk_cnt; + s32 dmic_6_7_clk_cnt; + u8 dmic_0_1_clk_div; + u8 dmic_2_3_clk_div; + u8 dmic_4_5_clk_div; + u8 dmic_6_7_clk_div; }; struct regmap *bolero_regmap_init(struct device *dev, diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 3295aacd23ba..356132b564a0 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -155,10 +155,6 @@ struct tx_macro_priv { struct work_struct tx_macro_add_child_devices_work; struct hpf_work tx_hpf_work[NUM_DECIMATORS]; struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS]; - s32 dmic_0_1_clk_cnt; - s32 dmic_2_3_clk_cnt; - s32 dmic_4_5_clk_cnt; - s32 dmic_6_7_clk_cnt; u16 dmic_clk_div; u32 version; u32 is_used_tx_swr_gpio; @@ -754,17 +750,9 @@ static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w, { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - u8 dmic_clk_en = 0x01; - u16 dmic_clk_reg = 0; - s32 *dmic_clk_cnt = NULL; unsigned int dmic = 0; int ret = 0; char *wname = NULL; - struct device *tx_dev = NULL; - struct tx_macro_priv *tx_priv = NULL; - - if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) - return -EINVAL; wname = strpbrk(w->name, "01234567"); if (!wname) { @@ -779,54 +767,15 @@ static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w, return -EINVAL; } - switch (dmic) { - case 0: - case 1: - dmic_clk_cnt = &(tx_priv->dmic_0_1_clk_cnt); - dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL; - break; - case 2: - case 3: - dmic_clk_cnt = &(tx_priv->dmic_2_3_clk_cnt); - dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL; - break; - case 4: - case 5: - dmic_clk_cnt = &(tx_priv->dmic_4_5_clk_cnt); - dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL; - break; - case 6: - case 7: - dmic_clk_cnt = &(tx_priv->dmic_6_7_clk_cnt); - dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL; - break; - default: - dev_err(component->dev, "%s: Invalid DMIC Selection\n", - __func__); - return -EINVAL; - } - dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", - __func__, event, dmic, *dmic_clk_cnt); + dev_dbg(component->dev, "%s: event %d DMIC%d\n", + __func__, event, dmic); switch (event) { case SND_SOC_DAPM_PRE_PMU: - (*dmic_clk_cnt)++; - if (*dmic_clk_cnt == 1) { - snd_soc_component_update_bits(component, - BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, - 0x80, 0x00); - - snd_soc_component_update_bits(component, dmic_clk_reg, - 0x0E, tx_priv->dmic_clk_div << 0x1); - snd_soc_component_update_bits(component, dmic_clk_reg, - dmic_clk_en, dmic_clk_en); - } + bolero_dmic_clk_enable(component, dmic, DMIC_TX, true); break; case SND_SOC_DAPM_POST_PMD: - (*dmic_clk_cnt)--; - if (*dmic_clk_cnt == 0) - snd_soc_component_update_bits(component, dmic_clk_reg, - dmic_clk_en, 0); + bolero_dmic_clk_enable(component, dmic, DMIC_TX, false); break; } @@ -2493,6 +2442,17 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, return ret; } +static int tx_macro_clk_div_get(struct snd_soc_component *component) +{ + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + return tx_priv->dmic_clk_div; +} + static int tx_macro_clk_switch(struct snd_soc_component *component) { struct device *tx_dev = NULL; @@ -3014,6 +2974,7 @@ static void tx_macro_init_ops(struct macro_ops *ops, ops->event_handler = tx_macro_event_handler; ops->reg_wake_irq = tx_macro_reg_wake_irq; ops->set_port_map = tx_macro_set_port_map; + ops->clk_div_get = tx_macro_clk_div_get; ops->clk_switch = tx_macro_clk_switch; ops->reg_evt_listener = tx_macro_register_event_listener; } diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 26475e600aa2..f03561e52a9f 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -140,10 +140,6 @@ struct va_macro_priv { struct va_mute_work va_mute_dwork[VA_MACRO_NUM_DECIMATORS]; unsigned long active_ch_mask[VA_MACRO_MAX_DAIS]; unsigned long active_ch_cnt[VA_MACRO_MAX_DAIS]; - s32 dmic_0_1_clk_cnt; - s32 dmic_2_3_clk_cnt; - s32 dmic_4_5_clk_cnt; - s32 dmic_6_7_clk_cnt; u16 dmic_clk_div; u16 va_mclk_users; int swr_clk_users; @@ -194,6 +190,17 @@ static bool va_macro_get_data(struct snd_soc_component *component, return true; } +static int va_macro_clk_div_get(struct snd_soc_component *component) +{ + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) + return -EINVAL; + + return va_priv->dmic_clk_div; +} + static int va_macro_mclk_enable(struct va_macro_priv *va_priv, bool mclk_enable, bool dapm) { @@ -953,81 +960,32 @@ static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w, { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - u8 dmic_clk_en = 0x01; - u16 dmic_clk_reg; - s32 *dmic_clk_cnt; - unsigned int dmic; - int ret; + unsigned int dmic = 0; + int ret = 0; char *wname; - struct device *va_dev = NULL; - struct va_macro_priv *va_priv = NULL; - - if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) - return -EINVAL; wname = strpbrk(w->name, "01234567"); if (!wname) { - dev_err(va_dev, "%s: widget not found\n", __func__); + dev_err(component->dev, "%s: widget not found\n", __func__); return -EINVAL; } ret = kstrtouint(wname, 10, &dmic); if (ret < 0) { - dev_err(va_dev, "%s: Invalid DMIC line on the codec\n", + dev_err(component->dev, "%s: Invalid DMIC line on the codec\n", __func__); return -EINVAL; } - switch (dmic) { - case 0: - case 1: - dmic_clk_cnt = &(va_priv->dmic_0_1_clk_cnt); - dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL; - break; - case 2: - case 3: - dmic_clk_cnt = &(va_priv->dmic_2_3_clk_cnt); - dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL; - break; - case 4: - case 5: - dmic_clk_cnt = &(va_priv->dmic_4_5_clk_cnt); - dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL; - break; - case 6: - case 7: - dmic_clk_cnt = &(va_priv->dmic_6_7_clk_cnt); - dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL; - break; - default: - dev_err(va_dev, "%s: Invalid DMIC Selection\n", - __func__); - return -EINVAL; - } - dev_dbg(va_dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", - __func__, event, dmic, *dmic_clk_cnt); + dev_dbg(component->dev, "%s: event %d DMIC%d\n", + __func__, event, dmic); switch (event) { case SND_SOC_DAPM_PRE_PMU: - (*dmic_clk_cnt)++; - if (*dmic_clk_cnt == 1) { - snd_soc_component_update_bits(component, - BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, - 0x80, 0x00); - snd_soc_component_update_bits(component, dmic_clk_reg, - VA_MACRO_TX_DMIC_CLK_DIV_MASK, - va_priv->dmic_clk_div << - VA_MACRO_TX_DMIC_CLK_DIV_SHFT); - snd_soc_component_update_bits(component, dmic_clk_reg, - dmic_clk_en, dmic_clk_en); - } + bolero_dmic_clk_enable(component, dmic, DMIC_VA, true); break; case SND_SOC_DAPM_POST_PMD: - (*dmic_clk_cnt)--; - if (*dmic_clk_cnt == 0) { - snd_soc_component_update_bits(component, dmic_clk_reg, - dmic_clk_en, 0); - } + bolero_dmic_clk_enable(component, dmic, DMIC_VA, false); break; } @@ -2784,6 +2742,7 @@ static void va_macro_init_ops(struct macro_ops *ops, ops->event_handler = va_macro_event_handler; ops->set_port_map = va_macro_set_port_map; ops->reg_wake_irq = va_macro_reg_wake_irq; + ops->clk_div_get = va_macro_clk_div_get; } static int va_macro_probe(struct platform_device *pdev) -- GitLab From 26803c88f685d8ae32976d28301f0b4a33bbb3ef Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Wed, 11 Dec 2019 15:40:03 -0800 Subject: [PATCH 1337/1645] ASoC: msm: update QUAT/QUIN TDM slot mappings for A2B Update QUAT and QUIN TDM slot mappings for extended usecases over A2B codec. QUAT TDM RX 0 -> DAC1 (8 CH) QUAT TDM RX 1 -> DAC2 (8 CH) QUAT TDM TX 0 -> ADC1 and ADC2 (16 CH) QUIN TDM RX 0 -> DAC1 and DAC2 (16 CH) QUIN TDM TX 0 -> ADC1 and ADC2 (16 CH) Change-Id: I0d13ab3d44a05716a043189e6eb6c809dfff6d9d Signed-off-by: Derek Chen --- asoc/sa6155.c | 38 +++++++++++++++++++------------------- asoc/sa8155.c | 36 +++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/asoc/sa6155.c b/asoc/sa6155.c index 73b95b2cef8b..3f32c8869c35 100644 --- a/asoc/sa6155.c +++ b/asoc/sa6155.c @@ -213,7 +213,7 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { }, { /* QUAT TDM */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* RX_1 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ @@ -222,10 +222,10 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ }, { /* QUIN TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ @@ -276,9 +276,9 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ }, { /* QUIN TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* TX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 4}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_2 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ @@ -415,20 +415,20 @@ static unsigned int tdm_rx_slot_offset {0xFFFF}, /* not used */ }, {/* QUAT TDM */ - {0, 4, 8, 12, 16, 20, 24, 28, 0xFFFF},/*AMP OUT*/ - {0xFFFF}, /* not used */ + {0, 8, 16, 24, 32, 40, 48, 56, 0xFFFF}, /*8 CH SPKR*/ + {4, 12, 20, 28, 36, 44, 52, 60, 0xFFFF}, /*8 CH SPKR*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {28,0xFFFF}, + {60,0xFFFF}, }, {/* QUIN TDM */ - {0, 4, 0xFFFF},/*STEREO SPKR1*/ - {8, 12, 0xFFFF},/*STEREO SPKR2*/ - {16, 20, 0xFFFF},/*STEREO SPKR3*/ - {24, 28, 0xFFFF},/*STEREO SPKR4*/ + {0, 4, 8, 12, 16, 20, 0xFFFF}, + {24, 0xFFFF}, + {28, 0xFFFF}, + {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -480,14 +480,14 @@ static unsigned int tdm_tx_slot_offset {60,0xFFFF}, }, {/* QUIN TDM */ - {0, 4, 8, 12, 16, 20, 0xFFFF},/*EC/ANC REF*/ - {0xFFFF}, /* not used */ - {0xFFFF}, /* not used */ + {0, 4, 8, 12, 0xFFFF}, + {16, 20, 0xFFFF}, + {24, 28, 0xFFFF}, {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {20, 0xFFFF}, + {28, 0xFFFF}, } }; diff --git a/asoc/sa8155.c b/asoc/sa8155.c index 228f43088604..ba686e674a26 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -205,7 +205,7 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { }, { /* QUAT TDM */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* RX_1 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ @@ -214,10 +214,10 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ }, { /* QUIN TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 16}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ @@ -268,7 +268,7 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ }, { /* QUIN TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 16}, /* TX_0 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ @@ -407,24 +407,25 @@ static unsigned int tdm_rx_slot_offset {0xFFFF}, /* not used */ }, {/* QUAT TDM */ - {0, 4, 8, 12, 16, 20, 24, 28, 0xFFFF},/*AMP OUT*/ - {0xFFFF}, /* not used */ + {0, 8, 16, 24, 32, 40, 48, 56, 0xFFFF}, /*8 CH SPKR*/ + {4, 12, 20, 28, 36, 44, 52, 60, 0xFFFF}, /*8 CH SPKR*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {28,0xFFFF}, + {60,0xFFFF}, }, {/* QUIN TDM */ - {0, 4, 0xFFFF},/*STEREO SPKR1*/ - {8, 12, 0xFFFF},/*STEREO SPKR2*/ - {16, 20, 0xFFFF},/*STEREO SPKR3*/ - {24, 28, 0xFFFF},/*STEREO SPKR4*/ + {0, 8, 16, 24, 32, 40, 48, 56, + 4, 12, 20, 28, 36, 44, 52, 60, 0xFFFF}, /*16 CH SPKR*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {60, 0xFFFF}, } }; @@ -462,7 +463,7 @@ static unsigned int tdm_tx_slot_offset }, {/* QUAT TDM */ {0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*MIC ARR*/ + 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*16 CH MIC ARR1*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -472,14 +473,15 @@ static unsigned int tdm_tx_slot_offset {60,0xFFFF}, }, {/* QUIN TDM */ - {0, 4, 8, 12, 16, 20, 0xFFFF},/*EC/ANC REF*/ + {0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*16 CH MIC ARR2*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ - {20, 0xFFFF}, + {60, 0xFFFF}, } }; -- GitLab From fc3adb04c498fe7055091c5e8bf7bf0bbf17f45b Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sun, 24 Nov 2019 10:14:21 +0530 Subject: [PATCH 1338/1645] ASoC: bolero: Use TX MCLK for non-island mode usecase Use TX MCLK for non-island mode usecase. Change-Id: Iff8f8efd3e83b09e5323abe19aabddb8c4de1964 Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/bolero-cdc.c | 36 +++++++++++++++++++++++++++++++++ asoc/codecs/bolero/bolero-cdc.h | 6 ++++++ asoc/codecs/bolero/tx-macro.c | 15 +++++++++++++- asoc/codecs/bolero/va-macro.c | 12 +++++++++-- 4 files changed, 66 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 52e155291ef3..460a725488e1 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -640,6 +640,7 @@ int bolero_register_macro(struct device *dev, u16 macro_id, priv->macro_params[macro_id].clk_switch = ops->clk_switch; priv->macro_params[macro_id].reg_evt_listener = ops->reg_evt_listener; + priv->macro_params[macro_id].clk_enable = ops->clk_enable; } if (macro_id == TX_MACRO || macro_id == VA_MACRO) priv->macro_params[macro_id].clk_div_get = ops->clk_div_get; @@ -713,6 +714,7 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) priv->macro_params[macro_id].reg_wake_irq = NULL; priv->macro_params[macro_id].clk_switch = NULL; priv->macro_params[macro_id].reg_evt_listener = NULL; + priv->macro_params[macro_id].clk_enable = NULL; } if (macro_id == TX_MACRO || macro_id == VA_MACRO) priv->macro_params[macro_id].clk_div_get = NULL; @@ -1015,6 +1017,40 @@ int bolero_tx_clk_switch(struct snd_soc_component *component) } EXPORT_SYMBOL(bolero_tx_clk_switch); +/** + * bolero_tx_mclk_enable - Enable/Disable TX Macro mclk + * + * @component: pointer to codec component instance. + * @enable: set true to enable, otherwise false. + * + * Returns 0 on success or -EINVAL on error. + */ +int bolero_tx_mclk_enable(struct snd_soc_component *component, + bool enable) +{ + struct bolero_priv *priv = NULL; + int ret = 0; + + if (!component) + return -EINVAL; + + priv = snd_soc_component_get_drvdata(component); + if (!priv) + return -EINVAL; + + if (!bolero_is_valid_codec_dev(priv->dev)) { + dev_err(component->dev, "%s: invalid codec\n", __func__); + return -EINVAL; + } + + if (priv->macro_params[TX_MACRO].clk_enable) + ret = priv->macro_params[TX_MACRO].clk_enable(component, + enable); + + return ret; +} +EXPORT_SYMBOL(bolero_tx_mclk_enable); + /** * bolero_register_event_listener - Register/Deregister to event listener * diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index ed437dd4318e..2294594c801f 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -83,6 +83,7 @@ struct macro_ops { int (*clk_switch)(struct snd_soc_component *component); int (*clk_div_get)(struct snd_soc_component *component); int (*reg_evt_listener)(struct snd_soc_component *component, bool en); + int (*clk_enable)(struct snd_soc_component *c, bool en); char __iomem *io_base; u16 clk_id_req; u16 default_clk_id; @@ -111,6 +112,7 @@ int bolero_register_event_listener(struct snd_soc_component *component, bool enable); void bolero_wsa_pa_on(struct device *dev); bool bolero_check_core_votes(struct device *dev); +int bolero_tx_mclk_enable(struct snd_soc_component *c, bool enable); int bolero_get_version(struct device *dev); int bolero_dmic_clk_enable(struct snd_soc_component *component, u32 dmic, u32 tx_mode, bool enable); @@ -204,5 +206,9 @@ static int bolero_dmic_clk_enable(struct snd_soc_component *component, { return 0; } +static int bolero_tx_mclk_enable(struct snd_soc_component *c, bool enable) +{ + return 0; +} #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 356132b564a0..f32c43a57ff6 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -275,6 +275,18 @@ static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv, return ret; } +static int __tx_macro_mclk_enable(struct snd_soc_component *component, + bool enable) +{ + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + return tx_macro_mclk_enable(tx_priv, enable); +} + static int tx_macro_va_swr_clk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -2266,7 +2278,7 @@ static int tx_macro_register_event_listener(struct snd_soc_component *component, "%s: priv is null for macro!\n", __func__); return -EINVAL; } - if (tx_priv->swr_ctrl_data) { + if (tx_priv->swr_ctrl_data && !tx_priv->tx_swr_clk_cnt) { if (enable) { ret = swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, @@ -2977,6 +2989,7 @@ static void tx_macro_init_ops(struct macro_ops *ops, ops->clk_div_get = tx_macro_clk_div_get; ops->clk_switch = tx_macro_clk_switch; ops->reg_evt_listener = tx_macro_register_event_listener; + ops->clk_enable = __tx_macro_mclk_enable; } static int tx_macro_probe(struct platform_device *pdev) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index f03561e52a9f..77957d1ba3cb 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -475,12 +475,20 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, true); if (!ret) va_priv->tx_clk_status++; - ret = va_macro_mclk_enable(va_priv, 1, true); + + if (va_priv->lpi_enable) + ret = va_macro_mclk_enable(va_priv, 1, true); + else + ret = bolero_tx_mclk_enable(component, 1); break; case SND_SOC_DAPM_POST_PMD: if (bolero_tx_clk_switch(component)) dev_dbg(va_dev, "%s: clock switch failed\n",__func__); - va_macro_mclk_enable(va_priv, 0, true); + if (va_priv->lpi_enable) + va_macro_mclk_enable(va_priv, 0, true); + else + bolero_tx_mclk_enable(component, 0); + if (va_priv->tx_clk_status > 0) { bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, -- GitLab From 8c50f2f787c6b7fcbef5ac1cea55c0ec39a5cda9 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 5 Dec 2019 01:14:47 +0530 Subject: [PATCH 1339/1645] soc: soundwire: Check for clock source before clock switch Check for soundwire clock source before clock switch to avoid redundant clock switch for the same clock source. Change-Id: I8a7a116cc956f427af677b413928dace5a39a23d Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 13 +++++++++++-- soc/swr-mstr-ctrl.h | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 598b269834a7..edc772dd12e2 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -3074,9 +3074,18 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) * next activity on soundwire will request clock from new clock * source. */ + if (!data) { + dev_err(swrm->dev, "%s: data is NULL for id:%d\n", + __func__, id); + ret = -EINVAL; + break; + } mutex_lock(&swrm->mlock); - if (swrm->state == SWR_MSTR_UP) - swrm_device_suspend(&pdev->dev); + if (swrm->clk_src != *(int *)data) { + if (swrm->state == SWR_MSTR_UP) + swrm_device_suspend(&pdev->dev); + swrm->clk_src = *(int *)data; + } mutex_unlock(&swrm->mlock); break; case SWR_CLK_FREQ: diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 1987e0fdffd1..c404fc6f9664 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -178,6 +178,7 @@ struct swr_mstr_ctrl { u32 swr_irq_wakeup_capable; int hw_core_clk_en; int aud_core_clk_en; + int clk_src; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_swrm_dent; struct dentry *debugfs_peek; -- GitLab From 8d37df9265d0d590228acd319a7ccb72fa40f5ff Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 22 Nov 2019 15:46:11 +0530 Subject: [PATCH 1340/1645] asoc: bengal: Avoid island config to afe for sva disable variant Check SVA disable variant and skip send afe island config. Change-Id: Ida6c32ec042f545291aaeb8e616478b991d923bd Signed-off-by: Laxminath Kasam --- asoc/bengal.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/asoc/bengal.c b/asoc/bengal.c index d60698d3b2ab..cb4f51313ce5 100644 --- a/asoc/bengal.c +++ b/asoc/bengal.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -260,6 +261,7 @@ static u32 mi2s_ebit_clk[MI2S_MAX] = { }; static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; +static bool va_disable; /* Default configuration of TDM channels */ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { @@ -3816,6 +3818,8 @@ static int msm_snd_cdc_dma_startup(struct snd_pcm_substream *substream) case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2: + if (va_disable) + break; ret = bengal_send_island_va_config(dai_link->id); if (ret) pr_err("%s: send island va cfg failed, err: %d\n", @@ -6443,6 +6447,10 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) const char *mbhc_audio_jack_type = NULL; int ret = 0; uint index = 0; + struct nvmem_cell *cell; + size_t len; + u32 *buf; + u32 adsp_var_idx = 0; if (!pdev->dev.of_node) { dev_err(&pdev->dev, @@ -6592,7 +6600,23 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) __func__, ret); is_initial_boot = true; - + /* get adsp variant idx */ + cell = nvmem_cell_get(&pdev->dev, "adsp_variant"); + if (IS_ERR_OR_NULL(cell)) { + dev_dbg(&pdev->dev, "%s: FAILED to get nvmem cell \n", __func__); + goto ret; + } + buf = nvmem_cell_read(cell, &len); + nvmem_cell_put(cell); + if (IS_ERR_OR_NULL(buf) || len <= 0 || len > sizeof(32)) { + dev_dbg(&pdev->dev, "%s: FAILED to read nvmem cell \n", __func__); + goto ret; + } + memcpy(&adsp_var_idx, buf, len); + kfree(buf); + va_disable = adsp_var_idx; + +ret: return 0; err: devm_kfree(&pdev->dev, pdata); -- GitLab From 8843c61330301e6d4db2faf95291cc4ccf171d45 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Mon, 16 Dec 2019 17:07:41 -0800 Subject: [PATCH 1341/1645] asoc: msm-lsm-client: abort LAB buffering before stop session and close TX Currently we only set read_abort flag to stop LAB buffering before we call q6lsm_stop_lab. There is a possibility that this step is skipped under certain circumstances. This might cause ADSP crash as a result. Therefore, set flag read_abort before calling q6lsm_stop and q6lsm_close to make sure LAB buffering is stopped before closing a SVA session. Change-Id: I7364c31348f908d8920e32f811745549cf305901 Signed-off-by: Xiaoyu Ye --- asoc/msm-lsm-client.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 5bc897d9e594..450e8b0f854b 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -1457,6 +1457,12 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, prtd->lsm_client->lab_started = false; } } + + if (!atomic_read(&prtd->read_abort)) { + dev_dbg(rtd->dev, + "%s: set read_abort to stop buffering\n", __func__); + atomic_set(&prtd->read_abort, 1); + } rc = q6lsm_stop(prtd->lsm_client, true); if (!rc) dev_dbg(rtd->dev, @@ -2660,6 +2666,12 @@ static int msm_lsm_close(struct snd_pcm_substream *substream) __func__, ret); } } + + if (!atomic_read(&prtd->read_abort)) { + dev_dbg(rtd->dev, + "%s: set read_abort to stop buffering\n", __func__); + atomic_set(&prtd->read_abort, 1); + } ret = q6lsm_stop(prtd->lsm_client, true); if (ret) dev_err(rtd->dev, @@ -2690,6 +2702,11 @@ static int msm_lsm_close(struct snd_pcm_substream *substream) SNDRV_PCM_STREAM_CAPTURE); if (prtd->lsm_client->opened) { + if (!atomic_read(&prtd->read_abort)) { + dev_dbg(rtd->dev, + "%s: set read_abort to stop buffering\n", __func__); + atomic_set(&prtd->read_abort, 1); + } q6lsm_close(prtd->lsm_client); prtd->lsm_client->opened = false; } -- GitLab From 4dcb7b2d162e206b774221e3ab3ff71948ecfee6 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 16 Dec 2019 15:03:41 +0530 Subject: [PATCH 1342/1645] ASoC: wcd938x: Fix headset detection during SSR/PDR Headset is corrected as lineout during SSR/PDR. This is because adc voltage is not measured correctly due to SSR state. Enable flag deinit_in_progress during SSR down to check if device is not reported and disable it after device up. Change-Id: I6fc4fff4149c36ba16aa668a960505504a5d811f Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x.c | 2 ++ asoc/codecs/wcd938x/wcd938x.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index e962067ed22d..cf1f5c9edbc6 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1580,6 +1580,7 @@ static int wcd937x_event_notify(struct notifier_block *block, 0x80, 0x00); break; case BOLERO_WCD_EVT_SSR_DOWN: + wcd937x->mbhc->wcd_mbhc.deinit_in_progress = true; mbhc = &wcd937x->mbhc->wcd_mbhc; wcd937x_mbhc_ssr_down(wcd937x->mbhc, component); wcd937x_reset_low(wcd937x->dev); @@ -1603,6 +1604,7 @@ static int wcd937x_event_notify(struct notifier_block *block, } else { wcd937x_mbhc_hs_detect(component, mbhc->mbhc_cfg); } + wcd937x->mbhc->wcd_mbhc.deinit_in_progress = false; break; default: dev_err(component->dev, "%s: invalid event %d\n", __func__, diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 3db8fc5a9733..aa62a469cf6b 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1903,6 +1903,7 @@ static int wcd938x_event_notify(struct notifier_block *block, break; case BOLERO_WCD_EVT_SSR_DOWN: wcd938x->dev_up = false; + wcd938x->mbhc->wcd_mbhc.deinit_in_progress = true; mbhc = &wcd938x->mbhc->wcd_mbhc; wcd938x_mbhc_ssr_down(wcd938x->mbhc, component); wcd938x_reset_low(wcd938x->dev); @@ -1927,6 +1928,7 @@ static int wcd938x_event_notify(struct notifier_block *block, } else { wcd938x_mbhc_hs_detect(component, mbhc->mbhc_cfg); } + wcd938x->mbhc->wcd_mbhc.deinit_in_progress = false; wcd938x->dev_up = true; break; case BOLERO_WCD_EVT_CLK_NOTIFY: -- GitLab From 793902c22a9b18957834441512624fb1f0b6a4ac Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 11 Dec 2019 18:16:52 +0530 Subject: [PATCH 1343/1645] asoc: bolero: Update mask of wsa macro Update mask of wsa macro to apply sample rate as per config send during hw_params at powerup. Change-Id: Icf9b40fecf655c06cc60d56ac31808e886f8a49d Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/wsa-macro.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 03bea4e0e964..38c075f4add0 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -41,7 +41,7 @@ #define NUM_INTERPOLATORS 2 #define WSA_MACRO_MUX_INP_SHFT 0x3 -#define WSA_MACRO_MUX_INP_MASK1 0x38 +#define WSA_MACRO_MUX_INP_MASK1 0x07 #define WSA_MACRO_MUX_INP_MASK2 0x38 #define WSA_MACRO_MUX_CFG_OFFSET 0x8 #define WSA_MACRO_MUX_CFG1_OFFSET 0x4 @@ -620,10 +620,10 @@ static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, inp0_sel = int_mux_cfg0_val & WSA_MACRO_MUX_INP_MASK1; inp1_sel = (int_mux_cfg0_val >> WSA_MACRO_MUX_INP_SHFT) & - WSA_MACRO_MUX_INP_MASK2; + WSA_MACRO_MUX_INP_MASK1; inp2_sel = (int_mux_cfg1_val >> WSA_MACRO_MUX_INP_SHFT) & - WSA_MACRO_MUX_INP_MASK2; + WSA_MACRO_MUX_INP_MASK1; if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || (inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) { -- GitLab From ec8c9095216d254d70263a0d5e961fb747754f6f Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 17 Dec 2019 13:12:58 +0530 Subject: [PATCH 1344/1645] soc: swr-ctrl: increase num retry count for soundwire link status Increase retry count to check soundwire link status at bootup inorder for probe to succeed. Handle error scenario if soundwire probe fails to cleanup device properly. Change-Id: I4a545530e68221a1f428e05aff3d8a93b1dacf84 Signed-off-by: Laxminath Kasam --- soc/swr-mstr-ctrl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 598b269834a7..6f5979bf3781 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -45,7 +45,7 @@ #define ERR_AUTO_SUSPEND_TIMER_VAL 0x1 #define SWRM_INTERRUPT_STATUS_MASK 0x1FDFD -#define SWRM_LINK_STATUS_RETRY_CNT 0x5 +#define SWRM_LINK_STATUS_RETRY_CNT 100 #define SWRM_ROW_48 48 #define SWRM_ROW_50 50 @@ -2582,7 +2582,7 @@ static int swrm_probe(struct platform_device *pdev) "%s: Error in master Initialization , err %d\n", __func__, ret); mutex_unlock(&swrm->mlock); - goto err_mstr_fail; + goto err_mstr_init_fail; } mutex_unlock(&swrm->mlock); @@ -2627,6 +2627,8 @@ static int swrm_probe(struct platform_device *pdev) return 0; err_irq_wakeup_fail: device_init_wakeup(swrm->dev, false); +err_mstr_init_fail: + swr_unregister_master(&swrm->master); err_mstr_fail: if (swrm->reg_irq) swrm->reg_irq(swrm->handle, swr_mstr_interrupt, -- GitLab From 31a7ef1382bfadededfbf44b0d8dcab2627f0518 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 18 Dec 2019 10:36:29 +0800 Subject: [PATCH 1345/1645] soc: swr-mstr: reset slave pending irq flag before every call Before every slave interrupt handler call, reset slave pending irq flag, so that if irq is halted it does not retain the old value. Change-Id: I2c78500e83eca7864029f58cffa80f8648902fb2 Signed-off-by: Meng Wang --- soc/swr-mstr-ctrl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 598b269834a7..aa15030274d4 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1807,6 +1807,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) continue; if (swr_dev->slave_irq) { do { + swr_dev->slave_irq_pending = 0; handle_nested_irq( irq_find_mapping( swr_dev->slave_irq, 0)); -- GitLab From 52a8fb14a7e615b5091e01e71e7e6a86de124b26 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 12 Dec 2019 20:36:05 +0800 Subject: [PATCH 1346/1645] asoc: bolero: increase tx_mclk_users when enabling VA-MCLK When enabling SVA, tx_mclk_users is not increased. If starting and stopping recording after enabling SVA, tx_mclk will be closed when powering down tx mclk widget. Increase tx_mclk_users when enabling VA_MCLK to avoid mismatch. Change-Id: I02d9400cf7309464bbba1e6749cfcfcf99f5876a Signed-off-by: Meng Wang --- asoc/codecs/bolero/tx-macro.c | 58 ++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 3295aacd23ba..a65590cb7978 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -222,19 +222,19 @@ static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv, mutex_lock(&tx_priv->mclk_lock); if (mclk_enable) { + ret = bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + true); + if (ret < 0) { + dev_err_ratelimited(tx_priv->dev, + "%s: request clock enable failed\n", + __func__); + goto exit; + } + bolero_clk_rsc_fs_gen_request(tx_priv->dev, + true); if (tx_priv->tx_mclk_users == 0) { - ret = bolero_clk_rsc_request_clock(tx_priv->dev, - TX_CORE_CLK, - TX_CORE_CLK, - true); - if (ret < 0) { - dev_err_ratelimited(tx_priv->dev, - "%s: request clock enable failed\n", - __func__); - goto exit; - } - bolero_clk_rsc_fs_gen_request(tx_priv->dev, - true); regcache_mark_dirty(regmap); regcache_sync_region(regmap, TX_START_OFFSET, @@ -265,14 +265,14 @@ static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv, regmap_update_bits(regmap, BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x00); - bolero_clk_rsc_fs_gen_request(tx_priv->dev, - false); - - bolero_clk_rsc_request_clock(tx_priv->dev, - TX_CORE_CLK, - TX_CORE_CLK, - false); } + + bolero_clk_rsc_fs_gen_request(tx_priv->dev, + false); + bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + false); } exit: mutex_unlock(&tx_priv->mclk_lock); @@ -2396,12 +2396,13 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK, 0x01, 0x01); regmap_update_bits(regmap, - BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, + BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x01); regmap_update_bits(regmap, - BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, + BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x01); } + tx_priv->tx_mclk_users++; } if (tx_priv->swr_clk_users == 0) { dev_dbg(tx_priv->dev, "%s: reset_swr: %d\n", @@ -2444,16 +2445,24 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, if (clk_type == TX_MCLK) tx_macro_mclk_enable(tx_priv, 0); if (clk_type == VA_MCLK) { + if (tx_priv->tx_mclk_users <= 0) { + dev_err(tx_priv->dev, "%s: clock already disabled\n", + __func__); + tx_priv->tx_mclk_users = 0; + goto tx_clk; + } + tx_priv->tx_mclk_users--; if (tx_priv->tx_mclk_users == 0) { regmap_update_bits(regmap, - BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, + BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x00); regmap_update_bits(regmap, - BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, + BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x00); } + bolero_clk_rsc_fs_gen_request(tx_priv->dev, - false); + false); ret = bolero_clk_rsc_request_clock(tx_priv->dev, TX_CORE_CLK, VA_CORE_CLK, @@ -2465,6 +2474,7 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, goto done; } } +tx_clk: if (!clk_tx_ret) ret = bolero_clk_rsc_request_clock(tx_priv->dev, TX_CORE_CLK, -- GitLab From aa736b245bcf25c04447c65885cac8d898639abf Mon Sep 17 00:00:00 2001 From: Kunlei Zhang Date: Wed, 18 Dec 2019 16:31:09 +0800 Subject: [PATCH 1347/1645] asoc: add routing control for Multimedia17 with USB TX Add routing control for Multimedia17 with USB TX. Change-Id: Ia05c4fe55ea4dab2b75f4a6da6a54fabdb870f7d Signed-off-by: Kunlei Zhang --- asoc/msm-pcm-routing-v2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 394ef47e8b4e..7bfc3b127a4b 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -14449,6 +14449,10 @@ static const struct snd_kcontrol_new mmul17_mixer_controls[] = { MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul18_mixer_controls[] = { @@ -25246,6 +25250,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia17 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia17 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia17 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia17 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia18 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia18 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia19 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, -- GitLab From c4183a65ab5e108b6be54aaffd907e226c75b80e Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 28 Nov 2019 20:35:44 +0530 Subject: [PATCH 1348/1645] dsp: voice: Remove common lock before sending unmap command Remove common mutex lock before invoking unmap physical memory command to avoid deadlock issue between voice lock and common lock in concurrency use cases. Change-Id: Iaca089f4ff1b6da16e0e59939088fb59516362aa Signed-off-by: Aditya Bavanari --- dsp/q6voice.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index e0491f1c703a..110d8445b9f4 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -1273,7 +1273,6 @@ static int voice_unmap_cal_block(struct voice_data *v, int cal_index) goto unlock; } - mutex_lock(&common.common_lock); result = voice_send_mvm_unmap_memory_physical_cmd( v, cal_block->map_data.q6map_handle); if (result) @@ -1281,7 +1280,6 @@ static int voice_unmap_cal_block(struct voice_data *v, int cal_index) __func__, v->session_id, result); cal_block->map_data.q6map_handle = 0; - mutex_unlock(&common.common_lock); unlock: mutex_unlock(&common.cal_data[cal_index]->lock); done: -- GitLab From 339c411726d185a557dbb940608741ab0f4080a7 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 13 Dec 2019 00:49:16 +0530 Subject: [PATCH 1349/1645] ASoC: bolero: Update TX HPF sequence for AMIC Update TX HPF sequence for AMIC to avoid pop during audio capture. Change-Id: Ib70fc5cd05f67c97977db96487294bfe14f554ad Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/tx-macro.c | 80 +++++++++++++++++-------- asoc/codecs/bolero/va-macro.c | 107 ++++++++++++++++++++++------------ 2 files changed, 127 insertions(+), 60 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 3295aacd23ba..e269498d7621 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -40,12 +40,15 @@ #define TX_MACRO_MCLK_FREQ 9600000 #define TX_MACRO_TX_PATH_OFFSET 0x80 #define TX_MACRO_SWR_MIC_MUX_SEL_MASK 0xF -#define TX_MACRO_ADC_MUX_CFG_OFFSET 0x2 +#define TX_MACRO_ADC_MUX_CFG_OFFSET 0x8 #define TX_MACRO_ADC_MODE_CFG0_SHIFT 1 -#define TX_MACRO_TX_UNMUTE_DELAY_MS 40 +#define TX_MACRO_DMIC_UNMUTE_DELAY_MS 40 +#define TX_MACRO_AMIC_UNMUTE_DELAY_MS 100 +#define TX_MACRO_DMIC_HPF_DELAY_MS 300 +#define TX_MACRO_AMIC_HPF_DELAY_MS 300 -static int tx_unmute_delay = TX_MACRO_TX_UNMUTE_DELAY_MS; +static int tx_unmute_delay = TX_MACRO_DMIC_UNMUTE_DELAY_MS; module_param(tx_unmute_delay, int, 0664); MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path"); @@ -423,6 +426,25 @@ static int tx_macro_reg_wake_irq(struct snd_soc_component *component, return ret; } +static int is_amic_enabled(struct snd_soc_component *component, int decimator) +{ + u16 adc_mux_reg = 0, adc_reg = 0; + u16 adc_n = BOLERO_ADC_MAX; + + adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + + TX_MACRO_ADC_MUX_CFG_OFFSET * decimator; + if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) { + adc_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + + TX_MACRO_ADC_MUX_CFG_OFFSET * decimator; + adc_n = snd_soc_component_read32(component, adc_reg) & + TX_MACRO_SWR_MIC_MUX_SEL_MASK; + if (adc_n >= BOLERO_ADC_MAX) + adc_n = BOLERO_ADC_MAX; + } + + return adc_n; +} + static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) { struct delayed_work *hpf_delayed_work = NULL; @@ -431,7 +453,7 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) struct snd_soc_component *component = NULL; u16 dec_cfg_reg = 0, hpf_gate_reg = 0; u8 hpf_cut_off_freq = 0; - u16 adc_mux_reg = 0, adc_n = 0, adc_reg = 0; + u16 adc_n = 0; hpf_delayed_work = to_delayed_work(work); hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); @@ -447,26 +469,30 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) dev_dbg(component->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", __func__, hpf_work->decimator, hpf_cut_off_freq); - adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + - TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator; - if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) { - adc_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + - TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator; - adc_n = snd_soc_component_read32(component, adc_reg) & - TX_MACRO_SWR_MIC_MUX_SEL_MASK; - if (adc_n >= BOLERO_ADC_MAX) - goto tx_hpf_set; + adc_n = is_amic_enabled(component, hpf_work->decimator); + if (adc_n < BOLERO_ADC_MAX) { /* analog mic clear TX hold */ bolero_clear_amic_tx_hold(component->dev, adc_n); + snd_soc_component_update_bits(component, + dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_component_update_bits(component, hpf_gate_reg, + 0x03, 0x02); + /* Minimum 1 clk cycle delay is required as per HW spec */ + usleep_range(1000, 1010); + snd_soc_component_update_bits(component, hpf_gate_reg, + 0x03, 0x01); + } else { + snd_soc_component_update_bits(component, + dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_component_update_bits(component, hpf_gate_reg, + 0x02, 0x02); + /* Minimum 1 clk cycle delay is required as per HW spec */ + usleep_range(1000, 1010); + snd_soc_component_update_bits(component, hpf_gate_reg, + 0x02, 0x00); } -tx_hpf_set: - snd_soc_component_update_bits(component, - dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, - hpf_cut_off_freq << 5); - snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x02); - /* Minimum 1 clk cycle delay is required as per HW spec */ - usleep_range(1000, 1010); - snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x00); } static void tx_macro_mute_update_callback(struct work_struct *work) @@ -844,6 +870,8 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, u16 hpf_gate_reg = 0; u16 tx_gain_ctl_reg = 0; u8 hpf_cut_off_freq = 0; + int hpf_delay = TX_MACRO_DMIC_HPF_DELAY_MS; + int unmute_delay = TX_MACRO_DMIC_UNMUTE_DELAY_MS; struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; @@ -895,14 +923,20 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, TX_HPF_CUT_OFF_FREQ_MASK, CF_MIN_3DB_150HZ << 5); + if (is_amic_enabled(component, decimator) < BOLERO_ADC_MAX) { + hpf_delay = TX_MACRO_AMIC_HPF_DELAY_MS; + unmute_delay = TX_MACRO_AMIC_UNMUTE_DELAY_MS; + } + if (tx_unmute_delay < unmute_delay) + tx_unmute_delay = unmute_delay; /* schedule work queue to Remove Mute */ schedule_delayed_work(&tx_priv->tx_mute_dwork[decimator].dwork, msecs_to_jiffies(tx_unmute_delay)); if (tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq != CF_MIN_3DB_150HZ) { schedule_delayed_work( - &tx_priv->tx_hpf_work[decimator].dwork, - msecs_to_jiffies(300)); + &tx_priv->tx_hpf_work[decimator].dwork, + msecs_to_jiffies(hpf_delay)); snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x03); /* diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 26475e600aa2..ec2e0fcc7d6b 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -44,16 +44,18 @@ #define VA_MACRO_TX_DMIC_CLK_DIV_MASK 0x0E #define VA_MACRO_TX_DMIC_CLK_DIV_SHFT 0x01 #define VA_MACRO_SWR_MIC_MUX_SEL_MASK 0xF -#define VA_MACRO_ADC_MUX_CFG_OFFSET 0x2 +#define VA_MACRO_ADC_MUX_CFG_OFFSET 0x8 -#define BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS 40 +#define BOLERO_CDC_VA_TX_DMIC_UNMUTE_DELAY_MS 40 +#define BOLERO_CDC_VA_TX_AMIC_UNMUTE_DELAY_MS 100 +#define BOLERO_CDC_VA_TX_DMIC_HPF_DELAY_MS 300 +#define BOLERO_CDC_VA_TX_AMIC_HPF_DELAY_MS 300 #define MAX_RETRY_ATTEMPTS 500 - #define VA_MACRO_SWR_STRING_LEN 80 #define VA_MACRO_CHILD_DEVICES_MAX 3 static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); -static int va_tx_unmute_delay = BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS; +static int va_tx_unmute_delay = BOLERO_CDC_VA_TX_DMIC_UNMUTE_DELAY_MS; module_param(va_tx_unmute_delay, int, 0664); MODULE_PARM_DESC(va_tx_unmute_delay, "delay to unmute the tx path"); @@ -708,6 +710,25 @@ static int va_macro_swrm_clock(void *handle, bool enable) return ret; } +static int is_amic_enabled(struct snd_soc_component *component, int decimator) +{ + u16 adc_mux_reg = 0, adc_reg = 0; + u16 adc_n = BOLERO_ADC_MAX; + + adc_mux_reg = BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1 + + VA_MACRO_ADC_MUX_CFG_OFFSET * decimator; + if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) { + adc_reg = BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0 + + VA_MACRO_ADC_MUX_CFG_OFFSET * decimator; + adc_n = snd_soc_component_read32(component, adc_reg) & + VA_MACRO_SWR_MIC_MUX_SEL_MASK; + if (adc_n >= BOLERO_ADC_MAX) + adc_n = BOLERO_ADC_MAX; + } + + return adc_n; +} + static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) { struct delayed_work *hpf_delayed_work; @@ -716,7 +737,7 @@ static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) struct snd_soc_component *component; u16 dec_cfg_reg, hpf_gate_reg; u8 hpf_cut_off_freq; - u16 adc_mux_reg = 0, adc_n = 0, adc_reg = 0; + u16 adc_n = 0; hpf_delayed_work = to_delayed_work(work); hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); @@ -732,26 +753,30 @@ static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) dev_dbg(va_priv->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", __func__, hpf_work->decimator, hpf_cut_off_freq); - adc_mux_reg = BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1 + - VA_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator; - if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) { - adc_reg = BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0 + - VA_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator; - adc_n = snd_soc_component_read32(component, adc_reg) & - VA_MACRO_SWR_MIC_MUX_SEL_MASK; - if (adc_n >= BOLERO_ADC_MAX) - goto va_hpf_set; + adc_n = is_amic_enabled(component, hpf_work->decimator); + if (adc_n < BOLERO_ADC_MAX) { /* analog mic clear TX hold */ bolero_clear_amic_tx_hold(component->dev, adc_n); + snd_soc_component_update_bits(component, + dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_component_update_bits(component, hpf_gate_reg, + 0x03, 0x02); + /* Minimum 1 clk cycle delay is required as per HW spec */ + usleep_range(1000, 1010); + snd_soc_component_update_bits(component, hpf_gate_reg, + 0x03, 0x01); + } else { + snd_soc_component_update_bits(component, + dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, + hpf_cut_off_freq << 5); + snd_soc_component_update_bits(component, hpf_gate_reg, + 0x02, 0x02); + /* Minimum 1 clk cycle delay is required as per HW spec */ + usleep_range(1000, 1010); + snd_soc_component_update_bits(component, hpf_gate_reg, + 0x02, 0x00); } -va_hpf_set: - snd_soc_component_update_bits(component, - dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, - hpf_cut_off_freq << 5); - snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x02); - /* Minimum 1 clk cycle delay is required as per HW spec */ - usleep_range(1000, 1010); - snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x00); } static void va_macro_mute_update_callback(struct work_struct *work) @@ -1045,6 +1070,8 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, u8 hpf_cut_off_freq; struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; + int hpf_delay = BOLERO_CDC_VA_TX_DMIC_HPF_DELAY_MS; + int unmute_delay = BOLERO_CDC_VA_TX_DMIC_UNMUTE_DELAY_MS; if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; @@ -1090,21 +1117,27 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, CF_MIN_3DB_150HZ << 5); - snd_soc_component_update_bits(component, - hpf_gate_reg, 0x03, 0x03); - /* - * Minimum 1 clk cycle delay is required as per HW spec - */ - usleep_range(1000, 1010); - snd_soc_component_update_bits(component, - hpf_gate_reg, 0x02, 0x00); - snd_soc_component_update_bits(component, - hpf_gate_reg, 0x01, 0x01); - /* - * 6ms delay is required as per HW spec - */ - usleep_range(6000, 6010); } + if (is_amic_enabled(component, decimator) < BOLERO_ADC_MAX) { + hpf_delay = BOLERO_CDC_VA_TX_AMIC_HPF_DELAY_MS; + unmute_delay = BOLERO_CDC_VA_TX_AMIC_UNMUTE_DELAY_MS; + if (va_tx_unmute_delay < unmute_delay) + va_tx_unmute_delay = unmute_delay; + } + snd_soc_component_update_bits(component, + hpf_gate_reg, 0x03, 0x03); + /* + * Minimum 1 clk cycle delay is required as per HW spec + */ + usleep_range(1000, 1010); + snd_soc_component_update_bits(component, + hpf_gate_reg, 0x02, 0x00); + snd_soc_component_update_bits(component, + hpf_gate_reg, 0x01, 0x01); + /* + * 6ms delay is required as per HW spec + */ + usleep_range(6000, 6010); /* schedule work queue to Remove Mute */ schedule_delayed_work(&va_priv->va_mute_dwork[decimator].dwork, msecs_to_jiffies(va_tx_unmute_delay)); @@ -1112,7 +1145,7 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, CF_MIN_3DB_150HZ) schedule_delayed_work( &va_priv->va_hpf_work[decimator].dwork, - msecs_to_jiffies(50)); + msecs_to_jiffies(hpf_delay)); /* apply gain after decimator is enabled */ snd_soc_component_write(component, tx_gain_ctl_reg, snd_soc_component_read32(component, tx_gain_ctl_reg)); -- GitLab From e74893fd6fa2ee6d4ad7d8e2d8fad01e0c4541d1 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Fri, 6 Dec 2019 17:45:57 -0800 Subject: [PATCH 1350/1645] asoc: codecs: wcd938x: bypass filter while enabling PA While enabling headphone PA, bypass preref filter to resolve clipping issue in the first second. Change-Id: I7524fe3215bac267c5e199c715931712e16adf88 Signed-off-by: Karthikeyan Mani --- asoc/codecs/wcd938x/wcd938x.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 3db8fc5a9733..5b46094205da 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -708,6 +708,11 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, WCD_CLSH_STATE_HPHR, hph_mode); wcd_clsh_set_hph_mode(component, CLS_H_HIFI); + if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI || + hph_mode == CLS_H_ULP) { + snd_soc_component_update_bits(component, + WCD938X_HPH_REFBUFF_LP_CTL, 0x01, 0x01); + } snd_soc_component_update_bits(component, WCD938X_ANA_HPH, 0x10, 0x10); wcd_clsh_set_hph_mode(component, hph_mode); @@ -728,6 +733,12 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, usleep_range(20000, 20100); else usleep_range(7000, 7100); + if (hph_mode == CLS_H_LP || + hph_mode == CLS_H_LOHIFI || + hph_mode == CLS_H_ULP) + snd_soc_component_update_bits(component, + WCD938X_HPH_REFBUFF_LP_CTL, 0x01, + 0x00); clear_bit(HPH_PA_DELAY, &wcd938x->status_mask); } snd_soc_component_update_bits(component, @@ -833,6 +844,11 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, WCD_CLSH_STATE_HPHL, hph_mode); wcd_clsh_set_hph_mode(component, CLS_H_HIFI); + if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI || + hph_mode == CLS_H_ULP) { + snd_soc_component_update_bits(component, + WCD938X_HPH_REFBUFF_LP_CTL, 0x01, 0x01); + } snd_soc_component_update_bits(component, WCD938X_ANA_HPH, 0x20, 0x20); wcd_clsh_set_hph_mode(component, hph_mode); @@ -853,6 +869,12 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, usleep_range(20000, 20100); else usleep_range(7000, 7100); + if (hph_mode == CLS_H_LP || + hph_mode == CLS_H_LOHIFI || + hph_mode == CLS_H_ULP) + snd_soc_component_update_bits(component, + WCD938X_HPH_REFBUFF_LP_CTL, + 0x01, 0x00); clear_bit(HPH_PA_DELAY, &wcd938x->status_mask); } snd_soc_component_update_bits(component, -- GitLab From 5a54216587763381502cede4420948868be3979b Mon Sep 17 00:00:00 2001 From: Viraja Kommaraju Date: Wed, 18 Dec 2019 09:39:38 +0530 Subject: [PATCH 1351/1645] ASoC: msm: Add support for MultiMedia23 Add MultiMedia23 fe dai Change-Id: I504889f1edb8298609d94a1350d81436bb874b22 --- asoc/sa8155.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/asoc/sa8155.c b/asoc/sa8155.c index 2939fc2a587b..695f122686bb 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -5879,6 +5879,23 @@ static struct snd_soc_dai_link msm_auto_fe_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA22 }, + { + .name = MSM_DAILINK_NAME(Media23), + .stream_name = "MultiMedia23", + .cpu_dai_name = "MultiMedia23", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA23 + }, }; static struct snd_soc_dai_link msm_custom_fe_dai_links[] = { -- GitLab From c89e6fb4cbd8e4501aeaa0fcddce4031e3eda066 Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Mon, 14 Oct 2019 14:30:17 +0530 Subject: [PATCH 1352/1645] dsp: Add afe_close in locked context Process port command DEVICE_STOP with afe_cmd_lock to avoid any race condition. Change-Id: I6e888a70e439cb6f3408d00644fb98a85ae53ef4 Signed-off-by: Soumya Managoli --- dsp/q6afe.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index b65cc98f912d..b47904264423 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -7463,6 +7463,7 @@ int afe_close(int port_id) pr_debug("%s: Not a MAD port\n", __func__); } + mutex_lock(&this_afe.afe_cmd_lock); port_index = afe_get_port_index(port_id); if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) { this_afe.afe_sample_rates[port_index] = 0; @@ -7505,6 +7506,7 @@ int afe_close(int port_id) pr_err("%s: AFE close failed %d\n", __func__, ret); fail_cmd: + mutex_unlock(&this_afe.afe_cmd_lock); return ret; } EXPORT_SYMBOL(afe_close); -- GitLab From ac0217c5ec49a8af2ba039ced4f871b81688e004 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 23 Dec 2019 17:27:58 +0530 Subject: [PATCH 1353/1645] ASoC: bolero: Resolve handset record not resuming after PDR Handset record does not resume if pdr is performed during record. Make VA DMIC_CTL registers as volatile to write proper value of register to hw. Change-Id: I2cc10d2eab18e3e8126c56caffa126195c02b4e3 Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/bolero-cdc-regmap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asoc/codecs/bolero/bolero-cdc-regmap.c b/asoc/codecs/bolero/bolero-cdc-regmap.c index b1a263fb008f..e6f03fcab6a6 100644 --- a/asoc/codecs/bolero/bolero-cdc-regmap.c +++ b/asoc/codecs/bolero/bolero-cdc-regmap.c @@ -797,6 +797,10 @@ static bool bolero_is_volatile_register(struct device *dev, case BOLERO_CDC_VA_TOP_CSR_CORE_ID_1: case BOLERO_CDC_VA_TOP_CSR_CORE_ID_2: case BOLERO_CDC_VA_TOP_CSR_CORE_ID_3: + case BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL: + case BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL: + case BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL: + case BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL: case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL: case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC1_CTL: case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC2_CTL: -- GitLab From 96210450f648917a4f35d685623aca0af3eaee40 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 23 Dec 2019 18:56:39 +0530 Subject: [PATCH 1354/1645] dsp: Update clk status when DSP returns error When DSP returns error in clock or vote request commands, update the clock status variable properly to bail out from error scenarios. Change-Id: Ib50e9e33b03fd77255b8719c125612686ea11b00 Signed-off-by: Aditya Bavanari --- dsp/q6afe.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 75ce5b004e55..a49a970f460b 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -704,7 +704,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) payload[0], payload[1], data->token); /* payload[1] contains the error status for response */ if (payload[1] != 0) { - atomic_set(&this_afe.status, payload[1]); + if(data->token == AFE_CLK_TOKEN) + atomic_set(&this_afe.clk_status, payload[1]); + else + atomic_set(&this_afe.status, payload[1]); pr_err("%s: cmd = 0x%x returned error = 0x%x\n", __func__, payload[0], payload[1]); } @@ -781,6 +784,9 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) case AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST: case AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST: atomic_set(&this_afe.clk_state, 0); + if (payload[1] != 0) + atomic_set(&this_afe.clk_status, + payload[1]); wake_up(&this_afe.lpass_core_hw_wait); break; case AFE_SVC_CMD_EVENT_CFG: -- GitLab From c7d471630e1ce0016b082a5bc15879a5539ee591 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Wed, 18 Dec 2019 16:33:23 -0800 Subject: [PATCH 1355/1645] dsp: adm: increase the length of timeout in adm_open to 2 seconds Currently, the length of timeout in adm_open for waiting response from ADSP is 1 second. To prevent unnecessary timeout that results adm_open failure, increase the length of timeout to 2 seconds. Change-Id: I670f44964538c3176130c4bb5f8b7a3b3eaf8d8b Signed-off-by: Xiaoyu Ye --- dsp/q6adm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index b161df90aec7..51a421b9c77c 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -3372,7 +3372,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], atomic_read(&this_adm.copp.stat [port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); + msecs_to_jiffies(2 * TIMEOUT_MS)); if (!ret) { pr_err("%s: ADM open timedout for port_id: 0x%x for [0x%x]\n", __func__, tmp_port, port_id); -- GitLab From cd05eb16bbb128add7136e0dfea5c2ed76af6f9c Mon Sep 17 00:00:00 2001 From: Jaideep Sharma Date: Thu, 12 Dec 2019 14:20:27 +0530 Subject: [PATCH 1356/1645] audio_kernel: convert Android.mk to Android.bp audio_kernel_headers Change-Id: Icfc26efae1d7c3b1a05f4a958115e8a1408d7f12 --- Android.bp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Android.bp diff --git a/Android.bp b/Android.bp new file mode 100644 index 000000000000..4422132c5247 --- /dev/null +++ b/Android.bp @@ -0,0 +1,18 @@ +gensrcs { + name: "qcom-audio-kernel-includes", + cmd: "$(location headers_install.sh) `dirname $(out)` `dirname $(in)` `basename $(in)`", + tools: ["headers_install.sh"], + export_include_dirs: ["include/uapi"], + srcs: [ + "include/uapi/**/*.h", + ], + output_extension: "h", +} + +cc_library_headers { + name: "qcom_audio_kernel_headers", + generated_headers: ["qcom-audio-kernel-includes"], + export_generated_headers: ["qcom-audio-kernel-includes"], + vendor: true, + recovery_available: true, +} -- GitLab From 9311ca46dd94035edd99e26251f6e4570991b557 Mon Sep 17 00:00:00 2001 From: Ramu Gottipati Date: Tue, 10 Dec 2019 16:08:30 +0530 Subject: [PATCH 1357/1645] ASoC: Add driver support for multi-ch ECNS Add Control names for newly supported channels Change-Id: Ia830b10f681224605e68af659248beb58bd530c0 Signed-off-by: Ramu Gottipati --- asoc/msm-pcm-routing-v2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index d37a58d01812..3d3e102fb4bb 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -5562,6 +5562,12 @@ static const struct snd_kcontrol_new ec_ref_param_controls[] = { SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch6", SND_SOC_NOPM, 5, 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, NULL, msm_ec_ref_chmixer_weights_put), + SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch7", SND_SOC_NOPM, + 6, 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, NULL, + msm_ec_ref_chmixer_weights_put), + SOC_SINGLE_MULTI_EXT("EC Reference ChMixer Weights Ch8", SND_SOC_NOPM, + 7, 16384, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, NULL, + msm_ec_ref_chmixer_weights_put), SOC_ENUM_EXT("AFE_LOOPBACK_TX Port", msm_route_ec_ref_rx_enum[0], msm_routing_afe_lb_tx_port_get, msm_routing_afe_lb_tx_port_put), }; -- GitLab From dd0e8a12b49d94341fd70529c6a4629decbfb506 Mon Sep 17 00:00:00 2001 From: Ramu Gottipati Date: Thu, 26 Dec 2019 10:44:25 +0530 Subject: [PATCH 1358/1645] ASoC: Add FFECNS Freeze event support Add mixer control support to send ffecns freeze event. Change-Id: I86bfd27aac312f85ebbde1f35ff4f65f589c6fec Signed-off-by: Ramu Gottipati --- asoc/msm-pcm-routing-v2.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index d37a58d01812..d67830171fe1 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -79,6 +79,7 @@ static uint32_t voc_session_id = ALL_SESSION_VSID; static int msm_route_ext_ec_ref; static bool is_custom_stereo_on; static bool is_ds2_on; +static bool ffecns_freeze_event; static bool swap_ch; static bool hifi_filter_enabled; static int aanc_level; @@ -22299,6 +22300,36 @@ static const struct snd_kcontrol_new hifi_filter_controls[] = { msm_routing_put_hifi_filter_control), }; +static int msm_routing_get_ffecns_freeze_event_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = ffecns_freeze_event; + return 0; +} + +static int msm_routing_put_ffecns_freeze_event_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = -EINVAL; + + ffecns_freeze_event = ucontrol->value.integer.value[0]; + + ret = adm_set_ffecns_freeze_event(ffecns_freeze_event); + if (ret) + pr_err("%s: failed to set ffecns imc event to%d\n", + __func__, ffecns_freeze_event); + + return ret; +} + +static const struct snd_kcontrol_new use_ffecns_freeze_event_controls[] = { + SOC_SINGLE_EXT("FFECNS Freeze Event", SND_SOC_NOPM, 0, + 1, 0, msm_routing_get_ffecns_freeze_event_control, + msm_routing_put_ffecns_freeze_event_control), +}; + int msm_routing_get_rms_value_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int rc = 0; @@ -29727,6 +29758,10 @@ static int msm_routing_probe(struct snd_soc_component *component) hifi_filter_controls, ARRAY_SIZE(hifi_filter_controls)); + snd_soc_add_component_controls(component, + use_ffecns_freeze_event_controls, + ARRAY_SIZE(use_ffecns_freeze_event_controls)); + snd_soc_add_component_controls(component, device_pp_params_mixer_controls, ARRAY_SIZE(device_pp_params_mixer_controls)); -- GitLab From 34dc362fb4021f02d70e115de6dd29f42c1ca1aa Mon Sep 17 00:00:00 2001 From: Ramu Gottipati Date: Thu, 26 Dec 2019 10:50:00 +0530 Subject: [PATCH 1359/1645] dsp: Add FFECNS Freeze event support Add support to send ffecns freeze event Change-Id: I73bc6ff8c091427ddb398ae11c95f19c36e904b6 Signed-off-by: Ramu Gottipati --- dsp/q6adm.c | 43 ++++++++++++++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 1 + include/dsp/q6adm-v2.h | 6 ++++++ 3 files changed, 50 insertions(+) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index b161df90aec7..ec4ca4e3bbf2 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -4568,6 +4568,49 @@ int adm_set_ffecns_effect(int effect) } EXPORT_SYMBOL(adm_set_ffecns_effect); +/** + * adm_set_ffecns_freeze_event - + * command to set event for ffecns module + * + * @event: send ffecns freeze event true or false + * + * Returns 0 on success or error on failure + */ +int adm_set_ffecns_freeze_event(bool ffecns_freeze_event) +{ + struct ffv_spf_freeze_param_t ffv_param; + struct param_hdr_v3 param_hdr; + int rc = 0; + int copp_idx = 0; + + memset(¶m_hdr, 0, sizeof(param_hdr)); + memset(&ffv_param, 0, sizeof(ffv_param)); + + ffv_param.freeze = ffecns_freeze_event ? 1 : 0; + ffv_param.source_id = 0; /*default value*/ + + copp_idx = adm_get_default_copp_idx(this_adm.ffecns_port_id); + if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { + pr_err("%s, no active copp to query rms copp_idx:%d\n", + __func__, copp_idx); + return -EINVAL; + } + + param_hdr.module_id = FFECNS_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = PARAM_ID_FFV_SPF_FREEZE; + param_hdr.param_size = sizeof(ffv_param); + + rc = adm_pack_and_set_one_pp_param(this_adm.ffecns_port_id, copp_idx, + param_hdr, (uint8_t *) &ffv_param); + if (rc) + pr_err("%s: Failed to set ffecns imc event, err %d\n", + __func__, rc); + + return rc; +} +EXPORT_SYMBOL(adm_set_ffecns_freeze_event); + /** * adm_param_enable - * command to send params to ADM for given module diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 0fcc76ae842a..111f191635f0 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -849,6 +849,7 @@ struct audproc_softvolume_params { */ #define AUDPROC_MODULE_ID_MFC_EC_REF 0x0001092C +#define PARAM_ID_FFV_SPF_FREEZE 0x00010960 struct adm_cmd_set_pp_params_v5 { struct apr_hdr hdr; diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 894bca40c816..6180cc77ba39 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -85,6 +85,11 @@ struct msm_pcm_channel_mixer { bool override_out_ch_map; }; +struct ffv_spf_freeze_param_t { + uint16_t freeze; + uint16_t source_id; +}; + int srs_trumedia_open(int port_id, int copp_idx, __s32 srs_tech_id, void *srs_params); @@ -221,4 +226,5 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, void msm_dts_srs_acquire_lock(void); void msm_dts_srs_release_lock(void); void adm_set_native_mode(int mode); +int adm_set_ffecns_freeze_event(bool ffecns_freeze_event); #endif /* __Q6_ADM_V2_H__ */ -- GitLab From 4f13298b484fa0d1af4f18ea1187ee2821f29fa3 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Wed, 18 Dec 2019 14:00:33 +0800 Subject: [PATCH 1360/1645] asoc: lsm: free confidence_levels memory to avoid memory leakage prtd->lsm_client->confidence_levels is allocated in msm_lsm_get_conf_levels and not freed in msm_lsm_set_conf. Make this change to free this memory. Change-Id: I617703b36c13e065fdf995e89121c442b32b08f3 Signed-off-by: Meng Wang --- asoc/msm-lsm-client.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 5bc897d9e594..14b7a753cc0a 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -659,6 +659,10 @@ static int msm_lsm_set_conf(struct snd_pcm_substream *substream, "%s: Failed to set min_conf_levels, err = %d\n", __func__, rc); + if (prtd->lsm_client->confidence_levels) { + kfree(prtd->lsm_client->confidence_levels); + prtd->lsm_client->confidence_levels = NULL; + } return rc; } @@ -1055,7 +1059,6 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime; struct lsm_priv *prtd; struct snd_lsm_detection_params det_params; - uint8_t *confidence_level = NULL; uint32_t max_detection_stages_supported = LSM_MAX_STAGES_PER_SESSION; if (!substream || !substream->private_data) { @@ -1210,12 +1213,12 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: Register snd Model v2 failed =%d\n", __func__, rc); - kfree(confidence_level); q6lsm_snd_model_buf_free(prtd->lsm_client, &p_info); } - - kfree(prtd->lsm_client->confidence_levels); - prtd->lsm_client->confidence_levels = NULL; + if (prtd->lsm_client->confidence_levels) { + kfree(prtd->lsm_client->confidence_levels); + prtd->lsm_client->confidence_levels = NULL; + } break; } case SNDRV_LSM_SET_PARAMS: @@ -1247,10 +1250,10 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: Failed to set params, err = %d\n", __func__, rc); - - kfree(prtd->lsm_client->confidence_levels); - prtd->lsm_client->confidence_levels = NULL; - + if (prtd->lsm_client->confidence_levels) { + kfree(prtd->lsm_client->confidence_levels); + prtd->lsm_client->confidence_levels = NULL; + } break; case SNDRV_LSM_DEREG_SND_MODEL: -- GitLab From 43fcbae5a38a592c850999cf41a70be21cf6739e Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 27 Dec 2019 13:02:43 +0530 Subject: [PATCH 1361/1645] ASoC: wcd938x: Disable ear path at power down Ear Path is not disabled properly disabled at power down. Disable clk and other registers depending on whether ear takes aux or hph path at pwd. Change-Id: I987904ddd9bf21b9ed96e754e6eb2514b4d277ce Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd938x/wcd938x.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index d5a48b321ddf..60ef2bf48764 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include @@ -628,6 +628,15 @@ static int wcd938x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) { snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_AUX_GAIN_CTL, 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x04, 0x00); + } else { + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_HPH_GAIN_CTL, 0x04, 0x00); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x00); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x00); } snd_soc_component_update_bits(component, WCD938X_ANA_EAR_COMPANDER_CTL, 0x80, 0x00); @@ -2379,7 +2388,6 @@ static const struct snd_kcontrol_new wcd938x_snd_controls[] = { wcd938x_get_compander, wcd938x_set_compander), SOC_SINGLE_EXT("HPHR_COMP Switch", SND_SOC_NOPM, 1, 1, 0, wcd938x_get_compander, wcd938x_set_compander), - SOC_SINGLE_EXT("LDOH Enable", SND_SOC_NOPM, 0, 1, 0, wcd938x_ldoh_get, wcd938x_ldoh_put), -- GitLab From f415500ef79320c2d957704ffde9f21eb3e38580 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 5 Dec 2019 01:36:13 +0530 Subject: [PATCH 1362/1645] ASoC: bolero: check clock source before clock switch Check soundwire clock source before clock switch to avoid redundant soundwire device suspend for the same clock source. Change-Id: I613789b23c171959a60c9a059a30b3f1494f3dfa Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/bolero-cdc.c | 9 +- asoc/codecs/bolero/bolero-cdc.h | 14 +++- asoc/codecs/bolero/tx-macro.c | 6 +- asoc/codecs/bolero/va-macro.c | 142 +++++++++++++++++++++++++++++--- 4 files changed, 151 insertions(+), 20 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 460a725488e1..af22bb2bb35e 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include @@ -991,9 +991,11 @@ EXPORT_SYMBOL(bolero_register_wake_irq); * * @component: pointer to codec component instance. * + * @clk_src: 0 for TX_RCG and 1 for VA_RCG + * * Returns 0 on success or -EINVAL on error. */ -int bolero_tx_clk_switch(struct snd_soc_component *component) +int bolero_tx_clk_switch(struct snd_soc_component *component, int clk_src) { struct bolero_priv *priv = NULL; int ret = 0; @@ -1011,7 +1013,8 @@ int bolero_tx_clk_switch(struct snd_soc_component *component) } if (priv->macro_params[TX_MACRO].clk_switch) - ret = priv->macro_params[TX_MACRO].clk_switch(component); + ret = priv->macro_params[TX_MACRO].clk_switch(component, + clk_src); return ret; } diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 2294594c801f..3144d88b6c5a 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #ifndef BOLERO_CDC_H @@ -37,6 +37,11 @@ enum { BOLERO_ADC_MAX }; +enum { + CLK_SRC_TX_RCG = 0, + CLK_SRC_VA_RCG, +}; + enum { BOLERO_MACRO_EVT_RX_MUTE = 1, /* for RX mute/unmute */ BOLERO_MACRO_EVT_IMPED_TRUE, /* for imped true */ @@ -80,8 +85,8 @@ struct macro_ops { int (*reg_wake_irq)(struct snd_soc_component *component, u32 data); int (*set_port_map)(struct snd_soc_component *component, u32 uc, u32 size, void *data); - int (*clk_switch)(struct snd_soc_component *component); int (*clk_div_get)(struct snd_soc_component *component); + int (*clk_switch)(struct snd_soc_component *component, int clk_src); int (*reg_evt_listener)(struct snd_soc_component *component, bool en); int (*clk_enable)(struct snd_soc_component *c, bool en); char __iomem *io_base; @@ -107,7 +112,7 @@ void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n); int bolero_runtime_resume(struct device *dev); int bolero_runtime_suspend(struct device *dev); int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *data); -int bolero_tx_clk_switch(struct snd_soc_component *component); +int bolero_tx_clk_switch(struct snd_soc_component *component, int clk_src); int bolero_register_event_listener(struct snd_soc_component *component, bool enable); void bolero_wsa_pa_on(struct device *dev); @@ -175,7 +180,8 @@ static inline int bolero_set_port_map(struct snd_soc_component *component, return 0; } -static inline int bolero_tx_clk_switch(struct snd_soc_component *component) +static inline int bolero_tx_clk_switch(struct snd_soc_component *component, + int clk_src) { return 0; } diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index b2b47531076a..a27c3e1a8111 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include @@ -2509,7 +2509,7 @@ static int tx_macro_clk_div_get(struct snd_soc_component *component) return tx_priv->dmic_clk_div; } -static int tx_macro_clk_switch(struct snd_soc_component *component) +static int tx_macro_clk_switch(struct snd_soc_component *component, int clk_src) { struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; @@ -2533,7 +2533,7 @@ static int tx_macro_clk_switch(struct snd_soc_component *component) if (tx_priv->swr_ctrl_data) { ret = swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, - SWR_REQ_CLK_SWITCH, NULL); + SWR_REQ_CLK_SWITCH, &clk_src); } return ret; diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index c595cadc6439..3493a6532c40 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include @@ -45,6 +45,7 @@ #define VA_MACRO_TX_DMIC_CLK_DIV_SHFT 0x01 #define VA_MACRO_SWR_MIC_MUX_SEL_MASK 0xF #define VA_MACRO_ADC_MUX_CFG_OFFSET 0x8 +#define VA_MACRO_ADC_MODE_CFG0_SHIFT 1 #define BOLERO_CDC_VA_TX_DMIC_UNMUTE_DELAY_MS 40 #define BOLERO_CDC_VA_TX_AMIC_UNMUTE_DELAY_MS 100 @@ -170,6 +171,7 @@ struct va_macro_priv { int tx_clk_status; bool lpi_enable; bool register_event_listener; + int dec_mode[VA_MACRO_NUM_DECIMATORS]; }; static bool va_macro_get_data(struct snd_soc_component *component, @@ -400,7 +402,12 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; - dev_dbg(va_dev, "%s: event = %d\n", __func__, event); + dev_dbg(va_dev, "%s: event = %d, lpi_enable = %d\n", + __func__, event, va_priv->lpi_enable); + + if (!va_priv->lpi_enable) + return ret; + switch (event) { case SND_SOC_DAPM_PRE_PMU: if (va_priv->lpass_audio_hw_vote) { @@ -411,7 +418,7 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, __func__); } if (!ret) - if (bolero_tx_clk_switch(component)) + if (bolero_tx_clk_switch(component, CLK_SRC_VA_RCG)) dev_dbg(va_dev, "%s: clock switch failed\n", __func__); if (va_priv->lpi_enable) { @@ -424,7 +431,7 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, va_priv->register_event_listener = false; bolero_register_event_listener(component, false); } - if (bolero_tx_clk_switch(component)) + if (bolero_tx_clk_switch(component, CLK_SRC_TX_RCG)) dev_dbg(va_dev, "%s: clock switch failed\n",__func__); if (va_priv->lpass_audio_hw_vote) clk_disable_unprepare(va_priv->lpass_audio_hw_vote); @@ -484,12 +491,14 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, ret = bolero_tx_mclk_enable(component, 1); break; case SND_SOC_DAPM_POST_PMD: - if (bolero_tx_clk_switch(component)) - dev_dbg(va_dev, "%s: clock switch failed\n",__func__); - if (va_priv->lpi_enable) + if (va_priv->lpi_enable) { + if (bolero_tx_clk_switch(component, CLK_SRC_TX_RCG)) + dev_dbg(va_dev, "%s: clock switch failed\n", + __func__); va_macro_mclk_enable(va_priv, 0, true); - else + } else { bolero_tx_mclk_enable(component, 0); + } if (va_priv->tx_clk_status > 0) { bolero_clk_rsc_request_clock(va_priv->dev, @@ -1058,6 +1067,9 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + snd_soc_component_update_bits(component, + dec_cfg_reg, 0x06, va_priv->dec_mode[decimator] << + VA_MACRO_ADC_MODE_CFG0_SHIFT); /* Enable TX PGA Mute */ snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x10); @@ -1171,8 +1183,6 @@ static int va_macro_enable_tx(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMU: - if (bolero_tx_clk_switch(component)) - dev_dbg(va_dev, "%s: clock switch failed\n",__func__); if (va_priv->tx_clk_status > 0) { ret = bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, @@ -1265,6 +1275,90 @@ static int va_macro_enable_micbias(struct snd_soc_dapm_widget *w, return 0; } +static inline int va_macro_path_get(const char *wname, + unsigned int *path_num) +{ + int ret = 0; + char *widget_name = NULL; + char *w_name = NULL; + char *path_num_char = NULL; + char *path_name = NULL; + + widget_name = kstrndup(wname, 10, GFP_KERNEL); + if (!widget_name) + return -EINVAL; + + w_name = widget_name; + + path_name = strsep(&widget_name, " "); + if (!path_name) { + pr_err("%s: Invalid widget name = %s\n", + __func__, widget_name); + ret = -EINVAL; + goto err; + } + path_num_char = strpbrk(path_name, "01234567"); + if (!path_num_char) { + pr_err("%s: va path index not found\n", + __func__); + ret = -EINVAL; + goto err; + } + ret = kstrtouint(path_num_char, 10, path_num); + if (ret < 0) + pr_err("%s: Invalid tx path = %s\n", + __func__, w_name); + +err: + kfree(w_name); + return ret; +} + +static int va_macro_dec_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct va_macro_priv *priv = NULL; + struct device *va_dev = NULL; + int ret = 0; + int path = 0; + + if (!va_macro_get_data(component, &va_dev, &priv, __func__)) + return -EINVAL; + + ret = va_macro_path_get(kcontrol->id.name, &path); + if (ret) + return ret; + + ucontrol->value.integer.value[0] = priv->dec_mode[path]; + + return 0; +} + +static int va_macro_dec_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct va_macro_priv *priv = NULL; + struct device *va_dev = NULL; + int value = ucontrol->value.integer.value[0]; + int ret = 0; + int path = 0; + + if (!va_macro_get_data(component, &va_dev, &priv, __func__)) + return -EINVAL; + + ret = va_macro_path_get(kcontrol->id.name, &path); + if (ret) + return ret; + + priv->dec_mode[path] = value; + + return 0; +} + static int va_macro_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -2313,8 +2407,24 @@ static const struct snd_soc_dapm_route va_audio_map[] = { {"VA SWR_ADC1", NULL, "VA_SWR_PWR"}, {"VA SWR_ADC2", NULL, "VA_SWR_PWR"}, {"VA SWR_ADC3", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC0", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC1", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC2", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC3", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC4", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC5", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC6", NULL, "VA_SWR_PWR"}, + {"VA SWR_MIC7", NULL, "VA_SWR_PWR"}, }; +static const char * const dec_mode_mux_text[] = { + "ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF", +}; + +static const struct soc_enum dec_mode_mux_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dec_mode_mux_text), + dec_mode_mux_text); + static const struct snd_kcontrol_new va_macro_snd_controls[] = { SOC_SINGLE_SX_TLV("VA_DEC0 Volume", BOLERO_CDC_VA_TX0_TX_VOL_CTL, @@ -2342,6 +2452,18 @@ static const struct snd_kcontrol_new va_macro_snd_controls[] = { 0, -84, 40, digital_gain), SOC_SINGLE_EXT("LPI Enable", 0, 0, 1, 0, va_macro_lpi_get, va_macro_lpi_put), + + SOC_ENUM_EXT("VA_DEC0 MODE", dec_mode_mux_enum, + va_macro_dec_mode_get, va_macro_dec_mode_put), + + SOC_ENUM_EXT("VA_DEC1 MODE", dec_mode_mux_enum, + va_macro_dec_mode_get, va_macro_dec_mode_put), + + SOC_ENUM_EXT("VA_DEC2 MODE", dec_mode_mux_enum, + va_macro_dec_mode_get, va_macro_dec_mode_put), + + SOC_ENUM_EXT("VA_DEC3 MODE", dec_mode_mux_enum, + va_macro_dec_mode_get, va_macro_dec_mode_put), }; static const struct snd_kcontrol_new va_macro_snd_controls_common[] = { -- GitLab From 16f1e6b1408b8b03768f04664b5e2e41d5cbb54e Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 7 Jan 2020 12:51:38 +0530 Subject: [PATCH 1363/1645] ASoC: Add flag to enable doa tracking params for LE Add DOA_PARAMS_ENABLED flag to enable tracking params for LE. Change-Id: I54f40a72338ab09e43d002d19c74f845c5afcd49 Signed-off-by: Vatsal Bucha --- config/qcs405auto.conf | 1 + config/qcs405autoconf.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config/qcs405auto.conf b/config/qcs405auto.conf index 61620ebb6d39..ebd6f7072766 100644 --- a/config/qcs405auto.conf +++ b/config/qcs405auto.conf @@ -36,3 +36,4 @@ CONFIG_SND_SOC_MSM_STUB=m CONFIG_MSM_AVTIMER=m CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m CONFIG_SND_SOC_EP92=m +CONFIG_DOA_PARAMS_ENABLED=m diff --git a/config/qcs405autoconf.h b/config/qcs405autoconf.h index 04f1e10fd414..286dd3108b80 100644 --- a/config/qcs405autoconf.h +++ b/config/qcs405autoconf.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #define CONFIG_PINCTRL_LPI 1 @@ -40,3 +40,4 @@ #define CONFIG_MSM_AVTIMER 1 #define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 #define CONFIG_SND_SOC_EP92 1 +#define CONFIG_DOA_PARAMS_ENABLED 1 -- GitLab From 37a8906f599127b1e33bdd90b78caf2427128918 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 7 Jan 2020 14:53:01 +0530 Subject: [PATCH 1364/1645] asoc: bengal: Fail SVA for fuse variant For fuse variant with SVA=0, ensure startup fails to make SVA app close with failure. Change-Id: Id35b04bae3b96fa1aaf36b75e835922a025388e9 Signed-off-by: Laxminath Kasam --- asoc/bengal.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/asoc/bengal.c b/asoc/bengal.c index f2a2ecea9db6..dcdf1ed1ed31 100644 --- a/asoc/bengal.c +++ b/asoc/bengal.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #include @@ -156,6 +156,7 @@ struct msm_asoc_mach_data { struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ bool is_afe_config_done; struct device_node *fsa_handle; + bool va_disable; }; struct tdm_port { @@ -261,7 +262,6 @@ static u32 mi2s_ebit_clk[MI2S_MAX] = { }; static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; -static bool va_disable; /* Default configuration of TDM channels */ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { @@ -3815,13 +3815,17 @@ static int msm_snd_cdc_dma_startup(struct snd_pcm_substream *substream) int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); switch (dai_link->id) { case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1: case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2: - if (va_disable) - break; + if (pdata->va_disable) { + pr_debug("%s: SVA not supported\n", __func__); + return -EINVAL; + } ret = bengal_send_island_va_config(dai_link->id); if (ret) pr_err("%s: send island va cfg failed, err: %d\n", @@ -6616,7 +6620,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) } memcpy(&adsp_var_idx, buf, len); kfree(buf); - va_disable = adsp_var_idx; + pdata->va_disable = adsp_var_idx; ret: return 0; -- GitLab From 2ebe1229afa1972d8cc5690053e012ca51303623 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 7 Jan 2020 18:21:31 +0530 Subject: [PATCH 1365/1645] ASoC: wcd-mbhc: Disable micbias internal pull-up after headphone detected Micbias2 internal pull-up remains enabled even after headphone is detected. This results in power issues. Disable pull up after insertion detection. Change-Id: I335dbb498192738fc282421d92510400a661cf0c Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd-mbhc-v2.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index fd55715af616..f0c0ce76d8eb 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #include #include @@ -732,6 +732,10 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, mbhc->hph_status |= jack_type; + if (jack_type == SND_JACK_HEADPHONE && + mbhc->mbhc_cb->mbhc_micb_ramp_control) + mbhc->mbhc_cb->mbhc_micb_ramp_control(component, false); + pr_debug("%s: Reporting insertion %d(%x)\n", __func__, jack_type, mbhc->hph_status); wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack, @@ -922,6 +926,10 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) else pr_info("%s: hs_detect_plug work not cancelled\n", __func__); + /* Enable micbias ramp */ + if (mbhc->mbhc_cb->mbhc_micb_ramp_control) + mbhc->mbhc_cb->mbhc_micb_ramp_control(component, true); + if (mbhc->mbhc_cb->micbias_enable_status) micbias1 = mbhc->mbhc_cb->micbias_enable_status(mbhc, MIC_BIAS_1); @@ -1417,9 +1425,6 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) /* Button Debounce set to 16ms */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_DBNC, 2); - /* Enable micbias ramp */ - if (mbhc->mbhc_cb->mbhc_micb_ramp_control) - mbhc->mbhc_cb->mbhc_micb_ramp_control(component, true); /* enable bias */ mbhc->mbhc_cb->mbhc_bias(component, true); /* enable MBHC clock */ -- GitLab From bc21b63cdcdbd2721c6738a6a95e07c3457c1fd4 Mon Sep 17 00:00:00 2001 From: Sanjana B Date: Wed, 11 Sep 2019 09:28:32 +0530 Subject: [PATCH 1366/1645] asoc: ep92: add support for DSD input Add sysfs nodes for dsd rate and update audio format sysfs node. Change-Id: Iefa09f0042bb244e42ee0bf788344d31df690af8 Signed-off-by: Sanjana B --- asoc/codecs/ep92/ep92.c | 50 +++++++++++++++++++++++++++++++++++++++-- asoc/codecs/ep92/ep92.h | 6 ++++- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/ep92/ep92.c b/asoc/codecs/ep92/ep92.c index 607707044152..07a328189331 100644 --- a/asoc/codecs/ep92/ep92.c +++ b/asoc/codecs/ep92/ep92.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include @@ -40,6 +40,10 @@ static const unsigned int ep92_samp_freq_table[8] = { 32000, 44100, 48000, 88200, 96000, 176400, 192000, 768000 }; +static const unsigned int ep92_dsd_freq_table[4] = { + 64, 128, 256, 0 +}; + static bool ep92_volatile_register(struct device *dev, unsigned int reg) { /* do not cache register state in regmap */ @@ -549,6 +553,23 @@ static void ep92_read_audio_info(struct snd_soc_component *component, send_uevent = true; } + old = ep92->ai.system_status_1; + ep92->ai.system_status_1 = snd_soc_read(codec, + EP92_AUDIO_INFO_SYSTEM_STATUS_1); + if (ep92->ai.system_status_1 == 0xff) { + dev_dbg(codec->dev, + "ep92 EP92_AUDIO_INFO_SYSTEM_STATUS_1 read 0xff\n"); + ep92->ai.system_status_1 = old; + } + change = ep92->ai.system_status_1 ^ old; + if (change & EP92_AI_DSD_RATE_MASK) { + dev_dbg(codec->dev, "ep92 dsd rate changed to %d\n", + ep92_dsd_freq_table[(ep92->ai.system_status_1 & + EP92_AI_DSD_RATE_MASK) + >> EP92_AI_DSD_RATE_SHIFT]); + send_uevent = true; + } + old = ep92->ai.audio_status; ep92->ai.audio_status = snd_soc_component_read32(component, EP92_AUDIO_INFO_AUDIO_STATUS); @@ -580,7 +601,9 @@ static void ep92_read_audio_info(struct snd_soc_component *component, } new_mode = ep92->old_mode; - if (ep92->ai.audio_status & EP92_AI_STD_ADO_MASK) { + if (ep92->ai.audio_status & EP92_AI_DSD_ADO_MASK) + new_mode = 2; /* One bit audio */ + else if (ep92->ai.audio_status & EP92_AI_STD_ADO_MASK) { if (ep92->ai.cs[0] & EP92_AI_NPCM_MASK) new_mode = 1; /* Compr */ else @@ -897,6 +920,27 @@ static ssize_t ep92_sysfs_rda_audio_format(struct device *dev, return ret; } +static ssize_t ep92_sysfs_rda_dsd_rate(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret = 0; + int val; + struct ep92_pdata *ep92 = dev_get_drvdata(dev); + + if (!ep92 || !ep92->codec) { + dev_err(dev, "%s: device error\n", __func__); + return -ENODEV; + } + + val = ep92_dsd_freq_table[(ep92->ai.system_status_1 & + EP92_AI_DSD_RATE_MASK) >> EP92_AI_DSD_RATE_SHIFT]; + + ret = snprintf(buf, EP92_SYSFS_ENTRY_MAX_LEN, "%d\n", val); + dev_dbg(dev, "%s: '%d'\n", __func__, val); + + return ret; +} + static ssize_t ep92_sysfs_rda_audio_rate(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1621,6 +1665,7 @@ static DEVICE_ATTR(cec_volume, 0644, ep92_sysfs_rda_cec_volume, static DEVICE_ATTR(runout, 0444, ep92_sysfs_rda_runout, NULL); static DEVICE_ATTR(force_inactive, 0644, ep92_sysfs_rda_force_inactive, ep92_sysfs_wta_force_inactive); +static DEVICE_ATTR(dsd_rate, 0444, ep92_sysfs_rda_dsd_rate, NULL); static struct attribute *ep92_fs_attrs[] = { &dev_attr_chipid.attr, @@ -1647,6 +1692,7 @@ static struct attribute *ep92_fs_attrs[] = { &dev_attr_cec_volume.attr, &dev_attr_runout.attr, &dev_attr_force_inactive.attr, + &dev_attr_dsd_rate.attr, NULL, }; diff --git a/asoc/codecs/ep92/ep92.h b/asoc/codecs/ep92/ep92.h index 18cb0105f56c..22384fbb6783 100644 --- a/asoc/codecs/ep92/ep92.h +++ b/asoc/codecs/ep92/ep92.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #ifndef __EP92_H__ @@ -175,6 +175,10 @@ static struct reg_default ep92_reg_defaults[] = { #define EP92_AI_PREEMPH_MASK 0x38 #define EP92_AI_CH_COUNT_MASK 0x07 #define EP92_AI_CH_ALLOC_MASK 0xff +#define EP92_AI_DSD_ADO_SHIFT 4 +#define EP92_AI_DSD_ADO_MASK 0x10 +#define EP92_AI_DSD_RATE_SHIFT 4 +#define EP92_AI_DSD_RATE_MASK 0x30 #define EP92_2CHOICE_MASK 1 #define EP92_GC_CEC_VOLUME_MIN 0 -- GitLab From 0ec67dd21a428e016095bc6cc86917fa276ffc33 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 27 Nov 2019 00:22:32 +0530 Subject: [PATCH 1367/1645] ASoC: wcd938x: Add support for ADC modes Different ADC modes need different clock rate. Update clock rate based on the ADC mode. Change-Id: Idaeda95a15e99038927de115727ece897bba7c29 Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd938x/internal.h | 3 +- asoc/codecs/wcd938x/wcd938x.c | 163 ++++++++++++++++++++++++++------- 2 files changed, 134 insertions(+), 32 deletions(-) diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index 46d61a00db9d..c59d5b882baf 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #ifndef _WCD938X_INTERNAL_H @@ -70,6 +70,7 @@ struct wcd938x_priv { bool comp1_enable; bool comp2_enable; bool ldoh; + bool bcs_dis; struct irq_domain *virq; struct wcd_irq_info irq_info; u32 rx_clk_cnt; diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 60ef2bf48764..191db8dc4ebb 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -69,6 +69,16 @@ enum { ADC_MODE_ULP2, }; +static u8 tx_mode_bit[] = { + [ADC_MODE_INVALID] = 0x00, + [ADC_MODE_HIFI] = 0x01, + [ADC_MODE_LO_HIF] = 0x02, + [ADC_MODE_NORMAL] = 0x04, + [ADC_MODE_LP] = 0x08, + [ADC_MODE_ULP1] = 0x10, + [ADC_MODE_ULP2] = 0x20, +}; + static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); @@ -141,26 +151,56 @@ static int wcd938x_swr_slv_get_current_bank(struct swr_device *dev, u8 devnum) return ((bank & 0x40) ? 1: 0); } -static int wcd938x_swr_slv_set_host_clk_div2(struct swr_device *dev, - u8 devnum, int bank) +static int wcd938x_get_clk_rate(int mode) { - u8 val = (bank ? 1 : 0); + int rate; + + switch (mode) { + case ADC_MODE_ULP2: + rate = SWR_CLK_RATE_0P6MHZ; + break; + case ADC_MODE_ULP1: + rate = SWR_CLK_RATE_1P2MHZ; + break; + case ADC_MODE_LP: + rate = SWR_CLK_RATE_4P8MHZ; + break; + case ADC_MODE_NORMAL: + case ADC_MODE_LO_HIF: + case ADC_MODE_HIFI: + case ADC_MODE_INVALID: + default: + rate = SWR_CLK_RATE_9P6MHZ; + break; + } - return (swr_write(dev, devnum, - (SWR_SCP_HOST_CLK_DIV2_CTL_BANK + (0x10 * bank)), &val)); + return rate; } static int wcd938x_set_swr_clk_rate(struct snd_soc_component *component, - int mode, int bank) + int rate, int bank) { u8 mask = (bank ? 0xF0 : 0x0F); u8 val = 0; - if ((mode == ADC_MODE_ULP1) || (mode == ADC_MODE_ULP2)) + switch (rate) { + case SWR_CLK_RATE_0P6MHZ: val = (bank ? 0x60 : 0x06); - else + break; + case SWR_CLK_RATE_1P2MHZ: + val = (bank ? 0x50 : 0x05); + break; + case SWR_CLK_RATE_2P4MHZ: + val = (bank ? 0x30 : 0x03); + break; + case SWR_CLK_RATE_4P8MHZ: + val = (bank ? 0x10 : 0x01); + break; + case SWR_CLK_RATE_9P6MHZ: + default: val = 0x00; - + break; + } snd_soc_component_update_bits(component, WCD938X_DIGITAL_SWR_TX_CLK_RATE, mask, val); @@ -354,7 +394,8 @@ static int wcd938x_parse_port_mapping(struct device *dev, } static int wcd938x_tx_connect_port(struct snd_soc_component *component, - u8 slv_port_type, u8 enable) + u8 slv_port_type, int clk_rate, + u8 enable) { struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); u8 port_id, num_ch, ch_mask, port_type; @@ -365,6 +406,8 @@ static int wcd938x_tx_connect_port(struct snd_soc_component *component, ret = wcd938x_set_port_params(component, slv_port_type, &port_id, &num_ch, &ch_mask, &ch_rate, &port_type, CODEC_TX); + if (clk_rate) + ch_rate = clk_rate; if (ret) return ret; @@ -1325,10 +1368,12 @@ static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w, /* enable clock scaling */ snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_DMIC_CTL, 0x06, 0x06); - wcd938x_tx_connect_port(component, DMIC0 + (w->shift), true); + wcd938x_tx_connect_port(component, DMIC0 + (w->shift), + SWR_CLK_RATE_2P4MHZ, true); break; case SND_SOC_DAPM_POST_PMD: - wcd938x_tx_connect_port(component, DMIC0 + (w->shift), false); + wcd938x_tx_connect_port(component, DMIC0 + (w->shift), 0, + false); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_AMIC_CTL, (0x01 << dmic_ctl_shift), @@ -1449,32 +1494,54 @@ static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w, struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); int ret = 0; int bank = 0; - int mode = 0; + u8 mode = 0; + int i = 0; + int rate = 0; + + bank = (wcd938x_swr_slv_get_current_bank(wcd938x->tx_swr_dev, + wcd938x->tx_swr_dev->dev_num) ? 0 : 1); - bank = wcd938x_swr_slv_get_current_bank(wcd938x->tx_swr_dev, - wcd938x->tx_swr_dev->dev_num); - wcd938x_swr_slv_set_host_clk_div2(wcd938x->tx_swr_dev, - wcd938x->tx_swr_dev->dev_num, bank); switch (event) { case SND_SOC_DAPM_PRE_PMU: + if (strnstr(w->name, "ADC", sizeof("ADC"))) { + if (test_bit(WCD_ADC1, &wcd938x->status_mask)) + mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC1]]; + if (test_bit(WCD_ADC2, &wcd938x->status_mask)) + mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC2]]; + if (test_bit(WCD_ADC3, &wcd938x->status_mask)) + mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC3]]; + if (test_bit(WCD_ADC4, &wcd938x->status_mask)) + mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC4]]; + + if (mode != 0) { + for (i = 0; i < ADC_MODE_ULP2; i++) { + if (mode & (1 << i)) { + i++; + break; + } + } + } + rate = wcd938x_get_clk_rate(i); + wcd938x_set_swr_clk_rate(component, rate, bank); + } ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev, wcd938x->tx_swr_dev->dev_num, true); - if (test_bit(WCD_ADC1, &wcd938x->status_mask)) - mode |= wcd938x->tx_mode[WCD_ADC1]; - if (test_bit(WCD_ADC2, &wcd938x->status_mask)) - mode |= wcd938x->tx_mode[WCD_ADC2]; - if (test_bit(WCD_ADC3, &wcd938x->status_mask)) - mode |= wcd938x->tx_mode[WCD_ADC3]; - if (test_bit(WCD_ADC4, &wcd938x->status_mask)) - mode |= wcd938x->tx_mode[WCD_ADC4]; - wcd938x_set_swr_clk_rate(component, mode, bank); + if (strnstr(w->name, "ADC", sizeof("ADC"))) { + /* Copy clk settings to active bank */ + wcd938x_set_swr_clk_rate(component, rate, !bank); + } break; case SND_SOC_DAPM_POST_PMD: + if (strnstr(w->name, "ADC", sizeof("ADC"))) { + rate = wcd938x_get_clk_rate(ADC_MODE_INVALID); + wcd938x_set_swr_clk_rate(component, rate, !bank); + } ret = swr_slvdev_datapath_control(wcd938x->tx_swr_dev, wcd938x->tx_swr_dev->dev_num, false); - wcd938x_set_swr_clk_rate(component, ADC_MODE_INVALID, bank); + if (strnstr(w->name, "ADC", sizeof("ADC"))) + wcd938x_set_swr_clk_rate(component, rate, bank); break; }; @@ -1521,6 +1588,7 @@ static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + int clk_rate = 0; dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -1532,19 +1600,25 @@ static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); set_bit(w->shift, &wcd938x->status_mask); + clk_rate = wcd938x_get_clk_rate(wcd938x->tx_mode[w->shift]); /* Enable BCS for Headset mic */ if (w->shift == 1 && !(snd_soc_component_read32(component, WCD938X_TX_NEW_AMIC_MUX_CFG) & 0x80)) { - wcd938x_tx_connect_port(component, MBHC, true); + if (!wcd938x->bcs_dis) + wcd938x_tx_connect_port(component, MBHC, + SWR_CLK_RATE_4P8MHZ, true); set_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask); } - wcd938x_tx_connect_port(component, ADC1 + (w->shift), true); + wcd938x_tx_connect_port(component, ADC1 + (w->shift), clk_rate, + true); break; case SND_SOC_DAPM_POST_PMD: - wcd938x_tx_connect_port(component, ADC1 + (w->shift), false); + wcd938x_tx_connect_port(component, ADC1 + (w->shift), 0, false); if (w->shift == 1 && test_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask)) { - wcd938x_tx_connect_port(component, MBHC, false); + if (!wcd938x->bcs_dis) + wcd938x_tx_connect_port(component, MBHC, 0, + false); clear_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask); } snd_soc_component_update_bits(component, @@ -2305,6 +2379,30 @@ static int wcd938x_ldoh_put(struct snd_kcontrol *kcontrol, return 0; } +static int wcd938x_bcs_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wcd938x->bcs_dis; + + return 0; +} + +static int wcd938x_bcs_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + wcd938x->bcs_dis = ucontrol->value.integer.value[0]; + + return 0; +} + static const char * const tx_mode_mux_text_wcd9380[] = { "ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP", }; @@ -2391,6 +2489,9 @@ static const struct snd_kcontrol_new wcd938x_snd_controls[] = { SOC_SINGLE_EXT("LDOH Enable", SND_SOC_NOPM, 0, 1, 0, wcd938x_ldoh_get, wcd938x_ldoh_put), + SOC_SINGLE_EXT("ADC2_BCS Disable", SND_SOC_NOPM, 0, 1, 0, + wcd938x_bcs_get, wcd938x_bcs_put), + SOC_SINGLE_TLV("HPHL Volume", WCD938X_HPH_L_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("HPHR Volume", WCD938X_HPH_R_EN, 0, 20, 1, line_gain), SOC_SINGLE_TLV("ADC1 Volume", WCD938X_ANA_TX_CH1, 0, 20, 0, -- GitLab From 3c6c7b6b0f56885c388fed3503da2b0a8b68dd18 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 13 Jan 2020 14:35:30 +0800 Subject: [PATCH 1368/1645] asoc: bolero: check if va is enabled when register/deregister wakeup irq When LPI SVA is enabled, start recording and stop LPI SVA, wakeup irq is not deregistered as tx_swr_clk_cnt is not 0. Add new check for va_swr_clk_cnt to resolve the issue. Change-Id: I441394f26b42f554169400194d021309ef70af9e Signed-off-by: Meng Wang --- asoc/codecs/bolero/tx-macro.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index a27c3e1a8111..3a47257615aa 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -2312,7 +2312,8 @@ static int tx_macro_register_event_listener(struct snd_soc_component *component, "%s: priv is null for macro!\n", __func__); return -EINVAL; } - if (tx_priv->swr_ctrl_data && !tx_priv->tx_swr_clk_cnt) { + if (tx_priv->swr_ctrl_data && + (!tx_priv->tx_swr_clk_cnt || !tx_priv->va_swr_clk_cnt)) { if (enable) { ret = swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, -- GitLab From 2825fce018598073b9e49a81cca5ac687572bdbf Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 13 Jan 2020 15:17:21 +0800 Subject: [PATCH 1369/1645] asoc: bolero: enable swr DMIC clk_div after tx mclk is enabled If swr DMIC clk_div is enabled before enabling tx mclk and LPASS power collapse happens, volatile swr DMIC clk_div registers would be cleared and swr DMIC would not work. Make this change to enable swr DMIC clk_div after tx mclk is enabled Change-Id: Ie9e7e8c74dc0e013898f3fd8b62344a670ad6664 Signed-off-by: Meng Wang --- asoc/codecs/bolero/tx-macro.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index a27c3e1a8111..a9efa300412f 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -835,6 +835,8 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, int unmute_delay = TX_MACRO_DMIC_UNMUTE_DELAY_MS; struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; + u16 adc_mux_reg = 0, adc_reg = 0, adc_n = 0; + u16 dmic_clk_reg = 0; if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) return -EINVAL; @@ -855,6 +857,22 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + + TX_MACRO_ADC_MUX_CFG_OFFSET * decimator; + if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) { + adc_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + + TX_MACRO_ADC_MUX_CFG_OFFSET * decimator; + adc_n = snd_soc_component_read32(component, adc_reg) & + TX_MACRO_SWR_MIC_MUX_SEL_MASK; + if (adc_n >= BOLERO_ADC_MAX) { + dmic_clk_reg = + BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL + + ((adc_n - 5) / 2) * 4; + snd_soc_component_update_bits(component, + dmic_clk_reg, + 0x0E, tx_priv->dmic_clk_div << 0x1); + } + } snd_soc_component_update_bits(component, dec_cfg_reg, 0x06, tx_priv->dec_mode[decimator] << TX_MACRO_ADC_MODE_CFG0_SHIFT); -- GitLab From 116ac37836f1c17eb2ed42ef02c75bfdb818e198 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 14 Jan 2020 12:55:18 +0530 Subject: [PATCH 1370/1645] ASoC: bolero: Fix higher btn press noise issue There is higher noise during headset btn press on some headsets. Change hold time after button release to 600ms to resolve the noise. Change-Id: I87e5e13ce39849090da3d3e50ec53e7fd5fdc0e7 Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/tx-macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index a27c3e1a8111..bc8b5eb9461f 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -2693,7 +2693,7 @@ static int tx_macro_validate_dmic_sample_rate(u32 dmic_sample_rate, } static const struct tx_macro_reg_mask_val tx_macro_reg_init[] = { - {BOLERO_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x02}, + {BOLERO_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x0A}, }; static int tx_macro_init(struct snd_soc_component *component) -- GitLab From ae5c363ae22f00e5e3e3652698efa50e4a2a0630 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 27 Nov 2019 06:52:06 +0530 Subject: [PATCH 1371/1645] soc: soundwire: Update bus clock frequency based on usecase Some usecase needs soundwire bus clock frequency to run at lower clock rate for better power and performance. Update soundwire bus clock frequency based on usecase. Change-Id: I2e786d9f5d5d2ec3841daa934802eeafa79a8f6c Signed-off-by: Sudheer Papothi --- include/soc/soundwire.h | 9 ++- include/soc/swr-wcd.h | 3 +- soc/swr-mstr-ctrl.c | 122 ++++++++++++++++++++++++++++++++++++---- soc/swr-mstr-ctrl.h | 7 ++- 4 files changed, 124 insertions(+), 17 deletions(-) diff --git a/include/soc/soundwire.h b/include/soc/soundwire.h index bb71a357366e..3e61da12b1dd 100644 --- a/include/soc/soundwire.h +++ b/include/soc/soundwire.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #ifndef _LINUX_SOUNDWIRE_H @@ -10,6 +10,13 @@ #include #include +#define SWR_CLK_RATE_0P6MHZ 600000 +#define SWR_CLK_RATE_1P2MHZ 1200000 +#define SWR_CLK_RATE_2P4MHZ 2400000 +#define SWR_CLK_RATE_4P8MHZ 4800000 +#define SWR_CLK_RATE_9P6MHZ 9600000 +#define SWR_CLK_RATE_11P2896MHZ 1128960 + extern struct bus_type soundwire_type; /* Soundwire supports max. of 8 channels per port */ diff --git a/include/soc/swr-wcd.h b/include/soc/swr-wcd.h index 4ec509442858..8ed9f0a05e3b 100644 --- a/include/soc/swr-wcd.h +++ b/include/soc/swr-wcd.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015, 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2015, 2017-2020 The Linux Foundation. All rights reserved. */ #ifndef _LINUX_SWR_WCD_H @@ -32,6 +32,7 @@ struct swr_mstr_port { }; #define MCLK_FREQ 9600000 +#define MCLK_FREQ_LP 600000 #define MCLK_FREQ_NATIVE 11289600 #if (IS_ENABLED(CONFIG_SOUNDWIRE_WCD_CTRL) || \ diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 2ab1bee1dd11..cd3805fc5578 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #include @@ -25,6 +25,8 @@ #include "swrm_registers.h" #include "swr-mstr-ctrl.h" +#define SWR_NUM_PORTS 4 /* TODO - Get this info from DT */ + #define SWRM_FRAME_SYNC_SEL 4000 /* 4KHz */ #define SWRM_FRAME_SYNC_SEL_NATIVE 3675 /* 3.675KHz */ #define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700 @@ -94,6 +96,42 @@ static void swrm_unlock_sleep(struct swr_mstr_ctrl *swrm); static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr); static void swr_master_write(struct swr_mstr_ctrl *swrm, u16 reg_addr, u32 val); + +static u8 swrm_get_clk_div(int mclk_freq, int bus_clk_freq) +{ + int clk_div = 0; + u8 div_val = 0; + + if (!mclk_freq || !bus_clk_freq) + return 0; + + clk_div = (mclk_freq / bus_clk_freq); + + switch (clk_div) { + case 32: + div_val = 5; + break; + case 16: + div_val = 4; + break; + case 8: + div_val = 3; + break; + case 4: + div_val = 2; + break; + case 2: + div_val = 1; + break; + case 1: + default: + div_val = 0; + break; + } + + return div_val; +} + static bool swrm_is_msm_variant(int val) { return (val == SWRM_VERSION_1_3); @@ -955,6 +993,49 @@ static bool swrm_remove_from_group(struct swr_master *master) return is_removed; } +int swrm_get_clk_div_rate(int mclk_freq, int bus_clk_freq) +{ + if (!bus_clk_freq) + return mclk_freq; + + if (mclk_freq == SWR_CLK_RATE_9P6MHZ) { + if (bus_clk_freq <= SWR_CLK_RATE_0P6MHZ) + bus_clk_freq = SWR_CLK_RATE_0P6MHZ; + else if (bus_clk_freq <= SWR_CLK_RATE_1P2MHZ) + bus_clk_freq = SWR_CLK_RATE_1P2MHZ; + else if (bus_clk_freq <= SWR_CLK_RATE_2P4MHZ) + bus_clk_freq = SWR_CLK_RATE_2P4MHZ; + else if(bus_clk_freq <= SWR_CLK_RATE_4P8MHZ) + bus_clk_freq = SWR_CLK_RATE_4P8MHZ; + else if(bus_clk_freq <= SWR_CLK_RATE_9P6MHZ) + bus_clk_freq = SWR_CLK_RATE_9P6MHZ; + } else if (mclk_freq == SWR_CLK_RATE_11P2896MHZ) + bus_clk_freq = SWR_CLK_RATE_11P2896MHZ; + + return bus_clk_freq; +} + +static int swrm_update_bus_clk(struct swr_mstr_ctrl *swrm) +{ + int ret = 0; + int agg_clk = 0; + int i; + + for (i = 0; i < SWR_MSTR_PORT_LEN; i++) + agg_clk += swrm->mport_cfg[i].ch_rate; + + if (agg_clk) + swrm->bus_clk = swrm_get_clk_div_rate(swrm->mclk_freq, + agg_clk); + else + swrm->bus_clk = swrm->mclk_freq; + + dev_dbg(swrm->dev, "%s: all_port_clk: %d, bus_clk: %d\n", + __func__, agg_clk, swrm->bus_clk); + + return ret; +} + static void swrm_disable_ports(struct swr_master *master, u8 bank) { @@ -1221,13 +1302,15 @@ static void swrm_apply_port_config(struct swr_master *master) static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) { u8 bank; - u32 value, n_row, n_col; + u32 value = 0, n_row = 0, n_col = 0; u32 row = 0, col = 0; + int bus_clk_div_factor; int ret; u8 ssp_period = 0; struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK | SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK | + SWRM_MCP_FRAME_CTRL_BANK_CLK_DIV_VALUE_BMSK | SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_BMSK); u8 inactive_bank; int frame_sync = SWRM_FRAME_SYNC_SEL; @@ -1288,13 +1371,17 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) clear_bit(DISABLE_PENDING, &swrm->port_req_pending); swrm_disable_ports(master, bank); } - dev_dbg(swrm->dev, "%s: enable: %d, cfg_devs: %d\n", - __func__, enable, swrm->num_cfg_devs); + dev_dbg(swrm->dev, "%s: enable: %d, cfg_devs: %d freq %d\n", + __func__, enable, swrm->num_cfg_devs, swrm->mclk_freq); if (enable) { /* set col = 16 */ n_col = SWR_MAX_COL; col = SWRM_COL_16; + if (swrm->bus_clk == MCLK_FREQ_LP) { + n_col = SWR_MIN_COL; + col = SWRM_COL_02; + } } else { /* * Do not change to col = 2 if there are still active ports @@ -1309,25 +1396,26 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) } /* Use default 50 * x, frame shape. Change based on mclk */ if (swrm->mclk_freq == MCLK_FREQ_NATIVE) { - dev_dbg(swrm->dev, "setting 64 x %d frameshape\n", - n_col ? 16 : 2); + dev_dbg(swrm->dev, "setting 64 x %d frameshape\n", col); n_row = SWR_ROW_64; row = SWRM_ROW_64; frame_sync = SWRM_FRAME_SYNC_SEL_NATIVE; } else { - dev_dbg(swrm->dev, "setting 50 x %d frameshape\n", - n_col ? 16 : 2); + dev_dbg(swrm->dev, "setting 50 x %d frameshape\n", col); n_row = SWR_ROW_50; row = SWRM_ROW_50; frame_sync = SWRM_FRAME_SYNC_SEL; } ssp_period = swrm_get_ssp_period(swrm, row, col, frame_sync); - dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period); - + bus_clk_div_factor = swrm_get_clk_div(swrm->mclk_freq, swrm->bus_clk); + dev_dbg(swrm->dev, "%s: ssp_period: %d, bus_clk_div:%d \n", __func__, + ssp_period, bus_clk_div_factor); value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank)); value &= (~mask); value |= ((n_row << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | (n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) | + (bus_clk_div_factor << + SWRM_MCP_FRAME_CTRL_BANK_CLK_DIV_VALUE_SHFT) | ((ssp_period - 1) << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT)); swr_master_write(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value); @@ -1431,6 +1519,11 @@ static int swrm_connect_port(struct swr_master *master, mport->port_en = true; mport->req_ch |= mstr_ch_msk; master->port_en_mask |= (1 << mstr_port_id); + if (swrm->clk_stop_mode0_supp && + (mport->ch_rate < portinfo->ch_rate[i])) { + mport->ch_rate = portinfo->ch_rate[i]; + swrm_update_bus_clk(swrm); + } } master->num_port += portinfo->num_port; set_bit(ENABLE_PENDING, &swrm->port_req_pending); @@ -1493,6 +1586,10 @@ static int swrm_disconnect_port(struct swr_master *master, } port_req->req_ch &= ~portinfo->ch_en[i]; mport->req_ch &= ~mstr_ch_mask; + if (swrm->clk_stop_mode0_supp && !mport->req_ch) { + mport->ch_rate = 0; + swrm_update_bus_clk(swrm); + } } master->num_port -= portinfo->num_port; set_bit(DISABLE_PENDING, &swrm->port_req_pending); @@ -2402,9 +2499,10 @@ static int swrm_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "%s: Looking up %s property failed\n", __func__, "qcom,swr-num-dev"); } else { - if (swrm->num_dev > SWR_MAX_SLAVE_DEVICES) { + if (swrm->num_dev > SWRM_NUM_AUTO_ENUM_SLAVES) { dev_err(&pdev->dev, "%s: num_dev %d > max limit %d\n", - __func__, swrm->num_dev, SWR_MAX_SLAVE_DEVICES); + __func__, swrm->num_dev, + SWRM_NUM_AUTO_ENUM_SLAVES); ret = -EINVAL; goto err_pdata_fail; } diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index c404fc6f9664..ce0b64d57766 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #ifndef _SWR_WCD_CTRL_H @@ -26,6 +26,7 @@ #define SWR_ROW_48 0 #define SWR_ROW_50 1 #define SWR_ROW_64 3 +#define SWR_COL_04 1 /* Cols = 4 */ #define SWR_MAX_COL 7 /* Cols = 16 */ #define SWR_MIN_COL 0 /* Cols = 2 */ @@ -42,7 +43,7 @@ #define SWR_MAX_CH_PER_PORT 8 -#define SWR_MAX_SLAVE_DEVICES 11 +#define SWRM_NUM_AUTO_ENUM_SLAVES 6 enum { SWR_MSTR_PAUSE, @@ -81,7 +82,6 @@ struct swrm_mports { bool port_en; u8 ch_en; u8 req_ch; - u8 ch_rate; u8 offset1; u8 offset2; u8 sinterval; @@ -91,6 +91,7 @@ struct swrm_mports { u8 blk_pack_mode; u8 word_length; u8 lane_ctrl; + u32 ch_rate; }; struct swrm_port_type { -- GitLab From eccd448c98c8437712e98b66cbd13e0e261fc1ba Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 19 Dec 2019 12:19:12 +0530 Subject: [PATCH 1372/1645] ASoC: Add doa tracking params only for LE platforms Doa tracking params are applicable only for LE platforms. Add respective check for the same. Also add config to enable doa params for LE. Change-Id: Ia8c2fd095deb44a3dd0b958da0b73c94dbc7d819 Signed-off-by: Vatsal Bucha --- asoc/msm-pcm-routing-v2.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 3d7c568959c3..bd9c9503b767 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -22970,6 +22970,9 @@ static const struct snd_kcontrol_new msm_source_tracking_controls[] = { .info = msm_source_tracking_info, .get = msm_audio_source_tracking_get, }, +}; + +static const struct snd_kcontrol_new msm_source_doa_tracking_controls[] = { { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -29712,6 +29715,20 @@ static const struct snd_pcm_ops msm_routing_pcm_ops = { .prepare = msm_pcm_routing_prepare, }; +#ifdef CONFIG_DOA_PARAMS_ENABLED +void msm_routing_add_doa_control(struct snd_soc_component *component) +{ + snd_soc_add_component_controls(component, + msm_source_doa_tracking_controls, + ARRAY_SIZE(msm_source_doa_tracking_controls)); +} +#else +void msm_routing_add_doa_control(struct snd_soc_component *component) +{ + return; +} +#endif + /* Not used but frame seems to require it */ static int msm_routing_probe(struct snd_soc_component *component) { @@ -29781,6 +29798,8 @@ static int msm_routing_probe(struct snd_soc_component *component) msm_routing_be_dai_name_table_mixer_controls, ARRAY_SIZE(msm_routing_be_dai_name_table_mixer_controls)); + /* Add doa control based on config */ + msm_routing_add_doa_control(component); snd_soc_add_component_controls(component, msm_source_tracking_controls, ARRAY_SIZE(msm_source_tracking_controls)); snd_soc_add_component_controls(component, adm_channel_config_controls, -- GitLab From 4f941546d770834686856fd95f1b923e3e2b5bfb Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Mon, 13 Jan 2020 14:37:40 -0800 Subject: [PATCH 1373/1645] ASoC: msm: update quin tdm slot for single lane Update QUIN TDM slot mapping for single lane configuration. Update QUAT TDM TX slot mapping for 8 channel capture over multilane configuration. Change-Id: If0f2792637eb513b7f64a291fc27c475f2c12683 --- asoc/sa6155.c | 7 +++---- asoc/sa8155.c | 16 +++++++--------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/asoc/sa6155.c b/asoc/sa6155.c index a69005cab49a..d242738d1a59 100644 --- a/asoc/sa6155.c +++ b/asoc/sa6155.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -266,7 +266,7 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ }, { /* QUAT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 16}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* TX_0 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ @@ -469,8 +469,7 @@ static unsigned int tdm_tx_slot_offset {28, 0xFFFF}, }, {/* QUAT TDM */ - {0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*MIC ARR*/ + {0, 8, 16, 24, 4, 12, 20, 28, 0xFFFF}, /*8 CH MIC ARR*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ diff --git a/asoc/sa8155.c b/asoc/sa8155.c index 17cc77580cda..2e5444707cf7 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. */ /* * Copyright 2011, The Android Open Source Project @@ -258,7 +258,7 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ }, { /* QUAT TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 16}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* TX_0 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ @@ -268,7 +268,7 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ }, { /* QUIN TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 16}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* TX_0 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ @@ -417,8 +417,8 @@ static unsigned int tdm_rx_slot_offset {60,0xFFFF}, }, {/* QUIN TDM */ - {0, 8, 16, 24, 32, 40, 48, 56, - 4, 12, 20, 28, 36, 44, 52, 60, 0xFFFF}, /*16 CH SPKR*/ + {0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF}, /*16 CH SPKR*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -462,8 +462,7 @@ static unsigned int tdm_tx_slot_offset {28, 0xFFFF}, }, {/* QUAT TDM */ - {0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*16 CH MIC ARR1*/ + {0, 8, 16, 24, 4, 12, 20, 28, 0xFFFF}, /*8 CH MIC ARR1*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -473,8 +472,7 @@ static unsigned int tdm_tx_slot_offset {60,0xFFFF}, }, {/* QUIN TDM */ - {0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*16 CH MIC ARR2*/ + {0, 4, 8, 12, 16, 20, 24, 28, 0xFFFF}, /*8 CH MIC ARR2*/ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ -- GitLab From 072b6f646e7782052f56ced90692dd1757c3fa78 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Mon, 2 Dec 2019 17:03:56 -0800 Subject: [PATCH 1374/1645] ASoC: add echo ref support for SENARY MI2S TX Add SENARY_MI2S_TX to ec_ref_rx and ext_ec_ref_rx so it can be used for Audio EC reference and Voice external EC reference. CRs-Fixed: 2576685 Change-Id: I08253e705f26293255eea41140fd3461ee300b6b Signed-off-by: Vignesh Kulothungan --- asoc/msm-pcm-routing-v2.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 3d7c568959c3..2c7bcbaa9659 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -5471,6 +5471,10 @@ static int get_ec_ref_port_id(int value, int *index) *index = 38; port_id = AFE_PORT_ID_SENARY_MI2S_RX; break; + case 39: + *index = 39; + port_id = AFE_PORT_ID_SENARY_MI2S_TX; + break; default: *index = 0; /* NONE */ pr_err("%s: Invalid value %d\n", __func__, value); @@ -5528,7 +5532,7 @@ static const char *const ec_ref_rx[] = { "None", "SLIM_RX", "I2S_RX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_2", "SLIM_7_RX", "RX_CDC_DMA_RX_0", "RX_CDC_DMA_RX_1", "RX_CDC_DMA_RX_2", "RX_CDC_DMA_RX_3", "TX_CDC_DMA_TX_0", "TERT_TDM_RX_2", "SEC_TDM_TX_0", - "DISPLAY_PORT1", "SEN_MI2S_RX", + "DISPLAY_PORT1", "SEN_MI2S_RX", "SENARY_MI2S_TX", }; static const struct soc_enum msm_route_ec_ref_rx_enum[] = { @@ -5761,7 +5765,7 @@ static const char * const ext_ec_ref_rx[] = {"NONE", "PRI_MI2S_TX", "SEC_MI2S_TX", "TERT_MI2S_TX", "QUAT_MI2S_TX", "QUIN_MI2S_TX", "SLIM_1_TX", "PRI_TDM_TX", - "SEC_TDM_TX"}; + "SEC_TDM_TX", "SENARY_MI2S_TX"}; static const struct soc_enum msm_route_ext_ec_ref_rx_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ext_ec_ref_rx), ext_ec_ref_rx), -- GitLab From fe39949b15c0d1bdfb0de231bf8a4593ca532778 Mon Sep 17 00:00:00 2001 From: Ramu Gottipati Date: Thu, 9 Jan 2020 10:57:33 +0530 Subject: [PATCH 1375/1645] dsp: Avoid configuring PSPD channel mixer if PSPD is already configured Observing audio glitch issue while trying to apply PSPD channel mixer coefficients for already applied COPP port. To fix this, added check condition to retun 0 without applying PSPD. Change-Id: I3825cacfd888f153144cc5d73eb274f4fbf5d8bc Signed-off-by: Ramu Gottipati --- dsp/q6adm.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 7dfb35cccfd5..9a4a7f914a35 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include #include @@ -513,6 +513,17 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, pr_err("%s: Invalid port_id %#x\n", __func__, port_id); return -EINVAL; } + + /* + * check if PSPD is already configured + * if it is configured already, return 0 without applying PSPD. + */ + if (atomic_read(&this_adm.copp.cnt[port_idx][copp_idx]) > 1) { + pr_debug("%s: copp.cnt:%#x\n", __func__, + atomic_read(&this_adm.copp.cnt[port_idx][copp_idx])); + return 0; + } + /* * First 8 bytes are 4 bytes as rule number, 2 bytes as output * channel and 2 bytes as input channel. -- GitLab From 3cc1e9ec645e276a7386150df4e656e14dae107e Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 21 Jan 2020 11:00:55 +0530 Subject: [PATCH 1376/1645] ASoC: wcd938x: Update hardware sequence for LDOL voltage Update wcd938x codec hardware sequence for LDOL voltage. Change-Id: I863c0832277d3d0533cdd97f15d1576c47cc4d1e Signed-off-by: Sudheer Papothi --- asoc/codecs/wcd938x/wcd938x.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 191db8dc4ebb..faa264f92b59 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -265,6 +265,9 @@ static int wcd938x_init_reg(struct snd_soc_component *component) WCD938X_MICB4_TEST_CTL_1, 0xE0, 0xE0); snd_soc_component_update_bits(component, WCD938X_TX_3_4_TEST_BLK_EN2, 0x01, 0x00); + snd_soc_component_update_bits(component, WCD938X_SLEEP_CTL, 0x0E, + ((snd_soc_component_read32(component, + WCD938X_DIGITAL_EFUSE_REG_30) & 0x07) << 1)); return 0; } -- GitLab From f08f2ac21bcdaa44caf2aa4394fbc88a86163ea4 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 17 Jan 2020 21:23:42 +0530 Subject: [PATCH 1377/1645] asoc: codecs: Update va_macro fix for SVA for bolero 2.1 For bolero 2.1 with SWR_TX in va macro, update SVA fixes. Change-Id: I250df0fe476bc2c0439ab491a17dea2e7ac18707 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/va-macro.c | 91 ++++++++++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 11 deletions(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 3493a6532c40..486f9fbc4094 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -342,12 +342,11 @@ static int va_macro_event_handler(struct snd_soc_component *component, return 0; } -static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w, +static int va_macro_swr_clk_event_v2(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - int ret = 0; struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; @@ -355,13 +354,46 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w, return -EINVAL; dev_dbg(va_dev, "%s: event = %d\n", __func__, event); + switch (event) { case SND_SOC_DAPM_PRE_PMU: va_priv->va_swr_clk_cnt++; + break; + case SND_SOC_DAPM_POST_PMD: + va_priv->va_swr_clk_cnt--; + break; + default: + break; + } + return 0; +} + +static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + int ret = 0; + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + int clk_src = 0; + + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) + return -EINVAL; + + dev_dbg(va_dev, "%s: event = %d, lpi_enable = %d\n", + __func__, event, va_priv->lpi_enable); + + if (!va_priv->lpi_enable) + return ret; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: if (va_priv->swr_ctrl_data) { + clk_src = CLK_SRC_VA_RCG; ret = swrm_wcd_notify( va_priv->swr_ctrl_data[0].va_swr_pdev, - SWR_REQ_CLK_SWITCH, NULL); + SWR_REQ_CLK_SWITCH, &clk_src); if (ret) dev_dbg(va_dev, "%s: clock switch failed\n", __func__); @@ -373,14 +405,14 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w, msm_cdc_pinctrl_set_wakeup_capable( va_priv->va_swr_gpio_p, true); if (va_priv->swr_ctrl_data) { + clk_src = CLK_SRC_TX_RCG; ret = swrm_wcd_notify( va_priv->swr_ctrl_data[0].va_swr_pdev, - SWR_REQ_CLK_SWITCH, NULL); + SWR_REQ_CLK_SWITCH, &clk_src); if (ret) dev_dbg(va_dev, "%s: clock switch failed\n", __func__); } - va_priv->va_swr_clk_cnt--; break; default: dev_err(va_priv->dev, @@ -471,6 +503,7 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, int ret = 0; struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; + int clk_src = 0; if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; @@ -492,9 +525,22 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: if (va_priv->lpi_enable) { - if (bolero_tx_clk_switch(component, CLK_SRC_TX_RCG)) + if (va_priv->version == BOLERO_VERSION_2_1) { + if (va_priv->swr_ctrl_data) { + clk_src = CLK_SRC_TX_RCG; + ret = swrm_wcd_notify( + va_priv->swr_ctrl_data[0].va_swr_pdev, + SWR_REQ_CLK_SWITCH, &clk_src); + if (ret) + dev_dbg(va_dev, + "%s: clock switch failed\n", + __func__); + } + } else if (bolero_tx_clk_switch(component, + CLK_SRC_TX_RCG)) { dev_dbg(va_dev, "%s: clock switch failed\n", __func__); + } va_macro_mclk_enable(va_priv, 0, true); } else { bolero_tx_mclk_enable(component, 0); @@ -1849,6 +1895,10 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v2[] = { SND_SOC_DAPM_SUPPLY_S("VA_TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, va_macro_tx_swr_clk_event_v2, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, + va_macro_swr_clk_event_v2, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v3[] = { @@ -2175,6 +2225,12 @@ static const struct snd_soc_dapm_route va_audio_map_v3[] = { {"VA SMIC MUX3", "SWR_MIC11", "VA SWR_MIC11"}, }; +static const struct snd_soc_dapm_route va_audio_map_v2[] = { + {"VA_AIF1 CAP", NULL, "VA_SWR_CLK"}, + {"VA_AIF2 CAP", NULL, "VA_SWR_CLK"}, + {"VA_AIF3 CAP", NULL, "VA_SWR_CLK"}, +}; + static const struct snd_soc_dapm_route va_audio_map[] = { {"VA_AIF1 CAP", NULL, "VA_MCLK"}, {"VA_AIF2 CAP", NULL, "VA_MCLK"}, @@ -2473,6 +2529,8 @@ static const struct snd_kcontrol_new va_macro_snd_controls_common[] = { SOC_SINGLE_SX_TLV("VA_DEC1 Volume", BOLERO_CDC_VA_TX1_TX_VOL_CTL, 0, -84, 40, digital_gain), + SOC_SINGLE_EXT("LPI Enable", 0, 0, 1, 0, + va_macro_lpi_get, va_macro_lpi_put), }; static const struct snd_kcontrol_new va_macro_snd_controls_v3[] = { @@ -2613,14 +2671,25 @@ static int va_macro_init(struct snd_soc_component *component) __func__); return ret; } - if (va_priv->version == BOLERO_VERSION_2_0) + if (va_priv->version == BOLERO_VERSION_2_0) { ret = snd_soc_dapm_add_routes(dapm, va_audio_map_v3, ARRAY_SIZE(va_audio_map_v3)); - if (ret < 0) { - dev_err(va_dev, "%s: Failed to add routes\n", - __func__); - return ret; + if (ret < 0) { + dev_err(va_dev, "%s: Failed to add routes\n", + __func__); + return ret; + } + } + if (va_priv->version == BOLERO_VERSION_2_1) { + ret = snd_soc_dapm_add_routes(dapm, + va_audio_map_v2, + ARRAY_SIZE(va_audio_map_v2)); + if (ret < 0) { + dev_err(va_dev, "%s: Failed to add routes\n", + __func__); + return ret; + } } } else { ret = snd_soc_dapm_add_routes(dapm, va_audio_map, -- GitLab From f500a1d81e4376d67d7dfdc7cef27a96b75c08ce Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 16 Sep 2019 18:27:51 -0700 Subject: [PATCH 1378/1645] codecs: Enable clock voting logs to debug AHB/NOC issues Enable clock voting logs to debug stability issues. Change-Id: Ie1f995ab004778a81ea42baad15ea36858407e9a Signed-off-by: Aditya Bavanari --- asoc/codecs/audio-ext-clk-up.c | 12 +++++ asoc/codecs/bolero/bolero-cdc.c | 11 +++++ asoc/codecs/bolero/bolero-clk-rsc.c | 13 +++++ asoc/codecs/bolero/rx-macro.c | 8 ++++ asoc/codecs/bolero/tx-macro.c | 18 +++++++ asoc/codecs/bolero/va-macro.c | 1 + asoc/codecs/bolero/wsa-macro.c | 8 ++++ asoc/msm-dai-q6-v2.c | 1 + asoc/msm-pcm-routing-v2.c | 4 +- dsp/q6afe.c | 73 ++++++++++++++++++++++------- soc/pinctrl-lpi.c | 6 +++ soc/swr-mstr-ctrl.c | 49 ++++++++++++++++++- 12 files changed, 184 insertions(+), 20 deletions(-) diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c index 632f6744b245..fc3cb386f42c 100644 --- a/asoc/codecs/audio-ext-clk-up.c +++ b/asoc/codecs/audio-ext-clk-up.c @@ -70,6 +70,8 @@ static int audio_ext_clk_prepare(struct clk_hw *hw) if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS) && (clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX)) { clk_priv->clk_cfg.enable = 1; + trace_printk("%s: vote for %d clock\n", + __func__, clk_priv->clk_src); ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg); if (ret < 0) { pr_err_ratelimited("%s afe_set_digital_codec_core_clock failed\n", @@ -112,6 +114,8 @@ static void audio_ext_clk_unprepare(struct clk_hw *hw) if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS) && (clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX)) { clk_priv->clk_cfg.enable = 0; + trace_printk("%s: unvote for %d clock\n", + __func__, clk_priv->clk_src); ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg); if (ret < 0) pr_err_ratelimited("%s: afe_set_lpass_clk_cfg failed, ret = %d\n", @@ -146,6 +150,8 @@ static int lpass_hw_vote_prepare(struct clk_hw *hw) int ret; if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE) { + trace_printk("%s: vote for %d clock\n", + __func__, clk_priv->clk_src); ret = afe_vote_lpass_core_hw(AFE_LPASS_CORE_HW_MACRO_BLOCK, "LPASS_HW_MACRO", &clk_priv->lpass_core_hwvote_client_handle); @@ -157,6 +163,8 @@ static int lpass_hw_vote_prepare(struct clk_hw *hw) } if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_AUDIO_HW_VOTE) { + trace_printk("%s: vote for %d clock\n", + __func__, clk_priv->clk_src); ret = afe_vote_lpass_core_hw(AFE_LPASS_CORE_HW_DCODEC_BLOCK, "LPASS_HW_DCODEC", &clk_priv->lpass_audio_hwvote_client_handle); @@ -176,6 +184,8 @@ static void lpass_hw_vote_unprepare(struct clk_hw *hw) int ret = 0; if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE) { + trace_printk("%s: unvote for %d clock\n", + __func__, clk_priv->clk_src); ret = afe_unvote_lpass_core_hw( AFE_LPASS_CORE_HW_MACRO_BLOCK, clk_priv->lpass_core_hwvote_client_handle); @@ -186,6 +196,8 @@ static void lpass_hw_vote_unprepare(struct clk_hw *hw) } if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_AUDIO_HW_VOTE) { + trace_printk("%s: unvote for %d clock\n", + __func__, clk_priv->clk_src); ret = afe_unvote_lpass_core_hw( AFE_LPASS_CORE_HW_DCODEC_BLOCK, clk_priv->lpass_audio_hwvote_client_handle); diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index af22bb2bb35e..53640a23a09e 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -828,6 +828,7 @@ static int bolero_ssr_enable(struct device *dev, void *data) priv->component, BOLERO_MACRO_EVT_CLK_RESET, 0x0); } + trace_printk("%s: clk count reset\n", __func__); regcache_cache_only(priv->regmap, false); mutex_lock(&priv->clk_lock); priv->dev_up = true; @@ -838,6 +839,7 @@ static int bolero_ssr_enable(struct device *dev, void *data) /* Add a 100usec sleep to ensure last register write is done */ usleep_range(100,110); bolero_clk_rsc_enable_all_clocks(priv->clk_dev, false); + trace_printk("%s: regcache_sync done\n", __func__); /* call ssr event for supported macros */ for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { if (!priv->macro_params[macro_idx].event_handler) @@ -846,6 +848,7 @@ static int bolero_ssr_enable(struct device *dev, void *data) priv->component, BOLERO_MACRO_EVT_SSR_UP, 0x0); } + trace_printk("%s: SSR up events processed by all macros\n", __func__); bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_SSR_UP); return 0; } @@ -1374,6 +1377,8 @@ int bolero_runtime_resume(struct device *dev) } } priv->core_hw_vote_count++; + trace_printk("%s: hw vote count %d\n", + __func__, priv->core_hw_vote_count); audio_vote: if (priv->lpass_audio_hw_vote == NULL) { @@ -1390,6 +1395,8 @@ int bolero_runtime_resume(struct device *dev) } } priv->core_audio_vote_count++; + trace_printk("%s: audio vote count %d\n", + __func__, priv->core_audio_vote_count); done: mutex_unlock(&priv->vote_lock); @@ -1412,6 +1419,8 @@ int bolero_runtime_suspend(struct device *dev) dev_dbg(dev, "%s: Invalid lpass core hw node\n", __func__); } + trace_printk("%s: hw vote count %d\n", + __func__, priv->core_hw_vote_count); if (priv->lpass_audio_hw_vote != NULL) { if (--priv->core_audio_vote_count == 0) @@ -1422,6 +1431,8 @@ int bolero_runtime_suspend(struct device *dev) dev_dbg(dev, "%s: Invalid lpass audio hw node\n", __func__); } + trace_printk("%s: audio vote count %d\n", + __func__, priv->core_audio_vote_count); mutex_unlock(&priv->vote_lock); return 0; diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c index b8ed6641633c..292162481d5e 100644 --- a/asoc/codecs/bolero/bolero-clk-rsc.c +++ b/asoc/codecs/bolero/bolero-clk-rsc.c @@ -129,6 +129,8 @@ int bolero_rsc_clk_reset(struct device *dev, int clk_id) } dev_dbg(priv->dev, "%s: clock reset after ssr, count %d\n", __func__, count); + + trace_printk("%s: clock reset after ssr, count %d\n", __func__, count); while (count--) { clk_prepare_enable(priv->clk[clk_id]); clk_prepare_enable(priv->clk[clk_id + NPL_CLK_OFFSET]); @@ -238,6 +240,7 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv, char __iomem *clk_muxsel = NULL; int ret = 0; int default_clk_id = priv->default_clk_id[clk_id]; + u32 muxsel = 0; clk_muxsel = bolero_clk_rsc_get_clk_muxsel(priv, clk_id); if (!clk_muxsel) { @@ -269,6 +272,9 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv, } } iowrite32(0x1, clk_muxsel); + muxsel = ioread32(clk_muxsel); + trace_printk("%s: muxsel value after enable: %d\n", + __func__, muxsel); bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, false); } @@ -288,6 +294,9 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv, if (!ret) iowrite32(0x0, clk_muxsel); + muxsel = ioread32(clk_muxsel); + trace_printk("%s: muxsel value after disable: %d\n", + __func__, muxsel); if (priv->clk[clk_id + NPL_CLK_OFFSET]) clk_disable_unprepare( priv->clk[clk_id + NPL_CLK_OFFSET]); @@ -504,6 +513,7 @@ int bolero_clk_rsc_request_clock(struct device *dev, if (!priv->dev_up && enable) { dev_err_ratelimited(priv->dev, "%s: SSR is in progress..\n", __func__); + trace_printk("%s: SSR is in progress..\n", __func__); ret = -EINVAL; goto err; } @@ -533,6 +543,9 @@ int bolero_clk_rsc_request_clock(struct device *dev, dev_dbg(priv->dev, "%s: clk_cnt: %d for requested clk: %d, enable: %d\n", __func__, priv->clk_cnt[clk_id_req], clk_id_req, enable); + trace_printk("%s: clk_cnt: %d for requested clk: %d, enable: %d\n", + __func__, priv->clk_cnt[clk_id_req], clk_id_req, + enable); mutex_unlock(&priv->rsc_clk_lock); diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 66be46833287..22ddf3f88ecd 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1284,6 +1284,8 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, } } exit: + trace_printk("%s: mclk_enable = %u, dapm = %d clk_users= %d\n", + __func__, mclk_enable, dapm, rx_priv->rx_mclk_users); mutex_unlock(&rx_priv->mclk_lock); return ret; } @@ -1369,6 +1371,7 @@ static int rx_macro_event_handler(struct snd_soc_component *component, rx_macro_wcd_clsh_imped_config(component, data, false); break; case BOLERO_MACRO_EVT_SSR_DOWN: + trace_printk("%s, enter SSR down\n", __func__); rx_priv->dev_up = false; if (rx_priv->swr_ctrl_data) { swrm_wcd_notify( @@ -1389,6 +1392,7 @@ static int rx_macro_event_handler(struct snd_soc_component *component, } break; case BOLERO_MACRO_EVT_SSR_UP: + trace_printk("%s, enter SSR up\n", __func__); rx_priv->dev_up = true; /* reset swr after ssr/pdr */ rx_priv->reset_swr = true; @@ -3636,6 +3640,8 @@ static int rx_swrm_clock(void *handle, bool enable) mutex_lock(&rx_priv->swr_clk_lock); + trace_printk("%s: swrm clock %s\n", + __func__, (enable ? "enable" : "disable")); dev_dbg(rx_priv->dev, "%s: swrm clock %s\n", __func__, (enable ? "enable" : "disable")); if (enable) { @@ -3702,6 +3708,8 @@ static int rx_swrm_clock(void *handle, bool enable) } } } + trace_printk("%s: swrm clock users %d\n", + __func__, rx_priv->swr_clk_users); dev_dbg(rx_priv->dev, "%s: swrm clock users %d\n", __func__, rx_priv->swr_clk_users); exit: diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index a9efa300412f..12bb331e0ea3 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -373,6 +373,7 @@ static int tx_macro_event_handler(struct snd_soc_component *component, switch (event) { case BOLERO_MACRO_EVT_SSR_DOWN: + trace_printk("%s, enter SSR down\n", __func__); if (tx_priv->swr_ctrl_data) { swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, @@ -392,6 +393,7 @@ static int tx_macro_event_handler(struct snd_soc_component *component, } break; case BOLERO_MACRO_EVT_SSR_UP: + trace_printk("%s, enter SSR up\n", __func__); /* reset swr after ssr/pdr */ tx_priv->reset_swr = true; if (tx_priv->swr_ctrl_data) @@ -2355,6 +2357,9 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, { int ret = 0, clk_tx_ret = 0; + trace_printk("%s: clock type %s, enable: %s tx_mclk_users: %d\n", + __func__, (clk_type ? "VA_MCLK" : "TX_MCLK"), + (enable ? "enable" : "disable"), tx_priv->tx_mclk_users); dev_dbg(tx_priv->dev, "%s: clock type %s, enable: %s tx_mclk_users: %d\n", __func__, (clk_type ? "VA_MCLK" : "TX_MCLK"), @@ -2362,6 +2367,7 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, if (enable) { if (tx_priv->swr_clk_users == 0) { + trace_printk("%s: tx swr clk users 0\n", __func__); ret = msm_cdc_pinctrl_select_active_state( tx_priv->tx_swr_gpio_p); if (ret < 0) { @@ -2377,6 +2383,7 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, TX_CORE_CLK, true); if (clk_type == TX_MCLK) { + trace_printk("%s: requesting TX_MCLK\n", __func__); ret = tx_macro_mclk_enable(tx_priv, 1); if (ret < 0) { if (tx_priv->swr_clk_users == 0) @@ -2389,6 +2396,7 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, } } if (clk_type == VA_MCLK) { + trace_printk("%s: requesting VA_MCLK\n", __func__); ret = bolero_clk_rsc_request_clock(tx_priv->dev, TX_CORE_CLK, VA_CORE_CLK, @@ -2420,6 +2428,8 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, if (tx_priv->swr_clk_users == 0) { dev_dbg(tx_priv->dev, "%s: reset_swr: %d\n", __func__, tx_priv->reset_swr); + trace_printk("%s: reset_swr: %d\n", + __func__, tx_priv->reset_swr); if (tx_priv->reset_swr) regmap_update_bits(regmap, BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, @@ -2513,6 +2523,7 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, TX_CORE_CLK, false); exit: + trace_printk("%s: exit\n", __func__); return ret; } @@ -2589,6 +2600,10 @@ static int tx_macro_swrm_clock(void *handle, bool enable) } mutex_lock(&tx_priv->swr_clk_lock); + trace_printk("%s: swrm clock %s tx_swr_clk_cnt: %d va_swr_clk_cnt: %d\n", + __func__, + (enable ? "enable" : "disable"), + tx_priv->tx_swr_clk_cnt, tx_priv->va_swr_clk_cnt); dev_dbg(tx_priv->dev, "%s: swrm clock %s tx_swr_clk_cnt: %d va_swr_clk_cnt: %d\n", __func__, (enable ? "enable" : "disable"), @@ -2651,6 +2666,9 @@ static int tx_macro_swrm_clock(void *handle, bool enable) } } + trace_printk("%s: swrm clock users %d tx_clk_sts_cnt: %d va_clk_sts_cnt: %d\n", + __func__, tx_priv->swr_clk_users, tx_priv->tx_clk_status, + tx_priv->va_clk_status); dev_dbg(tx_priv->dev, "%s: swrm clock users %d tx_clk_sts_cnt: %d va_clk_sts_cnt: %d\n", __func__, tx_priv->swr_clk_users, tx_priv->tx_clk_status, diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 3493a6532c40..34cb1773f64a 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -295,6 +295,7 @@ static int va_macro_event_handler(struct snd_soc_component *component, __func__); break; case BOLERO_MACRO_EVT_SSR_UP: + trace_printk("%s, enter SSR up\n", __func__); /* enable&disable VA_CORE_CLK to reset GFMUX reg */ ret = bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 38c075f4add0..e42627f70066 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -994,6 +994,7 @@ static int wsa_macro_event_handler(struct snd_soc_component *component, switch (event) { case BOLERO_MACRO_EVT_SSR_DOWN: + trace_printk("%s, enter SSR down\n", __func__); if (wsa_priv->swr_ctrl_data) { swrm_wcd_notify( wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, @@ -1013,6 +1014,7 @@ static int wsa_macro_event_handler(struct snd_soc_component *component, } break; case BOLERO_MACRO_EVT_SSR_UP: + trace_printk("%s, enter SSR up\n", __func__); /* reset swr after ssr/pdr */ wsa_priv->reset_swr = true; /* enable&disable WSA_CORE_CLK to reset GFMUX reg */ @@ -2832,6 +2834,9 @@ static int wsa_swrm_clock(void *handle, bool enable) mutex_lock(&wsa_priv->swr_clk_lock); + trace_printk("%s: %s swrm clock %s\n", + dev_name(wsa_priv->dev), __func__, + (enable ? "enable" : "disable")); dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n", __func__, (enable ? "enable" : "disable")); if (enable) { @@ -2897,6 +2902,9 @@ static int wsa_swrm_clock(void *handle, bool enable) } } } + trace_printk("%s: %s swrm clock users: %d\n", + dev_name(wsa_priv->dev), __func__, + wsa_priv->swr_clk_users); dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n", __func__, wsa_priv->swr_clk_users); exit: diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index e9d354b8af27..bf9c4c5b597b 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -1285,6 +1285,7 @@ static int msm_dai_q6_island_mode_put(struct snd_kcontrol *kcontrol, u16 port_id = (u16)kcontrol->private_value; pr_debug("%s: island mode = %d\n", __func__, value); + trace_printk("%s: island mode = %d\n", __func__, value); afe_set_island_mode_cfg(port_id, value); return 0; diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 2c7bcbaa9659..81c6c055268f 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -29267,8 +29267,8 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx, pr_debug("%s: port_id %d, copp_idx %d\n", __func__, port_id, copp_idx); if (port_id != HDMI_RX && port_id != DISPLAY_PORT_RX) { - pr_err("%s: Device pp params on invalid port %d\n", - __func__, port_id); + pr_err("%s: Device pp params on invalid port %d, copp_idx %d, fe_id %d\n", + __func__, port_id, copp_idx, fe_id); return -EINVAL; } diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 7370ae980de6..11f3c3e63a39 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1084,6 +1084,8 @@ static int afe_apr_send_pkt(void *data, wait_queue_head_t *wait) pr_err_ratelimited("%s: request timedout\n", __func__); ret = -ETIMEDOUT; + trace_printk("%s: wait for ADSP response timed out\n", + __func__); } else if (atomic_read(&this_afe.status) > 0) { pr_err("%s: DSP returned error[%s]\n", __func__, adsp_err_get_err_str(atomic_read( @@ -2235,7 +2237,7 @@ static int afe_send_hw_delay(u16 port_id, u32 rate) __func__, port_id, ret); fail_cmd: - pr_debug("%s: port_id 0x%x rate %u delay_usec %d status %d\n", + pr_info("%s: port_id 0x%x rate %u delay_usec %d status %d\n", __func__, port_id, rate, delay_entry.delay_usec, ret); return ret; } @@ -2259,6 +2261,8 @@ static struct cal_block_data *afe_find_cal_topo_id_by_port( /* Skip cal_block if it is already marked stale */ if (cal_utils_is_cal_stale(cal_block)) continue; + pr_info("%s: port id: 0x%x, dev_acdb_id: %d\n", __func__, + port_id, this_afe.dev_acdb_id[afe_port_index]); path = ((afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX)?(TX_DEVICE):(RX_DEVICE)); afe_top = @@ -2267,14 +2271,14 @@ static struct cal_block_data *afe_find_cal_topo_id_by_port( if (this_afe.dev_acdb_id[afe_port_index] > 0) { if (afe_top->acdb_id == this_afe.dev_acdb_id[afe_port_index]) { - pr_debug("%s: top_id:%x acdb_id:%d afe_port_id:%d\n", + pr_info("%s: top_id:%x acdb_id:%d afe_port_id:0x%x\n", __func__, afe_top->topology, afe_top->acdb_id, q6audio_get_port_id(port_id)); return cal_block; } } else { - pr_debug("%s: top_id:%x acdb_id:%d afe_port:%d\n", + pr_info("%s: top_id:%x acdb_id:%d afe_port:0x%x\n", __func__, afe_top->topology, afe_top->acdb_id, q6audio_get_port_id(port_id)); return cal_block; @@ -2331,9 +2335,9 @@ static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id, *topology_id = (u32)afe_top_info->topology; cal_utils_mark_cal_used(cal_block); - pr_debug("%s: port_id = %u acdb_id = %d topology_id = %u ret=%d\n", + pr_info("%s: port_id = 0x%x acdb_id = %d topology_id = 0x%x cal_type_index=%d ret=%d\n", __func__, port_id, afe_top_info->acdb_id, - afe_top_info->topology, ret); + afe_top_info->topology, cal_type_index, ret); unlock: mutex_unlock(&this_afe.cal_data[cal_type_index]->lock); return ret; @@ -2388,7 +2392,7 @@ static int afe_send_port_topology_id(u16 port_id) this_afe.topology[index] = topology_id; rtac_update_afe_topology(port_id); done: - pr_debug("%s: AFE set topology id 0x%x enable for port 0x%x ret %d\n", + pr_info("%s: AFE set topology id 0x%x enable for port 0x%x ret %d\n", __func__, topology_id, port_id, ret); return ret; @@ -2461,6 +2465,8 @@ int afe_send_port_island_mode(u16 port_id) } pr_debug("%s: AFE set island mode 0x%x enable for port 0x%x ret %d\n", __func__, island_mode, port_id, ret); + trace_printk("%s: AFE set island mode 0x%x enable for port 0x%x ret %d\n", + __func__, island_mode, port_id, ret); return ret; } EXPORT_SYMBOL(afe_send_port_island_mode); @@ -2623,7 +2629,7 @@ static struct cal_block_data *afe_find_cal(int cal_index, int port_id) struct audio_cal_info_afe *afe_cal_info = NULL; int afe_port_index = q6audio_get_port_index(port_id); - pr_debug("%s: cal_index %d port_id %d port_index %d\n", __func__, + pr_info("%s: cal_index %d port_id 0x%x port_index %d\n", __func__, cal_index, port_id, afe_port_index); if (afe_port_index < 0) { pr_err("%s: Error getting AFE port index %d\n", @@ -2635,16 +2641,21 @@ static struct cal_block_data *afe_find_cal(int cal_index, int port_id) &this_afe.cal_data[cal_index]->cal_blocks) { cal_block = list_entry(ptr, struct cal_block_data, list); afe_cal_info = cal_block->cal_info; + pr_info("%s: acdb_id %d dev_acdb_id %d sample_rate %d afe_sample_rates %d\n", + __func__, afe_cal_info->acdb_id, + this_afe.dev_acdb_id[afe_port_index], + afe_cal_info->sample_rate, + this_afe.afe_sample_rates[afe_port_index]); if ((afe_cal_info->acdb_id == this_afe.dev_acdb_id[afe_port_index]) && (afe_cal_info->sample_rate == this_afe.afe_sample_rates[afe_port_index])) { - pr_debug("%s: cal block is a match, size is %zd\n", + pr_info("%s: cal block is a match, size is %zd\n", __func__, cal_block->cal_data.size); goto exit; } } - pr_debug("%s: no matching cal_block found\n", __func__); + pr_info("%s: no matching cal_block found\n", __func__); cal_block = NULL; exit: @@ -2657,7 +2668,7 @@ static int send_afe_cal_type(int cal_index, int port_id) int ret; int afe_port_index = q6audio_get_port_index(port_id); - pr_debug("%s:\n", __func__); + pr_info("%s: cal_index is %d\n", __func__, cal_index); if (this_afe.cal_data[cal_index] == NULL) { pr_warn("%s: cal_index %d not allocated!\n", @@ -2674,7 +2685,9 @@ static int send_afe_cal_type(int cal_index, int port_id) } mutex_lock(&this_afe.cal_data[cal_index]->lock); - + pr_info("%s: dev_acdb_id[%d] is %d\n", + __func__, afe_port_index, + this_afe.dev_acdb_id[afe_port_index]); if (((cal_index == AFE_COMMON_RX_CAL) || (cal_index == AFE_COMMON_TX_CAL) || (cal_index == AFE_LSM_TX_CAL)) && @@ -2690,7 +2703,7 @@ static int send_afe_cal_type(int cal_index, int port_id) goto unlock; } - pr_debug("%s: Sending cal_index cal %d\n", __func__, cal_index); + pr_info("%s: Sending cal_index cal %d\n", __func__, cal_index); ret = remap_cal_data(cal_block, cal_index); if (ret) { @@ -2701,7 +2714,7 @@ static int send_afe_cal_type(int cal_index, int port_id) } ret = afe_send_cal_block(port_id, cal_block); if (ret < 0) - pr_debug("%s: No cal sent for cal_index %d, port_id = 0x%x! ret %d\n", + pr_err("%s: No cal sent for cal_index %d, port_id = 0x%x! ret %d\n", __func__, cal_index, port_id, ret); cal_utils_mark_cal_used(cal_block); @@ -3776,6 +3789,8 @@ void afe_set_island_mode_cfg(u16 port_id, u32 enable_flag) port_index = afe_get_port_index(port_id); this_afe.island_mode[port_index] = enable_flag; + trace_printk("%s: set island mode cfg 0x%x for port 0x%x\n", + __func__, this_afe.island_mode[port_index], port_id); } EXPORT_SYMBOL(afe_set_island_mode_cfg); @@ -4559,7 +4574,7 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, port_id = VIRTUAL_ID_TO_PORTID(port_id); } - pr_debug("%s: port id: 0x%x\n", __func__, port_id); + pr_info("%s: port id: 0x%x\n", __func__, port_id); index = q6audio_get_port_index(port_id); if (index < 0 || index >= AFE_MAX_PORTS) { @@ -7580,7 +7595,7 @@ int afe_close(int port_id) ret = -EINVAL; goto fail_cmd; } - pr_debug("%s: port_id = 0x%x\n", __func__, port_id); + pr_info("%s: port_id = 0x%x\n", __func__, port_id); if ((port_id == RT_PROXY_DAI_001_RX) || (port_id == RT_PROXY_DAI_002_TX)) { pr_debug("%s: before decrementing pcm_afe_instance %d\n", @@ -7767,6 +7782,15 @@ int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg) cfg->clk_root, cfg->clk_set_mode, cfg->reserved, q6audio_get_port_id(port_id)); + trace_printk("%s: Minor version =0x%x clk val1 = %d\n" + "clk val2 = %d, clk src = 0x%x\n" + "clk root = 0x%x clk mode = 0x%x resrv = 0x%x\n" + "port id = 0x%x\n", + __func__, cfg->i2s_cfg_minor_version, + cfg->clk_val1, cfg->clk_val2, cfg->clk_src, + cfg->clk_root, cfg->clk_set_mode, + cfg->reserved, q6audio_get_port_id(port_id)); + ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, (u8 *) &clk_cfg); @@ -7819,12 +7843,21 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg) cfg->clk_id, cfg->clk_freq_in_hz, cfg->clk_attri, cfg->clk_root, cfg->enable); + trace_printk("%s: Minor version =0x%x clk id = %d\n" + "clk freq (Hz) = %d, clk attri = 0x%x\n" + "clk root = 0x%x clk enable = 0x%x\n", + __func__, cfg->clk_set_minor_version, + cfg->clk_id, cfg->clk_freq_in_hz, cfg->clk_attri, + cfg->clk_root, cfg->enable); + ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr, (u8 *) cfg); - if (ret < 0) + if (ret < 0) { pr_err_ratelimited("%s: AFE clk cfg failed with ret %d\n", + __func__, ret); + trace_printk("%s: AFE clk cfg failed with ret %d\n", __func__, ret); - + } mutex_unlock(&this_afe.afe_clk_lock); return ret; } @@ -9327,6 +9360,8 @@ int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name, pr_debug("%s: lpass core hw vote opcode[0x%x] hw id[0x%x]\n", __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id); + trace_printk("%s: lpass core hw vote opcode[0x%x] hw id[0x%x]\n", + __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id); *client_handle = 0; ret = afe_apr_send_clk_pkt((uint32_t *)cmd_ptr, @@ -9366,6 +9401,7 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle) if (!this_afe.lpass_hw_core_client_hdl[hw_block_id]) { pr_debug("%s: SSR in progress, return\n", __func__); + trace_printk("%s: SSR in progress, return\n", __func__); goto done; } @@ -9385,6 +9421,9 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle) pr_debug("%s: lpass core hw unvote opcode[0x%x] hw id[0x%x]\n", __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id); + trace_printk("%s: lpass core hw unvote opcode[0x%x] hw id[0x%x]\n", + __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id); + if (cmd_ptr->client_handle <= 0) { pr_err("%s: invalid client handle\n", __func__); ret = -EINVAL; diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index 2b9e52e94308..e69afdd717dc 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -497,6 +497,7 @@ int lpi_pinctrl_suspend(struct device *dev) { int ret = 0; + trace_printk("%s: system suspend\n", __func__); dev_dbg(dev, "%s: system suspend\n", __func__); if ((!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev))) { @@ -533,6 +534,7 @@ static struct notifier_block service_nb = { static void lpi_pinctrl_ssr_disable(struct device *dev, void *data) { + trace_printk("%s: enter\n", __func__); lpi_dev_up = false; lpi_pinctrl_suspend(dev); } @@ -857,6 +859,7 @@ int lpi_pinctrl_runtime_resume(struct device *dev) int ret = 0; struct clk *hw_vote = state->lpass_core_hw_vote; + trace_printk("%s: enter\n", __func__); if (state->lpass_core_hw_vote == NULL) { dev_dbg(dev, "%s: Invalid core hw node\n", __func__); if (state->lpass_audio_hw_vote == NULL) { @@ -882,6 +885,7 @@ int lpi_pinctrl_runtime_resume(struct device *dev) exit: mutex_unlock(&state->core_hw_vote_lock); + trace_printk("%s: exit\n", __func__); return 0; } @@ -890,6 +894,7 @@ int lpi_pinctrl_runtime_suspend(struct device *dev) struct lpi_gpio_state *state = dev_get_drvdata(dev); struct clk *hw_vote = state->lpass_core_hw_vote; + trace_printk("%s: enter\n", __func__); if (state->lpass_core_hw_vote == NULL) { dev_dbg(dev, "%s: Invalid core hw node\n", __func__); if (state->lpass_audio_hw_vote == NULL) { @@ -905,6 +910,7 @@ int lpi_pinctrl_runtime_suspend(struct device *dev) state->core_hw_vote_status = false; } mutex_unlock(&state->core_hw_vote_lock); + trace_printk("%s: exit\n", __func__); return 0; } diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index cd3805fc5578..b8f8e2ac6393 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -454,6 +454,8 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) } swrm->clk_ref_count++; if (swrm->clk_ref_count == 1) { + trace_printk("%s: clock enable count %d", + __func__, swrm->clk_ref_count); ret = swrm->clk(swrm->handle, true); if (ret) { dev_err_ratelimited(swrm->dev, @@ -463,6 +465,8 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) } } } else if (--swrm->clk_ref_count == 0) { + trace_printk("%s: clock disable count %d", + __func__, swrm->clk_ref_count); swrm->clk(swrm->handle, false); complete(&swrm->clk_off_complete); } @@ -1673,6 +1677,7 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) struct swr_device *swr_dev; struct swr_master *mstr = &swrm->master; + trace_printk("%s enter\n", __func__); if (unlikely(swrm_lock_sleep(swrm) == false)) { dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__); return IRQ_NONE; @@ -1689,6 +1694,8 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); intr_sts_masked = intr_sts & swrm->intr_mask; + + trace_printk("%s: status: 0x%x \n", __func__, intr_sts_masked); handle_irq: for (i = 0; i < SWRM_INTERRUPT_MAX; i++) { value = intr_sts_masked & (1 << i); @@ -1833,6 +1840,7 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) mutex_unlock(&swrm->reslock); exit: swrm_unlock_sleep(swrm); + trace_printk("%s exit\n", __func__); return ret; } @@ -1847,6 +1855,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) struct swr_device *swr_dev; struct swr_master *mstr = &swrm->master; + trace_printk("%s enter\n", __func__); if (unlikely(swrm_lock_sleep(swrm) == false)) { dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__); return IRQ_NONE; @@ -1873,6 +1882,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) intr_sts_masked = intr_sts & swrm->intr_mask; dev_dbg(swrm->dev, "%s: status: 0x%x \n", __func__, intr_sts_masked); + trace_printk("%s: status: 0x%x \n", __func__, intr_sts_masked); handle_irq: for (i = 0; i < SWRM_INTERRUPT_MAX; i++) { value = intr_sts_masked & (1 << i); @@ -2054,6 +2064,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) exit: mutex_unlock(&swrm->reslock); swrm_unlock_sleep(swrm); + trace_printk("%s exit\n", __func__); return ret; } @@ -2067,6 +2078,7 @@ static irqreturn_t swrm_wakeup_interrupt(int irq, void *dev) return IRQ_NONE; } + trace_printk("%s enter\n", __func__); mutex_lock(&swrm->devlock); if (!swrm->dev_up) { if (swrm->wake_irq > 0) { @@ -2105,6 +2117,7 @@ static irqreturn_t swrm_wakeup_interrupt(int irq, void *dev) pm_runtime_put_autosuspend(swrm->dev); swrm_unlock_sleep(swrm); exit: + trace_printk("%s exit\n", __func__); return ret; } @@ -2119,6 +2132,7 @@ static void swrm_wakeup_work(struct work_struct *work) return; } + trace_printk("%s enter\n", __func__); mutex_lock(&swrm->devlock); if (!swrm->dev_up) { mutex_unlock(&swrm->devlock); @@ -2134,6 +2148,7 @@ static void swrm_wakeup_work(struct work_struct *work) pm_runtime_put_autosuspend(swrm->dev); swrm_unlock_sleep(swrm); exit: + trace_printk("%s exit\n", __func__); pm_relax(swrm->dev); } @@ -2238,6 +2253,8 @@ static void swrm_device_wakeup_vote(struct swr_master *mstr) } dev_dbg(swrm->dev, "%s: hw_clk_en: %d audio_core_clk_en: %d\n", __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); + trace_printk("%s: hw_clk_en: %d audio_core_clk_en: %d\n", + __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); pm_runtime_get_sync(swrm->dev); } @@ -2255,6 +2272,8 @@ static void swrm_device_wakeup_unvote(struct swr_master *mstr) dev_dbg(swrm->dev, "%s: hw_clk_en: %d audio_core_clk_en: %d\n", __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); + trace_printk("%s: hw_clk_en: %d audio_core_clk_en: %d\n", + __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); --swrm->aud_core_clk_en; if (swrm->aud_core_clk_en < 0) swrm->aud_core_clk_en = 0; @@ -2807,6 +2826,8 @@ static int swrm_runtime_resume(struct device *dev) dev_dbg(dev, "%s: pm_runtime: resume, state:%d\n", __func__, swrm->state); + trace_printk("%s: pm_runtime: resume, state:%d\n", + __func__, swrm->state); mutex_lock(&swrm->reslock); if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) { @@ -2857,6 +2878,9 @@ static int swrm_runtime_resume(struct device *dev) dev_dbg(dev, "%s slave device up not implemented\n", __func__); + trace_printk( + "%s slave device up not implemented\n", + __func__); ret = 0; } else if (ret) { dev_err(dev, @@ -2912,6 +2936,8 @@ static int swrm_runtime_resume(struct device *dev) auto_suspend_timer); mutex_unlock(&swrm->reslock); + trace_printk("%s: pm_runtime: resume done, state:%d\n", + __func__, swrm->state); return ret; } @@ -2926,6 +2952,8 @@ static int swrm_runtime_suspend(struct device *dev) struct swr_device *swr_dev; int current_state = 0; + trace_printk("%s: pm_runtime: suspend state: %d\n", + __func__, swrm->state); dev_dbg(dev, "%s: pm_runtime: suspend state: %d\n", __func__, swrm->state); mutex_lock(&swrm->reslock); @@ -2950,10 +2978,13 @@ static int swrm_runtime_suspend(struct device *dev) if ((current_state != SWR_MSTR_SSR) && swrm_is_port_en(&swrm->master)) { dev_dbg(dev, "%s ports are enabled\n", __func__); + trace_printk("%s ports are enabled\n", __func__); ret = -EBUSY; goto exit; } if (!swrm->clk_stop_mode0_supp || swrm->state == SWR_MSTR_SSR) { + dev_err(dev, "%s: clk stop mode not supported or SSR entry\n", + __func__); mutex_unlock(&swrm->reslock); enable_bank_switch(swrm, 0, SWR_ROW_50, SWR_MIN_COL); mutex_lock(&swrm->reslock); @@ -2964,15 +2995,23 @@ static int swrm_runtime_suspend(struct device *dev) if (ret == -ENODEV) { dev_dbg_ratelimited(dev, "%s slave device down not implemented\n", - __func__); + __func__); + trace_printk( + "%s slave device down not implemented\n", + __func__); ret = 0; } else if (ret) { dev_err(dev, "%s: failed to shutdown swr dev %d\n", __func__, swr_dev->dev_num); + trace_printk( + "%s: failed to shutdown swr dev %d\n", + __func__, swr_dev->dev_num); goto exit; } } + trace_printk("%s: clk stop mode not supported or SSR exit\n", + __func__); } else { /* Mask bus clash interrupt */ swrm->intr_mask &= ~((u32)0x08); @@ -3018,6 +3057,8 @@ static int swrm_runtime_suspend(struct device *dev) if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); mutex_unlock(&swrm->reslock); + trace_printk("%s: pm_runtime: suspend done state: %d\n", + __func__, swrm->state); return ret; } #endif /* CONFIG_PM */ @@ -3029,6 +3070,7 @@ static int swrm_device_suspend(struct device *dev) int ret = 0; dev_dbg(dev, "%s: swrm state: %d\n", __func__, swrm->state); + trace_printk("%s: swrm state: %d\n", __func__, swrm->state); if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) { ret = swrm_runtime_suspend(dev); if (!ret) { @@ -3047,6 +3089,7 @@ static int swrm_device_down(struct device *dev) struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); dev_dbg(dev, "%s: swrm state: %d\n", __func__, swrm->state); + trace_printk("%s: swrm state: %d\n", __func__, swrm->state); mutex_lock(&swrm->force_down_lock); swrm->state = SWR_MSTR_SSR; @@ -3220,6 +3263,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) } break; case SWR_DEVICE_SSR_DOWN: + trace_printk("%s: swr device down called\n", __func__); mutex_lock(&swrm->devlock); swrm->dev_up = false; mutex_unlock(&swrm->devlock); @@ -3229,6 +3273,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) break; case SWR_DEVICE_SSR_UP: /* wait for clk voting to be zero */ + trace_printk("%s: swr device up called\n", __func__); reinit_completion(&swrm->clk_off_complete); if (swrm->clk_ref_count && !wait_for_completion_timeout(&swrm->clk_off_complete, @@ -3242,6 +3287,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) break; case SWR_DEVICE_DOWN: dev_dbg(swrm->dev, "%s: swr master down called\n", __func__); + trace_printk("%s: swr master down called\n", __func__); mutex_lock(&swrm->mlock); if (swrm->state == SWR_MSTR_DOWN) dev_dbg(swrm->dev, "%s:SWR master is already Down:%d\n", @@ -3252,6 +3298,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) break; case SWR_DEVICE_UP: dev_dbg(swrm->dev, "%s: swr master up called\n", __func__); + trace_printk("%s: swr master up called\n", __func__); mutex_lock(&swrm->devlock); if (!swrm->dev_up) { dev_dbg(swrm->dev, "SSR not complete yet\n"); -- GitLab From 9530d74a9d3ed21dea2dc7809f34257c282ee67f Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Sun, 19 Jan 2020 17:40:25 +0800 Subject: [PATCH 1379/1645] asoc: lsm: hold wakelock when keyword is detected hold wakelock when keyword is detected Change-Id: Id25d4e3094a0cb430696aaeaf06dd176276d4e46 Signed-off-by: Meng Wang --- asoc/msm-lsm-client.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 8efeee5a8caa..4a58bad4a5dd 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. */ #include #include @@ -33,6 +33,8 @@ #define CAPTURE_MIN_PERIOD_SIZE 320 #define LISTEN_MAX_STATUS_PAYLOAD_SIZE 256 +#define WAKELOCK_TIMEOUT 2000 + #define LAB_BUFFER_ALLOC 1 #define LAB_BUFFER_DEALLOC 0 @@ -90,6 +92,7 @@ struct lsm_priv { int xrun_count; int xrun_index; spinlock_t xrun_lock; + struct wakeup_source ws; }; enum { /* lsm session states */ @@ -217,6 +220,8 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, } rtd = substream->private_data; + pm_wakeup_ws_event(&prtd->ws, WAKELOCK_TIMEOUT, true); + dev_dbg(rtd->dev, "%s: opcode %x\n", __func__, opcode); switch (opcode) { case LSM_DATA_EVENT_READ_DONE: { int rc; @@ -230,11 +235,13 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, "%s: EVENT_READ_DONE invalid callback, session %d callback %d payload %pK", __func__, prtd->lsm_client->session, token, read_done); + __pm_relax(&prtd->ws); return; } if (atomic_read(&prtd->read_abort)) { dev_dbg(rtd->dev, "%s: read abort set skip data\n", __func__); + __pm_relax(&prtd->ws); return; } if (!lsm_lab_buffer_sanity(prtd, read_done, &buf_index)) { @@ -247,6 +254,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, "%s: Invalid index %d buf_index max cnt %d\n", __func__, buf_index, prtd->lsm_client->out_hw_params.period_count); + __pm_relax(&prtd->ws); return; } spin_lock_irqsave(&prtd->xrun_lock, flags); @@ -284,6 +292,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, dev_err(rtd->dev, "%s: client_size has invalid size[%d]\n", __func__, client_size); + __pm_relax(&prtd->ws); return; } status = (uint16_t)((uint8_t *)payload)[0]; @@ -299,13 +308,14 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, dev_err(rtd->dev, "%s: client_size has invalid size[%d]\n", __func__, client_size); + __pm_relax(&prtd->ws); return; } status = (uint16_t)((uint8_t *)payload)[0]; payload_size = (uint16_t)((uint8_t *)payload)[1]; index = 2; dev_dbg(rtd->dev, - "%s: event detect status = %d payload size = %d\n", + "%s: event detect status_v2 = %d payload size = %d\n", __func__, status, payload_size); break; @@ -314,6 +324,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, dev_err(rtd->dev, "%s: client_size has invalid size[%d]\n", __func__, client_size); + __pm_relax(&prtd->ws); return; } event_ts_lsw = ((uint32_t *)payload)[0]; @@ -333,6 +344,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, dev_err(rtd->dev, "%s: client_size has invalid size[%d]\n", __func__, client_size); + __pm_relax(&prtd->ws); return; } @@ -352,6 +364,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, "LSM_SESSION_DETECTION_ENGINE_GENERIC_EVENT", sizeof(struct snd_lsm_event_status) + payload_size); + __pm_relax(&prtd->ws); return; } @@ -366,6 +379,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, dev_err(rtd->dev, "%s: Failed to copy memory with invalid size = %d\n", __func__, payload_size); + __pm_relax(&prtd->ws); return; } prtd->event_avail = 1; @@ -390,12 +404,14 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, opcode == LSM_SESSION_EVENT_DETECTION_STATUS_V2 || opcode == LSM_SESSION_EVENT_DETECTION_STATUS_V3) { spin_lock_irqsave(&prtd->event_lock, flags); + dev_dbg(rtd->dev, "%s: detection status\n", __func__); temp = krealloc(prtd->event_status, sizeof(struct snd_lsm_event_status_v3) + payload_size, GFP_ATOMIC); if (!temp) { dev_err(rtd->dev, "%s: no memory for event status\n", __func__); + __pm_relax(&prtd->ws); return; } /* @@ -415,12 +431,14 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, payload_size); prtd->event_avail = 1; spin_unlock_irqrestore(&prtd->event_lock, flags); + dev_dbg(rtd->dev, "%s: wakeup event_wait\n", __func__); wake_up(&prtd->event_wait); } else { spin_unlock_irqrestore(&prtd->event_lock, flags); dev_err(rtd->dev, "%s: Failed to copy memory with invalid size = %d\n", __func__, payload_size); + __pm_relax(&prtd->ws); return; } } else { @@ -432,6 +450,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, if (substream->timer_running) snd_timer_interrupt(substream->timer, 1); } + dev_dbg(rtd->dev, "%s: leave\n", __func__); } static int msm_lsm_lab_buffer_alloc(struct lsm_priv *lsm, int alloc) @@ -1071,6 +1090,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, prtd = runtime->private_data; rtd = substream->private_data; + dev_dbg(rtd->dev, "%s: enter, cmd %x\n", __func__, cmd); switch (cmd) { case SNDRV_LSM_SET_SESSION_DATA: case SNDRV_LSM_SET_SESSION_DATA_V2: @@ -1136,6 +1156,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: lsm open failed, %d\n", __func__, ret); + __pm_relax(&prtd->ws); return ret; } prtd->lsm_client->opened = true; @@ -1271,7 +1292,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, uint32_t ts_lsw, ts_msw; uint16_t status = 0, payload_size = 0; - dev_dbg(rtd->dev, "%s: Get event status\n", __func__); + dev_dbg(rtd->dev, "%s: Get event status cmd %xx\n", __func__, cmd); atomic_set(&prtd->event_wait_stop, 0); /* @@ -1284,6 +1305,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, (cmpxchg(&prtd->event_avail, 1, 0) || (xchg = atomic_cmpxchg(&prtd->event_wait_stop, 1, 0)))); + dev_dbg(rtd->dev, "%s: wait event is done\n", __func__); mutex_lock(&prtd->lsm_api_lock); dev_dbg(rtd->dev, "%s: wait_event_freezable %d event_wait_stop %d\n", __func__, rc, xchg); @@ -1482,12 +1504,14 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, if (prtd->lsm_client->num_stages > 1) { dev_err(rtd->dev, "%s: %s: not supported for multi stage session\n", __func__, "LSM_LAB_CONTROL"); + __pm_relax(&prtd->ws); return -EINVAL; } if (copy_from_user(&enable, arg, sizeof(enable))) { dev_err(rtd->dev, "%s: %s: copy_frm_user failed\n", __func__, "LSM_LAB_CONTROL"); + __pm_relax(&prtd->ws); return -EFAULT; } @@ -1542,6 +1566,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, if (copy_from_user(&mode, arg, sizeof(mode))) { dev_err(rtd->dev, "%s: %s: copy_frm_user failed\n", __func__, "LSM_SET_FWK_MODE_CONFIG"); + __pm_relax(&prtd->ws); return -EFAULT; } @@ -1572,6 +1597,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, if (copy_from_user(¶ms, arg, sizeof(params))) { dev_err(rtd->dev, "%s: %s: copy_from_user failed\n", __func__, "LSM_SET_INPUT_HW_PARAMS"); + __pm_relax(&prtd->ws); return -EFAULT; } @@ -1598,6 +1624,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: cmd 0x%x failed %d\n", __func__, cmd, rc); + __pm_relax(&prtd->ws); return rc; } @@ -2450,6 +2477,7 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) init_waitqueue_head(&prtd->event_wait); init_waitqueue_head(&prtd->period_wait); prtd->substream = substream; + wakeup_source_init(&prtd->ws, "lsm-client"); runtime->private_data = prtd; runtime->hw = msm_pcm_hardware_capture; @@ -2746,6 +2774,7 @@ static int msm_lsm_close(struct snd_pcm_substream *substream) q6lsm_client_free(prtd->lsm_client); + wakeup_source_trash(&prtd->ws); spin_lock_irqsave(&prtd->event_lock, flags); kfree(prtd->event_status); prtd->event_status = NULL; -- GitLab From 9f60c106bf1618545a9c6a9533c043181eaab016 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 14 Jan 2020 14:56:23 +0530 Subject: [PATCH 1380/1645] asoc: Set and get lsm port indices on a per session basis When multiple LSM sessions are running, lsm port index might be overwritten with index of different sessions during concurrent LPI and Non LPI session switches. Maintain lsm port index on a per session basis to avoid this issue. Change-Id: I943ea7899b977e06f467a140a9d1c9feb31c58bd Signed-off-by: Aditya Bavanari --- asoc/msm-pcm-routing-v2.c | 48 +++++++++++++++++++++++++++++++++++---- include/dsp/q6lsm.h | 4 +++- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 39ed0d5f4675..2c62b8787882 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -68,7 +68,7 @@ static int quin_mi2s_switch_enable; static int sen_mi2s_switch_enable; static int fm_pcmrx_switch_enable; static int usb_switch_enable; -static int lsm_port_index; +static int lsm_port_index[MAX_LSM_SESSIONS]; static int slim0_rx_aanc_fb_port; static int msm_route_ec_ref_rx; static int msm_ec_ref_ch = 4; @@ -1378,9 +1378,11 @@ static bool route_check_fe_id_adm_support(int fe_id) if ((fe_id >= MSM_FRONTEND_DAI_LSM1) && (fe_id <= MSM_FRONTEND_DAI_LSM8)) { /* fe id is listen while port is set to afe */ - if (lsm_port_index != ADM_LSM_PORT_INDEX) { + if (lsm_port_index[fe_id - MSM_FRONTEND_DAI_LSM1] != + ADM_LSM_PORT_INDEX) { pr_debug("%s: fe_id %d, lsm mux slim port %d\n", - __func__, fe_id, lsm_port_index); + __func__, fe_id, + lsm_port_index[fe_id - MSM_FRONTEND_DAI_LSM1]); rc = false; } } @@ -2971,10 +2973,44 @@ static int msm_routing_put_fm_pcmrx_switch_mixer(struct snd_kcontrol *kcontrol, return 1; } +static void msm_routing_get_lsm_fe_idx(struct snd_kcontrol *kcontrol, + u8 *fe_idx) +{ + int fe_id = MSM_FRONTEND_DAI_LSM1; + + if (strnstr(kcontrol->id.name, "LSM1", sizeof("LSM1"))) { + fe_id = MSM_FRONTEND_DAI_LSM1; + } else if (strnstr(kcontrol->id.name, "LSM2", sizeof("LSM2"))) { + fe_id = MSM_FRONTEND_DAI_LSM2; + } else if (strnstr(kcontrol->id.name, "LSM3", sizeof("LSM3"))) { + fe_id = MSM_FRONTEND_DAI_LSM3; + } else if (strnstr(kcontrol->id.name, "LSM4", sizeof("LSM4"))) { + fe_id = MSM_FRONTEND_DAI_LSM4; + } else if (strnstr(kcontrol->id.name, "LSM5", sizeof("LSM5"))) { + fe_id = MSM_FRONTEND_DAI_LSM5; + } else if (strnstr(kcontrol->id.name, "LSM6", sizeof("LSM6"))) { + fe_id = MSM_FRONTEND_DAI_LSM6; + } else if (strnstr(kcontrol->id.name, "LSM7", sizeof("LSM7"))) { + fe_id = MSM_FRONTEND_DAI_LSM7; + } else if (strnstr(kcontrol->id.name, "LSM8", sizeof("LSM8"))) { + fe_id = MSM_FRONTEND_DAI_LSM8; + } else { + pr_err("%s: Invalid kcontrol name:%s\n", __func__, + kcontrol->id.name); + return; + } + + *fe_idx = fe_id - MSM_FRONTEND_DAI_LSM1; + pr_debug("%s: fe_id: %d, fe_idx:%d\n", __func__, fe_id, *fe_idx); +} + static int msm_routing_lsm_port_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - ucontrol->value.integer.value[0] = lsm_port_index; + u8 fe_idx = 0; + + msm_routing_get_lsm_fe_idx(kcontrol, &fe_idx); + ucontrol->value.integer.value[0] = lsm_port_index[fe_idx]; return 0; } @@ -2984,6 +3020,7 @@ static int msm_routing_lsm_port_put(struct snd_kcontrol *kcontrol, struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; int mux = ucontrol->value.enumerated.item[0]; int lsm_port = AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX; + u8 fe_idx = 0; if (mux >= e->items) { pr_err("%s: Invalid mux value %d\n", __func__, mux); @@ -3046,7 +3083,8 @@ static int msm_routing_lsm_port_put(struct snd_kcontrol *kcontrol, break; } set_lsm_port(lsm_port); - lsm_port_index = ucontrol->value.integer.value[0]; + msm_routing_get_lsm_fe_idx(kcontrol, &fe_idx); + lsm_port_index[fe_idx] = ucontrol->value.integer.value[0]; return 0; } diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h index af43cdd4cbf3..02897d98e06d 100644 --- a/include/dsp/q6lsm.h +++ b/include/dsp/q6lsm.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. */ #ifndef __Q6LSM_H__ #define __Q6LSM_H__ @@ -20,6 +20,8 @@ #define LSM_API_VERSION_V3 3 +#define MAX_LSM_SESSIONS 8 + typedef void (*lsm_app_cb)(uint32_t opcode, uint32_t token, uint32_t *payload, uint16_t client_size, void *priv); -- GitLab From 957257212f1c469a9c1608218c381d74ae0b0ae5 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 8 Jan 2020 12:40:58 +0530 Subject: [PATCH 1381/1645] ASoC: Remove glitch during amic record Glitch is coming sometimes during amic record. Correct sequence to resolve the glitch. Change-Id: I3c062632229826f6fe32e2f1ea9e07381c21d902 Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/tx-macro.c | 39 +++++++++++++++++++++-------------- asoc/codecs/bolero/va-macro.c | 34 ++++++++++++++++++------------ 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index a9efa300412f..41c13ec3e5d9 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -883,13 +883,14 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x20, 0x20); - snd_soc_component_update_bits(component, - hpf_gate_reg, 0x01, 0x00); - /* - * Minimum 1 clk cycle delay is required as per HW spec - */ - usleep_range(1000, 1010); - + if (!(is_amic_enabled(component, decimator) < BOLERO_ADC_MAX)) { + snd_soc_component_update_bits(component, + hpf_gate_reg, 0x01, 0x00); + /* + * Minimum 1 clk cycle delay is required as per HW spec + */ + usleep_range(1000, 1010); + } hpf_cut_off_freq = ( snd_soc_component_read32(component, dec_cfg_reg) & TX_HPF_CUT_OFF_FREQ_MASK) >> 5; @@ -917,15 +918,17 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, &tx_priv->tx_hpf_work[decimator].dwork, msecs_to_jiffies(hpf_delay)); snd_soc_component_update_bits(component, - hpf_gate_reg, 0x03, 0x03); + hpf_gate_reg, 0x03, 0x02); + if (!(is_amic_enabled(component, decimator) + < BOLERO_ADC_MAX)) + snd_soc_component_update_bits(component, + hpf_gate_reg, 0x03, 0x00); /* * Minimum 1 clk cycle delay is required as per HW spec */ usleep_range(1000, 1010); snd_soc_component_update_bits(component, - hpf_gate_reg, 0x02, 0x00); - snd_soc_component_update_bits(component, - hpf_gate_reg, 0x01, 0x01); + hpf_gate_reg, 0x03, 0x01); /* * 6ms delay is required as per HW spec */ @@ -957,9 +960,15 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, component, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, hpf_cut_off_freq << 5); - snd_soc_component_update_bits(component, - hpf_gate_reg, - 0x02, 0x02); + if (is_amic_enabled(component, decimator) < BOLERO_ADC_MAX) + snd_soc_component_update_bits(component, + hpf_gate_reg, + 0x03, 0x02); + else + snd_soc_component_update_bits(component, + hpf_gate_reg, + 0x03, 0x03); + /* * Minimum 1 clk cycle delay is required * as per HW spec @@ -967,7 +976,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, usleep_range(1000, 1010); snd_soc_component_update_bits(component, hpf_gate_reg, - 0x02, 0x00); + 0x03, 0x01); } } cancel_delayed_work_sync( diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 3493a6532c40..fbdf5b4e5028 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -1078,13 +1078,14 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, /* Enable TX CLK */ snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x20, 0x20); - snd_soc_component_update_bits(component, + if (!(is_amic_enabled(component, decimator) < BOLERO_ADC_MAX)) { + snd_soc_component_update_bits(component, hpf_gate_reg, 0x01, 0x00); - /* - * Minimum 1 clk cycle delay is required as per HW spec - */ - usleep_range(1000, 1010); - + /* + * Minimum 1 clk cycle delay is required as per HW spec + */ + usleep_range(1000, 1010); + } hpf_cut_off_freq = (snd_soc_component_read32( component, dec_cfg_reg) & TX_HPF_CUT_OFF_FREQ_MASK) >> 5; @@ -1103,15 +1104,16 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, va_tx_unmute_delay = unmute_delay; } snd_soc_component_update_bits(component, - hpf_gate_reg, 0x03, 0x03); + hpf_gate_reg, 0x03, 0x02); + if (!(is_amic_enabled(component, decimator) < BOLERO_ADC_MAX)) + snd_soc_component_update_bits(component, + hpf_gate_reg, 0x03, 0x00); /* * Minimum 1 clk cycle delay is required as per HW spec */ usleep_range(1000, 1010); snd_soc_component_update_bits(component, - hpf_gate_reg, 0x02, 0x00); - snd_soc_component_update_bits(component, - hpf_gate_reg, 0x01, 0x01); + hpf_gate_reg, 0x03, 0x01); /* * 6ms delay is required as per HW spec */ @@ -1140,9 +1142,15 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, hpf_cut_off_freq << 5); - snd_soc_component_update_bits(component, + if (is_amic_enabled(component, decimator) < + BOLERO_ADC_MAX) + snd_soc_component_update_bits(component, + hpf_gate_reg, + 0x03, 0x02); + else + snd_soc_component_update_bits(component, hpf_gate_reg, - 0x02, 0x02); + 0x03, 0x03); /* * Minimum 1 clk cycle delay is required * as per HW spec @@ -1150,7 +1158,7 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, usleep_range(1000, 1010); snd_soc_component_update_bits(component, hpf_gate_reg, - 0x02, 0x00); + 0x03, 0x01); } } cancel_delayed_work_sync( -- GitLab From 516716188462676b1567d2c1859e9c1210aaf8dc Mon Sep 17 00:00:00 2001 From: Sanjana B Date: Thu, 28 Nov 2019 14:45:10 +0530 Subject: [PATCH 1382/1645] asoc: msm-cdc-pinctrl: Add alternate pinctrl state for DSD input Add additional pinctrl states to support alternative function. This change enables support of alternative pins through pinctrl framework. Change-Id: I1f3f9a13345846f1714b4ecaeecde975b5cf6813 Signed-off-by: Sanjana B --- asoc/codecs/msm-cdc-pinctrl.c | 36 +++++++++++++++++++++++++++++++++- include/asoc/msm-cdc-pinctrl.h | 7 ++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/msm-cdc-pinctrl.c b/asoc/codecs/msm-cdc-pinctrl.c index 5c6ca495faed..597be1b980b5 100644 --- a/asoc/codecs/msm-cdc-pinctrl.c +++ b/asoc/codecs/msm-cdc-pinctrl.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #include @@ -21,6 +21,7 @@ struct msm_cdc_pinctrl_info { struct pinctrl *pinctrl; struct pinctrl_state *pinctrl_active; struct pinctrl_state *pinctrl_sleep; + struct pinctrl_state *pinctrl_alt_active; int gpio; bool state; u32 tlmm_gpio[MAX_GPIOS]; @@ -104,6 +105,31 @@ int msm_cdc_pinctrl_select_sleep_state(struct device_node *np) } EXPORT_SYMBOL(msm_cdc_pinctrl_select_sleep_state); +/* + * msm_cdc_pinctrl_select_alt_active_state: select pinctrl alt_active state + * @np: pointer to struct device_node + * + * Returns error code for failure + */ +int msm_cdc_pinctrl_select_alt_active_state(struct device_node *np) +{ + struct msm_cdc_pinctrl_info *gpio_data; + + gpio_data = msm_cdc_pinctrl_get_gpiodata(np); + if (!gpio_data) + return -EINVAL; + + if (!gpio_data->pinctrl_alt_active) { + pr_err("%s: pinctrl alt_active state is null\n", __func__); + return -EINVAL; + } + gpio_data->state = true; + + return pinctrl_select_state(gpio_data->pinctrl, + gpio_data->pinctrl_alt_active); +} +EXPORT_SYMBOL(msm_cdc_pinctrl_select_alt_active_state); + /* * msm_cdc_pinctrl_select_active_state: select pinctrl active state * @np: pointer to struct device_node @@ -231,6 +257,14 @@ static int msm_cdc_pinctrl_probe(struct platform_device *pdev) ret = PTR_ERR(gpio_data->pinctrl_sleep); goto err_lookup_state; } + + gpio_data->pinctrl_alt_active = pinctrl_lookup_state( + gpio_data->pinctrl, "aud_alt_active"); + if (IS_ERR_OR_NULL(gpio_data->pinctrl_alt_active)) { + dev_dbg(&pdev->dev, "%s: Cannot get aud_alt_active pinctrl state:%ld\n", + __func__, PTR_ERR(gpio_data->pinctrl_alt_active)); + } + /* skip setting to sleep state for LPI_TLMM GPIOs */ if (!of_property_read_bool(pdev->dev.of_node, "qcom,lpi-gpios")) { /* Set pinctrl state to aud_sleep by default */ diff --git a/include/asoc/msm-cdc-pinctrl.h b/include/asoc/msm-cdc-pinctrl.h index 89fe699ccb88..3179a8408ed5 100644 --- a/include/asoc/msm-cdc-pinctrl.h +++ b/include/asoc/msm-cdc-pinctrl.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #ifndef __MFD_CDC_PINCTRL_H_ @@ -11,6 +11,7 @@ #if IS_ENABLED(CONFIG_MSM_CDC_PINCTRL) extern int msm_cdc_pinctrl_select_sleep_state(struct device_node *np); extern int msm_cdc_pinctrl_select_active_state(struct device_node *np); +extern int msm_cdc_pinctrl_select_alt_active_state(struct device_node *np); extern int msm_cdc_pinctrl_get_state(struct device_node *np); extern int msm_cdc_get_gpio_state(struct device_node *np); extern int msm_cdc_pinctrl_set_wakeup_capable(struct device_node *np, @@ -27,6 +28,10 @@ int msm_cdc_pinctrl_select_active_state(struct device_node *np) { return 0; } +int msm_cdc_pinctrl_select_alt_active_state(struct device_node *np) +{ + return 0; +} int msm_cdc_get_gpio_state(struct device_node *np) { return 0; -- GitLab From 61518cff6ea27cedd42d2af62c1c1f1221260454 Mon Sep 17 00:00:00 2001 From: Sanjana B Date: Tue, 12 Nov 2019 23:09:27 +0530 Subject: [PATCH 1383/1645] asoc:support for DSD on MI2S interface Add support for DSD in MI2S interface and corresponding api updates from ADSP. Change-Id: I494205763fa429f95e43497ed5b8f91332f5a2a3 Signed-off-by: Sanjana B --- asoc/msm-compress-q6-v2.c | 4 ++-- asoc/msm-dai-q6-v2.c | 8 +++++--- asoc/msm-pcm-routing-v2.c | 10 +++++----- dsp/q6adm.c | 8 +++++--- dsp/q6asm.c | 6 +++++- include/dsp/apr_audio-v2.h | 21 +++++++++++++++++++-- include/dsp/q6adm-v2.h | 5 +++-- 7 files changed, 44 insertions(+), 18 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 45602990ac61..1dc57696e327 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ @@ -1231,7 +1231,7 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, dsd_cfg.dsd_data_rate = prtd->sample_rate; dsd_cfg.num_version = 0; dsd_cfg.is_bitwise_big_endian = 1; - dsd_cfg.dsd_channel_block_size = 1; + dsd_cfg.dsd_channel_block_size = 4; ret = q6asm_media_format_block_dsd(prtd->audio_client, &dsd_cfg, stream_id); if (ret < 0) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index e9d354b8af27..a4a561e8c3a9 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -329,7 +329,8 @@ static const char *const mi2s_format[] = { "NA6", "NA7", "NA8", - "DSD_DOP_W_MARKER" + "DSD_DOP_W_MARKER", + "NATIVE_DSD_DATA" }; static const char *const mi2s_vi_feed_mono[] = { @@ -338,7 +339,7 @@ static const char *const mi2s_vi_feed_mono[] = { }; static const struct soc_enum mi2s_config_enum[] = { - SOC_ENUM_SINGLE_EXT(10, mi2s_format), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mi2s_format), mi2s_format), SOC_ENUM_SINGLE_EXT(2, mi2s_vi_feed_mono), }; @@ -5585,6 +5586,7 @@ static int msm_dai_q6_mi2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBM_CFS: mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.i2s.ws_src = 1; mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.ws_src = 1; break; diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 9cddca06503f..262182f9d2ca 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -1540,7 +1540,7 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, adm_open(port_id, path_type, sample_rate, channels, topology, perf_mode, bit_width, app_type, acdb_dev_id, - session_type); + session_type, passthr_mode); if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { pr_err("%s:adm open failed coppid:%d\n", @@ -1892,7 +1892,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, sample_rate, channels, topology, perf_mode, bits_per_sample, app_type, acdb_dev_id, - session_type); + session_type, passthr_mode); if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { pr_err("%s: adm open failed copp_idx:%d\n", @@ -2173,7 +2173,7 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set) sample_rate, channels, topology, fdai->perf_mode, bits_per_sample, app_type, acdb_dev_id, - session_type); + session_type, passthr_mode); if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { pr_err("%s: adm open failed\n", __func__); @@ -28852,7 +28852,7 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream) sample_rate, channels, topology, fdai->perf_mode, bits_per_sample, app_type, acdb_dev_id, - session_type); + session_type, fdai->passthr_mode); if ((copp_idx < 0) || (copp_idx >= MAX_COPPS_PER_PORT)) { pr_err("%s: adm open failed\n", __func__); diff --git a/dsp/q6adm.c b/dsp/q6adm.c index b161df90aec7..69c0d69096ae 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include #include @@ -2975,7 +2975,7 @@ static int adm_copp_set_ec_ref_mfc_cfg(int port_id, int copp_idx, */ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, int perf_mode, uint16_t bit_width, int app_type, int acdb_id, - int session_type) + int session_type, uint32_t passthr_mode) { struct adm_cmd_device_open_v5 open; struct adm_cmd_device_open_v6 open_v6; @@ -3188,7 +3188,9 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, } open_v8.topology_id = topology; - open_v8.reserved = 0; + open_v8.compressed_data_type = 0; + if (passthr_mode == COMPRESSED_PASSTHROUGH_DSD) + open_v8.compressed_data_type = 1; /* variable endpoint payload */ ep1_payload.dev_num_channel = channel_mode & 0x00FF; diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 11b307a18439..19e23e3b98c1 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. * Author: Brian Swetland * * This software is licensed under the terms of the GNU General Public @@ -3096,6 +3096,10 @@ int q6asm_open_read_compressed(struct audio_client *ac, uint32_t format, open.mode_flags = 0x1; open.frames_per_buf = 1; pr_debug("%s: Flag 1 IEC61937 output\n", __func__); + } else if (format == FORMAT_DSD) { + open.mode_flags = ASM_DSD_FORMAT_FLAG; + open.frames_per_buf = 1; + pr_debug("%s: Flag 2 DSD output\n", __func__); } else { open.mode_flags = 0; open.frames_per_buf = 1; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 0fcc76ae842a..40b44bad7240 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ @@ -598,7 +598,7 @@ struct adm_cmd_device_open_v8 { * In all other use cases this should be set to 0xffff */ - u16 reserved; + u16 compressed_data_type; } __packed; /* @@ -2543,6 +2543,7 @@ struct afe_port_data_cmd_rt_proxy_port_read_v2 { #define AFE_GENERIC_COMPRESSED 0x8 #define AFE_LINEAR_PCM_DATA_PACKED_16BIT 0X6 #define AFE_DSD_DOP_W_MARKER_DATA 0x9 +#define AFE_DSD_DATA 0xA /* This param id is used to configure I2S interface */ #define AFE_PARAM_ID_I2S_CONFIG 0x0001020D @@ -8866,6 +8867,13 @@ struct asm_data_cmd_remove_silence { /* Shift value for the IEC 61937 to 61937 pass-through capture. */ #define ASM_SHIFT_IEC_61937_PASS_THROUGH_FLAG 0 +/* Bitmask for the DSD pass-through capture. */ +#define ASM_BIT_MASK_COMPRESSED_FORMAT_FLAG (0x00000003UL) + +/* Shift value for the DSD pass-through capture. */ +#define ASM_SHIFT_DSD_COMPRESSED_FORMAT_FLAG 0 + +#define ASM_DSD_FORMAT_FLAG 2 struct asm_stream_cmd_open_read_compressed { struct apr_hdr hdr; u32 mode_flags; @@ -8877,6 +8885,12 @@ struct asm_stream_cmd_open_read_compressed { * - Use #ASM_BIT_MASK_IEC_61937_PASS_THROUGH_FLAG to set the bitmask * and #ASM_SHIFT_IEC_61937_PASS_THROUGH_FLAG to set the shift value * for this bit. + * Supported values for bit 1: (DSD native pass-through mode) + * 0 -- non DSD operation + * 1 -- Pass-through transfer of the DSD format stream + * To set this bit, use #ASM_BIT_MASK_DSD_PASS_THROUGH_FLAG and + * use #ASM_SHIFT_DSD_PASS_THROUGH_FLAG to set the shift value for + * this bit * Supported values for bit 4: * - 0 -- Return data buffer contains all encoded frames only; it does * not contain frame metadata. @@ -8893,6 +8907,9 @@ struct asm_stream_cmd_open_read_compressed { * Supported values: should be greater than 0 for IEC to RAW compressed * unpack mode. * Value is don't care for IEC 61937 pass-through mode. + * @values + * - >0 -- For IEC 61937-to-RAW Compressed Unpack mode + * - 1 -- For IEC 61937 or DSD Pass-through mode */ } __packed; diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 894bca40c816..d6945060b676 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef __Q6_ADM_V2_H__ #define __Q6_ADM_V2_H__ @@ -113,7 +113,8 @@ int adm_pack_and_set_one_pp_param(int port_id, int copp_idx, int adm_open(int port, int path, int rate, int mode, int topology, int perf_mode, uint16_t bits_per_sample, - int app_type, int acdbdev_id, int session_type); + int app_type, int acdbdev_id, int session_type, + uint32_t pass_thr); int adm_map_rtac_block(struct rtac_cal_block_data *cal_block); -- GitLab From c45335acb0e4291886973d540fff212fa76a30a3 Mon Sep 17 00:00:00 2001 From: Sanjana B Date: Fri, 6 Dec 2019 17:16:36 +0530 Subject: [PATCH 1384/1645] asoc: update block size for dsd input Update dsd channel block size from codec options. Change-Id: I54011f1092eb8a687d1d4899928daad6746c7aed Signed-off-by: Sanjana B --- asoc/msm-compress-q6-v2.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 1dc57696e327..4890749186a5 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -81,6 +81,8 @@ const DECLARE_TLV_DB_LINEAR(msm_compr_vol_gain, 0, #define COMPRESSED_PERF_MODE_FLAG 0 #endif +#define DSD_BLOCK_SIZE_4 4 + struct msm_compr_gapless_state { bool set_next_stream_id; int32_t stream_opened[MAX_NUMBER_OF_STREAMS]; @@ -1231,7 +1233,12 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, dsd_cfg.dsd_data_rate = prtd->sample_rate; dsd_cfg.num_version = 0; dsd_cfg.is_bitwise_big_endian = 1; - dsd_cfg.dsd_channel_block_size = 4; + dsd_cfg.dsd_channel_block_size = 1; + + if (codec_options->dsd_dec.blk_size == DSD_BLOCK_SIZE_4) + dsd_cfg.dsd_channel_block_size = + codec_options->dsd_dec.blk_size; + ret = q6asm_media_format_block_dsd(prtd->audio_client, &dsd_cfg, stream_id); if (ret < 0) -- GitLab From 94ebdd1be4533a82b9790148de3300ab2d1fa878 Mon Sep 17 00:00:00 2001 From: Sanjana B Date: Wed, 25 Sep 2019 14:20:47 +0530 Subject: [PATCH 1385/1645] asoc: qcs405: add support for dsd input Update machine driver to include support for dsd input. Change-Id: I37aa46484aa617f3ea543391b0edec4f5193d5bf Signed-off-by: Sanjana B --- asoc/qcs405.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 187 insertions(+), 5 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 18dfb82207be..e9e781fa1fba 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include #include @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -173,6 +174,7 @@ struct dev_config { u32 sample_rate; u32 bit_format; u32 channels; + u32 data_format; }; struct msm_wsa881x_dev_info { @@ -201,6 +203,7 @@ struct msm_asoc_mach_data { u32 tdm_micb_voltage; u32 tdm_micb_current; bool codec_is_csra; + void __iomem *mi2s_dsd_mode[MI2S_MAX]; }; struct msm_asoc_wcd93xx_codec { @@ -471,6 +474,19 @@ static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four", static const char *const vi_feed_ch_text[] = {"One", "Two"}; static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", "S32_LE"}; +static const char *const data_format_text[] = { + "LPCM", + "Compr", + "LPCM-60958", + "Compr-60958", + "NA4", + "NA5", + "NA6", + "NA7", + "NA8", + "DSD_DOP_W_MARKER", + "NATIVE_DSD_DATA" +}; static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", "KHZ_44P1", "KHZ_48", "KHZ_88P2", "KHZ_96", "KHZ_176P4", @@ -599,6 +615,8 @@ static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_data_format, data_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_data_format, data_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_meta_mi2s_rx_sample_rate, mi2s_rate_text); @@ -3049,7 +3067,8 @@ static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol, return idx; /* check for PRIM_MI2S and CSRAx config to allow 24bit BE config only */ - if ((PRIM_MI2S == idx) && (true==pdata->codec_is_csra)) + if ((idx == PRIM_MI2S) && (pdata->codec_is_csra == true) + && mi2s_rx_cfg[idx].data_format != AFE_DSD_DATA) { mi2s_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; pr_debug("%s: Keeping default format idx[%d]_rx_format = %d, item = %d\n", @@ -3103,6 +3122,74 @@ static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol, return 0; } +static int msm_mi2s_tx_data_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].data_format = ucontrol->value.enumerated.item[0]; + + pr_debug("%s: idx[%d]_data_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].data_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_data_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].data_format = ucontrol->value.enumerated.item[0]; + + pr_debug("%s: idx[%d]_data_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].data_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_tx_data_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].data_format; + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].data_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_data_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].data_format; + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].data_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + static int msm_meta_mi2s_get_port_idx(struct snd_kcontrol *kcontrol) { int idx = 0; @@ -4125,6 +4212,18 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), SOC_ENUM_EXT("SEN_MI2S_TX Channels", sen_mi2s_tx_chs, msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_TX DataFormat", mi2s_tx_data_format, + msm_mi2s_tx_data_format_get, + msm_mi2s_tx_data_format_put), + SOC_ENUM_EXT("QUAT_MI2S_TX DataFormat", mi2s_tx_data_format, + msm_mi2s_tx_data_format_get, + msm_mi2s_tx_data_format_put), + SOC_ENUM_EXT("PRIM_MI2S_RX DataFormat", mi2s_rx_data_format, + msm_mi2s_rx_data_format_get, + msm_mi2s_rx_data_format_put), + SOC_ENUM_EXT("QUAT_MI2S_RX DataFormat", mi2s_rx_data_format, + msm_mi2s_rx_data_format_get, + msm_mi2s_rx_data_format_put), SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format, @@ -6107,7 +6206,7 @@ static struct snd_soc_ops msm_fe_qos_ops = { static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) { - int ret = 0; + int ret = 0, val = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai_link *dai_link = rtd->dai_link; @@ -6115,6 +6214,12 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + int data_format; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + data_format = mi2s_rx_cfg[index].data_format; + else + data_format = mi2s_tx_cfg[index].data_format; dev_dbg(rtd->card->dev, "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", @@ -6140,6 +6245,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; fmt = SND_SOC_DAIFMT_CBM_CFM; } + + if (data_format == AFE_DSD_DATA) + fmt = SND_SOC_DAIFMT_CBM_CFS; ret = msm_mi2s_set_sclk(substream, true); if (ret < 0) { dev_err(rtd->card->dev, @@ -6154,9 +6262,34 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) __func__, index, ret); goto clk_off; } - if (pdata->mi2s_gpio_p[index]) - msm_cdc_pinctrl_select_active_state( + + if (pdata->mi2s_gpio_p[index]) { + if ((data_format == AFE_DSD_DATA) && + ((index == QUAT_MI2S) || + (index == PRIM_MI2S))) { + msm_cdc_pinctrl_select_alt_active_state( + pdata->mi2s_gpio_p[index]); + } else { + msm_cdc_pinctrl_select_active_state( pdata->mi2s_gpio_p[index]); + } + } + + if (index == QUAT_MI2S || index == PRIM_MI2S) { + switch (data_format) { + case AFE_DSD_DATA: + if (pdata->mi2s_dsd_mode[index]) { + val = ioread32( + pdata->mi2s_dsd_mode[index]); + val = val | 0x1; + iowrite32(val, + pdata->mi2s_dsd_mode[index]); + } + break; + default: + break; + } + } } ret = qcs405_send_island_vad_config(dai_link->id); @@ -6180,11 +6313,18 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) { int ret; + int val; + int data_format; struct snd_soc_pcm_runtime *rtd = substream->private_data; int index = rtd->cpu_dai->id; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + data_format = mi2s_rx_cfg[index].data_format; + else + data_format = mi2s_tx_cfg[index].data_format; + pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); if (index < PRIM_MI2S || index >= MI2S_MAX) { @@ -6198,6 +6338,22 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) msm_cdc_pinctrl_select_sleep_state( pdata->mi2s_gpio_p[index]); + if (index == QUAT_MI2S || index == PRIM_MI2S) { + switch (data_format) { + case AFE_DSD_DATA: + if (pdata->mi2s_dsd_mode[index]) { + val = ioread32( + pdata->mi2s_dsd_mode[index]); + val = val & ~1; + iowrite32(val, + pdata->mi2s_dsd_mode[index]); + } + break; + default: + break; + } + } + ret = msm_mi2s_set_sclk(substream, false); if (ret < 0) pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", @@ -9436,6 +9592,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) const char *micb_supply_str1 = "tdm-vdd-micb"; const char *micb_voltage_str = "qcom,tdm-vdd-micb-voltage"; const char *micb_current_str = "qcom,tdm-vdd-micb-current"; + u32 v_base_addr; if (!pdev->dev.of_node) { dev_err(&pdev->dev, "No platform supplied from device tree\n"); @@ -9447,6 +9604,31 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) if (!pdata) return -ENOMEM; + ret = of_property_read_u32( + pdev->dev.of_node, "tcsr_i2s_dsd_prim", &v_base_addr); + if (ret) { + dev_err(&pdev->dev, "MUX addr invalid for MI2S dsd prim\n"); + } else { + pdata->mi2s_dsd_mode[PRIM_MI2S] = + devm_ioremap(&pdev->dev, v_base_addr, 4); + if (pdata->mi2s_dsd_mode[PRIM_MI2S] == NULL) { + pr_err("%s ioremap failure for muxsel virt addr dsd prim\n", + __func__); + } + } + ret = of_property_read_u32( + pdev->dev.of_node, "tcsr_i2s_dsd_quat", &v_base_addr); + if (ret) { + dev_err(&pdev->dev, "MUX addr invalid for MI2S dsd quat\n"); + } else { + pdata->mi2s_dsd_mode[QUAT_MI2S] = + devm_ioremap(&pdev->dev, v_base_addr, 4); + if (pdata->mi2s_dsd_mode[QUAT_MI2S] == NULL) { + pr_err("%s ioremap failure for muxsel virt addr dsd quat\n", + __func__); + } + } + /* test for ep92 HDMI bridge and update dai links accordingly */ ret = msm_detect_ep92_dev(pdev, card); if (ret) -- GitLab From 7690154b6702194a54315d901be31c825dcff088 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 30 Dec 2019 18:20:47 +0530 Subject: [PATCH 1386/1645] asoc: codecs: Do not update VA clk muxsel register Because of a HW limitation in DSP, while switching RCG from TX MCLK to VA MCLK for SVA use cases a glitch is seen on AHB bus leading to data corruption in registers. So, while doing a mux switch for VA RCG clock selection, do not configure the muxsel register in HLOS as it is taken care in DSP itself as a workaround for HW limitation. Change-Id: Iccbe714397796259fa55f9852ece387e949b12e8 Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/bolero-clk-rsc.c | 63 ++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c index 292162481d5e..7e28c5bfeb86 100644 --- a/asoc/codecs/bolero/bolero-clk-rsc.c +++ b/asoc/codecs/bolero/bolero-clk-rsc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #include @@ -250,10 +250,13 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv, if (enable) { if (priv->clk_cnt[clk_id] == 0) { - ret = bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, + if (clk_id != VA_CORE_CLK) { + ret = bolero_clk_rsc_mux0_clk_request(priv, + default_clk_id, true); - if (ret < 0) - goto done; + if (ret < 0) + goto done; + } ret = clk_prepare_enable(priv->clk[clk_id]); if (ret < 0) { @@ -271,12 +274,22 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv, goto err_npl_clk; } } - iowrite32(0x1, clk_muxsel); - muxsel = ioread32(clk_muxsel); - trace_printk("%s: muxsel value after enable: %d\n", - __func__, muxsel); - bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, + + /* + * Temp SW workaround to address a glitch issue of + * VA GFMux instance responsible for switching from + * TX MCLK to VA MCLK. This configuration would be taken + * care in DSP itself + */ + if (clk_id != VA_CORE_CLK) { + iowrite32(0x1, clk_muxsel); + muxsel = ioread32(clk_muxsel); + trace_printk("%s: muxsel value after enable: %d\n", + __func__, muxsel); + bolero_clk_rsc_mux0_clk_request(priv, + default_clk_id, false); + } } priv->clk_cnt[clk_id]++; } else { @@ -288,23 +301,34 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv, } priv->clk_cnt[clk_id]--; if (priv->clk_cnt[clk_id] == 0) { - ret = bolero_clk_rsc_mux0_clk_request(priv, + if (clk_id != VA_CORE_CLK) { + ret = bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, true); - if (!ret) - iowrite32(0x0, clk_muxsel); - - muxsel = ioread32(clk_muxsel); - trace_printk("%s: muxsel value after disable: %d\n", - __func__, muxsel); + if (!ret) { + /* + * Temp SW workaround to address a glitch issue + * of VA GFMux instance responsible for + * switching from TX MCLK to VA MCLK. + * This configuration would be taken + * care in DSP itself. + */ + iowrite32(0x0, clk_muxsel); + muxsel = ioread32(clk_muxsel); + trace_printk("%s: muxsel value after disable: %d\n", + __func__, muxsel); + } + } if (priv->clk[clk_id + NPL_CLK_OFFSET]) clk_disable_unprepare( priv->clk[clk_id + NPL_CLK_OFFSET]); clk_disable_unprepare(priv->clk[clk_id]); - if (!ret) - bolero_clk_rsc_mux0_clk_request(priv, + if (clk_id != VA_CORE_CLK) { + if (!ret) + bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, false); + } } } return ret; @@ -313,7 +337,8 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv, clk_disable_unprepare(priv->clk[clk_id]); err_clk: - bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, false); + if (clk_id != VA_CORE_CLK) + bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, false); done: return ret; } -- GitLab From 4e908b24c525faf253696c1df2a1913e78f58ca0 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 31 Jan 2020 17:34:54 +0530 Subject: [PATCH 1387/1645] dsp: Make error as debug log when CPU buffer not available When CPU buffer is not available, continuous error log prints leads to excessive logging. Make the error as debug log to avoid this. Change-Id: Ic26006b4975fbe3d5467203d145a517c0067c296 Signed-off-by: Aditya Bavanari --- dsp/q6asm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 11b307a18439..08efe1acd9fc 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. * Author: Brian Swetland * * This software is licensed under the terms of the GNU General Public @@ -2552,7 +2552,7 @@ void *q6asm_is_cpu_buf_avail(int dir, struct audio_client *ac, uint32_t *size, /* To make it more robust, we could loop and get the * next avail buf, its risky though */ - pr_err("%s: Next buf idx[0x%x] not available, dir[%d]\n", + pr_debug("%s: Next buf idx[0x%x] not available, dir[%d]\n", __func__, idx, dir); mutex_unlock(&port->lock); return NULL; -- GitLab From 60720686b31096e451d0a721026e86ff3d253501 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 30 Jan 2020 16:11:15 +0530 Subject: [PATCH 1388/1645] bolero: va-macro: add dmic va rate to 1.2M for bolero 2.1 In bolero 2.1, VA macro has low power decimations and support 600k only at 8k/16k. For non-LPI sessions running at 48k will have mute data if use 600k. Update driver to use 1.2M for non-LPI sessions. Change-Id: If495ba8fb780bd22f188835ef87a0ec947df363c Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/va-macro.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 4fb16baf78ee..a0c0fd7faacc 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -202,6 +202,11 @@ static int va_macro_clk_div_get(struct snd_soc_component *component) if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; + if ((va_priv->version == BOLERO_VERSION_2_1) + && !va_priv->lpi_enable + && (va_priv->dmic_clk_div == VA_MACRO_CLK_DIV_16)) + return VA_MACRO_CLK_DIV_8; + return va_priv->dmic_clk_div; } -- GitLab From 1f2565b4f818cc506845a9d32d71cd4527e5d8d1 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 30 Jan 2020 05:22:47 +0530 Subject: [PATCH 1389/1645] soc: soundwire: use clock stop instead of clock pause If soundwire slave supports clock stop mode, use the clock stop mode instead of clock pause to avoid bus clash interrupts. Change-Id: I6eb0c76ffc0785c40d086f18ca16769a463f2e89 Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index b8f8e2ac6393..905286547970 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2988,7 +2988,23 @@ static int swrm_runtime_suspend(struct device *dev) mutex_unlock(&swrm->reslock); enable_bank_switch(swrm, 0, SWR_ROW_50, SWR_MIN_COL); mutex_lock(&swrm->reslock); - swrm_clk_pause(swrm); + if (!swrm->clk_stop_mode0_supp) { + swrm_clk_pause(swrm); + } else { + /* Mask bus clash interrupt */ + swrm->intr_mask &= ~((u32)0x08); + swr_master_write(swrm, + SWRM_INTERRUPT_MASK_ADDR, + swrm->intr_mask); + swr_master_write(swrm, + SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN, + swrm->intr_mask); + mutex_unlock(&swrm->reslock); + /* clock stop sequence */ + swrm_cmd_fifo_wr_cmd(swrm, 0x2, 0xF, 0xF, + SWRS_SCP_CONTROL); + mutex_lock(&swrm->reslock); + } swr_master_write(swrm, SWRM_COMP_CFG_ADDR, 0x00); list_for_each_entry(swr_dev, &mstr->devices, dev_list) { ret = swr_device_down(swr_dev); -- GitLab From 0bb3a1552ede02d56f229dc8b67826abf567519a Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 3 Feb 2020 12:47:48 +0530 Subject: [PATCH 1390/1645] asoc: wsa881x-analog: Disable MCLK if clk enabled state In WSA analog driver, disable MCLK only if clock enabled. Change-Id: I3a6aa42dc258e3c6ad1ceccdf74f0136338d79b2 Signed-off-by: Laxminath Kasam --- asoc/codecs/wsa881x-analog.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wsa881x-analog.c b/asoc/codecs/wsa881x-analog.c index c6b40669b343..038e338e53b6 100644 --- a/asoc/codecs/wsa881x-analog.c +++ b/asoc/codecs/wsa881x-analog.c @@ -1,9 +1,10 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2016, 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016, 2018-2020, The Linux Foundation. All rights reserved. */ #include +#include #include #include #include @@ -1027,7 +1028,8 @@ static int wsa881x_shutdown(struct wsa881x_pdata *pdata) return ret; } - clk_disable_unprepare(pdata->wsa_mclk); + if (__clk_is_enabled(pdata->wsa_mclk)) + clk_disable_unprepare(pdata->wsa_mclk); ret = msm_cdc_pinctrl_select_sleep_state(pdata->wsa_clk_gpio_p); if (ret) { -- GitLab From 018dbd2d4c16e3ae13828c94e5fa15b0743bfbe6 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 10 Feb 2020 16:53:58 +0530 Subject: [PATCH 1391/1645] ASoC: wcd937x: Fix headset record pop during SSR Pop is heard with special headset with silence record during SSR. Resolve pop by allowing sufficient time for wcd937x_reset post SSR and again initialize registers post SSR. Change-Id: I80e70a98a72b247dca878673a30651647b676659 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index cf1f5c9edbc6..01965391d4d9 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include @@ -1587,14 +1587,13 @@ static int wcd937x_event_notify(struct notifier_block *block, break; case BOLERO_WCD_EVT_SSR_UP: wcd937x_reset(wcd937x->dev); + /* allow reset to take effect */ + usleep_range(10000, 10010); wcd937x_get_logical_addr(wcd937x->tx_swr_dev); wcd937x_get_logical_addr(wcd937x->rx_swr_dev); + wcd937x_init_reg(component); regcache_mark_dirty(wcd937x->regmap); regcache_sync(wcd937x->regmap); - /* Enable surge protection */ - snd_soc_component_update_bits(component, - WCD937X_HPH_SURGE_HPHLR_SURGE_EN, - 0xFF, 0xD9); /* Initialize MBHC module */ mbhc = &wcd937x->mbhc->wcd_mbhc; ret = wcd937x_mbhc_post_ssr_init(wcd937x->mbhc, component); -- GitLab From 56c0a54c0fbdcf03812be9a3cd671b11bdf16698 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 4 Feb 2020 12:14:45 +0530 Subject: [PATCH 1392/1645] ASoC: wcd938x: Enable surge protection at bootup Enable surge protection at bootup for traverso. Change-Id: I443c576e6fdfc640b8e67c2d3f9622e8c3366d45 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd938x/wcd938x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index faa264f92b59..c65bf4d9ddd3 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -268,6 +268,8 @@ static int wcd938x_init_reg(struct snd_soc_component *component) snd_soc_component_update_bits(component, WCD938X_SLEEP_CTL, 0x0E, ((snd_soc_component_read32(component, WCD938X_DIGITAL_EFUSE_REG_30) & 0x07) << 1)); + snd_soc_component_update_bits(component, + WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0xC0); return 0; } -- GitLab From d8bb93c41bb116b22ae1deb79cbb672b5b5e4ecd Mon Sep 17 00:00:00 2001 From: Xiao Li Date: Tue, 7 Jan 2020 12:59:05 +0800 Subject: [PATCH 1393/1645] asoc: fix compilation issue Initialize some uninitlaized variable and correct some log. Change-Id: Ibd29a423450f6470e99941a7f3970128d11d9197 Signed-off-by: Xiao Li --- asoc/codecs/bolero/bolero-cdc.c | 2 +- asoc/codecs/bolero/bolero-clk-rsc.c | 8 ++++---- asoc/codecs/bolero/rx-macro.c | 4 ++-- asoc/codecs/wcd938x/wcd938x-slave.c | 4 ++-- asoc/codecs/wcd938x/wcd938x.c | 2 +- asoc/codecs/wsa881x.c | 6 +++--- asoc/kona.c | 6 +++--- asoc/msm-pcm-dtmf-v2.c | 4 ++-- dsp/q6lsm.c | 6 +++--- soc/pinctrl-lpi.c | 4 ++-- soc/soundwire.c | 6 +++--- soc/swr-mstr-ctrl.c | 2 +- 12 files changed, 27 insertions(+), 27 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 53640a23a09e..6d1887e0e0a8 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -654,7 +654,7 @@ int bolero_register_macro(struct device *dev, u16 macro_id, priv->num_macros_registered++; priv->macros_supported[macro_id] = true; - dev_dbg(dev, "%s: register macro successful:%d\n", macro_id); + dev_dbg(dev, "%s: register macro successful:%d\n", __func__, macro_id); if (priv->num_macros_registered == priv->num_macros) { ret = bolero_copy_dais_from_macro(priv); diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c index 7e28c5bfeb86..daed7e656684 100644 --- a/asoc/codecs/bolero/bolero-clk-rsc.c +++ b/asoc/codecs/bolero/bolero-clk-rsc.c @@ -100,7 +100,7 @@ int bolero_rsc_clk_reset(struct device *dev, int clk_id) int count = 0; if (!dev) { - pr_err("%s: dev is null %d\n", __func__); + pr_err("%s: dev is null\n", __func__); return -EINVAL; } @@ -147,7 +147,7 @@ void bolero_clk_rsc_enable_all_clocks(struct device *dev, bool enable) int i = 0; if (!dev) { - pr_err("%s: dev is null %d\n", __func__); + pr_err("%s: dev is null\n", __func__); return; } @@ -439,7 +439,7 @@ void bolero_clk_rsc_fs_gen_request(struct device *dev, bool enable) struct bolero_clk_rsc *priv = NULL; if (!dev) { - pr_err("%s: dev is null %d\n", __func__); + pr_err("%s: dev is null\n", __func__); return; } clk_dev = bolero_get_rsc_clk_device_ptr(dev->parent); @@ -514,7 +514,7 @@ int bolero_clk_rsc_request_clock(struct device *dev, bool mux_switch = false; if (!dev) { - pr_err("%s: dev is null %d\n", __func__); + pr_err("%s: dev is null\n", __func__); return -EINVAL; } if ((clk_id_req < 0 || clk_id_req >= MAX_CLK) && diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 22ddf3f88ecd..1c17d7ce617b 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include @@ -1120,7 +1120,7 @@ static int rx_macro_get_channel_map(struct snd_soc_dai *dai, *rx_slot = ch_mask; *rx_num = rx_priv->active_ch_cnt[dai->id]; dev_dbg(rx_priv->dev, - "%s: dai->id:%d, ch_mask:0x%x, active_ch_cnt:%d active_mask: 0x%x\n", + "%s: dai->id:%d, ch_mask:0x%x, active_ch_cnt:%d active_mask: 0x%lx\n", __func__, dai->id, *rx_slot, *rx_num, rx_priv->active_ch_mask[dai->id]); break; case RX_MACRO_AIF_ECHO: diff --git a/asoc/codecs/wcd938x/wcd938x-slave.c b/asoc/codecs/wcd938x/wcd938x-slave.c index 75cc7839c6d4..1f83b4ce1da5 100644 --- a/asoc/codecs/wcd938x/wcd938x-slave.c +++ b/asoc/codecs/wcd938x/wcd938x-slave.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include @@ -287,7 +287,7 @@ static int wcd938x_slave_bind(struct device *dev, ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum); if (ret) { dev_dbg(&pdev->dev, - "%s get devnum %d for dev addr %lx failed\n", + "%s get devnum %d for dev addr %llx failed\n", __func__, devnum, pdev->addr); return ret; } diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index faa264f92b59..99e15be4f3cf 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1958,7 +1958,7 @@ static int wcd938x_get_logical_addr(struct swr_device *swr_dev) ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum); if (ret) { dev_err(&swr_dev->dev, - "%s get devnum %d for dev addr %lx failed\n", + "%s get devnum %d for dev addr %llx failed\n", __func__, devnum, swr_dev->addr); /* retry after 1ms */ usleep_range(1000, 1010); diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index fc4f12387be1..11d5c3f8e37d 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #include @@ -1232,7 +1232,7 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_component *component, } if (retry == 0) { dev_err(component->dev, - "%s get devnum %d for dev addr %lx failed\n", + "%s get devnum %d for dev addr %llx failed\n", __func__, devnum, dev->addr); return -EINVAL; } @@ -1479,7 +1479,7 @@ static int wsa881x_swr_probe(struct swr_device *pdev) ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum); if (ret) { dev_dbg(&pdev->dev, - "%s get devnum %d for dev addr %lx failed\n", + "%s get devnum %d for dev addr %llx failed\n", __func__, devnum, pdev->addr); goto dev_err; } diff --git a/asoc/kona.c b/asoc/kona.c index bbb790983ae1..0272de53cd0a 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #include @@ -7596,8 +7596,8 @@ static int msm_init_aux_dev(struct platform_device *pdev, u32 codec_max_aux_devs = 0; u32 codec_aux_dev_cnt = 0; int i; - struct msm_wsa881x_dev_info *wsa881x_dev_info; - struct aux_codec_dev_info *aux_cdc_dev_info; + struct msm_wsa881x_dev_info *wsa881x_dev_info = NULL; + struct aux_codec_dev_info *aux_cdc_dev_info = NULL; const char *auxdev_name_prefix[1]; char *dev_name_str = NULL; int found = 0; diff --git a/asoc/msm-pcm-dtmf-v2.c b/asoc/msm-pcm-dtmf-v2.c index 3dc7a26a54c8..a13610215b6c 100644 --- a/asoc/msm-pcm-dtmf-v2.c +++ b/asoc/msm-pcm-dtmf-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2013-2014, 2017-2019 The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2017-2020 The Linux Foundation. All rights reserved. */ #include @@ -97,7 +97,7 @@ static int msm_dtmf_rx_generate_put(struct snd_kcontrol *kcontrol, uint16_t gain = ucontrol->value.integer.value[3]; pr_debug("%s: low_freq=%d high_freq=%d duration=%lld gain=%d\n", - __func__, low_freq, high_freq, (int)duration, gain); + __func__, low_freq, high_freq, duration, gain); if (duration == DTMF_MAX_DURATION) duration = -1; diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 8df449e499e7..66883ba77afb 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2013-2019, Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020, Linux Foundation. All rights reserved. */ #include #include @@ -1098,7 +1098,7 @@ int q6lsm_set_afe_data_format(uint64_t fe_id, uint16_t afe_data_format) lsm_client_afe_data[n].fe_id = fe_id; lsm_client_afe_data[n].unprocessed_data = afe_data_format; - pr_debug("%s: session ID is %d, fe_id is %d\n", + pr_debug("%s: session ID is %d, fe_id is %llu\n", __func__, n, fe_id); return 0; } @@ -1131,7 +1131,7 @@ void q6lsm_get_afe_data_format(uint64_t fe_id, uint16_t *afe_data_format) if (fe_id == lsm_client_afe_data[n].fe_id) { *afe_data_format = lsm_client_afe_data[n].unprocessed_data; - pr_debug("%s: session: %d, fe_id: %d, afe data: %s\n", + pr_debug("%s: session: %d, fe_id: %llu, afe data: %s\n", __func__, n, fe_id, *afe_data_format ? "unprocessed" : "processed"); return; diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index e69afdd717dc..c3d2326af593 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #include @@ -691,7 +691,7 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) } } else { slew_base = NULL; - dev_dbg(dev, "error in reading lpi slew register: %d\n", + dev_dbg(dev, "%s: error in reading lpi slew register: %d\n", __func__, ret); } diff --git a/soc/soundwire.c b/soc/soundwire.c index 72a94ace1482..2aa3ba4bdae0 100644 --- a/soc/soundwire.c +++ b/soc/soundwire.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #include @@ -126,7 +126,7 @@ struct swr_device *swr_new_device(struct swr_master *master, list_add_tail(&swr->dev_list, &master->devices); mutex_unlock(&master->mlock); - dev_set_name(&swr->dev, "%s.%lx", swr->name, swr->addr); + dev_set_name(&swr->dev, "%s.%llx", swr->name, swr->addr); result = device_register(&swr->dev); if (result) { dev_err(&master->dev, "device [%s] register failed err %d\n", @@ -138,7 +138,7 @@ struct swr_device *swr_new_device(struct swr_master *master, return swr; err_out: - dev_dbg(&master->dev, "Failed to register swr device %s at 0x%lx %d\n", + dev_dbg(&master->dev, "Failed to register swr device %s at 0x%llx %d\n", swr->name, swr->addr, result); swr_master_put(master); kfree(swr); diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 905286547970..539f9b935346 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2211,7 +2211,7 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id, ret = 0; } dev_dbg(swrm->dev, - "%s: devnum %d is assigned for dev addr %lx\n", + "%s: devnum %d is assigned for dev addr %llx\n", __func__, i, swr_dev->addr); } } -- GitLab From 9b8ab6d7f388c4024fcc0533edeff50b6eb46d26 Mon Sep 17 00:00:00 2001 From: Baochu Xu Date: Tue, 7 Jan 2020 15:36:04 +0800 Subject: [PATCH 1394/1645] audio-kernel: enable kona audio driver Enable kona audio driver for qrb5165. Change-Id: Ibf791f264bd29462f464cbe42318433bb2b7e54b --- Makefile.am | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Makefile.am b/Makefile.am index 9d263f2b8f98..14e8a8cc211e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -37,6 +37,11 @@ obj-m += asoc/codecs/bolero/ obj-m += asoc/codecs/wcd937x/ endif +ifeq ($(TARGET_SUPPORT), qrb5165) +obj-m += asoc/codecs/bolero/ +obj-m += asoc/codecs/wcd938x/ +endif + ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155 sa8155ivi sa6155 sa8195 qtiquingvm)) obj-m := ipc/ obj-m += dsp/ @@ -49,6 +54,9 @@ endif ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa6155)) KBUILD_OPTIONS += CONFIG_SND_SOC_SA6155=m endif +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), qrb5165)) +KBUILD_OPTIONS += CONFIG_SND_SOC_KONA=m +endif endif all: -- GitLab From 51672c60eabde657b98e626d328bff47e60478f2 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 21 Jan 2020 17:11:52 +0530 Subject: [PATCH 1395/1645] soc: swr-mstr: Enable dual-mic SVA for ULP2 mode Dual-Mic SVA in ULP2 mode has noise. Enable DIV2 bit based on enabled bank to resolve the issue. Change-Id: Icb35153924b972e0197a2b2b4142b5bffb787823 Signed-off-by: Vatsal Bucha --- include/soc/swr-wcd.h | 4 +++- soc/swr-mstr-ctrl.c | 9 ++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/soc/swr-wcd.h b/include/soc/swr-wcd.h index 8ed9f0a05e3b..c3e720a6410a 100644 --- a/include/soc/swr-wcd.h +++ b/include/soc/swr-wcd.h @@ -32,8 +32,10 @@ struct swr_mstr_port { }; #define MCLK_FREQ 9600000 -#define MCLK_FREQ_LP 600000 +#define MCLK_FREQ_LP 4800000 #define MCLK_FREQ_NATIVE 11289600 +#define MCLK_FREQ_ULP1 1200000 +#define MCLK_FREQ_ULP2 600000 #if (IS_ENABLED(CONFIG_SOUNDWIRE_WCD_CTRL) || \ IS_ENABLED(CONFIG_SOUNDWIRE_MSTR_CTRL)) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 905286547970..61b01856a703 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1296,9 +1296,12 @@ static void swrm_apply_port_config(struct swr_master *master) dev_dbg(swrm->dev, "%s: enter bank: %d master_ports: %d\n", __func__, bank, master->num_port); - - swrm_cmd_fifo_wr_cmd(swrm, 0x01, 0xF, 0x00, - SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(bank)); + if (bank == 0) + swrm_cmd_fifo_wr_cmd(swrm, 0x01, 0xF, 0x00, + SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(bank)); + else + swrm_cmd_fifo_wr_cmd(swrm, 0x00, 0xF, 0x00, + SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(bank)); swrm_copy_data_port_config(master, bank); } -- GitLab From 9a5be741993e6d84ac7ec5cb312e2f886968cea5 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Thu, 13 Feb 2020 14:15:01 -0800 Subject: [PATCH 1396/1645] ASoC: msm: unmap and free dma memory if smmu map failed Unmap and free DMA memory in case of ION SMMU mapping failure from PVM backend or MMHAB. Change-Id: I2d2780941ba6922534654afa463a011f27ef7c66 Signed-off-by: Derek Chen --- dsp/msm_audio_ion_vm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dsp/msm_audio_ion_vm.c b/dsp/msm_audio_ion_vm.c index f9635b3328d1..a84403750574 100644 --- a/dsp/msm_audio_ion_vm.c +++ b/dsp/msm_audio_ion_vm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. */ #include @@ -564,6 +564,7 @@ static int msm_audio_ion_map_buf(void *handle, dma_addr_t *paddr, if (rc) { pr_err("%s: failed to do smmu map, err = %d\n", __func__, rc); + msm_audio_dma_buf_unmap((struct dma_buf *) handle); goto err; } } -- GitLab From 71fef46921846cf0baa5f45c1cab6658b15fc7b6 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Fri, 31 Jan 2020 21:38:58 +0530 Subject: [PATCH 1397/1645] asoc: Fix port collision interrupt in WSA During multiple PDR usecases, due to sync issues port collision interrupt is observed. set wsa state to device down before cancelling the ocp workqueue and bail out from the workqueue when wsa state is set to device down. Change-Id: Ibefb338c1d6d2901b8773928fa2c0c48b51ac6f7 Signed-off-by: Prasad Kumpatla --- asoc/codecs/bolero/rx-macro.c | 3 --- asoc/codecs/bolero/tx-macro.c | 3 --- asoc/codecs/bolero/va-macro.c | 3 --- asoc/codecs/bolero/wsa-macro.c | 5 +---- asoc/codecs/wsa881x.c | 7 +++++-- soc/swr-mstr-ctrl.c | 7 +++++++ 6 files changed, 13 insertions(+), 15 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 1c17d7ce617b..ea1a3741a372 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1374,9 +1374,6 @@ static int rx_macro_event_handler(struct snd_soc_component *component, trace_printk("%s, enter SSR down\n", __func__); rx_priv->dev_up = false; if (rx_priv->swr_ctrl_data) { - swrm_wcd_notify( - rx_priv->swr_ctrl_data[0].rx_swr_pdev, - SWR_DEVICE_DOWN, NULL); swrm_wcd_notify( rx_priv->swr_ctrl_data[0].rx_swr_pdev, SWR_DEVICE_SSR_DOWN, NULL); diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 674495f7027b..12b37ab84396 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -375,9 +375,6 @@ static int tx_macro_event_handler(struct snd_soc_component *component, case BOLERO_MACRO_EVT_SSR_DOWN: trace_printk("%s, enter SSR down\n", __func__); if (tx_priv->swr_ctrl_data) { - swrm_wcd_notify( - tx_priv->swr_ctrl_data[0].tx_swr_pdev, - SWR_DEVICE_DOWN, NULL); swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, SWR_DEVICE_SSR_DOWN, NULL); diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index a0c0fd7faacc..1336c7c78577 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -325,9 +325,6 @@ static int va_macro_event_handler(struct snd_soc_component *component, break; case BOLERO_MACRO_EVT_SSR_DOWN: if (va_priv->swr_ctrl_data) { - swrm_wcd_notify( - va_priv->swr_ctrl_data[0].va_swr_pdev, - SWR_DEVICE_DOWN, NULL); swrm_wcd_notify( va_priv->swr_ctrl_data[0].va_swr_pdev, SWR_DEVICE_SSR_DOWN, NULL); diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index e42627f70066..e97d74607a1b 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include @@ -996,9 +996,6 @@ static int wsa_macro_event_handler(struct snd_soc_component *component, case BOLERO_MACRO_EVT_SSR_DOWN: trace_printk("%s, enter SSR down\n", __func__); if (wsa_priv->swr_ctrl_data) { - swrm_wcd_notify( - wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, - SWR_DEVICE_DOWN, NULL); swrm_wcd_notify( wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, SWR_DEVICE_SSR_DOWN, NULL); diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index 11d5c3f8e37d..fe88d805d932 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -985,6 +985,9 @@ static void wsa881x_ocp_ctl_work(struct work_struct *work) dwork = to_delayed_work(work); wsa881x = container_of(dwork, struct wsa881x_priv, ocp_ctl_work); + if (wsa881x->state == WSA881X_DEV_DOWN) + return; + component = wsa881x->component; wsa881x_get_temp(wsa881x->tz_pdata.tz_dev, &temp_val); dev_dbg(component->dev, " temp = %d\n", temp_val); @@ -1598,14 +1601,14 @@ static int wsa881x_swr_down(struct swr_device *pdev) dev_err(&pdev->dev, "%s: wsa881x is NULL\n", __func__); return -EINVAL; } - if (delayed_work_pending(&wsa881x->ocp_ctl_work)) - cancel_delayed_work_sync(&wsa881x->ocp_ctl_work); ret = wsa881x_gpio_ctrl(wsa881x, false); if (ret) dev_err(&pdev->dev, "%s: Failed to disable gpio\n", __func__); else wsa881x->state = WSA881X_DEV_DOWN; + if (delayed_work_pending(&wsa881x->ocp_ctl_work)) + cancel_delayed_work_sync(&wsa881x->ocp_ctl_work); return ret; } diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 539f9b935346..5f6329d1e81e 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -3280,12 +3280,19 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) break; case SWR_DEVICE_SSR_DOWN: trace_printk("%s: swr device down called\n", __func__); + mutex_lock(&swrm->mlock); + if (swrm->state == SWR_MSTR_DOWN) + dev_dbg(swrm->dev, "%s:SWR master is already Down:%d\n", + __func__, swrm->state); + else + swrm_device_down(&pdev->dev); mutex_lock(&swrm->devlock); swrm->dev_up = false; mutex_unlock(&swrm->devlock); mutex_lock(&swrm->reslock); swrm->state = SWR_MSTR_SSR; mutex_unlock(&swrm->reslock); + mutex_unlock(&swrm->mlock); break; case SWR_DEVICE_SSR_UP: /* wait for clk voting to be zero */ -- GitLab From f2b783618d869496115e98b11c6419a73e9f4aa0 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 7 Feb 2020 19:06:01 +0530 Subject: [PATCH 1398/1645] asoc: bolero: Update dmic clk_div for bolero 2.x For bolero 2.x, update dmic clk_div to use 1.2M instead of 600k if non-island usecase. Change-Id: Ia057283c164de576cfd05f4c64f6db24db589ead Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/va-macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index a0c0fd7faacc..213072d79ba1 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -202,7 +202,7 @@ static int va_macro_clk_div_get(struct snd_soc_component *component) if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; - if ((va_priv->version == BOLERO_VERSION_2_1) + if ((va_priv->version >= BOLERO_VERSION_2_0) && !va_priv->lpi_enable && (va_priv->dmic_clk_div == VA_MACRO_CLK_DIV_16)) return VA_MACRO_CLK_DIV_8; -- GitLab From f0af11ee9425e9a8e15a90d501c82f0b4272081c Mon Sep 17 00:00:00 2001 From: Kunlei Zhang Date: Wed, 19 Feb 2020 13:35:51 +0800 Subject: [PATCH 1399/1645] asoc: wcd937x: Fix compile error in wcd937x codec driver Update function return value to avoid compile error Change-Id: Ia463ea8bb3c87ac6fb9f5959be0f5a6fa461667d Signed-off-by: Kunlei Zhang --- asoc/codecs/wcd937x/wcd937x-mbhc.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x-mbhc.h b/asoc/codecs/wcd937x/wcd937x-mbhc.h index 43d16618956f..2e6bbe88f6b0 100644 --- a/asoc/codecs/wcd937x/wcd937x-mbhc.h +++ b/asoc/codecs/wcd937x/wcd937x-mbhc.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #ifndef __WCD937X_MBHC_H__ #define __WCD937X_MBHC_H__ @@ -52,7 +52,6 @@ static inline int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc, static inline void wcd937x_mbhc_ssr_down(struct wcd937x_mbhc *mbhc, struct snd_soc_component *component) { - return 0; } static inline int wcd937x_mbhc_get_impedance(struct wcd937x_mbhc *wcd937x_mbhc, uint32_t *zl, uint32_t *zr) -- GitLab From 80995e693b6d7783d97a7dedf3762cb7939da764 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 20 Feb 2020 14:35:44 +0530 Subject: [PATCH 1400/1645] Revert "soc: swr-mstr: Enable dual-mic SVA for ULP2 mode" Revert change to enable dual-mic SVA as speaker protection regressed with the change. This reverts commit 51672c60eabde657b98e626d328bff47e60478f2. --- include/soc/swr-wcd.h | 4 +--- soc/swr-mstr-ctrl.c | 9 +++------ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/include/soc/swr-wcd.h b/include/soc/swr-wcd.h index c3e720a6410a..8ed9f0a05e3b 100644 --- a/include/soc/swr-wcd.h +++ b/include/soc/swr-wcd.h @@ -32,10 +32,8 @@ struct swr_mstr_port { }; #define MCLK_FREQ 9600000 -#define MCLK_FREQ_LP 4800000 +#define MCLK_FREQ_LP 600000 #define MCLK_FREQ_NATIVE 11289600 -#define MCLK_FREQ_ULP1 1200000 -#define MCLK_FREQ_ULP2 600000 #if (IS_ENABLED(CONFIG_SOUNDWIRE_WCD_CTRL) || \ IS_ENABLED(CONFIG_SOUNDWIRE_MSTR_CTRL)) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index baed963e66ce..539f9b935346 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1296,12 +1296,9 @@ static void swrm_apply_port_config(struct swr_master *master) dev_dbg(swrm->dev, "%s: enter bank: %d master_ports: %d\n", __func__, bank, master->num_port); - if (bank == 0) - swrm_cmd_fifo_wr_cmd(swrm, 0x01, 0xF, 0x00, - SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(bank)); - else - swrm_cmd_fifo_wr_cmd(swrm, 0x00, 0xF, 0x00, - SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(bank)); + + swrm_cmd_fifo_wr_cmd(swrm, 0x01, 0xF, 0x00, + SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(bank)); swrm_copy_data_port_config(master, bank); } -- GitLab From 80ac1b29f1ea6be32eddb33bdf3d72407b315f38 Mon Sep 17 00:00:00 2001 From: Ajit Pandey Date: Tue, 11 Feb 2020 09:57:53 +0530 Subject: [PATCH 1401/1645] ASoC: msm-routing: Add lock in lsm_app_type_cfg_control callbacks Add routing_lock mutex to protect global variables in _get() & _put() callback of Listen App Type Config mixer control. Change-Id: I6857a6e72dcb7f21633919b716910577af4906d2 Signed-off-by: Ajit Pandey --- asoc/msm-pcm-routing-v2.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 30579bc1d391..144755e62eac 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -22249,6 +22249,7 @@ static int msm_routing_get_lsm_app_type_cfg_control( kcontrol->private_value)->shift; int i = 0, j = 0; + mutex_lock(&routing_lock); ucontrol->value.integer.value[i] = num_app_cfg_types; for (j = 0; j < num_app_cfg_types; ++j) { @@ -22262,6 +22263,7 @@ static int msm_routing_get_lsm_app_type_cfg_control( ucontrol->value.integer.value[++i] = lsm_app_type_cfg[j].num_out_channels; } + mutex_unlock(&routing_lock); return 0; } @@ -22273,9 +22275,11 @@ static int msm_routing_put_lsm_app_type_cfg_control( kcontrol->private_value)->shift; int i = 0, j; + mutex_lock(&routing_lock); if (ucontrol->value.integer.value[0] > MAX_APP_TYPES) { pr_err("%s: number of app types exceed the max supported\n", __func__); + mutex_unlock(&routing_lock); return -EINVAL; } @@ -22295,7 +22299,7 @@ static int msm_routing_put_lsm_app_type_cfg_control( lsm_app_type_cfg[j].num_out_channels = ucontrol->value.integer.value[i++]; } - + mutex_unlock(&routing_lock); return 0; } -- GitLab From 1c53d889f4fb93831aa80327c291c128716ea424 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 13 Feb 2020 11:14:58 +0530 Subject: [PATCH 1402/1645] dsp: Correct the instance ID assignment in IIR sidetone In set param for IIR sidetone in AFE, instance ID assignment is done to param ID. Correct the assigment to fix this. Change-Id: I3fc6011631a6b581facddc9c417e219ed25cc3a4 Signed-off-by: Aditya Bavanari --- dsp/q6afe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 11f3c3e63a39..16d156783c53 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include #include @@ -7020,7 +7020,7 @@ static int afe_sidetone_iir(u16 tx_port_id) * Set IIR enable params */ param_hdr.module_id = mid; - param_hdr.param_id = INSTANCE_ID_0; + param_hdr.instance_id = INSTANCE_ID_0; param_hdr.param_id = AFE_PARAM_ID_ENABLE; param_hdr.param_size = sizeof(enable); enable.enable = iir_enable; -- GitLab From 4f5815c8ed6d8673306c17b3e9d95fda7cfc4bbb Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 13 Feb 2020 14:10:20 +0800 Subject: [PATCH 1403/1645] asoc: kona: set wakeup to false when GPIOs are used as MI2S set wakeup to false when GPIOs are used as MI2S. Change-Id: I6c620270f073bcbdf87d0121af4afaa1a8ede0dc Signed-off-by: Meng Wang --- asoc/kona.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/asoc/kona.c b/asoc/kona.c index 0272de53cd0a..68f6ddbc1a8e 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -8157,8 +8157,11 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) "qcom,quin-mi2s-gpios", 0); pdata->mi2s_gpio_p[SEN_MI2S] = of_parse_phandle(pdev->dev.of_node, "qcom,sen-mi2s-gpios", 0); - for (index = PRIM_MI2S; index < MI2S_MAX; index++) + for (index = PRIM_MI2S; index < MI2S_MAX; index++) { + if (pdata->mi2s_gpio_p[index]) + msm_cdc_pinctrl_set_wakeup_capable(pdata->mi2s_gpio_p[index], false); atomic_set(&(pdata->mi2s_gpio_ref_count[index]), 0); + } /* Register LPASS audio hw vote */ lpass_audio_hw_vote = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote"); -- GitLab From 48147837b599da6531debb9c7711cc075f342d64 Mon Sep 17 00:00:00 2001 From: Hui Li Date: Wed, 12 Feb 2020 14:49:37 +0800 Subject: [PATCH 1404/1645] dsp: use dma handle as default input in hab export currently in hab driver, it want to hold all bufs as dmabuf for fulture implement, and it's hard to get dmabuf fd/handle from a kva, so hab need to generate a new dmabuf for itself, and this will intruduce audio crash issue in conclusion, for now hab just accept dma fd/handl as input in KHAB export path. Change-Id: I11715ba966036f7c02b67d0bdae97eb6d7118d5c Signed-off-by: Hui Li --- dsp/msm_audio_ion_vm.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/dsp/msm_audio_ion_vm.c b/dsp/msm_audio_ion_vm.c index a84403750574..37b17b685687 100644 --- a/dsp/msm_audio_ion_vm.c +++ b/dsp/msm_audio_ion_vm.c @@ -306,7 +306,6 @@ static int msm_audio_ion_smmu_map(void *handle, struct msm_audio_smmu_vm_map_cmd_rsp cmd_rsp; struct msm_audio_alloc_data *alloc_data = NULL; unsigned long delay = jiffies + (HZ / 2); - void *vaddr; *len = ((struct dma_buf*)handle)->size; @@ -315,14 +314,13 @@ static int msm_audio_ion_smmu_map(void *handle, list) { if (alloc_data->handle == handle) { found = true; - vaddr = alloc_data->vaddr; /* Export the buffer to physical VM */ - rc = habmm_export(msm_audio_ion_hab_handle, vaddr, *len, - &export_id, 0); + rc = habmm_export(msm_audio_ion_hab_handle, handle, *len, + &export_id, HABMM_EXPIMP_FLAGS_DMABUF); if (rc) { - pr_err("%s: habmm_export failed vaddr = %pK, len = %zd, rc = %d\n", - __func__, vaddr, *len, rc); + pr_err("%s: habmm_export failed handle = %pK, len = %zd, rc = %d\n", + __func__, handle, *len, rc); goto err; } -- GitLab From 858867779a305f46194c27cf45009b08140de1e3 Mon Sep 17 00:00:00 2001 From: Saurav Kumar Date: Fri, 21 Feb 2020 18:29:26 +0530 Subject: [PATCH 1405/1645] dsp: codecs: Add synchronization between SSR and native encoder decoder Add change to use global lock to make synchronization between SSR and native encoder decoder. Change-Id: I6c1f48c32d4c8290de8bf3dfa86e022abe2b34bc Signed-off-by: Saurav Kumar --- dsp/codecs/audio_native.c | 5 ++++- dsp/codecs/audio_utils.c | 5 ++++- dsp/codecs/audio_utils_aio.c | 4 +++- dsp/codecs/q6audio_common.h | 4 ++-- dsp/codecs/q6audio_v2.c | 9 ++++++++- dsp/codecs/q6audio_v2_aio.c | 7 +++++-- 6 files changed, 26 insertions(+), 8 deletions(-) diff --git a/dsp/codecs/audio_native.c b/dsp/codecs/audio_native.c index 93370295d4bc..6e2491459bf0 100644 --- a/dsp/codecs/audio_native.c +++ b/dsp/codecs/audio_native.c @@ -1,12 +1,14 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2017, 2020, The Linux Foundation. All rights reserved. */ #include #include #include "audio_utils.h" +spinlock_t enc_dec_lock; + static int __init audio_native_init(void) { aac_in_init(); @@ -31,6 +33,7 @@ static int __init audio_native_init(void) g711alaw_in_init(); g711mlaw_in_init(); qcelp_in_init(); + spin_lock_init(&enc_dec_lock); return 0; } diff --git a/dsp/codecs/audio_utils.c b/dsp/codecs/audio_utils.c index 26e9b0b36044..ac934132ac3b 100644 --- a/dsp/codecs/audio_utils.c +++ b/dsp/codecs/audio_utils.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2010-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2020, The Linux Foundation. All rights reserved. */ #include @@ -943,8 +943,11 @@ int audio_in_release(struct inode *inode, struct file *file) audio_in_disable(audio); q6asm_audio_client_free(audio->ac); mutex_unlock(&audio->lock); + spin_lock(&enc_dec_lock); kfree(audio->enc_cfg); kfree(audio->codec_cfg); kfree(audio); + file->private_data = NULL; + spin_unlock(&enc_dec_lock); return 0; } diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c index 62b9455dbdd3..93095e3007fb 100644 --- a/dsp/codecs/audio_utils_aio.c +++ b/dsp/codecs/audio_utils_aio.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2020, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -631,9 +631,11 @@ int audio_aio_release(struct inode *inode, struct file *file) #ifdef CONFIG_DEBUG_FS debugfs_remove(audio->dentry); #endif + spin_lock(&enc_dec_lock); kfree(audio->codec_cfg); kfree(audio); file->private_data = NULL; + spin_unlock(&enc_dec_lock); mutex_unlock(&lock); return 0; } diff --git a/dsp/codecs/q6audio_common.h b/dsp/codecs/q6audio_common.h index c37813edd0de..67003feaee43 100644 --- a/dsp/codecs/q6audio_common.h +++ b/dsp/codecs/q6audio_common.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2017, 2020 The Linux Foundation. All rights reserved. */ @@ -9,7 +9,7 @@ #include #include - +extern spinlock_t enc_dec_lock; void q6_audio_cb(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv); diff --git a/dsp/codecs/q6audio_v2.c b/dsp/codecs/q6audio_v2.c index c98ef1c4bc0a..6a402f538b75 100644 --- a/dsp/codecs/q6audio_v2.c +++ b/dsp/codecs/q6audio_v2.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2013, 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2013, 2015-2017, 2020 The Linux Foundation. All rights reserved. */ #include @@ -21,6 +21,11 @@ void q6asm_in_cb(uint32_t opcode, uint32_t token, struct q6audio_in *audio = (struct q6audio_in *)priv; unsigned long flags; + spin_lock(&enc_dec_lock); + if (audio == NULL) { + pr_err("%s: failed to get q6audio value\n", __func__); + goto error; + } pr_debug("%s:session id %d: opcode[0x%x]\n", __func__, audio->ac->session, opcode); @@ -58,6 +63,8 @@ void q6asm_in_cb(uint32_t opcode, uint32_t token, break; } spin_unlock_irqrestore(&audio->dsp_lock, flags); +error: + spin_unlock(&enc_dec_lock); } void audio_in_get_dsp_frames(void *priv, diff --git a/dsp/codecs/q6audio_v2_aio.c b/dsp/codecs/q6audio_v2_aio.c index a6f7836d8134..ecd14dadfee7 100644 --- a/dsp/codecs/q6audio_v2_aio.c +++ b/dsp/codecs/q6audio_v2_aio.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -43,9 +43,10 @@ void audio_aio_cb(uint32_t opcode, uint32_t token, struct q6audio_aio *audio = (struct q6audio_aio *)priv; union msm_audio_event_payload e_payload; + spin_lock(&enc_dec_lock); if (audio == NULL) { pr_err("%s: failed to get q6audio value\n", __func__); - return; + goto error; } switch (opcode) { case ASM_DATA_EVENT_WRITE_DONE_V2: @@ -111,6 +112,8 @@ void audio_aio_cb(uint32_t opcode, uint32_t token, default: break; } +error: + spin_unlock(&enc_dec_lock); } int extract_meta_out_info(struct q6audio_aio *audio, -- GitLab From 5489dbde93640bbaab143d6d22560a485fe5ff32 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 21 Feb 2020 19:47:54 +0530 Subject: [PATCH 1406/1645] asoc: bolero: Update fs_clk gen for va macro Enable and disable FS_CLK gen at every mclk enable and disable call to handle fs_clk gen count. Change-Id: I87e1cf112a48029cf0d6e7227fcc5167e973fdad Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/va-macro.c | 38 +++++++++++++++++------------------ 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index d79c70bc533d..9fe50e440cd1 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -226,19 +226,19 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, mutex_lock(&va_priv->mclk_lock); if (mclk_enable) { + ret = bolero_clk_rsc_request_clock(va_priv->dev, + va_priv->default_clk_id, + va_priv->clk_id, + true); + if (ret < 0) { + dev_err(va_priv->dev, + "%s: va request clock en failed\n", + __func__); + goto exit; + } + bolero_clk_rsc_fs_gen_request(va_priv->dev, + true); if (va_priv->va_mclk_users == 0) { - ret = bolero_clk_rsc_request_clock(va_priv->dev, - va_priv->default_clk_id, - va_priv->clk_id, - true); - if (ret < 0) { - dev_err(va_priv->dev, - "%s: va request clock en failed\n", - __func__); - goto exit; - } - bolero_clk_rsc_fs_gen_request(va_priv->dev, - true); regcache_mark_dirty(regmap); regcache_sync_region(regmap, VA_START_OFFSET, @@ -253,14 +253,12 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv, goto exit; } va_priv->va_mclk_users--; - if (va_priv->va_mclk_users == 0) { - bolero_clk_rsc_fs_gen_request(va_priv->dev, - false); - bolero_clk_rsc_request_clock(va_priv->dev, - va_priv->default_clk_id, - va_priv->clk_id, - false); - } + bolero_clk_rsc_fs_gen_request(va_priv->dev, + false); + bolero_clk_rsc_request_clock(va_priv->dev, + va_priv->default_clk_id, + va_priv->clk_id, + false); } exit: mutex_unlock(&va_priv->mclk_lock); -- GitLab From 29a5874d4e6b3104514125761d813b3ec2077e61 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 21 Feb 2020 19:53:59 +0530 Subject: [PATCH 1407/1645] ASoC: wcd-mbhc: Fix playback pause during lineout insertion Playback pauses during aux cable insertion as removal of cable is reported followed by insertion. Report removal of current cable only when headset connected to other end of extension cable and not lineout. Change-Id: I08933f4a88493136a518ee72646aa10b1f06eb70 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd-mbhc-adc.c | 3 ++- asoc/codecs/wcd-mbhc-v2.c | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index 0635d5468056..f961230758aa 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #include #include @@ -1113,6 +1113,7 @@ static irqreturn_t wcd_mbhc_adc_hs_ins_irq(int irq, void *data) WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_ISRC_EN, 0); mbhc->is_extn_cable = true; mbhc->btn_press_intr = false; + mbhc->force_linein = false; wcd_mbhc_adc_detect_plug_type(mbhc); WCD_MBHC_RSC_UNLOCK(mbhc); pr_debug("%s: leave\n", __func__); diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index f0c0ce76d8eb..46a3850ae91e 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -634,11 +634,12 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, } mbhc->hph_type = WCD_MBHC_HPH_NONE; mbhc->zl = mbhc->zr = 0; - pr_debug("%s: Reporting removal (%x)\n", - __func__, mbhc->hph_status); - wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack, - 0, WCD_MBHC_JACK_MASK); - + if (!mbhc->force_linein) { + pr_debug("%s: Reporting removal (%x)\n", + __func__, mbhc->hph_status); + wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack, + 0, WCD_MBHC_JACK_MASK); + } if (mbhc->hph_status == SND_JACK_LINEOUT) { pr_debug("%s: Enable micbias\n", __func__); -- GitLab From 40d4c5b4373843552663d27595c8d5ca788a17f9 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Wed, 26 Feb 2020 21:32:40 -0500 Subject: [PATCH 1408/1645] ASoC: msm: Add QUIN TDM TX interface to echo reference * Add QUIN_TDM_TX_0 text to echo reference mux text array * Add QUIN_TDM_TX_0 intercon to AUDIO_REF_EC_UL1 MUX Suggested-by: Tahir Dawson Signed-off-by: Derek Chen Change-Id: Ic633e8709ecd1d90ee2bbf95202d28bad60118f1 --- asoc/msm-pcm-routing-v2.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 30579bc1d391..7207375a2615 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -5513,6 +5513,10 @@ static int get_ec_ref_port_id(int value, int *index) *index = 39; port_id = AFE_PORT_ID_SENARY_MI2S_TX; break; + case 40: + *index = 40; + port_id = AFE_PORT_ID_QUINARY_TDM_TX; + break; default: *index = 0; /* NONE */ pr_err("%s: Invalid value %d\n", __func__, value); @@ -5570,7 +5574,7 @@ static const char *const ec_ref_rx[] = { "None", "SLIM_RX", "I2S_RX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_2", "SLIM_7_RX", "RX_CDC_DMA_RX_0", "RX_CDC_DMA_RX_1", "RX_CDC_DMA_RX_2", "RX_CDC_DMA_RX_3", "TX_CDC_DMA_TX_0", "TERT_TDM_RX_2", "SEC_TDM_TX_0", - "DISPLAY_PORT1", "SEN_MI2S_RX", "SENARY_MI2S_TX", + "DISPLAY_PORT1", "SEN_MI2S_RX", "SENARY_MI2S_TX", "QUIN_TDM_TX_0", }; static const struct soc_enum msm_route_ec_ref_rx_enum[] = { @@ -27426,6 +27430,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUDIO_REF_EC_UL1 MUX", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"AUDIO_REF_EC_UL1 MUX", "TERT_TDM_RX_2", "TERT_TDM_RX_2"}, {"AUDIO_REF_EC_UL1 MUX", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"AUDIO_REF_EC_UL1 MUX", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, {"AUDIO_REF_EC_UL2 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"AUDIO_REF_EC_UL2 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, -- GitLab From 3f7a0730a7c7b25de64c8be880c72cb6bcf0bfe3 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 26 Feb 2020 00:35:33 +0530 Subject: [PATCH 1409/1645] asoc: bolero: Fix AMIC TX pop on bolero 2.1 For bolero 2.1, amic can connect on any SWR input. Update API to check amic usecase. Change-Id: Iced7df39b0dbaf83e77a72536e55223d3bda2289 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/tx-macro.c | 34 ++++++++++++++++++++++------------ asoc/codecs/bolero/va-macro.c | 34 ++++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 12b37ab84396..bccf0f8ddbc9 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -433,23 +433,31 @@ static int tx_macro_reg_wake_irq(struct snd_soc_component *component, return ret; } -static int is_amic_enabled(struct snd_soc_component *component, int decimator) +static bool is_amic_enabled(struct snd_soc_component *component, int decimator) { u16 adc_mux_reg = 0, adc_reg = 0; u16 adc_n = BOLERO_ADC_MAX; + bool ret = false; + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) + return ret; adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + TX_MACRO_ADC_MUX_CFG_OFFSET * decimator; if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) { + if (tx_priv->version == BOLERO_VERSION_2_1) + return true; adc_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + TX_MACRO_ADC_MUX_CFG_OFFSET * decimator; adc_n = snd_soc_component_read32(component, adc_reg) & TX_MACRO_SWR_MIC_MUX_SEL_MASK; - if (adc_n >= BOLERO_ADC_MAX) - adc_n = BOLERO_ADC_MAX; + if (adc_n < BOLERO_ADC_MAX) + return true; } - return adc_n; + return ret; } static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) @@ -460,7 +468,7 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) struct snd_soc_component *component = NULL; u16 dec_cfg_reg = 0, hpf_gate_reg = 0; u8 hpf_cut_off_freq = 0; - u16 adc_n = 0; + u16 adc_reg = 0, adc_n = 0; hpf_delayed_work = to_delayed_work(work); hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); @@ -476,8 +484,11 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) dev_dbg(component->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", __func__, hpf_work->decimator, hpf_cut_off_freq); - adc_n = is_amic_enabled(component, hpf_work->decimator); - if (adc_n < BOLERO_ADC_MAX) { + if (is_amic_enabled(component, hpf_work->decimator)) { + adc_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + + TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator; + adc_n = snd_soc_component_read32(component, adc_reg) & + TX_MACRO_SWR_MIC_MUX_SEL_MASK; /* analog mic clear TX hold */ bolero_clear_amic_tx_hold(component->dev, adc_n); snd_soc_component_update_bits(component, @@ -882,7 +893,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x20, 0x20); - if (!(is_amic_enabled(component, decimator) < BOLERO_ADC_MAX)) { + if (!is_amic_enabled(component, decimator)) { snd_soc_component_update_bits(component, hpf_gate_reg, 0x01, 0x00); /* @@ -902,7 +913,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, TX_HPF_CUT_OFF_FREQ_MASK, CF_MIN_3DB_150HZ << 5); - if (is_amic_enabled(component, decimator) < BOLERO_ADC_MAX) { + if (is_amic_enabled(component, decimator)) { hpf_delay = TX_MACRO_AMIC_HPF_DELAY_MS; unmute_delay = TX_MACRO_AMIC_UNMUTE_DELAY_MS; } @@ -918,8 +929,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, msecs_to_jiffies(hpf_delay)); snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x02); - if (!(is_amic_enabled(component, decimator) - < BOLERO_ADC_MAX)) + if (!is_amic_enabled(component, decimator)) snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x00); /* @@ -959,7 +969,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, component, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, hpf_cut_off_freq << 5); - if (is_amic_enabled(component, decimator) < BOLERO_ADC_MAX) + if (is_amic_enabled(component, decimator)) snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x02); diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 9fe50e440cd1..dff74bdfea5a 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -781,23 +781,31 @@ static int va_macro_swrm_clock(void *handle, bool enable) return ret; } -static int is_amic_enabled(struct snd_soc_component *component, int decimator) +static bool is_amic_enabled(struct snd_soc_component *component, int decimator) { u16 adc_mux_reg = 0, adc_reg = 0; u16 adc_n = BOLERO_ADC_MAX; + bool ret = false; + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) + return ret; adc_mux_reg = BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1 + VA_MACRO_ADC_MUX_CFG_OFFSET * decimator; if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) { + if (va_priv->version == BOLERO_VERSION_2_1) + return true; adc_reg = BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0 + VA_MACRO_ADC_MUX_CFG_OFFSET * decimator; adc_n = snd_soc_component_read32(component, adc_reg) & VA_MACRO_SWR_MIC_MUX_SEL_MASK; - if (adc_n >= BOLERO_ADC_MAX) - adc_n = BOLERO_ADC_MAX; + if (adc_n < BOLERO_ADC_MAX) + return true; } - return adc_n; + return ret; } static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) @@ -808,7 +816,7 @@ static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) struct snd_soc_component *component; u16 dec_cfg_reg, hpf_gate_reg; u8 hpf_cut_off_freq; - u16 adc_n = 0; + u16 adc_reg = 0, adc_n = 0; hpf_delayed_work = to_delayed_work(work); hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); @@ -824,8 +832,11 @@ static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) dev_dbg(va_priv->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n", __func__, hpf_work->decimator, hpf_cut_off_freq); - adc_n = is_amic_enabled(component, hpf_work->decimator); - if (adc_n < BOLERO_ADC_MAX) { + if (is_amic_enabled(component, hpf_work->decimator)) { + adc_reg = BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0 + + VA_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator; + adc_n = snd_soc_component_read32(component, adc_reg) & + VA_MACRO_SWR_MIC_MUX_SEL_MASK; /* analog mic clear TX hold */ bolero_clear_amic_tx_hold(component->dev, adc_n); snd_soc_component_update_bits(component, @@ -1125,7 +1136,7 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, /* Enable TX CLK */ snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x20, 0x20); - if (!(is_amic_enabled(component, decimator) < BOLERO_ADC_MAX)) { + if (!is_amic_enabled(component, decimator)) { snd_soc_component_update_bits(component, hpf_gate_reg, 0x01, 0x00); /* @@ -1144,7 +1155,7 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, TX_HPF_CUT_OFF_FREQ_MASK, CF_MIN_3DB_150HZ << 5); } - if (is_amic_enabled(component, decimator) < BOLERO_ADC_MAX) { + if (is_amic_enabled(component, decimator)) { hpf_delay = BOLERO_CDC_VA_TX_AMIC_HPF_DELAY_MS; unmute_delay = BOLERO_CDC_VA_TX_AMIC_UNMUTE_DELAY_MS; if (va_tx_unmute_delay < unmute_delay) @@ -1152,7 +1163,7 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, } snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x02); - if (!(is_amic_enabled(component, decimator) < BOLERO_ADC_MAX)) + if (!is_amic_enabled(component, decimator)) snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x00); /* @@ -1189,8 +1200,7 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK, hpf_cut_off_freq << 5); - if (is_amic_enabled(component, decimator) < - BOLERO_ADC_MAX) + if (is_amic_enabled(component, decimator)) snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x02); -- GitLab From cb923683a8e54eff17534ae0cdbc7d49cc5c61eb Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 26 Feb 2020 08:56:00 +0530 Subject: [PATCH 1410/1645] asoc: wsa881x-analog: Update boost preset based on 8810/15 Update boost level setting of value 5.5v and 6v for 8815 and 8810 variants. Change-Id: I6e71c58bddb4958f1eda4ab4d4630bcb6073dcdb Signed-off-by: Laxminath Kasam --- asoc/codecs/wsa881x-analog.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/wsa881x-analog.c b/asoc/codecs/wsa881x-analog.c index 038e338e53b6..fe8a5b9c9d30 100644 --- a/asoc/codecs/wsa881x-analog.c +++ b/asoc/codecs/wsa881x-analog.c @@ -398,9 +398,14 @@ static int wsa881x_boost_ctrl(struct snd_soc_component *component, bool enable) snd_soc_component_update_bits(component, WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, 0x03, 0x00); - snd_soc_component_update_bits(component, - WSA881X_BOOST_PRESET_OUT1, - 0xF0, 0x70); + if (snd_soc_component_read32(component, WSA881X_OTP_REG_0)) + snd_soc_component_update_bits(component, + WSA881X_BOOST_PRESET_OUT1, + 0xF0, 0x70); + else + snd_soc_component_update_bits(component, + WSA881X_BOOST_PRESET_OUT1, + 0xF0, 0xB0); snd_soc_component_update_bits(component, WSA881X_ANA_CTL, 0x03, 0x01); snd_soc_component_update_bits(component, -- GitLab From 40788dc7e3422355b8d027635262bdbb9f9fb4d1 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 25 Feb 2020 14:51:21 +0800 Subject: [PATCH 1411/1645] asoc: lsm: move wakeup source down before return Wakeup source is not removed before freeing prtd memory which causes kernel panic during SSR. Move wakeup source after lsm_client initialization is done. Change-Id: I21cdafce84215d3fee3dc972af8e5b469dd5f565 Signed-off-by: Meng Wang --- asoc/msm-lsm-client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 4a58bad4a5dd..b6624f00296e 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -2477,7 +2477,6 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) init_waitqueue_head(&prtd->event_wait); init_waitqueue_head(&prtd->period_wait); prtd->substream = substream; - wakeup_source_init(&prtd->ws, "lsm-client"); runtime->private_data = prtd; runtime->hw = msm_pcm_hardware_capture; @@ -2530,6 +2529,7 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) prtd->lsm_client->fe_id = rtd->dai_link->id; prtd->lsm_client->unprocessed_data = 0; + wakeup_source_init(&prtd->ws, "lsm-client"); return 0; } -- GitLab From c483361879582283b9b3bca4ddd7715ffcea6a3e Mon Sep 17 00:00:00 2001 From: Kunlei Zhang Date: Thu, 20 Feb 2020 18:50:23 +0800 Subject: [PATCH 1412/1645] config: add wcd937x support for lagoon Add wcd937x DLKM files support for lagoon. Change-Id: I9fa80df4fd25ee476e59bb1bf6a7b25c0cf56a57 --- config/litoauto.conf | 2 ++ config/litoautoconf.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/config/litoauto.conf b/config/litoauto.conf index 0bbe4f742e9a..12bb1df71705 100644 --- a/config/litoauto.conf +++ b/config/litoauto.conf @@ -32,5 +32,7 @@ CONFIG_TX_MACRO=m CONFIG_SND_SOC_WCD_IRQ=m CONFIG_SND_SOC_WCD938X=m CONFIG_SND_SOC_WCD938X_SLAVE=m +CONFIG_SND_SOC_WCD937X=m +CONFIG_SND_SOC_WCD937X_SLAVE=m CONFIG_SND_SOC_LITO=m CONFIG_SND_EVENT=m diff --git a/config/litoautoconf.h b/config/litoautoconf.h index 2d19f2dab9ab..0cfdab2d3529 100644 --- a/config/litoautoconf.h +++ b/config/litoautoconf.h @@ -36,5 +36,7 @@ #define CONFIG_SND_SOC_WCD_IRQ 1 #define CONFIG_SND_SOC_WCD938X 1 #define CONFIG_SND_SOC_WCD938X_SLAVE 1 +#define CONFIG_SND_SOC_WCD937X 1 +#define CONFIG_SND_SOC_WCD937X_SLAVE 1 #define CONFIG_SND_SOC_LITO 1 #define CONFIG_SND_EVENT 1 -- GitLab From d35af03d3e96f5c4151951328040efacdd966f72 Mon Sep 17 00:00:00 2001 From: Jia Jin Date: Mon, 20 Jan 2020 17:10:03 +0800 Subject: [PATCH 1413/1645] asoc: Add asm loopback MultiMedia24 and MultiMedia25 Add asm loopback channel to support dual hfp Change-Id: I43265fd0da04a1481784e5ed3ed7b3a5bad9ac2c Signed-off-by: Jia Jin Signed-off-by: Han Lu --- asoc/msm-dai-fe.c | 66 ++++++ asoc/msm-pcm-routing-v2.c | 484 ++++++++++++++++++++++++++++++++++++++ asoc/msm-pcm-routing-v2.h | 2 + asoc/sa8155.c | 88 ++++--- 4 files changed, 613 insertions(+), 27 deletions(-) diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index 2025be91a119..29e15dda17cb 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -2757,6 +2757,72 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "MultiMedia23", .probe = fe_dai_probe, }, + { + .playback = { + .stream_name = "MultiMedia24 Playback", + .aif_name = "MM_DL24", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "MultiMedia24 Capture", + .aif_name = "MM_UL24", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .name = "MultiMedia24", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "MultiMedia25 Playback", + .aif_name = "MM_DL25", + .rates = (SNDRV_PCM_RATE_8000_384000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .capture = { + .stream_name = "MultiMedia25 Capture", + .aif_name = "MM_UL25", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S32_LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .name = "MultiMedia25", + .probe = fe_dai_probe, + }, { .playback = { .stream_name = "MultiMedia26 Playback", diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 7207375a2615..ae039ab962fa 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -771,6 +771,12 @@ static struct msm_pcm_routing_fdai_data {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA23 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, + /* MULTIMEDIA24 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, + /* MULTIMEDIA25 */ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM}, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL}, LEGACY_PCM} }, /* MULTIMEDIA26 */ @@ -9653,6 +9659,14 @@ static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = { @@ -9732,6 +9746,14 @@ static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = { @@ -9811,6 +9833,14 @@ static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = { @@ -9890,6 +9920,14 @@ static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_tdm_tx_0_mixer_controls[] = { @@ -9961,6 +9999,14 @@ static const struct snd_kcontrol_new pri_tdm_tx_0_mixer_controls[] = { MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = { @@ -10040,6 +10086,14 @@ static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = { @@ -10119,6 +10173,14 @@ static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = { @@ -10198,6 +10260,14 @@ static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = { @@ -10277,6 +10347,14 @@ static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_tdm_tx_0_mixer_controls[] = { @@ -10348,6 +10426,14 @@ static const struct snd_kcontrol_new sec_tdm_tx_0_mixer_controls[] = { MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_0_mixer_controls[] = { @@ -10427,6 +10513,14 @@ static const struct snd_kcontrol_new tert_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_tx_0_mixer_controls[] = { @@ -10498,6 +10592,14 @@ static const struct snd_kcontrol_new tert_tdm_tx_0_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_1_mixer_controls[] = { @@ -10577,6 +10679,14 @@ static const struct snd_kcontrol_new tert_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = { @@ -10656,6 +10766,14 @@ static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = { @@ -10735,6 +10853,14 @@ static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = { @@ -10814,6 +10940,14 @@ static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = { MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = { @@ -10897,6 +11031,14 @@ static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_tx_0_mixer_controls[] = { @@ -10968,6 +11110,14 @@ static const struct snd_kcontrol_new quat_tdm_tx_0_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_1_mixer_controls[] = { @@ -11051,6 +11201,14 @@ static const struct snd_kcontrol_new quat_tdm_rx_1_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = { @@ -11134,6 +11292,14 @@ static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = { @@ -11217,6 +11383,14 @@ static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_0_mixer_controls[] = { @@ -11300,6 +11474,14 @@ static const struct snd_kcontrol_new quin_tdm_rx_0_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_tx_0_mixer_controls[] = { @@ -11371,6 +11553,14 @@ static const struct snd_kcontrol_new quin_tdm_tx_0_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_tx_1_mixer_controls[] = { @@ -11588,6 +11778,14 @@ static const struct snd_kcontrol_new quin_tdm_tx_2_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = { @@ -11671,6 +11869,14 @@ static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quin_tdm_tx_3_mixer_controls[] = { @@ -11821,6 +12027,14 @@ static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = { MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sen_tdm_rx_0_mixer_controls[] = { @@ -15266,6 +15480,172 @@ static const struct snd_kcontrol_new mmul23_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new mmul24_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul25_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new mmul27_mixer_controls[] = { SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_SLIMBUS_0_TX, @@ -23273,6 +23653,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_IN("MM_DL21", "MultiMedia21 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("MM_DL22", "MultiMedia22 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("MM_DL23", "MultiMedia23 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL24", "MultiMedia24 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL25", "MultiMedia25 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("MM_DL26", "MultiMedia26 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0), @@ -23292,6 +23674,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("MM_UL21", "MultiMedia21 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL22", "MultiMedia22 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL23", "MultiMedia23 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL24", "MultiMedia24 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL25", "MultiMedia25 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL27", "MultiMedia27 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL28", "MultiMedia28 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL29", "MultiMedia29 Capture", 0, 0, 0, 0), @@ -24397,6 +24781,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { mmul22_mixer_controls, ARRAY_SIZE(mmul22_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia23 Mixer", SND_SOC_NOPM, 0, 0, mmul23_mixer_controls, ARRAY_SIZE(mmul23_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia24 Mixer", SND_SOC_NOPM, 0, 0, + mmul24_mixer_controls, ARRAY_SIZE(mmul24_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia25 Mixer", SND_SOC_NOPM, 0, 0, + mmul25_mixer_controls, ARRAY_SIZE(mmul25_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia27 Mixer", SND_SOC_NOPM, 0, 0, mmul27_mixer_controls, ARRAY_SIZE(mmul27_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia28 Mixer", SND_SOC_NOPM, 0, 0, @@ -25633,6 +26021,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Audio Mixer"}, {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25654,6 +26044,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Audio Mixer"}, {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25675,6 +26067,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Audio Mixer"}, {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25696,6 +26090,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Audio Mixer"}, {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25715,6 +26111,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"PRI_TDM_TX_0", NULL, "PRI_TDM_TX_0 Audio Mixer"}, {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25736,6 +26134,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Audio Mixer"}, {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25757,6 +26157,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Audio Mixer"}, {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25778,6 +26180,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Audio Mixer"}, {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25799,6 +26203,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Audio Mixer"}, {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25818,6 +26224,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"SEC_TDM_TX_0", NULL, "SEC_TDM_TX_0 Audio Mixer"}, {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25839,6 +26247,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Audio Mixer"}, {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25858,6 +26268,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"TERT_TDM_TX_0", NULL, "TERT_TDM_TX_0 Audio Mixer"}, {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25879,6 +26291,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Audio Mixer"}, {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25900,6 +26314,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Audio Mixer"}, {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25921,6 +26337,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Audio Mixer"}, {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25942,6 +26360,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"TERT_TDM_RX_4", NULL, "TERT_TDM_RX_4 Audio Mixer"}, {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25964,6 +26384,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Audio Mixer"}, {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -25983,6 +26405,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"QUAT_TDM_TX_0", NULL, "QUAT_TDM_TX_0 Audio Mixer"}, {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -26005,6 +26429,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Audio Mixer"}, {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -26027,6 +26453,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Audio Mixer"}, {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -26049,6 +26477,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Audio Mixer"}, {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -26071,6 +26501,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0 Audio Mixer"}, {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -26090,6 +26522,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"QUIN_TDM_TX_0", NULL, "QUIN_TDM_TX_0 Audio Mixer"}, {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -26112,6 +26546,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1 Audio Mixer"}, {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -26134,6 +26570,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2 Audio Mixer"}, {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -26156,6 +26594,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Audio Mixer"}, {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, @@ -26802,6 +27242,48 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia23 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, {"MultiMedia23 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia24 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia24 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia24 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia24 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia24 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia24 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia24 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia24 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia24 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia24 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia24 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia24 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia24 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia24 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia24 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia24 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia24 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia24 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia24 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia24 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + + {"MultiMedia25 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia25 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia25 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia25 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia25 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia25 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia25 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia25 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia25 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia25 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia25 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia25 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia25 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia25 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia25 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia25 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia25 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia25 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia25 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia25 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia27 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia27 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MultiMedia27 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, @@ -27047,6 +27529,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL21", NULL, "MultiMedia21 Mixer"}, {"MM_UL22", NULL, "MultiMedia22 Mixer"}, {"MM_UL23", NULL, "MultiMedia23 Mixer"}, + {"MM_UL24", NULL, "MultiMedia24 Mixer"}, + {"MM_UL25", NULL, "MultiMedia25 Mixer"}, {"MM_UL27", NULL, "MultiMedia27 Mixer"}, {"MM_UL28", NULL, "MultiMedia28 Mixer"}, {"MM_UL29", NULL, "MultiMedia29 Mixer"}, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 9c74c32ffbd5..7f6d036b30ab 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -261,6 +261,8 @@ enum { MSM_FRONTEND_DAI_MULTIMEDIA21, MSM_FRONTEND_DAI_MULTIMEDIA22, MSM_FRONTEND_DAI_MULTIMEDIA23, + MSM_FRONTEND_DAI_MULTIMEDIA24, + MSM_FRONTEND_DAI_MULTIMEDIA25, MSM_FRONTEND_DAI_MULTIMEDIA26, MSM_FRONTEND_DAI_MULTIMEDIA27, MSM_FRONTEND_DAI_MULTIMEDIA28, diff --git a/asoc/sa8155.c b/asoc/sa8155.c index 2e5444707cf7..473006056dde 100644 --- a/asoc/sa8155.c +++ b/asoc/sa8155.c @@ -174,14 +174,14 @@ struct tdm_conf { /* TDM default config */ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { { /* PRI TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_2 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_3 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ }, { /* SEC TDM */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_0 */ @@ -228,14 +228,14 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { /* TDM default config */ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { { /* PRI TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_2 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_3 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ }, { /* SEC TDM */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* TX_0 */ @@ -343,7 +343,7 @@ struct tdm_slot_cfg { static struct tdm_slot_cfg tdm_slot[TDM_INTERFACE_MAX] = { /* PRI TDM */ - {32, 8}, + {16, 16}, /* SEC TDM */ {32, 8}, /* TERT TDM */ @@ -377,11 +377,11 @@ static struct tdm_slot_cfg tdm_slot_custom[TDM_INTERFACE_MAX] = { static unsigned int tdm_rx_slot_offset [TDM_INTERFACE_MAX][TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { {/* PRI TDM */ - {0, 4, 0xFFFF}, - {8, 12, 0xFFFF}, - {16, 20, 0xFFFF}, - {24, 28, 0xFFFF}, - {0xFFFF}, /* not used */ + {0, 0xFFFF}, + {2, 0xFFFF}, + {4, 6, 0xFFFF}, + {8, 10, 0xFFFF}, + {12, 14, 0xFFFF}, {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -432,11 +432,11 @@ static unsigned int tdm_rx_slot_offset static unsigned int tdm_tx_slot_offset [TDM_INTERFACE_MAX][TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { {/* PRI TDM */ - {0, 4, 0xFFFF}, - {8, 12, 0xFFFF}, - {16, 20, 0xFFFF}, - {24, 28, 0xFFFF}, - {0xFFFF}, /* not used */ + {0, 0xFFFF}, + {2, 0xFFFF}, + {4, 6, 0xFFFF}, + {8, 10, 0xFFFF}, + {12, 14, 0xFFFF}, {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -5896,6 +5896,40 @@ static struct snd_soc_dai_link msm_auto_fe_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA23 }, + { + .name = MSM_DAILINK_NAME(Media24), + .stream_name = "MultiMedia24", + .cpu_dai_name = "MultiMedia24", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA24 + }, + { + .name = MSM_DAILINK_NAME(Media25), + .stream_name = "MultiMedia25", + .cpu_dai_name = "MultiMedia25", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA25 + }, }; static struct snd_soc_dai_link msm_custom_fe_dai_links[] = { -- GitLab From e87c0b1cfb352fa2ebac0961af8762696eb3de27 Mon Sep 17 00:00:00 2001 From: Manisha Agarwal Date: Thu, 30 Jan 2020 16:33:37 +0530 Subject: [PATCH 1414/1645] dsp: Bit rate mode support for aac codec Add variable bit rate mode support for aac codec. Change-Id: Iedd9fe0df2d3a12e3d4e6c2916305399da10873f Signed-off-by: Manisha Agarwal --- dsp/q6afe.c | 27 ++++++++++++++++++++++++++- include/dsp/apr_audio-v2.h | 3 ++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 16d156783c53..0274e1c6005d 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -4170,6 +4170,7 @@ static int q6afe_send_enc_config(u16 port_id, struct asm_aptx_ad_speech_mode_cfg_t speech_codec_init_param; struct param_hdr_v3 param_hdr; int ret; + uint32_t frame_size_ctl_value_v2; pr_debug("%s:update DSP for enc format = %d\n", __func__, format); @@ -4257,8 +4258,9 @@ static int q6afe_send_enc_config(u16 port_id, frame_ctl_param.ctl_type = enc_blk_param. enc_blk_config.aac_config.frame_ctl.ctl_type; frame_ctl_param.ctl_value = frame_size_ctl_value; + pr_debug("%s: send AFE_PARAM_ID_AAC_FRM_SIZE_CONTROL\n", - __func__); + __func__); ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, @@ -4269,6 +4271,29 @@ static int q6afe_send_enc_config(u16 port_id, goto exit; } } + frame_size_ctl_value_v2 = enc_blk_param.enc_blk_config. + aac_config.frame_ctl_v2.ctl_value; + if (frame_size_ctl_value_v2 > 0) { + param_hdr.param_id = + AFE_PARAM_ID_AAC_FRM_SIZE_CONTROL; + param_hdr.param_size = sizeof(frame_ctl_param); + frame_ctl_param.ctl_type = enc_blk_param. + enc_blk_config.aac_config.frame_ctl_v2.ctl_type; + frame_ctl_param.ctl_value = enc_blk_param. + enc_blk_config.aac_config.frame_ctl_v2.ctl_value; + + pr_debug("%s: send AFE_PARAM_ID_AAC_FRM_SIZE_CONTROL V2\n", + __func__); + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &frame_ctl_param); + if (ret) { + pr_err("%s: AAC_FRM_SIZE_CONTROL with VBR support failed %d\n", + __func__, ret); + goto exit; + } + } } if (format == ASM_MEDIA_FMT_APTX) { diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 111f191635f0..534e0c7f1412 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ @@ -4339,6 +4339,7 @@ struct asm_aac_frame_size_control_t { struct asm_aac_enc_cfg_t { struct asm_aac_enc_cfg_v2_t aac_cfg; struct asm_aac_frame_size_control_t frame_ctl; + struct asm_aac_frame_size_control_t frame_ctl_v2; } __packed; /* FMT ID for apt-X Classic */ -- GitLab From 21ba077504fa20706cb667b6e9dd3e98d4190b97 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 28 Feb 2020 20:36:46 +0530 Subject: [PATCH 1415/1645] soc: swr-mstr: Fix headset not detetcted issue on devnum 0 detached Headset is not detected if devnum 0 gets detached at bootup. This is because on detach being called hw will mask interrupt at slave side but will not unmask it afterwards. Also device 0 is used only for discovery purpose and interrupt shouldnt be masked if it detaches. Change-Id: I78d47243ef67ea5ee1fe3badaec94e596bc8faf3 Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 5f6329d1e81e..3150e23dcf08 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1636,9 +1636,12 @@ static void swrm_enable_slave_irq(struct swr_mstr_ctrl *swrm) } dev_dbg(swrm->dev, "%s: slave status: 0x%x\n", __func__, status); for (i = 0; i < (swrm->master.num_dev + 1); i++) { - if (status & SWRM_MCP_SLV_STATUS_MASK) + if (status & SWRM_MCP_SLV_STATUS_MASK) { + swrm_cmd_fifo_wr_cmd(swrm, 0xFF, i, 0x0, + SWRS_SCP_INT_STATUS_CLEAR_1); swrm_cmd_fifo_wr_cmd(swrm, 0x4, i, 0x0, - SWRS_SCP_INT_STATUS_MASK_1); + SWRS_SCP_INT_STATUS_MASK_1); + } status >>= 2; } } @@ -1943,6 +1946,17 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) dev_dbg(swrm->dev, "%s: device %d got detached\n", __func__, devnum); + if (devnum == 0) { + /* + * enable host irq if device 0 detached + * as hw will mask host_irq at slave + * but will not unmask it afterwards. + */ + swrm_cmd_fifo_wr_cmd(swrm, 0xFF, devnum, 0x0, + SWRS_SCP_INT_STATUS_CLEAR_1); + swrm_cmd_fifo_wr_cmd(swrm, 0x4, devnum, 0x0, + SWRS_SCP_INT_STATUS_MASK_1); + } break; case SWR_ATTACHED_OK: dev_dbg(swrm->dev, -- GitLab From 8a89f8dd15c3fad8234bb005a0d96b36e3be60a8 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 3 Mar 2020 20:02:19 +0530 Subject: [PATCH 1416/1645] va-macro: Add autosuspend after pm_runtime_get_sync If va_macro_tx_va_mclk_enable returns error, va macro autosuspend will not be called. Add autosuspend before return. Change-Id: Iea3728fab2d240514ca4a7e02ef535edce977ee8 Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/va-macro.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index dff74bdfea5a..85d4ae399703 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -727,14 +727,20 @@ static int va_macro_swrm_clock(void *handle, bool enable) if (va_priv->va_swr_clk_cnt && !va_priv->tx_swr_clk_cnt) { ret = va_macro_tx_va_mclk_enable(va_priv, regmap, VA_MCLK, enable); - if (ret) + if (ret) { + pm_runtime_mark_last_busy(va_priv->dev); + pm_runtime_put_autosuspend(va_priv->dev); goto done; + } va_priv->va_clk_status++; } else { ret = va_macro_tx_va_mclk_enable(va_priv, regmap, TX_MCLK, enable); - if (ret) + if (ret) { + pm_runtime_mark_last_busy(va_priv->dev); + pm_runtime_put_autosuspend(va_priv->dev); goto done; + } va_priv->tx_clk_status++; } pm_runtime_mark_last_busy(va_priv->dev); -- GitLab From b258e09d5d1da701279112320b0fbfed3aef7a7e Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 20 Jan 2020 20:38:05 +0530 Subject: [PATCH 1417/1645] asoc: codecs: Update muxsel registers only when clock counts are not stale During SSR/PDR use cases, core clock count in different macros becomes stale and muxsel registers are accessed leading to NOC errors. Update muxsel registers only after clock counts are reset after SSR/PDR recovery. Change-Id: I656f8e7ddc8a92a325c2ba644f1a945cbafb08a0 Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/bolero-cdc.c | 4 ++++ asoc/codecs/bolero/bolero-cdc.h | 3 ++- asoc/codecs/bolero/bolero-clk-rsc.c | 30 +++++++++++++++++++---------- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 6d1887e0e0a8..49fd1fcb9258 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -828,6 +828,10 @@ static int bolero_ssr_enable(struct device *dev, void *data) priv->component, BOLERO_MACRO_EVT_CLK_RESET, 0x0); } + + if (priv->rsc_clk_cb) + priv->rsc_clk_cb(priv->clk_dev, BOLERO_MACRO_EVT_SSR_GFMUX_UP); + trace_printk("%s: clk count reset\n", __func__); regcache_cache_only(priv->regmap, false); mutex_lock(&priv->clk_lock); diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 3144d88b6c5a..b37eeae6e15c 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -52,7 +52,8 @@ enum { BOLERO_MACRO_EVT_CLK_RESET, BOLERO_MACRO_EVT_REG_WAKE_IRQ, BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST, - BOLERO_MACRO_EVT_BCS_CLK_OFF + BOLERO_MACRO_EVT_BCS_CLK_OFF, + BOLERO_MACRO_EVT_SSR_GFMUX_UP, }; enum { diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c index daed7e656684..9cc9b1ca86b9 100644 --- a/asoc/codecs/bolero/bolero-clk-rsc.c +++ b/asoc/codecs/bolero/bolero-clk-rsc.c @@ -38,6 +38,7 @@ struct bolero_clk_rsc { int reg_seq_en_cnt; int va_tx_clk_cnt; bool dev_up; + bool dev_up_gfmux; u32 num_fs_reg; u32 *fs_gen_seq; int default_clk_id[MAX_CLK]; @@ -65,10 +66,14 @@ static int bolero_clk_rsc_cb(struct device *dev, u16 event) } mutex_lock(&priv->rsc_clk_lock); - if (event == BOLERO_MACRO_EVT_SSR_UP) + if (event == BOLERO_MACRO_EVT_SSR_UP) { priv->dev_up = true; - else if (event == BOLERO_MACRO_EVT_SSR_DOWN) + } else if (event == BOLERO_MACRO_EVT_SSR_DOWN) { priv->dev_up = false; + priv->dev_up_gfmux = false; + } else if (event == BOLERO_MACRO_EVT_SSR_GFMUX_UP) { + priv->dev_up_gfmux = true; + } mutex_unlock(&priv->rsc_clk_lock); return 0; @@ -282,10 +287,12 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv, * care in DSP itself */ if (clk_id != VA_CORE_CLK) { - iowrite32(0x1, clk_muxsel); - muxsel = ioread32(clk_muxsel); - trace_printk("%s: muxsel value after enable: %d\n", - __func__, muxsel); + if (priv->dev_up_gfmux) { + iowrite32(0x1, clk_muxsel); + muxsel = ioread32(clk_muxsel); + trace_printk("%s: muxsel value after enable: %d\n", + __func__, muxsel); + } bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, false); @@ -313,10 +320,12 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv, * This configuration would be taken * care in DSP itself. */ - iowrite32(0x0, clk_muxsel); - muxsel = ioread32(clk_muxsel); - trace_printk("%s: muxsel value after disable: %d\n", - __func__, muxsel); + if (priv->dev_up_gfmux) { + iowrite32(0x0, clk_muxsel); + muxsel = ioread32(clk_muxsel); + trace_printk("%s: muxsel value after disable: %d\n", + __func__, muxsel); + } } } if (priv->clk[clk_id + NPL_CLK_OFFSET]) @@ -706,6 +715,7 @@ static int bolero_clk_rsc_probe(struct platform_device *pdev) } priv->dev = &pdev->dev; priv->dev_up = true; + priv->dev_up_gfmux = true; mutex_init(&priv->rsc_clk_lock); mutex_init(&priv->fs_gen_lock); dev_set_drvdata(&pdev->dev, priv); -- GitLab From eb04461c1d986b36cc13753a6ef74d7c9008f9cf Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Sun, 22 Dec 2019 17:14:15 +0530 Subject: [PATCH 1418/1645] soc: Vote or unvote core and audio hw based on count In order to synchronize the core and audio hw votes in SSR use cases, vote or unvote for these based on clock count. Change-Id: I0047e2cc689cc96b34992e5f6f59dae84d1d4e4b Signed-off-by: Aditya Bavanari --- soc/swr-mstr-ctrl.c | 127 ++++++++++++++++++++++++++++---------------- soc/swr-mstr-ctrl.h | 1 + 2 files changed, 81 insertions(+), 47 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 5f6329d1e81e..21bf8013d4bf 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -364,33 +364,77 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm, { int ret = 0; + mutex_lock(&swrm->devlock); if (core_type == LPASS_HW_CORE) { if (swrm->lpass_core_hw_vote) { if (enable) { - ret = - clk_prepare_enable(swrm->lpass_core_hw_vote); - if (ret < 0) - dev_err(swrm->dev, - "%s:lpass core hw enable failed\n", - __func__); - } else - clk_disable_unprepare(swrm->lpass_core_hw_vote); + if (!swrm->dev_up) { + dev_dbg(swrm->dev, "%s: device is down or SSR state\n", + __func__); + trace_printk("%s: device is down or SSR state\n", + __func__); + mutex_unlock(&swrm->devlock); + return -ENODEV; + } + if (++swrm->hw_core_clk_en == 1) { + ret = + clk_prepare_enable( + swrm->lpass_core_hw_vote); + if (ret < 0) { + dev_err(swrm->dev, + "%s:lpass core hw enable failed\n", + __func__); + --swrm->hw_core_clk_en; + } + } + } else { + --swrm->hw_core_clk_en; + if (swrm->hw_core_clk_en < 0) + swrm->hw_core_clk_en = 0; + else if (swrm->hw_core_clk_en == 0) + clk_disable_unprepare( + swrm->lpass_core_hw_vote); + } } } if (core_type == LPASS_AUDIO_CORE) { if (swrm->lpass_core_audio) { if (enable) { - ret = - clk_prepare_enable(swrm->lpass_core_audio); - if (ret < 0) - dev_err(swrm->dev, - "%s:lpass audio hw enable failed\n", - __func__); - } else - clk_disable_unprepare(swrm->lpass_core_audio); + if (!swrm->dev_up) { + dev_dbg(swrm->dev, "%s: device is down or SSR state\n", + __func__); + trace_printk("%s: device is down or SSR state\n", + __func__); + mutex_unlock(&swrm->devlock); + return -ENODEV; + } + if (++swrm->aud_core_clk_en == 1) { + ret = + clk_prepare_enable( + swrm->lpass_core_audio); + if (ret < 0) { + dev_err(swrm->dev, + "%s:lpass audio hw enable failed\n", + __func__); + --swrm->aud_core_clk_en; + } + } + } else { + --swrm->aud_core_clk_en; + if (swrm->aud_core_clk_en < 0) + swrm->aud_core_clk_en = 0; + else if (swrm->aud_core_clk_en == 0) + clk_disable_unprepare( + swrm->lpass_core_audio); + } } } + mutex_unlock(&swrm->devlock); + dev_dbg(swrm->dev, "%s: hw_clk_en: %d audio_core_clk_en: %d\n", + __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); + trace_printk("%s: hw_clk_en: %d audio_core_clk_en: %d\n", + __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); return ret; } @@ -1861,6 +1905,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) return IRQ_NONE; } + mutex_lock(&swrm->ssr_lock); mutex_lock(&swrm->reslock); if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) { ret = IRQ_NONE; @@ -2063,6 +2108,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); exit: mutex_unlock(&swrm->reslock); + mutex_unlock(&swrm->ssr_lock); swrm_unlock_sleep(swrm); trace_printk("%s exit\n", __func__); return ret; @@ -2239,22 +2285,15 @@ static void swrm_device_wakeup_vote(struct swr_master *mstr) dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__); return; } - if (++swrm->hw_core_clk_en == 1) - if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) { - dev_err(swrm->dev, "%s:lpass core hw enable failed\n", - __func__); - --swrm->hw_core_clk_en; - } - if ( ++swrm->aud_core_clk_en == 1) - if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { - dev_err(swrm->dev, "%s:lpass audio hw enable failed\n", - __func__); - --swrm->aud_core_clk_en; - } - dev_dbg(swrm->dev, "%s: hw_clk_en: %d audio_core_clk_en: %d\n", - __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); - trace_printk("%s: hw_clk_en: %d audio_core_clk_en: %d\n", - __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); + mutex_lock(&swrm->reslock); + if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) + dev_err(swrm->dev, "%s:lpass core hw enable failed\n", + __func__); + if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) + dev_err(swrm->dev, "%s:lpass audio hw enable failed\n", + __func__); + mutex_unlock(&swrm->reslock); + pm_runtime_get_sync(swrm->dev); } @@ -2269,22 +2308,11 @@ static void swrm_device_wakeup_unvote(struct swr_master *mstr) } pm_runtime_mark_last_busy(swrm->dev); pm_runtime_put_autosuspend(swrm->dev); - dev_dbg(swrm->dev, "%s: hw_clk_en: %d audio_core_clk_en: %d\n", - __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); - - trace_printk("%s: hw_clk_en: %d audio_core_clk_en: %d\n", - __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); - --swrm->aud_core_clk_en; - if (swrm->aud_core_clk_en < 0) - swrm->aud_core_clk_en = 0; - else if (swrm->aud_core_clk_en == 0) - swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); - --swrm->hw_core_clk_en; - if (swrm->hw_core_clk_en < 0) - swrm->hw_core_clk_en = 0; - else if (swrm->hw_core_clk_en == 0) - swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); + mutex_lock(&swrm->reslock); + swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); + swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); + mutex_unlock(&swrm->reslock); swrm_unlock_sleep(swrm); } @@ -2613,6 +2641,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_init(&swrm->clklock); mutex_init(&swrm->devlock); mutex_init(&swrm->pm_lock); + mutex_init(&swrm->ssr_lock); swrm->wlock_holders = 0; swrm->pm_state = SWRM_PM_SLEEPABLE; init_waitqueue_head(&swrm->pm_wq); @@ -2761,6 +2790,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_destroy(&swrm->iolock); mutex_destroy(&swrm->clklock); mutex_destroy(&swrm->pm_lock); + mutex_destroy(&swrm->ssr_lock); pm_qos_remove_request(&swrm->pm_qos_req); err_pdata_fail: @@ -2794,6 +2824,7 @@ static int swrm_remove(struct platform_device *pdev) mutex_destroy(&swrm->clklock); mutex_destroy(&swrm->force_down_lock); mutex_destroy(&swrm->pm_lock); + mutex_destroy(&swrm->ssr_lock); pm_qos_remove_request(&swrm->pm_qos_req); devm_kfree(&pdev->dev, swrm); return 0; @@ -3280,6 +3311,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) break; case SWR_DEVICE_SSR_DOWN: trace_printk("%s: swr device down called\n", __func__); + mutex_lock(&swrm->ssr_lock); mutex_lock(&swrm->mlock); if (swrm->state == SWR_MSTR_DOWN) dev_dbg(swrm->dev, "%s:SWR master is already Down:%d\n", @@ -3293,6 +3325,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) swrm->state = SWR_MSTR_SSR; mutex_unlock(&swrm->reslock); mutex_unlock(&swrm->mlock); + mutex_unlock(&swrm->ssr_lock); break; case SWR_DEVICE_SSR_UP: /* wait for clk voting to be zero */ diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index ce0b64d57766..0fac80e6f0c3 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -126,6 +126,7 @@ struct swr_mstr_ctrl { struct mutex reslock; struct mutex pm_lock; struct mutex irq_lock; + struct mutex ssr_lock; u32 swrm_base_reg; char __iomem *swrm_dig_base; char __iomem *swrm_hctl_reg; -- GitLab From 745cbbba97bfdac129407f8bb9a4b571ba68b50a Mon Sep 17 00:00:00 2001 From: Kunlei Zhang Date: Mon, 10 Feb 2020 19:43:30 +0800 Subject: [PATCH 1419/1645] asoc: wcd937x: enable wcd937x codec driver compilation. Enable wcd937x codec driver compilation support. Change-Id: I001f7ca278549a4a77c5b02e1c6a86d1dbf51ff7 Signed-off-by: Kunlei Zhang --- Android.mk | 2 ++ asoc/codecs/wcd937x/Android.mk | 2 +- asoc/codecs/wcd937x/Kbuild | 5 +++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Android.mk b/Android.mk index cac738852a87..6c43c4e9b3f9 100644 --- a/Android.mk +++ b/Android.mk @@ -52,4 +52,6 @@ $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codec include $(MY_LOCAL_PATH)/asoc/codecs/bolero/Android.mk $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd938x/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wcd938x/Android.mk +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd937x/Module.symvers) +include $(MY_LOCAL_PATH)/asoc/codecs/wcd937x/Android.mk endif diff --git a/asoc/codecs/wcd937x/Android.mk b/asoc/codecs/wcd937x/Android.mk index 4168dd1b1eef..643339a14f2a 100644 --- a/asoc/codecs/wcd937x/Android.mk +++ b/asoc/codecs/wcd937x/Android.mk @@ -13,7 +13,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) bengal),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) bengal lito),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wcd937x/Kbuild b/asoc/codecs/wcd937x/Kbuild index e353e8a37d67..5bbbad7cbdf5 100644 --- a/asoc/codecs/wcd937x/Kbuild +++ b/asoc/codecs/wcd937x/Kbuild @@ -31,6 +31,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif + ifeq ($(CONFIG_ARCH_LITO), y) + include $(AUDIO_ROOT)/config/litoauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif endif # As per target team, build is done as follows: -- GitLab From aef38aebbf0e757d67a59b9f1763b65c1bba28f7 Mon Sep 17 00:00:00 2001 From: Ramlal Karra Date: Wed, 4 Mar 2020 13:13:13 +0530 Subject: [PATCH 1420/1645] asoc: codecs: Avoid MBHC OverCurrentProtection. In the existing code, Over Current Protection interrupt is enabled as part of MBHC insertion event handling. This is causing audio mute on Stereo Headset randomly. This OCP through MBHC is no more required as the Over Current/surge is handled in HW. Removing the OCP enabling code to fix the issue. CRs-Fixed: 2622368 Change-Id: Iae8994aa365eb294793190f665407af111b23c82 Signed-off-by: Ramlal Karra --- asoc/codecs/wcd-mbhc-v2.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 46a3850ae91e..f3e71af1944c 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -415,7 +415,6 @@ static void wcd_mbhc_clr_and_turnon_hph_padac(struct wcd_mbhc *mbhc) &mbhc->hph_pa_dac_state)) { pr_debug("%s: HPHR clear flag and enable PA\n", __func__); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHR_PA_EN, 1); - WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHR_OCP_DET_EN, 1); pa_turned_on = true; } mutex_unlock(&mbhc->hphr_pa_lock); @@ -424,7 +423,6 @@ static void wcd_mbhc_clr_and_turnon_hph_padac(struct wcd_mbhc *mbhc) &mbhc->hph_pa_dac_state)) { pr_debug("%s: HPHL clear flag and enable PA\n", __func__); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_PA_EN, 1); - WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_OCP_DET_EN, 1); pa_turned_on = true; } mutex_unlock(&mbhc->hphl_pa_lock); -- GitLab From 39932230f02a30ea087a6369399f2fcd36823b70 Mon Sep 17 00:00:00 2001 From: Jaideep Sharma Date: Wed, 11 Mar 2020 22:24:14 +0530 Subject: [PATCH 1421/1645] asoc: add code change for proxy playback and capture BE DAIs. proxy AFE port based BE DAIs can be used for various use cases, including but not limited to voice call. Add support for BE DAI link based on pseudo ports. Change-Id: I00384de1104399853743e709f53f969842ef69a1 Signed-off-by: Jaideep Sharma --- asoc/msm-dai-q6-v2.c | 49 ++++++++++++++++++++++++++++++++++++-- asoc/msm-pcm-routing-v2.c | 37 +++++++++++++++++++++++++++- asoc/msm-pcm-routing-v2.h | 6 ++++- dsp/q6afe.c | 10 ++++++++ dsp/q6audio-v2.c | 12 +++++++++- include/dsp/apr_audio-v2.h | 14 +++++++++-- include/dsp/q6afe-v2.h | 5 +++- 7 files changed, 125 insertions(+), 8 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index bf9c4c5b597b..7c2d118a8fc4 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -2621,6 +2621,8 @@ static int msm_dai_q6_hw_params(struct snd_pcm_substream *substream, case RT_PROXY_DAI_001_RX: case RT_PROXY_DAI_002_TX: case RT_PROXY_DAI_002_RX: + case RT_PROXY_PORT_002_TX: + case RT_PROXY_PORT_002_RX: rc = msm_dai_q6_afe_rtproxy_hw_params(params, dai); break; case VOICE_PLAYBACK_TX: @@ -4247,6 +4249,42 @@ static struct snd_soc_dai_driver msm_dai_q6_incall_record_dai[] = { }, }; +static struct snd_soc_dai_driver msm_dai_q6_proxy_tx_dai = { + .capture = { + .stream_name = "Proxy Capture", + .aif_name = "PROXY_TX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_ops, + .id = RT_PROXY_PORT_002_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, +}; + +static struct snd_soc_dai_driver msm_dai_q6_proxy_rx_dai = { + .playback = { + .stream_name = "Proxy Playback", + .aif_name = "PROXY_RX", + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_dai_q6_ops, + .id = RT_PROXY_PORT_002_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, +}; + static struct snd_soc_dai_driver msm_dai_q6_usb_rx_dai = { .playback = { .stream_name = "USB Audio Playback", @@ -7287,7 +7325,14 @@ static int msm_dai_q6_dev_probe(struct platform_device *pdev) pr_err("%s: Device not found stream name %s\n", __func__, stream_name); break; - + case RT_PROXY_PORT_002_RX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, &msm_dai_q6_proxy_rx_dai, 1); + break; + case RT_PROXY_PORT_002_TX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, &msm_dai_q6_proxy_tx_dai, 1); + break; default: rc = -ENODEV; break; diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 7207375a2615..24f39a60b2c2 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -697,6 +697,8 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_PRI_META_MI2S_RX}, { AFE_PORT_ID_SECONDARY_META_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SEC_META_MI2S_RX}, + { RT_PROXY_PORT_002_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PROXY_RX}, + { RT_PROXY_PORT_002_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PROXY_TX}, }; /* Track ASM playback & capture sessions of DAI @@ -3526,7 +3528,7 @@ static const char *const be_name[] = { "RX_CDC_DMA_RX_6", "RX_CDC_DMA_RX_7", "PRI_SPDIF_TX", "SEC_SPDIF_RX", "SEC_SPDIF_TX", "SLIM_9_RX", "SLIM_9_TX", "AFE_LOOPBACK_TX", "PRI_META_MI2S_RX", -"SEC_META_MI2S_RX" +"SEC_META_MI2S_RX", "PROXY_RX", "PROXY_TX" }; static SOC_ENUM_SINGLE_DECL(mm1_channel_mux, @@ -16747,6 +16749,17 @@ static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = { msm_routing_put_voice_mixer), }; +static const struct snd_kcontrol_new proxy_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PROXY_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PROXY_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_TX_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_I2S_TX, @@ -16844,6 +16857,9 @@ static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_TDM_TX_3_MMode1", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PROXY_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PROXY_TX, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { @@ -16939,6 +16955,9 @@ static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { SOC_DOUBLE_EXT("PRI_TDM_TX_3_MMode2", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PROXY_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PROXY_TX, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { @@ -24120,6 +24139,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_IN("SLIMBUS_9_TX", "Slimbus9 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("USB_AUDIO_RX", "USB Audio Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("USB_AUDIO_TX", "USB Audio Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PROXY_RX", "Proxy Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PROXY_TX", "Proxy Capture", 0, 0, 0, 0), /* Switch Definitions */ SND_SOC_DAPM_SWITCH("SLIMBUS_DL_HL", SND_SOC_NOPM, 0, 0, @@ -24549,6 +24570,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_NOPM, 0, 0, wsa_cdc_dma_rx_0_voice_mixer_controls, ARRAY_SIZE(wsa_cdc_dma_rx_0_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("PROXY_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + proxy_rx_voice_mixer_controls, + ARRAY_SIZE(proxy_rx_voice_mixer_controls)), SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0_Voice Mixer", SND_SOC_NOPM, 0, 0, rx_cdc_dma_rx_0_voice_mixer_controls, @@ -27396,6 +27421,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0_Voice Mixer"}, + {"PROXY_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PROXY_RX", NULL, "PROXY_RX_Voice Mixer"}, + + {"PROXY_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PROXY_RX", NULL, "PROXY_RX_Voice Mixer"}, + {"RX_CDC_DMA_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, @@ -27564,6 +27595,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode1_Tx Mixer", "QUAT_MI2S_TX_MMode1", "QUAT_MI2S_TX"}, {"VoiceMMode1_Tx Mixer", "QUIN_MI2S_TX_MMode1", "QUIN_MI2S_TX"}, {"VoiceMMode1_Tx Mixer", "PRI_TDM_TX_3_MMode1", "PRI_TDM_TX_3"}, + {"VoiceMMode1_Tx Mixer", "PROXY_TX_MMode1", "PROXY_TX"}, {"VOICEMMODE1_UL", NULL, "VoiceMMode1_Tx Mixer"}, {"VoiceMMode2_Tx Mixer", "PRI_TX_MMode2", "PRI_I2S_TX"}, @@ -27593,6 +27625,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode2_Tx Mixer", "QUAT_MI2S_TX_MMode2", "QUAT_MI2S_TX"}, {"VoiceMMode2_Tx Mixer", "QUIN_MI2S_TX_MMode2", "QUIN_MI2S_TX"}, {"VoiceMMode2_Tx Mixer", "PRI_TDM_TX_3_MMode2", "PRI_TDM_TX_3"}, + {"VoiceMMode2_Tx Mixer", "PROXY_TX_MMode2", "PROXY_TX"}, {"VOICEMMODE2_UL", NULL, "VoiceMMode2_Tx Mixer"}, {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"}, @@ -28898,6 +28931,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "RX_CDC_DMA_RX_5"}, {"BE_OUT", NULL, "RX_CDC_DMA_RX_6"}, {"BE_OUT", NULL, "RX_CDC_DMA_RX_7"}, + {"BE_OUT", NULL, "PROXY_RX"}, {"PRI_I2S_TX", NULL, "BE_IN"}, {"MI2S_TX", NULL, "BE_IN"}, @@ -28994,6 +29028,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"TX_CDC_DMA_TX_5", NULL, "BE_IN"}, {"PRI_SPDIF_TX", NULL, "BE_IN"}, {"SEC_SPDIF_TX", NULL, "BE_IN"}, + {"PROXY_TX", NULL, "BE_IN"}, }; static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 9c74c32ffbd5..ee9c63ad89c8 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef _MSM_PCM_ROUTING_H #define _MSM_PCM_ROUTING_H @@ -42,6 +42,8 @@ #define LPASS_BE_VOICE2_PLAYBACK_TX "VOICE2_PLAYBACK_TX" #define LPASS_BE_INCALL_RECORD_RX "INCALL_RECORD_RX" #define LPASS_BE_INCALL_RECORD_TX "INCALL_RECORD_TX" +#define LPASS_BE_PROXY_RX "PROXY_RX" +#define LPASS_BE_PROXY_TX "PROXY_TX" #define LPASS_BE_SEC_I2S_RX "SECONDARY_I2S_RX" #define LPASS_BE_PRI_SPDIF_RX "PRI_SPDIF_RX" #define LPASS_BE_PRI_SPDIF_TX "PRI_SPDIF_TX" @@ -500,6 +502,8 @@ enum { MSM_BACKEND_DAI_AFE_LOOPBACK_TX, MSM_BACKEND_DAI_PRI_META_MI2S_RX, MSM_BACKEND_DAI_SEC_META_MI2S_RX, + MSM_BACKEND_DAI_PROXY_RX, + MSM_BACKEND_DAI_PROXY_TX, MSM_BACKEND_DAI_MAX, }; diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 16d156783c53..e3d75ccc5727 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -988,6 +988,8 @@ int afe_sizeof_cfg_cmd(u16 port_id) break; case RT_PROXY_PORT_001_RX: case RT_PROXY_PORT_001_TX: + case RT_PROXY_PORT_002_RX: + case RT_PROXY_PORT_002_TX: ret_size = SIZEOF_CFG_CMD(afe_param_id_rt_proxy_port_cfg); break; case AFE_PORT_ID_USB_RX: @@ -4755,6 +4757,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, break; case RT_PROXY_PORT_001_RX: case RT_PROXY_PORT_001_TX: + case RT_PROXY_PORT_002_RX: + case RT_PROXY_PORT_002_TX: cfg_type = AFE_PARAM_ID_RT_PROXY_CONFIG; break; case INT_BT_SCO_RX: @@ -5302,6 +5306,10 @@ int afe_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_7; case AFE_LOOPBACK_TX: return IDX_AFE_LOOPBACK_TX; + case RT_PROXY_PORT_002_RX: + return IDX_RT_PROXY_PORT_002_RX; + case RT_PROXY_PORT_002_TX: + return IDX_RT_PROXY_PORT_002_TX; default: pr_err("%s: port 0x%x\n", __func__, port_id); return -EINVAL; @@ -7499,6 +7507,8 @@ int afe_validate_port(u16 port_id) case AFE_PORT_ID_TX_CODEC_DMA_TX_5: case AFE_PORT_ID_RX_CODEC_DMA_RX_6: case AFE_PORT_ID_RX_CODEC_DMA_RX_7: + case RT_PROXY_PORT_002_RX: + case RT_PROXY_PORT_002_TX: { ret = 0; break; diff --git a/dsp/q6audio-v2.c b/dsp/q6audio-v2.c index 68b373629a18..e3a2dc7805b7 100644 --- a/dsp/q6audio-v2.c +++ b/dsp/q6audio-v2.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -385,6 +385,10 @@ int q6audio_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_6; case AFE_PORT_ID_RX_CODEC_DMA_RX_7: return IDX_AFE_PORT_ID_RX_CODEC_DMA_RX_7; + case RT_PROXY_PORT_002_RX: + return IDX_RT_PROXY_PORT_002_RX; + case RT_PROXY_PORT_002_TX: + return IDX_RT_PROXY_PORT_002_TX; default: return -EINVAL; } } @@ -767,6 +771,10 @@ int q6audio_get_port_id(u16 port_id) return AFE_PORT_ID_RX_CODEC_DMA_RX_6; case AFE_PORT_ID_RX_CODEC_DMA_RX_7: return AFE_PORT_ID_RX_CODEC_DMA_RX_7; + case RT_PROXY_PORT_002_RX: + return RT_PROXY_PORT_002_RX; + case RT_PROXY_PORT_002_TX: + return RT_PROXY_PORT_002_TX; default: pr_warn("%s: Invalid port_id %d\n", __func__, port_id); return -EINVAL; @@ -1196,6 +1204,8 @@ int q6audio_validate_port(u16 port_id) case AFE_PORT_ID_TX_CODEC_DMA_TX_5: case AFE_PORT_ID_RX_CODEC_DMA_RX_6: case AFE_PORT_ID_RX_CODEC_DMA_RX_7: + case RT_PROXY_PORT_002_RX: + case RT_PROXY_PORT_002_TX: { ret = 0; break; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 111f191635f0..908ec649e462 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ @@ -1385,7 +1385,7 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_PORT_ID_SLIMBUS_RANGE_SIZE 0xA /* Size of the range of port IDs for real-time proxy ports. */ -#define AFE_PORT_ID_RT_PROXY_PORT_RANGE_SIZE 0x2 +#define AFE_PORT_ID_RT_PROXY_PORT_RANGE_SIZE 0x4 /* Size of the range of port IDs for pseudoports. */ #define AFE_PORT_ID_PSEUDOPORT_RANGE_SIZE 0x5 @@ -1664,6 +1664,16 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_PORT_ID_VOICE2_PLAYBACK_TX 0x8002 #define AFE_PORT_ID_VOICE_PLAYBACK_TX 0x8005 +/* + * Proxyport used for voice call data processing. + * In cases like call-screening feature, where user can communicate + * with caller with the help of "call screen" mode, and without + * connecting the call with any HW input/output devices in the phon, + * voice call can use Pseudo port to start voice data processing. + */ +#define RT_PROXY_PORT_002_TX 0x2003 +#define RT_PROXY_PORT_002_RX 0x2002 + #define AFE_PORT_ID_PRIMARY_TDM_RX \ (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x00) #define AFE_PORT_ID_PRIMARY_TDM_RX_1 \ diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 9e1a0b2f44fb..73a7cf872a61 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef __Q6AFE_V2_H__ #define __Q6AFE_V2_H__ @@ -284,6 +284,9 @@ enum { /* IDX 208-> 209 */ IDX_AFE_PORT_ID_PRIMARY_META_MI2S_RX, IDX_AFE_PORT_ID_SECONDARY_META_MI2S_RX, + /* IDX 210-> 211 */ + IDX_RT_PROXY_PORT_002_RX, + IDX_RT_PROXY_PORT_002_TX, AFE_MAX_PORTS }; -- GitLab From 2ef4fb23debb50ba868db96e886a6aeb245544c8 Mon Sep 17 00:00:00 2001 From: Jaideep Sharma Date: Wed, 11 Mar 2020 22:29:11 +0530 Subject: [PATCH 1422/1645] asoc:kona: add proxy ports for call screening in machine driver add machine driver changes for proxy port changes. Change-Id: I04146717ee68f7c2dac719d5e4b2bbefea1797b8 Signed-off-by: Jaideep Sharma --- asoc/kona.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/asoc/kona.c b/asoc/kona.c index 68f6ddbc1a8e..a97590f717bf 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -6189,6 +6189,33 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, }, + /* Proxy Tx BACK END DAI Link */ + { + .name = LPASS_BE_PROXY_TX, + .stream_name = "Proxy Capture", + .cpu_dai_name = "msm-dai-q6-dev.8195", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PROXY_TX, + .ignore_suspend = 1, + }, + /* Proxy Rx BACK END DAI Link */ + { + .name = LPASS_BE_PROXY_RX, + .stream_name = "Proxy Playback", + .cpu_dai_name = "msm-dai-q6-dev.8194", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PROXY_RX, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, { .name = LPASS_BE_USB_AUDIO_RX, .stream_name = "USB Audio Playback", -- GitLab From d273a6f0b68107816c4d9b7dff824d163b02c252 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 3 Mar 2020 21:59:03 +0530 Subject: [PATCH 1423/1645] asoc: codecs: Add support for rouleur codec Add support for rouleur codec driver and pm2250 spmi driver. Change-Id: Ie56f7af012c0c7b6e68077463f43050e051a3ef9 Signed-off-by: Aditya Bavanari --- asoc/codecs/rouleur/Android.mk | 65 + asoc/codecs/rouleur/Kbuild | 120 ++ asoc/codecs/rouleur/internal.h | 172 ++ asoc/codecs/rouleur/pm2250-spmi.h | 17 + asoc/codecs/rouleur/pm2250_spmi.c | 94 + asoc/codecs/rouleur/rouleur-mbhc.c | 1155 +++++++++++ asoc/codecs/rouleur/rouleur-mbhc.h | 67 + asoc/codecs/rouleur/rouleur-registers.h | 121 ++ asoc/codecs/rouleur/rouleur-regmap.c | 160 ++ asoc/codecs/rouleur/rouleur-tables.c | 105 + asoc/codecs/rouleur/rouleur.c | 2492 +++++++++++++++++++++++ asoc/codecs/rouleur/rouleur.h | 19 + asoc/codecs/rouleur/rouleur_slave.c | 144 ++ 13 files changed, 4731 insertions(+) create mode 100644 asoc/codecs/rouleur/Android.mk create mode 100644 asoc/codecs/rouleur/Kbuild create mode 100644 asoc/codecs/rouleur/internal.h create mode 100644 asoc/codecs/rouleur/pm2250-spmi.h create mode 100644 asoc/codecs/rouleur/pm2250_spmi.c create mode 100644 asoc/codecs/rouleur/rouleur-mbhc.c create mode 100644 asoc/codecs/rouleur/rouleur-mbhc.h create mode 100644 asoc/codecs/rouleur/rouleur-registers.h create mode 100644 asoc/codecs/rouleur/rouleur-regmap.c create mode 100644 asoc/codecs/rouleur/rouleur-tables.c create mode 100644 asoc/codecs/rouleur/rouleur.c create mode 100644 asoc/codecs/rouleur/rouleur.h create mode 100644 asoc/codecs/rouleur/rouleur_slave.c diff --git a/asoc/codecs/rouleur/Android.mk b/asoc/codecs/rouleur/Android.mk new file mode 100644 index 000000000000..4fb5793695d2 --- /dev/null +++ b/asoc/codecs/rouleur/Android.mk @@ -0,0 +1,65 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +# Check if this driver needs be built for current target +ifeq ($(call is-board-platform,bengal),true) +AUDIO_SELECT := CONFIG_SND_SOC_BENGAL=m +endif + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) bengal),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=rouleur_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_rouleur.ko +LOCAL_MODULE_KBUILD_NAME := rouleur_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_rouleur_slave.ko +LOCAL_MODULE_KBUILD_NAME := rouleur_slave_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_pm2250_spmi.ko +LOCAL_MODULE_KBUILD_NAME := pm2250_spmi_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/asoc/codecs/rouleur/Kbuild b/asoc/codecs/rouleur/Kbuild new file mode 100644 index 000000000000..b59bcb1194ef --- /dev/null +++ b/asoc/codecs/rouleur/Kbuild @@ -0,0 +1,120 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + + + +ifeq ($(KERNEL_BUILD), 1) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.19 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) + ifeq ($(CONFIG_ARCH_BENGAL), y) + include $(AUDIO_ROOT)/config/bengalauto.conf + export + INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h + endif +endif + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ ROULEUR ############ + +# for ROULEUR Codec +ifdef CONFIG_SND_SOC_ROULEUR + ROULEUR_OBJS += rouleur.o + ROULEUR_OBJS += rouleur-regmap.o + ROULEUR_OBJS += rouleur-tables.o + ROULEUR_OBJS += rouleur-mbhc.o +endif + +ifdef CONFIG_PM2250_SPMI + PM2250_SPMI_OBJS += pm2250_spmi.o +endif + +ifdef CONFIG_SND_SOC_ROULEUR_SLAVE + ROULEUR_SLAVE_OBJS += rouleur_slave.o +endif + +LINUX_INC += -Iinclude/linux + +INCS += $(COMMON_INC) \ + $(UAPI_INC) + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +ifeq ($(KERNEL_BUILD), 0) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_ROULEUR) += rouleur_dlkm.o +rouleur_dlkm-y := $(ROULEUR_OBJS) + +obj-$(CONFIG_SND_SOC_ROULEUR_SLAVE) += rouleur_slave_dlkm.o +rouleur_slave_dlkm-y := $(ROULEUR_SLAVE_OBJS) + +obj-$(CONFIG_PM2250_SPMI) += pm2250_spmi_dlkm.o +pm2250_spmi_dlkm-y := $(PM2250_SPMI_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/rouleur/internal.h b/asoc/codecs/rouleur/internal.h new file mode 100644 index 000000000000..7104685d7cd8 --- /dev/null +++ b/asoc/codecs/rouleur/internal.h @@ -0,0 +1,172 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _ROULEUR_INTERNAL_H +#define _ROULEUR_INTERNAL_H + +#include +#include +#include +#include "rouleur-mbhc.h" + +#define ROULEUR_MAX_MICBIAS 3 + +/* Convert from vout ctl to micbias voltage in mV */ +#define WCD_VOUT_CTL_TO_MICB(v) (1600 + v * 50) +#define MAX_PORT 8 +#define MAX_CH_PER_PORT 8 + +extern struct regmap_config rouleur_regmap_config; + +struct codec_port_info { + u32 slave_port_type; + u32 master_port_type; + u32 ch_mask; + u32 num_ch; + u32 ch_rate; +}; + +struct rouleur_priv { + struct device *dev; + + int variant; + struct snd_soc_component *component; + struct device_node *spmi_np; + struct regmap *regmap; + + struct swr_device *rx_swr_dev; + struct swr_device *tx_swr_dev; + + s32 micb_ref[ROULEUR_MAX_MICBIAS]; + s32 pullup_ref[ROULEUR_MAX_MICBIAS]; + + struct fw_info *fw_data; + + struct mutex micb_lock; + s32 dmic_0_1_clk_cnt; + /* mbhc module */ + struct rouleur_mbhc *mbhc; + + bool comp1_enable; + bool comp2_enable; + + struct irq_domain *virq; + struct wcd_irq_info irq_info; + u32 rx_clk_cnt; + int num_irq_regs; + /* to track the status */ + unsigned long status_mask; + + u8 num_tx_ports; + u8 num_rx_ports; + struct codec_port_info + tx_port_mapping[MAX_PORT][MAX_CH_PER_PORT]; + struct codec_port_info + rx_port_mapping[MAX_PORT][MAX_CH_PER_PORT]; + struct regulator_bulk_data *supplies; + struct notifier_block nblock; + /* wcd callback to bolero */ + void *handle; + int (*update_wcd_event)(void *handle, u16 event, u32 data); + int (*register_notifier)(void *handle, + struct notifier_block *nblock, + bool enable); + int (*wakeup)(void *handle, bool enable); + u32 version; + /* Entry for version info */ + struct snd_info_entry *entry; + struct snd_info_entry *version_entry; + struct device *spmi_dev; + int reset_reg; + int mbias_cnt; + struct mutex rx_clk_lock; + struct mutex main_bias_lock; +}; + +struct rouleur_micbias_setting { + u32 micb1_mv; + u32 micb2_mv; + u32 micb3_mv; +}; + +struct rouleur_pdata { + struct device_node *spmi_np; + struct device_node *rx_slave; + struct device_node *tx_slave; + struct rouleur_micbias_setting micbias; + + struct cdc_regulator *regulator; + int num_supplies; + int reset_reg; +}; + +struct wcd_ctrl_platform_data { + void *handle; + int (*update_wcd_event)(void *handle, u16 event, u32 data); + int (*register_notifier)(void *handle, + struct notifier_block *nblock, + bool enable); +}; + +enum { + WCD_RX1, + WCD_RX2, + WCD_RX3 +}; + +enum { + BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1, + BOLERO_WCD_EVT_PA_OFF_PRE_SSR, + BOLERO_WCD_EVT_SSR_DOWN, + BOLERO_WCD_EVT_SSR_UP, +}; + +enum { + WCD_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */ + WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */ + WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */ + WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST, + WCD_BOLERO_EVT_BCS_CLK_OFF, +}; + +enum { + /* INTR_CTRL_INT_MASK_0 */ + ROULEUR_IRQ_MBHC_BUTTON_PRESS_DET = 0, + ROULEUR_IRQ_MBHC_BUTTON_RELEASE_DET, + ROULEUR_IRQ_MBHC_ELECT_INS_REM_DET, + ROULEUR_IRQ_MBHC_ELECT_INS_REM_LEG_DET, + ROULEUR_IRQ_MBHC_SW_DET, + ROULEUR_IRQ_HPHR_OCP_INT, + ROULEUR_IRQ_HPHR_CNP_INT, + ROULEUR_IRQ_HPHL_OCP_INT, + + /* INTR_CTRL_INT_MASK_1 */ + ROULEUR_IRQ_HPHL_CNP_INT, + ROULEUR_IRQ_EAR_CNP_INT, + ROULEUR_IRQ_EAR_OCP_INT, + ROULEUR_IRQ_LO_CNP_INT, + ROULEUR_IRQ_LO_OCP_INT, + ROULEUR_IRQ_HPHL_PDM_WD_INT, + ROULEUR_IRQ_HPHR_PDM_WD_INT, + ROULEUR_IRQ_RESERVED_0, + + /* INTR_CTRL_INT_MASK_2 */ + ROULEUR_IRQ_RESERVED_1, + ROULEUR_IRQ_RESERVED_2, + ROULEUR_IRQ_HPHL_SURGE_DET_INT, + ROULEUR_IRQ_HPHR_SURGE_DET_INT, + ROULEUR_NUM_IRQS, +}; + +extern void rouleur_disable_bcs_before_slow_insert( + struct snd_soc_component *component, + bool bcs_disable); +extern struct rouleur_mbhc *rouleur_soc_get_mbhc( + struct snd_soc_component *component); +extern int rouleur_mbhc_micb_adjust_voltage(struct snd_soc_component *component, + int volt, int micb_num); +extern int rouleur_get_micb_vout_ctl_val(u32 micb_mv); +extern int rouleur_micbias_control(struct snd_soc_component *component, + int micb_num, int req, bool is_dapm); +#endif diff --git a/asoc/codecs/rouleur/pm2250-spmi.h b/asoc/codecs/rouleur/pm2250-spmi.h new file mode 100644 index 000000000000..87c913d43d0f --- /dev/null +++ b/asoc/codecs/rouleur/pm2250-spmi.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _PM2250_SPMI_H +#define _PM2250_SPMI_H + +#ifdef CONFIG_PM2250_SPMI +int pm2250_spmi_write(struct device *dev, int reg, int value); +#else +int pm2250_spmi_write(struct device *dev, int reg, int value) +{ + return 0; +} +#endif /* CONFIG_PM2250_SPMI */ + +#endif diff --git a/asoc/codecs/rouleur/pm2250_spmi.c b/asoc/codecs/rouleur/pm2250_spmi.c new file mode 100644 index 000000000000..1e5f70d177e8 --- /dev/null +++ b/asoc/codecs/rouleur/pm2250_spmi.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * @regmap: regmap used to access PMIC registers + */ +struct pm2250_spmi { + struct regmap *regmap; +}; + +static const struct of_device_id pm2250_id_table[] = { + { .compatible = "qcom,pm2250-spmi" }, + { }, +}; +MODULE_DEVICE_TABLE(of, pm2250_id_table); + +int pm2250_spmi_write(struct device *dev, int reg, int value) +{ + int rc; + struct pm2250_spmi *spmi_dd; + + if (!of_device_is_compatible(dev->of_node, "qcom,pm2250-spmi")) { + pr_err("%s: Device node is invalid\n", __func__); + return -EINVAL; + } + + spmi_dd = dev_get_drvdata(dev); + if (!spmi_dd) + return -EINVAL; + + rc = regmap_write(spmi_dd->regmap, reg, value); + if (rc) + dev_err(dev, "%s: Write to PMIC register failed\n", __func__); + + return rc; +} +EXPORT_SYMBOL(pm2250_spmi_write); + +static int pm2250_spmi_probe(struct platform_device *pdev) +{ + struct pm2250_spmi *spmi_dd; + const struct of_device_id *match; + + match = of_match_node(pm2250_id_table, pdev->dev.of_node); + if (!match) + return -ENXIO; + + spmi_dd = devm_kzalloc(&pdev->dev, sizeof(*spmi_dd), GFP_KERNEL); + if (spmi_dd == NULL) + return -ENOMEM; + + spmi_dd->regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!spmi_dd->regmap) { + dev_err(&pdev->dev, "Parent regmap unavailable.\n"); + return -ENXIO; + } + + platform_set_drvdata(pdev, spmi_dd); + + dev_dbg(&pdev->dev, "Probe success !!\n"); + + return 0; +} + +static int pm2250_spmi_remove(struct platform_device *pdev) +{ + of_platform_depopulate(&pdev->dev); + return 0; +} + +static struct platform_driver pm2250_spmi_driver = { + .probe = pm2250_spmi_probe, + .remove = pm2250_spmi_remove, + .driver = { + .name = "pm2250-spmi", + .of_match_table = pm2250_id_table, + }, +}; +module_platform_driver(pm2250_spmi_driver); + +MODULE_ALIAS("platform:pm2250-spmi"); +MODULE_DESCRIPTION("PMIC SPMI driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/rouleur/rouleur-mbhc.c b/asoc/codecs/rouleur/rouleur-mbhc.c new file mode 100644 index 000000000000..3e3ef51140bf --- /dev/null +++ b/asoc/codecs/rouleur/rouleur-mbhc.c @@ -0,0 +1,1155 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rouleur-registers.h" +#include +#include +#include "internal.h" + +#define ROULEUR_ZDET_SUPPORTED true +/* Z value defined in milliohm */ +#define ROULEUR_ZDET_VAL_32 32000 +#define ROULEUR_ZDET_VAL_400 400000 +#define ROULEUR_ZDET_VAL_1200 1200000 +#define ROULEUR_ZDET_VAL_100K 100000000 +/* Z floating defined in ohms */ +#define ROULEUR_ZDET_FLOATING_IMPEDANCE 0x0FFFFFFE + +#define ROULEUR_ZDET_NUM_MEASUREMENTS 900 +#define ROULEUR_MBHC_GET_C1(c) ((c & 0xC000) >> 14) +#define ROULEUR_MBHC_GET_X1(x) (x & 0x3FFF) +/* Z value compared in milliOhm */ +#define ROULEUR_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000)) +#define ROULEUR_MBHC_ZDET_CONST (86 * 16384) +#define ROULEUR_MBHC_MOISTURE_RREF R_24_KOHM + +static struct wcd_mbhc_register + wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = { + WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN", + ROULEUR_ANA_MBHC_MECH, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_DET_EN", + ROULEUR_ANA_MBHC_MECH, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MECH_DETECTION_TYPE", + ROULEUR_ANA_MBHC_MECH, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_CLAMP_CTL", + ROULEUR_ANA_MBHC_PLUG_DETECT_CTL, 0x30, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_DETECTION_TYPE", + ROULEUR_ANA_MBHC_ELECT, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_CTRL", + ROULEUR_ANA_MBHC_PLUG_DETECT_CTL, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL", + ROULEUR_ANA_MBHC_MECH, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PLUG_TYPE", + ROULEUR_ANA_MBHC_MECH, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_PLUG_TYPE", + ROULEUR_ANA_MBHC_MECH, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SW_HPH_LP_100K_TO_GND", + ROULEUR_ANA_MBHC_MECH, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_SCHMT_ISRC", + ROULEUR_ANA_MBHC_ELECT, 0x06, 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_EN", + ROULEUR_ANA_MBHC_ELECT, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_INSREM_DBNC", + ROULEUR_ANA_MBHC_PLUG_DETECT_CTL, 0x0F, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_DBNC", + ROULEUR_ANA_MBHC_CTL_1, 0x03, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_VREF", + ROULEUR_ANA_MBHC_CTL_2, 0x03, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT", + ROULEUR_ANA_MBHC_RESULT_3, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_IN2P_CLAMP_STATE", + ROULEUR_ANA_MBHC_RESULT_3, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT", + ROULEUR_ANA_MBHC_RESULT_3, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT", + ROULEUR_ANA_MBHC_RESULT_3, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_SCHMT_RESULT", + ROULEUR_ANA_MBHC_RESULT_3, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_OCP_FSM_EN", + SND_SOC_NOPM, 0x00, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_RESULT", + ROULEUR_ANA_MBHC_RESULT_3, 0x07, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_ISRC_CTL", + ROULEUR_ANA_MBHC_ELECT, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT", + ROULEUR_ANA_MBHC_RESULT_3, 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL", + ROULEUR_ANA_MICBIAS_MICB_1_2_EN, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME", + SND_SOC_NOPM, 0x00, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN", + ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PA_EN", + ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_PA_EN", + ROULEUR_ANA_HPHPA_CNP_CTL_2, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE", + ROULEUR_ANA_MBHC_RESULT_3, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL", + 0, 0, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN", + SND_SOC_NOPM, 0x00, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_STATUS", + ROULEUR_ANA_MBHC_FSM_STATUS, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL", + ROULEUR_ANA_MBHC_CTL_2, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MOISTURE_STATUS", + ROULEUR_ANA_MBHC_FSM_STATUS, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_GND", + SND_SOC_NOPM, 0x00, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_GND", + SND_SOC_NOPM, 0x00, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_DET_EN", + ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x02, 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_DET_EN", + ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_STATUS", + ROULEUR_DIG_SWR_INTR_STATUS_0, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_STATUS", + ROULEUR_DIG_SWR_INTR_STATUS_0, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_EN", + ROULEUR_ANA_MBHC_CTL_1, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_COMPLETE", ROULEUR_ANA_MBHC_FSM_STATUS, + 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_TIMEOUT", ROULEUR_ANA_MBHC_FSM_STATUS, + 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_RESULT", ROULEUR_ANA_MBHC_ADC_RESULT, + 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB2_VOUT", + ROULEUR_ANA_MICBIAS_LDO_1_SETTING, 0xF8, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ADC_MODE", + ROULEUR_ANA_MBHC_CTL_1, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_DETECTION_DONE", + ROULEUR_ANA_MBHC_CTL_1, 0x04, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_ISRC_EN", + ROULEUR_ANA_MBHC_ZDET, 0x02, 1, 0), +}; + +static const struct wcd_mbhc_intr intr_ids = { + .mbhc_sw_intr = ROULEUR_IRQ_MBHC_SW_DET, + .mbhc_btn_press_intr = ROULEUR_IRQ_MBHC_BUTTON_PRESS_DET, + .mbhc_btn_release_intr = ROULEUR_IRQ_MBHC_BUTTON_RELEASE_DET, + .mbhc_hs_ins_intr = ROULEUR_IRQ_MBHC_ELECT_INS_REM_LEG_DET, + .mbhc_hs_rem_intr = ROULEUR_IRQ_MBHC_ELECT_INS_REM_DET, + .hph_left_ocp = ROULEUR_IRQ_HPHL_OCP_INT, + .hph_right_ocp = ROULEUR_IRQ_HPHR_OCP_INT, +}; + +struct rouleur_mbhc_zdet_param { + u16 ldo_ctl; + u16 noff; + u16 nshift; + u16 btn5; + u16 btn6; + u16 btn7; +}; + +static int rouleur_mbhc_request_irq(struct snd_soc_component *component, + int irq, irq_handler_t handler, + const char *name, void *data) +{ + struct rouleur_priv *rouleur = dev_get_drvdata(component->dev); + + return wcd_request_irq(&rouleur->irq_info, irq, name, handler, data); +} + +static void rouleur_mbhc_irq_control(struct snd_soc_component *component, + int irq, bool enable) +{ + struct rouleur_priv *rouleur = dev_get_drvdata(component->dev); + + if (enable) + wcd_enable_irq(&rouleur->irq_info, irq); + else + wcd_disable_irq(&rouleur->irq_info, irq); +} + +static int rouleur_mbhc_free_irq(struct snd_soc_component *component, + int irq, void *data) +{ + struct rouleur_priv *rouleur = dev_get_drvdata(component->dev); + + wcd_free_irq(&rouleur->irq_info, irq, data); + + return 0; +} + +static void rouleur_mbhc_clk_setup(struct snd_soc_component *component, + bool enable) +{ + if (enable) + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_CTL_1, + 0x80, 0x80); + else + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_CTL_1, + 0x80, 0x00); +} + +static int rouleur_mbhc_btn_to_num(struct snd_soc_component *component) +{ + return snd_soc_component_read32(component, ROULEUR_ANA_MBHC_RESULT_3) & + 0x7; +} + +static void rouleur_mbhc_mbhc_bias_control(struct snd_soc_component *component, + bool enable) +{ + if (enable) + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ELECT, + 0x01, 0x01); + else + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ELECT, + 0x01, 0x00); +} + +static void rouleur_mbhc_program_btn_thr(struct snd_soc_component *component, + s16 *btn_low, s16 *btn_high, + int num_btn, bool is_micbias) +{ + int i; + int vth; + + if (num_btn > WCD_MBHC_DEF_BUTTONS) { + dev_err(component->dev, "%s: invalid number of buttons: %d\n", + __func__, num_btn); + return; + } + + for (i = 0; i < num_btn; i++) { + vth = ((btn_high[i] * 2) / 25) & 0x3F; + snd_soc_component_update_bits(component, + ROULEUR_ANA_MBHC_BTN0_ZDET_VREF1 + i, + 0xFC, vth << 2); + dev_dbg(component->dev, "%s: btn_high[%d]: %d, vth: %d\n", + __func__, i, btn_high[i], vth); + } +} + +static bool rouleur_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock) +{ + struct snd_soc_component *component = mbhc->component; + struct rouleur_priv *rouleur = dev_get_drvdata(component->dev); + + rouleur->wakeup((void *)rouleur, lock); + return true; +} + +static int rouleur_mbhc_register_notifier(struct wcd_mbhc *mbhc, + struct notifier_block *nblock, + bool enable) +{ + struct rouleur_mbhc *rouleur_mbhc; + + rouleur_mbhc = container_of(mbhc, struct rouleur_mbhc, wcd_mbhc); + + if (enable) + return blocking_notifier_chain_register(&rouleur_mbhc->notifier, + nblock); + else + return blocking_notifier_chain_unregister( + &rouleur_mbhc->notifier, nblock); +} + +static bool rouleur_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) +{ + u8 val = 0; + + if (micb_num == MIC_BIAS_2) { + val = ((snd_soc_component_read32(mbhc->component, + ROULEUR_ANA_MICBIAS_MICB_1_2_EN) & 0x04) + >> 2); + if (val == 0x01) + return true; + } + return false; +} + +static bool rouleur_mbhc_hph_pa_on_status(struct snd_soc_component *component) +{ + return (snd_soc_component_read32(component, ROULEUR_ANA_HPHPA_PA_STATUS) + & 0xFF) ? true : false; +} + +static void rouleur_mbhc_hph_l_pull_up_control( + struct snd_soc_component *component, + int pull_up_cur) +{ + /* Default pull up current to 2uA */ + if (pull_up_cur < I_OFF || pull_up_cur > I_3P0_UA || + pull_up_cur == I_DEFAULT) + pull_up_cur = I_2P0_UA; + + dev_dbg(component->dev, "%s: HS pull up current:%d\n", + __func__, pull_up_cur); + + snd_soc_component_update_bits(component, + ROULEUR_ANA_MBHC_PLUG_DETECT_CTL, + 0xC0, pull_up_cur); +} + +static int rouleur_mbhc_request_micbias(struct snd_soc_component *component, + int micb_num, int req) +{ + int ret = 0; + + ret = rouleur_micbias_control(component, micb_num, req, false); + + return ret; +} + +static void rouleur_mbhc_micb_ramp_control(struct snd_soc_component *component, + bool enable) +{ + if (enable) { + snd_soc_component_update_bits(component, + ROULEUR_ANA_MBHC_MICB2_RAMP, + 0x1C, 0x0C); + snd_soc_component_update_bits(component, + ROULEUR_ANA_MBHC_MICB2_RAMP, + 0x80, 0x80); + } else { + snd_soc_component_update_bits(component, + ROULEUR_ANA_MBHC_MICB2_RAMP, + 0x80, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_ANA_MBHC_MICB2_RAMP, + 0x1C, 0x00); + } +} + +static struct firmware_cal *rouleur_get_hwdep_fw_cal(struct wcd_mbhc *mbhc, + enum wcd_cal_type type) +{ + struct rouleur_mbhc *rouleur_mbhc; + struct firmware_cal *hwdep_cal; + struct snd_soc_component *component = mbhc->component; + + rouleur_mbhc = container_of(mbhc, struct rouleur_mbhc, wcd_mbhc); + + if (!component) { + pr_err("%s: NULL component pointer\n", __func__); + return NULL; + } + hwdep_cal = wcdcal_get_fw_cal(rouleur_mbhc->fw_data, type); + if (!hwdep_cal) + dev_err(component->dev, "%s: cal not sent by %d\n", + __func__, type); + + return hwdep_cal; +} + +static int rouleur_mbhc_micb_ctrl_threshold_mic( + struct snd_soc_component *component, + int micb_num, bool req_en) +{ + struct rouleur_pdata *pdata = dev_get_platdata(component->dev); + int rc, micb_mv; + + if (micb_num != MIC_BIAS_2) + return -EINVAL; + /* + * If device tree micbias level is already above the minimum + * voltage needed to detect threshold microphone, then do + * not change the micbias, just return. + */ + if (pdata->micbias.micb2_mv >= WCD_MBHC_THR_HS_MICB_MV) + return 0; + + micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb2_mv; + + rc = rouleur_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2); + + return rc; +} + +static inline void rouleur_mbhc_get_result_params(struct rouleur_priv *rouleur, + s16 *d1_a, u16 noff, + int32_t *zdet) +{ + int i; + int val = 0, val1 = 0; + s16 c1 = 0; + s32 x1 = 0, d1 = 0; + int32_t denom; + int minCode_param[] = { + 3277, 1639, 820, 410, 205, 103, 52, 26 + }; + + regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x20, 0x20); + for (i = 0; i < ROULEUR_ZDET_NUM_MEASUREMENTS; i++) { + regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &val); + if (val & 0x80) + break; + } + val = val << 0x8; + regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_1, &val1); + val |= val1; + regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x20, 0x00); + x1 = ROULEUR_MBHC_GET_X1(val); + c1 = ROULEUR_MBHC_GET_C1(val); + /* If ramp is not complete, give additional 5ms */ + if ((c1 < 2) && x1) + usleep_range(5000, 5050); + + if (!c1 || !x1) { + dev_dbg(rouleur->dev, + "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n", + __func__, c1, x1); + goto ramp_down; + } + d1 = d1_a[c1]; + denom = (x1 * d1) - (1 << (14 - noff)); + if (denom > 0) + *zdet = (ROULEUR_MBHC_ZDET_CONST * 1000) / denom; + else if (x1 < minCode_param[noff]) + *zdet = ROULEUR_ZDET_FLOATING_IMPEDANCE; + + dev_dbg(rouleur->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n", + __func__, d1, c1, x1, *zdet); +ramp_down: + i = 0; + while (x1) { + regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_1, &val); + regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &val1); + val = val << 0x8; + val |= val1; + x1 = ROULEUR_MBHC_GET_X1(val); + i++; + if (i == ROULEUR_ZDET_NUM_MEASUREMENTS) + break; + } +} + +#if 0 +static void rouleur_mbhc_zdet_ramp(struct snd_soc_component *component, + struct rouleur_mbhc_zdet_param *zdet_param, + int32_t *zl, int32_t *zr, s16 *d1_a) +{ + struct rouleur_priv *rouleur = dev_get_drvdata(component->dev); + int32_t zdet = 0; + + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ZDET_ANA_CTL, + 0x70, zdet_param->ldo_ctl << 4); + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_BTN5, 0xFC, + zdet_param->btn5); + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_BTN6, 0xFC, + zdet_param->btn6); + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_BTN7, 0xFC, + zdet_param->btn7); + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ZDET_ANA_CTL, + 0x0F, zdet_param->noff); + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ZDET_RAMP_CTL, + 0x0F, zdet_param->nshift); + + if (!zl) + goto z_right; + /* Start impedance measurement for HPH_L */ + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_MBHC_ZDET, 0x80, 0x80); + dev_dbg(rouleur->dev, "%s: ramp for HPH_L, noff = %d\n", + __func__, zdet_param->noff); + rouleur_mbhc_get_result_params(rouleur, d1_a, zdet_param->noff, &zdet); + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_MBHC_ZDET, 0x80, 0x00); + + *zl = zdet; + +z_right: + if (!zr) + return; + /* Start impedance measurement for HPH_R */ + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_MBHC_ZDET, 0x40, 0x40); + dev_dbg(rouleur->dev, "%s: ramp for HPH_R, noff = %d\n", + __func__, zdet_param->noff); + rouleur_mbhc_get_result_params(rouleur, d1_a, zdet_param->noff, &zdet); + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_MBHC_ZDET, 0x40, 0x00); + + *zr = zdet; +} + +static inline void rouleur_wcd_mbhc_qfuse_cal( + struct snd_soc_component *component, + int32_t *z_val, int flag_l_r) +{ + s16 q1; + int q1_cal; + + if (*z_val < (ROULEUR_ZDET_VAL_400/1000)) + q1 = snd_soc_component_read32(component, + ROULEUR_DIGITAL_EFUSE_REG_23 + (2 * flag_l_r)); + else + q1 = snd_soc_component_read32(component, + ROULEUR_DIGITAL_EFUSE_REG_24 + (2 * flag_l_r)); + if (q1 & 0x80) + q1_cal = (10000 - ((q1 & 0x7F) * 25)); + else + q1_cal = (10000 + (q1 * 25)); + if (q1_cal > 0) + *z_val = ((*z_val) * 10000) / q1_cal; +} + +static void rouleur_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, + uint32_t *zr) +{ + struct snd_soc_component *component = mbhc->component; + struct rouleur_priv *rouleur = dev_get_drvdata(component->dev); + s16 reg0, reg1, reg2, reg3, reg4; + int32_t z1L, z1R, z1Ls; + int zMono, z_diff1, z_diff2; + bool is_fsm_disable = false; + struct rouleur_mbhc_zdet_param zdet_param[] = { + {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */ + {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */ + {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */ + {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */ + }; + struct rouleur_mbhc_zdet_param *zdet_param_ptr = NULL; + s16 d1_a[][4] = { + {0, 30, 90, 30}, + {0, 30, 30, 5}, + {0, 30, 30, 5}, + {0, 30, 30, 5}, + }; + s16 *d1 = NULL; + + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + + reg0 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_BTN5); + reg1 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_BTN6); + reg2 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_BTN7); + reg3 = snd_soc_component_read32(component, ROULEUR_MBHC_CTL_CLK); + reg4 = snd_soc_component_read32(component, + ROULEUR_ANA_MBHC_ZDET_ANA_CTL); + + if (snd_soc_component_read32(component, ROULEUR_ANA_MBHC_ELECT) & + 0x80) { + is_fsm_disable = true; + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_MBHC_ELECT, 0x80, 0x00); + } + + /* For NO-jack, disable L_DET_EN before Z-det measurements */ + if (mbhc->hphl_swh) + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_MBHC_MECH, 0x80, 0x00); + + /* Turn off 100k pull down on HPHL */ + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_MBHC_MECH, 0x01, 0x00); + + /* Disable surge protection before impedance detection. + * This is done to give correct value for high impedance. + */ + regmap_update_bits(rouleur->regmap, + ROULEUR_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0x00); + /* 1ms delay needed after disable surge protection */ + usleep_range(1000, 1010); + + /* First get impedance on Left */ + d1 = d1_a[1]; + zdet_param_ptr = &zdet_param[1]; + rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1); + + if (!ROULEUR_MBHC_IS_SECOND_RAMP_REQUIRED(z1L)) + goto left_ch_impedance; + + /* Second ramp for left ch */ + if (z1L < ROULEUR_ZDET_VAL_32) { + zdet_param_ptr = &zdet_param[0]; + d1 = d1_a[0]; + } else if ((z1L > ROULEUR_ZDET_VAL_400) && + (z1L <= ROULEUR_ZDET_VAL_1200)) { + zdet_param_ptr = &zdet_param[2]; + d1 = d1_a[2]; + } else if (z1L > ROULEUR_ZDET_VAL_1200) { + zdet_param_ptr = &zdet_param[3]; + d1 = d1_a[3]; + } + rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1); + +left_ch_impedance: + if ((z1L == ROULEUR_ZDET_FLOATING_IMPEDANCE) || + (z1L > ROULEUR_ZDET_VAL_100K)) { + *zl = ROULEUR_ZDET_FLOATING_IMPEDANCE; + zdet_param_ptr = &zdet_param[1]; + d1 = d1_a[1]; + } else { + *zl = z1L/1000; + rouleur_wcd_mbhc_qfuse_cal(component, zl, 0); + } + dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n", + __func__, *zl); + + /* Start of right impedance ramp and calculation */ + rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1); + if (ROULEUR_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) { + if (((z1R > ROULEUR_ZDET_VAL_1200) && + (zdet_param_ptr->noff == 0x6)) || + ((*zl) != ROULEUR_ZDET_FLOATING_IMPEDANCE)) + goto right_ch_impedance; + /* Second ramp for right ch */ + if (z1R < ROULEUR_ZDET_VAL_32) { + zdet_param_ptr = &zdet_param[0]; + d1 = d1_a[0]; + } else if ((z1R > ROULEUR_ZDET_VAL_400) && + (z1R <= ROULEUR_ZDET_VAL_1200)) { + zdet_param_ptr = &zdet_param[2]; + d1 = d1_a[2]; + } else if (z1R > ROULEUR_ZDET_VAL_1200) { + zdet_param_ptr = &zdet_param[3]; + d1 = d1_a[3]; + } + rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, + &z1R, d1); + } +right_ch_impedance: + if ((z1R == ROULEUR_ZDET_FLOATING_IMPEDANCE) || + (z1R > ROULEUR_ZDET_VAL_100K)) { + *zr = ROULEUR_ZDET_FLOATING_IMPEDANCE; + } else { + *zr = z1R/1000; + rouleur_wcd_mbhc_qfuse_cal(component, zr, 1); + } + dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n", + __func__, *zr); + + /* Mono/stereo detection */ + if ((*zl == ROULEUR_ZDET_FLOATING_IMPEDANCE) && + (*zr == ROULEUR_ZDET_FLOATING_IMPEDANCE)) { + dev_dbg(component->dev, + "%s: plug type is invalid or extension cable\n", + __func__); + goto zdet_complete; + } + if ((*zl == ROULEUR_ZDET_FLOATING_IMPEDANCE) || + (*zr == ROULEUR_ZDET_FLOATING_IMPEDANCE) || + ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) || + ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) { + dev_dbg(component->dev, + "%s: Mono plug type with one ch floating or shorted to GND\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_MONO; + goto zdet_complete; + } + snd_soc_component_update_bits(component, ROULEUR_HPH_R_ATEST, + 0x02, 0x02); + snd_soc_component_update_bits(component, ROULEUR_HPH_PA_CTL2, + 0x40, 0x01); + if (*zl < (ROULEUR_ZDET_VAL_32/1000)) + rouleur_mbhc_zdet_ramp(component, &zdet_param[0], &z1Ls, + NULL, d1); + else + rouleur_mbhc_zdet_ramp(component, &zdet_param[1], &z1Ls, + NULL, d1); + snd_soc_component_update_bits(component, ROULEUR_HPH_PA_CTL2, + 0x40, 0x00); + snd_soc_component_update_bits(component, ROULEUR_HPH_R_ATEST, + 0x02, 0x00); + z1Ls /= 1000; + rouleur_wcd_mbhc_qfuse_cal(component, &z1Ls, 0); + /* Parallel of left Z and 9 ohm pull down resistor */ + zMono = ((*zl) * 9) / ((*zl) + 9); + z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls); + z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl)); + if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) { + dev_dbg(component->dev, "%s: stereo plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_STEREO; + } else { + dev_dbg(component->dev, "%s: MONO plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_MONO; + } + + /* Enable surge protection again after impedance detection */ + regmap_update_bits(rouleur->regmap, + ROULEUR_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0xC0); +zdet_complete: + snd_soc_component_write(component, ROULEUR_ANA_MBHC_BTN5, reg0); + snd_soc_component_write(component, ROULEUR_ANA_MBHC_BTN6, reg1); + snd_soc_component_write(component, ROULEUR_ANA_MBHC_BTN7, reg2); + /* Turn on 100k pull down on HPHL */ + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_MBHC_MECH, 0x01, 0x01); + + /* For NO-jack, re-enable L_DET_EN after Z-det measurements */ + if (mbhc->hphl_swh) + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_MBHC_MECH, 0x80, 0x80); + + snd_soc_component_write(component, ROULEUR_ANA_MBHC_ZDET_ANA_CTL, reg4); + snd_soc_component_write(component, ROULEUR_MBHC_CTL_CLK, reg3); + if (is_fsm_disable) + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_MBHC_ELECT, 0x80, 0x80); +} +#endif + +static void rouleur_mbhc_gnd_det_ctrl(struct snd_soc_component *component, + bool enable) +{ + if (enable) { + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_MECH, + 0x02, 0x02); + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_MECH, + 0x40, 0x40); + } else { + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_MECH, + 0x40, 0x00); + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_MECH, + 0x02, 0x00); + } +} + +static void rouleur_mbhc_hph_pull_down_ctrl(struct snd_soc_component *component, + bool enable) +{ + if (enable) { + snd_soc_component_update_bits(component, + ROULEUR_ANA_HPHPA_CNP_CTL_2, + 0x30, 0x10); + snd_soc_component_update_bits(component, + ROULEUR_ANA_HPHPA_CNP_CTL_2, + 0x0C, 0x04); + } else { + snd_soc_component_update_bits(component, + ROULEUR_ANA_HPHPA_CNP_CTL_2, + 0x30, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_ANA_HPHPA_CNP_CTL_2, + 0x0C, 0x00); + } +} + +static void rouleur_mbhc_moisture_config(struct wcd_mbhc *mbhc) +{ + struct snd_soc_component *component = mbhc->component; + + if ((mbhc->moist_rref == R_OFF) || + (mbhc->mbhc_cfg->enable_usbc_analog)) { + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_CTL_2, + 0x0C, R_OFF << 2); + return; + } + + /* Do not enable moisture detection if jack type is NC */ + if (!mbhc->hphl_swh) { + dev_dbg(component->dev, "%s: disable moisture detection for NC\n", + __func__); + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_CTL_2, + 0x0C, R_OFF << 2); + return; + } + + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_CTL_2, + 0x0C, mbhc->moist_rref << 2); +} + +static void rouleur_mbhc_moisture_detect_en(struct wcd_mbhc *mbhc, bool enable) +{ + struct snd_soc_component *component = mbhc->component; + + if (enable) + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_CTL_2, + 0x0C, mbhc->moist_rref << 2); + else + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_CTL_2, + 0x0C, R_OFF << 2); +} + +static bool rouleur_mbhc_get_moisture_status(struct wcd_mbhc *mbhc) +{ + struct snd_soc_component *component = mbhc->component; + bool ret = false; + + if ((mbhc->moist_rref == R_OFF) || + (mbhc->mbhc_cfg->enable_usbc_analog)) { + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_CTL_2, + 0x0C, R_OFF << 2); + goto done; + } + + /* Do not enable moisture detection if jack type is NC */ + if (!mbhc->hphl_swh) { + dev_dbg(component->dev, "%s: disable moisture detection for NC\n", + __func__); + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_CTL_2, + 0x0C, R_OFF << 2); + goto done; + } + + /* If moisture_en is already enabled, then skip to plug type + * detection. + */ + if ((snd_soc_component_read32(component, ROULEUR_ANA_MBHC_CTL_2) & + 0x0C)) + goto done; + + rouleur_mbhc_moisture_detect_en(mbhc, true); + /* Read moisture comparator status */ + ret = ((snd_soc_component_read32(component, ROULEUR_ANA_MBHC_FSM_STATUS) + & 0x20) ? 0 : 1); + +done: + return ret; + +} + +static void rouleur_mbhc_bcs_enable(struct wcd_mbhc *mbhc, + bool bcs_enable) +{ + if (bcs_enable) + rouleur_disable_bcs_before_slow_insert(mbhc->component, false); + else + rouleur_disable_bcs_before_slow_insert(mbhc->component, true); +} + +static const struct wcd_mbhc_cb mbhc_cb = { + .request_irq = rouleur_mbhc_request_irq, + .irq_control = rouleur_mbhc_irq_control, + .free_irq = rouleur_mbhc_free_irq, + .clk_setup = rouleur_mbhc_clk_setup, + .map_btn_code_to_num = rouleur_mbhc_btn_to_num, + .mbhc_bias = rouleur_mbhc_mbhc_bias_control, + .set_btn_thr = rouleur_mbhc_program_btn_thr, + .lock_sleep = rouleur_mbhc_lock_sleep, + .register_notifier = rouleur_mbhc_register_notifier, + .micbias_enable_status = rouleur_mbhc_micb_en_status, + .hph_pa_on_status = rouleur_mbhc_hph_pa_on_status, + .hph_pull_up_control = rouleur_mbhc_hph_l_pull_up_control, + .mbhc_micbias_control = rouleur_mbhc_request_micbias, + .mbhc_micb_ramp_control = rouleur_mbhc_micb_ramp_control, + .get_hwdep_fw_cal = rouleur_get_hwdep_fw_cal, + .mbhc_micb_ctrl_thr_mic = rouleur_mbhc_micb_ctrl_threshold_mic, + //.compute_impedance = rouleur_wcd_mbhc_calc_impedance, + .mbhc_gnd_det_ctrl = rouleur_mbhc_gnd_det_ctrl, + .hph_pull_down_ctrl = rouleur_mbhc_hph_pull_down_ctrl, + .mbhc_moisture_config = rouleur_mbhc_moisture_config, + .mbhc_get_moisture_status = rouleur_mbhc_get_moisture_status, + .mbhc_moisture_detect_en = rouleur_mbhc_moisture_detect_en, + .bcs_enable = rouleur_mbhc_bcs_enable, +}; + +static int rouleur_get_hph_type(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct rouleur_mbhc *rouleur_mbhc = rouleur_soc_get_mbhc(component); + struct wcd_mbhc *mbhc; + + if (!rouleur_mbhc) { + dev_err(component->dev, "%s: mbhc not initialized!\n", + __func__); + return -EINVAL; + } + + mbhc = &rouleur_mbhc->wcd_mbhc; + + ucontrol->value.integer.value[0] = (u32) mbhc->hph_type; + dev_dbg(component->dev, "%s: hph_type = %u\n", __func__, + mbhc->hph_type); + + return 0; +} + +static int rouleur_hph_impedance_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + uint32_t zl = 0, zr = 0; + bool hphr; + struct soc_multi_mixer_control *mc; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct rouleur_mbhc *rouleur_mbhc = rouleur_soc_get_mbhc(component); + + if (!rouleur_mbhc) { + dev_err(component->dev, "%s: mbhc not initialized!\n", + __func__); + return -EINVAL; + } + + mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); + hphr = mc->shift; + wcd_mbhc_get_impedance(&rouleur_mbhc->wcd_mbhc, &zl, &zr); + dev_dbg(component->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, + zl, zr); + ucontrol->value.integer.value[0] = hphr ? zr : zl; + + return 0; +} + +static const struct snd_kcontrol_new hph_type_detect_controls[] = { + SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0, + rouleur_get_hph_type, NULL), +}; + +static const struct snd_kcontrol_new impedance_detect_controls[] = { + SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0, + rouleur_hph_impedance_get, NULL), + SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0, + rouleur_hph_impedance_get, NULL), +}; + +/* + * rouleur_mbhc_get_impedance: get impedance of headphone + * left and right channels + * @rouleur_mbhc: handle to struct rouleur_mbhc * + * @zl: handle to left-ch impedance + * @zr: handle to right-ch impedance + * return 0 for success or error code in case of failure + */ +int rouleur_mbhc_get_impedance(struct rouleur_mbhc *rouleur_mbhc, + uint32_t *zl, uint32_t *zr) +{ + if (!rouleur_mbhc) { + pr_err("%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + if (!zl || !zr) { + pr_err("%s: zl or zr null!\n", __func__); + return -EINVAL; + } + + return wcd_mbhc_get_impedance(&rouleur_mbhc->wcd_mbhc, zl, zr); +} +EXPORT_SYMBOL(rouleur_mbhc_get_impedance); + +/* + * rouleur_mbhc_hs_detect: starts mbhc insertion/removal functionality + * @component: handle to snd_soc_component * + * @mbhc_cfg: handle to mbhc configuration structure + * return 0 if mbhc_start is success or error code in case of failure + */ +int rouleur_mbhc_hs_detect(struct snd_soc_component *component, + struct wcd_mbhc_config *mbhc_cfg) +{ + struct rouleur_priv *rouleur = NULL; + struct rouleur_mbhc *rouleur_mbhc = NULL; + + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + rouleur = snd_soc_component_get_drvdata(component); + if (!rouleur) { + pr_err("%s: rouleur is NULL\n", __func__); + return -EINVAL; + } + + rouleur_mbhc = rouleur->mbhc; + if (!rouleur_mbhc) { + dev_err(component->dev, "%s: mbhc not initialized!\n", + __func__); + return -EINVAL; + } + + return wcd_mbhc_start(&rouleur_mbhc->wcd_mbhc, mbhc_cfg); +} +EXPORT_SYMBOL(rouleur_mbhc_hs_detect); + +/* + * rouleur_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality + * @component: handle to snd_soc_component * + */ +void rouleur_mbhc_hs_detect_exit(struct snd_soc_component *component) +{ + struct rouleur_priv *rouleur = NULL; + struct rouleur_mbhc *rouleur_mbhc = NULL; + + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return; + } + + rouleur = snd_soc_component_get_drvdata(component); + if (!rouleur) { + pr_err("%s: rouleur is NULL\n", __func__); + return; + } + + rouleur_mbhc = rouleur->mbhc; + if (!rouleur_mbhc) { + dev_err(component->dev, "%s: mbhc not initialized!\n", + __func__); + return; + } + wcd_mbhc_stop(&rouleur_mbhc->wcd_mbhc); +} +EXPORT_SYMBOL(rouleur_mbhc_hs_detect_exit); + +/* + * rouleur_mbhc_ssr_down: stop mbhc during + * rouleur subsystem restart + * @mbhc: pointer to rouleur_mbhc structure + * @component: handle to snd_soc_component * + */ +void rouleur_mbhc_ssr_down(struct rouleur_mbhc *mbhc, + struct snd_soc_component *component) +{ + struct wcd_mbhc *wcd_mbhc = NULL; + + if (!mbhc || !component) + return; + + wcd_mbhc = &mbhc->wcd_mbhc; + if (wcd_mbhc == NULL) { + dev_err(component->dev, "%s: wcd_mbhc is NULL\n", __func__); + return; + } + + rouleur_mbhc_hs_detect_exit(component); + wcd_mbhc_deinit(wcd_mbhc); +} +EXPORT_SYMBOL(rouleur_mbhc_ssr_down); + +/* + * rouleur_mbhc_post_ssr_init: initialize mbhc for + * rouleur post subsystem restart + * @mbhc: poniter to rouleur_mbhc structure + * @component: handle to snd_soc_component * + * + * return 0 if mbhc_init is success or error code in case of failure + */ +int rouleur_mbhc_post_ssr_init(struct rouleur_mbhc *mbhc, + struct snd_soc_component *component) +{ + int ret = 0; + struct wcd_mbhc *wcd_mbhc = NULL; + + if (!mbhc || !component) + return -EINVAL; + + wcd_mbhc = &mbhc->wcd_mbhc; + if (wcd_mbhc == NULL) { + pr_err("%s: wcd_mbhc is NULL\n", __func__); + return -EINVAL; + } + + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_MECH, + 0x20, 0x20); + ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb, &intr_ids, + wcd_mbhc_registers, ROULEUR_ZDET_SUPPORTED); + if (ret) + dev_err(component->dev, "%s: mbhc initialization failed\n", + __func__); + + return ret; +} +EXPORT_SYMBOL(rouleur_mbhc_post_ssr_init); + +/* + * rouleur_mbhc_init: initialize mbhc for rouleur + * @mbhc: poniter to rouleur_mbhc struct pointer to store the configs + * @component: handle to snd_soc_component * + * @fw_data: handle to firmware data + * + * return 0 if mbhc_init is success or error code in case of failure + */ +int rouleur_mbhc_init(struct rouleur_mbhc **mbhc, + struct snd_soc_component *component, + struct fw_info *fw_data) +{ + struct rouleur_mbhc *rouleur_mbhc = NULL; + struct wcd_mbhc *wcd_mbhc = NULL; + struct rouleur_pdata *pdata; + int ret = 0; + + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + rouleur_mbhc = devm_kzalloc(component->dev, sizeof(struct rouleur_mbhc), + GFP_KERNEL); + if (!rouleur_mbhc) + return -ENOMEM; + + rouleur_mbhc->fw_data = fw_data; + BLOCKING_INIT_NOTIFIER_HEAD(&rouleur_mbhc->notifier); + wcd_mbhc = &rouleur_mbhc->wcd_mbhc; + if (wcd_mbhc == NULL) { + pr_err("%s: wcd_mbhc is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + + /* Setting default mbhc detection logic to ADC */ + wcd_mbhc->mbhc_detection_logic = WCD_DETECTION_ADC; + + pdata = dev_get_platdata(component->dev); + if (!pdata) { + dev_err(component->dev, "%s: pdata pointer is NULL\n", + __func__); + ret = -EINVAL; + goto err; + } + wcd_mbhc->micb_mv = pdata->micbias.micb2_mv; + + ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb, + &intr_ids, wcd_mbhc_registers, + ROULEUR_ZDET_SUPPORTED); + if (ret) { + dev_err(component->dev, "%s: mbhc initialization failed\n", + __func__); + goto err; + } + + (*mbhc) = rouleur_mbhc; + snd_soc_add_component_controls(component, impedance_detect_controls, + ARRAY_SIZE(impedance_detect_controls)); + snd_soc_add_component_controls(component, hph_type_detect_controls, + ARRAY_SIZE(hph_type_detect_controls)); + + return 0; +err: + devm_kfree(component->dev, rouleur_mbhc); + return ret; +} +EXPORT_SYMBOL(rouleur_mbhc_init); + +/* + * rouleur_mbhc_deinit: deinitialize mbhc for rouleur + * @component: handle to snd_soc_component * + */ +void rouleur_mbhc_deinit(struct snd_soc_component *component) +{ + struct rouleur_priv *rouleur; + struct rouleur_mbhc *rouleur_mbhc; + + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return; + } + + rouleur = snd_soc_component_get_drvdata(component); + if (!rouleur) { + pr_err("%s: rouleur is NULL\n", __func__); + return; + } + + rouleur_mbhc = rouleur->mbhc; + if (rouleur_mbhc) { + wcd_mbhc_deinit(&rouleur_mbhc->wcd_mbhc); + devm_kfree(component->dev, rouleur_mbhc); + } +} +EXPORT_SYMBOL(rouleur_mbhc_deinit); diff --git a/asoc/codecs/rouleur/rouleur-mbhc.h b/asoc/codecs/rouleur/rouleur-mbhc.h new file mode 100644 index 000000000000..40bef376ac7a --- /dev/null +++ b/asoc/codecs/rouleur/rouleur-mbhc.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ +#ifndef __ROULEUR_MBHC_H__ +#define __ROULEUR_MBHC_H__ +#include + +struct rouleur_mbhc { + struct wcd_mbhc wcd_mbhc; + struct blocking_notifier_head notifier; + struct fw_info *fw_data; +}; + +#if IS_ENABLED(CONFIG_SND_SOC_ROULEUR) +extern int rouleur_mbhc_init(struct rouleur_mbhc **mbhc, + struct snd_soc_component *component, + struct fw_info *fw_data); +extern void rouleur_mbhc_hs_detect_exit(struct snd_soc_component *component); +extern int rouleur_mbhc_hs_detect(struct snd_soc_component *component, + struct wcd_mbhc_config *mbhc_cfg); +extern void rouleur_mbhc_deinit(struct snd_soc_component *component); +extern int rouleur_mbhc_post_ssr_init(struct rouleur_mbhc *mbhc, + struct snd_soc_component *component); +extern void rouleur_mbhc_ssr_down(struct rouleur_mbhc *mbhc, + struct snd_soc_component *component); +extern int rouleur_mbhc_get_impedance(struct rouleur_mbhc *rouleur_mbhc, + uint32_t *zl, uint32_t *zr); +#else +static inline int rouleur_mbhc_init(struct rouleur_mbhc **mbhc, + struct snd_soc_component *component, + struct fw_info *fw_data) +{ + return 0; +} +static inline void rouleur_mbhc_hs_detect_exit( + struct snd_soc_component *component) +{ +} +static inline int rouleur_mbhc_hs_detect(struct snd_soc_component *component, + struct wcd_mbhc_config *mbhc_cfg) +{ + return 0; +} +static inline void rouleur_mbhc_deinit(struct snd_soc_component *component) +{ +} +static inline int rouleur_mbhc_post_ssr_init(struct rouleur_mbhc *mbhc, + struct snd_soc_component *component) +{ + return 0; +} +static inline void rouleur_mbhc_ssr_down(struct rouleur_mbhc *mbhc, + struct snd_soc_component *component) +{ +} +static inline int rouleur_mbhc_get_impedance(struct rouleur_mbhc *rouleur_mbhc, + uint32_t *zl, uint32_t *zr) +{ + if (zl) + *zl = 0; + if (zr) + *zr = 0; + return -EINVAL; +} +#endif + +#endif /* __ROULEUR_MBHC_H__ */ diff --git a/asoc/codecs/rouleur/rouleur-registers.h b/asoc/codecs/rouleur/rouleur-registers.h new file mode 100644 index 000000000000..ff3934bb236d --- /dev/null +++ b/asoc/codecs/rouleur/rouleur-registers.h @@ -0,0 +1,121 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _ROULEUR_REGISTERS_H +#define _ROULEUR_REGISTERS_H + +#define ROULEUR_ANA_BASE_ADDR 0x3000 +#define ROULEUR_DIG_BASE_ADDR 0x3400 + +#define ROULEUR_REG(reg) ((reg > ROULEUR_DIG_BASE_ADDR) ? \ + (reg - ROULEUR_DIG_BASE_ADDR) : \ + (reg - ROULEUR_ANA_BASE_ADDR)) + +enum { + REG_NO_ACCESS, + RD_REG, + WR_REG, + RD_WR_REG +}; + +#define ROULEUR_ANA_MICBIAS_MICB_1_2_EN (ROULEUR_ANA_BASE_ADDR+0x040) +#define ROULEUR_ANA_MICBIAS_MICB_3_EN (ROULEUR_ANA_BASE_ADDR+0x041) +#define ROULEUR_ANA_MICBIAS_LDO_1_SETTING (ROULEUR_ANA_BASE_ADDR+0x042) +#define ROULEUR_ANA_MICBIAS_LDO_1_CTRL (ROULEUR_ANA_BASE_ADDR+0x043) +#define ROULEUR_ANA_TX_AMIC1 (ROULEUR_ANA_BASE_ADDR+0x047) +#define ROULEUR_ANA_TX_AMIC2 (ROULEUR_ANA_BASE_ADDR+0x048) +#define ROULEUR_ANA_MBHC_MECH (ROULEUR_ANA_BASE_ADDR+0x05A) +#define ROULEUR_ANA_MBHC_ELECT (ROULEUR_ANA_BASE_ADDR+0x05B) +#define ROULEUR_ANA_MBHC_ZDET (ROULEUR_ANA_BASE_ADDR+0x05C) +#define ROULEUR_ANA_MBHC_RESULT_1 (ROULEUR_ANA_BASE_ADDR+0x05D) +#define ROULEUR_ANA_MBHC_RESULT_2 (ROULEUR_ANA_BASE_ADDR+0x05E) +#define ROULEUR_ANA_MBHC_RESULT_3 (ROULEUR_ANA_BASE_ADDR+0x05F) +#define ROULEUR_ANA_MBHC_BTN0_ZDET_VREF1 (ROULEUR_ANA_BASE_ADDR+0x060) +#define ROULEUR_ANA_MBHC_BTN1_ZDET_VREF2 (ROULEUR_ANA_BASE_ADDR+0x061) +#define ROULEUR_ANA_MBHC_BTN2_ZDET_VREF3 (ROULEUR_ANA_BASE_ADDR+0x062) +#define ROULEUR_ANA_MBHC_BTN3_ZDET_DBG_400 (ROULEUR_ANA_BASE_ADDR+0x063) +#define ROULEUR_ANA_MBHC_BTN4_ZDET_DBG_1400 (ROULEUR_ANA_BASE_ADDR+0x064) +#define ROULEUR_ANA_MBHC_MICB2_RAMP (ROULEUR_ANA_BASE_ADDR+0x065) +#define ROULEUR_ANA_MBHC_CTL_1 (ROULEUR_ANA_BASE_ADDR+0x066) +#define ROULEUR_ANA_MBHC_CTL_2 (ROULEUR_ANA_BASE_ADDR+0x067) +#define ROULEUR_ANA_MBHC_PLUG_DETECT_CTL (ROULEUR_ANA_BASE_ADDR+0x068) +#define ROULEUR_ANA_MBHC_ZDET_ANA_CTL (ROULEUR_ANA_BASE_ADDR+0x069) +#define ROULEUR_ANA_MBHC_ZDET_RAMP_CTL (ROULEUR_ANA_BASE_ADDR+0x06A) +#define ROULEUR_ANA_MBHC_FSM_STATUS (ROULEUR_ANA_BASE_ADDR+0x06B) +#define ROULEUR_ANA_MBHC_ADC_RESULT (ROULEUR_ANA_BASE_ADDR+0x06C) +#define ROULEUR_ANA_MBHC_MCLK (ROULEUR_ANA_BASE_ADDR+0x06D) +#define ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT (ROULEUR_ANA_BASE_ADDR+0x072) +#define ROULEUR_ANA_NCP_EN (ROULEUR_ANA_BASE_ADDR+0x077) +#define ROULEUR_ANA_HPHPA_CNP_CTL_2 (ROULEUR_ANA_BASE_ADDR+0x084) +#define ROULEUR_ANA_HPHPA_PA_STATUS (ROULEUR_ANA_BASE_ADDR+0x087) +#define ROULEUR_ANA_HPHPA_FSM_CLK (ROULEUR_ANA_BASE_ADDR+0x088) +#define ROULEUR_ANA_HPHPA_L_GAIN (ROULEUR_ANA_BASE_ADDR+0x08B) +#define ROULEUR_ANA_HPHPA_R_GAIN (ROULEUR_ANA_BASE_ADDR+0x08C) +#define ROULEUR_ANA_HPHPA_SPARE_CTL (ROULEUR_ANA_BASE_ADDR+0x08E) +#define ROULEUR_ANA_SURGE_EN (ROULEUR_ANA_BASE_ADDR+0x097) +#define ROULEUR_ANA_COMBOPA_CTL (ROULEUR_ANA_BASE_ADDR+0x09B) +#define ROULEUR_ANA_RXLDO_CTL (ROULEUR_ANA_BASE_ADDR+0x0B2) +#define ROULEUR_ANA_MBIAS_EN (ROULEUR_ANA_BASE_ADDR+0x0B4) + +#define ROULEUR_DIG_SWR_CHIP_ID0 (ROULEUR_DIG_BASE_ADDR+0x001) +#define ROULEUR_DIG_SWR_CHIP_ID1 (ROULEUR_DIG_BASE_ADDR+0x002) +#define ROULEUR_DIG_SWR_CHIP_ID2 (ROULEUR_DIG_BASE_ADDR+0x003) +#define ROULEUR_DIG_SWR_CHIP_ID3 (ROULEUR_DIG_BASE_ADDR+0x004) +#define ROULEUR_DIG_SWR_SWR_TX_CLK_RATE (ROULEUR_DIG_BASE_ADDR+0x040) +#define ROULEUR_DIG_SWR_CDC_RST_CTL (ROULEUR_DIG_BASE_ADDR+0x041) +#define ROULEUR_DIG_SWR_TOP_CLK_CFG (ROULEUR_DIG_BASE_ADDR+0x042) +#define ROULEUR_DIG_SWR_CDC_RX_CLK_CTL (ROULEUR_DIG_BASE_ADDR+0x043) +#define ROULEUR_DIG_SWR_CDC_TX_CLK_CTL (ROULEUR_DIG_BASE_ADDR+0x044) +#define ROULEUR_DIG_SWR_SWR_RST_EN (ROULEUR_DIG_BASE_ADDR+0x045) +#define ROULEUR_DIG_SWR_CDC_RX_RST (ROULEUR_DIG_BASE_ADDR+0x047) +#define ROULEUR_DIG_SWR_CDC_RX0_CTL (ROULEUR_DIG_BASE_ADDR+0x048) +#define ROULEUR_DIG_SWR_CDC_RX1_CTL (ROULEUR_DIG_BASE_ADDR+0x049) +#define ROULEUR_DIG_SWR_CDC_TX_ANA_MODE_0_1 (ROULEUR_DIG_BASE_ADDR+0x04B) +#define ROULEUR_DIG_SWR_CDC_COMP_CTL_0 (ROULEUR_DIG_BASE_ADDR+0x04F) +#define ROULEUR_DIG_SWR_CDC_RX_DELAY_CTL (ROULEUR_DIG_BASE_ADDR+0x052) +#define ROULEUR_DIG_SWR_CDC_RX_GAIN_0 (ROULEUR_DIG_BASE_ADDR+0x053) +#define ROULEUR_DIG_SWR_CDC_RX_GAIN_1 (ROULEUR_DIG_BASE_ADDR+0x054) +#define ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL (ROULEUR_DIG_BASE_ADDR+0x057) +#define ROULEUR_DIG_SWR_CDC_TX0_CTL (ROULEUR_DIG_BASE_ADDR+0x060) +#define ROULEUR_DIG_SWR_CDC_TX1_CTL (ROULEUR_DIG_BASE_ADDR+0x061) +#define ROULEUR_DIG_SWR_CDC_TX_RST (ROULEUR_DIG_BASE_ADDR+0x063) +#define ROULEUR_DIG_SWR_CDC_REQ0_CTL (ROULEUR_DIG_BASE_ADDR+0x064) +#define ROULEUR_DIG_SWR_CDC_REQ1_CTL (ROULEUR_DIG_BASE_ADDR+0x065) +#define ROULEUR_DIG_SWR_CDC_RST (ROULEUR_DIG_BASE_ADDR+0x067) +#define ROULEUR_DIG_SWR_CDC_AMIC_CTL (ROULEUR_DIG_BASE_ADDR+0x06A) +#define ROULEUR_DIG_SWR_CDC_DMIC_CTL (ROULEUR_DIG_BASE_ADDR+0x06B) +#define ROULEUR_DIG_SWR_CDC_DMIC1_CTL (ROULEUR_DIG_BASE_ADDR+0x06C) +#define ROULEUR_DIG_SWR_CDC_DMIC1_RATE (ROULEUR_DIG_BASE_ADDR+0x06D) +#define ROULEUR_DIG_SWR_PDM_WD_CTL0 (ROULEUR_DIG_BASE_ADDR+0x070) +#define ROULEUR_DIG_SWR_PDM_WD_CTL1 (ROULEUR_DIG_BASE_ADDR+0x071) +#define ROULEUR_DIG_SWR_INTR_MODE (ROULEUR_DIG_BASE_ADDR+0x080) +#define ROULEUR_DIG_SWR_INTR_MASK_0 (ROULEUR_DIG_BASE_ADDR+0x081) +#define ROULEUR_DIG_SWR_INTR_MASK_1 (ROULEUR_DIG_BASE_ADDR+0x082) +#define ROULEUR_DIG_SWR_INTR_MASK_2 (ROULEUR_DIG_BASE_ADDR+0x083) +#define ROULEUR_DIG_SWR_INTR_STATUS_0 (ROULEUR_DIG_BASE_ADDR+0x084) +#define ROULEUR_DIG_SWR_INTR_STATUS_1 (ROULEUR_DIG_BASE_ADDR+0x085) +#define ROULEUR_DIG_SWR_INTR_STATUS_2 (ROULEUR_DIG_BASE_ADDR+0x086) +#define ROULEUR_DIG_SWR_INTR_CLEAR_0 (ROULEUR_DIG_BASE_ADDR+0x087) +#define ROULEUR_DIG_SWR_INTR_CLEAR_1 (ROULEUR_DIG_BASE_ADDR+0x088) +#define ROULEUR_DIG_SWR_INTR_CLEAR_2 (ROULEUR_DIG_BASE_ADDR+0x089) +#define ROULEUR_DIG_SWR_INTR_LEVEL_0 (ROULEUR_DIG_BASE_ADDR+0x08A) +#define ROULEUR_DIG_SWR_INTR_LEVEL_1 (ROULEUR_DIG_BASE_ADDR+0x08B) +#define ROULEUR_DIG_SWR_INTR_LEVEL_2 (ROULEUR_DIG_BASE_ADDR+0x08C) +#define ROULEUR_DIG_SWR_CDC_CONN_RX0_CTL (ROULEUR_DIG_BASE_ADDR+0x093) +#define ROULEUR_DIG_SWR_CDC_CONN_RX1_CTL (ROULEUR_DIG_BASE_ADDR+0x094) +#define ROULEUR_DIG_SWR_LOOP_BACK_MODE (ROULEUR_DIG_BASE_ADDR+0x097) +#define ROULEUR_DIG_SWR_DRIVE_STRENGTH_0 (ROULEUR_DIG_BASE_ADDR+0x0A0) +#define ROULEUR_DIG_SWR_DIG_DEBUG_CTL (ROULEUR_DIG_BASE_ADDR+0x0AB) +#define ROULEUR_DIG_SWR_DIG_DEBUG_EN (ROULEUR_DIG_BASE_ADDR+0x0AC) +#define ROULEUR_DIG_SWR_DEM_BYPASS_DATA0 (ROULEUR_DIG_BASE_ADDR+0x0B0) +#define ROULEUR_DIG_SWR_DEM_BYPASS_DATA1 (ROULEUR_DIG_BASE_ADDR+0x0B1) +#define ROULEUR_DIG_SWR_DEM_BYPASS_DATA2 (ROULEUR_DIG_BASE_ADDR+0x0B2) +#define ROULEUR_DIG_SWR_DEM_BYPASS_DATA3 (ROULEUR_DIG_BASE_ADDR+0x0B3) + +#define ROULEUR_ANALOG_REGISTERS_MAX_SIZE (ROULEUR_ANA_BASE_ADDR+0x0B5) +#define ROULEUR_DIGITAL_REGISTERS_MAX_SIZE (ROULEUR_DIG_BASE_ADDR+0x0B4) +#define ROULEUR_ANALOG_MAX_REGISTER (ROULEUR_ANALOG_REGISTERS_MAX_SIZE - 1) +#define ROULEUR_DIGITAL_MAX_REGISTER (ROULEUR_DIGITAL_REGISTERS_MAX_SIZE - 1) +#endif diff --git a/asoc/codecs/rouleur/rouleur-regmap.c b/asoc/codecs/rouleur/rouleur-regmap.c new file mode 100644 index 000000000000..62502140ee99 --- /dev/null +++ b/asoc/codecs/rouleur/rouleur-regmap.c @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include "rouleur-registers.h" + +extern const u8 rouleur_reg_access_analog[ + ROULEUR_REG(ROULEUR_ANALOG_REGISTERS_MAX_SIZE)]; +extern const u8 rouleur_reg_access_digital[ + ROULEUR_REG(ROULEUR_DIGITAL_REGISTERS_MAX_SIZE)]; + +static const struct reg_default rouleur_defaults[] = { + { ROULEUR_ANA_MICBIAS_MICB_1_2_EN, 0x01 }, + { ROULEUR_ANA_MICBIAS_MICB_3_EN, 0x00 }, + { ROULEUR_ANA_MICBIAS_LDO_1_SETTING, 0x21 }, + { ROULEUR_ANA_MICBIAS_LDO_1_CTRL, 0x01 }, + { ROULEUR_ANA_TX_AMIC1, 0x00 }, + { ROULEUR_ANA_TX_AMIC2, 0x00 }, + { ROULEUR_ANA_MBHC_MECH, 0x39 }, + { ROULEUR_ANA_MBHC_ELECT, 0x08 }, + { ROULEUR_ANA_MBHC_ZDET, 0x10 }, + { ROULEUR_ANA_MBHC_RESULT_1, 0x00 }, + { ROULEUR_ANA_MBHC_RESULT_2, 0x00 }, + { ROULEUR_ANA_MBHC_RESULT_3, 0x00 }, + { ROULEUR_ANA_MBHC_BTN0_ZDET_VREF1, 0x00 }, + { ROULEUR_ANA_MBHC_BTN1_ZDET_VREF2, 0x10 }, + { ROULEUR_ANA_MBHC_BTN2_ZDET_VREF3, 0x20 }, + { ROULEUR_ANA_MBHC_BTN3_ZDET_DBG_400, 0x30 }, + { ROULEUR_ANA_MBHC_BTN4_ZDET_DBG_1400, 0x40 }, + { ROULEUR_ANA_MBHC_MICB2_RAMP, 0x00 }, + { ROULEUR_ANA_MBHC_CTL_1, 0x02 }, + { ROULEUR_ANA_MBHC_CTL_2, 0x05 }, + { ROULEUR_ANA_MBHC_PLUG_DETECT_CTL, 0xE9 }, + { ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x0F }, + { ROULEUR_ANA_MBHC_ZDET_RAMP_CTL, 0x00 }, + { ROULEUR_ANA_MBHC_FSM_STATUS, 0x00 }, + { ROULEUR_ANA_MBHC_ADC_RESULT, 0x00 }, + { ROULEUR_ANA_MBHC_MCLK, 0x30 }, + { ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT, 0x00 }, + { ROULEUR_ANA_NCP_EN, 0x00 }, + { ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x2B }, + { ROULEUR_ANA_HPHPA_PA_STATUS, 0x00 }, + { ROULEUR_ANA_HPHPA_FSM_CLK, 0x12 }, + { ROULEUR_ANA_HPHPA_SPARE_CTL, 0x02 }, + { ROULEUR_ANA_SURGE_EN, 0x38 }, + { ROULEUR_ANA_COMBOPA_CTL, 0x35 }, + { ROULEUR_ANA_RXLDO_CTL, 0x86 }, + { ROULEUR_ANA_MBIAS_EN, 0x00 }, + { ROULEUR_DIG_SWR_CHIP_ID0, 0x00 }, + { ROULEUR_DIG_SWR_CHIP_ID1, 0x00 }, + { ROULEUR_DIG_SWR_CHIP_ID2, 0x0C }, + { ROULEUR_DIG_SWR_CHIP_ID3, 0x01 }, + { ROULEUR_DIG_SWR_SWR_TX_CLK_RATE, 0x00 }, + { ROULEUR_DIG_SWR_CDC_RST_CTL, 0x03 }, + { ROULEUR_DIG_SWR_TOP_CLK_CFG, 0x00 }, + { ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x00 }, + { ROULEUR_DIG_SWR_CDC_TX_CLK_CTL, 0x33 }, + { ROULEUR_DIG_SWR_SWR_RST_EN, 0x00 }, + { ROULEUR_DIG_SWR_CDC_RX_RST, 0x00 }, + { ROULEUR_DIG_SWR_CDC_RX0_CTL, 0xFC }, + { ROULEUR_DIG_SWR_CDC_RX1_CTL, 0xFC }, + { ROULEUR_DIG_SWR_CDC_TX_ANA_MODE_0_1, 0x00 }, + { ROULEUR_DIG_SWR_CDC_COMP_CTL_0, 0x00 }, + { ROULEUR_DIG_SWR_CDC_RX_DELAY_CTL, 0x66 }, + { ROULEUR_DIG_SWR_CDC_RX_GAIN_0, 0x55 }, + { ROULEUR_DIG_SWR_CDC_RX_GAIN_1, 0xA9 }, + { ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, 0x00 }, + { ROULEUR_DIG_SWR_CDC_TX0_CTL, 0x68 }, + { ROULEUR_DIG_SWR_CDC_TX1_CTL, 0x68 }, + { ROULEUR_DIG_SWR_CDC_TX_RST, 0x00 }, + { ROULEUR_DIG_SWR_CDC_REQ0_CTL, 0x01 }, + { ROULEUR_DIG_SWR_CDC_REQ1_CTL, 0x01 }, + { ROULEUR_DIG_SWR_CDC_RST, 0x00 }, + { ROULEUR_DIG_SWR_CDC_AMIC_CTL, 0x02 }, + { ROULEUR_DIG_SWR_CDC_DMIC_CTL, 0x00 }, + { ROULEUR_DIG_SWR_CDC_DMIC1_CTL, 0x00 }, + { ROULEUR_DIG_SWR_CDC_DMIC1_RATE, 0x01 }, + { ROULEUR_DIG_SWR_PDM_WD_CTL0, 0x00 }, + { ROULEUR_DIG_SWR_PDM_WD_CTL1, 0x00 }, + { ROULEUR_DIG_SWR_INTR_MODE, 0x00 }, + { ROULEUR_DIG_SWR_INTR_MASK_0, 0xFF }, + { ROULEUR_DIG_SWR_INTR_MASK_1, 0x7F }, + { ROULEUR_DIG_SWR_INTR_MASK_2, 0x0C }, + { ROULEUR_DIG_SWR_INTR_STATUS_0, 0x00 }, + { ROULEUR_DIG_SWR_INTR_STATUS_1, 0x00 }, + { ROULEUR_DIG_SWR_INTR_STATUS_2, 0x00 }, + { ROULEUR_DIG_SWR_INTR_CLEAR_0, 0x00 }, + { ROULEUR_DIG_SWR_INTR_CLEAR_1, 0x00 }, + { ROULEUR_DIG_SWR_INTR_CLEAR_2, 0x00 }, + { ROULEUR_DIG_SWR_INTR_LEVEL_0, 0x00 }, + { ROULEUR_DIG_SWR_INTR_LEVEL_1, 0x2A }, + { ROULEUR_DIG_SWR_INTR_LEVEL_2, 0x00 }, + { ROULEUR_DIG_SWR_CDC_CONN_RX0_CTL, 0x00 }, + { ROULEUR_DIG_SWR_CDC_CONN_RX1_CTL, 0x00 }, + { ROULEUR_DIG_SWR_LOOP_BACK_MODE, 0x00 }, + { ROULEUR_DIG_SWR_DRIVE_STRENGTH_0, 0x00 }, + { ROULEUR_DIG_SWR_DIG_DEBUG_CTL, 0x00 }, + { ROULEUR_DIG_SWR_DIG_DEBUG_EN, 0x00 }, + { ROULEUR_DIG_SWR_DEM_BYPASS_DATA0, 0x55 }, + { ROULEUR_DIG_SWR_DEM_BYPASS_DATA1, 0x55 }, + { ROULEUR_DIG_SWR_DEM_BYPASS_DATA2, 0x55 }, + { ROULEUR_DIG_SWR_DEM_BYPASS_DATA3, 0x01 }, +}; + +static bool rouleur_readable_register(struct device *dev, unsigned int reg) +{ + if (reg > ROULEUR_ANA_BASE_ADDR && reg < + ROULEUR_ANALOG_REGISTERS_MAX_SIZE) + return rouleur_reg_access_analog[ROULEUR_REG(reg)] & RD_REG; + if (reg > ROULEUR_DIG_BASE_ADDR && reg < + ROULEUR_DIGITAL_REGISTERS_MAX_SIZE) + return rouleur_reg_access_digital[ROULEUR_REG(reg)] & RD_REG; + return 0; +} + +static bool rouleur_writeable_register(struct device *dev, unsigned int reg) +{ + if (reg > ROULEUR_ANA_BASE_ADDR && reg < + ROULEUR_ANALOG_REGISTERS_MAX_SIZE) + return rouleur_reg_access_analog[ROULEUR_REG(reg)] & WR_REG; + if (reg > ROULEUR_DIG_BASE_ADDR && reg < + ROULEUR_DIGITAL_REGISTERS_MAX_SIZE) + return rouleur_reg_access_digital[ROULEUR_REG(reg)] & WR_REG; + return 0; +} + +static bool rouleur_volatile_register(struct device *dev, unsigned int reg) +{ + if (reg > ROULEUR_ANA_BASE_ADDR && reg < + ROULEUR_ANALOG_REGISTERS_MAX_SIZE) + if ((rouleur_reg_access_analog[ROULEUR_REG(reg)] & RD_REG) + && !(rouleur_reg_access_analog[ROULEUR_REG(reg)] & WR_REG)) + return true; + return false; + if (reg > ROULEUR_DIG_BASE_ADDR && reg < + ROULEUR_DIGITAL_REGISTERS_MAX_SIZE) + if ((rouleur_reg_access_digital[ROULEUR_REG(reg)] & RD_REG) + && !(rouleur_reg_access_digital[ROULEUR_REG(reg)] & WR_REG)) + return true; + return false; + return 0; +} + +struct regmap_config rouleur_regmap_config = { + .name = "rouleur_csr", + .reg_bits = 16, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = rouleur_defaults, + .num_reg_defaults = ARRAY_SIZE(rouleur_defaults), + .max_register = ROULEUR_ANALOG_MAX_REGISTER + + ROULEUR_DIGITAL_MAX_REGISTER, + .readable_reg = rouleur_readable_register, + .writeable_reg = rouleur_writeable_register, + .volatile_reg = rouleur_volatile_register, + .can_multi_write = true, +}; diff --git a/asoc/codecs/rouleur/rouleur-tables.c b/asoc/codecs/rouleur/rouleur-tables.c new file mode 100644 index 000000000000..ea710ebb3a5c --- /dev/null +++ b/asoc/codecs/rouleur/rouleur-tables.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include "rouleur-registers.h" + +const u8 rouleur_reg_access_analog[ROULEUR_REG( + ROULEUR_ANALOG_REGISTERS_MAX_SIZE)] = { + [ROULEUR_REG(ROULEUR_ANA_MICBIAS_MICB_1_2_EN)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MICBIAS_MICB_3_EN)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MICBIAS_LDO_1_SETTING)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MICBIAS_LDO_1_CTRL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_TX_AMIC1)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_TX_AMIC2)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_MECH)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_ELECT)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_RESULT_1)] = RD_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_RESULT_2)] = RD_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_RESULT_3)] = RD_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_BTN0_ZDET_VREF1)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_BTN1_ZDET_VREF2)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_BTN2_ZDET_VREF3)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_BTN3_ZDET_DBG_400)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_BTN4_ZDET_DBG_1400)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_MICB2_RAMP)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_CTL_1)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_CTL_2)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_PLUG_DETECT_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET_ANA_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET_RAMP_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_FSM_STATUS)] = RD_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_ADC_RESULT)] = RD_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_MCLK)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT)] = RD_REG, + [ROULEUR_REG(ROULEUR_ANA_NCP_EN)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_HPHPA_CNP_CTL_2)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_HPHPA_PA_STATUS)] = RD_REG, + [ROULEUR_REG(ROULEUR_ANA_HPHPA_FSM_CLK)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_HPHPA_SPARE_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_SURGE_EN)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_COMBOPA_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_RXLDO_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBIAS_EN)] = RD_WR_REG, +}; + +const u8 rouleur_reg_access_digital[ROULEUR_REG( + ROULEUR_DIGITAL_REGISTERS_MAX_SIZE)] = { + [ROULEUR_REG(ROULEUR_DIG_SWR_CHIP_ID0)] = RD_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CHIP_ID1)] = RD_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CHIP_ID2)] = RD_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CHIP_ID3)] = RD_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_SWR_TX_CLK_RATE)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_RST_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_TOP_CLK_CFG)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_RX_CLK_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_TX_CLK_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_SWR_RST_EN)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_RX_RST)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_RX0_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_RX1_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_TX_ANA_MODE_0_1)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_COMP_CTL_0)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_RX_DELAY_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_RX_GAIN_0)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_RX_GAIN_1)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_TX0_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_TX1_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_TX_RST)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_REQ0_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_REQ1_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_RST)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_AMIC_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_DMIC_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_DMIC1_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_DMIC1_RATE)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_PDM_WD_CTL0)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_PDM_WD_CTL1)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_INTR_MODE)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_INTR_MASK_0)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_INTR_MASK_1)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_INTR_MASK_2)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_INTR_STATUS_0)] = RD_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_INTR_STATUS_1)] = RD_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_INTR_STATUS_2)] = RD_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_INTR_CLEAR_0)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_INTR_CLEAR_1)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_INTR_CLEAR_2)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_INTR_LEVEL_0)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_INTR_LEVEL_1)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_INTR_LEVEL_2)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_CONN_RX0_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_CDC_CONN_RX1_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_LOOP_BACK_MODE)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_DRIVE_STRENGTH_0)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_DIG_DEBUG_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_DIG_DEBUG_EN)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_DEM_BYPASS_DATA0)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_DEM_BYPASS_DATA1)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_DEM_BYPASS_DATA2)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_DIG_SWR_DEM_BYPASS_DATA3)] = RD_WR_REG, +}; diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c new file mode 100644 index 000000000000..14dfd52f49fb --- /dev/null +++ b/asoc/codecs/rouleur/rouleur.c @@ -0,0 +1,2492 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal.h" +#include "rouleur.h" +#include +#include "rouleur-registers.h" +#include "pm2250-spmi.h" +#include +#include +#include + +#define DRV_NAME "rouleur_codec" + +#define NUM_SWRS_DT_PARAMS 5 + +#define ROULEUR_VERSION_1_0 1 +#define ROULEUR_VERSION_ENTRY_SIZE 32 + +#define NUM_ATTEMPTS 5 + +enum { + CODEC_TX = 0, + CODEC_RX, +}; + +enum { + ALLOW_VPOS_DISABLE, + HPH_COMP_DELAY, + HPH_PA_DELAY, + AMIC2_BCS_ENABLE, +}; + +/* TODO: Check on the step values */ +static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); +static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); + +static int rouleur_handle_post_irq(void *data); +static int rouleur_reset(struct device *dev, int val); + +static const struct regmap_irq ROULEUR_IRQs[ROULEUR_NUM_IRQS] = { + REGMAP_IRQ_REG(ROULEUR_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x01), + REGMAP_IRQ_REG(ROULEUR_IRQ_MBHC_BUTTON_RELEASE_DET, 0, 0x02), + REGMAP_IRQ_REG(ROULEUR_IRQ_MBHC_ELECT_INS_REM_DET, 0, 0x04), + REGMAP_IRQ_REG(ROULEUR_IRQ_MBHC_ELECT_INS_REM_LEG_DET, 0, 0x08), + REGMAP_IRQ_REG(ROULEUR_IRQ_MBHC_SW_DET, 0, 0x10), + REGMAP_IRQ_REG(ROULEUR_IRQ_HPHR_OCP_INT, 0, 0x20), + REGMAP_IRQ_REG(ROULEUR_IRQ_HPHR_CNP_INT, 0, 0x40), + REGMAP_IRQ_REG(ROULEUR_IRQ_HPHL_OCP_INT, 0, 0x80), + REGMAP_IRQ_REG(ROULEUR_IRQ_HPHL_CNP_INT, 1, 0x01), + REGMAP_IRQ_REG(ROULEUR_IRQ_EAR_CNP_INT, 1, 0x02), + REGMAP_IRQ_REG(ROULEUR_IRQ_EAR_OCP_INT, 1, 0x04), + REGMAP_IRQ_REG(ROULEUR_IRQ_LO_CNP_INT, 1, 0x08), + REGMAP_IRQ_REG(ROULEUR_IRQ_LO_OCP_INT, 1, 0x10), + REGMAP_IRQ_REG(ROULEUR_IRQ_HPHL_PDM_WD_INT, 1, 0x20), + REGMAP_IRQ_REG(ROULEUR_IRQ_HPHR_PDM_WD_INT, 1, 0x40), + REGMAP_IRQ_REG(ROULEUR_IRQ_HPHL_SURGE_DET_INT, 2, 0x04), + REGMAP_IRQ_REG(ROULEUR_IRQ_HPHR_SURGE_DET_INT, 2, 0x08), +}; + +static struct regmap_irq_chip rouleur_regmap_irq_chip = { + .name = "rouleur", + .irqs = ROULEUR_IRQs, + .num_irqs = ARRAY_SIZE(ROULEUR_IRQs), + .num_regs = 3, + .status_base = ROULEUR_DIG_SWR_INTR_STATUS_0, + .mask_base = ROULEUR_DIG_SWR_INTR_MASK_0, + .ack_base = ROULEUR_DIG_SWR_INTR_CLEAR_0, + .use_ack = 1, + .type_base = ROULEUR_DIG_SWR_INTR_LEVEL_0, + .runtime_pm = false, + .handle_post_irq = rouleur_handle_post_irq, + .irq_drv_data = NULL, +}; + +static int rouleur_handle_post_irq(void *data) +{ + struct rouleur_priv *rouleur = data; + u32 status1 = 0, status2 = 0, status3 = 0; + + regmap_read(rouleur->regmap, ROULEUR_DIG_SWR_INTR_STATUS_0, &status1); + regmap_read(rouleur->regmap, ROULEUR_DIG_SWR_INTR_STATUS_1, &status2); + regmap_read(rouleur->regmap, ROULEUR_DIG_SWR_INTR_STATUS_2, &status3); + + rouleur->tx_swr_dev->slave_irq_pending = + ((status1 || status2 || status3) ? true : false); + + return IRQ_HANDLED; +} + +static int rouleur_init_reg(struct snd_soc_component *component) +{ + /* Enable surge protection */ + snd_soc_component_update_bits(component, ROULEUR_ANA_SURGE_EN, + 0xC0, 0xC0); + return 0; +} + +static int rouleur_set_port_params(struct snd_soc_component *component, + u8 slv_prt_type, u8 *port_id, u8 *num_ch, + u8 *ch_mask, u32 *ch_rate, + u8 *port_type, u8 path) +{ + int i, j; + u8 num_ports = 0; + struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT] = NULL; + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + + switch (path) { + case CODEC_RX: + map = &rouleur->rx_port_mapping; + num_ports = rouleur->num_rx_ports; + break; + case CODEC_TX: + map = &rouleur->tx_port_mapping; + num_ports = rouleur->num_tx_ports; + break; + default: + dev_err(component->dev, "%s Invalid path: %d\n", + __func__, path); + return -EINVAL; + } + + for (i = 0; i <= num_ports; i++) { + for (j = 0; j < MAX_CH_PER_PORT; j++) { + if ((*map)[i][j].slave_port_type == slv_prt_type) + goto found; + } + } + + dev_err(component->dev, "%s Failed to find slave port for type %u\n", + __func__, slv_prt_type); + return -EINVAL; +found: + *port_id = i; + *num_ch = (*map)[i][j].num_ch; + *ch_mask = (*map)[i][j].ch_mask; + *ch_rate = (*map)[i][j].ch_rate; + *port_type = (*map)[i][j].master_port_type; + + return 0; +} + +static int rouleur_parse_port_mapping(struct device *dev, + char *prop, u8 path) +{ + u32 *dt_array, map_size, map_length; + u32 port_num = 0, ch_mask, ch_rate, old_port_num = 0; + u32 slave_port_type, master_port_type; + u32 i, ch_iter = 0; + int ret = 0; + u8 *num_ports = NULL; + struct codec_port_info (*map)[MAX_PORT][MAX_CH_PER_PORT] = NULL; + struct rouleur_priv *rouleur = dev_get_drvdata(dev); + + switch (path) { + case CODEC_RX: + map = &rouleur->rx_port_mapping; + num_ports = &rouleur->num_rx_ports; + break; + case CODEC_TX: + map = &rouleur->tx_port_mapping; + num_ports = &rouleur->num_tx_ports; + break; + default: + dev_err(dev, "%s Invalid path: %d\n", + __func__, path); + return -EINVAL; + } + + if (!of_find_property(dev->of_node, prop, + &map_size)) { + dev_err(dev, "missing port mapping prop %s\n", prop); + ret = -EINVAL; + goto err; + } + + map_length = map_size / (NUM_SWRS_DT_PARAMS * sizeof(u32)); + + dt_array = kzalloc(map_size, GFP_KERNEL); + + if (!dt_array) { + ret = -ENOMEM; + goto err; + } + ret = of_property_read_u32_array(dev->of_node, prop, dt_array, + NUM_SWRS_DT_PARAMS * map_length); + if (ret) { + dev_err(dev, "%s: Failed to read port mapping from prop %s\n", + __func__, prop); + ret = -EINVAL; + goto err_pdata_fail; + } + + for (i = 0; i < map_length; i++) { + port_num = dt_array[NUM_SWRS_DT_PARAMS * i]; + slave_port_type = dt_array[NUM_SWRS_DT_PARAMS * i + 1]; + ch_mask = dt_array[NUM_SWRS_DT_PARAMS * i + 2]; + ch_rate = dt_array[NUM_SWRS_DT_PARAMS * i + 3]; + master_port_type = dt_array[NUM_SWRS_DT_PARAMS * i + 4]; + + if (port_num != old_port_num) + ch_iter = 0; + + (*map)[port_num][ch_iter].slave_port_type = slave_port_type; + (*map)[port_num][ch_iter].ch_mask = ch_mask; + (*map)[port_num][ch_iter].master_port_type = master_port_type; + (*map)[port_num][ch_iter].num_ch = __sw_hweight8(ch_mask); + (*map)[port_num][ch_iter++].ch_rate = ch_rate; + old_port_num = port_num; + } + *num_ports = port_num; + +err_pdata_fail: + kfree(dt_array); +err: + return ret; +} + +static int rouleur_tx_connect_port(struct snd_soc_component *component, + u8 slv_port_type, u8 enable) +{ + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + u8 port_id; + u8 num_ch; + u8 ch_mask; + u32 ch_rate; + u8 port_type; + u8 num_port = 1; + int ret = 0; + + ret = rouleur_set_port_params(component, slv_port_type, &port_id, + &num_ch, &ch_mask, &ch_rate, + &port_type, CODEC_TX); + + if (ret) { + dev_err(rouleur->dev, "%s:Failed to set port params: %d\n", + __func__, ret); + return ret; + } + + if (enable) + ret = swr_connect_port(rouleur->tx_swr_dev, &port_id, + num_port, &ch_mask, &ch_rate, + &num_ch, &port_type); + else + ret = swr_disconnect_port(rouleur->tx_swr_dev, &port_id, + num_port, &ch_mask, &port_type); + return ret; + +} +static int rouleur_rx_connect_port(struct snd_soc_component *component, + u8 slv_port_type, u8 enable) +{ + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + u8 port_id; + u8 num_ch; + u8 ch_mask; + u32 ch_rate; + u8 port_type; + u8 num_port = 1; + int ret = 0; + + ret = rouleur_set_port_params(component, slv_port_type, &port_id, + &num_ch, &ch_mask, &ch_rate, + &port_type, CODEC_RX); + + if (ret) { + dev_err(rouleur->dev, "%s:Failed to set port params: %d\n", + __func__, ret); + return ret; + } + + if (enable) + ret = swr_connect_port(rouleur->rx_swr_dev, &port_id, + num_port, &ch_mask, &ch_rate, + &num_ch, &port_type); + else + ret = swr_disconnect_port(rouleur->rx_swr_dev, &port_id, + num_port, &ch_mask, &port_type); + return ret; +} + +static int rouleur_global_mbias_enable(struct snd_soc_component *component) +{ + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + + mutex_lock(&rouleur->main_bias_lock); + if (rouleur->mbias_cnt == 0) { + snd_soc_component_update_bits(component, + ROULEUR_ANA_MBIAS_EN, 0x20, 0x20); + snd_soc_component_update_bits(component, + ROULEUR_ANA_MBIAS_EN, 0x10, 0x10); + usleep_range(1000, 1100); + } + rouleur->mbias_cnt++; + mutex_unlock(&rouleur->main_bias_lock); + + return 0; +} + +static int rouleur_global_mbias_disable(struct snd_soc_component *component) +{ + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + + mutex_lock(&rouleur->main_bias_lock); + if (rouleur->mbias_cnt == 0) { + dev_dbg(rouleur->dev, "%s:mbias already disabled\n", __func__); + mutex_unlock(&rouleur->main_bias_lock); + return 0; + } + rouleur->mbias_cnt--; + if (rouleur->mbias_cnt == 0) { + snd_soc_component_update_bits(component, + ROULEUR_ANA_MBIAS_EN, 0x10, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_ANA_MBIAS_EN, 0x20, 0x00); + } + mutex_unlock(&rouleur->main_bias_lock); + + return 0; +} + +static int rouleur_rx_clk_enable(struct snd_soc_component *component) +{ + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + + mutex_lock(&rouleur->rx_clk_lock); + if (rouleur->rx_clk_cnt == 0) { + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x10, 0x10); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x20, 0x20); + usleep_range(5000, 5100); + rouleur_global_mbias_enable(component); + snd_soc_component_update_bits(component, + ROULEUR_ANA_HPHPA_FSM_CLK, 0x11, 0x11); + snd_soc_component_update_bits(component, + ROULEUR_ANA_HPHPA_FSM_CLK, 0x80, 0x80); + snd_soc_component_update_bits(component, + ROULEUR_ANA_NCP_EN, 0x01, 0x01); + usleep_range(500, 510); + } + rouleur->rx_clk_cnt++; + mutex_unlock(&rouleur->rx_clk_lock); + + return 0; +} + +static int rouleur_rx_clk_disable(struct snd_soc_component *component) +{ + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + + mutex_lock(&rouleur->rx_clk_lock); + if (rouleur->rx_clk_cnt == 0) { + dev_dbg(rouleur->dev, "%s:clk already disabled\n", __func__); + mutex_unlock(&rouleur->rx_clk_lock); + return 0; + } + rouleur->rx_clk_cnt--; + if (rouleur->rx_clk_cnt == 0) { + snd_soc_component_update_bits(component, + ROULEUR_ANA_HPHPA_FSM_CLK, 0x80, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_ANA_HPHPA_FSM_CLK, 0x11, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_ANA_NCP_EN, 0x01, 0x00); + rouleur_global_mbias_disable(component); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x20, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x10, 0x00); + + } + mutex_unlock(&rouleur->rx_clk_lock); + return 0; +} + +/* + * rouleur_soc_get_mbhc: get rouleur_mbhc handle of corresponding component + * @component: handle to snd_soc_component * + * + * return rouleur_mbhc handle or error code in case of failure + */ +struct rouleur_mbhc *rouleur_soc_get_mbhc(struct snd_soc_component *component) +{ + struct rouleur_priv *rouleur; + + if (!component) { + pr_err("%s: Invalid params, NULL component\n", __func__); + return NULL; + } + rouleur = snd_soc_component_get_drvdata(component); + + if (!rouleur) { + pr_err("%s: Invalid params, NULL tavil\n", __func__); + return NULL; + } + + return rouleur->mbhc; +} +EXPORT_SYMBOL(rouleur_soc_get_mbhc); + +static int rouleur_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rouleur_rx_clk_enable(component); + set_bit(HPH_COMP_DELAY, &rouleur->status_mask); + break; + case SND_SOC_DAPM_POST_PMU: + if (rouleur->comp1_enable) { + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_COMP_CTL_0, + 0x02, 0x02); + + if (rouleur->comp2_enable) + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_COMP_CTL_0, + 0x01, 0x01); + /* + * 5ms sleep is required after COMP is enabled as per + * HW requirement + */ + if (test_bit(HPH_COMP_DELAY, &rouleur->status_mask)) { + usleep_range(5000, 5100); + clear_bit(HPH_COMP_DELAY, + &rouleur->status_mask); + } + } else { + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_COMP_CTL_0, + 0x02, 0x00); + } + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX0_CTL, + 0x7C, 0x7C); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, + 0x04, 0x04); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x01, 0x01); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_PDM_WD_CTL0, + 0x03, 0x03); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_PDM_WD_CTL0, + 0x03, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, + 0x01, 0x00); + break; + } + + return 0; +} + +static int rouleur_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rouleur_rx_clk_enable(component); + set_bit(HPH_COMP_DELAY, &rouleur->status_mask); + break; + case SND_SOC_DAPM_POST_PMU: + if (rouleur->comp2_enable) { + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_COMP_CTL_0, + 0x01, 0x01); + + if (rouleur->comp1_enable) + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_COMP_CTL_0, + 0x02, 0x02); + /* + * 5ms sleep is required after COMP is enabled as per + * HW requirement + */ + if (test_bit(HPH_COMP_DELAY, &rouleur->status_mask)) { + usleep_range(5000, 5100); + clear_bit(HPH_COMP_DELAY, + &rouleur->status_mask); + } + } else { + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_COMP_CTL_0, + 0x01, 0x00); + } + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX1_CTL, + 0x7C, 0x7C); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, + 0x08, 0x08); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x02, 0x02); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_PDM_WD_CTL1, + 0x03, 0x03); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_PDM_WD_CTL1, + 0x03, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x02, 0x00); + break; + + } + + return 0; +} + +static int rouleur_codec_ear_lo_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rouleur_rx_clk_enable(component); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX0_CTL, + 0x7C, 0x7C); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, + 0x01, 0x01); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_PDM_WD_CTL0, + 0x03, 0x03); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, + 0x04, 0x04); + + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_PDM_WD_CTL0, + 0x03, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, + 0x01, 0x00); + + break; + }; + return 0; + +} + +static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + int ret = 0; + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev, + rouleur->rx_swr_dev->dev_num, + true); + + snd_soc_component_update_bits(component, + ROULEUR_ANA_HPHPA_CNP_CTL_2, + 0x40, 0x40); + set_bit(HPH_PA_DELAY, &rouleur->status_mask); + /* TODO: WHY SECOND TIME */ + ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev, + rouleur->rx_swr_dev->dev_num, + true); + break; + case SND_SOC_DAPM_POST_PMU: + /* + * 5ms sleep is required after PA is enabled as per + * HW requirement. + */ + if (test_bit(HPH_PA_DELAY, &rouleur->status_mask)) { + usleep_range(5000, 5100); + clear_bit(HPH_PA_DELAY, &rouleur->status_mask); + } + + if (rouleur->update_wcd_event) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX2 << 0x10)); + wcd_enable_irq(&rouleur->irq_info, + ROULEUR_IRQ_HPHR_PDM_WD_INT); + break; + case SND_SOC_DAPM_PRE_PMD: + wcd_disable_irq(&rouleur->irq_info, + ROULEUR_IRQ_HPHR_PDM_WD_INT); + if (rouleur->update_wcd_event) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX2 << 0x10 | 0x1)); + blocking_notifier_call_chain(&rouleur->mbhc->notifier, + WCD_EVENT_PRE_HPHR_PA_OFF, + &rouleur->mbhc->wcd_mbhc); + set_bit(HPH_PA_DELAY, &rouleur->status_mask); + break; + case SND_SOC_DAPM_POST_PMD: + /* + * 7ms sleep is required after PA is disabled as per + * HW requirement. If compander is disabled, then + * 20ms delay is required. + */ + if (test_bit(HPH_PA_DELAY, &rouleur->status_mask)) { + + usleep_range(5000, 5100); + clear_bit(HPH_PA_DELAY, &rouleur->status_mask); + } + + blocking_notifier_call_chain(&rouleur->mbhc->notifier, + WCD_EVENT_POST_HPHR_PA_OFF, + &rouleur->mbhc->wcd_mbhc); + snd_soc_component_update_bits(component, + ROULEUR_ANA_HPHPA_CNP_CTL_2, + 0x40, 0x00); + break; + }; + return ret; +} + +static int rouleur_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + int ret = 0; + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev, + rouleur->rx_swr_dev->dev_num, + true); + snd_soc_component_update_bits(component, + ROULEUR_ANA_HPHPA_CNP_CTL_2, + 0x80, 0x80); + set_bit(HPH_PA_DELAY, &rouleur->status_mask); + break; + case SND_SOC_DAPM_POST_PMU: + /* + * 5ms sleep is required after PA is enabled as per + * HW requirement. + */ + if (test_bit(HPH_PA_DELAY, &rouleur->status_mask)) { + usleep_range(5000, 5100); + clear_bit(HPH_PA_DELAY, &rouleur->status_mask); + } + + if (rouleur->update_wcd_event) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10)); + wcd_enable_irq(&rouleur->irq_info, + ROULEUR_IRQ_HPHL_PDM_WD_INT); + break; + case SND_SOC_DAPM_PRE_PMD: + wcd_disable_irq(&rouleur->irq_info, + ROULEUR_IRQ_HPHL_PDM_WD_INT); + if (rouleur->update_wcd_event) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10 | 0x1)); + blocking_notifier_call_chain(&rouleur->mbhc->notifier, + WCD_EVENT_PRE_HPHL_PA_OFF, + &rouleur->mbhc->wcd_mbhc); + set_bit(HPH_PA_DELAY, &rouleur->status_mask); + break; + case SND_SOC_DAPM_POST_PMD: + /* + * 5ms sleep is required after PA is disabled as per + * HW requirement. + */ + if (test_bit(HPH_PA_DELAY, &rouleur->status_mask)) { + usleep_range(5000, 5100); + clear_bit(HPH_PA_DELAY, &rouleur->status_mask); + } + + blocking_notifier_call_chain(&rouleur->mbhc->notifier, + WCD_EVENT_POST_HPHL_PA_OFF, + &rouleur->mbhc->wcd_mbhc); + snd_soc_component_update_bits(component, + ROULEUR_ANA_HPHPA_CNP_CTL_2, + 0x80, 0x00); + + break; + }; + return ret; +} + +static int rouleur_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + int ret = 0; + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev, + rouleur->rx_swr_dev->dev_num, + true); + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL, + 0x80, 0x80); + usleep_range(5000, 5100); + break; + case SND_SOC_DAPM_POST_PMU: + if (rouleur->update_wcd_event) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10)); + wcd_enable_irq(&rouleur->irq_info, + ROULEUR_IRQ_HPHL_PDM_WD_INT); + break; + case SND_SOC_DAPM_PRE_PMD: + wcd_disable_irq(&rouleur->irq_info, + ROULEUR_IRQ_HPHL_PDM_WD_INT); + if (rouleur->update_wcd_event) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10 | 0x1)); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL, + 0x80, 0x00); + usleep_range(5000, 5100); + }; + return ret; +} + +static int rouleur_codec_enable_lo_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + int ret = 0; + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev, + rouleur->rx_swr_dev->dev_num, + true); + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL, + 0x40, 0x40); + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL, + 0x80, 0x80); + usleep_range(5000, 5100); + break; + case SND_SOC_DAPM_POST_PMU: + if (rouleur->update_wcd_event) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10)); + wcd_enable_irq(&rouleur->irq_info, + ROULEUR_IRQ_HPHL_PDM_WD_INT); + break; + case SND_SOC_DAPM_PRE_PMD: + wcd_disable_irq(&rouleur->irq_info, + ROULEUR_IRQ_HPHL_PDM_WD_INT); + if (rouleur->update_wcd_event) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_RX_MUTE, + (WCD_RX1 << 0x10 | 0x1)); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL, + 0x80, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL, + 0x40, 0x00); + usleep_range(5000, 5100); + }; + return ret; +} + +static int rouleur_enable_rx1(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rouleur_rx_connect_port(component, HPH_L, true); + if (rouleur->comp1_enable) + rouleur_rx_connect_port(component, COMP_L, true); + break; + case SND_SOC_DAPM_POST_PMD: + rouleur_rx_connect_port(component, HPH_L, false); + if (rouleur->comp1_enable) + rouleur_rx_connect_port(component, COMP_L, false); + rouleur_rx_clk_disable(component); + break; + }; + return 0; +} + +static int rouleur_enable_rx2(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rouleur_rx_connect_port(component, HPH_R, true); + if (rouleur->comp2_enable) + rouleur_rx_connect_port(component, COMP_R, true); + break; + case SND_SOC_DAPM_POST_PMD: + rouleur_rx_connect_port(component, HPH_R, false); + if (rouleur->comp2_enable) + rouleur_rx_connect_port(component, COMP_R, false); + rouleur_rx_clk_disable(component); + break; + }; + + return 0; +} + +static int rouleur_codec_enable_dmic(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + u16 dmic_clk_reg; + s32 *dmic_clk_cnt; + unsigned int dmic; + char *wname; + int ret = 0; + + wname = strpbrk(w->name, "01"); + + if (!wname) { + dev_err(component->dev, "%s: widget not found\n", __func__); + return -EINVAL; + } + + ret = kstrtouint(wname, 10, &dmic); + if (ret < 0) { + dev_err(component->dev, "%s: Invalid DMIC line on the codec\n", + __func__); + return -EINVAL; + } + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (dmic) { + case 0: + case 1: + dmic_clk_cnt = &(rouleur->dmic_0_1_clk_cnt); + dmic_clk_reg = ROULEUR_DIG_SWR_CDC_DMIC1_CTL; + break; + default: + dev_err(component->dev, "%s: Invalid DMIC Selection\n", + __func__); + return -EINVAL; + }; + dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n", + __func__, event, dmic, *dmic_clk_cnt); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_AMIC_CTL, 0x02, 0x00); + snd_soc_component_update_bits(component, + dmic_clk_reg, 0x08, 0x08); + rouleur_tx_connect_port(component, DMIC0 + (w->shift), true); + break; + case SND_SOC_DAPM_POST_PMD: + rouleur_tx_connect_port(component, DMIC0 + (w->shift), false); + snd_soc_component_update_bits(component, + dmic_clk_reg, 0x08, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_AMIC_CTL, 0x02, 0x02); + break; + + }; + return 0; +} + +static int rouleur_tx_swr_ctrl(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + int ret = 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = swr_slvdev_datapath_control(rouleur->tx_swr_dev, + rouleur->tx_swr_dev->dev_num, + true); + break; + case SND_SOC_DAPM_POST_PMD: + ret = swr_slvdev_datapath_control(rouleur->tx_swr_dev, + rouleur->tx_swr_dev->dev_num, + false); + break; + }; + + return ret; +} + +static int rouleur_codec_enable_adc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct rouleur_priv *rouleur = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Enable BCS for Headset mic */ + if (w->shift == 1 && !(snd_soc_component_read32(component, + ROULEUR_ANA_TX_AMIC2) & 0x10)) { + rouleur_tx_connect_port(component, MBHC, true); + set_bit(AMIC2_BCS_ENABLE, &rouleur->status_mask); + } + rouleur_tx_connect_port(component, ADC1 + (w->shift), true); + rouleur_global_mbias_enable(component); + if (w->shift) + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_TX_ANA_MODE_0_1, + 0x30, 0x30); + else + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_TX_ANA_MODE_0_1, + 0x03, 0x03); + break; + case SND_SOC_DAPM_POST_PMD: + rouleur_tx_connect_port(component, ADC1 + (w->shift), false); + if (w->shift == 1 && + test_bit(AMIC2_BCS_ENABLE, &rouleur->status_mask)) { + rouleur_tx_connect_port(component, MBHC, false); + clear_bit(AMIC2_BCS_ENABLE, &rouleur->status_mask); + } + if (w->shift) + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_TX_ANA_MODE_0_1, + 0x30, 0x00); + else + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_TX_ANA_MODE_0_1, + 0x03, 0x00); + rouleur_global_mbias_disable(component); + break; + }; + + return 0; +} + +/* + * rouleur_get_micb_vout_ctl_val: converts micbias from volts to register value + * @micb_mv: micbias in mv + * + * return register value converted + */ +int rouleur_get_micb_vout_ctl_val(u32 micb_mv) +{ + /* min micbias voltage is 1.6V and maximum is 2.85V */ + if (micb_mv < 1600 || micb_mv > 2850) { + pr_err("%s: unsupported micbias voltage\n", __func__); + return -EINVAL; + } + + return (micb_mv - 1600) / 50; +} +EXPORT_SYMBOL(rouleur_get_micb_vout_ctl_val); + +/* + * rouleur_mbhc_micb_adjust_voltage: adjust specific micbias voltage + * @component: handle to snd_soc_component * + * @req_volt: micbias voltage to be set + * @micb_num: micbias to be set, e.g. micbias1 or micbias2 + * + * return 0 if adjustment is success or error code in case of failure + */ +int rouleur_mbhc_micb_adjust_voltage(struct snd_soc_component *component, + int req_volt, int micb_num) +{ + struct rouleur_priv *rouleur = + snd_soc_component_get_drvdata(component); + int cur_vout_ctl, req_vout_ctl; + int micb_reg, micb_val, micb_en; + int ret = 0; + int pullup_mask; + + micb_reg = ROULEUR_ANA_MICBIAS_MICB_1_2_EN; + switch (micb_num) { + case MIC_BIAS_1: + micb_val = snd_soc_component_read32(component, micb_reg); + micb_en = (micb_val & 0x40) >> 6; + pullup_mask = 0x20; + break; + case MIC_BIAS_2: + micb_val = snd_soc_component_read32(component, micb_reg); + micb_en = (micb_val & 0x04) >> 2; + pullup_mask = 0x02; + break; + case MIC_BIAS_3: + default: + dev_err(component->dev, "%s: Invalid micbias number: %d\n", + __func__, micb_num); + return -EINVAL; + } + mutex_lock(&rouleur->micb_lock); + + /* + * If requested micbias voltage is same as current micbias + * voltage, then just return. Otherwise, adjust voltage as + * per requested value. If micbias is already enabled, then + * to avoid slow micbias ramp-up or down enable pull-up + * momentarily, change the micbias value and then re-enable + * micbias. + */ + cur_vout_ctl = (snd_soc_component_read32(component, + ROULEUR_ANA_MICBIAS_LDO_1_SETTING)) & 0xF8; + + req_vout_ctl = rouleur_get_micb_vout_ctl_val(req_volt); + if (req_vout_ctl < 0) { + ret = -EINVAL; + goto exit; + } + if (cur_vout_ctl == req_vout_ctl) { + ret = 0; + goto exit; + } + + dev_dbg(component->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n", + __func__, micb_num, WCD_VOUT_CTL_TO_MICB(cur_vout_ctl), + req_volt, micb_en); + + if (micb_en == 0x1) + snd_soc_component_update_bits(component, micb_reg, pullup_mask, + pullup_mask); + + snd_soc_component_update_bits(component, + ROULEUR_ANA_MICBIAS_LDO_1_SETTING, 0xF8, req_vout_ctl); + + if (micb_en == 0x1) { + snd_soc_component_update_bits(component, micb_reg, + pullup_mask, 0x00); + /* + * Add 2ms delay as per HW requirement after enabling + * micbias + */ + usleep_range(2000, 2100); + } +exit: + mutex_unlock(&rouleur->micb_lock); + return ret; +} +EXPORT_SYMBOL(rouleur_mbhc_micb_adjust_voltage); + +int rouleur_micbias_control(struct snd_soc_component *component, + int micb_num, int req, bool is_dapm) +{ + + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + int micb_index = micb_num - 1; + u16 micb_reg; + int pre_off_event = 0, post_off_event = 0; + int post_on_event = 0, post_dapm_off = 0; + int post_dapm_on = 0; + u8 pullup_mask = 0, enable_mask = 0; + + if ((micb_index < 0) || (micb_index > ROULEUR_MAX_MICBIAS - 1)) { + dev_err(component->dev, "%s: Invalid micbias index, micb_ind:%d\n", + __func__, micb_index); + return -EINVAL; + } + switch (micb_num) { + case MIC_BIAS_1: + micb_reg = ROULEUR_ANA_MICBIAS_MICB_1_2_EN; + pullup_mask = 0x20; + enable_mask = 0x40; + break; + case MIC_BIAS_2: + micb_reg = ROULEUR_ANA_MICBIAS_MICB_1_2_EN; + pullup_mask = 0x02; + enable_mask = 0x04; + pre_off_event = WCD_EVENT_PRE_MICBIAS_2_OFF; + post_off_event = WCD_EVENT_POST_MICBIAS_2_OFF; + post_on_event = WCD_EVENT_POST_MICBIAS_2_ON; + post_dapm_on = WCD_EVENT_POST_DAPM_MICBIAS_2_ON; + post_dapm_off = WCD_EVENT_POST_DAPM_MICBIAS_2_OFF; + break; + case MIC_BIAS_3: + micb_reg = ROULEUR_ANA_MICBIAS_MICB_3_EN; + pullup_mask = 0x02; + break; + default: + dev_err(component->dev, "%s: Invalid micbias number: %d\n", + __func__, micb_num); + return -EINVAL; + }; + mutex_lock(&rouleur->micb_lock); + + switch (req) { + case MICB_PULLUP_ENABLE: + rouleur->pullup_ref[micb_index]++; + if ((rouleur->pullup_ref[micb_index] == 1) && + (rouleur->micb_ref[micb_index] == 0)) + snd_soc_component_update_bits(component, micb_reg, + pullup_mask, pullup_mask); + break; + case MICB_PULLUP_DISABLE: + if (rouleur->pullup_ref[micb_index] > 0) + rouleur->pullup_ref[micb_index]--; + if ((rouleur->pullup_ref[micb_index] == 0) && + (rouleur->micb_ref[micb_index] == 0)) + snd_soc_component_update_bits(component, micb_reg, + pullup_mask, 0x00); + break; + case MICB_ENABLE: + rouleur->micb_ref[micb_index]++; + if (rouleur->micb_ref[micb_index] == 1) { + rouleur_global_mbias_enable(component); + snd_soc_component_update_bits(component, + micb_reg, enable_mask, enable_mask); + if (post_on_event) + blocking_notifier_call_chain( + &rouleur->mbhc->notifier, post_on_event, + &rouleur->mbhc->wcd_mbhc); + } + if (is_dapm && post_dapm_on && rouleur->mbhc) + blocking_notifier_call_chain( + &rouleur->mbhc->notifier, post_dapm_on, + &rouleur->mbhc->wcd_mbhc); + break; + case MICB_DISABLE: + if (rouleur->micb_ref[micb_index] > 0) + rouleur->micb_ref[micb_index]--; + if ((rouleur->micb_ref[micb_index] == 0) && + (rouleur->pullup_ref[micb_index] == 0)) { + if (pre_off_event && rouleur->mbhc) + blocking_notifier_call_chain( + &rouleur->mbhc->notifier, pre_off_event, + &rouleur->mbhc->wcd_mbhc); + snd_soc_component_update_bits(component, micb_reg, + enable_mask, 0x00); + rouleur_global_mbias_disable(component); + if (post_off_event && rouleur->mbhc) + blocking_notifier_call_chain( + &rouleur->mbhc->notifier, + post_off_event, + &rouleur->mbhc->wcd_mbhc); + } + if (is_dapm && post_dapm_off && rouleur->mbhc) + blocking_notifier_call_chain( + &rouleur->mbhc->notifier, post_dapm_off, + &rouleur->mbhc->wcd_mbhc); + break; + }; + + dev_dbg(component->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", + __func__, micb_num, rouleur->micb_ref[micb_index], + rouleur->pullup_ref[micb_index]); + mutex_unlock(&rouleur->micb_lock); + + return 0; +} +EXPORT_SYMBOL(rouleur_micbias_control); + +void rouleur_disable_bcs_before_slow_insert(struct snd_soc_component *component, + bool bcs_disable) +{ + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + + if (rouleur->update_wcd_event) { + if (bcs_disable) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_BCS_CLK_OFF, 0); + else + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_BCS_CLK_OFF, 1); + } +} + +static int rouleur_get_logical_addr(struct swr_device *swr_dev) +{ + int ret = 0; + uint8_t devnum = 0; + int num_retry = NUM_ATTEMPTS; + + do { + ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum); + if (ret) { + dev_err(&swr_dev->dev, + "%s get devnum %d for dev addr %lx failed\n", + __func__, devnum, swr_dev->addr); + /* retry after 1ms */ + usleep_range(1000, 1010); + } + } while (ret && --num_retry); + swr_dev->dev_num = devnum; + return 0; +} + +static int rouleur_event_notify(struct notifier_block *block, + unsigned long val, + void *data) +{ + u16 event = (val & 0xffff); + int ret = 0; + struct rouleur_priv *rouleur = dev_get_drvdata((struct device *)data); + struct snd_soc_component *component = rouleur->component; + struct wcd_mbhc *mbhc; + + switch (event) { + case BOLERO_WCD_EVT_PA_OFF_PRE_SSR: + snd_soc_component_update_bits(component, + ROULEUR_ANA_HPHPA_CNP_CTL_2, + 0xC0, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL, + 0x40, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL, + 0x80, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL, + 0x40, 0x40); + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL, + 0x80, 0x00); + break; + case BOLERO_WCD_EVT_SSR_DOWN: + rouleur->mbhc->wcd_mbhc.deinit_in_progress = true; + mbhc = &rouleur->mbhc->wcd_mbhc; + rouleur_mbhc_ssr_down(rouleur->mbhc, component); + rouleur_reset(rouleur->dev, 0x01); + break; + case BOLERO_WCD_EVT_SSR_UP: + rouleur_reset(rouleur->dev, 0x00); + /* allow reset to take effect */ + usleep_range(10000, 10010); + rouleur_get_logical_addr(rouleur->tx_swr_dev); + rouleur_get_logical_addr(rouleur->rx_swr_dev); + + rouleur_init_reg(component); + regcache_mark_dirty(rouleur->regmap); + regcache_sync(rouleur->regmap); + /* Initialize MBHC module */ + mbhc = &rouleur->mbhc->wcd_mbhc; + ret = rouleur_mbhc_post_ssr_init(rouleur->mbhc, component); + if (ret) { + dev_err(component->dev, "%s: mbhc initialization failed\n", + __func__); + } else { + rouleur_mbhc_hs_detect(component, mbhc->mbhc_cfg); + } + rouleur->mbhc->wcd_mbhc.deinit_in_progress = false; + break; + default: + dev_err(component->dev, "%s: invalid event %d\n", __func__, + event); + break; + } + return 0; +} + +static int __rouleur_codec_enable_micbias(struct snd_soc_dapm_widget *w, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + int micb_num; + + dev_dbg(component->dev, "%s: wname: %s, event: %d\n", + __func__, w->name, event); + + if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) + micb_num = MIC_BIAS_1; + else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2"))) + micb_num = MIC_BIAS_2; + else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3"))) + micb_num = MIC_BIAS_3; + else + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Micbias LD0 enable not supported for MicBias 3*/ + if (micb_num == MIC_BIAS_3) + rouleur_micbias_control(component, micb_num, + MICB_PULLUP_ENABLE, true); + else + rouleur_micbias_control(component, micb_num, + MICB_ENABLE, true); + break; + case SND_SOC_DAPM_POST_PMU: + usleep_range(1000, 1100); + break; + case SND_SOC_DAPM_POST_PMD: + if (micb_num == MIC_BIAS_3) + rouleur_micbias_control(component, micb_num, + MICB_PULLUP_DISABLE, true); + else + rouleur_micbias_control(component, micb_num, + MICB_DISABLE, true); + break; + }; + + return 0; + +} + +static int rouleur_codec_enable_micbias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + return __rouleur_codec_enable_micbias(w, event); +} + +static int __rouleur_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + int micb_num; + + dev_dbg(component->dev, "%s: wname: %s, event: %d\n", + __func__, w->name, event); + + if (strnstr(w->name, "VA MIC BIAS1", sizeof("VA MIC BIAS1"))) + micb_num = MIC_BIAS_1; + else if (strnstr(w->name, "VA MIC BIAS2", sizeof("VA MIC BIAS2"))) + micb_num = MIC_BIAS_2; + else if (strnstr(w->name, "VA MIC BIAS3", sizeof("VA MIC BIAS3"))) + micb_num = MIC_BIAS_3; + else + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + rouleur_micbias_control(component, micb_num, + MICB_PULLUP_ENABLE, true); + break; + case SND_SOC_DAPM_POST_PMU: + /* 1 msec delay as per HW requirement */ + usleep_range(1000, 1100); + break; + case SND_SOC_DAPM_POST_PMD: + rouleur_micbias_control(component, micb_num, + MICB_PULLUP_DISABLE, true); + break; + }; + + return 0; + +} + +static int rouleur_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + return __rouleur_codec_enable_micbias_pullup(w, event); +} + +static int rouleur_get_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + bool hphr; + struct soc_multi_mixer_control *mc; + + mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); + hphr = mc->shift; + + ucontrol->value.integer.value[0] = hphr ? rouleur->comp2_enable : + rouleur->comp1_enable; + return 0; +} + +static int rouleur_set_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + int value = ucontrol->value.integer.value[0]; + bool hphr; + struct soc_multi_mixer_control *mc; + + mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); + hphr = mc->shift; + if (hphr) + rouleur->comp2_enable = value; + else + rouleur->comp1_enable = value; + + return 0; +} + +static int rouleur_codec_enable_pa_vpos(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + struct rouleur_pdata *pdata = NULL; + int ret = 0; + + pdata = dev_get_platdata(rouleur->dev); + + if (!pdata) { + dev_err(component->dev, "%s: pdata is NULL\n", __func__); + return -EINVAL; + } + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (test_bit(ALLOW_VPOS_DISABLE, &rouleur->status_mask)) { + dev_dbg(component->dev, + "%s: vpos already in enabled state\n", + __func__); + clear_bit(ALLOW_VPOS_DISABLE, &rouleur->status_mask); + return 0; + } + ret = msm_cdc_enable_ondemand_supply(rouleur->dev, + rouleur->supplies, + pdata->regulator, + pdata->num_supplies, + "cdc-pa-vpos"); + if (ret == -EINVAL) { + dev_err(component->dev, "%s: pa vpos is not enabled\n", + __func__); + return ret; + } + clear_bit(ALLOW_VPOS_DISABLE, &rouleur->status_mask); + /* + * 200us sleep is required after LDO15 is enabled as per + * HW requirement + */ + usleep_range(200, 250); + + break; + case SND_SOC_DAPM_POST_PMD: + set_bit(ALLOW_VPOS_DISABLE, &rouleur->status_mask); + break; + } + return 0; +} + +static const struct snd_kcontrol_new rouleur_snd_controls[] = { + SOC_SINGLE_EXT("HPHL_COMP Switch", SND_SOC_NOPM, 0, 1, 0, + rouleur_get_compander, rouleur_set_compander), + SOC_SINGLE_EXT("HPHR_COMP Switch", SND_SOC_NOPM, 1, 1, 0, + rouleur_get_compander, rouleur_set_compander), + + SOC_SINGLE_TLV("HPHL Volume", ROULEUR_ANA_HPHPA_L_GAIN, 0, 20, 1, + line_gain), + SOC_SINGLE_TLV("HPHR Volume", ROULEUR_ANA_HPHPA_R_GAIN, 0, 20, 1, + line_gain), + SOC_SINGLE_TLV("ADC1 Volume", ROULEUR_ANA_TX_AMIC1, 0, 8, 0, + analog_gain), + SOC_SINGLE_TLV("ADC2 Volume", ROULEUR_ANA_TX_AMIC2, 0, 8, 0, + analog_gain), +}; + +static const struct snd_kcontrol_new adc1_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new adc2_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new dmic1_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new dmic2_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new ear_rdac_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new lo_rdac_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new hphl_rdac_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_kcontrol_new hphr_rdac_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const char * const adc2_mux_text[] = { + "INP2", "INP3" +}; + +static const struct soc_enum adc2_enum = + SOC_ENUM_SINGLE(ROULEUR_ANA_TX_AMIC2, 4, + ARRAY_SIZE(adc2_mux_text), adc2_mux_text); + + +static const struct snd_kcontrol_new tx_adc2_mux = + SOC_DAPM_ENUM("ADC2 MUX Mux", adc2_enum); + + +static const struct snd_soc_dapm_widget rouleur_dapm_widgets[] = { + + /*input widgets*/ + SND_SOC_DAPM_INPUT("AMIC1"), + SND_SOC_DAPM_INPUT("AMIC2"), + SND_SOC_DAPM_INPUT("AMIC3"), + SND_SOC_DAPM_INPUT("IN1_HPHL"), + SND_SOC_DAPM_INPUT("IN2_HPHR"), + + /*tx widgets*/ + SND_SOC_DAPM_ADC_E("ADC1", NULL, SND_SOC_NOPM, 0, 0, + rouleur_codec_enable_adc, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("ADC2", NULL, SND_SOC_NOPM, 1, 0, + rouleur_codec_enable_adc, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, + &tx_adc2_mux), + + /*tx mixers*/ + SND_SOC_DAPM_MIXER_E("ADC1_MIXER", SND_SOC_NOPM, 0, 0, + adc1_switch, ARRAY_SIZE(adc1_switch), + rouleur_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("ADC2_MIXER", SND_SOC_NOPM, 0, 0, + adc2_switch, ARRAY_SIZE(adc2_switch), + rouleur_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + /* micbias widgets*/ + SND_SOC_DAPM_MICBIAS_E("MIC BIAS1", SND_SOC_NOPM, 0, 0, + rouleur_codec_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS2", SND_SOC_NOPM, 0, 0, + rouleur_codec_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS3", SND_SOC_NOPM, 0, 0, + rouleur_codec_enable_micbias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("PA_VPOS", SND_SOC_NOPM, 0, 0, + rouleur_codec_enable_pa_vpos, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /*rx widgets*/ + SND_SOC_DAPM_PGA_E("EAR PGA", ROULEUR_ANA_COMBOPA_CTL, 7, 0, NULL, 0, + rouleur_codec_enable_ear_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("LO PGA", ROULEUR_ANA_COMBOPA_CTL, 7, 0, NULL, 0, + rouleur_codec_enable_lo_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("HPHL PGA", ROULEUR_ANA_HPHPA_CNP_CTL_2, 7, 0, NULL, + 0, rouleur_codec_enable_hphl_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("HPHR PGA", ROULEUR_ANA_HPHPA_CNP_CTL_2, 6, 0, NULL, + 0, rouleur_codec_enable_hphr_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_DAC_E("RDAC1", NULL, SND_SOC_NOPM, 0, 0, + rouleur_codec_hphl_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RDAC2", NULL, SND_SOC_NOPM, 0, 0, + rouleur_codec_hphr_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("RDAC3", NULL, SND_SOC_NOPM, 0, 0, + rouleur_codec_ear_lo_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER_E("RX1", SND_SOC_NOPM, 0, 0, NULL, 0, + rouleur_enable_rx1, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX2", SND_SOC_NOPM, 0, 0, NULL, 0, + rouleur_enable_rx2, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + /* rx mixer widgets*/ + + SND_SOC_DAPM_MIXER("EAR_RDAC", SND_SOC_NOPM, 0, 0, + ear_rdac_switch, ARRAY_SIZE(ear_rdac_switch)), + SND_SOC_DAPM_MIXER("LO_RDAC", SND_SOC_NOPM, 0, 0, + lo_rdac_switch, ARRAY_SIZE(lo_rdac_switch)), + SND_SOC_DAPM_MIXER("HPHL_RDAC", SND_SOC_NOPM, 0, 0, + hphl_rdac_switch, ARRAY_SIZE(hphl_rdac_switch)), + SND_SOC_DAPM_MIXER("HPHR_RDAC", SND_SOC_NOPM, 0, 0, + hphr_rdac_switch, ARRAY_SIZE(hphr_rdac_switch)), + + /*output widgets tx*/ + + SND_SOC_DAPM_OUTPUT("ADC1_OUTPUT"), + SND_SOC_DAPM_OUTPUT("ADC2_OUTPUT"), + + /*output widgets rx*/ + SND_SOC_DAPM_OUTPUT("EAR"), + SND_SOC_DAPM_OUTPUT("LO"), + SND_SOC_DAPM_OUTPUT("HPHL"), + SND_SOC_DAPM_OUTPUT("HPHR"), + + /* micbias pull up widgets*/ + SND_SOC_DAPM_MICBIAS_E("VA MIC BIAS1", SND_SOC_NOPM, 0, 0, + rouleur_codec_enable_micbias_pullup, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("VA MIC BIAS2", SND_SOC_NOPM, 0, 0, + rouleur_codec_enable_micbias_pullup, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("VA MIC BIAS3", SND_SOC_NOPM, 0, 0, + rouleur_codec_enable_micbias_pullup, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0, + rouleur_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 1, 0, + rouleur_codec_enable_dmic, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /*tx mixer widgets*/ + SND_SOC_DAPM_MIXER_E("DMIC1_MIXER", SND_SOC_NOPM, 0, + 0, dmic1_switch, ARRAY_SIZE(dmic1_switch), + rouleur_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("DMIC2_MIXER", SND_SOC_NOPM, 0, + 0, dmic2_switch, ARRAY_SIZE(dmic2_switch), + rouleur_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + /*output widgets*/ + SND_SOC_DAPM_OUTPUT("DMIC1_OUTPUT"), + SND_SOC_DAPM_OUTPUT("DMIC2_OUTPUT"), +}; + +static const struct snd_soc_dapm_route rouleur_audio_map[] = { + {"ADC1_OUTPUT", NULL, "ADC1_MIXER"}, + {"ADC1_MIXER", "Switch", "ADC1"}, + {"ADC1", NULL, "AMIC1"}, + + {"ADC2_OUTPUT", NULL, "ADC2_MIXER"}, + {"ADC2_MIXER", "Switch", "ADC2"}, + {"ADC2", NULL, "ADC2 MUX"}, + {"ADC2 MUX", "INP3", "AMIC3"}, + {"ADC2 MUX", "INP2", "AMIC2"}, + + {"IN1_HPHL", NULL, "PA_VPOS"}, + {"RX1", NULL, "IN1_HPHL"}, + {"RDAC1", NULL, "RX1"}, + {"HPHL_RDAC", "Switch", "RDAC1"}, + {"HPHL PGA", NULL, "HPHL_RDAC"}, + {"HPHL", NULL, "HPHL PGA"}, + + {"IN2_HPHR", NULL, "PA_VPOS"}, + {"RX2", NULL, "IN2_HPHR"}, + {"RDAC2", NULL, "RX2"}, + {"HPHR_RDAC", "Switch", "RDAC2"}, + {"HPHR PGA", NULL, "HPHR_RDAC"}, + {"HPHR", NULL, "HPHR PGA"}, + + {"RDAC3", NULL, "RX1"}, + {"EAR_RDAC", "Switch", "RDAC3"}, + {"EAR PGA", NULL, "EAR_RDAC"}, + {"EAR", NULL, "EAR PGA"}, + + {"RDAC3", NULL, "RX1"}, + {"LO_RDAC", "Switch", "RDAC3"}, + {"LO PGA", NULL, "LO_RDAC"}, + {"LO", NULL, "LO PGA"}, + + {"DMIC1_OUTPUT", NULL, "DMIC1_MIXER"}, + {"DMIC1_MIXER", "Switch", "DMIC1"}, + + {"DMIC2_OUTPUT", NULL, "DMIC2_MIXER"}, + {"DMIC2_MIXER", "Switch", "DMIC2"}, +}; + +static ssize_t rouleur_version_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, size_t count, + loff_t pos) +{ + struct rouleur_priv *priv; + char buffer[ROULEUR_VERSION_ENTRY_SIZE]; + int len = 0; + + priv = (struct rouleur_priv *) entry->private_data; + if (!priv) { + pr_err("%s: rouleur priv is null\n", __func__); + return -EINVAL; + } + + switch (priv->version) { + case ROULEUR_VERSION_1_0: + len = snprintf(buffer, sizeof(buffer), "rouleur_1_0\n"); + break; + default: + len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + } + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops rouleur_info_ops = { + .read = rouleur_version_read, +}; + +/* + * rouleur_info_create_codec_entry - creates rouleur module + * @codec_root: The parent directory + * @component: component instance + * + * Creates rouleur module and version entry under the given + * parent directory. + * + * Return: 0 on success or negative error code on failure. + */ +int rouleur_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_component *component) +{ + struct snd_info_entry *version_entry; + struct rouleur_priv *priv; + struct snd_soc_card *card; + + if (!codec_root || !component) + return -EINVAL; + + priv = snd_soc_component_get_drvdata(component); + if (priv->entry) { + dev_dbg(priv->dev, + "%s:rouleur module already created\n", __func__); + return 0; + } + card = component->card; + priv->entry = snd_info_create_subdir(codec_root->module, + "rouleur", codec_root); + if (!priv->entry) { + dev_dbg(component->dev, "%s: failed to create rouleur entry\n", + __func__); + return -ENOMEM; + } + version_entry = snd_info_create_card_entry(card->snd_card, + "version", + priv->entry); + if (!version_entry) { + dev_dbg(component->dev, "%s: failed to create rouleur version entry\n", + __func__); + return -ENOMEM; + } + + version_entry->private_data = priv; + version_entry->size = ROULEUR_VERSION_ENTRY_SIZE; + version_entry->content = SNDRV_INFO_CONTENT_DATA; + version_entry->c.ops = &rouleur_info_ops; + + if (snd_info_register(version_entry) < 0) { + snd_info_free_entry(version_entry); + return -ENOMEM; + } + priv->version_entry = version_entry; + + return 0; +} +EXPORT_SYMBOL(rouleur_info_create_codec_entry); + +static int rouleur_set_micbias_data(struct rouleur_priv *rouleur, + struct rouleur_pdata *pdata) +{ + int vout_ctl = 0; + int rc = 0; + + if (!pdata) { + dev_err(rouleur->dev, "%s: NULL pdata\n", __func__); + return -ENODEV; + } + + /* set micbias voltage */ + vout_ctl = rouleur_get_micb_vout_ctl_val(pdata->micbias.micb1_mv); + if (vout_ctl < 0) { + rc = -EINVAL; + goto done; + } + regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MICBIAS_LDO_1_SETTING, + 0xF8, vout_ctl); +done: + return rc; +} + +static int rouleur_soc_codec_probe(struct snd_soc_component *component) +{ + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); + int ret = -EINVAL; + + dev_info(component->dev, "%s()\n", __func__); + rouleur = snd_soc_component_get_drvdata(component); + + if (!rouleur) + return -EINVAL; + + rouleur->component = component; + snd_soc_component_init_regmap(component, rouleur->regmap); + + rouleur->fw_data = devm_kzalloc(component->dev, + sizeof(*(rouleur->fw_data)), + GFP_KERNEL); + if (!rouleur->fw_data) { + dev_err(component->dev, "Failed to allocate fw_data\n"); + ret = -ENOMEM; + goto done; + } + + set_bit(WCD9XXX_MBHC_CAL, rouleur->fw_data->cal_bit); + ret = wcd_cal_create_hwdep(rouleur->fw_data, + WCD9XXX_CODEC_HWDEP_NODE, component); + + if (ret < 0) { + dev_err(component->dev, "%s hwdep failed %d\n", __func__, ret); + goto done; + } + + ret = rouleur_mbhc_init(&rouleur->mbhc, component, rouleur->fw_data); + if (ret) { + pr_err("%s: mbhc initialization failed\n", __func__); + goto done; + } + snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "IN1_HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "IN2_HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "ADC1_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "ADC2_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "EAR"); + snd_soc_dapm_ignore_suspend(dapm, "LO"); + snd_soc_dapm_ignore_suspend(dapm, "HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC1_OUTPUT"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC2_OUTPUT"); + snd_soc_dapm_sync(dapm); + + rouleur_init_reg(component); + + rouleur->version = ROULEUR_VERSION_1_0; + /* Register event notifier */ + rouleur->nblock.notifier_call = rouleur_event_notify; + if (rouleur->register_notifier) { + ret = rouleur->register_notifier(rouleur->handle, + &rouleur->nblock, + true); + if (ret) { + dev_err(component->dev, + "%s: Failed to register notifier %d\n", + __func__, ret); + return ret; + } + } +done: + return ret; +} + +static void rouleur_soc_codec_remove(struct snd_soc_component *component) +{ + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + + if (!rouleur) + return; + + if (rouleur->register_notifier) + rouleur->register_notifier(rouleur->handle, + &rouleur->nblock, + false); +} + +static const struct snd_soc_component_driver soc_codec_dev_rouleur = { + .name = DRV_NAME, + .probe = rouleur_soc_codec_probe, + .remove = rouleur_soc_codec_remove, + .controls = rouleur_snd_controls, + .num_controls = ARRAY_SIZE(rouleur_snd_controls), + .dapm_widgets = rouleur_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(rouleur_dapm_widgets), + .dapm_routes = rouleur_audio_map, + .num_dapm_routes = ARRAY_SIZE(rouleur_audio_map), +}; + +#ifdef CONFIG_PM_SLEEP +static int rouleur_suspend(struct device *dev) +{ + struct rouleur_priv *rouleur = NULL; + int ret = 0; + struct rouleur_pdata *pdata = NULL; + + if (!dev) + return -ENODEV; + + rouleur = dev_get_drvdata(dev); + if (!rouleur) + return -EINVAL; + + pdata = dev_get_platdata(rouleur->dev); + + if (!pdata) { + dev_err(dev, "%s: pdata is NULL\n", __func__); + return -EINVAL; + } + + if (test_bit(ALLOW_VPOS_DISABLE, &rouleur->status_mask)) { + ret = msm_cdc_disable_ondemand_supply(rouleur->dev, + rouleur->supplies, + pdata->regulator, + pdata->num_supplies, + "cdc-pa-vpos"); + if (ret == -EINVAL) { + dev_err(dev, "%s: pa vpos is not disabled\n", + __func__); + return 0; + } + clear_bit(ALLOW_VPOS_DISABLE, &rouleur->status_mask); + } + return 0; +} + +static int rouleur_resume(struct device *dev) +{ + return 0; +} +#endif + +static int rouleur_reset(struct device *dev, int reset_val) +{ + struct rouleur_priv *rouleur = NULL; + + if (!dev) + return -ENODEV; + + rouleur = dev_get_drvdata(dev); + if (!rouleur) + return -EINVAL; + + pm2250_spmi_write(rouleur->spmi_dev, rouleur->reset_reg, reset_val); + + return 0; +} + +static int rouleur_read_of_property_u32(struct device *dev, const char *name, + u32 *val) +{ + int rc = 0; + + rc = of_property_read_u32(dev->of_node, name, val); + if (rc) + dev_err(dev, "%s: Looking up %s property in node %s failed\n", + __func__, name, dev->of_node->full_name); + + return rc; +} + +static void rouleur_dt_parse_micbias_info(struct device *dev, + struct rouleur_micbias_setting *mb) +{ + u32 prop_val = 0; + int rc = 0; + + /* MB1 */ + if (of_find_property(dev->of_node, "qcom,cdc-micbias1-mv", + NULL)) { + rc = rouleur_read_of_property_u32(dev, + "qcom,cdc-micbias1-mv", + &prop_val); + if (!rc) + mb->micb1_mv = prop_val; + } else { + dev_info(dev, "%s: Micbias1 DT property not found\n", + __func__); + } + + /* MB2 */ + if (of_find_property(dev->of_node, "qcom,cdc-micbias2-mv", + NULL)) { + rc = rouleur_read_of_property_u32(dev, + "qcom,cdc-micbias2-mv", + &prop_val); + if (!rc) + mb->micb2_mv = prop_val; + } else { + dev_info(dev, "%s: Micbias2 DT property not found\n", + __func__); + } + + /* MB3 */ + if (of_find_property(dev->of_node, "qcom,cdc-micbias3-mv", + NULL)) { + rc = rouleur_read_of_property_u32(dev, + "qcom,cdc-micbias3-mv", + &prop_val); + if (!rc) + mb->micb3_mv = prop_val; + } else { + dev_info(dev, "%s: Micbias3 DT property not found\n", + __func__); + } +} + +struct rouleur_pdata *rouleur_populate_dt_data(struct device *dev) +{ + struct rouleur_pdata *pdata = NULL; + u32 reg; + int ret = 0; + + pdata = kzalloc(sizeof(struct rouleur_pdata), + GFP_KERNEL); + if (!pdata) + return NULL; + + pdata->spmi_np = of_parse_phandle(dev->of_node, + "qcom,pmic-spmi-node", 0); + if (!pdata->spmi_np) { + dev_err(dev, "%s: Looking up %s property in node %s failed\n", + __func__, "qcom,pmic-spmi-node", + dev->of_node->full_name); + kfree(pdata); + return NULL; + } + + ret = of_property_read_u32(dev->of_node, "qcom,wcd-reset-reg", ®); + if (ret) { + dev_err(dev, "%s: Failed to obtain reset reg value %d\n", + __func__, ret); + kfree(pdata); + return NULL; + } + pdata->reset_reg = reg; + + /* Parse power supplies */ + msm_cdc_get_power_supplies(dev, &pdata->regulator, + &pdata->num_supplies); + if (!pdata->regulator || (pdata->num_supplies <= 0)) { + dev_err(dev, "%s: no power supplies defined for codec\n", + __func__); + kfree(pdata); + return NULL; + } + + pdata->rx_slave = of_parse_phandle(dev->of_node, "qcom,rx-slave", 0); + pdata->tx_slave = of_parse_phandle(dev->of_node, "qcom,tx-slave", 0); + rouleur_dt_parse_micbias_info(dev, &pdata->micbias); + + return pdata; +} + +static int rouleur_wakeup(void *handle, bool enable) +{ + struct rouleur_priv *priv; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + priv = (struct rouleur_priv *)handle; + if (!priv->tx_swr_dev) { + pr_err("%s: tx swr dev is NULL\n", __func__); + return -EINVAL; + } + if (enable) + return swr_device_wakeup_vote(priv->tx_swr_dev); + else + return swr_device_wakeup_unvote(priv->tx_swr_dev); +} + +static irqreturn_t rouleur_wd_handle_irq(int irq, void *data) +{ + pr_err_ratelimited("%s: Watchdog interrupt for irq =%d triggered\n", + __func__, irq); + return IRQ_HANDLED; +} + +static int rouleur_bind(struct device *dev) +{ + int ret = 0, i = 0; + struct rouleur_priv *rouleur = NULL; + struct rouleur_pdata *pdata = NULL; + struct wcd_ctrl_platform_data *plat_data = NULL; + struct platform_device *pdev = NULL; + + rouleur = kzalloc(sizeof(struct rouleur_priv), GFP_KERNEL); + if (!rouleur) + return -ENOMEM; + + dev_set_drvdata(dev, rouleur); + + pdata = rouleur_populate_dt_data(dev); + if (!pdata) { + dev_err(dev, "%s: Fail to obtain platform data\n", __func__); + kfree(rouleur); + return -EINVAL; + } + rouleur->dev = dev; + rouleur->dev->platform_data = pdata; + pdev = of_find_device_by_node(pdata->spmi_np); + if (!pdev) { + dev_err(dev, "%s: platform device from SPMI node is NULL\n", + __func__); + ret = -EINVAL; + goto err_bind_all; + } + + rouleur->spmi_dev = &pdev->dev; + rouleur->reset_reg = pdata->reset_reg; + ret = msm_cdc_init_supplies(dev, &rouleur->supplies, + pdata->regulator, pdata->num_supplies); + if (!rouleur->supplies) { + dev_err(dev, "%s: Cannot init wcd supplies\n", + __func__); + goto err_bind_all; + } + + plat_data = dev_get_platdata(dev->parent); + if (!plat_data) { + dev_err(dev, "%s: platform data from parent is NULL\n", + __func__); + ret = -EINVAL; + goto err_bind_all; + } + rouleur->handle = (void *)plat_data->handle; + if (!rouleur->handle) { + dev_err(dev, "%s: handle is NULL\n", __func__); + ret = -EINVAL; + goto err_bind_all; + } + rouleur->update_wcd_event = plat_data->update_wcd_event; + if (!rouleur->update_wcd_event) { + dev_err(dev, "%s: update_wcd_event api is null!\n", + __func__); + ret = -EINVAL; + goto err_bind_all; + } + rouleur->register_notifier = plat_data->register_notifier; + if (!rouleur->register_notifier) { + dev_err(dev, "%s: register_notifier api is null!\n", + __func__); + ret = -EINVAL; + goto err_bind_all; + } + + ret = msm_cdc_enable_static_supplies(dev, rouleur->supplies, + pdata->regulator, + pdata->num_supplies); + if (ret) { + dev_err(dev, "%s: wcd static supply enable failed!\n", + __func__); + goto err_bind_all; + } + + rouleur_reset(dev, 0x01); + usleep_range(20, 30); + rouleur_reset(dev, 0x00); + /* + * Add 5msec delay to provide sufficient time for + * soundwire auto enumeration of slave devices as + * as per HW requirement. + */ + usleep_range(5000, 5010); + rouleur->wakeup = rouleur_wakeup; + + ret = component_bind_all(dev, rouleur); + if (ret) { + dev_err(dev, "%s: Slave bind failed, ret = %d\n", + __func__, ret); + goto err_bind_all; + } + + ret = rouleur_parse_port_mapping(dev, "qcom,rx_swr_ch_map", CODEC_RX); + ret |= rouleur_parse_port_mapping(dev, "qcom,tx_swr_ch_map", CODEC_TX); + + if (ret) { + dev_err(dev, "Failed to read port mapping\n"); + goto err; + } + + rouleur->rx_swr_dev = get_matching_swr_slave_device(pdata->rx_slave); + if (!rouleur->rx_swr_dev) { + dev_err(dev, "%s: Could not find RX swr slave device\n", + __func__); + ret = -ENODEV; + goto err; + } + + rouleur->tx_swr_dev = get_matching_swr_slave_device(pdata->tx_slave); + if (!rouleur->tx_swr_dev) { + dev_err(dev, "%s: Could not find TX swr slave device\n", + __func__); + ret = -ENODEV; + goto err; + } + + rouleur->regmap = devm_regmap_init_swr(rouleur->tx_swr_dev, + &rouleur_regmap_config); + if (!rouleur->regmap) { + dev_err(dev, "%s: Regmap init failed\n", + __func__); + goto err; + } + + /* Set all interupts as edge triggered */ + for (i = 0; i < rouleur_regmap_irq_chip.num_regs; i++) + regmap_write(rouleur->regmap, + (ROULEUR_DIG_SWR_INTR_LEVEL_0 + i), 0); + + rouleur_regmap_irq_chip.irq_drv_data = rouleur; + rouleur->irq_info.wcd_regmap_irq_chip = &rouleur_regmap_irq_chip; + rouleur->irq_info.codec_name = "rouleur"; + rouleur->irq_info.regmap = rouleur->regmap; + rouleur->irq_info.dev = dev; + ret = wcd_irq_init(&rouleur->irq_info, &rouleur->virq); + + if (ret) { + dev_err(dev, "%s: IRQ init failed: %d\n", + __func__, ret); + goto err; + } + rouleur->tx_swr_dev->slave_irq = rouleur->virq; + + mutex_init(&rouleur->micb_lock); + mutex_init(&rouleur->main_bias_lock); + mutex_init(&rouleur->rx_clk_lock); + + ret = rouleur_set_micbias_data(rouleur, pdata); + if (ret < 0) { + dev_err(dev, "%s: bad micbias pdata\n", __func__); + goto err_irq; + } + + /* Request for watchdog interrupt */ + wcd_request_irq(&rouleur->irq_info, ROULEUR_IRQ_HPHR_PDM_WD_INT, + "HPHR PDM WD INT", rouleur_wd_handle_irq, NULL); + wcd_request_irq(&rouleur->irq_info, ROULEUR_IRQ_HPHL_PDM_WD_INT, + "HPHL PDM WD INT", rouleur_wd_handle_irq, NULL); + /* Disable watchdog interrupt for HPH */ + wcd_disable_irq(&rouleur->irq_info, ROULEUR_IRQ_HPHR_PDM_WD_INT); + wcd_disable_irq(&rouleur->irq_info, ROULEUR_IRQ_HPHL_PDM_WD_INT); + + ret = snd_soc_register_component(dev, &soc_codec_dev_rouleur, + NULL, 0); + if (ret) { + dev_err(dev, "%s: Codec registration failed\n", + __func__); + goto err_irq; + } + + return ret; +err_irq: + wcd_irq_exit(&rouleur->irq_info, rouleur->virq); + mutex_destroy(&rouleur->micb_lock); + mutex_destroy(&rouleur->main_bias_lock); + mutex_destroy(&rouleur->rx_clk_lock); +err: + component_unbind_all(dev, rouleur); +err_bind_all: + dev_set_drvdata(dev, NULL); + kfree(pdata); + kfree(rouleur); + return ret; +} + +static void rouleur_unbind(struct device *dev) +{ + struct rouleur_priv *rouleur = dev_get_drvdata(dev); + struct rouleur_pdata *pdata = dev_get_platdata(rouleur->dev); + + wcd_irq_exit(&rouleur->irq_info, rouleur->virq); + snd_soc_unregister_component(dev); + component_unbind_all(dev, rouleur); + mutex_destroy(&rouleur->micb_lock); + mutex_destroy(&rouleur->main_bias_lock); + mutex_destroy(&rouleur->rx_clk_lock); + dev_set_drvdata(dev, NULL); + kfree(pdata); + kfree(rouleur); +} + +static const struct of_device_id rouleur_dt_match[] = { + { .compatible = "qcom,rouleur-codec" }, + {} +}; + +static const struct component_master_ops rouleur_comp_ops = { + .bind = rouleur_bind, + .unbind = rouleur_unbind, +}; + +static int rouleur_compare_of(struct device *dev, void *data) +{ + return dev->of_node == data; +} + +static void rouleur_release_of(struct device *dev, void *data) +{ + of_node_put(data); +} + +static int rouleur_add_slave_components(struct device *dev, + struct component_match **matchptr) +{ + struct device_node *np, *rx_node, *tx_node; + + np = dev->of_node; + + rx_node = of_parse_phandle(np, "qcom,rx-slave", 0); + if (!rx_node) { + dev_err(dev, "%s: Rx-slave node not defined\n", __func__); + return -ENODEV; + } + of_node_get(rx_node); + component_match_add_release(dev, matchptr, + rouleur_release_of, + rouleur_compare_of, + rx_node); + + tx_node = of_parse_phandle(np, "qcom,tx-slave", 0); + if (!tx_node) { + dev_err(dev, "%s: Tx-slave node not defined\n", __func__); + return -ENODEV; + } + of_node_get(tx_node); + component_match_add_release(dev, matchptr, + rouleur_release_of, + rouleur_compare_of, + tx_node); + return 0; +} + +static int rouleur_probe(struct platform_device *pdev) +{ + struct component_match *match = NULL; + int ret; + + ret = rouleur_add_slave_components(&pdev->dev, &match); + if (ret) + return ret; + + return component_master_add_with_match(&pdev->dev, + &rouleur_comp_ops, match); +} + +static int rouleur_remove(struct platform_device *pdev) +{ + component_master_del(&pdev->dev, &rouleur_comp_ops); + dev_set_drvdata(&pdev->dev, NULL); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static const struct dev_pm_ops rouleur_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS( + rouleur_suspend, + rouleur_resume + ) +}; +#endif + +static struct platform_driver rouleur_codec_driver = { + .probe = rouleur_probe, + .remove = rouleur_remove, + .driver = { + .name = "rouleur_codec", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(rouleur_dt_match), +#ifdef CONFIG_PM_SLEEP + .pm = &rouleur_dev_pm_ops, +#endif + .suppress_bind_attrs = true, + }, +}; + +module_platform_driver(rouleur_codec_driver); +MODULE_DESCRIPTION("Rouleur Codec driver"); +MODULE_LICENSE("GPL v2"); + diff --git a/asoc/codecs/rouleur/rouleur.h b/asoc/codecs/rouleur/rouleur.h new file mode 100644 index 000000000000..51abff3a3a64 --- /dev/null +++ b/asoc/codecs/rouleur/rouleur.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _ROULEUR_H +#define _ROULEUR_H + +#ifdef CONFIG_SND_SOC_ROULEUR +extern int rouleur_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_component *component); +#else +extern int rouleur_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_component *component) +{ + return 0; +} +#endif /* CONFIG_SND_SOC_ROULEUR */ + +#endif diff --git a/asoc/codecs/rouleur/rouleur_slave.c b/asoc/codecs/rouleur/rouleur_slave.c new file mode 100644 index 000000000000..8fac8a6fbf25 --- /dev/null +++ b/asoc/codecs/rouleur/rouleur_slave.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include + +struct rouleur_slave_priv { + struct swr_device *swr_slave; +}; + +static int rouleur_slave_bind(struct device *dev, + struct device *master, void *data) +{ + int ret = 0; + struct rouleur_slave_priv *rouleur_slave = NULL; + uint8_t devnum = 0; + struct swr_device *pdev = to_swr_device(dev); + + if (pdev == NULL) { + dev_err(dev, "%s: pdev is NULL\n", __func__); + return -EINVAL; + } + + rouleur_slave = devm_kzalloc(&pdev->dev, + sizeof(struct rouleur_slave_priv), GFP_KERNEL); + if (!rouleur_slave) + return -ENOMEM; + + swr_set_dev_data(pdev, rouleur_slave); + + rouleur_slave->swr_slave = pdev; + + ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum); + if (ret) { + dev_dbg(&pdev->dev, + "%s get devnum %d for dev addr %lx failed\n", + __func__, devnum, pdev->addr); + swr_remove_device(pdev); + return ret; + } + pdev->dev_num = devnum; + + return ret; +} + +static void rouleur_slave_unbind(struct device *dev, + struct device *master, void *data) +{ + struct rouleur_slave_priv *rouleur_slave = NULL; + struct swr_device *pdev = to_swr_device(dev); + + if (pdev == NULL) { + dev_err(dev, "%s: pdev is NULL\n", __func__); + return; + } + + rouleur_slave = swr_get_dev_data(pdev); + if (!rouleur_slave) { + dev_err(&pdev->dev, "%s: rouleur_slave is NULL\n", __func__); + return; + } + + swr_set_dev_data(pdev, NULL); +} + +static const struct swr_device_id rouleur_swr_id[] = { + {"rouleur-slave", 0}, + {} +}; + +static const struct of_device_id rouleur_swr_dt_match[] = { + { + .compatible = "qcom,rouleur-slave", + }, + {} +}; + +static const struct component_ops rouleur_slave_comp_ops = { + .bind = rouleur_slave_bind, + .unbind = rouleur_slave_unbind, +}; + +static int rouleur_swr_up(struct swr_device *pdev) +{ + return 0; +} + +static int rouleur_swr_down(struct swr_device *pdev) +{ + return 0; +} + +static int rouleur_swr_reset(struct swr_device *pdev) +{ + return 0; +} + +static int rouleur_swr_probe(struct swr_device *pdev) +{ + return component_add(&pdev->dev, &rouleur_slave_comp_ops); +} + +static int rouleur_swr_remove(struct swr_device *pdev) +{ + component_del(&pdev->dev, &rouleur_slave_comp_ops); + return 0; +} + +static struct swr_driver rouleur_slave_driver = { + .driver = { + .name = "rouleur-slave", + .owner = THIS_MODULE, + .of_match_table = rouleur_swr_dt_match, + }, + .probe = rouleur_swr_probe, + .remove = rouleur_swr_remove, + .id_table = rouleur_swr_id, + .device_up = rouleur_swr_up, + .device_down = rouleur_swr_down, + .reset_device = rouleur_swr_reset, +}; + +static int __init rouleur_slave_init(void) +{ + return swr_driver_register(&rouleur_slave_driver); +} + +static void __exit rouleur_slave_exit(void) +{ + swr_driver_unregister(&rouleur_slave_driver); +} + +module_init(rouleur_slave_init); +module_exit(rouleur_slave_exit); + +MODULE_DESCRIPTION("WCD937X Swr Slave driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 7ad7274bb0704e82467fe6aadf939e43607c2c53 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 4 Mar 2020 22:19:33 +0530 Subject: [PATCH 1424/1645] asoc: bolero: Avoid reg access if audio hw vote fails Check audio hw vote before register access. Change-Id: I2753f6abd912910285f586bf95c71e3c99dfe60a Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 49fd1fcb9258..2db0c5b30a35 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -101,8 +101,11 @@ static int __bolero_reg_read(struct bolero_priv *priv, goto ssr_err; } - if (priv->macro_params[VA_MACRO].dev) + if (priv->macro_params[VA_MACRO].dev) { pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev); + if (!bolero_check_core_votes(priv->macro_params[VA_MACRO].dev)) + goto ssr_err; + } if (priv->version < BOLERO_VERSION_2_0) { /* Request Clk before register access */ @@ -149,8 +152,11 @@ static int __bolero_reg_write(struct bolero_priv *priv, ret = -EINVAL; goto ssr_err; } - if (priv->macro_params[VA_MACRO].dev) + if (priv->macro_params[VA_MACRO].dev) { pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev); + if (!bolero_check_core_votes(priv->macro_params[VA_MACRO].dev)) + goto ssr_err; + } if (priv->version < BOLERO_VERSION_2_0) { /* Request Clk before register access */ -- GitLab From d6f7f843d9824289f2d48efec23638f1e80a66a8 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 12 Mar 2020 11:23:50 +0530 Subject: [PATCH 1425/1645] asoc: rouleur: Enable rouleur codec driver compilation Add changes to enable compilation for rouleur codec driver. Change-Id: I87eefe0c3d9bbe6445391902110fb210c4b0cd5b Signed-off-by: Aditya Bavanari --- Android.mk | 5 +++++ asoc/codecs/Kbuild | 1 + config/bengalauto.conf | 3 +++ config/bengalautoconf.h | 3 +++ 4 files changed, 12 insertions(+) diff --git a/Android.mk b/Android.mk index 6c43c4e9b3f9..f5b893185db7 100644 --- a/Android.mk +++ b/Android.mk @@ -47,6 +47,11 @@ include $(MY_LOCAL_PATH)/asoc/codecs/wcd937x/Android.mk endif endif +ifeq ($(call is-board-platform-in-list, bengal),true) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/rouleur/Module.symvers) +include $(MY_LOCAL_PATH)/asoc/codecs/rouleur/Android.mk +endif + ifeq ($(call is-board-platform-in-list, kona lito),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/bolero/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/bolero/Android.mk diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 1ce059ec7012..7a2cfcd217b0 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -226,6 +226,7 @@ ifeq ($(KERNEL_BUILD), 1) obj-y += wcd937x/ obj-y += wcd938x/ obj-y += bolero/ + obj-y += rouleur/ endif # Module information used by KBuild framework obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd_core_dlkm.o diff --git a/config/bengalauto.conf b/config/bengalauto.conf index d6fdadd7a5f3..0478ecadfb65 100644 --- a/config/bengalauto.conf +++ b/config/bengalauto.conf @@ -30,5 +30,8 @@ CONFIG_TX_MACRO=m CONFIG_SND_SOC_WCD_IRQ=m CONFIG_SND_SOC_WCD937X=m CONFIG_SND_SOC_WCD937X_SLAVE=m +CONFIG_SND_SOC_ROULEUR=m +CONFIG_SND_SOC_ROULEUR_SLAVE=m +CONFIG_PM2250_SPMI=m CONFIG_SND_SOC_BENGAL=m CONFIG_SND_EVENT=m diff --git a/config/bengalautoconf.h b/config/bengalautoconf.h index 90d3e3c52448..3e72903c0af5 100644 --- a/config/bengalautoconf.h +++ b/config/bengalautoconf.h @@ -34,5 +34,8 @@ #define CONFIG_SND_SOC_WCD_IRQ 1 #define CONFIG_SND_SOC_WCD937X 1 #define CONFIG_SND_SOC_WCD937X_SLAVE 1 +#define CONFIG_SND_SOC_ROULEUR 1 +#define CONFIG_SND_SOC_ROULEUR_SLAVE 1 +#define CONFIG_PM2250_SPMI 1 #define CONFIG_SND_SOC_BENGAL 1 #define CONFIG_SND_EVENT 1 -- GitLab From 707bf359536dcaeeca6f42e9107205d65182fad5 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 12 Mar 2020 12:30:10 +0530 Subject: [PATCH 1426/1645] asoc: Add support for rouleur codec in machine driver Add rouleur codec support in bengal machine driver to create codec entry and invoke mbhc hs detect functions for respective codecs. Correct the logic for headset detection pull up current and volatile registers for digital part of rouleur codec. Change-Id: I22545dc796c215c1501e883796546c97d8ca8698 Signed-off-by: Aditya Bavanari --- asoc/bengal.c | 45 ++++++++++++++++++++++++++-- asoc/codecs/rouleur/rouleur-mbhc.c | 4 +-- asoc/codecs/rouleur/rouleur-regmap.c | 2 -- asoc/codecs/rouleur/rouleur.c | 2 +- asoc/codecs/wcd937x/wcd937x.c | 2 +- 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/asoc/bengal.c b/asoc/bengal.c index dcdf1ed1ed31..1ab7f9951b43 100644 --- a/asoc/bengal.c +++ b/asoc/bengal.c @@ -31,8 +31,10 @@ #include "asoc/msm-cdc-pinctrl.h" #include "asoc/wcd-mbhc-v2.h" #include "codecs/wcd937x/wcd937x-mbhc.h" +#include "codecs/rouleur/rouleur-mbhc.h" #include "codecs/wsa881x-analog.h" #include "codecs/wcd937x/wcd937x.h" +#include "codecs/rouleur/rouleur.h" #include "codecs/bolero/bolero-cdc.h" #include #include "bengal-port-config.h" @@ -5995,9 +5997,13 @@ static int msm_aux_codec_init(struct snd_soc_component *component) struct snd_info_entry *entry; struct snd_card *card = component->card->snd_card; struct msm_asoc_mach_data *pdata; + struct platform_device *pdev = NULL; + char *data = NULL; + int i = 0; snd_soc_dapm_ignore_suspend(dapm, "EAR"); snd_soc_dapm_ignore_suspend(dapm, "AUX"); + snd_soc_dapm_ignore_suspend(dapm, "LO"); snd_soc_dapm_ignore_suspend(dapm, "HPHL"); snd_soc_dapm_ignore_suspend(dapm, "HPHR"); snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); @@ -6018,14 +6024,49 @@ static int msm_aux_codec_init(struct snd_soc_component *component) } pdata->codec_root = entry; } - wcd937x_info_create_codec_entry(pdata->codec_root, component); + + for (i = 0; i < component->card->num_aux_devs; i++) + { + if (msm_aux_dev[i].name != NULL ) { + if (strstr(msm_aux_dev[i].name, "wsa")) + continue; + } + + if (msm_aux_dev[i].codec_of_node) { + pdev = of_find_device_by_node( + msm_aux_dev[i].codec_of_node); + if (pdev) + data = (char*) of_device_get_match_data( + &pdev->dev); + + if (data != NULL) { + if (!strncmp(data, "wcd937x", + sizeof("wcd937x"))) { + wcd937x_info_create_codec_entry( + pdata->codec_root, component); + break; + } else if (!strncmp(data, "rouleur", + sizeof("rouleur"))) { + rouleur_info_create_codec_entry( + pdata->codec_root, component); + break; + } + } + } + } mbhc_cfg_cal: mbhc_calibration = def_wcd_mbhc_cal(); if (!mbhc_calibration) return -ENOMEM; wcd_mbhc_cfg.calibration = mbhc_calibration; - ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg); + if (data != NULL) { + if (!strncmp(data, "wcd937x", sizeof("wcd937x"))) + ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg); + else if (!strncmp( data, "rouleur", sizeof("rouleur"))) + ret = rouleur_mbhc_hs_detect(component, &wcd_mbhc_cfg); + } + if (ret) { dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n", __func__, ret); diff --git a/asoc/codecs/rouleur/rouleur-mbhc.c b/asoc/codecs/rouleur/rouleur-mbhc.c index 3e3ef51140bf..2e1db78df68e 100644 --- a/asoc/codecs/rouleur/rouleur-mbhc.c +++ b/asoc/codecs/rouleur/rouleur-mbhc.c @@ -291,14 +291,14 @@ static void rouleur_mbhc_hph_l_pull_up_control( /* Default pull up current to 2uA */ if (pull_up_cur < I_OFF || pull_up_cur > I_3P0_UA || pull_up_cur == I_DEFAULT) - pull_up_cur = I_2P0_UA; + pull_up_cur = I_3P0_UA; dev_dbg(component->dev, "%s: HS pull up current:%d\n", __func__, pull_up_cur); snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_PLUG_DETECT_CTL, - 0xC0, pull_up_cur); + 0xC0, pull_up_cur << 6); } static int rouleur_mbhc_request_micbias(struct snd_soc_component *component, diff --git a/asoc/codecs/rouleur/rouleur-regmap.c b/asoc/codecs/rouleur/rouleur-regmap.c index 62502140ee99..39982bd20537 100644 --- a/asoc/codecs/rouleur/rouleur-regmap.c +++ b/asoc/codecs/rouleur/rouleur-regmap.c @@ -134,13 +134,11 @@ static bool rouleur_volatile_register(struct device *dev, unsigned int reg) if ((rouleur_reg_access_analog[ROULEUR_REG(reg)] & RD_REG) && !(rouleur_reg_access_analog[ROULEUR_REG(reg)] & WR_REG)) return true; - return false; if (reg > ROULEUR_DIG_BASE_ADDR && reg < ROULEUR_DIGITAL_REGISTERS_MAX_SIZE) if ((rouleur_reg_access_digital[ROULEUR_REG(reg)] & RD_REG) && !(rouleur_reg_access_digital[ROULEUR_REG(reg)] & WR_REG)) return true; - return false; return 0; } diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index 14dfd52f49fb..768b5e3455f2 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -2392,7 +2392,7 @@ static void rouleur_unbind(struct device *dev) } static const struct of_device_id rouleur_dt_match[] = { - { .compatible = "qcom,rouleur-codec" }, + { .compatible = "qcom,rouleur-codec" , .data = "rouleur" }, {} }; diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 01965391d4d9..5c3f14f84b9f 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -3007,7 +3007,7 @@ static void wcd937x_unbind(struct device *dev) } static const struct of_device_id wcd937x_dt_match[] = { - { .compatible = "qcom,wcd937x-codec" }, + { .compatible = "qcom,wcd937x-codec" , .data = "wcd937x" }, {} }; -- GitLab From 63bdc7bdab7a4a48c4cac89b95fceb8b37d55202 Mon Sep 17 00:00:00 2001 From: Sanjana B Date: Mon, 20 Jan 2020 19:31:18 +0530 Subject: [PATCH 1427/1645] asoc: support for audio over hdmi tx Add support for audio over hdmi tx. Change-Id: I4f2108fd14eb22ec4e226220787e0defe512bb5f Signed-off-by: Sanjana B --- asoc/codecs/msm_hdmi_codec_rx.c | 99 ++++++++++++++++++---- asoc/msm-dai-q6-hdmi-v2.c | 34 +++++++- asoc/msm-pcm-routing-v2.c | 141 +++++++++++++++++++++++++++++++- asoc/msm-pcm-routing-v2.h | 4 +- dsp/q6afe.c | 5 ++ dsp/q6audio-v2.c | 4 + include/dsp/apr_audio-v2.h | 3 + include/dsp/q6afe-v2.h | 2 + 8 files changed, 271 insertions(+), 21 deletions(-) diff --git a/asoc/codecs/msm_hdmi_codec_rx.c b/asoc/codecs/msm_hdmi_codec_rx.c index 1588c567675a..609dd45ea318 100644 --- a/asoc/codecs/msm_hdmi_codec_rx.c +++ b/asoc/codecs/msm_hdmi_codec_rx.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include #include @@ -25,8 +25,8 @@ static SOC_ENUM_SINGLE_DECL(ext_disp_audio_ack_state##index, \ SND_SOC_NOPM, index, ext_disp_audio_ack_text) -#define SWITCH_DP_CODEC(codec_info, codec_data, dai_id) \ - codec_info.type = EXT_DISPLAY_TYPE_DP; \ +#define SWITCH_DP_CODEC(codec_info, codec_data, dai_id, type) \ + codec_info.type = type; \ codec_info.ctrl_id = codec_data->ctl[dai_id]; \ codec_info.stream_id = codec_data->stream[dai_id]; \ @@ -38,6 +38,7 @@ enum { enum { DP_STREAM0 = 0, DP_STREAM1, + HDMI, DP_STREAM_MAX, }; @@ -49,6 +50,7 @@ enum { DP_DAI1 = 1, DP_DAI2, HDMI_DAI, + HDMI_MS_DAI, DP_DAI_MAX, }; @@ -60,6 +62,8 @@ SOC_EXT_DISP_AUDIO_TYPE(1); SOC_EXT_DISP_AUDIO_ACK_STATE(1); SOC_EXT_DISP_AUDIO_TYPE(2); SOC_EXT_DISP_AUDIO_ACK_STATE(2); +SOC_EXT_DISP_AUDIO_TYPE(3); +SOC_EXT_DISP_AUDIO_ACK_STATE(3); struct msm_ext_disp_audio_codec_rx_data { struct platform_device *ext_disp_core_pdev; @@ -80,6 +84,7 @@ static int msm_ext_disp_edid_ctl_info(struct snd_kcontrol *kcontrol, int rc = 0; struct msm_ext_disp_codec_id codec_info; int dai_id = kcontrol->private_value; + int type; codec_data = snd_soc_component_get_drvdata(component); if (!codec_data) { @@ -91,7 +96,11 @@ static int msm_ext_disp_edid_ctl_info(struct snd_kcontrol *kcontrol, codec_data->ctl[dai_id], codec_data->stream[dai_id]); mutex_lock(&codec_data->dp_ops_lock); - SWITCH_DP_CODEC(codec_info, codec_data, dai_id); + if (dai_id == HDMI_MS_DAI) + type = EXT_DISPLAY_TYPE_HDMI; + else + type = EXT_DISPLAY_TYPE_DP; + SWITCH_DP_CODEC(codec_info, codec_data, dai_id, type); rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, &codec_info); if (!codec_data->ext_disp_ops.get_audio_edid_blk || rc) { @@ -126,6 +135,7 @@ static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol, struct msm_ext_disp_codec_id codec_info; int rc = 0; int dai_id = kcontrol->private_value; + int type; codec_data = snd_soc_component_get_drvdata(component); if (!codec_data) { @@ -138,7 +148,11 @@ static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol, codec_data->ctl[dai_id], codec_data->stream[dai_id]); mutex_lock(&codec_data->dp_ops_lock); - SWITCH_DP_CODEC(codec_info, codec_data, dai_id); + if (dai_id == HDMI_MS_DAI) + type = EXT_DISPLAY_TYPE_HDMI; + else + type = EXT_DISPLAY_TYPE_DP; + SWITCH_DP_CODEC(codec_info, codec_data, dai_id, type); rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, &codec_info); if (!codec_data->ext_disp_ops.get_audio_edid_blk || rc) { @@ -147,7 +161,6 @@ static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol, mutex_unlock(&codec_data->dp_ops_lock); return -EINVAL; } - rc = codec_data->ext_disp_ops.get_audio_edid_blk( codec_data->ext_disp_core_pdev, &edid_blk); mutex_unlock(&codec_data->dp_ops_lock); @@ -188,6 +201,7 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, struct msm_ext_disp_codec_id codec_info; int rc = 0; int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l; + int type; codec_data = snd_soc_component_get_drvdata(component); if (!codec_data) { @@ -200,7 +214,11 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, codec_data->ctl[dai_id], codec_data->stream[dai_id]); mutex_lock(&codec_data->dp_ops_lock); - SWITCH_DP_CODEC(codec_info, codec_data, dai_id); + if (dai_id == HDMI_MS_DAI) + type = EXT_DISPLAY_TYPE_HDMI; + else + type = EXT_DISPLAY_TYPE_DP; + SWITCH_DP_CODEC(codec_info, codec_data, dai_id, type); rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, &codec_info); @@ -213,7 +231,7 @@ static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol, } cable_state = codec_data->ext_disp_ops.cable_status( - codec_data->ext_disp_core_pdev, 1); + codec_data->ext_disp_core_pdev, 1); if (cable_state < 0) { dev_err(component->dev, "%s: Error retrieving cable state from ext_disp, err:%d\n", __func__, cable_state); @@ -274,6 +292,7 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, struct msm_ext_disp_codec_id codec_info; int rc = 0; int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l; + int type; codec_data = snd_soc_component_get_drvdata(component); if (!codec_data) { @@ -287,7 +306,11 @@ static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol, codec_data->ctl[dai_id], codec_data->stream[dai_id]); mutex_lock(&codec_data->dp_ops_lock); - SWITCH_DP_CODEC(codec_info, codec_data, dai_id); + if (dai_id == HDMI_MS_DAI) + type = EXT_DISPLAY_TYPE_HDMI; + else + type = EXT_DISPLAY_TYPE_DP; + SWITCH_DP_CODEC(codec_info, codec_data, dai_id, type); rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, &codec_info); @@ -421,6 +444,15 @@ static const struct snd_kcontrol_new msm_ext_disp_codec_rx_controls[] = { .get = msm_ext_disp_edid_get, .private_value = HDMI_DAI, }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ | + SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "HDMI MS EDID", + .info = msm_ext_disp_edid_ctl_info, + .get = msm_ext_disp_edid_get, + .private_value = HDMI_MS_DAI, + }, { .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, @@ -445,12 +477,18 @@ static const struct snd_kcontrol_new msm_ext_disp_codec_rx_controls[] = { SOC_ENUM_EXT("External Display1 Type", ext_disp_audio_type2, msm_ext_disp_audio_type_get, NULL), + SOC_ENUM_EXT("External HDMI Type", + ext_disp_audio_type3, + msm_ext_disp_audio_type_get, NULL), SOC_ENUM_EXT("External Display Audio Ack", ext_disp_audio_ack_state1, NULL, msm_ext_disp_audio_ack_set), SOC_ENUM_EXT("External Display1 Audio Ack", ext_disp_audio_ack_state2, NULL, msm_ext_disp_audio_ack_set), + SOC_ENUM_EXT("External HDMI Audio Ack", + ext_disp_audio_ack_state3, + NULL, msm_ext_disp_audio_ack_set), SOC_SINGLE_MULTI_EXT("External Display Audio Device", SND_SOC_NOPM, DP_DAI1, DP_STREAM_MAX - 1, 0, 2, @@ -460,6 +498,11 @@ static const struct snd_kcontrol_new msm_ext_disp_codec_rx_controls[] = { SND_SOC_NOPM, DP_DAI2, DP_STREAM_MAX - 1, 0, 2, msm_ext_disp_audio_device_get, msm_ext_disp_audio_device_set), + SOC_SINGLE_MULTI_EXT("External HDMI Device", + SND_SOC_NOPM, HDMI_MS_DAI, DP_STREAM_MAX - 1, 0, 2, + msm_ext_disp_audio_device_get, + msm_ext_disp_audio_device_set), + }; static int msm_ext_disp_audio_codec_rx_dai_startup( @@ -470,6 +513,7 @@ static int msm_ext_disp_audio_codec_rx_dai_startup( struct msm_ext_disp_codec_id codec_info; struct msm_ext_disp_audio_codec_rx_data *codec_data = dev_get_drvdata(dai->component->dev); + int type; if (!codec_data) { dev_err(dai->dev, "%s() codec_data is null\n", @@ -482,7 +526,11 @@ static int msm_ext_disp_audio_codec_rx_dai_startup( codec_data->ctl[dai->id], codec_data->stream[dai->id]); mutex_lock(&codec_data->dp_ops_lock); - SWITCH_DP_CODEC(codec_info, codec_data, dai->id); + if (dai->id == HDMI_MS_DAI) + type = EXT_DISPLAY_TYPE_HDMI; + else + type = EXT_DISPLAY_TYPE_DP; + SWITCH_DP_CODEC(codec_info, codec_data, dai->id, type); rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, &codec_info); @@ -524,7 +572,7 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params( struct msm_ext_disp_codec_id codec_info; int rc = 0; struct msm_ext_disp_audio_setup_params audio_setup_params = {0}; - + int type; struct msm_ext_disp_audio_codec_rx_data *codec_data = dev_get_drvdata(dai->component->dev); @@ -539,7 +587,11 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params( codec_data->ctl[dai->id], codec_data->stream[dai->id]); mutex_lock(&codec_data->dp_ops_lock); - SWITCH_DP_CODEC(codec_info, codec_data, dai->id); + if (dai->id == HDMI_MS_DAI) + type = EXT_DISPLAY_TYPE_HDMI; + else + type = EXT_DISPLAY_TYPE_DP; + SWITCH_DP_CODEC(codec_info, codec_data, dai->id, type); rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, &codec_info); @@ -609,7 +661,7 @@ static int msm_ext_disp_audio_codec_rx_dai_hw_params( audio_setup_params.down_mix = down_mix; mutex_lock(&codec_data->dp_ops_lock); - SWITCH_DP_CODEC(codec_info, codec_data, dai->id); + SWITCH_DP_CODEC(codec_info, codec_data, dai->id, type); rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, &codec_info); if (rc) @@ -636,6 +688,7 @@ static void msm_ext_disp_audio_codec_rx_dai_shutdown( struct msm_ext_disp_audio_codec_rx_data *codec_data = dev_get_drvdata(dai->component->dev); + int type; if (!codec_data) { dev_err(dai->dev, "%s() codec_data is null\n", @@ -648,7 +701,11 @@ static void msm_ext_disp_audio_codec_rx_dai_shutdown( codec_data->ctl[dai->id], codec_data->stream[dai->id]); mutex_lock(&codec_data->dp_ops_lock); - SWITCH_DP_CODEC(codec_info, codec_data, dai->id); + if (dai->id == HDMI_MS_DAI) + type = EXT_DISPLAY_TYPE_HDMI; + else + type = EXT_DISPLAY_TYPE_DP; + SWITCH_DP_CODEC(codec_info, codec_data, dai->id, type); rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, &codec_info); @@ -754,6 +811,20 @@ static struct snd_soc_dai_driver msm_ext_disp_audio_codec_rx_dais[] = { }, .ops = &msm_ext_disp_audio_codec_rx_dai_ops, }, + { + .name = "msm_hdmi_ms_audio_codec_rx_dai", + .id = HDMI_MS_DAI, + .playback = { + .stream_name = "HDMI MS Playback", + .channels_min = 1, + .channels_max = 8, + .rate_min = 48000, + .rate_max = 48000, + .rates = MSM_EXT_DISP_PCM_RATES, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = &msm_ext_disp_audio_codec_rx_dai_ops, + }, { .name = "msm_dp_audio_codec_rx_dai", .id = DP_DAI1, diff --git a/asoc/msm-dai-q6-hdmi-v2.c b/asoc/msm-dai-q6-hdmi-v2.c index 664169bd8bf2..42d53e721928 100644 --- a/asoc/msm-dai-q6-hdmi-v2.c +++ b/asoc/msm-dai-q6-hdmi-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -54,7 +54,7 @@ struct msm_dai_q6_hdmi_dai_data { static int get_port_id(int dai_id) { /* Currently, display devices share a common AFE port */ - if (dai_id != HDMI_RX) + if (dai_id != HDMI_RX || dai_id != HDMI_RX_MS) return DISPLAY_PORT_RX; return dai_id; @@ -436,7 +436,7 @@ static int msm_dai_q6_hdmi_dai_probe(struct snd_soc_dai *dai) msm_dai_q6_hdmi_set_dai_id(dai); - if (dai->driver->id == HDMI_RX) { + if (dai->driver->id == HDMI_RX || dai->driver->id == HDMI_RX_MS) { kcontrol = &hdmi_config_controls[0]; rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(kcontrol, dai_data)); @@ -563,6 +563,28 @@ static struct snd_soc_dai_driver msm_dai_q6_hdmi_hdmi_rx_dai = { .remove = msm_dai_q6_hdmi_dai_remove, }; +static struct snd_soc_dai_driver msm_dai_q6_hdmi_hdmi_ms_rx_dai = { + .playback = { + .stream_name = "HDMI MS Playback", + .aif_name = "HDMI_MS", + .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .channels_min = 2, + .channels_max = 8, + .rate_max = 192000, + .rate_min = 48000, + }, + .ops = &msm_dai_q6_hdmi_ops, + .id = HDMI_RX_MS, + .probe = msm_dai_q6_hdmi_dai_probe, + .remove = msm_dai_q6_hdmi_dai_remove, +}; + static struct snd_soc_dai_driver msm_dai_q6_display_port_rx_dai[] = { { .playback = { @@ -646,6 +668,12 @@ static int msm_dai_q6_hdmi_dev_probe(struct platform_device *pdev) &msm_dai_hdmi_q6_component, &msm_dai_q6_display_port_rx_dai[1], 1); break; + case HDMI_RX_MS: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_hdmi_q6_component, + &msm_dai_q6_hdmi_hdmi_ms_rx_dai, 1); + break; + default: dev_err(&pdev->dev, "invalid device ID %d\n", pdev->id); rc = -ENODEV; diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index e4e6e6f1608d..011a3d142691 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -147,6 +147,7 @@ struct msm_pcm_route_bdai_pp_params { static struct msm_pcm_route_bdai_pp_params msm_bedais_pp_params[MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX] = { {HDMI_RX, 0, 0, 0}, + {HDMI_RX_MS, 0, 0, 0}, {DISPLAY_PORT_RX, 0, 0, 0}, }; @@ -699,6 +700,7 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_SEC_META_MI2S_RX}, { RT_PROXY_PORT_002_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PROXY_RX}, { RT_PROXY_PORT_002_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_PROXY_TX}, + { HDMI_RX_MS, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_HDMI_MS}, }; /* Track ASM playback & capture sessions of DAI @@ -3534,7 +3536,7 @@ static const char *const be_name[] = { "RX_CDC_DMA_RX_6", "RX_CDC_DMA_RX_7", "PRI_SPDIF_TX", "SEC_SPDIF_RX", "SEC_SPDIF_TX", "SLIM_9_RX", "SLIM_9_TX", "AFE_LOOPBACK_TX", "PRI_META_MI2S_RX", -"SEC_META_MI2S_RX", "PROXY_RX", "PROXY_TX" +"SEC_META_MI2S_RX", "PROXY_RX", "PROXY_TX", "HDMI_RX_MS" }; static SOC_ENUM_SINGLE_DECL(mm1_channel_mux, @@ -7549,6 +7551,101 @@ static const struct snd_kcontrol_new hdmi_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new hdmi_ms_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new display_port_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, MSM_BACKEND_DAI_DISPLAY_PORT_RX, @@ -18384,6 +18481,13 @@ static const struct snd_kcontrol_new hdmi_rx_port_mixer_controls[] = { msm_routing_put_port_mixer), }; +static const struct snd_kcontrol_new hdmi_rx_ms_port_mixer_controls[] = { + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + static const struct snd_kcontrol_new display_port_rx_port_mixer_controls[] = { SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, MSM_BACKEND_DAI_DISPLAY_PORT_RX, @@ -24149,6 +24253,7 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_RX", "Slimbus2 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_RX", "Slimbus5 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("HDMI_MS", "HDMI MS Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT", "Display Port Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT1", "Display Port1 Playback", @@ -24597,6 +24702,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { slimbus_9_rx_mixer_controls, ARRAY_SIZE(slimbus_9_rx_mixer_controls)), SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0, hdmi_mixer_controls, ARRAY_SIZE(hdmi_mixer_controls)), + SND_SOC_DAPM_MIXER("HDMI_MS Mixer", SND_SOC_NOPM, 0, 0, + hdmi_ms_mixer_controls, ARRAY_SIZE(hdmi_ms_mixer_controls)), SND_SOC_DAPM_MIXER("DISPLAY_PORT Mixer", SND_SOC_NOPM, 0, 0, display_port_mixer_controls, ARRAY_SIZE(display_port_mixer_controls)), SND_SOC_DAPM_MIXER("DISPLAY_PORT1 Mixer", SND_SOC_NOPM, 0, 0, @@ -25049,6 +25156,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("HDMI_RX Port Mixer", SND_SOC_NOPM, 0, 0, hdmi_rx_port_mixer_controls, ARRAY_SIZE(hdmi_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("HDMI_RX_MS Port Mixer", + SND_SOC_NOPM, 0, 0, hdmi_rx_ms_port_mixer_controls, + ARRAY_SIZE(hdmi_rx_ms_port_mixer_controls)), SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX Port Mixer", SND_SOC_NOPM, 0, 0, display_port_rx_port_mixer_controls, ARRAY_SIZE(display_port_rx_port_mixer_controls)), @@ -25570,6 +25680,25 @@ static const struct snd_soc_dapm_route intercon[] = { {"HDMI Mixer", "MultiMedia26", "MM_DL26"}, {"HDMI", NULL, "HDMI Mixer"}, + {"HDMI_MS Mixer", "MultiMedia1", "MM_DL1"}, + {"HDMI_MS Mixer", "MultiMedia2", "MM_DL2"}, + {"HDMI_MS Mixer", "MultiMedia3", "MM_DL3"}, + {"HDMI_MS Mixer", "MultiMedia4", "MM_DL4"}, + {"HDMI_MS Mixer", "MultiMedia5", "MM_DL5"}, + {"HDMI_MS Mixer", "MultiMedia6", "MM_DL6"}, + {"HDMI_MS Mixer", "MultiMedia7", "MM_DL7"}, + {"HDMI_MS Mixer", "MultiMedia8", "MM_DL8"}, + {"HDMI_MS Mixer", "MultiMedia9", "MM_DL9"}, + {"HDMI_MS Mixer", "MultiMedia10", "MM_DL10"}, + {"HDMI_MS Mixer", "MultiMedia11", "MM_DL11"}, + {"HDMI_MS Mixer", "MultiMedia12", "MM_DL12"}, + {"HDMI_MS Mixer", "MultiMedia13", "MM_DL13"}, + {"HDMI_MS Mixer", "MultiMedia14", "MM_DL14"}, + {"HDMI_MS Mixer", "MultiMedia15", "MM_DL15"}, + {"HDMI_MS Mixer", "MultiMedia16", "MM_DL16"}, + {"HDMI_MS Mixer", "MultiMedia26", "MM_DL26"}, + {"HDMI_MS", NULL, "HDMI_MS Mixer"}, + {"DISPLAY_PORT Mixer", "MultiMedia1", "MM_DL1"}, {"DISPLAY_PORT Mixer", "MultiMedia2", "MM_DL2"}, {"DISPLAY_PORT Mixer", "MultiMedia3", "MM_DL3"}, @@ -29252,6 +29381,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"HDMI_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, {"HDMI", NULL, "HDMI_RX Port Mixer"}, + {"HDMI_RX_MS Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"HDMI_MS", NULL, "HDMI_RX_MS Port Mixer"}, + {"DISPLAY_PORT_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, {"DISPLAY_PORT", NULL, "DISPLAY_PORT_RX Port Mixer"}, @@ -29347,6 +29479,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "SLIMBUS_9_RX"}, {"BE_OUT", NULL, "USB_AUDIO_RX"}, {"BE_OUT", NULL, "HDMI"}, + {"BE_OUT", NULL, "HDMI_MS"}, {"BE_OUT", NULL, "DISPLAY_PORT"}, {"BE_OUT", NULL, "DISPLAY_PORT1"}, {"BE_OUT", NULL, "PRI_SPDIF_RX"}, @@ -29835,7 +29968,8 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx, pr_debug("%s: port_id %d, copp_idx %d\n", __func__, port_id, copp_idx); - if (port_id != HDMI_RX && port_id != DISPLAY_PORT_RX) { + if (port_id != HDMI_RX && port_id != DISPLAY_PORT_RX + && port_id != HDMI_RX_MS) { pr_err("%s: Device pp params on invalid port %d, copp_idx %d, fe_id %d\n", __func__, port_id, copp_idx, fe_id); return -EINVAL; @@ -29972,7 +30106,8 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol, for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) { port_id = msm_bedais[be_idx].port_id; - if (port_id == HDMI_RX || port_id == DISPLAY_PORT_RX) + if (port_id == HDMI_RX || port_id == DISPLAY_PORT_RX + || port_id == HDMI_RX_MS) break; } diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index 6b96bdeb19f5..dc761b67fe47 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -17,6 +17,7 @@ #define LPASS_BE_SLIMBUS_0_RX "SLIMBUS_0_RX" #define LPASS_BE_SLIMBUS_0_TX "SLIMBUS_0_TX" #define LPASS_BE_HDMI "HDMI" +#define LPASS_BE_HDMI_MS "HDMI_MS" #define LPASS_BE_DISPLAY_PORT "DISPLAY_PORT" #define LPASS_BE_DISPLAY_PORT1 "DISPLAY_PORT1" #define LPASS_BE_INT_BT_SCO_RX "INT_BT_SCO_RX" @@ -506,6 +507,7 @@ enum { MSM_BACKEND_DAI_SEC_META_MI2S_RX, MSM_BACKEND_DAI_PROXY_RX, MSM_BACKEND_DAI_PROXY_TX, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_BACKEND_DAI_MAX, }; @@ -537,7 +539,7 @@ enum { #define RELEASE_LOCK 0 #define ACQUIRE_LOCK 1 -#define MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX 2 +#define MSM_BACKEND_DAI_PP_PARAMS_REQ_MAX 3 #define HDMI_RX_ID 0x8001 #define ADM_PP_PARAM_MUTE_ID 0 #define ADM_PP_PARAM_MUTE_BIT 1 diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 017ae06dfc1f..3b26c0cb58da 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -947,6 +947,7 @@ int afe_sizeof_cfg_cmd(u16 port_id) ret_size = SIZEOF_CFG_CMD(afe_param_id_meta_i2s_cfg); break; case HDMI_RX: + case HDMI_RX_MS: case DISPLAY_PORT_RX: ret_size = SIZEOF_CFG_CMD(afe_param_id_hdmi_multi_chan_audio_cfg); @@ -4745,6 +4746,7 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, cfg_type = AFE_PARAM_ID_META_I2S_CONFIG; break; case HDMI_RX: + case HDMI_RX_MS: case DISPLAY_PORT_RX: cfg_type = AFE_PARAM_ID_HDMI_CONFIG; break; @@ -4994,6 +4996,7 @@ int afe_get_port_index(u16 port_id) case MI2S_RX: return IDX_MI2S_RX; case MI2S_TX: return IDX_MI2S_TX; case HDMI_RX: return IDX_HDMI_RX; + case HDMI_RX_MS: return IDX_HDMI_RX_MS; case DISPLAY_PORT_RX: return IDX_DISPLAY_PORT_RX; case AFE_PORT_ID_PRIMARY_SPDIF_RX: return IDX_PRIMARY_SPDIF_RX; case AFE_PORT_ID_PRIMARY_SPDIF_TX: return IDX_PRIMARY_SPDIF_TX; @@ -5457,6 +5460,7 @@ int afe_open(u16 port_id, cfg_type = AFE_PARAM_ID_META_I2S_CONFIG; break; case HDMI_RX: + case HDMI_RX_MS: case DISPLAY_PORT_RX: cfg_type = AFE_PARAM_ID_HDMI_CONFIG; break; @@ -7347,6 +7351,7 @@ int afe_validate_port(u16 port_id) case MI2S_RX: case MI2S_TX: case HDMI_RX: + case HDMI_RX_MS: case DISPLAY_PORT_RX: case AFE_PORT_ID_PRIMARY_SPDIF_RX: case AFE_PORT_ID_PRIMARY_SPDIF_TX: diff --git a/dsp/q6audio-v2.c b/dsp/q6audio-v2.c index e3a2dc7805b7..7a811ee64677 100644 --- a/dsp/q6audio-v2.c +++ b/dsp/q6audio-v2.c @@ -46,6 +46,7 @@ int q6audio_get_port_index(u16 port_id) case MI2S_RX: return IDX_MI2S_RX; case MI2S_TX: return IDX_MI2S_TX; case HDMI_RX: return IDX_HDMI_RX; + case HDMI_RX_MS: return IDX_HDMI_RX_MS; case DISPLAY_PORT_RX: return IDX_DISPLAY_PORT_RX; case AFE_PORT_ID_PRIMARY_SPDIF_RX: return IDX_PRIMARY_SPDIF_RX; case AFE_PORT_ID_PRIMARY_SPDIF_TX: return IDX_PRIMARY_SPDIF_TX; @@ -427,6 +428,8 @@ int q6audio_get_port_id(u16 port_id) case MI2S_RX: return AFE_PORT_ID_PRIMARY_MI2S_RX; case MI2S_TX: return AFE_PORT_ID_PRIMARY_MI2S_TX; case HDMI_RX: return AFE_PORT_ID_MULTICHAN_HDMI_RX; + case HDMI_RX_MS: + return AFE_PORT_ID_HDMI_MS; case DISPLAY_PORT_RX: return AFE_PORT_ID_HDMI_OVER_DP_RX; case AFE_PORT_ID_PRIMARY_SPDIF_RX: @@ -1016,6 +1019,7 @@ int q6audio_validate_port(u16 port_id) case MI2S_RX: case MI2S_TX: case HDMI_RX: + case HDMI_RX_MS: case DISPLAY_PORT_RX: case RSVD_2: case RSVD_3: diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index dccd5edcc00d..c58999467760 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1356,6 +1356,7 @@ struct adm_cmd_connect_afe_port_v5 { #define RT_PROXY_PORT_001_RX 0x2000 #define RT_PROXY_PORT_001_TX 0x2001 #define AFE_LOOPBACK_TX 0x6001 +#define HDMI_RX_MS 0x6002 #define DISPLAY_PORT_RX 0x6020 #define AFE_LANE_MASK_INVALID 0 @@ -1562,6 +1563,8 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_9_RX 0x4012 /* SLIMbus Tx port on channel 9. */ #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_9_TX 0x4013 +/*AFE Rx port for audio over hdmi*/ +#define AFE_PORT_ID_HDMI_MS 0x6002 /* AFE Rx port for audio over Display port */ #define AFE_PORT_ID_HDMI_OVER_DP_RX 0x6020 /*USB AFE port */ diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 73a7cf872a61..76617a980d05 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -287,6 +287,8 @@ enum { /* IDX 210-> 211 */ IDX_RT_PROXY_PORT_002_RX, IDX_RT_PROXY_PORT_002_TX, + /* IDX 212 */ + IDX_HDMI_RX_MS, AFE_MAX_PORTS }; -- GitLab From 638877833c8b8f004679d9867215741500bbb389 Mon Sep 17 00:00:00 2001 From: Sanjana B Date: Mon, 16 Dec 2019 11:30:28 +0530 Subject: [PATCH 1428/1645] asoc: qcs405: Add dai links for hdmi tx Add machine driver dai links for hdmi tx. Change-Id: Id699d9d0421349418dbb75ffcb6ed5069d15c0a1 Signed-off-by: Sanjana B --- asoc/qcs405.c | 287 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 281 insertions(+), 6 deletions(-) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index 18dfb82207be..982b1f278958 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include #include @@ -148,6 +148,11 @@ enum { SPDIF_TX_MAX, }; +enum { + HDMI_RX_IDX = 0, + EXT_HDMI_RX_IDX_MAX, +}; + struct mi2s_conf { struct mutex lock; u32 ref_cnt; @@ -344,7 +349,9 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ } }; - +static struct dev_config ext_hdmi_rx_cfg[] = { + [HDMI_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; /* Default configuration of slimbus channels */ static struct dev_config slim_rx_cfg[] = { @@ -488,6 +495,12 @@ static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_32", "KHZ_44P1", "KHZ_48", "KHZ_88P2", "KHZ_96", "KHZ_176P4", "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static char const *ext_hdmi_sample_rate_text[] = {"KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_32", "KHZ_44P1", + "KHZ_88P2", "KHZ_176P4"}; +static char const *ext_hdmi_bit_format_text[] = {"S16_LE", "S24_LE", + "S24_3LE"}; + static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; @@ -539,6 +552,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_hdmi_rx_chs, ch_text); static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text); @@ -546,6 +560,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_hdmi_rx_format, ext_hdmi_bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text); @@ -553,6 +568,8 @@ static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_sink, bt_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_hdmi_rx_sample_rate, + ext_hdmi_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); @@ -2110,6 +2127,191 @@ static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, return rc; } +static int ext_hdmi_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "HDMI_RX", + sizeof("HDMI_RX"))) { + idx = HDMI_RX_IDX; + } else { + pr_err("%s: unsupported BE: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int ext_hdmi_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_hdmi_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_hdmi_rx_cfg[idx].bit_format) { + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: ext_hdmi_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_hdmi_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int ext_hdmi_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_hdmi_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 1: + ext_hdmi_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + ext_hdmi_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: ext_hdmi_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_hdmi_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int ext_hdmi_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_hdmi_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.integer.value[0] = + ext_hdmi_rx_cfg[idx].channels - 2; + + pr_debug("%s: ext_hdmi_rx[%d].ch = %d\n", __func__, + idx, ext_hdmi_rx_cfg[idx].channels); + + return 0; +} + +static int ext_hdmi_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_hdmi_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ext_hdmi_rx_cfg[idx].channels = + ucontrol->value.integer.value[0] + 2; + + pr_debug("%s: ext_hdmi_rx[%d].ch = %d\n", __func__, + idx, ext_hdmi_rx_cfg[idx].channels); + return 0; +} + +static int ext_hdmi_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + int idx = ext_hdmi_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_hdmi_rx_cfg[idx].sample_rate) { + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 6; + break; + + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 4; + break; + + case SAMPLING_RATE_32KHZ: + sample_rate_val = 3; + break; + + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: ext_hdmi_rx[%d].sample_rate = %d\n", __func__, + idx, ext_hdmi_rx_cfg[idx].sample_rate); + + return 0; +} + + +static int ext_hdmi_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_hdmi_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 6: + ext_hdmi_rx_cfg[idx].sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 5: + ext_hdmi_rx_cfg[idx].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 4: + ext_hdmi_rx_cfg[idx].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + ext_hdmi_rx_cfg[idx].sample_rate = SAMPLING_RATE_32KHZ; + break; + case 2: + ext_hdmi_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + ext_hdmi_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + ext_hdmi_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, ext_hdmi_rx[%d].sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], idx, + ext_hdmi_rx_cfg[idx].sample_rate); + return 0; +} + static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -3842,6 +4044,14 @@ static const struct snd_kcontrol_new msm_snd_sb_controls[] = { slim_rx_bit_format_get, slim_rx_bit_format_put), SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format, slim_tx_bit_format_get, slim_tx_bit_format_put), + SOC_ENUM_EXT("HDMI_RX Bit Format", ext_hdmi_rx_format, + ext_hdmi_rx_format_get, ext_hdmi_rx_format_put), + SOC_ENUM_EXT("HDMI_RX SampleRate", ext_hdmi_rx_sample_rate, + ext_hdmi_rx_sample_rate_get, + ext_hdmi_rx_sample_rate_put), + SOC_ENUM_EXT("HDMI_RX Channels", ext_hdmi_rx_chs, + ext_hdmi_rx_ch_get, + ext_hdmi_rx_ch_put), SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate, slim_rx_sample_rate_get, slim_rx_sample_rate_put), SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate, @@ -4506,6 +4716,23 @@ static int msm_slim_get_ch_from_beid(int32_t be_id) return ch_id; } +static int msm_ext_hdmi_get_idx_from_beid(int32_t be_id) +{ + int idx; + + switch (be_id) { + case MSM_BACKEND_DAI_HDMI_RX_MS: + idx = HDMI_RX_IDX; + break; + default: + pr_err("%s: Incorrect ext_hdmi BE id %d\n", __func__, be_id); + idx = -EINVAL; + break; + } + + return idx; +} + static int msm_cdc_dma_get_idx_from_beid(int32_t be_id) { int idx = 0; @@ -5040,11 +5267,27 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, channels->min = channels->max = afe_lb_tx_cfg.channels; break; + case MSM_BACKEND_DAI_HDMI_RX_MS: + idx = msm_ext_hdmi_get_idx_from_beid(dai_link->id); + + if (idx < 0) { + pr_err("%s: Incorrect ext hdmi idx %d\n", + __func__, idx); + rc = idx; + goto done; + } + + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + ext_hdmi_rx_cfg[idx].bit_format); + rate->min = rate->max = ext_hdmi_rx_cfg[idx].sample_rate; + channels->min = channels->max = ext_hdmi_rx_cfg[idx].channels; + break; + default: rate->min = rate->max = SAMPLING_RATE_48KHZ; break; } - +done: return rc; } @@ -6104,7 +6347,6 @@ static struct snd_soc_ops msm_fe_qos_ops = { .prepare = msm_fe_qos_prepare, }; - static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) { int ret = 0; @@ -7298,6 +7540,24 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { }, }; +static struct snd_soc_dai_link ext_hdmi_be_dai_link[] = { + /* HDMI RX BACK END DAI Link */ + { + .name = LPASS_BE_HDMI_MS, + .stream_name = "HDMI MS Playback", + .cpu_dai_name = "msm-dai-q6-hdmi.24578", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-ext-disp-audio-codec-rx", + .codec_dai_name = "msm_hdmi_ms_audio_codec_rx_dai", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_HDMI_RX_MS, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + static struct snd_soc_dai_link msm_common_be_dai_links[] = { /* Backend AFE DAI Links */ { @@ -8305,7 +8565,8 @@ static struct snd_soc_dai_link msm_qcs405_dai_links[ ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links) + ARRAY_SIZE(msm_bolero_fe_dai_links) + ARRAY_SIZE(msm_spdif_be_dai_links) + - ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link)]; + ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link) + + ARRAY_SIZE(ext_hdmi_be_dai_link)]; static int msm_snd_card_tasha_late_probe(struct snd_soc_card *card) { @@ -8556,6 +8817,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) uint32_t va_bolero_codec = 0, wsa_bolero_codec = 0, mi2s_audio_intf = 0; uint32_t spdif_audio_intf = 0, wcn_audio_intf = 0; uint32_t afe_loopback_intf = 0, meta_mi2s_intf = 0; + uint32_t ext_disp_hdmi_rx = 0; const struct of_device_id *match; char __iomem *spdif_cfg, *spdif_pin_ctl; int rc = 0; @@ -8743,6 +9005,20 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link); } } + rc = of_property_read_u32(dev->of_node, + "qcom,ext-disp-audio-rx", &ext_disp_hdmi_rx); + if (rc) { + dev_dbg(dev, "%s: No DT match ext disp hdmi rx\n", + __func__); + } else { + if (ext_disp_hdmi_rx) { + memcpy(msm_qcs405_dai_links + total_links, + ext_hdmi_be_dai_link, + sizeof(ext_hdmi_be_dai_link)); + total_links += ARRAY_SIZE(ext_hdmi_be_dai_link); + } + } + dailink = msm_qcs405_dai_links; } else if (!strcmp(match->data, "stub_codec")) { card = &snd_soc_card_stub_msm; @@ -8756,7 +9032,6 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) msm_stub_be_dai_links, sizeof(msm_stub_be_dai_links)); total_links += ARRAY_SIZE(msm_stub_be_dai_links); - dailink = msm_stub_dai_links; } -- GitLab From 8a3f1e622d443e5763c4c5692ceaa2d56c809ddd Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 23 Mar 2020 12:48:26 +0530 Subject: [PATCH 1429/1645] asoc: codecs: Add BCS channel select mixer control Add mixer control to support BCS SWR channel selection in bolero. Change-Id: Id26b20d674026d1798239c0e4e7e4c2d18ba89db Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/tx-macro.c | 63 +++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index bccf0f8ddbc9..9fe19c170cf2 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -793,6 +793,66 @@ static int tx_macro_set_bcs(struct snd_kcontrol *kcontrol, return 0; } +static const char * const bcs_ch_sel_mux_text[] = { + "SWR_MIC0", "SWR_MIC1", "SWR_MIC2", "SWR_MIC3", + "SWR_MIC4", "SWR_MIC5", "SWR_MIC6", "SWR_MIC7", + "SWR_MIC8", "SWR_MIC9", "SWR_MIC10", "SWR_MIC11", +}; + +static const struct soc_enum bcs_ch_sel_mux_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(bcs_ch_sel_mux_text), + bcs_ch_sel_mux_text); + +static int tx_macro_get_bcs_ch_sel(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tx_macro_priv *tx_priv = NULL; + struct device *tx_dev = NULL; + int value = 0; + + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + if (tx_priv->version == BOLERO_VERSION_2_1) + value = (snd_soc_component_read32(component, + BOLERO_CDC_VA_TOP_CSR_SWR_CTRL)) & 0x0F; + else if (tx_priv->version == BOLERO_VERSION_2_0) + value = (snd_soc_component_read32(component, + BOLERO_CDC_TX_TOP_CSR_SWR_CTRL)) & 0x0F; + + ucontrol->value.integer.value[0] = value; + return 0; +} + +static int tx_macro_put_bcs_ch_sel(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct tx_macro_priv *tx_priv = NULL; + struct device *tx_dev = NULL; + int value; + + if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + if (ucontrol->value.integer.value[0] < 0 || + ucontrol->value.integer.value[0] > ARRAY_SIZE(bcs_ch_sel_mux_text)) + return -EINVAL; + + value = ucontrol->value.integer.value[0]; + if (tx_priv->version == BOLERO_VERSION_2_1) + snd_soc_component_update_bits(component, + BOLERO_CDC_VA_TOP_CSR_SWR_CTRL, 0x0F, value); + else if (tx_priv->version == BOLERO_VERSION_2_0) + snd_soc_component_update_bits(component, + BOLERO_CDC_TX_TOP_CSR_SWR_CTRL, 0x0F, value); + + return 0; +} + static int tx_macro_enable_dmic(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -2243,6 +2303,9 @@ static const struct snd_kcontrol_new tx_macro_snd_controls_common[] = { SOC_SINGLE_EXT("DEC0_BCS Switch", SND_SOC_NOPM, 0, 1, 0, tx_macro_get_bcs, tx_macro_set_bcs), + + SOC_ENUM_EXT("BCS CH_SEL", bcs_ch_sel_mux_enum, + tx_macro_get_bcs_ch_sel, tx_macro_put_bcs_ch_sel), }; static const struct snd_kcontrol_new tx_macro_snd_controls_v3[] = { -- GitLab From b6a752da860daa2f9cdfa62677c695e7f83d4d46 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 24 Mar 2020 17:40:39 +0530 Subject: [PATCH 1430/1645] asoc: codecs: Update sequence for HPH path in rouleur Update HPHL and HPHR sequence to avoid clicks and pops by setting the LDIV and RDIV values in HD2 coefficients and increasing ramp time. Change-Id: Ib47d14255a098511393b4b75392854c8b34dc0d3 Signed-off-by: Aditya Bavanari --- asoc/codecs/rouleur/rouleur-mbhc.c | 4 ++-- asoc/codecs/rouleur/rouleur-registers.h | 2 ++ asoc/codecs/rouleur/rouleur-regmap.c | 4 +++- asoc/codecs/rouleur/rouleur-tables.c | 2 ++ asoc/codecs/rouleur/rouleur.c | 21 ++++++++++++++++++++- 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/rouleur/rouleur-mbhc.c b/asoc/codecs/rouleur/rouleur-mbhc.c index 2e1db78df68e..91ddc104acef 100644 --- a/asoc/codecs/rouleur/rouleur-mbhc.c +++ b/asoc/codecs/rouleur/rouleur-mbhc.c @@ -320,11 +320,11 @@ static void rouleur_mbhc_micb_ramp_control(struct snd_soc_component *component, 0x1C, 0x0C); snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_MICB2_RAMP, - 0x80, 0x80); + 0xA0, 0x80); } else { snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_MICB2_RAMP, - 0x80, 0x00); + 0xA0, 0x00); snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_MICB2_RAMP, 0x1C, 0x00); diff --git a/asoc/codecs/rouleur/rouleur-registers.h b/asoc/codecs/rouleur/rouleur-registers.h index ff3934bb236d..816e49237dfa 100644 --- a/asoc/codecs/rouleur/rouleur-registers.h +++ b/asoc/codecs/rouleur/rouleur-registers.h @@ -48,12 +48,14 @@ enum { #define ROULEUR_ANA_MBHC_MCLK (ROULEUR_ANA_BASE_ADDR+0x06D) #define ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT (ROULEUR_ANA_BASE_ADDR+0x072) #define ROULEUR_ANA_NCP_EN (ROULEUR_ANA_BASE_ADDR+0x077) +#define ROULEUR_ANA_HPHPA_CNP_CTL_1 (ROULEUR_ANA_BASE_ADDR+0x083) #define ROULEUR_ANA_HPHPA_CNP_CTL_2 (ROULEUR_ANA_BASE_ADDR+0x084) #define ROULEUR_ANA_HPHPA_PA_STATUS (ROULEUR_ANA_BASE_ADDR+0x087) #define ROULEUR_ANA_HPHPA_FSM_CLK (ROULEUR_ANA_BASE_ADDR+0x088) #define ROULEUR_ANA_HPHPA_L_GAIN (ROULEUR_ANA_BASE_ADDR+0x08B) #define ROULEUR_ANA_HPHPA_R_GAIN (ROULEUR_ANA_BASE_ADDR+0x08C) #define ROULEUR_ANA_HPHPA_SPARE_CTL (ROULEUR_ANA_BASE_ADDR+0x08E) +#define ROULEUR_SWR_HPHPA_HD2 (ROULEUR_ANA_BASE_ADDR+0x090) #define ROULEUR_ANA_SURGE_EN (ROULEUR_ANA_BASE_ADDR+0x097) #define ROULEUR_ANA_COMBOPA_CTL (ROULEUR_ANA_BASE_ADDR+0x09B) #define ROULEUR_ANA_RXLDO_CTL (ROULEUR_ANA_BASE_ADDR+0x0B2) diff --git a/asoc/codecs/rouleur/rouleur-regmap.c b/asoc/codecs/rouleur/rouleur-regmap.c index 39982bd20537..71e5e1901f54 100644 --- a/asoc/codecs/rouleur/rouleur-regmap.c +++ b/asoc/codecs/rouleur/rouleur-regmap.c @@ -38,12 +38,14 @@ static const struct reg_default rouleur_defaults[] = { { ROULEUR_ANA_MBHC_ZDET_RAMP_CTL, 0x00 }, { ROULEUR_ANA_MBHC_FSM_STATUS, 0x00 }, { ROULEUR_ANA_MBHC_ADC_RESULT, 0x00 }, - { ROULEUR_ANA_MBHC_MCLK, 0x30 }, + { ROULEUR_ANA_MBHC_MCLK, 0x30 }, { ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT, 0x00 }, { ROULEUR_ANA_NCP_EN, 0x00 }, + { ROULEUR_ANA_HPHPA_CNP_CTL_1, 0x54 }, { ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x2B }, { ROULEUR_ANA_HPHPA_PA_STATUS, 0x00 }, { ROULEUR_ANA_HPHPA_FSM_CLK, 0x12 }, + { ROULEUR_SWR_HPHPA_HD2, 0x1B }, { ROULEUR_ANA_HPHPA_SPARE_CTL, 0x02 }, { ROULEUR_ANA_SURGE_EN, 0x38 }, { ROULEUR_ANA_COMBOPA_CTL, 0x35 }, diff --git a/asoc/codecs/rouleur/rouleur-tables.c b/asoc/codecs/rouleur/rouleur-tables.c index ea710ebb3a5c..ba2fa9a40a79 100644 --- a/asoc/codecs/rouleur/rouleur-tables.c +++ b/asoc/codecs/rouleur/rouleur-tables.c @@ -36,10 +36,12 @@ const u8 rouleur_reg_access_analog[ROULEUR_REG( [ROULEUR_REG(ROULEUR_ANA_MBHC_MCLK)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT)] = RD_REG, [ROULEUR_REG(ROULEUR_ANA_NCP_EN)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_HPHPA_CNP_CTL_1)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_HPHPA_CNP_CTL_2)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_HPHPA_PA_STATUS)] = RD_REG, [ROULEUR_REG(ROULEUR_ANA_HPHPA_FSM_CLK)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_HPHPA_SPARE_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_SWR_HPHPA_HD2)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_SURGE_EN)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_COMBOPA_CTL)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_RXLDO_CTL)] = RD_WR_REG, diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index 768b5e3455f2..a0ed49a63bb0 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -110,6 +110,9 @@ static int rouleur_init_reg(struct snd_soc_component *component) /* Enable surge protection */ snd_soc_component_update_bits(component, ROULEUR_ANA_SURGE_EN, 0xC0, 0xC0); + /* Disable mic bias pull down */ + snd_soc_component_update_bits(component, ROULEUR_ANA_MICBIAS_MICB_1_2_EN, + 0x01, 0x00); return 0; } @@ -432,6 +435,12 @@ static int rouleur_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: rouleur_rx_clk_enable(component); + snd_soc_component_update_bits(component, + ROULEUR_ANA_HPHPA_CNP_CTL_1, + 0x02, 0x02); + snd_soc_component_update_bits(component, + ROULEUR_SWR_HPHPA_HD2, + 0x38, 0x38); set_bit(HPH_COMP_DELAY, &rouleur->status_mask); break; case SND_SOC_DAPM_POST_PMU: @@ -497,6 +506,12 @@ static int rouleur_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: rouleur_rx_clk_enable(component); + snd_soc_component_update_bits(component, + ROULEUR_ANA_HPHPA_CNP_CTL_1, + 0x02, 0x02); + snd_soc_component_update_bits(component, + ROULEUR_SWR_HPHPA_HD2, + 0x07, 0x07); set_bit(HPH_COMP_DELAY, &rouleur->status_mask); break; case SND_SOC_DAPM_POST_PMU: @@ -1204,6 +1219,8 @@ int rouleur_micbias_control(struct snd_soc_component *component, rouleur->micb_ref[micb_index]++; if (rouleur->micb_ref[micb_index] == 1) { rouleur_global_mbias_enable(component); + snd_soc_component_update_bits(component, micb_reg, + 0x80, 0x80); snd_soc_component_update_bits(component, micb_reg, enable_mask, enable_mask); if (post_on_event) @@ -1225,8 +1242,10 @@ int rouleur_micbias_control(struct snd_soc_component *component, blocking_notifier_call_chain( &rouleur->mbhc->notifier, pre_off_event, &rouleur->mbhc->wcd_mbhc); + snd_soc_component_update_bits(component, micb_reg, + enable_mask, 0x00); snd_soc_component_update_bits(component, micb_reg, - enable_mask, 0x00); + 0x80, 0x00); rouleur_global_mbias_disable(component); if (post_off_event && rouleur->mbhc) blocking_notifier_call_chain( -- GitLab From debd51e9d6f53ec438684b7dcee204b0bb3594e7 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Tue, 11 Feb 2020 15:17:14 -0500 Subject: [PATCH 1431/1645] ASoC: Add mixer control for DTMF module enabling Mixer controls are added to enable and disable DTMF ADSP modules. Change-Id: Ic04c4696b31f77488cb2047829b823255872f7ac Signed-off-by: Derek Chen --- asoc/msm-qti-pp-config.c | 57 +++++++++++++++++++++++++++++++++++++- include/dsp/apr_audio-v2.h | 6 ++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index 89386c49807e..1bafb20275b1 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -166,6 +166,45 @@ static int msm_qti_pp_put_eq_band_count_audio_mixer( return 0; } +static int msm_qti_pp_put_dtmf_module_enable + (struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u16 fe_id = 0; + struct msm_pcm_routing_fdai_data fe_dai; + struct audio_client *ac = NULL; + struct param_hdr_v3 param_hdr; + int ret = 0; + u32 flag = ucontrol->value.integer.value[0]; + + fe_id = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { + pr_err("%s: invalid FE %d\n", __func__, fe_id); + return -EINVAL; + } + + msm_pcm_routing_get_fedai_info(fe_id, SESSION_TYPE_RX, &fe_dai); + ac = q6asm_get_audio_client(fe_dai.strm_id); + + if (ac == NULL) { + pr_err("%s ac is null.\n", __func__); + ret = -EINVAL; + goto done; + } + + param_hdr.module_id = AUDPROC_MODULE_ID_DTMF_DETECTION; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE; + param_hdr.param_size = 4; + + ret = q6asm_pack_and_set_pp_param_in_band(ac, + param_hdr, (u8 *)&flag); + +done: + return ret; +} + static int msm_qti_pp_get_eq_band_audio_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1646,6 +1685,18 @@ static const struct snd_kcontrol_new asphere_mixer_controls[] = { 0xFFFFFFFF, 0, 2, msm_qti_pp_asphere_get, msm_qti_pp_asphere_set), }; +static const struct snd_kcontrol_new dtmf_detect_enable_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1 DTMF Detect Enable", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, NULL, + msm_qti_pp_put_dtmf_module_enable), + SOC_SINGLE_EXT("MultiMedia6 DTMF Detect Enable", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, NULL, + msm_qti_pp_put_dtmf_module_enable), + SOC_SINGLE_EXT("MultiMedia21 DTMF Detect Enable", SND_SOC_NOPM, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, NULL, + msm_qti_pp_put_dtmf_module_enable), +}; + #ifdef CONFIG_QTI_PP void msm_qti_pp_add_controls(struct snd_soc_component *component) { @@ -1718,5 +1769,9 @@ void msm_qti_pp_add_controls(struct snd_soc_component *component) snd_soc_add_component_controls(component, ec_ffecns_controls, ARRAY_SIZE(ec_ffecns_controls)); + + snd_soc_add_component_controls(component, + dtmf_detect_enable_mixer_controls, + ARRAY_SIZE(dtmf_detect_enable_mixer_controls)); } #endif /* CONFIG_QTI_PP */ diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index dbd116db5987..7d56a4d75c25 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -12713,6 +12713,12 @@ struct afe_doa_tracking_mon_get_param_resp { #define AUDPROC_MODULE_ID_FFECNS 0x00010952 #define AUDPROC_MODULE_ID_FFNS 0x00010962 #define AUDPROC_PARAM_ID_FFV_DOA_TRACKING_PARAM 0x0001097C + +/* +* ID of the DTMF Detection Module. +*/ +#define AUDPROC_MODULE_ID_DTMF_DETECTION 0x00010940 + #define AUDPROC_PARAM_ID_FFV_DOA_TRACKING_MONITOR 0x0001097D struct admx_sec_primary_mic_ch { -- GitLab From 849ebb85cbd85ad8db1068518f6d1c83ede40218 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 11 Mar 2020 13:11:51 +0530 Subject: [PATCH 1432/1645] ASoC: wcd-mbhc: Disable moisture detect threshold if duty cycle disabled Moisture detection is not disabled properly if threshold remains set as 24k even if duty cycle is disabled. This is leading into headset not getting detected sometimes. Disable threshold as well if duty cycle disabled. Change-Id: Ic90c65d8bbaa965cf147f95edf5add8980889e1f Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd-mbhc-v2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index f3e71af1944c..3692ed7ba0a6 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -1376,8 +1376,7 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) if (mbhc->mbhc_cfg->moisture_en && mbhc->mbhc_cb->mbhc_moisture_config && !mbhc->mbhc_cfg->moisture_duty_cycle_en) mbhc->mbhc_cb->mbhc_moisture_config(mbhc); - else if (mbhc->mbhc_cfg->moisture_duty_cycle_en && - mbhc->mbhc_cb->mbhc_moisture_detect_en) + else if (mbhc->mbhc_cb->mbhc_moisture_detect_en) mbhc->mbhc_cb->mbhc_moisture_detect_en(mbhc, false); /* -- GitLab From fc15b79b5f816fd567f3bf5194982891b409df58 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 16 Mar 2020 19:02:14 +0530 Subject: [PATCH 1433/1645] ASOC: wcd938x: Handle button press before release interrupt If button press and release interrupts occur at same time processing button release first would treat the button event as fake, as it is not preceeded with press event. Hence process button press before button release in irq driver. Change-Id: I36d5ad8a3571f4bd32d309a060a6988f29ff27ad Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd938x/internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index c59d5b882baf..f8a47fdba12a 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -155,8 +155,8 @@ enum { enum { /* INTR_CTRL_INT_MASK_0 */ - WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET = 0, - WCD938X_IRQ_MBHC_BUTTON_PRESS_DET, + WCD938X_IRQ_MBHC_BUTTON_PRESS_DET = 0, + WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET, WCD938X_IRQ_MBHC_ELECT_INS_REM_DET, WCD938X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, WCD938X_IRQ_MBHC_SW_DET, -- GitLab From fbe5c7c8e13ab89a13922aeb5f4a9954c959d055 Mon Sep 17 00:00:00 2001 From: Deru Wang Date: Tue, 24 Mar 2020 20:06:55 +0800 Subject: [PATCH 1434/1645] asoc: fix kernel panic due to Non-NULL ac set pcm->audio_client NULL when open pcm failed and add NULL pointer check. Change-Id: I5a293e09449d3b616761bbd66326274849ce2f58 Signed-off-by: Deru Wang --- asoc/msm-pcm-loopback-v2.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index 19fe1903881f..86e8c81b0aec 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -307,6 +307,7 @@ static int msm_pcm_open(struct snd_pcm_substream *substream) dev_err(component->dev, "%s: pcm out open failed\n", __func__); q6asm_audio_client_free(pcm->audio_client); + pcm->audio_client = NULL; mutex_unlock(&pcm->lock); return -ENOMEM; } @@ -346,8 +347,10 @@ static void stop_pcm(struct msm_pcm_loopback *pcm) struct snd_soc_pcm_runtime *soc_pcm_rx; struct snd_soc_pcm_runtime *soc_pcm_tx; - if (pcm->audio_client == NULL) + if (pcm->audio_client == NULL) { + pr_err("%s: audio client freed\n", __func__); return; + } mutex_lock(&loopback_session_lock); q6asm_cmd(pcm->audio_client, CMD_CLOSE); @@ -445,6 +448,12 @@ static int msm_pcm_prepare(struct snd_pcm_substream *substream) dev_dbg(component->dev, "%s: ASM loopback stream:%d\n", __func__, substream->stream); + if (!pcm || !pcm->audio_client) { + mutex_unlock(&pcm->lock); + pr_err("%s: private data null or audio client freed\n", __func__); + return -EINVAL; + } + if (pcm->playback_start && pcm->capture_start) { mutex_unlock(&pcm->lock); return ret; -- GitLab From 5ab8cbd5527b469d19333a68025ecfef25371aa2 Mon Sep 17 00:00:00 2001 From: Deru Wang Date: Wed, 25 Mar 2020 13:20:06 +0800 Subject: [PATCH 1435/1645] asoc: Add asm loopback MultiMedia24 & 25 Add asm loopback channel to support dual hfp Change-Id: I7b6e1ec773a9a0bbf3f9e3f8e47610b9096b7f37 Signed-off-by: Deru Wang --- asoc/sa6155.c | 88 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 27 deletions(-) diff --git a/asoc/sa6155.c b/asoc/sa6155.c index d242738d1a59..6ed96e1f8879 100644 --- a/asoc/sa6155.c +++ b/asoc/sa6155.c @@ -182,14 +182,14 @@ struct tdm_conf { /* TDM default config */ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { { /* PRI TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_2 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_3 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ }, { /* SEC TDM */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_0 */ @@ -236,14 +236,14 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { /* TDM default config */ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { { /* PRI TDM */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_0 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_1 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_2 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_3 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ - {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_2 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_3 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ }, { /* SEC TDM */ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* TX_0 */ @@ -351,7 +351,7 @@ struct tdm_slot_cfg { static struct tdm_slot_cfg tdm_slot[TDM_INTERFACE_MAX] = { /* PRI TDM */ - {32, 8}, + {16, 16}, /* SEC TDM */ {32, 8}, /* TERT TDM */ @@ -385,11 +385,11 @@ static struct tdm_slot_cfg tdm_slot_custom[TDM_INTERFACE_MAX] = { static unsigned int tdm_rx_slot_offset [TDM_INTERFACE_MAX][TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { {/* PRI TDM */ - {0, 4, 0xFFFF}, - {8, 12, 0xFFFF}, - {16, 20, 0xFFFF}, - {24, 28, 0xFFFF}, - {0xFFFF}, /* not used */ + {0, 0xFFFF}, + {2, 0xFFFF}, + {4, 6, 0xFFFF}, + {8, 10, 0xFFFF}, + {12, 14, 0xFFFF}, {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -439,11 +439,11 @@ static unsigned int tdm_rx_slot_offset static unsigned int tdm_tx_slot_offset [TDM_INTERFACE_MAX][TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { {/* PRI TDM */ - {0, 4, 0xFFFF}, - {8, 12, 0xFFFF}, - {16, 20, 0xFFFF}, - {24, 28, 0xFFFF}, - {0xFFFF}, /* not used */ + {0, 0xFFFF}, + {2, 0xFFFF}, + {4, 6, 0xFFFF}, + {8, 10, 0xFFFF}, + {12, 14, 0xFFFF}, {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ {0xFFFF}, /* not used */ @@ -5909,6 +5909,40 @@ static struct snd_soc_dai_link msm_auto_fe_dai_links[] = { .ignore_pmdown_time = 1, .id = MSM_FRONTEND_DAI_MULTIMEDIA23 }, + { + .name = MSM_DAILINK_NAME(Media24), + .stream_name = "MultiMedia24", + .cpu_dai_name = "MultiMedia24", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA24 + }, + { + .name = MSM_DAILINK_NAME(Media25), + .stream_name = "MultiMedia25", + .cpu_dai_name = "MultiMedia25", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA25 + }, }; static struct snd_soc_dai_link msm_custom_fe_dai_links[] = { -- GitLab From 2d763bac13803a8ca61c46daf552b94992da0988 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 17 Feb 2020 13:26:50 +0530 Subject: [PATCH 1436/1645] asoc: Add separate array for TDM BE dai links Create a separate array for TDM BE dai links and add only when the interface support is required. Also, add sound controls of MI2S, TDM and AUXPCM interfaces only when supported. Change-Id: I0ff092426d4ff81df44a15ad8c5d6cc438cba2ae Signed-off-by: Aditya Bavanari --- asoc/kona.c | 339 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 203 insertions(+), 136 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index a97590f717bf..4382689faaea 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -3691,6 +3691,46 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, usb_audio_tx_sample_rate_get, usb_audio_tx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, + usb_audio_rx_format_get, usb_audio_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, + usb_audio_tx_format_get, usb_audio_tx_format_put), + SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, + usb_audio_rx_ch_get, usb_audio_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, + usb_audio_tx_ch_get, usb_audio_tx_ch_put), + SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, + proxy_rx_ch_get, proxy_rx_ch_put), + SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, + ext_disp_rx_ch_get, ext_disp_rx_ch_put), + SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, + ext_disp_rx_format_get, ext_disp_rx_format_put), + SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, + ext_disp_rx_sample_rate_get, + ext_disp_rx_sample_rate_put), + SOC_ENUM_EXT("Display Port1 RX Channels", ext_disp_rx_chs, + ext_disp_rx_ch_get, ext_disp_rx_ch_put), + SOC_ENUM_EXT("Display Port1 RX Bit Format", ext_disp_rx_format, + ext_disp_rx_format_get, ext_disp_rx_format_put), + SOC_ENUM_EXT("Display Port1 RX SampleRate", ext_disp_rx_sample_rate, + ext_disp_rx_sample_rate_get, + ext_disp_rx_sample_rate_put), + SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), + SOC_ENUM_EXT("BT SampleRate RX", bt_sample_rate_rx, + msm_bt_sample_rate_rx_get, + msm_bt_sample_rate_rx_put), + SOC_ENUM_EXT("BT SampleRate TX", bt_sample_rate_tx, + msm_bt_sample_rate_tx_get, + msm_bt_sample_rate_tx_put), + SOC_ENUM_EXT("AFE_LOOPBACK_TX Channels", afe_loopback_tx_chs, + afe_loopback_tx_ch_get, afe_loopback_tx_ch_put), + SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, + msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), +}; + +static const struct snd_kcontrol_new msm_tdm_snd_controls[] = { SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, tdm_rx_sample_rate_get, tdm_rx_sample_rate_put), @@ -3727,6 +3767,83 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("SEN_TDM_TX_0 SampleRate", tdm_tx_sample_rate, tdm_tx_sample_rate_get, tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEN_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEN_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEN_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEN_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_SINGLE_MULTI_EXT("TDM Slot Map", SND_SOC_NOPM, 0, 255, 0, + TDM_MAX_SLOTS + MAX_PATH, NULL, tdm_slot_map_put), +}; + +static const struct snd_kcontrol_new msm_auxpcm_snd_controls[] = { SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, aux_pcm_rx_sample_rate_get, aux_pcm_rx_sample_rate_put), @@ -3763,6 +3880,33 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("SEN_AUX_PCM_TX SampleRate", sen_aux_pcm_tx_sample_rate, aux_pcm_tx_sample_rate_get, aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("SEN_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("SEN_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), +}; + +static const struct snd_kcontrol_new msm_mi2s_snd_controls[] = { SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, mi2s_rx_sample_rate_get, mi2s_rx_sample_rate_put), @@ -3799,70 +3943,6 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("SEN_MI2S_TX SampleRate", sen_mi2s_tx_sample_rate, mi2s_tx_sample_rate_get, mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, - usb_audio_rx_format_get, usb_audio_rx_format_put), - SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, - usb_audio_tx_format_get, usb_audio_tx_format_put), - SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("QUIN_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("SEN_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("QUIN_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("SEN_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("QUAT_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("QUIN_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("SEN_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("QUAT_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("QUIN_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("SEN_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format, @@ -3887,48 +3967,6 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), SOC_ENUM_EXT("SEN_MI2S_TX Format", mi2s_tx_format, msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), - SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, - usb_audio_rx_ch_get, usb_audio_rx_ch_put), - SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, - usb_audio_tx_ch_get, usb_audio_tx_ch_put), - SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, - proxy_rx_ch_get, proxy_rx_ch_put), - SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("QUIN_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("SEN_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("QUIN_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("SEN_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, @@ -3953,35 +3991,6 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), SOC_ENUM_EXT("SEN_MI2S_TX Channels", sen_mi2s_tx_chs, msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, - ext_disp_rx_ch_get, ext_disp_rx_ch_put), - SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, - ext_disp_rx_format_get, ext_disp_rx_format_put), - SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, - ext_disp_rx_sample_rate_get, - ext_disp_rx_sample_rate_put), - SOC_ENUM_EXT("Display Port1 RX Channels", ext_disp_rx_chs, - ext_disp_rx_ch_get, ext_disp_rx_ch_put), - SOC_ENUM_EXT("Display Port1 RX Bit Format", ext_disp_rx_format, - ext_disp_rx_format_get, ext_disp_rx_format_put), - SOC_ENUM_EXT("Display Port1 RX SampleRate", ext_disp_rx_sample_rate, - ext_disp_rx_sample_rate_get, - ext_disp_rx_sample_rate_put), - SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, - msm_bt_sample_rate_get, - msm_bt_sample_rate_put), - SOC_ENUM_EXT("BT SampleRate RX", bt_sample_rate_rx, - msm_bt_sample_rate_rx_get, - msm_bt_sample_rate_rx_put), - SOC_ENUM_EXT("BT SampleRate TX", bt_sample_rate_tx, - msm_bt_sample_rate_tx_get, - msm_bt_sample_rate_tx_put), - SOC_ENUM_EXT("AFE_LOOPBACK_TX Channels", afe_loopback_tx_chs, - afe_loopback_tx_ch_get, afe_loopback_tx_ch_put), - SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, - msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), - SOC_SINGLE_MULTI_EXT("TDM Slot Map", SND_SOC_NOPM, 0, 255, 0, - TDM_MAX_SLOTS + MAX_PATH, NULL, tdm_slot_map_put), }; static const struct snd_kcontrol_new msm_snd_controls[] = { @@ -5313,6 +5322,45 @@ static int msm_wcn_init_lito(struct snd_soc_pcm_runtime *rtd) tx_ch, ARRAY_SIZE(rx_ch), rx_ch); } +#ifndef CONFIG_TDM_DISABLE +static void msm_add_tdm_snd_controls(struct snd_soc_component *component) +{ + snd_soc_add_component_controls(component, msm_tdm_snd_controls, + ARRAY_SIZE(msm_tdm_snd_controls)); +} +#else +static void msm_add_tdm_snd_controls(struct snd_soc_component *component) +{ + return; +} +#endif + +#ifndef CONFIG_MI2S_DISABLE +static void msm_add_mi2s_snd_controls(struct snd_soc_component *component) +{ + snd_soc_add_component_controls(component, msm_mi2s_snd_controls, + ARRAY_SIZE(msm_mi2s_snd_controls)); +} +#else +static void msm_add_mi2s_snd_controls(struct snd_soc_component *component) +{ + return; +} +#endif + +#ifndef CONFIG_AUXPCM_DISABLE +static void msm_add_auxpcm_snd_controls(struct snd_soc_component *component) +{ + snd_soc_add_component_controls(component, msm_auxpcm_snd_controls, + ARRAY_SIZE(msm_auxpcm_snd_controls)); +} +#else +static void msm_add_auxpcm_snd_controls(struct snd_soc_component *component) +{ + return; +} +#endif + static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) { int ret = -EINVAL; @@ -5348,6 +5396,10 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) return ret; } + msm_add_tdm_snd_controls(component); + msm_add_mi2s_snd_controls(component); + msm_add_auxpcm_snd_controls(component); + snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets, ARRAY_SIZE(msm_int_dapm_widgets)); @@ -6244,6 +6296,10 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_suspend = 1, }, +}; + + +static struct snd_soc_dai_link msm_tdm_be_dai_links[] = { { .name = LPASS_BE_PRI_TDM_RX_0, .stream_name = "Primary TDM0 Playback", @@ -7120,7 +7176,8 @@ static struct snd_soc_dai_link msm_kona_dai_links[ ARRAY_SIZE(ext_disp_be_dai_link) + ARRAY_SIZE(msm_wcn_be_dai_links) + ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link) + - ARRAY_SIZE(msm_wcn_btfm_be_dai_links)]; + ARRAY_SIZE(msm_wcn_btfm_be_dai_links) + + ARRAY_SIZE(msm_tdm_be_dai_links)]; static int msm_populate_dai_link_component_of_node( struct snd_soc_card *card) @@ -7437,6 +7494,16 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link); } + rc = of_property_read_u32(dev->of_node, "qcom,tdm-audio-intf", + &val); + if (!rc && val) { + memcpy(msm_kona_dai_links + total_links, + msm_tdm_be_dai_links, + sizeof(msm_tdm_be_dai_links)); + total_links += + ARRAY_SIZE(msm_tdm_be_dai_links); + } + rc = of_property_read_u32(dev->of_node, "qcom,wcn-btfm", &wcn_btfm_intf); if (rc) { -- GitLab From 4460ed2e57aee6b62389760c9e8cc5c3afc45b70 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 20 Feb 2020 12:46:51 +0530 Subject: [PATCH 1437/1645] asoc: codecs: Add system sleep ops for macro drivers Add system sleep ops and invoke force runtime suspend for all the macro drivers in bolero in order to synchronize system suspend and runtime suspend callbacks. Use freezable delayed work queues instead of normal delayed workqueues in order to avoid contention with pm suspend callflow. Change-Id: Ibb0d35ad80c09e7f2a7032b4daef53c359056dfd Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/bolero-cdc.c | 2 ++ asoc/codecs/bolero/rx-macro.c | 4 ++++ asoc/codecs/bolero/tx-macro.c | 11 ++++++++--- asoc/codecs/bolero/va-macro.c | 11 ++++++++--- asoc/codecs/bolero/wsa-macro.c | 4 ++++ 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 2db0c5b30a35..9d5368437ed2 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -1367,6 +1367,7 @@ static int bolero_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM int bolero_runtime_resume(struct device *dev) { struct bolero_priv *priv = dev_get_drvdata(dev->parent); @@ -1448,6 +1449,7 @@ int bolero_runtime_suspend(struct device *dev) return 0; } EXPORT_SYMBOL(bolero_runtime_suspend); +#endif /* CONFIG_PM */ bool bolero_check_core_votes(struct device *dev) { diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index ea1a3741a372..eb7cb883cc05 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -4135,6 +4135,10 @@ static const struct of_device_id rx_macro_dt_match[] = { }; static const struct dev_pm_ops bolero_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS( + pm_runtime_force_suspend, + pm_runtime_force_resume + ) SET_RUNTIME_PM_OPS( bolero_runtime_suspend, bolero_runtime_resume, diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 9fe19c170cf2..472cdfeee46b 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -980,11 +980,12 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, if (tx_unmute_delay < unmute_delay) tx_unmute_delay = unmute_delay; /* schedule work queue to Remove Mute */ - schedule_delayed_work(&tx_priv->tx_mute_dwork[decimator].dwork, - msecs_to_jiffies(tx_unmute_delay)); + queue_delayed_work(system_freezable_wq, + &tx_priv->tx_mute_dwork[decimator].dwork, + msecs_to_jiffies(tx_unmute_delay)); if (tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq != CF_MIN_3DB_150HZ) { - schedule_delayed_work( + queue_delayed_work(system_freezable_wq, &tx_priv->tx_hpf_work[decimator].dwork, msecs_to_jiffies(hpf_delay)); snd_soc_component_update_bits(component, @@ -3297,6 +3298,10 @@ static const struct of_device_id tx_macro_dt_match[] = { }; static const struct dev_pm_ops bolero_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS( + pm_runtime_force_suspend, + pm_runtime_force_resume + ) SET_RUNTIME_PM_OPS( bolero_runtime_suspend, bolero_runtime_resume, diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 85d4ae399703..3f01b259ae32 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -1183,11 +1183,12 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, */ usleep_range(6000, 6010); /* schedule work queue to Remove Mute */ - schedule_delayed_work(&va_priv->va_mute_dwork[decimator].dwork, - msecs_to_jiffies(va_tx_unmute_delay)); + queue_delayed_work(system_freezable_wq, + &va_priv->va_mute_dwork[decimator].dwork, + msecs_to_jiffies(va_tx_unmute_delay)); if (va_priv->va_hpf_work[decimator].hpf_cut_off_freq != CF_MIN_3DB_150HZ) - schedule_delayed_work( + queue_delayed_work(system_freezable_wq, &va_priv->va_hpf_work[decimator].dwork, msecs_to_jiffies(hpf_delay)); /* apply gain after decimator is enabled */ @@ -3208,6 +3209,10 @@ static const struct of_device_id va_macro_dt_match[] = { }; static const struct dev_pm_ops bolero_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS( + pm_runtime_force_suspend, + pm_runtime_force_resume + ) SET_RUNTIME_PM_OPS( bolero_runtime_suspend, bolero_runtime_resume, diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index e97d74607a1b..2ab2e8af413e 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -3244,6 +3244,10 @@ static const struct of_device_id wsa_macro_dt_match[] = { }; static const struct dev_pm_ops bolero_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS( + pm_runtime_force_suspend, + pm_runtime_force_resume + ) SET_RUNTIME_PM_OPS( bolero_runtime_suspend, bolero_runtime_resume, -- GitLab From 060de8e1aa15ba34cb415e553e23693b8f221c83 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 5 Mar 2020 12:31:39 +0530 Subject: [PATCH 1438/1645] soc: swr-mstr-ctrl: Remove ssr_lock handling During SSR and headset detection/removal interrupt concurrencies, ssr_lock can lead to serv reg ack timeout issues. Remove this synchronization to avoid this issue. Change-Id: I242a013a7e9d833db21d737cbdfea2d84bbd29fa Signed-off-by: Aditya Bavanari --- soc/swr-mstr-ctrl.c | 7 ------- soc/swr-mstr-ctrl.h | 1 - 2 files changed, 8 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 4aa5c0c6aa5f..e2257fd8fc52 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1908,7 +1908,6 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) return IRQ_NONE; } - mutex_lock(&swrm->ssr_lock); mutex_lock(&swrm->reslock); if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) { ret = IRQ_NONE; @@ -2122,7 +2121,6 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); exit: mutex_unlock(&swrm->reslock); - mutex_unlock(&swrm->ssr_lock); swrm_unlock_sleep(swrm); trace_printk("%s exit\n", __func__); return ret; @@ -2655,7 +2653,6 @@ static int swrm_probe(struct platform_device *pdev) mutex_init(&swrm->clklock); mutex_init(&swrm->devlock); mutex_init(&swrm->pm_lock); - mutex_init(&swrm->ssr_lock); swrm->wlock_holders = 0; swrm->pm_state = SWRM_PM_SLEEPABLE; init_waitqueue_head(&swrm->pm_wq); @@ -2804,7 +2801,6 @@ static int swrm_probe(struct platform_device *pdev) mutex_destroy(&swrm->iolock); mutex_destroy(&swrm->clklock); mutex_destroy(&swrm->pm_lock); - mutex_destroy(&swrm->ssr_lock); pm_qos_remove_request(&swrm->pm_qos_req); err_pdata_fail: @@ -2838,7 +2834,6 @@ static int swrm_remove(struct platform_device *pdev) mutex_destroy(&swrm->clklock); mutex_destroy(&swrm->force_down_lock); mutex_destroy(&swrm->pm_lock); - mutex_destroy(&swrm->ssr_lock); pm_qos_remove_request(&swrm->pm_qos_req); devm_kfree(&pdev->dev, swrm); return 0; @@ -3325,7 +3320,6 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) break; case SWR_DEVICE_SSR_DOWN: trace_printk("%s: swr device down called\n", __func__); - mutex_lock(&swrm->ssr_lock); mutex_lock(&swrm->mlock); if (swrm->state == SWR_MSTR_DOWN) dev_dbg(swrm->dev, "%s:SWR master is already Down:%d\n", @@ -3339,7 +3333,6 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) swrm->state = SWR_MSTR_SSR; mutex_unlock(&swrm->reslock); mutex_unlock(&swrm->mlock); - mutex_unlock(&swrm->ssr_lock); break; case SWR_DEVICE_SSR_UP: /* wait for clk voting to be zero */ diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 0fac80e6f0c3..ce0b64d57766 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -126,7 +126,6 @@ struct swr_mstr_ctrl { struct mutex reslock; struct mutex pm_lock; struct mutex irq_lock; - struct mutex ssr_lock; u32 swrm_base_reg; char __iomem *swrm_dig_base; char __iomem *swrm_hctl_reg; -- GitLab From f0106d95ec67585999fdd555ae2a559789bdd23d Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 31 Jan 2020 17:01:21 +0530 Subject: [PATCH 1439/1645] soc: swr: Mask bus clash interrupt Mask bus clash interrupts to avoid interrupt storm issues. Change-Id: Ie5634e65c759f0ebbd74cf104888dfbc49a289f6 Signed-off-by: Aditya Bavanari --- soc/swr-mstr-ctrl.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 4aa5c0c6aa5f..2faab62f8ad8 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2025,6 +2025,11 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) dev_err_ratelimited(swrm->dev, "%s: SWR bus clsh detected\n", __func__); + swrm->intr_mask &= + ~SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET; + swr_master_write(swrm, + SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN, + swrm->intr_mask); break; case SWRM_INTERRUPT_STATUS_RD_FIFO_OVERFLOW: dev_dbg(swrm->dev, "%s: SWR read FIFO overflow\n", -- GitLab From 386699bca868348506849f224d889e9fa3b6db3e Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 24 Mar 2020 16:50:17 +0530 Subject: [PATCH 1440/1645] asoc: wcd937x: Update retry logic for SWR logical addr Update retry logic for SWR logical address during SSR. Change-Id: Ifa5cdec751a271c09a8b6340009ec0e862ffb326 Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd937x/wcd937x.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 5c3f14f84b9f..2fb954b029cc 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -37,6 +37,8 @@ #define WCD937X_VERSION_ENTRY_SIZE 32 #define EAR_RX_PATH_AUX 1 +#define NUM_ATTEMPTS 5 + enum { CODEC_TX = 0, CODEC_RX, @@ -1535,14 +1537,18 @@ static int wcd937x_get_logical_addr(struct swr_device *swr_dev) { int ret = 0; uint8_t devnum = 0; + int num_retry = NUM_ATTEMPTS; - ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum); - if (ret) { - dev_err(&swr_dev->dev, - "%s get devnum %d for dev addr %lx failed\n", - __func__, devnum, swr_dev->addr); - return ret; - } + do { + ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum); + if (ret) { + dev_err(&swr_dev->dev, + "%s get devnum %d for dev addr %lx failed\n", + __func__, devnum, swr_dev->addr); + /* retry after 1ms */ + usleep_range(1000, 1010); + } + } while (ret && --num_retry); swr_dev->dev_num = devnum; return 0; } -- GitLab From d08ab1fd6bf622fe789a1640227273e61f32e291 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 30 Jan 2020 19:07:58 +0530 Subject: [PATCH 1441/1645] asoc: Add null check for kctl private_data in volume controls In platform driver volume controls, add null check for kctl private data before access. CRs-Fixed: 2611397 Change-Id: I49bdac2bb780a7116e54c20bf5f0d01f13a53165 Signed-off-by: Laxminath Kasam --- asoc/msm-pcm-loopback-v2.c | 10 +++++++--- asoc/msm-pcm-q6-noirq.c | 10 +++++++--- asoc/msm-pcm-q6-v2.c | 10 +++++++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index 19fe1903881f..ffde93b7fad6 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. */ #include @@ -559,11 +559,15 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, { int rc = 0; struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol); - struct snd_pcm_substream *substream = - vol->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + struct snd_pcm_substream *substream = NULL; struct msm_pcm_loopback *prtd; pr_debug("%s\n", __func__); + if (!vol) { + pr_err("%s: vol is NULL\n", __func__); + return -ENODEV; + } + substream = vol->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; if ((!substream) || (!substream->runtime)) { pr_debug("%s substream or runtime not found\n", __func__); rc = -ENODEV; diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index 12a1f12b359b..8fb6f7cd4995 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #include @@ -720,13 +720,17 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, { struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol); struct msm_plat_data *pdata = NULL; - struct snd_pcm_substream *substream = - vol->pcm->streams[vol->stream].substream; + struct snd_pcm_substream *substream = NULL; struct snd_soc_pcm_runtime *soc_prtd = NULL; struct snd_soc_component *component = NULL; struct msm_audio *prtd; pr_debug("%s\n", __func__); + if (!vol) { + pr_err("%s: vol is NULL\n", __func__); + return -ENODEV; + } + substream = vol->pcm->streams[vol->stream].substream; if (!substream) { pr_err("%s substream not found\n", __func__); return -ENODEV; diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 60e84cb7dd2d..c22c39ba3ec0 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ @@ -1514,13 +1514,17 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, { struct snd_pcm_volume *vol = snd_kcontrol_chip(kcontrol); struct msm_plat_data *pdata = NULL; - struct snd_pcm_substream *substream = - vol->pcm->streams[vol->stream].substream; + struct snd_pcm_substream *substream = NULL; struct snd_soc_pcm_runtime *soc_prtd = NULL; struct snd_soc_component *component = NULL; struct msm_audio *prtd; pr_debug("%s\n", __func__); + if (!vol) { + pr_err("%s: vol is NULL\n", __func__); + return -ENODEV; + } + substream = vol->pcm->streams[vol->stream].substream; if (!substream) { pr_err("%s substream not found\n", __func__); return -ENODEV; -- GitLab From 99690f145258c2cb8c5606238b23b9d81062aa87 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Sun, 15 Mar 2020 15:38:21 +0530 Subject: [PATCH 1442/1645] asoc: kona: call wsa set channel map for wsa883x Update speaker amp call for wsa883x. Change-Id: I3ab9be48e169f15ef6fdda7ee61f34b35d333e05 Signed-off-by: Laxminath Kasam --- asoc/kona.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index a97590f717bf..82814ce0c36c 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -31,6 +31,7 @@ #include "asoc/wcd-mbhc-v2.h" #include "codecs/wcd938x/wcd938x-mbhc.h" #include "codecs/wsa881x.h" +#include "codecs/wsa883x/wsa883x.h" #include "codecs/wcd938x/wcd938x.h" #include "codecs/bolero/bolero-cdc.h" #include @@ -7503,9 +7504,14 @@ static int msm_wsa881x_init(struct snd_soc_component *component) if (!strcmp(component->name_prefix, "SpkrLeft")) { dev_dbg(component->dev, "%s: setting left ch map to codec %s\n", __func__, component->name); - wsa881x_set_channel_map(component, &spkleft_ports[0], - WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0], &spkleft_port_types[0]); + if (strnstr(component->name, "wsa883x", sizeof(component->name))) + wsa883x_set_channel_map(component, &spkleft_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0], &spkleft_port_types[0]); + else + wsa881x_set_channel_map(component, &spkleft_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0], &spkleft_port_types[0]); if (dapm->component) { snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); @@ -7513,9 +7519,14 @@ static int msm_wsa881x_init(struct snd_soc_component *component) } else if (!strcmp(component->name_prefix, "SpkrRight")) { dev_dbg(component->dev, "%s: setting right ch map to codec %s\n", __func__, component->name); - wsa881x_set_channel_map(component, &spkright_ports[0], - WSA881X_MAX_SWR_PORTS, &ch_mask[0], - &ch_rate[0], &spkright_port_types[0]); + if (strnstr(component->name, "wsa883x", sizeof(component->name))) + wsa883x_set_channel_map(component, &spkright_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0], &spkright_port_types[0]); + else + wsa881x_set_channel_map(component, &spkright_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0], &spkright_port_types[0]); if (dapm->component) { snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); @@ -7538,8 +7549,12 @@ static int msm_wsa881x_init(struct snd_soc_component *component) } pdata->codec_root = entry; } - wsa881x_codec_info_create_codec_entry(pdata->codec_root, - component); + if (strnstr(component->name, "wsa883x", sizeof(component->name))) + wsa883x_codec_info_create_codec_entry(pdata->codec_root, + component); + else + wsa881x_codec_info_create_codec_entry(pdata->codec_root, + component); err: return ret; } -- GitLab From 700983517f0c6534bca2c2d569fa541ee304ea9a Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 12 Mar 2020 17:40:47 +0530 Subject: [PATCH 1443/1645] asoc: wcd938x: Add vdd-buck as on demand supply On lagoon, vdd-buck need to be dynamic supply. Add required support to handle buck as dynamic supply. Change-Id: If6c27fffe0d0c44f178e61a6eae6ef63775c8988 Signed-off-by: Laxminath Kasam --- asoc/codecs/msm-cdc-supply.c | 43 ++++++++++++++- asoc/codecs/wcd938x/wcd938x.c | 99 +++++++++++++++++++++++++++++++++++ include/asoc/msm-cdc-supply.h | 6 ++- 3 files changed, 146 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/msm-cdc-supply.c b/asoc/codecs/msm-cdc-supply.c index 220da9dc10f7..831562f3af48 100644 --- a/asoc/codecs/msm-cdc-supply.c +++ b/asoc/codecs/msm-cdc-supply.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #include @@ -118,6 +118,47 @@ static int msm_cdc_check_supply_param(struct device *dev, return 0; } +/* + * msm_cdc_is_ondemand_supply: + * return if ondemand supply true or not + * + * @dev: pointer to codec device + * @supplies: pointer to regulator bulk data + * @cdc_vreg: pointer to platform regulator data + * @num_supplies: number of supplies + * @supply_name: supply name to be checked + * + * Return true/false + */ +bool msm_cdc_is_ondemand_supply(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies, + char *supply_name) +{ + bool rc = false; + int ret, i; + + if ((!supply_name) || (!supplies)) { + pr_err("%s: either dev or supplies or cdc_vreg is NULL\n", + __func__); + return rc; + } + /* input parameter validation */ + ret = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies); + if (ret) + return rc; + + for (i = 0; i < num_supplies; i++) { + if (cdc_vreg[i].ondemand && + !strcmp(cdc_vreg[i].name, supply_name)) + return true; + } + + return rc; +} +EXPORT_SYMBOL(msm_cdc_is_ondemand_supply); + /* * msm_cdc_disable_ondemand_supply: * Disable codec ondemand supply diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 8ade1d932868..c90bba491d81 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -2360,6 +2360,67 @@ static int wcd938x_set_compander(struct snd_kcontrol *kcontrol, return 0; } +static int wcd938x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + struct wcd938x_pdata *pdata = NULL; + int ret = 0; + + pdata = dev_get_platdata(wcd938x->dev); + + if (!pdata) { + dev_err(component->dev, "%s: pdata is NULL\n", __func__); + return -EINVAL; + } + + if (!msm_cdc_is_ondemand_supply(wcd938x->dev, + wcd938x->supplies, + pdata->regulator, + pdata->num_supplies, + "cdc-vdd-buck")) + return 0; + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (test_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask)) { + dev_dbg(component->dev, + "%s: buck already in enabled state\n", + __func__); + clear_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask); + return 0; + } + ret = msm_cdc_enable_ondemand_supply(wcd938x->dev, + wcd938x->supplies, + pdata->regulator, + pdata->num_supplies, + "cdc-vdd-buck"); + if (ret == -EINVAL) { + dev_err(component->dev, "%s: vdd buck is not enabled\n", + __func__); + return ret; + } + clear_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask); + /* + * 200us sleep is required after LDO is enabled as per + * HW requirement + */ + usleep_range(200, 250); + break; + case SND_SOC_DAPM_POST_PMD: + set_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask); + break; + } + return 0; +} + + static int wcd938x_ldoh_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2779,6 +2840,10 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("VDD_BUCK", SND_SOC_NOPM, 0, 0, + wcd938x_codec_enable_vdd_buck, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("CLS_H_PORT", 1, SND_SOC_NOPM, 0, 0, wcd938x_enable_clsh, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -2936,6 +3001,7 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = { {"DMIC8_OUTPUT", NULL, "DMIC8_MIXER"}, {"DMIC8_MIXER", "Switch", "DMIC8"}, + {"IN1_HPHL", NULL, "VDD_BUCK"}, {"IN1_HPHL", NULL, "CLS_H_PORT"}, {"RX1", NULL, "IN1_HPHL"}, {"RDAC1", NULL, "RX1"}, @@ -2943,6 +3009,7 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = { {"HPHL PGA", NULL, "HPHL_RDAC"}, {"HPHL", NULL, "HPHL PGA"}, + {"IN2_HPHR", NULL, "VDD_BUCK"}, {"IN2_HPHR", NULL, "CLS_H_PORT"}, {"RX2", NULL, "IN2_HPHR"}, {"RDAC2", NULL, "RX2"}, @@ -2950,6 +3017,7 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = { {"HPHR PGA", NULL, "HPHR_RDAC"}, {"HPHR", NULL, "HPHR PGA"}, + {"IN3_AUX", NULL, "VDD_BUCK"}, {"IN3_AUX", NULL, "CLS_H_PORT"}, {"RX3", NULL, "IN3_AUX"}, {"RDAC4", NULL, "RX3"}, @@ -3792,6 +3860,37 @@ static int wcd938x_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int wcd938x_suspend(struct device *dev) { + struct wcd938x_priv *wcd938x = NULL; + int ret = 0; + struct wcd938x_pdata *pdata = NULL; + + if (!dev) + return -ENODEV; + + wcd938x = dev_get_drvdata(dev); + if (!wcd938x) + return -EINVAL; + + pdata = dev_get_platdata(wcd938x->dev); + + if (!pdata) { + dev_err(dev, "%s: pdata is NULL\n", __func__); + return -EINVAL; + } + + if (test_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask)) { + ret = msm_cdc_disable_ondemand_supply(wcd938x->dev, + wcd938x->supplies, + pdata->regulator, + pdata->num_supplies, + "cdc-vdd-buck"); + if (ret == -EINVAL) { + dev_err(dev, "%s: vdd buck is not disabled\n", + __func__); + return 0; + } + clear_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask); + } return 0; } diff --git a/include/asoc/msm-cdc-supply.h b/include/asoc/msm-cdc-supply.h index c6aacf6bd8e3..cff1a4a18c37 100644 --- a/include/asoc/msm-cdc-supply.h +++ b/include/asoc/msm-cdc-supply.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2016, 2018-2019 The Linux Foundation. All rights reserved. +/* Copyright (c) 2016, 2018-2020 The Linux Foundation. All rights reserved. */ #ifndef __CODEC_POWER_SUPPLY_H__ @@ -21,6 +21,10 @@ struct cdc_regulator { extern int msm_cdc_get_power_supplies(struct device *dev, struct cdc_regulator **cdc_vreg, int *total_num_supplies); +extern bool msm_cdc_is_ondemand_supply(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies, char *supply_name); extern int msm_cdc_disable_ondemand_supply(struct device *dev, struct regulator_bulk_data *supplies, struct cdc_regulator *cdc_vreg, -- GitLab From 6ce71ff66446a0a9d1fa0d6c389f1ae86be72f03 Mon Sep 17 00:00:00 2001 From: Ramlal Karra Date: Thu, 30 Jan 2020 14:03:18 +0530 Subject: [PATCH 1444/1645] ASoC: wsa883x: Enable WSA883x codec driver compilation. Enable WSA883x codec driver compilation support. Change-Id: I263e4eb0e2446c345b250df9e484f380164e77e2 Signed-off-by: Ramlal Karra --- Android.mk | 5 +++++ asoc/codecs/Kbuild | 1 + asoc/codecs/wsa883x/Android.mk | 2 +- asoc/codecs/wsa883x/Kbuild | 4 ++++ config/litoauto.conf | 1 + config/litoautoconf.h | 3 ++- 6 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Android.mk b/Android.mk index f5b893185db7..e0d3f0f509fb 100644 --- a/Android.mk +++ b/Android.mk @@ -60,3 +60,8 @@ include $(MY_LOCAL_PATH)/asoc/codecs/wcd938x/Android.mk $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd937x/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wcd937x/Android.mk endif + +ifeq ($(call is-board-platform-in-list, lito),true) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wsa883x/Module.symvers) +include $(MY_LOCAL_PATH)/asoc/codecs/wsa883x/Android.mk +endif \ No newline at end of file diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 7a2cfcd217b0..5ab7c3b8ba11 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -227,6 +227,7 @@ ifeq ($(KERNEL_BUILD), 1) obj-y += wcd938x/ obj-y += bolero/ obj-y += rouleur/ + obj-y += wsa883x/ endif # Module information used by KBuild framework obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd_core_dlkm.o diff --git a/asoc/codecs/wsa883x/Android.mk b/asoc/codecs/wsa883x/Android.mk index 66056e8c442b..42ad517106c7 100644 --- a/asoc/codecs/wsa883x/Android.mk +++ b/asoc/codecs/wsa883x/Android.mk @@ -9,7 +9,7 @@ endif AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,lahaina),true) +ifeq ($(call is-board-platform-in-list,lahaina lito),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wsa883x/Kbuild b/asoc/codecs/wsa883x/Kbuild index 4eb844af518b..ac608b46c6a3 100644 --- a/asoc/codecs/wsa883x/Kbuild +++ b/asoc/codecs/wsa883x/Kbuild @@ -18,6 +18,10 @@ ifeq ($(KERNEL_BUILD), 0) include $(AUDIO_ROOT)/config/lahainaauto.conf INCS += -include $(AUDIO_ROOT)/config/lahainaautoconf.h endif + ifeq ($(CONFIG_ARCH_LITO), y) + include $(AUDIO_ROOT)/config/litoauto.conf + INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h + endif endif # As per target team, build is done as follows: diff --git a/config/litoauto.conf b/config/litoauto.conf index 12bb1df71705..d1db031fdcca 100644 --- a/config/litoauto.conf +++ b/config/litoauto.conf @@ -3,6 +3,7 @@ CONFIG_AUDIO_EXT_CLK=m CONFIG_SND_SOC_WCD9XXX_V2=m CONFIG_SND_SOC_WCD_MBHC=m CONFIG_SND_SOC_WSA881X=m +CONFIG_SND_SOC_WSA883X=m CONFIG_WCD9XXX_CODEC_CORE_V2=m CONFIG_MSM_CDC_PINCTRL=m CONFIG_MSM_QDSP6V2_CODECS=m diff --git a/config/litoautoconf.h b/config/litoautoconf.h index 0cfdab2d3529..76c47fb1015a 100644 --- a/config/litoautoconf.h +++ b/config/litoautoconf.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #define CONFIG_PINCTRL_LPI 1 @@ -7,6 +7,7 @@ #define CONFIG_SND_SOC_WCD9XXX_V2 1 #define CONFIG_SND_SOC_WCD_MBHC 1 #define CONFIG_SND_SOC_WSA881X 1 +#define CONFIG_SND_SOC_WSA883X 1 #define CONFIG_WCD9XXX_CODEC_CORE_V2 1 #define CONFIG_MSM_CDC_PINCTRL 1 #define CONFIG_MSM_QDSP6V2_CODECS 1 -- GitLab From 832e52704a32b013f422776c2313effea2c89047 Mon Sep 17 00:00:00 2001 From: Ramlal Karra Date: Tue, 4 Feb 2020 19:56:46 +0530 Subject: [PATCH 1445/1645] ASoC: wsa883x: WSA883x codec driver support. WSA883x codec driver support. Change-Id: I08b43771c3690b7e663179d8345f8ed85d41ac88 Signed-off-by: Ramlal Karra --- asoc/codecs/wsa883x/internal.h | 22 +- asoc/codecs/wsa883x/wsa883x-registers.h | 62 ++--- asoc/codecs/wsa883x/wsa883x-regmap.c | 162 ++++++------- asoc/codecs/wsa883x/wsa883x-tables.c | 44 ++-- asoc/codecs/wsa883x/wsa883x.c | 289 +++++++++++++++++++++--- 5 files changed, 425 insertions(+), 154 deletions(-) diff --git a/asoc/codecs/wsa883x/internal.h b/asoc/codecs/wsa883x/internal.h index 2384043fb21b..f2fc381e9859 100644 --- a/asoc/codecs/wsa883x/internal.h +++ b/asoc/codecs/wsa883x/internal.h @@ -1,11 +1,12 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #ifndef WSA883X_INTERNAL_H #define WSA883X_INTERNAL_H +#include #include "wsa883x.h" #include "wsa883x-registers.h" @@ -25,7 +26,11 @@ #define WSA883X_DRV_NAME "wsa883x-codec" #define WSA883X_NUM_RETRY 5 -#define WSA883X_VERSION_ENTRY_SIZE 27 +#define WSA883X_VERSION_ENTRY_SIZE 32 +#define WSA883X_VARIANT_ENTRY_SIZE 32 + +#define WSA883X_VERSION_1_0 0 +#define WSA883X_VERSION_1_1 1 enum { G_18DB = 0, @@ -63,9 +68,9 @@ enum { }; struct wsa_ctrl_platform_data { - void *handle, + void *handle; int (*update_wsa_event)(void *handle, u16 event, u32 data); - int (*register_notifier)(void *handle, struct notifer_block *nblock, + int (*register_notifier)(void *handle, struct notifier_block *nblock, bool enable); }; @@ -97,10 +102,13 @@ struct wsa883x_priv { struct mutex res_lock; struct snd_info_entry *entry; struct snd_info_entry *version_entry; + struct snd_info_entry *variant_entry; struct device_node *wsa_rst_np; int pa_mute; int curr_temp; int variant; + int version; + u8 pa_gain; struct irq_domain *virq; struct wcd_irq_info irq_info; #ifdef CONFIG_DEBUG_FS @@ -116,8 +124,10 @@ struct wsa883x_priv { void *handle; int (*register_notifier)(void *handle, struct notifier_block *nblock, bool enable); + struct delayed_work vbat_work; + struct cdc_regulator *regulator; + int num_supplies; + struct regulator_bulk_data *supplies; }; -static int32_t wsa883x_resource_acquire(struct snd_soc_component *component, - bool enable); #endif /* WSA883X_INTERNAL_H */ diff --git a/asoc/codecs/wsa883x/wsa883x-registers.h b/asoc/codecs/wsa883x/wsa883x-registers.h index 7e518d2fd04b..6450a45b8c56 100644 --- a/asoc/codecs/wsa883x/wsa883x-registers.h +++ b/asoc/codecs/wsa883x/wsa883x-registers.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015, 2019-2020, The Linux Foundation. All rights reserved. */ #ifndef WSA883X_REGISTERS_H @@ -15,7 +15,7 @@ enum { RD_WR_REG, }; -#define WSA883X_ANA_BG_TSADC_BASE (WSA883X_BASE+0x00000000) +#define WSA883X_ANA_BG_TSADC_BASE (WSA883X_BASE+0x00000001) #define WSA883X_REF_CTRL (WSA883X_ANA_BG_TSADC_BASE+0x0000) #define WSA883X_TEST_CTL_0 (WSA883X_ANA_BG_TSADC_BASE+0x0001) #define WSA883X_BIAS_0 (WSA883X_ANA_BG_TSADC_BASE+0x0002) @@ -69,8 +69,8 @@ enum { #define WSA883X_SPKR_DRV_LF_MASK_DCC_CTL (WSA883X_ANA_SPK_TOP_BASE+0x000F) #define WSA883X_SPKR_DRV_LF_MISC_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0010) #define WSA883X_SPKR_DRV_LF_REG_GAIN (WSA883X_ANA_SPK_TOP_BASE+0x0011) -#define WSA883X_SPKR_DRV_LF_OS_CAL_CTL1 (WSA883X_ANA_SPK_TOP_BASE+0x0012) -#define WSA883X_SPKR_DRV_LF_OS_CAL_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0013) +#define WSA883X_SPKR_DRV_OS_CAL_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0012) +#define WSA883X_SPKR_DRV_OS_CAL_CTL1 (WSA883X_ANA_SPK_TOP_BASE+0x0013) #define WSA883X_SPKR_PWM_CLK_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0014) #define WSA883X_SPKR_PDRV_HS_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0015) #define WSA883X_SPKR_PDRV_LS_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0016) @@ -81,7 +81,7 @@ enum { #define WSA883X_PA_STATUS1 (WSA883X_ANA_SPK_TOP_BASE+0x001B) #define WSA883X_PA_STATUS2 (WSA883X_ANA_SPK_TOP_BASE+0x001C) -#define WSA883X_ANA_BOOST_BASE (WSA883X_BASE+0x00000045) +#define WSA883X_ANA_BOOST_BASE (WSA883X_BASE+0x00000043) #define WSA883X_EN_CTRL (WSA883X_ANA_BOOST_BASE+0x0000) #define WSA883X_CURRENT_LIMIT (WSA883X_ANA_BOOST_BASE+0x0001) #define WSA883X_IBIAS1 (WSA883X_ANA_BOOST_BASE+0x0002) @@ -92,34 +92,35 @@ enum { #define WSA883X_STABILITY_CTRL2 (WSA883X_ANA_BOOST_BASE+0x0007) #define WSA883X_PWRSTAGE_CTRL1 (WSA883X_ANA_BOOST_BASE+0x0008) #define WSA883X_PWRSTAGE_CTRL2 (WSA883X_ANA_BOOST_BASE+0x0009) -#define WSA883X_UVLO (WSA883X_ANA_BOOST_BASE+0x000A) -#define WSA883X_SEQUENCE_CTRL (WSA883X_ANA_BOOST_BASE+0x000B) +#define WSA883X_BYPASS_1 (WSA883X_ANA_BOOST_BASE+0x000A) +#define WSA883X_BYPASS_2 (WSA883X_ANA_BOOST_BASE+0x000B) #define WSA883X_ZX_CTRL_1 (WSA883X_ANA_BOOST_BASE+0x000C) #define WSA883X_ZX_CTRL_2 (WSA883X_ANA_BOOST_BASE+0x000D) #define WSA883X_MISC1 (WSA883X_ANA_BOOST_BASE+0x000E) #define WSA883X_MISC2 (WSA883X_ANA_BOOST_BASE+0x000F) #define WSA883X_GMAMP_SUP1 (WSA883X_ANA_BOOST_BASE+0x0010) #define WSA883X_PWRSTAGE_CTRL3 (WSA883X_ANA_BOOST_BASE+0x0011) -#define WSA883X_PRSTAGE_CTRL4 (WSA883X_ANA_BOOST_BASE+0x0012) -#define WSA883X_SPARE1 (WSA883X_ANA_BOOST_BASE+0x0013) +#define WSA883X_PWRSTAGE_CTRL4 (WSA883X_ANA_BOOST_BASE+0x0012) +#define WSA883X_TEST1 (WSA883X_ANA_BOOST_BASE+0x0013) +#define WSA883X_SPARE1 (WSA883X_ANA_BOOST_BASE+0x0014) +#define WSA883X_SPARE2 (WSA883X_ANA_BOOST_BASE+0x0015) #define WSA883X_ANA_PON_LDOL_BASE (WSA883X_BASE+0x00000059) #define WSA883X_PON_CTL_0 (WSA883X_ANA_PON_LDOL_BASE+0x0000) #define WSA883X_PON_CLT_1 (WSA883X_ANA_PON_LDOL_BASE+0x0001) #define WSA883X_PON_CTL_2 (WSA883X_ANA_PON_LDOL_BASE+0x0002) #define WSA883X_PON_CTL_3 (WSA883X_ANA_PON_LDOL_BASE+0x0003) -#define WSA883X_PON_CTL_4 (WSA883X_ANA_PON_LDOL_BASE+0x0004) -#define WSA883X_CKWD_CTL_0 (WSA883X_ANA_PON_LDOL_BASE+0x0005) -#define WSA883X_CKWD_CTL_1 (WSA883X_ANA_PON_LDOL_BASE+0x0006) -#define WSA883X_CKWD_CTL_2 (WSA883X_ANA_PON_LDOL_BASE+0x0007) -#define WSA883X_CKSK_CTL_0 (WSA883X_ANA_PON_LDOL_BASE+0x0008) +#define WSA883X_CKWD_CTL_0 (WSA883X_ANA_PON_LDOL_BASE+0x0004) +#define WSA883X_CKWD_CTL_1 (WSA883X_ANA_PON_LDOL_BASE+0x0005) +#define WSA883X_CKWD_CTL_2 (WSA883X_ANA_PON_LDOL_BASE+0x0006) +#define WSA883X_CKSK_CTL_0 (WSA883X_ANA_PON_LDOL_BASE+0x0007) +#define WSA883X_PADSW_CTL_0 (WSA883X_ANA_PON_LDOL_BASE+0x0008) #define WSA883X_TEST_0 (WSA883X_ANA_PON_LDOL_BASE+0x0009) #define WSA883X_TEST_1 (WSA883X_ANA_PON_LDOL_BASE+0x000A) #define WSA883X_STATUS_0 (WSA883X_ANA_PON_LDOL_BASE+0x000B) #define WSA883X_STATUS_1 (WSA883X_ANA_PON_LDOL_BASE+0x000C) #define WSA883X_DIG_CTRL_BASE (WSA883X_BASE+0x00000400) -#define WSA883X_PAGE_REGISTER (WSA883X_DIG_CTRL_BASE+0x0000) #define WSA883X_CHIP_ID0 (WSA883X_DIG_CTRL_BASE+0x0001) #define WSA883X_CHIP_ID1 (WSA883X_DIG_CTRL_BASE+0x0002) #define WSA883X_CHIP_ID2 (WSA883X_DIG_CTRL_BASE+0x0003) @@ -130,6 +131,7 @@ enum { #define WSA883X_CDC_PATH_MODE (WSA883X_DIG_CTRL_BASE+0x0008) #define WSA883X_CDC_CLK_CTL (WSA883X_DIG_CTRL_BASE+0x0009) #define WSA883X_SWR_RESET_EN (WSA883X_DIG_CTRL_BASE+0x000A) +#define WSA883X_RESET_CTL (WSA883X_DIG_CTRL_BASE+0x000B) #define WSA883X_PA_FSM_CTL (WSA883X_DIG_CTRL_BASE+0x0010) #define WSA883X_PA_FSM_TIMER0 (WSA883X_DIG_CTRL_BASE+0x0011) #define WSA883X_PA_FSM_TIMER1 (WSA883X_DIG_CTRL_BASE+0x0012) @@ -137,6 +139,7 @@ enum { #define WSA883X_PA_FSM_ERR_COND (WSA883X_DIG_CTRL_BASE+0x0014) #define WSA883X_PA_FSM_MSK (WSA883X_DIG_CTRL_BASE+0x0015) #define WSA883X_PA_FSM_BYP (WSA883X_DIG_CTRL_BASE+0x0016) +#define WSA883X_PA_FSM_DBG (WSA883X_DIG_CTRL_BASE+0x0017) #define WSA883X_TADC_VALUE_CTL (WSA883X_DIG_CTRL_BASE+0x0020) #define WSA883X_TEMP_DETECT_CTL (WSA883X_DIG_CTRL_BASE+0x0021) #define WSA883X_TEMP_MSB (WSA883X_DIG_CTRL_BASE+0x0022) @@ -208,8 +211,10 @@ enum { #define WSA883X_WAVG_PER_2_3 (WSA883X_DIG_CTRL_BASE+0x0068) #define WSA883X_WAVG_PER_4_5 (WSA883X_DIG_CTRL_BASE+0x0069) #define WSA883X_WAVG_PER_6_7 (WSA883X_DIG_CTRL_BASE+0x006A) +#define WSA883X_WAVG_STA (WSA883X_DIG_CTRL_BASE+0x006B) #define WSA883X_DRE_CTL_0 (WSA883X_DIG_CTRL_BASE+0x006C) #define WSA883X_DRE_CTL_1 (WSA883X_DIG_CTRL_BASE+0x006D) +#define WSA883X_DRE_IDLE_DET_CTL (WSA883X_DIG_CTRL_BASE+0x006E) #define WSA883X_CLSH_CTL_0 (WSA883X_DIG_CTRL_BASE+0x0070) #define WSA883X_CLSH_CTL_1 (WSA883X_DIG_CTRL_BASE+0x0071) #define WSA883X_CLSH_V_HD_PA (WSA883X_DIG_CTRL_BASE+0x0072) @@ -249,26 +254,28 @@ enum { #define WSA883X_I2C_SLAVE_CTL (WSA883X_DIG_CTRL_BASE+0x0097) #define WSA883X_PDM_TEST_MODE (WSA883X_DIG_CTRL_BASE+0x00A0) #define WSA883X_ATE_TEST_MODE (WSA883X_DIG_CTRL_BASE+0x00A1) -#define WSA883X_DRE_TEST (WSA883X_DIG_CTRL_BASE+0x00A2) #define WSA883X_DIG_DEBUG_MODE (WSA883X_DIG_CTRL_BASE+0x00A3) #define WSA883X_DIG_DEBUG_SEL (WSA883X_DIG_CTRL_BASE+0x00A4) #define WSA883X_DIG_DEBUG_EN (WSA883X_DIG_CTRL_BASE+0x00A5) #define WSA883X_SWR_HM_TEST0 (WSA883X_DIG_CTRL_BASE+0x00A6) #define WSA883X_SWR_HM_TEST1 (WSA883X_DIG_CTRL_BASE+0x00A7) #define WSA883X_SWR_PAD_CTL (WSA883X_DIG_CTRL_BASE+0x00A8) -#define WSA883X_TEMP_DETECT_DBG_CTL (WSA883X_DIG_CTRL_BASE+0x00A9) -#define WSA883X_TEMP_DEBUG_MSB (WSA883X_DIG_CTRL_BASE+0x00AA) -#define WSA883X_TEMP_DEBUG_LSB (WSA883X_DIG_CTRL_BASE+0x00AB) +#define WSA883X_TADC_DETECT_DBG_CTL (WSA883X_DIG_CTRL_BASE+0x00A9) +#define WSA883X_TADC_DEBUG_MSB (WSA883X_DIG_CTRL_BASE+0x00AA) +#define WSA883X_TADC_DEBUG_LSB (WSA883X_DIG_CTRL_BASE+0x00AB) #define WSA883X_SAMPLE_EDGE_SEL (WSA883X_DIG_CTRL_BASE+0x00AC) -#define WSA883X_TEST_MODE_CTL (WSA883X_DIG_CTRL_BASE+0x00AD) -#define WSA883X_IOPAD_CTL (WSA883X_DIG_CTRL_BASE+0x00AE) -#define WSA883X_SPARE_0 (WSA883X_DIG_CTRL_BASE+0x00B0) -#define WSA883X_SPARE_1 (WSA883X_DIG_CTRL_BASE+0x00B1) -#define WSA883X_SPARE_2 (WSA883X_DIG_CTRL_BASE+0x00B2) +#define WSA883X_SWR_EDGE_SEL (WSA883X_DIG_CTRL_BASE+0x00AD) +#define WSA883X_TEST_MODE_CTL (WSA883X_DIG_CTRL_BASE+0x00AE) +#define WSA883X_IOPAD_CTL (WSA883X_DIG_CTRL_BASE+0x00AF) +#define WSA883X_ANA_CSR_DBG_ADD (WSA883X_DIG_CTRL_BASE+0x00B0) +#define WSA883X_ANA_CSR_DBG_CTL (WSA883X_DIG_CTRL_BASE+0x00B1) +#define WSA883X_SPARE_R (WSA883X_DIG_CTRL_BASE+0x00BC) +#define WSA883X_SPARE_0 (WSA883X_DIG_CTRL_BASE+0x00BD) +#define WSA883X_SPARE_1 (WSA883X_DIG_CTRL_BASE+0x00BE) +#define WSA883X_SPARE_2 (WSA883X_DIG_CTRL_BASE+0x00BF) #define WSA883X_SCODE (WSA883X_DIG_CTRL_BASE+0x00C0) #define WSA883X_DIG_TRIM_BASE (WSA883X_BASE+0x00000500) -#define WSA883X_PAGE_REGISTER (WSA883X_DIG_TRIM_BASE+0x0000) #define WSA883X_OTP_REG_0 (WSA883X_DIG_TRIM_BASE+0x0080) #define WSA883X_OTP_REG_1 (WSA883X_DIG_TRIM_BASE+0x0081) #define WSA883X_OTP_REG_2 (WSA883X_DIG_TRIM_BASE+0x0082) @@ -301,7 +308,10 @@ enum { #define WSA883X_OTP_REG_29 (WSA883X_DIG_TRIM_BASE+0x009D) #define WSA883X_OTP_REG_30 (WSA883X_DIG_TRIM_BASE+0x009E) #define WSA883X_OTP_REG_31 (WSA883X_DIG_TRIM_BASE+0x009F) -#define WSA883X_OTP_REG_SCODE (WSA883X_DIG_TRIM_BASE+0x00A0) +#define WSA883X_OTP_REG_32 (WSA883X_DIG_TRIM_BASE+0x00A0) +#define WSA883X_OTP_REG_33 (WSA883X_DIG_TRIM_BASE+0x00A1) +#define WSA883X_OTP_REG_34 (WSA883X_DIG_TRIM_BASE+0x00A2) +#define WSA883X_OTP_REG_35 (WSA883X_DIG_TRIM_BASE+0x00A3) #define WSA883X_OTP_REG_63 (WSA883X_DIG_TRIM_BASE+0x00BF) #define WSA883X_DIG_EMEM_BASE (WSA883X_BASE+0x000005C0) diff --git a/asoc/codecs/wsa883x/wsa883x-regmap.c b/asoc/codecs/wsa883x/wsa883x-regmap.c index 8394e9c73e72..b55fbad25145 100644 --- a/asoc/codecs/wsa883x/wsa883x-regmap.c +++ b/asoc/codecs/wsa883x/wsa883x-regmap.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2016, 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016, 2019-2020, The Linux Foundation. All rights reserved. */ #include @@ -11,100 +11,101 @@ extern const u8 wsa883x_reg_access[WSA883X_NUM_REGISTERS]; static struct reg_default wsa883x_defaults[] = { - {WSA883X_REF_CTRL, 0x6C}, + {WSA883X_REF_CTRL, 0xD5}, {WSA883X_TEST_CTL_0, 0x06}, {WSA883X_BIAS_0, 0xD2}, {WSA883X_OP_CTL, 0xE0}, - {WSA883X_IREF_CTL, 0x58}, + {WSA883X_IREF_CTL, 0x57}, {WSA883X_ISENS_CTL, 0x47}, {WSA883X_CLK_CTL, 0x87}, {WSA883X_TEST_CTL_1, 0x00}, {WSA883X_BIAS_1, 0x51}, - {WSA883X_ADC_CTL, 0x03}, + {WSA883X_ADC_CTL, 0x01}, {WSA883X_DOUT_MSB, 0x00}, {WSA883X_DOUT_LSB, 0x00}, - {WSA883X_VBAT_SNS, 0x00}, - {WSA883X_ITRIM_CODE, 0x1F}, - {WSA883X_EN, 0x00}, + {WSA883X_VBAT_SNS, 0x40}, + {WSA883X_ITRIM_CODE, 0x9F}, + {WSA883X_EN, 0x20}, {WSA883X_OVERRIDE1, 0x00}, {WSA883X_OVERRIDE2, 0x08}, {WSA883X_VSENSE1, 0xD3}, {WSA883X_ISENSE1, 0xD4}, {WSA883X_ISENSE2, 0x20}, {WSA883X_ISENSE_CAL, 0x00}, - {WSA883X_MISC, 0x00}, + {WSA883X_MISC, 0x08}, {WSA883X_ADC_0, 0x00}, {WSA883X_ADC_1, 0x00}, - {WSA883X_ADC_2, 0x00}, - {WSA883X_ADC_3, 0x00}, - {WSA883X_ADC_4, 0x45}, - {WSA883X_ADC_5, 0x20}, - {WSA883X_ADC_6, 0x10}, - {WSA883X_ADC_7, 0x00}, + {WSA883X_ADC_2, 0x40}, + {WSA883X_ADC_3, 0x80}, + {WSA883X_ADC_4, 0x25}, + {WSA883X_ADC_5, 0x25}, + {WSA883X_ADC_6, 0x08}, + {WSA883X_ADC_7, 0x81}, {WSA883X_STATUS, 0x00}, - {WSA883X_DAC_CTRL_REG, 0x41}, + {WSA883X_DAC_CTRL_REG, 0x53}, {WSA883X_DAC_EN_DEBUG_REG, 0x00}, {WSA883X_DAC_OPAMP_BIAS1_REG, 0x48}, {WSA883X_DAC_OPAMP_BIAS2_REG, 0x48}, - {WSA883X_DAC_VCM_CTRL_REG, 0x0B}, - {WSA883X_DAC_VOLTAGE_CTRL_REG, 0x05}, + {WSA883X_DAC_VCM_CTRL_REG, 0x88}, + {WSA883X_DAC_VOLTAGE_CTRL_REG, 0xA5}, {WSA883X_ATEST1_REG, 0x00}, {WSA883X_ATEST2_REG, 0x00}, - {WSA883X_SPKR_TOP_BIAS_REG1, 0x4A}, + {WSA883X_SPKR_TOP_BIAS_REG1, 0x6A}, {WSA883X_SPKR_TOP_BIAS_REG2, 0x65}, {WSA883X_SPKR_TOP_BIAS_REG3, 0x55}, {WSA883X_SPKR_TOP_BIAS_REG4, 0xA9}, - {WSA883X_SPKR_CLIP_DET_REG, 0x00}, + {WSA883X_SPKR_CLIP_DET_REG, 0x9C}, {WSA883X_SPKR_DRV_LF_BLK_EN, 0x0F}, {WSA883X_SPKR_DRV_LF_EN, 0x0A}, {WSA883X_SPKR_DRV_LF_MASK_DCC_CTL, 0x00}, - {WSA883X_SPKR_DRV_LF_MISC_CTL, 0x32}, + {WSA883X_SPKR_DRV_LF_MISC_CTL, 0x3A}, {WSA883X_SPKR_DRV_LF_REG_GAIN, 0x00}, - {WSA883X_SPKR_DRV_LF_OS_CAL_CTL1, 0x90}, - {WSA883X_SPKR_DRV_LF_OS_CAL_CTL, 0x00}, + {WSA883X_SPKR_DRV_OS_CAL_CTL, 0x00}, + {WSA883X_SPKR_DRV_OS_CAL_CTL1, 0x90}, {WSA883X_SPKR_PWM_CLK_CTL, 0x00}, - {WSA883X_SPKR_PDRV_HS_CTL, 0x50}, + {WSA883X_SPKR_PDRV_HS_CTL, 0x52}, {WSA883X_SPKR_PDRV_LS_CTL, 0x48}, - {WSA883X_SPKR_PWRSTG_DBG, 0x00}, - {WSA883X_SPKR_OCP_CTL, 0x00}, - {WSA883X_SPKR_BBM_CTL, 0x90}, + {WSA883X_SPKR_PWRSTG_DBG, 0x08}, + {WSA883X_SPKR_OCP_CTL, 0xE2}, + {WSA883X_SPKR_BBM_CTL, 0x92}, {WSA883X_PA_STATUS0, 0x00}, {WSA883X_PA_STATUS1, 0x00}, - {WSA883X_PA_STATUS2, 0x00}, - {WSA883X_EN_CTRL, 0x54}, - {WSA883X_CURRENT_LIMIT, 0x90}, + {WSA883X_PA_STATUS2, 0x80}, + {WSA883X_EN_CTRL, 0x44}, + {WSA883X_CURRENT_LIMIT, 0xCC}, {WSA883X_IBIAS1, 0x00}, {WSA883X_IBIAS2, 0x00}, {WSA883X_IBIAS3, 0x00}, - {WSA883X_LDO_PROG, 0x2A}, + {WSA883X_LDO_PROG, 0x02}, {WSA883X_STABILITY_CTRL1, 0x8E}, - {WSA883X_STABILITY_CTRL2, 0x00}, - {WSA883X_PWRSTAGE_CTRL1, 0x00}, - {WSA883X_PWRSTAGE_CTRL2, 0x40}, - {WSA883X_UVLO, 0xE9}, - {WSA883X_SEQUENCE_CTRL, 0x11}, + {WSA883X_STABILITY_CTRL2, 0x10}, + {WSA883X_PWRSTAGE_CTRL1, 0x06}, + {WSA883X_PWRSTAGE_CTRL2, 0x00}, + {WSA883X_BYPASS_1, 0x19}, + {WSA883X_BYPASS_2, 0x13}, {WSA883X_ZX_CTRL_1, 0xF0}, - {WSA883X_ZX_CTRL_2, 0x06}, - {WSA883X_MISC1, 0x02}, - {WSA883X_MISC2, 0x81}, - {WSA883X_GMAMP_SUP1, 0x84}, - {WSA883X_PWRSTAGE_CTRL3, 0x14}, - {WSA883X_PRSTAGE_CTRL4, 0x5F}, + {WSA883X_ZX_CTRL_2, 0x04}, + {WSA883X_MISC1, 0x06}, + {WSA883X_MISC2, 0xA0}, + {WSA883X_GMAMP_SUP1, 0x82}, + {WSA883X_PWRSTAGE_CTRL3, 0x39}, + {WSA883X_PWRSTAGE_CTRL4, 0x5F}, + {WSA883X_TEST1, 0x00}, {WSA883X_SPARE1, 0x00}, - {WSA883X_PON_CTL_0, 0xE3}, - {WSA883X_PON_CLT_1, 0x70}, - {WSA883X_PON_CTL_2, 0x00}, - {WSA883X_PON_CTL_3, 0x00}, - {WSA883X_PON_CTL_4, 0x00}, + {WSA883X_SPARE2, 0x00}, + {WSA883X_PON_CTL_0, 0x10}, + {WSA883X_PON_CLT_1, 0xE0}, + {WSA883X_PON_CTL_2, 0x90}, + {WSA883X_PON_CTL_3, 0x70}, {WSA883X_CKWD_CTL_0, 0x34}, - {WSA883X_CKWD_CTL_1, 0x80}, + {WSA883X_CKWD_CTL_1, 0x0F}, {WSA883X_CKWD_CTL_2, 0x00}, - {WSA883X_CKSK_CTL_0, 0x0A}, + {WSA883X_CKSK_CTL_0, 0x00}, + {WSA883X_PADSW_CTL_0, 0x00}, {WSA883X_TEST_0, 0x00}, {WSA883X_TEST_1, 0x00}, {WSA883X_STATUS_0, 0x00}, {WSA883X_STATUS_1, 0x00}, - {WSA883X_PAGE_REGISTER, 0x00}, {WSA883X_CHIP_ID0, 0x00}, {WSA883X_CHIP_ID1, 0x00}, {WSA883X_CHIP_ID2, 0x02}, @@ -115,13 +116,15 @@ static struct reg_default wsa883x_defaults[] = { {WSA883X_CDC_PATH_MODE, 0x00}, {WSA883X_CDC_CLK_CTL, 0xFF}, {WSA883X_SWR_RESET_EN, 0x00}, + {WSA883X_RESET_CTL, 0x00}, {WSA883X_PA_FSM_CTL, 0x00}, {WSA883X_PA_FSM_TIMER0, 0x80}, {WSA883X_PA_FSM_TIMER1, 0x80}, {WSA883X_PA_FSM_STA, 0x00}, {WSA883X_PA_FSM_ERR_COND, 0x00}, {WSA883X_PA_FSM_MSK, 0x00}, - {WSA883X_PA_FSM_BYP, 0x00}, + {WSA883X_PA_FSM_BYP, 0x01}, + {WSA883X_PA_FSM_DBG, 0x00}, {WSA883X_TADC_VALUE_CTL, 0x03}, {WSA883X_TEMP_DETECT_CTL, 0x01}, {WSA883X_TEMP_MSB, 0x00}, @@ -193,15 +196,17 @@ static struct reg_default wsa883x_defaults[] = { {WSA883X_WAVG_PER_2_3, 0x88}, {WSA883X_WAVG_PER_4_5, 0x88}, {WSA883X_WAVG_PER_6_7, 0x88}, - {WSA883X_DRE_CTL_0, 0x30}, - {WSA883X_DRE_CTL_1, 0x20}, + {WSA883X_WAVG_STA, 0x00}, + {WSA883X_DRE_CTL_0, 0x70}, + {WSA883X_DRE_CTL_1, 0x08}, + {WSA883X_DRE_IDLE_DET_CTL, 0x1F}, {WSA883X_CLSH_CTL_0, 0x37}, {WSA883X_CLSH_CTL_1, 0x81}, {WSA883X_CLSH_V_HD_PA, 0x0F}, {WSA883X_CLSH_V_PA_MIN, 0x00}, {WSA883X_CLSH_OVRD_VAL, 0x00}, {WSA883X_CLSH_HARD_MAX, 0xFF}, - {WSA883X_CLSH_SOFT_MAX, 0xFF}, + {WSA883X_CLSH_SOFT_MAX, 0xF5}, {WSA883X_CLSH_SIG_DP, 0x00}, {WSA883X_TAGC_CTL, 0x10}, {WSA883X_TAGC_TIME, 0x20}, @@ -212,18 +217,18 @@ static struct reg_default wsa883x_defaults[] = { {WSA883X_VAGC_ATTN_LVL_1_2, 0x21}, {WSA883X_VAGC_ATTN_LVL_3, 0x03}, {WSA883X_INTR_MODE, 0x00}, - {WSA883X_INTR_MASK0, 0x1B}, - {WSA883X_INTR_MASK1, 0x03}, + {WSA883X_INTR_MASK0, 0x90}, + {WSA883X_INTR_MASK1, 0x00}, {WSA883X_INTR_STATUS0, 0x00}, {WSA883X_INTR_STATUS1, 0x00}, {WSA883X_INTR_CLEAR0, 0x00}, - {WSA883X_INTR_CLEAR1, 0x03}, + {WSA883X_INTR_CLEAR1, 0x00}, {WSA883X_INTR_LEVEL0, 0x00}, - {WSA883X_INTR_LEVEL1, 0x03}, + {WSA883X_INTR_LEVEL1, 0x00}, {WSA883X_INTR_SET0, 0x00}, - {WSA883X_INTR_SET1, 0x03}, + {WSA883X_INTR_SET1, 0x00}, {WSA883X_INTR_TEST0, 0x00}, - {WSA883X_INTR_TEST1, 0x03}, + {WSA883X_INTR_TEST1, 0x00}, {WSA883X_OTP_CTRL0, 0x00}, {WSA883X_OTP_CTRL1, 0x00}, {WSA883X_HDRIVE_CTL_GROUP1, 0x00}, @@ -234,25 +239,27 @@ static struct reg_default wsa883x_defaults[] = { {WSA883X_I2C_SLAVE_CTL, 0x00}, {WSA883X_PDM_TEST_MODE, 0x00}, {WSA883X_ATE_TEST_MODE, 0x00}, - {WSA883X_DRE_TEST, 0x00}, {WSA883X_DIG_DEBUG_MODE, 0x00}, {WSA883X_DIG_DEBUG_SEL, 0x00}, {WSA883X_DIG_DEBUG_EN, 0x00}, {WSA883X_SWR_HM_TEST0, 0x08}, {WSA883X_SWR_HM_TEST1, 0x00}, - {WSA883X_SWR_PAD_CTL, 0x45}, - {WSA883X_TEMP_DETECT_DBG_CTL, 0x00}, - {WSA883X_TEMP_DEBUG_MSB, 0x00}, - {WSA883X_TEMP_DEBUG_LSB, 0x00}, + {WSA883X_SWR_PAD_CTL, 0x37}, + {WSA883X_TADC_DETECT_DBG_CTL, 0x00}, + {WSA883X_TADC_DEBUG_MSB, 0x00}, + {WSA883X_TADC_DEBUG_LSB, 0x00}, {WSA883X_SAMPLE_EDGE_SEL, 0x7F}, - {WSA883X_TEST_MODE_CTL, 0x00}, + {WSA883X_SWR_EDGE_SEL, 0x00}, + {WSA883X_TEST_MODE_CTL, 0x04}, {WSA883X_IOPAD_CTL, 0x00}, + {WSA883X_ANA_CSR_DBG_ADD, 0x00}, + {WSA883X_ANA_CSR_DBG_CTL, 0x12}, + {WSA883X_SPARE_R, 0x00}, {WSA883X_SPARE_0, 0x00}, {WSA883X_SPARE_1, 0x00}, {WSA883X_SPARE_2, 0x00}, {WSA883X_SCODE, 0x00}, - {WSA883X_PAGE_REGISTER, 0x00}, - {WSA883X_OTP_REG_0, 0x01}, + {WSA883X_OTP_REG_0, 0x05}, {WSA883X_OTP_REG_1, 0xFF}, {WSA883X_OTP_REG_2, 0xC0}, {WSA883X_OTP_REG_3, 0xFF}, @@ -276,15 +283,18 @@ static struct reg_default wsa883x_defaults[] = { {WSA883X_OTP_REG_21, 0xFF}, {WSA883X_OTP_REG_22, 0xFF}, {WSA883X_OTP_REG_23, 0xFF}, - {WSA883X_OTP_REG_24, 0x03}, - {WSA883X_OTP_REG_25, 0x01}, + {WSA883X_OTP_REG_24, 0x37}, + {WSA883X_OTP_REG_25, 0x3F}, {WSA883X_OTP_REG_26, 0x03}, - {WSA883X_OTP_REG_27, 0x11}, - {WSA883X_OTP_REG_28, 0x3F}, - {WSA883X_OTP_REG_29, 0x3F}, - {WSA883X_OTP_REG_30, 0x01}, - {WSA883X_OTP_REG_31, 0x01}, - {WSA883X_OTP_REG_SCODE, 0x00}, + {WSA883X_OTP_REG_27, 0x00}, + {WSA883X_OTP_REG_28, 0x00}, + {WSA883X_OTP_REG_29, 0x00}, + {WSA883X_OTP_REG_30, 0x00}, + {WSA883X_OTP_REG_31, 0x03}, + {WSA883X_OTP_REG_32, 0x00}, + {WSA883X_OTP_REG_33, 0xFF}, + {WSA883X_OTP_REG_34, 0x00}, + {WSA883X_OTP_REG_35, 0x00}, {WSA883X_OTP_REG_63, 0x40}, {WSA883X_EMEM_0, 0x00}, {WSA883X_EMEM_1, 0x00}, @@ -377,7 +387,7 @@ static bool wsa883x_volatile_register(struct device *dev, unsigned int reg) !(wsa883x_reg_access[WSA883X_REG(reg)] & WR_REG)); } -struct regmap_config wsa881x_regmap_config = { +struct regmap_config wsa883x_regmap_config = { .reg_bits = 16, .val_bits = 8, .cache_type = REGCACHE_RBTREE, diff --git a/asoc/codecs/wsa883x/wsa883x-tables.c b/asoc/codecs/wsa883x/wsa883x-tables.c index 16b0a880a7ec..c693097d80a1 100644 --- a/asoc/codecs/wsa883x/wsa883x-tables.c +++ b/asoc/codecs/wsa883x/wsa883x-tables.c @@ -1,13 +1,13 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2015, 2020 The Linux Foundation. All rights reserved. */ #include #include #include "wsa883x-registers.h" -const u8 wsa883x_reg_readable[WSA883X_NUM_REGISTERS] = { +const u8 wsa883x_reg_access[WSA883X_NUM_REGISTERS] = { [WSA883X_REG(WSA883X_REF_CTRL)] = RD_WR_REG, [WSA883X_REG(WSA883X_TEST_CTL_0)] = RD_WR_REG, [WSA883X_REG(WSA883X_BIAS_0)] = RD_WR_REG, @@ -57,14 +57,14 @@ const u8 wsa883x_reg_readable[WSA883X_NUM_REGISTERS] = { [WSA883X_REG(WSA883X_SPKR_DRV_LF_MASK_DCC_CTL)] = RD_WR_REG, [WSA883X_REG(WSA883X_SPKR_DRV_LF_MISC_CTL)] = RD_WR_REG, [WSA883X_REG(WSA883X_SPKR_DRV_LF_REG_GAIN)] = RD_WR_REG, - [WSA883X_REG(WSA883X_SPKR_DRV_LF_OS_CAL_CTL1)] = RD_WR_REG, - [WSA883X_REG(WSA883X_SPKR_DRV_LF_OS_CAL_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_DRV_OS_CAL_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPKR_DRV_OS_CAL_CTL1)] = RD_WR_REG, [WSA883X_REG(WSA883X_SPKR_PWM_CLK_CTL)] = RD_WR_REG, [WSA883X_REG(WSA883X_SPKR_PDRV_HS_CTL)] = RD_WR_REG, [WSA883X_REG(WSA883X_SPKR_PDRV_LS_CTL)] = RD_WR_REG, [WSA883X_REG(WSA883X_SPKR_PWRSTG_DBG)] = RD_WR_REG, [WSA883X_REG(WSA883X_SPKR_OCP_CTL)] = RD_WR_REG, - [WSA883X_REG(WSA883X_SPKR_BBM_CTL)] = RD_REG, + [WSA883X_REG(WSA883X_SPKR_BBM_CTL)] = RD_WR_REG, [WSA883X_REG(WSA883X_PA_STATUS0)] = RD_REG, [WSA883X_REG(WSA883X_PA_STATUS1)] = RD_REG, [WSA883X_REG(WSA883X_PA_STATUS2)] = RD_REG, @@ -78,30 +78,31 @@ const u8 wsa883x_reg_readable[WSA883X_NUM_REGISTERS] = { [WSA883X_REG(WSA883X_STABILITY_CTRL2)] = RD_WR_REG, [WSA883X_REG(WSA883X_PWRSTAGE_CTRL1)] = RD_WR_REG, [WSA883X_REG(WSA883X_PWRSTAGE_CTRL2)] = RD_WR_REG, - [WSA883X_REG(WSA883X_UVLO)] = RD_WR_REG, - [WSA883X_REG(WSA883X_SEQUENCE_CTRL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_BYPASS_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_BYPASS_2)] = RD_WR_REG, [WSA883X_REG(WSA883X_ZX_CTRL_1)] = RD_WR_REG, [WSA883X_REG(WSA883X_ZX_CTRL_2)] = RD_WR_REG, [WSA883X_REG(WSA883X_MISC1)] = RD_WR_REG, [WSA883X_REG(WSA883X_MISC2)] = RD_WR_REG, [WSA883X_REG(WSA883X_GMAMP_SUP1)] = RD_WR_REG, [WSA883X_REG(WSA883X_PWRSTAGE_CTRL3)] = RD_WR_REG, - [WSA883X_REG(WSA883X_PRSTAGE_CTRL4)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PWRSTAGE_CTRL4)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TEST1)] = RD_WR_REG, [WSA883X_REG(WSA883X_SPARE1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPARE2)] = RD_WR_REG, [WSA883X_REG(WSA883X_PON_CTL_0)] = RD_WR_REG, [WSA883X_REG(WSA883X_PON_CLT_1)] = RD_WR_REG, [WSA883X_REG(WSA883X_PON_CTL_2)] = RD_WR_REG, [WSA883X_REG(WSA883X_PON_CTL_3)] = RD_WR_REG, - [WSA883X_REG(WSA883X_PON_CTL_4)] = RD_WR_REG, [WSA883X_REG(WSA883X_CKWD_CTL_0)] = RD_WR_REG, [WSA883X_REG(WSA883X_CKWD_CTL_1)] = RD_WR_REG, [WSA883X_REG(WSA883X_CKWD_CTL_2)] = RD_WR_REG, [WSA883X_REG(WSA883X_CKSK_CTL_0)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PADSW_CTL_0)] = RD_WR_REG, [WSA883X_REG(WSA883X_TEST_0)] = RD_WR_REG, [WSA883X_REG(WSA883X_TEST_1)] = RD_WR_REG, [WSA883X_REG(WSA883X_STATUS_0)] = RD_REG, [WSA883X_REG(WSA883X_STATUS_1)] = RD_REG, - [WSA883X_REG(WSA883X_PAGE_REGISTER)] = RD_WR_REG, [WSA883X_REG(WSA883X_CHIP_ID0)] = RD_REG, [WSA883X_REG(WSA883X_CHIP_ID1)] = RD_REG, [WSA883X_REG(WSA883X_CHIP_ID2)] = RD_REG, @@ -112,6 +113,7 @@ const u8 wsa883x_reg_readable[WSA883X_NUM_REGISTERS] = { [WSA883X_REG(WSA883X_CDC_PATH_MODE)] = RD_WR_REG, [WSA883X_REG(WSA883X_CDC_CLK_CTL)] = RD_WR_REG, [WSA883X_REG(WSA883X_SWR_RESET_EN)] = RD_WR_REG, + [WSA883X_REG(WSA883X_RESET_CTL)] = RD_WR_REG, [WSA883X_REG(WSA883X_PA_FSM_CTL)] = RD_WR_REG, [WSA883X_REG(WSA883X_PA_FSM_TIMER0)] = RD_WR_REG, [WSA883X_REG(WSA883X_PA_FSM_TIMER1)] = RD_WR_REG, @@ -119,6 +121,7 @@ const u8 wsa883x_reg_readable[WSA883X_NUM_REGISTERS] = { [WSA883X_REG(WSA883X_PA_FSM_ERR_COND)] = RD_REG, [WSA883X_REG(WSA883X_PA_FSM_MSK)] = RD_WR_REG, [WSA883X_REG(WSA883X_PA_FSM_BYP)] = RD_WR_REG, + [WSA883X_REG(WSA883X_PA_FSM_DBG)] = RD_WR_REG, [WSA883X_REG(WSA883X_TADC_VALUE_CTL)] = RD_WR_REG, [WSA883X_REG(WSA883X_TEMP_DETECT_CTL)] = RD_WR_REG, [WSA883X_REG(WSA883X_TEMP_MSB)] = RD_REG, @@ -190,8 +193,10 @@ const u8 wsa883x_reg_readable[WSA883X_NUM_REGISTERS] = { [WSA883X_REG(WSA883X_WAVG_PER_2_3)] = RD_WR_REG, [WSA883X_REG(WSA883X_WAVG_PER_4_5)] = RD_WR_REG, [WSA883X_REG(WSA883X_WAVG_PER_6_7)] = RD_WR_REG, + [WSA883X_REG(WSA883X_WAVG_STA)] = RD_REG, [WSA883X_REG(WSA883X_DRE_CTL_0)] = RD_WR_REG, [WSA883X_REG(WSA883X_DRE_CTL_1)] = RD_WR_REG, + [WSA883X_REG(WSA883X_DRE_IDLE_DET_CTL)] = RD_WR_REG, [WSA883X_REG(WSA883X_CLSH_CTL_0)] = RD_WR_REG, [WSA883X_REG(WSA883X_CLSH_CTL_1)] = RD_WR_REG, [WSA883X_REG(WSA883X_CLSH_V_HD_PA)] = RD_WR_REG, @@ -231,24 +236,26 @@ const u8 wsa883x_reg_readable[WSA883X_NUM_REGISTERS] = { [WSA883X_REG(WSA883X_I2C_SLAVE_CTL)] = RD_WR_REG, [WSA883X_REG(WSA883X_PDM_TEST_MODE)] = RD_WR_REG, [WSA883X_REG(WSA883X_ATE_TEST_MODE)] = RD_REG, - [WSA883X_REG(WSA883X_DRE_TEST)] = RD_WR_REG, [WSA883X_REG(WSA883X_DIG_DEBUG_MODE)] = RD_WR_REG, [WSA883X_REG(WSA883X_DIG_DEBUG_SEL)] = RD_WR_REG, [WSA883X_REG(WSA883X_DIG_DEBUG_EN)] = RD_WR_REG, [WSA883X_REG(WSA883X_SWR_HM_TEST0)] = RD_WR_REG, [WSA883X_REG(WSA883X_SWR_HM_TEST1)] = RD_REG, [WSA883X_REG(WSA883X_SWR_PAD_CTL)] = RD_WR_REG, - [WSA883X_REG(WSA883X_TEMP_DETECT_DBG_CTL)] = RD_WR_REG, - [WSA883X_REG(WSA883X_TEMP_DEBUG_MSB)] = RD_WR_REG, - [WSA883X_REG(WSA883X_TEMP_DEBUG_LSB)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TADC_DETECT_DBG_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TADC_DEBUG_MSB)] = RD_WR_REG, + [WSA883X_REG(WSA883X_TADC_DEBUG_LSB)] = RD_WR_REG, [WSA883X_REG(WSA883X_SAMPLE_EDGE_SEL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SWR_EDGE_SEL)] = RD_WR_REG, [WSA883X_REG(WSA883X_TEST_MODE_CTL)] = RD_WR_REG, [WSA883X_REG(WSA883X_IOPAD_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ANA_CSR_DBG_ADD)] = RD_WR_REG, + [WSA883X_REG(WSA883X_ANA_CSR_DBG_CTL)] = RD_WR_REG, + [WSA883X_REG(WSA883X_SPARE_R)] = RD_REG, [WSA883X_REG(WSA883X_SPARE_0)] = RD_WR_REG, [WSA883X_REG(WSA883X_SPARE_1)] = RD_WR_REG, [WSA883X_REG(WSA883X_SPARE_2)] = RD_WR_REG, [WSA883X_REG(WSA883X_SCODE)] = RD_WR_REG, - [WSA883X_REG(WSA883X_PAGE_REGISTER)] = RD_WR_REG, [WSA883X_REG(WSA883X_OTP_REG_0)] = RD_WR_REG, [WSA883X_REG(WSA883X_OTP_REG_1)] = RD_WR_REG, [WSA883X_REG(WSA883X_OTP_REG_2)] = RD_WR_REG, @@ -280,8 +287,11 @@ const u8 wsa883x_reg_readable[WSA883X_NUM_REGISTERS] = { [WSA883X_REG(WSA883X_OTP_REG_28)] = RD_WR_REG, [WSA883X_REG(WSA883X_OTP_REG_29)] = RD_WR_REG, [WSA883X_REG(WSA883X_OTP_REG_30)] = RD_WR_REG, - [WSA883X_REG(WSA883X_OTP_REG_31)] = RD_REG, - [WSA883X_REG(WSA883X_OTP_REG_SCODE)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_31)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_32)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_33)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_34)] = RD_WR_REG, + [WSA883X_REG(WSA883X_OTP_REG_35)] = RD_WR_REG, [WSA883X_REG(WSA883X_OTP_REG_63)] = RD_WR_REG, [WSA883X_REG(WSA883X_EMEM_0)] = RD_WR_REG, [WSA883X_REG(WSA883X_EMEM_1)] = RD_WR_REG, diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 08f6858f73ab..4ee07810941c 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #include @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,7 @@ #include #include #include +#include #include "wsa883x.h" #include "internal.h" @@ -34,6 +36,13 @@ #define HIGH_TEMP_THRESHOLD 45 #define TEMP_INVALID 0xFFFF #define WSA883X_TEMP_RETRY 3 +#define WSA883X_VBAT_TIMER_SEC 2 + +static int wsa883x_vbat_timer_sec = WSA883X_VBAT_TIMER_SEC; +module_param(wsa883x_vbat_timer_sec, int, 0664); +MODULE_PARM_DESC(wsa883x_vbat_timer_sec, "timer for VBAT monitor polling"); + +#define DRV_NAME "wsa-codec" enum { WSA_4OHMS =4, @@ -51,6 +60,56 @@ struct wsa_temp_register { u8 dmeas_lsb; }; +struct wsa_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + +static const struct wsa_reg_mask_val reg_init[] = { + {WSA883X_PA_FSM_BYP, 0x01, 0x00}, + {WSA883X_CDC_SPK_DSM_A2_0, 0xFF, 0x0A}, + {WSA883X_CDC_SPK_DSM_A2_1, 0x0F, 0x08}, + {WSA883X_CDC_SPK_DSM_A3_0, 0xFF, 0xF3}, + {WSA883X_CDC_SPK_DSM_A3_1, 0x07, 0x07}, + {WSA883X_CDC_SPK_DSM_A4_0, 0xFF, 0x79}, + {WSA883X_CDC_SPK_DSM_A4_1, 0x03, 0x02}, + {WSA883X_CDC_SPK_DSM_A5_0, 0xFF, 0x0B}, + {WSA883X_CDC_SPK_DSM_A5_1, 0x03, 0x02}, + {WSA883X_CDC_SPK_DSM_A6_0, 0xFF, 0x8A}, + {WSA883X_CDC_SPK_DSM_A7_0, 0xFF, 0x9B}, + {WSA883X_CDC_SPK_DSM_C_0, 0xFF, 0x68}, + {WSA883X_CDC_SPK_DSM_C_1, 0xFF, 0x54}, + {WSA883X_CDC_SPK_DSM_C_2, 0xFF, 0xF2}, + {WSA883X_CDC_SPK_DSM_C_3, 0x3F, 0x20}, + {WSA883X_CDC_SPK_DSM_R1, 0xFF, 0x83}, + {WSA883X_CDC_SPK_DSM_R2, 0xFF, 0x7F}, + {WSA883X_CDC_SPK_DSM_R3, 0xFF, 0x9D}, + {WSA883X_CDC_SPK_DSM_R4, 0xFF, 0x82}, + {WSA883X_CDC_SPK_DSM_R5, 0xFF, 0x8B}, + {WSA883X_CDC_SPK_DSM_R6, 0xFF, 0x9B}, + {WSA883X_CDC_SPK_DSM_R7, 0xFF, 0x3F}, + {WSA883X_DRE_CTL_0, 0xF0, 0x90}, + {WSA883X_DRE_IDLE_DET_CTL, 0x10, 0x00}, + {WSA883X_PDM_WD_CTL, 0x01, 0x01}, + {WSA883X_CURRENT_LIMIT, 0x78, 0x40}, + {WSA883X_DRE_CTL_0, 0x07, 0x02}, + {WSA883X_VAGC_TIME, 0x03, 0x02}, + {WSA883X_VAGC_CTL, 0x01, 0x01}, + {WSA883X_TAGC_CTL, 0x0E, 0x0A}, + {WSA883X_TAGC_TIME, 0x0C, 0x0C}, + {WSA883X_TAGC_E2E_GAIN, 0x1F, 0x02}, + {WSA883X_TEMP_CONFIG0, 0x07, 0x02}, + {WSA883X_TEMP_CONFIG1, 0x07, 0x02}, + {WSA883X_OTP_REG_1, 0xFF, 0x49}, + {WSA883X_OTP_REG_2, 0xC0, 0x80}, + {WSA883X_OTP_REG_3, 0xFF, 0xC9}, + {WSA883X_OTP_REG_4, 0xC0, 0x40}, + {WSA883X_TAGC_CTL, 0x01, 0x01}, + {WSA883X_CKWD_CTL_0, 0x60, 0x00}, + {WSA883X_CKWD_CTL_1, 0x1F, 0x1B}, +}; + static int wsa883x_get_temperature(struct snd_soc_component *component, int *temp); enum { @@ -69,6 +128,7 @@ enum { WSA883X_IRQ_INT_INTR_PIN, WSA883X_IRQ_INT_UVLO, WSA883X_IRQ_INT_PA_ON_ERR, + WSA883X_NUM_IRQS, }; static const struct regmap_irq wsa883x_irqs[WSA883X_NUM_IRQS] = { @@ -535,7 +595,17 @@ static ssize_t wsa883x_codec_version_read(struct snd_info_entry *entry, return -EINVAL; } - len = snprintf(buffer, sizeof(buffer), "WSA883X-SOUNDWIRE_1_0\n"); + switch (wsa883x->version) { + case WSA883X_VERSION_1_0: + len = snprintf(buffer, sizeof(buffer), "WSA883X_1_0\n"); + break; + case WSA883X_VERSION_1_1: + len = snprintf(buffer, sizeof(buffer), "WSA883X_1_1\n"); + break; + default: + len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + break; + } return simple_read_from_buffer(buf, count, &pos, buffer, len); } @@ -544,6 +614,41 @@ static struct snd_info_entry_ops wsa883x_codec_info_ops = { .read = wsa883x_codec_version_read, }; +static ssize_t wsa883x_variant_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, size_t count, + loff_t pos) +{ + struct wsa883x_priv *wsa883x; + char buffer[WSA883X_VARIANT_ENTRY_SIZE]; + int len = 0; + + wsa883x = (struct wsa883x_priv *) entry->private_data; + if (!wsa883x) { + pr_err("%s: wsa883x priv is null\n", __func__); + return -EINVAL; + } + + switch (wsa883x->variant) { + case WSA8830: + len = snprintf(buffer, sizeof(buffer), "WSA8830\n"); + break; + case WSA8835: + len = snprintf(buffer, sizeof(buffer), "WSA8835\n"); + break; + default: + len = snprintf(buffer, sizeof(buffer), "UNDEFINED\n"); + break; + } + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops wsa883x_variant_ops = { + .read = wsa883x_variant_read, +}; + /* * wsa883x_codec_info_create_codec_entry - creates wsa883x module * @codec_root: The parent directory @@ -558,6 +663,7 @@ int wsa883x_codec_info_create_codec_entry(struct snd_info_entry *codec_root, struct snd_soc_component *component) { struct snd_info_entry *version_entry; + struct snd_info_entry *variant_entry; struct wsa883x_priv *wsa883x; struct snd_soc_card *card; char name[80]; @@ -566,11 +672,17 @@ int wsa883x_codec_info_create_codec_entry(struct snd_info_entry *codec_root, return -EINVAL; wsa883x = snd_soc_component_get_drvdata(component); + if (wsa883x->entry) { + dev_dbg(wsa883x->dev, + "%s:wsa883x module already created\n", __func__); + return 0; + } card = component->card; + snprintf(name, sizeof(name), "%s.%x", "wsa883x", (u32)wsa883x->swr_slave->addr); - wsa883x->entry = snd_info_create_subdir(codec_root->module, + wsa883x->entry = snd_info_create_module_entry(codec_root->module, (const char *)name, codec_root); if (!wsa883x->entry) { @@ -579,12 +691,19 @@ int wsa883x_codec_info_create_codec_entry(struct snd_info_entry *codec_root, return -ENOMEM; } + wsa883x->entry->mode = S_IFDIR | 0555; + if (snd_info_register(wsa883x->entry) < 0) { + snd_info_free_entry(wsa883x->entry); + return -ENOMEM; + } + version_entry = snd_info_create_card_entry(card->snd_card, "version", wsa883x->entry); if (!version_entry) { dev_dbg(component->dev, "%s: failed to create wsa883x version entry\n", __func__); + snd_info_free_entry(wsa883x->entry); return -ENOMEM; } @@ -595,22 +714,40 @@ int wsa883x_codec_info_create_codec_entry(struct snd_info_entry *codec_root, if (snd_info_register(version_entry) < 0) { snd_info_free_entry(version_entry); + snd_info_free_entry(wsa883x->entry); return -ENOMEM; } wsa883x->version_entry = version_entry; + variant_entry = snd_info_create_card_entry(card->snd_card, + "variant", + wsa883x->entry); + if (!variant_entry) { + dev_dbg(component->dev, + "%s: failed to create wsa883x variant entry\n", + __func__); + snd_info_free_entry(version_entry); + snd_info_free_entry(wsa883x->entry); + return -ENOMEM; + } + + variant_entry->private_data = wsa883x; + variant_entry->size = WSA883X_VARIANT_ENTRY_SIZE; + variant_entry->content = SNDRV_INFO_CONTENT_DATA; + variant_entry->c.ops = &wsa883x_variant_ops; + + if (snd_info_register(variant_entry) < 0) { + snd_info_free_entry(variant_entry); + snd_info_free_entry(version_entry); + snd_info_free_entry(wsa883x->entry); + return -ENOMEM; + } + wsa883x->variant_entry = variant_entry; + return 0; } EXPORT_SYMBOL(wsa883x_codec_info_create_codec_entry); -static void wsa883x_regcache_sync(struct wsa883x_priv *wsa883x) -{ - mutex_lock(&wsa883x->res_lock); - regcache_mark_dirty(wsa883x->regmap); - regcache_sync(wsa883x->regmap); - mutex_unlock(&wsa883x->res_lock); -} - static int wsa883x_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -819,21 +956,34 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); - int min_gain, max_gain; dev_dbg(component->dev, "%s: %s %d\n", __func__, w->name, event); switch (event) { - case SND_SOC_DAPM_PRE_PMU: - /* TODO Vote for Global PA */ - break; - case SND_SOC_DAPM_POST_PMU: + snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, + 0x01, 0x01); /* Force remove group */ swr_remove_from_group(wsa883x->swr_slave, wsa883x->swr_slave->dev_num); + snd_soc_component_update_bits(component, + WSA883X_VBAT_ADC_FLT_CTL, + 0x0E, 0x06); + snd_soc_component_update_bits(component, + WSA883X_VBAT_ADC_FLT_CTL, + 0x01, 0x01); + schedule_delayed_work(&wsa883x->vbat_work, + msecs_to_jiffies(wsa883x_vbat_timer_sec * 1000)); break; - case SND_SOC_DAPM_POST_PMD: - /* TODO Unvote for Global PA */ + case SND_SOC_DAPM_PRE_PMD: + cancel_delayed_work_sync(&wsa883x->vbat_work); + snd_soc_component_update_bits(component, + WSA883X_VBAT_ADC_FLT_CTL, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WSA883X_VBAT_ADC_FLT_CTL, + 0x0E, 0x00); + snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, + 0x01, 0x00); break; } return 0; @@ -884,10 +1034,14 @@ EXPORT_SYMBOL(wsa883x_set_channel_map); static void wsa883x_codec_init(struct snd_soc_component *component) { struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + int i; if (!wsa883x) return; + for (i = 0; i < ARRAY_SIZE(reg_init); i++) + snd_soc_component_update_bits(component, reg_init[i].reg, + reg_init[i].mask, reg_init[i].val); } static int32_t wsa883x_temp_reg_read(struct snd_soc_component *component, @@ -929,7 +1083,6 @@ static int32_t wsa883x_temp_reg_read(struct snd_soc_component *component, static int wsa883x_get_temperature(struct snd_soc_component *component, int *temp) { - struct snd_soc_component *component; struct wsa_temp_register reg; int dmeas, d1, d2; int ret = 0; @@ -943,7 +1096,7 @@ static int wsa883x_get_temperature(struct snd_soc_component *component, return -EINVAL; do { - ret = wsa883x_temp_reg_read(component, ®) + ret = wsa883x_temp_reg_read(component, ®); if (ret) { pr_err("%s: temp read failed: %d, current temp: %d\n", __func__, ret, wsa883x->curr_temp); @@ -996,10 +1149,42 @@ static int wsa883x_get_temperature(struct snd_soc_component *component, return ret; } +static void wsa883x_vbat_monitor_work(struct work_struct *work) +{ + struct wsa883x_priv *wsa883x; + struct delayed_work *dwork; + struct snd_soc_component *component; + u16 val = 0, vbat_code = 0; + int vbat_val = 0; + + dwork = to_delayed_work(work); + wsa883x = container_of(dwork, struct wsa883x_priv, vbat_work); + component = wsa883x->component; + + val = snd_soc_component_read32(component, WSA883X_VBAT_DIN_MSB); + vbat_code = (val << 2); + val = (snd_soc_component_read32(component, WSA883X_VBAT_DIN_LSB) + & 0xC0); + vbat_code |= (val >> 6); + vbat_val = ((vbat_code * 5) / 1023); + dev_dbg(component->dev, "%s: instant vbat code = %d val = %d\n", + __func__, vbat_code, vbat_val); + + val = snd_soc_component_read32(component, WSA883X_VBAT_DOUT); + vbat_val = ((val * 5) / 255); + + dev_dbg(component->dev, "%s: low pass vbat code = %d val = %d\n", + __func__, val, vbat_val); + + schedule_delayed_work(&wsa883x->vbat_work, + msecs_to_jiffies(wsa883x_vbat_timer_sec * 1000)); +} + static int wsa883x_codec_probe(struct snd_soc_component *component) { struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); struct swr_device *dev; + int variant = 0, version = 0; if (!wsa883x) return -EINVAL; @@ -1007,8 +1192,18 @@ static int wsa883x_codec_probe(struct snd_soc_component *component) dev = wsa883x->swr_slave; wsa883x->component = component; + + variant = (snd_soc_component_read32(component, WSA883X_OTP_REG_0) + & 0x0F); + wsa883x->variant = variant; + + version = (snd_soc_component_read32(component, WSA883X_CHIP_ID0) + & 0xFF); + wsa883x->version = version; + wsa883x_codec_init(component); wsa883x->global_pa_cnt = 0; + INIT_DELAYED_WORK(&wsa883x->vbat_work, wsa883x_vbat_monitor_work); return 0; } @@ -1067,23 +1262,55 @@ static int wsa883x_event_notify(struct notifier_block *nb, switch (event) { case BOLERO_WSA_EVT_PA_OFF_PRE_SSR: + if (delayed_work_pending(&wsa883x->vbat_work)) + cancel_delayed_work_sync(&wsa883x->vbat_work); snd_soc_component_update_bits(wsa883x->component, - WSA883X_SPKR_DRV_GAIN, - 0xF0, 0xC0); - snd_soc_component_update_bits(wsa883x->component, - WSA883X_SPKR_DRV_EN, - 0x80, 0x00); + WSA883X_PA_FSM_CTL, + 0x01, 0x00); break; default: + dev_dbg(wsa883x->dev, "%s: unknown event %d\n", + __func__, event); break; } return 0; } -static int wsa883x_swr_probe(struct swr_device *pdev) +static int wsa883x_enable_supplies(struct device * dev, + struct wsa883x_priv *priv) { int ret = 0; + + /* Parse power supplies */ + msm_cdc_get_power_supplies(dev, &priv->regulator, + &priv->num_supplies); + if (!priv->regulator || (priv->num_supplies <= 0)) { + dev_err(dev, "%s: no power supplies defined\n", __func__); + return -EINVAL; + } + + ret = msm_cdc_init_supplies(dev, &priv->supplies, + priv->regulator, priv->num_supplies); + if (!priv->supplies) { + dev_err(dev, "%s: Cannot init wsa supplies\n", + __func__); + return ret; + } + + ret = msm_cdc_enable_static_supplies(dev, priv->supplies, + priv->regulator, + priv->num_supplies); + if (ret) + dev_err(dev, "%s: wsa static supply enable failed!\n", + __func__); + + return ret; +} + +static int wsa883x_swr_probe(struct swr_device *pdev) +{ + int ret = 0, i = 0; struct wsa883x_priv *wsa883x; u8 devnum = 0; bool pin_state_current = false; @@ -1094,6 +1321,10 @@ static int wsa883x_swr_probe(struct swr_device *pdev) if (!wsa883x) return -ENOMEM; + ret = wsa883x_enable_supplies(&pdev->dev, wsa883x); + if (ret) + return -EINVAL; + wsa883x->wsa_rst_np = of_parse_phandle(pdev->dev.of_node, "qcom,spkr-sd-n-node", 0); if (!wsa883x->wsa_rst_np) { @@ -1109,10 +1340,10 @@ static int wsa883x_swr_probe(struct swr_device *pdev) * soundwire auto enumeration of slave devices as * as per HW requirement. */ - usleep_range(5000, 5010); + usleep_range(20000, 20010); ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum); if (ret) { - dev_dbg(&pdev->dev, + dev_err(&pdev->dev, "%s get devnum %d for dev addr %lx failed\n", __func__, devnum, pdev->addr); goto dev_err; @@ -1136,7 +1367,7 @@ static int wsa883x_swr_probe(struct swr_device *pdev) wsa883x->irq_info.wcd_regmap_irq_chip = &wsa883x_regmap_irq_chip; wsa883x->irq_info.codec_name = "WSA883X"; wsa883x->irq_info.regmap = wsa883x->regmap; - wsa883x->irq_info.dev = dev; + wsa883x->irq_info.dev = &pdev->dev; ret = wcd_irq_init(&wsa883x->irq_info, &wsa883x->virq); if (ret) { -- GitLab From 9a354de6dea277742961134f84afe991980810ee Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 3 Mar 2020 09:25:38 +0530 Subject: [PATCH 1446/1645] ASoC: wsa883x: Update speaker playback sequence Update speaker playback sequence on wsa883x codec to avoid click and pop and loss of VI sense data on speaker. Change-Id: I8ec7072b63bef6c2e7bd64c96df4d98852c4f40d Signed-off-by: Sudheer Papothi --- asoc/codecs/wsa883x/internal.h | 1 + asoc/codecs/wsa883x/wsa883x.c | 25 +++++++++++++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/asoc/codecs/wsa883x/internal.h b/asoc/codecs/wsa883x/internal.h index f2fc381e9859..5e19ac2ab2b6 100644 --- a/asoc/codecs/wsa883x/internal.h +++ b/asoc/codecs/wsa883x/internal.h @@ -65,6 +65,7 @@ enum { BOLERO_WSA_EVT_PA_OFF_PRE_SSR, BOLERO_WSA_EVT_SSR_DOWN, BOLERO_WSA_EVT_SSR_UP, + BOLERO_WSA_EVT_PA_ON_POST_FSCLK, }; struct wsa_ctrl_platform_data { diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 4ee07810941c..50fe49ab4539 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -911,16 +911,8 @@ static int wsa883x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, &port_type[0]); break; case SND_SOC_DAPM_POST_PMU: - swr_slvdev_datapath_control(wsa883x->swr_slave, - wsa883x->swr_slave->dev_num, - true); break; case SND_SOC_DAPM_PRE_PMD: - swr_slvdev_datapath_control(wsa883x->swr_slave, - wsa883x->swr_slave->dev_num, - false); - break; - case SND_SOC_DAPM_POST_PMD: wsa883x_set_port(component, SWR_DAC_PORT, &port_id[num_port], &num_ch[num_port], &ch_mask[num_port], &ch_rate[num_port], @@ -944,6 +936,11 @@ static int wsa883x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, swr_disconnect_port(wsa883x->swr_slave, &port_id[0], num_port, &ch_mask[0], &port_type[0]); break; + case SND_SOC_DAPM_POST_PMD: + swr_slvdev_datapath_control(wsa883x->swr_slave, + wsa883x->swr_slave->dev_num, + false); + break; default: break; } @@ -960,8 +957,10 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, dev_dbg(component->dev, "%s: %s %d\n", __func__, w->name, event); switch (event) { case SND_SOC_DAPM_POST_PMU: - snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, - 0x01, 0x01); + swr_slvdev_datapath_control(wsa883x->swr_slave, + wsa883x->swr_slave->dev_num, + true); + wcd_enable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD); /* Force remove group */ swr_remove_from_group(wsa883x->swr_slave, wsa883x->swr_slave->dev_num); @@ -984,6 +983,7 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, 0x0E, 0x00); snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, 0x01, 0x00); + wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD); break; } return 0; @@ -1268,6 +1268,11 @@ static int wsa883x_event_notify(struct notifier_block *nb, WSA883X_PA_FSM_CTL, 0x01, 0x00); break; + case BOLERO_WSA_EVT_PA_ON_POST_FSCLK: + snd_soc_component_update_bits(wsa883x->component, + WSA883X_PA_FSM_CTL, + 0x01, 0x01); + break; default: dev_dbg(wsa883x->dev, "%s: unknown event %d\n", __func__, event); -- GitLab From a4023899e1a64844f4be9cce9f8b5e0325933a0e Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 5 Feb 2020 00:13:50 +0530 Subject: [PATCH 1447/1645] ASoC: wsa883x: Disable interrupts during bootup Disable interrupts while bringing codec out of reset to avoid fake interrupts. Change-Id: Iec1e6c67429b7424693c2628e6f6d121a4c9ce71 Signed-off-by: Sudheer Papothi --- asoc/codecs/wsa883x/wsa883x.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 50fe49ab4539..bcd59967ca9c 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -1393,15 +1393,23 @@ static int wsa883x_swr_probe(struct swr_device *pdev) wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_OCP, "WSA OCP", wsa883x_ocp_handle_irq, NULL); + wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_OCP); + wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_CLIP, "WSA CLIP", wsa883x_clip_handle_irq, NULL); + wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_CLIP); + wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD, "WSA PDM WD", wsa883x_pdm_wd_handle_irq, NULL); + wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD); + wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_CLK_WD, "WSA CLK WD", wsa883x_clk_wd_handle_irq, NULL); + wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_CLK_WD); + wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_INTR_PIN, "WSA EXT INT", wsa883x_ext_int_handle_irq, NULL); @@ -1412,6 +1420,8 @@ static int wsa883x_swr_probe(struct swr_device *pdev) wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR, "WSA PA ERR", wsa883x_pa_on_err_handle_irq, NULL); + wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR); + ret = snd_soc_register_component(&pdev->dev, &soc_codec_dev_wsa883x, NULL, 0); if (ret) { -- GitLab From d76953687be12bff2cf6459dff92c74fbb4d6b1f Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 16 Mar 2020 19:07:00 +0530 Subject: [PATCH 1448/1645] SoC: wsa883x: Remove from soundwire group during teardown After playback on speaker, remove from soundwire group to properly close the soundwire port configuration. Change-Id: I278e7510869200bc1236eb45968bc8d986a93a96 Signed-off-by: Sudheer Papothi Signed-off-by: Laxminath Kasam --- asoc/codecs/wsa883x/internal.h | 1 + asoc/codecs/wsa883x/wsa883x.c | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wsa883x/internal.h b/asoc/codecs/wsa883x/internal.h index 5e19ac2ab2b6..1863aacf8992 100644 --- a/asoc/codecs/wsa883x/internal.h +++ b/asoc/codecs/wsa883x/internal.h @@ -129,6 +129,7 @@ struct wsa883x_priv { struct cdc_regulator *regulator; int num_supplies; struct regulator_bulk_data *supplies; + unsigned long status_mask; }; #endif /* WSA883X_INTERNAL_H */ diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index bcd59967ca9c..730c7c4d1089 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -117,6 +117,10 @@ enum { WSA8835, }; +enum { + SPKR_STATUS = 0, +}; + enum { WSA883X_IRQ_INT_SAF2WAR = 0, WSA883X_IRQ_INT_WAR2SAF, @@ -937,6 +941,10 @@ static int wsa883x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, &ch_mask[0], &port_type[0]); break; case SND_SOC_DAPM_POST_PMD: + if (swr_set_device_group(wsa883x->swr_slave, SWR_GROUP_NONE)) + dev_err(component->dev, + "%s: set num ch failed\n", __func__); + swr_slvdev_datapath_control(wsa883x->swr_slave, wsa883x->swr_slave->dev_num, false); @@ -972,6 +980,7 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, 0x01, 0x01); schedule_delayed_work(&wsa883x->vbat_work, msecs_to_jiffies(wsa883x_vbat_timer_sec * 1000)); + set_bit(SPKR_STATUS, &wsa883x->status_mask); break; case SND_SOC_DAPM_PRE_PMD: cancel_delayed_work_sync(&wsa883x->vbat_work); @@ -984,6 +993,7 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, 0x01, 0x00); wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD); + clear_bit(SPKR_STATUS, &wsa883x->status_mask); break; } return 0; @@ -1269,7 +1279,8 @@ static int wsa883x_event_notify(struct notifier_block *nb, 0x01, 0x00); break; case BOLERO_WSA_EVT_PA_ON_POST_FSCLK: - snd_soc_component_update_bits(wsa883x->component, + if (test_bit(SPKR_STATUS, &wsa883x->status_mask)) + snd_soc_component_update_bits(wsa883x->component, WSA883X_PA_FSM_CTL, 0x01, 0x01); break; -- GitLab From 9eac251984a410ebb66cd56e75f4fa1df7e4b3aa Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 17 Mar 2020 20:43:05 +0530 Subject: [PATCH 1449/1645] asoc: wsa883x: Fix SSR mute on speaker During SSR/PDR, bring down wsa at down event and restore after SSR up event. Change-Id: I9a8d3c109144cb0a911cd7597bffc220b0ce95b7 Signed-off-by: Laxminath Kasam --- asoc/codecs/wsa883x/wsa883x.c | 60 +++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 730c7c4d1089..1e6757d44751 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -398,6 +398,14 @@ static const struct file_operations codec_debug_dump_ops = { }; #endif +static void wsa883x_regcache_sync(struct wsa883x_priv *wsa883x) +{ + mutex_lock(&wsa883x->res_lock); + regcache_mark_dirty(wsa883x->regmap); + regcache_sync(wsa883x->regmap); + mutex_unlock(&wsa883x->res_lock); +} + static irqreturn_t wsa883x_saf2war_handle_irq(int irq, void *data) { pr_err_ratelimited("%s: interrupt for irq =%d triggered\n", @@ -683,8 +691,8 @@ int wsa883x_codec_info_create_codec_entry(struct snd_info_entry *codec_root, } card = component->card; - snprintf(name, sizeof(name), "%s.%x", "wsa883x", - (u32)wsa883x->swr_slave->addr); + snprintf(name, sizeof(name), "%s.%llx", "wsa883x", + wsa883x->swr_slave->addr); wsa883x->entry = snd_info_create_module_entry(codec_root->module, (const char *)name, @@ -1260,6 +1268,45 @@ static int wsa883x_gpio_ctrl(struct wsa883x_priv *wsa883x, bool enable) return ret; } +static int wsa883x_swr_up(struct wsa883x_priv *wsa883x) +{ + int ret; + + ret = wsa883x_gpio_ctrl(wsa883x, true); + if (ret) + dev_err(wsa883x->dev, "%s: Failed to enable gpio\n", __func__); + + return ret; +} + +static int wsa883x_swr_down(struct wsa883x_priv *wsa883x) +{ + int ret; + + ret = wsa883x_gpio_ctrl(wsa883x, false); + if (ret) + dev_err(wsa883x->dev, "%s: Failed to disable gpio\n", __func__); + + return ret; +} + +static int wsa883x_swr_reset(struct wsa883x_priv *wsa883x) +{ + u8 retry = WSA883X_NUM_RETRY; + u8 devnum = 0; + struct swr_device *pdev; + + pdev = wsa883x->swr_slave; + while (swr_get_logical_dev_num(pdev, pdev->addr, &devnum) && retry--) { + /* Retry after 1 msec delay */ + usleep_range(1000, 1100); + } + pdev->dev_num = devnum; + wsa883x_regcache_sync(wsa883x); + + return 0; +} + static int wsa883x_event_notify(struct notifier_block *nb, unsigned long val, void *ptr) { @@ -1277,7 +1324,16 @@ static int wsa883x_event_notify(struct notifier_block *nb, snd_soc_component_update_bits(wsa883x->component, WSA883X_PA_FSM_CTL, 0x01, 0x00); + wsa883x_swr_down(wsa883x); + break; + + case BOLERO_WSA_EVT_SSR_UP: + wsa883x_swr_up(wsa883x); + /* Add delay to allow enumerate */ + usleep_range(20000, 20010); + wsa883x_swr_reset(wsa883x); break; + case BOLERO_WSA_EVT_PA_ON_POST_FSCLK: if (test_bit(SPKR_STATUS, &wsa883x->status_mask)) snd_soc_component_update_bits(wsa883x->component, -- GitLab From 9e8e0f6d803c5cd744df8edce965bb1c8a1866ce Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 27 Mar 2020 15:10:12 +0530 Subject: [PATCH 1450/1645] config: Enable digital codec resource manager config Enable digital codec resource manager config for kona, lito and bengal targets. Change-Id: Ie41a9e61032d20d4deaa95b0669c509ff9b14968 Signed-off-by: Aditya Bavanari --- config/bengalauto.conf | 1 + config/bengalautoconf.h | 3 ++- config/konaauto.conf | 1 + config/konaautoconf.h | 3 ++- config/litoauto.conf | 1 + config/litoautoconf.h | 1 + 6 files changed, 8 insertions(+), 2 deletions(-) diff --git a/config/bengalauto.conf b/config/bengalauto.conf index 0478ecadfb65..cd614f66ed54 100644 --- a/config/bengalauto.conf +++ b/config/bengalauto.conf @@ -27,6 +27,7 @@ CONFIG_SND_SOC_BOLERO=m CONFIG_VA_MACRO=m CONFIG_RX_MACRO=m CONFIG_TX_MACRO=m +CONFIG_DIGITAL_CDC_RSC_MGR=m CONFIG_SND_SOC_WCD_IRQ=m CONFIG_SND_SOC_WCD937X=m CONFIG_SND_SOC_WCD937X_SLAVE=m diff --git a/config/bengalautoconf.h b/config/bengalautoconf.h index 3e72903c0af5..83cca0807411 100644 --- a/config/bengalautoconf.h +++ b/config/bengalautoconf.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #define CONFIG_PINCTRL_LPI 1 @@ -31,6 +31,7 @@ #define CONFIG_VA_MACRO 1 #define CONFIG_RX_MACRO 1 #define CONFIG_TX_MACRO 1 +#define CONFIG_DIGITAL_CDC_RSC_MGR 1 #define CONFIG_SND_SOC_WCD_IRQ 1 #define CONFIG_SND_SOC_WCD937X 1 #define CONFIG_SND_SOC_WCD937X_SLAVE 1 diff --git a/config/konaauto.conf b/config/konaauto.conf index 03e054150385..74ca2d48ea77 100644 --- a/config/konaauto.conf +++ b/config/konaauto.conf @@ -36,3 +36,4 @@ export CONFIG_SND_SOC_WCD938X_SLAVE=m export CONFIG_SND_SOC_KONA=m export CONFIG_SND_EVENT=m export CONFIG_VOICE_MHI=m +export CONFIG_DIGITAL_CDC_RSC_MGR=m diff --git a/config/konaautoconf.h b/config/konaautoconf.h index f93223641b15..e489b41abd84 100644 --- a/config/konaautoconf.h +++ b/config/konaautoconf.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #define CONFIG_PINCTRL_LPI 1 @@ -40,3 +40,4 @@ #define CONFIG_SND_SOC_KONA 1 #define CONFIG_SND_EVENT 1 #define CONFIG_VOICE_MHI 1 +#define CONFIG_DIGITAL_CDC_RSC_MGR 1 diff --git a/config/litoauto.conf b/config/litoauto.conf index 12bb1df71705..8dbeee095924 100644 --- a/config/litoauto.conf +++ b/config/litoauto.conf @@ -29,6 +29,7 @@ CONFIG_WSA_MACRO=m CONFIG_VA_MACRO=m CONFIG_RX_MACRO=m CONFIG_TX_MACRO=m +CONFIG_DIGITAL_CDC_RSC_MGR=m CONFIG_SND_SOC_WCD_IRQ=m CONFIG_SND_SOC_WCD938X=m CONFIG_SND_SOC_WCD938X_SLAVE=m diff --git a/config/litoautoconf.h b/config/litoautoconf.h index 0cfdab2d3529..adf43e2f0d35 100644 --- a/config/litoautoconf.h +++ b/config/litoautoconf.h @@ -33,6 +33,7 @@ #define CONFIG_VA_MACRO 1 #define CONFIG_RX_MACRO 1 #define CONFIG_TX_MACRO 1 +#define CONFIG_DIGITAL_CDC_RSC_MGR 1 #define CONFIG_SND_SOC_WCD_IRQ 1 #define CONFIG_SND_SOC_WCD938X 1 #define CONFIG_SND_SOC_WCD938X_SLAVE 1 -- GitLab From bb981b707efecb499346bf2cad3142efad6f1e8d Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 19 Mar 2020 18:30:10 +0530 Subject: [PATCH 1451/1645] audio-kernel: Synchronize hw vote and unvote requests HW vote and unvote is currently called from multiple clients leading to synchronization issues during SSR/PDR scenarios. Synchronize all the vote requests by using digital codec resource manager. Change-Id: I7e63f69ab5d761a3bb4c7ce70bbef2e8bfd76cfb Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/bolero-cdc.c | 11 ++-- asoc/codecs/bolero/va-macro.c | 7 ++- dsp/Kbuild | 4 ++ dsp/digital-cdc-rsc-mgr.c | 100 ++++++++++++++++++++++++++++++ dsp/q6_init.c | 4 +- dsp/q6_init.h | 16 ++++- include/dsp/digital-cdc-rsc-mgr.h | 32 ++++++++++ soc/pinctrl-lpi.c | 17 ++++- soc/swr-mstr-ctrl.c | 19 +++--- 9 files changed, 192 insertions(+), 18 deletions(-) create mode 100644 dsp/digital-cdc-rsc-mgr.c create mode 100644 include/dsp/digital-cdc-rsc-mgr.h diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 2db0c5b30a35..1b28382f6fc0 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "bolero-cdc.h" #include "internal.h" #include "bolero-clk-rsc.h" @@ -1379,7 +1380,7 @@ int bolero_runtime_resume(struct device *dev) } if (priv->core_hw_vote_count == 0) { - ret = clk_prepare_enable(priv->lpass_core_hw_vote); + ret = digital_cdc_rsc_mgr_hw_vote_enable(priv->lpass_core_hw_vote); if (ret < 0) { dev_err(dev, "%s:lpass core hw enable failed\n", __func__); @@ -1397,7 +1398,7 @@ int bolero_runtime_resume(struct device *dev) } if (priv->core_audio_vote_count == 0) { - ret = clk_prepare_enable(priv->lpass_audio_hw_vote); + ret = digital_cdc_rsc_mgr_hw_vote_enable(priv->lpass_audio_hw_vote); if (ret < 0) { dev_err(dev, "%s:lpass audio hw enable failed\n", __func__); @@ -1422,7 +1423,8 @@ int bolero_runtime_suspend(struct device *dev) mutex_lock(&priv->vote_lock); if (priv->lpass_core_hw_vote != NULL) { if (--priv->core_hw_vote_count == 0) - clk_disable_unprepare(priv->lpass_core_hw_vote); + digital_cdc_rsc_mgr_hw_vote_disable( + priv->lpass_core_hw_vote); if (priv->core_hw_vote_count < 0) priv->core_hw_vote_count = 0; } else { @@ -1434,7 +1436,8 @@ int bolero_runtime_suspend(struct device *dev) if (priv->lpass_audio_hw_vote != NULL) { if (--priv->core_audio_vote_count == 0) - clk_disable_unprepare(priv->lpass_audio_hw_vote); + digital_cdc_rsc_mgr_hw_vote_disable( + priv->lpass_audio_hw_vote); if (priv->core_audio_vote_count < 0) priv->core_audio_vote_count = 0; } else { diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 85d4ae399703..02534d6a4f1f 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "bolero-cdc.h" #include "bolero-cdc-registers.h" #include "bolero-clk-rsc.h" @@ -444,7 +445,8 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: if (va_priv->lpass_audio_hw_vote) { - ret = clk_prepare_enable(va_priv->lpass_audio_hw_vote); + ret = digital_cdc_rsc_mgr_hw_vote_enable( + va_priv->lpass_audio_hw_vote); if (ret) dev_err(va_dev, "%s: lpass audio hw enable failed\n", @@ -467,7 +469,8 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, if (bolero_tx_clk_switch(component, CLK_SRC_TX_RCG)) dev_dbg(va_dev, "%s: clock switch failed\n",__func__); if (va_priv->lpass_audio_hw_vote) - clk_disable_unprepare(va_priv->lpass_audio_hw_vote); + digital_cdc_rsc_mgr_hw_vote_disable( + va_priv->lpass_audio_hw_vote); break; default: dev_err(va_priv->dev, diff --git a/dsp/Kbuild b/dsp/Kbuild index 006de44589f2..43180e7a3dc3 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -184,6 +184,10 @@ ifdef CONFIG_VOICE_MHI Q6_OBJS += voice_mhi.o endif +ifdef CONFIG_DIGITAL_CDC_RSC_MGR + Q6_OBJS += digital-cdc-rsc-mgr.o +endif + LINUX_INC += -Iinclude/linux INCS += $(COMMON_INC) \ diff --git a/dsp/digital-cdc-rsc-mgr.c b/dsp/digital-cdc-rsc-mgr.c new file mode 100644 index 000000000000..4206523ea85b --- /dev/null +++ b/dsp/digital-cdc-rsc-mgr.c @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +struct mutex hw_vote_lock; +static bool is_init_done; + +/** + * digital_cdc_rsc_mgr_hw_vote_enable - Enables hw vote in DSP + * + * @vote_handle: vote handle for which voting needs to be done + * + * Returns 0 on success or -EINVAL/error code on failure + */ +int digital_cdc_rsc_mgr_hw_vote_enable(struct clk* vote_handle) +{ + int ret = 0; + + if (!is_init_done || vote_handle == NULL) { + pr_err_ratelimited("%s: init failed or vote handle NULL\n", + __func__); + return -EINVAL; + } + + mutex_lock(&hw_vote_lock); + ret = clk_prepare_enable(vote_handle); + mutex_unlock(&hw_vote_lock); + + pr_debug("%s: return %d\n", __func__, ret); + trace_printk("%s: return %d\n", __func__, ret); + return ret; +} +EXPORT_SYMBOL(digital_cdc_rsc_mgr_hw_vote_enable); + +/** + * digital_cdc_rsc_mgr_hw_vote_disable - Disables hw vote in DSP + * + * @vote_handle: vote handle for which voting needs to be disabled + * + */ +void digital_cdc_rsc_mgr_hw_vote_disable(struct clk* vote_handle) +{ + if (!is_init_done || vote_handle == NULL) { + pr_err_ratelimited("%s: init failed or vote handle NULL\n", + __func__); + return; + } + + mutex_lock(&hw_vote_lock); + clk_disable_unprepare(vote_handle); + mutex_unlock(&hw_vote_lock); + trace_printk("%s\n", __func__); +} +EXPORT_SYMBOL(digital_cdc_rsc_mgr_hw_vote_disable); + +/** + * digital_cdc_rsc_mgr_hw_vote_reset - Resets hw vote count + * + */ +void digital_cdc_rsc_mgr_hw_vote_reset(struct clk* vote_handle) +{ + int count = 0; + + if (!is_init_done || vote_handle == NULL) { + pr_err_ratelimited("%s: init failed or vote handle NULL\n", + __func__); + return; + } + + mutex_lock(&hw_vote_lock); + while (__clk_is_enabled(vote_handle)) { + clk_disable_unprepare(vote_handle); + count++; + } + pr_debug("%s: Vote count after SSR: %d\n", __func__, count); + trace_printk("%s: Vote count after SSR: %d\n", __func__, count); + + while (count--) + clk_prepare_enable(vote_handle); + mutex_unlock(&hw_vote_lock); +} +EXPORT_SYMBOL(digital_cdc_rsc_mgr_hw_vote_reset); + +void digital_cdc_rsc_mgr_init() +{ + mutex_init(&hw_vote_lock); + is_init_done = true; +} + +void digital_cdc_rsc_mgr_exit() +{ + mutex_destroy(&hw_vote_lock); + is_init_done = false; +} diff --git a/dsp/q6_init.c b/dsp/q6_init.c index fb18741d3838..e990f2a15109 100644 --- a/dsp/q6_init.c +++ b/dsp/q6_init.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017, 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017, 2019-2020 The Linux Foundation. All rights reserved. */ #include @@ -24,11 +24,13 @@ static int __init audio_q6_init(void) avtimer_init(); msm_mdf_init(); voice_mhi_init(); + digital_cdc_rsc_mgr_init(); return 0; } static void __exit audio_q6_exit(void) { + digital_cdc_rsc_mgr_exit(); msm_mdf_exit(); avtimer_exit(); audio_slimslave_exit(); diff --git a/dsp/q6_init.h b/dsp/q6_init.h index 4df2e032700f..77ba743484b4 100644 --- a/dsp/q6_init.h +++ b/dsp/q6_init.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #ifndef __Q6_INIT_H__ @@ -80,5 +80,19 @@ static inline void voice_mhi_exit(void) return; } #endif + +#ifdef CONFIG_DIGITAL_CDC_RSC_MGR +void digital_cdc_rsc_mgr_init(void); +void digital_cdc_rsc_mgr_exit(void); +#else +static inline void digital_cdc_rsc_mgr_init(void) +{ +} + +static inline void digital_cdc_rsc_mgr_exit(void) +{ +} +#endif /* CONFIG_DIGITAL_CDC_RSC_MGR */ + #endif diff --git a/include/dsp/digital-cdc-rsc-mgr.h b/include/dsp/digital-cdc-rsc-mgr.h new file mode 100644 index 000000000000..685cd5c1fc5f --- /dev/null +++ b/include/dsp/digital-cdc-rsc-mgr.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef DIGITAL_CDC_RSC_MGR_H +#define DIGITAL_CDC_RSC_MGR_H + +#ifdef CONFIG_DIGITAL_CDC_RSC_MGR + +int digital_cdc_rsc_mgr_hw_vote_enable(struct clk* vote_handle); +void digital_cdc_rsc_mgr_hw_vote_disable(struct clk* vote_handle); +void digital_cdc_rsc_mgr_hw_vote_reset(struct clk* vote_handle); + +#else + +static inline int digital_cdc_rsc_mgr_hw_vote_enable(struct clk* vote_handle) +{ + return 0; +} + +static inline void digital_cdc_rsc_mgr_hw_vote_disable(struct clk* vote_handle) +{ +} + +static inline void digital_cdc_rsc_mgr_hw_vote_reset(struct clk* vote_handle) +{ +} + +#endif /* CONFIG_DIGITAL_CDC_RSC_MGR */ + +#endif /* DIGITAL_CDC_RSC_MGR_H */ diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index c3d2326af593..0b0eef5ab9cc 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -469,6 +470,7 @@ static int lpi_notifier_service_cb(struct notifier_block *this, unsigned long opcode, void *ptr) { static bool initial_boot = true; + struct lpi_gpio_state *state = dev_get_drvdata(lpi_dev); pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); @@ -484,6 +486,17 @@ static int lpi_notifier_service_cb(struct notifier_block *this, case AUDIO_NOTIFIER_SERVICE_UP: if (initial_boot) initial_boot = false; + + /* Reset HW votes after SSR */ + if (!lpi_dev_up) { + if (state->lpass_core_hw_vote) + digital_cdc_rsc_mgr_hw_vote_reset( + state->lpass_core_hw_vote); + if (state->lpass_audio_hw_vote) + digital_cdc_rsc_mgr_hw_vote_reset( + state->lpass_audio_hw_vote); + } + lpi_dev_up = true; snd_event_notify(lpi_dev, SND_EVENT_UP); break; @@ -870,7 +883,7 @@ int lpi_pinctrl_runtime_resume(struct device *dev) } mutex_lock(&state->core_hw_vote_lock); - ret = clk_prepare_enable(hw_vote); + ret = digital_cdc_rsc_mgr_hw_vote_enable(hw_vote); if (ret < 0) { pm_runtime_set_autosuspend_delay(dev, LPI_AUTO_SUSPEND_DELAY_ERROR); @@ -906,7 +919,7 @@ int lpi_pinctrl_runtime_suspend(struct device *dev) mutex_lock(&state->core_hw_vote_lock); if (state->core_hw_vote_status) { - clk_disable_unprepare(hw_vote); + digital_cdc_rsc_mgr_hw_vote_disable(hw_vote); state->core_hw_vote_status = false; } mutex_unlock(&state->core_hw_vote_lock); diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 4aa5c0c6aa5f..77ece45ea049 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "swrm_registers.h" #include "swr-mstr-ctrl.h" @@ -378,8 +379,8 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm, } if (++swrm->hw_core_clk_en == 1) { ret = - clk_prepare_enable( - swrm->lpass_core_hw_vote); + digital_cdc_rsc_mgr_hw_vote_enable( + swrm->lpass_core_hw_vote); if (ret < 0) { dev_err(swrm->dev, "%s:lpass core hw enable failed\n", @@ -392,8 +393,8 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm, if (swrm->hw_core_clk_en < 0) swrm->hw_core_clk_en = 0; else if (swrm->hw_core_clk_en == 0) - clk_disable_unprepare( - swrm->lpass_core_hw_vote); + digital_cdc_rsc_mgr_hw_vote_disable( + swrm->lpass_core_hw_vote); } } } @@ -410,8 +411,8 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm, } if (++swrm->aud_core_clk_en == 1) { ret = - clk_prepare_enable( - swrm->lpass_core_audio); + digital_cdc_rsc_mgr_hw_vote_enable( + swrm->lpass_core_audio); if (ret < 0) { dev_err(swrm->dev, "%s:lpass audio hw enable failed\n", @@ -424,8 +425,8 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm, if (swrm->aud_core_clk_en < 0) swrm->aud_core_clk_en = 0; else if (swrm->aud_core_clk_en == 0) - clk_disable_unprepare( - swrm->lpass_core_audio); + digital_cdc_rsc_mgr_hw_vote_disable( + swrm->lpass_core_audio); } } } @@ -3334,6 +3335,8 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) swrm_device_down(&pdev->dev); mutex_lock(&swrm->devlock); swrm->dev_up = false; + swrm->hw_core_clk_en = 0; + swrm->aud_core_clk_en = 0; mutex_unlock(&swrm->devlock); mutex_lock(&swrm->reslock); swrm->state = SWR_MSTR_SSR; -- GitLab From 22cd4cbcc757d8bb7592cf9cb36d6b923b9a9631 Mon Sep 17 00:00:00 2001 From: Sanjana B Date: Sun, 5 Apr 2020 18:24:24 +0530 Subject: [PATCH 1452/1645] asoc: csra: update mute register of csra66x0 codec Update mute register of csra66x0 codec when called from hw_free api. Change-Id: I728d1ca3076899ad0e6dea4dcac28416b3e40b18 Signed-off-by: Sanjana B --- asoc/codecs/csra66x0/csra66x0.c | 21 ++++++++++++++++++++- asoc/codecs/csra66x0/csra66x0.h | 4 +++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/csra66x0/csra66x0.c b/asoc/codecs/csra66x0/csra66x0.c index e0e702f565b3..9cdbbdaaaba4 100644 --- a/asoc/codecs/csra66x0/csra66x0.c +++ b/asoc/codecs/csra66x0/csra66x0.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include #include @@ -602,6 +602,25 @@ static const struct snd_soc_dapm_route csra66x0_dapm_routes[] = { {"PGA", NULL, "DAC"}, {"SPKR", NULL, "PGA"}, }; +/* + * csra66x0_hw_free_mute - Update csra66x0 mute register + * + * @component - csra66x0 component + * + */ +void csra66x0_hw_free_mute(struct snd_soc_component *component) +{ + int val = 0; + + if (component == NULL) + return; + + val = snd_soc_component_read32(component, + CSRA66X0_MISC_CONTROL_STATUS_1_FA); + snd_soc_component_write(component, CSRA66X0_MISC_CONTROL_STATUS_1_FA, + val | 0x04); +} +EXPORT_SYMBOL(csra66x0_hw_free_mute); static int csra66x0_wait_for_config_state(struct snd_soc_component *component) { diff --git a/asoc/codecs/csra66x0/csra66x0.h b/asoc/codecs/csra66x0/csra66x0.h index 04d9ef836dfd..2bde3cc06bda 100644 --- a/asoc/codecs/csra66x0/csra66x0.h +++ b/asoc/codecs/csra66x0/csra66x0.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #ifndef _CSRA66X0_H @@ -226,4 +226,6 @@ #define FAULT_STATUS_TEMP 0x10 #define FAULT_STATUS_PROTECT 0x20 + +void csra66x0_hw_free_mute(struct snd_soc_component *component); #endif /* _CSRA66X0_H */ -- GitLab From dc52af1584da6fa6e00405769a3ddd85c1f41d68 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 16 Mar 2020 23:54:29 +0530 Subject: [PATCH 1453/1645] soc: swr-mstr: Add delay between fifo writes to avoid overflow/underflow Overflow/Underflow errors are observed sometimes while doing fifo write. Add delay between writes to resolve error. Change-Id: Id460e17753001a0dd52acd01a181d91132c36048 Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 4aa5c0c6aa5f..17fca51c6e13 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -615,10 +615,10 @@ static int swr_master_bulk_write(struct swr_mstr_ctrl *swrm, u32 *reg_addr, for (i = 0; i < length; i++) { /* wait for FIFO WR command to complete to avoid overflow */ /* - * Reduce sleep from 100us to 10us to meet KPIs + * Reduce sleep from 100us to 50us to meet KPIs * This still meets the hardware spec */ - usleep_range(10, 12); + usleep_range(50, 55); swr_master_write(swrm, reg_addr[i], val[i]); } mutex_unlock(&swrm->iolock); -- GitLab From 5bf91ea5f65dd98fd015b5f406ea2ab97230de27 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Sat, 28 Mar 2020 08:40:16 +0530 Subject: [PATCH 1454/1645] ASoC: wcd938x: Enable digital clk for tx0 if micbias enabled Mute is observed in amic record sometimes in concurrency with sva. This is because if record is over tx0 then digital clk is not enabled. Enable clk after enabling micbias to resolve mute. Change-Id: Iba3aa4fade0ac5889218eaee2c5d2c4bd4431d50 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/wcd937x.c | 2 +- asoc/codecs/wcd938x/wcd938x.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 5c3f14f84b9f..0d878cbd9c2b 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1447,7 +1447,7 @@ int wcd937x_micbias_control(struct snd_soc_component *component, mutex_unlock(&wcd937x->ana_tx_clk_lock); if (wcd937x->micb_ref[micb_index] == 1) { snd_soc_component_update_bits(component, - WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0xE0, 0xE0); + WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0xF0, 0xF0); snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); snd_soc_component_update_bits(component, diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 8ade1d932868..07adedfb2e23 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1878,7 +1878,7 @@ int wcd938x_micbias_control(struct snd_soc_component *component, wcd938x->micb_ref[micb_index]++; if (wcd938x->micb_ref[micb_index] == 1) { snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0xE0, 0xE0); + WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0xF0, 0xF0); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); snd_soc_component_update_bits(component, -- GitLab From 0c4087b94a5c9b8e5e4b7a59c25386a35e8a9ff9 Mon Sep 17 00:00:00 2001 From: Sanjana Date: Mon, 16 Mar 2020 10:21:54 +0530 Subject: [PATCH 1455/1645] asoc: qcs405: fix pop at end of DSD playback Fix pop at end of DSD playback by muting csra devices during hw_free. Change-Id: Ie084ade6aeb310ee28e4478b4673075ca69153c9 Signed-off-by: Sanjana --- asoc/qcs405.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index b76728cd21c0..241305c59ff7 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -6552,6 +6552,36 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) return ret; } +static int msm_mi2s_snd_hw_free(struct snd_pcm_substream *substream) +{ + int i, data_format = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int index = rtd->cpu_dai->id; + struct snd_soc_card *card = rtd->card; + struct snd_soc_component *component; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + data_format = mi2s_rx_cfg[index].data_format; + else + data_format = mi2s_tx_cfg[index].data_format; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + /* Call csra mute function if data format is DSD, else return */ + if (data_format != AFE_DSD_DATA) + return 0; + + for (i = 0; i < card->num_aux_devs; i++) { + component = + soc_find_component(card->aux_dev[i].codec_of_node, + NULL); + csra66x0_hw_free_mute(component); + } + + return 0; +} + static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) { int ret; @@ -6902,6 +6932,7 @@ static void msm_spdif_snd_shutdown(struct snd_pcm_substream *substream) static struct snd_soc_ops msm_mi2s_be_ops = { .startup = msm_mi2s_snd_startup, + .hw_free = msm_mi2s_snd_hw_free, .shutdown = msm_mi2s_snd_shutdown, }; -- GitLab From fe23747f9e2664f0b7be268b8364adfbeed177bf Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 7 Apr 2020 11:42:19 +0530 Subject: [PATCH 1456/1645] dsp: lsm: Change wake up latency for LAB module In order to reduce the LPI memory consumption, reduce the apps wake up latency from 250msec to 40msec in LAB module config. Change-Id: I5451e2b43b81ce7c6f8840f774b74e3cffc0a032 Signed-off-by: Aditya Bavanari --- dsp/q6lsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index 66883ba77afb..a77ffd3c29d3 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -2393,7 +2393,7 @@ int q6lsm_lab_control(struct lsm_client *client, u32 enable, lab_config_hdr.param_id = LSM_PARAM_ID_LAB_CONFIG; lab_config_hdr.param_size = sizeof(lab_config); lab_config.minor_version = 1; - lab_config.wake_up_latency_ms = 250; + lab_config.wake_up_latency_ms = 40; rc = q6lsm_pack_and_set_params(client, &lab_config_hdr, (uint8_t *) &lab_config, LSM_SESSION_CMD_SET_PARAMS); -- GitLab From c345c635840c10c495c4bfa5a270a41b7493918e Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Sun, 5 Apr 2020 21:41:23 +0530 Subject: [PATCH 1457/1645] soc:bengal: add proxy ports for call screening in machine driver add machine driver changes for proxy port changes. Change-Id: I95e269953fa482002d028c60165ba5ad95521f6f Signed-off-by: Samyak Jain --- asoc/bengal.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/asoc/bengal.c b/asoc/bengal.c index 1ab7f9951b43..ec73cc9d6d40 100644 --- a/asoc/bengal.c +++ b/asoc/bengal.c @@ -5030,6 +5030,33 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .ignore_suspend = 1, .ignore_pmdown_time = 1, }, + /* Proxy Tx BACK END DAI Link */ + { + .name = LPASS_BE_PROXY_TX, + .stream_name = "Proxy Capture", + .cpu_dai_name = "msm-dai-q6-dev.8195", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PROXY_TX, + .ignore_suspend = 1, + }, + /* Proxy Rx BACK END DAI Link */ + { + .name = LPASS_BE_PROXY_RX, + .stream_name = "Proxy Playback", + .cpu_dai_name = "msm-dai-q6-dev.8194", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PROXY_RX, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, { .name = LPASS_BE_USB_AUDIO_RX, .stream_name = "USB Audio Playback", -- GitLab From 687f98214dd8276c6d2a7b79e739a3ea5428762b Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 1 Apr 2020 18:21:41 +0530 Subject: [PATCH 1458/1645] soc: swr-mstr: Add node to disable clk switch for rx master RX Master does not support div2 clk switching as div2_en bit for rx master is floating. Do not do clk switch for rx master. Change-Id: Iee1716fe892e792ffd17d0861a807e3711cee5d5 Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 13 ++++++++++--- soc/swr-mstr-ctrl.h | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index b0ad17f7ab2f..5eab8d5f1635 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1341,9 +1341,9 @@ static void swrm_apply_port_config(struct swr_master *master) dev_dbg(swrm->dev, "%s: enter bank: %d master_ports: %d\n", __func__, bank, master->num_port); - - swrm_cmd_fifo_wr_cmd(swrm, 0x01, 0xF, 0x00, - SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(bank)); + if (!swrm->disable_div2_clk_switch) + swrm_cmd_fifo_wr_cmd(swrm, 0x01, 0xF, 0x00, + SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(bank)); swrm_copy_data_port_config(master, bank); } @@ -2648,6 +2648,7 @@ static int swrm_probe(struct platform_device *pdev) swrm->state = SWR_MSTR_UP; swrm->ipc_wakeup = false; swrm->ipc_wakeup_triggered = false; + swrm->disable_div2_clk_switch = FALSE; init_completion(&swrm->reset); init_completion(&swrm->broadcast); init_completion(&swrm->clk_off_complete); @@ -2669,6 +2670,12 @@ static int swrm_probe(struct platform_device *pdev) for (i = 0 ; i < SWR_MSTR_PORT_LEN; i++) INIT_LIST_HEAD(&swrm->mport_cfg[i].port_req_list); + if (of_property_read_u32(pdev->dev.of_node, + "qcom,disable-div2-clk-switch", + &swrm->disable_div2_clk_switch)) { + swrm->disable_div2_clk_switch = FALSE; + } + /* Register LPASS core hw vote */ lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote"); if (IS_ERR(lpass_core_hw_vote)) { diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index ce0b64d57766..ec5bbd2ff533 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -180,6 +180,7 @@ struct swr_mstr_ctrl { int hw_core_clk_en; int aud_core_clk_en; int clk_src; + u32 disable_div2_clk_switch; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_swrm_dent; struct dentry *debugfs_peek; -- GitLab From 46bec304fafe5739669b76267af7b72e95722529 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 1 Apr 2020 21:25:25 +0530 Subject: [PATCH 1459/1645] ASoC: wcd938x: Do not enable hold_off while enabling watchdog Hold_off bit for enabling watchdog will enable mute until there is a block reset and watchdog bits aren't toggled. Disable hold_off bit so that wcd is recovered from mute instantly once watchdog occurred. Change-Id: Ia87593ead05dde4e31a0afefd6ffaca89bb95448 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd938x/wcd938x.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index c90bba491d81..98e7083b11d9 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -777,7 +777,7 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, usleep_range(100, 110); set_bit(HPH_PA_DELAY, &wcd938x->status_mask); snd_soc_component_update_bits(component, - WCD938X_DIGITAL_PDM_WD_CTL1, 0x17, 0x13); + WCD938X_DIGITAL_PDM_WD_CTL1, 0x07, 0x03); break; case SND_SOC_DAPM_POST_PMU: /* @@ -857,7 +857,7 @@ static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD938X_ANA_HPH, 0x10, 0x00); snd_soc_component_update_bits(component, - WCD938X_DIGITAL_PDM_WD_CTL1, 0x17, 0x00); + WCD938X_DIGITAL_PDM_WD_CTL1, 0x07, 0x00); wcd_cls_h_fsm(component, &wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_HPHR, @@ -913,7 +913,7 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, usleep_range(100, 110); set_bit(HPH_PA_DELAY, &wcd938x->status_mask); snd_soc_component_update_bits(component, - WCD938X_DIGITAL_PDM_WD_CTL0, 0x17, 0x13); + WCD938X_DIGITAL_PDM_WD_CTL0, 0x07, 0x03); break; case SND_SOC_DAPM_POST_PMU: /* @@ -993,7 +993,7 @@ static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD938X_ANA_HPH, 0x20, 0x00); snd_soc_component_update_bits(component, - WCD938X_DIGITAL_PDM_WD_CTL0, 0x17, 0x00); + WCD938X_DIGITAL_PDM_WD_CTL0, 0x07, 0x00); wcd_cls_h_fsm(component, &wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_HPHL, @@ -1026,7 +1026,7 @@ static int wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, wcd938x->rx_swr_dev->dev_num, true); snd_soc_component_update_bits(component, - WCD938X_DIGITAL_PDM_WD_CTL2, 0x05, 0x05); + WCD938X_DIGITAL_PDM_WD_CTL2, 0x01, 0x01); break; case SND_SOC_DAPM_POST_PMU: /* 1 msec delay as per HW requirement */ @@ -1054,7 +1054,7 @@ static int wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w, /* 1 msec delay as per HW requirement */ usleep_range(1000, 1010); snd_soc_component_update_bits(component, - WCD938X_DIGITAL_PDM_WD_CTL2, 0x05, 0x00); + WCD938X_DIGITAL_PDM_WD_CTL2, 0x01, 0x00); wcd_cls_h_fsm(component, &wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_AUX, @@ -1098,11 +1098,11 @@ static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) snd_soc_component_update_bits(component, WCD938X_DIGITAL_PDM_WD_CTL2, - 0x05, 0x05); + 0x01, 0x01); else snd_soc_component_update_bits(component, WCD938X_DIGITAL_PDM_WD_CTL0, - 0x17, 0x13); + 0x07, 0x03); if (!wcd938x->comp1_enable) snd_soc_component_update_bits(component, WCD938X_ANA_EAR_COMPANDER_CTL, 0x80, 0x80); @@ -1157,11 +1157,11 @@ static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) snd_soc_component_update_bits(component, WCD938X_DIGITAL_PDM_WD_CTL2, - 0x05, 0x00); + 0x01, 0x00); else snd_soc_component_update_bits(component, WCD938X_DIGITAL_PDM_WD_CTL0, - 0x17, 0x00); + 0x07, 0x00); wcd_cls_h_fsm(component, &wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA, WCD_CLSH_STATE_EAR, -- GitLab From d304a4b769044317134ad2e86fe46dc92db52860 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 9 Apr 2020 13:11:29 +0530 Subject: [PATCH 1460/1645] bolero: tx-macro: Fix audio distortion during amic record Distortion is heard during CTS audio record. Do not add delay while toggle hpf frequency and zero gate to resolve distortion. Change-Id: I234cfcce43a6fb5d9c372f2655abdb2f8b5c4853 Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/tx-macro.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 472cdfeee46b..121f56df255d 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -496,8 +496,6 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) hpf_cut_off_freq << 5); snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x02); - /* Minimum 1 clk cycle delay is required as per HW spec */ - usleep_range(1000, 1010); snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x01); } else { @@ -993,10 +991,6 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, if (!is_amic_enabled(component, decimator)) snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x00); - /* - * Minimum 1 clk cycle delay is required as per HW spec - */ - usleep_range(1000, 1010); snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x01); /* -- GitLab From 2854a2ed7cca9d8eb45981ea79e876ab07a9eccb Mon Sep 17 00:00:00 2001 From: Ramlal Karra Date: Mon, 13 Apr 2020 13:32:05 +0530 Subject: [PATCH 1461/1645] uapi: add ADM_AUDPROC_PERSISTENT cal type ADM supports certain modules that can have very large calibration sizes, in such cases the calibration is expected to be persistent in memory. Add new cal type ADM_AUDPROC_PERSISTENT for this purpose. Change-Id: If85c0b6675ea7481c7d71d5c0d770bc129332026 --- include/uapi/linux/msm_audio_calibration.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h index 35b596062247..e8ba1b3c206a 100644 --- a/include/uapi/linux/msm_audio_calibration.h +++ b/include/uapi/linux/msm_audio_calibration.h @@ -104,6 +104,7 @@ enum { ADM_LSM_TOPOLOGY_CAL_TYPE, ADM_LSM_AUDPROC_CAL_TYPE, ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE, + ADM_AUDPROC_PERSISTENT_CAL_TYPE, MAX_CAL_TYPES, }; @@ -117,6 +118,7 @@ enum { #define ADM_LSM_TOPOLOGY_CAL_TYPE ADM_LSM_TOPOLOGY_CAL_TYPE #define ADM_LSM_AUDPROC_CAL_TYPE ADM_LSM_AUDPROC_CAL_TYPE #define ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE +#define ADM_AUDPROC_PERSISTENT_CAL_TYPE ADM_AUDPROC_PERSISTENT_CAL_TYPE #define LSM_CAL_TYPES #define TOPOLOGY_SPECIFIC_CHANNEL_INFO -- GitLab From 471fe91296e31190f55cde4f87fefd4a1abe24a7 Mon Sep 17 00:00:00 2001 From: Ramlal Karra Date: Mon, 13 Apr 2020 13:47:07 +0530 Subject: [PATCH 1462/1645] dsp: q6adm: add ADM_AUDPROC_PERSISTENT cal type ADM supports certain modules that can have very large calibration sizes, in such cases the calibration is expected to be persistent in memory. Add new calibration type for this purpose. Change-Id: I2d1fb219a3748d0ead5ca2199da2b55669f2550e Signed-off-by: Ramlal Karra --- dsp/audio_cal_utils.c | 4 +++- dsp/q6adm.c | 31 +++++++++++++++++++++++++++---- include/dsp/q6adm-v2.h | 1 + 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index 7e243e88609b..fab5186ab889 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. */ #include #include @@ -57,6 +57,7 @@ size_t get_cal_info_size(int32_t cal_type) case ADM_AUDPROC_CAL_TYPE: case ADM_LSM_AUDPROC_CAL_TYPE: case ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE: + case ADM_AUDPROC_PERSISTENT_CAL_TYPE: size = sizeof(struct audio_cal_info_audproc); break; case ADM_AUDVOL_CAL_TYPE: @@ -211,6 +212,7 @@ size_t get_user_cal_type_size(int32_t cal_type) case ADM_AUDPROC_CAL_TYPE: case ADM_LSM_AUDPROC_CAL_TYPE: case ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE: + case ADM_AUDPROC_PERSISTENT_CAL_TYPE: size = sizeof(struct audio_cal_type_audproc); break; case ADM_AUDVOL_CAL_TYPE: diff --git a/dsp/q6adm.c b/dsp/q6adm.c index a2f644f6eb54..8791e288836a 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2149,7 +2149,8 @@ static struct cal_block_data *adm_find_cal_by_path(int cal_index, int path) if (cal_index == ADM_AUDPROC_CAL || cal_index == ADM_LSM_AUDPROC_CAL || - cal_index == ADM_LSM_AUDPROC_PERSISTENT_CAL) { + cal_index == ADM_LSM_AUDPROC_PERSISTENT_CAL || + cal_index == ADM_AUDPROC_PERSISTENT_CAL) { audproc_cal_info = cal_block->cal_info; if ((audproc_cal_info->path == path) && (cal_block->cal_data.size > 0)) @@ -2187,7 +2188,8 @@ static struct cal_block_data *adm_find_cal_by_app_type(int cal_index, int path, if (cal_index == ADM_AUDPROC_CAL || cal_index == ADM_LSM_AUDPROC_CAL || - cal_index == ADM_LSM_AUDPROC_PERSISTENT_CAL) { + cal_index == ADM_LSM_AUDPROC_PERSISTENT_CAL || + cal_index == ADM_AUDPROC_PERSISTENT_CAL) { audproc_cal_info = cal_block->cal_info; if ((audproc_cal_info->path == path) && (audproc_cal_info->app_type == app_type) && @@ -2228,7 +2230,8 @@ static struct cal_block_data *adm_find_cal(int cal_index, int path, if (cal_index == ADM_AUDPROC_CAL || cal_index == ADM_LSM_AUDPROC_CAL || - cal_index == ADM_LSM_AUDPROC_PERSISTENT_CAL) { + cal_index == ADM_LSM_AUDPROC_PERSISTENT_CAL|| + cal_index == ADM_AUDPROC_PERSISTENT_CAL) { audproc_cal_info = cal_block->cal_info; if ((audproc_cal_info->path == path) && (audproc_cal_info->app_type == app_type) && @@ -2319,6 +2322,9 @@ static void send_adm_cal(int port_id, int copp_idx, int path, int perf_mode, if (passthr_mode != LISTEN) { send_adm_cal_type(ADM_AUDPROC_CAL, path, port_id, copp_idx, perf_mode, app_type, acdb_id, sample_rate); + send_adm_cal_type(ADM_AUDPROC_PERSISTENT_CAL, path, + port_id, copp_idx, perf_mode, app_type, + acdb_id, sample_rate); } else { send_adm_cal_type(ADM_LSM_AUDPROC_CAL, path, port_id, copp_idx, perf_mode, app_type, acdb_id, sample_rate); @@ -4136,6 +4142,9 @@ static int get_cal_type_index(int32_t cal_type) case ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE: ret = ADM_LSM_AUDPROC_PERSISTENT_CAL; break; + case ADM_AUDPROC_PERSISTENT_CAL_TYPE: + ret = ADM_AUDPROC_PERSISTENT_CAL; + break; default: pr_err("%s: invalid cal type %d!\n", __func__, cal_type); } @@ -4363,6 +4372,12 @@ static int adm_init_cal_data(void) adm_set_cal, NULL, NULL} }, {adm_map_cal_data, adm_unmap_cal_data, cal_utils_match_buf_num} }, + + {{ADM_AUDPROC_PERSISTENT_CAL_TYPE, + {adm_alloc_cal, adm_dealloc_cal, NULL, + adm_set_cal, NULL, NULL} }, + {adm_map_cal_data, adm_unmap_cal_data, + cal_utils_match_buf_num} }, }; pr_debug("%s:\n", __func__); @@ -4924,7 +4939,15 @@ int adm_store_cal_data(int port_id, int copp_idx, int path, int perf_mode, rc = -ENOMEM; goto unlock; } - } else if (cal_index == ADM_AUDVOL_CAL) { + } else if (cal_index == ADM_AUDPROC_PERSISTENT_CAL) { + if (cal_block->cal_data.size > AUD_PROC_PERSIST_BLOCK_SIZE) { + pr_err("%s:persist invalid size exp/actual[%zd, %d]\n", + __func__, cal_block->cal_data.size, *size); + rc = -ENOMEM; + goto unlock; + } + } + else if (cal_index == ADM_AUDVOL_CAL) { if (cal_block->cal_data.size > AUD_VOL_BLOCK_SIZE) { pr_err("%s:aud_vol:invalid size exp/actual[%zd, %d]\n", __func__, cal_block->cal_data.size, *size); diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 53514c391244..644855d0bb83 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -35,6 +35,7 @@ enum { ADM_SRS_TRUMEDIA, ADM_RTAC_AUDVOL_CAL, ADM_LSM_AUDPROC_PERSISTENT_CAL, + ADM_AUDPROC_PERSISTENT_CAL, ADM_MAX_CAL_TYPES }; -- GitLab From cf3f8e684f0b324abc1f789aac88c4010b07e952 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Fri, 24 Jan 2020 14:35:07 +0530 Subject: [PATCH 1463/1645] dsp: Add support to set clock drift - Add support to adjust drift in audio interface clock source PLL. - ADSP adjusts the source clock based on clk id. Add support in AFE driver to get clk id based on the AFE port. Change-Id: I45ceb6579bb15e32541051e0ba936a2d903e4923 Signed-off-by: Surendar Karka --- dsp/q6afe.c | 191 +++++++++++++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 29 ++++++ include/dsp/q6afe-v2.h | 3 + 3 files changed, 223 insertions(+) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 3b26c0cb58da..2586bd56b30e 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -174,6 +174,43 @@ struct afe_ctl { uint32_t v_vali_flag; }; +struct afe_clkinfo_per_port { + u16 port_id; /* AFE port ID */ + uint32_t clk_id; /* Clock ID */ +}; + +struct afe_clkinfo_per_port clkinfo_per_port[] = { + { AFE_PORT_ID_PRIMARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT}, + { AFE_PORT_ID_SECONDARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT}, + { AFE_PORT_ID_TERTIARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT}, + { AFE_PORT_ID_QUATERNARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT}, + { AFE_PORT_ID_QUINARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT}, + { AFE_PORT_ID_SENARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT}, + { AFE_PORT_ID_PRIMARY_PCM_RX, Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT}, + { AFE_PORT_ID_SECONDARY_PCM_RX, Q6AFE_LPASS_CLK_ID_SEC_PCM_IBIT}, + { AFE_PORT_ID_TERTIARY_PCM_RX, Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT}, + { AFE_PORT_ID_QUATERNARY_PCM_RX, Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT}, + { AFE_PORT_ID_QUINARY_PCM_RX, Q6AFE_LPASS_CLK_ID_QUIN_PCM_IBIT}, + { AFE_PORT_ID_SENARY_PCM_RX, Q6AFE_LPASS_CLK_ID_SEN_PCM_IBIT}, + { AFE_PORT_ID_PRIMARY_TDM_RX, Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT}, + { AFE_PORT_ID_SECONDARY_TDM_RX, Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT}, + { AFE_PORT_ID_TERTIARY_TDM_RX, Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT}, + { AFE_PORT_ID_QUATERNARY_TDM_RX, Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT}, + { AFE_PORT_ID_QUINARY_TDM_RX, Q6AFE_LPASS_CLK_ID_QUIN_TDM_IBIT}, + { AFE_PORT_ID_PRIMARY_SPDIF_RX, + AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_OUTPUT_CORE}, + { AFE_PORT_ID_PRIMARY_SPDIF_TX, + AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_INPUT_CORE}, + { AFE_PORT_ID_SECONDARY_SPDIF_RX, + AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_OUTPUT_CORE}, + { AFE_PORT_ID_SECONDARY_SPDIF_TX, + AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_INPUT_CORE}, + { AFE_PORT_ID_PRIMARY_META_MI2S_RX, + Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT}, + { AFE_PORT_ID_SECONDARY_META_MI2S_RX, + Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT}, +}; + static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX]; static unsigned long afe_configured_cmd; @@ -7843,6 +7880,156 @@ int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg) } EXPORT_SYMBOL(afe_set_lpass_clock); +static int afe_get_port_idx(u16 port_id) +{ + u16 afe_port = 0; + int i = -EINVAL; + + pr_debug("%s: port id 0x%x\n", __func__, port_id); + + if ((port_id >= AFE_PORT_ID_TDM_PORT_RANGE_START) && + (port_id <= AFE_PORT_ID_TDM_PORT_RANGE_END)) + afe_port = port_id & 0xFFF0; + else if ((port_id == AFE_PORT_ID_PRIMARY_SPDIF_RX) || + (port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) || + (port_id == AFE_PORT_ID_SECONDARY_SPDIF_RX) || + (port_id == AFE_PORT_ID_SECONDARY_SPDIF_TX)) + afe_port = port_id; + else + afe_port = port_id & 0xFFFE; + + for (i = 0; i < ARRAY_SIZE(clkinfo_per_port); i++) { + if (afe_port == clkinfo_per_port[i].port_id) { + pr_debug("%s: idx 0x%x port id 0x%x\n", __func__, + i, afe_port); + return i; + } + } + + pr_debug("%s: cannot get idx for port id 0x%x\n", __func__, + afe_port); + + return -EINVAL; +} + +static int afe_get_clk_id(u16 port_id) +{ + u16 afe_port = 0; + uint32_t clk_id = -EINVAL; + int idx = 0; + + idx = afe_get_port_idx(port_id); + if (idx < 0) { + pr_err("%s: cannot get clock id for port id 0x%x\n", __func__, + afe_port); + return -EINVAL; + } + + clk_id = clkinfo_per_port[idx].clk_id; + pr_debug("%s: clk id 0x%x port id 0x%x\n", __func__, clk_id, + afe_port); + + return clk_id; +} + +/** + * afe_set_clk_id - Update clock id for AFE port + * + * @port_id: AFE port id + * @clk_id: CLock ID + * + * Returns 0 on success, appropriate error code otherwise + */ +int afe_set_clk_id(u16 port_id, uint32_t clk_id) +{ + u16 afe_port = 0; + int idx = 0; + + idx = afe_get_port_idx(port_id); + if (idx < 0) { + pr_debug("%s: cannot set clock id for port id 0x%x\n", __func__, + afe_port); + return -EINVAL; + } + + clkinfo_per_port[idx].clk_id = clk_id; + pr_debug("%s: updated clk id 0x%x port id 0x%x\n", __func__, + clkinfo_per_port[idx].clk_id, afe_port); + + return 0; +} +EXPORT_SYMBOL(afe_set_clk_id); + +/** + * afe_set_pll_clk_drift - Set audio interface PLL clock drift + * + * @port_id: AFE port id + * @set_clk_drift: clk drift to adjust PLL + * @clk_reset: reset Interface clock to original value + * + * Returns 0 on success, appropriate error code otherwise + */ +int afe_set_pll_clk_drift(u16 port_id, int32_t set_clk_drift, + uint32_t clk_reset) +{ + struct afe_set_clk_drift clk_drift; + struct param_hdr_v3 param_hdr; + uint32_t clk_id; + int index = 0, ret = 0; + + memset(¶m_hdr, 0, sizeof(param_hdr)); + memset(&clk_drift, 0, sizeof(clk_drift)); + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: index[%d] invalid!\n", __func__, index); + return -EINVAL; + } + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err_ratelimited("%s: Q6 interface prepare failed %d\n", + __func__, ret); + return ret; + } + + clk_id = afe_get_clk_id(port_id); + if (clk_id < 0) { + pr_err("%s: cannot get clk id for port id 0x%x\n", + __func__, port_id); + return -EINVAL; + } + + if (clk_id & 0x01) { + pr_err("%s: cannot adjust clock drift for external clock id 0x%x\n", + __func__, clk_id); + return -EINVAL; + } + + clk_drift.clk_drift = set_clk_drift; + clk_drift.clk_reset = clk_reset; + clk_drift.clk_id = clk_id; + pr_debug("%s: clk id = 0x%x clk drift = %d clk reset = %d port id 0x%x\n", + __func__, clk_drift.clk_id, clk_drift.clk_drift, + clk_drift.clk_reset, port_id); + + mutex_lock(&this_afe.afe_clk_lock); + param_hdr.module_id = AFE_MODULE_CLOCK_SET; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CLOCK_ADJUST; + param_hdr.param_size = sizeof(struct afe_set_clk_drift); + + ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr, + (u8 *) &clk_drift); + if (ret < 0) + pr_err_ratelimited("%s: AFE PLL clk drift failed with ret %d\n", + __func__, ret); + + mutex_unlock(&this_afe.afe_clk_lock); + return ret; +} +EXPORT_SYMBOL(afe_set_pll_clk_drift); + /** * afe_set_lpass_clk_cfg - Set AFE clk config * @@ -7929,6 +8116,10 @@ int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg) return -EINVAL; } + ret = afe_set_clk_id(port_id, cfg->clk_id); + if (ret < 0) + pr_debug("%s: afe_set_clk_id fail %d\n", __func__, ret); + ret = afe_set_lpass_clk_cfg(index, cfg); if (ret) pr_err("%s: afe_set_lpass_clk_cfg_v2 failed %d\n", diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 7d56a4d75c25..5ac775188fa6 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -11766,6 +11766,35 @@ struct afe_clk_cfg { #define AFE_MODULE_CLOCK_SET 0x0001028F #define AFE_PARAM_ID_CLOCK_SET 0x00010290 +struct afe_set_clk_drift { + /* + * Clock ID + * @values + * - 0x100 to 0x10E + * - 0x200 to 0x20C + * - 0x500 to 0x505 + */ + uint32_t clk_id; + + /* + * Clock drift (in PPB) to be set. + * @values + * - need to get values from DSP team + */ + int32_t clk_drift; + + /* + * Clock rest. + * @values + * - 1 -- Reset PLL with the original frequency + * - 0 -- Adjust the clock with the clk drift value + */ + uint32_t clk_reset; +} __packed; + +/* This param id is used to adjust audio interface PLL*/ +#define AFE_PARAM_ID_CLOCK_ADJUST 0x000102C6 + enum afe_lpass_digital_clk_src { Q6AFE_LPASS_DIGITAL_ROOT_INVALID, Q6AFE_LPASS_DIGITAL_ROOT_PRI_MI2S_OSR, diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 76617a980d05..3ff3028c46ac 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -487,6 +487,9 @@ void afe_register_wakeup_irq_callback( void (*afe_cb_wakeup_irq)(void *handle)); int afe_get_doa_tracking_mon(u16 port_id, struct doa_tracking_mon_param *doa_tracking_data); +int afe_set_pll_clk_drift(u16 port_id, int32_t set_clk_drift, + uint32_t clk_reset); +int afe_set_clk_id(u16 port_id, uint32_t clk_id); enum { AFE_LPASS_CORE_HW_BLOCK_ID_NONE, -- GitLab From 76a9c9888f2395ae218ce735702aa33b5d56baa6 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Fri, 24 Jan 2020 14:41:46 +0530 Subject: [PATCH 1464/1645] asoc: add mixer control to set clock drift Add mixer controls support in routing driver to adjust the source PLL clock drift. Change-Id: I211330793f8650902130905f308dc5d4b73e09fa Signed-off-by: Surendar Karka --- asoc/msm-pcm-routing-v2.c | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 70e2ebf5fc76..d4fbe39fe325 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -30222,6 +30222,50 @@ static const struct snd_kcontrol_new aptx_dec_license_controls[] = { msm_aptx_dec_license_control_put), }; +static int msm_routing_get_pll_clk_drift(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static int msm_routing_put_pll_clk_drift(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u16 port_id = 0; + int32_t clk_drift = 0; + uint32_t clk_reset = 0; + int be_idx, ret = -EINVAL; + + be_idx = ucontrol->value.integer.value[0]; + clk_drift = ucontrol->value.integer.value[1]; + clk_reset = ucontrol->value.integer.value[2]; + + if (be_idx < 0 && be_idx >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: Invalid be id %d\n", __func__, be_idx); + return -EINVAL; + } + + if (!msm_bedais[be_idx].active && !clk_reset) { + pr_err("%s:BE is not active %d, cannot set clock drift\n", + __func__, be_idx); + return -EINVAL; + } + + port_id = msm_bedais[be_idx].port_id; + pr_debug("%s: clk drift %d be idx %d clk reset %d port id 0x%x\n", + __func__, clk_drift, be_idx, clk_reset, port_id); + ret = afe_set_pll_clk_drift(port_id, clk_drift, clk_reset); + if (ret < 0) + pr_err("%s: failed to set pll clk drift\n", __func__); + + return ret; +} + +static const struct snd_kcontrol_new pll_clk_drift_controls[] = { + SOC_SINGLE_MULTI_EXT("PLL config data", SND_SOC_NOPM, 0, 0xFFFFFFFF, + 0, 128, msm_routing_get_pll_clk_drift, msm_routing_put_pll_clk_drift), +}; + static int msm_routing_put_port_chmap_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -30522,6 +30566,9 @@ static int msm_routing_probe(struct snd_soc_component *component) port_multi_channel_map_mixer_controls, ARRAY_SIZE(port_multi_channel_map_mixer_controls)); + snd_soc_add_component_controls(component, pll_clk_drift_controls, + ARRAY_SIZE(pll_clk_drift_controls)); + return 0; } -- GitLab From 8948a6df166304391f5c2bd890f5527d239618b6 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Fri, 24 Jan 2020 14:44:13 +0530 Subject: [PATCH 1465/1645] asoc: qcs405: add support to set clock drift AFE driver maintains the clk id for each port. AFE driver has no clue of the master port in META I2S port. Add support to set the clk id for META I2S port. Change-Id: Ic531e94df5503f5ff95364830c5177e9cd86af6c Signed-off-by: Surendar Karka --- asoc/qcs405.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/asoc/qcs405.c b/asoc/qcs405.c index b76728cd21c0..63422f666915 100644 --- a/asoc/qcs405.c +++ b/asoc/qcs405.c @@ -6677,6 +6677,7 @@ static int msm_meta_mi2s_snd_startup(struct snd_pcm_substream *substream) unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; struct snd_soc_card *card = rtd->card; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + u16 port_id = 0; dev_dbg(rtd->card->dev, "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", @@ -6710,6 +6711,13 @@ static int msm_meta_mi2s_snd_startup(struct snd_pcm_substream *substream) meta_mi2s_intf_conf[index].clk_enable[i] = true; if (i == 0) { + port_id = msm_get_port_id(rtd->dai_link->id); + ret = afe_set_clk_id(port_id, + mi2s_clk[member_port].clk_id); + if (ret < 0) + pr_err("%s: afe_set_clk_id fail %d\n", + __func__, ret); + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); if (ret < 0) { pr_err("%s: set fmt cpu dai failed for META_MI2S (%d), err:%d\n", -- GitLab From db84397ed40c00de6c5e91cac2b2da5efda18439 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 10 Apr 2020 17:40:37 +0530 Subject: [PATCH 1466/1645] audio-kernel: Fix compile with CONFIG_DEBUG_FS removed Add fix for compilation failure after remove CONFIG_DEBUG_FS. Change-Id: I94f851916e1c397848aa5d107774f7480a74270f Signed-off-by: Laxminath Kasam --- dsp/codecs/audio_alac.c | 6 ++- dsp/codecs/audio_ape.c | 6 ++- dsp/codecs/audio_g711alaw.c | 6 ++- dsp/codecs/audio_g711mlaw.c | 6 ++- dsp/q6asm.c | 100 ++++++++++++++++++------------------ ipc/apr.c | 8 +-- ipc/apr_vm.c | 8 +-- 7 files changed, 80 insertions(+), 60 deletions(-) diff --git a/dsp/codecs/audio_alac.c b/dsp/codecs/audio_alac.c index a3e473f7082e..dbe9399d2476 100644 --- a/dsp/codecs/audio_alac.c +++ b/dsp/codecs/audio_alac.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #include @@ -10,6 +10,7 @@ static struct miscdevice audio_alac_misc; static struct ws_mgr audio_alac_ws_mgr; +#ifdef CONFIG_DEBUG_FS static const struct file_operations audio_alac_debug_fops = { .read = audio_aio_debug_read, .open = audio_aio_debug_open, @@ -20,6 +21,7 @@ static struct dentry *config_debugfs_create_file(const char *name, void *data) return debugfs_create_file(name, S_IFREG | 0444, NULL, (void *)data, &audio_alac_debug_fops); } +#endif static int alac_channel_map(u8 *channel_mapping, uint32_t channels); @@ -323,10 +325,12 @@ static int audio_open(struct inode *inode, struct file *file) } snprintf(name, sizeof(name), "msm_alac_%04x", audio->ac->session); +#ifdef CONFIG_DEBUG_FS audio->dentry = config_debugfs_create_file(name, (void *)audio); if (IS_ERR_OR_NULL(audio->dentry)) pr_debug("debugfs_create_file failed\n"); +#endif pr_debug("%s:alacdec success mode[%d]session[%d]\n", __func__, audio->feedback, audio->ac->session); diff --git a/dsp/codecs/audio_ape.c b/dsp/codecs/audio_ape.c index 319828bd5465..939f1e1ae2b9 100644 --- a/dsp/codecs/audio_ape.c +++ b/dsp/codecs/audio_ape.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #include @@ -10,6 +10,7 @@ static struct miscdevice audio_ape_misc; static struct ws_mgr audio_ape_ws_mgr; +#ifdef CONFIG_DEBUG_FS static const struct file_operations audio_ape_debug_fops = { .read = audio_aio_debug_read, .open = audio_aio_debug_open, @@ -19,6 +20,7 @@ static struct dentry *config_debugfs_create_file(const char *name, void *data) return debugfs_create_file(name, S_IFREG | 0444, NULL, (void *)data, &audio_ape_debug_fops); } +#endif static long audio_ioctl_shared(struct file *file, unsigned int cmd, void *arg) @@ -305,10 +307,12 @@ static int audio_open(struct inode *inode, struct file *file) } snprintf(name, sizeof(name), "msm_ape_%04x", audio->ac->session); +#ifdef CONFIG_DEBUG_FS audio->dentry = config_debugfs_create_file(name, (void *)audio); if (IS_ERR_OR_NULL(audio->dentry)) pr_debug("debugfs_create_file failed\n"); +#endif pr_debug("%s:apedec success mode[%d]session[%d]\n", __func__, audio->feedback, audio->ac->session); diff --git a/dsp/codecs/audio_g711alaw.c b/dsp/codecs/audio_g711alaw.c index 27d7fe0b35dd..2aca8e1b4501 100644 --- a/dsp/codecs/audio_g711alaw.c +++ b/dsp/codecs/audio_g711alaw.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, 2019-2020 The Linux Foundation. All rights reserved. */ #include @@ -10,6 +10,7 @@ static struct miscdevice audio_g711alaw_misc; static struct ws_mgr audio_g711_ws_mgr; +#ifdef CONFIG_DEBUG_FS static const struct file_operations audio_g711_debug_fops = { .read = audio_aio_debug_read, .open = audio_aio_debug_open, @@ -20,6 +21,7 @@ static struct dentry *config_debugfs_create_file(const char *name, void *data) return debugfs_create_file(name, S_IFREG | 0444, NULL, (void *)data, &audio_g711_debug_fops); } +#endif static int g711_channel_map(u8 *channel_mapping, uint32_t channels); @@ -278,10 +280,12 @@ static int audio_open(struct inode *inode, struct file *file) } snprintf(name, sizeof(name), "msm_g711_%04x", audio->ac->session); +#ifdef CONFIG_DEBUG_FS audio->dentry = config_debugfs_create_file(name, (void *)audio); if (IS_ERR_OR_NULL(audio->dentry)) pr_debug("%s: debugfs_create_file failed\n", __func__); +#endif pr_debug("%s: g711dec success mode[%d]session[%d]\n", __func__, audio->feedback, audio->ac->session); diff --git a/dsp/codecs/audio_g711mlaw.c b/dsp/codecs/audio_g711mlaw.c index 57c7f1ae7e09..623c7a0c275f 100644 --- a/dsp/codecs/audio_g711mlaw.c +++ b/dsp/codecs/audio_g711mlaw.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, 2019-2020 The Linux Foundation. All rights reserved. */ #include @@ -10,6 +10,7 @@ static struct miscdevice audio_g711mlaw_misc; static struct ws_mgr audio_g711_ws_mgr; +#ifdef CONFIG_DEBUG_FS static const struct file_operations audio_g711_debug_fops = { .read = audio_aio_debug_read, .open = audio_aio_debug_open, @@ -20,6 +21,7 @@ static struct dentry *config_debugfs_create_file(const char *name, void *data) return debugfs_create_file(name, S_IFREG | 0444, NULL, (void *)data, &audio_g711_debug_fops); } +#endif static int g711_channel_map(u8 *channel_mapping, uint32_t channels); @@ -277,10 +279,12 @@ static int audio_open(struct inode *inode, struct file *file) } snprintf(name, sizeof(name), "msm_g711_%04x", audio->ac->session); +#ifdef CONFIG_DEBUG_FS audio->dentry = config_debugfs_create_file(name, (void *)audio); if (IS_ERR_OR_NULL(audio->dentry)) pr_debug("%s: debugfs_create_file failed\n", __func__); +#endif pr_debug("%s: g711dec success mode[%d]session[%d]\n", __func__, audio->feedback, audio->ac->session); diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 6b0a377df532..fef09c589722 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -145,56 +145,6 @@ struct generic_get_data_ { }; static struct generic_get_data_ *generic_get_data; -#ifdef CONFIG_DEBUG_FS -#define OUT_BUFFER_SIZE 56 -#define IN_BUFFER_SIZE 24 - -static struct timeval out_cold_tv; -static struct timeval out_warm_tv; -static struct timeval out_cont_tv; -static struct timeval in_cont_tv; -static long out_enable_flag; -static long in_enable_flag; -static struct dentry *out_dentry; -static struct dentry *in_dentry; -static int in_cont_index; -/*This var is used to keep track of first write done for cold output latency */ -static int out_cold_index; -static char *out_buffer; -static char *in_buffer; - -static uint32_t adsp_reg_event_opcode[] = { - ASM_STREAM_CMD_REGISTER_PP_EVENTS, - ASM_STREAM_CMD_REGISTER_ENCDEC_EVENTS, - ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE }; - -static uint32_t adsp_raise_event_opcode[] = { - ASM_STREAM_PP_EVENT, - ASM_STREAM_CMD_ENCDEC_EVENTS, - ASM_IEC_61937_MEDIA_FMT_EVENT }; - -static int is_adsp_reg_event(uint32_t cmd) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(adsp_reg_event_opcode); i++) { - if (cmd == adsp_reg_event_opcode[i]) - return i; - } - return -EINVAL; -} - -static int is_adsp_raise_event(uint32_t cmd) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(adsp_raise_event_opcode); i++) { - if (cmd == adsp_raise_event_opcode[i]) - return i; - } - return -EINVAL; -} - static inline void q6asm_set_flag_in_token(union asm_token_struct *asm_token, int flag, int flag_offset) { @@ -277,6 +227,56 @@ uint8_t q6asm_get_stream_id_from_token(uint32_t token) } EXPORT_SYMBOL(q6asm_get_stream_id_from_token); +static uint32_t adsp_reg_event_opcode[] = { + ASM_STREAM_CMD_REGISTER_PP_EVENTS, + ASM_STREAM_CMD_REGISTER_ENCDEC_EVENTS, + ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE }; + +static int is_adsp_reg_event(uint32_t cmd) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(adsp_reg_event_opcode); i++) { + if (cmd == adsp_reg_event_opcode[i]) + return i; + } + return -EINVAL; +} + +static uint32_t adsp_raise_event_opcode[] = { + ASM_STREAM_PP_EVENT, + ASM_STREAM_CMD_ENCDEC_EVENTS, + ASM_IEC_61937_MEDIA_FMT_EVENT }; + +static int is_adsp_raise_event(uint32_t cmd) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(adsp_raise_event_opcode); i++) { + if (cmd == adsp_raise_event_opcode[i]) + return i; + } + return -EINVAL; +} + +#ifdef CONFIG_DEBUG_FS +#define OUT_BUFFER_SIZE 56 +#define IN_BUFFER_SIZE 24 + +static struct timeval out_cold_tv; +static struct timeval out_warm_tv; +static struct timeval out_cont_tv; +static struct timeval in_cont_tv; +static long out_enable_flag; +static long in_enable_flag; +static struct dentry *out_dentry; +static struct dentry *in_dentry; +static int in_cont_index; +/*This var is used to keep track of first write done for cold output latency */ +static int out_cold_index; +static char *out_buffer; +static char *in_buffer; + static int audio_output_latency_dbgfs_open(struct inode *inode, struct file *file) { diff --git a/ipc/apr.c b/ipc/apr.c index 0ea269454035..54761875cf67 100644 --- a/ipc/apr.c +++ b/ipc/apr.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2010-2014, 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2014, 2016-2020 The Linux Foundation. All rights reserved. */ #include @@ -1117,9 +1117,9 @@ static int __init apr_debug_init(void) } #else static int __init apr_debug_init(void) -( +{ return 0; -) +} #endif static void apr_cleanup(void) @@ -1140,7 +1140,9 @@ static void apr_cleanup(void) mutex_destroy(&client[i][j].svc[k].m_lock); } } +#ifdef CONFIG_DEBUG_FS debugfs_remove(debugfs_apr_debug); +#endif } static int apr_probe(struct platform_device *pdev) diff --git a/ipc/apr_vm.c b/ipc/apr_vm.c index f94e3a22db64..1b66013b8cf4 100644 --- a/ipc/apr_vm.c +++ b/ipc/apr_vm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2010-2014, 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2014, 2016-2020 The Linux Foundation. All rights reserved. */ #include @@ -1308,9 +1308,9 @@ static int __init apr_debug_init(void) } #else static int __init apr_debug_init(void) -( +{ return 0; -) +} #endif static void apr_cleanup(void) @@ -1331,7 +1331,9 @@ static void apr_cleanup(void) mutex_destroy(&client[i][j].svc[k].m_lock); } } +#ifdef CONFIG_DEBUG_FS debugfs_remove(debugfs_apr_debug); +#endif } static int apr_probe(struct platform_device *pdev) -- GitLab From b0818d077054eba33429b0a2da4df1028f86dc0f Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 1 Apr 2020 10:45:30 +0530 Subject: [PATCH 1467/1645] asoc: codecs: Set EAR compander if mixer ctl set Enable compander based on mixer ctl set for ear path. Change-Id: Ie6287469f1baa9dba239d369bd5a29ed8e44522f Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd937x/wcd937x.c | 7 ++++++- asoc/codecs/wcd938x/wcd938x.c | 12 ++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 1f4146a17fe9..30ad7e333e13 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -570,7 +570,8 @@ static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x06); - snd_soc_component_update_bits(component, + if (wcd937x->comp1_enable) + snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x02); usleep_range(5000, 5010); @@ -588,6 +589,10 @@ static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x0F, 0x01); + if (wcd937x->comp1_enable) + snd_soc_component_update_bits(component, + WCD937X_DIGITAL_CDC_COMP_CTL_0, + 0x02, 0x00); break; }; return 0; diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 36c18eae6e36..abd3106fe743 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -657,8 +657,10 @@ static int wcd938x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, WCD938X_DIGITAL_CDC_HPH_GAIN_CTL, 0x04, 0x04); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x01); - snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x02); + if (wcd938x->comp1_enable) + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_COMP_CTL_0, + 0x02, 0x02); } /* 5 msec delay as per HW requirement */ usleep_range(5000, 5010); @@ -683,8 +685,10 @@ static int wcd938x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, WCD938X_DIGITAL_CDC_HPH_GAIN_CTL, 0x04, 0x00); snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x00); - snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x00); + if (wcd938x->comp1_enable) + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_COMP_CTL_0, + 0x02, 0x00); } snd_soc_component_update_bits(component, WCD938X_ANA_EAR_COMPANDER_CTL, 0x80, 0x00); -- GitLab From fddc9df2d5fdaabd9c8d49a5bcb3729c2c3ac5b7 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 21 Apr 2020 14:16:51 +0530 Subject: [PATCH 1468/1645] bolero: rx-macro: Resolve noise on ear path during hph ear concurrency There is noise on ear path during hph and ear concurrency. Set proper HPH_V_PA voltage when both hph PA is in class-H mode to resolve noise. Change-Id: Ifbbfb5691687dcb2202358c1e387252954d58db2 Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/rx-macro.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index eb7cb883cc05..70b012682b6d 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1908,7 +1908,12 @@ static int rx_macro_config_classh(struct snd_soc_component *component, 0x40, 0x40); break; case INTERP_HPHR: - snd_soc_component_update_bits(component, + if (rx_priv->is_ear_mode_on) + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_CLSH_HPH_V_PA, + 0x3F, 0x39); + else + snd_soc_component_update_bits(component, BOLERO_CDC_RX_CLSH_HPH_V_PA, 0x3F, 0x1C); snd_soc_component_update_bits(component, -- GitLab From 1ac295b4944bbe43469953670164584b9e7790f5 Mon Sep 17 00:00:00 2001 From: Preetam Singh Ranawat Date: Wed, 22 Apr 2020 16:57:02 +0530 Subject: [PATCH 1469/1645] asoc: msm-compress: Reset channel map flag during close. For some of the clips improper channel map is applied when not set from userspace. Reset channel map flag to apply default channel map. Change-Id: Ic128b835ecea632c99fba5b14471fc76e767b80e Signed-off-by: Preetam Singh Ranawat --- asoc/msm-compress-q6-v2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index 6221a2f83c67..cd779ccb7cdf 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -1975,6 +1975,9 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream) kfree(pdata->dec_params[soc_prtd->dai_link->id]); pdata->dec_params[soc_prtd->dai_link->id] = NULL; } + if (pdata->ch_map[soc_prtd->dai_link->id]) { + pdata->ch_map[soc_prtd->dai_link->id]->set_ch_map = false; + } pdata->is_in_use[soc_prtd->dai_link->id] = false; kfree(prtd); runtime->private_data = NULL; -- GitLab From 100a2501338712163731c200d5193359483afbdd Mon Sep 17 00:00:00 2001 From: Guodong Hu Date: Tue, 14 Apr 2020 23:03:31 +0800 Subject: [PATCH 1470/1645] asoc: fix prepare error in pulseaudio loopback cases In pulseaudio, prepare comes just after open for every substream in loopback cases, but the 'audio_client' is not allocated for the first substream in every pcm. And the returned error causes the failure of pulseaudio initialization for all loopback cases. Change-Id: I7fb6c1f23b9cf2660e4dd519a731c7e13a809a4a Signed-off-by: Guodong Hu --- asoc/msm-pcm-loopback-v2.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index 4c00c72e7a74..af6be3ad4515 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -448,12 +448,6 @@ static int msm_pcm_prepare(struct snd_pcm_substream *substream) dev_dbg(component->dev, "%s: ASM loopback stream:%d\n", __func__, substream->stream); - if (!pcm || !pcm->audio_client) { - mutex_unlock(&pcm->lock); - pr_err("%s: private data null or audio client freed\n", __func__); - return -EINVAL; - } - if (pcm->playback_start && pcm->capture_start) { mutex_unlock(&pcm->lock); return ret; @@ -474,6 +468,12 @@ static int msm_pcm_prepare(struct snd_pcm_substream *substream) pcm->capture_substream->private_data; event.event_func = msm_pcm_route_event_handler; event.priv_data = (void *) pcm; + + if (!pcm->audio_client) { + mutex_unlock(&pcm->lock); + pr_err("%s: audio client freed\n", __func__); + return -EINVAL; + } msm_pcm_routing_reg_phy_stream(soc_pcm_tx->dai_link->id, pcm->audio_client->perf_mode, pcm->session_id, pcm->capture_substream->stream); -- GitLab From c77cce854f10488ff4f84783517b21680ae17e7c Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Sun, 12 Apr 2020 21:15:12 +0530 Subject: [PATCH 1471/1645] dsp: Add spinlock to protect audio client Add spinlock in callback func to avoid race condition between session_free and q6lsm_callback. Change-Id: Ic008bf17693a2c2217c8933c2e52a7965c249bda Signed-off-by: Prasad Kumpatla --- dsp/q6lsm.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index a77ffd3c29d3..c00bb9406833 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -117,6 +117,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) struct lsm_client *client = (struct lsm_client *)priv; uint32_t token; uint32_t *payload; + unsigned long flags; if (!client || !data) { pr_err("%s: client %pK data %pK\n", @@ -150,6 +151,13 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) return 0; } + spin_lock_irqsave(&lsm_session_lock, flags); + if (!client || !q6lsm_is_valid_lsm_client(client)) { + pr_err("%s: client already freed/invalid, return\n", + __func__); + spin_unlock_irqrestore(&lsm_session_lock, flags); + return -EINVAL; + } payload = data->payload; pr_debug("%s: Session %d opcode 0x%x token 0x%x payload size %d\n" "payload [0] = 0x%x\n", __func__, client->session, @@ -163,6 +171,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) pr_err("%s: read done error payload size %d expected size %zd\n", __func__, data->payload_size, sizeof(read_done)); + spin_unlock_irqrestore(&lsm_session_lock, flags); return -EINVAL; } pr_debug("%s: opcode %x status %x lsw %x msw %x mem_map handle %x\n", @@ -179,6 +188,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) (void *)&read_done, sizeof(read_done), client->priv); + spin_unlock_irqrestore(&lsm_session_lock, flags); return 0; } else if (data->opcode == APR_BASIC_RSP_RESULT) { token = data->token; @@ -203,11 +213,13 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL) { pr_err("%s: Invalid session %d receivced expected %d\n", __func__, token, client->session); + spin_unlock_irqrestore(&lsm_session_lock, flags); return -EINVAL; } if (data->payload_size < 2 * sizeof(payload[0])) { pr_err("%s: payload has invalid size[%d]\n", __func__, data->payload_size); + spin_unlock_irqrestore(&lsm_session_lock, flags); return -EINVAL; } client->cmd_err_code = payload[1]; @@ -225,6 +237,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) __func__, payload[0]); break; } + spin_unlock_irqrestore(&lsm_session_lock, flags); return 0; } @@ -232,6 +245,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) client->cb(data->opcode, data->token, data->payload, data->payload_size, client->priv); + spin_unlock_irqrestore(&lsm_session_lock, flags); return 0; } -- GitLab From 107e8ebad82e3d3122968df60ac1aece2683bed4 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Thu, 16 Apr 2020 20:05:01 +0800 Subject: [PATCH 1472/1645] asoc: codecs: fix incorrect micbias value set at rouleur Micbias value set does not take effect on rouleur. Shift micbias value to correct bits. Change-Id: Ice083e3bc30f6e8e3fe7132c633a4043329ccfa5 Signed-off-by: Xiaojun Sang --- asoc/codecs/rouleur/rouleur.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index a0ed49a63bb0..d028ed48b58f 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -1118,7 +1118,7 @@ int rouleur_mbhc_micb_adjust_voltage(struct snd_soc_component *component, */ cur_vout_ctl = (snd_soc_component_read32(component, ROULEUR_ANA_MICBIAS_LDO_1_SETTING)) & 0xF8; - + cur_vout_ctl = cur_vout_ctl >> 3; req_vout_ctl = rouleur_get_micb_vout_ctl_val(req_volt); if (req_vout_ctl < 0) { ret = -EINVAL; @@ -1138,7 +1138,7 @@ int rouleur_mbhc_micb_adjust_voltage(struct snd_soc_component *component, pullup_mask); snd_soc_component_update_bits(component, - ROULEUR_ANA_MICBIAS_LDO_1_SETTING, 0xF8, req_vout_ctl); + ROULEUR_ANA_MICBIAS_LDO_1_SETTING, 0xF8, req_vout_ctl << 3); if (micb_en == 0x1) { snd_soc_component_update_bits(component, micb_reg, @@ -1911,7 +1911,7 @@ static int rouleur_set_micbias_data(struct rouleur_priv *rouleur, goto done; } regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MICBIAS_LDO_1_SETTING, - 0xF8, vout_ctl); + 0xF8, vout_ctl << 3); done: return rc; } -- GitLab From 4dbbce0f6338f2223c03bb8e57065d885ef49fd9 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Thu, 9 Apr 2020 17:24:02 +0530 Subject: [PATCH 1473/1645] asoc: codecs: Fix out of bounds access in register show function In register show function, when snprintf returns a negative value out of bounds access occurs while copying the data to user. Add return value check on snprintf before copy_to_user to fix this and add sizeof() for tmp_buff to avoid buffer overflow. Change-Id: I15f1add37987d2176a165669d7a5b40bd576004c Signed-off-by: Prasad Kumpatla --- asoc/codecs/wsa883x/wsa883x.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 1e6757d44751..9e25e53a8bff 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -238,8 +238,13 @@ static ssize_t swr_slave_reg_show(struct swr_device *pdev, char __user *ubuf, if (!is_swr_slave_reg_readable(i)) continue; swr_read(pdev, pdev->dev_num, i, ®_val, 1); - len = snprintf(tmp_buf, 25, "0x%.3x: 0x%.2x\n", i, + len = snprintf(tmp_buf, sizeof(tmp_buf), "0x%.3x: 0x%.2x\n", i, (reg_val & 0xFF)); + if (len < 0) { + pr_err("%s: fail to fill the buffer\n", __func__); + total = -EFAULT; + goto copy_err; + } if ((total + len) >= count - 1) break; if (copy_to_user((ubuf + total), tmp_buf, len)) { -- GitLab From 13d9c56f1204765ef18a652315ef7c18dd3a3682 Mon Sep 17 00:00:00 2001 From: Avinash Chandra Date: Mon, 27 Apr 2020 19:23:49 +0530 Subject: [PATCH 1474/1645] dsp: q6adm: Update the proper param_hdr for offset For Source Tracking adm_get_param, param_hdr (struct param_hdr_v3) size being sent was different as param_hdr(struct param_hdr_v1)size used for offset of virtual memory to copy the param data in out-band case get_param. Change-Id: I01dd4f704cc5b6994f1203a0e28199a6936cba7f Signed-off-by: Avinash Chandra --- dsp/q6adm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index a2f644f6eb54..fc44819f1c18 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -5337,7 +5337,7 @@ int adm_get_source_tracking(int port_id, int copp_idx, */ param_hdr.param_size = sizeof(struct adm_param_fluence_sourcetracking_t) + - sizeof(union param_hdrs); + sizeof(struct param_hdr_v3); /* * Retrieving parameters out of band, so no need to provide a buffer for @@ -5366,7 +5366,7 @@ int adm_get_source_tracking(int port_id, int copp_idx, source_tracking_params = (struct adm_param_fluence_sourcetracking_t *) (this_adm.sourceTrackingData.memmap.kvaddr + - sizeof(struct param_hdr_v1)); + sizeof(struct param_hdr_v3)); for (i = 0; i < MAX_SECTORS; i++) { sourceTrackingData->vad[i] = source_tracking_params->vad[i]; pr_debug("%s: vad[%d] = %d\n", -- GitLab From 73438d1c8be043f7125fe537ee4bb52791e22beb Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 27 Apr 2020 13:02:03 +0530 Subject: [PATCH 1475/1645] audio-kernel: Add void param in function definition Add void param in function definition to avoid compilation errors when strict prototypes flag is defined. Change-Id: I4515c730139fff18638805cd70db24ec1886f127 --- dsp/digital-cdc-rsc-mgr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dsp/digital-cdc-rsc-mgr.c b/dsp/digital-cdc-rsc-mgr.c index 4206523ea85b..be5d5cad79d7 100644 --- a/dsp/digital-cdc-rsc-mgr.c +++ b/dsp/digital-cdc-rsc-mgr.c @@ -87,13 +87,13 @@ void digital_cdc_rsc_mgr_hw_vote_reset(struct clk* vote_handle) } EXPORT_SYMBOL(digital_cdc_rsc_mgr_hw_vote_reset); -void digital_cdc_rsc_mgr_init() +void digital_cdc_rsc_mgr_init(void) { mutex_init(&hw_vote_lock); is_init_done = true; } -void digital_cdc_rsc_mgr_exit() +void digital_cdc_rsc_mgr_exit(void) { mutex_destroy(&hw_vote_lock); is_init_done = false; -- GitLab From 681a9ea6957daba065f30e69fad21f5689ceeb11 Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Thu, 14 Mar 2019 12:49:47 +0530 Subject: [PATCH 1476/1645] asoc: add render mode support in transcode loopback Add new TTP render mode in compress driver and render mode support in transcode loopback driver. Change-Id: I636ecd5fd3fa5ccafb6086b4fca41c240b758391 Signed-off-by: Surendar Karka --- asoc/msm-compress-q6-v2.c | 13 ++++-- asoc/msm-transcode-loopback-q6-v2.c | 63 +++++++++++++++++++++++++++-- include/dsp/apr_audio-v2.h | 2 + 3 files changed, 72 insertions(+), 6 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index cd779ccb7cdf..fdf61cfde6ea 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -231,12 +231,19 @@ static int msm_compr_set_render_mode(struct msm_compr_audio *prtd, pr_debug("%s, got render mode %u\n", __func__, render_mode); - if (render_mode == SNDRV_COMPRESS_RENDER_MODE_AUDIO_MASTER) { + switch (render_mode) { + case SNDRV_COMPRESS_RENDER_MODE_AUDIO_MASTER: render_mode = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_DEFAULT; - } else if (render_mode == SNDRV_COMPRESS_RENDER_MODE_STC_MASTER) { + break; + case SNDRV_COMPRESS_RENDER_MODE_STC_MASTER: render_mode = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_LOCAL_STC; prtd->run_mode = ASM_SESSION_CMD_RUN_STARTIME_RUN_WITH_DELAY; - } else { + break; + case SNDRV_COMPRESS_RENDER_MODE_TTP: + render_mode = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_LOCAL_STC; + prtd->run_mode = ASM_SESSION_CMD_RUN_STARTIME_RUN_WITH_TTP; + break; + default: pr_err("%s, Invalid render mode %u\n", __func__, render_mode); ret = -EINVAL; diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index df48f5a57adc..e20f0dfebdc6 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #include @@ -95,6 +95,9 @@ struct msm_transcode_loopback { int session_id; struct audio_client *audio_client; + uint32_t run_mode; + uint32_t start_delay_lsw; + uint32_t start_delay_msw; }; /* Transcode loopback global info struct */ @@ -342,6 +345,7 @@ static int msm_transcode_loopback_free(struct snd_compr_stream *cstream) } trans->session_state = LOOPBACK_SESSION_CLOSE; + trans->run_mode = ASM_SESSION_CMD_RUN_STARTIME_RUN_IMMEDIATE; mutex_unlock(&trans->lock); return ret; } @@ -360,7 +364,9 @@ static int msm_transcode_loopback_trigger(struct snd_compr_stream *cstream, if (trans->session_state == LOOPBACK_SESSION_START) { pr_debug("%s: Issue Loopback session %d RUN\n", __func__, trans->instance); - q6asm_run_nowait(trans->audio_client, 0, 0, 0); + q6asm_run_nowait(trans->audio_client, trans->run_mode, + trans->start_delay_msw, + trans->start_delay_lsw); trans->session_state = LOOPBACK_SESSION_RUN; } break; @@ -606,6 +612,42 @@ static int msm_transcode_loopback_get_caps(struct snd_compr_stream *cstream, return 0; } +static int msm_transcode_set_render_mode(struct msm_transcode_loopback *prtd, + uint32_t render_mode) +{ + int ret = -EINVAL; + struct audio_client *ac = prtd->audio_client; + + pr_debug("%s: got render mode %u\n", __func__, render_mode); + + switch (render_mode) { + case SNDRV_COMPRESS_RENDER_MODE_AUDIO_MASTER: + render_mode = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_DEFAULT; + break; + case SNDRV_COMPRESS_RENDER_MODE_STC_MASTER: + render_mode = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_LOCAL_STC; + prtd->run_mode = ASM_SESSION_CMD_RUN_STARTIME_RUN_WITH_DELAY; + break; + case SNDRV_COMPRESS_RENDER_MODE_TTP: + render_mode = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_LOCAL_STC; + prtd->run_mode = ASM_SESSION_CMD_RUN_STARTIME_RUN_WITH_TTP; + break; + default: + pr_err("%s: Invalid render mode %u\n", __func__, + render_mode); + ret = -EINVAL; + goto exit; + } + + ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode); + if (ret) { + pr_err("%s: Render mode can't be set error %d\n", __func__, + ret); + } +exit: + return ret; +} + static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream, struct snd_compr_metadata *metadata) { @@ -614,6 +656,7 @@ static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream, struct msm_transcode_loopback *prtd = NULL; struct snd_soc_component *component; struct audio_client *ac = NULL; + int rc = 0; if (!metadata || !cstream) { pr_err("%s: Invalid arguments\n", __func__); @@ -660,6 +703,20 @@ static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream, } break; } + case SNDRV_COMPRESS_RENDER_MODE: + { + rc = msm_transcode_set_render_mode(prtd, metadata->value[0]); + if (rc) + pr_err("%s: error setting render mode %d\n", __func__, + rc); + break; + } + case SNDRV_COMPRESS_START_DELAY: + { + prtd->start_delay_lsw = metadata->value[0]; + prtd->start_delay_msw = metadata->value[1]; + break; + } case SNDRV_COMPRESS_RENDER_WINDOW: { return msm_transcode_set_render_window( @@ -674,7 +731,7 @@ static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream, __func__, metadata->key); break; } - return 0; + return rc; } static int msm_transcode_stream_cmd_put(struct snd_kcontrol *kcontrol, diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 5ac775188fa6..311c892ee695 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -7550,6 +7550,7 @@ struct asm_data_cmd_iec_60958_frame_rate { #define ASM_SESSION_CMD_RUN_STARTIME_RUN_AT_ABSOLUTEIME 1 #define ASM_SESSION_CMD_RUN_STARTIME_RUN_AT_RELATIVEIME 2 #define ASM_SESSION_CMD_RUN_STARTIME_RUN_WITH_DELAY 3 +#define ASM_SESSION_CMD_RUN_STARTIME_RUN_WITH_TTP 4 #define ASM_BIT_MASK_RUN_STARTIME (0x00000003UL) @@ -7573,6 +7574,7 @@ struct asm_session_cmd_run_v2 { *- #ASM_SESSION_CMD_RUN_STARTIME_RUN_AT_ABSOLUTEIME *- #ASM_SESSION_CMD_RUN_STARTIME_RUN_AT_RELATIVEIME *- #ASM_SESSION_CMD_RUN_STARTIME_RUN_WITH_DELAY + *- #ASM_SESSION_CMD_RUN_STARTIME_RUN_WITH_TTP * *All other bits are reserved; clients must set them to zero. */ -- GitLab From 21d663fa7d8b0db5d5358fbe0702d6caa7052869 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Sat, 18 Apr 2020 11:21:43 +0530 Subject: [PATCH 1477/1645] asoc: Add Rx swr master port config for scuba target Add port config for Rx swr master in order to support the rouleur codec in scuba target. Change-Id: Ic278d02f222686afc6ff976c4b1c3bb499ed903f Signed-off-by: Aditya Bavanari --- asoc/bengal-port-config.h | 16 +++++++++++++++- asoc/bengal.c | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/asoc/bengal-port-config.h b/asoc/bengal-port-config.h index a20a6d54487e..37d4f740aac6 100644 --- a/asoc/bengal-port-config.h +++ b/asoc/bengal-port-config.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #ifndef _BENGAL_PORT_CONFIG @@ -21,6 +21,15 @@ static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = { {0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0}, }; +static struct port_params rx_frame_params_rouleur[SWR_MSTR_PORT_LEN] = { + {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1}, + {31, 0, 0, 3, 6, 7, 0, 0xFF, 0}, + {31, 1, 0, 0xFF, 0xFF, 4, 1, 0xFF, 0}, + {7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, + {0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0}, +}; + + static struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = { {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1}, {31, 0, 0, 3, 6, 7, 0, 0xFF, 0}, @@ -42,4 +51,9 @@ static struct swr_mstr_port_map sm_port_map[] = { {RX_MACRO, SWR_UC1, rx_frame_params_dsd}, }; +static struct swr_mstr_port_map sm_port_map_rouleur[] = { + {VA_MACRO, SWR_UC0, tx_frame_params_default}, + {RX_MACRO, SWR_UC0, rx_frame_params_rouleur}, + {RX_MACRO, SWR_UC1, rx_frame_params_dsd}, +}; #endif /* _BENGAL_PORT_CONFIG */ diff --git a/asoc/bengal.c b/asoc/bengal.c index ec73cc9d6d40..a3f8319edebe 100644 --- a/asoc/bengal.c +++ b/asoc/bengal.c @@ -4218,6 +4218,9 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dapm_context *dapm; struct snd_card *card; struct snd_info_entry *entry; + struct platform_device *pdev = NULL; + int i = 0; + char *data = NULL; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); @@ -4260,8 +4263,38 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_sync(dapm); - bolero_set_port_map(component, ARRAY_SIZE(sm_port_map), - sm_port_map); + for (i = 0; i < rtd->card->num_aux_devs; i++) + { + if (msm_aux_dev[i].name != NULL ) { + if (strstr(msm_aux_dev[i].name, "wsa")) + continue; + } + + if (msm_aux_dev[i].codec_of_node) { + pdev = of_find_device_by_node( + msm_aux_dev[i].codec_of_node); + + if (pdev) + data = (char*) of_device_get_match_data( + &pdev->dev); + if (data != NULL) { + if (!strncmp(data, "wcd937x", + sizeof("wcd937x"))) { + bolero_set_port_map(component, + ARRAY_SIZE(sm_port_map), + sm_port_map); + break; + } else if (!strncmp( data, "rouleur", + sizeof("rouleur"))) { + bolero_set_port_map(component, + ARRAY_SIZE(sm_port_map_rouleur), + sm_port_map_rouleur); + break; + } + } + } + } + card = rtd->card->snd_card; if (!pdata->codec_root) { entry = snd_info_create_subdir(card->module, "codecs", -- GitLab From 55f4acd888b776c3b26e1221f98fdeb39db1b508 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 23 Apr 2020 18:57:27 +0530 Subject: [PATCH 1478/1645] asoc: codecs: Fix button interrupts issue in rouleur Current source mode in rouleur does not work properly leading to issues in button interrupts and fake electrical removal interrupts. Enable pull up mode instead of current source mode to fix these issues. Modify the headset max vref voltage to 1.7 volts and micbias calculation logic. Change-Id: If3e4a2fdcf080b07fe3c363b6eb6115f101b91f4 Signed-off-by: Aditya Bavanari --- asoc/codecs/rouleur/internal.h | 1 + asoc/codecs/rouleur/rouleur-mbhc.c | 39 +++++++++++++++++++++++++++ asoc/codecs/rouleur/rouleur.c | 43 +++++++++++++++++++++++++----- asoc/codecs/wcd-mbhc-adc.c | 22 ++++++++------- asoc/codecs/wcd-mbhc-v2.c | 26 +++++++++++++++--- include/asoc/wcd-mbhc-v2.h | 8 +++++- 6 files changed, 119 insertions(+), 20 deletions(-) diff --git a/asoc/codecs/rouleur/internal.h b/asoc/codecs/rouleur/internal.h index 7104685d7cd8..df8541e34041 100644 --- a/asoc/codecs/rouleur/internal.h +++ b/asoc/codecs/rouleur/internal.h @@ -82,6 +82,7 @@ struct rouleur_priv { int mbias_cnt; struct mutex rx_clk_lock; struct mutex main_bias_lock; + bool dev_up; }; struct rouleur_micbias_setting { diff --git a/asoc/codecs/rouleur/rouleur-mbhc.c b/asoc/codecs/rouleur/rouleur-mbhc.c index 91ddc104acef..673c6147af33 100644 --- a/asoc/codecs/rouleur/rouleur-mbhc.c +++ b/asoc/codecs/rouleur/rouleur-mbhc.c @@ -820,6 +820,42 @@ static void rouleur_mbhc_bcs_enable(struct wcd_mbhc *mbhc, rouleur_disable_bcs_before_slow_insert(mbhc->component, true); } +static void rouleur_mbhc_hs_vref_max_update(struct wcd_mbhc *mbhc) +{ + struct snd_soc_component *component = mbhc->component; + + /* Update the HS Vref max voltage to 1.7V */ + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_CTL_2, + 0x03, 0x03); +} + +static void rouleur_mbhc_get_micbias_val(struct wcd_mbhc *mbhc, int *mb) +{ + u8 vout_ctl = 0; + + /* Read MBHC Micbias (Mic Bias2) voltage */ + WCD_MBHC_REG_READ(WCD_MBHC_MICB2_VOUT, vout_ctl); + + /* Formula for getting micbias from vout + * micbias = 1.6V + VOUT_CTL * 50mV + */ + *mb = 1600 + (vout_ctl * 50); + pr_debug("%s: vout_ctl: %d, micbias: %d\n", __func__, vout_ctl, *mb); +} + +static void rouleur_mbhc_micb_pullup_control( + struct snd_soc_component *component, + bool pullup_enable) +{ + if (pullup_enable) + rouleur_micbias_control(component, MIC_BIAS_2, + MICB_PULLUP_ENABLE, false); + else + rouleur_micbias_control(component, MIC_BIAS_2, + MICB_PULLUP_DISABLE, false); + +} + static const struct wcd_mbhc_cb mbhc_cb = { .request_irq = rouleur_mbhc_request_irq, .irq_control = rouleur_mbhc_irq_control, @@ -844,6 +880,9 @@ static const struct wcd_mbhc_cb mbhc_cb = { .mbhc_get_moisture_status = rouleur_mbhc_get_moisture_status, .mbhc_moisture_detect_en = rouleur_mbhc_moisture_detect_en, .bcs_enable = rouleur_mbhc_bcs_enable, + .hs_vref_max_update = rouleur_mbhc_hs_vref_max_update, + .get_micbias_val = rouleur_mbhc_get_micbias_val, + .mbhc_micb_pullup_control = rouleur_mbhc_micb_pullup_control, }; static int rouleur_get_hph_type(struct snd_kcontrol *kcontrol, diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index d028ed48b58f..cd52580610e8 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -1166,6 +1166,7 @@ int rouleur_micbias_control(struct snd_soc_component *component, int post_on_event = 0, post_dapm_off = 0; int post_dapm_on = 0; u8 pullup_mask = 0, enable_mask = 0; + int ret = 0; if ((micb_index < 0) || (micb_index > ROULEUR_MAX_MICBIAS - 1)) { dev_err(component->dev, "%s: Invalid micbias index, micb_ind:%d\n", @@ -1201,6 +1202,12 @@ int rouleur_micbias_control(struct snd_soc_component *component, switch (req) { case MICB_PULLUP_ENABLE: + if (!rouleur->dev_up) { + dev_dbg(component->dev, "%s: enable req %d wcd device down\n", + __func__, req); + ret = -ENODEV; + goto done; + } rouleur->pullup_ref[micb_index]++; if ((rouleur->pullup_ref[micb_index] == 1) && (rouleur->micb_ref[micb_index] == 0)) @@ -1208,6 +1215,12 @@ int rouleur_micbias_control(struct snd_soc_component *component, pullup_mask, pullup_mask); break; case MICB_PULLUP_DISABLE: + if (!rouleur->dev_up) { + dev_dbg(component->dev, "%s: enable req %d wcd device down\n", + __func__, req); + ret = -ENODEV; + goto done; + } if (rouleur->pullup_ref[micb_index] > 0) rouleur->pullup_ref[micb_index]--; if ((rouleur->pullup_ref[micb_index] == 0) && @@ -1216,11 +1229,15 @@ int rouleur_micbias_control(struct snd_soc_component *component, pullup_mask, 0x00); break; case MICB_ENABLE: + if (!rouleur->dev_up) { + dev_dbg(component->dev, "%s: enable req %d wcd device down\n", + __func__, req); + ret = -ENODEV; + goto done; + } rouleur->micb_ref[micb_index]++; if (rouleur->micb_ref[micb_index] == 1) { rouleur_global_mbias_enable(component); - snd_soc_component_update_bits(component, micb_reg, - 0x80, 0x80); snd_soc_component_update_bits(component, micb_reg, enable_mask, enable_mask); if (post_on_event) @@ -1236,16 +1253,27 @@ int rouleur_micbias_control(struct snd_soc_component *component, case MICB_DISABLE: if (rouleur->micb_ref[micb_index] > 0) rouleur->micb_ref[micb_index]--; + if (!rouleur->dev_up) { + dev_dbg(component->dev, "%s: enable req %d wcd device down\n", + __func__, req); + ret = -ENODEV; + goto done; + } if ((rouleur->micb_ref[micb_index] == 0) && - (rouleur->pullup_ref[micb_index] == 0)) { + (rouleur->pullup_ref[micb_index] > 0)) { + snd_soc_component_update_bits(component, micb_reg, + pullup_mask, pullup_mask); + snd_soc_component_update_bits(component, micb_reg, + enable_mask, 0x00); + rouleur_global_mbias_disable(component); + } else if ((rouleur->micb_ref[micb_index] == 0) && + (rouleur->pullup_ref[micb_index] == 0)) { if (pre_off_event && rouleur->mbhc) blocking_notifier_call_chain( &rouleur->mbhc->notifier, pre_off_event, &rouleur->mbhc->wcd_mbhc); snd_soc_component_update_bits(component, micb_reg, enable_mask, 0x00); - snd_soc_component_update_bits(component, micb_reg, - 0x80, 0x00); rouleur_global_mbias_disable(component); if (post_off_event && rouleur->mbhc) blocking_notifier_call_chain( @@ -1263,8 +1291,8 @@ int rouleur_micbias_control(struct snd_soc_component *component, dev_dbg(component->dev, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", __func__, micb_num, rouleur->micb_ref[micb_index], rouleur->pullup_ref[micb_index]); +done: mutex_unlock(&rouleur->micb_lock); - return 0; } EXPORT_SYMBOL(rouleur_micbias_control); @@ -1333,6 +1361,7 @@ static int rouleur_event_notify(struct notifier_block *block, 0x80, 0x00); break; case BOLERO_WCD_EVT_SSR_DOWN: + rouleur->dev_up = false; rouleur->mbhc->wcd_mbhc.deinit_in_progress = true; mbhc = &rouleur->mbhc->wcd_mbhc; rouleur_mbhc_ssr_down(rouleur->mbhc, component); @@ -1358,6 +1387,7 @@ static int rouleur_event_notify(struct notifier_block *block, rouleur_mbhc_hs_detect(component, mbhc->mbhc_cfg); } rouleur->mbhc->wcd_mbhc.deinit_in_progress = false; + rouleur->dev_up = true; break; default: dev_err(component->dev, "%s: invalid event %d\n", __func__, @@ -1986,6 +2016,7 @@ static int rouleur_soc_codec_probe(struct snd_soc_component *component) return ret; } } + rouleur->dev_up = true; done: return ret; } diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index f961230758aa..52585ac2b3ac 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -33,16 +33,20 @@ static int wcd_mbhc_get_micbias(struct wcd_mbhc *mbhc) int micbias = 0; u8 vout_ctl = 0; - /* Read MBHC Micbias (Mic Bias2) voltage */ - WCD_MBHC_REG_READ(WCD_MBHC_MICB2_VOUT, vout_ctl); - - /* Formula for getting micbias from vout - * micbias = 1.0V + VOUT_CTL * 50mV - */ - micbias = 1000 + (vout_ctl * 50); - pr_debug("%s: vout_ctl: %d, micbias: %d\n", - __func__, vout_ctl, micbias); + if (mbhc->mbhc_cb->get_micbias_val) { + mbhc->mbhc_cb->get_micbias_val(mbhc, &micbias); + pr_debug("%s: micbias: %d\n", __func__, micbias); + } else { + /* Read MBHC Micbias (Mic Bias2) voltage */ + WCD_MBHC_REG_READ(WCD_MBHC_MICB2_VOUT, vout_ctl); + /* Formula for getting micbias from vout + * micbias = 1.0V + VOUT_CTL * 50mV + */ + micbias = 1000 + (vout_ctl * 50); + pr_debug("%s: vout_ctl: %d, micbias: %d\n", + __func__, vout_ctl, micbias); + } return micbias; } diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 3692ed7ba0a6..9a2178aec9ca 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -77,11 +77,17 @@ static void wcd_program_hs_vref(struct wcd_mbhc *mbhc) struct snd_soc_component *component = mbhc->component; u32 reg_val; - plug_type_cfg = WCD_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration); - reg_val = ((plug_type_cfg->v_hs_max - HS_VREF_MIN_VAL) / 100); + if (mbhc->mbhc_cb->hs_vref_max_update) { + mbhc->mbhc_cb->hs_vref_max_update(mbhc); + } else { + plug_type_cfg = WCD_MBHC_CAL_PLUG_TYPE_PTR( + mbhc->mbhc_cfg->calibration); + reg_val = ((plug_type_cfg->v_hs_max - HS_VREF_MIN_VAL) / 100); - dev_dbg(component->dev, "%s: reg_val = %x\n", __func__, reg_val); - WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_VREF, reg_val); + dev_dbg(component->dev, "%s: reg_val = %x\n", + __func__, reg_val); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_VREF, reg_val); + } } static void wcd_program_btn_threshold(const struct wcd_mbhc *mbhc, bool micbias) @@ -967,6 +973,14 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) mbhc->mbhc_cb->enable_mb_source(mbhc, true); mbhc->btn_press_intr = false; mbhc->is_btn_press = false; + /* + * When current source mode doesn't work properly + * use mic bias pull up mode for button interrupts + * to function properly + */ + if (mbhc->mbhc_cb->mbhc_micb_pullup_control) + mbhc->mbhc_cb->mbhc_micb_pullup_control(component, + true); if (mbhc->mbhc_fn) mbhc->mbhc_fn->wcd_mbhc_detect_plug_type(mbhc); } else if ((mbhc->current_plug != MBHC_PLUG_TYPE_NONE) @@ -1041,6 +1055,10 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) false); } + if (mbhc->mbhc_cb->mbhc_micb_pullup_control) + mbhc->mbhc_cb->mbhc_micb_pullup_control(component, + false); + } else if (!detection_type) { /* Disable external voltage source to micbias if present */ if (mbhc->mbhc_cb->enable_mb_source) diff --git a/include/asoc/wcd-mbhc-v2.h b/include/asoc/wcd-mbhc-v2.h index f3ee72824380..774542a59ddb 100644 --- a/include/asoc/wcd-mbhc-v2.h +++ b/include/asoc/wcd-mbhc-v2.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. */ #ifndef __WCD_MBHC_V2_H__ #define __WCD_MBHC_V2_H__ @@ -451,6 +451,12 @@ struct wcd_mbhc_register { }; struct wcd_mbhc_cb { + void (*mbhc_micb_pullup_control) + (struct snd_soc_component *component, bool enable); + void (*get_micbias_val) + (struct wcd_mbhc *mbhc, int *mb); + void (*hs_vref_max_update) + (struct wcd_mbhc *mbhc); void (*bcs_enable) (struct wcd_mbhc *mbhc, bool bcs_enable); int (*enable_mb_source)(struct wcd_mbhc *mbhc, bool turn_on); -- GitLab From 9f892d810bb78a18f9a57ca747c17ae9e3413525 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 29 Apr 2020 20:40:53 +0530 Subject: [PATCH 1479/1645] asoc: Add a separate mbhc config for rouleur codec As rouleur codec supports only 5 buttons and headset vref max value is 1.7V, use a separate mbhc config structure to initizlize mbhc. Change-Id: Icd78d8c10f3d4dd3585c76c407d2d323c20cbe3f Signed-off-by: Aditya Bavanari --- asoc/bengal.c | 54 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/asoc/bengal.c b/asoc/bengal.c index ec73cc9d6d40..7627516ef0bd 100644 --- a/asoc/bengal.c +++ b/asoc/bengal.c @@ -59,10 +59,12 @@ #define WCD9XXX_MBHC_DEF_RLOADS 5 #define WCD9XXX_MBHC_DEF_BUTTONS 8 +#define ROULEUR_MBHC_DEF_BUTTONS 5 #define CODEC_EXT_CLK_RATE 9600000 #define ADSP_STATE_READY_TIMEOUT_MS 3000 #define DEV_NAME_STR_LEN 32 #define WCD_MBHC_HS_V_MAX 1600 +#define ROULEUR_MBHC_HS_V_MAX 1700 #define TDM_CHANNEL_MAX 8 #define DEV_NAME_STR_LEN 32 @@ -555,6 +557,7 @@ static int dmic_0_1_gpio_cnt; static int dmic_2_3_gpio_cnt; static void *def_wcd_mbhc_cal(void); +static void *def_rouleur_mbhc_cal(void); /* * Need to report LINEIN @@ -4311,6 +4314,34 @@ static void *def_wcd_mbhc_cal(void) return wcd_mbhc_cal; } +static void *def_rouleur_mbhc_cal(void) +{ + void *wcd_mbhc_cal; + struct wcd_mbhc_btn_detect_cfg *btn_cfg; + u16 *btn_high; + + wcd_mbhc_cal = kzalloc(WCD_MBHC_CAL_SIZE(ROULEUR_MBHC_DEF_BUTTONS, + WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); + if (!wcd_mbhc_cal) + return NULL; + + WCD_MBHC_CAL_PLUG_TYPE_PTR(wcd_mbhc_cal)->v_hs_max = + ROULEUR_MBHC_HS_V_MAX; + WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal)->num_btn = + ROULEUR_MBHC_DEF_BUTTONS; + btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal); + btn_high = ((void *)&btn_cfg->_v_btn_low) + + (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); + + btn_high[0] = 75; + btn_high[1] = 150; + btn_high[2] = 237; + btn_high[3] = 500; + btn_high[4] = 500; + + return wcd_mbhc_cal; +} + /* Digital audio interface glue - connects codec <---> CPU */ static struct snd_soc_dai_link msm_common_dai_links[] = { /* FrontEnd DAI Links */ @@ -6083,16 +6114,21 @@ static int msm_aux_codec_init(struct snd_soc_component *component) } mbhc_cfg_cal: - mbhc_calibration = def_wcd_mbhc_cal(); - if (!mbhc_calibration) - return -ENOMEM; - wcd_mbhc_cfg.calibration = mbhc_calibration; if (data != NULL) { - if (!strncmp(data, "wcd937x", sizeof("wcd937x"))) - ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg); - else if (!strncmp( data, "rouleur", sizeof("rouleur"))) - ret = rouleur_mbhc_hs_detect(component, &wcd_mbhc_cfg); - } + if (!strncmp(data, "wcd937x", sizeof("wcd937x"))) { + mbhc_calibration = def_wcd_mbhc_cal(); + if (!mbhc_calibration) + return -ENOMEM; + wcd_mbhc_cfg.calibration = mbhc_calibration; + ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg); + } else if (!strncmp( data, "rouleur", sizeof("rouleur"))) { + mbhc_calibration = def_rouleur_mbhc_cal(); + if (!mbhc_calibration) + return -ENOMEM; + wcd_mbhc_cfg.calibration = mbhc_calibration; + ret = rouleur_mbhc_hs_detect(component, &wcd_mbhc_cfg); + } + } if (ret) { dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n", -- GitLab From bc657256ecba41d4e9981dd672b8aa57505eb253 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Fri, 10 Apr 2020 16:38:29 +0530 Subject: [PATCH 1480/1645] asoc: codecs: Update rouleur watchdog interrupt sequence Update PDM watchdog interrupt sequence for rouleur codec. Add HPH PA gain registers in regmap and update defaults. Update mic bias register bits and rouleur version for ADIE RTC to work. Change-Id: I1bbb41efcdd9a0a8b38fcd4beadbd5d639a4b858 Signed-off-by: Aditya Bavanari --- asoc/codecs/rouleur/rouleur-mbhc.c | 2 +- asoc/codecs/rouleur/rouleur-regmap.c | 2 + asoc/codecs/rouleur/rouleur-tables.c | 2 + asoc/codecs/rouleur/rouleur.c | 73 +++++++++++----------------- 4 files changed, 33 insertions(+), 46 deletions(-) diff --git a/asoc/codecs/rouleur/rouleur-mbhc.c b/asoc/codecs/rouleur/rouleur-mbhc.c index 91ddc104acef..caf6d4a04fc8 100644 --- a/asoc/codecs/rouleur/rouleur-mbhc.c +++ b/asoc/codecs/rouleur/rouleur-mbhc.c @@ -88,7 +88,7 @@ static struct wcd_mbhc_register WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT", ROULEUR_ANA_MBHC_RESULT_3, 0xFF, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL", - ROULEUR_ANA_MICBIAS_MICB_1_2_EN, 0x04, 2, 0), + ROULEUR_ANA_MICBIAS_MICB_1_2_EN, 0x06, 1, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME", SND_SOC_NOPM, 0x00, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN", diff --git a/asoc/codecs/rouleur/rouleur-regmap.c b/asoc/codecs/rouleur/rouleur-regmap.c index 71e5e1901f54..08b490db3a5f 100644 --- a/asoc/codecs/rouleur/rouleur-regmap.c +++ b/asoc/codecs/rouleur/rouleur-regmap.c @@ -45,6 +45,8 @@ static const struct reg_default rouleur_defaults[] = { { ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x2B }, { ROULEUR_ANA_HPHPA_PA_STATUS, 0x00 }, { ROULEUR_ANA_HPHPA_FSM_CLK, 0x12 }, + { ROULEUR_ANA_HPHPA_L_GAIN, 0x00 }, + { ROULEUR_ANA_HPHPA_R_GAIN, 0x00 }, { ROULEUR_SWR_HPHPA_HD2, 0x1B }, { ROULEUR_ANA_HPHPA_SPARE_CTL, 0x02 }, { ROULEUR_ANA_SURGE_EN, 0x38 }, diff --git a/asoc/codecs/rouleur/rouleur-tables.c b/asoc/codecs/rouleur/rouleur-tables.c index ba2fa9a40a79..59b7cf2d3383 100644 --- a/asoc/codecs/rouleur/rouleur-tables.c +++ b/asoc/codecs/rouleur/rouleur-tables.c @@ -40,6 +40,8 @@ const u8 rouleur_reg_access_analog[ROULEUR_REG( [ROULEUR_REG(ROULEUR_ANA_HPHPA_CNP_CTL_2)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_HPHPA_PA_STATUS)] = RD_REG, [ROULEUR_REG(ROULEUR_ANA_HPHPA_FSM_CLK)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_HPHPA_L_GAIN)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_HPHPA_R_GAIN)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_HPHPA_SPARE_CTL)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_SWR_HPHPA_HD2)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_SURGE_EN)] = RD_WR_REG, diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index d028ed48b58f..3f039c4082d8 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -475,14 +475,8 @@ static int rouleur_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, 0x04, 0x04); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x01, 0x01); - snd_soc_component_update_bits(component, - ROULEUR_DIG_SWR_PDM_WD_CTL0, - 0x03, 0x03); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_component_update_bits(component, - ROULEUR_DIG_SWR_PDM_WD_CTL0, - 0x03, 0x00); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x01, 0x00); @@ -546,14 +540,8 @@ static int rouleur_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, 0x08, 0x08); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x02, 0x02); - snd_soc_component_update_bits(component, - ROULEUR_DIG_SWR_PDM_WD_CTL1, - 0x03, 0x03); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_component_update_bits(component, - ROULEUR_DIG_SWR_PDM_WD_CTL1, - 0x03, 0x00); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x02, 0x00); break; @@ -582,18 +570,12 @@ static int rouleur_codec_ear_lo_dac_event(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x01, 0x01); - snd_soc_component_update_bits(component, - ROULEUR_DIG_SWR_PDM_WD_CTL0, - 0x03, 0x03); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, 0x04, 0x04); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_component_update_bits(component, - ROULEUR_DIG_SWR_PDM_WD_CTL0, - 0x03, 0x00); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x01, 0x00); @@ -622,14 +604,11 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, rouleur->rx_swr_dev->dev_num, true); - snd_soc_component_update_bits(component, - ROULEUR_ANA_HPHPA_CNP_CTL_2, - 0x40, 0x40); set_bit(HPH_PA_DELAY, &rouleur->status_mask); - /* TODO: WHY SECOND TIME */ - ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev, - rouleur->rx_swr_dev->dev_num, - true); + usleep_range(5000, 5100); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_PDM_WD_CTL1, + 0x03, 0x03); break; case SND_SOC_DAPM_POST_PMU: /* @@ -676,8 +655,8 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, WCD_EVENT_POST_HPHR_PA_OFF, &rouleur->mbhc->wcd_mbhc); snd_soc_component_update_bits(component, - ROULEUR_ANA_HPHPA_CNP_CTL_2, - 0x40, 0x00); + ROULEUR_DIG_SWR_PDM_WD_CTL1, + 0x03, 0x00); break; }; return ret; @@ -700,10 +679,11 @@ static int rouleur_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev, rouleur->rx_swr_dev->dev_num, true); - snd_soc_component_update_bits(component, - ROULEUR_ANA_HPHPA_CNP_CTL_2, - 0x80, 0x80); set_bit(HPH_PA_DELAY, &rouleur->status_mask); + usleep_range(5000, 5100); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_PDM_WD_CTL0, + 0x03, 0x03); break; case SND_SOC_DAPM_POST_PMU: /* @@ -748,8 +728,8 @@ static int rouleur_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, WCD_EVENT_POST_HPHL_PA_OFF, &rouleur->mbhc->wcd_mbhc); snd_soc_component_update_bits(component, - ROULEUR_ANA_HPHPA_CNP_CTL_2, - 0x80, 0x00); + ROULEUR_DIG_SWR_PDM_WD_CTL0, + 0x03, 0x00); break; }; @@ -773,10 +753,10 @@ static int rouleur_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev, rouleur->rx_swr_dev->dev_num, true); - snd_soc_component_update_bits(component, - ROULEUR_ANA_COMBOPA_CTL, - 0x80, 0x80); usleep_range(5000, 5100); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_PDM_WD_CTL0, + 0x03, 0x03); break; case SND_SOC_DAPM_POST_PMU: if (rouleur->update_wcd_event) @@ -795,10 +775,10 @@ static int rouleur_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, (WCD_RX1 << 0x10 | 0x1)); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_component_update_bits(component, - ROULEUR_ANA_COMBOPA_CTL, - 0x80, 0x00); usleep_range(5000, 5100); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_PDM_WD_CTL0, + 0x03, 0x00); }; return ret; } @@ -823,10 +803,10 @@ static int rouleur_codec_enable_lo_pa(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, ROULEUR_ANA_COMBOPA_CTL, 0x40, 0x40); - snd_soc_component_update_bits(component, - ROULEUR_ANA_COMBOPA_CTL, - 0x80, 0x80); usleep_range(5000, 5100); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_PDM_WD_CTL0, + 0x03, 0x03); break; case SND_SOC_DAPM_POST_PMU: if (rouleur->update_wcd_event) @@ -845,13 +825,13 @@ static int rouleur_codec_enable_lo_pa(struct snd_soc_dapm_widget *w, (WCD_RX1 << 0x10 | 0x1)); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_component_update_bits(component, - ROULEUR_ANA_COMBOPA_CTL, - 0x80, 0x00); snd_soc_component_update_bits(component, ROULEUR_ANA_COMBOPA_CTL, 0x40, 0x00); usleep_range(5000, 5100); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_PDM_WD_CTL0, + 0x03, 0x00); }; return ret; } @@ -1552,6 +1532,9 @@ static int rouleur_codec_enable_pa_vpos(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: set_bit(ALLOW_VPOS_DISABLE, &rouleur->status_mask); + ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev, + rouleur->rx_swr_dev->dev_num, + false); break; } return 0; @@ -1822,7 +1805,7 @@ static ssize_t rouleur_version_read(struct snd_info_entry *entry, switch (priv->version) { case ROULEUR_VERSION_1_0: - len = snprintf(buffer, sizeof(buffer), "rouleur_1_0\n"); + len = snprintf(buffer, sizeof(buffer), "ROULEUR_1_0\n"); break; default: len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); -- GitLab From a2675b64067e1ede554cdc83d7858dd6113962c0 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 29 Apr 2020 20:43:53 +0530 Subject: [PATCH 1481/1645] asoc: codecs: Add comparator autozeroing support for rouleur When current source mode is enabled, comparator auto zeroing should be turned ON by HW. As rouleur codec HW doesn't do this automatically, add this support in SW to set the auto zero enable before FSM enable and reset to auto once FSM is enabled. Disable surge protection before ADC measurements and change HPHL and HPHR thresholds while identifying cross connection for proper accessory identification. Change-Id: Ib775de0f0bdb6c655a3c0eb4775276acfbca1e84 Signed-off-by: Aditya Bavanari --- asoc/codecs/rouleur/rouleur-mbhc.c | 59 +++++++++++++++++++----------- asoc/codecs/rouleur/rouleur.c | 36 ++++++++++++++---- asoc/codecs/wcd-mbhc-adc.c | 29 ++++++++++++++- asoc/codecs/wcd-mbhc-v2.c | 30 ++++----------- include/asoc/wcd-mbhc-v2.h | 14 +++++-- 5 files changed, 112 insertions(+), 56 deletions(-) diff --git a/asoc/codecs/rouleur/rouleur-mbhc.c b/asoc/codecs/rouleur/rouleur-mbhc.c index 78bef6a8ed09..2f8e954b5a23 100644 --- a/asoc/codecs/rouleur/rouleur-mbhc.c +++ b/asoc/codecs/rouleur/rouleur-mbhc.c @@ -37,6 +37,10 @@ #define ROULEUR_MBHC_ZDET_CONST (86 * 16384) #define ROULEUR_MBHC_MOISTURE_RREF R_24_KOHM +/* Cross connection thresholds in mV */ +#define ROULEUR_HPHL_CROSS_CONN_THRESHOLD 200 +#define ROULEUR_HPHR_CROSS_CONN_THRESHOLD 200 + static struct wcd_mbhc_register wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = { WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN", @@ -320,11 +324,11 @@ static void rouleur_mbhc_micb_ramp_control(struct snd_soc_component *component, 0x1C, 0x0C); snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_MICB2_RAMP, - 0xA0, 0x80); + 0x80, 0x80); } else { snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_MICB2_RAMP, - 0xA0, 0x00); + 0x80, 0x00); snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_MICB2_RAMP, 0x1C, 0x00); @@ -820,15 +824,6 @@ static void rouleur_mbhc_bcs_enable(struct wcd_mbhc *mbhc, rouleur_disable_bcs_before_slow_insert(mbhc->component, true); } -static void rouleur_mbhc_hs_vref_max_update(struct wcd_mbhc *mbhc) -{ - struct snd_soc_component *component = mbhc->component; - - /* Update the HS Vref max voltage to 1.7V */ - snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_CTL_2, - 0x03, 0x03); -} - static void rouleur_mbhc_get_micbias_val(struct wcd_mbhc *mbhc, int *mb) { u8 vout_ctl = 0; @@ -843,17 +838,38 @@ static void rouleur_mbhc_get_micbias_val(struct wcd_mbhc *mbhc, int *mb) pr_debug("%s: vout_ctl: %d, micbias: %d\n", __func__, vout_ctl, *mb); } -static void rouleur_mbhc_micb_pullup_control( - struct snd_soc_component *component, - bool pullup_enable) +static void rouleur_mbhc_comp_autozero_control(struct wcd_mbhc *mbhc, + bool az_enable) { - if (pullup_enable) - rouleur_micbias_control(component, MIC_BIAS_2, - MICB_PULLUP_ENABLE, false); + if (az_enable) + snd_soc_component_update_bits(mbhc->component, + ROULEUR_ANA_MBHC_MCLK, 0x08, 0x08); else - rouleur_micbias_control(component, MIC_BIAS_2, - MICB_PULLUP_DISABLE, false); + snd_soc_component_update_bits(mbhc->component, + ROULEUR_ANA_MBHC_MCLK, 0x08, 0x00); + +} + +static void rouleur_mbhc_surge_control(struct wcd_mbhc *mbhc, + bool surge_enable) +{ + if (surge_enable) + snd_soc_component_update_bits(mbhc->component, + ROULEUR_ANA_SURGE_EN, 0xC0, 0xC0); + else + snd_soc_component_update_bits(mbhc->component, + ROULEUR_ANA_SURGE_EN, 0xC0, 0x00); + +} + +static void rouleur_mbhc_update_cross_conn_thr(struct wcd_mbhc *mbhc) +{ + mbhc->hphl_cross_conn_thr = ROULEUR_HPHL_CROSS_CONN_THRESHOLD; + mbhc->hphr_cross_conn_thr = ROULEUR_HPHR_CROSS_CONN_THRESHOLD; + pr_debug("%s: Cross connection threshold for hphl: %d, hphr: %d\n", + __func__, mbhc->hphl_cross_conn_thr, + mbhc->hphr_cross_conn_thr); } static const struct wcd_mbhc_cb mbhc_cb = { @@ -880,9 +896,10 @@ static const struct wcd_mbhc_cb mbhc_cb = { .mbhc_get_moisture_status = rouleur_mbhc_get_moisture_status, .mbhc_moisture_detect_en = rouleur_mbhc_moisture_detect_en, .bcs_enable = rouleur_mbhc_bcs_enable, - .hs_vref_max_update = rouleur_mbhc_hs_vref_max_update, .get_micbias_val = rouleur_mbhc_get_micbias_val, - .mbhc_micb_pullup_control = rouleur_mbhc_micb_pullup_control, + .mbhc_comp_autozero_control = rouleur_mbhc_comp_autozero_control, + .mbhc_surge_ctl = rouleur_mbhc_surge_control, + .update_cross_conn_thr = rouleur_mbhc_update_cross_conn_thr, }; static int rouleur_get_hph_type(struct snd_kcontrol *kcontrol, diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index cdb1de2c6996..e1ecdba83f3b 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -107,6 +107,9 @@ static int rouleur_handle_post_irq(void *data) static int rouleur_init_reg(struct snd_soc_component *component) { + /* Disable HPH OCP */ + snd_soc_component_update_bits(component, ROULEUR_ANA_HPHPA_CNP_CTL_2, + 0x03, 0x00); /* Enable surge protection */ snd_soc_component_update_bits(component, ROULEUR_ANA_SURGE_EN, 0xC0, 0xC0); @@ -354,7 +357,7 @@ static int rouleur_rx_clk_enable(struct snd_soc_component *component) usleep_range(5000, 5100); rouleur_global_mbias_enable(component); snd_soc_component_update_bits(component, - ROULEUR_ANA_HPHPA_FSM_CLK, 0x11, 0x11); + ROULEUR_ANA_HPHPA_FSM_CLK, 0x7F, 0x11); snd_soc_component_update_bits(component, ROULEUR_ANA_HPHPA_FSM_CLK, 0x80, 0x80); snd_soc_component_update_bits(component, @@ -382,14 +385,14 @@ static int rouleur_rx_clk_disable(struct snd_soc_component *component) snd_soc_component_update_bits(component, ROULEUR_ANA_HPHPA_FSM_CLK, 0x80, 0x00); snd_soc_component_update_bits(component, - ROULEUR_ANA_HPHPA_FSM_CLK, 0x11, 0x00); + ROULEUR_ANA_HPHPA_FSM_CLK, 0x7F, 0x00); snd_soc_component_update_bits(component, ROULEUR_ANA_NCP_EN, 0x01, 0x00); - rouleur_global_mbias_disable(component); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x20, 0x00); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x10, 0x00); + rouleur_global_mbias_disable(component); } mutex_unlock(&rouleur->rx_clk_lock); @@ -478,8 +481,15 @@ static int rouleur_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: snd_soc_component_update_bits(component, - ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, - 0x01, 0x00); + ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, + 0x01, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, + 0x04, 0x00); + if (rouleur->comp1_enable) + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_COMP_CTL_0, + 0x02, 0x00); break; } @@ -544,6 +554,13 @@ static int rouleur_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMD: snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x02, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, + 0x08, 0x00); + if (rouleur->comp2_enable) + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_COMP_CTL_0, + 0x01, 0x00); break; } @@ -567,18 +584,21 @@ static int rouleur_codec_ear_lo_dac_event(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX0_CTL, 0x7C, 0x7C); - snd_soc_component_update_bits(component, - ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, - 0x01, 0x01); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, 0x04, 0x04); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, + 0x01, 0x01); break; case SND_SOC_DAPM_POST_PMD: snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x01, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, + 0x04, 0x00); break; }; diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index 52585ac2b3ac..bfb32d121e4b 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -80,8 +80,22 @@ static int wcd_measure_adc_continuous(struct wcd_mbhc *mbhc) WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); /* Set the MUX selection to IN2P */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MUX_CTL, MUX_CTL_IN2P); + + /* + * Current source mode requires Auto zeroing to be enabled + * automatically. If HW doesn't do it, SW has to take care of this + * for button interrupts to work fine and to avoid + * fake electrical removal interrupts by enabling autozero before FSM + * enable and disable it after FSM enable + */ + if (mbhc->mbhc_cb->mbhc_comp_autozero_control) + mbhc->mbhc_cb->mbhc_comp_autozero_control(mbhc, + true); /* Enable MBHC FSM */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); + if (mbhc->mbhc_cb->mbhc_comp_autozero_control) + mbhc->mbhc_cb->mbhc_comp_autozero_control(mbhc, + false); /* Enable ADC_ENABLE bit */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 1); @@ -294,6 +308,10 @@ static int wcd_check_cross_conn(struct wcd_mbhc *mbhc) WCD_MBHC_REG_READ(WCD_MBHC_ELECT_SCHMT_ISRC, elect_ctl); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0x00); + /* Disable surge detection before ADC measurement */ + if (mbhc->mbhc_cb->mbhc_surge_ctl) + mbhc->mbhc_cb->mbhc_surge_ctl(mbhc, false); + /* Read and set ADC to single measurement */ WCD_MBHC_REG_READ(WCD_MBHC_ADC_MODE, adc_mode); /* Read ADC Enable bit to restore after adc measurement */ @@ -317,7 +335,12 @@ static int wcd_check_cross_conn(struct wcd_mbhc *mbhc) goto done; } - if (hphl_adc_res > 100 || hphr_adc_res > 100) { + /* Update cross connection threshold voltages if needed */ + if (mbhc->mbhc_cb->update_cross_conn_thr) + mbhc->mbhc_cb->update_cross_conn_thr(mbhc); + + if (hphl_adc_res > mbhc->hphl_cross_conn_thr || + hphr_adc_res > mbhc->hphr_cross_conn_thr) { plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; pr_debug("%s: Cross connection identified\n", __func__); } else { @@ -339,6 +362,10 @@ static int wcd_check_cross_conn(struct wcd_mbhc *mbhc) /* Restore FSM state */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, fsm_en); + /* Restore surge detection */ + if (mbhc->mbhc_cb->mbhc_surge_ctl) + mbhc->mbhc_cb->mbhc_surge_ctl(mbhc, true); + /* Restore electrical detection */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, elect_ctl); diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index 9a2178aec9ca..ee24ea63a031 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -77,17 +77,13 @@ static void wcd_program_hs_vref(struct wcd_mbhc *mbhc) struct snd_soc_component *component = mbhc->component; u32 reg_val; - if (mbhc->mbhc_cb->hs_vref_max_update) { - mbhc->mbhc_cb->hs_vref_max_update(mbhc); - } else { - plug_type_cfg = WCD_MBHC_CAL_PLUG_TYPE_PTR( - mbhc->mbhc_cfg->calibration); - reg_val = ((plug_type_cfg->v_hs_max - HS_VREF_MIN_VAL) / 100); + plug_type_cfg = WCD_MBHC_CAL_PLUG_TYPE_PTR( + mbhc->mbhc_cfg->calibration); + reg_val = ((plug_type_cfg->v_hs_max - HS_VREF_MIN_VAL) / 100); - dev_dbg(component->dev, "%s: reg_val = %x\n", - __func__, reg_val); - WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_VREF, reg_val); - } + dev_dbg(component->dev, "%s: reg_val = %x\n", + __func__, reg_val); + WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_VREF, reg_val); } static void wcd_program_btn_threshold(const struct wcd_mbhc *mbhc, bool micbias) @@ -973,14 +969,6 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) mbhc->mbhc_cb->enable_mb_source(mbhc, true); mbhc->btn_press_intr = false; mbhc->is_btn_press = false; - /* - * When current source mode doesn't work properly - * use mic bias pull up mode for button interrupts - * to function properly - */ - if (mbhc->mbhc_cb->mbhc_micb_pullup_control) - mbhc->mbhc_cb->mbhc_micb_pullup_control(component, - true); if (mbhc->mbhc_fn) mbhc->mbhc_fn->wcd_mbhc_detect_plug_type(mbhc); } else if ((mbhc->current_plug != MBHC_PLUG_TYPE_NONE) @@ -1055,10 +1043,6 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) false); } - if (mbhc->mbhc_cb->mbhc_micb_pullup_control) - mbhc->mbhc_cb->mbhc_micb_pullup_control(component, - false); - } else if (!detection_type) { /* Disable external voltage source to micbias if present */ if (mbhc->mbhc_cb->enable_mb_source) @@ -1815,6 +1799,8 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_component *component, mbhc->hph_type = WCD_MBHC_HPH_NONE; mbhc->wcd_mbhc_regs = wcd_mbhc_regs; mbhc->swap_thr = GND_MIC_SWAP_THRESHOLD; + mbhc->hphl_cross_conn_thr = HPHL_CROSS_CONN_THRESHOLD; + mbhc->hphr_cross_conn_thr = HPHR_CROSS_CONN_THRESHOLD; if (mbhc->intr_ids == NULL) { pr_err("%s: Interrupt mapping not provided\n", __func__); diff --git a/include/asoc/wcd-mbhc-v2.h b/include/asoc/wcd-mbhc-v2.h index 774542a59ddb..193414138711 100644 --- a/include/asoc/wcd-mbhc-v2.h +++ b/include/asoc/wcd-mbhc-v2.h @@ -140,6 +140,8 @@ do { \ #define FW_READ_ATTEMPTS 15 #define FW_READ_TIMEOUT 4000000 #define FAKE_REM_RETRY_ATTEMPTS 3 +#define HPHL_CROSS_CONN_THRESHOLD 100 +#define HPHR_CROSS_CONN_THRESHOLD 100 #define WCD_MBHC_BTN_PRESS_COMPL_TIMEOUT_MS 50 #define ANC_DETECT_RETRY_CNT 7 @@ -451,12 +453,14 @@ struct wcd_mbhc_register { }; struct wcd_mbhc_cb { - void (*mbhc_micb_pullup_control) - (struct snd_soc_component *component, bool enable); + void (*update_cross_conn_thr) + (struct wcd_mbhc *mbhc); + void (*mbhc_surge_ctl) + (struct wcd_mbhc *mbhc, bool surge_en); + void (*mbhc_comp_autozero_control) + (struct wcd_mbhc *mbhc, bool az_enable); void (*get_micbias_val) (struct wcd_mbhc *mbhc, int *mb); - void (*hs_vref_max_update) - (struct wcd_mbhc *mbhc); void (*bcs_enable) (struct wcd_mbhc *mbhc, bool bcs_enable); int (*enable_mb_source)(struct wcd_mbhc *mbhc, bool turn_on); @@ -552,6 +556,8 @@ struct wcd_mbhc { u32 moist_vref; u32 moist_iref; u32 moist_rref; + u32 hphl_cross_conn_thr; + u32 hphr_cross_conn_thr; u8 micbias1_cap_mode; /* track ext cap setting */ u8 micbias2_cap_mode; /* track ext cap setting */ bool hs_detect_work_stop; -- GitLab From 80581c4b4f57e7c140c04db4c7b73df166aba7f4 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 14 Apr 2020 18:10:28 +0530 Subject: [PATCH 1482/1645] asoc: bolero: Update rx dc droop register setting For RX DC droop setting, ensure update proper value during powerup/powerdown based on sample rate. Change-Id: I269d41452911e1999b2dbdf4fa22e383aa973848 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 70b012682b6d..22d636e84c58 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1687,13 +1687,6 @@ static int rx_macro_config_compander(struct snd_soc_component *component, dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n", __func__, event, comp + 1, rx_priv->comp_enabled[comp]); - if (!rx_priv->comp_enabled[comp]) - return 0; - - comp_ctl0_reg = BOLERO_CDC_RX_COMPANDER0_CTL0 + - (comp * RX_MACRO_COMP_OFFSET); - rx_path_cfg0_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0 + - (comp * RX_MACRO_RX_PATH_OFFSET); rx_path_cfg3_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG3 + (comp * RX_MACRO_RX_PATH_OFFSET); rx0_path_ctl_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + @@ -1709,6 +1702,19 @@ static int rx_macro_config_compander(struct snd_soc_component *component, else val = 0x00; + if (SND_SOC_DAPM_EVENT_ON(event)) + snd_soc_component_update_bits(component, rx_path_cfg3_reg, + 0x03, val); + if (SND_SOC_DAPM_EVENT_OFF(event)) + snd_soc_component_update_bits(component, rx_path_cfg3_reg, + 0x03, 0x03); + if (!rx_priv->comp_enabled[comp]) + return 0; + + comp_ctl0_reg = BOLERO_CDC_RX_COMPANDER0_CTL0 + + (comp * RX_MACRO_COMP_OFFSET); + rx_path_cfg0_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0 + + (comp * RX_MACRO_RX_PATH_OFFSET); if (SND_SOC_DAPM_EVENT_ON(event)) { /* Enable Compander Clock */ snd_soc_component_update_bits(component, comp_ctl0_reg, @@ -1719,8 +1725,6 @@ static int rx_macro_config_compander(struct snd_soc_component *component, 0x02, 0x00); snd_soc_component_update_bits(component, rx_path_cfg0_reg, 0x02, 0x02); - snd_soc_component_update_bits(component, rx_path_cfg3_reg, - 0x03, val); } if (SND_SOC_DAPM_EVENT_OFF(event)) { @@ -1732,8 +1736,6 @@ static int rx_macro_config_compander(struct snd_soc_component *component, 0x01, 0x00); snd_soc_component_update_bits(component, comp_ctl0_reg, 0x04, 0x00); - snd_soc_component_update_bits(component, rx_path_cfg3_reg, - 0x03, 0x03); } return 0; -- GitLab From 007d252f509ca8db426cd18adbe5b6063d2151fe Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 23 Apr 2020 11:00:44 +0530 Subject: [PATCH 1483/1645] asoc: wsa-macro: Update VI sense setting based on pcm rate Retrieve sample rate for VI sense and update codec settings based on it. Change-Id: If4341bac77ecae290c44c4412a39b9e5cbf46ac0 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/wsa-macro.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 2ab2e8af413e..1bc8f9d2a1f3 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -241,6 +241,7 @@ struct wsa_macro_priv { struct wsa_macro_bcl_pmic_params bcl_pmic_params; char __iomem *mclk_mode_muxsel; u16 default_clk_id; + u32 pcm_rate_vi; int wsa_digital_mute_status[WSA_MACRO_RX_MAX]; }; @@ -747,6 +748,15 @@ static int wsa_macro_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_component *component = dai->component; int ret; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + wsa_priv = dev_get_drvdata(wsa_dev); + if (!wsa_priv) + return -EINVAL; dev_dbg(component->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__, @@ -764,6 +774,8 @@ static int wsa_macro_hw_params(struct snd_pcm_substream *substream, } break; case SNDRV_PCM_STREAM_CAPTURE: + if (dai->id == WSA_MACRO_AIF_VI) + wsa_priv->pcm_rate_vi = params_rate(params); default: break; } @@ -1046,10 +1058,24 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w, snd_soc_dapm_to_component(w->dapm); struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; + u8 val = 0x0; if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; + switch (wsa_priv->pcm_rate_vi) { + case 48000: + val = 0x04; + break; + case 24000: + val = 0x02; + break; + case 8000: + default: + val = 0x00; + break; + } + switch (event) { case SND_SOC_DAPM_POST_PMU: if (test_bit(WSA_MACRO_TX0, @@ -1064,10 +1090,10 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w, 0x20, 0x20); snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, - 0x0F, 0x00); + 0x0F, val); snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL, - 0x0F, 0x00); + 0x0F, val); snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, 0x10, 0x10); @@ -1093,10 +1119,10 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w, 0x20, 0x20); snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, - 0x0F, 0x00); + 0x0F, val); snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL, - 0x0F, 0x00); + 0x0F, val); snd_soc_component_update_bits(component, BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, 0x10, 0x10); -- GitLab From 9524bda6e484e5ce2f36abd8c400e7dc66e380f5 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 9 Mar 2020 08:37:53 +0800 Subject: [PATCH 1484/1645] asoc: update wakeup_source API wakeup_source_init and wakeup_source_trash are removed in new kernel. Update these two APIs to wakeup_source_register and wakeup_source_unregister. Change-Id: If628aac4f5391b483bb20e66b49cdf47618462c9 Signed-off-by: Meng Wang --- asoc/msm-lsm-client.c | 48 +++++++++++++++++++++++-------------------- dsp/q6afe.c | 18 +++++++++------- dsp/usf.c | 16 +++++++++------ 3 files changed, 47 insertions(+), 35 deletions(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index b6624f00296e..8a179fde913a 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -92,7 +93,7 @@ struct lsm_priv { int xrun_count; int xrun_index; spinlock_t xrun_lock; - struct wakeup_source ws; + struct wakeup_source *ws; }; enum { /* lsm session states */ @@ -220,7 +221,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, } rtd = substream->private_data; - pm_wakeup_ws_event(&prtd->ws, WAKELOCK_TIMEOUT, true); + pm_wakeup_ws_event(prtd->ws, WAKELOCK_TIMEOUT, true); dev_dbg(rtd->dev, "%s: opcode %x\n", __func__, opcode); switch (opcode) { case LSM_DATA_EVENT_READ_DONE: { @@ -235,13 +236,13 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, "%s: EVENT_READ_DONE invalid callback, session %d callback %d payload %pK", __func__, prtd->lsm_client->session, token, read_done); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return; } if (atomic_read(&prtd->read_abort)) { dev_dbg(rtd->dev, "%s: read abort set skip data\n", __func__); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return; } if (!lsm_lab_buffer_sanity(prtd, read_done, &buf_index)) { @@ -254,7 +255,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, "%s: Invalid index %d buf_index max cnt %d\n", __func__, buf_index, prtd->lsm_client->out_hw_params.period_count); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return; } spin_lock_irqsave(&prtd->xrun_lock, flags); @@ -292,7 +293,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, dev_err(rtd->dev, "%s: client_size has invalid size[%d]\n", __func__, client_size); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return; } status = (uint16_t)((uint8_t *)payload)[0]; @@ -308,7 +309,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, dev_err(rtd->dev, "%s: client_size has invalid size[%d]\n", __func__, client_size); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return; } status = (uint16_t)((uint8_t *)payload)[0]; @@ -324,7 +325,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, dev_err(rtd->dev, "%s: client_size has invalid size[%d]\n", __func__, client_size); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return; } event_ts_lsw = ((uint32_t *)payload)[0]; @@ -344,7 +345,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, dev_err(rtd->dev, "%s: client_size has invalid size[%d]\n", __func__, client_size); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return; } @@ -364,7 +365,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, "LSM_SESSION_DETECTION_ENGINE_GENERIC_EVENT", sizeof(struct snd_lsm_event_status) + payload_size); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return; } @@ -379,7 +380,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, dev_err(rtd->dev, "%s: Failed to copy memory with invalid size = %d\n", __func__, payload_size); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return; } prtd->event_avail = 1; @@ -411,7 +412,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, if (!temp) { dev_err(rtd->dev, "%s: no memory for event status\n", __func__); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return; } /* @@ -438,7 +439,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, dev_err(rtd->dev, "%s: Failed to copy memory with invalid size = %d\n", __func__, payload_size); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return; } } else { @@ -1156,7 +1157,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: lsm open failed, %d\n", __func__, ret); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return ret; } prtd->lsm_client->opened = true; @@ -1504,14 +1505,14 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, if (prtd->lsm_client->num_stages > 1) { dev_err(rtd->dev, "%s: %s: not supported for multi stage session\n", __func__, "LSM_LAB_CONTROL"); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return -EINVAL; } if (copy_from_user(&enable, arg, sizeof(enable))) { dev_err(rtd->dev, "%s: %s: copy_frm_user failed\n", __func__, "LSM_LAB_CONTROL"); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return -EFAULT; } @@ -1566,7 +1567,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, if (copy_from_user(&mode, arg, sizeof(mode))) { dev_err(rtd->dev, "%s: %s: copy_frm_user failed\n", __func__, "LSM_SET_FWK_MODE_CONFIG"); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return -EFAULT; } @@ -1597,7 +1598,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, if (copy_from_user(¶ms, arg, sizeof(params))) { dev_err(rtd->dev, "%s: %s: copy_from_user failed\n", __func__, "LSM_SET_INPUT_HW_PARAMS"); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return -EFAULT; } @@ -1624,7 +1625,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: cmd 0x%x failed %d\n", __func__, cmd, rc); - __pm_relax(&prtd->ws); + __pm_relax(prtd->ws); return rc; } @@ -2528,8 +2529,11 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) prtd->lsm_client->event_type = LSM_DET_EVENT_TYPE_LEGACY; prtd->lsm_client->fe_id = rtd->dai_link->id; prtd->lsm_client->unprocessed_data = 0; - - wakeup_source_init(&prtd->ws, "lsm-client"); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 110)) + prtd->ws = wakeup_source_register(rtd->dev, "lsm-client"); +#else + prtd->ws = wakeup_source_register("lsm-client"); +#endif return 0; } @@ -2774,7 +2778,7 @@ static int msm_lsm_close(struct snd_pcm_substream *substream) q6lsm_client_free(prtd->lsm_client); - wakeup_source_trash(&prtd->ws); + wakeup_source_unregister(prtd->ws); spin_lock_irqsave(&prtd->event_lock, flags); kfree(prtd->event_status); prtd->event_status = NULL; diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 2586bd56b30e..b6c11697d2e8 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -98,7 +99,7 @@ enum { }; struct wlock { - struct wakeup_source ws; + struct wakeup_source *ws; }; static struct wlock wl; @@ -8960,7 +8961,7 @@ static int afe_set_cal_fb_spkr_prot(int32_t cal_type, size_t data_size, goto done; if (cal_data->cal_info.mode == MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) - __pm_wakeup_event(&wl.ws, jiffies_to_msecs(WAKELOCK_TIMEOUT)); + __pm_wakeup_event(wl.ws, jiffies_to_msecs(WAKELOCK_TIMEOUT)); mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); memcpy(&this_afe.prot_cfg, &cal_data->cal_info, sizeof(this_afe.prot_cfg)); @@ -9166,7 +9167,7 @@ static int afe_get_cal_fb_spkr_prot(int32_t cal_type, size_t data_size, } this_afe.initial_cal = 0; mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); - __pm_relax(&wl.ws); + __pm_relax(wl.ws); done: return ret; } @@ -9464,7 +9465,6 @@ int __init afe_init(void) init_waitqueue_head(&this_afe.wait_wakeup); init_waitqueue_head(&this_afe.lpass_core_hw_wait); init_waitqueue_head(&this_afe.clk_wait); - wakeup_source_init(&wl.ws, "spkr-prot"); ret = afe_init_cal_data(); if (ret) pr_err("%s: could not init cal data! %d\n", __func__, ret); @@ -9474,8 +9474,12 @@ int __init afe_init(void) this_afe.uevent_data = kzalloc(sizeof(*(this_afe.uevent_data)), GFP_KERNEL); if (!this_afe.uevent_data) return -ENOMEM; - - /* +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 110)) + wl.ws = wakeup_source_register(NULL, "spkr-prot"); +#else + wl.ws = wakeup_source_register("spkr-prot"); +#endif +/* * Set release function to cleanup memory related to kobject * before initializing the kobject. */ @@ -9509,7 +9513,7 @@ void afe_exit(void) mutex_destroy(&this_afe.afe_cmd_lock); mutex_destroy(&this_afe.afe_apr_lock); mutex_destroy(&this_afe.afe_clk_lock); - wakeup_source_trash(&wl.ws); + wakeup_source_unregister(wl.ws); } /* diff --git a/dsp/usf.c b/dsp/usf.c index e408c7d70f5b..d0f6ed3ca7a4 100644 --- a/dsp/usf.c +++ b/dsp/usf.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017, 2020, The Linux Foundation. All rights reserved. */ #include @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "q6usm.h" #include "usf.h" @@ -173,7 +174,7 @@ static const int s_button_map[] = { /* The opened devices container */ static atomic_t s_opened_devs[MAX_DEVS_NUMBER]; -static struct wakeup_source usf_wakeup_source; +static struct wakeup_source *usf_wakeup_source; #define USF_NAME_PREFIX "usf_" #define USF_NAME_PREFIX_SIZE 4 @@ -442,7 +443,7 @@ static void usf_tx_cb(uint32_t opcode, uint32_t token, case Q6USM_EVENT_READ_DONE: pr_debug("%s: acquiring %d msec wake lock\n", __func__, STAY_AWAKE_AFTER_READ_MSECS); - __pm_wakeup_event(&usf_wakeup_source, + __pm_wakeup_event(usf_wakeup_source, STAY_AWAKE_AFTER_READ_MSECS); if (token == USM_WRONG_TOKEN) usf_xx->usf_state = USF_ERROR_STATE; @@ -2369,8 +2370,11 @@ static int usf_open(struct inode *inode, struct file *file) usf = kzalloc(sizeof(struct usf_type), GFP_KERNEL); if (usf == NULL) return -ENOMEM; - - wakeup_source_init(&usf_wakeup_source, "usf"); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 110)) + usf_wakeup_source = wakeup_source_register(NULL, "usf"); +#else + usf_wakeup_source = wakeup_source_register("usf"); +#endif file->private_data = usf; usf->dev_ind = dev_ind; @@ -2401,7 +2405,7 @@ static int usf_release(struct inode *inode, struct file *file) atomic_set(&s_opened_devs[usf->dev_ind], 0); - wakeup_source_trash(&usf_wakeup_source); + wakeup_source_unregister(usf_wakeup_source); mutex_unlock(&usf->mutex); mutex_destroy(&usf->mutex); kfree(usf); -- GitLab From 5568eb939ffcebcd2f1c298fec394cd0f7781d83 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 6 May 2020 14:09:09 +0530 Subject: [PATCH 1485/1645] asoc: codecs: Fix volume fluctuation issue in headphone playback HPH PA pull down control is set to force ON instead of auto due of which saturation/noise is observed in headset playback at highest volumes. Set pull down control to Auto to fix this issue. Change-Id: I465588f46b04bbb32d84f76b8b5bedd2ef21bd2a Signed-off-by: Aditya Bavanari --- asoc/codecs/rouleur/rouleur-mbhc.c | 4 ++-- asoc/codecs/rouleur/rouleur.c | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/asoc/codecs/rouleur/rouleur-mbhc.c b/asoc/codecs/rouleur/rouleur-mbhc.c index 2f8e954b5a23..8dc959b08917 100644 --- a/asoc/codecs/rouleur/rouleur-mbhc.c +++ b/asoc/codecs/rouleur/rouleur-mbhc.c @@ -727,10 +727,10 @@ static void rouleur_mbhc_hph_pull_down_ctrl(struct snd_soc_component *component, if (enable) { snd_soc_component_update_bits(component, ROULEUR_ANA_HPHPA_CNP_CTL_2, - 0x30, 0x10); + 0x30, 0x20); snd_soc_component_update_bits(component, ROULEUR_ANA_HPHPA_CNP_CTL_2, - 0x0C, 0x04); + 0x0C, 0x08); } else { snd_soc_component_update_bits(component, ROULEUR_ANA_HPHPA_CNP_CTL_2, diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index e1ecdba83f3b..01274693c421 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -472,7 +472,7 @@ static int rouleur_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, } snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX0_CTL, - 0x7C, 0x7C); + 0x80, 0x00); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, 0x04, 0x04); @@ -486,6 +486,9 @@ static int rouleur_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, 0x04, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX0_CTL, + 0x80, 0x80); if (rouleur->comp1_enable) snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_COMP_CTL_0, @@ -544,7 +547,7 @@ static int rouleur_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, } snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX1_CTL, - 0x7C, 0x7C); + 0x80, 0x00); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, 0x08, 0x08); @@ -557,6 +560,9 @@ static int rouleur_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, 0x08, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX1_CTL, + 0x80, 0x80); if (rouleur->comp2_enable) snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_COMP_CTL_0, @@ -583,7 +589,7 @@ static int rouleur_codec_ear_lo_dac_event(struct snd_soc_dapm_widget *w, rouleur_rx_clk_enable(component); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX0_CTL, - 0x7C, 0x7C); + 0x80, 0x00); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, 0x04, 0x04); @@ -599,6 +605,9 @@ static int rouleur_codec_ear_lo_dac_event(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, 0x04, 0x00); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX0_CTL, + 0x80, 0x80); break; }; -- GitLab From c3ee406cd98ca5a5f56b1aba730cf9f77d972234 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Mon, 4 May 2020 13:07:09 +0530 Subject: [PATCH 1486/1645] dsp: codecs: Add spin_lock_irqsave instead of spin_lock spin_lock is acquired in process context and trying do the operation in process context,while the interrupt came and the same lock is trying to take in interrupt context which leads to deadlock.To avoid this we are using spin_lock_irqsave instead of spin_lock. Change-Id: I9c4a3ac65d92b0612d7c4845212647c51a72065b Signed-off-by: Prasad Kumpatla --- dsp/codecs/audio_utils.c | 5 +++-- dsp/codecs/audio_utils_aio.c | 5 +++-- dsp/codecs/q6audio_v2.c | 5 +++-- dsp/codecs/q6audio_v2_aio.c | 5 +++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/dsp/codecs/audio_utils.c b/dsp/codecs/audio_utils.c index ac934132ac3b..33495b2f7da4 100644 --- a/dsp/codecs/audio_utils.c +++ b/dsp/codecs/audio_utils.c @@ -936,6 +936,7 @@ ssize_t audio_in_write(struct file *file, int audio_in_release(struct inode *inode, struct file *file) { + unsigned long flags = 0; struct q6audio_in *audio = file->private_data; pr_info("%s: session id %d\n", __func__, audio->ac->session); @@ -943,11 +944,11 @@ int audio_in_release(struct inode *inode, struct file *file) audio_in_disable(audio); q6asm_audio_client_free(audio->ac); mutex_unlock(&audio->lock); - spin_lock(&enc_dec_lock); + spin_lock_irqsave(&enc_dec_lock, flags); kfree(audio->enc_cfg); kfree(audio->codec_cfg); kfree(audio); file->private_data = NULL; - spin_unlock(&enc_dec_lock); + spin_unlock_irqrestore(&enc_dec_lock, flags); return 0; } diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c index 93095e3007fb..94be57db32bd 100644 --- a/dsp/codecs/audio_utils_aio.c +++ b/dsp/codecs/audio_utils_aio.c @@ -588,6 +588,7 @@ int enable_volume_ramp(struct q6audio_aio *audio) int audio_aio_release(struct inode *inode, struct file *file) { + unsigned long flags = 0; struct q6audio_aio *audio = file->private_data; pr_debug("%s[%pK]\n", __func__, audio); @@ -631,11 +632,11 @@ int audio_aio_release(struct inode *inode, struct file *file) #ifdef CONFIG_DEBUG_FS debugfs_remove(audio->dentry); #endif - spin_lock(&enc_dec_lock); + spin_lock_irqsave(&enc_dec_lock, flags); kfree(audio->codec_cfg); kfree(audio); file->private_data = NULL; - spin_unlock(&enc_dec_lock); + spin_unlock_irqrestore(&enc_dec_lock, flags); mutex_unlock(&lock); return 0; } diff --git a/dsp/codecs/q6audio_v2.c b/dsp/codecs/q6audio_v2.c index 6a402f538b75..51ff85049b00 100644 --- a/dsp/codecs/q6audio_v2.c +++ b/dsp/codecs/q6audio_v2.c @@ -20,8 +20,9 @@ void q6asm_in_cb(uint32_t opcode, uint32_t token, { struct q6audio_in *audio = (struct q6audio_in *)priv; unsigned long flags; + unsigned long en_de_flags; - spin_lock(&enc_dec_lock); + spin_lock_irqsave(&enc_dec_lock, en_de_flags); if (audio == NULL) { pr_err("%s: failed to get q6audio value\n", __func__); goto error; @@ -64,7 +65,7 @@ void q6asm_in_cb(uint32_t opcode, uint32_t token, } spin_unlock_irqrestore(&audio->dsp_lock, flags); error: - spin_unlock(&enc_dec_lock); + spin_unlock_irqrestore(&enc_dec_lock, en_de_flags); } void audio_in_get_dsp_frames(void *priv, diff --git a/dsp/codecs/q6audio_v2_aio.c b/dsp/codecs/q6audio_v2_aio.c index ecd14dadfee7..d9dd29b23bcb 100644 --- a/dsp/codecs/q6audio_v2_aio.c +++ b/dsp/codecs/q6audio_v2_aio.c @@ -42,8 +42,9 @@ void audio_aio_cb(uint32_t opcode, uint32_t token, { struct q6audio_aio *audio = (struct q6audio_aio *)priv; union msm_audio_event_payload e_payload; + unsigned long flags = 0; - spin_lock(&enc_dec_lock); + spin_lock_irqsave(&enc_dec_lock, flags); if (audio == NULL) { pr_err("%s: failed to get q6audio value\n", __func__); goto error; @@ -113,7 +114,7 @@ void audio_aio_cb(uint32_t opcode, uint32_t token, break; } error: - spin_unlock(&enc_dec_lock); + spin_unlock_irqrestore(&enc_dec_lock, flags); } int extract_meta_out_info(struct q6audio_aio *audio, -- GitLab From 80c1005aa1cc4e81290b33611cc24e740ce1ce94 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 1 May 2020 00:22:25 +0530 Subject: [PATCH 1487/1645] asoc: wsa883x: Update init values of VAGC Update current limit and VAGC settings to limit the current drawn at chipset causing target reset. Change-Id: I8cc1c91d45f1e27c236c00b5b0f851502f69d82c Signed-off-by: Laxminath Kasam --- asoc/codecs/wsa883x/wsa883x.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 9e25e53a8bff..cee2a32d0742 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -92,9 +92,10 @@ static const struct wsa_reg_mask_val reg_init[] = { {WSA883X_DRE_CTL_0, 0xF0, 0x90}, {WSA883X_DRE_IDLE_DET_CTL, 0x10, 0x00}, {WSA883X_PDM_WD_CTL, 0x01, 0x01}, - {WSA883X_CURRENT_LIMIT, 0x78, 0x40}, + {WSA883X_CURRENT_LIMIT, 0x78, 0x20}, {WSA883X_DRE_CTL_0, 0x07, 0x02}, - {WSA883X_VAGC_TIME, 0x03, 0x02}, + {WSA883X_VAGC_TIME, 0x0F, 0x0F}, + {WSA883X_VAGC_ATTN_LVL_3, 0x07, 0x02}, {WSA883X_VAGC_CTL, 0x01, 0x01}, {WSA883X_TAGC_CTL, 0x0E, 0x0A}, {WSA883X_TAGC_TIME, 0x0C, 0x0C}, -- GitLab From b06236e6377a48282b59410e0440b8be6d83095f Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 27 Mar 2020 12:46:38 +0530 Subject: [PATCH 1488/1645] asoc: bolero: Register for AFE event for all SVA usecases For island SVA usecase, ensure register for AFE in-band interrupt. Change-Id: I24e6dfadfaa38919114000fb09a7906264020cd9 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc.c | 5 ++- asoc/codecs/bolero/bolero-cdc.h | 7 ++-- asoc/codecs/bolero/tx-macro.c | 8 ++-- asoc/codecs/bolero/va-macro.c | 69 ++++++++++++++++++++++++++++++++- 4 files changed, 79 insertions(+), 10 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 417b34dc0a4d..fea1686bddf9 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -1078,7 +1078,7 @@ EXPORT_SYMBOL(bolero_tx_mclk_enable); * Returns 0 on success or -EINVAL on error. */ int bolero_register_event_listener(struct snd_soc_component *component, - bool enable) + bool enable, bool is_dmic_sva) { struct bolero_priv *priv = NULL; int ret = 0; @@ -1097,7 +1097,8 @@ int bolero_register_event_listener(struct snd_soc_component *component, if (priv->macro_params[TX_MACRO].reg_evt_listener) ret = priv->macro_params[TX_MACRO].reg_evt_listener(component, - enable); + enable, + is_dmic_sva); return ret; } diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index b37eeae6e15c..7528eaed9974 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -88,7 +88,8 @@ struct macro_ops { u32 size, void *data); int (*clk_div_get)(struct snd_soc_component *component); int (*clk_switch)(struct snd_soc_component *component, int clk_src); - int (*reg_evt_listener)(struct snd_soc_component *component, bool en); + int (*reg_evt_listener)(struct snd_soc_component *component, + bool en, bool is_dmic_sva); int (*clk_enable)(struct snd_soc_component *c, bool en); char __iomem *io_base; u16 clk_id_req; @@ -115,7 +116,7 @@ int bolero_runtime_suspend(struct device *dev); int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *data); int bolero_tx_clk_switch(struct snd_soc_component *component, int clk_src); int bolero_register_event_listener(struct snd_soc_component *component, - bool enable); + bool enable, bool is_dmic_sva); void bolero_wsa_pa_on(struct device *dev); bool bolero_check_core_votes(struct device *dev); int bolero_tx_mclk_enable(struct snd_soc_component *c, bool enable); @@ -189,7 +190,7 @@ static inline int bolero_tx_clk_switch(struct snd_soc_component *component, static inline int bolero_register_event_listener( struct snd_soc_component *component, - bool enable) + bool enable, bool is_dmic_sva) { return 0; } diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 121f56df255d..ff941984e897 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -2385,7 +2385,7 @@ static const struct snd_kcontrol_new tx_macro_snd_controls[] = { }; static int tx_macro_register_event_listener(struct snd_soc_component *component, - bool enable) + bool enable, bool is_dmic_sva) { struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; @@ -2412,10 +2412,12 @@ static int tx_macro_register_event_listener(struct snd_soc_component *component, ret = swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, SWR_REGISTER_WAKEUP, NULL); - msm_cdc_pinctrl_set_wakeup_capable( + if (!is_dmic_sva) + msm_cdc_pinctrl_set_wakeup_capable( tx_priv->tx_swr_gpio_p, false); } else { - msm_cdc_pinctrl_set_wakeup_capable( + if (!is_dmic_sva) + msm_cdc_pinctrl_set_wakeup_capable( tx_priv->tx_swr_gpio_p, true); ret = swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index a947a28a22ff..de834aded74f 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -457,14 +457,14 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, dev_dbg(va_dev, "%s: clock switch failed\n", __func__); if (va_priv->lpi_enable) { - bolero_register_event_listener(component, true); + bolero_register_event_listener(component, true, false); va_priv->register_event_listener = true; } break; case SND_SOC_DAPM_POST_PMD: if (va_priv->register_event_listener) { va_priv->register_event_listener = false; - bolero_register_event_listener(component, false); + bolero_register_event_listener(component, false, false); } if (bolero_tx_clk_switch(component, CLK_SRC_TX_RCG)) dev_dbg(va_dev, "%s: clock switch failed\n",__func__); @@ -480,6 +480,45 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, return ret; } +static int va_macro_swr_intr_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + int ret = 0; + struct device *va_dev = NULL; + struct va_macro_priv *va_priv = NULL; + + if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) + return -EINVAL; + + dev_dbg(va_dev, "%s: event = %d, lpi_enable = %d\n", + __func__, event, va_priv->lpi_enable); + + if (!va_priv->lpi_enable) + return ret; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (va_priv->lpi_enable) { + bolero_register_event_listener(component, true, true); + va_priv->register_event_listener = true; + } + break; + case SND_SOC_DAPM_POST_PMD: + if (va_priv->register_event_listener) { + va_priv->register_event_listener = false; + bolero_register_event_listener(component, false, true); + } + break; + default: + dev_err(va_priv->dev, + "%s: invalid DAPM event %d\n", __func__, event); + ret = -EINVAL; + } + return ret; +} + static int va_macro_tx_swr_clk_event_v2(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -1962,6 +2001,10 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v3[] = { SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0, va_macro_swr_pwr_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("VA_SWR_INTR", 0, SND_SOC_NOPM, 0, 0, + va_macro_swr_intr_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = { @@ -2106,6 +2149,10 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0, va_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("VA_SWR_INTR", 0, SND_SOC_NOPM, 0, 0, + va_macro_swr_intr_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; static const struct snd_soc_dapm_widget va_macro_wod_dapm_widgets[] = { @@ -2252,6 +2299,15 @@ static const struct snd_soc_dapm_route va_audio_map_v3[] = { {"VA SMIC MUX3", "SWR_MIC9", "VA SWR_MIC9"}, {"VA SMIC MUX3", "SWR_MIC10", "VA SWR_MIC10"}, {"VA SMIC MUX3", "SWR_MIC11", "VA SWR_MIC11"}, + + {"VA DMIC0", NULL, "VA_SWR_INTR"}, + {"VA DMIC1", NULL, "VA_SWR_INTR"}, + {"VA DMIC2", NULL, "VA_SWR_INTR"}, + {"VA DMIC3", NULL, "VA_SWR_INTR"}, + {"VA DMIC4", NULL, "VA_SWR_INTR"}, + {"VA DMIC5", NULL, "VA_SWR_INTR"}, + {"VA DMIC6", NULL, "VA_SWR_INTR"}, + {"VA DMIC7", NULL, "VA_SWR_INTR"}, }; static const struct snd_soc_dapm_route va_audio_map_v2[] = { @@ -2488,6 +2544,15 @@ static const struct snd_soc_dapm_route va_audio_map[] = { {"VA SMIC MUX7", "SWR_DMIC6", "VA SWR_MIC6"}, {"VA SMIC MUX7", "SWR_DMIC7", "VA SWR_MIC7"}, + {"VA DMIC0", NULL, "VA_SWR_INTR"}, + {"VA DMIC1", NULL, "VA_SWR_INTR"}, + {"VA DMIC2", NULL, "VA_SWR_INTR"}, + {"VA DMIC3", NULL, "VA_SWR_INTR"}, + {"VA DMIC4", NULL, "VA_SWR_INTR"}, + {"VA DMIC5", NULL, "VA_SWR_INTR"}, + {"VA DMIC6", NULL, "VA_SWR_INTR"}, + {"VA DMIC7", NULL, "VA_SWR_INTR"}, + {"VA SWR_ADC0", NULL, "VA_SWR_PWR"}, {"VA SWR_ADC1", NULL, "VA_SWR_PWR"}, {"VA SWR_ADC2", NULL, "VA_SWR_PWR"}, -- GitLab From 645fbe2cb321b5657120da39a90021ea6fd94949 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 7 May 2020 10:30:39 +0530 Subject: [PATCH 1489/1645] ASoC: wcd938x: Resolve noise during dmic record Channel rate is set same as clk rate resulting in noise during dmic record. Set channel rate for dmic based on port params not clk rate to resolve noise. Change-Id: Ie65c72be5ed3719a1204f800571329ea5b5985fc Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd938x/wcd938x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index abd3106fe743..26174dcd9ba2 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1377,8 +1377,7 @@ static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w, /* enable clock scaling */ snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_DMIC_CTL, 0x06, 0x06); - wcd938x_tx_connect_port(component, DMIC0 + (w->shift), - SWR_CLK_RATE_2P4MHZ, true); + wcd938x_tx_connect_port(component, DMIC0 + (w->shift), 0, true); break; case SND_SOC_DAPM_POST_PMD: wcd938x_tx_connect_port(component, DMIC0 + (w->shift), 0, -- GitLab From fc93c48633d21fd0f13335bf6d4b734af4daa66f Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Thu, 31 Oct 2019 11:05:59 +0530 Subject: [PATCH 1490/1645] asoc: add support to set TTP offset - Add support to set TTP offset. - Add direction support for render mode Change-Id: Ia869767c58192f3e07cddc7bf230992076f7a02e Signed-off-by: Surendar Karka --- asoc/msm-compress-q6-v2.c | 33 +++++++++- asoc/msm-transcode-loopback-q6-v2.c | 7 ++- dsp/q6asm.c | 93 ++++++++++++++++++++++++++++- include/dsp/apr_audio-v2.h | 27 +++++++++ include/dsp/q6asm-v2.h | 8 ++- 5 files changed, 158 insertions(+), 10 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index fdf61cfde6ea..b34202cb1d13 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -225,7 +225,7 @@ static int msm_compr_send_dec_params(struct snd_compr_stream *cstream, int stream_id); static int msm_compr_set_render_mode(struct msm_compr_audio *prtd, - uint32_t render_mode) { + uint32_t render_mode, int dir) { int ret = -EINVAL; struct audio_client *ac = prtd->audio_client; @@ -250,7 +250,7 @@ static int msm_compr_set_render_mode(struct msm_compr_audio *prtd, goto exit; } - ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode); + ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode, dir); if (ret) { pr_err("%s, Render mode can't be set error %d\n", __func__, ret); @@ -324,6 +324,29 @@ static int msm_compr_set_render_window(struct audio_client *ac, return ret; } +static int msm_compr_set_ttp_offset(struct audio_client *ac, + uint32_t offset_lsw, uint32_t offset_msw, int dir) +{ + int ret = -EINVAL; + struct asm_session_mtmx_strtr_param_ttp_offset_t ttp_offset; + uint32_t param_id; + + pr_debug("%s, ttp offset lsw 0x%x ttp offset msw 0x%x\n", + __func__, offset_lsw, offset_msw); + + memset(&ttp_offset, 0, + sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t)); + ttp_offset.ttp_offset_lsw = offset_lsw; + ttp_offset.ttp_offset_msw = offset_msw; + param_id = ASM_SESSION_MTMX_STRTR_PARAM_TTP_OFFSET; + ret = q6asm_send_mtmx_strtr_ttp_offset(ac, &ttp_offset, param_id, dir); + if (ret) + pr_err("%s, ttp offset can't be set error %d\n", __func__, + ret); + + return ret; +} + static int msm_compr_enable_adjust_session_clock(struct audio_client *ac, bool enable) { @@ -3221,7 +3244,8 @@ static int msm_compr_set_metadata(struct snd_compr_stream *cstream, __func__, metadata->value[0]); prtd->gapless_state.initial_samples_drop = metadata->value[0]; } else if (metadata->key == SNDRV_COMPRESS_RENDER_MODE) { - return msm_compr_set_render_mode(prtd, metadata->value[0]); + return msm_compr_set_render_mode(prtd, metadata->value[0], + cstream->direction); } else if (metadata->key == SNDRV_COMPRESS_CLK_REC_MODE) { return msm_compr_set_clk_rec_mode(ac, metadata->value[0]); } else if (metadata->key == SNDRV_COMPRESS_RENDER_WINDOW) { @@ -3242,6 +3266,9 @@ static int msm_compr_set_metadata(struct snd_compr_stream *cstream, return msm_compr_adjust_session_clock(ac, metadata->value[0], metadata->value[1]); + } else if (metadata->key == SNDRV_COMPRESS_IN_TTP_OFFSET) { + return msm_compr_set_ttp_offset(ac, metadata->value[0], + metadata->value[1], cstream->direction); } return 0; diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index e20f0dfebdc6..bba4ad7f902e 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -613,7 +613,7 @@ static int msm_transcode_loopback_get_caps(struct snd_compr_stream *cstream, } static int msm_transcode_set_render_mode(struct msm_transcode_loopback *prtd, - uint32_t render_mode) + uint32_t render_mode, int dir) { int ret = -EINVAL; struct audio_client *ac = prtd->audio_client; @@ -639,7 +639,7 @@ static int msm_transcode_set_render_mode(struct msm_transcode_loopback *prtd, goto exit; } - ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode); + ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode, dir); if (ret) { pr_err("%s: Render mode can't be set error %d\n", __func__, ret); @@ -705,7 +705,8 @@ static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream, } case SNDRV_COMPRESS_RENDER_MODE: { - rc = msm_transcode_set_render_mode(prtd, metadata->value[0]); + rc = msm_transcode_set_render_mode(prtd, metadata->value[0], + cstream->direction); if (rc) pr_err("%s: error setting render mode %d\n", __func__, rc); diff --git a/dsp/q6asm.c b/dsp/q6asm.c index fef09c589722..e56c7c54f753 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -10047,17 +10047,106 @@ int q6asm_send_mtmx_strtr_window(struct audio_client *ac, } EXPORT_SYMBOL(q6asm_send_mtmx_strtr_window); +/** + * q6asm_send_mtmx_strtr_ttp_offset - + * command to send matrix for ttp offset + * + * @ac: Audio client handle + * @ttp_offset: ttp offset params + * @param_id: param id for ttp offset + * @dir: RX or TX direction + * + * Returns 0 on success or error on failure + */ +int q6asm_send_mtmx_strtr_ttp_offset(struct audio_client *ac, + struct asm_session_mtmx_strtr_param_ttp_offset_t *ttp_offset, + uint32_t param_id, int dir) +{ + struct asm_mtmx_strtr_params matrix; + int sz = 0; + int rc = 0; + + pr_debug("%s: ttp offset lsw is %d, ttp offset msw is %d\n", __func__, + ttp_offset->ttp_offset_lsw, ttp_offset->ttp_offset_msw); + + if (!ac) { + pr_err("%s: audio client handle is NULL\n", __func__); + rc = -EINVAL; + goto fail_cmd; + } + + if (ac->apr == NULL) { + pr_err("%s: ac->apr is NULL", __func__); + rc = -EINVAL; + goto fail_cmd; + } + + memset(&matrix, 0, sizeof(struct asm_mtmx_strtr_params)); + sz = sizeof(struct asm_mtmx_strtr_params); + q6asm_add_hdr(ac, &matrix.hdr, sz, TRUE); + atomic_set(&ac->cmd_state, -1); + matrix.hdr.opcode = ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2; + + matrix.param.data_payload_addr_lsw = 0; + matrix.param.data_payload_addr_msw = 0; + matrix.param.mem_map_handle = 0; + matrix.param.data_payload_size = + sizeof(struct param_hdr_v1) + + sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t); + matrix.param.direction = dir; + matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; + matrix.data.param_id = param_id; + matrix.data.param_size = + sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t); + matrix.data.reserved = 0; + memcpy(&(matrix.config.ttp_offset), + ttp_offset, + sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t)); + + rc = apr_send_pkt(ac->apr, (uint32_t *) &matrix); + if (rc < 0) { + pr_err("%s: ttp offset send failed paramid [0x%x]\n", + __func__, matrix.data.param_id); + rc = -EINVAL; + goto fail_cmd; + } + + rc = wait_event_timeout(ac->cmd_wait, + (atomic_read(&ac->cmd_state) >= 0), + msecs_to_jiffies(TIMEOUT_MS)); + if (!rc) { + pr_err("%s: timeout, ttp offset paramid[0x%x]\n", + __func__, matrix.data.param_id); + rc = -ETIMEDOUT; + goto fail_cmd; + } + + if (atomic_read(&ac->cmd_state) > 0) { + pr_err("%s: DSP returned error[%s]\n", + __func__, adsp_err_get_err_str( + atomic_read(&ac->cmd_state))); + rc = adsp_err_get_lnx_err_code( + atomic_read(&ac->cmd_state)); + goto fail_cmd; + } + rc = 0; +fail_cmd: + return rc; +} +EXPORT_SYMBOL(q6asm_send_mtmx_strtr_ttp_offset); + /** * q6asm_send_mtmx_strtr_render_mode - * command to send matrix for render mode * * @ac: Audio client handle * @render_mode: rendering mode + * @dir: RX or TX direction * * Returns 0 on success or error on failure */ int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac, - uint32_t render_mode) + uint32_t render_mode, int dir) { struct asm_mtmx_strtr_params matrix; struct asm_session_mtmx_strtr_param_render_mode_t render_param; @@ -10101,7 +10190,7 @@ int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac, matrix.param.data_payload_size = sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_render_mode_t); - matrix.param.direction = 0; /* RX */ + matrix.param.direction = dir; matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; matrix.data.param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_MODE_CMD; matrix.data.param_size = diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 311c892ee695..cd131cfb2964 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -12348,6 +12348,12 @@ struct afe_av_dev_drift_get_param_resp { */ #define ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_END_V2 0x00010DD2 +/* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC to specify the + * ttp offset value. This parameter is supported only for a Set + * command (not a Get command) in the Tx direction + */ +#define ASM_SESSION_MTMX_STRTR_PARAM_TTP_OFFSET 0x00013228 + /* Generic payload of the window parameters in the * #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC module. * This payload is supported only for a Set command @@ -12456,6 +12462,26 @@ struct asm_session_mtmx_strtr_param_render_mode_t { u32 flags; } __packed; +struct asm_session_mtmx_strtr_param_ttp_offset_t { + uint32_t ttp_offset_lsw; + /* Lower 32 bits of the ttp_offset in microseconds. */ + + uint32_t ttp_offset_msw; + /* Upper 32 bits of the ttp_offset in microseconds. + * + * Internal default value is 0 for both values. The 64-bit number + * formed by ttp_offset_lsw and ttp_offset_lsw is treated as unsigned. + * In case of local DSP loopback when using start flag + * ASM_SESSION_CMD_RUN_START_TIME_RUN_WITH_TTP the max. ttp_offset + * value is limited by internal buffer constraints. Currently the + * limit is 200ms. + + * This parameter can be set before or while an ASM stream is running, + * allowing “at-run-time†changes of the overall latency. + */ + +} __packed; + /* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC which allows the * audio client to specify the clock recovery mechanism that the audio DSP * should use. @@ -12527,6 +12553,7 @@ union asm_session_mtmx_strtr_param_config { struct asm_session_mtmx_strtr_param_render_mode_t render_param; struct asm_session_mtmx_strtr_param_clk_rec_t clk_rec_param; struct asm_session_mtmx_param_adjust_session_time_ctl_t adj_time_param; + struct asm_session_mtmx_strtr_param_ttp_offset_t ttp_offset; } __packed; struct asm_mtmx_strtr_params { diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h index 5ad8fb0f6abe..1a34161c3bad 100644 --- a/include/dsp/q6asm-v2.h +++ b/include/dsp/q6asm-v2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef __Q6_ASM_V2_H__ #define __Q6_ASM_V2_H__ @@ -726,9 +726,13 @@ int q6asm_send_mtmx_strtr_window(struct audio_client *ac, struct asm_session_mtmx_strtr_param_window_v2_t *window_param, uint32_t param_id); +int q6asm_send_mtmx_strtr_ttp_offset(struct audio_client *ac, + struct asm_session_mtmx_strtr_param_ttp_offset_t *ttp_offset, + uint32_t param_id, int dir); + /* Configure DSP render mode */ int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac, - uint32_t render_mode); + uint32_t render_mode, int dir); /* Configure DSP clock recovery mode */ int q6asm_send_mtmx_strtr_clk_rec_mode(struct audio_client *ac, -- GitLab From b50f4233ef5a442dd4c30dcd3d12bb1f938aec6b Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Tue, 12 Feb 2019 12:46:05 +0530 Subject: [PATCH 1491/1645] asoc: enable TTP generator Add support to enable TTP generator in AFE. Change-Id: I0186dc18809b87a912a1c3ec9dd7fcd26aa726f5 Signed-off-by: Surendar Karka --- asoc/msm-dai-q6-v2.c | 142 +++++++++++++++++++++++++++++++++++-- dsp/q6afe.c | 99 ++++++++++++++++++++++++-- include/dsp/apr_audio-v2.h | 50 +++++++++++++ include/dsp/q6afe-v2.h | 5 ++ 4 files changed, 284 insertions(+), 12 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index a0d98959074d..4dd8c9cae111 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -232,6 +232,7 @@ struct msm_dai_q6_dai_data { u16 afe_tx_out_bitformat; struct afe_enc_config enc_config; struct afe_dec_config dec_config; + struct afe_ttp_config ttp_config; union afe_port_config port_config; u16 vi_feed_mono; u32 xt_logging_disable; @@ -2230,6 +2231,7 @@ static int msm_dai_q6_prepare(struct snd_pcm_substream *substream, { struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); int rc = 0; + uint16_t ttp_gen_enable = dai_data->ttp_config.ttp_gen_enable.enable; if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { if (dai_data->enc_config.format != ENC_FMT_NONE) { @@ -2279,13 +2281,27 @@ static int msm_dai_q6_prepare(struct snd_pcm_substream *substream, bitwidth = 0; break; } - pr_debug("%s: calling AFE_PORT_START_V2 with dec format: %d\n", - __func__, dai_data->dec_config.format); - rc = afe_port_start_v2(dai->id, &dai_data->port_config, - dai_data->rate, - dai_data->afe_tx_out_channels, - bitwidth, - NULL, &dai_data->dec_config); + + if (ttp_gen_enable == true) { + pr_debug("%s: calling AFE_PORT_START_V3 with dec format: %d\n", + __func__, dai_data->dec_config.format); + rc = afe_port_start_v3(dai->id, + &dai_data->port_config, + dai_data->rate, + dai_data->afe_tx_out_channels, + bitwidth, + NULL, &dai_data->dec_config, + &dai_data->ttp_config); + } else { + pr_debug("%s: calling AFE_PORT_START_V2 with dec format: %d\n", + __func__, dai_data->dec_config.format); + rc = afe_port_start_v2(dai->id, + &dai_data->port_config, + dai_data->rate, + dai_data->afe_tx_out_channels, + bitwidth, + NULL, &dai_data->dec_config); + } if (rc < 0) { pr_err("%s: fail to open AFE port 0x%x\n", __func__, dai->id); @@ -3669,6 +3685,91 @@ static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol, return ret; } +static int msm_dai_q6_afe_enable_ttp_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(struct afe_ttp_gen_enable_t); + + return 0; +} + +static int msm_dai_q6_afe_enable_ttp_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + pr_debug("%s:\n", __func__); + if (!dai_data) { + pr_err("%s: Invalid dai data\n", __func__); + return -EINVAL; + } + + memcpy(ucontrol->value.bytes.data, + &dai_data->ttp_config.ttp_gen_enable, + sizeof(struct afe_ttp_gen_enable_t)); + return 0; +} + +static int msm_dai_q6_afe_enable_ttp_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + pr_debug("%s:\n", __func__); + if (!dai_data) { + pr_err("%s: Invalid dai data\n", __func__); + return -EINVAL; + } + + memcpy(&dai_data->ttp_config.ttp_gen_enable, + ucontrol->value.bytes.data, + sizeof(struct afe_ttp_gen_enable_t)); + return 0; +} + +static int msm_dai_q6_afe_ttp_cfg_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(struct afe_ttp_gen_cfg_t); + + return 0; +} + +static int msm_dai_q6_afe_ttp_cfg_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + pr_debug("%s:\n", __func__); + if (!dai_data) { + pr_err("%s: Invalid dai data\n", __func__); + return -EINVAL; + } + + memcpy(ucontrol->value.bytes.data, + &dai_data->ttp_config.ttp_gen_cfg, + sizeof(struct afe_ttp_gen_cfg_t)); + return 0; +} + +static int msm_dai_q6_afe_ttp_cfg_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + pr_debug("%s: Received ttp config\n", __func__); + if (!dai_data) { + pr_err("%s: Invalid dai data\n", __func__); + return -EINVAL; + } + + memcpy(&dai_data->ttp_config.ttp_gen_cfg, + ucontrol->value.bytes.data, sizeof(struct afe_ttp_gen_cfg_t)); + return 0; +} + static const struct snd_kcontrol_new afe_dec_config_controls[] = { { .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | @@ -3696,6 +3797,27 @@ static const struct snd_kcontrol_new afe_dec_config_controls[] = { msm_dai_q6_afe_output_bit_format_put), }; +static const struct snd_kcontrol_new afe_ttp_config_controls[] = { + { + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_INACTIVE), + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "TTP Enable", + .info = msm_dai_q6_afe_enable_ttp_info, + .get = msm_dai_q6_afe_enable_ttp_get, + .put = msm_dai_q6_afe_enable_ttp_put, + }, + { + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_INACTIVE), + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "AFE TTP config", + .info = msm_dai_q6_afe_ttp_cfg_info, + .get = msm_dai_q6_afe_ttp_cfg_get, + .put = msm_dai_q6_afe_ttp_cfg_put, + }, +}; + static int msm_dai_q6_slim_rx_drift_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -3919,6 +4041,12 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&afe_dec_config_controls[3], dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&afe_ttp_config_controls[0], + dai_data)); + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&afe_ttp_config_controls[1], + dai_data)); break; case RT_PROXY_DAI_001_RX: rc = snd_ctl_add(dai->component->card->snd_card, diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 2586bd56b30e..c9d34c523d5b 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -3924,6 +3924,51 @@ int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) return ret; } +static int q6afe_send_ttp_config(u16 port_id, + union afe_port_config afe_config, + struct afe_ttp_config *ttp_cfg) +{ + struct afe_ttp_gen_enable_t ttp_gen_enable; + struct afe_ttp_gen_cfg_t ttp_gen_cfg; + struct param_hdr_v3 param_hdr; + int ret; + + memset(&ttp_gen_enable, 0, sizeof(ttp_gen_enable)); + memset(&ttp_gen_cfg, 0, sizeof(ttp_gen_cfg)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AFE_MODULE_ID_DECODER; + param_hdr.instance_id = INSTANCE_ID_0; + + pr_debug("%s: Enable TTP generator\n", __func__); + ttp_gen_enable = ttp_cfg->ttp_gen_enable; + param_hdr.param_id = AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE; + param_hdr.param_size = sizeof(struct afe_ttp_gen_enable_t); + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &ttp_gen_enable); + if (ret) { + pr_err("%s: AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + + pr_debug("%s: sending TTP generator config\n", __func__); + ttp_gen_cfg = ttp_cfg->ttp_gen_cfg; + param_hdr.param_id = AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG; + param_hdr.param_size = sizeof(struct afe_ttp_gen_cfg_t); + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &ttp_gen_cfg); + if (ret) + pr_err("%s: AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG for port 0x%x failed %d\n", + __func__, port_id, ret); +exit: + return ret; +} + static int q6afe_send_dec_config(u16 port_id, union afe_port_config afe_config, struct afe_dec_config *cfg, @@ -4594,7 +4639,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, union afe_enc_config_data *enc_cfg, u32 codec_format, u32 scrambler_mode, u32 mono_mode, - struct afe_dec_config *dec_cfg) + struct afe_dec_config *dec_cfg, + struct afe_ttp_config *ttp_cfg) { union afe_port_config port_cfg; struct param_hdr_v3 param_hdr; @@ -4912,6 +4958,15 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, goto fail_cmd; } } + if (ttp_cfg != NULL) { + ret = q6afe_send_ttp_config(port_id, *afe_config, + ttp_cfg); + if (ret) { + pr_err("%s: AFE TTP config for port 0x%x failed %d\n", + __func__, port_id, ret); + goto fail_cmd; + } + } } port_index = afe_get_port_index(port_id); @@ -4958,8 +5013,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate) { - return __afe_port_start(port_id, afe_config, rate, - 0, 0, NULL, ASM_MEDIA_FMT_NONE, 0, 0, NULL); + return __afe_port_start(port_id, afe_config, rate, 0, 0, NULL, + ASM_MEDIA_FMT_NONE, 0, 0, NULL, NULL); } EXPORT_SYMBOL(afe_port_start); @@ -4989,16 +5044,50 @@ int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, afe_in_channels, afe_in_bit_width, &enc_cfg->data, enc_cfg->format, enc_cfg->scrambler_mode, - enc_cfg->mono_mode, dec_cfg); + enc_cfg->mono_mode, dec_cfg, NULL); else if (dec_cfg != NULL) ret = __afe_port_start(port_id, afe_config, rate, afe_in_channels, afe_in_bit_width, - NULL, dec_cfg->format, 0, 0, dec_cfg); + NULL, dec_cfg->format, 0, 0, + dec_cfg, NULL); return ret; } EXPORT_SYMBOL(afe_port_start_v2); +/** + * afe_port_start_v3 - to configure AFE session with + * specified port configuration and encoder /decoder params + * + * @port_id: AFE port id number + * @afe_config: port configuration + * @rate: sampling rate of port + * @enc_cfg: AFE enc configuration information to setup encoder + * @afe_in_channels: AFE input channel configuration, this needs + * update only if input channel is differ from AFE output + * @dec_cfg: AFE dec configuration information to set up decoder + * @ttp_cfg: TTP generator configuration to enable TTP in AFE + * + * Returns 0 on success or error value on port start failure. + */ +int afe_port_start_v3(u16 port_id, union afe_port_config *afe_config, + u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, + struct afe_enc_config *enc_cfg, + struct afe_dec_config *dec_cfg, + struct afe_ttp_config *ttp_cfg) +{ + int ret = 0; + + if (dec_cfg != NULL && ttp_cfg != NULL) + ret = __afe_port_start(port_id, afe_config, rate, + afe_in_channels, afe_in_bit_width, + NULL, dec_cfg->format, 0, 0, + dec_cfg, ttp_cfg); + + return ret; +} +EXPORT_SYMBOL(afe_port_start_v3); + int afe_get_port_index(u16 port_id) { switch (port_id) { diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index cd131cfb2964..681464670409 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -4732,6 +4732,56 @@ struct afe_enc_config { union afe_enc_config_data data; }; +/* + * Enable TTP generator in AFE. + */ +#define AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE 0x000132EF +/* + * Configure TTP generator params in AFE. + */ +#define AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG 0x000132F0 +#define MAX_TTP_OFFSET_PAIRS 4 +struct afe_ttp_gen_enable_t { + uint16_t enable; + uint16_t reserved; +} __packed; + +struct afe_ttp_ssrc_offset_pair_t { + uint32_t ssrc; + uint32_t offset; +} __packed; + +struct afe_ttp_gen_cfg_t { + uint32_t ttp_offset_default; + /* + * TTP offset uses for all other cases + * where no valid SSRC is received. + */ + uint32_t settling_time; + /* + * If settling_mode==0x00: time in [us] + * after first received packet until + * packets are no longer dropped. + */ + uint16_t settling_mode; + /* + * 0x00(Drop), 0x01(Settle) + */ + uint16_t num_ssrc_offsets; + /* + * Number of SSRC/TTPOFFSET pairs to follow + */ + struct afe_ttp_ssrc_offset_pair_t ssrc_ttp_offset[MAX_TTP_OFFSET_PAIRS]; + /* + * Array of ssrc/offset pairs + */ +} __packed; + +struct afe_ttp_config { + struct afe_ttp_gen_enable_t ttp_gen_enable; + struct afe_ttp_gen_cfg_t ttp_gen_cfg; +}; + union afe_dec_config_data { struct asm_sbc_dec_cfg_t sbc_config; struct asm_aac_dec_cfg_v2_t aac_config; diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 3ff3028c46ac..55ae6be1074b 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -402,6 +402,11 @@ int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, struct afe_enc_config *enc_config, struct afe_dec_config *dec_config); +int afe_port_start_v3(u16 port_id, union afe_port_config *afe_config, + u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, + struct afe_enc_config *enc_config, + struct afe_dec_config *dec_config, + struct afe_ttp_config *ttp_config); int afe_spk_prot_feed_back_cfg(int src_port, int dst_port, int l_ch, int r_ch, u32 enable); int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib); -- GitLab From 1434a0a1e4f9c66e8acf4f2b2f7cf364dc65af1d Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Sat, 28 Mar 2020 13:09:08 +0530 Subject: [PATCH 1492/1645] asoc: codecs: Enable impedance detection for rouleur codec Implement the impedance calculation logic for rouleur codec. Change-Id: I2b62e8c1109f949a12d2f31b4c1f6035a1bc2bba Signed-off-by: Aditya Bavanari --- asoc/codecs/rouleur/internal.h | 2 + asoc/codecs/rouleur/rouleur-mbhc.c | 363 ++++++++++-------------- asoc/codecs/rouleur/rouleur-registers.h | 2 +- asoc/codecs/rouleur/rouleur-regmap.c | 2 +- asoc/codecs/rouleur/rouleur-tables.c | 2 +- asoc/codecs/rouleur/rouleur.c | 4 +- 6 files changed, 157 insertions(+), 218 deletions(-) diff --git a/asoc/codecs/rouleur/internal.h b/asoc/codecs/rouleur/internal.h index df8541e34041..233ca519be57 100644 --- a/asoc/codecs/rouleur/internal.h +++ b/asoc/codecs/rouleur/internal.h @@ -170,4 +170,6 @@ extern int rouleur_mbhc_micb_adjust_voltage(struct snd_soc_component *component, extern int rouleur_get_micb_vout_ctl_val(u32 micb_mv); extern int rouleur_micbias_control(struct snd_soc_component *component, int micb_num, int req, bool is_dapm); +extern int rouleur_global_mbias_enable(struct snd_soc_component *component); +extern int rouleur_global_mbias_disable(struct snd_soc_component *component); #endif diff --git a/asoc/codecs/rouleur/rouleur-mbhc.c b/asoc/codecs/rouleur/rouleur-mbhc.c index 8dc959b08917..f0eea091cba5 100644 --- a/asoc/codecs/rouleur/rouleur-mbhc.c +++ b/asoc/codecs/rouleur/rouleur-mbhc.c @@ -22,20 +22,15 @@ #define ROULEUR_ZDET_SUPPORTED true /* Z value defined in milliohm */ -#define ROULEUR_ZDET_VAL_32 32000 -#define ROULEUR_ZDET_VAL_400 400000 -#define ROULEUR_ZDET_VAL_1200 1200000 #define ROULEUR_ZDET_VAL_100K 100000000 /* Z floating defined in ohms */ #define ROULEUR_ZDET_FLOATING_IMPEDANCE 0x0FFFFFFE -#define ROULEUR_ZDET_NUM_MEASUREMENTS 900 -#define ROULEUR_MBHC_GET_C1(c) ((c & 0xC000) >> 14) -#define ROULEUR_MBHC_GET_X1(x) (x & 0x3FFF) -/* Z value compared in milliOhm */ -#define ROULEUR_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000)) -#define ROULEUR_MBHC_ZDET_CONST (86 * 16384) -#define ROULEUR_MBHC_MOISTURE_RREF R_24_KOHM +#define ROULEUR_ZDET_NUM_MEASUREMENTS 100 +#define ROULEUR_ZDET_RMAX 1280000 +#define ROULEUR_ZDET_C1 7500000 +#define ROULEUR_ZDET_C2 187 +#define ROULEUR_ZDET_C3 4500 /* Cross connection thresholds in mV */ #define ROULEUR_HPHL_CROSS_CONN_THRESHOLD 200 @@ -157,9 +152,6 @@ struct rouleur_mbhc_zdet_param { u16 ldo_ctl; u16 noff; u16 nshift; - u16 btn5; - u16 btn6; - u16 btn7; }; static int rouleur_mbhc_request_irq(struct snd_soc_component *component, @@ -380,174 +372,180 @@ static int rouleur_mbhc_micb_ctrl_threshold_mic( return rc; } -static inline void rouleur_mbhc_get_result_params(struct rouleur_priv *rouleur, - s16 *d1_a, u16 noff, - int32_t *zdet) +static void rouleur_mbhc_get_result_params(struct rouleur_priv *rouleur, + struct snd_soc_component *component, + int32_t *zdet) { int i; - int val = 0, val1 = 0; - s16 c1 = 0; - s32 x1 = 0, d1 = 0; - int32_t denom; - int minCode_param[] = { - 3277, 1639, 820, 410, 205, 103, 52, 26 - }; + int zcode = 0, zcode1 = 0, zdet_cal_result = 0, zdet_est_range = 0; + int noff = 0, ndac = 14; + int zdet_cal_coeff = 0, div_ratio = 0; + int num = 0, denom = 0; + /* Charge enable and wait for zcode to be updated */ regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x20, 0x20); for (i = 0; i < ROULEUR_ZDET_NUM_MEASUREMENTS; i++) { - regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &val); - if (val & 0x80) + regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &zcode); + if (zcode & 0x80) break; + usleep_range(200, 210); } - val = val << 0x8; - regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_1, &val1); - val |= val1; - regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x20, 0x00); - x1 = ROULEUR_MBHC_GET_X1(val); - c1 = ROULEUR_MBHC_GET_C1(val); - /* If ramp is not complete, give additional 5ms */ - if ((c1 < 2) && x1) - usleep_range(5000, 5050); - if (!c1 || !x1) { + /* If zcode updation is not complete, give additional 10ms */ + if (!(zcode & 0x80)) + usleep_range(10000, 10100); + + regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &zcode); + if (!(zcode & 0x80)) { dev_dbg(rouleur->dev, - "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n", - __func__, c1, x1); - goto ramp_down; + "%s: Impedance detect calculation error, zcode=0x%x\n", + __func__, zcode); + regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, + 0x20, 0x00); + return; + } + zcode = zcode << 0x8; + zcode = zcode & 0x3FFF; + regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_1, &zcode1); + zcode |= zcode1; + + dev_dbg(rouleur->dev, + "%s: zcode: %d, zcode1: %d\n", __func__, zcode, zcode1); + + /* Calculate calibration coefficient */ + zdet_cal_result = (snd_soc_component_read32(component, + ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT)) & 0x1F; + zdet_cal_coeff = ROULEUR_ZDET_C1 / + ((ROULEUR_ZDET_C2 * zdet_cal_result) + ROULEUR_ZDET_C3); + /* Rload calculation */ + zdet_est_range = (snd_soc_component_read32(component, + ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT) & 0x60) >> 5; + + dev_dbg(rouleur->dev, + "%s: zdet_cal_result: %d, zdet_cal_coeff: %d, zdet_est_range: %d\n", + __func__, zdet_cal_result, zdet_cal_coeff, zdet_est_range); + switch (zdet_est_range) { + case 0: + default: + noff = 0; + div_ratio = 320; + break; + case 1: + noff = 0; + div_ratio = 64; + break; + case 2: + noff = 4; + div_ratio = 64; + break; + case 3: + noff = 5; + div_ratio = 40; + break; } - d1 = d1_a[c1]; - denom = (x1 * d1) - (1 << (14 - noff)); + + num = zdet_cal_coeff * ROULEUR_ZDET_RMAX; + denom = ((zcode * div_ratio * 100) - (1 << (ndac - noff)) * 1000); + dev_dbg(rouleur->dev, + "%s: num: %d, denom: %d\n", __func__, num, denom); if (denom > 0) - *zdet = (ROULEUR_MBHC_ZDET_CONST * 1000) / denom; - else if (x1 < minCode_param[noff]) + *zdet = (int32_t) ((num / denom) * 1000); + else *zdet = ROULEUR_ZDET_FLOATING_IMPEDANCE; - dev_dbg(rouleur->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n", - __func__, d1, c1, x1, *zdet); -ramp_down: - i = 0; - while (x1) { - regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_1, &val); - regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &val1); - val = val << 0x8; - val |= val1; - x1 = ROULEUR_MBHC_GET_X1(val); - i++; - if (i == ROULEUR_ZDET_NUM_MEASUREMENTS) - break; - } + dev_dbg(rouleur->dev, "%s: z_val=%d(milliOhm)\n", + __func__, *zdet); + /* Start discharge */ + regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x20, 0x00); } -#if 0 -static void rouleur_mbhc_zdet_ramp(struct snd_soc_component *component, - struct rouleur_mbhc_zdet_param *zdet_param, - int32_t *zl, int32_t *zr, s16 *d1_a) +static void rouleur_mbhc_zdet_start(struct snd_soc_component *component, + int32_t *zl, int32_t *zr) { struct rouleur_priv *rouleur = dev_get_drvdata(component->dev); int32_t zdet = 0; - snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ZDET_ANA_CTL, - 0x70, zdet_param->ldo_ctl << 4); - snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_BTN5, 0xFC, - zdet_param->btn5); - snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_BTN6, 0xFC, - zdet_param->btn6); - snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_BTN7, 0xFC, - zdet_param->btn7); - snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ZDET_ANA_CTL, - 0x0F, zdet_param->noff); - snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ZDET_RAMP_CTL, - 0x0F, zdet_param->nshift); - if (!zl) goto z_right; - /* Start impedance measurement for HPH_L */ + + /* HPHL pull down switch to force OFF */ + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x30, 0x00); + /* Averaging enable for reliable results */ + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x80, 0x80); + /* ZDET left measurement enable */ regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x80, 0x80); - dev_dbg(rouleur->dev, "%s: ramp for HPH_L, noff = %d\n", - __func__, zdet_param->noff); - rouleur_mbhc_get_result_params(rouleur, d1_a, zdet_param->noff, &zdet); + /* Calculate the left Rload result */ + rouleur_mbhc_get_result_params(rouleur, component, &zdet); + regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x80, 0x00); + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x80, 0x00); + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x30, 0x20); *zl = zdet; z_right: if (!zr) return; - /* Start impedance measurement for HPH_R */ + /* HPHR pull down switch to force OFF */ + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x0C, 0x00); + /* Averaging enable for reliable results */ + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x80, 0x80); + /* ZDET right measurement enable */ regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x40, 0x40); - dev_dbg(rouleur->dev, "%s: ramp for HPH_R, noff = %d\n", - __func__, zdet_param->noff); - rouleur_mbhc_get_result_params(rouleur, d1_a, zdet_param->noff, &zdet); + + /* Calculate the right Rload result */ + rouleur_mbhc_get_result_params(rouleur, component, &zdet); + regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x40, 0x00); + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x80, 0x00); + regmap_update_bits(rouleur->regmap, + ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x0C, 0x08); *zr = zdet; } -static inline void rouleur_wcd_mbhc_qfuse_cal( - struct snd_soc_component *component, - int32_t *z_val, int flag_l_r) -{ - s16 q1; - int q1_cal; - - if (*z_val < (ROULEUR_ZDET_VAL_400/1000)) - q1 = snd_soc_component_read32(component, - ROULEUR_DIGITAL_EFUSE_REG_23 + (2 * flag_l_r)); - else - q1 = snd_soc_component_read32(component, - ROULEUR_DIGITAL_EFUSE_REG_24 + (2 * flag_l_r)); - if (q1 & 0x80) - q1_cal = (10000 - ((q1 & 0x7F) * 25)); - else - q1_cal = (10000 + (q1 * 25)); - if (q1_cal > 0) - *z_val = ((*z_val) * 10000) / q1_cal; -} - static void rouleur_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, uint32_t *zr) { struct snd_soc_component *component = mbhc->component; struct rouleur_priv *rouleur = dev_get_drvdata(component->dev); - s16 reg0, reg1, reg2, reg3, reg4; + s16 reg0; int32_t z1L, z1R, z1Ls; int zMono, z_diff1, z_diff2; bool is_fsm_disable = false; - struct rouleur_mbhc_zdet_param zdet_param[] = { - {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */ - {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */ - {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */ - {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */ - }; - struct rouleur_mbhc_zdet_param *zdet_param_ptr = NULL; - s16 d1_a[][4] = { - {0, 30, 90, 30}, - {0, 30, 30, 5}, - {0, 30, 30, 5}, - {0, 30, 30, 5}, - }; - s16 *d1 = NULL; WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); - reg0 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_BTN5); - reg1 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_BTN6); - reg2 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_BTN7); - reg3 = snd_soc_component_read32(component, ROULEUR_MBHC_CTL_CLK); - reg4 = snd_soc_component_read32(component, - ROULEUR_ANA_MBHC_ZDET_ANA_CTL); + reg0 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_ELECT); - if (snd_soc_component_read32(component, ROULEUR_ANA_MBHC_ELECT) & - 0x80) { + if (reg0 & 0x80) { is_fsm_disable = true; regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ELECT, 0x80, 0x00); } + /* Enable electrical bias */ + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ELECT, + 0x01, 0x01); + + /* Enable codec main bias */ + rouleur_global_mbias_enable(component); + + /* Enable RCO clock */ + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_CTL_1, + 0x80, 0x80); + /* For NO-jack, disable L_DET_EN before Z-det measurements */ if (mbhc->hphl_swh) regmap_update_bits(rouleur->regmap, @@ -557,79 +555,34 @@ static void rouleur_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_MECH, 0x01, 0x00); - /* Disable surge protection before impedance detection. + /* + * Disable surge protection before impedance detection. * This is done to give correct value for high impedance. */ - regmap_update_bits(rouleur->regmap, - ROULEUR_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0x00); + snd_soc_component_update_bits(component, ROULEUR_ANA_SURGE_EN, + 0xC0, 0x00); /* 1ms delay needed after disable surge protection */ usleep_range(1000, 1010); - /* First get impedance on Left */ - d1 = d1_a[1]; - zdet_param_ptr = &zdet_param[1]; - rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1); - - if (!ROULEUR_MBHC_IS_SECOND_RAMP_REQUIRED(z1L)) - goto left_ch_impedance; - - /* Second ramp for left ch */ - if (z1L < ROULEUR_ZDET_VAL_32) { - zdet_param_ptr = &zdet_param[0]; - d1 = d1_a[0]; - } else if ((z1L > ROULEUR_ZDET_VAL_400) && - (z1L <= ROULEUR_ZDET_VAL_1200)) { - zdet_param_ptr = &zdet_param[2]; - d1 = d1_a[2]; - } else if (z1L > ROULEUR_ZDET_VAL_1200) { - zdet_param_ptr = &zdet_param[3]; - d1 = d1_a[3]; - } - rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1); - -left_ch_impedance: + /* Start of left ch impedance calculation */ + rouleur_mbhc_zdet_start(component, &z1L, NULL); if ((z1L == ROULEUR_ZDET_FLOATING_IMPEDANCE) || - (z1L > ROULEUR_ZDET_VAL_100K)) { + (z1L > ROULEUR_ZDET_VAL_100K)) *zl = ROULEUR_ZDET_FLOATING_IMPEDANCE; - zdet_param_ptr = &zdet_param[1]; - d1 = d1_a[1]; - } else { + else *zl = z1L/1000; - rouleur_wcd_mbhc_qfuse_cal(component, zl, 0); - } + dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n", __func__, *zl); - /* Start of right impedance ramp and calculation */ - rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1); - if (ROULEUR_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) { - if (((z1R > ROULEUR_ZDET_VAL_1200) && - (zdet_param_ptr->noff == 0x6)) || - ((*zl) != ROULEUR_ZDET_FLOATING_IMPEDANCE)) - goto right_ch_impedance; - /* Second ramp for right ch */ - if (z1R < ROULEUR_ZDET_VAL_32) { - zdet_param_ptr = &zdet_param[0]; - d1 = d1_a[0]; - } else if ((z1R > ROULEUR_ZDET_VAL_400) && - (z1R <= ROULEUR_ZDET_VAL_1200)) { - zdet_param_ptr = &zdet_param[2]; - d1 = d1_a[2]; - } else if (z1R > ROULEUR_ZDET_VAL_1200) { - zdet_param_ptr = &zdet_param[3]; - d1 = d1_a[3]; - } - rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, - &z1R, d1); - } -right_ch_impedance: + /* Start of right ch impedance calculation */ + rouleur_mbhc_zdet_start(component, NULL, &z1R); if ((z1R == ROULEUR_ZDET_FLOATING_IMPEDANCE) || - (z1R > ROULEUR_ZDET_VAL_100K)) { + (z1R > ROULEUR_ZDET_VAL_100K)) *zr = ROULEUR_ZDET_FLOATING_IMPEDANCE; - } else { + else *zr = z1R/1000; - rouleur_wcd_mbhc_qfuse_cal(component, zr, 1); - } + dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n", __func__, *zr); @@ -651,24 +604,10 @@ static void rouleur_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, mbhc->hph_type = WCD_MBHC_HPH_MONO; goto zdet_complete; } - snd_soc_component_update_bits(component, ROULEUR_HPH_R_ATEST, - 0x02, 0x02); - snd_soc_component_update_bits(component, ROULEUR_HPH_PA_CTL2, - 0x40, 0x01); - if (*zl < (ROULEUR_ZDET_VAL_32/1000)) - rouleur_mbhc_zdet_ramp(component, &zdet_param[0], &z1Ls, - NULL, d1); - else - rouleur_mbhc_zdet_ramp(component, &zdet_param[1], &z1Ls, - NULL, d1); - snd_soc_component_update_bits(component, ROULEUR_HPH_PA_CTL2, - 0x40, 0x00); - snd_soc_component_update_bits(component, ROULEUR_HPH_R_ATEST, - 0x02, 0x00); - z1Ls /= 1000; - rouleur_wcd_mbhc_qfuse_cal(component, &z1Ls, 0); - /* Parallel of left Z and 9 ohm pull down resistor */ - zMono = ((*zl) * 9) / ((*zl) + 9); + + z1Ls = z1L/1000; + /* Parallel of left Z and 20 ohm pull down resistor */ + zMono = ((*zl) * 20) / ((*zl) + 20); z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls); z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl)); if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) { @@ -681,13 +620,10 @@ static void rouleur_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, mbhc->hph_type = WCD_MBHC_HPH_MONO; } +zdet_complete: /* Enable surge protection again after impedance detection */ regmap_update_bits(rouleur->regmap, - ROULEUR_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0xC0); -zdet_complete: - snd_soc_component_write(component, ROULEUR_ANA_MBHC_BTN5, reg0); - snd_soc_component_write(component, ROULEUR_ANA_MBHC_BTN6, reg1); - snd_soc_component_write(component, ROULEUR_ANA_MBHC_BTN7, reg2); + ROULEUR_ANA_SURGE_EN, 0xC0, 0xC0); /* Turn on 100k pull down on HPHL */ regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_MECH, 0x01, 0x01); @@ -697,13 +633,14 @@ static void rouleur_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_MECH, 0x80, 0x80); - snd_soc_component_write(component, ROULEUR_ANA_MBHC_ZDET_ANA_CTL, reg4); - snd_soc_component_write(component, ROULEUR_MBHC_CTL_CLK, reg3); + /* Restore electrical bias state */ + snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ELECT, 0x01, + reg0 >> 7); if (is_fsm_disable) regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ELECT, 0x80, 0x80); + rouleur_global_mbias_disable(component); } -#endif static void rouleur_mbhc_gnd_det_ctrl(struct snd_soc_component *component, bool enable) @@ -843,10 +780,10 @@ static void rouleur_mbhc_comp_autozero_control(struct wcd_mbhc *mbhc, { if (az_enable) snd_soc_component_update_bits(mbhc->component, - ROULEUR_ANA_MBHC_MCLK, 0x08, 0x08); + ROULEUR_ANA_MBHC_CTL_CLK, 0x08, 0x08); else snd_soc_component_update_bits(mbhc->component, - ROULEUR_ANA_MBHC_MCLK, 0x08, 0x00); + ROULEUR_ANA_MBHC_CTL_CLK, 0x08, 0x00); } @@ -889,7 +826,7 @@ static const struct wcd_mbhc_cb mbhc_cb = { .mbhc_micb_ramp_control = rouleur_mbhc_micb_ramp_control, .get_hwdep_fw_cal = rouleur_get_hwdep_fw_cal, .mbhc_micb_ctrl_thr_mic = rouleur_mbhc_micb_ctrl_threshold_mic, - //.compute_impedance = rouleur_wcd_mbhc_calc_impedance, + .compute_impedance = rouleur_wcd_mbhc_calc_impedance, .mbhc_gnd_det_ctrl = rouleur_mbhc_gnd_det_ctrl, .hph_pull_down_ctrl = rouleur_mbhc_hph_pull_down_ctrl, .mbhc_moisture_config = rouleur_mbhc_moisture_config, diff --git a/asoc/codecs/rouleur/rouleur-registers.h b/asoc/codecs/rouleur/rouleur-registers.h index 816e49237dfa..8cc0ae473af0 100644 --- a/asoc/codecs/rouleur/rouleur-registers.h +++ b/asoc/codecs/rouleur/rouleur-registers.h @@ -45,7 +45,7 @@ enum { #define ROULEUR_ANA_MBHC_ZDET_RAMP_CTL (ROULEUR_ANA_BASE_ADDR+0x06A) #define ROULEUR_ANA_MBHC_FSM_STATUS (ROULEUR_ANA_BASE_ADDR+0x06B) #define ROULEUR_ANA_MBHC_ADC_RESULT (ROULEUR_ANA_BASE_ADDR+0x06C) -#define ROULEUR_ANA_MBHC_MCLK (ROULEUR_ANA_BASE_ADDR+0x06D) +#define ROULEUR_ANA_MBHC_CTL_CLK (ROULEUR_ANA_BASE_ADDR+0x06D) #define ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT (ROULEUR_ANA_BASE_ADDR+0x072) #define ROULEUR_ANA_NCP_EN (ROULEUR_ANA_BASE_ADDR+0x077) #define ROULEUR_ANA_HPHPA_CNP_CTL_1 (ROULEUR_ANA_BASE_ADDR+0x083) diff --git a/asoc/codecs/rouleur/rouleur-regmap.c b/asoc/codecs/rouleur/rouleur-regmap.c index 08b490db3a5f..23b8ddc96757 100644 --- a/asoc/codecs/rouleur/rouleur-regmap.c +++ b/asoc/codecs/rouleur/rouleur-regmap.c @@ -38,7 +38,7 @@ static const struct reg_default rouleur_defaults[] = { { ROULEUR_ANA_MBHC_ZDET_RAMP_CTL, 0x00 }, { ROULEUR_ANA_MBHC_FSM_STATUS, 0x00 }, { ROULEUR_ANA_MBHC_ADC_RESULT, 0x00 }, - { ROULEUR_ANA_MBHC_MCLK, 0x30 }, + { ROULEUR_ANA_MBHC_CTL_CLK, 0x30 }, { ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT, 0x00 }, { ROULEUR_ANA_NCP_EN, 0x00 }, { ROULEUR_ANA_HPHPA_CNP_CTL_1, 0x54 }, diff --git a/asoc/codecs/rouleur/rouleur-tables.c b/asoc/codecs/rouleur/rouleur-tables.c index 59b7cf2d3383..7912267dac33 100644 --- a/asoc/codecs/rouleur/rouleur-tables.c +++ b/asoc/codecs/rouleur/rouleur-tables.c @@ -33,7 +33,7 @@ const u8 rouleur_reg_access_analog[ROULEUR_REG( [ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET_RAMP_CTL)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_MBHC_FSM_STATUS)] = RD_REG, [ROULEUR_REG(ROULEUR_ANA_MBHC_ADC_RESULT)] = RD_REG, - [ROULEUR_REG(ROULEUR_ANA_MBHC_MCLK)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_MBHC_CTL_CLK)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT)] = RD_REG, [ROULEUR_REG(ROULEUR_ANA_NCP_EN)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_HPHPA_CNP_CTL_1)] = RD_WR_REG, diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index 01274693c421..480e0ce7a522 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -304,7 +304,7 @@ static int rouleur_rx_connect_port(struct snd_soc_component *component, return ret; } -static int rouleur_global_mbias_enable(struct snd_soc_component *component) +int rouleur_global_mbias_enable(struct snd_soc_component *component) { struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); @@ -322,7 +322,7 @@ static int rouleur_global_mbias_enable(struct snd_soc_component *component) return 0; } -static int rouleur_global_mbias_disable(struct snd_soc_component *component) +int rouleur_global_mbias_disable(struct snd_soc_component *component) { struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); -- GitLab From ef3fa691bd4fae7f00fb52142822140df48f43bd Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 6 Feb 2020 12:53:35 +0530 Subject: [PATCH 1493/1645] config: lito: Disable MI2S, TDM and AUXPCM interfaces Disable MI2S, TDM and AUXPCM interfaces to avoid unnecessary registration of mixer controls and improve performance in loading mixer paths. Change-Id: I093aa1cee9bf6b6e5f17c45e3327deb6fc11018c Signed-off-by: Aditya Bavanari --- config/litoauto.conf | 3 +++ config/litoautoconf.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/config/litoauto.conf b/config/litoauto.conf index d0030bbe4c68..ecf848cfa28c 100644 --- a/config/litoauto.conf +++ b/config/litoauto.conf @@ -38,3 +38,6 @@ CONFIG_SND_SOC_WCD937X=m CONFIG_SND_SOC_WCD937X_SLAVE=m CONFIG_SND_SOC_LITO=m CONFIG_SND_EVENT=m +CONFIG_MI2S_DISABLE=m +CONFIG_TDM_DISABLE=m +CONFIG_AUXPCM_DISABLE=m diff --git a/config/litoautoconf.h b/config/litoautoconf.h index 322ac73a7a49..3c979ccbc805 100644 --- a/config/litoautoconf.h +++ b/config/litoautoconf.h @@ -42,3 +42,6 @@ #define CONFIG_SND_SOC_WCD937X_SLAVE 1 #define CONFIG_SND_SOC_LITO 1 #define CONFIG_SND_EVENT 1 +#define CONFIG_MI2S_DISABLE 1 +#define CONFIG_TDM_DISABLE 1 +#define CONFIG_AUXPCM_DISABLE 1 -- GitLab From 8010a7d6564f224f2f33d23785b7c01300b73e96 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 29 Apr 2020 09:40:56 +0530 Subject: [PATCH 1494/1645] asoc: Add digital mute callback function for cdc dma Add a new digital mute callback function for cdc dma as it uses a different dai structure. Change-Id: I8db4e9610aee0d519ccc50975a779b9d2d8c671e Signed-off-by: Aditya Bavanari --- asoc/msm-dai-q6-v2.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index a0d98959074d..c0051d838d0a 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -2795,7 +2795,6 @@ static int msm_dai_q6_set_channel_map(struct snd_soc_dai *dai, return rc; } -/* all ports with excursion logging requirement can use this digital_mute api */ static int msm_dai_q6_spk_digital_mute(struct snd_soc_dai *dai, int mute) { @@ -12337,7 +12336,8 @@ static int msm_dai_q6_cdc_dma_prepare(struct snd_pcm_substream *substream, static void msm_dai_q6_cdc_dma_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + struct msm_dai_q6_cdc_dma_dai_data *dai_data = + dev_get_drvdata(dai->dev); int rc = 0; if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { @@ -12356,6 +12356,19 @@ static void msm_dai_q6_cdc_dma_shutdown(struct snd_pcm_substream *substream, clear_bit(STATUS_PORT_STARTED, dai_data->hwfree_status); } +static int msm_dai_q6_cdc_dma_digital_mute(struct snd_soc_dai *dai, + int mute) +{ + int port_id = dai->id; + struct msm_dai_q6_cdc_dma_dai_data *dai_data = + dev_get_drvdata(dai->dev); + + if (mute && !dai_data->xt_logging_disable) + afe_get_sp_xt_logging_data(port_id); + + return 0; +} + static struct snd_soc_dai_ops msm_dai_q6_cdc_dma_ops = { .prepare = msm_dai_q6_cdc_dma_prepare, .hw_params = msm_dai_q6_cdc_dma_hw_params, @@ -12368,7 +12381,7 @@ static struct snd_soc_dai_ops msm_dai_q6_cdc_wsa_dma_ops = { .hw_params = msm_dai_q6_cdc_dma_hw_params, .shutdown = msm_dai_q6_cdc_dma_shutdown, .set_channel_map = msm_dai_q6_cdc_dma_set_channel_map, - .digital_mute = msm_dai_q6_spk_digital_mute, + .digital_mute = msm_dai_q6_cdc_dma_digital_mute, }; static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = { -- GitLab From 59fd55ccc0eadcfc99ef3036f9bfbeaf2af1ad61 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Tue, 28 Apr 2020 23:01:55 -0700 Subject: [PATCH 1495/1645] Revert "ASoC: wsa883x: Add support for VBAT monitor" This reverts commit eecf60dcb58fbb2dc75acc834ff8d5edd519c4fa. Change-Id: Id5cd06a70aab59e0bbd83985526078572d126457 --- asoc/codecs/wsa883x/internal.h | 1 - asoc/codecs/wsa883x/wsa883x.c | 53 ---------------------------------- 2 files changed, 54 deletions(-) diff --git a/asoc/codecs/wsa883x/internal.h b/asoc/codecs/wsa883x/internal.h index 1863aacf8992..83cef64a0246 100644 --- a/asoc/codecs/wsa883x/internal.h +++ b/asoc/codecs/wsa883x/internal.h @@ -125,7 +125,6 @@ struct wsa883x_priv { void *handle; int (*register_notifier)(void *handle, struct notifier_block *nblock, bool enable); - struct delayed_work vbat_work; struct cdc_regulator *regulator; int num_supplies; struct regulator_bulk_data *supplies; diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 9e25e53a8bff..cb1b33a9f74a 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -36,11 +36,7 @@ #define HIGH_TEMP_THRESHOLD 45 #define TEMP_INVALID 0xFFFF #define WSA883X_TEMP_RETRY 3 -#define WSA883X_VBAT_TIMER_SEC 2 -static int wsa883x_vbat_timer_sec = WSA883X_VBAT_TIMER_SEC; -module_param(wsa883x_vbat_timer_sec, int, 0664); -MODULE_PARM_DESC(wsa883x_vbat_timer_sec, "timer for VBAT monitor polling"); #define DRV_NAME "wsa-codec" @@ -985,24 +981,9 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, /* Force remove group */ swr_remove_from_group(wsa883x->swr_slave, wsa883x->swr_slave->dev_num); - snd_soc_component_update_bits(component, - WSA883X_VBAT_ADC_FLT_CTL, - 0x0E, 0x06); - snd_soc_component_update_bits(component, - WSA883X_VBAT_ADC_FLT_CTL, - 0x01, 0x01); - schedule_delayed_work(&wsa883x->vbat_work, - msecs_to_jiffies(wsa883x_vbat_timer_sec * 1000)); set_bit(SPKR_STATUS, &wsa883x->status_mask); break; case SND_SOC_DAPM_PRE_PMD: - cancel_delayed_work_sync(&wsa883x->vbat_work); - snd_soc_component_update_bits(component, - WSA883X_VBAT_ADC_FLT_CTL, - 0x01, 0x00); - snd_soc_component_update_bits(component, - WSA883X_VBAT_ADC_FLT_CTL, - 0x0E, 0x00); snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, 0x01, 0x00); wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD); @@ -1172,37 +1153,6 @@ static int wsa883x_get_temperature(struct snd_soc_component *component, return ret; } -static void wsa883x_vbat_monitor_work(struct work_struct *work) -{ - struct wsa883x_priv *wsa883x; - struct delayed_work *dwork; - struct snd_soc_component *component; - u16 val = 0, vbat_code = 0; - int vbat_val = 0; - - dwork = to_delayed_work(work); - wsa883x = container_of(dwork, struct wsa883x_priv, vbat_work); - component = wsa883x->component; - - val = snd_soc_component_read32(component, WSA883X_VBAT_DIN_MSB); - vbat_code = (val << 2); - val = (snd_soc_component_read32(component, WSA883X_VBAT_DIN_LSB) - & 0xC0); - vbat_code |= (val >> 6); - vbat_val = ((vbat_code * 5) / 1023); - dev_dbg(component->dev, "%s: instant vbat code = %d val = %d\n", - __func__, vbat_code, vbat_val); - - val = snd_soc_component_read32(component, WSA883X_VBAT_DOUT); - vbat_val = ((val * 5) / 255); - - dev_dbg(component->dev, "%s: low pass vbat code = %d val = %d\n", - __func__, val, vbat_val); - - schedule_delayed_work(&wsa883x->vbat_work, - msecs_to_jiffies(wsa883x_vbat_timer_sec * 1000)); -} - static int wsa883x_codec_probe(struct snd_soc_component *component) { struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); @@ -1226,7 +1176,6 @@ static int wsa883x_codec_probe(struct snd_soc_component *component) wsa883x_codec_init(component); wsa883x->global_pa_cnt = 0; - INIT_DELAYED_WORK(&wsa883x->vbat_work, wsa883x_vbat_monitor_work); return 0; } @@ -1324,8 +1273,6 @@ static int wsa883x_event_notify(struct notifier_block *nb, switch (event) { case BOLERO_WSA_EVT_PA_OFF_PRE_SSR: - if (delayed_work_pending(&wsa883x->vbat_work)) - cancel_delayed_work_sync(&wsa883x->vbat_work); snd_soc_component_update_bits(wsa883x->component, WSA883X_PA_FSM_CTL, 0x01, 0x00); -- GitLab From 7a01c26dfd6ad611e8a6f236ce23bc5f116f1e3d Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Thu, 9 Apr 2020 17:53:35 +0530 Subject: [PATCH 1496/1645] asoc: codecs: Add default case for switch. Add default case for switch to avoid the Null pointer dereference for the map and num_ports variable in for loop. Change-Id: I59c9dc6e5396bcb409876378c811143da1c81551 Signed-off-by: Prasad Kumpatla --- asoc/codecs/wcd937x/wcd937x.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 30ad7e333e13..d5315c89119c 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -163,6 +163,10 @@ static int wcd937x_set_port_params(struct snd_soc_component *component, map = &wcd937x->tx_port_mapping; num_ports = wcd937x->num_tx_ports; break; + default: + dev_err(component->dev, "%s Invalid path selected %u\n", + __func__, path); + return -EINVAL; } for (i = 0; i <= num_ports; i++) { @@ -207,6 +211,10 @@ static int wcd937x_parse_port_mapping(struct device *dev, map = &wcd937x->tx_port_mapping; num_ports = &wcd937x->num_tx_ports; break; + default: + dev_err(dev, "%s Invalid path selected %u\n", + __func__, path); + return -EINVAL; } if (!of_find_property(dev->of_node, prop, -- GitLab From 4299945ecdee49cc8ca5669a74677933e9e3edbc Mon Sep 17 00:00:00 2001 From: Harshal Ahire Date: Tue, 28 Jan 2020 14:22:01 +0530 Subject: [PATCH 1497/1645] asoc: Add separate array for TDM BE dai links -Register for the widgets and interconnections in routing driver only when the respective interfaces are supported. -Create a separate array for TDM BE dai links. Change-Id: Ic1570ef432c76556aff8c592e12c879aed50e4ef Signed-off-by: Harshal Ahire --- asoc/bengal.c | 245 +++++++++++++++++++++++++--------------- config/bengalauto.conf | 3 + config/bengalautoconf.h | 3 + 3 files changed, 160 insertions(+), 91 deletions(-) diff --git a/asoc/bengal.c b/asoc/bengal.c index 02352a8eb3d3..4c6befdadfb1 100644 --- a/asoc/bengal.c +++ b/asoc/bengal.c @@ -2976,6 +2976,32 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, usb_audio_tx_sample_rate_get, usb_audio_tx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, + usb_audio_rx_format_get, usb_audio_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, + usb_audio_tx_format_get, usb_audio_tx_format_put), + SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, + usb_audio_rx_ch_get, usb_audio_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, + usb_audio_tx_ch_get, usb_audio_tx_ch_put), + SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, + proxy_rx_ch_get, proxy_rx_ch_put), + SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), + SOC_ENUM_EXT("BT SampleRate RX", bt_sample_rate_rx, + msm_bt_sample_rate_rx_get, + msm_bt_sample_rate_rx_put), + SOC_ENUM_EXT("BT SampleRate TX", bt_sample_rate_tx, + msm_bt_sample_rate_tx_get, + msm_bt_sample_rate_tx_put), + SOC_ENUM_EXT("AFE_LOOPBACK_TX Channels", afe_loopback_tx_chs, + afe_loopback_tx_ch_get, afe_loopback_tx_ch_put), + SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, + msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), +}; + +static const struct snd_kcontrol_new msm_tdm_snd_controls[] = { SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, tdm_rx_sample_rate_get, tdm_rx_sample_rate_put), @@ -3000,6 +3026,57 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, tdm_tx_sample_rate_get, tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), +}; + +static const struct snd_kcontrol_new msm_auxpcm_snd_controls[] = { SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, aux_pcm_rx_sample_rate_get, aux_pcm_rx_sample_rate_put), @@ -3024,6 +3101,25 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, aux_pcm_tx_sample_rate_get, aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX Format", aux_pcm_rx_format, + msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX Format", aux_pcm_tx_format, + msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), +}; + +static const struct snd_kcontrol_new msm_mi2s_snd_controls[] = { SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, mi2s_rx_sample_rate_get, mi2s_rx_sample_rate_put), @@ -3035,9 +3131,6 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { mi2s_rx_sample_rate_put), SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, mi2s_rx_sample_rate_get, - mi2s_rx_sample_rate_put), - SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, - mi2s_tx_sample_rate_get, mi2s_tx_sample_rate_put), SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, mi2s_tx_sample_rate_get, @@ -3048,50 +3141,6 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, mi2s_tx_sample_rate_get, mi2s_tx_sample_rate_put), - SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, - usb_audio_rx_format_get, usb_audio_rx_format_put), - SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, - usb_audio_tx_format_get, usb_audio_tx_format_put), - SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, - tdm_rx_format_get, - tdm_rx_format_put), - SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, - tdm_tx_format_get, - tdm_tx_format_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("QUAT_AUX_PCM_RX Format", aux_pcm_rx_format, - msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), - SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), - SOC_ENUM_EXT("QUAT_AUX_PCM_TX Format", aux_pcm_tx_format, - msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put), SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format, msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format, @@ -3108,36 +3157,6 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), SOC_ENUM_EXT("QUAT_MI2S_TX Format", mi2s_tx_format, msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), - SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, - usb_audio_rx_ch_get, usb_audio_rx_ch_put), - SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, - usb_audio_tx_ch_get, usb_audio_tx_ch_put), - SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, - proxy_rx_ch_get, proxy_rx_ch_put), - SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, - tdm_rx_ch_get, - tdm_rx_ch_put), - SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), - SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, - tdm_tx_ch_get, - tdm_tx_ch_put), SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, @@ -3154,19 +3173,6 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = { msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), - SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, - msm_bt_sample_rate_get, - msm_bt_sample_rate_put), - SOC_ENUM_EXT("BT SampleRate RX", bt_sample_rate_rx, - msm_bt_sample_rate_rx_get, - msm_bt_sample_rate_rx_put), - SOC_ENUM_EXT("BT SampleRate TX", bt_sample_rate_tx, - msm_bt_sample_rate_tx_get, - msm_bt_sample_rate_tx_put), - SOC_ENUM_EXT("AFE_LOOPBACK_TX Channels", afe_loopback_tx_chs, - afe_loopback_tx_ch_get, afe_loopback_tx_ch_put), - SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, - msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), }; static const struct snd_kcontrol_new msm_snd_controls[] = { @@ -4214,6 +4220,45 @@ static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) tx_ch, ARRAY_SIZE(rx_ch), rx_ch); } +#ifndef CONFIG_TDM_DISABLE +static void msm_add_tdm_snd_controls(struct snd_soc_component *component) +{ + snd_soc_add_component_controls(component, msm_tdm_snd_controls, + ARRAY_SIZE(msm_tdm_snd_controls)); +} +#else +static void msm_add_tdm_snd_controls(struct snd_soc_component *component) +{ + return; +} +#endif + +#ifndef CONFIG_MI2S_DISABLE +static void msm_add_mi2s_snd_controls(struct snd_soc_component *component) +{ + snd_soc_add_component_controls(component, msm_mi2s_snd_controls, + ARRAY_SIZE(msm_mi2s_snd_controls)); +} +#else +static void msm_add_mi2s_snd_controls(struct snd_soc_component *component) +{ + return; +} +#endif + +#ifndef CONFIG_AUXPCM_DISABLE +static void msm_add_auxpcm_snd_controls(struct snd_soc_component *component) +{ + snd_soc_add_component_controls(component, msm_auxpcm_snd_controls, + ARRAY_SIZE(msm_auxpcm_snd_controls)); +} +#else +static void msm_add_auxpcm_snd_controls(struct snd_soc_component *component) +{ + return; +} +#endif + static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) { int ret = -EINVAL; @@ -4251,6 +4296,10 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) return ret; } + msm_add_tdm_snd_controls(component); + msm_add_mi2s_snd_controls(component); + msm_add_auxpcm_snd_controls(component); + snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets, ARRAY_SIZE(msm_int_dapm_widgets)); @@ -5149,6 +5198,9 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_suspend = 1, }, +}; + +static struct snd_soc_dai_link msm_tdm_be_dai_links[] = { { .name = LPASS_BE_PRI_TDM_RX_0, .stream_name = "Primary TDM0 Playback", @@ -5728,7 +5780,8 @@ static struct snd_soc_dai_link msm_bengal_dai_links[ ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links) + ARRAY_SIZE(msm_va_cdc_dma_be_dai_links) + ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link) + - ARRAY_SIZE(msm_wcn_btfm_be_dai_links)]; + ARRAY_SIZE(msm_wcn_btfm_be_dai_links) + + ARRAY_SIZE(msm_tdm_be_dai_links)]; static int msm_populate_dai_link_component_of_node( struct snd_soc_card *card) @@ -6040,6 +6093,16 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link); } + rc = of_property_read_u32(dev->of_node, "qcom,tdm-audio-intf", + &val); + if (!rc && val) { + memcpy(msm_bengal_dai_links + total_links, + msm_tdm_be_dai_links, + sizeof(msm_tdm_be_dai_links)); + total_links += + ARRAY_SIZE(msm_tdm_be_dai_links); + } + rc = of_property_read_u32(dev->of_node, "qcom,wcn-btfm", &wcn_btfm_intf); if (rc) { diff --git a/config/bengalauto.conf b/config/bengalauto.conf index cd614f66ed54..f9c28daa19b0 100644 --- a/config/bengalauto.conf +++ b/config/bengalauto.conf @@ -36,3 +36,6 @@ CONFIG_SND_SOC_ROULEUR_SLAVE=m CONFIG_PM2250_SPMI=m CONFIG_SND_SOC_BENGAL=m CONFIG_SND_EVENT=m +CONFIG_TDM_DISABLE=m +CONFIG_MI2S_DISABLE=m +CONFIG_AUXPCM_DISABLE=m diff --git a/config/bengalautoconf.h b/config/bengalautoconf.h index 83cca0807411..f14f005fb7a5 100644 --- a/config/bengalautoconf.h +++ b/config/bengalautoconf.h @@ -40,3 +40,6 @@ #define CONFIG_PM2250_SPMI 1 #define CONFIG_SND_SOC_BENGAL 1 #define CONFIG_SND_EVENT 1 +#define CONFIG_TDM_DISABLE 1 +#define CONFIG_MI2S_DISABLE 1 +#define CONFIG_AUXPCM_DISABLE 1 -- GitLab From 8abed769af2e0a112ff6664d8fbdb684b3c338b9 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 16 Apr 2020 11:16:12 +0530 Subject: [PATCH 1498/1645] soc: pinctrl-lpi: Add 100msec before resetting hw votes Add 100msec delay before resetting hw vote counts in SSR up sequence in order to ensure AVS is up when votes are requested. Change-Id: I0f46c60555f6bf833b1cac76f86a54afdcb78ba0 Signed-off-by: Aditya Bavanari --- soc/pinctrl-lpi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index 0b0eef5ab9cc..3258b10f18e8 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -489,6 +490,8 @@ static int lpi_notifier_service_cb(struct notifier_block *this, /* Reset HW votes after SSR */ if (!lpi_dev_up) { + /* Add 100ms sleep to ensure AVS is up after SSR */ + msleep(100); if (state->lpass_core_hw_vote) digital_cdc_rsc_mgr_hw_vote_reset( state->lpass_core_hw_vote); -- GitLab From 21d5ac5462e195606c3ada740628e81f0f8b1710 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 27 Feb 2020 05:26:23 +0530 Subject: [PATCH 1499/1645] ASoC: wsa883x: Update sequence for temperature Update sequence to enable temperature sensor in wsa883x to read proper temperature measurement. Change-Id: I7db16344a92b82539929511bd0de322ed086beb7 Signed-off-by: Sudheer Papothi Signed-off-by: Vangala, Amarnath --- asoc/codecs/wsa883x/wsa883x.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 9e25e53a8bff..0f8abc4aec06 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -849,7 +849,7 @@ static const struct snd_kcontrol_new wsa883x_snd_controls[] = { SOC_SINGLE_EXT("WSA PA Mute", SND_SOC_NOPM, 0, 1, 0, wsa883x_get_mute, wsa883x_set_mute), - SOC_SINGLE_EXT("WSA Temp", SND_SOC_NOPM, 0, 1, 0, + SOC_SINGLE_EXT("WSA Temp", SND_SOC_NOPM, 0, UINT_MAX, 0, wsa_get_temp, NULL), SOC_ENUM_EXT("WSA MODE", wsa_dev_mode_enum, @@ -1079,7 +1079,19 @@ static int32_t wsa883x_temp_reg_read(struct snd_soc_component *component, mutex_lock(&wsa883x->res_lock); - /* TODO Vote for global PA */ + snd_soc_component_update_bits(component, WSA883X_PA_FSM_BYP, + 0x01, 0x01); + snd_soc_component_update_bits(component, WSA883X_PA_FSM_BYP, + 0x04, 0x04); + snd_soc_component_update_bits(component, WSA883X_PA_FSM_BYP, + 0x02, 0x02); + snd_soc_component_update_bits(component, WSA883X_PA_FSM_BYP, + 0x80, 0x80); + snd_soc_component_update_bits(component, WSA883X_PA_FSM_BYP, + 0x20, 0x20); + snd_soc_component_update_bits(component, WSA883X_PA_FSM_BYP, + 0x40, 0x40); + snd_soc_component_update_bits(component, WSA883X_TADC_VALUE_CTL, 0x01, 0x00); wsa_temp_reg->dmeas_msb = snd_soc_component_read32( @@ -1097,7 +1109,8 @@ static int32_t wsa883x_temp_reg_read(struct snd_soc_component *component, wsa_temp_reg->d2_lsb = snd_soc_component_read32( component, WSA883X_OTP_REG_4); - /* TODO Unvote for global PA */ + snd_soc_component_update_bits(component, WSA883X_PA_FSM_BYP, + 0xE7, 0x00); mutex_unlock(&wsa883x->res_lock); return 0; -- GitLab From 1b9c789cd922aadd77963294da01da259dc66193 Mon Sep 17 00:00:00 2001 From: "Vangala, Amarnath" Date: Fri, 8 May 2020 17:59:02 +0530 Subject: [PATCH 1500/1645] ASOC: Sampling rate fix for for WSA_CDC_DMA_TX_0. Removed hardcoding of sampling rate for WSA_CDC_DMA_TX_0. Updated the Sampling rate in the cdc_dmx_tx_cfg table. Change-Id: Ie9a611fbcc364ded53f3c8c668a8acdb40e16327 Signed-off-by: Vangala, Amarnath --- asoc/kona.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index 7560fa99f1fb..33c24f1efd1a 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -647,7 +647,7 @@ static struct dev_config cdc_dma_rx_cfg[] = { /* Default configuration of Codec DMA Interface TX */ static struct dev_config cdc_dma_tx_cfg[] = { - [WSA_CDC_DMA_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [WSA_CDC_DMA_TX_0] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, [WSA_CDC_DMA_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, [WSA_CDC_DMA_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, [TX_CDC_DMA_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, @@ -4430,9 +4430,10 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, break; case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0: + idx = msm_cdc_dma_get_idx_from_beid(dai_link->id); param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_FORMAT_S32_LE); - rate->min = rate->max = SAMPLING_RATE_8KHZ; + rate->min = rate->max = cdc_dma_tx_cfg[idx].sample_rate; channels->min = channels->max = msm_vi_feed_tx_ch; break; -- GitLab From 96975d40a42ffff4e677f5d5e8b96dae4e949690 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Sat, 9 May 2020 11:49:54 +0530 Subject: [PATCH 1501/1645] asoc: codecs: check the spkr status before access the wsa registers Before access the wsa register check the spkr status bit in power-down sequence. Change-Id: I5e07ee56e17701275784fd4c413bc214c5893989 Signed-off-by: Prasad Kumpatla --- asoc/codecs/wsa883x/wsa883x.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 8433185479e4..fa725850538b 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -1274,9 +1274,10 @@ static int wsa883x_event_notify(struct notifier_block *nb, switch (event) { case BOLERO_WSA_EVT_PA_OFF_PRE_SSR: - snd_soc_component_update_bits(wsa883x->component, - WSA883X_PA_FSM_CTL, - 0x01, 0x00); + if (test_bit(SPKR_STATUS, &wsa883x->status_mask)) + snd_soc_component_update_bits(wsa883x->component, + WSA883X_PA_FSM_CTL, + 0x01, 0x00); wsa883x_swr_down(wsa883x); break; -- GitLab From ea6cbeeb1ad818c8c7907252409edb306c81d0ae Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 28 Apr 2020 00:02:32 +0530 Subject: [PATCH 1502/1645] soc: mstr-ctrl: Retain Audio_HM voting until suspend Restore change to retain audio_hm voting and ensure AOP hang issue not seen by masking interrupt wakeup of swr pinctrl pins. Change-Id: I51bf36d6d6b0999abf10a4bc94cce900d1adf1d5 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 2 ++ asoc/codecs/bolero/tx-macro.c | 36 ++++++++++++++++++++++++++-------- asoc/codecs/bolero/va-macro.c | 2 ++ asoc/codecs/bolero/wsa-macro.c | 2 ++ soc/swr-mstr-ctrl.c | 23 ++++++++++++---------- soc/swr-mstr-ctrl.h | 4 ++++ 6 files changed, 51 insertions(+), 18 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 22d636e84c58..c09de8591152 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -378,6 +378,7 @@ struct rx_swr_ctrl_platform_data { void *data), void *swrm_handle, int action); + int (*pinctrl_setup)(void *handle, bool enable); }; enum { @@ -4068,6 +4069,7 @@ static int rx_macro_probe(struct platform_device *pdev) rx_priv->swr_plat_data.clk = rx_swrm_clock; rx_priv->swr_plat_data.core_vote = rx_macro_core_vote; rx_priv->swr_plat_data.handle_irq = NULL; + rx_priv->swr_plat_data.pinctrl_setup = NULL; ret = of_property_read_u8_array(pdev->dev.of_node, "qcom,rx-bcl-pmic-params", bcl_pmic_params, diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index ff941984e897..3d6c33e9d79c 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -81,6 +81,7 @@ struct tx_macro_swr_ctrl_platform_data { void *data), void *swrm_handle, int action); + int (*pinctrl_setup)(void *handle, bool enable); }; enum { @@ -2384,12 +2385,30 @@ static const struct snd_kcontrol_new tx_macro_snd_controls[] = { tx_macro_get_bcs, tx_macro_set_bcs), }; +static int tx_macro_pinctrl_setup(void *handle, bool enable) +{ + struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle; + + if (tx_priv == NULL) { + pr_err("%s: tx priv data is NULL\n", __func__); + return -EINVAL; + } + if (enable) + msm_cdc_pinctrl_set_wakeup_capable( + tx_priv->tx_swr_gpio_p, true); + else + msm_cdc_pinctrl_set_wakeup_capable( + tx_priv->tx_swr_gpio_p, false); + return 0; +} + static int tx_macro_register_event_listener(struct snd_soc_component *component, bool enable, bool is_dmic_sva) { struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; int ret = 0; + u32 dmic_sva = is_dmic_sva; if (!component) return -EINVAL; @@ -2411,17 +2430,17 @@ static int tx_macro_register_event_listener(struct snd_soc_component *component, if (enable) { ret = swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, - SWR_REGISTER_WAKEUP, NULL); - if (!is_dmic_sva) - msm_cdc_pinctrl_set_wakeup_capable( - tx_priv->tx_swr_gpio_p, false); + SWR_REGISTER_WAKEUP, &dmic_sva); + msm_cdc_pinctrl_set_wakeup_capable( + tx_priv->tx_swr_gpio_p, false); } else { - if (!is_dmic_sva) - msm_cdc_pinctrl_set_wakeup_capable( - tx_priv->tx_swr_gpio_p, true); + /* while teardown we can reset the flag */ + dmic_sva = 0; + msm_cdc_pinctrl_set_wakeup_capable( + tx_priv->tx_swr_gpio_p, true); ret = swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, - SWR_DEREGISTER_WAKEUP, NULL); + SWR_DEREGISTER_WAKEUP, &dmic_sva); } } @@ -3230,6 +3249,7 @@ static int tx_macro_probe(struct platform_device *pdev) tx_priv->swr_plat_data.clk = tx_macro_swrm_clock; tx_priv->swr_plat_data.core_vote = tx_macro_core_vote; tx_priv->swr_plat_data.handle_irq = NULL; + tx_priv->swr_plat_data.pinctrl_setup = tx_macro_pinctrl_setup; mutex_init(&tx_priv->swr_clk_lock); } tx_priv->is_used_tx_swr_gpio = is_used_tx_swr_gpio; diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index de834aded74f..f8aae9d3f477 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -130,6 +130,7 @@ struct va_macro_swr_ctrl_platform_data { void *data), void *swrm_handle, int action); + int (*pinctrl_setup)(void *handle, bool enable); }; struct va_macro_priv { @@ -3213,6 +3214,7 @@ static int va_macro_probe(struct platform_device *pdev) va_priv->swr_plat_data.clk = va_macro_swrm_clock; va_priv->swr_plat_data.core_vote = va_macro_core_vote; va_priv->swr_plat_data.handle_irq = NULL; + va_priv->swr_plat_data.pinctrl_setup = NULL; mutex_init(&va_priv->swr_clk_lock); } va_priv->is_used_va_swr_gpio = is_used_va_swr_gpio; diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 1bc8f9d2a1f3..4a158129ae18 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -166,6 +166,7 @@ struct wsa_macro_swr_ctrl_platform_data { void *data), void *swrm_handle, int action); + int (*pinctrl_setup)(void *handle, bool enable); }; struct wsa_macro_bcl_pmic_params { @@ -3195,6 +3196,7 @@ static int wsa_macro_probe(struct platform_device *pdev) wsa_priv->swr_plat_data.clk = wsa_swrm_clock; wsa_priv->swr_plat_data.core_vote = wsa_macro_core_vote; wsa_priv->swr_plat_data.handle_irq = NULL; + wsa_priv->swr_plat_data.pinctrl_setup = NULL; ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id", &default_clk_id); diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 6358437ffb3d..981060cda4cc 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2552,6 +2552,8 @@ static int swrm_probe(struct platform_device *pdev) ret = -EINVAL; goto err_pdata_fail; } + swrm->pinctrl_setup = pdata->pinctrl_setup; + if (of_property_read_u32(pdev->dev.of_node, "qcom,swr-clock-stop-mode0", &swrm->clk_stop_mode0_supp)) { @@ -2873,7 +2875,6 @@ static int swrm_runtime_resume(struct device *dev) int ret = 0; bool swrm_clk_req_err = false; bool hw_core_err = false; - bool aud_core_err = false; struct swr_master *mstr = &swrm->master; struct swr_device *swr_dev; @@ -2891,7 +2892,7 @@ static int swrm_runtime_resume(struct device *dev) if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { dev_err(dev, "%s:lpass audio hw enable failed\n", __func__); - aud_core_err = true; + swrm->aud_core_err = true; } if ((swrm->state == SWR_MSTR_DOWN) || @@ -2910,6 +2911,9 @@ static int swrm_runtime_resume(struct device *dev) irq_get_irq_data(swrm->wake_irq))) disable_irq_nosync(swrm->wake_irq); mutex_unlock(&swrm->irq_lock); + if (swrm->dmic_sva && swrm->pinctrl_setup) + swrm->pinctrl_setup(swrm->handle, + false); } if (swrm->ipc_wakeup) msm_aud_evt_blocking_notifier_call_chain( @@ -2977,7 +2981,7 @@ static int swrm_runtime_resume(struct device *dev) swrm->state = SWR_MSTR_UP; } exit: - if (!aud_core_err) + if (ret && !swrm->aud_core_err) swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); @@ -3000,7 +3004,6 @@ static int swrm_runtime_suspend(struct device *dev) struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); int ret = 0; bool hw_core_err = false; - bool aud_core_err = false; struct swr_master *mstr = &swrm->master; struct swr_device *swr_dev; int current_state = 0; @@ -3019,11 +3022,6 @@ static int swrm_runtime_suspend(struct device *dev) __func__); hw_core_err = true; } - if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { - dev_err(dev, "%s:lpass audio hw enable failed\n", - __func__); - aud_core_err = true; - } if ((current_state == SWR_MSTR_UP) || (current_state == SWR_MSTR_SSR)) { @@ -3108,6 +3106,8 @@ static int swrm_runtime_suspend(struct device *dev) if (swrm->clk_stop_mode0_supp) { if (swrm->wake_irq > 0) { + if (swrm->dmic_sva && swrm->pinctrl_setup) + swrm->pinctrl_setup(swrm->handle, true); enable_irq(swrm->wake_irq); } else if (swrm->ipc_wakeup) { msm_aud_evt_blocking_notifier_call_chain( @@ -3121,10 +3121,11 @@ static int swrm_runtime_suspend(struct device *dev) if (current_state != SWR_MSTR_SSR) swrm->state = SWR_MSTR_DOWN; exit: - if (!aud_core_err) + if (!swrm->aud_core_err) swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); + swrm->aud_core_err = false; mutex_unlock(&swrm->reslock); trace_printk("%s: pm_runtime: suspend done state: %d\n", __func__, swrm->state); @@ -3451,10 +3452,12 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) case SWR_REGISTER_WAKEUP: msm_aud_evt_blocking_notifier_call_chain( SWR_WAKE_IRQ_REGISTER, (void *)swrm); + swrm->dmic_sva = *(u32 *)data; break; case SWR_DEREGISTER_WAKEUP: msm_aud_evt_blocking_notifier_call_chain( SWR_WAKE_IRQ_DEREGISTER, (void *)swrm); + swrm->dmic_sva = 0; break; case SWR_SET_PORT_MAP: if (!data) { diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index ec5bbd2ff533..5439ce6f2820 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -108,6 +108,7 @@ struct swr_ctrl_platform_data { int (*core_vote)(void *handle, bool enable); int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq, void *data), void *swr_handle, int type); + int (*pinctrl_setup)(void *handle, bool enable); }; struct swr_mstr_ctrl { @@ -140,6 +141,7 @@ struct swr_mstr_ctrl { int (*core_vote)(void *handle, bool enable); int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq, void *data), void *swr_handle, int type); + int (*pinctrl_setup)(void *handle, bool enable); int irq; int wake_irq; int version; @@ -165,8 +167,10 @@ struct swr_mstr_ctrl { u32 clk_stop_mode0_supp; struct work_struct wakeup_work; u32 ipc_wakeup; + u32 dmic_sva; bool dev_up; bool ipc_wakeup_triggered; + bool aud_core_err; struct pm_qos_request pm_qos_req; enum swrm_pm_state pm_state; wait_queue_head_t pm_wq; -- GitLab From ea9b7c38f11de3423f249c1a344d6e2d3b2366e0 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Fri, 13 Mar 2020 17:19:56 +0530 Subject: [PATCH 1503/1645] asoc: codecs: Add delay to eliminate playback pause post SSR on hs Add delay in post ssr to eliminate playback pause on euro headset.On post ssr hs detected as hp due to where pa become on before the completion of wcd_correct_swch_plug workqueue which lead to detect plug_type as hp. Change-Id: Ie114fcd0458d9f5edebeee087c90600c3b0c3da2 Signed-off-by: Prasad Kumpatla --- asoc/codecs/wcd937x/internal.h | 1 + asoc/codecs/wcd937x/wcd937x.c | 15 +++++++++++++++ asoc/codecs/wcd938x/internal.h | 1 + asoc/codecs/wcd938x/wcd938x.c | 15 +++++++++++++++ 4 files changed, 32 insertions(+) diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index 381634caf9da..f998bf1f1f75 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -87,6 +87,7 @@ struct wcd937x_priv { int ear_rx_path; int ana_clk_count; struct mutex ana_tx_clk_lock; + bool usbc_hs_status; }; struct wcd937x_micbias_setting { diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index d5315c89119c..6e4f6872959b 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1566,6 +1566,17 @@ static int wcd937x_get_logical_addr(struct swr_device *swr_dev) return 0; } +static bool get_usbc_hs_status(struct snd_soc_component *component, + struct wcd_mbhc_config *mbhc_cfg) +{ + if (mbhc_cfg->enable_usbc_analog) { + if (!(snd_soc_component_read32(component, WCD937X_ANA_MBHC_MECH) + & 0x20)) + return true; + } + return false; +} + static int wcd937x_event_notify(struct notifier_block *block, unsigned long val, void *data) @@ -1601,6 +1612,8 @@ static int wcd937x_event_notify(struct notifier_block *block, case BOLERO_WCD_EVT_SSR_DOWN: wcd937x->mbhc->wcd_mbhc.deinit_in_progress = true; mbhc = &wcd937x->mbhc->wcd_mbhc; + wcd937x->usbc_hs_status = get_usbc_hs_status(component, + mbhc->mbhc_cfg); wcd937x_mbhc_ssr_down(wcd937x->mbhc, component); wcd937x_reset_low(wcd937x->dev); break; @@ -1621,6 +1634,8 @@ static int wcd937x_event_notify(struct notifier_block *block, __func__); } else { wcd937x_mbhc_hs_detect(component, mbhc->mbhc_cfg); + if (wcd937x->usbc_hs_status) + mdelay(500); } wcd937x->mbhc->wcd_mbhc.deinit_in_progress = false; break; diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index f8a47fdba12a..2bc6f1f66167 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -101,6 +101,7 @@ struct wcd938x_priv { int flyback_cur_det_disable; int ear_rx_path; bool dev_up; + bool usbc_hs_status; }; struct wcd938x_micbias_setting { diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 26174dcd9ba2..950f7312a2f4 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1973,6 +1973,17 @@ static int wcd938x_get_logical_addr(struct swr_device *swr_dev) return 0; } +static bool get_usbc_hs_status(struct snd_soc_component *component, + struct wcd_mbhc_config *mbhc_cfg) +{ + if (mbhc_cfg->enable_usbc_analog) { + if (!(snd_soc_component_read32(component, WCD938X_ANA_MBHC_MECH) + & 0x20)) + return true; + } + return false; +} + static int wcd938x_event_notify(struct notifier_block *block, unsigned long val, void *data) @@ -2018,6 +2029,8 @@ static int wcd938x_event_notify(struct notifier_block *block, wcd938x->dev_up = false; wcd938x->mbhc->wcd_mbhc.deinit_in_progress = true; mbhc = &wcd938x->mbhc->wcd_mbhc; + wcd938x->usbc_hs_status = get_usbc_hs_status(component, + mbhc->mbhc_cfg); wcd938x_mbhc_ssr_down(wcd938x->mbhc, component); wcd938x_reset_low(wcd938x->dev); break; @@ -2040,6 +2053,8 @@ static int wcd938x_event_notify(struct notifier_block *block, __func__); } else { wcd938x_mbhc_hs_detect(component, mbhc->mbhc_cfg); + if (wcd938x->usbc_hs_status) + mdelay(500); } wcd938x->mbhc->wcd_mbhc.deinit_in_progress = false; wcd938x->dev_up = true; -- GitLab From f24bc1f9d895afc422b544832104e0aa75af8843 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Wed, 19 Feb 2020 10:23:24 +0530 Subject: [PATCH 1504/1645] dsp: check ac before access the service id Check the audio client and apr before retrieving the service_id and avoid the race condition b/w q6asm_session_free and get_service_id calls with mutex lock. Change-Id: I05c5fb872f866c79c909123b595df345da828967 Signed-off-by: Prasad Kumpatla --- dsp/q6asm.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index e56c7c54f753..235cdbd468ec 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -11000,14 +11000,23 @@ EXPORT_SYMBOL(q6asm_get_path_delay); int q6asm_get_apr_service_id(int session_id) { + int service_id; + pr_debug("%s:\n", __func__); if (session_id <= 0 || session_id > ASM_ACTIVE_STREAMS_ALLOWED) { pr_err("%s: invalid session_id = %d\n", __func__, session_id); return -EINVAL; } - - return ((struct apr_svc *)(session[session_id].ac)->apr)->id; + mutex_lock(&session[session_id].mutex_lock_per_session); + if (session[session_id].ac != NULL) + if ((session[session_id].ac)->apr != NULL) { + service_id = ((struct apr_svc *)(session[session_id].ac)->apr)->id; + mutex_unlock(&session[session_id].mutex_lock_per_session); + return service_id; + } + mutex_unlock(&session[session_id].mutex_lock_per_session); + return -EINVAL; } uint8_t q6asm_get_asm_stream_id(int session_id) -- GitLab From efdb3934ec7eb83731e3c930b8d5948b05c1221e Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Wed, 13 May 2020 18:55:32 +0530 Subject: [PATCH 1505/1645] asoc: codec: Add pre ssr up event for all macros Add a pre ssr up event in all macros ,where GFMUX reset to done before set the dev_up flag to true. Change-Id: I77229ccd0ed68aac841146a89fe7f76961260aea Signed-off-by: Prasad Kumpatla --- asoc/codecs/bolero/bolero-cdc.c | 10 +++++++++- asoc/codecs/bolero/bolero-cdc.h | 1 + asoc/codecs/bolero/rx-macro.c | 12 +++++++----- asoc/codecs/bolero/tx-macro.c | 3 +++ asoc/codecs/bolero/va-macro.c | 6 ++++-- asoc/codecs/bolero/wsa-macro.c | 10 ++++++---- 6 files changed, 30 insertions(+), 12 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index fea1686bddf9..38b12817a77b 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -835,11 +835,19 @@ static int bolero_ssr_enable(struct device *dev, void *data) priv->component, BOLERO_MACRO_EVT_CLK_RESET, 0x0); } + trace_printk("%s: clk count reset\n", __func__); if (priv->rsc_clk_cb) priv->rsc_clk_cb(priv->clk_dev, BOLERO_MACRO_EVT_SSR_GFMUX_UP); - trace_printk("%s: clk count reset\n", __func__); + for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { + if (!priv->macro_params[macro_idx].event_handler) + continue; + priv->macro_params[macro_idx].event_handler( + priv->component, + BOLERO_MACRO_EVT_PRE_SSR_UP, 0x0); + } + regcache_cache_only(priv->regmap, false); mutex_lock(&priv->clk_lock); priv->dev_up = true; diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 7528eaed9974..5e90f27c3a0f 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -54,6 +54,7 @@ enum { BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST, BOLERO_MACRO_EVT_BCS_CLK_OFF, BOLERO_MACRO_EVT_SSR_GFMUX_UP, + BOLERO_MACRO_EVT_PRE_SSR_UP, }; enum { diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 22d636e84c58..87b1e0c154f8 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1388,11 +1388,7 @@ static int rx_macro_event_handler(struct snd_soc_component *component, } } break; - case BOLERO_MACRO_EVT_SSR_UP: - trace_printk("%s, enter SSR up\n", __func__); - rx_priv->dev_up = true; - /* reset swr after ssr/pdr */ - rx_priv->reset_swr = true; + case BOLERO_MACRO_EVT_PRE_SSR_UP: /* enable&disable RX_CORE_CLK to reset GFMUX reg */ ret = bolero_clk_rsc_request_clock(rx_priv->dev, rx_priv->default_clk_id, @@ -1405,6 +1401,12 @@ static int rx_macro_event_handler(struct snd_soc_component *component, bolero_clk_rsc_request_clock(rx_priv->dev, rx_priv->default_clk_id, RX_CORE_CLK, false); + break; + case BOLERO_MACRO_EVT_SSR_UP: + trace_printk("%s, enter SSR up\n", __func__); + rx_priv->dev_up = true; + /* reset swr after ssr/pdr */ + rx_priv->reset_swr = true; if (rx_priv->swr_ctrl_data) swrm_wcd_notify( diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index ff941984e897..4d82efaa7573 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -410,6 +410,9 @@ static int tx_macro_event_handler(struct snd_soc_component *component, else tx_priv->hs_slow_insert_complete = false; break; + default: + pr_debug("%s Invalid Event\n", __func__); + break; } return 0; } diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index de834aded74f..c113d288ca27 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -298,8 +298,7 @@ static int va_macro_event_handler(struct snd_soc_component *component, "%s: va_mclk_users is non-zero still, audio SSR fail!!\n", __func__); break; - case BOLERO_MACRO_EVT_SSR_UP: - trace_printk("%s, enter SSR up\n", __func__); + case BOLERO_MACRO_EVT_PRE_SSR_UP: /* enable&disable VA_CORE_CLK to reset GFMUX reg */ ret = bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, @@ -312,6 +311,9 @@ static int va_macro_event_handler(struct snd_soc_component *component, bolero_clk_rsc_request_clock(va_priv->dev, va_priv->default_clk_id, VA_CORE_CLK, false); + break; + case BOLERO_MACRO_EVT_SSR_UP: + trace_printk("%s, enter SSR up\n", __func__); /* reset swr after ssr/pdr */ va_priv->reset_swr = true; if (va_priv->swr_ctrl_data) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 1bc8f9d2a1f3..8642b3597af1 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -1022,10 +1022,7 @@ static int wsa_macro_event_handler(struct snd_soc_component *component, } } break; - case BOLERO_MACRO_EVT_SSR_UP: - trace_printk("%s, enter SSR up\n", __func__); - /* reset swr after ssr/pdr */ - wsa_priv->reset_swr = true; + case BOLERO_MACRO_EVT_PRE_SSR_UP: /* enable&disable WSA_CORE_CLK to reset GFMUX reg */ ret = bolero_clk_rsc_request_clock(wsa_priv->dev, wsa_priv->default_clk_id, @@ -1038,6 +1035,11 @@ static int wsa_macro_event_handler(struct snd_soc_component *component, bolero_clk_rsc_request_clock(wsa_priv->dev, wsa_priv->default_clk_id, WSA_CORE_CLK, false); + break; + case BOLERO_MACRO_EVT_SSR_UP: + trace_printk("%s, enter SSR up\n", __func__); + /* reset swr after ssr/pdr */ + wsa_priv->reset_swr = true; if (wsa_priv->swr_ctrl_data) swrm_wcd_notify( wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, -- GitLab From 01d2eb25fb24e01baa4a206bf5d115a6e12bdd94 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 13 May 2020 18:44:49 +0530 Subject: [PATCH 1506/1645] asoc: wsa-macro: Fix mixing path on WSA Standalone mixing path on WSA is mute. Enable soundwire path is not happening, add respective call in mixing path widget callback to setup soundwire and WSA. Change-Id: Ia8df0fdcc4a022e4b86c11283dd3606412a2fb69 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/wsa-macro.c | 81 +++++++++++++++++----------------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 4a158129ae18..e0cc3e81c2ea 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -1179,45 +1179,6 @@ static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w, return 0; } -static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_component *component = - snd_soc_dapm_to_component(w->dapm); - u16 gain_reg; - int offset_val = 0; - int val = 0; - - dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name); - - switch (w->reg) { - case BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL: - gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL; - break; - case BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL: - gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL; - break; - default: - dev_err(component->dev, "%s: No gain register avail for %s\n", - __func__, w->name); - return 0; - } - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - val = snd_soc_component_read32(component, gain_reg); - val += offset_val; - snd_soc_component_write(component, gain_reg, val); - break; - case SND_SOC_DAPM_POST_PMD: - snd_soc_component_update_bits(component, - w->reg, 0x20, 0x00); - break; - } - - return 0; -} - static void wsa_macro_hd2_control(struct snd_soc_component *component, u16 reg, int event) { @@ -1304,6 +1265,44 @@ static int wsa_macro_enable_swr(struct snd_soc_dapm_widget *w, return 0; } +static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + u16 gain_reg; + int offset_val = 0; + int val = 0; + + dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name); + + if (!(strcmp(w->name, "WSA_RX0 MIX INP"))) { + gain_reg = BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL; + } else if (!(strcmp(w->name, "WSA_RX1 MIX INP"))) { + gain_reg = BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL; + } else { + dev_err(component->dev, "%s: No gain register avail for %s\n", + __func__, w->name); + return 0; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + wsa_macro_enable_swr(w, kcontrol, event); + val = snd_soc_component_read32(component, gain_reg); + val += offset_val; + snd_soc_component_write(component, gain_reg, val); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, + w->reg, 0x20, 0x00); + wsa_macro_enable_swr(w, kcontrol, event); + break; + } + + return 0; +} + static int wsa_macro_config_compander(struct snd_soc_component *component, int comp, int event) { @@ -2551,7 +2550,7 @@ static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = { SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0, &rx0_prim_inp2_mux, wsa_macro_enable_swr, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL, + SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, 0, 0, &rx0_mix_mux, wsa_macro_enable_mix_path, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0, @@ -2563,7 +2562,7 @@ static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = { SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0, &rx1_prim_inp2_mux, wsa_macro_enable_swr, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL, + SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, 0, 0, &rx1_mix_mux, wsa_macro_enable_mix_path, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MIXER_E("WSA_RX INT0 MIX", SND_SOC_NOPM, -- GitLab From 29bb821fb55c8a32a47d77bfb35b18515f30172b Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 29 Apr 2020 17:57:00 +0530 Subject: [PATCH 1507/1645] asoc: codecs: Update LPM voting support in codec supplies For power saving during RBSC, need to vote for minimum or zero current on load for respective regulator to enter LPM mode. Add required support from audio WCD/WSA to vote accordingly during suspend/resume. Change-Id: I578195b84ba18a0b69dde3b93a3f6461efa85f7f Signed-off-by: Laxminath Kasam --- asoc/codecs/msm-cdc-supply.c | 70 +++++++++++++++++++++++++++++++++- asoc/codecs/wcd938x/internal.h | 1 + asoc/codecs/wcd938x/wcd938x.c | 63 ++++++++++++++++++++++++++++-- asoc/codecs/wsa883x/internal.h | 1 + asoc/codecs/wsa883x/wsa883x.c | 48 ++++++++++++++++++++++- include/asoc/msm-cdc-supply.h | 6 +++ 6 files changed, 182 insertions(+), 7 deletions(-) diff --git a/asoc/codecs/msm-cdc-supply.c b/asoc/codecs/msm-cdc-supply.c index 831562f3af48..0d49c28f1eb9 100644 --- a/asoc/codecs/msm-cdc-supply.c +++ b/asoc/codecs/msm-cdc-supply.c @@ -59,9 +59,22 @@ static int msm_cdc_dt_parse_vreg_info(struct device *dev, } cdc_vreg->optimum_uA = prop_val; - dev_info(dev, "%s: %s: vol=[%d %d]uV, curr=[%d]uA, ond %d\n", + /* Parse supply - LPM or NOM mode(default NOM) */ + snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "qcom,%s-lpm-supported", name); + rc = of_property_read_u32(dev->of_node, prop_name, &prop_val); + if (rc) { + dev_dbg(dev, "%s: Looking up %s property in node %s failed", + __func__, prop_name, dev->of_node->full_name); + cdc_vreg->lpm_supported = 0; + rc = 0; + } else { + cdc_vreg->lpm_supported = prop_val; + } + + dev_info(dev, "%s: %s: vol=[%d %d]uV, curr=[%d]uA, ond %d lpm %d\n", __func__, cdc_vreg->name, cdc_vreg->min_uV, cdc_vreg->max_uV, - cdc_vreg->optimum_uA, cdc_vreg->ondemand); + cdc_vreg->optimum_uA, cdc_vreg->ondemand, + cdc_vreg->lpm_supported); done: return rc; @@ -259,6 +272,59 @@ int msm_cdc_enable_ondemand_supply(struct device *dev, } EXPORT_SYMBOL(msm_cdc_enable_ondemand_supply); +/* + * msm_cdc_set_supplies_lpm_mode: + * Update load for given supply string + * + * @dev: pointer to codec device + * @supplies: pointer to regulator bulk data + * @cdc_vreg: pointer to platform regulator data + * @num_supplies: number of supplies + * @supply_name: supply name to be checked + * @min_max: Apply optimum or 0 current + * + * Return error code if set current fail + */ +int msm_cdc_set_supplies_lpm_mode(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies, + bool flag) +{ + int rc = 0, i; + + if (!supplies) { + pr_err("%s: supplies is NULL\n", + __func__); + return -EINVAL; + } + /* input parameter validation */ + rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies); + if (rc) + return rc; + + for (i = 0; i < num_supplies; i++) { + if (cdc_vreg[i].lpm_supported) { + rc = regulator_set_load( + supplies[i].consumer, + flag ? 0 : cdc_vreg[i].optimum_uA); + if (rc) + dev_err(dev, + "%s: failed to set supply %s to %s, err:%d\n", + __func__, supplies[i].supply, + flag ? "LPM" : "NOM", + rc); + else + dev_dbg(dev, "%s: regulator %s load set to %s\n", + __func__, supplies[i].supply, + flag ? "LPM" : "NOM"); + } + } + + return rc; +} +EXPORT_SYMBOL(msm_cdc_set_supplies_lpm_mode); + /* * msm_cdc_disable_static_supplies: * Disable codec static supplies diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index f8a47fdba12a..c91d54e43832 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -71,6 +71,7 @@ struct wcd938x_priv { bool comp2_enable; bool ldoh; bool bcs_dis; + bool dapm_bias_off; struct irq_domain *virq; struct wcd_irq_info irq_info; u32 rx_clk_cnt; diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 26174dcd9ba2..e88437d2d1c0 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -57,6 +57,7 @@ enum { HPH_COMP_DELAY, HPH_PA_DELAY, AMIC2_BCS_ENABLE, + WCD_SUPPLIES_LPM_MODE, }; enum { @@ -3373,6 +3374,26 @@ static void wcd938x_soc_codec_remove(struct snd_soc_component *component) false); } +static int wcd938x_soc_codec_suspend(struct snd_soc_component *component) +{ + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + if (!wcd938x) + return 0; + wcd938x->dapm_bias_off = true; + return 0; +} + +static int wcd938x_soc_codec_resume(struct snd_soc_component *component) +{ + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + if (!wcd938x) + return 0; + wcd938x->dapm_bias_off = false; + return 0; +} + static struct snd_soc_component_driver soc_codec_dev_wcd938x = { .name = WCD938X_DRV_NAME, .probe = wcd938x_soc_codec_probe, @@ -3383,6 +3404,8 @@ static struct snd_soc_component_driver soc_codec_dev_wcd938x = { .num_dapm_widgets = ARRAY_SIZE(wcd938x_dapm_widgets), .dapm_routes = wcd938x_audio_map, .num_dapm_routes = ARRAY_SIZE(wcd938x_audio_map), + .suspend = wcd938x_soc_codec_suspend, + .resume = wcd938x_soc_codec_resume, }; static int wcd938x_reset(struct device *dev) @@ -3894,19 +3917,51 @@ static int wcd938x_suspend(struct device *dev) } clear_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask); } + if (wcd938x->dapm_bias_off) { + msm_cdc_set_supplies_lpm_mode(wcd938x->dev, + wcd938x->supplies, + pdata->regulator, + pdata->num_supplies, + true); + set_bit(WCD_SUPPLIES_LPM_MODE, &wcd938x->status_mask); + } return 0; } static int wcd938x_resume(struct device *dev) { + struct wcd938x_priv *wcd938x = NULL; + struct wcd938x_pdata *pdata = NULL; + + if (!dev) + return -ENODEV; + + wcd938x = dev_get_drvdata(dev); + if (!wcd938x) + return -EINVAL; + + pdata = dev_get_platdata(wcd938x->dev); + + if (!pdata) { + dev_err(dev, "%s: pdata is NULL\n", __func__); + return -EINVAL; + } + + if (test_bit(WCD_SUPPLIES_LPM_MODE, &wcd938x->status_mask)) { + msm_cdc_set_supplies_lpm_mode(wcd938x->dev, + wcd938x->supplies, + pdata->regulator, + pdata->num_supplies, + false); + clear_bit(WCD_SUPPLIES_LPM_MODE, &wcd938x->status_mask); + } + return 0; } static const struct dev_pm_ops wcd938x_dev_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS( - wcd938x_suspend, - wcd938x_resume - ) + .suspend_late = wcd938x_suspend, + .resume_early = wcd938x_resume, }; #endif diff --git a/asoc/codecs/wsa883x/internal.h b/asoc/codecs/wsa883x/internal.h index 83cef64a0246..d464ecacbf53 100644 --- a/asoc/codecs/wsa883x/internal.h +++ b/asoc/codecs/wsa883x/internal.h @@ -97,6 +97,7 @@ struct wsa883x_priv { bool comp_enable; bool visense_enable; bool ext_vdd_spk; + bool dapm_bias_off; struct swr_port port[WSA883X_MAX_SWR_PORTS]; int global_pa_cnt; int dev_mode; diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index fa725850538b..6b20e4452880 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -116,6 +116,7 @@ enum { enum { SPKR_STATUS = 0, + WSA_SUPPLIES_LPM_MODE, }; enum { @@ -1193,6 +1194,28 @@ static void wsa883x_codec_remove(struct snd_soc_component *component) return; } +static int wsa883x_soc_codec_suspend(struct snd_soc_component *component) +{ + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + if (!wsa883x) + return 0; + + wsa883x->dapm_bias_off = true; + return 0; +} + +static int wsa883x_soc_codec_resume(struct snd_soc_component *component) +{ + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + if (!wsa883x) + return 0; + + wsa883x->dapm_bias_off = false; + return 0; +} + static const struct snd_soc_component_driver soc_codec_dev_wsa883x = { .name = DRV_NAME, .probe = wsa883x_codec_probe, @@ -1203,6 +1226,8 @@ static const struct snd_soc_component_driver soc_codec_dev_wsa883x = { .num_dapm_widgets = ARRAY_SIZE(wsa883x_dapm_widgets), .dapm_routes = wsa883x_audio_map, .num_dapm_routes = ARRAY_SIZE(wsa883x_audio_map), + .suspend = wsa883x_soc_codec_suspend, + .resume = wsa883x_soc_codec_resume, }; static int wsa883x_gpio_ctrl(struct wsa883x_priv *wsa883x, bool enable) @@ -1572,7 +1597,20 @@ static int wsa883x_swr_remove(struct swr_device *pdev) #ifdef CONFIG_PM_SLEEP static int wsa883x_swr_suspend(struct device *dev) { + struct wsa883x_priv *wsa883x = swr_get_dev_data(to_swr_device(dev)); + + if (!wsa883x) { + dev_err(dev, "%s: wsa883x private data is NULL\n", __func__); + return -EINVAL; + } dev_dbg(dev, "%s: system suspend\n", __func__); + if (wsa883x->dapm_bias_off) { + msm_cdc_set_supplies_lpm_mode(dev, wsa883x->supplies, + wsa883x->regulator, + wsa883x->num_supplies, + true); + set_bit(WSA_SUPPLIES_LPM_MODE, &wsa883x->status_mask); + } return 0; } @@ -1584,13 +1622,21 @@ static int wsa883x_swr_resume(struct device *dev) dev_err(dev, "%s: wsa883x private data is NULL\n", __func__); return -EINVAL; } + if (test_bit(WSA_SUPPLIES_LPM_MODE, &wsa883x->status_mask)) { + msm_cdc_set_supplies_lpm_mode(dev, wsa883x->supplies, + wsa883x->regulator, + wsa883x->num_supplies, + false); + clear_bit(WSA_SUPPLIES_LPM_MODE, &wsa883x->status_mask); + } dev_dbg(dev, "%s: system resume\n", __func__); return 0; } #endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops wsa883x_swr_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(wsa883x_swr_suspend, wsa883x_swr_resume) + .suspend_late = wsa883x_swr_suspend, + .resume_early = wsa883x_swr_resume, }; static const struct swr_device_id wsa883x_swr_id[] = { diff --git a/include/asoc/msm-cdc-supply.h b/include/asoc/msm-cdc-supply.h index cff1a4a18c37..336ec22eb495 100644 --- a/include/asoc/msm-cdc-supply.h +++ b/include/asoc/msm-cdc-supply.h @@ -15,6 +15,7 @@ struct cdc_regulator { int max_uV; int optimum_uA; bool ondemand; + bool lpm_supported; struct regulator *regulator; }; @@ -45,6 +46,11 @@ extern int msm_cdc_enable_static_supplies(struct device *dev, struct regulator_bulk_data *supplies, struct cdc_regulator *cdc_vreg, int num_supplies); +extern int msm_cdc_set_supplies_lpm_mode(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies, + bool flag); extern int msm_cdc_init_supplies(struct device *dev, struct regulator_bulk_data **supplies, struct cdc_regulator *cdc_vreg, -- GitLab From e46998406f26d23bdd633a25c9c9513f33eba483 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 20 May 2020 14:12:20 +0530 Subject: [PATCH 1508/1645] asoc: codecs: Update LPM voting support for vdd-mic-bias-supply For power saving during RBSC, need to vote for minimum or zero current on load for respective regulator to enter LPM mode. Add required support from rouleur to vote for mic bias accordingly during suspend/resume. Change-Id: Idb2accbc77241e19f688225081e1b68b99c19e29 Signed-off-by: Aditya Bavanari --- asoc/codecs/rouleur/internal.h | 1 + asoc/codecs/rouleur/rouleur.c | 63 +++++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/rouleur/internal.h b/asoc/codecs/rouleur/internal.h index 233ca519be57..28a4c0c07ca9 100644 --- a/asoc/codecs/rouleur/internal.h +++ b/asoc/codecs/rouleur/internal.h @@ -50,6 +50,7 @@ struct rouleur_priv { bool comp1_enable; bool comp2_enable; + bool dapm_bias_off; struct irq_domain *virq; struct wcd_irq_info irq_info; diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index 480e0ce7a522..bd7141e21354 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -46,6 +46,7 @@ enum { HPH_COMP_DELAY, HPH_PA_DELAY, AMIC2_BCS_ENABLE, + WCD_SUPPLIES_LPM_MODE, }; /* TODO: Check on the step values */ @@ -2046,6 +2047,26 @@ static void rouleur_soc_codec_remove(struct snd_soc_component *component) false); } +static int rouleur_soc_codec_suspend(struct snd_soc_component *component) +{ + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + + if (!rouleur) + return 0; + rouleur->dapm_bias_off = true; + return 0; +} + +static int rouleur_soc_codec_resume(struct snd_soc_component *component) +{ + struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); + + if (!rouleur) + return 0; + rouleur->dapm_bias_off = false; + return 0; +} + static const struct snd_soc_component_driver soc_codec_dev_rouleur = { .name = DRV_NAME, .probe = rouleur_soc_codec_probe, @@ -2056,6 +2077,8 @@ static const struct snd_soc_component_driver soc_codec_dev_rouleur = { .num_dapm_widgets = ARRAY_SIZE(rouleur_dapm_widgets), .dapm_routes = rouleur_audio_map, .num_dapm_routes = ARRAY_SIZE(rouleur_audio_map), + .suspend = rouleur_soc_codec_suspend, + .resume = rouleur_soc_codec_resume, }; #ifdef CONFIG_PM_SLEEP @@ -2092,11 +2115,45 @@ static int rouleur_suspend(struct device *dev) } clear_bit(ALLOW_VPOS_DISABLE, &rouleur->status_mask); } + if (rouleur->dapm_bias_off) { + msm_cdc_set_supplies_lpm_mode(rouleur->dev, + rouleur->supplies, + pdata->regulator, + pdata->num_supplies, + true); + set_bit(WCD_SUPPLIES_LPM_MODE, &rouleur->status_mask); + } return 0; } static int rouleur_resume(struct device *dev) { + struct rouleur_priv *rouleur = NULL; + struct rouleur_pdata *pdata = NULL; + + if (!dev) + return -ENODEV; + + rouleur = dev_get_drvdata(dev); + if (!rouleur) + return -EINVAL; + + pdata = dev_get_platdata(rouleur->dev); + + if (!pdata) { + dev_err(dev, "%s: pdata is NULL\n", __func__); + return -EINVAL; + } + + if (test_bit(WCD_SUPPLIES_LPM_MODE, &rouleur->status_mask)) { + msm_cdc_set_supplies_lpm_mode(rouleur->dev, + rouleur->supplies, + pdata->regulator, + pdata->num_supplies, + false); + clear_bit(WCD_SUPPLIES_LPM_MODE, &rouleur->status_mask); + } + return 0; } #endif @@ -2527,10 +2584,8 @@ static int rouleur_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static const struct dev_pm_ops rouleur_dev_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS( - rouleur_suspend, - rouleur_resume - ) + .suspend_late = rouleur_suspend, + .resume_early = rouleur_resume }; #endif -- GitLab From cf73d419560b2bfff066e77643468de4d4bdc88a Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Tue, 26 May 2020 21:08:21 +0530 Subject: [PATCH 1509/1645] dsp: Fix issues due to accessing array out of bounds Add check for ASM_ACTIVE_STREAMS_ALLOWED sessions to avoid accessing the array out of bounds. Change-Id: I7b2fe2dffdb3132fded0b1e268ebd29139050823 Signed-off-by: Prasad Kumpatla --- dsp/rtac.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/dsp/rtac.c b/dsp/rtac.c index 7c7137e58cfb..c77b5f0971f1 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -957,6 +957,12 @@ void rtac_set_asm_handle(u32 session_id, void *handle) { pr_debug("%s\n", __func__); + if (session_id >= (ASM_ACTIVE_STREAMS_ALLOWED + 1)) { + pr_err_ratelimited("%s: Invalid Session = %d\n", + __func__, session_id); + return; + } + mutex_lock(&rtac_asm_apr_mutex); rtac_asm_apr_data[session_id].apr_handle = handle; mutex_unlock(&rtac_asm_apr_mutex); @@ -965,6 +971,12 @@ void rtac_set_asm_handle(u32 session_id, void *handle) bool rtac_make_asm_callback(u32 session_id, uint32_t *payload, u32 payload_size) { + if (session_id >= (ASM_ACTIVE_STREAMS_ALLOWED + 1)) { + pr_err_ratelimited("%s: Invalid Session = %d\n", + __func__, session_id); + return false; + } + if (atomic_read(&rtac_asm_apr_data[session_id].cmd_state) != 1) return false; -- GitLab From e88db6090a1fb7c772e706d642ea75a17a0eab22 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 27 May 2020 13:09:33 +0530 Subject: [PATCH 1510/1645] asoc: Fix a memory leak issue when nvmem read returns invalid length When nvmem cell read returns invalid length the allocated buffer is not freed. Free the buffer in this scenario to fix memory leak issue. Change-Id: I68585c1dd45b0a40c471bf42dea201cd0ebb497f Signed-off-by: Aditya Bavanari --- asoc/bengal.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/asoc/bengal.c b/asoc/bengal.c index 4c6befdadfb1..1617d3695c49 100644 --- a/asoc/bengal.c +++ b/asoc/bengal.c @@ -6814,10 +6814,16 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) } buf = nvmem_cell_read(cell, &len); nvmem_cell_put(cell); - if (IS_ERR_OR_NULL(buf) || len <= 0 || len > sizeof(32)) { + if (IS_ERR_OR_NULL(buf)) { dev_dbg(&pdev->dev, "%s: FAILED to read nvmem cell \n", __func__); goto ret; } + if (len <= 0 || len > sizeof(u32)) { + dev_dbg(&pdev->dev, "%s: nvmem cell length out of range: %d\n", + __func__, len); + kfree(buf); + goto ret; + } memcpy(&adsp_var_idx, buf, len); kfree(buf); pdata->va_disable = adsp_var_idx; -- GitLab From d34438955c75289f9702823c86c61f6a10cba9c6 Mon Sep 17 00:00:00 2001 From: Kunlei Zhang Date: Wed, 27 May 2020 17:58:10 +0800 Subject: [PATCH 1511/1645] dsp: adm: change channel number for FLUENCE_SM module FLUENCE_SM module in COPreP topology doesn't support stereo input. Update channel number to mono for VPM_TX_VOICE_FLUENCE_SM_COPP_TOPOLOGY. Change-Id: I7de7b49706387b09031f67e1a0271db1825cb81d Signed-off-by: Kunlei Zhang --- dsp/q6adm.c | 3 ++- include/dsp/apr_audio-v2.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 4be8b118836b..f98de7c57b51 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -3082,7 +3082,8 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, this_adm.ffecns_port_id); } - if (topology == VPM_TX_VOICE_SMECNS_V2_COPP_TOPOLOGY) + if (topology == VPM_TX_VOICE_SMECNS_V2_COPP_TOPOLOGY || + topology == VPM_TX_VOICE_FLUENCE_SM_COPP_TOPOLOGY) channel_mode = 1; /* diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 681464670409..ca0f6ddb473c 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -5428,6 +5428,7 @@ struct afe_param_id_lpass_core_shared_clk_cfg { #define COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY 0x00010774 #define VPM_TX_SM_ECNS_V2_COPP_TOPOLOGY 0x00010F89 #define VPM_TX_VOICE_SMECNS_V2_COPP_TOPOLOGY 0x10000003 +#define VPM_TX_VOICE_FLUENCE_SM_COPP_TOPOLOGY 0x10000004 #define VPM_TX_DM_FLUENCE_COPP_TOPOLOGY 0x00010F72 #define VPM_TX_QMIC_FLUENCE_COPP_TOPOLOGY 0x00010F75 #define VPM_TX_DM_RFECNS_COPP_TOPOLOGY 0x00010F86 -- GitLab From 2fe71f51d43d72259ab373ceaa3a4654f1d69747 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 15 May 2020 00:39:51 +0530 Subject: [PATCH 1512/1645] soc: wsa: Fix adie loopback test In ADIE loopback, need PA enable to avoid mute. Ensure PA enable post slave path setup and FS clock. Change-Id: I4df9d7b919325b50f237f31338859e1b5b34b2eb Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc.c | 10 +++++++--- asoc/codecs/bolero/bolero-cdc.h | 4 ++-- asoc/codecs/bolero/internal.h | 3 ++- asoc/codecs/bolero/wsa-macro.c | 11 +++++++---- asoc/codecs/wsa881x.c | 2 ++ asoc/codecs/wsa883x/internal.h | 1 + asoc/codecs/wsa883x/wsa883x.c | 11 ++++++++++- 7 files changed, 31 insertions(+), 11 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 38b12817a77b..afaadf900452 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -735,7 +735,7 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) } EXPORT_SYMBOL(bolero_unregister_macro); -void bolero_wsa_pa_on(struct device *dev) +void bolero_wsa_pa_on(struct device *dev, bool adie_lb) { struct bolero_priv *priv; @@ -753,8 +753,12 @@ void bolero_wsa_pa_on(struct device *dev) dev_err(dev, "%s: priv is null\n", __func__); return; } - - bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_PA_ON_POST_FSCLK); + if (adie_lb) + bolero_cdc_notifier_call(priv, + BOLERO_WCD_EVT_PA_ON_POST_FSCLK_ADIE_LB); + else + bolero_cdc_notifier_call(priv, + BOLERO_WCD_EVT_PA_ON_POST_FSCLK); } EXPORT_SYMBOL(bolero_wsa_pa_on); diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 5e90f27c3a0f..f4af2d920b12 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -118,7 +118,7 @@ int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *dat int bolero_tx_clk_switch(struct snd_soc_component *component, int clk_src); int bolero_register_event_listener(struct snd_soc_component *component, bool enable, bool is_dmic_sva); -void bolero_wsa_pa_on(struct device *dev); +void bolero_wsa_pa_on(struct device *dev, bool adie_lb); bool bolero_check_core_votes(struct device *dev); int bolero_tx_mclk_enable(struct snd_soc_component *c, bool enable); int bolero_get_version(struct device *dev); @@ -196,7 +196,7 @@ static inline int bolero_register_event_listener( return 0; } -static void bolero_wsa_pa_on(struct device *dev) +static void bolero_wsa_pa_on(struct device *dev, bool adie_lb) { } diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 5b3dd4978024..d3a072c9cea9 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #ifndef _BOLERO_INTERNAL_H @@ -16,6 +16,7 @@ enum { BOLERO_WCD_EVT_SSR_DOWN, BOLERO_WCD_EVT_SSR_UP, BOLERO_WCD_EVT_PA_ON_POST_FSCLK, + BOLERO_WCD_EVT_PA_ON_POST_FSCLK_ADIE_LB, }; enum { diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index e67f22ebddfa..fd8a3a84479a 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -846,6 +846,7 @@ static int wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute) uint16_t j = 0, reg = 0, mix_reg = 0, dsm_reg = 0; u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0; u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0; + bool adie_lb = false; if (mute) return 0; @@ -882,7 +883,7 @@ static int wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute) } } } - bolero_wsa_pa_on(wsa_dev); + bolero_wsa_pa_on(wsa_dev, adie_lb); break; default: break; @@ -1473,6 +1474,7 @@ static int wsa_macro_enable_main_path(struct snd_soc_dapm_widget *w, u16 reg = 0; struct device *wsa_dev = NULL; struct wsa_macro_priv *wsa_priv = NULL; + bool adie_lb = false; if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; @@ -1483,9 +1485,10 @@ static int wsa_macro_enable_main_path(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: if (wsa_macro_adie_lb(component, w->shift)) { + adie_lb = true; snd_soc_component_update_bits(component, reg, 0x20, 0x20); - bolero_wsa_pa_on(wsa_dev); + bolero_wsa_pa_on(wsa_dev, adie_lb); } break; default: @@ -2567,10 +2570,10 @@ static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = { SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, 0, 0, &rx1_mix_mux, wsa_macro_enable_mix_path, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER_E("WSA_RX INT0 MIX", SND_SOC_NOPM, + SND_SOC_DAPM_PGA_E("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0, wsa_macro_enable_main_path, SND_SOC_DAPM_PRE_PMU), - SND_SOC_DAPM_MIXER_E("WSA_RX INT1 MIX", SND_SOC_NOPM, + SND_SOC_DAPM_PGA_E("WSA_RX INT1 MIX", SND_SOC_NOPM, 1, 0, NULL, 0, wsa_macro_enable_main_path, SND_SOC_DAPM_PRE_PMU), SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index fe88d805d932..c72fcc1c2c71 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -118,6 +118,7 @@ enum { BOLERO_WSA_EVT_SSR_DOWN, BOLERO_WSA_EVT_SSR_UP, BOLERO_WSA_EVT_PA_ON_POST_FSCLK, + BOLERO_WSA_EVT_PA_ON_POST_FSCLK_ADIE_LB, }; struct wsa_ctrl_platform_data { @@ -1393,6 +1394,7 @@ static int wsa881x_event_notify(struct notifier_block *nb, 0x80, 0x00); break; case BOLERO_WSA_EVT_PA_ON_POST_FSCLK: + case BOLERO_WSA_EVT_PA_ON_POST_FSCLK_ADIE_LB: if ((snd_soc_component_read32(wsa881x->component, WSA881X_SPKR_DAC_CTL) & 0x80) == 0x80) snd_soc_component_update_bits(wsa881x->component, diff --git a/asoc/codecs/wsa883x/internal.h b/asoc/codecs/wsa883x/internal.h index d464ecacbf53..f27b6ca4279f 100644 --- a/asoc/codecs/wsa883x/internal.h +++ b/asoc/codecs/wsa883x/internal.h @@ -66,6 +66,7 @@ enum { BOLERO_WSA_EVT_SSR_DOWN, BOLERO_WSA_EVT_SSR_UP, BOLERO_WSA_EVT_PA_ON_POST_FSCLK, + BOLERO_WSA_EVT_PA_ON_POST_FSCLK_ADIE_LB, }; struct wsa_ctrl_platform_data { diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 6b20e4452880..1c735189d45e 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -117,6 +117,7 @@ enum { enum { SPKR_STATUS = 0, WSA_SUPPLIES_LPM_MODE, + SPKR_ADIE_LB, }; enum { @@ -926,6 +927,7 @@ static int wsa883x_enable_swr_dac_port(struct snd_soc_dapm_widget *w, &port_type[0]); break; case SND_SOC_DAPM_POST_PMU: + set_bit(SPKR_STATUS, &wsa883x->status_mask); break; case SND_SOC_DAPM_PRE_PMD: wsa883x_set_port(component, SWR_DAC_PORT, @@ -983,13 +985,16 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, /* Force remove group */ swr_remove_from_group(wsa883x->swr_slave, wsa883x->swr_slave->dev_num); - set_bit(SPKR_STATUS, &wsa883x->status_mask); + if (test_bit(SPKR_ADIE_LB, &wsa883x->status_mask)) + snd_soc_component_update_bits(component, + WSA883X_PA_FSM_CTL, 0x01, 0x01); break; case SND_SOC_DAPM_PRE_PMD: snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, 0x01, 0x00); wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD); clear_bit(SPKR_STATUS, &wsa883x->status_mask); + clear_bit(SPKR_ADIE_LB, &wsa883x->status_mask); break; } return 0; @@ -1319,6 +1324,10 @@ static int wsa883x_event_notify(struct notifier_block *nb, WSA883X_PA_FSM_CTL, 0x01, 0x01); break; + case BOLERO_WSA_EVT_PA_ON_POST_FSCLK_ADIE_LB: + if (test_bit(SPKR_STATUS, &wsa883x->status_mask)) + set_bit(SPKR_ADIE_LB, &wsa883x->status_mask); + break; default: dev_dbg(wsa883x->dev, "%s: unknown event %d\n", __func__, event); -- GitLab From 64bb44c24c8fcebace3f8cf612773612487d91b4 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 5 May 2020 14:25:35 +0530 Subject: [PATCH 1513/1645] soc: swr-mstr: Avoid overflow during swr fifo read/write Avoid swr fifo overflow by checking no. of outstanding commands in fifo and comparing with fifo depth before every read/write. If no. of commands is equal to fifo depth then give some delay and retry. If no of outstanding commands are still equal to fifo depth then flush fifo and try writing/reading from fifo again. Change-Id: I612203ce6879f5ffcffadc23650f5bba1d45856f Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ soc/swr-mstr-ctrl.h | 2 ++ 2 files changed, 70 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 981060cda4cc..a5808c6a325d 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -84,6 +84,11 @@ enum { LPASS_AUDIO_CORE, }; +enum { + SWRM_WR_CHECK_AVAIL, + SWRM_RD_CHECK_AVAIL, +}; + #define TRUE 1 #define FALSE 0 @@ -742,6 +747,52 @@ static u32 swrm_get_packed_reg_val(u8 *cmd_id, u8 cmd_data, return val; } +static void swrm_wait_for_fifo_avail(struct swr_mstr_ctrl *swrm, int swrm_rd_wr) +{ + u32 fifo_outstanding_cmd; + u8 fifo_retry_count = 10; + + if (swrm_rd_wr) { + /* Check for fifo underflow during read */ + /* Check no of outstanding commands in fifo before read */ + fifo_outstanding_cmd = ((swr_master_read(swrm, + SWRM_CMD_FIFO_STATUS) & 0x001F0000) >> 16); + if (fifo_outstanding_cmd == 0) { + while (fifo_retry_count) { + usleep_range(50, 55); + fifo_outstanding_cmd = + ((swr_master_read (swrm, + SWRM_CMD_FIFO_STATUS) & 0x001F0000) + >> 16); + fifo_retry_count--; + if (fifo_outstanding_cmd > 0) + break; + } + } + if (fifo_outstanding_cmd == 0) + pr_err("%s err read underflow\n", __func__); + } else { + /* Check for fifo overflow during write */ + /* Check no of outstanding commands in fifo before write */ + fifo_outstanding_cmd = ((swr_master_read(swrm, + SWRM_CMD_FIFO_STATUS) & 0x00001F00) + >> 8); + if (fifo_outstanding_cmd == swrm->wr_fifo_depth) { + while (fifo_retry_count) { + usleep_range(50, 55); + fifo_outstanding_cmd = + ((swr_master_read(swrm, SWRM_CMD_FIFO_STATUS) + & 0x00001F00) >> 8); + fifo_retry_count--; + if (fifo_outstanding_cmd < swrm->wr_fifo_depth) + break; + } + } + if (fifo_outstanding_cmd == swrm->wr_fifo_depth) + pr_err("%s err write overflow\n", __func__); + } +} + static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, u8 dev_addr, u8 cmd_id, u16 reg_addr, u32 len) @@ -755,12 +806,19 @@ static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, /* skip delay if read is handled in platform driver */ swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val); } else { + /* + * Check for outstanding cmd wrt. write fifo depth to avoid + * overflow as read will also increase write fifo cnt. + */ + swrm_wait_for_fifo_avail(swrm, SWRM_WR_CHECK_AVAIL); /* wait for FIFO RD to complete to avoid overflow */ usleep_range(100, 105); swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val); /* wait for FIFO RD CMD complete to avoid overflow */ usleep_range(250, 255); } + /* Check if slave responds properly after FIFO RD is complete */ + swrm_wait_for_fifo_avail(swrm, SWRM_RD_CHECK_AVAIL); retry_read: *cmd_data = swr_master_read(swrm, SWRM_CMD_FIFO_RD_FIFO_ADDR); dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, rcmd_id: 0x%x, \ @@ -807,6 +865,11 @@ static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data, dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x,wcmd_id: 0x%x, \ dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, cmd_id, swrm->wcmd_id,dev_addr, cmd_data); + /* + * Check for outstanding cmd wrt. write fifo depth to avoid + * overflow. + */ + swrm_wait_for_fifo_avail(swrm, SWRM_WR_CHECK_AVAIL); swr_master_write(swrm, SWRM_CMD_FIFO_WR_CMD, val); /* * wait for FIFO WR command to complete to avoid overflow @@ -2764,6 +2827,11 @@ static int swrm_probe(struct platform_device *pdev) if (pdev->dev.of_node) of_register_swr_devices(&swrm->master); + swrm->rd_fifo_depth = ((swr_master_read(swrm, SWRM_COMP_PARAMS) + & SWRM_COMP_PARAMS_RD_FIFO_DEPTH) >> 15); + swrm->wr_fifo_depth = ((swr_master_read(swrm, SWRM_COMP_PARAMS) + & SWRM_COMP_PARAMS_WR_FIFO_DEPTH) >> 10); + #ifdef CONFIG_DEBUG_FS swrm->debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0); if (!IS_ERR(swrm->debugfs_swrm_dent)) { diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 5439ce6f2820..326cd8bdf720 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -185,6 +185,8 @@ struct swr_mstr_ctrl { int aud_core_clk_en; int clk_src; u32 disable_div2_clk_switch; + u32 rd_fifo_depth; + u32 wr_fifo_depth; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_swrm_dent; struct dentry *debugfs_peek; -- GitLab From 53d316acc7acc586a90d1ca96d2504100eabeade Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 29 May 2020 09:46:12 +0530 Subject: [PATCH 1514/1645] ASoC: mbhc-adc: Fix fake electrical removal interrupts on rouleur aatc Auto Zero mode needs to be enabled before fsm enable in sw if hw dosen't enable auto zero mode. Do this for measure_adc_once and cross_conn check to resolve fake electrical interrupts after headset insertion. Change-Id: I6915440fbccc84cab1c08710829ca5ca4276b4a5 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd-mbhc-adc.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c index bfb32d121e4b..5865af3dfc9b 100644 --- a/asoc/codecs/wcd-mbhc-adc.c +++ b/asoc/codecs/wcd-mbhc-adc.c @@ -138,7 +138,20 @@ static int wcd_measure_adc_once(struct wcd_mbhc *mbhc, int mux_ctl) WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); /* Set the appropriate MUX selection */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MUX_CTL, mux_ctl); + /* + * Current source mode requires Auto zeroing to be enabled + * automatically. If HW doesn't do it, SW has to take care of this + * for button interrupts to work fine and to avoid + * fake electrical removal interrupts by enabling autozero before FSM + * enable and disable it after FSM enable + */ + if (mbhc->mbhc_cb->mbhc_comp_autozero_control) + mbhc->mbhc_cb->mbhc_comp_autozero_control(mbhc, + true); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); + if (mbhc->mbhc_cb->mbhc_comp_autozero_control) + mbhc->mbhc_cb->mbhc_comp_autozero_control(mbhc, + false); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 1); while (retry--) { @@ -351,8 +364,20 @@ static int wcd_check_cross_conn(struct wcd_mbhc *mbhc) WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); /* Set the MUX selection to Auto */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MUX_CTL, MUX_CTL_AUTO); + /* + * Current source mode requires Auto zeroing to be enabled + * automatically. If HW doesn't do it, SW has to take care of this + * for button interrupts to work fine and to avoid + * fake electrical removal interrupts by enabling autozero before FSM + * enable and disable it after FSM enable + */ + if (mbhc->mbhc_cb->mbhc_comp_autozero_control) + mbhc->mbhc_cb->mbhc_comp_autozero_control(mbhc, + true); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); - + if (mbhc->mbhc_cb->mbhc_comp_autozero_control) + mbhc->mbhc_cb->mbhc_comp_autozero_control(mbhc, + false); /* Restore ADC Enable */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, adc_en); -- GitLab From 94bc9eae4483499d46481f6dcaf9cf9558835ba0 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 21 May 2020 12:04:20 +0530 Subject: [PATCH 1515/1645] ASoC: bengal: Fix euro usbc plug not detected during reboot Euro usbc plug is not detected if we keep headset inserted and reboot target. This is because usbc_swap_gnd_mic function does not get called until mbhc interrupt is generated. Implement late probe so that hs_detect is called after sound card is registered. Change-Id: I8cdf94f3cc14bc625afd3a1e05bbcd25e4f9a7fa Signed-off-by: Vatsal Bucha --- asoc/bengal.c | 88 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 29 deletions(-) diff --git a/asoc/bengal.c b/asoc/bengal.c index 4c6befdadfb1..7c2002815ee2 100644 --- a/asoc/bengal.c +++ b/asoc/bengal.c @@ -5979,6 +5979,62 @@ static const struct of_device_id bengal_asoc_machine_of_match[] = { {}, }; +static int msm_snd_card_bengal_late_probe(struct snd_soc_card *card) +{ + struct snd_soc_component *component; + struct platform_device *pdev = NULL; + char *data = NULL; + int ret = 0, i = 0; + void *mbhc_calibration; + + for (i = 0; i < card->num_aux_devs; i++) + { + if (msm_aux_dev[i].name != NULL ) { + if (strstr(msm_aux_dev[i].name, "wsa")) + continue; + } + + if (msm_aux_dev[i].codec_of_node) { + pdev = of_find_device_by_node( + msm_aux_dev[i].codec_of_node); + if (pdev) { + data = (char*) of_device_get_match_data( + &pdev->dev); + component = soc_find_component( + msm_aux_dev[i].codec_of_node, + NULL); + } + } + } + + if (data != NULL && component != NULL) { + if (!strncmp(data, "wcd937x", sizeof("wcd937x"))) { + mbhc_calibration = def_wcd_mbhc_cal(); + if (!mbhc_calibration) + goto err_mbhc_cal; + wcd_mbhc_cfg.calibration = mbhc_calibration; + ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg); + } else if (!strncmp( data, "rouleur", sizeof("rouleur"))) { + mbhc_calibration = def_rouleur_mbhc_cal(); + if (!mbhc_calibration) + goto err_mbhc_cal; + wcd_mbhc_cfg.calibration = mbhc_calibration; + ret = rouleur_mbhc_hs_detect(component, &wcd_mbhc_cfg); + } + } + + if (ret) { + dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n", + __func__, ret); + goto err_hs_detect; + } + return 0; + +err_hs_detect: + kfree(mbhc_calibration); +err_mbhc_cal: + return ret; +} static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) { struct snd_soc_card *card = NULL; @@ -6137,6 +6193,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) if (card) { card->dai_link = dailink; card->num_links = total_links; + card->late_probe = msm_snd_card_bengal_late_probe; } return card; @@ -6147,7 +6204,6 @@ static int msm_aux_codec_init(struct snd_soc_component *component) struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); int ret = 0; - void *mbhc_calibration; struct snd_info_entry *entry; struct snd_card *card = component->card->snd_card; struct msm_asoc_mach_data *pdata; @@ -6174,7 +6230,7 @@ static int msm_aux_codec_init(struct snd_soc_component *component) dev_dbg(component->dev, "%s: Cannot create codecs module entry\n", __func__); ret = 0; - goto mbhc_cfg_cal; + goto err; } pdata->codec_root = entry; } @@ -6208,33 +6264,7 @@ static int msm_aux_codec_init(struct snd_soc_component *component) } } } - -mbhc_cfg_cal: - if (data != NULL) { - if (!strncmp(data, "wcd937x", sizeof("wcd937x"))) { - mbhc_calibration = def_wcd_mbhc_cal(); - if (!mbhc_calibration) - return -ENOMEM; - wcd_mbhc_cfg.calibration = mbhc_calibration; - ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg); - } else if (!strncmp( data, "rouleur", sizeof("rouleur"))) { - mbhc_calibration = def_rouleur_mbhc_cal(); - if (!mbhc_calibration) - return -ENOMEM; - wcd_mbhc_cfg.calibration = mbhc_calibration; - ret = rouleur_mbhc_hs_detect(component, &wcd_mbhc_cfg); - } - } - - if (ret) { - dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n", - __func__, ret); - goto err_hs_detect; - } - return 0; - -err_hs_detect: - kfree(mbhc_calibration); +err: return ret; } -- GitLab From 3695642785cdbf44f6d8a469ae0c7f5ed3205a18 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 1 Jun 2020 19:23:48 +0530 Subject: [PATCH 1516/1645] Soc: soundwire: Update hw_ctl on HCLK at bootup For soundwire version 1.6, HCLK remove HW controlled at bootup before soundwire frame generation status check. Change-Id: Idc2420d086261766ea4e79f69320f12c4d6b2259 Signed-off-by: Laxminath Kasam --- soc/swr-mstr-ctrl.c | 50 ++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 981060cda4cc..1f61bad5347a 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2337,7 +2337,7 @@ static void swrm_device_wakeup_unvote(struct swr_master *mstr) static int swrm_master_init(struct swr_mstr_ctrl *swrm) { - int ret = 0; + int ret = 0, i = 0; u32 val; u8 row_ctrl = SWR_ROW_50; u8 col_ctrl = SWR_MIN_COL; @@ -2348,6 +2348,18 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) u32 temp = 0; int len = 0; + /* SW workaround to gate hw_ctl for SWR version >=1.6 */ + if (swrm->version >= SWRM_VERSION_1_6) { + if (swrm->swrm_hctl_reg) { + temp = ioread32(swrm->swrm_hctl_reg); + temp &= 0xFFFFFFFD; + iowrite32(temp, swrm->swrm_hctl_reg); + usleep_range(500, 505); + temp = ioread32(swrm->swrm_hctl_reg); + dev_dbg(swrm->dev, "%s: hctl_reg val: 0x%x\n", + __func__, temp); + } + } ssp_period = swrm_get_ssp_period(swrm, SWRM_ROW_50, SWRM_COL_02, SWRM_FRAME_SYNC_SEL); dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period); @@ -2403,6 +2415,13 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) dev_err(swrm->dev, "%s: swr link failed to connect\n", __func__); + for (i = 0; i < len; i++) { + usleep_range(50, 55); + dev_err(swrm->dev, + "%s:reg:0x%x val:0x%x\n", + __func__, + reg[i], swr_master_read(swrm, reg[i])); + } return -EINVAL; } /* @@ -2415,14 +2434,6 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) (swr_master_read(swrm, SWRM_CMD_FIFO_CFG_ADDR) | 0x80000000)); - /* SW workaround to gate hw_ctl for SWR version >=1.6 */ - if (swrm->version >= SWRM_VERSION_1_6) { - if (swrm->swrm_hctl_reg) { - temp = ioread32(swrm->swrm_hctl_reg); - temp &= 0xFFFFFFFD; - iowrite32(temp, swrm->swrm_hctl_reg); - } - } return ret; } @@ -2755,6 +2766,7 @@ static int swrm_probe(struct platform_device *pdev) "%s: Error in master Initialization , err %d\n", __func__, ret); mutex_unlock(&swrm->mlock); + ret = -EPROBE_DEFER; goto err_mstr_init_fail; } @@ -2803,11 +2815,17 @@ static int swrm_probe(struct platform_device *pdev) err_mstr_init_fail: swr_unregister_master(&swrm->master); err_mstr_fail: - if (swrm->reg_irq) + if (swrm->reg_irq) { swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, SWR_IRQ_FREE); - else if (swrm->irq) + } else if (swrm->irq) { free_irq(swrm->irq, swrm); + irqd_set_trigger_type( + irq_get_irq_data(swrm->irq), + IRQ_TYPE_NONE); + } + if (swrm->swr_irq_wakeup_capable) + irq_set_irq_wake(swrm->irq, 0); err_irq_fail: mutex_destroy(&swrm->irq_lock); mutex_destroy(&swrm->mlock); @@ -2827,13 +2845,17 @@ static int swrm_remove(struct platform_device *pdev) { struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); - if (swrm->reg_irq) + if (swrm->reg_irq) { swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, SWR_IRQ_FREE); - else if (swrm->irq) + } else if (swrm->irq) { free_irq(swrm->irq, swrm); - else if (swrm->wake_irq > 0) + irqd_set_trigger_type( + irq_get_irq_data(swrm->irq), + IRQ_TYPE_NONE); + } else if (swrm->wake_irq > 0) { free_irq(swrm->wake_irq, swrm); + } if (swrm->swr_irq_wakeup_capable) irq_set_irq_wake(swrm->irq, 0); cancel_work_sync(&swrm->wakeup_work); -- GitLab From 0905845d8aced5f5997fd999c16c244f9490668e Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 19 May 2020 10:41:35 +0530 Subject: [PATCH 1517/1645] asoc: codecs: Add delay to eliminate playback pause post SSR on hs Add delay in post ssr to eliminate playback pause on euro usbc headset. Post ssr, headset is detected as headphone as HPH PA gets turned ON before the completion of wcd_correct_swch_plug workqueue in MBHC. Change-Id: Ib0334b37aa12b7e7371146b26eb3a1f4484656a3 Signed-off-by: Aditya Bavanari --- asoc/codecs/rouleur/internal.h | 1 + asoc/codecs/rouleur/rouleur.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/asoc/codecs/rouleur/internal.h b/asoc/codecs/rouleur/internal.h index 28a4c0c07ca9..cc1500be70d6 100644 --- a/asoc/codecs/rouleur/internal.h +++ b/asoc/codecs/rouleur/internal.h @@ -84,6 +84,7 @@ struct rouleur_priv { struct mutex rx_clk_lock; struct mutex main_bias_lock; bool dev_up; + bool usbc_hs_status; }; struct rouleur_micbias_setting { diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index bd7141e21354..d2cf31a5100a 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -1342,6 +1342,17 @@ static int rouleur_get_logical_addr(struct swr_device *swr_dev) return 0; } +static bool get_usbc_hs_status(struct snd_soc_component *component, + struct wcd_mbhc_config *mbhc_cfg) +{ + if (mbhc_cfg->enable_usbc_analog) { + if (!(snd_soc_component_read32(component, ROULEUR_ANA_MBHC_MECH) + & 0x20)) + return true; + } + return false; +} + static int rouleur_event_notify(struct notifier_block *block, unsigned long val, void *data) @@ -1374,6 +1385,8 @@ static int rouleur_event_notify(struct notifier_block *block, rouleur->dev_up = false; rouleur->mbhc->wcd_mbhc.deinit_in_progress = true; mbhc = &rouleur->mbhc->wcd_mbhc; + rouleur->usbc_hs_status = get_usbc_hs_status(component, + mbhc->mbhc_cfg); rouleur_mbhc_ssr_down(rouleur->mbhc, component); rouleur_reset(rouleur->dev, 0x01); break; @@ -1395,6 +1408,8 @@ static int rouleur_event_notify(struct notifier_block *block, __func__); } else { rouleur_mbhc_hs_detect(component, mbhc->mbhc_cfg); + if (rouleur->usbc_hs_status) + mdelay(500); } rouleur->mbhc->wcd_mbhc.deinit_in_progress = false; rouleur->dev_up = true; -- GitLab From 4fcf3b4129ea1e6da27f7f00bd3a1ece0fedb80b Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 2 Jun 2020 16:00:14 +0530 Subject: [PATCH 1518/1645] asoc: Use soc_find_component_locked API Use locked version of soc_find_component API to avoid page fault issues. Change-Id: Ie92e502d3ad6a11e33e0977b1a86bd362b83b7cd --- asoc/bengal.c | 4 ++-- asoc/kona.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/asoc/bengal.c b/asoc/bengal.c index 7c2002815ee2..63c4fa26c7cf 100644 --- a/asoc/bengal.c +++ b/asoc/bengal.c @@ -6370,7 +6370,7 @@ static int msm_init_aux_dev(struct platform_device *pdev, ret = -EINVAL; goto err; } - if (soc_find_component(wsa_of_node, NULL)) { + if (soc_find_component_locked(wsa_of_node, NULL)) { /* WSA device registered with ALSA core */ wsa881x_dev_info[found].of_node = wsa_of_node; wsa881x_dev_info[found].index = i; @@ -6467,7 +6467,7 @@ static int msm_init_aux_dev(struct platform_device *pdev, ret = -EINVAL; goto err; } - if (soc_find_component(aux_codec_of_node, NULL)) { + if (soc_find_component_locked(aux_codec_of_node, NULL)) { /* AUX codec registered with ALSA core */ aux_cdc_dev_info[codecs_found].of_node = aux_codec_of_node; diff --git a/asoc/kona.c b/asoc/kona.c index 33c24f1efd1a..6fcf10508a6e 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -7798,7 +7798,7 @@ static int msm_init_aux_dev(struct platform_device *pdev, ret = -EINVAL; goto err; } - if (soc_find_component(wsa_of_node, NULL)) { + if (soc_find_component_locked(wsa_of_node, NULL)) { /* WSA device registered with ALSA core */ wsa881x_dev_info[found].of_node = wsa_of_node; wsa881x_dev_info[found].index = i; @@ -7895,7 +7895,7 @@ static int msm_init_aux_dev(struct platform_device *pdev, ret = -EINVAL; goto err; } - if (soc_find_component(aux_codec_of_node, NULL)) { + if (soc_find_component_locked(aux_codec_of_node, NULL)) { /* AUX codec registered with ALSA core */ aux_cdc_dev_info[codecs_found].of_node = aux_codec_of_node; -- GitLab From a8e2cf6b96aab4979136a88cd94a1fceaf22f54c Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 8 Jun 2020 04:34:47 -0700 Subject: [PATCH 1519/1645] Revert "soc: swr-mstr: Avoid overflow during swr fifo read/write" This reverts commit 96c04bee538a04fa95946dec9e1c81c483643ac2. Change-Id: Icc7e33adce6cff5c284faf351351e8b9febc583f Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 68 --------------------------------------------- soc/swr-mstr-ctrl.h | 2 -- 2 files changed, 70 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index a5808c6a325d..981060cda4cc 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -84,11 +84,6 @@ enum { LPASS_AUDIO_CORE, }; -enum { - SWRM_WR_CHECK_AVAIL, - SWRM_RD_CHECK_AVAIL, -}; - #define TRUE 1 #define FALSE 0 @@ -747,52 +742,6 @@ static u32 swrm_get_packed_reg_val(u8 *cmd_id, u8 cmd_data, return val; } -static void swrm_wait_for_fifo_avail(struct swr_mstr_ctrl *swrm, int swrm_rd_wr) -{ - u32 fifo_outstanding_cmd; - u8 fifo_retry_count = 10; - - if (swrm_rd_wr) { - /* Check for fifo underflow during read */ - /* Check no of outstanding commands in fifo before read */ - fifo_outstanding_cmd = ((swr_master_read(swrm, - SWRM_CMD_FIFO_STATUS) & 0x001F0000) >> 16); - if (fifo_outstanding_cmd == 0) { - while (fifo_retry_count) { - usleep_range(50, 55); - fifo_outstanding_cmd = - ((swr_master_read (swrm, - SWRM_CMD_FIFO_STATUS) & 0x001F0000) - >> 16); - fifo_retry_count--; - if (fifo_outstanding_cmd > 0) - break; - } - } - if (fifo_outstanding_cmd == 0) - pr_err("%s err read underflow\n", __func__); - } else { - /* Check for fifo overflow during write */ - /* Check no of outstanding commands in fifo before write */ - fifo_outstanding_cmd = ((swr_master_read(swrm, - SWRM_CMD_FIFO_STATUS) & 0x00001F00) - >> 8); - if (fifo_outstanding_cmd == swrm->wr_fifo_depth) { - while (fifo_retry_count) { - usleep_range(50, 55); - fifo_outstanding_cmd = - ((swr_master_read(swrm, SWRM_CMD_FIFO_STATUS) - & 0x00001F00) >> 8); - fifo_retry_count--; - if (fifo_outstanding_cmd < swrm->wr_fifo_depth) - break; - } - } - if (fifo_outstanding_cmd == swrm->wr_fifo_depth) - pr_err("%s err write overflow\n", __func__); - } -} - static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, u8 dev_addr, u8 cmd_id, u16 reg_addr, u32 len) @@ -806,19 +755,12 @@ static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, /* skip delay if read is handled in platform driver */ swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val); } else { - /* - * Check for outstanding cmd wrt. write fifo depth to avoid - * overflow as read will also increase write fifo cnt. - */ - swrm_wait_for_fifo_avail(swrm, SWRM_WR_CHECK_AVAIL); /* wait for FIFO RD to complete to avoid overflow */ usleep_range(100, 105); swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val); /* wait for FIFO RD CMD complete to avoid overflow */ usleep_range(250, 255); } - /* Check if slave responds properly after FIFO RD is complete */ - swrm_wait_for_fifo_avail(swrm, SWRM_RD_CHECK_AVAIL); retry_read: *cmd_data = swr_master_read(swrm, SWRM_CMD_FIFO_RD_FIFO_ADDR); dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, rcmd_id: 0x%x, \ @@ -865,11 +807,6 @@ static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data, dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x,wcmd_id: 0x%x, \ dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, cmd_id, swrm->wcmd_id,dev_addr, cmd_data); - /* - * Check for outstanding cmd wrt. write fifo depth to avoid - * overflow. - */ - swrm_wait_for_fifo_avail(swrm, SWRM_WR_CHECK_AVAIL); swr_master_write(swrm, SWRM_CMD_FIFO_WR_CMD, val); /* * wait for FIFO WR command to complete to avoid overflow @@ -2827,11 +2764,6 @@ static int swrm_probe(struct platform_device *pdev) if (pdev->dev.of_node) of_register_swr_devices(&swrm->master); - swrm->rd_fifo_depth = ((swr_master_read(swrm, SWRM_COMP_PARAMS) - & SWRM_COMP_PARAMS_RD_FIFO_DEPTH) >> 15); - swrm->wr_fifo_depth = ((swr_master_read(swrm, SWRM_COMP_PARAMS) - & SWRM_COMP_PARAMS_WR_FIFO_DEPTH) >> 10); - #ifdef CONFIG_DEBUG_FS swrm->debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0); if (!IS_ERR(swrm->debugfs_swrm_dent)) { diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 326cd8bdf720..5439ce6f2820 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -185,8 +185,6 @@ struct swr_mstr_ctrl { int aud_core_clk_en; int clk_src; u32 disable_div2_clk_switch; - u32 rd_fifo_depth; - u32 wr_fifo_depth; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_swrm_dent; struct dentry *debugfs_peek; -- GitLab From be581c2cec81baf613ae8cd1e8cd7e429f3dcc16 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 23 Apr 2020 17:32:17 +0530 Subject: [PATCH 1520/1645] asoc: wsa883x: Fix speaker noise issue Soundwire port is misconfigured and causing noise issue randomly. Ensure reset and powerup WSA speaker amp for every usecase. Change-Id: I857ff2939900ab60ec7208554e340d7d2c693fa9 Signed-off-by: Laxminath Kasam --- asoc/codecs/wsa883x/wsa883x.c | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 1c735189d45e..a2dbea65f9ec 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -1264,6 +1264,19 @@ static int wsa883x_swr_up(struct wsa883x_priv *wsa883x) return ret; } +static int wsa883x_swr_device_up(struct swr_device *pdev) +{ + struct wsa883x_priv *wsa883x; + + wsa883x = swr_get_dev_data(pdev); + if (!wsa883x) { + dev_err(&pdev->dev, "%s: wsa883x is NULL\n", __func__); + return -EINVAL; + } + wsa883x_swr_up(wsa883x); + return 0; +} + static int wsa883x_swr_down(struct wsa883x_priv *wsa883x) { int ret; @@ -1275,6 +1288,19 @@ static int wsa883x_swr_down(struct wsa883x_priv *wsa883x) return ret; } +static int wsa883x_swr_device_down(struct swr_device *pdev) +{ + struct wsa883x_priv *wsa883x; + + wsa883x = swr_get_dev_data(pdev); + if (!wsa883x) { + dev_err(&pdev->dev, "%s: wsa883x is NULL\n", __func__); + return -EINVAL; + } + wsa883x_swr_down(wsa883x); + return 0; +} + static int wsa883x_swr_reset(struct wsa883x_priv *wsa883x) { u8 retry = WSA883X_NUM_RETRY; @@ -1292,6 +1318,19 @@ static int wsa883x_swr_reset(struct wsa883x_priv *wsa883x) return 0; } +static int wsa883x_swr_device_reset(struct swr_device *pdev) +{ + struct wsa883x_priv *wsa883x; + + wsa883x = swr_get_dev_data(pdev); + if (!wsa883x) { + dev_err(&pdev->dev, "%s: wsa883x is NULL\n", __func__); + return -EINVAL; + } + wsa883x_swr_reset(wsa883x); + return 0; +} + static int wsa883x_event_notify(struct notifier_block *nb, unsigned long val, void *ptr) { @@ -1670,6 +1709,9 @@ static struct swr_driver wsa883x_swr_driver = { .probe = wsa883x_swr_probe, .remove = wsa883x_swr_remove, .id_table = wsa883x_swr_id, + .device_up = wsa883x_swr_device_up, + .device_down = wsa883x_swr_device_down, + .reset_device = wsa883x_swr_device_reset, }; static int __init wsa883x_swr_init(void) -- GitLab From 4bfe0fe94070acf5e7cbf47719068d7e65f33c4e Mon Sep 17 00:00:00 2001 From: Kunlei Zhang Date: Fri, 6 Mar 2020 21:20:07 +0800 Subject: [PATCH 1521/1645] asoc: update tx frame config for soundwire port Set correct tx frame config for soundwire port using wcd9375. Change-Id: Icbefda65713338908e4d94935296ff30ac4e5f9c Signed-off-by: Kunlei Zhang --- asoc/codecs/wcd938x/wcd938x.c | 2 +- asoc/kona-port-config.h | 15 +++++++++ asoc/kona.c | 57 +++++++++++++++++++++++++++++------ 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 79a95c03d76f..3f6292c95849 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -3722,7 +3722,7 @@ static void wcd938x_unbind(struct device *dev) } static const struct of_device_id wcd938x_dt_match[] = { - { .compatible = "qcom,wcd938x-codec" }, + { .compatible = "qcom,wcd938x-codec", .data = "wcd938x"}, {} }; diff --git a/asoc/kona-port-config.h b/asoc/kona-port-config.h index 723c94a7dde3..6ab1d29ca0ba 100644 --- a/asoc/kona-port-config.h +++ b/asoc/kona-port-config.h @@ -59,6 +59,14 @@ static struct port_params tx_frame_params_v2[SWR_MSTR_PORT_LEN] = { {3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2}, /* TX4 */ }; +static struct port_params tx_frame_params_wcd937x[SWR_MSTR_PORT_LEN] = { + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, + {3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, + {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, + {3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, +}; + static struct swr_mstr_port_map sm_port_map[] = { {TX_MACRO, SWR_UC0, tx_frame_params_default}, {RX_MACRO, SWR_UC0, rx_frame_params_default}, @@ -73,4 +81,11 @@ static struct swr_mstr_port_map sm_port_map_v2[] = { {WSA_MACRO, SWR_UC0, wsa_frame_params_default}, }; +static struct swr_mstr_port_map sm_port_map_wcd937x[] = { + {TX_MACRO, SWR_UC0, tx_frame_params_wcd937x}, + {RX_MACRO, SWR_UC0, rx_frame_params_default}, + {RX_MACRO, SWR_UC1, rx_frame_params_dsd}, + {WSA_MACRO, SWR_UC0, wsa_frame_params_default}, +}; + #endif /* _KONA_PORT_CONFIG */ diff --git a/asoc/kona.c b/asoc/kona.c index 33c24f1efd1a..bff29eb6f36a 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -5371,6 +5371,9 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) struct snd_card *card; struct snd_info_entry *entry; struct snd_soc_component *aux_comp; + struct platform_device *pdev = NULL; + int i = 0; + char *data = NULL; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); @@ -5447,18 +5450,52 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) WSA_MACRO_GAIN_OFFSET_M1P5_DB); } } - if (pdata->lito_v2_enabled) { - /* - * Enable tx data line3 for saipan version v2 amd - * write corresponding lpi register. - */ - bolero_set_port_map(component, ARRAY_SIZE(sm_port_map_v2), - sm_port_map_v2); - } else { - bolero_set_port_map(component, ARRAY_SIZE(sm_port_map), - sm_port_map); + } + + for (i = 0; i < rtd->card->num_aux_devs; i++) + { + if (msm_aux_dev[i].name != NULL ) { + if (strstr(msm_aux_dev[i].name, "wsa")) + continue; + } + + if (msm_aux_dev[i].codec_of_node) { + pdev = of_find_device_by_node( + msm_aux_dev[i].codec_of_node); + + if (pdev) + data = (char*) of_device_get_match_data( + &pdev->dev); + if (data != NULL) { + if (!strncmp(data, "wcd937x", + sizeof("wcd937x"))) { + bolero_set_port_map(component, + ARRAY_SIZE(sm_port_map_wcd937x), + sm_port_map_wcd937x); + break; + } else if (!strncmp( data, "wcd938x", + sizeof("wcd938x"))) { + if (pdata->lito_v2_enabled) { + /* + * Enable tx data line3 for + * saipan version v2 and + * write corresponding + * lpi register. + */ + bolero_set_port_map(component, + ARRAY_SIZE(sm_port_map_v2), + sm_port_map_v2); + } else { + bolero_set_port_map(component, + ARRAY_SIZE(sm_port_map), + sm_port_map); + } + break; + } + } } } + card = rtd->card->snd_card; if (!pdata->codec_root) { entry = snd_info_create_subdir(card->module, "codecs", -- GitLab From f61a23138f9198906c2e7311a2a9580d6c2f53aa Mon Sep 17 00:00:00 2001 From: Kunlei Zhang Date: Tue, 11 Feb 2020 15:37:03 +0800 Subject: [PATCH 1522/1645] asoc: add wcd937x codec support in machine driver Add wcd937x codec support in machine driver for lagoon. Change-Id: Ie28579713aa99f28f447494e735f678ab6a72e0c Signed-off-by: Kunlei Zhang --- asoc/kona.c | 85 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 12 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index 33c24f1efd1a..80ddda41e2d7 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -33,6 +33,8 @@ #include "codecs/wsa881x.h" #include "codecs/wsa883x/wsa883x.h" #include "codecs/wcd938x/wcd938x.h" +#include "codecs/wcd937x/wcd937x-mbhc.h" +#include "codecs/wcd937x/wcd937x.h" #include "codecs/bolero/bolero-cdc.h" #include #include "codecs/bolero/wsa-macro.h" @@ -860,6 +862,23 @@ static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc85_dma_rx_3_sample_rate, static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc85_dma_rx_5_sample_rate, cdc_dma_sample_rate_text); +/* WCD937x */ +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_sample_rate, + cdc_dma_sample_rate_text); + static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, @@ -3685,6 +3704,39 @@ static const struct snd_kcontrol_new msm_int_wcd9385_snd_controls[] = { cdc_dma_rx_sample_rate_put), }; +static const struct snd_kcontrol_new msm_int_wcd937x_snd_controls[] = { + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 Format", rx_cdc_dma_rx_0_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 Format", rx_cdc_dma_rx_1_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 Format", rx_cdc_dma_rx_2_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 Format", rx_cdc_dma_rx_3_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 Format", rx_cdc_dma_rx_5_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 SampleRate", + rx_cdc_dma_rx_0_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 SampleRate", + rx_cdc_dma_rx_1_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 SampleRate", + rx_cdc_dma_rx_2_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 SampleRate", + rx_cdc_dma_rx_3_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 SampleRate", + rx_cdc_dma_rx_5_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), +}; + static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, usb_audio_rx_sample_rate_get, @@ -7659,18 +7711,24 @@ static int msm_aux_codec_init(struct snd_soc_component *component) } pdata->codec_root = entry; } - wcd938x_info_create_codec_entry(pdata->codec_root, component); - - codec_variant = wcd938x_get_codec_variant(component); - dev_dbg(component->dev, "%s: variant %d\n", __func__, codec_variant); - if (codec_variant == WCD9380) + if (!strncmp(component->driver->name, "wcd937x", 7)) { + wcd937x_info_create_codec_entry(pdata->codec_root, component); ret = snd_soc_add_component_controls(component, - msm_int_wcd9380_snd_controls, - ARRAY_SIZE(msm_int_wcd9380_snd_controls)); - else if (codec_variant == WCD9385) - ret = snd_soc_add_component_controls(component, - msm_int_wcd9385_snd_controls, - ARRAY_SIZE(msm_int_wcd9385_snd_controls)); + msm_int_wcd937x_snd_controls, + ARRAY_SIZE(msm_int_wcd937x_snd_controls)); + } else { + wcd938x_info_create_codec_entry(pdata->codec_root, component); + codec_variant = wcd938x_get_codec_variant(component); + dev_dbg(component->dev, "%s: variant %d\n", __func__, codec_variant); + if (codec_variant == WCD9380) + ret = snd_soc_add_component_controls(component, + msm_int_wcd9380_snd_controls, + ARRAY_SIZE(msm_int_wcd9380_snd_controls)); + else if (codec_variant == WCD9385) + ret = snd_soc_add_component_controls(component, + msm_int_wcd9385_snd_controls, + ARRAY_SIZE(msm_int_wcd9385_snd_controls)); + } if (ret < 0) { dev_err(component->dev, "%s: add codec specific snd controls failed: %d\n", @@ -7683,7 +7741,10 @@ static int msm_aux_codec_init(struct snd_soc_component *component) if (!mbhc_calibration) return -ENOMEM; wcd_mbhc_cfg.calibration = mbhc_calibration; - ret = wcd938x_mbhc_hs_detect(component, &wcd_mbhc_cfg); + if (!strncmp(component->driver->name, "wcd937x", 7)) + ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg); + else + ret = wcd938x_mbhc_hs_detect(component, &wcd_mbhc_cfg); if (ret) { dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n", __func__, ret); -- GitLab From bd68a7c023d559a1a2ba24ae09c134a015d61047 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 8 Jun 2020 10:41:56 +0530 Subject: [PATCH 1523/1645] soc: swr-mstr: Fix headset detection during sva clk switch Headset insertion/removal is not detected sometime due to fifo read failure due to swr underflow. This is because if headset sva is enabled, during clk switch swr force stop happens and if mbhc has already taken pm vote for 3sec further mbhc reads/writes will fail. If swr is in clk switch mode then call swrm runtime_resume during reads/writes to resolve issue. Change-Id: I0d65869bd1c645bbf7ded9c0265f8d7de0dc624b Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 32 ++++++++++++++++++++++++-------- soc/swr-mstr-ctrl.h | 1 + 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 981060cda4cc..d3121f7aca4e 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -96,7 +96,7 @@ static bool swrm_lock_sleep(struct swr_mstr_ctrl *swrm); static void swrm_unlock_sleep(struct swr_mstr_ctrl *swrm); static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr); static void swr_master_write(struct swr_mstr_ctrl *swrm, u16 reg_addr, u32 val); - +static int swrm_runtime_resume(struct device *dev); static u8 swrm_get_clk_div(int mclk_freq, int bus_clk_freq) { @@ -853,6 +853,8 @@ static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr, mutex_unlock(&swrm->devlock); pm_runtime_get_sync(swrm->dev); + if (swrm->req_clk_switch) + swrm_runtime_resume(swrm->dev); ret = swrm_cmd_fifo_rd_cmd(swrm, &val, dev_num, 0, reg_addr, len); if (!ret) @@ -886,6 +888,8 @@ static int swrm_write(struct swr_master *master, u8 dev_num, u16 reg_addr, mutex_unlock(&swrm->devlock); pm_runtime_get_sync(swrm->dev); + if (swrm->req_clk_switch) + swrm_runtime_resume(swrm->dev); ret = swrm_cmd_fifo_wr_cmd(swrm, reg_val, dev_num, 0, reg_addr); pm_runtime_put_autosuspend(swrm->dev); @@ -2032,16 +2036,22 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) swrm->intr_mask); break; case SWRM_INTERRUPT_STATUS_RD_FIFO_OVERFLOW: - dev_dbg(swrm->dev, "%s: SWR read FIFO overflow\n", - __func__); + value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS); + dev_err(swrm->dev, + "%s: SWR read FIFO overflow fifo status 0x%x\n", + __func__, value); break; case SWRM_INTERRUPT_STATUS_RD_FIFO_UNDERFLOW: - dev_dbg(swrm->dev, "%s: SWR read FIFO underflow\n", - __func__); + value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS); + dev_err(swrm->dev, + "%s: SWR read FIFO underflow fifo status 0x%x\n", + __func__, value); break; case SWRM_INTERRUPT_STATUS_WR_CMD_FIFO_OVERFLOW: - dev_dbg(swrm->dev, "%s: SWR write FIFO overflow\n", - __func__); + value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS); + dev_err(swrm->dev, + "%s: SWR write FIFO overflow fifo status %x\n", + __func__, value); swr_master_write(swrm, SWRM_CMD_FIFO_CMD, 0x1); break; case SWRM_INTERRUPT_STATUS_CMD_ERROR: @@ -2991,6 +3001,8 @@ static int swrm_runtime_resume(struct device *dev) else pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer); + if (swrm->req_clk_switch) + swrm->req_clk_switch = false; mutex_unlock(&swrm->reslock); trace_printk("%s: pm_runtime: resume done, state:%d\n", @@ -3296,8 +3308,12 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) } mutex_lock(&swrm->mlock); if (swrm->clk_src != *(int *)data) { - if (swrm->state == SWR_MSTR_UP) + if (swrm->state == SWR_MSTR_UP) { + swrm->req_clk_switch = true; swrm_device_suspend(&pdev->dev); + if (swrm->state == SWR_MSTR_UP) + swrm->req_clk_switch = false; + } swrm->clk_src = *(int *)data; } mutex_unlock(&swrm->mlock); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 5439ce6f2820..c7d42b0da0fb 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -171,6 +171,7 @@ struct swr_mstr_ctrl { bool dev_up; bool ipc_wakeup_triggered; bool aud_core_err; + bool req_clk_switch; struct pm_qos_request pm_qos_req; enum swrm_pm_state pm_state; wait_queue_head_t pm_wq; -- GitLab From 4f9cd65b9bac6bae9ffd97f1305850a3b507931d Mon Sep 17 00:00:00 2001 From: "Vangala, Amarnath" Date: Thu, 9 Apr 2020 16:31:20 +0530 Subject: [PATCH 1524/1645] ASOC: Speaker Protection V4 API API changes for Speaker Protection V4. Change-Id: I3f00831d90ba0fd11db915cc0af96cf429fc98c9 Signed-off-by: Vangala, Amarnath --- include/uapi/linux/msm_audio_calibration.h | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h index e8ba1b3c206a..5562692d75f4 100644 --- a/include/uapi/linux/msm_audio_calibration.h +++ b/include/uapi/linux/msm_audio_calibration.h @@ -105,11 +105,13 @@ enum { ADM_LSM_AUDPROC_CAL_TYPE, ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE, ADM_AUDPROC_PERSISTENT_CAL_TYPE, + AFE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE, MAX_CAL_TYPES, }; #define AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE #define AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE +#define FE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE AFE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE #define AFE_SIDETONE_IIR_CAL_TYPE AFE_SIDETONE_IIR_CAL_TYPE @@ -123,6 +125,7 @@ enum { #define TOPOLOGY_SPECIFIC_CHANNEL_INFO #define MSM_SPKR_PROT_SPV3 +#define MSM_SPKR_PROT_SPV4 enum { VERSION_0_0, @@ -375,6 +378,16 @@ struct audio_cal_info_sp_ex_vi_param { int32_t status[SP_V2_NUM_MAX_SPKRS]; }; +struct audio_cal_info_sp_v4_ex_vi_param { + int32_t ftm_re_q24[SP_V2_NUM_MAX_SPKRS]; + int32_t ftm_Bl_q24[SP_V2_NUM_MAX_SPKRS]; + int32_t ftm_Rms_q24[SP_V2_NUM_MAX_SPKRS]; + int32_t ftm_Kms_q24[SP_V2_NUM_MAX_SPKRS]; + int32_t ftm_freq_q20[SP_V2_NUM_MAX_SPKRS]; + int32_t ftm_Qms_q24[SP_V2_NUM_MAX_SPKRS]; + uint32_t status[SP_V2_NUM_MAX_SPKRS]; +}; + struct audio_cal_info_sp_th_vi_param { /* * mode should be first param, add new params later to this. @@ -797,6 +810,7 @@ struct audio_cal_sp_th_vi_v_vali_param { struct audio_cal_header hdr; struct audio_cal_type_sp_th_vi_v_vali_param cal_type; }; + struct audio_cal_type_sp_ex_vi_param { struct audio_cal_type_header cal_hdr; struct audio_cal_data cal_data; @@ -807,4 +821,16 @@ struct audio_cal_sp_ex_vi_param { struct audio_cal_header hdr; struct audio_cal_type_sp_ex_vi_param cal_type; }; + +struct audio_cal_type_sp_v4_ex_vi_param { + struct audio_cal_type_header cal_hdr; + struct audio_cal_data cal_data; + struct audio_cal_info_sp_v4_ex_vi_param cal_info; +}; + +struct audio_cal_sp_v4_ex_vi_param { + struct audio_cal_header hdr; + struct audio_cal_type_sp_v4_ex_vi_param cal_type; +}; + #endif /* _UAPI_MSM_AUDIO_CALIBRATION_H */ -- GitLab From 7873230284b39ca297d2546fc5b1ad7fe910f434 Mon Sep 17 00:00:00 2001 From: "Vangala, Amarnath" Date: Thu, 9 Apr 2020 03:57:14 +0530 Subject: [PATCH 1525/1645] ASOC: Speaker Protection V4 Support for Speaker Protection V4. Change-Id: I2237836243a716d4ed3288c9c613bc8d4ec5a282 Signed-off-by: Vangala, Amarnath --- dsp/audio_cal_utils.c | 6 + dsp/q6afe.c | 1025 +++++++++++++++++++++++++++++++++--- include/dsp/apr_audio-v2.h | 375 ++++++++++++- include/dsp/q6afe-v2.h | 3 +- 4 files changed, 1312 insertions(+), 97 deletions(-) diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index fab5186ab889..8e0d7e03196f 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -109,6 +109,9 @@ size_t get_cal_info_size(int32_t cal_type) size = max(sizeof(struct audio_cal_info_sp_ex_vi_ftm_cfg), sizeof(struct audio_cal_info_sp_ex_vi_param)); break; + case AFE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE: + size = sizeof(struct audio_cal_info_sp_v4_ex_vi_param); + break; case AFE_ANC_CAL_TYPE: size = 0; break; @@ -261,6 +264,9 @@ size_t get_user_cal_type_size(int32_t cal_type) size = max(sizeof(struct audio_cal_type_sp_ex_vi_ftm_cfg), sizeof(struct audio_cal_type_sp_ex_vi_param)); break; + case AFE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE: + size = sizeof(struct audio_cal_type_sp_v4_ex_vi_param); + break; case AFE_ANC_CAL_TYPE: size = 0; break; diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 9d5908d92715..d1fcb513562f 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -39,6 +39,7 @@ enum { AFE_CUST_TOPOLOGY_CAL, AFE_FB_SPKR_PROT_TH_VI_CAL, AFE_FB_SPKR_PROT_EX_VI_CAL, + AFE_FB_SPKR_PROT_V4_EX_VI_CAL, MAX_AFE_CAL_TYPES }; @@ -98,6 +99,11 @@ enum { AFE_MATCHED_PORT_ENABLE }; +enum { + AFE_FBSP_V4_EX_VI_MODE_NORMAL = 0, + AFE_FBSP_V4_EX_VI_MODE_FTM = 1 +}; + struct wlock { struct wakeup_source *ws; }; @@ -151,6 +157,10 @@ struct afe_ctl { struct afe_sp_th_vi_v_vali_get_param_resp th_vi_v_vali_resp; struct afe_sp_ex_vi_get_param_resp ex_vi_resp; struct afe_sp_rx_tmax_xmax_logging_resp xt_logging_resp; + struct afe_sp_v4_th_vi_calib_resp spv4_calib_data; + struct afe_sp_v4_param_vi_channel_map_cfg v4_ch_map_cfg; + struct afe_sp_v4_gen_get_param_resp *spv4_get_param_resp_ptr; + uint32_t spv4_rcvd_param_size; struct afe_av_dev_drift_get_param_resp av_dev_drift_resp; struct afe_doa_tracking_mon_get_param_resp doa_tracking_mon_resp; int vi_tx_port; @@ -445,6 +455,7 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, u32 *data_dest = NULL; u32 *data_start = NULL; size_t expected_size = sizeof(u32); + uint32_t num_ch = 0; memset(¶m_hdr, 0, sizeof(param_hdr)); @@ -505,16 +516,79 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, struct afe_sp_rx_tmax_xmax_logging_param); data_dest = (u32 *) &this_afe.xt_logging_resp; break; + case AFE_PARAM_ID_SP_V4_CALIB_RES_CFG: + expected_size += sizeof( + struct afe_sp_v4_param_th_vi_calib_res_cfg); + data_dest = (u32 *) &this_afe.spv4_calib_data; + break; + case AFE_PARAM_ID_SP_V4_TH_VI_FTM_PARAMS: + num_ch = data_start[0]; + this_afe.spv4_rcvd_param_size = + sizeof(struct afe_sp_v4_gen_get_param_resp) + + sizeof(struct afe_sp_v4_param_th_vi_ftm_params) + + (num_ch * sizeof(struct afe_sp_v4_channel_ftm_params)); + this_afe.spv4_get_param_resp_ptr = + kzalloc(this_afe.spv4_rcvd_param_size, GFP_ATOMIC); + data_dest = (u32 *)this_afe.spv4_get_param_resp_ptr; + expected_size += + sizeof(struct afe_sp_v4_param_th_vi_ftm_params) + + (num_ch * sizeof(struct afe_sp_v4_channel_ftm_params)); + break; + case AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_PARAMS: + num_ch = data_start[0]; + this_afe.spv4_rcvd_param_size = + sizeof(struct afe_sp_v4_gen_get_param_resp) + + sizeof(struct afe_sp_v4_param_th_vi_v_vali_params) + + (num_ch * + sizeof(struct afe_sp_v4_channel_v_vali_params)); + this_afe.spv4_get_param_resp_ptr = + kzalloc(this_afe.spv4_rcvd_param_size, GFP_ATOMIC); + data_dest = (u32 *)this_afe.spv4_get_param_resp_ptr; + expected_size += + sizeof(struct afe_sp_v4_param_th_vi_v_vali_params) + + (num_ch * + sizeof(struct afe_sp_v4_channel_v_vali_params)); + break; + case AFE_PARAM_ID_SP_V4_EX_VI_FTM_PARAMS: + num_ch = data_start[0]; + this_afe.spv4_rcvd_param_size = + sizeof(struct afe_sp_v4_gen_get_param_resp) + + sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) + + (num_ch * sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params)); + this_afe.spv4_get_param_resp_ptr = + kzalloc(this_afe.spv4_rcvd_param_size, GFP_ATOMIC); + data_dest = (u32 *)this_afe.spv4_get_param_resp_ptr; + expected_size += + sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) + + (num_ch * sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params)); + break; + case AFE_PARAM_ID_SP_V4_RX_TMAX_XMAX_LOGGING: + num_ch = data_start[0]; + this_afe.spv4_rcvd_param_size = + sizeof(struct afe_sp_v4_gen_get_param_resp) + + sizeof(struct afe_sp_v4_param_tmax_xmax_logging) + + (num_ch * sizeof(struct afe_sp_v4_channel_tmax_xmax_params)); + this_afe.spv4_get_param_resp_ptr = + kzalloc(this_afe.spv4_rcvd_param_size, GFP_ATOMIC); + data_dest = (u32 *)this_afe.spv4_get_param_resp_ptr; + expected_size += + sizeof(struct afe_sp_v4_param_tmax_xmax_logging) + + (num_ch * sizeof(struct afe_sp_v4_channel_tmax_xmax_params)); + break; default: pr_err("%s: Unrecognized param ID %d\n", __func__, param_hdr.param_id); return -EINVAL; } + if (!data_dest) + return -ENOMEM; + if (payload_size < expected_size) { - pr_err("%s: Error: received size %d, expected size %zu for param %d\n", - __func__, payload_size, expected_size, - param_hdr.param_id); + pr_err( + "%s: Error: received size %d, expected size %zu for param %d\n", + __func__, payload_size, expected_size, + param_hdr.param_id); return -EINVAL; } @@ -879,6 +953,22 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) flag_dc_presence[1] == 1) { afe_notify_dc_presence(); } + } else if ((evt_pl->module_id == + AFE_MODULE_SPEAKER_PROTECTION_V4_VI) && + (evt_pl->event_id == + AFE_PORT_SP_DC_DETECTION_EVENT)) { + bool dc_detected = false; + uint32_t *num_channels = + (uint32_t *)((uint8_t *)payload + + sizeof(struct afe_port_mod_evt_rsp_hdr)); + uint32_t *dc_presence_flag = num_channels + 1; + + for (i = 0; i < *num_channels; i++) { + if (dc_presence_flag[i] == 1) + dc_detected = true; + } + if (dc_detected) + afe_notify_dc_presence(); } else if (evt_pl->port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) { if (this_afe.pri_spdif_tx_cb) { this_afe.pri_spdif_tx_cb(data->opcode, @@ -1923,7 +2013,7 @@ static int afe_spk_ramp_dn_cfg(int port) } static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, - union afe_spkr_prot_config *prot_config) + union afe_spkr_prot_config *prot_config, uint32_t param_size) { struct param_hdr_v3 param_info; int ret = -EINVAL; @@ -1950,6 +2040,9 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, case AFE_PARAM_ID_SP_RX_LIMITER_TH: param_info.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; break; + case AFE_PARAM_ID_SP_V4_OP_MODE: + param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_RX; + break; case AFE_PARAM_ID_FEEDBACK_PATH_CFG: this_afe.vi_tx_port = src_port; this_afe.vi_rx_port = dst_port; @@ -1969,6 +2062,15 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, case AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG: param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; break; + case AFE_PARAM_ID_SP_V4_VI_CHANNEL_MAP_CFG: + case AFE_PARAM_ID_SP_V4_VI_OP_MODE_CFG: + case AFE_PARAM_ID_SP_V4_VI_R0T0_CFG: + case AFE_PARAM_ID_SP_V4_TH_VI_FTM_CFG: + case AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_CFG: + case AFE_PARAM_ID_SP_V4_EX_VI_MODE_CFG: + case AFE_PARAM_ID_SP_V4_EX_VI_FTM_CFG: + param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI; + break; default: pr_err("%s: default case 0x%x\n", __func__, param_id); goto fail_cmd; @@ -1976,7 +2078,7 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, param_info.instance_id = INSTANCE_ID_0; param_info.param_id = param_id; - param_info.param_size = sizeof(union afe_spkr_prot_config); + param_info.param_size = param_size; ret = q6afe_pack_and_set_param_in_band(src_port, q6audio_get_port_index(src_port), @@ -1991,7 +2093,7 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, return ret; } -static int afe_spkr_prot_reg_event_cfg(u16 port_id) +static int afe_spkr_prot_reg_event_cfg(u16 port_id, uint32_t module_id) { struct afe_port_cmd_event_cfg *config; struct afe_port_cmd_mod_evt_cfg_payload pl; @@ -2013,7 +2115,7 @@ static int afe_spkr_prot_reg_event_cfg(u16 port_id) } memset(&pl, 0, sizeof(pl)); - pl.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; + pl.module_id = module_id; pl.event_id = AFE_PORT_SP_DC_DETECTION_EVENT; pl.reg_flag = AFE_MODULE_REGISTER_EVENT_FLAG; @@ -2037,10 +2139,260 @@ static int afe_spkr_prot_reg_event_cfg(u16 port_id) return ret; } +static void afe_send_cal_spv4_tx(int port_id) +{ + union afe_spkr_prot_config afe_spk_config; + uint32_t size = 0; + void *tmp_ptr = NULL; + struct afe_sp_v4_param_th_vi_r0t0_cfg *th_vi_r0t0_cfg; + struct afe_sp_v4_channel_r0t0 *ch_r0t0_cfg; + struct afe_sp_v4_param_th_vi_ftm_cfg *th_vi_ftm_cfg; + struct afe_sp_v4_channel_ftm_cfg *ch_ftm_cfg; + struct afe_sp_v4_param_th_vi_v_vali_cfg *th_vi_v_vali_cfg; + struct afe_sp_v4_channel_v_vali_cfg *ch_v_vali_cfg; + struct afe_sp_v4_param_ex_vi_ftm_cfg *ex_vi_ftm_cfg; + struct afe_sp_v4_channel_ex_vi_ftm *ch_ex_vi_ftm_cfg; + + pr_debug("%s: Entry.. port_id %d\n", __func__, port_id); + + if (this_afe.vi_tx_port == port_id) { + memcpy(&afe_spk_config.v4_ch_map_cfg, &this_afe.v4_ch_map_cfg, + sizeof(struct afe_sp_v4_param_vi_channel_map_cfg)); + if (afe_spk_prot_prepare(port_id, this_afe.vi_rx_port, + AFE_PARAM_ID_SP_V4_VI_CHANNEL_MAP_CFG, &afe_spk_config, + sizeof(struct afe_sp_v4_param_vi_channel_map_cfg))) + pr_info("%s: SPKR_CALIB_CHANNEL_MAP_CFG failed\n", + __func__); + } + + if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL || + this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL || + this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL) { + pr_info("%s: Returning as no cal data cached\n", __func__); + return; + } + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); + if ((this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED) && + (this_afe.vi_tx_port == port_id) && + (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9)) { + + if (this_afe.prot_cfg.mode == + MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) { + afe_spk_config.v4_vi_op_mode.th_operation_mode = + Q6AFE_MSM_SPKR_CALIBRATION; + afe_spk_config.v4_vi_op_mode.th_quick_calib_flag = + this_afe.prot_cfg.quick_calib_flag; + } else { + afe_spk_config.v4_vi_op_mode.th_operation_mode = + Q6AFE_MSM_SPKR_PROCESSING; + } + + if (this_afe.th_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) + afe_spk_config.v4_vi_op_mode.th_operation_mode = + Q6AFE_MSM_SPKR_FTM_MODE; + else if (this_afe.v_vali_cfg.mode == + MSM_SPKR_PROT_IN_V_VALI_MODE) + afe_spk_config.v4_vi_op_mode.th_operation_mode = + Q6AFE_MSM_SPKR_V_VALI_MODE; + if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_NOT_CALIBRATED) { + struct afe_sp_v4_param_vi_op_mode_cfg *v4_vi_op_mode; + + v4_vi_op_mode = &afe_spk_config.v4_vi_op_mode; + v4_vi_op_mode->th_r0t0_selection_flag[SP_V2_SPKR_1] = + USE_CALIBRATED_R0TO; + v4_vi_op_mode->th_r0t0_selection_flag[SP_V2_SPKR_2] = + USE_CALIBRATED_R0TO; + } else { + struct afe_sp_v4_param_vi_op_mode_cfg *v4_vi_op_mode; + + v4_vi_op_mode = &afe_spk_config.v4_vi_op_mode; + v4_vi_op_mode->th_r0t0_selection_flag[SP_V2_SPKR_1] = + USE_SAFE_R0TO; + v4_vi_op_mode->th_r0t0_selection_flag[SP_V2_SPKR_2] = + USE_SAFE_R0TO; + } + afe_spk_config.v4_vi_op_mode.num_speakers = SP_V2_NUM_MAX_SPKRS; + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V4_VI_OP_MODE_CFG, + &afe_spk_config, + sizeof(struct afe_sp_v4_param_vi_op_mode_cfg))) + pr_info("%s: SPKR_CALIB_VI_PROC_CFG failed\n", + __func__); + + size = sizeof(struct afe_sp_v4_param_th_vi_r0t0_cfg) + + (SP_V2_NUM_MAX_SPKRS * sizeof(struct afe_sp_v4_channel_r0t0)); + tmp_ptr = kzalloc(size, GFP_KERNEL); + if (!tmp_ptr) { + mutex_unlock( + &this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); + return; + } + memset(tmp_ptr, 0, size); + + th_vi_r0t0_cfg = + (struct afe_sp_v4_param_th_vi_r0t0_cfg *)tmp_ptr; + ch_r0t0_cfg = + (struct afe_sp_v4_channel_r0t0 *)(th_vi_r0t0_cfg + 1); + + th_vi_r0t0_cfg->num_speakers = SP_V2_NUM_MAX_SPKRS; + ch_r0t0_cfg[SP_V2_SPKR_1].r0_cali_q24 = + (uint32_t) this_afe.prot_cfg.r0[SP_V2_SPKR_1]; + ch_r0t0_cfg[SP_V2_SPKR_2].r0_cali_q24 = + (uint32_t) this_afe.prot_cfg.r0[SP_V2_SPKR_2]; + ch_r0t0_cfg[SP_V2_SPKR_1].t0_cali_q6 = + (uint32_t) this_afe.prot_cfg.t0[SP_V2_SPKR_1]; + ch_r0t0_cfg[SP_V2_SPKR_2].t0_cali_q6 = + (uint32_t) this_afe.prot_cfg.t0[SP_V2_SPKR_2]; + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V4_VI_R0T0_CFG, + (union afe_spkr_prot_config *)tmp_ptr, size)) + pr_info("%s: th vi ftm cfg failed\n", __func__); + + kfree(tmp_ptr); + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + if ((this_afe.th_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) && + (this_afe.vi_tx_port == port_id) && + (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9)) { + size = sizeof(struct afe_sp_v4_param_th_vi_ftm_cfg) + + (SP_V2_NUM_MAX_SPKRS*sizeof(struct afe_sp_v4_channel_ftm_cfg)); + tmp_ptr = kzalloc(size, GFP_KERNEL); + if (!tmp_ptr) { + mutex_unlock( + &this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + return; + } + memset(tmp_ptr, 0, size); + + th_vi_ftm_cfg = (struct afe_sp_v4_param_th_vi_ftm_cfg *)tmp_ptr; + ch_ftm_cfg = + (struct afe_sp_v4_channel_ftm_cfg *)(th_vi_ftm_cfg+1); + + th_vi_ftm_cfg->num_ch = SP_V2_NUM_MAX_SPKRS; + ch_ftm_cfg[SP_V2_SPKR_1].wait_time_ms = + this_afe.th_ftm_cfg.wait_time[SP_V2_SPKR_1]; + ch_ftm_cfg[SP_V2_SPKR_2].wait_time_ms = + this_afe.th_ftm_cfg.wait_time[SP_V2_SPKR_2]; + ch_ftm_cfg[SP_V2_SPKR_1].ftm_time_ms = + this_afe.th_ftm_cfg.ftm_time[SP_V2_SPKR_1]; + ch_ftm_cfg[SP_V2_SPKR_2].ftm_time_ms = + this_afe.th_ftm_cfg.ftm_time[SP_V2_SPKR_2]; + + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V4_TH_VI_FTM_CFG, + (union afe_spkr_prot_config *)tmp_ptr, size)) + pr_info("%s: th vi ftm cfg failed\n", __func__); + + kfree(tmp_ptr); + this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; + } else if ((this_afe.v_vali_cfg.mode == + MSM_SPKR_PROT_IN_V_VALI_MODE) && + (this_afe.vi_tx_port == port_id)) { + size = sizeof(struct afe_sp_v4_param_th_vi_v_vali_cfg) + + (SP_V2_NUM_MAX_SPKRS * + sizeof(struct afe_sp_v4_channel_v_vali_cfg)); + tmp_ptr = kzalloc(size, GFP_KERNEL); + if (!tmp_ptr) { + mutex_unlock( + &this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + return; + } + memset(tmp_ptr, 0, size); + + th_vi_v_vali_cfg = + (struct afe_sp_v4_param_th_vi_v_vali_cfg *)tmp_ptr; + ch_v_vali_cfg = + (struct afe_sp_v4_channel_v_vali_cfg *)(th_vi_v_vali_cfg + 1); + + th_vi_v_vali_cfg->num_ch = SP_V2_NUM_MAX_SPKRS; + ch_v_vali_cfg[SP_V2_SPKR_1].wait_time_ms = + this_afe.v_vali_cfg.wait_time[SP_V2_SPKR_1]; + ch_v_vali_cfg[SP_V2_SPKR_2].wait_time_ms = + this_afe.v_vali_cfg.wait_time[SP_V2_SPKR_2]; + ch_v_vali_cfg[SP_V2_SPKR_1].vali_time_ms = + this_afe.v_vali_cfg.vali_time[SP_V2_SPKR_1]; + ch_v_vali_cfg[SP_V2_SPKR_2].vali_time_ms = + this_afe.v_vali_cfg.vali_time[SP_V2_SPKR_2]; + + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_CFG, + (union afe_spkr_prot_config *)tmp_ptr, size)) + pr_info("%s: th vi v-vali cfg failed\n", __func__); + + kfree(tmp_ptr); + this_afe.v_vali_cfg.mode = MSM_SPKR_PROT_DISABLED; + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL]->lock); + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); + if ((this_afe.ex_ftm_cfg.mode == MSM_SPKR_PROT_IN_FTM_MODE) && + (this_afe.vi_tx_port == port_id) && + (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9)) { + size = sizeof(struct afe_sp_v4_param_ex_vi_ftm_cfg) + + (SP_V2_NUM_MAX_SPKRS * + sizeof(struct afe_sp_v4_channel_ex_vi_ftm)); + tmp_ptr = kzalloc(size, GFP_KERNEL); + if (!tmp_ptr) { + mutex_unlock( + &this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); + return; + } + memset(tmp_ptr, 0, size); + + ex_vi_ftm_cfg = (struct afe_sp_v4_param_ex_vi_ftm_cfg *)tmp_ptr; + ch_ex_vi_ftm_cfg = + (struct afe_sp_v4_channel_ex_vi_ftm *)(ex_vi_ftm_cfg + 1); + + afe_spk_config.v4_ex_vi_mode_cfg.operation_mode = + AFE_FBSP_V4_EX_VI_MODE_FTM; + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V4_EX_VI_MODE_CFG, + &afe_spk_config, + sizeof(struct afe_sp_v4_param_ex_vi_mode_cfg))) + pr_info("%s: ex vi mode cfg failed\n", __func__); + + ex_vi_ftm_cfg->num_ch = SP_V2_NUM_MAX_SPKRS; + + ch_ex_vi_ftm_cfg[SP_V2_SPKR_1].wait_time_ms = + this_afe.ex_ftm_cfg.wait_time[SP_V2_SPKR_1]; + ch_ex_vi_ftm_cfg[SP_V2_SPKR_2].wait_time_ms = + this_afe.ex_ftm_cfg.wait_time[SP_V2_SPKR_2]; + ch_ex_vi_ftm_cfg[SP_V2_SPKR_1].ftm_time_ms = + this_afe.ex_ftm_cfg.ftm_time[SP_V2_SPKR_1]; + ch_ex_vi_ftm_cfg[SP_V2_SPKR_2].ftm_time_ms = + this_afe.ex_ftm_cfg.ftm_time[SP_V2_SPKR_2]; + + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V4_EX_VI_FTM_CFG, + (union afe_spkr_prot_config *)tmp_ptr, size)) + pr_info("%s: ex vi ftm cfg failed\n", __func__); + kfree(tmp_ptr); + this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; + } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); + + /* Register for DC detection event if speaker protection is enabled */ + if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED && + (this_afe.vi_tx_port == port_id)) { + afe_spkr_prot_reg_event_cfg(port_id, + AFE_MODULE_SPEAKER_PROTECTION_V4_VI); + } + +} + static void afe_send_cal_spkr_prot_tx(int port_id) { union afe_spkr_prot_config afe_spk_config; + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) { + afe_send_cal_spv4_tx(port_id); + return; + } + if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL || this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL || this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL) @@ -2095,7 +2447,7 @@ static void afe_send_cal_spkr_prot_tx(int port_id) } if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2, - &afe_spk_config)) + &afe_spk_config, sizeof(union afe_spkr_prot_config))) pr_err("%s: SPKR_CALIB_VI_PROC_CFG failed\n", __func__); } @@ -2115,8 +2467,9 @@ static void afe_send_cal_spkr_prot_tx(int port_id) this_afe.th_ftm_cfg.ftm_time[SP_V2_SPKR_2]; if (afe_spk_prot_prepare(port_id, 0, - AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG, - &afe_spk_config)) + AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG, + &afe_spk_config, + sizeof(union afe_spkr_prot_config))) pr_err("%s: th vi ftm cfg failed\n", __func__); this_afe.th_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; } else if ((this_afe.v_vali_cfg.mode == @@ -2134,7 +2487,8 @@ static void afe_send_cal_spkr_prot_tx(int port_id) if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_SP_V2_TH_VI_V_VALI_CFG, - &afe_spk_config)) + &afe_spk_config, + sizeof(union afe_spkr_prot_config))) pr_err("%s: th vi v-vali cfg failed\n", __func__); this_afe.v_vali_cfg.mode = MSM_SPKR_PROT_DISABLED; @@ -2149,7 +2503,8 @@ static void afe_send_cal_spkr_prot_tx(int port_id) Q6AFE_MSM_SPKR_FTM_MODE; if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_SP_V2_EX_VI_MODE_CFG, - &afe_spk_config)) + &afe_spk_config, + sizeof(union afe_spkr_prot_config))) pr_err("%s: ex vi mode cfg failed\n", __func__); afe_spk_config.ex_vi_ftm_cfg.minor_version = 1; @@ -2164,7 +2519,8 @@ static void afe_send_cal_spkr_prot_tx(int port_id) if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG, - &afe_spk_config)) + &afe_spk_config, + sizeof(union afe_spkr_prot_config))) pr_err("%s: ex vi ftm cfg failed\n", __func__); this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED; } @@ -2173,8 +2529,37 @@ static void afe_send_cal_spkr_prot_tx(int port_id) /* Register for DC detection event if speaker protection is enabled */ if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED && (this_afe.vi_tx_port == port_id)) { - afe_spkr_prot_reg_event_cfg(port_id); + afe_spkr_prot_reg_event_cfg(port_id, + AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI); + } +} + +static void afe_send_cal_spv4_rx(int port_id) +{ + + union afe_spkr_prot_config afe_spk_config; + + if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL) + return; + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); + if (this_afe.prot_cfg.mode != MSM_SPKR_PROT_DISABLED && + (this_afe.vi_rx_port == port_id) && + (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9)) { + if (this_afe.prot_cfg.mode == + MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS) + afe_spk_config.v4_op_mode.mode = + Q6AFE_MSM_SPKR_CALIBRATION; + else + afe_spk_config.v4_op_mode.mode = + Q6AFE_MSM_SPKR_PROCESSING; + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_SP_V4_OP_MODE, + &afe_spk_config, sizeof(union afe_spkr_prot_config))) + pr_info("%s: RX MODE_VI_PROC_CFG failed\n", + __func__); } + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock); } static void afe_send_cal_spkr_prot_rx(int port_id) @@ -2182,6 +2567,12 @@ static void afe_send_cal_spkr_prot_rx(int port_id) union afe_spkr_prot_config afe_spk_config; union afe_spkr_prot_config afe_spk_limiter_config; + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) { + afe_send_cal_spv4_rx(port_id); + return; + } + if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL) goto done; @@ -2199,9 +2590,9 @@ static void afe_send_cal_spkr_prot_rx(int port_id) afe_spk_config.mode_rx_cfg.minor_version = 1; if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_FBSP_MODE_RX_CFG, - &afe_spk_config)) + &afe_spk_config, sizeof(union afe_spkr_prot_config))) pr_err("%s: RX MODE_VI_PROC_CFG failed\n", - __func__); + __func__); if (afe_spk_config.mode_rx_cfg.mode == Q6AFE_MSM_SPKR_PROCESSING) { @@ -2217,7 +2608,8 @@ static void afe_send_cal_spkr_prot_rx(int port_id) this_afe.prot_cfg.limiter_th[SP_V2_SPKR_2]; if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_SP_RX_LIMITER_TH, - &afe_spk_limiter_config)) + &afe_spk_limiter_config, + sizeof(union afe_spkr_prot_config))) pr_err("%s: SP_RX_LIMITER_TH failed.\n", __func__); } else { @@ -8346,6 +8738,62 @@ int q6afe_check_osr_clk_freq(u32 freq) } EXPORT_SYMBOL(q6afe_check_osr_clk_freq); +static int afe_get_spv4_th_vi_v_vali_data(void *params, uint32_t size) +{ + struct param_hdr_v3 param_hdr; + int port = SLIMBUS_4_TX; + int ret = -EINVAL; + u8 *rcvd_params = NULL; + struct afe_sp_v4_channel_v_vali_params *v_vali_params; + + if (!params) { + pr_err("%s: Invalid params\n", __func__); + goto done; + } + if (this_afe.vi_tx_port != -1) + port = this_afe.vi_tx_port; + + mutex_lock(&this_afe.afe_cmd_lock); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_PARAMS; + param_hdr.param_size = size; + + ret = q6afe_get_params(port, NULL, ¶m_hdr); + if (ret) { + pr_err("%s: Failed to get TH VI V-Vali data\n", __func__); + goto get_params_fail; + } + + rcvd_params = (u8 *)this_afe.spv4_get_param_resp_ptr + + sizeof(struct afe_sp_v4_gen_get_param_resp); + + memcpy(params, rcvd_params, this_afe.spv4_rcvd_param_size); + + v_vali_params = (struct afe_sp_v4_channel_v_vali_params *) + (params + sizeof(struct afe_sp_v4_param_th_vi_v_vali_params)); + pr_debug("%s: Vrms %d %d status %d %d\n", __func__, + v_vali_params[SP_V2_SPKR_1].vrms_q24, + v_vali_params[SP_V2_SPKR_2].vrms_q24, + v_vali_params[SP_V2_SPKR_1].status, + v_vali_params[SP_V2_SPKR_2].status); + + /*using the non-spv4 status varaible to support v_vali debug app. */ + this_afe.th_vi_v_vali_resp.param.status[SP_V2_SPKR_1] = + v_vali_params[SP_V2_SPKR_1].status; + this_afe.th_vi_v_vali_resp.param.status[SP_V2_SPKR_2] = + v_vali_params[SP_V2_SPKR_2].status; + + ret = 0; +get_params_fail: + kfree(this_afe.spv4_get_param_resp_ptr); + mutex_unlock(&this_afe.afe_cmd_lock); +done: + return ret; +} + static int afe_get_sp_th_vi_v_vali_data( struct afe_sp_th_vi_v_vali_get_param *th_vi_v_vali) { @@ -8389,7 +8837,57 @@ static int afe_get_sp_th_vi_v_vali_data( return ret; } -int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) +static int afe_get_spv4_th_vi_ftm_data(void *params, uint32_t size) +{ + struct param_hdr_v3 param_hdr; + int port = SLIMBUS_4_TX; + int ret = -EINVAL; + u8 *rcvd_params = NULL; + struct afe_sp_v4_channel_ftm_params *th_vi_params; + + if (!params) { + pr_err("%s: Invalid params\n", __func__); + goto done; + } + if (this_afe.vi_tx_port != -1) + port = this_afe.vi_tx_port; + + mutex_lock(&this_afe.afe_cmd_lock); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_V4_TH_VI_FTM_PARAMS; + param_hdr.param_size = size; + + ret = q6afe_get_params(port, NULL, ¶m_hdr); + if (ret) { + pr_err("%s: Failed to get TH VI FTM data\n", __func__); + goto get_params_fail; + } + + rcvd_params = (u8 *)this_afe.spv4_get_param_resp_ptr + + sizeof(struct afe_sp_v4_gen_get_param_resp); + memcpy(params, rcvd_params, this_afe.spv4_rcvd_param_size); + + th_vi_params = (struct afe_sp_v4_channel_ftm_params *) + (params + sizeof(struct afe_sp_v4_param_th_vi_ftm_params)); + pr_debug("%s: DC resistance %d %d temp %d %d status %d %d\n", + __func__, th_vi_params[SP_V2_SPKR_1].dc_res_q24, + th_vi_params[SP_V2_SPKR_2].dc_res_q24, + th_vi_params[SP_V2_SPKR_1].temp_q22, + th_vi_params[SP_V2_SPKR_2].temp_q22, + th_vi_params[SP_V2_SPKR_1].status, + th_vi_params[SP_V2_SPKR_2].status); + ret = 0; +get_params_fail: + kfree(this_afe.spv4_get_param_resp_ptr); + mutex_unlock(&this_afe.afe_cmd_lock); +done: + return ret; +} + +static int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) { struct param_hdr_v3 param_hdr; int port = SLIMBUS_4_TX; @@ -8433,7 +8931,69 @@ int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) return ret; } -int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) +static int afe_get_spv4_ex_vi_ftm_data(void *params, uint32_t size) +{ + struct param_hdr_v3 param_hdr; + int port = SLIMBUS_4_TX; + int ret = -EINVAL; + u8 *rcvd_params = NULL; + struct afe_sp_v4_channel_ex_vi_ftm_params *ex_vi_ftm_param; + + if (!params) { + pr_err("%s: Invalid params\n", __func__); + goto done; + } + if (this_afe.vi_tx_port != -1) + port = this_afe.vi_tx_port; + + mutex_lock(&this_afe.afe_cmd_lock); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_V4_EX_VI_FTM_PARAMS; + param_hdr.param_size = size; + + ret = q6afe_get_params(port, NULL, ¶m_hdr); + if (ret < 0) { + pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", + __func__, port, param_hdr.param_id, ret); + goto get_params_fail; + } + + rcvd_params = (u8 *)this_afe.spv4_get_param_resp_ptr + + sizeof(struct afe_sp_v4_gen_get_param_resp); + + memcpy(params, rcvd_params, this_afe.spv4_rcvd_param_size); + + ex_vi_ftm_param = (struct afe_sp_v4_channel_ex_vi_ftm_params *) + (params + sizeof(struct afe_sp_v4_param_ex_vi_ftm_params)); + + pr_debug("%s: resistance %d %d force factor %d %d Damping kg/s %d %d\n" + "stiffness N/mm %d %d freq %d %d Qfactor %d %d status %d %d", + __func__, ex_vi_ftm_param[SP_V2_SPKR_1].ftm_re_q24, + ex_vi_ftm_param[SP_V2_SPKR_2].ftm_re_q24, + ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Bl_q24, + ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Bl_q24, + ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Rms_q24, + ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Rms_q24, + ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Kms_q24, + ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Kms_q24, + ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Fres_q20, + ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Fres_q20, + ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Qms_q24, + ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Qms_q24, + ex_vi_ftm_param[SP_V2_SPKR_1].status, + ex_vi_ftm_param[SP_V2_SPKR_2].status); + ret = 0; +get_params_fail: + kfree(this_afe.spv4_get_param_resp_ptr); + mutex_unlock(&this_afe.afe_cmd_lock); +done: + return ret; +} + +static int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) { struct param_hdr_v3 param_hdr; int port = SLIMBUS_4_TX; @@ -8480,6 +9040,61 @@ int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) return ret; } +int afe_get_sp_v4_rx_tmax_xmax_logging_data( + struct afe_sp_rx_tmax_xmax_logging_param *xt_logging, + u16 port_id) +{ + struct param_hdr_v3 param_hdr; + int ret = -EINVAL; + struct afe_sp_v4_param_tmax_xmax_logging *tmax_xmax_logging; + struct afe_sp_v4_channel_tmax_xmax_params *tx_channel_params; + uint32_t i, size = 0; + + if (!xt_logging) { + pr_err("%s: Invalid params\n", __func__); + goto done; + } + + size = sizeof(struct afe_sp_v4_param_tmax_xmax_logging) + + (SP_V2_NUM_MAX_SPKRS * + sizeof(struct afe_sp_v4_channel_tmax_xmax_params)); + memset(¶m_hdr, 0, sizeof(param_hdr)); + + param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_RX; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_V4_RX_TMAX_XMAX_LOGGING; + param_hdr.param_size = size; + + ret = q6afe_get_params(port_id, NULL, ¶m_hdr); + if (ret) { + pr_err("%s: Failed to get Tmax Xmax logging data\n", __func__); + goto get_params_fail; + } + + tmax_xmax_logging = (struct afe_sp_v4_param_tmax_xmax_logging *) + ((u8 *)this_afe.spv4_get_param_resp_ptr + + sizeof(struct afe_sp_v4_gen_get_param_resp)); + tx_channel_params = (struct afe_sp_v4_channel_tmax_xmax_params *) + ((u8 *)tmax_xmax_logging + + sizeof(struct afe_sp_v4_param_tmax_xmax_logging)); + for (i = 0; i < tmax_xmax_logging->num_ch; i++) { + xt_logging->max_excursion[i] = + tx_channel_params[i].max_excursion; + xt_logging->count_exceeded_excursion[i] = + tx_channel_params[i].count_exceeded_excursion; + xt_logging->max_temperature[i] = + tx_channel_params[i].max_temperature; + xt_logging->count_exceeded_temperature[i] = + tx_channel_params[i].count_exceeded_temperature; + } + + ret = 0; +get_params_fail: + kfree(this_afe.spv4_get_param_resp_ptr); +done: + return ret; +} + /** * afe_get_sp_rx_tmax_xmax_logging_data - * command to get excursion logging data from DSP @@ -8502,23 +9117,32 @@ int afe_get_sp_rx_tmax_xmax_logging_data( } mutex_lock(&this_afe.afe_cmd_lock); - memset(¶m_hdr, 0, sizeof(param_hdr)); + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) { + ret = afe_get_sp_v4_rx_tmax_xmax_logging_data(xt_logging, + port_id); + } else { + memset(¶m_hdr, 0, sizeof(param_hdr)); - param_hdr.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; - param_hdr.instance_id = INSTANCE_ID_0; - param_hdr.param_id = AFE_PARAM_ID_SP_RX_TMAX_XMAX_LOGGING; - param_hdr.param_size = sizeof(struct afe_sp_rx_tmax_xmax_logging_param); + param_hdr.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_RX_TMAX_XMAX_LOGGING; + param_hdr.param_size = + sizeof(struct afe_sp_rx_tmax_xmax_logging_param); - ret = q6afe_get_params(port_id, NULL, ¶m_hdr); - if (ret < 0) { - pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", - __func__, port_id, param_hdr.param_id, ret); - goto get_params_fail; - } + ret = q6afe_get_params(port_id, NULL, ¶m_hdr); + if (ret < 0) { + pr_err( + "%s: get param port 0x%x param id[0x%x]failed %d\n", + __func__, port_id, param_hdr.param_id, ret); + goto get_params_fail; + } - memcpy(xt_logging, &this_afe.xt_logging_resp.param, - sizeof(this_afe.xt_logging_resp.param)); - pr_debug("%s: max_excursion %d %d count_exceeded_excursion %d %d max_temperature %d %d count_exceeded_temperature %d %d\n", + memcpy(xt_logging, &this_afe.xt_logging_resp.param, + sizeof(this_afe.xt_logging_resp.param)); + } + pr_debug("%s: max_excursion %d %d count_exceeded_excursion %d %d" + " max_temperature %d %d count_exceeded_temperature %d %d\n", __func__, xt_logging->max_excursion[SP_V2_SPKR_1], xt_logging->max_excursion[SP_V2_SPKR_2], xt_logging->count_exceeded_excursion[SP_V2_SPKR_1], @@ -8628,6 +9252,46 @@ int afe_get_doa_tracking_mon(u16 port, } EXPORT_SYMBOL(afe_get_doa_tracking_mon); +static int afe_spv4_get_calib_data( + struct afe_sp_v4_th_vi_calib_resp *calib_resp) +{ + struct param_hdr_v3 param_hdr; + int port = SLIMBUS_4_TX; + int ret = -EINVAL; + + if (!calib_resp) { + pr_err("%s: Invalid params\n", __func__); + goto fail_cmd; + } + if (this_afe.vi_tx_port != -1) + port = this_afe.vi_tx_port; + + mutex_lock(&this_afe.afe_cmd_lock); + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_V4_CALIB_RES_CFG; + param_hdr.param_size = sizeof(struct afe_sp_v4_th_vi_calib_resp); + + ret = q6afe_get_params(port, NULL, ¶m_hdr); + if (ret < 0) { + pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", + __func__, port, param_hdr.param_id, ret); + goto get_params_fail; + } + memcpy(&calib_resp->res_cfg, &this_afe.spv4_calib_data.res_cfg, + sizeof(this_afe.calib_data.res_cfg)); + pr_info("%s: state %s resistance %d %d\n", __func__, + fbsp_state[calib_resp->res_cfg.th_vi_ca_state], + calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_1], + calib_resp->res_cfg.r0_cali_q24[SP_V2_SPKR_2]); + ret = 0; +get_params_fail: + mutex_unlock(&this_afe.afe_cmd_lock); +fail_cmd: + return ret; +} + int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) { struct param_hdr_v3 param_hdr; @@ -8705,22 +9369,41 @@ int afe_spk_prot_feed_back_cfg(int src_port, int dst_port, } pr_debug("%s: src_port 0x%x dst_port 0x%x l_ch %d r_ch %d\n", __func__, src_port, dst_port, l_ch, r_ch); - memset(&prot_config, 0, sizeof(prot_config)); - prot_config.feedback_path_cfg.dst_portid = + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) { + if (l_ch) { + this_afe.v4_ch_map_cfg.chan_info[index++] = 1; + this_afe.v4_ch_map_cfg.chan_info[index++] = 2; + } + if (r_ch) { + this_afe.v4_ch_map_cfg.chan_info[index++] = 3; + this_afe.v4_ch_map_cfg.chan_info[index++] = 4; + } + this_afe.v4_ch_map_cfg.num_channels = index; + pr_debug("%s no of channels: %d\n", __func__, index); + this_afe.vi_tx_port = src_port; + this_afe.vi_rx_port = dst_port; + ret = 0; + } else { + memset(&prot_config, 0, sizeof(prot_config)); + prot_config.feedback_path_cfg.dst_portid = q6audio_get_port_id(dst_port); - if (l_ch) { - prot_config.feedback_path_cfg.chan_info[index++] = 1; - prot_config.feedback_path_cfg.chan_info[index++] = 2; - } - if (r_ch) { - prot_config.feedback_path_cfg.chan_info[index++] = 3; - prot_config.feedback_path_cfg.chan_info[index++] = 4; - } - prot_config.feedback_path_cfg.num_channels = index; - pr_debug("%s no of channels: %d\n", __func__, index); - prot_config.feedback_path_cfg.minor_version = 1; - ret = afe_spk_prot_prepare(src_port, dst_port, - AFE_PARAM_ID_FEEDBACK_PATH_CFG, &prot_config); + if (l_ch) { + prot_config.feedback_path_cfg.chan_info[index++] = 1; + prot_config.feedback_path_cfg.chan_info[index++] = 2; + } + if (r_ch) { + prot_config.feedback_path_cfg.chan_info[index++] = 3; + prot_config.feedback_path_cfg.chan_info[index++] = 4; + } + prot_config.feedback_path_cfg.num_channels = index; + pr_debug("%s no of channels: %d\n", __func__, index); + prot_config.feedback_path_cfg.minor_version = 1; + ret = afe_spk_prot_prepare(src_port, dst_port, + AFE_PARAM_ID_FEEDBACK_PATH_CFG, &prot_config, + sizeof(union afe_spkr_prot_config)); + } + fail_cmd: return ret; } @@ -9065,6 +9748,9 @@ static int afe_get_cal_sp_th_vi_v_vali_param(int32_t cal_type, size_t data_size, int i, ret = 0; struct audio_cal_type_sp_th_vi_v_vali_param *cal_data = data; struct afe_sp_th_vi_v_vali_get_param th_vi_v_vali; + uint32_t size; + void *params = NULL; + struct afe_sp_v4_channel_v_vali_params *v_vali_params; if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL || cal_data == NULL || @@ -9075,18 +9761,51 @@ static int afe_get_cal_sp_th_vi_v_vali_param(int32_t cal_type, size_t data_size, cal_data->cal_info.status[i] = -EINVAL; cal_data->cal_info.vrms_q24[i] = -1; } - if (!afe_get_sp_th_vi_v_vali_data(&th_vi_v_vali)) { - for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { - pr_debug("%s: v-vali param status = %d\n", - __func__, th_vi_v_vali.param.status[i]); - if (th_vi_v_vali.param.status[i] == - V_VALI_IN_PROGRESS) { - cal_data->cal_info.status[i] = -EAGAIN; - } else if (th_vi_v_vali.param.status[i] == - V_VALI_SUCCESS) { - cal_data->cal_info.status[i] = V_VALI_SUCCESS; - cal_data->cal_info.vrms_q24[i] = - th_vi_v_vali.param.vrms_q24[i]; + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) { + size = sizeof(struct afe_sp_v4_param_th_vi_v_vali_params) + + (SP_V2_NUM_MAX_SPKRS * + sizeof(struct afe_sp_v4_channel_v_vali_params)); + params = kzalloc(size, GFP_KERNEL); + if (!params) + return -ENOMEM; + v_vali_params = + (struct afe_sp_v4_channel_v_vali_params *)((u8 *)params + + sizeof(struct afe_sp_v4_param_th_vi_v_vali_params)); + + if (!afe_get_spv4_th_vi_v_vali_data(params, size)) { + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + pr_debug("%s: ftm param status = %d\n", + __func__, v_vali_params[i].status); + if (v_vali_params[i].status == + V_VALI_IN_PROGRESS) { + cal_data->cal_info.status[i] = -EAGAIN; + } else if (v_vali_params[i].status == + V_VALI_SUCCESS) { + cal_data->cal_info.status[i] = + V_VALI_SUCCESS; + cal_data->cal_info.vrms_q24[i] = + v_vali_params[i].vrms_q24; + } + } + } + kfree(params); + } else { + if (!afe_get_sp_th_vi_v_vali_data(&th_vi_v_vali)) { + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + pr_debug( + "%s: v-vali param status = %d\n", + __func__, th_vi_v_vali.param.status[i]); + if (th_vi_v_vali.param.status[i] == + V_VALI_IN_PROGRESS) { + cal_data->cal_info.status[i] = -EAGAIN; + } else if (th_vi_v_vali.param.status[i] == + V_VALI_SUCCESS) { + cal_data->cal_info.status[i] = + V_VALI_SUCCESS; + cal_data->cal_info.vrms_q24[i] = + th_vi_v_vali.param.vrms_q24[i]; + } } } } @@ -9101,6 +9820,9 @@ static int afe_get_cal_sp_th_vi_ftm_param(int32_t cal_type, size_t data_size, int i, ret = 0; struct audio_cal_type_sp_th_vi_param *cal_data = data; struct afe_sp_th_vi_get_param th_vi; + uint32_t size; + void *params = NULL; + struct afe_sp_v4_channel_ftm_params *th_vi_ftm_params; if (this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL || cal_data == NULL || @@ -9112,18 +9834,52 @@ static int afe_get_cal_sp_th_vi_ftm_param(int32_t cal_type, size_t data_size, cal_data->cal_info.r_dc_q24[i] = -1; cal_data->cal_info.temp_q22[i] = -1; } - if (!afe_get_sp_th_vi_ftm_data(&th_vi)) { - for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { - pr_debug("%s: ftm param status = %d\n", - __func__, th_vi.param.status[i]); - if (th_vi.param.status[i] == FBSP_IN_PROGRESS) { - cal_data->cal_info.status[i] = -EAGAIN; - } else if (th_vi.param.status[i] == FBSP_SUCCESS) { - cal_data->cal_info.status[i] = 0; - cal_data->cal_info.r_dc_q24[i] = - th_vi.param.dc_res_q24[i]; - cal_data->cal_info.temp_q22[i] = - th_vi.param.temp_q22[i]; + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) { + size = sizeof(struct afe_sp_v4_param_th_vi_ftm_params) + + (SP_V2_NUM_MAX_SPKRS * + sizeof(struct afe_sp_v4_channel_ftm_params)); + params = kzalloc(size, GFP_KERNEL); + if (!params) + return -ENOMEM; + th_vi_ftm_params = (struct afe_sp_v4_channel_ftm_params *) + ((u8 *)params + + sizeof(struct afe_sp_v4_param_th_vi_ftm_params)); + + if (!afe_get_spv4_th_vi_ftm_data(params, size)) { + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + pr_debug("%s: SP V4 ftm param status = %d\n", + __func__, th_vi_ftm_params[i].status); + if (th_vi_ftm_params[i].status == + FBSP_IN_PROGRESS) { + cal_data->cal_info.status[i] = -EAGAIN; + } else if (th_vi_ftm_params[i].status == + FBSP_SUCCESS) { + cal_data->cal_info.status[i] = 0; + cal_data->cal_info.r_dc_q24[i] = + th_vi_ftm_params[i].dc_res_q24; + cal_data->cal_info.temp_q22[i] = + th_vi_ftm_params[i].temp_q22; + } + } + } + kfree(params); + } else { + + if (!afe_get_sp_th_vi_ftm_data(&th_vi)) { + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + pr_debug("%s: ftm param status = %d\n", + __func__, th_vi.param.status[i]); + if (th_vi.param.status[i] == FBSP_IN_PROGRESS) { + cal_data->cal_info.status[i] = -EAGAIN; + } else if (th_vi.param.status[i] == + FBSP_SUCCESS) { + cal_data->cal_info.status[i] = 0; + cal_data->cal_info.r_dc_q24[i] = + th_vi.param.dc_res_q24[i]; + cal_data->cal_info.temp_q22[i] = + th_vi.param.temp_q22[i]; + } } } } @@ -9156,6 +9912,75 @@ static int afe_get_cal_sp_th_vi_param(int32_t cal_type, size_t data_size, return ret; } +static int afe_get_cal_spv4_ex_vi_ftm_param(int32_t cal_type, size_t data_size, + void *data) +{ + int i, ret = 0; + struct audio_cal_type_sp_v4_ex_vi_param *cal_data = data; + uint32_t size; + void *params = NULL; + struct afe_sp_v4_channel_ex_vi_ftm_params *ex_vi_ftm_param; + + pr_debug("%s: cal_type = %d\n", __func__, cal_type); + if (this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL] == NULL || + cal_data == NULL || + data_size != sizeof(*cal_data)) + goto done; + + mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL]->lock); + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + cal_data->cal_info.status[i] = -EINVAL; + cal_data->cal_info.ftm_re_q24[i] = -1; + cal_data->cal_info.ftm_re_q24[i] = -1; + cal_data->cal_info.ftm_Rms_q24[i] = -1; + cal_data->cal_info.ftm_Kms_q24[i] = -1; + cal_data->cal_info.ftm_freq_q20[i] = -1; + cal_data->cal_info.ftm_Qms_q24[i] = -1; + } + + size = sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) + + (SP_V2_NUM_MAX_SPKRS * + sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params)); + params = kzalloc(size, GFP_KERNEL); + if (!params) { + mutex_unlock( + &this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL]->lock); + return -ENOMEM; + } + ex_vi_ftm_param = (struct afe_sp_v4_channel_ex_vi_ftm_params *) + ((u8 *)params + + sizeof(struct afe_sp_v4_param_ex_vi_ftm_params)); + + if (!afe_get_spv4_ex_vi_ftm_data(params, size)) { + for (i = 0; i < SP_V2_NUM_MAX_SPKRS; i++) { + pr_debug("%s: ftm param status = %d\n", + __func__, ex_vi_ftm_param[i].status); + if (ex_vi_ftm_param[i].status == FBSP_IN_PROGRESS) { + cal_data->cal_info.status[i] = -EAGAIN; + } else if (ex_vi_ftm_param[i].status == FBSP_SUCCESS) { + cal_data->cal_info.status[i] = 0; + cal_data->cal_info.ftm_re_q24[i] = + ex_vi_ftm_param[i].ftm_re_q24; + cal_data->cal_info.ftm_Bl_q24[i] = + ex_vi_ftm_param[i].ftm_Bl_q24; + cal_data->cal_info.ftm_Rms_q24[i] = + ex_vi_ftm_param[i].ftm_Rms_q24; + cal_data->cal_info.ftm_Kms_q24[i] = + ex_vi_ftm_param[i].ftm_Kms_q24; + cal_data->cal_info.ftm_freq_q20[i] = + ex_vi_ftm_param[i].ftm_Fres_q20; + cal_data->cal_info.ftm_Qms_q24[i] = + ex_vi_ftm_param[i].ftm_Qms_q24; + } + } + } + kfree(params); + + mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL]->lock); +done: + return ret; +} + static int afe_get_cal_sp_ex_vi_ftm_param(int32_t cal_type, size_t data_size, void *data) { @@ -9204,6 +10029,7 @@ static int afe_get_cal_fb_spkr_prot(int32_t cal_type, size_t data_size, int ret = 0; struct audio_cal_type_fb_spk_prot_status *cal_data = data; struct afe_spkr_prot_get_vi_calib calib_resp; + struct afe_sp_v4_th_vi_calib_resp spv4_calib_resp; pr_debug("%s:\n", __func__); @@ -9227,17 +10053,47 @@ static int afe_get_cal_fb_spkr_prot(int32_t cal_type, size_t data_size, cal_data->cal_info.status = -EINVAL; cal_data->cal_info.r0[SP_V2_SPKR_1] = -1; cal_data->cal_info.r0[SP_V2_SPKR_2] = -1; - if (!afe_spk_prot_get_calib_data(&calib_resp)) { - if (calib_resp.res_cfg.th_vi_ca_state == + if (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9) { + if (!(q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= + AFE_API_VERSION_V9)) { + pr_debug( + "%s: AFE API version is not supported!\n", + __func__); + goto done; + } + if (!afe_spv4_get_calib_data(&spv4_calib_resp)) { + if (spv4_calib_resp.res_cfg.th_vi_ca_state == FBSP_IN_PROGRESS) - cal_data->cal_info.status = -EAGAIN; - else if (calib_resp.res_cfg.th_vi_ca_state == + cal_data->cal_info.status = -EAGAIN; + else if ( + spv4_calib_resp.res_cfg.th_vi_ca_state == FBSP_SUCCESS) { - cal_data->cal_info.status = 0; - cal_data->cal_info.r0[SP_V2_SPKR_1] = - calib_resp.res_cfg.r0_cali_q24[SP_V2_SPKR_1]; - cal_data->cal_info.r0[SP_V2_SPKR_2] = - calib_resp.res_cfg.r0_cali_q24[SP_V2_SPKR_2]; + cal_data->cal_info.status = 0; + cal_data->cal_info.r0[SP_V2_SPKR_1] = + spv4_calib_resp.res_cfg.r0_cali_q24[ + SP_V2_SPKR_1]; + cal_data->cal_info.r0[SP_V2_SPKR_2] = + spv4_calib_resp.res_cfg.r0_cali_q24[ + SP_V2_SPKR_2]; + } + } + } else { + + if (!afe_spk_prot_get_calib_data(&calib_resp)) { + if (calib_resp.res_cfg.th_vi_ca_state == + FBSP_IN_PROGRESS) + cal_data->cal_info.status = -EAGAIN; + else if (calib_resp.res_cfg.th_vi_ca_state == + FBSP_SUCCESS) { + cal_data->cal_info.status = 0; + cal_data->cal_info.r0[SP_V2_SPKR_1] = + calib_resp.res_cfg.r0_cali_q24[ + SP_V2_SPKR_1]; + cal_data->cal_info.r0[SP_V2_SPKR_2] = + calib_resp.res_cfg.r0_cali_q24[ + SP_V2_SPKR_2]; + } } } if (!cal_data->cal_info.status) { @@ -9422,6 +10278,11 @@ static int afe_init_cal_data(void) {NULL, NULL, NULL, afe_set_cal_sp_ex_vi_ftm_cfg, afe_get_cal_sp_ex_vi_ftm_param, NULL} }, {NULL, NULL, cal_utils_match_buf_num} }, + + {{AFE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE, + {NULL, NULL, NULL, NULL, + afe_get_cal_spv4_ex_vi_ftm_param, NULL} }, + {NULL, NULL, cal_utils_match_buf_num} }, }; pr_debug("%s:\n", __func__); @@ -9568,7 +10429,7 @@ int __init afe_init(void) #else wl.ws = wakeup_source_register("spkr-prot"); #endif -/* + /* * Set release function to cleanup memory related to kobject * before initializing the kobject. */ diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index ca0f6ddb473c..86a803efbc1c 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -11074,19 +11074,6 @@ struct afe_sp_rx_limiter_th_param { uint32_t lim_thr_per_calib_q27[SP_V2_NUM_MAX_SPKR]; } __packed; -union afe_spkr_prot_config { - struct asm_fbsp_mode_rx_cfg mode_rx_cfg; - struct asm_spkr_calib_vi_proc_cfg vi_proc_cfg; - struct asm_feedback_path_cfg feedback_path_cfg; - struct asm_mode_vi_proc_cfg mode_vi_proc_cfg; - struct afe_sp_th_vi_mode_cfg th_vi_mode_cfg; - struct afe_sp_th_vi_ftm_cfg th_vi_ftm_cfg; - struct afe_sp_th_vi_v_vali_cfg th_vi_v_vali_cfg; - struct afe_sp_ex_vi_mode_cfg ex_vi_mode_cfg; - struct afe_sp_ex_vi_ftm_cfg ex_vi_ftm_cfg; - struct afe_sp_rx_limiter_th_param limiter_th_cfg; -} __packed; - struct afe_spkr_prot_get_vi_calib { struct apr_hdr hdr; struct mem_mapping_hdr mem_hdr; @@ -11101,6 +11088,366 @@ struct afe_spkr_prot_calib_get_resp { } __packed; +#define AFE_MODULE_SPEAKER_PROTECTION_V4_RX 0x000102C7 +#define AFE_PARAM_ID_SP_V4_OP_MODE 0x000102C9 +#define AFE_PARAM_ID_SP_V4_RX_TMAX_XMAX_LOGGING 0x000102D2 + +struct afe_sp_v4_param_op_mode { + uint32_t mode; +} __packed; + +struct afe_sp_v4_channel_tmax_xmax_params { + /* + * Maximum excursion since the last grasp of xmax in mm. + */ + int32_t max_excursion; + /* + * Number of periods when the monitored excursion exceeds to and + * stays at Xmax during logging_count_period. + */ + uint32_t count_exceeded_excursion; + /* + * Maximum temperature since the last grasp of tmax in C. + */ + int32_t max_temperature; + /* + * Number of periods when the monitored temperature exceeds to and + * stays at Tmax during logging_count_period + */ + uint32_t count_exceeded_temperature; +} __packed; + +/* This structure is followed by 'num_ch' number of structures of + * type afe_sp_v4_channel_tmax_xmax_params. + */ +struct afe_sp_v4_param_tmax_xmax_logging { + uint32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_tmax_xmax_params ch_tmax_xmax[0]; +} __packed; + +#define AFE_MODULE_SPEAKER_PROTECTION_V4_VI 0x000102D3 +#define AFE_PARAM_ID_SP_V4_VI_OP_MODE_CFG 0x000102D4 +#define AFE_PARAM_ID_SP_V4_VI_R0T0_CFG 0x000102D5 +#define AFE_PARAM_ID_SP_V4_CALIB_RES_CFG 0x000102D8 +#define AFE_PARAM_ID_SP_V4_TH_VI_FTM_CFG 0x000102D9 +#define AFE_PARAM_ID_SP_V4_TH_VI_FTM_PARAMS 0x000102DA +#define AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_CFG 0x000102DB +#define AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_PARAMS 0x000102DC +#define AFE_PARAM_ID_SP_V4_EX_VI_MODE_CFG 0x000102DF +#define AFE_PARAM_ID_SP_V4_EX_VI_FTM_CFG 0x000102E0 +#define AFE_PARAM_ID_SP_V4_EX_VI_FTM_PARAMS 0x000102E1 +#define AFE_PARAM_ID_SP_V4_VI_CHANNEL_MAP_CFG 0x000102E5 + +struct afe_sp_v4_param_vi_op_mode_cfg { + uint32_t num_speakers; + /* Number of channels for Rx signal. + */ + uint32_t th_operation_mode; + /* + * Operation mode of thermal VI module. + * 0 -- Normal Running mode + * 1 -- Calibration mode + * 2 -- FTM mode + * 3 -- V-Validation mode + */ + uint32_t th_quick_calib_flag; + /* + * Indicates whether calibration is to be done in quick mode or not. + * This field is valid only in Calibration mode (operation_mode = 1). + * 0 -- Disabled + * 1 -- Enabled + */ + uint32_t th_r0t0_selection_flag[SP_V2_NUM_MAX_SPKR]; + /* + * Specifies which set of R0, T0 values the algorithm will use. + * This field is valid only in Normal mode (operation_mode = 0). + * 0 -- Use calibrated R0, T0 value + * 1 -- Use safe R0, T0 value + */ +} __packed; + +struct afe_sp_v4_channel_r0t0 { + int32_t r0_cali_q24; + /* + * Calibration point resistance per device. This field is valid + * only in Normal mode (operation_mode = 0). + * values 33554432 to 1073741824 Ohms (in Q24 format) + */ + int16_t t0_cali_q6; + /* + * Calibration point temperature per device. This field is valid + * in both Normal mode and Calibration mode. + * values -1920 to 5120 degrees C (in Q6 format) + */ + uint16_t reserved; + +} __packed; + +/* Followed by this structure are 'num_speaakers' number of structures + * of type afe_sp_v4_channel_r0t0. + */ +struct afe_sp_v4_param_th_vi_r0t0_cfg { + uint32_t num_speakers; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_r0t0 ch_r0t0[0]; +} __packed; + +struct afe_sp_v4_param_th_vi_calib_res_cfg { + uint32_t num_ch; + /* Number of channels for Rx signal. + */ + uint32_t th_vi_ca_state; + /* + * Represents the calibration state for both speakers. + * 0 -- Incorrect operation mode. + * 1 -- Inactive mode. + * 2 -- Wait state. + * 3 -- Calibration in progress state. + * 4 -- Calibration success. + * 5 -- Calibration failed. + */ + int32_t r0_cali_q24[SP_V2_NUM_MAX_SPKR]; + /* Calibration resistance per device. + */ +} __packed; + +struct afe_sp_v4_th_vi_calib_resp { + uint32_t status; + struct param_hdr_v3 pdata; + struct afe_sp_v4_param_th_vi_calib_res_cfg res_cfg; +} __packed; + +struct afe_sp_v4_channel_ftm_cfg { + uint32_t wait_time_ms; + /* + * Wait time to heat up speaker before collecting statistics + * for ftm mode in ms. + * values 0 to 4294967295 ms + */ + uint32_t ftm_time_ms; + /* + * duration for which FTM statistics are collected in ms. + * values 0 to 2000 ms + */ +} __packed; + +/* This structure is followed by 'num_ch' number of structures + * of type afe_sp_v4_channel_ftm_cfg. + */ +struct afe_sp_v4_param_th_vi_ftm_cfg { + uint32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_ftm_cfg ch_ftm_cfg[0]; +} __packed; + +struct afe_sp_v4_channel_ftm_params { + int32_t dc_res_q24; + /* + * DC resistance value in q24 format + * values 0 to 2147483647 Ohms (in Q24 format) + */ + int32_t temp_q22; + /* + * temperature value in q22 format + * values -125829120 to 2147483647 degC (in Q22 format) + */ + uint32_t status; + /* + * FTM packet status + * 0 - Incorrect operation mode.This status is returned + * when GET_PARAM is called in non FTM Mode + * 1 - Inactive mode -- Port is not yet started. + * 2 - Wait state. wait_time_ms has not yet elapsed + * 3 - In progress state. ftm_time_ms has not yet elapsed. + * 4 - Success. + * 5 - Failed. + */ +} __packed; + +/* This structure is followed by 'num_ch' number of structures + * of type afe_sp_v4_channel_ftm_params. + */ +struct afe_sp_v4_param_th_vi_ftm_params { + uint32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_ftm_params ch_ftm_params[0]; +} __packed; + +struct afe_sp_v4_gen_get_param_resp { + uint32_t status; + struct param_hdr_v3 pdata; +} __packed; + +struct afe_sp_v4_channel_v_vali_cfg { + uint32_t wait_time_ms; + /* + * Wait time to heat up speaker before collecting statistics + * for V validation mode in ms. + * values 100 to 1000 ms + */ + uint32_t vali_time_ms; + /* + * duration for which V VALIDATION statistics are collected in ms. + * values 1000 to 3000 ms + */ +} __packed; + +/* This structure is followed by 'num_ch' number of structures + * of type afe_sp_v4_channel_v_vali_cfg. + */ +struct afe_sp_v4_param_th_vi_v_vali_cfg { + uint32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_v_vali_cfg ch_v_vali_cfg[0]; +} __packed; + +struct afe_sp_v4_channel_v_vali_params { + uint32_t vrms_q24; + /* + * Vrms value in q24 format + * values [0 33554432] Q24 (0 - 2Vrms) + */ + uint32_t status; + /* + * v-vali packet status + * 0 - Failed. + * 1 - Success. + * 2 - Incorrect operation mode.This status is returned + * when GET_PARAM is called in non v-vali Mode + * 3 - Inactive mode -- Port is not yet started. + * 4 - Wait state. wait_time_ms has not yet elapsed + * 5 - In progress state. ftm_time_ms has not yet elapsed. + */ +} __packed; + +/* This structure is followed by 'num_ch' number of structures + * of type afe_sp_v4_channel_v_vali_params. + */ +struct afe_sp_v4_param_th_vi_v_vali_params { + uint32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_v_vali_params ch_v_vali_params[0]; +} __packed; + +struct afe_sp_v4_param_ex_vi_mode_cfg { + uint32_t operation_mode; + /* + * Operation mode of Excursion VI module. + * 0 - Normal Running mode + * 2 - FTM mode + */ +} __packed; + +struct afe_sp_v4_channel_ex_vi_ftm { + uint32_t wait_time_ms; + /* + * Wait time to heat up speaker before collecting statistics + * for ftm mode in ms. + * values 0 to 4294967295 ms + */ + uint32_t ftm_time_ms; + /* + * duration for which FTM statistics are collected in ms. + * values 0 to 2000 ms + */ +} __packed; + +/* This structure is followed by 'num_ch' number of structures + * of type afe_sp_v4_channel_ex_vi_ftm. + */ +struct afe_sp_v4_param_ex_vi_ftm_cfg { + uint32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_ex_vi_ftm ch_ex_vi_ftm[0]; +} __packed; + +struct afe_sp_v4_channel_ex_vi_ftm_params { + int32_t ftm_re_q24; + /* + * DC resistance of voice coil at room temperature + * or small signal level in Ohm. + */ + int32_t ftm_Bl_q24; + /* Force factor. + */ + int32_t ftm_Rms_q24; + /* Mechanical damping or resistance of loudspeaker in Kg/sec. + */ + int32_t ftm_Kms_q24; + /* Mechanical stiffness of driver suspension in N/mm. + */ + int32_t ftm_Fres_q20; + /* Resonance frequency in Hz. + */ + int32_t ftm_Qms_q24; + /* Mechanical Q-factor. + */ + uint32_t status; + /* + * FTM packet status + * 0 - Incorrect operation mode.This status is returned + * when GET_PARAM is called in non FTM Mode. + * 1 - Inactive mode -- Port is not yet started. + * 2 - Wait state. wait_time_ms has not yet elapsed + * 3 - In progress state. ftm_time_ms has not yet elapsed. + * 4 - Success. + * 5 - Failed. + */ +} __packed; + +/* This structure is followed by 'num_ch' number of structures of + * type afe_sp_v4_channel_ex_vi_ftm_params. + */ +struct afe_sp_v4_param_ex_vi_ftm_params { + uint32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_ex_vi_ftm_params ch_ex_vi_ftm_params[0]; +} __packed; + +struct afe_sp_v4_param_vi_channel_map_cfg { + int32_t num_channels; + int32_t chan_info[4]; +} __packed; + +union afe_spkr_prot_config { + struct asm_fbsp_mode_rx_cfg mode_rx_cfg; + struct asm_spkr_calib_vi_proc_cfg vi_proc_cfg; + struct asm_feedback_path_cfg feedback_path_cfg; + struct asm_mode_vi_proc_cfg mode_vi_proc_cfg; + struct afe_sp_th_vi_mode_cfg th_vi_mode_cfg; + struct afe_sp_th_vi_ftm_cfg th_vi_ftm_cfg; + struct afe_sp_th_vi_v_vali_cfg th_vi_v_vali_cfg; + struct afe_sp_ex_vi_mode_cfg ex_vi_mode_cfg; + struct afe_sp_ex_vi_ftm_cfg ex_vi_ftm_cfg; + struct afe_sp_rx_limiter_th_param limiter_th_cfg; + struct afe_sp_v4_param_op_mode v4_op_mode; + struct afe_sp_v4_param_vi_op_mode_cfg v4_vi_op_mode; + struct afe_sp_v4_param_th_vi_r0t0_cfg v4_r0t0_cfg; + struct afe_sp_v4_param_th_vi_ftm_cfg v4_th_vi_ftm_cfg; + struct afe_sp_v4_param_th_vi_v_vali_cfg v4_v_vali_cfg; + struct afe_sp_v4_param_ex_vi_mode_cfg v4_ex_vi_mode_cfg; + struct afe_sp_v4_param_ex_vi_ftm_cfg v4_ex_vi_ftm_cfg; + struct afe_sp_v4_param_vi_channel_map_cfg v4_ch_map_cfg; +} __packed; + + /* SRS TRUMEDIA start */ /* topology */ #define SRS_TRUMEDIA_TOPOLOGY_ID 0x00010D90 @@ -11772,7 +12119,7 @@ struct afe_clk_set { * for enable and disable clock. * "clk_freq_in_hz", "clk_attri", and "clk_root" * are ignored in disable clock case. - * @values  + * @values * - 0 -- Disabled * - 1 -- Enabled @tablebulletend */ diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 55ae6be1074b..8b82069a2f38 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -45,7 +45,8 @@ #define AFE_API_VERSION_V4 4 /* for VAD enable */ #define AFE_API_VERSION_V6 6 - +/* for Speaker Protection V4 */ +#define AFE_API_VERSION_V9 9 typedef int (*routing_cb)(int port); -- GitLab From 10e8384973f83093e587837d51ce77f1f99b2c0a Mon Sep 17 00:00:00 2001 From: Harshal Ahire Date: Fri, 27 Mar 2020 04:37:23 +0530 Subject: [PATCH 1526/1645] dsp: Add support to dynamically load and unload BT modules Add new APIs to enable dynamic load and unload of BT modules before afe_port_start and afe_close. Change-Id: I74da9a49aac754d4557c7206155de65cf9b6bdaf Signed-off-by: Harshal Ahire --- dsp/q6afe.c | 177 ++++++++++++++++++++++++++++++++++++- dsp/q6core.c | 137 +++++++++++++++++++++++++++- include/dsp/apr_audio-v2.h | 10 +++ include/dsp/q6core.h | 121 +++++++++++++++++++++++++ 4 files changed, 441 insertions(+), 4 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 9d5908d92715..567f7feed17a 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -25,6 +25,21 @@ #define WAKELOCK_TIMEOUT 5000 #define AFE_CLK_TOKEN 1024 + +struct afe_avcs_payload_port_mapping { + u16 port_id; + struct avcs_load_unload_modules_payload *payload; +} __packed; + +enum { + ENCODER_CASE, + DECODER_CASE, + /* Add new use case here */ + MAX_ALLOWED_USE_CASES +}; + +static struct afe_avcs_payload_port_mapping *pm[MAX_ALLOWED_USE_CASES]; + enum { AFE_COMMON_RX_CAL = 0, AFE_COMMON_TX_CAL, @@ -227,6 +242,124 @@ bool afe_close_done[2] = {true, true}; #define SIZEOF_CFG_CMD(y) \ (sizeof(struct apr_hdr) + sizeof(u16) + (sizeof(struct y))) +static void q6afe_unload_avcs_modules(u16 port_id, int index) +{ + int ret = 0; + + ret = q6core_avcs_load_unload_modules(pm[index]->payload, + AVCS_UNLOAD_MODULES); + + if (ret < 0) + pr_err("%s: avcs module unload failed %d\n", __func__, ret); + + kfree(pm[index]->payload); + pm[index]->payload = NULL; + kfree(pm[index]); + pm[index] = NULL; +} + +static int q6afe_load_avcs_modules(int num_modules, u16 port_id, + uint32_t use_case, u32 format_id) +{ + int i = 0; + int32_t ret = 0; + size_t payload_size = 0, port_struct_size = 0; + struct afe_avcs_payload_port_mapping payload_map; + struct avcs_load_unload_modules_sec_payload sec_payload; + + if (num_modules <= 0) { + pr_err("%s: Invalid number of modules to load\n", __func__); + return -EINVAL; + } + + for (i = 0; i < MAX_ALLOWED_USE_CASES; i++) { + if (pm[i] == NULL) { + port_struct_size = sizeof(payload_map); + pm[i] = kzalloc(port_struct_size, GFP_KERNEL); + if (!pm[i]) + return -ENOMEM; + + pm[i]->port_id = port_id; + payload_size = sizeof(uint32_t) + (sizeof(sec_payload) + * num_modules); + pm[i]->payload = kzalloc(payload_size, GFP_KERNEL); + if (!pm[i]->payload) { + kfree(pm[i]); + pm[i] = NULL; + return -ENOMEM; + } + + /* + * index 0 : packetizer/de-packetizer + * index 1 : encoder/decoder + */ + + pm[i]->payload->num_modules = num_modules; + + /* + * Remaining fields of payload + * are initialized to zero + */ + + if (use_case == ENCODER_CASE) { + pm[i]->payload->load_unload_info[0].module_type = + AMDB_MODULE_TYPE_PACKETIZER; + pm[i]->payload->load_unload_info[0].id1 = + AVS_MODULE_ID_PACKETIZER_COP; + pm[i]->payload->load_unload_info[1].module_type = + AMDB_MODULE_TYPE_ENCODER; + pm[i]->payload->load_unload_info[1].id1 = + format_id; + } else if (use_case == DECODER_CASE) { + pm[i]->payload->load_unload_info[0].module_type = + AMDB_MODULE_TYPE_DEPACKETIZER; + pm[i]->payload->load_unload_info[0].id1 = + AVS_MODULE_ID_DEPACKETIZER_COP_V1; + + if (format_id == ENC_CODEC_TYPE_LDAC) { + pm[i]->payload->load_unload_info[0].id1 = + AVS_MODULE_ID_DEPACKETIZER_COP; + goto load_unload; + } + + pm[i]->payload->load_unload_info[1].module_type = + AMDB_MODULE_TYPE_DECODER; + pm[i]->payload->load_unload_info[1].id1 = + format_id; + + } else { + pr_err("%s:load usecase %d not supported\n", + __func__, use_case); + ret = -EINVAL; + goto fail; + } + +load_unload: + ret = q6core_avcs_load_unload_modules(pm[i]->payload, + AVCS_LOAD_MODULES); + + if (ret < 0) { + pr_err("%s: load failed %d\n", __func__, ret); + goto fail; + } + return 0; + } + + } + + ret = -EINVAL; + if (i == MAX_ALLOWED_USE_CASES) { + pr_err("%s: Not enough ports available\n", __func__); + return ret; + } +fail: + kfree(pm[i]->payload); + pm[i]->payload = NULL; + kfree(pm[i]); + pm[i] = NULL; + return ret; +} + static int afe_get_cal_hw_delay(int32_t path, struct audio_cal_hw_delay_entry *entry); static int remap_cal_data(struct cal_block_data *cal_block, int cal_index); @@ -4933,8 +5066,21 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, if ((codec_format != ASM_MEDIA_FMT_NONE) && (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) { if (enc_cfg != NULL) { - pr_debug("%s: Found AFE encoder support for SLIMBUS format = %d\n", + pr_debug("%s: Found AFE encoder support for SLIMBUS format = %d\n", __func__, codec_format); + + if ((q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= + AVCS_API_VERSION_V5)) { + ret = q6afe_load_avcs_modules(2, port_id, + ENCODER_CASE, codec_format); + if (ret < 0) { + pr_err("%s:encoder load for port 0x%x failed %d\n", + __func__, port_id, ret); + goto fail_cmd; + } + } + ret = q6afe_send_enc_config(port_id, enc_cfg, codec_format, *afe_config, afe_in_channels, @@ -4948,7 +5094,24 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, } if (dec_cfg != NULL) { pr_debug("%s: Found AFE decoder support for SLIMBUS format = %d\n", - __func__, codec_format); + __func__, codec_format); + + if ((q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= + AVCS_API_VERSION_V5)) { + /* LDAC doesn't require decoder */ + if (codec_format == ENC_CODEC_TYPE_LDAC) + ret = q6afe_load_avcs_modules(1, port_id, + DECODER_CASE, codec_format); + else + ret = q6afe_load_avcs_modules(2, port_id, + DECODER_CASE, codec_format); + if (ret < 0) { + pr_err("%s:decoder load for port 0x%x failed %d\n", + __func__, port_id, ret); + goto fail_cmd; + } + } ret = q6afe_send_dec_config(port_id, *afe_config, dec_cfg, codec_format, afe_in_channels, @@ -7747,6 +7910,7 @@ int afe_close(int port_id) struct afe_port_cmd_device_stop stop; enum afe_mad_type mad_type; int ret = 0; + u16 i; int index = 0; uint16_t port_index; @@ -7863,6 +8027,15 @@ int afe_close(int port_id) pr_err("%s: AFE close failed %d\n", __func__, ret); fail_cmd: + if ((q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= AVCS_API_VERSION_V5)) { + for (i = 0; i < MAX_ALLOWED_USE_CASES; i++) { + if (pm[i] && pm[i]->port_id == port_id) { + q6afe_unload_avcs_modules(port_id, i); + break; + } + } + } mutex_unlock(&this_afe.afe_cmd_lock); return ret; } diff --git a/dsp/q6core.c b/dsp/q6core.c index 15c00bdec764..8e8bedff42dd 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -61,9 +61,11 @@ struct q6core_str { wait_queue_head_t cmd_req_wait; wait_queue_head_t avcs_fwk_ver_req_wait; wait_queue_head_t lpass_npa_rsc_wait; + wait_queue_head_t avcs_module_load_unload_wait; u32 lpass_npa_rsc_rsp_rcvd; u32 bus_bw_resp_received; u32 mdf_map_resp_received; + u32 avcs_module_resp_received; enum cmd_flags { FLAG_NONE, FLAG_CMDRSP_LICENSE_RESULT @@ -87,6 +89,9 @@ struct q6core_str { static struct q6core_str q6core_lcl; +/* Global payload used for AVCS_CMD_RSP_MODULES command */ +static struct avcs_load_unload_modules_payload *rsp_payload; + struct generic_get_data_ { int valid; int size_in_ints; @@ -343,6 +348,29 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) q6core_lcl.lpass_npa_rsc_rsp_rcvd = 1; wake_up(&q6core_lcl.lpass_npa_rsc_wait); break; + case AVCS_CMD_LOAD_MODULES: + pr_err("%s: Cmd = %s failed status[%s]\n", + __func__, "AVCS_CMD_LOAD__MODULES", + adsp_err_get_err_str(payload1[1])); + q6core_lcl.avcs_module_resp_received = 1; + q6core_lcl.adsp_status = -payload1[1]; + wake_up(&q6core_lcl.avcs_module_load_unload_wait); + break; + case AVCS_CMD_UNLOAD_MODULES: + if (payload1[1] == ADSP_EOK) { + pr_debug("%s: Cmd = %s success status[%s]\n", + __func__, "AVCS_CMD_UNLOAD_MODULES", + "ADSP_EOK"); + } else { + pr_err("%s: Cmd = %s failed status[%s]\n", + __func__, "AVCS_CMD_UNLOAD_MODULES", + adsp_err_get_err_str(payload1[1])); + q6core_lcl.adsp_status = -payload1[1]; + } + q6core_lcl.avcs_module_resp_received = 1; + wake_up(&q6core_lcl.avcs_module_load_unload_wait); + break; + default: pr_err("%s: Invalid cmd rsp[0x%x][0x%x] opcode %d\n", __func__, @@ -441,6 +469,13 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) q6core_lcl.avcs_fwk_ver_resp_received = 1; wake_up(&q6core_lcl.avcs_fwk_ver_req_wait); break; + case AVCS_CMD_RSP_LOAD_MODULES: + pr_debug("%s: Received AVCS_CMD_RSP_LOAD_MODULES\n", + __func__); + memcpy(rsp_payload, data->payload, data->payload_size); + q6core_lcl.avcs_module_resp_received = 1; + wake_up(&q6core_lcl.avcs_module_load_unload_wait); + break; default: pr_err("%s: Message id from adsp core svc: 0x%x\n", __func__, data->opcode); @@ -821,7 +856,6 @@ int32_t core_get_license_status(uint32_t module_id) get_lvr_cmd.hdr.opcode = AVCS_CMD_GET_LICENSE_VALIDATION_RESULT; get_lvr_cmd.id = module_id; - ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) &get_lvr_cmd); if (ret < 0) { pr_err("%s: license_validation request failed, err %d\n", @@ -894,6 +928,105 @@ uint32_t core_set_dolby_manufacturer_id(int manufacturer_id) } EXPORT_SYMBOL(core_set_dolby_manufacturer_id); +int32_t q6core_avcs_load_unload_modules(struct avcs_load_unload_modules_payload + *payload, uint32_t preload_type) +{ + int ret = 0; + size_t packet_size = 0, payload_size = 0; + struct avcs_cmd_dynamic_modules *mod = NULL; + int num_modules; + + if (payload == NULL) { + pr_err("%s: payload is null\n", __func__); + return -EINVAL; + } + + mutex_lock(&(q6core_lcl.cmd_lock)); + num_modules = payload->num_modules; + ocm_core_open(); + + if (q6core_lcl.core_handle_q == NULL) { + pr_err("%s: apr registration for CORE failed\n", __func__); + mutex_unlock(&(q6core_lcl.cmd_lock)); + return -ENODEV; + } + + payload_size = (sizeof(struct avcs_load_unload_modules_sec_payload) + * num_modules) + sizeof(uint32_t); + packet_size = sizeof(struct avcs_cmd_dynamic_modules) + + payload_size - sizeof(uint32_t); + mod = kzalloc(packet_size, GFP_KERNEL); + + if (!mod) { + mutex_unlock(&(q6core_lcl.cmd_lock)); + return -ENOMEM; + } + + rsp_payload = kzalloc(payload_size, GFP_KERNEL); + if (!rsp_payload) { + kfree(mod); + mutex_unlock(&(q6core_lcl.cmd_lock)); + return -ENOMEM; + } + + memcpy((uint8_t *)mod + sizeof(struct apr_hdr) + + sizeof(struct avcs_load_unload_modules_meminfo), + payload, payload_size); + + mod->hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + mod->hdr.pkt_size = packet_size; + mod->hdr.src_port = 0; + mod->hdr.dest_port = 0; + mod->hdr.token = 0; + mod->meminfo.data_payload_addr_lsw = 0; + mod->meminfo.data_payload_addr_msw = 0; + mod->meminfo.mem_map_handle = 0; + mod->meminfo.buffer_size = payload_size; + + if (preload_type == AVCS_LOAD_MODULES) + mod->hdr.opcode = AVCS_CMD_LOAD_MODULES; + else + mod->hdr.opcode = AVCS_CMD_UNLOAD_MODULES; + + q6core_lcl.avcs_module_resp_received = 0; + ret = apr_send_pkt(q6core_lcl.core_handle_q, + (uint32_t *)mod); + + if (ret < 0) { + pr_err("%s: modules load/unload failed ret = %d\n", + __func__, ret); + goto done; + } + + ret = wait_event_timeout(q6core_lcl.avcs_module_load_unload_wait, + (q6core_lcl.avcs_module_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s wait event timeout for avcs load/unload module\n", + __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (q6core_lcl.adsp_status < 0) { + pr_err("%s: modules load/unload failed %d\n", __func__, + q6core_lcl.adsp_status); + ret = q6core_lcl.adsp_status; + goto done; + } else { + if (mod->hdr.opcode == AVCS_CMD_LOAD_MODULES) + memcpy(payload, rsp_payload, payload_size); + } +done: + kfree(mod); + kfree(rsp_payload); + mutex_unlock(&(q6core_lcl.cmd_lock)); + return ret; +} +EXPORT_SYMBOL(q6core_avcs_load_unload_modules); + int32_t q6core_load_unload_topo_modules(uint32_t topo_id, bool preload_type) { @@ -1871,7 +2004,6 @@ static int q6core_probe(struct platform_device *pdev) if (rc < 0) goto err; q6core_lcl.avs_state = avs_state; - rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); if (rc) { dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n", @@ -1926,6 +2058,7 @@ int __init core_init(void) init_waitqueue_head(&q6core_lcl.avcs_fwk_ver_req_wait); init_waitqueue_head(&q6core_lcl.mdf_map_resp_wait); init_waitqueue_head(&q6core_lcl.lpass_npa_rsc_wait); + init_waitqueue_head(&q6core_lcl.avcs_module_load_unload_wait); q6core_lcl.cmd_resp_received_flag = FLAG_NONE; mutex_init(&q6core_lcl.cmd_lock); mutex_init(&q6core_lcl.ver_lock); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index ca0f6ddb473c..18947379b98c 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -4137,6 +4137,16 @@ struct afe_id_aptx_adaptive_enc_init #define AFE_MODULE_ID_DEPACKETIZER_COP 0x00013233 #define AFE_MODULE_ID_DEPACKETIZER_COP_V1 0x000132E9 +/* Macros for dynamic loading of modules by AVCS */ + +#define AVS_MODULE_ID_PACKETIZER_COP 0x0001322A + +#define AVS_MODULE_ID_PACKETIZER_COP_V1 0x000132E8 + +#define AVS_MODULE_ID_DEPACKETIZER_COP 0x00013233 + +#define AVS_MODULE_ID_DEPACKETIZER_COP_V1 0x000132E9 + /* * Depacketizer type parameter for the #AVS_MODULE_ID_DECODER module. * This parameter cannot be set runtime. diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index 210471cd2d15..adfb83e86190 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -13,6 +13,7 @@ #define AVCS_CMD_ADSP_EVENT_GET_STATE 0x0001290C #define AVCS_CMDRSP_ADSP_EVENT_GET_STATE 0x0001290D #define AVCS_API_VERSION_V4 4 +#define AVCS_API_VERSION_V5 5 #define APRV2_IDS_SERVICE_ID_ADSP_CORE_V (0x3) bool q6core_is_adsp_ready(void); @@ -191,6 +192,126 @@ struct avcs_cmd_load_unload_topo_modules { uint32_t topology_id; } __packed; +#define AVCS_LOAD_MODULES 1 + +#define AVCS_UNLOAD_MODULES 0 + +#define AVCS_CMD_LOAD_MODULES 0x00012989 + +#define AVCS_CMD_UNLOAD_MODULES 0x0001298A + +#define AVCS_CMD_RSP_LOAD_MODULES 0x0001298B + +/* + * Module is generic, such as a preprocessor, + * postprocessor, or volume control + * module. + */ +#define AMDB_MODULE_TYPE_GENERIC 0 + +/** Module is a decoder. */ +#define AMDB_MODULE_TYPE_DECODER 1 + +/** Module is an encoder. */ +#define AMDB_MODULE_TYPE_ENCODER 2 + +/** Module is a converter. */ +#define AMDB_MODULE_TYPE_CONVERTER 3 + +/** Module is a packetizer. */ +#define AMDB_MODULE_TYPE_PACKETIZER 4 + +/** Module is a depacketizer. */ +#define AMDB_MODULE_TYPE_DEPACKETIZER 5 + + +struct avcs_load_unload_modules_sec_payload { + uint32_t module_type; + /* + * < Type of module. + + * @values + * - #AMDB_MODULE_TYPE_GENERIC + * - #AMDB_MODULE_TYPE_DECODER + * - #AMDB_MODULE_TYPE_ENCODER + * - #AMDB_MODULE_TYPE_CONVERTER + * - #AMDB_MODULE_TYPE_PACKETIZER + * - #AMDB_MODULE_TYPE_DEPACKETIZER + */ + + + uint32_t id1; + /* + * < One of the following types of IDs: + * - Format ID for the encoder, decoder, and packetizer module types + * - Module ID for the generic module type + * - Source format ID for the converter module type + */ + + uint32_t id2; + /* + * < Sink format ID for the converter module type. + * Zero for other module types + */ + + uint32_t handle_lsw; + /* < LSW of the Handle to the module loaded */ + + uint32_t handle_msw; + /* < MSW of the Handle to the module loaded. */ +} __packed; + +struct avcs_load_unload_modules_payload { + uint32_t num_modules; + /**< Number of modules being registered */ + + struct avcs_load_unload_modules_sec_payload load_unload_info[0]; + /* + * < Load/unload information for num_modules. + * It will be of type avcs_load_unload_info_t[num_modules] + */ +} __packed; + +struct avcs_load_unload_modules_meminfo { + uint32_t data_payload_addr_lsw; + /**< Lower 32 bits of the 64-bit data payload address. */ + + uint32_t data_payload_addr_msw; + /**< Upper 32 bits of the 64-bit data payload address. */ + + uint32_t mem_map_handle; + /* + * < Unique identifier for an address. The aDSP returns this memory map + * handle through the #AVCS_CMD_SHARED_MEM_MAP_REGIONS command. + + * @values @vertspace{-2} + * - NULL -- Parameter data payloads are within the message payload + * (in-band). + * - Non-NULL -- Parameter data payloads begin at the address specified + * in the data_payload_addr_lsw and data_payload_addr_msw fields + * (out-of-band). + + * The client can choose in-band or out-of-band + */ + + uint32_t buffer_size; + /* + * < Actual size (in bytes) of the valid data + * in the data payload address. + */ +} __packed; + +struct avcs_cmd_dynamic_modules { + struct apr_hdr hdr; + struct avcs_load_unload_modules_meminfo meminfo; + struct avcs_load_unload_modules_payload payload; +} __packed; + + +int32_t q6core_avcs_load_unload_modules(struct avcs_load_unload_modules_payload *payload, + uint32_t preload_type); + + /* This command allows a remote client(HLOS) creates a client to LPASS NPA * resource node. Currently, this command supports only the NPA Sleep resource * "/island/core/drivers" node ID. -- GitLab From 0e55cca9db4350bb3bbeb9980ecb0dca83f6d68a Mon Sep 17 00:00:00 2001 From: Guodong Hu Date: Thu, 21 May 2020 13:07:12 +0800 Subject: [PATCH 1527/1645] dsp: redefine audio_notifier_init to silence PDR error CONFIG_MSM_QDSP6_PDR is not enabled on Auto targets. Change-Id: If7ac374bbe88635eeb328593b4d3a9f01a716c5c Signed-off-by: Guodong Hu --- dsp/audio_notifier.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dsp/audio_notifier.c b/dsp/audio_notifier.c index 56cfa31fa645..7a8249dc3d0a 100644 --- a/dsp/audio_notifier.c +++ b/dsp/audio_notifier.c @@ -606,6 +606,7 @@ static int __init audio_notifier_late_init(void) return 0; } +#ifdef CONFIG_MSM_QDSP6_PDR static int __init audio_notifier_init(void) { int ret; @@ -624,6 +625,17 @@ static int __init audio_notifier_init(void) return 0; } +#else +static int __init audio_notifier_init(void) +{ + audio_notifier_subsys_init(); + audio_notifier_disable_service(AUDIO_NOTIFIER_PDR_SERVICE); + + audio_notifier_late_init(); + + return 0; +} +#endif module_init(audio_notifier_init); static void __exit audio_notifier_exit(void) -- GitLab From bd7bfe461144557b2744d1e16dcacc209e1d5a7c Mon Sep 17 00:00:00 2001 From: Kunlei Zhang Date: Tue, 11 Feb 2020 15:37:03 +0800 Subject: [PATCH 1528/1645] asoc: add wcd937x codec support in machine driver Add wcd937x codec support in machine driver for lagoon. Change-Id: Ie28579713aa99f28f447494e735f678ab6a72e0c Signed-off-by: Kunlei Zhang --- asoc/kona.c | 85 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 12 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index 33c24f1efd1a..80ddda41e2d7 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -33,6 +33,8 @@ #include "codecs/wsa881x.h" #include "codecs/wsa883x/wsa883x.h" #include "codecs/wcd938x/wcd938x.h" +#include "codecs/wcd937x/wcd937x-mbhc.h" +#include "codecs/wcd937x/wcd937x.h" #include "codecs/bolero/bolero-cdc.h" #include #include "codecs/bolero/wsa-macro.h" @@ -860,6 +862,23 @@ static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc85_dma_rx_3_sample_rate, static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc85_dma_rx_5_sample_rate, cdc_dma_sample_rate_text); +/* WCD937x */ +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_0_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_1_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_2_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_3_sample_rate, + cdc_dma_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(rx_cdc_dma_rx_5_sample_rate, + cdc_dma_sample_rate_text); + static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, @@ -3685,6 +3704,39 @@ static const struct snd_kcontrol_new msm_int_wcd9385_snd_controls[] = { cdc_dma_rx_sample_rate_put), }; +static const struct snd_kcontrol_new msm_int_wcd937x_snd_controls[] = { + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 Format", rx_cdc_dma_rx_0_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 Format", rx_cdc_dma_rx_1_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 Format", rx_cdc_dma_rx_2_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 Format", rx_cdc_dma_rx_3_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 Format", rx_cdc_dma_rx_5_format, + cdc_dma_rx_format_get, cdc_dma_rx_format_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_0 SampleRate", + rx_cdc_dma_rx_0_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_1 SampleRate", + rx_cdc_dma_rx_1_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_2 SampleRate", + rx_cdc_dma_rx_2_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_3 SampleRate", + rx_cdc_dma_rx_3_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), + SOC_ENUM_EXT("RX_CDC_DMA_RX_5 SampleRate", + rx_cdc_dma_rx_5_sample_rate, + cdc_dma_rx_sample_rate_get, + cdc_dma_rx_sample_rate_put), +}; + static const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, usb_audio_rx_sample_rate_get, @@ -7659,18 +7711,24 @@ static int msm_aux_codec_init(struct snd_soc_component *component) } pdata->codec_root = entry; } - wcd938x_info_create_codec_entry(pdata->codec_root, component); - - codec_variant = wcd938x_get_codec_variant(component); - dev_dbg(component->dev, "%s: variant %d\n", __func__, codec_variant); - if (codec_variant == WCD9380) + if (!strncmp(component->driver->name, "wcd937x", 7)) { + wcd937x_info_create_codec_entry(pdata->codec_root, component); ret = snd_soc_add_component_controls(component, - msm_int_wcd9380_snd_controls, - ARRAY_SIZE(msm_int_wcd9380_snd_controls)); - else if (codec_variant == WCD9385) - ret = snd_soc_add_component_controls(component, - msm_int_wcd9385_snd_controls, - ARRAY_SIZE(msm_int_wcd9385_snd_controls)); + msm_int_wcd937x_snd_controls, + ARRAY_SIZE(msm_int_wcd937x_snd_controls)); + } else { + wcd938x_info_create_codec_entry(pdata->codec_root, component); + codec_variant = wcd938x_get_codec_variant(component); + dev_dbg(component->dev, "%s: variant %d\n", __func__, codec_variant); + if (codec_variant == WCD9380) + ret = snd_soc_add_component_controls(component, + msm_int_wcd9380_snd_controls, + ARRAY_SIZE(msm_int_wcd9380_snd_controls)); + else if (codec_variant == WCD9385) + ret = snd_soc_add_component_controls(component, + msm_int_wcd9385_snd_controls, + ARRAY_SIZE(msm_int_wcd9385_snd_controls)); + } if (ret < 0) { dev_err(component->dev, "%s: add codec specific snd controls failed: %d\n", @@ -7683,7 +7741,10 @@ static int msm_aux_codec_init(struct snd_soc_component *component) if (!mbhc_calibration) return -ENOMEM; wcd_mbhc_cfg.calibration = mbhc_calibration; - ret = wcd938x_mbhc_hs_detect(component, &wcd_mbhc_cfg); + if (!strncmp(component->driver->name, "wcd937x", 7)) + ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg); + else + ret = wcd938x_mbhc_hs_detect(component, &wcd_mbhc_cfg); if (ret) { dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n", __func__, ret); -- GitLab From 2ecd7d48f39094e6004783c8e670f1983a99c8ab Mon Sep 17 00:00:00 2001 From: Zhou Song Date: Mon, 15 Jun 2020 20:46:17 +0800 Subject: [PATCH 1529/1645] dsp: don't reset rx ec ref channel after adm open Remove reset of rx ec ref channel for adm after using, if the channel value is not changed, user space won't set it to driver again, then causing adm opening failed. --- dsp/q6adm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index f98de7c57b51..51ca185b9ca2 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -3281,7 +3281,6 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, if ((this_adm.num_ec_ref_rx_chans != 0) && (path != ADM_PATH_PLAYBACK) && (open_v8.endpoint_id_2 != 0xFFFF)) { - this_adm.num_ec_ref_rx_chans = 0; memcpy(adm_params + sizeof(open_v8) + ep1_payload_size, (void *)&ep2_payload, -- GitLab From ca3b79b9729a1952a06d4f31c6917bd5bb9df341 Mon Sep 17 00:00:00 2001 From: "Vangala, Amarnath" Date: Wed, 13 May 2020 22:51:37 +0530 Subject: [PATCH 1530/1645] ASOC: macro name correction. Correction to macro name. Change-Id: I609df6b1a18231c285a5290872fa7b62ab9bffea Signed-off-by: Vangala, Amarnath --- include/uapi/linux/msm_audio_calibration.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h index 5562692d75f4..db968355149b 100644 --- a/include/uapi/linux/msm_audio_calibration.h +++ b/include/uapi/linux/msm_audio_calibration.h @@ -111,7 +111,7 @@ enum { #define AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE #define AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE -#define FE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE AFE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE +#define AFE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE AFE_FB_SPKR_PROT_V4_EX_VI_CAL_TYPE #define AFE_SIDETONE_IIR_CAL_TYPE AFE_SIDETONE_IIR_CAL_TYPE -- GitLab From 2ffc69ed68794e53437a9389f256e1d6dc6bb2d5 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 16 Jun 2020 20:15:26 +0530 Subject: [PATCH 1531/1645] Revert "soc: mstr-ctrl: Retain Audio_HM voting until suspend" This reverts commits ea6cbeeb1ad818c8c7907252409edb306c81d0ae and b06236e6377a48282b59410e0440b8be6d83095f. Change-Id: I0b8b44bc5cca6bef6bc18c228f08a9c585c79c1c Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc.c | 5 +-- asoc/codecs/bolero/bolero-cdc.h | 7 ++-- asoc/codecs/bolero/rx-macro.c | 2 - asoc/codecs/bolero/tx-macro.c | 32 +++------------ asoc/codecs/bolero/va-macro.c | 71 +-------------------------------- asoc/codecs/bolero/wsa-macro.c | 2 - soc/swr-mstr-ctrl.c | 23 +++++------ soc/swr-mstr-ctrl.h | 4 -- 8 files changed, 22 insertions(+), 124 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index afaadf900452..d7dc7d7d63b2 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -1090,7 +1090,7 @@ EXPORT_SYMBOL(bolero_tx_mclk_enable); * Returns 0 on success or -EINVAL on error. */ int bolero_register_event_listener(struct snd_soc_component *component, - bool enable, bool is_dmic_sva) + bool enable) { struct bolero_priv *priv = NULL; int ret = 0; @@ -1109,8 +1109,7 @@ int bolero_register_event_listener(struct snd_soc_component *component, if (priv->macro_params[TX_MACRO].reg_evt_listener) ret = priv->macro_params[TX_MACRO].reg_evt_listener(component, - enable, - is_dmic_sva); + enable); return ret; } diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index f4af2d920b12..bd52879fddb5 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -89,8 +89,7 @@ struct macro_ops { u32 size, void *data); int (*clk_div_get)(struct snd_soc_component *component); int (*clk_switch)(struct snd_soc_component *component, int clk_src); - int (*reg_evt_listener)(struct snd_soc_component *component, - bool en, bool is_dmic_sva); + int (*reg_evt_listener)(struct snd_soc_component *component, bool en); int (*clk_enable)(struct snd_soc_component *c, bool en); char __iomem *io_base; u16 clk_id_req; @@ -117,7 +116,7 @@ int bolero_runtime_suspend(struct device *dev); int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *data); int bolero_tx_clk_switch(struct snd_soc_component *component, int clk_src); int bolero_register_event_listener(struct snd_soc_component *component, - bool enable, bool is_dmic_sva); + bool enable); void bolero_wsa_pa_on(struct device *dev, bool adie_lb); bool bolero_check_core_votes(struct device *dev); int bolero_tx_mclk_enable(struct snd_soc_component *c, bool enable); @@ -191,7 +190,7 @@ static inline int bolero_tx_clk_switch(struct snd_soc_component *component, static inline int bolero_register_event_listener( struct snd_soc_component *component, - bool enable, bool is_dmic_sva) + bool enable) { return 0; } diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 523f3c7045e8..87b1e0c154f8 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -378,7 +378,6 @@ struct rx_swr_ctrl_platform_data { void *data), void *swrm_handle, int action); - int (*pinctrl_setup)(void *handle, bool enable); }; enum { @@ -4071,7 +4070,6 @@ static int rx_macro_probe(struct platform_device *pdev) rx_priv->swr_plat_data.clk = rx_swrm_clock; rx_priv->swr_plat_data.core_vote = rx_macro_core_vote; rx_priv->swr_plat_data.handle_irq = NULL; - rx_priv->swr_plat_data.pinctrl_setup = NULL; ret = of_property_read_u8_array(pdev->dev.of_node, "qcom,rx-bcl-pmic-params", bcl_pmic_params, diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 85e5e954f25a..16d79c918dcf 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -81,7 +81,6 @@ struct tx_macro_swr_ctrl_platform_data { void *data), void *swrm_handle, int action); - int (*pinctrl_setup)(void *handle, bool enable); }; enum { @@ -2388,30 +2387,12 @@ static const struct snd_kcontrol_new tx_macro_snd_controls[] = { tx_macro_get_bcs, tx_macro_set_bcs), }; -static int tx_macro_pinctrl_setup(void *handle, bool enable) -{ - struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle; - - if (tx_priv == NULL) { - pr_err("%s: tx priv data is NULL\n", __func__); - return -EINVAL; - } - if (enable) - msm_cdc_pinctrl_set_wakeup_capable( - tx_priv->tx_swr_gpio_p, true); - else - msm_cdc_pinctrl_set_wakeup_capable( - tx_priv->tx_swr_gpio_p, false); - return 0; -} - static int tx_macro_register_event_listener(struct snd_soc_component *component, - bool enable, bool is_dmic_sva) + bool enable) { struct device *tx_dev = NULL; struct tx_macro_priv *tx_priv = NULL; int ret = 0; - u32 dmic_sva = is_dmic_sva; if (!component) return -EINVAL; @@ -2433,17 +2414,15 @@ static int tx_macro_register_event_listener(struct snd_soc_component *component, if (enable) { ret = swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, - SWR_REGISTER_WAKEUP, &dmic_sva); + SWR_REGISTER_WAKEUP, NULL); msm_cdc_pinctrl_set_wakeup_capable( - tx_priv->tx_swr_gpio_p, false); + tx_priv->tx_swr_gpio_p, false); } else { - /* while teardown we can reset the flag */ - dmic_sva = 0; msm_cdc_pinctrl_set_wakeup_capable( - tx_priv->tx_swr_gpio_p, true); + tx_priv->tx_swr_gpio_p, true); ret = swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, - SWR_DEREGISTER_WAKEUP, &dmic_sva); + SWR_DEREGISTER_WAKEUP, NULL); } } @@ -3252,7 +3231,6 @@ static int tx_macro_probe(struct platform_device *pdev) tx_priv->swr_plat_data.clk = tx_macro_swrm_clock; tx_priv->swr_plat_data.core_vote = tx_macro_core_vote; tx_priv->swr_plat_data.handle_irq = NULL; - tx_priv->swr_plat_data.pinctrl_setup = tx_macro_pinctrl_setup; mutex_init(&tx_priv->swr_clk_lock); } tx_priv->is_used_tx_swr_gpio = is_used_tx_swr_gpio; diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 46e454344e20..f0a85ac07306 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -130,7 +130,6 @@ struct va_macro_swr_ctrl_platform_data { void *data), void *swrm_handle, int action); - int (*pinctrl_setup)(void *handle, bool enable); }; struct va_macro_priv { @@ -460,14 +459,14 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, dev_dbg(va_dev, "%s: clock switch failed\n", __func__); if (va_priv->lpi_enable) { - bolero_register_event_listener(component, true, false); + bolero_register_event_listener(component, true); va_priv->register_event_listener = true; } break; case SND_SOC_DAPM_POST_PMD: if (va_priv->register_event_listener) { va_priv->register_event_listener = false; - bolero_register_event_listener(component, false, false); + bolero_register_event_listener(component, false); } if (bolero_tx_clk_switch(component, CLK_SRC_TX_RCG)) dev_dbg(va_dev, "%s: clock switch failed\n",__func__); @@ -483,45 +482,6 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, return ret; } -static int va_macro_swr_intr_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_component *component = - snd_soc_dapm_to_component(w->dapm); - int ret = 0; - struct device *va_dev = NULL; - struct va_macro_priv *va_priv = NULL; - - if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) - return -EINVAL; - - dev_dbg(va_dev, "%s: event = %d, lpi_enable = %d\n", - __func__, event, va_priv->lpi_enable); - - if (!va_priv->lpi_enable) - return ret; - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (va_priv->lpi_enable) { - bolero_register_event_listener(component, true, true); - va_priv->register_event_listener = true; - } - break; - case SND_SOC_DAPM_POST_PMD: - if (va_priv->register_event_listener) { - va_priv->register_event_listener = false; - bolero_register_event_listener(component, false, true); - } - break; - default: - dev_err(va_priv->dev, - "%s: invalid DAPM event %d\n", __func__, event); - ret = -EINVAL; - } - return ret; -} - static int va_macro_tx_swr_clk_event_v2(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -2004,10 +1964,6 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v3[] = { SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0, va_macro_swr_pwr_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SUPPLY_S("VA_SWR_INTR", 0, SND_SOC_NOPM, 0, 0, - va_macro_swr_intr_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = { @@ -2152,10 +2108,6 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0, va_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SUPPLY_S("VA_SWR_INTR", 0, SND_SOC_NOPM, 0, 0, - va_macro_swr_intr_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; static const struct snd_soc_dapm_widget va_macro_wod_dapm_widgets[] = { @@ -2302,15 +2254,6 @@ static const struct snd_soc_dapm_route va_audio_map_v3[] = { {"VA SMIC MUX3", "SWR_MIC9", "VA SWR_MIC9"}, {"VA SMIC MUX3", "SWR_MIC10", "VA SWR_MIC10"}, {"VA SMIC MUX3", "SWR_MIC11", "VA SWR_MIC11"}, - - {"VA DMIC0", NULL, "VA_SWR_INTR"}, - {"VA DMIC1", NULL, "VA_SWR_INTR"}, - {"VA DMIC2", NULL, "VA_SWR_INTR"}, - {"VA DMIC3", NULL, "VA_SWR_INTR"}, - {"VA DMIC4", NULL, "VA_SWR_INTR"}, - {"VA DMIC5", NULL, "VA_SWR_INTR"}, - {"VA DMIC6", NULL, "VA_SWR_INTR"}, - {"VA DMIC7", NULL, "VA_SWR_INTR"}, }; static const struct snd_soc_dapm_route va_audio_map_v2[] = { @@ -2547,15 +2490,6 @@ static const struct snd_soc_dapm_route va_audio_map[] = { {"VA SMIC MUX7", "SWR_DMIC6", "VA SWR_MIC6"}, {"VA SMIC MUX7", "SWR_DMIC7", "VA SWR_MIC7"}, - {"VA DMIC0", NULL, "VA_SWR_INTR"}, - {"VA DMIC1", NULL, "VA_SWR_INTR"}, - {"VA DMIC2", NULL, "VA_SWR_INTR"}, - {"VA DMIC3", NULL, "VA_SWR_INTR"}, - {"VA DMIC4", NULL, "VA_SWR_INTR"}, - {"VA DMIC5", NULL, "VA_SWR_INTR"}, - {"VA DMIC6", NULL, "VA_SWR_INTR"}, - {"VA DMIC7", NULL, "VA_SWR_INTR"}, - {"VA SWR_ADC0", NULL, "VA_SWR_PWR"}, {"VA SWR_ADC1", NULL, "VA_SWR_PWR"}, {"VA SWR_ADC2", NULL, "VA_SWR_PWR"}, @@ -3216,7 +3150,6 @@ static int va_macro_probe(struct platform_device *pdev) va_priv->swr_plat_data.clk = va_macro_swrm_clock; va_priv->swr_plat_data.core_vote = va_macro_core_vote; va_priv->swr_plat_data.handle_irq = NULL; - va_priv->swr_plat_data.pinctrl_setup = NULL; mutex_init(&va_priv->swr_clk_lock); } va_priv->is_used_va_swr_gpio = is_used_va_swr_gpio; diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index fd8a3a84479a..d2852eea9e71 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -166,7 +166,6 @@ struct wsa_macro_swr_ctrl_platform_data { void *data), void *swrm_handle, int action); - int (*pinctrl_setup)(void *handle, bool enable); }; struct wsa_macro_bcl_pmic_params { @@ -3200,7 +3199,6 @@ static int wsa_macro_probe(struct platform_device *pdev) wsa_priv->swr_plat_data.clk = wsa_swrm_clock; wsa_priv->swr_plat_data.core_vote = wsa_macro_core_vote; wsa_priv->swr_plat_data.handle_irq = NULL; - wsa_priv->swr_plat_data.pinctrl_setup = NULL; ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id", &default_clk_id); diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 2e7779ac402d..998cddcc26b2 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2573,8 +2573,6 @@ static int swrm_probe(struct platform_device *pdev) ret = -EINVAL; goto err_pdata_fail; } - swrm->pinctrl_setup = pdata->pinctrl_setup; - if (of_property_read_u32(pdev->dev.of_node, "qcom,swr-clock-stop-mode0", &swrm->clk_stop_mode0_supp)) { @@ -2907,6 +2905,7 @@ static int swrm_runtime_resume(struct device *dev) int ret = 0; bool swrm_clk_req_err = false; bool hw_core_err = false; + bool aud_core_err = false; struct swr_master *mstr = &swrm->master; struct swr_device *swr_dev; @@ -2924,7 +2923,7 @@ static int swrm_runtime_resume(struct device *dev) if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { dev_err(dev, "%s:lpass audio hw enable failed\n", __func__); - swrm->aud_core_err = true; + aud_core_err = true; } if ((swrm->state == SWR_MSTR_DOWN) || @@ -2943,9 +2942,6 @@ static int swrm_runtime_resume(struct device *dev) irq_get_irq_data(swrm->wake_irq))) disable_irq_nosync(swrm->wake_irq); mutex_unlock(&swrm->irq_lock); - if (swrm->dmic_sva && swrm->pinctrl_setup) - swrm->pinctrl_setup(swrm->handle, - false); } if (swrm->ipc_wakeup) msm_aud_evt_blocking_notifier_call_chain( @@ -3013,7 +3009,7 @@ static int swrm_runtime_resume(struct device *dev) swrm->state = SWR_MSTR_UP; } exit: - if (ret && !swrm->aud_core_err) + if (!aud_core_err) swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); @@ -3038,6 +3034,7 @@ static int swrm_runtime_suspend(struct device *dev) struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); int ret = 0; bool hw_core_err = false; + bool aud_core_err = false; struct swr_master *mstr = &swrm->master; struct swr_device *swr_dev; int current_state = 0; @@ -3056,6 +3053,11 @@ static int swrm_runtime_suspend(struct device *dev) __func__); hw_core_err = true; } + if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { + dev_err(dev, "%s:lpass audio hw enable failed\n", + __func__); + aud_core_err = true; + } if ((current_state == SWR_MSTR_UP) || (current_state == SWR_MSTR_SSR)) { @@ -3140,8 +3142,6 @@ static int swrm_runtime_suspend(struct device *dev) if (swrm->clk_stop_mode0_supp) { if (swrm->wake_irq > 0) { - if (swrm->dmic_sva && swrm->pinctrl_setup) - swrm->pinctrl_setup(swrm->handle, true); enable_irq(swrm->wake_irq); } else if (swrm->ipc_wakeup) { msm_aud_evt_blocking_notifier_call_chain( @@ -3155,11 +3155,10 @@ static int swrm_runtime_suspend(struct device *dev) if (current_state != SWR_MSTR_SSR) swrm->state = SWR_MSTR_DOWN; exit: - if (!swrm->aud_core_err) + if (!aud_core_err) swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); - swrm->aud_core_err = false; mutex_unlock(&swrm->reslock); trace_printk("%s: pm_runtime: suspend done state: %d\n", __func__, swrm->state); @@ -3490,12 +3489,10 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) case SWR_REGISTER_WAKEUP: msm_aud_evt_blocking_notifier_call_chain( SWR_WAKE_IRQ_REGISTER, (void *)swrm); - swrm->dmic_sva = *(u32 *)data; break; case SWR_DEREGISTER_WAKEUP: msm_aud_evt_blocking_notifier_call_chain( SWR_WAKE_IRQ_DEREGISTER, (void *)swrm); - swrm->dmic_sva = 0; break; case SWR_SET_PORT_MAP: if (!data) { diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index c7d42b0da0fb..8d38441289b9 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -108,7 +108,6 @@ struct swr_ctrl_platform_data { int (*core_vote)(void *handle, bool enable); int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq, void *data), void *swr_handle, int type); - int (*pinctrl_setup)(void *handle, bool enable); }; struct swr_mstr_ctrl { @@ -141,7 +140,6 @@ struct swr_mstr_ctrl { int (*core_vote)(void *handle, bool enable); int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq, void *data), void *swr_handle, int type); - int (*pinctrl_setup)(void *handle, bool enable); int irq; int wake_irq; int version; @@ -167,10 +165,8 @@ struct swr_mstr_ctrl { u32 clk_stop_mode0_supp; struct work_struct wakeup_work; u32 ipc_wakeup; - u32 dmic_sva; bool dev_up; bool ipc_wakeup_triggered; - bool aud_core_err; bool req_clk_switch; struct pm_qos_request pm_qos_req; enum swrm_pm_state pm_state; -- GitLab From e83115d27b0eff727fa12687485590d3aa79db23 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Wed, 24 Jun 2020 20:38:03 +0530 Subject: [PATCH 1532/1645] asoc: codecs: remove cancel_delayed_work_sync to avoid race condition Remove cancel_delayed_work_sync in swr_down,to avoid race condition between skr_pa_event POST_PMD and swr_down.we are taking care of schedule_delayed_work and cancel_delayed_work_sync in PMU and PMD. Change-Id: I4f43ffc354ec930dabd7c4a8b2382f6064a24653 Signed-off-by: Prasad Kumpatla --- asoc/codecs/wsa881x.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index c72fcc1c2c71..8850ea60935a 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -1609,8 +1609,6 @@ static int wsa881x_swr_down(struct swr_device *pdev) else wsa881x->state = WSA881X_DEV_DOWN; - if (delayed_work_pending(&wsa881x->ocp_ctl_work)) - cancel_delayed_work_sync(&wsa881x->ocp_ctl_work); return ret; } -- GitLab From d4e346813cb764d3a6bb2f35ff22c43844d8cab2 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Thu, 25 Jun 2020 19:38:34 +0530 Subject: [PATCH 1533/1645] asoc: Add check for substream ref_count before access the substream. Add check for substream ref count before access the substream. Change-Id: Iccb6226519e8fddf624f82160a0d8d22641944db Signed-off-by: Prasad Kumpatla --- asoc/msm-pcm-loopback-v2.c | 34 ++++++++++++-------- asoc/msm-pcm-q6-noirq.c | 18 ++++++----- asoc/msm-pcm-q6-v2.c | 63 ++++++++++++++++++++++++++++---------- 3 files changed, 80 insertions(+), 35 deletions(-) diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index af6be3ad4515..4da7848daacb 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -551,13 +551,15 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, goto exit; } mutex_lock(&loopback_session_lock); - prtd = substream->runtime->private_data; - if (!prtd) { - rc = -ENODEV; - mutex_unlock(&loopback_session_lock); - goto exit; + if (substream->ref_count > 0) { + prtd = substream->runtime->private_data; + if (!prtd) { + rc = -ENODEV; + mutex_unlock(&loopback_session_lock); + goto exit; + } + rc = pcm_loopback_set_volume(prtd, volume); } - rc = pcm_loopback_set_volume(prtd, volume); mutex_unlock(&loopback_session_lock); exit: return rc; @@ -583,13 +585,15 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, goto exit; } mutex_lock(&loopback_session_lock); - prtd = substream->runtime->private_data; - if (!prtd) { - rc = -ENODEV; - mutex_unlock(&loopback_session_lock); - goto exit; + if (substream->ref_count > 0) { + prtd = substream->runtime->private_data; + if (!prtd) { + rc = -ENODEV; + mutex_unlock(&loopback_session_lock); + goto exit; + } + ucontrol->value.integer.value[0] = prtd->volume; } - ucontrol->value.integer.value[0] = prtd->volume; mutex_unlock(&loopback_session_lock); exit: return rc; @@ -877,6 +881,12 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, chmixer_pspd); mutex_lock(&loopback_session_lock); + if (substream->ref_count <= 0) { + pr_err_ratelimited("%s: substream ref_count:%d invalid\n", + __func__, substream->ref_count); + mutex_unlock(&loopback_session_lock); + return -EINVAL; + } if (chmixer_pspd->enable && substream->runtime) { prtd = substream->runtime->private_data; if (!prtd) { diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index 8fb6f7cd4995..e3f59e8dc502 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -754,9 +754,11 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, return -ENODEV; } mutex_lock(&pdata->lock); - prtd = substream->runtime->private_data; - if (prtd) - ucontrol->value.integer.value[0] = prtd->volume; + if (substream->ref_count > 0) { + prtd = substream->runtime->private_data; + if (prtd) + ucontrol->value.integer.value[0] = prtd->volume; + } mutex_unlock(&pdata->lock); return 0; } @@ -799,10 +801,12 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, } mutex_lock(&pdata->lock); - prtd = substream->runtime->private_data; - if (prtd) { - rc = msm_pcm_set_volume(prtd, volume); - prtd->volume = volume; + if (substream->ref_count > 0) { + prtd = substream->runtime->private_data; + if (prtd) { + rc = msm_pcm_set_volume(prtd, volume); + prtd->volume = volume; + } } mutex_unlock(&pdata->lock); return rc; diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index c22c39ba3ec0..2fc5c8459263 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1325,7 +1325,12 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, ret = -EINVAL; goto done; } - + if (substream->ref_count <= 0) { + pr_err_ratelimited("%s substream ref_count:%d invalid\n", + __func__, substream->ref_count); + ret = -EINVAL; + goto done; + } prtd = substream->runtime->private_data; if (prtd == NULL) { pr_err("%s prtd is null.\n", __func__); @@ -1549,9 +1554,11 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, } mutex_lock(&pdata->lock); - prtd = substream->runtime->private_data; - if (prtd) - ucontrol->value.integer.value[0] = prtd->volume; + if (substream->ref_count > 0) { + prtd = substream->runtime->private_data; + if (prtd) + ucontrol->value.integer.value[0] = prtd->volume; + } mutex_unlock(&pdata->lock); return 0; } @@ -1595,10 +1602,12 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, } mutex_lock(&pdata->lock); - prtd = substream->runtime->private_data; - if (prtd) { - rc = msm_pcm_set_volume(prtd, volume); - prtd->volume = volume; + if (substream->ref_count > 0) { + prtd = substream->runtime->private_data; + if (prtd) { + rc = msm_pcm_set_volume(prtd, volume); + prtd->volume = volume; + } } mutex_unlock(&pdata->lock); return rc; @@ -1659,9 +1668,11 @@ static int msm_pcm_compress_ctl_get(struct snd_kcontrol *kcontrol, return 0; } mutex_lock(&pdata->lock); - prtd = substream->runtime->private_data; - if (prtd) - ucontrol->value.integer.value[0] = prtd->compress_enable; + if (substream->ref_count > 0) { + prtd = substream->runtime->private_data; + if (prtd) + ucontrol->value.integer.value[0] = prtd->compress_enable; + } mutex_unlock(&pdata->lock); return 0; } @@ -1691,11 +1702,13 @@ static int msm_pcm_compress_ctl_put(struct snd_kcontrol *kcontrol, return 0; } mutex_lock(&pdata->lock); - prtd = substream->runtime->private_data; - if (prtd) { - pr_debug("%s: setting compress flag to 0x%x\n", - __func__, compress); - prtd->compress_enable = compress; + if (substream->ref_count > 0) { + prtd = substream->runtime->private_data; + if (prtd) { + pr_debug("%s: setting compress flag to 0x%x\n", + __func__, compress); + prtd->compress_enable = compress; + } } mutex_unlock(&pdata->lock); return rc; @@ -1805,6 +1818,12 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol, return 0; mutex_lock(&pdata->lock); + if (substream->ref_count <= 0) { + pr_err_ratelimited("%s: substream ref_count:%d invalid\n", + __func__, substream->ref_count); + mutex_unlock(&pdata->lock); + return -EINVAL; + } prtd = substream->runtime ? substream->runtime->private_data : NULL; if (prtd) { prtd->set_channel_map = true; @@ -1872,6 +1891,12 @@ static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol, return 0; /* no channels set */ mutex_lock(&pdata->lock); + if (substream->ref_count <= 0) { + pr_err_ratelimited("%s: substream ref_count:%d invalid\n", + __func__, substream->ref_count); + mutex_unlock(&pdata->lock); + return -EINVAL; + } prtd = substream->runtime ? substream->runtime->private_data : NULL; if (prtd && prtd->set_channel_map == true) { @@ -2154,6 +2179,12 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, } mutex_lock(&pdata->lock); + if (substream->ref_count <= 0) { + pr_err_ratelimited("%s: substream ref_count:%d invalid\n", + __func__, substream->ref_count); + mutex_unlock(&pdata->lock); + return -EINVAL; + } prtd = substream->runtime ? substream->runtime->private_data : NULL; if (chmixer_pspd->enable && prtd) { if (session_type == SESSION_TYPE_RX && -- GitLab From e44b8fb55e433dd5d205b276e45b9b96d3531848 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 25 Jun 2020 11:43:18 +0530 Subject: [PATCH 1534/1645] soc: swr-mstr: Add delay of 100us after last write during bulk write There is no delay after last write during bulk write. Add 100us delay so as to ensure that last write goes fine. Change-Id: Ifc1585f30eec639ffd6b80dde2e0365f368349d7 Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 2e7779ac402d..512ef618f708 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -622,6 +622,7 @@ static int swr_master_bulk_write(struct swr_mstr_ctrl *swrm, u32 *reg_addr, usleep_range(50, 55); swr_master_write(swrm, reg_addr[i], val[i]); } + usleep_range(100, 110); mutex_unlock(&swrm->iolock); } return 0; -- GitLab From 75ad8c137af924186fdec5d06fd64dd7603c480a Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 22 Jun 2020 09:46:36 +0530 Subject: [PATCH 1535/1645] ASoC: bolero: Resolve glitch during amic record Glitch is observed during amic record due to improper sequence being followed. Reduce delay between toggle of hpf gate to depending on sample rate to resolve glitch. Change-Id: I8d9810dbc00264662f24532be9338198e6d7316d Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/tx-macro.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 16d79c918dcf..500876b21875 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -175,6 +175,7 @@ struct tx_macro_priv { int dec_mode[NUM_DECIMATORS]; bool bcs_clk_en; bool hs_slow_insert_complete; + int amic_sample_rate; }; static bool tx_macro_get_data(struct snd_soc_component *component, @@ -499,6 +500,29 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) hpf_cut_off_freq << 5); snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x02); + /* Add delay between toggle hpf gate based on sample rate */ + switch(tx_priv->amic_sample_rate) { + case 8000: + usleep_range(125, 130); + break; + case 16000: + usleep_range(62, 65); + break; + case 32000: + usleep_range(31, 32); + break; + case 48000: + usleep_range(20, 21); + break; + case 96000: + usleep_range(10, 11); + break; + case 192000: + usleep_range(5, 6); + break; + default: + usleep_range(125, 130); + } snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x01); } else { @@ -901,6 +925,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, u16 dec_cfg_reg = 0; u16 hpf_gate_reg = 0; u16 tx_gain_ctl_reg = 0; + u16 tx_fs_reg = 0; u8 hpf_cut_off_freq = 0; int hpf_delay = TX_MACRO_DMIC_HPF_DELAY_MS; int unmute_delay = TX_MACRO_DMIC_UNMUTE_DELAY_MS; @@ -925,6 +950,11 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, TX_MACRO_TX_PATH_OFFSET * decimator; tx_gain_ctl_reg = BOLERO_CDC_TX0_TX_VOL_CTL + TX_MACRO_TX_PATH_OFFSET * decimator; + tx_fs_reg = BOLERO_CDC_TX0_TX_PATH_CTL + + TX_MACRO_TX_PATH_OFFSET * decimator; + + tx_priv->amic_sample_rate = (snd_soc_component_read32(component, + tx_fs_reg) & 0x0F); switch (event) { case SND_SOC_DAPM_PRE_PMU: -- GitLab From b1a33c4c0239812105fd94203400a4a933859b23 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 2 Jul 2020 18:52:46 +0530 Subject: [PATCH 1536/1645] ASoC: rouleur-mbhc: Fix aux cable detected as unsupported sometimes Aux cable is detected as unsupported sometimes due to it being detected as cross conn. Increase hph cross conn threshold to 350mV so that it detects fine. Change-Id: I87e4bd36f80d7cd62e06c76acf9c9d06bb6f148a Signed-off-by: Vatsal Bucha --- asoc/codecs/rouleur/rouleur-mbhc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/rouleur/rouleur-mbhc.c b/asoc/codecs/rouleur/rouleur-mbhc.c index f0eea091cba5..c7ba03cd2b1a 100644 --- a/asoc/codecs/rouleur/rouleur-mbhc.c +++ b/asoc/codecs/rouleur/rouleur-mbhc.c @@ -33,8 +33,8 @@ #define ROULEUR_ZDET_C3 4500 /* Cross connection thresholds in mV */ -#define ROULEUR_HPHL_CROSS_CONN_THRESHOLD 200 -#define ROULEUR_HPHR_CROSS_CONN_THRESHOLD 200 +#define ROULEUR_HPHL_CROSS_CONN_THRESHOLD 350 +#define ROULEUR_HPHR_CROSS_CONN_THRESHOLD 350 static struct wcd_mbhc_register wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = { -- GitLab From e55d0fcb406ed7e876f585d6bda1ae92972fe65b Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 2 Jul 2020 18:12:35 +0530 Subject: [PATCH 1537/1645] ASoC: wcd938x: Reduce glitch during headset record Enable ADC Mode and tx channel cfg as part of enable_adc. This should be enabled before enabling bolero dec so as to reduce glitch or saturation for headset. Change-Id: I94045d0c3b7b96744afb9e6a9a3eecf0abc5a55f Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd938x/wcd938x.c | 139 +++++++++++++++++----------------- 1 file changed, 69 insertions(+), 70 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 3f6292c95849..511fd1f22414 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1591,69 +1591,6 @@ static int wcd938x_get_adc_mode(int val) return ret; } -static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event){ - struct snd_soc_component *component = - snd_soc_dapm_to_component(w->dapm); - struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); - int clk_rate = 0; - - dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, - w->name, event); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x08); - snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); - set_bit(w->shift, &wcd938x->status_mask); - clk_rate = wcd938x_get_clk_rate(wcd938x->tx_mode[w->shift]); - /* Enable BCS for Headset mic */ - if (w->shift == 1 && !(snd_soc_component_read32(component, - WCD938X_TX_NEW_AMIC_MUX_CFG) & 0x80)) { - if (!wcd938x->bcs_dis) - wcd938x_tx_connect_port(component, MBHC, - SWR_CLK_RATE_4P8MHZ, true); - set_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask); - } - wcd938x_tx_connect_port(component, ADC1 + (w->shift), clk_rate, - true); - break; - case SND_SOC_DAPM_POST_PMD: - wcd938x_tx_connect_port(component, ADC1 + (w->shift), 0, false); - if (w->shift == 1 && - test_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask)) { - if (!wcd938x->bcs_dis) - wcd938x_tx_connect_port(component, MBHC, 0, - false); - clear_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask); - } - snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00); - clear_bit(w->shift, &wcd938x->status_mask); - break; - }; - - return 0; -} - -void wcd938x_disable_bcs_before_slow_insert(struct snd_soc_component *component, - bool bcs_disable) -{ - struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); - - if (wcd938x->update_wcd_event) { - if (bcs_disable) - wcd938x->update_wcd_event(wcd938x->handle, - WCD_BOLERO_EVT_BCS_CLK_OFF, 0); - else - wcd938x->update_wcd_event(wcd938x->handle, - WCD_BOLERO_EVT_BCS_CLK_OFF, 1); - } -} - int wcd938x_tx_channel_config(struct snd_soc_component *component, int channel, int mode) { @@ -1694,14 +1631,14 @@ int wcd938x_tx_channel_config(struct snd_soc_component *component, return ret; } -static int wcd938x_enable_req(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ +static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event){ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - int mode; - int ret = 0; struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + int clk_rate = 0, mode; + int ret = 0; dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, w->name, event); @@ -1709,9 +1646,21 @@ static int wcd938x_enable_req(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_REQ_CTL, 0x02, 0x02); + WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x08); snd_soc_component_update_bits(component, - WCD938X_DIGITAL_CDC_REQ_CTL, 0x01, 0x00); + WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); + set_bit(w->shift, &wcd938x->status_mask); + clk_rate = wcd938x_get_clk_rate(wcd938x->tx_mode[w->shift]); + /* Enable BCS for Headset mic */ + if (w->shift == 1 && !(snd_soc_component_read32(component, + WCD938X_TX_NEW_AMIC_MUX_CFG) & 0x80)) { + if (!wcd938x->bcs_dis) + wcd938x_tx_connect_port(component, MBHC, + SWR_CLK_RATE_4P8MHZ, true); + set_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask); + } + wcd938x_tx_connect_port(component, ADC1 + (w->shift), clk_rate, + true); ret = wcd938x_tx_channel_config(component, w->shift, 1); mode = wcd938x_get_adc_mode(wcd938x->tx_mode[w->shift]); if (mode < 0) { @@ -1787,6 +1736,56 @@ static int wcd938x_enable_req(struct snd_soc_dapm_widget *w, default: break; } + wcd938x_tx_connect_port(component, ADC1 + (w->shift), 0, false); + if (w->shift == 1 && + test_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask)) { + if (!wcd938x->bcs_dis) + wcd938x_tx_connect_port(component, MBHC, 0, + false); + clear_bit(AMIC2_BCS_ENABLE, &wcd938x->status_mask); + } + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00); + clear_bit(w->shift, &wcd938x->status_mask); + break; + }; + + return 0; +} + +void wcd938x_disable_bcs_before_slow_insert(struct snd_soc_component *component, + bool bcs_disable) +{ + struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + + if (wcd938x->update_wcd_event) { + if (bcs_disable) + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_BCS_CLK_OFF, 0); + else + wcd938x->update_wcd_event(wcd938x->handle, + WCD_BOLERO_EVT_BCS_CLK_OFF, 1); + } +} + +static int wcd938x_enable_req(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + int ret = 0; + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_REQ_CTL, 0x02, 0x02); + snd_soc_component_update_bits(component, + WCD938X_DIGITAL_CDC_REQ_CTL, 0x01, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: snd_soc_component_update_bits(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00); break; -- GitLab From 9dd95164292c672b4768288796afc5488cbdadf9 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 18 Jun 2020 08:57:27 +0530 Subject: [PATCH 1538/1645] soc: swr-mstr: Fix KW issue in swrm_remove Irq pointer is first freed and then used in irq_set_trigger_type and set wakeup capable. This may lead to Null pointer dereference if irq is NULL. Free irq after using it. Change-Id: I86339e9995922cc8111f12593eb781226bb07a2a Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 73439eeabaf0..beaaa26f2833 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2828,13 +2828,14 @@ static int swrm_probe(struct platform_device *pdev) swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, SWR_IRQ_FREE); } else if (swrm->irq) { + if (irq_get_irq_data(swrm->irq) != NULL) + irqd_set_trigger_type( + irq_get_irq_data(swrm->irq), + IRQ_TYPE_NONE); + if (swrm->swr_irq_wakeup_capable) + irq_set_irq_wake(swrm->irq, 0); free_irq(swrm->irq, swrm); - irqd_set_trigger_type( - irq_get_irq_data(swrm->irq), - IRQ_TYPE_NONE); } - if (swrm->swr_irq_wakeup_capable) - irq_set_irq_wake(swrm->irq, 0); err_irq_fail: mutex_destroy(&swrm->irq_lock); mutex_destroy(&swrm->mlock); @@ -2858,15 +2859,16 @@ static int swrm_remove(struct platform_device *pdev) swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm, SWR_IRQ_FREE); } else if (swrm->irq) { + if (irq_get_irq_data(swrm->irq) != NULL) + irqd_set_trigger_type( + irq_get_irq_data(swrm->irq), + IRQ_TYPE_NONE); + if (swrm->swr_irq_wakeup_capable) + irq_set_irq_wake(swrm->irq, 0); free_irq(swrm->irq, swrm); - irqd_set_trigger_type( - irq_get_irq_data(swrm->irq), - IRQ_TYPE_NONE); } else if (swrm->wake_irq > 0) { free_irq(swrm->wake_irq, swrm); } - if (swrm->swr_irq_wakeup_capable) - irq_set_irq_wake(swrm->irq, 0); cancel_work_sync(&swrm->wakeup_work); pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); -- GitLab From 251ce993dd69fc33890c2904165737fa971fd219 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 1 Jul 2020 23:37:33 +0530 Subject: [PATCH 1539/1645] asoc: bolero: Ensure va-macro is registered before other macros As va-macro has fs_clk gen, ensure va-macro is registered before other macros. Change-Id: I8283dc11817caf0c208fe231132951a7a79b7d51 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc.c | 24 +++++++++++++++++++++++- asoc/codecs/bolero/bolero-cdc.h | 6 ++++++ asoc/codecs/bolero/rx-macro.c | 6 ++++++ asoc/codecs/bolero/tx-macro.c | 6 ++++++ asoc/codecs/bolero/wsa-macro.c | 7 +++++++ 5 files changed, 48 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index d7dc7d7d63b2..233a0b4b40a9 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -600,6 +600,28 @@ int bolero_dmic_clk_enable(struct snd_soc_component *component, } EXPORT_SYMBOL(bolero_dmic_clk_enable); +bool bolero_is_va_macro_registered(struct device *dev) +{ + struct bolero_priv *priv; + + if (!dev) { + pr_err("%s: dev is null\n", __func__); + return false; + } + if (!bolero_is_valid_child_dev(dev)) { + dev_err(dev, "%s: child device calling is not added yet\n", + __func__); + return false; + } + priv = dev_get_drvdata(dev->parent); + if (!priv) { + dev_err(dev, "%s: priv is null\n", __func__); + return false; + } + return priv->macros_supported[VA_MACRO]; +} +EXPORT_SYMBOL(bolero_is_va_macro_registered); + /** * bolero_register_macro - Registers macro to bolero * @@ -661,7 +683,7 @@ int bolero_register_macro(struct device *dev, u16 macro_id, priv->num_macros_registered++; priv->macros_supported[macro_id] = true; - dev_dbg(dev, "%s: register macro successful:%d\n", __func__, macro_id); + dev_info(dev, "%s: register macro successful:%d\n", __func__, macro_id); if (priv->num_macros_registered == priv->num_macros) { ret = bolero_copy_dais_from_macro(priv); diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index bd52879fddb5..7e3468a8fa1a 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -101,6 +101,7 @@ typedef int (*rsc_clk_cb_t)(struct device *dev, u16 event); #if IS_ENABLED(CONFIG_SND_SOC_BOLERO) int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb); void bolero_unregister_res_clk(struct device *dev); +bool bolero_is_va_macro_registered(struct device *dev); int bolero_register_macro(struct device *dev, u16 macro_id, struct macro_ops *ops); void bolero_unregister_macro(struct device *dev, u16 macro_id); @@ -132,6 +133,11 @@ static inline void bolero_unregister_res_clk(struct device *dev) { } +static bool bolero_is_va_macro_registered(struct device *dev) +{ + return false; +} + static inline int bolero_register_macro(struct device *dev, u16 macro_id, struct macro_ops *ops) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 87b1e0c154f8..c858d2c65356 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -3994,6 +3994,12 @@ static int rx_macro_probe(struct platform_device *pdev) u32 is_used_rx_swr_gpio = 1; const char *is_used_rx_swr_gpio_dt = "qcom,is-used-swr-gpio"; + if (!bolero_is_va_macro_registered(&pdev->dev)) { + dev_err(&pdev->dev, + "%s: va-macro not registered yet, defer\n", __func__); + return -EPROBE_DEFER; + } + rx_priv = devm_kzalloc(&pdev->dev, sizeof(struct rx_macro_priv), GFP_KERNEL); if (!rx_priv) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 16d79c918dcf..593406744766 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -3161,6 +3161,12 @@ static int tx_macro_probe(struct platform_device *pdev) u32 is_used_tx_swr_gpio = 1; const char *is_used_tx_swr_gpio_dt = "qcom,is-used-swr-gpio"; + if (!bolero_is_va_macro_registered(&pdev->dev)) { + dev_err(&pdev->dev, + "%s: va-macro not registered yet, defer\n", __func__); + return -EPROBE_DEFER; + } + tx_priv = devm_kzalloc(&pdev->dev, sizeof(struct tx_macro_priv), GFP_KERNEL); if (!tx_priv) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index d2852eea9e71..ca7391d0726b 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -3144,6 +3144,12 @@ static int wsa_macro_probe(struct platform_device *pdev) u32 is_used_wsa_swr_gpio = 1; const char *is_used_wsa_swr_gpio_dt = "qcom,is-used-swr-gpio"; + if (!bolero_is_va_macro_registered(&pdev->dev)) { + dev_err(&pdev->dev, + "%s: va-macro not registered yet, defer\n", __func__); + return -EPROBE_DEFER; + } + wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct wsa_macro_priv), GFP_KERNEL); if (!wsa_priv) @@ -3227,6 +3233,7 @@ static int wsa_macro_probe(struct platform_device *pdev) wsa_macro_init_ops(&ops, wsa_io_base); ops.clk_id_req = wsa_priv->default_clk_id; ops.default_clk_id = wsa_priv->default_clk_id; + ret = bolero_register_macro(&pdev->dev, WSA_MACRO, &ops); if (ret < 0) { dev_err(&pdev->dev, "%s: register macro failed\n", __func__); -- GitLab From 3ba988e0ed877bd0ee3ef7599395870ea245350c Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Sat, 18 Apr 2020 13:53:19 +0530 Subject: [PATCH 1540/1645] adsp-loader: Add support to load adsp fw name When adsp variant read from fuse registers is not supported, add support to read the fw name and load the same. Change-Id: Icf9aeee8b4c607a6f768f0d73ab0e55d78dc8ac9 Signed-off-by: Aditya Bavanari --- dsp/adsp-loader.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/dsp/adsp-loader.c b/dsp/adsp-loader.c index 8316f003bcd4..c8e1270b020a 100644 --- a/dsp/adsp-loader.c +++ b/dsp/adsp-loader.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2014, 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014, 2017-2020, The Linux Foundation. All rights reserved. */ #include @@ -333,6 +333,8 @@ static int adsp_loader_probe(struct platform_device *pdev) int fw_name_size; u32 adsp_var_idx = 0; int ret = 0; + u32 adsp_fuse_not_supported = 0; + const char *adsp_fw_name; ret = adsp_loader_init_sysfs(pdev); if (ret != 0) { @@ -344,7 +346,44 @@ static int adsp_loader_probe(struct platform_device *pdev) /* get adsp variant idx */ cell = nvmem_cell_get(&pdev->dev, "adsp_variant"); if (IS_ERR_OR_NULL(cell)) { - dev_dbg(&pdev->dev, "%s: FAILED to get nvmem cell \n", __func__); + dev_dbg(&pdev->dev, "%s: FAILED to get nvmem cell \n", + __func__); + + /* + * When ADSP variant read from fuse register is not + * supported, check if image with different fw image + * name needs to be loaded + */ + ret = of_property_read_u32(pdev->dev.of_node, + "adsp-fuse-not-supported", + &adsp_fuse_not_supported); + if (ret) { + dev_dbg(&pdev->dev, + "%s: adsp_fuse_not_supported prop not found", + __func__, ret); + goto wqueue; + } + + if (adsp_fuse_not_supported) { + /* Read ADSP firmware image name */ + ret = of_property_read_string(pdev->dev.of_node, + "adsp-fw-name", + &adsp_fw_name); + if (ret < 0) { + dev_dbg(&pdev->dev, "%s: unable to read fw-name\n", + __func__); + goto wqueue; + } + + fw_name_size = strlen(adsp_fw_name) + 1; + priv->adsp_fw_name = devm_kzalloc(&pdev->dev, + fw_name_size, + GFP_KERNEL); + if (!priv->adsp_fw_name) + goto wqueue; + strlcpy(priv->adsp_fw_name, adsp_fw_name, + fw_name_size); + } goto wqueue; } buf = nvmem_cell_read(cell, &len); -- GitLab From 4744ed702bae3b6c6fa8c59e617631f954eea566 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 27 May 2020 13:00:33 +0530 Subject: [PATCH 1541/1645] dsp: Fix a memory leak issue when nvmem read returns invalid length When nvmem cell read returns invalid length the allocated buffer is not freed. Free the buffer in this scenario to fix memory leak issue. Change-Id: I2e0010c1cfb2ea03cb4f25abf55e94ce4f0c5fcf Signed-off-by: Aditya Bavanari --- dsp/adsp-loader.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dsp/adsp-loader.c b/dsp/adsp-loader.c index c8e1270b020a..e99d6a3c7265 100644 --- a/dsp/adsp-loader.c +++ b/dsp/adsp-loader.c @@ -388,10 +388,16 @@ static int adsp_loader_probe(struct platform_device *pdev) } buf = nvmem_cell_read(cell, &len); nvmem_cell_put(cell); - if (IS_ERR_OR_NULL(buf) || len <= 0 || len > sizeof(u32)) { + if (IS_ERR_OR_NULL(buf)) { dev_dbg(&pdev->dev, "%s: FAILED to read nvmem cell \n", __func__); goto wqueue; } + if (len <= 0 || len > sizeof(u32)) { + dev_dbg(&pdev->dev, "%s: nvmem cell length out of range: %d\n", + __func__, len); + kfree(buf); + goto wqueue; + } memcpy(&adsp_var_idx, buf, len); kfree(buf); -- GitLab From bd940fbe427e7152d1cab7389b10fb7942fad7f3 Mon Sep 17 00:00:00 2001 From: Dhananjay Kumar Date: Thu, 9 Jul 2020 00:01:35 +0530 Subject: [PATCH 1542/1645] dsp: voice: Reset music_info on SSR Reset music_info playback states during SSR to fix incall music session failure after SSR. Music delivery session requests are getting ignored if the state is not reset. Change-Id: I7dd736baa538fb3697c874230c5a9c02f90b6a06 Signed-off-by: Dhananjay Kumar --- dsp/q6voice.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 110d8445b9f4..c63cf982e9f8 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -515,6 +515,8 @@ static void voc_set_error_state(uint16_t reset_proc) if (v != NULL) { v->voc_state = VOC_ERROR; v->rec_info.recording = 0; + v->music_info.playing = 0; + v->music_info.force = 0; } } } -- GitLab From 82861cad6b5e5e419570627e99b91c6d2711b75c Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 10 Jul 2020 14:36:50 +0530 Subject: [PATCH 1543/1645] asoc: wsa883x: Update the PDM_WD at startup/teardown Update PDM_WD bit only at startup and teardown of speaker playback. Change-Id: If385c0f4d99b7f5aa4ccd8b1ee94c4afa6754518 Signed-off-by: Laxminath Kasam --- asoc/codecs/wsa883x/wsa883x.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index a2dbea65f9ec..c14114f935d7 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -87,7 +87,6 @@ static const struct wsa_reg_mask_val reg_init[] = { {WSA883X_CDC_SPK_DSM_R7, 0xFF, 0x3F}, {WSA883X_DRE_CTL_0, 0xF0, 0x90}, {WSA883X_DRE_IDLE_DET_CTL, 0x10, 0x00}, - {WSA883X_PDM_WD_CTL, 0x01, 0x01}, {WSA883X_CURRENT_LIMIT, 0x78, 0x20}, {WSA883X_DRE_CTL_0, 0x07, 0x02}, {WSA883X_VAGC_TIME, 0x0F, 0x0F}, @@ -981,7 +980,6 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, swr_slvdev_datapath_control(wsa883x->swr_slave, wsa883x->swr_slave->dev_num, true); - wcd_enable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD); /* Force remove group */ swr_remove_from_group(wsa883x->swr_slave, wsa883x->swr_slave->dev_num); @@ -990,9 +988,14 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, WSA883X_PA_FSM_CTL, 0x01, 0x01); break; case SND_SOC_DAPM_PRE_PMD: + if (!test_bit(SPKR_ADIE_LB, &wsa883x->status_mask)) + wcd_disable_irq(&wsa883x->irq_info, + WSA883X_IRQ_INT_PDM_WD); snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, 0x01, 0x00); - wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD); + snd_soc_component_update_bits(wsa883x->component, + WSA883X_PDM_WD_CTL, + 0x01, 0x00); clear_bit(SPKR_STATUS, &wsa883x->status_mask); clear_bit(SPKR_ADIE_LB, &wsa883x->status_mask); break; @@ -1358,10 +1361,16 @@ static int wsa883x_event_notify(struct notifier_block *nb, break; case BOLERO_WSA_EVT_PA_ON_POST_FSCLK: - if (test_bit(SPKR_STATUS, &wsa883x->status_mask)) + if (test_bit(SPKR_STATUS, &wsa883x->status_mask)) { + snd_soc_component_update_bits(wsa883x->component, + WSA883X_PDM_WD_CTL, + 0x01, 0x01); snd_soc_component_update_bits(wsa883x->component, WSA883X_PA_FSM_CTL, 0x01, 0x01); + wcd_enable_irq(&wsa883x->irq_info, + WSA883X_IRQ_INT_PDM_WD); + } break; case BOLERO_WSA_EVT_PA_ON_POST_FSCLK_ADIE_LB: if (test_bit(SPKR_STATUS, &wsa883x->status_mask)) -- GitLab From f813d50dc4db8936dcde05ac1fe2d564e590be9d Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 1 Jul 2020 17:01:55 +0530 Subject: [PATCH 1544/1645] asoc: wsa881x: Disable WSA ADC register when teardown To ensure mono/stereo speaker usecases with speaker protection enabled switch properly and apply register during powerup, update disable sequence of ADC register. CRs-Fixed: 2705914 Change-Id: If9ceb4436ed6ce236a4e529d65b0acc8f9f6cd0e Signed-off-by: Laxminath Kasam --- asoc/codecs/wsa881x.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index 8850ea60935a..b23bc01fd8ed 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -1077,6 +1077,9 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, 0x80, 0x00); if (wsa881x->visense_enable) { wsa881x_visense_adc_ctrl(component, DISABLE); + snd_soc_component_update_bits(component, + WSA881X_ADC_EN_SEL_IBAIS, + 0x07, 0x00); wsa881x_visense_txfe_ctrl(component, DISABLE, 0x00, 0x01, 0x01); } -- GitLab From de33391c58d2c2d43c5a28422659ef9f2dd1f5a5 Mon Sep 17 00:00:00 2001 From: Surendar karka Date: Fri, 10 Jul 2020 15:58:21 +0530 Subject: [PATCH 1545/1645] asoc: update error check to avoid fix crash issues During negative test case if the backend index is out of range we will observe crash issues, update error check to avoid crashes. Change-Id: I07531ee538013841f93acd02537ac5a7c1e350ba Signed-off-by: Surendar karka --- asoc/msm-pcm-routing-v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index d4fbe39fe325..580c59889cc5 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -30240,7 +30240,7 @@ static int msm_routing_put_pll_clk_drift(struct snd_kcontrol *kcontrol, clk_drift = ucontrol->value.integer.value[1]; clk_reset = ucontrol->value.integer.value[2]; - if (be_idx < 0 && be_idx >= MSM_BACKEND_DAI_MAX) { + if (be_idx < 0 || be_idx >= MSM_BACKEND_DAI_MAX) { pr_err("%s: Invalid be id %d\n", __func__, be_idx); return -EINVAL; } -- GitLab From f712be0718828b5e04a89dd4d658febfae5a8f56 Mon Sep 17 00:00:00 2001 From: Kunlei Zhang Date: Tue, 30 Jun 2020 21:05:46 +0800 Subject: [PATCH 1546/1645] asoc: kona: update sound wire port frame config routing update sound wire port frame config routing to ensure use correct port config for device with no WCD. Change-Id: I1746323230064f51020850cf8e1dbf2c29977bed Signed-off-by: Kunlei Zhang --- asoc/kona.c | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index 02b9e0162ee8..f2bdb382cd51 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -5425,6 +5425,7 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_component *aux_comp; struct platform_device *pdev = NULL; int i = 0; + bool is_wcd937x_used = false; char *data = NULL; struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); @@ -5521,33 +5522,29 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) if (data != NULL) { if (!strncmp(data, "wcd937x", sizeof("wcd937x"))) { - bolero_set_port_map(component, - ARRAY_SIZE(sm_port_map_wcd937x), - sm_port_map_wcd937x); - break; - } else if (!strncmp( data, "wcd938x", - sizeof("wcd938x"))) { - if (pdata->lito_v2_enabled) { - /* - * Enable tx data line3 for - * saipan version v2 and - * write corresponding - * lpi register. - */ - bolero_set_port_map(component, - ARRAY_SIZE(sm_port_map_v2), - sm_port_map_v2); - } else { - bolero_set_port_map(component, - ARRAY_SIZE(sm_port_map), - sm_port_map); - } + is_wcd937x_used = true; break; } } } } + if (is_wcd937x_used) { + bolero_set_port_map(component, + ARRAY_SIZE(sm_port_map_wcd937x), + sm_port_map_wcd937x); + } else if (pdata->lito_v2_enabled) { + /* + * Enable tx data line3 for saipan version v2 and + * write corresponding lpi register. + */ + bolero_set_port_map(component, ARRAY_SIZE(sm_port_map_v2), + sm_port_map_v2); + } else { + bolero_set_port_map(component, ARRAY_SIZE(sm_port_map), + sm_port_map); + } + card = rtd->card->snd_card; if (!pdata->codec_root) { entry = snd_info_create_subdir(card->module, "codecs", -- GitLab From a620a95be0f41954e9adc7021b431f2e6f3f51f9 Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Thu, 11 Jun 2020 12:14:46 +0530 Subject: [PATCH 1547/1645] ASoC: sdm660 audio bring up changes Enable compilation of ipc, soc, dsp and asoc components for sdm660 target. Change-Id: I5f575fcbca4d4e2e2ef6fcb8705d6bf3d54bcf61 Signed-off-by: Soumya Managoli --- Android.mk | 4 +-- Makefile | 7 +++++ Makefile.am | 3 ++ config/sdm660auto.conf | 49 ++++++++++++++++++++++++++++++++ config/sdm660autoconf.h | 62 +++++++++++++++++++++++++++++++++++++++++ dsp/Android.mk | 6 +++- dsp/Kbuild | 5 ++++ ipc/Android.mk | 8 ++++-- ipc/Kbuild | 5 ++++ soc/Android.mk | 10 +++++-- soc/Kbuild | 5 ++++ 11 files changed, 156 insertions(+), 8 deletions(-) create mode 100644 config/sdm660auto.conf create mode 100644 config/sdm660autoconf.h diff --git a/Android.mk b/Android.mk index e0d3f0f509fb..581d0968802c 100644 --- a/Android.mk +++ b/Android.mk @@ -3,7 +3,7 @@ MY_LOCAL_PATH := $(call my-dir) UAPI_OUT := $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/include -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike sdm660),true) $(shell mkdir -p $(UAPI_OUT)/linux;) $(shell mkdir -p $(UAPI_OUT)/sound;) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers) @@ -64,4 +64,4 @@ endif ifeq ($(call is-board-platform-in-list, lito),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wsa883x/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wsa883x/Android.mk -endif \ No newline at end of file +endif diff --git a/Makefile b/Makefile index 8daa4601fa74..a858349a6b86 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,9 @@ endif ifeq ($(CONFIG_ARCH_KONA), y) include $(srctree)/techpack/audio/config/konaauto.conf endif +ifeq ($(CONFIG_ARCH_SDM660), y) +include $(srctree)/techpack/audio/config/sdm660auto.conf +endif # Use USERINCLUDE when you must reference the UAPI directories only. USERINCLUDE += \ @@ -42,6 +45,10 @@ ifeq ($(CONFIG_ARCH_KONA), y) LINUXINCLUDE += \ -include $(srctree)/techpack/audio/config/konaautoconf.h endif +ifeq ($(CONFIG_ARCH_SDM660), y) +LINUXINCLUDE += \ + -include $(srctree)/techpack/audio/config/sdm660autoconf.h +endif obj-y += soc/ obj-y += dsp/ diff --git a/Makefile.am b/Makefile.am index 14e8a8cc211e..3a0e7f678f0a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,6 +17,9 @@ endif ifeq ($(TARGET_SUPPORT), sdmsteppe) KBUILD_OPTIONS += CONFIG_ARCH_SM6150=y endif +ifeq ($(TARGET_SUPPORT),sdm660) +KBUILD_OPTIONS += CONFIG_ARCH_SDM660=y +endif obj-m := ipc/ obj-m += dsp/ diff --git a/config/sdm660auto.conf b/config/sdm660auto.conf new file mode 100644 index 000000000000..a39bd05c6d4a --- /dev/null +++ b/config/sdm660auto.conf @@ -0,0 +1,49 @@ +CONFIG_PINCTRL_LPI=m +CONFIG_PINCTRL_WCD=m +CONFIG_AUDIO_EXT_CLK=m +CONFIG_SND_SOC_WCD9XXX_V2=m +CONFIG_SND_SOC_WCD_MBHC=m +CONFIG_SND_SOC_WSA881X=m +CONFIG_SND_SOC_WCD_DSP_MGR=m +CONFIG_SND_SOC_WCD_SPI=m +CONFIG_SND_SOC_WCD_CPE=m +CONFIG_SND_SOC_CPE=m +CONFIG_SND_SOC_WCD9335=m +CONFIG_SND_SOC_WCD934X=m +CONFIG_SND_SOC_WCD934X_MBHC=m +CONFIG_SND_SOC_WCD934X_DSD=m +CONFIG_MSM_QDSP6V2_CODECS=m +CONFIG_MSM_ULTRASOUND=m +CONFIG_MSM_QDSP6_APRV2_RPMSG=m +CONFIG_MSM_ADSP_LOADER=m +CONFIG_REGMAP_SWR=m +CONFIG_MSM_QDSP6_SSR=m +CONFIG_MSM_QDSP6_PDR=m +CONFIG_MSM_QDSP6_NOTIFIER=m +CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +CONFIG_SND_SOC_SDM660=m +CONFIG_MSM_GLINK_SPI_XPRT=m +CONFIG_SOUNDWIRE=m +CONFIG_SOUNDWIRE_WCD_CTRL=m +CONFIG_SND_SOC_QDSP6V2=m +CONFIG_WCD9XXX_CODEC_CORE=m +CONFIG_MSM_CDC_PINCTRL=m +CONFIG_SND_SOC_WCD_MBHC_ADC=m +CONFIG_SND_SOC_WCD_MBHC_LEGACY=m +CONFIG_QTI_PP=m +CONFIG_SND_HWDEP_ROUTING=m +CONFIG_DTS_EAGLE=m +CONFIG_DOLBY_DS2=m +CONFIG_DOLBY_LICENSE=m +CONFIG_DTS_SRS_TM=m +CONFIG_SND_SOC_EXT_CODEC=m +CONFIG_SND_SOC_INT_CODEC=m +CONFIG_SND_SOC_MSM_STUB=m +CONFIG_WCD_DSP_GLINK=m +CONFIG_MSM_AVTIMER=m +CONFIG_SND_SOC_SDM660_CDC=m +CONFIG_SND_SOC_ANALOG_CDC=m +CONFIG_SND_SOC_DIGITAL_CDC=m +CONFIG_SND_SOC_MSM_SDW=m +CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m diff --git a/config/sdm660autoconf.h b/config/sdm660autoconf.h new file mode 100644 index 000000000000..7fa702159d26 --- /dev/null +++ b/config/sdm660autoconf.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define CONFIG_PINCTRL_LPI 1 +#define CONFIG_PINCTRL_WCD 1 +#define CONFIG_AUDIO_EXT_CLK 1 +#define CONFIG_SND_SOC_WCD9XXX_V2 1 +#define CONFIG_SND_SOC_WCD_CPE 1 +#define CONFIG_SND_SOC_WCD_MBHC 1 +#define CONFIG_SND_SOC_WSA881X 1 +#define CONFIG_SND_SOC_WCD_DSP_MGR 1 +#define CONFIG_SND_SOC_WCD_SPI 1 +#define CONFIG_SND_SOC_WCD9335 1 +#define CONFIG_SND_SOC_WCD934X 1 +#define CONFIG_SND_SOC_WCD934X_MBHC 1 +#define CONFIG_SND_SOC_WCD934X_DSD 1 +#define CONFIG_MSM_QDSP6V2_CODECS 1 +#define CONFIG_MSM_ULTRASOUND 1 +#define CONFIG_MSM_QDSP6_APRV2_RPMSG 1 +#define CONFIG_MSM_ADSP_LOADER 1 +#define CONFIG_REGMAP_SWR 1 +#define CONFIG_MSM_QDSP6_SSR 1 +#define CONFIG_MSM_QDSP6_PDR 1 +#define CONFIG_MSM_QDSP6_NOTIFIER 1 +#define CONFIG_SND_SOC_MSM_HOSTLESS_PCM 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 +#define CONFIG_SND_SOC_SDM660 1 +#define CONFIG_MSM_GLINK_SPI_XPRT 1 +#define CONFIG_SOUNDWIRE 1 +#define CONFIG_SOUNDWIRE_WCD_CTRL 1 +#define CONFIG_SND_SOC_WCD_MBHC_ADC 1 +#define CONFIG_SND_SOC_WCD_MBHC_LEGACY 1 +#define CONFIG_SND_SOC_QDSP6V2 1 +#define CONFIG_QTI_PP 1 +#define CONFIG_SND_HWDEP_ROUTING 1 +#define CONFIG_DTS_EAGLE 1 +#define CONFIG_DOLBY_DS2 1 +#define CONFIG_DOLBY_LICENSE 1 +#define CONFIG_DTS_SRS_TM 1 +#define CONFIG_WCD9XXX_CODEC_CORE 1 +#define CONFIG_MSM_CDC_PINCTRL 1 +#define CONFIG_SND_SOC_MSM_STUB 1 +#define CONFIG_WCD_DSP_GLINK 1 +#define CONFIG_MSM_AVTIMER 1 +#define CONFIG_SND_SOC_EXT_CODEC 1 +#define CONFIG_SND_SOC_INT_CODEC 1 +#define CONFIG_SND_SOC_CPE 1 +#define CONFIG_SND_SOC_SDM660_CDC 1 +#define CONFIG_SND_SOC_ANALOG_CDC 1 +#define CONFIG_SND_SOC_DIGITAL_CDC 1 +#define CONFIG_SND_SOC_MSM_SDW 1 +#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1 diff --git a/dsp/Android.mk b/dsp/Android.mk index c5ab3ff51ab6..90a486e46fc7 100644 --- a/dsp/Android.mk +++ b/dsp/Android.mk @@ -31,9 +31,13 @@ ifeq ($(call is-board-platform, bengal),true) AUDIO_SELECT := CONFIG_SND_SOC_BENGAL=m endif +ifeq ($(call is-board-platform,sdm660),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM660=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike sdm660),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/Kbuild b/dsp/Kbuild index 43180e7a3dc3..490b458bfc2b 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -76,6 +76,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h endif + ifeq ($(CONFIG_ARCH_SDM660), y) + include $(AUDIO_ROOT)/config/sdm660auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h + endif endif diff --git a/ipc/Android.mk b/ipc/Android.mk index 3238a791e15e..99ffc3076a1c 100644 --- a/ipc/Android.mk +++ b/ipc/Android.mk @@ -31,9 +31,13 @@ ifeq ($(call is-board-platform,bengal),true) AUDIO_SELECT := CONFIG_SND_SOC_BENGAL=m endif +ifeq ($(call is-board-platform,sdm660),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM660=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike sdm660),true) LOCAL_PATH := $(call my-dir) @@ -68,7 +72,7 @@ LOCAL_MODULE_DEBUG_ENABLE := true LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) sdmshrike),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) sdmshrike sdm660),true) ifneq ($(TARGET_BOARD_AUTO),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wglink.ko diff --git a/ipc/Kbuild b/ipc/Kbuild index bbea67396ed4..755d6d8eacd5 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -77,6 +77,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h endif + ifeq ($(CONFIG_ARCH_SDM660), y) + include $(AUDIO_ROOT)/config/sdm660auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/soc/Android.mk b/soc/Android.mk index 9ed83d4d468e..d6a1203c1c75 100644 --- a/soc/Android.mk +++ b/soc/Android.mk @@ -31,9 +31,13 @@ ifeq ($(call is-board-platform,bengal),true) AUDIO_SELECT := CONFIG_SND_SOC_BENGAL=m endif +ifeq ($(call is-board-platform,sdm660),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM660=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike sdm660),true) LOCAL_PATH := $(call my-dir) @@ -60,7 +64,7 @@ KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) KBUILD_OPTIONS += $(AUDIO_SELECT) ########################################################### -ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona lito bengal),true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona lito bengal sdm660),true) ifneq ($(TARGET_BOARD_AUTO),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_lpi.ko @@ -72,7 +76,7 @@ include $(DLKM_DIR)/AndroidKernelModule.mk endif endif ########################################################### -ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona), true) +ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona sdm660), true) ifneq ($(TARGET_BOARD_AUTO),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_pinctrl_wcd.ko diff --git a/soc/Kbuild b/soc/Kbuild index 9e32c429fa2b..f77f38619695 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -76,6 +76,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h endif + ifeq ($(CONFIG_ARCH_SDM660), y) + include $(AUDIO_ROOT)/config/sdm660auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h + endif endif # As per target team, build is done as follows: -- GitLab From 348bc6783bf11000bf811f1e0df9db9917f39add Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Thu, 25 Jun 2020 19:38:34 +0530 Subject: [PATCH 1548/1645] asoc: Add check for substream ref_count before access the substream. Add check for substream ref count before access the substream. Change-Id: Iccb6226519e8fddf624f82160a0d8d22641944db Signed-off-by: Prasad Kumpatla --- asoc/msm-pcm-loopback-v2.c | 34 ++++++++++++-------- asoc/msm-pcm-q6-noirq.c | 18 ++++++----- asoc/msm-pcm-q6-v2.c | 63 ++++++++++++++++++++++++++++---------- 3 files changed, 80 insertions(+), 35 deletions(-) diff --git a/asoc/msm-pcm-loopback-v2.c b/asoc/msm-pcm-loopback-v2.c index af6be3ad4515..4da7848daacb 100644 --- a/asoc/msm-pcm-loopback-v2.c +++ b/asoc/msm-pcm-loopback-v2.c @@ -551,13 +551,15 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, goto exit; } mutex_lock(&loopback_session_lock); - prtd = substream->runtime->private_data; - if (!prtd) { - rc = -ENODEV; - mutex_unlock(&loopback_session_lock); - goto exit; + if (substream->ref_count > 0) { + prtd = substream->runtime->private_data; + if (!prtd) { + rc = -ENODEV; + mutex_unlock(&loopback_session_lock); + goto exit; + } + rc = pcm_loopback_set_volume(prtd, volume); } - rc = pcm_loopback_set_volume(prtd, volume); mutex_unlock(&loopback_session_lock); exit: return rc; @@ -583,13 +585,15 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, goto exit; } mutex_lock(&loopback_session_lock); - prtd = substream->runtime->private_data; - if (!prtd) { - rc = -ENODEV; - mutex_unlock(&loopback_session_lock); - goto exit; + if (substream->ref_count > 0) { + prtd = substream->runtime->private_data; + if (!prtd) { + rc = -ENODEV; + mutex_unlock(&loopback_session_lock); + goto exit; + } + ucontrol->value.integer.value[0] = prtd->volume; } - ucontrol->value.integer.value[0] = prtd->volume; mutex_unlock(&loopback_session_lock); exit: return rc; @@ -877,6 +881,12 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, chmixer_pspd); mutex_lock(&loopback_session_lock); + if (substream->ref_count <= 0) { + pr_err_ratelimited("%s: substream ref_count:%d invalid\n", + __func__, substream->ref_count); + mutex_unlock(&loopback_session_lock); + return -EINVAL; + } if (chmixer_pspd->enable && substream->runtime) { prtd = substream->runtime->private_data; if (!prtd) { diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index 8fb6f7cd4995..e3f59e8dc502 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -754,9 +754,11 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, return -ENODEV; } mutex_lock(&pdata->lock); - prtd = substream->runtime->private_data; - if (prtd) - ucontrol->value.integer.value[0] = prtd->volume; + if (substream->ref_count > 0) { + prtd = substream->runtime->private_data; + if (prtd) + ucontrol->value.integer.value[0] = prtd->volume; + } mutex_unlock(&pdata->lock); return 0; } @@ -799,10 +801,12 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, } mutex_lock(&pdata->lock); - prtd = substream->runtime->private_data; - if (prtd) { - rc = msm_pcm_set_volume(prtd, volume); - prtd->volume = volume; + if (substream->ref_count > 0) { + prtd = substream->runtime->private_data; + if (prtd) { + rc = msm_pcm_set_volume(prtd, volume); + prtd->volume = volume; + } } mutex_unlock(&pdata->lock); return rc; diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index c22c39ba3ec0..2fc5c8459263 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1325,7 +1325,12 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, ret = -EINVAL; goto done; } - + if (substream->ref_count <= 0) { + pr_err_ratelimited("%s substream ref_count:%d invalid\n", + __func__, substream->ref_count); + ret = -EINVAL; + goto done; + } prtd = substream->runtime->private_data; if (prtd == NULL) { pr_err("%s prtd is null.\n", __func__); @@ -1549,9 +1554,11 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, } mutex_lock(&pdata->lock); - prtd = substream->runtime->private_data; - if (prtd) - ucontrol->value.integer.value[0] = prtd->volume; + if (substream->ref_count > 0) { + prtd = substream->runtime->private_data; + if (prtd) + ucontrol->value.integer.value[0] = prtd->volume; + } mutex_unlock(&pdata->lock); return 0; } @@ -1595,10 +1602,12 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol, } mutex_lock(&pdata->lock); - prtd = substream->runtime->private_data; - if (prtd) { - rc = msm_pcm_set_volume(prtd, volume); - prtd->volume = volume; + if (substream->ref_count > 0) { + prtd = substream->runtime->private_data; + if (prtd) { + rc = msm_pcm_set_volume(prtd, volume); + prtd->volume = volume; + } } mutex_unlock(&pdata->lock); return rc; @@ -1659,9 +1668,11 @@ static int msm_pcm_compress_ctl_get(struct snd_kcontrol *kcontrol, return 0; } mutex_lock(&pdata->lock); - prtd = substream->runtime->private_data; - if (prtd) - ucontrol->value.integer.value[0] = prtd->compress_enable; + if (substream->ref_count > 0) { + prtd = substream->runtime->private_data; + if (prtd) + ucontrol->value.integer.value[0] = prtd->compress_enable; + } mutex_unlock(&pdata->lock); return 0; } @@ -1691,11 +1702,13 @@ static int msm_pcm_compress_ctl_put(struct snd_kcontrol *kcontrol, return 0; } mutex_lock(&pdata->lock); - prtd = substream->runtime->private_data; - if (prtd) { - pr_debug("%s: setting compress flag to 0x%x\n", - __func__, compress); - prtd->compress_enable = compress; + if (substream->ref_count > 0) { + prtd = substream->runtime->private_data; + if (prtd) { + pr_debug("%s: setting compress flag to 0x%x\n", + __func__, compress); + prtd->compress_enable = compress; + } } mutex_unlock(&pdata->lock); return rc; @@ -1805,6 +1818,12 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol, return 0; mutex_lock(&pdata->lock); + if (substream->ref_count <= 0) { + pr_err_ratelimited("%s: substream ref_count:%d invalid\n", + __func__, substream->ref_count); + mutex_unlock(&pdata->lock); + return -EINVAL; + } prtd = substream->runtime ? substream->runtime->private_data : NULL; if (prtd) { prtd->set_channel_map = true; @@ -1872,6 +1891,12 @@ static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol, return 0; /* no channels set */ mutex_lock(&pdata->lock); + if (substream->ref_count <= 0) { + pr_err_ratelimited("%s: substream ref_count:%d invalid\n", + __func__, substream->ref_count); + mutex_unlock(&pdata->lock); + return -EINVAL; + } prtd = substream->runtime ? substream->runtime->private_data : NULL; if (prtd && prtd->set_channel_map == true) { @@ -2154,6 +2179,12 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol, } mutex_lock(&pdata->lock); + if (substream->ref_count <= 0) { + pr_err_ratelimited("%s: substream ref_count:%d invalid\n", + __func__, substream->ref_count); + mutex_unlock(&pdata->lock); + return -EINVAL; + } prtd = substream->runtime ? substream->runtime->private_data : NULL; if (chmixer_pspd->enable && prtd) { if (session_type == SESSION_TYPE_RX && -- GitLab From 0d196604a5e78eb1cceac10d58a73395843716a0 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Tue, 26 Nov 2019 16:51:55 -0800 Subject: [PATCH 1549/1645] ASoC: Add tdm dynamic configuration support Add support to use dynamic tdm slots. The max number of tdm slots is defined in device tree and tdm configuration is dynamically assigned based on tdm max slots. CRs-Fixed: 2553156 Change-Id: If444da44e02e6cbcbb4ea1e2396627745bd1e982 Signed-off-by: Vignesh Kulothungan --- asoc/kona.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index 02b9e0162ee8..f8d12981446b 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -106,6 +106,7 @@ enum { #define TDM_MAX_SLOTS 8 #define TDM_SLOT_WIDTH_BITS 32 +#define TDM_SLOT_WIDTH_BYTES TDM_SLOT_WIDTH_BITS/8 enum { TDM_PRI = 0, @@ -192,6 +193,7 @@ struct msm_asoc_mach_data { struct device_node *fsa_handle; struct clk *lpass_audio_hw_vote; int core_audio_vote_count; + u32 tdm_max_slots; /* Max TDM slots used */ }; struct tdm_port { @@ -1989,8 +1991,11 @@ static int tdm_slot_map_put(struct snd_kcontrol *kcontrol, int interface = ucontrol->value.integer.value[0]; int channel = ucontrol->value.integer.value[1]; unsigned int offset_val = 0; + unsigned int max_slot_offset = 0; unsigned int *slot_offset = NULL; struct tdm_dev_config *config = NULL; + struct msm_asoc_mach_data *pdata = NULL; + struct snd_soc_component *component = NULL; if (interface < 0 || interface >= (TDM_INTERFACE_MAX * MAX_PATH)) { pr_err("%s: incorrect interface = %d\n", __func__, interface); @@ -2004,15 +2009,28 @@ static int tdm_slot_map_put(struct snd_kcontrol *kcontrol, pr_debug("%s: interface = %d, channel = %d\n", __func__, interface, channel); + component = snd_soc_kcontrol_component(kcontrol); + pdata = snd_soc_card_get_drvdata(component->card); config = ((struct tdm_dev_config *) tdm_cfg[interface / MAX_PATH]) + ((interface % MAX_PATH) * TDM_PORT_MAX) + channel; + if (!config) { + pr_err("%s: tdm config is NULL\n", __func__); + return -EINVAL; + } + slot_offset = config->tdm_slot_offset; + if (!slot_offset) { + pr_err("%s: slot offset is NULL\n", __func__); + return -EINVAL; + } + + max_slot_offset = TDM_SLOT_WIDTH_BYTES * (pdata->tdm_max_slots - 1); - for (slot_index = 0; slot_index < TDM_MAX_SLOTS; slot_index++) { + for (slot_index = 0; slot_index < pdata->tdm_max_slots; slot_index++) { offset_val = ucontrol->value.integer.value[MAX_PATH + slot_index]; - /* Offset value can only be 0, 4, 8, ..28 */ - if (offset_val % 4 == 0 && offset_val <= 28) + /* Offset value can only be 0, 4, 8, .. */ + if (offset_val % 4 == 0 && offset_val <= max_slot_offset) slot_offset[slot_index] = offset_val; pr_debug("%s: slot offset[%d] = %d\n", __func__, slot_index, slot_offset[slot_index]); @@ -4585,14 +4603,17 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret = 0; int slot_width = TDM_SLOT_WIDTH_BITS; - int channels, slots = TDM_MAX_SLOTS; + int channels, slots; unsigned int slot_mask, rate, clk_freq; unsigned int *slot_offset; struct tdm_dev_config *config; + struct msm_asoc_mach_data *pdata = NULL; unsigned int path_dir = 0, interface = 0, channel_interface = 0; pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + pdata = snd_soc_card_get_drvdata(rtd->card); + slots = pdata->tdm_max_slots; if (cpu_dai->id < AFE_PORT_ID_TDM_PORT_RANGE_START) { pr_err("%s: dai id 0x%x not supported\n", __func__, cpu_dai->id); @@ -4616,7 +4637,16 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream, config = ((struct tdm_dev_config *) tdm_cfg[interface]) + (path_dir * TDM_PORT_MAX) + channel_interface; + if (!config) { + pr_err("%s: tdm config is NULL\n", __func__); + return -EINVAL; + } + slot_offset = config->tdm_slot_offset; + if (!slot_offset) { + pr_err("%s: slot offset is NULL\n", __func__); + return -EINVAL; + } if (path_dir) channels = tdm_tx_cfg[interface][channel_interface].channels; @@ -8273,6 +8303,20 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) dev_info(&pdev->dev, "%s: Sound card %s registered\n", __func__, card->name); + ret = of_property_read_u32(pdev->dev.of_node, "qcom,tdm-max-slots", + &pdata->tdm_max_slots); + if (ret) { + dev_err(&pdev->dev, "%s: No DT match for tdm max slots\n", + __func__); + } + + if ((pdata->tdm_max_slots <= 0) || (pdata->tdm_max_slots > + TDM_MAX_SLOTS)) { + pdata->tdm_max_slots = TDM_MAX_SLOTS; + dev_err(&pdev->dev, "%s: Using default tdm max slot: %d\n", + __func__, pdata->tdm_max_slots); + } + pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, "qcom,hph-en1-gpio", 0); if (!pdata->hph_en1_gpio_p) { -- GitLab From fee4cc91d1c45e1c8fb4c300fdf607d83525378c Mon Sep 17 00:00:00 2001 From: Faiz Nabi Kuchay Date: Mon, 8 Jun 2020 19:02:55 +0530 Subject: [PATCH 1550/1645] asoc: codecs: Fix mute after SSR issue in rouleur codec Make dev_up true before giving 500 ms delay in case of AATC variant during BOLERO_WCD_EVT_SSR_UP event. Change-Id: Ie8306c92a80df69f087f055d425b22f48f319873 Signed-off-by: Faiz Nabi Kuchay --- asoc/codecs/rouleur/rouleur.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index d2cf31a5100a..e2c324179241 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -783,6 +783,9 @@ static int rouleur_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev, rouleur->rx_swr_dev->dev_num, true); + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL, + 0x40, 0x00); usleep_range(5000, 5100); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_PDM_WD_CTL0, @@ -1400,6 +1403,7 @@ static int rouleur_event_notify(struct notifier_block *block, rouleur_init_reg(component); regcache_mark_dirty(rouleur->regmap); regcache_sync(rouleur->regmap); + rouleur->dev_up = true; /* Initialize MBHC module */ mbhc = &rouleur->mbhc->wcd_mbhc; ret = rouleur_mbhc_post_ssr_init(rouleur->mbhc, component); @@ -1412,7 +1416,6 @@ static int rouleur_event_notify(struct notifier_block *block, mdelay(500); } rouleur->mbhc->wcd_mbhc.deinit_in_progress = false; - rouleur->dev_up = true; break; default: dev_err(component->dev, "%s: invalid event %d\n", __func__, -- GitLab From b333e2c52f69d1a16e6592e13878b1c6680107fd Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Mon, 13 Jul 2020 18:19:21 +0530 Subject: [PATCH 1551/1645] asoc: rouleur: Fix CnP issues in EAR and LO paths Update EAR and LO power up and down sequences to fix CnP issues in rouleur codec. Change-Id: I7e6d1cc82e9c1358b336c32b1befb7eb1dd9b552 Signed-off-by: Aditya Bavanari --- asoc/codecs/rouleur/rouleur-registers.h | 3 ++ asoc/codecs/rouleur/rouleur-regmap.c | 3 ++ asoc/codecs/rouleur/rouleur-tables.c | 3 ++ asoc/codecs/rouleur/rouleur.c | 53 ++++++++++++++++++------- 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/asoc/codecs/rouleur/rouleur-registers.h b/asoc/codecs/rouleur/rouleur-registers.h index 8cc0ae473af0..d890a2ba443e 100644 --- a/asoc/codecs/rouleur/rouleur-registers.h +++ b/asoc/codecs/rouleur/rouleur-registers.h @@ -48,6 +48,7 @@ enum { #define ROULEUR_ANA_MBHC_CTL_CLK (ROULEUR_ANA_BASE_ADDR+0x06D) #define ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT (ROULEUR_ANA_BASE_ADDR+0x072) #define ROULEUR_ANA_NCP_EN (ROULEUR_ANA_BASE_ADDR+0x077) +#define ROULEUR_ANA_NCP_VCTRL (ROULEUR_ANA_BASE_ADDR+0x07C) #define ROULEUR_ANA_HPHPA_CNP_CTL_1 (ROULEUR_ANA_BASE_ADDR+0x083) #define ROULEUR_ANA_HPHPA_CNP_CTL_2 (ROULEUR_ANA_BASE_ADDR+0x084) #define ROULEUR_ANA_HPHPA_PA_STATUS (ROULEUR_ANA_BASE_ADDR+0x087) @@ -58,6 +59,8 @@ enum { #define ROULEUR_SWR_HPHPA_HD2 (ROULEUR_ANA_BASE_ADDR+0x090) #define ROULEUR_ANA_SURGE_EN (ROULEUR_ANA_BASE_ADDR+0x097) #define ROULEUR_ANA_COMBOPA_CTL (ROULEUR_ANA_BASE_ADDR+0x09B) +#define ROULEUR_ANA_COMBOPA_CTL_4 (ROULEUR_ANA_BASE_ADDR+0x09F) +#define ROULEUR_ANA_COMBOPA_CTL_5 (ROULEUR_ANA_BASE_ADDR+0x0A0) #define ROULEUR_ANA_RXLDO_CTL (ROULEUR_ANA_BASE_ADDR+0x0B2) #define ROULEUR_ANA_MBIAS_EN (ROULEUR_ANA_BASE_ADDR+0x0B4) diff --git a/asoc/codecs/rouleur/rouleur-regmap.c b/asoc/codecs/rouleur/rouleur-regmap.c index 23b8ddc96757..51ed46a3b23b 100644 --- a/asoc/codecs/rouleur/rouleur-regmap.c +++ b/asoc/codecs/rouleur/rouleur-regmap.c @@ -41,6 +41,7 @@ static const struct reg_default rouleur_defaults[] = { { ROULEUR_ANA_MBHC_CTL_CLK, 0x30 }, { ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT, 0x00 }, { ROULEUR_ANA_NCP_EN, 0x00 }, + { ROULEUR_ANA_NCP_VCTRL, 0xA7 }, { ROULEUR_ANA_HPHPA_CNP_CTL_1, 0x54 }, { ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x2B }, { ROULEUR_ANA_HPHPA_PA_STATUS, 0x00 }, @@ -51,6 +52,8 @@ static const struct reg_default rouleur_defaults[] = { { ROULEUR_ANA_HPHPA_SPARE_CTL, 0x02 }, { ROULEUR_ANA_SURGE_EN, 0x38 }, { ROULEUR_ANA_COMBOPA_CTL, 0x35 }, + { ROULEUR_ANA_COMBOPA_CTL_4, 0x84 }, + { ROULEUR_ANA_COMBOPA_CTL_5, 0x05 }, { ROULEUR_ANA_RXLDO_CTL, 0x86 }, { ROULEUR_ANA_MBIAS_EN, 0x00 }, { ROULEUR_DIG_SWR_CHIP_ID0, 0x00 }, diff --git a/asoc/codecs/rouleur/rouleur-tables.c b/asoc/codecs/rouleur/rouleur-tables.c index 7912267dac33..63604566ab16 100644 --- a/asoc/codecs/rouleur/rouleur-tables.c +++ b/asoc/codecs/rouleur/rouleur-tables.c @@ -36,6 +36,7 @@ const u8 rouleur_reg_access_analog[ROULEUR_REG( [ROULEUR_REG(ROULEUR_ANA_MBHC_CTL_CLK)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT)] = RD_REG, [ROULEUR_REG(ROULEUR_ANA_NCP_EN)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_NCP_VCTRL)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_HPHPA_CNP_CTL_1)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_HPHPA_CNP_CTL_2)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_HPHPA_PA_STATUS)] = RD_REG, @@ -46,6 +47,8 @@ const u8 rouleur_reg_access_analog[ROULEUR_REG( [ROULEUR_REG(ROULEUR_SWR_HPHPA_HD2)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_SURGE_EN)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_COMBOPA_CTL)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_COMBOPA_CTL_4)] = RD_WR_REG, + [ROULEUR_REG(ROULEUR_ANA_COMBOPA_CTL_5)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_RXLDO_CTL)] = RD_WR_REG, [ROULEUR_REG(ROULEUR_ANA_MBIAS_EN)] = RD_WR_REG, }; diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index e2c324179241..8ce51a3b159c 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -361,6 +361,8 @@ static int rouleur_rx_clk_enable(struct snd_soc_component *component) ROULEUR_ANA_HPHPA_FSM_CLK, 0x7F, 0x11); snd_soc_component_update_bits(component, ROULEUR_ANA_HPHPA_FSM_CLK, 0x80, 0x80); + snd_soc_component_update_bits(component, + ROULEUR_ANA_NCP_VCTRL, 0x07, 0x06); snd_soc_component_update_bits(component, ROULEUR_ANA_NCP_EN, 0x01, 0x01); usleep_range(500, 510); @@ -591,12 +593,12 @@ static int rouleur_codec_ear_lo_dac_event(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX0_CTL, 0x80, 0x00); - snd_soc_component_update_bits(component, - ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, - 0x04, 0x04); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_CDC_RX_CLK_CTL, 0x01, 0x01); + snd_soc_component_update_bits(component, + ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL, + 0x04, 0x04); break; case SND_SOC_DAPM_POST_PMD: @@ -635,7 +637,7 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, true); set_bit(HPH_PA_DELAY, &rouleur->status_mask); - usleep_range(5000, 5100); + usleep_range(200, 210); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_PDM_WD_CTL1, 0x03, 0x03); @@ -671,9 +673,8 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: /* - * 7ms sleep is required after PA is disabled as per - * HW requirement. If compander is disabled, then - * 20ms delay is required. + * 5ms sleep is required after PA is disabled as per + * HW requirement. */ if (test_bit(HPH_PA_DELAY, &rouleur->status_mask)) { @@ -710,7 +711,7 @@ static int rouleur_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, rouleur->rx_swr_dev->dev_num, true); set_bit(HPH_PA_DELAY, &rouleur->status_mask); - usleep_range(5000, 5100); + usleep_range(200, 210); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_PDM_WD_CTL0, 0x03, 0x03); @@ -783,21 +784,32 @@ static int rouleur_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev, rouleur->rx_swr_dev->dev_num, true); + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL_5, + 0x04, 0x00); + usleep_range(1000, 1010); + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL_4, + 0x0F, 0x0F); + usleep_range(1000, 1010); snd_soc_component_update_bits(component, ROULEUR_ANA_COMBOPA_CTL, 0x40, 0x00); - usleep_range(5000, 5100); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_PDM_WD_CTL0, 0x03, 0x03); break; case SND_SOC_DAPM_POST_PMU: + usleep_range(5000, 5100); + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL_4, + 0x0F, 0x04); if (rouleur->update_wcd_event) rouleur->update_wcd_event(rouleur->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX1 << 0x10)); - wcd_enable_irq(&rouleur->irq_info, - ROULEUR_IRQ_HPHL_PDM_WD_INT); + wcd_enable_irq(&rouleur->irq_info, + ROULEUR_IRQ_HPHL_PDM_WD_INT); break; case SND_SOC_DAPM_PRE_PMD: wcd_disable_irq(&rouleur->irq_info, @@ -833,24 +845,35 @@ static int rouleur_codec_enable_lo_pa(struct snd_soc_dapm_widget *w, ret = swr_slvdev_datapath_control(rouleur->rx_swr_dev, rouleur->rx_swr_dev->dev_num, true); + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL_5, + 0x04, 0x00); + usleep_range(1000, 1010); + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL_4, + 0x0F, 0x0F); + usleep_range(1000, 1010); snd_soc_component_update_bits(component, ROULEUR_ANA_COMBOPA_CTL, 0x40, 0x40); - usleep_range(5000, 5100); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_PDM_WD_CTL0, 0x03, 0x03); break; case SND_SOC_DAPM_POST_PMU: + usleep_range(5000, 5100); + snd_soc_component_update_bits(component, + ROULEUR_ANA_COMBOPA_CTL_4, + 0x0F, 0x04); if (rouleur->update_wcd_event) rouleur->update_wcd_event(rouleur->handle, WCD_BOLERO_EVT_RX_MUTE, (WCD_RX1 << 0x10)); - wcd_enable_irq(&rouleur->irq_info, - ROULEUR_IRQ_HPHL_PDM_WD_INT); + wcd_enable_irq(&rouleur->irq_info, + ROULEUR_IRQ_HPHL_PDM_WD_INT); break; case SND_SOC_DAPM_PRE_PMD: - wcd_disable_irq(&rouleur->irq_info, + wcd_disable_irq(&rouleur->irq_info, ROULEUR_IRQ_HPHL_PDM_WD_INT); if (rouleur->update_wcd_event) rouleur->update_wcd_event(rouleur->handle, -- GitLab From 5e3924dbf0249b86d81a44b11221e1fa83f68731 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 9 Jul 2020 19:36:36 +0530 Subject: [PATCH 1552/1645] asoc: Reset the buffer if size is partial or zero Sometimes during device switch in recording, observe size 0 is return from DSP due to EOS handling. For ALSA pcm_read to unblock, buffer appl_ptr is elapsed without actually updating the buffer. And userspace copies the stale data(old buffer) causing issue sometimes. Reset the buffer for that period_size in such cases instead of transfer stale data. Change-Id: I0d3ac133a8d95fad0710586e3e947410a41c9c5a Signed-off-by: Laxminath Kasam --- asoc/msm-pcm-q6-v2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 2fc5c8459263..1592c3f7ae41 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1007,6 +1007,11 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, xfer = size; offset = prtd->in_frame_info[idx].offset; pr_debug("Offset value = %d\n", offset); + if (size == 0 || size < fbytes) { + memset(bufptr + offset + size, 0, fbytes - size); + size = xfer = fbytes; + } + if (copy_to_user(buf, bufptr+offset, xfer)) { pr_err("Failed to copy buf to user\n"); ret = -EFAULT; -- GitLab From 9f083ad60abc7ed3087417f35d86691cebf2f1f8 Mon Sep 17 00:00:00 2001 From: Harshal Ahire Date: Mon, 13 Jul 2020 14:53:02 +0530 Subject: [PATCH 1553/1645] dsp: fix mute for AptX Adaptive A2DP streaming Only load depacketizer module for aptx_adaptive and ldac playback use-case during dynamic load of BT modules, decoder module loading not required. Change-Id: If7ec559f5cc7ff428b8e0e4fac1f34e7f2469c8e Signed-off-by: Harshal Ahire --- dsp/q6afe.c | 8 ++++++-- dsp/q6core.c | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 3d76e484859e..0811d6c137f3 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -5491,8 +5491,12 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, if ((q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= AVCS_API_VERSION_V5)) { - /* LDAC doesn't require decoder */ - if (codec_format == ENC_CODEC_TYPE_LDAC) + /* + * LDAC and APTX_ADAPTIVE don't require loading decoder module + * Only loading de-packetizer module. + */ + if (codec_format == ENC_CODEC_TYPE_LDAC || + codec_format == ASM_MEDIA_FMT_APTX_ADAPTIVE) ret = q6afe_load_avcs_modules(1, port_id, DECODER_CASE, codec_format); else diff --git a/dsp/q6core.c b/dsp/q6core.c index 8e8bedff42dd..392b09dec8e7 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -990,6 +990,7 @@ int32_t q6core_avcs_load_unload_modules(struct avcs_load_unload_modules_payload else mod->hdr.opcode = AVCS_CMD_UNLOAD_MODULES; + q6core_lcl.adsp_status = 0; q6core_lcl.avcs_module_resp_received = 0; ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *)mod); -- GitLab From 5741915c18cd3d3ddae9783e6e545c0a433018c8 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Thu, 23 Jul 2020 15:36:36 +0530 Subject: [PATCH 1554/1645] adsp-loader: Fix compilation error in adsp loader Debug logs arguments are not correct in adsp loader during an error scenario. Correct the arguments to fix compilation error. Change-Id: Ibdba5ce1332b287c84a38512fba8764298f4dd80 --- dsp/adsp-loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/adsp-loader.c b/dsp/adsp-loader.c index e99d6a3c7265..4804f8c7b047 100644 --- a/dsp/adsp-loader.c +++ b/dsp/adsp-loader.c @@ -359,7 +359,7 @@ static int adsp_loader_probe(struct platform_device *pdev) &adsp_fuse_not_supported); if (ret) { dev_dbg(&pdev->dev, - "%s: adsp_fuse_not_supported prop not found", + "%s: adsp_fuse_not_supported prop not found %d\n", __func__, ret); goto wqueue; } -- GitLab From ad9d364285b1b3363909a325545b720b02794122 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Mon, 13 Jul 2020 02:30:04 -0700 Subject: [PATCH 1555/1645] soc: swr-mstr: Avoid overflow during swr fifo read/write Avoid swr fifo overflow by checking no. of outstanding commands in fifo and comparing with fifo depth before every read/write. If no. of commands is equal to fifo depth then give some delay and retry. If no of outstanding commands are still equal to fifo depth then flush fifo and try writing/reading from fifo again. Change-Id: Ifd986c7affb70a61f8a90e4960a2779273a7d4d2 Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 72 +++++++++++++++++++++++++++++++++++++++++++++ soc/swr-mstr-ctrl.h | 2 ++ 2 files changed, 74 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index beaaa26f2833..623f70e6b56e 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -56,6 +56,8 @@ #define SWRM_COL_02 02 #define SWRM_COL_16 16 +#define SWR_OVERFLOW_RETRY_COUNT 30 + /* pm runtime auto suspend timer in msecs */ static int auto_suspend_timer = SWR_AUTO_SUSPEND_DELAY * 1000; module_param(auto_suspend_timer, int, 0664); @@ -84,6 +86,11 @@ enum { LPASS_AUDIO_CORE, }; +enum { + SWRM_WR_CHECK_AVAIL, + SWRM_RD_CHECK_AVAIL, +}; + #define TRUE 1 #define FALSE 0 @@ -743,6 +750,54 @@ static u32 swrm_get_packed_reg_val(u8 *cmd_id, u8 cmd_data, return val; } +static void swrm_wait_for_fifo_avail(struct swr_mstr_ctrl *swrm, int swrm_rd_wr) +{ + u32 fifo_outstanding_cmd; + u8 fifo_retry_count = SWR_OVERFLOW_RETRY_COUNT; + + if (swrm_rd_wr) { + /* Check for fifo underflow during read */ + /* Check no of outstanding commands in fifo before read */ + fifo_outstanding_cmd = ((swr_master_read(swrm, + SWRM_CMD_FIFO_STATUS) & 0x001F0000) >> 16); + if (fifo_outstanding_cmd == 0) { + while (fifo_retry_count) { + usleep_range(500, 510); + fifo_outstanding_cmd = + ((swr_master_read (swrm, + SWRM_CMD_FIFO_STATUS) & 0x001F0000) + >> 16); + fifo_retry_count--; + if (fifo_outstanding_cmd > 0) + break; + } + } + if (fifo_outstanding_cmd == 0) + dev_err_ratelimited(swrm->dev, + "%s err read underflow\n", __func__); + } else { + /* Check for fifo overflow during write */ + /* Check no of outstanding commands in fifo before write */ + fifo_outstanding_cmd = ((swr_master_read(swrm, + SWRM_CMD_FIFO_STATUS) & 0x00001F00) + >> 8); + if (fifo_outstanding_cmd == swrm->wr_fifo_depth) { + while (fifo_retry_count) { + usleep_range(500, 510); + fifo_outstanding_cmd = + ((swr_master_read(swrm, SWRM_CMD_FIFO_STATUS) + & 0x00001F00) >> 8); + fifo_retry_count--; + if (fifo_outstanding_cmd < swrm->wr_fifo_depth) + break; + } + } + if (fifo_outstanding_cmd == swrm->wr_fifo_depth) + dev_err_ratelimited(swrm->dev, + "%s err write overflow\n", __func__); + } +} + static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, u8 dev_addr, u8 cmd_id, u16 reg_addr, u32 len) @@ -756,12 +811,19 @@ static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data, /* skip delay if read is handled in platform driver */ swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val); } else { + /* + * Check for outstanding cmd wrt. write fifo depth to avoid + * overflow as read will also increase write fifo cnt. + */ + swrm_wait_for_fifo_avail(swrm, SWRM_WR_CHECK_AVAIL); /* wait for FIFO RD to complete to avoid overflow */ usleep_range(100, 105); swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val); /* wait for FIFO RD CMD complete to avoid overflow */ usleep_range(250, 255); } + /* Check if slave responds properly after FIFO RD is complete */ + swrm_wait_for_fifo_avail(swrm, SWRM_RD_CHECK_AVAIL); retry_read: *cmd_data = swr_master_read(swrm, SWRM_CMD_FIFO_RD_FIFO_ADDR); dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x, rcmd_id: 0x%x, \ @@ -808,6 +870,11 @@ static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data, dev_dbg(swrm->dev, "%s: reg: 0x%x, cmd_id: 0x%x,wcmd_id: 0x%x, \ dev_num: 0x%x, cmd_data: 0x%x\n", __func__, reg_addr, cmd_id, swrm->wcmd_id,dev_addr, cmd_data); + /* + * Check for outstanding cmd wrt. write fifo depth to avoid + * overflow. + */ + swrm_wait_for_fifo_avail(swrm, SWRM_WR_CHECK_AVAIL); swr_master_write(swrm, SWRM_CMD_FIFO_WR_CMD, val); /* * wait for FIFO WR command to complete to avoid overflow @@ -2785,6 +2852,11 @@ static int swrm_probe(struct platform_device *pdev) if (pdev->dev.of_node) of_register_swr_devices(&swrm->master); + swrm->rd_fifo_depth = ((swr_master_read(swrm, SWRM_COMP_PARAMS) + & SWRM_COMP_PARAMS_RD_FIFO_DEPTH) >> 15); + swrm->wr_fifo_depth = ((swr_master_read(swrm, SWRM_COMP_PARAMS) + & SWRM_COMP_PARAMS_WR_FIFO_DEPTH) >> 10); + #ifdef CONFIG_DEBUG_FS swrm->debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0); if (!IS_ERR(swrm->debugfs_swrm_dent)) { diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 8d38441289b9..51b35386ff49 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -182,6 +182,8 @@ struct swr_mstr_ctrl { int aud_core_clk_en; int clk_src; u32 disable_div2_clk_switch; + u32 rd_fifo_depth; + u32 wr_fifo_depth; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_swrm_dent; struct dentry *debugfs_peek; -- GitLab From 6167754f0e21a27259c8ef9570f8d877e4410811 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 27 Mar 2020 07:12:58 +0530 Subject: [PATCH 1556/1645] ASoC: wsa883x: Update initial register sequence Update initial regsiter sequence for wsa883x speaker amplifier as per hardware requirements. Change-Id: I3cd0458980bdc5140ff81b3b8ba6bab42e72fd49 Signed-off-by: Sudheer Papothi --- asoc/codecs/wsa883x/wsa883x.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index c14114f935d7..578163ca8a98 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -64,6 +64,8 @@ struct wsa_reg_mask_val { static const struct wsa_reg_mask_val reg_init[] = { {WSA883X_PA_FSM_BYP, 0x01, 0x00}, + {WSA883X_ISENSE2, 0xE0, 0x40}, + {WSA883X_ADC_6, 0x02, 0x02}, {WSA883X_CDC_SPK_DSM_A2_0, 0xFF, 0x0A}, {WSA883X_CDC_SPK_DSM_A2_1, 0x0F, 0x08}, {WSA883X_CDC_SPK_DSM_A3_0, 0xFF, 0xF3}, @@ -102,8 +104,12 @@ static const struct wsa_reg_mask_val reg_init[] = { {WSA883X_OTP_REG_3, 0xFF, 0xC9}, {WSA883X_OTP_REG_4, 0xC0, 0x40}, {WSA883X_TAGC_CTL, 0x01, 0x01}, + {WSA883X_ADC_2, 0x40, 0x00}, + {WSA883X_ADC_7, 0x04, 0x04}, + {WSA883X_ADC_7, 0x02, 0x02}, {WSA883X_CKWD_CTL_0, 0x60, 0x00}, {WSA883X_CKWD_CTL_1, 0x1F, 0x1B}, + {WSA883X_GMAMP_SUP1, 0x60, 0x60}, }; static int wsa883x_get_temperature(struct snd_soc_component *component, -- GitLab From 51af4b3c2a755f45d5409e43157d498edb05a9a1 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 28 Apr 2020 23:32:45 +0530 Subject: [PATCH 1557/1645] soc: wsa883x: Update changes for wsa8830 Update DRE_CTL offset to 3 for wsa8830 variant. Change-Id: I9acab01b0099093b8e427d52e48ba9744c6f5aac Signed-off-by: Laxminath Kasam --- asoc/codecs/wsa883x/wsa883x.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index c14114f935d7..734b2410086d 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -1056,6 +1056,10 @@ static void wsa883x_codec_init(struct snd_soc_component *component) for (i = 0; i < ARRAY_SIZE(reg_init); i++) snd_soc_component_update_bits(component, reg_init[i].reg, reg_init[i].mask, reg_init[i].val); + + if (wsa883x->variant == WSA8830) + snd_soc_component_update_bits(component, WSA883X_DRE_CTL_0, + 0x07, 0x03); } static int32_t wsa883x_temp_reg_read(struct snd_soc_component *component, -- GitLab From da73727233214647063e09fde1d45129b5694efa Mon Sep 17 00:00:00 2001 From: Xiao Li Date: Mon, 27 Jul 2020 15:47:02 +0800 Subject: [PATCH 1558/1645] adsp-loader: Fix compilation error Print the variables of size_t length using '%zu' to fix compilation error. Change-Id: I56b15d56a213d994d278d353336afefe0907a426 Signed-off-by: Xiao Li --- dsp/adsp-loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/adsp-loader.c b/dsp/adsp-loader.c index 4804f8c7b047..a32acfd35909 100644 --- a/dsp/adsp-loader.c +++ b/dsp/adsp-loader.c @@ -393,7 +393,7 @@ static int adsp_loader_probe(struct platform_device *pdev) goto wqueue; } if (len <= 0 || len > sizeof(u32)) { - dev_dbg(&pdev->dev, "%s: nvmem cell length out of range: %d\n", + dev_dbg(&pdev->dev, "%s: nvmem cell length out of range: %zu\n", __func__, len); kfree(buf); goto wqueue; -- GitLab From 8203a06e6197a322b426971de2bfb94d5c29616a Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 17 Jul 2020 19:13:19 +0530 Subject: [PATCH 1559/1645] ASoC: rouleur: Change hph and ear gain according to soc capacity Register to power supply framework to get soc capacity. Reduce ear and hph gain for reduced voltage to optimize power consumption. Also set LD22 voltage to lower value for low SoC. Change-Id: I94de9341b8c7307128d3cd41c7398c31d57fa685 Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/bolero-cdc.c | 6 ++ asoc/codecs/bolero/bolero-cdc.h | 1 + asoc/codecs/bolero/internal.h | 1 + asoc/codecs/bolero/rx-macro.c | 49 ++++++++++++++ asoc/codecs/msm-cdc-supply.c | 46 +++++++++++++ asoc/codecs/rouleur/internal.h | 4 ++ asoc/codecs/rouleur/rouleur.c | 113 ++++++++++++++++++++++++++++++++ include/asoc/msm-cdc-supply.h | 6 ++ 8 files changed, 226 insertions(+) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 233a0b4b40a9..173343cab6e1 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -232,6 +232,12 @@ static int bolero_cdc_update_wcd_event(void *handle, u16 event, u32 data) priv->component, BOLERO_MACRO_EVT_BCS_CLK_OFF, data); break; + case WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE: + if (priv->macro_params[RX_MACRO].event_handler) + priv->macro_params[RX_MACRO].event_handler( + priv->component, + BOLERO_MACRO_EVT_RX_PA_GAIN_UPDATE, data); + break; default: dev_err(priv->dev, "%s: Invalid event %d trigger from wcd\n", __func__, event); diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 7e3468a8fa1a..bcd4a255bd17 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -55,6 +55,7 @@ enum { BOLERO_MACRO_EVT_BCS_CLK_OFF, BOLERO_MACRO_EVT_SSR_GFMUX_UP, BOLERO_MACRO_EVT_PRE_SSR_UP, + BOLERO_MACRO_EVT_RX_PA_GAIN_UPDATE, }; enum { diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index d3a072c9cea9..4d098da335a2 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -33,6 +33,7 @@ enum { WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */ WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST, WCD_BOLERO_EVT_BCS_CLK_OFF, + WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE, }; struct wcd_ctrl_platform_data { diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index c858d2c65356..f79e984ed397 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -77,6 +77,11 @@ static const struct snd_kcontrol_new name##_mux = \ #define RX_MACRO_EC_MIX_TX1_MASK 0x0f #define RX_MACRO_EC_MIX_TX2_MASK 0x0f +#define RX_MACRO_GAIN_MAX_VAL 0x28 +#define RX_MACRO_GAIN_VAL_UNITY 0x0 +/* Define macros to increase PA Gain by half */ +#define RX_MACRO_MOD_GAIN (RX_MACRO_GAIN_VAL_UNITY + 6) + #define COMP_MAX_COEFF 25 struct wcd_imped_val { @@ -452,6 +457,8 @@ struct rx_macro_priv { struct rx_macro_bcl_pmic_params bcl_pmic_params; u16 clk_id; u16 default_clk_id; + int8_t rx0_gain_val; + int8_t rx1_gain_val; }; static struct snd_soc_dai_driver rx_macro_dai[]; @@ -1416,6 +1423,46 @@ static int rx_macro_event_handler(struct snd_soc_component *component, case BOLERO_MACRO_EVT_CLK_RESET: bolero_rsc_clk_reset(rx_dev, RX_CORE_CLK); break; + case BOLERO_MACRO_EVT_RX_PA_GAIN_UPDATE: + rx_priv->rx0_gain_val = snd_soc_component_read32(component, + BOLERO_CDC_RX_RX0_RX_VOL_CTL); + rx_priv->rx1_gain_val = snd_soc_component_read32(component, + BOLERO_CDC_RX_RX1_RX_VOL_CTL); + if (data) { + /* Reduce gain by half only if its greater than -6DB */ + if ((rx_priv->rx0_gain_val >= RX_MACRO_GAIN_VAL_UNITY) + && (rx_priv->rx0_gain_val <= RX_MACRO_GAIN_MAX_VAL)) + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xFF, + (rx_priv->rx0_gain_val - + RX_MACRO_MOD_GAIN)); + if ((rx_priv->rx1_gain_val >= RX_MACRO_GAIN_VAL_UNITY) + && (rx_priv->rx1_gain_val <= RX_MACRO_GAIN_MAX_VAL)) + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xFF, + (rx_priv->rx1_gain_val - + RX_MACRO_MOD_GAIN)); + } + else { + /* Reset gain value to default */ + if ((rx_priv->rx0_gain_val >= + (RX_MACRO_GAIN_VAL_UNITY - RX_MACRO_MOD_GAIN)) && + (rx_priv->rx0_gain_val <= (RX_MACRO_GAIN_MAX_VAL - + RX_MACRO_MOD_GAIN))) + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xFF, + (rx_priv->rx0_gain_val + + RX_MACRO_MOD_GAIN)); + if ((rx_priv->rx1_gain_val >= + (RX_MACRO_GAIN_VAL_UNITY - RX_MACRO_MOD_GAIN)) && + (rx_priv->rx1_gain_val <= (RX_MACRO_GAIN_MAX_VAL - + RX_MACRO_MOD_GAIN))) + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xFF, + (rx_priv->rx1_gain_val + + RX_MACRO_MOD_GAIN)); + } + break; } done: return ret; @@ -3825,6 +3872,8 @@ static int rx_macro_init(struct snd_soc_component *component) return ret; } rx_priv->dev_up = true; + rx_priv->rx0_gain_val = 0; + rx_priv->rx1_gain_val = 0; snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF1 Playback"); snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF2 Playback"); snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF3 Playback"); diff --git a/asoc/codecs/msm-cdc-supply.c b/asoc/codecs/msm-cdc-supply.c index 0d49c28f1eb9..98639f3cf8b2 100644 --- a/asoc/codecs/msm-cdc-supply.c +++ b/asoc/codecs/msm-cdc-supply.c @@ -172,6 +172,52 @@ bool msm_cdc_is_ondemand_supply(struct device *dev, } EXPORT_SYMBOL(msm_cdc_is_ondemand_supply); +/* + * msm_cdc_set_supply_min_voltage: + * Set min supply voltage for particular supply + * + * @dev: pointer to codec device + * @supplies: pointer to regulator bulk data + * @cdc_vreg: pointer to platform regulator data + * @num_supplies: number of supplies + * @supply_name: Supply name to change voltage for + * @vval_min: Min voltage to be set in uV + * @override_min_vol: True if override min voltage from default + * Return error code if unable to set voltage + */ +int msm_cdc_set_supply_min_voltage(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies, char *supply_name, + int vval_min, bool override_min_vol) +{ + int rc = 0, i; + + if ((!supply_name) || (!supplies)) { + pr_err("%s: either dev or supplies or cdc_vreg is NULL\n", + __func__); + return -EINVAL; + } + /* input parameter validation */ + rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies); + if (rc) + return rc; + for (i = 0; i < num_supplies; i++) { + if (!strcmp(cdc_vreg[i].name, supply_name)) { + if (override_min_vol) + regulator_set_voltage(supplies[i].consumer, + vval_min, cdc_vreg[i].max_uV); + else + regulator_set_voltage(supplies[i].consumer, + cdc_vreg[i].min_uV, cdc_vreg[i].max_uV); + break; + } + } + + return rc; +} +EXPORT_SYMBOL(msm_cdc_set_supply_min_voltage); + /* * msm_cdc_disable_ondemand_supply: * Disable codec ondemand supply diff --git a/asoc/codecs/rouleur/internal.h b/asoc/codecs/rouleur/internal.h index cc1500be70d6..b1d21faafb20 100644 --- a/asoc/codecs/rouleur/internal.h +++ b/asoc/codecs/rouleur/internal.h @@ -85,6 +85,9 @@ struct rouleur_priv { struct mutex main_bias_lock; bool dev_up; bool usbc_hs_status; + struct notifier_block psy_nb; + struct work_struct soc_eval_work; + bool low_soc; }; struct rouleur_micbias_setting { @@ -131,6 +134,7 @@ enum { WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */ WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST, WCD_BOLERO_EVT_BCS_CLK_OFF, + WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE, /* To reduce PA gain for low SoC */ }; enum { diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index 8ce51a3b159c..9066bd8e60d8 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -26,6 +26,7 @@ #include #include #include +#include #define DRV_NAME "rouleur_codec" @@ -35,6 +36,8 @@ #define ROULEUR_VERSION_ENTRY_SIZE 32 #define NUM_ATTEMPTS 5 +#define SOC_THRESHOLD_LEVEL 25 +#define LOW_SOC_MBIAS_REG_MIN_VOLTAGE 2850000 enum { CODEC_TX = 0, @@ -2000,6 +2003,107 @@ static int rouleur_set_micbias_data(struct rouleur_priv *rouleur, return rc; } +static int rouleur_battery_supply_cb(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct power_supply *psy = data; + struct rouleur_priv *rouleur = + container_of(nb, struct rouleur_priv, psy_nb); + + if (strcmp(psy->desc->name, "battery")) + return NOTIFY_OK; + queue_work(system_freezable_wq, &rouleur->soc_eval_work); + + return NOTIFY_OK; +} + +static int rouleur_read_battery_soc(struct rouleur_priv *rouleur, int *soc_val) +{ + static struct power_supply *batt_psy; + union power_supply_propval ret = {0,}; + int err = 0; + + *soc_val = 100; + if (!batt_psy) + batt_psy = power_supply_get_by_name("battery"); + if (batt_psy) { + err = power_supply_get_property(batt_psy, + POWER_SUPPLY_PROP_CAPACITY, &ret); + if (err) { + pr_err("%s: battery SoC read error:%d\n", + __func__, err); + return err; + } + *soc_val = ret.intval; + } + pr_debug("%s: soc:%d\n", __func__, *soc_val); + + return err; +} + +static void rouleur_evaluate_soc(struct work_struct *work) +{ + struct rouleur_priv *rouleur = + container_of(work, struct rouleur_priv, soc_eval_work); + int soc_val = 0, ret = 0; + struct rouleur_pdata *pdata = NULL; + + pdata = dev_get_platdata(rouleur->dev); + if (!pdata) { + dev_err(rouleur->dev, "%s: pdata is NULL\n", __func__); + return; + } + + if (rouleur_read_battery_soc(rouleur, &soc_val) < 0) { + dev_err(rouleur->dev, "%s unable to read battery SoC\n", + __func__); + return; + } + + if (soc_val < SOC_THRESHOLD_LEVEL) { + dev_dbg(rouleur->dev, + "%s battery SoC less than threshold soc_val = %d\n", + __func__, soc_val); + /* Reduce PA Gain by 6DB for low SoC */ + if (rouleur->update_wcd_event) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE, + true); + rouleur->low_soc = true; + ret = msm_cdc_set_supply_min_voltage(rouleur->dev, + rouleur->supplies, + pdata->regulator, + pdata->num_supplies, + "cdc-vdd-mic-bias", + LOW_SOC_MBIAS_REG_MIN_VOLTAGE, + true); + if (ret < 0) + dev_err(rouleur->dev, + "%s unable to set mbias min voltage\n", + __func__); + } else { + if (rouleur->low_soc == true) { + /* Reset PA Gain to default for normal SoC */ + if (rouleur->update_wcd_event) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE, + false); + ret = msm_cdc_set_supply_min_voltage(rouleur->dev, + rouleur->supplies, + pdata->regulator, + pdata->num_supplies, + "cdc-vdd-mic-bias", + LOW_SOC_MBIAS_REG_MIN_VOLTAGE, + false); + if (ret < 0) + dev_err(rouleur->dev, + "%s unable to set mbias min voltage\n", + __func__); + rouleur->low_soc = false; + } + } +} + static int rouleur_soc_codec_probe(struct snd_soc_component *component) { struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); @@ -2070,7 +2174,16 @@ static int rouleur_soc_codec_probe(struct snd_soc_component *component) return ret; } } + rouleur->low_soc = false; rouleur->dev_up = true; + /* Register notifier to change gain based on state of charge */ + INIT_WORK(&rouleur->soc_eval_work, rouleur_evaluate_soc); + rouleur->psy_nb.notifier_call = rouleur_battery_supply_cb; + if (power_supply_reg_notifier(&rouleur->psy_nb) < 0) + dev_dbg(rouleur->dev, + "%s: could not register pwr supply notifier\n", + __func__); + queue_work(system_freezable_wq, &rouleur->soc_eval_work); done: return ret; } diff --git a/include/asoc/msm-cdc-supply.h b/include/asoc/msm-cdc-supply.h index 336ec22eb495..c5e410603253 100644 --- a/include/asoc/msm-cdc-supply.h +++ b/include/asoc/msm-cdc-supply.h @@ -60,4 +60,10 @@ extern int msm_cdc_init_supplies_v2(struct device *dev, struct cdc_regulator *cdc_vreg, int num_supplies, u32 vote_regulator_on_demand); +extern int msm_cdc_set_supply_min_voltage(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies, char *supply_name, + int vval_min, bool override_min_vol); + #endif -- GitLab From 8d4f94c54af0e3f32d12d5f2b4f92bc10acd5e15 Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Wed, 1 Jul 2020 17:05:03 +0530 Subject: [PATCH 1560/1645] ASoC: soc: Add pinctrl-lpi legacy driver for sdm660 Use the legacy pinctrl-lpi driver for sdm660 instead of the latest driver to avoid conflicts. Change-Id: I58b1854eecb9488227c6e378c9ac10f779259e90 Signed-off-by: Soumya Managoli --- config/sdm660auto.conf | 2 +- config/sdm660autoconf.h | 2 +- soc/Kbuild | 8 + soc/pinctrl-lpi-legacy.c | 777 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 787 insertions(+), 2 deletions(-) create mode 100644 soc/pinctrl-lpi-legacy.c diff --git a/config/sdm660auto.conf b/config/sdm660auto.conf index a39bd05c6d4a..9a31ece8a19b 100644 --- a/config/sdm660auto.conf +++ b/config/sdm660auto.conf @@ -1,4 +1,4 @@ -CONFIG_PINCTRL_LPI=m +CONFIG_PINCTRL_LPI_LEGACY=m CONFIG_PINCTRL_WCD=m CONFIG_AUDIO_EXT_CLK=m CONFIG_SND_SOC_WCD9XXX_V2=m diff --git a/config/sdm660autoconf.h b/config/sdm660autoconf.h index 7fa702159d26..077149a02ef8 100644 --- a/config/sdm660autoconf.h +++ b/config/sdm660autoconf.h @@ -11,7 +11,7 @@ * GNU General Public License for more details. */ -#define CONFIG_PINCTRL_LPI 1 +#define CONFIG_PINCTRL_LPI_LEGACY 1 #define CONFIG_PINCTRL_WCD 1 #define CONFIG_AUDIO_EXT_CLK 1 #define CONFIG_SND_SOC_WCD9XXX_V2 1 diff --git a/soc/Kbuild b/soc/Kbuild index f77f38619695..4fedbddcf460 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -119,6 +119,11 @@ ifdef CONFIG_PINCTRL_LPI PINCTRL_LPI_OBJS += pinctrl-lpi.o endif +# for pinctrl LPI legacy driver +ifdef CONFIG_PINCTRL_LPI_LEGACY + PINCTRL_LPI_OBJS += pinctrl-lpi-legacy.o +endif + # for soundwire driver ifdef CONFIG_SOUNDWIRE_WCD_CTRL SWR_CTRL_OBJS += swr-wcd-ctrl.o @@ -191,6 +196,9 @@ pinctrl_wcd_dlkm-y := $(PINCTRL_WCD_OBJS) obj-$(CONFIG_PINCTRL_LPI) += pinctrl_lpi_dlkm.o pinctrl_lpi_dlkm-y := $(PINCTRL_LPI_OBJS) +obj-$(CONFIG_PINCTRL_LPI_LEGACY) += pinctrl_lpi_dlkm.o +pinctrl_lpi_dlkm-y := $(PINCTRL_LPI_OBJS) + obj-$(CONFIG_SOUNDWIRE) += swr_dlkm.o swr_dlkm-y := $(SWR_OBJS) diff --git a/soc/pinctrl-lpi-legacy.c b/soc/pinctrl-lpi-legacy.c new file mode 100644 index 000000000000..5bf64966d9ee --- /dev/null +++ b/soc/pinctrl-lpi-legacy.c @@ -0,0 +1,777 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "core.h" +#include "pinctrl-utils.h" + +#define LPI_AUTO_SUSPEND_DELAY 100 /* delay in msec */ + +#define LPI_ADDRESS_SIZE 0x20000 + +#define LPI_GPIO_REG_VAL_CTL 0x00 +#define LPI_GPIO_REG_DIR_CTL 0x04 + +#define LPI_GPIO_REG_PULL_SHIFT 0x0 +#define LPI_GPIO_REG_PULL_MASK 0x3 + +#define LPI_GPIO_REG_FUNCTION_SHIFT 0x2 +#define LPI_GPIO_REG_FUNCTION_MASK 0x3C + +#define LPI_GPIO_REG_OUT_STRENGTH_SHIFT 0x6 +#define LPI_GPIO_REG_OUT_STRENGTH_MASK 0x1C0 + +#define LPI_GPIO_REG_OE_SHIFT 0x9 +#define LPI_GPIO_REG_OE_MASK 0x200 + +#define LPI_GPIO_REG_DIR_SHIFT 0x1 +#define LPI_GPIO_REG_DIR_MASK 0x2 + +#define LPI_GPIO_BIAS_DISABLE 0x0 +#define LPI_GPIO_PULL_DOWN 0x1 +#define LPI_GPIO_KEEPER 0x2 +#define LPI_GPIO_PULL_UP 0x3 + +#define LPI_GPIO_FUNC_GPIO "gpio" +#define LPI_GPIO_FUNC_FUNC1 "func1" +#define LPI_GPIO_FUNC_FUNC2 "func2" +#define LPI_GPIO_FUNC_FUNC3 "func3" +#define LPI_GPIO_FUNC_FUNC4 "func4" +#define LPI_GPIO_FUNC_FUNC5 "func5" + +static bool lpi_dev_up; +static struct device *lpi_dev; + +/* The index of each function in lpi_gpio_functions[] array */ +enum lpi_gpio_func_index { + LPI_GPIO_FUNC_INDEX_GPIO = 0x00, + LPI_GPIO_FUNC_INDEX_FUNC1 = 0x01, + LPI_GPIO_FUNC_INDEX_FUNC2 = 0x02, + LPI_GPIO_FUNC_INDEX_FUNC3 = 0x03, + LPI_GPIO_FUNC_INDEX_FUNC4 = 0x04, + LPI_GPIO_FUNC_INDEX_FUNC5 = 0x05, +}; + +/** + * struct lpi_gpio_pad - keep current GPIO settings + * @offset: Nth GPIO in supported GPIOs. + * @output_enabled: Set to true if GPIO output logic is enabled. + * @value: value of a pin + * @base: Address base of LPI GPIO PAD. + * @pullup: Constant current which flow through GPIO output buffer. + * @strength: No, Low, Medium, High + * @function: See lpi_gpio_functions[] + */ +struct lpi_gpio_pad { + u32 offset; + bool output_enabled; + bool value; + char __iomem *base; + unsigned int pullup; + unsigned int strength; + unsigned int function; +}; + +struct lpi_gpio_state { + struct device *dev; + struct pinctrl_dev *ctrl; + struct gpio_chip chip; + char __iomem *base; + struct clk *lpass_core_hw_vote; + bool core_hw_vote_status; +}; + +static const char *const lpi_gpio_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", + "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", + "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", + "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", + "gpio29", "gpio30", "gpio31", +}; + +#define LPI_TLMM_MAX_PINS 100 +static u32 lpi_offset[LPI_TLMM_MAX_PINS]; + +static const char *const lpi_gpio_functions[] = { + [LPI_GPIO_FUNC_INDEX_GPIO] = LPI_GPIO_FUNC_GPIO, + [LPI_GPIO_FUNC_INDEX_FUNC1] = LPI_GPIO_FUNC_FUNC1, + [LPI_GPIO_FUNC_INDEX_FUNC2] = LPI_GPIO_FUNC_FUNC2, + [LPI_GPIO_FUNC_INDEX_FUNC3] = LPI_GPIO_FUNC_FUNC3, + [LPI_GPIO_FUNC_INDEX_FUNC4] = LPI_GPIO_FUNC_FUNC4, + [LPI_GPIO_FUNC_INDEX_FUNC5] = LPI_GPIO_FUNC_FUNC5, +}; + +static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr) +{ + int ret; + + if (!lpi_dev_up) { + pr_err_ratelimited("%s: ADSP is down due to SSR, return\n", + __func__); + return 0; + } + pm_runtime_get_sync(lpi_dev); + + ret = ioread32(pad->base + pad->offset + addr); + if (ret < 0) + pr_err("%s: read 0x%x failed\n", __func__, addr); + + pm_runtime_mark_last_busy(lpi_dev); + pm_runtime_put_autosuspend(lpi_dev); + return ret; +} + +static int lpi_gpio_write(struct lpi_gpio_pad *pad, unsigned int addr, + unsigned int val) +{ + if (!lpi_dev_up) { + pr_err_ratelimited("%s: ADSP is down due to SSR, return\n", + __func__); + return 0; + } + pm_runtime_get_sync(lpi_dev); + + iowrite32(val, pad->base + pad->offset + addr); + + pm_runtime_mark_last_busy(lpi_dev); + pm_runtime_put_autosuspend(lpi_dev); + return 0; +} + +static int lpi_gpio_get_groups_count(struct pinctrl_dev *pctldev) +{ + /* Every PIN is a group */ + return pctldev->desc->npins; +} + +static const char *lpi_gpio_get_group_name(struct pinctrl_dev *pctldev, + unsigned int pin) +{ + return pctldev->desc->pins[pin].name; +} + +static int lpi_gpio_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int pin, + const unsigned int **pins, + unsigned int *num_pins) +{ + *pins = &pctldev->desc->pins[pin].number; + *num_pins = 1; + return 0; +} + +static const struct pinctrl_ops lpi_gpio_pinctrl_ops = { + .get_groups_count = lpi_gpio_get_groups_count, + .get_group_name = lpi_gpio_get_group_name, + .get_group_pins = lpi_gpio_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_group, + .dt_free_map = pinctrl_utils_free_map, +}; + +static int lpi_gpio_get_functions_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(lpi_gpio_functions); +} + +static const char *lpi_gpio_get_function_name(struct pinctrl_dev *pctldev, + unsigned int function) +{ + return lpi_gpio_functions[function]; +} + +static int lpi_gpio_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int function, + const char *const **groups, + unsigned *const num_qgroups) +{ + *groups = lpi_gpio_groups; + *num_qgroups = pctldev->desc->npins; + return 0; +} + +static int lpi_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int function, + unsigned int pin) +{ + struct lpi_gpio_pad *pad; + unsigned int val; + + pad = pctldev->desc->pins[pin].drv_data; + + pad->function = function; + + val = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL); + val &= ~(LPI_GPIO_REG_FUNCTION_MASK); + val |= pad->function << LPI_GPIO_REG_FUNCTION_SHIFT; + lpi_gpio_write(pad, LPI_GPIO_REG_VAL_CTL, val); + return 0; +} + +static const struct pinmux_ops lpi_gpio_pinmux_ops = { + .get_functions_count = lpi_gpio_get_functions_count, + .get_function_name = lpi_gpio_get_function_name, + .get_function_groups = lpi_gpio_get_function_groups, + .set_mux = lpi_gpio_set_mux, +}; + +static int lpi_config_get(struct pinctrl_dev *pctldev, + unsigned int pin, unsigned long *config) +{ + unsigned int param = pinconf_to_config_param(*config); + struct lpi_gpio_pad *pad; + unsigned int arg; + + pad = pctldev->desc->pins[pin].drv_data; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + arg = pad->pullup = LPI_GPIO_BIAS_DISABLE; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + arg = pad->pullup == LPI_GPIO_PULL_DOWN; + break; + case PIN_CONFIG_BIAS_BUS_HOLD: + arg = pad->pullup = LPI_GPIO_KEEPER; + break; + case PIN_CONFIG_BIAS_PULL_UP: + arg = pad->pullup == LPI_GPIO_PULL_UP; + break; + case PIN_CONFIG_INPUT_ENABLE: + case PIN_CONFIG_OUTPUT: + arg = pad->output_enabled; + break; + default: + return -EINVAL; + } + + *config = pinconf_to_config_packed(param, arg); + return 0; +} + +static unsigned int lpi_drive_to_regval(u32 arg) +{ + return (arg/2 - 1); +} + +static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int nconfs) +{ + struct lpi_gpio_pad *pad; + unsigned int param, arg; + int i, ret = 0, val; + + pad = pctldev->desc->pins[pin].drv_data; + + for (i = 0; i < nconfs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + dev_dbg(pctldev->dev, "%s: param: %d arg: %d pin: %d\n", + __func__, param, arg, pin); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + pad->pullup = LPI_GPIO_BIAS_DISABLE; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + pad->pullup = LPI_GPIO_PULL_DOWN; + break; + case PIN_CONFIG_BIAS_BUS_HOLD: + pad->pullup = LPI_GPIO_KEEPER; + break; + case PIN_CONFIG_BIAS_PULL_UP: + pad->pullup = LPI_GPIO_PULL_UP; + break; + case PIN_CONFIG_INPUT_ENABLE: + pad->output_enabled = false; + break; + case PIN_CONFIG_OUTPUT: + pad->output_enabled = true; + pad->value = arg; + break; + case PIN_CONFIG_DRIVE_STRENGTH: + pad->strength = arg; + break; + default: + ret = -EINVAL; + goto done; + } + } + + val = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL); + val &= ~(LPI_GPIO_REG_PULL_MASK | LPI_GPIO_REG_OUT_STRENGTH_MASK | + LPI_GPIO_REG_OE_MASK); + val |= pad->pullup << LPI_GPIO_REG_PULL_SHIFT; + val |= lpi_drive_to_regval(pad->strength) << + LPI_GPIO_REG_OUT_STRENGTH_SHIFT; + if (pad->output_enabled) + val |= pad->value << LPI_GPIO_REG_OE_SHIFT; + + lpi_gpio_write(pad, LPI_GPIO_REG_VAL_CTL, val); + lpi_gpio_write(pad, LPI_GPIO_REG_DIR_CTL, + pad->output_enabled << LPI_GPIO_REG_DIR_SHIFT); +done: + return ret; +} + +static const struct pinconf_ops lpi_gpio_pinconf_ops = { + .is_generic = true, + .pin_config_group_get = lpi_config_get, + .pin_config_group_set = lpi_config_set, +}; + +static int lpi_gpio_direction_input(struct gpio_chip *chip, unsigned int pin) +{ + struct lpi_gpio_state *state = gpiochip_get_data(chip); + unsigned long config; + + config = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1); + + return lpi_config_set(state->ctrl, pin, &config, 1); +} + +static int lpi_gpio_direction_output(struct gpio_chip *chip, + unsigned int pin, int val) +{ + struct lpi_gpio_state *state = gpiochip_get_data(chip); + unsigned long config; + + config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, val); + + return lpi_config_set(state->ctrl, pin, &config, 1); +} + +static int lpi_gpio_get(struct gpio_chip *chip, unsigned int pin) +{ + struct lpi_gpio_state *state = gpiochip_get_data(chip); + struct lpi_gpio_pad *pad; + int value; + + pad = state->ctrl->desc->pins[pin].drv_data; + + value = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL); + return value; +} + +static void lpi_gpio_set(struct gpio_chip *chip, unsigned int pin, int value) +{ + struct lpi_gpio_state *state = gpiochip_get_data(chip); + unsigned long config; + + config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, value); + + lpi_config_set(state->ctrl, pin, &config, 1); +} + +static int lpi_notifier_service_cb(struct notifier_block *this, + unsigned long opcode, void *ptr) +{ + static bool initial_boot = true; + + pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); + + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + if (initial_boot) { + initial_boot = false; + break; + } + snd_event_notify(lpi_dev, SND_EVENT_DOWN); + lpi_dev_up = false; + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (initial_boot) + initial_boot = false; + lpi_dev_up = true; + snd_event_notify(lpi_dev, SND_EVENT_UP); + break; + default: + break; + } + return NOTIFY_OK; +} + +static struct notifier_block service_nb = { + .notifier_call = lpi_notifier_service_cb, + .priority = -INT_MAX, +}; + +static void lpi_pinctrl_ssr_disable(struct device *dev, void *data) +{ + lpi_dev_up = false; +} + +static const struct snd_event_ops lpi_pinctrl_ssr_ops = { + .disable = lpi_pinctrl_ssr_disable, +}; + +#ifdef CONFIG_DEBUG_FS +#include + +static unsigned int lpi_regval_to_drive(u32 val) +{ + return (val + 1) * 2; +} + +static void lpi_gpio_dbg_show_one(struct seq_file *s, + struct pinctrl_dev *pctldev, + struct gpio_chip *chip, + unsigned int offset, + unsigned int gpio) +{ + struct lpi_gpio_state *state = gpiochip_get_data(chip); + struct pinctrl_pin_desc pindesc; + struct lpi_gpio_pad *pad; + unsigned int func; + int is_out; + int drive; + int pull; + u32 ctl_reg; + + static const char * const pulls[] = { + "no pull", + "pull down", + "keeper", + "pull up" + }; + + pctldev = pctldev ? : state->ctrl; + pindesc = pctldev->desc->pins[offset]; + pad = pctldev->desc->pins[offset].drv_data; + ctl_reg = lpi_gpio_read(pad, LPI_GPIO_REG_DIR_CTL); + is_out = (ctl_reg & LPI_GPIO_REG_DIR_MASK) >> LPI_GPIO_REG_DIR_SHIFT; + ctl_reg = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL); + + func = (ctl_reg & LPI_GPIO_REG_FUNCTION_MASK) >> + LPI_GPIO_REG_FUNCTION_SHIFT; + drive = (ctl_reg & LPI_GPIO_REG_OUT_STRENGTH_MASK) >> + LPI_GPIO_REG_OUT_STRENGTH_SHIFT; + pull = (ctl_reg & LPI_GPIO_REG_PULL_MASK) >> LPI_GPIO_REG_PULL_SHIFT; + + seq_printf(s, " %-8s: %-3s %d", + pindesc.name, is_out ? "out" : "in", func); + seq_printf(s, " %dmA", lpi_regval_to_drive(drive)); + seq_printf(s, " %s", pulls[pull]); +} + +static void lpi_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) +{ + unsigned int gpio = chip->base; + unsigned int i; + + for (i = 0; i < chip->ngpio; i++, gpio++) { + lpi_gpio_dbg_show_one(s, NULL, chip, i, gpio); + seq_puts(s, "\n"); + } +} + +#else +#define lpi_gpio_dbg_show NULL +#endif + +static const struct gpio_chip lpi_gpio_template = { + .direction_input = lpi_gpio_direction_input, + .direction_output = lpi_gpio_direction_output, + .get = lpi_gpio_get, + .set = lpi_gpio_set, + .request = gpiochip_generic_request, + .free = gpiochip_generic_free, + .dbg_show = lpi_gpio_dbg_show, +}; + +static int lpi_get_lpass_core_hw_clk(struct device *dev, + struct lpi_gpio_state *state) +{ + struct clk *lpass_core_hw_vote = NULL; + int ret = 0; + + if (state->lpass_core_hw_vote == NULL) { + lpass_core_hw_vote = devm_clk_get(dev, "lpass_core_hw_vote"); + if (IS_ERR(lpass_core_hw_vote) || lpass_core_hw_vote == NULL) { + ret = PTR_ERR(lpass_core_hw_vote); + dev_dbg(dev, "%s: clk get %s failed %d\n", + __func__, "lpass_core_hw_vote", ret); + return ret; + } + state->lpass_core_hw_vote = lpass_core_hw_vote; + } + return 0; +} + +static int lpi_pinctrl_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct pinctrl_pin_desc *pindesc; + struct pinctrl_desc *pctrldesc; + struct lpi_gpio_pad *pad, *pads; + struct lpi_gpio_state *state; + int ret, npins, i; + char __iomem *lpi_base; + u32 reg; + + ret = of_property_read_u32(dev->of_node, "reg", ®); + if (ret < 0) { + dev_err(dev, "missing base address\n"); + return ret; + } + + ret = of_property_read_u32(dev->of_node, "qcom,num-gpios", &npins); + if (ret < 0) + return ret; + + WARN_ON(npins > ARRAY_SIZE(lpi_gpio_groups)); + + ret = of_property_read_u32_array(dev->of_node, "qcom,lpi-offset-tbl", + lpi_offset, npins); + if (ret < 0) { + dev_err(dev, "error in reading lpi offset table: %d\n", ret); + return ret; + } + + state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); + if (!state) + return -ENOMEM; + + platform_set_drvdata(pdev, state); + + state->dev = &pdev->dev; + + pindesc = devm_kcalloc(dev, npins, sizeof(*pindesc), GFP_KERNEL); + if (!pindesc) + return -ENOMEM; + + pads = devm_kcalloc(dev, npins, sizeof(*pads), GFP_KERNEL); + if (!pads) + return -ENOMEM; + + pctrldesc = devm_kzalloc(dev, sizeof(*pctrldesc), GFP_KERNEL); + if (!pctrldesc) + return -ENOMEM; + + pctrldesc->pctlops = &lpi_gpio_pinctrl_ops; + pctrldesc->pmxops = &lpi_gpio_pinmux_ops; + pctrldesc->confops = &lpi_gpio_pinconf_ops; + pctrldesc->owner = THIS_MODULE; + pctrldesc->name = dev_name(dev); + pctrldesc->pins = pindesc; + pctrldesc->npins = npins; + + lpi_base = devm_ioremap(dev, reg, LPI_ADDRESS_SIZE); + if (lpi_base == NULL) { + dev_err(dev, "%s devm_ioremap failed\n", __func__); + return -ENOMEM; + } + + state->base = lpi_base; + + for (i = 0; i < npins; i++, pindesc++) { + pad = &pads[i]; + pindesc->drv_data = pad; + pindesc->number = i; + pindesc->name = lpi_gpio_groups[i]; + + pad->base = lpi_base; + pad->offset = lpi_offset[i]; + } + + state->chip = lpi_gpio_template; + state->chip.parent = dev; + state->chip.base = -1; + state->chip.ngpio = npins; + state->chip.label = dev_name(dev); + state->chip.of_gpio_n_cells = 2; + state->chip.can_sleep = false; + + state->ctrl = devm_pinctrl_register(dev, pctrldesc, state); + if (IS_ERR(state->ctrl)) + return PTR_ERR(state->ctrl); + + ret = gpiochip_add_data(&state->chip, state); + if (ret) { + dev_err(state->dev, "can't add gpio chip\n"); + goto err_chip; + } + + ret = gpiochip_add_pin_range(&state->chip, dev_name(dev), 0, 0, npins); + if (ret) { + dev_err(dev, "failed to add pin range\n"); + goto err_range; + } + + lpi_dev = &pdev->dev; + lpi_dev_up = true; + ret = audio_notifier_register("lpi_tlmm", AUDIO_NOTIFIER_ADSP_DOMAIN, + &service_nb); + if (ret < 0) { + pr_err("%s: Audio notifier register failed ret = %d\n", + __func__, ret); + goto err_range; + } + + ret = snd_event_client_register(dev, &lpi_pinctrl_ssr_ops, NULL); + if (!ret) { + snd_event_notify(dev, SND_EVENT_UP); + } else { + dev_err(dev, "%s: snd_event registration failed, ret [%d]\n", + __func__, ret); + goto err_snd_evt; + } + + /* Register LPASS core hw vote */ + ret = lpi_get_lpass_core_hw_clk(dev, state); + if (ret) + dev_dbg(dev, "%s: unable to get core clk handle %d\n", + __func__, ret); + + state->core_hw_vote_status = false; + pm_runtime_set_autosuspend_delay(&pdev->dev, LPI_AUTO_SUSPEND_DELAY); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + return 0; + +err_snd_evt: + audio_notifier_deregister("lpi_tlmm"); +err_range: + gpiochip_remove(&state->chip); +err_chip: + return ret; +} + +static int lpi_pinctrl_remove(struct platform_device *pdev) +{ + struct lpi_gpio_state *state = platform_get_drvdata(pdev); + + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + + snd_event_client_deregister(&pdev->dev); + audio_notifier_deregister("lpi_tlmm"); + gpiochip_remove(&state->chip); + return 0; +} + +static const struct of_device_id lpi_pinctrl_of_match[] = { + { .compatible = "qcom,lpi-pinctrl" }, /* Generic */ + { }, +}; + +MODULE_DEVICE_TABLE(of, lpi_pinctrl_of_match); + +static int lpi_pinctrl_runtime_resume(struct device *dev) +{ + struct lpi_gpio_state *state = dev_get_drvdata(dev); + int ret = 0; + + ret = lpi_get_lpass_core_hw_clk(dev, state); + if (ret) { + dev_err(dev, "%s: unable to get core clk handle %d\n", + __func__, ret); + return 0; + } + + ret = clk_prepare_enable(state->lpass_core_hw_vote); + if (ret < 0) + dev_err(dev, "%s: lpass core hw enable failed\n", + __func__); + else + state->core_hw_vote_status = true; + + pm_runtime_set_autosuspend_delay(dev, LPI_AUTO_SUSPEND_DELAY); + return 0; +} + +static int lpi_pinctrl_runtime_suspend(struct device *dev) +{ + struct lpi_gpio_state *state = dev_get_drvdata(dev); + int ret = 0; + + ret = lpi_get_lpass_core_hw_clk(dev, state); + if (ret) { + dev_err(dev, "%s: unable to get core clk handle %d\n", + __func__, ret); + return 0; + } + + if (state->core_hw_vote_status) { + clk_disable_unprepare(state->lpass_core_hw_vote); + state->core_hw_vote_status = false; + } + return 0; +} + +int lpi_pinctrl_suspend(struct device *dev) +{ + int ret = 0; + + dev_dbg(dev, "%s: system suspend\n", __func__); + + if ((!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev))) { + ret = lpi_pinctrl_runtime_suspend(dev); + if (!ret) { + /* + * Synchronize runtime-pm and system-pm states: + * At this point, we are already suspended. If + * runtime-pm still thinks its active, then + * make sure its status is in sync with HW + * status. The three below calls let the + * runtime-pm know that we are suspended + * already without re-invoking the suspend + * callback + */ + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + pm_runtime_enable(dev); + } + } + + return ret; +} + +int lpi_pinctrl_resume(struct device *dev) +{ + return 0; +} + +static const struct dev_pm_ops lpi_pinctrl_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS( + lpi_pinctrl_suspend, + lpi_pinctrl_resume + ) + SET_RUNTIME_PM_OPS( + lpi_pinctrl_runtime_suspend, + lpi_pinctrl_runtime_resume, + NULL + ) +}; + +static struct platform_driver lpi_pinctrl_driver = { + .driver = { + .name = "qcom-lpi-pinctrl", + .pm = &lpi_pinctrl_dev_pm_ops, + .of_match_table = lpi_pinctrl_of_match, + }, + .probe = lpi_pinctrl_probe, + .remove = lpi_pinctrl_remove, +}; + +module_platform_driver(lpi_pinctrl_driver); + +MODULE_DESCRIPTION("QTI LPI GPIO pin control driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From d11d6f06c9a5bc64aabec05e8f0d8006aa48f3d6 Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Wed, 27 May 2020 17:25:12 +0530 Subject: [PATCH 1561/1645] ASoC: sdm660 audio changes Enable compilation for sdm660 target. Bring in sdm660_cdc codec driver. Bring in sdm660 machine driver. Update codec driver to component driver to align with kernel-4.19 ALSA. Change-Id: I927a032d077bcce6b3dcc4a95445e8b1e86d461a Signed-off-by: Soumya Managoli --- Android.mk | 12 + Makefile | 1 - Makefile.am | 6 +- asoc/Android.mk | 7 +- asoc/Kbuild | 29 + asoc/codecs/Android.mk | 8 +- asoc/codecs/Kbuild | 6 + asoc/codecs/msm_sdw/Android.mk | 50 + asoc/codecs/msm_sdw/Kbuild | 109 + asoc/codecs/msm_sdw/msm-sdw-tables.c | 312 + asoc/codecs/msm_sdw/msm_sdw.h | 201 + asoc/codecs/msm_sdw/msm_sdw_cdc.c | 2142 +++++++ asoc/codecs/msm_sdw/msm_sdw_cdc_utils.c | 204 + asoc/codecs/msm_sdw/msm_sdw_registers.h | 119 + asoc/codecs/msm_sdw/msm_sdw_regmap.c | 154 + asoc/codecs/sdm660_cdc/Android.mk | 53 + asoc/codecs/sdm660_cdc/Kbuild | 115 + .../codecs/sdm660_cdc/msm-analog-cdc-regmap.h | 178 + asoc/codecs/sdm660_cdc/msm-analog-cdc.c | 4778 ++++++++++++++ asoc/codecs/sdm660_cdc/msm-analog-cdc.h | 269 + asoc/codecs/sdm660_cdc/msm-cdc-common.h | 60 + .../sdm660_cdc/msm-digital-cdc-regmap.c | 444 ++ asoc/codecs/sdm660_cdc/msm-digital-cdc.c | 2238 +++++++ asoc/codecs/sdm660_cdc/msm-digital-cdc.h | 110 + asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c | 411 ++ asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h | 28 + asoc/codecs/sdm660_cdc/sdm660-cdc-registers.h | 596 ++ asoc/codecs/wcd9335-regmap.c | 4 +- asoc/codecs/wcd934x/Android.mk | 6 +- asoc/codecs/wcd934x/Kbuild | 5 + asoc/codecs/wcd934x/wcd934x.c | 4 +- asoc/codecs/wcd9xxx-utils.h | 6 +- asoc/msm-cpe-lsm.c | 4 +- asoc/sdm660-common.c | 5583 +++++++++++++++++ asoc/sdm660-ext-dai-links.c | 1992 ++++++ asoc/sdm660-external.c | 1984 ++++++ asoc/sdm660-internal.c | 3206 ++++++++++ config/sdm660auto.conf | 3 +- config/sdm660autoconf.h | 3 +- dsp/codecs/Android.mk | 6 +- dsp/codecs/Kbuild | 5 + include/asoc/sdm660-common.h | 147 + include/asoc/sdm660-external.h | 49 + include/asoc/sdm660-internal.h | 25 + 44 files changed, 25652 insertions(+), 20 deletions(-) create mode 100644 asoc/codecs/msm_sdw/Android.mk create mode 100644 asoc/codecs/msm_sdw/Kbuild create mode 100644 asoc/codecs/msm_sdw/msm-sdw-tables.c create mode 100644 asoc/codecs/msm_sdw/msm_sdw.h create mode 100644 asoc/codecs/msm_sdw/msm_sdw_cdc.c create mode 100644 asoc/codecs/msm_sdw/msm_sdw_cdc_utils.c create mode 100644 asoc/codecs/msm_sdw/msm_sdw_registers.h create mode 100644 asoc/codecs/msm_sdw/msm_sdw_regmap.c create mode 100644 asoc/codecs/sdm660_cdc/Android.mk create mode 100644 asoc/codecs/sdm660_cdc/Kbuild create mode 100644 asoc/codecs/sdm660_cdc/msm-analog-cdc-regmap.h create mode 100644 asoc/codecs/sdm660_cdc/msm-analog-cdc.c create mode 100644 asoc/codecs/sdm660_cdc/msm-analog-cdc.h create mode 100644 asoc/codecs/sdm660_cdc/msm-cdc-common.h create mode 100644 asoc/codecs/sdm660_cdc/msm-digital-cdc-regmap.c create mode 100644 asoc/codecs/sdm660_cdc/msm-digital-cdc.c create mode 100644 asoc/codecs/sdm660_cdc/msm-digital-cdc.h create mode 100644 asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c create mode 100644 asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h create mode 100644 asoc/codecs/sdm660_cdc/sdm660-cdc-registers.h create mode 100644 asoc/sdm660-common.c create mode 100644 asoc/sdm660-ext-dai-links.c create mode 100644 asoc/sdm660-external.c create mode 100644 asoc/sdm660-internal.c create mode 100644 include/asoc/sdm660-common.h create mode 100644 include/asoc/sdm660-external.h create mode 100644 include/asoc/sdm660-internal.h diff --git a/Android.mk b/Android.mk index 581d0968802c..9b875d9701dd 100644 --- a/Android.mk +++ b/Android.mk @@ -31,6 +31,11 @@ include $(MY_LOCAL_PATH)/soc/Android.mk endif endif +ifeq ($(call is-board-platform-in-list,sdm660),true) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers) +include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk +endif + ifeq ($(call is-board-platform-in-list,msmnile sdmshrike),true) ifneq ($(TARGET_BOARD_AUTO),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/aqt1000/Module.symvers) @@ -65,3 +70,10 @@ ifeq ($(call is-board-platform-in-list, lito),true) $(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wsa883x/Module.symvers) include $(MY_LOCAL_PATH)/asoc/codecs/wsa883x/Android.mk endif + +ifeq ($(call is-board-platform-in-list, sdm660),true) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers) +$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers) +include $(MY_LOCAL_PATH)/asoc/codecs/sdm660_cdc/Android.mk +include $(MY_LOCAL_PATH)/asoc/codecs/msm_sdw/Android.mk +endif diff --git a/Makefile b/Makefile index a858349a6b86..e66fd39dd646 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,6 @@ ifeq ($(CONFIG_ARCH_SDM660), y) LINUXINCLUDE += \ -include $(srctree)/techpack/audio/config/sdm660autoconf.h endif - obj-y += soc/ obj-y += dsp/ obj-y += ipc/ diff --git a/Makefile.am b/Makefile.am index 3a0e7f678f0a..b5f37d28bf74 100644 --- a/Makefile.am +++ b/Makefile.am @@ -27,7 +27,7 @@ obj-m += dsp/codecs/ obj-m += soc/ obj-m += asoc/ obj-m += asoc/codecs/ -ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sdmsteppe)) +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sdmsteppe, sdm660)) obj-m += asoc/codecs/wcd934x/ endif ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), qcs40x)) @@ -45,6 +45,10 @@ obj-m += asoc/codecs/bolero/ obj-m += asoc/codecs/wcd938x/ endif +ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sdm660)) +obj-m += asoc/codecs/sdm660_cdc/ +endif + ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sa8155 sa8155ivi sa6155 sa8195 qtiquingvm)) obj-m := ipc/ obj-m += dsp/ diff --git a/asoc/Android.mk b/asoc/Android.mk index 4ce1fa77d4ab..c6e5a354f0ca 100644 --- a/asoc/Android.mk +++ b/asoc/Android.mk @@ -41,9 +41,14 @@ TARGET := bengal AUDIO_SELECT := CONFIG_SND_SOC_BENGAL=m endif +ifeq ($(call is-board-platform,sdm660),true) +TARGET := sdm660 +AUDIO_SELECT := CONFIG_SND_SOC_SDM660=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike sdm660),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/Kbuild b/asoc/Kbuild index 137fd60f8841..a0d8de1f66e7 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -76,6 +76,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h endif + ifeq ($(CONFIG_ARCH_SDM660), y) + include $(AUDIO_ROOT)/config/sdm660auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h + endif endif # As per target team, build is done as follows: @@ -145,6 +150,22 @@ ifdef CONFIG_SND_SOC_SA8155 MACHINE_OBJS += sa8155.o endif +# for SDM6xx sound card driver +ifdef CONFIG_SND_SOC_SDM660 + MACHINE_OBJS += sdm660-common.o +endif + +# for SDM6xx sound card driver +ifdef CONFIG_SND_SOC_INT_CODEC + MACHINE_OBJS += sdm660-internal.o +endif + +# for SDM6xx sound card driver +ifdef CONFIG_SND_SOC_EXT_CODEC + MACHINE_OBJS += sdm660-external.o + MACHINE_OBJS += sdm660-ext-dai-links.o +endif + ifdef CONFIG_SND_SOC_CPE CPE_LSM_OBJS += msm-cpe-lsm.o endif @@ -223,6 +244,8 @@ KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd937x/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers endif ifeq ($(KERNEL_BUILD), 1) obj-y += codecs/ @@ -255,6 +278,12 @@ machine_dlkm-y := $(MACHINE_OBJS) obj-$(CONFIG_SND_SOC_SA8155) += machine_dlkm.o machine_dlkm-y := $(MACHINE_OBJS) +obj-$(CONFIG_SND_SOC_EXT_CODEC) += machine_dlkm.o +machine_dlkm-y := $(MACHINE_OBJS) + +obj-$(CONFIG_SND_SOC_INT_CODEC) += machine_dlkm.o +machine_dlkm-y := $(MACHINE_OBJS) + obj-$(CONFIG_SND_SOC_CPE) += cpe_lsm_dlkm.o cpe_lsm_dlkm-y := $(CPE_LSM_OBJS) diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk index 5e3114e479f6..7fb175426afd 100644 --- a/asoc/codecs/Android.mk +++ b/asoc/codecs/Android.mk @@ -35,9 +35,13 @@ ifeq ($(call is-board-platform,bengal),true) AUDIO_SELECT := CONFIG_SND_SOC_BENGAL=m endif +ifeq ($(call is-board-platform,sdm660),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM660=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike sdm660),true) LOCAL_PATH := $(call my-dir) @@ -101,7 +105,7 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) include $(DLKM_DIR)/AndroidKernelModule.mk endif ########################################################### -ifeq ($(call is-board-platform-in-list, ),true) +ifeq ($(call is-board-platform-in-list, sdm660),true) include $(CLEAR_VARS) LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd9335.ko LOCAL_MODULE_KBUILD_NAME := wcd9335_dlkm.ko diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 5ab7c3b8ba11..6dc444290245 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -70,6 +70,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h endif + ifeq ($(CONFIG_ARCH_SDM660), y) + include $(AUDIO_ROOT)/config/sdm660auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h + endif endif # As per target team, build is done as follows: @@ -228,6 +233,7 @@ ifeq ($(KERNEL_BUILD), 1) obj-y += bolero/ obj-y += rouleur/ obj-y += wsa883x/ + obj-y += sdm660_cdc/ endif # Module information used by KBuild framework obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd_core_dlkm.o diff --git a/asoc/codecs/msm_sdw/Android.mk b/asoc/codecs/msm_sdw/Android.mk new file mode 100644 index 000000000000..b975298c3461 --- /dev/null +++ b/asoc/codecs/msm_sdw/Android.mk @@ -0,0 +1,50 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target + +ifeq ($(call is-board-platform,sdm660),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM660=m +endif + +ifeq ($(call is-board-platform-in-list, sdm660),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=msm_sdw_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_msm_sdw.ko +LOCAL_MODULE_KBUILD_NAME := msm_sdw_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/asoc/codecs/msm_sdw/Kbuild b/asoc/codecs/msm_sdw/Kbuild new file mode 100644 index 000000000000..ccd515d085eb --- /dev/null +++ b/asoc/codecs/msm_sdw/Kbuild @@ -0,0 +1,109 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + + +ifeq ($(KERNEL_BUILD), 1) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.19 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) + ifeq ($(CONFIG_ARCH_SDM660), y) + include $(AUDIO_ROOT)/config/sdm660auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h + endif +endif + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ MSM Soundwire ############ + +# for MSM Soundwire Codec +ifdef CONFIG_SND_SOC_MSM_SDW + MSM_SDW_OBJS += msm_sdw_cdc.o + MSM_SDW_OBJS += msm_sdw_regmap.o + MSM_SDW_OBJS += msm-sdw-tables.o + MSM_SDW_OBJS += msm_sdw_cdc_utils.o +endif + +LINUX_INC += -Iinclude/linux + +INCS += $(COMMON_INC) \ + $(UAPI_INC) + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + +ifeq ($(KERNEL_BUILD), 0) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + +ifeq ($(CONFIG_SND_SOC_GCOV), y) +GCOV_PROFILE := y +endif + +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_MSM_SDW) += msm_sdw_dlkm.o +msm_sdw_dlkm-y := $(MSM_SDW_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/msm_sdw/msm-sdw-tables.c b/asoc/codecs/msm_sdw/msm-sdw-tables.c new file mode 100644 index 000000000000..a332c5b0a232 --- /dev/null +++ b/asoc/codecs/msm_sdw/msm-sdw-tables.c @@ -0,0 +1,312 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2016-2017, 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include "msm_sdw.h" + +const u8 msm_sdw_page_map[MSM_SDW_MAX_REGISTER] = { + [MSM_SDW_TX9_SPKR_PROT_PATH_CTL] = 0xa, + [MSM_SDW_TX9_SPKR_PROT_PATH_CFG0] = 0xa, + [MSM_SDW_TX10_SPKR_PROT_PATH_CTL] = 0xa, + [MSM_SDW_TX10_SPKR_PROT_PATH_CFG0] = 0xa, + [MSM_SDW_TX11_SPKR_PROT_PATH_CTL] = 0xa, + [MSM_SDW_TX11_SPKR_PROT_PATH_CFG0] = 0xa, + [MSM_SDW_TX12_SPKR_PROT_PATH_CTL] = 0xa, + [MSM_SDW_TX12_SPKR_PROT_PATH_CFG0] = 0xa, + [MSM_SDW_COMPANDER7_CTL0] = 0xb, + [MSM_SDW_COMPANDER7_CTL1] = 0xb, + [MSM_SDW_COMPANDER7_CTL2] = 0xb, + [MSM_SDW_COMPANDER7_CTL3] = 0xb, + [MSM_SDW_COMPANDER7_CTL4] = 0xb, + [MSM_SDW_COMPANDER7_CTL5] = 0xb, + [MSM_SDW_COMPANDER7_CTL6] = 0xb, + [MSM_SDW_COMPANDER7_CTL7] = 0xb, + [MSM_SDW_COMPANDER8_CTL0] = 0xb, + [MSM_SDW_COMPANDER8_CTL1] = 0xb, + [MSM_SDW_COMPANDER8_CTL2] = 0xb, + [MSM_SDW_COMPANDER8_CTL3] = 0xb, + [MSM_SDW_COMPANDER8_CTL4] = 0xb, + [MSM_SDW_COMPANDER8_CTL5] = 0xb, + [MSM_SDW_COMPANDER8_CTL6] = 0xb, + [MSM_SDW_COMPANDER8_CTL7] = 0xb, + [MSM_SDW_RX7_RX_PATH_CTL] = 0xb, + [MSM_SDW_RX7_RX_PATH_CFG0] = 0xb, + [MSM_SDW_RX7_RX_PATH_CFG1] = 0xb, + [MSM_SDW_RX7_RX_PATH_CFG2] = 0xb, + [MSM_SDW_RX7_RX_VOL_CTL] = 0xb, + [MSM_SDW_RX7_RX_PATH_MIX_CTL] = 0xb, + [MSM_SDW_RX7_RX_PATH_MIX_CFG] = 0xb, + [MSM_SDW_RX7_RX_VOL_MIX_CTL] = 0xb, + [MSM_SDW_RX7_RX_PATH_SEC0] = 0xb, + [MSM_SDW_RX7_RX_PATH_SEC1] = 0xb, + [MSM_SDW_RX7_RX_PATH_SEC2] = 0xb, + [MSM_SDW_RX7_RX_PATH_SEC3] = 0xb, + [MSM_SDW_RX7_RX_PATH_SEC5] = 0xb, + [MSM_SDW_RX7_RX_PATH_SEC6] = 0xb, + [MSM_SDW_RX7_RX_PATH_SEC7] = 0xb, + [MSM_SDW_RX7_RX_PATH_MIX_SEC0] = 0xb, + [MSM_SDW_RX7_RX_PATH_MIX_SEC1] = 0xb, + [MSM_SDW_RX8_RX_PATH_CTL] = 0xb, + [MSM_SDW_RX8_RX_PATH_CFG0] = 0xb, + [MSM_SDW_RX8_RX_PATH_CFG1] = 0xb, + [MSM_SDW_RX8_RX_PATH_CFG2] = 0xb, + [MSM_SDW_RX8_RX_VOL_CTL] = 0xb, + [MSM_SDW_RX8_RX_PATH_MIX_CTL] = 0xb, + [MSM_SDW_RX8_RX_PATH_MIX_CFG] = 0xb, + [MSM_SDW_RX8_RX_VOL_MIX_CTL] = 0xb, + [MSM_SDW_RX8_RX_PATH_SEC0] = 0xb, + [MSM_SDW_RX8_RX_PATH_SEC1] = 0xb, + [MSM_SDW_RX8_RX_PATH_SEC2] = 0xb, + [MSM_SDW_RX8_RX_PATH_SEC3] = 0xb, + [MSM_SDW_RX8_RX_PATH_SEC5] = 0xb, + [MSM_SDW_RX8_RX_PATH_SEC6] = 0xb, + [MSM_SDW_RX8_RX_PATH_SEC7] = 0xb, + [MSM_SDW_RX8_RX_PATH_MIX_SEC0] = 0xb, + [MSM_SDW_RX8_RX_PATH_MIX_SEC1] = 0xb, + [MSM_SDW_BOOST0_BOOST_PATH_CTL] = 0xc, + [MSM_SDW_BOOST0_BOOST_CTL] = 0xc, + [MSM_SDW_BOOST0_BOOST_CFG1] = 0xc, + [MSM_SDW_BOOST0_BOOST_CFG2] = 0xc, + [MSM_SDW_BOOST1_BOOST_PATH_CTL] = 0xc, + [MSM_SDW_BOOST1_BOOST_CTL] = 0xc, + [MSM_SDW_BOOST1_BOOST_CFG1] = 0xc, + [MSM_SDW_BOOST1_BOOST_CFG2] = 0xc, + [MSM_SDW_AHB_BRIDGE_WR_DATA_0] = 0xc, + [MSM_SDW_AHB_BRIDGE_WR_DATA_1] = 0xc, + [MSM_SDW_AHB_BRIDGE_WR_DATA_2] = 0xc, + [MSM_SDW_AHB_BRIDGE_WR_DATA_3] = 0xc, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_0] = 0xc, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_1] = 0xc, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_2] = 0xc, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_3] = 0xc, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_0] = 0xc, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_1] = 0xc, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_2] = 0xc, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_3] = 0xc, + [MSM_SDW_AHB_BRIDGE_RD_DATA_0] = 0xc, + [MSM_SDW_AHB_BRIDGE_RD_DATA_1] = 0xc, + [MSM_SDW_AHB_BRIDGE_RD_DATA_2] = 0xc, + [MSM_SDW_AHB_BRIDGE_RD_DATA_3] = 0xc, + [MSM_SDW_AHB_BRIDGE_ACCESS_CFG] = 0xc, + [MSM_SDW_AHB_BRIDGE_ACCESS_STATUS] = 0xc, + [MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL] = 0xd, + [MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL] = 0xd, + [MSM_SDW_CLK_RST_CTRL_SWR_CONTROL] = 0xd, + [MSM_SDW_TOP_TOP_CFG0] = 0xd, + [MSM_SDW_TOP_TOP_CFG1] = 0xd, + [MSM_SDW_TOP_RX_I2S_CTL] = 0xd, + [MSM_SDW_TOP_TX_I2S_CTL] = 0xd, + [MSM_SDW_TOP_I2S_CLK] = 0xd, + [MSM_SDW_TOP_RX7_PATH_INPUT0_MUX] = 0xd, + [MSM_SDW_TOP_RX7_PATH_INPUT1_MUX] = 0xd, + [MSM_SDW_TOP_RX8_PATH_INPUT0_MUX] = 0xd, + [MSM_SDW_TOP_RX8_PATH_INPUT1_MUX] = 0xd, + [MSM_SDW_TOP_FREQ_MCLK] = 0xd, + [MSM_SDW_TOP_DEBUG_BUS_SEL] = 0xd, + [MSM_SDW_TOP_DEBUG_EN] = 0xd, + [MSM_SDW_TOP_I2S_RESET] = 0xd, + [MSM_SDW_TOP_BLOCKS_RESET] = 0xd, +}; + +const u8 msm_sdw_reg_readable[MSM_SDW_MAX_REGISTER] = { + [MSM_SDW_PAGE_REGISTER] = 1, + [MSM_SDW_TX9_SPKR_PROT_PATH_CTL] = 1, + [MSM_SDW_TX9_SPKR_PROT_PATH_CFG0] = 1, + [MSM_SDW_TX10_SPKR_PROT_PATH_CTL] = 1, + [MSM_SDW_TX10_SPKR_PROT_PATH_CFG0] = 1, + [MSM_SDW_TX11_SPKR_PROT_PATH_CTL] = 1, + [MSM_SDW_TX11_SPKR_PROT_PATH_CFG0] = 1, + [MSM_SDW_TX12_SPKR_PROT_PATH_CTL] = 1, + [MSM_SDW_TX12_SPKR_PROT_PATH_CFG0] = 1, + [MSM_SDW_COMPANDER7_CTL0] = 1, + [MSM_SDW_COMPANDER7_CTL1] = 1, + [MSM_SDW_COMPANDER7_CTL2] = 1, + [MSM_SDW_COMPANDER7_CTL3] = 1, + [MSM_SDW_COMPANDER7_CTL4] = 1, + [MSM_SDW_COMPANDER7_CTL5] = 1, + [MSM_SDW_COMPANDER7_CTL6] = 1, + [MSM_SDW_COMPANDER7_CTL7] = 1, + [MSM_SDW_COMPANDER8_CTL0] = 1, + [MSM_SDW_COMPANDER8_CTL1] = 1, + [MSM_SDW_COMPANDER8_CTL2] = 1, + [MSM_SDW_COMPANDER8_CTL3] = 1, + [MSM_SDW_COMPANDER8_CTL4] = 1, + [MSM_SDW_COMPANDER8_CTL5] = 1, + [MSM_SDW_COMPANDER8_CTL6] = 1, + [MSM_SDW_COMPANDER8_CTL7] = 1, + [MSM_SDW_RX7_RX_PATH_CTL] = 1, + [MSM_SDW_RX7_RX_PATH_CFG0] = 1, + [MSM_SDW_RX7_RX_PATH_CFG1] = 1, + [MSM_SDW_RX7_RX_PATH_CFG2] = 1, + [MSM_SDW_RX7_RX_VOL_CTL] = 1, + [MSM_SDW_RX7_RX_PATH_MIX_CTL] = 1, + [MSM_SDW_RX7_RX_PATH_MIX_CFG] = 1, + [MSM_SDW_RX7_RX_VOL_MIX_CTL] = 1, + [MSM_SDW_RX7_RX_PATH_SEC0] = 1, + [MSM_SDW_RX7_RX_PATH_SEC1] = 1, + [MSM_SDW_RX7_RX_PATH_SEC2] = 1, + [MSM_SDW_RX7_RX_PATH_SEC3] = 1, + [MSM_SDW_RX7_RX_PATH_SEC5] = 1, + [MSM_SDW_RX7_RX_PATH_SEC6] = 1, + [MSM_SDW_RX7_RX_PATH_SEC7] = 1, + [MSM_SDW_RX7_RX_PATH_MIX_SEC0] = 1, + [MSM_SDW_RX7_RX_PATH_MIX_SEC1] = 1, + [MSM_SDW_RX8_RX_PATH_CTL] = 1, + [MSM_SDW_RX8_RX_PATH_CFG0] = 1, + [MSM_SDW_RX8_RX_PATH_CFG1] = 1, + [MSM_SDW_RX8_RX_PATH_CFG2] = 1, + [MSM_SDW_RX8_RX_VOL_CTL] = 1, + [MSM_SDW_RX8_RX_PATH_MIX_CTL] = 1, + [MSM_SDW_RX8_RX_PATH_MIX_CFG] = 1, + [MSM_SDW_RX8_RX_VOL_MIX_CTL] = 1, + [MSM_SDW_RX8_RX_PATH_SEC0] = 1, + [MSM_SDW_RX8_RX_PATH_SEC1] = 1, + [MSM_SDW_RX8_RX_PATH_SEC2] = 1, + [MSM_SDW_RX8_RX_PATH_SEC3] = 1, + [MSM_SDW_RX8_RX_PATH_SEC5] = 1, + [MSM_SDW_RX8_RX_PATH_SEC6] = 1, + [MSM_SDW_RX8_RX_PATH_SEC7] = 1, + [MSM_SDW_RX8_RX_PATH_MIX_SEC0] = 1, + [MSM_SDW_RX8_RX_PATH_MIX_SEC1] = 1, + [MSM_SDW_BOOST0_BOOST_PATH_CTL] = 1, + [MSM_SDW_BOOST0_BOOST_CTL] = 1, + [MSM_SDW_BOOST0_BOOST_CFG1] = 1, + [MSM_SDW_BOOST0_BOOST_CFG2] = 1, + [MSM_SDW_BOOST1_BOOST_PATH_CTL] = 1, + [MSM_SDW_BOOST1_BOOST_CTL] = 1, + [MSM_SDW_BOOST1_BOOST_CFG1] = 1, + [MSM_SDW_BOOST1_BOOST_CFG2] = 1, + [MSM_SDW_AHB_BRIDGE_WR_DATA_0] = 1, + [MSM_SDW_AHB_BRIDGE_WR_DATA_1] = 1, + [MSM_SDW_AHB_BRIDGE_WR_DATA_2] = 1, + [MSM_SDW_AHB_BRIDGE_WR_DATA_3] = 1, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_0] = 1, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_1] = 1, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_2] = 1, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_3] = 1, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_0] = 1, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_1] = 1, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_2] = 1, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_3] = 1, + [MSM_SDW_AHB_BRIDGE_RD_DATA_0] = 1, + [MSM_SDW_AHB_BRIDGE_RD_DATA_1] = 1, + [MSM_SDW_AHB_BRIDGE_RD_DATA_2] = 1, + [MSM_SDW_AHB_BRIDGE_RD_DATA_3] = 1, + [MSM_SDW_AHB_BRIDGE_ACCESS_CFG] = 1, + [MSM_SDW_AHB_BRIDGE_ACCESS_STATUS] = 1, + [MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL] = 1, + [MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL] = 1, + [MSM_SDW_CLK_RST_CTRL_SWR_CONTROL] = 1, + [MSM_SDW_TOP_TOP_CFG0] = 1, + [MSM_SDW_TOP_TOP_CFG1] = 1, + [MSM_SDW_TOP_RX_I2S_CTL] = 1, + [MSM_SDW_TOP_TX_I2S_CTL] = 1, + [MSM_SDW_TOP_RX7_PATH_INPUT0_MUX] = 1, + [MSM_SDW_TOP_RX7_PATH_INPUT1_MUX] = 1, + [MSM_SDW_TOP_RX8_PATH_INPUT0_MUX] = 1, + [MSM_SDW_TOP_RX8_PATH_INPUT1_MUX] = 1, + [MSM_SDW_TOP_FREQ_MCLK] = 1, + [MSM_SDW_TOP_DEBUG_BUS_SEL] = 1, + [MSM_SDW_TOP_DEBUG_EN] = 1, + [MSM_SDW_TOP_I2S_RESET] = 1, + [MSM_SDW_TOP_BLOCKS_RESET] = 1, +}; + +const u8 msm_sdw_reg_writeable[MSM_SDW_MAX_REGISTER] = { + [MSM_SDW_PAGE_REGISTER] = 1, + [MSM_SDW_TX9_SPKR_PROT_PATH_CTL] = 1, + [MSM_SDW_TX9_SPKR_PROT_PATH_CFG0] = 1, + [MSM_SDW_TX10_SPKR_PROT_PATH_CTL] = 1, + [MSM_SDW_TX10_SPKR_PROT_PATH_CFG0] = 1, + [MSM_SDW_TX11_SPKR_PROT_PATH_CTL] = 1, + [MSM_SDW_TX11_SPKR_PROT_PATH_CFG0] = 1, + [MSM_SDW_TX12_SPKR_PROT_PATH_CTL] = 1, + [MSM_SDW_TX12_SPKR_PROT_PATH_CFG0] = 1, + [MSM_SDW_COMPANDER7_CTL0] = 1, + [MSM_SDW_COMPANDER7_CTL1] = 1, + [MSM_SDW_COMPANDER7_CTL2] = 1, + [MSM_SDW_COMPANDER7_CTL3] = 1, + [MSM_SDW_COMPANDER7_CTL4] = 1, + [MSM_SDW_COMPANDER7_CTL5] = 1, + [MSM_SDW_COMPANDER7_CTL7] = 1, + [MSM_SDW_COMPANDER8_CTL0] = 1, + [MSM_SDW_COMPANDER8_CTL1] = 1, + [MSM_SDW_COMPANDER8_CTL2] = 1, + [MSM_SDW_COMPANDER8_CTL3] = 1, + [MSM_SDW_COMPANDER8_CTL4] = 1, + [MSM_SDW_COMPANDER8_CTL5] = 1, + [MSM_SDW_COMPANDER8_CTL7] = 1, + [MSM_SDW_RX7_RX_PATH_CTL] = 1, + [MSM_SDW_RX7_RX_PATH_CFG0] = 1, + [MSM_SDW_RX7_RX_PATH_CFG1] = 1, + [MSM_SDW_RX7_RX_PATH_CFG2] = 1, + [MSM_SDW_RX7_RX_VOL_CTL] = 1, + [MSM_SDW_RX7_RX_PATH_MIX_CTL] = 1, + [MSM_SDW_RX7_RX_PATH_MIX_CFG] = 1, + [MSM_SDW_RX7_RX_VOL_MIX_CTL] = 1, + [MSM_SDW_RX7_RX_PATH_SEC0] = 1, + [MSM_SDW_RX7_RX_PATH_SEC1] = 1, + [MSM_SDW_RX7_RX_PATH_SEC2] = 1, + [MSM_SDW_RX7_RX_PATH_SEC3] = 1, + [MSM_SDW_RX7_RX_PATH_SEC5] = 1, + [MSM_SDW_RX7_RX_PATH_SEC6] = 1, + [MSM_SDW_RX7_RX_PATH_SEC7] = 1, + [MSM_SDW_RX7_RX_PATH_MIX_SEC0] = 1, + [MSM_SDW_RX7_RX_PATH_MIX_SEC1] = 1, + [MSM_SDW_RX8_RX_PATH_CTL] = 1, + [MSM_SDW_RX8_RX_PATH_CFG0] = 1, + [MSM_SDW_RX8_RX_PATH_CFG1] = 1, + [MSM_SDW_RX8_RX_PATH_CFG2] = 1, + [MSM_SDW_RX8_RX_VOL_CTL] = 1, + [MSM_SDW_RX8_RX_PATH_MIX_CTL] = 1, + [MSM_SDW_RX8_RX_PATH_MIX_CFG] = 1, + [MSM_SDW_RX8_RX_VOL_MIX_CTL] = 1, + [MSM_SDW_RX8_RX_PATH_SEC0] = 1, + [MSM_SDW_RX8_RX_PATH_SEC1] = 1, + [MSM_SDW_RX8_RX_PATH_SEC2] = 1, + [MSM_SDW_RX8_RX_PATH_SEC3] = 1, + [MSM_SDW_RX8_RX_PATH_SEC5] = 1, + [MSM_SDW_RX8_RX_PATH_SEC6] = 1, + [MSM_SDW_RX8_RX_PATH_SEC7] = 1, + [MSM_SDW_RX8_RX_PATH_MIX_SEC0] = 1, + [MSM_SDW_RX8_RX_PATH_MIX_SEC1] = 1, + [MSM_SDW_BOOST0_BOOST_PATH_CTL] = 1, + [MSM_SDW_BOOST0_BOOST_CTL] = 1, + [MSM_SDW_BOOST0_BOOST_CFG1] = 1, + [MSM_SDW_BOOST0_BOOST_CFG2] = 1, + [MSM_SDW_BOOST1_BOOST_PATH_CTL] = 1, + [MSM_SDW_BOOST1_BOOST_CTL] = 1, + [MSM_SDW_BOOST1_BOOST_CFG1] = 1, + [MSM_SDW_BOOST1_BOOST_CFG2] = 1, + [MSM_SDW_AHB_BRIDGE_WR_DATA_0] = 1, + [MSM_SDW_AHB_BRIDGE_WR_DATA_1] = 1, + [MSM_SDW_AHB_BRIDGE_WR_DATA_2] = 1, + [MSM_SDW_AHB_BRIDGE_WR_DATA_3] = 1, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_0] = 1, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_1] = 1, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_2] = 1, + [MSM_SDW_AHB_BRIDGE_WR_ADDR_3] = 1, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_0] = 1, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_1] = 1, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_2] = 1, + [MSM_SDW_AHB_BRIDGE_RD_ADDR_3] = 1, + [MSM_SDW_AHB_BRIDGE_ACCESS_CFG] = 1, + [MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL] = 1, + [MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL] = 1, + [MSM_SDW_CLK_RST_CTRL_SWR_CONTROL] = 1, + [MSM_SDW_TOP_TOP_CFG0] = 1, + [MSM_SDW_TOP_TOP_CFG1] = 1, + [MSM_SDW_TOP_RX_I2S_CTL] = 1, + [MSM_SDW_TOP_TX_I2S_CTL] = 1, + [MSM_SDW_TOP_RX7_PATH_INPUT0_MUX] = 1, + [MSM_SDW_TOP_RX7_PATH_INPUT1_MUX] = 1, + [MSM_SDW_TOP_RX8_PATH_INPUT0_MUX] = 1, + [MSM_SDW_TOP_RX8_PATH_INPUT1_MUX] = 1, + [MSM_SDW_TOP_FREQ_MCLK] = 1, + [MSM_SDW_TOP_DEBUG_BUS_SEL] = 1, + [MSM_SDW_TOP_DEBUG_EN] = 1, + [MSM_SDW_TOP_I2S_RESET] = 1, + [MSM_SDW_TOP_BLOCKS_RESET] = 1, +}; diff --git a/asoc/codecs/msm_sdw/msm_sdw.h b/asoc/codecs/msm_sdw/msm_sdw.h new file mode 100644 index 000000000000..82cff87d6417 --- /dev/null +++ b/asoc/codecs/msm_sdw/msm_sdw.h @@ -0,0 +1,201 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. + */ +#ifndef MSM_SDW_H +#define MSM_SDW_H + +#include +#include +#include "msm_sdw_registers.h" + +#define MSM_SDW_MAX_REGISTER 0x400 +#define MSM_SDW_CHILD_DEVICES_MAX 1 + +extern const struct regmap_config msm_sdw_regmap_config; +extern const u8 msm_sdw_page_map[MSM_SDW_MAX_REGISTER]; +extern const u8 msm_sdw_reg_readable[MSM_SDW_MAX_REGISTER]; +extern const u8 msm_sdw_reg_writeable[MSM_SDW_MAX_REGISTER]; + +enum { + MSM_SDW_RX4 = 0, + MSM_SDW_RX5, + MSM_SDW_RX_MAX, +}; + +enum { + MSM_SDW_TX0 = 0, + MSM_SDW_TX1, + MSM_SDW_TX_MAX, +}; + +enum { + COMP1, /* SPK_L */ + COMP2, /* SPK_R */ + COMP_MAX +}; + +/* + * Structure used to update codec + * register defaults after reset + */ +struct msm_sdw_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + +/* + * Selects compander and smart boost settings + * for a given speaker mode + */ +enum { + SPKR_MODE_DEFAULT, + SPKR_MODE_1, /* COMP Gain = 12dB, Smartboost Max = 5.5V */ +}; + +/* Rx path gain offsets */ +enum { + RX_GAIN_OFFSET_M1P5_DB, + RX_GAIN_OFFSET_0_DB, +}; + +struct msm_sdw_reg_val { + unsigned short reg; /* register address */ + u8 *buf; /* buffer to be written to reg. addr */ + int bytes; /* number of bytes to be written */ +}; + +/* Hold instance to soundwire platform device */ +struct msm_sdw_ctrl_data { + struct platform_device *sdw_pdev; +}; + +struct wcd_sdw_ctrl_platform_data { + void *handle; /* holds codec private data */ + int (*read)(void *handle, int reg); + int (*write)(void *handle, int reg, int val); + int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len); + int (*clk)(void *handle, bool enable); + int (*handle_irq)(void *handle, + irqreturn_t (*swrm_irq_handler)(int irq, + void *data), + void *swrm_handle, + int action); +}; + +struct msm_sdw_priv { + struct device *dev; + struct mutex io_lock; + + int (*read_dev)(struct msm_sdw_priv *msm_sdw, unsigned short reg, + int bytes, void *dest); + int (*write_dev)(struct msm_sdw_priv *msm_sdw, unsigned short reg, + int bytes, void *src); + int (*multi_reg_write)(struct msm_sdw_priv *msm_sdw, const void *data, + size_t count); + struct snd_soc_component *component; + struct device_node *sdw_gpio_p; /* used by pinctrl API */ + /* SoundWire data structure */ + struct msm_sdw_ctrl_data *sdw_ctrl_data; + int nr; + + /* compander */ + int comp_enabled[COMP_MAX]; + int ear_spkr_gain; + + /* to track the status */ + unsigned long status_mask; + + struct work_struct msm_sdw_add_child_devices_work; + struct wcd_sdw_ctrl_platform_data sdw_plat_data; + + unsigned int vi_feed_value; + + struct mutex sdw_read_lock; + struct mutex sdw_write_lock; + struct mutex sdw_clk_lock; + int sdw_clk_users; + int sdw_mclk_users; + + int sdw_irq; + int int_mclk1_rsc_ref; + bool int_mclk1_enabled; + bool sdw_npl_clk_enabled; + struct mutex cdc_int_mclk1_mutex; + struct mutex sdw_npl_clk_mutex; + struct delayed_work disable_int_mclk1_work; + struct afe_clk_set sdw_cdc_core_clk; + struct afe_clk_set sdw_npl_clk; + struct notifier_block service_nb; + int (*sdw_cdc_gpio_fn)(bool enable, + struct snd_soc_component *component); + bool dev_up; + + int spkr_gain_offset; + int spkr_mode; + struct mutex codec_mutex; + int rx_4_count; + int rx_5_count; + u32 mclk_rate; + struct regmap *regmap; + + bool prev_pg_valid; + u8 prev_pg; + u32 sdw_base_addr; + char __iomem *sdw_base; + u32 version; + + /* Entry for version info */ + struct snd_info_entry *entry; + struct snd_info_entry *version_entry; + struct platform_device *pdev_child_devices + [MSM_SDW_CHILD_DEVICES_MAX]; + int child_count; +}; + +#if IS_ENABLED(CONFIG_SND_SOC_MSM_SDW) +extern int msm_sdw_set_spkr_mode(struct snd_soc_component *component, int mode); +extern int msm_sdw_set_spkr_gain_offset(struct snd_soc_component *component, + int offset); +extern void msm_sdw_gpio_cb( + int (*sdw_cdc_gpio_fn)(bool enable, + struct snd_soc_component *component), + struct snd_soc_component *component); +extern struct regmap *msm_sdw_regmap_init(struct device *dev, + const struct regmap_config *config); +extern int msm_sdw_codec_info_create_codec_entry( + struct snd_info_entry *component_root, + struct snd_soc_component *component); +#else /* CONFIG_SND_SOC_MSM_SDW */ +static inline int msm_sdw_set_spkr_mode(struct snd_soc_component *component, + int mode) +{ + return 0; +} +static inline int msm_sdw_set_spkr_gain_offset( + struct snd_soc_component *component, + int offset); +{ + return 0; +} +static inline void msm_sdw_gpio_cb( + int (*sdw_cdc_gpio_fn)(bool enable, + struct snd_soc_component *component), + struct snd_soc_component *component); +{ + +} +static inline struct regmap *msm_sdw_regmap_init(struct device *dev, + const struct regmap_config *config); +{ + return NULL; +} +static inline int msm_sdw_codec_info_create_codec_entry( + struct snd_info_entry *component_root, + struct snd_soc_component *component) +{ + return 0; +} +#endif /* CONFIG_SND_SOC_MSM_SDW */ +#endif diff --git a/asoc/codecs/msm_sdw/msm_sdw_cdc.c b/asoc/codecs/msm_sdw/msm_sdw_cdc.c new file mode 100644 index 000000000000..2b39e35c2ce5 --- /dev/null +++ b/asoc/codecs/msm_sdw/msm_sdw_cdc.c @@ -0,0 +1,2142 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm_sdw.h" +#include "msm_sdw_registers.h" +#include + +#define MSM_SDW_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000) +#define MSM_SDW_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_3LE) + +#define MSM_SDW_STRING_LEN 80 + +#define INT_MCLK1_FREQ 9600000 +#define SDW_NPL_FREQ 153600000 + +#define MSM_SDW_VERSION_1_0 0x0001 +#define MSM_SDW_VERSION_ENTRY_SIZE 32 +#define DRV_NAME "msm_sdw_codec" + +/* + * 200 Milliseconds sufficient for DSP bring up in the modem + * after Sub System Restart + */ +#define ADSP_STATE_READY_TIMEOUT_MS 200 + +static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); +static struct snd_soc_dai_driver msm_sdw_dai[]; +static bool skip_irq = true; + +static int msm_sdw_config_ear_spkr_gain(struct snd_soc_component *component, + int event, int gain_reg); +static int msm_sdw_config_compander(struct snd_soc_component *, int, int); +static int msm_sdw_mclk_enable(struct msm_sdw_priv *msm_sdw, + int mclk_enable, bool dapm); +static int msm_int_enable_sdw_cdc_clk(struct msm_sdw_priv *msm_sdw, + int enable, bool dapm); + +enum { + VI_SENSE_1, + VI_SENSE_2, +}; + +enum { + AIF1_SDW_PB = 0, + AIF1_SDW_VIFEED, + NUM_CODEC_DAIS, +}; + +static const struct msm_sdw_reg_mask_val msm_sdw_spkr_default[] = { + {MSM_SDW_COMPANDER7_CTL3, 0x80, 0x80}, + {MSM_SDW_COMPANDER8_CTL3, 0x80, 0x80}, + {MSM_SDW_COMPANDER7_CTL7, 0x01, 0x01}, + {MSM_SDW_COMPANDER8_CTL7, 0x01, 0x01}, + {MSM_SDW_BOOST0_BOOST_CTL, 0x7C, 0x58}, + {MSM_SDW_BOOST1_BOOST_CTL, 0x7C, 0x58}, +}; + +static const struct msm_sdw_reg_mask_val msm_sdw_spkr_mode1[] = { + {MSM_SDW_COMPANDER7_CTL3, 0x80, 0x00}, + {MSM_SDW_COMPANDER8_CTL3, 0x80, 0x00}, + {MSM_SDW_COMPANDER7_CTL7, 0x01, 0x00}, + {MSM_SDW_COMPANDER8_CTL7, 0x01, 0x00}, + {MSM_SDW_BOOST0_BOOST_CTL, 0x7C, 0x44}, + {MSM_SDW_BOOST1_BOOST_CTL, 0x7C, 0x44}, +}; + +/** + * msm_sdw_set_spkr_gain_offset - offset the speaker path + * gain with the given offset value. + * + * @component: component instance + * @offset: Indicates speaker path gain offset value. + * + * Returns 0 on success or -EINVAL on error. + */ +int msm_sdw_set_spkr_gain_offset(struct snd_soc_component *component, + int offset) +{ + struct msm_sdw_priv *priv; + + if (!component) { + pr_err("%s: NULL component pointer!\n", __func__); + return -EINVAL; + } + + priv = snd_soc_component_get_drvdata(component); + if (!priv) + return -EINVAL; + + priv->spkr_gain_offset = offset; + return 0; +} +EXPORT_SYMBOL(msm_sdw_set_spkr_gain_offset); + +/** + * msm_sdw_set_spkr_mode - Configures speaker compander and smartboost + * settings based on speaker mode. + * + * @component: codec component instance + * @mode: Indicates speaker configuration mode. + * + * Returns 0 on success or -EINVAL on error. + */ +int msm_sdw_set_spkr_mode(struct snd_soc_component *component, int mode) +{ + struct msm_sdw_priv *priv; + int i; + const struct msm_sdw_reg_mask_val *regs; + int size; + + if (!component) { + pr_err("%s: NULL codec pointer!\n", __func__); + return -EINVAL; + } + + priv = snd_soc_component_get_drvdata(component); + if (!priv) + return -EINVAL; + + switch (mode) { + case SPKR_MODE_1: + regs = msm_sdw_spkr_mode1; + size = ARRAY_SIZE(msm_sdw_spkr_mode1); + break; + default: + regs = msm_sdw_spkr_default; + size = ARRAY_SIZE(msm_sdw_spkr_default); + break; + } + + priv->spkr_mode = mode; + for (i = 0; i < size; i++) + snd_soc_component_update_bits(component, regs[i].reg, + regs[i].mask, regs[i].val); + return 0; +} +EXPORT_SYMBOL(msm_sdw_set_spkr_mode); + +static int msm_enable_sdw_npl_clk(struct msm_sdw_priv *msm_sdw, int enable) +{ + int ret = 0; + + dev_dbg(msm_sdw->dev, "%s: enable %d\n", __func__, enable); + + mutex_lock(&msm_sdw->sdw_npl_clk_mutex); + if (enable) { + if (msm_sdw->sdw_npl_clk_enabled == false) { + msm_sdw->sdw_npl_clk.enable = 1; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT4_MI2S_RX, + &msm_sdw->sdw_npl_clk); + if (ret < 0) { + dev_err(msm_sdw->dev, + "%s: failed to enable SDW NPL CLK\n", + __func__); + mutex_unlock(&msm_sdw->sdw_npl_clk_mutex); + return ret; + } + dev_dbg(msm_sdw->dev, "enabled sdw npl clk\n"); + msm_sdw->sdw_npl_clk_enabled = true; + } + } else { + if (msm_sdw->sdw_npl_clk_enabled == true) { + msm_sdw->sdw_npl_clk.enable = 0; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT4_MI2S_RX, + &msm_sdw->sdw_npl_clk); + if (ret < 0) + dev_err(msm_sdw->dev, + "%s: failed to disable SDW NPL CLK\n", + __func__); + msm_sdw->sdw_npl_clk_enabled = false; + } + } + mutex_unlock(&msm_sdw->sdw_npl_clk_mutex); + return ret; +} + +static int msm_int_enable_sdw_cdc_clk(struct msm_sdw_priv *msm_sdw, + int enable, bool dapm) +{ + int ret = 0; + + mutex_lock(&msm_sdw->cdc_int_mclk1_mutex); + dev_dbg(msm_sdw->dev, "%s: enable %d mclk1 ref counter %d\n", + __func__, enable, msm_sdw->int_mclk1_rsc_ref); + if (enable) { + if (msm_sdw->int_mclk1_rsc_ref == 0) { + cancel_delayed_work_sync( + &msm_sdw->disable_int_mclk1_work); + if (msm_sdw->int_mclk1_enabled == false) { + msm_sdw->sdw_cdc_core_clk.enable = 1; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT4_MI2S_RX, + &msm_sdw->sdw_cdc_core_clk); + if (ret < 0) { + dev_err(msm_sdw->dev, + "%s: failed to enable SDW MCLK\n", + __func__); + goto rtn; + } + dev_dbg(msm_sdw->dev, + "enabled sdw codec core mclk\n"); + msm_sdw->int_mclk1_enabled = true; + } + } + msm_sdw->int_mclk1_rsc_ref++; + } else { + cancel_delayed_work_sync(&msm_sdw->disable_int_mclk1_work); + if (msm_sdw->int_mclk1_rsc_ref > 0) { + msm_sdw->int_mclk1_rsc_ref--; + dev_dbg(msm_sdw->dev, + "%s: decrementing mclk_res_ref %d\n", + __func__, msm_sdw->int_mclk1_rsc_ref); + } + if (msm_sdw->int_mclk1_enabled == true && + msm_sdw->int_mclk1_rsc_ref == 0) { + msm_sdw->sdw_cdc_core_clk.enable = 0; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT4_MI2S_RX, + &msm_sdw->sdw_cdc_core_clk); + if (ret < 0) + dev_err(msm_sdw->dev, + "%s: failed to disable SDW MCLK\n", + __func__); + msm_sdw->int_mclk1_enabled = false; + } + } +rtn: + mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); + return ret; +} +EXPORT_SYMBOL(msm_int_enable_sdw_cdc_clk); + +static void msm_disable_int_mclk1(struct work_struct *work) +{ + struct msm_sdw_priv *msm_sdw = NULL; + struct delayed_work *dwork; + int ret = 0; + + dwork = to_delayed_work(work); + msm_sdw = container_of(dwork, struct msm_sdw_priv, + disable_int_mclk1_work); + mutex_lock(&msm_sdw->cdc_int_mclk1_mutex); + dev_dbg(msm_sdw->dev, "%s: mclk1_enabled %d mclk1_rsc_ref %d\n", + __func__, msm_sdw->int_mclk1_enabled, + msm_sdw->int_mclk1_rsc_ref); + if (msm_sdw->int_mclk1_enabled == true + && msm_sdw->int_mclk1_rsc_ref == 0) { + dev_dbg(msm_sdw->dev, "Disable the mclk1\n"); + msm_sdw->sdw_cdc_core_clk.enable = 0; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT4_MI2S_RX, + &msm_sdw->sdw_cdc_core_clk); + if (ret < 0) + dev_err(msm_sdw->dev, + "%s failed to disable the MCLK1\n", + __func__); + msm_sdw->int_mclk1_enabled = false; + } + mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); +} + +static int msm_int_mclk1_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct msm_sdw_priv *msm_sdw = + snd_soc_component_get_drvdata(component); + int ret = 0; + + dev_dbg(msm_sdw->dev, "%s: event = %d\n", __func__, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* enable the codec mclk config */ + msm_int_enable_sdw_cdc_clk(msm_sdw, 1, true); + msm_sdw_mclk_enable(msm_sdw, 1, true); + break; + case SND_SOC_DAPM_POST_PMD: + /* disable the codec mclk config */ + msm_sdw_mclk_enable(msm_sdw, 0, true); + msm_int_enable_sdw_cdc_clk(msm_sdw, 0, true); + break; + default: + dev_err(msm_sdw->dev, + "%s: invalid DAPM event %d\n", __func__, event); + ret = -EINVAL; + } + return ret; +} + +static int msm_sdw_ahb_write_device(struct msm_sdw_priv *msm_sdw, + u16 reg, u8 *value) +{ + u32 temp = (u32)(*value) & 0x000000FF; + + if (!msm_sdw->dev_up) { + dev_err_ratelimited(msm_sdw->dev, "%s: q6 not ready\n", + __func__); + return 0; + } + + iowrite32(temp, msm_sdw->sdw_base + reg); + return 0; +} + +static int msm_sdw_ahb_read_device(struct msm_sdw_priv *msm_sdw, + u16 reg, u8 *value) +{ + u32 temp; + + if (!msm_sdw->dev_up) { + dev_err_ratelimited(msm_sdw->dev, "%s: q6 not ready\n", + __func__); + return 0; + } + + temp = ioread32(msm_sdw->sdw_base + reg); + *value = (u8)temp; + return 0; +} + +static int __msm_sdw_reg_read(struct msm_sdw_priv *msm_sdw, unsigned short reg, + int bytes, void *dest) +{ + int ret = -EINVAL, i; + u8 temp = 0; + + dev_dbg(msm_sdw->dev, "%s reg = %x\n", __func__, reg); + mutex_lock(&msm_sdw->cdc_int_mclk1_mutex); + if (msm_sdw->int_mclk1_enabled == false) { + msm_sdw->sdw_cdc_core_clk.enable = 1; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT4_MI2S_RX, + &msm_sdw->sdw_cdc_core_clk); + if (ret < 0) { + dev_err(msm_sdw->dev, + "%s:failed to enable the INT_MCLK1\n", + __func__); + goto unlock_exit; + } + dev_dbg(msm_sdw->dev, "%s:enabled sdw codec core clk\n", + __func__); + for (i = 0; i < bytes; i++) { + ret = msm_sdw_ahb_read_device( + msm_sdw, reg + (4 * i), &temp); + ((u8 *)dest)[i] = temp; + } + msm_sdw->int_mclk1_enabled = true; + schedule_delayed_work(&msm_sdw->disable_int_mclk1_work, 50); + goto unlock_exit; + } + for (i = 0; i < bytes; i++) { + ret = msm_sdw_ahb_read_device( + msm_sdw, reg + (4 * i), &temp); + ((u8 *)dest)[i] = temp; + } +unlock_exit: + mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); + if (ret < 0) { + dev_err_ratelimited(msm_sdw->dev, + "%s: codec read failed for reg 0x%x\n", + __func__, reg); + return ret; + } + dev_dbg(msm_sdw->dev, "Read 0x%02x from 0x%x\n", temp, reg); + + return 0; +} + +static int __msm_sdw_reg_write(struct msm_sdw_priv *msm_sdw, unsigned short reg, + int bytes, void *src) +{ + int ret = -EINVAL, i; + + mutex_lock(&msm_sdw->cdc_int_mclk1_mutex); + if (msm_sdw->int_mclk1_enabled == false) { + msm_sdw->sdw_cdc_core_clk.enable = 1; + ret = afe_set_lpass_clock_v2(AFE_PORT_ID_INT4_MI2S_RX, + &msm_sdw->sdw_cdc_core_clk); + if (ret < 0) { + dev_err(msm_sdw->dev, + "%s: failed to enable the INT_MCLK1\n", + __func__); + ret = 0; + goto unlock_exit; + } + dev_dbg(msm_sdw->dev, "%s: enabled INT_MCLK1\n", __func__); + for (i = 0; i < bytes; i++) + ret = msm_sdw_ahb_write_device(msm_sdw, reg + (4 * i), + &((u8 *)src)[i]); + msm_sdw->int_mclk1_enabled = true; + schedule_delayed_work(&msm_sdw->disable_int_mclk1_work, 50); + goto unlock_exit; + } + for (i = 0; i < bytes; i++) + ret = msm_sdw_ahb_write_device(msm_sdw, reg + (4 * i), + &((u8 *)src)[i]); +unlock_exit: + mutex_unlock(&msm_sdw->cdc_int_mclk1_mutex); + dev_dbg(msm_sdw->dev, "Write 0x%x val 0x%02x\n", + reg, (u32)(*(u32 *)src)); + + return ret; +} + +static int msm_sdw_codec_enable_vi_feedback(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = NULL; + struct msm_sdw_priv *msm_sdw_p = NULL; + int ret = 0; + + if (!w) { + pr_err("%s invalid params\n", __func__); + return -EINVAL; + } + component = snd_soc_dapm_to_component(w->dapm); + msm_sdw_p = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: num_dai %d stream name %s\n", + __func__, component->num_dai, w->sname); + + dev_dbg(component->dev, "%s(): w->name %s event %d w->shift %d\n", + __func__, w->name, event, w->shift); + if (w->shift != AIF1_SDW_VIFEED) { + dev_err(component->dev, + "%s:Error in enabling the vi feedback path\n", + __func__); + ret = -EINVAL; + goto out_vi; + } + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (test_bit(VI_SENSE_1, &msm_sdw_p->status_mask)) { + dev_dbg(component->dev, + "%s: spkr1 enabled\n", __func__); + /* Enable V&I sensing */ + snd_soc_component_update_bits(component, + MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); + snd_soc_component_update_bits(component, + MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_component_update_bits(component, + MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x0F, 0x04); + snd_soc_component_update_bits(component, + MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x0F, 0x04); + snd_soc_component_update_bits(component, + MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x10); + snd_soc_component_update_bits(component, + MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x10, + 0x10); + snd_soc_component_update_bits(component, + MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x00); + snd_soc_component_update_bits(component, + MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x20, + 0x00); + } + if (test_bit(VI_SENSE_2, &msm_sdw_p->status_mask)) { + dev_dbg(component->dev, + "%s: spkr2 enabled\n", __func__); + /* Enable V&I sensing */ + snd_soc_component_update_bits(component, + MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_component_update_bits(component, + MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_component_update_bits(component, + MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x0F, + 0x04); + snd_soc_component_update_bits(component, + MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x0F, + 0x04); + snd_soc_component_update_bits(component, + MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x10, + 0x10); + snd_soc_component_update_bits(component, + MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x10, + 0x10); + snd_soc_component_update_bits(component, + MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x20, + 0x00); + snd_soc_component_update_bits(component, + MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x20, + 0x00); + } + break; + case SND_SOC_DAPM_POST_PMD: + if (test_bit(VI_SENSE_1, &msm_sdw_p->status_mask)) { + /* Disable V&I sensing */ + dev_dbg(component->dev, + "%s: spkr1 disabled\n", __func__); + snd_soc_component_update_bits(component, + MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20); + snd_soc_component_update_bits(component, + MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_component_update_bits(component, + MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x00); + snd_soc_component_update_bits(component, + MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x10, + 0x00); + } + if (test_bit(VI_SENSE_2, &msm_sdw_p->status_mask)) { + /* Disable V&I sensing */ + dev_dbg(component->dev, + "%s: spkr2 disabled\n", __func__); + snd_soc_component_update_bits(component, + MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_component_update_bits(component, + MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x20, + 0x20); + snd_soc_component_update_bits(component, + MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x10, + 0x00); + snd_soc_component_update_bits(component, + MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x10, + 0x00); + } + break; + } +out_vi: + return ret; +} + +static int msm_sdwm_handle_irq(void *handle, + irqreturn_t (*swrm_irq_handler)(int irq, + void *data), + void *swrm_handle, + int action) +{ + struct msm_sdw_priv *msm_sdw; + int ret = 0; + + if (!handle) { + pr_err("%s: null handle received\n", __func__); + return -EINVAL; + } + msm_sdw = (struct msm_sdw_priv *) handle; + + if (skip_irq) + return ret; + + if (action) { + ret = request_threaded_irq(msm_sdw->sdw_irq, NULL, + swrm_irq_handler, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "swr_master_irq", swrm_handle); + if (ret) + dev_err(msm_sdw->dev, "%s: Failed to request irq %d\n", + __func__, ret); + } else + free_irq(msm_sdw->sdw_irq, swrm_handle); + + return ret; +} + +static void msm_sdw_codec_hd2_control(struct snd_soc_component *component, + u16 reg, int event) +{ + u16 hd2_scale_reg; + u16 hd2_enable_reg = 0; + + if (reg == MSM_SDW_RX7_RX_PATH_CTL) { + hd2_scale_reg = MSM_SDW_RX7_RX_PATH_SEC3; + hd2_enable_reg = MSM_SDW_RX7_RX_PATH_CFG0; + } + if (reg == MSM_SDW_RX8_RX_PATH_CTL) { + hd2_scale_reg = MSM_SDW_RX8_RX_PATH_SEC3; + hd2_enable_reg = MSM_SDW_RX8_RX_PATH_CFG0; + } + + if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { + snd_soc_component_update_bits(component, hd2_scale_reg, + 0x3C, 0x10); + snd_soc_component_update_bits(component, hd2_scale_reg, + 0x03, 0x01); + snd_soc_component_update_bits(component, hd2_enable_reg, + 0x04, 0x04); + } + + if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_component_update_bits(component, hd2_enable_reg, + 0x04, 0x00); + snd_soc_component_update_bits(component, hd2_scale_reg, + 0x03, 0x00); + snd_soc_component_update_bits(component, hd2_scale_reg, + 0x3C, 0x00); + } +} + +static int msm_sdw_enable_swr(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct msm_sdw_priv *msm_sdw; + int i, ch_cnt; + + msm_sdw = snd_soc_component_get_drvdata(component); + + if (!msm_sdw->nr) + return 0; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (!(strnstr(w->name, "RX4", sizeof("RX4 MIX"))) && + !msm_sdw->rx_4_count) + msm_sdw->rx_4_count++; + if (!(strnstr(w->name, "RX5", sizeof("RX5 MIX"))) && + !msm_sdw->rx_5_count) + msm_sdw->rx_5_count++; + ch_cnt = msm_sdw->rx_4_count + msm_sdw->rx_5_count; + + for (i = 0; i < msm_sdw->nr; i++) { + swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, + SWR_DEVICE_UP, NULL); + swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, + SWR_SET_NUM_RX_CH, &ch_cnt); + } + break; + case SND_SOC_DAPM_POST_PMD: + if (!(strnstr(w->name, "RX4", sizeof("RX4 MIX"))) && + msm_sdw->rx_4_count) + msm_sdw->rx_4_count--; + if (!(strnstr(w->name, "RX5", sizeof("RX5 MIX"))) && + msm_sdw->rx_5_count) + msm_sdw->rx_5_count--; + ch_cnt = msm_sdw->rx_4_count + msm_sdw->rx_5_count; + + for (i = 0; i < msm_sdw->nr; i++) + swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, + SWR_SET_NUM_RX_CH, &ch_cnt); + break; + } + dev_dbg(msm_sdw->dev, "%s: current swr ch cnt: %d\n", + __func__, msm_sdw->rx_4_count + msm_sdw->rx_5_count); + + return 0; +} + +static int msm_sdw_codec_enable_interpolator(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct msm_sdw_priv *msm_sdw = + snd_soc_component_get_drvdata(component); + u16 gain_reg; + u16 reg; + int val; + int offset_val = 0; + + dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name); + + if (!(strcmp(w->name, "RX INT4 INTERP"))) { + reg = MSM_SDW_RX7_RX_PATH_CTL; + gain_reg = MSM_SDW_RX7_RX_VOL_CTL; + } else if (!(strcmp(w->name, "RX INT5 INTERP"))) { + reg = MSM_SDW_RX8_RX_PATH_CTL; + gain_reg = MSM_SDW_RX8_RX_VOL_CTL; + } else { + dev_err(component->dev, "%s: Interpolator reg not found\n", + __func__); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_component_update_bits(component, reg, 0x10, 0x10); + msm_sdw_codec_hd2_control(component, reg, event); + snd_soc_component_update_bits(component, reg, + 1 << 0x5, 1 << 0x5); + break; + case SND_SOC_DAPM_POST_PMU: + msm_sdw_config_compander(component, w->shift, event); + /* apply gain after int clk is enabled */ + if ((msm_sdw->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && + (msm_sdw->comp_enabled[COMP1] || + msm_sdw->comp_enabled[COMP2]) && + (gain_reg == MSM_SDW_RX7_RX_VOL_CTL || + gain_reg == MSM_SDW_RX8_RX_VOL_CTL)) { + snd_soc_component_update_bits(component, + MSM_SDW_RX7_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_component_update_bits(component, + MSM_SDW_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x01); + snd_soc_component_update_bits(component, + MSM_SDW_RX8_RX_PATH_SEC1, + 0x01, 0x01); + snd_soc_component_update_bits(component, + MSM_SDW_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x01); + offset_val = -2; + } + val = snd_soc_component_read32(component, gain_reg); + val += offset_val; + snd_soc_component_write(component, gain_reg, val); + msm_sdw_config_ear_spkr_gain(component, event, gain_reg); + snd_soc_component_update_bits(component, reg, 0x10, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, reg, + 1 << 0x5, 0 << 0x5); + snd_soc_component_update_bits(component, reg, 0x40, 0x40); + snd_soc_component_update_bits(component, reg, 0x40, 0x00); + msm_sdw_codec_hd2_control(component, reg, event); + msm_sdw_config_compander(component, w->shift, event); + if ((msm_sdw->spkr_gain_offset == RX_GAIN_OFFSET_M1P5_DB) && + (msm_sdw->comp_enabled[COMP1] || + msm_sdw->comp_enabled[COMP2]) && + (gain_reg == MSM_SDW_RX7_RX_VOL_CTL || + gain_reg == MSM_SDW_RX8_RX_VOL_CTL)) { + snd_soc_component_update_bits(component, + MSM_SDW_RX7_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_component_update_bits(component, + MSM_SDW_RX7_RX_PATH_MIX_SEC0, + 0x01, 0x00); + snd_soc_component_update_bits(component, + MSM_SDW_RX8_RX_PATH_SEC1, + 0x01, 0x00); + snd_soc_component_update_bits(component, + MSM_SDW_RX8_RX_PATH_MIX_SEC0, + 0x01, 0x00); + offset_val = 2; + val = snd_soc_component_read32(component, gain_reg); + val += offset_val; + snd_soc_component_write(component, gain_reg, val); + } + msm_sdw_config_ear_spkr_gain(component, event, gain_reg); + break; + }; + + return 0; +} + +static int msm_sdw_config_ear_spkr_gain(struct snd_soc_component *component, + int event, int gain_reg) +{ + int comp_gain_offset, val; + struct msm_sdw_priv *msm_sdw = snd_soc_component_get_drvdata(component); + + switch (msm_sdw->spkr_mode) { + /* Compander gain in SPKR_MODE1 case is 12 dB */ + case SPKR_MODE_1: + comp_gain_offset = -12; + break; + /* Default case compander gain is 15 dB */ + default: + comp_gain_offset = -15; + break; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* Apply ear spkr gain only if compander is enabled */ + if (msm_sdw->comp_enabled[COMP1] && + (gain_reg == MSM_SDW_RX7_RX_VOL_CTL) && + (msm_sdw->ear_spkr_gain != 0)) { + /* For example, val is -8(-12+5-1) for 4dB of gain */ + val = comp_gain_offset + msm_sdw->ear_spkr_gain - 1; + snd_soc_component_write(component, gain_reg, val); + + dev_dbg(component->dev, "%s: RX4 Volume %d dB\n", + __func__, val); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* + * Reset RX4 volume to 0 dB if compander is enabled and + * ear_spkr_gain is non-zero. + */ + if (msm_sdw->comp_enabled[COMP1] && + (gain_reg == MSM_SDW_RX7_RX_VOL_CTL) && + (msm_sdw->ear_spkr_gain != 0)) { + snd_soc_component_write(component, gain_reg, 0x0); + + dev_dbg(component->dev, + "%s: Reset RX4 Volume to 0 dB\n", __func__); + } + break; + } + + return 0; +} + +static int msm_sdw_codec_spk_boost_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + u16 boost_path_ctl, boost_path_cfg1; + u16 reg; + + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); + + if (!strcmp(w->name, "RX INT4 CHAIN")) { + boost_path_ctl = MSM_SDW_BOOST0_BOOST_PATH_CTL; + boost_path_cfg1 = MSM_SDW_RX7_RX_PATH_CFG1; + reg = MSM_SDW_RX7_RX_PATH_CTL; + } else if (!strcmp(w->name, "RX INT5 CHAIN")) { + boost_path_ctl = MSM_SDW_BOOST1_BOOST_PATH_CTL; + boost_path_cfg1 = MSM_SDW_RX8_RX_PATH_CFG1; + reg = MSM_SDW_RX8_RX_PATH_CTL; + } else { + dev_err(component->dev, "%s: boost reg not found\n", + __func__); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_component_update_bits(component, boost_path_ctl, + 0x10, 0x10); + snd_soc_component_update_bits(component, boost_path_cfg1, + 0x01, 0x01); + snd_soc_component_update_bits(component, reg, 0x10, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, boost_path_cfg1, + 0x01, 0x00); + snd_soc_component_update_bits(component, boost_path_ctl, + 0x10, 0x00); + break; + }; + + return 0; +} + +static int msm_sdw_config_compander(struct snd_soc_component *component, + int comp, int event) +{ + struct msm_sdw_priv *msm_sdw = snd_soc_component_get_drvdata(component); + u16 comp_ctl0_reg, rx_path_cfg0_reg; + + if (comp < COMP1 || comp >= COMP_MAX) + return 0; + + dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n", + __func__, event, comp + 1, msm_sdw->comp_enabled[comp]); + + if (!msm_sdw->comp_enabled[comp]) + return 0; + + comp_ctl0_reg = MSM_SDW_COMPANDER7_CTL0 + (comp * 0x20); + rx_path_cfg0_reg = MSM_SDW_RX7_RX_PATH_CFG0 + (comp * 0x1E0); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* Enable Compander Clock */ + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x01, 0x01); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x02); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x00); + snd_soc_component_update_bits(component, rx_path_cfg0_reg, + 0x02, 0x02); + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x04, 0x04); + snd_soc_component_update_bits(component, rx_path_cfg0_reg, + 0x02, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x02); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x02, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x01, 0x00); + snd_soc_component_update_bits(component, comp_ctl0_reg, + 0x04, 0x00); + } + + return 0; +} + +static int msm_sdw_get_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + struct msm_sdw_priv *msm_sdw = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = msm_sdw->comp_enabled[comp]; + return 0; +} + +static int msm_sdw_set_compander(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct msm_sdw_priv *msm_sdw = snd_soc_component_get_drvdata(component); + int comp = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int value = ucontrol->value.integer.value[0]; + + dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n", + __func__, comp + 1, msm_sdw->comp_enabled[comp], value); + msm_sdw->comp_enabled[comp] = value; + + return 0; +} + +static int msm_sdw_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct msm_sdw_priv *msm_sdw = + snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = msm_sdw->ear_spkr_gain; + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_sdw_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct msm_sdw_priv *msm_sdw = + snd_soc_component_get_drvdata(component); + + msm_sdw->ear_spkr_gain = ucontrol->value.integer.value[0]; + + dev_dbg(component->dev, "%s: gain = %d\n", __func__, + msm_sdw->ear_spkr_gain); + + return 0; +} + +static int msm_sdw_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max = 0; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + + bst_state_max = snd_soc_component_read32(component, + MSM_SDW_BOOST0_BOOST_CTL); + bst_state_max = (bst_state_max & 0x0c) >> 2; + ucontrol->value.integer.value[0] = bst_state_max; + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_sdw_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + bst_state_max = ucontrol->value.integer.value[0] << 2; + snd_soc_component_update_bits(component, MSM_SDW_BOOST0_BOOST_CTL, + 0x0c, bst_state_max); + + return 0; +} + +static int msm_sdw_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max = 0; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + + bst_state_max = snd_soc_component_read32(component, + MSM_SDW_BOOST1_BOOST_CTL); + bst_state_max = (bst_state_max & 0x0c) >> 2; + ucontrol->value.integer.value[0] = bst_state_max; + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_sdw_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 bst_state_max; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + bst_state_max = ucontrol->value.integer.value[0] << 2; + snd_soc_component_update_bits(component, MSM_SDW_BOOST1_BOOST_CTL, + 0x0c, bst_state_max); + + return 0; +} + +static int msm_sdw_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct msm_sdw_priv *msm_sdw_p = + snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = msm_sdw_p->vi_feed_value; + + return 0; +} + +static int msm_sdw_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = + snd_soc_dapm_to_component(widget->dapm); + struct msm_sdw_priv *msm_sdw_p = + snd_soc_component_get_drvdata(component); + struct soc_multi_mixer_control *mixer = + ((struct soc_multi_mixer_control *)kcontrol->private_value); + u32 dai_id = widget->shift; + u32 port_id = mixer->shift; + u32 enable = ucontrol->value.integer.value[0]; + + dev_dbg(component->dev, "%s: enable: %d, port_id:%d, dai_id: %d\n", + __func__, enable, port_id, dai_id); + + msm_sdw_p->vi_feed_value = ucontrol->value.integer.value[0]; + + mutex_lock(&msm_sdw_p->codec_mutex); + if (enable) { + if (port_id == MSM_SDW_TX0 && !test_bit(VI_SENSE_1, + &msm_sdw_p->status_mask)) + set_bit(VI_SENSE_1, &msm_sdw_p->status_mask); + if (port_id == MSM_SDW_TX1 && !test_bit(VI_SENSE_2, + &msm_sdw_p->status_mask)) + set_bit(VI_SENSE_2, &msm_sdw_p->status_mask); + } else { + if (port_id == MSM_SDW_TX0 && test_bit(VI_SENSE_1, + &msm_sdw_p->status_mask)) + clear_bit(VI_SENSE_1, &msm_sdw_p->status_mask); + if (port_id == MSM_SDW_TX1 && test_bit(VI_SENSE_2, + &msm_sdw_p->status_mask)) + clear_bit(VI_SENSE_2, &msm_sdw_p->status_mask); + } + mutex_unlock(&msm_sdw_p->codec_mutex); + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL); + + return 0; +} + +static int msm_sdw_mclk_enable(struct msm_sdw_priv *msm_sdw, + int mclk_enable, bool dapm) +{ + dev_dbg(msm_sdw->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", + __func__, mclk_enable, dapm, msm_sdw->sdw_mclk_users); + if (mclk_enable) { + msm_sdw->sdw_mclk_users++; + if (msm_sdw->sdw_mclk_users == 1) { + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + /* 9.6MHz MCLK, set value 0x00 if other frequency */ + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_TOP_FREQ_MCLK, 0x01, 0x01); + } + } else { + msm_sdw->sdw_mclk_users--; + if (msm_sdw->sdw_mclk_users == 0) { + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x00); + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x00); + } + } + return 0; +} +EXPORT_SYMBOL(msm_sdw_mclk_enable); + +static int msm_sdw_swrm_read(void *handle, int reg) +{ + struct msm_sdw_priv *msm_sdw; + unsigned short sdw_rd_addr_base; + unsigned short sdw_rd_data_base; + int val, ret; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + msm_sdw = (struct msm_sdw_priv *)handle; + + dev_dbg(msm_sdw->dev, "%s: Reading soundwire register, 0x%x\n", + __func__, reg); + sdw_rd_addr_base = MSM_SDW_AHB_BRIDGE_RD_ADDR_0; + sdw_rd_data_base = MSM_SDW_AHB_BRIDGE_RD_DATA_0; + /* + * Add sleep as SWR slave access read takes time. + * Allow for RD_DONE to complete for previous register if any. + */ + usleep_range(100, 105); + + /* read_lock */ + mutex_lock(&msm_sdw->sdw_read_lock); + ret = regmap_bulk_write(msm_sdw->regmap, sdw_rd_addr_base, + (u8 *)®, 4); + if (ret < 0) { + dev_err(msm_sdw->dev, "%s: RD Addr Failure\n", __func__); + goto err; + } + /* Add sleep for SWR register read value to get updated. */ + usleep_range(100, 105); + /* Check for RD value */ + ret = regmap_bulk_read(msm_sdw->regmap, sdw_rd_data_base, + (u8 *)&val, 4); + if (ret < 0) { + dev_err(msm_sdw->dev, "%s: RD Data Failure\n", __func__); + goto err; + } + ret = val; +err: + /* read_unlock */ + mutex_unlock(&msm_sdw->sdw_read_lock); + return ret; +} + +static int msm_sdw_bulk_write(struct msm_sdw_priv *msm_sdw, + struct msm_sdw_reg_val *bulk_reg, + size_t len) +{ + int i, ret = 0; + unsigned short sdw_wr_addr_base; + unsigned short sdw_wr_data_base; + + sdw_wr_addr_base = MSM_SDW_AHB_BRIDGE_WR_ADDR_0; + sdw_wr_data_base = MSM_SDW_AHB_BRIDGE_WR_DATA_0; + + for (i = 0; i < len; i += 2) { + /* + * Add sleep as SWR slave write takes time. + * Allow for any previous pending write to complete. + */ + usleep_range(100, 105); + /* First Write the Data to register */ + ret = regmap_bulk_write(msm_sdw->regmap, + sdw_wr_data_base, bulk_reg[i].buf, 4); + if (ret < 0) { + dev_err(msm_sdw->dev, "%s: WR Data Failure\n", + __func__); + break; + } + /* Next Write Address */ + ret = regmap_bulk_write(msm_sdw->regmap, + sdw_wr_addr_base, bulk_reg[i+1].buf, 4); + if (ret < 0) { + dev_err(msm_sdw->dev, + "%s: WR Addr Failure: 0x%x\n", + __func__, (u32)(bulk_reg[i+1].buf[0])); + break; + } + } + return ret; +} + +static int msm_sdw_swrm_bulk_write(void *handle, u32 *reg, u32 *val, size_t len) +{ + struct msm_sdw_priv *msm_sdw; + struct msm_sdw_reg_val *bulk_reg; + unsigned short sdw_wr_addr_base; + unsigned short sdw_wr_data_base; + int i, j, ret; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + + msm_sdw = (struct msm_sdw_priv *)handle; + if (len <= 0) { + dev_err(msm_sdw->dev, + "%s: Invalid size: %zu\n", __func__, len); + return -EINVAL; + } + + sdw_wr_addr_base = MSM_SDW_AHB_BRIDGE_WR_ADDR_0; + sdw_wr_data_base = MSM_SDW_AHB_BRIDGE_WR_DATA_0; + + bulk_reg = kzalloc((2 * len * sizeof(struct msm_sdw_reg_val)), + GFP_KERNEL); + if (!bulk_reg) + return -ENOMEM; + + for (i = 0, j = 0; i < (len * 2); i += 2, j++) { + bulk_reg[i].reg = sdw_wr_data_base; + bulk_reg[i].buf = (u8 *)(&val[j]); + bulk_reg[i].bytes = 4; + bulk_reg[i+1].reg = sdw_wr_addr_base; + bulk_reg[i+1].buf = (u8 *)(®[j]); + bulk_reg[i+1].bytes = 4; + } + mutex_lock(&msm_sdw->sdw_write_lock); + + ret = msm_sdw_bulk_write(msm_sdw, bulk_reg, (len * 2)); + if (ret) + dev_err(msm_sdw->dev, "%s: swrm bulk write failed, ret: %d\n", + __func__, ret); + + mutex_unlock(&msm_sdw->sdw_write_lock); + kfree(bulk_reg); + + return ret; +} + +static int msm_sdw_swrm_write(void *handle, int reg, int val) +{ + struct msm_sdw_priv *msm_sdw; + unsigned short sdw_wr_addr_base; + unsigned short sdw_wr_data_base; + struct msm_sdw_reg_val bulk_reg[2]; + int ret; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + msm_sdw = (struct msm_sdw_priv *)handle; + + sdw_wr_addr_base = MSM_SDW_AHB_BRIDGE_WR_ADDR_0; + sdw_wr_data_base = MSM_SDW_AHB_BRIDGE_WR_DATA_0; + + /* First Write the Data to register */ + bulk_reg[0].reg = sdw_wr_data_base; + bulk_reg[0].buf = (u8 *)(&val); + bulk_reg[0].bytes = 4; + bulk_reg[1].reg = sdw_wr_addr_base; + bulk_reg[1].buf = (u8 *)(®); + bulk_reg[1].bytes = 4; + + mutex_lock(&msm_sdw->sdw_write_lock); + + ret = msm_sdw_bulk_write(msm_sdw, bulk_reg, 2); + if (ret < 0) + dev_err(msm_sdw->dev, "%s: WR Data Failure\n", __func__); + + mutex_unlock(&msm_sdw->sdw_write_lock); + return ret; +} + +static int msm_sdw_swrm_clock(void *handle, bool enable) +{ + struct msm_sdw_priv *msm_sdw; + + if (!handle) { + pr_err("%s: NULL handle\n", __func__); + return -EINVAL; + } + msm_sdw = (struct msm_sdw_priv *)handle; + + mutex_lock(&msm_sdw->sdw_clk_lock); + + dev_dbg(msm_sdw->dev, "%s: swrm clock %s\n", + __func__, (enable ? "enable" : "disable")); + if (enable) { + msm_sdw->sdw_clk_users++; + if (msm_sdw->sdw_clk_users == 1) { + msm_int_enable_sdw_cdc_clk(msm_sdw, 1, true); + msm_sdw_mclk_enable(msm_sdw, 1, true); + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x01); + msm_enable_sdw_npl_clk(msm_sdw, true); + msm_cdc_pinctrl_select_active_state( + msm_sdw->sdw_gpio_p); + } + } else { + msm_sdw->sdw_clk_users--; + if (msm_sdw->sdw_clk_users == 0) { + regmap_update_bits(msm_sdw->regmap, + MSM_SDW_CLK_RST_CTRL_SWR_CONTROL, + 0x01, 0x00); + msm_sdw_mclk_enable(msm_sdw, 0, true); + msm_int_enable_sdw_cdc_clk(msm_sdw, 0, true); + msm_enable_sdw_npl_clk(msm_sdw, false); + msm_cdc_pinctrl_select_sleep_state(msm_sdw->sdw_gpio_p); + } + } + dev_dbg(msm_sdw->dev, "%s: swrm clock users %d\n", + __func__, msm_sdw->sdw_clk_users); + mutex_unlock(&msm_sdw->sdw_clk_lock); + return 0; +} + +static int msm_sdw_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + dev_dbg(dai->component->dev, "%s(): substream = %s stream = %d\n", + __func__, + substream->name, substream->stream); + return 0; +} + +static int msm_sdw_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + u8 clk_fs_rate, fs_rate; + + dev_dbg(dai->component->dev, + "%s: dai_name = %s DAI-ID %x rate %d num_ch %d format %d\n", + __func__, dai->name, dai->id, params_rate(params), + params_channels(params), params_format(params)); + + switch (params_rate(params)) { + case 8000: + clk_fs_rate = 0x00; + fs_rate = 0x00; + break; + case 16000: + clk_fs_rate = 0x01; + fs_rate = 0x01; + break; + case 32000: + clk_fs_rate = 0x02; + fs_rate = 0x03; + break; + case 48000: + clk_fs_rate = 0x03; + fs_rate = 0x04; + break; + case 96000: + clk_fs_rate = 0x04; + fs_rate = 0x05; + break; + case 192000: + clk_fs_rate = 0x05; + fs_rate = 0x06; + break; + default: + dev_err(dai->component->dev, + "%s: Invalid sampling rate %d\n", __func__, + params_rate(params)); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + snd_soc_component_update_bits(dai->component, + MSM_SDW_TOP_TX_I2S_CTL, 0x1C, + (clk_fs_rate << 2)); + } else { + snd_soc_component_update_bits(dai->component, + MSM_SDW_TOP_RX_I2S_CTL, 0x1C, + (clk_fs_rate << 2)); + snd_soc_component_update_bits(dai->component, + MSM_SDW_RX7_RX_PATH_CTL, 0x0F, + fs_rate); + snd_soc_component_update_bits(dai->component, + MSM_SDW_RX8_RX_PATH_CTL, 0x0F, + fs_rate); + } + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + snd_soc_component_update_bits(dai->component, + MSM_SDW_TOP_TX_I2S_CTL, 0x20, 0x20); + else + snd_soc_component_update_bits(dai->component, + MSM_SDW_TOP_RX_I2S_CTL, 0x20, 0x20); + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + snd_soc_component_update_bits(dai->component, + MSM_SDW_TOP_TX_I2S_CTL, 0x20, 0x00); + else + snd_soc_component_update_bits(dai->component, + MSM_SDW_TOP_RX_I2S_CTL, 0x20, 0x00); + break; + default: + dev_err(dai->component->dev, "%s: wrong format selected\n", + __func__); + return -EINVAL; + } + + return 0; +} + +static void msm_sdw_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + dev_dbg(dai->component->dev, + "%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); +} + +static ssize_t msm_sdw_codec_version_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, size_t count, + loff_t pos) +{ + struct msm_sdw_priv *msm_sdw; + char buffer[MSM_SDW_VERSION_ENTRY_SIZE]; + int len = 0; + + msm_sdw = (struct msm_sdw_priv *) entry->private_data; + if (!msm_sdw) { + pr_err("%s: msm_sdw priv is null\n", __func__); + return -EINVAL; + } + + switch (msm_sdw->version) { + case MSM_SDW_VERSION_1_0: + len = snprintf(buffer, sizeof(buffer), "SDW-CDC_1_0\n"); + break; + default: + len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + } + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops msm_sdw_codec_info_ops = { + .read = msm_sdw_codec_version_read, +}; + +/* + * msm_sdw_codec_info_create_codec_entry - creates msm_sdw module + * @codec_root: The parent directory + * @codec: Codec instance + * + * Creates msm_sdw module and version entry under the given + * parent directory. + * + * Return: 0 on success or negative error code on failure. + */ +int msm_sdw_codec_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_component *component) +{ + struct snd_info_entry *version_entry; + struct msm_sdw_priv *msm_sdw; + struct snd_soc_card *card; + char name[80]; + + if (!codec_root || !component) + return -EINVAL; + + msm_sdw = snd_soc_component_get_drvdata(component); + card = component->card; + + snprintf(name, sizeof(name), "%x.%s", (u32)msm_sdw->sdw_base_addr, + "msm-sdw-codec"); + msm_sdw->entry = snd_info_create_subdir(codec_root->module, + (const char *)name, + codec_root); + if (!msm_sdw->entry) { + dev_err(component->dev, "%s: failed to create msm_sdw entry\n", + __func__); + return -ENOMEM; + } + + version_entry = snd_info_create_card_entry(card->snd_card, + "version", + msm_sdw->entry); + if (!version_entry) { + dev_err(component->dev, "%s: failed to create msm_sdw version entry\n", + __func__); + return -ENOMEM; + } + + version_entry->private_data = msm_sdw; + version_entry->size = MSM_SDW_VERSION_ENTRY_SIZE; + version_entry->content = SNDRV_INFO_CONTENT_DATA; + version_entry->c.ops = &msm_sdw_codec_info_ops; + + if (snd_info_register(version_entry) < 0) { + snd_info_free_entry(version_entry); + return -ENOMEM; + } + msm_sdw->version_entry = version_entry; + + return 0; +} +EXPORT_SYMBOL(msm_sdw_codec_info_create_codec_entry); + +static struct snd_soc_dai_ops msm_sdw_dai_ops = { + .startup = msm_sdw_startup, + .shutdown = msm_sdw_shutdown, + .hw_params = msm_sdw_hw_params, +}; + +static struct snd_soc_dai_driver msm_sdw_dai[] = { + { + .name = "msm_sdw_i2s_rx1", + .id = AIF1_SDW_PB, + .playback = { + .stream_name = "AIF1_SDW Playback", + .rates = MSM_SDW_RATES, + .formats = MSM_SDW_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 4, + }, + .ops = &msm_sdw_dai_ops, + }, + { + .name = "msm_sdw_vifeedback", + .id = AIF1_SDW_VIFEED, + .capture = { + .stream_name = "VIfeed_SDW", + .rates = MSM_SDW_RATES, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_max = 48000, + .rate_min = 8000, + .channels_min = 2, + .channels_max = 4, + }, + .ops = &msm_sdw_dai_ops, + }, +}; + +static const char * const rx_mix1_text[] = { + "ZERO", "RX4", "RX5" +}; + +static const char * const msm_sdw_ear_spkr_pa_gain_text[] = { + "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB", + "G_4_DB", "G_5_DB", "G_6_DB" +}; + +static const char * const msm_sdw_speaker_boost_stage_text[] = { + "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2" +}; + +static SOC_ENUM_SINGLE_EXT_DECL(msm_sdw_ear_spkr_pa_gain_enum, + msm_sdw_ear_spkr_pa_gain_text); +static SOC_ENUM_SINGLE_EXT_DECL(msm_sdw_spkr_boost_stage_enum, + msm_sdw_speaker_boost_stage_text); + +/* RX4 MIX1 */ +static const struct soc_enum rx4_mix1_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM_SDW_TOP_RX7_PATH_INPUT0_MUX, + 0, 3, rx_mix1_text); + +static const struct soc_enum rx4_mix1_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM_SDW_TOP_RX7_PATH_INPUT1_MUX, + 0, 3, rx_mix1_text); + +/* RX5 MIX1 */ +static const struct soc_enum rx5_mix1_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM_SDW_TOP_RX8_PATH_INPUT0_MUX, + 0, 3, rx_mix1_text); + +static const struct soc_enum rx5_mix1_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM_SDW_TOP_RX8_PATH_INPUT1_MUX, + 0, 3, rx_mix1_text); + +static const struct snd_kcontrol_new rx4_mix1_inp1_mux = + SOC_DAPM_ENUM("RX4 MIX1 INP1 Mux", rx4_mix1_inp1_chain_enum); + +static const struct snd_kcontrol_new rx4_mix1_inp2_mux = + SOC_DAPM_ENUM("RX4 MIX1 INP2 Mux", rx4_mix1_inp2_chain_enum); + +static const struct snd_kcontrol_new rx5_mix1_inp1_mux = + SOC_DAPM_ENUM("RX5 MIX1 INP1 Mux", rx5_mix1_inp1_chain_enum); + +static const struct snd_kcontrol_new rx5_mix1_inp2_mux = + SOC_DAPM_ENUM("RX5 MIX1 INP2 Mux", rx5_mix1_inp2_chain_enum); + +static const struct snd_kcontrol_new aif1_vi_mixer[] = { + SOC_SINGLE_EXT("SPKR_VI_1", SND_SOC_NOPM, MSM_SDW_TX0, 1, 0, + msm_sdw_vi_feed_mixer_get, msm_sdw_vi_feed_mixer_put), + SOC_SINGLE_EXT("SPKR_VI_2", SND_SOC_NOPM, MSM_SDW_TX1, 1, 0, + msm_sdw_vi_feed_mixer_get, msm_sdw_vi_feed_mixer_put), +}; + +static const struct snd_soc_dapm_widget msm_sdw_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN("I2S RX4", "AIF1_SDW Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_IN("I2S RX5", "AIF1_SDW Playback", 0, + SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_OUT_E("AIF1_SDW VI", "VIfeed_SDW", 0, SND_SOC_NOPM, + AIF1_SDW_VIFEED, 0, msm_sdw_codec_enable_vi_feedback, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("AIF1_VI_SDW Mixer", SND_SOC_NOPM, AIF1_SDW_VIFEED, + 0, aif1_vi_mixer, ARRAY_SIZE(aif1_vi_mixer)), + + SND_SOC_DAPM_MUX_E("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx4_mix1_inp1_mux, msm_sdw_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx4_mix1_inp2_mux, msm_sdw_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX5 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx5_mix1_inp1_mux, msm_sdw_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX5 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx5_mix1_inp2_mux, msm_sdw_enable_swr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("RX4 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX5 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MIXER_E("RX INT4 INTERP", SND_SOC_NOPM, + COMP1, 0, NULL, 0, msm_sdw_codec_enable_interpolator, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX INT5 INTERP", SND_SOC_NOPM, + COMP2, 0, NULL, 0, msm_sdw_codec_enable_interpolator, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER_E("RX INT4 CHAIN", SND_SOC_NOPM, 0, 0, + NULL, 0, msm_sdw_codec_spk_boost_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX INT5 CHAIN", SND_SOC_NOPM, 0, 0, + NULL, 0, msm_sdw_codec_spk_boost_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_INPUT("VIINPUT_SDW"), + + SND_SOC_DAPM_OUTPUT("SPK1 OUT"), + SND_SOC_DAPM_OUTPUT("SPK2 OUT"), + + SND_SOC_DAPM_SUPPLY_S("SDW_CONN", -1, MSM_SDW_TOP_I2S_CLK, + 0, 0, NULL, 0), + + SND_SOC_DAPM_SUPPLY_S("INT_MCLK1", -2, SND_SOC_NOPM, 0, 0, + msm_int_mclk1_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("SDW_RX_I2S_CLK", + MSM_SDW_TOP_RX_I2S_CTL, 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("SDW_TX_I2S_CLK", + MSM_SDW_TOP_TX_I2S_CTL, 0, 0, NULL, 0), +}; + +static const struct snd_kcontrol_new msm_sdw_snd_controls[] = { + SOC_ENUM_EXT("EAR SPKR PA Gain", msm_sdw_ear_spkr_pa_gain_enum, + msm_sdw_ear_spkr_pa_gain_get, + msm_sdw_ear_spkr_pa_gain_put), + SOC_ENUM_EXT("SPKR Left Boost Max State", + msm_sdw_spkr_boost_stage_enum, + msm_sdw_spkr_left_boost_stage_get, + msm_sdw_spkr_left_boost_stage_put), + SOC_ENUM_EXT("SPKR Right Boost Max State", + msm_sdw_spkr_boost_stage_enum, + msm_sdw_spkr_right_boost_stage_get, + msm_sdw_spkr_right_boost_stage_put), + SOC_SINGLE_SX_TLV("RX4 Digital Volume", MSM_SDW_RX7_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX5 Digital Volume", MSM_SDW_RX8_RX_VOL_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMP1, 1, 0, + msm_sdw_get_compander, msm_sdw_set_compander), + SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMP2, 1, 0, + msm_sdw_get_compander, msm_sdw_set_compander), +}; + +static const struct snd_soc_dapm_route audio_map[] = { + + {"AIF1_SDW VI", NULL, "SDW_TX_I2S_CLK"}, + {"SDW_TX_I2S_CLK", NULL, "INT_MCLK1"}, + {"SDW_TX_I2S_CLK", NULL, "SDW_CONN"}, + + /* VI Feedback */ + {"AIF1_VI_SDW Mixer", "SPKR_VI_1", "VIINPUT_SDW"}, + {"AIF1_VI_SDW Mixer", "SPKR_VI_2", "VIINPUT_SDW"}, + {"AIF1_SDW VI", NULL, "AIF1_VI_SDW Mixer"}, + + {"SDW_RX_I2S_CLK", NULL, "INT_MCLK1"}, + {"SDW_RX_I2S_CLK", NULL, "SDW_CONN"}, + {"I2S RX4", NULL, "SDW_RX_I2S_CLK"}, + {"I2S RX5", NULL, "SDW_RX_I2S_CLK"}, + + {"RX4 MIX1 INP1", "RX4", "I2S RX4"}, + {"RX4 MIX1 INP1", "RX5", "I2S RX5"}, + {"RX4 MIX1 INP2", "RX4", "I2S RX4"}, + {"RX4 MIX1 INP2", "RX5", "I2S RX5"}, + {"RX5 MIX1 INP1", "RX4", "I2S RX4"}, + {"RX5 MIX1 INP1", "RX5", "I2S RX5"}, + {"RX5 MIX1 INP2", "RX4", "I2S RX4"}, + {"RX5 MIX1 INP2", "RX5", "I2S RX5"}, + + {"RX4 MIX1", NULL, "RX4 MIX1 INP1"}, + {"RX4 MIX1", NULL, "RX4 MIX1 INP2"}, + {"RX5 MIX1", NULL, "RX5 MIX1 INP1"}, + {"RX5 MIX1", NULL, "RX5 MIX1 INP2"}, + + {"RX INT4 INTERP", NULL, "RX4 MIX1"}, + {"RX INT4 CHAIN", NULL, "RX INT4 INTERP"}, + {"SPK1 OUT", NULL, "RX INT4 CHAIN"}, + + {"RX INT5 INTERP", NULL, "RX5 MIX1"}, + {"RX INT5 CHAIN", NULL, "RX INT5 INTERP"}, + {"SPK2 OUT", NULL, "RX INT5 CHAIN"}, +}; + +static const struct msm_sdw_reg_mask_val msm_sdw_reg_init[] = { + {MSM_SDW_BOOST0_BOOST_CFG1, 0x3F, 0x12}, + {MSM_SDW_BOOST0_BOOST_CFG2, 0x1C, 0x08}, + {MSM_SDW_COMPANDER7_CTL7, 0x1E, 0x18}, + {MSM_SDW_BOOST1_BOOST_CFG1, 0x3F, 0x12}, + {MSM_SDW_BOOST1_BOOST_CFG2, 0x1C, 0x08}, + {MSM_SDW_COMPANDER8_CTL7, 0x1E, 0x18}, + {MSM_SDW_BOOST0_BOOST_CTL, 0x7C, 0x58}, + {MSM_SDW_BOOST1_BOOST_CTL, 0x7C, 0x58}, + {MSM_SDW_RX7_RX_PATH_CFG1, 0x08, 0x08}, + {MSM_SDW_RX8_RX_PATH_CFG1, 0x08, 0x08}, + {MSM_SDW_TOP_TOP_CFG1, 0x02, 0x02}, + {MSM_SDW_TOP_TOP_CFG1, 0x01, 0x01}, + {MSM_SDW_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_COMPANDER7_CTL3, 0x80, 0x80}, + {MSM_SDW_COMPANDER8_CTL3, 0x80, 0x80}, + {MSM_SDW_COMPANDER7_CTL7, 0x01, 0x01}, + {MSM_SDW_COMPANDER8_CTL7, 0x01, 0x01}, + {MSM_SDW_RX7_RX_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_RX8_RX_PATH_CFG0, 0x01, 0x01}, + {MSM_SDW_RX7_RX_PATH_MIX_CFG, 0x01, 0x01}, + {MSM_SDW_RX8_RX_PATH_MIX_CFG, 0x01, 0x01}, +}; + +static void msm_sdw_init_reg(struct snd_soc_component *component) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(msm_sdw_reg_init); i++) + snd_soc_component_update_bits(component, + msm_sdw_reg_init[i].reg, + msm_sdw_reg_init[i].mask, + msm_sdw_reg_init[i].val); +} + +static int msm_sdw_notifier_service_cb(struct notifier_block *nb, + unsigned long opcode, void *ptr) +{ + int i; + struct msm_sdw_priv *msm_sdw = container_of(nb, + struct msm_sdw_priv, + service_nb); + bool adsp_ready = false; + unsigned long timeout; + static bool initial_boot = true; + + pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); + + mutex_lock(&msm_sdw->codec_mutex); + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + if (initial_boot) { + initial_boot = false; + break; + } + msm_sdw->int_mclk1_enabled = false; + msm_sdw->dev_up = false; + for (i = 0; i < msm_sdw->nr; i++) + swrm_wcd_notify(msm_sdw->sdw_ctrl_data[i].sdw_pdev, + SWR_DEVICE_DOWN, NULL); + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (initial_boot) + initial_boot = false; + if (!q6core_is_adsp_ready()) { + dev_dbg(msm_sdw->dev, "ADSP isn't ready\n"); + timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + while (!time_after(jiffies, timeout)) { + if (!q6core_is_adsp_ready()) { + dev_dbg(msm_sdw->dev, + "ADSP isn't ready\n"); + } else { + dev_dbg(msm_sdw->dev, + "ADSP is ready\n"); + adsp_ready = true; + goto powerup; + } + } + } else { + adsp_ready = true; + dev_dbg(msm_sdw->dev, "%s: DSP is ready\n", __func__); + } +powerup: + if (adsp_ready) { + msm_sdw->dev_up = true; + msm_sdw_init_reg(msm_sdw->component); + regcache_mark_dirty(msm_sdw->regmap); + regcache_sync(msm_sdw->regmap); + msm_sdw_set_spkr_mode(msm_sdw->component, + msm_sdw->spkr_mode); + } + break; + default: + break; + } + mutex_unlock(&msm_sdw->codec_mutex); + return NOTIFY_OK; +} + +static int msm_sdw_codec_probe(struct snd_soc_component *component) +{ + struct msm_sdw_priv *msm_sdw; + int i, ret; + + msm_sdw = snd_soc_component_get_drvdata(component); + if (!msm_sdw) { + pr_err("%s:SDW priv data null\n", __func__); + return -EINVAL; + } + msm_sdw->component = component; + for (i = 0; i < COMP_MAX; i++) + msm_sdw->comp_enabled[i] = 0; + + msm_sdw->spkr_gain_offset = RX_GAIN_OFFSET_0_DB; + msm_sdw_init_reg(component); + msm_sdw->version = MSM_SDW_VERSION_1_0; + + msm_sdw->service_nb.notifier_call = msm_sdw_notifier_service_cb; + ret = audio_notifier_register("msm_sdw", + AUDIO_NOTIFIER_ADSP_DOMAIN, + &msm_sdw->service_nb); + if (ret < 0) + dev_err(msm_sdw->dev, + "%s: Audio notifier register failed ret = %d\n", + __func__, ret); + return 0; +} + +static void msm_sdw_codec_remove(struct snd_soc_component *component) +{ +} + +static const struct snd_soc_component_driver soc_codec_dev_msm_sdw = { + .name = DRV_NAME, + .probe = msm_sdw_codec_probe, + .remove = msm_sdw_codec_remove, + .controls = msm_sdw_snd_controls, + .num_controls = ARRAY_SIZE(msm_sdw_snd_controls), + .dapm_widgets = msm_sdw_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(msm_sdw_dapm_widgets), + .dapm_routes = audio_map, + .num_dapm_routes = ARRAY_SIZE(audio_map), +}; + +static void msm_sdw_add_child_devices(struct work_struct *work) +{ + struct msm_sdw_priv *msm_sdw; + struct platform_device *pdev; + struct device_node *node; + struct msm_sdw_ctrl_data *sdw_ctrl_data = NULL, *temp; + int ret, ctrl_num = 0; + struct wcd_sdw_ctrl_platform_data *platdata; + char plat_dev_name[MSM_SDW_STRING_LEN]; + + msm_sdw = container_of(work, struct msm_sdw_priv, + msm_sdw_add_child_devices_work); + if (!msm_sdw) { + pr_err("%s: Memory for msm_sdw does not exist\n", + __func__); + return; + } + if (!msm_sdw->dev->of_node) { + dev_err(msm_sdw->dev, + "%s: DT node for msm_sdw does not exist\n", __func__); + return; + } + + platdata = &msm_sdw->sdw_plat_data; + + for_each_available_child_of_node(msm_sdw->dev->of_node, node) { + if (!strcmp(node->name, "swr_master")) + strlcpy(plat_dev_name, "msm_sdw_swr_ctrl", + (MSM_SDW_STRING_LEN - 1)); + else if (strnstr(node->name, "msm_cdc_pinctrl", + strlen("msm_cdc_pinctrl")) != NULL) + strlcpy(plat_dev_name, node->name, + (MSM_SDW_STRING_LEN - 1)); + else + continue; + + pdev = platform_device_alloc(plat_dev_name, -1); + if (!pdev) { + dev_err(msm_sdw->dev, "%s: pdev memory alloc failed\n", + __func__); + ret = -ENOMEM; + goto err; + } + pdev->dev.parent = msm_sdw->dev; + pdev->dev.of_node = node; + + if (!strcmp(node->name, "swr_master")) { + ret = platform_device_add_data(pdev, platdata, + sizeof(*platdata)); + if (ret) { + dev_err(&pdev->dev, + "%s: cannot add plat data ctrl:%d\n", + __func__, ctrl_num); + goto fail_pdev_add; + } + } + + ret = platform_device_add(pdev); + if (ret) { + dev_err(&pdev->dev, + "%s: Cannot add platform device\n", + __func__); + goto fail_pdev_add; + } + + if (!strcmp(node->name, "swr_master")) { + temp = krealloc(sdw_ctrl_data, + (ctrl_num + 1) * sizeof( + struct msm_sdw_ctrl_data), + GFP_KERNEL); + if (!temp) { + dev_err(&pdev->dev, "out of memory\n"); + ret = -ENOMEM; + goto err; + } + sdw_ctrl_data = temp; + sdw_ctrl_data[ctrl_num].sdw_pdev = pdev; + ctrl_num++; + dev_dbg(&pdev->dev, + "%s: Added soundwire ctrl device(s)\n", + __func__); + msm_sdw->nr = ctrl_num; + msm_sdw->sdw_ctrl_data = sdw_ctrl_data; + } + msm_sdw->pdev_child_devices[msm_sdw->child_count++] = pdev; + } + + return; +fail_pdev_add: + platform_device_put(pdev); +err: + return; +} + +static int msm_sdw_probe(struct platform_device *pdev) +{ + int ret = 0; + struct msm_sdw_priv *msm_sdw; + int adsp_state; + + adsp_state = apr_get_subsys_state(); + if (adsp_state != APR_SUBSYS_LOADED) { + dev_err(&pdev->dev, "Adsp is not loaded yet %d\n", + adsp_state); + return -EPROBE_DEFER; + } + + msm_sdw = devm_kzalloc(&pdev->dev, sizeof(struct msm_sdw_priv), + GFP_KERNEL); + if (!msm_sdw) + return -ENOMEM; + dev_set_drvdata(&pdev->dev, msm_sdw); + msm_sdw->dev_up = true; + + msm_sdw->dev = &pdev->dev; + INIT_WORK(&msm_sdw->msm_sdw_add_child_devices_work, + msm_sdw_add_child_devices); + msm_sdw->sdw_plat_data.handle = (void *) msm_sdw; + msm_sdw->sdw_plat_data.read = msm_sdw_swrm_read; + msm_sdw->sdw_plat_data.write = msm_sdw_swrm_write; + msm_sdw->sdw_plat_data.bulk_write = msm_sdw_swrm_bulk_write; + msm_sdw->sdw_plat_data.clk = msm_sdw_swrm_clock; + msm_sdw->sdw_plat_data.handle_irq = msm_sdwm_handle_irq; + ret = of_property_read_u32(pdev->dev.of_node, "reg", + &msm_sdw->sdw_base_addr); + if (ret) { + dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "reg"); + goto err_sdw_cdc; + } + + msm_sdw->sdw_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-sdw-gpios", 0); + msm_sdw->sdw_base = ioremap(msm_sdw->sdw_base_addr, + MSM_SDW_MAX_REGISTER); + msm_sdw->read_dev = __msm_sdw_reg_read; + msm_sdw->write_dev = __msm_sdw_reg_write; + + msm_sdw->regmap = msm_sdw_regmap_init(msm_sdw->dev, + &msm_sdw_regmap_config); + msm_sdw->sdw_irq = platform_get_irq_byname(pdev, "swr_master_irq"); + if (msm_sdw->sdw_irq < 0) { + dev_err(msm_sdw->dev, "%s() error getting irq handle: %d\n", + __func__, msm_sdw->sdw_irq); + ret = -ENODEV; + goto err_sdw_cdc; + } + ret = snd_soc_register_component(&pdev->dev, &soc_codec_dev_msm_sdw, + msm_sdw_dai, ARRAY_SIZE(msm_sdw_dai)); + if (ret) { + dev_err(&pdev->dev, "%s: Codec registration failed, ret = %d\n", + __func__, ret); + goto err_sdw_cdc; + } + /* initialize the int_mclk1 */ + msm_sdw->sdw_cdc_core_clk.clk_set_minor_version = + AFE_API_VERSION_I2S_CONFIG; + msm_sdw->sdw_cdc_core_clk.clk_id = + Q6AFE_LPASS_CLK_ID_INT_MCLK_1; + msm_sdw->sdw_cdc_core_clk.clk_freq_in_hz = + INT_MCLK1_FREQ; + msm_sdw->sdw_cdc_core_clk.clk_attri = + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO; + msm_sdw->sdw_cdc_core_clk.clk_root = + Q6AFE_LPASS_CLK_ROOT_DEFAULT; + msm_sdw->sdw_cdc_core_clk.enable = 0; + + /* initialize the sdw_npl_clk */ + msm_sdw->sdw_npl_clk.clk_set_minor_version = + AFE_API_VERSION_I2S_CONFIG; + msm_sdw->sdw_npl_clk.clk_id = + AFE_CLOCK_SET_CLOCK_ID_SWR_NPL_CLK; + msm_sdw->sdw_npl_clk.clk_freq_in_hz = SDW_NPL_FREQ; + msm_sdw->sdw_npl_clk.clk_attri = + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO; + msm_sdw->sdw_npl_clk.clk_root = + Q6AFE_LPASS_CLK_ROOT_DEFAULT; + msm_sdw->sdw_npl_clk.enable = 0; + + INIT_DELAYED_WORK(&msm_sdw->disable_int_mclk1_work, + msm_disable_int_mclk1); + mutex_init(&msm_sdw->cdc_int_mclk1_mutex); + mutex_init(&msm_sdw->sdw_npl_clk_mutex); + mutex_init(&msm_sdw->io_lock); + mutex_init(&msm_sdw->sdw_read_lock); + mutex_init(&msm_sdw->sdw_write_lock); + mutex_init(&msm_sdw->sdw_clk_lock); + mutex_init(&msm_sdw->codec_mutex); + schedule_work(&msm_sdw->msm_sdw_add_child_devices_work); + + dev_dbg(&pdev->dev, "%s: msm_sdw driver probe done\n", __func__); + return ret; + +err_sdw_cdc: + devm_kfree(&pdev->dev, msm_sdw); + return ret; +} + +static int msm_sdw_remove(struct platform_device *pdev) +{ + struct msm_sdw_priv *msm_sdw; + int count; + + msm_sdw = dev_get_drvdata(&pdev->dev); + + for (count = 0; count < msm_sdw->child_count && + count < MSM_SDW_CHILD_DEVICES_MAX; count++) + platform_device_unregister(msm_sdw->pdev_child_devices[count]); + + mutex_destroy(&msm_sdw->io_lock); + mutex_destroy(&msm_sdw->sdw_read_lock); + mutex_destroy(&msm_sdw->sdw_write_lock); + mutex_destroy(&msm_sdw->sdw_clk_lock); + mutex_destroy(&msm_sdw->codec_mutex); + mutex_destroy(&msm_sdw->cdc_int_mclk1_mutex); + + devm_kfree(&pdev->dev, msm_sdw); + snd_soc_unregister_component(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_sdw_codec_dt_match[] = { + { .compatible = "qcom,msm-sdw-codec", }, + {} +}; + +static struct platform_driver msm_sdw_codec_driver = { + .probe = msm_sdw_probe, + .remove = msm_sdw_remove, + .driver = { + .name = "msm_sdw_codec", + .owner = THIS_MODULE, + .of_match_table = msm_sdw_codec_dt_match, + }, +}; +module_platform_driver(msm_sdw_codec_driver); + +MODULE_DESCRIPTION("MSM Soundwire Codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/msm_sdw/msm_sdw_cdc_utils.c b/asoc/codecs/msm_sdw/msm_sdw_cdc_utils.c new file mode 100644 index 000000000000..49759d87feea --- /dev/null +++ b/asoc/codecs/msm_sdw/msm_sdw_cdc_utils.c @@ -0,0 +1,204 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2016-2017, 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include "msm_sdw.h" + +#define REG_BYTES 2 +#define VAL_BYTES 1 +/* + * Page Register Address that APP Proc uses to + * access WCD9335 Codec registers is identified + * as 0x00 + */ +#define PAGE_REG_ADDR 0x00 + +/* + * msm_sdw_page_write: + * Retrieve page number from register and + * write that page number to the page address. + * Called under io_lock acquisition. + * + * @msm_sdw: pointer to msm_sdw + * @reg: Register address from which page number is retrieved + * + * Returns 0 for success and negative error code for failure. + */ +int msm_sdw_page_write(struct msm_sdw_priv *msm_sdw, unsigned short reg) +{ + int ret = 0; + u8 pg_num, prev_pg_num; + + pg_num = msm_sdw_page_map[reg]; + if (msm_sdw->prev_pg_valid) { + prev_pg_num = msm_sdw->prev_pg; + if (prev_pg_num != pg_num) { + ret = msm_sdw->write_dev(msm_sdw, PAGE_REG_ADDR, 1, + (void *) &pg_num); + if (ret < 0) { + dev_err(msm_sdw->dev, + "page write error, pg_num: 0x%x\n", + pg_num); + } else { + msm_sdw->prev_pg = pg_num; + dev_dbg(msm_sdw->dev, + "%s: Page 0x%x Write to 0x00\n", + __func__, pg_num); + } + } + } else { + ret = msm_sdw->write_dev(msm_sdw, PAGE_REG_ADDR, 1, + (void *) &pg_num); + if (ret < 0) { + dev_err(msm_sdw->dev, + "page write error, pg_num: 0x%x\n", pg_num); + } else { + msm_sdw->prev_pg = pg_num; + msm_sdw->prev_pg_valid = true; + dev_dbg(msm_sdw->dev, "%s: Page 0x%x Write to 0x00\n", + __func__, pg_num); + } + } + return ret; +} +EXPORT_SYMBOL(msm_sdw_page_write); + +static int regmap_bus_read(void *context, const void *reg, size_t reg_size, + void *val, size_t val_size) +{ + struct device *dev = context; + struct msm_sdw_priv *msm_sdw = dev_get_drvdata(dev); + unsigned short c_reg; + int ret, i; + + if (!msm_sdw) { + dev_err(dev, "%s: msm_sdw is NULL\n", __func__); + return -EINVAL; + } + if (!reg || !val) { + dev_err(dev, "%s: reg or val is NULL\n", __func__); + return -EINVAL; + } + if (reg_size != REG_BYTES) { + dev_err(dev, "%s: register size %zd bytes, not supported\n", + __func__, reg_size); + return -EINVAL; + } + if (!msm_sdw->dev_up) { + dev_dbg_ratelimited(dev, "%s: No read allowed. dev_up = %d\n", + __func__, msm_sdw->dev_up); + return 0; + } + + mutex_lock(&msm_sdw->io_lock); + c_reg = *(u16 *)reg; + ret = msm_sdw_page_write(msm_sdw, c_reg); + if (ret) + goto err; + ret = msm_sdw->read_dev(msm_sdw, c_reg, val_size, val); + if (ret < 0) + dev_err(dev, "%s: Codec read failed (%d), reg: 0x%x, size:%zd\n", + __func__, ret, c_reg, val_size); + else { + for (i = 0; i < val_size; i++) + dev_dbg(dev, "%s: Read 0x%02x from 0x%x\n", + __func__, ((u8 *)val)[i], c_reg + i); + } +err: + mutex_unlock(&msm_sdw->io_lock); + + return ret; +} + +static int regmap_bus_gather_write(void *context, + const void *reg, size_t reg_size, + const void *val, size_t val_size) +{ + struct device *dev = context; + struct msm_sdw_priv *msm_sdw = dev_get_drvdata(dev); + unsigned short c_reg; + int ret, i; + + if (!msm_sdw) { + dev_err(dev, "%s: msm_sdw is NULL\n", __func__); + return -EINVAL; + } + if (!reg || !val) { + dev_err(dev, "%s: reg or val is NULL\n", __func__); + return -EINVAL; + } + if (reg_size != REG_BYTES) { + dev_err(dev, "%s: register size %zd bytes, not supported\n", + __func__, reg_size); + return -EINVAL; + } + if (!msm_sdw->dev_up) { + dev_dbg_ratelimited(dev, "%s: No write allowed. dev_up = %d\n", + __func__, msm_sdw->dev_up); + return 0; + } + + mutex_lock(&msm_sdw->io_lock); + c_reg = *(u16 *)reg; + ret = msm_sdw_page_write(msm_sdw, c_reg); + if (ret) + goto err; + + for (i = 0; i < val_size; i++) + dev_dbg(dev, "Write %02x to 0x%x\n", ((u8 *)val)[i], + c_reg + i*4); + + ret = msm_sdw->write_dev(msm_sdw, c_reg, val_size, (void *) val); + if (ret < 0) + dev_err(dev, + "%s: Codec write failed (%d), reg:0x%x, size:%zd\n", + __func__, ret, c_reg, val_size); + +err: + mutex_unlock(&msm_sdw->io_lock); + return ret; +} + +static int regmap_bus_write(void *context, const void *data, size_t count) +{ + struct device *dev = context; + struct msm_sdw_priv *msm_sdw = dev_get_drvdata(dev); + + if (!msm_sdw) + return -EINVAL; + + WARN_ON(count < REG_BYTES); + + return regmap_bus_gather_write(context, data, REG_BYTES, + data + REG_BYTES, + count - REG_BYTES); + +} + +static struct regmap_bus regmap_bus_config = { + .write = regmap_bus_write, + .gather_write = regmap_bus_gather_write, + .read = regmap_bus_read, + .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, + .val_format_endian_default = REGMAP_ENDIAN_NATIVE, +}; + +/* + * msm_sdw_regmap_init: + * Initialize msm_sdw register map + * + * @dev: pointer to wcd device + * @config: pointer to register map config + * + * Returns pointer to regmap structure for success + * or NULL in case of failure. + */ +struct regmap *msm_sdw_regmap_init(struct device *dev, + const struct regmap_config *config) +{ + return devm_regmap_init(dev, ®map_bus_config, dev, config); +} +EXPORT_SYMBOL(msm_sdw_regmap_init); diff --git a/asoc/codecs/msm_sdw/msm_sdw_registers.h b/asoc/codecs/msm_sdw/msm_sdw_registers.h new file mode 100644 index 000000000000..f095dd5ec358 --- /dev/null +++ b/asoc/codecs/msm_sdw/msm_sdw_registers.h @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2016-2017, 2020, The Linux Foundation. All rights reserved. + */ +#ifndef MSM_SDW_REGISTERS_H +#define MSM_SDW_REGISTERS_H + +#define MSM_SDW_PAGE_REGISTER 0x0000 + +/* Page-A Registers */ +#define MSM_SDW_TX9_SPKR_PROT_PATH_CTL 0x0308 +#define MSM_SDW_TX9_SPKR_PROT_PATH_CFG0 0x030c +#define MSM_SDW_TX10_SPKR_PROT_PATH_CTL 0x0318 +#define MSM_SDW_TX10_SPKR_PROT_PATH_CFG0 0x031c +#define MSM_SDW_TX11_SPKR_PROT_PATH_CTL 0x0328 +#define MSM_SDW_TX11_SPKR_PROT_PATH_CFG0 0x032c +#define MSM_SDW_TX12_SPKR_PROT_PATH_CTL 0x0338 +#define MSM_SDW_TX12_SPKR_PROT_PATH_CFG0 0x033c + +/* Page-B Registers */ +#define MSM_SDW_COMPANDER7_CTL0 0x0024 +#define MSM_SDW_COMPANDER7_CTL1 0x0028 +#define MSM_SDW_COMPANDER7_CTL2 0x002c +#define MSM_SDW_COMPANDER7_CTL3 0x0030 +#define MSM_SDW_COMPANDER7_CTL4 0x0034 +#define MSM_SDW_COMPANDER7_CTL5 0x0038 +#define MSM_SDW_COMPANDER7_CTL6 0x003c +#define MSM_SDW_COMPANDER7_CTL7 0x0040 +#define MSM_SDW_COMPANDER8_CTL0 0x0044 +#define MSM_SDW_COMPANDER8_CTL1 0x0048 +#define MSM_SDW_COMPANDER8_CTL2 0x004c +#define MSM_SDW_COMPANDER8_CTL3 0x0050 +#define MSM_SDW_COMPANDER8_CTL4 0x0054 +#define MSM_SDW_COMPANDER8_CTL5 0x0058 +#define MSM_SDW_COMPANDER8_CTL6 0x005c +#define MSM_SDW_COMPANDER8_CTL7 0x0060 +#define MSM_SDW_RX7_RX_PATH_CTL 0x01a4 +#define MSM_SDW_RX7_RX_PATH_CFG0 0x01a8 +#define MSM_SDW_RX7_RX_PATH_CFG1 0x01ac +#define MSM_SDW_RX7_RX_PATH_CFG2 0x01b0 +#define MSM_SDW_RX7_RX_VOL_CTL 0x01b4 +#define MSM_SDW_RX7_RX_PATH_MIX_CTL 0x01b8 +#define MSM_SDW_RX7_RX_PATH_MIX_CFG 0x01bc +#define MSM_SDW_RX7_RX_VOL_MIX_CTL 0x01c0 +#define MSM_SDW_RX7_RX_PATH_SEC0 0x01c4 +#define MSM_SDW_RX7_RX_PATH_SEC1 0x01c8 +#define MSM_SDW_RX7_RX_PATH_SEC2 0x01cc +#define MSM_SDW_RX7_RX_PATH_SEC3 0x01d0 +#define MSM_SDW_RX7_RX_PATH_SEC5 0x01d8 +#define MSM_SDW_RX7_RX_PATH_SEC6 0x01dc +#define MSM_SDW_RX7_RX_PATH_SEC7 0x01e0 +#define MSM_SDW_RX7_RX_PATH_MIX_SEC0 0x01e4 +#define MSM_SDW_RX7_RX_PATH_MIX_SEC1 0x01e8 +#define MSM_SDW_RX8_RX_PATH_CTL 0x0384 +#define MSM_SDW_RX8_RX_PATH_CFG0 0x0388 +#define MSM_SDW_RX8_RX_PATH_CFG1 0x038c +#define MSM_SDW_RX8_RX_PATH_CFG2 0x0390 +#define MSM_SDW_RX8_RX_VOL_CTL 0x0394 +#define MSM_SDW_RX8_RX_PATH_MIX_CTL 0x0398 +#define MSM_SDW_RX8_RX_PATH_MIX_CFG 0x039c +#define MSM_SDW_RX8_RX_VOL_MIX_CTL 0x03a0 +#define MSM_SDW_RX8_RX_PATH_SEC0 0x03a4 +#define MSM_SDW_RX8_RX_PATH_SEC1 0x03a8 +#define MSM_SDW_RX8_RX_PATH_SEC2 0x03ac +#define MSM_SDW_RX8_RX_PATH_SEC3 0x03b0 +#define MSM_SDW_RX8_RX_PATH_SEC5 0x03b8 +#define MSM_SDW_RX8_RX_PATH_SEC6 0x03bc +#define MSM_SDW_RX8_RX_PATH_SEC7 0x03c0 +#define MSM_SDW_RX8_RX_PATH_MIX_SEC0 0x03c4 +#define MSM_SDW_RX8_RX_PATH_MIX_SEC1 0x03c8 + +/* Page-C Registers */ +#define MSM_SDW_BOOST0_BOOST_PATH_CTL 0x0064 +#define MSM_SDW_BOOST0_BOOST_CTL 0x0068 +#define MSM_SDW_BOOST0_BOOST_CFG1 0x006c +#define MSM_SDW_BOOST0_BOOST_CFG2 0x0070 +#define MSM_SDW_BOOST1_BOOST_PATH_CTL 0x0084 +#define MSM_SDW_BOOST1_BOOST_CTL 0x0088 +#define MSM_SDW_BOOST1_BOOST_CFG1 0x008c +#define MSM_SDW_BOOST1_BOOST_CFG2 0x0090 +#define MSM_SDW_AHB_BRIDGE_WR_DATA_0 0x00a4 +#define MSM_SDW_AHB_BRIDGE_WR_DATA_1 0x00a8 +#define MSM_SDW_AHB_BRIDGE_WR_DATA_2 0x00ac +#define MSM_SDW_AHB_BRIDGE_WR_DATA_3 0x00b0 +#define MSM_SDW_AHB_BRIDGE_WR_ADDR_0 0x00b4 +#define MSM_SDW_AHB_BRIDGE_WR_ADDR_1 0x00b8 +#define MSM_SDW_AHB_BRIDGE_WR_ADDR_2 0x00bc +#define MSM_SDW_AHB_BRIDGE_WR_ADDR_3 0x00c0 +#define MSM_SDW_AHB_BRIDGE_RD_ADDR_0 0x00c4 +#define MSM_SDW_AHB_BRIDGE_RD_ADDR_1 0x00c8 +#define MSM_SDW_AHB_BRIDGE_RD_ADDR_2 0x00cc +#define MSM_SDW_AHB_BRIDGE_RD_ADDR_3 0x00d0 +#define MSM_SDW_AHB_BRIDGE_RD_DATA_0 0x00d4 +#define MSM_SDW_AHB_BRIDGE_RD_DATA_1 0x00d8 +#define MSM_SDW_AHB_BRIDGE_RD_DATA_2 0x00dc +#define MSM_SDW_AHB_BRIDGE_RD_DATA_3 0x00e0 +#define MSM_SDW_AHB_BRIDGE_ACCESS_CFG 0x00e4 +#define MSM_SDW_AHB_BRIDGE_ACCESS_STATUS 0x00e8 + +/* Page-D Registers */ +#define MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL 0x0104 +#define MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL 0x0108 +#define MSM_SDW_CLK_RST_CTRL_SWR_CONTROL 0x010c +#define MSM_SDW_TOP_TOP_CFG0 0x0204 +#define MSM_SDW_TOP_TOP_CFG1 0x0208 +#define MSM_SDW_TOP_RX_I2S_CTL 0x020c +#define MSM_SDW_TOP_TX_I2S_CTL 0x0210 +#define MSM_SDW_TOP_I2S_CLK 0x0214 +#define MSM_SDW_TOP_RX7_PATH_INPUT0_MUX 0x0218 +#define MSM_SDW_TOP_RX7_PATH_INPUT1_MUX 0x021c +#define MSM_SDW_TOP_RX8_PATH_INPUT0_MUX 0x0220 +#define MSM_SDW_TOP_RX8_PATH_INPUT1_MUX 0x0224 +#define MSM_SDW_TOP_FREQ_MCLK 0x0228 +#define MSM_SDW_TOP_DEBUG_BUS_SEL 0x022c +#define MSM_SDW_TOP_DEBUG_EN 0x0230 +#define MSM_SDW_TOP_I2S_RESET 0x0234 +#define MSM_SDW_TOP_BLOCKS_RESET 0x0238 + +#endif diff --git a/asoc/codecs/msm_sdw/msm_sdw_regmap.c b/asoc/codecs/msm_sdw/msm_sdw_regmap.c new file mode 100644 index 000000000000..7ddea7304e87 --- /dev/null +++ b/asoc/codecs/msm_sdw/msm_sdw_regmap.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include "msm_sdw.h" + +static const struct reg_default msm_sdw_defaults[] = { + /* Page #10 registers */ + { MSM_SDW_PAGE_REGISTER, 0x00 }, + { MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x02 }, + { MSM_SDW_TX9_SPKR_PROT_PATH_CFG0, 0x00 }, + { MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x02 }, + { MSM_SDW_TX10_SPKR_PROT_PATH_CFG0, 0x00 }, + { MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x02 }, + { MSM_SDW_TX11_SPKR_PROT_PATH_CFG0, 0x00 }, + { MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x02 }, + { MSM_SDW_TX12_SPKR_PROT_PATH_CFG0, 0x00 }, + /* Page #11 registers */ + { MSM_SDW_COMPANDER7_CTL0, 0x60 }, + { MSM_SDW_COMPANDER7_CTL1, 0xdb }, + { MSM_SDW_COMPANDER7_CTL2, 0xff }, + { MSM_SDW_COMPANDER7_CTL3, 0x35 }, + { MSM_SDW_COMPANDER7_CTL4, 0xff }, + { MSM_SDW_COMPANDER7_CTL5, 0x00 }, + { MSM_SDW_COMPANDER7_CTL6, 0x01 }, + { MSM_SDW_COMPANDER8_CTL0, 0x60 }, + { MSM_SDW_COMPANDER8_CTL1, 0xdb }, + { MSM_SDW_COMPANDER8_CTL2, 0xff }, + { MSM_SDW_COMPANDER8_CTL3, 0x35 }, + { MSM_SDW_COMPANDER8_CTL4, 0xff }, + { MSM_SDW_COMPANDER8_CTL5, 0x00 }, + { MSM_SDW_COMPANDER8_CTL6, 0x01 }, + { MSM_SDW_RX7_RX_PATH_CTL, 0x04 }, + { MSM_SDW_RX7_RX_PATH_CFG0, 0x00 }, + { MSM_SDW_RX7_RX_PATH_CFG2, 0x8f }, + { MSM_SDW_RX7_RX_VOL_CTL, 0x00 }, + { MSM_SDW_RX7_RX_PATH_MIX_CTL, 0x04 }, + { MSM_SDW_RX7_RX_VOL_MIX_CTL, 0x00 }, + { MSM_SDW_RX7_RX_PATH_SEC2, 0x00 }, + { MSM_SDW_RX7_RX_PATH_SEC3, 0x00 }, + { MSM_SDW_RX7_RX_PATH_SEC5, 0x00 }, + { MSM_SDW_RX7_RX_PATH_SEC6, 0x00 }, + { MSM_SDW_RX7_RX_PATH_SEC7, 0x00 }, + { MSM_SDW_RX7_RX_PATH_MIX_SEC1, 0x00 }, + { MSM_SDW_RX8_RX_PATH_CTL, 0x04 }, + { MSM_SDW_RX8_RX_PATH_CFG0, 0x00 }, + { MSM_SDW_RX8_RX_PATH_CFG2, 0x8f }, + { MSM_SDW_RX8_RX_VOL_CTL, 0x00 }, + { MSM_SDW_RX8_RX_PATH_MIX_CTL, 0x04 }, + { MSM_SDW_RX8_RX_VOL_MIX_CTL, 0x00 }, + { MSM_SDW_RX8_RX_PATH_SEC2, 0x00 }, + { MSM_SDW_RX8_RX_PATH_SEC3, 0x00 }, + { MSM_SDW_RX8_RX_PATH_SEC5, 0x00 }, + { MSM_SDW_RX8_RX_PATH_SEC6, 0x00 }, + { MSM_SDW_RX8_RX_PATH_SEC7, 0x00 }, + { MSM_SDW_RX8_RX_PATH_MIX_SEC1, 0x00 }, + /* Page #12 registers */ + { MSM_SDW_BOOST0_BOOST_PATH_CTL, 0x00 }, + { MSM_SDW_BOOST0_BOOST_CTL, 0xb2 }, + { MSM_SDW_BOOST0_BOOST_CFG1, 0x00 }, + { MSM_SDW_BOOST0_BOOST_CFG2, 0x00 }, + { MSM_SDW_BOOST1_BOOST_PATH_CTL, 0x00 }, + { MSM_SDW_BOOST1_BOOST_CTL, 0xb2 }, + { MSM_SDW_BOOST1_BOOST_CFG1, 0x00 }, + { MSM_SDW_BOOST1_BOOST_CFG2, 0x00 }, + { MSM_SDW_AHB_BRIDGE_WR_DATA_0, 0x00 }, + { MSM_SDW_AHB_BRIDGE_WR_DATA_1, 0x00 }, + { MSM_SDW_AHB_BRIDGE_WR_DATA_2, 0x00 }, + { MSM_SDW_AHB_BRIDGE_WR_DATA_3, 0x00 }, + { MSM_SDW_AHB_BRIDGE_WR_ADDR_0, 0x00 }, + { MSM_SDW_AHB_BRIDGE_WR_ADDR_1, 0x00 }, + { MSM_SDW_AHB_BRIDGE_WR_ADDR_2, 0x00 }, + { MSM_SDW_AHB_BRIDGE_WR_ADDR_3, 0x00 }, + { MSM_SDW_AHB_BRIDGE_RD_ADDR_0, 0x00 }, + { MSM_SDW_AHB_BRIDGE_RD_ADDR_1, 0x00 }, + { MSM_SDW_AHB_BRIDGE_RD_ADDR_2, 0x00 }, + { MSM_SDW_AHB_BRIDGE_RD_ADDR_3, 0x00 }, + { MSM_SDW_AHB_BRIDGE_RD_DATA_0, 0x00 }, + { MSM_SDW_AHB_BRIDGE_RD_DATA_1, 0x00 }, + { MSM_SDW_AHB_BRIDGE_RD_DATA_2, 0x00 }, + { MSM_SDW_AHB_BRIDGE_RD_DATA_3, 0x00 }, + { MSM_SDW_AHB_BRIDGE_ACCESS_CFG, 0x0f }, + { MSM_SDW_AHB_BRIDGE_ACCESS_STATUS, 0x03 }, + /* Page #13 registers */ + { MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL, 0x00 }, + { MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00 }, + { MSM_SDW_CLK_RST_CTRL_SWR_CONTROL, 0x00 }, + { MSM_SDW_TOP_TOP_CFG0, 0x00 }, + { MSM_SDW_TOP_TOP_CFG1, 0x00 }, + { MSM_SDW_TOP_RX_I2S_CTL, 0x0C }, + { MSM_SDW_TOP_TX_I2S_CTL, 0x00 }, + { MSM_SDW_TOP_I2S_CLK, 0x00 }, + { MSM_SDW_TOP_RX7_PATH_INPUT0_MUX, 0x00 }, + { MSM_SDW_TOP_RX7_PATH_INPUT1_MUX, 0x00 }, + { MSM_SDW_TOP_RX8_PATH_INPUT0_MUX, 0x00 }, + { MSM_SDW_TOP_RX8_PATH_INPUT1_MUX, 0x00 }, + { MSM_SDW_TOP_FREQ_MCLK, 0x00 }, + { MSM_SDW_TOP_DEBUG_BUS_SEL, 0x00 }, + { MSM_SDW_TOP_DEBUG_EN, 0x00 }, + { MSM_SDW_TOP_I2S_RESET, 0x00 }, + { MSM_SDW_TOP_BLOCKS_RESET, 0x00 }, +}; + +static bool msm_sdw_is_readable_register(struct device *dev, unsigned int reg) +{ + return msm_sdw_reg_readable[reg]; +} + +static bool msm_sdw_is_writeable_register(struct device *dev, unsigned int reg) +{ + return msm_sdw_reg_writeable[reg]; +} + +static bool msm_sdw_is_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MSM_SDW_AHB_BRIDGE_WR_DATA_0: + case MSM_SDW_AHB_BRIDGE_WR_DATA_1: + case MSM_SDW_AHB_BRIDGE_WR_DATA_2: + case MSM_SDW_AHB_BRIDGE_WR_DATA_3: + case MSM_SDW_AHB_BRIDGE_WR_ADDR_0: + case MSM_SDW_AHB_BRIDGE_WR_ADDR_1: + case MSM_SDW_AHB_BRIDGE_WR_ADDR_2: + case MSM_SDW_AHB_BRIDGE_WR_ADDR_3: + case MSM_SDW_AHB_BRIDGE_RD_DATA_0: + case MSM_SDW_AHB_BRIDGE_RD_DATA_1: + case MSM_SDW_AHB_BRIDGE_RD_DATA_2: + case MSM_SDW_AHB_BRIDGE_RD_DATA_3: + case MSM_SDW_AHB_BRIDGE_RD_ADDR_0: + case MSM_SDW_AHB_BRIDGE_RD_ADDR_1: + case MSM_SDW_AHB_BRIDGE_RD_ADDR_2: + case MSM_SDW_AHB_BRIDGE_RD_ADDR_3: + case MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL: + case MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL: + return true; + default: + return false; + } +} + +const struct regmap_config msm_sdw_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .reg_stride = 4, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = msm_sdw_defaults, + .num_reg_defaults = ARRAY_SIZE(msm_sdw_defaults), + .max_register = MSM_SDW_MAX_REGISTER, + .writeable_reg = msm_sdw_is_writeable_register, + .volatile_reg = msm_sdw_is_volatile_register, + .readable_reg = msm_sdw_is_readable_register, +}; diff --git a/asoc/codecs/sdm660_cdc/Android.mk b/asoc/codecs/sdm660_cdc/Android.mk new file mode 100644 index 000000000000..ced40f4b3a8b --- /dev/null +++ b/asoc/codecs/sdm660_cdc/Android.mk @@ -0,0 +1,53 @@ +# Android makefile for audio kernel modules + +# Assume no targets will be supported + +AUDIO_CHIPSET := audio +# Build/Package only in case of supported target +ifeq ($(call is-board-platform-in-list, sdm660),true) + +LOCAL_PATH := $(call my-dir) + +# This makefile is only for DLKM +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + AUDIO_BLD_DIR := $(shell pwd)/vendor/qcom/opensource/audio-kernel +endif # opensource + +DLKM_DIR := $(TOP)/device/qcom/common/dlkm + +# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko +########################################################### +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR) + +# We are actually building audio.ko here, as per the +# requirement we are specifying _audio.ko as LOCAL_MODULE. +# This means we need to rename the module to _audio.ko +# after audio.ko is built. +KBUILD_OPTIONS += MODNAME=analog_cdc_dlkm +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(AUDIO_SELECT) + +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_analog_cdc.ko +LOCAL_MODULE_KBUILD_NAME := analog_cdc_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +include $(CLEAR_VARS) +LOCAL_MODULE := $(AUDIO_CHIPSET)_digital_cdc.ko +LOCAL_MODULE_KBUILD_NAME := digital_cdc_dlkm.ko +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_DEBUG_ENABLE := true +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### +########################################################### + +endif # DLKM check +endif # supported target check diff --git a/asoc/codecs/sdm660_cdc/Kbuild b/asoc/codecs/sdm660_cdc/Kbuild new file mode 100644 index 000000000000..c6cf4b705617 --- /dev/null +++ b/asoc/codecs/sdm660_cdc/Kbuild @@ -0,0 +1,115 @@ +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + + +ifeq ($(KERNEL_BUILD), 1) + # These are configurable via Kconfig for kernel-based builds + # Need to explicitly configure for Android-based builds + AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-4.19 + AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio +endif + +ifeq ($(KERNEL_BUILD), 0) + ifeq ($(CONFIG_ARCH_SDM660), y) + include $(AUDIO_ROOT)/config/sdm660auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h + endif +endif + +# As per target team, build is done as follows: +# Defconfig : build with default flags +# Slub : defconfig + CONFIG_SLUB_DEBUG := y + +# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y +# Perf : Using appropriate msmXXXX-perf_defconfig +# +# Shipment builds (user variants) should not have any debug feature +# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds +# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since +# there is no other way to identify defconfig builds, QTI internal +# representation of perf builds (identified using the string 'perf'), +# is used to identify if the build is a slub or defconfig one. This +# way no critical debug feature will be enabled for perf and shipment +# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT +# config. + +############ UAPI ############ +UAPI_DIR := uapi +UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR) + +############ COMMON ############ +COMMON_DIR := include +COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR) + +############ SDM660_CDC ############ + +# for SDM660_CDC Codec +ifdef CONFIG_SND_SOC_ANALOG_CDC + ANALOG_CDC_OBJS += msm-analog-cdc.o + ANALOG_CDC_OBJS += sdm660-cdc-irq.o +endif + +ifdef CONFIG_SND_SOC_DIGITAL_CDC + DIGITAL_CDC_OBJS += msm-digital-cdc.o + DIGITAL_CDC_OBJS += msm-digital-cdc-regmap.o +endif +LINUX_INC += -Iinclude/linux + +INCS += $(COMMON_INC) \ + $(UAPI_INC) + +EXTRA_CFLAGS += $(INCS) + + +CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -Werror\ + -D__linux__ + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Currently, for versions of gcc which support it, the kernel Makefile +# is disabling the maybe-uninitialized warning. Re-enable it for the +# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it +# will override the kernel settings. +ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y) +EXTRA_CFLAGS += -Wmaybe-uninitialized +endif +#EXTRA_CFLAGS += -Wmissing-prototypes + +ifeq ($(call cc-option-yn, -Wheader-guard),y) +EXTRA_CFLAGS += -Wheader-guard +endif + + +ifeq ($(KERNEL_BUILD), 0) +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers +KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers +endif + +ifeq ($(CONFIG_SND_SOC_GCOV), y) +GCOV_PROFILE := y +endif + +# Module information used by KBuild framework +obj-$(CONFIG_SND_SOC_ANALOG_CDC) += analog_cdc_dlkm.o +analog_cdc_dlkm-y := $(ANALOG_CDC_OBJS) + +obj-$(CONFIG_SND_SOC_DIGITAL_CDC) += digital_cdc_dlkm.o +digital_cdc_dlkm-y := $(DIGITAL_CDC_OBJS) + +# inject some build related information +DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc-regmap.h b/asoc/codecs/sdm660_cdc/msm-analog-cdc-regmap.h new file mode 100644 index 000000000000..404822fc8605 --- /dev/null +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc-regmap.h @@ -0,0 +1,178 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2015-2017, 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef ANALOG_CDC_REGMAP_H +#define ANALOG_CDC_REGMAP_H + +#include +#include "sdm660-cdc-registers.h" + +/* + * Default register reset values that are common across different versions + * are defined here. If a register reset value is changed based on version + * then remove it from this structure and add it in version specific + * structures. + */ + +struct reg_default + msm89xx_pmic_cdc_defaults[MSM89XX_PMIC_CDC_CACHE_SIZE] = { + {MSM89XX_PMIC_DIGITAL_REVISION1, 0x00}, + {MSM89XX_PMIC_DIGITAL_REVISION2, 0x00}, + {MSM89XX_PMIC_DIGITAL_PERPH_TYPE, 0x23}, + {MSM89XX_PMIC_DIGITAL_PERPH_SUBTYPE, 0x01}, + {MSM89XX_PMIC_DIGITAL_INT_RT_STS, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_SET_TYPE, 0xFF}, + {MSM89XX_PMIC_DIGITAL_INT_POLARITY_HIGH, 0xFF}, + {MSM89XX_PMIC_DIGITAL_INT_POLARITY_LOW, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_LATCHED_CLR, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_EN_SET, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_EN_CLR, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_LATCHED_STS, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_PENDING_STS, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_MID_SEL, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_PRIORITY, 0x00}, + {MSM89XX_PMIC_DIGITAL_GPIO_MODE, 0x00}, + {MSM89XX_PMIC_DIGITAL_PIN_CTL_OE, 0x01}, + {MSM89XX_PMIC_DIGITAL_PIN_CTL_DATA, 0x00}, + {MSM89XX_PMIC_DIGITAL_PIN_STATUS, 0x00}, + {MSM89XX_PMIC_DIGITAL_HDRIVE_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL, 0x02}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL, 0x02}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_HPHR_DAC_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX1_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX2_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX3_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_CONN_RX_LB_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_CDC_RX_CTL1, 0x7C}, + {MSM89XX_PMIC_DIGITAL_CDC_RX_CTL2, 0x7C}, + {MSM89XX_PMIC_DIGITAL_CDC_RX_CTL3, 0x7C}, + {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA0, 0x00}, + {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA1, 0x00}, + {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA2, 0x00}, + {MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA3, 0x00}, + {MSM89XX_PMIC_DIGITAL_DIG_DEBUG_CTL, 0x00}, + {MSM89XX_PMIC_DIGITAL_DIG_DEBUG_EN, 0x00}, + {MSM89XX_PMIC_DIGITAL_SPARE_0, 0x00}, + {MSM89XX_PMIC_DIGITAL_SPARE_1, 0x00}, + {MSM89XX_PMIC_DIGITAL_SPARE_2, 0x00}, + {MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0x00}, + {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL1, 0x00}, + {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL2, 0x02}, + {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x05}, + {MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_TEST1, 0x00}, + {MSM89XX_PMIC_DIGITAL_INT_TEST_VAL, 0x00}, + {MSM89XX_PMIC_DIGITAL_TRIM_NUM, 0x00}, + {MSM89XX_PMIC_DIGITAL_TRIM_CTRL, 0x00}, + {MSM89XX_PMIC_ANALOG_REVISION1, 0x00}, + {MSM89XX_PMIC_ANALOG_REVISION2, 0x00}, + {MSM89XX_PMIC_ANALOG_REVISION3, 0x00}, + {MSM89XX_PMIC_ANALOG_REVISION4, 0x00}, + {MSM89XX_PMIC_ANALOG_PERPH_TYPE, 0x23}, + {MSM89XX_PMIC_ANALOG_PERPH_SUBTYPE, 0x09}, + {MSM89XX_PMIC_ANALOG_INT_RT_STS, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_SET_TYPE, 0x3F}, + {MSM89XX_PMIC_ANALOG_INT_POLARITY_HIGH, 0x3F}, + {MSM89XX_PMIC_ANALOG_INT_POLARITY_LOW, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_LATCHED_CLR, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_EN_SET, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_EN_CLR, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_LATCHED_STS, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_PENDING_STS, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_MID_SEL, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_PRIORITY, 0x00}, + {MSM89XX_PMIC_ANALOG_MICB_1_EN, 0x00}, + {MSM89XX_PMIC_ANALOG_MICB_1_VAL, 0x20}, + {MSM89XX_PMIC_ANALOG_MICB_1_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS, 0x49}, + {MSM89XX_PMIC_ANALOG_MICB_2_EN, 0x20}, + {MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2, 0x00}, + {MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x35}, + {MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x08}, + {MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, 0x98}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL, 0x20}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL, 0x40}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN3_CTL, 0x61}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN4_CTL, 0x80}, + {MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT, 0x00}, + {MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x00}, + {MSM89XX_PMIC_ANALOG_TX_1_EN, 0x03}, + {MSM89XX_PMIC_ANALOG_TX_2_EN, 0x03}, + {MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_1, 0xBF}, + {MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_2, 0x8C}, + {MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x6B}, + {MSM89XX_PMIC_ANALOG_TX_1_2_TXFE_CLKDIV, 0x51}, + {MSM89XX_PMIC_ANALOG_TX_3_EN, 0x02}, + {MSM89XX_PMIC_ANALOG_NCP_EN, 0x26}, + {MSM89XX_PMIC_ANALOG_NCP_CLK, 0x23}, + {MSM89XX_PMIC_ANALOG_NCP_DEGLITCH, 0x5B}, + {MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0x08}, + {MSM89XX_PMIC_ANALOG_NCP_BIAS, 0x29}, + {MSM89XX_PMIC_ANALOG_NCP_VCTRL, 0x24}, + {MSM89XX_PMIC_ANALOG_NCP_TEST, 0x00}, + {MSM89XX_PMIC_ANALOG_NCP_CLIM_ADDR, 0xD5}, + {MSM89XX_PMIC_ANALOG_RX_CLOCK_DIVIDER, 0xE8}, + {MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL, 0xCF}, + {MSM89XX_PMIC_ANALOG_RX_COM_OCP_COUNT, 0x6E}, + {MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, 0x18}, + {MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA, 0x5A}, + {MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_LDO_OCP, 0x69}, + {MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_CNP, 0x29}, + {MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, 0x80}, + {MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_CTL, 0xDA}, + {MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME, 0x16}, + {MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x00}, + {MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x20}, + {MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x00}, + {MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x20}, + {MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x12}, + {MSM89XX_PMIC_ANALOG_RX_ATEST, 0x00}, + {MSM89XX_PMIC_ANALOG_RX_HPH_STATUS, 0x0C}, + {MSM89XX_PMIC_ANALOG_RX_EAR_STATUS, 0x00}, + {MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x00}, + {MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x83}, + {MSM89XX_PMIC_ANALOG_SPKR_DRV_CLIP_DET, 0x91}, + {MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x29}, + {MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET, 0x4D}, + {MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1}, + {MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0x1E}, + {MSM89XX_PMIC_ANALOG_SPKR_DRV_MISC, 0xCB}, + {MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x00}, + {MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x02}, + {MSM89XX_PMIC_ANALOG_OUTPUT_VOLTAGE, 0x14}, + {MSM89XX_PMIC_ANALOG_BYPASS_MODE, 0x00}, + {MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, 0x1F}, + {MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO, 0x8C}, + {MSM89XX_PMIC_ANALOG_RDSON_MAX_DUTY_CYCLE, 0xC0}, + {MSM89XX_PMIC_ANALOG_BOOST_TEST1_1, 0x00}, + {MSM89XX_PMIC_ANALOG_BOOST_TEST_2, 0x00}, + {MSM89XX_PMIC_ANALOG_SPKR_SAR_STATUS, 0x00}, + {MSM89XX_PMIC_ANALOG_SPKR_DRV_STATUS, 0x00}, + {MSM89XX_PMIC_ANALOG_PBUS_ADD_CSR, 0x00}, + {MSM89XX_PMIC_ANALOG_PBUS_ADD_SEL, 0x00}, + {MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0x00}, + {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL1, 0x00}, + {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL2, 0x01}, + {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x05}, + {MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_TEST1, 0x00}, + {MSM89XX_PMIC_ANALOG_INT_TEST_VAL, 0x00}, + {MSM89XX_PMIC_ANALOG_TRIM_NUM, 0x04}, + {MSM89XX_PMIC_ANALOG_TRIM_CTRL1, 0x00}, + {MSM89XX_PMIC_ANALOG_TRIM_CTRL2, 0x00}, + {MSM89XX_PMIC_ANALOG_TRIM_CTRL3, 0x00}, + {MSM89XX_PMIC_ANALOG_TRIM_CTRL4, 0x00}, +}; + +#endif diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c new file mode 100644 index 000000000000..4caed82a2236 --- /dev/null +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c @@ -0,0 +1,4778 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015-2018, 2020, The Linux Foundation. All rights reserved. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm-analog-cdc.h" +#include "msm-cdc-common.h" +#include "sdm660-cdc-irq.h" +#include "msm-analog-cdc-regmap.h" +#include +#include + +#define DRV_NAME "pmic_analog_codec" +#define SDM660_CDC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_192000) +#define SDM660_CDC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE) +#define MSM_DIG_CDC_STRING_LEN 80 +#define MSM_ANLG_CDC_VERSION_ENTRY_SIZE 32 + +#define CODEC_DT_MAX_PROP_SIZE 40 +#define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64 +#define BUS_DOWN 1 + +/* + * 200 Milliseconds sufficient for DSP bring up in the lpass + * after Sub System Restart + */ +#define ADSP_STATE_READY_TIMEOUT_MS 200 + +#define EAR_PMD 0 +#define EAR_PMU 1 +#define SPK_PMD 2 +#define SPK_PMU 3 + +#define MICBIAS_DEFAULT_VAL 1800000 +#define MICBIAS_MIN_VAL 1600000 +#define MICBIAS_STEP_SIZE 50000 + +#define DEFAULT_BOOST_VOLTAGE 5000 +#define MIN_BOOST_VOLTAGE 4000 +#define MAX_BOOST_VOLTAGE 5550 +#define BOOST_VOLTAGE_STEP 50 + +#define SDM660_CDC_MBHC_BTN_COARSE_ADJ 100 /* in mV */ +#define SDM660_CDC_MBHC_BTN_FINE_ADJ 12 /* in mV */ + +#define VOLTAGE_CONVERTER(value, min_value, step_size)\ + ((value - min_value)/step_size) + +enum { + BOOST_SWITCH = 0, + BOOST_ALWAYS, + BYPASS_ALWAYS, + BOOST_ON_FOREVER, +}; + +static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); +static struct snd_soc_dai_driver msm_anlg_cdc_i2s_dai[]; +/* By default enable the internal speaker boost */ +static bool spkr_boost_en = true; + +static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = { + "cdc-vdd-mic-bias", +}; + +static struct wcd_mbhc_register + wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = { + WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_DET_EN", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x40, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MECH_DETECTION_TYPE", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_CLAMP_CTL", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1, 0x18, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_DETECTION_TYPE", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_CTRL", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PLUG_TYPE", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_GND_PLUG_TYPE", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x08, 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SW_HPH_LP_100K_TO_GND", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x01, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_SCHMT_ISRC", + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, 0x06, 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_EN", + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, 0x80, 7, 0), + WCD_MBHC_REGISTER("WCD_MBHC_INSREM_DBNC", + MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, 0xF0, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_DBNC", + MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, 0x0C, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_VREF", + MSM89XX_PMIC_ANALOG_MBHC_BTN3_CTL, 0x03, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT", + MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x01, + 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_IN2P_CLAMP_STATE", + SND_SOC_NOPM, 0x0, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT", + MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x02, + 1, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT", + MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x08, + 3, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_SCHMT_RESULT", + MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0x04, + 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_OCP_FSM_EN", + MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_RESULT", + MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT, 0xFF, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_BTN_ISRC_CTL", + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, 0x70, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT", + MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, 0xFF, + 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL", + MSM89XX_PMIC_ANALOG_MICB_2_EN, 0xC0, 6, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME", + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME, 0xFC, 2, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN", + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PA_EN", + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_HPH_PA_EN", + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, 0x30, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE", + MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT, + 0x10, 4, 0), + WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL", + MSM89XX_PMIC_ANALOG_MICB_2_EN, 0x20, 5, 0), + WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN", 0, 0, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_FSM_STATUS", 0, 0, 0, 0), + WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL", 0, 0, 0, 0), +}; + +/* Multiply gain_adj and offset by 1000 and 100 to avoid float arithmetic */ +static const struct wcd_imped_i_ref imped_i_ref[] = { + {I_h4_UA, 8, 800, 9000, 10000}, + {I_pt5_UA, 10, 100, 990, 4600}, + {I_14_UA, 17, 14, 1050, 700}, + {I_l4_UA, 10, 4, 1165, 110}, + {I_1_UA, 0, 1, 1200, 65}, +}; + +static const struct wcd_mbhc_intr intr_ids = { + .mbhc_sw_intr = MSM89XX_IRQ_MBHC_HS_DET, + .mbhc_btn_press_intr = MSM89XX_IRQ_MBHC_PRESS, + .mbhc_btn_release_intr = MSM89XX_IRQ_MBHC_RELEASE, + .mbhc_hs_ins_intr = MSM89XX_IRQ_MBHC_INSREM_DET1, + .mbhc_hs_rem_intr = MSM89XX_IRQ_MBHC_INSREM_DET, + .hph_left_ocp = MSM89XX_IRQ_HPHL_OCP, + .hph_right_ocp = MSM89XX_IRQ_HPHR_OCP, +}; + +static int msm_anlg_cdc_dt_parse_vreg_info(struct device *dev, + struct sdm660_cdc_regulator *vreg, + const char *vreg_name, + bool ondemand); +static struct sdm660_cdc_pdata *msm_anlg_cdc_populate_dt_pdata( + struct device *dev); +static int msm_anlg_cdc_enable_ext_mb_source(struct wcd_mbhc *wcd_mbhc, + bool turn_on); +static void msm_anlg_cdc_trim_btn_reg(struct snd_soc_component *component); +static void msm_anlg_cdc_set_micb_v(struct snd_soc_component *component); +static void msm_anlg_cdc_set_boost_v(struct snd_soc_component *component); +static void msm_anlg_cdc_set_auto_zeroing(struct snd_soc_component *component, + bool enable); +static void msm_anlg_cdc_configure_cap(struct snd_soc_component *component, + bool micbias1, bool micbias2); +static bool msm_anlg_cdc_use_mb(struct snd_soc_component *component); + +static int get_codec_version(struct sdm660_cdc_priv *sdm660_cdc) +{ + if (sdm660_cdc->codec_version == DRAX_CDC) + return DRAX_CDC; + else if (sdm660_cdc->codec_version == DIANGU) + return DIANGU; + else if (sdm660_cdc->codec_version == CAJON_2_0) + return CAJON_2_0; + else if (sdm660_cdc->codec_version == CAJON) + return CAJON; + else if (sdm660_cdc->codec_version == CONGA) + return CONGA; + else if (sdm660_cdc->pmic_rev == TOMBAK_2_0) + return TOMBAK_2_0; + else if (sdm660_cdc->pmic_rev == TOMBAK_1_0) + return TOMBAK_1_0; + + pr_err("%s: unsupported codec version\n", __func__); + return UNSUPPORTED; +} + +static void wcd_mbhc_meas_imped(struct snd_soc_component *component, + s16 *impedance_l, s16 *impedance_r) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + if ((sdm660_cdc->imped_det_pin == WCD_MBHC_DET_BOTH) || + (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHL)) { + /* Enable ZDET_L_MEAS_EN */ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x08, 0x08); + /* Wait for 2ms for measurement to complete */ + usleep_range(2000, 2100); + /* Read Left impedance value from Result1 */ + *impedance_l = snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT); + /* Enable ZDET_R_MEAS_EN */ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x08, 0x00); + } + if ((sdm660_cdc->imped_det_pin == WCD_MBHC_DET_BOTH) || + (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHR)) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x04, 0x04); + /* Wait for 2ms for measurement to complete */ + usleep_range(2000, 2100); + /* Read Right impedance value from Result1 */ + *impedance_r = snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x04, 0x00); + } +} + +static void msm_anlg_cdc_set_ref_current(struct snd_soc_component *component, + enum wcd_curr_ref curr_ref) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: curr_ref: %d\n", __func__, curr_ref); + + if (get_codec_version(sdm660_cdc) < CAJON) + dev_dbg(component->dev, + "%s: Setting ref current not required\n", __func__); + + sdm660_cdc->imped_i_ref = imped_i_ref[curr_ref]; + + switch (curr_ref) { + case I_h4_UA: + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_2_EN, + 0x07, 0x01); + break; + case I_pt5_UA: + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_2_EN, + 0x07, 0x04); + break; + case I_14_UA: + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_2_EN, + 0x07, 0x03); + break; + case I_l4_UA: + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_2_EN, + 0x07, 0x01); + break; + case I_1_UA: + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_2_EN, + 0x07, 0x00); + break; + default: + pr_debug("%s: No ref current set\n", __func__); + break; + } +} + +static bool msm_anlg_cdc_adj_ref_current(struct snd_soc_component *component, + s16 *impedance_l, s16 *impedance_r) +{ + int i = 2; + s16 compare_imp = 0; + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHR) + compare_imp = *impedance_r; + else + compare_imp = *impedance_l; + + if (get_codec_version(sdm660_cdc) < CAJON) { + dev_dbg(component->dev, + "%s: Reference current adjustment not required\n", + __func__); + return false; + } + + while (compare_imp < imped_i_ref[i].min_val) { + msm_anlg_cdc_set_ref_current(component, + imped_i_ref[++i].curr_ref); + wcd_mbhc_meas_imped(component, impedance_l, impedance_r); + compare_imp = (sdm660_cdc->imped_det_pin == + WCD_MBHC_DET_HPHR) ? *impedance_r : *impedance_l; + if (i >= I_1_UA) + break; + } + return true; +} + +void msm_anlg_cdc_spk_ext_pa_cb( + int (*codec_spk_ext_pa)(struct snd_soc_component *component, + int enable), struct snd_soc_component *component) +{ + struct sdm660_cdc_priv *sdm660_cdc; + + if (!component) { + pr_err("%s: NULL codec pointer!\n", __func__); + return; + } + + sdm660_cdc = snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: Enter\n", __func__); + sdm660_cdc->codec_spk_ext_pa_cb = codec_spk_ext_pa; +} +EXPORT_SYMBOL(msm_anlg_cdc_spk_ext_pa_cb); + +static void msm_anlg_cdc_compute_impedance(struct snd_soc_component *component, + s16 l, s16 r, + uint32_t *zl, uint32_t *zr, + bool high) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + uint32_t rl = 0, rr = 0; + struct wcd_imped_i_ref R = sdm660_cdc->imped_i_ref; + int codec_ver = get_codec_version(sdm660_cdc); + + switch (codec_ver) { + case TOMBAK_1_0: + case TOMBAK_2_0: + case CONGA: + if (high) { + dev_dbg(component->dev, + "%s: This plug has high range impedance\n", + __func__); + rl = (uint32_t)(((100 * (l * 400 - 200))/96) - 230); + rr = (uint32_t)(((100 * (r * 400 - 200))/96) - 230); + } else { + dev_dbg(component->dev, + "%s: This plug has low range impedance\n", + __func__); + rl = (uint32_t)(((1000 * (l * 2 - 1))/1165) - (13/10)); + rr = (uint32_t)(((1000 * (r * 2 - 1))/1165) - (13/10)); + } + break; + case CAJON: + case CAJON_2_0: + case DIANGU: + case DRAX_CDC: + if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHL) { + rr = (uint32_t)(((DEFAULT_MULTIPLIER * (10 * r - 5)) - + (DEFAULT_OFFSET * DEFAULT_GAIN))/DEFAULT_GAIN); + rl = (uint32_t)(((10000 * (R.multiplier * (10 * l - 5))) + - R.offset * R.gain_adj)/(R.gain_adj * 100)); + } else if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHR) { + rr = (uint32_t)(((10000 * (R.multiplier * (10 * r - 5))) + - R.offset * R.gain_adj)/(R.gain_adj * 100)); + rl = (uint32_t)(((DEFAULT_MULTIPLIER * (10 * l - 5))- + (DEFAULT_OFFSET * DEFAULT_GAIN))/DEFAULT_GAIN); + } else if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_NONE) { + rr = (uint32_t)(((DEFAULT_MULTIPLIER * (10 * r - 5)) - + (DEFAULT_OFFSET * DEFAULT_GAIN))/DEFAULT_GAIN); + rl = (uint32_t)(((DEFAULT_MULTIPLIER * (10 * l - 5))- + (DEFAULT_OFFSET * DEFAULT_GAIN))/DEFAULT_GAIN); + } else { + rr = (uint32_t)(((10000 * (R.multiplier * (10 * r - 5))) + - R.offset * R.gain_adj)/(R.gain_adj * 100)); + rl = (uint32_t)(((10000 * (R.multiplier * (10 * l - 5))) + - R.offset * R.gain_adj)/(R.gain_adj * 100)); + } + break; + default: + dev_dbg(component->dev, "%s: No codec mentioned\n", __func__); + break; + } + *zl = rl; + *zr = rr; +} + +static struct firmware_cal *msm_anlg_cdc_get_hwdep_fw_cal( + struct wcd_mbhc *wcd_mbhc, + enum wcd_cal_type type) +{ + struct sdm660_cdc_priv *sdm660_cdc; + struct firmware_cal *hwdep_cal; + struct snd_soc_component *component = wcd_mbhc->component; + + if (!component) { + pr_err("%s: NULL codec pointer\n", __func__); + return NULL; + } + sdm660_cdc = snd_soc_component_get_drvdata(component); + hwdep_cal = wcdcal_get_fw_cal(sdm660_cdc->fw_data, type); + if (!hwdep_cal) { + dev_err(component->dev, "%s: cal not sent by %d\n", + __func__, type); + return NULL; + } + return hwdep_cal; +} + +static void wcd9xxx_spmi_irq_control(struct snd_soc_component *component, + int irq, bool enable) +{ + if (enable) + wcd9xxx_spmi_enable_irq(irq); + else + wcd9xxx_spmi_disable_irq(irq); +} + +static void msm_anlg_cdc_mbhc_clk_setup(struct snd_soc_component *component, + bool enable) +{ + if (enable) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x08, 0x08); + else + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x08, 0x00); +} + +static int msm_anlg_cdc_mbhc_map_btn_code_to_num( + struct snd_soc_component *component) +{ + int btn_code; + int btn; + + btn_code = snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT); + + switch (btn_code) { + case 0: + btn = 0; + break; + case 1: + btn = 1; + break; + case 3: + btn = 2; + break; + case 7: + btn = 3; + break; + case 15: + btn = 4; + break; + default: + btn = -EINVAL; + break; + }; + + return btn; +} + +static bool msm_anlg_cdc_spmi_lock_sleep(struct wcd_mbhc *mbhc, bool lock) +{ + if (lock) + return wcd9xxx_spmi_lock_sleep(); + wcd9xxx_spmi_unlock_sleep(); + return 0; +} + +static bool msm_anlg_cdc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num) +{ + if (micb_num == MIC_BIAS_1) + return (snd_soc_component_read32(mbhc->component, + MSM89XX_PMIC_ANALOG_MICB_1_EN) & + 0x80); + if (micb_num == MIC_BIAS_2) + return (snd_soc_component_read32(mbhc->component, + MSM89XX_PMIC_ANALOG_MICB_2_EN) & + 0x80); + return false; +} + +static void msm_anlg_cdc_enable_master_bias(struct snd_soc_component *component, + bool enable) +{ + if (enable) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, + 0x30, 0x30); + else + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, + 0x30, 0x00); +} + +static void msm_anlg_cdc_mbhc_common_micb_ctrl( + struct snd_soc_component *component, + int event, bool enable) +{ + u16 reg; + u8 mask; + u8 val; + + switch (event) { + case MBHC_COMMON_MICB_PRECHARGE: + reg = MSM89XX_PMIC_ANALOG_MICB_1_CTL; + mask = 0x60; + val = (enable ? 0x60 : 0x00); + break; + case MBHC_COMMON_MICB_SET_VAL: + reg = MSM89XX_PMIC_ANALOG_MICB_1_VAL; + mask = 0xFF; + val = (enable ? 0xC0 : 0x00); + break; + case MBHC_COMMON_MICB_TAIL_CURR: + reg = MSM89XX_PMIC_ANALOG_MICB_1_EN; + mask = 0x04; + val = (enable ? 0x04 : 0x00); + break; + default: + dev_err(component->dev, + "%s: Invalid event received\n", __func__); + return; + }; + snd_soc_component_update_bits(component, reg, mask, val); +} + +static void msm_anlg_cdc_mbhc_internal_micbias_ctrl( + struct snd_soc_component *component, + int micbias_num, + bool enable) +{ + if (micbias_num == 1) { + if (enable) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS, + 0x10, 0x10); + else + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS, + 0x10, 0x00); + } +} + +static bool msm_anlg_cdc_mbhc_hph_pa_on_status( + struct snd_soc_component *component) +{ + return (snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN) + & 0x30) ? true : false; +} + +static void msm_anlg_cdc_mbhc_program_btn_thr( + struct snd_soc_component *component, + s16 *btn_low, s16 *btn_high, + int num_btn, bool is_micbias) +{ + int i; + u32 course, fine, reg_val; + u16 reg_addr = MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL; + s16 *btn_voltage; + + btn_voltage = ((is_micbias) ? btn_high : btn_low); + + for (i = 0; i < num_btn; i++) { + course = (btn_voltage[i] / SDM660_CDC_MBHC_BTN_COARSE_ADJ); + fine = ((btn_voltage[i] % SDM660_CDC_MBHC_BTN_COARSE_ADJ) / + SDM660_CDC_MBHC_BTN_FINE_ADJ); + + reg_val = (course << 5) | (fine << 2); + snd_soc_component_update_bits(component, reg_addr, + 0xFC, reg_val); + dev_dbg(component->dev, + "%s: course: %d fine: %d reg_addr: %x reg_val: %x\n", + __func__, course, fine, reg_addr, reg_val); + reg_addr++; + } +} + +static void msm_anlg_cdc_mbhc_calc_impedance(struct wcd_mbhc *mbhc, + uint32_t *zl, uint32_t *zr) +{ + struct snd_soc_component *component = mbhc->component; + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + s16 impedance_l, impedance_r; + s16 impedance_l_fixed; + s16 reg0, reg1, reg2, reg3, reg4; + bool high = false; + bool min_range_used = false; + + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + reg0 = snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER); + reg1 = snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL); + reg2 = snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2); + reg3 = snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_MICB_2_EN); + reg4 = snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL); + + sdm660_cdc->imped_det_pin = WCD_MBHC_DET_BOTH; + mbhc->hph_type = WCD_MBHC_HPH_NONE; + + /* disable FSM and micbias and enable pullup*/ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x80, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_2_EN, + 0xA5, 0x25); + /* + * Enable legacy electrical detection current sources + * and disable fast ramp and enable manual switching + * of extra capacitance + */ + dev_dbg(component->dev, "%s: Setup for impedance det\n", __func__); + + msm_anlg_cdc_set_ref_current(component, I_h4_UA); + + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, + 0x06, 0x02); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, + 0x02, 0x02); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL, + 0x02, 0x00); + + dev_dbg(component->dev, "%s: Start performing impedance detection\n", + __func__); + + wcd_mbhc_meas_imped(component, &impedance_l, &impedance_r); + + if (impedance_l > 2 || impedance_r > 2) { + high = true; + if (!mbhc->mbhc_cfg->mono_stero_detection) { + /* Set ZDET_CHG to 0 to discharge ramp */ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x02, 0x00); + /* wait 40ms for the discharge ramp to complete */ + usleep_range(40000, 40100); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, + 0x03, 0x00); + sdm660_cdc->imped_det_pin = (impedance_l > 2 && + impedance_r > 2) ? + WCD_MBHC_DET_NONE : + ((impedance_l > 2) ? + WCD_MBHC_DET_HPHR : + WCD_MBHC_DET_HPHL); + if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_NONE) + goto exit; + } else { + if (get_codec_version(sdm660_cdc) >= CAJON) { + if (impedance_l == 63 && impedance_r == 63) { + dev_dbg(component->dev, + "%s: HPHL and HPHR are floating\n", + __func__); + sdm660_cdc->imped_det_pin = + WCD_MBHC_DET_NONE; + mbhc->hph_type = WCD_MBHC_HPH_NONE; + } else if (impedance_l == 63 + && impedance_r < 63) { + dev_dbg(component->dev, + "%s: Mono HS with HPHL floating\n", + __func__); + sdm660_cdc->imped_det_pin = + WCD_MBHC_DET_HPHR; + mbhc->hph_type = WCD_MBHC_HPH_MONO; + } else if (impedance_r == 63 && + impedance_l < 63) { + dev_dbg(component->dev, + "%s: Mono HS with HPHR floating\n", + __func__); + sdm660_cdc->imped_det_pin = + WCD_MBHC_DET_HPHL; + mbhc->hph_type = WCD_MBHC_HPH_MONO; + } else if (impedance_l > 3 && impedance_r > 3 && + (impedance_l == impedance_r)) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, + 0x06, 0x06); + wcd_mbhc_meas_imped(component, + &impedance_l, + &impedance_r); + if (impedance_r == impedance_l) + dev_dbg(component->dev, + "%s: Mono Headset\n", + __func__); + sdm660_cdc->imped_det_pin = + WCD_MBHC_DET_NONE; + mbhc->hph_type = + WCD_MBHC_HPH_MONO; + } else { + dev_dbg(component->dev, + "%s: STEREO headset is found\n", + __func__); + sdm660_cdc->imped_det_pin = + WCD_MBHC_DET_BOTH; + mbhc->hph_type = WCD_MBHC_HPH_STEREO; + } + } + } + } + + msm_anlg_cdc_set_ref_current(component, I_pt5_UA); + msm_anlg_cdc_set_ref_current(component, I_14_UA); + + /* Enable RAMP_L , RAMP_R & ZDET_CHG*/ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, + 0x03, 0x03); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x02, 0x02); + /* wait for 50msec for the HW to apply ramp on HPHL and HPHR */ + usleep_range(50000, 50100); + /* Enable ZDET_DISCHG_CAP_CTL to add extra capacitance */ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x01, 0x01); + /* wait for 5msec for the voltage to get stable */ + usleep_range(5000, 5100); + + wcd_mbhc_meas_imped(component, &impedance_l, &impedance_r); + + min_range_used = msm_anlg_cdc_adj_ref_current(component, + &impedance_l, &impedance_r); + if (!mbhc->mbhc_cfg->mono_stero_detection) { + /* Set ZDET_CHG to 0 to discharge ramp */ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x02, 0x00); + /* wait for 40msec for the capacitor to discharge */ + usleep_range(40000, 40100); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, + 0x03, 0x00); + goto exit; + } + + /* we are setting ref current to the minimun range or the measured + * value larger than the minimum value, so min_range_used is true. + * If the headset is mono headset with either HPHL or HPHR floating + * then we have already done the mono stereo detection and do not + * need to continue further. + */ + + if (!min_range_used || + sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHL || + sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHR) + goto exit; + + + /* Disable Set ZDET_CONN_RAMP_L and enable ZDET_CONN_FIXED_L */ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, + 0x02, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL, + 0x02, 0x02); + /* Set ZDET_CHG to 0 */ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x02, 0x00); + /* wait for 40msec for the capacitor to discharge */ + usleep_range(40000, 40100); + + /* Set ZDET_CONN_RAMP_R to 0 */ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, + 0x01, 0x00); + /* Enable ZDET_L_MEAS_EN */ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x08, 0x08); + /* wait for 2msec for the HW to compute left inpedance value */ + usleep_range(2000, 2100); + /* Read Left impedance value from Result1 */ + impedance_l_fixed = snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT); + /* Disable ZDET_L_MEAS_EN */ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x08, 0x00); + /* + * Assume impedance_l is L1, impedance_l_fixed is L2. + * If the following condition is met, we can take this + * headset as mono one with impedance of L2. + * Otherwise, take it as stereo with impedance of L1. + * Condition: + * abs[(L2-0.5L1)/(L2+0.5L1)] < abs [(L2-L1)/(L2+L1)] + */ + if ((abs(impedance_l_fixed - impedance_l/2) * + (impedance_l_fixed + impedance_l)) >= + (abs(impedance_l_fixed - impedance_l) * + (impedance_l_fixed + impedance_l/2))) { + dev_dbg(component->dev, + "%s: STEREO plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_STEREO; + } else { + dev_dbg(component->dev, + "%s: MONO plug type detected\n", + __func__); + mbhc->hph_type = WCD_MBHC_HPH_MONO; + impedance_l = impedance_l_fixed; + } + /* Enable ZDET_CHG */ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x02, 0x02); + /* wait for 10msec for the capacitor to charge */ + usleep_range(10000, 10100); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, + 0x02, 0x02); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL, + 0x02, 0x00); + /* Set ZDET_CHG to 0 to discharge HPHL */ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, + 0x02, 0x00); + /* wait for 40msec for the capacitor to discharge */ + usleep_range(40000, 40100); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL, + 0x02, 0x00); + +exit: + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, reg4); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_MICB_2_EN, reg3); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL, reg1); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, reg0); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, reg2); + msm_anlg_cdc_compute_impedance(component, impedance_l, impedance_r, + zl, zr, high); + + dev_dbg(component->dev, "%s: RL %d ohm, RR %d ohm\n", + __func__, *zl, *zr); + dev_dbg(component->dev, "%s: Impedance detection completed\n", + __func__); +} + +static int msm_anlg_cdc_dig_register_notifier(void *handle, + struct notifier_block *nblock, + bool enable) +{ + struct sdm660_cdc_priv *handle_cdc = handle; + + if (enable) + return blocking_notifier_chain_register(&handle_cdc->notifier, + nblock); + + return blocking_notifier_chain_unregister(&handle_cdc->notifier, + nblock); +} + +static int msm_anlg_cdc_mbhc_register_notifier(struct wcd_mbhc *wcd_mbhc, + struct notifier_block *nblock, + bool enable) +{ + struct snd_soc_component *component = wcd_mbhc->component; + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + if (enable) + return blocking_notifier_chain_register( + &sdm660_cdc->notifier_mbhc, + nblock); + + return blocking_notifier_chain_unregister(&sdm660_cdc->notifier_mbhc, + nblock); +} + +static int msm_anlg_cdc_request_irq(struct snd_soc_component *component, + int irq, irq_handler_t handler, + const char *name, void *data) +{ + return wcd9xxx_spmi_request_irq(irq, handler, name, data); +} + +static int msm_anlg_cdc_free_irq(struct snd_soc_component *component, + int irq, void *data) +{ + return wcd9xxx_spmi_free_irq(irq, data); +} + +static const struct wcd_mbhc_cb mbhc_cb = { + .enable_mb_source = msm_anlg_cdc_enable_ext_mb_source, + .trim_btn_reg = msm_anlg_cdc_trim_btn_reg, + .compute_impedance = msm_anlg_cdc_mbhc_calc_impedance, + .set_micbias_value = msm_anlg_cdc_set_micb_v, + .set_auto_zeroing = msm_anlg_cdc_set_auto_zeroing, + .get_hwdep_fw_cal = msm_anlg_cdc_get_hwdep_fw_cal, + .set_cap_mode = msm_anlg_cdc_configure_cap, + .register_notifier = msm_anlg_cdc_mbhc_register_notifier, + .request_irq = msm_anlg_cdc_request_irq, + .irq_control = wcd9xxx_spmi_irq_control, + .free_irq = msm_anlg_cdc_free_irq, + .clk_setup = msm_anlg_cdc_mbhc_clk_setup, + .map_btn_code_to_num = msm_anlg_cdc_mbhc_map_btn_code_to_num, + .lock_sleep = msm_anlg_cdc_spmi_lock_sleep, + .micbias_enable_status = msm_anlg_cdc_micb_en_status, + .mbhc_bias = msm_anlg_cdc_enable_master_bias, + .mbhc_common_micb_ctrl = msm_anlg_cdc_mbhc_common_micb_ctrl, + .micb_internal = msm_anlg_cdc_mbhc_internal_micbias_ctrl, + .hph_pa_on_status = msm_anlg_cdc_mbhc_hph_pa_on_status, + .set_btn_thr = msm_anlg_cdc_mbhc_program_btn_thr, + .extn_use_mb = msm_anlg_cdc_use_mb, +}; + +static const uint32_t wcd_imped_val[] = {4, 8, 12, 13, 16, + 20, 24, 28, 32, + 36, 40, 44, 48}; + +static void msm_anlg_cdc_dig_notifier_call(struct snd_soc_component *component, + const enum dig_cdc_notify_event event) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + pr_debug("%s: notifier call event %d\n", __func__, event); + blocking_notifier_call_chain(&sdm660_cdc->notifier, + event, NULL); +} + +static void msm_anlg_cdc_notifier_call(struct snd_soc_component *component, + const enum wcd_notify_event event) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, + "%s: notifier call event %d\n", __func__, event); + blocking_notifier_call_chain(&sdm660_cdc->notifier_mbhc, event, + &sdm660_cdc->mbhc); +} + +static void msm_anlg_cdc_boost_on(struct snd_soc_component *component) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x0F, 0x0F); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0xA5); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x0F); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, 0x30); + if (get_codec_version(sdm660_cdc) < CAJON_2_0) + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x82); + else + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0xA2); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, + 0x69, 0x69); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, + 0x01, 0x01); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO, + 0x88, 0x88); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, + 0x03, 0x03); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, + 0xE1, 0xE1); + if (get_codec_version(sdm660_cdc) < CAJON_2_0) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x20, 0x20); + /* Wait for 1ms after clock ctl enable */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, + 0xDF, 0xDF); + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + } else { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, + 0x40, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x20, 0x20); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, + 0x80, 0x80); + /* Wait for 500us after BOOST_EN to happen */ + usleep_range(500, 510); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, + 0x40, 0x40); + /* Wait for 500us after BOOST pulse_skip */ + usleep_range(500, 510); + } +} + +static void msm_anlg_cdc_boost_off(struct snd_soc_component *component) +{ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, 0xDF, 0x5F); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x20, 0x00); +} + +static void msm_anlg_cdc_bypass_on(struct snd_soc_component *component) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + if (get_codec_version(sdm660_cdc) < CAJON_2_0) { + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_SEC_ACCESS, + 0xA5); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, + 0x07); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x02, 0x02); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x01, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x40, 0x40); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x80, 0x80); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, + 0xDF, 0xDF); + } else { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x20, 0x20); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x20, 0x20); + } +} + +static void msm_anlg_cdc_bypass_off(struct snd_soc_component *component) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + if (get_codec_version(sdm660_cdc) < CAJON_2_0) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, + 0x80, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x80, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x02, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x40, 0x00); + } else { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_BYPASS_MODE, + 0x20, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x20, 0x00); + } +} + +static void msm_anlg_cdc_boost_mode_sequence( + struct snd_soc_component *component, + int flag) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + if (flag == EAR_PMU) { + switch (sdm660_cdc->boost_option) { + case BOOST_SWITCH: + if (sdm660_cdc->ear_pa_boost_set) { + msm_anlg_cdc_boost_off(component); + msm_anlg_cdc_bypass_on(component); + } + break; + case BOOST_ALWAYS: + msm_anlg_cdc_boost_on(component); + break; + case BYPASS_ALWAYS: + msm_anlg_cdc_bypass_on(component); + break; + case BOOST_ON_FOREVER: + msm_anlg_cdc_boost_on(component); + break; + default: + dev_err(component->dev, + "%s: invalid boost option: %d\n", __func__, + sdm660_cdc->boost_option); + break; + } + } else if (flag == EAR_PMD) { + switch (sdm660_cdc->boost_option) { + case BOOST_SWITCH: + if (sdm660_cdc->ear_pa_boost_set) + msm_anlg_cdc_bypass_off(component); + break; + case BOOST_ALWAYS: + msm_anlg_cdc_boost_off(component); + /* 80ms for EAR boost to settle down */ + msleep(80); + break; + case BYPASS_ALWAYS: + /* nothing to do as bypass on always */ + break; + case BOOST_ON_FOREVER: + /* nothing to do as boost on forever */ + break; + default: + dev_err(component->dev, + "%s: invalid boost option: %d\n", __func__, + sdm660_cdc->boost_option); + break; + } + } else if (flag == SPK_PMU) { + switch (sdm660_cdc->boost_option) { + case BOOST_SWITCH: + if (sdm660_cdc->spk_boost_set) { + msm_anlg_cdc_bypass_off(component); + msm_anlg_cdc_boost_on(component); + } + break; + case BOOST_ALWAYS: + msm_anlg_cdc_boost_on(component); + break; + case BYPASS_ALWAYS: + msm_anlg_cdc_bypass_on(component); + break; + case BOOST_ON_FOREVER: + msm_anlg_cdc_boost_on(component); + break; + default: + dev_err(component->dev, + "%s: invalid boost option: %d\n", __func__, + sdm660_cdc->boost_option); + break; + } + } else if (flag == SPK_PMD) { + switch (sdm660_cdc->boost_option) { + case BOOST_SWITCH: + if (sdm660_cdc->spk_boost_set) { + msm_anlg_cdc_boost_off(component); + /* + * Add 40 ms sleep for the spk + * boost to settle down + */ + msleep(40); + } + break; + case BOOST_ALWAYS: + msm_anlg_cdc_boost_off(component); + /* + * Add 40 ms sleep for the spk + * boost to settle down + */ + msleep(40); + break; + case BYPASS_ALWAYS: + /* nothing to do as bypass on always */ + break; + case BOOST_ON_FOREVER: + /* nothing to do as boost on forever */ + break; + default: + dev_err(component->dev, + "%s: invalid boost option: %d\n", __func__, + sdm660_cdc->boost_option); + break; + } + } +} + +static int msm_anlg_cdc_dt_parse_vreg_info(struct device *dev, + struct sdm660_cdc_regulator *vreg, const char *vreg_name, + bool ondemand) +{ + int len, ret = 0; + const __be32 *prop; + char prop_name[CODEC_DT_MAX_PROP_SIZE]; + struct device_node *regnode = NULL; + u32 prop_val; + + snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "%s-supply", + vreg_name); + regnode = of_parse_phandle(dev->of_node, prop_name, 0); + + if (!regnode) { + dev_err(dev, "Looking up %s property in node %s failed\n", + prop_name, dev->of_node->full_name); + return -ENODEV; + } + + dev_dbg(dev, "Looking up %s property in node %s\n", + prop_name, dev->of_node->full_name); + + vreg->name = vreg_name; + vreg->ondemand = ondemand; + + snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, + "qcom,%s-voltage", vreg_name); + prop = of_get_property(dev->of_node, prop_name, &len); + + if (!prop || (len != (2 * sizeof(__be32)))) { + dev_err(dev, "%s %s property\n", + prop ? "invalid format" : "no", prop_name); + return -EINVAL; + } + vreg->min_uv = be32_to_cpup(&prop[0]); + vreg->max_uv = be32_to_cpup(&prop[1]); + + snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, + "qcom,%s-current", vreg_name); + + ret = of_property_read_u32(dev->of_node, prop_name, &prop_val); + if (ret) { + dev_err(dev, "Looking up %s property in node %s failed", + prop_name, dev->of_node->full_name); + return -EFAULT; + } + vreg->optimum_ua = prop_val; + + dev_dbg(dev, "%s: vol=[%d %d]uV, curr=[%d]uA, ond %d\n\n", vreg->name, + vreg->min_uv, vreg->max_uv, vreg->optimum_ua, vreg->ondemand); + return 0; +} + +static void msm_anlg_cdc_dt_parse_boost_info( + struct snd_soc_component *component) +{ + struct sdm660_cdc_priv *sdm660_cdc_priv = + snd_soc_component_get_drvdata(component); + const char *prop_name = "qcom,cdc-boost-voltage"; + int boost_voltage, ret; + + ret = of_property_read_u32(component->dev->of_node, prop_name, + &boost_voltage); + if (ret) { + dev_dbg(component->dev, + "Looking up %s property in node %s failed\n", + prop_name, component->dev->of_node->full_name); + boost_voltage = DEFAULT_BOOST_VOLTAGE; + } + if (boost_voltage < MIN_BOOST_VOLTAGE || + boost_voltage > MAX_BOOST_VOLTAGE) { + dev_err(component->dev, + "Incorrect boost voltage. Reverting to default\n"); + boost_voltage = DEFAULT_BOOST_VOLTAGE; + } + + sdm660_cdc_priv->boost_voltage = + VOLTAGE_CONVERTER(boost_voltage, MIN_BOOST_VOLTAGE, + BOOST_VOLTAGE_STEP); + dev_dbg(component->dev, "Boost voltage value is: %d\n", + boost_voltage); +} + +static void msm_anlg_cdc_dt_parse_micbias_info(struct device *dev, + struct wcd_micbias_setting *micbias) +{ + const char *prop_name = "qcom,cdc-micbias-cfilt-mv"; + int ret; + + ret = of_property_read_u32(dev->of_node, prop_name, + &micbias->cfilt1_mv); + if (ret) { + dev_dbg(dev, "Looking up %s property in node %s failed", + prop_name, dev->of_node->full_name); + micbias->cfilt1_mv = MICBIAS_DEFAULT_VAL; + } +} + +static struct sdm660_cdc_pdata *msm_anlg_cdc_populate_dt_pdata( + struct device *dev) +{ + struct sdm660_cdc_pdata *pdata; + int ret, static_cnt, ond_cnt, idx, i; + const char *name = NULL; + const char *static_prop_name = "qcom,cdc-static-supplies"; + const char *ond_prop_name = "qcom,cdc-on-demand-supplies"; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return NULL; + + static_cnt = of_property_count_strings(dev->of_node, static_prop_name); + if (static_cnt < 0) { + dev_err(dev, "%s: Failed to get static supplies %d\n", __func__, + static_cnt); + ret = -EINVAL; + goto err; + } + + /* On-demand supply list is an optional property */ + ond_cnt = of_property_count_strings(dev->of_node, ond_prop_name); + if (ond_cnt < 0) + ond_cnt = 0; + + WARN_ON(static_cnt <= 0 || ond_cnt < 0); + if ((static_cnt + ond_cnt) > ARRAY_SIZE(pdata->regulator)) { + dev_err(dev, "%s: Num of supplies %u > max supported %zd\n", + __func__, (static_cnt + ond_cnt), + ARRAY_SIZE(pdata->regulator)); + ret = -EINVAL; + goto err; + } + + for (idx = 0; idx < static_cnt; idx++) { + ret = of_property_read_string_index(dev->of_node, + static_prop_name, idx, + &name); + if (ret) { + dev_err(dev, "%s: of read string %s idx %d error %d\n", + __func__, static_prop_name, idx, ret); + goto err; + } + + dev_dbg(dev, "%s: Found static cdc supply %s\n", __func__, + name); + ret = msm_anlg_cdc_dt_parse_vreg_info(dev, + &pdata->regulator[idx], + name, false); + if (ret) { + dev_err(dev, "%s:err parsing vreg for %s idx %d\n", + __func__, name, idx); + goto err; + } + } + + for (i = 0; i < ond_cnt; i++, idx++) { + ret = of_property_read_string_index(dev->of_node, ond_prop_name, + i, &name); + if (ret) { + dev_err(dev, "%s: err parsing on_demand for %s idx %d\n", + __func__, ond_prop_name, i); + goto err; + } + + dev_dbg(dev, "%s: Found on-demand cdc supply %s\n", __func__, + name); + ret = msm_anlg_cdc_dt_parse_vreg_info(dev, + &pdata->regulator[idx], + name, true); + if (ret) { + dev_err(dev, "%s: err parsing vreg on_demand for %s idx %d\n", + __func__, name, idx); + goto err; + } + } + msm_anlg_cdc_dt_parse_micbias_info(dev, &pdata->micbias); + + return pdata; +err: + devm_kfree(dev, pdata); + dev_err(dev, "%s: Failed to populate DT data ret = %d\n", + __func__, ret); + return NULL; +} + +static int msm_anlg_cdc_codec_enable_on_demand_supply( + struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + int ret = 0; + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + struct on_demand_supply *supply; + + if (w->shift >= ON_DEMAND_SUPPLIES_MAX) { + dev_err(component->dev, "%s: error index > MAX Demand supplies", + __func__); + ret = -EINVAL; + goto out; + } + dev_dbg(component->dev, "%s: supply: %s event: %d ref: %d\n", + __func__, on_demand_supply_name[w->shift], event, + atomic_read(&sdm660_cdc->on_demand_list[w->shift].ref)); + + supply = &sdm660_cdc->on_demand_list[w->shift]; + WARN_ONCE(!supply->supply, "%s isn't defined\n", + on_demand_supply_name[w->shift]); + if (!supply->supply) { + dev_err(component->dev, "%s: err supply not present ond for %d", + __func__, w->shift); + goto out; + } + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (atomic_inc_return(&supply->ref) == 1) { + ret = regulator_set_voltage(supply->supply, + supply->min_uv, + supply->max_uv); + if (ret) { + dev_err(component->dev, + "Setting regulator voltage(en) for micbias with err = %d\n", + ret); + goto out; + } + ret = regulator_set_load(supply->supply, + supply->optimum_ua); + if (ret < 0) { + dev_err(component->dev, + "Setting regulator optimum mode(en) failed for micbias with err = %d\n", + ret); + goto out; + } + ret = regulator_enable(supply->supply); + } + if (ret) + dev_err(component->dev, "%s: Failed to enable %s\n", + __func__, + on_demand_supply_name[w->shift]); + break; + case SND_SOC_DAPM_POST_PMD: + if (atomic_read(&supply->ref) == 0) { + dev_dbg(component->dev, "%s: %s supply has been disabled.\n", + __func__, on_demand_supply_name[w->shift]); + goto out; + } + if (atomic_dec_return(&supply->ref) == 0) { + ret = regulator_disable(supply->supply); + if (ret) + dev_err(component->dev, "%s: Failed to disable %s\n", + __func__, + on_demand_supply_name[w->shift]); + ret = regulator_set_voltage(supply->supply, + 0, + supply->max_uv); + if (ret) { + dev_err(component->dev, + "Setting regulator voltage(dis) failed for micbias with err = %d\n", + ret); + goto out; + } + ret = regulator_set_load(supply->supply, 0); + if (ret < 0) + dev_err(component->dev, + "Setting regulator optimum mode(dis) failed for micbias with err = %d\n", + ret); + } + break; + default: + break; + } +out: + return ret; +} + +static int msm_anlg_cdc_codec_enable_clock_block( + struct snd_soc_component *component, + int enable) +{ + struct msm_asoc_mach_data *pdata = NULL; + + pdata = snd_soc_card_get_drvdata(component->card); + if (enable) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, 0x30, 0x30); + msm_anlg_cdc_dig_notifier_call(component, DIG_CDC_EVENT_CLK_ON); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80, 0x80); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL, 0x0C, 0x0C); + } else { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL, 0x0C, 0x00); + } + return 0; +} + +static int msm_anlg_cdc_codec_enable_charge_pump(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: event = %d\n", __func__, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + msm_anlg_cdc_codec_enable_clock_block(component, 1); + if (!(strcmp(w->name, "EAR CP"))) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x80); + msm_anlg_cdc_boost_mode_sequence(component, EAR_PMU); + } else if (get_codec_version(sdm660_cdc) >= DIANGU) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x80); + } else { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0xC0, 0xC0); + } + break; + case SND_SOC_DAPM_POST_PMU: + /* Wait for 1ms post powerup of chargepump */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + break; + case SND_SOC_DAPM_POST_PMD: + /* Wait for 1ms post powerdown of chargepump */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + if (!(strcmp(w->name, "EAR CP"))) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x00); + if (sdm660_cdc->boost_option != BOOST_ALWAYS) { + dev_dbg(component->dev, + "%s: boost_option:%d, tear down ear\n", + __func__, sdm660_cdc->boost_option); + msm_anlg_cdc_boost_mode_sequence(component, + EAR_PMD); + } + /* + * Reset pa select bit from ear to hph after ear pa + * is disabled and HPH DAC disable to reduce ear + * turn off pop and avoid HPH pop in concurrency + */ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x80, 0x00); + } else { + if (get_codec_version(sdm660_cdc) < DIANGU) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x40, 0x00); + if (sdm660_cdc->rx_bias_count == 0) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x00); + dev_dbg(component->dev, "%s: rx_bias_count = %d\n", + __func__, sdm660_cdc->rx_bias_count); + } + break; + } + return 0; +} + +static int msm_anlg_cdc_ear_pa_boost_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = + (sdm660_cdc->ear_pa_boost_set ? 1 : 0); + dev_dbg(component->dev, "%s: sdm660_cdc->ear_pa_boost_set = %d\n", + __func__, sdm660_cdc->ear_pa_boost_set); + return 0; +} + +static int msm_anlg_cdc_ear_pa_boost_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + sdm660_cdc->ear_pa_boost_set = + (ucontrol->value.integer.value[0] ? true : false); + return 0; +} + +static int msm_anlg_cdc_pa_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 ear_pa_gain; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + if (get_codec_version(sdm660_cdc) >= DIANGU) { + ear_pa_gain = snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC); + ear_pa_gain = (ear_pa_gain >> 1) & 0x3; + + if (ear_pa_gain == 0x00) { + ucontrol->value.integer.value[0] = 3; + } else if (ear_pa_gain == 0x01) { + ucontrol->value.integer.value[0] = 2; + } else if (ear_pa_gain == 0x02) { + ucontrol->value.integer.value[0] = 1; + } else if (ear_pa_gain == 0x03) { + ucontrol->value.integer.value[0] = 0; + } else { + dev_err(component->dev, + "%s: ERROR: Unsupported Ear Gain = 0x%x\n", + __func__, ear_pa_gain); + return -EINVAL; + } + } else { + ear_pa_gain = snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL); + ear_pa_gain = (ear_pa_gain >> 5) & 0x1; + if (ear_pa_gain == 0x00) { + ucontrol->value.integer.value[0] = 0; + } else if (ear_pa_gain == 0x01) { + ucontrol->value.integer.value[0] = 3; + } else { + dev_err(component->dev, + "%s: ERROR: Unsupported Ear Gain = 0x%x\n", + __func__, ear_pa_gain); + return -EINVAL; + } + } + dev_dbg(component->dev, "%s: ear_pa_gain = 0x%x\n", + __func__, ear_pa_gain); + return 0; +} + +static int msm_anlg_cdc_pa_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 ear_pa_gain; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + if (get_codec_version(sdm660_cdc) >= DIANGU) { + switch (ucontrol->value.integer.value[0]) { + case 0: + ear_pa_gain = 0x06; + break; + case 1: + ear_pa_gain = 0x04; + break; + case 2: + ear_pa_gain = 0x02; + break; + case 3: + ear_pa_gain = 0x00; + break; + default: + return -EINVAL; + } + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, + 0x06, ear_pa_gain); + } else { + switch (ucontrol->value.integer.value[0]) { + case 0: + ear_pa_gain = 0x00; + break; + case 3: + ear_pa_gain = 0x20; + break; + case 1: + case 2: + default: + return -EINVAL; + } + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x20, ear_pa_gain); + } + return 0; +} + +static int msm_anlg_cdc_hph_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + if (sdm660_cdc->hph_mode == NORMAL_MODE) { + ucontrol->value.integer.value[0] = 0; + } else if (sdm660_cdc->hph_mode == HD2_MODE) { + ucontrol->value.integer.value[0] = 1; + } else { + dev_err(component->dev, "%s: ERROR: Default HPH Mode= %d\n", + __func__, sdm660_cdc->hph_mode); + } + + dev_dbg(component->dev, "%s: sdm660_cdc->hph_mode = %d\n", __func__, + sdm660_cdc->hph_mode); + return 0; +} + +static int msm_anlg_cdc_hph_mode_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + switch (ucontrol->value.integer.value[0]) { + case 0: + sdm660_cdc->hph_mode = NORMAL_MODE; + break; + case 1: + if (get_codec_version(sdm660_cdc) >= DIANGU) + sdm660_cdc->hph_mode = HD2_MODE; + break; + default: + sdm660_cdc->hph_mode = NORMAL_MODE; + break; + } + dev_dbg(component->dev, "%s: sdm660_cdc->hph_mode_set = %d\n", + __func__, sdm660_cdc->hph_mode); + return 0; +} + +static int msm_anlg_cdc_boost_option_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + if (sdm660_cdc->boost_option == BOOST_SWITCH) { + ucontrol->value.integer.value[0] = 0; + } else if (sdm660_cdc->boost_option == BOOST_ALWAYS) { + ucontrol->value.integer.value[0] = 1; + } else if (sdm660_cdc->boost_option == BYPASS_ALWAYS) { + ucontrol->value.integer.value[0] = 2; + } else if (sdm660_cdc->boost_option == BOOST_ON_FOREVER) { + ucontrol->value.integer.value[0] = 3; + } else { + dev_err(component->dev, + "%s: ERROR: Unsupported Boost option= %d\n", + __func__, sdm660_cdc->boost_option); + return -EINVAL; + } + + dev_dbg(component->dev, "%s: sdm660_cdc->boost_option = %d\n", __func__, + sdm660_cdc->boost_option); + return 0; +} + +static int msm_anlg_cdc_boost_option_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + switch (ucontrol->value.integer.value[0]) { + case 0: + sdm660_cdc->boost_option = BOOST_SWITCH; + break; + case 1: + sdm660_cdc->boost_option = BOOST_ALWAYS; + break; + case 2: + sdm660_cdc->boost_option = BYPASS_ALWAYS; + msm_anlg_cdc_bypass_on(component); + break; + case 3: + sdm660_cdc->boost_option = BOOST_ON_FOREVER; + msm_anlg_cdc_boost_on(component); + break; + default: + pr_err("%s: invalid boost option: %d\n", __func__, + sdm660_cdc->boost_option); + return -EINVAL; + } + dev_dbg(component->dev, "%s: sdm660_cdc->boost_option_set = %d\n", + __func__, sdm660_cdc->boost_option); + return 0; +} + +static int msm_anlg_cdc_spk_boost_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + if (sdm660_cdc->spk_boost_set == false) { + ucontrol->value.integer.value[0] = 0; + } else if (sdm660_cdc->spk_boost_set == true) { + ucontrol->value.integer.value[0] = 1; + } else { + dev_err(component->dev, + "%s: ERROR: Unsupported Speaker Boost = %d\n", + __func__, sdm660_cdc->spk_boost_set); + return -EINVAL; + } + + dev_dbg(component->dev, + "%s: sdm660_cdc->spk_boost_set = %d\n", __func__, + sdm660_cdc->spk_boost_set); + return 0; +} + +static int msm_anlg_cdc_spk_boost_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + switch (ucontrol->value.integer.value[0]) { + case 0: + sdm660_cdc->spk_boost_set = false; + break; + case 1: + sdm660_cdc->spk_boost_set = true; + break; + default: + return -EINVAL; + } + dev_dbg(component->dev, "%s: sdm660_cdc->spk_boost_set = %d\n", + __func__, sdm660_cdc->spk_boost_set); + return 0; +} + +static int msm_anlg_cdc_ext_spk_boost_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + if (sdm660_cdc->ext_spk_boost_set == false) + ucontrol->value.integer.value[0] = 0; + else + ucontrol->value.integer.value[0] = 1; + + dev_dbg(component->dev, "%s: sdm660_cdc->ext_spk_boost_set = %d\n", + __func__, sdm660_cdc->ext_spk_boost_set); + return 0; +} + +static int msm_anlg_cdc_ext_spk_boost_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + switch (ucontrol->value.integer.value[0]) { + case 0: + sdm660_cdc->ext_spk_boost_set = false; + break; + case 1: + sdm660_cdc->ext_spk_boost_set = true; + break; + default: + return -EINVAL; + } + dev_dbg(component->dev, "%s: sdm660_cdc->spk_boost_set = %d\n", + __func__, sdm660_cdc->spk_boost_set); + return 0; +} + +static const char * const msm_anlg_cdc_ear_pa_boost_ctrl_text[] = { + "DISABLE", "ENABLE"}; +static const struct soc_enum msm_anlg_cdc_ear_pa_boost_ctl_enum[] = { + SOC_ENUM_SINGLE_EXT(2, msm_anlg_cdc_ear_pa_boost_ctrl_text), +}; + +static const char * const msm_anlg_cdc_ear_pa_gain_text[] = { + "POS_1P5_DB", "POS_3_DB", "POS_4P5_DB", "POS_6_DB"}; +static const struct soc_enum msm_anlg_cdc_ear_pa_gain_enum[] = { + SOC_ENUM_SINGLE_EXT(4, msm_anlg_cdc_ear_pa_gain_text), +}; + +static const char * const msm_anlg_cdc_boost_option_ctrl_text[] = { + "BOOST_SWITCH", "BOOST_ALWAYS", "BYPASS_ALWAYS", + "BOOST_ON_FOREVER"}; +static const struct soc_enum msm_anlg_cdc_boost_option_ctl_enum[] = { + SOC_ENUM_SINGLE_EXT(4, msm_anlg_cdc_boost_option_ctrl_text), +}; +static const char * const msm_anlg_cdc_spk_boost_ctrl_text[] = { + "DISABLE", "ENABLE"}; +static const struct soc_enum msm_anlg_cdc_spk_boost_ctl_enum[] = { + SOC_ENUM_SINGLE_EXT(2, msm_anlg_cdc_spk_boost_ctrl_text), +}; + +static const char * const msm_anlg_cdc_ext_spk_boost_ctrl_text[] = { + "DISABLE", "ENABLE"}; +static const struct soc_enum msm_anlg_cdc_ext_spk_boost_ctl_enum[] = { + SOC_ENUM_SINGLE_EXT(2, msm_anlg_cdc_ext_spk_boost_ctrl_text), +}; + +static const char * const msm_anlg_cdc_hph_mode_ctrl_text[] = { + "NORMAL", "HD2"}; +static const struct soc_enum msm_anlg_cdc_hph_mode_ctl_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(msm_anlg_cdc_hph_mode_ctrl_text), + msm_anlg_cdc_hph_mode_ctrl_text), +}; + +/*cut of frequency for high pass filter*/ +static const char * const cf_text[] = { + "MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz" +}; + + +static const struct snd_kcontrol_new msm_anlg_cdc_snd_controls[] = { + + SOC_ENUM_EXT("RX HPH Mode", msm_anlg_cdc_hph_mode_ctl_enum[0], + msm_anlg_cdc_hph_mode_get, msm_anlg_cdc_hph_mode_set), + + SOC_ENUM_EXT("Boost Option", msm_anlg_cdc_boost_option_ctl_enum[0], + msm_anlg_cdc_boost_option_get, msm_anlg_cdc_boost_option_set), + + SOC_ENUM_EXT("EAR PA Boost", msm_anlg_cdc_ear_pa_boost_ctl_enum[0], + msm_anlg_cdc_ear_pa_boost_get, msm_anlg_cdc_ear_pa_boost_set), + + SOC_ENUM_EXT("EAR PA Gain", msm_anlg_cdc_ear_pa_gain_enum[0], + msm_anlg_cdc_pa_gain_get, msm_anlg_cdc_pa_gain_put), + + SOC_ENUM_EXT("Speaker Boost", msm_anlg_cdc_spk_boost_ctl_enum[0], + msm_anlg_cdc_spk_boost_get, msm_anlg_cdc_spk_boost_set), + + SOC_ENUM_EXT("Ext Spk Boost", msm_anlg_cdc_ext_spk_boost_ctl_enum[0], + msm_anlg_cdc_ext_spk_boost_get, msm_anlg_cdc_ext_spk_boost_set), + + SOC_SINGLE_TLV("ADC1 Volume", MSM89XX_PMIC_ANALOG_TX_1_EN, 3, + 8, 0, analog_gain), + SOC_SINGLE_TLV("ADC2 Volume", MSM89XX_PMIC_ANALOG_TX_2_EN, 3, + 8, 0, analog_gain), + SOC_SINGLE_TLV("ADC3 Volume", MSM89XX_PMIC_ANALOG_TX_3_EN, 3, + 8, 0, analog_gain), + + +}; + +static int tombak_hph_impedance_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret; + uint32_t zl, zr; + bool hphr; + struct soc_multi_mixer_control *mc; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct sdm660_cdc_priv *priv = + snd_soc_component_get_drvdata(component); + + mc = (struct soc_multi_mixer_control *)(kcontrol->private_value); + + hphr = mc->shift; + ret = wcd_mbhc_get_impedance(&priv->mbhc, &zl, &zr); + if (ret) + dev_dbg(component->dev, "%s: Failed to get mbhc imped", + __func__); + dev_dbg(component->dev, "%s: zl %u, zr %u\n", __func__, zl, zr); + ucontrol->value.integer.value[0] = hphr ? zr : zl; + + return 0; +} + +static const struct snd_kcontrol_new impedance_detect_controls[] = { + SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0, + tombak_hph_impedance_get, NULL), + SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0, + tombak_hph_impedance_get, NULL), +}; + +static int tombak_get_hph_type(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct sdm660_cdc_priv *priv = snd_soc_component_get_drvdata(component); + struct wcd_mbhc *mbhc; + + if (!priv) { + dev_err(component->dev, + "%s: sdm660_cdc-wcd private data is NULL\n", + __func__); + return -EINVAL; + } + + mbhc = &priv->mbhc; + if (!mbhc) { + dev_err(component->dev, "%s: mbhc not initialized\n", __func__); + return -EINVAL; + } + + ucontrol->value.integer.value[0] = (u32) mbhc->hph_type; + dev_dbg(component->dev, "%s: hph_type = %u\n", + __func__, mbhc->hph_type); + + return 0; +} + +static const struct snd_kcontrol_new hph_type_detect_controls[] = { + SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0, + tombak_get_hph_type, NULL), +}; + +static const char * const rdac2_mux_text[] = { + "ZERO", "RX2", "RX1" +}; + +static const struct snd_kcontrol_new adc1_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const struct soc_enum rdac2_mux_enum = + SOC_ENUM_SINGLE(MSM89XX_PMIC_DIGITAL_CDC_CONN_HPHR_DAC_CTL, + 0, 3, rdac2_mux_text); + +static const char * const adc2_mux_text[] = { + "ZERO", "INP2", "INP3" +}; + +static const char * const ext_spk_text[] = { + "Off", "On" +}; + +static const char * const wsa_spk_text[] = { + "ZERO", "WSA" +}; + +static const struct soc_enum adc2_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, + ARRAY_SIZE(adc2_mux_text), adc2_mux_text); + +static const struct soc_enum ext_spk_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, + ARRAY_SIZE(ext_spk_text), ext_spk_text); + +static const struct soc_enum wsa_spk_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, + ARRAY_SIZE(wsa_spk_text), wsa_spk_text); + + + +static const struct snd_kcontrol_new ext_spk_mux = + SOC_DAPM_ENUM("Ext Spk Switch Mux", ext_spk_enum); + + + +static const struct snd_kcontrol_new tx_adc2_mux = + SOC_DAPM_ENUM("ADC2 MUX Mux", adc2_enum); + + +static const struct snd_kcontrol_new rdac2_mux = + SOC_DAPM_ENUM("RDAC2 MUX Mux", rdac2_mux_enum); + +static const char * const ear_text[] = { + "ZERO", "Switch", +}; + +static const struct soc_enum ear_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(ear_text), ear_text); + +static const struct snd_kcontrol_new ear_pa_mux[] = { + SOC_DAPM_ENUM("EAR_S", ear_enum) +}; + +static const struct snd_kcontrol_new wsa_spk_mux[] = { + SOC_DAPM_ENUM("WSA Spk Switch", wsa_spk_enum) +}; + + + +static const char * const hph_text[] = { + "ZERO", "Switch", +}; + +static const struct soc_enum hph_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hph_text), hph_text); + +static const struct snd_kcontrol_new hphl_mux[] = { + SOC_DAPM_ENUM("HPHL", hph_enum) +}; + +static const struct snd_kcontrol_new hphr_mux[] = { + SOC_DAPM_ENUM("HPHR", hph_enum) +}; + +static const struct snd_kcontrol_new spkr_mux[] = { + SOC_DAPM_ENUM("SPK", hph_enum) +}; + +static const char * const lo_text[] = { + "ZERO", "Switch", +}; + +static const struct soc_enum lo_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hph_text), hph_text); + +static const struct snd_kcontrol_new lo_mux[] = { + SOC_DAPM_ENUM("LINE_OUT", lo_enum) +}; + +static void msm_anlg_cdc_codec_enable_adc_block( + struct snd_soc_component *component, + int enable) +{ + struct sdm660_cdc_priv *wcd8x16 = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s %d\n", __func__, enable); + + if (enable) { + wcd8x16->adc_count++; + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, + 0x20, 0x20); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x10, 0x10); + } else { + wcd8x16->adc_count--; + if (!wcd8x16->adc_count) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x10, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, + 0x20, 0x0); + } + } +} + +static int msm_anlg_cdc_codec_enable_adc(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + u16 adc_reg; + u8 init_bit_shift; + + dev_dbg(component->dev, "%s %d\n", __func__, event); + + adc_reg = MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_2; + + if (w->reg == MSM89XX_PMIC_ANALOG_TX_1_EN) + init_bit_shift = 5; + else if ((w->reg == MSM89XX_PMIC_ANALOG_TX_2_EN) || + (w->reg == MSM89XX_PMIC_ANALOG_TX_3_EN)) + init_bit_shift = 4; + else { + dev_err(component->dev, "%s: Error, invalid adc register\n", + __func__); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + msm_anlg_cdc_codec_enable_adc_block(component, 1); + if (w->reg == MSM89XX_PMIC_ANALOG_TX_2_EN) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_1_CTL, 0x02, 0x02); + /* + * Add delay of 10 ms to give sufficient time for the voltage + * to shoot up and settle so that the txfe init does not + * happen when the input voltage is changing too much. + */ + usleep_range(10000, 10010); + snd_soc_component_update_bits(component, adc_reg, + 1 << init_bit_shift, 1 << init_bit_shift); + if (w->reg == MSM89XX_PMIC_ANALOG_TX_1_EN) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL, + 0x03, 0x00); + else if ((w->reg == MSM89XX_PMIC_ANALOG_TX_2_EN) || + (w->reg == MSM89XX_PMIC_ANALOG_TX_3_EN)) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL, + 0x03, 0x00); + /* Wait for 1ms to allow txfe settling time */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + break; + case SND_SOC_DAPM_POST_PMU: + /* + * Add delay of 12 ms before deasserting the init + * to reduce the tx pop + */ + usleep_range(12000, 12010); + snd_soc_component_update_bits(component, adc_reg, + 1 << init_bit_shift, 0x00); + /* Wait for 1ms to allow txfe settling time post powerup */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + break; + case SND_SOC_DAPM_POST_PMD: + msm_anlg_cdc_codec_enable_adc_block(component, 0); + if (w->reg == MSM89XX_PMIC_ANALOG_TX_2_EN) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_1_CTL, 0x02, 0x00); + if (w->reg == MSM89XX_PMIC_ANALOG_TX_1_EN) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL, + 0x03, 0x02); + else if ((w->reg == MSM89XX_PMIC_ANALOG_TX_2_EN) || + (w->reg == MSM89XX_PMIC_ANALOG_TX_3_EN)) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL, + 0x03, 0x02); + + break; + } + return 0; +} + +static int msm_anlg_cdc_codec_enable_spk_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0x01, 0x01); + switch (sdm660_cdc->boost_option) { + case BOOST_SWITCH: + if (!sdm660_cdc->spk_boost_set) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, + 0x10, 0x10); + break; + case BOOST_ALWAYS: + case BOOST_ON_FOREVER: + break; + case BYPASS_ALWAYS: + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, + 0x10, 0x10); + break; + default: + dev_err(component->dev, + "%s: invalid boost option: %d\n", __func__, + sdm660_cdc->boost_option); + break; + } + /* Wait for 1ms after SPK_DAC CTL setting */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0xE0, 0xE0); + if (get_codec_version(sdm660_cdc) != TOMBAK_1_0) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x01, 0x01); + break; + case SND_SOC_DAPM_POST_PMU: + /* Wait for 1ms after SPK_VBAT_LDO Enable */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + switch (sdm660_cdc->boost_option) { + case BOOST_SWITCH: + if (sdm660_cdc->spk_boost_set) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, + 0xEF, 0xEF); + else + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, + 0x10, 0x00); + break; + case BOOST_ALWAYS: + case BOOST_ON_FOREVER: + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, + 0xEF, 0xEF); + break; + case BYPASS_ALWAYS: + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x10, 0x00); + break; + default: + dev_err(component->dev, + "%s: invalid boost option: %d\n", __func__, + sdm660_cdc->boost_option); + break; + } + msm_anlg_cdc_dig_notifier_call(component, + DIG_CDC_EVENT_RX3_MUTE_OFF); + snd_soc_component_update_bits(component, w->reg, 0x80, 0x80); + break; + case SND_SOC_DAPM_PRE_PMD: + msm_anlg_cdc_dig_notifier_call(component, + DIG_CDC_EVENT_RX3_MUTE_ON); + /* + * Add 1 ms sleep for the mute to take effect + */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x10, 0x10); + if (get_codec_version(sdm660_cdc) < CAJON_2_0) + msm_anlg_cdc_boost_mode_sequence(component, SPK_PMD); + snd_soc_component_update_bits(component, w->reg, 0x80, 0x00); + switch (sdm660_cdc->boost_option) { + case BOOST_SWITCH: + if (sdm660_cdc->spk_boost_set) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, + 0xEF, 0x69); + break; + case BOOST_ALWAYS: + case BOOST_ON_FOREVER: + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, + 0xEF, 0x69); + break; + case BYPASS_ALWAYS: + break; + default: + dev_err(component->dev, + "%s: invalid boost option: %d\n", __func__, + sdm660_cdc->boost_option); + break; + } + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0xE0, 0x00); + /* Wait for 1ms to allow setting time for spkr path disable */ + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, 0x01, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x10, 0x00); + if (get_codec_version(sdm660_cdc) != TOMBAK_1_0) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x01, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00); + if (get_codec_version(sdm660_cdc) >= CAJON_2_0) + msm_anlg_cdc_boost_mode_sequence(component, SPK_PMD); + break; + } + return 0; +} + +static int msm_anlg_cdc_codec_enable_dig_clk(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + struct msm_asoc_mach_data *pdata = NULL; + + pdata = snd_soc_card_get_drvdata(component->card); + + dev_dbg(component->dev, "%s event %d w->name %s\n", __func__, + event, w->name); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + msm_anlg_cdc_codec_enable_clock_block(component, 1); + snd_soc_component_update_bits(component, w->reg, 0x80, 0x80); + msm_anlg_cdc_boost_mode_sequence(component, SPK_PMU); + break; + case SND_SOC_DAPM_POST_PMD: + if (sdm660_cdc->rx_bias_count == 0) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x00); + } + return 0; +} + +static bool msm_anlg_cdc_use_mb(struct snd_soc_component *component) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + if (get_codec_version(sdm660_cdc) < CAJON) + return true; + else + return false; +} + +static void msm_anlg_cdc_set_auto_zeroing(struct snd_soc_component *component, + bool enable) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + if (get_codec_version(sdm660_cdc) < CONGA) { + if (enable) + /* + * Set autozeroing for special headset detection and + * buttons to work. + */ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_2_EN, + 0x18, 0x10); + else + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_2_EN, + 0x18, 0x00); + + } else { + dev_dbg(component->dev, + "%s: Auto Zeroing is not required from CONGA\n", + __func__); + } +} + +static void msm_anlg_cdc_trim_btn_reg(struct snd_soc_component *component) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + if (get_codec_version(sdm660_cdc) == TOMBAK_1_0) { + pr_debug("%s: This device needs to be trimmed\n", __func__); + /* + * Calculate the trim value for each device used + * till is comes in production by hardware team + */ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SEC_ACCESS, + 0xA5, 0xA5); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_TRIM_CTRL2, + 0xFF, 0x30); + } else { + dev_dbg(component->dev, "%s: This device is trimmed at ATE\n", + __func__); + } +} + +static int msm_anlg_cdc_enable_ext_mb_source(struct wcd_mbhc *wcd_mbhc, + bool turn_on) +{ + int ret = 0; + static int count; + struct snd_soc_component *component = wcd_mbhc->component; + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); + + dev_dbg(component->dev, "%s turn_on: %d count: %d\n", __func__, turn_on, + count); + if (turn_on) { + if (!count) { + ret = snd_soc_dapm_force_enable_pin(dapm, + "MICBIAS_REGULATOR"); + snd_soc_dapm_sync(dapm); + } + count++; + } else { + if (count > 0) + count--; + if (!count) { + ret = snd_soc_dapm_disable_pin(dapm, + "MICBIAS_REGULATOR"); + snd_soc_dapm_sync(dapm); + } + } + + if (ret) + dev_err(component->dev, + "%s: Failed to %s external micbias source\n", + __func__, turn_on ? "enable" : "disabled"); + else + dev_dbg(component->dev, "%s: %s external micbias source\n", + __func__, turn_on ? "Enabled" : "Disabled"); + + return ret; +} + +static int msm_anlg_cdc_codec_enable_micbias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + u16 micb_int_reg; + char *internal1_text = "Internal1"; + char *internal2_text = "Internal2"; + char *internal3_text = "Internal3"; + char *external2_text = "External2"; + char *external_text = "External"; + bool micbias2; + + dev_dbg(component->dev, "%s %d\n", __func__, event); + switch (w->reg) { + case MSM89XX_PMIC_ANALOG_MICB_1_EN: + case MSM89XX_PMIC_ANALOG_MICB_2_EN: + micb_int_reg = MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS; + break; + default: + dev_err(component->dev, + "%s: Error, invalid micbias register 0x%x\n", + __func__, w->reg); + return -EINVAL; + } + + micbias2 = (snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_MICB_2_EN) & 0x80); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (strnstr(w->name, internal1_text, strlen(w->name))) { + if (get_codec_version(sdm660_cdc) >= CAJON) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2, + 0x02, 0x02); + snd_soc_component_update_bits(component, micb_int_reg, + 0x80, 0x80); + } else if (strnstr(w->name, internal2_text, strlen(w->name))) { + snd_soc_component_update_bits(component, micb_int_reg, + 0x10, 0x10); + snd_soc_component_update_bits(component, w->reg, + 0x60, 0x00); + } else if (strnstr(w->name, internal3_text, strlen(w->name))) { + snd_soc_component_update_bits(component, micb_int_reg, + 0x2, 0x2); + /* + * update MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2 + * for external bias only, not for external2. + */ + } else if (!strnstr(w->name, external2_text, strlen(w->name)) && + strnstr(w->name, external_text, + strlen(w->name))) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2, + 0x02, 0x02); + } + if (!strnstr(w->name, external_text, strlen(w->name))) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_1_EN, 0x05, 0x04); + if (w->reg == MSM89XX_PMIC_ANALOG_MICB_1_EN) + msm_anlg_cdc_configure_cap(component, true, micbias2); + + break; + case SND_SOC_DAPM_POST_PMU: + if (get_codec_version(sdm660_cdc) <= TOMBAK_2_0) + /* + * Wait for 20ms post micbias enable + * for version < tombak 2.0. + */ + usleep_range(20000, 20100); + if (strnstr(w->name, internal1_text, strlen(w->name))) { + snd_soc_component_update_bits(component, micb_int_reg, + 0x40, 0x40); + } else if (strnstr(w->name, internal2_text, strlen(w->name))) { + snd_soc_component_update_bits(component, micb_int_reg, + 0x08, 0x08); + msm_anlg_cdc_notifier_call(component, + WCD_EVENT_POST_MICBIAS_2_ON); + } else if (strnstr(w->name, internal3_text, 30)) { + snd_soc_component_update_bits(component, micb_int_reg, + 0x01, 0x01); + } else if (strnstr(w->name, external2_text, strlen(w->name))) { + msm_anlg_cdc_notifier_call(component, + WCD_EVENT_POST_MICBIAS_2_ON); + } + break; + case SND_SOC_DAPM_POST_PMD: + if (strnstr(w->name, internal1_text, strlen(w->name))) { + snd_soc_component_update_bits(component, micb_int_reg, + 0xC0, 0x40); + } else if (strnstr(w->name, internal2_text, strlen(w->name))) { + msm_anlg_cdc_notifier_call(component, + WCD_EVENT_POST_MICBIAS_2_OFF); + } else if (strnstr(w->name, internal3_text, 30)) { + snd_soc_component_update_bits(component, micb_int_reg, + 0x2, 0x0); + } else if (strnstr(w->name, external2_text, strlen(w->name))) { + /* + * send micbias turn off event to mbhc driver and then + * break, as no need to set MICB_1_EN register. + */ + msm_anlg_cdc_notifier_call(component, + WCD_EVENT_POST_MICBIAS_2_OFF); + break; + } + if (w->reg == MSM89XX_PMIC_ANALOG_MICB_1_EN) + msm_anlg_cdc_configure_cap(component, false, micbias2); + break; + } + return 0; +} + +static void set_compander_mode(void *handle, int val) +{ + struct sdm660_cdc_priv *handle_cdc = handle; + struct snd_soc_component *component = handle_cdc->component; + + if (get_codec_version(handle_cdc) >= DIANGU) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, + 0x08, val); + }; +} + +static void update_clkdiv(void *handle, int val) +{ + struct sdm660_cdc_priv *handle_cdc = handle; + struct snd_soc_component *component = handle_cdc->component; + + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_TX_1_2_TXFE_CLKDIV, + 0xFF, val); +} + +static int get_cdc_version(void *handle) +{ + struct sdm660_cdc_priv *sdm660_cdc = handle; + + return get_codec_version(sdm660_cdc); +} + +static int sdm660_wcd_codec_enable_vdd_spkr(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + int ret = 0; + + if (!sdm660_cdc->ext_spk_boost_set) { + dev_dbg(component->dev, "%s: ext_boost not supported/disabled\n", + __func__); + return 0; + } + dev_dbg(component->dev, "%s: %s %d\n", __func__, w->name, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (sdm660_cdc->spkdrv_reg) { + ret = regulator_enable(sdm660_cdc->spkdrv_reg); + if (ret) + dev_err(component->dev, + "%s Failed to enable spkdrv reg %s\n", + __func__, MSM89XX_VDD_SPKDRV_NAME); + } + break; + case SND_SOC_DAPM_POST_PMD: + if (sdm660_cdc->spkdrv_reg) { + ret = regulator_disable(sdm660_cdc->spkdrv_reg); + if (ret) + dev_err(component->dev, + "%s: Failed to disable spkdrv_reg %s\n", + __func__, MSM89XX_VDD_SPKDRV_NAME); + } + break; + } + return 0; +} + + +/* The register address is the same as other codec so it can use resmgr */ +static int msm_anlg_cdc_codec_enable_rx_bias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + sdm660_cdc->rx_bias_count++; + if (sdm660_cdc->rx_bias_count == 1) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, + 0x80, 0x80); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, + 0x01, 0x01); + } + break; + case SND_SOC_DAPM_POST_PMD: + sdm660_cdc->rx_bias_count--; + if (sdm660_cdc->rx_bias_count == 0) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, + 0x01, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, + 0x80, 0x00); + } + break; + } + dev_dbg(component->dev, "%s rx_bias_count = %d\n", + __func__, sdm660_cdc->rx_bias_count); + return 0; +} + +static uint32_t wcd_get_impedance_value(uint32_t imped) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(wcd_imped_val) - 1; i++) { + if (imped >= wcd_imped_val[i] && + imped < wcd_imped_val[i + 1]) + break; + } + + pr_debug("%s: selected impedance value = %d\n", + __func__, wcd_imped_val[i]); + return wcd_imped_val[i]; +} + +static void wcd_imped_config(struct snd_soc_component *component, + uint32_t imped, bool set_gain) +{ + uint32_t value; + int codec_version; + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + value = wcd_get_impedance_value(imped); + + if (value < wcd_imped_val[0]) { + dev_dbg(component->dev, + "%s, detected impedance is less than 4 Ohm\n", + __func__); + return; + } + + codec_version = get_codec_version(sdm660_cdc); + + if (set_gain) { + switch (codec_version) { + case TOMBAK_1_0: + case TOMBAK_2_0: + case CONGA: + /* + * For 32Ohm load and higher loads, Set 0x19E + * bit 5 to 1 (POS_0_DB_DI). For loads lower + * than 32Ohm (such as 16Ohm load), Set 0x19E + * bit 5 to 0 (POS_M4P5_DB_DI) + */ + if (value >= 32) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x20, 0x20); + else + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x20, 0x00); + break; + case CAJON: + case CAJON_2_0: + case DIANGU: + case DRAX_CDC: + if (value >= 13) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x20, 0x20); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_NCP_VCTRL, + 0x07, 0x07); + } else { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x20, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_NCP_VCTRL, + 0x07, 0x04); + } + break; + } + } else { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x20, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_NCP_VCTRL, + 0x07, 0x04); + } + + dev_dbg(component->dev, "%s: Exit\n", __func__); +} + +static int msm_anlg_cdc_hphl_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + uint32_t impedl, impedr; + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + int ret; + + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); + ret = wcd_mbhc_get_impedance(&sdm660_cdc->mbhc, + &impedl, &impedr); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (get_codec_version(sdm660_cdc) > CAJON) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, + 0x08, 0x08); + if (get_codec_version(sdm660_cdc) == CAJON || + get_codec_version(sdm660_cdc) == CAJON_2_0) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, + 0x80, 0x80); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, + 0x80, 0x80); + } + if (get_codec_version(sdm660_cdc) > CAJON) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, + 0x08, 0x00); + if (sdm660_cdc->hph_mode == HD2_MODE) + msm_anlg_cdc_dig_notifier_call(component, + DIG_CDC_EVENT_PRE_RX1_INT_ON); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x02, 0x02); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x01); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x02); + if (!ret) + wcd_imped_config(component, impedl, true); + else + dev_dbg(component->dev, "Failed to get mbhc impedance %d\n", + ret); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x02, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + wcd_imped_config(component, impedl, false); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x00); + if (sdm660_cdc->hph_mode == HD2_MODE) + msm_anlg_cdc_dig_notifier_call(component, + DIG_CDC_EVENT_POST_RX1_INT_OFF); + break; + } + return 0; +} + +static int msm_anlg_cdc_lo_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x20, 0x20); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x80, 0x80); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x08, 0x08); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x40, 0x40); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x80, 0x80); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x08, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x40, 0x40); + break; + case SND_SOC_DAPM_POST_PMD: + /* Wait for 20ms before powerdown of lineout_dac */ + usleep_range(20000, 20100); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x80, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x40, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL, 0x08, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x80, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x40, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, 0x20, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00); + break; + } + return 0; +} + +static int msm_anlg_cdc_hphr_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (sdm660_cdc->hph_mode == HD2_MODE) + msm_anlg_cdc_dig_notifier_call(component, + DIG_CDC_EVENT_PRE_RX2_INT_ON); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x02, 0x02); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x02, 0x02); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x01, 0x01); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x02, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, 0x01, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, 0x02, 0x00); + if (sdm660_cdc->hph_mode == HD2_MODE) + msm_anlg_cdc_dig_notifier_call(component, + DIG_CDC_EVENT_POST_RX2_INT_OFF); + break; + } + return 0; +} + +static int msm_anlg_cdc_hph_pa_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: %s event = %d\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (w->shift == 5) + msm_anlg_cdc_notifier_call(component, + WCD_EVENT_PRE_HPHL_PA_ON); + else if (w->shift == 4) + msm_anlg_cdc_notifier_call(component, + WCD_EVENT_PRE_HPHR_PA_ON); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0x20, 0x20); + break; + + case SND_SOC_DAPM_POST_PMU: + /* Wait for 7ms to allow setting time for HPH_PA Enable */ + usleep_range(7000, 7100); + if (w->shift == 5) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x04, 0x04); + msm_anlg_cdc_dig_notifier_call(component, + DIG_CDC_EVENT_RX1_MUTE_OFF); + } else if (w->shift == 4) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x04, 0x04); + msm_anlg_cdc_dig_notifier_call(component, + DIG_CDC_EVENT_RX2_MUTE_OFF); + } + break; + + case SND_SOC_DAPM_PRE_PMD: + if (w->shift == 5) { + msm_anlg_cdc_dig_notifier_call(component, + DIG_CDC_EVENT_RX1_MUTE_ON); + /* Wait for 20ms after HPHL RX digital mute */ + msleep(20); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x04, 0x00); + msm_anlg_cdc_notifier_call(component, + WCD_EVENT_PRE_HPHL_PA_OFF); + } else if (w->shift == 4) { + msm_anlg_cdc_dig_notifier_call(component, + DIG_CDC_EVENT_RX2_MUTE_ON); + /* Wait for 20ms after HPHR RX digital mute */ + msleep(20); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x04, 0x00); + msm_anlg_cdc_notifier_call(component, + WCD_EVENT_PRE_HPHR_PA_OFF); + } + if (get_codec_version(sdm660_cdc) >= CAJON) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_CNP, + 0xF0, 0x30); + } + break; + case SND_SOC_DAPM_POST_PMD: + if (w->shift == 5) { + clear_bit(WCD_MBHC_HPHL_PA_OFF_ACK, + &sdm660_cdc->mbhc.hph_pa_dac_state); + msm_anlg_cdc_notifier_call(component, + WCD_EVENT_POST_HPHL_PA_OFF); + } else if (w->shift == 4) { + clear_bit(WCD_MBHC_HPHR_PA_OFF_ACK, + &sdm660_cdc->mbhc.hph_pa_dac_state); + msm_anlg_cdc_notifier_call(component, + WCD_EVENT_POST_HPHR_PA_OFF); + } + /* Wait for 15ms after HPH RX teardown */ + usleep_range(15000, 15100); + break; + } + return 0; +} + +static const struct snd_soc_dapm_route audio_map[] = { + /* RDAC Connections */ + {"HPHR DAC", NULL, "RDAC2 MUX"}, + {"RDAC2 MUX", "RX1", "PDM_IN_RX1"}, + {"RDAC2 MUX", "RX2", "PDM_IN_RX2"}, + + /* WSA */ + {"WSA_SPK OUT", NULL, "WSA Spk Switch"}, + {"WSA Spk Switch", "WSA", "EAR PA"}, + + /* Earpiece (RX MIX1) */ + {"EAR", NULL, "EAR_S"}, + {"EAR_S", "Switch", "EAR PA"}, + {"EAR PA", NULL, "RX_BIAS"}, + {"EAR PA", NULL, "HPHL DAC"}, + {"EAR PA", NULL, "HPHR DAC"}, + {"EAR PA", NULL, "EAR CP"}, + + /* Headset (RX MIX1 and RX MIX2) */ + {"HEADPHONE", NULL, "HPHL PA"}, + {"HEADPHONE", NULL, "HPHR PA"}, + + {"Ext Spk", NULL, "Ext Spk Switch"}, + {"Ext Spk Switch", "On", "HPHL PA"}, + {"Ext Spk Switch", "On", "HPHR PA"}, + + {"HPHL PA", NULL, "HPHL"}, + {"HPHR PA", NULL, "HPHR"}, + {"HPHL", "Switch", "HPHL DAC"}, + {"HPHR", "Switch", "HPHR DAC"}, + {"HPHL PA", NULL, "CP"}, + {"HPHL PA", NULL, "RX_BIAS"}, + {"HPHR PA", NULL, "CP"}, + {"HPHR PA", NULL, "RX_BIAS"}, + {"HPHL DAC", NULL, "PDM_IN_RX1"}, + + {"SPK_OUT", NULL, "SPK PA"}, + {"SPK PA", NULL, "SPK_RX_BIAS"}, + {"SPK PA", NULL, "SPK"}, + {"SPK", "Switch", "SPK DAC"}, + {"SPK DAC", NULL, "PDM_IN_RX3"}, + {"SPK DAC", NULL, "VDD_SPKDRV"}, + + /* lineout */ + {"LINEOUT", NULL, "LINEOUT PA"}, + {"LINEOUT PA", NULL, "SPK_RX_BIAS"}, + {"LINEOUT PA", NULL, "LINE_OUT"}, + {"LINE_OUT", "Switch", "LINEOUT DAC"}, + {"LINEOUT DAC", NULL, "PDM_IN_RX3"}, + + /* lineout to WSA */ + {"WSA_SPK OUT", NULL, "LINEOUT PA"}, + + {"PDM_IN_RX1", NULL, "RX1 CLK"}, + {"PDM_IN_RX2", NULL, "RX2 CLK"}, + {"PDM_IN_RX3", NULL, "RX3 CLK"}, + + {"ADC1_OUT", NULL, "ADC1"}, + {"ADC2_OUT", NULL, "ADC2"}, + {"ADC3_OUT", NULL, "ADC3"}, + + /* ADC Connections */ + {"ADC2", NULL, "ADC2 MUX"}, + {"ADC3", NULL, "ADC2 MUX"}, + {"ADC2 MUX", "INP2", "ADC2_INP2"}, + {"ADC2 MUX", "INP3", "ADC2_INP3"}, + + {"ADC1", NULL, "ADC1_INP1"}, + {"ADC1_INP1", "Switch", "AMIC1"}, + {"ADC2_INP2", NULL, "AMIC2"}, + {"ADC2_INP3", NULL, "AMIC3"}, + + {"MIC BIAS Internal1", NULL, "INT_LDO_H"}, + {"MIC BIAS Internal2", NULL, "INT_LDO_H"}, + {"MIC BIAS External", NULL, "INT_LDO_H"}, + {"MIC BIAS External2", NULL, "INT_LDO_H"}, + {"MIC BIAS Internal1", NULL, "MICBIAS_REGULATOR"}, + {"MIC BIAS Internal2", NULL, "MICBIAS_REGULATOR"}, + {"MIC BIAS External", NULL, "MICBIAS_REGULATOR"}, + {"MIC BIAS External2", NULL, "MICBIAS_REGULATOR"}, +}; + +static int msm_anlg_cdc_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(dai->component); + + dev_dbg(dai->component->dev, "%s(): substream = %s stream = %d\n", + __func__, + substream->name, substream->stream); + /* + * If status_mask is BUS_DOWN it means SSR is not complete. + * So return error. + */ + if (test_bit(BUS_DOWN, &sdm660_cdc->status_mask)) { + dev_err(dai->component->dev, "Error, Device is not up post SSR\n"); + return -EINVAL; + } + return 0; +} + +static void msm_anlg_cdc_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + dev_dbg(dai->component->dev, + "%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); +} + +int msm_anlg_cdc_mclk_enable(struct snd_soc_component *component, + int mclk_enable, bool dapm) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: mclk_enable = %u, dapm = %d\n", + __func__, mclk_enable, dapm); + if (mclk_enable) { + sdm660_cdc->int_mclk0_enabled = true; + msm_anlg_cdc_codec_enable_clock_block(component, 1); + } else { + if (!sdm660_cdc->int_mclk0_enabled) { + dev_err(component->dev, "Error, MCLK already diabled\n"); + return -EINVAL; + } + sdm660_cdc->int_mclk0_enabled = false; + msm_anlg_cdc_codec_enable_clock_block(component, 0); + } + return 0; +} +EXPORT_SYMBOL(msm_anlg_cdc_mclk_enable); + +static int msm_anlg_cdc_set_dai_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + dev_dbg(dai->component->dev, "%s\n", __func__); + return 0; +} + +static int msm_anlg_cdc_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + dev_dbg(dai->component->dev, "%s\n", __func__); + return 0; +} + +static int msm_anlg_cdc_set_channel_map(struct snd_soc_dai *dai, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot) + +{ + dev_dbg(dai->component->dev, "%s\n", __func__); + return 0; +} + +static int msm_anlg_cdc_get_channel_map(struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot) + +{ + dev_dbg(dai->component->dev, "%s\n", __func__); + return 0; +} + +static struct snd_soc_dai_ops msm_anlg_cdc_dai_ops = { + .startup = msm_anlg_cdc_startup, + .shutdown = msm_anlg_cdc_shutdown, + .set_sysclk = msm_anlg_cdc_set_dai_sysclk, + .set_fmt = msm_anlg_cdc_set_dai_fmt, + .set_channel_map = msm_anlg_cdc_set_channel_map, + .get_channel_map = msm_anlg_cdc_get_channel_map, +}; + +static struct snd_soc_dai_driver msm_anlg_cdc_i2s_dai[] = { + { + .name = "msm_anlg_cdc_i2s_rx1", + .id = AIF1_PB, + .playback = { + .stream_name = "PDM Playback", + .rates = SDM660_CDC_RATES, + .formats = SDM660_CDC_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 3, + }, + .ops = &msm_anlg_cdc_dai_ops, + }, + { + .name = "msm_anlg_cdc_i2s_tx1", + .id = AIF1_CAP, + .capture = { + .stream_name = "PDM Capture", + .rates = SDM660_CDC_RATES, + .formats = SDM660_CDC_FORMATS, + .rate_max = 48000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 4, + }, + .ops = &msm_anlg_cdc_dai_ops, + }, + { + .name = "msm_anlg_cdc_i2s_tx2", + .id = AIF3_SVA, + .capture = { + .stream_name = "RecordSVA", + .rates = SDM660_CDC_RATES, + .formats = SDM660_CDC_FORMATS, + .rate_max = 48000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &msm_anlg_cdc_dai_ops, + }, + { + .name = "msm_anlg_vifeedback", + .id = AIF2_VIFEED, + .capture = { + .stream_name = "VIfeed", + .rates = SDM660_CDC_RATES, + .formats = SDM660_CDC_FORMATS, + .rate_max = 48000, + .rate_min = 48000, + .channels_min = 2, + .channels_max = 2, + }, + .ops = &msm_anlg_cdc_dai_ops, + }, +}; + + +static int msm_anlg_cdc_codec_enable_lo_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + + dev_dbg(component->dev, "%s: %d %s\n", __func__, event, w->name); + switch (event) { + case SND_SOC_DAPM_POST_PMU: + msm_anlg_cdc_dig_notifier_call(component, + DIG_CDC_EVENT_RX3_MUTE_OFF); + break; + case SND_SOC_DAPM_POST_PMD: + msm_anlg_cdc_dig_notifier_call(component, + DIG_CDC_EVENT_RX3_MUTE_ON); + break; + } + + return 0; +} + +static int msm_anlg_cdc_codec_enable_spk_ext_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: %s event = %d\n", __func__, + w->name, event); + switch (event) { + case SND_SOC_DAPM_POST_PMU: + dev_dbg(component->dev, + "%s: enable external speaker PA\n", __func__); + if (sdm660_cdc->codec_spk_ext_pa_cb) + sdm660_cdc->codec_spk_ext_pa_cb(component, 1); + break; + case SND_SOC_DAPM_PRE_PMD: + dev_dbg(component->dev, + "%s: enable external speaker PA\n", __func__); + if (sdm660_cdc->codec_spk_ext_pa_cb) + sdm660_cdc->codec_spk_ext_pa_cb(component, 0); + break; + } + return 0; +} + +static int msm_anlg_cdc_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + dev_dbg(component->dev, + "%s: Sleeping 20ms after select EAR PA\n", + __func__); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x80, 0x80); + if (get_codec_version(sdm660_cdc) < CONGA) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME, 0xFF, 0x2A); + if (get_codec_version(sdm660_cdc) >= DIANGU) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, 0x08, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x04, 0x04); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x04, 0x04); + } + break; + case SND_SOC_DAPM_POST_PMU: + dev_dbg(component->dev, + "%s: Sleeping 20ms after enabling EAR PA\n", + __func__); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x40, 0x40); + /* Wait for 7ms after EAR PA enable */ + usleep_range(7000, 7100); + msm_anlg_cdc_dig_notifier_call(component, + DIG_CDC_EVENT_RX1_MUTE_OFF); + break; + case SND_SOC_DAPM_PRE_PMD: + msm_anlg_cdc_dig_notifier_call(component, + DIG_CDC_EVENT_RX1_MUTE_ON); + /* Wait for 20ms for RX digital mute to take effect */ + msleep(20); + if (sdm660_cdc->boost_option == BOOST_ALWAYS) { + dev_dbg(component->dev, + "%s: boost_option:%d, tear down ear\n", + __func__, sdm660_cdc->boost_option); + msm_anlg_cdc_boost_mode_sequence(component, EAR_PMD); + } + if (get_codec_version(sdm660_cdc) >= DIANGU) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST, 0x04, 0x0); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST, 0x04, 0x0); + } + break; + case SND_SOC_DAPM_POST_PMD: + dev_dbg(component->dev, + "%s: Sleeping 7ms after disabling EAR PA\n", + __func__); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0x40, 0x00); + /* Wait for 7ms after EAR PA teardown */ + usleep_range(7000, 7100); + if (get_codec_version(sdm660_cdc) < CONGA) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME, 0xFF, 0x16); + if (get_codec_version(sdm660_cdc) >= DIANGU) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, 0x08, 0x08); + break; + } + return 0; +} + +static const struct snd_soc_dapm_widget msm_anlg_cdc_dapm_widgets[] = { + SND_SOC_DAPM_PGA_E("EAR PA", SND_SOC_NOPM, + 0, 0, NULL, 0, msm_anlg_cdc_codec_enable_ear_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("HPHL PA", MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, + 5, 0, NULL, 0, + msm_anlg_cdc_hph_pa_event, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("HPHR PA", MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, + 4, 0, NULL, 0, + msm_anlg_cdc_hph_pa_event, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("SPK PA", SND_SOC_NOPM, + 0, 0, NULL, 0, msm_anlg_cdc_codec_enable_spk_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("LINEOUT PA", MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL, + 5, 0, NULL, 0, msm_anlg_cdc_codec_enable_lo_pa, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("EAR_S", SND_SOC_NOPM, 0, 0, ear_pa_mux), + SND_SOC_DAPM_MUX("SPK", SND_SOC_NOPM, 0, 0, spkr_mux), + SND_SOC_DAPM_MUX("HPHL", SND_SOC_NOPM, 0, 0, hphl_mux), + SND_SOC_DAPM_MUX("HPHR", SND_SOC_NOPM, 0, 0, hphr_mux), + SND_SOC_DAPM_MUX("RDAC2 MUX", SND_SOC_NOPM, 0, 0, &rdac2_mux), + SND_SOC_DAPM_MUX("WSA Spk Switch", SND_SOC_NOPM, 0, 0, wsa_spk_mux), + SND_SOC_DAPM_MUX("Ext Spk Switch", SND_SOC_NOPM, 0, 0, &ext_spk_mux), + SND_SOC_DAPM_MUX("LINE_OUT", SND_SOC_NOPM, 0, 0, lo_mux), + SND_SOC_DAPM_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, &tx_adc2_mux), + + SND_SOC_DAPM_MIXER_E("HPHL DAC", + MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 3, 0, NULL, + 0, msm_anlg_cdc_hphl_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("HPHR DAC", + MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 3, 0, NULL, + 0, msm_anlg_cdc_hphr_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("ADC2", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("ADC3", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_DAC("SPK DAC", NULL, MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, + 7, 0), + SND_SOC_DAPM_DAC_E("LINEOUT DAC", NULL, + SND_SOC_NOPM, 0, 0, msm_anlg_cdc_lo_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SPK("Ext Spk", msm_anlg_cdc_codec_enable_spk_ext_pa), + + SND_SOC_DAPM_SWITCH("ADC1_INP1", SND_SOC_NOPM, 0, 0, + &adc1_switch), + SND_SOC_DAPM_SUPPLY("RX1 CLK", MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("RX2 CLK", MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 1, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("RX3 CLK", MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 2, 0, msm_anlg_cdc_codec_enable_dig_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("CP", MSM89XX_PMIC_ANALOG_NCP_EN, 0, 0, + msm_anlg_cdc_codec_enable_charge_pump, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("EAR CP", MSM89XX_PMIC_ANALOG_NCP_EN, 4, 0, + msm_anlg_cdc_codec_enable_charge_pump, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("RX_BIAS", 1, SND_SOC_NOPM, + 0, 0, msm_anlg_cdc_codec_enable_rx_bias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("SPK_RX_BIAS", 1, SND_SOC_NOPM, 0, 0, + msm_anlg_cdc_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("VDD_SPKDRV", SND_SOC_NOPM, 0, 0, + sdm660_wcd_codec_enable_vdd_spkr, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("INT_LDO_H", SND_SOC_NOPM, 1, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("MICBIAS_REGULATOR", SND_SOC_NOPM, + ON_DEMAND_MICBIAS, 0, + msm_anlg_cdc_codec_enable_on_demand_supply, + SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MICBIAS_E("MIC BIAS Internal1", + MSM89XX_PMIC_ANALOG_MICB_1_EN, 7, 0, + msm_anlg_cdc_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS Internal2", + MSM89XX_PMIC_ANALOG_MICB_2_EN, 7, 0, + msm_anlg_cdc_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS Internal3", + MSM89XX_PMIC_ANALOG_MICB_1_EN, 7, 0, + msm_anlg_cdc_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("ADC1", NULL, MSM89XX_PMIC_ANALOG_TX_1_EN, 7, 0, + msm_anlg_cdc_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("ADC2_INP2", + NULL, MSM89XX_PMIC_ANALOG_TX_2_EN, 7, 0, + msm_anlg_cdc_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("ADC2_INP3", + NULL, MSM89XX_PMIC_ANALOG_TX_3_EN, 7, 0, + msm_anlg_cdc_codec_enable_adc, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MICBIAS_E("MIC BIAS External", + MSM89XX_PMIC_ANALOG_MICB_1_EN, 7, 0, + msm_anlg_cdc_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MICBIAS_E("MIC BIAS External2", + MSM89XX_PMIC_ANALOG_MICB_2_EN, 7, 0, + msm_anlg_cdc_codec_enable_micbias, SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_INPUT("AMIC1"), + SND_SOC_DAPM_INPUT("AMIC2"), + SND_SOC_DAPM_INPUT("AMIC3"), + SND_SOC_DAPM_AIF_IN("PDM_IN_RX1", "PDM Playback", + 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("PDM_IN_RX2", "PDM Playback", + 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("PDM_IN_RX3", "PDM Playback", + 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_OUTPUT("EAR"), + SND_SOC_DAPM_OUTPUT("WSA_SPK OUT"), + SND_SOC_DAPM_OUTPUT("HEADPHONE"), + SND_SOC_DAPM_OUTPUT("SPK_OUT"), + SND_SOC_DAPM_OUTPUT("LINEOUT"), + SND_SOC_DAPM_AIF_OUT("ADC1_OUT", "PDM Capture", + 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("ADC2_OUT", "PDM Capture", + 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("ADC3_OUT", "PDM Capture", + 0, SND_SOC_NOPM, 0, 0), +}; + +static const struct sdm660_cdc_reg_mask_val msm_anlg_cdc_reg_defaults[] = { + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x03), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x82), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1), +}; + +static const struct sdm660_cdc_reg_mask_val + msm_anlg_cdc_reg_defaults_2_0[] = { + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0xA5), + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x0F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x4F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0x28), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x69), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x01), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_BOOST_EN_CTL, 0x5F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO, 0x88), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0xA5), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x0F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x82), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x03), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1), + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80), +}; + +static const struct sdm660_cdc_reg_mask_val conga_wcd_reg_defaults[] = { + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0xA5), + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x0F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0xA5), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x0F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x4C), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0x28), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x69), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x01), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_PERPH_SUBTYPE, 0x0A), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x03), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1), + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80), +}; + +static const struct sdm660_cdc_reg_mask_val cajon_wcd_reg_defaults[] = { + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0xA5), + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x0F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0xA5), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x0F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x4C), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0x82), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0xA8), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_VCTRL, 0xA4), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET, 0x41), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x69), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x01), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x03), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA, 0xFA), + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80), +}; + +static const struct sdm660_cdc_reg_mask_val cajon2p0_wcd_reg_defaults[] = { + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_SEC_ACCESS, 0xA5), + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3, 0x0F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SEC_ACCESS, 0xA5), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3, 0x0F), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS, 0x4C), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_CURRENT_LIMIT, 0xA2), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_FBCTRL, 0xA8), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_NCP_VCTRL, 0xA4), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET, 0x41), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x69), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG, 0x01), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL, 0xE1), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x03), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_RX_EAR_STATUS, 0x10), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_BYPASS_MODE, 0x18), + MSM89XX_REG_VAL(MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA, 0xFA), + MSM89XX_REG_VAL(MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80), +}; + +static void msm_anlg_cdc_update_reg_defaults( + struct snd_soc_component *component) +{ + u32 i, version; + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + + version = get_codec_version(sdm660_cdc); + if (version == TOMBAK_1_0) { + for (i = 0; i < ARRAY_SIZE(msm_anlg_cdc_reg_defaults); i++) + snd_soc_component_write(component, + msm_anlg_cdc_reg_defaults[i].reg, + msm_anlg_cdc_reg_defaults[i].val); + } else if (version == TOMBAK_2_0) { + for (i = 0; i < ARRAY_SIZE(msm_anlg_cdc_reg_defaults_2_0); i++) + snd_soc_component_write(component, + msm_anlg_cdc_reg_defaults_2_0[i].reg, + msm_anlg_cdc_reg_defaults_2_0[i].val); + } else if (version == CONGA) { + for (i = 0; i < ARRAY_SIZE(conga_wcd_reg_defaults); i++) + snd_soc_component_write(component, + conga_wcd_reg_defaults[i].reg, + conga_wcd_reg_defaults[i].val); + } else if (version == CAJON) { + for (i = 0; i < ARRAY_SIZE(cajon_wcd_reg_defaults); i++) + snd_soc_component_write(component, + cajon_wcd_reg_defaults[i].reg, + cajon_wcd_reg_defaults[i].val); + } else if (version == CAJON_2_0 || version == DIANGU + || version == DRAX_CDC) { + for (i = 0; i < ARRAY_SIZE(cajon2p0_wcd_reg_defaults); i++) + snd_soc_component_write(component, + cajon2p0_wcd_reg_defaults[i].reg, + cajon2p0_wcd_reg_defaults[i].val); + } +} + +static const struct sdm660_cdc_reg_mask_val + msm_anlg_cdc_codec_reg_init_val[] = { + + /* Initialize current threshold to 350MA + * number of wait and run cycles to 4096 + */ + {MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL, 0xFF, 0x12}, + {MSM89XX_PMIC_ANALOG_RX_COM_OCP_COUNT, 0xFF, 0xFF}, +}; + +static void msm_anlg_cdc_codec_init_reg(struct snd_soc_component *component) +{ + u32 i; + + for (i = 0; i < ARRAY_SIZE(msm_anlg_cdc_codec_reg_init_val); i++) + snd_soc_component_update_bits(component, + msm_anlg_cdc_codec_reg_init_val[i].reg, + msm_anlg_cdc_codec_reg_init_val[i].mask, + msm_anlg_cdc_codec_reg_init_val[i].val); +} + +static int msm_anlg_cdc_bringup(struct snd_soc_component *component) +{ + snd_soc_component_write(component, + MSM89XX_PMIC_DIGITAL_SEC_ACCESS, + 0xA5); + snd_soc_component_write(component, + MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4, 0x01); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_SEC_ACCESS, + 0xA5); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4, 0x01); + snd_soc_component_write(component, + MSM89XX_PMIC_DIGITAL_SEC_ACCESS, + 0xA5); + snd_soc_component_write(component, + MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4, 0x00); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_SEC_ACCESS, + 0xA5); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4, 0x00); + + return 0; +} + +static struct regulator *msm_anlg_cdc_find_regulator( + const struct sdm660_cdc_priv *sdm660_cdc, + const char *name) +{ + int i; + + for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { + if (sdm660_cdc->supplies[i].supply && + !strcmp(sdm660_cdc->supplies[i].supply, name)) + return sdm660_cdc->supplies[i].consumer; + } + + dev_dbg(sdm660_cdc->dev, "Error: regulator not found:%s\n" + , name); + return NULL; +} + +static void msm_anlg_cdc_update_micbias_regulator( + const struct sdm660_cdc_priv *sdm660_cdc, + const char *name, + struct on_demand_supply *micbias_supply) +{ + int i; + struct sdm660_cdc_pdata *pdata = sdm660_cdc->dev->platform_data; + + for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { + if (sdm660_cdc->supplies[i].supply && + !strcmp(sdm660_cdc->supplies[i].supply, name)) { + micbias_supply->supply = + sdm660_cdc->supplies[i].consumer; + micbias_supply->min_uv = pdata->regulator[i].min_uv; + micbias_supply->max_uv = pdata->regulator[i].max_uv; + micbias_supply->optimum_ua = + pdata->regulator[i].optimum_ua; + return; + } + } + + dev_err(sdm660_cdc->dev, "Error: regulator not found:%s\n", name); +} + +static int msm_anlg_cdc_device_down(struct snd_soc_component *component) +{ + struct msm_asoc_mach_data *pdata = NULL; + struct sdm660_cdc_priv *sdm660_cdc_priv = + snd_soc_component_get_drvdata(component); + unsigned int tx_1_en; + unsigned int tx_2_en; + + pdata = snd_soc_card_get_drvdata(component->card); + dev_dbg(component->dev, "%s: device down!\n", __func__); + + tx_1_en = snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_TX_1_EN); + tx_2_en = snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_TX_2_EN); + tx_1_en = tx_1_en & 0x7f; + tx_2_en = tx_2_en & 0x7f; + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_TX_1_EN, tx_1_en); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_TX_2_EN, tx_2_en); + if (sdm660_cdc_priv->boost_option == BOOST_ON_FOREVER) { + if ((snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL) + & 0x80) == 0) { + msm_anlg_cdc_dig_notifier_call(component, + DIG_CDC_EVENT_CLK_ON); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, 0x30); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_RST_CTL, 0x80, 0x80); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL, + 0x0C, 0x0C); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL, + 0x84, 0x84); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL, + 0x10, 0x10); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, + 0x1F, 0x1F); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC, + 0x90, 0x90); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, + 0xFF, 0xFF); + /* Wait for 20us for boost settings to take effect */ + usleep_range(20, 21); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL, + 0xFF, 0xFF); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, + 0xE9, 0xE9); + } + } + msm_anlg_cdc_boost_off(component); + sdm660_cdc_priv->hph_mode = NORMAL_MODE; + + /* 40ms to allow boost to discharge */ + msleep(40); + /* Disable PA to avoid pop during codec bring up */ + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN, 0x30, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL, 0x80, 0x00); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x20); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x20); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_RX_EAR_CTL, 0x12); + snd_soc_component_write(component, + MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x93); + + msm_anlg_cdc_dig_notifier_call(component, DIG_CDC_EVENT_SSR_DOWN); + atomic_set(&pdata->int_mclk0_enabled, false); + set_bit(BUS_DOWN, &sdm660_cdc_priv->status_mask); + snd_soc_card_change_online_state(component->card, 0); + + return 0; +} + +static int msm_anlg_cdc_device_up(struct snd_soc_component *component) +{ + struct sdm660_cdc_priv *sdm660_cdc_priv = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s: device up!\n", __func__); + + msm_anlg_cdc_dig_notifier_call(component, DIG_CDC_EVENT_SSR_UP); + clear_bit(BUS_DOWN, &sdm660_cdc_priv->status_mask); + snd_soc_card_change_online_state(component->card, 1); + /* delay is required to make sure sound card state updated */ + usleep_range(5000, 5100); + + snd_soc_component_write(component, MSM89XX_PMIC_DIGITAL_INT_EN_SET, + MSM89XX_PMIC_DIGITAL_INT_EN_SET__POR); + snd_soc_component_write(component, MSM89XX_PMIC_DIGITAL_INT_EN_CLR, + MSM89XX_PMIC_DIGITAL_INT_EN_CLR__POR); + + msm_anlg_cdc_set_boost_v(component); + msm_anlg_cdc_set_micb_v(component); + if (sdm660_cdc_priv->boost_option == BOOST_ON_FOREVER) + msm_anlg_cdc_boost_on(component); + else if (sdm660_cdc_priv->boost_option == BYPASS_ALWAYS) + msm_anlg_cdc_bypass_on(component); + + return 0; +} + +static int sdm660_cdc_notifier_service_cb(struct notifier_block *nb, + unsigned long opcode, void *ptr) +{ + struct snd_soc_component *component; + struct sdm660_cdc_priv *sdm660_cdc_priv = + container_of(nb, struct sdm660_cdc_priv, + audio_ssr_nb); + bool adsp_ready = false; + bool timedout; + unsigned long timeout; + static bool initial_boot = true; + + component = sdm660_cdc_priv->component; + dev_dbg(component->dev, "%s: Service opcode 0x%lx\n", __func__, opcode); + + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + if (initial_boot) { + initial_boot = false; + break; + } + dev_dbg(component->dev, + "ADSP is about to power down. teardown/reset codec\n"); + msm_anlg_cdc_device_down(component); + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (initial_boot) + initial_boot = false; + dev_dbg(component->dev, + "ADSP is about to power up. bring up codec\n"); + + if (!q6core_is_adsp_ready()) { + dev_dbg(component->dev, + "ADSP isn't ready\n"); + timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + while (!(timedout = time_after(jiffies, timeout))) { + if (!q6core_is_adsp_ready()) { + dev_dbg(component->dev, + "ADSP isn't ready\n"); + } else { + dev_dbg(component->dev, + "ADSP is ready\n"); + adsp_ready = true; + goto powerup; + } + } + } else { + adsp_ready = true; + dev_dbg(component->dev, "%s: DSP is ready\n", __func__); + } +powerup: + if (adsp_ready) + msm_anlg_cdc_device_up(component); + break; + default: + break; + } + return NOTIFY_OK; +} + +int msm_anlg_cdc_hs_detect(struct snd_soc_component *component, + struct wcd_mbhc_config *mbhc_cfg) +{ + struct sdm660_cdc_priv *sdm660_cdc_priv = + snd_soc_component_get_drvdata(component); + + return wcd_mbhc_start(&sdm660_cdc_priv->mbhc, mbhc_cfg); +} +EXPORT_SYMBOL(msm_anlg_cdc_hs_detect); + +void msm_anlg_cdc_hs_detect_exit(struct snd_soc_component *component) +{ + struct sdm660_cdc_priv *sdm660_cdc_priv = + snd_soc_component_get_drvdata(component); + + wcd_mbhc_stop(&sdm660_cdc_priv->mbhc); +} +EXPORT_SYMBOL(msm_anlg_cdc_hs_detect_exit); + +void msm_anlg_cdc_update_int_spk_boost(bool enable) +{ + pr_debug("%s: enable = %d\n", __func__, enable); + spkr_boost_en = enable; +} +EXPORT_SYMBOL(msm_anlg_cdc_update_int_spk_boost); + +static void msm_anlg_cdc_set_micb_v(struct snd_soc_component *component) +{ + + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + struct sdm660_cdc_pdata *pdata = sdm660_cdc->dev->platform_data; + u8 reg_val; + + reg_val = VOLTAGE_CONVERTER(pdata->micbias.cfilt1_mv, MICBIAS_MIN_VAL, + MICBIAS_STEP_SIZE); + dev_dbg(component->dev, "cfilt1_mv %d reg_val %x\n", + (u32)pdata->micbias.cfilt1_mv, reg_val); + snd_soc_component_update_bits(component, MSM89XX_PMIC_ANALOG_MICB_1_VAL, + 0xF8, (reg_val << 3)); +} + +static void msm_anlg_cdc_set_boost_v(struct snd_soc_component *component) +{ + struct sdm660_cdc_priv *sdm660_cdc_priv = + snd_soc_component_get_drvdata(component); + + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_OUTPUT_VOLTAGE, + 0x1F, sdm660_cdc_priv->boost_voltage); +} + +static void msm_anlg_cdc_configure_cap(struct snd_soc_component *component, + bool micbias1, bool micbias2) +{ + + struct msm_asoc_mach_data *pdata = NULL; + + pdata = snd_soc_card_get_drvdata(component->card); + + pr_debug("\n %s: micbias1 %x micbias2 = %d\n", __func__, micbias1, + micbias2); + if (micbias1 && micbias2) { + if ((pdata->micbias1_cap_mode + == MICBIAS_EXT_BYP_CAP) || + (pdata->micbias2_cap_mode + == MICBIAS_EXT_BYP_CAP)) + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_1_EN, + 0x40, (MICBIAS_EXT_BYP_CAP << 6)); + else + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_1_EN, + 0x40, (MICBIAS_NO_EXT_BYP_CAP << 6)); + } else if (micbias2) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_1_EN, + 0x40, (pdata->micbias2_cap_mode << 6)); + } else if (micbias1) { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_1_EN, 0x40, + (pdata->micbias1_cap_mode << 6)); + } else { + snd_soc_component_update_bits(component, + MSM89XX_PMIC_ANALOG_MICB_1_EN, 0x40, 0x00); + } +} + +static ssize_t msm_anlg_codec_version_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, size_t count, + loff_t pos) +{ + struct sdm660_cdc_priv *sdm660_cdc_priv; + char buffer[MSM_ANLG_CDC_VERSION_ENTRY_SIZE]; + int len = 0; + + sdm660_cdc_priv = (struct sdm660_cdc_priv *) entry->private_data; + if (!sdm660_cdc_priv) { + pr_err("%s: sdm660_cdc_priv is null\n", __func__); + return -EINVAL; + } + + switch (get_codec_version(sdm660_cdc_priv)) { + case DRAX_CDC: + len = snprintf(buffer, sizeof(buffer), "DRAX-CDC_1_0\n"); + break; + default: + len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + } + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops msm_anlg_codec_info_ops = { + .read = msm_anlg_codec_version_read, +}; + +/* + * msm_anlg_codec_info_create_codec_entry - creates pmic_analog module + * @codec_root: The parent directory + * @codec: Codec instance + * + * Creates pmic_analog module and version entry under the given + * parent directory. + * + * Return: 0 on success or negative error code on failure. + */ +int msm_anlg_codec_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_component *component) +{ + struct snd_info_entry *version_entry; + struct sdm660_cdc_priv *sdm660_cdc_priv; + struct snd_soc_card *card; + int ret; + + if (!codec_root || !component) + return -EINVAL; + + sdm660_cdc_priv = snd_soc_component_get_drvdata(component); + card = component->card; + sdm660_cdc_priv->entry = snd_info_create_subdir(codec_root->module, + "spmi0-03", + codec_root); + if (!sdm660_cdc_priv->entry) { + dev_dbg(component->dev, "%s: failed to create pmic_analog entry\n", + __func__); + return -ENOMEM; + } + + version_entry = snd_info_create_card_entry(card->snd_card, + "version", + sdm660_cdc_priv->entry); + if (!version_entry) { + dev_dbg(component->dev, "%s: failed to create pmic_analog version entry\n", + __func__); + return -ENOMEM; + } + + version_entry->private_data = sdm660_cdc_priv; + version_entry->size = MSM_ANLG_CDC_VERSION_ENTRY_SIZE; + version_entry->content = SNDRV_INFO_CONTENT_DATA; + version_entry->c.ops = &msm_anlg_codec_info_ops; + + if (snd_info_register(version_entry) < 0) { + snd_info_free_entry(version_entry); + return -ENOMEM; + } + sdm660_cdc_priv->version_entry = version_entry; + + sdm660_cdc_priv->audio_ssr_nb.notifier_call = + sdm660_cdc_notifier_service_cb; + ret = audio_notifier_register("pmic_analog_cdc", + AUDIO_NOTIFIER_ADSP_DOMAIN, + &sdm660_cdc_priv->audio_ssr_nb); + if (ret < 0) { + pr_err("%s: Audio notifier register failed ret = %d\n", + __func__, ret); + return ret; + } + return 0; +} +EXPORT_SYMBOL(msm_anlg_codec_info_create_codec_entry); + +static int msm_anlg_cdc_soc_probe(struct snd_soc_component *component) +{ + struct sdm660_cdc_priv *sdm660_cdc; + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); + int ret; + + sdm660_cdc = dev_get_drvdata(component->dev); + sdm660_cdc->component = component; + + snd_soc_component_init_regmap(component, sdm660_cdc->regmap); + /* codec resmgr module init */ + sdm660_cdc->spkdrv_reg = + msm_anlg_cdc_find_regulator(sdm660_cdc, + MSM89XX_VDD_SPKDRV_NAME); + sdm660_cdc->pmic_rev = + snd_soc_component_read32(component, + MSM89XX_PMIC_DIGITAL_REVISION1); + sdm660_cdc->codec_version = + snd_soc_component_read32(component, + MSM89XX_PMIC_DIGITAL_PERPH_SUBTYPE); + sdm660_cdc->analog_major_rev = + snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_REVISION4); + + if (sdm660_cdc->codec_version == CONGA) { + dev_dbg(component->dev, "%s :Conga REV: %d\n", __func__, + sdm660_cdc->codec_version); + sdm660_cdc->ext_spk_boost_set = true; + } else { + dev_dbg(component->dev, "%s :PMIC REV: %d\n", __func__, + sdm660_cdc->pmic_rev); + if (sdm660_cdc->pmic_rev == TOMBAK_1_0 && + sdm660_cdc->codec_version == CAJON_2_0) { + if (sdm660_cdc->analog_major_rev == 0x02) { + sdm660_cdc->codec_version = DRAX_CDC; + dev_dbg(component->dev, + "%s : Drax codec detected\n", __func__); + } else { + sdm660_cdc->codec_version = DIANGU; + dev_dbg(component->dev, + "%s : Diangu detected\n", __func__); + } + } else if (sdm660_cdc->pmic_rev == TOMBAK_1_0 && + (snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_NCP_FBCTRL) + & 0x80)) { + sdm660_cdc->codec_version = CAJON; + dev_dbg(component->dev, "%s : Cajon detected\n", + __func__); + } else if (sdm660_cdc->pmic_rev == TOMBAK_2_0 && + (snd_soc_component_read32(component, + MSM89XX_PMIC_ANALOG_NCP_FBCTRL) + & 0x80)) { + sdm660_cdc->codec_version = CAJON_2_0; + dev_dbg(component->dev, "%s : Cajon 2.0 detected\n", + __func__); + } + } + /* + * set to default boost option BOOST_SWITCH, user mixer path can change + * it to BOOST_ALWAYS or BOOST_BYPASS based on solution chosen. + */ + sdm660_cdc->boost_option = BOOST_SWITCH; + sdm660_cdc->hph_mode = NORMAL_MODE; + + msm_anlg_cdc_dt_parse_boost_info(component); + msm_anlg_cdc_set_boost_v(component); + + snd_soc_add_component_controls(component, impedance_detect_controls, + ARRAY_SIZE(impedance_detect_controls)); + snd_soc_add_component_controls(component, hph_type_detect_controls, + ARRAY_SIZE(hph_type_detect_controls)); + + msm_anlg_cdc_bringup(component); + msm_anlg_cdc_codec_init_reg(component); + msm_anlg_cdc_update_reg_defaults(component); + + wcd9xxx_spmi_set_codec(component); + + msm_anlg_cdc_update_micbias_regulator( + sdm660_cdc, + on_demand_supply_name[ON_DEMAND_MICBIAS], + &sdm660_cdc->on_demand_list[ON_DEMAND_MICBIAS]); + atomic_set(&sdm660_cdc->on_demand_list[ON_DEMAND_MICBIAS].ref, + 0); + + sdm660_cdc->fw_data = devm_kzalloc(component->dev, + sizeof(*(sdm660_cdc->fw_data)), + GFP_KERNEL); + if (!sdm660_cdc->fw_data) + return -ENOMEM; + + set_bit(WCD9XXX_MBHC_CAL, sdm660_cdc->fw_data->cal_bit); + ret = wcd_cal_create_hwdep(sdm660_cdc->fw_data, + WCD9XXX_CODEC_HWDEP_NODE, component); + if (ret < 0) { + dev_err(component->dev, "%s hwdep failed %d\n", __func__, ret); + return ret; + } + + wcd_mbhc_init(&sdm660_cdc->mbhc, component, &mbhc_cb, &intr_ids, + wcd_mbhc_registers, true); + + sdm660_cdc->int_mclk0_enabled = false; + /*Update speaker boost configuration*/ + sdm660_cdc->spk_boost_set = spkr_boost_en; + pr_debug("%s: speaker boost configured = %d\n", + __func__, sdm660_cdc->spk_boost_set); + + /* Set initial MICBIAS voltage level */ + msm_anlg_cdc_set_micb_v(component); + + /* Set initial cap mode */ + msm_anlg_cdc_configure_cap(component, false, false); + + snd_soc_dapm_ignore_suspend(dapm, "PDM Playback"); + snd_soc_dapm_ignore_suspend(dapm, "PDM Capture"); + + snd_soc_dapm_sync(dapm); + + return 0; +} + +static void msm_anlg_cdc_soc_remove(struct snd_soc_component *component) +{ + struct sdm660_cdc_priv *sdm660_cdc_priv = + dev_get_drvdata(component->dev); + + sdm660_cdc_priv->spkdrv_reg = NULL; + sdm660_cdc_priv->on_demand_list[ON_DEMAND_MICBIAS].supply = NULL; + atomic_set(&sdm660_cdc_priv->on_demand_list[ON_DEMAND_MICBIAS].ref, + 0); + wcd_mbhc_deinit(&sdm660_cdc_priv->mbhc); +} + +static int msm_anlg_cdc_enable_static_supplies_to_optimum( + struct sdm660_cdc_priv *sdm660_cdc, + struct sdm660_cdc_pdata *pdata) +{ + int i; + int ret = 0, rc = 0; + + for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { + if (pdata->regulator[i].ondemand) + continue; + if (regulator_count_voltages( + sdm660_cdc->supplies[i].consumer) <= 0) + continue; + + rc = regulator_enable(sdm660_cdc->supplies[i].consumer); + if (rc) { + dev_err(sdm660_cdc->dev, "Failed to enable %s: %d\n", + sdm660_cdc->supplies[i].supply, rc); + break; + } + ret = regulator_set_voltage( + sdm660_cdc->supplies[i].consumer, + pdata->regulator[i].min_uv, + pdata->regulator[i].max_uv); + if (ret) { + dev_err(sdm660_cdc->dev, + "Setting volt failed for regulator %s err %d\n", + sdm660_cdc->supplies[i].supply, ret); + } + + ret = regulator_set_load(sdm660_cdc->supplies[i].consumer, + pdata->regulator[i].optimum_ua); + dev_dbg(sdm660_cdc->dev, "Regulator %s set optimum mode\n", + sdm660_cdc->supplies[i].supply); + } + + while (rc && i--) + if (!pdata->regulator[i].ondemand) + regulator_disable(sdm660_cdc->supplies[i].consumer); + return rc; +} + +static int msm_anlg_cdc_disable_static_supplies_to_optimum( + struct sdm660_cdc_priv *sdm660_cdc, + struct sdm660_cdc_pdata *pdata) +{ + int i; + int ret = 0; + + for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { + if (pdata->regulator[i].ondemand) + continue; + if (regulator_count_voltages( + sdm660_cdc->supplies[i].consumer) <= 0) + continue; + regulator_set_voltage(sdm660_cdc->supplies[i].consumer, 0, + pdata->regulator[i].max_uv); + regulator_set_load(sdm660_cdc->supplies[i].consumer, 0); + ret = regulator_disable(sdm660_cdc->supplies[i].consumer); + if (ret) + dev_err(sdm660_cdc->dev, "Failed to disable %s: %d\n", + sdm660_cdc->supplies[i].supply, ret); + + dev_dbg(sdm660_cdc->dev, "Regulator %s disable\n", + sdm660_cdc->supplies[i].supply); + } + + return ret; +} + +static int msm_anlg_cdc_suspend(struct snd_soc_component *component) +{ + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + struct sdm660_cdc_pdata *sdm660_cdc_pdata = + sdm660_cdc->dev->platform_data; + + msm_anlg_cdc_disable_static_supplies_to_optimum(sdm660_cdc, + sdm660_cdc_pdata); + return 0; +} + +static int msm_anlg_cdc_resume(struct snd_soc_component *component) +{ + struct msm_asoc_mach_data *pdata = NULL; + struct sdm660_cdc_priv *sdm660_cdc = + snd_soc_component_get_drvdata(component); + struct sdm660_cdc_pdata *sdm660_cdc_pdata = + sdm660_cdc->dev->platform_data; + + pdata = snd_soc_card_get_drvdata(component->card); + msm_anlg_cdc_enable_static_supplies_to_optimum(sdm660_cdc, + sdm660_cdc_pdata); + return 0; +} + +static const struct snd_soc_component_driver soc_codec_dev_sdm660_cdc = { + .name = DRV_NAME, + .probe = msm_anlg_cdc_soc_probe, + .remove = msm_anlg_cdc_soc_remove, + .suspend = msm_anlg_cdc_suspend, + .resume = msm_anlg_cdc_resume, + .controls = msm_anlg_cdc_snd_controls, + .num_controls = ARRAY_SIZE(msm_anlg_cdc_snd_controls), + .dapm_widgets = msm_anlg_cdc_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(msm_anlg_cdc_dapm_widgets), + .dapm_routes = audio_map, + .num_dapm_routes = ARRAY_SIZE(audio_map), +}; + +static int msm_anlg_cdc_init_supplies(struct sdm660_cdc_priv *sdm660_cdc, + struct sdm660_cdc_pdata *pdata) +{ + int ret; + int i; + + sdm660_cdc->supplies = devm_kzalloc(sdm660_cdc->dev, + sizeof(struct regulator_bulk_data) * + ARRAY_SIZE(pdata->regulator), + GFP_KERNEL); + if (!sdm660_cdc->supplies) { + ret = -ENOMEM; + goto err; + } + + sdm660_cdc->num_of_supplies = 0; + if (ARRAY_SIZE(pdata->regulator) > MAX_REGULATOR) { + dev_err(sdm660_cdc->dev, "%s: Array Size out of bound\n", + __func__); + ret = -EINVAL; + goto err; + } + + for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) { + if (pdata->regulator[i].name) { + sdm660_cdc->supplies[i].supply = + pdata->regulator[i].name; + sdm660_cdc->num_of_supplies++; + } + } + + ret = devm_regulator_bulk_get(sdm660_cdc->dev, + sdm660_cdc->num_of_supplies, + sdm660_cdc->supplies); + if (ret != 0) { + dev_err(sdm660_cdc->dev, + "Failed to get supplies: err = %d\n", + ret); + goto err_supplies; + } + + for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { + if (regulator_count_voltages( + sdm660_cdc->supplies[i].consumer) <= 0) + continue; + if (pdata->regulator[i].ondemand) { + ret = regulator_set_voltage( + sdm660_cdc->supplies[i].consumer, + 0, pdata->regulator[i].max_uv); + if (ret) { + dev_err(sdm660_cdc->dev, + "Setting regulator voltage failed for regulator %s err = %d\n", + sdm660_cdc->supplies[i].supply, ret); + goto err_supplies; + } + ret = regulator_set_load( + sdm660_cdc->supplies[i].consumer, 0); + if (ret < 0) { + dev_err(sdm660_cdc->dev, + "Setting regulator optimum mode failed for regulator %s err = %d\n", + sdm660_cdc->supplies[i].supply, ret); + goto err_supplies; + } else { + ret = 0; + continue; + } + } + ret = regulator_set_voltage(sdm660_cdc->supplies[i].consumer, + pdata->regulator[i].min_uv, + pdata->regulator[i].max_uv); + if (ret) { + dev_err(sdm660_cdc->dev, + "Setting regulator voltage failed for regulator %s err = %d\n", + sdm660_cdc->supplies[i].supply, ret); + goto err_supplies; + } + ret = regulator_set_load(sdm660_cdc->supplies[i].consumer, + pdata->regulator[i].optimum_ua); + if (ret < 0) { + dev_err(sdm660_cdc->dev, + "Setting regulator optimum mode failed for regulator %s err = %d\n", + sdm660_cdc->supplies[i].supply, ret); + goto err_supplies; + } else { + ret = 0; + } + } + + return ret; + +err_supplies: + devm_kfree(sdm660_cdc->dev, sdm660_cdc->supplies); +err: + return ret; +} + +static int msm_anlg_cdc_enable_static_supplies( + struct sdm660_cdc_priv *sdm660_cdc, + struct sdm660_cdc_pdata *pdata) +{ + int i; + int ret = 0; + + for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { + if (pdata->regulator[i].ondemand) + continue; + ret = regulator_enable(sdm660_cdc->supplies[i].consumer); + if (ret) { + dev_err(sdm660_cdc->dev, "Failed to enable %s\n", + sdm660_cdc->supplies[i].supply); + break; + } + dev_dbg(sdm660_cdc->dev, "Enabled regulator %s\n", + sdm660_cdc->supplies[i].supply); + } + + while (ret && i--) + if (!pdata->regulator[i].ondemand) + regulator_disable(sdm660_cdc->supplies[i].consumer); + return ret; +} + +static void msm_anlg_cdc_disable_supplies(struct sdm660_cdc_priv *sdm660_cdc, + struct sdm660_cdc_pdata *pdata) +{ + int i; + + regulator_bulk_disable(sdm660_cdc->num_of_supplies, + sdm660_cdc->supplies); + for (i = 0; i < sdm660_cdc->num_of_supplies; i++) { + if (regulator_count_voltages( + sdm660_cdc->supplies[i].consumer) <= 0) + continue; + regulator_set_voltage(sdm660_cdc->supplies[i].consumer, 0, + pdata->regulator[i].max_uv); + regulator_set_load(sdm660_cdc->supplies[i].consumer, 0); + } +} + +static const struct of_device_id sdm660_codec_of_match[] = { + { .compatible = "qcom,pmic-analog-codec", }, + {}, +}; + +static void msm_anlg_add_child_devices(struct work_struct *work) +{ + struct sdm660_cdc_priv *pdata; + struct platform_device *pdev; + struct device_node *node; + struct msm_dig_ctrl_data *dig_ctrl_data = NULL, *temp; + int ret, ctrl_num = 0; + struct msm_dig_ctrl_platform_data *platdata; + char plat_dev_name[MSM_DIG_CDC_STRING_LEN]; + + pdata = container_of(work, struct sdm660_cdc_priv, + msm_anlg_add_child_devices_work); + if (!pdata) { + pr_err("%s: Memory for pdata does not exist\n", + __func__); + return; + } + if (!pdata->dev->of_node) { + dev_err(pdata->dev, + "%s: DT node for pdata does not exist\n", __func__); + return; + } + + platdata = &pdata->dig_plat_data; + + for_each_child_of_node(pdata->dev->of_node, node) { + if (!strcmp(node->name, "msm-dig-codec")) + strlcpy(plat_dev_name, "msm_digital_codec", + (MSM_DIG_CDC_STRING_LEN - 1)); + else + continue; + + pdev = platform_device_alloc(plat_dev_name, -1); + if (!pdev) { + dev_err(pdata->dev, "%s: pdev memory alloc failed\n", + __func__); + ret = -ENOMEM; + goto err; + } + pdev->dev.parent = pdata->dev; + pdev->dev.of_node = node; + + if (!strcmp(node->name, "msm-dig-codec")) { + ret = platform_device_add_data(pdev, platdata, + sizeof(*platdata)); + if (ret) { + dev_err(&pdev->dev, + "%s: cannot add plat data ctrl:%d\n", + __func__, ctrl_num); + goto fail_pdev_add; + } + } + + ret = platform_device_add(pdev); + if (ret) { + dev_err(&pdev->dev, + "%s: Cannot add platform device\n", + __func__); + goto fail_pdev_add; + } + + if (!strcmp(node->name, "msm-dig-codec")) { + temp = krealloc(dig_ctrl_data, + (ctrl_num + 1) * sizeof( + struct msm_dig_ctrl_data), + GFP_KERNEL); + if (!temp) { + dev_err(&pdev->dev, "out of memory\n"); + ret = -ENOMEM; + goto err; + } + dig_ctrl_data = temp; + dig_ctrl_data[ctrl_num].dig_pdev = pdev; + ctrl_num++; + dev_dbg(&pdev->dev, + "%s: Added digital codec device(s)\n", + __func__); + pdata->dig_ctrl_data = dig_ctrl_data; + } + pdata->pdev_child_devices[pdata->child_count++] = pdev; + } + + return; +fail_pdev_add: + platform_device_put(pdev); +err: + return; +} + +static int msm_anlg_cdc_probe(struct platform_device *pdev) +{ + int ret = 0; + struct sdm660_cdc_priv *sdm660_cdc = NULL; + struct sdm660_cdc_pdata *pdata; + int adsp_state; + + adsp_state = apr_get_subsys_state(); + if (adsp_state != APR_SUBSYS_LOADED) { + dev_err(&pdev->dev, "Adsp is not loaded yet %d\n", + adsp_state); + return -EPROBE_DEFER; + } + device_init_wakeup(&pdev->dev, true); + + if (pdev->dev.of_node) { + dev_dbg(&pdev->dev, "%s:Platform data from device tree\n", + __func__); + pdata = msm_anlg_cdc_populate_dt_pdata(&pdev->dev); + pdev->dev.platform_data = pdata; + } else { + dev_dbg(&pdev->dev, "%s:Platform data from board file\n", + __func__); + pdata = pdev->dev.platform_data; + } + if (pdata == NULL) { + dev_err(&pdev->dev, "%s:Platform data failed to populate\n", + __func__); + goto rtn; + } + sdm660_cdc = devm_kzalloc(&pdev->dev, sizeof(struct sdm660_cdc_priv), + GFP_KERNEL); + if (sdm660_cdc == NULL) { + ret = -ENOMEM; + goto rtn; + } + + sdm660_cdc->dev = &pdev->dev; + ret = msm_anlg_cdc_init_supplies(sdm660_cdc, pdata); + if (ret) { + dev_err(&pdev->dev, "%s: Fail to enable Codec supplies\n", + __func__); + goto rtn; + } + ret = msm_anlg_cdc_enable_static_supplies(sdm660_cdc, pdata); + if (ret) { + dev_err(&pdev->dev, + "%s: Fail to enable Codec pre-reset supplies\n", + __func__); + goto rtn; + } + /* Allow supplies to be ready */ + usleep_range(5, 6); + + wcd9xxx_spmi_set_dev(pdev, 0); + wcd9xxx_spmi_set_dev(pdev, 1); + if (wcd9xxx_spmi_irq_init()) { + dev_err(&pdev->dev, + "%s: irq initialization failed\n", __func__); + } else { + dev_dbg(&pdev->dev, + "%s: irq initialization passed\n", __func__); + } + dev_set_drvdata(&pdev->dev, sdm660_cdc); + + sdm660_cdc->regmap = dev_get_regmap(sdm660_cdc->dev->parent, NULL); + if (IS_ERR_OR_NULL((void *)(sdm660_cdc->regmap))) { + dev_err(&pdev->dev, "%s:regmap init failed\n", __func__); + return -EINVAL; + } + + ret = snd_soc_register_component(&pdev->dev, + &soc_codec_dev_sdm660_cdc, + msm_anlg_cdc_i2s_dai, + ARRAY_SIZE(msm_anlg_cdc_i2s_dai)); + if (ret) { + dev_err(&pdev->dev, + "%s:snd_soc_register_component failed with error %d\n", + __func__, ret); + goto err_supplies; + } + BLOCKING_INIT_NOTIFIER_HEAD(&sdm660_cdc->notifier); + BLOCKING_INIT_NOTIFIER_HEAD(&sdm660_cdc->notifier_mbhc); + + sdm660_cdc->dig_plat_data.handle = (void *) sdm660_cdc; + sdm660_cdc->dig_plat_data.set_compander_mode = set_compander_mode; + sdm660_cdc->dig_plat_data.update_clkdiv = update_clkdiv; + sdm660_cdc->dig_plat_data.get_cdc_version = get_cdc_version; + sdm660_cdc->dig_plat_data.register_notifier = + msm_anlg_cdc_dig_register_notifier; + INIT_WORK(&sdm660_cdc->msm_anlg_add_child_devices_work, + msm_anlg_add_child_devices); + schedule_work(&sdm660_cdc->msm_anlg_add_child_devices_work); + + return ret; +err_supplies: + msm_anlg_cdc_disable_supplies(sdm660_cdc, pdata); +rtn: + return ret; +} + +static int msm_anlg_cdc_remove(struct platform_device *pdev) +{ + struct sdm660_cdc_priv *sdm660_cdc = dev_get_drvdata(&pdev->dev); + struct sdm660_cdc_pdata *pdata = sdm660_cdc->dev->platform_data; + int count; + + for (count = 0; count < sdm660_cdc->child_count && + count < ANLG_CDC_CHILD_DEVICES_MAX; count++) + platform_device_unregister( + sdm660_cdc->pdev_child_devices[count]); + snd_soc_unregister_component(&pdev->dev); + msm_anlg_cdc_disable_supplies(sdm660_cdc, pdata); + wcd9xxx_spmi_irq_exit(); + devm_kfree(&pdev->dev, sdm660_cdc); + return 0; +} + +static struct platform_driver msm_anlg_codec_driver = { + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + .of_match_table = of_match_ptr(sdm660_codec_of_match) + }, + .probe = msm_anlg_cdc_probe, + .remove = msm_anlg_cdc_remove, +}; +module_platform_driver(msm_anlg_codec_driver); + +MODULE_DESCRIPTION("MSM Audio Analog codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.h b/asoc/codecs/sdm660_cdc/msm-analog-cdc.h new file mode 100644 index 000000000000..dbeb76706e31 --- /dev/null +++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.h @@ -0,0 +1,269 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2015-2018, 2020, The Linux Foundation. All rights reserved. + */ +#ifndef MSM_ANALOG_CDC_H +#define MSM_ANALOG_CDC_H + +#include +#include +#include +#include +#include +#include "sdm660-cdc-registers.h" + +#define MICBIAS_EXT_BYP_CAP 0x00 +#define MICBIAS_NO_EXT_BYP_CAP 0x01 +#define ANLG_CDC_CHILD_DEVICES_MAX 1 + +#define MSM89XX_NUM_IRQ_REGS 2 +#define MAX_REGULATOR 7 +#define MSM89XX_REG_VAL(reg, val) {reg, 0, val} + +#define MSM89XX_VDD_SPKDRV_NAME "cdc-vdd-spkdrv" + +#define DEFAULT_MULTIPLIER 800 +#define DEFAULT_GAIN 9 +#define DEFAULT_OFFSET 100 + +extern const u8 msm89xx_pmic_cdc_reg_readable[MSM89XX_PMIC_CDC_CACHE_SIZE]; +extern const u8 msm89xx_cdc_core_reg_readable[MSM89XX_CDC_CORE_CACHE_SIZE]; +extern struct regmap_config msm89xx_cdc_core_regmap_config; +extern struct regmap_config msm89xx_pmic_cdc_regmap_config; + +enum wcd_curr_ref { + I_h4_UA = 0, + I_pt5_UA, + I_14_UA, + I_l4_UA, + I_1_UA, +}; + +enum wcd_mbhc_imp_det_pin { + WCD_MBHC_DET_NONE = 0, + WCD_MBHC_DET_HPHL, + WCD_MBHC_DET_HPHR, + WCD_MBHC_DET_BOTH, +}; + + +/* Each micbias can be assigned to one of three cfilters + * Vbatt_min >= .15V + ldoh_v + * ldoh_v >= .15v + cfiltx_mv + * If ldoh_v = 1.95 160 mv < cfiltx_mv < 1800 mv + * If ldoh_v = 2.35 200 mv < cfiltx_mv < 2200 mv + * If ldoh_v = 2.75 240 mv < cfiltx_mv < 2600 mv + * If ldoh_v = 2.85 250 mv < cfiltx_mv < 2700 mv + */ + +struct wcd_micbias_setting { + u8 ldoh_v; + u32 cfilt1_mv; /* in mv */ + u32 cfilt2_mv; /* in mv */ + u32 cfilt3_mv; /* in mv */ + /* Different WCD9xxx series codecs may not + * have 4 mic biases. If a codec has fewer + * mic biases, some of these properties will + * not be used. + */ + u8 bias1_cfilt_sel; + u8 bias2_cfilt_sel; + u8 bias3_cfilt_sel; + u8 bias4_cfilt_sel; + u8 bias1_cap_mode; + u8 bias2_cap_mode; + u8 bias3_cap_mode; + u8 bias4_cap_mode; + bool bias2_is_headset_only; +}; + +enum sdm660_cdc_pid_current { + MSM89XX_PID_MIC_2P5_UA, + MSM89XX_PID_MIC_5_UA, + MSM89XX_PID_MIC_10_UA, + MSM89XX_PID_MIC_20_UA, +}; + +struct sdm660_cdc_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + +enum { + /* INTR_REG 0 - Digital Periph */ + MSM89XX_IRQ_SPKR_CNP = 0, + MSM89XX_IRQ_SPKR_CLIP, + MSM89XX_IRQ_SPKR_OCP, + MSM89XX_IRQ_MBHC_INSREM_DET1, + MSM89XX_IRQ_MBHC_RELEASE, + MSM89XX_IRQ_MBHC_PRESS, + MSM89XX_IRQ_MBHC_INSREM_DET, + MSM89XX_IRQ_MBHC_HS_DET, + /* INTR_REG 1 - Analog Periph */ + MSM89XX_IRQ_EAR_OCP, + MSM89XX_IRQ_HPHR_OCP, + MSM89XX_IRQ_HPHL_OCP, + MSM89XX_IRQ_EAR_CNP, + MSM89XX_IRQ_HPHR_CNP, + MSM89XX_IRQ_HPHL_CNP, + MSM89XX_NUM_IRQS, +}; + +enum { + ON_DEMAND_MICBIAS = 0, + ON_DEMAND_SPKDRV, + ON_DEMAND_SUPPLIES_MAX, +}; + +/* + * The delay list is per codec HW specification. + * Please add delay in the list in the future instead + * of magic number + */ +enum { + CODEC_DELAY_1_MS = 1000, + CODEC_DELAY_1_1_MS = 1100, +}; + +struct sdm660_cdc_regulator { + const char *name; + int min_uv; + int max_uv; + int optimum_ua; + bool ondemand; + struct regulator *regulator; +}; + +struct on_demand_supply { + struct regulator *supply; + atomic_t ref; + int min_uv; + int max_uv; + int optimum_ua; +}; + +struct wcd_imped_i_ref { + enum wcd_curr_ref curr_ref; + int min_val; + int multiplier; + int gain_adj; + int offset; +}; + +enum sdm660_cdc_micbias_num { + MSM89XX_MICBIAS1 = 0, +}; + +/* Hold instance to digital codec platform device */ +struct msm_dig_ctrl_data { + struct platform_device *dig_pdev; +}; + +struct msm_dig_ctrl_platform_data { + void *handle; + void (*set_compander_mode)(void *handle, int val); + void (*update_clkdiv)(void *handle, int val); + int (*get_cdc_version)(void *handle); + int (*register_notifier)(void *handle, + struct notifier_block *nblock, + bool enable); +}; + +struct sdm660_cdc_priv { + struct device *dev; + u32 num_of_supplies; + struct regulator_bulk_data *supplies; + struct snd_soc_component *component; + struct work_struct msm_anlg_add_child_devices_work; + struct msm_dig_ctrl_platform_data dig_plat_data; + /* digital codec data structure */ + struct msm_dig_ctrl_data *dig_ctrl_data; + struct blocking_notifier_head notifier; + u16 pmic_rev; + u16 codec_version; + u16 analog_major_rev; + u32 boost_voltage; + u32 adc_count; + u32 rx_bias_count; + bool int_mclk0_enabled; + u16 boost_option; + /* mode to select hd2 */ + u32 hph_mode; + /* compander used for each rx chain */ + bool spk_boost_set; + bool ear_pa_boost_set; + bool ext_spk_boost_set; + struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX]; + struct regulator *spkdrv_reg; + struct blocking_notifier_head notifier_mbhc; + /* mbhc module */ + struct wcd_mbhc mbhc; + /* cal info for codec */ + struct fw_info *fw_data; + struct notifier_block audio_ssr_nb; + int (*codec_spk_ext_pa_cb)(struct snd_soc_component *component, + int enable); + unsigned long status_mask; + struct wcd_imped_i_ref imped_i_ref; + enum wcd_mbhc_imp_det_pin imped_det_pin; + /* Entry for version info */ + struct snd_info_entry *entry; + struct snd_info_entry *version_entry; + struct platform_device *pdev_child_devices + [ANLG_CDC_CHILD_DEVICES_MAX]; + int child_count; + struct regmap *regmap; +}; + +struct sdm660_cdc_pdata { + struct wcd_micbias_setting micbias; + struct sdm660_cdc_regulator regulator[MAX_REGULATOR]; +}; + +#if IS_ENABLED(CONFIG_SND_SOC_ANALOG_CDC) +extern int msm_anlg_cdc_mclk_enable(struct snd_soc_component *component, + int mclk_enable, bool dapm); +extern int msm_anlg_cdc_hs_detect(struct snd_soc_component *component, + struct wcd_mbhc_config *mbhc_cfg); +extern void msm_anlg_cdc_hs_detect_exit(struct snd_soc_component *component); +extern void sdm660_cdc_update_int_spk_boost(bool enable); +extern void msm_anlg_cdc_spk_ext_pa_cb( + int (*codec_spk_ext_pa)(struct snd_soc_component *component, + int enable), struct snd_soc_component *component); +int msm_anlg_codec_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_component *component); +#else /* CONFIG_SND_SOC_ANALOG_CDC */ +static inline int msm_anlg_cdc_mclk_enable(struct snd_soc_component *component, + int mclk_enable, bool dapm) +{ + return 0; +} +static inline int msm_anlg_cdc_hs_detect(struct snd_soc_component *component, + struct wcd_mbhc_config *mbhc_cfg) +{ + return 0; +} +static inline void msm_anlg_cdc_hs_detect_exit( + struct snd_soc_component *component) +{ + +} +static inline void sdm660_cdc_update_int_spk_boost(bool enable) +{ + +} +static inline void msm_anlg_cdc_spk_ext_pa_cb( + int (*codec_spk_ext_pa)(struct snd_soc_component *component, + int enable), struct snd_soc_component *codec) +{ + +} +static inline int msm_anlg_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_component *component) +{ + return 0; +} +#endif /* CONFIG_SND_SOC_ANALOG_CDC */ +#endif diff --git a/asoc/codecs/sdm660_cdc/msm-cdc-common.h b/asoc/codecs/sdm660_cdc/msm-cdc-common.h new file mode 100644 index 000000000000..ca66de9821f0 --- /dev/null +++ b/asoc/codecs/sdm660_cdc/msm-cdc-common.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2016-2017, 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include "sdm660-cdc-registers.h" + +extern struct reg_default + msm89xx_cdc_core_defaults[MSM89XX_CDC_CORE_CACHE_SIZE]; +extern struct reg_default + msm89xx_pmic_cdc_defaults[MSM89XX_PMIC_CDC_CACHE_SIZE]; + +bool msm89xx_cdc_core_readable_reg(struct device *dev, unsigned int reg); +bool msm89xx_cdc_core_writeable_reg(struct device *dev, unsigned int reg); +bool msm89xx_cdc_core_volatile_reg(struct device *dev, unsigned int reg); + +enum { + AIF1_PB = 0, + AIF1_CAP, + AIF2_VIFEED, + AIF3_SVA, + NUM_CODEC_DAIS, +}; + +enum codec_versions { + TOMBAK_1_0, + TOMBAK_2_0, + CONGA, + CAJON, + CAJON_2_0, + DIANGU, + DRAX_CDC, + UNSUPPORTED, +}; + +/* Support different hph modes */ +enum { + NORMAL_MODE = 0, + HD2_MODE, +}; + +enum dig_cdc_notify_event { + DIG_CDC_EVENT_INVALID, + DIG_CDC_EVENT_CLK_ON, + DIG_CDC_EVENT_CLK_OFF, + DIG_CDC_EVENT_RX1_MUTE_ON, + DIG_CDC_EVENT_RX1_MUTE_OFF, + DIG_CDC_EVENT_RX2_MUTE_ON, + DIG_CDC_EVENT_RX2_MUTE_OFF, + DIG_CDC_EVENT_RX3_MUTE_ON, + DIG_CDC_EVENT_RX3_MUTE_OFF, + DIG_CDC_EVENT_PRE_RX1_INT_ON, + DIG_CDC_EVENT_PRE_RX2_INT_ON, + DIG_CDC_EVENT_POST_RX1_INT_OFF, + DIG_CDC_EVENT_POST_RX2_INT_OFF, + DIG_CDC_EVENT_SSR_DOWN, + DIG_CDC_EVENT_SSR_UP, + DIG_CDC_EVENT_LAST, +}; diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc-regmap.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc-regmap.c new file mode 100644 index 000000000000..f7f942ff68f5 --- /dev/null +++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc-regmap.c @@ -0,0 +1,444 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015-2017, 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include "msm-cdc-common.h" +#include "sdm660-cdc-registers.h" + +/* + * Default register reset values that are common across different versions + * are defined here. If a register reset value is changed based on version + * then remove it from this structure and add it in version specific + * structures. + */ +struct reg_default + msm89xx_cdc_core_defaults[MSM89XX_CDC_CORE_CACHE_SIZE] = { + {MSM89XX_CDC_CORE_CLK_RX_RESET_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x13}, + {MSM89XX_CDC_CORE_CLK_TX_I2S_CTL, 0x13}, + {MSM89XX_CDC_CORE_CLK_OTHR_RESET_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_OTHR_CTL, 0x04}, + {MSM89XX_CDC_CORE_CLK_RX_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_MCLK_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_PDM_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_SD_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CLK_TX2_I2S_CTL, 0x13}, + {MSM89XX_CDC_CORE_RX1_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX2_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX3_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX1_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX2_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX3_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX1_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX2_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX3_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX1_B4_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX2_B4_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX3_B4_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX1_B5_CTL, 0x68}, + {MSM89XX_CDC_CORE_RX2_B5_CTL, 0x68}, + {MSM89XX_CDC_CORE_RX3_B5_CTL, 0x68}, + {MSM89XX_CDC_CORE_RX1_B6_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX2_B6_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX3_B6_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX1_VOL_CTL_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX2_VOL_CTL_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX3_VOL_CTL_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_TOP_GAIN_UPDATE, 0x00}, + {MSM89XX_CDC_CORE_TOP_CTL, 0x01}, + {MSM89XX_CDC_CORE_COMP0_B1_CTL, 0x30}, + {MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xB5}, + {MSM89XX_CDC_CORE_COMP0_B3_CTL, 0x28}, + {MSM89XX_CDC_CORE_COMP0_B4_CTL, 0x37}, + {MSM89XX_CDC_CORE_COMP0_B5_CTL, 0x7F}, + {MSM89XX_CDC_CORE_COMP0_B6_CTL, 0x00}, + {MSM89XX_CDC_CORE_COMP0_SHUT_DOWN_STATUS, 0x03}, + {MSM89XX_CDC_CORE_COMP0_FS_CFG, 0x03}, + {MSM89XX_CDC_CORE_COMP0_DELAY_BUF_CTL, 0x02}, + {MSM89XX_CDC_CORE_DEBUG_DESER1_CTL, 0x00}, + {MSM89XX_CDC_CORE_DEBUG_DESER2_CTL, 0x00}, + {MSM89XX_CDC_CORE_DEBUG_B1_CTL_CFG, 0x00}, + {MSM89XX_CDC_CORE_DEBUG_B2_CTL_CFG, 0x00}, + {MSM89XX_CDC_CORE_DEBUG_B3_CTL_CFG, 0x00}, + {MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_B4_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_GAIN_B5_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_B5_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_GAIN_B6_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_B6_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_GAIN_B7_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_B7_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_GAIN_B8_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_B8_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_CTL, 0x40}, + {MSM89XX_CDC_CORE_IIR2_CTL, 0x40}, + {MSM89XX_CDC_CORE_IIR1_GAIN_TIMER_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_GAIN_TIMER_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_IIR2_COEF_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_RX1_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_RX1_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_RX1_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_RX2_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_RX2_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_RX2_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_RX3_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_RX3_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_TX_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_TX_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_EQ1_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_EQ1_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_EQ1_B4_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_EQ2_B2_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_EQ2_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_EQ2_B4_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL, 0x00}, + {MSM89XX_CDC_CORE_CONN_TX_B3_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX5_VOL_CTL_TIMER, 0x00}, + {MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN, 0x00}, + {MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG, 0x00}, + {MSM89XX_CDC_CORE_TX5_MUX_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX5_CLK_FS_CTL, 0x03}, + {MSM89XX_CDC_CORE_TX5_DMIC_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX1_VOL_CTL_TIMER, 0x00}, + {MSM89XX_CDC_CORE_TX2_VOL_CTL_TIMER, 0x00}, + {MSM89XX_CDC_CORE_TX3_VOL_CTL_TIMER, 0x00}, + {MSM89XX_CDC_CORE_TX4_VOL_CTL_TIMER, 0x00}, + {MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN, 0x00}, + {MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN, 0x00}, + {MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN, 0x00}, + {MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN, 0x00}, + {MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG, 0x00}, + {MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG, 0x00}, + {MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG, 0x00}, + {MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG, 0x00}, + {MSM89XX_CDC_CORE_TX1_MUX_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX2_MUX_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX3_MUX_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX4_MUX_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX1_CLK_FS_CTL, 0x03}, + {MSM89XX_CDC_CORE_TX2_CLK_FS_CTL, 0x03}, + {MSM89XX_CDC_CORE_TX3_CLK_FS_CTL, 0x03}, + {MSM89XX_CDC_CORE_TX4_CLK_FS_CTL, 0x03}, + {MSM89XX_CDC_CORE_TX1_DMIC_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX2_DMIC_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX3_DMIC_CTL, 0x00}, + {MSM89XX_CDC_CORE_TX4_DMIC_CTL, 0x00}, +}; + +static const u8 msm89xx_cdc_core_reg_readable[MSM89XX_CDC_CORE_CACHE_SIZE] = { + [MSM89XX_CDC_CORE_CLK_RX_RESET_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_RX_I2S_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_TX_I2S_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_OTHR_RESET_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_OTHR_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_RX_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_MCLK_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_PDM_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_SD_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_RX_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_TX2_I2S_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B3_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B3_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B3_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B4_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B4_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B4_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B5_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B5_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B5_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B6_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B6_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B6_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_VOL_CTL_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_VOL_CTL_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_VOL_CTL_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL] = 1, + [MSM89XX_CDC_CORE_TOP_GAIN_UPDATE] = 1, + [MSM89XX_CDC_CORE_TOP_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B1_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B2_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B3_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B4_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B5_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B6_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_SHUT_DOWN_STATUS] = 1, + [MSM89XX_CDC_CORE_COMP0_FS_CFG] = 1, + [MSM89XX_CDC_CORE_COMP0_DELAY_BUF_CTL] = 1, + [MSM89XX_CDC_CORE_DEBUG_DESER1_CTL] = 1, + [MSM89XX_CDC_CORE_DEBUG_DESER2_CTL] = 1, + [MSM89XX_CDC_CORE_DEBUG_B1_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_DEBUG_B2_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_DEBUG_B3_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B2_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B3_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B4_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B5_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B5_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B6_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B6_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B7_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B7_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B8_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B8_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_TIMER_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_TIMER_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_COEF_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX1_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX1_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX1_B3_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX2_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX2_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX2_B3_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX3_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX3_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_TX_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_TX_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ1_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ1_B3_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ1_B4_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ2_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ2_B3_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ2_B4_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_TX_B3_CTL] = 1, + [MSM89XX_CDC_CORE_TX1_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX2_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX3_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX4_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX1_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX2_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX3_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX4_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX1_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX2_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX3_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX4_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX5_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX5_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX5_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX5_DMIC_CTL] = 1, + [MSM89XX_CDC_CORE_TX1_DMIC_CTL] = 1, + [MSM89XX_CDC_CORE_TX2_DMIC_CTL] = 1, + [MSM89XX_CDC_CORE_TX3_DMIC_CTL] = 1, + [MSM89XX_CDC_CORE_TX4_DMIC_CTL] = 1, +}; + +static const u8 msm89xx_cdc_core_reg_writeable[MSM89XX_CDC_CORE_CACHE_SIZE] = { + [MSM89XX_CDC_CORE_CLK_RX_RESET_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_RX_I2S_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_TX_I2S_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_OTHR_RESET_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_OTHR_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_RX_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_MCLK_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_PDM_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_SD_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_RX_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CLK_TX2_I2S_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B3_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B3_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B3_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B4_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B4_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B4_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B5_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B5_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B5_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_B6_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_B6_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_B6_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_VOL_CTL_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_VOL_CTL_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_VOL_CTL_B1_CTL] = 1, + [MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL] = 1, + [MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL] = 1, + [MSM89XX_CDC_CORE_TOP_GAIN_UPDATE] = 1, + [MSM89XX_CDC_CORE_TOP_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B1_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B2_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B3_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B4_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B5_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_B6_CTL] = 1, + [MSM89XX_CDC_CORE_COMP0_FS_CFG] = 1, + [MSM89XX_CDC_CORE_COMP0_DELAY_BUF_CTL] = 1, + [MSM89XX_CDC_CORE_DEBUG_DESER1_CTL] = 1, + [MSM89XX_CDC_CORE_DEBUG_DESER2_CTL] = 1, + [MSM89XX_CDC_CORE_DEBUG_B1_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_DEBUG_B2_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_DEBUG_B3_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B2_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B3_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B4_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B5_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B5_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B6_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B6_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B7_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B7_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_B8_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_B8_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_GAIN_TIMER_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_GAIN_TIMER_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL] = 1, + [MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL] = 1, + [MSM89XX_CDC_CORE_IIR2_COEF_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX1_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX1_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX1_B3_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX2_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX2_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX2_B3_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX3_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_RX3_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_TX_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_TX_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ1_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ1_B3_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ1_B4_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ2_B2_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ2_B3_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_EQ2_B4_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL] = 1, + [MSM89XX_CDC_CORE_CONN_TX_B3_CTL] = 1, + [MSM89XX_CDC_CORE_TX1_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX2_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX3_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX4_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX1_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX2_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX3_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX4_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX1_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX2_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX3_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX4_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX5_VOL_CTL_TIMER] = 1, + [MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN] = 1, + [MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG] = 1, + [MSM89XX_CDC_CORE_TX5_MUX_CTL] = 1, + [MSM89XX_CDC_CORE_TX5_CLK_FS_CTL] = 1, + [MSM89XX_CDC_CORE_TX5_DMIC_CTL] = 1, + [MSM89XX_CDC_CORE_TX1_DMIC_CTL] = 1, + [MSM89XX_CDC_CORE_TX2_DMIC_CTL] = 1, + [MSM89XX_CDC_CORE_TX3_DMIC_CTL] = 1, + [MSM89XX_CDC_CORE_TX4_DMIC_CTL] = 1, +}; + +bool msm89xx_cdc_core_readable_reg(struct device *dev, unsigned int reg) +{ + return msm89xx_cdc_core_reg_readable[reg]; +} + +bool msm89xx_cdc_core_writeable_reg(struct device *dev, unsigned int reg) +{ + return msm89xx_cdc_core_reg_writeable[reg]; +} + +bool msm89xx_cdc_core_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MSM89XX_CDC_CORE_RX1_B1_CTL: + case MSM89XX_CDC_CORE_RX2_B1_CTL: + case MSM89XX_CDC_CORE_RX3_B1_CTL: + case MSM89XX_CDC_CORE_RX1_B6_CTL: + case MSM89XX_CDC_CORE_RX2_B6_CTL: + case MSM89XX_CDC_CORE_RX3_B6_CTL: + case MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG: + case MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG: + case MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG: + case MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG: + case MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG: + case MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL: + case MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL: + case MSM89XX_CDC_CORE_CLK_MCLK_CTL: + case MSM89XX_CDC_CORE_CLK_PDM_CTL: + return true; + default: + return false; + } +} diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c new file mode 100644 index 000000000000..42f67b142ee6 --- /dev/null +++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -0,0 +1,2238 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015-2017, 2020, The Linux Foundation. All rights reserved. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sdm660-cdc-registers.h" +#include "msm-digital-cdc.h" +#include "msm-cdc-common.h" +#include + +#define DRV_NAME "msm_digital_codec" +#define MCLK_RATE_9P6MHZ 9600000 +#define MCLK_RATE_12P288MHZ 12288000 +#define TX_MUX_CTL_CUT_OFF_FREQ_MASK 0x30 +#define CF_MIN_3DB_4HZ 0x0 +#define CF_MIN_3DB_75HZ 0x1 +#define CF_MIN_3DB_150HZ 0x2 + +#define DEC_SVA 5 +#define MSM_DIG_CDC_VERSION_ENTRY_SIZE 32 + +static unsigned long rx_digital_gain_reg[] = { + MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL, + MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL, + MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL, +}; + +static unsigned long tx_digital_gain_reg[] = { + MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN, + MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN, + MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN, + MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN, + MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN, +}; + +#define SDM660_TX_UNMUTE_DELAY_MS 40 +static int tx_unmute_delay = SDM660_TX_UNMUTE_DELAY_MS; +module_param(tx_unmute_delay, int, 0664); +MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path"); + +static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); + +struct snd_soc_component *registered_digcodec; +struct hpf_work tx_hpf_work[NUM_DECIMATORS]; + +/* Codec supports 2 IIR filters */ +enum { + IIR1 = 0, + IIR2, + IIR_MAX, +}; + +static int msm_digcdc_clock_control(bool flag) +{ + int ret = -EINVAL; + struct msm_asoc_mach_data *pdata = NULL; + struct msm_dig_priv *msm_dig_cdc = + snd_soc_component_get_drvdata(registered_digcodec); + + pdata = snd_soc_card_get_drvdata(registered_digcodec->card); + + if (flag) { + mutex_lock(&pdata->cdc_int_mclk0_mutex); + if (atomic_read(&pdata->int_mclk0_enabled) == false) { + if (pdata->native_clk_set) + pdata->digital_cdc_core_clk.clk_freq_in_hz = + NATIVE_MCLK_RATE; + else + pdata->digital_cdc_core_clk.clk_freq_in_hz = + DEFAULT_MCLK_RATE; + pdata->digital_cdc_core_clk.enable = 1; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + if (ret < 0) { + pr_err("%s:failed to enable the MCLK\n", + __func__); + /* + * Avoid access to lpass register + * as clock enable failed during SSR. + */ + if (ret == -ENODEV) + msm_dig_cdc->regmap->cache_only = true; + return ret; + } + pr_debug("enabled digital codec core clk\n"); + atomic_set(&pdata->int_mclk0_enabled, true); + schedule_delayed_work(&pdata->disable_int_mclk0_work, + 50); + } + } else { + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + dev_dbg(registered_digcodec->dev, + "disable MCLK, workq to disable set already\n"); + } + return 0; +} + +static void enable_digital_callback(void *flag) +{ + msm_digcdc_clock_control(true); +} + +static void disable_digital_callback(void *flag) +{ + msm_digcdc_clock_control(false); + pr_debug("disable mclk happens in workq\n"); +} + +static int msm_dig_cdc_put_dec_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int dec_mux, decimator; + char *dec_name = NULL; + char *widget_name = NULL; + char *temp; + u16 tx_mux_ctl_reg; + u8 adc_dmic_sel = 0x0; + int ret = 0; + char *dec_num; + + if (ucontrol->value.enumerated.item[0] > e->items) { + dev_err(component->dev, "%s: Invalid enum value: %d\n", + __func__, ucontrol->value.enumerated.item[0]); + return -EINVAL; + } + dec_mux = ucontrol->value.enumerated.item[0]; + + widget_name = kstrndup(w->name, 15, GFP_KERNEL); + if (!widget_name) { + dev_err(component->dev, "%s: failed to copy string\n", + __func__); + return -ENOMEM; + } + temp = widget_name; + + dec_name = strsep(&widget_name, " "); + widget_name = temp; + if (!dec_name) { + dev_err(component->dev, "%s: Invalid decimator = %s\n", + __func__, w->name); + ret = -EINVAL; + goto out; + } + + dec_num = strpbrk(dec_name, "12345"); + if (dec_num == NULL) { + dev_err(component->dev, "%s: Invalid DEC selected\n", __func__); + ret = -EINVAL; + goto out; + } + + ret = kstrtouint(dec_num, 10, &decimator); + if (ret < 0) { + dev_err(component->dev, "%s: Invalid decimator = %s\n", + __func__, dec_name); + ret = -EINVAL; + goto out; + } + + dev_dbg(w->dapm->dev, "%s(): widget = %s decimator = %u dec_mux = %u\n" + , __func__, w->name, decimator, dec_mux); + + switch (decimator) { + case 1: + case 2: + case 3: + case 4: + case 5: + if ((dec_mux == 4) || (dec_mux == 5) || + (dec_mux == 6) || (dec_mux == 7)) + adc_dmic_sel = 0x1; + else + adc_dmic_sel = 0x0; + break; + default: + dev_err(component->dev, "%s: Invalid Decimator = %u\n", + __func__, decimator); + ret = -EINVAL; + goto out; + } + + tx_mux_ctl_reg = + MSM89XX_CDC_CORE_TX1_MUX_CTL + 32 * (decimator - 1); + + if (decimator == DEC_SVA) + tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX5_MUX_CTL; + + snd_soc_component_update_bits(component, tx_mux_ctl_reg, + 0x1, adc_dmic_sel); + + ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol); + +out: + kfree(widget_name); + return ret; +} + + +static int msm_dig_cdc_codec_config_compander( + struct snd_soc_component *component, + int interp_n, int event) +{ + struct msm_dig_priv *dig_cdc = snd_soc_component_get_drvdata(component); + int comp_ch_bits_set = 0x03; + int comp_ch_value; + + dev_dbg(component->dev, "%s: event %d shift %d, enabled %d\n", + __func__, event, interp_n, + dig_cdc->comp_enabled[interp_n]); + + /* compander is invalid */ + if (dig_cdc->comp_enabled[interp_n] != COMPANDER_1 && + dig_cdc->comp_enabled[interp_n]) { + dev_dbg(component->dev, "%s: Invalid compander %d\n", __func__, + dig_cdc->comp_enabled[interp_n]); + return 0; + } + + if (SND_SOC_DAPM_EVENT_ON(event)) { + /* compander is not enabled */ + if (!dig_cdc->comp_enabled[interp_n]) { + dig_cdc->set_compander_mode(dig_cdc->handle, 0x00); + return 0; + }; + comp_ch_value = snd_soc_component_read32(component, + MSM89XX_CDC_CORE_COMP0_B1_CTL); + if (interp_n == 0) { + if (comp_ch_value & 0x02) { + dev_dbg(component->dev, + "%s comp ch 1 already enabled\n", + __func__); + return 0; + } + } + if (interp_n == 1) { + if (comp_ch_value & 0x01) { + dev_dbg(component->dev, + "%s comp ch 0 already enabled\n", + __func__); + return 0; + } + } + dig_cdc->set_compander_mode(dig_cdc->handle, 0x08); + /* Enable Compander Clock */ + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_COMP0_B2_CTL, 0x0F, 0x09); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x01, 0x01); + if (dig_cdc->comp_enabled[MSM89XX_RX1]) { + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_COMP0_B1_CTL, + 0x02, 0x02); + } + if (dig_cdc->comp_enabled[MSM89XX_RX2]) { + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_COMP0_B1_CTL, + 0x01, 0x01); + } + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x01); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xF0, 0x50); + /* add sleep for compander to settle */ + usleep_range(1000, 1100); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x28); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xF0, 0xB0); + + /* Enable Compander GPIO */ + if (dig_cdc->codec_hph_comp_gpio) + dig_cdc->codec_hph_comp_gpio(1, component); + } else if (SND_SOC_DAPM_EVENT_OFF(event)) { + /* Disable Compander GPIO */ + if (dig_cdc->codec_hph_comp_gpio) + dig_cdc->codec_hph_comp_gpio(0, component); + + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_COMP0_B1_CTL, + 1 << interp_n, 0); + comp_ch_bits_set = snd_soc_component_read32(component, + MSM89XX_CDC_CORE_COMP0_B1_CTL); + if ((comp_ch_bits_set & 0x03) == 0x00) { + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_COMP0_B2_CTL, 0x0F, 0x05); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x01, 0x00); + } + } + return 0; +} + +/** + * msm_dig_cdc_hph_comp_cb - registers callback to codec by machine driver. + * + * @codec_hph_comp_gpio: function pointer to set comp gpio at machine driver + * @codec: codec pointer + * + */ +void msm_dig_cdc_hph_comp_cb( + int (*codec_hph_comp_gpio)(bool enable, + struct snd_soc_component *component), + struct snd_soc_component *component) +{ + struct msm_dig_priv *dig_cdc = + snd_soc_component_get_drvdata(component); + + pr_debug("%s: Enter\n", __func__); + dig_cdc->codec_hph_comp_gpio = codec_hph_comp_gpio; +} +EXPORT_SYMBOL(msm_dig_cdc_hph_comp_cb); + +static int msm_dig_cdc_codec_enable_interpolator(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct msm_dig_priv *msm_dig_cdc = + snd_soc_component_get_drvdata(component); + + dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name); + + if (w->shift >= MSM89XX_RX_MAX || w->shift < 0) { + dev_err(component->dev, "%s: wrong RX index: %d\n", + __func__, w->shift); + return -EINVAL; + } + switch (event) { + case SND_SOC_DAPM_POST_PMU: + msm_dig_cdc_codec_config_compander(component, w->shift, event); + /* apply the digital gain after the interpolator is enabled*/ + if ((w->shift) < ARRAY_SIZE(rx_digital_gain_reg)) + snd_soc_component_write(component, + rx_digital_gain_reg[w->shift], + snd_soc_component_read32(component, + rx_digital_gain_reg[w->shift]) + ); + break; + case SND_SOC_DAPM_POST_PMD: + msm_dig_cdc_codec_config_compander(component, w->shift, event); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_CLK_RX_RESET_CTL, + 1 << w->shift, 1 << w->shift); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_CLK_RX_RESET_CTL, + 1 << w->shift, 0x0); + /* + * disable the mute enabled during the PMD of this device + */ + if ((w->shift == 0) && + (msm_dig_cdc->mute_mask & HPHL_PA_DISABLE)) { + pr_debug("disabling HPHL mute\n"); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX1_B6_CTL, 0x01, 0x00); + msm_dig_cdc->mute_mask &= ~(HPHL_PA_DISABLE); + } else if ((w->shift == 1) && + (msm_dig_cdc->mute_mask & HPHR_PA_DISABLE)) { + pr_debug("disabling HPHR mute\n"); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX2_B6_CTL, 0x01, 0x00); + msm_dig_cdc->mute_mask &= ~(HPHR_PA_DISABLE); + } else if ((w->shift == 2) && + (msm_dig_cdc->mute_mask & SPKR_PA_DISABLE)) { + pr_debug("disabling SPKR mute\n"); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX3_B6_CTL, 0x01, 0x00); + msm_dig_cdc->mute_mask &= ~(SPKR_PA_DISABLE); + } + } + return 0; +} + +static int msm_dig_cdc_get_iir_enable_audio_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + ucontrol->value.integer.value[0] = + (snd_soc_component_read32(component, + (MSM89XX_CDC_CORE_IIR1_CTL + 64 * iir_idx)) & + (1 << band_idx)) != 0; + + dev_dbg(component->dev, "%s: IIR #%d band #%d enable %d\n", __func__, + iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_dig_cdc_put_iir_enable_audio_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int value = ucontrol->value.integer.value[0]; + + /* Mask first 5 bits, 6-8 are reserved */ + snd_soc_component_update_bits(component, + (MSM89XX_CDC_CORE_IIR1_CTL + 64 * iir_idx), + (1 << band_idx), (value << band_idx)); + + dev_dbg(component->dev, "%s: IIR #%d band #%d enable %d\n", __func__, + iir_idx, band_idx, + ((snd_soc_component_read32(component, + (MSM89XX_CDC_CORE_IIR1_CTL + 64 * iir_idx)) & + (1 << band_idx)) != 0)); + + return 0; +} + +static uint32_t get_iir_band_coeff(struct snd_soc_component *component, + int iir_idx, int band_idx, + int coeff_idx) +{ + uint32_t value = 0; + + /* Address does not automatically update if reading */ + snd_soc_component_write(component, + (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t)) & 0x7F); + + value |= snd_soc_component_read32(component, + (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx)); + + snd_soc_component_write(component, + (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 1) & 0x7F); + + value |= (snd_soc_component_read32(component, + (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 8); + + snd_soc_component_write(component, + (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 2) & 0x7F); + + value |= (snd_soc_component_read32(component, + (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 16); + + snd_soc_component_write(component, + (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx), + ((band_idx * BAND_MAX + coeff_idx) + * sizeof(uint32_t) + 3) & 0x7F); + + /* Mask bits top 2 bits since they are reserved */ + value |= ((snd_soc_component_read32(component, + (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + + 64 * iir_idx)) & 0x3f) << 24); + return value; +} + +static void set_iir_band_coeff(struct snd_soc_component *component, + int iir_idx, int band_idx, + uint32_t value) +{ + snd_soc_component_write(component, + (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx), + (value & 0xFF)); + + snd_soc_component_write(component, + (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx), + (value >> 8) & 0xFF); + + snd_soc_component_write(component, + (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx), + (value >> 16) & 0xFF); + + /* Mask top 2 bits, 7-8 are reserved */ + snd_soc_component_write(component, + (MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL + 64 * iir_idx), + (value >> 24) & 0x3F); + +} + +static int msm_dig_cdc_get_iir_band_audio_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + ucontrol->value.integer.value[0] = + get_iir_band_coeff(component, iir_idx, band_idx, 0); + ucontrol->value.integer.value[1] = + get_iir_band_coeff(component, iir_idx, band_idx, 1); + ucontrol->value.integer.value[2] = + get_iir_band_coeff(component, iir_idx, band_idx, 2); + ucontrol->value.integer.value[3] = + get_iir_band_coeff(component, iir_idx, band_idx, 3); + ucontrol->value.integer.value[4] = + get_iir_band_coeff(component, iir_idx, band_idx, 4); + + dev_dbg(component->dev, "%s: IIR #%d band #%d b0 = 0x%x\n" + "%s: IIR #%d band #%d b1 = 0x%x\n" + "%s: IIR #%d band #%d b2 = 0x%x\n" + "%s: IIR #%d band #%d a1 = 0x%x\n" + "%s: IIR #%d band #%d a2 = 0x%x\n", + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[0], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[1], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[2], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[3], + __func__, iir_idx, band_idx, + (uint32_t)ucontrol->value.integer.value[4]); + return 0; +} + +static int msm_dig_cdc_put_iir_band_audio_mixer( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + int iir_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int band_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + /* Mask top bit it is reserved */ + /* Updates addr automatically for each B2 write */ + snd_soc_component_write(component, + (MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL + 64 * iir_idx), + (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F); + + + set_iir_band_coeff(component, iir_idx, band_idx, + ucontrol->value.integer.value[0]); + set_iir_band_coeff(component, iir_idx, band_idx, + ucontrol->value.integer.value[1]); + set_iir_band_coeff(component, iir_idx, band_idx, + ucontrol->value.integer.value[2]); + set_iir_band_coeff(component, iir_idx, band_idx, + ucontrol->value.integer.value[3]); + set_iir_band_coeff(component, iir_idx, band_idx, + ucontrol->value.integer.value[4]); + + dev_dbg(component->dev, "%s: IIR #%d band #%d b0 = 0x%x\n" + "%s: IIR #%d band #%d b1 = 0x%x\n" + "%s: IIR #%d band #%d b2 = 0x%x\n" + "%s: IIR #%d band #%d a1 = 0x%x\n" + "%s: IIR #%d band #%d a2 = 0x%x\n", + __func__, iir_idx, band_idx, + get_iir_band_coeff(component, iir_idx, band_idx, 0), + __func__, iir_idx, band_idx, + get_iir_band_coeff(component, iir_idx, band_idx, 1), + __func__, iir_idx, band_idx, + get_iir_band_coeff(component, iir_idx, band_idx, 2), + __func__, iir_idx, band_idx, + get_iir_band_coeff(component, iir_idx, band_idx, 3), + __func__, iir_idx, band_idx, + get_iir_band_coeff(component, iir_idx, band_idx, 4)); + return 0; +} + +static void tx_hpf_corner_freq_callback(struct work_struct *work) +{ + struct delayed_work *hpf_delayed_work; + struct hpf_work *hpf_work; + struct snd_soc_component *component; + struct msm_dig_priv *msm_dig_cdc; + u16 tx_mux_ctl_reg; + u8 hpf_cut_of_freq; + + hpf_delayed_work = to_delayed_work(work); + hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); + component = hpf_work->dig_cdc->component; + msm_dig_cdc = hpf_work->dig_cdc; + hpf_cut_of_freq = hpf_work->tx_hpf_cut_of_freq; + + tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX1_MUX_CTL + + (hpf_work->decimator - 1) * 32; + + if (hpf_work->decimator == DEC_SVA) + tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX5_MUX_CTL; + + dev_dbg(component->dev, "%s(): decimator %u hpf_cut_of_freq 0x%x\n", + __func__, hpf_work->decimator, (unsigned int)hpf_cut_of_freq); + msm_dig_cdc->update_clkdiv(msm_dig_cdc->handle, 0x51); + + snd_soc_component_update_bits(component, tx_mux_ctl_reg, + 0x30, hpf_cut_of_freq << 4); +} + +static int msm_dig_cdc_codec_set_iir_gain(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + int value = 0, reg; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (w->shift == 0) + reg = MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL; + else if (w->shift == 1) + reg = MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL; + else + goto ret; + value = snd_soc_component_read32(component, reg); + snd_soc_component_write(component, reg, value); + break; + default: + pr_err("%s: event = %d not expected\n", __func__, event); + } +ret: + return 0; +} + +static int msm_dig_cdc_compander_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct msm_dig_priv *dig_cdc = snd_soc_component_get_drvdata(component); + int comp_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int rx_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + + dev_dbg(component->dev, "%s: msm_dig_cdc->comp[%d]_enabled[%d] = %d\n", + __func__, comp_idx, rx_idx, + dig_cdc->comp_enabled[rx_idx]); + + ucontrol->value.integer.value[0] = dig_cdc->comp_enabled[rx_idx]; + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int msm_dig_cdc_compander_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct msm_dig_priv *dig_cdc = snd_soc_component_get_drvdata(component); + int comp_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->reg; + int rx_idx = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int value = ucontrol->value.integer.value[0]; + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + if (dig_cdc->version >= DIANGU) { + if (!value) + dig_cdc->comp_enabled[rx_idx] = 0; + else + dig_cdc->comp_enabled[rx_idx] = comp_idx; + } + + dev_dbg(component->dev, "%s: msm_dig_cdc->comp[%d]_enabled[%d] = %d\n", + __func__, comp_idx, rx_idx, + dig_cdc->comp_enabled[rx_idx]); + + return 0; +} + +static const struct snd_kcontrol_new compander_kcontrols[] = { + SOC_SINGLE_EXT("COMP0 RX1", COMPANDER_1, MSM89XX_RX1, 1, 0, + msm_dig_cdc_compander_get, msm_dig_cdc_compander_set), + + SOC_SINGLE_EXT("COMP0 RX2", COMPANDER_1, MSM89XX_RX2, 1, 0, + msm_dig_cdc_compander_get, msm_dig_cdc_compander_set), + +}; + +static int msm_dig_cdc_set_interpolator_rate(struct snd_soc_dai *dai, + u8 rx_fs_rate_reg_val, + u32 sample_rate) +{ + snd_soc_component_update_bits(dai->component, + MSM89XX_CDC_CORE_RX1_B5_CTL, 0xF0, rx_fs_rate_reg_val); + snd_soc_component_update_bits(dai->component, + MSM89XX_CDC_CORE_RX2_B5_CTL, 0xF0, rx_fs_rate_reg_val); + return 0; +} + +static int msm_dig_cdc_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + u8 tx_fs_rate, rx_fs_rate, rx_clk_fs_rate; + int ret; + + dev_dbg(dai->component->dev, + "%s: dai_name = %s DAI-ID %x rate %d num_ch %d format %d\n", + __func__, dai->name, dai->id, params_rate(params), + params_channels(params), params_format(params)); + + switch (params_rate(params)) { + case 8000: + tx_fs_rate = 0x00; + rx_fs_rate = 0x00; + rx_clk_fs_rate = 0x00; + break; + case 16000: + tx_fs_rate = 0x20; + rx_fs_rate = 0x20; + rx_clk_fs_rate = 0x01; + break; + case 32000: + tx_fs_rate = 0x40; + rx_fs_rate = 0x40; + rx_clk_fs_rate = 0x02; + break; + case 44100: + case 48000: + tx_fs_rate = 0x60; + rx_fs_rate = 0x60; + rx_clk_fs_rate = 0x03; + break; + case 96000: + tx_fs_rate = 0x80; + rx_fs_rate = 0x80; + rx_clk_fs_rate = 0x04; + break; + case 192000: + tx_fs_rate = 0xA0; + rx_fs_rate = 0xA0; + rx_clk_fs_rate = 0x05; + break; + default: + dev_err(dai->component->dev, + "%s: Invalid sampling rate %d\n", __func__, + params_rate(params)); + return -EINVAL; + } + + snd_soc_component_update_bits(dai->component, + MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x0F, rx_clk_fs_rate); + + switch (substream->stream) { + case SNDRV_PCM_STREAM_CAPTURE: + break; + case SNDRV_PCM_STREAM_PLAYBACK: + ret = msm_dig_cdc_set_interpolator_rate(dai, rx_fs_rate, + params_rate(params)); + if (ret < 0) { + dev_err(dai->component->dev, + "%s: set decimator rate failed %d\n", __func__, + ret); + return ret; + } + break; + default: + dev_err(dai->component->dev, + "%s: Invalid stream type %d\n", __func__, + substream->stream); + return -EINVAL; + } + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + snd_soc_component_update_bits(dai->component, + MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x20, 0x20); + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + snd_soc_component_update_bits(dai->component, + MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x20, 0x00); + break; + default: + dev_err(dai->component->dev, "%s: wrong format selected\n", + __func__); + return -EINVAL; + } + return 0; +} + +static int msm_dig_cdc_codec_enable_dmic(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct msm_dig_priv *dig_cdc = + snd_soc_component_get_drvdata(component); + u8 dmic_clk_en; + u16 dmic_clk_reg; + s32 *dmic_clk_cnt; + unsigned int dmic; + int ret; + char *dmic_num = strpbrk(w->name, "1234"); + + if (dmic_num == NULL) { + dev_err(component->dev, "%s: Invalid DMIC\n", __func__); + return -EINVAL; + } + + ret = kstrtouint(dmic_num, 10, &dmic); + if (ret < 0) { + dev_err(component->dev, + "%s: Invalid DMIC line on the codec\n", __func__); + return -EINVAL; + } + + switch (dmic) { + case 1: + case 2: + dmic_clk_en = 0x01; + dmic_clk_cnt = &(dig_cdc->dmic_1_2_clk_cnt); + dmic_clk_reg = MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL; + dev_dbg(component->dev, + "%s() event %d DMIC%d dmic_1_2_clk_cnt %d\n", + __func__, event, dmic, *dmic_clk_cnt); + break; + case 3: + case 4: + dmic_clk_en = 0x01; + dmic_clk_cnt = &(dig_cdc->dmic_3_4_clk_cnt); + dmic_clk_reg = MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL; + dev_dbg(component->dev, + "%s() event %d DMIC%d dmic_3_4_clk_cnt %d\n", + __func__, event, dmic, *dmic_clk_cnt); + break; + default: + dev_err(component->dev, "%s: Invalid DMIC Selection\n", + __func__); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + (*dmic_clk_cnt)++; + if (*dmic_clk_cnt == 1) { + snd_soc_component_update_bits(component, dmic_clk_reg, + 0x0E, 0x04); + snd_soc_component_update_bits(component, dmic_clk_reg, + dmic_clk_en, dmic_clk_en); + } + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_TX1_DMIC_CTL + (dmic - 1) * 0x20, + 0x07, 0x02); + break; + case SND_SOC_DAPM_POST_PMD: + (*dmic_clk_cnt)--; + if (*dmic_clk_cnt == 0) + snd_soc_component_update_bits(component, dmic_clk_reg, + dmic_clk_en, 0); + break; + } + return 0; +} + +static int msm_dig_cdc_codec_enable_dec(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct msm_asoc_mach_data *pdata = NULL; + unsigned int decimator; + struct msm_dig_priv *msm_dig_cdc = + snd_soc_component_get_drvdata(component); + char *dec_name = NULL; + char *widget_name = NULL; + char *temp; + int ret = 0, i; + u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg; + u8 dec_hpf_cut_of_freq; + int offset; + char *dec_num; + + pdata = snd_soc_card_get_drvdata(component->card); + dev_dbg(component->dev, "%s %d\n", __func__, event); + + widget_name = kstrndup(w->name, 15, GFP_KERNEL); + if (!widget_name) + return -ENOMEM; + temp = widget_name; + + dec_name = strsep(&widget_name, " "); + widget_name = temp; + if (!dec_name) { + dev_err(component->dev, + "%s: Invalid decimator = %s\n", __func__, w->name); + ret = -EINVAL; + goto out; + } + + dec_num = strpbrk(dec_name, "12345"); + if (dec_num == NULL) { + dev_err(component->dev, "%s: Invalid Decimator\n", __func__); + ret = -EINVAL; + goto out; + } + + ret = kstrtouint(dec_num, 10, &decimator); + if (ret < 0) { + dev_err(component->dev, + "%s: Invalid decimator = %s\n", __func__, dec_name); + ret = -EINVAL; + goto out; + } + + dev_dbg(component->dev, + "%s(): widget = %s dec_name = %s decimator = %u\n", __func__, + w->name, dec_name, decimator); + + if (w->reg == MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL) { + dec_reset_reg = MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL; + offset = 0; + } else { + dev_err(component->dev, "%s: Error, incorrect dec\n", + __func__); + ret = -EINVAL; + goto out; + } + + tx_vol_ctl_reg = MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG + + 32 * (decimator - 1); + tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX1_MUX_CTL + + 32 * (decimator - 1); + if (decimator == DEC_SVA) { + tx_vol_ctl_reg = MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG; + tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX5_MUX_CTL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Enableable TX digital mute */ + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x01, 0x01); + for (i = 0; i < NUM_DECIMATORS; i++) { + if (decimator == i + 1) + msm_dig_cdc->dec_active[i] = true; + } + + dec_hpf_cut_of_freq = snd_soc_component_read32(component, + tx_mux_ctl_reg); + + dec_hpf_cut_of_freq = (dec_hpf_cut_of_freq & 0x30) >> 4; + + tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq = + dec_hpf_cut_of_freq; + + if (dec_hpf_cut_of_freq != CF_MIN_3DB_150HZ) { + + /* set cut of freq to CF_MIN_3DB_150HZ (0x1); */ + snd_soc_component_update_bits(component, + tx_mux_ctl_reg, 0x30, + CF_MIN_3DB_150HZ << 4); + } + msm_dig_cdc->update_clkdiv(msm_dig_cdc->handle, 0x42); + break; + case SND_SOC_DAPM_POST_PMU: + /* enable HPF */ + snd_soc_component_update_bits(component, tx_mux_ctl_reg, + 0x08, 0x00); + + schedule_delayed_work( + &msm_dig_cdc->tx_mute_dwork[decimator - 1].dwork, + msecs_to_jiffies(tx_unmute_delay)); + if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq != + CF_MIN_3DB_150HZ) { + + schedule_delayed_work(&tx_hpf_work[decimator - 1].dwork, + msecs_to_jiffies(300)); + } + /* apply the digital gain after the decimator is enabled*/ + if ((w->shift) < ARRAY_SIZE(tx_digital_gain_reg)) + snd_soc_component_write(component, + tx_digital_gain_reg[w->shift + offset], + snd_soc_component_read32(component, + tx_digital_gain_reg[w->shift + offset]) + ); + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x01, 0x01); + msleep(20); + snd_soc_component_update_bits(component, tx_mux_ctl_reg, + 0x08, 0x08); + cancel_delayed_work_sync(&tx_hpf_work[decimator - 1].dwork); + cancel_delayed_work_sync( + &msm_dig_cdc->tx_mute_dwork[decimator - 1].dwork); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, dec_reset_reg, + 1 << w->shift, 1 << w->shift); + snd_soc_component_update_bits(component, dec_reset_reg, + 1 << w->shift, 0x0); + snd_soc_component_update_bits(component, tx_mux_ctl_reg, + 0x08, 0x08); + snd_soc_component_update_bits(component, tx_mux_ctl_reg, 0x30, + (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq) << 4); + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x01, 0x00); + for (i = 0; i < NUM_DECIMATORS; i++) { + if (decimator == i + 1) + msm_dig_cdc->dec_active[i] = false; + } + break; + } +out: + kfree(widget_name); + return ret; +} + +static int msm_dig_cdc_event_notify(struct notifier_block *block, + unsigned long val, + void *data) +{ + enum dig_cdc_notify_event event = (enum dig_cdc_notify_event)val; + struct snd_soc_component *component = registered_digcodec; + struct msm_dig_priv *msm_dig_cdc = + snd_soc_component_get_drvdata(component); + struct msm_asoc_mach_data *pdata = NULL; + int ret = -EINVAL; + + pdata = snd_soc_card_get_drvdata(component->card); + + switch (event) { + case DIG_CDC_EVENT_CLK_ON: + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_CLK_PDM_CTL, 0x03, 0x03); + if (pdata->mclk_freq == MCLK_RATE_12P288MHZ || + pdata->native_clk_set) + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_TOP_CTL, 0x01, 0x00); + else if (pdata->mclk_freq == MCLK_RATE_9P6MHZ) + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_TOP_CTL, 0x01, 0x01); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_CLK_MCLK_CTL, 0x01, 0x01); + break; + case DIG_CDC_EVENT_CLK_OFF: + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_CLK_PDM_CTL, 0x03, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_CLK_MCLK_CTL, 0x01, 0x00); + break; + case DIG_CDC_EVENT_RX1_MUTE_ON: + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX1_B6_CTL, 0x01, 0x01); + msm_dig_cdc->mute_mask |= HPHL_PA_DISABLE; + break; + case DIG_CDC_EVENT_RX1_MUTE_OFF: + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX1_B6_CTL, 0x01, 0x00); + msm_dig_cdc->mute_mask &= (~HPHL_PA_DISABLE); + break; + case DIG_CDC_EVENT_RX2_MUTE_ON: + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX2_B6_CTL, 0x01, 0x01); + msm_dig_cdc->mute_mask |= HPHR_PA_DISABLE; + break; + case DIG_CDC_EVENT_RX2_MUTE_OFF: + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX2_B6_CTL, 0x01, 0x00); + msm_dig_cdc->mute_mask &= (~HPHR_PA_DISABLE); + break; + case DIG_CDC_EVENT_RX3_MUTE_ON: + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX3_B6_CTL, 0x01, 0x01); + msm_dig_cdc->mute_mask |= SPKR_PA_DISABLE; + break; + case DIG_CDC_EVENT_RX3_MUTE_OFF: + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX3_B6_CTL, 0x01, 0x00); + msm_dig_cdc->mute_mask &= (~SPKR_PA_DISABLE); + break; + case DIG_CDC_EVENT_PRE_RX1_INT_ON: + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX1_B3_CTL, 0x3C, 0x28); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX1_B4_CTL, 0x18, 0x10); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX1_B3_CTL, 0x80, 0x80); + break; + case DIG_CDC_EVENT_PRE_RX2_INT_ON: + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX2_B3_CTL, 0x3C, 0x28); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX2_B4_CTL, 0x18, 0x10); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX2_B3_CTL, 0x80, 0x80); + break; + case DIG_CDC_EVENT_POST_RX1_INT_OFF: + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX1_B3_CTL, 0x3C, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX1_B4_CTL, 0x18, 0xFF); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX1_B3_CTL, 0x80, 0x00); + break; + case DIG_CDC_EVENT_POST_RX2_INT_OFF: + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX2_B3_CTL, 0x3C, 0x00); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX2_B4_CTL, 0x18, 0xFF); + snd_soc_component_update_bits(component, + MSM89XX_CDC_CORE_RX2_B3_CTL, 0x80, 0x00); + break; + case DIG_CDC_EVENT_SSR_DOWN: + regcache_cache_only(msm_dig_cdc->regmap, true); + break; + case DIG_CDC_EVENT_SSR_UP: + regcache_cache_only(msm_dig_cdc->regmap, false); + regcache_mark_dirty(msm_dig_cdc->regmap); + + mutex_lock(&pdata->cdc_int_mclk0_mutex); + pdata->digital_cdc_core_clk.enable = 1; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + if (ret < 0) { + pr_err("%s:failed to enable the MCLK\n", + __func__); + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + break; + } + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + + regcache_sync(msm_dig_cdc->regmap); + + mutex_lock(&pdata->cdc_int_mclk0_mutex); + pdata->digital_cdc_core_clk.enable = 0; + afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + break; + case DIG_CDC_EVENT_INVALID: + default: + break; + } + return 0; +} + +static ssize_t msm_dig_codec_version_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, size_t count, + loff_t pos) +{ + struct msm_dig_priv *msm_dig; + char buffer[MSM_DIG_CDC_VERSION_ENTRY_SIZE]; + int len = 0; + + msm_dig = (struct msm_dig_priv *) entry->private_data; + if (!msm_dig) { + pr_err("%s: msm_dig priv is null\n", __func__); + return -EINVAL; + } + + switch (msm_dig->version) { + case DRAX_CDC: + len = snprintf(buffer, sizeof(buffer), "SDM660-CDC_1_0\n"); + break; + default: + len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n"); + } + + return simple_read_from_buffer(buf, count, &pos, buffer, len); +} + +static struct snd_info_entry_ops msm_dig_codec_info_ops = { + .read = msm_dig_codec_version_read, +}; + +/* + * msm_dig_codec_info_create_codec_entry - creates msm_dig module + * @codec_root: The parent directory + * @codec: Codec instance + * + * Creates msm_dig module and version entry under the given + * parent directory. + * + * Return: 0 on success or negative error code on failure. + */ +int msm_dig_codec_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_component *component) +{ + struct snd_info_entry *version_entry; + struct msm_dig_priv *msm_dig; + struct snd_soc_card *card; + + if (!codec_root || !component) + return -EINVAL; + + msm_dig = snd_soc_component_get_drvdata(component); + card = component->card; + msm_dig->entry = snd_info_create_subdir(codec_root->module, + "msm_digital_codec", + codec_root); + if (!msm_dig->entry) { + dev_dbg(component->dev, "%s: failed to create msm_digital entry\n", + __func__); + return -ENOMEM; + } + + version_entry = snd_info_create_card_entry(card->snd_card, + "version", + msm_dig->entry); + if (!version_entry) { + dev_dbg(component->dev, "%s: failed to create msm_digital version entry\n", + __func__); + return -ENOMEM; + } + + version_entry->private_data = msm_dig; + version_entry->size = MSM_DIG_CDC_VERSION_ENTRY_SIZE; + version_entry->content = SNDRV_INFO_CONTENT_DATA; + version_entry->c.ops = &msm_dig_codec_info_ops; + + if (snd_info_register(version_entry) < 0) { + snd_info_free_entry(version_entry); + return -ENOMEM; + } + msm_dig->version_entry = version_entry; + if (msm_dig->get_cdc_version) + msm_dig->version = msm_dig->get_cdc_version(msm_dig->handle); + else + msm_dig->version = DRAX_CDC; + + return 0; +} +EXPORT_SYMBOL(msm_dig_codec_info_create_codec_entry); + +static void sdm660_tx_mute_update_callback(struct work_struct *work) +{ + struct tx_mute_work *tx_mute_dwork; + struct snd_soc_component *component = NULL; + struct msm_dig_priv *dig_cdc; + struct delayed_work *delayed_work; + u16 tx_vol_ctl_reg = 0; + u8 decimator = 0, i; + + delayed_work = to_delayed_work(work); + tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); + dig_cdc = tx_mute_dwork->dig_cdc; + component = dig_cdc->component; + + for (i = 0; i < NUM_DECIMATORS; i++) { + if (dig_cdc->dec_active[i]) + decimator = i + 1; + if (decimator && decimator <= NUM_DECIMATORS) { + /* unmute decimators corresponding to Tx DAI's*/ + tx_vol_ctl_reg = + MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG + + 32 * (decimator - 1); + if (decimator == DEC_SVA) + tx_vol_ctl_reg = + MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG; + + snd_soc_component_update_bits(component, tx_vol_ctl_reg, + 0x01, 0x00); + } + decimator = 0; + } +} + +static int msm_dig_cdc_soc_probe(struct snd_soc_component *component) +{ + struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(component->dev); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); + int i, ret; + + msm_dig_cdc->component = component; + + snd_soc_add_component_controls(component, compander_kcontrols, + ARRAY_SIZE(compander_kcontrols)); + + for (i = 0; i < NUM_DECIMATORS; i++) { + tx_hpf_work[i].dig_cdc = msm_dig_cdc; + tx_hpf_work[i].decimator = i + 1; + INIT_DELAYED_WORK(&tx_hpf_work[i].dwork, + tx_hpf_corner_freq_callback); + msm_dig_cdc->tx_mute_dwork[i].dig_cdc = msm_dig_cdc; + msm_dig_cdc->tx_mute_dwork[i].decimator = i + 1; + INIT_DELAYED_WORK(&msm_dig_cdc->tx_mute_dwork[i].dwork, + sdm660_tx_mute_update_callback); + } + + for (i = 0; i < MSM89XX_RX_MAX; i++) + msm_dig_cdc->comp_enabled[i] = COMPANDER_NONE; + + /* Register event notifier */ + msm_dig_cdc->nblock.notifier_call = msm_dig_cdc_event_notify; + if (msm_dig_cdc->register_notifier) { + ret = msm_dig_cdc->register_notifier(msm_dig_cdc->handle, + &msm_dig_cdc->nblock, + true); + if (ret) { + pr_err("%s: Failed to register notifier %d\n", + __func__, ret); + return ret; + } + } + registered_digcodec = component; + + snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback"); + snd_soc_dapm_ignore_suspend(dapm, "AIF1 Capture"); + snd_soc_dapm_ignore_suspend(dapm, "ADC1_IN"); + snd_soc_dapm_ignore_suspend(dapm, "ADC2_IN"); + snd_soc_dapm_ignore_suspend(dapm, "ADC3_IN"); + snd_soc_dapm_ignore_suspend(dapm, "PDM_OUT_RX1"); + snd_soc_dapm_ignore_suspend(dapm, "PDM_OUT_RX2"); + snd_soc_dapm_ignore_suspend(dapm, "PDM_OUT_RX3"); + + snd_soc_dapm_sync(dapm); + + return 0; +} + +static void msm_dig_cdc_soc_remove(struct snd_soc_component *component) +{ + struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(component->dev); + + if (msm_dig_cdc->register_notifier) + msm_dig_cdc->register_notifier(msm_dig_cdc->handle, + &msm_dig_cdc->nblock, + false); + iounmap(msm_dig_cdc->dig_base); +} + +static const struct snd_soc_dapm_route audio_dig_map[] = { + {"RX_I2S_CLK", NULL, "CDC_CONN"}, + {"I2S RX1", NULL, "RX_I2S_CLK"}, + {"I2S RX2", NULL, "RX_I2S_CLK"}, + {"I2S RX3", NULL, "RX_I2S_CLK"}, + + {"I2S TX1", NULL, "TX_I2S_CLK"}, + {"I2S TX2", NULL, "TX_I2S_CLK"}, + {"I2S TX3", NULL, "TX_I2S_CLK"}, + {"I2S TX4", NULL, "TX_I2S_CLK"}, + {"I2S TX5", NULL, "TX_I2S_CLK"}, + {"I2S TX6", NULL, "TX_I2S_CLK"}, + + {"I2S TX1", NULL, "DEC1 MUX"}, + {"I2S TX2", NULL, "DEC2 MUX"}, + {"I2S TX3", NULL, "I2S TX2 INP1"}, + {"I2S TX4", NULL, "I2S TX2 INP2"}, + {"I2S TX5", NULL, "DEC3 MUX"}, + {"I2S TX6", NULL, "I2S TX3 INP2"}, + + {"I2S TX2 INP1", "RX_MIX1", "RX1 MIX2"}, + {"I2S TX2 INP1", "DEC3", "DEC3 MUX"}, + {"I2S TX2 INP2", "RX_MIX2", "RX2 MIX2"}, + {"I2S TX2 INP2", "RX_MIX3", "RX3 MIX1"}, + {"I2S TX2 INP2", "DEC4", "DEC4 MUX"}, + {"I2S TX3 INP2", "DEC4", "DEC4 MUX"}, + {"I2S TX3 INP2", "DEC5", "DEC5 MUX"}, + + {"PDM_OUT_RX1", NULL, "RX1 CHAIN"}, + {"PDM_OUT_RX2", NULL, "RX2 CHAIN"}, + {"PDM_OUT_RX3", NULL, "RX3 CHAIN"}, + + {"RX1 CHAIN", NULL, "RX1 MIX2"}, + {"RX2 CHAIN", NULL, "RX2 MIX2"}, + {"RX3 CHAIN", NULL, "RX3 MIX1"}, + + {"RX1 MIX1", NULL, "RX1 MIX1 INP1"}, + {"RX1 MIX1", NULL, "RX1 MIX1 INP2"}, + {"RX1 MIX1", NULL, "RX1 MIX1 INP3"}, + {"RX2 MIX1", NULL, "RX2 MIX1 INP1"}, + {"RX2 MIX1", NULL, "RX2 MIX1 INP2"}, + {"RX3 MIX1", NULL, "RX3 MIX1 INP1"}, + {"RX3 MIX1", NULL, "RX3 MIX1 INP2"}, + {"RX1 MIX2", NULL, "RX1 MIX1"}, + {"RX1 MIX2", NULL, "RX1 MIX2 INP1"}, + {"RX2 MIX2", NULL, "RX2 MIX1"}, + {"RX2 MIX2", NULL, "RX2 MIX2 INP1"}, + + {"RX1 MIX1 INP1", "RX1", "I2S RX1"}, + {"RX1 MIX1 INP1", "RX2", "I2S RX2"}, + {"RX1 MIX1 INP1", "RX3", "I2S RX3"}, + {"RX1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX1 MIX1 INP1", "IIR2", "IIR2"}, + {"RX1 MIX1 INP2", "RX1", "I2S RX1"}, + {"RX1 MIX1 INP2", "RX2", "I2S RX2"}, + {"RX1 MIX1 INP2", "RX3", "I2S RX3"}, + {"RX1 MIX1 INP2", "IIR1", "IIR1"}, + {"RX1 MIX1 INP2", "IIR2", "IIR2"}, + {"RX1 MIX1 INP3", "RX1", "I2S RX1"}, + {"RX1 MIX1 INP3", "RX2", "I2S RX2"}, + {"RX1 MIX1 INP3", "RX3", "I2S RX3"}, + + {"RX2 MIX1 INP1", "RX1", "I2S RX1"}, + {"RX2 MIX1 INP1", "RX2", "I2S RX2"}, + {"RX2 MIX1 INP1", "RX3", "I2S RX3"}, + {"RX2 MIX1 INP1", "IIR1", "IIR1"}, + {"RX2 MIX1 INP1", "IIR2", "IIR2"}, + {"RX2 MIX1 INP2", "RX1", "I2S RX1"}, + {"RX2 MIX1 INP2", "RX2", "I2S RX2"}, + {"RX2 MIX1 INP2", "RX3", "I2S RX3"}, + {"RX2 MIX1 INP2", "IIR1", "IIR1"}, + {"RX2 MIX1 INP2", "IIR2", "IIR2"}, + {"RX2 MIX1 INP3", "RX1", "I2S RX1"}, + {"RX2 MIX1 INP3", "RX2", "I2S RX2"}, + {"RX2 MIX1 INP3", "RX3", "I2S RX3"}, + + {"RX3 MIX1 INP1", "RX1", "I2S RX1"}, + {"RX3 MIX1 INP1", "RX2", "I2S RX2"}, + {"RX3 MIX1 INP1", "RX3", "I2S RX3"}, + {"RX3 MIX1 INP1", "IIR1", "IIR1"}, + {"RX3 MIX1 INP1", "IIR2", "IIR2"}, + {"RX3 MIX1 INP2", "RX1", "I2S RX1"}, + {"RX3 MIX1 INP2", "RX2", "I2S RX2"}, + {"RX3 MIX1 INP2", "RX3", "I2S RX3"}, + {"RX3 MIX1 INP2", "IIR1", "IIR1"}, + {"RX3 MIX1 INP2", "IIR2", "IIR2"}, + {"RX3 MIX1 INP3", "RX1", "I2S RX1"}, + {"RX3 MIX1 INP3", "RX2", "I2S RX2"}, + {"RX3 MIX1 INP3", "RX3", "I2S RX3"}, + + {"RX1 MIX2 INP1", "IIR1", "IIR1"}, + {"RX2 MIX2 INP1", "IIR1", "IIR1"}, + {"RX1 MIX2 INP1", "IIR2", "IIR2"}, + {"RX2 MIX2 INP1", "IIR2", "IIR2"}, + + /* Decimator Inputs */ + {"DEC1 MUX", "DMIC1", "DMIC1"}, + {"DEC1 MUX", "DMIC2", "DMIC2"}, + {"DEC1 MUX", "DMIC3", "DMIC3"}, + {"DEC1 MUX", "DMIC4", "DMIC4"}, + {"DEC1 MUX", "ADC1", "ADC1_IN"}, + {"DEC1 MUX", "ADC2", "ADC2_IN"}, + {"DEC1 MUX", "ADC3", "ADC3_IN"}, + {"DEC1 MUX", NULL, "CDC_CONN"}, + + {"DEC2 MUX", "DMIC1", "DMIC1"}, + {"DEC2 MUX", "DMIC2", "DMIC2"}, + {"DEC2 MUX", "DMIC3", "DMIC3"}, + {"DEC2 MUX", "DMIC4", "DMIC4"}, + {"DEC2 MUX", "ADC1", "ADC1_IN"}, + {"DEC2 MUX", "ADC2", "ADC2_IN"}, + {"DEC2 MUX", "ADC3", "ADC3_IN"}, + {"DEC2 MUX", NULL, "CDC_CONN"}, + + {"DEC3 MUX", "DMIC1", "DMIC1"}, + {"DEC3 MUX", "DMIC2", "DMIC2"}, + {"DEC3 MUX", "DMIC3", "DMIC3"}, + {"DEC3 MUX", "DMIC4", "DMIC4"}, + {"DEC3 MUX", "ADC1", "ADC1_IN"}, + {"DEC3 MUX", "ADC2", "ADC2_IN"}, + {"DEC3 MUX", "ADC3", "ADC3_IN"}, + {"DEC3 MUX", NULL, "CDC_CONN"}, + + {"DEC4 MUX", "DMIC1", "DMIC1"}, + {"DEC4 MUX", "DMIC2", "DMIC2"}, + {"DEC4 MUX", "DMIC3", "DMIC3"}, + {"DEC4 MUX", "DMIC4", "DMIC4"}, + {"DEC4 MUX", "ADC1", "ADC1_IN"}, + {"DEC4 MUX", "ADC2", "ADC2_IN"}, + {"DEC4 MUX", "ADC3", "ADC3_IN"}, + {"DEC4 MUX", NULL, "CDC_CONN"}, + + {"DEC5 MUX", "DMIC1", "DMIC1"}, + {"DEC5 MUX", "DMIC2", "DMIC2"}, + {"DEC5 MUX", "DMIC3", "DMIC3"}, + {"DEC5 MUX", "DMIC4", "DMIC4"}, + {"DEC5 MUX", "ADC1", "ADC1_IN"}, + {"DEC5 MUX", "ADC2", "ADC2_IN"}, + {"DEC5 MUX", "ADC3", "ADC3_IN"}, + {"DEC5 MUX", NULL, "CDC_CONN"}, + + {"IIR1", NULL, "IIR1 INP1 MUX"}, + {"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"}, + {"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"}, + {"IIR1 INP1 MUX", "DEC3", "DEC3 MUX"}, + {"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"}, + {"IIR2", NULL, "IIR2 INP1 MUX"}, + {"IIR2 INP1 MUX", "DEC1", "DEC1 MUX"}, + {"IIR2 INP1 MUX", "DEC2", "DEC2 MUX"}, + {"IIR1 INP1 MUX", "DEC3", "DEC3 MUX"}, + {"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"}, +}; + + +static const char * const i2s_tx2_inp1_text[] = { + "ZERO", "RX_MIX1", "DEC3" +}; + +static const char * const i2s_tx2_inp2_text[] = { + "ZERO", "RX_MIX2", "RX_MIX3", "DEC4" +}; + +static const char * const i2s_tx3_inp2_text[] = { + "DEC4", "DEC5" +}; + +static const char * const rx_mix1_text[] = { + "ZERO", "IIR1", "IIR2", "RX1", "RX2", "RX3" +}; + +static const char * const rx_mix2_text[] = { + "ZERO", "IIR1", "IIR2" +}; + +static const char * const dec_mux_text[] = { + "ZERO", "ADC1", "ADC2", "ADC3", "DMIC1", "DMIC2", "DMIC3", "DMIC4" +}; + +static const char * const iir_inp1_text[] = { + "ZERO", "DEC1", "DEC2", "RX1", "RX2", "RX3", "DEC3", "DEC4" +}; + +/* I2S TX MUXes */ +static const struct soc_enum i2s_tx2_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL, + 2, 3, i2s_tx2_inp1_text); + +static const struct soc_enum i2s_tx2_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL, + 0, 4, i2s_tx2_inp2_text); + +static const struct soc_enum i2s_tx3_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL, + 4, 2, i2s_tx3_inp2_text); + +/* RX1 MIX1 */ +static const struct soc_enum rx_mix1_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B1_CTL, + 0, 6, rx_mix1_text); + +static const struct soc_enum rx_mix1_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B1_CTL, + 3, 6, rx_mix1_text); + +static const struct soc_enum rx_mix1_inp3_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B2_CTL, + 0, 6, rx_mix1_text); + +/* RX1 MIX2 */ +static const struct soc_enum rx_mix2_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B3_CTL, + 0, 3, rx_mix2_text); + +/* RX2 MIX1 */ +static const struct soc_enum rx2_mix1_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX2_B1_CTL, + 0, 6, rx_mix1_text); + +static const struct soc_enum rx2_mix1_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX2_B1_CTL, + 3, 6, rx_mix1_text); + +static const struct soc_enum rx2_mix1_inp3_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX2_B1_CTL, + 0, 6, rx_mix1_text); + +/* RX2 MIX2 */ +static const struct soc_enum rx2_mix2_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX2_B3_CTL, + 0, 3, rx_mix2_text); + +/* RX3 MIX1 */ +static const struct soc_enum rx3_mix1_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX3_B1_CTL, + 0, 6, rx_mix1_text); + +static const struct soc_enum rx3_mix1_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX3_B1_CTL, + 3, 6, rx_mix1_text); + +static const struct soc_enum rx3_mix1_inp3_chain_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX3_B1_CTL, + 0, 6, rx_mix1_text); + +/* DEC */ +static const struct soc_enum dec1_mux_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B1_CTL, + 0, 8, dec_mux_text); + +static const struct soc_enum dec2_mux_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B1_CTL, + 3, 8, dec_mux_text); + +static const struct soc_enum dec3_mux_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B2_CTL, + 0, 8, dec_mux_text); + +static const struct soc_enum dec4_mux_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B2_CTL, + 3, 8, dec_mux_text); + +static const struct soc_enum decsva_mux_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_B3_CTL, + 0, 8, dec_mux_text); + +static const struct soc_enum iir1_inp1_mux_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL, + 0, 8, iir_inp1_text); + +static const struct soc_enum iir2_inp1_mux_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL, + 0, 8, iir_inp1_text); + +/*cut of frequency for high pass filter*/ +static const char * const cf_text[] = { + "MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz" +}; + +static const struct soc_enum cf_rxmix1_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_RX1_B4_CTL, 0, 3, cf_text); + +static const struct soc_enum cf_rxmix2_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_RX2_B4_CTL, 0, 3, cf_text); + +static const struct soc_enum cf_rxmix3_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_RX3_B4_CTL, 0, 3, cf_text); + +static const struct snd_kcontrol_new rx3_mix1_inp1_mux = + SOC_DAPM_ENUM("RX3 MIX1 INP1 Mux", rx3_mix1_inp1_chain_enum); + +#define MSM89XX_DEC_ENUM(xname, xenum) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_soc_info_enum_double, \ + .get = snd_soc_dapm_get_enum_double, \ + .put = msm_dig_cdc_put_dec_enum, \ + .private_value = (unsigned long)&xenum } + +static const struct snd_kcontrol_new dec1_mux = + MSM89XX_DEC_ENUM("DEC1 MUX Mux", dec1_mux_enum); + +static const struct snd_kcontrol_new dec2_mux = + MSM89XX_DEC_ENUM("DEC2 MUX Mux", dec2_mux_enum); + +static const struct snd_kcontrol_new dec3_mux = + MSM89XX_DEC_ENUM("DEC3 MUX Mux", dec3_mux_enum); + +static const struct snd_kcontrol_new dec4_mux = + MSM89XX_DEC_ENUM("DEC4 MUX Mux", dec4_mux_enum); + +static const struct snd_kcontrol_new decsva_mux = + MSM89XX_DEC_ENUM("DEC5 MUX Mux", decsva_mux_enum); + +static const struct snd_kcontrol_new i2s_tx2_inp1_mux = + SOC_DAPM_ENUM("I2S TX2 INP1 Mux", i2s_tx2_inp1_chain_enum); + +static const struct snd_kcontrol_new i2s_tx2_inp2_mux = + SOC_DAPM_ENUM("I2S TX2 INP2 Mux", i2s_tx2_inp2_chain_enum); + +static const struct snd_kcontrol_new i2s_tx3_inp2_mux = + SOC_DAPM_ENUM("I2S TX3 INP2 Mux", i2s_tx3_inp2_chain_enum); + +static const struct snd_kcontrol_new iir1_inp1_mux = + SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum); + +static const struct snd_kcontrol_new iir2_inp1_mux = + SOC_DAPM_ENUM("IIR2 INP1 Mux", iir2_inp1_mux_enum); + +static const struct snd_kcontrol_new rx_mix1_inp1_mux = + SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum); + +static const struct snd_kcontrol_new rx_mix1_inp2_mux = + SOC_DAPM_ENUM("RX1 MIX1 INP2 Mux", rx_mix1_inp2_chain_enum); + +static const struct snd_kcontrol_new rx_mix1_inp3_mux = + SOC_DAPM_ENUM("RX1 MIX1 INP3 Mux", rx_mix1_inp3_chain_enum); + +static const struct snd_kcontrol_new rx2_mix1_inp1_mux = + SOC_DAPM_ENUM("RX2 MIX1 INP1 Mux", rx2_mix1_inp1_chain_enum); + +static const struct snd_kcontrol_new rx2_mix1_inp2_mux = + SOC_DAPM_ENUM("RX2 MIX1 INP2 Mux", rx2_mix1_inp2_chain_enum); + +static const struct snd_kcontrol_new rx2_mix1_inp3_mux = + SOC_DAPM_ENUM("RX2 MIX1 INP3 Mux", rx2_mix1_inp3_chain_enum); + +static const struct snd_kcontrol_new rx3_mix1_inp2_mux = + SOC_DAPM_ENUM("RX3 MIX1 INP2 Mux", rx3_mix1_inp2_chain_enum); + +static const struct snd_kcontrol_new rx3_mix1_inp3_mux = + SOC_DAPM_ENUM("RX3 MIX1 INP3 Mux", rx3_mix1_inp3_chain_enum); + +static const struct snd_kcontrol_new rx1_mix2_inp1_mux = + SOC_DAPM_ENUM("RX1 MIX2 INP1 Mux", rx_mix2_inp1_chain_enum); + +static const struct snd_kcontrol_new rx2_mix2_inp1_mux = + SOC_DAPM_ENUM("RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum); + +static const struct snd_soc_dapm_widget msm_dig_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN("I2S RX1", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("I2S RX2", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("I2S RX3", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_OUT("I2S TX1", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("I2S TX2", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("I2S TX3", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("I2S TX4", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("I2S TX5", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("I2S TX6", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_MIXER_E("RX1 MIX2", MSM89XX_CDC_CORE_CLK_RX_B1_CTL, + MSM89XX_RX1, 0, NULL, 0, + msm_dig_cdc_codec_enable_interpolator, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX2 MIX2", MSM89XX_CDC_CORE_CLK_RX_B1_CTL, + MSM89XX_RX2, 0, NULL, 0, + msm_dig_cdc_codec_enable_interpolator, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX3 MIX1", MSM89XX_CDC_CORE_CLK_RX_B1_CTL, + MSM89XX_RX3, 0, NULL, 0, + msm_dig_cdc_codec_enable_interpolator, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MIXER("RX1 CHAIN", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX2 CHAIN", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("RX3 CHAIN", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx_mix1_inp1_mux), + SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx_mix1_inp2_mux), + SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0, + &rx_mix1_inp3_mux), + + SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx2_mix1_inp1_mux), + SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx2_mix1_inp2_mux), + SND_SOC_DAPM_MUX("RX2 MIX1 INP3", SND_SOC_NOPM, 0, 0, + &rx2_mix1_inp3_mux), + + SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx3_mix1_inp1_mux), + SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx3_mix1_inp2_mux), + SND_SOC_DAPM_MUX("RX3 MIX1 INP3", SND_SOC_NOPM, 0, 0, + &rx3_mix1_inp3_mux), + + SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0, + &rx1_mix2_inp1_mux), + SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0, + &rx2_mix2_inp1_mux), + + SND_SOC_DAPM_SUPPLY_S("CDC_CONN", -2, MSM89XX_CDC_CORE_CLK_OTHR_CTL, + 2, 0, NULL, 0), + + SND_SOC_DAPM_MUX_E("DEC1 MUX", + MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 0, 0, + &dec1_mux, msm_dig_cdc_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("DEC2 MUX", + MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 1, 0, + &dec2_mux, msm_dig_cdc_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("DEC3 MUX", + MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 2, 0, + &dec3_mux, msm_dig_cdc_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("DEC4 MUX", + MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 3, 0, + &dec4_mux, msm_dig_cdc_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX_E("DEC5 MUX", + MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL, 4, 0, + &decsva_mux, msm_dig_cdc_codec_enable_dec, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + /* Sidetone */ + SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux), + SND_SOC_DAPM_PGA_E("IIR1", MSM89XX_CDC_CORE_CLK_SD_CTL, 0, 0, NULL, 0, + msm_dig_cdc_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_MUX("IIR2 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir2_inp1_mux), + SND_SOC_DAPM_PGA_E("IIR2", MSM89XX_CDC_CORE_CLK_SD_CTL, 1, 0, NULL, 0, + msm_dig_cdc_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", + MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 4, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("TX_I2S_CLK", + MSM89XX_CDC_CORE_CLK_TX_I2S_CTL, 4, 0, NULL, 0), + + + SND_SOC_DAPM_MUX("I2S TX2 INP1", SND_SOC_NOPM, 0, 0, + &i2s_tx2_inp1_mux), + SND_SOC_DAPM_MUX("I2S TX2 INP2", SND_SOC_NOPM, 0, 0, + &i2s_tx2_inp2_mux), + SND_SOC_DAPM_MUX("I2S TX3 INP2", SND_SOC_NOPM, 0, 0, + &i2s_tx3_inp2_mux), + + /* Digital Mic Inputs */ + SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0, + msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0, + msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0, + msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0, + msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_INPUT("ADC1_IN"), + SND_SOC_DAPM_INPUT("ADC2_IN"), + SND_SOC_DAPM_INPUT("ADC3_IN"), + SND_SOC_DAPM_OUTPUT("PDM_OUT_RX1"), + SND_SOC_DAPM_OUTPUT("PDM_OUT_RX2"), + SND_SOC_DAPM_OUTPUT("PDM_OUT_RX3"), +}; + +static const struct soc_enum cf_dec1_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX1_MUX_CTL, 4, 3, cf_text); + +static const struct soc_enum cf_dec2_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX2_MUX_CTL, 4, 3, cf_text); + +static const struct soc_enum cf_dec3_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX3_MUX_CTL, 4, 3, cf_text); + +static const struct soc_enum cf_dec4_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX4_MUX_CTL, 4, 3, cf_text); + +static const struct soc_enum cf_decsva_enum = + SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_TX5_MUX_CTL, 4, 3, cf_text); + +static const struct snd_kcontrol_new msm_dig_snd_controls[] = { + SOC_SINGLE_SX_TLV("DEC1 Volume", + MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC2 Volume", + MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC3 Volume", + MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC4 Volume", + MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("DEC5 Volume", + MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN, + 0, -84, 40, digital_gain), + + SOC_SINGLE_SX_TLV("IIR1 INP1 Volume", + MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP2 Volume", + MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP3 Volume", + MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("IIR1 INP4 Volume", + MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("IIR2 INP1 Volume", + MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL, + 0, -84, 40, digital_gain), + + SOC_SINGLE_SX_TLV("RX1 Digital Volume", + MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX2 Digital Volume", + MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX3 Digital Volume", + MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL, + 0, -84, 40, digital_gain), + + SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + + SOC_SINGLE_EXT("IIR2 Enable Band1", IIR2, BAND1, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR2 Enable Band2", IIR2, BAND2, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR2 Enable Band3", IIR2, BAND3, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR2 Enable Band4", IIR2, BAND4, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + SOC_SINGLE_EXT("IIR2 Enable Band5", IIR2, BAND5, 1, 0, + msm_dig_cdc_get_iir_enable_audio_mixer, + msm_dig_cdc_put_iir_enable_audio_mixer), + + SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + + SOC_SINGLE_MULTI_EXT("IIR2 Band1", IIR2, BAND1, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR2 Band2", IIR2, BAND2, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR2 Band3", IIR2, BAND3, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR2 Band4", IIR2, BAND4, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5, + msm_dig_cdc_get_iir_band_audio_mixer, + msm_dig_cdc_put_iir_band_audio_mixer), + + SOC_SINGLE("RX1 HPF Switch", + MSM89XX_CDC_CORE_RX1_B5_CTL, 2, 1, 0), + SOC_SINGLE("RX2 HPF Switch", + MSM89XX_CDC_CORE_RX2_B5_CTL, 2, 1, 0), + SOC_SINGLE("RX3 HPF Switch", + MSM89XX_CDC_CORE_RX3_B5_CTL, 2, 1, 0), + + SOC_ENUM("RX1 HPF cut off", cf_rxmix1_enum), + SOC_ENUM("RX2 HPF cut off", cf_rxmix2_enum), + SOC_ENUM("RX3 HPF cut off", cf_rxmix3_enum), + + SOC_ENUM("TX1 HPF cut off", cf_dec1_enum), + SOC_ENUM("TX2 HPF cut off", cf_dec2_enum), + SOC_ENUM("TX3 HPF cut off", cf_dec3_enum), + SOC_ENUM("TX4 HPF cut off", cf_dec4_enum), + SOC_ENUM("TX5 HPF cut off", cf_decsva_enum), + SOC_SINGLE("TX1 HPF Switch", + MSM89XX_CDC_CORE_TX1_MUX_CTL, 3, 1, 0), + SOC_SINGLE("TX2 HPF Switch", + MSM89XX_CDC_CORE_TX2_MUX_CTL, 3, 1, 0), + SOC_SINGLE("TX3 HPF Switch", + MSM89XX_CDC_CORE_TX3_MUX_CTL, 3, 1, 0), + SOC_SINGLE("TX4 HPF Switch", + MSM89XX_CDC_CORE_TX4_MUX_CTL, 3, 1, 0), + SOC_SINGLE("TX5 HPF Switch", + MSM89XX_CDC_CORE_TX5_MUX_CTL, 3, 1, 0), +}; + +static struct snd_soc_dai_ops msm_dig_dai_ops = { + .hw_params = msm_dig_cdc_hw_params, +}; + + +static struct snd_soc_dai_driver msm_codec_dais[] = { + { + .name = "msm_dig_cdc_dai_rx1", + .id = AIF1_PB, + .playback = { /* Support maximum range */ + .stream_name = "AIF1 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .rate_max = 192000, + .rate_min = 8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + }, + .ops = &msm_dig_dai_ops, + }, + { + .name = "msm_dig_cdc_dai_tx1", + .id = AIF1_CAP, + .capture = { /* Support maximum range */ + .stream_name = "AIF1 Capture", + .channels_min = 1, + .channels_max = 4, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = &msm_dig_dai_ops, + }, + { + .name = "msm_dig_cdc_dai_tx2", + .id = AIF3_SVA, + .capture = { /* Support maximum range */ + .stream_name = "AIF2 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = &msm_dig_dai_ops, + }, + { + .name = "msm_dig_cdc_dai_vifeed", + .id = AIF2_VIFEED, + .capture = { /* Support maximum range */ + .stream_name = "AIF2 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = &msm_dig_dai_ops, + }, +}; + +static int msm_dig_cdc_suspend(struct snd_soc_component *component) +{ + struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(component->dev); + + msm_dig_cdc->dapm_bias_off = 1; + return 0; +} + +static int msm_dig_cdc_resume(struct snd_soc_component *component) +{ + struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(component->dev); + + msm_dig_cdc->dapm_bias_off = 0; + return 0; +} + +static const struct snd_soc_component_driver soc_msm_dig_codec = { + .name = DRV_NAME, + .probe = msm_dig_cdc_soc_probe, + .remove = msm_dig_cdc_soc_remove, + .suspend = msm_dig_cdc_suspend, + .resume = msm_dig_cdc_resume, + .controls = msm_dig_snd_controls, + .num_controls = ARRAY_SIZE(msm_dig_snd_controls), + .dapm_widgets = msm_dig_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(msm_dig_dapm_widgets), + .dapm_routes = audio_dig_map, + .num_dapm_routes = ARRAY_SIZE(audio_dig_map), +}; + +const struct regmap_config msm_digital_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 8, + .lock = enable_digital_callback, + .unlock = disable_digital_callback, + .cache_type = REGCACHE_FLAT, + .reg_defaults = msm89xx_cdc_core_defaults, + .num_reg_defaults = MSM89XX_CDC_CORE_MAX_REGISTER, + .writeable_reg = msm89xx_cdc_core_writeable_reg, + .readable_reg = msm89xx_cdc_core_readable_reg, + .volatile_reg = msm89xx_cdc_core_volatile_reg, + .reg_format_endian = REGMAP_ENDIAN_NATIVE, + .val_format_endian = REGMAP_ENDIAN_NATIVE, + .max_register = MSM89XX_CDC_CORE_MAX_REGISTER, +}; + +static int msm_dig_cdc_probe(struct platform_device *pdev) +{ + int ret; + u32 dig_cdc_addr; + struct msm_dig_priv *msm_dig_cdc; + struct dig_ctrl_platform_data *pdata; + + msm_dig_cdc = devm_kzalloc(&pdev->dev, sizeof(struct msm_dig_priv), + GFP_KERNEL); + if (!msm_dig_cdc) + return -ENOMEM; + pdata = dev_get_platdata(&pdev->dev); + if (!pdata) { + dev_err(&pdev->dev, "%s: pdata from parent is NULL\n", + __func__); + ret = -EINVAL; + goto rtn; + } + + ret = of_property_read_u32(pdev->dev.of_node, "reg", + &dig_cdc_addr); + if (ret) { + dev_err(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "reg"); + return ret; + } + + msm_dig_cdc->dig_base = ioremap(dig_cdc_addr, + MSM89XX_CDC_CORE_MAX_REGISTER); + if (msm_dig_cdc->dig_base == NULL) { + dev_err(&pdev->dev, "%s ioremap failed\n", __func__); + return -ENOMEM; + } + msm_dig_cdc->regmap = + devm_regmap_init_mmio_clk(&pdev->dev, NULL, + msm_dig_cdc->dig_base, &msm_digital_regmap_config); + + msm_dig_cdc->update_clkdiv = pdata->update_clkdiv; + msm_dig_cdc->set_compander_mode = pdata->set_compander_mode; + msm_dig_cdc->get_cdc_version = pdata->get_cdc_version; + msm_dig_cdc->handle = pdata->handle; + msm_dig_cdc->register_notifier = pdata->register_notifier; + + dev_set_drvdata(&pdev->dev, msm_dig_cdc); + snd_soc_register_component(&pdev->dev, &soc_msm_dig_codec, + msm_codec_dais, ARRAY_SIZE(msm_codec_dais)); + dev_dbg(&pdev->dev, "%s: registered DIG CODEC 0x%x\n", + __func__, dig_cdc_addr); +rtn: + return ret; +} + +static int msm_dig_cdc_remove(struct platform_device *pdev) +{ + snd_soc_unregister_component(&pdev->dev); + return 0; +} + +#ifdef CONFIG_PM +static int msm_dig_suspend(struct device *dev) +{ + struct msm_asoc_mach_data *pdata; + struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(dev); + + if (!registered_digcodec || !msm_dig_cdc) { + pr_debug("%s:digcodec not initialized, return\n", __func__); + return 0; + } + pdata = snd_soc_card_get_drvdata(registered_digcodec->card); + if (!pdata) { + pr_debug("%s:card not initialized, return\n", __func__); + return 0; + } + if (msm_dig_cdc->dapm_bias_off) { + pr_debug("%s: mclk cnt = %d, mclk_enabled = %d\n", + __func__, atomic_read(&pdata->int_mclk0_rsc_ref), + atomic_read(&pdata->int_mclk0_enabled)); + + if (atomic_read(&pdata->int_mclk0_enabled) == true) { + cancel_delayed_work_sync( + &pdata->disable_int_mclk0_work); + mutex_lock(&pdata->cdc_int_mclk0_mutex); + pdata->digital_cdc_core_clk.enable = 0; + afe_set_lpass_clock_v2(AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + atomic_set(&pdata->int_mclk0_enabled, false); + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + } + } + + return 0; +} + +static int msm_dig_resume(struct device *dev) +{ + return 0; +} + +static const struct dev_pm_ops msm_dig_pm_ops = { + .suspend_late = msm_dig_suspend, + .resume_early = msm_dig_resume, +}; +#endif + +static const struct of_device_id msm_dig_cdc_of_match[] = { + {.compatible = "qcom,msm-digital-codec"}, + {}, +}; + +static struct platform_driver msm_digcodec_driver = { + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + .of_match_table = msm_dig_cdc_of_match, +#ifdef CONFIG_PM + .pm = &msm_dig_pm_ops, +#endif + }, + .probe = msm_dig_cdc_probe, + .remove = msm_dig_cdc_remove, +}; +module_platform_driver(msm_digcodec_driver); + +MODULE_DESCRIPTION("MSM Audio Digital codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.h b/asoc/codecs/sdm660_cdc/msm-digital-cdc.h new file mode 100644 index 000000000000..a6178cd20419 --- /dev/null +++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.h @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2016-2017, 2020, The Linux Foundation. All rights reserved. + */ +#ifndef MSM_DIGITAL_CDC_H +#define MSM_DIGITAL_CDC_H + +#define HPHL_PA_DISABLE (0x01 << 1) +#define HPHR_PA_DISABLE (0x01 << 2) +#define SPKR_PA_DISABLE (0x01 << 3) + +#define NUM_DECIMATORS 5 +/* Codec supports 1 compander */ +enum { + COMPANDER_NONE = 0, + COMPANDER_1, /* HPHL/R */ + COMPANDER_MAX, +}; + +/* Number of output I2S port */ +enum { + MSM89XX_RX1 = 0, + MSM89XX_RX2, + MSM89XX_RX3, + MSM89XX_RX_MAX, +}; + +struct tx_mute_work { + struct msm_dig_priv *dig_cdc; + u32 decimator; + struct delayed_work dwork; +}; + +struct msm_dig_priv { + struct snd_soc_component *component; + u32 comp_enabled[MSM89XX_RX_MAX]; + int (*codec_hph_comp_gpio)(bool enable, + struct snd_soc_component *component); + s32 dmic_1_2_clk_cnt; + s32 dmic_3_4_clk_cnt; + bool dec_active[NUM_DECIMATORS]; + int version; + /* Entry for version info */ + struct snd_info_entry *entry; + struct snd_info_entry *version_entry; + char __iomem *dig_base; + struct regmap *regmap; + struct notifier_block nblock; + u32 mute_mask; + int dapm_bias_off; + void *handle; + void (*set_compander_mode)(void *handle, int val); + void (*update_clkdiv)(void *handle, int val); + int (*get_cdc_version)(void *handle); + int (*register_notifier)(void *handle, + struct notifier_block *nblock, + bool enable); + struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS]; +}; + +struct dig_ctrl_platform_data { + void *handle; + void (*set_compander_mode)(void *handle, int val); + void (*update_clkdiv)(void *handle, int val); + int (*get_cdc_version)(void *handle); + int (*register_notifier)(void *handle, + struct notifier_block *nblock, + bool enable); +}; + +struct hpf_work { + struct msm_dig_priv *dig_cdc; + u32 decimator; + u8 tx_hpf_cut_of_freq; + struct delayed_work dwork; +}; + +/* Codec supports 5 bands */ +enum { + BAND1 = 0, + BAND2, + BAND3, + BAND4, + BAND5, + BAND_MAX, +}; + +#if IS_ENABLED(CONFIG_SND_SOC_DIGITAL_CDC) +extern void msm_dig_cdc_hph_comp_cb( + int (*codec_hph_comp_gpio)( + bool enable, struct snd_soc_component *component), + struct snd_soc_component *component); +int msm_dig_codec_info_create_codec_entry(struct snd_info_entry *codec_root, + struct snd_soc_component *component); +#else /* CONFIG_SND_SOC_DIGITAL_CDC */ +static inline void msm_dig_cdc_hph_comp_cb( + int (*codec_hph_comp_gpio)( + bool enable, struct snd_soc_component *component), + struct snd_soc_component *component) +{ + +} +static inline int msm_dig_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_component *component) +{ + return 0; +} +#endif /* CONFIG_SND_SOC_DIGITAL_CDC */ +#endif diff --git a/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c b/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c new file mode 100644 index 000000000000..b74b2a1af5fe --- /dev/null +++ b/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c @@ -0,0 +1,411 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015-2018, 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm-analog-cdc.h" +#include "sdm660-cdc-irq.h" +#include "sdm660-cdc-registers.h" + +#define MAX_NUM_IRQS 14 +#define NUM_IRQ_REGS 2 +#define WCD9XXX_SYSTEM_RESUME_TIMEOUT_MS 700 + +#define BYTE_BIT_MASK(nr) (1UL << ((nr) % BITS_PER_BYTE)) +#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE) + +static irqreturn_t wcd9xxx_spmi_irq_handler(int linux_irq, void *data); + +char *irq_names[MAX_NUM_IRQS] = { + "spk_cnp_int", + "spk_clip_int", + "spk_ocp_int", + "ins_rem_det1", + "but_rel_det", + "but_press_det", + "ins_rem_det", + "mbhc_int", + "ear_ocp_int", + "hphr_ocp_int", + "hphl_ocp_det", + "ear_cnp_int", + "hphr_cnp_int", + "hphl_cnp_int" +}; + +int order[MAX_NUM_IRQS] = { + MSM89XX_IRQ_SPKR_CNP, + MSM89XX_IRQ_SPKR_CLIP, + MSM89XX_IRQ_SPKR_OCP, + MSM89XX_IRQ_MBHC_INSREM_DET1, + MSM89XX_IRQ_MBHC_RELEASE, + MSM89XX_IRQ_MBHC_PRESS, + MSM89XX_IRQ_MBHC_INSREM_DET, + MSM89XX_IRQ_MBHC_HS_DET, + MSM89XX_IRQ_EAR_OCP, + MSM89XX_IRQ_HPHR_OCP, + MSM89XX_IRQ_HPHL_OCP, + MSM89XX_IRQ_EAR_CNP, + MSM89XX_IRQ_HPHR_CNP, + MSM89XX_IRQ_HPHL_CNP, +}; + +enum wcd9xxx_spmi_pm_state { + WCD9XXX_PM_SLEEPABLE, + WCD9XXX_PM_AWAKE, + WCD9XXX_PM_ASLEEP, +}; + +struct wcd9xxx_spmi_map { + uint8_t handled[NUM_IRQ_REGS]; + uint8_t mask[NUM_IRQ_REGS]; + int linuxirq[MAX_NUM_IRQS]; + irq_handler_t handler[MAX_NUM_IRQS]; + struct platform_device *spmi[NUM_IRQ_REGS]; + struct snd_soc_component *component; + + enum wcd9xxx_spmi_pm_state pm_state; + struct mutex pm_lock; + /* pm_wq notifies change of pm_state */ + wait_queue_head_t pm_wq; + struct pm_qos_request pm_qos_req; + int wlock_holders; +}; + +struct wcd9xxx_spmi_map map; + +void wcd9xxx_spmi_enable_irq(int irq) +{ + pr_debug("%s: irqno =%d\n", __func__, irq); + + if (!(map.mask[BIT_BYTE(irq)] & (BYTE_BIT_MASK(irq)))) + return; + + map.mask[BIT_BYTE(irq)] &= + ~(BYTE_BIT_MASK(irq)); + + enable_irq(map.linuxirq[irq]); +} + +void wcd9xxx_spmi_disable_irq(int irq) +{ + pr_debug("%s: irqno =%d\n", __func__, irq); + + if (map.mask[BIT_BYTE(irq)] & (BYTE_BIT_MASK(irq))) + return; + + map.mask[BIT_BYTE(irq)] |= + (BYTE_BIT_MASK(irq)); + + disable_irq_nosync(map.linuxirq[irq]); +} + +int wcd9xxx_spmi_request_irq(int irq, irq_handler_t handler, + const char *name, void *priv) +{ + int rc; + unsigned long irq_flags; + + map.linuxirq[irq] = + platform_get_irq_byname(map.spmi[BIT_BYTE(irq)], + irq_names[irq]); + + if (strcmp(name, "mbhc sw intr")) + irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_ONESHOT; + else + irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_ONESHOT | IRQF_NO_SUSPEND; + pr_debug("%s: name:%s irq_flags = %lx\n", __func__, name, irq_flags); + + rc = devm_request_threaded_irq(&map.spmi[BIT_BYTE(irq)]->dev, + map.linuxirq[irq], NULL, + wcd9xxx_spmi_irq_handler, + irq_flags, + name, priv); + if (rc < 0) { + dev_err(&map.spmi[BIT_BYTE(irq)]->dev, + "Can't request %d IRQ\n", irq); + return rc; + } + + dev_dbg(&map.spmi[BIT_BYTE(irq)]->dev, + "irq %d linuxIRQ: %d\n", irq, map.linuxirq[irq]); + map.mask[BIT_BYTE(irq)] &= ~BYTE_BIT_MASK(irq); + map.handler[irq] = handler; + enable_irq_wake(map.linuxirq[irq]); + return 0; +} + +int wcd9xxx_spmi_free_irq(int irq, void *priv) +{ + devm_free_irq(&map.spmi[BIT_BYTE(irq)]->dev, map.linuxirq[irq], + priv); + map.mask[BIT_BYTE(irq)] |= BYTE_BIT_MASK(irq); + return 0; +} + +static int get_irq_bit(int linux_irq) +{ + int i = 0; + + for (; i < MAX_NUM_IRQS; i++) + if (map.linuxirq[i] == linux_irq) + return i; + + return i; +} + +static int get_order_irq(int i) +{ + return order[i]; +} + +static irqreturn_t wcd9xxx_spmi_irq_handler(int linux_irq, void *data) +{ + int irq, i, j; + unsigned long status[NUM_IRQ_REGS] = {0}; + + if (unlikely(wcd9xxx_spmi_lock_sleep() == false)) { + pr_err("Failed to hold suspend\n"); + return IRQ_NONE; + } + + irq = get_irq_bit(linux_irq); + if (irq == MAX_NUM_IRQS) + return IRQ_HANDLED; + + status[BIT_BYTE(irq)] |= BYTE_BIT_MASK(irq); + for (i = 0; i < NUM_IRQ_REGS; i++) { + status[i] |= snd_soc_component_read32(map.component, + BIT_BYTE(irq) * 0x100 + + MSM89XX_PMIC_DIGITAL_INT_LATCHED_STS); + status[i] &= ~map.mask[i]; + } + for (i = 0; i < MAX_NUM_IRQS; i++) { + j = get_order_irq(i); + if ((status[BIT_BYTE(j)] & BYTE_BIT_MASK(j)) && + ((map.handled[BIT_BYTE(j)] & + BYTE_BIT_MASK(j)) == 0)) { + map.handler[j](irq, data); + map.handled[BIT_BYTE(j)] |= + BYTE_BIT_MASK(j); + } + } + map.handled[BIT_BYTE(irq)] &= ~BYTE_BIT_MASK(irq); + wcd9xxx_spmi_unlock_sleep(); + + return IRQ_HANDLED; +} + +enum wcd9xxx_spmi_pm_state wcd9xxx_spmi_pm_cmpxchg( + enum wcd9xxx_spmi_pm_state o, + enum wcd9xxx_spmi_pm_state n) +{ + enum wcd9xxx_spmi_pm_state old; + + mutex_lock(&map.pm_lock); + old = map.pm_state; + if (old == o) + map.pm_state = n; + pr_debug("%s: map.pm_state = %d\n", __func__, map.pm_state); + mutex_unlock(&map.pm_lock); + return old; +} +EXPORT_SYMBOL(wcd9xxx_spmi_pm_cmpxchg); + +int wcd9xxx_spmi_suspend(pm_message_t pmesg) +{ + int ret = 0; + + pr_debug("%s: enter\n", __func__); + /* + * pm_qos_update_request() can be called after this suspend chain call + * started. thus suspend can be called while lock is being held + */ + mutex_lock(&map.pm_lock); + if (map.pm_state == WCD9XXX_PM_SLEEPABLE) { + pr_debug("%s: suspending system, state %d, wlock %d\n", + __func__, map.pm_state, + map.wlock_holders); + map.pm_state = WCD9XXX_PM_ASLEEP; + } else if (map.pm_state == WCD9XXX_PM_AWAKE) { + /* + * unlock to wait for pm_state == WCD9XXX_PM_SLEEPABLE + * then set to WCD9XXX_PM_ASLEEP + */ + pr_debug("%s: waiting to suspend system, state %d, wlock %d\n", + __func__, map.pm_state, + map.wlock_holders); + mutex_unlock(&map.pm_lock); + if (!(wait_event_timeout(map.pm_wq, + wcd9xxx_spmi_pm_cmpxchg( + WCD9XXX_PM_SLEEPABLE, + WCD9XXX_PM_ASLEEP) == + WCD9XXX_PM_SLEEPABLE, + HZ))) { + pr_debug("%s: suspend failed state %d, wlock %d\n", + __func__, map.pm_state, + map.wlock_holders); + ret = -EBUSY; + } else { + pr_debug("%s: done, state %d, wlock %d\n", __func__, + map.pm_state, + map.wlock_holders); + } + mutex_lock(&map.pm_lock); + } else if (map.pm_state == WCD9XXX_PM_ASLEEP) { + pr_warn("%s: system is already suspended, state %d, wlock %dn", + __func__, map.pm_state, + map.wlock_holders); + } + mutex_unlock(&map.pm_lock); + + return ret; +} +EXPORT_SYMBOL(wcd9xxx_spmi_suspend); + +int wcd9xxx_spmi_resume(void) +{ + int ret = 0; + + pr_debug("%s: enter\n", __func__); + mutex_lock(&map.pm_lock); + if (map.pm_state == WCD9XXX_PM_ASLEEP) { + pr_debug("%s: resuming system, state %d, wlock %d\n", __func__, + map.pm_state, + map.wlock_holders); + map.pm_state = WCD9XXX_PM_SLEEPABLE; + } else { + pr_warn("%s: system is already awake, state %d wlock %d\n", + __func__, map.pm_state, + map.wlock_holders); + } + mutex_unlock(&map.pm_lock); + wake_up_all(&map.pm_wq); + + return ret; +} +EXPORT_SYMBOL(wcd9xxx_spmi_resume); + +bool wcd9xxx_spmi_lock_sleep(void) +{ + /* + * wcd9xxx_spmi_{lock/unlock}_sleep will be called by + * wcd9xxx_spmi_irq_thread + * and its subroutines only motly. + * but btn0_lpress_fn is not wcd9xxx_spmi_irq_thread's subroutine and + * It can race with wcd9xxx_spmi_irq_thread. + * So need to embrace wlock_holders with mutex. + */ + mutex_lock(&map.pm_lock); + if (map.wlock_holders++ == 0) { + pr_debug("%s: holding wake lock\n", __func__); + pm_qos_update_request(&map.pm_qos_req, + msm_cpuidle_get_deep_idle_latency()); + pm_stay_awake(&map.spmi[0]->dev); + } + mutex_unlock(&map.pm_lock); + pr_debug("%s: wake lock counter %d\n", __func__, + map.wlock_holders); + pr_debug("%s: map.pm_state = %d\n", __func__, map.pm_state); + + if (!wait_event_timeout(map.pm_wq, + ((wcd9xxx_spmi_pm_cmpxchg( + WCD9XXX_PM_SLEEPABLE, + WCD9XXX_PM_AWAKE)) == + WCD9XXX_PM_SLEEPABLE || + (wcd9xxx_spmi_pm_cmpxchg( + WCD9XXX_PM_SLEEPABLE, + WCD9XXX_PM_AWAKE) == + WCD9XXX_PM_AWAKE)), + msecs_to_jiffies( + WCD9XXX_SYSTEM_RESUME_TIMEOUT_MS))) { + pr_warn("%s: system didn't resume within %dms, s %d, w %d\n", + __func__, + WCD9XXX_SYSTEM_RESUME_TIMEOUT_MS, map.pm_state, + map.wlock_holders); + wcd9xxx_spmi_unlock_sleep(); + return false; + } + wake_up_all(&map.pm_wq); + pr_debug("%s: leaving pm_state = %d\n", __func__, map.pm_state); + return true; +} +EXPORT_SYMBOL(wcd9xxx_spmi_lock_sleep); + +void wcd9xxx_spmi_unlock_sleep(void) +{ + mutex_lock(&map.pm_lock); + if (--map.wlock_holders == 0) { + pr_debug("%s: releasing wake lock pm_state %d -> %d\n", + __func__, map.pm_state, WCD9XXX_PM_SLEEPABLE); + /* + * if wcd9xxx_spmi_lock_sleep failed, pm_state would be still + * WCD9XXX_PM_ASLEEP, don't overwrite + */ + if (likely(map.pm_state == WCD9XXX_PM_AWAKE)) + map.pm_state = WCD9XXX_PM_SLEEPABLE; + pm_qos_update_request(&map.pm_qos_req, + PM_QOS_DEFAULT_VALUE); + pm_relax(&map.spmi[0]->dev); + } + mutex_unlock(&map.pm_lock); + pr_debug("%s: wake lock counter %d\n", __func__, + map.wlock_holders); + pr_debug("%s: map.pm_state = %d\n", __func__, map.pm_state); + wake_up_all(&map.pm_wq); +} +EXPORT_SYMBOL(wcd9xxx_spmi_unlock_sleep); + +void wcd9xxx_spmi_set_codec(struct snd_soc_component *component) +{ + map.component = component; +} + +void wcd9xxx_spmi_set_dev(struct platform_device *spmi, int i) +{ + if (i < NUM_IRQ_REGS) + map.spmi[i] = spmi; +} + +int wcd9xxx_spmi_irq_init(void) +{ + int i = 0; + + for (; i < MAX_NUM_IRQS; i++) + map.mask[BIT_BYTE(i)] |= BYTE_BIT_MASK(i); + mutex_init(&map.pm_lock); + map.wlock_holders = 0; + map.pm_state = WCD9XXX_PM_SLEEPABLE; + init_waitqueue_head(&map.pm_wq); + pm_qos_add_request(&map.pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + PM_QOS_DEFAULT_VALUE); + + return 0; +} + +void wcd9xxx_spmi_irq_exit(void) +{ + pm_qos_remove_request(&map.pm_qos_req); + mutex_destroy(&map.pm_lock); +} +MODULE_DESCRIPTION("MSM8x16 SPMI IRQ driver"); +MODULE_LICENSE("GPL v2"); diff --git a/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h b/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h new file mode 100644 index 000000000000..02f50481c37e --- /dev/null +++ b/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2015-2018, 2020, The Linux Foundation. All rights reserved. + */ +#ifndef __WCD9XXX_SPMI_IRQ_H__ +#define __WCD9XXX_SPMI_IRQ_H__ + +#include +#include +#include +#include +#include + +extern void wcd9xxx_spmi_enable_irq(int irq); +extern void wcd9xxx_spmi_disable_irq(int irq); +extern int wcd9xxx_spmi_request_irq(int irq, irq_handler_t handler, + const char *name, void *priv); +extern int wcd9xxx_spmi_free_irq(int irq, void *priv); +extern void wcd9xxx_spmi_set_codec(struct snd_soc_component *component); +extern void wcd9xxx_spmi_set_dev(struct platform_device *spmi, int i); +extern int wcd9xxx_spmi_irq_init(void); +extern void wcd9xxx_spmi_irq_exit(void); +extern int wcd9xxx_spmi_suspend(pm_message_t pmesg); +extern int wcd9xxx_spmi_resume(void); +bool wcd9xxx_spmi_lock_sleep(void); +void wcd9xxx_spmi_unlock_sleep(void); + +#endif diff --git a/asoc/codecs/sdm660_cdc/sdm660-cdc-registers.h b/asoc/codecs/sdm660_cdc/sdm660-cdc-registers.h new file mode 100644 index 000000000000..6f9b74a8e219 --- /dev/null +++ b/asoc/codecs/sdm660_cdc/sdm660-cdc-registers.h @@ -0,0 +1,596 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2015-2017, 2020, The Linux Foundation. All rights reserved. + */ +#ifndef SDM660_WCD_REGISTERS_H +#define SDM660_WCD_REGISTERS_H + +#define CDC_DIG_BASE 0xF000 +#define CDC_ANA_BASE 0xF100 + +#define MSM89XX_PMIC_DIGITAL_REVISION1 (CDC_DIG_BASE+0x000) +#define MSM89XX_PMIC_DIGITAL_REVISION1__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_REVISION2 (CDC_DIG_BASE+0x001) +#define MSM89XX_PMIC_DIGITAL_REVISION2__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_PERPH_TYPE (CDC_DIG_BASE+0x004) +#define MSM89XX_PMIC_DIGITAL_PERPH_TYPE__POR (0x23) +#define MSM89XX_PMIC_DIGITAL_PERPH_SUBTYPE (CDC_DIG_BASE+0x005) +#define MSM89XX_PMIC_DIGITAL_PERPH_SUBTYPE__POR (0x01) +#define MSM89XX_PMIC_DIGITAL_INT_RT_STS (CDC_DIG_BASE+0x010) +#define MSM89XX_PMIC_DIGITAL_INT_RT_STS__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_SET_TYPE (CDC_DIG_BASE+0x011) +#define MSM89XX_PMIC_DIGITAL_INT_SET_TYPE__POR (0xFF) +#define MSM89XX_PMIC_DIGITAL_INT_POLARITY_HIGH (CDC_DIG_BASE+0x012) +#define MSM89XX_PMIC_DIGITAL_INT_POLARITY_HIGH__POR (0xFF) +#define MSM89XX_PMIC_DIGITAL_INT_POLARITY_LOW (CDC_DIG_BASE+0x013) +#define MSM89XX_PMIC_DIGITAL_INT_POLARITY_LOW__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_LATCHED_CLR (CDC_DIG_BASE+0x014) +#define MSM89XX_PMIC_DIGITAL_INT_LATCHED_CLR__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_EN_SET (CDC_DIG_BASE+0x015) +#define MSM89XX_PMIC_DIGITAL_INT_EN_SET__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_EN_CLR (CDC_DIG_BASE+0x016) +#define MSM89XX_PMIC_DIGITAL_INT_EN_CLR__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_LATCHED_STS (CDC_DIG_BASE+0x018) +#define MSM89XX_PMIC_DIGITAL_INT_LATCHED_STS__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_PENDING_STS (CDC_DIG_BASE+0x019) +#define MSM89XX_PMIC_DIGITAL_INT_PENDING_STS__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_MID_SEL (CDC_DIG_BASE+0x01A) +#define MSM89XX_PMIC_DIGITAL_INT_MID_SEL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_PRIORITY (CDC_DIG_BASE+0x01B) +#define MSM89XX_PMIC_DIGITAL_INT_PRIORITY__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_GPIO_MODE (CDC_DIG_BASE+0x040) +#define MSM89XX_PMIC_DIGITAL_GPIO_MODE__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_PIN_CTL_OE (CDC_DIG_BASE+0x041) +#define MSM89XX_PMIC_DIGITAL_PIN_CTL_OE__POR (0x01) +#define MSM89XX_PMIC_DIGITAL_PIN_CTL_DATA (CDC_DIG_BASE+0x042) +#define MSM89XX_PMIC_DIGITAL_PIN_CTL_DATA__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_PIN_STATUS (CDC_DIG_BASE+0x043) +#define MSM89XX_PMIC_DIGITAL_PIN_STATUS__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_HDRIVE_CTL (CDC_DIG_BASE+0x044) +#define MSM89XX_PMIC_DIGITAL_HDRIVE_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_RST_CTL (CDC_DIG_BASE+0x046) +#define MSM89XX_PMIC_DIGITAL_CDC_RST_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL (CDC_DIG_BASE+0x048) +#define MSM89XX_PMIC_DIGITAL_CDC_TOP_CLK_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL (CDC_DIG_BASE+0x049) +#define MSM89XX_PMIC_DIGITAL_CDC_ANA_CLK_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL (CDC_DIG_BASE+0x04A) +#define MSM89XX_PMIC_DIGITAL_CDC_DIG_CLK_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL (CDC_DIG_BASE+0x050) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_TX1_CTL__POR (0x02) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL (CDC_DIG_BASE+0x051) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_TX2_CTL__POR (0x02) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_HPHR_DAC_CTL (CDC_DIG_BASE+0x052) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_HPHR_DAC_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX1_CTL (CDC_DIG_BASE+0x053) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX1_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX2_CTL (CDC_DIG_BASE+0x054) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX2_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX3_CTL (CDC_DIG_BASE+0x055) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX3_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX_LB_CTL (CDC_DIG_BASE+0x056) +#define MSM89XX_PMIC_DIGITAL_CDC_CONN_RX_LB_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL1 (CDC_DIG_BASE+0x058) +#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL1__POR (0x7C) +#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL2 (CDC_DIG_BASE+0x059) +#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL2__POR (0x7C) +#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL3 (CDC_DIG_BASE+0x05A) +#define MSM89XX_PMIC_DIGITAL_CDC_RX_CTL3__POR (0x7C) +#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA0 (CDC_DIG_BASE+0x05B) +#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA0__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA1 (CDC_DIG_BASE+0x05C) +#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA1__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA2 (CDC_DIG_BASE+0x05D) +#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA2__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA3 (CDC_DIG_BASE+0x05E) +#define MSM89XX_PMIC_DIGITAL_DEM_BYPASS_DATA3__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_DIG_DEBUG_CTL (CDC_DIG_BASE+0x068) +#define MSM89XX_PMIC_DIGITAL_DIG_DEBUG_CTL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_DIG_DEBUG_EN (CDC_DIG_BASE+0x069) +#define MSM89XX_PMIC_DIGITAL_DIG_DEBUG_EN__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_SPARE_0 (CDC_DIG_BASE+0x070) +#define MSM89XX_PMIC_DIGITAL_SPARE_0__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_SPARE_1 (CDC_DIG_BASE+0x071) +#define MSM89XX_PMIC_DIGITAL_SPARE_1__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_SPARE_2 (CDC_DIG_BASE+0x072) +#define MSM89XX_PMIC_DIGITAL_SPARE_2__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_SEC_ACCESS (CDC_DIG_BASE+0x0D0) +#define MSM89XX_PMIC_DIGITAL_SEC_ACCESS__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL1 (CDC_DIG_BASE+0x0D8) +#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL1__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL2 (CDC_DIG_BASE+0x0D9) +#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL2__POR (0x01) +#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3 (CDC_DIG_BASE+0x0DA) +#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL3__POR (0x05) +#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4 (CDC_DIG_BASE+0x0DB) +#define MSM89XX_PMIC_DIGITAL_PERPH_RESET_CTL4__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_TEST1 (CDC_DIG_BASE+0x0E0) +#define MSM89XX_PMIC_DIGITAL_INT_TEST1__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_INT_TEST_VAL (CDC_DIG_BASE+0x0E1) +#define MSM89XX_PMIC_DIGITAL_INT_TEST_VAL__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_TRIM_NUM (CDC_DIG_BASE+0x0F0) +#define MSM89XX_PMIC_DIGITAL_TRIM_NUM__POR (0x00) +#define MSM89XX_PMIC_DIGITAL_TRIM_CTRL (CDC_DIG_BASE+0x0F1) +#define MSM89XX_PMIC_DIGITAL_TRIM_CTRL__POR (0x00) + +#define MSM89XX_PMIC_ANALOG_REVISION1 (CDC_ANA_BASE+0x00) +#define MSM89XX_PMIC_ANALOG_REVISION1__POR (0x00) +#define MSM89XX_PMIC_ANALOG_REVISION2 (CDC_ANA_BASE+0x01) +#define MSM89XX_PMIC_ANALOG_REVISION2__POR (0x00) +#define MSM89XX_PMIC_ANALOG_REVISION3 (CDC_ANA_BASE+0x02) +#define MSM89XX_PMIC_ANALOG_REVISION3__POR (0x00) +#define MSM89XX_PMIC_ANALOG_REVISION4 (CDC_ANA_BASE+0x03) +#define MSM89XX_PMIC_ANALOG_REVISION4__POR (0x00) +#define MSM89XX_PMIC_ANALOG_PERPH_TYPE (CDC_ANA_BASE+0x04) +#define MSM89XX_PMIC_ANALOG_PERPH_TYPE__POR (0x23) +#define MSM89XX_PMIC_ANALOG_PERPH_SUBTYPE (CDC_ANA_BASE+0x05) +#define MSM89XX_PMIC_ANALOG_PERPH_SUBTYPE__POR (0x09) +#define MSM89XX_PMIC_ANALOG_INT_RT_STS (CDC_ANA_BASE+0x10) +#define MSM89XX_PMIC_ANALOG_INT_RT_STS__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_SET_TYPE (CDC_ANA_BASE+0x11) +#define MSM89XX_PMIC_ANALOG_INT_SET_TYPE__POR (0x3F) +#define MSM89XX_PMIC_ANALOG_INT_POLARITY_HIGH (CDC_ANA_BASE+0x12) +#define MSM89XX_PMIC_ANALOG_INT_POLARITY_HIGH__POR (0x3F) +#define MSM89XX_PMIC_ANALOG_INT_POLARITY_LOW (CDC_ANA_BASE+0x13) +#define MSM89XX_PMIC_ANALOG_INT_POLARITY_LOW__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_LATCHED_CLR (CDC_ANA_BASE+0x14) +#define MSM89XX_PMIC_ANALOG_INT_LATCHED_CLR__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_EN_SET (CDC_ANA_BASE+0x15) +#define MSM89XX_PMIC_ANALOG_INT_EN_SET__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_EN_CLR (CDC_ANA_BASE+0x16) +#define MSM89XX_PMIC_ANALOG_INT_EN_CLR__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_LATCHED_STS (CDC_ANA_BASE+0x18) +#define MSM89XX_PMIC_ANALOG_INT_LATCHED_STS__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_PENDING_STS (CDC_ANA_BASE+0x19) +#define MSM89XX_PMIC_ANALOG_INT_PENDING_STS__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_MID_SEL (CDC_ANA_BASE+0x1A) +#define MSM89XX_PMIC_ANALOG_INT_MID_SEL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_PRIORITY (CDC_ANA_BASE+0x1B) +#define MSM89XX_PMIC_ANALOG_INT_PRIORITY__POR (0x00) +#define MSM89XX_PMIC_ANALOG_MICB_1_EN (CDC_ANA_BASE+0x40) +#define MSM89XX_PMIC_ANALOG_MICB_1_EN__POR (0x00) +#define MSM89XX_PMIC_ANALOG_MICB_1_VAL (CDC_ANA_BASE+0x41) +#define MSM89XX_PMIC_ANALOG_MICB_1_VAL__POR (0x20) +#define MSM89XX_PMIC_ANALOG_MICB_1_CTL (CDC_ANA_BASE+0x42) +#define MSM89XX_PMIC_ANALOG_MICB_1_CTL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS (CDC_ANA_BASE+0x43) +#define MSM89XX_PMIC_ANALOG_MICB_1_INT_RBIAS__POR (0x49) +#define MSM89XX_PMIC_ANALOG_MICB_2_EN (CDC_ANA_BASE+0x44) +#define MSM89XX_PMIC_ANALOG_MICB_2_EN__POR (0x20) +#define MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2 (CDC_ANA_BASE+0x45) +#define MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL_2__POR (0x00) +#define MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL (CDC_ANA_BASE+0x46) +#define MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1 (CDC_ANA_BASE+0x47) +#define MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_1__POR (0x35) +#define MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2 (CDC_ANA_BASE+0x50) +#define MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2__POR (0x08) +#define MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL (CDC_ANA_BASE+0x51) +#define MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER (CDC_ANA_BASE+0x52) +#define MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER__POR (0x98) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL (CDC_ANA_BASE+0x53) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL (CDC_ANA_BASE+0x54) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL__POR (0x20) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL (CDC_ANA_BASE+0x55) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL__POR (0x40) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN3_CTL (CDC_ANA_BASE+0x56) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN3_CTL__POR (0x61) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN4_CTL (CDC_ANA_BASE+0x57) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN4_CTL__POR (0x80) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT (CDC_ANA_BASE+0x58) +#define MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT__POR (0x00) +#define MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT (CDC_ANA_BASE+0x59) +#define MSM89XX_PMIC_ANALOG_MBHC_ZDET_ELECT_RESULT__POR (0x00) +#define MSM89XX_PMIC_ANALOG_TX_1_EN (CDC_ANA_BASE+0x60) +#define MSM89XX_PMIC_ANALOG_TX_1_EN__POR (0x03) +#define MSM89XX_PMIC_ANALOG_TX_2_EN (CDC_ANA_BASE+0x61) +#define MSM89XX_PMIC_ANALOG_TX_2_EN__POR (0x03) +#define MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_1 (CDC_ANA_BASE+0x62) +#define MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_1__POR (0xBF) +#define MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_2 (CDC_ANA_BASE+0x63) +#define MSM89XX_PMIC_ANALOG_TX_1_2_TEST_CTL_2__POR (0x8C) +#define MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL (CDC_ANA_BASE+0x64) +#define MSM89XX_PMIC_ANALOG_TX_1_2_ATEST_CTL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS (CDC_ANA_BASE+0x65) +#define MSM89XX_PMIC_ANALOG_TX_1_2_OPAMP_BIAS__POR (0x6B) +#define MSM89XX_PMIC_ANALOG_TX_1_2_TXFE_CLKDIV (CDC_ANA_BASE+0x66) +#define MSM89XX_PMIC_ANALOG_TX_1_2_TXFE_CLKDIV__POR (0x51) +#define MSM89XX_PMIC_ANALOG_TX_3_EN (CDC_ANA_BASE+0x67) +#define MSM89XX_PMIC_ANALOG_TX_3_EN__POR (0x02) +#define MSM89XX_PMIC_ANALOG_NCP_EN (CDC_ANA_BASE+0x80) +#define MSM89XX_PMIC_ANALOG_NCP_EN__POR (0x26) +#define MSM89XX_PMIC_ANALOG_NCP_CLK (CDC_ANA_BASE+0x81) +#define MSM89XX_PMIC_ANALOG_NCP_CLK__POR (0x23) +#define MSM89XX_PMIC_ANALOG_NCP_DEGLITCH (CDC_ANA_BASE+0x82) +#define MSM89XX_PMIC_ANALOG_NCP_DEGLITCH__POR (0x5B) +#define MSM89XX_PMIC_ANALOG_NCP_FBCTRL (CDC_ANA_BASE+0x83) +#define MSM89XX_PMIC_ANALOG_NCP_FBCTRL__POR (0x08) +#define MSM89XX_PMIC_ANALOG_NCP_BIAS (CDC_ANA_BASE+0x84) +#define MSM89XX_PMIC_ANALOG_NCP_BIAS__POR (0x29) +#define MSM89XX_PMIC_ANALOG_NCP_VCTRL (CDC_ANA_BASE+0x85) +#define MSM89XX_PMIC_ANALOG_NCP_VCTRL__POR (0x24) +#define MSM89XX_PMIC_ANALOG_NCP_TEST (CDC_ANA_BASE+0x86) +#define MSM89XX_PMIC_ANALOG_NCP_TEST__POR (0x00) +#define MSM89XX_PMIC_ANALOG_NCP_CLIM_ADDR (CDC_ANA_BASE+0x87) +#define MSM89XX_PMIC_ANALOG_NCP_CLIM_ADDR__POR (0xD5) +#define MSM89XX_PMIC_ANALOG_RX_CLOCK_DIVIDER (CDC_ANA_BASE+0x90) +#define MSM89XX_PMIC_ANALOG_RX_CLOCK_DIVIDER__POR (0xE8) +#define MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL (CDC_ANA_BASE+0x91) +#define MSM89XX_PMIC_ANALOG_RX_COM_OCP_CTL__POR (0xCF) +#define MSM89XX_PMIC_ANALOG_RX_COM_OCP_COUNT (CDC_ANA_BASE+0x92) +#define MSM89XX_PMIC_ANALOG_RX_COM_OCP_COUNT__POR (0x6E) +#define MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC (CDC_ANA_BASE+0x93) +#define MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC__POR (0x18) +#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA (CDC_ANA_BASE+0x94) +#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_PA__POR (0x5A) +#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_LDO_OCP (CDC_ANA_BASE+0x95) +#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_LDO_OCP__POR (0x69) +#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_CNP (CDC_ANA_BASE+0x96) +#define MSM89XX_PMIC_ANALOG_RX_HPH_BIAS_CNP__POR (0x29) +#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN (CDC_ANA_BASE+0x97) +#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_EN__POR (0x80) +#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_CTL (CDC_ANA_BASE+0x98) +#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_CTL__POR (0xDA) +#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME (CDC_ANA_BASE+0x99) +#define MSM89XX_PMIC_ANALOG_RX_HPH_CNP_WG_TIME__POR (0x16) +#define MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST (CDC_ANA_BASE+0x9A) +#define MSM89XX_PMIC_ANALOG_RX_HPH_L_TEST__POR (0x00) +#define MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL (CDC_ANA_BASE+0x9B) +#define MSM89XX_PMIC_ANALOG_RX_HPH_L_PA_DAC_CTL__POR (0x20) +#define MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST (CDC_ANA_BASE+0x9C) +#define MSM89XX_PMIC_ANALOG_RX_HPH_R_TEST__POR (0x00) +#define MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL (CDC_ANA_BASE+0x9D) +#define MSM89XX_PMIC_ANALOG_RX_HPH_R_PA_DAC_CTL__POR (0x20) +#define MSM89XX_PMIC_ANALOG_RX_EAR_CTL (CDC_ANA_BASE+0x9E) +#define MSM89XX_PMIC_ANALOG_RX_EAR_CTL___POR (0x12) +#define MSM89XX_PMIC_ANALOG_RX_ATEST (CDC_ANA_BASE+0x9F) +#define MSM89XX_PMIC_ANALOG_RX_ATEST__POR (0x00) +#define MSM89XX_PMIC_ANALOG_RX_HPH_STATUS (CDC_ANA_BASE+0xA0) +#define MSM89XX_PMIC_ANALOG_RX_HPH_STATUS__POR (0x0C) +#define MSM89XX_PMIC_ANALOG_RX_EAR_STATUS (CDC_ANA_BASE+0xA1) +#define MSM89XX_PMIC_ANALOG_RX_EAR_STATUS__POR (0x00) +#define MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL (CDC_ANA_BASE+0xAC) +#define MSM89XX_PMIC_ANALOG_RX_LO_DAC_CTL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_RX_LO_EN_CTL (CDC_ANA_BASE+0xAD) +#define MSM89XX_PMIC_ANALOG_RX_RX_LO_EN_CTL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL (CDC_ANA_BASE+0xB0) +#define MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL__POR (0x83) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_CLIP_DET (CDC_ANA_BASE+0xB1) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_CLIP_DET__POR (0x91) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL (CDC_ANA_BASE+0xB2) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_CTL__POR (0x29) +#define MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET (CDC_ANA_BASE+0xB3) +#define MSM89XX_PMIC_ANALOG_SPKR_ANA_BIAS_SET__POR (0x4D) +#define MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL (CDC_ANA_BASE+0xB4) +#define MSM89XX_PMIC_ANALOG_SPKR_OCP_CTL__POR (0xE1) +#define MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL (CDC_ANA_BASE+0xB5) +#define MSM89XX_PMIC_ANALOG_SPKR_PWRSTG_CTL__POR (0x1E) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_MISC (CDC_ANA_BASE+0xB6) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_MISC__POR (0xCB) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG (CDC_ANA_BASE+0xB7) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_DBG__POR (0x00) +#define MSM89XX_PMIC_ANALOG_CURRENT_LIMIT (CDC_ANA_BASE+0xC0) +#define MSM89XX_PMIC_ANALOG_CURRENT_LIMIT__POR (0x02) +#define MSM89XX_PMIC_ANALOG_OUTPUT_VOLTAGE (CDC_ANA_BASE+0xC1) +#define MSM89XX_PMIC_ANALOG_OUTPUT_VOLTAGE__POR (0x14) +#define MSM89XX_PMIC_ANALOG_BYPASS_MODE (CDC_ANA_BASE+0xC2) +#define MSM89XX_PMIC_ANALOG_BYPASS_MODE__POR (0x00) +#define MSM89XX_PMIC_ANALOG_BOOST_EN_CTL (CDC_ANA_BASE+0xC3) +#define MSM89XX_PMIC_ANALOG_BOOST_EN_CTL__POR (0x1F) +#define MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO (CDC_ANA_BASE+0xC4) +#define MSM89XX_PMIC_ANALOG_SLOPE_COMP_IP_ZERO__POR (0x8C) +#define MSM89XX_PMIC_ANALOG_RDSON_MAX_DUTY_CYCLE (CDC_ANA_BASE+0xC5) +#define MSM89XX_PMIC_ANALOG_RDSON_MAX_DUTY_CYCLE__POR (0xC0) +#define MSM89XX_PMIC_ANALOG_BOOST_TEST1_1 (CDC_ANA_BASE+0xC6) +#define MSM89XX_PMIC_ANALOG_BOOST_TEST1_1__POR (0x00) +#define MSM89XX_PMIC_ANALOG_BOOST_TEST_2 (CDC_ANA_BASE+0xC7) +#define MSM89XX_PMIC_ANALOG_BOOST_TEST_2__POR (0x00) +#define MSM89XX_PMIC_ANALOG_SPKR_SAR_STATUS (CDC_ANA_BASE+0xC8) +#define MSM89XX_PMIC_ANALOG_SPKR_SAR_STATUS__POR (0x00) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_STATUS (CDC_ANA_BASE+0xC9) +#define MSM89XX_PMIC_ANALOG_SPKR_DRV_STATUS__POR (0x00) +#define MSM89XX_PMIC_ANALOG_PBUS_ADD_CSR (CDC_ANA_BASE+0xCE) +#define MSM89XX_PMIC_ANALOG_PBUS_ADD_CSR__POR (0x00) +#define MSM89XX_PMIC_ANALOG_PBUS_ADD_SEL (CDC_ANA_BASE+0xCF) +#define MSM89XX_PMIC_ANALOG_PBUS_ADD_SEL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_SEC_ACCESS (CDC_ANA_BASE+0xD0) +#define MSM89XX_PMIC_ANALOG_SEC_ACCESS__POR (0x00) +#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL1 (CDC_ANA_BASE+0xD8) +#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL1__POR (0x00) +#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL2 (CDC_ANA_BASE+0xD9) +#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL2__POR (0x01) +#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3 (CDC_ANA_BASE+0xDA) +#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL3__POR (0x05) +#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4 (CDC_ANA_BASE+0xDB) +#define MSM89XX_PMIC_ANALOG_PERPH_RESET_CTL4__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_TEST1 (CDC_ANA_BASE+0xE0) +#define MSM89XX_PMIC_ANALOG_INT_TEST1__POR (0x00) +#define MSM89XX_PMIC_ANALOG_INT_TEST_VAL (CDC_ANA_BASE+0xE1) +#define MSM89XX_PMIC_ANALOG_INT_TEST_VAL__POR (0x00) +#define MSM89XX_PMIC_ANALOG_TRIM_NUM (CDC_ANA_BASE+0xF0) +#define MSM89XX_PMIC_ANALOG_TRIM_NUM__POR (0x04) +#define MSM89XX_PMIC_ANALOG_TRIM_CTRL1 (CDC_ANA_BASE+0xF1) +#define MSM89XX_PMIC_ANALOG_TRIM_CTRL1__POR (0x00) +#define MSM89XX_PMIC_ANALOG_TRIM_CTRL2 (CDC_ANA_BASE+0xF2) +#define MSM89XX_PMIC_ANALOG_TRIM_CTRL2__POR (0x00) +#define MSM89XX_PMIC_ANALOG_TRIM_CTRL3 (CDC_ANA_BASE+0xF3) +#define MSM89XX_PMIC_ANALOG_TRIM_CTRL3__POR (0x00) +#define MSM89XX_PMIC_ANALOG_TRIM_CTRL4 (CDC_ANA_BASE+0xF4) +#define MSM89XX_PMIC_ANALOG_TRIM_CTRL4__POR (0x00) + +#define MSM89XX_PMIC_CDC_NUM_REGISTERS \ + (MSM89XX_PMIC_ANALOG_TRIM_CTRL4+1) +#define MSM89XX_PMIC_CDC_MAX_REGISTER \ + (MSM89XX_PMIC_CDC_NUM_REGISTERS-1) +#define MSM89XX_PMIC_CDC_CACHE_SIZE \ + MSM89XX_PMIC_CDC_NUM_REGISTERS + + +#define MSM89XX_CDC_CORE_CLK_RX_RESET_CTL (0x00) +#define MSM89XX_CDC_CORE_CLK_RX_RESET_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL (0x04) +#define MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL (0x08) +#define MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_RX_I2S_CTL (0x0C) +#define MSM89XX_CDC_CORE_CLK_RX_I2S_CTL__POR (0x13) +#define MSM89XX_CDC_CORE_CLK_TX_I2S_CTL (0x10) +#define MSM89XX_CDC_CORE_CLK_TX_I2S_CTL__POR (0x13) +#define MSM89XX_CDC_CORE_CLK_OTHR_RESET_B1_CTL (0x14) +#define MSM89XX_CDC_CORE_CLK_OTHR_RESET_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL (0x18) +#define MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_OTHR_CTL (0x1C) +#define MSM89XX_CDC_CORE_CLK_OTHR_CTL__POR (0x04) +#define MSM89XX_CDC_CORE_CLK_RX_B1_CTL (0x20) +#define MSM89XX_CDC_CORE_CLK_RX_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_MCLK_CTL (0x24) +#define MSM89XX_CDC_CORE_CLK_MCLK_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_PDM_CTL (0x28) +#define MSM89XX_CDC_CORE_CLK_PDM_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_SD_CTL (0x2C) +#define MSM89XX_CDC_CORE_CLK_SD_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL (0x30) +#define MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_RX_B2_CTL (0x34) +#define MSM89XX_CDC_CORE_CLK_RX_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CLK_TX2_I2S_CTL (0x38) +#define MSM89XX_CDC_CORE_CLK_TX2_I2S_CTL__POR (0x13) +#define MSM89XX_CDC_CORE_RX1_B1_CTL (0x40) +#define MSM89XX_CDC_CORE_RX1_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX2_B1_CTL (0x60) +#define MSM89XX_CDC_CORE_RX2_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX3_B1_CTL (0x80) +#define MSM89XX_CDC_CORE_RX3_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX1_B2_CTL (0x44) +#define MSM89XX_CDC_CORE_RX1_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX2_B2_CTL (0x64) +#define MSM89XX_CDC_CORE_RX2_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX3_B2_CTL (0x84) +#define MSM89XX_CDC_CORE_RX3_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX1_B3_CTL (0x48) +#define MSM89XX_CDC_CORE_RX1_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX2_B3_CTL (0x68) +#define MSM89XX_CDC_CORE_RX2_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX3_B3_CTL (0x88) +#define MSM89XX_CDC_CORE_RX3_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX1_B4_CTL (0x4C) +#define MSM89XX_CDC_CORE_RX1_B4_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX2_B4_CTL (0x6C) +#define MSM89XX_CDC_CORE_RX2_B4_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX3_B4_CTL (0x8C) +#define MSM89XX_CDC_CORE_RX3_B4_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX1_B5_CTL (0x50) +#define MSM89XX_CDC_CORE_RX1_B5_CTL__POR (0x68) +#define MSM89XX_CDC_CORE_RX2_B5_CTL (0x70) +#define MSM89XX_CDC_CORE_RX2_B5_CTL__POR (0x68) +#define MSM89XX_CDC_CORE_RX3_B5_CTL (0x90) +#define MSM89XX_CDC_CORE_RX3_B5_CTL__POR (0x68) +#define MSM89XX_CDC_CORE_RX1_B6_CTL (0x54) +#define MSM89XX_CDC_CORE_RX1_B6_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX2_B6_CTL (0x74) +#define MSM89XX_CDC_CORE_RX2_B6_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX3_B6_CTL (0x94) +#define MSM89XX_CDC_CORE_RX3_B6_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX1_VOL_CTL_B1_CTL (0x58) +#define MSM89XX_CDC_CORE_RX1_VOL_CTL_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX2_VOL_CTL_B1_CTL (0x78) +#define MSM89XX_CDC_CORE_RX2_VOL_CTL_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX3_VOL_CTL_B1_CTL (0x98) +#define MSM89XX_CDC_CORE_RX3_VOL_CTL_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL (0x5C) +#define MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL (0x7C) +#define MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL (0x9C) +#define MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TOP_GAIN_UPDATE (0xA0) +#define MSM89XX_CDC_CORE_TOP_GAIN_UPDATE__POR (0x00) +#define MSM89XX_CDC_CORE_TOP_CTL (0xA4) +#define MSM89XX_CDC_CORE_TOP_CTL__POR (0x01) +#define MSM89XX_CDC_CORE_COMP0_B1_CTL (0xB0) +#define MSM89XX_CDC_CORE_COMP0_B1_CTL__POR (0x30) +#define MSM89XX_CDC_CORE_COMP0_B2_CTL (0xB4) +#define MSM89XX_CDC_CORE_COMP0_B2_CTL__POR (0xB5) +#define MSM89XX_CDC_CORE_COMP0_B3_CTL (0xB8) +#define MSM89XX_CDC_CORE_COMP0_B3_CTL__POR (0x28) +#define MSM89XX_CDC_CORE_COMP0_B4_CTL (0xBC) +#define MSM89XX_CDC_CORE_COMP0_B4_CTL__POR (0x37) +#define MSM89XX_CDC_CORE_COMP0_B5_CTL (0xC0) +#define MSM89XX_CDC_CORE_COMP0_B5_CTL__POR (0x7F) +#define MSM89XX_CDC_CORE_COMP0_B6_CTL (0xC4) +#define MSM89XX_CDC_CORE_COMP0_B6_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_COMP0_SHUT_DOWN_STATUS (0xC8) +#define MSM89XX_CDC_CORE_COMP0_SHUT_DOWN_STATUS__POR (0x03) +#define MSM89XX_CDC_CORE_COMP0_FS_CFG (0xCC) +#define MSM89XX_CDC_CORE_COMP0_FS_CFG__POR (0x03) +#define MSM89XX_CDC_CORE_COMP0_DELAY_BUF_CTL (0xD0) +#define MSM89XX_CDC_CORE_COMP0_DELAY_BUF_CTL__POR (0x02) +#define MSM89XX_CDC_CORE_DEBUG_DESER1_CTL (0xE0) +#define MSM89XX_CDC_CORE_DEBUG_DESER1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_DEBUG_DESER2_CTL (0xE4) +#define MSM89XX_CDC_CORE_DEBUG_DESER2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_DEBUG_B1_CTL_CFG (0xE8) +#define MSM89XX_CDC_CORE_DEBUG_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_DEBUG_B2_CTL_CFG (0xEC) +#define MSM89XX_CDC_CORE_DEBUG_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_DEBUG_B3_CTL_CFG (0xF0) +#define MSM89XX_CDC_CORE_DEBUG_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL (0x100) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL (0x140) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL (0x104) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B2_CTL (0x144) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL (0x108) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B3_CTL (0x148) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL (0x10C) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B4_CTL (0x14C) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B4_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B5_CTL (0x110) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B5_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B5_CTL (0x150) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B5_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B6_CTL (0x114) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B6_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B6_CTL (0x154) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B6_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B7_CTL (0x118) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B7_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B7_CTL (0x158) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B7_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B8_CTL (0x11C) +#define MSM89XX_CDC_CORE_IIR1_GAIN_B8_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B8_CTL (0x15C) +#define MSM89XX_CDC_CORE_IIR2_GAIN_B8_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_CTL (0x120) +#define MSM89XX_CDC_CORE_IIR1_CTL__POR (0x40) +#define MSM89XX_CDC_CORE_IIR2_CTL (0x160) +#define MSM89XX_CDC_CORE_IIR2_CTL__POR (0x40) +#define MSM89XX_CDC_CORE_IIR1_GAIN_TIMER_CTL (0x124) +#define MSM89XX_CDC_CORE_IIR1_GAIN_TIMER_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_GAIN_TIMER_CTL (0x164) +#define MSM89XX_CDC_CORE_IIR2_GAIN_TIMER_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL (0x128) +#define MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL (0x168) +#define MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL (0x12C) +#define MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_IIR2_COEF_B2_CTL (0x16C) +#define MSM89XX_CDC_CORE_IIR2_COEF_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_RX1_B1_CTL (0x180) +#define MSM89XX_CDC_CORE_CONN_RX1_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_RX1_B2_CTL (0x184) +#define MSM89XX_CDC_CORE_CONN_RX1_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_RX1_B3_CTL (0x188) +#define MSM89XX_CDC_CORE_CONN_RX1_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_RX2_B1_CTL (0x18C) +#define MSM89XX_CDC_CORE_CONN_RX2_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_RX2_B2_CTL (0x190) +#define MSM89XX_CDC_CORE_CONN_RX2_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_RX2_B3_CTL (0x194) +#define MSM89XX_CDC_CORE_CONN_RX2_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_RX3_B1_CTL (0x198) +#define MSM89XX_CDC_CORE_CONN_RX3_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_RX3_B2_CTL (0x19C) +#define MSM89XX_CDC_CORE_CONN_RX3_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_TX_B1_CTL (0x1A0) +#define MSM89XX_CDC_CORE_CONN_TX_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_TX_B2_CTL (0x1A4) +#define MSM89XX_CDC_CORE_CONN_TX_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL (0x1A8) +#define MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_EQ1_B2_CTL (0x1AC) +#define MSM89XX_CDC_CORE_CONN_EQ1_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_EQ1_B3_CTL (0x1B0) +#define MSM89XX_CDC_CORE_CONN_EQ1_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_EQ1_B4_CTL (0x1B4) +#define MSM89XX_CDC_CORE_CONN_EQ1_B4_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL (0x1B8) +#define MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_EQ2_B2_CTL (0x1BC) +#define MSM89XX_CDC_CORE_CONN_EQ2_B2_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_EQ2_B3_CTL (0x1C0) +#define MSM89XX_CDC_CORE_CONN_EQ2_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_EQ2_B4_CTL (0x1C4) +#define MSM89XX_CDC_CORE_CONN_EQ2_B4_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL (0x1C8) +#define MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_CONN_TX_B3_CTL (0x1CC) +#define MSM89XX_CDC_CORE_CONN_TX_B3_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX5_VOL_CTL_TIMER (0x1E0) +#define MSM89XX_CDC_CORE_TX5_VOL_CTL_TIMER__POR (0x00) +#define MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN (0x1E4) +#define MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN__POR (0x00) +#define MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG (0x1E8) +#define MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG__POR (0x00) +#define MSM89XX_CDC_CORE_TX5_MUX_CTL (0x1EC) +#define MSM89XX_CDC_CORE_TX5_MUX_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX5_CLK_FS_CTL (0x1F0) +#define MSM89XX_CDC_CORE_TX5_CLK_FS_CTL__POR (0x03) +#define MSM89XX_CDC_CORE_TX5_DMIC_CTL (0x1F4) +#define MSM89XX_CDC_CORE_TX5_DMIC_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX1_VOL_CTL_TIMER (0x280) +#define MSM89XX_CDC_CORE_TX1_VOL_CTL_TIMER__POR (0x00) +#define MSM89XX_CDC_CORE_TX2_VOL_CTL_TIMER (0x2A0) +#define MSM89XX_CDC_CORE_TX2_VOL_CTL_TIMER__POR (0x00) +#define MSM89XX_CDC_CORE_TX3_VOL_CTL_TIMER (0x2C0) +#define MSM89XX_CDC_CORE_TX3_VOL_CTL_TIMER__POR (0x00) +#define MSM89XX_CDC_CORE_TX4_VOL_CTL_TIMER (0x2E0) +#define MSM89XX_CDC_CORE_TX4_VOL_CTL_TIMER__POR (0x00) +#define MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN (0x284) +#define MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN__POR (0x00) +#define MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN (0x2A4) +#define MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN__POR (0x00) +#define MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN (0x2C4) +#define MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN__POR (0x00) +#define MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN (0x2E4) +#define MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN__POR (0x00) +#define MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG (0x288) +#define MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG__POR (0x00) +#define MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG (0x2A8) +#define MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG__POR (0x00) +#define MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG (0x2C8) +#define MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG__POR (0x00) +#define MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG (0x2E8) +#define MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG__POR (0x00) +#define MSM89XX_CDC_CORE_TX1_MUX_CTL (0x28C) +#define MSM89XX_CDC_CORE_TX1_MUX_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX2_MUX_CTL (0x2AC) +#define MSM89XX_CDC_CORE_TX2_MUX_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX3_MUX_CTL (0x2CC) +#define MSM89XX_CDC_CORE_TX3_MUX_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX4_MUX_CTL (0x2EC) +#define MSM89XX_CDC_CORE_TX4_MUX_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX1_CLK_FS_CTL (0x290) +#define MSM89XX_CDC_CORE_TX1_CLK_FS_CTL__POR (0x03) +#define MSM89XX_CDC_CORE_TX2_CLK_FS_CTL (0x2B0) +#define MSM89XX_CDC_CORE_TX2_CLK_FS_CTL__POR (0x03) +#define MSM89XX_CDC_CORE_TX3_CLK_FS_CTL (0x2D0) +#define MSM89XX_CDC_CORE_TX3_CLK_FS_CTL__POR (0x03) +#define MSM89XX_CDC_CORE_TX4_CLK_FS_CTL (0x2F0) +#define MSM89XX_CDC_CORE_TX4_CLK_FS_CTL__POR (0x03) +#define MSM89XX_CDC_CORE_TX1_DMIC_CTL (0x294) +#define MSM89XX_CDC_CORE_TX1_DMIC_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX2_DMIC_CTL (0x2B4) +#define MSM89XX_CDC_CORE_TX2_DMIC_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX3_DMIC_CTL (0x2D4) +#define MSM89XX_CDC_CORE_TX3_DMIC_CTL__POR (0x00) +#define MSM89XX_CDC_CORE_TX4_DMIC_CTL (0x2F4) +#define MSM89XX_CDC_CORE_TX4_DMIC_CTL__POR (0x00) + +#define MSM89XX_CDC_CORE_NUM_REGISTERS \ + (MSM89XX_CDC_CORE_TX4_DMIC_CTL+1) +#define MSM89XX_CDC_CORE_MAX_REGISTER \ + (MSM89XX_CDC_CORE_NUM_REGISTERS-1) +#define MSM89XX_CDC_CORE_CACHE_SIZE \ + MSM89XX_CDC_CORE_NUM_REGISTERS +#endif diff --git a/asoc/codecs/wcd9335-regmap.c b/asoc/codecs/wcd9335-regmap.c index 7b3363f08f1b..a9cd20f51426 100644 --- a/asoc/codecs/wcd9335-regmap.c +++ b/asoc/codecs/wcd9335-regmap.c @@ -1,13 +1,13 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018, 2020, The Linux Foundation. All rights reserved. */ #include #include #include #include -#include +#include "wcd9335_registers.h" static const struct reg_sequence wcd9335_1_x_defaults[] = { { WCD9335_CODEC_RPM_CLK_GATE, 0x03, 0x00 }, diff --git a/asoc/codecs/wcd934x/Android.mk b/asoc/codecs/wcd934x/Android.mk index f4fe33c27122..18170f404cb8 100644 --- a/asoc/codecs/wcd934x/Android.mk +++ b/asoc/codecs/wcd934x/Android.mk @@ -11,9 +11,13 @@ ifeq ($(call is-board-platform,$(MSMSTEPPE) $(TRINKET)),true) AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m endif +ifeq ($(call is-board-platform,sdm660),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM660=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) sdm660),true) LOCAL_PATH := $(call my-dir) diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index 63a75a770c23..d372ed762cef 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -36,6 +36,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif + ifeq ($(CONFIG_ARCH_SDM660), y) + include $(AUDIO_ROOT)/config/sdm660auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 50c83fa76b1a..49f164c9d9ff 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019, 2020, The Linux Foundation. All rights reserved. */ #include #include @@ -10354,7 +10354,7 @@ static int tavil_post_reset_cb(struct wcd9xxx *wcd9xxx) component = (struct snd_soc_component *)(wcd9xxx->ssr_priv); if (!component->card) { - dev_err(codec->dev, "%s: sound card is not enumerated.\n", + dev_err(component->dev, "%s: sound card is not enumerated.\n", __func__); return -EINVAL; } diff --git a/asoc/codecs/wcd9xxx-utils.h b/asoc/codecs/wcd9xxx-utils.h index 1e063abfb5f5..9d4bf0fc6d31 100644 --- a/asoc/codecs/wcd9xxx-utils.h +++ b/asoc/codecs/wcd9xxx-utils.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. */ #ifndef __WCD9XXX_UTILS_H__ @@ -8,8 +8,8 @@ #include #include #include -#include "pdata.h" -#include "core.h" +#include +#include struct wcd9xxx_pdata *wcd9xxx_populate_dt_data(struct device *dev); int wcd9xxx_bringup(struct device *dev); diff --git a/asoc/msm-cpe-lsm.c b/asoc/msm-cpe-lsm.c index 7765554cb3d9..0f98192a083e 100644 --- a/asoc/msm-cpe-lsm.c +++ b/asoc/msm-cpe-lsm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019, 2020, The Linux Foundation. All rights reserved. */ #include @@ -18,7 +18,7 @@ #include #include #include "msm-slim-dma.h" -#include "codecs/cpe_core.h" +#include #define DRV_NAME "msm-cpe-lsm" diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c new file mode 100644 index 000000000000..b89d1c8e73df --- /dev/null +++ b/asoc/sdm660-common.c @@ -0,0 +1,5583 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm-pcm-routing-v2.h" +#include +#include +#include +#include +#include "codecs/sdm660_cdc/msm-analog-cdc.h" +#include "codecs/wsa881x.h" + +#define __CHIPSET__ "SDM660 " +#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) + +#define DRV_NAME "sdm660-asoc-snd" + +#define MSM_INT_DIGITAL_CODEC "msm-dig-codec" +#define PMIC_INT_ANALOG_CODEC "analog-codec" + +#define DEV_NAME_STR_LEN 32 +#define DEFAULT_MCLK_RATE 9600000 +#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ + +enum { + DP_RX_IDX, + EXT_DISP_RX_IDX_MAX, +}; + +bool codec_reg_done; + +enum { + STATUS_PORT_STARTED, /* track if AFE port has started */ + /* track AFE Tx port status for bi-directional transfers */ + STATUS_TX_PORT, + /* track AFE Rx port status for bi-directional transfers */ + STATUS_RX_PORT, + STATUS_MAX +}; + +struct tdm_dai_data { + DECLARE_BITMAP(status_mask, STATUS_MAX); + u32 rate; + u32 channels; + u32 bitwidth; + u32 num_group_ports; + u32 is_island_dai; + struct afe_clk_set clk_set; /* hold LPASS clock config. */ + union afe_port_group_config group_cfg; /* hold tdm group config */ + struct afe_tdm_port_config port_cfg; /* hold tdm config */ +}; + +/* TDM default config */ +static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUIN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + } +}; + +/* TDM default config */ +static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUIN TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + } +}; + +/* Default configuration of external display BE */ +static struct dev_config ext_disp_rx_cfg[] = { + [DP_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; +static struct dev_config usb_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +static struct dev_config usb_tx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 1, +}; + +enum { + PRIM_AUX_PCM = 0, + SEC_AUX_PCM, + TERT_AUX_PCM, + QUAT_AUX_PCM, + QUIN_AUX_PCM, + AUX_PCM_MAX, +}; + +enum { + PCM_I2S_SEL_PRIM = 0, + PCM_I2S_SEL_SEC, + PCM_I2S_SEL_TERT, + PCM_I2S_SEL_QUAT, + PCM_I2S_SEL_QUIN, + PCM_I2S_SEL_MAX, +}; + +struct mi2s_conf { + struct mutex lock; + u32 ref_cnt; + u32 msm_is_mi2s_master; + u32 msm_is_ext_mclk; +}; + +static u32 mi2s_ebit_clk[MI2S_MAX] = { + Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT +}; + +struct msm_wsa881x_dev_info { + struct device_node *of_node; + u32 index; +}; +static struct snd_soc_aux_dev *msm_aux_dev; +static struct snd_soc_codec_conf *msm_codec_conf; + +static bool msm_swap_gnd_mic(struct snd_soc_component *component, bool active); + +static struct wcd_mbhc_config mbhc_cfg = { + .read_fw_bin = false, + .calibration = NULL, + .detect_extn_cable = true, + .mono_stero_detection = false, + .swap_gnd_mic = NULL, + .hs_ext_micbias = true, + .key_code[0] = KEY_MEDIA, + .key_code[1] = KEY_VOICECOMMAND, + .key_code[2] = KEY_VOLUMEUP, + .key_code[3] = KEY_VOLUMEDOWN, + .key_code[4] = 0, + .key_code[5] = 0, + .key_code[6] = 0, + .key_code[7] = 0, + .linein_th = 5000, + .moisture_en = false, + .mbhc_micbias = 0, + .anc_micbias = 0, + .enable_anc_mic_detect = false, +}; + +static struct dev_config proxy_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +/* Default configuration of MI2S channels */ +static struct dev_config mi2s_rx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config mi2s_tx_cfg[] = { + [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_rx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config aux_pcm_tx_cfg[] = { + [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static char const *ch_text[] = {"Two", "Three", "Four", "Five", + "Six", "Seven", "Eight"}; +static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"}; +static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_96", "KHZ_192"}; +static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; +static char const *mi2s_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; +static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", "Eight", + "Nine", "Ten", "Eleven", "Twelve", + "Thirteen", "Fourteen", "Fifteen", + "Sixteen"}; +static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; +static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", + "KHZ_44P1", "KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static const char *const tdm_slot_num_text[] = {"One", "Two", "Four", + "Eight", "Sixteen", "ThirtyTwo"}; +static const char *const tdm_slot_width_text[] = {"16", "24", "32"}; +static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_96", "KHZ_192", "KHZ_384"}; +static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE"}; +static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96", + "KHZ_192"}; +static const char *const qos_text[] = {"Disable", "Enable"}; + +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_rx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_tx_sample_rate, auxpcm_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_sample_rate, mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_format, mi2s_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate, + ext_disp_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_slot_num, tdm_slot_num_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_slot_width, tdm_slot_width_text); +static SOC_ENUM_SINGLE_EXT_DECL(qos_vote, qos_text); + +static int qos_vote_status; + +static struct afe_clk_set mi2s_clk[MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + } +}; + +static struct afe_clk_set mi2s_mclk[MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_MCLK_3, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_MCLK_2, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_MCLK_1, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_MCLK_1, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + } +}; + +static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; + +/* TDM default slot config */ +struct tdm_slot_cfg { + u32 width; + u32 num; +}; + +static struct tdm_slot_cfg tdm_slot[TDM_INTERFACE_MAX] = { + /* PRI TDM */ + {32, 8}, + /* SEC TDM */ + {32, 8}, + /* TERT TDM */ + {32, 8}, + /* QUAT TDM */ + {32, 8}, + /* QUIN TDM */ + {32, 8} +}; + +static unsigned int tdm_rx_slot_offset + [TDM_INTERFACE_MAX][TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { + {/* PRI TDM */ + {0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* SEC TDM */ + {0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* TERT TDM */ + {0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUAT TDM */ + {0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUIN TDM */ + {0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + } +}; + +static unsigned int tdm_tx_slot_offset + [TDM_INTERFACE_MAX][TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { + {/* PRI TDM */ + {0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* SEC TDM */ + {0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* TERT TDM */ + {0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUAT TDM */ + {0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*MIC ARR*/ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + }, + {/* QUIN TDM */ + {0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + } +}; +static unsigned int tdm_param_set_slot_mask(int slots) +{ + unsigned int slot_mask = 0; + int i = 0; + + if ((slots <= 0) || (slots > 32)) { + pr_err("%s: invalid slot number %d\n", __func__, slots); + return -EINVAL; + } + + for (i = 0; i < slots ; i++) + slot_mask |= 1 << i; + + return slot_mask; +} + +int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + int channels, slot_width, slots, rate, format; + unsigned int slot_mask; + unsigned int *slot_offset; + int offset_channels = 0; + int i; + int clk_freq; + + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + + channels = params_channels(params); + if (channels < 1 || channels > 32) { + pr_err("%s: invalid param channels %d\n", + __func__, channels); + return -EINVAL; + } + + format = params_format(params); + if (format != SNDRV_PCM_FORMAT_S32_LE && + format != SNDRV_PCM_FORMAT_S24_LE && + format != SNDRV_PCM_FORMAT_S16_LE) { + /* + * up to 8 channels HW config should + * use 32 bit slot width for max support of + * stream bit width. (slot_width > bit_width) + */ + pr_err("%s: invalid param format 0x%x\n", + __func__, format); + return -EINVAL; + } + + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_0]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_1]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_2]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_3]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_4]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_5]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_6]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_7]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_0]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_1]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_2]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_3]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_4]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_5]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_6]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + slots = tdm_slot[TDM_PRI].num; + slot_width = tdm_slot[TDM_PRI].width; + slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_7]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_0]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_1]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_2]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_3]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_4]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_5]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_6]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_7]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_0]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_1]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_2]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_3]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_4]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_5]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_6]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + slots = tdm_slot[TDM_SEC].num; + slot_width = tdm_slot[TDM_SEC].width; + slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_7]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_0]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_1]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_2]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_3]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_4]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_5]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_6]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_7]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_0]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_1]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_2]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_3]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_4]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_5]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_6]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + slots = tdm_slot[TDM_TERT].num; + slot_width = tdm_slot[TDM_TERT].width; + slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_7]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_0]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_1]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_2]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_3]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_4]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_5]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_6]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_7]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_0]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_1]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_2]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_3]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_4]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_5]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_6]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + slots = tdm_slot[TDM_QUAT].num; + slot_width = tdm_slot[TDM_QUAT].width; + slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_7]; + break; + case AFE_PORT_ID_QUINARY_TDM_RX: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_0]; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_1: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_1]; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_2: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_2]; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_3: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_3]; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_4: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_4]; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_5: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_5]; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_6: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_6]; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_7: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_7]; + break; + case AFE_PORT_ID_QUINARY_TDM_TX: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_0]; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_1: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_1]; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_2: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_2]; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_3: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_3]; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_4: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_4]; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_5: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_5]; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_6: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_6]; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_7: + slots = tdm_slot[TDM_QUIN].num; + slot_width = tdm_slot[TDM_QUIN].width; + slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_7]; + break; + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) + offset_channels++; + else + break; + } + + if (offset_channels == 0) { + pr_err("%s: slot offset not supported, offset_channels %d\n", + __func__, offset_channels); + return -EINVAL; + } + + if (channels > offset_channels) { + pr_err("%s: channels %d exceed offset_channels %d\n", + __func__, channels, offset_channels); + return -EINVAL; + } + + slot_mask = tdm_param_set_slot_mask(slots); + if (!slot_mask) { + pr_err("%s: invalid slot_mask 0x%x\n", + __func__, slot_mask); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + pr_debug("%s: slot_width %d\n", __func__, slot_width); + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, + channels, slot_offset); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, channels, + slot_offset, 0, NULL); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } else { + ret = -EINVAL; + pr_err("%s: invalid use case, err:%d\n", + __func__, ret); + goto end; + } + + rate = params_rate(params); + clk_freq = rate * slot_width * slots; + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, clk_freq, SND_SOC_CLOCK_OUT); + if (ret < 0) { + pr_err("%s: failed to set tdm clk, err:%d\n", + __func__, ret); + } + +end: + return ret; +} +EXPORT_SYMBOL(msm_tdm_snd_hw_params); + +static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2; + + return 0; +} + +static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2; + pr_debug("%s: proxy_rx channels = %d\n", + __func__, proxy_rx_cfg.channels); + + return 1; +} + +static int tdm_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_384KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int tdm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 8; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int tdm_get_mode(struct snd_kcontrol *kcontrol) +{ + int mode; + + if (strnstr(kcontrol->id.name, "PRI", + sizeof(kcontrol->id.name))) { + mode = TDM_PRI; + } else if (strnstr(kcontrol->id.name, "SEC", + sizeof(kcontrol->id.name))) { + mode = TDM_SEC; + } else if (strnstr(kcontrol->id.name, "TERT", + sizeof(kcontrol->id.name))) { + mode = TDM_TERT; + } else if (strnstr(kcontrol->id.name, "QUAT", + sizeof(kcontrol->id.name))) { + mode = TDM_QUAT; + } else if (strnstr(kcontrol->id.name, "QUIN", + sizeof(kcontrol->id.name))) { + mode = TDM_QUIN; + } else { + pr_err("%s: unsupported mode in: %s\n", + __func__, kcontrol->id.name); + mode = -EINVAL; + } + + return mode; +} + +static int tdm_get_channel(struct snd_kcontrol *kcontrol) +{ + int channel; + + if (strnstr(kcontrol->id.name, "RX_0", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_0", + sizeof(kcontrol->id.name))) { + channel = TDM_0; + } else if (strnstr(kcontrol->id.name, "RX_1", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_1", + sizeof(kcontrol->id.name))) { + channel = TDM_1; + } else if (strnstr(kcontrol->id.name, "RX_2", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_2", + sizeof(kcontrol->id.name))) { + channel = TDM_2; + } else if (strnstr(kcontrol->id.name, "RX_3", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_3", + sizeof(kcontrol->id.name))) { + channel = TDM_3; + } else if (strnstr(kcontrol->id.name, "RX_4", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_4", + sizeof(kcontrol->id.name))) { + channel = TDM_4; + } else if (strnstr(kcontrol->id.name, "RX_5", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_5", + sizeof(kcontrol->id.name))) { + channel = TDM_5; + } else if (strnstr(kcontrol->id.name, "RX_6", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_6", + sizeof(kcontrol->id.name))) { + channel = TDM_6; + } else if (strnstr(kcontrol->id.name, "RX_7", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_7", + sizeof(kcontrol->id.name))) { + channel = TDM_7; + } else { + pr_err("%s: unsupported channel in: %s\n", + __func__, kcontrol->id.name); + channel = -EINVAL; + } + + return channel; +} + +static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, + struct tdm_port *port) +{ + if (port) { + port->mode = tdm_get_mode(kcontrol); + if (port->mode < 0) + return port->mode; + + port->channel = tdm_get_channel(kcontrol); + if (port->channel < 0) + return port->channel; + } else + return -EINVAL; + + return 0; +} + +static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_rx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_tx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_get_format(int value) +{ + int format = 0; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int tdm_get_format_val(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 2; + break; + default: + value = 0; + break; + } + return value; +} + +static int mi2s_get_format(int value) +{ + int format = 0; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int mi2s_get_format_value(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + value = 2; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 3; + break; + default: + value = 0; + break; + } + return value; +} + +static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_rx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_tx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + + ucontrol->value.enumerated.item[0] = + tdm_rx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = + tdm_tx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int tdm_get_slot_num_val(int slot_num) +{ + int slot_num_val; + + switch (slot_num) { + case 1: + slot_num_val = 0; + break; + case 2: + slot_num_val = 1; + break; + case 4: + slot_num_val = 2; + break; + case 8: + slot_num_val = 3; + break; + case 16: + slot_num_val = 4; + break; + case 32: + slot_num_val = 5; + break; + default: + slot_num_val = 5; + break; + } + return slot_num_val; +} + +static int tdm_slot_num_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int mode = tdm_get_mode(kcontrol); + + if (mode < 0) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + return mode; + } + + ucontrol->value.enumerated.item[0] = + tdm_get_slot_num_val(tdm_slot[mode].num); + + pr_debug("%s: mode = %d, tdm_slot_num = %d, item = %d\n", __func__, + mode, tdm_slot[mode].num, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int tdm_get_slot_num(int value) +{ + int slot_num; + + switch (value) { + case 0: + slot_num = 1; + break; + case 1: + slot_num = 2; + break; + case 2: + slot_num = 4; + break; + case 3: + slot_num = 8; + break; + case 4: + slot_num = 16; + break; + case 5: + slot_num = 32; + break; + default: + slot_num = 8; + break; + } + return slot_num; +} + +static int tdm_slot_num_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int mode = tdm_get_mode(kcontrol); + + if (mode < 0) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + return mode; + } + + tdm_slot[mode].num = + tdm_get_slot_num(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: mode = %d, tdm_slot_num = %d, item = %d\n", __func__, + mode, tdm_slot[mode].num, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int tdm_get_slot_width_val(int slot_width) +{ + int slot_width_val; + + switch (slot_width) { + case 16: + slot_width_val = 0; + break; + case 24: + slot_width_val = 1; + break; + case 32: + slot_width_val = 2; + break; + default: + slot_width_val = 2; + break; + } + return slot_width_val; +} + +static int tdm_slot_width_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int mode = tdm_get_mode(kcontrol); + + if (mode < 0) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + return mode; + } + + ucontrol->value.enumerated.item[0] = + tdm_get_slot_width_val(tdm_slot[mode].width); + + pr_debug("%s: mode = %d, tdm_slot_width = %d, item = %d\n", __func__, + mode, tdm_slot[mode].width, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int tdm_get_slot_width(int value) +{ + int slot_width; + + switch (value) { + case 0: + slot_width = 16; + break; + case 1: + slot_width = 24; + break; + case 2: + slot_width = 32; + break; + default: + slot_width = 32; + break; + } + return slot_width; +} + +static int tdm_slot_width_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int mode = tdm_get_mode(kcontrol); + + if (mode < 0) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + return mode; + } + + tdm_slot[mode].width = + tdm_get_slot_width(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: mode = %d, tdm_slot_width = %d, item = %d\n", __func__, + mode, tdm_slot[mode].width, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int tdm_rx_slot_mapping_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int *slot_offset; + int i; + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + if (port.mode < TDM_INTERFACE_MAX && + port.channel < TDM_PORT_MAX) { + slot_offset = + tdm_rx_slot_offset[port.mode][port.channel]; + pr_debug("%s: mode = %d, channel = %d\n", + __func__, port.mode, port.channel); + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + ucontrol->value.integer.value[i] = + slot_offset[i]; + pr_debug("%s: offset %d, value %d\n", + __func__, i, slot_offset[i]); + } + } else { + pr_err("%s: unsupported mode/channel\n", __func__); + } + } + return ret; +} + +static int tdm_rx_slot_mapping_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int *slot_offset; + int i; + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + if (port.mode < TDM_INTERFACE_MAX && + port.channel < TDM_PORT_MAX) { + slot_offset = + tdm_rx_slot_offset[port.mode][port.channel]; + pr_debug("%s: mode = %d, channel = %d\n", + __func__, port.mode, port.channel); + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + slot_offset[i] = + ucontrol->value.integer.value[i]; + pr_debug("%s: offset %d, value %d\n", + __func__, i, slot_offset[i]); + } + } else { + pr_err("%s: unsupported mode/channel\n", __func__); + } + } + return ret; +} + +static int tdm_tx_slot_mapping_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int *slot_offset; + int i; + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + if (port.mode < TDM_INTERFACE_MAX && + port.channel < TDM_PORT_MAX) { + slot_offset = + tdm_tx_slot_offset[port.mode][port.channel]; + pr_debug("%s: mode = %d, channel = %d\n", + __func__, port.mode, port.channel); + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + ucontrol->value.integer.value[i] = + slot_offset[i]; + pr_debug("%s: offset %d, value %d\n", + __func__, i, slot_offset[i]); + } + } else { + pr_err("%s: unsupported mode/channel\n", __func__); + } + } + return ret; +} + +static int tdm_tx_slot_mapping_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int *slot_offset; + int i; + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s\n", + __func__, kcontrol->id.name); + } else { + if (port.mode < TDM_INTERFACE_MAX && + port.channel < TDM_PORT_MAX) { + slot_offset = + tdm_tx_slot_offset[port.mode][port.channel]; + pr_debug("%s: mode = %d, channel = %d\n", + __func__, port.mode, port.channel); + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + slot_offset[i] = + ucontrol->value.integer.value[i]; + pr_debug("%s: offset %d, value %d\n", + __func__, i, slot_offset[i]); + } + } else { + pr_err("%s: unsupported mode/channel\n", __func__); + } + } + return ret; +} + +static int aux_pcm_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 0: + default: + sample_rate = SAMPLING_RATE_8KHZ; + break; + } + return sample_rate; +} + +static int aux_pcm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + return sample_rate_val; +} + +static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM", + sizeof("PRIM_AUX_PCM"))) + idx = PRIM_AUX_PCM; + else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM", + sizeof("SEC_AUX_PCM"))) + idx = SEC_AUX_PCM; + else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM", + sizeof("TERT_AUX_PCM"))) + idx = TERT_AUX_PCM; + else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM", + sizeof("QUAT_AUX_PCM"))) + idx = QUAT_AUX_PCM; + else if (strnstr(kcontrol->id.name, "QUIN_AUX_PCM", + sizeof("QUIN_AUX_PCM"))) + idx = QUIN_AUX_PCM; + else { + pr_err("%s: unsupported port: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_rx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + aux_pcm_tx_cfg[idx].sample_rate = + aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = aux_pcm_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, aux_pcm_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX", + sizeof("PRIM_MI2S_RX"))) + idx = PRIM_MI2S; + else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX", + sizeof("SEC_MI2S_RX"))) + idx = SEC_MI2S; + else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX", + sizeof("TERT_MI2S_RX"))) + idx = TERT_MI2S; + else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX", + sizeof("QUAT_MI2S_RX"))) + idx = QUAT_MI2S; + else if (strnstr(kcontrol->id.name, "QUIN_MI2S_RX", + sizeof("QUIN_MI2S_RX"))) + idx = QUIN_MI2S; + else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX", + sizeof("PRIM_MI2S_TX"))) + idx = PRIM_MI2S; + else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX", + sizeof("SEC_MI2S_TX"))) + idx = SEC_MI2S; + else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX", + sizeof("TERT_MI2S_TX"))) + idx = TERT_MI2S; + else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX", + sizeof("QUAT_MI2S_TX"))) + idx = QUAT_MI2S; + else if (strnstr(kcontrol->id.name, "QUIN_MI2S_TX", + sizeof("QUIN_MI2S_TX"))) + idx = QUIN_MI2S; + else { + pr_err("%s: unsupported channel: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int mi2s_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 6; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int mi2s_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_192KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].sample_rate = + mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].bit_format = + mi2s_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d] _tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_format_value(mi2s_tx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__, + idx, mi2s_tx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].bit_format = + mi2s_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d] _rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int mi2s_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + mi2s_get_format_value(mi2s_rx_cfg[idx].bit_format); + + pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__, + idx, mi2s_rx_cfg[idx].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, mi2s_rx_cfg[idx].channels); + + return 1; +} + +static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1; + + return 0; +} + +static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__, + idx, mi2s_tx_cfg[idx].channels); + + return 1; +} + +static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, + usb_rx_cfg.channels); + ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1; + return 0; +} + +static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels); + return 1; +} + +static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_rx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__, + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 9: + usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 8: + usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 7: + usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_rx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, + usb_tx_cfg.channels); + ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1; + return 0; +} + +static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels); + return 1; +} + +static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_tx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + default: + sample_rate_val = 6; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__, + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 9: + usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 8: + usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 7: + usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_tx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int idx; + + if (strnstr(kcontrol->id.name, "Display Port RX", + sizeof("Display Port RX"))) + idx = DP_RX_IDX; + else { + pr_err("%s: unsupported BE: %s", + __func__, kcontrol->id.name); + idx = -EINVAL; + } + + return idx; +} + +static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].bit_format) { + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 1: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n", + __func__, idx, ext_disp_rx_cfg[idx].bit_format, + ucontrol->value.integer.value[0]); + + return 0; +} + +static int ext_disp_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.integer.value[0] = + ext_disp_rx_cfg[idx].channels - 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + + return 0; +} + +static int ext_disp_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ext_disp_rx_cfg[idx].channels = + ucontrol->value.integer.value[0] + 2; + + pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].channels); + return 1; +} + +static int ext_disp_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ext_disp_rx_cfg[idx].sample_rate) { + case SAMPLING_RATE_192KHZ: + sample_rate_val = 2; + break; + + case SAMPLING_RATE_96KHZ: + sample_rate_val = 1; + break; + + case SAMPLING_RATE_48KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: ext_disp_rx[%d].sample_rate = %d\n", __func__, + idx, ext_disp_rx_cfg[idx].sample_rate); + + return 0; +} + +static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = ext_disp_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + switch (ucontrol->value.integer.value[0]) { + case 2: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ; + break; + case 1: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, ext_disp_rx[%d].sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], idx, + ext_disp_rx_cfg[idx].sample_rate); + return 0; +} + +static int msm_qos_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = qos_vote_status; + + return 0; +} + +static int msm_qos_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct snd_soc_card *card = component->card; + const char *fe_name = MSM_DAILINK_NAME(LowLatency); + struct snd_soc_pcm_runtime *rtd; + struct snd_pcm_substream *substream; + s32 usecs; + + rtd = snd_soc_get_pcm_runtime(card, fe_name); + if (!rtd) { + pr_err("%s: fail to get pcm runtime for %s\n", + __func__, fe_name); + return -EINVAL; + } + + substream = rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + if (!substream) { + pr_err("%s: substream is null\n", __func__); + return -EINVAL; + } + + qos_vote_status = ucontrol->value.enumerated.item[0]; + if (qos_vote_status) { + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + if (!substream->runtime) { + pr_err("%s: runtime is null\n", __func__); + return -EINVAL; + } + usecs = MSM_LL_QOS_VALUE; + if (usecs >= 0) + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, usecs); + } else { + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + } + + return 0; +} + +const struct snd_kcontrol_new msm_common_snd_controls[] = { + SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, + proxy_rx_ch_get, proxy_rx_ch_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_RX SampleRate", quin_aux_pcm_rx_sample_rate, + aux_pcm_rx_sample_rate_get, + aux_pcm_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_AUX_PCM_TX SampleRate", quin_aux_pcm_tx_sample_rate, + aux_pcm_tx_sample_rate_get, + aux_pcm_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_MI2S_RX SampleRate", quin_mi2s_rx_sample_rate, + mi2s_rx_sample_rate_get, + mi2s_rx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_MI2S_TX SampleRate", quin_mi2s_tx_sample_rate, + mi2s_tx_sample_rate_get, + mi2s_tx_sample_rate_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Format", prim_mi2s_rx_format, + mi2s_rx_format_get, + mi2s_rx_format_put), + SOC_ENUM_EXT("SEC_MI2S_RX Format", sec_mi2s_rx_format, + mi2s_rx_format_get, + mi2s_rx_format_put), + SOC_ENUM_EXT("TERT_MI2S_RX Format", tert_mi2s_rx_format, + mi2s_rx_format_get, + mi2s_rx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Format", quat_mi2s_rx_format, + mi2s_rx_format_get, + mi2s_rx_format_put), + SOC_ENUM_EXT("QUIN_MI2S_RX Format", quin_mi2s_rx_format, + mi2s_rx_format_get, + mi2s_rx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Format", prim_mi2s_tx_format, + mi2s_tx_format_get, + mi2s_tx_format_put), + SOC_ENUM_EXT("SEC_MI2S_TX Format", sec_mi2s_tx_format, + mi2s_tx_format_get, + mi2s_tx_format_put), + SOC_ENUM_EXT("TERT_MI2S_TX Format", tert_mi2s_tx_format, + mi2s_tx_format_get, + mi2s_tx_format_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Format", quat_mi2s_tx_format, + mi2s_tx_format_get, + mi2s_tx_format_put), + SOC_ENUM_EXT("QUIN_MI2S_TX Format", quin_mi2s_tx_format, + mi2s_tx_format_get, + mi2s_tx_format_put), + SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("QUIN_MI2S_RX Channels", quin_mi2s_rx_chs, + msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), + SOC_ENUM_EXT("QUIN_MI2S_TX Channels", quin_mi2s_tx_chs, + msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, + usb_audio_rx_ch_get, usb_audio_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, + usb_audio_tx_ch_get, usb_audio_tx_ch_put), + SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs, + ext_disp_rx_ch_get, ext_disp_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, + usb_audio_rx_format_get, usb_audio_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, + usb_audio_tx_format_get, usb_audio_tx_format_put), + SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format, + ext_disp_rx_format_get, ext_disp_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, + usb_audio_rx_sample_rate_get, + usb_audio_rx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, + usb_audio_tx_sample_rate_get, + usb_audio_tx_sample_rate_put), + SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate, + ext_disp_rx_sample_rate_get, + ext_disp_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUIN_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUIN_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("PRI_TDM SlotNumber", tdm_slot_num, + tdm_slot_num_get, tdm_slot_num_put), + SOC_ENUM_EXT("PRI_TDM SlotWidth", tdm_slot_width, + tdm_slot_width_get, tdm_slot_width_put), + SOC_ENUM_EXT("SEC_TDM SlotNumber", tdm_slot_num, + tdm_slot_num_get, tdm_slot_num_put), + SOC_ENUM_EXT("SEC_TDM SlotWidth", tdm_slot_width, + tdm_slot_width_get, tdm_slot_width_put), + SOC_ENUM_EXT("TERT_TDM SlotNumber", tdm_slot_num, + tdm_slot_num_get, tdm_slot_num_put), + SOC_ENUM_EXT("TERT_TDM SlotWidth", tdm_slot_width, + tdm_slot_width_get, tdm_slot_width_put), + SOC_ENUM_EXT("QUAT_TDM SlotNumber", tdm_slot_num, + tdm_slot_num_get, tdm_slot_num_put), + SOC_ENUM_EXT("QUAT_TDM SlotWidth", tdm_slot_width, + tdm_slot_width_get, tdm_slot_width_put), + SOC_ENUM_EXT("QUIN_TDM SlotNumber", tdm_slot_num, + tdm_slot_num_get, tdm_slot_num_put), + SOC_ENUM_EXT("QUIN_TDM SlotWidth", tdm_slot_width, + tdm_slot_width_get, tdm_slot_width_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_4 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_5 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_6 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_7 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_4 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_5 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_6 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_7 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_4 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_5 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_6 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_7 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_4 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_5 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_6 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_7 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_4 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_5 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_6 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_7 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_4 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_5 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_6 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_7 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_4 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_5 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_6 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_7 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_4 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_5 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_6 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_7 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_4 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_5 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_6 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_RX_7 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_rx_slot_mapping_get, tdm_rx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_0 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_1 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_2 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_3 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_4 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_5 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_6 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUIN_TDM_TX_7 SlotMapping", + SND_SOC_NOPM, 0, 0xFFFF, 0, TDM_SLOT_OFFSET_MAX, + tdm_tx_slot_mapping_get, tdm_tx_slot_mapping_put), + SOC_ENUM_EXT("MultiMedia5_RX QOS Vote", qos_vote, msm_qos_ctl_get, + msm_qos_ctl_put), +}; + +/** + * msm_common_snd_controls_size - to return controls size + * + * Return: returns size of common controls array + */ +int msm_common_snd_controls_size(void) +{ + return ARRAY_SIZE(msm_common_snd_controls); +} +EXPORT_SYMBOL(msm_common_snd_controls_size); + +void msm_set_codec_reg_done(bool done) +{ + codec_reg_done = done; +} +EXPORT_SYMBOL(msm_set_codec_reg_done); + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, + int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_1].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_PRI][TDM_1].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_2].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_PRI][TDM_2].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_3].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_PRI][TDM_3].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_4].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_4].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_PRI][TDM_4].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_5].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_5].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_PRI][TDM_5].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_6].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_6].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_PRI][TDM_6].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_7].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_PRI][TDM_7].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_1].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_PRI][TDM_1].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_2].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_PRI][TDM_2].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_3].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_PRI][TDM_3].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_4].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_4].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_PRI][TDM_4].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_5].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_5].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_PRI][TDM_5].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_6].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_6].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_PRI][TDM_6].sample_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_7].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_PRI][TDM_7].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_1].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_1].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_2].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_2].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_3].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_3].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_4].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_4].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_4].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_5].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_5].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_5].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_6].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_6].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_6].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_7].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_SEC][TDM_7].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_1].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_SEC][TDM_1].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_2].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_SEC][TDM_2].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_3].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_SEC][TDM_3].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_4].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_4].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_SEC][TDM_4].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_5].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_5].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_SEC][TDM_5].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_6].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_6].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_SEC][TDM_6].sample_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_7].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_SEC][TDM_7].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_1].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_1].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_2].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_2].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_3].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_3].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_4].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_4].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_4].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_5].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_5].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_5].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_6].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_6].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_6].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_7].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_TERT][TDM_7].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_1].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_1].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_2].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_2].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_3].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_3].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_4].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_4].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_4].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_5].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_5].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_5].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_6].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_6].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_6].sample_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_7].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_TERT][TDM_7].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_1].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_1].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_2].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_2].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_3].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_3].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_4].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_4].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_4].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_5].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_5].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_5].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_6].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_6].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_6].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_7].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUAT][TDM_7].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_1].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_1].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_2].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_2].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_3].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_3].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_4].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_4].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_4].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_5].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_5].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_5].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_6].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_6].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_6].sample_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_7].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUAT][TDM_7].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_RX: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_1: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_1].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_1].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_2: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_2].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_2].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_3: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_3].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_3].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_4: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_4].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_4].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_4].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_5: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_5].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_5].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_5].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_6: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_6].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_6].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_6].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_RX_7: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_7].bit_format); + rate->min = rate->max = + tdm_rx_cfg[TDM_QUIN][TDM_7].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_TX: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_1: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_1].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_1].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_1].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_2: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_2].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_2].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_2].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_3: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_3].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_3].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_3].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_4: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_4].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_4].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_4].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_5: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_5].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_5].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_5].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_6: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_6].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_6].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_6].sample_rate; + break; + case AFE_PORT_ID_QUINARY_TDM_TX_7: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_7].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_7].bit_format); + rate->min = rate->max = + tdm_tx_cfg[TDM_QUIN][TDM_7].sample_rate; + break; + + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n", + __func__, cpu_dai->id, channels->max, rate->max, + params_format(params)); + + return 0; +} +EXPORT_SYMBOL(msm_tdm_be_hw_params_fixup); + +static int msm_ext_disp_get_idx_from_beid(int32_t id) +{ + int idx; + + switch (id) { + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = DP_RX_IDX; + break; + default: + pr_err("%s: Incorrect ext_disp id %d\n", __func__, id); + idx = -EINVAL; + break; + } + + return idx; +} + +/** + * msm_common_be_hw_params_fixup - updates settings of ALSA BE hw params. + * + * @rtd: runtime dailink instance + * @params: HW params of associated backend dailink. + * + * Returns 0. + */ +int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int rc = 0; + int idx; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->id) { + case MSM_BACKEND_DAI_USB_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_rx_cfg.bit_format); + rate->min = rate->max = usb_rx_cfg.sample_rate; + channels->min = channels->max = usb_rx_cfg.channels; + break; + + case MSM_BACKEND_DAI_USB_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_tx_cfg.bit_format); + rate->min = rate->max = usb_tx_cfg.sample_rate; + channels->min = channels->max = usb_tx_cfg.channels; + break; + + case MSM_BACKEND_DAI_DISPLAY_PORT_RX: + idx = msm_ext_disp_get_idx_from_beid(dai_link->id); + if (idx < 0) { + pr_err("%s: Incorrect ext disp idx %d\n", + __func__, idx); + rc = idx; + break; + } + + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + ext_disp_rx_cfg[idx].bit_format); + rate->min = rate->max = ext_disp_rx_cfg[idx].sample_rate; + channels->min = channels->max = ext_disp_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_AFE_PCM_RX: + channels->min = channels->max = proxy_rx_cfg.channels; + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + + case MSM_BACKEND_DAI_PRI_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_PRI_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUIN_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUIN_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUIN][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUIN][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUIN][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[PRIM_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_SEC_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[SEC_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_TERT_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[TERT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUAT_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUAT_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUIN_AUXPCM_RX: + rate->min = rate->max = + aux_pcm_rx_cfg[QUIN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_rx_cfg[QUIN_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_QUIN_AUXPCM_TX: + rate->min = rate->max = + aux_pcm_tx_cfg[QUIN_AUX_PCM].sample_rate; + channels->min = channels->max = + aux_pcm_tx_cfg[QUIN_AUX_PCM].channels; + break; + + case MSM_BACKEND_DAI_PRI_MI2S_RX: + rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[PRIM_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[PRIM_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_PRI_MI2S_TX: + rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[PRIM_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[PRIM_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[SEC_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[SEC_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[SEC_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[SEC_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[TERT_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[TERT_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[TERT_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[TERT_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUAT_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUAT_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUAT_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUAT_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_QUINARY_MI2S_RX: + rate->min = rate->max = mi2s_rx_cfg[QUIN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_rx_cfg[QUIN_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_rx_cfg[QUIN_MI2S].bit_format); + break; + + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + rate->min = rate->max = mi2s_tx_cfg[QUIN_MI2S].sample_rate; + channels->min = channels->max = + mi2s_tx_cfg[QUIN_MI2S].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + mi2s_tx_cfg[QUIN_MI2S].bit_format); + break; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + return rc; +} +EXPORT_SYMBOL(msm_common_be_hw_params_fixup); + +/** + * msm_aux_pcm_snd_startup - startup ops of auxpcm. + * + * @substream: PCM stream pointer of associated backend dailink + * + * Returns 0 on success or -EINVAL on error. + */ +int msm_aux_pcm_snd_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + rtd->cpu_dai->name, rtd->cpu_dai->id); + + return 0; +} +EXPORT_SYMBOL(msm_aux_pcm_snd_startup); + +/** + * msm_aux_pcm_snd_shutdown - shutdown ops of auxpcm. + * + * @substream: PCM stream pointer of associated backend dailink + */ +void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, + substream->name, substream->stream, + rtd->cpu_dai->name, rtd->cpu_dai->id); +} +EXPORT_SYMBOL(msm_aux_pcm_snd_shutdown); + +static int msm_get_port_id(int id) +{ + int afe_port_id; + + switch (id) { + case MSM_BACKEND_DAI_PRI_MI2S_RX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_PRI_MI2S_TX: + afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_SECONDARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_TERTIARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; + break; + case MSM_BACKEND_DAI_QUINARY_MI2S_RX: + afe_port_id = AFE_PORT_ID_QUINARY_MI2S_RX; + break; + case MSM_BACKEND_DAI_QUINARY_MI2S_TX: + afe_port_id = AFE_PORT_ID_QUINARY_MI2S_TX; + break; + default: + pr_err("%s: Invalid id: %d\n", __func__, id); + afe_port_id = -EINVAL; + } + + return afe_port_id; +} + +static u32 get_mi2s_bits_per_sample(u32 bit_format) +{ + u32 bit_per_sample; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + case SNDRV_PCM_FORMAT_S24_LE: + bit_per_sample = 32; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bit_per_sample = 16; + break; + } + + return bit_per_sample; +} + +static void update_mi2s_clk_val(int dai_id, int stream) +{ + u32 bit_per_sample; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } else { + bit_per_sample = + get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format); + mi2s_clk[dai_id].clk_freq_in_hz = + mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample; + } +} + +static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int port_id = 0; + int index = cpu_dai->id; + + port_id = msm_get_port_id(rtd->dai_link->id); + if (port_id < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto done; + } + + if (enable) { + update_mi2s_clk_val(index, substream->stream); + dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, + mi2s_clk[index].clk_freq_in_hz); + } + + mi2s_clk[index].enable = enable; + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_clk[index]); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed for port 0x%x , err:%d\n", + __func__, port_id, ret); + goto done; + } + +done: + return ret; +} + +/** + * msm_mi2s_snd_startup - startup ops of mi2s. + * + * @substream: PCM stream pointer of associated backend dailink + * + * Returns 0 on success or -EINVAL on error. + */ +int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int port_id = msm_get_port_id(rtd->dai_link->id); + int index = cpu_dai->id; + unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); + + dev_dbg(rtd->card->dev, + "%s: substream = %s stream = %d, dai name %s, dai ID %d\n", + __func__, substream->name, substream->stream, + cpu_dai->name, cpu_dai->id); + + if (index < PRIM_MI2S || index >= MI2S_MAX) { + ret = -EINVAL; + dev_err(rtd->card->dev, + "%s: CPU DAI id (%d) out of range\n", + __func__, cpu_dai->id); + goto done; + } + /* + * Muxtex protection in case the same MI2S + * interface using for both TX and RX so + * that the same clock won't be enable twice. + */ + mutex_lock(&mi2s_intf_conf[index].lock); + if (++mi2s_intf_conf[index].ref_cnt == 1) { + /* Check if msm needs to provide the clock to the interface */ + if (!mi2s_intf_conf[index].msm_is_mi2s_master) { + mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; + fmt = SND_SOC_DAIFMT_CBM_CFM; + } + ret = msm_mi2s_set_sclk(substream, true); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed to enable MI2S clock, err:%d\n", + __func__, ret); + goto clean_up; + } + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: set fmt cpu dai failed for MI2S (%d), err:%d\n", + __func__, index, ret); + goto clk_off; + } + if (mi2s_intf_conf[index].msm_is_ext_mclk) { + mi2s_mclk[index].enable = 1; + pr_debug("%s: Enabling mclk, clk_freq_in_hz = %u\n", + __func__, mi2s_mclk[index].clk_freq_in_hz); + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_mclk[index]); + if (ret < 0) { + pr_err("%s: afe lpass mclk failed, err:%d\n", + __func__, ret); + goto clk_off; + } + } + if (pdata->mi2s_gpio_p[index]) + msm_cdc_pinctrl_select_active_state( + pdata->mi2s_gpio_p[index]); + } + mutex_unlock(&mi2s_intf_conf[index].lock); + return 0; +clk_off: + if (ret < 0) + msm_mi2s_set_sclk(substream, false); +clean_up: + if (ret < 0) + mi2s_intf_conf[index].ref_cnt--; + mutex_unlock(&mi2s_intf_conf[index].lock); +done: + return ret; +} +EXPORT_SYMBOL(msm_mi2s_snd_startup); + +/** + * msm_mi2s_snd_shutdown - shutdown ops of mi2s. + * + * @substream: PCM stream pointer of associated backend dailink + */ +void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int port_id = msm_get_port_id(rtd->dai_link->id); + int index = rtd->cpu_dai->id; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + if (index < PRIM_MI2S || index >= MI2S_MAX) { + pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index); + return; + } + + mutex_lock(&mi2s_intf_conf[index].lock); + if (--mi2s_intf_conf[index].ref_cnt == 0) { + if (pdata->mi2s_gpio_p[index]) + msm_cdc_pinctrl_select_sleep_state( + pdata->mi2s_gpio_p[index]); + + ret = msm_mi2s_set_sclk(substream, false); + if (ret < 0) + pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n", + __func__, index, ret); + + if (mi2s_intf_conf[index].msm_is_ext_mclk) { + mi2s_mclk[index].enable = 0; + pr_debug("%s: Disabling mclk, clk_freq_in_hz = %u\n", + __func__, mi2s_mclk[index].clk_freq_in_hz); + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_mclk[index]); + if (ret < 0) { + pr_err("%s: mclk disable failed for MCLK (%d); ret=%d\n", + __func__, index, ret); + } + } + } + mutex_unlock(&mi2s_intf_conf[index].lock); +} +EXPORT_SYMBOL(msm_mi2s_snd_shutdown); + +static int msm_get_tdm_mode(u32 port_id) +{ + int tdm_mode; + + switch (port_id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_TX: + tdm_mode = TDM_PRI; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_TX: + tdm_mode = TDM_SEC; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_TX: + tdm_mode = TDM_TERT; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + tdm_mode = TDM_QUAT; + break; + case AFE_PORT_ID_QUINARY_TDM_RX: + case AFE_PORT_ID_QUINARY_TDM_TX: + tdm_mode = TDM_QUIN; + break; + default: + pr_err("%s: Invalid port id: %d\n", __func__, port_id); + tdm_mode = -EINVAL; + } + return tdm_mode; +} + +int msm_tdm_snd_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct tdm_dai_data *dai_data = dev_get_drvdata(cpu_dai->dev); + int tdm_mode = msm_get_tdm_mode(cpu_dai->id); + + if (tdm_mode < 0) { + dev_err(rtd->card->dev, "%s: Invalid tdm_mode\n", __func__); + return tdm_mode; + } + dai_data->clk_set.enable = true; + ret = afe_set_lpass_clock_v2(cpu_dai->id, &dai_data->clk_set); + if (ret < 0) + pr_err("%s: afe lpass clock failed, err:%d\n", + __func__, ret); + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + if (pdata->mi2s_gpio_p[tdm_mode]) + ret = msm_cdc_pinctrl_select_active_state( + pdata->mi2s_gpio_p[tdm_mode]); + return ret; +} +EXPORT_SYMBOL(msm_tdm_snd_startup); + +void msm_tdm_snd_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_card *card = rtd->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct tdm_dai_data *dai_data = dev_get_drvdata(cpu_dai->dev); + int tdm_mode = msm_get_tdm_mode(cpu_dai->id); + int ret; + + if (tdm_mode < 0) { + dev_err(rtd->card->dev, "%s: Invalid tdm_mode\n", __func__); + return; + } + dai_data->clk_set.enable = false; + ret = afe_set_lpass_clock_v2(cpu_dai->id, &dai_data->clk_set); + if (ret < 0) + pr_err("%s: afe lpass clock failed, err:%d\n", __func__, ret); + + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + if (pdata->mi2s_gpio_p[tdm_mode]) + msm_cdc_pinctrl_select_sleep_state( + pdata->mi2s_gpio_p[tdm_mode]); +} +EXPORT_SYMBOL(msm_tdm_snd_shutdown); + +/* Validate whether US EU switch is present or not */ +static int msm_prepare_us_euro(struct snd_soc_card *card) +{ + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + int ret = 0; + + if (pdata->us_euro_gpio >= 0) { + dev_dbg(card->dev, "%s: us_euro gpio request %d", __func__, + pdata->us_euro_gpio); + ret = gpio_request(pdata->us_euro_gpio, "TASHA_CODEC_US_EURO"); + if (ret) { + dev_err(card->dev, + "%s: Failed to request codec US/EURO gpio %d error %d\n", + __func__, pdata->us_euro_gpio, ret); + } + } + + return ret; +} + + +static bool msm_usbc_swap_gnd_mic(struct snd_soc_component *component, + bool active) +{ + int value = 0; + bool ret = false; + struct snd_soc_card *card = component->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + struct pinctrl_state *en2_pinctrl_active; + struct pinctrl_state *en2_pinctrl_sleep; + + if (!pdata->usbc_en2_gpio_p) { + if (active) { + /* if active and usbc_en2_gpio undefined, get pin */ + pdata->usbc_en2_gpio_p = devm_pinctrl_get(card->dev); + if (IS_ERR_OR_NULL(pdata->usbc_en2_gpio_p)) { + dev_err(card->dev, + "%s: Can't get EN2 gpio pinctrl:%ld\n", + __func__, + PTR_ERR(pdata->usbc_en2_gpio_p)); + pdata->usbc_en2_gpio_p = NULL; + return false; + } + } else { + /* if not active and usbc_en2_gpio undefined, return */ + return false; + } + } + + pdata->usbc_en2_gpio = of_get_named_gpio(card->dev->of_node, + "qcom,usbc-analog-en2-gpio", 0); + if (!gpio_is_valid(pdata->usbc_en2_gpio)) { + dev_err(card->dev, "%s, property %s not in node %s\n", + __func__, "qcom,usbc-analog-en2-gpio", + card->dev->of_node->full_name); + return false; + } + + en2_pinctrl_active = pinctrl_lookup_state( + pdata->usbc_en2_gpio_p, "aud_active"); + if (IS_ERR_OR_NULL(en2_pinctrl_active)) { + dev_err(card->dev, + "%s: Cannot get aud_active pinctrl state:%ld\n", + __func__, PTR_ERR(en2_pinctrl_active)); + ret = false; + goto err_lookup_state; + } + + en2_pinctrl_sleep = pinctrl_lookup_state( + pdata->usbc_en2_gpio_p, "aud_sleep"); + if (IS_ERR_OR_NULL(en2_pinctrl_sleep)) { + dev_err(card->dev, + "%s: Cannot get aud_sleep pinctrl state:%ld\n", + __func__, PTR_ERR(en2_pinctrl_sleep)); + ret = false; + goto err_lookup_state; + } + + /* if active and usbc_en2_gpio_p defined, swap using usbc_en2_gpio_p */ + if (active) { + dev_dbg(component->dev, "%s: enter\n", __func__); + if (pdata->usbc_en2_gpio_p) { + value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); + if (value) + pinctrl_select_state(pdata->usbc_en2_gpio_p, + en2_pinctrl_sleep); + else + pinctrl_select_state(pdata->usbc_en2_gpio_p, + en2_pinctrl_active); + } else if (pdata->usbc_en2_gpio >= 0) { + value = gpio_get_value_cansleep(pdata->usbc_en2_gpio); + gpio_set_value_cansleep(pdata->usbc_en2_gpio, !value); + } + pr_debug("%s: swap select switch %d to %d\n", __func__, + value, !value); + ret = true; + } else { + /* if not active, release usbc_en2_gpio_p pin */ + pinctrl_select_state(pdata->usbc_en2_gpio_p, + en2_pinctrl_sleep); + } + +err_lookup_state: + devm_pinctrl_put(pdata->usbc_en2_gpio_p); + pdata->usbc_en2_gpio_p = NULL; + return ret; +} + +static bool msm_swap_gnd_mic(struct snd_soc_component *component, bool active) +{ + struct snd_soc_card *card = component->card; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(card); + int value = 0; + bool ret = 0; + + if (!mbhc_cfg.enable_usbc_analog) { + if (pdata->us_euro_gpio_p) { + value = msm_cdc_pinctrl_get_state( + pdata->us_euro_gpio_p); + if (value) + msm_cdc_pinctrl_select_sleep_state( + pdata->us_euro_gpio_p); + else + msm_cdc_pinctrl_select_active_state( + pdata->us_euro_gpio_p); + } else if (pdata->us_euro_gpio >= 0) { + value = gpio_get_value_cansleep(pdata->us_euro_gpio); + gpio_set_value_cansleep(pdata->us_euro_gpio, !value); + } + pr_debug("%s: swap select switch %d to %d\n", + __func__, value, !value); + ret = true; + } else { + /* if usbc is defined, swap using usbc_en2 */ + ret = msm_usbc_swap_gnd_mic(component, active); + } + return ret; +} + +static int msm_populate_dai_link_component_of_node( + struct msm_asoc_mach_data *pdata, + struct snd_soc_card *card) +{ + int i, index, ret = 0; + struct device *cdev = card->dev; + struct snd_soc_dai_link *dai_link = card->dai_link; + struct device_node *phandle; + + if (!cdev) { + pr_err("%s: Sound card device memory NULL\n", __func__); + return -ENODEV; + } + + for (i = 0; i < card->num_links; i++) { + if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node) + continue; + + /* populate platform_of_node for snd card dai links */ + if (dai_link[i].platform_name && + !dai_link[i].platform_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-platform-names", + dai_link[i].platform_name); + if (index < 0) { + pr_err("%s: No match found for platform name: %s\n", + __func__, dai_link[i].platform_name); + ret = index; + goto cpu_dai; + } + phandle = of_parse_phandle(cdev->of_node, + "asoc-platform", + index); + if (!phandle) { + pr_err("%s: retrieving phandle for platform %s, index %d failed\n", + __func__, dai_link[i].platform_name, + index); + ret = -ENODEV; + goto err; + } + dai_link[i].platform_of_node = phandle; + dai_link[i].platform_name = NULL; + } +cpu_dai: + /* populate cpu_of_node for snd card dai links */ + if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-cpu-names", + dai_link[i].cpu_dai_name); + if (index < 0) + goto codec_dai; + phandle = of_parse_phandle(cdev->of_node, "asoc-cpu", + index); + if (!phandle) { + pr_err("%s: retrieving phandle for cpu dai %s failed\n", + __func__, dai_link[i].cpu_dai_name); + ret = -ENODEV; + goto err; + } + dai_link[i].cpu_of_node = phandle; + dai_link[i].cpu_dai_name = NULL; + } +codec_dai: + /* populate codec_of_node for snd card dai links */ + if (dai_link[i].codec_name && !dai_link[i].codec_of_node) { + index = of_property_match_string(cdev->of_node, + "asoc-codec-names", + dai_link[i].codec_name); + if (index < 0) + continue; + phandle = of_parse_phandle(cdev->of_node, "asoc-codec", + index); + if (!phandle) { + pr_err("%s: retrieving phandle for codec dai %s failed\n", + __func__, dai_link[i].codec_name); + ret = -ENODEV; + goto err; + } + dai_link[i].codec_of_node = phandle; + dai_link[i].codec_name = NULL; + } + if (pdata->snd_card_val == INT_SND_CARD) { + if ((dai_link[i].id == + MSM_BACKEND_DAI_INT0_MI2S_RX) || + (dai_link[i].id == + MSM_BACKEND_DAI_INT1_MI2S_RX) || + (dai_link[i].id == + MSM_BACKEND_DAI_INT2_MI2S_TX) || + (dai_link[i].id == + MSM_BACKEND_DAI_INT3_MI2S_TX)) { + index = of_property_match_string(cdev->of_node, + "asoc-codec-names", + MSM_INT_DIGITAL_CODEC); + phandle = of_parse_phandle(cdev->of_node, + "asoc-codec", + index); + dai_link[i].codecs[DIG_CDC].of_node = phandle; + index = of_property_match_string(cdev->of_node, + "asoc-codec-names", + PMIC_INT_ANALOG_CODEC); + phandle = of_parse_phandle(cdev->of_node, + "asoc-codec", + index); + dai_link[i].codecs[ANA_CDC].of_node = phandle; + } + } + } +err: + return ret; +} + +static int msm_wsa881x_init(struct snd_soc_component *component) +{ + u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106}; + u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107}; + unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200}; + unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3}; + struct msm_asoc_mach_data *pdata; + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); + + if (!component) { + pr_err("%s codec is NULL\n", __func__); + return -EINVAL; + } + + if (!strcmp(component->name_prefix, "SpkrLeft")) { + dev_dbg(component->dev, "%s: setting left ch map to codec %s\n", + __func__, component->name); + wsa881x_set_channel_map(component, &spkleft_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0], NULL); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR"); + } + } else if (!strcmp(component->name_prefix, "SpkrRight")) { + dev_dbg(component->dev, "%s: setting right ch map to codec %s\n", + __func__, component->name); + wsa881x_set_channel_map(component, &spkright_ports[0], + WSA881X_MAX_SWR_PORTS, &ch_mask[0], + &ch_rate[0], NULL); + if (dapm->component) { + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN"); + snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR"); + } + } else { + dev_err(component->dev, "%s: wrong codec name %s\n", __func__, + component->name); + return -EINVAL; + } + + + pdata = snd_soc_card_get_drvdata(component->card); + if (pdata && pdata->codec_root) + wsa881x_codec_info_create_codec_entry(pdata->codec_root, + component); + return 0; +} + + +static int msm_init_wsa_dev(struct platform_device *pdev, + struct snd_soc_card *card) +{ + struct device_node *wsa_of_node; + u32 wsa_max_devs; + u32 wsa_dev_cnt; + char *dev_name_str = NULL; + struct msm_wsa881x_dev_info *wsa881x_dev_info; + const char *wsa_auxdev_name_prefix[1]; + int found = 0; + int i; + int ret; + + /* Get maximum WSA device count for this platform */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,wsa-max-devs", &wsa_max_devs); + if (ret) { + dev_dbg(&pdev->dev, + "%s: wsa-max-devs property missing in DT %s, ret = %d\n", + __func__, pdev->dev.of_node->full_name, ret); + goto err_dt; + } + if (wsa_max_devs == 0) { + dev_warn(&pdev->dev, + "%s: Max WSA devices is 0 for this target?\n", + __func__); + goto err_dt; + } + + /* Get count of WSA device phandles for this platform */ + wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node, + "qcom,wsa-devs", NULL); + if (wsa_dev_cnt == -ENOENT) { + dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n", + __func__); + goto err_dt; + } else if (wsa_dev_cnt <= 0) { + dev_err(&pdev->dev, + "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n", + __func__, wsa_dev_cnt); + ret = -EINVAL; + goto err_dt; + } + + /* + * Expect total phandles count to be NOT less than maximum possible + * WSA count. However, if it is less, then assign same value to + * max count as well. + */ + if (wsa_dev_cnt < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n", + __func__, wsa_max_devs, wsa_dev_cnt); + wsa_max_devs = wsa_dev_cnt; + } + + /* Make sure prefix string passed for each WSA device */ + ret = of_property_count_strings(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix"); + if (ret != wsa_dev_cnt) { + dev_err(&pdev->dev, + "%s: expecting %d wsa prefix. Defined only %d in DT\n", + __func__, wsa_dev_cnt, ret); + ret = -EINVAL; + goto err_dt; + } + + /* + * Alloc mem to store phandle and index info of WSA device, if already + * registered with ALSA core + */ + wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs, + sizeof(struct msm_wsa881x_dev_info), + GFP_KERNEL); + if (!wsa881x_dev_info) { + ret = -ENOMEM; + goto err_mem; + } + + /* + * search and check whether all WSA devices are already + * registered with ALSA core or not. If found a node, store + * the node and the index in a local array of struct for later + * use. + */ + for (i = 0; i < wsa_dev_cnt; i++) { + wsa_of_node = of_parse_phandle(pdev->dev.of_node, + "qcom,wsa-devs", i); + if (unlikely(!wsa_of_node)) { + /* we should not be here */ + dev_err(&pdev->dev, + "%s: wsa dev node is not present\n", + __func__); + ret = -EINVAL; + goto err_dev_node; + } + if (soc_find_component(wsa_of_node, NULL)) { + /* WSA device registered with ALSA core */ + wsa881x_dev_info[found].of_node = wsa_of_node; + wsa881x_dev_info[found].index = i; + found++; + if (found == wsa_max_devs) + break; + } + } + + if (found < wsa_max_devs) { + dev_dbg(&pdev->dev, + "%s: failed to find %d components. Found only %d\n", + __func__, wsa_max_devs, found); + return -EPROBE_DEFER; + } + dev_info(&pdev->dev, + "%s: found %d wsa881x devices registered with ALSA core\n", + __func__, found); + + card->num_aux_devs = wsa_max_devs; + card->num_configs = wsa_max_devs; + + /* Alloc array of AUX devs struct */ + msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_aux_dev), + GFP_KERNEL); + if (!msm_aux_dev) { + ret = -ENOMEM; + goto err_auxdev_mem; + } + + /* Alloc array of codec conf struct */ + msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs, + sizeof(struct snd_soc_codec_conf), + GFP_KERNEL); + if (!msm_codec_conf) { + ret = -ENOMEM; + goto err_codec_conf; + } + + for (i = 0; i < card->num_aux_devs; i++) { + dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN, + GFP_KERNEL); + if (!dev_name_str) { + ret = -ENOMEM; + goto err_dev_str; + } + + ret = of_property_read_string_index(pdev->dev.of_node, + "qcom,wsa-aux-dev-prefix", + wsa881x_dev_info[i].index, + wsa_auxdev_name_prefix); + if (ret) { + dev_err(&pdev->dev, + "%s: failed to read wsa aux dev prefix, ret = %d\n", + __func__, ret); + ret = -EINVAL; + goto err_dt_prop; + } + + snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i); + msm_aux_dev[i].name = dev_name_str; + msm_aux_dev[i].codec_name = NULL; + msm_aux_dev[i].codec_of_node = + wsa881x_dev_info[i].of_node; + msm_aux_dev[i].init = msm_wsa881x_init; + msm_codec_conf[i].dev_name = NULL; + msm_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0]; + msm_codec_conf[i].of_node = wsa881x_dev_info[i].of_node; + } + card->codec_conf = msm_codec_conf; + card->aux_dev = msm_aux_dev; + return 0; + +err_dt_prop: + devm_kfree(&pdev->dev, dev_name_str); +err_dev_str: + devm_kfree(&pdev->dev, msm_codec_conf); +err_codec_conf: + devm_kfree(&pdev->dev, msm_aux_dev); +err_auxdev_mem: +err_dev_node: + devm_kfree(&pdev->dev, wsa881x_dev_info); +err_mem: +err_dt: + return ret; +} + +static void i2s_auxpcm_init(struct platform_device *pdev) +{ + int count; + u32 mi2s_master_slave[MI2S_MAX]; + u32 mi2s_ext_mclk[MI2S_MAX]; + int ret; + + for (count = 0; count < MI2S_MAX; count++) { + mutex_init(&mi2s_intf_conf[count].lock); + mi2s_intf_conf[count].ref_cnt = 0; + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-master", + mi2s_master_slave, MI2S_MAX); + if (ret) { + dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n", + __func__); + } else { + for (count = 0; count < MI2S_MAX; count++) { + mi2s_intf_conf[count].msm_is_mi2s_master = + mi2s_master_slave[count]; + } + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-ext-mclk", + mi2s_ext_mclk, MI2S_MAX); + if (ret) { + dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-ext-mclk in DT node\n", + __func__); + } else { + for (count = 0; count < MI2S_MAX; count++) + mi2s_intf_conf[count].msm_is_ext_mclk = + mi2s_ext_mclk[count]; + } +} + +static const struct of_device_id sdm660_asoc_machine_of_match[] = { + { .compatible = "qcom,sdm660-asoc-snd", + .data = "internal_codec"}, + { .compatible = "qcom,sdm660-asoc-snd-tasha", + .data = "tasha_codec"}, + { .compatible = "qcom,sdm660-asoc-snd-tavil", + .data = "tavil_codec"}, + { .compatible = "qcom,sdm670-asoc-snd", + .data = "internal_codec"}, + { .compatible = "qcom,sdm670-asoc-snd-tasha", + .data = "tasha_codec"}, + { .compatible = "qcom,sdm670-asoc-snd-tavil", + .data = "tavil_codec"}, + {}, +}; + +static int msm_asoc_machine_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = NULL; + struct msm_asoc_mach_data *pdata = NULL; + const char *mclk = "qcom,msm-mclk-freq"; + int ret = -EINVAL, id; + const struct of_device_id *match; + const char *usb_c_dt = "qcom,msm-mbhc-usbc-audio-supported"; + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct msm_asoc_mach_data), + GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + msm_set_codec_reg_done(false); + match = of_match_node(sdm660_asoc_machine_of_match, + pdev->dev.of_node); + if (!match) + goto err; + + ret = of_property_read_u32(pdev->dev.of_node, mclk, &id); + if (ret) { + dev_err(&pdev->dev, + "%s: missing %s in dt node\n", __func__, mclk); + id = DEFAULT_MCLK_RATE; + } + pdata->mclk_freq = id; + + if (!strcmp(match->data, "tasha_codec") || + !strcmp(match->data, "tavil_codec")) { + if (!strcmp(match->data, "tasha_codec")) + pdata->snd_card_val = EXT_SND_CARD_TASHA; + else + pdata->snd_card_val = EXT_SND_CARD_TAVIL; + ret = msm_ext_cdc_init(pdev, pdata, &card, &mbhc_cfg); + if (ret) + goto err; + } else if (!strcmp(match->data, "internal_codec")) { + pdata->snd_card_val = INT_SND_CARD; + ret = msm_int_cdc_init(pdev, pdata, &card, &mbhc_cfg); + if (ret) + goto err; + } else { + dev_err(&pdev->dev, + "%s: Not a matching DT sound node\n", __func__); + goto err; + } + if (!card) + goto err; + + if (pdata->snd_card_val == INT_SND_CARD) { + /*reading the gpio configurations from dtsi file*/ + pdata->pdm_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-pdm-gpios", 0); + pdata->comp_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-comp-gpios", 0); + pdata->dmic_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-dmic-gpios", 0); + pdata->ext_spk_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,cdc-ext-spk-gpios", 0); + } + + pdata->mi2s_gpio_p[PRIM_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,pri-mi2s-gpios", 0); + pdata->mi2s_gpio_p[SEC_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,sec-mi2s-gpios", 0); + pdata->mi2s_gpio_p[TERT_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,tert-mi2s-gpios", 0); + pdata->mi2s_gpio_p[QUAT_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,quat-mi2s-gpios", 0); + pdata->mi2s_gpio_p[QUIN_MI2S] = of_parse_phandle(pdev->dev.of_node, + "qcom,quin-mi2s-gpios", 0); + /* + * Parse US-Euro gpio info from DT. Report no error if us-euro + * entry is not found in DT file as some targets do not support + * US-Euro detection + */ + pdata->us_euro_gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,us-euro-gpios", 0); + if (!gpio_is_valid(pdata->us_euro_gpio)) + pdata->us_euro_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,us-euro-gpios", 0); + if (!gpio_is_valid(pdata->us_euro_gpio) && (!pdata->us_euro_gpio_p)) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,us-euro-gpios", pdev->dev.of_node->full_name); + } else { + dev_dbg(&pdev->dev, "%s detected", + "qcom,us-euro-gpios"); + mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; + } + + if (of_find_property(pdev->dev.of_node, usb_c_dt, NULL)) + mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; + + ret = msm_prepare_us_euro(card); + if (ret) + dev_dbg(&pdev->dev, "msm_prepare_us_euro failed (%d)\n", + ret); + + i2s_auxpcm_init(pdev); + + ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing"); + if (ret) + goto err; + ret = msm_populate_dai_link_component_of_node(pdata, card); + if (ret) { + ret = -EPROBE_DEFER; + goto err; + } + + if (!of_property_read_bool(pdev->dev.of_node, "qcom,wsa-disable")) { + ret = msm_init_wsa_dev(pdev, card); + if (ret) + goto err; + } + + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret == -EPROBE_DEFER) { + if (codec_reg_done) { + /* + * return failure as EINVAL since other codec + * registered sound card successfully. + * This avoids any further probe calls. + */ + ret = -EINVAL; + } + goto err; + } else if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); + goto err; + } + if (pdata->snd_card_val != INT_SND_CARD) + msm_ext_register_audio_notifier(pdev); + + return 0; +err: + if (pdata->us_euro_gpio > 0) { + dev_dbg(&pdev->dev, "%s free us_euro gpio %d\n", + __func__, pdata->us_euro_gpio); + pdata->us_euro_gpio = 0; + } + if (pdata->hph_en1_gpio > 0) { + dev_dbg(&pdev->dev, "%s free hph_en1_gpio %d\n", + __func__, pdata->hph_en1_gpio); + gpio_free(pdata->hph_en1_gpio); + pdata->hph_en1_gpio = 0; + } + if (pdata->hph_en0_gpio > 0) { + dev_dbg(&pdev->dev, "%s free hph_en0_gpio %d\n", + __func__, pdata->hph_en0_gpio); + gpio_free(pdata->hph_en0_gpio); + pdata->hph_en0_gpio = 0; + } + if (pdata->snd_card_val != INT_SND_CARD) + msm_ext_cdc_deinit(pdata); + devm_kfree(&pdev->dev, pdata); + return ret; +} + +static int msm_asoc_machine_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + + if (pdata->snd_card_val == INT_SND_CARD) + mutex_destroy(&pdata->cdc_int_mclk0_mutex); + + if (gpio_is_valid(pdata->us_euro_gpio)) { + gpio_free(pdata->us_euro_gpio); + pdata->us_euro_gpio = 0; + } + if (gpio_is_valid(pdata->hph_en1_gpio)) { + gpio_free(pdata->hph_en1_gpio); + pdata->hph_en1_gpio = 0; + } + if (gpio_is_valid(pdata->hph_en0_gpio)) { + gpio_free(pdata->hph_en0_gpio); + pdata->hph_en0_gpio = 0; + } + + if (pdata->snd_card_val != INT_SND_CARD) { + audio_notifier_deregister("sdm660"); + msm_ext_cdc_deinit(pdata); + } + + snd_soc_unregister_card(card); + return 0; +} + +static struct platform_driver sdm660_asoc_machine_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = sdm660_asoc_machine_of_match, + }, + .probe = msm_asoc_machine_probe, + .remove = msm_asoc_machine_remove, +}; +module_platform_driver(sdm660_asoc_machine_driver); + +MODULE_DESCRIPTION("ALSA SoC msm"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, sdm660_asoc_machine_of_match); diff --git a/asoc/sdm660-ext-dai-links.c b/asoc/sdm660-ext-dai-links.c new file mode 100644 index 000000000000..534585fca485 --- /dev/null +++ b/asoc/sdm660-ext-dai-links.c @@ -0,0 +1,1992 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015-2019, 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include "msm-pcm-routing-v2.h" +#include +#include +#include +#include "codecs/wcd9335.h" +#include + +#define DEV_NAME_STR_LEN 32 +#define __CHIPSET__ "SDM660 " +#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) + +#define WCN_CDC_SLIM_RX_CH_MAX 2 +#define WCN_CDC_SLIM_TX_CH_MAX 3 +#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ + +static struct snd_soc_card snd_soc_card_msm_card_tavil = { + .name = "sdm670-tavil-snd-card", + .late_probe = msm_snd_card_tavil_late_probe, +}; + +static struct snd_soc_card snd_soc_card_msm_card_tasha = { + .name = "sdm670-tasha-snd-card", + .late_probe = msm_snd_card_tasha_late_probe, +}; + +static struct snd_soc_ops msm_ext_slimbus_be_ops = { + .hw_params = msm_snd_hw_params, +}; + +static struct snd_soc_ops msm_ext_cpe_ops = { + .hw_params = msm_snd_cpe_hw_params, +}; + +static struct snd_soc_ops msm_ext_slimbus_2_be_ops = { + .hw_params = msm_ext_slimbus_2_hw_params, +}; + +static struct snd_soc_ops msm_mi2s_be_ops = { + .startup = msm_mi2s_snd_startup, + .shutdown = msm_mi2s_snd_shutdown, +}; + +static struct snd_soc_ops msm_aux_pcm_be_ops = { + .startup = msm_aux_pcm_snd_startup, + .shutdown = msm_aux_pcm_snd_shutdown, +}; + +static struct snd_soc_ops msm_tdm_be_ops = { + .startup = msm_tdm_snd_startup, + .shutdown = msm_tdm_snd_shutdown, + .hw_params = msm_tdm_snd_hw_params, +}; + +static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) +{ + unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; + unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); +} + +static int msm_wcn_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + int ret; + + dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret) { + dev_err(rtd->dev, + "%s: failed to get BTFM codec chan map\n, err:%d\n", + __func__, ret); + goto exit; + } + + dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) id %d\n", + __func__, tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); + if (ret) + dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + +exit: + return ret; +} + +static struct snd_soc_ops msm_wcn_ops = { + .hw_params = msm_wcn_hw_params, +}; + +static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) +{ + cpumask_t mask; + + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + + cpumask_clear(&mask); + cpumask_set_cpu(1, &mask); /* affine to core 1 */ + cpumask_set_cpu(2, &mask); /* affine to core 2 */ + cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); + + substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; + + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + MSM_LL_QOS_VALUE); + return 0; +} + +static struct snd_soc_ops msm_fe_qos_ops = { + .prepare = msm_fe_qos_prepare, +}; + +static struct snd_soc_dai_link msm_ext_tasha_fe_dai[] = { + /* tasha_vifeedback for speaker protection */ + { + .name = LPASS_BE_SLIMBUS_4_TX, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_vifeedback", + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + }, + /* Ultrasound RX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Playback", + .stream_name = "SLIMBUS_2 Hostless Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx2", + .ignore_suspend = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .ignore_pmdown_time = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_ext_slimbus_2_be_ops, + }, + /* Ultrasound TX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Capture", + .stream_name = "SLIMBUS_2 Hostless Capture", + .cpu_dai_name = "msm-dai-q6-dev.16389", + .platform_name = "msm-pcm-hostless", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx2", + .ignore_suspend = 1, + .dpcm_capture = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_ext_slimbus_2_be_ops, + }, + /* CPE LSM direct dai-link */ + { + .name = "CPE Listen service", + .stream_name = "CPE Listen Audio Service", + .cpu_dai_name = "msm-dai-slim", + .platform_name = "msm-cpe-lsm", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .dpcm_capture = 1, + .codec_dai_name = "tasha_mad1", + .codec_name = "tasha_codec", + .ops = &msm_ext_cpe_ops, + }, + { + .name = "SLIMBUS_6 Hostless Playback", + .stream_name = "SLIMBUS_6 Hostless", + .cpu_dai_name = "SLIMBUS6_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + /* CPE LSM EC PP direct dai-link */ + { + .name = "CPE Listen service ECPP", + .stream_name = "CPE Listen Audio Service ECPP", + .cpu_dai_name = "CPE_LSM_NOHOST", + .platform_name = "msm-cpe-lsm.3", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "tasha_cpe", + .codec_name = "tasha_codec", + }, +}; + +static struct snd_soc_dai_link msm_ext_tavil_fe_dai[] = { + { + .name = LPASS_BE_SLIMBUS_4_TX, + .stream_name = "Slimbus4 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16393", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_vifeedback", + .id = MSM_BACKEND_DAI_SLIMBUS_4_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + }, + /* Ultrasound RX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Playback", + .stream_name = "SLIMBUS_2 Hostless Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx2", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_ext_slimbus_2_be_ops, + }, + /* Ultrasound TX DAI Link */ + { + .name = "SLIMBUS_2 Hostless Capture", + .stream_name = "SLIMBUS_2 Hostless Capture", + .cpu_dai_name = "msm-dai-q6-dev.16389", + .platform_name = "msm-pcm-hostless", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx2", + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ops = &msm_ext_slimbus_2_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_ext_tasha_be_dai[] = { + /* Backend DAI Links */ + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_init, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_ext_slimbus_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_ext_slimbus_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_1_RX, + .stream_name = "Slimbus1 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16386", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_1_TX, + .stream_name = "Slimbus1 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16387", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx3", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_RX, + .stream_name = "Slimbus3 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16390", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_TX, + .stream_name = "Slimbus3 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16391", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_4_RX, + .stream_name = "Slimbus4 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16392", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mix_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_5_RX, + .stream_name = "Slimbus5 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16394", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx3", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* MAD BE */ + { + .name = LPASS_BE_SLIMBUS_5_TX, + .stream_name = "Slimbus5 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16395", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_mad1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_6_RX, + .stream_name = "Slimbus6 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16396", + .platform_name = "msm-pcm-routing", + .codec_name = "tasha_codec", + .codec_dai_name = "tasha_rx4", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_ext_tavil_be_dai[] = { + { + .name = LPASS_BE_SLIMBUS_0_RX, + .stream_name = "Slimbus Playback", + .cpu_dai_name = "msm-dai-q6-dev.16384", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_RX, + .init = &msm_audrx_init, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_ext_slimbus_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_0_TX, + .stream_name = "Slimbus Capture", + .cpu_dai_name = "msm-dai-q6-dev.16385", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_0_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_ext_slimbus_be_ops, + }, + { + .name = LPASS_BE_SLIMBUS_1_RX, + .stream_name = "Slimbus1 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16386", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_1_TX, + .stream_name = "Slimbus1 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16387", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx3", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_1_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_2_RX, + .stream_name = "Slimbus2 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16388", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx2", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_2_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_RX, + .stream_name = "Slimbus3 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16390", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_3_TX, + .stream_name = "Slimbus3 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16391", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_tx1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_3_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_4_RX, + .stream_name = "Slimbus4 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16392", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_4_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_5_RX, + .stream_name = "Slimbus5 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16394", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx3", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + /* MAD BE */ + { + .name = LPASS_BE_SLIMBUS_5_TX, + .stream_name = "Slimbus5 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16395", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_mad1", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_5_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_6_RX, + .stream_name = "Slimbus6 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16396", + .platform_name = "msm-pcm-routing", + .codec_name = "tavil_codec", + .codec_dai_name = "tavil_rx4", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_6_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_ext_slimbus_be_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { + /* FrontEnd DAI Links */ + {/* hw:x,0 */ + .name = MSM_DAILINK_NAME(Media1), + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, + {/* hw:x,1 */ + .name = MSM_DAILINK_NAME(Media2), + .stream_name = "MultiMedia2", + .cpu_dai_name = "MultiMedia2", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, + }, + {/* hw:x,2 */ + .name = "VoiceMMode1", + .stream_name = "VoiceMMode1", + .cpu_dai_name = "VoiceMMode1", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE1, + }, + {/* hw:x,3 */ + .name = "MSM VoIP", + .stream_name = "VoIP", + .cpu_dai_name = "VoIP", + .platform_name = "msm-voip-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_VOIP, + }, + {/* hw:x,4 */ + .name = MSM_DAILINK_NAME(ULL), + .stream_name = "ULL", + .cpu_dai_name = "MultiMedia3", + .platform_name = "msm-pcm-dsp.2", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA3, + }, + /* Hostless PCM purpose */ + {/* hw:x,5 */ + .name = "SLIMBUS_0 Hostless", + .stream_name = "SLIMBUS_0 Hostless", + .cpu_dai_name = "SLIMBUS0_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* This dai link has MI2S support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,6 */ + .name = "MSM AFE-PCM RX", + .stream_name = "AFE-PROXY RX", + .cpu_dai_name = "msm-dai-q6-dev.241", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .platform_name = "msm-pcm-afe", + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + }, + {/* hw:x,7 */ + .name = "MSM AFE-PCM TX", + .stream_name = "AFE-PROXY TX", + .cpu_dai_name = "msm-dai-q6-dev.240", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .platform_name = "msm-pcm-afe", + .ignore_suspend = 1, + }, + {/* hw:x,8 */ + .name = MSM_DAILINK_NAME(Compress1), + .stream_name = "Compress1", + .cpu_dai_name = "MultiMedia4", + .platform_name = "msm-compress-dsp", + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA4, + }, + {/* hw:x,9*/ + .name = "AUXPCM Hostless", + .stream_name = "AUXPCM Hostless", + .cpu_dai_name = "AUXPCM_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,10 */ + .name = "SLIMBUS_1 Hostless", + .stream_name = "SLIMBUS_1 Hostless", + .cpu_dai_name = "SLIMBUS1_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, /* dai link has playback support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,11 */ + .name = "SLIMBUS_3 Hostless", + .stream_name = "SLIMBUS_3 Hostless", + .cpu_dai_name = "SLIMBUS3_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, /* dai link has playback support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,12 */ + .name = "SLIMBUS_4 Hostless", + .stream_name = "SLIMBUS_4 Hostless", + .cpu_dai_name = "SLIMBUS4_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, /* dai link has playback support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,13 */ + .name = MSM_DAILINK_NAME(LowLatency), + .stream_name = "MultiMedia5", + .cpu_dai_name = "MultiMedia5", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .ops = &msm_fe_qos_ops, + }, + /* LSM FE */ + {/* hw:x,14 */ + .name = "Listen 1 Audio Service", + .stream_name = "Listen 1 Audio Service", + .cpu_dai_name = "LSM1", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM1, + }, + {/* hw:x,15 */ + .name = MSM_DAILINK_NAME(Compress2), + .stream_name = "Compress2", + .cpu_dai_name = "MultiMedia7", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA7, + }, + {/* hw:x,16 */ + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", + .cpu_dai_name = "MultiMedia10", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA10, + }, + {/* hw:x,17 */ + .name = MSM_DAILINK_NAME(ULL_NOIRQ), + .stream_name = "MM_NOIRQ", + .cpu_dai_name = "MultiMedia8", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + .ops = &msm_fe_qos_ops, + }, + {/* hw:x,18 */ + .name = "HDMI_RX_HOSTLESS", + .stream_name = "HDMI_RX_HOSTLESS", + .cpu_dai_name = "HDMI_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,19 */ + .name = "VoiceMMode2", + .stream_name = "VoiceMMode2", + .cpu_dai_name = "VoiceMMode2", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE2, + }, + {/* hw:x,20 */ + .name = "Listen 2 Audio Service", + .stream_name = "Listen 2 Audio Service", + .cpu_dai_name = "LSM2", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM2, + }, + {/* hw:x,21 */ + .name = "Listen 3 Audio Service", + .stream_name = "Listen 3 Audio Service", + .cpu_dai_name = "LSM3", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM3, + }, + {/* hw:x,22 */ + .name = "Listen 4 Audio Service", + .stream_name = "Listen 4 Audio Service", + .cpu_dai_name = "LSM4", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM4, + }, + {/* hw:x,23 */ + .name = "Listen 5 Audio Service", + .stream_name = "Listen 5 Audio Service", + .cpu_dai_name = "LSM5", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM5, + }, + {/* hw:x,24 */ + .name = "Listen 6 Audio Service", + .stream_name = "Listen 6 Audio Service", + .cpu_dai_name = "LSM6", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM6 + }, + {/* hw:x,25 */ + .name = "Listen 7 Audio Service", + .stream_name = "Listen 7 Audio Service", + .cpu_dai_name = "LSM7", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM7, + }, + {/* hw:x,26 */ + .name = "Listen 8 Audio Service", + .stream_name = "Listen 8 Audio Service", + .cpu_dai_name = "LSM8", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM8, + }, + {/* hw:x,27 */ + .name = MSM_DAILINK_NAME(Media9), + .stream_name = "MultiMedia9", + .cpu_dai_name = "MultiMedia9", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA9, + }, + {/* hw:x,28 */ + .name = MSM_DAILINK_NAME(Compress4), + .stream_name = "Compress4", + .cpu_dai_name = "MultiMedia11", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA11, + }, + {/* hw:x,29 */ + .name = MSM_DAILINK_NAME(Compress5), + .stream_name = "Compress5", + .cpu_dai_name = "MultiMedia12", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA12, + }, + {/* hw:x,30 */ + .name = MSM_DAILINK_NAME(Compress6), + .stream_name = "Compress6", + .cpu_dai_name = "MultiMedia13", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA13, + }, + {/* hw:x,31 */ + .name = MSM_DAILINK_NAME(Compress7), + .stream_name = "Compress7", + .cpu_dai_name = "MultiMedia14", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA14, + }, + {/* hw:x,32 */ + .name = MSM_DAILINK_NAME(Compress8), + .stream_name = "Compress8", + .cpu_dai_name = "MultiMedia15", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA15, + }, + {/* hw:x,33 */ + .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), + .stream_name = "MM_NOIRQ_2", + .cpu_dai_name = "MultiMedia16", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA16, + }, + {/* hw:x,34 */ + .name = "SLIMBUS_8 Hostless", + .stream_name = "SLIMBUS8_HOSTLESS Capture", + .cpu_dai_name = "SLIMBUS8_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,35 */ + .name = "SLIMBUS7 Hostless", + .stream_name = "SLIMBUS7 Hostless", + .cpu_dai_name = "SLIMBUS7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,36 */ + .name = "SDM660 HFP TX", + .stream_name = "MultiMedia6", + .cpu_dai_name = "MultiMedia6", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA6, + }, +}; + +static struct snd_soc_dai_link msm_ext_common_be_dai[] = { + { + .name = LPASS_BE_AFE_PCM_RX, + .stream_name = "AFE Playback", + .cpu_dai_name = "msm-dai-q6-dev.224", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AFE_PCM_TX, + .stream_name = "AFE Capture", + .cpu_dai_name = "msm-dai-q6-dev.225", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Uplink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_TX, + .stream_name = "Voice Uplink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32772", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Downlink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_RX, + .stream_name = "Voice Downlink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32771", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music BACK END DAI Link */ + { + .name = LPASS_BE_VOICE_PLAYBACK_TX, + .stream_name = "Voice Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32773", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + /* Incall Music 2 BACK END DAI Link */ + { + .name = LPASS_BE_VOICE2_PLAYBACK_TX, + .stream_name = "Voice2 Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32770", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_RX, + .stream_name = "USB Audio Playback", + .cpu_dai_name = "msm-dai-q6-dev.28672", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_USB_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_TX, + .stream_name = "USB Audio Capture", + .cpu_dai_name = "msm-dai-q6-dev.28673", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_USB_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_0, + .stream_name = "Primary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36864", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_0, + .stream_name = "Primary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36865", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_0, + .stream_name = "Secondary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36880", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_0, + .stream_name = "Secondary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36881", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_0, + .stream_name = "Tertiary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36896", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_0, + .stream_name = "Tertiary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36897", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_0, + .stream_name = "Quaternary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36912", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_0, + .stream_name = "Quaternary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36913", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_TDM_RX_0, + .stream_name = "Quinary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36928", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_RX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_TDM_TX_0, + .stream_name = "Quinary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36929", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { + { + .name = LPASS_BE_PRI_MI2S_RX, + .stream_name = "Primary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_MI2S_TX, + .stream_name = "Primary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX, + .stream_name = "Secondary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX, + .stream_name = "Secondary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX, + .stream_name = "Tertiary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX, + .stream_name = "Tertiary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX, + .stream_name = "Quaternary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_RX, + .stream_name = "Quinary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_TX, + .stream_name = "Quinary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { + /* Primary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_AUXPCM_RX, + .stream_name = "AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_AUXPCM_TX, + .stream_name = "AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Secondary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_SEC_AUXPCM_RX, + .stream_name = "Sec AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_SEC_AUXPCM_TX, + .stream_name = "Sec AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Tertiary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_TERT_AUXPCM_RX, + .stream_name = "Tert AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_TERT_AUXPCM_TX, + .stream_name = "Tert AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Quaternary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUAT_AUXPCM_RX, + .stream_name = "Quat AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_QUAT_AUXPCM_TX, + .stream_name = "Quat AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Quinary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUIN_AUXPCM_RX, + .stream_name = "Quin AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_QUIN_AUXPCM_TX, + .stream_name = "Quin AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, +}; + +static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_7_RX, + .stream_name = "Slimbus7 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16398", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + /* BT codec driver determines capabilities based on + * dai name, bt codecdai name should always contains + * supported usecase information + */ + .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_wcn_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_7_TX, + .stream_name = "Slimbus7 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16399", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_bt_sco_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_8_TX, + .stream_name = "Slimbus8 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16401", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_fm_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_8_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .init = &msm_wcn_init, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link ext_disp_be_dai_link[] = { + /* DISP PORT BACK END DAI Link */ + { + .name = LPASS_BE_DISPLAY_PORT, + .stream_name = "Display Port Playback", + .cpu_dai_name = "msm-dai-q6-dp.24608", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-ext-disp-audio-codec-rx", + .codec_dai_name = "msm_dp_audio_codec_rx_dai", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_ext_tasha_dai_links[ +ARRAY_SIZE(msm_ext_common_fe_dai) + +ARRAY_SIZE(msm_ext_tasha_fe_dai) + +ARRAY_SIZE(msm_ext_common_be_dai) + +ARRAY_SIZE(msm_ext_tasha_be_dai) + +ARRAY_SIZE(msm_mi2s_be_dai_links) + +ARRAY_SIZE(msm_auxpcm_be_dai_links) + +ARRAY_SIZE(msm_wcn_be_dai_links) + +ARRAY_SIZE(ext_disp_be_dai_link)]; + +static struct snd_soc_dai_link msm_ext_tavil_dai_links[ +ARRAY_SIZE(msm_ext_common_fe_dai) + +ARRAY_SIZE(msm_ext_tavil_fe_dai) + +ARRAY_SIZE(msm_ext_common_be_dai) + +ARRAY_SIZE(msm_ext_tavil_be_dai) + +ARRAY_SIZE(msm_mi2s_be_dai_links) + +ARRAY_SIZE(msm_auxpcm_be_dai_links) + +ARRAY_SIZE(msm_wcn_be_dai_links) + +ARRAY_SIZE(ext_disp_be_dai_link)]; + +/** + * populate_snd_card_dailinks - prepares dailink array and initializes card. + * + * @dev: device handle + * + * Returns card on success or NULL on failure. + */ +struct snd_soc_card *populate_snd_card_dailinks(struct device *dev, + int snd_card_val) +{ + struct snd_soc_card *card; + struct snd_soc_dai_link *msm_ext_dai_links = NULL; + int ret, len1, len2, len3, len4; + enum codec_variant codec_ver = 0; + + if (snd_card_val == EXT_SND_CARD_TASHA) { + card = &snd_soc_card_msm_card_tasha; + } else if (snd_card_val == EXT_SND_CARD_TAVIL) { + card = &snd_soc_card_msm_card_tavil; + } else { + dev_err(dev, "%s: failing as no matching card name\n", + __func__); + return NULL; + } + + card->dev = dev; + ret = snd_soc_of_parse_card_name(card, "qcom,model"); + if (ret) { + dev_err(dev, "%s: parse card name failed, err:%d\n", + __func__, ret); + return NULL; + } + + if (strnstr(card->name, "tasha", strlen(card->name))) { + codec_ver = tasha_codec_ver(); + if (codec_ver == WCD9326) { + card->name = "sdm670-tashalite-snd-card"; + } else if (codec_ver == WCD9XXX) { + dev_err(dev, "%s: Invalid codec version %d\n", + __func__, codec_ver); + return NULL; + } + + len1 = ARRAY_SIZE(msm_ext_common_fe_dai); + len2 = len1 + ARRAY_SIZE(msm_ext_tasha_fe_dai); + len3 = len2 + ARRAY_SIZE(msm_ext_common_be_dai); + memcpy(msm_ext_tasha_dai_links, msm_ext_common_fe_dai, + sizeof(msm_ext_common_fe_dai)); + memcpy(msm_ext_tasha_dai_links + len1, + msm_ext_tasha_fe_dai, sizeof(msm_ext_tasha_fe_dai)); + memcpy(msm_ext_tasha_dai_links + len2, + msm_ext_common_be_dai, sizeof(msm_ext_common_be_dai)); + memcpy(msm_ext_tasha_dai_links + len3, + msm_ext_tasha_be_dai, sizeof(msm_ext_tasha_be_dai)); + len4 = len3 + ARRAY_SIZE(msm_ext_tasha_be_dai); + if (of_property_read_bool(dev->of_node, + "qcom,mi2s-audio-intf")) { + memcpy(msm_ext_tasha_dai_links + len4, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + len4 += ARRAY_SIZE(msm_mi2s_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,auxpcm-audio-intf")) { + memcpy(msm_ext_tasha_dai_links + len4, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + len4 += ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + dev_dbg(dev, "%s(): WCN BTFM support present\n", + __func__); + memcpy(msm_ext_tasha_dai_links + len4, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + len4 += ARRAY_SIZE(msm_wcn_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,ext-disp-audio-rx")) { + dev_dbg(dev, "%s(): ext disp audio support present\n", + __func__); + memcpy(msm_ext_tasha_dai_links + len4, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + len4 += ARRAY_SIZE(ext_disp_be_dai_link); + } + msm_ext_dai_links = msm_ext_tasha_dai_links; + } else if (strnstr(card->name, "tavil", strlen(card->name))) { + len1 = ARRAY_SIZE(msm_ext_common_fe_dai); + len2 = len1 + ARRAY_SIZE(msm_ext_tavil_fe_dai); + len3 = len2 + ARRAY_SIZE(msm_ext_common_be_dai); + memcpy(msm_ext_tavil_dai_links, msm_ext_common_fe_dai, + sizeof(msm_ext_common_fe_dai)); + memcpy(msm_ext_tavil_dai_links + len1, + msm_ext_tavil_fe_dai, sizeof(msm_ext_tavil_fe_dai)); + memcpy(msm_ext_tavil_dai_links + len2, + msm_ext_common_be_dai, sizeof(msm_ext_common_be_dai)); + memcpy(msm_ext_tavil_dai_links + len3, + msm_ext_tavil_be_dai, sizeof(msm_ext_tavil_be_dai)); + len4 = len3 + ARRAY_SIZE(msm_ext_tavil_be_dai); + if (of_property_read_bool(dev->of_node, + "qcom,mi2s-audio-intf")) { + memcpy(msm_ext_tavil_dai_links + len4, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + len4 += ARRAY_SIZE(msm_mi2s_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,auxpcm-audio-intf")) { + memcpy(msm_ext_tavil_dai_links + len4, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + len4 += ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + dev_dbg(dev, "%s(): WCN BTFM support present\n", + __func__); + memcpy(msm_ext_tavil_dai_links + len4, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + len4 += ARRAY_SIZE(msm_wcn_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,ext-disp-audio-rx")) { + dev_dbg(dev, "%s(): ext disp audio support present\n", + __func__); + memcpy(msm_ext_tavil_dai_links + len4, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + len4 += ARRAY_SIZE(ext_disp_be_dai_link); + } + msm_ext_dai_links = msm_ext_tavil_dai_links; + } else { + dev_err(dev, "%s: failing as no matching card name\n", + __func__); + return NULL; + } + card->dai_link = msm_ext_dai_links; + card->num_links = len4; + + return card; +} +EXPORT_SYMBOL(populate_snd_card_dailinks); diff --git a/asoc/sdm660-external.c b/asoc/sdm660-external.c new file mode 100644 index 000000000000..6edec14d2b8c --- /dev/null +++ b/asoc/sdm660-external.c @@ -0,0 +1,1984 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015-2018, 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm-pcm-routing-v2.h" +#include +#include +#include "codecs/wcd9335.h" +#include "codecs/wcd934x/wcd934x.h" +#include "codecs/wcd934x/wcd934x-mbhc.h" +#include + +#define SDM660_SPK_ON 1 +#define SDM660_SPK_OFF 0 + +#define WCD9XXX_MBHC_DEF_BUTTONS 8 +#define WCD9XXX_MBHC_DEF_RLOADS 5 +#define CODEC_EXT_CLK_RATE 9600000 +#define ADSP_STATE_READY_TIMEOUT_MS 3000 + +#define TLMM_CENTER_MPM_WAKEUP_INT_EN_0 0x03596000 +#define LPI_GPIO_22_WAKEUP_VAL 0x00000002 + +#define TLMM_LPI_DIR_CONN_INTR1_CFG_APPS 0x0359D004 +#define LPI_GPIO_22_INTR1_CFG_VAL 0x01 +#define LPI_GPIO_22_INTR1_CFG_MASK 0x03 + +#define TLMM_LPI_GPIO_INTR_CFG1 0x0359B004 +#define LPI_GPIO_INTR_CFG1_VAL 0x00000113 + +#define TLMM_LPI_GPIO22_CFG 0x15078040 +#define LPI_GPIO22_CFG_VAL 0x0000009 + +#define TLMM_LPI_GPIO22_INOUT 0x179D1318 +#define LPI_GPIO22_INOUT_VAL 0x0020000 + + +#define WSA8810_NAME_1 "wsa881x.20170211" +#define WSA8810_NAME_2 "wsa881x.20170212" +#define SDM660_SOC_MSM_ID 0x13D +static int msm_ext_spk_control = 1; +static struct wcd_mbhc_config *wcd_mbhc_cfg_ptr; + +struct msm_asoc_wcd93xx_codec { + void* (*get_afe_config_fn)(struct snd_soc_component *component, + enum afe_config_type config_type); + void (*mbhc_hs_detect_exit)(struct snd_soc_component *component); +}; + +static struct msm_asoc_wcd93xx_codec msm_codec_fn; +static struct platform_device *spdev; + +static bool is_initial_boot; + +static void *def_ext_mbhc_cal(void); + +enum { + SLIM_RX_0 = 0, + SLIM_RX_1, + SLIM_RX_2, + SLIM_RX_3, + SLIM_RX_4, + SLIM_RX_5, + SLIM_RX_6, + SLIM_RX_7, + SLIM_RX_MAX, +}; + +enum { + SLIM_TX_0 = 0, + SLIM_TX_1, + SLIM_TX_2, + SLIM_TX_3, + SLIM_TX_4, + SLIM_TX_5, + SLIM_TX_6, + SLIM_TX_7, + SLIM_TX_8, + SLIM_TX_MAX, +}; + +/* Default configuration of slimbus channels */ +static struct dev_config slim_rx_cfg[] = { + [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, +}; + +static struct dev_config slim_tx_cfg[] = { + [SLIM_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static int msm_vi_feed_tx_ch = 2; +static const char *const slim_rx_ch_text[] = {"One", "Two"}; +static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static const char *const vi_feed_ch_text[] = {"One", "Two"}; +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; +static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96", "KHZ_176P4", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static const char *const spk_function_text[] = {"Off", "On"}; +static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; + +static SOC_ENUM_SINGLE_EXT_DECL(spk_func_en, spk_function_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_1_tx_chs, slim_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); + +static int slim_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_88P2KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_176P4KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 10; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int slim_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_176P4KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 9: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 10: + sample_rate = SAMPLING_RATE_384KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int slim_get_bit_format_val(int bit_format) +{ + int val = 0; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + val = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + val = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + val = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + val = 0; + break; + } + return val; +} + +static int slim_get_bit_format(int val) +{ + int bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + + switch (val) { + case 0: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + bit_fmt = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + bit_fmt = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 3: + bit_fmt = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return bit_fmt; +} + +static int slim_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int port_id = 0; + + if (strnstr(kcontrol->id.name, "SLIM_0_RX", sizeof("SLIM_0_RX"))) + port_id = SLIM_RX_0; + else if (strnstr(kcontrol->id.name, "SLIM_2_RX", sizeof("SLIM_2_RX"))) + port_id = SLIM_RX_2; + else if (strnstr(kcontrol->id.name, "SLIM_5_RX", sizeof("SLIM_5_RX"))) + port_id = SLIM_RX_5; + else if (strnstr(kcontrol->id.name, "SLIM_6_RX", sizeof("SLIM_6_RX"))) + port_id = SLIM_RX_6; + else if (strnstr(kcontrol->id.name, "SLIM_0_TX", sizeof("SLIM_0_TX"))) + port_id = SLIM_TX_0; + else if (strnstr(kcontrol->id.name, "SLIM_1_TX", sizeof("SLIM_1_TX"))) + port_id = SLIM_TX_1; + else { + pr_err("%s: unsupported channel: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + + return port_id; +} + +static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* + * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) + * when used for BT_SCO use case. Return either Rx or Tx sample rate + * value. + */ + switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate = %d", __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n", + __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate, + slim_tx_cfg[SLIM_TX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_sample_rate_val(slim_rx_cfg[ch_num].sample_rate); + + pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].sample_rate = + slim_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_sample_rate_val(slim_tx_cfg[ch_num].sample_rate); + + pr_debug("%s: slim[%d]_tx_sample_rate = %d, item = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate = 0; + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + sample_rate = slim_get_sample_rate(ucontrol->value.enumerated.item[0]); + if (sample_rate == SAMPLING_RATE_44P1KHZ) { + pr_err("%s: Unsupported sample rate %d: for Tx path\n", + __func__, sample_rate); + return -EINVAL; + } + slim_tx_cfg[ch_num].sample_rate = sample_rate; + + pr_debug("%s: slim[%d]_tx_sample_rate = %d, value = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_bit_format_val(slim_rx_cfg[ch_num].bit_format); + + pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_rx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_rx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].bit_format = + slim_get_bit_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_rx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + slim_get_bit_format_val(slim_tx_cfg[ch_num].bit_format); + + pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_tx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int slim_tx_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_tx_cfg[ch_num].bit_format = + slim_get_bit_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, slim_tx_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int msm_slim_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].channels); + ucontrol->value.enumerated.item[0] = slim_rx_cfg[ch_num].channels - 1; + + return 0; +} + +static int msm_slim_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_rx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__, + ch_num, slim_rx_cfg[ch_num].channels); + + return 1; +} + +static int msm_slim_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].channels); + ucontrol->value.enumerated.item[0] = slim_tx_cfg[ch_num].channels - 1; + + return 0; +} + +static int msm_slim_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = slim_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + slim_tx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__, + ch_num, slim_tx_cfg[ch_num].channels); + + return 1; +} + +static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1; + pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch); + return 1; +} + +static void *def_ext_mbhc_cal(void) +{ + void *wcd_mbhc_cal; + struct wcd_mbhc_btn_detect_cfg *btn_cfg; + u16 *btn_high; + + wcd_mbhc_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, + WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); + if (!wcd_mbhc_cal) + return NULL; + +#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(wcd_mbhc_cal)->X) = (Y)) + S(v_hs_max, 1600); +#undef S +#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal)->X) = (Y)) + S(num_btn, WCD_MBHC_DEF_BUTTONS); +#undef S + + btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal); + btn_high = ((void *)&btn_cfg->_v_btn_low) + + (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); + + btn_high[0] = 75; + btn_high[1] = 150; + btn_high[2] = 237; + btn_high[3] = 500; + btn_high[4] = 500; + btn_high[5] = 500; + btn_high[6] = 500; + btn_high[7] = 500; + + return wcd_mbhc_cal; +} + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + + +static void msm_ext_control(struct snd_soc_component *codec) +{ + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(codec); + + pr_debug("%s: msm_ext_spk_control = %d", __func__, msm_ext_spk_control); + if (msm_ext_spk_control == SDM660_SPK_ON) { + snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp"); + snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp"); + } else { + snd_soc_dapm_disable_pin(dapm, "Lineout_1 amp"); + snd_soc_dapm_disable_pin(dapm, "Lineout_3 amp"); + } + snd_soc_dapm_sync(dapm); +} + +static int msm_ext_get_spk(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_ext_spk_control = %d\n", + __func__, msm_ext_spk_control); + ucontrol->value.integer.value[0] = msm_ext_spk_control; + return 0; +} + +static int msm_ext_set_spk(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + + pr_debug("%s()\n", __func__); + if (msm_ext_spk_control == ucontrol->value.integer.value[0]) + return 0; + + msm_ext_spk_control = ucontrol->value.integer.value[0]; + msm_ext_control(component); + return 1; +} + + +int msm_ext_enable_codec_mclk(struct snd_soc_component *component, int enable, + bool dapm) +{ + int ret; + + pr_debug("%s: enable = %d\n", __func__, enable); + + if (!strcmp(dev_name(component->dev), "tasha_codec")) + ret = tasha_cdc_mclk_enable(component, enable, dapm); + else if (!strcmp(dev_name(component->dev), "tavil_codec")) + ret = tavil_cdc_mclk_enable(component, enable); + else { + dev_err(component->dev, "%s: unknown codec to enable ext clk\n", + __func__); + ret = -EINVAL; + } + return ret; +} + +static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("Speaker Function", spk_func_en, msm_ext_get_spk, + msm_ext_set_spk), + SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs, + msm_slim_rx_ch_get, msm_slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs, + msm_slim_rx_ch_get, msm_slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs, + msm_slim_tx_ch_get, msm_slim_tx_ch_put), + SOC_ENUM_EXT("SLIM_1_TX Channels", slim_1_tx_chs, + msm_slim_tx_ch_get, msm_slim_tx_ch_put), + SOC_ENUM_EXT("SLIM_5_RX Channels", slim_5_rx_chs, + msm_slim_rx_ch_get, msm_slim_rx_ch_put), + SOC_ENUM_EXT("SLIM_6_RX Channels", slim_6_rx_chs, + msm_slim_rx_ch_get, msm_slim_rx_ch_put), + SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs, + msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), + SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_5_RX Format", slim_5_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_6_RX Format", slim_6_rx_format, + slim_rx_bit_format_get, slim_rx_bit_format_put), + SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format, + slim_tx_bit_format_get, slim_tx_bit_format_put), + SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate, + slim_tx_sample_rate_get, slim_tx_sample_rate_put), + SOC_ENUM_EXT("SLIM_5_RX SampleRate", slim_5_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("SLIM_6_RX SampleRate", slim_6_rx_sample_rate, + slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), +}; + +static int msm_slim_get_ch_from_beid(int32_t id) +{ + int ch_id = 0; + + switch (id) { + case MSM_BACKEND_DAI_SLIMBUS_0_RX: + ch_id = SLIM_RX_0; + break; + case MSM_BACKEND_DAI_SLIMBUS_1_RX: + ch_id = SLIM_RX_1; + break; + case MSM_BACKEND_DAI_SLIMBUS_2_RX: + ch_id = SLIM_RX_2; + break; + case MSM_BACKEND_DAI_SLIMBUS_3_RX: + ch_id = SLIM_RX_3; + break; + case MSM_BACKEND_DAI_SLIMBUS_4_RX: + ch_id = SLIM_RX_4; + break; + case MSM_BACKEND_DAI_SLIMBUS_6_RX: + ch_id = SLIM_RX_6; + break; + case MSM_BACKEND_DAI_SLIMBUS_0_TX: + ch_id = SLIM_TX_0; + break; + case MSM_BACKEND_DAI_SLIMBUS_3_TX: + ch_id = SLIM_TX_3; + break; + default: + ch_id = SLIM_RX_0; + break; + } + + return ch_id; +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +/** + * msm_ext_be_hw_params_fixup - updates settings of ALSA BE hw params. + * + * @rtd: runtime dailink instance + * @params: HW params of associated backend dailink. + * + * Returns 0 on success or rc on failure. + */ +int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int rc = 0; + int idx; + void *config = NULL; + struct snd_soc_component *component = NULL; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->id) { + case MSM_BACKEND_DAI_SLIMBUS_0_RX: + case MSM_BACKEND_DAI_SLIMBUS_1_RX: + case MSM_BACKEND_DAI_SLIMBUS_2_RX: + case MSM_BACKEND_DAI_SLIMBUS_3_RX: + case MSM_BACKEND_DAI_SLIMBUS_4_RX: + case MSM_BACKEND_DAI_SLIMBUS_6_RX: + idx = msm_slim_get_ch_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[idx].bit_format); + rate->min = rate->max = slim_rx_cfg[idx].sample_rate; + channels->min = channels->max = slim_rx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_0_TX: + case MSM_BACKEND_DAI_SLIMBUS_3_TX: + idx = msm_slim_get_ch_from_beid(dai_link->id); + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[idx].bit_format); + rate->min = rate->max = slim_tx_cfg[idx].sample_rate; + channels->min = channels->max = slim_tx_cfg[idx].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_1_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_tx_cfg[1].bit_format); + rate->min = rate->max = slim_tx_cfg[1].sample_rate; + channels->min = channels->max = slim_tx_cfg[1].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_4_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + SNDRV_PCM_FORMAT_S32_LE); + rate->min = rate->max = SAMPLING_RATE_8KHZ; + channels->min = channels->max = msm_vi_feed_tx_ch; + break; + + case MSM_BACKEND_DAI_SLIMBUS_5_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[5].bit_format); + rate->min = rate->max = slim_rx_cfg[5].sample_rate; + channels->min = channels->max = slim_rx_cfg[5].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_5_TX: + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) + component = snd_soc_rtdcom_lookup(rtd, "tavil_codec"); + else if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) + component = snd_soc_rtdcom_lookup(rtd, "tasha_codec"); + rate->min = rate->max = SAMPLING_RATE_16KHZ; + channels->min = channels->max = 1; + + config = msm_codec_fn.get_afe_config_fn(component, + AFE_SLIMBUS_SLAVE_PORT_CONFIG); + if (config) { + rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, + config, SLIMBUS_5_TX); + if (rc) + pr_err("%s: Failed to set slimbus slave port config %d\n", + __func__, rc); + } + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + slim_rx_cfg[SLIM_RX_7].bit_format); + rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate; + channels->min = channels->max = + slim_rx_cfg[SLIM_RX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_7_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_8_TX: + rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate; + channels->min = channels->max = + slim_tx_cfg[SLIM_TX_8].channels; + break; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + return rc; +} +EXPORT_SYMBOL(msm_ext_be_hw_params_fixup); + +/** + * msm_snd_hw_params - hw params ops of backend dailink. + * + * @substream: PCM stream of associated backend dailink. + * @params: HW params of associated backend dailink. + * + * Returns 0 on success or ret on failure. + */ +int msm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + + int ret = 0; + u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + u32 user_set_tx_ch = 0; + u32 rx_ch_count; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto err_ch_map; + } + if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_5_RX) { + pr_debug("%s: rx_5_ch=%d\n", __func__, + slim_rx_cfg[5].channels); + rx_ch_count = slim_rx_cfg[5].channels; + } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_2_RX) { + pr_debug("%s: rx_2_ch=%d\n", __func__, + slim_rx_cfg[2].channels); + rx_ch_count = slim_rx_cfg[2].channels; + } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_6_RX) { + pr_debug("%s: rx_6_ch=%d\n", __func__, + slim_rx_cfg[6].channels); + rx_ch_count = slim_rx_cfg[6].channels; + } else { + pr_debug("%s: rx_0_ch=%d\n", __func__, + slim_rx_cfg[0].channels); + rx_ch_count = slim_rx_cfg[0].channels; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + rx_ch_count, rx_ch); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto err_ch_map; + } + } else { + pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__, + codec_dai->name, codec_dai->id, user_set_tx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map\n, err:%d\n", + __func__, ret); + goto err_ch_map; + } + /* For _tx1 case */ + if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_0_TX) + user_set_tx_ch = slim_tx_cfg[0].channels; + /* For _tx3 case */ + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_1_TX) + user_set_tx_ch = slim_tx_cfg[1].channels; + else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_4_TX) + user_set_tx_ch = msm_vi_feed_tx_ch; + else + user_set_tx_ch = tx_ch_cnt; + + pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), id (%d)\n", + __func__, slim_tx_cfg[0].channels, user_set_tx_ch, + tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + user_set_tx_ch, tx_ch, 0, 0); + if (ret < 0) + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + } + +err_ch_map: + return ret; +} +EXPORT_SYMBOL(msm_snd_hw_params); + +/** + * msm_ext_slimbus_2_hw_params - hw params ops of slimbus_2 BE. + * + * @substream: PCM stream of associated backend dailink. + * @params: HW params of associated backend dailink. + * + * Returns 0 on success or ret on failure. + */ +int msm_ext_slimbus_2_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; + unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0; + unsigned int num_tx_ch = 0; + unsigned int num_rx_ch = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + num_rx_ch = params_channels(params); + pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__, + codec_dai->name, codec_dai->id, num_rx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto end; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + num_rx_ch, rx_ch); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto end; + } + } else { + num_tx_ch = params_channels(params); + pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__, + codec_dai->name, codec_dai->id, num_tx_ch); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret < 0) { + pr_err("%s: failed to get codec chan map, err:%d\n", + __func__, ret); + goto end; + } + ret = snd_soc_dai_set_channel_map(cpu_dai, + num_tx_ch, tx_ch, 0, 0); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto end; + } + } +end: + return ret; +} +EXPORT_SYMBOL(msm_ext_slimbus_2_hw_params); + +/** + * msm_snd_cpe_hw_params - hw params ops of CPE backend. + * + * @substream: PCM stream of associated backend dailink. + * @params: HW params of associated backend dailink. + * + * Returns 0 on success or ret on failure. + */ +int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + int ret = 0; + u32 tx_ch[SLIM_MAX_TX_PORTS]; + u32 tx_ch_cnt = 0; + + if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) { + pr_err("%s: Invalid stream type %d\n", + __func__, substream->stream); + ret = -EINVAL; + goto end; + } + + pr_debug("%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, NULL, NULL); + if (ret < 0) { + pr_err("%s: failed to get codec chan map\n, err:%d\n", + __func__, ret); + goto end; + } + + pr_debug("%s: tx_ch_cnt(%d) id %d\n", + __func__, tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, 0, 0); + if (ret < 0) { + pr_err("%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + goto end; + } +end: + return ret; +} +EXPORT_SYMBOL(msm_snd_cpe_hw_params); + +static int msm_afe_set_config(struct snd_soc_component *component) +{ + int rc; + void *config_data; + + pr_debug("%s: enter\n", __func__); + + if (!msm_codec_fn.get_afe_config_fn) { + dev_err(component->dev, "%s: codec get afe config not init'ed\n", + __func__); + return -EINVAL; + } + config_data = msm_codec_fn.get_afe_config_fn(component, + AFE_CDC_REGISTERS_CONFIG); + if (config_data) { + rc = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0); + if (rc) { + pr_err("%s: Failed to set codec registers config %d\n", + __func__, rc); + return rc; + } + } + + config_data = msm_codec_fn.get_afe_config_fn(component, + AFE_CDC_REGISTER_PAGE_CONFIG); + if (config_data) { + rc = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, + 0); + if (rc) + pr_err("%s: Failed to set cdc register page config\n", + __func__); + } + + config_data = msm_codec_fn.get_afe_config_fn(component, + AFE_SLIMBUS_SLAVE_CONFIG); + if (config_data) { + rc = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0); + if (rc) { + pr_err("%s: Failed to set slimbus slave config %d\n", + __func__, rc); + return rc; + } + } + + config_data = msm_codec_fn.get_afe_config_fn(component, + AFE_AANC_VERSION); + if (config_data) { + rc = afe_set_config(AFE_AANC_VERSION, config_data, 0); + if (rc) { + pr_err("%s: Failed to set AANC version %d\n", + __func__, rc); + return rc; + } + } + + config_data = msm_codec_fn.get_afe_config_fn(component, + AFE_CDC_CLIP_REGISTERS_CONFIG); + if (config_data) { + rc = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG, + config_data, 0); + if (rc) { + pr_err("%s: Failed to set clip registers %d\n", + __func__, rc); + return rc; + } + } + + config_data = msm_codec_fn.get_afe_config_fn(component, + AFE_CLIP_BANK_SEL); + if (config_data) { + rc = afe_set_config(AFE_CLIP_BANK_SEL, + config_data, 0); + if (rc) { + pr_err("%s: Failed to set AFE bank selection %d\n", + __func__, rc); + return rc; + } + } + + config_data = msm_codec_fn.get_afe_config_fn(component, + AFE_CDC_REGISTER_PAGE_CONFIG); + if (config_data) { + rc = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data, + 0); + if (rc) + pr_err("%s: Failed to set cdc register page config\n", + __func__); + } + + return 0; +} + +static void msm_afe_clear_config(void) +{ + afe_clear_config(AFE_CDC_REGISTERS_CONFIG); + afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); +} + +static void msm_snd_interrupt_config(struct msm_asoc_mach_data *pdata) +{ + int val; + + val = ioread32(pdata->msm_snd_intr_lpi.mpm_wakeup); + val |= LPI_GPIO_22_WAKEUP_VAL; + iowrite32(val, pdata->msm_snd_intr_lpi.mpm_wakeup); + + val = ioread32(pdata->msm_snd_intr_lpi.intr1_cfg_apps); + val &= ~(LPI_GPIO_22_INTR1_CFG_MASK); + val |= LPI_GPIO_22_INTR1_CFG_VAL; + iowrite32(val, pdata->msm_snd_intr_lpi.intr1_cfg_apps); + + iowrite32(LPI_GPIO_INTR_CFG1_VAL, + pdata->msm_snd_intr_lpi.lpi_gpio_intr_cfg); + iowrite32(LPI_GPIO22_CFG_VAL, + pdata->msm_snd_intr_lpi.lpi_gpio_cfg); + + val = ioread32(pdata->msm_snd_intr_lpi.lpi_gpio_inout); + val |= LPI_GPIO22_INOUT_VAL; + iowrite32(val, pdata->msm_snd_intr_lpi.lpi_gpio_inout); +} + +static int msm_adsp_power_up_config(struct snd_soc_component *component, + struct snd_card *card) +{ + int ret = 0; + unsigned long timeout; + int adsp_ready = 0; + bool snd_card_online = 0; + struct snd_soc_card *soc_card = component->card; + struct msm_asoc_mach_data *pdata; + + pdata = snd_soc_card_get_drvdata(soc_card); + timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + + do { + if (!snd_card_online) { + snd_card_online = snd_card_is_online_state(card); + pr_debug("%s: Sound card is %s\n", __func__, + snd_card_online ? "Online" : "Offline"); + } + if (!adsp_ready) { + adsp_ready = q6core_is_adsp_ready(); + pr_debug("%s: ADSP Audio is %s\n", __func__, + adsp_ready ? "ready" : "not ready"); + } + if (snd_card_online && adsp_ready) + break; + + /* + * Sound card/ADSP will be coming up after subsystem restart and + * it might not be fully up when the control reaches + * here. So, wait for 50msec before checking ADSP state + */ + msleep(50); + } while (time_after(timeout, jiffies)); + + if (!snd_card_online || !adsp_ready) { + pr_err("%s: Timeout. Sound card is %s, ADSP Audio is %s\n", + __func__, + snd_card_online ? "Online" : "Offline", + adsp_ready ? "ready" : "not ready"); + ret = -ETIMEDOUT; + goto err_fail; + } + + if (socinfo_get_id() == SDM660_SOC_MSM_ID) + msm_snd_interrupt_config(pdata); + + ret = msm_afe_set_config(component); + if (ret) + pr_err("%s: Failed to set AFE config. err %d\n", + __func__, ret); + + return 0; + +err_fail: + return ret; +} + +static int sdm660_notifier_service_cb(struct notifier_block *this, + unsigned long opcode, void *ptr) +{ + int ret; + struct snd_soc_card *card = NULL; + struct snd_soc_dai *codec_dai; + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + struct snd_soc_component *component; + + pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); + + switch (opcode) { + case AUDIO_NOTIFIER_SERVICE_DOWN: + /* + * Use flag to ignore initial boot notifications + * On initial boot msm_adsp_power_up_config is + * called on init. There is no need to clear + * and set the config again on initial boot. + */ + if (is_initial_boot) + break; + msm_afe_clear_config(); + break; + case AUDIO_NOTIFIER_SERVICE_UP: + if (is_initial_boot) { + is_initial_boot = false; + break; + } + if (!spdev) + return -EINVAL; + + card = platform_get_drvdata(spdev); + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto done; + } + codec_dai = rtd->codec_dai; + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) + component = snd_soc_rtdcom_lookup(rtd, "tavil_codec"); + else if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) + component = snd_soc_rtdcom_lookup(rtd, "tasha_codec"); + ret = msm_adsp_power_up_config(component, card->snd_card); + if (ret < 0) { + dev_err(card->dev, + "%s: msm_adsp_power_up_config failed ret = %d!\n", + __func__, ret); + goto done; + } + break; + default: + break; + } +done: + return NOTIFY_OK; +} + +static struct notifier_block service_nb = { + .notifier_call = sdm660_notifier_service_cb, + .priority = -INT_MAX, +}; + +static int msm_config_hph_en0_gpio(struct snd_soc_component *component, + bool high) +{ + struct snd_soc_card *card = component->card; + struct msm_asoc_mach_data *pdata; + int val; + + if (!card) + return 0; + + pdata = snd_soc_card_get_drvdata(card); + if (!pdata || !gpio_is_valid(pdata->hph_en0_gpio)) + return 0; + + val = gpio_get_value_cansleep(pdata->hph_en0_gpio); + if ((!!val) == high) + return 0; + + gpio_direction_output(pdata->hph_en0_gpio, (int)high); + + return 1; +} + +static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_component *component, + int enable, bool dapm) +{ + int ret = 0; + + if (!strcmp(dev_name(component->dev), "tasha_codec")) + ret = tasha_cdc_mclk_tx_enable(component, enable, dapm); + else { + dev_err(component->dev, "%s: unknown codec to enable ext clk\n", + __func__); + ret = -EINVAL; + } + return ret; +} + +static int msm_ext_mclk_tx_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + + pr_debug("%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return msm_snd_enable_codec_ext_tx_clk(component, 1, true); + case SND_SOC_DAPM_POST_PMD: + return msm_snd_enable_codec_ext_tx_clk(component, 0, true); + } + return 0; +} + +static int msm_ext_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + + pr_debug("%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return msm_ext_enable_codec_mclk(component, 1, true); + case SND_SOC_DAPM_POST_PMD: + return msm_ext_enable_codec_mclk(component, 0, true); + } + return 0; +} + +static int msm_ext_prepare_hifi(struct msm_asoc_mach_data *pdata) +{ + int ret = 0; + + if (gpio_is_valid(pdata->hph_en1_gpio)) { + pr_debug("%s: hph_en1_gpio request %d\n", __func__, + pdata->hph_en1_gpio); + ret = gpio_request(pdata->hph_en1_gpio, "hph_en1_gpio"); + if (ret) { + pr_err("%s: hph_en1_gpio request failed, ret:%d\n", + __func__, ret); + goto err; + } + } + if (gpio_is_valid(pdata->hph_en0_gpio)) { + pr_debug("%s: hph_en0_gpio request %d\n", __func__, + pdata->hph_en0_gpio); + ret = gpio_request(pdata->hph_en0_gpio, "hph_en0_gpio"); + if (ret) + pr_err("%s: hph_en0_gpio request failed, ret:%d\n", + __func__, ret); + } + +err: + return ret; +} + +static const struct snd_soc_dapm_widget msm_dapm_widgets[] = { + + SND_SOC_DAPM_SUPPLY_S("MCLK", -1, SND_SOC_NOPM, 0, 0, + msm_ext_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("MCLK TX", -1, SND_SOC_NOPM, 0, 0, + msm_ext_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SPK("Lineout_1 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_3 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_2 amp", NULL), + SND_SOC_DAPM_SPK("Lineout_4 amp", NULL), + SND_SOC_DAPM_MIC("Handset Mic", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Secondary Mic", NULL), + SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL), + SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL), + SND_SOC_DAPM_MIC("Analog Mic4", NULL), + SND_SOC_DAPM_MIC("Analog Mic6", NULL), + SND_SOC_DAPM_MIC("Analog Mic7", NULL), + SND_SOC_DAPM_MIC("Analog Mic8", NULL), + + SND_SOC_DAPM_MIC("Digital Mic0", NULL), + SND_SOC_DAPM_MIC("Digital Mic1", NULL), + SND_SOC_DAPM_MIC("Digital Mic2", NULL), + SND_SOC_DAPM_MIC("Digital Mic3", NULL), + SND_SOC_DAPM_MIC("Digital Mic4", NULL), + SND_SOC_DAPM_MIC("Digital Mic5", NULL), + SND_SOC_DAPM_MIC("Digital Mic6", NULL), +}; + +static struct snd_soc_dapm_route wcd_audio_paths_tasha[] = { + {"MIC BIAS1", NULL, "MCLK TX"}, + {"MIC BIAS2", NULL, "MCLK TX"}, + {"MIC BIAS3", NULL, "MCLK TX"}, + {"MIC BIAS4", NULL, "MCLK TX"}, +}; + +static struct snd_soc_dapm_route wcd_audio_paths[] = { + {"MIC BIAS1", NULL, "MCLK"}, + {"MIC BIAS2", NULL, "MCLK"}, + {"MIC BIAS3", NULL, "MCLK"}, + {"MIC BIAS4", NULL, "MCLK"}, +}; + +int msm_snd_card_tasha_late_probe(struct snd_soc_card *card) +{ + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + void *mbhc_calibration; + struct snd_soc_component *component = NULL; + + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err_pcm_runtime; + } + + component = snd_soc_rtdcom_lookup(rtd, "tasha_codec"); + if (!component) { + dev_err(card->dev, "%s: component is NULL\n", __func__); + ret = -EINVAL; + goto err_pcm_runtime; + } + + mbhc_calibration = def_ext_mbhc_cal(); + if (!mbhc_calibration) { + ret = -ENOMEM; + goto err_mbhc_cal; + } + wcd_mbhc_cfg_ptr->calibration = mbhc_calibration; + ret = tasha_mbhc_hs_detect(component, wcd_mbhc_cfg_ptr); + if (ret) { + dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", + __func__, ret); + goto err_hs_detect; + } + return 0; + +err_hs_detect: + kfree(mbhc_calibration); +err_mbhc_cal: +err_pcm_runtime: + return ret; +} + +int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) +{ + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + void *mbhc_calibration; + struct snd_soc_component *component = NULL; + + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err; + } + + component = snd_soc_rtdcom_lookup(rtd, "tavil_codec"); + if (!component) { + dev_err(card->dev, "%s: component is NULL\n", __func__); + ret = -EINVAL; + goto err; + } + + mbhc_calibration = def_ext_mbhc_cal(); + if (!mbhc_calibration) { + ret = -ENOMEM; + goto err; + } + wcd_mbhc_cfg_ptr->calibration = mbhc_calibration; + ret = tavil_mbhc_hs_detect(component, wcd_mbhc_cfg_ptr); + if (ret) { + dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", + __func__, ret); + goto err_free_mbhc_cal; + } + return 0; + +err_free_mbhc_cal: + kfree(mbhc_calibration); +err: + return ret; +} + +/** + * msm_audrx_init - Audio init function of sound card instantiate. + * + * @rtd: runtime dailink instance + * + * Returns 0 on success or ret on failure. + */ +int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret; + void *config_data; + struct snd_soc_component *component; + struct snd_soc_dapm_context *dapm; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_component *aux_comp; + struct snd_card *card = rtd->card->snd_card; + struct snd_info_entry *entry; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); + + /* Codec SLIMBUS configuration + * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13 + * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 + * TX14, TX15, TX16 + */ + unsigned int rx_ch[TASHA_RX_MAX] = {144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156}; + unsigned int tx_ch[TASHA_TX_MAX] = {128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143}; + + /* Tavil Codec SLIMBUS configuration + * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8 + * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 + * TX14, TX15, TX16 + */ + unsigned int rx_ch_tavil[WCD934X_RX_MAX] = {144, 145, 146, 147, 148, + 149, 150, 151}; + unsigned int tx_ch_tavil[WCD934X_TX_MAX] = {128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143}; + + pr_debug("%s: dev_name%s\n", __func__, dev_name(cpu_dai->dev)); + + rtd->pmdown_time = 0; + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) + component = snd_soc_rtdcom_lookup(rtd, "tavil_codec"); + else if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) + component = snd_soc_rtdcom_lookup(rtd, "tasha_codec"); + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + dapm = snd_soc_component_get_dapm(component); + + ret = snd_soc_add_component_controls(component, msm_snd_controls, + ARRAY_SIZE(msm_snd_controls)); + if (ret < 0) { + pr_err("%s: add_codec_controls failed: %d\n", + __func__, ret); + return ret; + } + + ret = snd_soc_add_component_controls(component, msm_common_snd_controls, + msm_common_snd_controls_size()); + if (ret < 0) { + pr_err("%s: add_common_snd_controls failed: %d\n", + __func__, ret); + return ret; + } + + snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, + ARRAY_SIZE(msm_dapm_widgets)); + + if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) + snd_soc_dapm_add_routes(dapm, wcd_audio_paths_tasha, + ARRAY_SIZE(wcd_audio_paths_tasha)); + else + snd_soc_dapm_add_routes(dapm, wcd_audio_paths, + ARRAY_SIZE(wcd_audio_paths)); + + snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp"); + snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp"); + snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp"); + snd_soc_dapm_enable_pin(dapm, "Lineout_4 amp"); + + snd_soc_dapm_ignore_suspend(dapm, "MADINPUT"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT"); + snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Secondary Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Lineout_1 amp"); + snd_soc_dapm_ignore_suspend(dapm, "Lineout_3 amp"); + snd_soc_dapm_ignore_suspend(dapm, "Lineout_2 amp"); + snd_soc_dapm_ignore_suspend(dapm, "Lineout_4 amp"); + snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic7"); + snd_soc_dapm_ignore_suspend(dapm, "Analog Mic8"); + + snd_soc_dapm_ignore_suspend(dapm, "EAR"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC4"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC5"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC0"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC4"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC5"); + snd_soc_dapm_ignore_suspend(dapm, "ANC EAR"); + snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI"); + snd_soc_dapm_ignore_suspend(dapm, "VIINPUT"); + + if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) { + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3"); + snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL"); + snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR"); + snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT1"); + snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT2"); + } else { + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT1"); + snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT2"); + } + + snd_soc_dapm_sync(dapm); + + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { + snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch_tavil), + tx_ch_tavil, ARRAY_SIZE(rx_ch_tavil), + rx_ch_tavil); + } else { + snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), + rx_ch); + } + + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { + msm_codec_fn.get_afe_config_fn = tavil_get_afe_config; + } else { + msm_codec_fn.get_afe_config_fn = tasha_get_afe_config; + msm_codec_fn.mbhc_hs_detect_exit = tasha_mbhc_hs_detect_exit; + } + + ret = msm_adsp_power_up_config(component, rtd->card->snd_card); + if (ret) { + pr_err("%s: Failed to set AFE config %d\n", __func__, ret); + goto err_afe_cfg; + } + + config_data = msm_codec_fn.get_afe_config_fn(component, + AFE_AANC_VERSION); + if (config_data) { + ret = afe_set_config(AFE_AANC_VERSION, config_data, 0); + if (ret) { + pr_err("%s: Failed to set aanc version %d\n", + __func__, ret); + goto err_afe_cfg; + } + } + + if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) { + config_data = msm_codec_fn.get_afe_config_fn(component, + AFE_CDC_CLIP_REGISTERS_CONFIG); + if (config_data) { + ret = afe_set_config(AFE_CDC_CLIP_REGISTERS_CONFIG, + config_data, 0); + if (ret) { + pr_err("%s: Failed to set clip registers %d\n", + __func__, ret); + goto err_afe_cfg; + } + } + config_data = msm_codec_fn.get_afe_config_fn(component, + AFE_CLIP_BANK_SEL); + if (config_data) { + ret = afe_set_config(AFE_CLIP_BANK_SEL, config_data, 0); + if (ret) { + pr_err("%s: Failed to set AFE bank selection %d\n", + __func__, ret); + goto err_afe_cfg; + } + } + } + + /* + * Send speaker configuration only for WSA8810. + * Defalut configuration is for WSA8815. + */ + pr_debug("%s: Number of aux devices: %d\n", + __func__, rtd->card->num_aux_devs); + + if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->aux_comp_list)) { + aux_comp = list_first_entry(&rtd->card->aux_comp_list, + struct snd_soc_component, card_aux_list); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { + tavil_set_spkr_mode(component, SPKR_MODE_1); + tavil_set_spkr_gain_offset(component, + RX_GAIN_OFFSET_M1P5_DB); + } + } + card = rtd->card->snd_card; + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + goto done; + } + pdata->codec_root = entry; + tavil_codec_info_create_codec_entry(pdata->codec_root, + component); + } else { + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->aux_comp_list)) { + aux_comp = list_first_entry(&rtd->card->aux_comp_list, + struct snd_soc_component, card_aux_list); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { + tasha_set_spkr_mode(component, SPKR_MODE_1); + tasha_set_spkr_gain_offset(component, + RX_GAIN_OFFSET_M1P5_DB); + } + } + card = rtd->card->snd_card; + entry = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!entry) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + goto done; + } + pdata->codec_root = entry; + tasha_codec_info_create_codec_entry(pdata->codec_root, + component); + tasha_mbhc_zdet_gpio_ctrl(msm_config_hph_en0_gpio, + component); + } +done: + msm_set_codec_reg_done(true); + return 0; + +err_afe_cfg: + return ret; +} +EXPORT_SYMBOL(msm_audrx_init); + +/** + * msm_ext_register_audio_notifier - register SSR notifier. + */ +void msm_ext_register_audio_notifier(struct platform_device *pdev) +{ + int ret; + + is_initial_boot = true; + spdev = pdev; + ret = audio_notifier_register("sdm660", AUDIO_NOTIFIER_ADSP_DOMAIN, + &service_nb); + if (ret < 0) + pr_err("%s: Audio notifier register failed ret = %d\n", + __func__, ret); +} +EXPORT_SYMBOL(msm_ext_register_audio_notifier); + +/** + * msm_ext_cdc_init - external codec machine specific init. + * + * @pdev: platform device handle + * @pdata: private data of machine driver + * @card: sound card pointer reference + * @mbhc_cfg: MBHC config reference + * + * Returns 0 on success or ret on failure. + */ +int msm_ext_cdc_init(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata, + struct snd_soc_card **card, + struct wcd_mbhc_config *wcd_mbhc_cfg_ptr1) +{ + int ret = 0; + + wcd_mbhc_cfg_ptr = wcd_mbhc_cfg_ptr1; + pdev->id = 0; + wcd_mbhc_cfg_ptr->moisture_en = true; + wcd_mbhc_cfg_ptr->mbhc_micbias = MIC_BIAS_2; + wcd_mbhc_cfg_ptr->anc_micbias = MIC_BIAS_2; + wcd_mbhc_cfg_ptr->enable_anc_mic_detect = false; + + *card = populate_snd_card_dailinks(&pdev->dev, pdata->snd_card_val); + if (!(*card)) { + dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); + ret = -EPROBE_DEFER; + goto err; + } + platform_set_drvdata(pdev, *card); + snd_soc_card_set_drvdata(*card, pdata); + pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,hph-en1-gpio", 0); + if (!gpio_is_valid(pdata->hph_en1_gpio)) + pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en1-gpio", 0); + if (!gpio_is_valid(pdata->hph_en1_gpio) && (!pdata->hph_en1_gpio_p)) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,hph-en1-gpio", pdev->dev.of_node->full_name); + } + + pdata->hph_en0_gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,hph-en0-gpio", 0); + if (!gpio_is_valid(pdata->hph_en0_gpio)) + pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node, + "qcom,hph-en0-gpio", 0); + if (!gpio_is_valid(pdata->hph_en0_gpio) && (!pdata->hph_en0_gpio_p)) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + "qcom,hph-en0-gpio", pdev->dev.of_node->full_name); + } + + ret = msm_ext_prepare_hifi(pdata); + if (ret) { + dev_dbg(&pdev->dev, "msm_ext_prepare_hifi failed (%d)\n", + ret); + ret = 0; + } + pdata->msm_snd_intr_lpi.mpm_wakeup = + ioremap(TLMM_CENTER_MPM_WAKEUP_INT_EN_0, 4); + pdata->msm_snd_intr_lpi.intr1_cfg_apps = + ioremap(TLMM_LPI_DIR_CONN_INTR1_CFG_APPS, 4); + pdata->msm_snd_intr_lpi.lpi_gpio_intr_cfg = + ioremap(TLMM_LPI_GPIO_INTR_CFG1, 4); + pdata->msm_snd_intr_lpi.lpi_gpio_cfg = + ioremap(TLMM_LPI_GPIO22_CFG, 4); + pdata->msm_snd_intr_lpi.lpi_gpio_inout = + ioremap(TLMM_LPI_GPIO22_INOUT, 4); +err: + return ret; +} +EXPORT_SYMBOL(msm_ext_cdc_init); + +/** + * msm_ext_cdc_deinit - external codec machine specific deinit. + */ +void msm_ext_cdc_deinit(struct msm_asoc_mach_data *pdata) +{ + if (pdata->msm_snd_intr_lpi.mpm_wakeup) + iounmap(pdata->msm_snd_intr_lpi.mpm_wakeup); + if (pdata->msm_snd_intr_lpi.intr1_cfg_apps) + iounmap(pdata->msm_snd_intr_lpi.intr1_cfg_apps); + if (pdata->msm_snd_intr_lpi.lpi_gpio_intr_cfg) + iounmap(pdata->msm_snd_intr_lpi.lpi_gpio_intr_cfg); + if (pdata->msm_snd_intr_lpi.lpi_gpio_cfg) + iounmap(pdata->msm_snd_intr_lpi.lpi_gpio_cfg); + if (pdata->msm_snd_intr_lpi.lpi_gpio_inout) + iounmap(pdata->msm_snd_intr_lpi.lpi_gpio_inout); +} +EXPORT_SYMBOL(msm_ext_cdc_deinit); diff --git a/asoc/sdm660-internal.c b/asoc/sdm660-internal.c new file mode 100644 index 000000000000..f1ae71951e9e --- /dev/null +++ b/asoc/sdm660-internal.c @@ -0,0 +1,3206 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include "msm-pcm-routing-v2.h" +#include +#include +#include "codecs/sdm660_cdc/msm-digital-cdc.h" +#include "codecs/sdm660_cdc/msm-analog-cdc.h" +#include "codecs/msm_sdw/msm_sdw.h" +#include + +#define __CHIPSET__ "SDM660 " +#define MSM_DAILINK_NAME(name) (__CHIPSET__#name) + +#define WCD_MBHC_DEF_RLOADS 5 + +#define WCN_CDC_SLIM_RX_CH_MAX 2 +#define WCN_CDC_SLIM_TX_CH_MAX 3 + +#define WSA8810_NAME_1 "wsa881x.20170211" +#define WSA8810_NAME_2 "wsa881x.20170212" +#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */ +enum { + INT0_MI2S = 0, + INT1_MI2S, + INT2_MI2S, + INT3_MI2S, + INT4_MI2S, + INT5_MI2S, + INT6_MI2S, + INT_MI2S_MAX, +}; + +enum { + BT_SLIM7, + FM_SLIM8, + SLIM_MAX, +}; + +static struct afe_clk_set int_mi2s_clk[INT_MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_INT0_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_INT1_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_INT2_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_INT3_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_INT4_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_INT5_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_INT6_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, +}; + +/* Default configuration of MI2S channels */ +static struct dev_config int_mi2s_cfg[] = { + [INT0_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [INT1_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [INT2_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [INT3_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [INT4_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [INT5_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, + [INT6_MI2S] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static struct dev_config bt_fm_cfg[] = { + [BT_SLIM7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [FM_SLIM8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + +static char const *int_mi2s_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_96", "KHZ_192"}; +static const char *const int_mi2s_ch_text[] = {"One", "Two"}; +static const char *const int_mi2s_tx_ch_text[] = {"One", "Two", + "Three", "Four"}; +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"}; +static const char *const loopback_mclk_text[] = {"DISABLE", "ENABLE"}; +static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", + "KHZ_44P1", "KHZ_48", + "KHZ_88P2", "KHZ_96"}; + +static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_sample_rate, int_mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_chs, int_mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(int2_mi2s_tx_sample_rate, int_mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(int2_mi2s_tx_chs, int_mi2s_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(int2_mi2s_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(int3_mi2s_tx_sample_rate, int_mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(int3_mi2s_tx_chs, int_mi2s_tx_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(int3_mi2s_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_sample_rate, int_mi2s_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_chs, int_mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(int5_mi2s_tx_chs, int_mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(loopback_mclk_en, loopback_mclk_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); + +static int msm_dmic_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); +static int msm_int_enable_dig_cdc_clk(struct snd_soc_component *component, + int enable, bool dapm); +static int msm_int_mclk0_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); +static int msm_int_mi2s_snd_startup(struct snd_pcm_substream *substream); +static void msm_int_mi2s_snd_shutdown(struct snd_pcm_substream *substream); + +static struct wcd_mbhc_config *mbhc_cfg_ptr; +static struct snd_info_entry *codec_root; + +static int int_mi2s_get_bit_format_val(int bit_format) +{ + int val = 0; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S24_3LE: + val = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + val = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + val = 0; + break; + } + return val; +} + +static int int_mi2s_get_bit_format(int val) +{ + int bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + + switch (val) { + case 0: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + bit_fmt = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + bit_fmt = SNDRV_PCM_FORMAT_S24_3LE; + break; + default: + bit_fmt = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return bit_fmt; +} + +static int int_mi2s_get_port_idx(struct snd_kcontrol *kcontrol) +{ + int port_id = 0; + + if (strnstr(kcontrol->id.name, "INT0_MI2S", sizeof("INT0_MI2S"))) + port_id = INT0_MI2S; + else if (strnstr(kcontrol->id.name, "INT2_MI2S", sizeof("INT2_MI2S"))) + port_id = INT2_MI2S; + else if (strnstr(kcontrol->id.name, "INT3_MI2S", sizeof("INT3_MI2S"))) + port_id = INT3_MI2S; + else if (strnstr(kcontrol->id.name, "INT4_MI2S", sizeof("INT4_MI2S"))) + port_id = INT4_MI2S; + else { + pr_err("%s: unsupported channel: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + + return port_id; +} + +static int int_mi2s_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = int_mi2s_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + ucontrol->value.enumerated.item[0] = + int_mi2s_get_bit_format_val(int_mi2s_cfg[ch_num].bit_format); + + pr_debug("%s: int_mi2s[%d]_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, int_mi2s_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int int_mi2s_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ch_num = int_mi2s_get_port_idx(kcontrol); + + if (ch_num < 0) + return ch_num; + + int_mi2s_cfg[ch_num].bit_format = + int_mi2s_get_bit_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: int_mi2s[%d]_rx_bit_format = %d, ucontrol value = %d\n", + __func__, ch_num, int_mi2s_cfg[ch_num].bit_format, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, + int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + +static int int_mi2s_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 6; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int int_mi2s_get_sample_rate(int value) +{ + int sample_rate; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_192KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int int_mi2s_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = int_mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + int_mi2s_cfg[idx].sample_rate = + int_mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: idx[%d]_sample_rate = %d, item = %d\n", __func__, + idx, int_mi2s_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int int_mi2s_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = int_mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + ucontrol->value.enumerated.item[0] = + int_mi2s_get_sample_rate_val(int_mi2s_cfg[idx].sample_rate); + + pr_debug("%s: idx[%d]_sample_rate = %d, item = %d\n", __func__, + idx, int_mi2s_cfg[idx].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static int int_mi2s_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = int_mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + pr_debug("%s: int_mi2s_[%d]_rx_ch = %d\n", __func__, + idx, int_mi2s_cfg[idx].channels); + ucontrol->value.enumerated.item[0] = int_mi2s_cfg[idx].channels - 1; + + return 0; +} + +static int int_mi2s_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int idx = int_mi2s_get_port_idx(kcontrol); + + if (idx < 0) + return idx; + + int_mi2s_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1; + pr_debug("%s: int_mi2s_[%d]_ch = %d\n", __func__, + idx, int_mi2s_cfg[idx].channels); + + return 1; +} + +static const struct snd_soc_dapm_widget msm_int_dapm_widgets[] = { + SND_SOC_DAPM_SUPPLY_S("INT_MCLK0", -1, SND_SOC_NOPM, 0, 0, + msm_int_mclk0_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIC("Handset Mic", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Secondary Mic", NULL), + SND_SOC_DAPM_MIC("Digital Mic1", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic2", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic3", msm_dmic_event), + SND_SOC_DAPM_MIC("Digital Mic4", msm_dmic_event), +}; + +static int msm_config_hph_compander_gpio(bool enable, + struct snd_soc_component *component) +{ + struct snd_soc_card *card = component->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + int ret = 0; + + pr_debug("%s: %s HPH Compander\n", __func__, + enable ? "Enable" : "Disable"); + + if (enable) { + ret = msm_cdc_pinctrl_select_active_state(pdata->comp_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be activated %s\n", + __func__, "comp_gpio"); + goto done; + } + } else { + ret = msm_cdc_pinctrl_select_sleep_state(pdata->comp_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be de-activated %s\n", + __func__, "comp_gpio"); + goto done; + } + } + +done: + return ret; +} + +static int is_ext_spk_gpio_support(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata) +{ + const char *spk_ext_pa = "qcom,msm-spk-ext-pa"; + + pr_debug("%s:Enter\n", __func__); + + pdata->spk_ext_pa_gpio = of_get_named_gpio(pdev->dev.of_node, + spk_ext_pa, 0); + + if (pdata->spk_ext_pa_gpio < 0) { + dev_dbg(&pdev->dev, + "%s: missing %s in dt node\n", __func__, spk_ext_pa); + } else { + if (!gpio_is_valid(pdata->spk_ext_pa_gpio)) { + pr_err("%s: Invalid external speaker gpio: %d", + __func__, pdata->spk_ext_pa_gpio); + return -EINVAL; + } + } + return 0; +} + +static int enable_spk_ext_pa(struct snd_soc_component *component, int enable) +{ + struct snd_soc_card *card = component->card; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); + int ret; + + if (!gpio_is_valid(pdata->spk_ext_pa_gpio)) { + pr_err("%s: Invalid gpio: %d\n", __func__, + pdata->spk_ext_pa_gpio); + return false; + } + + pr_debug("%s: %s external speaker PA\n", __func__, + enable ? "Enable" : "Disable"); + + if (enable) { + ret = msm_cdc_pinctrl_select_active_state( + pdata->ext_spk_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be de-activated %s\n", + __func__, "ext_spk_gpio"); + return ret; + } + gpio_set_value_cansleep(pdata->spk_ext_pa_gpio, enable); + } else { + gpio_set_value_cansleep(pdata->spk_ext_pa_gpio, enable); + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->ext_spk_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be de-activated %s\n", + __func__, "ext_spk_gpio"); + return ret; + } + } + return 0; +} + +static int int_mi2s_get_idx_from_beid(int32_t id) +{ + int idx = 0; + + switch (id) { + case MSM_BACKEND_DAI_INT0_MI2S_RX: + idx = INT0_MI2S; + break; + case MSM_BACKEND_DAI_INT2_MI2S_TX: + idx = INT2_MI2S; + break; + case MSM_BACKEND_DAI_INT3_MI2S_TX: + idx = INT3_MI2S; + break; + case MSM_BACKEND_DAI_INT4_MI2S_RX: + idx = INT4_MI2S; + break; + case MSM_BACKEND_DAI_INT5_MI2S_TX: + idx = INT5_MI2S; + break; + default: + idx = INT0_MI2S; + break; + } + + return idx; +} + +static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + pr_debug("%s()\n", __func__); + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + + return 0; +} + +static int int_mi2s_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + int idx; + + pr_debug("%s: format = %d, rate = %d\n", + __func__, params_format(params), params_rate(params)); + + switch (dai_link->id) { + case MSM_BACKEND_DAI_INT0_MI2S_RX: + case MSM_BACKEND_DAI_INT2_MI2S_TX: + case MSM_BACKEND_DAI_INT3_MI2S_TX: + case MSM_BACKEND_DAI_INT4_MI2S_RX: + case MSM_BACKEND_DAI_INT5_MI2S_TX: + idx = int_mi2s_get_idx_from_beid(dai_link->id); + rate->min = rate->max = int_mi2s_cfg[idx].sample_rate; + channels->min = channels->max = + int_mi2s_cfg[idx].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + int_mi2s_cfg[idx].bit_format); + break; + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + return 0; +} + +static int msm_btfm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + switch (dai_link->id) { + case MSM_BACKEND_DAI_SLIMBUS_7_RX: + case MSM_BACKEND_DAI_SLIMBUS_7_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + bt_fm_cfg[BT_SLIM7].bit_format); + rate->min = rate->max = bt_fm_cfg[BT_SLIM7].sample_rate; + channels->min = channels->max = + bt_fm_cfg[BT_SLIM7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_8_TX: + rate->min = rate->max = bt_fm_cfg[FM_SLIM8].sample_rate; + channels->min = channels->max = + bt_fm_cfg[FM_SLIM8].channels; + break; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + return 0; +} + +static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = + (int_mi2s_cfg[INT5_MI2S].channels/2 - 1); + pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int_mi2s_cfg[INT5_MI2S].channels = + roundup_pow_of_two(ucontrol->value.integer.value[0] + 2); + + pr_debug("%s: msm_vi_feed_tx_ch = %d\n", + __func__, int_mi2s_cfg[INT5_MI2S].channels); + return 1; +} + +static int msm_int_enable_dig_cdc_clk(struct snd_soc_component *component, + int enable, bool dapm) +{ + int ret = 0; + struct msm_asoc_mach_data *pdata = NULL; + int clk_freq_in_hz; + bool int_mclk0_freq_chg = false; + + pdata = snd_soc_card_get_drvdata(component->card); + pr_debug("%s: enable %d mclk ref counter %d\n", + __func__, enable, + atomic_read(&pdata->int_mclk0_rsc_ref)); + if (enable) { + if (int_mi2s_cfg[INT0_MI2S].sample_rate == + SAMPLING_RATE_44P1KHZ) { + clk_freq_in_hz = NATIVE_MCLK_RATE; + pdata->native_clk_set = true; + } else { + clk_freq_in_hz = pdata->mclk_freq; + pdata->native_clk_set = false; + } + + if (pdata->digital_cdc_core_clk.clk_freq_in_hz + != clk_freq_in_hz) + int_mclk0_freq_chg = true; + if (!atomic_read(&pdata->int_mclk0_rsc_ref) || + int_mclk0_freq_chg) { + cancel_delayed_work_sync( + &pdata->disable_int_mclk0_work); + mutex_lock(&pdata->cdc_int_mclk0_mutex); + if (atomic_read(&pdata->int_mclk0_enabled) == false || + int_mclk0_freq_chg) { + if (atomic_read(&pdata->int_mclk0_enabled)) { + pdata->digital_cdc_core_clk.enable = 0; + afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + } + pdata->digital_cdc_core_clk.clk_freq_in_hz = + clk_freq_in_hz; + pdata->digital_cdc_core_clk.enable = 1; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + if (ret < 0) { + pr_err("%s: failed to enable CCLK\n", + __func__); + mutex_unlock( + &pdata->cdc_int_mclk0_mutex); + return ret; + } + pr_debug("enabled digital codec core clk\n"); + atomic_set(&pdata->int_mclk0_enabled, true); + } + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + } + atomic_inc(&pdata->int_mclk0_rsc_ref); + } else { + cancel_delayed_work_sync(&pdata->disable_int_mclk0_work); + mutex_lock(&pdata->cdc_int_mclk0_mutex); + if (atomic_read(&pdata->int_mclk0_enabled) == true) { + pdata->digital_cdc_core_clk.clk_freq_in_hz = + DEFAULT_MCLK_RATE; + pdata->digital_cdc_core_clk.enable = 0; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + if (ret < 0) + pr_err("%s: failed to disable CCLK\n", + __func__); + atomic_set(&pdata->int_mclk0_enabled, false); + atomic_set(&pdata->int_mclk0_rsc_ref, 0); + } + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + } + return ret; +} + +static int loopback_mclk_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s\n", __func__); + return 0; +} + +static int loopback_mclk_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = -EINVAL; + struct msm_asoc_mach_data *pdata = NULL; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + + pdata = snd_soc_card_get_drvdata(component->card); + pr_debug("%s: mclk_rsc_ref %d enable %ld\n", + __func__, atomic_read(&pdata->int_mclk0_rsc_ref), + ucontrol->value.integer.value[0]); + switch (ucontrol->value.integer.value[0]) { + case 1: + ret = msm_cdc_pinctrl_select_active_state(pdata->pdm_gpio_p); + if (ret) { + pr_err("%s: failed to enable the pri gpios: %d\n", + __func__, ret); + break; + } + mutex_lock(&pdata->cdc_int_mclk0_mutex); + if ((!atomic_read(&pdata->int_mclk0_rsc_ref)) && + (!atomic_read(&pdata->int_mclk0_enabled))) { + pdata->digital_cdc_core_clk.enable = 1; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + if (ret < 0) { + pr_err("%s: failed to enable the MCLK: %d\n", + __func__, ret); + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->pdm_gpio_p); + if (ret) + pr_err("%s: failed to disable the pri gpios: %d\n", + __func__, ret); + break; + } + atomic_set(&pdata->int_mclk0_enabled, true); + } + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + atomic_inc(&pdata->int_mclk0_rsc_ref); + msm_anlg_cdc_mclk_enable(component, 1, true); + break; + case 0: + if (atomic_read(&pdata->int_mclk0_rsc_ref) <= 0) + break; + msm_anlg_cdc_mclk_enable(component, 0, true); + mutex_lock(&pdata->cdc_int_mclk0_mutex); + if ((!atomic_dec_return(&pdata->int_mclk0_rsc_ref)) && + (atomic_read(&pdata->int_mclk0_enabled))) { + pdata->digital_cdc_core_clk.enable = 0; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + if (ret < 0) { + pr_err("%s: failed to disable the CCLK: %d\n", + __func__, ret); + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + break; + } + atomic_set(&pdata->int_mclk0_enabled, false); + } + mutex_unlock(&pdata->cdc_int_mclk0_mutex); + ret = msm_cdc_pinctrl_select_sleep_state(pdata->pdm_gpio_p); + if (ret) + pr_err("%s: failed to disable the pri gpios: %d\n", + __func__, ret); + break; + default: + pr_err("%s: Unexpected input value\n", __func__); + break; + } + return ret; +} + +static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* + * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) + * when used for BT_SCO use case. Return either Rx or Tx sample rate + * value. + */ + switch (bt_fm_cfg[BT_SLIM7].sample_rate) { + case SAMPLING_RATE_96KHZ: + ucontrol->value.integer.value[0] = 5; + break; + case SAMPLING_RATE_88P2KHZ: + ucontrol->value.integer.value[0] = 4; + break; + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 3; + break; + case SAMPLING_RATE_44P1KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate = %d", __func__, + bt_fm_cfg[BT_SLIM7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 3: + bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 4: + bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_88P2KHZ; + break; + case 5: + bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_96KHZ; + break; + case 0: + default: + bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rates: slim7_rx = %d, value = %d\n", + __func__, + bt_fm_cfg[BT_SLIM7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + +static const struct snd_kcontrol_new msm_snd_controls[] = { + SOC_ENUM_EXT("INT0_MI2S_RX Format", int0_mi2s_rx_format, + int_mi2s_bit_format_get, int_mi2s_bit_format_put), + SOC_ENUM_EXT("INT2_MI2S_TX Format", int2_mi2s_tx_format, + int_mi2s_bit_format_get, int_mi2s_bit_format_put), + SOC_ENUM_EXT("INT3_MI2S_TX Format", int3_mi2s_tx_format, + int_mi2s_bit_format_get, int_mi2s_bit_format_put), + SOC_ENUM_EXT("INT0_MI2S_RX SampleRate", int0_mi2s_rx_sample_rate, + int_mi2s_sample_rate_get, + int_mi2s_sample_rate_put), + SOC_ENUM_EXT("INT2_MI2S_TX SampleRate", int2_mi2s_tx_sample_rate, + int_mi2s_sample_rate_get, + int_mi2s_sample_rate_put), + SOC_ENUM_EXT("INT3_MI2S_TX SampleRate", int3_mi2s_tx_sample_rate, + int_mi2s_sample_rate_get, + int_mi2s_sample_rate_put), + SOC_ENUM_EXT("INT0_MI2S_RX Channels", int0_mi2s_rx_chs, + int_mi2s_ch_get, int_mi2s_ch_put), + SOC_ENUM_EXT("INT2_MI2S_TX Channels", int2_mi2s_tx_chs, + int_mi2s_ch_get, int_mi2s_ch_put), + SOC_ENUM_EXT("INT3_MI2S_TX Channels", int3_mi2s_tx_chs, + int_mi2s_ch_get, int_mi2s_ch_put), + SOC_ENUM_EXT("Loopback MCLK", loopback_mclk_en, + loopback_mclk_get, loopback_mclk_put), + SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), +}; + +static const struct snd_kcontrol_new msm_sdw_controls[] = { + SOC_ENUM_EXT("INT4_MI2S_RX Format", int4_mi2s_rx_format, + int_mi2s_bit_format_get, int_mi2s_bit_format_put), + SOC_ENUM_EXT("INT4_MI2S_RX SampleRate", int4_mi2s_rx_sample_rate, + int_mi2s_sample_rate_get, + int_mi2s_sample_rate_put), + SOC_ENUM_EXT("INT4_MI2S_RX Channels", int4_mi2s_rx_chs, + int_mi2s_ch_get, int_mi2s_ch_put), + SOC_ENUM_EXT("VI_FEED_TX Channels", int5_mi2s_tx_chs, + msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put), +}; + +static int msm_dmic_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct msm_asoc_mach_data *pdata = NULL; + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + int ret = 0; + + pdata = snd_soc_card_get_drvdata(component->card); + pr_debug("%s: event = %d\n", __func__, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = msm_cdc_pinctrl_select_active_state(pdata->dmic_gpio_p); + if (ret < 0) { + pr_err("%s: gpio set cannot be activated %sd", + __func__, "dmic_gpio"); + return ret; + } + break; + case SND_SOC_DAPM_POST_PMD: + ret = msm_cdc_pinctrl_select_sleep_state(pdata->dmic_gpio_p); + if (ret < 0) { + pr_err("%s: gpio set cannot be de-activated %sd", + __func__, "dmic_gpio"); + return ret; + } + break; + default: + pr_err("%s: invalid DAPM event %d\n", __func__, event); + return -EINVAL; + } + return 0; +} + +static int msm_int_mclk0_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct msm_asoc_mach_data *pdata = NULL; + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + int ret = 0; + + pdata = snd_soc_card_get_drvdata(component->card); + pr_debug("%s: event = %d\n", __func__, event); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = msm_cdc_pinctrl_select_active_state(pdata->pdm_gpio_p); + if (ret < 0) { + pr_err("%s: gpio set cannot be activated %s\n", + __func__, "int_pdm"); + return ret; + } + msm_int_enable_dig_cdc_clk(component, 1, true); + msm_anlg_cdc_mclk_enable(component, 1, true); + break; + case SND_SOC_DAPM_POST_PMD: + pr_debug("%s: mclk_res_ref = %d\n", + __func__, atomic_read(&pdata->int_mclk0_rsc_ref)); + ret = msm_cdc_pinctrl_select_sleep_state(pdata->pdm_gpio_p); + if (ret < 0) { + pr_err("%s: gpio set cannot be de-activated %sd", + __func__, "int_pdm"); + return ret; + } + pr_debug("%s: disabling MCLK\n", __func__); + /* disable the codec mclk config*/ + msm_anlg_cdc_mclk_enable(component, 0, true); + msm_int_enable_dig_cdc_clk(component, 0, true); + break; + default: + pr_err("%s: invalid DAPM event %d\n", __func__, event); + return -EINVAL; + } + return 0; +} + +static int int_mi2s_get_port_id(int id) +{ + int afe_port_id; + + switch (id) { + case MSM_BACKEND_DAI_INT0_MI2S_RX: + afe_port_id = AFE_PORT_ID_INT0_MI2S_RX; + break; + case MSM_BACKEND_DAI_INT2_MI2S_TX: + afe_port_id = AFE_PORT_ID_INT2_MI2S_TX; + break; + case MSM_BACKEND_DAI_INT3_MI2S_TX: + afe_port_id = AFE_PORT_ID_INT3_MI2S_TX; + break; + case MSM_BACKEND_DAI_INT4_MI2S_RX: + afe_port_id = AFE_PORT_ID_INT4_MI2S_RX; + break; + case MSM_BACKEND_DAI_INT5_MI2S_TX: + afe_port_id = AFE_PORT_ID_INT5_MI2S_TX; + break; + default: + pr_err("%s: Invalid id: %d\n", __func__, id); + afe_port_id = -EINVAL; + } + + return afe_port_id; +} + +static int int_mi2s_get_index(int port_id) +{ + int index; + + switch (port_id) { + case AFE_PORT_ID_INT0_MI2S_RX: + index = INT0_MI2S; + break; + case AFE_PORT_ID_INT2_MI2S_TX: + index = INT2_MI2S; + break; + case AFE_PORT_ID_INT3_MI2S_TX: + index = INT3_MI2S; + break; + case AFE_PORT_ID_INT4_MI2S_RX: + index = INT4_MI2S; + break; + case AFE_PORT_ID_INT5_MI2S_TX: + index = INT5_MI2S; + break; + default: + pr_err("%s: Invalid port_id: %d\n", __func__, port_id); + index = -EINVAL; + } + + return index; +} + +static u32 get_int_mi2s_bits_per_sample(u32 bit_format) +{ + u32 bit_per_sample; + + switch (bit_format) { + case SNDRV_PCM_FORMAT_S24_3LE: + case SNDRV_PCM_FORMAT_S24_LE: + bit_per_sample = 32; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bit_per_sample = 16; + break; + } + + return bit_per_sample; +} + +static void update_int_mi2s_clk_val(int idx, int stream) +{ + u32 bit_per_sample; + + bit_per_sample = + get_int_mi2s_bits_per_sample(int_mi2s_cfg[idx].bit_format); + int_mi2s_clk[idx].clk_freq_in_hz = + (int_mi2s_cfg[idx].sample_rate * 2 * bit_per_sample); +} + +static int int_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable) +{ + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int port_id = 0; + int index; + + port_id = int_mi2s_get_port_id(rtd->dai_link->id); + if (port_id < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto done; + } + index = int_mi2s_get_index(port_id); + if (index < 0) { + dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__); + ret = port_id; + goto done; + } + if (enable) { + update_int_mi2s_clk_val(index, substream->stream); + dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__, + int_mi2s_clk[index].clk_freq_in_hz); + } + + int_mi2s_clk[index].enable = enable; + ret = afe_set_lpass_clock_v2(port_id, + &int_mi2s_clk[index]); + if (ret < 0) { + dev_err(rtd->card->dev, + "%s: afe lpass clock failed for port 0x%x , err:%d\n", + __func__, port_id, ret); + goto done; + } + +done: + return ret; +} + +static int msm_sdw_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + ret = int_mi2s_set_sclk(substream, true); + if (ret < 0) { + pr_err("%s: failed to enable sclk %d\n", + __func__, ret); + return ret; + } + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + pr_err("%s: set fmt cpu dai failed; ret=%d\n", __func__, ret); + + return ret; +} + +static void msm_sdw_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + ret = int_mi2s_set_sclk(substream, false); + if (ret < 0) + pr_err("%s:clock disable failed; ret=%d\n", __func__, + ret); +} + +static int msm_int_mi2s_snd_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(rtd, "pmic_analog_codec"); + int ret = 0; + struct msm_asoc_mach_data *pdata = NULL; + + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + pdata = snd_soc_card_get_drvdata(component->card); + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + ret = int_mi2s_set_sclk(substream, true); + if (ret < 0) { + pr_err("%s: failed to enable sclk %d\n", + __func__, ret); + return ret; + } + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + pr_err("%s: set fmt cpu dai failed; ret=%d\n", __func__, ret); + + return ret; +} + +static void msm_int_mi2s_snd_shutdown(struct snd_pcm_substream *substream) +{ + int ret; + + pr_debug("%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); + + ret = int_mi2s_set_sclk(substream, false); + if (ret < 0) + pr_err("%s:clock disable failed; ret=%d\n", __func__, + ret); +} + +static void *def_msm_int_wcd_mbhc_cal(void) +{ + void *msm_int_wcd_cal; + struct wcd_mbhc_btn_detect_cfg *btn_cfg; + u16 *btn_low, *btn_high; + + msm_int_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, + WCD_MBHC_DEF_RLOADS), GFP_KERNEL); + if (!msm_int_wcd_cal) + return NULL; + +#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(msm_int_wcd_cal)->X) = (Y)) + S(v_hs_max, 1500); +#undef S +#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(msm_int_wcd_cal)->X) = (Y)) + S(num_btn, WCD_MBHC_DEF_BUTTONS); +#undef S + + + btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(msm_int_wcd_cal); + btn_low = btn_cfg->_v_btn_low; + btn_high = ((void *)&btn_cfg->_v_btn_low) + + (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); + + /* + * In SW we are maintaining two sets of threshold register + * one for current source and another for Micbias. + * all btn_low corresponds to threshold for current source + * all bt_high corresponds to threshold for Micbias + * Below thresholds are based on following resistances + * 0-70 == Button 0 + * 110-180 == Button 1 + * 210-290 == Button 2 + * 360-680 == Button 3 + */ + btn_low[0] = 75; + btn_high[0] = 75; + btn_low[1] = 150; + btn_high[1] = 150; + btn_low[2] = 225; + btn_high[2] = 225; + btn_low[3] = 450; + btn_high[3] = 450; + btn_low[4] = 500; + btn_high[4] = 500; + + return msm_int_wcd_cal; +} + +static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_component *dig_cdc = + snd_soc_rtdcom_lookup(rtd, "msm_digital_codec"); + struct snd_soc_component *ana_cdc = + snd_soc_rtdcom_lookup(rtd, "pmic_analog_codec"); + struct snd_soc_dapm_context *dapm; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); + struct snd_card *card; + int ret = -ENOMEM; + + pr_debug("%s(),dev_name%s\n", __func__, dev_name(cpu_dai->dev)); + + if (!dig_cdc || !ana_cdc) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + + dapm = snd_soc_component_get_dapm(ana_cdc); + ret = snd_soc_add_component_controls(ana_cdc, msm_snd_controls, + ARRAY_SIZE(msm_snd_controls)); + if (ret < 0) { + pr_err("%s: add_codec_controls failed: %d\n", + __func__, ret); + return ret; + } + ret = snd_soc_add_component_controls(ana_cdc, msm_common_snd_controls, + msm_common_snd_controls_size()); + if (ret < 0) { + pr_err("%s: add common snd controls failed: %d\n", + __func__, ret); + return ret; + } + + snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets, + ARRAY_SIZE(msm_int_dapm_widgets)); + + snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Secondary Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); + + snd_soc_dapm_ignore_suspend(dapm, "EAR"); + snd_soc_dapm_ignore_suspend(dapm, "HEADPHONE"); + snd_soc_dapm_ignore_suspend(dapm, "SPK_OUT"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "AMIC3"); + snd_soc_dapm_sync(dapm); + + dapm = snd_soc_component_get_dapm(dig_cdc); + snd_soc_dapm_ignore_suspend(dapm, "DMIC1"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC2"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC3"); + snd_soc_dapm_ignore_suspend(dapm, "DMIC4"); + + snd_soc_dapm_sync(dapm); + + msm_anlg_cdc_spk_ext_pa_cb(enable_spk_ext_pa, ana_cdc); + msm_dig_cdc_hph_comp_cb(msm_config_hph_compander_gpio, dig_cdc); + + card = rtd->card->snd_card; + if (!codec_root) + codec_root = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!codec_root) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + goto done; + } + pdata->codec_root = codec_root; + msm_dig_codec_info_create_codec_entry(codec_root, dig_cdc); + msm_anlg_codec_info_create_codec_entry(codec_root, ana_cdc); +done: + msm_set_codec_reg_done(true); + return 0; +} + +static int msm_sdw_audrx_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dapm_context *dapm; + struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_component *aux_comp; + struct snd_card *card; + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(rtd, "msm_sdw_codec"); + + if (!component) { + pr_err("%s: component is NULL\n", __func__); + return -EINVAL; + } + dapm = snd_soc_component_get_dapm(component); + + snd_soc_add_component_controls(component, msm_sdw_controls, + ARRAY_SIZE(msm_sdw_controls)); + + snd_soc_dapm_ignore_suspend(dapm, "AIF1_SDW Playback"); + snd_soc_dapm_ignore_suspend(dapm, "VIfeed_SDW"); + snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT"); + snd_soc_dapm_ignore_suspend(dapm, "AIF1_SDW VI"); + snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_SDW"); + + snd_soc_dapm_sync(dapm); + + /* + * Send speaker configuration only for WSA8810. + * Default configuration is for WSA8815. + */ + pr_debug("%s: Number of aux devices: %d\n", + __func__, rtd->card->num_aux_devs); + if (rtd->card->num_aux_devs && + !list_empty(&rtd->card->aux_comp_list)) { + aux_comp = list_first_entry(&rtd->card->aux_comp_list, + struct snd_soc_component, card_aux_list); + if (!strcmp(aux_comp->name, WSA8810_NAME_1) || + !strcmp(aux_comp->name, WSA8810_NAME_2)) { + msm_sdw_set_spkr_mode(component, SPKR_MODE_1); + msm_sdw_set_spkr_gain_offset(component, + RX_GAIN_OFFSET_M1P5_DB); + } + } + card = rtd->card->snd_card; + if (!codec_root) + codec_root = snd_info_create_subdir(card->module, "codecs", + card->proc_root); + if (!codec_root) { + pr_debug("%s: Cannot create codecs module entry\n", + __func__); + goto done; + } + pdata->codec_root = codec_root; + msm_sdw_codec_info_create_codec_entry(codec_root, component); +done: + return 0; +} + +static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) +{ + unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; + unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; + struct snd_soc_dai *component_dai = rtd->codec_dai; + + return snd_soc_dai_set_channel_map(component_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); +} + +static int msm_wcn_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + int ret; + + dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret) { + dev_err(rtd->dev, + "%s: failed to get BTFM codec chan map\n, err:%d\n", + __func__, ret); + goto exit; + } + + dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) id %d\n", + __func__, tx_ch_cnt, dai_link->id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); + if (ret) + dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + +exit: + return ret; +} + +static int msm_snd_card_late_probe(struct snd_soc_card *card) +{ + const char *be_dl_name = LPASS_BE_INT0_MI2S_RX; + struct snd_soc_component *ana_cdc; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + return -EINVAL; + } + ana_cdc = snd_soc_rtdcom_lookup(rtd, "pmic_analog_codec"); + if (!ana_cdc) { + dev_err(card->dev, + "%s: component is NULL\n", __func__); + return -EINVAL; + } + + mbhc_cfg_ptr->calibration = def_msm_int_wcd_mbhc_cal(); + if (!mbhc_cfg_ptr->calibration) + return -ENOMEM; + + ret = msm_anlg_cdc_hs_detect(ana_cdc, mbhc_cfg_ptr); + if (ret) { + dev_err(card->dev, + "%s: msm_anlg_cdc_hs_detect failed\n", __func__); + kfree(mbhc_cfg_ptr->calibration); + } + + return ret; +} + +static struct snd_soc_ops msm_tdm_be_ops = { + .startup = msm_tdm_snd_startup, + .shutdown = msm_tdm_snd_shutdown, + .hw_params = msm_tdm_snd_hw_params, +}; + +static struct snd_soc_ops msm_wcn_ops = { + .hw_params = msm_wcn_hw_params, +}; + +static struct snd_soc_ops msm_mi2s_be_ops = { + .startup = msm_mi2s_snd_startup, + .shutdown = msm_mi2s_snd_shutdown, +}; + +static struct snd_soc_ops msm_aux_pcm_be_ops = { + .startup = msm_aux_pcm_snd_startup, + .shutdown = msm_aux_pcm_snd_shutdown, +}; + +static struct snd_soc_ops msm_int_mi2s_be_ops = { + .startup = msm_int_mi2s_snd_startup, + .shutdown = msm_int_mi2s_snd_shutdown, +}; + +static struct snd_soc_ops msm_sdw_mi2s_be_ops = { + .startup = msm_sdw_mi2s_snd_startup, + .shutdown = msm_sdw_mi2s_snd_shutdown, +}; + +static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) +{ + cpumask_t mask; + + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); + + cpumask_clear(&mask); + cpumask_set_cpu(1, &mask); /* affine to core 1 */ + cpumask_set_cpu(2, &mask); /* affine to core 2 */ + cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); + + substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; + + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, + MSM_LL_QOS_VALUE); + return 0; +} + +static struct snd_soc_ops msm_fe_qos_ops = { + .prepare = msm_fe_qos_prepare, +}; + +struct snd_soc_dai_link_component dlc_rx1[] = { + { + .of_node = NULL, + .dai_name = "msm_dig_cdc_dai_rx1", + }, + { + .of_node = NULL, + .dai_name = "msm_anlg_cdc_i2s_rx1", + }, +}; + +struct snd_soc_dai_link_component dlc_tx1[] = { + { + .of_node = NULL, + .dai_name = "msm_dig_cdc_dai_tx1", + }, + { + .of_node = NULL, + .dai_name = "msm_anlg_cdc_i2s_tx1", + }, +}; + +struct snd_soc_dai_link_component dlc_tx2[] = { + { + .of_node = NULL, + .dai_name = "msm_dig_cdc_dai_tx2", + }, + { + .of_node = NULL, + .dai_name = "msm_anlg_cdc_i2s_tx2", + }, +}; + +/* Digital audio interface glue - connects codec <---> CPU */ +static struct snd_soc_dai_link msm_int_dai[] = { + /* FrontEnd DAI Links */ + {/* hw:x,0 */ + .name = MSM_DAILINK_NAME(Media1), + .stream_name = "MultiMedia1", + .cpu_dai_name = "MultiMedia1", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA1 + }, + {/* hw:x,1 */ + .name = MSM_DAILINK_NAME(Media2), + .stream_name = "MultiMedia2", + .cpu_dai_name = "MultiMedia2", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA2, + }, + {/* hw:x,2 */ + .name = "VoiceMMode1", + .stream_name = "VoiceMMode1", + .cpu_dai_name = "VoiceMMode1", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE1, + }, + {/* hw:x,3 */ + .name = "MSM VoIP", + .stream_name = "VoIP", + .cpu_dai_name = "VoIP", + .platform_name = "msm-voip-dsp", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_VOIP, + }, + {/* hw:x,4 */ + .name = MSM_DAILINK_NAME(ULL), + .stream_name = "ULL", + .cpu_dai_name = "MultiMedia3", + .platform_name = "msm-pcm-dsp.2", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA3, + }, + /* Hostless PCM purpose */ + {/* hw:x,5 */ + .name = "INT4 MI2S_RX Hostless", + .stream_name = "INT4 MI2S_RX Hostless", + .cpu_dai_name = "INT4_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + /* This dainlink has MI2S support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,6 */ + .name = "MSM AFE-PCM RX", + .stream_name = "AFE-PROXY RX", + .cpu_dai_name = "msm-dai-q6-dev.241", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .platform_name = "msm-pcm-afe", + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + }, + {/* hw:x,7 */ + .name = "MSM AFE-PCM TX", + .stream_name = "AFE-PROXY TX", + .cpu_dai_name = "msm-dai-q6-dev.240", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .platform_name = "msm-pcm-afe", + .ignore_suspend = 1, + }, + {/* hw:x,8 */ + .name = MSM_DAILINK_NAME(Compress1), + .stream_name = "Compress1", + .cpu_dai_name = "MultiMedia4", + .platform_name = "msm-compress-dsp", + .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS, + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA4, + }, + {/* hw:x,9*/ + .name = "AUXPCM Hostless", + .stream_name = "AUXPCM Hostless", + .cpu_dai_name = "AUXPCM_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,10 */ + .name = "SLIMBUS_1 Hostless", + .stream_name = "SLIMBUS_1 Hostless", + .cpu_dai_name = "SLIMBUS1_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, /* dai link has playback support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,11 */ + .name = "INT3 MI2S_TX Hostless", + .stream_name = "INT3 MI2S_TX Hostless", + .cpu_dai_name = "INT3_MI2S_TX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,12 */ + .name = "SLIMBUS_7 Hostless", + .stream_name = "SLIMBUS_7 Hostless", + .cpu_dai_name = "SLIMBUS7_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, /* dai link has playback support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,13 */ + .name = MSM_DAILINK_NAME(LowLatency), + .stream_name = "MultiMedia5", + .cpu_dai_name = "MultiMedia5", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + /* this dai link has playback support */ + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA5, + .ops = &msm_fe_qos_ops, + }, + /* LSM FE */ + {/* hw:x,14 */ + .name = "Listen 1 Audio Service", + .stream_name = "Listen 1 Audio Service", + .cpu_dai_name = "LSM1", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM1, + }, + {/* hw:x,15 */ + .name = MSM_DAILINK_NAME(Compress2), + .stream_name = "Compress2", + .cpu_dai_name = "MultiMedia7", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA7, + }, + {/* hw:x,16 */ + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", + .cpu_dai_name = "MultiMedia10", + .platform_name = "msm-pcm-dsp.1", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA10, + }, + {/* hw:x,17 */ + .name = MSM_DAILINK_NAME(ULL_NOIRQ), + .stream_name = "MM_NOIRQ", + .cpu_dai_name = "MultiMedia8", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA8, + .ops = &msm_fe_qos_ops, + }, + {/* hw:x,18 */ + .name = "HDMI_RX_HOSTLESS", + .stream_name = "HDMI_RX_HOSTLESS", + .cpu_dai_name = "HDMI_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,19 */ + .name = "VoiceMMode2", + .stream_name = "VoiceMMode2", + .cpu_dai_name = "VoiceMMode2", + .platform_name = "msm-pcm-voice", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_VOICEMMODE2, + }, + {/* hw:x,20 */ + .name = "Listen 2 Audio Service", + .stream_name = "Listen 2 Audio Service", + .cpu_dai_name = "LSM2", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM2, + }, + {/* hw:x,21 */ + .name = "Listen 3 Audio Service", + .stream_name = "Listen 3 Audio Service", + .cpu_dai_name = "LSM3", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM3, + }, + {/* hw:x,22 */ + .name = "Listen 4 Audio Service", + .stream_name = "Listen 4 Audio Service", + .cpu_dai_name = "LSM4", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM4, + }, + {/* hw:x,23 */ + .name = "Listen 5 Audio Service", + .stream_name = "Listen 5 Audio Service", + .cpu_dai_name = "LSM5", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM5, + }, + {/* hw:x,24 */ + .name = "Listen 6 Audio Service", + .stream_name = "Listen 6 Audio Service", + .cpu_dai_name = "LSM6", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM6 + }, + {/* hw:x,25 */ + .name = "Listen 7 Audio Service", + .stream_name = "Listen 7 Audio Service", + .cpu_dai_name = "LSM7", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM7, + }, + {/* hw:x,26 */ + .name = "Listen 8 Audio Service", + .stream_name = "Listen 8 Audio Service", + .cpu_dai_name = "LSM8", + .platform_name = "msm-lsm-client", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST }, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .id = MSM_FRONTEND_DAI_LSM8, + }, + {/* hw:x,27 */ + .name = MSM_DAILINK_NAME(Media9), + .stream_name = "MultiMedia9", + .cpu_dai_name = "MultiMedia9", + .platform_name = "msm-pcm-dsp.0", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA9, + }, + {/* hw:x,28 */ + .name = MSM_DAILINK_NAME(Compress4), + .stream_name = "Compress4", + .cpu_dai_name = "MultiMedia11", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA11, + }, + {/* hw:x,29 */ + .name = MSM_DAILINK_NAME(Compress5), + .stream_name = "Compress5", + .cpu_dai_name = "MultiMedia12", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA12, + }, + {/* hw:x,30 */ + .name = MSM_DAILINK_NAME(Compress6), + .stream_name = "Compress6", + .cpu_dai_name = "MultiMedia13", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA13, + }, + {/* hw:x,31 */ + .name = MSM_DAILINK_NAME(Compress7), + .stream_name = "Compress7", + .cpu_dai_name = "MultiMedia14", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA14, + }, + {/* hw:x,32 */ + .name = MSM_DAILINK_NAME(Compress8), + .stream_name = "Compress8", + .cpu_dai_name = "MultiMedia15", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA15, + }, + {/* hw:x,33 */ + .name = MSM_DAILINK_NAME(ULL_NOIRQ_2), + .stream_name = "MM_NOIRQ_2", + .cpu_dai_name = "MultiMedia16", + .platform_name = "msm-pcm-dsp-noirq", + .dynamic = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + /* this dai link has playback support */ + .id = MSM_FRONTEND_DAI_MULTIMEDIA16, + }, + {/* hw:x,34 */ + .name = "SLIMBUS_8 Hostless", + .stream_name = "SLIMBUS8_HOSTLESS Capture", + .cpu_dai_name = "SLIMBUS8_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,35 */ + .name = "Primary MI2S_RX Hostless", + .stream_name = "Primary MI2S_RX Hostless", + .cpu_dai_name = "PRI_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + /* This dainlink has MI2S support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,36 */ + .name = "Secondary MI2S_RX Hostless", + .stream_name = "Secondary MI2S_RX Hostless", + .cpu_dai_name = "SEC_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + /* This dainlink has MI2S support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,37 */ + .name = "Tertiary MI2S_RX Hostless", + .stream_name = "Tertiary MI2S_RX Hostless", + .cpu_dai_name = "TERT_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + /* This dainlink has MI2S support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,38 */ + .name = "INT0 MI2S_RX Hostless", + .stream_name = "INT0 MI2S_RX Hostless", + .cpu_dai_name = "INT0_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + /* this dailink has playback support */ + .ignore_pmdown_time = 1, + /* This dainlink has MI2S support */ + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + {/* hw:x,39 */ + .name = "SDM660 HFP TX", + .stream_name = "MultiMedia6", + .cpu_dai_name = "MultiMedia6", + .platform_name = "msm-pcm-loopback", + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .ignore_suspend = 1, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_pmdown_time = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA6, + }, +}; + + +static struct snd_soc_dai_link msm_int_wsa_dai[] = { + {/* hw:x,40 */ + .name = LPASS_BE_INT5_MI2S_TX, + .stream_name = "INT5_mi2s Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.12", + .platform_name = "msm-pcm-hostless", + .codec_name = "msm_sdw_codec", + .codec_dai_name = "msm_sdw_vifeedback", + .id = MSM_BACKEND_DAI_INT5_MI2S_TX, + .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, + .ops = &msm_sdw_mi2s_be_ops, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .dpcm_capture = 1, + }, +}; + +static struct snd_soc_dai_link msm_int_compress_capture_dai[] = { + {/* hw:x,41 */ + .name = "Compress9", + .stream_name = "Compress9", + .cpu_dai_name = "MultiMedia17", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA17, + }, + {/* hw:x,42 */ + .name = "Compress10", + .stream_name = "Compress10", + .cpu_dai_name = "MultiMedia18", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA18, + }, + {/* hw:x,43 */ + .name = "Compress11", + .stream_name = "Compress11", + .cpu_dai_name = "MultiMedia19", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA19, + }, + {/* hw:x,44 */ + .name = "Compress12", + .stream_name = "Compress12", + .cpu_dai_name = "MultiMedia28", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA28, + }, + {/* hw:x,45 */ + .name = "Compress13", + .stream_name = "Compress13", + .cpu_dai_name = "MultiMedia29", + .platform_name = "msm-compress-dsp", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .ignore_suspend = 1, + .id = MSM_FRONTEND_DAI_MULTIMEDIA29, + }, +}; + +static struct snd_soc_dai_link msm_int_be_dai[] = { + /* Backend I2S DAI Links */ + { + .name = LPASS_BE_INT0_MI2S_RX, + .stream_name = "INT0 MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.7", + .platform_name = "msm-pcm-routing", + .codecs = dlc_rx1, + .num_codecs = CODECS_MAX, + .no_pcm = 1, + .dpcm_playback = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE | + ASYNC_DPCM_SND_SOC_HW_PARAMS, + .id = MSM_BACKEND_DAI_INT0_MI2S_RX, + .init = &msm_audrx_init, + .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, + .ops = &msm_int_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_INT3_MI2S_TX, + .stream_name = "INT3 MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.10", + .platform_name = "msm-pcm-routing", + .codecs = dlc_tx1, + .num_codecs = CODECS_MAX, + .no_pcm = 1, + .dpcm_capture = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE | + ASYNC_DPCM_SND_SOC_HW_PARAMS, + .id = MSM_BACKEND_DAI_INT3_MI2S_TX, + .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, + .ops = &msm_int_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_INT2_MI2S_TX, + .stream_name = "INT2 MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.9", + .platform_name = "msm-pcm-routing", + .codecs = dlc_tx2, + .num_codecs = CODECS_MAX, + .no_pcm = 1, + .dpcm_capture = 1, + .async_ops = ASYNC_DPCM_SND_SOC_PREPARE | + ASYNC_DPCM_SND_SOC_HW_PARAMS, + .id = MSM_BACKEND_DAI_INT2_MI2S_TX, + .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, + .ops = &msm_int_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AFE_PCM_RX, + .stream_name = "AFE Playback", + .cpu_dai_name = "msm-dai-q6-dev.224", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + /* this dainlink has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_AFE_PCM_TX, + .stream_name = "AFE Capture", + .cpu_dai_name = "msm-dai-q6-dev.225", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AFE_PCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Uplink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_TX, + .stream_name = "Voice Uplink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32772", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Record Downlink BACK END DAI Link */ + { + .name = LPASS_BE_INCALL_RECORD_RX, + .stream_name = "Voice Downlink Capture", + .cpu_dai_name = "msm-dai-q6-dev.32771", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_INCALL_RECORD_RX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + }, + /* Incall Music BACK END DAI Link */ + { + .name = LPASS_BE_VOICE_PLAYBACK_TX, + .stream_name = "Voice Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32773", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + /* Incall Music 2 BACK END DAI Link */ + { + .name = LPASS_BE_VOICE2_PLAYBACK_TX, + .stream_name = "Voice2 Farend Playback", + .cpu_dai_name = "msm-dai-q6-dev.32770", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + .be_hw_params_fixup = msm_be_hw_params_fixup, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_RX, + .stream_name = "USB Audio Playback", + .cpu_dai_name = "msm-dai-q6-dev.28672", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_USB_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_TX, + .stream_name = "USB Audio Capture", + .cpu_dai_name = "msm-dai-q6-dev.28673", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_USB_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_0, + .stream_name = "Primary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36864", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_0, + .stream_name = "Primary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36865", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_0, + .stream_name = "Secondary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36880", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_0, + .stream_name = "Secondary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36881", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_0, + .stream_name = "Tertiary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36896", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_0, + .stream_name = "Tertiary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36897", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_0, + .stream_name = "Quaternary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36912", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_0, + .stream_name = "Quaternary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36913", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_TDM_RX_0, + .stream_name = "Quinary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36928", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_TDM_TX_0, + .stream_name = "Quinary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36929", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { + { + .name = LPASS_BE_PRI_MI2S_RX, + .stream_name = "Primary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_PRI_MI2S_TX, + .stream_name = "Primary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.0", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_PRI_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX, + .stream_name = "Secondary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX, + .stream_name = "Secondary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX, + .stream_name = "Tertiary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX, + .stream_name = "Tertiary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX, + .stream_name = "Quaternary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX, + .stream_name = "Quaternary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_RX, + .stream_name = "Quinary MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + }, + { + .name = LPASS_BE_QUIN_MI2S_TX, + .stream_name = "Quinary MI2S Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUINARY_MI2S_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_mi2s_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { + /* Primary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_AUXPCM_RX, + .stream_name = "AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_AUXPCM_TX, + .stream_name = "AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.1", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Secondary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_SEC_AUXPCM_RX, + .stream_name = "Sec AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_SEC_AUXPCM_TX, + .stream_name = "Sec AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.2", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Tertiary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_TERT_AUXPCM_RX, + .stream_name = "Tert AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_TERT_AUXPCM_TX, + .stream_name = "Tert AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.3", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Quaternary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUAT_AUXPCM_RX, + .stream_name = "Quat AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_QUAT_AUXPCM_TX, + .stream_name = "Quat AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.4", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + /* Quinary AUX PCM Backend DAI Links */ + { + .name = LPASS_BE_QUIN_AUXPCM_RX, + .stream_name = "Quin AUX PCM Playback", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, + { + .name = LPASS_BE_QUIN_AUXPCM_TX, + .stream_name = "Quin AUX PCM Capture", + .cpu_dai_name = "msm-dai-q6-auxpcm.5", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + .ops = &msm_aux_pcm_be_ops, + }, +}; + + +static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_7_RX, + .stream_name = "Slimbus7 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16398", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + /* BT codec driver determines capabilities based on + * dai name, bt codecdai name should always contains + * supported usecase information + */ + .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_RX, + .be_hw_params_fixup = msm_btfm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_7_TX, + .stream_name = "Slimbus7 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16399", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_bt_sco_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_7_TX, + .be_hw_params_fixup = msm_btfm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_8_TX, + .stream_name = "Slimbus8 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16401", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_fm_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .id = MSM_BACKEND_DAI_SLIMBUS_8_TX, + .be_hw_params_fixup = msm_btfm_be_hw_params_fixup, + .init = &msm_wcn_init, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_wsa_be_dai_links[] = { + { + .name = LPASS_BE_INT4_MI2S_RX, + .stream_name = "INT4 MI2S Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.11", + .platform_name = "msm-pcm-routing", + .codec_name = "msm_sdw_codec", + .codec_dai_name = "msm_sdw_i2s_rx1", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_INT4_MI2S_RX, + .init = &msm_sdw_audrx_init, + .be_hw_params_fixup = int_mi2s_be_hw_params_fixup, + .ops = &msm_sdw_mi2s_be_ops, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link ext_disp_be_dai_link[] = { + /* DISP PORT BACK END DAI Link */ + { + .name = LPASS_BE_DISPLAY_PORT, + .stream_name = "Display Port Playback", + .cpu_dai_name = "msm-dai-q6-dp.24608", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-ext-disp-audio-codec-rx", + .codec_dai_name = "msm_dp_audio_codec_rx_dai", + .no_pcm = 1, + .dpcm_playback = 1, + .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +}; + +static struct snd_soc_dai_link msm_int_dai_links[ +ARRAY_SIZE(msm_int_dai) + +ARRAY_SIZE(msm_int_wsa_dai) + +ARRAY_SIZE(msm_int_compress_capture_dai) + +ARRAY_SIZE(msm_int_be_dai) + +ARRAY_SIZE(msm_mi2s_be_dai_links) + +ARRAY_SIZE(msm_auxpcm_be_dai_links)+ +ARRAY_SIZE(msm_wcn_be_dai_links) + +ARRAY_SIZE(msm_wsa_be_dai_links) + +ARRAY_SIZE(ext_disp_be_dai_link)]; + +static struct snd_soc_card sdm660_card = { + /* snd_soc_card_sdm660 */ + .name = "sdm660-snd-card", + .dai_link = msm_int_dai, + .num_links = ARRAY_SIZE(msm_int_dai), + .late_probe = msm_snd_card_late_probe, +}; + +static void msm_disable_int_mclk0(struct work_struct *work) +{ + struct msm_asoc_mach_data *pdata = NULL; + struct delayed_work *dwork; + int ret = 0; + + dwork = to_delayed_work(work); + pdata = container_of(dwork, struct msm_asoc_mach_data, + disable_int_mclk0_work); + mutex_lock(&pdata->cdc_int_mclk0_mutex); + pr_debug("%s: mclk_enabled %d mclk_rsc_ref %d\n", __func__, + atomic_read(&pdata->int_mclk0_enabled), + atomic_read(&pdata->int_mclk0_rsc_ref)); + + if (atomic_read(&pdata->int_mclk0_enabled) == true + && atomic_read(&pdata->int_mclk0_rsc_ref) == 0) { + pr_debug("Disable the mclk\n"); + pdata->digital_cdc_core_clk.enable = 0; + pdata->digital_cdc_core_clk.clk_freq_in_hz = + DEFAULT_MCLK_RATE; + ret = afe_set_lpass_clock_v2( + AFE_PORT_ID_INT0_MI2S_RX, + &pdata->digital_cdc_core_clk); + if (ret < 0) + pr_err("%s failed to disable the CCLK\n", __func__); + atomic_set(&pdata->int_mclk0_enabled, false); + } + mutex_unlock(&pdata->cdc_int_mclk0_mutex); +} + +static void msm_int_dt_parse_cap_info(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata) +{ + const char *ext1_cap = "qcom,msm-micbias1-ext-cap"; + const char *ext2_cap = "qcom,msm-micbias2-ext-cap"; + + pdata->micbias1_cap_mode = + (of_property_read_bool(pdev->dev.of_node, ext1_cap) ? + MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); + + pdata->micbias2_cap_mode = + (of_property_read_bool(pdev->dev.of_node, ext2_cap) ? + MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); +} + +static struct snd_soc_card *msm_int_populate_sndcard_dailinks( + struct device *dev) +{ + struct snd_soc_card *card = &sdm660_card; + struct snd_soc_dai_link *dailink; + int len1; + + card->name = dev_name(dev); + len1 = ARRAY_SIZE(msm_int_dai); + memcpy(msm_int_dai_links, msm_int_dai, sizeof(msm_int_dai)); + dailink = msm_int_dai_links; + if (!of_property_read_bool(dev->of_node, + "qcom,wsa-disable")) { + memcpy(dailink + len1, + msm_int_wsa_dai, + sizeof(msm_int_wsa_dai)); + len1 += ARRAY_SIZE(msm_int_wsa_dai); + } + memcpy(dailink + len1, msm_int_compress_capture_dai, + sizeof(msm_int_compress_capture_dai)); + len1 += ARRAY_SIZE(msm_int_compress_capture_dai); + + memcpy(dailink + len1, msm_int_be_dai, sizeof(msm_int_be_dai)); + len1 += ARRAY_SIZE(msm_int_be_dai); + + if (of_property_read_bool(dev->of_node, + "qcom,mi2s-audio-intf")) { + memcpy(dailink + len1, + msm_mi2s_be_dai_links, + sizeof(msm_mi2s_be_dai_links)); + len1 += ARRAY_SIZE(msm_mi2s_be_dai_links); + } + if (of_property_read_bool(dev->of_node, + "qcom,auxpcm-audio-intf")) { + memcpy(dailink + len1, + msm_auxpcm_be_dai_links, + sizeof(msm_auxpcm_be_dai_links)); + len1 += ARRAY_SIZE(msm_auxpcm_be_dai_links); + } + if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + dev_dbg(dev, "%s(): WCN BTFM support present\n", + __func__); + memcpy(dailink + len1, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + len1 += ARRAY_SIZE(msm_wcn_be_dai_links); + } + if (!of_property_read_bool(dev->of_node, "qcom,wsa-disable")) { + memcpy(dailink + len1, + msm_wsa_be_dai_links, + sizeof(msm_wsa_be_dai_links)); + len1 += ARRAY_SIZE(msm_wsa_be_dai_links); + } + if (of_property_read_bool(dev->of_node, "qcom,ext-disp-audio-rx")) { + dev_dbg(dev, "%s(): ext disp audio support present\n", + __func__); + memcpy(dailink + len1, + ext_disp_be_dai_link, + sizeof(ext_disp_be_dai_link)); + len1 += ARRAY_SIZE(ext_disp_be_dai_link); + } + card->dai_link = dailink; + card->num_links = len1; + return card; +} + +static int msm_internal_init(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata, + struct snd_soc_card *card) +{ + const char *type = NULL; + const char *hs_micbias_type = "qcom,msm-hs-micbias-type"; + int ret; + + ret = is_ext_spk_gpio_support(pdev, pdata); + if (ret < 0) + dev_dbg(&pdev->dev, + "%s: doesn't support external speaker pa\n", + __func__); + + ret = of_property_read_string(pdev->dev.of_node, + hs_micbias_type, &type); + if (ret) { + dev_err(&pdev->dev, "%s: missing %s in dt node\n", + __func__, hs_micbias_type); + goto err; + } + if (!strcmp(type, "external")) { + dev_dbg(&pdev->dev, "Headset is using external micbias\n"); + mbhc_cfg_ptr->hs_ext_micbias = true; + } else { + dev_dbg(&pdev->dev, "Headset is using internal micbias\n"); + mbhc_cfg_ptr->hs_ext_micbias = false; + } + + /* initialize the int_mclk0 */ + pdata->digital_cdc_core_clk.clk_set_minor_version = + AFE_API_VERSION_I2S_CONFIG; + pdata->digital_cdc_core_clk.clk_id = + Q6AFE_LPASS_CLK_ID_INT_MCLK_0; + pdata->digital_cdc_core_clk.clk_freq_in_hz = pdata->mclk_freq; + pdata->digital_cdc_core_clk.clk_attri = + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO; + pdata->digital_cdc_core_clk.clk_root = + Q6AFE_LPASS_CLK_ROOT_DEFAULT; + pdata->digital_cdc_core_clk.enable = 1; + + /* Initialize loopback mode to false */ + pdata->lb_mode = false; + + msm_int_dt_parse_cap_info(pdev, pdata); + + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, pdata); + ret = snd_soc_of_parse_card_name(card, "qcom,model"); + if (ret) + goto err; + /* initialize timer */ + INIT_DELAYED_WORK(&pdata->disable_int_mclk0_work, + msm_disable_int_mclk0); + mutex_init(&pdata->cdc_int_mclk0_mutex); + atomic_set(&pdata->int_mclk0_rsc_ref, 0); + atomic_set(&pdata->int_mclk0_enabled, false); + + dev_info(&pdev->dev, "%s: default codec configured\n", __func__); + + return 0; +err: + return ret; +} + +/** + * msm_int_cdc_init - internal codec machine specific init. + * + * @pdev: platform device handle + * @pdata: private data of machine driver + * @card: sound card pointer reference + * @mbhc_cfg: MBHC config reference + * + * Returns 0. + */ +int msm_int_cdc_init(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata, + struct snd_soc_card **card, + struct wcd_mbhc_config *mbhc_cfg) +{ + mbhc_cfg_ptr = mbhc_cfg; + + *card = msm_int_populate_sndcard_dailinks(&pdev->dev); + msm_internal_init(pdev, pdata, *card); + return 0; +} +EXPORT_SYMBOL(msm_int_cdc_init); diff --git a/config/sdm660auto.conf b/config/sdm660auto.conf index 9a31ece8a19b..7f0d1d7e6dbd 100644 --- a/config/sdm660auto.conf +++ b/config/sdm660auto.conf @@ -6,8 +6,6 @@ CONFIG_SND_SOC_WCD_MBHC=m CONFIG_SND_SOC_WSA881X=m CONFIG_SND_SOC_WCD_DSP_MGR=m CONFIG_SND_SOC_WCD_SPI=m -CONFIG_SND_SOC_WCD_CPE=m -CONFIG_SND_SOC_CPE=m CONFIG_SND_SOC_WCD9335=m CONFIG_SND_SOC_WCD934X=m CONFIG_SND_SOC_WCD934X_MBHC=m @@ -27,6 +25,7 @@ CONFIG_MSM_GLINK_SPI_XPRT=m CONFIG_SOUNDWIRE=m CONFIG_SOUNDWIRE_WCD_CTRL=m CONFIG_SND_SOC_QDSP6V2=m +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m CONFIG_WCD9XXX_CODEC_CORE=m CONFIG_MSM_CDC_PINCTRL=m CONFIG_SND_SOC_WCD_MBHC_ADC=m diff --git a/config/sdm660autoconf.h b/config/sdm660autoconf.h index 077149a02ef8..d55918be1235 100644 --- a/config/sdm660autoconf.h +++ b/config/sdm660autoconf.h @@ -15,7 +15,6 @@ #define CONFIG_PINCTRL_WCD 1 #define CONFIG_AUDIO_EXT_CLK 1 #define CONFIG_SND_SOC_WCD9XXX_V2 1 -#define CONFIG_SND_SOC_WCD_CPE 1 #define CONFIG_SND_SOC_WCD_MBHC 1 #define CONFIG_SND_SOC_WSA881X 1 #define CONFIG_SND_SOC_WCD_DSP_MGR 1 @@ -41,6 +40,7 @@ #define CONFIG_SND_SOC_WCD_MBHC_ADC 1 #define CONFIG_SND_SOC_WCD_MBHC_LEGACY 1 #define CONFIG_SND_SOC_QDSP6V2 1 +#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1 #define CONFIG_QTI_PP 1 #define CONFIG_SND_HWDEP_ROUTING 1 #define CONFIG_DTS_EAGLE 1 @@ -54,7 +54,6 @@ #define CONFIG_MSM_AVTIMER 1 #define CONFIG_SND_SOC_EXT_CODEC 1 #define CONFIG_SND_SOC_INT_CODEC 1 -#define CONFIG_SND_SOC_CPE 1 #define CONFIG_SND_SOC_SDM660_CDC 1 #define CONFIG_SND_SOC_ANALOG_CDC 1 #define CONFIG_SND_SOC_DIGITAL_CDC 1 diff --git a/dsp/codecs/Android.mk b/dsp/codecs/Android.mk index 59a1603cb19e..a27f1b06d5a6 100644 --- a/dsp/codecs/Android.mk +++ b/dsp/codecs/Android.mk @@ -23,9 +23,13 @@ ifeq ($(call is-board-platform,bengal),true) AUDIO_SELECT := CONFIG_SND_SOC_BENGAL=m endif +ifeq ($(call is-board-platform,sdm660),true) +AUDIO_SELECT := CONFIG_SND_SOC_SDM660=m +endif + AUDIO_CHIPSET := audio # Build/Package only in case of supported target -ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike),true) +ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito bengal sdmshrike sdm660),true) LOCAL_PATH := $(call my-dir) diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 8709901de96b..808bfe22a076 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -58,6 +58,11 @@ ifeq ($(KERNEL_BUILD), 0) export INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h endif + ifeq ($(CONFIG_ARCH_SDM660), y) + include $(AUDIO_ROOT)/config/sdm660auto.conf + export + INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h + endif endif # As per target team, build is done as follows: diff --git a/include/asoc/sdm660-common.h b/include/asoc/sdm660-common.h new file mode 100644 index 000000000000..a8c815c330f1 --- /dev/null +++ b/include/asoc/sdm660-common.h @@ -0,0 +1,147 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2015-2019, 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef __MSM_COMMON +#define __MSM_COMMON + +#include +#include +#include + +#define DEFAULT_MCLK_RATE 9600000 +#define NATIVE_MCLK_RATE 11289600 + +#define SAMPLING_RATE_8KHZ 8000 +#define SAMPLING_RATE_11P025KHZ 11025 +#define SAMPLING_RATE_16KHZ 16000 +#define SAMPLING_RATE_22P05KHZ 22050 +#define SAMPLING_RATE_32KHZ 32000 +#define SAMPLING_RATE_44P1KHZ 44100 +#define SAMPLING_RATE_48KHZ 48000 +#define SAMPLING_RATE_88P2KHZ 88200 +#define SAMPLING_RATE_96KHZ 96000 +#define SAMPLING_RATE_176P4KHZ 176400 +#define SAMPLING_RATE_192KHZ 192000 +#define SAMPLING_RATE_352P8KHZ 352800 +#define SAMPLING_RATE_384KHZ 384000 + +#define TDM_CHANNEL_MAX 16 +#define TDM_SLOT_OFFSET_MAX 32 + +enum { + TDM_0 = 0, + TDM_1, + TDM_2, + TDM_3, + TDM_4, + TDM_5, + TDM_6, + TDM_7, + TDM_PORT_MAX, +}; + +enum { + TDM_PRI = 0, + TDM_SEC, + TDM_TERT, + TDM_QUAT, + TDM_QUIN, + TDM_INTERFACE_MAX, +}; + +struct tdm_port { + u32 mode; + u32 channel; +}; + +struct dev_config { + u32 sample_rate; + u32 bit_format; + u32 channels; +}; + +enum { + PRIM_MI2S = 0, + SEC_MI2S, + TERT_MI2S, + QUAT_MI2S, + QUIN_MI2S, + MI2S_MAX, +}; + +enum { + DIG_CDC, + ANA_CDC, + CODECS_MAX, +}; + +extern const struct snd_kcontrol_new msm_common_snd_controls[]; +extern bool codec_reg_done; +struct sdm660_codec { + void* (*get_afe_config_fn)(struct snd_soc_codec *codec, + enum afe_config_type config_type); +}; + +enum { + INT_SND_CARD, + EXT_SND_CARD_TASHA, + EXT_SND_CARD_TAVIL, +}; + +struct msm_snd_interrupt { + void __iomem *mpm_wakeup; + void __iomem *intr1_cfg_apps; + void __iomem *lpi_gpio_intr_cfg; + void __iomem *lpi_gpio_cfg; + void __iomem *lpi_gpio_inout; +}; + +struct msm_asoc_mach_data { + int us_euro_gpio; /* used by gpio driver API */ + int usbc_en2_gpio; /* used by gpio driver API */ + int hph_en1_gpio; + int hph_en0_gpio; + struct device_node *us_euro_gpio_p; /* used by pinctrl API */ + struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */ + struct device_node *hph_en1_gpio_p; /* used by pinctrl API */ + struct device_node *hph_en0_gpio_p; /* used by pinctrl API */ + struct device_node *pdm_gpio_p; /* used by pinctrl API */ + struct device_node *comp_gpio_p; /* used by pinctrl API */ + struct device_node *dmic_gpio_p; /* used by pinctrl API */ + struct device_node *ext_spk_gpio_p; /* used by pinctrl API */ + struct device_node *mi2s_gpio_p[MI2S_MAX]; /* used by pinctrl API */ + struct snd_soc_codec *codec; + struct sdm660_codec sdm660_codec_fn; + struct snd_info_entry *codec_root; + int spk_ext_pa_gpio; + int mclk_freq; + bool native_clk_set; + int lb_mode; + int snd_card_val; + u8 micbias1_cap_mode; + u8 micbias2_cap_mode; + atomic_t int_mclk0_rsc_ref; + atomic_t int_mclk0_enabled; + struct mutex cdc_int_mclk0_mutex; + struct delayed_work disable_int_mclk0_work; + struct afe_clk_set digital_cdc_core_clk; + struct msm_snd_interrupt msm_snd_intr_lpi; +}; + +int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params); +int msm_aux_pcm_snd_startup(struct snd_pcm_substream *substream); +void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream); +int msm_mi2s_snd_startup(struct snd_pcm_substream *substream); +void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream); +int msm_common_snd_controls_size(void); +void msm_set_codec_reg_done(bool done); +int msm_tdm_snd_startup(struct snd_pcm_substream *substream); +void msm_tdm_snd_shutdown(struct snd_pcm_substream *substream); +int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params); +int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params); +#endif diff --git a/include/asoc/sdm660-external.h b/include/asoc/sdm660-external.h new file mode 100644 index 000000000000..0de17cc67b38 --- /dev/null +++ b/include/asoc/sdm660-external.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2015-2017, 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef __SDM660_EXTERNAL +#define __SDM660_EXTERNAL + +int msm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params); +int msm_ext_slimbus_2_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params); +int msm_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params); +int msm_proxy_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params); +int msm_proxy_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params); +int msm_audrx_init(struct snd_soc_pcm_runtime *rtd); +int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params); +struct snd_soc_card *populate_snd_card_dailinks(struct device *dev, + int snd_card_val); +int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params); +int msm_snd_card_tavil_late_probe(struct snd_soc_card *card); +int msm_snd_card_tasha_late_probe(struct snd_soc_card *card); +#if IS_ENABLED(CONFIG_SND_SOC_EXT_CODEC) +int msm_ext_cdc_init(struct platform_device *, struct msm_asoc_mach_data *, + struct snd_soc_card **, struct wcd_mbhc_config *); +void msm_ext_register_audio_notifier(struct platform_device *pdev); +void msm_ext_cdc_deinit(struct msm_asoc_mach_data *pdata); +#else +inline int msm_ext_cdc_init(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata, + struct snd_soc_card **card, + struct wcd_mbhc_config *wcd_mbhc_cfg_ptr1) +{ + return 0; +} + +inline void msm_ext_register_audio_notifier(struct platform_device *pdev) +{ +} +inline void msm_ext_cdc_deinit(void) +{ +} +#endif +#endif diff --git a/include/asoc/sdm660-internal.h b/include/asoc/sdm660-internal.h new file mode 100644 index 000000000000..69214d9bb12b --- /dev/null +++ b/include/asoc/sdm660-internal.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2016-2017, 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef __SDM660_INTERNAL +#define __SDM660_INTERNAL + +#include + +#if IS_ENABLED(CONFIG_SND_SOC_INT_CODEC) +int msm_int_cdc_init(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata, + struct snd_soc_card **card, + struct wcd_mbhc_config *mbhc_cfg); +#else +int msm_int_cdc_init(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata, + struct snd_soc_card **card, + struct wcd_mbhc_config *mbhc_cfg) +{ + return 0; +} +#endif +#endif -- GitLab From 04170363287912fa23dd6e2d0ff06f1ae588c528 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 5 Jun 2020 20:36:44 +0530 Subject: [PATCH 1562/1645] asoc: wcd938x: Add WCD ADC Mode mask to control modes To set correct swr clk rate in concurrency, use WCD ADC modes as status mask bit to confirm ADC paths active and control set clock rate. Change-Id: Id3401d6ed59bd617e0751e7c704268346b36dac4 Signed-off-by: Laxminath Kasam --- asoc/codecs/wcd938x/wcd938x.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 511fd1f22414..9207bbd20319 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -58,6 +58,10 @@ enum { HPH_PA_DELAY, AMIC2_BCS_ENABLE, WCD_SUPPLIES_LPM_MODE, + WCD_ADC1_MODE, + WCD_ADC2_MODE, + WCD_ADC3_MODE, + WCD_ADC4_MODE, }; enum { @@ -1513,13 +1517,17 @@ static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: if (strnstr(w->name, "ADC", sizeof("ADC"))) { - if (test_bit(WCD_ADC1, &wcd938x->status_mask)) + if (test_bit(WCD_ADC1, &wcd938x->status_mask) || + test_bit(WCD_ADC1_MODE, &wcd938x->status_mask)) mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC1]]; - if (test_bit(WCD_ADC2, &wcd938x->status_mask)) + if (test_bit(WCD_ADC2, &wcd938x->status_mask) || + test_bit(WCD_ADC2_MODE, &wcd938x->status_mask)) mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC2]]; - if (test_bit(WCD_ADC3, &wcd938x->status_mask)) + if (test_bit(WCD_ADC3, &wcd938x->status_mask) || + test_bit(WCD_ADC3_MODE, &wcd938x->status_mask)) mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC3]]; - if (test_bit(WCD_ADC4, &wcd938x->status_mask)) + if (test_bit(WCD_ADC4, &wcd938x->status_mask) || + test_bit(WCD_ADC4_MODE, &wcd938x->status_mask)) mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC4]]; if (mode != 0) { @@ -1551,6 +1559,14 @@ static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w, false); if (strnstr(w->name, "ADC", sizeof("ADC"))) wcd938x_set_swr_clk_rate(component, rate, bank); + if (strnstr(w->name, "ADC1", sizeof("ADC1"))) + clear_bit(WCD_ADC1_MODE, &wcd938x->status_mask); + else if (strnstr(w->name, "ADC2", sizeof("ADC2"))) + clear_bit(WCD_ADC2_MODE, &wcd938x->status_mask); + else if (strnstr(w->name, "ADC3", sizeof("ADC3"))) + clear_bit(WCD_ADC3_MODE, &wcd938x->status_mask); + else if (strnstr(w->name, "ADC4", sizeof("ADC4"))) + clear_bit(WCD_ADC4_MODE, &wcd938x->status_mask); break; }; @@ -1999,21 +2015,25 @@ static int wcd938x_event_notify(struct notifier_block *block, if (test_bit(WCD_ADC1, &wcd938x->status_mask)) { snd_soc_component_update_bits(component, WCD938X_ANA_TX_CH2, 0x40, 0x00); + set_bit(WCD_ADC1_MODE, &wcd938x->status_mask); clear_bit(WCD_ADC1, &wcd938x->status_mask); } if (test_bit(WCD_ADC2, &wcd938x->status_mask)) { snd_soc_component_update_bits(component, WCD938X_ANA_TX_CH2, 0x20, 0x00); + set_bit(WCD_ADC2_MODE, &wcd938x->status_mask); clear_bit(WCD_ADC2, &wcd938x->status_mask); } if (test_bit(WCD_ADC3, &wcd938x->status_mask)) { snd_soc_component_update_bits(component, WCD938X_ANA_TX_CH4, 0x40, 0x00); + set_bit(WCD_ADC3_MODE, &wcd938x->status_mask); clear_bit(WCD_ADC3, &wcd938x->status_mask); } if (test_bit(WCD_ADC4, &wcd938x->status_mask)) { snd_soc_component_update_bits(component, WCD938X_ANA_TX_CH4, 0x20, 0x00); + set_bit(WCD_ADC4_MODE, &wcd938x->status_mask); clear_bit(WCD_ADC4, &wcd938x->status_mask); } break; -- GitLab From 4732998c6da18b2f0def3b8ab7aec634be67ac6e Mon Sep 17 00:00:00 2001 From: "Vangala, Amarnath" Date: Tue, 7 Jul 2020 20:50:44 +0530 Subject: [PATCH 1563/1645] dsp: fix to race condition in voice call mute command handling. Apply the cached value of device mute setting to dsp, after voc state moves to RUN. Change-Id: I82bc9ab2d49a199f0277b1694cd00311eddd6115 Signed-off-by: Vangala, Amarnath --- dsp/q6voice.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index c63cf982e9f8..84a2eb94b0e4 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -7204,6 +7204,16 @@ int voc_enable_device(uint32_t session_id) goto done; } v->voc_state = VOC_RUN; + + if (v->lch_mode == 0) { + pr_debug("%s: dev_mute = %d, ramp_duration = %d ms\n", + __func__, v->dev_rx.dev_mute, + v->dev_rx.dev_mute_ramp_duration_ms); + ret = voice_send_device_mute_cmd(v, + VSS_IVOLUME_DIRECTION_RX, + v->dev_rx.dev_mute, + v->dev_rx.dev_mute_ramp_duration_ms); + } } else { pr_debug("%s: called in voc state=%d, No_OP\n", __func__, v->voc_state); -- GitLab From 4b3e523207e04954ff8c49082f9772ddb2edf37f Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 14 Jul 2020 05:33:06 +0530 Subject: [PATCH 1564/1645] ASoC: rouleur: Update hph registers based on foundry id Rouleur has different hph settings for different foundry id. Read foundry id and update hph settings so as to provide same settings to end user. Change-Id: I114047226462ab95e0c93271c3d6099f15af2343 Signed-off-by: Vatsal Bucha --- asoc/codecs/bolero/bolero-cdc.c | 12 +++++++ asoc/codecs/bolero/bolero-cdc.h | 2 ++ asoc/codecs/bolero/internal.h | 2 ++ asoc/codecs/bolero/rx-macro.c | 10 ++++++ asoc/codecs/rouleur/internal.h | 5 +++ asoc/codecs/rouleur/pm2250-spmi.h | 5 +++ asoc/codecs/rouleur/pm2250_spmi.c | 34 +++++++++++++++++++ asoc/codecs/rouleur/rouleur.c | 55 +++++++++++++++++++++++++++++++ 8 files changed, 125 insertions(+) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 173343cab6e1..53c70fabedb8 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -238,6 +238,18 @@ static int bolero_cdc_update_wcd_event(void *handle, u16 event, u32 data) priv->component, BOLERO_MACRO_EVT_RX_PA_GAIN_UPDATE, data); break; + case WCD_BOLERO_EVT_HPHL_HD2_ENABLE: + if (priv->macro_params[RX_MACRO].event_handler) + priv->macro_params[RX_MACRO].event_handler( + priv->component, + BOLERO_MACRO_EVT_HPHL_HD2_ENABLE, data); + break; + case WCD_BOLERO_EVT_HPHR_HD2_ENABLE: + if (priv->macro_params[RX_MACRO].event_handler) + priv->macro_params[RX_MACRO].event_handler( + priv->component, + BOLERO_MACRO_EVT_HPHR_HD2_ENABLE, data); + break; default: dev_err(priv->dev, "%s: Invalid event %d trigger from wcd\n", __func__, event); diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index bcd4a255bd17..48f6cd3cd7f6 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -56,6 +56,8 @@ enum { BOLERO_MACRO_EVT_SSR_GFMUX_UP, BOLERO_MACRO_EVT_PRE_SSR_UP, BOLERO_MACRO_EVT_RX_PA_GAIN_UPDATE, + BOLERO_MACRO_EVT_HPHL_HD2_ENABLE, /* Enable HD2 cfg for HPHL */ + BOLERO_MACRO_EVT_HPHR_HD2_ENABLE, /* Enable HD2 cfg for HPHR */ }; enum { diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index 4d098da335a2..cf132bdd2cfc 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -34,6 +34,8 @@ enum { WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST, WCD_BOLERO_EVT_BCS_CLK_OFF, WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE, + WCD_BOLERO_EVT_HPHL_HD2_ENABLE, /* to enable hd2 config for hphl */ + WCD_BOLERO_EVT_HPHR_HD2_ENABLE, /* to enable hd2 config for hphr */ }; struct wcd_ctrl_platform_data { diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index f79e984ed397..07dd8adae9e7 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1463,6 +1463,16 @@ static int rx_macro_event_handler(struct snd_soc_component *component, RX_MACRO_MOD_GAIN)); } break; + case BOLERO_MACRO_EVT_HPHL_HD2_ENABLE: + /* Enable hd2 config for hphl*/ + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX0_RX_PATH_CFG0, 0x04, data); + break; + case BOLERO_MACRO_EVT_HPHR_HD2_ENABLE: + /* Enable hd2 config for hphr*/ + snd_soc_component_update_bits(component, + BOLERO_CDC_RX_RX1_RX_PATH_CFG0, 0x04, data); + break; } done: return ret; diff --git a/asoc/codecs/rouleur/internal.h b/asoc/codecs/rouleur/internal.h index b1d21faafb20..a8fc83325c33 100644 --- a/asoc/codecs/rouleur/internal.h +++ b/asoc/codecs/rouleur/internal.h @@ -88,6 +88,8 @@ struct rouleur_priv { struct notifier_block psy_nb; struct work_struct soc_eval_work; bool low_soc; + int foundry_id_reg; + int foundry_id; }; struct rouleur_micbias_setting { @@ -105,6 +107,7 @@ struct rouleur_pdata { struct cdc_regulator *regulator; int num_supplies; int reset_reg; + int foundry_id_reg; }; struct wcd_ctrl_platform_data { @@ -135,6 +138,8 @@ enum { WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST, WCD_BOLERO_EVT_BCS_CLK_OFF, WCD_BOLERO_EVT_RX_PA_GAIN_UPDATE, /* To reduce PA gain for low SoC */ + WCD_BOLERO_EVT_HPHL_HD2_ENABLE, /* to enable hd2 config for hphl */ + WCD_BOLERO_EVT_HPHR_HD2_ENABLE, /* to enable hd2 config for hphr */ }; enum { diff --git a/asoc/codecs/rouleur/pm2250-spmi.h b/asoc/codecs/rouleur/pm2250-spmi.h index 87c913d43d0f..2eaf28f02cc6 100644 --- a/asoc/codecs/rouleur/pm2250-spmi.h +++ b/asoc/codecs/rouleur/pm2250-spmi.h @@ -7,11 +7,16 @@ #ifdef CONFIG_PM2250_SPMI int pm2250_spmi_write(struct device *dev, int reg, int value); +int pm2250_spmi_read(struct device *dev, int reg, int *value); #else int pm2250_spmi_write(struct device *dev, int reg, int value) { return 0; } +int pm2250_spmi_read(struct device *dev, int reg, int *value); +{ + return 0; +} #endif /* CONFIG_PM2250_SPMI */ #endif diff --git a/asoc/codecs/rouleur/pm2250_spmi.c b/asoc/codecs/rouleur/pm2250_spmi.c index 1e5f70d177e8..10a7d109bbbe 100644 --- a/asoc/codecs/rouleur/pm2250_spmi.c +++ b/asoc/codecs/rouleur/pm2250_spmi.c @@ -25,6 +25,12 @@ static const struct of_device_id pm2250_id_table[] = { }; MODULE_DEVICE_TABLE(of, pm2250_id_table); +/** + * pm2250_spmi_write: Function to write to PMIC register + * @device: node for rouleur device + * @reg: PMIC register to write value + * @value: Value to be written to PMIC register + */ int pm2250_spmi_write(struct device *dev, int reg, int value) { int rc; @@ -47,6 +53,34 @@ int pm2250_spmi_write(struct device *dev, int reg, int value) } EXPORT_SYMBOL(pm2250_spmi_write); +/** + * pm2250_spmi_read: Function to read PMIC register + * @device: node for rouleur device + * @reg: PMIC register to read value + * @value: Pointer to value of reg to be read + */ +int pm2250_spmi_read(struct device *dev, int reg, int *value) +{ + int rc; + struct pm2250_spmi *spmi_dd; + + if (!of_device_is_compatible(dev->of_node, "qcom,pm2250-spmi")) { + pr_err("%s: Device node is invalid\n", __func__); + return -EINVAL; + } + + spmi_dd = dev_get_drvdata(dev); + if (!spmi_dd) + return -EINVAL; + + rc = regmap_read(spmi_dd->regmap, reg, value); + if (rc) + dev_err(dev, "%s: Read from PMIC register failed\n", __func__); + + return rc; +} +EXPORT_SYMBOL(pm2250_spmi_read); + static int pm2250_spmi_probe(struct platform_device *pdev) { struct pm2250_spmi *spmi_dd; diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c index 9066bd8e60d8..0a2cf8f9d9f9 100644 --- a/asoc/codecs/rouleur/rouleur.c +++ b/asoc/codecs/rouleur/rouleur.c @@ -39,6 +39,8 @@ #define SOC_THRESHOLD_LEVEL 25 #define LOW_SOC_MBIAS_REG_MIN_VOLTAGE 2850000 +#define FOUNDRY_ID_SEC 0x5 + enum { CODEC_TX = 0, CODEC_RX, @@ -641,6 +643,11 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, set_bit(HPH_PA_DELAY, &rouleur->status_mask); usleep_range(200, 210); + /* Enable HD2 Config for HPHR if foundry id is SEC */ + if (rouleur->foundry_id == FOUNDRY_ID_SEC) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_HPHR_HD2_ENABLE, + 0x04); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_PDM_WD_CTL1, 0x03, 0x03); @@ -685,6 +692,10 @@ static int rouleur_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, clear_bit(HPH_PA_DELAY, &rouleur->status_mask); } + if (rouleur->foundry_id == FOUNDRY_ID_SEC) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_HPHR_HD2_ENABLE, + 0x00); blocking_notifier_call_chain(&rouleur->mbhc->notifier, WCD_EVENT_POST_HPHR_PA_OFF, &rouleur->mbhc->wcd_mbhc); @@ -715,6 +726,10 @@ static int rouleur_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, true); set_bit(HPH_PA_DELAY, &rouleur->status_mask); usleep_range(200, 210); + if (rouleur->foundry_id == FOUNDRY_ID_SEC) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_HPHL_HD2_ENABLE, + 0x04); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_PDM_WD_CTL0, 0x03, 0x03); @@ -758,6 +773,10 @@ static int rouleur_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, clear_bit(HPH_PA_DELAY, &rouleur->status_mask); } + if (rouleur->foundry_id == FOUNDRY_ID_SEC) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_HPHL_HD2_ENABLE, + 0x00); blocking_notifier_call_chain(&rouleur->mbhc->notifier, WCD_EVENT_POST_HPHL_PA_OFF, &rouleur->mbhc->wcd_mbhc); @@ -798,6 +817,10 @@ static int rouleur_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, ROULEUR_ANA_COMBOPA_CTL, 0x40, 0x00); + if (rouleur->foundry_id == FOUNDRY_ID_SEC) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_HPHL_HD2_ENABLE, + 0x04); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_PDM_WD_CTL0, 0x03, 0x03); @@ -824,6 +847,10 @@ static int rouleur_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: usleep_range(5000, 5100); + if (rouleur->foundry_id == FOUNDRY_ID_SEC) + rouleur->update_wcd_event(rouleur->handle, + WCD_BOLERO_EVT_HPHL_HD2_ENABLE, + 0x00); snd_soc_component_update_bits(component, ROULEUR_DIG_SWR_PDM_WD_CTL0, 0x03, 0x00); @@ -2104,6 +2131,25 @@ static void rouleur_evaluate_soc(struct work_struct *work) } } +static void rouleur_get_foundry_id(struct rouleur_priv *rouleur) +{ + int ret; + + if (rouleur->foundry_id_reg == 0) { + pr_debug("%s: foundry id not defined\n", __func__); + return; + } + + ret = pm2250_spmi_read(rouleur->spmi_dev, + rouleur->foundry_id_reg, &rouleur->foundry_id); + if (ret == 0) + pr_debug("%s: rouleur foundry id = %x\n", rouleur->foundry_id, + __func__); + else + pr_debug("%s: rouleur error spmi read ret = %d\n", + __func__, ret); +} + static int rouleur_soc_codec_probe(struct snd_soc_component *component) { struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component); @@ -2159,6 +2205,8 @@ static int rouleur_soc_codec_probe(struct snd_soc_component *component) snd_soc_dapm_sync(dapm); rouleur_init_reg(component); + /* Get rouleur foundry id */ + rouleur_get_foundry_id(rouleur); rouleur->version = ROULEUR_VERSION_1_0; /* Register event notifier */ @@ -2417,6 +2465,12 @@ struct rouleur_pdata *rouleur_populate_dt_data(struct device *dev) } pdata->reset_reg = reg; + if (of_property_read_u32(dev->of_node, "qcom,foundry-id-reg", ®)) + dev_dbg(dev, "%s: Failed to obtain foundry id\n", + __func__); + else + pdata->foundry_id_reg = reg; + /* Parse power supplies */ msm_cdc_get_power_supplies(dev, &pdata->regulator, &pdata->num_supplies); @@ -2492,6 +2546,7 @@ static int rouleur_bind(struct device *dev) rouleur->spmi_dev = &pdev->dev; rouleur->reset_reg = pdata->reset_reg; + rouleur->foundry_id_reg = pdata->foundry_id_reg; ret = msm_cdc_init_supplies(dev, &rouleur->supplies, pdata->regulator, pdata->num_supplies); if (!rouleur->supplies) { -- GitLab From 34105387283dcc46fe54866bc191a0fb5dfd98ee Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Thu, 4 Jun 2020 13:12:48 +0530 Subject: [PATCH 1565/1645] ASoC: wcd937x: Add mixer ctl for TX CH power level Add mixer ctl for tx channel power level. CRs-Fixed: 2703598 Change-Id: Iecb0dfe491afaface4c4dd1995aa13c7efd9df82 Signed-off-by: Vatsal Bucha --- asoc/codecs/wcd937x/internal.h | 4 ++- asoc/codecs/wcd937x/wcd937x.c | 57 +++++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/wcd937x/internal.h b/asoc/codecs/wcd937x/internal.h index f998bf1f1f75..cf9751516952 100644 --- a/asoc/codecs/wcd937x/internal.h +++ b/asoc/codecs/wcd937x/internal.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #ifndef _WCD937X_INTERNAL_H @@ -16,6 +16,7 @@ #define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50) #define MAX_PORT 8 #define MAX_CH_PER_PORT 8 +#define MAX_TX_PWR_CH 2 extern struct regmap_config wcd937x_regmap_config; @@ -88,6 +89,7 @@ struct wcd937x_priv { int ana_clk_count; struct mutex ana_tx_clk_lock; bool usbc_hs_status; + u32 tx_ch_pwr[MAX_TX_PWR_CH]; }; struct wcd937x_micbias_setting { diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index 6e4f6872959b..f181cdd6da0b 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1768,6 +1768,48 @@ static int wcd937x_rx_hph_mode_put(struct snd_kcontrol *kcontrol, return 0; } +static int wcd937x_tx_ch_pwr_level_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); + + if (strnstr(kcontrol->id.name, "CH1", sizeof(kcontrol->id.name))) + ucontrol->value.integer.value[0] = wcd937x->tx_ch_pwr[0]; + else if (strnstr(kcontrol->id.name, "CH3", sizeof(kcontrol->id.name))) + ucontrol->value.integer.value[0] = wcd937x->tx_ch_pwr[1]; + + return 0; +} + +static int wcd937x_tx_ch_pwr_level_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component); + u32 pwr_level = ucontrol->value.enumerated.item[0]; + + dev_dbg(component->dev, "%s: tx ch pwr_level: %d\n", + __func__, pwr_level); + + if (strnstr(kcontrol->id.name, "CH1", + sizeof(kcontrol->id.name))) { + snd_soc_component_update_bits(component, + WCD937X_ANA_TX_CH1, 0x60, + pwr_level << 0x5); + wcd937x->tx_ch_pwr[0] = pwr_level; + } else if (strnstr(kcontrol->id.name, "CH3", + sizeof(kcontrol->id.name))) { + snd_soc_component_update_bits(component, + WCD937X_ANA_TX_CH3, 0x60, + pwr_level << 0x5); + wcd937x->tx_ch_pwr[1] = pwr_level; + } + return 0; +} + static int wcd937x_ear_pa_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1906,6 +1948,10 @@ static const char * const rx_hph_mode_mux_text[] = { "CLS_H_ULP", "CLS_AB_HIFI", }; +static const char * const wcd937x_tx_ch_pwr_level_text[] = { + "L0", "L1", "L2", "L3", +}; + static const char * const wcd937x_ear_pa_gain_text[] = { "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB", "G_0_DB", "G_M1P5_DB", "G_M3_DB", "G_M4P5_DB", @@ -1921,6 +1967,9 @@ static const struct soc_enum rx_hph_mode_mux_enum = static SOC_ENUM_SINGLE_EXT_DECL(wcd937x_ear_pa_gain_enum, wcd937x_ear_pa_gain_text); +static SOC_ENUM_SINGLE_EXT_DECL(wcd937x_tx_ch_pwr_level_enum, + wcd937x_tx_ch_pwr_level_text); + static const struct snd_kcontrol_new wcd937x_snd_controls[] = { SOC_ENUM_EXT("EAR PA GAIN", wcd937x_ear_pa_gain_enum, wcd937x_ear_pa_gain_get, wcd937x_ear_pa_gain_put), @@ -1939,6 +1988,10 @@ static const struct snd_kcontrol_new wcd937x_snd_controls[] = { analog_gain), SOC_SINGLE_TLV("ADC3 Volume", WCD937X_ANA_TX_CH3, 0, 20, 0, analog_gain), + SOC_ENUM_EXT("TX CH1 PWR", wcd937x_tx_ch_pwr_level_enum, + wcd937x_tx_ch_pwr_level_get, wcd937x_tx_ch_pwr_level_put), + SOC_ENUM_EXT("TX CH3 PWR", wcd937x_tx_ch_pwr_level_enum, + wcd937x_tx_ch_pwr_level_get, wcd937x_tx_ch_pwr_level_put), }; static const struct snd_kcontrol_new adc1_switch[] = { @@ -2990,7 +3043,9 @@ static int wcd937x_bind(struct device *dev) dev_err(dev, "%s: bad micbias pdata\n", __func__); goto err_irq; } - + /* default L1 power setting */ + wcd937x->tx_ch_pwr[0] = 1; + wcd937x->tx_ch_pwr[1] = 1; mutex_init(&wcd937x->micb_lock); mutex_init(&wcd937x->ana_tx_clk_lock); /* Request for watchdog interrupt */ -- GitLab From 00083bdb4f38ef287aaa9bd72af0f3fa6caffb70 Mon Sep 17 00:00:00 2001 From: Harshal Ahire Date: Tue, 7 Jul 2020 15:45:49 +0530 Subject: [PATCH 1566/1645] dsp: Add support for GET_PARAMS Add support to query module parameters from ADSP. Change-Id: Ie63dd95cf27277f9c836becc98952d48971a3ec3 Signed-off-by: Harshal Ahire --- asoc/msm-lsm-client.c | 177 ++++++++++++++++++++++++++++++++ dsp/q6lsm.c | 147 ++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 4 + include/dsp/q6lsm.h | 17 +++ include/uapi/sound/lsm_params.h | 29 +++++- 5 files changed, 372 insertions(+), 2 deletions(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 8a179fde913a..77b25de138c1 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -1700,6 +1700,17 @@ struct lsm_params_info_v2_32 { u16 stage_idx; }; +struct lsm_params_get_info_32 { + u32 module_id; + u16 instance_id; + u16 reserved; + u32 param_id; + u32 param_size; + uint32_t param_type; + __u16 stage_idx; + u8 payload[0]; +} __packed; + struct snd_lsm_module_params_32 { compat_uptr_t params; u32 num_params; @@ -1717,6 +1728,8 @@ enum { _IOW('U', 0x0F, struct snd_lsm_event_status_v3_32), SNDRV_LSM_SET_MODULE_PARAMS_V2_32 = _IOW('U', 0x13, struct snd_lsm_module_params_32), + SNDRV_LSM_GET_MODULE_PARAMS_32 = + _IOWR('U', 0x14, struct lsm_params_get_info_32), }; static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, @@ -2096,6 +2109,95 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, kfree(params32); break; } + case SNDRV_LSM_GET_MODULE_PARAMS_32: { + struct lsm_params_get_info_32 p_info_32, *param_info_rsp = NULL; + struct lsm_params_get_info *p_info = NULL; + + memset(&p_info_32, 0 , sizeof(p_info_32)); + if (!prtd->lsm_client->use_topology) { + dev_err(rtd->dev, + "%s: %s: not supported if not using topology\n", + __func__, "GET_MODULE_PARAMS_32"); + err = -EINVAL; + goto done; + } + + if (copy_from_user(&p_info_32, arg, sizeof(p_info_32))) { + dev_err(rtd->dev, + "%s: %s: copy_from_user failed, size = %zd\n", + __func__, "GET_MODULE_PARAMS_32", + sizeof(p_info_32)); + err = -EFAULT; + goto done; + } + size = sizeof(p_info_32); + p_info = kzalloc(size, GFP_KERNEL); + + if (!p_info) { + err = -ENOMEM; + goto done; + } + + p_info->module_id = p_info_32.module_id; + p_info->param_id = p_info_32.param_id; + p_info->param_size = p_info_32.param_size; + p_info->param_type = p_info_32.param_type; + p_info->instance_id = p_info_32.instance_id; + p_info->stage_idx = p_info_32.stage_idx; + + prtd->lsm_client->get_param_payload = kzalloc(p_info_32.param_size, + GFP_KERNEL); + if (!prtd->lsm_client->get_param_payload) { + err = -ENOMEM; + kfree(p_info); + goto done; + } + prtd->lsm_client->param_size = p_info_32.param_size; + + err = q6lsm_get_one_param(prtd->lsm_client, p_info, + LSM_GET_CUSTOM_PARAMS); + if (err) { + dev_err(rtd->dev, + "%s: Failed to get custom param, err=%d\n", + __func__, err); + kfree(p_info); + kfree(prtd->lsm_client->get_param_payload); + goto done; + } + + size = sizeof(p_info_32) + p_info_32.param_size; + param_info_rsp = kzalloc(size, GFP_KERNEL); + + if (!param_info_rsp) { + err = -ENOMEM; + kfree(p_info); + kfree(prtd->lsm_client->get_param_payload); + goto done; + } + + if (!access_ok(VERIFY_WRITE, arg, size)) { + dev_err(rtd->dev, + "%s: Failed to verify write, size = %d\n", + __func__, size); + err = -EFAULT; + goto free; + } + + memcpy(param_info_rsp, &p_info_32, sizeof(p_info_32)); + memcpy(param_info_rsp->payload, prtd->lsm_client->get_param_payload, + p_info_32.param_size); + + if (copy_to_user(arg, param_info_rsp, size)) { + dev_err(rtd->dev, "%s: Failed to copy payload to user, size = %d\n", + __func__, size); + err = -EFAULT; + } +free: + kfree(p_info); + kfree(param_info_rsp); + kfree(prtd->lsm_client->get_param_payload); + break; + } case SNDRV_LSM_REG_SND_MODEL_V2: case SNDRV_LSM_SET_PARAMS: case SNDRV_LSM_SET_MODULE_PARAMS: @@ -2303,6 +2405,81 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, break; } + case SNDRV_LSM_GET_MODULE_PARAMS: { + struct lsm_params_get_info temp_p_info, *p_info = NULL; + + memset(&temp_p_info, 0, sizeof(temp_p_info)); + if (!prtd->lsm_client->use_topology) { + dev_err(rtd->dev, + "%s: %s: not supported if not using topology\n", + __func__, "GET_MODULE_PARAMS_32"); + err = -EINVAL; + goto done; + } + + if (copy_from_user(&temp_p_info, arg, sizeof(temp_p_info))) { + dev_err(rtd->dev, + "%s: %s: copy_from_user failed, size = %zd\n", + __func__, "GET_MODULE_PARAMS_32", + sizeof(temp_p_info)); + err = -EFAULT; + goto done; + } + size = sizeof(temp_p_info) + temp_p_info.param_size; + p_info = kzalloc(size, GFP_KERNEL); + + if (!p_info) { + err = -ENOMEM; + goto done; + } + + p_info->module_id = temp_p_info.module_id; + p_info->param_id = temp_p_info.param_id; + p_info->param_size = temp_p_info.param_size; + p_info->param_type = temp_p_info.param_type; + p_info->instance_id = temp_p_info.instance_id; + p_info->stage_idx = temp_p_info.stage_idx; + + prtd->lsm_client->get_param_payload = kzalloc(temp_p_info.param_size, + GFP_KERNEL); + if (!prtd->lsm_client->get_param_payload) { + err = -ENOMEM; + kfree(p_info); + goto done; + } + + prtd->lsm_client->param_size = p_info->param_size; + err = q6lsm_get_one_param(prtd->lsm_client, p_info, + LSM_GET_CUSTOM_PARAMS); + if (err) { + dev_err(rtd->dev, + "%s: Failed to get custom param, err=%d\n", + __func__, err); + goto free; + } + + if (!access_ok(VERIFY_WRITE, arg, size)) { + dev_err(rtd->dev, + "%s: Failed to verify write, size = %d\n", + __func__, size); + err = -EFAULT; + goto free; + } + + memcpy(p_info->payload, prtd->lsm_client->get_param_payload, + temp_p_info.param_size); + + if (copy_to_user(arg, p_info, sizeof(struct lsm_params_get_info) + + p_info->param_size)) { + dev_err(rtd->dev, "%s: Failed to copy payload to user, size = %d\n", + __func__, size); + err = -EFAULT; + } +free: + kfree(p_info); + kfree(prtd->lsm_client->get_param_payload); + break; + } case SNDRV_LSM_EVENT_STATUS: case SNDRV_LSM_GENERIC_DET_EVENT: { struct snd_lsm_event_status *user = NULL; diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index c00bb9406833..cc57a25361a6 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -190,6 +190,58 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) client->priv); spin_unlock_irqrestore(&lsm_session_lock, flags); return 0; + } else if (data->opcode == LSM_SESSION_CMDRSP_GET_PARAMS_V3 || + data->opcode == LSM_SESSION_CMDRSP_GET_PARAMS_V2) { + + uint32_t payload_min_size_expected = 0; + uint32_t param_size = 0, ret = 0; + /* + * sizeof(uint32_t) is added to accomodate the status field + * in adsp response payload + */ + + if (data->opcode == LSM_SESSION_CMDRSP_GET_PARAMS_V3) + payload_min_size_expected = sizeof(uint32_t) + + sizeof(struct param_hdr_v3); + else + payload_min_size_expected = sizeof(uint32_t) + + sizeof(struct param_hdr_v2); + + if (data->payload_size < payload_min_size_expected) { + pr_err("%s: invalid payload size %d expected size %d\n", + __func__, data->payload_size, + payload_min_size_expected); + ret = -EINVAL; + goto done; + } + + if (data->opcode == LSM_SESSION_CMDRSP_GET_PARAMS_V3) + param_size = payload[4]; + else + param_size = payload[3]; + + if (data->payload_size != payload_min_size_expected + param_size) { + pr_err("%s: cmdrsp_get_params error payload size %d expected size %d\n", + __func__, data->payload_size, + payload_min_size_expected + param_size); + ret = -EINVAL; + goto done; + } + + if (client->param_size != param_size) { + pr_err("%s: response payload size %d mismatched with user requested %d\n", + __func__, param_size, client->param_size); + ret = -EINVAL; + goto done; + } + + memcpy((u8 *)client->get_param_payload, + (u8 *)payload + payload_min_size_expected, param_size); +done: + spin_unlock_irqrestore(&lsm_session_lock, flags); + atomic_set(&client->cmd_state, CMD_STATE_CLEARED); + wake_up(&client->cmd_wait); + return ret; } else if (data->opcode == APR_BASIC_RSP_RESULT) { token = data->token; switch (payload[0]) { @@ -208,6 +260,8 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) case LSM_CMD_ADD_TOPOLOGIES: case LSM_SESSION_CMD_SET_PARAMS_V2: case LSM_SESSION_CMD_SET_PARAMS_V3: + case LSM_SESSION_CMD_GET_PARAMS_V2: + case LSM_SESSION_CMD_GET_PARAMS_V3: if (token != client->session && payload[0] != LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL) { @@ -623,6 +677,48 @@ static int q6lsm_set_params_v3(struct lsm_client *client, return ret; } +static int q6lsm_get_params_v2(struct lsm_client *client, + struct mem_mapping_hdr *mem_hdr, + struct param_hdr_v2 *param_hdr) +{ + struct lsm_session_cmd_get_params_v2 lsm_get_param; + uint16_t pkt_size = sizeof(lsm_get_param); + + memset(&lsm_get_param, 0, pkt_size); + q6lsm_add_hdr(client, &lsm_get_param.apr_hdr, pkt_size, true); + lsm_get_param.apr_hdr.opcode = LSM_SESSION_CMD_GET_PARAMS_V2; + + if (mem_hdr != NULL) + lsm_get_param.mem_hdr = *mem_hdr; + + memcpy(&lsm_get_param.param_info, param_hdr, + sizeof(struct param_hdr_v2)); + + return q6lsm_apr_send_pkt(client, client->apr, &lsm_get_param, true, + NULL); +} + +static int q6lsm_get_params_v3(struct lsm_client *client, + struct mem_mapping_hdr *mem_hdr, + struct param_hdr_v3 *param_hdr) +{ + struct lsm_session_cmd_get_params_v3 lsm_get_param; + uint16_t pkt_size = sizeof(lsm_get_param); + + memset(&lsm_get_param, 0, pkt_size); + q6lsm_add_hdr(client, &lsm_get_param.apr_hdr, pkt_size, true); + lsm_get_param.apr_hdr.opcode = LSM_SESSION_CMD_GET_PARAMS_V3; + + if (mem_hdr != NULL) + lsm_get_param.mem_hdr = *mem_hdr; + + memcpy(&lsm_get_param.param_info, param_hdr, + sizeof(struct param_hdr_v3)); + + return q6lsm_apr_send_pkt(client, client->apr, &lsm_get_param, true, + NULL); +} + static int q6lsm_set_params(struct lsm_client *client, struct mem_mapping_hdr *mem_hdr, uint8_t *param_data, uint32_t param_size, @@ -665,6 +761,27 @@ static int q6lsm_pack_and_set_params(struct lsm_client *client, return ret; } +static int q6lsm_get_params(struct lsm_client *client, + struct mem_mapping_hdr *mem_hdr, + struct param_hdr_v3 *param_info) + +{ + struct param_hdr_v2 param_info_v2; + int ret = 0; + bool iid_supported = q6common_is_instance_id_supported(); + memset(¶m_info_v2, 0, sizeof(struct param_hdr_v2)); + + if (iid_supported) + ret = q6lsm_get_params_v3(client, mem_hdr, param_info); + else { + param_info_v2.module_id = param_info->module_id; + param_info_v2.param_id = param_info->param_id; + param_info_v2.param_size = param_info->param_size; + ret = q6lsm_get_params_v2(client, mem_hdr, ¶m_info_v2); + } + return ret; +} + static int q6lsm_send_custom_topologies(struct lsm_client *client) { int rc; @@ -2313,6 +2430,36 @@ int q6lsm_set_one_param(struct lsm_client *client, } EXPORT_SYMBOL(q6lsm_set_one_param); +int q6lsm_get_one_param(struct lsm_client *client, + struct lsm_params_get_info *p_info, + uint32_t param_type) +{ + struct param_hdr_v3 param_info; + int rc = 0; + + memset(¶m_info, 0, sizeof(param_info)); + + switch (param_type) { + case LSM_GET_CUSTOM_PARAMS: { + param_info.module_id = p_info->module_id; + param_info.instance_id = p_info->instance_id; + param_info.param_id = p_info->param_id; + param_info.param_size = p_info->param_size + sizeof(param_info); + rc = q6lsm_get_params(client, NULL, ¶m_info); + if (rc) { + pr_err("%s: LSM_GET_CUSTOM_PARAMS failed, rc %d\n", + __func__, rc); + } + break; + + } + default: + pr_err("%s: wrong param_type 0x%x\n", + __func__, p_info->param_type); + } + return rc; +} +EXPORT_SYMBOL(q6lsm_get_one_param); /** * q6lsm_start - diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 607b9101c886..eed5652f910e 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -11694,6 +11694,10 @@ struct avcs_fwk_ver_info { #define LSM_SESSION_CMD_SET_PARAMS (0x00012A83) #define LSM_SESSION_CMD_SET_PARAMS_V2 (0x00012A8F) #define LSM_SESSION_CMD_SET_PARAMS_V3 (0x00012A92) +#define LSM_SESSION_CMD_GET_PARAMS_V2 (0x00012A90) +#define LSM_SESSION_CMDRSP_GET_PARAMS_V2 (0x00012A91) +#define LSM_SESSION_CMD_GET_PARAMS_V3 (0x00012A93) +#define LSM_SESSION_CMDRSP_GET_PARAMS_V3 (0x00012A94) #define LSM_SESSION_CMD_REGISTER_SOUND_MODEL (0x00012A84) #define LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL (0x00012A85) #define LSM_SESSION_CMD_START (0x00012A86) diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h index 02897d98e06d..d5d6ad63b164 100644 --- a/include/dsp/q6lsm.h +++ b/include/dsp/q6lsm.h @@ -106,6 +106,8 @@ struct lsm_client { struct lsm_stage_config stage_cfg[LSM_MAX_STAGES_PER_SESSION]; uint64_t fe_id; uint16_t unprocessed_data; + void *get_param_payload; + size_t param_size; }; struct lsm_stream_cmd_open_tx { @@ -153,6 +155,18 @@ struct lsm_session_cmd_set_params_v3 { u32 param_data[0]; } __packed; +struct lsm_session_cmd_get_params_v2 { + struct apr_hdr apr_hdr; + struct mem_mapping_hdr mem_hdr; + struct param_hdr_v2 param_info; +} __packed; + +struct lsm_session_cmd_get_params_v3 { + struct apr_hdr apr_hdr; + struct mem_mapping_hdr mem_hdr; + struct param_hdr_v3 param_info; +} __packed; + struct lsm_param_op_mode { uint32_t minor_version; uint16_t mode; @@ -289,6 +303,9 @@ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc); int q6lsm_set_one_param(struct lsm_client *client, struct lsm_params_info_v2 *p_info, void *data, uint32_t param_type); +int q6lsm_get_one_param(struct lsm_client *client, + struct lsm_params_get_info *p_info, + uint32_t param_type); void q6lsm_sm_set_param_data(struct lsm_client *client, struct lsm_params_info_v2 *p_info, size_t *offset); diff --git a/include/uapi/sound/lsm_params.h b/include/uapi/sound/lsm_params.h index 57dc3be5d454..8e1a3d6bbf53 100644 --- a/include/uapi/sound/lsm_params.h +++ b/include/uapi/sound/lsm_params.h @@ -34,7 +34,8 @@ #define LSM_POLLING_ENABLE (7) #define LSM_DET_EVENT_TYPE (8) #define LSM_LAB_CONTROL (9) -#define LSM_PARAMS_MAX (LSM_LAB_CONTROL + 1) +#define LSM_GET_CUSTOM_PARAMS (10) +#define LSM_PARAMS_MAX (LSM_GET_CUSTOM_PARAMS + 1) #define LSM_EVENT_NON_TIME_STAMP_MODE (0) #define LSM_EVENT_TIME_STAMP_MODE (1) @@ -284,6 +285,29 @@ struct snd_lsm_input_hw_params { __u16 num_channels; } __packed; +/* + * Param get info for each parameter type + * add "for SNDRV_LSM_GET_MODULE_PARAMS ioctl" + * Existing member variables: + * @module_id: Module to which parameter is to be set + * @instance_id: instance id of the param to which parameter is to be set + * @param_id: Parameter that is to be set + * @param_size: size of requested param + * @param_type: Parameter type as defined in values upto LSM_PARAMS_MAX + * @stage_idx: detection stage for which the param is applicable + * @payload: memory where requested param info will be populated + */ +struct lsm_params_get_info { + __u32 module_id; + __u16 instance_id; + __u16 reserved; + __u32 param_id; + __u32 param_size; + uint32_t param_type; + __u16 stage_idx; + __u8 payload[0]; +} __packed; + #define SNDRV_LSM_DEREG_SND_MODEL _IOW('U', 0x01, int) #define SNDRV_LSM_EVENT_STATUS _IOW('U', 0x02, struct snd_lsm_event_status) #define SNDRV_LSM_ABORT_EVENT _IOW('U', 0x03, int) @@ -311,5 +335,6 @@ struct snd_lsm_input_hw_params { struct snd_lsm_session_data_v2) #define SNDRV_LSM_SET_MODULE_PARAMS_V2 _IOW('U', 0x13, \ struct snd_lsm_module_params) - +#define SNDRV_LSM_GET_MODULE_PARAMS _IOWR('U', 0x14, \ + struct lsm_params_get_info) #endif -- GitLab From 2f0dee30677424b586bacc275ed3cecc75a78255 Mon Sep 17 00:00:00 2001 From: Harshal Ahire Date: Mon, 10 Aug 2020 01:59:14 +0530 Subject: [PATCH 1567/1645] asoc: Register widgets and intercons only when supported Register for the widgets and interconnections in routing driver only when the respective interfaces are supported. Add config based approach for TDM, AUXPCM and MI2S interfaces. Change-Id: I2b76e295d7cafde6062a3e0afbe7f25721fa9cca Signed-off-by: Harshal Ahire --- asoc/msm-pcm-routing-v2.c | 37560 ++++++++++++++++++------------------ 1 file changed, 19036 insertions(+), 18524 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 580c59889cc5..03603a2cf672 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -58,6 +58,7 @@ static int fm_switch_enable; static int hfp_switch_enable; static int a2dp_switch_enable; static int sco_switch_enable; +#ifndef CONFIG_MI2S_DISABLE static int int0_mi2s_switch_enable; static int int4_mi2s_switch_enable; static int pri_mi2s_switch_enable; @@ -66,6 +67,7 @@ static int tert_mi2s_switch_enable; static int quat_mi2s_switch_enable; static int quin_mi2s_switch_enable; static int sen_mi2s_switch_enable; +#endif static int fm_pcmrx_switch_enable; static int usb_switch_enable; static int lsm_port_index[MAX_LSM_SESSIONS]; @@ -2694,7 +2696,7 @@ static int msm_routing_sco_switch_mixer_put(struct snd_kcontrol *kcontrol, 0, update); return 1; } - +#ifndef CONFIG_MI2S_DISABLE static int msm_routing_get_int0_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2751,34 +2753,6 @@ static int msm_routing_put_int4_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, return 1; } -static int msm_routing_get_usb_switch_mixer(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = usb_switch_enable; - pr_debug("%s: HFP Switch enable %ld\n", __func__, - ucontrol->value.integer.value[0]); - return 0; -} - -static int msm_routing_put_usb_switch_mixer(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_dapm_update *update = NULL; - - pr_debug("%s: USB Switch enable %ld\n", __func__, - ucontrol->value.integer.value[0]); - if (ucontrol->value.integer.value[0]) - snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, - 1, update); - else - snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, - 0, update); - usb_switch_enable = ucontrol->value.integer.value[0]; - return 1; -} - static int msm_routing_get_pri_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2954,6 +2928,35 @@ static int msm_routing_put_sen_mi2s_switch_mixer( sen_mi2s_switch_enable = ucontrol->value.integer.value[0]; return 1; } +#endif + +static int msm_routing_get_usb_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = usb_switch_enable; + pr_debug("%s: HFP Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_put_usb_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: USB Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + if (ucontrol->value.integer.value[0]) + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, + 1, update); + else + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, + 0, update); + usb_switch_enable = ucontrol->value.integer.value[0]; + return 1; +} static int msm_routing_get_fm_pcmrx_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -5827,197 +5830,6 @@ static const struct snd_kcontrol_new voc_ext_ec_mux = SOC_DAPM_ENUM_EXT("VOC_EXT_EC MUX Mux", msm_route_ext_ec_ref_rx_enum[0], msm_routing_ext_ec_get, msm_routing_ext_ec_put); - -static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - static const struct snd_kcontrol_new pri_spdif_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_RX, @@ -6469,13 +6281,204 @@ static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = { msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE +static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, @@ -7456,17068 +7459,16656 @@ static const struct snd_kcontrol_new sec_meta_mi2s_rx_mixer_controls[] = { msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new hdmi_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), +static const struct snd_kcontrol_new int0_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_INT3_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new hdmi_ms_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), +static const struct snd_kcontrol_new int4_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_INT3_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new display_port_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), +static const struct snd_kcontrol_new sec_i2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new display_port1_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), +static const struct snd_kcontrol_new mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; - /* incall music delivery mixer */ -static const struct snd_kcontrol_new incall_music_delivery_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), +static const struct snd_kcontrol_new primary_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new incall_music2_delivery_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), +static const struct snd_kcontrol_new quat_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new slimbus_4_rx_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_RX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_RX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_RX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_RX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), +static const struct snd_kcontrol_new quin_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new slimbus_6_rx_mixer_controls[] = { +static const struct snd_kcontrol_new sen_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + + +static const struct snd_kcontrol_new tert_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new int0_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_int0_mi2s_switch_mixer, + msm_routing_put_int0_mi2s_switch_mixer); + +static const struct snd_kcontrol_new int4_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_int4_mi2s_switch_mixer, + msm_routing_put_int4_mi2s_switch_mixer); + +static const struct snd_kcontrol_new pri_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_pri_mi2s_switch_mixer, + msm_routing_put_pri_mi2s_switch_mixer); + +static const struct snd_kcontrol_new sec_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_sec_mi2s_switch_mixer, + msm_routing_put_sec_mi2s_switch_mixer); + +static const struct snd_kcontrol_new tert_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_tert_mi2s_switch_mixer, + msm_routing_put_tert_mi2s_switch_mixer); + +static const struct snd_kcontrol_new quat_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_quat_mi2s_switch_mixer, + msm_routing_put_quat_mi2s_switch_mixer); + +static const struct snd_kcontrol_new quin_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_quin_mi2s_switch_mixer, + msm_routing_put_quin_mi2s_switch_mixer); + +static const struct snd_kcontrol_new sen_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_sen_mi2s_switch_mixer, + msm_routing_put_sen_mi2s_switch_mixer); +#endif + +static const struct snd_kcontrol_new hdmi_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_mixer_controls[] = { +static const struct snd_kcontrol_new hdmi_ms_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new wsa_cdc_dma_rx_1_mixer_controls[] = { +static const struct snd_kcontrol_new display_port_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new rx_cdc_dma_rx_0_mixer_controls[] = { +static const struct snd_kcontrol_new display_port1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new rx_cdc_dma_rx_1_mixer_controls[] = { + /* incall music delivery mixer */ +static const struct snd_kcontrol_new incall_music_delivery_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new incall_music2_delivery_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new slimbus_4_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new slimbus_6_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new rx_cdc_dma_rx_2_mixer_controls[] = { +static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new rx_cdc_dma_rx_3_mixer_controls[] = { +static const struct snd_kcontrol_new wsa_cdc_dma_rx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new rx_cdc_dma_rx_4_mixer_controls[] = { +static const struct snd_kcontrol_new rx_cdc_dma_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new rx_cdc_dma_rx_5_mixer_controls[] = { +static const struct snd_kcontrol_new rx_cdc_dma_rx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new rx_cdc_dma_rx_6_mixer_controls[] = { +static const struct snd_kcontrol_new rx_cdc_dma_rx_2_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new rx_cdc_dma_rx_7_mixer_controls[] = { +static const struct snd_kcontrol_new rx_cdc_dma_rx_3_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new slimbus_7_rx_mixer_controls[] = { +static const struct snd_kcontrol_new rx_cdc_dma_rx_4_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new slimbus_9_rx_mixer_controls[] = { +static const struct snd_kcontrol_new rx_cdc_dma_rx_5_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new usb_audio_rx_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + +static const struct snd_kcontrol_new rx_cdc_dma_rx_6_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = { +static const struct snd_kcontrol_new rx_cdc_dma_rx_7_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new int_bt_a2dp_rx_mixer_controls[] = { +static const struct snd_kcontrol_new slimbus_7_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = { +static const struct snd_kcontrol_new slimbus_9_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), }; - -static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = { +static const struct snd_kcontrol_new usb_audio_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = { +static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = { +static const struct snd_kcontrol_new int_bt_a2dp_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new tert_auxpcm_rx_mixer_controls[] = { +static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quat_auxpcm_rx_mixer_controls[] = { +static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quin_auxpcm_rx_mixer_controls[] = { +#ifndef CONFIG_AUXPCM_DISABLE +static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sen_auxpcm_rx_mixer_controls[] = { +static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = { +static const struct snd_kcontrol_new tert_auxpcm_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = { +static const struct snd_kcontrol_new quat_auxpcm_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = { +static const struct snd_kcontrol_new quin_auxpcm_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = { +static const struct snd_kcontrol_new sen_auxpcm_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; +#endif -static const struct snd_kcontrol_new pri_tdm_tx_0_mixer_controls[] = { +#ifndef CONFIG_TDM_DISABLE +static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = { +static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = { +static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = { +static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = { +static const struct snd_kcontrol_new pri_tdm_tx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sec_tdm_tx_0_mixer_controls[] = { +static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new tert_tdm_rx_0_mixer_controls[] = { +static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new tert_tdm_tx_0_mixer_controls[] = { +static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new tert_tdm_rx_1_mixer_controls[] = { +static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = { +static const struct snd_kcontrol_new sec_tdm_tx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = { +static const struct snd_kcontrol_new tert_tdm_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = { +static const struct snd_kcontrol_new tert_tdm_tx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = { +static const struct snd_kcontrol_new tert_tdm_rx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quat_tdm_tx_0_mixer_controls[] = { +static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quat_tdm_rx_1_mixer_controls[] = { +static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = { +static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = { +static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quin_tdm_rx_0_mixer_controls[] = { +static const struct snd_kcontrol_new quat_tdm_tx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quin_tdm_tx_0_mixer_controls[] = { +static const struct snd_kcontrol_new quat_tdm_rx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quin_tdm_tx_1_mixer_controls[] = { +static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new quin_tdm_rx_1_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quin_tdm_tx_2_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_tx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quin_tdm_tx_3_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_tx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_rx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sen_tdm_rx_0_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_tx_2_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sen_tdm_tx_0_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sen_tdm_rx_1_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_tx_3_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sen_tdm_rx_2_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sen_tdm_rx_3_mixer_controls[] = { +static const struct snd_kcontrol_new sen_tdm_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new mmul1_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul2_mixer_controls[] = { - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul3_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul4_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul5_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul6_mixer_controls[] = { - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul8_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul16_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul9_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul10_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; -static const struct snd_kcontrol_new mmul17_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul18_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul19_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul20_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul21_mixer_controls[] = { - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul22_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul23_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul24_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul25_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul27_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul28_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul29_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul30_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new sec_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new slimbus_6_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new usb_audio_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new display_port_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new display_port_rx1_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new pri_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new int0_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new int4_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new tert_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new quat_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new quin_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new sen_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new sec_aux_pcm_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new tert_aux_pcm_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new quat_aux_pcm_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new quin_aux_pcm_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new sen_aux_pcm_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, MSM_BACKEND_DAI_SEN_AUXPCM_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, MSM_BACKEND_DAI_SEN_AUXPCM_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, MSM_BACKEND_DAI_SEN_AUXPCM_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new slimbus_7_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new slimbus_8_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new quat_tdm_rx_2_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new quin_tdm_rx_2_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new wsa_cdc_dma_rx_1_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_0_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_1_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_2_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_3_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_4_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_5_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_6_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_7_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new pri_tdm_rx_0_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new pri_tdm_rx_1_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new pri_tdm_rx_2_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new pri_tdm_rx_3_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new stub_rx_mixer_controls[] = { - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_EXTPROC_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_EXTPROC_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new slimbus_1_rx_mixer_controls[] = { - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = { - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new proxy_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PROXY_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PROXY_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_TX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("MI2S_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("INT_BT_SCO_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PROXY_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PROXY_TX, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_TX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("MI2S_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("INT_BT_SCO_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PROXY_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PROXY_TX, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("MI2S_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_3_Voip", MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { - SOC_DOUBLE_EXT("STUB_TX_HL", SND_SOC_NOPM, - MSM_BACKEND_DAI_EXTPROC_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("STUB_1_TX_HL", SND_SOC_NOPM, - MSM_BACKEND_DAI_EXTPROC_EC_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), -}; - -static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = { - SOC_DOUBLE_EXT("STUB_TX_HL", SND_SOC_NOPM, - MSM_BACKEND_DAI_EXTPROC_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("STUB_1_TX_HL", SND_SOC_NOPM, - MSM_BACKEND_DAI_EXTPROC_EC_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), -}; - -static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = { - SOC_DOUBLE_EXT("STUB_TX_HL", SND_SOC_NOPM, - MSM_BACKEND_DAI_EXTPROC_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("STUB_1_TX_HL", SND_SOC_NOPM, - MSM_BACKEND_DAI_EXTPROC_EC_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), -}; - -static const struct snd_kcontrol_new tx_qchat_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("MI2S_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new int0_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_INT3_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new int4_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_INT3_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_port_mixer_controls[] = { - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_0_port_mixer_controls[] = { - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_PRI_MI2S_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_MI2S_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SENARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new aux_pcm_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_auxpcm_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new tert_auxpcm_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quat_auxpcm_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quin_auxpcm_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sen_auxpcm_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sbus_1_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sbus_3_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_BACKEND_DAI_INT_BT_SCO_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_BACKEND_DAI_AFE_PCM_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_BACKEND_DAI_AUXPCM_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_BACKEND_DAI_SLIMBUS_0_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sbus_6_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new bt_sco_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new afe_pcm_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - - -static const struct snd_kcontrol_new hdmi_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new hdmi_rx_ms_port_mixer_controls[] = { - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new display_port_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new display_port_rx1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_i2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new primary_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new usb_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, - MSM_BACKEND_DAI_USB_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quat_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quin_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sen_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new pri_tdm_rx_0_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new pri_tdm_rx_1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new pri_tdm_rx_2_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new pri_tdm_rx_3_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_tdm_rx_0_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_tdm_rx_1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_tdm_rx_2_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_tdm_rx_3_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_tdm_rx_7_port_mixer_controls[] = { - SOC_DOUBLE_EXT("TERT_TDM_TX_7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_7, - MSM_BACKEND_DAI_TERT_TDM_TX_7, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new tert_tdm_rx_0_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new tert_tdm_rx_1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new tert_tdm_rx_2_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new tert_tdm_rx_3_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quat_tdm_rx_0_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quat_tdm_rx_1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quat_tdm_rx_2_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quat_tdm_rx_3_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quat_tdm_rx_7_port_mixer_controls[] = { - SOC_DOUBLE_EXT("QUAT_TDM_TX_7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_7, - MSM_BACKEND_DAI_QUAT_TDM_TX_7, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_7, - MSM_BACKEND_DAI_QUIN_TDM_TX_7, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quin_tdm_rx_0_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quin_tdm_rx_1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quin_tdm_rx_2_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quin_tdm_rx_3_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sen_tdm_rx_0_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sen_tdm_rx_1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sen_tdm_rx_2_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sen_tdm_rx_3_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quin_tdm_rx_7_port_mixer_controls[] = { - SOC_DOUBLE_EXT("TERT_TDM_TX_7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_7, - MSM_BACKEND_DAI_TERT_TDM_TX_7, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_7, - MSM_BACKEND_DAI_QUAT_TDM_TX_7, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_7, - MSM_BACKEND_DAI_QUIN_TDM_TX_7, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new tert_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new lsm1_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_5_TX, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), -}; - -static const struct snd_kcontrol_new lsm2_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_1_TX", - SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_5_TX, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), -}; - -static const struct snd_kcontrol_new lsm3_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_5_TX, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), -}; - -static const struct snd_kcontrol_new lsm4_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_5_TX, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), -}; - -static const struct snd_kcontrol_new lsm5_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_5_TX, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), -}; - -static const struct snd_kcontrol_new lsm6_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_5_TX, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), -}; - -static const struct snd_kcontrol_new lsm7_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_5_TX, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), -}; - -static const struct snd_kcontrol_new lsm8_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_5_TX, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), -}; - -static const struct snd_kcontrol_new slim_fm_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_switch_mixer, - msm_routing_put_switch_mixer); - -static const struct snd_kcontrol_new slim1_fm_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_switch_mixer, - msm_routing_put_switch_mixer); - -static const struct snd_kcontrol_new slim3_fm_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_switch_mixer, - msm_routing_put_switch_mixer); - -static const struct snd_kcontrol_new slim4_fm_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_switch_mixer, - msm_routing_put_switch_mixer); - -static const struct snd_kcontrol_new cdc_dma_wsa_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_switch_mixer, - msm_routing_put_switch_mixer); - -static const struct snd_kcontrol_new cdc_dma_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_switch_mixer, - msm_routing_put_switch_mixer); - -static const struct snd_kcontrol_new cdc_dma_rx_1_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_switch_mixer, - msm_routing_put_switch_mixer); - -static const struct snd_kcontrol_new slim6_fm_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_switch_mixer, - msm_routing_put_switch_mixer); - -static const struct snd_kcontrol_new pcm_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_fm_pcmrx_switch_mixer, - msm_routing_put_fm_pcmrx_switch_mixer); - -static const struct snd_kcontrol_new int0_mi2s_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_int0_mi2s_switch_mixer, - msm_routing_put_int0_mi2s_switch_mixer); - -static const struct snd_kcontrol_new int4_mi2s_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_int4_mi2s_switch_mixer, - msm_routing_put_int4_mi2s_switch_mixer); - -static const struct snd_kcontrol_new pri_mi2s_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_pri_mi2s_switch_mixer, - msm_routing_put_pri_mi2s_switch_mixer); - -static const struct snd_kcontrol_new sec_mi2s_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_sec_mi2s_switch_mixer, - msm_routing_put_sec_mi2s_switch_mixer); - -static const struct snd_kcontrol_new tert_mi2s_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_tert_mi2s_switch_mixer, - msm_routing_put_tert_mi2s_switch_mixer); - -static const struct snd_kcontrol_new quat_mi2s_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_quat_mi2s_switch_mixer, - msm_routing_put_quat_mi2s_switch_mixer); - -static const struct snd_kcontrol_new quin_mi2s_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_quin_mi2s_switch_mixer, - msm_routing_put_quin_mi2s_switch_mixer); - -static const struct snd_kcontrol_new sen_mi2s_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_sen_mi2s_switch_mixer, - msm_routing_put_sen_mi2s_switch_mixer); - -static const struct snd_kcontrol_new hfp_pri_aux_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_hfp_switch_mixer, - msm_routing_put_hfp_switch_mixer); - -static const struct snd_kcontrol_new hfp_aux_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_hfp_switch_mixer, - msm_routing_put_hfp_switch_mixer); - -static const struct snd_kcontrol_new hfp_int_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_hfp_switch_mixer, - msm_routing_put_hfp_switch_mixer); - -static const struct snd_kcontrol_new hfp_slim7_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_hfp_switch_mixer, - msm_routing_put_hfp_switch_mixer); - -static const struct snd_kcontrol_new usb_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_usb_switch_mixer, - msm_routing_put_usb_switch_mixer); - -static const struct snd_kcontrol_new a2dp_slim7_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_a2dp_switch_mixer_get, - msm_routing_a2dp_switch_mixer_put); - -static const struct snd_kcontrol_new sco_slim7_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_sco_switch_mixer_get, - msm_routing_sco_switch_mixer_put); - -static const struct soc_enum lsm_port_enum = - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_port_text), lsm_port_text); - -static const char * const lsm_func_text[] = { - "None", "AUDIO", "BEACON", "ULTRASOUND", "SWAUDIO", -}; -static const struct soc_enum lsm_func_enum = - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_func_text), lsm_func_text); - -static const struct snd_kcontrol_new lsm_controls[] = { - /* kcontrol of lsm_function */ - SOC_ENUM_EXT(SLIMBUS_0_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(SLIMBUS_1_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(SLIMBUS_2_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(SLIMBUS_3_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(SLIMBUS_4_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(SLIMBUS_5_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(TERT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(QUAT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(INT3_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(TX_CDC_DMA_TX_3_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(QUIN_TDM_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(TERT_TDM_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - /* kcontrol of lsm_port */ - SOC_ENUM_EXT("LSM1 Port", lsm_port_enum, - msm_routing_lsm_port_get, - msm_routing_lsm_port_put), - SOC_ENUM_EXT("LSM2 Port", lsm_port_enum, - msm_routing_lsm_port_get, - msm_routing_lsm_port_put), - SOC_ENUM_EXT("LSM3 Port", lsm_port_enum, - msm_routing_lsm_port_get, - msm_routing_lsm_port_put), - SOC_ENUM_EXT("LSM4 Port", lsm_port_enum, - msm_routing_lsm_port_get, - msm_routing_lsm_port_put), - SOC_ENUM_EXT("LSM5 Port", lsm_port_enum, - msm_routing_lsm_port_get, - msm_routing_lsm_port_put), - SOC_ENUM_EXT("LSM6 Port", lsm_port_enum, - msm_routing_lsm_port_get, - msm_routing_lsm_port_put), - SOC_ENUM_EXT("LSM7 Port", lsm_port_enum, - msm_routing_lsm_port_get, - msm_routing_lsm_port_put), - SOC_ENUM_EXT("LSM8 Port", lsm_port_enum, - msm_routing_lsm_port_get, - msm_routing_lsm_port_put), -}; - -static const char * const aanc_slim_0_rx_text[] = { - "ZERO", "SLIMBUS_0_TX", "SLIMBUS_1_TX", "SLIMBUS_2_TX", "SLIMBUS_3_TX", - "SLIMBUS_4_TX", "SLIMBUS_5_TX", "SLIMBUS_6_TX" -}; - -static const struct soc_enum aanc_slim_0_rx_enum = - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(aanc_slim_0_rx_text), - aanc_slim_0_rx_text); - -static const struct snd_kcontrol_new aanc_slim_0_rx_mux[] = { - SOC_ENUM_EXT("AANC_SLIM_0_RX MUX", aanc_slim_0_rx_enum, - msm_routing_slim_0_rx_aanc_mux_get, - msm_routing_slim_0_rx_aanc_mux_put) -}; - -static int msm_routing_aanc_noise_level_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = aanc_level; - - return 0; -} - -static int msm_routing_aanc_noise_level_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - - mutex_lock(&routing_lock); - aanc_level = ucontrol->value.integer.value[0]; - pr_debug("%s: value: %ld\n", - __func__, ucontrol->value.integer.value[0]); - ret = afe_set_aanc_noise_level(aanc_level); - mutex_unlock(&routing_lock); - - return ret; -} - -static const struct snd_kcontrol_new aanc_noise_level[] = { - SOC_SINGLE_EXT("AANC Noise Level", SND_SOC_NOPM, 0, 255, - 0, msm_routing_aanc_noise_level_get, msm_routing_aanc_noise_level_put) -}; - -static int msm_routing_get_stereo_to_custom_stereo_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = is_custom_stereo_on; - return 0; -} - -static int msm_routing_put_stereo_to_custom_stereo_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int flag = 0, i = 0, rc = 0, idx = 0; - int be_index = 0, port_id, topo_id; - unsigned int session_id = 0; - uint16_t op_FL_ip_FL_weight = 0; - uint16_t op_FL_ip_FR_weight = 0; - uint16_t op_FR_ip_FL_weight = 0; - uint16_t op_FR_ip_FR_weight = 0; - - flag = ucontrol->value.integer.value[0]; - pr_debug("%s E flag %d\n", __func__, flag); - - if ((is_custom_stereo_on && flag) || (!is_custom_stereo_on && !flag)) { - pr_err("%s: is_custom_stereo_on %d, flag %d\n", - __func__, is_custom_stereo_on, flag); - return 0; - } - is_custom_stereo_on = flag ? true : false; - pr_debug("%s:is_custom_stereo_on %d\n", __func__, is_custom_stereo_on); - for (be_index = 0; be_index < MSM_BACKEND_DAI_MAX; be_index++) { - port_id = msm_bedais[be_index].port_id; - if (!msm_bedais[be_index].active) - continue; - if ((port_id != SLIMBUS_0_RX) && - (port_id != RT_PROXY_PORT_001_RX) && - (port_id != AFE_PORT_ID_PRIMARY_MI2S_RX) && - (port_id != AFE_PORT_ID_INT4_MI2S_RX)) - continue; - - for_each_set_bit(i, &msm_bedais[be_index].fe_sessions[0], - MSM_FRONTEND_DAI_MM_SIZE) { - if (fe_dai_map[i][SESSION_TYPE_RX].perf_mode != - LEGACY_PCM_MODE) - goto skip_send_custom_stereo; - session_id = - fe_dai_map[i][SESSION_TYPE_RX].strm_id; - if (is_custom_stereo_on) { - op_FL_ip_FL_weight = - Q14_GAIN_ZERO_POINT_FIVE; - op_FL_ip_FR_weight = - Q14_GAIN_ZERO_POINT_FIVE; - op_FR_ip_FL_weight = - Q14_GAIN_ZERO_POINT_FIVE; - op_FR_ip_FR_weight = - Q14_GAIN_ZERO_POINT_FIVE; - } else { - op_FL_ip_FL_weight = Q14_GAIN_UNITY; - op_FL_ip_FR_weight = 0; - op_FR_ip_FL_weight = 0; - op_FR_ip_FR_weight = Q14_GAIN_UNITY; - } - for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { - unsigned long copp = - session_copp_map[i] - [SESSION_TYPE_RX][be_index]; - if (!test_bit(idx, &copp)) - goto skip_send_custom_stereo; - topo_id = adm_get_topology_for_port_copp_idx( - msm_bedais[be_index].port_id, idx); - if (topo_id < 0) - pr_debug("%s:Err:custom stereo topo %d", - __func__, topo_id); - pr_debug("idx %d\n", idx); - if (topo_id == DS2_ADM_COPP_TOPOLOGY_ID) - rc = msm_ds2_dap_set_custom_stereo_onoff - (msm_bedais[be_index].port_id, - idx, is_custom_stereo_on); - else if (topo_id == DOLBY_ADM_COPP_TOPOLOGY_ID) - rc = dolby_dap_set_custom_stereo_onoff( - msm_bedais[be_index].port_id, - idx, is_custom_stereo_on); - else - rc = msm_qti_pp_send_stereo_to_custom_stereo_cmd - (msm_bedais[be_index].port_id, - idx, session_id, - op_FL_ip_FL_weight, - op_FL_ip_FR_weight, - op_FR_ip_FL_weight, - op_FR_ip_FR_weight); - if (rc < 0) -skip_send_custom_stereo: - pr_err("%s: err setting custom stereo\n", - __func__); - } - - } - } - return 0; -} - -static const struct snd_kcontrol_new stereo_to_custom_stereo_controls[] = { - SOC_SINGLE_EXT("Set Custom Stereo OnOff", SND_SOC_NOPM, 0, - 1, 0, msm_routing_get_stereo_to_custom_stereo_control, - msm_routing_put_stereo_to_custom_stereo_control), -}; - -static int msm_routing_get_app_type_cfg_control(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - return 0; -} - -static int msm_routing_put_app_type_cfg_control(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int i = 0, j; - int num_app_types = ucontrol->value.integer.value[i++]; - - pr_debug("%s\n", __func__); - - memset(app_type_cfg, 0, MAX_APP_TYPES* - sizeof(struct msm_pcm_routing_app_type_data)); - if (num_app_types > MAX_APP_TYPES) { - pr_err("%s: number of app types exceed the max supported\n", - __func__); - return -EINVAL; - } - for (j = 0; j < num_app_types; j++) { - app_type_cfg[j].app_type = - ucontrol->value.integer.value[i++]; - app_type_cfg[j].sample_rate = - ucontrol->value.integer.value[i++]; - app_type_cfg[j].bit_width = - ucontrol->value.integer.value[i++]; - } - - return 0; -} - -static int msm_routing_put_app_type_gain_control(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int j, fe_id, be_id, port_type; - int ret = 0; - unsigned long copp; - struct msm_pcm_routing_bdai_data *bedai; - int dir = ucontrol->value.integer.value[0] ? SESSION_TYPE_TX : - SESSION_TYPE_RX; - int app_type = ucontrol->value.integer.value[1]; - int gain = (ucontrol->value.integer.value[2] + - ucontrol->value.integer.value[3])/2; - - port_type = (dir == SESSION_TYPE_RX) ? MSM_AFE_PORT_TYPE_RX : - MSM_AFE_PORT_TYPE_TX; - - mutex_lock(&routing_lock); - for (be_id = 0; be_id < MSM_BACKEND_DAI_MAX; be_id++) { - if (is_be_dai_extproc(be_id)) - continue; - - bedai = &msm_bedais[be_id]; - if (afe_get_port_type(bedai->port_id) != port_type) - continue; - - if (!bedai->active) - continue; - - for (fe_id = 0; fe_id < MSM_FRONTEND_DAI_MAX; fe_id++) { - if (!test_bit(fe_id, &bedai->fe_sessions[0])) - continue; - - if (app_type != - fe_dai_app_type_cfg[fe_id][dir][be_id].app_type) - continue; - - copp = session_copp_map[fe_id][dir][be_id]; - for (j = 0; j < MAX_COPPS_PER_PORT; j++) { - if (!test_bit(j, &copp)) - continue; - ret |= adm_set_volume(bedai->port_id, j, gain); - } - } - } - mutex_unlock(&routing_lock); - return ret ? -EINVAL : 0; -} - -static const struct snd_kcontrol_new app_type_cfg_controls[] = { - SOC_SINGLE_MULTI_EXT("App Type Config", SND_SOC_NOPM, 0, - 0x7FFFFFFF, 0, 128, msm_routing_get_app_type_cfg_control, - msm_routing_put_app_type_cfg_control), - SOC_SINGLE_MULTI_EXT("App Type Gain", SND_SOC_NOPM, 0, - 0x2000, 0, 4, NULL, msm_routing_put_app_type_gain_control) -}; - -static int msm_routing_put_module_cfg_control(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int copp_idx, fe_id, be_id, port_type; - int ret = 0; - unsigned long copp; - struct msm_pcm_routing_bdai_data *bedai; - u8 *packed_params = NULL; - struct param_hdr_v3 param_hdr; - u32 packed_param_size = (sizeof(struct param_hdr_v3) + - sizeof(uint32_t)); - - int dir = ucontrol->value.integer.value[0] ? SESSION_TYPE_TX : - SESSION_TYPE_RX; - int app_type = ucontrol->value.integer.value[1]; - int module_id = ucontrol->value.integer.value[2]; - int instance_id = ucontrol->value.integer.value[3]; - int param_id = ucontrol->value.integer.value[4]; - int param_value = ucontrol->value.integer.value[5]; - - port_type = (dir == SESSION_TYPE_RX) ? MSM_AFE_PORT_TYPE_RX : - MSM_AFE_PORT_TYPE_TX; - pr_debug("%s app_type:%d mod_id:%d instance_id:%d param_id:%d value:%d\n", - __func__, app_type, module_id, - instance_id, param_id, param_value); - - packed_params = kzalloc(packed_param_size, GFP_KERNEL); - if (!packed_params) - return -ENOMEM; - - memset(¶m_hdr, 0, sizeof(param_hdr)); - param_hdr.module_id = module_id; - param_hdr.instance_id = instance_id; - param_hdr.param_id = param_id; - param_hdr.param_size = sizeof(uint32_t); - - packed_param_size = 0; - - mutex_lock(&routing_lock); - for (be_id = 0; be_id < MSM_BACKEND_DAI_MAX; be_id++) { - if (is_be_dai_extproc(be_id)) - continue; - - bedai = &msm_bedais[be_id]; - if (afe_get_port_type(bedai->port_id) != port_type) - continue; - - if (!bedai->active) - continue; - - for (fe_id = 0; fe_id < MSM_FRONTEND_DAI_MAX; fe_id++) { - if (!test_bit(fe_id, &bedai->fe_sessions[0])) - continue; - - if (app_type != - fe_dai_app_type_cfg[fe_id][dir][be_id].app_type) - continue; - - copp = session_copp_map[fe_id][dir][be_id]; - for (copp_idx = 0; copp_idx < MAX_COPPS_PER_PORT; - copp_idx++) { - if (!test_bit(copp_idx, &copp)) - continue; - - ret = q6common_pack_pp_params(packed_params, - ¶m_hdr, - (u8 *) ¶m_value, - &packed_param_size); - if (ret) { - pr_err("%s: Failed to pack params, error %d\n", - __func__, ret); - goto done; - } - - ret = adm_set_pp_params(bedai->port_id, - copp_idx, NULL, - packed_params, - packed_param_size); - if (ret) { - pr_err("%s: Setting param failed with err=%d\n", - __func__, ret); - ret = -EINVAL; - goto done; - } - } - } - } -done: - mutex_unlock(&routing_lock); - kfree(packed_params); - return ret; -} - -static const struct snd_kcontrol_new module_cfg_controls[] = { - SOC_SINGLE_MULTI_EXT("Audio Effect", SND_SOC_NOPM, 0, - 0x2000, 0, 6, NULL, msm_routing_put_module_cfg_control) -}; - -static int msm_routing_get_lsm_app_type_cfg_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int shift = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - int i = 0, j = 0; - - mutex_lock(&routing_lock); - ucontrol->value.integer.value[i] = num_app_cfg_types; - - for (j = 0; j < num_app_cfg_types; ++j) { - ucontrol->value.integer.value[++i] = - lsm_app_type_cfg[j].app_type; - ucontrol->value.integer.value[++i] = - lsm_app_type_cfg[j].sample_rate; - ucontrol->value.integer.value[++i] = - lsm_app_type_cfg[j].bit_width; - if (shift == 1) - ucontrol->value.integer.value[++i] = - lsm_app_type_cfg[j].num_out_channels; - } - mutex_unlock(&routing_lock); - return 0; -} - -static int msm_routing_put_lsm_app_type_cfg_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int shift = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - int i = 0, j; - - mutex_lock(&routing_lock); - if (ucontrol->value.integer.value[0] > MAX_APP_TYPES) { - pr_err("%s: number of app types exceed the max supported\n", - __func__); - mutex_unlock(&routing_lock); - return -EINVAL; - } - - num_app_cfg_types = ucontrol->value.integer.value[i++]; - memset(lsm_app_type_cfg, 0, MAX_APP_TYPES* - sizeof(struct msm_pcm_routing_app_type_data)); - - for (j = 0; j < num_app_cfg_types; j++) { - lsm_app_type_cfg[j].app_type = - ucontrol->value.integer.value[i++]; - lsm_app_type_cfg[j].sample_rate = - ucontrol->value.integer.value[i++]; - lsm_app_type_cfg[j].bit_width = - ucontrol->value.integer.value[i++]; - /* Shift of 1 indicates this is V2 mixer control */ - if (shift == 1) - lsm_app_type_cfg[j].num_out_channels = - ucontrol->value.integer.value[i++]; - } - mutex_unlock(&routing_lock); - return 0; -} - -static const struct snd_kcontrol_new lsm_app_type_cfg_controls[] = { - SOC_SINGLE_MULTI_EXT("Listen App Type Config", SND_SOC_NOPM, 0, - 0xFFFFFFFF, 0, 128, msm_routing_get_lsm_app_type_cfg_control, - msm_routing_put_lsm_app_type_cfg_control), - SOC_SINGLE_MULTI_EXT("Listen App Type Config V2", SND_SOC_NOPM, 1, - 0xFFFFFFFF, 0, 128, msm_routing_get_lsm_app_type_cfg_control, - msm_routing_put_lsm_app_type_cfg_control), -}; - -static int msm_routing_get_use_ds1_or_ds2_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = is_ds2_on; - return 0; -} - -static int msm_routing_put_use_ds1_or_ds2_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - is_ds2_on = ucontrol->value.integer.value[0]; - return 0; -} - -static const struct snd_kcontrol_new use_ds1_or_ds2_controls[] = { - SOC_SINGLE_EXT("DS2 OnOff", SND_SOC_NOPM, 0, - 1, 0, msm_routing_get_use_ds1_or_ds2_control, - msm_routing_put_use_ds1_or_ds2_control), -}; - -static int msm_routing_get_hifi_filter_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = hifi_filter_enabled; - return 0; -} - -static int msm_routing_put_hifi_filter_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - hifi_filter_enabled = ucontrol->value.integer.value[0]; - return 0; -} - -static const struct snd_kcontrol_new hifi_filter_controls[] = { - SOC_SINGLE_EXT("HiFi Filter", SND_SOC_NOPM, 0, - 1, 0, msm_routing_get_hifi_filter_control, - msm_routing_put_hifi_filter_control), -}; - -static int msm_routing_get_ffecns_freeze_event_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = ffecns_freeze_event; - return 0; -} - -static int msm_routing_put_ffecns_freeze_event_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = -EINVAL; - - ffecns_freeze_event = ucontrol->value.integer.value[0]; - - ret = adm_set_ffecns_freeze_event(ffecns_freeze_event); - if (ret) - pr_err("%s: failed to set ffecns imc event to%d\n", - __func__, ffecns_freeze_event); - - return ret; -} - -static const struct snd_kcontrol_new use_ffecns_freeze_event_controls[] = { - SOC_SINGLE_EXT("FFECNS Freeze Event", SND_SOC_NOPM, 0, - 1, 0, msm_routing_get_ffecns_freeze_event_control, - msm_routing_put_ffecns_freeze_event_control), -}; - -int msm_routing_get_rms_value_control(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) { - int rc = 0; - int be_idx = 0; - char *param_value; - int *update_param_value; - uint32_t param_size = (RMS_PAYLOAD_LEN + 1) * sizeof(uint32_t); - struct param_hdr_v3 param_hdr; - - param_value = kzalloc(param_size, GFP_KERNEL); - if (!param_value) - return -ENOMEM; - - memset(¶m_hdr, 0, sizeof(param_hdr)); - for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) - if (msm_bedais[be_idx].port_id == SLIMBUS_0_TX) - break; - if ((be_idx < MSM_BACKEND_DAI_MAX) && msm_bedais[be_idx].active) { - param_hdr.module_id = RMS_MODULEID_APPI_PASSTHRU; - param_hdr.instance_id = INSTANCE_ID_0; - param_hdr.param_id = RMS_PARAM_FIRST_SAMPLE; - param_hdr.param_size = param_size; - rc = adm_get_pp_params(SLIMBUS_0_TX, 0, ADM_CLIENT_ID_DEFAULT, - NULL, ¶m_hdr, (u8 *) param_value); - if (rc) { - pr_err("%s: get parameters failed:%d\n", __func__, rc); - kfree(param_value); - return -EINVAL; - } - update_param_value = (int *)param_value; - ucontrol->value.integer.value[0] = update_param_value[0]; - - pr_debug("%s: FROM DSP value[0] 0x%x\n", - __func__, update_param_value[0]); - } - kfree(param_value); - return 0; -} - -static int msm_voc_session_id_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - voc_session_id = ucontrol->value.integer.value[0]; - - pr_debug("%s: voc_session_id=%u\n", __func__, voc_session_id); - - return 0; -} - -static int msm_voc_session_id_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = voc_session_id; - - return 0; -} - -static struct snd_kcontrol_new msm_voc_session_controls[] = { - SOC_SINGLE_MULTI_EXT("Voc VSID", SND_SOC_NOPM, 0, - 0xFFFFFFFF, 0, 1, msm_voc_session_id_get, - msm_voc_session_id_put), -}; - -static int msm_sound_focus_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; - uinfo->count = sizeof(struct sound_focus_param); - - return 0; -} - -static int msm_voice_sound_focus_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct sound_focus_param soundFocusData; - - memcpy((void *)&soundFocusData, ucontrol->value.bytes.data, - sizeof(struct sound_focus_param)); - ret = voc_set_sound_focus(soundFocusData); - if (ret) { - pr_err("%s: Error setting Sound Focus Params, err=%d\n", - __func__, ret); - - ret = -EINVAL; - } - - return ret; -} - -static int msm_voice_sound_focus_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct sound_focus_param soundFocusData; - - memset(&soundFocusData, 0, sizeof(struct sound_focus_param)); - - ret = voc_get_sound_focus(&soundFocusData); - if (ret) { - pr_debug("%s: Error getting Sound Focus Params, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - memcpy(ucontrol->value.bytes.data, (void *)&soundFocusData, - sizeof(struct sound_focus_param)); - -done: - return ret; -} - -static int msm_source_tracking_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; - uinfo->count = sizeof(struct source_tracking_param); - - return 0; -} - -static int msm_voice_source_tracking_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct source_tracking_param sourceTrackingData; - - memset(&sourceTrackingData, 0, sizeof(struct source_tracking_param)); - - ret = voc_get_source_tracking(&sourceTrackingData); - if (ret) { - pr_debug("%s: Error getting Source Tracking Params, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - memcpy(ucontrol->value.bytes.data, (void *)&sourceTrackingData, - sizeof(struct source_tracking_param)); - -done: - return ret; -} - -static int msm_audio_get_copp_idx_from_port_id(int port_id, int session_type, - int *copp_idx) -{ - int i, idx, be_idx; - int ret = 0; - unsigned long copp; - - pr_debug("%s: Enter, port_id=%d\n", __func__, port_id); - - ret = q6audio_validate_port(port_id); - if (ret < 0) { - pr_err("%s: port validation failed id 0x%x ret %d\n", - __func__, port_id, ret); - - ret = -EINVAL; - goto done; - } - - for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) { - if (msm_bedais[be_idx].port_id == port_id) - break; - } - if (be_idx >= MSM_BACKEND_DAI_MAX) { - pr_err("%s: Invalid be id %d\n", __func__, be_idx); - - ret = -EINVAL; - goto done; - } - - for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0], - MSM_FRONTEND_DAI_MAX) { - if (!(is_mm_lsm_fe_id(i) && - route_check_fe_id_adm_support(i))) - continue; - - for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { - copp = session_copp_map[i] - [session_type][be_idx]; - if (test_bit(idx, &copp)) - break; - } - if (idx >= MAX_COPPS_PER_PORT) - continue; - else - break; - } - if (i >= MSM_FRONTEND_DAI_MAX) { - pr_debug("%s: Invalid FE, exiting\n", __func__); - - ret = -EINVAL; - goto done; - } - *copp_idx = idx; - pr_debug("%s: copp_idx=%d\n", __func__, *copp_idx); - -done: - return ret; -} - -static int msm_audio_sound_focus_derive_port_id(struct snd_kcontrol *kcontrol, - const char *prefix, int *port_id) -{ - int ret = 0; - - pr_debug("%s: Enter, prefix:%s\n", __func__, prefix); - - /* - * Mixer control name will be like "Sound Focus Audio Tx SLIMBUS_0" - * where the prefix is "Sound Focus Audio Tx ". Skip the prefix - * and compare the string with the backend name to derive the port id. - */ - if (!strcmp(kcontrol->id.name + strlen(prefix), - "SLIMBUS_0")) { - *port_id = SLIMBUS_0_TX; - } else if (!strcmp(kcontrol->id.name + strlen(prefix), - "TERT_MI2S")) { - *port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; - } else if (!strcmp(kcontrol->id.name + strlen(prefix), - "INT3_MI2S")) { - *port_id = AFE_PORT_ID_INT3_MI2S_TX; - } else if (!strcmp(kcontrol->id.name + strlen(prefix), - "VA_CDC_DMA_TX_0")) { - *port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0; - } else if (!strcmp(kcontrol->id.name + strlen(prefix), - "TX_CDC_DMA_TX_3")) { - *port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3; - } else if (!strcmp(kcontrol->id.name + strlen(prefix), - "QUIN_TDM_TX_0")) { - *port_id = AFE_PORT_ID_QUINARY_TDM_TX; - } else if (!strcmp(kcontrol->id.name + strlen(prefix), - "PRIMARY_TDM")) { - *port_id = AFE_PORT_ID_PRIMARY_TDM_TX; - } else { - pr_err("%s: mixer ctl name=%s, could not derive valid port id\n", - __func__, kcontrol->id.name); - - ret = -EINVAL; - goto done; - } - pr_debug("%s: mixer ctl name=%s, derived port_id=%d\n", - __func__, kcontrol->id.name, *port_id); - -done: - return ret; -} - -static int msm_audio_sound_focus_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct sound_focus_param soundFocusData; - int port_id, copp_idx; - - ret = msm_audio_sound_focus_derive_port_id(kcontrol, - "Sound Focus Audio Tx ", &port_id); - if (ret != 0) { - pr_err("%s: Error in deriving port id, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - - ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, - &copp_idx); - if (ret) { - pr_err("%s: Could not get copp idx for port_id=%d\n", - __func__, port_id); - - ret = -EINVAL; - goto done; - } - - memcpy((void *)&soundFocusData, ucontrol->value.bytes.data, - sizeof(struct sound_focus_param)); - - ret = adm_set_sound_focus(port_id, copp_idx, soundFocusData); - if (ret) { - pr_err("%s: Error setting Sound Focus Params, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - -done: - return ret; -} - -static int msm_audio_sound_focus_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct sound_focus_param soundFocusData; - int port_id, copp_idx; - - ret = msm_audio_sound_focus_derive_port_id(kcontrol, - "Sound Focus Audio Tx ", &port_id); - if (ret) { - pr_err("%s: Error in deriving port id, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - - ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, - &copp_idx); - if (ret) { - pr_debug("%s: Could not get copp idx for port_id=%d\n", - __func__, port_id); - - ret = -EINVAL; - goto done; - } - - ret = adm_get_sound_focus(port_id, copp_idx, &soundFocusData); - if (ret) { - pr_err("%s: Error getting Sound Focus Params, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - - memcpy(ucontrol->value.bytes.data, (void *)&soundFocusData, - sizeof(struct sound_focus_param)); - -done: - return ret; -} - -static int msm_audio_source_tracking_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct source_tracking_param sourceTrackingData; - int port_id, copp_idx; - - ret = msm_audio_sound_focus_derive_port_id(kcontrol, - "Source Tracking Audio Tx ", &port_id); - if (ret) { - pr_err("%s: Error in deriving port id, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - - ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, - &copp_idx); - if (ret) { - pr_debug("%s: Could not get copp idx for port_id=%d\n", - __func__, port_id); - - ret = -EINVAL; - goto done; - } - - ret = adm_get_source_tracking(port_id, copp_idx, &sourceTrackingData); - if (ret) { - pr_err("%s: Error getting Source Tracking Params, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - - memcpy(ucontrol->value.bytes.data, (void *)&sourceTrackingData, - sizeof(struct source_tracking_param)); - -done: - return ret; -} - -static int msm_doa_tracking_mon_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; - uinfo->count = sizeof(struct doa_tracking_mon_param); - - return 0; -} - -static int msm_doa_tracking_mon_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct doa_tracking_mon_param doa_tracking_data; - int port_id, copp_idx; - - memset(&doa_tracking_data, 0, sizeof(struct doa_tracking_mon_param)); - ret = msm_audio_sound_focus_derive_port_id(kcontrol, - "Doa Tracking Monitor Listen ", &port_id); - if (ret) { - pr_err("%s: Error in deriving port id, err=%d\n", - __func__, ret); - ret = -EINVAL; - goto done; - } - - /* - * If copp id exists for given port id, query adm to get doa data. - * Else query afe for doa tracking params. - * This is to support in cases where LSM directly connects to - * AFE for FFNS. - */ - ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, - &copp_idx); - if (!ret) - ret = adm_get_doa_tracking_mon(port_id, copp_idx, - &doa_tracking_data); - else - ret = afe_get_doa_tracking_mon(port_id, &doa_tracking_data); - - if (ret) { - pr_err("%s: Error getting Doa Tracking Params, err=%d\n", - __func__, ret); - ret = -EINVAL; - goto done; - } - - memcpy(ucontrol->value.bytes.data, (void *)&doa_tracking_data, - sizeof(struct doa_tracking_mon_param)); -done: - return ret; -} - -static const struct snd_kcontrol_new msm_source_tracking_controls[] = { - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Voice Tx SLIMBUS_0", - .info = msm_sound_focus_info, - .get = msm_voice_sound_focus_get, - .put = msm_voice_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Voice Tx SLIMBUS_0", - .info = msm_source_tracking_info, - .get = msm_voice_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Audio Tx SLIMBUS_0", - .info = msm_sound_focus_info, - .get = msm_audio_sound_focus_get, - .put = msm_audio_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Audio Tx SLIMBUS_0", - .info = msm_source_tracking_info, - .get = msm_audio_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Voice Tx TERT_MI2S", - .info = msm_sound_focus_info, - .get = msm_voice_sound_focus_get, - .put = msm_voice_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Voice Tx TERT_MI2S", - .info = msm_source_tracking_info, - .get = msm_voice_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Audio Tx TERT_MI2S", - .info = msm_sound_focus_info, - .get = msm_audio_sound_focus_get, - .put = msm_audio_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Audio Tx TERT_MI2S", - .info = msm_source_tracking_info, - .get = msm_audio_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Voice Tx INT3_MI2S", - .info = msm_sound_focus_info, - .get = msm_voice_sound_focus_get, - .put = msm_voice_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Voice Tx INT3_MI2S", - .info = msm_source_tracking_info, - .get = msm_voice_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Audio Tx INT3_MI2S", - .info = msm_sound_focus_info, - .get = msm_audio_sound_focus_get, - .put = msm_audio_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Audio Tx INT3_MI2S", - .info = msm_source_tracking_info, - .get = msm_audio_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Voice Tx VA_CDC_DMA_TX_0", - .info = msm_sound_focus_info, - .get = msm_voice_sound_focus_get, - .put = msm_voice_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Voice Tx VA_CDC_DMA_TX_0", - .info = msm_source_tracking_info, - .get = msm_voice_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Audio Tx VA_CDC_DMA_TX_0", - .info = msm_sound_focus_info, - .get = msm_audio_sound_focus_get, - .put = msm_audio_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Audio Tx VA_CDC_DMA_TX_0", - .info = msm_source_tracking_info, - .get = msm_audio_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Voice Tx TX_CDC_DMA_TX_3", - .info = msm_sound_focus_info, - .get = msm_voice_sound_focus_get, - .put = msm_voice_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Voice Tx TX_CDC_DMA_TX_3", - .info = msm_source_tracking_info, - .get = msm_voice_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Audio Tx TX_CDC_DMA_TX_3", - .info = msm_sound_focus_info, - .get = msm_audio_sound_focus_get, - .put = msm_audio_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Audio Tx TX_CDC_DMA_TX_3", - .info = msm_source_tracking_info, - .get = msm_audio_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Voice Tx QUIN_TDM_TX_0", - .info = msm_sound_focus_info, - .get = msm_voice_sound_focus_get, - .put = msm_voice_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Voice Tx QUIN_TDM_TX_0", - .info = msm_source_tracking_info, - .get = msm_voice_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Audio Tx QUIN_TDM_TX_0", - .info = msm_sound_focus_info, - .get = msm_audio_sound_focus_get, - .put = msm_audio_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Audio Tx QUIN_TDM_TX_0", - .info = msm_source_tracking_info, - .get = msm_audio_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Audio Tx PRIMARY_TDM", - .info = msm_sound_focus_info, - .get = msm_audio_sound_focus_get, - .put = msm_audio_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Audio Tx PRIMARY_TDM", - .info = msm_source_tracking_info, - .get = msm_audio_source_tracking_get, - }, -}; - -static const struct snd_kcontrol_new msm_source_doa_tracking_controls[] = { - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Doa Tracking Monitor Listen VA_CDC_DMA_TX_0", - .info = msm_doa_tracking_mon_info, - .get = msm_doa_tracking_mon_get, - }, -}; - -static int spkr_prot_put_vi_lch_port(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - int item; - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - - pr_debug("%s item is %d\n", __func__, - ucontrol->value.enumerated.item[0]); - mutex_lock(&routing_lock); - item = ucontrol->value.enumerated.item[0]; - if (item < e->items) { - pr_debug("%s RX DAI ID %d TX DAI id %d\n", - __func__, e->shift_l, e->values[item]); - if (e->shift_l < MSM_BACKEND_DAI_MAX && - e->values[item] < MSM_BACKEND_DAI_MAX) - /* Enable feedback TX path */ - ret = afe_spk_prot_feed_back_cfg( - msm_bedais[e->values[item]].port_id, - msm_bedais[e->shift_l].port_id, 1, 0, 1); - else { - pr_debug("%s values are out of range item %d\n", - __func__, e->values[item]); - /* Disable feedback TX path */ - if (e->values[item] == MSM_BACKEND_DAI_MAX) - ret = afe_spk_prot_feed_back_cfg(0, 0, 0, 0, 0); - else - ret = -EINVAL; - } - } else { - pr_err("%s item value is out of range item\n", __func__); - ret = -EINVAL; - } - mutex_unlock(&routing_lock); - return ret; -} - -static int spkr_prot_put_vi_rch_port(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - int item; - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - - pr_debug("%s item is %d\n", __func__, - ucontrol->value.enumerated.item[0]); - mutex_lock(&routing_lock); - item = ucontrol->value.enumerated.item[0]; - if (item < e->items) { - pr_debug("%s RX DAI ID %d TX DAI id %d\n", - __func__, e->shift_l, e->values[item]); - if (e->shift_l < MSM_BACKEND_DAI_MAX && - e->values[item] < MSM_BACKEND_DAI_MAX) - /* Enable feedback TX path */ - ret = afe_spk_prot_feed_back_cfg( - msm_bedais[e->values[item]].port_id, - msm_bedais[e->shift_l].port_id, - 1, 1, 1); - else { - pr_debug("%s values are out of range item %d\n", - __func__, e->values[item]); - /* Disable feedback TX path */ - if (e->values[item] == MSM_BACKEND_DAI_MAX) - ret = afe_spk_prot_feed_back_cfg(0, - 0, 0, 0, 0); - else - ret = -EINVAL; - } - } else { - pr_err("%s item value is out of range item\n", __func__); - ret = -EINVAL; - } - mutex_unlock(&routing_lock); - return ret; -} - -static int spkr_prot_get_vi_lch_port(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s\n", __func__); - return 0; -} - -static int spkr_prot_get_vi_rch_port(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s\n", __func__); - ucontrol->value.enumerated.item[0] = 0; - return 0; -} - -static const char * const slim0_rx_vi_fb_tx_lch_mux_text[] = { - "ZERO", "SLIM4_TX" -}; - -static const char * const slim0_rx_vi_fb_tx_rch_mux_text[] = { - "ZERO", "SLIM4_TX" -}; - -static const char * const wsa_rx_0_vi_fb_tx_lch_mux_text[] = { - "ZERO", "WSA_CDC_DMA_TX_0" -}; - -static const char * const wsa_rx_0_vi_fb_tx_rch_mux_text[] = { - "ZERO", "WSA_CDC_DMA_TX_0" -}; - -static const char * const mi2s_rx_vi_fb_tx_mux_text[] = { - "ZERO", "SENARY_TX" -}; - -static const char * const int4_mi2s_rx_vi_fb_tx_mono_mux_text[] = { - "ZERO", "INT5_MI2S_TX" -}; - -static const char * const int4_mi2s_rx_vi_fb_tx_stereo_mux_text[] = { - "ZERO", "INT5_MI2S_TX" -}; - -static const int slim0_rx_vi_fb_tx_lch_value[] = { - MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SLIMBUS_4_TX -}; - -static const int slim0_rx_vi_fb_tx_rch_value[] = { - MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SLIMBUS_4_TX -}; - -static const int wsa_rx_0_vi_fb_tx_lch_value[] = { - MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0 -}; - -static const int wsa_rx_0_vi_fb_tx_rch_value[] = { - MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0 -}; - - -static const int mi2s_rx_vi_fb_tx_value[] = { - MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SENARY_MI2S_TX -}; - -static const int int4_mi2s_rx_vi_fb_tx_mono_ch_value[] = { - MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_INT5_MI2S_TX -}; - -static const int int4_mi2s_rx_vi_fb_tx_stereo_ch_value[] = { - MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_INT5_MI2S_TX -}; - -static const struct soc_enum slim0_rx_vi_fb_lch_mux_enum = - SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_SLIMBUS_0_RX, 0, 0, - ARRAY_SIZE(slim0_rx_vi_fb_tx_lch_mux_text), - slim0_rx_vi_fb_tx_lch_mux_text, slim0_rx_vi_fb_tx_lch_value); - -static const struct soc_enum slim0_rx_vi_fb_rch_mux_enum = - SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_SLIMBUS_0_RX, 0, 0, - ARRAY_SIZE(slim0_rx_vi_fb_tx_rch_mux_text), - slim0_rx_vi_fb_tx_rch_mux_text, slim0_rx_vi_fb_tx_rch_value); - -static const struct soc_enum wsa_rx_0_vi_fb_lch_mux_enum = - SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, 0, 0, - ARRAY_SIZE(wsa_rx_0_vi_fb_tx_lch_mux_text), - wsa_rx_0_vi_fb_tx_lch_mux_text, wsa_rx_0_vi_fb_tx_lch_value); - -static const struct soc_enum wsa_rx_0_vi_fb_rch_mux_enum = - SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, 0, 0, - ARRAY_SIZE(wsa_rx_0_vi_fb_tx_rch_mux_text), - wsa_rx_0_vi_fb_tx_rch_mux_text, wsa_rx_0_vi_fb_tx_rch_value); - -static const struct soc_enum mi2s_rx_vi_fb_mux_enum = - SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_PRI_MI2S_RX, 0, 0, - ARRAY_SIZE(mi2s_rx_vi_fb_tx_mux_text), - mi2s_rx_vi_fb_tx_mux_text, mi2s_rx_vi_fb_tx_value); - -static const struct soc_enum int4_mi2s_rx_vi_fb_mono_ch_mux_enum = - SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_INT4_MI2S_RX, 0, 0, - ARRAY_SIZE(int4_mi2s_rx_vi_fb_tx_mono_mux_text), - int4_mi2s_rx_vi_fb_tx_mono_mux_text, - int4_mi2s_rx_vi_fb_tx_mono_ch_value); - -static const struct soc_enum int4_mi2s_rx_vi_fb_stereo_ch_mux_enum = - SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_INT4_MI2S_RX, 0, 0, - ARRAY_SIZE(int4_mi2s_rx_vi_fb_tx_stereo_mux_text), - int4_mi2s_rx_vi_fb_tx_stereo_mux_text, - int4_mi2s_rx_vi_fb_tx_stereo_ch_value); - -static const struct snd_kcontrol_new slim0_rx_vi_fb_lch_mux = - SOC_DAPM_ENUM_EXT("SLIM0_RX_VI_FB_LCH_MUX", - slim0_rx_vi_fb_lch_mux_enum, spkr_prot_get_vi_lch_port, - spkr_prot_put_vi_lch_port); - -static const struct snd_kcontrol_new slim0_rx_vi_fb_rch_mux = - SOC_DAPM_ENUM_EXT("SLIM0_RX_VI_FB_RCH_MUX", - slim0_rx_vi_fb_rch_mux_enum, spkr_prot_get_vi_rch_port, - spkr_prot_put_vi_rch_port); - -static const struct snd_kcontrol_new wsa_rx_0_vi_fb_lch_mux = - SOC_DAPM_ENUM_EXT("WSA_RX_0_VI_FB_LCH_MUX", - wsa_rx_0_vi_fb_lch_mux_enum, spkr_prot_get_vi_lch_port, - spkr_prot_put_vi_lch_port); - -static const struct snd_kcontrol_new wsa_rx_0_vi_fb_rch_mux = - SOC_DAPM_ENUM_EXT("WSA_RX_0_VI_FB_RCH_MUX", - wsa_rx_0_vi_fb_rch_mux_enum, spkr_prot_get_vi_rch_port, - spkr_prot_put_vi_rch_port); - -static const struct snd_kcontrol_new mi2s_rx_vi_fb_mux = - SOC_DAPM_ENUM_EXT("PRI_MI2S_RX_VI_FB_MUX", - mi2s_rx_vi_fb_mux_enum, spkr_prot_get_vi_lch_port, - spkr_prot_put_vi_lch_port); - -static const struct snd_kcontrol_new int4_mi2s_rx_vi_fb_mono_ch_mux = - SOC_DAPM_ENUM_EXT("INT4_MI2S_RX_VI_FB_MONO_CH_MUX", - int4_mi2s_rx_vi_fb_mono_ch_mux_enum, spkr_prot_get_vi_lch_port, - spkr_prot_put_vi_lch_port); - -static const struct snd_kcontrol_new int4_mi2s_rx_vi_fb_stereo_ch_mux = - SOC_DAPM_ENUM_EXT("INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", - int4_mi2s_rx_vi_fb_stereo_ch_mux_enum, spkr_prot_get_vi_rch_port, - spkr_prot_put_vi_rch_port); - -static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { - /* Frontend AIF */ - /* Widget name equals to Front-End DAI name, - * Stream name must contains substring of front-end dai name - */ - SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL5", "MultiMedia5 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL6", "MultiMedia6 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL7", "MultiMedia7 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL8", "MultiMedia8 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL9", "MultiMedia9 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL10", "MultiMedia10 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL11", "MultiMedia11 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL12", "MultiMedia12 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL13", "MultiMedia13 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL14", "MultiMedia14 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL15", "MultiMedia15 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL16", "MultiMedia16 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL20", "MultiMedia20 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL21", "MultiMedia21 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL22", "MultiMedia22 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL23", "MultiMedia23 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL24", "MultiMedia24 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL25", "MultiMedia25 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL26", "MultiMedia26 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL3", "MultiMedia3 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL4", "MultiMedia4 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL5", "MultiMedia5 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL9", "MultiMedia9 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL10", "MultiMedia10 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL16", "MultiMedia16 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL17", "MultiMedia17 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL18", "MultiMedia18 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL19", "MultiMedia19 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL20", "MultiMedia20 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL21", "MultiMedia21 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL22", "MultiMedia22 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL23", "MultiMedia23 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL24", "MultiMedia24 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL25", "MultiMedia25 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL27", "MultiMedia27 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL28", "MultiMedia28 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL29", "MultiMedia29 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL30", "MultiMedia30 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("VOICEMMODE1_DL", - "VoiceMMode1 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VOICEMMODE1_UL", - "VoiceMMode1 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("VOICEMMODE2_DL", - "VoiceMMode2 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VOICEMMODE2_UL", - "VoiceMMode2 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIM0_DL_HL", "SLIMBUS0_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIM0_UL_HL", "SLIMBUS0_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("CDC_DMA_DL_HL", "CDC_DMA_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("CDC_DMA_UL_HL", "CDC_DMA_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TX3_CDC_DMA_UL_HL", - "TX3_CDC_DMA_HOSTLESS Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("CPE_LSM_UL_HL", "CPE LSM capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIM1_DL_HL", "SLIMBUS1_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIM1_UL_HL", "SLIMBUS1_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIM3_DL_HL", "SLIMBUS3_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIM3_UL_HL", "SLIMBUS3_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIM4_DL_HL", "SLIMBUS4_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIM4_UL_HL", "SLIMBUS4_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIM6_DL_HL", "SLIMBUS6_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIM6_UL_HL", "SLIMBUS6_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIM7_DL_HL", "SLIMBUS7_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIM7_UL_HL", "SLIMBUS7_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIM8_DL_HL", "SLIMBUS8_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIM8_UL_HL", "SLIMBUS8_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INTFM_DL_HL", "INT_FM_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INTHFP_DL_HL", "INT_HFP_BT_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INTHFP_UL_HL", "INT_HFP_BT_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("USBAUDIO_DL_HL", "USBAUDIO_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("USBAUDIO_UL_HL", "USBAUDIO_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("HDMI_DL_HL", "HDMI_HOSTLESS Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_I2S_DL_HL", "SEC_I2S_RX_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INT0_MI2S_DL_HL", - "INT0 MI2S_RX Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INT4_MI2S_DL_HL", - "INT4 MI2S_RX Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_MI2S_DL_HL", - "Primary MI2S_RX Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_MI2S_DL_HL", - "Secondary MI2S_RX Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_MI2S_DL_HL", - "Tertiary MI2S_RX Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_MI2S_DL_HL", - "Quaternary MI2S_RX Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_MI2S_DL_HL", - "Quinary MI2S_RX Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_MI2S_DL_HL", - "Senary MI2S_RX Hostless Playback", - 0, 0, 0, 0), - - SND_SOC_DAPM_AIF_IN("AUXPCM_DL_HL", "AUXPCM_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("AUXPCM_UL_HL", "AUXPCM_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_AUXPCM_DL_HL", "SEC_AUXPCM_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_AUXPCM_UL_HL", "SEC_AUXPCM_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MI2S_UL_HL", "MI2S_TX_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT3_MI2S_UL_HL", - "INT3 MI2S_TX Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_MI2S_UL_HL", - "Tertiary MI2S_TX Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_MI2S_UL_HL", - "Secondary MI2S_TX Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_MI2S_UL_HL", - "Primary MI2S_TX Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MI2S_DL_HL", "MI2S_RX_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("DTMF_DL_HL", "DTMF_RX_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_UL_HL", - "Quaternary MI2S_TX Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_MI2S_UL_HL", - "Quinary MI2S_TX Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_MI2S_UL_HL", - "Senary MI2S_TX Hostless Capture", - 0, 0, 0, 0), - - SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_0_DL_HL", - "Primary TDM0 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_0_UL_HL", - "Primary TDM0 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_1_DL_HL", - "Primary TDM1 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_1_UL_HL", - "Primary TDM1 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_2_DL_HL", - "Primary TDM2 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_2_UL_HL", - "Primary TDM2 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_3_DL_HL", - "Primary TDM3 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_3_UL_HL", - "Primary TDM3 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_4_DL_HL", - "Primary TDM4 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_4_UL_HL", - "Primary TDM4 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_5_DL_HL", - "Primary TDM5 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_5_UL_HL", - "Primary TDM5 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_6_DL_HL", - "Primary TDM6 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_6_UL_HL", - "Primary TDM6 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_7_DL_HL", - "Primary TDM7 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_7_UL_HL", - "Primary TDM7 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_0_DL_HL", - "Secondary TDM0 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_0_UL_HL", - "Secondary TDM0 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_1_DL_HL", - "Secondary TDM1 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_1_UL_HL", - "Secondary TDM1 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_2_DL_HL", - "Secondary TDM2 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_2_UL_HL", - "Secondary TDM2 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_3_DL_HL", - "Secondary TDM3 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_3_UL_HL", - "Secondary TDM3 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_4_DL_HL", - "Secondary TDM4 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_4_UL_HL", - "Secondary TDM4 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_5_DL_HL", - "Secondary TDM5 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_5_UL_HL", - "Secondary TDM5 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_6_DL_HL", - "Secondary TDM6 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_6_UL_HL", - "Secondary TDM6 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_7_DL_HL", - "Secondary TDM7 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_7_UL_HL", - "Secondary TDM7 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_0_DL_HL", - "Tertiary TDM0 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_0_UL_HL", - "Tertiary TDM0 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_1_DL_HL", - "Tertiary TDM1 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_1_UL_HL", - "Tertiary TDM1 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_2_DL_HL", - "Tertiary TDM2 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_2_UL_HL", - "Tertiary TDM2 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_3_DL_HL", - "Tertiary TDM3 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_3_UL_HL", - "Tertiary TDM3 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_4_DL_HL", - "Tertiary TDM4 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_4_UL_HL", - "Tertiary TDM4 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_5_DL_HL", - "Tertiary TDM5 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_5_UL_HL", - "Tertiary TDM5 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_6_DL_HL", - "Tertiary TDM6 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_6_UL_HL", - "Tertiary TDM6 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_7_DL_HL", - "Tertiary TDM7 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_7_UL_HL", - "Tertiary TDM7 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_0_DL_HL", - "Quaternary TDM0 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_0_UL_HL", - "Quaternary TDM0 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_1_DL_HL", - "Quaternary TDM1 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_1_UL_HL", - "Quaternary TDM1 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_2_DL_HL", - "Quaternary TDM2 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_2_UL_HL", - "Quaternary TDM2 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_3_DL_HL", - "Quaternary TDM3 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_3_UL_HL", - "Quaternary TDM3 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_4_DL_HL", - "Quaternary TDM4 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_4_UL_HL", - "Quaternary TDM4 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_5_DL_HL", - "Quaternary TDM5 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_5_UL_HL", - "Quaternary TDM5 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_6_DL_HL", - "Quaternary TDM6 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_6_UL_HL", - "Quaternary TDM6 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_7_DL_HL", - "Quaternary TDM7 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_7_UL_HL", - "Quaternary TDM7 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_0_DL_HL", - "Quinary TDM0 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_0_UL_HL", - "Quinary TDM0 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_1_DL_HL", - "Quinary TDM1 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_1_UL_HL", - "Quinary TDM1 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_2_DL_HL", - "Quinary TDM2 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_2_UL_HL", - "Quinary TDM2 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_3_DL_HL", - "Quinary TDM3 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_3_UL_HL", - "Quinary TDM3 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_4_DL_HL", - "Quinary TDM4 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_4_UL_HL", - "Quinary TDM4 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_5_DL_HL", - "Quinary TDM5 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_5_UL_HL", - "Quinary TDM5 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_6_DL_HL", - "Quinary TDM6 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_6_UL_HL", - "Quinary TDM6 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_7_DL_HL", - "Quinary TDM7 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_7_UL_HL", - "Quinary TDM7 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_0_DL_HL", - "Senary TDM0 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_0_UL_HL", - "Senary TDM0 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_1_DL_HL", - "Senary TDM1 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_1_UL_HL", - "Senary TDM1 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_2_DL_HL", - "Senary TDM2 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_2_UL_HL", - "Senary TDM2 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_3_DL_HL", - "Senary TDM3 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_3_UL_HL", - "Senary TDM3 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_4_DL_HL", - "Senary TDM4 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_4_UL_HL", - "Senary TDM4 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_5_DL_HL", - "Senary TDM5 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_5_UL_HL", - "Senary TDM5 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_6_DL_HL", - "Senary TDM6 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_6_UL_HL", - "Senary TDM6 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_7_DL_HL", - "Senary TDM7 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_7_UL_HL", - "Senary TDM7 Hostless Capture", - 0, 0, 0, 0), - - /* LSM */ - SND_SOC_DAPM_AIF_OUT("LSM1_UL_HL", "Listen 1 Audio Service Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("LSM2_UL_HL", "Listen 2 Audio Service Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("LSM3_UL_HL", "Listen 3 Audio Service Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("LSM4_UL_HL", "Listen 4 Audio Service Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("LSM5_UL_HL", "Listen 5 Audio Service Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("LSM6_UL_HL", "Listen 6 Audio Service Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("LSM7_UL_HL", "Listen 7 Audio Service Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("LSM8_UL_HL", "Listen 8 Audio Service Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QCHAT_DL", "QCHAT Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QCHAT_UL", "QCHAT Capture", 0, 0, 0, 0), - /* Backend AIF */ - /* Stream name equals to backend dai link stream name */ - SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_I2S_RX", "Secondary I2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_SPDIF_RX", "Primary SPDIF Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_SPDIF_TX", "Primary SPDIF Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_SPDIF_RX", "Secondary SPDIF Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_SPDIF_TX", "Secondary SPDIF Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_RX", "Slimbus2 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_RX", "Slimbus5 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("HDMI_MS", "HDMI MS Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT", "Display Port Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT1", "Display Port1 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX", "Quaternary MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX", "Tertiary MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX", "Secondary MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_SD1", - "Secondary MI2S Playback SD1", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_MI2S_RX", "Primary MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT0_MI2S_RX", "INT0 MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT2_MI2S_RX", "INT2 MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT3_MI2S_RX", "INT3 MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT5_MI2S_RX", "INT5 MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT4_MI2S_RX", "INT4 MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT4_MI2S_TX", "INT4 MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_MI2S_RX", "Quinary MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_MI2S_RX", "Senary MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MI2S_TX", "MI2S Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX", "Quaternary MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_MI2S_TX", "Primary MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX", "Tertiary MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT0_MI2S_TX", "INT0 MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INT2_MI2S_TX", "INT2 MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INT3_MI2S_TX", "INT3 MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX", "Secondary MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_2_TX", "Slimbus2 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_MI2S_TX", "Quinary MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SENARY_MI2S_TX", "Senary MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INT_BT_SCO_TX", "Internal BT-SCO Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT_BT_A2DP_RX", "Internal BT-A2DP Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT_FM_RX", "Internal FM Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INT_FM_TX", "Internal FM Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PCM_RX", "AFE Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PCM_TX", "AFE Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_0", "Primary TDM0 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_0", "Primary TDM0 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_1", "Primary TDM1 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_1", "Primary TDM1 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_2", "Primary TDM2 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_2", "Primary TDM2 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_3", "Primary TDM3 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_3", "Primary TDM3 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_4", "Primary TDM4 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_4", "Primary TDM4 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_5", "Primary TDM5 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_5", "Primary TDM5 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_6", "Primary TDM6 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_6", "Primary TDM6 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_7", "Primary TDM7 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_7", "Primary TDM7 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_0", "Secondary TDM0 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_0", "Secondary TDM0 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_1", "Secondary TDM1 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_1", "Secondary TDM1 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_2", "Secondary TDM2 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_2", "Secondary TDM2 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_3", "Secondary TDM3 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_3", "Secondary TDM3 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_4", "Secondary TDM4 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_4", "Secondary TDM4 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_5", "Secondary TDM5 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_5", "Secondary TDM5 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_6", "Secondary TDM6 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_6", "Secondary TDM6 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_7", "Secondary TDM7 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_7", "Secondary TDM7 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_0", "Tertiary TDM0 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_0", "Tertiary TDM0 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_1", "Tertiary TDM1 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_1", "Tertiary TDM1 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_2", "Tertiary TDM2 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_2", "Tertiary TDM2 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_3", "Tertiary TDM3 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_3", "Tertiary TDM3 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_4", "Tertiary TDM4 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_4", "Tertiary TDM4 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_5", "Tertiary TDM5 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_5", "Tertiary TDM5 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_6", "Tertiary TDM6 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_6", "Tertiary TDM6 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_7", "Tertiary TDM7 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_7", "Tertiary TDM7 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_0", "Quaternary TDM0 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_0", "Quaternary TDM0 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_1", "Quaternary TDM1 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_1", "Quaternary TDM1 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_2", "Quaternary TDM2 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_2", "Quaternary TDM2 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_3", "Quaternary TDM3 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_3", "Quaternary TDM3 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_4", "Quaternary TDM4 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_4", "Quaternary TDM4 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_5", "Quaternary TDM5 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_5", "Quaternary TDM5 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_6", "Quaternary TDM6 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_6", "Quaternary TDM6 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_7", "Quaternary TDM7 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_7", "Quaternary TDM7 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_0", "Quinary TDM0 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_0", "Quinary TDM0 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_1", "Quinary TDM1 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_1", "Quinary TDM1 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_2", "Quinary TDM2 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_2", "Quinary TDM2 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_3", "Quinary TDM3 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_3", "Quinary TDM3 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_4", "Quinary TDM4 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_4", "Quinary TDM4 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_5", "Quinary TDM5 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_5", "Quinary TDM5 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_6", "Quinary TDM6 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_6", "Quinary TDM6 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_7", "Quinary TDM7 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_7", "Quinary TDM7 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_0", "Senary TDM0 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_0", "Senary TDM0 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_1", "Senary TDM1 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_1", "Senary TDM1 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_2", "Senary TDM2 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_2", "Senary TDM2 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_3", "Senary TDM3 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_3", "Senary TDM3 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_4", "Senary TDM4 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_4", "Senary TDM4 Capture", +static const struct snd_kcontrol_new sen_tdm_tx_0_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sen_tdm_rx_1_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sen_tdm_rx_2_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sen_tdm_rx_3_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_2_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_rx_2_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_0_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_1_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_2_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_3_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_0_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_1_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_2_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_3_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_0_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_1_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_2_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_3_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_7_port_mixer_controls[] = { + SOC_DOUBLE_EXT("TERT_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_7, + MSM_BACKEND_DAI_TERT_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_0_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_1_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_2_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_3_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_0_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_1_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_2_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_3_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_7_port_mixer_controls[] = { + SOC_DOUBLE_EXT("QUAT_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_7, + MSM_BACKEND_DAI_QUAT_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_7, + MSM_BACKEND_DAI_QUIN_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_rx_0_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_rx_1_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_rx_2_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_rx_3_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sen_tdm_rx_0_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sen_tdm_rx_1_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sen_tdm_rx_2_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sen_tdm_rx_3_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_rx_7_port_mixer_controls[] = { + SOC_DOUBLE_EXT("TERT_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_7, + MSM_BACKEND_DAI_TERT_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_7, + MSM_BACKEND_DAI_QUAT_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_7, + MSM_BACKEND_DAI_QUIN_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; +#endif + +static const struct snd_kcontrol_new mmul1_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul2_mixer_controls[] = { + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_AUXPCM_DISABLE + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +}; + +static const struct snd_kcontrol_new mmul3_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_AUXPCM_DISABLE + SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul4_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul5_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul6_mixer_controls[] = { + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul8_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul16_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul9_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul10_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; +static const struct snd_kcontrol_new mmul17_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul18_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul19_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul20_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul21_mixer_controls[] = { + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul22_mixer_controls[] = { +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +}; + +static const struct snd_kcontrol_new mmul23_mixer_controls[] = { +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +}; + +static const struct snd_kcontrol_new mmul24_mixer_controls[] = { +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +}; + +static const struct snd_kcontrol_new mmul25_mixer_controls[] = { +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +}; + +static const struct snd_kcontrol_new mmul27_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul28_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul29_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul30_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; +#ifndef CONFIG_MI2S_DISABLE +static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new sec_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; +#endif +static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new slimbus_6_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new usb_audio_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new display_port_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new display_port_rx1_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +#ifndef CONFIG_MI2S_DISABLE +static const struct snd_kcontrol_new mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new pri_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new int0_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new int4_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tert_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new quat_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new quin_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new sen_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +#endif +static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +#ifndef CONFIG_AUXPCM_DISABLE +static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new sec_aux_pcm_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tert_aux_pcm_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new quat_aux_pcm_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new quin_aux_pcm_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new sen_aux_pcm_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; +#endif + +static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new slimbus_7_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new slimbus_8_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new wsa_cdc_dma_rx_1_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_0_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_1_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_2_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_3_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_4_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_5_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_6_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_7_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + + +static const struct snd_kcontrol_new stub_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new slimbus_1_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new proxy_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PROXY_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PROXY_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_0_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("INT_BT_SCO_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), +#ifndef CONFIG_AUXPCM_DISABLE + SOC_DOUBLE_EXT("AUX_PCM_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_7_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PROXY_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PROXY_TX, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("INT_BT_SCO_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("AUX_PCM_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PROXY_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PROXY_TX, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("MI2S_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +#ifndef CONFIG_AUXPCM_DISABLE + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +#endif + SOC_DOUBLE_EXT("PRI_MI2S_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3_Voip", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { + SOC_DOUBLE_EXT("STUB_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("STUB_1_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_EC_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#ifndef CONFIG_AUXPCM_DISABLE + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +}; + +static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = { + SOC_DOUBLE_EXT("STUB_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("STUB_1_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_EC_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#ifndef CONFIG_AUXPCM_DISABLE + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +//aditya to confirm +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +}; + +static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = { + SOC_DOUBLE_EXT("STUB_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("STUB_1_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_EC_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#ifndef CONFIG_AUXPCM_DISABLE + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +}; + +static const struct snd_kcontrol_new tx_qchat_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +#ifndef CONFIG_AUXPCM_DISABLE + SOC_DOUBLE_EXT("AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +#endif +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("MI2S_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_7_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_port_mixer_controls[] = { + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_0_port_mixer_controls[] = { + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_1_port_mixer_controls[] = { + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_PRI_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SENARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +#ifndef CONFIG_AUXPCM_DISABLE +static const struct snd_kcontrol_new aux_pcm_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_auxpcm_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_auxpcm_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_auxpcm_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quin_auxpcm_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sen_auxpcm_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; +#endif + +static const struct snd_kcontrol_new sbus_1_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sbus_3_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_BACKEND_DAI_AUXPCM_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_BACKEND_DAI_SLIMBUS_0_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sbus_6_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new bt_sco_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new afe_pcm_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + + +static const struct snd_kcontrol_new hdmi_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new hdmi_rx_ms_port_mixer_controls[] = { + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new display_port_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new display_port_rx1_port_mixer_controls[] = { + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + + +static const struct snd_kcontrol_new usb_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_USB_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new lsm1_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif +}; + +static const struct snd_kcontrol_new lsm2_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_1_TX", + SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif +}; + +static const struct snd_kcontrol_new lsm3_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif +}; + +static const struct snd_kcontrol_new lsm4_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif +}; + +static const struct snd_kcontrol_new lsm5_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif +}; + +static const struct snd_kcontrol_new lsm6_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif +}; + +static const struct snd_kcontrol_new lsm7_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif +}; + +static const struct snd_kcontrol_new lsm8_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif +}; + +static const struct snd_kcontrol_new slim_fm_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new slim1_fm_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new slim3_fm_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new slim4_fm_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new cdc_dma_wsa_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new cdc_dma_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new cdc_dma_rx_1_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new slim6_fm_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new pcm_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_fm_pcmrx_switch_mixer, + msm_routing_put_fm_pcmrx_switch_mixer); + +static const struct snd_kcontrol_new hfp_pri_aux_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_hfp_switch_mixer, + msm_routing_put_hfp_switch_mixer); + +static const struct snd_kcontrol_new hfp_aux_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_hfp_switch_mixer, + msm_routing_put_hfp_switch_mixer); + +static const struct snd_kcontrol_new hfp_int_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_hfp_switch_mixer, + msm_routing_put_hfp_switch_mixer); + +static const struct snd_kcontrol_new hfp_slim7_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_hfp_switch_mixer, + msm_routing_put_hfp_switch_mixer); + +static const struct snd_kcontrol_new usb_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_usb_switch_mixer, + msm_routing_put_usb_switch_mixer); + +static const struct snd_kcontrol_new a2dp_slim7_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_a2dp_switch_mixer_get, + msm_routing_a2dp_switch_mixer_put); + +static const struct snd_kcontrol_new sco_slim7_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_sco_switch_mixer_get, + msm_routing_sco_switch_mixer_put); + +static const struct soc_enum lsm_port_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_port_text), lsm_port_text); + +static const char * const lsm_func_text[] = { + "None", "AUDIO", "BEACON", "ULTRASOUND", "SWAUDIO", +}; +static const struct soc_enum lsm_func_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_func_text), lsm_func_text); + +static const struct snd_kcontrol_new lsm_controls[] = { + /* kcontrol of lsm_function */ + SOC_ENUM_EXT(SLIMBUS_0_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(SLIMBUS_1_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(SLIMBUS_2_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(SLIMBUS_3_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(SLIMBUS_4_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(SLIMBUS_5_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(TERT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(QUAT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(INT3_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(TX_CDC_DMA_TX_3_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(QUIN_TDM_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(TERT_TDM_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + /* kcontrol of lsm_port */ + SOC_ENUM_EXT("LSM1 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM2 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM3 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM4 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM5 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM6 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM7 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM8 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), +}; + +static const char * const aanc_slim_0_rx_text[] = { + "ZERO", "SLIMBUS_0_TX", "SLIMBUS_1_TX", "SLIMBUS_2_TX", "SLIMBUS_3_TX", + "SLIMBUS_4_TX", "SLIMBUS_5_TX", "SLIMBUS_6_TX" +}; + +static const struct soc_enum aanc_slim_0_rx_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(aanc_slim_0_rx_text), + aanc_slim_0_rx_text); + +static const struct snd_kcontrol_new aanc_slim_0_rx_mux[] = { + SOC_ENUM_EXT("AANC_SLIM_0_RX MUX", aanc_slim_0_rx_enum, + msm_routing_slim_0_rx_aanc_mux_get, + msm_routing_slim_0_rx_aanc_mux_put) +}; + +static int msm_routing_aanc_noise_level_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = aanc_level; + + return 0; +} + +static int msm_routing_aanc_noise_level_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + + mutex_lock(&routing_lock); + aanc_level = ucontrol->value.integer.value[0]; + pr_debug("%s: value: %ld\n", + __func__, ucontrol->value.integer.value[0]); + ret = afe_set_aanc_noise_level(aanc_level); + mutex_unlock(&routing_lock); + + return ret; +} + +static const struct snd_kcontrol_new aanc_noise_level[] = { + SOC_SINGLE_EXT("AANC Noise Level", SND_SOC_NOPM, 0, 255, + 0, msm_routing_aanc_noise_level_get, msm_routing_aanc_noise_level_put) +}; + +static int msm_routing_get_stereo_to_custom_stereo_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = is_custom_stereo_on; + return 0; +} + +static int msm_routing_put_stereo_to_custom_stereo_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int flag = 0, i = 0, rc = 0, idx = 0; + int be_index = 0, port_id, topo_id; + unsigned int session_id = 0; + uint16_t op_FL_ip_FL_weight = 0; + uint16_t op_FL_ip_FR_weight = 0; + uint16_t op_FR_ip_FL_weight = 0; + uint16_t op_FR_ip_FR_weight = 0; + + flag = ucontrol->value.integer.value[0]; + pr_debug("%s E flag %d\n", __func__, flag); + + if ((is_custom_stereo_on && flag) || (!is_custom_stereo_on && !flag)) { + pr_err("%s: is_custom_stereo_on %d, flag %d\n", + __func__, is_custom_stereo_on, flag); + return 0; + } + is_custom_stereo_on = flag ? true : false; + pr_debug("%s:is_custom_stereo_on %d\n", __func__, is_custom_stereo_on); + for (be_index = 0; be_index < MSM_BACKEND_DAI_MAX; be_index++) { + port_id = msm_bedais[be_index].port_id; + if (!msm_bedais[be_index].active) + continue; + if ((port_id != SLIMBUS_0_RX) && + (port_id != RT_PROXY_PORT_001_RX) && + (port_id != AFE_PORT_ID_PRIMARY_MI2S_RX) && + (port_id != AFE_PORT_ID_INT4_MI2S_RX)) + continue; + + for_each_set_bit(i, &msm_bedais[be_index].fe_sessions[0], + MSM_FRONTEND_DAI_MM_SIZE) { + if (fe_dai_map[i][SESSION_TYPE_RX].perf_mode != + LEGACY_PCM_MODE) + goto skip_send_custom_stereo; + session_id = + fe_dai_map[i][SESSION_TYPE_RX].strm_id; + if (is_custom_stereo_on) { + op_FL_ip_FL_weight = + Q14_GAIN_ZERO_POINT_FIVE; + op_FL_ip_FR_weight = + Q14_GAIN_ZERO_POINT_FIVE; + op_FR_ip_FL_weight = + Q14_GAIN_ZERO_POINT_FIVE; + op_FR_ip_FR_weight = + Q14_GAIN_ZERO_POINT_FIVE; + } else { + op_FL_ip_FL_weight = Q14_GAIN_UNITY; + op_FL_ip_FR_weight = 0; + op_FR_ip_FL_weight = 0; + op_FR_ip_FR_weight = Q14_GAIN_UNITY; + } + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { + unsigned long copp = + session_copp_map[i] + [SESSION_TYPE_RX][be_index]; + if (!test_bit(idx, &copp)) + goto skip_send_custom_stereo; + topo_id = adm_get_topology_for_port_copp_idx( + msm_bedais[be_index].port_id, idx); + if (topo_id < 0) + pr_debug("%s:Err:custom stereo topo %d", + __func__, topo_id); + pr_debug("idx %d\n", idx); + if (topo_id == DS2_ADM_COPP_TOPOLOGY_ID) + rc = msm_ds2_dap_set_custom_stereo_onoff + (msm_bedais[be_index].port_id, + idx, is_custom_stereo_on); + else if (topo_id == DOLBY_ADM_COPP_TOPOLOGY_ID) + rc = dolby_dap_set_custom_stereo_onoff( + msm_bedais[be_index].port_id, + idx, is_custom_stereo_on); + else + rc = msm_qti_pp_send_stereo_to_custom_stereo_cmd + (msm_bedais[be_index].port_id, + idx, session_id, + op_FL_ip_FL_weight, + op_FL_ip_FR_weight, + op_FR_ip_FL_weight, + op_FR_ip_FR_weight); + if (rc < 0) +skip_send_custom_stereo: + pr_err("%s: err setting custom stereo\n", + __func__); + } + + } + } + return 0; +} + +static const struct snd_kcontrol_new stereo_to_custom_stereo_controls[] = { + SOC_SINGLE_EXT("Set Custom Stereo OnOff", SND_SOC_NOPM, 0, + 1, 0, msm_routing_get_stereo_to_custom_stereo_control, + msm_routing_put_stereo_to_custom_stereo_control), +}; + +static int msm_routing_get_app_type_cfg_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static int msm_routing_put_app_type_cfg_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int i = 0, j; + int num_app_types = ucontrol->value.integer.value[i++]; + + pr_debug("%s\n", __func__); + + memset(app_type_cfg, 0, MAX_APP_TYPES* + sizeof(struct msm_pcm_routing_app_type_data)); + if (num_app_types > MAX_APP_TYPES) { + pr_err("%s: number of app types exceed the max supported\n", + __func__); + return -EINVAL; + } + for (j = 0; j < num_app_types; j++) { + app_type_cfg[j].app_type = + ucontrol->value.integer.value[i++]; + app_type_cfg[j].sample_rate = + ucontrol->value.integer.value[i++]; + app_type_cfg[j].bit_width = + ucontrol->value.integer.value[i++]; + } + + return 0; +} + +static int msm_routing_put_app_type_gain_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int j, fe_id, be_id, port_type; + int ret = 0; + unsigned long copp; + struct msm_pcm_routing_bdai_data *bedai; + int dir = ucontrol->value.integer.value[0] ? SESSION_TYPE_TX : + SESSION_TYPE_RX; + int app_type = ucontrol->value.integer.value[1]; + int gain = (ucontrol->value.integer.value[2] + + ucontrol->value.integer.value[3])/2; + + port_type = (dir == SESSION_TYPE_RX) ? MSM_AFE_PORT_TYPE_RX : + MSM_AFE_PORT_TYPE_TX; + + mutex_lock(&routing_lock); + for (be_id = 0; be_id < MSM_BACKEND_DAI_MAX; be_id++) { + if (is_be_dai_extproc(be_id)) + continue; + + bedai = &msm_bedais[be_id]; + if (afe_get_port_type(bedai->port_id) != port_type) + continue; + + if (!bedai->active) + continue; + + for (fe_id = 0; fe_id < MSM_FRONTEND_DAI_MAX; fe_id++) { + if (!test_bit(fe_id, &bedai->fe_sessions[0])) + continue; + + if (app_type != + fe_dai_app_type_cfg[fe_id][dir][be_id].app_type) + continue; + + copp = session_copp_map[fe_id][dir][be_id]; + for (j = 0; j < MAX_COPPS_PER_PORT; j++) { + if (!test_bit(j, &copp)) + continue; + ret |= adm_set_volume(bedai->port_id, j, gain); + } + } + } + mutex_unlock(&routing_lock); + return ret ? -EINVAL : 0; +} + +static const struct snd_kcontrol_new app_type_cfg_controls[] = { + SOC_SINGLE_MULTI_EXT("App Type Config", SND_SOC_NOPM, 0, + 0x7FFFFFFF, 0, 128, msm_routing_get_app_type_cfg_control, + msm_routing_put_app_type_cfg_control), + SOC_SINGLE_MULTI_EXT("App Type Gain", SND_SOC_NOPM, 0, + 0x2000, 0, 4, NULL, msm_routing_put_app_type_gain_control) +}; + +static int msm_routing_put_module_cfg_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int copp_idx, fe_id, be_id, port_type; + int ret = 0; + unsigned long copp; + struct msm_pcm_routing_bdai_data *bedai; + u8 *packed_params = NULL; + struct param_hdr_v3 param_hdr; + u32 packed_param_size = (sizeof(struct param_hdr_v3) + + sizeof(uint32_t)); + + int dir = ucontrol->value.integer.value[0] ? SESSION_TYPE_TX : + SESSION_TYPE_RX; + int app_type = ucontrol->value.integer.value[1]; + int module_id = ucontrol->value.integer.value[2]; + int instance_id = ucontrol->value.integer.value[3]; + int param_id = ucontrol->value.integer.value[4]; + int param_value = ucontrol->value.integer.value[5]; + + port_type = (dir == SESSION_TYPE_RX) ? MSM_AFE_PORT_TYPE_RX : + MSM_AFE_PORT_TYPE_TX; + pr_debug("%s app_type:%d mod_id:%d instance_id:%d param_id:%d value:%d\n", + __func__, app_type, module_id, + instance_id, param_id, param_value); + + packed_params = kzalloc(packed_param_size, GFP_KERNEL); + if (!packed_params) + return -ENOMEM; + + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = module_id; + param_hdr.instance_id = instance_id; + param_hdr.param_id = param_id; + param_hdr.param_size = sizeof(uint32_t); + + packed_param_size = 0; + + mutex_lock(&routing_lock); + for (be_id = 0; be_id < MSM_BACKEND_DAI_MAX; be_id++) { + if (is_be_dai_extproc(be_id)) + continue; + + bedai = &msm_bedais[be_id]; + if (afe_get_port_type(bedai->port_id) != port_type) + continue; + + if (!bedai->active) + continue; + + for (fe_id = 0; fe_id < MSM_FRONTEND_DAI_MAX; fe_id++) { + if (!test_bit(fe_id, &bedai->fe_sessions[0])) + continue; + + if (app_type != + fe_dai_app_type_cfg[fe_id][dir][be_id].app_type) + continue; + + copp = session_copp_map[fe_id][dir][be_id]; + for (copp_idx = 0; copp_idx < MAX_COPPS_PER_PORT; + copp_idx++) { + if (!test_bit(copp_idx, &copp)) + continue; + + ret = q6common_pack_pp_params(packed_params, + ¶m_hdr, + (u8 *) ¶m_value, + &packed_param_size); + if (ret) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, ret); + goto done; + } + + ret = adm_set_pp_params(bedai->port_id, + copp_idx, NULL, + packed_params, + packed_param_size); + if (ret) { + pr_err("%s: Setting param failed with err=%d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + } + } + } +done: + mutex_unlock(&routing_lock); + kfree(packed_params); + return ret; +} + +static const struct snd_kcontrol_new module_cfg_controls[] = { + SOC_SINGLE_MULTI_EXT("Audio Effect", SND_SOC_NOPM, 0, + 0x2000, 0, 6, NULL, msm_routing_put_module_cfg_control) +}; + +static int msm_routing_get_lsm_app_type_cfg_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int shift = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int i = 0, j = 0; + + mutex_lock(&routing_lock); + ucontrol->value.integer.value[i] = num_app_cfg_types; + + for (j = 0; j < num_app_cfg_types; ++j) { + ucontrol->value.integer.value[++i] = + lsm_app_type_cfg[j].app_type; + ucontrol->value.integer.value[++i] = + lsm_app_type_cfg[j].sample_rate; + ucontrol->value.integer.value[++i] = + lsm_app_type_cfg[j].bit_width; + if (shift == 1) + ucontrol->value.integer.value[++i] = + lsm_app_type_cfg[j].num_out_channels; + } + mutex_unlock(&routing_lock); + return 0; +} + +static int msm_routing_put_lsm_app_type_cfg_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int shift = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int i = 0, j; + + mutex_lock(&routing_lock); + if (ucontrol->value.integer.value[0] > MAX_APP_TYPES) { + pr_err("%s: number of app types exceed the max supported\n", + __func__); + mutex_unlock(&routing_lock); + return -EINVAL; + } + + num_app_cfg_types = ucontrol->value.integer.value[i++]; + memset(lsm_app_type_cfg, 0, MAX_APP_TYPES* + sizeof(struct msm_pcm_routing_app_type_data)); + + for (j = 0; j < num_app_cfg_types; j++) { + lsm_app_type_cfg[j].app_type = + ucontrol->value.integer.value[i++]; + lsm_app_type_cfg[j].sample_rate = + ucontrol->value.integer.value[i++]; + lsm_app_type_cfg[j].bit_width = + ucontrol->value.integer.value[i++]; + /* Shift of 1 indicates this is V2 mixer control */ + if (shift == 1) + lsm_app_type_cfg[j].num_out_channels = + ucontrol->value.integer.value[i++]; + } + mutex_unlock(&routing_lock); + return 0; +} + +static const struct snd_kcontrol_new lsm_app_type_cfg_controls[] = { + SOC_SINGLE_MULTI_EXT("Listen App Type Config", SND_SOC_NOPM, 0, + 0xFFFFFFFF, 0, 128, msm_routing_get_lsm_app_type_cfg_control, + msm_routing_put_lsm_app_type_cfg_control), + SOC_SINGLE_MULTI_EXT("Listen App Type Config V2", SND_SOC_NOPM, 1, + 0xFFFFFFFF, 0, 128, msm_routing_get_lsm_app_type_cfg_control, + msm_routing_put_lsm_app_type_cfg_control), +}; + +static int msm_routing_get_use_ds1_or_ds2_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = is_ds2_on; + return 0; +} + +static int msm_routing_put_use_ds1_or_ds2_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + is_ds2_on = ucontrol->value.integer.value[0]; + return 0; +} + +static const struct snd_kcontrol_new use_ds1_or_ds2_controls[] = { + SOC_SINGLE_EXT("DS2 OnOff", SND_SOC_NOPM, 0, + 1, 0, msm_routing_get_use_ds1_or_ds2_control, + msm_routing_put_use_ds1_or_ds2_control), +}; + +static int msm_routing_get_hifi_filter_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = hifi_filter_enabled; + return 0; +} + +static int msm_routing_put_hifi_filter_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + hifi_filter_enabled = ucontrol->value.integer.value[0]; + return 0; +} + +static const struct snd_kcontrol_new hifi_filter_controls[] = { + SOC_SINGLE_EXT("HiFi Filter", SND_SOC_NOPM, 0, + 1, 0, msm_routing_get_hifi_filter_control, + msm_routing_put_hifi_filter_control), +}; + +static int msm_routing_get_ffecns_freeze_event_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = ffecns_freeze_event; + return 0; +} + +static int msm_routing_put_ffecns_freeze_event_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = -EINVAL; + + ffecns_freeze_event = ucontrol->value.integer.value[0]; + + ret = adm_set_ffecns_freeze_event(ffecns_freeze_event); + if (ret) + pr_err("%s: failed to set ffecns imc event to%d\n", + __func__, ffecns_freeze_event); + + return ret; +} + +static const struct snd_kcontrol_new use_ffecns_freeze_event_controls[] = { + SOC_SINGLE_EXT("FFECNS Freeze Event", SND_SOC_NOPM, 0, + 1, 0, msm_routing_get_ffecns_freeze_event_control, + msm_routing_put_ffecns_freeze_event_control), +}; + +int msm_routing_get_rms_value_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { + int rc = 0; + int be_idx = 0; + char *param_value; + int *update_param_value; + uint32_t param_size = (RMS_PAYLOAD_LEN + 1) * sizeof(uint32_t); + struct param_hdr_v3 param_hdr; + + param_value = kzalloc(param_size, GFP_KERNEL); + if (!param_value) + return -ENOMEM; + + memset(¶m_hdr, 0, sizeof(param_hdr)); + for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) + if (msm_bedais[be_idx].port_id == SLIMBUS_0_TX) + break; + if ((be_idx < MSM_BACKEND_DAI_MAX) && msm_bedais[be_idx].active) { + param_hdr.module_id = RMS_MODULEID_APPI_PASSTHRU; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = RMS_PARAM_FIRST_SAMPLE; + param_hdr.param_size = param_size; + rc = adm_get_pp_params(SLIMBUS_0_TX, 0, ADM_CLIENT_ID_DEFAULT, + NULL, ¶m_hdr, (u8 *) param_value); + if (rc) { + pr_err("%s: get parameters failed:%d\n", __func__, rc); + kfree(param_value); + return -EINVAL; + } + update_param_value = (int *)param_value; + ucontrol->value.integer.value[0] = update_param_value[0]; + + pr_debug("%s: FROM DSP value[0] 0x%x\n", + __func__, update_param_value[0]); + } + kfree(param_value); + return 0; +} + +static int msm_voc_session_id_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + voc_session_id = ucontrol->value.integer.value[0]; + + pr_debug("%s: voc_session_id=%u\n", __func__, voc_session_id); + + return 0; +} + +static int msm_voc_session_id_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = voc_session_id; + + return 0; +} + +static struct snd_kcontrol_new msm_voc_session_controls[] = { + SOC_SINGLE_MULTI_EXT("Voc VSID", SND_SOC_NOPM, 0, + 0xFFFFFFFF, 0, 1, msm_voc_session_id_get, + msm_voc_session_id_put), +}; + +static int msm_sound_focus_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(struct sound_focus_param); + + return 0; +} + +static int msm_voice_sound_focus_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct sound_focus_param soundFocusData; + + memcpy((void *)&soundFocusData, ucontrol->value.bytes.data, + sizeof(struct sound_focus_param)); + ret = voc_set_sound_focus(soundFocusData); + if (ret) { + pr_err("%s: Error setting Sound Focus Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + } + + return ret; +} + +static int msm_voice_sound_focus_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct sound_focus_param soundFocusData; + + memset(&soundFocusData, 0, sizeof(struct sound_focus_param)); + + ret = voc_get_sound_focus(&soundFocusData); + if (ret) { + pr_debug("%s: Error getting Sound Focus Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + memcpy(ucontrol->value.bytes.data, (void *)&soundFocusData, + sizeof(struct sound_focus_param)); + +done: + return ret; +} + +static int msm_source_tracking_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(struct source_tracking_param); + + return 0; +} + +static int msm_voice_source_tracking_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct source_tracking_param sourceTrackingData; + + memset(&sourceTrackingData, 0, sizeof(struct source_tracking_param)); + + ret = voc_get_source_tracking(&sourceTrackingData); + if (ret) { + pr_debug("%s: Error getting Source Tracking Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + memcpy(ucontrol->value.bytes.data, (void *)&sourceTrackingData, + sizeof(struct source_tracking_param)); + +done: + return ret; +} + +static int msm_audio_get_copp_idx_from_port_id(int port_id, int session_type, + int *copp_idx) +{ + int i, idx, be_idx; + int ret = 0; + unsigned long copp; + + pr_debug("%s: Enter, port_id=%d\n", __func__, port_id); + + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: port validation failed id 0x%x ret %d\n", + __func__, port_id, ret); + + ret = -EINVAL; + goto done; + } + + for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) { + if (msm_bedais[be_idx].port_id == port_id) + break; + } + if (be_idx >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: Invalid be id %d\n", __func__, be_idx); + + ret = -EINVAL; + goto done; + } + + for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0], + MSM_FRONTEND_DAI_MAX) { + if (!(is_mm_lsm_fe_id(i) && + route_check_fe_id_adm_support(i))) + continue; + + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { + copp = session_copp_map[i] + [session_type][be_idx]; + if (test_bit(idx, &copp)) + break; + } + if (idx >= MAX_COPPS_PER_PORT) + continue; + else + break; + } + if (i >= MSM_FRONTEND_DAI_MAX) { + pr_debug("%s: Invalid FE, exiting\n", __func__); + + ret = -EINVAL; + goto done; + } + *copp_idx = idx; + pr_debug("%s: copp_idx=%d\n", __func__, *copp_idx); + +done: + return ret; +} + +static int msm_audio_sound_focus_derive_port_id(struct snd_kcontrol *kcontrol, + const char *prefix, int *port_id) +{ + int ret = 0; + + pr_debug("%s: Enter, prefix:%s\n", __func__, prefix); + + /* + * Mixer control name will be like "Sound Focus Audio Tx SLIMBUS_0" + * where the prefix is "Sound Focus Audio Tx ". Skip the prefix + * and compare the string with the backend name to derive the port id. + */ + if (!strcmp(kcontrol->id.name + strlen(prefix), + "SLIMBUS_0")) { + *port_id = SLIMBUS_0_TX; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "TERT_MI2S")) { + *port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "INT3_MI2S")) { + *port_id = AFE_PORT_ID_INT3_MI2S_TX; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "VA_CDC_DMA_TX_0")) { + *port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "TX_CDC_DMA_TX_3")) { + *port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "QUIN_TDM_TX_0")) { + *port_id = AFE_PORT_ID_QUINARY_TDM_TX; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "PRIMARY_TDM")) { + *port_id = AFE_PORT_ID_PRIMARY_TDM_TX; + } else { + pr_err("%s: mixer ctl name=%s, could not derive valid port id\n", + __func__, kcontrol->id.name); + + ret = -EINVAL; + goto done; + } + pr_debug("%s: mixer ctl name=%s, derived port_id=%d\n", + __func__, kcontrol->id.name, *port_id); + +done: + return ret; +} + +static int msm_audio_sound_focus_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct sound_focus_param soundFocusData; + int port_id, copp_idx; + + ret = msm_audio_sound_focus_derive_port_id(kcontrol, + "Sound Focus Audio Tx ", &port_id); + if (ret != 0) { + pr_err("%s: Error in deriving port id, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, + &copp_idx); + if (ret) { + pr_err("%s: Could not get copp idx for port_id=%d\n", + __func__, port_id); + + ret = -EINVAL; + goto done; + } + + memcpy((void *)&soundFocusData, ucontrol->value.bytes.data, + sizeof(struct sound_focus_param)); + + ret = adm_set_sound_focus(port_id, copp_idx, soundFocusData); + if (ret) { + pr_err("%s: Error setting Sound Focus Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + +done: + return ret; +} + +static int msm_audio_sound_focus_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct sound_focus_param soundFocusData; + int port_id, copp_idx; + + ret = msm_audio_sound_focus_derive_port_id(kcontrol, + "Sound Focus Audio Tx ", &port_id); + if (ret) { + pr_err("%s: Error in deriving port id, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, + &copp_idx); + if (ret) { + pr_debug("%s: Could not get copp idx for port_id=%d\n", + __func__, port_id); + + ret = -EINVAL; + goto done; + } + + ret = adm_get_sound_focus(port_id, copp_idx, &soundFocusData); + if (ret) { + pr_err("%s: Error getting Sound Focus Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + memcpy(ucontrol->value.bytes.data, (void *)&soundFocusData, + sizeof(struct sound_focus_param)); + +done: + return ret; +} + +static int msm_audio_source_tracking_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct source_tracking_param sourceTrackingData; + int port_id, copp_idx; + + ret = msm_audio_sound_focus_derive_port_id(kcontrol, + "Source Tracking Audio Tx ", &port_id); + if (ret) { + pr_err("%s: Error in deriving port id, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, + &copp_idx); + if (ret) { + pr_debug("%s: Could not get copp idx for port_id=%d\n", + __func__, port_id); + + ret = -EINVAL; + goto done; + } + + ret = adm_get_source_tracking(port_id, copp_idx, &sourceTrackingData); + if (ret) { + pr_err("%s: Error getting Source Tracking Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + memcpy(ucontrol->value.bytes.data, (void *)&sourceTrackingData, + sizeof(struct source_tracking_param)); + +done: + return ret; +} + +static int msm_doa_tracking_mon_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(struct doa_tracking_mon_param); + + return 0; +} + +static int msm_doa_tracking_mon_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct doa_tracking_mon_param doa_tracking_data; + int port_id, copp_idx; + + memset(&doa_tracking_data, 0, sizeof(struct doa_tracking_mon_param)); + ret = msm_audio_sound_focus_derive_port_id(kcontrol, + "Doa Tracking Monitor Listen ", &port_id); + if (ret) { + pr_err("%s: Error in deriving port id, err=%d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + /* + * If copp id exists for given port id, query adm to get doa data. + * Else query afe for doa tracking params. + * This is to support in cases where LSM directly connects to + * AFE for FFNS. + */ + ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, + &copp_idx); + if (!ret) + ret = adm_get_doa_tracking_mon(port_id, copp_idx, + &doa_tracking_data); + else + ret = afe_get_doa_tracking_mon(port_id, &doa_tracking_data); + + if (ret) { + pr_err("%s: Error getting Doa Tracking Params, err=%d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + memcpy(ucontrol->value.bytes.data, (void *)&doa_tracking_data, + sizeof(struct doa_tracking_mon_param)); +done: + return ret; +} + +static const struct snd_kcontrol_new msm_source_tracking_controls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx SLIMBUS_0", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx SLIMBUS_0", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx SLIMBUS_0", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx SLIMBUS_0", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx TERT_MI2S", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx TERT_MI2S", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx TERT_MI2S", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx TERT_MI2S", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx INT3_MI2S", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx INT3_MI2S", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx INT3_MI2S", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx INT3_MI2S", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx VA_CDC_DMA_TX_0", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx VA_CDC_DMA_TX_0", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx VA_CDC_DMA_TX_0", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx VA_CDC_DMA_TX_0", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx TX_CDC_DMA_TX_3", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx TX_CDC_DMA_TX_3", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx TX_CDC_DMA_TX_3", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx TX_CDC_DMA_TX_3", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx QUIN_TDM_TX_0", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx QUIN_TDM_TX_0", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx QUIN_TDM_TX_0", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx QUIN_TDM_TX_0", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx PRIMARY_TDM", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx PRIMARY_TDM", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, +}; + +static const struct snd_kcontrol_new msm_source_doa_tracking_controls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Doa Tracking Monitor Listen VA_CDC_DMA_TX_0", + .info = msm_doa_tracking_mon_info, + .get = msm_doa_tracking_mon_get, + }, +}; + +static int spkr_prot_put_vi_lch_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int item; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + + pr_debug("%s item is %d\n", __func__, + ucontrol->value.enumerated.item[0]); + mutex_lock(&routing_lock); + item = ucontrol->value.enumerated.item[0]; + if (item < e->items) { + pr_debug("%s RX DAI ID %d TX DAI id %d\n", + __func__, e->shift_l, e->values[item]); + if (e->shift_l < MSM_BACKEND_DAI_MAX && + e->values[item] < MSM_BACKEND_DAI_MAX) + /* Enable feedback TX path */ + ret = afe_spk_prot_feed_back_cfg( + msm_bedais[e->values[item]].port_id, + msm_bedais[e->shift_l].port_id, 1, 0, 1); + else { + pr_debug("%s values are out of range item %d\n", + __func__, e->values[item]); + /* Disable feedback TX path */ + if (e->values[item] == MSM_BACKEND_DAI_MAX) + ret = afe_spk_prot_feed_back_cfg(0, 0, 0, 0, 0); + else + ret = -EINVAL; + } + } else { + pr_err("%s item value is out of range item\n", __func__); + ret = -EINVAL; + } + mutex_unlock(&routing_lock); + return ret; +} + +static int spkr_prot_put_vi_rch_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int item; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + + pr_debug("%s item is %d\n", __func__, + ucontrol->value.enumerated.item[0]); + mutex_lock(&routing_lock); + item = ucontrol->value.enumerated.item[0]; + if (item < e->items) { + pr_debug("%s RX DAI ID %d TX DAI id %d\n", + __func__, e->shift_l, e->values[item]); + if (e->shift_l < MSM_BACKEND_DAI_MAX && + e->values[item] < MSM_BACKEND_DAI_MAX) + /* Enable feedback TX path */ + ret = afe_spk_prot_feed_back_cfg( + msm_bedais[e->values[item]].port_id, + msm_bedais[e->shift_l].port_id, + 1, 1, 1); + else { + pr_debug("%s values are out of range item %d\n", + __func__, e->values[item]); + /* Disable feedback TX path */ + if (e->values[item] == MSM_BACKEND_DAI_MAX) + ret = afe_spk_prot_feed_back_cfg(0, + 0, 0, 0, 0); + else + ret = -EINVAL; + } + } else { + pr_err("%s item value is out of range item\n", __func__); + ret = -EINVAL; + } + mutex_unlock(&routing_lock); + return ret; +} + +static int spkr_prot_get_vi_lch_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s\n", __func__); + return 0; +} + +static int spkr_prot_get_vi_rch_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s\n", __func__); + ucontrol->value.enumerated.item[0] = 0; + return 0; +} + +static const char * const slim0_rx_vi_fb_tx_lch_mux_text[] = { + "ZERO", "SLIM4_TX" +}; + +static const char * const slim0_rx_vi_fb_tx_rch_mux_text[] = { + "ZERO", "SLIM4_TX" +}; + +static const char * const wsa_rx_0_vi_fb_tx_lch_mux_text[] = { + "ZERO", "WSA_CDC_DMA_TX_0" +}; + +static const char * const wsa_rx_0_vi_fb_tx_rch_mux_text[] = { + "ZERO", "WSA_CDC_DMA_TX_0" +}; + +static const char * const mi2s_rx_vi_fb_tx_mux_text[] = { + "ZERO", "SENARY_TX" +}; + +static const char * const int4_mi2s_rx_vi_fb_tx_mono_mux_text[] = { + "ZERO", "INT5_MI2S_TX" +}; + +static const char * const int4_mi2s_rx_vi_fb_tx_stereo_mux_text[] = { + "ZERO", "INT5_MI2S_TX" +}; + +static const int slim0_rx_vi_fb_tx_lch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SLIMBUS_4_TX +}; + +static const int slim0_rx_vi_fb_tx_rch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SLIMBUS_4_TX +}; + +static const int wsa_rx_0_vi_fb_tx_lch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0 +}; + +static const int wsa_rx_0_vi_fb_tx_rch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0 +}; + + +static const int mi2s_rx_vi_fb_tx_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SENARY_MI2S_TX +}; + +static const int int4_mi2s_rx_vi_fb_tx_mono_ch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_INT5_MI2S_TX +}; + +static const int int4_mi2s_rx_vi_fb_tx_stereo_ch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_INT5_MI2S_TX +}; + +static const struct soc_enum slim0_rx_vi_fb_lch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_SLIMBUS_0_RX, 0, 0, + ARRAY_SIZE(slim0_rx_vi_fb_tx_lch_mux_text), + slim0_rx_vi_fb_tx_lch_mux_text, slim0_rx_vi_fb_tx_lch_value); + +static const struct soc_enum slim0_rx_vi_fb_rch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_SLIMBUS_0_RX, 0, 0, + ARRAY_SIZE(slim0_rx_vi_fb_tx_rch_mux_text), + slim0_rx_vi_fb_tx_rch_mux_text, slim0_rx_vi_fb_tx_rch_value); + +static const struct soc_enum wsa_rx_0_vi_fb_lch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, 0, 0, + ARRAY_SIZE(wsa_rx_0_vi_fb_tx_lch_mux_text), + wsa_rx_0_vi_fb_tx_lch_mux_text, wsa_rx_0_vi_fb_tx_lch_value); + +static const struct soc_enum wsa_rx_0_vi_fb_rch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, 0, 0, + ARRAY_SIZE(wsa_rx_0_vi_fb_tx_rch_mux_text), + wsa_rx_0_vi_fb_tx_rch_mux_text, wsa_rx_0_vi_fb_tx_rch_value); + +static const struct soc_enum mi2s_rx_vi_fb_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_PRI_MI2S_RX, 0, 0, + ARRAY_SIZE(mi2s_rx_vi_fb_tx_mux_text), + mi2s_rx_vi_fb_tx_mux_text, mi2s_rx_vi_fb_tx_value); + +static const struct soc_enum int4_mi2s_rx_vi_fb_mono_ch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_INT4_MI2S_RX, 0, 0, + ARRAY_SIZE(int4_mi2s_rx_vi_fb_tx_mono_mux_text), + int4_mi2s_rx_vi_fb_tx_mono_mux_text, + int4_mi2s_rx_vi_fb_tx_mono_ch_value); + +static const struct soc_enum int4_mi2s_rx_vi_fb_stereo_ch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_INT4_MI2S_RX, 0, 0, + ARRAY_SIZE(int4_mi2s_rx_vi_fb_tx_stereo_mux_text), + int4_mi2s_rx_vi_fb_tx_stereo_mux_text, + int4_mi2s_rx_vi_fb_tx_stereo_ch_value); + +static const struct snd_kcontrol_new slim0_rx_vi_fb_lch_mux = + SOC_DAPM_ENUM_EXT("SLIM0_RX_VI_FB_LCH_MUX", + slim0_rx_vi_fb_lch_mux_enum, spkr_prot_get_vi_lch_port, + spkr_prot_put_vi_lch_port); + +static const struct snd_kcontrol_new slim0_rx_vi_fb_rch_mux = + SOC_DAPM_ENUM_EXT("SLIM0_RX_VI_FB_RCH_MUX", + slim0_rx_vi_fb_rch_mux_enum, spkr_prot_get_vi_rch_port, + spkr_prot_put_vi_rch_port); + +static const struct snd_kcontrol_new wsa_rx_0_vi_fb_lch_mux = + SOC_DAPM_ENUM_EXT("WSA_RX_0_VI_FB_LCH_MUX", + wsa_rx_0_vi_fb_lch_mux_enum, spkr_prot_get_vi_lch_port, + spkr_prot_put_vi_lch_port); + +static const struct snd_kcontrol_new wsa_rx_0_vi_fb_rch_mux = + SOC_DAPM_ENUM_EXT("WSA_RX_0_VI_FB_RCH_MUX", + wsa_rx_0_vi_fb_rch_mux_enum, spkr_prot_get_vi_rch_port, + spkr_prot_put_vi_rch_port); + +static const struct snd_kcontrol_new mi2s_rx_vi_fb_mux = + SOC_DAPM_ENUM_EXT("PRI_MI2S_RX_VI_FB_MUX", + mi2s_rx_vi_fb_mux_enum, spkr_prot_get_vi_lch_port, + spkr_prot_put_vi_lch_port); + +static const struct snd_kcontrol_new int4_mi2s_rx_vi_fb_mono_ch_mux = + SOC_DAPM_ENUM_EXT("INT4_MI2S_RX_VI_FB_MONO_CH_MUX", + int4_mi2s_rx_vi_fb_mono_ch_mux_enum, spkr_prot_get_vi_lch_port, + spkr_prot_put_vi_lch_port); + +static const struct snd_kcontrol_new int4_mi2s_rx_vi_fb_stereo_ch_mux = + SOC_DAPM_ENUM_EXT("INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", + int4_mi2s_rx_vi_fb_stereo_ch_mux_enum, spkr_prot_get_vi_rch_port, + spkr_prot_put_vi_rch_port); + +static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { + /* Frontend AIF */ + /* Widget name equals to Front-End DAI name, + * Stream name must contains substring of front-end dai name + */ + SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL5", "MultiMedia5 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL6", "MultiMedia6 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL7", "MultiMedia7 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL8", "MultiMedia8 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL9", "MultiMedia9 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL10", "MultiMedia10 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL11", "MultiMedia11 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL12", "MultiMedia12 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL13", "MultiMedia13 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL14", "MultiMedia14 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL15", "MultiMedia15 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL16", "MultiMedia16 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL20", "MultiMedia20 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL21", "MultiMedia21 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL22", "MultiMedia22 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL23", "MultiMedia23 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL24", "MultiMedia24 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL25", "MultiMedia25 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL26", "MultiMedia26 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL3", "MultiMedia3 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL4", "MultiMedia4 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL5", "MultiMedia5 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL9", "MultiMedia9 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL10", "MultiMedia10 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL16", "MultiMedia16 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL17", "MultiMedia17 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL18", "MultiMedia18 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL19", "MultiMedia19 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL20", "MultiMedia20 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL21", "MultiMedia21 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL22", "MultiMedia22 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL23", "MultiMedia23 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL24", "MultiMedia24 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL25", "MultiMedia25 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL27", "MultiMedia27 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL28", "MultiMedia28 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL29", "MultiMedia29 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL30", "MultiMedia30 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOICEMMODE1_DL", + "VoiceMMode1 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICEMMODE1_UL", + "VoiceMMode1 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOICEMMODE2_DL", + "VoiceMMode2 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICEMMODE2_UL", + "VoiceMMode2 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM0_DL_HL", "SLIMBUS0_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM0_UL_HL", "SLIMBUS0_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("CDC_DMA_DL_HL", "CDC_DMA_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("CDC_DMA_UL_HL", "CDC_DMA_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TX3_CDC_DMA_UL_HL", + "TX3_CDC_DMA_HOSTLESS Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("CPE_LSM_UL_HL", "CPE LSM capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM1_DL_HL", "SLIMBUS1_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM1_UL_HL", "SLIMBUS1_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM3_DL_HL", "SLIMBUS3_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM3_UL_HL", "SLIMBUS3_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM4_DL_HL", "SLIMBUS4_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM4_UL_HL", "SLIMBUS4_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM6_DL_HL", "SLIMBUS6_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM6_UL_HL", "SLIMBUS6_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM7_DL_HL", "SLIMBUS7_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM7_UL_HL", "SLIMBUS7_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM8_DL_HL", "SLIMBUS8_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM8_UL_HL", "SLIMBUS8_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INTFM_DL_HL", "INT_FM_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INTHFP_DL_HL", "INT_HFP_BT_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INTHFP_UL_HL", "INT_HFP_BT_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("USBAUDIO_DL_HL", "USBAUDIO_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("USBAUDIO_UL_HL", "USBAUDIO_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("HDMI_DL_HL", "HDMI_HOSTLESS Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("DTMF_DL_HL", "DTMF_RX_HOSTLESS Playback", + 0, 0, 0, 0), + /* LSM */ + SND_SOC_DAPM_AIF_OUT("LSM1_UL_HL", "Listen 1 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM2_UL_HL", "Listen 2 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM3_UL_HL", "Listen 3 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM4_UL_HL", "Listen 4 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM5_UL_HL", "Listen 5 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM6_UL_HL", "Listen 6 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM7_UL_HL", "Listen 7 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM8_UL_HL", "Listen 8 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QCHAT_DL", "QCHAT Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QCHAT_UL", "QCHAT Capture", 0, 0, 0, 0), + /* Backend AIF */ + /* Stream name equals to backend dai link stream name */ + SND_SOC_DAPM_AIF_OUT("PRI_SPDIF_RX", "Primary SPDIF Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_SPDIF_TX", "Primary SPDIF Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_SPDIF_RX", "Secondary SPDIF Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_SPDIF_TX", "Secondary SPDIF Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_RX", "Slimbus2 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_RX", "Slimbus5 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("HDMI_MS", "HDMI MS Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT", "Display Port Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT1", "Display Port1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_5", "Senary TDM5 Playback", + SND_SOC_DAPM_AIF_IN("INT_BT_SCO_TX", "Internal BT-SCO Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_5", "Senary TDM5 Capture", + SND_SOC_DAPM_AIF_OUT("INT_BT_A2DP_RX", "Internal BT-A2DP Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_6", "Senary TDM6 Playback", + SND_SOC_DAPM_AIF_OUT("INT_FM_RX", "Internal FM Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_6", "Senary TDM6 Capture", + SND_SOC_DAPM_AIF_IN("INT_FM_TX", "Internal FM Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_7", "Senary TDM7 Playback", + SND_SOC_DAPM_AIF_OUT("PCM_RX", "AFE Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_7", "Senary TDM7 Capture", + SND_SOC_DAPM_AIF_IN("PCM_TX", "AFE Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_META_MI2S_RX", "Primary META MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_META_MI2S_RX", "Secondary META MI2S Playback", - 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("WSA_CDC_DMA_RX_0", "WSA CDC DMA0 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("WSA_CDC_DMA_TX_0", "WSA CDC DMA0 Capture", @@ -24563,24 +24154,412 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("RX_CDC_DMA_RX_7", "RX CDC DMA7 Playback", 0, 0, 0, 0), /* incall */ - SND_SOC_DAPM_AIF_OUT("VOICE_PLAYBACK_TX", "Voice Farend Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VOICE2_PLAYBACK_TX", "Voice2 Farend Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_4_RX", "Slimbus4 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INCALL_RECORD_TX", "Voice Uplink Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INCALL_RECORD_RX", "Voice Downlink Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_4_TX", "Slimbus4 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SENARY_TX", "Senary_mi2s Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INT5_MI2S_TX", "INT5 MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_5_TX", "Slimbus5 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICE_PLAYBACK_TX", "Voice Farend Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICE2_PLAYBACK_TX", "Voice2 Farend Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_4_RX", "Slimbus4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INCALL_RECORD_TX", "Voice Uplink Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INCALL_RECORD_RX", "Voice Downlink Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_2_TX", "Slimbus2 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_4_TX", "Slimbus4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_5_TX", "Slimbus5 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOICE_STUB_DL", "VOICE_STUB Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICE_STUB_UL", "VOICE_STUB Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOICE2_STUB_DL", "VOICE2_STUB Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICE2_STUB_UL", "VOICE2_STUB Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOLTE_STUB_DL", "VOLTE_STUB Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOLTE_STUB_UL", "VOLTE_STUB Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("STUB_RX", "Stub Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("STUB_TX", "Stub Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_RX", "Slimbus1 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_1_TX", "Slimbus1 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("STUB_1_TX", "Stub1 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_3_RX", "Slimbus3 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_3_TX", "Slimbus3 Capture", 0, 0, 0, 0), + /* In- call recording */ + SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_RX", "Slimbus6 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_6_TX", "Slimbus6 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("AFE_LOOPBACK_TX", "AFE Loopback Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_7_RX", "Slimbus7 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_7_TX", "Slimbus7 Capture", 0, 0, 0, 0), + + SND_SOC_DAPM_AIF_OUT("SLIMBUS_8_RX", "Slimbus8 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_8_TX", "Slimbus8 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_9_RX", "Slimbus9 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_9_TX", "Slimbus9 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("USB_AUDIO_RX", "USB Audio Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("USB_AUDIO_TX", "USB Audio Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PROXY_RX", "Proxy Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PROXY_TX", "Proxy Capture", 0, 0, 0, 0), + + /* Switch Definitions */ + SND_SOC_DAPM_SWITCH("SLIMBUS_DL_HL", SND_SOC_NOPM, 0, 0, + &slim_fm_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SLIMBUS1_DL_HL", SND_SOC_NOPM, 0, 0, + &slim1_fm_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SLIMBUS3_DL_HL", SND_SOC_NOPM, 0, 0, + &slim3_fm_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SLIMBUS4_DL_HL", SND_SOC_NOPM, 0, 0, + &slim4_fm_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SLIMBUS6_DL_HL", SND_SOC_NOPM, 0, 0, + &slim6_fm_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("PCM_RX_DL_HL", SND_SOC_NOPM, 0, 0, + &pcm_rx_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SCO_SLIM7_DL_HL", SND_SOC_NOPM, 0, 0, + &sco_slim7_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("HFP_PRI_AUX_UL_HL", SND_SOC_NOPM, 0, 0, + &hfp_pri_aux_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("HFP_AUX_UL_HL", SND_SOC_NOPM, 0, 0, + &hfp_aux_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("HFP_INT_UL_HL", SND_SOC_NOPM, 0, 0, + &hfp_int_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("HFP_SLIM7_UL_HL", SND_SOC_NOPM, 0, 0, + &hfp_slim7_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("USB_DL_HL", SND_SOC_NOPM, 0, 0, + &usb_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("A2DP_SLIM7_UL_HL", SND_SOC_NOPM, 0, 0, + &a2dp_slim7_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("WSA_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, + &cdc_dma_wsa_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("RX_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, + &cdc_dma_rx_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("RX_CDC_DMA_RX_1_DL_HL", SND_SOC_NOPM, 0, 0, + &cdc_dma_rx_1_switch_mixer_controls), + + /* Mixer definitions */ + SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_2_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_2_rx_mixer_controls, ARRAY_SIZE(slimbus_2_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_5_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_5_rx_mixer_controls, ARRAY_SIZE(slimbus_5_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_7_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_7_rx_mixer_controls, ARRAY_SIZE(slimbus_7_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_9_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_9_rx_mixer_controls, ARRAY_SIZE(slimbus_9_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0, + hdmi_mixer_controls, ARRAY_SIZE(hdmi_mixer_controls)), + SND_SOC_DAPM_MIXER("HDMI_MS Mixer", SND_SOC_NOPM, 0, 0, + hdmi_ms_mixer_controls, ARRAY_SIZE(hdmi_ms_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT Mixer", SND_SOC_NOPM, 0, 0, + display_port_mixer_controls, ARRAY_SIZE(display_port_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT1 Mixer", SND_SOC_NOPM, 0, 0, + display_port1_mixer_controls, ARRAY_SIZE(display_port1_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_SPDIF_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_spdif_rx_mixer_controls, ARRAY_SIZE(pri_spdif_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_SPDIF_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_spdif_rx_mixer_controls, ARRAY_SIZE(sec_spdif_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + wsa_cdc_dma_rx_0_mixer_controls, + ARRAY_SIZE(wsa_cdc_dma_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + wsa_cdc_dma_rx_1_mixer_controls, + ARRAY_SIZE(wsa_cdc_dma_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_0_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_1_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_2_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_3_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_4_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_4_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_5 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_5_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_5_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_6 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_6_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_6_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_7 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_7_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_7_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0, + mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0, + mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia3 Mixer", SND_SOC_NOPM, 0, 0, + mmul3_mixer_controls, ARRAY_SIZE(mmul3_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia4 Mixer", SND_SOC_NOPM, 0, 0, + mmul4_mixer_controls, ARRAY_SIZE(mmul4_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia5 Mixer", SND_SOC_NOPM, 0, 0, + mmul5_mixer_controls, ARRAY_SIZE(mmul5_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia6 Mixer", SND_SOC_NOPM, 0, 0, + mmul6_mixer_controls, ARRAY_SIZE(mmul6_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia8 Mixer", SND_SOC_NOPM, 0, 0, + mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia9 Mixer", SND_SOC_NOPM, 0, 0, + mmul9_mixer_controls, ARRAY_SIZE(mmul9_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia10 Mixer", SND_SOC_NOPM, 0, 0, + mmul10_mixer_controls, ARRAY_SIZE(mmul10_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia16 Mixer", SND_SOC_NOPM, 0, 0, + mmul16_mixer_controls, ARRAY_SIZE(mmul16_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia17 Mixer", SND_SOC_NOPM, 0, 0, + mmul17_mixer_controls, ARRAY_SIZE(mmul17_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia18 Mixer", SND_SOC_NOPM, 0, 0, + mmul18_mixer_controls, ARRAY_SIZE(mmul18_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia19 Mixer", SND_SOC_NOPM, 0, 0, + mmul19_mixer_controls, ARRAY_SIZE(mmul19_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia20 Mixer", SND_SOC_NOPM, 0, 0, + mmul20_mixer_controls, ARRAY_SIZE(mmul20_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia21 Mixer", SND_SOC_NOPM, 0, 0, + mmul21_mixer_controls, ARRAY_SIZE(mmul21_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia22 Mixer", SND_SOC_NOPM, 0, 0, + mmul22_mixer_controls, ARRAY_SIZE(mmul22_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia23 Mixer", SND_SOC_NOPM, 0, 0, + mmul23_mixer_controls, ARRAY_SIZE(mmul23_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia24 Mixer", SND_SOC_NOPM, 0, 0, + mmul24_mixer_controls, ARRAY_SIZE(mmul24_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia25 Mixer", SND_SOC_NOPM, 0, 0, + mmul25_mixer_controls, ARRAY_SIZE(mmul25_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia27 Mixer", SND_SOC_NOPM, 0, 0, + mmul27_mixer_controls, ARRAY_SIZE(mmul27_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia28 Mixer", SND_SOC_NOPM, 0, 0, + mmul28_mixer_controls, ARRAY_SIZE(mmul28_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia29 Mixer", SND_SOC_NOPM, 0, 0, + mmul29_mixer_controls, ARRAY_SIZE(mmul29_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia30 Mixer", SND_SOC_NOPM, 0, 0, + mmul30_mixer_controls, ARRAY_SIZE(mmul30_mixer_controls)), + /* incall */ + SND_SOC_DAPM_MIXER("Incall_Music Audio Mixer", SND_SOC_NOPM, 0, 0, + incall_music_delivery_mixer_controls, + ARRAY_SIZE(incall_music_delivery_mixer_controls)), + SND_SOC_DAPM_MIXER("Incall_Music_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + incall_music2_delivery_mixer_controls, + ARRAY_SIZE(incall_music2_delivery_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_4_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_4_rx_mixer_controls, + ARRAY_SIZE(slimbus_4_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_6_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_6_rx_mixer_controls, + ARRAY_SIZE(slimbus_6_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("USB_AUDIO_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + usb_audio_rx_mixer_controls, + ARRAY_SIZE(usb_audio_rx_mixer_controls)), + /* Voice Mixer */ + SND_SOC_DAPM_MIXER("SLIM_0_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + slimbus_rx_voice_mixer_controls, + ARRAY_SIZE(slimbus_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + bt_sco_rx_voice_mixer_controls, + ARRAY_SIZE(bt_sco_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("AFE_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + afe_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(afe_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("HDMI_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + hdmi_rx_voice_mixer_controls, + ARRAY_SIZE(hdmi_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0_Voice Mixer", + SND_SOC_NOPM, 0, 0, + wsa_cdc_dma_rx_0_voice_mixer_controls, + ARRAY_SIZE(wsa_cdc_dma_rx_0_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("PROXY_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + proxy_rx_voice_mixer_controls, + ARRAY_SIZE(proxy_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0_Voice Mixer", + SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_0_voice_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_0_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_1_Voice Mixer", + SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_1_voice_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_1_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("Voip_Tx Mixer", + SND_SOC_NOPM, 0, 0, tx_voip_mixer_controls, + ARRAY_SIZE(tx_voip_mixer_controls)), + SND_SOC_DAPM_MIXER("VoiceMMode1_Tx Mixer", + SND_SOC_NOPM, 0, 0, tx_voicemmode1_mixer_controls, + ARRAY_SIZE(tx_voicemmode1_mixer_controls)), + SND_SOC_DAPM_MIXER("VoiceMMode2_Tx Mixer", + SND_SOC_NOPM, 0, 0, tx_voicemmode2_mixer_controls, + ARRAY_SIZE(tx_voicemmode2_mixer_controls)), + SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + int_bt_sco_rx_mixer_controls, ARRAY_SIZE(int_bt_sco_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("INTERNAL_A2DP_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + int_bt_a2dp_rx_mixer_controls, + ARRAY_SIZE(int_bt_a2dp_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("INTERNAL_FM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + int_fm_rx_mixer_controls, ARRAY_SIZE(int_fm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("AFE_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + afe_pcm_rx_mixer_controls, ARRAY_SIZE(afe_pcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("Voice Stub Tx Mixer", SND_SOC_NOPM, 0, 0, + tx_voice_stub_mixer_controls, ARRAY_SIZE(tx_voice_stub_mixer_controls)), + SND_SOC_DAPM_MIXER("Voice2 Stub Tx Mixer", SND_SOC_NOPM, 0, 0, + tx_voice2_stub_mixer_controls, + ARRAY_SIZE(tx_voice2_stub_mixer_controls)), + SND_SOC_DAPM_MIXER("VoLTE Stub Tx Mixer", SND_SOC_NOPM, 0, 0, + tx_volte_stub_mixer_controls, ARRAY_SIZE(tx_volte_stub_mixer_controls)), + SND_SOC_DAPM_MIXER("STUB_RX Mixer", SND_SOC_NOPM, 0, 0, + stub_rx_mixer_controls, ARRAY_SIZE(stub_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Mixer", SND_SOC_NOPM, 0, 0, + slimbus_1_rx_mixer_controls, ARRAY_SIZE(slimbus_1_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_3_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, + slimbus_3_rx_mixer_controls, ARRAY_SIZE(slimbus_3_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIM_6_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + slimbus_6_rx_voice_mixer_controls, + ARRAY_SIZE(slimbus_6_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIM_7_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, + slimbus_7_rx_voice_mixer_controls, + ARRAY_SIZE(slimbus_7_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIM_8_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, + slimbus_8_rx_voice_mixer_controls, + ARRAY_SIZE(slimbus_8_rx_voice_mixer_controls)), + /* port mixer */ + SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Port Mixer", + SND_SOC_NOPM, 0, 0, sbus_0_rx_port_mixer_controls, + ARRAY_SIZE(sbus_0_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Port Mixer", SND_SOC_NOPM, 0, 0, + sbus_1_rx_port_mixer_controls, + ARRAY_SIZE(sbus_1_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Port Mixer", SND_SOC_NOPM, 0, 0, + bt_sco_rx_port_mixer_controls, + ARRAY_SIZE(bt_sco_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("AFE_PCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, afe_pcm_rx_port_mixer_controls, + ARRAY_SIZE(afe_pcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("HDMI_RX Port Mixer", + SND_SOC_NOPM, 0, 0, hdmi_rx_port_mixer_controls, + ARRAY_SIZE(hdmi_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("HDMI_RX_MS Port Mixer", + SND_SOC_NOPM, 0, 0, hdmi_rx_ms_port_mixer_controls, + ARRAY_SIZE(hdmi_rx_ms_port_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX Port Mixer", + SND_SOC_NOPM, 0, 0, display_port_rx_port_mixer_controls, + ARRAY_SIZE(display_port_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX1 Port Mixer", + SND_SOC_NOPM, 0, 0, display_port_rx1_port_mixer_controls, + ARRAY_SIZE(display_port_rx1_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_3_RX Port Mixer", + SND_SOC_NOPM, 0, 0, sbus_3_rx_port_mixer_controls, + ARRAY_SIZE(sbus_3_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_6_RX Port Mixer", + SND_SOC_NOPM, 0, 0, sbus_6_rx_port_mixer_controls, + ARRAY_SIZE(sbus_6_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, + wsa_cdc_dma_rx_0_port_mixer_controls, + ARRAY_SIZE(wsa_cdc_dma_rx_0_port_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_0_port_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_0_port_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_1 Port Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_1_port_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_1_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QCHAT_Tx Mixer", + SND_SOC_NOPM, 0, 0, tx_qchat_mixer_controls, + ARRAY_SIZE(tx_qchat_mixer_controls)), + SND_SOC_DAPM_MIXER("USB_AUDIO_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, usb_audio_rx_voice_mixer_controls, + ARRAY_SIZE(usb_audio_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("USB_AUDIO_RX Port Mixer", + SND_SOC_NOPM, 0, 0, usb_rx_port_mixer_controls, + ARRAY_SIZE(usb_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, display_port_rx_voice_mixer_controls, + ARRAY_SIZE(display_port_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX1_Voice Mixer", + SND_SOC_NOPM, 0, 0, display_port_rx1_voice_mixer_controls, + ARRAY_SIZE(display_port_rx1_voice_mixer_controls)), + /* lsm mixer definitions */ + SND_SOC_DAPM_MIXER("LSM1 Mixer", SND_SOC_NOPM, 0, 0, + lsm1_mixer_controls, ARRAY_SIZE(lsm1_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM2 Mixer", SND_SOC_NOPM, 0, 0, + lsm2_mixer_controls, ARRAY_SIZE(lsm2_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM3 Mixer", SND_SOC_NOPM, 0, 0, + lsm3_mixer_controls, ARRAY_SIZE(lsm3_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM4 Mixer", SND_SOC_NOPM, 0, 0, + lsm4_mixer_controls, ARRAY_SIZE(lsm4_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM5 Mixer", SND_SOC_NOPM, 0, 0, + lsm5_mixer_controls, ARRAY_SIZE(lsm5_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM6 Mixer", SND_SOC_NOPM, 0, 0, + lsm6_mixer_controls, ARRAY_SIZE(lsm6_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM7 Mixer", SND_SOC_NOPM, 0, 0, + lsm7_mixer_controls, ARRAY_SIZE(lsm7_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM8 Mixer", SND_SOC_NOPM, 0, 0, + lsm8_mixer_controls, ARRAY_SIZE(lsm8_mixer_controls)), + /* Virtual Pins to force backends ON atm */ + SND_SOC_DAPM_OUTPUT("BE_OUT"), + SND_SOC_DAPM_INPUT("BE_IN"), + + SND_SOC_DAPM_MUX("SLIM0_RX_VI_FB_LCH_MUX", SND_SOC_NOPM, 0, 0, + &slim0_rx_vi_fb_lch_mux), + SND_SOC_DAPM_MUX("SLIM0_RX_VI_FB_RCH_MUX", SND_SOC_NOPM, 0, 0, + &slim0_rx_vi_fb_rch_mux), + SND_SOC_DAPM_MUX("WSA_RX_0_VI_FB_LCH_MUX", SND_SOC_NOPM, 0, 0, + &wsa_rx_0_vi_fb_lch_mux), + SND_SOC_DAPM_MUX("WSA_RX_0_VI_FB_RCH_MUX", SND_SOC_NOPM, 0, 0, + &wsa_rx_0_vi_fb_rch_mux), + SND_SOC_DAPM_MUX("VOC_EXT_EC MUX", SND_SOC_NOPM, 0, 0, + &voc_ext_ec_mux), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL1 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul1), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL2 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul2), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL3 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul3), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL4 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul4), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL5 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul5), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL6 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul6), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL8 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul8), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL9 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul9), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL10 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul10), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL16 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul16), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL17 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul17), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL18 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul18), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL19 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul19), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL28 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul28), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL29 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul29), +}; +#ifndef CONFIG_AUXPCM_DISABLE +static const struct snd_soc_dapm_widget msm_qdsp6_widgets_aux_pcm[] = { + /* Frontend AIF */ + /* Widget name equals to Front-End DAI name, + * Stream name must contains substring of front-end dai name + */ + SND_SOC_DAPM_AIF_IN("AUXPCM_DL_HL", "AUXPCM_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("AUXPCM_UL_HL", "AUXPCM_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_AUXPCM_DL_HL", "SEC_AUXPCM_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_AUXPCM_UL_HL", "SEC_AUXPCM_HOSTLESS Capture", + 0, 0, 0, 0), + /* LSM */ + /* Backend AIF */ + /* Stream name equals to backend dai link stream name */ + /* incall */ SND_SOC_DAPM_AIF_OUT("AUX_PCM_RX", "AUX PCM Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("AUX_PCM_TX", "AUX PCM Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("SEC_AUX_PCM_RX", "Sec AUX PCM Playback", @@ -24603,51 +24582,199 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("SEN_AUX_PCM_TX", "Sen AUX PCM Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("VOICE_STUB_DL", "VOICE_STUB Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VOICE_STUB_UL", "VOICE_STUB Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("VOICE2_STUB_DL", "VOICE2_STUB Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VOICE2_STUB_UL", "VOICE2_STUB Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("VOLTE_STUB_DL", "VOLTE_STUB Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VOLTE_STUB_UL", "VOLTE_STUB Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("STUB_RX", "Stub Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("STUB_TX", "Stub Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_RX", "Slimbus1 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_1_TX", "Slimbus1 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("STUB_1_TX", "Stub1 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_3_RX", "Slimbus3 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_3_TX", "Slimbus3 Capture", 0, 0, 0, 0), /* In- call recording */ - SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_RX", "Slimbus6 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_6_TX", "Slimbus6 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("AFE_LOOPBACK_TX", "AFE Loopback Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_7_RX", "Slimbus7 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_7_TX", "Slimbus7 Capture", 0, 0, 0, 0), - - SND_SOC_DAPM_AIF_OUT("SLIMBUS_8_RX", "Slimbus8 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_8_TX", "Slimbus8 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_9_RX", "Slimbus9 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_9_TX", "Slimbus9 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("USB_AUDIO_RX", "USB Audio Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("USB_AUDIO_TX", "USB Audio Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PROXY_RX", "Proxy Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PROXY_TX", "Proxy Capture", 0, 0, 0, 0), /* Switch Definitions */ - SND_SOC_DAPM_SWITCH("SLIMBUS_DL_HL", SND_SOC_NOPM, 0, 0, - &slim_fm_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("SLIMBUS1_DL_HL", SND_SOC_NOPM, 0, 0, - &slim1_fm_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("SLIMBUS3_DL_HL", SND_SOC_NOPM, 0, 0, - &slim3_fm_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("SLIMBUS4_DL_HL", SND_SOC_NOPM, 0, 0, - &slim4_fm_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("SLIMBUS6_DL_HL", SND_SOC_NOPM, 0, 0, - &slim6_fm_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("PCM_RX_DL_HL", SND_SOC_NOPM, 0, 0, - &pcm_rx_switch_mixer_controls), + + /* Mixer definitions */ + SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_auxpcm_rx_mixer_controls, ARRAY_SIZE(sec_auxpcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_auxpcm_rx_mixer_controls, + ARRAY_SIZE(tert_auxpcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_auxpcm_rx_mixer_controls, + ARRAY_SIZE(quat_auxpcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_auxpcm_rx_mixer_controls, + ARRAY_SIZE(quin_auxpcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_auxpcm_rx_mixer_controls, + ARRAY_SIZE(sen_auxpcm_rx_mixer_controls)), + /* incall */ + /* Voice Mixer */ + SND_SOC_DAPM_MIXER("AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(aux_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + sec_aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(sec_aux_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + tert_aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(tert_aux_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + quat_aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(quat_aux_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + quin_aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(quin_aux_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + sen_aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(sen_aux_pcm_rx_voice_mixer_controls)), + /* port mixer */ + SND_SOC_DAPM_MIXER("AUX_PCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, aux_pcm_rx_port_mixer_controls, + ARRAY_SIZE(aux_pcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_AUXPCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, sec_auxpcm_rx_port_mixer_controls, + ARRAY_SIZE(sec_auxpcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_AUXPCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, tert_auxpcm_rx_port_mixer_controls, + ARRAY_SIZE(tert_auxpcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_AUXPCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, quat_auxpcm_rx_port_mixer_controls, + ARRAY_SIZE(quat_auxpcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_AUXPCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, quin_auxpcm_rx_port_mixer_controls, + ARRAY_SIZE(quin_auxpcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_AUXPCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, sen_auxpcm_rx_port_mixer_controls, + ARRAY_SIZE(sen_auxpcm_rx_port_mixer_controls)), +}; +#endif + +#ifndef CONFIG_MI2S_DISABLE +static const struct snd_soc_dapm_widget msm_qdsp6_widgets_mi2s[] = { + /* Frontend AIF */ + /* Widget name equals to Front-End DAI name, + * Stream name must contains substring of front-end dai name + */ + SND_SOC_DAPM_AIF_IN("SEC_I2S_DL_HL", "SEC_I2S_RX_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT0_MI2S_DL_HL", + "INT0 MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT4_MI2S_DL_HL", + "INT4 MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_MI2S_DL_HL", + "Primary MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_MI2S_DL_HL", + "Secondary MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_MI2S_DL_HL", + "Tertiary MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_MI2S_DL_HL", + "Quaternary MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_MI2S_DL_HL", + "Quinary MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_MI2S_DL_HL", + "Senary MI2S_RX Hostless Playback", + 0, 0, 0, 0), + + SND_SOC_DAPM_AIF_OUT("MI2S_UL_HL", "MI2S_TX_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT3_MI2S_UL_HL", + "INT3 MI2S_TX Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_MI2S_UL_HL", + "Tertiary MI2S_TX Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_MI2S_UL_HL", + "Secondary MI2S_TX Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_MI2S_UL_HL", + "Primary MI2S_TX Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MI2S_DL_HL", "MI2S_RX_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_UL_HL", + "Quaternary MI2S_TX Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_MI2S_UL_HL", + "Quinary MI2S_TX Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_MI2S_UL_HL", + "Senary MI2S_TX Hostless Capture", + 0, 0, 0, 0), + + /* Backend AIF */ + /* Stream name equals to backend dai link stream name */ + SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_I2S_RX", "Secondary I2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX", "Quaternary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX", "Tertiary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX", "Secondary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_SD1", + "Secondary MI2S Playback SD1", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_MI2S_RX", "Primary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT0_MI2S_RX", "INT0 MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT2_MI2S_RX", "INT2 MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT3_MI2S_RX", "INT3 MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT5_MI2S_RX", "INT5 MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT4_MI2S_RX", "INT4 MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT4_MI2S_TX", "INT4 MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_MI2S_RX", "Quinary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_MI2S_RX", "Senary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MI2S_TX", "MI2S Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX", "Quaternary MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_MI2S_TX", "Primary MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX", "Tertiary MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT0_MI2S_TX", "INT0 MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT2_MI2S_TX", "INT2 MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT3_MI2S_TX", "INT3 MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX", "Secondary MI2S Capture", + 0, 0, 0, 0), + + SND_SOC_DAPM_AIF_IN("QUIN_MI2S_TX", "Quinary MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SENARY_MI2S_TX", "Senary MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_META_MI2S_RX", "Primary META MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_META_MI2S_RX", "Secondary META MI2S Playback", + 0, 0, 0, 0), + /* incall */ + SND_SOC_DAPM_AIF_IN("SENARY_TX", "Senary_mi2s Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT5_MI2S_TX", "INT5 MI2S Capture", + 0, 0, 0, 0), + /* In- call recording */ + /* Switch Definitions */ SND_SOC_DAPM_SWITCH("INT0_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, &int0_mi2s_rx_switch_mixer_controls), SND_SOC_DAPM_SWITCH("INT4_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, @@ -24662,56 +24789,14 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &quat_mi2s_rx_switch_mixer_controls), SND_SOC_DAPM_SWITCH("QUIN_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, &quin_mi2s_rx_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("SCO_SLIM7_DL_HL", SND_SOC_NOPM, 0, 0, - &sco_slim7_switch_mixer_controls), SND_SOC_DAPM_SWITCH("SEN_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, &sen_mi2s_rx_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("HFP_PRI_AUX_UL_HL", SND_SOC_NOPM, 0, 0, - &hfp_pri_aux_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("HFP_AUX_UL_HL", SND_SOC_NOPM, 0, 0, - &hfp_aux_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("HFP_INT_UL_HL", SND_SOC_NOPM, 0, 0, - &hfp_int_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("HFP_SLIM7_UL_HL", SND_SOC_NOPM, 0, 0, - &hfp_slim7_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("USB_DL_HL", SND_SOC_NOPM, 0, 0, - &usb_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("A2DP_SLIM7_UL_HL", SND_SOC_NOPM, 0, 0, - &a2dp_slim7_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("WSA_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, - &cdc_dma_wsa_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("RX_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, - &cdc_dma_rx_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("RX_CDC_DMA_RX_1_DL_HL", SND_SOC_NOPM, 0, 0, - &cdc_dma_rx_1_switch_mixer_controls), /* Mixer definitions */ SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0, pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)), SND_SOC_DAPM_MIXER("SEC_RX Audio Mixer", SND_SOC_NOPM, 0, 0, sec_i2s_rx_mixer_controls, ARRAY_SIZE(sec_i2s_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_2_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - slimbus_2_rx_mixer_controls, ARRAY_SIZE(slimbus_2_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_5_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - slimbus_5_rx_mixer_controls, ARRAY_SIZE(slimbus_5_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_7_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - slimbus_7_rx_mixer_controls, ARRAY_SIZE(slimbus_7_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_9_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - slimbus_9_rx_mixer_controls, ARRAY_SIZE(slimbus_9_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0, - hdmi_mixer_controls, ARRAY_SIZE(hdmi_mixer_controls)), - SND_SOC_DAPM_MIXER("HDMI_MS Mixer", SND_SOC_NOPM, 0, 0, - hdmi_ms_mixer_controls, ARRAY_SIZE(hdmi_ms_mixer_controls)), - SND_SOC_DAPM_MIXER("DISPLAY_PORT Mixer", SND_SOC_NOPM, 0, 0, - display_port_mixer_controls, ARRAY_SIZE(display_port_mixer_controls)), - SND_SOC_DAPM_MIXER("DISPLAY_PORT1 Mixer", SND_SOC_NOPM, 0, 0, - display_port1_mixer_controls, ARRAY_SIZE(display_port1_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_SPDIF_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - pri_spdif_rx_mixer_controls, ARRAY_SIZE(pri_spdif_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_SPDIF_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - sec_spdif_rx_mixer_controls, ARRAY_SIZE(sec_spdif_rx_mixer_controls)), SND_SOC_DAPM_MIXER("MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, mi2s_rx_mixer_controls, ARRAY_SIZE(mi2s_rx_mixer_controls)), SND_SOC_DAPM_MIXER("QUAT_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, @@ -24741,222 +24826,13 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("SEN_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, senary_mi2s_rx_mixer_controls, ARRAY_SIZE(senary_mi2s_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - pri_tdm_rx_0_mixer_controls, - ARRAY_SIZE(pri_tdm_rx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - pri_tdm_rx_1_mixer_controls, - ARRAY_SIZE(pri_tdm_rx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - pri_tdm_rx_2_mixer_controls, - ARRAY_SIZE(pri_tdm_rx_2_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, - pri_tdm_rx_3_mixer_controls, - ARRAY_SIZE(pri_tdm_rx_3_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - pri_tdm_tx_0_mixer_controls, - ARRAY_SIZE(pri_tdm_tx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - sec_tdm_rx_0_mixer_controls, - ARRAY_SIZE(sec_tdm_rx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - sec_tdm_rx_1_mixer_controls, - ARRAY_SIZE(sec_tdm_rx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - sec_tdm_rx_2_mixer_controls, - ARRAY_SIZE(sec_tdm_rx_2_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, - sec_tdm_rx_3_mixer_controls, - ARRAY_SIZE(sec_tdm_rx_3_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - sec_tdm_tx_0_mixer_controls, - ARRAY_SIZE(sec_tdm_tx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - tert_tdm_rx_0_mixer_controls, - ARRAY_SIZE(tert_tdm_rx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - tert_tdm_tx_0_mixer_controls, - ARRAY_SIZE(tert_tdm_tx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - tert_tdm_rx_1_mixer_controls, - ARRAY_SIZE(tert_tdm_rx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - tert_tdm_rx_2_mixer_controls, - ARRAY_SIZE(tert_tdm_rx_2_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, - tert_tdm_rx_3_mixer_controls, - ARRAY_SIZE(tert_tdm_rx_3_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_TDM_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0, - tert_tdm_rx_4_mixer_controls, - ARRAY_SIZE(tert_tdm_rx_4_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - quat_tdm_rx_0_mixer_controls, - ARRAY_SIZE(quat_tdm_rx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - quat_tdm_tx_0_mixer_controls, - ARRAY_SIZE(quat_tdm_tx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - quat_tdm_rx_1_mixer_controls, - ARRAY_SIZE(quat_tdm_rx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - quat_tdm_rx_2_mixer_controls, - ARRAY_SIZE(quat_tdm_rx_2_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, - quat_tdm_rx_3_mixer_controls, - ARRAY_SIZE(quat_tdm_rx_3_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_tdm_rx_0_mixer_controls, - ARRAY_SIZE(quin_tdm_rx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_tdm_tx_0_mixer_controls, - ARRAY_SIZE(quin_tdm_tx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_tdm_rx_1_mixer_controls, - ARRAY_SIZE(quin_tdm_rx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_TX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_tdm_tx_1_mixer_controls, - ARRAY_SIZE(quin_tdm_tx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_tdm_rx_2_mixer_controls, - ARRAY_SIZE(quin_tdm_rx_2_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_TX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_tdm_tx_2_mixer_controls, - ARRAY_SIZE(quin_tdm_tx_2_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_tdm_rx_3_mixer_controls, - ARRAY_SIZE(quin_tdm_rx_3_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_TX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_tdm_tx_3_mixer_controls, - ARRAY_SIZE(quin_tdm_tx_3_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - sen_tdm_tx_0_mixer_controls, - ARRAY_SIZE(sen_tdm_tx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - sen_tdm_rx_0_mixer_controls, - ARRAY_SIZE(sen_tdm_rx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - sen_tdm_rx_1_mixer_controls, - ARRAY_SIZE(sen_tdm_rx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - sen_tdm_rx_2_mixer_controls, - ARRAY_SIZE(sen_tdm_rx_2_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, - sen_tdm_rx_3_mixer_controls, - ARRAY_SIZE(sen_tdm_rx_3_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_META_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_MIXER("PRI_META_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, pri_meta_mi2s_rx_mixer_controls, - ARRAY_SIZE(pri_meta_mi2s_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_META_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - sec_meta_mi2s_rx_mixer_controls, - ARRAY_SIZE(sec_meta_mi2s_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - wsa_cdc_dma_rx_0_mixer_controls, - ARRAY_SIZE(wsa_cdc_dma_rx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - wsa_cdc_dma_rx_1_mixer_controls, - ARRAY_SIZE(wsa_cdc_dma_rx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_0_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_1_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_2_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_2_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_3_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_3_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_4_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_4_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_5 Audio Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_5_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_5_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_6 Audio Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_6_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_6_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_7 Audio Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_7_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_7_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0, - mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0, - mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia3 Mixer", SND_SOC_NOPM, 0, 0, - mmul3_mixer_controls, ARRAY_SIZE(mmul3_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia4 Mixer", SND_SOC_NOPM, 0, 0, - mmul4_mixer_controls, ARRAY_SIZE(mmul4_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia5 Mixer", SND_SOC_NOPM, 0, 0, - mmul5_mixer_controls, ARRAY_SIZE(mmul5_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia6 Mixer", SND_SOC_NOPM, 0, 0, - mmul6_mixer_controls, ARRAY_SIZE(mmul6_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia8 Mixer", SND_SOC_NOPM, 0, 0, - mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia9 Mixer", SND_SOC_NOPM, 0, 0, - mmul9_mixer_controls, ARRAY_SIZE(mmul9_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia10 Mixer", SND_SOC_NOPM, 0, 0, - mmul10_mixer_controls, ARRAY_SIZE(mmul10_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia16 Mixer", SND_SOC_NOPM, 0, 0, - mmul16_mixer_controls, ARRAY_SIZE(mmul16_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia17 Mixer", SND_SOC_NOPM, 0, 0, - mmul17_mixer_controls, ARRAY_SIZE(mmul17_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia18 Mixer", SND_SOC_NOPM, 0, 0, - mmul18_mixer_controls, ARRAY_SIZE(mmul18_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia19 Mixer", SND_SOC_NOPM, 0, 0, - mmul19_mixer_controls, ARRAY_SIZE(mmul19_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia20 Mixer", SND_SOC_NOPM, 0, 0, - mmul20_mixer_controls, ARRAY_SIZE(mmul20_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia21 Mixer", SND_SOC_NOPM, 0, 0, - mmul21_mixer_controls, ARRAY_SIZE(mmul21_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia22 Mixer", SND_SOC_NOPM, 0, 0, - mmul22_mixer_controls, ARRAY_SIZE(mmul22_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia23 Mixer", SND_SOC_NOPM, 0, 0, - mmul23_mixer_controls, ARRAY_SIZE(mmul23_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia24 Mixer", SND_SOC_NOPM, 0, 0, - mmul24_mixer_controls, ARRAY_SIZE(mmul24_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia25 Mixer", SND_SOC_NOPM, 0, 0, - mmul25_mixer_controls, ARRAY_SIZE(mmul25_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia27 Mixer", SND_SOC_NOPM, 0, 0, - mmul27_mixer_controls, ARRAY_SIZE(mmul27_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia28 Mixer", SND_SOC_NOPM, 0, 0, - mmul28_mixer_controls, ARRAY_SIZE(mmul28_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia29 Mixer", SND_SOC_NOPM, 0, 0, - mmul29_mixer_controls, ARRAY_SIZE(mmul29_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia30 Mixer", SND_SOC_NOPM, 0, 0, - mmul30_mixer_controls, ARRAY_SIZE(mmul30_mixer_controls)), - SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - sec_auxpcm_rx_mixer_controls, ARRAY_SIZE(sec_auxpcm_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - tert_auxpcm_rx_mixer_controls, - ARRAY_SIZE(tert_auxpcm_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - quat_auxpcm_rx_mixer_controls, - ARRAY_SIZE(quat_auxpcm_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_auxpcm_rx_mixer_controls, - ARRAY_SIZE(quin_auxpcm_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - sen_auxpcm_rx_mixer_controls, - ARRAY_SIZE(sen_auxpcm_rx_mixer_controls)), - /* incall */ - SND_SOC_DAPM_MIXER("Incall_Music Audio Mixer", SND_SOC_NOPM, 0, 0, - incall_music_delivery_mixer_controls, - ARRAY_SIZE(incall_music_delivery_mixer_controls)), - SND_SOC_DAPM_MIXER("Incall_Music_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - incall_music2_delivery_mixer_controls, - ARRAY_SIZE(incall_music2_delivery_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_4_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - slimbus_4_rx_mixer_controls, - ARRAY_SIZE(slimbus_4_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_6_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - slimbus_6_rx_mixer_controls, - ARRAY_SIZE(slimbus_6_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("USB_AUDIO_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - usb_audio_rx_mixer_controls, - ARRAY_SIZE(usb_audio_rx_mixer_controls)), + ARRAY_SIZE(pri_meta_mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_META_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_meta_mi2s_rx_mixer_controls, + ARRAY_SIZE(sec_meta_mi2s_rx_mixer_controls)), + /* incall */ /* Voice Mixer */ SND_SOC_DAPM_MIXER("PRI_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, pri_rx_voice_mixer_controls, @@ -24969,46 +24845,6 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_NOPM, 0, 0, sec_mi2s_rx_voice_mixer_controls, ARRAY_SIZE(sec_mi2s_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIM_0_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - slimbus_rx_voice_mixer_controls, - ARRAY_SIZE(slimbus_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - bt_sco_rx_voice_mixer_controls, - ARRAY_SIZE(bt_sco_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("AFE_PCM_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - afe_pcm_rx_voice_mixer_controls, - ARRAY_SIZE(afe_pcm_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("AUX_PCM_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - aux_pcm_rx_voice_mixer_controls, - ARRAY_SIZE(aux_pcm_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - sec_aux_pcm_rx_voice_mixer_controls, - ARRAY_SIZE(sec_aux_pcm_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_AUX_PCM_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - tert_aux_pcm_rx_voice_mixer_controls, - ARRAY_SIZE(tert_aux_pcm_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_AUX_PCM_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - quat_aux_pcm_rx_voice_mixer_controls, - ARRAY_SIZE(quat_aux_pcm_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_AUX_PCM_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - quin_aux_pcm_rx_voice_mixer_controls, - ARRAY_SIZE(quin_aux_pcm_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_AUX_PCM_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - sen_aux_pcm_rx_voice_mixer_controls, - ARRAY_SIZE(sen_aux_pcm_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("HDMI_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - hdmi_rx_voice_mixer_controls, - ARRAY_SIZE(hdmi_rx_voice_mixer_controls)), SND_SOC_DAPM_MIXER("MI2S_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, mi2s_rx_voice_mixer_controls, @@ -25037,143 +24873,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_NOPM, 0, 0, quin_mi2s_rx_voice_mixer_controls, ARRAY_SIZE(quin_mi2s_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_RX_0_Voice Mixer", - SND_SOC_NOPM, 0, 0, - pri_tdm_rx_0_voice_mixer_controls, - ARRAY_SIZE(pri_tdm_rx_0_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_RX_1_Voice Mixer", - SND_SOC_NOPM, 0, 0, - pri_tdm_rx_1_voice_mixer_controls, - ARRAY_SIZE(pri_tdm_rx_1_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_RX_2_Voice Mixer", - SND_SOC_NOPM, 0, 0, - pri_tdm_rx_2_voice_mixer_controls, - ARRAY_SIZE(pri_tdm_rx_2_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_RX_3_Voice Mixer", - SND_SOC_NOPM, 0, 0, - pri_tdm_rx_3_voice_mixer_controls, - ARRAY_SIZE(pri_tdm_rx_3_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_MI2S_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - sen_mi2s_rx_voice_mixer_controls, - ARRAY_SIZE(sen_mi2s_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_TDM_RX_2_Voice Mixer", - SND_SOC_NOPM, 0, 0, - quat_tdm_rx_2_voice_mixer_controls, - ARRAY_SIZE(quat_tdm_rx_2_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_RX_2_Voice Mixer", - SND_SOC_NOPM, 0, 0, - quin_tdm_rx_2_voice_mixer_controls, - ARRAY_SIZE(quin_tdm_rx_2_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0_Voice Mixer", - SND_SOC_NOPM, 0, 0, - wsa_cdc_dma_rx_0_voice_mixer_controls, - ARRAY_SIZE(wsa_cdc_dma_rx_0_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("PROXY_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - proxy_rx_voice_mixer_controls, - ARRAY_SIZE(proxy_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0_Voice Mixer", - SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_0_voice_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_0_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_1_Voice Mixer", - SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_1_voice_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_1_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("Voip_Tx Mixer", - SND_SOC_NOPM, 0, 0, tx_voip_mixer_controls, - ARRAY_SIZE(tx_voip_mixer_controls)), - SND_SOC_DAPM_MIXER("VoiceMMode1_Tx Mixer", - SND_SOC_NOPM, 0, 0, tx_voicemmode1_mixer_controls, - ARRAY_SIZE(tx_voicemmode1_mixer_controls)), - SND_SOC_DAPM_MIXER("VoiceMMode2_Tx Mixer", - SND_SOC_NOPM, 0, 0, tx_voicemmode2_mixer_controls, - ARRAY_SIZE(tx_voicemmode2_mixer_controls)), - SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - int_bt_sco_rx_mixer_controls, ARRAY_SIZE(int_bt_sco_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("INTERNAL_A2DP_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - int_bt_a2dp_rx_mixer_controls, - ARRAY_SIZE(int_bt_a2dp_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("INTERNAL_FM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - int_fm_rx_mixer_controls, ARRAY_SIZE(int_fm_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("AFE_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - afe_pcm_rx_mixer_controls, ARRAY_SIZE(afe_pcm_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("Voice Stub Tx Mixer", SND_SOC_NOPM, 0, 0, - tx_voice_stub_mixer_controls, ARRAY_SIZE(tx_voice_stub_mixer_controls)), - SND_SOC_DAPM_MIXER("Voice2 Stub Tx Mixer", SND_SOC_NOPM, 0, 0, - tx_voice2_stub_mixer_controls, - ARRAY_SIZE(tx_voice2_stub_mixer_controls)), - SND_SOC_DAPM_MIXER("VoLTE Stub Tx Mixer", SND_SOC_NOPM, 0, 0, - tx_volte_stub_mixer_controls, ARRAY_SIZE(tx_volte_stub_mixer_controls)), - SND_SOC_DAPM_MIXER("STUB_RX Mixer", SND_SOC_NOPM, 0, 0, - stub_rx_mixer_controls, ARRAY_SIZE(stub_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Mixer", SND_SOC_NOPM, 0, 0, - slimbus_1_rx_mixer_controls, ARRAY_SIZE(slimbus_1_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_3_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, - slimbus_3_rx_mixer_controls, ARRAY_SIZE(slimbus_3_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIM_6_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - slimbus_6_rx_voice_mixer_controls, - ARRAY_SIZE(slimbus_6_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIM_7_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, - slimbus_7_rx_voice_mixer_controls, - ARRAY_SIZE(slimbus_7_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIM_8_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, - slimbus_8_rx_voice_mixer_controls, - ARRAY_SIZE(slimbus_8_rx_voice_mixer_controls)), /* port mixer */ - SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Port Mixer", - SND_SOC_NOPM, 0, 0, sbus_0_rx_port_mixer_controls, - ARRAY_SIZE(sbus_0_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("AUX_PCM_RX Port Mixer", - SND_SOC_NOPM, 0, 0, aux_pcm_rx_port_mixer_controls, - ARRAY_SIZE(aux_pcm_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_AUXPCM_RX Port Mixer", - SND_SOC_NOPM, 0, 0, sec_auxpcm_rx_port_mixer_controls, - ARRAY_SIZE(sec_auxpcm_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_AUXPCM_RX Port Mixer", - SND_SOC_NOPM, 0, 0, tert_auxpcm_rx_port_mixer_controls, - ARRAY_SIZE(tert_auxpcm_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_AUXPCM_RX Port Mixer", - SND_SOC_NOPM, 0, 0, quat_auxpcm_rx_port_mixer_controls, - ARRAY_SIZE(quat_auxpcm_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_AUXPCM_RX Port Mixer", - SND_SOC_NOPM, 0, 0, quin_auxpcm_rx_port_mixer_controls, - ARRAY_SIZE(quin_auxpcm_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_AUXPCM_RX Port Mixer", - SND_SOC_NOPM, 0, 0, sen_auxpcm_rx_port_mixer_controls, - ARRAY_SIZE(sen_auxpcm_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Port Mixer", SND_SOC_NOPM, 0, 0, - sbus_1_rx_port_mixer_controls, - ARRAY_SIZE(sbus_1_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Port Mixer", SND_SOC_NOPM, 0, 0, - bt_sco_rx_port_mixer_controls, - ARRAY_SIZE(bt_sco_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("AFE_PCM_RX Port Mixer", - SND_SOC_NOPM, 0, 0, afe_pcm_rx_port_mixer_controls, - ARRAY_SIZE(afe_pcm_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("HDMI_RX Port Mixer", - SND_SOC_NOPM, 0, 0, hdmi_rx_port_mixer_controls, - ARRAY_SIZE(hdmi_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("HDMI_RX_MS Port Mixer", - SND_SOC_NOPM, 0, 0, hdmi_rx_ms_port_mixer_controls, - ARRAY_SIZE(hdmi_rx_ms_port_mixer_controls)), - SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX Port Mixer", - SND_SOC_NOPM, 0, 0, display_port_rx_port_mixer_controls, - ARRAY_SIZE(display_port_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX1 Port Mixer", - SND_SOC_NOPM, 0, 0, display_port_rx1_port_mixer_controls, - ARRAY_SIZE(display_port_rx1_port_mixer_controls)), SND_SOC_DAPM_MIXER("SEC_I2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, sec_i2s_rx_port_mixer_controls, ARRAY_SIZE(sec_i2s_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_3_RX Port Mixer", - SND_SOC_NOPM, 0, 0, sbus_3_rx_port_mixer_controls, - ARRAY_SIZE(sbus_3_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_6_RX Port Mixer", - SND_SOC_NOPM, 0, 0, sbus_6_rx_port_mixer_controls, - ARRAY_SIZE(sbus_6_rx_port_mixer_controls)), SND_SOC_DAPM_MIXER("MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, mi2s_rx_port_mixer_controls, ARRAY_SIZE(mi2s_rx_port_mixer_controls)), SND_SOC_DAPM_MIXER("PRI_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, @@ -25194,6 +24897,650 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("SEN_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, sen_mi2s_rx_port_mixer_controls, ARRAY_SIZE(sen_mi2s_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("INT0_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, + int0_mi2s_rx_port_mixer_controls, + ARRAY_SIZE(int0_mi2s_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("INT4_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, + int4_mi2s_rx_port_mixer_controls, + ARRAY_SIZE(int4_mi2s_rx_port_mixer_controls)), + /* lsm mixer definitions */ + /* Virtual Pins to force backends ON atm */ + SND_SOC_DAPM_MUX("PRI_MI2S_RX_VI_FB_MUX", SND_SOC_NOPM, 0, 0, + &mi2s_rx_vi_fb_mux), + SND_SOC_DAPM_MUX("INT4_MI2S_RX_VI_FB_MONO_CH_MUX", SND_SOC_NOPM, 0, 0, + &int4_mi2s_rx_vi_fb_mono_ch_mux), + SND_SOC_DAPM_MUX("INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", SND_SOC_NOPM, 0, 0, + &int4_mi2s_rx_vi_fb_stereo_ch_mux), +}; +#endif + +#ifndef CONFIG_TDM_DISABLE +static const struct snd_soc_dapm_widget msm_qdsp6_widgets_tdm[] = { + /* Frontend AIF */ + /* Widget name equals to Front-End DAI name, + * Stream name must contains substring of front-end dai name + */ + + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_0_DL_HL", + "Primary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_0_UL_HL", + "Primary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_1_DL_HL", + "Primary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_1_UL_HL", + "Primary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_2_DL_HL", + "Primary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_2_UL_HL", + "Primary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_3_DL_HL", + "Primary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_3_UL_HL", + "Primary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_4_DL_HL", + "Primary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_4_UL_HL", + "Primary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_5_DL_HL", + "Primary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_5_UL_HL", + "Primary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_6_DL_HL", + "Primary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_6_UL_HL", + "Primary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_7_DL_HL", + "Primary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_7_UL_HL", + "Primary TDM7 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_0_DL_HL", + "Secondary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_0_UL_HL", + "Secondary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_1_DL_HL", + "Secondary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_1_UL_HL", + "Secondary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_2_DL_HL", + "Secondary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_2_UL_HL", + "Secondary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_3_DL_HL", + "Secondary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_3_UL_HL", + "Secondary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_4_DL_HL", + "Secondary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_4_UL_HL", + "Secondary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_5_DL_HL", + "Secondary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_5_UL_HL", + "Secondary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_6_DL_HL", + "Secondary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_6_UL_HL", + "Secondary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_7_DL_HL", + "Secondary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_7_UL_HL", + "Secondary TDM7 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_0_DL_HL", + "Tertiary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_0_UL_HL", + "Tertiary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_1_DL_HL", + "Tertiary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_1_UL_HL", + "Tertiary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_2_DL_HL", + "Tertiary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_2_UL_HL", + "Tertiary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_3_DL_HL", + "Tertiary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_3_UL_HL", + "Tertiary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_4_DL_HL", + "Tertiary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_4_UL_HL", + "Tertiary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_5_DL_HL", + "Tertiary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_5_UL_HL", + "Tertiary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_6_DL_HL", + "Tertiary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_6_UL_HL", + "Tertiary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_7_DL_HL", + "Tertiary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_7_UL_HL", + "Tertiary TDM7 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_0_DL_HL", + "Quaternary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_0_UL_HL", + "Quaternary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_1_DL_HL", + "Quaternary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_1_UL_HL", + "Quaternary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_2_DL_HL", + "Quaternary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_2_UL_HL", + "Quaternary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_3_DL_HL", + "Quaternary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_3_UL_HL", + "Quaternary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_4_DL_HL", + "Quaternary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_4_UL_HL", + "Quaternary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_5_DL_HL", + "Quaternary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_5_UL_HL", + "Quaternary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_6_DL_HL", + "Quaternary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_6_UL_HL", + "Quaternary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_7_DL_HL", + "Quaternary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_7_UL_HL", + "Quaternary TDM7 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_0_DL_HL", + "Quinary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_0_UL_HL", + "Quinary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_1_DL_HL", + "Quinary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_1_UL_HL", + "Quinary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_2_DL_HL", + "Quinary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_2_UL_HL", + "Quinary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_3_DL_HL", + "Quinary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_3_UL_HL", + "Quinary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_4_DL_HL", + "Quinary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_4_UL_HL", + "Quinary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_5_DL_HL", + "Quinary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_5_UL_HL", + "Quinary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_6_DL_HL", + "Quinary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_6_UL_HL", + "Quinary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_7_DL_HL", + "Quinary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_7_UL_HL", + "Quinary TDM7 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_0_DL_HL", + "Senary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_0_UL_HL", + "Senary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_1_DL_HL", + "Senary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_1_UL_HL", + "Senary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_2_DL_HL", + "Senary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_2_UL_HL", + "Senary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_3_DL_HL", + "Senary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_3_UL_HL", + "Senary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_4_DL_HL", + "Senary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_4_UL_HL", + "Senary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_5_DL_HL", + "Senary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_5_UL_HL", + "Senary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_6_DL_HL", + "Senary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_6_UL_HL", + "Senary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_7_DL_HL", + "Senary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_7_UL_HL", + "Senary TDM7 Hostless Capture", + 0, 0, 0, 0), + + /* Backend AIF */ + /* Stream name equals to backend dai link stream name */ + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_0", "Primary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_0", "Primary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_1", "Primary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_1", "Primary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_2", "Primary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_2", "Primary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_3", "Primary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_3", "Primary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_4", "Primary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_4", "Primary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_5", "Primary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_5", "Primary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_6", "Primary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_6", "Primary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_7", "Primary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_7", "Primary TDM7 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_0", "Secondary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_0", "Secondary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_1", "Secondary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_1", "Secondary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_2", "Secondary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_2", "Secondary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_3", "Secondary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_3", "Secondary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_4", "Secondary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_4", "Secondary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_5", "Secondary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_5", "Secondary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_6", "Secondary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_6", "Secondary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_7", "Secondary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_7", "Secondary TDM7 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_0", "Tertiary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_0", "Tertiary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_1", "Tertiary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_1", "Tertiary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_2", "Tertiary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_2", "Tertiary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_3", "Tertiary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_3", "Tertiary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_4", "Tertiary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_4", "Tertiary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_5", "Tertiary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_5", "Tertiary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_6", "Tertiary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_6", "Tertiary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_7", "Tertiary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_7", "Tertiary TDM7 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_0", "Quaternary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_0", "Quaternary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_1", "Quaternary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_1", "Quaternary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_2", "Quaternary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_2", "Quaternary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_3", "Quaternary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_3", "Quaternary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_4", "Quaternary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_4", "Quaternary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_5", "Quaternary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_5", "Quaternary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_6", "Quaternary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_6", "Quaternary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_7", "Quaternary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_7", "Quaternary TDM7 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_0", "Quinary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_0", "Quinary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_1", "Quinary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_1", "Quinary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_2", "Quinary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_2", "Quinary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_3", "Quinary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_3", "Quinary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_4", "Quinary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_4", "Quinary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_5", "Quinary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_5", "Quinary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_6", "Quinary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_6", "Quinary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_7", "Quinary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_7", "Quinary TDM7 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_0", "Senary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_0", "Senary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_1", "Senary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_1", "Senary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_2", "Senary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_2", "Senary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_3", "Senary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_3", "Senary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_4", "Senary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_4", "Senary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_5", "Senary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_5", "Senary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_6", "Senary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_6", "Senary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_7", "Senary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_7", "Senary TDM7 Capture", + 0, 0, 0, 0), + /* incall */ + /* In- call recording */ + /* Switch Definitions */ + /* Mixer definitions */ + SND_SOC_DAPM_MIXER("PRI_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_0_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_1_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_2_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_3_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_tx_0_mixer_controls, + ARRAY_SIZE(pri_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_0_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_1_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_2_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_3_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_tx_0_mixer_controls, + ARRAY_SIZE(sec_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_0_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_tx_0_mixer_controls, + ARRAY_SIZE(tert_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_1_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_2_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_3_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_4_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_4_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_0_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_tx_0_mixer_controls, + ARRAY_SIZE(quat_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_1_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_2_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_3_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_0_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_tx_0_mixer_controls, + ARRAY_SIZE(quin_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_1_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_TX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_tx_1_mixer_controls, + ARRAY_SIZE(quin_tdm_tx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_2_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_TX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_tx_2_mixer_controls, + ARRAY_SIZE(quin_tdm_tx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_3_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_TX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_tx_3_mixer_controls, + ARRAY_SIZE(quin_tdm_tx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_tx_0_mixer_controls, + ARRAY_SIZE(sen_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_rx_0_mixer_controls, + ARRAY_SIZE(sen_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_rx_1_mixer_controls, + ARRAY_SIZE(sen_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_rx_2_mixer_controls, + ARRAY_SIZE(sen_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_rx_3_mixer_controls, + ARRAY_SIZE(sen_tdm_rx_3_mixer_controls)), + /* incall */ + /* Voice Mixer */ + SND_SOC_DAPM_MIXER("PRI_TDM_RX_0_Voice Mixer", + SND_SOC_NOPM, 0, 0, + pri_tdm_rx_0_voice_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_0_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_1_Voice Mixer", + SND_SOC_NOPM, 0, 0, + pri_tdm_rx_1_voice_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_1_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_2_Voice Mixer", + SND_SOC_NOPM, 0, 0, + pri_tdm_rx_2_voice_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_2_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_3_Voice Mixer", + SND_SOC_NOPM, 0, 0, + pri_tdm_rx_3_voice_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_3_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_MI2S_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + sen_mi2s_rx_voice_mixer_controls, + ARRAY_SIZE(sen_mi2s_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_2_Voice Mixer", + SND_SOC_NOPM, 0, 0, + quat_tdm_rx_2_voice_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_2_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_2_Voice Mixer", + SND_SOC_NOPM, 0, 0, + quin_tdm_rx_2_voice_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_2_voice_mixer_controls)), + /* port mixer */ SND_SOC_DAPM_MIXER("PRI_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, pri_tdm_rx_0_port_mixer_controls, ARRAY_SIZE(pri_tdm_rx_0_port_mixer_controls)), @@ -25275,2851 +25622,3619 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("SEN_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0, sen_tdm_rx_3_port_mixer_controls, ARRAY_SIZE(sen_tdm_rx_3_port_mixer_controls)), - SND_SOC_DAPM_MIXER("INT0_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, - int0_mi2s_rx_port_mixer_controls, - ARRAY_SIZE(int0_mi2s_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("INT4_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, - int4_mi2s_rx_port_mixer_controls, - ARRAY_SIZE(int4_mi2s_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, - wsa_cdc_dma_rx_0_port_mixer_controls, - ARRAY_SIZE(wsa_cdc_dma_rx_0_port_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_0_port_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_0_port_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_1 Port Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_1_port_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_1_port_mixer_controls)), - SND_SOC_DAPM_MIXER("QCHAT_Tx Mixer", - SND_SOC_NOPM, 0, 0, tx_qchat_mixer_controls, - ARRAY_SIZE(tx_qchat_mixer_controls)), - SND_SOC_DAPM_MIXER("USB_AUDIO_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, usb_audio_rx_voice_mixer_controls, - ARRAY_SIZE(usb_audio_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("USB_AUDIO_RX Port Mixer", - SND_SOC_NOPM, 0, 0, usb_rx_port_mixer_controls, - ARRAY_SIZE(usb_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, display_port_rx_voice_mixer_controls, - ARRAY_SIZE(display_port_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX1_Voice Mixer", - SND_SOC_NOPM, 0, 0, display_port_rx1_voice_mixer_controls, - ARRAY_SIZE(display_port_rx1_voice_mixer_controls)), - /* lsm mixer definitions */ - SND_SOC_DAPM_MIXER("LSM1 Mixer", SND_SOC_NOPM, 0, 0, - lsm1_mixer_controls, ARRAY_SIZE(lsm1_mixer_controls)), - SND_SOC_DAPM_MIXER("LSM2 Mixer", SND_SOC_NOPM, 0, 0, - lsm2_mixer_controls, ARRAY_SIZE(lsm2_mixer_controls)), - SND_SOC_DAPM_MIXER("LSM3 Mixer", SND_SOC_NOPM, 0, 0, - lsm3_mixer_controls, ARRAY_SIZE(lsm3_mixer_controls)), - SND_SOC_DAPM_MIXER("LSM4 Mixer", SND_SOC_NOPM, 0, 0, - lsm4_mixer_controls, ARRAY_SIZE(lsm4_mixer_controls)), - SND_SOC_DAPM_MIXER("LSM5 Mixer", SND_SOC_NOPM, 0, 0, - lsm5_mixer_controls, ARRAY_SIZE(lsm5_mixer_controls)), - SND_SOC_DAPM_MIXER("LSM6 Mixer", SND_SOC_NOPM, 0, 0, - lsm6_mixer_controls, ARRAY_SIZE(lsm6_mixer_controls)), - SND_SOC_DAPM_MIXER("LSM7 Mixer", SND_SOC_NOPM, 0, 0, - lsm7_mixer_controls, ARRAY_SIZE(lsm7_mixer_controls)), - SND_SOC_DAPM_MIXER("LSM8 Mixer", SND_SOC_NOPM, 0, 0, - lsm8_mixer_controls, ARRAY_SIZE(lsm8_mixer_controls)), - /* Virtual Pins to force backends ON atm */ - SND_SOC_DAPM_OUTPUT("BE_OUT"), - SND_SOC_DAPM_INPUT("BE_IN"), - SND_SOC_DAPM_MUX("SLIM0_RX_VI_FB_LCH_MUX", SND_SOC_NOPM, 0, 0, - &slim0_rx_vi_fb_lch_mux), - SND_SOC_DAPM_MUX("SLIM0_RX_VI_FB_RCH_MUX", SND_SOC_NOPM, 0, 0, - &slim0_rx_vi_fb_rch_mux), - SND_SOC_DAPM_MUX("WSA_RX_0_VI_FB_LCH_MUX", SND_SOC_NOPM, 0, 0, - &wsa_rx_0_vi_fb_lch_mux), - SND_SOC_DAPM_MUX("WSA_RX_0_VI_FB_RCH_MUX", SND_SOC_NOPM, 0, 0, - &wsa_rx_0_vi_fb_rch_mux), - SND_SOC_DAPM_MUX("PRI_MI2S_RX_VI_FB_MUX", SND_SOC_NOPM, 0, 0, - &mi2s_rx_vi_fb_mux), - SND_SOC_DAPM_MUX("INT4_MI2S_RX_VI_FB_MONO_CH_MUX", SND_SOC_NOPM, 0, 0, - &int4_mi2s_rx_vi_fb_mono_ch_mux), - SND_SOC_DAPM_MUX("INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", SND_SOC_NOPM, 0, 0, - &int4_mi2s_rx_vi_fb_stereo_ch_mux), +}; +#endif + +static const struct snd_soc_dapm_route intercon[] = { + + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"}, + + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SLIMBUS_2_RX", NULL, "SLIMBUS_2_RX Audio Mixer"}, + + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SLIMBUS_5_RX", NULL, "SLIMBUS_5_RX Audio Mixer"}, + + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0 Audio Mixer"}, + + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"WSA_CDC_DMA_RX_1", NULL, "WSA_CDC_DMA_RX_1 Audio Mixer"}, + + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0 Audio Mixer"}, + + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1 Audio Mixer"}, + + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"RX_CDC_DMA_RX_2", NULL, "RX_CDC_DMA_RX_2 Audio Mixer"}, + + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"RX_CDC_DMA_RX_3", NULL, "RX_CDC_DMA_RX_3 Audio Mixer"}, + + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"RX_CDC_DMA_RX_4", NULL, "RX_CDC_DMA_RX_4 Audio Mixer"}, + + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"RX_CDC_DMA_RX_5", NULL, "RX_CDC_DMA_RX_5 Audio Mixer"}, + + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"RX_CDC_DMA_RX_6", NULL, "RX_CDC_DMA_RX_6 Audio Mixer"}, + + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"RX_CDC_DMA_RX_7", NULL, "RX_CDC_DMA_RX_7 Audio Mixer"}, + + {"HDMI Mixer", "MultiMedia1", "MM_DL1"}, + {"HDMI Mixer", "MultiMedia2", "MM_DL2"}, + {"HDMI Mixer", "MultiMedia3", "MM_DL3"}, + {"HDMI Mixer", "MultiMedia4", "MM_DL4"}, + {"HDMI Mixer", "MultiMedia5", "MM_DL5"}, + {"HDMI Mixer", "MultiMedia6", "MM_DL6"}, + {"HDMI Mixer", "MultiMedia7", "MM_DL7"}, + {"HDMI Mixer", "MultiMedia8", "MM_DL8"}, + {"HDMI Mixer", "MultiMedia9", "MM_DL9"}, + {"HDMI Mixer", "MultiMedia10", "MM_DL10"}, + {"HDMI Mixer", "MultiMedia11", "MM_DL11"}, + {"HDMI Mixer", "MultiMedia12", "MM_DL12"}, + {"HDMI Mixer", "MultiMedia13", "MM_DL13"}, + {"HDMI Mixer", "MultiMedia14", "MM_DL14"}, + {"HDMI Mixer", "MultiMedia15", "MM_DL15"}, + {"HDMI Mixer", "MultiMedia16", "MM_DL16"}, + {"HDMI Mixer", "MultiMedia26", "MM_DL26"}, + {"HDMI", NULL, "HDMI Mixer"}, + + {"HDMI_MS Mixer", "MultiMedia1", "MM_DL1"}, + {"HDMI_MS Mixer", "MultiMedia2", "MM_DL2"}, + {"HDMI_MS Mixer", "MultiMedia3", "MM_DL3"}, + {"HDMI_MS Mixer", "MultiMedia4", "MM_DL4"}, + {"HDMI_MS Mixer", "MultiMedia5", "MM_DL5"}, + {"HDMI_MS Mixer", "MultiMedia6", "MM_DL6"}, + {"HDMI_MS Mixer", "MultiMedia7", "MM_DL7"}, + {"HDMI_MS Mixer", "MultiMedia8", "MM_DL8"}, + {"HDMI_MS Mixer", "MultiMedia9", "MM_DL9"}, + {"HDMI_MS Mixer", "MultiMedia10", "MM_DL10"}, + {"HDMI_MS Mixer", "MultiMedia11", "MM_DL11"}, + {"HDMI_MS Mixer", "MultiMedia12", "MM_DL12"}, + {"HDMI_MS Mixer", "MultiMedia13", "MM_DL13"}, + {"HDMI_MS Mixer", "MultiMedia14", "MM_DL14"}, + {"HDMI_MS Mixer", "MultiMedia15", "MM_DL15"}, + {"HDMI_MS Mixer", "MultiMedia16", "MM_DL16"}, + {"HDMI_MS Mixer", "MultiMedia26", "MM_DL26"}, + {"HDMI_MS", NULL, "HDMI_MS Mixer"}, + + {"DISPLAY_PORT Mixer", "MultiMedia1", "MM_DL1"}, + {"DISPLAY_PORT Mixer", "MultiMedia2", "MM_DL2"}, + {"DISPLAY_PORT Mixer", "MultiMedia3", "MM_DL3"}, + {"DISPLAY_PORT Mixer", "MultiMedia4", "MM_DL4"}, + {"DISPLAY_PORT Mixer", "MultiMedia5", "MM_DL5"}, + {"DISPLAY_PORT Mixer", "MultiMedia6", "MM_DL6"}, + {"DISPLAY_PORT Mixer", "MultiMedia7", "MM_DL7"}, + {"DISPLAY_PORT Mixer", "MultiMedia8", "MM_DL8"}, + {"DISPLAY_PORT Mixer", "MultiMedia9", "MM_DL9"}, + {"DISPLAY_PORT Mixer", "MultiMedia10", "MM_DL10"}, + {"DISPLAY_PORT Mixer", "MultiMedia11", "MM_DL11"}, + {"DISPLAY_PORT Mixer", "MultiMedia12", "MM_DL12"}, + {"DISPLAY_PORT Mixer", "MultiMedia13", "MM_DL13"}, + {"DISPLAY_PORT Mixer", "MultiMedia14", "MM_DL14"}, + {"DISPLAY_PORT Mixer", "MultiMedia15", "MM_DL15"}, + {"DISPLAY_PORT Mixer", "MultiMedia16", "MM_DL16"}, + {"DISPLAY_PORT Mixer", "MultiMedia26", "MM_DL26"}, + {"DISPLAY_PORT", NULL, "DISPLAY_PORT Mixer"}, + + {"DISPLAY_PORT1 Mixer", "MultiMedia1", "MM_DL1"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia2", "MM_DL2"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia3", "MM_DL3"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia4", "MM_DL4"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia5", "MM_DL5"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia6", "MM_DL6"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia7", "MM_DL7"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia8", "MM_DL8"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia9", "MM_DL9"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia10", "MM_DL10"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia11", "MM_DL11"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia12", "MM_DL12"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia13", "MM_DL13"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia14", "MM_DL14"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia15", "MM_DL15"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia16", "MM_DL16"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia26", "MM_DL26"}, + {"DISPLAY_PORT1", NULL, "DISPLAY_PORT1 Mixer"}, + + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"PRI_SPDIF_RX", NULL, "PRI_SPDIF_RX Audio Mixer"}, + + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SEC_SPDIF_RX", NULL, "SEC_SPDIF_RX Audio Mixer"}, + + /* incall */ + {"Incall_Music Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"Incall_Music Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"Incall_Music Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"Incall_Music Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"Incall_Music Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"VOICE_PLAYBACK_TX", NULL, "Incall_Music Audio Mixer"}, + {"Incall_Music_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"Incall_Music_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"Incall_Music_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"Incall_Music_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"VOICE2_PLAYBACK_TX", NULL, "Incall_Music_2 Audio Mixer"}, + {"SLIMBUS_4_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_4_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_4_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_4_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_4_RX", NULL, "SLIMBUS_4_RX Audio Mixer"}, + + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SLIMBUS_6_RX", NULL, "SLIMBUS_6_RX Audio Mixer"}, + + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SLIMBUS_7_RX", NULL, "SLIMBUS_7_RX Audio Mixer"}, + + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SLIMBUS_9_RX", NULL, "SLIMBUS_9_RX Audio Mixer"}, + + {"USB_AUDIO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX Audio Mixer"}, + + {"MultiMedia1 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, + {"MultiMedia4 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, + {"MultiMedia8 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, + {"MultiMedia9 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, + {"MultiMedia1 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, + {"MultiMedia4 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, + {"MultiMedia8 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, + {"MultiMedia9 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, + {"MultiMedia1 Mixer", "SLIM_4_TX", "SLIMBUS_4_TX"}, + {"MultiMedia1 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, + {"MultiMedia1 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia1 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"MultiMedia1 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, + {"MultiMedia8 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, + {"MultiMedia8 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia8 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, + {"MultiMedia4 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia4 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia17 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia17 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia17 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia17 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia18 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia18 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia19 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia19 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia28 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia28 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia29 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia29 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia30 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia30 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia8 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia8 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia3 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia5 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia10 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia10 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia16 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia16 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia5 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia5 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"MultiMedia5 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, + {"MultiMedia10 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia10 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, + {"MultiMedia18 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia19 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia28 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia29 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia30 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia18 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia19 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia28 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia29 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia30 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + + {"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia1 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia2 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia2 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, + {"MultiMedia2 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia2 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"MultiMedia6 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia6 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + + {"MultiMedia1 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia1 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia1 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + + {"MultiMedia2 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia2 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia2 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + + {"MultiMedia3 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia3 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia3 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + + {"MultiMedia4 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia4 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia4 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + + {"MultiMedia5 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia5 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia5 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + + {"MultiMedia6 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia6 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia6 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + + {"MultiMedia8 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia8 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia8 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + + {"MultiMedia9 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia9 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia9 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia9 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia10 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + + {"MultiMedia20 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia20 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia20 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia20 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia20 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia20 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, + {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia20 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia20 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia20 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + + {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia21 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia21 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia21 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + + {"MultiMedia27 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia27 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia27 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, + {"MultiMedia27 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia27 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, + {"MultiMedia27 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia27 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia27 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + + {"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia4 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia5 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia6 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia8 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia10 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + + {"MultiMedia16 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia16 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia16 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia16 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia17 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia18 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia18 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia18 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia19 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia19 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia19 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia28 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia28 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia28 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia29 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia29 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia29 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia30 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia30 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia30 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia6", "MM_UL6"}, + {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"}, + + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia6", "MM_UL6"}, + {"INT_BT_A2DP_RX", NULL, "INTERNAL_A2DP_RX Audio Mixer"}, + + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"}, + + {"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"}, + + {"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia3 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia4 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia10 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia17 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia18 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia19 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia28 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia29 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia30 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia5 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia8 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia16 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia4 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia16 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia17 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia18 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia19 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia28 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia29 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia30 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia5 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia6 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia8 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + + {"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia3 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia4 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia10 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia17 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia18 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia19 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia28 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia29 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia30 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia5 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia8 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia16 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MM_UL1", NULL, "MultiMedia1 Mixer"}, + {"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MM_UL2", NULL, "MultiMedia2 Mixer"}, + {"MM_UL3", NULL, "MultiMedia3 Mixer"}, + {"MM_UL4", NULL, "MultiMedia4 Mixer"}, + {"MM_UL5", NULL, "MultiMedia5 Mixer"}, + {"MM_UL6", NULL, "MultiMedia6 Mixer"}, + {"MM_UL8", NULL, "MultiMedia8 Mixer"}, + {"MM_UL9", NULL, "MultiMedia9 Mixer"}, + {"MM_UL10", NULL, "MultiMedia10 Mixer"}, + {"MM_UL16", NULL, "MultiMedia16 Mixer"}, + {"MM_UL17", NULL, "MultiMedia17 Mixer"}, + {"MM_UL18", NULL, "MultiMedia18 Mixer"}, + {"MM_UL19", NULL, "MultiMedia19 Mixer"}, + {"MM_UL20", NULL, "MultiMedia20 Mixer"}, + {"MM_UL21", NULL, "MultiMedia21 Mixer"}, + {"MM_UL22", NULL, "MultiMedia22 Mixer"}, + {"MM_UL23", NULL, "MultiMedia23 Mixer"}, + {"MM_UL24", NULL, "MultiMedia24 Mixer"}, + {"MM_UL25", NULL, "MultiMedia25 Mixer"}, + {"MM_UL27", NULL, "MultiMedia27 Mixer"}, + {"MM_UL28", NULL, "MultiMedia28 Mixer"}, + {"MM_UL29", NULL, "MultiMedia29 Mixer"}, + {"MM_UL30", NULL, "MultiMedia30 Mixer"}, + - SND_SOC_DAPM_MUX("VOC_EXT_EC MUX", SND_SOC_NOPM, 0, 0, - &voc_ext_ec_mux), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL1 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul1), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL2 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul2), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL3 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul3), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL4 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul4), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL5 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul5), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL6 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul6), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL8 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul8), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL9 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul9), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL10 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul10), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL16 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul16), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL17 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul17), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL18 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul18), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL19 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul19), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL28 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul28), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL29 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul29), -}; + {"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SLIM_0_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SLIM_0_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SLIM_0_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIM_0_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"}, -static const struct snd_soc_dapm_route intercon[] = { - {"PRI_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"}, + {"SLIM_6_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SLIM_6_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SLIM_6_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SLIM_6_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIM_6_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SLIMBUS_6_RX", NULL, "SLIM_6_RX_Voice Mixer"}, - {"SEC_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SEC_I2S_RX", NULL, "SEC_RX Audio Mixer"}, + {"USB_AUDIO_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"USB_AUDIO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX_Voice Mixer"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"}, + {"DISPLAY_PORT_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"DISPLAY_PORT_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"DISPLAY_PORT_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"DISPLAY_PORT_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"DISPLAY_PORT_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"DISPLAY_PORT", NULL, "DISPLAY_PORT_RX_Voice Mixer"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SLIMBUS_2_RX", NULL, "SLIMBUS_2_RX Audio Mixer"}, + {"DISPLAY_PORT_RX1_Voice Mixer", "Voip", "VOIP_DL"}, + {"DISPLAY_PORT_RX1_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"DISPLAY_PORT_RX1_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"DISPLAY_PORT_RX1_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"DISPLAY_PORT_RX1_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"DISPLAY_PORT1", NULL, "DISPLAY_PORT_RX1_Voice Mixer"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SLIMBUS_5_RX", NULL, "SLIMBUS_5_RX Audio Mixer"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0 Audio Mixer"}, + {"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"AFE_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"AFE_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"AFE_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"AFE_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"WSA_CDC_DMA_RX_1", NULL, "WSA_CDC_DMA_RX_1 Audio Mixer"}, + {"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"HDMI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"HDMI_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"HDMI_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"HDMI_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"HDMI", NULL, "HDMI_RX_Voice Mixer"}, + {"HDMI", NULL, "HDMI_DL_HL"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0 Audio Mixer"}, + {"WSA_CDC_DMA_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, + {"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0_Voice Mixer"}, + + {"PROXY_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PROXY_RX", NULL, "PROXY_RX_Voice Mixer"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1 Audio Mixer"}, + {"PROXY_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PROXY_RX", NULL, "PROXY_RX_Voice Mixer"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"RX_CDC_DMA_RX_2", NULL, "RX_CDC_DMA_RX_2 Audio Mixer"}, + {"RX_CDC_DMA_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, + {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0_Voice Mixer"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"RX_CDC_DMA_RX_3", NULL, "RX_CDC_DMA_RX_3 Audio Mixer"}, + {"RX_CDC_DMA_RX_1_Voice Mixer", "Voip", "VOIP_DL"}, + {"RX_CDC_DMA_RX_1_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"RX_CDC_DMA_RX_1_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1_Voice Mixer"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"RX_CDC_DMA_RX_4", NULL, "RX_CDC_DMA_RX_4 Audio Mixer"}, + {"VOC_EXT_EC MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"VOIP_UL", NULL, "VOC_EXT_EC MUX"}, + {"VOICEMMODE1_UL", NULL, "VOC_EXT_EC MUX"}, + {"VOICEMMODE2_UL", NULL, "VOC_EXT_EC MUX"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"RX_CDC_DMA_RX_5", NULL, "RX_CDC_DMA_RX_5 Audio Mixer"}, + {"AUDIO_REF_EC_UL1 MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"RX_CDC_DMA_RX_6", NULL, "RX_CDC_DMA_RX_6 Audio Mixer"}, + {"LSM1_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM2_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM3_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM4_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM5_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM6_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM7_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM8_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"RX_CDC_DMA_RX_7", NULL, "RX_CDC_DMA_RX_7 Audio Mixer"}, + {"MM_UL1", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"MM_UL2", NULL, "AUDIO_REF_EC_UL2 MUX"}, + {"MM_UL3", NULL, "AUDIO_REF_EC_UL3 MUX"}, + {"MM_UL4", NULL, "AUDIO_REF_EC_UL4 MUX"}, + {"MM_UL5", NULL, "AUDIO_REF_EC_UL5 MUX"}, + {"MM_UL6", NULL, "AUDIO_REF_EC_UL6 MUX"}, + {"MM_UL8", NULL, "AUDIO_REF_EC_UL8 MUX"}, + {"MM_UL9", NULL, "AUDIO_REF_EC_UL9 MUX"}, + {"MM_UL10", NULL, "AUDIO_REF_EC_UL10 MUX"}, + {"MM_UL16", NULL, "AUDIO_REF_EC_UL16 MUX"}, + {"MM_UL17", NULL, "AUDIO_REF_EC_UL17 MUX"}, + {"MM_UL18", NULL, "AUDIO_REF_EC_UL18 MUX"}, + {"MM_UL19", NULL, "AUDIO_REF_EC_UL19 MUX"}, + {"MM_UL28", NULL, "AUDIO_REF_EC_UL28 MUX"}, + {"MM_UL29", NULL, "AUDIO_REF_EC_UL29 MUX"}, + {"MM_UL30", NULL, "AUDIO_REF_EC_UL30 MUX"}, - {"HDMI Mixer", "MultiMedia1", "MM_DL1"}, - {"HDMI Mixer", "MultiMedia2", "MM_DL2"}, - {"HDMI Mixer", "MultiMedia3", "MM_DL3"}, - {"HDMI Mixer", "MultiMedia4", "MM_DL4"}, - {"HDMI Mixer", "MultiMedia5", "MM_DL5"}, - {"HDMI Mixer", "MultiMedia6", "MM_DL6"}, - {"HDMI Mixer", "MultiMedia7", "MM_DL7"}, - {"HDMI Mixer", "MultiMedia8", "MM_DL8"}, - {"HDMI Mixer", "MultiMedia9", "MM_DL9"}, - {"HDMI Mixer", "MultiMedia10", "MM_DL10"}, - {"HDMI Mixer", "MultiMedia11", "MM_DL11"}, - {"HDMI Mixer", "MultiMedia12", "MM_DL12"}, - {"HDMI Mixer", "MultiMedia13", "MM_DL13"}, - {"HDMI Mixer", "MultiMedia14", "MM_DL14"}, - {"HDMI Mixer", "MultiMedia15", "MM_DL15"}, - {"HDMI Mixer", "MultiMedia16", "MM_DL16"}, - {"HDMI Mixer", "MultiMedia26", "MM_DL26"}, - {"HDMI", NULL, "HDMI Mixer"}, + {"VoiceMMode1_Tx Mixer", "SLIM_0_TX_MMode1", "SLIMBUS_0_TX"}, + {"VoiceMMode1_Tx Mixer", "SLIM_7_TX_MMode1", "SLIMBUS_7_TX"}, + {"VoiceMMode1_Tx Mixer", "SLIM_8_TX_MMode1", "SLIMBUS_8_TX"}, + {"VoiceMMode1_Tx Mixer", "USB_AUDIO_TX_MMode1", "USB_AUDIO_TX"}, + {"VoiceMMode1_Tx Mixer", "INT_BT_SCO_TX_MMode1", "INT_BT_SCO_TX"}, + {"VoiceMMode1_Tx Mixer", "AFE_PCM_TX_MMode1", "PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_0_MMode1", "TX_CDC_DMA_TX_0"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_1_MMode1", "TX_CDC_DMA_TX_1"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_2_MMode1", "TX_CDC_DMA_TX_2"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_3_MMode1", "TX_CDC_DMA_TX_3"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_4_MMode1", "TX_CDC_DMA_TX_4"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_5_MMode1", "TX_CDC_DMA_TX_5"}, + {"VoiceMMode1_Tx Mixer", "PROXY_TX_MMode1", "PROXY_TX"}, + {"VOICEMMODE1_UL", NULL, "VoiceMMode1_Tx Mixer"}, - {"HDMI_MS Mixer", "MultiMedia1", "MM_DL1"}, - {"HDMI_MS Mixer", "MultiMedia2", "MM_DL2"}, - {"HDMI_MS Mixer", "MultiMedia3", "MM_DL3"}, - {"HDMI_MS Mixer", "MultiMedia4", "MM_DL4"}, - {"HDMI_MS Mixer", "MultiMedia5", "MM_DL5"}, - {"HDMI_MS Mixer", "MultiMedia6", "MM_DL6"}, - {"HDMI_MS Mixer", "MultiMedia7", "MM_DL7"}, - {"HDMI_MS Mixer", "MultiMedia8", "MM_DL8"}, - {"HDMI_MS Mixer", "MultiMedia9", "MM_DL9"}, - {"HDMI_MS Mixer", "MultiMedia10", "MM_DL10"}, - {"HDMI_MS Mixer", "MultiMedia11", "MM_DL11"}, - {"HDMI_MS Mixer", "MultiMedia12", "MM_DL12"}, - {"HDMI_MS Mixer", "MultiMedia13", "MM_DL13"}, - {"HDMI_MS Mixer", "MultiMedia14", "MM_DL14"}, - {"HDMI_MS Mixer", "MultiMedia15", "MM_DL15"}, - {"HDMI_MS Mixer", "MultiMedia16", "MM_DL16"}, - {"HDMI_MS Mixer", "MultiMedia26", "MM_DL26"}, - {"HDMI_MS", NULL, "HDMI_MS Mixer"}, + {"VoiceMMode2_Tx Mixer", "SLIM_0_TX_MMode2", "SLIMBUS_0_TX"}, + {"VoiceMMode2_Tx Mixer", "SLIM_7_TX_MMode2", "SLIMBUS_7_TX"}, + {"VoiceMMode2_Tx Mixer", "SLIM_8_TX_MMode2", "SLIMBUS_8_TX"}, + {"VoiceMMode2_Tx Mixer", "USB_AUDIO_TX_MMode2", "USB_AUDIO_TX"}, + {"VoiceMMode2_Tx Mixer", "INT_BT_SCO_TX_MMode2", "INT_BT_SCO_TX"}, + {"VoiceMMode2_Tx Mixer", "AFE_PCM_TX_MMode2", "PCM_TX"}, + + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_0_MMode2", "TX_CDC_DMA_TX_0"}, + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_1_MMode2", "TX_CDC_DMA_TX_1"}, + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_2_MMode2", "TX_CDC_DMA_TX_2"}, + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_3_MMode2", "TX_CDC_DMA_TX_3"}, + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_4_MMode2", "TX_CDC_DMA_TX_4"}, + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_5_MMode2", "TX_CDC_DMA_TX_5"}, + {"VoiceMMode2_Tx Mixer", "PROXY_TX_MMode2", "PROXY_TX"}, + {"VOICEMMODE2_UL", NULL, "VoiceMMode2_Tx Mixer"}, + + {"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"}, + {"Voip_Tx Mixer", "SLIM_7_TX_Voip", "SLIMBUS_7_TX"}, + {"Voip_Tx Mixer", "SLIM_8_TX_Voip", "SLIMBUS_8_TX"}, + {"Voip_Tx Mixer", "USB_AUDIO_TX_Voip", "USB_AUDIO_TX"}, + {"Voip_Tx Mixer", "INTERNAL_BT_SCO_TX_Voip", "INT_BT_SCO_TX"}, + {"Voip_Tx Mixer", "AFE_PCM_TX_Voip", "PCM_TX"}, + + {"Voip_Tx Mixer", "PRI_MI2S_TX_Voip", "PRI_MI2S_TX"}, + {"Voip_Tx Mixer", "PRI_TDM_TX_3_Voip", "PRI_TDM_TX_3"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_0_Voip", "TX_CDC_DMA_TX_0"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_1_Voip", "TX_CDC_DMA_TX_1"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_2_Voip", "TX_CDC_DMA_TX_2"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_3_Voip", "TX_CDC_DMA_TX_3"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_4_Voip", "TX_CDC_DMA_TX_4"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_5_Voip", "TX_CDC_DMA_TX_5"}, + {"VOIP_UL", NULL, "Voip_Tx Mixer"}, + + {"SLIMBUS_DL_HL", "Switch", "SLIM0_DL_HL"}, + {"SLIMBUS_0_RX", NULL, "SLIMBUS_DL_HL"}, + {"SLIMBUS1_DL_HL", "Switch", "SLIM1_DL_HL"}, + {"SLIMBUS_1_RX", NULL, "SLIMBUS1_DL_HL"}, + {"SLIMBUS3_DL_HL", "Switch", "SLIM3_DL_HL"}, + {"SLIMBUS_3_RX", NULL, "SLIMBUS3_DL_HL"}, + {"SLIMBUS4_DL_HL", "Switch", "SLIM4_DL_HL"}, + {"SLIMBUS_4_RX", NULL, "SLIMBUS4_DL_HL"}, + {"SLIMBUS6_DL_HL", "Switch", "SLIM0_DL_HL"}, + {"SLIMBUS_6_RX", NULL, "SLIMBUS6_DL_HL"}, + {"SCO_SLIM7_DL_HL", "Switch", "SLIM7_DL_HL"}, + {"SLIMBUS_7_RX", NULL, "SCO_SLIM7_DL_HL"}, + {"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"}, + {"SLIM1_UL_HL", NULL, "SLIMBUS_1_TX"}, + {"SLIM3_UL_HL", NULL, "SLIMBUS_3_TX"}, + {"SLIM4_UL_HL", NULL, "SLIMBUS_4_TX"}, + {"SLIM8_UL_HL", NULL, "SLIMBUS_8_TX"}, + {"WSA_CDC_DMA_RX_0_DL_HL", "Switch", "CDC_DMA_DL_HL"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0_DL_HL"}, + {"CDC_DMA_UL_HL", NULL, "VA_CDC_DMA_TX_0"}, + {"RX_CDC_DMA_RX_0_DL_HL", "Switch", "CDC_DMA_DL_HL"}, + {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0_DL_HL"}, + {"RX_CDC_DMA_RX_1_DL_HL", "Switch", "CDC_DMA_DL_HL"}, + {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1_DL_HL"}, + {"TX3_CDC_DMA_UL_HL", NULL, "TX_CDC_DMA_TX_3"}, + {"LSM1 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM1 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM1 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM1 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM1 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM1 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"LSM1 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM1_UL_HL", NULL, "LSM1 Mixer"}, - {"DISPLAY_PORT Mixer", "MultiMedia1", "MM_DL1"}, - {"DISPLAY_PORT Mixer", "MultiMedia2", "MM_DL2"}, - {"DISPLAY_PORT Mixer", "MultiMedia3", "MM_DL3"}, - {"DISPLAY_PORT Mixer", "MultiMedia4", "MM_DL4"}, - {"DISPLAY_PORT Mixer", "MultiMedia5", "MM_DL5"}, - {"DISPLAY_PORT Mixer", "MultiMedia6", "MM_DL6"}, - {"DISPLAY_PORT Mixer", "MultiMedia7", "MM_DL7"}, - {"DISPLAY_PORT Mixer", "MultiMedia8", "MM_DL8"}, - {"DISPLAY_PORT Mixer", "MultiMedia9", "MM_DL9"}, - {"DISPLAY_PORT Mixer", "MultiMedia10", "MM_DL10"}, - {"DISPLAY_PORT Mixer", "MultiMedia11", "MM_DL11"}, - {"DISPLAY_PORT Mixer", "MultiMedia12", "MM_DL12"}, - {"DISPLAY_PORT Mixer", "MultiMedia13", "MM_DL13"}, - {"DISPLAY_PORT Mixer", "MultiMedia14", "MM_DL14"}, - {"DISPLAY_PORT Mixer", "MultiMedia15", "MM_DL15"}, - {"DISPLAY_PORT Mixer", "MultiMedia16", "MM_DL16"}, - {"DISPLAY_PORT Mixer", "MultiMedia26", "MM_DL26"}, - {"DISPLAY_PORT", NULL, "DISPLAY_PORT Mixer"}, + {"LSM2 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM2 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM2 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM2 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM2 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM2 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"LSM2 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM2_UL_HL", NULL, "LSM2 Mixer"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia1", "MM_DL1"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia2", "MM_DL2"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia3", "MM_DL3"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia4", "MM_DL4"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia5", "MM_DL5"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia6", "MM_DL6"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia7", "MM_DL7"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia8", "MM_DL8"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia9", "MM_DL9"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia10", "MM_DL10"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia11", "MM_DL11"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia12", "MM_DL12"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia13", "MM_DL13"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia14", "MM_DL14"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia15", "MM_DL15"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia16", "MM_DL16"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia26", "MM_DL26"}, - {"DISPLAY_PORT1", NULL, "DISPLAY_PORT1 Mixer"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"PRI_SPDIF_RX", NULL, "PRI_SPDIF_RX Audio Mixer"}, + {"LSM3 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM3 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM3 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM3 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM3 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM3 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"LSM3 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM3_UL_HL", NULL, "LSM3 Mixer"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SEC_SPDIF_RX", NULL, "SEC_SPDIF_RX Audio Mixer"}, - /* incall */ - {"Incall_Music Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"Incall_Music Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"Incall_Music Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"Incall_Music Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"Incall_Music Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"VOICE_PLAYBACK_TX", NULL, "Incall_Music Audio Mixer"}, - {"Incall_Music_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"Incall_Music_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"Incall_Music_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"Incall_Music_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"VOICE2_PLAYBACK_TX", NULL, "Incall_Music_2 Audio Mixer"}, - {"SLIMBUS_4_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SLIMBUS_4_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SLIMBUS_4_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SLIMBUS_4_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SLIMBUS_4_RX", NULL, "SLIMBUS_4_RX Audio Mixer"}, + {"LSM4 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM4 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM4 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM4 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM4 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM4 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"LSM4 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM4_UL_HL", NULL, "LSM4 Mixer"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SLIMBUS_6_RX", NULL, "SLIMBUS_6_RX Audio Mixer"}, + {"LSM5 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM5 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM5 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM5 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM5 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM5 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"LSM5 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM5_UL_HL", NULL, "LSM5 Mixer"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SLIMBUS_7_RX", NULL, "SLIMBUS_7_RX Audio Mixer"}, + {"LSM6 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM6 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM6 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM6 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM6 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM6 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"LSM6 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM6_UL_HL", NULL, "LSM6 Mixer"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SLIMBUS_9_RX", NULL, "SLIMBUS_9_RX Audio Mixer"}, + {"LSM7 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM7 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM7 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM7 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM7 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM7 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM7 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM7 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"LSM7 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM7_UL_HL", NULL, "LSM7 Mixer"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX Audio Mixer"}, + {"LSM8 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM8 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM8 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM8 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM8 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM8 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"LSM8 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM8_UL_HL", NULL, "LSM8 Mixer"}, - {"MultiMedia1 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, - {"MultiMedia4 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, - {"MultiMedia8 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, - {"MultiMedia9 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, - {"MultiMedia1 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, - {"MultiMedia4 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, - {"MultiMedia8 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, - {"MultiMedia9 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, - {"MultiMedia1 Mixer", "SLIM_4_TX", "SLIMBUS_4_TX"}, - {"MultiMedia1 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, - {"MultiMedia1 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"MultiMedia1 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"MultiMedia1 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"MultiMedia8 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, - {"MultiMedia8 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"MultiMedia8 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"MultiMedia4 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia4 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia17 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia17 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia17 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"MultiMedia17 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"MultiMedia18 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia18 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia19 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia19 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia28 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia28 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia29 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia29 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia30 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia30 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia8 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia8 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia2 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia4 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia17 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia18 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia19 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia28 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia29 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia30 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia8 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia18 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia19 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia28 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia29 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia30 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia17 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia18 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia19 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia28 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia29 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia30 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia17 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia18 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia19 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia28 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia29 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia30 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia8 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia3 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia5 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia10 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia10 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia16 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia16 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia5 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"MultiMedia5 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"MultiMedia5 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"MultiMedia10 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"MultiMedia10 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"MultiMedia18 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia19 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia28 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia29 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia30 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia18 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia19 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia28 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia29 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia30 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"MI2S_RX", NULL, "MI2S_RX Audio Mixer"}, + {"CPE_LSM_UL_HL", NULL, "BE_IN"}, + {"QCHAT_Tx Mixer", "SLIM_0_TX_QCHAT", "SLIMBUS_0_TX"}, + {"QCHAT_Tx Mixer", "SLIM_7_TX_QCHAT", "SLIMBUS_7_TX"}, + {"QCHAT_Tx Mixer", "SLIM_8_TX_QCHAT", "SLIMBUS_8_TX"}, + {"QCHAT_Tx Mixer", "INTERNAL_BT_SCO_TX_QCHAT", "INT_BT_SCO_TX"}, + {"QCHAT_Tx Mixer", "AFE_PCM_TX_QCHAT", "PCM_TX"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX Audio Mixer"}, + {"QCHAT_Tx Mixer", "USB_AUDIO_TX_QCHAT", "USB_AUDIO_TX"}, + {"QCHAT_UL", NULL, "QCHAT_Tx Mixer"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX Audio Mixer"}, + {"INT_FM_RX", NULL, "INTFM_DL_HL"}, + {"INTFM_UL_HL", NULL, "INT_FM_TX"}, + {"INTHFP_UL_HL", NULL, "HFP_INT_UL_HL"}, + {"HFP_INT_UL_HL", "Switch", "INT_BT_SCO_TX"}, + {"SLIM7_UL_HL", NULL, "HFP_SLIM7_UL_HL"}, + {"HFP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"}, + {"SLIM7_UL_HL", NULL, "A2DP_SLIM7_UL_HL"}, + {"A2DP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"}, + {"PCM_RX_DL_HL", "Switch", "SLIM0_DL_HL"}, + {"PCM_RX", NULL, "PCM_RX_DL_HL"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Audio Mixer"}, + /* connect to INT4_MI2S_DL_HL since same pcm_id */ + {"WSA_CDC_DMA_RX_0 Port Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"WSA_CDC_DMA_RX_0 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"WSA_CDC_DMA_RX_0 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0 Port Mixer"}, - {"SEC_MI2S_RX_SD1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_MI2S_RX_SD1", NULL, "SEC_MI2S_RX_SD1 Audio Mixer"}, + {"RX_CDC_DMA_RX_0 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"RX_CDC_DMA_RX_0 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0 Port Mixer"}, - {"SEC_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEC_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"RX_CDC_DMA_RX_1 Port Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"RX_CDC_DMA_RX_1 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"RX_CDC_DMA_RX_1 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1 Port Mixer"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Audio Mixer"}, - {"PRI_MI2S_RX Audio Mixer", "DTMF", "DTMF_DL_HL"}, + {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, + {"SLIMBUS_0_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"}, + {"AFE_PCM_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"AFE_PCM_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"PCM_RX", NULL, "AFE_PCM_RX Port Mixer"}, + {"USB_AUDIO_RX Port Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX Port Mixer"}, + {"USB_DL_HL", "Switch", "USBAUDIO_DL_HL"}, + {"USB_AUDIO_RX", NULL, "USB_DL_HL"}, + {"USBAUDIO_UL_HL", NULL, "USB_AUDIO_TX"}, + + {"Voice Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, + {"Voice Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"Voice Stub Tx Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"Voice Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"}, + + {"Voice Stub Tx Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"Voice Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"}, + {"Voice Stub Tx Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"Voice Stub Tx Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"Voice Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"VOICE_STUB_UL", NULL, "Voice Stub Tx Mixer"}, + + {"VoLTE Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, + {"VoLTE Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"VoLTE Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"}, + {"VoLTE Stub Tx Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"VoLTE Stub Tx Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"VoLTE Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"}, + {"VoLTE Stub Tx Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"VoLTE Stub Tx Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"VoLTE Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"VOLTE_STUB_UL", NULL, "VoLTE Stub Tx Mixer"}, + + {"Voice2 Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, + {"Voice2 Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"Voice2 Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"}, + {"Voice2 Stub Tx Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"Voice2 Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"}, + {"Voice2 Stub Tx Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"Voice2 Stub Tx Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"Voice2 Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"VOICE2_STUB_UL", NULL, "Voice2 Stub Tx Mixer"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX Audio Mixer"}, + {"STUB_RX Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"STUB_RX Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"STUB_RX", NULL, "STUB_RX Mixer"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX Audio Mixer"}, + {"SLIMBUS_1_RX Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIMBUS_1_RX Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Mixer"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX Audio Mixer"}, + {"SLIMBUS_3_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIMBUS_3_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX_Voice Mixer"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX Audio Mixer"}, + {"SLIM_7_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SLIM_7_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SLIM_7_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SLIM_7_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIM_7_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SLIMBUS_7_RX", NULL, "SLIM_7_RX_Voice Mixer"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"PRI_META_MI2S_RX", NULL, "PRI_META_MI2S_RX Audio Mixer"}, + {"SLIM_8_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SLIM_8_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SLIM_8_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SLIM_8_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIM_8_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SLIMBUS_8_RX", NULL, "SLIM_8_RX_Voice Mixer"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SEC_META_MI2S_RX", NULL, "SEC_META_MI2S_RX Audio Mixer"}, + {"SLIMBUS_1_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SLIMBUS_1_RX Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Port Mixer"}, + {"INTERNAL_BT_SCO_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"INTERNAL_BT_SCO_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Port Mixer"}, + {"SLIMBUS_3_RX Port Mixer", "INTERNAL_BT_SCO_RX", "INT_BT_SCO_RX"}, + {"SLIMBUS_3_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"SLIMBUS_3_RX Port Mixer", "AFE_PCM_RX", "PCM_RX"}, + {"SLIMBUS_3_RX Port Mixer", "SLIM_0_RX", "SLIMBUS_0_RX"}, + {"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX Port Mixer"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Audio Mixer"}, + {"SLIMBUS_6_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Audio Mixer"}, + {"SLIMBUS_6_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SLIMBUS_6_RX", NULL, "SLIMBUS_6_RX Port Mixer"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Audio Mixer"}, + {"HDMI_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"HDMI", NULL, "HDMI_RX Port Mixer"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Audio Mixer"}, + {"HDMI_RX_MS Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"HDMI_MS", NULL, "HDMI_RX_MS Port Mixer"}, + + {"DISPLAY_PORT_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"DISPLAY_PORT", NULL, "DISPLAY_PORT_RX Port Mixer"}, + + {"DISPLAY_PORT_RX1 Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"DISPLAY_PORT1", NULL, "DISPLAY_PORT_RX1 Port Mixer"}, + + {"BE_OUT", NULL, "SLIMBUS_0_RX"}, + {"BE_OUT", NULL, "SLIMBUS_1_RX"}, + {"BE_OUT", NULL, "SLIMBUS_2_RX"}, + {"BE_OUT", NULL, "SLIMBUS_3_RX"}, + {"BE_OUT", NULL, "SLIMBUS_4_RX"}, + {"BE_OUT", NULL, "SLIMBUS_5_RX"}, + {"BE_OUT", NULL, "SLIMBUS_6_RX"}, + {"BE_OUT", NULL, "SLIMBUS_7_RX"}, + {"BE_OUT", NULL, "SLIMBUS_8_RX"}, + {"BE_OUT", NULL, "SLIMBUS_9_RX"}, + {"BE_OUT", NULL, "USB_AUDIO_RX"}, + {"BE_OUT", NULL, "HDMI"}, + {"BE_OUT", NULL, "HDMI_MS"}, + {"BE_OUT", NULL, "DISPLAY_PORT"}, + {"BE_OUT", NULL, "DISPLAY_PORT1"}, + {"BE_OUT", NULL, "PRI_SPDIF_RX"}, + {"BE_OUT", NULL, "SEC_SPDIF_RX"}, + {"BE_OUT", NULL, "INT_BT_SCO_RX"}, + {"BE_OUT", NULL, "INT_BT_A2DP_RX"}, + {"BE_OUT", NULL, "INT_FM_RX"}, + {"BE_OUT", NULL, "PCM_RX"}, + {"BE_OUT", NULL, "SLIMBUS_3_RX"}, + {"BE_OUT", NULL, "INT_BT_SCO_RX"}, + {"BE_OUT", NULL, "INT_FM_RX"}, + {"BE_OUT", NULL, "PCM_RX"}, + {"BE_OUT", NULL, "SLIMBUS_3_RX"}, + {"BE_OUT", NULL, "VOICE_PLAYBACK_TX"}, + {"BE_OUT", NULL, "VOICE2_PLAYBACK_TX"}, + {"BE_OUT", NULL, "WSA_CDC_DMA_RX_0"}, + {"BE_OUT", NULL, "WSA_CDC_DMA_RX_1"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_0"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_1"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_2"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_3"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_4"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_5"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_6"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_7"}, + {"BE_OUT", NULL, "PROXY_RX"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"PRI_TDM_TX_0", NULL, "PRI_TDM_TX_0 Audio Mixer"}, + {"SLIMBUS_0_TX", NULL, "BE_IN" }, + {"SLIMBUS_1_TX", NULL, "BE_IN" }, + {"SLIMBUS_3_TX", NULL, "BE_IN" }, + {"SLIMBUS_4_TX", NULL, "BE_IN" }, + {"SLIMBUS_5_TX", NULL, "BE_IN" }, + {"SLIMBUS_6_TX", NULL, "BE_IN" }, + {"SLIMBUS_7_TX", NULL, "BE_IN" }, + {"SLIMBUS_8_TX", NULL, "BE_IN" }, + {"SLIMBUS_9_TX", NULL, "BE_IN" }, + {"USB_AUDIO_TX", NULL, "BE_IN" }, + {"INT_BT_SCO_TX", NULL, "BE_IN"}, + {"INT_FM_TX", NULL, "BE_IN"}, + {"PCM_TX", NULL, "BE_IN"}, + {"BE_OUT", NULL, "SLIMBUS_3_RX"}, + {"BE_OUT", NULL, "STUB_RX"}, + {"STUB_TX", NULL, "BE_IN"}, + {"STUB_1_TX", NULL, "BE_IN"}, + {"BE_OUT", NULL, "AUX_PCM_RX"}, + {"INCALL_RECORD_TX", NULL, "BE_IN"}, + {"INCALL_RECORD_RX", NULL, "BE_IN"}, + {"SLIM0_RX_VI_FB_LCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"}, + {"SLIM0_RX_VI_FB_RCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"}, + {"WSA_RX_0_VI_FB_LCH_MUX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"WSA_RX_0_VI_FB_RCH_MUX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_LCH_MUX"}, + {"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_RCH_MUX"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_RX_0_VI_FB_LCH_MUX"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_RX_0_VI_FB_RCH_MUX"}, + {"WSA_CDC_DMA_TX_0", NULL, "BE_IN"}, + {"WSA_CDC_DMA_TX_1", NULL, "BE_IN"}, + {"WSA_CDC_DMA_TX_2", NULL, "BE_IN"}, + {"VA_CDC_DMA_TX_0", NULL, "BE_IN"}, + {"VA_CDC_DMA_TX_1", NULL, "BE_IN"}, + {"VA_CDC_DMA_TX_2", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_0", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_1", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_2", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_3", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_4", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_5", NULL, "BE_IN"}, + {"PRI_SPDIF_TX", NULL, "BE_IN"}, + {"SEC_SPDIF_TX", NULL, "BE_IN"}, + {"PROXY_TX", NULL, "BE_IN"}, +}; - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Audio Mixer"}, +#ifndef CONFIG_AUXPCM_DISABLE +static const struct snd_soc_dapm_route intercon_aux_pcm[] = { + /* incall */ + {"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"MultiMedia10 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia2 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia10 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia16 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, + {"MultiMedia16 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, + {"MultiMedia10 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia10 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia16 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "QUIN_AUX_PCM_TX", "QUIN_AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "QUIN_AUX_PCM_TX", "QUIN_AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "SEN_AUXPCM_UL_TX", "SEN_AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "SEN_AUX_PCM_TX", "SEN_AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "SEN_AUX_PCM_TX", "SEN_AUX_PCM_TX"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Audio Mixer"}, + {"MultiMedia21 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"MultiMedia21 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Audio Mixer"}, + {"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"MultiMedia6 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Audio Mixer"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"SEC_TDM_TX_0", NULL, "SEC_TDM_TX_0 Audio Mixer"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX Audio Mixer"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Audio Mixer"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_AUX_PCM_RX", NULL, "TERT_AUX_PCM_RX Audio Mixer"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"TERT_TDM_TX_0", NULL, "TERT_TDM_TX_0 Audio Mixer"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUX_PCM_RX Audio Mixer"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Audio Mixer"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUX_PCM_RX Audio Mixer"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Audio Mixer"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_AUX_PCM_RX", NULL, "SEN_AUX_PCM_RX Audio Mixer"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Audio Mixer"}, + {"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"TERT_TDM_RX_4", NULL, "TERT_TDM_RX_4 Audio Mixer"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX_Voice Mixer"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Audio Mixer"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"TERT_AUX_PCM_RX", NULL, "TERT_AUX_PCM_RX_Voice Mixer"}, + + {"QUAT_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUX_PCM_RX_Voice Mixer"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUAT_TDM_TX_0", NULL, "QUAT_TDM_TX_0 Audio Mixer"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUX_PCM_RX_Voice Mixer"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Audio Mixer"}, + {"SEN_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SEN_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SEN_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SEN_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SEN_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SEN_AUX_PCM_RX", NULL, "SEN_AUX_PCM_RX_Voice Mixer"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Audio Mixer"}, + {"VoiceMMode1_Tx Mixer", "AUX_PCM_TX_MMode1", "AUX_PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "SEC_AUX_PCM_TX_MMode1", "SEC_AUX_PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "TERT_AUX_PCM_TX_MMode1", "TERT_AUX_PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "QUAT_AUX_PCM_TX_MMode1", "QUAT_AUX_PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "QUIN_AUX_PCM_TX_MMode1", "QUIN_AUX_PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "SEN_AUX_PCM_TX_MMode1", "SEN_AUX_PCM_TX"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Audio Mixer"}, + {"VoiceMMode2_Tx Mixer", "AUX_PCM_TX_MMode2", "AUX_PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "SEC_AUX_PCM_TX_MMode2", "SEC_AUX_PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "TERT_AUX_PCM_TX_MMode2", "TERT_AUX_PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "QUAT_AUX_PCM_TX_MMode2", "QUAT_AUX_PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "QUIN_AUX_PCM_TX_MMode2", "QUIN_AUX_PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "SEN_AUX_PCM_TX_MMode2", "SEN_AUX_PCM_TX"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0 Audio Mixer"}, + {"Voip_Tx Mixer", "AUX_PCM_TX_Voip", "AUX_PCM_TX"}, + {"Voip_Tx Mixer", "SEC_AUX_PCM_TX_Voip", "SEC_AUX_PCM_TX"}, + {"Voip_Tx Mixer", "TERT_AUX_PCM_TX_Voip", "TERT_AUX_PCM_TX"}, + {"Voip_Tx Mixer", "QUAT_AUX_PCM_TX_Voip", "QUAT_AUX_PCM_TX"}, + {"Voip_Tx Mixer", "QUIN_AUX_PCM_TX_Voip", "QUIN_AUX_PCM_TX"}, + {"Voip_Tx Mixer", "SEN_AUX_PCM_TX_Voip", "SEN_AUX_PCM_TX"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUIN_TDM_TX_0", NULL, "QUIN_TDM_TX_0 Audio Mixer"}, + {"QCHAT_Tx Mixer", "AUX_PCM_TX_QCHAT", "AUX_PCM_TX"}, + {"QCHAT_Tx Mixer", "SEC_AUX_PCM_TX_QCHAT", "SEC_AUX_PCM_TX"}, + {"QCHAT_Tx Mixer", "TERT_AUX_PCM_TX_QCHAT", "TERT_AUX_PCM_TX"}, + {"QCHAT_Tx Mixer", "QUAT_AUX_PCM_TX_QCHAT", "QUAT_AUX_PCM_TX"}, + {"QCHAT_Tx Mixer", "QUIN_AUX_PCM_TX_QCHAT", "QUIN_AUX_PCM_TX"}, + {"QCHAT_Tx Mixer", "SEN_AUX_PCM_TX_QCHAT", "SEN_AUX_PCM_TX"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1 Audio Mixer"}, + {"Voice2 Stub Tx Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2 Audio Mixer"}, + /* connect to INT4_MI2S_DL_HL since same pcm_id */ - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Audio Mixer"}, + {"INTHFP_UL_HL", NULL, "HFP_PRI_AUX_UL_HL"}, + {"HFP_PRI_AUX_UL_HL", "Switch", "AUX_PCM_TX"}, + {"INTHFP_UL_HL", NULL, "HFP_AUX_UL_HL"}, + {"HFP_AUX_UL_HL", "Switch", "SEC_AUX_PCM_TX"}, + {"AUX_PCM_RX", NULL, "AUXPCM_DL_HL"}, + {"AUX_PCM_RX", NULL, "INTHFP_DL_HL"}, + {"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_DL_HL"}, + {"AUXPCM_UL_HL", NULL, "AUX_PCM_TX"}, + {"SEC_AUXPCM_UL_HL", NULL, "SEC_AUX_PCM_TX"}, + + {"AUX_PCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"AUX_PCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"AUX_PCM_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"AUX_PCM_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"AUX_PCM_RX Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"AUX_PCM_RX Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"AUX_PCM_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUX_PCM_RX", NULL, "AUX_PCM_RX Port Mixer"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEN_TDM_RX_0", NULL, "SEN_TDM_RX_0 Audio Mixer"}, + {"SEC_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_AUXPCM_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SEC_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"SEC_AUXPCM_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_RX Port Mixer"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEN_TDM_TX_0", NULL, "SEN_TDM_TX_0 Audio Mixer"}, + {"TERT_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"TERT_AUXPCM_RX Port Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, + {"TERT_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"TERT_AUX_PCM_RX", NULL, "TERT_AUXPCM_RX Port Mixer"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEN_TDM_RX_1", NULL, "SEN_TDM_RX_1 Audio Mixer"}, + {"QUAT_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUAT_AUXPCM_RX Port Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"QUAT_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUXPCM_RX Port Mixer"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEN_TDM_RX_2", NULL, "SEN_TDM_RX_2 Audio Mixer"}, + {"QUIN_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUIN_AUXPCM_RX Port Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, + {"QUIN_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUXPCM_RX Port Mixer"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEN_TDM_RX_3", NULL, "SEN_TDM_RX_3 Audio Mixer"}, + {"Voice Stub Tx Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "SEN_AUXPCM_UL_TX", "SEN_AUX_PCM_TX"}, - {"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"}, - {"MultiMedia1 Mixer", "MI2S_TX", "MI2S_TX"}, - {"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"}, - {"MultiMedia3 Mixer", "MI2S_TX", "MI2S_TX"}, - {"MultiMedia5 Mixer", "MI2S_TX", "MI2S_TX"}, - {"MultiMedia10 Mixer", "MI2S_TX", "MI2S_TX"}, - {"MultiMedia16 Mixer", "MI2S_TX", "MI2S_TX"}, - {"MultiMedia1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia1 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"MultiMedia2 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"MultiMedia1 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"MultiMedia2 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"MultiMedia1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia1 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, - {"MultiMedia2 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, - {"MultiMedia1 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia2 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia1 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"MultiMedia3 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, - {"MultiMedia5 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"MultiMedia10 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, - {"MultiMedia1 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia2 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia3 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia5 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia10 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia16 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, - {"MultiMedia16 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia1 Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, - {"MultiMedia3 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, - {"MultiMedia5 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, - {"MultiMedia10 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, - {"MultiMedia1 Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, - {"MultiMedia3 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, - {"MultiMedia5 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, - {"MultiMedia10 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, - {"MultiMedia16 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, - {"MultiMedia1 Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, - {"MultiMedia3 Mixer", "QUIN_AUX_PCM_TX", "QUIN_AUX_PCM_TX"}, - {"MultiMedia5 Mixer", "QUIN_AUX_PCM_TX", "QUIN_AUX_PCM_TX"}, - {"MultiMedia1 Mixer", "SEN_AUXPCM_UL_TX", "SEN_AUX_PCM_TX"}, - {"MultiMedia3 Mixer", "SEN_AUX_PCM_TX", "SEN_AUX_PCM_TX"}, - {"MultiMedia5 Mixer", "SEN_AUX_PCM_TX", "SEN_AUX_PCM_TX"}, - {"MultiMedia2 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia2 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, - {"MultiMedia2 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia2 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"MultiMedia1 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia1 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia2 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia6 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia6 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia6 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia10 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia6 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, - {"MultiMedia3 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, - {"MultiMedia5 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, - {"MultiMedia10 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, - {"MultiMedia16 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, - {"MultiMedia6 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia10 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia16 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia17 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia18 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia19 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia28 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia29 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia30 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia6 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"MultiMedia6 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia6 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia6 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"MultiMedia5 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"MultiMedia6 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"MultiMedia5 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, + {"SLIMBUS_1_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SLIMBUS_3_RX Port Mixer", "AUX_PCM_RX", "AUX_PCM_RX"}, + {"SLIMBUS_6_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + + /* Backend Enablement */ + {"BE_OUT", NULL, "AUX_PCM_RX"}, + {"BE_OUT", NULL, "SEC_AUX_PCM_RX"}, + {"BE_OUT", NULL, "TERT_AUX_PCM_RX"}, + {"BE_OUT", NULL, "QUAT_AUX_PCM_RX"}, + {"BE_OUT", NULL, "QUIN_AUX_PCM_RX"}, + {"BE_OUT", NULL, "SEN_AUX_PCM_RX"}, + + {"AUX_PCM_TX", NULL, "BE_IN"}, + {"SEC_AUX_PCM_TX", NULL, "BE_IN"}, + {"TERT_AUX_PCM_TX", NULL, "BE_IN"}, + {"QUAT_AUX_PCM_TX", NULL, "BE_IN"}, + {"QUIN_AUX_PCM_TX", NULL, "BE_IN"}, + {"SEN_AUX_PCM_TX", NULL, "BE_IN"}, +}; +#endif + +#ifndef CONFIG_TDM_DISABLE +static const struct snd_soc_dapm_route intercon_tdm[] = { + /* incall */ + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Audio Mixer"}, + + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Audio Mixer"}, - {"MultiMedia1 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia1 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia1 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia1 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia1 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia1 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia1 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia1 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia1 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia1 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia1 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia1 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia1 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia1 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia1 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia1 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia1 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia1 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia1 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia1 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia1 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia1 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia1 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia1 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia1 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia1 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia1 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Audio Mixer"}, - {"MultiMedia2 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia2 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia2 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia2 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia2 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia2 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia2 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia2 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia2 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia2 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia2 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia2 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia2 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia2 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia2 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia2 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia2 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia2 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia2 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia2 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia2 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia2 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia2 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia2 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia2 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia2 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia2 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Audio Mixer"}, - {"MultiMedia3 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia3 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia3 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia3 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia3 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia3 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia3 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia3 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia3 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia3 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia3 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia3 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia3 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia3 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia3 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia3 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia3 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia3 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia3 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia3 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia3 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia3 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia3 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia3 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia3 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia3 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia3 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"PRI_TDM_TX_0", NULL, "PRI_TDM_TX_0 Audio Mixer"}, + + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Audio Mixer"}, + + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Audio Mixer"}, + + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Audio Mixer"}, - {"MultiMedia4 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia4 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia4 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia4 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia4 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia4 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia4 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia4 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia4 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia4 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia4 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia4 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia4 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia4 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia4 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia4 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia4 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia4 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia4 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia4 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia4 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia4 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia4 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia4 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia4 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia4 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia4 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Audio Mixer"}, - {"MultiMedia5 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia5 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia5 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia5 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia5 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia5 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia5 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia5 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia5 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia5 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia5 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia5 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia5 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia5 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia5 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia5 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia5 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia5 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia5 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia5 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia5 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia5 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia5 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia5 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia5 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia5 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia5 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"SEC_TDM_TX_0", NULL, "SEC_TDM_TX_0 Audio Mixer"}, - {"MultiMedia6 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia6 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia6 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia6 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia6 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia6 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia6 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia6 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia6 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia6 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia6 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia6 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia6 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia6 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia6 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia6 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia6 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia6 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia6 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia6 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia6 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia6 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia6 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia6 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia6 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia6 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia6 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Audio Mixer"}, - {"MultiMedia8 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia8 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia8 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia8 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia8 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia8 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia8 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia8 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia8 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia8 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia8 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia8 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia8 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia8 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia8 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia8 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia8 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia8 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia8 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia8 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia8 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia8 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia8 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia8 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia8 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia8 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia8 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"TERT_TDM_TX_0", NULL, "TERT_TDM_TX_0 Audio Mixer"}, + + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Audio Mixer"}, - {"MultiMedia9 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia9 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia9 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia9 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia9 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia9 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia9 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia9 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia9 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia9 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia9 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia9 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia9 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia9 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia9 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia9 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia9 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia9 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia9 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia9 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Audio Mixer"}, - {"MultiMedia10 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia10 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia10 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia10 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia10 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia10 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia10 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia10 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia10 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Audio Mixer"}, - {"MultiMedia20 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia20 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia20 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia20 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia20 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"MultiMedia20 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"MultiMedia20 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia20 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia20 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia20 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia20 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia20 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia20 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia20 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia20 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia20 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia20 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia20 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia20 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia20 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia20 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia20 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia20 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia20 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia20 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia20 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia20 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia20 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia20 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia20 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia20 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia20 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia20 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"TERT_TDM_RX_4", NULL, "TERT_TDM_RX_4 Audio Mixer"}, - {"MultiMedia21 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"MultiMedia21 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia21 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia21 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia21 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia21 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia21 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia21 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia21 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia21 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia21 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia21 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia21 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia21 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia21 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia21 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia21 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia21 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia21 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia21 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia21 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia21 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia21 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia21 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia21 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia21 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia21 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia21 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia21 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Audio Mixer"}, + + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUAT_TDM_TX_0", NULL, "QUAT_TDM_TX_0 Audio Mixer"}, - {"MultiMedia22 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia22 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia22 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia22 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia22 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia22 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia22 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia22 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia22 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia22 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia22 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia22 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia22 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia22 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia22 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia22 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia22 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia22 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia22 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia22 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Audio Mixer"}, - {"MultiMedia23 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia23 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia23 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia23 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia23 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia23 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia23 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia23 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia23 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia23 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia23 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia23 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia23 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia23 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia23 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia23 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia23 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia23 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia23 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia23 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Audio Mixer"}, - {"MultiMedia24 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia24 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia24 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia24 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia24 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia24 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia24 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia24 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia24 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia24 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia24 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia24 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia24 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia24 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia24 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia24 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia24 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia24 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia24 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia24 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Audio Mixer"}, - {"MultiMedia25 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia25 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia25 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia25 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia25 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia25 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia25 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia25 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia25 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia25 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia25 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia25 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia25 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia25 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia25 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia25 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia25 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia25 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia25 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia25 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0 Audio Mixer"}, - {"MultiMedia27 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia27 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia27 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, - {"MultiMedia27 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"MultiMedia27 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"MultiMedia27 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia27 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia27 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia27 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia27 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"MultiMedia27 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"MultiMedia27 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia27 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia27 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUIN_TDM_TX_0", NULL, "QUIN_TDM_TX_0 Audio Mixer"}, + + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1 Audio Mixer"}, + + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2 Audio Mixer"}, - {"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"MultiMedia4 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"MultiMedia5 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"MultiMedia6 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"MultiMedia8 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"MultiMedia10 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Audio Mixer"}, - {"MultiMedia16 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia16 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia16 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia16 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia16 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia16 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia16 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia16 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia16 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia16 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia16 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia16 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia16 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia16 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia16 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia16 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia16 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia16 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia16 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia16 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEN_TDM_RX_0", NULL, "SEN_TDM_RX_0 Audio Mixer"}, - {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia17 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_TDM_TX_0", NULL, "SEN_TDM_TX_0 Audio Mixer"}, - {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia18 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia18 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia18 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEN_TDM_RX_1", NULL, "SEN_TDM_RX_1 Audio Mixer"}, - {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia19 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia19 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia19 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEN_TDM_RX_2", NULL, "SEN_TDM_RX_2 Audio Mixer"}, - {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia28 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia28 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia28 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEN_TDM_RX_3", NULL, "SEN_TDM_RX_3 Audio Mixer"}, - {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia29 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia29 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia29 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia1 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia1 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia1 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia1 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia1 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia1 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia1 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia1 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia1 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia1 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia1 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia1 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia1 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia1 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia1 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia1 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia30 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia30 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia30 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia1 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia1 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia1 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia1 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia1 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia1 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia1 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia1 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + + {"MultiMedia2 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia2 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia2 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia2 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia2 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia2 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia2 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia2 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia2 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia2 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia2 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia2 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia2 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia2 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia2 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia2 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia2 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia2 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia2 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia2 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia2 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia2 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia2 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia2 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia6", "MM_UL6"}, - {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"}, + {"MultiMedia3 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia3 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia3 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia3 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia3 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia3 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia3 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia3 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia3 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia3 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia3 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia3 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia3 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia3 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia3 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia3 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia3 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia3 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia3 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia3 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia3 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia3 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia3 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia3 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia6", "MM_UL6"}, - {"INT_BT_A2DP_RX", NULL, "INTERNAL_A2DP_RX Audio Mixer"}, + {"MultiMedia4 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia4 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia4 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia4 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia4 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia4 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia4 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia4 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia4 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia4 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia4 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia4 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia4 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia4 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia4 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia4 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia4 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia4 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia4 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia4 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia4 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia4 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia4 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia4 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"}, + {"MultiMedia5 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia5 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia5 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia5 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia5 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia5 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia5 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia5 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia5 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia5 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia5 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia5 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia5 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia5 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia5 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia5 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia5 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia5 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia5 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia5 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia5 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia5 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia5 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia5 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"}, + {"MultiMedia6 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia6 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia6 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia6 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia6 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia6 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia6 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia6 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia6 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia6 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia6 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia6 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia6 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia6 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia6 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia6 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia6 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia6 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia6 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia6 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia6 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia6 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia6 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia6 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia3 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia4 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia10 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia17 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia18 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia19 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia28 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia29 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia30 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia5 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia8 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia16 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia4 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia16 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia17 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia18 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia19 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia28 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia29 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia30 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia5 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia6 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia8 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia8 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia8 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia8 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia8 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia8 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia8 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia8 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia8 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia8 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia8 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia8 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia8 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia8 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia8 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia8 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia8 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia8 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia8 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia8 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia8 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia8 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia8 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia8 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia8 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia3 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia4 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia10 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia17 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia18 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia19 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia28 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia29 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia30 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia5 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia8 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia16 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MM_UL1", NULL, "MultiMedia1 Mixer"}, - {"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MM_UL2", NULL, "MultiMedia2 Mixer"}, - {"MM_UL3", NULL, "MultiMedia3 Mixer"}, - {"MM_UL4", NULL, "MultiMedia4 Mixer"}, - {"MM_UL5", NULL, "MultiMedia5 Mixer"}, - {"MM_UL6", NULL, "MultiMedia6 Mixer"}, - {"MM_UL8", NULL, "MultiMedia8 Mixer"}, - {"MM_UL9", NULL, "MultiMedia9 Mixer"}, - {"MM_UL10", NULL, "MultiMedia10 Mixer"}, - {"MM_UL16", NULL, "MultiMedia16 Mixer"}, - {"MM_UL17", NULL, "MultiMedia17 Mixer"}, - {"MM_UL18", NULL, "MultiMedia18 Mixer"}, - {"MM_UL19", NULL, "MultiMedia19 Mixer"}, - {"MM_UL20", NULL, "MultiMedia20 Mixer"}, - {"MM_UL21", NULL, "MultiMedia21 Mixer"}, - {"MM_UL22", NULL, "MultiMedia22 Mixer"}, - {"MM_UL23", NULL, "MultiMedia23 Mixer"}, - {"MM_UL24", NULL, "MultiMedia24 Mixer"}, - {"MM_UL25", NULL, "MultiMedia25 Mixer"}, - {"MM_UL27", NULL, "MultiMedia27 Mixer"}, - {"MM_UL28", NULL, "MultiMedia28 Mixer"}, - {"MM_UL29", NULL, "MultiMedia29 Mixer"}, - {"MM_UL30", NULL, "MultiMedia30 Mixer"}, + {"MultiMedia9 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia9 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia9 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia9 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia9 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia9 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia9 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia9 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia9 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia9 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia9 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia9 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia9 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia9 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia9 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia9 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"}, + {"MultiMedia10 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia10 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia10 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia10 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia10 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia10 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia10 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia10 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX Audio Mixer"}, + {"MultiMedia20 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia20 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia20 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia20 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia20 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia20 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia20 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia20 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia20 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia20 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia20 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia20 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia20 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia20 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia20 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia20 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia20 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia20 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia20 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia20 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia20 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia20 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia20 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia20 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"TERT_AUX_PCM_RX", NULL, "TERT_AUX_PCM_RX Audio Mixer"}, + {"MultiMedia21 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia21 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia21 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia21 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia21 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia21 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia21 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia21 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia21 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia21 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia21 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia21 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia21 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia21 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia21 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia21 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia21 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia21 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia21 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia21 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia21 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia21 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia21 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia21 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUX_PCM_RX Audio Mixer"}, + {"MultiMedia22 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia22 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia22 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia22 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia22 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia22 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia22 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia22 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia22 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia22 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia22 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia22 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia22 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia22 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia22 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia22 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia22 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia22 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia22 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia22 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUX_PCM_RX Audio Mixer"}, + {"MultiMedia23 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia23 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia23 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia23 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia23 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia23 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia23 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia23 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia23 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia23 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia23 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia23 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia23 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia23 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia23 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia23 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia23 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia23 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia23 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia23 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEN_AUX_PCM_RX", NULL, "SEN_AUX_PCM_RX Audio Mixer"}, + {"MultiMedia24 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia24 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia24 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia24 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia24 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia24 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia24 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia24 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia24 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia24 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia24 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia24 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia24 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia24 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia24 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia24 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia24 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia24 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia24 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia24 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"PRI_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"PRI_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"PRI_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"}, + {"MultiMedia25 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia25 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia25 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia25 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia25 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia25 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia25 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia25 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia25 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia25 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia25 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia25 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia25 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia25 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia25 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia25 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia25 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia25 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia25 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia25 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SEC_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SEC_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"}, + {"MultiMedia16 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia16 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia16 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia16 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia16 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia16 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia16 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia16 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia16 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia16 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia16 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia16 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia16 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia16 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia16 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia16 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEC_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SEC_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"SEC_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"SEC_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SEC_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SEC_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SEC_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX_Voice Mixer"}, + {"PRI_TDM_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_TDM_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0_Voice Mixer"}, - {"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SLIM_0_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SLIM_0_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SLIM_0_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SLIM_0_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"}, + {"PRI_TDM_RX_1_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_TDM_RX_1_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1_Voice Mixer"}, - {"SLIM_6_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SLIM_6_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SLIM_6_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SLIM_6_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SLIM_6_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SLIMBUS_6_RX", NULL, "SLIM_6_RX_Voice Mixer"}, + {"PRI_TDM_RX_2_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2_Voice Mixer"}, - {"USB_AUDIO_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"USB_AUDIO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"USB_AUDIO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"USB_AUDIO_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"USB_AUDIO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX_Voice Mixer"}, + {"PRI_TDM_RX_3_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_TDM_RX_3_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3_Voice Mixer"}, - {"DISPLAY_PORT_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"DISPLAY_PORT_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"DISPLAY_PORT_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"DISPLAY_PORT_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"DISPLAY_PORT_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"DISPLAY_PORT", NULL, "DISPLAY_PORT_RX_Voice Mixer"}, + {"QUAT_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_Voice Mixer"}, - {"DISPLAY_PORT_RX1_Voice Mixer", "Voip", "VOIP_DL"}, - {"DISPLAY_PORT_RX1_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"DISPLAY_PORT_RX1_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"DISPLAY_PORT_RX1_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"DISPLAY_PORT_RX1_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"DISPLAY_PORT1", NULL, "DISPLAY_PORT_RX1_Voice Mixer"}, + {"QUIN_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2_Voice Mixer"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"}, + {"VoiceMMode1_Tx Mixer", "QUAT_TDM_TX_0_MMode1", "QUAT_TDM_TX_0"}, + {"VoiceMMode2_Tx Mixer", "PRI_TDM_TX_3_MMode2", "PRI_TDM_TX_3"}, + {"VoiceMMode1_Tx Mixer", "PRI_TDM_TX_3_MMode1", "PRI_TDM_TX_3"}, - {"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"AFE_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"AFE_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"AFE_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"AFE_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"}, + {"VOC_EXT_EC MUX", "PRI_TDM_TX", "PRI_TDM_TX_0"}, + {"VOC_EXT_EC MUX", "SEC_TDM_TX", "SEC_TDM_TX_0"}, - {"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"}, + {"PRI_TDM_TX_0_UL_HL", NULL, "PRI_TDM_TX_0"}, + {"PRI_TDM_TX_1_UL_HL", NULL, "PRI_TDM_TX_1"}, + {"PRI_TDM_TX_2_UL_HL", NULL, "PRI_TDM_TX_2"}, + {"PRI_TDM_TX_3_UL_HL", NULL, "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0_DL_HL"}, + {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1_DL_HL"}, + {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2_DL_HL"}, + {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3_DL_HL"}, + {"SEC_TDM_TX_0_UL_HL", NULL, "SEC_TDM_TX_0"}, + {"SEC_TDM_TX_1_UL_HL", NULL, "SEC_TDM_TX_1"}, + {"SEC_TDM_TX_2_UL_HL", NULL, "SEC_TDM_TX_2"}, + {"SEC_TDM_TX_3_UL_HL", NULL, "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0_DL_HL"}, + {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1_DL_HL"}, + {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2_DL_HL"}, + {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3_DL_HL"}, + {"SEC_TDM_RX_7", NULL, "SEC_TDM_RX_7_DL_HL"}, + {"TERT_TDM_TX_0_UL_HL", NULL, "TERT_TDM_TX_0"}, + {"TERT_TDM_TX_1_UL_HL", NULL, "TERT_TDM_TX_1"}, + {"TERT_TDM_TX_2_UL_HL", NULL, "TERT_TDM_TX_2"}, + {"TERT_TDM_TX_3_UL_HL", NULL, "TERT_TDM_TX_3"}, + {"TERT_TDM_TX_7_UL_HL", NULL, "TERT_TDM_TX_7"}, + {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0_DL_HL"}, + {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1_DL_HL"}, + {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2_DL_HL"}, + {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3_DL_HL"}, + {"QUAT_TDM_TX_0_UL_HL", NULL, "QUAT_TDM_TX_0"}, + {"QUAT_TDM_TX_1_UL_HL", NULL, "QUAT_TDM_TX_1"}, + {"QUAT_TDM_TX_2_UL_HL", NULL, "QUAT_TDM_TX_2"}, + {"QUAT_TDM_TX_3_UL_HL", NULL, "QUAT_TDM_TX_3"}, + {"QUAT_TDM_TX_7_UL_HL", NULL, "QUAT_TDM_TX_7"}, + {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0_DL_HL"}, + {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1_DL_HL"}, + {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_DL_HL"}, + {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3_DL_HL"}, + {"QUAT_TDM_RX_7", NULL, "QUAT_TDM_RX_7_DL_HL"}, + {"QUIN_TDM_TX_0_UL_HL", NULL, "QUIN_TDM_TX_0"}, + {"QUIN_TDM_TX_1_UL_HL", NULL, "QUIN_TDM_TX_1"}, + {"QUIN_TDM_TX_2_UL_HL", NULL, "QUIN_TDM_TX_2"}, + {"QUIN_TDM_TX_3_UL_HL", NULL, "QUIN_TDM_TX_3"}, + {"QUIN_TDM_TX_7_UL_HL", NULL, "QUIN_TDM_TX_7"}, + {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0_DL_HL"}, + {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1_DL_HL"}, + {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2_DL_HL"}, + {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3_DL_HL"}, + {"QUIN_TDM_RX_7", NULL, "QUIN_TDM_RX_7_DL_HL"}, + {"SEN_TDM_TX_0_UL_HL", NULL, "SEN_TDM_TX_0"}, + {"SEN_TDM_TX_1_UL_HL", NULL, "SEN_TDM_TX_1"}, + {"SEN_TDM_TX_2_UL_HL", NULL, "SEN_TDM_TX_2"}, + {"SEN_TDM_TX_3_UL_HL", NULL, "SEN_TDM_TX_3"}, + {"SEN_TDM_RX_0", NULL, "SEN_TDM_RX_0_DL_HL"}, + {"SEN_TDM_RX_1", NULL, "SEN_TDM_RX_1_DL_HL"}, + {"SEN_TDM_RX_2", NULL, "SEN_TDM_RX_2_DL_HL"}, + {"SEN_TDM_RX_3", NULL, "SEN_TDM_RX_3_DL_HL"}, - {"SEC_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SEC_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SEC_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SEC_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SEC_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX_Voice Mixer"}, + #ifndef CONFIG_MI2S_DISABLE + {"PRI_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"PRI_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"PRI_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Port Mixer"}, - {"TERT_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"TERT_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"TERT_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"TERT_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"TERT_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"TERT_AUX_PCM_RX", NULL, "TERT_AUX_PCM_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"PRI_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"PRI_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"PRI_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Port Mixer"}, + +#ifndef CONFIG_MI2S_DISABLE + {"PRI_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"PRI_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"PRI_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Port Mixer"}, - {"QUAT_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"QUAT_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"QUAT_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"QUAT_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"QUAT_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUX_PCM_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"PRI_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"PRI_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"PRI_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Port Mixer"}, - {"QUIN_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"QUIN_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"QUIN_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"QUIN_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"QUIN_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUX_PCM_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"SEC_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"SEC_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"SEC_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Port Mixer"}, - {"SEN_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SEN_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SEN_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SEN_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SEN_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SEN_AUX_PCM_RX", NULL, "SEN_AUX_PCM_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"SEC_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"SEC_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"SEC_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Port Mixer"}, - {"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"HDMI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"HDMI_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"HDMI_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"HDMI_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"HDMI", NULL, "HDMI_RX_Voice Mixer"}, - {"HDMI", NULL, "HDMI_DL_HL"}, +#ifndef CONFIG_MI2S_DISABLE + {"SEC_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"SEC_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"SEC_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Port Mixer"}, - {"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"SEC_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"SEC_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"SEC_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Port Mixer"}, - {"PRI_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"PRI_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"PRI_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"PRI_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"PRI_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"PRI_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_Voice Mixer"}, + {"SEC_TDM_RX_7 Port Mixer", "TERT_TDM_TX_7", "TERT_TDM_TX_7"}, + {"SEC_TDM_RX_7", NULL, "SEC_TDM_RX_7 Port Mixer"}, - {"INT0_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"INT0_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"INT0_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"INT0_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"INT0_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"TERT_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"TERT_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"TERT_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Port Mixer"}, - {"INT4_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"INT4_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"INT4_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"INT4_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"INT4_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"TERT_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"TERT_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"TERT_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Port Mixer"}, - {"TERT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"TERT_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"TERT_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"TERT_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"TERT_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"TERT_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"TERT_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX_Voice Mixer"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"TERT_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"TERT_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"TERT_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Port Mixer"}, - {"QUAT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"QUAT_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"QUAT_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"QUAT_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"QUAT_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"QUAT_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"TERT_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"TERT_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"TERT_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Port Mixer"}, - {"QUIN_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"QUIN_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"QUIN_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"QUIN_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"QUIN_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"QUIN_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"QUAT_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"QUAT_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"QUAT_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Port Mixer"}, - {"PRI_TDM_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_TDM_RX_0_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, - {"PRI_TDM_RX_0_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"PRI_TDM_RX_0_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"PRI_TDM_RX_0_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"PRI_TDM_RX_0_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"PRI_TDM_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"PRI_TDM_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"QUAT_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"QUAT_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"QUAT_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Port Mixer"}, - {"PRI_TDM_RX_1_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_TDM_RX_1_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, - {"PRI_TDM_RX_1_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"PRI_TDM_RX_1_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"PRI_TDM_RX_1_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"PRI_TDM_RX_1_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"PRI_TDM_RX_1_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"PRI_TDM_RX_1_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"QUAT_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"QUAT_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"QUAT_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Port Mixer"}, - {"PRI_TDM_RX_2_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_TDM_RX_2_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, - {"PRI_TDM_RX_2_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"PRI_TDM_RX_2_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"PRI_TDM_RX_2_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"PRI_TDM_RX_2_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"PRI_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"PRI_TDM_RX_2_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"QUAT_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"QUAT_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"QUAT_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Port Mixer"}, - {"PRI_TDM_RX_3_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_TDM_RX_3_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, - {"PRI_TDM_RX_3_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"PRI_TDM_RX_3_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"PRI_TDM_RX_3_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"PRI_TDM_RX_3_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"PRI_TDM_RX_3_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"PRI_TDM_RX_3_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3_Voice Mixer"}, + {"QUAT_TDM_RX_7 Port Mixer", "QUAT_TDM_TX_7", "QUAT_TDM_TX_7"}, + {"QUAT_TDM_RX_7 Port Mixer", "QUIN_TDM_TX_7", "QUIN_TDM_TX_7"}, + {"QUAT_TDM_RX_7", NULL, "QUAT_TDM_RX_7 Port Mixer"}, - {"SEN_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SEN_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SEN_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SEN_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"QUIN_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"QUIN_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"QUIN_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0 Port Mixer"}, - {"QUAT_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"QUIN_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"QUIN_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"QUIN_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1 Port Mixer"}, - {"QUIN_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"QUIN_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"QUIN_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"QUIN_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2 Port Mixer"}, - {"WSA_CDC_DMA_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, - {"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"QUIN_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"QUIN_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"QUIN_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Port Mixer"}, - {"PROXY_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"PROXY_RX", NULL, "PROXY_RX_Voice Mixer"}, + {"QUIN_TDM_RX_7 Port Mixer", "TERT_TDM_TX_7", "TERT_TDM_TX_7"}, + {"QUIN_TDM_RX_7 Port Mixer", "QUAT_TDM_TX_7", "QUAT_TDM_TX_7"}, + {"QUIN_TDM_RX_7 Port Mixer", "QUIN_TDM_TX_7", "QUIN_TDM_TX_7"}, + {"QUIN_TDM_RX_7", NULL, "QUIN_TDM_RX_7 Port Mixer"}, - {"PROXY_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"PROXY_RX", NULL, "PROXY_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"SEN_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"SEN_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"SEN_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEN_TDM_RX_0", NULL, "SEN_TDM_RX_0 Port Mixer"}, - {"RX_CDC_DMA_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, - {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"SEN_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"SEN_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"SEN_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEN_TDM_RX_1", NULL, "SEN_TDM_RX_1 Port Mixer"}, - {"RX_CDC_DMA_RX_1_Voice Mixer", "Voip", "VOIP_DL"}, - {"RX_CDC_DMA_RX_1_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"RX_CDC_DMA_RX_1_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"SEN_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"SEN_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"SEN_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEN_TDM_RX_2", NULL, "SEN_TDM_RX_2 Port Mixer"}, - {"VOC_EXT_EC MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"VOC_EXT_EC MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"VOC_EXT_EC MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"VOC_EXT_EC MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"VOC_EXT_EC MUX", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"VOC_EXT_EC MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"VOC_EXT_EC MUX", "PRI_TDM_TX", "PRI_TDM_TX_0"}, - {"VOC_EXT_EC MUX", "SEC_TDM_TX", "SEC_TDM_TX_0"}, - {"VOIP_UL", NULL, "VOC_EXT_EC MUX"}, - {"VOICEMMODE1_UL", NULL, "VOC_EXT_EC MUX"}, - {"VOICEMMODE2_UL", NULL, "VOC_EXT_EC MUX"}, +#ifndef CONFIG_MI2S_DISABLE + {"SEN_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"SEN_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"SEN_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEN_TDM_RX_3", NULL, "SEN_TDM_RX_3 Port Mixer"}, - {"AUDIO_REF_EC_UL1 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL1 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL1 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL1 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"AUDIO_REF_EC_UL1 MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_0", "QUAT_TDM_RX_0"}, {"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_1", "QUAT_TDM_RX_1"}, - {"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_2", "QUAT_TDM_RX_2"}, - {"AUDIO_REF_EC_UL1 MUX", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"AUDIO_REF_EC_UL1 MUX", "TERT_TDM_RX_2", "TERT_TDM_RX_2"}, - {"AUDIO_REF_EC_UL1 MUX", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"AUDIO_REF_EC_UL1 MUX", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - - {"AUDIO_REF_EC_UL2 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL2 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL2 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL2 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL3 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL3 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL3 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL3 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL4 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL4 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL4 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL4 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL5 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL5 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL5 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL5 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL6 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL6 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL6 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL6 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL8 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL8 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL8 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL8 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL9 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL9 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL9 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL9 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_2", "QUAT_TDM_RX_2"}, + {"AUDIO_REF_EC_UL1 MUX", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"AUDIO_REF_EC_UL1 MUX", "TERT_TDM_RX_2", "TERT_TDM_RX_2"}, + {"AUDIO_REF_EC_UL1 MUX", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"AUDIO_REF_EC_UL1 MUX", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"AUDIO_REF_EC_UL10 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL10 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL10 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL10 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"AUDIO_REF_EC_UL10 MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_0", "QUAT_TDM_RX_0"}, {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_1", "QUAT_TDM_RX_1"}, @@ -28128,1103 +29243,645 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUDIO_REF_EC_UL10 MUX", "TERT_TDM_RX_2", "TERT_TDM_RX_2"}, {"AUDIO_REF_EC_UL10 MUX", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"AUDIO_REF_EC_UL16 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL16 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL16 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL16 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL17 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL17 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL17 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL17 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL18 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL18 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL18 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL18 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL19 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL19 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL19 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL19 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL28 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL28 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL28 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL28 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL29 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL29 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL29 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL29 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"LSM1_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"LSM2_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"LSM3_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"LSM4_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"LSM5_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"LSM6_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"LSM7_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"LSM8_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - - {"MM_UL1", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"MM_UL2", NULL, "AUDIO_REF_EC_UL2 MUX"}, - {"MM_UL3", NULL, "AUDIO_REF_EC_UL3 MUX"}, - {"MM_UL4", NULL, "AUDIO_REF_EC_UL4 MUX"}, - {"MM_UL5", NULL, "AUDIO_REF_EC_UL5 MUX"}, - {"MM_UL6", NULL, "AUDIO_REF_EC_UL6 MUX"}, - {"MM_UL8", NULL, "AUDIO_REF_EC_UL8 MUX"}, - {"MM_UL9", NULL, "AUDIO_REF_EC_UL9 MUX"}, - {"MM_UL10", NULL, "AUDIO_REF_EC_UL10 MUX"}, - {"MM_UL16", NULL, "AUDIO_REF_EC_UL16 MUX"}, - {"MM_UL17", NULL, "AUDIO_REF_EC_UL17 MUX"}, - {"MM_UL18", NULL, "AUDIO_REF_EC_UL18 MUX"}, - {"MM_UL19", NULL, "AUDIO_REF_EC_UL19 MUX"}, - {"MM_UL28", NULL, "AUDIO_REF_EC_UL28 MUX"}, - {"MM_UL29", NULL, "AUDIO_REF_EC_UL29 MUX"}, - {"MM_UL30", NULL, "AUDIO_REF_EC_UL30 MUX"}, - - {"VoiceMMode1_Tx Mixer", "PRI_TX_MMode1", "PRI_I2S_TX"}, - {"VoiceMMode1_Tx Mixer", "PRI_MI2S_TX_MMode1", "PRI_MI2S_TX"}, - {"VoiceMMode1_Tx Mixer", "MI2S_TX_MMode1", "MI2S_TX"}, - {"VoiceMMode1_Tx Mixer", "SEC_MI2S_TX_MMode1", "SEC_MI2S_TX"}, - {"VoiceMMode1_Tx Mixer", "TERT_MI2S_TX_MMode1", "TERT_MI2S_TX"}, - {"VoiceMMode1_Tx Mixer", "INT3_MI2S_TX_MMode1", "INT3_MI2S_TX"}, - {"VoiceMMode1_Tx Mixer", "SLIM_0_TX_MMode1", "SLIMBUS_0_TX"}, - {"VoiceMMode1_Tx Mixer", "SLIM_7_TX_MMode1", "SLIMBUS_7_TX"}, - {"VoiceMMode1_Tx Mixer", "SLIM_8_TX_MMode1", "SLIMBUS_8_TX"}, - {"VoiceMMode1_Tx Mixer", "USB_AUDIO_TX_MMode1", "USB_AUDIO_TX"}, - {"VoiceMMode1_Tx Mixer", "INT_BT_SCO_TX_MMode1", "INT_BT_SCO_TX"}, - {"VoiceMMode1_Tx Mixer", "AFE_PCM_TX_MMode1", "PCM_TX"}, - {"VoiceMMode1_Tx Mixer", "AUX_PCM_TX_MMode1", "AUX_PCM_TX"}, - {"VoiceMMode1_Tx Mixer", "SEC_AUX_PCM_TX_MMode1", "SEC_AUX_PCM_TX"}, - {"VoiceMMode1_Tx Mixer", "TERT_AUX_PCM_TX_MMode1", "TERT_AUX_PCM_TX"}, - {"VoiceMMode1_Tx Mixer", "QUAT_AUX_PCM_TX_MMode1", "QUAT_AUX_PCM_TX"}, - {"VoiceMMode1_Tx Mixer", "QUIN_AUX_PCM_TX_MMode1", "QUIN_AUX_PCM_TX"}, - {"VoiceMMode1_Tx Mixer", "SEN_AUX_PCM_TX_MMode1", "SEN_AUX_PCM_TX"}, - {"VoiceMMode1_Tx Mixer", "QUAT_TDM_TX_0_MMode1", "QUAT_TDM_TX_0"}, - {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_0_MMode1", "TX_CDC_DMA_TX_0"}, - {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_1_MMode1", "TX_CDC_DMA_TX_1"}, - {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_2_MMode1", "TX_CDC_DMA_TX_2"}, - {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_3_MMode1", "TX_CDC_DMA_TX_3"}, - {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_4_MMode1", "TX_CDC_DMA_TX_4"}, - {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_5_MMode1", "TX_CDC_DMA_TX_5"}, - {"VoiceMMode1_Tx Mixer", "QUAT_MI2S_TX_MMode1", "QUAT_MI2S_TX"}, - {"VoiceMMode1_Tx Mixer", "QUIN_MI2S_TX_MMode1", "QUIN_MI2S_TX"}, - {"VoiceMMode1_Tx Mixer", "PRI_TDM_TX_3_MMode1", "PRI_TDM_TX_3"}, - {"VoiceMMode1_Tx Mixer", "PROXY_TX_MMode1", "PROXY_TX"}, - {"VOICEMMODE1_UL", NULL, "VoiceMMode1_Tx Mixer"}, + {"LSM1 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM1 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"LSM2 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM2 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"LSM3 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM3 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"LSM4 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM4 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"LSM5 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM5 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"LSM6 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM6 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"LSM7 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM7 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"LSM8 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM8 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"VoiceMMode2_Tx Mixer", "PRI_TX_MMode2", "PRI_I2S_TX"}, - {"VoiceMMode2_Tx Mixer", "PRI_MI2S_TX_MMode2", "PRI_MI2S_TX"}, - {"VoiceMMode2_Tx Mixer", "SEC_MI2S_TX_MMode2", "SEC_MI2S_TX"}, - {"VoiceMMode2_Tx Mixer", "MI2S_TX_MMode2", "MI2S_TX"}, - {"VoiceMMode2_Tx Mixer", "TERT_MI2S_TX_MMode2", "TERT_MI2S_TX"}, - {"VoiceMMode2_Tx Mixer", "INT3_MI2S_TX_MMode2", "INT3_MI2S_TX"}, - {"VoiceMMode2_Tx Mixer", "SLIM_0_TX_MMode2", "SLIMBUS_0_TX"}, - {"VoiceMMode2_Tx Mixer", "SLIM_7_TX_MMode2", "SLIMBUS_7_TX"}, - {"VoiceMMode2_Tx Mixer", "SLIM_8_TX_MMode2", "SLIMBUS_8_TX"}, - {"VoiceMMode2_Tx Mixer", "USB_AUDIO_TX_MMode2", "USB_AUDIO_TX"}, - {"VoiceMMode2_Tx Mixer", "INT_BT_SCO_TX_MMode2", "INT_BT_SCO_TX"}, - {"VoiceMMode2_Tx Mixer", "AFE_PCM_TX_MMode2", "PCM_TX"}, - {"VoiceMMode2_Tx Mixer", "AUX_PCM_TX_MMode2", "AUX_PCM_TX"}, - {"VoiceMMode2_Tx Mixer", "SEC_AUX_PCM_TX_MMode2", "SEC_AUX_PCM_TX"}, - {"VoiceMMode2_Tx Mixer", "TERT_AUX_PCM_TX_MMode2", "TERT_AUX_PCM_TX"}, - {"VoiceMMode2_Tx Mixer", "QUAT_AUX_PCM_TX_MMode2", "QUAT_AUX_PCM_TX"}, - {"VoiceMMode2_Tx Mixer", "QUIN_AUX_PCM_TX_MMode2", "QUIN_AUX_PCM_TX"}, - {"VoiceMMode2_Tx Mixer", "SEN_AUX_PCM_TX_MMode2", "SEN_AUX_PCM_TX"}, - {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_0_MMode2", "TX_CDC_DMA_TX_0"}, - {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_1_MMode2", "TX_CDC_DMA_TX_1"}, - {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_2_MMode2", "TX_CDC_DMA_TX_2"}, - {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_3_MMode2", "TX_CDC_DMA_TX_3"}, - {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_4_MMode2", "TX_CDC_DMA_TX_4"}, - {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_5_MMode2", "TX_CDC_DMA_TX_5"}, - {"VoiceMMode2_Tx Mixer", "QUAT_MI2S_TX_MMode2", "QUAT_MI2S_TX"}, - {"VoiceMMode2_Tx Mixer", "QUIN_MI2S_TX_MMode2", "QUIN_MI2S_TX"}, - {"VoiceMMode2_Tx Mixer", "PRI_TDM_TX_3_MMode2", "PRI_TDM_TX_3"}, - {"VoiceMMode2_Tx Mixer", "PROXY_TX_MMode2", "PROXY_TX"}, - {"VOICEMMODE2_UL", NULL, "VoiceMMode2_Tx Mixer"}, + {"SLIMBUS_0_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SEN_AUXPCM_UL_TX", "SEN_AUX_PCM_TX"}, - {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"}, - {"Voip_Tx Mixer", "MI2S_TX_Voip", "MI2S_TX"}, - {"Voip_Tx Mixer", "SEC_MI2S_TX_Voip", "SEC_MI2S_TX"}, - {"Voip_Tx Mixer", "TERT_MI2S_TX_Voip", "TERT_MI2S_TX"}, - {"Voip_Tx Mixer", "INT3_MI2S_TX_Voip", "INT3_MI2S_TX"}, - {"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"}, - {"Voip_Tx Mixer", "SLIM_7_TX_Voip", "SLIMBUS_7_TX"}, - {"Voip_Tx Mixer", "SLIM_8_TX_Voip", "SLIMBUS_8_TX"}, - {"Voip_Tx Mixer", "USB_AUDIO_TX_Voip", "USB_AUDIO_TX"}, - {"Voip_Tx Mixer", "INTERNAL_BT_SCO_TX_Voip", "INT_BT_SCO_TX"}, - {"Voip_Tx Mixer", "AFE_PCM_TX_Voip", "PCM_TX"}, - {"Voip_Tx Mixer", "AUX_PCM_TX_Voip", "AUX_PCM_TX"}, - {"Voip_Tx Mixer", "SEC_AUX_PCM_TX_Voip", "SEC_AUX_PCM_TX"}, - {"Voip_Tx Mixer", "TERT_AUX_PCM_TX_Voip", "TERT_AUX_PCM_TX"}, - {"Voip_Tx Mixer", "QUAT_AUX_PCM_TX_Voip", "QUAT_AUX_PCM_TX"}, - {"Voip_Tx Mixer", "QUIN_AUX_PCM_TX_Voip", "QUIN_AUX_PCM_TX"}, - {"Voip_Tx Mixer", "SEN_AUX_PCM_TX_Voip", "SEN_AUX_PCM_TX"}, - {"Voip_Tx Mixer", "PRI_MI2S_TX_Voip", "PRI_MI2S_TX"}, - {"Voip_Tx Mixer", "PRI_TDM_TX_3_Voip", "PRI_TDM_TX_3"}, - {"Voip_Tx Mixer", "TX_CDC_DMA_TX_0_Voip", "TX_CDC_DMA_TX_0"}, - {"Voip_Tx Mixer", "TX_CDC_DMA_TX_1_Voip", "TX_CDC_DMA_TX_1"}, - {"Voip_Tx Mixer", "TX_CDC_DMA_TX_2_Voip", "TX_CDC_DMA_TX_2"}, - {"Voip_Tx Mixer", "TX_CDC_DMA_TX_3_Voip", "TX_CDC_DMA_TX_3"}, - {"Voip_Tx Mixer", "TX_CDC_DMA_TX_4_Voip", "TX_CDC_DMA_TX_4"}, - {"Voip_Tx Mixer", "TX_CDC_DMA_TX_5_Voip", "TX_CDC_DMA_TX_5"}, - {"VOIP_UL", NULL, "Voip_Tx Mixer"}, + /* Backend Enablement */ + {"BE_OUT", NULL, "PRI_TDM_RX_0"}, + {"BE_OUT", NULL, "PRI_TDM_RX_1"}, + {"BE_OUT", NULL, "PRI_TDM_RX_2"}, + {"BE_OUT", NULL, "PRI_TDM_RX_3"}, + {"BE_OUT", NULL, "SEC_TDM_RX_0"}, + {"BE_OUT", NULL, "SEC_TDM_RX_1"}, + {"BE_OUT", NULL, "SEC_TDM_RX_2"}, + {"BE_OUT", NULL, "SEC_TDM_RX_3"}, + {"BE_OUT", NULL, "SEC_TDM_RX_7"}, + {"BE_OUT", NULL, "TERT_TDM_RX_0"}, + {"BE_OUT", NULL, "TERT_TDM_RX_1"}, + {"BE_OUT", NULL, "TERT_TDM_RX_2"}, + {"BE_OUT", NULL, "TERT_TDM_RX_3"}, + {"BE_OUT", NULL, "TERT_TDM_RX_4"}, + {"BE_OUT", NULL, "QUAT_TDM_RX_0"}, + {"BE_OUT", NULL, "QUAT_TDM_RX_1"}, + {"BE_OUT", NULL, "QUAT_TDM_RX_2"}, + {"BE_OUT", NULL, "QUAT_TDM_RX_3"}, + {"BE_OUT", NULL, "QUAT_TDM_RX_7"}, + {"BE_OUT", NULL, "QUIN_TDM_RX_0"}, + {"BE_OUT", NULL, "QUIN_TDM_RX_1"}, + {"BE_OUT", NULL, "QUIN_TDM_RX_2"}, + {"BE_OUT", NULL, "QUIN_TDM_RX_3"}, + {"BE_OUT", NULL, "QUIN_TDM_RX_7"}, + {"BE_OUT", NULL, "SEN_TDM_RX_0"}, + {"BE_OUT", NULL, "SEN_TDM_RX_1"}, + {"BE_OUT", NULL, "SEN_TDM_RX_2"}, + {"BE_OUT", NULL, "SEN_TDM_RX_3"}, - {"SLIMBUS_DL_HL", "Switch", "SLIM0_DL_HL"}, - {"SLIMBUS_0_RX", NULL, "SLIMBUS_DL_HL"}, - {"SLIMBUS1_DL_HL", "Switch", "SLIM1_DL_HL"}, - {"SLIMBUS_1_RX", NULL, "SLIMBUS1_DL_HL"}, - {"SLIMBUS3_DL_HL", "Switch", "SLIM3_DL_HL"}, - {"SLIMBUS_3_RX", NULL, "SLIMBUS3_DL_HL"}, - {"SLIMBUS4_DL_HL", "Switch", "SLIM4_DL_HL"}, - {"SLIMBUS_4_RX", NULL, "SLIMBUS4_DL_HL"}, - {"SLIMBUS6_DL_HL", "Switch", "SLIM0_DL_HL"}, - {"SLIMBUS_6_RX", NULL, "SLIMBUS6_DL_HL"}, - {"SCO_SLIM7_DL_HL", "Switch", "SLIM7_DL_HL"}, - {"SLIMBUS_7_RX", NULL, "SCO_SLIM7_DL_HL"}, - {"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"}, - {"SLIM1_UL_HL", NULL, "SLIMBUS_1_TX"}, - {"SLIM3_UL_HL", NULL, "SLIMBUS_3_TX"}, - {"SLIM4_UL_HL", NULL, "SLIMBUS_4_TX"}, - {"SLIM8_UL_HL", NULL, "SLIMBUS_8_TX"}, - {"WSA_CDC_DMA_RX_0_DL_HL", "Switch", "CDC_DMA_DL_HL"}, - {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0_DL_HL"}, - {"CDC_DMA_UL_HL", NULL, "VA_CDC_DMA_TX_0"}, - {"RX_CDC_DMA_RX_0_DL_HL", "Switch", "CDC_DMA_DL_HL"}, - {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0_DL_HL"}, - {"RX_CDC_DMA_RX_1_DL_HL", "Switch", "CDC_DMA_DL_HL"}, - {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1_DL_HL"}, - {"TX3_CDC_DMA_UL_HL", NULL, "TX_CDC_DMA_TX_3"}, - {"LSM1 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM1 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM1 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM1 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM1 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"LSM1 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"LSM1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"LSM1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"LSM1 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"LSM1 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"LSM1 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"LSM1 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"LSM1_UL_HL", NULL, "LSM1 Mixer"}, + {"PRI_TDM_TX_0", NULL, "BE_IN"}, + {"PRI_TDM_TX_1", NULL, "BE_IN"}, + {"PRI_TDM_TX_2", NULL, "BE_IN"}, + {"PRI_TDM_TX_3", NULL, "BE_IN"}, + {"SEC_TDM_TX_0", NULL, "BE_IN"}, + {"SEC_TDM_TX_1", NULL, "BE_IN"}, + {"SEC_TDM_TX_2", NULL, "BE_IN"}, + {"SEC_TDM_TX_3", NULL, "BE_IN"}, + {"TERT_TDM_TX_0", NULL, "BE_IN"}, + {"TERT_TDM_TX_1", NULL, "BE_IN"}, + {"TERT_TDM_TX_2", NULL, "BE_IN"}, + {"TERT_TDM_TX_3", NULL, "BE_IN"}, + {"TERT_TDM_TX_7", NULL, "BE_IN"}, + {"QUAT_TDM_TX_0", NULL, "BE_IN"}, + {"QUAT_TDM_TX_1", NULL, "BE_IN"}, + {"QUAT_TDM_TX_2", NULL, "BE_IN"}, + {"QUAT_TDM_TX_3", NULL, "BE_IN"}, + {"QUAT_TDM_TX_7", NULL, "BE_IN"}, + {"AFE_LOOPBACK_TX", NULL, "BE_IN"}, + {"QUIN_TDM_TX_0", NULL, "BE_IN"}, + {"QUIN_TDM_TX_1", NULL, "BE_IN"}, + {"QUIN_TDM_TX_2", NULL, "BE_IN"}, + {"QUIN_TDM_TX_3", NULL, "BE_IN"}, + {"QUIN_TDM_TX_7", NULL, "BE_IN"}, + {"SEN_TDM_TX_0", NULL, "BE_IN"}, + {"SEN_TDM_TX_1", NULL, "BE_IN"}, + {"SEN_TDM_TX_2", NULL, "BE_IN"}, + {"SEN_TDM_TX_3", NULL, "BE_IN"}, +}; +#endif - {"LSM2 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM2 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM2 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM2 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM2 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"LSM2 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"LSM2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"LSM2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"LSM2 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"LSM2 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"LSM2 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"LSM2 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"LSM2_UL_HL", NULL, "LSM2 Mixer"}, +#ifndef CONFIG_MI2S_DISABLE +static const struct snd_soc_dapm_route intercon_mi2s[] = { + {"PRI_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"}, + + {"SEC_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SEC_I2S_RX", NULL, "SEC_RX Audio Mixer"}, + /* incall */ + {"MultiMedia2 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia4 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia17 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia18 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia19 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia28 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia29 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia30 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia8 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia18 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia19 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia28 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia29 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia30 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia17 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia18 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia19 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia28 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia29 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia30 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia17 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia18 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia19 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia28 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia29 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia30 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia8 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"LSM3 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM3 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM3 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM3 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM3 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM3 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"LSM3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"LSM3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"LSM3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"LSM3 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"LSM3 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"LSM3 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"LSM3 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"LSM3_UL_HL", NULL, "LSM3 Mixer"}, + {"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"MI2S_RX", NULL, "MI2S_RX Audio Mixer"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX Audio Mixer"}, - {"LSM4 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM4 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM4 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM4 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM4 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM4 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM4 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"LSM4 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"LSM4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"LSM4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"LSM4 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"LSM4 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"LSM4 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"LSM4 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"LSM4_UL_HL", NULL, "LSM4 Mixer"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX Audio Mixer"}, - {"LSM5 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM5 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM5 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM5 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM5 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"LSM5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"LSM5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"LSM5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"LSM5 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"LSM5 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"LSM5 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"LSM5 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"LSM5_UL_HL", NULL, "LSM5 Mixer"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Audio Mixer"}, - {"LSM6 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM6 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM6 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM6 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM6 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"LSM6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"LSM6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"LSM6 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"LSM6 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"LSM6 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"LSM6 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"LSM6_UL_HL", NULL, "LSM6 Mixer"}, + {"SEC_MI2S_RX_SD1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_MI2S_RX_SD1", NULL, "SEC_MI2S_RX_SD1 Audio Mixer"}, - {"LSM7 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM7 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM7 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM7 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM7 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM7 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"LSM7 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"LSM7 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"LSM7 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"LSM7 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"LSM7 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"LSM7 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"LSM7_UL_HL", NULL, "LSM7 Mixer"}, + {"SEC_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + + {"PRI_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Audio Mixer"}, + {"PRI_MI2S_RX Audio Mixer", "DTMF", "DTMF_DL_HL"}, - {"LSM8 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM8 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM8 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM8 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM8 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM8 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"LSM8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"LSM8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"LSM8 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"LSM8 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"LSM8 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"LSM8 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"LSM8_UL_HL", NULL, "LSM8 Mixer"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX Audio Mixer"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX Audio Mixer"}, - {"CPE_LSM_UL_HL", NULL, "BE_IN"}, - {"QCHAT_Tx Mixer", "PRI_TX_QCHAT", "PRI_I2S_TX"}, - {"QCHAT_Tx Mixer", "SLIM_0_TX_QCHAT", "SLIMBUS_0_TX"}, - {"QCHAT_Tx Mixer", "SLIM_7_TX_QCHAT", "SLIMBUS_7_TX"}, - {"QCHAT_Tx Mixer", "SLIM_8_TX_QCHAT", "SLIMBUS_8_TX"}, - {"QCHAT_Tx Mixer", "INTERNAL_BT_SCO_TX_QCHAT", "INT_BT_SCO_TX"}, - {"QCHAT_Tx Mixer", "AFE_PCM_TX_QCHAT", "PCM_TX"}, - {"QCHAT_Tx Mixer", "AUX_PCM_TX_QCHAT", "AUX_PCM_TX"}, - {"QCHAT_Tx Mixer", "SEC_AUX_PCM_TX_QCHAT", "SEC_AUX_PCM_TX"}, - {"QCHAT_Tx Mixer", "TERT_AUX_PCM_TX_QCHAT", "TERT_AUX_PCM_TX"}, - {"QCHAT_Tx Mixer", "QUAT_AUX_PCM_TX_QCHAT", "QUAT_AUX_PCM_TX"}, - {"QCHAT_Tx Mixer", "QUIN_AUX_PCM_TX_QCHAT", "QUIN_AUX_PCM_TX"}, - {"QCHAT_Tx Mixer", "SEN_AUX_PCM_TX_QCHAT", "SEN_AUX_PCM_TX"}, - {"QCHAT_Tx Mixer", "MI2S_TX_QCHAT", "MI2S_TX"}, - {"QCHAT_Tx Mixer", "PRI_MI2S_TX_QCHAT", "PRI_MI2S_TX"}, - {"QCHAT_Tx Mixer", "TERT_MI2S_TX_QCHAT", "TERT_MI2S_TX"}, - {"QCHAT_Tx Mixer", "INT3_MI2S_TX_QCHAT", "INT3_MI2S_TX"}, - {"QCHAT_Tx Mixer", "USB_AUDIO_TX_QCHAT", "USB_AUDIO_TX"}, - {"QCHAT_UL", NULL, "QCHAT_Tx Mixer"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX Audio Mixer"}, - {"INT_FM_RX", NULL, "INTFM_DL_HL"}, - {"INTFM_UL_HL", NULL, "INT_FM_TX"}, - {"INTHFP_UL_HL", NULL, "HFP_PRI_AUX_UL_HL"}, - {"HFP_PRI_AUX_UL_HL", "Switch", "AUX_PCM_TX"}, - {"INTHFP_UL_HL", NULL, "HFP_AUX_UL_HL"}, - {"HFP_AUX_UL_HL", "Switch", "SEC_AUX_PCM_TX"}, - {"INTHFP_UL_HL", NULL, "HFP_INT_UL_HL"}, - {"HFP_INT_UL_HL", "Switch", "INT_BT_SCO_TX"}, - {"SLIM7_UL_HL", NULL, "HFP_SLIM7_UL_HL"}, - {"HFP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"}, - {"AUX_PCM_RX", NULL, "AUXPCM_DL_HL"}, - {"AUX_PCM_RX", NULL, "INTHFP_DL_HL"}, - {"SLIM7_UL_HL", NULL, "A2DP_SLIM7_UL_HL"}, - {"A2DP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"}, - {"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_DL_HL"}, - {"AUXPCM_UL_HL", NULL, "AUX_PCM_TX"}, - {"SEC_AUXPCM_UL_HL", NULL, "SEC_AUX_PCM_TX"}, - {"MI2S_RX", NULL, "MI2S_DL_HL"}, - {"MI2S_UL_HL", NULL, "MI2S_TX"}, - {"PCM_RX_DL_HL", "Switch", "SLIM0_DL_HL"}, - {"PCM_RX", NULL, "PCM_RX_DL_HL"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX Audio Mixer"}, - /* connect to INT4_MI2S_DL_HL since same pcm_id */ - {"INT0_MI2S_RX_DL_HL", "Switch", "INT4_MI2S_DL_HL"}, - {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX_DL_HL"}, - {"INT4_MI2S_RX_DL_HL", "Switch", "INT4_MI2S_DL_HL"}, - {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_DL_HL"}, - {"PRI_MI2S_RX_DL_HL", "Switch", "PRI_MI2S_DL_HL"}, - {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_DL_HL"}, - {"SEC_MI2S_RX_DL_HL", "Switch", "SEC_MI2S_DL_HL"}, - {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX_DL_HL"}, - {"TERT_MI2S_RX_DL_HL", "Switch", "TERT_MI2S_DL_HL"}, - {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX_DL_HL"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"PRI_META_MI2S_RX", NULL, "PRI_META_MI2S_RX Audio Mixer"}, - {"QUAT_MI2S_RX_DL_HL", "Switch", "QUAT_MI2S_DL_HL"}, - {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_DL_HL"}, - {"QUIN_MI2S_RX_DL_HL", "Switch", "QUIN_MI2S_DL_HL"}, - {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_DL_HL"}, - {"SEN_MI2S_RX_DL_HL", "Switch", "SEN_MI2S_DL_HL"}, - {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX_DL_HL"}, - {"MI2S_UL_HL", NULL, "TERT_MI2S_TX"}, - {"INT3_MI2S_UL_HL", NULL, "INT3_MI2S_TX"}, - {"TERT_MI2S_UL_HL", NULL, "TERT_MI2S_TX"}, - {"SEC_I2S_RX", NULL, "SEC_I2S_DL_HL"}, - {"PRI_MI2S_UL_HL", NULL, "PRI_MI2S_TX"}, - {"SEC_MI2S_UL_HL", NULL, "SEC_MI2S_TX"}, - {"SEC_MI2S_RX", NULL, "SEC_MI2S_DL_HL"}, - {"PRI_MI2S_RX", NULL, "PRI_MI2S_DL_HL"}, - {"TERT_MI2S_RX", NULL, "TERT_MI2S_DL_HL"}, - {"QUAT_MI2S_UL_HL", NULL, "QUAT_MI2S_TX"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SEC_META_MI2S_RX", NULL, "SEC_META_MI2S_RX Audio Mixer"}, - {"PRI_TDM_TX_0_UL_HL", NULL, "PRI_TDM_TX_0"}, - {"PRI_TDM_TX_1_UL_HL", NULL, "PRI_TDM_TX_1"}, - {"PRI_TDM_TX_2_UL_HL", NULL, "PRI_TDM_TX_2"}, - {"PRI_TDM_TX_3_UL_HL", NULL, "PRI_TDM_TX_3"}, - {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0_DL_HL"}, - {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1_DL_HL"}, - {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2_DL_HL"}, - {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3_DL_HL"}, - {"SEC_TDM_TX_0_UL_HL", NULL, "SEC_TDM_TX_0"}, - {"SEC_TDM_TX_1_UL_HL", NULL, "SEC_TDM_TX_1"}, - {"SEC_TDM_TX_2_UL_HL", NULL, "SEC_TDM_TX_2"}, - {"SEC_TDM_TX_3_UL_HL", NULL, "SEC_TDM_TX_3"}, - {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0_DL_HL"}, - {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1_DL_HL"}, - {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2_DL_HL"}, - {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3_DL_HL"}, - {"SEC_TDM_RX_7", NULL, "SEC_TDM_RX_7_DL_HL"}, - {"TERT_TDM_TX_0_UL_HL", NULL, "TERT_TDM_TX_0"}, - {"TERT_TDM_TX_1_UL_HL", NULL, "TERT_TDM_TX_1"}, - {"TERT_TDM_TX_2_UL_HL", NULL, "TERT_TDM_TX_2"}, - {"TERT_TDM_TX_3_UL_HL", NULL, "TERT_TDM_TX_3"}, - {"TERT_TDM_TX_7_UL_HL", NULL, "TERT_TDM_TX_7"}, - {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0_DL_HL"}, - {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1_DL_HL"}, - {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2_DL_HL"}, - {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3_DL_HL"}, - {"QUAT_TDM_TX_0_UL_HL", NULL, "QUAT_TDM_TX_0"}, - {"QUAT_TDM_TX_1_UL_HL", NULL, "QUAT_TDM_TX_1"}, - {"QUAT_TDM_TX_2_UL_HL", NULL, "QUAT_TDM_TX_2"}, - {"QUAT_TDM_TX_3_UL_HL", NULL, "QUAT_TDM_TX_3"}, - {"QUAT_TDM_TX_7_UL_HL", NULL, "QUAT_TDM_TX_7"}, - {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0_DL_HL"}, - {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1_DL_HL"}, - {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_DL_HL"}, - {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3_DL_HL"}, - {"QUAT_TDM_RX_7", NULL, "QUAT_TDM_RX_7_DL_HL"}, - {"QUIN_TDM_TX_0_UL_HL", NULL, "QUIN_TDM_TX_0"}, - {"QUIN_TDM_TX_1_UL_HL", NULL, "QUIN_TDM_TX_1"}, - {"QUIN_TDM_TX_2_UL_HL", NULL, "QUIN_TDM_TX_2"}, - {"QUIN_TDM_TX_3_UL_HL", NULL, "QUIN_TDM_TX_3"}, - {"QUIN_TDM_TX_7_UL_HL", NULL, "QUIN_TDM_TX_7"}, - {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0_DL_HL"}, - {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1_DL_HL"}, - {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2_DL_HL"}, - {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3_DL_HL"}, - {"QUIN_TDM_RX_7", NULL, "QUIN_TDM_RX_7_DL_HL"}, - {"SEN_TDM_TX_0_UL_HL", NULL, "SEN_TDM_TX_0"}, - {"SEN_TDM_TX_1_UL_HL", NULL, "SEN_TDM_TX_1"}, - {"SEN_TDM_TX_2_UL_HL", NULL, "SEN_TDM_TX_2"}, - {"SEN_TDM_TX_3_UL_HL", NULL, "SEN_TDM_TX_3"}, - {"SEN_TDM_RX_0", NULL, "SEN_TDM_RX_0_DL_HL"}, - {"SEN_TDM_RX_1", NULL, "SEN_TDM_RX_1_DL_HL"}, - {"SEN_TDM_RX_2", NULL, "SEN_TDM_RX_2_DL_HL"}, - {"SEN_TDM_RX_3", NULL, "SEN_TDM_RX_3_DL_HL"}, + {"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"}, + {"MultiMedia1 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia3 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia5 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia10 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia16 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia1 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia2 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia1 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, + {"MultiMedia2 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, + {"MultiMedia1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia1 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia2 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia1 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia2 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia1 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia1 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia2 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia6 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia10 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia6 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia3 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia5 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia10 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia16 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia6 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia10 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia16 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia17 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia18 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia19 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia28 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia29 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia30 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia6 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia6 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia6 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia5 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia6 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, + {"MultiMedia5 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Port Mixer"}, + {"MultiMedia27 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia27 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia27 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia27 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia27 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia27 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Port Mixer"}, + {"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"}, - {"PRI_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"PRI_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"PRI_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"PRI_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"PRI_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"PRI_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"PRI_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"PRI_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Port Mixer"}, + {"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SEC_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SEC_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"}, - {"PRI_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"PRI_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"PRI_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"PRI_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"PRI_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"PRI_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"PRI_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"PRI_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Port Mixer"}, + {"SEC_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SEC_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX_Voice Mixer"}, - {"SEC_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEC_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"SEC_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SEC_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SEC_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SEC_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SEC_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEC_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Port Mixer"}, + {"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"}, - {"SEC_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEC_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"SEC_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SEC_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SEC_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SEC_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SEC_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEC_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Port Mixer"}, + {"PRI_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_Voice Mixer"}, - {"SEC_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEC_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"SEC_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SEC_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SEC_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SEC_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SEC_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEC_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Port Mixer"}, + {"INT0_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"INT0_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"INT0_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"INT0_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"INT0_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX_Voice Mixer"}, + + {"INT4_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"INT4_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"INT4_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"INT4_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"INT4_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_Voice Mixer"}, - {"SEC_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEC_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"SEC_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SEC_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SEC_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SEC_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SEC_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEC_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Port Mixer"}, + {"TERT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"TERT_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX_Voice Mixer"}, - {"SEC_TDM_RX_7 Port Mixer", "TERT_TDM_TX_7", "TERT_TDM_TX_7"}, - {"SEC_TDM_RX_7", NULL, "SEC_TDM_RX_7 Port Mixer"}, + {"QUAT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_Voice Mixer"}, - {"TERT_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"TERT_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"TERT_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"TERT_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"TERT_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"TERT_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"TERT_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"TERT_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Port Mixer"}, + {"QUIN_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_Voice Mixer"}, - {"TERT_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"TERT_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"TERT_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"TERT_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"TERT_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"TERT_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"TERT_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"TERT_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Port Mixer"}, + {"SEN_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SEN_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SEN_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SEN_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX_Voice Mixer"}, - {"TERT_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"TERT_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"TERT_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"TERT_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"TERT_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"TERT_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"TERT_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"TERT_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Port Mixer"}, + {"VOC_EXT_EC MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"VOC_EXT_EC MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"VOC_EXT_EC MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"VOC_EXT_EC MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"VOC_EXT_EC MUX", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Port Mixer"}, + {"AUDIO_REF_EC_UL1 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL1 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL1 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL1 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Port Mixer"}, + {"AUDIO_REF_EC_UL2 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL2 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL2 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL2 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Port Mixer"}, + {"AUDIO_REF_EC_UL3 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL3 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL3 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL3 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Port Mixer"}, + {"AUDIO_REF_EC_UL4 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL4 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL4 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL4 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"AUDIO_REF_EC_UL5 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL5 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL5 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL5 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Port Mixer"}, + {"AUDIO_REF_EC_UL6 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL6 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL6 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL6 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUAT_TDM_RX_7 Port Mixer", "QUAT_TDM_TX_7", "QUAT_TDM_TX_7"}, - {"QUAT_TDM_RX_7 Port Mixer", "QUIN_TDM_TX_7", "QUIN_TDM_TX_7"}, - {"QUAT_TDM_RX_7", NULL, "QUAT_TDM_RX_7 Port Mixer"}, + {"AUDIO_REF_EC_UL8 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL8 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL8 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL8 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0 Port Mixer"}, + {"AUDIO_REF_EC_UL9 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL9 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL9 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL9 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1 Port Mixer"}, + {"AUDIO_REF_EC_UL10 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2 Port Mixer"}, + {"AUDIO_REF_EC_UL16 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL16 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL16 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL16 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Port Mixer"}, + {"AUDIO_REF_EC_UL17 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL17 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL17 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL17 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUIN_TDM_RX_7 Port Mixer", "TERT_TDM_TX_7", "TERT_TDM_TX_7"}, - {"QUIN_TDM_RX_7 Port Mixer", "QUAT_TDM_TX_7", "QUAT_TDM_TX_7"}, - {"QUIN_TDM_RX_7 Port Mixer", "QUIN_TDM_TX_7", "QUIN_TDM_TX_7"}, - {"QUIN_TDM_RX_7", NULL, "QUIN_TDM_RX_7 Port Mixer"}, + {"AUDIO_REF_EC_UL18 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL18 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL18 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL18 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"SEN_TDM_RX_0", NULL, "SEN_TDM_RX_0 Port Mixer"}, + {"AUDIO_REF_EC_UL19 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL19 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL19 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL19 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"SEN_TDM_RX_1", NULL, "SEN_TDM_RX_1 Port Mixer"}, + {"AUDIO_REF_EC_UL28 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL28 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL28 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL28 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"SEN_TDM_RX_2", NULL, "SEN_TDM_RX_2 Port Mixer"}, + {"AUDIO_REF_EC_UL29 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL29 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL29 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL29 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"VoiceMMode1_Tx Mixer", "PRI_TX_MMode1", "PRI_I2S_TX"}, + {"VoiceMMode1_Tx Mixer", "PRI_MI2S_TX_MMode1", "PRI_MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "MI2S_TX_MMode1", "MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "SEC_MI2S_TX_MMode1", "SEC_MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "TERT_MI2S_TX_MMode1", "TERT_MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "INT3_MI2S_TX_MMode1", "INT3_MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "QUAT_MI2S_TX_MMode1", "QUAT_MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "QUIN_MI2S_TX_MMode1", "QUIN_MI2S_TX"}, + + {"VoiceMMode2_Tx Mixer", "PRI_TX_MMode2", "PRI_I2S_TX"}, + {"VoiceMMode2_Tx Mixer", "PRI_MI2S_TX_MMode2", "PRI_MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "SEC_MI2S_TX_MMode2", "SEC_MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "MI2S_TX_MMode2", "MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "TERT_MI2S_TX_MMode2", "TERT_MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "INT3_MI2S_TX_MMode2", "INT3_MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "QUAT_MI2S_TX_MMode2", "QUAT_MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "QUIN_MI2S_TX_MMode2", "QUIN_MI2S_TX"}, + {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"}, + {"Voip_Tx Mixer", "MI2S_TX_Voip", "MI2S_TX"}, + {"Voip_Tx Mixer", "SEC_MI2S_TX_Voip", "SEC_MI2S_TX"}, + {"Voip_Tx Mixer", "TERT_MI2S_TX_Voip", "TERT_MI2S_TX"}, + {"Voip_Tx Mixer", "INT3_MI2S_TX_Voip", "INT3_MI2S_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"SEN_TDM_RX_3", NULL, "SEN_TDM_RX_3 Port Mixer"}, + {"LSM1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM1 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM2 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM3 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM4 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM4 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM4 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM7 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM8 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"INT0_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"INT0_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"INT0_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"INT0_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"INT0_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"INT0_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"INT0_MI2S_RX Port Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"INT0_MI2S_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"INT0_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"INT0_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"INT0_MI2S_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"INT0_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX Port Mixer"}, + {"QCHAT_Tx Mixer", "PRI_TX_QCHAT", "PRI_I2S_TX"}, + {"QCHAT_Tx Mixer", "MI2S_TX_QCHAT", "MI2S_TX"}, + {"QCHAT_Tx Mixer", "PRI_MI2S_TX_QCHAT", "PRI_MI2S_TX"}, + {"QCHAT_Tx Mixer", "TERT_MI2S_TX_QCHAT", "TERT_MI2S_TX"}, + {"QCHAT_Tx Mixer", "INT3_MI2S_TX_QCHAT", "INT3_MI2S_TX"}, - {"INT4_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"INT4_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"INT4_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"INT4_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"INT4_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"INT4_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"INT4_MI2S_RX Port Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"INT4_MI2S_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"INT4_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"INT4_MI2S_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"INT4_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"INT4_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX Port Mixer"}, + {"MI2S_RX", NULL, "MI2S_DL_HL"}, + {"MI2S_UL_HL", NULL, "MI2S_TX"}, - {"WSA_CDC_DMA_RX_0 Port Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"WSA_CDC_DMA_RX_0 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"WSA_CDC_DMA_RX_0 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + /* connect to INT4_MI2S_DL_HL since same pcm_id */ {"WSA_CDC_DMA_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0 Port Mixer"}, - - {"RX_CDC_DMA_RX_0 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"RX_CDC_DMA_RX_0 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"RX_CDC_DMA_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0 Port Mixer"}, - - {"RX_CDC_DMA_RX_1 Port Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"RX_CDC_DMA_RX_1 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"RX_CDC_DMA_RX_1 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"RX_CDC_DMA_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1 Port Mixer"}, - {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"SLIMBUS_0_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"SLIMBUS_0_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"SLIMBUS_0_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"SLIMBUS_0_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"SLIMBUS_0_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SLIMBUS_0_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SLIMBUS_0_RX Port Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, - {"SLIMBUS_0_RX Port Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, - {"SLIMBUS_0_RX Port Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, - {"SLIMBUS_0_RX Port Mixer", "SEN_AUXPCM_UL_TX", "SEN_AUX_PCM_TX"}, {"SLIMBUS_0_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, @@ -29232,168 +29889,85 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_0_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"SLIMBUS_0_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"}, - {"AFE_PCM_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"AFE_PCM_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"PCM_RX", NULL, "AFE_PCM_RX Port Mixer"}, - {"USB_AUDIO_RX Port Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX Port Mixer"}, - {"USB_DL_HL", "Switch", "USBAUDIO_DL_HL"}, - {"USB_AUDIO_RX", NULL, "USB_DL_HL"}, - {"USBAUDIO_UL_HL", NULL, "USB_AUDIO_TX"}, - - - {"AUX_PCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"AUX_PCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"AUX_PCM_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"AUX_PCM_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"AUX_PCM_RX Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"AUX_PCM_RX Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"AUX_PCM_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUX_PCM_RX", NULL, "AUX_PCM_RX Port Mixer"}, - - {"SEC_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEC_AUXPCM_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEC_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"SEC_AUXPCM_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_RX Port Mixer"}, - - {"TERT_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"TERT_AUXPCM_RX Port Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, - {"TERT_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"TERT_AUX_PCM_RX", NULL, "TERT_AUXPCM_RX Port Mixer"}, - - {"QUAT_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUAT_AUXPCM_RX Port Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, - {"QUAT_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUXPCM_RX Port Mixer"}, - - {"QUIN_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUIN_AUXPCM_RX Port Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, - {"QUIN_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUXPCM_RX Port Mixer"}, - - {"Voice Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, - {"Voice Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"Voice Stub Tx Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"Voice Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"}, - {"Voice Stub Tx Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"Voice Stub Tx Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"Voice Stub Tx Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, - {"Voice Stub Tx Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, - {"Voice Stub Tx Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, - {"Voice Stub Tx Mixer", "SEN_AUXPCM_UL_TX", "SEN_AUX_PCM_TX"}, - {"Voice Stub Tx Mixer", "MI2S_TX", "MI2S_TX"}, - {"Voice Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"Voice Stub Tx Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"Voice Stub Tx Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"Voice Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"Voice Stub Tx Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"Voice Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"}, - {"Voice Stub Tx Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"Voice Stub Tx Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"Voice Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"VOICE_STUB_UL", NULL, "Voice Stub Tx Mixer"}, - - {"VoLTE Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, - {"VoLTE Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"VoLTE Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"}, - {"VoLTE Stub Tx Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"VoLTE Stub Tx Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"VoLTE Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"}, - {"VoLTE Stub Tx Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"VoLTE Stub Tx Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"VoLTE Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"VoLTE Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"VoLTE Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"VOLTE_STUB_UL", NULL, "VoLTE Stub Tx Mixer"}, - - {"Voice2 Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, - {"Voice2 Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"Voice2 Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"}, - {"Voice2 Stub Tx Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"Voice2 Stub Tx Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"Voice2 Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"}, - {"Voice2 Stub Tx Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"Voice2 Stub Tx Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"Voice2 Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"Voice2 Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"Voice2 Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"Voice2 Stub Tx Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"VOICE2_STUB_UL", NULL, "Voice2 Stub Tx Mixer"}, - - {"STUB_RX Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"STUB_RX Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"STUB_RX", NULL, "STUB_RX Mixer"}, - - {"SLIMBUS_1_RX Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SLIMBUS_1_RX Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Mixer"}, - - {"SLIMBUS_3_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SLIMBUS_3_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX_Voice Mixer"}, - {"SLIM_7_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SLIM_7_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SLIM_7_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SLIM_7_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SLIM_7_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SLIMBUS_7_RX", NULL, "SLIM_7_RX_Voice Mixer"}, + {"SLIMBUS_6_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"SLIMBUS_6_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SLIMBUS_6_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"SLIMBUS_6_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SLIM_8_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SLIM_8_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SLIM_8_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SLIM_8_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SLIM_8_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SLIMBUS_8_RX", NULL, "SLIM_8_RX_Voice Mixer"}, + {"INT0_MI2S_RX_DL_HL", "Switch", "INT4_MI2S_DL_HL"}, + {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX_DL_HL"}, + {"INT4_MI2S_RX_DL_HL", "Switch", "INT4_MI2S_DL_HL"}, + {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_DL_HL"}, + {"PRI_MI2S_RX_DL_HL", "Switch", "PRI_MI2S_DL_HL"}, + {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_DL_HL"}, + {"SEC_MI2S_RX_DL_HL", "Switch", "SEC_MI2S_DL_HL"}, + {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX_DL_HL"}, + {"TERT_MI2S_RX_DL_HL", "Switch", "TERT_MI2S_DL_HL"}, + {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX_DL_HL"}, - {"SLIMBUS_1_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SLIMBUS_1_RX Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SLIMBUS_1_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Port Mixer"}, - {"INTERNAL_BT_SCO_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"INTERNAL_BT_SCO_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Port Mixer"}, - {"SLIMBUS_3_RX Port Mixer", "INTERNAL_BT_SCO_RX", "INT_BT_SCO_RX"}, - {"SLIMBUS_3_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, - {"SLIMBUS_3_RX Port Mixer", "AFE_PCM_RX", "PCM_RX"}, - {"SLIMBUS_3_RX Port Mixer", "AUX_PCM_RX", "AUX_PCM_RX"}, - {"SLIMBUS_3_RX Port Mixer", "SLIM_0_RX", "SLIMBUS_0_RX"}, - {"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX Port Mixer"}, + {"QUAT_MI2S_RX_DL_HL", "Switch", "QUAT_MI2S_DL_HL"}, + {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_DL_HL"}, + {"QUIN_MI2S_RX_DL_HL", "Switch", "QUIN_MI2S_DL_HL"}, + {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_DL_HL"}, + {"SEN_MI2S_RX_DL_HL", "Switch", "SEN_MI2S_DL_HL"}, + {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX_DL_HL"}, + {"MI2S_UL_HL", NULL, "TERT_MI2S_TX"}, + {"INT3_MI2S_UL_HL", NULL, "INT3_MI2S_TX"}, + {"TERT_MI2S_UL_HL", NULL, "TERT_MI2S_TX"}, + {"SEC_I2S_RX", NULL, "SEC_I2S_DL_HL"}, + {"PRI_MI2S_UL_HL", NULL, "PRI_MI2S_TX"}, + {"SEC_MI2S_UL_HL", NULL, "SEC_MI2S_TX"}, + {"SEC_MI2S_RX", NULL, "SEC_MI2S_DL_HL"}, + {"PRI_MI2S_RX", NULL, "PRI_MI2S_DL_HL"}, + {"TERT_MI2S_RX", NULL, "TERT_MI2S_DL_HL"}, + {"QUAT_MI2S_UL_HL", NULL, "QUAT_MI2S_TX"}, - {"SLIMBUS_6_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SLIMBUS_6_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"SLIMBUS_6_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"SLIMBUS_6_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"SLIMBUS_6_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"SLIMBUS_6_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"SLIMBUS_6_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SLIMBUS_6_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SLIMBUS_6_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, - {"SLIMBUS_6_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SLIMBUS_6_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"SLIMBUS_6_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SLIMBUS_6_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SLIMBUS_6_RX", NULL, "SLIMBUS_6_RX Port Mixer"}, + {"INT0_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"INT0_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"INT0_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"INT0_MI2S_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, + {"INT0_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX Port Mixer"}, - {"HDMI_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, - {"HDMI", NULL, "HDMI_RX Port Mixer"}, + {"INT4_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"INT4_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"INT4_MI2S_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, + {"INT4_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"INT4_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX Port Mixer"}, - {"HDMI_RX_MS Port Mixer", "MI2S_TX", "MI2S_TX"}, - {"HDMI_MS", NULL, "HDMI_RX_MS Port Mixer"}, + {"Voice Stub Tx Mixer", "MI2S_TX", "MI2S_TX"}, + {"Voice Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"Voice Stub Tx Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"Voice Stub Tx Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"Voice Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"DISPLAY_PORT_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, - {"DISPLAY_PORT", NULL, "DISPLAY_PORT_RX Port Mixer"}, + {"VoLTE Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"VoLTE Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"DISPLAY_PORT_RX1 Port Mixer", "MI2S_TX", "MI2S_TX"}, - {"DISPLAY_PORT1", NULL, "DISPLAY_PORT_RX1 Port Mixer"}, + {"Voice2 Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"Voice2 Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"Voice2 Stub Tx Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"SEC_I2S_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, {"SEC_I2S_RX", NULL, "SEC_I2S_RX Port Mixer"}, - {"MI2S_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MI2S_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MI2S_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, {"MI2S_RX", NULL, "MI2S_RX Port Mixer"}, @@ -29407,7 +29981,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"PRI_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"PRI_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE {"PRI_MI2S_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Port Mixer"}, {"SEC_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -29419,7 +29995,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"SEC_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"SEC_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE {"SEC_MI2S_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, +#endif {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Port Mixer"}, {"TERT_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -29440,7 +30018,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEN_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, {"QUAT_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"QUAT_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE {"QUAT_MI2S_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, +#endif {"QUAT_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX Port Mixer"}, @@ -29467,23 +30047,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "PRI_I2S_RX"}, {"BE_OUT", NULL, "SEC_I2S_RX"}, - {"BE_OUT", NULL, "SLIMBUS_0_RX"}, - {"BE_OUT", NULL, "SLIMBUS_1_RX"}, - {"BE_OUT", NULL, "SLIMBUS_2_RX"}, - {"BE_OUT", NULL, "SLIMBUS_3_RX"}, - {"BE_OUT", NULL, "SLIMBUS_4_RX"}, - {"BE_OUT", NULL, "SLIMBUS_5_RX"}, - {"BE_OUT", NULL, "SLIMBUS_6_RX"}, - {"BE_OUT", NULL, "SLIMBUS_7_RX"}, - {"BE_OUT", NULL, "SLIMBUS_8_RX"}, - {"BE_OUT", NULL, "SLIMBUS_9_RX"}, - {"BE_OUT", NULL, "USB_AUDIO_RX"}, - {"BE_OUT", NULL, "HDMI"}, - {"BE_OUT", NULL, "HDMI_MS"}, - {"BE_OUT", NULL, "DISPLAY_PORT"}, - {"BE_OUT", NULL, "DISPLAY_PORT1"}, - {"BE_OUT", NULL, "PRI_SPDIF_RX"}, - {"BE_OUT", NULL, "SEC_SPDIF_RX"}, {"BE_OUT", NULL, "MI2S_RX"}, {"BE_OUT", NULL, "QUAT_MI2S_RX"}, {"BE_OUT", NULL, "QUIN_MI2S_RX"}, @@ -29497,62 +30060,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "INT2_MI2S_RX"}, {"BE_OUT", NULL, "INT3_MI2S_RX"}, {"BE_OUT", NULL, "INT5_MI2S_RX"}, - {"BE_OUT", NULL, "INT_BT_SCO_RX"}, - {"BE_OUT", NULL, "INT_BT_A2DP_RX"}, - {"BE_OUT", NULL, "INT_FM_RX"}, - {"BE_OUT", NULL, "PCM_RX"}, - {"BE_OUT", NULL, "SLIMBUS_3_RX"}, - {"BE_OUT", NULL, "AUX_PCM_RX"}, - {"BE_OUT", NULL, "SEC_AUX_PCM_RX"}, - {"BE_OUT", NULL, "TERT_AUX_PCM_RX"}, - {"BE_OUT", NULL, "QUAT_AUX_PCM_RX"}, - {"BE_OUT", NULL, "QUIN_AUX_PCM_RX"}, - {"BE_OUT", NULL, "SEN_AUX_PCM_RX"}, - {"BE_OUT", NULL, "INT_BT_SCO_RX"}, - {"BE_OUT", NULL, "INT_FM_RX"}, - {"BE_OUT", NULL, "PCM_RX"}, - {"BE_OUT", NULL, "SLIMBUS_3_RX"}, - {"BE_OUT", NULL, "VOICE_PLAYBACK_TX"}, - {"BE_OUT", NULL, "VOICE2_PLAYBACK_TX"}, - {"BE_OUT", NULL, "PRI_TDM_RX_0"}, - {"BE_OUT", NULL, "PRI_TDM_RX_1"}, - {"BE_OUT", NULL, "PRI_TDM_RX_2"}, - {"BE_OUT", NULL, "PRI_TDM_RX_3"}, - {"BE_OUT", NULL, "SEC_TDM_RX_0"}, - {"BE_OUT", NULL, "SEC_TDM_RX_1"}, - {"BE_OUT", NULL, "SEC_TDM_RX_2"}, - {"BE_OUT", NULL, "SEC_TDM_RX_3"}, - {"BE_OUT", NULL, "SEC_TDM_RX_7"}, - {"BE_OUT", NULL, "TERT_TDM_RX_0"}, - {"BE_OUT", NULL, "TERT_TDM_RX_1"}, - {"BE_OUT", NULL, "TERT_TDM_RX_2"}, - {"BE_OUT", NULL, "TERT_TDM_RX_3"}, - {"BE_OUT", NULL, "TERT_TDM_RX_4"}, - {"BE_OUT", NULL, "QUAT_TDM_RX_0"}, - {"BE_OUT", NULL, "QUAT_TDM_RX_1"}, - {"BE_OUT", NULL, "QUAT_TDM_RX_2"}, - {"BE_OUT", NULL, "QUAT_TDM_RX_3"}, - {"BE_OUT", NULL, "QUAT_TDM_RX_7"}, - {"BE_OUT", NULL, "QUIN_TDM_RX_0"}, - {"BE_OUT", NULL, "QUIN_TDM_RX_1"}, - {"BE_OUT", NULL, "QUIN_TDM_RX_2"}, - {"BE_OUT", NULL, "QUIN_TDM_RX_3"}, - {"BE_OUT", NULL, "QUIN_TDM_RX_7"}, - {"BE_OUT", NULL, "SEN_TDM_RX_0"}, - {"BE_OUT", NULL, "SEN_TDM_RX_1"}, - {"BE_OUT", NULL, "SEN_TDM_RX_2"}, - {"BE_OUT", NULL, "SEN_TDM_RX_3"}, - {"BE_OUT", NULL, "WSA_CDC_DMA_RX_0"}, - {"BE_OUT", NULL, "WSA_CDC_DMA_RX_1"}, - {"BE_OUT", NULL, "RX_CDC_DMA_RX_0"}, - {"BE_OUT", NULL, "RX_CDC_DMA_RX_1"}, - {"BE_OUT", NULL, "RX_CDC_DMA_RX_2"}, - {"BE_OUT", NULL, "RX_CDC_DMA_RX_3"}, - {"BE_OUT", NULL, "RX_CDC_DMA_RX_4"}, - {"BE_OUT", NULL, "RX_CDC_DMA_RX_5"}, - {"BE_OUT", NULL, "RX_CDC_DMA_RX_6"}, - {"BE_OUT", NULL, "RX_CDC_DMA_RX_7"}, - {"BE_OUT", NULL, "PROXY_RX"}, {"PRI_I2S_TX", NULL, "BE_IN"}, {"MI2S_TX", NULL, "BE_IN"}, @@ -29567,90 +30074,15 @@ static const struct snd_soc_dapm_route intercon[] = { {"INT5_MI2S_TX", NULL, "BE_IN"}, {"SEC_MI2S_TX", NULL, "BE_IN"}, {"SENARY_MI2S_TX", NULL, "BE_IN"}, - {"SLIMBUS_0_TX", NULL, "BE_IN" }, - {"SLIMBUS_1_TX", NULL, "BE_IN" }, - {"SLIMBUS_3_TX", NULL, "BE_IN" }, - {"SLIMBUS_4_TX", NULL, "BE_IN" }, - {"SLIMBUS_5_TX", NULL, "BE_IN" }, - {"SLIMBUS_6_TX", NULL, "BE_IN" }, - {"SLIMBUS_7_TX", NULL, "BE_IN" }, - {"SLIMBUS_8_TX", NULL, "BE_IN" }, - {"SLIMBUS_9_TX", NULL, "BE_IN" }, - {"USB_AUDIO_TX", NULL, "BE_IN" }, - {"INT_BT_SCO_TX", NULL, "BE_IN"}, - {"INT_FM_TX", NULL, "BE_IN"}, - {"PCM_TX", NULL, "BE_IN"}, - {"BE_OUT", NULL, "SLIMBUS_3_RX"}, - {"BE_OUT", NULL, "STUB_RX"}, - {"STUB_TX", NULL, "BE_IN"}, - {"STUB_1_TX", NULL, "BE_IN"}, - {"BE_OUT", NULL, "AUX_PCM_RX"}, - {"AUX_PCM_TX", NULL, "BE_IN"}, - {"SEC_AUX_PCM_TX", NULL, "BE_IN"}, - {"TERT_AUX_PCM_TX", NULL, "BE_IN"}, - {"QUAT_AUX_PCM_TX", NULL, "BE_IN"}, - {"QUIN_AUX_PCM_TX", NULL, "BE_IN"}, - {"SEN_AUX_PCM_TX", NULL, "BE_IN"}, - {"INCALL_RECORD_TX", NULL, "BE_IN"}, - {"INCALL_RECORD_RX", NULL, "BE_IN"}, - {"SLIM0_RX_VI_FB_LCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"}, - {"SLIM0_RX_VI_FB_RCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"}, - {"WSA_RX_0_VI_FB_LCH_MUX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"WSA_RX_0_VI_FB_RCH_MUX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"PRI_MI2S_RX_VI_FB_MUX", "SENARY_TX", "SENARY_TX"}, {"INT4_MI2S_RX_VI_FB_MONO_CH_MUX", "INT5_MI2S_TX", "INT5_MI2S_TX"}, {"INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", "INT5_MI2S_TX", "INT5_MI2S_TX"}, - {"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_LCH_MUX"}, - {"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_RCH_MUX"}, - {"WSA_CDC_DMA_RX_0", NULL, "WSA_RX_0_VI_FB_LCH_MUX"}, - {"WSA_CDC_DMA_RX_0", NULL, "WSA_RX_0_VI_FB_RCH_MUX"}, {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_VI_FB_MUX"}, {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_MONO_CH_MUX"}, {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_STEREO_CH_MUX"}, - {"PRI_TDM_TX_0", NULL, "BE_IN"}, - {"PRI_TDM_TX_1", NULL, "BE_IN"}, - {"PRI_TDM_TX_2", NULL, "BE_IN"}, - {"PRI_TDM_TX_3", NULL, "BE_IN"}, - {"SEC_TDM_TX_0", NULL, "BE_IN"}, - {"SEC_TDM_TX_1", NULL, "BE_IN"}, - {"SEC_TDM_TX_2", NULL, "BE_IN"}, - {"SEC_TDM_TX_3", NULL, "BE_IN"}, - {"TERT_TDM_TX_0", NULL, "BE_IN"}, - {"TERT_TDM_TX_1", NULL, "BE_IN"}, - {"TERT_TDM_TX_2", NULL, "BE_IN"}, - {"TERT_TDM_TX_3", NULL, "BE_IN"}, - {"TERT_TDM_TX_7", NULL, "BE_IN"}, - {"QUAT_TDM_TX_0", NULL, "BE_IN"}, - {"QUAT_TDM_TX_1", NULL, "BE_IN"}, - {"QUAT_TDM_TX_2", NULL, "BE_IN"}, - {"QUAT_TDM_TX_3", NULL, "BE_IN"}, - {"QUAT_TDM_TX_7", NULL, "BE_IN"}, - {"AFE_LOOPBACK_TX", NULL, "BE_IN"}, - {"QUIN_TDM_TX_0", NULL, "BE_IN"}, - {"QUIN_TDM_TX_1", NULL, "BE_IN"}, - {"QUIN_TDM_TX_2", NULL, "BE_IN"}, - {"QUIN_TDM_TX_3", NULL, "BE_IN"}, - {"QUIN_TDM_TX_7", NULL, "BE_IN"}, - {"SEN_TDM_TX_0", NULL, "BE_IN"}, - {"SEN_TDM_TX_1", NULL, "BE_IN"}, - {"SEN_TDM_TX_2", NULL, "BE_IN"}, - {"SEN_TDM_TX_3", NULL, "BE_IN"}, - {"WSA_CDC_DMA_TX_0", NULL, "BE_IN"}, - {"WSA_CDC_DMA_TX_1", NULL, "BE_IN"}, - {"WSA_CDC_DMA_TX_2", NULL, "BE_IN"}, - {"VA_CDC_DMA_TX_0", NULL, "BE_IN"}, - {"VA_CDC_DMA_TX_1", NULL, "BE_IN"}, - {"VA_CDC_DMA_TX_2", NULL, "BE_IN"}, - {"TX_CDC_DMA_TX_0", NULL, "BE_IN"}, - {"TX_CDC_DMA_TX_1", NULL, "BE_IN"}, - {"TX_CDC_DMA_TX_2", NULL, "BE_IN"}, - {"TX_CDC_DMA_TX_3", NULL, "BE_IN"}, - {"TX_CDC_DMA_TX_4", NULL, "BE_IN"}, - {"TX_CDC_DMA_TX_5", NULL, "BE_IN"}, - {"PRI_SPDIF_TX", NULL, "BE_IN"}, - {"SEC_SPDIF_TX", NULL, "BE_IN"}, - {"PROXY_TX", NULL, "BE_IN"}, }; +#endif static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) @@ -30478,16 +30910,96 @@ void msm_routing_add_doa_control(struct snd_soc_component *component) } #endif +#ifndef CONFIG_TDM_DISABLE +static void snd_soc_dapm_new_controls_tdm(struct snd_soc_component *component) +{ + snd_soc_dapm_new_controls(&component->dapm, + msm_qdsp6_widgets_tdm, + ARRAY_SIZE(msm_qdsp6_widgets_tdm)); +} +static void snd_soc_dapm_add_routes_tdm(struct snd_soc_component *component) +{ + snd_soc_dapm_add_routes(&component->dapm, intercon_tdm, + ARRAY_SIZE(intercon_tdm)); +} +#else +static void snd_soc_dapm_new_controls_tdm(struct snd_soc_component *component) +{ + return; +} + +static void snd_soc_dapm_add_routes_tdm(struct snd_soc_component *component) +{ + return; +} +#endif + + +#ifndef CONFIG_MI2S_DISABLE +static void snd_soc_dapm_new_controls_mi2s(struct snd_soc_component *component) +{ + snd_soc_dapm_new_controls(&component->dapm, + msm_qdsp6_widgets_mi2s, + ARRAY_SIZE(msm_qdsp6_widgets_mi2s)); +} +static void snd_soc_dapm_add_routes_mi2s(struct snd_soc_component *component) +{ + snd_soc_dapm_add_routes(&component->dapm, intercon_mi2s, + ARRAY_SIZE(intercon_mi2s)); +} +#else +static void snd_soc_dapm_new_controls_mi2s(struct snd_soc_component *component) +{ + return; +} +static void snd_soc_dapm_add_routes_mi2s(struct snd_soc_component *component) +{ + return; +} +#endif + +#ifndef CONFIG_AUXPCM_DISABLE +static void snd_soc_dapm_new_controls_aux_pcm(struct snd_soc_component *component) +{ + snd_soc_dapm_new_controls(&component->dapm, + msm_qdsp6_widgets_aux_pcm, + ARRAY_SIZE(msm_qdsp6_widgets_aux_pcm)); +} +static void snd_soc_dapm_add_routes_aux_pcm(struct snd_soc_component *component) +{ + snd_soc_dapm_add_routes(&component->dapm, intercon_aux_pcm, + ARRAY_SIZE(intercon_aux_pcm)); +} +#else +static void snd_soc_dapm_new_controls_aux_pcm(struct snd_soc_component *component) +{ + return; +} +static void snd_soc_dapm_add_routes_aux_pcm(struct snd_soc_component *component) +{ + return; +} +#endif + /* Not used but frame seems to require it */ static int msm_routing_probe(struct snd_soc_component *component) { snd_soc_dapm_new_controls(&component->dapm, msm_qdsp6_widgets, ARRAY_SIZE(msm_qdsp6_widgets)); + + snd_soc_dapm_new_controls_tdm(component); + snd_soc_dapm_new_controls_mi2s(component); + snd_soc_dapm_new_controls_aux_pcm(component); + snd_soc_dapm_ignore_suspend(&component->dapm, "BE_OUT"); snd_soc_dapm_ignore_suspend(&component->dapm, "BE_IN"); snd_soc_dapm_add_routes(&component->dapm, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_add_routes_tdm(component); + snd_soc_dapm_add_routes_mi2s(component); + snd_soc_dapm_add_routes_aux_pcm(component); + snd_soc_dapm_new_widgets(component->dapm.card); snd_soc_add_component_controls(component, lsm_controls, -- GitLab From 024ec08025902eef021afd50dda400c288bae136 Mon Sep 17 00:00:00 2001 From: Harshal Ahire Date: Mon, 10 Aug 2020 01:59:14 +0530 Subject: [PATCH 1568/1645] asoc: Register widgets and intercons only when supported Register for the widgets and interconnections in routing driver only when the respective interfaces are supported. Add config based approach for TDM, AUXPCM and MI2S interfaces. Change-Id: I2b76e295d7cafde6062a3e0afbe7f25721fa9cca Signed-off-by: Harshal Ahire --- asoc/msm-pcm-routing-v2.c | 37560 ++++++++++++++++++------------------ 1 file changed, 19036 insertions(+), 18524 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 580c59889cc5..03603a2cf672 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -58,6 +58,7 @@ static int fm_switch_enable; static int hfp_switch_enable; static int a2dp_switch_enable; static int sco_switch_enable; +#ifndef CONFIG_MI2S_DISABLE static int int0_mi2s_switch_enable; static int int4_mi2s_switch_enable; static int pri_mi2s_switch_enable; @@ -66,6 +67,7 @@ static int tert_mi2s_switch_enable; static int quat_mi2s_switch_enable; static int quin_mi2s_switch_enable; static int sen_mi2s_switch_enable; +#endif static int fm_pcmrx_switch_enable; static int usb_switch_enable; static int lsm_port_index[MAX_LSM_SESSIONS]; @@ -2694,7 +2696,7 @@ static int msm_routing_sco_switch_mixer_put(struct snd_kcontrol *kcontrol, 0, update); return 1; } - +#ifndef CONFIG_MI2S_DISABLE static int msm_routing_get_int0_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2751,34 +2753,6 @@ static int msm_routing_put_int4_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, return 1; } -static int msm_routing_get_usb_switch_mixer(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = usb_switch_enable; - pr_debug("%s: HFP Switch enable %ld\n", __func__, - ucontrol->value.integer.value[0]); - return 0; -} - -static int msm_routing_put_usb_switch_mixer(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); - struct snd_soc_dapm_update *update = NULL; - - pr_debug("%s: USB Switch enable %ld\n", __func__, - ucontrol->value.integer.value[0]); - if (ucontrol->value.integer.value[0]) - snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, - 1, update); - else - snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, - 0, update); - usb_switch_enable = ucontrol->value.integer.value[0]; - return 1; -} - static int msm_routing_get_pri_mi2s_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2954,6 +2928,35 @@ static int msm_routing_put_sen_mi2s_switch_mixer( sen_mi2s_switch_enable = ucontrol->value.integer.value[0]; return 1; } +#endif + +static int msm_routing_get_usb_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = usb_switch_enable; + pr_debug("%s: HFP Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_routing_put_usb_switch_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = + snd_soc_dapm_kcontrol_widget(kcontrol); + struct snd_soc_dapm_update *update = NULL; + + pr_debug("%s: USB Switch enable %ld\n", __func__, + ucontrol->value.integer.value[0]); + if (ucontrol->value.integer.value[0]) + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, + 1, update); + else + snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, + 0, update); + usb_switch_enable = ucontrol->value.integer.value[0]; + return 1; +} static int msm_routing_get_fm_pcmrx_switch_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -5827,197 +5830,6 @@ static const struct snd_kcontrol_new voc_ext_ec_mux = SOC_DAPM_ENUM_EXT("VOC_EXT_EC MUX Mux", msm_route_ext_ec_ref_rx_enum[0], msm_routing_ext_ec_get, msm_routing_ext_ec_put); - -static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - static const struct snd_kcontrol_new pri_spdif_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, MSM_BACKEND_DAI_PRI_SPDIF_RX, @@ -6469,13 +6281,204 @@ static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = { msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE +static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, + MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, @@ -7456,17068 +7459,16656 @@ static const struct snd_kcontrol_new sec_meta_mi2s_rx_mixer_controls[] = { msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new hdmi_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), +static const struct snd_kcontrol_new int0_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_INT3_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new hdmi_ms_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), +static const struct snd_kcontrol_new int4_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_INT3_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new display_port_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), +static const struct snd_kcontrol_new sec_i2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new display_port1_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), +static const struct snd_kcontrol_new mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; - /* incall music delivery mixer */ -static const struct snd_kcontrol_new incall_music_delivery_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), +static const struct snd_kcontrol_new primary_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new incall_music2_delivery_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), +static const struct snd_kcontrol_new quat_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new slimbus_4_rx_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_RX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_RX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_RX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_RX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), +static const struct snd_kcontrol_new quin_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; -static const struct snd_kcontrol_new slimbus_6_rx_mixer_controls[] = { +static const struct snd_kcontrol_new sen_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + + +static const struct snd_kcontrol_new tert_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_mi2s_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new int0_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_int0_mi2s_switch_mixer, + msm_routing_put_int0_mi2s_switch_mixer); + +static const struct snd_kcontrol_new int4_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_int4_mi2s_switch_mixer, + msm_routing_put_int4_mi2s_switch_mixer); + +static const struct snd_kcontrol_new pri_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_pri_mi2s_switch_mixer, + msm_routing_put_pri_mi2s_switch_mixer); + +static const struct snd_kcontrol_new sec_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_sec_mi2s_switch_mixer, + msm_routing_put_sec_mi2s_switch_mixer); + +static const struct snd_kcontrol_new tert_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_tert_mi2s_switch_mixer, + msm_routing_put_tert_mi2s_switch_mixer); + +static const struct snd_kcontrol_new quat_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_quat_mi2s_switch_mixer, + msm_routing_put_quat_mi2s_switch_mixer); + +static const struct snd_kcontrol_new quin_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_quin_mi2s_switch_mixer, + msm_routing_put_quin_mi2s_switch_mixer); + +static const struct snd_kcontrol_new sen_mi2s_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_sen_mi2s_switch_mixer, + msm_routing_put_sen_mi2s_switch_mixer); +#endif + +static const struct snd_kcontrol_new hdmi_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_mixer_controls[] = { +static const struct snd_kcontrol_new hdmi_ms_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_HDMI_RX_MS, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new wsa_cdc_dma_rx_1_mixer_controls[] = { +static const struct snd_kcontrol_new display_port_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new rx_cdc_dma_rx_0_mixer_controls[] = { +static const struct snd_kcontrol_new display_port1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new rx_cdc_dma_rx_1_mixer_controls[] = { + /* incall music delivery mixer */ +static const struct snd_kcontrol_new incall_music_delivery_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new incall_music2_delivery_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new slimbus_4_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new slimbus_6_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_6_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new rx_cdc_dma_rx_2_mixer_controls[] = { +static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new rx_cdc_dma_rx_3_mixer_controls[] = { +static const struct snd_kcontrol_new wsa_cdc_dma_rx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new rx_cdc_dma_rx_4_mixer_controls[] = { +static const struct snd_kcontrol_new rx_cdc_dma_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new rx_cdc_dma_rx_5_mixer_controls[] = { +static const struct snd_kcontrol_new rx_cdc_dma_rx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new rx_cdc_dma_rx_6_mixer_controls[] = { +static const struct snd_kcontrol_new rx_cdc_dma_rx_2_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new rx_cdc_dma_rx_7_mixer_controls[] = { +static const struct snd_kcontrol_new rx_cdc_dma_rx_3_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new slimbus_7_rx_mixer_controls[] = { +static const struct snd_kcontrol_new rx_cdc_dma_rx_4_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new slimbus_9_rx_mixer_controls[] = { +static const struct snd_kcontrol_new rx_cdc_dma_rx_5_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new usb_audio_rx_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + +static const struct snd_kcontrol_new rx_cdc_dma_rx_6_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = { +static const struct snd_kcontrol_new rx_cdc_dma_rx_7_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new int_bt_a2dp_rx_mixer_controls[] = { +static const struct snd_kcontrol_new slimbus_7_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_A2DP_RX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = { +static const struct snd_kcontrol_new slimbus_9_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, + MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), }; - -static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = { +static const struct snd_kcontrol_new usb_audio_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_USB_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = { +static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = { +static const struct snd_kcontrol_new int_bt_a2dp_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_INT_BT_A2DP_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new tert_auxpcm_rx_mixer_controls[] = { +static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quat_auxpcm_rx_mixer_controls[] = { +static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quin_auxpcm_rx_mixer_controls[] = { +#ifndef CONFIG_AUXPCM_DISABLE +static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sen_auxpcm_rx_mixer_controls[] = { +static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia30", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = { +static const struct snd_kcontrol_new tert_auxpcm_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = { +static const struct snd_kcontrol_new quat_auxpcm_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = { +static const struct snd_kcontrol_new quin_auxpcm_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = { +static const struct snd_kcontrol_new sen_auxpcm_rx_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; +#endif -static const struct snd_kcontrol_new pri_tdm_tx_0_mixer_controls[] = { +#ifndef CONFIG_TDM_DISABLE +static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = { +static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = { +static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = { +static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = { +static const struct snd_kcontrol_new pri_tdm_tx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sec_tdm_tx_0_mixer_controls[] = { +static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new tert_tdm_rx_0_mixer_controls[] = { +static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new tert_tdm_tx_0_mixer_controls[] = { +static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_BACKEND_DAI_SEC_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new tert_tdm_rx_1_mixer_controls[] = { +static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = { +static const struct snd_kcontrol_new sec_tdm_tx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = { +static const struct snd_kcontrol_new tert_tdm_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = { +static const struct snd_kcontrol_new tert_tdm_tx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_4, + MSM_BACKEND_DAI_TERT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = { +static const struct snd_kcontrol_new tert_tdm_rx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quat_tdm_tx_0_mixer_controls[] = { +static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_BACKEND_DAI_TERT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quat_tdm_rx_1_mixer_controls[] = { +static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = { +static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_RX_4, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = { +static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quin_tdm_rx_0_mixer_controls[] = { +static const struct snd_kcontrol_new quat_tdm_tx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quin_tdm_tx_0_mixer_controls[] = { +static const struct snd_kcontrol_new quat_tdm_rx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quin_tdm_tx_1_mixer_controls[] = { +static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new quin_tdm_rx_1_mixer_controls[] = { - SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quin_tdm_tx_2_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_tx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quin_tdm_tx_3_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_tx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_rx_1_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sen_tdm_rx_0_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_tx_2_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sen_tdm_tx_0_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sen_tdm_rx_1_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_tx_3_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sen_tdm_rx_2_mixer_controls[] = { +static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia22", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia23", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia24", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia25", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new sen_tdm_rx_3_mixer_controls[] = { +static const struct snd_kcontrol_new sen_tdm_rx_0_mixer_controls[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_RX_0, MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), }; -static const struct snd_kcontrol_new mmul1_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul2_mixer_controls[] = { - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul3_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul4_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul5_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul6_mixer_controls[] = { - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul8_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul16_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul9_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul10_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT2_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; -static const struct snd_kcontrol_new mmul17_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul18_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul19_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul20_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul21_mixer_controls[] = { - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul22_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul23_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul24_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul25_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul27_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_9_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul28_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul29_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mmul30_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_FM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_RX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, - MSM_BACKEND_DAI_INCALL_RECORD_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, - msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_SPDIF_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), - SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_LOOPBACK_TX, - MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, - msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new sec_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new slimbus_6_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new usb_audio_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new display_port_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new display_port_rx1_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new pri_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new int0_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new int4_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new tert_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new quat_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new quin_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new sen_mi2s_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new sec_aux_pcm_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new tert_aux_pcm_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new quat_aux_pcm_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new quin_aux_pcm_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new sen_aux_pcm_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, MSM_BACKEND_DAI_SEN_AUXPCM_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, MSM_BACKEND_DAI_SEN_AUXPCM_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, MSM_BACKEND_DAI_SEN_AUXPCM_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new slimbus_7_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, -MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new slimbus_8_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new quat_tdm_rx_2_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new quin_tdm_rx_2_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new wsa_cdc_dma_rx_1_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_0_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_1_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_2_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_3_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_4_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_5_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_6_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_7_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new pri_tdm_rx_0_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new pri_tdm_rx_1_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new pri_tdm_rx_2_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new pri_tdm_rx_3_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new stub_rx_mixer_controls[] = { - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_EXTPROC_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_EXTPROC_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new slimbus_1_rx_mixer_controls[] = { - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = { - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new proxy_rx_voice_mixer_controls[] = { - SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PROXY_RX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PROXY_RX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_TX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("MI2S_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("INT_BT_SCO_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PROXY_TX_MMode1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PROXY_TX, MSM_FRONTEND_DAI_VOICEMMODE1, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_TX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("MI2S_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("INT_BT_SCO_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, - 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PROXY_TX_MMode2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PROXY_TX, MSM_FRONTEND_DAI_VOICEMMODE2, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("MI2S_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_Voip", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOIP, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_SINGLE_EXT("PRI_TDM_TX_3_Voip", MSM_BACKEND_DAI_PRI_TDM_TX_3, - MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { - SOC_DOUBLE_EXT("STUB_TX_HL", SND_SOC_NOPM, - MSM_BACKEND_DAI_EXTPROC_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("STUB_1_TX_HL", SND_SOC_NOPM, - MSM_BACKEND_DAI_EXTPROC_EC_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), -}; - -static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = { - SOC_DOUBLE_EXT("STUB_TX_HL", SND_SOC_NOPM, - MSM_BACKEND_DAI_EXTPROC_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("STUB_1_TX_HL", SND_SOC_NOPM, - MSM_BACKEND_DAI_EXTPROC_EC_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICE2_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), -}; - -static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = { - SOC_DOUBLE_EXT("STUB_TX_HL", SND_SOC_NOPM, - MSM_BACKEND_DAI_EXTPROC_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("STUB_1_TX_HL", SND_SOC_NOPM, - MSM_BACKEND_DAI_EXTPROC_EC_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOLTE_STUB, - 1, 0, msm_routing_get_voice_stub_mixer, - msm_routing_put_voice_stub_mixer), -}; - -static const struct snd_kcontrol_new tx_qchat_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_I2S_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, - msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("AUX_PCM_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("MI2S_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_8_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("USB_AUDIO_TX_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_TX, - MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, - msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_QCHAT", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_QCHAT, - 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), -}; - -static const struct snd_kcontrol_new int0_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_INT3_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT0_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new int4_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_INT3_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT4_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_port_mixer_controls[] = { - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_0_port_mixer_controls[] = { - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - -}; - -static const struct snd_kcontrol_new rx_cdc_dma_rx_1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_PRI_MI2S_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_MI2S_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SENARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_RX, - MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new aux_pcm_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_AUXPCM_RX, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_auxpcm_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_AUXPCM_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new tert_auxpcm_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_AUXPCM_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quat_auxpcm_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_AUXPCM_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quin_auxpcm_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_BACKEND_DAI_QUIN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_AUXPCM_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sen_auxpcm_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, - MSM_BACKEND_DAI_SEN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_AUXPCM_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sbus_1_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_RX, - MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sbus_3_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_BACKEND_DAI_INT_BT_SCO_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_BACKEND_DAI_AFE_PCM_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_BACKEND_DAI_AUXPCM_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_RX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_RX, - MSM_BACKEND_DAI_SLIMBUS_0_RX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sbus_6_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new bt_sco_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT_BT_SCO_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new afe_pcm_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_AFE_PCM_RX, - MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - - -static const struct snd_kcontrol_new hdmi_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new hdmi_rx_ms_port_mixer_controls[] = { - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_HDMI_RX_MS, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new display_port_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new display_port_rx1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_i2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_I2S_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_MI2S_RX, - MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new primary_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_MI2S_RX, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new usb_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_USB_RX, - MSM_BACKEND_DAI_USB_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quat_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quin_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUINARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sen_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SENARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new pri_tdm_rx_0_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new pri_tdm_rx_1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new pri_tdm_rx_2_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new pri_tdm_rx_3_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_PRI_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_tdm_rx_0_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_tdm_rx_1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_tdm_rx_2_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_tdm_rx_3_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_tdm_rx_7_port_mixer_controls[] = { - SOC_DOUBLE_EXT("TERT_TDM_TX_7", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEC_TDM_RX_7, - MSM_BACKEND_DAI_TERT_TDM_TX_7, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new tert_tdm_rx_0_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new tert_tdm_rx_1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new tert_tdm_rx_2_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new tert_tdm_rx_3_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quat_tdm_rx_0_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quat_tdm_rx_1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quat_tdm_rx_2_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quat_tdm_rx_3_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quat_tdm_rx_7_port_mixer_controls[] = { - SOC_DOUBLE_EXT("QUAT_TDM_TX_7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_7, - MSM_BACKEND_DAI_QUAT_TDM_TX_7, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUAT_TDM_RX_7, - MSM_BACKEND_DAI_QUIN_TDM_TX_7, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quin_tdm_rx_0_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quin_tdm_rx_1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quin_tdm_rx_2_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quin_tdm_rx_3_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sen_tdm_rx_0_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_0, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sen_tdm_rx_1_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_1, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sen_tdm_rx_2_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_2, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sen_tdm_rx_3_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_SEN_TDM_RX_3, - MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new quin_tdm_rx_7_port_mixer_controls[] = { - SOC_DOUBLE_EXT("TERT_TDM_TX_7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_7, - MSM_BACKEND_DAI_TERT_TDM_TX_7, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_TDM_TX_7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_7, - MSM_BACKEND_DAI_QUAT_TDM_TX_7, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_7", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_RX_7, - MSM_BACKEND_DAI_QUIN_TDM_TX_7, 1, 0, - msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new tert_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new sec_mi2s_rx_port_mixer_controls[] = { - SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), -}; - -static const struct snd_kcontrol_new lsm1_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_5_TX, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), -}; - -static const struct snd_kcontrol_new lsm2_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_1_TX", - SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_5_TX, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), -}; - -static const struct snd_kcontrol_new lsm3_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_5_TX, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), -}; - -static const struct snd_kcontrol_new lsm4_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_5_TX, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), -}; - -static const struct snd_kcontrol_new lsm5_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_5_TX, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), -}; - -static const struct snd_kcontrol_new lsm6_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_5_TX, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), -}; - -static const struct snd_kcontrol_new lsm7_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_5_TX, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), -}; - -static const struct snd_kcontrol_new lsm8_mixer_controls[] = { - SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_0_TX, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_1_TX, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_3_TX, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_4_TX, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_SLIMBUS_5_TX, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERTIARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, - MSM_BACKEND_DAI_INT3_MI2S_TX, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, - MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, - MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_QUIN_TDM_TX_0, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), - SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, - MSM_BACKEND_DAI_TERT_TDM_TX_0, - MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, - msm_routing_put_listen_mixer), -}; - -static const struct snd_kcontrol_new slim_fm_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_switch_mixer, - msm_routing_put_switch_mixer); - -static const struct snd_kcontrol_new slim1_fm_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_switch_mixer, - msm_routing_put_switch_mixer); - -static const struct snd_kcontrol_new slim3_fm_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_switch_mixer, - msm_routing_put_switch_mixer); - -static const struct snd_kcontrol_new slim4_fm_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_switch_mixer, - msm_routing_put_switch_mixer); - -static const struct snd_kcontrol_new cdc_dma_wsa_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_switch_mixer, - msm_routing_put_switch_mixer); - -static const struct snd_kcontrol_new cdc_dma_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_switch_mixer, - msm_routing_put_switch_mixer); - -static const struct snd_kcontrol_new cdc_dma_rx_1_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_switch_mixer, - msm_routing_put_switch_mixer); - -static const struct snd_kcontrol_new slim6_fm_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_switch_mixer, - msm_routing_put_switch_mixer); - -static const struct snd_kcontrol_new pcm_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_fm_pcmrx_switch_mixer, - msm_routing_put_fm_pcmrx_switch_mixer); - -static const struct snd_kcontrol_new int0_mi2s_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_int0_mi2s_switch_mixer, - msm_routing_put_int0_mi2s_switch_mixer); - -static const struct snd_kcontrol_new int4_mi2s_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_int4_mi2s_switch_mixer, - msm_routing_put_int4_mi2s_switch_mixer); - -static const struct snd_kcontrol_new pri_mi2s_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_pri_mi2s_switch_mixer, - msm_routing_put_pri_mi2s_switch_mixer); - -static const struct snd_kcontrol_new sec_mi2s_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_sec_mi2s_switch_mixer, - msm_routing_put_sec_mi2s_switch_mixer); - -static const struct snd_kcontrol_new tert_mi2s_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_tert_mi2s_switch_mixer, - msm_routing_put_tert_mi2s_switch_mixer); - -static const struct snd_kcontrol_new quat_mi2s_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_quat_mi2s_switch_mixer, - msm_routing_put_quat_mi2s_switch_mixer); - -static const struct snd_kcontrol_new quin_mi2s_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_quin_mi2s_switch_mixer, - msm_routing_put_quin_mi2s_switch_mixer); - -static const struct snd_kcontrol_new sen_mi2s_rx_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_sen_mi2s_switch_mixer, - msm_routing_put_sen_mi2s_switch_mixer); - -static const struct snd_kcontrol_new hfp_pri_aux_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_hfp_switch_mixer, - msm_routing_put_hfp_switch_mixer); - -static const struct snd_kcontrol_new hfp_aux_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_hfp_switch_mixer, - msm_routing_put_hfp_switch_mixer); - -static const struct snd_kcontrol_new hfp_int_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_hfp_switch_mixer, - msm_routing_put_hfp_switch_mixer); - -static const struct snd_kcontrol_new hfp_slim7_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_hfp_switch_mixer, - msm_routing_put_hfp_switch_mixer); - -static const struct snd_kcontrol_new usb_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_get_usb_switch_mixer, - msm_routing_put_usb_switch_mixer); - -static const struct snd_kcontrol_new a2dp_slim7_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_a2dp_switch_mixer_get, - msm_routing_a2dp_switch_mixer_put); - -static const struct snd_kcontrol_new sco_slim7_switch_mixer_controls = - SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, - 0, 1, 0, msm_routing_sco_switch_mixer_get, - msm_routing_sco_switch_mixer_put); - -static const struct soc_enum lsm_port_enum = - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_port_text), lsm_port_text); - -static const char * const lsm_func_text[] = { - "None", "AUDIO", "BEACON", "ULTRASOUND", "SWAUDIO", -}; -static const struct soc_enum lsm_func_enum = - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_func_text), lsm_func_text); - -static const struct snd_kcontrol_new lsm_controls[] = { - /* kcontrol of lsm_function */ - SOC_ENUM_EXT(SLIMBUS_0_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(SLIMBUS_1_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(SLIMBUS_2_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(SLIMBUS_3_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(SLIMBUS_4_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(SLIMBUS_5_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(TERT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(QUAT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(INT3_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(TX_CDC_DMA_TX_3_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(QUIN_TDM_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - SOC_ENUM_EXT(TERT_TDM_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, - msm_routing_lsm_func_get, msm_routing_lsm_func_put), - /* kcontrol of lsm_port */ - SOC_ENUM_EXT("LSM1 Port", lsm_port_enum, - msm_routing_lsm_port_get, - msm_routing_lsm_port_put), - SOC_ENUM_EXT("LSM2 Port", lsm_port_enum, - msm_routing_lsm_port_get, - msm_routing_lsm_port_put), - SOC_ENUM_EXT("LSM3 Port", lsm_port_enum, - msm_routing_lsm_port_get, - msm_routing_lsm_port_put), - SOC_ENUM_EXT("LSM4 Port", lsm_port_enum, - msm_routing_lsm_port_get, - msm_routing_lsm_port_put), - SOC_ENUM_EXT("LSM5 Port", lsm_port_enum, - msm_routing_lsm_port_get, - msm_routing_lsm_port_put), - SOC_ENUM_EXT("LSM6 Port", lsm_port_enum, - msm_routing_lsm_port_get, - msm_routing_lsm_port_put), - SOC_ENUM_EXT("LSM7 Port", lsm_port_enum, - msm_routing_lsm_port_get, - msm_routing_lsm_port_put), - SOC_ENUM_EXT("LSM8 Port", lsm_port_enum, - msm_routing_lsm_port_get, - msm_routing_lsm_port_put), -}; - -static const char * const aanc_slim_0_rx_text[] = { - "ZERO", "SLIMBUS_0_TX", "SLIMBUS_1_TX", "SLIMBUS_2_TX", "SLIMBUS_3_TX", - "SLIMBUS_4_TX", "SLIMBUS_5_TX", "SLIMBUS_6_TX" -}; - -static const struct soc_enum aanc_slim_0_rx_enum = - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(aanc_slim_0_rx_text), - aanc_slim_0_rx_text); - -static const struct snd_kcontrol_new aanc_slim_0_rx_mux[] = { - SOC_ENUM_EXT("AANC_SLIM_0_RX MUX", aanc_slim_0_rx_enum, - msm_routing_slim_0_rx_aanc_mux_get, - msm_routing_slim_0_rx_aanc_mux_put) -}; - -static int msm_routing_aanc_noise_level_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = aanc_level; - - return 0; -} - -static int msm_routing_aanc_noise_level_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - - mutex_lock(&routing_lock); - aanc_level = ucontrol->value.integer.value[0]; - pr_debug("%s: value: %ld\n", - __func__, ucontrol->value.integer.value[0]); - ret = afe_set_aanc_noise_level(aanc_level); - mutex_unlock(&routing_lock); - - return ret; -} - -static const struct snd_kcontrol_new aanc_noise_level[] = { - SOC_SINGLE_EXT("AANC Noise Level", SND_SOC_NOPM, 0, 255, - 0, msm_routing_aanc_noise_level_get, msm_routing_aanc_noise_level_put) -}; - -static int msm_routing_get_stereo_to_custom_stereo_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = is_custom_stereo_on; - return 0; -} - -static int msm_routing_put_stereo_to_custom_stereo_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int flag = 0, i = 0, rc = 0, idx = 0; - int be_index = 0, port_id, topo_id; - unsigned int session_id = 0; - uint16_t op_FL_ip_FL_weight = 0; - uint16_t op_FL_ip_FR_weight = 0; - uint16_t op_FR_ip_FL_weight = 0; - uint16_t op_FR_ip_FR_weight = 0; - - flag = ucontrol->value.integer.value[0]; - pr_debug("%s E flag %d\n", __func__, flag); - - if ((is_custom_stereo_on && flag) || (!is_custom_stereo_on && !flag)) { - pr_err("%s: is_custom_stereo_on %d, flag %d\n", - __func__, is_custom_stereo_on, flag); - return 0; - } - is_custom_stereo_on = flag ? true : false; - pr_debug("%s:is_custom_stereo_on %d\n", __func__, is_custom_stereo_on); - for (be_index = 0; be_index < MSM_BACKEND_DAI_MAX; be_index++) { - port_id = msm_bedais[be_index].port_id; - if (!msm_bedais[be_index].active) - continue; - if ((port_id != SLIMBUS_0_RX) && - (port_id != RT_PROXY_PORT_001_RX) && - (port_id != AFE_PORT_ID_PRIMARY_MI2S_RX) && - (port_id != AFE_PORT_ID_INT4_MI2S_RX)) - continue; - - for_each_set_bit(i, &msm_bedais[be_index].fe_sessions[0], - MSM_FRONTEND_DAI_MM_SIZE) { - if (fe_dai_map[i][SESSION_TYPE_RX].perf_mode != - LEGACY_PCM_MODE) - goto skip_send_custom_stereo; - session_id = - fe_dai_map[i][SESSION_TYPE_RX].strm_id; - if (is_custom_stereo_on) { - op_FL_ip_FL_weight = - Q14_GAIN_ZERO_POINT_FIVE; - op_FL_ip_FR_weight = - Q14_GAIN_ZERO_POINT_FIVE; - op_FR_ip_FL_weight = - Q14_GAIN_ZERO_POINT_FIVE; - op_FR_ip_FR_weight = - Q14_GAIN_ZERO_POINT_FIVE; - } else { - op_FL_ip_FL_weight = Q14_GAIN_UNITY; - op_FL_ip_FR_weight = 0; - op_FR_ip_FL_weight = 0; - op_FR_ip_FR_weight = Q14_GAIN_UNITY; - } - for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { - unsigned long copp = - session_copp_map[i] - [SESSION_TYPE_RX][be_index]; - if (!test_bit(idx, &copp)) - goto skip_send_custom_stereo; - topo_id = adm_get_topology_for_port_copp_idx( - msm_bedais[be_index].port_id, idx); - if (topo_id < 0) - pr_debug("%s:Err:custom stereo topo %d", - __func__, topo_id); - pr_debug("idx %d\n", idx); - if (topo_id == DS2_ADM_COPP_TOPOLOGY_ID) - rc = msm_ds2_dap_set_custom_stereo_onoff - (msm_bedais[be_index].port_id, - idx, is_custom_stereo_on); - else if (topo_id == DOLBY_ADM_COPP_TOPOLOGY_ID) - rc = dolby_dap_set_custom_stereo_onoff( - msm_bedais[be_index].port_id, - idx, is_custom_stereo_on); - else - rc = msm_qti_pp_send_stereo_to_custom_stereo_cmd - (msm_bedais[be_index].port_id, - idx, session_id, - op_FL_ip_FL_weight, - op_FL_ip_FR_weight, - op_FR_ip_FL_weight, - op_FR_ip_FR_weight); - if (rc < 0) -skip_send_custom_stereo: - pr_err("%s: err setting custom stereo\n", - __func__); - } - - } - } - return 0; -} - -static const struct snd_kcontrol_new stereo_to_custom_stereo_controls[] = { - SOC_SINGLE_EXT("Set Custom Stereo OnOff", SND_SOC_NOPM, 0, - 1, 0, msm_routing_get_stereo_to_custom_stereo_control, - msm_routing_put_stereo_to_custom_stereo_control), -}; - -static int msm_routing_get_app_type_cfg_control(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - return 0; -} - -static int msm_routing_put_app_type_cfg_control(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int i = 0, j; - int num_app_types = ucontrol->value.integer.value[i++]; - - pr_debug("%s\n", __func__); - - memset(app_type_cfg, 0, MAX_APP_TYPES* - sizeof(struct msm_pcm_routing_app_type_data)); - if (num_app_types > MAX_APP_TYPES) { - pr_err("%s: number of app types exceed the max supported\n", - __func__); - return -EINVAL; - } - for (j = 0; j < num_app_types; j++) { - app_type_cfg[j].app_type = - ucontrol->value.integer.value[i++]; - app_type_cfg[j].sample_rate = - ucontrol->value.integer.value[i++]; - app_type_cfg[j].bit_width = - ucontrol->value.integer.value[i++]; - } - - return 0; -} - -static int msm_routing_put_app_type_gain_control(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int j, fe_id, be_id, port_type; - int ret = 0; - unsigned long copp; - struct msm_pcm_routing_bdai_data *bedai; - int dir = ucontrol->value.integer.value[0] ? SESSION_TYPE_TX : - SESSION_TYPE_RX; - int app_type = ucontrol->value.integer.value[1]; - int gain = (ucontrol->value.integer.value[2] + - ucontrol->value.integer.value[3])/2; - - port_type = (dir == SESSION_TYPE_RX) ? MSM_AFE_PORT_TYPE_RX : - MSM_AFE_PORT_TYPE_TX; - - mutex_lock(&routing_lock); - for (be_id = 0; be_id < MSM_BACKEND_DAI_MAX; be_id++) { - if (is_be_dai_extproc(be_id)) - continue; - - bedai = &msm_bedais[be_id]; - if (afe_get_port_type(bedai->port_id) != port_type) - continue; - - if (!bedai->active) - continue; - - for (fe_id = 0; fe_id < MSM_FRONTEND_DAI_MAX; fe_id++) { - if (!test_bit(fe_id, &bedai->fe_sessions[0])) - continue; - - if (app_type != - fe_dai_app_type_cfg[fe_id][dir][be_id].app_type) - continue; - - copp = session_copp_map[fe_id][dir][be_id]; - for (j = 0; j < MAX_COPPS_PER_PORT; j++) { - if (!test_bit(j, &copp)) - continue; - ret |= adm_set_volume(bedai->port_id, j, gain); - } - } - } - mutex_unlock(&routing_lock); - return ret ? -EINVAL : 0; -} - -static const struct snd_kcontrol_new app_type_cfg_controls[] = { - SOC_SINGLE_MULTI_EXT("App Type Config", SND_SOC_NOPM, 0, - 0x7FFFFFFF, 0, 128, msm_routing_get_app_type_cfg_control, - msm_routing_put_app_type_cfg_control), - SOC_SINGLE_MULTI_EXT("App Type Gain", SND_SOC_NOPM, 0, - 0x2000, 0, 4, NULL, msm_routing_put_app_type_gain_control) -}; - -static int msm_routing_put_module_cfg_control(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int copp_idx, fe_id, be_id, port_type; - int ret = 0; - unsigned long copp; - struct msm_pcm_routing_bdai_data *bedai; - u8 *packed_params = NULL; - struct param_hdr_v3 param_hdr; - u32 packed_param_size = (sizeof(struct param_hdr_v3) + - sizeof(uint32_t)); - - int dir = ucontrol->value.integer.value[0] ? SESSION_TYPE_TX : - SESSION_TYPE_RX; - int app_type = ucontrol->value.integer.value[1]; - int module_id = ucontrol->value.integer.value[2]; - int instance_id = ucontrol->value.integer.value[3]; - int param_id = ucontrol->value.integer.value[4]; - int param_value = ucontrol->value.integer.value[5]; - - port_type = (dir == SESSION_TYPE_RX) ? MSM_AFE_PORT_TYPE_RX : - MSM_AFE_PORT_TYPE_TX; - pr_debug("%s app_type:%d mod_id:%d instance_id:%d param_id:%d value:%d\n", - __func__, app_type, module_id, - instance_id, param_id, param_value); - - packed_params = kzalloc(packed_param_size, GFP_KERNEL); - if (!packed_params) - return -ENOMEM; - - memset(¶m_hdr, 0, sizeof(param_hdr)); - param_hdr.module_id = module_id; - param_hdr.instance_id = instance_id; - param_hdr.param_id = param_id; - param_hdr.param_size = sizeof(uint32_t); - - packed_param_size = 0; - - mutex_lock(&routing_lock); - for (be_id = 0; be_id < MSM_BACKEND_DAI_MAX; be_id++) { - if (is_be_dai_extproc(be_id)) - continue; - - bedai = &msm_bedais[be_id]; - if (afe_get_port_type(bedai->port_id) != port_type) - continue; - - if (!bedai->active) - continue; - - for (fe_id = 0; fe_id < MSM_FRONTEND_DAI_MAX; fe_id++) { - if (!test_bit(fe_id, &bedai->fe_sessions[0])) - continue; - - if (app_type != - fe_dai_app_type_cfg[fe_id][dir][be_id].app_type) - continue; - - copp = session_copp_map[fe_id][dir][be_id]; - for (copp_idx = 0; copp_idx < MAX_COPPS_PER_PORT; - copp_idx++) { - if (!test_bit(copp_idx, &copp)) - continue; - - ret = q6common_pack_pp_params(packed_params, - ¶m_hdr, - (u8 *) ¶m_value, - &packed_param_size); - if (ret) { - pr_err("%s: Failed to pack params, error %d\n", - __func__, ret); - goto done; - } - - ret = adm_set_pp_params(bedai->port_id, - copp_idx, NULL, - packed_params, - packed_param_size); - if (ret) { - pr_err("%s: Setting param failed with err=%d\n", - __func__, ret); - ret = -EINVAL; - goto done; - } - } - } - } -done: - mutex_unlock(&routing_lock); - kfree(packed_params); - return ret; -} - -static const struct snd_kcontrol_new module_cfg_controls[] = { - SOC_SINGLE_MULTI_EXT("Audio Effect", SND_SOC_NOPM, 0, - 0x2000, 0, 6, NULL, msm_routing_put_module_cfg_control) -}; - -static int msm_routing_get_lsm_app_type_cfg_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int shift = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - int i = 0, j = 0; - - mutex_lock(&routing_lock); - ucontrol->value.integer.value[i] = num_app_cfg_types; - - for (j = 0; j < num_app_cfg_types; ++j) { - ucontrol->value.integer.value[++i] = - lsm_app_type_cfg[j].app_type; - ucontrol->value.integer.value[++i] = - lsm_app_type_cfg[j].sample_rate; - ucontrol->value.integer.value[++i] = - lsm_app_type_cfg[j].bit_width; - if (shift == 1) - ucontrol->value.integer.value[++i] = - lsm_app_type_cfg[j].num_out_channels; - } - mutex_unlock(&routing_lock); - return 0; -} - -static int msm_routing_put_lsm_app_type_cfg_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int shift = ((struct soc_multi_mixer_control *) - kcontrol->private_value)->shift; - int i = 0, j; - - mutex_lock(&routing_lock); - if (ucontrol->value.integer.value[0] > MAX_APP_TYPES) { - pr_err("%s: number of app types exceed the max supported\n", - __func__); - mutex_unlock(&routing_lock); - return -EINVAL; - } - - num_app_cfg_types = ucontrol->value.integer.value[i++]; - memset(lsm_app_type_cfg, 0, MAX_APP_TYPES* - sizeof(struct msm_pcm_routing_app_type_data)); - - for (j = 0; j < num_app_cfg_types; j++) { - lsm_app_type_cfg[j].app_type = - ucontrol->value.integer.value[i++]; - lsm_app_type_cfg[j].sample_rate = - ucontrol->value.integer.value[i++]; - lsm_app_type_cfg[j].bit_width = - ucontrol->value.integer.value[i++]; - /* Shift of 1 indicates this is V2 mixer control */ - if (shift == 1) - lsm_app_type_cfg[j].num_out_channels = - ucontrol->value.integer.value[i++]; - } - mutex_unlock(&routing_lock); - return 0; -} - -static const struct snd_kcontrol_new lsm_app_type_cfg_controls[] = { - SOC_SINGLE_MULTI_EXT("Listen App Type Config", SND_SOC_NOPM, 0, - 0xFFFFFFFF, 0, 128, msm_routing_get_lsm_app_type_cfg_control, - msm_routing_put_lsm_app_type_cfg_control), - SOC_SINGLE_MULTI_EXT("Listen App Type Config V2", SND_SOC_NOPM, 1, - 0xFFFFFFFF, 0, 128, msm_routing_get_lsm_app_type_cfg_control, - msm_routing_put_lsm_app_type_cfg_control), -}; - -static int msm_routing_get_use_ds1_or_ds2_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = is_ds2_on; - return 0; -} - -static int msm_routing_put_use_ds1_or_ds2_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - is_ds2_on = ucontrol->value.integer.value[0]; - return 0; -} - -static const struct snd_kcontrol_new use_ds1_or_ds2_controls[] = { - SOC_SINGLE_EXT("DS2 OnOff", SND_SOC_NOPM, 0, - 1, 0, msm_routing_get_use_ds1_or_ds2_control, - msm_routing_put_use_ds1_or_ds2_control), -}; - -static int msm_routing_get_hifi_filter_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = hifi_filter_enabled; - return 0; -} - -static int msm_routing_put_hifi_filter_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - hifi_filter_enabled = ucontrol->value.integer.value[0]; - return 0; -} - -static const struct snd_kcontrol_new hifi_filter_controls[] = { - SOC_SINGLE_EXT("HiFi Filter", SND_SOC_NOPM, 0, - 1, 0, msm_routing_get_hifi_filter_control, - msm_routing_put_hifi_filter_control), -}; - -static int msm_routing_get_ffecns_freeze_event_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = ffecns_freeze_event; - return 0; -} - -static int msm_routing_put_ffecns_freeze_event_control( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = -EINVAL; - - ffecns_freeze_event = ucontrol->value.integer.value[0]; - - ret = adm_set_ffecns_freeze_event(ffecns_freeze_event); - if (ret) - pr_err("%s: failed to set ffecns imc event to%d\n", - __func__, ffecns_freeze_event); - - return ret; -} - -static const struct snd_kcontrol_new use_ffecns_freeze_event_controls[] = { - SOC_SINGLE_EXT("FFECNS Freeze Event", SND_SOC_NOPM, 0, - 1, 0, msm_routing_get_ffecns_freeze_event_control, - msm_routing_put_ffecns_freeze_event_control), -}; - -int msm_routing_get_rms_value_control(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) { - int rc = 0; - int be_idx = 0; - char *param_value; - int *update_param_value; - uint32_t param_size = (RMS_PAYLOAD_LEN + 1) * sizeof(uint32_t); - struct param_hdr_v3 param_hdr; - - param_value = kzalloc(param_size, GFP_KERNEL); - if (!param_value) - return -ENOMEM; - - memset(¶m_hdr, 0, sizeof(param_hdr)); - for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) - if (msm_bedais[be_idx].port_id == SLIMBUS_0_TX) - break; - if ((be_idx < MSM_BACKEND_DAI_MAX) && msm_bedais[be_idx].active) { - param_hdr.module_id = RMS_MODULEID_APPI_PASSTHRU; - param_hdr.instance_id = INSTANCE_ID_0; - param_hdr.param_id = RMS_PARAM_FIRST_SAMPLE; - param_hdr.param_size = param_size; - rc = adm_get_pp_params(SLIMBUS_0_TX, 0, ADM_CLIENT_ID_DEFAULT, - NULL, ¶m_hdr, (u8 *) param_value); - if (rc) { - pr_err("%s: get parameters failed:%d\n", __func__, rc); - kfree(param_value); - return -EINVAL; - } - update_param_value = (int *)param_value; - ucontrol->value.integer.value[0] = update_param_value[0]; - - pr_debug("%s: FROM DSP value[0] 0x%x\n", - __func__, update_param_value[0]); - } - kfree(param_value); - return 0; -} - -static int msm_voc_session_id_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - voc_session_id = ucontrol->value.integer.value[0]; - - pr_debug("%s: voc_session_id=%u\n", __func__, voc_session_id); - - return 0; -} - -static int msm_voc_session_id_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = voc_session_id; - - return 0; -} - -static struct snd_kcontrol_new msm_voc_session_controls[] = { - SOC_SINGLE_MULTI_EXT("Voc VSID", SND_SOC_NOPM, 0, - 0xFFFFFFFF, 0, 1, msm_voc_session_id_get, - msm_voc_session_id_put), -}; - -static int msm_sound_focus_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; - uinfo->count = sizeof(struct sound_focus_param); - - return 0; -} - -static int msm_voice_sound_focus_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct sound_focus_param soundFocusData; - - memcpy((void *)&soundFocusData, ucontrol->value.bytes.data, - sizeof(struct sound_focus_param)); - ret = voc_set_sound_focus(soundFocusData); - if (ret) { - pr_err("%s: Error setting Sound Focus Params, err=%d\n", - __func__, ret); - - ret = -EINVAL; - } - - return ret; -} - -static int msm_voice_sound_focus_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct sound_focus_param soundFocusData; - - memset(&soundFocusData, 0, sizeof(struct sound_focus_param)); - - ret = voc_get_sound_focus(&soundFocusData); - if (ret) { - pr_debug("%s: Error getting Sound Focus Params, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - memcpy(ucontrol->value.bytes.data, (void *)&soundFocusData, - sizeof(struct sound_focus_param)); - -done: - return ret; -} - -static int msm_source_tracking_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; - uinfo->count = sizeof(struct source_tracking_param); - - return 0; -} - -static int msm_voice_source_tracking_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct source_tracking_param sourceTrackingData; - - memset(&sourceTrackingData, 0, sizeof(struct source_tracking_param)); - - ret = voc_get_source_tracking(&sourceTrackingData); - if (ret) { - pr_debug("%s: Error getting Source Tracking Params, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - memcpy(ucontrol->value.bytes.data, (void *)&sourceTrackingData, - sizeof(struct source_tracking_param)); - -done: - return ret; -} - -static int msm_audio_get_copp_idx_from_port_id(int port_id, int session_type, - int *copp_idx) -{ - int i, idx, be_idx; - int ret = 0; - unsigned long copp; - - pr_debug("%s: Enter, port_id=%d\n", __func__, port_id); - - ret = q6audio_validate_port(port_id); - if (ret < 0) { - pr_err("%s: port validation failed id 0x%x ret %d\n", - __func__, port_id, ret); - - ret = -EINVAL; - goto done; - } - - for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) { - if (msm_bedais[be_idx].port_id == port_id) - break; - } - if (be_idx >= MSM_BACKEND_DAI_MAX) { - pr_err("%s: Invalid be id %d\n", __func__, be_idx); - - ret = -EINVAL; - goto done; - } - - for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0], - MSM_FRONTEND_DAI_MAX) { - if (!(is_mm_lsm_fe_id(i) && - route_check_fe_id_adm_support(i))) - continue; - - for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { - copp = session_copp_map[i] - [session_type][be_idx]; - if (test_bit(idx, &copp)) - break; - } - if (idx >= MAX_COPPS_PER_PORT) - continue; - else - break; - } - if (i >= MSM_FRONTEND_DAI_MAX) { - pr_debug("%s: Invalid FE, exiting\n", __func__); - - ret = -EINVAL; - goto done; - } - *copp_idx = idx; - pr_debug("%s: copp_idx=%d\n", __func__, *copp_idx); - -done: - return ret; -} - -static int msm_audio_sound_focus_derive_port_id(struct snd_kcontrol *kcontrol, - const char *prefix, int *port_id) -{ - int ret = 0; - - pr_debug("%s: Enter, prefix:%s\n", __func__, prefix); - - /* - * Mixer control name will be like "Sound Focus Audio Tx SLIMBUS_0" - * where the prefix is "Sound Focus Audio Tx ". Skip the prefix - * and compare the string with the backend name to derive the port id. - */ - if (!strcmp(kcontrol->id.name + strlen(prefix), - "SLIMBUS_0")) { - *port_id = SLIMBUS_0_TX; - } else if (!strcmp(kcontrol->id.name + strlen(prefix), - "TERT_MI2S")) { - *port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; - } else if (!strcmp(kcontrol->id.name + strlen(prefix), - "INT3_MI2S")) { - *port_id = AFE_PORT_ID_INT3_MI2S_TX; - } else if (!strcmp(kcontrol->id.name + strlen(prefix), - "VA_CDC_DMA_TX_0")) { - *port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0; - } else if (!strcmp(kcontrol->id.name + strlen(prefix), - "TX_CDC_DMA_TX_3")) { - *port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3; - } else if (!strcmp(kcontrol->id.name + strlen(prefix), - "QUIN_TDM_TX_0")) { - *port_id = AFE_PORT_ID_QUINARY_TDM_TX; - } else if (!strcmp(kcontrol->id.name + strlen(prefix), - "PRIMARY_TDM")) { - *port_id = AFE_PORT_ID_PRIMARY_TDM_TX; - } else { - pr_err("%s: mixer ctl name=%s, could not derive valid port id\n", - __func__, kcontrol->id.name); - - ret = -EINVAL; - goto done; - } - pr_debug("%s: mixer ctl name=%s, derived port_id=%d\n", - __func__, kcontrol->id.name, *port_id); - -done: - return ret; -} - -static int msm_audio_sound_focus_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct sound_focus_param soundFocusData; - int port_id, copp_idx; - - ret = msm_audio_sound_focus_derive_port_id(kcontrol, - "Sound Focus Audio Tx ", &port_id); - if (ret != 0) { - pr_err("%s: Error in deriving port id, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - - ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, - &copp_idx); - if (ret) { - pr_err("%s: Could not get copp idx for port_id=%d\n", - __func__, port_id); - - ret = -EINVAL; - goto done; - } - - memcpy((void *)&soundFocusData, ucontrol->value.bytes.data, - sizeof(struct sound_focus_param)); - - ret = adm_set_sound_focus(port_id, copp_idx, soundFocusData); - if (ret) { - pr_err("%s: Error setting Sound Focus Params, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - -done: - return ret; -} - -static int msm_audio_sound_focus_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct sound_focus_param soundFocusData; - int port_id, copp_idx; - - ret = msm_audio_sound_focus_derive_port_id(kcontrol, - "Sound Focus Audio Tx ", &port_id); - if (ret) { - pr_err("%s: Error in deriving port id, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - - ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, - &copp_idx); - if (ret) { - pr_debug("%s: Could not get copp idx for port_id=%d\n", - __func__, port_id); - - ret = -EINVAL; - goto done; - } - - ret = adm_get_sound_focus(port_id, copp_idx, &soundFocusData); - if (ret) { - pr_err("%s: Error getting Sound Focus Params, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - - memcpy(ucontrol->value.bytes.data, (void *)&soundFocusData, - sizeof(struct sound_focus_param)); - -done: - return ret; -} - -static int msm_audio_source_tracking_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct source_tracking_param sourceTrackingData; - int port_id, copp_idx; - - ret = msm_audio_sound_focus_derive_port_id(kcontrol, - "Source Tracking Audio Tx ", &port_id); - if (ret) { - pr_err("%s: Error in deriving port id, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - - ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, - &copp_idx); - if (ret) { - pr_debug("%s: Could not get copp idx for port_id=%d\n", - __func__, port_id); - - ret = -EINVAL; - goto done; - } - - ret = adm_get_source_tracking(port_id, copp_idx, &sourceTrackingData); - if (ret) { - pr_err("%s: Error getting Source Tracking Params, err=%d\n", - __func__, ret); - - ret = -EINVAL; - goto done; - } - - memcpy(ucontrol->value.bytes.data, (void *)&sourceTrackingData, - sizeof(struct source_tracking_param)); - -done: - return ret; -} - -static int msm_doa_tracking_mon_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; - uinfo->count = sizeof(struct doa_tracking_mon_param); - - return 0; -} - -static int msm_doa_tracking_mon_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - struct doa_tracking_mon_param doa_tracking_data; - int port_id, copp_idx; - - memset(&doa_tracking_data, 0, sizeof(struct doa_tracking_mon_param)); - ret = msm_audio_sound_focus_derive_port_id(kcontrol, - "Doa Tracking Monitor Listen ", &port_id); - if (ret) { - pr_err("%s: Error in deriving port id, err=%d\n", - __func__, ret); - ret = -EINVAL; - goto done; - } - - /* - * If copp id exists for given port id, query adm to get doa data. - * Else query afe for doa tracking params. - * This is to support in cases where LSM directly connects to - * AFE for FFNS. - */ - ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, - &copp_idx); - if (!ret) - ret = adm_get_doa_tracking_mon(port_id, copp_idx, - &doa_tracking_data); - else - ret = afe_get_doa_tracking_mon(port_id, &doa_tracking_data); - - if (ret) { - pr_err("%s: Error getting Doa Tracking Params, err=%d\n", - __func__, ret); - ret = -EINVAL; - goto done; - } - - memcpy(ucontrol->value.bytes.data, (void *)&doa_tracking_data, - sizeof(struct doa_tracking_mon_param)); -done: - return ret; -} - -static const struct snd_kcontrol_new msm_source_tracking_controls[] = { - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Voice Tx SLIMBUS_0", - .info = msm_sound_focus_info, - .get = msm_voice_sound_focus_get, - .put = msm_voice_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Voice Tx SLIMBUS_0", - .info = msm_source_tracking_info, - .get = msm_voice_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Audio Tx SLIMBUS_0", - .info = msm_sound_focus_info, - .get = msm_audio_sound_focus_get, - .put = msm_audio_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Audio Tx SLIMBUS_0", - .info = msm_source_tracking_info, - .get = msm_audio_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Voice Tx TERT_MI2S", - .info = msm_sound_focus_info, - .get = msm_voice_sound_focus_get, - .put = msm_voice_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Voice Tx TERT_MI2S", - .info = msm_source_tracking_info, - .get = msm_voice_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Audio Tx TERT_MI2S", - .info = msm_sound_focus_info, - .get = msm_audio_sound_focus_get, - .put = msm_audio_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Audio Tx TERT_MI2S", - .info = msm_source_tracking_info, - .get = msm_audio_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Voice Tx INT3_MI2S", - .info = msm_sound_focus_info, - .get = msm_voice_sound_focus_get, - .put = msm_voice_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Voice Tx INT3_MI2S", - .info = msm_source_tracking_info, - .get = msm_voice_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Audio Tx INT3_MI2S", - .info = msm_sound_focus_info, - .get = msm_audio_sound_focus_get, - .put = msm_audio_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Audio Tx INT3_MI2S", - .info = msm_source_tracking_info, - .get = msm_audio_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Voice Tx VA_CDC_DMA_TX_0", - .info = msm_sound_focus_info, - .get = msm_voice_sound_focus_get, - .put = msm_voice_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Voice Tx VA_CDC_DMA_TX_0", - .info = msm_source_tracking_info, - .get = msm_voice_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Audio Tx VA_CDC_DMA_TX_0", - .info = msm_sound_focus_info, - .get = msm_audio_sound_focus_get, - .put = msm_audio_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Audio Tx VA_CDC_DMA_TX_0", - .info = msm_source_tracking_info, - .get = msm_audio_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Voice Tx TX_CDC_DMA_TX_3", - .info = msm_sound_focus_info, - .get = msm_voice_sound_focus_get, - .put = msm_voice_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Voice Tx TX_CDC_DMA_TX_3", - .info = msm_source_tracking_info, - .get = msm_voice_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Audio Tx TX_CDC_DMA_TX_3", - .info = msm_sound_focus_info, - .get = msm_audio_sound_focus_get, - .put = msm_audio_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Audio Tx TX_CDC_DMA_TX_3", - .info = msm_source_tracking_info, - .get = msm_audio_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Voice Tx QUIN_TDM_TX_0", - .info = msm_sound_focus_info, - .get = msm_voice_sound_focus_get, - .put = msm_voice_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Voice Tx QUIN_TDM_TX_0", - .info = msm_source_tracking_info, - .get = msm_voice_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Audio Tx QUIN_TDM_TX_0", - .info = msm_sound_focus_info, - .get = msm_audio_sound_focus_get, - .put = msm_audio_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Audio Tx QUIN_TDM_TX_0", - .info = msm_source_tracking_info, - .get = msm_audio_source_tracking_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Sound Focus Audio Tx PRIMARY_TDM", - .info = msm_sound_focus_info, - .get = msm_audio_sound_focus_get, - .put = msm_audio_sound_focus_put, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Source Tracking Audio Tx PRIMARY_TDM", - .info = msm_source_tracking_info, - .get = msm_audio_source_tracking_get, - }, -}; - -static const struct snd_kcontrol_new msm_source_doa_tracking_controls[] = { - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Doa Tracking Monitor Listen VA_CDC_DMA_TX_0", - .info = msm_doa_tracking_mon_info, - .get = msm_doa_tracking_mon_get, - }, -}; - -static int spkr_prot_put_vi_lch_port(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - int item; - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - - pr_debug("%s item is %d\n", __func__, - ucontrol->value.enumerated.item[0]); - mutex_lock(&routing_lock); - item = ucontrol->value.enumerated.item[0]; - if (item < e->items) { - pr_debug("%s RX DAI ID %d TX DAI id %d\n", - __func__, e->shift_l, e->values[item]); - if (e->shift_l < MSM_BACKEND_DAI_MAX && - e->values[item] < MSM_BACKEND_DAI_MAX) - /* Enable feedback TX path */ - ret = afe_spk_prot_feed_back_cfg( - msm_bedais[e->values[item]].port_id, - msm_bedais[e->shift_l].port_id, 1, 0, 1); - else { - pr_debug("%s values are out of range item %d\n", - __func__, e->values[item]); - /* Disable feedback TX path */ - if (e->values[item] == MSM_BACKEND_DAI_MAX) - ret = afe_spk_prot_feed_back_cfg(0, 0, 0, 0, 0); - else - ret = -EINVAL; - } - } else { - pr_err("%s item value is out of range item\n", __func__); - ret = -EINVAL; - } - mutex_unlock(&routing_lock); - return ret; -} - -static int spkr_prot_put_vi_rch_port(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int ret = 0; - int item; - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - - pr_debug("%s item is %d\n", __func__, - ucontrol->value.enumerated.item[0]); - mutex_lock(&routing_lock); - item = ucontrol->value.enumerated.item[0]; - if (item < e->items) { - pr_debug("%s RX DAI ID %d TX DAI id %d\n", - __func__, e->shift_l, e->values[item]); - if (e->shift_l < MSM_BACKEND_DAI_MAX && - e->values[item] < MSM_BACKEND_DAI_MAX) - /* Enable feedback TX path */ - ret = afe_spk_prot_feed_back_cfg( - msm_bedais[e->values[item]].port_id, - msm_bedais[e->shift_l].port_id, - 1, 1, 1); - else { - pr_debug("%s values are out of range item %d\n", - __func__, e->values[item]); - /* Disable feedback TX path */ - if (e->values[item] == MSM_BACKEND_DAI_MAX) - ret = afe_spk_prot_feed_back_cfg(0, - 0, 0, 0, 0); - else - ret = -EINVAL; - } - } else { - pr_err("%s item value is out of range item\n", __func__); - ret = -EINVAL; - } - mutex_unlock(&routing_lock); - return ret; -} - -static int spkr_prot_get_vi_lch_port(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s\n", __func__); - return 0; -} - -static int spkr_prot_get_vi_rch_port(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - pr_debug("%s\n", __func__); - ucontrol->value.enumerated.item[0] = 0; - return 0; -} - -static const char * const slim0_rx_vi_fb_tx_lch_mux_text[] = { - "ZERO", "SLIM4_TX" -}; - -static const char * const slim0_rx_vi_fb_tx_rch_mux_text[] = { - "ZERO", "SLIM4_TX" -}; - -static const char * const wsa_rx_0_vi_fb_tx_lch_mux_text[] = { - "ZERO", "WSA_CDC_DMA_TX_0" -}; - -static const char * const wsa_rx_0_vi_fb_tx_rch_mux_text[] = { - "ZERO", "WSA_CDC_DMA_TX_0" -}; - -static const char * const mi2s_rx_vi_fb_tx_mux_text[] = { - "ZERO", "SENARY_TX" -}; - -static const char * const int4_mi2s_rx_vi_fb_tx_mono_mux_text[] = { - "ZERO", "INT5_MI2S_TX" -}; - -static const char * const int4_mi2s_rx_vi_fb_tx_stereo_mux_text[] = { - "ZERO", "INT5_MI2S_TX" -}; - -static const int slim0_rx_vi_fb_tx_lch_value[] = { - MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SLIMBUS_4_TX -}; - -static const int slim0_rx_vi_fb_tx_rch_value[] = { - MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SLIMBUS_4_TX -}; - -static const int wsa_rx_0_vi_fb_tx_lch_value[] = { - MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0 -}; - -static const int wsa_rx_0_vi_fb_tx_rch_value[] = { - MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0 -}; - - -static const int mi2s_rx_vi_fb_tx_value[] = { - MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SENARY_MI2S_TX -}; - -static const int int4_mi2s_rx_vi_fb_tx_mono_ch_value[] = { - MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_INT5_MI2S_TX -}; - -static const int int4_mi2s_rx_vi_fb_tx_stereo_ch_value[] = { - MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_INT5_MI2S_TX -}; - -static const struct soc_enum slim0_rx_vi_fb_lch_mux_enum = - SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_SLIMBUS_0_RX, 0, 0, - ARRAY_SIZE(slim0_rx_vi_fb_tx_lch_mux_text), - slim0_rx_vi_fb_tx_lch_mux_text, slim0_rx_vi_fb_tx_lch_value); - -static const struct soc_enum slim0_rx_vi_fb_rch_mux_enum = - SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_SLIMBUS_0_RX, 0, 0, - ARRAY_SIZE(slim0_rx_vi_fb_tx_rch_mux_text), - slim0_rx_vi_fb_tx_rch_mux_text, slim0_rx_vi_fb_tx_rch_value); - -static const struct soc_enum wsa_rx_0_vi_fb_lch_mux_enum = - SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, 0, 0, - ARRAY_SIZE(wsa_rx_0_vi_fb_tx_lch_mux_text), - wsa_rx_0_vi_fb_tx_lch_mux_text, wsa_rx_0_vi_fb_tx_lch_value); - -static const struct soc_enum wsa_rx_0_vi_fb_rch_mux_enum = - SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, 0, 0, - ARRAY_SIZE(wsa_rx_0_vi_fb_tx_rch_mux_text), - wsa_rx_0_vi_fb_tx_rch_mux_text, wsa_rx_0_vi_fb_tx_rch_value); - -static const struct soc_enum mi2s_rx_vi_fb_mux_enum = - SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_PRI_MI2S_RX, 0, 0, - ARRAY_SIZE(mi2s_rx_vi_fb_tx_mux_text), - mi2s_rx_vi_fb_tx_mux_text, mi2s_rx_vi_fb_tx_value); - -static const struct soc_enum int4_mi2s_rx_vi_fb_mono_ch_mux_enum = - SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_INT4_MI2S_RX, 0, 0, - ARRAY_SIZE(int4_mi2s_rx_vi_fb_tx_mono_mux_text), - int4_mi2s_rx_vi_fb_tx_mono_mux_text, - int4_mi2s_rx_vi_fb_tx_mono_ch_value); - -static const struct soc_enum int4_mi2s_rx_vi_fb_stereo_ch_mux_enum = - SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_INT4_MI2S_RX, 0, 0, - ARRAY_SIZE(int4_mi2s_rx_vi_fb_tx_stereo_mux_text), - int4_mi2s_rx_vi_fb_tx_stereo_mux_text, - int4_mi2s_rx_vi_fb_tx_stereo_ch_value); - -static const struct snd_kcontrol_new slim0_rx_vi_fb_lch_mux = - SOC_DAPM_ENUM_EXT("SLIM0_RX_VI_FB_LCH_MUX", - slim0_rx_vi_fb_lch_mux_enum, spkr_prot_get_vi_lch_port, - spkr_prot_put_vi_lch_port); - -static const struct snd_kcontrol_new slim0_rx_vi_fb_rch_mux = - SOC_DAPM_ENUM_EXT("SLIM0_RX_VI_FB_RCH_MUX", - slim0_rx_vi_fb_rch_mux_enum, spkr_prot_get_vi_rch_port, - spkr_prot_put_vi_rch_port); - -static const struct snd_kcontrol_new wsa_rx_0_vi_fb_lch_mux = - SOC_DAPM_ENUM_EXT("WSA_RX_0_VI_FB_LCH_MUX", - wsa_rx_0_vi_fb_lch_mux_enum, spkr_prot_get_vi_lch_port, - spkr_prot_put_vi_lch_port); - -static const struct snd_kcontrol_new wsa_rx_0_vi_fb_rch_mux = - SOC_DAPM_ENUM_EXT("WSA_RX_0_VI_FB_RCH_MUX", - wsa_rx_0_vi_fb_rch_mux_enum, spkr_prot_get_vi_rch_port, - spkr_prot_put_vi_rch_port); - -static const struct snd_kcontrol_new mi2s_rx_vi_fb_mux = - SOC_DAPM_ENUM_EXT("PRI_MI2S_RX_VI_FB_MUX", - mi2s_rx_vi_fb_mux_enum, spkr_prot_get_vi_lch_port, - spkr_prot_put_vi_lch_port); - -static const struct snd_kcontrol_new int4_mi2s_rx_vi_fb_mono_ch_mux = - SOC_DAPM_ENUM_EXT("INT4_MI2S_RX_VI_FB_MONO_CH_MUX", - int4_mi2s_rx_vi_fb_mono_ch_mux_enum, spkr_prot_get_vi_lch_port, - spkr_prot_put_vi_lch_port); - -static const struct snd_kcontrol_new int4_mi2s_rx_vi_fb_stereo_ch_mux = - SOC_DAPM_ENUM_EXT("INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", - int4_mi2s_rx_vi_fb_stereo_ch_mux_enum, spkr_prot_get_vi_rch_port, - spkr_prot_put_vi_rch_port); - -static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { - /* Frontend AIF */ - /* Widget name equals to Front-End DAI name, - * Stream name must contains substring of front-end dai name - */ - SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL5", "MultiMedia5 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL6", "MultiMedia6 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL7", "MultiMedia7 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL8", "MultiMedia8 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL9", "MultiMedia9 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL10", "MultiMedia10 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL11", "MultiMedia11 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL12", "MultiMedia12 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL13", "MultiMedia13 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL14", "MultiMedia14 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL15", "MultiMedia15 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL16", "MultiMedia16 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL20", "MultiMedia20 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL21", "MultiMedia21 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL22", "MultiMedia22 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL23", "MultiMedia23 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL24", "MultiMedia24 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL25", "MultiMedia25 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MM_DL26", "MultiMedia26 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL3", "MultiMedia3 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL4", "MultiMedia4 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL5", "MultiMedia5 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL9", "MultiMedia9 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL10", "MultiMedia10 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL16", "MultiMedia16 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL17", "MultiMedia17 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL18", "MultiMedia18 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL19", "MultiMedia19 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL20", "MultiMedia20 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL21", "MultiMedia21 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL22", "MultiMedia22 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL23", "MultiMedia23 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL24", "MultiMedia24 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL25", "MultiMedia25 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL27", "MultiMedia27 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL28", "MultiMedia28 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL29", "MultiMedia29 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MM_UL30", "MultiMedia30 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("VOICEMMODE1_DL", - "VoiceMMode1 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VOICEMMODE1_UL", - "VoiceMMode1 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("VOICEMMODE2_DL", - "VoiceMMode2 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VOICEMMODE2_UL", - "VoiceMMode2 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIM0_DL_HL", "SLIMBUS0_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIM0_UL_HL", "SLIMBUS0_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("CDC_DMA_DL_HL", "CDC_DMA_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("CDC_DMA_UL_HL", "CDC_DMA_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TX3_CDC_DMA_UL_HL", - "TX3_CDC_DMA_HOSTLESS Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("CPE_LSM_UL_HL", "CPE LSM capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIM1_DL_HL", "SLIMBUS1_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIM1_UL_HL", "SLIMBUS1_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIM3_DL_HL", "SLIMBUS3_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIM3_UL_HL", "SLIMBUS3_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIM4_DL_HL", "SLIMBUS4_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIM4_UL_HL", "SLIMBUS4_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIM6_DL_HL", "SLIMBUS6_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIM6_UL_HL", "SLIMBUS6_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIM7_DL_HL", "SLIMBUS7_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIM7_UL_HL", "SLIMBUS7_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIM8_DL_HL", "SLIMBUS8_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIM8_UL_HL", "SLIMBUS8_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INTFM_DL_HL", "INT_FM_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INTHFP_DL_HL", "INT_HFP_BT_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INTHFP_UL_HL", "INT_HFP_BT_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("USBAUDIO_DL_HL", "USBAUDIO_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("USBAUDIO_UL_HL", "USBAUDIO_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("HDMI_DL_HL", "HDMI_HOSTLESS Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_I2S_DL_HL", "SEC_I2S_RX_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INT0_MI2S_DL_HL", - "INT0 MI2S_RX Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INT4_MI2S_DL_HL", - "INT4 MI2S_RX Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_MI2S_DL_HL", - "Primary MI2S_RX Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_MI2S_DL_HL", - "Secondary MI2S_RX Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_MI2S_DL_HL", - "Tertiary MI2S_RX Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_MI2S_DL_HL", - "Quaternary MI2S_RX Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_MI2S_DL_HL", - "Quinary MI2S_RX Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_MI2S_DL_HL", - "Senary MI2S_RX Hostless Playback", - 0, 0, 0, 0), - - SND_SOC_DAPM_AIF_IN("AUXPCM_DL_HL", "AUXPCM_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("AUXPCM_UL_HL", "AUXPCM_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_AUXPCM_DL_HL", "SEC_AUXPCM_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_AUXPCM_UL_HL", "SEC_AUXPCM_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MI2S_UL_HL", "MI2S_TX_HOSTLESS Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT3_MI2S_UL_HL", - "INT3 MI2S_TX Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_MI2S_UL_HL", - "Tertiary MI2S_TX Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_MI2S_UL_HL", - "Secondary MI2S_TX Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_MI2S_UL_HL", - "Primary MI2S_TX Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MI2S_DL_HL", "MI2S_RX_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("DTMF_DL_HL", "DTMF_RX_HOSTLESS Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_UL_HL", - "Quaternary MI2S_TX Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_MI2S_UL_HL", - "Quinary MI2S_TX Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_MI2S_UL_HL", - "Senary MI2S_TX Hostless Capture", - 0, 0, 0, 0), - - SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_0_DL_HL", - "Primary TDM0 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_0_UL_HL", - "Primary TDM0 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_1_DL_HL", - "Primary TDM1 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_1_UL_HL", - "Primary TDM1 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_2_DL_HL", - "Primary TDM2 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_2_UL_HL", - "Primary TDM2 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_3_DL_HL", - "Primary TDM3 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_3_UL_HL", - "Primary TDM3 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_4_DL_HL", - "Primary TDM4 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_4_UL_HL", - "Primary TDM4 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_5_DL_HL", - "Primary TDM5 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_5_UL_HL", - "Primary TDM5 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_6_DL_HL", - "Primary TDM6 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_6_UL_HL", - "Primary TDM6 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_7_DL_HL", - "Primary TDM7 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_7_UL_HL", - "Primary TDM7 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_0_DL_HL", - "Secondary TDM0 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_0_UL_HL", - "Secondary TDM0 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_1_DL_HL", - "Secondary TDM1 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_1_UL_HL", - "Secondary TDM1 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_2_DL_HL", - "Secondary TDM2 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_2_UL_HL", - "Secondary TDM2 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_3_DL_HL", - "Secondary TDM3 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_3_UL_HL", - "Secondary TDM3 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_4_DL_HL", - "Secondary TDM4 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_4_UL_HL", - "Secondary TDM4 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_5_DL_HL", - "Secondary TDM5 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_5_UL_HL", - "Secondary TDM5 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_6_DL_HL", - "Secondary TDM6 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_6_UL_HL", - "Secondary TDM6 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_7_DL_HL", - "Secondary TDM7 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_7_UL_HL", - "Secondary TDM7 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_0_DL_HL", - "Tertiary TDM0 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_0_UL_HL", - "Tertiary TDM0 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_1_DL_HL", - "Tertiary TDM1 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_1_UL_HL", - "Tertiary TDM1 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_2_DL_HL", - "Tertiary TDM2 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_2_UL_HL", - "Tertiary TDM2 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_3_DL_HL", - "Tertiary TDM3 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_3_UL_HL", - "Tertiary TDM3 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_4_DL_HL", - "Tertiary TDM4 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_4_UL_HL", - "Tertiary TDM4 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_5_DL_HL", - "Tertiary TDM5 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_5_UL_HL", - "Tertiary TDM5 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_6_DL_HL", - "Tertiary TDM6 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_6_UL_HL", - "Tertiary TDM6 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_7_DL_HL", - "Tertiary TDM7 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_7_UL_HL", - "Tertiary TDM7 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_0_DL_HL", - "Quaternary TDM0 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_0_UL_HL", - "Quaternary TDM0 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_1_DL_HL", - "Quaternary TDM1 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_1_UL_HL", - "Quaternary TDM1 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_2_DL_HL", - "Quaternary TDM2 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_2_UL_HL", - "Quaternary TDM2 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_3_DL_HL", - "Quaternary TDM3 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_3_UL_HL", - "Quaternary TDM3 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_4_DL_HL", - "Quaternary TDM4 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_4_UL_HL", - "Quaternary TDM4 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_5_DL_HL", - "Quaternary TDM5 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_5_UL_HL", - "Quaternary TDM5 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_6_DL_HL", - "Quaternary TDM6 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_6_UL_HL", - "Quaternary TDM6 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_7_DL_HL", - "Quaternary TDM7 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_7_UL_HL", - "Quaternary TDM7 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_0_DL_HL", - "Quinary TDM0 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_0_UL_HL", - "Quinary TDM0 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_1_DL_HL", - "Quinary TDM1 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_1_UL_HL", - "Quinary TDM1 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_2_DL_HL", - "Quinary TDM2 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_2_UL_HL", - "Quinary TDM2 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_3_DL_HL", - "Quinary TDM3 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_3_UL_HL", - "Quinary TDM3 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_4_DL_HL", - "Quinary TDM4 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_4_UL_HL", - "Quinary TDM4 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_5_DL_HL", - "Quinary TDM5 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_5_UL_HL", - "Quinary TDM5 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_6_DL_HL", - "Quinary TDM6 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_6_UL_HL", - "Quinary TDM6 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_7_DL_HL", - "Quinary TDM7 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_7_UL_HL", - "Quinary TDM7 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_0_DL_HL", - "Senary TDM0 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_0_UL_HL", - "Senary TDM0 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_1_DL_HL", - "Senary TDM1 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_1_UL_HL", - "Senary TDM1 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_2_DL_HL", - "Senary TDM2 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_2_UL_HL", - "Senary TDM2 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_3_DL_HL", - "Senary TDM3 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_3_UL_HL", - "Senary TDM3 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_4_DL_HL", - "Senary TDM4 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_4_UL_HL", - "Senary TDM4 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_5_DL_HL", - "Senary TDM5 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_5_UL_HL", - "Senary TDM5 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_6_DL_HL", - "Senary TDM6 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_6_UL_HL", - "Senary TDM6 Hostless Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_7_DL_HL", - "Senary TDM7 Hostless Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_7_UL_HL", - "Senary TDM7 Hostless Capture", - 0, 0, 0, 0), - - /* LSM */ - SND_SOC_DAPM_AIF_OUT("LSM1_UL_HL", "Listen 1 Audio Service Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("LSM2_UL_HL", "Listen 2 Audio Service Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("LSM3_UL_HL", "Listen 3 Audio Service Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("LSM4_UL_HL", "Listen 4 Audio Service Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("LSM5_UL_HL", "Listen 5 Audio Service Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("LSM6_UL_HL", "Listen 6 Audio Service Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("LSM7_UL_HL", "Listen 7 Audio Service Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("LSM8_UL_HL", "Listen 8 Audio Service Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QCHAT_DL", "QCHAT Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QCHAT_UL", "QCHAT Capture", 0, 0, 0, 0), - /* Backend AIF */ - /* Stream name equals to backend dai link stream name */ - SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_I2S_RX", "Secondary I2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_SPDIF_RX", "Primary SPDIF Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_SPDIF_TX", "Primary SPDIF Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_SPDIF_RX", "Secondary SPDIF Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_SPDIF_TX", "Secondary SPDIF Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_RX", "Slimbus2 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_RX", "Slimbus5 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("HDMI_MS", "HDMI MS Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT", "Display Port Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT1", "Display Port1 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX", "Quaternary MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX", "Tertiary MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX", "Secondary MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_SD1", - "Secondary MI2S Playback SD1", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_MI2S_RX", "Primary MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT0_MI2S_RX", "INT0 MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT2_MI2S_RX", "INT2 MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT3_MI2S_RX", "INT3 MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT5_MI2S_RX", "INT5 MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT4_MI2S_RX", "INT4 MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT4_MI2S_TX", "INT4 MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_MI2S_RX", "Quinary MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_MI2S_RX", "Senary MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("MI2S_TX", "MI2S Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX", "Quaternary MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_MI2S_TX", "Primary MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX", "Tertiary MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT0_MI2S_TX", "INT0 MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INT2_MI2S_TX", "INT2 MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INT3_MI2S_TX", "INT3 MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX", "Secondary MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_2_TX", "Slimbus2 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_MI2S_TX", "Quinary MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SENARY_MI2S_TX", "Senary MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INT_BT_SCO_TX", "Internal BT-SCO Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT_BT_A2DP_RX", "Internal BT-A2DP Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("INT_FM_RX", "Internal FM Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INT_FM_TX", "Internal FM Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PCM_RX", "AFE Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PCM_TX", "AFE Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_0", "Primary TDM0 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_0", "Primary TDM0 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_1", "Primary TDM1 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_1", "Primary TDM1 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_2", "Primary TDM2 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_2", "Primary TDM2 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_3", "Primary TDM3 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_3", "Primary TDM3 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_4", "Primary TDM4 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_4", "Primary TDM4 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_5", "Primary TDM5 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_5", "Primary TDM5 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_6", "Primary TDM6 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_6", "Primary TDM6 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_7", "Primary TDM7 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_7", "Primary TDM7 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_0", "Secondary TDM0 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_0", "Secondary TDM0 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_1", "Secondary TDM1 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_1", "Secondary TDM1 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_2", "Secondary TDM2 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_2", "Secondary TDM2 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_3", "Secondary TDM3 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_3", "Secondary TDM3 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_4", "Secondary TDM4 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_4", "Secondary TDM4 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_5", "Secondary TDM5 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_5", "Secondary TDM5 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_6", "Secondary TDM6 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_6", "Secondary TDM6 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_7", "Secondary TDM7 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_7", "Secondary TDM7 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_0", "Tertiary TDM0 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_0", "Tertiary TDM0 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_1", "Tertiary TDM1 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_1", "Tertiary TDM1 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_2", "Tertiary TDM2 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_2", "Tertiary TDM2 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_3", "Tertiary TDM3 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_3", "Tertiary TDM3 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_4", "Tertiary TDM4 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_4", "Tertiary TDM4 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_5", "Tertiary TDM5 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_5", "Tertiary TDM5 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_6", "Tertiary TDM6 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_6", "Tertiary TDM6 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_7", "Tertiary TDM7 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_7", "Tertiary TDM7 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_0", "Quaternary TDM0 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_0", "Quaternary TDM0 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_1", "Quaternary TDM1 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_1", "Quaternary TDM1 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_2", "Quaternary TDM2 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_2", "Quaternary TDM2 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_3", "Quaternary TDM3 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_3", "Quaternary TDM3 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_4", "Quaternary TDM4 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_4", "Quaternary TDM4 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_5", "Quaternary TDM5 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_5", "Quaternary TDM5 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_6", "Quaternary TDM6 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_6", "Quaternary TDM6 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_7", "Quaternary TDM7 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_7", "Quaternary TDM7 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_0", "Quinary TDM0 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_0", "Quinary TDM0 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_1", "Quinary TDM1 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_1", "Quinary TDM1 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_2", "Quinary TDM2 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_2", "Quinary TDM2 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_3", "Quinary TDM3 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_3", "Quinary TDM3 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_4", "Quinary TDM4 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_4", "Quinary TDM4 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_5", "Quinary TDM5 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_5", "Quinary TDM5 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_6", "Quinary TDM6 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_6", "Quinary TDM6 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_7", "Quinary TDM7 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_7", "Quinary TDM7 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_0", "Senary TDM0 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_0", "Senary TDM0 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_1", "Senary TDM1 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_1", "Senary TDM1 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_2", "Senary TDM2 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_2", "Senary TDM2 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_3", "Senary TDM3 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_3", "Senary TDM3 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_4", "Senary TDM4 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_4", "Senary TDM4 Capture", +static const struct snd_kcontrol_new sen_tdm_tx_0_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sen_tdm_rx_1_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sen_tdm_rx_2_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new sen_tdm_rx_3_mixer_controls[] = { + SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia20", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MultiMedia21", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_2_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_rx_2_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_0_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_1_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_2_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_3_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VoLTE Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_0_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_1_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_2_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new pri_tdm_rx_3_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_0_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_1_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_2_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_3_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_tdm_rx_7_port_mixer_controls[] = { + SOC_DOUBLE_EXT("TERT_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_RX_7, + MSM_BACKEND_DAI_TERT_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_0_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_1_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_2_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_tdm_rx_3_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_0_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_1_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_2_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_3_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_tdm_rx_7_port_mixer_controls[] = { + SOC_DOUBLE_EXT("QUAT_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_7, + MSM_BACKEND_DAI_QUAT_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_RX_7, + MSM_BACKEND_DAI_QUIN_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_rx_0_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_rx_1_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_rx_2_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_rx_3_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sen_tdm_rx_0_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_0, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sen_tdm_rx_1_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_1, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sen_tdm_rx_2_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_2, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sen_tdm_rx_3_port_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_TERT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_0, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_1, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_2, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_RX_3, + MSM_BACKEND_DAI_SEN_TDM_TX_3, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quin_tdm_rx_7_port_mixer_controls[] = { + SOC_DOUBLE_EXT("TERT_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_7, + MSM_BACKEND_DAI_TERT_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_7, + MSM_BACKEND_DAI_QUAT_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_7", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_RX_7, + MSM_BACKEND_DAI_QUIN_TDM_TX_7, 1, 0, + msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; +#endif + +static const struct snd_kcontrol_new mmul1_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul2_mixer_controls[] = { + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_AUXPCM_DISABLE + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +}; + +static const struct snd_kcontrol_new mmul3_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_AUXPCM_DISABLE + SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul4_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul5_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul6_mixer_controls[] = { + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul8_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul16_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul9_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul10_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT2_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT2_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; +static const struct snd_kcontrol_new mmul17_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul18_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul19_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul20_mixer_controls[] = { +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul21_mixer_controls[] = { + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul22_mixer_controls[] = { +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +}; + +static const struct snd_kcontrol_new mmul23_mixer_controls[] = { +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +}; + +static const struct snd_kcontrol_new mmul24_mixer_controls[] = { +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +}; + +static const struct snd_kcontrol_new mmul25_mixer_controls[] = { +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("PRI_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_TDM_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif +}; + +static const struct snd_kcontrol_new mmul27_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_9_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul28_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul29_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul30_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +#endif + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_DL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VOC_REC_UL", SND_SOC_NOPM, + MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("WSA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, + msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_SPDIF_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_DOUBLE_EXT("AFE_LOOPBACK_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_LOOPBACK_TX, + MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; +#ifndef CONFIG_MI2S_DISABLE +static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new sec_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; +#endif +static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new slimbus_6_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new usb_audio_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new display_port_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new display_port_rx1_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +#ifndef CONFIG_MI2S_DISABLE +static const struct snd_kcontrol_new mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new pri_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new int0_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_INT0_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new int4_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT4_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tert_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new quat_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new quin_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("Voice Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("Voice2 Stub", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new sen_mi2s_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SENARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +#endif +static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +#ifndef CONFIG_AUXPCM_DISABLE +static const struct snd_kcontrol_new aux_pcm_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new sec_aux_pcm_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tert_aux_pcm_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new quat_aux_pcm_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new quin_aux_pcm_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new sen_aux_pcm_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; +#endif + +static const struct snd_kcontrol_new hdmi_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new slimbus_7_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, +MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new slimbus_8_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new wsa_cdc_dma_rx_1_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_0_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_1_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_2_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_2, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_3_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_3, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_4_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_4, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_5_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_5, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_6_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_6, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_7_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_7, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + + +static const struct snd_kcontrol_new stub_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new slimbus_1_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = { + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new proxy_rx_voice_mixer_controls[] = { + SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PROXY_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VoiceMMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PROXY_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_0_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("INT_BT_SCO_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), +#ifndef CONFIG_AUXPCM_DISABLE + SOC_DOUBLE_EXT("AUX_PCM_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_7_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PROXY_TX_MMode1", SND_SOC_NOPM, + MSM_BACKEND_DAI_PROXY_TX, MSM_FRONTEND_DAI_VOICEMMODE1, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("INT_BT_SCO_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("AUX_PCM_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PRI_TDM_TX_3_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_TDM_TX_3, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PROXY_TX_MMode2", SND_SOC_NOPM, + MSM_BACKEND_DAI_PROXY_TX, MSM_FRONTEND_DAI_VOICEMMODE2, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("MI2S_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +#ifndef CONFIG_AUXPCM_DISABLE + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +#endif + SOC_DOUBLE_EXT("PRI_MI2S_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_Voip", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOIP, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("PRI_TDM_TX_3_Voip", MSM_BACKEND_DAI_PRI_TDM_TX_3, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { + SOC_DOUBLE_EXT("STUB_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("STUB_1_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_EC_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#ifndef CONFIG_AUXPCM_DISABLE + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +}; + +static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = { + SOC_DOUBLE_EXT("STUB_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("STUB_1_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_EC_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#ifndef CONFIG_AUXPCM_DISABLE + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +//aditya to confirm +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOICE2_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +}; + +static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = { + SOC_DOUBLE_EXT("STUB_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("STUB_1_TX_HL", SND_SOC_NOPM, + MSM_BACKEND_DAI_EXTPROC_EC_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#ifndef CONFIG_AUXPCM_DISABLE + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_VOLTE_STUB, + 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), +}; + +static const struct snd_kcontrol_new tx_qchat_mixer_controls[] = { + SOC_DOUBLE_EXT("PRI_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_I2S_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, + msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +#ifndef CONFIG_AUXPCM_DISABLE + SOC_DOUBLE_EXT("AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TERT_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUAT_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("QUIN_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SEN_AUX_PCM_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +#endif +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("MI2S_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_MI2S_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +#endif + SOC_DOUBLE_EXT("SLIM_7_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("USB_AUDIO_TX_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_0_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_0, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_1_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_1, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_2_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_2, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_4_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_4, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_5_QCHAT", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_5, MSM_FRONTEND_DAI_QCHAT, + 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), +}; + +static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_port_mixer_controls[] = { + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_0_port_mixer_controls[] = { + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_0, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + +}; + +static const struct snd_kcontrol_new rx_cdc_dma_rx_1_port_mixer_controls[] = { + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_RX_CDC_DMA_RX_1, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SENARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_PRI_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUIN_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEN_MI2S_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SENARY_MI2S_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +#ifndef CONFIG_AUXPCM_DISABLE +static const struct snd_kcontrol_new aux_pcm_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_AUXPCM_RX, + MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sec_auxpcm_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new tert_auxpcm_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quat_auxpcm_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new quin_auxpcm_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("QUIN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_QUIN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sen_auxpcm_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("SEN_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SEN_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SEN_AUXPCM_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; +#endif + +static const struct snd_kcontrol_new sbus_1_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_AUXPCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_RX, + MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sbus_3_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_BACKEND_DAI_INT_BT_SCO_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AFE_PCM_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_BACKEND_DAI_AFE_PCM_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_BACKEND_DAI_AUXPCM_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_RX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_RX, + MSM_BACKEND_DAI_SLIMBUS_0_RX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new sbus_6_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_7_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_8_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SEC_AUX_PCM_UL_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("INTERNAL_BT_SCO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_9_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_9_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new bt_sco_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new afe_pcm_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_BACKEND_DAI_SLIMBUS_1_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + + +static const struct snd_kcontrol_new hdmi_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new hdmi_rx_ms_port_mixer_controls[] = { + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_HDMI_RX_MS, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new display_port_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new display_port_rx1_port_mixer_controls[] = { + SOC_DOUBLE_EXT("MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_DISPLAY_PORT_RX_1, + MSM_BACKEND_DAI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + + +static const struct snd_kcontrol_new usb_rx_port_mixer_controls[] = { + SOC_DOUBLE_EXT("USB_AUDIO_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_USB_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), +}; + +static const struct snd_kcontrol_new lsm1_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif +}; + +static const struct snd_kcontrol_new lsm2_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_1_TX", + SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif +}; + +static const struct snd_kcontrol_new lsm3_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif +}; + +static const struct snd_kcontrol_new lsm4_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif +}; + +static const struct snd_kcontrol_new lsm5_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif +}; + +static const struct snd_kcontrol_new lsm6_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif +}; + +static const struct snd_kcontrol_new lsm7_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif +}; + +static const struct snd_kcontrol_new lsm8_mixer_controls[] = { + SOC_DOUBLE_EXT("SLIMBUS_0_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_1_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_1_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_3_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_4_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("SLIMBUS_5_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_MI2S_DISABLE + SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("QUAT_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("INT3_MI2S_TX", SND_SOC_NOPM, + MSM_BACKEND_DAI_INT3_MI2S_TX, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_0, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_1, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("VA_CDC_DMA_TX_2", SND_SOC_NOPM, + MSM_BACKEND_DAI_VA_CDC_DMA_TX_2, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#ifndef CONFIG_TDM_DISABLE + SOC_DOUBLE_EXT("QUIN_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUIN_TDM_TX_0, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), + SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM, + MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer, + msm_routing_put_listen_mixer), +#endif +}; + +static const struct snd_kcontrol_new slim_fm_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new slim1_fm_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new slim3_fm_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new slim4_fm_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new cdc_dma_wsa_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new cdc_dma_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new cdc_dma_rx_1_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new slim6_fm_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_switch_mixer, + msm_routing_put_switch_mixer); + +static const struct snd_kcontrol_new pcm_rx_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_fm_pcmrx_switch_mixer, + msm_routing_put_fm_pcmrx_switch_mixer); + +static const struct snd_kcontrol_new hfp_pri_aux_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_hfp_switch_mixer, + msm_routing_put_hfp_switch_mixer); + +static const struct snd_kcontrol_new hfp_aux_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_hfp_switch_mixer, + msm_routing_put_hfp_switch_mixer); + +static const struct snd_kcontrol_new hfp_int_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_hfp_switch_mixer, + msm_routing_put_hfp_switch_mixer); + +static const struct snd_kcontrol_new hfp_slim7_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_hfp_switch_mixer, + msm_routing_put_hfp_switch_mixer); + +static const struct snd_kcontrol_new usb_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_get_usb_switch_mixer, + msm_routing_put_usb_switch_mixer); + +static const struct snd_kcontrol_new a2dp_slim7_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_a2dp_switch_mixer_get, + msm_routing_a2dp_switch_mixer_put); + +static const struct snd_kcontrol_new sco_slim7_switch_mixer_controls = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, + 0, 1, 0, msm_routing_sco_switch_mixer_get, + msm_routing_sco_switch_mixer_put); + +static const struct soc_enum lsm_port_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_port_text), lsm_port_text); + +static const char * const lsm_func_text[] = { + "None", "AUDIO", "BEACON", "ULTRASOUND", "SWAUDIO", +}; +static const struct soc_enum lsm_func_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_func_text), lsm_func_text); + +static const struct snd_kcontrol_new lsm_controls[] = { + /* kcontrol of lsm_function */ + SOC_ENUM_EXT(SLIMBUS_0_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(SLIMBUS_1_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(SLIMBUS_2_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(SLIMBUS_3_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(SLIMBUS_4_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(SLIMBUS_5_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(TERT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(QUAT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(INT3_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(TX_CDC_DMA_TX_3_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(QUIN_TDM_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + SOC_ENUM_EXT(TERT_TDM_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum, + msm_routing_lsm_func_get, msm_routing_lsm_func_put), + /* kcontrol of lsm_port */ + SOC_ENUM_EXT("LSM1 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM2 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM3 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM4 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM5 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM6 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM7 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), + SOC_ENUM_EXT("LSM8 Port", lsm_port_enum, + msm_routing_lsm_port_get, + msm_routing_lsm_port_put), +}; + +static const char * const aanc_slim_0_rx_text[] = { + "ZERO", "SLIMBUS_0_TX", "SLIMBUS_1_TX", "SLIMBUS_2_TX", "SLIMBUS_3_TX", + "SLIMBUS_4_TX", "SLIMBUS_5_TX", "SLIMBUS_6_TX" +}; + +static const struct soc_enum aanc_slim_0_rx_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(aanc_slim_0_rx_text), + aanc_slim_0_rx_text); + +static const struct snd_kcontrol_new aanc_slim_0_rx_mux[] = { + SOC_ENUM_EXT("AANC_SLIM_0_RX MUX", aanc_slim_0_rx_enum, + msm_routing_slim_0_rx_aanc_mux_get, + msm_routing_slim_0_rx_aanc_mux_put) +}; + +static int msm_routing_aanc_noise_level_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = aanc_level; + + return 0; +} + +static int msm_routing_aanc_noise_level_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + + mutex_lock(&routing_lock); + aanc_level = ucontrol->value.integer.value[0]; + pr_debug("%s: value: %ld\n", + __func__, ucontrol->value.integer.value[0]); + ret = afe_set_aanc_noise_level(aanc_level); + mutex_unlock(&routing_lock); + + return ret; +} + +static const struct snd_kcontrol_new aanc_noise_level[] = { + SOC_SINGLE_EXT("AANC Noise Level", SND_SOC_NOPM, 0, 255, + 0, msm_routing_aanc_noise_level_get, msm_routing_aanc_noise_level_put) +}; + +static int msm_routing_get_stereo_to_custom_stereo_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = is_custom_stereo_on; + return 0; +} + +static int msm_routing_put_stereo_to_custom_stereo_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int flag = 0, i = 0, rc = 0, idx = 0; + int be_index = 0, port_id, topo_id; + unsigned int session_id = 0; + uint16_t op_FL_ip_FL_weight = 0; + uint16_t op_FL_ip_FR_weight = 0; + uint16_t op_FR_ip_FL_weight = 0; + uint16_t op_FR_ip_FR_weight = 0; + + flag = ucontrol->value.integer.value[0]; + pr_debug("%s E flag %d\n", __func__, flag); + + if ((is_custom_stereo_on && flag) || (!is_custom_stereo_on && !flag)) { + pr_err("%s: is_custom_stereo_on %d, flag %d\n", + __func__, is_custom_stereo_on, flag); + return 0; + } + is_custom_stereo_on = flag ? true : false; + pr_debug("%s:is_custom_stereo_on %d\n", __func__, is_custom_stereo_on); + for (be_index = 0; be_index < MSM_BACKEND_DAI_MAX; be_index++) { + port_id = msm_bedais[be_index].port_id; + if (!msm_bedais[be_index].active) + continue; + if ((port_id != SLIMBUS_0_RX) && + (port_id != RT_PROXY_PORT_001_RX) && + (port_id != AFE_PORT_ID_PRIMARY_MI2S_RX) && + (port_id != AFE_PORT_ID_INT4_MI2S_RX)) + continue; + + for_each_set_bit(i, &msm_bedais[be_index].fe_sessions[0], + MSM_FRONTEND_DAI_MM_SIZE) { + if (fe_dai_map[i][SESSION_TYPE_RX].perf_mode != + LEGACY_PCM_MODE) + goto skip_send_custom_stereo; + session_id = + fe_dai_map[i][SESSION_TYPE_RX].strm_id; + if (is_custom_stereo_on) { + op_FL_ip_FL_weight = + Q14_GAIN_ZERO_POINT_FIVE; + op_FL_ip_FR_weight = + Q14_GAIN_ZERO_POINT_FIVE; + op_FR_ip_FL_weight = + Q14_GAIN_ZERO_POINT_FIVE; + op_FR_ip_FR_weight = + Q14_GAIN_ZERO_POINT_FIVE; + } else { + op_FL_ip_FL_weight = Q14_GAIN_UNITY; + op_FL_ip_FR_weight = 0; + op_FR_ip_FL_weight = 0; + op_FR_ip_FR_weight = Q14_GAIN_UNITY; + } + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { + unsigned long copp = + session_copp_map[i] + [SESSION_TYPE_RX][be_index]; + if (!test_bit(idx, &copp)) + goto skip_send_custom_stereo; + topo_id = adm_get_topology_for_port_copp_idx( + msm_bedais[be_index].port_id, idx); + if (topo_id < 0) + pr_debug("%s:Err:custom stereo topo %d", + __func__, topo_id); + pr_debug("idx %d\n", idx); + if (topo_id == DS2_ADM_COPP_TOPOLOGY_ID) + rc = msm_ds2_dap_set_custom_stereo_onoff + (msm_bedais[be_index].port_id, + idx, is_custom_stereo_on); + else if (topo_id == DOLBY_ADM_COPP_TOPOLOGY_ID) + rc = dolby_dap_set_custom_stereo_onoff( + msm_bedais[be_index].port_id, + idx, is_custom_stereo_on); + else + rc = msm_qti_pp_send_stereo_to_custom_stereo_cmd + (msm_bedais[be_index].port_id, + idx, session_id, + op_FL_ip_FL_weight, + op_FL_ip_FR_weight, + op_FR_ip_FL_weight, + op_FR_ip_FR_weight); + if (rc < 0) +skip_send_custom_stereo: + pr_err("%s: err setting custom stereo\n", + __func__); + } + + } + } + return 0; +} + +static const struct snd_kcontrol_new stereo_to_custom_stereo_controls[] = { + SOC_SINGLE_EXT("Set Custom Stereo OnOff", SND_SOC_NOPM, 0, + 1, 0, msm_routing_get_stereo_to_custom_stereo_control, + msm_routing_put_stereo_to_custom_stereo_control), +}; + +static int msm_routing_get_app_type_cfg_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static int msm_routing_put_app_type_cfg_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int i = 0, j; + int num_app_types = ucontrol->value.integer.value[i++]; + + pr_debug("%s\n", __func__); + + memset(app_type_cfg, 0, MAX_APP_TYPES* + sizeof(struct msm_pcm_routing_app_type_data)); + if (num_app_types > MAX_APP_TYPES) { + pr_err("%s: number of app types exceed the max supported\n", + __func__); + return -EINVAL; + } + for (j = 0; j < num_app_types; j++) { + app_type_cfg[j].app_type = + ucontrol->value.integer.value[i++]; + app_type_cfg[j].sample_rate = + ucontrol->value.integer.value[i++]; + app_type_cfg[j].bit_width = + ucontrol->value.integer.value[i++]; + } + + return 0; +} + +static int msm_routing_put_app_type_gain_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int j, fe_id, be_id, port_type; + int ret = 0; + unsigned long copp; + struct msm_pcm_routing_bdai_data *bedai; + int dir = ucontrol->value.integer.value[0] ? SESSION_TYPE_TX : + SESSION_TYPE_RX; + int app_type = ucontrol->value.integer.value[1]; + int gain = (ucontrol->value.integer.value[2] + + ucontrol->value.integer.value[3])/2; + + port_type = (dir == SESSION_TYPE_RX) ? MSM_AFE_PORT_TYPE_RX : + MSM_AFE_PORT_TYPE_TX; + + mutex_lock(&routing_lock); + for (be_id = 0; be_id < MSM_BACKEND_DAI_MAX; be_id++) { + if (is_be_dai_extproc(be_id)) + continue; + + bedai = &msm_bedais[be_id]; + if (afe_get_port_type(bedai->port_id) != port_type) + continue; + + if (!bedai->active) + continue; + + for (fe_id = 0; fe_id < MSM_FRONTEND_DAI_MAX; fe_id++) { + if (!test_bit(fe_id, &bedai->fe_sessions[0])) + continue; + + if (app_type != + fe_dai_app_type_cfg[fe_id][dir][be_id].app_type) + continue; + + copp = session_copp_map[fe_id][dir][be_id]; + for (j = 0; j < MAX_COPPS_PER_PORT; j++) { + if (!test_bit(j, &copp)) + continue; + ret |= adm_set_volume(bedai->port_id, j, gain); + } + } + } + mutex_unlock(&routing_lock); + return ret ? -EINVAL : 0; +} + +static const struct snd_kcontrol_new app_type_cfg_controls[] = { + SOC_SINGLE_MULTI_EXT("App Type Config", SND_SOC_NOPM, 0, + 0x7FFFFFFF, 0, 128, msm_routing_get_app_type_cfg_control, + msm_routing_put_app_type_cfg_control), + SOC_SINGLE_MULTI_EXT("App Type Gain", SND_SOC_NOPM, 0, + 0x2000, 0, 4, NULL, msm_routing_put_app_type_gain_control) +}; + +static int msm_routing_put_module_cfg_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int copp_idx, fe_id, be_id, port_type; + int ret = 0; + unsigned long copp; + struct msm_pcm_routing_bdai_data *bedai; + u8 *packed_params = NULL; + struct param_hdr_v3 param_hdr; + u32 packed_param_size = (sizeof(struct param_hdr_v3) + + sizeof(uint32_t)); + + int dir = ucontrol->value.integer.value[0] ? SESSION_TYPE_TX : + SESSION_TYPE_RX; + int app_type = ucontrol->value.integer.value[1]; + int module_id = ucontrol->value.integer.value[2]; + int instance_id = ucontrol->value.integer.value[3]; + int param_id = ucontrol->value.integer.value[4]; + int param_value = ucontrol->value.integer.value[5]; + + port_type = (dir == SESSION_TYPE_RX) ? MSM_AFE_PORT_TYPE_RX : + MSM_AFE_PORT_TYPE_TX; + pr_debug("%s app_type:%d mod_id:%d instance_id:%d param_id:%d value:%d\n", + __func__, app_type, module_id, + instance_id, param_id, param_value); + + packed_params = kzalloc(packed_param_size, GFP_KERNEL); + if (!packed_params) + return -ENOMEM; + + memset(¶m_hdr, 0, sizeof(param_hdr)); + param_hdr.module_id = module_id; + param_hdr.instance_id = instance_id; + param_hdr.param_id = param_id; + param_hdr.param_size = sizeof(uint32_t); + + packed_param_size = 0; + + mutex_lock(&routing_lock); + for (be_id = 0; be_id < MSM_BACKEND_DAI_MAX; be_id++) { + if (is_be_dai_extproc(be_id)) + continue; + + bedai = &msm_bedais[be_id]; + if (afe_get_port_type(bedai->port_id) != port_type) + continue; + + if (!bedai->active) + continue; + + for (fe_id = 0; fe_id < MSM_FRONTEND_DAI_MAX; fe_id++) { + if (!test_bit(fe_id, &bedai->fe_sessions[0])) + continue; + + if (app_type != + fe_dai_app_type_cfg[fe_id][dir][be_id].app_type) + continue; + + copp = session_copp_map[fe_id][dir][be_id]; + for (copp_idx = 0; copp_idx < MAX_COPPS_PER_PORT; + copp_idx++) { + if (!test_bit(copp_idx, &copp)) + continue; + + ret = q6common_pack_pp_params(packed_params, + ¶m_hdr, + (u8 *) ¶m_value, + &packed_param_size); + if (ret) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, ret); + goto done; + } + + ret = adm_set_pp_params(bedai->port_id, + copp_idx, NULL, + packed_params, + packed_param_size); + if (ret) { + pr_err("%s: Setting param failed with err=%d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + } + } + } +done: + mutex_unlock(&routing_lock); + kfree(packed_params); + return ret; +} + +static const struct snd_kcontrol_new module_cfg_controls[] = { + SOC_SINGLE_MULTI_EXT("Audio Effect", SND_SOC_NOPM, 0, + 0x2000, 0, 6, NULL, msm_routing_put_module_cfg_control) +}; + +static int msm_routing_get_lsm_app_type_cfg_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int shift = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int i = 0, j = 0; + + mutex_lock(&routing_lock); + ucontrol->value.integer.value[i] = num_app_cfg_types; + + for (j = 0; j < num_app_cfg_types; ++j) { + ucontrol->value.integer.value[++i] = + lsm_app_type_cfg[j].app_type; + ucontrol->value.integer.value[++i] = + lsm_app_type_cfg[j].sample_rate; + ucontrol->value.integer.value[++i] = + lsm_app_type_cfg[j].bit_width; + if (shift == 1) + ucontrol->value.integer.value[++i] = + lsm_app_type_cfg[j].num_out_channels; + } + mutex_unlock(&routing_lock); + return 0; +} + +static int msm_routing_put_lsm_app_type_cfg_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int shift = ((struct soc_multi_mixer_control *) + kcontrol->private_value)->shift; + int i = 0, j; + + mutex_lock(&routing_lock); + if (ucontrol->value.integer.value[0] > MAX_APP_TYPES) { + pr_err("%s: number of app types exceed the max supported\n", + __func__); + mutex_unlock(&routing_lock); + return -EINVAL; + } + + num_app_cfg_types = ucontrol->value.integer.value[i++]; + memset(lsm_app_type_cfg, 0, MAX_APP_TYPES* + sizeof(struct msm_pcm_routing_app_type_data)); + + for (j = 0; j < num_app_cfg_types; j++) { + lsm_app_type_cfg[j].app_type = + ucontrol->value.integer.value[i++]; + lsm_app_type_cfg[j].sample_rate = + ucontrol->value.integer.value[i++]; + lsm_app_type_cfg[j].bit_width = + ucontrol->value.integer.value[i++]; + /* Shift of 1 indicates this is V2 mixer control */ + if (shift == 1) + lsm_app_type_cfg[j].num_out_channels = + ucontrol->value.integer.value[i++]; + } + mutex_unlock(&routing_lock); + return 0; +} + +static const struct snd_kcontrol_new lsm_app_type_cfg_controls[] = { + SOC_SINGLE_MULTI_EXT("Listen App Type Config", SND_SOC_NOPM, 0, + 0xFFFFFFFF, 0, 128, msm_routing_get_lsm_app_type_cfg_control, + msm_routing_put_lsm_app_type_cfg_control), + SOC_SINGLE_MULTI_EXT("Listen App Type Config V2", SND_SOC_NOPM, 1, + 0xFFFFFFFF, 0, 128, msm_routing_get_lsm_app_type_cfg_control, + msm_routing_put_lsm_app_type_cfg_control), +}; + +static int msm_routing_get_use_ds1_or_ds2_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = is_ds2_on; + return 0; +} + +static int msm_routing_put_use_ds1_or_ds2_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + is_ds2_on = ucontrol->value.integer.value[0]; + return 0; +} + +static const struct snd_kcontrol_new use_ds1_or_ds2_controls[] = { + SOC_SINGLE_EXT("DS2 OnOff", SND_SOC_NOPM, 0, + 1, 0, msm_routing_get_use_ds1_or_ds2_control, + msm_routing_put_use_ds1_or_ds2_control), +}; + +static int msm_routing_get_hifi_filter_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = hifi_filter_enabled; + return 0; +} + +static int msm_routing_put_hifi_filter_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + hifi_filter_enabled = ucontrol->value.integer.value[0]; + return 0; +} + +static const struct snd_kcontrol_new hifi_filter_controls[] = { + SOC_SINGLE_EXT("HiFi Filter", SND_SOC_NOPM, 0, + 1, 0, msm_routing_get_hifi_filter_control, + msm_routing_put_hifi_filter_control), +}; + +static int msm_routing_get_ffecns_freeze_event_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = ffecns_freeze_event; + return 0; +} + +static int msm_routing_put_ffecns_freeze_event_control( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = -EINVAL; + + ffecns_freeze_event = ucontrol->value.integer.value[0]; + + ret = adm_set_ffecns_freeze_event(ffecns_freeze_event); + if (ret) + pr_err("%s: failed to set ffecns imc event to%d\n", + __func__, ffecns_freeze_event); + + return ret; +} + +static const struct snd_kcontrol_new use_ffecns_freeze_event_controls[] = { + SOC_SINGLE_EXT("FFECNS Freeze Event", SND_SOC_NOPM, 0, + 1, 0, msm_routing_get_ffecns_freeze_event_control, + msm_routing_put_ffecns_freeze_event_control), +}; + +int msm_routing_get_rms_value_control(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { + int rc = 0; + int be_idx = 0; + char *param_value; + int *update_param_value; + uint32_t param_size = (RMS_PAYLOAD_LEN + 1) * sizeof(uint32_t); + struct param_hdr_v3 param_hdr; + + param_value = kzalloc(param_size, GFP_KERNEL); + if (!param_value) + return -ENOMEM; + + memset(¶m_hdr, 0, sizeof(param_hdr)); + for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) + if (msm_bedais[be_idx].port_id == SLIMBUS_0_TX) + break; + if ((be_idx < MSM_BACKEND_DAI_MAX) && msm_bedais[be_idx].active) { + param_hdr.module_id = RMS_MODULEID_APPI_PASSTHRU; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = RMS_PARAM_FIRST_SAMPLE; + param_hdr.param_size = param_size; + rc = adm_get_pp_params(SLIMBUS_0_TX, 0, ADM_CLIENT_ID_DEFAULT, + NULL, ¶m_hdr, (u8 *) param_value); + if (rc) { + pr_err("%s: get parameters failed:%d\n", __func__, rc); + kfree(param_value); + return -EINVAL; + } + update_param_value = (int *)param_value; + ucontrol->value.integer.value[0] = update_param_value[0]; + + pr_debug("%s: FROM DSP value[0] 0x%x\n", + __func__, update_param_value[0]); + } + kfree(param_value); + return 0; +} + +static int msm_voc_session_id_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + voc_session_id = ucontrol->value.integer.value[0]; + + pr_debug("%s: voc_session_id=%u\n", __func__, voc_session_id); + + return 0; +} + +static int msm_voc_session_id_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = voc_session_id; + + return 0; +} + +static struct snd_kcontrol_new msm_voc_session_controls[] = { + SOC_SINGLE_MULTI_EXT("Voc VSID", SND_SOC_NOPM, 0, + 0xFFFFFFFF, 0, 1, msm_voc_session_id_get, + msm_voc_session_id_put), +}; + +static int msm_sound_focus_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(struct sound_focus_param); + + return 0; +} + +static int msm_voice_sound_focus_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct sound_focus_param soundFocusData; + + memcpy((void *)&soundFocusData, ucontrol->value.bytes.data, + sizeof(struct sound_focus_param)); + ret = voc_set_sound_focus(soundFocusData); + if (ret) { + pr_err("%s: Error setting Sound Focus Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + } + + return ret; +} + +static int msm_voice_sound_focus_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct sound_focus_param soundFocusData; + + memset(&soundFocusData, 0, sizeof(struct sound_focus_param)); + + ret = voc_get_sound_focus(&soundFocusData); + if (ret) { + pr_debug("%s: Error getting Sound Focus Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + memcpy(ucontrol->value.bytes.data, (void *)&soundFocusData, + sizeof(struct sound_focus_param)); + +done: + return ret; +} + +static int msm_source_tracking_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(struct source_tracking_param); + + return 0; +} + +static int msm_voice_source_tracking_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct source_tracking_param sourceTrackingData; + + memset(&sourceTrackingData, 0, sizeof(struct source_tracking_param)); + + ret = voc_get_source_tracking(&sourceTrackingData); + if (ret) { + pr_debug("%s: Error getting Source Tracking Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + memcpy(ucontrol->value.bytes.data, (void *)&sourceTrackingData, + sizeof(struct source_tracking_param)); + +done: + return ret; +} + +static int msm_audio_get_copp_idx_from_port_id(int port_id, int session_type, + int *copp_idx) +{ + int i, idx, be_idx; + int ret = 0; + unsigned long copp; + + pr_debug("%s: Enter, port_id=%d\n", __func__, port_id); + + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: port validation failed id 0x%x ret %d\n", + __func__, port_id, ret); + + ret = -EINVAL; + goto done; + } + + for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) { + if (msm_bedais[be_idx].port_id == port_id) + break; + } + if (be_idx >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: Invalid be id %d\n", __func__, be_idx); + + ret = -EINVAL; + goto done; + } + + for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0], + MSM_FRONTEND_DAI_MAX) { + if (!(is_mm_lsm_fe_id(i) && + route_check_fe_id_adm_support(i))) + continue; + + for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) { + copp = session_copp_map[i] + [session_type][be_idx]; + if (test_bit(idx, &copp)) + break; + } + if (idx >= MAX_COPPS_PER_PORT) + continue; + else + break; + } + if (i >= MSM_FRONTEND_DAI_MAX) { + pr_debug("%s: Invalid FE, exiting\n", __func__); + + ret = -EINVAL; + goto done; + } + *copp_idx = idx; + pr_debug("%s: copp_idx=%d\n", __func__, *copp_idx); + +done: + return ret; +} + +static int msm_audio_sound_focus_derive_port_id(struct snd_kcontrol *kcontrol, + const char *prefix, int *port_id) +{ + int ret = 0; + + pr_debug("%s: Enter, prefix:%s\n", __func__, prefix); + + /* + * Mixer control name will be like "Sound Focus Audio Tx SLIMBUS_0" + * where the prefix is "Sound Focus Audio Tx ". Skip the prefix + * and compare the string with the backend name to derive the port id. + */ + if (!strcmp(kcontrol->id.name + strlen(prefix), + "SLIMBUS_0")) { + *port_id = SLIMBUS_0_TX; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "TERT_MI2S")) { + *port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "INT3_MI2S")) { + *port_id = AFE_PORT_ID_INT3_MI2S_TX; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "VA_CDC_DMA_TX_0")) { + *port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "TX_CDC_DMA_TX_3")) { + *port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "QUIN_TDM_TX_0")) { + *port_id = AFE_PORT_ID_QUINARY_TDM_TX; + } else if (!strcmp(kcontrol->id.name + strlen(prefix), + "PRIMARY_TDM")) { + *port_id = AFE_PORT_ID_PRIMARY_TDM_TX; + } else { + pr_err("%s: mixer ctl name=%s, could not derive valid port id\n", + __func__, kcontrol->id.name); + + ret = -EINVAL; + goto done; + } + pr_debug("%s: mixer ctl name=%s, derived port_id=%d\n", + __func__, kcontrol->id.name, *port_id); + +done: + return ret; +} + +static int msm_audio_sound_focus_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct sound_focus_param soundFocusData; + int port_id, copp_idx; + + ret = msm_audio_sound_focus_derive_port_id(kcontrol, + "Sound Focus Audio Tx ", &port_id); + if (ret != 0) { + pr_err("%s: Error in deriving port id, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, + &copp_idx); + if (ret) { + pr_err("%s: Could not get copp idx for port_id=%d\n", + __func__, port_id); + + ret = -EINVAL; + goto done; + } + + memcpy((void *)&soundFocusData, ucontrol->value.bytes.data, + sizeof(struct sound_focus_param)); + + ret = adm_set_sound_focus(port_id, copp_idx, soundFocusData); + if (ret) { + pr_err("%s: Error setting Sound Focus Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + +done: + return ret; +} + +static int msm_audio_sound_focus_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct sound_focus_param soundFocusData; + int port_id, copp_idx; + + ret = msm_audio_sound_focus_derive_port_id(kcontrol, + "Sound Focus Audio Tx ", &port_id); + if (ret) { + pr_err("%s: Error in deriving port id, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, + &copp_idx); + if (ret) { + pr_debug("%s: Could not get copp idx for port_id=%d\n", + __func__, port_id); + + ret = -EINVAL; + goto done; + } + + ret = adm_get_sound_focus(port_id, copp_idx, &soundFocusData); + if (ret) { + pr_err("%s: Error getting Sound Focus Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + memcpy(ucontrol->value.bytes.data, (void *)&soundFocusData, + sizeof(struct sound_focus_param)); + +done: + return ret; +} + +static int msm_audio_source_tracking_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct source_tracking_param sourceTrackingData; + int port_id, copp_idx; + + ret = msm_audio_sound_focus_derive_port_id(kcontrol, + "Source Tracking Audio Tx ", &port_id); + if (ret) { + pr_err("%s: Error in deriving port id, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, + &copp_idx); + if (ret) { + pr_debug("%s: Could not get copp idx for port_id=%d\n", + __func__, port_id); + + ret = -EINVAL; + goto done; + } + + ret = adm_get_source_tracking(port_id, copp_idx, &sourceTrackingData); + if (ret) { + pr_err("%s: Error getting Source Tracking Params, err=%d\n", + __func__, ret); + + ret = -EINVAL; + goto done; + } + + memcpy(ucontrol->value.bytes.data, (void *)&sourceTrackingData, + sizeof(struct source_tracking_param)); + +done: + return ret; +} + +static int msm_doa_tracking_mon_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(struct doa_tracking_mon_param); + + return 0; +} + +static int msm_doa_tracking_mon_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct doa_tracking_mon_param doa_tracking_data; + int port_id, copp_idx; + + memset(&doa_tracking_data, 0, sizeof(struct doa_tracking_mon_param)); + ret = msm_audio_sound_focus_derive_port_id(kcontrol, + "Doa Tracking Monitor Listen ", &port_id); + if (ret) { + pr_err("%s: Error in deriving port id, err=%d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + /* + * If copp id exists for given port id, query adm to get doa data. + * Else query afe for doa tracking params. + * This is to support in cases where LSM directly connects to + * AFE for FFNS. + */ + ret = msm_audio_get_copp_idx_from_port_id(port_id, SESSION_TYPE_TX, + &copp_idx); + if (!ret) + ret = adm_get_doa_tracking_mon(port_id, copp_idx, + &doa_tracking_data); + else + ret = afe_get_doa_tracking_mon(port_id, &doa_tracking_data); + + if (ret) { + pr_err("%s: Error getting Doa Tracking Params, err=%d\n", + __func__, ret); + ret = -EINVAL; + goto done; + } + + memcpy(ucontrol->value.bytes.data, (void *)&doa_tracking_data, + sizeof(struct doa_tracking_mon_param)); +done: + return ret; +} + +static const struct snd_kcontrol_new msm_source_tracking_controls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx SLIMBUS_0", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx SLIMBUS_0", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx SLIMBUS_0", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx SLIMBUS_0", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx TERT_MI2S", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx TERT_MI2S", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx TERT_MI2S", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx TERT_MI2S", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx INT3_MI2S", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx INT3_MI2S", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx INT3_MI2S", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx INT3_MI2S", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx VA_CDC_DMA_TX_0", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx VA_CDC_DMA_TX_0", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx VA_CDC_DMA_TX_0", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx VA_CDC_DMA_TX_0", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx TX_CDC_DMA_TX_3", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx TX_CDC_DMA_TX_3", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx TX_CDC_DMA_TX_3", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx TX_CDC_DMA_TX_3", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Voice Tx QUIN_TDM_TX_0", + .info = msm_sound_focus_info, + .get = msm_voice_sound_focus_get, + .put = msm_voice_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Voice Tx QUIN_TDM_TX_0", + .info = msm_source_tracking_info, + .get = msm_voice_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx QUIN_TDM_TX_0", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx QUIN_TDM_TX_0", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Sound Focus Audio Tx PRIMARY_TDM", + .info = msm_sound_focus_info, + .get = msm_audio_sound_focus_get, + .put = msm_audio_sound_focus_put, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Source Tracking Audio Tx PRIMARY_TDM", + .info = msm_source_tracking_info, + .get = msm_audio_source_tracking_get, + }, +}; + +static const struct snd_kcontrol_new msm_source_doa_tracking_controls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Doa Tracking Monitor Listen VA_CDC_DMA_TX_0", + .info = msm_doa_tracking_mon_info, + .get = msm_doa_tracking_mon_get, + }, +}; + +static int spkr_prot_put_vi_lch_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int item; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + + pr_debug("%s item is %d\n", __func__, + ucontrol->value.enumerated.item[0]); + mutex_lock(&routing_lock); + item = ucontrol->value.enumerated.item[0]; + if (item < e->items) { + pr_debug("%s RX DAI ID %d TX DAI id %d\n", + __func__, e->shift_l, e->values[item]); + if (e->shift_l < MSM_BACKEND_DAI_MAX && + e->values[item] < MSM_BACKEND_DAI_MAX) + /* Enable feedback TX path */ + ret = afe_spk_prot_feed_back_cfg( + msm_bedais[e->values[item]].port_id, + msm_bedais[e->shift_l].port_id, 1, 0, 1); + else { + pr_debug("%s values are out of range item %d\n", + __func__, e->values[item]); + /* Disable feedback TX path */ + if (e->values[item] == MSM_BACKEND_DAI_MAX) + ret = afe_spk_prot_feed_back_cfg(0, 0, 0, 0, 0); + else + ret = -EINVAL; + } + } else { + pr_err("%s item value is out of range item\n", __func__); + ret = -EINVAL; + } + mutex_unlock(&routing_lock); + return ret; +} + +static int spkr_prot_put_vi_rch_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + int item; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + + pr_debug("%s item is %d\n", __func__, + ucontrol->value.enumerated.item[0]); + mutex_lock(&routing_lock); + item = ucontrol->value.enumerated.item[0]; + if (item < e->items) { + pr_debug("%s RX DAI ID %d TX DAI id %d\n", + __func__, e->shift_l, e->values[item]); + if (e->shift_l < MSM_BACKEND_DAI_MAX && + e->values[item] < MSM_BACKEND_DAI_MAX) + /* Enable feedback TX path */ + ret = afe_spk_prot_feed_back_cfg( + msm_bedais[e->values[item]].port_id, + msm_bedais[e->shift_l].port_id, + 1, 1, 1); + else { + pr_debug("%s values are out of range item %d\n", + __func__, e->values[item]); + /* Disable feedback TX path */ + if (e->values[item] == MSM_BACKEND_DAI_MAX) + ret = afe_spk_prot_feed_back_cfg(0, + 0, 0, 0, 0); + else + ret = -EINVAL; + } + } else { + pr_err("%s item value is out of range item\n", __func__); + ret = -EINVAL; + } + mutex_unlock(&routing_lock); + return ret; +} + +static int spkr_prot_get_vi_lch_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s\n", __func__); + return 0; +} + +static int spkr_prot_get_vi_rch_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s\n", __func__); + ucontrol->value.enumerated.item[0] = 0; + return 0; +} + +static const char * const slim0_rx_vi_fb_tx_lch_mux_text[] = { + "ZERO", "SLIM4_TX" +}; + +static const char * const slim0_rx_vi_fb_tx_rch_mux_text[] = { + "ZERO", "SLIM4_TX" +}; + +static const char * const wsa_rx_0_vi_fb_tx_lch_mux_text[] = { + "ZERO", "WSA_CDC_DMA_TX_0" +}; + +static const char * const wsa_rx_0_vi_fb_tx_rch_mux_text[] = { + "ZERO", "WSA_CDC_DMA_TX_0" +}; + +static const char * const mi2s_rx_vi_fb_tx_mux_text[] = { + "ZERO", "SENARY_TX" +}; + +static const char * const int4_mi2s_rx_vi_fb_tx_mono_mux_text[] = { + "ZERO", "INT5_MI2S_TX" +}; + +static const char * const int4_mi2s_rx_vi_fb_tx_stereo_mux_text[] = { + "ZERO", "INT5_MI2S_TX" +}; + +static const int slim0_rx_vi_fb_tx_lch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SLIMBUS_4_TX +}; + +static const int slim0_rx_vi_fb_tx_rch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SLIMBUS_4_TX +}; + +static const int wsa_rx_0_vi_fb_tx_lch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0 +}; + +static const int wsa_rx_0_vi_fb_tx_rch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0 +}; + + +static const int mi2s_rx_vi_fb_tx_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SENARY_MI2S_TX +}; + +static const int int4_mi2s_rx_vi_fb_tx_mono_ch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_INT5_MI2S_TX +}; + +static const int int4_mi2s_rx_vi_fb_tx_stereo_ch_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_INT5_MI2S_TX +}; + +static const struct soc_enum slim0_rx_vi_fb_lch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_SLIMBUS_0_RX, 0, 0, + ARRAY_SIZE(slim0_rx_vi_fb_tx_lch_mux_text), + slim0_rx_vi_fb_tx_lch_mux_text, slim0_rx_vi_fb_tx_lch_value); + +static const struct soc_enum slim0_rx_vi_fb_rch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_SLIMBUS_0_RX, 0, 0, + ARRAY_SIZE(slim0_rx_vi_fb_tx_rch_mux_text), + slim0_rx_vi_fb_tx_rch_mux_text, slim0_rx_vi_fb_tx_rch_value); + +static const struct soc_enum wsa_rx_0_vi_fb_lch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, 0, 0, + ARRAY_SIZE(wsa_rx_0_vi_fb_tx_lch_mux_text), + wsa_rx_0_vi_fb_tx_lch_mux_text, wsa_rx_0_vi_fb_tx_lch_value); + +static const struct soc_enum wsa_rx_0_vi_fb_rch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0, 0, 0, + ARRAY_SIZE(wsa_rx_0_vi_fb_tx_rch_mux_text), + wsa_rx_0_vi_fb_tx_rch_mux_text, wsa_rx_0_vi_fb_tx_rch_value); + +static const struct soc_enum mi2s_rx_vi_fb_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_PRI_MI2S_RX, 0, 0, + ARRAY_SIZE(mi2s_rx_vi_fb_tx_mux_text), + mi2s_rx_vi_fb_tx_mux_text, mi2s_rx_vi_fb_tx_value); + +static const struct soc_enum int4_mi2s_rx_vi_fb_mono_ch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_INT4_MI2S_RX, 0, 0, + ARRAY_SIZE(int4_mi2s_rx_vi_fb_tx_mono_mux_text), + int4_mi2s_rx_vi_fb_tx_mono_mux_text, + int4_mi2s_rx_vi_fb_tx_mono_ch_value); + +static const struct soc_enum int4_mi2s_rx_vi_fb_stereo_ch_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_INT4_MI2S_RX, 0, 0, + ARRAY_SIZE(int4_mi2s_rx_vi_fb_tx_stereo_mux_text), + int4_mi2s_rx_vi_fb_tx_stereo_mux_text, + int4_mi2s_rx_vi_fb_tx_stereo_ch_value); + +static const struct snd_kcontrol_new slim0_rx_vi_fb_lch_mux = + SOC_DAPM_ENUM_EXT("SLIM0_RX_VI_FB_LCH_MUX", + slim0_rx_vi_fb_lch_mux_enum, spkr_prot_get_vi_lch_port, + spkr_prot_put_vi_lch_port); + +static const struct snd_kcontrol_new slim0_rx_vi_fb_rch_mux = + SOC_DAPM_ENUM_EXT("SLIM0_RX_VI_FB_RCH_MUX", + slim0_rx_vi_fb_rch_mux_enum, spkr_prot_get_vi_rch_port, + spkr_prot_put_vi_rch_port); + +static const struct snd_kcontrol_new wsa_rx_0_vi_fb_lch_mux = + SOC_DAPM_ENUM_EXT("WSA_RX_0_VI_FB_LCH_MUX", + wsa_rx_0_vi_fb_lch_mux_enum, spkr_prot_get_vi_lch_port, + spkr_prot_put_vi_lch_port); + +static const struct snd_kcontrol_new wsa_rx_0_vi_fb_rch_mux = + SOC_DAPM_ENUM_EXT("WSA_RX_0_VI_FB_RCH_MUX", + wsa_rx_0_vi_fb_rch_mux_enum, spkr_prot_get_vi_rch_port, + spkr_prot_put_vi_rch_port); + +static const struct snd_kcontrol_new mi2s_rx_vi_fb_mux = + SOC_DAPM_ENUM_EXT("PRI_MI2S_RX_VI_FB_MUX", + mi2s_rx_vi_fb_mux_enum, spkr_prot_get_vi_lch_port, + spkr_prot_put_vi_lch_port); + +static const struct snd_kcontrol_new int4_mi2s_rx_vi_fb_mono_ch_mux = + SOC_DAPM_ENUM_EXT("INT4_MI2S_RX_VI_FB_MONO_CH_MUX", + int4_mi2s_rx_vi_fb_mono_ch_mux_enum, spkr_prot_get_vi_lch_port, + spkr_prot_put_vi_lch_port); + +static const struct snd_kcontrol_new int4_mi2s_rx_vi_fb_stereo_ch_mux = + SOC_DAPM_ENUM_EXT("INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", + int4_mi2s_rx_vi_fb_stereo_ch_mux_enum, spkr_prot_get_vi_rch_port, + spkr_prot_put_vi_rch_port); + +static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { + /* Frontend AIF */ + /* Widget name equals to Front-End DAI name, + * Stream name must contains substring of front-end dai name + */ + SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL5", "MultiMedia5 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL6", "MultiMedia6 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL7", "MultiMedia7 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL8", "MultiMedia8 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL9", "MultiMedia9 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL10", "MultiMedia10 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL11", "MultiMedia11 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL12", "MultiMedia12 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL13", "MultiMedia13 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL14", "MultiMedia14 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL15", "MultiMedia15 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL16", "MultiMedia16 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL20", "MultiMedia20 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL21", "MultiMedia21 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL22", "MultiMedia22 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL23", "MultiMedia23 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL24", "MultiMedia24 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL25", "MultiMedia25 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MM_DL26", "MultiMedia26 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL3", "MultiMedia3 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL4", "MultiMedia4 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL5", "MultiMedia5 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL9", "MultiMedia9 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL10", "MultiMedia10 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL16", "MultiMedia16 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL17", "MultiMedia17 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL18", "MultiMedia18 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL19", "MultiMedia19 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL20", "MultiMedia20 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL21", "MultiMedia21 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL22", "MultiMedia22 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL23", "MultiMedia23 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL24", "MultiMedia24 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL25", "MultiMedia25 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL27", "MultiMedia27 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL28", "MultiMedia28 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL29", "MultiMedia29 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL30", "MultiMedia30 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOIP_UL", "VoIP Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOICEMMODE1_DL", + "VoiceMMode1 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICEMMODE1_UL", + "VoiceMMode1 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOICEMMODE2_DL", + "VoiceMMode2 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICEMMODE2_UL", + "VoiceMMode2 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM0_DL_HL", "SLIMBUS0_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM0_UL_HL", "SLIMBUS0_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("CDC_DMA_DL_HL", "CDC_DMA_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("CDC_DMA_UL_HL", "CDC_DMA_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TX3_CDC_DMA_UL_HL", + "TX3_CDC_DMA_HOSTLESS Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("CPE_LSM_UL_HL", "CPE LSM capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM1_DL_HL", "SLIMBUS1_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM1_UL_HL", "SLIMBUS1_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM3_DL_HL", "SLIMBUS3_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM3_UL_HL", "SLIMBUS3_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM4_DL_HL", "SLIMBUS4_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM4_UL_HL", "SLIMBUS4_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM6_DL_HL", "SLIMBUS6_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM6_UL_HL", "SLIMBUS6_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM7_DL_HL", "SLIMBUS7_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM7_UL_HL", "SLIMBUS7_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM8_DL_HL", "SLIMBUS8_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM8_UL_HL", "SLIMBUS8_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INTFM_DL_HL", "INT_FM_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INTHFP_DL_HL", "INT_HFP_BT_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INTHFP_UL_HL", "INT_HFP_BT_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("USBAUDIO_DL_HL", "USBAUDIO_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("USBAUDIO_UL_HL", "USBAUDIO_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("HDMI_DL_HL", "HDMI_HOSTLESS Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("DTMF_DL_HL", "DTMF_RX_HOSTLESS Playback", + 0, 0, 0, 0), + /* LSM */ + SND_SOC_DAPM_AIF_OUT("LSM1_UL_HL", "Listen 1 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM2_UL_HL", "Listen 2 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM3_UL_HL", "Listen 3 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM4_UL_HL", "Listen 4 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM5_UL_HL", "Listen 5 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM6_UL_HL", "Listen 6 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM7_UL_HL", "Listen 7 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("LSM8_UL_HL", "Listen 8 Audio Service Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QCHAT_DL", "QCHAT Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QCHAT_UL", "QCHAT Capture", 0, 0, 0, 0), + /* Backend AIF */ + /* Stream name equals to backend dai link stream name */ + SND_SOC_DAPM_AIF_OUT("PRI_SPDIF_RX", "Primary SPDIF Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_SPDIF_TX", "Primary SPDIF Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_SPDIF_RX", "Secondary SPDIF Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_SPDIF_TX", "Secondary SPDIF Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_RX", "Slimbus2 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_RX", "Slimbus5 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("HDMI_MS", "HDMI MS Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT", "Display Port Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT1", "Display Port1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_5", "Senary TDM5 Playback", + SND_SOC_DAPM_AIF_IN("INT_BT_SCO_TX", "Internal BT-SCO Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_5", "Senary TDM5 Capture", + SND_SOC_DAPM_AIF_OUT("INT_BT_A2DP_RX", "Internal BT-A2DP Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_6", "Senary TDM6 Playback", + SND_SOC_DAPM_AIF_OUT("INT_FM_RX", "Internal FM Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_6", "Senary TDM6 Capture", + SND_SOC_DAPM_AIF_IN("INT_FM_TX", "Internal FM Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_7", "Senary TDM7 Playback", + SND_SOC_DAPM_AIF_OUT("PCM_RX", "AFE Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_7", "Senary TDM7 Capture", + SND_SOC_DAPM_AIF_IN("PCM_TX", "AFE Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_META_MI2S_RX", "Primary META MI2S Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_META_MI2S_RX", "Secondary META MI2S Playback", - 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("WSA_CDC_DMA_RX_0", "WSA CDC DMA0 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("WSA_CDC_DMA_TX_0", "WSA CDC DMA0 Capture", @@ -24563,24 +24154,412 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("RX_CDC_DMA_RX_7", "RX CDC DMA7 Playback", 0, 0, 0, 0), /* incall */ - SND_SOC_DAPM_AIF_OUT("VOICE_PLAYBACK_TX", "Voice Farend Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VOICE2_PLAYBACK_TX", "Voice2 Farend Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_4_RX", "Slimbus4 Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INCALL_RECORD_TX", "Voice Uplink Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INCALL_RECORD_RX", "Voice Downlink Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_4_TX", "Slimbus4 Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SENARY_TX", "Senary_mi2s Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("INT5_MI2S_TX", "INT5 MI2S Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_5_TX", "Slimbus5 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICE_PLAYBACK_TX", "Voice Farend Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICE2_PLAYBACK_TX", "Voice2 Farend Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_4_RX", "Slimbus4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INCALL_RECORD_TX", "Voice Uplink Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INCALL_RECORD_RX", "Voice Downlink Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_2_TX", "Slimbus2 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_4_TX", "Slimbus4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_5_TX", "Slimbus5 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOICE_STUB_DL", "VOICE_STUB Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICE_STUB_UL", "VOICE_STUB Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOICE2_STUB_DL", "VOICE2_STUB Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOICE2_STUB_UL", "VOICE2_STUB Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("VOLTE_STUB_DL", "VOLTE_STUB Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("VOLTE_STUB_UL", "VOLTE_STUB Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("STUB_RX", "Stub Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("STUB_TX", "Stub Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_RX", "Slimbus1 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_1_TX", "Slimbus1 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("STUB_1_TX", "Stub1 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_3_RX", "Slimbus3 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_3_TX", "Slimbus3 Capture", 0, 0, 0, 0), + /* In- call recording */ + SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_RX", "Slimbus6 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_6_TX", "Slimbus6 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("AFE_LOOPBACK_TX", "AFE Loopback Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_7_RX", "Slimbus7 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_7_TX", "Slimbus7 Capture", 0, 0, 0, 0), + + SND_SOC_DAPM_AIF_OUT("SLIMBUS_8_RX", "Slimbus8 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_8_TX", "Slimbus8 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_9_RX", "Slimbus9 Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_9_TX", "Slimbus9 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("USB_AUDIO_RX", "USB Audio Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("USB_AUDIO_TX", "USB Audio Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PROXY_RX", "Proxy Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PROXY_TX", "Proxy Capture", 0, 0, 0, 0), + + /* Switch Definitions */ + SND_SOC_DAPM_SWITCH("SLIMBUS_DL_HL", SND_SOC_NOPM, 0, 0, + &slim_fm_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SLIMBUS1_DL_HL", SND_SOC_NOPM, 0, 0, + &slim1_fm_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SLIMBUS3_DL_HL", SND_SOC_NOPM, 0, 0, + &slim3_fm_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SLIMBUS4_DL_HL", SND_SOC_NOPM, 0, 0, + &slim4_fm_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SLIMBUS6_DL_HL", SND_SOC_NOPM, 0, 0, + &slim6_fm_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("PCM_RX_DL_HL", SND_SOC_NOPM, 0, 0, + &pcm_rx_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("SCO_SLIM7_DL_HL", SND_SOC_NOPM, 0, 0, + &sco_slim7_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("HFP_PRI_AUX_UL_HL", SND_SOC_NOPM, 0, 0, + &hfp_pri_aux_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("HFP_AUX_UL_HL", SND_SOC_NOPM, 0, 0, + &hfp_aux_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("HFP_INT_UL_HL", SND_SOC_NOPM, 0, 0, + &hfp_int_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("HFP_SLIM7_UL_HL", SND_SOC_NOPM, 0, 0, + &hfp_slim7_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("USB_DL_HL", SND_SOC_NOPM, 0, 0, + &usb_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("A2DP_SLIM7_UL_HL", SND_SOC_NOPM, 0, 0, + &a2dp_slim7_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("WSA_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, + &cdc_dma_wsa_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("RX_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, + &cdc_dma_rx_switch_mixer_controls), + SND_SOC_DAPM_SWITCH("RX_CDC_DMA_RX_1_DL_HL", SND_SOC_NOPM, 0, 0, + &cdc_dma_rx_1_switch_mixer_controls), + + /* Mixer definitions */ + SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_2_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_2_rx_mixer_controls, ARRAY_SIZE(slimbus_2_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_5_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_5_rx_mixer_controls, ARRAY_SIZE(slimbus_5_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_7_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_7_rx_mixer_controls, ARRAY_SIZE(slimbus_7_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_9_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_9_rx_mixer_controls, ARRAY_SIZE(slimbus_9_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0, + hdmi_mixer_controls, ARRAY_SIZE(hdmi_mixer_controls)), + SND_SOC_DAPM_MIXER("HDMI_MS Mixer", SND_SOC_NOPM, 0, 0, + hdmi_ms_mixer_controls, ARRAY_SIZE(hdmi_ms_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT Mixer", SND_SOC_NOPM, 0, 0, + display_port_mixer_controls, ARRAY_SIZE(display_port_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT1 Mixer", SND_SOC_NOPM, 0, 0, + display_port1_mixer_controls, ARRAY_SIZE(display_port1_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_SPDIF_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_spdif_rx_mixer_controls, ARRAY_SIZE(pri_spdif_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_SPDIF_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_spdif_rx_mixer_controls, ARRAY_SIZE(sec_spdif_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + wsa_cdc_dma_rx_0_mixer_controls, + ARRAY_SIZE(wsa_cdc_dma_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + wsa_cdc_dma_rx_1_mixer_controls, + ARRAY_SIZE(wsa_cdc_dma_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_0_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_1_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_2_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_3_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_4_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_4_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_5 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_5_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_5_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_6 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_6_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_6_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_7 Audio Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_7_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_7_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0, + mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0, + mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia3 Mixer", SND_SOC_NOPM, 0, 0, + mmul3_mixer_controls, ARRAY_SIZE(mmul3_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia4 Mixer", SND_SOC_NOPM, 0, 0, + mmul4_mixer_controls, ARRAY_SIZE(mmul4_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia5 Mixer", SND_SOC_NOPM, 0, 0, + mmul5_mixer_controls, ARRAY_SIZE(mmul5_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia6 Mixer", SND_SOC_NOPM, 0, 0, + mmul6_mixer_controls, ARRAY_SIZE(mmul6_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia8 Mixer", SND_SOC_NOPM, 0, 0, + mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia9 Mixer", SND_SOC_NOPM, 0, 0, + mmul9_mixer_controls, ARRAY_SIZE(mmul9_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia10 Mixer", SND_SOC_NOPM, 0, 0, + mmul10_mixer_controls, ARRAY_SIZE(mmul10_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia16 Mixer", SND_SOC_NOPM, 0, 0, + mmul16_mixer_controls, ARRAY_SIZE(mmul16_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia17 Mixer", SND_SOC_NOPM, 0, 0, + mmul17_mixer_controls, ARRAY_SIZE(mmul17_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia18 Mixer", SND_SOC_NOPM, 0, 0, + mmul18_mixer_controls, ARRAY_SIZE(mmul18_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia19 Mixer", SND_SOC_NOPM, 0, 0, + mmul19_mixer_controls, ARRAY_SIZE(mmul19_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia20 Mixer", SND_SOC_NOPM, 0, 0, + mmul20_mixer_controls, ARRAY_SIZE(mmul20_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia21 Mixer", SND_SOC_NOPM, 0, 0, + mmul21_mixer_controls, ARRAY_SIZE(mmul21_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia22 Mixer", SND_SOC_NOPM, 0, 0, + mmul22_mixer_controls, ARRAY_SIZE(mmul22_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia23 Mixer", SND_SOC_NOPM, 0, 0, + mmul23_mixer_controls, ARRAY_SIZE(mmul23_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia24 Mixer", SND_SOC_NOPM, 0, 0, + mmul24_mixer_controls, ARRAY_SIZE(mmul24_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia25 Mixer", SND_SOC_NOPM, 0, 0, + mmul25_mixer_controls, ARRAY_SIZE(mmul25_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia27 Mixer", SND_SOC_NOPM, 0, 0, + mmul27_mixer_controls, ARRAY_SIZE(mmul27_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia28 Mixer", SND_SOC_NOPM, 0, 0, + mmul28_mixer_controls, ARRAY_SIZE(mmul28_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia29 Mixer", SND_SOC_NOPM, 0, 0, + mmul29_mixer_controls, ARRAY_SIZE(mmul29_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia30 Mixer", SND_SOC_NOPM, 0, 0, + mmul30_mixer_controls, ARRAY_SIZE(mmul30_mixer_controls)), + /* incall */ + SND_SOC_DAPM_MIXER("Incall_Music Audio Mixer", SND_SOC_NOPM, 0, 0, + incall_music_delivery_mixer_controls, + ARRAY_SIZE(incall_music_delivery_mixer_controls)), + SND_SOC_DAPM_MIXER("Incall_Music_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + incall_music2_delivery_mixer_controls, + ARRAY_SIZE(incall_music2_delivery_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_4_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_4_rx_mixer_controls, + ARRAY_SIZE(slimbus_4_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_6_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + slimbus_6_rx_mixer_controls, + ARRAY_SIZE(slimbus_6_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("USB_AUDIO_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + usb_audio_rx_mixer_controls, + ARRAY_SIZE(usb_audio_rx_mixer_controls)), + /* Voice Mixer */ + SND_SOC_DAPM_MIXER("SLIM_0_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + slimbus_rx_voice_mixer_controls, + ARRAY_SIZE(slimbus_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + bt_sco_rx_voice_mixer_controls, + ARRAY_SIZE(bt_sco_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("AFE_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + afe_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(afe_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("HDMI_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + hdmi_rx_voice_mixer_controls, + ARRAY_SIZE(hdmi_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0_Voice Mixer", + SND_SOC_NOPM, 0, 0, + wsa_cdc_dma_rx_0_voice_mixer_controls, + ARRAY_SIZE(wsa_cdc_dma_rx_0_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("PROXY_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + proxy_rx_voice_mixer_controls, + ARRAY_SIZE(proxy_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0_Voice Mixer", + SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_0_voice_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_0_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_1_Voice Mixer", + SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_1_voice_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_1_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("Voip_Tx Mixer", + SND_SOC_NOPM, 0, 0, tx_voip_mixer_controls, + ARRAY_SIZE(tx_voip_mixer_controls)), + SND_SOC_DAPM_MIXER("VoiceMMode1_Tx Mixer", + SND_SOC_NOPM, 0, 0, tx_voicemmode1_mixer_controls, + ARRAY_SIZE(tx_voicemmode1_mixer_controls)), + SND_SOC_DAPM_MIXER("VoiceMMode2_Tx Mixer", + SND_SOC_NOPM, 0, 0, tx_voicemmode2_mixer_controls, + ARRAY_SIZE(tx_voicemmode2_mixer_controls)), + SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + int_bt_sco_rx_mixer_controls, ARRAY_SIZE(int_bt_sco_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("INTERNAL_A2DP_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + int_bt_a2dp_rx_mixer_controls, + ARRAY_SIZE(int_bt_a2dp_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("INTERNAL_FM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + int_fm_rx_mixer_controls, ARRAY_SIZE(int_fm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("AFE_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + afe_pcm_rx_mixer_controls, ARRAY_SIZE(afe_pcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("Voice Stub Tx Mixer", SND_SOC_NOPM, 0, 0, + tx_voice_stub_mixer_controls, ARRAY_SIZE(tx_voice_stub_mixer_controls)), + SND_SOC_DAPM_MIXER("Voice2 Stub Tx Mixer", SND_SOC_NOPM, 0, 0, + tx_voice2_stub_mixer_controls, + ARRAY_SIZE(tx_voice2_stub_mixer_controls)), + SND_SOC_DAPM_MIXER("VoLTE Stub Tx Mixer", SND_SOC_NOPM, 0, 0, + tx_volte_stub_mixer_controls, ARRAY_SIZE(tx_volte_stub_mixer_controls)), + SND_SOC_DAPM_MIXER("STUB_RX Mixer", SND_SOC_NOPM, 0, 0, + stub_rx_mixer_controls, ARRAY_SIZE(stub_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Mixer", SND_SOC_NOPM, 0, 0, + slimbus_1_rx_mixer_controls, ARRAY_SIZE(slimbus_1_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_3_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, + slimbus_3_rx_mixer_controls, ARRAY_SIZE(slimbus_3_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIM_6_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + slimbus_6_rx_voice_mixer_controls, + ARRAY_SIZE(slimbus_6_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIM_7_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, + slimbus_7_rx_voice_mixer_controls, + ARRAY_SIZE(slimbus_7_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIM_8_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, + slimbus_8_rx_voice_mixer_controls, + ARRAY_SIZE(slimbus_8_rx_voice_mixer_controls)), + /* port mixer */ + SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Port Mixer", + SND_SOC_NOPM, 0, 0, sbus_0_rx_port_mixer_controls, + ARRAY_SIZE(sbus_0_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Port Mixer", SND_SOC_NOPM, 0, 0, + sbus_1_rx_port_mixer_controls, + ARRAY_SIZE(sbus_1_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Port Mixer", SND_SOC_NOPM, 0, 0, + bt_sco_rx_port_mixer_controls, + ARRAY_SIZE(bt_sco_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("AFE_PCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, afe_pcm_rx_port_mixer_controls, + ARRAY_SIZE(afe_pcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("HDMI_RX Port Mixer", + SND_SOC_NOPM, 0, 0, hdmi_rx_port_mixer_controls, + ARRAY_SIZE(hdmi_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("HDMI_RX_MS Port Mixer", + SND_SOC_NOPM, 0, 0, hdmi_rx_ms_port_mixer_controls, + ARRAY_SIZE(hdmi_rx_ms_port_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX Port Mixer", + SND_SOC_NOPM, 0, 0, display_port_rx_port_mixer_controls, + ARRAY_SIZE(display_port_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX1 Port Mixer", + SND_SOC_NOPM, 0, 0, display_port_rx1_port_mixer_controls, + ARRAY_SIZE(display_port_rx1_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_3_RX Port Mixer", + SND_SOC_NOPM, 0, 0, sbus_3_rx_port_mixer_controls, + ARRAY_SIZE(sbus_3_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SLIMBUS_6_RX Port Mixer", + SND_SOC_NOPM, 0, 0, sbus_6_rx_port_mixer_controls, + ARRAY_SIZE(sbus_6_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, + wsa_cdc_dma_rx_0_port_mixer_controls, + ARRAY_SIZE(wsa_cdc_dma_rx_0_port_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_0_port_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_0_port_mixer_controls)), + SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_1 Port Mixer", SND_SOC_NOPM, 0, 0, + rx_cdc_dma_rx_1_port_mixer_controls, + ARRAY_SIZE(rx_cdc_dma_rx_1_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QCHAT_Tx Mixer", + SND_SOC_NOPM, 0, 0, tx_qchat_mixer_controls, + ARRAY_SIZE(tx_qchat_mixer_controls)), + SND_SOC_DAPM_MIXER("USB_AUDIO_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, usb_audio_rx_voice_mixer_controls, + ARRAY_SIZE(usb_audio_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("USB_AUDIO_RX Port Mixer", + SND_SOC_NOPM, 0, 0, usb_rx_port_mixer_controls, + ARRAY_SIZE(usb_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, display_port_rx_voice_mixer_controls, + ARRAY_SIZE(display_port_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX1_Voice Mixer", + SND_SOC_NOPM, 0, 0, display_port_rx1_voice_mixer_controls, + ARRAY_SIZE(display_port_rx1_voice_mixer_controls)), + /* lsm mixer definitions */ + SND_SOC_DAPM_MIXER("LSM1 Mixer", SND_SOC_NOPM, 0, 0, + lsm1_mixer_controls, ARRAY_SIZE(lsm1_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM2 Mixer", SND_SOC_NOPM, 0, 0, + lsm2_mixer_controls, ARRAY_SIZE(lsm2_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM3 Mixer", SND_SOC_NOPM, 0, 0, + lsm3_mixer_controls, ARRAY_SIZE(lsm3_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM4 Mixer", SND_SOC_NOPM, 0, 0, + lsm4_mixer_controls, ARRAY_SIZE(lsm4_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM5 Mixer", SND_SOC_NOPM, 0, 0, + lsm5_mixer_controls, ARRAY_SIZE(lsm5_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM6 Mixer", SND_SOC_NOPM, 0, 0, + lsm6_mixer_controls, ARRAY_SIZE(lsm6_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM7 Mixer", SND_SOC_NOPM, 0, 0, + lsm7_mixer_controls, ARRAY_SIZE(lsm7_mixer_controls)), + SND_SOC_DAPM_MIXER("LSM8 Mixer", SND_SOC_NOPM, 0, 0, + lsm8_mixer_controls, ARRAY_SIZE(lsm8_mixer_controls)), + /* Virtual Pins to force backends ON atm */ + SND_SOC_DAPM_OUTPUT("BE_OUT"), + SND_SOC_DAPM_INPUT("BE_IN"), + + SND_SOC_DAPM_MUX("SLIM0_RX_VI_FB_LCH_MUX", SND_SOC_NOPM, 0, 0, + &slim0_rx_vi_fb_lch_mux), + SND_SOC_DAPM_MUX("SLIM0_RX_VI_FB_RCH_MUX", SND_SOC_NOPM, 0, 0, + &slim0_rx_vi_fb_rch_mux), + SND_SOC_DAPM_MUX("WSA_RX_0_VI_FB_LCH_MUX", SND_SOC_NOPM, 0, 0, + &wsa_rx_0_vi_fb_lch_mux), + SND_SOC_DAPM_MUX("WSA_RX_0_VI_FB_RCH_MUX", SND_SOC_NOPM, 0, 0, + &wsa_rx_0_vi_fb_rch_mux), + SND_SOC_DAPM_MUX("VOC_EXT_EC MUX", SND_SOC_NOPM, 0, 0, + &voc_ext_ec_mux), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL1 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul1), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL2 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul2), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL3 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul3), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL4 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul4), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL5 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul5), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL6 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul6), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL8 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul8), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL9 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul9), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL10 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul10), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL16 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul16), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL17 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul17), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL18 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul18), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL19 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul19), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL28 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul28), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL29 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul29), +}; +#ifndef CONFIG_AUXPCM_DISABLE +static const struct snd_soc_dapm_widget msm_qdsp6_widgets_aux_pcm[] = { + /* Frontend AIF */ + /* Widget name equals to Front-End DAI name, + * Stream name must contains substring of front-end dai name + */ + SND_SOC_DAPM_AIF_IN("AUXPCM_DL_HL", "AUXPCM_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("AUXPCM_UL_HL", "AUXPCM_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_AUXPCM_DL_HL", "SEC_AUXPCM_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_AUXPCM_UL_HL", "SEC_AUXPCM_HOSTLESS Capture", + 0, 0, 0, 0), + /* LSM */ + /* Backend AIF */ + /* Stream name equals to backend dai link stream name */ + /* incall */ SND_SOC_DAPM_AIF_OUT("AUX_PCM_RX", "AUX PCM Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("AUX_PCM_TX", "AUX PCM Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("SEC_AUX_PCM_RX", "Sec AUX PCM Playback", @@ -24603,51 +24582,199 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("SEN_AUX_PCM_TX", "Sen AUX PCM Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("VOICE_STUB_DL", "VOICE_STUB Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VOICE_STUB_UL", "VOICE_STUB Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("VOICE2_STUB_DL", "VOICE2_STUB Playback", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VOICE2_STUB_UL", "VOICE2_STUB Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("VOLTE_STUB_DL", "VOLTE_STUB Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("VOLTE_STUB_UL", "VOLTE_STUB Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("STUB_RX", "Stub Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("STUB_TX", "Stub Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_RX", "Slimbus1 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_1_TX", "Slimbus1 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("STUB_1_TX", "Stub1 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_3_RX", "Slimbus3 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_3_TX", "Slimbus3 Capture", 0, 0, 0, 0), /* In- call recording */ - SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_RX", "Slimbus6 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_6_TX", "Slimbus6 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("AFE_LOOPBACK_TX", "AFE Loopback Capture", - 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_7_RX", "Slimbus7 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_7_TX", "Slimbus7 Capture", 0, 0, 0, 0), - - SND_SOC_DAPM_AIF_OUT("SLIMBUS_8_RX", "Slimbus8 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_8_TX", "Slimbus8 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_9_RX", "Slimbus9 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_9_TX", "Slimbus9 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("USB_AUDIO_RX", "USB Audio Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("USB_AUDIO_TX", "USB Audio Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PROXY_RX", "Proxy Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PROXY_TX", "Proxy Capture", 0, 0, 0, 0), /* Switch Definitions */ - SND_SOC_DAPM_SWITCH("SLIMBUS_DL_HL", SND_SOC_NOPM, 0, 0, - &slim_fm_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("SLIMBUS1_DL_HL", SND_SOC_NOPM, 0, 0, - &slim1_fm_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("SLIMBUS3_DL_HL", SND_SOC_NOPM, 0, 0, - &slim3_fm_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("SLIMBUS4_DL_HL", SND_SOC_NOPM, 0, 0, - &slim4_fm_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("SLIMBUS6_DL_HL", SND_SOC_NOPM, 0, 0, - &slim6_fm_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("PCM_RX_DL_HL", SND_SOC_NOPM, 0, 0, - &pcm_rx_switch_mixer_controls), + + /* Mixer definitions */ + SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_auxpcm_rx_mixer_controls, ARRAY_SIZE(sec_auxpcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_auxpcm_rx_mixer_controls, + ARRAY_SIZE(tert_auxpcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_auxpcm_rx_mixer_controls, + ARRAY_SIZE(quat_auxpcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_auxpcm_rx_mixer_controls, + ARRAY_SIZE(quin_auxpcm_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_auxpcm_rx_mixer_controls, + ARRAY_SIZE(sen_auxpcm_rx_mixer_controls)), + /* incall */ + /* Voice Mixer */ + SND_SOC_DAPM_MIXER("AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(aux_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + sec_aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(sec_aux_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + tert_aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(tert_aux_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + quat_aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(quat_aux_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + quin_aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(quin_aux_pcm_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_AUX_PCM_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + sen_aux_pcm_rx_voice_mixer_controls, + ARRAY_SIZE(sen_aux_pcm_rx_voice_mixer_controls)), + /* port mixer */ + SND_SOC_DAPM_MIXER("AUX_PCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, aux_pcm_rx_port_mixer_controls, + ARRAY_SIZE(aux_pcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_AUXPCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, sec_auxpcm_rx_port_mixer_controls, + ARRAY_SIZE(sec_auxpcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_AUXPCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, tert_auxpcm_rx_port_mixer_controls, + ARRAY_SIZE(tert_auxpcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_AUXPCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, quat_auxpcm_rx_port_mixer_controls, + ARRAY_SIZE(quat_auxpcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_AUXPCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, quin_auxpcm_rx_port_mixer_controls, + ARRAY_SIZE(quin_auxpcm_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_AUXPCM_RX Port Mixer", + SND_SOC_NOPM, 0, 0, sen_auxpcm_rx_port_mixer_controls, + ARRAY_SIZE(sen_auxpcm_rx_port_mixer_controls)), +}; +#endif + +#ifndef CONFIG_MI2S_DISABLE +static const struct snd_soc_dapm_widget msm_qdsp6_widgets_mi2s[] = { + /* Frontend AIF */ + /* Widget name equals to Front-End DAI name, + * Stream name must contains substring of front-end dai name + */ + SND_SOC_DAPM_AIF_IN("SEC_I2S_DL_HL", "SEC_I2S_RX_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT0_MI2S_DL_HL", + "INT0 MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT4_MI2S_DL_HL", + "INT4 MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_MI2S_DL_HL", + "Primary MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_MI2S_DL_HL", + "Secondary MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_MI2S_DL_HL", + "Tertiary MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_MI2S_DL_HL", + "Quaternary MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_MI2S_DL_HL", + "Quinary MI2S_RX Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_MI2S_DL_HL", + "Senary MI2S_RX Hostless Playback", + 0, 0, 0, 0), + + SND_SOC_DAPM_AIF_OUT("MI2S_UL_HL", "MI2S_TX_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT3_MI2S_UL_HL", + "INT3 MI2S_TX Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_MI2S_UL_HL", + "Tertiary MI2S_TX Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_MI2S_UL_HL", + "Secondary MI2S_TX Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_MI2S_UL_HL", + "Primary MI2S_TX Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MI2S_DL_HL", "MI2S_RX_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_UL_HL", + "Quaternary MI2S_TX Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_MI2S_UL_HL", + "Quinary MI2S_TX Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_MI2S_UL_HL", + "Senary MI2S_TX Hostless Capture", + 0, 0, 0, 0), + + /* Backend AIF */ + /* Stream name equals to backend dai link stream name */ + SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_I2S_RX", "Secondary I2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX", "Quaternary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX", "Tertiary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX", "Secondary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_SD1", + "Secondary MI2S Playback SD1", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_MI2S_RX", "Primary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT0_MI2S_RX", "INT0 MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT2_MI2S_RX", "INT2 MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT3_MI2S_RX", "INT3 MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT5_MI2S_RX", "INT5 MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT4_MI2S_RX", "INT4 MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT4_MI2S_TX", "INT4 MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_MI2S_RX", "Quinary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_MI2S_RX", "Senary MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("MI2S_TX", "MI2S Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX", "Quaternary MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_MI2S_TX", "Primary MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX", "Tertiary MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("INT0_MI2S_TX", "INT0 MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT2_MI2S_TX", "INT2 MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT3_MI2S_TX", "INT3 MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX", "Secondary MI2S Capture", + 0, 0, 0, 0), + + SND_SOC_DAPM_AIF_IN("QUIN_MI2S_TX", "Quinary MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SENARY_MI2S_TX", "Senary MI2S Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_META_MI2S_RX", "Primary META MI2S Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_META_MI2S_RX", "Secondary META MI2S Playback", + 0, 0, 0, 0), + /* incall */ + SND_SOC_DAPM_AIF_IN("SENARY_TX", "Senary_mi2s Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("INT5_MI2S_TX", "INT5 MI2S Capture", + 0, 0, 0, 0), + /* In- call recording */ + /* Switch Definitions */ SND_SOC_DAPM_SWITCH("INT0_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, &int0_mi2s_rx_switch_mixer_controls), SND_SOC_DAPM_SWITCH("INT4_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, @@ -24662,56 +24789,14 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &quat_mi2s_rx_switch_mixer_controls), SND_SOC_DAPM_SWITCH("QUIN_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, &quin_mi2s_rx_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("SCO_SLIM7_DL_HL", SND_SOC_NOPM, 0, 0, - &sco_slim7_switch_mixer_controls), SND_SOC_DAPM_SWITCH("SEN_MI2S_RX_DL_HL", SND_SOC_NOPM, 0, 0, &sen_mi2s_rx_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("HFP_PRI_AUX_UL_HL", SND_SOC_NOPM, 0, 0, - &hfp_pri_aux_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("HFP_AUX_UL_HL", SND_SOC_NOPM, 0, 0, - &hfp_aux_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("HFP_INT_UL_HL", SND_SOC_NOPM, 0, 0, - &hfp_int_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("HFP_SLIM7_UL_HL", SND_SOC_NOPM, 0, 0, - &hfp_slim7_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("USB_DL_HL", SND_SOC_NOPM, 0, 0, - &usb_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("A2DP_SLIM7_UL_HL", SND_SOC_NOPM, 0, 0, - &a2dp_slim7_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("WSA_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, - &cdc_dma_wsa_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("RX_CDC_DMA_RX_0_DL_HL", SND_SOC_NOPM, 0, 0, - &cdc_dma_rx_switch_mixer_controls), - SND_SOC_DAPM_SWITCH("RX_CDC_DMA_RX_1_DL_HL", SND_SOC_NOPM, 0, 0, - &cdc_dma_rx_1_switch_mixer_controls), /* Mixer definitions */ SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0, pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)), SND_SOC_DAPM_MIXER("SEC_RX Audio Mixer", SND_SOC_NOPM, 0, 0, sec_i2s_rx_mixer_controls, ARRAY_SIZE(sec_i2s_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_2_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - slimbus_2_rx_mixer_controls, ARRAY_SIZE(slimbus_2_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_5_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - slimbus_5_rx_mixer_controls, ARRAY_SIZE(slimbus_5_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_7_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - slimbus_7_rx_mixer_controls, ARRAY_SIZE(slimbus_7_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_9_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - slimbus_9_rx_mixer_controls, ARRAY_SIZE(slimbus_9_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0, - hdmi_mixer_controls, ARRAY_SIZE(hdmi_mixer_controls)), - SND_SOC_DAPM_MIXER("HDMI_MS Mixer", SND_SOC_NOPM, 0, 0, - hdmi_ms_mixer_controls, ARRAY_SIZE(hdmi_ms_mixer_controls)), - SND_SOC_DAPM_MIXER("DISPLAY_PORT Mixer", SND_SOC_NOPM, 0, 0, - display_port_mixer_controls, ARRAY_SIZE(display_port_mixer_controls)), - SND_SOC_DAPM_MIXER("DISPLAY_PORT1 Mixer", SND_SOC_NOPM, 0, 0, - display_port1_mixer_controls, ARRAY_SIZE(display_port1_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_SPDIF_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - pri_spdif_rx_mixer_controls, ARRAY_SIZE(pri_spdif_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_SPDIF_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - sec_spdif_rx_mixer_controls, ARRAY_SIZE(sec_spdif_rx_mixer_controls)), SND_SOC_DAPM_MIXER("MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, mi2s_rx_mixer_controls, ARRAY_SIZE(mi2s_rx_mixer_controls)), SND_SOC_DAPM_MIXER("QUAT_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, @@ -24741,222 +24826,13 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("SEN_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, senary_mi2s_rx_mixer_controls, ARRAY_SIZE(senary_mi2s_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - pri_tdm_rx_0_mixer_controls, - ARRAY_SIZE(pri_tdm_rx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - pri_tdm_rx_1_mixer_controls, - ARRAY_SIZE(pri_tdm_rx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - pri_tdm_rx_2_mixer_controls, - ARRAY_SIZE(pri_tdm_rx_2_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, - pri_tdm_rx_3_mixer_controls, - ARRAY_SIZE(pri_tdm_rx_3_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - pri_tdm_tx_0_mixer_controls, - ARRAY_SIZE(pri_tdm_tx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - sec_tdm_rx_0_mixer_controls, - ARRAY_SIZE(sec_tdm_rx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - sec_tdm_rx_1_mixer_controls, - ARRAY_SIZE(sec_tdm_rx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - sec_tdm_rx_2_mixer_controls, - ARRAY_SIZE(sec_tdm_rx_2_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, - sec_tdm_rx_3_mixer_controls, - ARRAY_SIZE(sec_tdm_rx_3_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - sec_tdm_tx_0_mixer_controls, - ARRAY_SIZE(sec_tdm_tx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - tert_tdm_rx_0_mixer_controls, - ARRAY_SIZE(tert_tdm_rx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - tert_tdm_tx_0_mixer_controls, - ARRAY_SIZE(tert_tdm_tx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - tert_tdm_rx_1_mixer_controls, - ARRAY_SIZE(tert_tdm_rx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - tert_tdm_rx_2_mixer_controls, - ARRAY_SIZE(tert_tdm_rx_2_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, - tert_tdm_rx_3_mixer_controls, - ARRAY_SIZE(tert_tdm_rx_3_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_TDM_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0, - tert_tdm_rx_4_mixer_controls, - ARRAY_SIZE(tert_tdm_rx_4_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - quat_tdm_rx_0_mixer_controls, - ARRAY_SIZE(quat_tdm_rx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - quat_tdm_tx_0_mixer_controls, - ARRAY_SIZE(quat_tdm_tx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - quat_tdm_rx_1_mixer_controls, - ARRAY_SIZE(quat_tdm_rx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - quat_tdm_rx_2_mixer_controls, - ARRAY_SIZE(quat_tdm_rx_2_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, - quat_tdm_rx_3_mixer_controls, - ARRAY_SIZE(quat_tdm_rx_3_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_tdm_rx_0_mixer_controls, - ARRAY_SIZE(quin_tdm_rx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_tdm_tx_0_mixer_controls, - ARRAY_SIZE(quin_tdm_tx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_tdm_rx_1_mixer_controls, - ARRAY_SIZE(quin_tdm_rx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_TX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_tdm_tx_1_mixer_controls, - ARRAY_SIZE(quin_tdm_tx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_tdm_rx_2_mixer_controls, - ARRAY_SIZE(quin_tdm_rx_2_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_TX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_tdm_tx_2_mixer_controls, - ARRAY_SIZE(quin_tdm_tx_2_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_tdm_rx_3_mixer_controls, - ARRAY_SIZE(quin_tdm_rx_3_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_TX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_tdm_tx_3_mixer_controls, - ARRAY_SIZE(quin_tdm_tx_3_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - sen_tdm_tx_0_mixer_controls, - ARRAY_SIZE(sen_tdm_tx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - sen_tdm_rx_0_mixer_controls, - ARRAY_SIZE(sen_tdm_rx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - sen_tdm_rx_1_mixer_controls, - ARRAY_SIZE(sen_tdm_rx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - sen_tdm_rx_2_mixer_controls, - ARRAY_SIZE(sen_tdm_rx_2_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, - sen_tdm_rx_3_mixer_controls, - ARRAY_SIZE(sen_tdm_rx_3_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_META_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_MIXER("PRI_META_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, pri_meta_mi2s_rx_mixer_controls, - ARRAY_SIZE(pri_meta_mi2s_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_META_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - sec_meta_mi2s_rx_mixer_controls, - ARRAY_SIZE(sec_meta_mi2s_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - wsa_cdc_dma_rx_0_mixer_controls, - ARRAY_SIZE(wsa_cdc_dma_rx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - wsa_cdc_dma_rx_1_mixer_controls, - ARRAY_SIZE(wsa_cdc_dma_rx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_0_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_0_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_1_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_1_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_2_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_2_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_3_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_3_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_4_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_4_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_5 Audio Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_5_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_5_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_6 Audio Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_6_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_6_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_7 Audio Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_7_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_7_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0, - mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0, - mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia3 Mixer", SND_SOC_NOPM, 0, 0, - mmul3_mixer_controls, ARRAY_SIZE(mmul3_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia4 Mixer", SND_SOC_NOPM, 0, 0, - mmul4_mixer_controls, ARRAY_SIZE(mmul4_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia5 Mixer", SND_SOC_NOPM, 0, 0, - mmul5_mixer_controls, ARRAY_SIZE(mmul5_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia6 Mixer", SND_SOC_NOPM, 0, 0, - mmul6_mixer_controls, ARRAY_SIZE(mmul6_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia8 Mixer", SND_SOC_NOPM, 0, 0, - mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia9 Mixer", SND_SOC_NOPM, 0, 0, - mmul9_mixer_controls, ARRAY_SIZE(mmul9_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia10 Mixer", SND_SOC_NOPM, 0, 0, - mmul10_mixer_controls, ARRAY_SIZE(mmul10_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia16 Mixer", SND_SOC_NOPM, 0, 0, - mmul16_mixer_controls, ARRAY_SIZE(mmul16_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia17 Mixer", SND_SOC_NOPM, 0, 0, - mmul17_mixer_controls, ARRAY_SIZE(mmul17_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia18 Mixer", SND_SOC_NOPM, 0, 0, - mmul18_mixer_controls, ARRAY_SIZE(mmul18_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia19 Mixer", SND_SOC_NOPM, 0, 0, - mmul19_mixer_controls, ARRAY_SIZE(mmul19_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia20 Mixer", SND_SOC_NOPM, 0, 0, - mmul20_mixer_controls, ARRAY_SIZE(mmul20_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia21 Mixer", SND_SOC_NOPM, 0, 0, - mmul21_mixer_controls, ARRAY_SIZE(mmul21_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia22 Mixer", SND_SOC_NOPM, 0, 0, - mmul22_mixer_controls, ARRAY_SIZE(mmul22_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia23 Mixer", SND_SOC_NOPM, 0, 0, - mmul23_mixer_controls, ARRAY_SIZE(mmul23_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia24 Mixer", SND_SOC_NOPM, 0, 0, - mmul24_mixer_controls, ARRAY_SIZE(mmul24_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia25 Mixer", SND_SOC_NOPM, 0, 0, - mmul25_mixer_controls, ARRAY_SIZE(mmul25_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia27 Mixer", SND_SOC_NOPM, 0, 0, - mmul27_mixer_controls, ARRAY_SIZE(mmul27_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia28 Mixer", SND_SOC_NOPM, 0, 0, - mmul28_mixer_controls, ARRAY_SIZE(mmul28_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia29 Mixer", SND_SOC_NOPM, 0, 0, - mmul29_mixer_controls, ARRAY_SIZE(mmul29_mixer_controls)), - SND_SOC_DAPM_MIXER("MultiMedia30 Mixer", SND_SOC_NOPM, 0, 0, - mmul30_mixer_controls, ARRAY_SIZE(mmul30_mixer_controls)), - SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - sec_auxpcm_rx_mixer_controls, ARRAY_SIZE(sec_auxpcm_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - tert_auxpcm_rx_mixer_controls, - ARRAY_SIZE(tert_auxpcm_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - quat_auxpcm_rx_mixer_controls, - ARRAY_SIZE(quat_auxpcm_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - quin_auxpcm_rx_mixer_controls, - ARRAY_SIZE(quin_auxpcm_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - sen_auxpcm_rx_mixer_controls, - ARRAY_SIZE(sen_auxpcm_rx_mixer_controls)), - /* incall */ - SND_SOC_DAPM_MIXER("Incall_Music Audio Mixer", SND_SOC_NOPM, 0, 0, - incall_music_delivery_mixer_controls, - ARRAY_SIZE(incall_music_delivery_mixer_controls)), - SND_SOC_DAPM_MIXER("Incall_Music_2 Audio Mixer", SND_SOC_NOPM, 0, 0, - incall_music2_delivery_mixer_controls, - ARRAY_SIZE(incall_music2_delivery_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_4_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - slimbus_4_rx_mixer_controls, - ARRAY_SIZE(slimbus_4_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_6_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - slimbus_6_rx_mixer_controls, - ARRAY_SIZE(slimbus_6_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("USB_AUDIO_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - usb_audio_rx_mixer_controls, - ARRAY_SIZE(usb_audio_rx_mixer_controls)), + ARRAY_SIZE(pri_meta_mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_META_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_meta_mi2s_rx_mixer_controls, + ARRAY_SIZE(sec_meta_mi2s_rx_mixer_controls)), + /* incall */ /* Voice Mixer */ SND_SOC_DAPM_MIXER("PRI_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, pri_rx_voice_mixer_controls, @@ -24969,46 +24845,6 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_NOPM, 0, 0, sec_mi2s_rx_voice_mixer_controls, ARRAY_SIZE(sec_mi2s_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIM_0_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - slimbus_rx_voice_mixer_controls, - ARRAY_SIZE(slimbus_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - bt_sco_rx_voice_mixer_controls, - ARRAY_SIZE(bt_sco_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("AFE_PCM_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - afe_pcm_rx_voice_mixer_controls, - ARRAY_SIZE(afe_pcm_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("AUX_PCM_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - aux_pcm_rx_voice_mixer_controls, - ARRAY_SIZE(aux_pcm_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - sec_aux_pcm_rx_voice_mixer_controls, - ARRAY_SIZE(sec_aux_pcm_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_AUX_PCM_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - tert_aux_pcm_rx_voice_mixer_controls, - ARRAY_SIZE(tert_aux_pcm_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_AUX_PCM_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - quat_aux_pcm_rx_voice_mixer_controls, - ARRAY_SIZE(quat_aux_pcm_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_AUX_PCM_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - quin_aux_pcm_rx_voice_mixer_controls, - ARRAY_SIZE(quin_aux_pcm_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_AUX_PCM_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - sen_aux_pcm_rx_voice_mixer_controls, - ARRAY_SIZE(sen_aux_pcm_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("HDMI_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - hdmi_rx_voice_mixer_controls, - ARRAY_SIZE(hdmi_rx_voice_mixer_controls)), SND_SOC_DAPM_MIXER("MI2S_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, mi2s_rx_voice_mixer_controls, @@ -25037,143 +24873,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_NOPM, 0, 0, quin_mi2s_rx_voice_mixer_controls, ARRAY_SIZE(quin_mi2s_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_RX_0_Voice Mixer", - SND_SOC_NOPM, 0, 0, - pri_tdm_rx_0_voice_mixer_controls, - ARRAY_SIZE(pri_tdm_rx_0_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_RX_1_Voice Mixer", - SND_SOC_NOPM, 0, 0, - pri_tdm_rx_1_voice_mixer_controls, - ARRAY_SIZE(pri_tdm_rx_1_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_RX_2_Voice Mixer", - SND_SOC_NOPM, 0, 0, - pri_tdm_rx_2_voice_mixer_controls, - ARRAY_SIZE(pri_tdm_rx_2_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("PRI_TDM_RX_3_Voice Mixer", - SND_SOC_NOPM, 0, 0, - pri_tdm_rx_3_voice_mixer_controls, - ARRAY_SIZE(pri_tdm_rx_3_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_MI2S_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - sen_mi2s_rx_voice_mixer_controls, - ARRAY_SIZE(sen_mi2s_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_TDM_RX_2_Voice Mixer", - SND_SOC_NOPM, 0, 0, - quat_tdm_rx_2_voice_mixer_controls, - ARRAY_SIZE(quat_tdm_rx_2_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_TDM_RX_2_Voice Mixer", - SND_SOC_NOPM, 0, 0, - quin_tdm_rx_2_voice_mixer_controls, - ARRAY_SIZE(quin_tdm_rx_2_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0_Voice Mixer", - SND_SOC_NOPM, 0, 0, - wsa_cdc_dma_rx_0_voice_mixer_controls, - ARRAY_SIZE(wsa_cdc_dma_rx_0_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("PROXY_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - proxy_rx_voice_mixer_controls, - ARRAY_SIZE(proxy_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0_Voice Mixer", - SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_0_voice_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_0_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_1_Voice Mixer", - SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_1_voice_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_1_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("Voip_Tx Mixer", - SND_SOC_NOPM, 0, 0, tx_voip_mixer_controls, - ARRAY_SIZE(tx_voip_mixer_controls)), - SND_SOC_DAPM_MIXER("VoiceMMode1_Tx Mixer", - SND_SOC_NOPM, 0, 0, tx_voicemmode1_mixer_controls, - ARRAY_SIZE(tx_voicemmode1_mixer_controls)), - SND_SOC_DAPM_MIXER("VoiceMMode2_Tx Mixer", - SND_SOC_NOPM, 0, 0, tx_voicemmode2_mixer_controls, - ARRAY_SIZE(tx_voicemmode2_mixer_controls)), - SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - int_bt_sco_rx_mixer_controls, ARRAY_SIZE(int_bt_sco_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("INTERNAL_A2DP_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - int_bt_a2dp_rx_mixer_controls, - ARRAY_SIZE(int_bt_a2dp_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("INTERNAL_FM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - int_fm_rx_mixer_controls, ARRAY_SIZE(int_fm_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("AFE_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, - afe_pcm_rx_mixer_controls, ARRAY_SIZE(afe_pcm_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("Voice Stub Tx Mixer", SND_SOC_NOPM, 0, 0, - tx_voice_stub_mixer_controls, ARRAY_SIZE(tx_voice_stub_mixer_controls)), - SND_SOC_DAPM_MIXER("Voice2 Stub Tx Mixer", SND_SOC_NOPM, 0, 0, - tx_voice2_stub_mixer_controls, - ARRAY_SIZE(tx_voice2_stub_mixer_controls)), - SND_SOC_DAPM_MIXER("VoLTE Stub Tx Mixer", SND_SOC_NOPM, 0, 0, - tx_volte_stub_mixer_controls, ARRAY_SIZE(tx_volte_stub_mixer_controls)), - SND_SOC_DAPM_MIXER("STUB_RX Mixer", SND_SOC_NOPM, 0, 0, - stub_rx_mixer_controls, ARRAY_SIZE(stub_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Mixer", SND_SOC_NOPM, 0, 0, - slimbus_1_rx_mixer_controls, ARRAY_SIZE(slimbus_1_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_3_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, - slimbus_3_rx_mixer_controls, ARRAY_SIZE(slimbus_3_rx_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIM_6_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, - slimbus_6_rx_voice_mixer_controls, - ARRAY_SIZE(slimbus_6_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIM_7_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, - slimbus_7_rx_voice_mixer_controls, - ARRAY_SIZE(slimbus_7_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIM_8_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, - slimbus_8_rx_voice_mixer_controls, - ARRAY_SIZE(slimbus_8_rx_voice_mixer_controls)), /* port mixer */ - SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Port Mixer", - SND_SOC_NOPM, 0, 0, sbus_0_rx_port_mixer_controls, - ARRAY_SIZE(sbus_0_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("AUX_PCM_RX Port Mixer", - SND_SOC_NOPM, 0, 0, aux_pcm_rx_port_mixer_controls, - ARRAY_SIZE(aux_pcm_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_AUXPCM_RX Port Mixer", - SND_SOC_NOPM, 0, 0, sec_auxpcm_rx_port_mixer_controls, - ARRAY_SIZE(sec_auxpcm_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("TERT_AUXPCM_RX Port Mixer", - SND_SOC_NOPM, 0, 0, tert_auxpcm_rx_port_mixer_controls, - ARRAY_SIZE(tert_auxpcm_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("QUAT_AUXPCM_RX Port Mixer", - SND_SOC_NOPM, 0, 0, quat_auxpcm_rx_port_mixer_controls, - ARRAY_SIZE(quat_auxpcm_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("QUIN_AUXPCM_RX Port Mixer", - SND_SOC_NOPM, 0, 0, quin_auxpcm_rx_port_mixer_controls, - ARRAY_SIZE(quin_auxpcm_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("SEN_AUXPCM_RX Port Mixer", - SND_SOC_NOPM, 0, 0, sen_auxpcm_rx_port_mixer_controls, - ARRAY_SIZE(sen_auxpcm_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Port Mixer", SND_SOC_NOPM, 0, 0, - sbus_1_rx_port_mixer_controls, - ARRAY_SIZE(sbus_1_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("INTERNAL_BT_SCO_RX Port Mixer", SND_SOC_NOPM, 0, 0, - bt_sco_rx_port_mixer_controls, - ARRAY_SIZE(bt_sco_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("AFE_PCM_RX Port Mixer", - SND_SOC_NOPM, 0, 0, afe_pcm_rx_port_mixer_controls, - ARRAY_SIZE(afe_pcm_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("HDMI_RX Port Mixer", - SND_SOC_NOPM, 0, 0, hdmi_rx_port_mixer_controls, - ARRAY_SIZE(hdmi_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("HDMI_RX_MS Port Mixer", - SND_SOC_NOPM, 0, 0, hdmi_rx_ms_port_mixer_controls, - ARRAY_SIZE(hdmi_rx_ms_port_mixer_controls)), - SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX Port Mixer", - SND_SOC_NOPM, 0, 0, display_port_rx_port_mixer_controls, - ARRAY_SIZE(display_port_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX1 Port Mixer", - SND_SOC_NOPM, 0, 0, display_port_rx1_port_mixer_controls, - ARRAY_SIZE(display_port_rx1_port_mixer_controls)), SND_SOC_DAPM_MIXER("SEC_I2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, sec_i2s_rx_port_mixer_controls, ARRAY_SIZE(sec_i2s_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_3_RX Port Mixer", - SND_SOC_NOPM, 0, 0, sbus_3_rx_port_mixer_controls, - ARRAY_SIZE(sbus_3_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("SLIMBUS_6_RX Port Mixer", - SND_SOC_NOPM, 0, 0, sbus_6_rx_port_mixer_controls, - ARRAY_SIZE(sbus_6_rx_port_mixer_controls)), SND_SOC_DAPM_MIXER("MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, mi2s_rx_port_mixer_controls, ARRAY_SIZE(mi2s_rx_port_mixer_controls)), SND_SOC_DAPM_MIXER("PRI_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, @@ -25194,6 +24897,650 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("SEN_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, sen_mi2s_rx_port_mixer_controls, ARRAY_SIZE(sen_mi2s_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("INT0_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, + int0_mi2s_rx_port_mixer_controls, + ARRAY_SIZE(int0_mi2s_rx_port_mixer_controls)), + SND_SOC_DAPM_MIXER("INT4_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, + int4_mi2s_rx_port_mixer_controls, + ARRAY_SIZE(int4_mi2s_rx_port_mixer_controls)), + /* lsm mixer definitions */ + /* Virtual Pins to force backends ON atm */ + SND_SOC_DAPM_MUX("PRI_MI2S_RX_VI_FB_MUX", SND_SOC_NOPM, 0, 0, + &mi2s_rx_vi_fb_mux), + SND_SOC_DAPM_MUX("INT4_MI2S_RX_VI_FB_MONO_CH_MUX", SND_SOC_NOPM, 0, 0, + &int4_mi2s_rx_vi_fb_mono_ch_mux), + SND_SOC_DAPM_MUX("INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", SND_SOC_NOPM, 0, 0, + &int4_mi2s_rx_vi_fb_stereo_ch_mux), +}; +#endif + +#ifndef CONFIG_TDM_DISABLE +static const struct snd_soc_dapm_widget msm_qdsp6_widgets_tdm[] = { + /* Frontend AIF */ + /* Widget name equals to Front-End DAI name, + * Stream name must contains substring of front-end dai name + */ + + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_0_DL_HL", + "Primary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_0_UL_HL", + "Primary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_1_DL_HL", + "Primary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_1_UL_HL", + "Primary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_2_DL_HL", + "Primary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_2_UL_HL", + "Primary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_3_DL_HL", + "Primary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_3_UL_HL", + "Primary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_4_DL_HL", + "Primary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_4_UL_HL", + "Primary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_5_DL_HL", + "Primary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_5_UL_HL", + "Primary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_6_DL_HL", + "Primary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_6_UL_HL", + "Primary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_RX_7_DL_HL", + "Primary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_TX_7_UL_HL", + "Primary TDM7 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_0_DL_HL", + "Secondary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_0_UL_HL", + "Secondary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_1_DL_HL", + "Secondary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_1_UL_HL", + "Secondary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_2_DL_HL", + "Secondary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_2_UL_HL", + "Secondary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_3_DL_HL", + "Secondary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_3_UL_HL", + "Secondary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_4_DL_HL", + "Secondary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_4_UL_HL", + "Secondary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_5_DL_HL", + "Secondary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_5_UL_HL", + "Secondary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_6_DL_HL", + "Secondary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_6_UL_HL", + "Secondary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_7_DL_HL", + "Secondary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_7_UL_HL", + "Secondary TDM7 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_0_DL_HL", + "Tertiary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_0_UL_HL", + "Tertiary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_1_DL_HL", + "Tertiary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_1_UL_HL", + "Tertiary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_2_DL_HL", + "Tertiary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_2_UL_HL", + "Tertiary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_3_DL_HL", + "Tertiary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_3_UL_HL", + "Tertiary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_4_DL_HL", + "Tertiary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_4_UL_HL", + "Tertiary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_5_DL_HL", + "Tertiary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_5_UL_HL", + "Tertiary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_6_DL_HL", + "Tertiary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_6_UL_HL", + "Tertiary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_7_DL_HL", + "Tertiary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_7_UL_HL", + "Tertiary TDM7 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_0_DL_HL", + "Quaternary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_0_UL_HL", + "Quaternary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_1_DL_HL", + "Quaternary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_1_UL_HL", + "Quaternary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_2_DL_HL", + "Quaternary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_2_UL_HL", + "Quaternary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_3_DL_HL", + "Quaternary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_3_UL_HL", + "Quaternary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_4_DL_HL", + "Quaternary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_4_UL_HL", + "Quaternary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_5_DL_HL", + "Quaternary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_5_UL_HL", + "Quaternary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_6_DL_HL", + "Quaternary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_6_UL_HL", + "Quaternary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_7_DL_HL", + "Quaternary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_7_UL_HL", + "Quaternary TDM7 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_0_DL_HL", + "Quinary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_0_UL_HL", + "Quinary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_1_DL_HL", + "Quinary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_1_UL_HL", + "Quinary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_2_DL_HL", + "Quinary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_2_UL_HL", + "Quinary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_3_DL_HL", + "Quinary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_3_UL_HL", + "Quinary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_4_DL_HL", + "Quinary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_4_UL_HL", + "Quinary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_5_DL_HL", + "Quinary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_5_UL_HL", + "Quinary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_6_DL_HL", + "Quinary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_6_UL_HL", + "Quinary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_7_DL_HL", + "Quinary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_7_UL_HL", + "Quinary TDM7 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_0_DL_HL", + "Senary TDM0 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_0_UL_HL", + "Senary TDM0 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_1_DL_HL", + "Senary TDM1 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_1_UL_HL", + "Senary TDM1 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_2_DL_HL", + "Senary TDM2 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_2_UL_HL", + "Senary TDM2 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_3_DL_HL", + "Senary TDM3 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_3_UL_HL", + "Senary TDM3 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_4_DL_HL", + "Senary TDM4 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_4_UL_HL", + "Senary TDM4 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_5_DL_HL", + "Senary TDM5 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_5_UL_HL", + "Senary TDM5 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_6_DL_HL", + "Senary TDM6 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_6_UL_HL", + "Senary TDM6 Hostless Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_RX_7_DL_HL", + "Senary TDM7 Hostless Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_TX_7_UL_HL", + "Senary TDM7 Hostless Capture", + 0, 0, 0, 0), + + /* Backend AIF */ + /* Stream name equals to backend dai link stream name */ + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_0", "Primary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_0", "Primary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_1", "Primary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_1", "Primary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_2", "Primary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_2", "Primary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_3", "Primary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_3", "Primary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_4", "Primary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_4", "Primary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_5", "Primary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_5", "Primary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_6", "Primary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_6", "Primary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_7", "Primary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_7", "Primary TDM7 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_0", "Secondary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_0", "Secondary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_1", "Secondary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_1", "Secondary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_2", "Secondary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_2", "Secondary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_3", "Secondary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_3", "Secondary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_4", "Secondary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_4", "Secondary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_5", "Secondary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_5", "Secondary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_6", "Secondary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_6", "Secondary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_7", "Secondary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_7", "Secondary TDM7 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_0", "Tertiary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_0", "Tertiary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_1", "Tertiary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_1", "Tertiary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_2", "Tertiary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_2", "Tertiary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_3", "Tertiary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_3", "Tertiary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_4", "Tertiary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_4", "Tertiary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_5", "Tertiary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_5", "Tertiary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_6", "Tertiary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_6", "Tertiary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_7", "Tertiary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_7", "Tertiary TDM7 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_0", "Quaternary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_0", "Quaternary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_1", "Quaternary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_1", "Quaternary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_2", "Quaternary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_2", "Quaternary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_3", "Quaternary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_3", "Quaternary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_4", "Quaternary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_4", "Quaternary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_5", "Quaternary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_5", "Quaternary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_6", "Quaternary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_6", "Quaternary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_7", "Quaternary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_7", "Quaternary TDM7 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_0", "Quinary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_0", "Quinary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_1", "Quinary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_1", "Quinary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_2", "Quinary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_2", "Quinary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_3", "Quinary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_3", "Quinary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_4", "Quinary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_4", "Quinary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_5", "Quinary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_5", "Quinary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_6", "Quinary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_6", "Quinary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_7", "Quinary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_7", "Quinary TDM7 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_0", "Senary TDM0 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_0", "Senary TDM0 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_1", "Senary TDM1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_1", "Senary TDM1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_2", "Senary TDM2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_2", "Senary TDM2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_3", "Senary TDM3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_3", "Senary TDM3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_4", "Senary TDM4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_4", "Senary TDM4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_5", "Senary TDM5 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_5", "Senary TDM5 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_6", "Senary TDM6 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_6", "Senary TDM6 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEN_TDM_RX_7", "Senary TDM7 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_7", "Senary TDM7 Capture", + 0, 0, 0, 0), + /* incall */ + /* In- call recording */ + /* Switch Definitions */ + /* Mixer definitions */ + SND_SOC_DAPM_MIXER("PRI_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_0_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_1_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_2_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_rx_3_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + pri_tdm_tx_0_mixer_controls, + ARRAY_SIZE(pri_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_0_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_1_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_2_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_rx_3_mixer_controls, + ARRAY_SIZE(sec_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + sec_tdm_tx_0_mixer_controls, + ARRAY_SIZE(sec_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_0_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_tx_0_mixer_controls, + ARRAY_SIZE(tert_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_1_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_2_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_3_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_TDM_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0, + tert_tdm_rx_4_mixer_controls, + ARRAY_SIZE(tert_tdm_rx_4_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_0_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_tx_0_mixer_controls, + ARRAY_SIZE(quat_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_1_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_2_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + quat_tdm_rx_3_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_0_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_tx_0_mixer_controls, + ARRAY_SIZE(quin_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_1_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_TX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_tx_1_mixer_controls, + ARRAY_SIZE(quin_tdm_tx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_2_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_TX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_tx_2_mixer_controls, + ARRAY_SIZE(quin_tdm_tx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_rx_3_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_TX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + quin_tdm_tx_3_mixer_controls, + ARRAY_SIZE(quin_tdm_tx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_tx_0_mixer_controls, + ARRAY_SIZE(sen_tdm_tx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_rx_0_mixer_controls, + ARRAY_SIZE(sen_tdm_rx_0_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_rx_1_mixer_controls, + ARRAY_SIZE(sen_tdm_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_rx_2_mixer_controls, + ARRAY_SIZE(sen_tdm_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + sen_tdm_rx_3_mixer_controls, + ARRAY_SIZE(sen_tdm_rx_3_mixer_controls)), + /* incall */ + /* Voice Mixer */ + SND_SOC_DAPM_MIXER("PRI_TDM_RX_0_Voice Mixer", + SND_SOC_NOPM, 0, 0, + pri_tdm_rx_0_voice_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_0_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_1_Voice Mixer", + SND_SOC_NOPM, 0, 0, + pri_tdm_rx_1_voice_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_1_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_2_Voice Mixer", + SND_SOC_NOPM, 0, 0, + pri_tdm_rx_2_voice_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_2_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("PRI_TDM_RX_3_Voice Mixer", + SND_SOC_NOPM, 0, 0, + pri_tdm_rx_3_voice_mixer_controls, + ARRAY_SIZE(pri_tdm_rx_3_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("SEN_MI2S_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, + sen_mi2s_rx_voice_mixer_controls, + ARRAY_SIZE(sen_mi2s_rx_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_TDM_RX_2_Voice Mixer", + SND_SOC_NOPM, 0, 0, + quat_tdm_rx_2_voice_mixer_controls, + ARRAY_SIZE(quat_tdm_rx_2_voice_mixer_controls)), + SND_SOC_DAPM_MIXER("QUIN_TDM_RX_2_Voice Mixer", + SND_SOC_NOPM, 0, 0, + quin_tdm_rx_2_voice_mixer_controls, + ARRAY_SIZE(quin_tdm_rx_2_voice_mixer_controls)), + /* port mixer */ SND_SOC_DAPM_MIXER("PRI_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, pri_tdm_rx_0_port_mixer_controls, ARRAY_SIZE(pri_tdm_rx_0_port_mixer_controls)), @@ -25275,2851 +25622,3619 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("SEN_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0, sen_tdm_rx_3_port_mixer_controls, ARRAY_SIZE(sen_tdm_rx_3_port_mixer_controls)), - SND_SOC_DAPM_MIXER("INT0_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, - int0_mi2s_rx_port_mixer_controls, - ARRAY_SIZE(int0_mi2s_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("INT4_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, - int4_mi2s_rx_port_mixer_controls, - ARRAY_SIZE(int4_mi2s_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, - wsa_cdc_dma_rx_0_port_mixer_controls, - ARRAY_SIZE(wsa_cdc_dma_rx_0_port_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_0_port_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_0_port_mixer_controls)), - SND_SOC_DAPM_MIXER("RX_CDC_DMA_RX_1 Port Mixer", SND_SOC_NOPM, 0, 0, - rx_cdc_dma_rx_1_port_mixer_controls, - ARRAY_SIZE(rx_cdc_dma_rx_1_port_mixer_controls)), - SND_SOC_DAPM_MIXER("QCHAT_Tx Mixer", - SND_SOC_NOPM, 0, 0, tx_qchat_mixer_controls, - ARRAY_SIZE(tx_qchat_mixer_controls)), - SND_SOC_DAPM_MIXER("USB_AUDIO_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, usb_audio_rx_voice_mixer_controls, - ARRAY_SIZE(usb_audio_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("USB_AUDIO_RX Port Mixer", - SND_SOC_NOPM, 0, 0, usb_rx_port_mixer_controls, - ARRAY_SIZE(usb_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX_Voice Mixer", - SND_SOC_NOPM, 0, 0, display_port_rx_voice_mixer_controls, - ARRAY_SIZE(display_port_rx_voice_mixer_controls)), - SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX1_Voice Mixer", - SND_SOC_NOPM, 0, 0, display_port_rx1_voice_mixer_controls, - ARRAY_SIZE(display_port_rx1_voice_mixer_controls)), - /* lsm mixer definitions */ - SND_SOC_DAPM_MIXER("LSM1 Mixer", SND_SOC_NOPM, 0, 0, - lsm1_mixer_controls, ARRAY_SIZE(lsm1_mixer_controls)), - SND_SOC_DAPM_MIXER("LSM2 Mixer", SND_SOC_NOPM, 0, 0, - lsm2_mixer_controls, ARRAY_SIZE(lsm2_mixer_controls)), - SND_SOC_DAPM_MIXER("LSM3 Mixer", SND_SOC_NOPM, 0, 0, - lsm3_mixer_controls, ARRAY_SIZE(lsm3_mixer_controls)), - SND_SOC_DAPM_MIXER("LSM4 Mixer", SND_SOC_NOPM, 0, 0, - lsm4_mixer_controls, ARRAY_SIZE(lsm4_mixer_controls)), - SND_SOC_DAPM_MIXER("LSM5 Mixer", SND_SOC_NOPM, 0, 0, - lsm5_mixer_controls, ARRAY_SIZE(lsm5_mixer_controls)), - SND_SOC_DAPM_MIXER("LSM6 Mixer", SND_SOC_NOPM, 0, 0, - lsm6_mixer_controls, ARRAY_SIZE(lsm6_mixer_controls)), - SND_SOC_DAPM_MIXER("LSM7 Mixer", SND_SOC_NOPM, 0, 0, - lsm7_mixer_controls, ARRAY_SIZE(lsm7_mixer_controls)), - SND_SOC_DAPM_MIXER("LSM8 Mixer", SND_SOC_NOPM, 0, 0, - lsm8_mixer_controls, ARRAY_SIZE(lsm8_mixer_controls)), - /* Virtual Pins to force backends ON atm */ - SND_SOC_DAPM_OUTPUT("BE_OUT"), - SND_SOC_DAPM_INPUT("BE_IN"), - SND_SOC_DAPM_MUX("SLIM0_RX_VI_FB_LCH_MUX", SND_SOC_NOPM, 0, 0, - &slim0_rx_vi_fb_lch_mux), - SND_SOC_DAPM_MUX("SLIM0_RX_VI_FB_RCH_MUX", SND_SOC_NOPM, 0, 0, - &slim0_rx_vi_fb_rch_mux), - SND_SOC_DAPM_MUX("WSA_RX_0_VI_FB_LCH_MUX", SND_SOC_NOPM, 0, 0, - &wsa_rx_0_vi_fb_lch_mux), - SND_SOC_DAPM_MUX("WSA_RX_0_VI_FB_RCH_MUX", SND_SOC_NOPM, 0, 0, - &wsa_rx_0_vi_fb_rch_mux), - SND_SOC_DAPM_MUX("PRI_MI2S_RX_VI_FB_MUX", SND_SOC_NOPM, 0, 0, - &mi2s_rx_vi_fb_mux), - SND_SOC_DAPM_MUX("INT4_MI2S_RX_VI_FB_MONO_CH_MUX", SND_SOC_NOPM, 0, 0, - &int4_mi2s_rx_vi_fb_mono_ch_mux), - SND_SOC_DAPM_MUX("INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", SND_SOC_NOPM, 0, 0, - &int4_mi2s_rx_vi_fb_stereo_ch_mux), +}; +#endif + +static const struct snd_soc_dapm_route intercon[] = { + + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_0_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"}, + + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_2_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SLIMBUS_2_RX", NULL, "SLIMBUS_2_RX Audio Mixer"}, + + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_5_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SLIMBUS_5_RX", NULL, "SLIMBUS_5_RX Audio Mixer"}, + + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0 Audio Mixer"}, + + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"WSA_CDC_DMA_RX_1", NULL, "WSA_CDC_DMA_RX_1 Audio Mixer"}, + + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0 Audio Mixer"}, + + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1 Audio Mixer"}, + + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"RX_CDC_DMA_RX_2", NULL, "RX_CDC_DMA_RX_2 Audio Mixer"}, + + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"RX_CDC_DMA_RX_3", NULL, "RX_CDC_DMA_RX_3 Audio Mixer"}, + + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"RX_CDC_DMA_RX_4", NULL, "RX_CDC_DMA_RX_4 Audio Mixer"}, + + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"RX_CDC_DMA_RX_5", NULL, "RX_CDC_DMA_RX_5 Audio Mixer"}, + + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"RX_CDC_DMA_RX_6", NULL, "RX_CDC_DMA_RX_6 Audio Mixer"}, + + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"RX_CDC_DMA_RX_7", NULL, "RX_CDC_DMA_RX_7 Audio Mixer"}, + + {"HDMI Mixer", "MultiMedia1", "MM_DL1"}, + {"HDMI Mixer", "MultiMedia2", "MM_DL2"}, + {"HDMI Mixer", "MultiMedia3", "MM_DL3"}, + {"HDMI Mixer", "MultiMedia4", "MM_DL4"}, + {"HDMI Mixer", "MultiMedia5", "MM_DL5"}, + {"HDMI Mixer", "MultiMedia6", "MM_DL6"}, + {"HDMI Mixer", "MultiMedia7", "MM_DL7"}, + {"HDMI Mixer", "MultiMedia8", "MM_DL8"}, + {"HDMI Mixer", "MultiMedia9", "MM_DL9"}, + {"HDMI Mixer", "MultiMedia10", "MM_DL10"}, + {"HDMI Mixer", "MultiMedia11", "MM_DL11"}, + {"HDMI Mixer", "MultiMedia12", "MM_DL12"}, + {"HDMI Mixer", "MultiMedia13", "MM_DL13"}, + {"HDMI Mixer", "MultiMedia14", "MM_DL14"}, + {"HDMI Mixer", "MultiMedia15", "MM_DL15"}, + {"HDMI Mixer", "MultiMedia16", "MM_DL16"}, + {"HDMI Mixer", "MultiMedia26", "MM_DL26"}, + {"HDMI", NULL, "HDMI Mixer"}, + + {"HDMI_MS Mixer", "MultiMedia1", "MM_DL1"}, + {"HDMI_MS Mixer", "MultiMedia2", "MM_DL2"}, + {"HDMI_MS Mixer", "MultiMedia3", "MM_DL3"}, + {"HDMI_MS Mixer", "MultiMedia4", "MM_DL4"}, + {"HDMI_MS Mixer", "MultiMedia5", "MM_DL5"}, + {"HDMI_MS Mixer", "MultiMedia6", "MM_DL6"}, + {"HDMI_MS Mixer", "MultiMedia7", "MM_DL7"}, + {"HDMI_MS Mixer", "MultiMedia8", "MM_DL8"}, + {"HDMI_MS Mixer", "MultiMedia9", "MM_DL9"}, + {"HDMI_MS Mixer", "MultiMedia10", "MM_DL10"}, + {"HDMI_MS Mixer", "MultiMedia11", "MM_DL11"}, + {"HDMI_MS Mixer", "MultiMedia12", "MM_DL12"}, + {"HDMI_MS Mixer", "MultiMedia13", "MM_DL13"}, + {"HDMI_MS Mixer", "MultiMedia14", "MM_DL14"}, + {"HDMI_MS Mixer", "MultiMedia15", "MM_DL15"}, + {"HDMI_MS Mixer", "MultiMedia16", "MM_DL16"}, + {"HDMI_MS Mixer", "MultiMedia26", "MM_DL26"}, + {"HDMI_MS", NULL, "HDMI_MS Mixer"}, + + {"DISPLAY_PORT Mixer", "MultiMedia1", "MM_DL1"}, + {"DISPLAY_PORT Mixer", "MultiMedia2", "MM_DL2"}, + {"DISPLAY_PORT Mixer", "MultiMedia3", "MM_DL3"}, + {"DISPLAY_PORT Mixer", "MultiMedia4", "MM_DL4"}, + {"DISPLAY_PORT Mixer", "MultiMedia5", "MM_DL5"}, + {"DISPLAY_PORT Mixer", "MultiMedia6", "MM_DL6"}, + {"DISPLAY_PORT Mixer", "MultiMedia7", "MM_DL7"}, + {"DISPLAY_PORT Mixer", "MultiMedia8", "MM_DL8"}, + {"DISPLAY_PORT Mixer", "MultiMedia9", "MM_DL9"}, + {"DISPLAY_PORT Mixer", "MultiMedia10", "MM_DL10"}, + {"DISPLAY_PORT Mixer", "MultiMedia11", "MM_DL11"}, + {"DISPLAY_PORT Mixer", "MultiMedia12", "MM_DL12"}, + {"DISPLAY_PORT Mixer", "MultiMedia13", "MM_DL13"}, + {"DISPLAY_PORT Mixer", "MultiMedia14", "MM_DL14"}, + {"DISPLAY_PORT Mixer", "MultiMedia15", "MM_DL15"}, + {"DISPLAY_PORT Mixer", "MultiMedia16", "MM_DL16"}, + {"DISPLAY_PORT Mixer", "MultiMedia26", "MM_DL26"}, + {"DISPLAY_PORT", NULL, "DISPLAY_PORT Mixer"}, + + {"DISPLAY_PORT1 Mixer", "MultiMedia1", "MM_DL1"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia2", "MM_DL2"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia3", "MM_DL3"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia4", "MM_DL4"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia5", "MM_DL5"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia6", "MM_DL6"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia7", "MM_DL7"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia8", "MM_DL8"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia9", "MM_DL9"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia10", "MM_DL10"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia11", "MM_DL11"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia12", "MM_DL12"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia13", "MM_DL13"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia14", "MM_DL14"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia15", "MM_DL15"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia16", "MM_DL16"}, + {"DISPLAY_PORT1 Mixer", "MultiMedia26", "MM_DL26"}, + {"DISPLAY_PORT1", NULL, "DISPLAY_PORT1 Mixer"}, + + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_SPDIF_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"PRI_SPDIF_RX", NULL, "PRI_SPDIF_RX Audio Mixer"}, + + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_SPDIF_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SEC_SPDIF_RX", NULL, "SEC_SPDIF_RX Audio Mixer"}, + + /* incall */ + {"Incall_Music Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"Incall_Music Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"Incall_Music Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"Incall_Music Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"Incall_Music Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"VOICE_PLAYBACK_TX", NULL, "Incall_Music Audio Mixer"}, + {"Incall_Music_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"Incall_Music_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"Incall_Music_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"Incall_Music_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"VOICE2_PLAYBACK_TX", NULL, "Incall_Music_2 Audio Mixer"}, + {"SLIMBUS_4_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_4_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_4_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_4_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_4_RX", NULL, "SLIMBUS_4_RX Audio Mixer"}, + + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_6_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SLIMBUS_6_RX", NULL, "SLIMBUS_6_RX Audio Mixer"}, + + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_7_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SLIMBUS_7_RX", NULL, "SLIMBUS_7_RX Audio Mixer"}, + + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SLIMBUS_9_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SLIMBUS_9_RX", NULL, "SLIMBUS_9_RX Audio Mixer"}, + + {"USB_AUDIO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX Audio Mixer"}, + + {"MultiMedia1 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, + {"MultiMedia4 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, + {"MultiMedia8 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, + {"MultiMedia9 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, + {"MultiMedia1 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, + {"MultiMedia4 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, + {"MultiMedia8 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, + {"MultiMedia9 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, + {"MultiMedia1 Mixer", "SLIM_4_TX", "SLIMBUS_4_TX"}, + {"MultiMedia1 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, + {"MultiMedia1 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia1 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"MultiMedia1 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, + {"MultiMedia8 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, + {"MultiMedia8 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia8 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, + {"MultiMedia4 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia4 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia17 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia17 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia17 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia17 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia18 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia18 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia19 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia19 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia28 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia28 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia29 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia29 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia30 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia30 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia8 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia8 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia3 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia5 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia10 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia10 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia16 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia16 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia5 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia5 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"MultiMedia5 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, + {"MultiMedia10 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia10 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, + {"MultiMedia18 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia19 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia28 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia29 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia30 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia18 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia19 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia28 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia29 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia30 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + + {"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia1 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia2 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia2 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, + {"MultiMedia2 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia2 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"MultiMedia6 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia6 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + + {"MultiMedia1 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia1 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia1 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + + {"MultiMedia2 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia2 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia2 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + + {"MultiMedia3 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia3 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia3 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + + {"MultiMedia4 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia4 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia4 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + + {"MultiMedia5 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia5 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia5 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + + {"MultiMedia6 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia6 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia6 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + + {"MultiMedia8 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia8 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia8 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + + {"MultiMedia9 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia9 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia9 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia9 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia10 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + + {"MultiMedia20 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia20 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia20 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia20 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia20 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia20 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, + {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia20 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia20 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia20 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + + {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia21 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia21 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia21 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + + {"MultiMedia27 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia27 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MultiMedia27 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, + {"MultiMedia27 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"MultiMedia27 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, + {"MultiMedia27 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia27 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia27 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + + {"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia4 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia5 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia6 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia8 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia10 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + + {"MultiMedia16 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, + {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, + {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia16 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, + {"MultiMedia16 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"MultiMedia16 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia17 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia18 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia18 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia18 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia19 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia19 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia19 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia28 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia28 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia28 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia29 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia29 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia29 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, + {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, + {"MultiMedia30 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"MultiMedia30 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"MultiMedia30 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia6", "MM_UL6"}, + {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"}, + + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia6", "MM_UL6"}, + {"INT_BT_A2DP_RX", NULL, "INTERNAL_A2DP_RX Audio Mixer"}, + + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"INTERNAL_FM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"}, + + {"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"AFE_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"}, + + {"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia3 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia4 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia10 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia17 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia18 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia19 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia28 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia29 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia30 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia5 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia8 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia16 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia4 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia16 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia17 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia18 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia19 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia28 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia29 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia30 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia5 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia6 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia8 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + + {"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia3 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia4 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia10 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia17 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia18 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia19 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia28 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia29 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia30 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia5 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia8 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia16 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MM_UL1", NULL, "MultiMedia1 Mixer"}, + {"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MM_UL2", NULL, "MultiMedia2 Mixer"}, + {"MM_UL3", NULL, "MultiMedia3 Mixer"}, + {"MM_UL4", NULL, "MultiMedia4 Mixer"}, + {"MM_UL5", NULL, "MultiMedia5 Mixer"}, + {"MM_UL6", NULL, "MultiMedia6 Mixer"}, + {"MM_UL8", NULL, "MultiMedia8 Mixer"}, + {"MM_UL9", NULL, "MultiMedia9 Mixer"}, + {"MM_UL10", NULL, "MultiMedia10 Mixer"}, + {"MM_UL16", NULL, "MultiMedia16 Mixer"}, + {"MM_UL17", NULL, "MultiMedia17 Mixer"}, + {"MM_UL18", NULL, "MultiMedia18 Mixer"}, + {"MM_UL19", NULL, "MultiMedia19 Mixer"}, + {"MM_UL20", NULL, "MultiMedia20 Mixer"}, + {"MM_UL21", NULL, "MultiMedia21 Mixer"}, + {"MM_UL22", NULL, "MultiMedia22 Mixer"}, + {"MM_UL23", NULL, "MultiMedia23 Mixer"}, + {"MM_UL24", NULL, "MultiMedia24 Mixer"}, + {"MM_UL25", NULL, "MultiMedia25 Mixer"}, + {"MM_UL27", NULL, "MultiMedia27 Mixer"}, + {"MM_UL28", NULL, "MultiMedia28 Mixer"}, + {"MM_UL29", NULL, "MultiMedia29 Mixer"}, + {"MM_UL30", NULL, "MultiMedia30 Mixer"}, + - SND_SOC_DAPM_MUX("VOC_EXT_EC MUX", SND_SOC_NOPM, 0, 0, - &voc_ext_ec_mux), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL1 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul1), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL2 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul2), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL3 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul3), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL4 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul4), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL5 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul5), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL6 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul6), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL8 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul8), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL9 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul9), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL10 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul10), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL16 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul16), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL17 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul17), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL18 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul18), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL19 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul19), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL28 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul28), - SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL29 MUX", SND_SOC_NOPM, 0, 0, - &ext_ec_ref_mux_ul29), -}; + {"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SLIM_0_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SLIM_0_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SLIM_0_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIM_0_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"}, -static const struct snd_soc_dapm_route intercon[] = { - {"PRI_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"}, + {"SLIM_6_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SLIM_6_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SLIM_6_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SLIM_6_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIM_6_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SLIMBUS_6_RX", NULL, "SLIM_6_RX_Voice Mixer"}, - {"SEC_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SEC_I2S_RX", NULL, "SEC_RX Audio Mixer"}, + {"USB_AUDIO_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"USB_AUDIO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX_Voice Mixer"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SLIMBUS_0_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"}, + {"DISPLAY_PORT_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"DISPLAY_PORT_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"DISPLAY_PORT_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"DISPLAY_PORT_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"DISPLAY_PORT_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"DISPLAY_PORT", NULL, "DISPLAY_PORT_RX_Voice Mixer"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SLIMBUS_2_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SLIMBUS_2_RX", NULL, "SLIMBUS_2_RX Audio Mixer"}, + {"DISPLAY_PORT_RX1_Voice Mixer", "Voip", "VOIP_DL"}, + {"DISPLAY_PORT_RX1_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"DISPLAY_PORT_RX1_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"DISPLAY_PORT_RX1_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"DISPLAY_PORT_RX1_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"DISPLAY_PORT1", NULL, "DISPLAY_PORT_RX1_Voice Mixer"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SLIMBUS_5_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SLIMBUS_5_RX", NULL, "SLIMBUS_5_RX Audio Mixer"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"WSA_CDC_DMA_RX_0 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0 Audio Mixer"}, + {"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"AFE_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"AFE_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"AFE_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"AFE_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"WSA_CDC_DMA_RX_1 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"WSA_CDC_DMA_RX_1", NULL, "WSA_CDC_DMA_RX_1 Audio Mixer"}, + {"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"HDMI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"HDMI_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"HDMI_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"HDMI_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"HDMI", NULL, "HDMI_RX_Voice Mixer"}, + {"HDMI", NULL, "HDMI_DL_HL"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"RX_CDC_DMA_RX_0 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0 Audio Mixer"}, + {"WSA_CDC_DMA_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, + {"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0_Voice Mixer"}, + + {"PROXY_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PROXY_RX", NULL, "PROXY_RX_Voice Mixer"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"RX_CDC_DMA_RX_1 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1 Audio Mixer"}, + {"PROXY_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PROXY_RX", NULL, "PROXY_RX_Voice Mixer"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"RX_CDC_DMA_RX_2 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"RX_CDC_DMA_RX_2", NULL, "RX_CDC_DMA_RX_2 Audio Mixer"}, + {"RX_CDC_DMA_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, + {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0_Voice Mixer"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"RX_CDC_DMA_RX_3 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"RX_CDC_DMA_RX_3", NULL, "RX_CDC_DMA_RX_3 Audio Mixer"}, + {"RX_CDC_DMA_RX_1_Voice Mixer", "Voip", "VOIP_DL"}, + {"RX_CDC_DMA_RX_1_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"RX_CDC_DMA_RX_1_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1_Voice Mixer"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"RX_CDC_DMA_RX_4 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"RX_CDC_DMA_RX_4", NULL, "RX_CDC_DMA_RX_4 Audio Mixer"}, + {"VOC_EXT_EC MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"VOIP_UL", NULL, "VOC_EXT_EC MUX"}, + {"VOICEMMODE1_UL", NULL, "VOC_EXT_EC MUX"}, + {"VOICEMMODE2_UL", NULL, "VOC_EXT_EC MUX"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"RX_CDC_DMA_RX_5 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"RX_CDC_DMA_RX_5", NULL, "RX_CDC_DMA_RX_5 Audio Mixer"}, + {"AUDIO_REF_EC_UL1 MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"RX_CDC_DMA_RX_6 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"RX_CDC_DMA_RX_6", NULL, "RX_CDC_DMA_RX_6 Audio Mixer"}, + {"LSM1_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM2_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM3_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM4_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM5_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM6_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM7_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"LSM8_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"RX_CDC_DMA_RX_7 Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"RX_CDC_DMA_RX_7", NULL, "RX_CDC_DMA_RX_7 Audio Mixer"}, + {"MM_UL1", NULL, "AUDIO_REF_EC_UL1 MUX"}, + {"MM_UL2", NULL, "AUDIO_REF_EC_UL2 MUX"}, + {"MM_UL3", NULL, "AUDIO_REF_EC_UL3 MUX"}, + {"MM_UL4", NULL, "AUDIO_REF_EC_UL4 MUX"}, + {"MM_UL5", NULL, "AUDIO_REF_EC_UL5 MUX"}, + {"MM_UL6", NULL, "AUDIO_REF_EC_UL6 MUX"}, + {"MM_UL8", NULL, "AUDIO_REF_EC_UL8 MUX"}, + {"MM_UL9", NULL, "AUDIO_REF_EC_UL9 MUX"}, + {"MM_UL10", NULL, "AUDIO_REF_EC_UL10 MUX"}, + {"MM_UL16", NULL, "AUDIO_REF_EC_UL16 MUX"}, + {"MM_UL17", NULL, "AUDIO_REF_EC_UL17 MUX"}, + {"MM_UL18", NULL, "AUDIO_REF_EC_UL18 MUX"}, + {"MM_UL19", NULL, "AUDIO_REF_EC_UL19 MUX"}, + {"MM_UL28", NULL, "AUDIO_REF_EC_UL28 MUX"}, + {"MM_UL29", NULL, "AUDIO_REF_EC_UL29 MUX"}, + {"MM_UL30", NULL, "AUDIO_REF_EC_UL30 MUX"}, - {"HDMI Mixer", "MultiMedia1", "MM_DL1"}, - {"HDMI Mixer", "MultiMedia2", "MM_DL2"}, - {"HDMI Mixer", "MultiMedia3", "MM_DL3"}, - {"HDMI Mixer", "MultiMedia4", "MM_DL4"}, - {"HDMI Mixer", "MultiMedia5", "MM_DL5"}, - {"HDMI Mixer", "MultiMedia6", "MM_DL6"}, - {"HDMI Mixer", "MultiMedia7", "MM_DL7"}, - {"HDMI Mixer", "MultiMedia8", "MM_DL8"}, - {"HDMI Mixer", "MultiMedia9", "MM_DL9"}, - {"HDMI Mixer", "MultiMedia10", "MM_DL10"}, - {"HDMI Mixer", "MultiMedia11", "MM_DL11"}, - {"HDMI Mixer", "MultiMedia12", "MM_DL12"}, - {"HDMI Mixer", "MultiMedia13", "MM_DL13"}, - {"HDMI Mixer", "MultiMedia14", "MM_DL14"}, - {"HDMI Mixer", "MultiMedia15", "MM_DL15"}, - {"HDMI Mixer", "MultiMedia16", "MM_DL16"}, - {"HDMI Mixer", "MultiMedia26", "MM_DL26"}, - {"HDMI", NULL, "HDMI Mixer"}, + {"VoiceMMode1_Tx Mixer", "SLIM_0_TX_MMode1", "SLIMBUS_0_TX"}, + {"VoiceMMode1_Tx Mixer", "SLIM_7_TX_MMode1", "SLIMBUS_7_TX"}, + {"VoiceMMode1_Tx Mixer", "SLIM_8_TX_MMode1", "SLIMBUS_8_TX"}, + {"VoiceMMode1_Tx Mixer", "USB_AUDIO_TX_MMode1", "USB_AUDIO_TX"}, + {"VoiceMMode1_Tx Mixer", "INT_BT_SCO_TX_MMode1", "INT_BT_SCO_TX"}, + {"VoiceMMode1_Tx Mixer", "AFE_PCM_TX_MMode1", "PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_0_MMode1", "TX_CDC_DMA_TX_0"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_1_MMode1", "TX_CDC_DMA_TX_1"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_2_MMode1", "TX_CDC_DMA_TX_2"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_3_MMode1", "TX_CDC_DMA_TX_3"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_4_MMode1", "TX_CDC_DMA_TX_4"}, + {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_5_MMode1", "TX_CDC_DMA_TX_5"}, + {"VoiceMMode1_Tx Mixer", "PROXY_TX_MMode1", "PROXY_TX"}, + {"VOICEMMODE1_UL", NULL, "VoiceMMode1_Tx Mixer"}, - {"HDMI_MS Mixer", "MultiMedia1", "MM_DL1"}, - {"HDMI_MS Mixer", "MultiMedia2", "MM_DL2"}, - {"HDMI_MS Mixer", "MultiMedia3", "MM_DL3"}, - {"HDMI_MS Mixer", "MultiMedia4", "MM_DL4"}, - {"HDMI_MS Mixer", "MultiMedia5", "MM_DL5"}, - {"HDMI_MS Mixer", "MultiMedia6", "MM_DL6"}, - {"HDMI_MS Mixer", "MultiMedia7", "MM_DL7"}, - {"HDMI_MS Mixer", "MultiMedia8", "MM_DL8"}, - {"HDMI_MS Mixer", "MultiMedia9", "MM_DL9"}, - {"HDMI_MS Mixer", "MultiMedia10", "MM_DL10"}, - {"HDMI_MS Mixer", "MultiMedia11", "MM_DL11"}, - {"HDMI_MS Mixer", "MultiMedia12", "MM_DL12"}, - {"HDMI_MS Mixer", "MultiMedia13", "MM_DL13"}, - {"HDMI_MS Mixer", "MultiMedia14", "MM_DL14"}, - {"HDMI_MS Mixer", "MultiMedia15", "MM_DL15"}, - {"HDMI_MS Mixer", "MultiMedia16", "MM_DL16"}, - {"HDMI_MS Mixer", "MultiMedia26", "MM_DL26"}, - {"HDMI_MS", NULL, "HDMI_MS Mixer"}, + {"VoiceMMode2_Tx Mixer", "SLIM_0_TX_MMode2", "SLIMBUS_0_TX"}, + {"VoiceMMode2_Tx Mixer", "SLIM_7_TX_MMode2", "SLIMBUS_7_TX"}, + {"VoiceMMode2_Tx Mixer", "SLIM_8_TX_MMode2", "SLIMBUS_8_TX"}, + {"VoiceMMode2_Tx Mixer", "USB_AUDIO_TX_MMode2", "USB_AUDIO_TX"}, + {"VoiceMMode2_Tx Mixer", "INT_BT_SCO_TX_MMode2", "INT_BT_SCO_TX"}, + {"VoiceMMode2_Tx Mixer", "AFE_PCM_TX_MMode2", "PCM_TX"}, + + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_0_MMode2", "TX_CDC_DMA_TX_0"}, + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_1_MMode2", "TX_CDC_DMA_TX_1"}, + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_2_MMode2", "TX_CDC_DMA_TX_2"}, + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_3_MMode2", "TX_CDC_DMA_TX_3"}, + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_4_MMode2", "TX_CDC_DMA_TX_4"}, + {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_5_MMode2", "TX_CDC_DMA_TX_5"}, + {"VoiceMMode2_Tx Mixer", "PROXY_TX_MMode2", "PROXY_TX"}, + {"VOICEMMODE2_UL", NULL, "VoiceMMode2_Tx Mixer"}, + + {"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"}, + {"Voip_Tx Mixer", "SLIM_7_TX_Voip", "SLIMBUS_7_TX"}, + {"Voip_Tx Mixer", "SLIM_8_TX_Voip", "SLIMBUS_8_TX"}, + {"Voip_Tx Mixer", "USB_AUDIO_TX_Voip", "USB_AUDIO_TX"}, + {"Voip_Tx Mixer", "INTERNAL_BT_SCO_TX_Voip", "INT_BT_SCO_TX"}, + {"Voip_Tx Mixer", "AFE_PCM_TX_Voip", "PCM_TX"}, + + {"Voip_Tx Mixer", "PRI_MI2S_TX_Voip", "PRI_MI2S_TX"}, + {"Voip_Tx Mixer", "PRI_TDM_TX_3_Voip", "PRI_TDM_TX_3"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_0_Voip", "TX_CDC_DMA_TX_0"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_1_Voip", "TX_CDC_DMA_TX_1"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_2_Voip", "TX_CDC_DMA_TX_2"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_3_Voip", "TX_CDC_DMA_TX_3"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_4_Voip", "TX_CDC_DMA_TX_4"}, + {"Voip_Tx Mixer", "TX_CDC_DMA_TX_5_Voip", "TX_CDC_DMA_TX_5"}, + {"VOIP_UL", NULL, "Voip_Tx Mixer"}, + + {"SLIMBUS_DL_HL", "Switch", "SLIM0_DL_HL"}, + {"SLIMBUS_0_RX", NULL, "SLIMBUS_DL_HL"}, + {"SLIMBUS1_DL_HL", "Switch", "SLIM1_DL_HL"}, + {"SLIMBUS_1_RX", NULL, "SLIMBUS1_DL_HL"}, + {"SLIMBUS3_DL_HL", "Switch", "SLIM3_DL_HL"}, + {"SLIMBUS_3_RX", NULL, "SLIMBUS3_DL_HL"}, + {"SLIMBUS4_DL_HL", "Switch", "SLIM4_DL_HL"}, + {"SLIMBUS_4_RX", NULL, "SLIMBUS4_DL_HL"}, + {"SLIMBUS6_DL_HL", "Switch", "SLIM0_DL_HL"}, + {"SLIMBUS_6_RX", NULL, "SLIMBUS6_DL_HL"}, + {"SCO_SLIM7_DL_HL", "Switch", "SLIM7_DL_HL"}, + {"SLIMBUS_7_RX", NULL, "SCO_SLIM7_DL_HL"}, + {"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"}, + {"SLIM1_UL_HL", NULL, "SLIMBUS_1_TX"}, + {"SLIM3_UL_HL", NULL, "SLIMBUS_3_TX"}, + {"SLIM4_UL_HL", NULL, "SLIMBUS_4_TX"}, + {"SLIM8_UL_HL", NULL, "SLIMBUS_8_TX"}, + {"WSA_CDC_DMA_RX_0_DL_HL", "Switch", "CDC_DMA_DL_HL"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0_DL_HL"}, + {"CDC_DMA_UL_HL", NULL, "VA_CDC_DMA_TX_0"}, + {"RX_CDC_DMA_RX_0_DL_HL", "Switch", "CDC_DMA_DL_HL"}, + {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0_DL_HL"}, + {"RX_CDC_DMA_RX_1_DL_HL", "Switch", "CDC_DMA_DL_HL"}, + {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1_DL_HL"}, + {"TX3_CDC_DMA_UL_HL", NULL, "TX_CDC_DMA_TX_3"}, + {"LSM1 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM1 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM1 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM1 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM1 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM1 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"LSM1 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM1_UL_HL", NULL, "LSM1 Mixer"}, - {"DISPLAY_PORT Mixer", "MultiMedia1", "MM_DL1"}, - {"DISPLAY_PORT Mixer", "MultiMedia2", "MM_DL2"}, - {"DISPLAY_PORT Mixer", "MultiMedia3", "MM_DL3"}, - {"DISPLAY_PORT Mixer", "MultiMedia4", "MM_DL4"}, - {"DISPLAY_PORT Mixer", "MultiMedia5", "MM_DL5"}, - {"DISPLAY_PORT Mixer", "MultiMedia6", "MM_DL6"}, - {"DISPLAY_PORT Mixer", "MultiMedia7", "MM_DL7"}, - {"DISPLAY_PORT Mixer", "MultiMedia8", "MM_DL8"}, - {"DISPLAY_PORT Mixer", "MultiMedia9", "MM_DL9"}, - {"DISPLAY_PORT Mixer", "MultiMedia10", "MM_DL10"}, - {"DISPLAY_PORT Mixer", "MultiMedia11", "MM_DL11"}, - {"DISPLAY_PORT Mixer", "MultiMedia12", "MM_DL12"}, - {"DISPLAY_PORT Mixer", "MultiMedia13", "MM_DL13"}, - {"DISPLAY_PORT Mixer", "MultiMedia14", "MM_DL14"}, - {"DISPLAY_PORT Mixer", "MultiMedia15", "MM_DL15"}, - {"DISPLAY_PORT Mixer", "MultiMedia16", "MM_DL16"}, - {"DISPLAY_PORT Mixer", "MultiMedia26", "MM_DL26"}, - {"DISPLAY_PORT", NULL, "DISPLAY_PORT Mixer"}, + {"LSM2 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM2 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM2 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM2 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM2 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM2 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"LSM2 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM2_UL_HL", NULL, "LSM2 Mixer"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia1", "MM_DL1"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia2", "MM_DL2"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia3", "MM_DL3"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia4", "MM_DL4"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia5", "MM_DL5"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia6", "MM_DL6"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia7", "MM_DL7"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia8", "MM_DL8"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia9", "MM_DL9"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia10", "MM_DL10"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia11", "MM_DL11"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia12", "MM_DL12"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia13", "MM_DL13"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia14", "MM_DL14"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia15", "MM_DL15"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia16", "MM_DL16"}, - {"DISPLAY_PORT1 Mixer", "MultiMedia26", "MM_DL26"}, - {"DISPLAY_PORT1", NULL, "DISPLAY_PORT1 Mixer"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_SPDIF_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"PRI_SPDIF_RX", NULL, "PRI_SPDIF_RX Audio Mixer"}, + {"LSM3 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM3 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM3 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM3 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM3 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM3 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"LSM3 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM3_UL_HL", NULL, "LSM3 Mixer"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_SPDIF_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SEC_SPDIF_RX", NULL, "SEC_SPDIF_RX Audio Mixer"}, - /* incall */ - {"Incall_Music Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"Incall_Music Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"Incall_Music Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"Incall_Music Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"Incall_Music Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"VOICE_PLAYBACK_TX", NULL, "Incall_Music Audio Mixer"}, - {"Incall_Music_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"Incall_Music_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"Incall_Music_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"Incall_Music_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"VOICE2_PLAYBACK_TX", NULL, "Incall_Music_2 Audio Mixer"}, - {"SLIMBUS_4_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SLIMBUS_4_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SLIMBUS_4_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SLIMBUS_4_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SLIMBUS_4_RX", NULL, "SLIMBUS_4_RX Audio Mixer"}, + {"LSM4 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM4 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM4 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM4 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM4 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM4 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"LSM4 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM4_UL_HL", NULL, "LSM4 Mixer"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SLIMBUS_6_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SLIMBUS_6_RX", NULL, "SLIMBUS_6_RX Audio Mixer"}, + {"LSM5 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM5 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM5 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM5 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM5 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM5 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"LSM5 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM5_UL_HL", NULL, "LSM5 Mixer"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SLIMBUS_7_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SLIMBUS_7_RX", NULL, "SLIMBUS_7_RX Audio Mixer"}, + {"LSM6 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM6 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM6 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM6 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM6 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM6 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"LSM6 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM6_UL_HL", NULL, "LSM6 Mixer"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SLIMBUS_9_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SLIMBUS_9_RX", NULL, "SLIMBUS_9_RX Audio Mixer"}, + {"LSM7 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM7 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM7 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM7 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM7 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM7 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM7 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM7 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"LSM7 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM7_UL_HL", NULL, "LSM7 Mixer"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"USB_AUDIO_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX Audio Mixer"}, + {"LSM8 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, + {"LSM8 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, + {"LSM8 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, + {"LSM8 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, + {"LSM8 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, + {"LSM8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"LSM8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"LSM8 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, + {"LSM8 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"LSM8_UL_HL", NULL, "LSM8 Mixer"}, - {"MultiMedia1 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, - {"MultiMedia4 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, - {"MultiMedia8 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, - {"MultiMedia9 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, - {"MultiMedia1 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, - {"MultiMedia4 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, - {"MultiMedia8 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, - {"MultiMedia9 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"}, - {"MultiMedia1 Mixer", "SLIM_4_TX", "SLIMBUS_4_TX"}, - {"MultiMedia1 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, - {"MultiMedia1 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"MultiMedia1 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"MultiMedia1 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"MultiMedia8 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, - {"MultiMedia8 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"MultiMedia8 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"MultiMedia4 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia4 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia17 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia17 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia17 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"MultiMedia17 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"MultiMedia18 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia18 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia19 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia19 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia28 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia28 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia29 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia29 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia30 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia30 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia8 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia8 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia2 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia4 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia17 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia18 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia19 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia28 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia29 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia30 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia8 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia18 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia19 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia28 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia29 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia30 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia17 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia18 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia19 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia28 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia29 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia30 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia17 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia18 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia19 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia28 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia29 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia30 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia8 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia3 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia5 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia10 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia10 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia16 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia16 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia5 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"MultiMedia5 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"MultiMedia5 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"MultiMedia10 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"MultiMedia10 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"MultiMedia18 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia19 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia28 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia29 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia30 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia18 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia19 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia28 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia29 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia30 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"MI2S_RX", NULL, "MI2S_RX Audio Mixer"}, + {"CPE_LSM_UL_HL", NULL, "BE_IN"}, + {"QCHAT_Tx Mixer", "SLIM_0_TX_QCHAT", "SLIMBUS_0_TX"}, + {"QCHAT_Tx Mixer", "SLIM_7_TX_QCHAT", "SLIMBUS_7_TX"}, + {"QCHAT_Tx Mixer", "SLIM_8_TX_QCHAT", "SLIMBUS_8_TX"}, + {"QCHAT_Tx Mixer", "INTERNAL_BT_SCO_TX_QCHAT", "INT_BT_SCO_TX"}, + {"QCHAT_Tx Mixer", "AFE_PCM_TX_QCHAT", "PCM_TX"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUAT_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX Audio Mixer"}, + {"QCHAT_Tx Mixer", "USB_AUDIO_TX_QCHAT", "USB_AUDIO_TX"}, + {"QCHAT_UL", NULL, "QCHAT_Tx Mixer"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"TERT_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX Audio Mixer"}, + {"INT_FM_RX", NULL, "INTFM_DL_HL"}, + {"INTFM_UL_HL", NULL, "INT_FM_TX"}, + {"INTHFP_UL_HL", NULL, "HFP_INT_UL_HL"}, + {"HFP_INT_UL_HL", "Switch", "INT_BT_SCO_TX"}, + {"SLIM7_UL_HL", NULL, "HFP_SLIM7_UL_HL"}, + {"HFP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"}, + {"SLIM7_UL_HL", NULL, "A2DP_SLIM7_UL_HL"}, + {"A2DP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"}, + {"PCM_RX_DL_HL", "Switch", "SLIM0_DL_HL"}, + {"PCM_RX", NULL, "PCM_RX_DL_HL"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Audio Mixer"}, + /* connect to INT4_MI2S_DL_HL since same pcm_id */ + {"WSA_CDC_DMA_RX_0 Port Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"WSA_CDC_DMA_RX_0 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"WSA_CDC_DMA_RX_0 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0 Port Mixer"}, - {"SEC_MI2S_RX_SD1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_MI2S_RX_SD1", NULL, "SEC_MI2S_RX_SD1 Audio Mixer"}, + {"RX_CDC_DMA_RX_0 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"RX_CDC_DMA_RX_0 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0 Port Mixer"}, - {"SEC_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEC_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"RX_CDC_DMA_RX_1 Port Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, + {"RX_CDC_DMA_RX_1 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, + {"RX_CDC_DMA_RX_1 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1 Port Mixer"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Audio Mixer"}, - {"PRI_MI2S_RX Audio Mixer", "DTMF", "DTMF_DL_HL"}, + {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, + {"SLIMBUS_0_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"}, + {"AFE_PCM_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"AFE_PCM_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"PCM_RX", NULL, "AFE_PCM_RX Port Mixer"}, + {"USB_AUDIO_RX Port Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX Port Mixer"}, + {"USB_DL_HL", "Switch", "USBAUDIO_DL_HL"}, + {"USB_AUDIO_RX", NULL, "USB_DL_HL"}, + {"USBAUDIO_UL_HL", NULL, "USB_AUDIO_TX"}, + + {"Voice Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, + {"Voice Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"Voice Stub Tx Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"Voice Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"}, + + {"Voice Stub Tx Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"Voice Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"}, + {"Voice Stub Tx Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"Voice Stub Tx Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"Voice Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"VOICE_STUB_UL", NULL, "Voice Stub Tx Mixer"}, + + {"VoLTE Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, + {"VoLTE Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"VoLTE Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"}, + {"VoLTE Stub Tx Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"VoLTE Stub Tx Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"VoLTE Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"}, + {"VoLTE Stub Tx Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"VoLTE Stub Tx Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"VoLTE Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"VOLTE_STUB_UL", NULL, "VoLTE Stub Tx Mixer"}, + + {"Voice2 Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, + {"Voice2 Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"Voice2 Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"}, + {"Voice2 Stub Tx Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"Voice2 Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"}, + {"Voice2 Stub Tx Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"Voice2 Stub Tx Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"Voice2 Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"VOICE2_STUB_UL", NULL, "Voice2 Stub Tx Mixer"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"INT0_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX Audio Mixer"}, + {"STUB_RX Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"STUB_RX Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"STUB_RX", NULL, "STUB_RX Mixer"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"INT4_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX Audio Mixer"}, + {"SLIMBUS_1_RX Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIMBUS_1_RX Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Mixer"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUIN_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX Audio Mixer"}, + {"SLIMBUS_3_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIMBUS_3_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX_Voice Mixer"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEN_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX Audio Mixer"}, + {"SLIM_7_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SLIM_7_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SLIM_7_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SLIM_7_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIM_7_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SLIMBUS_7_RX", NULL, "SLIM_7_RX_Voice Mixer"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"PRI_META_MI2S_RX", NULL, "PRI_META_MI2S_RX Audio Mixer"}, + {"SLIM_8_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SLIM_8_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SLIM_8_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SLIM_8_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SLIM_8_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SLIMBUS_8_RX", NULL, "SLIM_8_RX_Voice Mixer"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, - {"SEC_META_MI2S_RX", NULL, "SEC_META_MI2S_RX Audio Mixer"}, + {"SLIMBUS_1_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SLIMBUS_1_RX Port Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Port Mixer"}, + {"INTERNAL_BT_SCO_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"INTERNAL_BT_SCO_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Port Mixer"}, + {"SLIMBUS_3_RX Port Mixer", "INTERNAL_BT_SCO_RX", "INT_BT_SCO_RX"}, + {"SLIMBUS_3_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"SLIMBUS_3_RX Port Mixer", "AFE_PCM_RX", "PCM_RX"}, + {"SLIMBUS_3_RX Port Mixer", "SLIM_0_RX", "SLIMBUS_0_RX"}, + {"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX Port Mixer"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Audio Mixer"}, + {"SLIMBUS_6_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Audio Mixer"}, + {"SLIMBUS_6_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SLIMBUS_6_RX", NULL, "SLIMBUS_6_RX Port Mixer"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Audio Mixer"}, + {"HDMI_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"HDMI", NULL, "HDMI_RX Port Mixer"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Audio Mixer"}, + {"HDMI_RX_MS Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"HDMI_MS", NULL, "HDMI_RX_MS Port Mixer"}, + + {"DISPLAY_PORT_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"DISPLAY_PORT", NULL, "DISPLAY_PORT_RX Port Mixer"}, + + {"DISPLAY_PORT_RX1 Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"DISPLAY_PORT1", NULL, "DISPLAY_PORT_RX1 Port Mixer"}, + + {"BE_OUT", NULL, "SLIMBUS_0_RX"}, + {"BE_OUT", NULL, "SLIMBUS_1_RX"}, + {"BE_OUT", NULL, "SLIMBUS_2_RX"}, + {"BE_OUT", NULL, "SLIMBUS_3_RX"}, + {"BE_OUT", NULL, "SLIMBUS_4_RX"}, + {"BE_OUT", NULL, "SLIMBUS_5_RX"}, + {"BE_OUT", NULL, "SLIMBUS_6_RX"}, + {"BE_OUT", NULL, "SLIMBUS_7_RX"}, + {"BE_OUT", NULL, "SLIMBUS_8_RX"}, + {"BE_OUT", NULL, "SLIMBUS_9_RX"}, + {"BE_OUT", NULL, "USB_AUDIO_RX"}, + {"BE_OUT", NULL, "HDMI"}, + {"BE_OUT", NULL, "HDMI_MS"}, + {"BE_OUT", NULL, "DISPLAY_PORT"}, + {"BE_OUT", NULL, "DISPLAY_PORT1"}, + {"BE_OUT", NULL, "PRI_SPDIF_RX"}, + {"BE_OUT", NULL, "SEC_SPDIF_RX"}, + {"BE_OUT", NULL, "INT_BT_SCO_RX"}, + {"BE_OUT", NULL, "INT_BT_A2DP_RX"}, + {"BE_OUT", NULL, "INT_FM_RX"}, + {"BE_OUT", NULL, "PCM_RX"}, + {"BE_OUT", NULL, "SLIMBUS_3_RX"}, + {"BE_OUT", NULL, "INT_BT_SCO_RX"}, + {"BE_OUT", NULL, "INT_FM_RX"}, + {"BE_OUT", NULL, "PCM_RX"}, + {"BE_OUT", NULL, "SLIMBUS_3_RX"}, + {"BE_OUT", NULL, "VOICE_PLAYBACK_TX"}, + {"BE_OUT", NULL, "VOICE2_PLAYBACK_TX"}, + {"BE_OUT", NULL, "WSA_CDC_DMA_RX_0"}, + {"BE_OUT", NULL, "WSA_CDC_DMA_RX_1"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_0"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_1"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_2"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_3"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_4"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_5"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_6"}, + {"BE_OUT", NULL, "RX_CDC_DMA_RX_7"}, + {"BE_OUT", NULL, "PROXY_RX"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"PRI_TDM_TX_0", NULL, "PRI_TDM_TX_0 Audio Mixer"}, + {"SLIMBUS_0_TX", NULL, "BE_IN" }, + {"SLIMBUS_1_TX", NULL, "BE_IN" }, + {"SLIMBUS_3_TX", NULL, "BE_IN" }, + {"SLIMBUS_4_TX", NULL, "BE_IN" }, + {"SLIMBUS_5_TX", NULL, "BE_IN" }, + {"SLIMBUS_6_TX", NULL, "BE_IN" }, + {"SLIMBUS_7_TX", NULL, "BE_IN" }, + {"SLIMBUS_8_TX", NULL, "BE_IN" }, + {"SLIMBUS_9_TX", NULL, "BE_IN" }, + {"USB_AUDIO_TX", NULL, "BE_IN" }, + {"INT_BT_SCO_TX", NULL, "BE_IN"}, + {"INT_FM_TX", NULL, "BE_IN"}, + {"PCM_TX", NULL, "BE_IN"}, + {"BE_OUT", NULL, "SLIMBUS_3_RX"}, + {"BE_OUT", NULL, "STUB_RX"}, + {"STUB_TX", NULL, "BE_IN"}, + {"STUB_1_TX", NULL, "BE_IN"}, + {"BE_OUT", NULL, "AUX_PCM_RX"}, + {"INCALL_RECORD_TX", NULL, "BE_IN"}, + {"INCALL_RECORD_RX", NULL, "BE_IN"}, + {"SLIM0_RX_VI_FB_LCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"}, + {"SLIM0_RX_VI_FB_RCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"}, + {"WSA_RX_0_VI_FB_LCH_MUX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"WSA_RX_0_VI_FB_RCH_MUX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_LCH_MUX"}, + {"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_RCH_MUX"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_RX_0_VI_FB_LCH_MUX"}, + {"WSA_CDC_DMA_RX_0", NULL, "WSA_RX_0_VI_FB_RCH_MUX"}, + {"WSA_CDC_DMA_TX_0", NULL, "BE_IN"}, + {"WSA_CDC_DMA_TX_1", NULL, "BE_IN"}, + {"WSA_CDC_DMA_TX_2", NULL, "BE_IN"}, + {"VA_CDC_DMA_TX_0", NULL, "BE_IN"}, + {"VA_CDC_DMA_TX_1", NULL, "BE_IN"}, + {"VA_CDC_DMA_TX_2", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_0", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_1", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_2", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_3", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_4", NULL, "BE_IN"}, + {"TX_CDC_DMA_TX_5", NULL, "BE_IN"}, + {"PRI_SPDIF_TX", NULL, "BE_IN"}, + {"SEC_SPDIF_TX", NULL, "BE_IN"}, + {"PROXY_TX", NULL, "BE_IN"}, +}; - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Audio Mixer"}, +#ifndef CONFIG_AUXPCM_DISABLE +static const struct snd_soc_dapm_route intercon_aux_pcm[] = { + /* incall */ + {"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"MultiMedia10 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia2 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia10 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia16 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, + {"MultiMedia16 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, + {"MultiMedia10 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia10 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia16 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "QUIN_AUX_PCM_TX", "QUIN_AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "QUIN_AUX_PCM_TX", "QUIN_AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "SEN_AUXPCM_UL_TX", "SEN_AUX_PCM_TX"}, + {"MultiMedia3 Mixer", "SEN_AUX_PCM_TX", "SEN_AUX_PCM_TX"}, + {"MultiMedia5 Mixer", "SEN_AUX_PCM_TX", "SEN_AUX_PCM_TX"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Audio Mixer"}, + {"MultiMedia21 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"MultiMedia21 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Audio Mixer"}, + {"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"MultiMedia6 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Audio Mixer"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"AUX_PCM_RX Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"SEC_TDM_TX_0", NULL, "SEC_TDM_TX_0 Audio Mixer"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX Audio Mixer"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Audio Mixer"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_AUX_PCM_RX", NULL, "TERT_AUX_PCM_RX Audio Mixer"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"TERT_TDM_TX_0", NULL, "TERT_TDM_TX_0 Audio Mixer"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUX_PCM_RX Audio Mixer"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Audio Mixer"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUX_PCM_RX Audio Mixer"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Audio Mixer"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_AUX_PCM_RX", NULL, "SEN_AUX_PCM_RX Audio Mixer"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Audio Mixer"}, + {"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"TERT_TDM_RX_4", NULL, "TERT_TDM_RX_4 Audio Mixer"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SEC_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX_Voice Mixer"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Audio Mixer"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"TERT_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"TERT_AUX_PCM_RX", NULL, "TERT_AUX_PCM_RX_Voice Mixer"}, + + {"QUAT_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUAT_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUX_PCM_RX_Voice Mixer"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUAT_TDM_TX_0", NULL, "QUAT_TDM_TX_0 Audio Mixer"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUIN_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUX_PCM_RX_Voice Mixer"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Audio Mixer"}, + {"SEN_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SEN_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SEN_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SEN_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SEN_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SEN_AUX_PCM_RX", NULL, "SEN_AUX_PCM_RX_Voice Mixer"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Audio Mixer"}, + {"VoiceMMode1_Tx Mixer", "AUX_PCM_TX_MMode1", "AUX_PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "SEC_AUX_PCM_TX_MMode1", "SEC_AUX_PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "TERT_AUX_PCM_TX_MMode1", "TERT_AUX_PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "QUAT_AUX_PCM_TX_MMode1", "QUAT_AUX_PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "QUIN_AUX_PCM_TX_MMode1", "QUIN_AUX_PCM_TX"}, + {"VoiceMMode1_Tx Mixer", "SEN_AUX_PCM_TX_MMode1", "SEN_AUX_PCM_TX"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Audio Mixer"}, + {"VoiceMMode2_Tx Mixer", "AUX_PCM_TX_MMode2", "AUX_PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "SEC_AUX_PCM_TX_MMode2", "SEC_AUX_PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "TERT_AUX_PCM_TX_MMode2", "TERT_AUX_PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "QUAT_AUX_PCM_TX_MMode2", "QUAT_AUX_PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "QUIN_AUX_PCM_TX_MMode2", "QUIN_AUX_PCM_TX"}, + {"VoiceMMode2_Tx Mixer", "SEN_AUX_PCM_TX_MMode2", "SEN_AUX_PCM_TX"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0 Audio Mixer"}, + {"Voip_Tx Mixer", "AUX_PCM_TX_Voip", "AUX_PCM_TX"}, + {"Voip_Tx Mixer", "SEC_AUX_PCM_TX_Voip", "SEC_AUX_PCM_TX"}, + {"Voip_Tx Mixer", "TERT_AUX_PCM_TX_Voip", "TERT_AUX_PCM_TX"}, + {"Voip_Tx Mixer", "QUAT_AUX_PCM_TX_Voip", "QUAT_AUX_PCM_TX"}, + {"Voip_Tx Mixer", "QUIN_AUX_PCM_TX_Voip", "QUIN_AUX_PCM_TX"}, + {"Voip_Tx Mixer", "SEN_AUX_PCM_TX_Voip", "SEN_AUX_PCM_TX"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUIN_TDM_TX_0", NULL, "QUIN_TDM_TX_0 Audio Mixer"}, + {"QCHAT_Tx Mixer", "AUX_PCM_TX_QCHAT", "AUX_PCM_TX"}, + {"QCHAT_Tx Mixer", "SEC_AUX_PCM_TX_QCHAT", "SEC_AUX_PCM_TX"}, + {"QCHAT_Tx Mixer", "TERT_AUX_PCM_TX_QCHAT", "TERT_AUX_PCM_TX"}, + {"QCHAT_Tx Mixer", "QUAT_AUX_PCM_TX_QCHAT", "QUAT_AUX_PCM_TX"}, + {"QCHAT_Tx Mixer", "QUIN_AUX_PCM_TX_QCHAT", "QUIN_AUX_PCM_TX"}, + {"QCHAT_Tx Mixer", "SEN_AUX_PCM_TX_QCHAT", "SEN_AUX_PCM_TX"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1 Audio Mixer"}, + {"Voice2 Stub Tx Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2 Audio Mixer"}, + /* connect to INT4_MI2S_DL_HL since same pcm_id */ - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, - {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, - {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Audio Mixer"}, + {"INTHFP_UL_HL", NULL, "HFP_PRI_AUX_UL_HL"}, + {"HFP_PRI_AUX_UL_HL", "Switch", "AUX_PCM_TX"}, + {"INTHFP_UL_HL", NULL, "HFP_AUX_UL_HL"}, + {"HFP_AUX_UL_HL", "Switch", "SEC_AUX_PCM_TX"}, + {"AUX_PCM_RX", NULL, "AUXPCM_DL_HL"}, + {"AUX_PCM_RX", NULL, "INTHFP_DL_HL"}, + {"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_DL_HL"}, + {"AUXPCM_UL_HL", NULL, "AUX_PCM_TX"}, + {"SEC_AUXPCM_UL_HL", NULL, "SEC_AUX_PCM_TX"}, + + {"AUX_PCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"AUX_PCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"AUX_PCM_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"AUX_PCM_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"AUX_PCM_RX Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"AUX_PCM_RX Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"AUX_PCM_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUX_PCM_RX", NULL, "AUX_PCM_RX Port Mixer"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEN_TDM_RX_0", NULL, "SEN_TDM_RX_0 Audio Mixer"}, + {"SEC_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_AUXPCM_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SEC_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"SEC_AUXPCM_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_RX Port Mixer"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEN_TDM_TX_0", NULL, "SEN_TDM_TX_0 Audio Mixer"}, + {"TERT_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"TERT_AUXPCM_RX Port Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, + {"TERT_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"TERT_AUX_PCM_RX", NULL, "TERT_AUXPCM_RX Port Mixer"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEN_TDM_RX_1", NULL, "SEN_TDM_RX_1 Audio Mixer"}, + {"QUAT_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUAT_AUXPCM_RX Port Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"QUAT_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUXPCM_RX Port Mixer"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEN_TDM_RX_2", NULL, "SEN_TDM_RX_2 Audio Mixer"}, + {"QUIN_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUIN_AUXPCM_RX Port Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, + {"QUIN_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUXPCM_RX Port Mixer"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, - {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEN_TDM_RX_3", NULL, "SEN_TDM_RX_3 Audio Mixer"}, + {"Voice Stub Tx Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "SEN_AUXPCM_UL_TX", "SEN_AUX_PCM_TX"}, - {"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"}, - {"MultiMedia1 Mixer", "MI2S_TX", "MI2S_TX"}, - {"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"}, - {"MultiMedia3 Mixer", "MI2S_TX", "MI2S_TX"}, - {"MultiMedia5 Mixer", "MI2S_TX", "MI2S_TX"}, - {"MultiMedia10 Mixer", "MI2S_TX", "MI2S_TX"}, - {"MultiMedia16 Mixer", "MI2S_TX", "MI2S_TX"}, - {"MultiMedia1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia1 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"MultiMedia2 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"MultiMedia1 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"MultiMedia2 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"MultiMedia1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia1 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, - {"MultiMedia2 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, - {"MultiMedia1 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia2 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia1 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"MultiMedia3 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, - {"MultiMedia5 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"MultiMedia10 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, - {"MultiMedia1 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia2 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia3 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia5 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia10 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia16 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, - {"MultiMedia16 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia1 Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, - {"MultiMedia3 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, - {"MultiMedia5 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, - {"MultiMedia10 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, - {"MultiMedia1 Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, - {"MultiMedia3 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, - {"MultiMedia5 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, - {"MultiMedia10 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, - {"MultiMedia16 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, - {"MultiMedia1 Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, - {"MultiMedia3 Mixer", "QUIN_AUX_PCM_TX", "QUIN_AUX_PCM_TX"}, - {"MultiMedia5 Mixer", "QUIN_AUX_PCM_TX", "QUIN_AUX_PCM_TX"}, - {"MultiMedia1 Mixer", "SEN_AUXPCM_UL_TX", "SEN_AUX_PCM_TX"}, - {"MultiMedia3 Mixer", "SEN_AUX_PCM_TX", "SEN_AUX_PCM_TX"}, - {"MultiMedia5 Mixer", "SEN_AUX_PCM_TX", "SEN_AUX_PCM_TX"}, - {"MultiMedia2 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia2 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, - {"MultiMedia2 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia2 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"MultiMedia1 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia1 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia2 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia6 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia6 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia6 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia10 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia6 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, - {"MultiMedia3 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, - {"MultiMedia5 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, - {"MultiMedia10 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, - {"MultiMedia16 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, - {"MultiMedia6 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia10 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia16 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia17 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia18 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia19 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia28 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia29 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia30 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"MultiMedia5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia6 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"MultiMedia6 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia6 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia6 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"MultiMedia5 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"MultiMedia6 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"MultiMedia5 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, + {"SLIMBUS_1_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SLIMBUS_3_RX Port Mixer", "AUX_PCM_RX", "AUX_PCM_RX"}, + {"SLIMBUS_6_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SLIMBUS_6_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + + /* Backend Enablement */ + {"BE_OUT", NULL, "AUX_PCM_RX"}, + {"BE_OUT", NULL, "SEC_AUX_PCM_RX"}, + {"BE_OUT", NULL, "TERT_AUX_PCM_RX"}, + {"BE_OUT", NULL, "QUAT_AUX_PCM_RX"}, + {"BE_OUT", NULL, "QUIN_AUX_PCM_RX"}, + {"BE_OUT", NULL, "SEN_AUX_PCM_RX"}, + + {"AUX_PCM_TX", NULL, "BE_IN"}, + {"SEC_AUX_PCM_TX", NULL, "BE_IN"}, + {"TERT_AUX_PCM_TX", NULL, "BE_IN"}, + {"QUAT_AUX_PCM_TX", NULL, "BE_IN"}, + {"QUIN_AUX_PCM_TX", NULL, "BE_IN"}, + {"SEN_AUX_PCM_TX", NULL, "BE_IN"}, +}; +#endif + +#ifndef CONFIG_TDM_DISABLE +static const struct snd_soc_dapm_route intercon_tdm[] = { + /* incall */ + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Audio Mixer"}, + + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Audio Mixer"}, - {"MultiMedia1 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia1 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia1 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia1 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia1 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia1 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia1 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia1 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia1 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia1 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia1 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia1 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia1 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia1 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia1 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia1 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia1 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia1 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia1 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia1 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia1 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia1 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia1 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia1 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia1 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia1 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia1 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia1 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia1 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Audio Mixer"}, - {"MultiMedia2 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia2 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia2 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia2 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia2 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia2 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia2 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia2 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia2 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia2 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia2 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia2 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia2 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia2 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia2 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia2 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia2 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia2 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia2 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia2 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia2 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia2 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia2 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia2 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia2 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia2 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia2 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia2 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia2 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Audio Mixer"}, - {"MultiMedia3 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia3 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia3 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia3 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia3 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia3 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia3 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia3 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia3 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia3 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia3 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia3 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia3 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia3 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia3 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia3 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia3 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia3 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia3 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia3 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia3 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia3 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia3 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia3 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia3 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia3 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia3 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia3 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia3 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"PRI_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"PRI_TDM_TX_0", NULL, "PRI_TDM_TX_0 Audio Mixer"}, + + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Audio Mixer"}, + + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Audio Mixer"}, + + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Audio Mixer"}, - {"MultiMedia4 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia4 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia4 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia4 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia4 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia4 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia4 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia4 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia4 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia4 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia4 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia4 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia4 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia4 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia4 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia4 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia4 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia4 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia4 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia4 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia4 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia4 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia4 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia4 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia4 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia4 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia4 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia4 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia4 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Audio Mixer"}, - {"MultiMedia5 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia5 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia5 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia5 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia5 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia5 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia5 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia5 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia5 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia5 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia5 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia5 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia5 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia5 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia5 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia5 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia5 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia5 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia5 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia5 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia5 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia5 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia5 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia5 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia5 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia5 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia5 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia5 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia5 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"SEC_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"SEC_TDM_TX_0", NULL, "SEC_TDM_TX_0 Audio Mixer"}, - {"MultiMedia6 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia6 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia6 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia6 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia6 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia6 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia6 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia6 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia6 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia6 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia6 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia6 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia6 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia6 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia6 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia6 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia6 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia6 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia6 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia6 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia6 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia6 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia6 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia6 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia6 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia6 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia6 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia6 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia6 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Audio Mixer"}, - {"MultiMedia8 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia8 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia8 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia8 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia8 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia8 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia8 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia8 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia8 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia8 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia8 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia8 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia8 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia8 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia8 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia8 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia8 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia8 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia8 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia8 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia8 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia8 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia8 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia8 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia8 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia8 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia8 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia8 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia8 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia8 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"TERT_TDM_TX_0", NULL, "TERT_TDM_TX_0 Audio Mixer"}, + + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Audio Mixer"}, - {"MultiMedia9 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia9 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia9 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia9 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia9 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia9 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia9 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia9 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia9 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia9 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia9 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia9 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia9 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia9 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia9 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia9 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia9 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia9 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia9 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia9 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia9 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia9 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia9 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Audio Mixer"}, - {"MultiMedia10 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia10 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia10 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia10 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia10 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia10 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia10 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia10 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia10 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia10 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Audio Mixer"}, - {"MultiMedia20 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia20 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia20 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia20 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia20 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"MultiMedia20 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"MultiMedia20 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia20 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia20 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia20 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia20 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia20 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia20 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia20 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia20 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia20 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia20 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia20 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia20 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia20 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia20 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia20 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia20 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia20 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia20 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia20 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia20 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia20 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia20 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia20 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia20 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia20 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia20 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia20 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia20 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia20 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"TERT_TDM_RX_4", NULL, "TERT_TDM_RX_4 Audio Mixer"}, - {"MultiMedia21 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"MultiMedia21 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia21 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia21 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia21 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia21 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia21 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia21 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia21 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia21 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia21 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia21 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia21 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia21 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia21 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia21 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia21 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia21 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia21 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia21 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia21 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia21 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"MultiMedia21 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"MultiMedia21 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"MultiMedia21 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"MultiMedia21 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia21 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia21 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia21 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia21 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia21 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia21 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Audio Mixer"}, + + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUAT_TDM_TX_0", NULL, "QUAT_TDM_TX_0 Audio Mixer"}, - {"MultiMedia22 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia22 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia22 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia22 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia22 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia22 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia22 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia22 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia22 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia22 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia22 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia22 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia22 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia22 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia22 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia22 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia22 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia22 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia22 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia22 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Audio Mixer"}, - {"MultiMedia23 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia23 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia23 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia23 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia23 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia23 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia23 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia23 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia23 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia23 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia23 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia23 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia23 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia23 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia23 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia23 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia23 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia23 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia23 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia23 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Audio Mixer"}, - {"MultiMedia24 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia24 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia24 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia24 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia24 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia24 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia24 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia24 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia24 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia24 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia24 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia24 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia24 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia24 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia24 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia24 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia24 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia24 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia24 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia24 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Audio Mixer"}, - {"MultiMedia25 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia25 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia25 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia25 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia25 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia25 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia25 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia25 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia25 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia25 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia25 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia25 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia25 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia25 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia25 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia25 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia25 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"MultiMedia25 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"MultiMedia25 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"MultiMedia25 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0 Audio Mixer"}, - {"MultiMedia27 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"MultiMedia27 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"MultiMedia27 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, - {"MultiMedia27 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"MultiMedia27 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"MultiMedia27 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"MultiMedia27 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"MultiMedia27 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"MultiMedia27 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"MultiMedia27 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"MultiMedia27 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"MultiMedia27 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia27 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia27 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUIN_TDM_TX_0", NULL, "QUIN_TDM_TX_0 Audio Mixer"}, + + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1 Audio Mixer"}, + + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUIN_TDM_RX_2 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2 Audio Mixer"}, - {"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"MultiMedia4 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"MultiMedia5 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"MultiMedia6 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"MultiMedia8 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"MultiMedia10 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia22", "MM_DL22"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia23", "MM_DL23"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia24", "MM_DL24"}, + {"QUIN_TDM_RX_3 Audio Mixer", "MultiMedia25", "MM_DL25"}, + {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Audio Mixer"}, - {"MultiMedia16 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"MultiMedia16 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"MultiMedia16 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"MultiMedia16 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"MultiMedia16 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"MultiMedia16 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"MultiMedia16 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"MultiMedia16 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"MultiMedia16 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"MultiMedia16 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"MultiMedia16 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"MultiMedia16 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"MultiMedia16 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"MultiMedia16 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"MultiMedia16 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"MultiMedia16 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia16 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_1"}, - {"MultiMedia16 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"}, - {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"MultiMedia16 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia16 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia16 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"}, - {"MultiMedia16 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"}, - {"MultiMedia16 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"SEN_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEN_TDM_RX_0", NULL, "SEN_TDM_RX_0 Audio Mixer"}, - {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia17 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia17 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_TDM_TX_0", NULL, "SEN_TDM_TX_0 Audio Mixer"}, - {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia18 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia18 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia18 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia18 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"SEN_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEN_TDM_RX_1", NULL, "SEN_TDM_RX_1 Audio Mixer"}, - {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia19 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia19 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia19 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia19 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"SEN_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEN_TDM_RX_2", NULL, "SEN_TDM_RX_2 Audio Mixer"}, - {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia28 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia28 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia28 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia28 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"}, + {"SEN_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"SEN_TDM_RX_3", NULL, "SEN_TDM_RX_3 Audio Mixer"}, - {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia29 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia29 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia29 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia29 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia1 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia1 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia1 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia1 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia1 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia1 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia1 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia1 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia1 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia1 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia1 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia1 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia1 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia1 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia1 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia1 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_0", "TX_CDC_DMA_TX_0"}, - {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_1", "TX_CDC_DMA_TX_1"}, - {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_2", "TX_CDC_DMA_TX_2"}, - {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_4", "TX_CDC_DMA_TX_4"}, - {"MultiMedia30 Mixer", "TX_CDC_DMA_TX_5", "TX_CDC_DMA_TX_5"}, - {"MultiMedia30 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"}, - {"MultiMedia30 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"MultiMedia30 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, + {"MultiMedia1 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia1 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia1 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia1 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia1 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia1 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia1 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia1 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + + {"MultiMedia2 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia2 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia2 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia2 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia2 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia2 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia2 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia2 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia2 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia2 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia2 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia2 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia2 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia2 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia2 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia2 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia2 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia2 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia2 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia2 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia2 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia2 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia2 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia2 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia6", "MM_UL6"}, - {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"}, + {"MultiMedia3 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia3 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia3 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia3 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia3 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia3 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia3 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia3 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia3 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia3 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia3 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia3 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia3 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia3 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia3 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia3 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia3 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia3 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia3 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia3 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia3 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia3 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia3 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia3 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"INTERNAL_A2DP_RX Audio Mixer", "MultiMedia6", "MM_UL6"}, - {"INT_BT_A2DP_RX", NULL, "INTERNAL_A2DP_RX Audio Mixer"}, + {"MultiMedia4 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia4 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia4 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia4 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia4 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia4 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia4 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia4 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia4 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia4 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia4 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia4 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia4 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia4 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia4 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia4 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia4 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia4 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia4 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia4 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia4 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia4 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia4 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia4 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"INTERNAL_FM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"}, + {"MultiMedia5 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia5 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia5 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia5 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia5 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia5 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia5 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia5 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia5 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia5 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia5 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia5 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia5 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia5 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia5 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia5 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia5 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia5 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia5 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia5 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia5 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia5 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia5 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia5 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"AFE_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"}, + {"MultiMedia6 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia6 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia6 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia6 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia6 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia6 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia6 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia6 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia6 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia6 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia6 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia6 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia6 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia6 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia6 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia6 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia6 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia6 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia6 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia6 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia6 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia6 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia6 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia6 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia3 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia4 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia10 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia17 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia18 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia19 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia28 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia29 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia30 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia5 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia8 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia16 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia4 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia16 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia17 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia18 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia19 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia28 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia29 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia30 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia5 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia6 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MultiMedia8 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia8 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia8 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia8 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia8 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia8 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia8 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia8 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia8 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia8 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia8 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia8 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia8 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia8 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia8 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia8 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia8 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia8 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia8 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia8 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia8 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia8 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia8 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia8 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia8 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia3 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia4 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia10 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia17 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia18 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia19 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia28 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia29 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia30 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia5 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia8 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MultiMedia16 Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"MM_UL1", NULL, "MultiMedia1 Mixer"}, - {"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"MM_UL2", NULL, "MultiMedia2 Mixer"}, - {"MM_UL3", NULL, "MultiMedia3 Mixer"}, - {"MM_UL4", NULL, "MultiMedia4 Mixer"}, - {"MM_UL5", NULL, "MultiMedia5 Mixer"}, - {"MM_UL6", NULL, "MultiMedia6 Mixer"}, - {"MM_UL8", NULL, "MultiMedia8 Mixer"}, - {"MM_UL9", NULL, "MultiMedia9 Mixer"}, - {"MM_UL10", NULL, "MultiMedia10 Mixer"}, - {"MM_UL16", NULL, "MultiMedia16 Mixer"}, - {"MM_UL17", NULL, "MultiMedia17 Mixer"}, - {"MM_UL18", NULL, "MultiMedia18 Mixer"}, - {"MM_UL19", NULL, "MultiMedia19 Mixer"}, - {"MM_UL20", NULL, "MultiMedia20 Mixer"}, - {"MM_UL21", NULL, "MultiMedia21 Mixer"}, - {"MM_UL22", NULL, "MultiMedia22 Mixer"}, - {"MM_UL23", NULL, "MultiMedia23 Mixer"}, - {"MM_UL24", NULL, "MultiMedia24 Mixer"}, - {"MM_UL25", NULL, "MultiMedia25 Mixer"}, - {"MM_UL27", NULL, "MultiMedia27 Mixer"}, - {"MM_UL28", NULL, "MultiMedia28 Mixer"}, - {"MM_UL29", NULL, "MultiMedia29 Mixer"}, - {"MM_UL30", NULL, "MultiMedia30 Mixer"}, + {"MultiMedia9 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia9 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia9 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia9 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia9 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia9 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia9 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia9 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia9 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia9 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia9 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia9 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia9 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia9 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia9 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia9 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"AUX_PCM_RX Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"}, + {"MultiMedia10 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia10 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia10 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia10 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia10 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia10 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia10 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia10 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia21", "MM_DL21"}, - {"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX Audio Mixer"}, + {"MultiMedia20 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia20 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia20 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia20 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia20 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia20 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia20 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia20 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia20 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia20 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia20 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia20 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia20 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia20 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia20 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia20 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia20 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia20 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia20 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia20 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia20 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia20 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia20 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia20 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"TERT_AUX_PCM_RX", NULL, "TERT_AUX_PCM_RX Audio Mixer"}, + {"MultiMedia21 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia21 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia21 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia21 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia21 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia21 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia21 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia21 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia21 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia21 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia21 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia21 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia21 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia21 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia21 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia21 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia21 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia21 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia21 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia21 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"MultiMedia21 Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"MultiMedia21 Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"MultiMedia21 Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"MultiMedia21 Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUAT_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUX_PCM_RX Audio Mixer"}, + {"MultiMedia22 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia22 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia22 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia22 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia22 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia22 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia22 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia22 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia22 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia22 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia22 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia22 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia22 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia22 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia22 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia22 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia22 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia22 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia22 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia22 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"QUIN_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUX_PCM_RX Audio Mixer"}, + {"MultiMedia23 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia23 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia23 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia23 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia23 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia23 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia23 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia23 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia23 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia23 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia23 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia23 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia23 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia23 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia23 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia23 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia23 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia23 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia23 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia23 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, - {"SEN_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, - {"SEN_AUX_PCM_RX", NULL, "SEN_AUX_PCM_RX Audio Mixer"}, + {"MultiMedia24 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia24 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia24 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia24 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia24 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia24 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia24 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia24 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia24 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia24 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia24 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia24 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia24 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia24 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia24 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia24 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia24 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia24 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia24 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia24 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"PRI_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"PRI_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"PRI_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"}, + {"MultiMedia25 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia25 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia25 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia25 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia25 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia25 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia25 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia25 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia25 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia25 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia25 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia25 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia25 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia25 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia25 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia25 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia25 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"MultiMedia25 Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"MultiMedia25 Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"MultiMedia25 Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SEC_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SEC_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"}, + {"MultiMedia16 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"MultiMedia16 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"MultiMedia16 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"MultiMedia16 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"MultiMedia16 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"MultiMedia16 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"MultiMedia16 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"MultiMedia16 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"MultiMedia16 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia16 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia16 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia16 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia16 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia16 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia16 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia16 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEC_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SEC_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"SEC_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"SEC_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SEC_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SEC_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SEC_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX_Voice Mixer"}, + {"PRI_TDM_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_TDM_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_TDM_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0_Voice Mixer"}, - {"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SLIM_0_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SLIM_0_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SLIM_0_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SLIM_0_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"}, + {"PRI_TDM_RX_1_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_TDM_RX_1_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_TDM_RX_1_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1_Voice Mixer"}, - {"SLIM_6_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SLIM_6_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SLIM_6_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SLIM_6_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SLIM_6_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SLIMBUS_6_RX", NULL, "SLIM_6_RX_Voice Mixer"}, + {"PRI_TDM_RX_2_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_TDM_RX_2_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2_Voice Mixer"}, - {"USB_AUDIO_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"USB_AUDIO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"USB_AUDIO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"USB_AUDIO_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"USB_AUDIO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX_Voice Mixer"}, + {"PRI_TDM_RX_3_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_TDM_RX_3_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_TDM_RX_3_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3_Voice Mixer"}, - {"DISPLAY_PORT_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"DISPLAY_PORT_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"DISPLAY_PORT_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"DISPLAY_PORT_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"DISPLAY_PORT_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"DISPLAY_PORT", NULL, "DISPLAY_PORT_RX_Voice Mixer"}, + {"QUAT_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_Voice Mixer"}, - {"DISPLAY_PORT_RX1_Voice Mixer", "Voip", "VOIP_DL"}, - {"DISPLAY_PORT_RX1_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"DISPLAY_PORT_RX1_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"DISPLAY_PORT_RX1_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"DISPLAY_PORT_RX1_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"DISPLAY_PORT1", NULL, "DISPLAY_PORT_RX1_Voice Mixer"}, + {"QUIN_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2_Voice Mixer"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"}, + {"VoiceMMode1_Tx Mixer", "QUAT_TDM_TX_0_MMode1", "QUAT_TDM_TX_0"}, + {"VoiceMMode2_Tx Mixer", "PRI_TDM_TX_3_MMode2", "PRI_TDM_TX_3"}, + {"VoiceMMode1_Tx Mixer", "PRI_TDM_TX_3_MMode1", "PRI_TDM_TX_3"}, - {"AFE_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"AFE_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"AFE_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"AFE_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"AFE_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"PCM_RX", NULL, "AFE_PCM_RX_Voice Mixer"}, + {"VOC_EXT_EC MUX", "PRI_TDM_TX", "PRI_TDM_TX_0"}, + {"VOC_EXT_EC MUX", "SEC_TDM_TX", "SEC_TDM_TX_0"}, - {"AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"AUX_PCM_RX", NULL, "AUX_PCM_RX_Voice Mixer"}, + {"PRI_TDM_TX_0_UL_HL", NULL, "PRI_TDM_TX_0"}, + {"PRI_TDM_TX_1_UL_HL", NULL, "PRI_TDM_TX_1"}, + {"PRI_TDM_TX_2_UL_HL", NULL, "PRI_TDM_TX_2"}, + {"PRI_TDM_TX_3_UL_HL", NULL, "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0_DL_HL"}, + {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1_DL_HL"}, + {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2_DL_HL"}, + {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3_DL_HL"}, + {"SEC_TDM_TX_0_UL_HL", NULL, "SEC_TDM_TX_0"}, + {"SEC_TDM_TX_1_UL_HL", NULL, "SEC_TDM_TX_1"}, + {"SEC_TDM_TX_2_UL_HL", NULL, "SEC_TDM_TX_2"}, + {"SEC_TDM_TX_3_UL_HL", NULL, "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0_DL_HL"}, + {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1_DL_HL"}, + {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2_DL_HL"}, + {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3_DL_HL"}, + {"SEC_TDM_RX_7", NULL, "SEC_TDM_RX_7_DL_HL"}, + {"TERT_TDM_TX_0_UL_HL", NULL, "TERT_TDM_TX_0"}, + {"TERT_TDM_TX_1_UL_HL", NULL, "TERT_TDM_TX_1"}, + {"TERT_TDM_TX_2_UL_HL", NULL, "TERT_TDM_TX_2"}, + {"TERT_TDM_TX_3_UL_HL", NULL, "TERT_TDM_TX_3"}, + {"TERT_TDM_TX_7_UL_HL", NULL, "TERT_TDM_TX_7"}, + {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0_DL_HL"}, + {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1_DL_HL"}, + {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2_DL_HL"}, + {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3_DL_HL"}, + {"QUAT_TDM_TX_0_UL_HL", NULL, "QUAT_TDM_TX_0"}, + {"QUAT_TDM_TX_1_UL_HL", NULL, "QUAT_TDM_TX_1"}, + {"QUAT_TDM_TX_2_UL_HL", NULL, "QUAT_TDM_TX_2"}, + {"QUAT_TDM_TX_3_UL_HL", NULL, "QUAT_TDM_TX_3"}, + {"QUAT_TDM_TX_7_UL_HL", NULL, "QUAT_TDM_TX_7"}, + {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0_DL_HL"}, + {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1_DL_HL"}, + {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_DL_HL"}, + {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3_DL_HL"}, + {"QUAT_TDM_RX_7", NULL, "QUAT_TDM_RX_7_DL_HL"}, + {"QUIN_TDM_TX_0_UL_HL", NULL, "QUIN_TDM_TX_0"}, + {"QUIN_TDM_TX_1_UL_HL", NULL, "QUIN_TDM_TX_1"}, + {"QUIN_TDM_TX_2_UL_HL", NULL, "QUIN_TDM_TX_2"}, + {"QUIN_TDM_TX_3_UL_HL", NULL, "QUIN_TDM_TX_3"}, + {"QUIN_TDM_TX_7_UL_HL", NULL, "QUIN_TDM_TX_7"}, + {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0_DL_HL"}, + {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1_DL_HL"}, + {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2_DL_HL"}, + {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3_DL_HL"}, + {"QUIN_TDM_RX_7", NULL, "QUIN_TDM_RX_7_DL_HL"}, + {"SEN_TDM_TX_0_UL_HL", NULL, "SEN_TDM_TX_0"}, + {"SEN_TDM_TX_1_UL_HL", NULL, "SEN_TDM_TX_1"}, + {"SEN_TDM_TX_2_UL_HL", NULL, "SEN_TDM_TX_2"}, + {"SEN_TDM_TX_3_UL_HL", NULL, "SEN_TDM_TX_3"}, + {"SEN_TDM_RX_0", NULL, "SEN_TDM_RX_0_DL_HL"}, + {"SEN_TDM_RX_1", NULL, "SEN_TDM_RX_1_DL_HL"}, + {"SEN_TDM_RX_2", NULL, "SEN_TDM_RX_2_DL_HL"}, + {"SEN_TDM_RX_3", NULL, "SEN_TDM_RX_3_DL_HL"}, - {"SEC_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SEC_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SEC_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SEC_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SEC_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX_Voice Mixer"}, + #ifndef CONFIG_MI2S_DISABLE + {"PRI_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"PRI_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"PRI_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"PRI_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Port Mixer"}, - {"TERT_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"TERT_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"TERT_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"TERT_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"TERT_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"TERT_AUX_PCM_RX", NULL, "TERT_AUX_PCM_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"PRI_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"PRI_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"PRI_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"PRI_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Port Mixer"}, + +#ifndef CONFIG_MI2S_DISABLE + {"PRI_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"PRI_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"PRI_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"PRI_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Port Mixer"}, - {"QUAT_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"QUAT_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"QUAT_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"QUAT_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"QUAT_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUX_PCM_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"PRI_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"PRI_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"PRI_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"PRI_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, + {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, + {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, + {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Port Mixer"}, - {"QUIN_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"QUIN_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"QUIN_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"QUIN_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"QUIN_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUX_PCM_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"SEC_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"SEC_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"SEC_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Port Mixer"}, - {"SEN_AUX_PCM_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SEN_AUX_PCM_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SEN_AUX_PCM_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SEN_AUX_PCM_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SEN_AUX_PCM_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SEN_AUX_PCM_RX", NULL, "SEN_AUX_PCM_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"SEC_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"SEC_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"SEC_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Port Mixer"}, - {"HDMI_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"HDMI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"HDMI_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"HDMI_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"HDMI_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"HDMI", NULL, "HDMI_RX_Voice Mixer"}, - {"HDMI", NULL, "HDMI_DL_HL"}, +#ifndef CONFIG_MI2S_DISABLE + {"SEC_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"SEC_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"SEC_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Port Mixer"}, - {"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"SEC_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"SEC_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"SEC_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, + {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Port Mixer"}, - {"PRI_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"PRI_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"PRI_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"PRI_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"PRI_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"PRI_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_Voice Mixer"}, + {"SEC_TDM_RX_7 Port Mixer", "TERT_TDM_TX_7", "TERT_TDM_TX_7"}, + {"SEC_TDM_RX_7", NULL, "SEC_TDM_RX_7 Port Mixer"}, - {"INT0_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"INT0_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"INT0_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"INT0_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"INT0_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"TERT_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"TERT_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"TERT_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"TERT_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Port Mixer"}, - {"INT4_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"INT4_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"INT4_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"INT4_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"INT4_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"TERT_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"TERT_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"TERT_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"TERT_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Port Mixer"}, - {"TERT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"TERT_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"TERT_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"TERT_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"TERT_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"TERT_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"TERT_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX_Voice Mixer"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"TERT_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"TERT_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"TERT_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"TERT_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Port Mixer"}, - {"QUAT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"QUAT_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"QUAT_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"QUAT_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"QUAT_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"QUAT_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"TERT_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, +#endif + {"TERT_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"TERT_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"TERT_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Port Mixer"}, - {"QUIN_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"QUIN_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"QUIN_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"QUIN_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"QUIN_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"QUIN_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"QUAT_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"QUAT_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"QUAT_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Port Mixer"}, - {"PRI_TDM_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_TDM_RX_0_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, - {"PRI_TDM_RX_0_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"PRI_TDM_RX_0_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"PRI_TDM_RX_0_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"PRI_TDM_RX_0_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"PRI_TDM_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"PRI_TDM_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"QUAT_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"QUAT_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"QUAT_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Port Mixer"}, - {"PRI_TDM_RX_1_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_TDM_RX_1_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, - {"PRI_TDM_RX_1_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"PRI_TDM_RX_1_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"PRI_TDM_RX_1_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"PRI_TDM_RX_1_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"PRI_TDM_RX_1_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"PRI_TDM_RX_1_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"QUAT_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"QUAT_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"QUAT_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Port Mixer"}, - {"PRI_TDM_RX_2_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_TDM_RX_2_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, - {"PRI_TDM_RX_2_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"PRI_TDM_RX_2_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"PRI_TDM_RX_2_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"PRI_TDM_RX_2_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"PRI_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"PRI_TDM_RX_2_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"QUAT_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"QUAT_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"QUAT_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Port Mixer"}, - {"PRI_TDM_RX_3_Voice Mixer", "Voip", "VOIP_DL"}, - {"PRI_TDM_RX_3_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, - {"PRI_TDM_RX_3_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"PRI_TDM_RX_3_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, - {"PRI_TDM_RX_3_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"PRI_TDM_RX_3_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"PRI_TDM_RX_3_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"PRI_TDM_RX_3_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3_Voice Mixer"}, + {"QUAT_TDM_RX_7 Port Mixer", "QUAT_TDM_TX_7", "QUAT_TDM_TX_7"}, + {"QUAT_TDM_RX_7 Port Mixer", "QUIN_TDM_TX_7", "QUIN_TDM_TX_7"}, + {"QUAT_TDM_RX_7", NULL, "QUAT_TDM_RX_7 Port Mixer"}, - {"SEN_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SEN_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SEN_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SEN_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"QUIN_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"QUIN_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"QUIN_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0 Port Mixer"}, - {"QUAT_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"QUIN_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"QUIN_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"QUIN_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1 Port Mixer"}, - {"QUIN_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"QUIN_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"QUIN_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"QUIN_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2 Port Mixer"}, - {"WSA_CDC_DMA_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, - {"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"QUIN_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"QUIN_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"QUIN_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, + {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Port Mixer"}, - {"PROXY_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"PROXY_RX", NULL, "PROXY_RX_Voice Mixer"}, + {"QUIN_TDM_RX_7 Port Mixer", "TERT_TDM_TX_7", "TERT_TDM_TX_7"}, + {"QUIN_TDM_RX_7 Port Mixer", "QUAT_TDM_TX_7", "QUAT_TDM_TX_7"}, + {"QUIN_TDM_RX_7 Port Mixer", "QUIN_TDM_TX_7", "QUIN_TDM_TX_7"}, + {"QUIN_TDM_RX_7", NULL, "QUIN_TDM_RX_7 Port Mixer"}, - {"PROXY_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"PROXY_RX", NULL, "PROXY_RX_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"SEN_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"SEN_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"SEN_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEN_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEN_TDM_RX_0", NULL, "SEN_TDM_RX_0 Port Mixer"}, - {"RX_CDC_DMA_RX_0_Voice Mixer", "Voip", "VOIP_DL"}, - {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"RX_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"SEN_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"SEN_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"SEN_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEN_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEN_TDM_RX_1", NULL, "SEN_TDM_RX_1 Port Mixer"}, - {"RX_CDC_DMA_RX_1_Voice Mixer", "Voip", "VOIP_DL"}, - {"RX_CDC_DMA_RX_1_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"RX_CDC_DMA_RX_1_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1_Voice Mixer"}, +#ifndef CONFIG_MI2S_DISABLE + {"SEN_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"SEN_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"SEN_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEN_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEN_TDM_RX_2", NULL, "SEN_TDM_RX_2 Port Mixer"}, - {"VOC_EXT_EC MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"VOC_EXT_EC MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"VOC_EXT_EC MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"VOC_EXT_EC MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"VOC_EXT_EC MUX", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"VOC_EXT_EC MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"VOC_EXT_EC MUX", "PRI_TDM_TX", "PRI_TDM_TX_0"}, - {"VOC_EXT_EC MUX", "SEC_TDM_TX", "SEC_TDM_TX_0"}, - {"VOIP_UL", NULL, "VOC_EXT_EC MUX"}, - {"VOICEMMODE1_UL", NULL, "VOC_EXT_EC MUX"}, - {"VOICEMMODE2_UL", NULL, "VOC_EXT_EC MUX"}, +#ifndef CONFIG_MI2S_DISABLE + {"SEN_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, +#endif + {"SEN_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE + {"SEN_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SEN_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif + {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, + {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, + {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, + {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, + {"SEN_TDM_RX_3", NULL, "SEN_TDM_RX_3 Port Mixer"}, - {"AUDIO_REF_EC_UL1 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL1 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL1 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL1 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"AUDIO_REF_EC_UL1 MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_0", "QUAT_TDM_RX_0"}, {"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_1", "QUAT_TDM_RX_1"}, - {"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_2", "QUAT_TDM_RX_2"}, - {"AUDIO_REF_EC_UL1 MUX", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"AUDIO_REF_EC_UL1 MUX", "TERT_TDM_RX_2", "TERT_TDM_RX_2"}, - {"AUDIO_REF_EC_UL1 MUX", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"AUDIO_REF_EC_UL1 MUX", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - - {"AUDIO_REF_EC_UL2 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL2 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL2 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL2 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL3 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL3 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL3 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL3 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL4 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL4 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL4 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL4 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL5 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL5 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL5 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL5 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL6 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL6 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL6 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL6 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL8 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL8 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL8 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL8 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL9 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL9 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL9 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL9 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_2", "QUAT_TDM_RX_2"}, + {"AUDIO_REF_EC_UL1 MUX", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"AUDIO_REF_EC_UL1 MUX", "TERT_TDM_RX_2", "TERT_TDM_RX_2"}, + {"AUDIO_REF_EC_UL1 MUX", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, + {"AUDIO_REF_EC_UL1 MUX", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"AUDIO_REF_EC_UL10 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL10 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL10 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL10 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"AUDIO_REF_EC_UL10 MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_0", "QUAT_TDM_RX_0"}, {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_1", "QUAT_TDM_RX_1"}, @@ -28128,1103 +29243,645 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUDIO_REF_EC_UL10 MUX", "TERT_TDM_RX_2", "TERT_TDM_RX_2"}, {"AUDIO_REF_EC_UL10 MUX", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"AUDIO_REF_EC_UL16 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL16 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL16 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL16 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL17 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL17 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL17 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL17 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL18 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL18 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL18 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL18 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL19 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL19 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL19 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL19 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL28 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL28 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL28 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL28 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"AUDIO_REF_EC_UL29 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"AUDIO_REF_EC_UL29 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUDIO_REF_EC_UL29 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"AUDIO_REF_EC_UL29 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - - {"LSM1_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"LSM2_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"LSM3_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"LSM4_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"LSM5_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"LSM6_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"LSM7_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"LSM8_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"}, - - {"MM_UL1", NULL, "AUDIO_REF_EC_UL1 MUX"}, - {"MM_UL2", NULL, "AUDIO_REF_EC_UL2 MUX"}, - {"MM_UL3", NULL, "AUDIO_REF_EC_UL3 MUX"}, - {"MM_UL4", NULL, "AUDIO_REF_EC_UL4 MUX"}, - {"MM_UL5", NULL, "AUDIO_REF_EC_UL5 MUX"}, - {"MM_UL6", NULL, "AUDIO_REF_EC_UL6 MUX"}, - {"MM_UL8", NULL, "AUDIO_REF_EC_UL8 MUX"}, - {"MM_UL9", NULL, "AUDIO_REF_EC_UL9 MUX"}, - {"MM_UL10", NULL, "AUDIO_REF_EC_UL10 MUX"}, - {"MM_UL16", NULL, "AUDIO_REF_EC_UL16 MUX"}, - {"MM_UL17", NULL, "AUDIO_REF_EC_UL17 MUX"}, - {"MM_UL18", NULL, "AUDIO_REF_EC_UL18 MUX"}, - {"MM_UL19", NULL, "AUDIO_REF_EC_UL19 MUX"}, - {"MM_UL28", NULL, "AUDIO_REF_EC_UL28 MUX"}, - {"MM_UL29", NULL, "AUDIO_REF_EC_UL29 MUX"}, - {"MM_UL30", NULL, "AUDIO_REF_EC_UL30 MUX"}, - - {"VoiceMMode1_Tx Mixer", "PRI_TX_MMode1", "PRI_I2S_TX"}, - {"VoiceMMode1_Tx Mixer", "PRI_MI2S_TX_MMode1", "PRI_MI2S_TX"}, - {"VoiceMMode1_Tx Mixer", "MI2S_TX_MMode1", "MI2S_TX"}, - {"VoiceMMode1_Tx Mixer", "SEC_MI2S_TX_MMode1", "SEC_MI2S_TX"}, - {"VoiceMMode1_Tx Mixer", "TERT_MI2S_TX_MMode1", "TERT_MI2S_TX"}, - {"VoiceMMode1_Tx Mixer", "INT3_MI2S_TX_MMode1", "INT3_MI2S_TX"}, - {"VoiceMMode1_Tx Mixer", "SLIM_0_TX_MMode1", "SLIMBUS_0_TX"}, - {"VoiceMMode1_Tx Mixer", "SLIM_7_TX_MMode1", "SLIMBUS_7_TX"}, - {"VoiceMMode1_Tx Mixer", "SLIM_8_TX_MMode1", "SLIMBUS_8_TX"}, - {"VoiceMMode1_Tx Mixer", "USB_AUDIO_TX_MMode1", "USB_AUDIO_TX"}, - {"VoiceMMode1_Tx Mixer", "INT_BT_SCO_TX_MMode1", "INT_BT_SCO_TX"}, - {"VoiceMMode1_Tx Mixer", "AFE_PCM_TX_MMode1", "PCM_TX"}, - {"VoiceMMode1_Tx Mixer", "AUX_PCM_TX_MMode1", "AUX_PCM_TX"}, - {"VoiceMMode1_Tx Mixer", "SEC_AUX_PCM_TX_MMode1", "SEC_AUX_PCM_TX"}, - {"VoiceMMode1_Tx Mixer", "TERT_AUX_PCM_TX_MMode1", "TERT_AUX_PCM_TX"}, - {"VoiceMMode1_Tx Mixer", "QUAT_AUX_PCM_TX_MMode1", "QUAT_AUX_PCM_TX"}, - {"VoiceMMode1_Tx Mixer", "QUIN_AUX_PCM_TX_MMode1", "QUIN_AUX_PCM_TX"}, - {"VoiceMMode1_Tx Mixer", "SEN_AUX_PCM_TX_MMode1", "SEN_AUX_PCM_TX"}, - {"VoiceMMode1_Tx Mixer", "QUAT_TDM_TX_0_MMode1", "QUAT_TDM_TX_0"}, - {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_0_MMode1", "TX_CDC_DMA_TX_0"}, - {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_1_MMode1", "TX_CDC_DMA_TX_1"}, - {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_2_MMode1", "TX_CDC_DMA_TX_2"}, - {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_3_MMode1", "TX_CDC_DMA_TX_3"}, - {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_4_MMode1", "TX_CDC_DMA_TX_4"}, - {"VoiceMMode1_Tx Mixer", "TX_CDC_DMA_TX_5_MMode1", "TX_CDC_DMA_TX_5"}, - {"VoiceMMode1_Tx Mixer", "QUAT_MI2S_TX_MMode1", "QUAT_MI2S_TX"}, - {"VoiceMMode1_Tx Mixer", "QUIN_MI2S_TX_MMode1", "QUIN_MI2S_TX"}, - {"VoiceMMode1_Tx Mixer", "PRI_TDM_TX_3_MMode1", "PRI_TDM_TX_3"}, - {"VoiceMMode1_Tx Mixer", "PROXY_TX_MMode1", "PROXY_TX"}, - {"VOICEMMODE1_UL", NULL, "VoiceMMode1_Tx Mixer"}, + {"LSM1 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM1 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"LSM2 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM2 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"LSM3 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM3 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"LSM4 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM4 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"LSM5 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM5 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"LSM6 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM6 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"LSM7 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM7 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"LSM8 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, + {"LSM8 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"VoiceMMode2_Tx Mixer", "PRI_TX_MMode2", "PRI_I2S_TX"}, - {"VoiceMMode2_Tx Mixer", "PRI_MI2S_TX_MMode2", "PRI_MI2S_TX"}, - {"VoiceMMode2_Tx Mixer", "SEC_MI2S_TX_MMode2", "SEC_MI2S_TX"}, - {"VoiceMMode2_Tx Mixer", "MI2S_TX_MMode2", "MI2S_TX"}, - {"VoiceMMode2_Tx Mixer", "TERT_MI2S_TX_MMode2", "TERT_MI2S_TX"}, - {"VoiceMMode2_Tx Mixer", "INT3_MI2S_TX_MMode2", "INT3_MI2S_TX"}, - {"VoiceMMode2_Tx Mixer", "SLIM_0_TX_MMode2", "SLIMBUS_0_TX"}, - {"VoiceMMode2_Tx Mixer", "SLIM_7_TX_MMode2", "SLIMBUS_7_TX"}, - {"VoiceMMode2_Tx Mixer", "SLIM_8_TX_MMode2", "SLIMBUS_8_TX"}, - {"VoiceMMode2_Tx Mixer", "USB_AUDIO_TX_MMode2", "USB_AUDIO_TX"}, - {"VoiceMMode2_Tx Mixer", "INT_BT_SCO_TX_MMode2", "INT_BT_SCO_TX"}, - {"VoiceMMode2_Tx Mixer", "AFE_PCM_TX_MMode2", "PCM_TX"}, - {"VoiceMMode2_Tx Mixer", "AUX_PCM_TX_MMode2", "AUX_PCM_TX"}, - {"VoiceMMode2_Tx Mixer", "SEC_AUX_PCM_TX_MMode2", "SEC_AUX_PCM_TX"}, - {"VoiceMMode2_Tx Mixer", "TERT_AUX_PCM_TX_MMode2", "TERT_AUX_PCM_TX"}, - {"VoiceMMode2_Tx Mixer", "QUAT_AUX_PCM_TX_MMode2", "QUAT_AUX_PCM_TX"}, - {"VoiceMMode2_Tx Mixer", "QUIN_AUX_PCM_TX_MMode2", "QUIN_AUX_PCM_TX"}, - {"VoiceMMode2_Tx Mixer", "SEN_AUX_PCM_TX_MMode2", "SEN_AUX_PCM_TX"}, - {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_0_MMode2", "TX_CDC_DMA_TX_0"}, - {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_1_MMode2", "TX_CDC_DMA_TX_1"}, - {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_2_MMode2", "TX_CDC_DMA_TX_2"}, - {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_3_MMode2", "TX_CDC_DMA_TX_3"}, - {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_4_MMode2", "TX_CDC_DMA_TX_4"}, - {"VoiceMMode2_Tx Mixer", "TX_CDC_DMA_TX_5_MMode2", "TX_CDC_DMA_TX_5"}, - {"VoiceMMode2_Tx Mixer", "QUAT_MI2S_TX_MMode2", "QUAT_MI2S_TX"}, - {"VoiceMMode2_Tx Mixer", "QUIN_MI2S_TX_MMode2", "QUIN_MI2S_TX"}, - {"VoiceMMode2_Tx Mixer", "PRI_TDM_TX_3_MMode2", "PRI_TDM_TX_3"}, - {"VoiceMMode2_Tx Mixer", "PROXY_TX_MMode2", "PROXY_TX"}, - {"VOICEMMODE2_UL", NULL, "VoiceMMode2_Tx Mixer"}, + {"SLIMBUS_0_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "SEN_AUXPCM_UL_TX", "SEN_AUX_PCM_TX"}, - {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"}, - {"Voip_Tx Mixer", "MI2S_TX_Voip", "MI2S_TX"}, - {"Voip_Tx Mixer", "SEC_MI2S_TX_Voip", "SEC_MI2S_TX"}, - {"Voip_Tx Mixer", "TERT_MI2S_TX_Voip", "TERT_MI2S_TX"}, - {"Voip_Tx Mixer", "INT3_MI2S_TX_Voip", "INT3_MI2S_TX"}, - {"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"}, - {"Voip_Tx Mixer", "SLIM_7_TX_Voip", "SLIMBUS_7_TX"}, - {"Voip_Tx Mixer", "SLIM_8_TX_Voip", "SLIMBUS_8_TX"}, - {"Voip_Tx Mixer", "USB_AUDIO_TX_Voip", "USB_AUDIO_TX"}, - {"Voip_Tx Mixer", "INTERNAL_BT_SCO_TX_Voip", "INT_BT_SCO_TX"}, - {"Voip_Tx Mixer", "AFE_PCM_TX_Voip", "PCM_TX"}, - {"Voip_Tx Mixer", "AUX_PCM_TX_Voip", "AUX_PCM_TX"}, - {"Voip_Tx Mixer", "SEC_AUX_PCM_TX_Voip", "SEC_AUX_PCM_TX"}, - {"Voip_Tx Mixer", "TERT_AUX_PCM_TX_Voip", "TERT_AUX_PCM_TX"}, - {"Voip_Tx Mixer", "QUAT_AUX_PCM_TX_Voip", "QUAT_AUX_PCM_TX"}, - {"Voip_Tx Mixer", "QUIN_AUX_PCM_TX_Voip", "QUIN_AUX_PCM_TX"}, - {"Voip_Tx Mixer", "SEN_AUX_PCM_TX_Voip", "SEN_AUX_PCM_TX"}, - {"Voip_Tx Mixer", "PRI_MI2S_TX_Voip", "PRI_MI2S_TX"}, - {"Voip_Tx Mixer", "PRI_TDM_TX_3_Voip", "PRI_TDM_TX_3"}, - {"Voip_Tx Mixer", "TX_CDC_DMA_TX_0_Voip", "TX_CDC_DMA_TX_0"}, - {"Voip_Tx Mixer", "TX_CDC_DMA_TX_1_Voip", "TX_CDC_DMA_TX_1"}, - {"Voip_Tx Mixer", "TX_CDC_DMA_TX_2_Voip", "TX_CDC_DMA_TX_2"}, - {"Voip_Tx Mixer", "TX_CDC_DMA_TX_3_Voip", "TX_CDC_DMA_TX_3"}, - {"Voip_Tx Mixer", "TX_CDC_DMA_TX_4_Voip", "TX_CDC_DMA_TX_4"}, - {"Voip_Tx Mixer", "TX_CDC_DMA_TX_5_Voip", "TX_CDC_DMA_TX_5"}, - {"VOIP_UL", NULL, "Voip_Tx Mixer"}, + /* Backend Enablement */ + {"BE_OUT", NULL, "PRI_TDM_RX_0"}, + {"BE_OUT", NULL, "PRI_TDM_RX_1"}, + {"BE_OUT", NULL, "PRI_TDM_RX_2"}, + {"BE_OUT", NULL, "PRI_TDM_RX_3"}, + {"BE_OUT", NULL, "SEC_TDM_RX_0"}, + {"BE_OUT", NULL, "SEC_TDM_RX_1"}, + {"BE_OUT", NULL, "SEC_TDM_RX_2"}, + {"BE_OUT", NULL, "SEC_TDM_RX_3"}, + {"BE_OUT", NULL, "SEC_TDM_RX_7"}, + {"BE_OUT", NULL, "TERT_TDM_RX_0"}, + {"BE_OUT", NULL, "TERT_TDM_RX_1"}, + {"BE_OUT", NULL, "TERT_TDM_RX_2"}, + {"BE_OUT", NULL, "TERT_TDM_RX_3"}, + {"BE_OUT", NULL, "TERT_TDM_RX_4"}, + {"BE_OUT", NULL, "QUAT_TDM_RX_0"}, + {"BE_OUT", NULL, "QUAT_TDM_RX_1"}, + {"BE_OUT", NULL, "QUAT_TDM_RX_2"}, + {"BE_OUT", NULL, "QUAT_TDM_RX_3"}, + {"BE_OUT", NULL, "QUAT_TDM_RX_7"}, + {"BE_OUT", NULL, "QUIN_TDM_RX_0"}, + {"BE_OUT", NULL, "QUIN_TDM_RX_1"}, + {"BE_OUT", NULL, "QUIN_TDM_RX_2"}, + {"BE_OUT", NULL, "QUIN_TDM_RX_3"}, + {"BE_OUT", NULL, "QUIN_TDM_RX_7"}, + {"BE_OUT", NULL, "SEN_TDM_RX_0"}, + {"BE_OUT", NULL, "SEN_TDM_RX_1"}, + {"BE_OUT", NULL, "SEN_TDM_RX_2"}, + {"BE_OUT", NULL, "SEN_TDM_RX_3"}, - {"SLIMBUS_DL_HL", "Switch", "SLIM0_DL_HL"}, - {"SLIMBUS_0_RX", NULL, "SLIMBUS_DL_HL"}, - {"SLIMBUS1_DL_HL", "Switch", "SLIM1_DL_HL"}, - {"SLIMBUS_1_RX", NULL, "SLIMBUS1_DL_HL"}, - {"SLIMBUS3_DL_HL", "Switch", "SLIM3_DL_HL"}, - {"SLIMBUS_3_RX", NULL, "SLIMBUS3_DL_HL"}, - {"SLIMBUS4_DL_HL", "Switch", "SLIM4_DL_HL"}, - {"SLIMBUS_4_RX", NULL, "SLIMBUS4_DL_HL"}, - {"SLIMBUS6_DL_HL", "Switch", "SLIM0_DL_HL"}, - {"SLIMBUS_6_RX", NULL, "SLIMBUS6_DL_HL"}, - {"SCO_SLIM7_DL_HL", "Switch", "SLIM7_DL_HL"}, - {"SLIMBUS_7_RX", NULL, "SCO_SLIM7_DL_HL"}, - {"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"}, - {"SLIM1_UL_HL", NULL, "SLIMBUS_1_TX"}, - {"SLIM3_UL_HL", NULL, "SLIMBUS_3_TX"}, - {"SLIM4_UL_HL", NULL, "SLIMBUS_4_TX"}, - {"SLIM8_UL_HL", NULL, "SLIMBUS_8_TX"}, - {"WSA_CDC_DMA_RX_0_DL_HL", "Switch", "CDC_DMA_DL_HL"}, - {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0_DL_HL"}, - {"CDC_DMA_UL_HL", NULL, "VA_CDC_DMA_TX_0"}, - {"RX_CDC_DMA_RX_0_DL_HL", "Switch", "CDC_DMA_DL_HL"}, - {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0_DL_HL"}, - {"RX_CDC_DMA_RX_1_DL_HL", "Switch", "CDC_DMA_DL_HL"}, - {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1_DL_HL"}, - {"TX3_CDC_DMA_UL_HL", NULL, "TX_CDC_DMA_TX_3"}, - {"LSM1 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM1 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM1 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM1 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM1 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"LSM1 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"LSM1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"LSM1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"LSM1 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"LSM1 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"LSM1 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"LSM1 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"LSM1_UL_HL", NULL, "LSM1 Mixer"}, + {"PRI_TDM_TX_0", NULL, "BE_IN"}, + {"PRI_TDM_TX_1", NULL, "BE_IN"}, + {"PRI_TDM_TX_2", NULL, "BE_IN"}, + {"PRI_TDM_TX_3", NULL, "BE_IN"}, + {"SEC_TDM_TX_0", NULL, "BE_IN"}, + {"SEC_TDM_TX_1", NULL, "BE_IN"}, + {"SEC_TDM_TX_2", NULL, "BE_IN"}, + {"SEC_TDM_TX_3", NULL, "BE_IN"}, + {"TERT_TDM_TX_0", NULL, "BE_IN"}, + {"TERT_TDM_TX_1", NULL, "BE_IN"}, + {"TERT_TDM_TX_2", NULL, "BE_IN"}, + {"TERT_TDM_TX_3", NULL, "BE_IN"}, + {"TERT_TDM_TX_7", NULL, "BE_IN"}, + {"QUAT_TDM_TX_0", NULL, "BE_IN"}, + {"QUAT_TDM_TX_1", NULL, "BE_IN"}, + {"QUAT_TDM_TX_2", NULL, "BE_IN"}, + {"QUAT_TDM_TX_3", NULL, "BE_IN"}, + {"QUAT_TDM_TX_7", NULL, "BE_IN"}, + {"AFE_LOOPBACK_TX", NULL, "BE_IN"}, + {"QUIN_TDM_TX_0", NULL, "BE_IN"}, + {"QUIN_TDM_TX_1", NULL, "BE_IN"}, + {"QUIN_TDM_TX_2", NULL, "BE_IN"}, + {"QUIN_TDM_TX_3", NULL, "BE_IN"}, + {"QUIN_TDM_TX_7", NULL, "BE_IN"}, + {"SEN_TDM_TX_0", NULL, "BE_IN"}, + {"SEN_TDM_TX_1", NULL, "BE_IN"}, + {"SEN_TDM_TX_2", NULL, "BE_IN"}, + {"SEN_TDM_TX_3", NULL, "BE_IN"}, +}; +#endif - {"LSM2 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM2 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM2 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM2 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM2 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"LSM2 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"LSM2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"LSM2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"LSM2 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"LSM2 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"LSM2 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"LSM2 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"LSM2_UL_HL", NULL, "LSM2 Mixer"}, +#ifndef CONFIG_MI2S_DISABLE +static const struct snd_soc_dapm_route intercon_mi2s[] = { + {"PRI_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"}, + + {"SEC_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SEC_I2S_RX", NULL, "SEC_RX Audio Mixer"}, + /* incall */ + {"MultiMedia2 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia4 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia17 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia18 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia19 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia28 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia29 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia30 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia8 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia18 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia19 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia28 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia29 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia30 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia17 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia18 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia19 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia28 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia29 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia30 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia17 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia18 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia19 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia28 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia29 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia30 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia8 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"LSM3 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM3 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM3 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM3 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM3 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM3 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"LSM3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"LSM3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"LSM3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"LSM3 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"LSM3 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"LSM3 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"LSM3 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"LSM3_UL_HL", NULL, "LSM3 Mixer"}, + {"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"MI2S_RX", NULL, "MI2S_RX Audio Mixer"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia21", "MM_DL21"}, + {"QUAT_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX Audio Mixer"}, - {"LSM4 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM4 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM4 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM4 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM4 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM4 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM4 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"LSM4 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"LSM4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"LSM4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"LSM4 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"LSM4 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"LSM4 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"LSM4 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"LSM4_UL_HL", NULL, "LSM4 Mixer"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX Audio Mixer"}, - {"LSM5 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM5 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM5 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM5 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM5 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"LSM5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"LSM5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"LSM5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"LSM5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"LSM5 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"LSM5 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"LSM5 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"LSM5 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"LSM5_UL_HL", NULL, "LSM5 Mixer"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Audio Mixer"}, - {"LSM6 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM6 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM6 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM6 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM6 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"LSM6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"LSM6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"LSM6 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"LSM6 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"LSM6 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"LSM6 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"LSM6_UL_HL", NULL, "LSM6 Mixer"}, + {"SEC_MI2S_RX_SD1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_MI2S_RX_SD1", NULL, "SEC_MI2S_RX_SD1 Audio Mixer"}, - {"LSM7 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM7 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM7 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM7 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM7 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM7 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"LSM7 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"LSM7 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"LSM7 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"LSM7 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"LSM7 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"LSM7 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"LSM7_UL_HL", NULL, "LSM7 Mixer"}, + {"SEC_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SEC_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + + {"PRI_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Audio Mixer"}, + {"PRI_MI2S_RX Audio Mixer", "DTMF", "DTMF_DL_HL"}, - {"LSM8 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"}, - {"LSM8 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"}, - {"LSM8 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"}, - {"LSM8 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"}, - {"LSM8 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"}, - {"LSM8 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"LSM8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"LSM8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"}, - {"LSM8 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"}, - {"LSM8 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"LSM8 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"LSM8 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"LSM8_UL_HL", NULL, "LSM8 Mixer"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"INT0_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX Audio Mixer"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"INT4_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX Audio Mixer"}, - {"CPE_LSM_UL_HL", NULL, "BE_IN"}, - {"QCHAT_Tx Mixer", "PRI_TX_QCHAT", "PRI_I2S_TX"}, - {"QCHAT_Tx Mixer", "SLIM_0_TX_QCHAT", "SLIMBUS_0_TX"}, - {"QCHAT_Tx Mixer", "SLIM_7_TX_QCHAT", "SLIMBUS_7_TX"}, - {"QCHAT_Tx Mixer", "SLIM_8_TX_QCHAT", "SLIMBUS_8_TX"}, - {"QCHAT_Tx Mixer", "INTERNAL_BT_SCO_TX_QCHAT", "INT_BT_SCO_TX"}, - {"QCHAT_Tx Mixer", "AFE_PCM_TX_QCHAT", "PCM_TX"}, - {"QCHAT_Tx Mixer", "AUX_PCM_TX_QCHAT", "AUX_PCM_TX"}, - {"QCHAT_Tx Mixer", "SEC_AUX_PCM_TX_QCHAT", "SEC_AUX_PCM_TX"}, - {"QCHAT_Tx Mixer", "TERT_AUX_PCM_TX_QCHAT", "TERT_AUX_PCM_TX"}, - {"QCHAT_Tx Mixer", "QUAT_AUX_PCM_TX_QCHAT", "QUAT_AUX_PCM_TX"}, - {"QCHAT_Tx Mixer", "QUIN_AUX_PCM_TX_QCHAT", "QUIN_AUX_PCM_TX"}, - {"QCHAT_Tx Mixer", "SEN_AUX_PCM_TX_QCHAT", "SEN_AUX_PCM_TX"}, - {"QCHAT_Tx Mixer", "MI2S_TX_QCHAT", "MI2S_TX"}, - {"QCHAT_Tx Mixer", "PRI_MI2S_TX_QCHAT", "PRI_MI2S_TX"}, - {"QCHAT_Tx Mixer", "TERT_MI2S_TX_QCHAT", "TERT_MI2S_TX"}, - {"QCHAT_Tx Mixer", "INT3_MI2S_TX_QCHAT", "INT3_MI2S_TX"}, - {"QCHAT_Tx Mixer", "USB_AUDIO_TX_QCHAT", "USB_AUDIO_TX"}, - {"QCHAT_UL", NULL, "QCHAT_Tx Mixer"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUIN_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX Audio Mixer"}, - {"INT_FM_RX", NULL, "INTFM_DL_HL"}, - {"INTFM_UL_HL", NULL, "INT_FM_TX"}, - {"INTHFP_UL_HL", NULL, "HFP_PRI_AUX_UL_HL"}, - {"HFP_PRI_AUX_UL_HL", "Switch", "AUX_PCM_TX"}, - {"INTHFP_UL_HL", NULL, "HFP_AUX_UL_HL"}, - {"HFP_AUX_UL_HL", "Switch", "SEC_AUX_PCM_TX"}, - {"INTHFP_UL_HL", NULL, "HFP_INT_UL_HL"}, - {"HFP_INT_UL_HL", "Switch", "INT_BT_SCO_TX"}, - {"SLIM7_UL_HL", NULL, "HFP_SLIM7_UL_HL"}, - {"HFP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"}, - {"AUX_PCM_RX", NULL, "AUXPCM_DL_HL"}, - {"AUX_PCM_RX", NULL, "INTHFP_DL_HL"}, - {"SLIM7_UL_HL", NULL, "A2DP_SLIM7_UL_HL"}, - {"A2DP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"}, - {"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_DL_HL"}, - {"AUXPCM_UL_HL", NULL, "AUX_PCM_TX"}, - {"SEC_AUXPCM_UL_HL", NULL, "SEC_AUX_PCM_TX"}, - {"MI2S_RX", NULL, "MI2S_DL_HL"}, - {"MI2S_UL_HL", NULL, "MI2S_TX"}, - {"PCM_RX_DL_HL", "Switch", "SLIM0_DL_HL"}, - {"PCM_RX", NULL, "PCM_RX_DL_HL"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEN_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX Audio Mixer"}, - /* connect to INT4_MI2S_DL_HL since same pcm_id */ - {"INT0_MI2S_RX_DL_HL", "Switch", "INT4_MI2S_DL_HL"}, - {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX_DL_HL"}, - {"INT4_MI2S_RX_DL_HL", "Switch", "INT4_MI2S_DL_HL"}, - {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_DL_HL"}, - {"PRI_MI2S_RX_DL_HL", "Switch", "PRI_MI2S_DL_HL"}, - {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_DL_HL"}, - {"SEC_MI2S_RX_DL_HL", "Switch", "SEC_MI2S_DL_HL"}, - {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX_DL_HL"}, - {"TERT_MI2S_RX_DL_HL", "Switch", "TERT_MI2S_DL_HL"}, - {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX_DL_HL"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"PRI_META_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"PRI_META_MI2S_RX", NULL, "PRI_META_MI2S_RX Audio Mixer"}, - {"QUAT_MI2S_RX_DL_HL", "Switch", "QUAT_MI2S_DL_HL"}, - {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_DL_HL"}, - {"QUIN_MI2S_RX_DL_HL", "Switch", "QUIN_MI2S_DL_HL"}, - {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_DL_HL"}, - {"SEN_MI2S_RX_DL_HL", "Switch", "SEN_MI2S_DL_HL"}, - {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX_DL_HL"}, - {"MI2S_UL_HL", NULL, "TERT_MI2S_TX"}, - {"INT3_MI2S_UL_HL", NULL, "INT3_MI2S_TX"}, - {"TERT_MI2S_UL_HL", NULL, "TERT_MI2S_TX"}, - {"SEC_I2S_RX", NULL, "SEC_I2S_DL_HL"}, - {"PRI_MI2S_UL_HL", NULL, "PRI_MI2S_TX"}, - {"SEC_MI2S_UL_HL", NULL, "SEC_MI2S_TX"}, - {"SEC_MI2S_RX", NULL, "SEC_MI2S_DL_HL"}, - {"PRI_MI2S_RX", NULL, "PRI_MI2S_DL_HL"}, - {"TERT_MI2S_RX", NULL, "TERT_MI2S_DL_HL"}, - {"QUAT_MI2S_UL_HL", NULL, "QUAT_MI2S_TX"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_META_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SEC_META_MI2S_RX", NULL, "SEC_META_MI2S_RX Audio Mixer"}, - {"PRI_TDM_TX_0_UL_HL", NULL, "PRI_TDM_TX_0"}, - {"PRI_TDM_TX_1_UL_HL", NULL, "PRI_TDM_TX_1"}, - {"PRI_TDM_TX_2_UL_HL", NULL, "PRI_TDM_TX_2"}, - {"PRI_TDM_TX_3_UL_HL", NULL, "PRI_TDM_TX_3"}, - {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0_DL_HL"}, - {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1_DL_HL"}, - {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2_DL_HL"}, - {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3_DL_HL"}, - {"SEC_TDM_TX_0_UL_HL", NULL, "SEC_TDM_TX_0"}, - {"SEC_TDM_TX_1_UL_HL", NULL, "SEC_TDM_TX_1"}, - {"SEC_TDM_TX_2_UL_HL", NULL, "SEC_TDM_TX_2"}, - {"SEC_TDM_TX_3_UL_HL", NULL, "SEC_TDM_TX_3"}, - {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0_DL_HL"}, - {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1_DL_HL"}, - {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2_DL_HL"}, - {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3_DL_HL"}, - {"SEC_TDM_RX_7", NULL, "SEC_TDM_RX_7_DL_HL"}, - {"TERT_TDM_TX_0_UL_HL", NULL, "TERT_TDM_TX_0"}, - {"TERT_TDM_TX_1_UL_HL", NULL, "TERT_TDM_TX_1"}, - {"TERT_TDM_TX_2_UL_HL", NULL, "TERT_TDM_TX_2"}, - {"TERT_TDM_TX_3_UL_HL", NULL, "TERT_TDM_TX_3"}, - {"TERT_TDM_TX_7_UL_HL", NULL, "TERT_TDM_TX_7"}, - {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0_DL_HL"}, - {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1_DL_HL"}, - {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2_DL_HL"}, - {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3_DL_HL"}, - {"QUAT_TDM_TX_0_UL_HL", NULL, "QUAT_TDM_TX_0"}, - {"QUAT_TDM_TX_1_UL_HL", NULL, "QUAT_TDM_TX_1"}, - {"QUAT_TDM_TX_2_UL_HL", NULL, "QUAT_TDM_TX_2"}, - {"QUAT_TDM_TX_3_UL_HL", NULL, "QUAT_TDM_TX_3"}, - {"QUAT_TDM_TX_7_UL_HL", NULL, "QUAT_TDM_TX_7"}, - {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0_DL_HL"}, - {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1_DL_HL"}, - {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_DL_HL"}, - {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3_DL_HL"}, - {"QUAT_TDM_RX_7", NULL, "QUAT_TDM_RX_7_DL_HL"}, - {"QUIN_TDM_TX_0_UL_HL", NULL, "QUIN_TDM_TX_0"}, - {"QUIN_TDM_TX_1_UL_HL", NULL, "QUIN_TDM_TX_1"}, - {"QUIN_TDM_TX_2_UL_HL", NULL, "QUIN_TDM_TX_2"}, - {"QUIN_TDM_TX_3_UL_HL", NULL, "QUIN_TDM_TX_3"}, - {"QUIN_TDM_TX_7_UL_HL", NULL, "QUIN_TDM_TX_7"}, - {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0_DL_HL"}, - {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1_DL_HL"}, - {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2_DL_HL"}, - {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3_DL_HL"}, - {"QUIN_TDM_RX_7", NULL, "QUIN_TDM_RX_7_DL_HL"}, - {"SEN_TDM_TX_0_UL_HL", NULL, "SEN_TDM_TX_0"}, - {"SEN_TDM_TX_1_UL_HL", NULL, "SEN_TDM_TX_1"}, - {"SEN_TDM_TX_2_UL_HL", NULL, "SEN_TDM_TX_2"}, - {"SEN_TDM_TX_3_UL_HL", NULL, "SEN_TDM_TX_3"}, - {"SEN_TDM_RX_0", NULL, "SEN_TDM_RX_0_DL_HL"}, - {"SEN_TDM_RX_1", NULL, "SEN_TDM_RX_1_DL_HL"}, - {"SEN_TDM_RX_2", NULL, "SEN_TDM_RX_2_DL_HL"}, - {"SEN_TDM_RX_3", NULL, "SEN_TDM_RX_3_DL_HL"}, + {"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"}, + {"MultiMedia1 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia3 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia5 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia10 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia16 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia1 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia2 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia1 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, + {"MultiMedia2 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, + {"MultiMedia1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia1 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia2 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia1 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia2 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia1 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia1 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia2 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia6 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia10 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia6 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia3 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia5 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia10 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia16 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia6 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia10 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia16 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia17 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia18 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia19 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia28 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia29 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia30 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia6 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia6 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia6 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia5 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia6 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, + {"MultiMedia5 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"PRI_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"PRI_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Port Mixer"}, + {"MultiMedia27 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia27 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"MultiMedia27 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia27 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia27 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"MultiMedia27 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"PRI_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"PRI_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Port Mixer"}, + {"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"}, - {"PRI_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"PRI_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"PRI_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"PRI_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"PRI_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"PRI_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"PRI_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"PRI_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"PRI_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"PRI_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Port Mixer"}, + {"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SEC_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SEC_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"}, - {"PRI_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"PRI_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"PRI_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"PRI_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"PRI_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"PRI_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"PRI_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"PRI_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, - {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, - {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, - {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"}, - {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"PRI_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"PRI_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Port Mixer"}, + {"SEC_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"SEC_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SEC_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX_Voice Mixer"}, - {"SEC_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEC_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"SEC_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SEC_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SEC_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SEC_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SEC_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEC_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"SEC_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"SEC_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Port Mixer"}, + {"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"}, - {"SEC_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEC_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"SEC_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SEC_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SEC_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SEC_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SEC_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEC_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"SEC_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"SEC_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Port Mixer"}, + {"PRI_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"PRI_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"PRI_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_Voice Mixer"}, - {"SEC_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEC_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"SEC_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SEC_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SEC_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SEC_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SEC_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEC_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"SEC_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"SEC_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Port Mixer"}, + {"INT0_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"INT0_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"INT0_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"INT0_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"INT0_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX_Voice Mixer"}, + + {"INT4_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"INT4_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"INT4_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"INT4_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"INT4_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_Voice Mixer"}, - {"SEC_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEC_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"SEC_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SEC_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SEC_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SEC_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SEC_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEC_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, - {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, - {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, - {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, - {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"SEC_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"SEC_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Port Mixer"}, + {"TERT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"TERT_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"TERT_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX_Voice Mixer"}, - {"SEC_TDM_RX_7 Port Mixer", "TERT_TDM_TX_7", "TERT_TDM_TX_7"}, - {"SEC_TDM_RX_7", NULL, "SEC_TDM_RX_7 Port Mixer"}, + {"QUAT_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUAT_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_Voice Mixer"}, - {"TERT_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"TERT_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"TERT_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"TERT_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"TERT_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"TERT_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"TERT_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"TERT_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"TERT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"TERT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"TERT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"TERT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Port Mixer"}, + {"QUIN_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"QUIN_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_Voice Mixer"}, - {"TERT_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"TERT_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"TERT_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"TERT_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"TERT_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"TERT_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"TERT_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"TERT_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"TERT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"TERT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"TERT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"TERT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Port Mixer"}, + {"SEN_MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"SEN_MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"SEN_MI2S_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"SEN_MI2S_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX_Voice Mixer"}, - {"TERT_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"TERT_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"TERT_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"TERT_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"TERT_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"TERT_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"TERT_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"TERT_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"TERT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"TERT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"TERT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"TERT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Port Mixer"}, + {"VOC_EXT_EC MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"VOC_EXT_EC MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"VOC_EXT_EC MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"VOC_EXT_EC MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"VOC_EXT_EC MUX", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"TERT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"TERT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"TERT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"TERT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Port Mixer"}, + {"AUDIO_REF_EC_UL1 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL1 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL1 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL1 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"QUAT_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"QUAT_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"QUAT_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Port Mixer"}, + {"AUDIO_REF_EC_UL2 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL2 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL2 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL2 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"QUAT_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"QUAT_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"QUAT_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Port Mixer"}, + {"AUDIO_REF_EC_UL3 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL3 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL3 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL3 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"QUAT_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"QUAT_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"QUAT_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Port Mixer"}, + {"AUDIO_REF_EC_UL4 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL4 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL4 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL4 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"AUDIO_REF_EC_UL5 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL5 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL5 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL5 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"QUAT_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"QUAT_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"QUAT_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Port Mixer"}, + {"AUDIO_REF_EC_UL6 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL6 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL6 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL6 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUAT_TDM_RX_7 Port Mixer", "QUAT_TDM_TX_7", "QUAT_TDM_TX_7"}, - {"QUAT_TDM_RX_7 Port Mixer", "QUIN_TDM_TX_7", "QUIN_TDM_TX_7"}, - {"QUAT_TDM_RX_7", NULL, "QUAT_TDM_RX_7 Port Mixer"}, + {"AUDIO_REF_EC_UL8 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL8 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL8 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL8 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"QUIN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"QUIN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"QUIN_TDM_RX_0 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"QUIN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0 Port Mixer"}, + {"AUDIO_REF_EC_UL9 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL9 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL9 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL9 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"QUIN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"QUIN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"QUIN_TDM_RX_1 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"QUIN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUIN_TDM_RX_1", NULL, "QUIN_TDM_RX_1 Port Mixer"}, + {"AUDIO_REF_EC_UL10 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"QUIN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"QUIN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"QUIN_TDM_RX_2 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"QUIN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2 Port Mixer"}, + {"AUDIO_REF_EC_UL16 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL16 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL16 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL16 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"QUIN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"QUIN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, - {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, - {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, - {"QUIN_TDM_RX_3 Port Mixer", "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, - {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"QUIN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"QUIN_TDM_RX_3", NULL, "QUIN_TDM_RX_3 Port Mixer"}, + {"AUDIO_REF_EC_UL17 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL17 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL17 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL17 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"QUIN_TDM_RX_7 Port Mixer", "TERT_TDM_TX_7", "TERT_TDM_TX_7"}, - {"QUIN_TDM_RX_7 Port Mixer", "QUAT_TDM_TX_7", "QUAT_TDM_TX_7"}, - {"QUIN_TDM_RX_7 Port Mixer", "QUIN_TDM_TX_7", "QUIN_TDM_TX_7"}, - {"QUIN_TDM_RX_7", NULL, "QUIN_TDM_RX_7 Port Mixer"}, + {"AUDIO_REF_EC_UL18 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL18 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL18 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL18 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"SEN_TDM_RX_0 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"SEN_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"SEN_TDM_RX_0 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"SEN_TDM_RX_0", NULL, "SEN_TDM_RX_0 Port Mixer"}, + {"AUDIO_REF_EC_UL19 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL19 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL19 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL19 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"SEN_TDM_RX_1 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"SEN_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"SEN_TDM_RX_1 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"SEN_TDM_RX_1", NULL, "SEN_TDM_RX_1 Port Mixer"}, + {"AUDIO_REF_EC_UL28 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL28 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL28 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL28 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"SEN_TDM_RX_2 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"SEN_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"SEN_TDM_RX_2 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"SEN_TDM_RX_2", NULL, "SEN_TDM_RX_2 Port Mixer"}, + {"AUDIO_REF_EC_UL29 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL29 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL29 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL29 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"VoiceMMode1_Tx Mixer", "PRI_TX_MMode1", "PRI_I2S_TX"}, + {"VoiceMMode1_Tx Mixer", "PRI_MI2S_TX_MMode1", "PRI_MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "MI2S_TX_MMode1", "MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "SEC_MI2S_TX_MMode1", "SEC_MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "TERT_MI2S_TX_MMode1", "TERT_MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "INT3_MI2S_TX_MMode1", "INT3_MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "QUAT_MI2S_TX_MMode1", "QUAT_MI2S_TX"}, + {"VoiceMMode1_Tx Mixer", "QUIN_MI2S_TX_MMode1", "QUIN_MI2S_TX"}, + + {"VoiceMMode2_Tx Mixer", "PRI_TX_MMode2", "PRI_I2S_TX"}, + {"VoiceMMode2_Tx Mixer", "PRI_MI2S_TX_MMode2", "PRI_MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "SEC_MI2S_TX_MMode2", "SEC_MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "MI2S_TX_MMode2", "MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "TERT_MI2S_TX_MMode2", "TERT_MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "INT3_MI2S_TX_MMode2", "INT3_MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "QUAT_MI2S_TX_MMode2", "QUAT_MI2S_TX"}, + {"VoiceMMode2_Tx Mixer", "QUIN_MI2S_TX_MMode2", "QUIN_MI2S_TX"}, + {"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"}, + {"Voip_Tx Mixer", "MI2S_TX_Voip", "MI2S_TX"}, + {"Voip_Tx Mixer", "SEC_MI2S_TX_Voip", "SEC_MI2S_TX"}, + {"Voip_Tx Mixer", "TERT_MI2S_TX_Voip", "TERT_MI2S_TX"}, + {"Voip_Tx Mixer", "INT3_MI2S_TX_Voip", "INT3_MI2S_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, - {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, - {"SEN_TDM_RX_3 Port Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, - {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, - {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, - {"SEN_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, - {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_0", "SEN_TDM_TX_0"}, - {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_1", "SEN_TDM_TX_1"}, - {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_2", "SEN_TDM_TX_2"}, - {"SEN_TDM_RX_3 Port Mixer", "SEN_TDM_TX_3", "SEN_TDM_TX_3"}, - {"SEN_TDM_RX_3", NULL, "SEN_TDM_RX_3 Port Mixer"}, + {"LSM1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM1 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM2 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM3 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM4 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM4 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM4 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"LSM5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"LSM6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM7 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"LSM8 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"INT0_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"INT0_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"INT0_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"INT0_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"INT0_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"INT0_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"INT0_MI2S_RX Port Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"INT0_MI2S_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"INT0_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"INT0_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"INT0_MI2S_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"INT0_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX Port Mixer"}, + {"QCHAT_Tx Mixer", "PRI_TX_QCHAT", "PRI_I2S_TX"}, + {"QCHAT_Tx Mixer", "MI2S_TX_QCHAT", "MI2S_TX"}, + {"QCHAT_Tx Mixer", "PRI_MI2S_TX_QCHAT", "PRI_MI2S_TX"}, + {"QCHAT_Tx Mixer", "TERT_MI2S_TX_QCHAT", "TERT_MI2S_TX"}, + {"QCHAT_Tx Mixer", "INT3_MI2S_TX_QCHAT", "INT3_MI2S_TX"}, - {"INT4_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"INT4_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"INT4_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"INT4_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"INT4_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, - {"INT4_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"INT4_MI2S_RX Port Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"INT4_MI2S_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"INT4_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"INT4_MI2S_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"INT4_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"INT4_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX Port Mixer"}, + {"MI2S_RX", NULL, "MI2S_DL_HL"}, + {"MI2S_UL_HL", NULL, "MI2S_TX"}, - {"WSA_CDC_DMA_RX_0 Port Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"WSA_CDC_DMA_RX_0 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"WSA_CDC_DMA_RX_0 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + /* connect to INT4_MI2S_DL_HL since same pcm_id */ {"WSA_CDC_DMA_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"WSA_CDC_DMA_RX_0", NULL, "WSA_CDC_DMA_RX_0 Port Mixer"}, - - {"RX_CDC_DMA_RX_0 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"RX_CDC_DMA_RX_0 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"RX_CDC_DMA_RX_0 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"RX_CDC_DMA_RX_0", NULL, "RX_CDC_DMA_RX_0 Port Mixer"}, - - {"RX_CDC_DMA_RX_1 Port Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"}, - {"RX_CDC_DMA_RX_1 Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, - {"RX_CDC_DMA_RX_1 Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"RX_CDC_DMA_RX_1 Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"RX_CDC_DMA_RX_1", NULL, "RX_CDC_DMA_RX_1 Port Mixer"}, - {"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"SLIMBUS_0_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"SLIMBUS_0_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"SLIMBUS_0_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"SLIMBUS_0_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"SLIMBUS_0_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SLIMBUS_0_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SLIMBUS_0_RX Port Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, - {"SLIMBUS_0_RX Port Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, - {"SLIMBUS_0_RX Port Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, - {"SLIMBUS_0_RX Port Mixer", "SEN_AUXPCM_UL_TX", "SEN_AUX_PCM_TX"}, {"SLIMBUS_0_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, @@ -29232,168 +29889,85 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_0_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, - {"SLIMBUS_0_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"}, - {"AFE_PCM_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"AFE_PCM_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"PCM_RX", NULL, "AFE_PCM_RX Port Mixer"}, - {"USB_AUDIO_RX Port Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, - {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX Port Mixer"}, - {"USB_DL_HL", "Switch", "USBAUDIO_DL_HL"}, - {"USB_AUDIO_RX", NULL, "USB_DL_HL"}, - {"USBAUDIO_UL_HL", NULL, "USB_AUDIO_TX"}, - - - {"AUX_PCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"AUX_PCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"AUX_PCM_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"AUX_PCM_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"AUX_PCM_RX Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, - {"AUX_PCM_RX Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, - {"AUX_PCM_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, - {"AUX_PCM_RX", NULL, "AUX_PCM_RX Port Mixer"}, - - {"SEC_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SEC_AUXPCM_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SEC_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"SEC_AUXPCM_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_RX Port Mixer"}, - - {"TERT_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"TERT_AUXPCM_RX Port Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, - {"TERT_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"TERT_AUX_PCM_RX", NULL, "TERT_AUXPCM_RX Port Mixer"}, - - {"QUAT_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUAT_AUXPCM_RX Port Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, - {"QUAT_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUXPCM_RX Port Mixer"}, - - {"QUIN_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUIN_AUXPCM_RX Port Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, - {"QUIN_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"QUIN_AUX_PCM_RX", NULL, "QUIN_AUXPCM_RX Port Mixer"}, - - {"Voice Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, - {"Voice Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"Voice Stub Tx Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"Voice Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"}, - {"Voice Stub Tx Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"Voice Stub Tx Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"Voice Stub Tx Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, - {"Voice Stub Tx Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, - {"Voice Stub Tx Mixer", "QUIN_AUXPCM_UL_TX", "QUIN_AUX_PCM_TX"}, - {"Voice Stub Tx Mixer", "SEN_AUXPCM_UL_TX", "SEN_AUX_PCM_TX"}, - {"Voice Stub Tx Mixer", "MI2S_TX", "MI2S_TX"}, - {"Voice Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"Voice Stub Tx Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"Voice Stub Tx Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, - {"Voice Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"Voice Stub Tx Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"Voice Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"}, - {"Voice Stub Tx Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"Voice Stub Tx Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"Voice Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"VOICE_STUB_UL", NULL, "Voice Stub Tx Mixer"}, - - {"VoLTE Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, - {"VoLTE Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"VoLTE Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"}, - {"VoLTE Stub Tx Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"VoLTE Stub Tx Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"VoLTE Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"}, - {"VoLTE Stub Tx Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"VoLTE Stub Tx Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"VoLTE Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"VoLTE Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"VoLTE Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"VOLTE_STUB_UL", NULL, "VoLTE Stub Tx Mixer"}, - - {"Voice2 Stub Tx Mixer", "STUB_TX_HL", "STUB_TX"}, - {"Voice2 Stub Tx Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"Voice2 Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"}, - {"Voice2 Stub Tx Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"Voice2 Stub Tx Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"Voice2 Stub Tx Mixer", "SLIM_3_TX", "SLIMBUS_3_TX"}, - {"Voice2 Stub Tx Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"Voice2 Stub Tx Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"Voice2 Stub Tx Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"Voice2 Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"Voice2 Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"Voice2 Stub Tx Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"VOICE2_STUB_UL", NULL, "Voice2 Stub Tx Mixer"}, - - {"STUB_RX Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"STUB_RX Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"STUB_RX", NULL, "STUB_RX Mixer"}, - - {"SLIMBUS_1_RX Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SLIMBUS_1_RX Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Mixer"}, - - {"SLIMBUS_3_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SLIMBUS_3_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX_Voice Mixer"}, - {"SLIM_7_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SLIM_7_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SLIM_7_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SLIM_7_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SLIM_7_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SLIMBUS_7_RX", NULL, "SLIM_7_RX_Voice Mixer"}, + {"SLIMBUS_6_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, + {"SLIMBUS_6_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"SLIMBUS_6_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"SLIMBUS_6_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SLIM_8_RX_Voice Mixer", "Voip", "VOIP_DL"}, - {"SLIM_8_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, - {"SLIM_8_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, - {"SLIM_8_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, - {"SLIM_8_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, - {"SLIMBUS_8_RX", NULL, "SLIM_8_RX_Voice Mixer"}, + {"INT0_MI2S_RX_DL_HL", "Switch", "INT4_MI2S_DL_HL"}, + {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX_DL_HL"}, + {"INT4_MI2S_RX_DL_HL", "Switch", "INT4_MI2S_DL_HL"}, + {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_DL_HL"}, + {"PRI_MI2S_RX_DL_HL", "Switch", "PRI_MI2S_DL_HL"}, + {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_DL_HL"}, + {"SEC_MI2S_RX_DL_HL", "Switch", "SEC_MI2S_DL_HL"}, + {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX_DL_HL"}, + {"TERT_MI2S_RX_DL_HL", "Switch", "TERT_MI2S_DL_HL"}, + {"TERT_MI2S_RX", NULL, "TERT_MI2S_RX_DL_HL"}, - {"SLIMBUS_1_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SLIMBUS_1_RX Port Mixer", "AFE_PCM_TX", "PCM_TX"}, - {"SLIMBUS_1_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Port Mixer"}, - {"INTERNAL_BT_SCO_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"INTERNAL_BT_SCO_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Port Mixer"}, - {"SLIMBUS_3_RX Port Mixer", "INTERNAL_BT_SCO_RX", "INT_BT_SCO_RX"}, - {"SLIMBUS_3_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, - {"SLIMBUS_3_RX Port Mixer", "AFE_PCM_RX", "PCM_RX"}, - {"SLIMBUS_3_RX Port Mixer", "AUX_PCM_RX", "AUX_PCM_RX"}, - {"SLIMBUS_3_RX Port Mixer", "SLIM_0_RX", "SLIMBUS_0_RX"}, - {"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX Port Mixer"}, + {"QUAT_MI2S_RX_DL_HL", "Switch", "QUAT_MI2S_DL_HL"}, + {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_DL_HL"}, + {"QUIN_MI2S_RX_DL_HL", "Switch", "QUIN_MI2S_DL_HL"}, + {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_DL_HL"}, + {"SEN_MI2S_RX_DL_HL", "Switch", "SEN_MI2S_DL_HL"}, + {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX_DL_HL"}, + {"MI2S_UL_HL", NULL, "TERT_MI2S_TX"}, + {"INT3_MI2S_UL_HL", NULL, "INT3_MI2S_TX"}, + {"TERT_MI2S_UL_HL", NULL, "TERT_MI2S_TX"}, + {"SEC_I2S_RX", NULL, "SEC_I2S_DL_HL"}, + {"PRI_MI2S_UL_HL", NULL, "PRI_MI2S_TX"}, + {"SEC_MI2S_UL_HL", NULL, "SEC_MI2S_TX"}, + {"SEC_MI2S_RX", NULL, "SEC_MI2S_DL_HL"}, + {"PRI_MI2S_RX", NULL, "PRI_MI2S_DL_HL"}, + {"TERT_MI2S_RX", NULL, "TERT_MI2S_DL_HL"}, + {"QUAT_MI2S_UL_HL", NULL, "QUAT_MI2S_TX"}, - {"SLIMBUS_6_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, - {"SLIMBUS_6_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, - {"SLIMBUS_6_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, - {"SLIMBUS_6_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, - {"SLIMBUS_6_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, - {"SLIMBUS_6_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, - {"SLIMBUS_6_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"SLIMBUS_6_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SLIMBUS_6_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, - {"SLIMBUS_6_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, - {"SLIMBUS_6_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, - {"SLIMBUS_6_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"SLIMBUS_6_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, - {"SLIMBUS_6_RX", NULL, "SLIMBUS_6_RX Port Mixer"}, + {"INT0_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"INT0_MI2S_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"INT0_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"INT0_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"INT0_MI2S_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, + {"INT0_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"INT0_MI2S_RX", NULL, "INT0_MI2S_RX Port Mixer"}, - {"HDMI_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, - {"HDMI", NULL, "HDMI_RX Port Mixer"}, + {"INT4_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"INT4_MI2S_RX Port Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, + {"INT4_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"INT4_MI2S_RX Port Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"}, + {"INT4_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"INT4_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX Port Mixer"}, - {"HDMI_RX_MS Port Mixer", "MI2S_TX", "MI2S_TX"}, - {"HDMI_MS", NULL, "HDMI_RX_MS Port Mixer"}, + {"Voice Stub Tx Mixer", "MI2S_TX", "MI2S_TX"}, + {"Voice Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"Voice Stub Tx Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"Voice Stub Tx Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"Voice Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"DISPLAY_PORT_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, - {"DISPLAY_PORT", NULL, "DISPLAY_PORT_RX Port Mixer"}, + {"VoLTE Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"VoLTE Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, - {"DISPLAY_PORT_RX1 Port Mixer", "MI2S_TX", "MI2S_TX"}, - {"DISPLAY_PORT1", NULL, "DISPLAY_PORT_RX1 Port Mixer"}, + {"Voice2 Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"Voice2 Stub Tx Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"Voice2 Stub Tx Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"SEC_I2S_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, {"SEC_I2S_RX", NULL, "SEC_I2S_RX Port Mixer"}, - {"MI2S_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"MI2S_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"}, {"MI2S_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, {"MI2S_RX", NULL, "MI2S_RX Port Mixer"}, @@ -29407,7 +29981,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"PRI_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"PRI_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"PRI_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE {"PRI_MI2S_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, +#endif {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Port Mixer"}, {"SEC_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -29419,7 +29995,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"SEC_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"SEC_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE {"SEC_MI2S_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, +#endif {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Port Mixer"}, {"TERT_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -29440,7 +30018,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEN_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, {"QUAT_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"QUAT_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, +#ifndef CONFIG_AUXPCM_DISABLE {"QUAT_MI2S_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, +#endif {"QUAT_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX Port Mixer"}, @@ -29467,23 +30047,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "PRI_I2S_RX"}, {"BE_OUT", NULL, "SEC_I2S_RX"}, - {"BE_OUT", NULL, "SLIMBUS_0_RX"}, - {"BE_OUT", NULL, "SLIMBUS_1_RX"}, - {"BE_OUT", NULL, "SLIMBUS_2_RX"}, - {"BE_OUT", NULL, "SLIMBUS_3_RX"}, - {"BE_OUT", NULL, "SLIMBUS_4_RX"}, - {"BE_OUT", NULL, "SLIMBUS_5_RX"}, - {"BE_OUT", NULL, "SLIMBUS_6_RX"}, - {"BE_OUT", NULL, "SLIMBUS_7_RX"}, - {"BE_OUT", NULL, "SLIMBUS_8_RX"}, - {"BE_OUT", NULL, "SLIMBUS_9_RX"}, - {"BE_OUT", NULL, "USB_AUDIO_RX"}, - {"BE_OUT", NULL, "HDMI"}, - {"BE_OUT", NULL, "HDMI_MS"}, - {"BE_OUT", NULL, "DISPLAY_PORT"}, - {"BE_OUT", NULL, "DISPLAY_PORT1"}, - {"BE_OUT", NULL, "PRI_SPDIF_RX"}, - {"BE_OUT", NULL, "SEC_SPDIF_RX"}, {"BE_OUT", NULL, "MI2S_RX"}, {"BE_OUT", NULL, "QUAT_MI2S_RX"}, {"BE_OUT", NULL, "QUIN_MI2S_RX"}, @@ -29497,62 +30060,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "INT2_MI2S_RX"}, {"BE_OUT", NULL, "INT3_MI2S_RX"}, {"BE_OUT", NULL, "INT5_MI2S_RX"}, - {"BE_OUT", NULL, "INT_BT_SCO_RX"}, - {"BE_OUT", NULL, "INT_BT_A2DP_RX"}, - {"BE_OUT", NULL, "INT_FM_RX"}, - {"BE_OUT", NULL, "PCM_RX"}, - {"BE_OUT", NULL, "SLIMBUS_3_RX"}, - {"BE_OUT", NULL, "AUX_PCM_RX"}, - {"BE_OUT", NULL, "SEC_AUX_PCM_RX"}, - {"BE_OUT", NULL, "TERT_AUX_PCM_RX"}, - {"BE_OUT", NULL, "QUAT_AUX_PCM_RX"}, - {"BE_OUT", NULL, "QUIN_AUX_PCM_RX"}, - {"BE_OUT", NULL, "SEN_AUX_PCM_RX"}, - {"BE_OUT", NULL, "INT_BT_SCO_RX"}, - {"BE_OUT", NULL, "INT_FM_RX"}, - {"BE_OUT", NULL, "PCM_RX"}, - {"BE_OUT", NULL, "SLIMBUS_3_RX"}, - {"BE_OUT", NULL, "VOICE_PLAYBACK_TX"}, - {"BE_OUT", NULL, "VOICE2_PLAYBACK_TX"}, - {"BE_OUT", NULL, "PRI_TDM_RX_0"}, - {"BE_OUT", NULL, "PRI_TDM_RX_1"}, - {"BE_OUT", NULL, "PRI_TDM_RX_2"}, - {"BE_OUT", NULL, "PRI_TDM_RX_3"}, - {"BE_OUT", NULL, "SEC_TDM_RX_0"}, - {"BE_OUT", NULL, "SEC_TDM_RX_1"}, - {"BE_OUT", NULL, "SEC_TDM_RX_2"}, - {"BE_OUT", NULL, "SEC_TDM_RX_3"}, - {"BE_OUT", NULL, "SEC_TDM_RX_7"}, - {"BE_OUT", NULL, "TERT_TDM_RX_0"}, - {"BE_OUT", NULL, "TERT_TDM_RX_1"}, - {"BE_OUT", NULL, "TERT_TDM_RX_2"}, - {"BE_OUT", NULL, "TERT_TDM_RX_3"}, - {"BE_OUT", NULL, "TERT_TDM_RX_4"}, - {"BE_OUT", NULL, "QUAT_TDM_RX_0"}, - {"BE_OUT", NULL, "QUAT_TDM_RX_1"}, - {"BE_OUT", NULL, "QUAT_TDM_RX_2"}, - {"BE_OUT", NULL, "QUAT_TDM_RX_3"}, - {"BE_OUT", NULL, "QUAT_TDM_RX_7"}, - {"BE_OUT", NULL, "QUIN_TDM_RX_0"}, - {"BE_OUT", NULL, "QUIN_TDM_RX_1"}, - {"BE_OUT", NULL, "QUIN_TDM_RX_2"}, - {"BE_OUT", NULL, "QUIN_TDM_RX_3"}, - {"BE_OUT", NULL, "QUIN_TDM_RX_7"}, - {"BE_OUT", NULL, "SEN_TDM_RX_0"}, - {"BE_OUT", NULL, "SEN_TDM_RX_1"}, - {"BE_OUT", NULL, "SEN_TDM_RX_2"}, - {"BE_OUT", NULL, "SEN_TDM_RX_3"}, - {"BE_OUT", NULL, "WSA_CDC_DMA_RX_0"}, - {"BE_OUT", NULL, "WSA_CDC_DMA_RX_1"}, - {"BE_OUT", NULL, "RX_CDC_DMA_RX_0"}, - {"BE_OUT", NULL, "RX_CDC_DMA_RX_1"}, - {"BE_OUT", NULL, "RX_CDC_DMA_RX_2"}, - {"BE_OUT", NULL, "RX_CDC_DMA_RX_3"}, - {"BE_OUT", NULL, "RX_CDC_DMA_RX_4"}, - {"BE_OUT", NULL, "RX_CDC_DMA_RX_5"}, - {"BE_OUT", NULL, "RX_CDC_DMA_RX_6"}, - {"BE_OUT", NULL, "RX_CDC_DMA_RX_7"}, - {"BE_OUT", NULL, "PROXY_RX"}, {"PRI_I2S_TX", NULL, "BE_IN"}, {"MI2S_TX", NULL, "BE_IN"}, @@ -29567,90 +30074,15 @@ static const struct snd_soc_dapm_route intercon[] = { {"INT5_MI2S_TX", NULL, "BE_IN"}, {"SEC_MI2S_TX", NULL, "BE_IN"}, {"SENARY_MI2S_TX", NULL, "BE_IN"}, - {"SLIMBUS_0_TX", NULL, "BE_IN" }, - {"SLIMBUS_1_TX", NULL, "BE_IN" }, - {"SLIMBUS_3_TX", NULL, "BE_IN" }, - {"SLIMBUS_4_TX", NULL, "BE_IN" }, - {"SLIMBUS_5_TX", NULL, "BE_IN" }, - {"SLIMBUS_6_TX", NULL, "BE_IN" }, - {"SLIMBUS_7_TX", NULL, "BE_IN" }, - {"SLIMBUS_8_TX", NULL, "BE_IN" }, - {"SLIMBUS_9_TX", NULL, "BE_IN" }, - {"USB_AUDIO_TX", NULL, "BE_IN" }, - {"INT_BT_SCO_TX", NULL, "BE_IN"}, - {"INT_FM_TX", NULL, "BE_IN"}, - {"PCM_TX", NULL, "BE_IN"}, - {"BE_OUT", NULL, "SLIMBUS_3_RX"}, - {"BE_OUT", NULL, "STUB_RX"}, - {"STUB_TX", NULL, "BE_IN"}, - {"STUB_1_TX", NULL, "BE_IN"}, - {"BE_OUT", NULL, "AUX_PCM_RX"}, - {"AUX_PCM_TX", NULL, "BE_IN"}, - {"SEC_AUX_PCM_TX", NULL, "BE_IN"}, - {"TERT_AUX_PCM_TX", NULL, "BE_IN"}, - {"QUAT_AUX_PCM_TX", NULL, "BE_IN"}, - {"QUIN_AUX_PCM_TX", NULL, "BE_IN"}, - {"SEN_AUX_PCM_TX", NULL, "BE_IN"}, - {"INCALL_RECORD_TX", NULL, "BE_IN"}, - {"INCALL_RECORD_RX", NULL, "BE_IN"}, - {"SLIM0_RX_VI_FB_LCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"}, - {"SLIM0_RX_VI_FB_RCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"}, - {"WSA_RX_0_VI_FB_LCH_MUX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, - {"WSA_RX_0_VI_FB_RCH_MUX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"PRI_MI2S_RX_VI_FB_MUX", "SENARY_TX", "SENARY_TX"}, {"INT4_MI2S_RX_VI_FB_MONO_CH_MUX", "INT5_MI2S_TX", "INT5_MI2S_TX"}, {"INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", "INT5_MI2S_TX", "INT5_MI2S_TX"}, - {"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_LCH_MUX"}, - {"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_RCH_MUX"}, - {"WSA_CDC_DMA_RX_0", NULL, "WSA_RX_0_VI_FB_LCH_MUX"}, - {"WSA_CDC_DMA_RX_0", NULL, "WSA_RX_0_VI_FB_RCH_MUX"}, {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_VI_FB_MUX"}, {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_MONO_CH_MUX"}, {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_STEREO_CH_MUX"}, - {"PRI_TDM_TX_0", NULL, "BE_IN"}, - {"PRI_TDM_TX_1", NULL, "BE_IN"}, - {"PRI_TDM_TX_2", NULL, "BE_IN"}, - {"PRI_TDM_TX_3", NULL, "BE_IN"}, - {"SEC_TDM_TX_0", NULL, "BE_IN"}, - {"SEC_TDM_TX_1", NULL, "BE_IN"}, - {"SEC_TDM_TX_2", NULL, "BE_IN"}, - {"SEC_TDM_TX_3", NULL, "BE_IN"}, - {"TERT_TDM_TX_0", NULL, "BE_IN"}, - {"TERT_TDM_TX_1", NULL, "BE_IN"}, - {"TERT_TDM_TX_2", NULL, "BE_IN"}, - {"TERT_TDM_TX_3", NULL, "BE_IN"}, - {"TERT_TDM_TX_7", NULL, "BE_IN"}, - {"QUAT_TDM_TX_0", NULL, "BE_IN"}, - {"QUAT_TDM_TX_1", NULL, "BE_IN"}, - {"QUAT_TDM_TX_2", NULL, "BE_IN"}, - {"QUAT_TDM_TX_3", NULL, "BE_IN"}, - {"QUAT_TDM_TX_7", NULL, "BE_IN"}, - {"AFE_LOOPBACK_TX", NULL, "BE_IN"}, - {"QUIN_TDM_TX_0", NULL, "BE_IN"}, - {"QUIN_TDM_TX_1", NULL, "BE_IN"}, - {"QUIN_TDM_TX_2", NULL, "BE_IN"}, - {"QUIN_TDM_TX_3", NULL, "BE_IN"}, - {"QUIN_TDM_TX_7", NULL, "BE_IN"}, - {"SEN_TDM_TX_0", NULL, "BE_IN"}, - {"SEN_TDM_TX_1", NULL, "BE_IN"}, - {"SEN_TDM_TX_2", NULL, "BE_IN"}, - {"SEN_TDM_TX_3", NULL, "BE_IN"}, - {"WSA_CDC_DMA_TX_0", NULL, "BE_IN"}, - {"WSA_CDC_DMA_TX_1", NULL, "BE_IN"}, - {"WSA_CDC_DMA_TX_2", NULL, "BE_IN"}, - {"VA_CDC_DMA_TX_0", NULL, "BE_IN"}, - {"VA_CDC_DMA_TX_1", NULL, "BE_IN"}, - {"VA_CDC_DMA_TX_2", NULL, "BE_IN"}, - {"TX_CDC_DMA_TX_0", NULL, "BE_IN"}, - {"TX_CDC_DMA_TX_1", NULL, "BE_IN"}, - {"TX_CDC_DMA_TX_2", NULL, "BE_IN"}, - {"TX_CDC_DMA_TX_3", NULL, "BE_IN"}, - {"TX_CDC_DMA_TX_4", NULL, "BE_IN"}, - {"TX_CDC_DMA_TX_5", NULL, "BE_IN"}, - {"PRI_SPDIF_TX", NULL, "BE_IN"}, - {"SEC_SPDIF_TX", NULL, "BE_IN"}, - {"PROXY_TX", NULL, "BE_IN"}, }; +#endif static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) @@ -30478,16 +30910,96 @@ void msm_routing_add_doa_control(struct snd_soc_component *component) } #endif +#ifndef CONFIG_TDM_DISABLE +static void snd_soc_dapm_new_controls_tdm(struct snd_soc_component *component) +{ + snd_soc_dapm_new_controls(&component->dapm, + msm_qdsp6_widgets_tdm, + ARRAY_SIZE(msm_qdsp6_widgets_tdm)); +} +static void snd_soc_dapm_add_routes_tdm(struct snd_soc_component *component) +{ + snd_soc_dapm_add_routes(&component->dapm, intercon_tdm, + ARRAY_SIZE(intercon_tdm)); +} +#else +static void snd_soc_dapm_new_controls_tdm(struct snd_soc_component *component) +{ + return; +} + +static void snd_soc_dapm_add_routes_tdm(struct snd_soc_component *component) +{ + return; +} +#endif + + +#ifndef CONFIG_MI2S_DISABLE +static void snd_soc_dapm_new_controls_mi2s(struct snd_soc_component *component) +{ + snd_soc_dapm_new_controls(&component->dapm, + msm_qdsp6_widgets_mi2s, + ARRAY_SIZE(msm_qdsp6_widgets_mi2s)); +} +static void snd_soc_dapm_add_routes_mi2s(struct snd_soc_component *component) +{ + snd_soc_dapm_add_routes(&component->dapm, intercon_mi2s, + ARRAY_SIZE(intercon_mi2s)); +} +#else +static void snd_soc_dapm_new_controls_mi2s(struct snd_soc_component *component) +{ + return; +} +static void snd_soc_dapm_add_routes_mi2s(struct snd_soc_component *component) +{ + return; +} +#endif + +#ifndef CONFIG_AUXPCM_DISABLE +static void snd_soc_dapm_new_controls_aux_pcm(struct snd_soc_component *component) +{ + snd_soc_dapm_new_controls(&component->dapm, + msm_qdsp6_widgets_aux_pcm, + ARRAY_SIZE(msm_qdsp6_widgets_aux_pcm)); +} +static void snd_soc_dapm_add_routes_aux_pcm(struct snd_soc_component *component) +{ + snd_soc_dapm_add_routes(&component->dapm, intercon_aux_pcm, + ARRAY_SIZE(intercon_aux_pcm)); +} +#else +static void snd_soc_dapm_new_controls_aux_pcm(struct snd_soc_component *component) +{ + return; +} +static void snd_soc_dapm_add_routes_aux_pcm(struct snd_soc_component *component) +{ + return; +} +#endif + /* Not used but frame seems to require it */ static int msm_routing_probe(struct snd_soc_component *component) { snd_soc_dapm_new_controls(&component->dapm, msm_qdsp6_widgets, ARRAY_SIZE(msm_qdsp6_widgets)); + + snd_soc_dapm_new_controls_tdm(component); + snd_soc_dapm_new_controls_mi2s(component); + snd_soc_dapm_new_controls_aux_pcm(component); + snd_soc_dapm_ignore_suspend(&component->dapm, "BE_OUT"); snd_soc_dapm_ignore_suspend(&component->dapm, "BE_IN"); snd_soc_dapm_add_routes(&component->dapm, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_add_routes_tdm(component); + snd_soc_dapm_add_routes_mi2s(component); + snd_soc_dapm_add_routes_aux_pcm(component); + snd_soc_dapm_new_widgets(component->dapm.card); snd_soc_add_component_controls(component, lsm_controls, -- GitLab From 76165e883b6ed7c412951357b36db54b962400e2 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Thu, 6 Aug 2020 11:59:13 +0530 Subject: [PATCH 1569/1645] config: kona: Disable MI2S, TDM and AUXPCM interfaces Disable MI2S, TDM and AUXPCM interfaces to avoid unnecessary registration of mixer controls and improve performance in loading mixer paths. Change-Id: Id0e37ee772ac10a84eb683a4f8736e7f6ff42fad Signed-off-by: Prasad Kumpatla --- config/konaauto.conf | 2 ++ config/konaautoconf.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/config/konaauto.conf b/config/konaauto.conf index 74ca2d48ea77..e88e51e96d99 100644 --- a/config/konaauto.conf +++ b/config/konaauto.conf @@ -37,3 +37,5 @@ export CONFIG_SND_SOC_KONA=m export CONFIG_SND_EVENT=m export CONFIG_VOICE_MHI=m export CONFIG_DIGITAL_CDC_RSC_MGR=m +export CONFIG_TDM_DISABLE=m +export CONFIG_AUXPCM_DISABLE=m diff --git a/config/konaautoconf.h b/config/konaautoconf.h index e489b41abd84..1a8038e3e5a3 100644 --- a/config/konaautoconf.h +++ b/config/konaautoconf.h @@ -41,3 +41,5 @@ #define CONFIG_SND_EVENT 1 #define CONFIG_VOICE_MHI 1 #define CONFIG_DIGITAL_CDC_RSC_MGR 1 +#define CONFIG_TDM_DISABLE 1 +#define CONFIG_AUXPCM_DISABLE 1 -- GitLab From 4a1d4552fd04aa38d83b6a127a15463752a14355 Mon Sep 17 00:00:00 2001 From: "Vangala, Amarnath" Date: Tue, 14 Jul 2020 03:39:52 +0530 Subject: [PATCH 1570/1645] asoc: dsp: Fix possible invalid memory access due to race condition Fix for possible double free issue in speaker protection implementation. Replace vulnerable code with safe call flow. Change-Id: Id96cf97dd60d85897d64f1d8f2440a5b6de3ba61 Signed-off-by: Vangala, Amarnath --- dsp/q6afe.c | 171 +++++++++++++++++++++++++++++----------------------- 1 file changed, 94 insertions(+), 77 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 0811d6c137f3..c9a5c95e4d29 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -26,6 +26,8 @@ #define WAKELOCK_TIMEOUT 5000 #define AFE_CLK_TOKEN 1024 +#define SP_V4_NUM_MAX_SPKRS SP_V2_NUM_MAX_SPKRS + struct afe_avcs_payload_port_mapping { u16 port_id; struct avcs_load_unload_modules_payload *payload; @@ -125,6 +127,46 @@ struct wlock { static struct wlock wl; +struct afe_sp_v4_th_vi_ftm_get_param_resp { + struct afe_sp_v4_gen_get_param_resp gen_resp; + int32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_ftm_params + ch_ftm_params[SP_V4_NUM_MAX_SPKRS]; +} __packed; + +struct afe_sp_v4_v_vali_get_param_resp { + struct afe_sp_v4_gen_get_param_resp gen_resp; + int32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_v_vali_params + ch_v_vali_params[SP_V4_NUM_MAX_SPKRS]; +} __packed; + +struct afe_sp_v4_ex_vi_ftm_get_param_resp { + struct afe_sp_v4_gen_get_param_resp gen_resp; + int32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_ex_vi_ftm_params + ch_ex_vi_ftm_params[SP_V4_NUM_MAX_SPKRS]; +} __packed; + +struct afe_sp_v4_max_log_get_param_resp { + struct afe_sp_v4_gen_get_param_resp gen_resp; + int32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_tmax_xmax_params + ch_max_params[SP_V4_NUM_MAX_SPKRS]; +} __packed; + struct afe_ctl { void *apr; atomic_t state; @@ -174,8 +216,14 @@ struct afe_ctl { struct afe_sp_rx_tmax_xmax_logging_resp xt_logging_resp; struct afe_sp_v4_th_vi_calib_resp spv4_calib_data; struct afe_sp_v4_param_vi_channel_map_cfg v4_ch_map_cfg; - struct afe_sp_v4_gen_get_param_resp *spv4_get_param_resp_ptr; - uint32_t spv4_rcvd_param_size; + struct afe_sp_v4_th_vi_ftm_get_param_resp spv4_th_vi_ftm_resp; + uint32_t spv4_th_vi_ftm_rcvd_param_size; + struct afe_sp_v4_v_vali_get_param_resp spv4_v_vali_resp; + uint32_t spv4_v_vali_rcvd_param_size; + struct afe_sp_v4_ex_vi_ftm_get_param_resp spv4_ex_vi_ftm_resp; + uint32_t spv4_ex_vi_ftm_rcvd_param_size; + struct afe_sp_v4_max_log_get_param_resp spv4_max_log_resp; + uint32_t spv4_max_log_rcvd_param_size; struct afe_av_dev_drift_get_param_resp av_dev_drift_resp; struct afe_doa_tracking_mon_get_param_resp doa_tracking_mon_resp; int vi_tx_port; @@ -656,27 +704,16 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, break; case AFE_PARAM_ID_SP_V4_TH_VI_FTM_PARAMS: num_ch = data_start[0]; - this_afe.spv4_rcvd_param_size = - sizeof(struct afe_sp_v4_gen_get_param_resp) + - sizeof(struct afe_sp_v4_param_th_vi_ftm_params) + - (num_ch * sizeof(struct afe_sp_v4_channel_ftm_params)); - this_afe.spv4_get_param_resp_ptr = - kzalloc(this_afe.spv4_rcvd_param_size, GFP_ATOMIC); - data_dest = (u32 *)this_afe.spv4_get_param_resp_ptr; + this_afe.spv4_th_vi_ftm_rcvd_param_size = param_hdr.param_size; + data_dest = (u32 *)&this_afe.spv4_th_vi_ftm_resp; expected_size += sizeof(struct afe_sp_v4_param_th_vi_ftm_params) + (num_ch * sizeof(struct afe_sp_v4_channel_ftm_params)); break; case AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_PARAMS: num_ch = data_start[0]; - this_afe.spv4_rcvd_param_size = - sizeof(struct afe_sp_v4_gen_get_param_resp) + - sizeof(struct afe_sp_v4_param_th_vi_v_vali_params) + - (num_ch * - sizeof(struct afe_sp_v4_channel_v_vali_params)); - this_afe.spv4_get_param_resp_ptr = - kzalloc(this_afe.spv4_rcvd_param_size, GFP_ATOMIC); - data_dest = (u32 *)this_afe.spv4_get_param_resp_ptr; + this_afe.spv4_v_vali_rcvd_param_size = param_hdr.param_size; + data_dest = (u32 *)&this_afe.spv4_v_vali_resp; expected_size += sizeof(struct afe_sp_v4_param_th_vi_v_vali_params) + (num_ch * @@ -684,29 +721,19 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, break; case AFE_PARAM_ID_SP_V4_EX_VI_FTM_PARAMS: num_ch = data_start[0]; - this_afe.spv4_rcvd_param_size = - sizeof(struct afe_sp_v4_gen_get_param_resp) + - sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) + - (num_ch * sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params)); - this_afe.spv4_get_param_resp_ptr = - kzalloc(this_afe.spv4_rcvd_param_size, GFP_ATOMIC); - data_dest = (u32 *)this_afe.spv4_get_param_resp_ptr; + this_afe.spv4_ex_vi_ftm_rcvd_param_size = param_hdr.param_size; + data_dest = (u32 *)&this_afe.spv4_ex_vi_ftm_resp; expected_size += - sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) + - (num_ch * sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params)); + sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) + + (num_ch * sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params)); break; case AFE_PARAM_ID_SP_V4_RX_TMAX_XMAX_LOGGING: num_ch = data_start[0]; - this_afe.spv4_rcvd_param_size = - sizeof(struct afe_sp_v4_gen_get_param_resp) + - sizeof(struct afe_sp_v4_param_tmax_xmax_logging) + - (num_ch * sizeof(struct afe_sp_v4_channel_tmax_xmax_params)); - this_afe.spv4_get_param_resp_ptr = - kzalloc(this_afe.spv4_rcvd_param_size, GFP_ATOMIC); - data_dest = (u32 *)this_afe.spv4_get_param_resp_ptr; + this_afe.spv4_max_log_rcvd_param_size = param_hdr.param_size; + data_dest = (u32 *)&this_afe.spv4_max_log_resp; expected_size += - sizeof(struct afe_sp_v4_param_tmax_xmax_logging) + - (num_ch * sizeof(struct afe_sp_v4_channel_tmax_xmax_params)); + sizeof(struct afe_sp_v4_param_tmax_xmax_logging) + + (num_ch * sizeof(struct afe_sp_v4_channel_tmax_xmax_params)); break; default: pr_err("%s: Unrecognized param ID %d\n", __func__, @@ -8920,8 +8947,8 @@ static int afe_get_spv4_th_vi_v_vali_data(void *params, uint32_t size) struct param_hdr_v3 param_hdr; int port = SLIMBUS_4_TX; int ret = -EINVAL; - u8 *rcvd_params = NULL; - struct afe_sp_v4_channel_v_vali_params *v_vali_params; + uint32_t min_size = 0; + struct afe_sp_v4_channel_v_vali_params *v_vali_params = NULL; if (!params) { pr_err("%s: Invalid params\n", __func__); @@ -8944,14 +8971,14 @@ static int afe_get_spv4_th_vi_v_vali_data(void *params, uint32_t size) goto get_params_fail; } - rcvd_params = (u8 *)this_afe.spv4_get_param_resp_ptr + - sizeof(struct afe_sp_v4_gen_get_param_resp); + min_size = (size < this_afe.spv4_v_vali_rcvd_param_size) ? + size : this_afe.spv4_v_vali_rcvd_param_size; + memcpy(params, (void*)&this_afe.spv4_v_vali_resp.num_ch, min_size); - memcpy(params, rcvd_params, this_afe.spv4_rcvd_param_size); + v_vali_params = &this_afe.spv4_v_vali_resp.ch_v_vali_params[0]; - v_vali_params = (struct afe_sp_v4_channel_v_vali_params *) - (params + sizeof(struct afe_sp_v4_param_th_vi_v_vali_params)); - pr_debug("%s: Vrms %d %d status %d %d\n", __func__, + pr_debug("%s: num_ch %d Vrms %d %d status %d %d\n", __func__, + this_afe.spv4_v_vali_resp.num_ch, v_vali_params[SP_V2_SPKR_1].vrms_q24, v_vali_params[SP_V2_SPKR_2].vrms_q24, v_vali_params[SP_V2_SPKR_1].status, @@ -8965,7 +8992,6 @@ static int afe_get_spv4_th_vi_v_vali_data(void *params, uint32_t size) ret = 0; get_params_fail: - kfree(this_afe.spv4_get_param_resp_ptr); mutex_unlock(&this_afe.afe_cmd_lock); done: return ret; @@ -9019,7 +9045,7 @@ static int afe_get_spv4_th_vi_ftm_data(void *params, uint32_t size) struct param_hdr_v3 param_hdr; int port = SLIMBUS_4_TX; int ret = -EINVAL; - u8 *rcvd_params = NULL; + uint32_t min_size = 0; struct afe_sp_v4_channel_ftm_params *th_vi_params; if (!params) { @@ -9043,22 +9069,21 @@ static int afe_get_spv4_th_vi_ftm_data(void *params, uint32_t size) goto get_params_fail; } - rcvd_params = (u8 *)this_afe.spv4_get_param_resp_ptr + - sizeof(struct afe_sp_v4_gen_get_param_resp); - memcpy(params, rcvd_params, this_afe.spv4_rcvd_param_size); + min_size = (size < this_afe.spv4_th_vi_ftm_rcvd_param_size) ? + size : this_afe.spv4_th_vi_ftm_rcvd_param_size; + memcpy(params, (void*)&this_afe.spv4_th_vi_ftm_resp.num_ch, min_size); - th_vi_params = (struct afe_sp_v4_channel_ftm_params *) - (params + sizeof(struct afe_sp_v4_param_th_vi_ftm_params)); - pr_debug("%s: DC resistance %d %d temp %d %d status %d %d\n", - __func__, th_vi_params[SP_V2_SPKR_1].dc_res_q24, - th_vi_params[SP_V2_SPKR_2].dc_res_q24, - th_vi_params[SP_V2_SPKR_1].temp_q22, - th_vi_params[SP_V2_SPKR_2].temp_q22, - th_vi_params[SP_V2_SPKR_1].status, - th_vi_params[SP_V2_SPKR_2].status); + th_vi_params = &this_afe.spv4_th_vi_ftm_resp.ch_ftm_params[0]; + pr_debug("%s:num_ch %d, DC resistance %d %d temp %d %d status %d %d\n", + __func__, this_afe.spv4_th_vi_ftm_resp.num_ch, + th_vi_params[SP_V2_SPKR_1].dc_res_q24, + th_vi_params[SP_V2_SPKR_2].dc_res_q24, + th_vi_params[SP_V2_SPKR_1].temp_q22, + th_vi_params[SP_V2_SPKR_2].temp_q22, + th_vi_params[SP_V2_SPKR_1].status, + th_vi_params[SP_V2_SPKR_2].status); ret = 0; get_params_fail: - kfree(this_afe.spv4_get_param_resp_ptr); mutex_unlock(&this_afe.afe_cmd_lock); done: return ret; @@ -9113,7 +9138,7 @@ static int afe_get_spv4_ex_vi_ftm_data(void *params, uint32_t size) struct param_hdr_v3 param_hdr; int port = SLIMBUS_4_TX; int ret = -EINVAL; - u8 *rcvd_params = NULL; + uint32_t min_size = 0; struct afe_sp_v4_channel_ex_vi_ftm_params *ex_vi_ftm_param; if (!params) { @@ -9138,17 +9163,16 @@ static int afe_get_spv4_ex_vi_ftm_data(void *params, uint32_t size) goto get_params_fail; } - rcvd_params = (u8 *)this_afe.spv4_get_param_resp_ptr + - sizeof(struct afe_sp_v4_gen_get_param_resp); + min_size = (size < this_afe.spv4_ex_vi_ftm_rcvd_param_size) ? + size : this_afe.spv4_ex_vi_ftm_rcvd_param_size; + memcpy(params, (void*)&this_afe.spv4_ex_vi_ftm_resp.num_ch, min_size); - memcpy(params, rcvd_params, this_afe.spv4_rcvd_param_size); + ex_vi_ftm_param = &this_afe.spv4_ex_vi_ftm_resp.ch_ex_vi_ftm_params[0]; - ex_vi_ftm_param = (struct afe_sp_v4_channel_ex_vi_ftm_params *) - (params + sizeof(struct afe_sp_v4_param_ex_vi_ftm_params)); - - pr_debug("%s: resistance %d %d force factor %d %d Damping kg/s %d %d\n" + pr_debug("%s:num_ch %d, res %d %d forcefactor %d %d Dmping kg/s %d %d\n" "stiffness N/mm %d %d freq %d %d Qfactor %d %d status %d %d", - __func__, ex_vi_ftm_param[SP_V2_SPKR_1].ftm_re_q24, + __func__, this_afe.spv4_ex_vi_ftm_resp.num_ch, + ex_vi_ftm_param[SP_V2_SPKR_1].ftm_re_q24, ex_vi_ftm_param[SP_V2_SPKR_2].ftm_re_q24, ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Bl_q24, ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Bl_q24, @@ -9164,7 +9188,6 @@ static int afe_get_spv4_ex_vi_ftm_data(void *params, uint32_t size) ex_vi_ftm_param[SP_V2_SPKR_2].status); ret = 0; get_params_fail: - kfree(this_afe.spv4_get_param_resp_ptr); mutex_unlock(&this_afe.afe_cmd_lock); done: return ret; @@ -9223,7 +9246,6 @@ int afe_get_sp_v4_rx_tmax_xmax_logging_data( { struct param_hdr_v3 param_hdr; int ret = -EINVAL; - struct afe_sp_v4_param_tmax_xmax_logging *tmax_xmax_logging; struct afe_sp_v4_channel_tmax_xmax_params *tx_channel_params; uint32_t i, size = 0; @@ -9248,13 +9270,9 @@ int afe_get_sp_v4_rx_tmax_xmax_logging_data( goto get_params_fail; } - tmax_xmax_logging = (struct afe_sp_v4_param_tmax_xmax_logging *) - ((u8 *)this_afe.spv4_get_param_resp_ptr + - sizeof(struct afe_sp_v4_gen_get_param_resp)); - tx_channel_params = (struct afe_sp_v4_channel_tmax_xmax_params *) - ((u8 *)tmax_xmax_logging + - sizeof(struct afe_sp_v4_param_tmax_xmax_logging)); - for (i = 0; i < tmax_xmax_logging->num_ch; i++) { + tx_channel_params = &this_afe.spv4_max_log_resp.ch_max_params[0]; + for (i = 0; i < this_afe.spv4_max_log_resp.num_ch; i++) { + xt_logging->max_excursion[i] = tx_channel_params[i].max_excursion; xt_logging->count_exceeded_excursion[i] = @@ -9267,7 +9285,6 @@ int afe_get_sp_v4_rx_tmax_xmax_logging_data( ret = 0; get_params_fail: - kfree(this_afe.spv4_get_param_resp_ptr); done: return ret; } -- GitLab From aed50c37842d6c4c30b29da23ad78bf06c4e3db4 Mon Sep 17 00:00:00 2001 From: Harshal Ahire Date: Tue, 7 Jul 2020 15:45:49 +0530 Subject: [PATCH 1571/1645] dsp: Add support for GET_PARAMS Add support to query module parameters from ADSP. Change-Id: Ie63dd95cf27277f9c836becc98952d48971a3ec3 Signed-off-by: Harshal Ahire --- asoc/msm-lsm-client.c | 177 ++++++++++++++++++++++++++++++++ dsp/q6lsm.c | 147 ++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 4 + include/dsp/q6lsm.h | 17 +++ include/uapi/sound/lsm_params.h | 29 +++++- 5 files changed, 372 insertions(+), 2 deletions(-) diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index 8a179fde913a..77b25de138c1 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -1700,6 +1700,17 @@ struct lsm_params_info_v2_32 { u16 stage_idx; }; +struct lsm_params_get_info_32 { + u32 module_id; + u16 instance_id; + u16 reserved; + u32 param_id; + u32 param_size; + uint32_t param_type; + __u16 stage_idx; + u8 payload[0]; +} __packed; + struct snd_lsm_module_params_32 { compat_uptr_t params; u32 num_params; @@ -1717,6 +1728,8 @@ enum { _IOW('U', 0x0F, struct snd_lsm_event_status_v3_32), SNDRV_LSM_SET_MODULE_PARAMS_V2_32 = _IOW('U', 0x13, struct snd_lsm_module_params_32), + SNDRV_LSM_GET_MODULE_PARAMS_32 = + _IOWR('U', 0x14, struct lsm_params_get_info_32), }; static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, @@ -2096,6 +2109,95 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, kfree(params32); break; } + case SNDRV_LSM_GET_MODULE_PARAMS_32: { + struct lsm_params_get_info_32 p_info_32, *param_info_rsp = NULL; + struct lsm_params_get_info *p_info = NULL; + + memset(&p_info_32, 0 , sizeof(p_info_32)); + if (!prtd->lsm_client->use_topology) { + dev_err(rtd->dev, + "%s: %s: not supported if not using topology\n", + __func__, "GET_MODULE_PARAMS_32"); + err = -EINVAL; + goto done; + } + + if (copy_from_user(&p_info_32, arg, sizeof(p_info_32))) { + dev_err(rtd->dev, + "%s: %s: copy_from_user failed, size = %zd\n", + __func__, "GET_MODULE_PARAMS_32", + sizeof(p_info_32)); + err = -EFAULT; + goto done; + } + size = sizeof(p_info_32); + p_info = kzalloc(size, GFP_KERNEL); + + if (!p_info) { + err = -ENOMEM; + goto done; + } + + p_info->module_id = p_info_32.module_id; + p_info->param_id = p_info_32.param_id; + p_info->param_size = p_info_32.param_size; + p_info->param_type = p_info_32.param_type; + p_info->instance_id = p_info_32.instance_id; + p_info->stage_idx = p_info_32.stage_idx; + + prtd->lsm_client->get_param_payload = kzalloc(p_info_32.param_size, + GFP_KERNEL); + if (!prtd->lsm_client->get_param_payload) { + err = -ENOMEM; + kfree(p_info); + goto done; + } + prtd->lsm_client->param_size = p_info_32.param_size; + + err = q6lsm_get_one_param(prtd->lsm_client, p_info, + LSM_GET_CUSTOM_PARAMS); + if (err) { + dev_err(rtd->dev, + "%s: Failed to get custom param, err=%d\n", + __func__, err); + kfree(p_info); + kfree(prtd->lsm_client->get_param_payload); + goto done; + } + + size = sizeof(p_info_32) + p_info_32.param_size; + param_info_rsp = kzalloc(size, GFP_KERNEL); + + if (!param_info_rsp) { + err = -ENOMEM; + kfree(p_info); + kfree(prtd->lsm_client->get_param_payload); + goto done; + } + + if (!access_ok(VERIFY_WRITE, arg, size)) { + dev_err(rtd->dev, + "%s: Failed to verify write, size = %d\n", + __func__, size); + err = -EFAULT; + goto free; + } + + memcpy(param_info_rsp, &p_info_32, sizeof(p_info_32)); + memcpy(param_info_rsp->payload, prtd->lsm_client->get_param_payload, + p_info_32.param_size); + + if (copy_to_user(arg, param_info_rsp, size)) { + dev_err(rtd->dev, "%s: Failed to copy payload to user, size = %d\n", + __func__, size); + err = -EFAULT; + } +free: + kfree(p_info); + kfree(param_info_rsp); + kfree(prtd->lsm_client->get_param_payload); + break; + } case SNDRV_LSM_REG_SND_MODEL_V2: case SNDRV_LSM_SET_PARAMS: case SNDRV_LSM_SET_MODULE_PARAMS: @@ -2303,6 +2405,81 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, break; } + case SNDRV_LSM_GET_MODULE_PARAMS: { + struct lsm_params_get_info temp_p_info, *p_info = NULL; + + memset(&temp_p_info, 0, sizeof(temp_p_info)); + if (!prtd->lsm_client->use_topology) { + dev_err(rtd->dev, + "%s: %s: not supported if not using topology\n", + __func__, "GET_MODULE_PARAMS_32"); + err = -EINVAL; + goto done; + } + + if (copy_from_user(&temp_p_info, arg, sizeof(temp_p_info))) { + dev_err(rtd->dev, + "%s: %s: copy_from_user failed, size = %zd\n", + __func__, "GET_MODULE_PARAMS_32", + sizeof(temp_p_info)); + err = -EFAULT; + goto done; + } + size = sizeof(temp_p_info) + temp_p_info.param_size; + p_info = kzalloc(size, GFP_KERNEL); + + if (!p_info) { + err = -ENOMEM; + goto done; + } + + p_info->module_id = temp_p_info.module_id; + p_info->param_id = temp_p_info.param_id; + p_info->param_size = temp_p_info.param_size; + p_info->param_type = temp_p_info.param_type; + p_info->instance_id = temp_p_info.instance_id; + p_info->stage_idx = temp_p_info.stage_idx; + + prtd->lsm_client->get_param_payload = kzalloc(temp_p_info.param_size, + GFP_KERNEL); + if (!prtd->lsm_client->get_param_payload) { + err = -ENOMEM; + kfree(p_info); + goto done; + } + + prtd->lsm_client->param_size = p_info->param_size; + err = q6lsm_get_one_param(prtd->lsm_client, p_info, + LSM_GET_CUSTOM_PARAMS); + if (err) { + dev_err(rtd->dev, + "%s: Failed to get custom param, err=%d\n", + __func__, err); + goto free; + } + + if (!access_ok(VERIFY_WRITE, arg, size)) { + dev_err(rtd->dev, + "%s: Failed to verify write, size = %d\n", + __func__, size); + err = -EFAULT; + goto free; + } + + memcpy(p_info->payload, prtd->lsm_client->get_param_payload, + temp_p_info.param_size); + + if (copy_to_user(arg, p_info, sizeof(struct lsm_params_get_info) + + p_info->param_size)) { + dev_err(rtd->dev, "%s: Failed to copy payload to user, size = %d\n", + __func__, size); + err = -EFAULT; + } +free: + kfree(p_info); + kfree(prtd->lsm_client->get_param_payload); + break; + } case SNDRV_LSM_EVENT_STATUS: case SNDRV_LSM_GENERIC_DET_EVENT: { struct snd_lsm_event_status *user = NULL; diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index c00bb9406833..cc57a25361a6 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -190,6 +190,58 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) client->priv); spin_unlock_irqrestore(&lsm_session_lock, flags); return 0; + } else if (data->opcode == LSM_SESSION_CMDRSP_GET_PARAMS_V3 || + data->opcode == LSM_SESSION_CMDRSP_GET_PARAMS_V2) { + + uint32_t payload_min_size_expected = 0; + uint32_t param_size = 0, ret = 0; + /* + * sizeof(uint32_t) is added to accomodate the status field + * in adsp response payload + */ + + if (data->opcode == LSM_SESSION_CMDRSP_GET_PARAMS_V3) + payload_min_size_expected = sizeof(uint32_t) + + sizeof(struct param_hdr_v3); + else + payload_min_size_expected = sizeof(uint32_t) + + sizeof(struct param_hdr_v2); + + if (data->payload_size < payload_min_size_expected) { + pr_err("%s: invalid payload size %d expected size %d\n", + __func__, data->payload_size, + payload_min_size_expected); + ret = -EINVAL; + goto done; + } + + if (data->opcode == LSM_SESSION_CMDRSP_GET_PARAMS_V3) + param_size = payload[4]; + else + param_size = payload[3]; + + if (data->payload_size != payload_min_size_expected + param_size) { + pr_err("%s: cmdrsp_get_params error payload size %d expected size %d\n", + __func__, data->payload_size, + payload_min_size_expected + param_size); + ret = -EINVAL; + goto done; + } + + if (client->param_size != param_size) { + pr_err("%s: response payload size %d mismatched with user requested %d\n", + __func__, param_size, client->param_size); + ret = -EINVAL; + goto done; + } + + memcpy((u8 *)client->get_param_payload, + (u8 *)payload + payload_min_size_expected, param_size); +done: + spin_unlock_irqrestore(&lsm_session_lock, flags); + atomic_set(&client->cmd_state, CMD_STATE_CLEARED); + wake_up(&client->cmd_wait); + return ret; } else if (data->opcode == APR_BASIC_RSP_RESULT) { token = data->token; switch (payload[0]) { @@ -208,6 +260,8 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) case LSM_CMD_ADD_TOPOLOGIES: case LSM_SESSION_CMD_SET_PARAMS_V2: case LSM_SESSION_CMD_SET_PARAMS_V3: + case LSM_SESSION_CMD_GET_PARAMS_V2: + case LSM_SESSION_CMD_GET_PARAMS_V3: if (token != client->session && payload[0] != LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL) { @@ -623,6 +677,48 @@ static int q6lsm_set_params_v3(struct lsm_client *client, return ret; } +static int q6lsm_get_params_v2(struct lsm_client *client, + struct mem_mapping_hdr *mem_hdr, + struct param_hdr_v2 *param_hdr) +{ + struct lsm_session_cmd_get_params_v2 lsm_get_param; + uint16_t pkt_size = sizeof(lsm_get_param); + + memset(&lsm_get_param, 0, pkt_size); + q6lsm_add_hdr(client, &lsm_get_param.apr_hdr, pkt_size, true); + lsm_get_param.apr_hdr.opcode = LSM_SESSION_CMD_GET_PARAMS_V2; + + if (mem_hdr != NULL) + lsm_get_param.mem_hdr = *mem_hdr; + + memcpy(&lsm_get_param.param_info, param_hdr, + sizeof(struct param_hdr_v2)); + + return q6lsm_apr_send_pkt(client, client->apr, &lsm_get_param, true, + NULL); +} + +static int q6lsm_get_params_v3(struct lsm_client *client, + struct mem_mapping_hdr *mem_hdr, + struct param_hdr_v3 *param_hdr) +{ + struct lsm_session_cmd_get_params_v3 lsm_get_param; + uint16_t pkt_size = sizeof(lsm_get_param); + + memset(&lsm_get_param, 0, pkt_size); + q6lsm_add_hdr(client, &lsm_get_param.apr_hdr, pkt_size, true); + lsm_get_param.apr_hdr.opcode = LSM_SESSION_CMD_GET_PARAMS_V3; + + if (mem_hdr != NULL) + lsm_get_param.mem_hdr = *mem_hdr; + + memcpy(&lsm_get_param.param_info, param_hdr, + sizeof(struct param_hdr_v3)); + + return q6lsm_apr_send_pkt(client, client->apr, &lsm_get_param, true, + NULL); +} + static int q6lsm_set_params(struct lsm_client *client, struct mem_mapping_hdr *mem_hdr, uint8_t *param_data, uint32_t param_size, @@ -665,6 +761,27 @@ static int q6lsm_pack_and_set_params(struct lsm_client *client, return ret; } +static int q6lsm_get_params(struct lsm_client *client, + struct mem_mapping_hdr *mem_hdr, + struct param_hdr_v3 *param_info) + +{ + struct param_hdr_v2 param_info_v2; + int ret = 0; + bool iid_supported = q6common_is_instance_id_supported(); + memset(¶m_info_v2, 0, sizeof(struct param_hdr_v2)); + + if (iid_supported) + ret = q6lsm_get_params_v3(client, mem_hdr, param_info); + else { + param_info_v2.module_id = param_info->module_id; + param_info_v2.param_id = param_info->param_id; + param_info_v2.param_size = param_info->param_size; + ret = q6lsm_get_params_v2(client, mem_hdr, ¶m_info_v2); + } + return ret; +} + static int q6lsm_send_custom_topologies(struct lsm_client *client) { int rc; @@ -2313,6 +2430,36 @@ int q6lsm_set_one_param(struct lsm_client *client, } EXPORT_SYMBOL(q6lsm_set_one_param); +int q6lsm_get_one_param(struct lsm_client *client, + struct lsm_params_get_info *p_info, + uint32_t param_type) +{ + struct param_hdr_v3 param_info; + int rc = 0; + + memset(¶m_info, 0, sizeof(param_info)); + + switch (param_type) { + case LSM_GET_CUSTOM_PARAMS: { + param_info.module_id = p_info->module_id; + param_info.instance_id = p_info->instance_id; + param_info.param_id = p_info->param_id; + param_info.param_size = p_info->param_size + sizeof(param_info); + rc = q6lsm_get_params(client, NULL, ¶m_info); + if (rc) { + pr_err("%s: LSM_GET_CUSTOM_PARAMS failed, rc %d\n", + __func__, rc); + } + break; + + } + default: + pr_err("%s: wrong param_type 0x%x\n", + __func__, p_info->param_type); + } + return rc; +} +EXPORT_SYMBOL(q6lsm_get_one_param); /** * q6lsm_start - diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 607b9101c886..eed5652f910e 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -11694,6 +11694,10 @@ struct avcs_fwk_ver_info { #define LSM_SESSION_CMD_SET_PARAMS (0x00012A83) #define LSM_SESSION_CMD_SET_PARAMS_V2 (0x00012A8F) #define LSM_SESSION_CMD_SET_PARAMS_V3 (0x00012A92) +#define LSM_SESSION_CMD_GET_PARAMS_V2 (0x00012A90) +#define LSM_SESSION_CMDRSP_GET_PARAMS_V2 (0x00012A91) +#define LSM_SESSION_CMD_GET_PARAMS_V3 (0x00012A93) +#define LSM_SESSION_CMDRSP_GET_PARAMS_V3 (0x00012A94) #define LSM_SESSION_CMD_REGISTER_SOUND_MODEL (0x00012A84) #define LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL (0x00012A85) #define LSM_SESSION_CMD_START (0x00012A86) diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h index 02897d98e06d..d5d6ad63b164 100644 --- a/include/dsp/q6lsm.h +++ b/include/dsp/q6lsm.h @@ -106,6 +106,8 @@ struct lsm_client { struct lsm_stage_config stage_cfg[LSM_MAX_STAGES_PER_SESSION]; uint64_t fe_id; uint16_t unprocessed_data; + void *get_param_payload; + size_t param_size; }; struct lsm_stream_cmd_open_tx { @@ -153,6 +155,18 @@ struct lsm_session_cmd_set_params_v3 { u32 param_data[0]; } __packed; +struct lsm_session_cmd_get_params_v2 { + struct apr_hdr apr_hdr; + struct mem_mapping_hdr mem_hdr; + struct param_hdr_v2 param_info; +} __packed; + +struct lsm_session_cmd_get_params_v3 { + struct apr_hdr apr_hdr; + struct mem_mapping_hdr mem_hdr; + struct param_hdr_v3 param_info; +} __packed; + struct lsm_param_op_mode { uint32_t minor_version; uint16_t mode; @@ -289,6 +303,9 @@ int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc); int q6lsm_set_one_param(struct lsm_client *client, struct lsm_params_info_v2 *p_info, void *data, uint32_t param_type); +int q6lsm_get_one_param(struct lsm_client *client, + struct lsm_params_get_info *p_info, + uint32_t param_type); void q6lsm_sm_set_param_data(struct lsm_client *client, struct lsm_params_info_v2 *p_info, size_t *offset); diff --git a/include/uapi/sound/lsm_params.h b/include/uapi/sound/lsm_params.h index 57dc3be5d454..8e1a3d6bbf53 100644 --- a/include/uapi/sound/lsm_params.h +++ b/include/uapi/sound/lsm_params.h @@ -34,7 +34,8 @@ #define LSM_POLLING_ENABLE (7) #define LSM_DET_EVENT_TYPE (8) #define LSM_LAB_CONTROL (9) -#define LSM_PARAMS_MAX (LSM_LAB_CONTROL + 1) +#define LSM_GET_CUSTOM_PARAMS (10) +#define LSM_PARAMS_MAX (LSM_GET_CUSTOM_PARAMS + 1) #define LSM_EVENT_NON_TIME_STAMP_MODE (0) #define LSM_EVENT_TIME_STAMP_MODE (1) @@ -284,6 +285,29 @@ struct snd_lsm_input_hw_params { __u16 num_channels; } __packed; +/* + * Param get info for each parameter type + * add "for SNDRV_LSM_GET_MODULE_PARAMS ioctl" + * Existing member variables: + * @module_id: Module to which parameter is to be set + * @instance_id: instance id of the param to which parameter is to be set + * @param_id: Parameter that is to be set + * @param_size: size of requested param + * @param_type: Parameter type as defined in values upto LSM_PARAMS_MAX + * @stage_idx: detection stage for which the param is applicable + * @payload: memory where requested param info will be populated + */ +struct lsm_params_get_info { + __u32 module_id; + __u16 instance_id; + __u16 reserved; + __u32 param_id; + __u32 param_size; + uint32_t param_type; + __u16 stage_idx; + __u8 payload[0]; +} __packed; + #define SNDRV_LSM_DEREG_SND_MODEL _IOW('U', 0x01, int) #define SNDRV_LSM_EVENT_STATUS _IOW('U', 0x02, struct snd_lsm_event_status) #define SNDRV_LSM_ABORT_EVENT _IOW('U', 0x03, int) @@ -311,5 +335,6 @@ struct snd_lsm_input_hw_params { struct snd_lsm_session_data_v2) #define SNDRV_LSM_SET_MODULE_PARAMS_V2 _IOW('U', 0x13, \ struct snd_lsm_module_params) - +#define SNDRV_LSM_GET_MODULE_PARAMS _IOWR('U', 0x14, \ + struct lsm_params_get_info) #endif -- GitLab From e1815843066bf82ac90eec43082478eef557dad1 Mon Sep 17 00:00:00 2001 From: "Vangala, Amarnath" Date: Tue, 14 Jul 2020 03:39:52 +0530 Subject: [PATCH 1572/1645] asoc: dsp: Fix possible invalid memory access due to race condition Fix for possible double free issue in speaker protection implementation. Replace vulnerable code with safe call flow. Change-Id: Id96cf97dd60d85897d64f1d8f2440a5b6de3ba61 Signed-off-by: Vangala, Amarnath --- dsp/q6afe.c | 171 +++++++++++++++++++++++++++++----------------------- 1 file changed, 94 insertions(+), 77 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 0811d6c137f3..c9a5c95e4d29 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -26,6 +26,8 @@ #define WAKELOCK_TIMEOUT 5000 #define AFE_CLK_TOKEN 1024 +#define SP_V4_NUM_MAX_SPKRS SP_V2_NUM_MAX_SPKRS + struct afe_avcs_payload_port_mapping { u16 port_id; struct avcs_load_unload_modules_payload *payload; @@ -125,6 +127,46 @@ struct wlock { static struct wlock wl; +struct afe_sp_v4_th_vi_ftm_get_param_resp { + struct afe_sp_v4_gen_get_param_resp gen_resp; + int32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_ftm_params + ch_ftm_params[SP_V4_NUM_MAX_SPKRS]; +} __packed; + +struct afe_sp_v4_v_vali_get_param_resp { + struct afe_sp_v4_gen_get_param_resp gen_resp; + int32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_v_vali_params + ch_v_vali_params[SP_V4_NUM_MAX_SPKRS]; +} __packed; + +struct afe_sp_v4_ex_vi_ftm_get_param_resp { + struct afe_sp_v4_gen_get_param_resp gen_resp; + int32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_ex_vi_ftm_params + ch_ex_vi_ftm_params[SP_V4_NUM_MAX_SPKRS]; +} __packed; + +struct afe_sp_v4_max_log_get_param_resp { + struct afe_sp_v4_gen_get_param_resp gen_resp; + int32_t num_ch; + /* Number of channels for Rx signal. + */ + + struct afe_sp_v4_channel_tmax_xmax_params + ch_max_params[SP_V4_NUM_MAX_SPKRS]; +} __packed; + struct afe_ctl { void *apr; atomic_t state; @@ -174,8 +216,14 @@ struct afe_ctl { struct afe_sp_rx_tmax_xmax_logging_resp xt_logging_resp; struct afe_sp_v4_th_vi_calib_resp spv4_calib_data; struct afe_sp_v4_param_vi_channel_map_cfg v4_ch_map_cfg; - struct afe_sp_v4_gen_get_param_resp *spv4_get_param_resp_ptr; - uint32_t spv4_rcvd_param_size; + struct afe_sp_v4_th_vi_ftm_get_param_resp spv4_th_vi_ftm_resp; + uint32_t spv4_th_vi_ftm_rcvd_param_size; + struct afe_sp_v4_v_vali_get_param_resp spv4_v_vali_resp; + uint32_t spv4_v_vali_rcvd_param_size; + struct afe_sp_v4_ex_vi_ftm_get_param_resp spv4_ex_vi_ftm_resp; + uint32_t spv4_ex_vi_ftm_rcvd_param_size; + struct afe_sp_v4_max_log_get_param_resp spv4_max_log_resp; + uint32_t spv4_max_log_rcvd_param_size; struct afe_av_dev_drift_get_param_resp av_dev_drift_resp; struct afe_doa_tracking_mon_get_param_resp doa_tracking_mon_resp; int vi_tx_port; @@ -656,27 +704,16 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, break; case AFE_PARAM_ID_SP_V4_TH_VI_FTM_PARAMS: num_ch = data_start[0]; - this_afe.spv4_rcvd_param_size = - sizeof(struct afe_sp_v4_gen_get_param_resp) + - sizeof(struct afe_sp_v4_param_th_vi_ftm_params) + - (num_ch * sizeof(struct afe_sp_v4_channel_ftm_params)); - this_afe.spv4_get_param_resp_ptr = - kzalloc(this_afe.spv4_rcvd_param_size, GFP_ATOMIC); - data_dest = (u32 *)this_afe.spv4_get_param_resp_ptr; + this_afe.spv4_th_vi_ftm_rcvd_param_size = param_hdr.param_size; + data_dest = (u32 *)&this_afe.spv4_th_vi_ftm_resp; expected_size += sizeof(struct afe_sp_v4_param_th_vi_ftm_params) + (num_ch * sizeof(struct afe_sp_v4_channel_ftm_params)); break; case AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_PARAMS: num_ch = data_start[0]; - this_afe.spv4_rcvd_param_size = - sizeof(struct afe_sp_v4_gen_get_param_resp) + - sizeof(struct afe_sp_v4_param_th_vi_v_vali_params) + - (num_ch * - sizeof(struct afe_sp_v4_channel_v_vali_params)); - this_afe.spv4_get_param_resp_ptr = - kzalloc(this_afe.spv4_rcvd_param_size, GFP_ATOMIC); - data_dest = (u32 *)this_afe.spv4_get_param_resp_ptr; + this_afe.spv4_v_vali_rcvd_param_size = param_hdr.param_size; + data_dest = (u32 *)&this_afe.spv4_v_vali_resp; expected_size += sizeof(struct afe_sp_v4_param_th_vi_v_vali_params) + (num_ch * @@ -684,29 +721,19 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, break; case AFE_PARAM_ID_SP_V4_EX_VI_FTM_PARAMS: num_ch = data_start[0]; - this_afe.spv4_rcvd_param_size = - sizeof(struct afe_sp_v4_gen_get_param_resp) + - sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) + - (num_ch * sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params)); - this_afe.spv4_get_param_resp_ptr = - kzalloc(this_afe.spv4_rcvd_param_size, GFP_ATOMIC); - data_dest = (u32 *)this_afe.spv4_get_param_resp_ptr; + this_afe.spv4_ex_vi_ftm_rcvd_param_size = param_hdr.param_size; + data_dest = (u32 *)&this_afe.spv4_ex_vi_ftm_resp; expected_size += - sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) + - (num_ch * sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params)); + sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) + + (num_ch * sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params)); break; case AFE_PARAM_ID_SP_V4_RX_TMAX_XMAX_LOGGING: num_ch = data_start[0]; - this_afe.spv4_rcvd_param_size = - sizeof(struct afe_sp_v4_gen_get_param_resp) + - sizeof(struct afe_sp_v4_param_tmax_xmax_logging) + - (num_ch * sizeof(struct afe_sp_v4_channel_tmax_xmax_params)); - this_afe.spv4_get_param_resp_ptr = - kzalloc(this_afe.spv4_rcvd_param_size, GFP_ATOMIC); - data_dest = (u32 *)this_afe.spv4_get_param_resp_ptr; + this_afe.spv4_max_log_rcvd_param_size = param_hdr.param_size; + data_dest = (u32 *)&this_afe.spv4_max_log_resp; expected_size += - sizeof(struct afe_sp_v4_param_tmax_xmax_logging) + - (num_ch * sizeof(struct afe_sp_v4_channel_tmax_xmax_params)); + sizeof(struct afe_sp_v4_param_tmax_xmax_logging) + + (num_ch * sizeof(struct afe_sp_v4_channel_tmax_xmax_params)); break; default: pr_err("%s: Unrecognized param ID %d\n", __func__, @@ -8920,8 +8947,8 @@ static int afe_get_spv4_th_vi_v_vali_data(void *params, uint32_t size) struct param_hdr_v3 param_hdr; int port = SLIMBUS_4_TX; int ret = -EINVAL; - u8 *rcvd_params = NULL; - struct afe_sp_v4_channel_v_vali_params *v_vali_params; + uint32_t min_size = 0; + struct afe_sp_v4_channel_v_vali_params *v_vali_params = NULL; if (!params) { pr_err("%s: Invalid params\n", __func__); @@ -8944,14 +8971,14 @@ static int afe_get_spv4_th_vi_v_vali_data(void *params, uint32_t size) goto get_params_fail; } - rcvd_params = (u8 *)this_afe.spv4_get_param_resp_ptr + - sizeof(struct afe_sp_v4_gen_get_param_resp); + min_size = (size < this_afe.spv4_v_vali_rcvd_param_size) ? + size : this_afe.spv4_v_vali_rcvd_param_size; + memcpy(params, (void*)&this_afe.spv4_v_vali_resp.num_ch, min_size); - memcpy(params, rcvd_params, this_afe.spv4_rcvd_param_size); + v_vali_params = &this_afe.spv4_v_vali_resp.ch_v_vali_params[0]; - v_vali_params = (struct afe_sp_v4_channel_v_vali_params *) - (params + sizeof(struct afe_sp_v4_param_th_vi_v_vali_params)); - pr_debug("%s: Vrms %d %d status %d %d\n", __func__, + pr_debug("%s: num_ch %d Vrms %d %d status %d %d\n", __func__, + this_afe.spv4_v_vali_resp.num_ch, v_vali_params[SP_V2_SPKR_1].vrms_q24, v_vali_params[SP_V2_SPKR_2].vrms_q24, v_vali_params[SP_V2_SPKR_1].status, @@ -8965,7 +8992,6 @@ static int afe_get_spv4_th_vi_v_vali_data(void *params, uint32_t size) ret = 0; get_params_fail: - kfree(this_afe.spv4_get_param_resp_ptr); mutex_unlock(&this_afe.afe_cmd_lock); done: return ret; @@ -9019,7 +9045,7 @@ static int afe_get_spv4_th_vi_ftm_data(void *params, uint32_t size) struct param_hdr_v3 param_hdr; int port = SLIMBUS_4_TX; int ret = -EINVAL; - u8 *rcvd_params = NULL; + uint32_t min_size = 0; struct afe_sp_v4_channel_ftm_params *th_vi_params; if (!params) { @@ -9043,22 +9069,21 @@ static int afe_get_spv4_th_vi_ftm_data(void *params, uint32_t size) goto get_params_fail; } - rcvd_params = (u8 *)this_afe.spv4_get_param_resp_ptr + - sizeof(struct afe_sp_v4_gen_get_param_resp); - memcpy(params, rcvd_params, this_afe.spv4_rcvd_param_size); + min_size = (size < this_afe.spv4_th_vi_ftm_rcvd_param_size) ? + size : this_afe.spv4_th_vi_ftm_rcvd_param_size; + memcpy(params, (void*)&this_afe.spv4_th_vi_ftm_resp.num_ch, min_size); - th_vi_params = (struct afe_sp_v4_channel_ftm_params *) - (params + sizeof(struct afe_sp_v4_param_th_vi_ftm_params)); - pr_debug("%s: DC resistance %d %d temp %d %d status %d %d\n", - __func__, th_vi_params[SP_V2_SPKR_1].dc_res_q24, - th_vi_params[SP_V2_SPKR_2].dc_res_q24, - th_vi_params[SP_V2_SPKR_1].temp_q22, - th_vi_params[SP_V2_SPKR_2].temp_q22, - th_vi_params[SP_V2_SPKR_1].status, - th_vi_params[SP_V2_SPKR_2].status); + th_vi_params = &this_afe.spv4_th_vi_ftm_resp.ch_ftm_params[0]; + pr_debug("%s:num_ch %d, DC resistance %d %d temp %d %d status %d %d\n", + __func__, this_afe.spv4_th_vi_ftm_resp.num_ch, + th_vi_params[SP_V2_SPKR_1].dc_res_q24, + th_vi_params[SP_V2_SPKR_2].dc_res_q24, + th_vi_params[SP_V2_SPKR_1].temp_q22, + th_vi_params[SP_V2_SPKR_2].temp_q22, + th_vi_params[SP_V2_SPKR_1].status, + th_vi_params[SP_V2_SPKR_2].status); ret = 0; get_params_fail: - kfree(this_afe.spv4_get_param_resp_ptr); mutex_unlock(&this_afe.afe_cmd_lock); done: return ret; @@ -9113,7 +9138,7 @@ static int afe_get_spv4_ex_vi_ftm_data(void *params, uint32_t size) struct param_hdr_v3 param_hdr; int port = SLIMBUS_4_TX; int ret = -EINVAL; - u8 *rcvd_params = NULL; + uint32_t min_size = 0; struct afe_sp_v4_channel_ex_vi_ftm_params *ex_vi_ftm_param; if (!params) { @@ -9138,17 +9163,16 @@ static int afe_get_spv4_ex_vi_ftm_data(void *params, uint32_t size) goto get_params_fail; } - rcvd_params = (u8 *)this_afe.spv4_get_param_resp_ptr + - sizeof(struct afe_sp_v4_gen_get_param_resp); + min_size = (size < this_afe.spv4_ex_vi_ftm_rcvd_param_size) ? + size : this_afe.spv4_ex_vi_ftm_rcvd_param_size; + memcpy(params, (void*)&this_afe.spv4_ex_vi_ftm_resp.num_ch, min_size); - memcpy(params, rcvd_params, this_afe.spv4_rcvd_param_size); + ex_vi_ftm_param = &this_afe.spv4_ex_vi_ftm_resp.ch_ex_vi_ftm_params[0]; - ex_vi_ftm_param = (struct afe_sp_v4_channel_ex_vi_ftm_params *) - (params + sizeof(struct afe_sp_v4_param_ex_vi_ftm_params)); - - pr_debug("%s: resistance %d %d force factor %d %d Damping kg/s %d %d\n" + pr_debug("%s:num_ch %d, res %d %d forcefactor %d %d Dmping kg/s %d %d\n" "stiffness N/mm %d %d freq %d %d Qfactor %d %d status %d %d", - __func__, ex_vi_ftm_param[SP_V2_SPKR_1].ftm_re_q24, + __func__, this_afe.spv4_ex_vi_ftm_resp.num_ch, + ex_vi_ftm_param[SP_V2_SPKR_1].ftm_re_q24, ex_vi_ftm_param[SP_V2_SPKR_2].ftm_re_q24, ex_vi_ftm_param[SP_V2_SPKR_1].ftm_Bl_q24, ex_vi_ftm_param[SP_V2_SPKR_2].ftm_Bl_q24, @@ -9164,7 +9188,6 @@ static int afe_get_spv4_ex_vi_ftm_data(void *params, uint32_t size) ex_vi_ftm_param[SP_V2_SPKR_2].status); ret = 0; get_params_fail: - kfree(this_afe.spv4_get_param_resp_ptr); mutex_unlock(&this_afe.afe_cmd_lock); done: return ret; @@ -9223,7 +9246,6 @@ int afe_get_sp_v4_rx_tmax_xmax_logging_data( { struct param_hdr_v3 param_hdr; int ret = -EINVAL; - struct afe_sp_v4_param_tmax_xmax_logging *tmax_xmax_logging; struct afe_sp_v4_channel_tmax_xmax_params *tx_channel_params; uint32_t i, size = 0; @@ -9248,13 +9270,9 @@ int afe_get_sp_v4_rx_tmax_xmax_logging_data( goto get_params_fail; } - tmax_xmax_logging = (struct afe_sp_v4_param_tmax_xmax_logging *) - ((u8 *)this_afe.spv4_get_param_resp_ptr + - sizeof(struct afe_sp_v4_gen_get_param_resp)); - tx_channel_params = (struct afe_sp_v4_channel_tmax_xmax_params *) - ((u8 *)tmax_xmax_logging + - sizeof(struct afe_sp_v4_param_tmax_xmax_logging)); - for (i = 0; i < tmax_xmax_logging->num_ch; i++) { + tx_channel_params = &this_afe.spv4_max_log_resp.ch_max_params[0]; + for (i = 0; i < this_afe.spv4_max_log_resp.num_ch; i++) { + xt_logging->max_excursion[i] = tx_channel_params[i].max_excursion; xt_logging->count_exceeded_excursion[i] = @@ -9267,7 +9285,6 @@ int afe_get_sp_v4_rx_tmax_xmax_logging_data( ret = 0; get_params_fail: - kfree(this_afe.spv4_get_param_resp_ptr); done: return ret; } -- GitLab From 37dacc9fd3fc8cde5e3abdf13de97c7fd3bf9ded Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Thu, 6 Aug 2020 11:59:13 +0530 Subject: [PATCH 1573/1645] config: kona: Disable MI2S, TDM and AUXPCM interfaces Disable MI2S, TDM and AUXPCM interfaces to avoid unnecessary registration of mixer controls and improve performance in loading mixer paths. Change-Id: Id0e37ee772ac10a84eb683a4f8736e7f6ff42fad Signed-off-by: Prasad Kumpatla --- config/konaauto.conf | 2 ++ config/konaautoconf.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/config/konaauto.conf b/config/konaauto.conf index 74ca2d48ea77..e88e51e96d99 100644 --- a/config/konaauto.conf +++ b/config/konaauto.conf @@ -37,3 +37,5 @@ export CONFIG_SND_SOC_KONA=m export CONFIG_SND_EVENT=m export CONFIG_VOICE_MHI=m export CONFIG_DIGITAL_CDC_RSC_MGR=m +export CONFIG_TDM_DISABLE=m +export CONFIG_AUXPCM_DISABLE=m diff --git a/config/konaautoconf.h b/config/konaautoconf.h index e489b41abd84..1a8038e3e5a3 100644 --- a/config/konaautoconf.h +++ b/config/konaautoconf.h @@ -41,3 +41,5 @@ #define CONFIG_SND_EVENT 1 #define CONFIG_VOICE_MHI 1 #define CONFIG_DIGITAL_CDC_RSC_MGR 1 +#define CONFIG_TDM_DISABLE 1 +#define CONFIG_AUXPCM_DISABLE 1 -- GitLab From 908583ff00ed2b342fffc388e0a15693c2801bb4 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 4 Aug 2020 07:46:05 +0530 Subject: [PATCH 1574/1645] soc: swr-mstr: Fix random headset detection issue on scuba When headset is inserted and reboot device sometimes headset is not detected after reboot as host_irq from swr slave gets masked. This is because of cmd error seen after clearing all irq which results in fifo flush. Read swrslave irq before clearing so as to resolve cmd error. Also enable slave irq only after clearing enum interrupt at master which results in proper enabling of irq. Change-Id: Id66029c65c4d813391bfeb8c0c619560f298eeab Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 20 +++++++++++--------- soc/swr-mstr-ctrl.h | 1 + 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 623f70e6b56e..ad4db4f7ea02 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1744,6 +1744,7 @@ static void swrm_enable_slave_irq(struct swr_mstr_ctrl *swrm) { int i; int status = 0; + u32 temp; status = swr_master_read(swrm, SWRM_MCP_SLV_STATUS); if (!status) { @@ -1754,6 +1755,8 @@ static void swrm_enable_slave_irq(struct swr_mstr_ctrl *swrm) dev_dbg(swrm->dev, "%s: slave status: 0x%x\n", __func__, status); for (i = 0; i < (swrm->master.num_dev + 1); i++) { if (status & SWRM_MCP_SLV_STATUS_MASK) { + swrm_cmd_fifo_rd_cmd(swrm, &temp, i, 0x0, + SWRS_SCP_INT_STATUS_CLEAR_1, 1); swrm_cmd_fifo_wr_cmd(swrm, 0xFF, i, 0x0, SWRS_SCP_INT_STATUS_CLEAR_1); swrm_cmd_fifo_wr_cmd(swrm, 0x4, i, 0x0, @@ -2069,10 +2072,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) * as hw will mask host_irq at slave * but will not unmask it afterwards. */ - swrm_cmd_fifo_wr_cmd(swrm, 0xFF, devnum, 0x0, - SWRS_SCP_INT_STATUS_CLEAR_1); - swrm_cmd_fifo_wr_cmd(swrm, 0x4, devnum, 0x0, - SWRS_SCP_INT_STATUS_MASK_1); + swrm->enable_slave_irq = true; } break; case SWR_ATTACHED_OK: @@ -2080,11 +2080,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) "%s: device %d got attached\n", __func__, devnum); /* enable host irq from slave device*/ - swrm_cmd_fifo_wr_cmd(swrm, 0xFF, devnum, 0x0, - SWRS_SCP_INT_STATUS_CLEAR_1); - swrm_cmd_fifo_wr_cmd(swrm, 0x4, devnum, 0x0, - SWRS_SCP_INT_STATUS_MASK_1); - + swrm->enable_slave_irq = true; break; case SWR_ALERT: dev_dbg(swrm->dev, @@ -2187,6 +2183,12 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, intr_sts); swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, 0x0); + if (swrm->enable_slave_irq) { + /* Enable slave irq here */ + swrm_enable_slave_irq(swrm); + swrm->enable_slave_irq = false; + } + intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); intr_sts_masked = intr_sts & swrm->intr_mask; diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 51b35386ff49..f53659234b5a 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -184,6 +184,7 @@ struct swr_mstr_ctrl { u32 disable_div2_clk_switch; u32 rd_fifo_depth; u32 wr_fifo_depth; + bool enable_slave_irq; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_swrm_dent; struct dentry *debugfs_peek; -- GitLab From 6bb6f668f80b6855255cd4a74953bd610a753b06 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 25 Aug 2020 17:14:49 +0800 Subject: [PATCH 1575/1645] soc: swr-mstr: update component and interrupt enable sequence Enable component after enabling interrupt to avoid missing some intterupt during master init. Change-Id: I0f60c5431a815c58f878d3b9275a046e47939111 Signed-off-by: Meng Wang --- soc/swr-mstr-ctrl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 623f70e6b56e..a489be17a05d 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2473,9 +2473,6 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) reg[len] = SWRM_COMP_CFG_ADDR; value[len++] = 0x02; - reg[len] = SWRM_COMP_CFG_ADDR; - value[len++] = 0x03; - reg[len] = SWRM_INTERRUPT_CLEAR; value[len++] = 0xFFFFFFFF; @@ -2487,6 +2484,9 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) reg[len] = SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN; value[len++] = swrm->intr_mask; + reg[len] = SWRM_COMP_CFG_ADDR; + value[len++] = 0x03; + swr_master_bulk_write(swrm, reg, value, len); if (!swrm_check_link_status(swrm, 0x1)) { -- GitLab From ec0d9f5e723ffd1a98c3624f40abc61591074a02 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 12 Aug 2020 09:42:46 +0530 Subject: [PATCH 1576/1645] soc: swr-mstr: Fix headset detect issue due to master.num_dev not updated Headset is not detected sometimes due to master.num_dev not being updated when we call GET_ENUM_SLAVE_STATUS as get_logical address may not have been called. Also enable slave irq only when swr wokeup from clk stop and not when master is already up. This will prevent valid irq to be discarded as spurious irq. Change-Id: I00284e9340668c853d0bd604fe66801118982780 Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 623f70e6b56e..f1840a7e2ea5 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2161,20 +2161,21 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) case SWRM_INTERRUPT_STATUS_CLK_STOP_FINISHED_V2: break; case SWRM_INTERRUPT_STATUS_EXT_CLK_STOP_WAKEUP: - if (swrm->state == SWR_MSTR_UP) + if (swrm->state == SWR_MSTR_UP) { dev_dbg(swrm->dev, "%s:SWR Master is already up\n", __func__); - else + } else { dev_err_ratelimited(swrm->dev, "%s: SWR wokeup during clock stop\n", __func__); - /* It might be possible the slave device gets reset - * and slave interrupt gets missed. So re-enable - * Host IRQ and process slave pending - * interrupts, if any. - */ - swrm_enable_slave_irq(swrm); + /* It might be possible the slave device gets + * reset and slave interrupt gets missed. So + * re-enable Host IRQ and process slave pending + * interrupts, if any. + */ + swrm_enable_slave_irq(swrm); + } break; default: dev_err_ratelimited(swrm->dev, @@ -2659,6 +2660,8 @@ static int swrm_probe(struct platform_device *pdev) SWRM_NUM_AUTO_ENUM_SLAVES); ret = -EINVAL; goto err_pdata_fail; + } else { + swrm->master.num_dev = swrm->num_dev; } } -- GitLab From e41f985fa4ce16bc1767595914f76d8d8eae88d0 Mon Sep 17 00:00:00 2001 From: xsang Date: Fri, 19 Jun 2020 19:46:57 +0800 Subject: [PATCH 1577/1645] asoc: add null check for pcm pointer of snd_pcm_volume In platform driver volume controls, add null check for pcm pointer of struct snd_pcm_volume. Change-Id: I511a79422eaeced6240849cbb665a289afdc5984 Signed-off-by: Xiaojun Sang --- asoc/msm-pcm-q6-noirq.c | 6 ++++++ asoc/msm-pcm-q6-v2.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index e3f59e8dc502..7338013c7e7c 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -730,6 +730,12 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, pr_err("%s: vol is NULL\n", __func__); return -ENODEV; } + + if (!vol->pcm) { + pr_err("%s: vol->pcm is NULL\n", __func__); + return -ENODEV; + } + substream = vol->pcm->streams[vol->stream].substream; if (!substream) { pr_err("%s substream not found\n", __func__); diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 1592c3f7ae41..de28f65a6f34 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1534,6 +1534,12 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, pr_err("%s: vol is NULL\n", __func__); return -ENODEV; } + + if (!vol->pcm) { + pr_err("%s: vol->pcm is NULL\n", __func__); + return -ENODEV; + } + substream = vol->pcm->streams[vol->stream].substream; if (!substream) { pr_err("%s substream not found\n", __func__); -- GitLab From 95712bc373cded8b676210ebb59a4be9c60bbb7b Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 16 May 2020 11:50:48 +0530 Subject: [PATCH 1578/1645] ASoC: wsa883x: Update register sequence to reduce CnP Update register sequence of WSA883x codec to reduce CnP during bringup and teardown of speaker path. Change-Id: I348a55e1324b5c26a36b8d7c78edf52a66e40381 Signed-off-by: Sudheer Papothi --- asoc/codecs/wsa883x/wsa883x.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 3a319c7e2b80..8a5e99e4c980 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -108,6 +108,7 @@ static const struct wsa_reg_mask_val reg_init[] = { {WSA883X_ADC_7, 0x04, 0x04}, {WSA883X_ADC_7, 0x02, 0x02}, {WSA883X_CKWD_CTL_0, 0x60, 0x00}, + {WSA883X_DRE_CTL_1, 0x3E, 0x20}, {WSA883X_CKWD_CTL_1, 0x1F, 0x1B}, {WSA883X_GMAMP_SUP1, 0x60, 0x60}, }; @@ -986,6 +987,12 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, swr_slvdev_datapath_control(wsa883x->swr_slave, wsa883x->swr_slave->dev_num, true); + /* Added delay as per HW sequence */ + usleep_range(250, 300); + snd_soc_component_update_bits(component, WSA883X_DRE_CTL_1, + 0x01, 0x01); + /* Added delay as per HW sequence */ + usleep_range(250, 300); /* Force remove group */ swr_remove_from_group(wsa883x->swr_slave, wsa883x->swr_slave->dev_num); @@ -1393,6 +1400,13 @@ static int wsa883x_event_notify(struct notifier_block *nb, 0x01, 0x01); wcd_enable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD); + /* Added delay as per HW sequence */ + usleep_range(3000, 3100); + snd_soc_component_update_bits(wsa883x->component, + WSA883X_DRE_CTL_1, + 0x01, 0x00); + /* Added delay as per HW sequence */ + usleep_range(5000, 5050); } break; case BOLERO_WSA_EVT_PA_ON_POST_FSCLK_ADIE_LB: -- GitLab From 6da283a531c293f454d2ac8289c744b35db6258f Mon Sep 17 00:00:00 2001 From: xsang Date: Fri, 19 Jun 2020 19:46:57 +0800 Subject: [PATCH 1579/1645] asoc: add null check for pcm pointer of snd_pcm_volume In platform driver volume controls, add null check for pcm pointer of struct snd_pcm_volume. Change-Id: I511a79422eaeced6240849cbb665a289afdc5984 Signed-off-by: Xiaojun Sang --- asoc/msm-pcm-q6-noirq.c | 6 ++++++ asoc/msm-pcm-q6-v2.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c index e3f59e8dc502..7338013c7e7c 100644 --- a/asoc/msm-pcm-q6-noirq.c +++ b/asoc/msm-pcm-q6-noirq.c @@ -730,6 +730,12 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, pr_err("%s: vol is NULL\n", __func__); return -ENODEV; } + + if (!vol->pcm) { + pr_err("%s: vol->pcm is NULL\n", __func__); + return -ENODEV; + } + substream = vol->pcm->streams[vol->stream].substream; if (!substream) { pr_err("%s substream not found\n", __func__); diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index 1592c3f7ae41..de28f65a6f34 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1534,6 +1534,12 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol, pr_err("%s: vol is NULL\n", __func__); return -ENODEV; } + + if (!vol->pcm) { + pr_err("%s: vol->pcm is NULL\n", __func__); + return -ENODEV; + } + substream = vol->pcm->streams[vol->stream].substream; if (!substream) { pr_err("%s substream not found\n", __func__); -- GitLab From 9c7b6f8ba2398b6471ae1936142f0d99aba2b9ba Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 16 Sep 2020 22:25:41 +0530 Subject: [PATCH 1580/1645] dsp: q6core: Check q6core avs state to be modules ready During PDR, in dynamic load module if attempted before all module state ready on AVS it may fail. Add AVS state check before send load module cmd. Change-Id: I70a5a5b11f5661042d704222759608179ba9d47c Signed-off-by: Laxminath Kasam --- dsp/q6core.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/dsp/q6core.c b/dsp/q6core.c index 392b09dec8e7..1e168e8ecc5f 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -33,6 +33,8 @@ #define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define ADSP_MODULES_READY_AVS_STATE 5 + #define APR_ENOTREADY 10 #define MEMPOOL_ID_MASK 0xFF #define MDF_MAP_TOKEN 0xF000 @@ -935,12 +937,39 @@ int32_t q6core_avcs_load_unload_modules(struct avcs_load_unload_modules_payload size_t packet_size = 0, payload_size = 0; struct avcs_cmd_dynamic_modules *mod = NULL; int num_modules; + unsigned long timeout; if (payload == NULL) { pr_err("%s: payload is null\n", __func__); return -EINVAL; } + if ((q6core_lcl.avs_state != ADSP_MODULES_READY_AVS_STATE) + && (preload_type == AVCS_LOAD_MODULES)) { + timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + + do { + q6core_is_adsp_ready(); + if (q6core_lcl.param == ADSP_MODULES_READY_AVS_STATE) { + pr_debug("%s: ADSP state up with all modules loaded\n", + __func__); + q6core_lcl.avs_state = ADSP_MODULES_READY_AVS_STATE; + break; + } + + /* + * ADSP will be coming up after boot up and AVS might + * not be fully up with all modules when the control reaches here. + * So, wait for 50msec before checking ADSP state again. + */ + msleep(50); + } while (time_after(timeout, jiffies)); + + if (q6core_lcl.param != ADSP_MODULES_READY_AVS_STATE) + pr_err("%s: all modules might be not loaded yet on ADSP\n", + __func__); + } mutex_lock(&(q6core_lcl.cmd_lock)); num_modules = payload->num_modules; ocm_core_open(); @@ -1951,7 +1980,7 @@ static int q6core_is_avs_up(int32_t *avs_state) msleep(50); } while (time_after(timeout, jiffies)); - *avs_state = adsp_ready; + *avs_state = q6core_lcl.param; pr_debug("%s: ADSP Audio is %s\n", __func__, adsp_ready ? "ready" : "not ready"); -- GitLab From aee057e0150bd401b063c193b1d16c9350763fe4 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 18 Sep 2020 15:43:21 +0530 Subject: [PATCH 1581/1645] asoc: va-macro: Update widget order for VA_MCLK and VA_SWR_PWR Update widget order for widgets VA_MCLK and VA_SWR_PWR. As both are having widget supply priority -1, sometimes dapm is triggering both widget callbacks simultaneously causing race condition in handling the SWR clock release with proper request for VA_CLK instead of TX_CLK and next usecase powerup is impacted. Change-Id: I3d3a3fadcdb897287ad070dc9e81e354c6f970b0 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/va-macro.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index f0a85ac07306..5ce2ec12be92 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -509,7 +509,6 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, int ret = 0; struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; - int clk_src = 0; if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; @@ -531,22 +530,6 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: if (va_priv->lpi_enable) { - if (va_priv->version == BOLERO_VERSION_2_1) { - if (va_priv->swr_ctrl_data) { - clk_src = CLK_SRC_TX_RCG; - ret = swrm_wcd_notify( - va_priv->swr_ctrl_data[0].va_swr_pdev, - SWR_REQ_CLK_SWITCH, &clk_src); - if (ret) - dev_dbg(va_dev, - "%s: clock switch failed\n", - __func__); - } - } else if (bolero_tx_clk_switch(component, - CLK_SRC_TX_RCG)) { - dev_dbg(va_dev, "%s: clock switch failed\n", - __func__); - } va_macro_mclk_enable(va_priv, 0, true); } else { bolero_tx_mclk_enable(component, 0); @@ -1919,7 +1902,7 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v2[] = { VA_MACRO_AIF3_CAP, 0, va_aif3_cap_mixer_v2, ARRAY_SIZE(va_aif3_cap_mixer_v2)), - SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -2, SND_SOC_NOPM, 0, 0, va_macro_swr_pwr_event_v2, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -1961,7 +1944,7 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v3[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -2, SND_SOC_NOPM, 0, 0, va_macro_swr_pwr_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; -- GitLab From d362103415a0d246674bd601005277f70cafe15f Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 1 Apr 2020 18:14:05 +0530 Subject: [PATCH 1582/1645] asoc: kona: Update wsa8815 default config With wsa883x supported in lagoon, need to set wsa8815 default config also. Change-Id: I7e247cb564c893f7fbbc715de68821c6b91d559a Signed-off-by: Laxminath Kasam --- asoc/kona.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index 5192e3eca753..23f5f427859d 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -80,8 +80,10 @@ #define ADSP_STATE_READY_TIMEOUT_MS 3000 -#define WSA8810_NAME_1 "wsa881x.20170211" -#define WSA8810_NAME_2 "wsa881x.20170212" +#define WSA8810_NAME_1 "wsa881x.1020170211" +#define WSA8810_NAME_2 "wsa881x.1020170212" +#define WSA8815_NAME_1 "wsa881x.1021170213" +#define WSA8815_NAME_2 "wsa881x.1021170214" #define WCN_CDC_SLIM_RX_CH_MAX 2 #define WCN_CDC_SLIM_TX_CH_MAX 2 #define WCN_CDC_SLIM_TX_CH_MAX_LITO 3 @@ -5531,6 +5533,11 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) WSA_MACRO_SPKR_MODE_1); wsa_macro_set_spkr_gain_offset(component, WSA_MACRO_GAIN_OFFSET_M1P5_DB); + } else if (aux_comp->name != NULL && ( + !strcmp(aux_comp->name, WSA8815_NAME_1) || + !strcmp(aux_comp->name, WSA8815_NAME_2))) { + wsa_macro_set_spkr_mode(component, + WSA_MACRO_SPKR_MODE_DEFAULT); } } } -- GitLab From 44f2b8694b901c33e7c3d9f85eca138ca65ee730 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Sat, 28 Mar 2020 10:03:21 +0530 Subject: [PATCH 1583/1645] ASoC: wsa-macro: Update smart boost sequence for wsa883x Update smart boost sequence for wsa883x speaker amplifier to reach max voltage at full scale signal. Update default tables to maintain backward compatible with wsa8810/wsa8815. Change-Id: Ic1a9ce13753d6e573c7916ae99643c85d6892aa0 Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/wsa-macro.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index ca7391d0726b..5ace96db07ca 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -445,8 +445,8 @@ static struct snd_soc_dai_driver wsa_macro_dai[] = { static const struct wsa_macro_reg_mask_val wsa_macro_spkr_default[] = { {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80}, {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80}, - {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01}, - {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01}, + {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1F, 0x19}, + {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1F, 0x19}, {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x58}, {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x58}, }; @@ -454,8 +454,8 @@ static const struct wsa_macro_reg_mask_val wsa_macro_spkr_default[] = { static const struct wsa_macro_reg_mask_val wsa_macro_spkr_mode1[] = { {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x00}, {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x00}, - {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x00}, - {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x00}, + {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1F, 0x18}, + {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1F, 0x18}, {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x44}, {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x44}, }; @@ -2744,10 +2744,10 @@ static const struct snd_soc_dapm_route wsa_audio_map[] = { static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = { {BOLERO_CDC_WSA_BOOST0_BOOST_CFG1, 0x3F, 0x12}, {BOLERO_CDC_WSA_BOOST0_BOOST_CFG2, 0x1C, 0x08}, - {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x18}, + {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x0C}, {BOLERO_CDC_WSA_BOOST1_BOOST_CFG1, 0x3F, 0x12}, {BOLERO_CDC_WSA_BOOST1_BOOST_CFG2, 0x1C, 0x08}, - {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x18}, + {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x0C}, {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x70, 0x58}, {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x70, 0x58}, {BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 0x08, 0x08}, @@ -2758,8 +2758,6 @@ static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = { {BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, {BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, {BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, - {BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80}, - {BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80}, {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01}, {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01}, {BOLERO_CDC_WSA_RX0_RX_PATH_CFG0, 0x01, 0x01}, -- GitLab From 4a089bc4aed683e85738bae1ba6df517e60b80e2 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Wed, 12 Aug 2020 23:52:48 -0700 Subject: [PATCH 1584/1645] ASoC: wsa883x: enable vbat adc filter Enable vbat adc filter inorder to read vbat and temperature values for cps speaker protection. Change-Id: I31c50bdd6ed0becae355600ba3cf48e761406d87 Signed-off-by: Vignesh Kulothungan --- asoc/codecs/wsa883x/wsa883x.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 8a5e99e4c980..dc121374f722 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -996,6 +996,12 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, /* Force remove group */ swr_remove_from_group(wsa883x->swr_slave, wsa883x->swr_slave->dev_num); + snd_soc_component_update_bits(component, + WSA883X_VBAT_ADC_FLT_CTL, + 0x0E, 0x06); + snd_soc_component_update_bits(component, + WSA883X_VBAT_ADC_FLT_CTL, + 0x01, 0x01); if (test_bit(SPKR_ADIE_LB, &wsa883x->status_mask)) snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, 0x01, 0x01); @@ -1004,6 +1010,12 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, if (!test_bit(SPKR_ADIE_LB, &wsa883x->status_mask)) wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD); + snd_soc_component_update_bits(component, + WSA883X_VBAT_ADC_FLT_CTL, + 0x01, 0x00); + snd_soc_component_update_bits(component, + WSA883X_VBAT_ADC_FLT_CTL, + 0x0E, 0x00); snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, 0x01, 0x00); snd_soc_component_update_bits(wsa883x->component, -- GitLab From 73a7b9379c46461f7e65310a4bdff09380b4da6a Mon Sep 17 00:00:00 2001 From: Sujin Panicker Date: Wed, 23 Sep 2020 10:45:52 +0530 Subject: [PATCH 1585/1645] dsp: Add param header size based on the instance id support Add param header size to the actual parameter size based on the instance id support. Change-Id: I8937e71254265dbc9faf00b9cfc7c40c88f4388a Signed-off-by: Sujin Panicker --- dsp/q6lsm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c index cc57a25361a6..857dad3f9c5d 100644 --- a/dsp/q6lsm.c +++ b/dsp/q6lsm.c @@ -2436,6 +2436,7 @@ int q6lsm_get_one_param(struct lsm_client *client, { struct param_hdr_v3 param_info; int rc = 0; + bool iid_supported = q6common_is_instance_id_supported(); memset(¶m_info, 0, sizeof(param_info)); @@ -2444,7 +2445,12 @@ int q6lsm_get_one_param(struct lsm_client *client, param_info.module_id = p_info->module_id; param_info.instance_id = p_info->instance_id; param_info.param_id = p_info->param_id; - param_info.param_size = p_info->param_size + sizeof(param_info); + + if (iid_supported) + param_info.param_size = p_info->param_size + sizeof(struct param_hdr_v3); + else + param_info.param_size = p_info->param_size + sizeof(struct param_hdr_v2); + rc = q6lsm_get_params(client, NULL, ¶m_info); if (rc) { pr_err("%s: LSM_GET_CUSTOM_PARAMS failed, rc %d\n", -- GitLab From 0b2d06e7180ab085f86d0e16b9f3e09afe8f9e39 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Fri, 16 Oct 2020 17:53:22 +0530 Subject: [PATCH 1586/1645] asoc: msm-pcm-q6-v2: Update memset for period size tinycap test can attempt with different size to read from driver and need to avoid access more than period size. Change-Id: Ifa4ddfb086bd83aa981da62e88da3a9395f5aabc Signed-off-by: Laxminath Kasam --- asoc/msm-pcm-q6-v2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index de28f65a6f34..de8519d1bcca 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1007,9 +1007,9 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, xfer = size; offset = prtd->in_frame_info[idx].offset; pr_debug("Offset value = %d\n", offset); - if (size == 0 || size < fbytes) { - memset(bufptr + offset + size, 0, fbytes - size); - size = xfer = fbytes; + if (size == 0 || size < prtd->pcm_count) { + memset(bufptr + offset + size, 0, prtd->pcm_count - size); + size = xfer = prtd->pcm_count; } if (copy_to_user(buf, bufptr+offset, xfer)) { -- GitLab From c8b96b4629a1b59632d6858543b9bd6fece7899c Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 15 Oct 2020 20:30:28 +0530 Subject: [PATCH 1587/1645] asoc: va-macro: Allow swr switch at powerup/shutdown Ensure soundwire clock re-setup always for SWR AMIC usecase startup and at end of usecase. Change-Id: Ie0e94a456c8e5e529a2a7435ded094483e369f01 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/va-macro.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 5ce2ec12be92..cbb77ee7fdc8 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -388,9 +388,6 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w, dev_dbg(va_dev, "%s: event = %d, lpi_enable = %d\n", __func__, event, va_priv->lpi_enable); - if (!va_priv->lpi_enable) - return ret; - switch (event) { case SND_SOC_DAPM_PRE_PMU: if (va_priv->swr_ctrl_data) { @@ -441,9 +438,6 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, dev_dbg(va_dev, "%s: event = %d, lpi_enable = %d\n", __func__, event, va_priv->lpi_enable); - if (!va_priv->lpi_enable) - return ret; - switch (event) { case SND_SOC_DAPM_PRE_PMU: if (va_priv->lpass_audio_hw_vote) { -- GitLab From 70b1077b3cfab8168cddb2ab930ee9e0645633bd Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 22 Oct 2020 09:29:59 +0530 Subject: [PATCH 1588/1645] soc: swr-mstr: Update soundwire state to SSR during UP During SSR up event handler, if soundwire state is already up or auto suspend jiffies is not completed, ensure put in suspend/SSR state. Change-Id: I853f42d125eb5a60e3f1f065a60516877e3a463c Signed-off-by: Laxminath Kasam --- soc/swr-mstr-ctrl.c | 18 +++++++++++++++++- soc/swr-mstr-ctrl.h | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 7bf2f9a6a695..d594a9923028 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -3093,7 +3093,7 @@ static int swrm_runtime_resume(struct device *dev) swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); - if (swrm_clk_req_err) + if (swrm_clk_req_err || aud_core_err || hw_core_err) pm_runtime_set_autosuspend_delay(&pdev->dev, ERR_AUTO_SUSPEND_TIMER_VAL); else @@ -3123,6 +3123,10 @@ static int swrm_runtime_suspend(struct device *dev) __func__, swrm->state); dev_dbg(dev, "%s: pm_runtime: suspend state: %d\n", __func__, swrm->state); + if (swrm->state == SWR_MSTR_SSR_RESET) { + swrm->state = SWR_MSTR_SSR; + return 0; + } mutex_lock(&swrm->reslock); mutex_lock(&swrm->force_down_lock); current_state = swrm->state; @@ -3477,6 +3481,18 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) dev_err(swrm->dev, "%s: clock voting not zero\n", __func__); + if (swrm->state == SWR_MSTR_UP || + pm_runtime_autosuspend_expiration(swrm->dev)) { + swrm->state = SWR_MSTR_SSR_RESET; + dev_dbg(swrm->dev, + "%s:suspend swr if active at SSR up\n", + __func__); + pm_runtime_set_autosuspend_delay(swrm->dev, + ERR_AUTO_SUSPEND_TIMER_VAL); + usleep_range(50000, 50100); + swrm->state = SWR_MSTR_SSR; + } + mutex_lock(&swrm->devlock); swrm->dev_up = true; mutex_unlock(&swrm->devlock); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index f53659234b5a..ed67f0e443e6 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -51,6 +51,7 @@ enum { SWR_MSTR_UP, SWR_MSTR_DOWN, SWR_MSTR_SSR, + SWR_MSTR_SSR_RESET, }; enum swrm_pm_state { -- GitLab From 36bf29967ea5c9fdc2b6f24464cd281f62b01325 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 2 Nov 2020 10:56:07 +0530 Subject: [PATCH 1589/1645] asoc: bolero: control wakeup of swr_tx during clock setup Move the enable and disable of wakeup capability of swr_tx gpios to clock setup to disable or enable it in all required usecases. Change-Id: I9fb76926d8520c382e7f19777190357c50f98994 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/tx-macro.c | 8 ++++---- asoc/codecs/bolero/va-macro.c | 14 ++++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 158f35007549..7e982fac449e 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -2445,11 +2445,7 @@ static int tx_macro_register_event_listener(struct snd_soc_component *component, ret = swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, SWR_REGISTER_WAKEUP, NULL); - msm_cdc_pinctrl_set_wakeup_capable( - tx_priv->tx_swr_gpio_p, false); } else { - msm_cdc_pinctrl_set_wakeup_capable( - tx_priv->tx_swr_gpio_p, true); ret = swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, SWR_DEREGISTER_WAKEUP, NULL); @@ -2484,6 +2480,8 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, __func__); goto exit; } + msm_cdc_pinctrl_set_wakeup_capable( + tx_priv->tx_swr_gpio_p, false); } clk_tx_ret = bolero_clk_rsc_request_clock(tx_priv->dev, @@ -2612,6 +2610,8 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, TX_CORE_CLK, false); if (tx_priv->swr_clk_users == 0) { + msm_cdc_pinctrl_set_wakeup_capable( + tx_priv->tx_swr_gpio_p, true); ret = msm_cdc_pinctrl_select_sleep_state( tx_priv->tx_swr_gpio_p); if (ret < 0) { diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 5ce2ec12be92..d5966cd2aa14 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -402,12 +402,8 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w, dev_dbg(va_dev, "%s: clock switch failed\n", __func__); } - msm_cdc_pinctrl_set_wakeup_capable( - va_priv->va_swr_gpio_p, false); break; case SND_SOC_DAPM_POST_PMD: - msm_cdc_pinctrl_set_wakeup_capable( - va_priv->va_swr_gpio_p, true); if (va_priv->swr_ctrl_data) { clk_src = CLK_SRC_TX_RCG; ret = swrm_wcd_notify( @@ -563,9 +559,12 @@ static int va_macro_tx_va_mclk_enable(struct va_macro_priv *va_priv, (enable ? "enable" : "disable"), va_priv->va_mclk_users); if (enable) { - if (va_priv->swr_clk_users == 0) + if (va_priv->swr_clk_users == 0) { msm_cdc_pinctrl_select_active_state( va_priv->va_swr_gpio_p); + msm_cdc_pinctrl_set_wakeup_capable( + va_priv->va_swr_gpio_p, false); + } clk_tx_ret = bolero_clk_rsc_request_clock(va_priv->dev, TX_CORE_CLK, TX_CORE_CLK, @@ -658,9 +657,12 @@ static int va_macro_tx_va_mclk_enable(struct va_macro_priv *va_priv, TX_CORE_CLK, TX_CORE_CLK, false); - if (va_priv->swr_clk_users == 0) + if (va_priv->swr_clk_users == 0) { + msm_cdc_pinctrl_set_wakeup_capable( + va_priv->va_swr_gpio_p, true); msm_cdc_pinctrl_select_sleep_state( va_priv->va_swr_gpio_p); + } } return 0; -- GitLab From 3e3537e5676d23e43385765be821e42c3eab1a0a Mon Sep 17 00:00:00 2001 From: "Vangala, Amarnath" Date: Wed, 13 May 2020 23:11:14 +0530 Subject: [PATCH 1590/1645] ASOC: SPV4 set correct number of speakers. Set correct number of speakers for Speaker Protection V4. Change-Id: I66c656174bef64d3cdd64b17d994073e9ee58472 Signed-off-by: Vangala, Amarnath --- dsp/q6afe.c | 89 +++++++++++++++++++++++++---------------------------- 1 file changed, 42 insertions(+), 47 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index c9a5c95e4d29..58d440b0e323 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -246,6 +246,7 @@ struct afe_ctl { /* FTM spk params */ uint32_t initial_cal; uint32_t v_vali_flag; + uint32_t num_spkrs; }; struct afe_clkinfo_per_port { @@ -2312,6 +2313,7 @@ static void afe_send_cal_spv4_tx(int port_id) struct afe_sp_v4_channel_v_vali_cfg *ch_v_vali_cfg; struct afe_sp_v4_param_ex_vi_ftm_cfg *ex_vi_ftm_cfg; struct afe_sp_v4_channel_ex_vi_ftm *ch_ex_vi_ftm_cfg; + uint32_t i = 0; pr_debug("%s: Entry.. port_id %d\n", __func__, port_id); @@ -2372,7 +2374,7 @@ static void afe_send_cal_spv4_tx(int port_id) v4_vi_op_mode->th_r0t0_selection_flag[SP_V2_SPKR_2] = USE_SAFE_R0TO; } - afe_spk_config.v4_vi_op_mode.num_speakers = SP_V2_NUM_MAX_SPKRS; + afe_spk_config.v4_vi_op_mode.num_speakers = this_afe.num_spkrs; if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_SP_V4_VI_OP_MODE_CFG, &afe_spk_config, @@ -2381,7 +2383,7 @@ static void afe_send_cal_spv4_tx(int port_id) __func__); size = sizeof(struct afe_sp_v4_param_th_vi_r0t0_cfg) + - (SP_V2_NUM_MAX_SPKRS * sizeof(struct afe_sp_v4_channel_r0t0)); + (this_afe.num_spkrs * sizeof(struct afe_sp_v4_channel_r0t0)); tmp_ptr = kzalloc(size, GFP_KERNEL); if (!tmp_ptr) { mutex_unlock( @@ -2395,15 +2397,13 @@ static void afe_send_cal_spv4_tx(int port_id) ch_r0t0_cfg = (struct afe_sp_v4_channel_r0t0 *)(th_vi_r0t0_cfg + 1); - th_vi_r0t0_cfg->num_speakers = SP_V2_NUM_MAX_SPKRS; - ch_r0t0_cfg[SP_V2_SPKR_1].r0_cali_q24 = - (uint32_t) this_afe.prot_cfg.r0[SP_V2_SPKR_1]; - ch_r0t0_cfg[SP_V2_SPKR_2].r0_cali_q24 = - (uint32_t) this_afe.prot_cfg.r0[SP_V2_SPKR_2]; - ch_r0t0_cfg[SP_V2_SPKR_1].t0_cali_q6 = - (uint32_t) this_afe.prot_cfg.t0[SP_V2_SPKR_1]; - ch_r0t0_cfg[SP_V2_SPKR_2].t0_cali_q6 = - (uint32_t) this_afe.prot_cfg.t0[SP_V2_SPKR_2]; + th_vi_r0t0_cfg->num_speakers = this_afe.num_spkrs; + for (i = 0; i < this_afe.num_spkrs; i++) { + ch_r0t0_cfg[i].r0_cali_q24 = + (uint32_t) this_afe.prot_cfg.r0[i]; + ch_r0t0_cfg[i].t0_cali_q6 = + (uint32_t) this_afe.prot_cfg.t0[i]; + } if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_SP_V4_VI_R0T0_CFG, (union afe_spkr_prot_config *)tmp_ptr, size)) @@ -2418,7 +2418,7 @@ static void afe_send_cal_spv4_tx(int port_id) (this_afe.vi_tx_port == port_id) && (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9)) { size = sizeof(struct afe_sp_v4_param_th_vi_ftm_cfg) + - (SP_V2_NUM_MAX_SPKRS*sizeof(struct afe_sp_v4_channel_ftm_cfg)); + (this_afe.num_spkrs * sizeof(struct afe_sp_v4_channel_ftm_cfg)); tmp_ptr = kzalloc(size, GFP_KERNEL); if (!tmp_ptr) { mutex_unlock( @@ -2431,16 +2431,13 @@ static void afe_send_cal_spv4_tx(int port_id) ch_ftm_cfg = (struct afe_sp_v4_channel_ftm_cfg *)(th_vi_ftm_cfg+1); - th_vi_ftm_cfg->num_ch = SP_V2_NUM_MAX_SPKRS; - ch_ftm_cfg[SP_V2_SPKR_1].wait_time_ms = - this_afe.th_ftm_cfg.wait_time[SP_V2_SPKR_1]; - ch_ftm_cfg[SP_V2_SPKR_2].wait_time_ms = - this_afe.th_ftm_cfg.wait_time[SP_V2_SPKR_2]; - ch_ftm_cfg[SP_V2_SPKR_1].ftm_time_ms = - this_afe.th_ftm_cfg.ftm_time[SP_V2_SPKR_1]; - ch_ftm_cfg[SP_V2_SPKR_2].ftm_time_ms = - this_afe.th_ftm_cfg.ftm_time[SP_V2_SPKR_2]; - + th_vi_ftm_cfg->num_ch = this_afe.num_spkrs; + for (i = 0; i < this_afe.num_spkrs; i++) { + ch_ftm_cfg[i].wait_time_ms = + this_afe.th_ftm_cfg.wait_time[i]; + ch_ftm_cfg[i].ftm_time_ms = + this_afe.th_ftm_cfg.ftm_time[i]; + } if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_SP_V4_TH_VI_FTM_CFG, (union afe_spkr_prot_config *)tmp_ptr, size)) @@ -2452,8 +2449,8 @@ static void afe_send_cal_spv4_tx(int port_id) MSM_SPKR_PROT_IN_V_VALI_MODE) && (this_afe.vi_tx_port == port_id)) { size = sizeof(struct afe_sp_v4_param_th_vi_v_vali_cfg) + - (SP_V2_NUM_MAX_SPKRS * - sizeof(struct afe_sp_v4_channel_v_vali_cfg)); + (this_afe.num_spkrs * + sizeof(struct afe_sp_v4_channel_v_vali_cfg)); tmp_ptr = kzalloc(size, GFP_KERNEL); if (!tmp_ptr) { mutex_unlock( @@ -2467,16 +2464,13 @@ static void afe_send_cal_spv4_tx(int port_id) ch_v_vali_cfg = (struct afe_sp_v4_channel_v_vali_cfg *)(th_vi_v_vali_cfg + 1); - th_vi_v_vali_cfg->num_ch = SP_V2_NUM_MAX_SPKRS; - ch_v_vali_cfg[SP_V2_SPKR_1].wait_time_ms = - this_afe.v_vali_cfg.wait_time[SP_V2_SPKR_1]; - ch_v_vali_cfg[SP_V2_SPKR_2].wait_time_ms = - this_afe.v_vali_cfg.wait_time[SP_V2_SPKR_2]; - ch_v_vali_cfg[SP_V2_SPKR_1].vali_time_ms = - this_afe.v_vali_cfg.vali_time[SP_V2_SPKR_1]; - ch_v_vali_cfg[SP_V2_SPKR_2].vali_time_ms = - this_afe.v_vali_cfg.vali_time[SP_V2_SPKR_2]; - + th_vi_v_vali_cfg->num_ch = this_afe.num_spkrs; + for (i = 0; i < this_afe.num_spkrs; i++) { + ch_v_vali_cfg[i].wait_time_ms = + this_afe.v_vali_cfg.wait_time[i]; + ch_v_vali_cfg[i].vali_time_ms = + this_afe.v_vali_cfg.vali_time[i]; + } if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_CFG, (union afe_spkr_prot_config *)tmp_ptr, size)) @@ -2492,7 +2486,7 @@ static void afe_send_cal_spv4_tx(int port_id) (this_afe.vi_tx_port == port_id) && (this_afe.prot_cfg.sp_version >= AFE_API_VERSION_V9)) { size = sizeof(struct afe_sp_v4_param_ex_vi_ftm_cfg) + - (SP_V2_NUM_MAX_SPKRS * + (this_afe.num_spkrs * sizeof(struct afe_sp_v4_channel_ex_vi_ftm)); tmp_ptr = kzalloc(size, GFP_KERNEL); if (!tmp_ptr) { @@ -2514,17 +2508,14 @@ static void afe_send_cal_spv4_tx(int port_id) sizeof(struct afe_sp_v4_param_ex_vi_mode_cfg))) pr_info("%s: ex vi mode cfg failed\n", __func__); - ex_vi_ftm_cfg->num_ch = SP_V2_NUM_MAX_SPKRS; - - ch_ex_vi_ftm_cfg[SP_V2_SPKR_1].wait_time_ms = - this_afe.ex_ftm_cfg.wait_time[SP_V2_SPKR_1]; - ch_ex_vi_ftm_cfg[SP_V2_SPKR_2].wait_time_ms = - this_afe.ex_ftm_cfg.wait_time[SP_V2_SPKR_2]; - ch_ex_vi_ftm_cfg[SP_V2_SPKR_1].ftm_time_ms = - this_afe.ex_ftm_cfg.ftm_time[SP_V2_SPKR_1]; - ch_ex_vi_ftm_cfg[SP_V2_SPKR_2].ftm_time_ms = - this_afe.ex_ftm_cfg.ftm_time[SP_V2_SPKR_2]; + ex_vi_ftm_cfg->num_ch = this_afe.num_spkrs; + for (i = 0; i < this_afe.num_spkrs; i++) { + ch_ex_vi_ftm_cfg[i].wait_time_ms = + this_afe.ex_ftm_cfg.wait_time[i]; + ch_ex_vi_ftm_cfg[i].ftm_time_ms = + this_afe.ex_ftm_cfg.ftm_time[i]; + } if (afe_spk_prot_prepare(port_id, 0, AFE_PARAM_ID_SP_V4_EX_VI_FTM_CFG, (union afe_spkr_prot_config *)tmp_ptr, size)) @@ -8432,8 +8423,11 @@ int afe_close(int port_id) * even if ramp down configuration failed it is not serious enough to * warrant bailaing out. */ - if (afe_spk_ramp_dn_cfg(port_id) < 0) - pr_err("%s: ramp down configuration failed\n", __func__); + if (q6core_get_avcs_api_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_AFE_V) < AFE_API_VERSION_V9) { + if (afe_spk_ramp_dn_cfg(port_id) < 0) + pr_err("%s: ramp down config failed\n", __func__); + } stop.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); @@ -9574,6 +9568,7 @@ int afe_spk_prot_feed_back_cfg(int src_port, int dst_port, this_afe.v4_ch_map_cfg.chan_info[index++] = 4; } this_afe.v4_ch_map_cfg.num_channels = index; + this_afe.num_spkrs = index / 2; pr_debug("%s no of channels: %d\n", __func__, index); this_afe.vi_tx_port = src_port; this_afe.vi_rx_port = dst_port; -- GitLab From 77ab1182b29e6e390fca1c31d68daccaf03db23c Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Wed, 5 Aug 2020 23:26:06 -0700 Subject: [PATCH 1591/1645] ASoC: wsa883x: add function to get swr device number Add a function in wsa883x which returns the sound wire device number for a given wsa883x codec slave instance. Change-Id: Ie3d0e309870f488b1643a853bcddcf93314d94b5 Signed-off-by: Vignesh Kulothungan --- asoc/codecs/wsa883x/wsa883x.c | 24 ++++++++++++++++++++++++ asoc/codecs/wsa883x/wsa883x.h | 5 +++++ 2 files changed, 29 insertions(+) diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 8a5e99e4c980..edfeceee9464 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -770,6 +770,30 @@ int wsa883x_codec_info_create_codec_entry(struct snd_info_entry *codec_root, } EXPORT_SYMBOL(wsa883x_codec_info_create_codec_entry); +/* + * wsa883x_codec_get_dev_num - returns swr device number + * @component: Codec instance + * + * Return: swr device number on success or negative error + * code on failure. + */ +int wsa883x_codec_get_dev_num(struct snd_soc_component *component) +{ + struct wsa883x_priv *wsa883x; + + if (!component) + return -EINVAL; + + wsa883x = snd_soc_component_get_drvdata(component); + if (!wsa883x) { + pr_err("%s: wsa883x component is NULL\n", __func__); + return -EINVAL; + } + + return wsa883x->swr_slave->dev_num; +} +EXPORT_SYMBOL(wsa883x_codec_get_dev_num); + static int wsa883x_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { diff --git a/asoc/codecs/wsa883x/wsa883x.h b/asoc/codecs/wsa883x/wsa883x.h index e080134eb016..bb719831ed61 100644 --- a/asoc/codecs/wsa883x/wsa883x.h +++ b/asoc/codecs/wsa883x/wsa883x.h @@ -21,6 +21,7 @@ int wsa883x_set_channel_map(struct snd_soc_component *component, int wsa883x_codec_info_create_codec_entry( struct snd_info_entry *codec_root, struct snd_soc_component *component); +int wsa883x_codec_get_dev_num(struct snd_soc_component *component); #else static int wsa883x_set_channel_map(struct snd_soc_component *component, u8 *port, u8 num_port, unsigned int *ch_mask, @@ -36,6 +37,10 @@ static int wsa883x_codec_info_create_codec_entry( return 0; } +static int wsa883x_codec_get_dev_num(struct snd_soc_component *component) +{ + return 0; +} #endif #endif /* _WSA883X_H */ -- GitLab From 1f3c09dacf46067bedf4ef1fb9fb6e5b642d058a Mon Sep 17 00:00:00 2001 From: Saurav Kumar Date: Thu, 10 Sep 2020 16:06:16 +0530 Subject: [PATCH 1592/1645] dsp: add change to handle use-after-free in cal_utils_is_cal_stale Add change to address the race condition between pointer dereference and memory deallocation. Change-Id: Ia1ed47986ec81d3dc2feb3bc874847fadddac292 Signed-off-by: Saurav Kumar --- asoc/msm-pcm-routing-v2.c | 4 ++-- dsp/audio_cal_utils.c | 38 +++++++++++++++++++++++++++++++---- dsp/audio_calibration.c | 3 ++- dsp/q6adm.c | 11 +++++----- dsp/q6afe.c | 14 ++++++------- dsp/q6asm.c | 6 +++--- include/dsp/audio_cal_utils.h | 6 ++++-- 7 files changed, 58 insertions(+), 24 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 03603a2cf672..7d05543dcfd4 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1177,7 +1177,7 @@ static struct cal_block_data *msm_routing_find_topology_by_path(int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block)) + if (cal_utils_is_cal_stale(cal_block, cal_data[cal_index])) continue; if (((struct audio_cal_info_adm_top *)cal_block @@ -1207,7 +1207,7 @@ static struct cal_block_data *msm_routing_find_topology(int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block)) + if (cal_utils_is_cal_stale(cal_block, cal_data[cal_index])) continue; cal_info = (struct audio_cal_info_adm_top *) diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index 8e0d7e03196f..cc66c2d43b9d 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -10,6 +10,8 @@ #include #include +spinlock_t cal_lock; + static int unmap_memory(struct cal_type_data *cal_type, struct cal_block_data *cal_block); @@ -899,6 +901,7 @@ int cal_utils_dealloc_cal(size_t data_size, void *data, int ret = 0; struct cal_block_data *cal_block; struct audio_cal_type_dealloc *dealloc_data = data; + unsigned long flags = 0; pr_debug("%s\n", __func__); @@ -946,7 +949,9 @@ int cal_utils_dealloc_cal(size_t data_size, void *data, if (ret < 0) goto err; + spin_lock_irqsave(&cal_lock, flags); delete_cal_block(cal_block); + spin_unlock_irqrestore(&cal_lock, flags); err: mutex_unlock(&cal_type->lock); done: @@ -1061,18 +1066,43 @@ void cal_utils_mark_cal_used(struct cal_block_data *cal_block) } EXPORT_SYMBOL(cal_utils_mark_cal_used); +int __init cal_utils_init(void) +{ + spin_lock_init(&cal_lock); + return 0; +} /** * cal_utils_is_cal_stale * * @cal_block: pointer to cal block * + * @cal_type: pointer to the cal type + * * Returns true if cal block is stale, false otherwise */ -bool cal_utils_is_cal_stale(struct cal_block_data *cal_block) +bool cal_utils_is_cal_stale(struct cal_block_data *cal_block, struct cal_type_data *cal_type) { - if ((cal_block) && (cal_block->cal_stale)) - return true; + bool ret = false; + unsigned long flags = 0; + + if (!cal_type) { + pr_err("%s: cal_type is Null", __func__); + goto done; + } + + spin_lock_irqsave(&cal_lock, flags); + cal_block = cal_utils_get_only_cal_block(cal_type); + if (!cal_block) { + pr_err("%s: cal_block is Null", __func__); + goto unlock; + } - return false; + if (cal_block->cal_stale) + ret = true; + +unlock: + spin_unlock_irqrestore(&cal_lock, flags); +done: + return ret; } EXPORT_SYMBOL(cal_utils_is_cal_stale); diff --git a/dsp/audio_calibration.c b/dsp/audio_calibration.c index a5167be3cfaa..854d882191f6 100644 --- a/dsp/audio_calibration.c +++ b/dsp/audio_calibration.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2014, 2016-2017, 2020, The Linux Foundation. All rights reserved. */ #include #include @@ -591,6 +591,7 @@ int __init audio_cal_init(void) pr_debug("%s\n", __func__); + cal_utils_init(); memset(&audio_cal, 0, sizeof(audio_cal)); mutex_init(&audio_cal.common_lock); for (; i < MAX_CAL_TYPES; i++) { diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 51ca185b9ca2..ed1a50a17cec 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2004,7 +2004,7 @@ static void send_adm_custom_topology(void) this_adm.set_custom_topology = 0; cal_block = cal_utils_get_only_cal_block(this_adm.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index])) goto unlock; pr_debug("%s: Sending cal_index %d\n", __func__, cal_index); @@ -2144,7 +2144,7 @@ static struct cal_block_data *adm_find_cal_by_path(int cal_index, int path) cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block)) + if (cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index])) continue; if (cal_index == ADM_AUDPROC_CAL || @@ -2183,7 +2183,7 @@ static struct cal_block_data *adm_find_cal_by_app_type(int cal_index, int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block)) + if (cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index])) continue; if (cal_index == ADM_AUDPROC_CAL || @@ -2225,7 +2225,7 @@ static struct cal_block_data *adm_find_cal(int cal_index, int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block)) + if (cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index])) continue; if (cal_index == ADM_AUDPROC_CAL || @@ -3963,7 +3963,8 @@ int send_rtac_audvol_cal(void) cal_block = cal_utils_get_only_cal_block( this_adm.cal_data[ADM_RTAC_AUDVOL_CAL]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, + this_adm.cal_data[ADM_RTAC_AUDVOL_CAL])) { pr_err("%s: can't find cal block!\n", __func__); goto unlock; } diff --git a/dsp/q6afe.c b/dsp/q6afe.c index c9a5c95e4d29..8cb25197e740 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2108,7 +2108,7 @@ static void afe_send_custom_topology(void) goto unlock; this_afe.set_custom_topology = 0; cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) { pr_err("%s cal_block not found!!\n", __func__); goto unlock; } @@ -2852,7 +2852,7 @@ static struct cal_block_data *afe_find_cal_topo_id_by_port( cal_block = list_entry(ptr, struct cal_block_data, list); /* Skip cal_block if it is already marked stale */ - if (cal_utils_is_cal_stale(cal_block)) + if (cal_utils_is_cal_stale(cal_block, cal_type)) continue; pr_info("%s: port id: 0x%x, dev_acdb_id: %d\n", __func__, port_id, this_afe.dev_acdb_id[afe_port_index]); @@ -3290,8 +3290,8 @@ static int send_afe_cal_type(int cal_index, int port_id) cal_block = cal_utils_get_only_cal_block( this_afe.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { - pr_err("%s cal_block not found!!\n", __func__); + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) { + pr_err_ratelimited("%s cal_block not found!!\n", __func__); ret = -EINVAL; goto unlock; } @@ -7727,7 +7727,7 @@ static int afe_sidetone_iir(u16 tx_port_id) } mutex_lock(&this_afe.cal_data[cal_index]->lock); cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) { pr_err("%s: cal_block not found\n ", __func__); mutex_unlock(&this_afe.cal_data[cal_index]->lock); ret = -EINVAL; @@ -7854,7 +7854,7 @@ static int afe_sidetone(u16 tx_port_id, u16 rx_port_id, bool enable) mutex_lock(&this_afe.cal_data[cal_index]->lock); cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) { pr_err("%s: cal_block not found\n", __func__); mutex_unlock(&this_afe.cal_data[cal_index]->lock); ret = -EINVAL; @@ -9758,7 +9758,7 @@ static struct cal_block_data *afe_find_hw_delay_by_path( cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block)) + if (cal_utils_is_cal_stale(cal_block, cal_type)) continue; if (((struct audio_cal_info_hw_delay *)cal_block->cal_info) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 235cdbd468ec..2a078eadbb7c 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -808,7 +808,7 @@ int send_asm_custom_topology(struct audio_client *ac) set_custom_topology = 0; cal_block = cal_utils_get_only_cal_block(cal_data[ASM_CUSTOM_TOP_CAL]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, cal_data[ASM_CUSTOM_TOP_CAL])) goto unlock; if (cal_block->cal_data.size == 0) { @@ -11092,7 +11092,7 @@ static int q6asm_get_asm_topology_apptype(struct q6asm_cal_info *cal_info) mutex_lock(&cal_data[ASM_TOPOLOGY_CAL]->lock); cal_block = cal_utils_get_only_cal_block(cal_data[ASM_TOPOLOGY_CAL]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, cal_data[ASM_CUSTOM_TOP_CAL])) goto unlock; cal_info->topology_id = ((struct audio_cal_info_asm_top *) cal_block->cal_info)->topology; @@ -11152,7 +11152,7 @@ int q6asm_send_cal(struct audio_client *ac) goto unlock; } - if (cal_utils_is_cal_stale(cal_block)) { + if (cal_utils_is_cal_stale(cal_block, cal_data[ASM_AUDSTRM_CAL])) { rc = 0; /* not error case */ pr_debug("%s: cal_block is stale\n", __func__); diff --git a/include/dsp/audio_cal_utils.h b/include/dsp/audio_cal_utils.h index 0607815037f0..0507486c9f8f 100644 --- a/include/dsp/audio_cal_utils.h +++ b/include/dsp/audio_cal_utils.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2014, 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2014, 2018, 2020, The Linux Foundation. All rights reserved. */ #ifndef _AUDIO_CAL_UTILS_H #define _AUDIO_CAL_UTILS_H @@ -94,5 +94,7 @@ int32_t cal_utils_get_cal_type_version(void *cal_type_data); void cal_utils_mark_cal_used(struct cal_block_data *cal_block); -bool cal_utils_is_cal_stale(struct cal_block_data *cal_block); +bool cal_utils_is_cal_stale(struct cal_block_data *cal_block, struct cal_type_data *cal_type); + +int cal_utils_init(void); #endif -- GitLab From 811d618ec9df3ab9cd4df21cbce0242c4ecb1a1f Mon Sep 17 00:00:00 2001 From: Saurav Kumar Date: Thu, 22 Oct 2020 15:49:26 +0530 Subject: [PATCH 1593/1645] dsp: add change to enable preemption at cal_utils_dealloc_cal. Add change to enable preemption at cal_utils_dealloc_cal. Change-Id: I3d9304851f4d61d7afb82c0512421159ec788db1 Signed-off-by: Saurav Kumar --- asoc/msm-pcm-routing-v2.c | 4 ++-- dsp/audio_cal_utils.c | 25 +++++++------------------ dsp/q6adm.c | 11 +++++------ dsp/q6afe.c | 12 ++++++------ dsp/q6asm.c | 6 +++--- include/dsp/audio_cal_utils.h | 2 +- 6 files changed, 24 insertions(+), 36 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 7d05543dcfd4..03603a2cf672 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1177,7 +1177,7 @@ static struct cal_block_data *msm_routing_find_topology_by_path(int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block, cal_data[cal_index])) + if (cal_utils_is_cal_stale(cal_block)) continue; if (((struct audio_cal_info_adm_top *)cal_block @@ -1207,7 +1207,7 @@ static struct cal_block_data *msm_routing_find_topology(int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block, cal_data[cal_index])) + if (cal_utils_is_cal_stale(cal_block)) continue; cal_info = (struct audio_cal_info_adm_top *) diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index cc66c2d43b9d..0f37fda418e5 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -10,7 +10,7 @@ #include #include -spinlock_t cal_lock; +struct mutex cal_lock; static int unmap_memory(struct cal_type_data *cal_type, struct cal_block_data *cal_block); @@ -901,7 +901,6 @@ int cal_utils_dealloc_cal(size_t data_size, void *data, int ret = 0; struct cal_block_data *cal_block; struct audio_cal_type_dealloc *dealloc_data = data; - unsigned long flags = 0; pr_debug("%s\n", __func__); @@ -949,9 +948,9 @@ int cal_utils_dealloc_cal(size_t data_size, void *data, if (ret < 0) goto err; - spin_lock_irqsave(&cal_lock, flags); + mutex_lock(&cal_lock); delete_cal_block(cal_block); - spin_unlock_irqrestore(&cal_lock, flags); + mutex_unlock(&cal_lock); err: mutex_unlock(&cal_type->lock); done: @@ -1068,7 +1067,7 @@ EXPORT_SYMBOL(cal_utils_mark_cal_used); int __init cal_utils_init(void) { - spin_lock_init(&cal_lock); + mutex_init(&cal_lock); return 0; } /** @@ -1076,22 +1075,13 @@ int __init cal_utils_init(void) * * @cal_block: pointer to cal block * - * @cal_type: pointer to the cal type - * * Returns true if cal block is stale, false otherwise */ -bool cal_utils_is_cal_stale(struct cal_block_data *cal_block, struct cal_type_data *cal_type) +bool cal_utils_is_cal_stale(struct cal_block_data *cal_block) { bool ret = false; - unsigned long flags = 0; - - if (!cal_type) { - pr_err("%s: cal_type is Null", __func__); - goto done; - } - spin_lock_irqsave(&cal_lock, flags); - cal_block = cal_utils_get_only_cal_block(cal_type); + mutex_lock(&cal_lock); if (!cal_block) { pr_err("%s: cal_block is Null", __func__); goto unlock; @@ -1101,8 +1091,7 @@ bool cal_utils_is_cal_stale(struct cal_block_data *cal_block, struct cal_type_da ret = true; unlock: - spin_unlock_irqrestore(&cal_lock, flags); -done: + mutex_unlock(&cal_lock); return ret; } EXPORT_SYMBOL(cal_utils_is_cal_stale); diff --git a/dsp/q6adm.c b/dsp/q6adm.c index ed1a50a17cec..51ca185b9ca2 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2004,7 +2004,7 @@ static void send_adm_custom_topology(void) this_adm.set_custom_topology = 0; cal_block = cal_utils_get_only_cal_block(this_adm.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index])) + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) goto unlock; pr_debug("%s: Sending cal_index %d\n", __func__, cal_index); @@ -2144,7 +2144,7 @@ static struct cal_block_data *adm_find_cal_by_path(int cal_index, int path) cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index])) + if (cal_utils_is_cal_stale(cal_block)) continue; if (cal_index == ADM_AUDPROC_CAL || @@ -2183,7 +2183,7 @@ static struct cal_block_data *adm_find_cal_by_app_type(int cal_index, int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index])) + if (cal_utils_is_cal_stale(cal_block)) continue; if (cal_index == ADM_AUDPROC_CAL || @@ -2225,7 +2225,7 @@ static struct cal_block_data *adm_find_cal(int cal_index, int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index])) + if (cal_utils_is_cal_stale(cal_block)) continue; if (cal_index == ADM_AUDPROC_CAL || @@ -3963,8 +3963,7 @@ int send_rtac_audvol_cal(void) cal_block = cal_utils_get_only_cal_block( this_adm.cal_data[ADM_RTAC_AUDVOL_CAL]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, - this_adm.cal_data[ADM_RTAC_AUDVOL_CAL])) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { pr_err("%s: can't find cal block!\n", __func__); goto unlock; } diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 8cb25197e740..283d425b8c81 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2108,7 +2108,7 @@ static void afe_send_custom_topology(void) goto unlock; this_afe.set_custom_topology = 0; cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { pr_err("%s cal_block not found!!\n", __func__); goto unlock; } @@ -2852,7 +2852,7 @@ static struct cal_block_data *afe_find_cal_topo_id_by_port( cal_block = list_entry(ptr, struct cal_block_data, list); /* Skip cal_block if it is already marked stale */ - if (cal_utils_is_cal_stale(cal_block, cal_type)) + if (cal_utils_is_cal_stale(cal_block)) continue; pr_info("%s: port id: 0x%x, dev_acdb_id: %d\n", __func__, port_id, this_afe.dev_acdb_id[afe_port_index]); @@ -3290,7 +3290,7 @@ static int send_afe_cal_type(int cal_index, int port_id) cal_block = cal_utils_get_only_cal_block( this_afe.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { pr_err_ratelimited("%s cal_block not found!!\n", __func__); ret = -EINVAL; goto unlock; @@ -7727,7 +7727,7 @@ static int afe_sidetone_iir(u16 tx_port_id) } mutex_lock(&this_afe.cal_data[cal_index]->lock); cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { pr_err("%s: cal_block not found\n ", __func__); mutex_unlock(&this_afe.cal_data[cal_index]->lock); ret = -EINVAL; @@ -7854,7 +7854,7 @@ static int afe_sidetone(u16 tx_port_id, u16 rx_port_id, bool enable) mutex_lock(&this_afe.cal_data[cal_index]->lock); cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { pr_err("%s: cal_block not found\n", __func__); mutex_unlock(&this_afe.cal_data[cal_index]->lock); ret = -EINVAL; @@ -9758,7 +9758,7 @@ static struct cal_block_data *afe_find_hw_delay_by_path( cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block, cal_type)) + if (cal_utils_is_cal_stale(cal_block)) continue; if (((struct audio_cal_info_hw_delay *)cal_block->cal_info) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 2a078eadbb7c..235cdbd468ec 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -808,7 +808,7 @@ int send_asm_custom_topology(struct audio_client *ac) set_custom_topology = 0; cal_block = cal_utils_get_only_cal_block(cal_data[ASM_CUSTOM_TOP_CAL]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, cal_data[ASM_CUSTOM_TOP_CAL])) + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) goto unlock; if (cal_block->cal_data.size == 0) { @@ -11092,7 +11092,7 @@ static int q6asm_get_asm_topology_apptype(struct q6asm_cal_info *cal_info) mutex_lock(&cal_data[ASM_TOPOLOGY_CAL]->lock); cal_block = cal_utils_get_only_cal_block(cal_data[ASM_TOPOLOGY_CAL]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, cal_data[ASM_CUSTOM_TOP_CAL])) + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) goto unlock; cal_info->topology_id = ((struct audio_cal_info_asm_top *) cal_block->cal_info)->topology; @@ -11152,7 +11152,7 @@ int q6asm_send_cal(struct audio_client *ac) goto unlock; } - if (cal_utils_is_cal_stale(cal_block, cal_data[ASM_AUDSTRM_CAL])) { + if (cal_utils_is_cal_stale(cal_block)) { rc = 0; /* not error case */ pr_debug("%s: cal_block is stale\n", __func__); diff --git a/include/dsp/audio_cal_utils.h b/include/dsp/audio_cal_utils.h index 0507486c9f8f..99f619f23c37 100644 --- a/include/dsp/audio_cal_utils.h +++ b/include/dsp/audio_cal_utils.h @@ -94,7 +94,7 @@ int32_t cal_utils_get_cal_type_version(void *cal_type_data); void cal_utils_mark_cal_used(struct cal_block_data *cal_block); -bool cal_utils_is_cal_stale(struct cal_block_data *cal_block, struct cal_type_data *cal_type); +bool cal_utils_is_cal_stale(struct cal_block_data *cal_block); int cal_utils_init(void); #endif -- GitLab From cd9b0b0b6cabdf23433ecfe5ea3f9a282fd943c6 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 31 Jul 2020 10:34:29 +0530 Subject: [PATCH 1594/1645] ASoC: tx-macro: Allow regcache sync during clock enablement Allow regcache sync during clock enable to make sure the registers are in proper state before the usecase. Change-Id: I8a9214e460c7f77759d1956e0e7e2d6b2f5b3d3a Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/tx-macro.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 7e982fac449e..de04e1e90c49 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -234,11 +234,11 @@ static int tx_macro_mclk_enable(struct tx_macro_priv *tx_priv, } bolero_clk_rsc_fs_gen_request(tx_priv->dev, true); + regcache_mark_dirty(regmap); + regcache_sync_region(regmap, + TX_START_OFFSET, + TX_MAX_OFFSET); if (tx_priv->tx_mclk_users == 0) { - regcache_mark_dirty(regmap); - regcache_sync_region(regmap, - TX_START_OFFSET, - TX_MAX_OFFSET); /* 9.6MHz MCLK, set value 0x00 if other frequency */ regmap_update_bits(regmap, BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK, 0x01, 0x01); -- GitLab From 123608cd5c3bb00998570cc2e1f10a5681cd1a3e Mon Sep 17 00:00:00 2001 From: Faiz Nabi Kuchay Date: Thu, 8 Oct 2020 12:52:19 +0530 Subject: [PATCH 1595/1645] ASoC: lagoon: add support for CPS speaker protection Add support to parse static cps configuration from dt. Add support to send cps configuration for speaker protection usecases. Change-Id: I0166a378f24cedef07393bdbb8618df944c62984 Signed-off-by: Faiz Nabi Kuchay --- asoc/kona.c | 253 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+) diff --git a/asoc/kona.c b/asoc/kona.c index 5192e3eca753..6564917d1f60 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -86,6 +86,8 @@ #define WCN_CDC_SLIM_TX_CH_MAX 2 #define WCN_CDC_SLIM_TX_CH_MAX_LITO 3 +#define SWR_MAX_SLAVE_DEVICES 6 + enum { RX_PATH = 0, TX_PATH, @@ -193,7 +195,10 @@ struct msm_asoc_mach_data { struct device_node *fsa_handle; struct clk *lpass_audio_hw_vote; int core_audio_vote_count; + u32 wsa_max_devs; u32 tdm_max_slots; /* Max TDM slots used */ + int (*get_wsa_dev_num)(struct snd_soc_component*); + struct afe_cps_hw_intf_cfg cps_config; }; struct tdm_port { @@ -2689,6 +2694,12 @@ static int msm_get_port_id(int be_id) case MSM_BACKEND_DAI_SENARY_MI2S_TX: afe_port_id = AFE_PORT_ID_SENARY_MI2S_TX; break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0: + afe_port_id = AFE_PORT_ID_WSA_CODEC_DMA_RX_0; + break; + case MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0: + afe_port_id = AFE_PORT_ID_WSA_CODEC_DMA_TX_0; + break; case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0: afe_port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0; break; @@ -4900,6 +4911,121 @@ static int msm_snd_cdc_dma_startup(struct snd_pcm_substream *substream) return ret; } +static void set_cps_config(struct snd_soc_pcm_runtime *rtd, + u32 num_ch, u32 ch_mask) +{ + int i = 0; + int val = 0; + u8 dev_num = 0; + int ch_configured = 0; + int j = 0; + int n = 0; + char wsa_cdc_name[DEV_NAME_STR_LEN]; + struct snd_soc_component *component = NULL; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct msm_asoc_mach_data *pdata = + snd_soc_card_get_drvdata(rtd->card); + + if (!pdata) { + pr_err("%s: pdata is NULL\n", __func__); + return; + } + + if (!num_ch) { + pr_err("%s: channel count is 0\n", __func__); + return; + } + + if (!pdata->get_wsa_dev_num) { + pr_err("%s: get_wsa_dev_num is NULL\n", __func__); + return; + } + + if (!pdata->cps_config.spkr_dep_cfg) { + pr_debug("%s: spkr_dep_cfg is NULL\n", __func__); + return; + } + + if (!pdata->cps_config.hw_reg_cfg.lpass_wr_cmd_reg_phy_addr || + !pdata->cps_config.hw_reg_cfg.lpass_rd_cmd_reg_phy_addr || + !pdata->cps_config.hw_reg_cfg.lpass_rd_fifo_reg_phy_addr) { + pr_err("%s: cps static configuration is not set\n", __func__); + return; + } + + pdata->cps_config.lpass_hw_intf_cfg_mode = 1; + + while (ch_configured < num_ch) { + if (!(ch_mask & (1 << i))) { + i++; + continue; + } + + snprintf(wsa_cdc_name, sizeof(wsa_cdc_name), "wsa-codec.%d", + i+1); + + /* Use n to make sure both WSA components are retrieved */ + /* When first WSA component is retrieved adjust looping + variable such that the next time only the remaining part + of the array is traversed */ + for (j = n; j < rtd->card->num_aux_devs; j++) + { + if (msm_codec_conf[j].name_prefix != NULL ) { + if (strstr(msm_codec_conf[j].name_prefix, + "Left")) { + component = soc_find_component_locked( + msm_aux_dev[j].codec_of_node, + NULL); + n = j+1; + break; + } + else if (strstr(msm_codec_conf[j].name_prefix, + "Right")) { + component = soc_find_component_locked( + msm_aux_dev[j].codec_of_node, + NULL); + n = j+1; + break; + } + } + } + + if (!component) { + pr_err("%s: %s component is NULL\n", __func__, + wsa_cdc_name); + return; + } + + dev_num = pdata->get_wsa_dev_num(component); + if (dev_num < 0 || dev_num > SWR_MAX_SLAVE_DEVICES) { + pr_err("%s: invalid slave dev num : %d\n", __func__, + dev_num); + return; + } + + /* Clear stale dev num info */ + pdata->cps_config.spkr_dep_cfg[i].vbatt_pkd_reg_addr &= 0xFFFF; + pdata->cps_config.spkr_dep_cfg[i].temp_pkd_reg_addr &= 0xFFFF; + + val = 0; + + /* bits 20:23 carry swr device number */ + val |= dev_num << 20; + + /* bits 24:27 carry read length in bytes */ + val |= 1 << 24; + + /* Update dev num in packed reg addr */ + pdata->cps_config.spkr_dep_cfg[i].vbatt_pkd_reg_addr |= val; + pdata->cps_config.spkr_dep_cfg[i].temp_pkd_reg_addr |= val; + i++; + ch_configured++; + } + + afe_set_cps_config(msm_get_port_id(dai_link->id), + &pdata->cps_config, ch_mask); +} + static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -4947,6 +5073,11 @@ static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream, goto err; } + if (dai_link->id == MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0 || + dai_link->id == MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1) { + set_cps_config(rtd, user_set_rx_ch, + rx_ch_cdc_dma); + } } break; } @@ -8229,6 +8360,115 @@ static int msm_audio_ssr_register(struct device *dev) return ret; } +static void parse_cps_configuration(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata) +{ + int ret = 0; + int i = 0, j = 0; + u32 dt_values[MAX_CPS_LEVELS]; + + if (!pdev || !pdata || !pdata->wsa_max_devs) + return; + + pdata->get_wsa_dev_num = wsa883x_codec_get_dev_num; + pdata->cps_config.hw_reg_cfg.num_spkr = pdata->wsa_max_devs; + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,cps_reg_phy_addr", dt_values, + sizeof(dt_values)/sizeof(dt_values[0])); + if (ret) { + dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "qcom,cps_reg_phy_addr"); + } else { + pdata->cps_config.hw_reg_cfg.lpass_wr_cmd_reg_phy_addr = + dt_values[0]; + pdata->cps_config.hw_reg_cfg.lpass_rd_cmd_reg_phy_addr = + dt_values[1]; + pdata->cps_config.hw_reg_cfg.lpass_rd_fifo_reg_phy_addr = + dt_values[2]; + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,cps_threshold_levels", dt_values, + sizeof(dt_values)/sizeof(dt_values[0]) - 1); + if (ret) { + dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "qcom,cps_threshold_levels"); + } else { + pdata->cps_config.hw_reg_cfg.vbatt_lower2_threshold = + dt_values[0]; + pdata->cps_config.hw_reg_cfg.vbatt_lower1_threshold = + dt_values[1]; + } + + pdata->cps_config.spkr_dep_cfg = devm_kzalloc(&pdev->dev, + sizeof(struct lpass_swr_spkr_dep_cfg_t) + * pdata->wsa_max_devs, GFP_KERNEL); + if (!pdata->cps_config.spkr_dep_cfg) { + dev_err(&pdev->dev, "%s: spkr dep cfg alloc failed\n", __func__); + return; + } + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,cps_wsa_vbatt_temp_reg_addr", dt_values, + sizeof(dt_values)/sizeof(dt_values[0]) - 1); + if (ret) { + dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "qcom,cps_wsa_vbatt_temp_reg_addr"); + } else { + for (i = 0; i < pdata->wsa_max_devs; i++) { + pdata->cps_config.spkr_dep_cfg[i].vbatt_pkd_reg_addr = + dt_values[0]; + pdata->cps_config.spkr_dep_cfg[i].temp_pkd_reg_addr = + dt_values[1]; + } + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,cps_normal_values", dt_values, + sizeof(dt_values)/sizeof(dt_values[0])); + if (ret) { + dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "qcom,cps_normal_values"); + } else { + for (i = 0; i < pdata->wsa_max_devs; i++) { + for (j = 0; j < MAX_CPS_LEVELS; j++) { + pdata->cps_config.spkr_dep_cfg[i]. + value_normal_thrsd[j] = dt_values[j]; + } + } + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,cps_lower1_values", dt_values, + sizeof(dt_values)/sizeof(dt_values[0])); + if (ret) { + dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "qcom,cps_lower1_values"); + } else { + for (i = 0; i < pdata->wsa_max_devs; i++) { + for (j = 0; j < MAX_CPS_LEVELS; j++) { + pdata->cps_config.spkr_dep_cfg[i]. + value_low1_thrsd[j] = dt_values[j]; + } + } + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,cps_lower2_values", dt_values, + sizeof(dt_values)/sizeof(dt_values[0])); + if (ret) { + dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n", + __func__, "qcom,cps_lower2_values"); + } else { + for (i = 0; i < pdata->wsa_max_devs; i++) { + for (j = 0; j < MAX_CPS_LEVELS; j++) { + pdata->cps_config.spkr_dep_cfg[i]. + value_low2_thrsd[j] = dt_values[j]; + } + } + } +} + static int msm_asoc_machine_probe(struct platform_device *pdev) { struct snd_soc_card *card = NULL; @@ -8300,6 +8540,15 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) dev_info(&pdev->dev, "%s: Sound card %s registered\n", __func__, card->name); + /* Get maximum WSA device count for this platform */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,wsa-max-devs", &pdata->wsa_max_devs); + if (ret) { + dev_err(&pdev->dev, "%s: No DT match for wsa max devs\n", + __func__); + pdata->wsa_max_devs = 0; + } + ret = of_property_read_u32(pdev->dev.of_node, "qcom,tdm-max-slots", &pdata->tdm_max_slots); if (ret) { @@ -8412,6 +8661,10 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) atomic_set(&(pdata->mi2s_gpio_ref_count[index]), 0); } + /* parse cps configuration from dt */ + if (of_property_read_bool(pdev->dev.of_node, "qcom,cps_reg_phy_addr")) + parse_cps_configuration(pdev, pdata); + /* Register LPASS audio hw vote */ lpass_audio_hw_vote = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote"); if (IS_ERR(lpass_audio_hw_vote)) { -- GitLab From 290930211b84092b80da27ed66f11864934c0a1c Mon Sep 17 00:00:00 2001 From: Faiz Nabi Kuchay Date: Thu, 8 Oct 2020 18:25:49 +0530 Subject: [PATCH 1596/1645] dsp: add afe function to send cps configuration Define cps hw interface configuration structures. Add AFE_PARAM_ID_CPS_LPASS_HW_INTF_CFG parameter id. Add a function to send afe cps speaker protection configuration. Change-Id: I865e9981b6dd1da4b9ef1a3e18be82cea2996309 Signed-off-by: Faiz Nabi Kuchay --- dsp/q6afe.c | 102 +++++++++++++++++++++++++++++++++++++ include/dsp/apr_audio-v2.h | 26 ++++++++++ include/dsp/q6afe-v2.h | 3 ++ 3 files changed, 131 insertions(+) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 58d440b0e323..c96011a35ed6 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -247,6 +247,8 @@ struct afe_ctl { uint32_t initial_cal; uint32_t v_vali_flag; uint32_t num_spkrs; + uint32_t cps_ch_mask; + struct afe_cps_hw_intf_cfg *cps_config; }; struct afe_clkinfo_per_port { @@ -2173,6 +2175,70 @@ static int afe_spk_ramp_dn_cfg(int port) return ret; } +static int afe_send_cps_config(int src_port) +{ + int i = 0; + struct param_hdr_v3 param_info; + int ret = -EINVAL; + u8 *packed_payload = NULL; + int cpy_size = 0; + int ch_copied = 0; + size_t param_size = 0; + + if ((-1 == this_afe.vi_tx_port) || (!this_afe.cps_ch_mask) || + (!this_afe.cps_config)) { + pr_err("%s: speaker prot not configured for 0x%x\n", __func__, + src_port); + return -EINVAL; + } + + param_size = sizeof(struct afe_cps_hw_intf_cfg) - + sizeof(this_afe.cps_config->spkr_dep_cfg) + + (sizeof(struct lpass_swr_spkr_dep_cfg_t) + * this_afe.num_spkrs); + + this_afe.cps_config->hw_reg_cfg.num_spkr = this_afe.num_spkrs; + packed_payload = kzalloc(param_size, GFP_KERNEL); + if (packed_payload == NULL) + return -ENOMEM; + + cpy_size = sizeof(struct afe_cps_hw_intf_cfg) - + sizeof(this_afe.cps_config->spkr_dep_cfg); + memcpy(packed_payload, this_afe.cps_config, cpy_size); + + while (ch_copied < this_afe.num_spkrs) { + if (!(this_afe.cps_ch_mask & (1 << i))) { + i++; + continue; + } + + memcpy(packed_payload + cpy_size, + &this_afe.cps_config->spkr_dep_cfg[i], + sizeof(struct lpass_swr_spkr_dep_cfg_t)); + cpy_size += sizeof(struct lpass_swr_spkr_dep_cfg_t); + ch_copied++; + i++; + } + + memset(¶m_info, 0, sizeof(param_info)); + param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_RX; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = AFE_PARAM_ID_CPS_LPASS_HW_INTF_CFG; + param_info.param_size = param_size; + + ret = q6afe_pack_and_set_param_in_band(src_port, + q6audio_get_port_index(src_port), + param_info, packed_payload); + if (ret) + pr_err("%s: port = 0x%x param = 0x%x failed %d\n", __func__, + src_port, param_info.param_id, ret); + + pr_debug("%s: config.pdata.param_id 0x%x status %d 0x%x\n", __func__, + param_info.param_id, ret, src_port); + kfree(packed_payload); + return ret; +} + static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, union afe_spkr_prot_config *prot_config, uint32_t param_size) { @@ -5268,6 +5334,11 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, afe_send_hw_delay(port_id, rate); } + if ((this_afe.cps_config) && + (this_afe.vi_rx_port == port_id)) { + afe_send_cps_config(port_id); + } + /* Start SW MAD module */ mad_type = afe_port_get_mad_type(port_id); pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, @@ -10811,3 +10882,34 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle) return ret; } EXPORT_SYMBOL(afe_unvote_lpass_core_hw); + +/** + * afe_set_cps_config - + * to set cps speaker protection configuration + * + * @src_port: source port to send configuration to + * @cps_config: cps speaker protection v4 configuration + * @ch_mask: channel mask + * + */ +void afe_set_cps_config(int src_port, + struct afe_cps_hw_intf_cfg *cps_config, + u32 ch_mask) +{ + this_afe.cps_config = NULL; + this_afe.cps_ch_mask = 0; + + if (!cps_config) { + pr_err("%s: cps config is NULL\n", __func__); + return; + } + + if (q6audio_validate_port(src_port) < 0) { + pr_err("%s: Invalid src port 0x%x\n", __func__, src_port); + return; + } + + this_afe.cps_ch_mask = ch_mask; + this_afe.cps_config = cps_config; +} +EXPORT_SYMBOL(afe_set_cps_config); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index eed5652f910e..dc51307ad5d2 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -10,6 +10,9 @@ #include #include +/* number of threshold levels in speaker protection module */ +#define MAX_CPS_LEVELS 3 + /* size of header needed for passing data out of band */ #define APR_CMD_OB_HDR_SZ 12 @@ -2364,6 +2367,28 @@ int16_t excursionf[AFE_SPKR_PROT_EXCURSIONF_LEN]; */ } __packed; +struct lpass_swr_spkr_dep_cfg_t { + uint32_t vbatt_pkd_reg_addr; + uint32_t temp_pkd_reg_addr; + uint32_t value_normal_thrsd[MAX_CPS_LEVELS]; + uint32_t value_low1_thrsd[MAX_CPS_LEVELS]; + uint32_t value_low2_thrsd[MAX_CPS_LEVELS]; +} __packed; + +struct lpass_swr_hw_reg_cfg_t { + uint32_t lpass_wr_cmd_reg_phy_addr; + uint32_t lpass_rd_cmd_reg_phy_addr; + uint32_t lpass_rd_fifo_reg_phy_addr; + uint32_t vbatt_lower1_threshold; + uint32_t vbatt_lower2_threshold; + uint32_t num_spkr; +} __packed; + +struct afe_cps_hw_intf_cfg { + uint32_t lpass_hw_intf_cfg_mode; + struct lpass_swr_hw_reg_cfg_t hw_reg_cfg; + struct lpass_swr_spkr_dep_cfg_t *spkr_dep_cfg; +} __packed; #define AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER 0x000100E0 @@ -10784,6 +10809,7 @@ struct cmd_set_topologies { #define AFE_PARAM_ID_FBSP_MODE_RX_CFG 0x0001021D #define AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG 0x00010260 #define AFE_PARAM_ID_SP_RX_TMAX_XMAX_LOGGING 0x000102BC +#define AFE_PARAM_ID_CPS_LPASS_HW_INTF_CFG 0x000102EF struct asm_fbsp_mode_rx_cfg { uint32_t minor_version; diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 8b82069a2f38..310de65c739d 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -432,6 +432,9 @@ int afe_pseudo_port_start_nowait(u16 port_id); int afe_pseudo_port_stop_nowait(u16 port_id); int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg); int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg); +void afe_set_cps_config(int src_port, + struct afe_cps_hw_intf_cfg *cps_config, + u32 ch_mask); int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg); int afe_set_digital_codec_core_clock(u16 port_id, struct afe_digital_clk_cfg *cfg); -- GitLab From 9beffd7d5b93b86c5d666b21e5496aec8305439a Mon Sep 17 00:00:00 2001 From: Saurav Kumar Date: Thu, 10 Sep 2020 16:06:16 +0530 Subject: [PATCH 1597/1645] dsp: add change to handle use-after-free in cal_utils_is_cal_stale Add change to address the race condition between pointer dereference and memory deallocation. Change-Id: Ia1ed47986ec81d3dc2feb3bc874847fadddac292 Signed-off-by: Saurav Kumar --- asoc/msm-pcm-routing-v2.c | 4 ++-- dsp/audio_cal_utils.c | 38 +++++++++++++++++++++++++++++++---- dsp/audio_calibration.c | 3 ++- dsp/q6adm.c | 11 +++++----- dsp/q6afe.c | 14 ++++++------- dsp/q6asm.c | 6 +++--- include/dsp/audio_cal_utils.h | 6 ++++-- 7 files changed, 58 insertions(+), 24 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 03603a2cf672..7d05543dcfd4 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1177,7 +1177,7 @@ static struct cal_block_data *msm_routing_find_topology_by_path(int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block)) + if (cal_utils_is_cal_stale(cal_block, cal_data[cal_index])) continue; if (((struct audio_cal_info_adm_top *)cal_block @@ -1207,7 +1207,7 @@ static struct cal_block_data *msm_routing_find_topology(int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block)) + if (cal_utils_is_cal_stale(cal_block, cal_data[cal_index])) continue; cal_info = (struct audio_cal_info_adm_top *) diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index 8e0d7e03196f..cc66c2d43b9d 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -10,6 +10,8 @@ #include #include +spinlock_t cal_lock; + static int unmap_memory(struct cal_type_data *cal_type, struct cal_block_data *cal_block); @@ -899,6 +901,7 @@ int cal_utils_dealloc_cal(size_t data_size, void *data, int ret = 0; struct cal_block_data *cal_block; struct audio_cal_type_dealloc *dealloc_data = data; + unsigned long flags = 0; pr_debug("%s\n", __func__); @@ -946,7 +949,9 @@ int cal_utils_dealloc_cal(size_t data_size, void *data, if (ret < 0) goto err; + spin_lock_irqsave(&cal_lock, flags); delete_cal_block(cal_block); + spin_unlock_irqrestore(&cal_lock, flags); err: mutex_unlock(&cal_type->lock); done: @@ -1061,18 +1066,43 @@ void cal_utils_mark_cal_used(struct cal_block_data *cal_block) } EXPORT_SYMBOL(cal_utils_mark_cal_used); +int __init cal_utils_init(void) +{ + spin_lock_init(&cal_lock); + return 0; +} /** * cal_utils_is_cal_stale * * @cal_block: pointer to cal block * + * @cal_type: pointer to the cal type + * * Returns true if cal block is stale, false otherwise */ -bool cal_utils_is_cal_stale(struct cal_block_data *cal_block) +bool cal_utils_is_cal_stale(struct cal_block_data *cal_block, struct cal_type_data *cal_type) { - if ((cal_block) && (cal_block->cal_stale)) - return true; + bool ret = false; + unsigned long flags = 0; + + if (!cal_type) { + pr_err("%s: cal_type is Null", __func__); + goto done; + } + + spin_lock_irqsave(&cal_lock, flags); + cal_block = cal_utils_get_only_cal_block(cal_type); + if (!cal_block) { + pr_err("%s: cal_block is Null", __func__); + goto unlock; + } - return false; + if (cal_block->cal_stale) + ret = true; + +unlock: + spin_unlock_irqrestore(&cal_lock, flags); +done: + return ret; } EXPORT_SYMBOL(cal_utils_is_cal_stale); diff --git a/dsp/audio_calibration.c b/dsp/audio_calibration.c index a5167be3cfaa..854d882191f6 100644 --- a/dsp/audio_calibration.c +++ b/dsp/audio_calibration.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2014, 2016-2017, 2020, The Linux Foundation. All rights reserved. */ #include #include @@ -591,6 +591,7 @@ int __init audio_cal_init(void) pr_debug("%s\n", __func__); + cal_utils_init(); memset(&audio_cal, 0, sizeof(audio_cal)); mutex_init(&audio_cal.common_lock); for (; i < MAX_CAL_TYPES; i++) { diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 51ca185b9ca2..ed1a50a17cec 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2004,7 +2004,7 @@ static void send_adm_custom_topology(void) this_adm.set_custom_topology = 0; cal_block = cal_utils_get_only_cal_block(this_adm.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index])) goto unlock; pr_debug("%s: Sending cal_index %d\n", __func__, cal_index); @@ -2144,7 +2144,7 @@ static struct cal_block_data *adm_find_cal_by_path(int cal_index, int path) cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block)) + if (cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index])) continue; if (cal_index == ADM_AUDPROC_CAL || @@ -2183,7 +2183,7 @@ static struct cal_block_data *adm_find_cal_by_app_type(int cal_index, int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block)) + if (cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index])) continue; if (cal_index == ADM_AUDPROC_CAL || @@ -2225,7 +2225,7 @@ static struct cal_block_data *adm_find_cal(int cal_index, int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block)) + if (cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index])) continue; if (cal_index == ADM_AUDPROC_CAL || @@ -3963,7 +3963,8 @@ int send_rtac_audvol_cal(void) cal_block = cal_utils_get_only_cal_block( this_adm.cal_data[ADM_RTAC_AUDVOL_CAL]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, + this_adm.cal_data[ADM_RTAC_AUDVOL_CAL])) { pr_err("%s: can't find cal block!\n", __func__); goto unlock; } diff --git a/dsp/q6afe.c b/dsp/q6afe.c index c9a5c95e4d29..8cb25197e740 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2108,7 +2108,7 @@ static void afe_send_custom_topology(void) goto unlock; this_afe.set_custom_topology = 0; cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) { pr_err("%s cal_block not found!!\n", __func__); goto unlock; } @@ -2852,7 +2852,7 @@ static struct cal_block_data *afe_find_cal_topo_id_by_port( cal_block = list_entry(ptr, struct cal_block_data, list); /* Skip cal_block if it is already marked stale */ - if (cal_utils_is_cal_stale(cal_block)) + if (cal_utils_is_cal_stale(cal_block, cal_type)) continue; pr_info("%s: port id: 0x%x, dev_acdb_id: %d\n", __func__, port_id, this_afe.dev_acdb_id[afe_port_index]); @@ -3290,8 +3290,8 @@ static int send_afe_cal_type(int cal_index, int port_id) cal_block = cal_utils_get_only_cal_block( this_afe.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { - pr_err("%s cal_block not found!!\n", __func__); + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) { + pr_err_ratelimited("%s cal_block not found!!\n", __func__); ret = -EINVAL; goto unlock; } @@ -7727,7 +7727,7 @@ static int afe_sidetone_iir(u16 tx_port_id) } mutex_lock(&this_afe.cal_data[cal_index]->lock); cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) { pr_err("%s: cal_block not found\n ", __func__); mutex_unlock(&this_afe.cal_data[cal_index]->lock); ret = -EINVAL; @@ -7854,7 +7854,7 @@ static int afe_sidetone(u16 tx_port_id, u16 rx_port_id, bool enable) mutex_lock(&this_afe.cal_data[cal_index]->lock); cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) { pr_err("%s: cal_block not found\n", __func__); mutex_unlock(&this_afe.cal_data[cal_index]->lock); ret = -EINVAL; @@ -9758,7 +9758,7 @@ static struct cal_block_data *afe_find_hw_delay_by_path( cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block)) + if (cal_utils_is_cal_stale(cal_block, cal_type)) continue; if (((struct audio_cal_info_hw_delay *)cal_block->cal_info) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 235cdbd468ec..2a078eadbb7c 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -808,7 +808,7 @@ int send_asm_custom_topology(struct audio_client *ac) set_custom_topology = 0; cal_block = cal_utils_get_only_cal_block(cal_data[ASM_CUSTOM_TOP_CAL]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, cal_data[ASM_CUSTOM_TOP_CAL])) goto unlock; if (cal_block->cal_data.size == 0) { @@ -11092,7 +11092,7 @@ static int q6asm_get_asm_topology_apptype(struct q6asm_cal_info *cal_info) mutex_lock(&cal_data[ASM_TOPOLOGY_CAL]->lock); cal_block = cal_utils_get_only_cal_block(cal_data[ASM_TOPOLOGY_CAL]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, cal_data[ASM_CUSTOM_TOP_CAL])) goto unlock; cal_info->topology_id = ((struct audio_cal_info_asm_top *) cal_block->cal_info)->topology; @@ -11152,7 +11152,7 @@ int q6asm_send_cal(struct audio_client *ac) goto unlock; } - if (cal_utils_is_cal_stale(cal_block)) { + if (cal_utils_is_cal_stale(cal_block, cal_data[ASM_AUDSTRM_CAL])) { rc = 0; /* not error case */ pr_debug("%s: cal_block is stale\n", __func__); diff --git a/include/dsp/audio_cal_utils.h b/include/dsp/audio_cal_utils.h index 0607815037f0..0507486c9f8f 100644 --- a/include/dsp/audio_cal_utils.h +++ b/include/dsp/audio_cal_utils.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2014, 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2014, 2018, 2020, The Linux Foundation. All rights reserved. */ #ifndef _AUDIO_CAL_UTILS_H #define _AUDIO_CAL_UTILS_H @@ -94,5 +94,7 @@ int32_t cal_utils_get_cal_type_version(void *cal_type_data); void cal_utils_mark_cal_used(struct cal_block_data *cal_block); -bool cal_utils_is_cal_stale(struct cal_block_data *cal_block); +bool cal_utils_is_cal_stale(struct cal_block_data *cal_block, struct cal_type_data *cal_type); + +int cal_utils_init(void); #endif -- GitLab From 3b7c3af956f691419a86afeb7c2dde53e3f28c0f Mon Sep 17 00:00:00 2001 From: Saurav Kumar Date: Thu, 22 Oct 2020 15:49:26 +0530 Subject: [PATCH 1598/1645] dsp: add change to enable preemption at cal_utils_dealloc_cal. Add change to enable preemption at cal_utils_dealloc_cal. Change-Id: I3d9304851f4d61d7afb82c0512421159ec788db1 Signed-off-by: Saurav Kumar --- asoc/msm-pcm-routing-v2.c | 4 ++-- dsp/audio_cal_utils.c | 25 +++++++------------------ dsp/q6adm.c | 11 +++++------ dsp/q6afe.c | 12 ++++++------ dsp/q6asm.c | 6 +++--- include/dsp/audio_cal_utils.h | 2 +- 6 files changed, 24 insertions(+), 36 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 7d05543dcfd4..03603a2cf672 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1177,7 +1177,7 @@ static struct cal_block_data *msm_routing_find_topology_by_path(int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block, cal_data[cal_index])) + if (cal_utils_is_cal_stale(cal_block)) continue; if (((struct audio_cal_info_adm_top *)cal_block @@ -1207,7 +1207,7 @@ static struct cal_block_data *msm_routing_find_topology(int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block, cal_data[cal_index])) + if (cal_utils_is_cal_stale(cal_block)) continue; cal_info = (struct audio_cal_info_adm_top *) diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c index cc66c2d43b9d..0f37fda418e5 100644 --- a/dsp/audio_cal_utils.c +++ b/dsp/audio_cal_utils.c @@ -10,7 +10,7 @@ #include #include -spinlock_t cal_lock; +struct mutex cal_lock; static int unmap_memory(struct cal_type_data *cal_type, struct cal_block_data *cal_block); @@ -901,7 +901,6 @@ int cal_utils_dealloc_cal(size_t data_size, void *data, int ret = 0; struct cal_block_data *cal_block; struct audio_cal_type_dealloc *dealloc_data = data; - unsigned long flags = 0; pr_debug("%s\n", __func__); @@ -949,9 +948,9 @@ int cal_utils_dealloc_cal(size_t data_size, void *data, if (ret < 0) goto err; - spin_lock_irqsave(&cal_lock, flags); + mutex_lock(&cal_lock); delete_cal_block(cal_block); - spin_unlock_irqrestore(&cal_lock, flags); + mutex_unlock(&cal_lock); err: mutex_unlock(&cal_type->lock); done: @@ -1068,7 +1067,7 @@ EXPORT_SYMBOL(cal_utils_mark_cal_used); int __init cal_utils_init(void) { - spin_lock_init(&cal_lock); + mutex_init(&cal_lock); return 0; } /** @@ -1076,22 +1075,13 @@ int __init cal_utils_init(void) * * @cal_block: pointer to cal block * - * @cal_type: pointer to the cal type - * * Returns true if cal block is stale, false otherwise */ -bool cal_utils_is_cal_stale(struct cal_block_data *cal_block, struct cal_type_data *cal_type) +bool cal_utils_is_cal_stale(struct cal_block_data *cal_block) { bool ret = false; - unsigned long flags = 0; - - if (!cal_type) { - pr_err("%s: cal_type is Null", __func__); - goto done; - } - spin_lock_irqsave(&cal_lock, flags); - cal_block = cal_utils_get_only_cal_block(cal_type); + mutex_lock(&cal_lock); if (!cal_block) { pr_err("%s: cal_block is Null", __func__); goto unlock; @@ -1101,8 +1091,7 @@ bool cal_utils_is_cal_stale(struct cal_block_data *cal_block, struct cal_type_da ret = true; unlock: - spin_unlock_irqrestore(&cal_lock, flags); -done: + mutex_unlock(&cal_lock); return ret; } EXPORT_SYMBOL(cal_utils_is_cal_stale); diff --git a/dsp/q6adm.c b/dsp/q6adm.c index ed1a50a17cec..51ca185b9ca2 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -2004,7 +2004,7 @@ static void send_adm_custom_topology(void) this_adm.set_custom_topology = 0; cal_block = cal_utils_get_only_cal_block(this_adm.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index])) + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) goto unlock; pr_debug("%s: Sending cal_index %d\n", __func__, cal_index); @@ -2144,7 +2144,7 @@ static struct cal_block_data *adm_find_cal_by_path(int cal_index, int path) cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index])) + if (cal_utils_is_cal_stale(cal_block)) continue; if (cal_index == ADM_AUDPROC_CAL || @@ -2183,7 +2183,7 @@ static struct cal_block_data *adm_find_cal_by_app_type(int cal_index, int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index])) + if (cal_utils_is_cal_stale(cal_block)) continue; if (cal_index == ADM_AUDPROC_CAL || @@ -2225,7 +2225,7 @@ static struct cal_block_data *adm_find_cal(int cal_index, int path, cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index])) + if (cal_utils_is_cal_stale(cal_block)) continue; if (cal_index == ADM_AUDPROC_CAL || @@ -3963,8 +3963,7 @@ int send_rtac_audvol_cal(void) cal_block = cal_utils_get_only_cal_block( this_adm.cal_data[ADM_RTAC_AUDVOL_CAL]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, - this_adm.cal_data[ADM_RTAC_AUDVOL_CAL])) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { pr_err("%s: can't find cal block!\n", __func__); goto unlock; } diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 8cb25197e740..283d425b8c81 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2108,7 +2108,7 @@ static void afe_send_custom_topology(void) goto unlock; this_afe.set_custom_topology = 0; cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { pr_err("%s cal_block not found!!\n", __func__); goto unlock; } @@ -2852,7 +2852,7 @@ static struct cal_block_data *afe_find_cal_topo_id_by_port( cal_block = list_entry(ptr, struct cal_block_data, list); /* Skip cal_block if it is already marked stale */ - if (cal_utils_is_cal_stale(cal_block, cal_type)) + if (cal_utils_is_cal_stale(cal_block)) continue; pr_info("%s: port id: 0x%x, dev_acdb_id: %d\n", __func__, port_id, this_afe.dev_acdb_id[afe_port_index]); @@ -3290,7 +3290,7 @@ static int send_afe_cal_type(int cal_index, int port_id) cal_block = cal_utils_get_only_cal_block( this_afe.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { pr_err_ratelimited("%s cal_block not found!!\n", __func__); ret = -EINVAL; goto unlock; @@ -7727,7 +7727,7 @@ static int afe_sidetone_iir(u16 tx_port_id) } mutex_lock(&this_afe.cal_data[cal_index]->lock); cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { pr_err("%s: cal_block not found\n ", __func__); mutex_unlock(&this_afe.cal_data[cal_index]->lock); ret = -EINVAL; @@ -7854,7 +7854,7 @@ static int afe_sidetone(u16 tx_port_id, u16 rx_port_id, bool enable) mutex_lock(&this_afe.cal_data[cal_index]->lock); cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) { + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) { pr_err("%s: cal_block not found\n", __func__); mutex_unlock(&this_afe.cal_data[cal_index]->lock); ret = -EINVAL; @@ -9758,7 +9758,7 @@ static struct cal_block_data *afe_find_hw_delay_by_path( cal_block = list_entry(ptr, struct cal_block_data, list); - if (cal_utils_is_cal_stale(cal_block, cal_type)) + if (cal_utils_is_cal_stale(cal_block)) continue; if (((struct audio_cal_info_hw_delay *)cal_block->cal_info) diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 2a078eadbb7c..235cdbd468ec 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -808,7 +808,7 @@ int send_asm_custom_topology(struct audio_client *ac) set_custom_topology = 0; cal_block = cal_utils_get_only_cal_block(cal_data[ASM_CUSTOM_TOP_CAL]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, cal_data[ASM_CUSTOM_TOP_CAL])) + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) goto unlock; if (cal_block->cal_data.size == 0) { @@ -11092,7 +11092,7 @@ static int q6asm_get_asm_topology_apptype(struct q6asm_cal_info *cal_info) mutex_lock(&cal_data[ASM_TOPOLOGY_CAL]->lock); cal_block = cal_utils_get_only_cal_block(cal_data[ASM_TOPOLOGY_CAL]); - if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, cal_data[ASM_CUSTOM_TOP_CAL])) + if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) goto unlock; cal_info->topology_id = ((struct audio_cal_info_asm_top *) cal_block->cal_info)->topology; @@ -11152,7 +11152,7 @@ int q6asm_send_cal(struct audio_client *ac) goto unlock; } - if (cal_utils_is_cal_stale(cal_block, cal_data[ASM_AUDSTRM_CAL])) { + if (cal_utils_is_cal_stale(cal_block)) { rc = 0; /* not error case */ pr_debug("%s: cal_block is stale\n", __func__); diff --git a/include/dsp/audio_cal_utils.h b/include/dsp/audio_cal_utils.h index 0507486c9f8f..99f619f23c37 100644 --- a/include/dsp/audio_cal_utils.h +++ b/include/dsp/audio_cal_utils.h @@ -94,7 +94,7 @@ int32_t cal_utils_get_cal_type_version(void *cal_type_data); void cal_utils_mark_cal_used(struct cal_block_data *cal_block); -bool cal_utils_is_cal_stale(struct cal_block_data *cal_block, struct cal_type_data *cal_type); +bool cal_utils_is_cal_stale(struct cal_block_data *cal_block); int cal_utils_init(void); #endif -- GitLab From 5bdb6c330ce30c0e34f62c517163fc4790cff399 Mon Sep 17 00:00:00 2001 From: Saurav Kumar Date: Tue, 18 Aug 2020 18:33:35 +0530 Subject: [PATCH 1599/1645] dsp: add change to fix use-after-free issue Add change to properly handle the pointers by setting them to NULL after free and adding some null checks before dereferencing. Change-Id: I3e52b9a6885a8d8a91c09f75fe92ba69e3eb555f Signed-off-by: Saurav Kumar --- dsp/msm_audio_ion.c | 11 +++++++++-- dsp/q6asm.c | 6 ++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c index 566f8bf1b80b..2bf02fcad7bb 100644 --- a/dsp/msm_audio_ion.c +++ b/dsp/msm_audio_ion.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. */ #include @@ -67,7 +67,7 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf, dma_addr_t *addr, size_t *len) { - struct msm_audio_alloc_data *alloc_data; + struct msm_audio_alloc_data *alloc_data = NULL; struct device *cb_dev; unsigned long ionflag = 0; int rc = 0; @@ -133,6 +133,7 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf, alloc_data->attach); free_alloc_data: kfree(alloc_data); + alloc_data = NULL; return rc; } @@ -170,6 +171,7 @@ static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf) list_del(&(alloc_data->list)); kfree(alloc_data); + alloc_data = NULL; break; } } @@ -312,6 +314,11 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr, { int rc = 0; + if (!dma_buf || !paddr || !vaddr || !plen) { + pr_err("%s: Invalid params\n", __func__); + return -EINVAL; + } + rc = msm_audio_ion_get_phys(dma_buf, paddr, plen); if (rc) { pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 235cdbd468ec..2939599d907e 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -8486,6 +8486,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, if (mmap_region_cmd == NULL) { rc = -EINVAL; kfree(buffer_node); + buffer_node = NULL; return rc; } mmap_regions = (struct avs_cmd_shared_mem_map_regions *) @@ -8522,6 +8523,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, mmap_regions->hdr.opcode, rc); rc = -EINVAL; kfree(buffer_node); + buffer_node = NULL; goto fail_cmd; } @@ -8533,6 +8535,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, pr_err("%s: timeout. waited for memory_map\n", __func__); rc = -ETIMEDOUT; kfree(buffer_node); + buffer_node = NULL; goto fail_cmd; } if (atomic_read(&ac->mem_state) > 0) { @@ -8542,6 +8545,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, rc = adsp_err_get_lnx_err_code( atomic_read(&ac->mem_state)); kfree(buffer_node); + buffer_node = NULL; goto fail_cmd; } mutex_lock(&ac->cmd_lock); @@ -8561,6 +8565,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir, rc = 0; fail_cmd: kfree(mmap_region_cmd); + mmap_region_cmd = NULL; return rc; } EXPORT_SYMBOL(q6asm_memory_map_regions); @@ -8656,6 +8661,7 @@ static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir) if (buf_node->buf_phys_addr == buf_add) { list_del(&buf_node->list); kfree(buf_node); + buf_node = NULL; break; } } -- GitLab From 154ac2f8432e9270da63cf609fb16c40dd6378d7 Mon Sep 17 00:00:00 2001 From: Saurav Kumar Date: Fri, 30 Oct 2020 16:03:27 +0530 Subject: [PATCH 1600/1645] dsp: add change to fix use-after-free issue Add change to properly handle the pointers by setting them to NULL after free and adding some null checks before dereferencing. Change-Id: Ic2f3ef5631d0f4e4191bf772eb0b3f0b825044a6 --- dsp/msm_audio_ion_vm.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dsp/msm_audio_ion_vm.c b/dsp/msm_audio_ion_vm.c index 37b17b685687..ed60c652fb64 100644 --- a/dsp/msm_audio_ion_vm.c +++ b/dsp/msm_audio_ion_vm.c @@ -124,7 +124,7 @@ static int msm_audio_ion_dma_buf_map(struct dma_buf *dma_buf, dma_addr_t *addr, size_t *len) { - struct msm_audio_alloc_data *alloc_data; + struct msm_audio_alloc_data *alloc_data = NULL; struct device *cb_dev; unsigned long ionflag = 0; int rc = 0; @@ -189,6 +189,7 @@ static int msm_audio_ion_dma_buf_map(struct dma_buf *dma_buf, dma_buf_detach(dma_buf, alloc_data->attach); free_alloc_data: kfree(alloc_data); + alloc_data = NULL; return rc; } @@ -262,6 +263,7 @@ static int msm_audio_dma_buf_unmap(void *handle) list_del(&(alloc_data->list)); kfree(alloc_data); + alloc_data = NULL; break; } } else { @@ -278,6 +280,7 @@ static int msm_audio_dma_buf_unmap(void *handle) list_del(&(alloc_data->list)); kfree(alloc_data); + alloc_data = NULL; break; } } @@ -541,6 +544,11 @@ static int msm_audio_ion_map_buf(void *handle, dma_addr_t *paddr, { int rc = 0; + if (!handle || !paddr || !vaddr || !plen) { + pr_err("%s: Invalid params\n", __func__); + return -EINVAL; + } + rc = msm_audio_ion_get_phys((struct dma_buf*) handle, paddr, plen); if (rc) { pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n", -- GitLab From adeb331165b22dbdd8a7a20e0caf8fda9f40463b Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Fri, 27 Nov 2020 15:43:55 +0530 Subject: [PATCH 1601/1645] ASoC: Add support to send voice UI port id to afe As per the current design in afe, if the afe_get_cal_topology for AFE_TOPOLOGY_CAL or send_afe_cal_type for AFE_COMMON_TX_CAL fails, then the voice UI calblock is fetched/sent. This is resulting in sending voice UI calblock on a non voice UI port during concurrent usecase scenario. Fix is to check if the calblock for get/set is for a voice UI port or not. Added support to send this port id info from routing driver to afe when usecase is enabled via mixer_control. Change-Id: I356aae61e1b9d11324e7b9f9a57953767a64b71e Signed-off-by: Soumya Managoli --- asoc/msm-pcm-routing-v2.c | 6 ++++++ dsp/q6afe.c | 37 +++++++++++++++++++++++++++++++++++-- include/dsp/q6afe-v2.h | 1 + 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 03603a2cf672..37635a84764f 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -3033,6 +3033,7 @@ static int msm_routing_lsm_port_put(struct snd_kcontrol *kcontrol, struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; int mux = ucontrol->value.enumerated.item[0]; int lsm_port = AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX; + int lsm_port_idx = 0; u8 fe_idx = 0; if (mux >= e->items) { @@ -3042,6 +3043,7 @@ static int msm_routing_lsm_port_put(struct snd_kcontrol *kcontrol, pr_debug("%s: LSM enable %ld\n", __func__, ucontrol->value.integer.value[0]); + lsm_port_idx = ucontrol->value.integer.value[0]; switch (ucontrol->value.integer.value[0]) { case 1: lsm_port = AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX; @@ -3098,6 +3100,10 @@ static int msm_routing_lsm_port_put(struct snd_kcontrol *kcontrol, set_lsm_port(lsm_port); msm_routing_get_lsm_fe_idx(kcontrol, &fe_idx); lsm_port_index[fe_idx] = ucontrol->value.integer.value[0]; + /* Set the default AFE LSM Port to 0xffff */ + if(lsm_port_idx <= 0 || lsm_port_idx >= ARRAY_SIZE(lsm_port_text)) + lsm_port = 0xffff; + afe_set_lsm_afe_port_id(fe_idx, lsm_port); return 0; } diff --git a/dsp/q6afe.c b/dsp/q6afe.c index bfcbfced6adc..88124df9deda 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -27,6 +27,7 @@ #define AFE_CLK_TOKEN 1024 #define SP_V4_NUM_MAX_SPKRS SP_V2_NUM_MAX_SPKRS +#define MAX_LSM_SESSIONS 8 struct afe_avcs_payload_port_mapping { u16 port_id; @@ -249,6 +250,7 @@ struct afe_ctl { uint32_t num_spkrs; uint32_t cps_ch_mask; struct afe_cps_hw_intf_cfg *cps_config; + int lsm_afe_ports[MAX_LSM_SESSIONS]; }; struct afe_clkinfo_per_port { @@ -303,6 +305,8 @@ bool afe_close_done[2] = {true, true}; #define SIZEOF_CFG_CMD(y) \ (sizeof(struct apr_hdr) + sizeof(u16) + (sizeof(struct y))) +static bool q6afe_is_afe_lsm_port(int port_id); + static void q6afe_unload_avcs_modules(u16 port_id, int index) { int ret = 0; @@ -3011,7 +3015,7 @@ static int afe_send_port_topology_id(u16 port_id) } ret = afe_get_cal_topology_id(port_id, &topology_id, AFE_TOPOLOGY_CAL); - if (ret < 0) { + if (ret < 0 && q6afe_is_afe_lsm_port(port_id)) { pr_debug("%s: Check for LSM topology\n", __func__); ret = afe_get_cal_topology_id(port_id, &topology_id, AFE_LSM_TOPOLOGY_CAL); @@ -3384,7 +3388,7 @@ void afe_send_cal(u16 port_id) if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX) { afe_send_cal_spkr_prot_tx(port_id); ret = send_afe_cal_type(AFE_COMMON_TX_CAL, port_id); - if (ret < 0) + if (ret < 0 && q6afe_is_afe_lsm_port(port_id)) send_afe_cal_type(AFE_LSM_TX_CAL, port_id); } else if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) { send_afe_cal_type(AFE_COMMON_RX_CAL, port_id); @@ -10675,6 +10679,8 @@ int __init afe_init(void) init_waitqueue_head(&this_afe.wait_wakeup); init_waitqueue_head(&this_afe.lpass_core_hw_wait); init_waitqueue_head(&this_afe.clk_wait); + for (i = 0; i < MAX_LSM_SESSIONS; i++) + this_afe.lsm_afe_ports[i] = 0xffff; ret = afe_init_cal_data(); if (ret) pr_err("%s: could not init cal data! %d\n", __func__, ret); @@ -10913,3 +10919,30 @@ void afe_set_cps_config(int src_port, this_afe.cps_config = cps_config; } EXPORT_SYMBOL(afe_set_cps_config); + +static bool q6afe_is_afe_lsm_port(int port_id) +{ + int i = 0; + + for (i = 0; i < MAX_LSM_SESSIONS; i++) { + if (port_id == this_afe.lsm_afe_ports[i]) + return true; + } + return false; +} + +/** + * afe_set_lsm_afe_port_id - + * Update LSM AFE port + * idx: LSM port index + * lsm_port: LSM port id +*/ +void afe_set_lsm_afe_port_id(int idx, int lsm_port) +{ + if (idx < 0 || idx >= MAX_LSM_SESSIONS) { + pr_err("%s: %d Invalid lsm port index\n", __func__, idx); + return; + } + this_afe.lsm_afe_ports[idx] = lsm_port; +} +EXPORT_SYMBOL(afe_set_lsm_afe_port_id); diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index 310de65c739d..bd2cba69354f 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -499,6 +499,7 @@ int afe_get_doa_tracking_mon(u16 port_id, int afe_set_pll_clk_drift(u16 port_id, int32_t set_clk_drift, uint32_t clk_reset); int afe_set_clk_id(u16 port_id, uint32_t clk_id); +void afe_set_lsm_afe_port_id(int idx, int lsm_port); enum { AFE_LPASS_CORE_HW_BLOCK_ID_NONE, -- GitLab From 8e3d6a8632f6eac48eacebb6939a3063ba0c2946 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 24 Sep 2020 11:15:42 +0530 Subject: [PATCH 1602/1645] ASoC: wsa883x: Handle PA_ERR interrupt on WSA speaker PA_ERR can happen during speaker path setup. Log the error status in the interrupt handler and clear the error status for next audio playback to resume properly on the speaker. Change-Id: I5800d9505a3036127097745aaa880b73b3e87f30 Signed-off-by: Sudheer Papothi --- asoc/codecs/wsa883x/wsa883x.c | 44 ++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index f2f16dafb3f0..31ba5ba75d10 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -481,8 +481,33 @@ static irqreturn_t wsa883x_uvlo_handle_irq(int irq, void *data) static irqreturn_t wsa883x_pa_on_err_handle_irq(int irq, void *data) { - pr_err_ratelimited("%s: interrupt for irq =%d triggered\n", - __func__, irq); + u8 pa_fsm_sta = 0, pa_fsm_err = 0; + struct wsa883x_priv *wsa883x = data; + struct snd_soc_component *component = NULL; + + if (!wsa883x) + return IRQ_NONE; + + component = wsa883x->component; + if (!component) + return IRQ_NONE; + + pa_fsm_sta = (snd_soc_component_read32(component, WSA883X_PA_FSM_STA) + & 0x70); + + if (pa_fsm_sta) + pa_fsm_err = snd_soc_component_read32(component, + WSA883X_PA_FSM_ERR_COND); + pr_err_ratelimited("%s: irq: %d, pa_fsm_sta: %d, pa_fsm_err: %d\n", + __func__, irq, pa_fsm_sta, pa_fsm_err); + + snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, + 0x10, 0x00); + snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, + 0x10, 0x10); + snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, + 0x10, 0x00); + return IRQ_HANDLED; } @@ -1017,6 +1042,7 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, 0x01, 0x01); /* Added delay as per HW sequence */ usleep_range(250, 300); + wcd_enable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR); /* Force remove group */ swr_remove_from_group(wsa883x->swr_slave, wsa883x->swr_slave->dev_num); @@ -1042,9 +1068,15 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, 0x0E, 0x00); snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, 0x01, 0x00); - snd_soc_component_update_bits(wsa883x->component, - WSA883X_PDM_WD_CTL, - 0x01, 0x00); + snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, + 0x10, 0x00); + snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, + 0x10, 0x10); + snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, + 0x10, 0x00); + snd_soc_component_update_bits(wsa883x->component, WSA883X_PDM_WD_CTL, + 0x01, 0x00); + wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR); clear_bit(SPKR_STATUS, &wsa883x->status_mask); clear_bit(SPKR_ADIE_LB, &wsa883x->status_mask); break; @@ -1594,7 +1626,7 @@ static int wsa883x_swr_probe(struct swr_device *pdev) "WSA UVLO", wsa883x_uvlo_handle_irq, NULL); wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR, - "WSA PA ERR", wsa883x_pa_on_err_handle_irq, NULL); + "WSA PA ERR", wsa883x_pa_on_err_handle_irq, wsa883x); wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR); -- GitLab From 8b699bc1775f1df3eeed557c6aaf5fa2d647d6f6 Mon Sep 17 00:00:00 2001 From: Shashi Kant Maurya Date: Thu, 19 Nov 2020 17:33:42 +0530 Subject: [PATCH 1603/1645] asoc: wsa881x: Fix crash while capturing swr_slv codec dump Swr-slv address is overwritten during wsa881x_swr_probe, hence soundwire getting incorrect slave address. While accessing swr master from swr slave due to incorrect address device crashed To avoid the issue align the debugfs similar to wsa883x codec. Change-Id: Ic8aaa0728a43936cd4c6e1ed590e01ba8f0fbf5b Signed-off-by: Shashi Kant Maurya --- asoc/codecs/wsa881x.c | 227 ++++++++++++++++++++++++++---------------- 1 file changed, 140 insertions(+), 87 deletions(-) diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index b23bc01fd8ed..52f29d886ab5 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -109,6 +109,11 @@ struct wsa881x_priv { int (*register_notifier)(void *handle, struct notifier_block *nblock, bool enable); + struct dentry *debugfs_dent; + struct dentry *debugfs_peek; + struct dentry *debugfs_poke; + struct dentry *debugfs_reg_dump; + unsigned int read_data; }; /* from bolero to WSA events */ @@ -146,14 +151,6 @@ static int wsa881x_ocp_poll_timer_sec = WSA881X_OCP_CTL_POLL_TIMER_SEC; module_param(wsa881x_ocp_poll_timer_sec, int, 0664); MODULE_PARM_DESC(wsa881x_ocp_poll_timer_sec, "timer for ocp ctl polling"); -static struct wsa881x_priv *dbgwsa881x; -static struct dentry *debugfs_wsa881x_dent; -static struct dentry *debugfs_peek; -static struct dentry *debugfs_poke; -static struct dentry *debugfs_reg_dump; -static unsigned int read_data; -static unsigned int devnum; - static int32_t wsa881x_resource_acquire(struct snd_soc_component *component, bool enable); @@ -401,30 +398,28 @@ static bool is_swr_slv_reg_readable(int reg) return ret; } -static ssize_t wsa881x_swrslave_reg_show(char __user *ubuf, size_t count, - loff_t *ppos) +static ssize_t wsa881x_swrslave_reg_show(struct swr_device *pdev, char __user *ubuf, + size_t count, loff_t *ppos) { int i, reg_val, len; ssize_t total = 0; char tmp_buf[SWR_SLV_MAX_BUF_LEN]; - if (!ubuf || !ppos || (devnum == 0)) + if (!ubuf || !ppos) return 0; for (i = (((int) *ppos / BYTES_PER_LINE) + SWR_SLV_START_REG_ADDR); - i <= SWR_SLV_MAX_REG_ADDR; i++) { + i <= SWR_SLV_MAX_REG_ADDR; i++) { if (!is_swr_slv_reg_readable(i)) continue; - swr_read(dbgwsa881x->swr_slave, devnum, - i, ®_val, 1); - len = snprintf(tmp_buf, 25, "0x%.3x: 0x%.2x\n", i, - (reg_val & 0xFF)); + swr_read(pdev, pdev->dev_num, i, ®_val, 1); + len = snprintf(tmp_buf, sizeof(tmp_buf), "0x%.3x: 0x%.2x\n", i, + (reg_val & 0xFF)); if (len < 0) { pr_err("%s: fail to fill the buffer\n", __func__); total = -EFAULT; goto copy_err; } - if ((total + len) >= count - 1) break; if (copy_to_user((ubuf + total), tmp_buf, len)) { @@ -432,53 +427,84 @@ static ssize_t wsa881x_swrslave_reg_show(char __user *ubuf, size_t count, total = -EFAULT; goto copy_err; } - *ppos += len; total += len; + *ppos += len; } copy_err: + *ppos = SWR_SLV_MAX_REG_ADDR * BYTES_PER_LINE; return total; } +static ssize_t codec_debug_dump(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct swr_device *pdev; + + if (!count || !file || !ppos || !ubuf) + return -EINVAL; + + pdev = file->private_data; + if (!pdev) + return -EINVAL; + + if (*ppos < 0) + return -EINVAL; + + return wsa881x_swrslave_reg_show(pdev, ubuf, count, ppos); +} + static ssize_t codec_debug_read(struct file *file, char __user *ubuf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { char lbuf[SWR_SLV_RD_BUF_LEN]; - char *access_str; - ssize_t ret_cnt; + struct swr_device *pdev = NULL; + struct wsa881x_priv *wsa881x = NULL; if (!count || !file || !ppos || !ubuf) return -EINVAL; - access_str = file->private_data; + pdev = file->private_data; + if (!pdev) + return -EINVAL; + + wsa881x = swr_get_dev_data(pdev); + if (!wsa881x) + return -EINVAL; + if (*ppos < 0) return -EINVAL; - if (!strcmp(access_str, "swrslave_peek")) { - snprintf(lbuf, sizeof(lbuf), "0x%x\n", (read_data & 0xFF)); - ret_cnt = simple_read_from_buffer(ubuf, count, ppos, lbuf, - strnlen(lbuf, 7)); - } else if (!strcmp(access_str, "swrslave_reg_dump")) { - ret_cnt = wsa881x_swrslave_reg_show(ubuf, count, ppos); - } else { - pr_err("%s: %s not permitted to read\n", __func__, access_str); - ret_cnt = -EPERM; - } - return ret_cnt; + snprintf(lbuf, sizeof(lbuf), "0x%x\n", + (wsa881x->read_data & 0xFF)); + + return simple_read_from_buffer(ubuf, count, ppos, lbuf, + strnlen(lbuf, 7)); } -static ssize_t codec_debug_write(struct file *filp, - const char __user *ubuf, size_t cnt, loff_t *ppos) +static ssize_t codec_debug_peek_write(struct file *file, + const char __user *ubuf, size_t cnt, loff_t *ppos) { char lbuf[SWR_SLV_WR_BUF_LEN]; - int rc; + int rc = 0; u32 param[5]; - char *access_str; + struct swr_device *pdev = NULL; + struct wsa881x_priv *wsa881x = NULL; + + if (!cnt || !file || !ppos || !ubuf) + return -EINVAL; + + pdev = file->private_data; + if (!pdev) + return -EINVAL; - if (!filp || !ppos || !ubuf) + wsa881x = swr_get_dev_data(pdev); + if (!wsa881x) + return -EINVAL; + + if (*ppos < 0) return -EINVAL; - access_str = filp->private_data; if (cnt > sizeof(lbuf) - 1) return -EINVAL; @@ -487,32 +513,46 @@ static ssize_t codec_debug_write(struct file *filp, return -EFAULT; lbuf[cnt] = '\0'; - if (!strcmp(access_str, "swrslave_poke")) { - /* write */ - rc = get_parameters(lbuf, param, 3); - if ((param[0] <= SWR_SLV_MAX_REG_ADDR) && (param[1] <= 0xFF) && - (rc == 0)) - swr_write(dbgwsa881x->swr_slave, param[2], - param[0], ¶m[1]); - else - rc = -EINVAL; - } else if (!strcmp(access_str, "swrslave_peek")) { - /* read */ - rc = get_parameters(lbuf, param, 2); - if ((param[0] <= SWR_SLV_MAX_REG_ADDR) && (rc == 0)) - swr_read(dbgwsa881x->swr_slave, param[1], - param[0], &read_data, 1); - else - rc = -EINVAL; - } else if (!strcmp(access_str, "swrslave_reg_dump")) { - /* reg dump */ - rc = get_parameters(lbuf, param, 1); - if ((rc == 0) && (param[0] > 0) && - (param[0] <= SWR_SLV_MAX_DEVICES)) - devnum = param[0]; - else - rc = -EINVAL; - } + rc = get_parameters(lbuf, param, 1); + if (!((param[0] <= SWR_SLV_MAX_REG_ADDR) && (rc == 0))) + return -EINVAL; + swr_read(pdev, pdev->dev_num, param[0], &wsa881x->read_data, 1); + if (rc == 0) + rc = cnt; + else + pr_err("%s: rc = %d\n", __func__, rc); + + return rc; +} + +static ssize_t codec_debug_write(struct file *file, + const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char lbuf[SWR_SLV_WR_BUF_LEN]; + int rc = 0; + u32 param[5]; + struct swr_device *pdev; + + if (!file || !ppos || !ubuf) + return -EINVAL; + + pdev = file->private_data; + if (!pdev) + return -EINVAL; + + if (cnt > sizeof(lbuf) - 1) + return -EINVAL; + + rc = copy_from_user(lbuf, ubuf, cnt); + if (rc) + return -EFAULT; + + lbuf[cnt] = '\0'; + rc = get_parameters(lbuf, param, 2); + if (!((param[0] <= SWR_SLV_MAX_REG_ADDR) && + (param[1] <= 0xFF) && (rc == 0))) + return -EINVAL; + swr_write(pdev, pdev->dev_num, param[0], ¶m[1]); if (rc == 0) rc = cnt; else @@ -521,12 +561,21 @@ static ssize_t codec_debug_write(struct file *filp, return rc; } -static const struct file_operations codec_debug_ops = { +static const struct file_operations codec_debug_write_ops = { .open = codec_debug_open, .write = codec_debug_write, +}; + +static const struct file_operations codec_debug_read_ops = { + .open = codec_debug_open, .read = codec_debug_read, + .write = codec_debug_peek_write, }; +static const struct file_operations codec_debug_dump_ops = { + .open = codec_debug_open, + .read = codec_debug_dump, +}; static void wsa881x_regcache_sync(struct wsa881x_priv *wsa881x) { mutex_lock(&wsa881x->res_lock); @@ -1454,27 +1503,31 @@ static int wsa881x_swr_probe(struct swr_device *pdev) wsa881x_gpio_ctrl(wsa881x, true); wsa881x->state = WSA881X_DEV_UP; - if (!debugfs_wsa881x_dent) { - dbgwsa881x = wsa881x; - debugfs_wsa881x_dent = debugfs_create_dir( - "wsa881x_swr_slave", 0); - if (!IS_ERR(debugfs_wsa881x_dent)) { - debugfs_peek = debugfs_create_file("swrslave_peek", - S_IFREG | 0444, debugfs_wsa881x_dent, - (void *) "swrslave_peek", - &codec_debug_ops); - - debugfs_poke = debugfs_create_file("swrslave_poke", - S_IFREG | 0444, debugfs_wsa881x_dent, - (void *) "swrslave_poke", - &codec_debug_ops); - - debugfs_reg_dump = debugfs_create_file( + if (!wsa881x->debugfs_dent) { + wsa881x->debugfs_dent = debugfs_create_dir( + dev_name(&pdev->dev), 0); + if (!IS_ERR(wsa881x->debugfs_dent)) { + wsa881x->debugfs_peek = + debugfs_create_file("swrslave_peek", + S_IFREG | 0444, + wsa881x->debugfs_dent, + (void *) pdev, + &codec_debug_read_ops); + + wsa881x->debugfs_poke = + debugfs_create_file("swrslave_poke", + S_IFREG | 0444, + wsa881x->debugfs_dent, + (void *) pdev, + &codec_debug_write_ops); + + wsa881x->debugfs_reg_dump = + debugfs_create_file( "swrslave_reg_dump", S_IFREG | 0444, - debugfs_wsa881x_dent, - (void *) "swrslave_reg_dump", - &codec_debug_ops); + wsa881x->debugfs_dent, + (void *) pdev, + &codec_debug_dump_ops); } } @@ -1566,8 +1619,8 @@ static int wsa881x_swr_remove(struct swr_device *pdev) if (wsa881x->register_notifier) wsa881x->register_notifier(wsa881x->handle, &wsa881x->bolero_nblock, false); - debugfs_remove_recursive(debugfs_wsa881x_dent); - debugfs_wsa881x_dent = NULL; + debugfs_remove_recursive(wsa881x->debugfs_dent); + wsa881x->debugfs_dent = NULL; mutex_destroy(&wsa881x->res_lock); mutex_destroy(&wsa881x->temp_lock); snd_soc_unregister_component(&pdev->dev); -- GitLab From d8696c49ee477c5283c39871d34e472e53159a1a Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Thu, 24 Sep 2020 11:15:42 +0530 Subject: [PATCH 1604/1645] ASoC: wsa883x: Handle PA_ERR interrupt on WSA speaker PA_ERR can happen during speaker path setup. Log the error status in the interrupt handler and clear the error status for next audio playback to resume properly on the speaker. Change-Id: I5800d9505a3036127097745aaa880b73b3e87f30 Signed-off-by: Sudheer Papothi --- asoc/codecs/wsa883x/wsa883x.c | 44 ++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index f2f16dafb3f0..31ba5ba75d10 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -481,8 +481,33 @@ static irqreturn_t wsa883x_uvlo_handle_irq(int irq, void *data) static irqreturn_t wsa883x_pa_on_err_handle_irq(int irq, void *data) { - pr_err_ratelimited("%s: interrupt for irq =%d triggered\n", - __func__, irq); + u8 pa_fsm_sta = 0, pa_fsm_err = 0; + struct wsa883x_priv *wsa883x = data; + struct snd_soc_component *component = NULL; + + if (!wsa883x) + return IRQ_NONE; + + component = wsa883x->component; + if (!component) + return IRQ_NONE; + + pa_fsm_sta = (snd_soc_component_read32(component, WSA883X_PA_FSM_STA) + & 0x70); + + if (pa_fsm_sta) + pa_fsm_err = snd_soc_component_read32(component, + WSA883X_PA_FSM_ERR_COND); + pr_err_ratelimited("%s: irq: %d, pa_fsm_sta: %d, pa_fsm_err: %d\n", + __func__, irq, pa_fsm_sta, pa_fsm_err); + + snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, + 0x10, 0x00); + snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, + 0x10, 0x10); + snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, + 0x10, 0x00); + return IRQ_HANDLED; } @@ -1017,6 +1042,7 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, 0x01, 0x01); /* Added delay as per HW sequence */ usleep_range(250, 300); + wcd_enable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR); /* Force remove group */ swr_remove_from_group(wsa883x->swr_slave, wsa883x->swr_slave->dev_num); @@ -1042,9 +1068,15 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, 0x0E, 0x00); snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, 0x01, 0x00); - snd_soc_component_update_bits(wsa883x->component, - WSA883X_PDM_WD_CTL, - 0x01, 0x00); + snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, + 0x10, 0x00); + snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, + 0x10, 0x10); + snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL, + 0x10, 0x00); + snd_soc_component_update_bits(wsa883x->component, WSA883X_PDM_WD_CTL, + 0x01, 0x00); + wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR); clear_bit(SPKR_STATUS, &wsa883x->status_mask); clear_bit(SPKR_ADIE_LB, &wsa883x->status_mask); break; @@ -1594,7 +1626,7 @@ static int wsa883x_swr_probe(struct swr_device *pdev) "WSA UVLO", wsa883x_uvlo_handle_irq, NULL); wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR, - "WSA PA ERR", wsa883x_pa_on_err_handle_irq, NULL); + "WSA PA ERR", wsa883x_pa_on_err_handle_irq, wsa883x); wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR); -- GitLab From b5e20f6e299c5e1d18c508f534265568e988ab58 Mon Sep 17 00:00:00 2001 From: Shashi Kant Maurya Date: Thu, 19 Nov 2020 17:33:42 +0530 Subject: [PATCH 1605/1645] asoc: wsa881x: Fix crash while capturing swr_slv codec dump Swr-slv address is overwritten during wsa881x_swr_probe, hence soundwire getting incorrect slave address. While accessing swr master from swr slave due to incorrect address device crashed To avoid the issue align the debugfs similar to wsa883x codec. Change-Id: Ic8aaa0728a43936cd4c6e1ed590e01ba8f0fbf5b Signed-off-by: Shashi Kant Maurya --- asoc/codecs/wsa881x.c | 227 ++++++++++++++++++++++++++---------------- 1 file changed, 140 insertions(+), 87 deletions(-) diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index b23bc01fd8ed..52f29d886ab5 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -109,6 +109,11 @@ struct wsa881x_priv { int (*register_notifier)(void *handle, struct notifier_block *nblock, bool enable); + struct dentry *debugfs_dent; + struct dentry *debugfs_peek; + struct dentry *debugfs_poke; + struct dentry *debugfs_reg_dump; + unsigned int read_data; }; /* from bolero to WSA events */ @@ -146,14 +151,6 @@ static int wsa881x_ocp_poll_timer_sec = WSA881X_OCP_CTL_POLL_TIMER_SEC; module_param(wsa881x_ocp_poll_timer_sec, int, 0664); MODULE_PARM_DESC(wsa881x_ocp_poll_timer_sec, "timer for ocp ctl polling"); -static struct wsa881x_priv *dbgwsa881x; -static struct dentry *debugfs_wsa881x_dent; -static struct dentry *debugfs_peek; -static struct dentry *debugfs_poke; -static struct dentry *debugfs_reg_dump; -static unsigned int read_data; -static unsigned int devnum; - static int32_t wsa881x_resource_acquire(struct snd_soc_component *component, bool enable); @@ -401,30 +398,28 @@ static bool is_swr_slv_reg_readable(int reg) return ret; } -static ssize_t wsa881x_swrslave_reg_show(char __user *ubuf, size_t count, - loff_t *ppos) +static ssize_t wsa881x_swrslave_reg_show(struct swr_device *pdev, char __user *ubuf, + size_t count, loff_t *ppos) { int i, reg_val, len; ssize_t total = 0; char tmp_buf[SWR_SLV_MAX_BUF_LEN]; - if (!ubuf || !ppos || (devnum == 0)) + if (!ubuf || !ppos) return 0; for (i = (((int) *ppos / BYTES_PER_LINE) + SWR_SLV_START_REG_ADDR); - i <= SWR_SLV_MAX_REG_ADDR; i++) { + i <= SWR_SLV_MAX_REG_ADDR; i++) { if (!is_swr_slv_reg_readable(i)) continue; - swr_read(dbgwsa881x->swr_slave, devnum, - i, ®_val, 1); - len = snprintf(tmp_buf, 25, "0x%.3x: 0x%.2x\n", i, - (reg_val & 0xFF)); + swr_read(pdev, pdev->dev_num, i, ®_val, 1); + len = snprintf(tmp_buf, sizeof(tmp_buf), "0x%.3x: 0x%.2x\n", i, + (reg_val & 0xFF)); if (len < 0) { pr_err("%s: fail to fill the buffer\n", __func__); total = -EFAULT; goto copy_err; } - if ((total + len) >= count - 1) break; if (copy_to_user((ubuf + total), tmp_buf, len)) { @@ -432,53 +427,84 @@ static ssize_t wsa881x_swrslave_reg_show(char __user *ubuf, size_t count, total = -EFAULT; goto copy_err; } - *ppos += len; total += len; + *ppos += len; } copy_err: + *ppos = SWR_SLV_MAX_REG_ADDR * BYTES_PER_LINE; return total; } +static ssize_t codec_debug_dump(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct swr_device *pdev; + + if (!count || !file || !ppos || !ubuf) + return -EINVAL; + + pdev = file->private_data; + if (!pdev) + return -EINVAL; + + if (*ppos < 0) + return -EINVAL; + + return wsa881x_swrslave_reg_show(pdev, ubuf, count, ppos); +} + static ssize_t codec_debug_read(struct file *file, char __user *ubuf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { char lbuf[SWR_SLV_RD_BUF_LEN]; - char *access_str; - ssize_t ret_cnt; + struct swr_device *pdev = NULL; + struct wsa881x_priv *wsa881x = NULL; if (!count || !file || !ppos || !ubuf) return -EINVAL; - access_str = file->private_data; + pdev = file->private_data; + if (!pdev) + return -EINVAL; + + wsa881x = swr_get_dev_data(pdev); + if (!wsa881x) + return -EINVAL; + if (*ppos < 0) return -EINVAL; - if (!strcmp(access_str, "swrslave_peek")) { - snprintf(lbuf, sizeof(lbuf), "0x%x\n", (read_data & 0xFF)); - ret_cnt = simple_read_from_buffer(ubuf, count, ppos, lbuf, - strnlen(lbuf, 7)); - } else if (!strcmp(access_str, "swrslave_reg_dump")) { - ret_cnt = wsa881x_swrslave_reg_show(ubuf, count, ppos); - } else { - pr_err("%s: %s not permitted to read\n", __func__, access_str); - ret_cnt = -EPERM; - } - return ret_cnt; + snprintf(lbuf, sizeof(lbuf), "0x%x\n", + (wsa881x->read_data & 0xFF)); + + return simple_read_from_buffer(ubuf, count, ppos, lbuf, + strnlen(lbuf, 7)); } -static ssize_t codec_debug_write(struct file *filp, - const char __user *ubuf, size_t cnt, loff_t *ppos) +static ssize_t codec_debug_peek_write(struct file *file, + const char __user *ubuf, size_t cnt, loff_t *ppos) { char lbuf[SWR_SLV_WR_BUF_LEN]; - int rc; + int rc = 0; u32 param[5]; - char *access_str; + struct swr_device *pdev = NULL; + struct wsa881x_priv *wsa881x = NULL; + + if (!cnt || !file || !ppos || !ubuf) + return -EINVAL; + + pdev = file->private_data; + if (!pdev) + return -EINVAL; - if (!filp || !ppos || !ubuf) + wsa881x = swr_get_dev_data(pdev); + if (!wsa881x) + return -EINVAL; + + if (*ppos < 0) return -EINVAL; - access_str = filp->private_data; if (cnt > sizeof(lbuf) - 1) return -EINVAL; @@ -487,32 +513,46 @@ static ssize_t codec_debug_write(struct file *filp, return -EFAULT; lbuf[cnt] = '\0'; - if (!strcmp(access_str, "swrslave_poke")) { - /* write */ - rc = get_parameters(lbuf, param, 3); - if ((param[0] <= SWR_SLV_MAX_REG_ADDR) && (param[1] <= 0xFF) && - (rc == 0)) - swr_write(dbgwsa881x->swr_slave, param[2], - param[0], ¶m[1]); - else - rc = -EINVAL; - } else if (!strcmp(access_str, "swrslave_peek")) { - /* read */ - rc = get_parameters(lbuf, param, 2); - if ((param[0] <= SWR_SLV_MAX_REG_ADDR) && (rc == 0)) - swr_read(dbgwsa881x->swr_slave, param[1], - param[0], &read_data, 1); - else - rc = -EINVAL; - } else if (!strcmp(access_str, "swrslave_reg_dump")) { - /* reg dump */ - rc = get_parameters(lbuf, param, 1); - if ((rc == 0) && (param[0] > 0) && - (param[0] <= SWR_SLV_MAX_DEVICES)) - devnum = param[0]; - else - rc = -EINVAL; - } + rc = get_parameters(lbuf, param, 1); + if (!((param[0] <= SWR_SLV_MAX_REG_ADDR) && (rc == 0))) + return -EINVAL; + swr_read(pdev, pdev->dev_num, param[0], &wsa881x->read_data, 1); + if (rc == 0) + rc = cnt; + else + pr_err("%s: rc = %d\n", __func__, rc); + + return rc; +} + +static ssize_t codec_debug_write(struct file *file, + const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char lbuf[SWR_SLV_WR_BUF_LEN]; + int rc = 0; + u32 param[5]; + struct swr_device *pdev; + + if (!file || !ppos || !ubuf) + return -EINVAL; + + pdev = file->private_data; + if (!pdev) + return -EINVAL; + + if (cnt > sizeof(lbuf) - 1) + return -EINVAL; + + rc = copy_from_user(lbuf, ubuf, cnt); + if (rc) + return -EFAULT; + + lbuf[cnt] = '\0'; + rc = get_parameters(lbuf, param, 2); + if (!((param[0] <= SWR_SLV_MAX_REG_ADDR) && + (param[1] <= 0xFF) && (rc == 0))) + return -EINVAL; + swr_write(pdev, pdev->dev_num, param[0], ¶m[1]); if (rc == 0) rc = cnt; else @@ -521,12 +561,21 @@ static ssize_t codec_debug_write(struct file *filp, return rc; } -static const struct file_operations codec_debug_ops = { +static const struct file_operations codec_debug_write_ops = { .open = codec_debug_open, .write = codec_debug_write, +}; + +static const struct file_operations codec_debug_read_ops = { + .open = codec_debug_open, .read = codec_debug_read, + .write = codec_debug_peek_write, }; +static const struct file_operations codec_debug_dump_ops = { + .open = codec_debug_open, + .read = codec_debug_dump, +}; static void wsa881x_regcache_sync(struct wsa881x_priv *wsa881x) { mutex_lock(&wsa881x->res_lock); @@ -1454,27 +1503,31 @@ static int wsa881x_swr_probe(struct swr_device *pdev) wsa881x_gpio_ctrl(wsa881x, true); wsa881x->state = WSA881X_DEV_UP; - if (!debugfs_wsa881x_dent) { - dbgwsa881x = wsa881x; - debugfs_wsa881x_dent = debugfs_create_dir( - "wsa881x_swr_slave", 0); - if (!IS_ERR(debugfs_wsa881x_dent)) { - debugfs_peek = debugfs_create_file("swrslave_peek", - S_IFREG | 0444, debugfs_wsa881x_dent, - (void *) "swrslave_peek", - &codec_debug_ops); - - debugfs_poke = debugfs_create_file("swrslave_poke", - S_IFREG | 0444, debugfs_wsa881x_dent, - (void *) "swrslave_poke", - &codec_debug_ops); - - debugfs_reg_dump = debugfs_create_file( + if (!wsa881x->debugfs_dent) { + wsa881x->debugfs_dent = debugfs_create_dir( + dev_name(&pdev->dev), 0); + if (!IS_ERR(wsa881x->debugfs_dent)) { + wsa881x->debugfs_peek = + debugfs_create_file("swrslave_peek", + S_IFREG | 0444, + wsa881x->debugfs_dent, + (void *) pdev, + &codec_debug_read_ops); + + wsa881x->debugfs_poke = + debugfs_create_file("swrslave_poke", + S_IFREG | 0444, + wsa881x->debugfs_dent, + (void *) pdev, + &codec_debug_write_ops); + + wsa881x->debugfs_reg_dump = + debugfs_create_file( "swrslave_reg_dump", S_IFREG | 0444, - debugfs_wsa881x_dent, - (void *) "swrslave_reg_dump", - &codec_debug_ops); + wsa881x->debugfs_dent, + (void *) pdev, + &codec_debug_dump_ops); } } @@ -1566,8 +1619,8 @@ static int wsa881x_swr_remove(struct swr_device *pdev) if (wsa881x->register_notifier) wsa881x->register_notifier(wsa881x->handle, &wsa881x->bolero_nblock, false); - debugfs_remove_recursive(debugfs_wsa881x_dent); - debugfs_wsa881x_dent = NULL; + debugfs_remove_recursive(wsa881x->debugfs_dent); + wsa881x->debugfs_dent = NULL; mutex_destroy(&wsa881x->res_lock); mutex_destroy(&wsa881x->temp_lock); snd_soc_unregister_component(&pdev->dev); -- GitLab From 27e8e9bf68f7d2cc23f7d42407a213a03e3faaa5 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Wed, 30 Dec 2020 19:05:37 +0530 Subject: [PATCH 1606/1645] soc: swr-mstr: Fix headset detect issue during clk stop wakeup When ext clk stop wakeup and slave_pending_irq come together then interrupt at swrslave is cleared due to calling enable_slave_irq. Do not clear interrupts for enable_slave_irq when its called from clk stop wakeup. Change-Id: Ia710030ab80306d6750bea7264f0d4c07053d701 Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 12 +++++++++--- soc/swr-mstr-ctrl.h | 3 ++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index d594a9923028..e9dfcf4d9569 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ #include @@ -1755,10 +1755,12 @@ static void swrm_enable_slave_irq(struct swr_mstr_ctrl *swrm) dev_dbg(swrm->dev, "%s: slave status: 0x%x\n", __func__, status); for (i = 0; i < (swrm->master.num_dev + 1); i++) { if (status & SWRM_MCP_SLV_STATUS_MASK) { - swrm_cmd_fifo_rd_cmd(swrm, &temp, i, 0x0, + if (!swrm->clk_stop_wakeup) { + swrm_cmd_fifo_rd_cmd(swrm, &temp, i, 0x0, SWRS_SCP_INT_STATUS_CLEAR_1, 1); - swrm_cmd_fifo_wr_cmd(swrm, 0xFF, i, 0x0, + swrm_cmd_fifo_wr_cmd(swrm, 0xFF, i, 0x0, SWRS_SCP_INT_STATUS_CLEAR_1); + } swrm_cmd_fifo_wr_cmd(swrm, 0x4, i, 0x0, SWRS_SCP_INT_STATUS_MASK_1); } @@ -2170,7 +2172,9 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) * re-enable Host IRQ and process slave pending * interrupts, if any. */ + swrm->clk_stop_wakeup = true; swrm_enable_slave_irq(swrm); + swrm->clk_stop_wakeup = false; } break; default: @@ -2741,6 +2745,8 @@ static int swrm_probe(struct platform_device *pdev) swrm->dev_up = true; swrm->state = SWR_MSTR_UP; swrm->ipc_wakeup = false; + swrm->enable_slave_irq = false; + swrm->clk_stop_wakeup = false; swrm->ipc_wakeup_triggered = false; swrm->disable_div2_clk_switch = FALSE; init_completion(&swrm->reset); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index ed67f0e443e6..1b707166bd29 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ #ifndef _SWR_WCD_CTRL_H @@ -186,6 +186,7 @@ struct swr_mstr_ctrl { u32 rd_fifo_depth; u32 wr_fifo_depth; bool enable_slave_irq; + bool clk_stop_wakeup; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_swrm_dent; struct dentry *debugfs_peek; -- GitLab From 989605a308e760bc4e65bf8a70eace857c627535 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 20 Jan 2021 11:17:22 +0530 Subject: [PATCH 1607/1645] asoc: Update copy_to_user to requested buffer size Avoid copy to user more than requested buffer size to avoid memory corruption. Change-Id: Ibf1607f777a358ebd16fd8b8728809afda34eba7 Signed-off-by: Laxminath Kasam --- asoc/msm-pcm-q6-v2.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index de8519d1bcca..e6a5c1a7a34b 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ @@ -1009,7 +1009,10 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, pr_debug("Offset value = %d\n", offset); if (size == 0 || size < prtd->pcm_count) { memset(bufptr + offset + size, 0, prtd->pcm_count - size); - size = xfer = prtd->pcm_count; + if (fbytes > prtd->pcm_count) + size = xfer = prtd->pcm_count; + else + size = xfer = fbytes; } if (copy_to_user(buf, bufptr+offset, xfer)) { -- GitLab From 8165cfdabdd8f15c63bea533054560a4299bb019 Mon Sep 17 00:00:00 2001 From: Harshal Ahire Date: Tue, 12 Jan 2021 17:09:34 +0530 Subject: [PATCH 1608/1645] asoc: Add check to handle negative value passed for num_app_cfg_type Long int negative value passed as part of ucontrol structure is assigned to int num_app_cfg_type making it positive and leading to overflow while populating maximum supported lsm_app_type_cfg structures. Change-Id: I81e3c75eea82265c8e8e1b3f8f95d9e334c895c4 Signed-off-by: Harshal Ahire --- asoc/msm-pcm-routing-v2.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 37635a84764f..7aafe2b93c19 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #include @@ -22773,9 +22773,9 @@ static int msm_routing_put_app_type_cfg_control(struct snd_kcontrol *kcontrol, memset(app_type_cfg, 0, MAX_APP_TYPES* sizeof(struct msm_pcm_routing_app_type_data)); - if (num_app_types > MAX_APP_TYPES) { - pr_err("%s: number of app types exceed the max supported\n", - __func__); + if (num_app_types > MAX_APP_TYPES || num_app_types < 0) { + pr_err("%s: number of app types %d is invalid\n", + __func__, num_app_types); return -EINVAL; } for (j = 0; j < num_app_types; j++) { @@ -22979,9 +22979,10 @@ static int msm_routing_put_lsm_app_type_cfg_control( int i = 0, j; mutex_lock(&routing_lock); - if (ucontrol->value.integer.value[0] > MAX_APP_TYPES) { - pr_err("%s: number of app types exceed the max supported\n", - __func__); + if (ucontrol->value.integer.value[0] < 0 || + ucontrol->value.integer.value[0] > MAX_APP_TYPES) { + pr_err("%s: number of app types %ld is invalid\n", + __func__, ucontrol->value.integer.value[0]); mutex_unlock(&routing_lock); return -EINVAL; } -- GitLab From 227a982a2cfae41cc9595f220fd7de234f2253ce Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 22 Sep 2020 16:06:33 +0530 Subject: [PATCH 1609/1645] soc: swr-mstr: Check if fifo available before bulk write Check for fifo availability before writing slave registers during swrm master bulk write so as to prevent swr overflow, underflow errors. Change-Id: I97a914cac289b3f1215ccf5c1abec88b959a9f21 Signed-off-by: Vatsal Bucha --- soc/swr-mstr-ctrl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index e9dfcf4d9569..385e59fa4e14 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -104,6 +104,7 @@ static void swrm_unlock_sleep(struct swr_mstr_ctrl *swrm); static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr); static void swr_master_write(struct swr_mstr_ctrl *swrm, u16 reg_addr, u32 val); static int swrm_runtime_resume(struct device *dev); +static void swrm_wait_for_fifo_avail(struct swr_mstr_ctrl *swrm, int swrm_rd_wr); static u8 swrm_get_clk_div(int mclk_freq, int bus_clk_freq) { @@ -627,6 +628,9 @@ static int swr_master_bulk_write(struct swr_mstr_ctrl *swrm, u32 *reg_addr, * This still meets the hardware spec */ usleep_range(50, 55); + if (reg_addr[i] == SWRM_CMD_FIFO_WR_CMD) + swrm_wait_for_fifo_avail(swrm, + SWRM_WR_CHECK_AVAIL); swr_master_write(swrm, reg_addr[i], val[i]); } usleep_range(100, 110); -- GitLab From 97f90ea914913fa6c2c0ba6e27667a3604dbf732 Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Tue, 28 Apr 2020 09:16:55 +0530 Subject: [PATCH 1610/1645] ASoC: dsp: Synchronise adm and rtac commands Race condition observed while processing the set_pp_params command responses sent back to back by adsp for commands sent from adm and rtac. Handle this by synchronising the get/set pp_params command in both the drivers. Change-Id: Id89d98217dc5cad3703e5d545ddee21cb145c874 Signed-off-by: Soumya Managoli --- dsp/q6adm.c | 107 +++++++++++++++++++++++++++++------------ dsp/rtac.c | 30 ++---------- include/dsp/q6adm-v2.h | 2 + 3 files changed, 81 insertions(+), 58 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 51ca185b9ca2..708cc0fdbca3 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -95,6 +95,7 @@ struct adm_ctl { struct param_outband outband_memmap; struct source_tracking_data sourceTrackingData; + struct mutex adm_apr_lock; int set_custom_topology; int ec_ref_rx; int num_ec_ref_rx_chans; @@ -869,6 +870,58 @@ int adm_set_custom_chmix_cfg(int port_id, int copp_idx, } EXPORT_SYMBOL(adm_set_custom_chmix_cfg); +/* + * adm_apr_send_pkt : returns 0 on success, negative otherwise. + */ +int adm_apr_send_pkt(void *data, wait_queue_head_t *wait, + int port_idx, int copp_idx) +{ + int ret = 0; + atomic_t *copp_stat = NULL; + wait = &this_adm.copp.wait[port_idx][copp_idx]; + + if (!wait) + return -EINVAL; + + mutex_lock(&this_adm.adm_apr_lock); + pr_debug("%s: port idx %d copp idx %d\n", __func__, + port_idx, copp_idx); + copp_stat = &this_adm.copp.stat[port_idx][copp_idx]; + atomic_set(copp_stat, -1); + + if (atomic_read(&this_adm.copp.cnt[port_idx][copp_idx]) == 0) { + pr_err("%s: port[0x%x] coppid[0x%x] is not active, ERROR\n", + __func__, port_idx, copp_idx); + mutex_unlock(&this_adm.adm_apr_lock); + return -EINVAL; + } + + ret = apr_send_pkt(this_adm.apr, data); + if (ret > 0) { + ret = wait_event_timeout(*wait, + atomic_read(copp_stat) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (atomic_read(copp_stat) > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(atomic_read(copp_stat))); + ret = adsp_err_get_lnx_err_code(atomic_read(copp_stat)); + } else if (!ret) { + pr_err_ratelimited("%s: request timedout\n", + __func__); + ret = -ETIMEDOUT; + } else { + ret = 0; + } + } else if (ret == 0) { + pr_err("%s: packet not transmitted\n", __func__); + /* apr_send_pkt can return 0 when nothing is transmitted */ + ret = -EINVAL; + } + + mutex_unlock(&this_adm.adm_apr_lock); + return ret; +} + /* * With pre-packed data, only the opcode differes from V5 and V6. * Use q6common_pack_pp_params to pack the data correctly. @@ -880,7 +933,6 @@ int adm_set_pp_params(int port_id, int copp_idx, struct adm_cmd_set_pp_params *adm_set_params = NULL; int size = 0; int port_idx = 0; - atomic_t *copp_stat = NULL; int ret = 0; port_id = afe_convert_virtual_to_portid(port_id); @@ -938,32 +990,9 @@ int adm_set_pp_params(int port_id, int copp_idx, ret = -EINVAL; goto done; } - - copp_stat = &this_adm.copp.stat[port_idx][copp_idx]; - atomic_set(copp_stat, -1); - ret = apr_send_pkt(this_adm.apr, (uint32_t *) adm_set_params); - if (ret < 0) { - pr_err("%s: Set params APR send failed port = 0x%x ret %d\n", - __func__, port_id, ret); - goto done; - } - ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(copp_stat) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: Set params timed out port = 0x%x\n", __func__, - port_id); - ret = -ETIMEDOUT; - goto done; - } - if (atomic_read(copp_stat) > 0) { - pr_err("%s: DSP returned error[%s]\n", __func__, - adsp_err_get_err_str(atomic_read(copp_stat))); - ret = adsp_err_get_lnx_err_code(atomic_read(copp_stat)); - goto done; - } - - ret = 0; + ret = adm_apr_send_pkt((uint32_t *) adm_set_params, + &this_adm.copp.wait[port_idx][copp_idx], + port_idx, copp_idx); done: kfree(adm_set_params); return ret; @@ -1601,8 +1630,15 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) this_adm.sourceTrackingData. apr_cmd_status = payload[1]; else if (rtac_make_adm_callback(payload, - data->payload_size)) - break; + data->payload_size)) { + pr_debug("%s: rtac cmd response\n", + __func__); + } + atomic_set(&this_adm.copp.stat[port_idx] + [copp_idx], payload[1]); + wake_up( + &this_adm.copp.wait[port_idx][copp_idx]); + break; /* * if soft volume is called and already * interrupted break out of the sequence here @@ -1611,8 +1647,8 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) case ADM_CMD_DEVICE_CLOSE_V5: case ADM_CMD_DEVICE_OPEN_V6: case ADM_CMD_DEVICE_OPEN_V8: - pr_debug("%s: Basic callback received, wake up.\n", - __func__); + pr_debug("%s: Basic callback received for 0x%x, wake up.\n", + __func__, payload[0]); atomic_set(&this_adm.copp.stat[port_idx] [copp_idx], payload[1]); wake_up( @@ -1745,8 +1781,13 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) this_adm.sourceTrackingData.apr_cmd_status = payload[0]; else if (rtac_make_adm_callback(payload, - data->payload_size)) + data->payload_size)) { + pr_debug("%s: rtac cmd response\n", __func__); + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], + payload[0]); + wake_up(&this_adm.copp.wait[port_idx][copp_idx]); break; + } idx = ADM_GET_PARAMETER_LENGTH * copp_idx; if (payload[0] == 0 && data->payload_size > 0) { @@ -5504,6 +5545,7 @@ int __init adm_init(void) this_adm.ffecns_port_id = -1; init_waitqueue_head(&this_adm.matrix_map_wait); init_waitqueue_head(&this_adm.adm_wait); + mutex_init(&this_adm.adm_apr_lock); for (i = 0; i < AFE_MAX_PORTS; i++) { for (j = 0; j < MAX_COPPS_PER_PORT; j++) { @@ -5528,6 +5570,7 @@ int __init adm_init(void) void adm_exit(void) { + mutex_destroy(&this_adm.adm_apr_lock); if (this_adm.apr) adm_reset_data(); adm_delete_cal_data(); diff --git a/dsp/rtac.c b/dsp/rtac.c index c77b5f0971f1..ed298e9caab0 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -728,7 +728,6 @@ bool rtac_make_adm_callback(uint32_t *payload, u32 payload_size) atomic_set(&rtac_common.apr_err_code, payload[1]); atomic_set(&rtac_adm_apr_data.cmd_state, 0); - wake_up(&rtac_adm_apr_data.cmd_wait); return true; } @@ -880,33 +879,12 @@ int send_adm_apr(void *buf, u32 opcode) pr_debug("%s: Sending RTAC command ioctl 0x%x, paddr 0x%pK\n", __func__, opcode, &rtac_cal[ADM_RTAC_CAL].cal_data.paddr); + mutex_unlock(&rtac_adm_apr_mutex); - result = apr_send_pkt(rtac_adm_apr_data.apr_handle, - (uint32_t *)rtac_adm_buffer); - if (result < 0) { - pr_err("%s: Set params failed copp = %d\n", __func__, copp_id); - goto err; - } - /* Wait for the callback */ - result = wait_event_timeout(rtac_adm_apr_data.cmd_wait, - (atomic_read(&rtac_adm_apr_data.cmd_state) == 0), - msecs_to_jiffies(TIMEOUT_MS)); - if (!result) { - pr_err("%s: Set params timed out copp = %d\n", __func__, - copp_id); - goto err; - } - if (atomic_read(&rtac_common.apr_err_code)) { - pr_err("%s: DSP returned error code = [%s], opcode = 0x%x\n", - __func__, adsp_err_get_err_str(atomic_read( - &rtac_common.apr_err_code)), - opcode); - result = adsp_err_get_lnx_err_code( - atomic_read( - &rtac_common.apr_err_code)); - goto err; - } + result = adm_apr_send_pkt((uint32_t *)rtac_adm_buffer, + NULL, port_idx, copp_idx); + mutex_lock(&rtac_adm_apr_mutex); if (opcode == ADM_CMD_GET_PP_PARAMS_V5) { bytes_returned = ((u32 *)rtac_cal[ADM_RTAC_CAL].cal_data. kvaddr)[2] + 3 * sizeof(u32); diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 644855d0bb83..20b2450be0a5 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -229,4 +229,6 @@ void msm_dts_srs_acquire_lock(void); void msm_dts_srs_release_lock(void); void adm_set_native_mode(int mode); int adm_set_ffecns_freeze_event(bool ffecns_freeze_event); +int adm_apr_send_pkt(void *data, wait_queue_head_t *wait, + int port_idx, int copp_idx); #endif /* __Q6_ADM_V2_H__ */ -- GitLab From cc71e4908e5d5a60892793d54a4b0be61d458421 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Wed, 14 Oct 2020 20:52:09 +0530 Subject: [PATCH 1611/1645] asoc: bolero: Add core_vote before gfmux access GFMUX access happen during RX macro usecase. Update rx macro to do core_vote before clock request. Change-Id: I1afd38ae13066dcfbda307308afce7c4291142d9 Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/rx-macro.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 07dd8adae9e7..7b3cad04fd6e 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -350,6 +350,7 @@ struct rx_macro_bcl_pmic_params { u8 ppid; }; +static int rx_macro_core_vote(void *handle, bool enable); static int rx_macro_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai); @@ -1230,6 +1231,7 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, if (rx_priv->rx_mclk_users == 0) { if (rx_priv->is_native_on) rx_priv->clk_id = RX_CORE_CLK; + rx_macro_core_vote(rx_priv, true); ret = bolero_clk_rsc_request_clock(rx_priv->dev, rx_priv->default_clk_id, rx_priv->clk_id, @@ -1283,6 +1285,7 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, 0x01, 0x00); bolero_clk_rsc_fs_gen_request(rx_priv->dev, false); + rx_macro_core_vote(rx_priv, true); bolero_clk_rsc_request_clock(rx_priv->dev, rx_priv->default_clk_id, rx_priv->clk_id, @@ -1396,18 +1399,21 @@ static int rx_macro_event_handler(struct snd_soc_component *component, } break; case BOLERO_MACRO_EVT_PRE_SSR_UP: + rx_macro_core_vote(rx_priv, true); /* enable&disable RX_CORE_CLK to reset GFMUX reg */ ret = bolero_clk_rsc_request_clock(rx_priv->dev, rx_priv->default_clk_id, RX_CORE_CLK, true); - if (ret < 0) + if (ret < 0) { dev_err_ratelimited(rx_priv->dev, "%s, failed to enable clk, ret:%d\n", __func__, ret); - else + } else { + rx_macro_core_vote(rx_priv, true); bolero_clk_rsc_request_clock(rx_priv->dev, rx_priv->default_clk_id, RX_CORE_CLK, false); + } break; case BOLERO_MACRO_EVT_SSR_UP: trace_printk("%s, enter SSR up\n", __func__); -- GitLab From 0a0c718a77ba6da31de9bf5d6726635f2a924b3d Mon Sep 17 00:00:00 2001 From: "Vangala, Amarnath" Date: Thu, 3 Dec 2020 14:14:56 +0530 Subject: [PATCH 1612/1645] asoc: codecs: add child devices after completing initialization In bolero-cdc and tx, va, wsa and rx macros, move schedule_work call to add the child devices to the point later to where the parent initialization gets completed. Change-Id: Iaa07329a25020dde21d9249c3848bb7fcf7d816a Signed-off-by: Vangala, Amarnath --- asoc/codecs/bolero/bolero-cdc.c | 2 +- asoc/codecs/bolero/rx-macro.c | 2 +- asoc/codecs/bolero/tx-macro.c | 4 ++-- asoc/codecs/bolero/va-macro.c | 4 ++-- asoc/codecs/bolero/wsa-macro.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 53c70fabedb8..e80a82390a81 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -1379,7 +1379,6 @@ static int bolero_probe(struct platform_device *pdev) mutex_init(&priv->vote_lock); INIT_WORK(&priv->bolero_add_child_devices_work, bolero_add_child_devices); - schedule_work(&priv->bolero_add_child_devices_work); /* Register LPASS core hw vote */ lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote"); @@ -1403,6 +1402,7 @@ static int bolero_probe(struct platform_device *pdev) } priv->lpass_audio_hw_vote = lpass_audio_hw_vote; + schedule_work(&priv->bolero_add_child_devices_work); return 0; } diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 07dd8adae9e7..f619c51a9cd4 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -4165,12 +4165,12 @@ static int rx_macro_probe(struct platform_device *pdev) "%s: register macro failed\n", __func__); goto err_reg_macro; } - schedule_work(&rx_priv->rx_macro_add_child_devices_work); pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); pm_suspend_ignore_children(&pdev->dev, true); pm_runtime_enable(&pdev->dev); + schedule_work(&rx_priv->rx_macro_add_child_devices_work); return 0; diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index de04e1e90c49..a9afea49a2a5 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -3280,13 +3280,13 @@ static int tx_macro_probe(struct platform_device *pdev) "%s: register macro failed\n", __func__); goto err_reg_macro; } - if (is_used_tx_swr_gpio) - schedule_work(&tx_priv->tx_macro_add_child_devices_work); pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); pm_suspend_ignore_children(&pdev->dev, true); pm_runtime_enable(&pdev->dev); + if (is_used_tx_swr_gpio) + schedule_work(&tx_priv->tx_macro_add_child_devices_work); return 0; err_reg_macro: diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 2e36995242fa..20117e7f0b47 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -3143,13 +3143,13 @@ static int va_macro_probe(struct platform_device *pdev) dev_err(&pdev->dev, "%s: register macro failed\n", __func__); goto reg_macro_fail; } - if (is_used_va_swr_gpio) - schedule_work(&va_priv->va_macro_add_child_devices_work); pm_runtime_set_autosuspend_delay(&pdev->dev, VA_AUTO_SUSPEND_DELAY); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); pm_suspend_ignore_children(&pdev->dev, true); pm_runtime_enable(&pdev->dev); + if (is_used_va_swr_gpio) + schedule_work(&va_priv->va_macro_add_child_devices_work); return ret; reg_macro_fail: diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 5ace96db07ca..e867141fd337 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -3237,12 +3237,12 @@ static int wsa_macro_probe(struct platform_device *pdev) dev_err(&pdev->dev, "%s: register macro failed\n", __func__); goto reg_macro_fail; } - schedule_work(&wsa_priv->wsa_macro_add_child_devices_work); pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); pm_suspend_ignore_children(&pdev->dev, true); pm_runtime_enable(&pdev->dev); + schedule_work(&wsa_priv->wsa_macro_add_child_devices_work); return ret; reg_macro_fail: -- GitLab From 34df55a3bd442a10cb6839bb729bfb08dc0e8c93 Mon Sep 17 00:00:00 2001 From: Kunlei Zhang Date: Wed, 24 Feb 2021 11:25:41 +0800 Subject: [PATCH 1613/1645] dsp: update size check for get VI param function In afe_get_cal_sp_th_vi_param functions, data size should check with size of cal_type_header. The check is not present which might lead to out of bounds access. Update condition to ensure data_size is greater than or equal to size of cal_type_header. Change-Id: Ib2904f53243f4fb858131511812fd90de32b4656 Signed-off-by: Kunlei Zhang --- dsp/q6afe.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 88124df9deda..7f594f29b2b7 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -10160,6 +10160,7 @@ static int afe_get_cal_sp_th_vi_param(int32_t cal_type, size_t data_size, if (cal_data == NULL || data_size > sizeof(*cal_data) || + data_size < sizeof(cal_data->cal_hdr) || this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL) return 0; @@ -10188,7 +10189,8 @@ static int afe_get_cal_spv4_ex_vi_ftm_param(int32_t cal_type, size_t data_size, pr_debug("%s: cal_type = %d\n", __func__, cal_type); if (this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL] == NULL || cal_data == NULL || - data_size != sizeof(*cal_data)) + data_size > sizeof(*cal_data) || + data_size < sizeof(cal_data->cal_hdr)) goto done; mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL]->lock); @@ -10255,7 +10257,8 @@ static int afe_get_cal_sp_ex_vi_ftm_param(int32_t cal_type, size_t data_size, pr_debug("%s: cal_type = %d\n", __func__, cal_type); if (this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL || cal_data == NULL || - data_size != sizeof(*cal_data)) + data_size > sizeof(*cal_data) || + data_size < sizeof(cal_data->cal_hdr)) goto done; mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); -- GitLab From e4c6762dbd22f4290839ce63165dccfbdaf4e9bc Mon Sep 17 00:00:00 2001 From: Shashi Kant Maurya Date: Tue, 23 Feb 2021 17:30:16 +0530 Subject: [PATCH 1614/1645] dsp: adm: add to check output/input channel To avoid out of bound value of output/input channel add the check. Change-Id: I25b7616d6fc08c2d0bb530dfb1457471dc25861c Signed-off-by: Shashi Kant Maurya Signed-off-by: Lakshman Chaluvaraju --- asoc/msm-pcm-routing-v2.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 7aafe2b93c19..99e93c3995b2 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1729,6 +1729,11 @@ static int msm_pcm_routing_channel_mixer(int fe_id, bool perf_mode, for (i = 0; i < ADM_MAX_CHANNELS && channel_input[fe_id][i] > 0; ++i) { be_id = channel_input[fe_id][i] - 1; + if (be_id < 0 || be_id >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: Received out of bounds be_id %d\n", + __func__, be_id); + return -EINVAL; + } channel_mixer[fe_id].input_channels[i] = msm_bedais[be_id].channel; @@ -3470,10 +3475,10 @@ static int msm_pcm_get_out_chs(struct snd_kcontrol *kcontrol, static int msm_pcm_put_out_chs(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - u16 fe_id = 0; - + u16 fe_id = 0, out_ch = 0; fe_id = ((struct soc_multi_mixer_control *) kcontrol->private_value)->shift; + out_ch = ucontrol->value.integer.value[0]; if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) { pr_err("%s: invalid FE %d\n", __func__, fe_id); return -EINVAL; @@ -3482,6 +3487,12 @@ static int msm_pcm_put_out_chs(struct snd_kcontrol *kcontrol, pr_debug("%s: fe_id is %d, output channels = %d\n", __func__, fe_id, (unsigned int)(ucontrol->value.integer.value[0])); + if (out_ch < 0 || + out_ch > ADM_MAX_CHANNELS) { + pr_err("%s: invalid output channel %d\n", __func__, + out_ch); + return -EINVAL; + } channel_mixer[fe_id].output_channel = (unsigned int)(ucontrol->value.integer.value[0]); -- GitLab From d0adc6a072415e18524238c02685a29a59363577 Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Wed, 24 Feb 2021 19:33:53 +0530 Subject: [PATCH 1615/1645] ASoC: dsp: Synchronise adm commands Race condition observed while processing the get/set_pp_params and adm_close command. Synchronise adm open, close and get/set_pp_params by sending the apr cmd pkt using the same lock. Change-Id: I9a1ebcedc91f78f3940846688f8569ec9088e1e7 Signed-off-by: Soumya Managoli --- dsp/q6adm.c | 120 +++++++++++++---------------------------- dsp/rtac.c | 4 +- include/dsp/q6adm-v2.h | 4 +- 3 files changed, 40 insertions(+), 88 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index 708cc0fdbca3..e63547d85738 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -874,10 +874,11 @@ EXPORT_SYMBOL(adm_set_custom_chmix_cfg); * adm_apr_send_pkt : returns 0 on success, negative otherwise. */ int adm_apr_send_pkt(void *data, wait_queue_head_t *wait, - int port_idx, int copp_idx) + int port_idx, int copp_idx, int opcode) { int ret = 0; atomic_t *copp_stat = NULL; + int32_t time_out = msecs_to_jiffies(TIMEOUT_MS); wait = &this_adm.copp.wait[port_idx][copp_idx]; if (!wait) @@ -889,18 +890,30 @@ int adm_apr_send_pkt(void *data, wait_queue_head_t *wait, copp_stat = &this_adm.copp.stat[port_idx][copp_idx]; atomic_set(copp_stat, -1); - if (atomic_read(&this_adm.copp.cnt[port_idx][copp_idx]) == 0) { - pr_err("%s: port[0x%x] coppid[0x%x] is not active, ERROR\n", - __func__, port_idx, copp_idx); - mutex_unlock(&this_adm.adm_apr_lock); - return -EINVAL; + if (opcode != ADM_CMD_DEVICE_OPEN_V8 && + opcode != ADM_CMD_DEVICE_OPEN_V6 && + opcode != ADM_CMD_DEVICE_OPEN_V5 && + opcode != ADM_CMD_DEVICE_CLOSE_V5) { + if (atomic_read(&this_adm.copp.cnt[port_idx][copp_idx]) + == 0) { + pr_err("%s: port[0x%x] copp[0x%x] inactive\n", + __func__, port_idx, copp_idx); + mutex_unlock(&this_adm.adm_apr_lock); + return -EINVAL; + } + } + + if (opcode == ADM_CMD_DEVICE_OPEN_V8 || + opcode == ADM_CMD_DEVICE_OPEN_V6 || + opcode == ADM_CMD_DEVICE_OPEN_V5) { + time_out = msecs_to_jiffies(2 * TIMEOUT_MS); } ret = apr_send_pkt(this_adm.apr, data); if (ret > 0) { ret = wait_event_timeout(*wait, atomic_read(copp_stat) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); + time_out); if (atomic_read(copp_stat) > 0) { pr_err("%s: DSP returned error[%s]\n", __func__, adsp_err_get_err_str(atomic_read(copp_stat))); @@ -992,7 +1005,7 @@ int adm_set_pp_params(int port_id, int copp_idx, } ret = adm_apr_send_pkt((uint32_t *) adm_set_params, &this_adm.copp.wait[port_idx][copp_idx], - port_idx, copp_idx); + port_idx, copp_idx, adm_set_params->apr_hdr.opcode); done: kfree(adm_set_params); return ret; @@ -1045,7 +1058,6 @@ int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id, int returned_param_size_in_bytes = 0; int port_idx = 0; int idx = 0; - atomic_t *copp_stat = NULL; int ret = 0; if (param_hdr == NULL) { @@ -1093,33 +1105,9 @@ int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id, else adm_get_params.apr_hdr.opcode = ADM_CMD_GET_PP_PARAMS_V5; - copp_stat = &this_adm.copp.stat[port_idx][copp_idx]; - atomic_set(copp_stat, -1); - - ret = apr_send_pkt(this_adm.apr, (uint32_t *) &adm_get_params); - if (ret < 0) { - pr_err("%s: Get params APR send failed port = 0x%x ret %d\n", - __func__, port_id, ret); - ret = -EINVAL; - goto done; - } - ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(copp_stat) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: Get params timed out port = 0x%x\n", __func__, - port_id); - ret = -ETIMEDOUT; - goto done; - } - if (atomic_read(copp_stat) > 0) { - pr_err("%s: DSP returned error[%s]\n", __func__, - adsp_err_get_err_str(atomic_read(copp_stat))); - ret = adsp_err_get_lnx_err_code(atomic_read(copp_stat)); - goto done; - } - - ret = 0; + ret = adm_apr_send_pkt((uint32_t *) &adm_get_params, + &this_adm.copp.wait[port_idx][copp_idx], + port_idx, copp_idx, adm_get_params.apr_hdr.opcode); /* Copy data to caller if sent in band */ if (!returned_param_data) { @@ -1147,7 +1135,6 @@ int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id, memcpy(returned_param_data, &adm_get_parameters[idx + 1], returned_param_size_in_bytes); -done: return ret; } EXPORT_SYMBOL(adm_get_pp_params); @@ -3328,8 +3315,9 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, ep2_payload_size); } - ret = apr_send_pkt(this_adm.apr, - (uint32_t *)adm_params); + ret = adm_apr_send_pkt((uint32_t *) adm_params, + &this_adm.copp.wait[port_idx][copp_idx], + port_idx, copp_idx, open_v8.hdr.opcode); if (ret < 0) { pr_err("%s: port_id: 0x%x for[0x%x] failed %d for open_v8\n", __func__, tmp_port, port_id, ret); @@ -3415,11 +3403,13 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, if (ret) return ret; - ret = apr_send_pkt(this_adm.apr, - (uint32_t *)&open_v6); + ret = adm_apr_send_pkt((uint32_t *) &open_v6, + &this_adm.copp.wait[port_idx][copp_idx], + port_idx, copp_idx, open_v6.hdr.opcode); } else { - ret = apr_send_pkt(this_adm.apr, - (uint32_t *)&open); + ret = adm_apr_send_pkt((uint32_t *) &open, + &this_adm.copp.wait[port_idx][copp_idx], + port_idx, copp_idx, open.hdr.opcode); } if (ret < 0) { pr_err("%s: port_id: 0x%x for[0x%x] failed %d\n", @@ -3427,26 +3417,6 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, return -EINVAL; } } - - /* Wait for the callback with copp id */ - ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) >= 0, - msecs_to_jiffies(2 * TIMEOUT_MS)); - if (!ret) { - pr_err("%s: ADM open timedout for port_id: 0x%x for [0x%x]\n", - __func__, tmp_port, port_id); - return -EINVAL; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - return adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - } } atomic_inc(&this_adm.copp.cnt[port_idx][copp_idx]); @@ -3951,31 +3921,13 @@ int adm_close(int port_id, int perf_mode, int copp_idx) clear_bit(ADM_STATUS_CALIBRATION_REQUIRED, (void *)&this_adm.copp.adm_status[port_idx][copp_idx]); - - ret = apr_send_pkt(this_adm.apr, (uint32_t *)&close); + ret = adm_apr_send_pkt((uint32_t *) &close, + &this_adm.copp.wait[port_idx][copp_idx], + port_idx, copp_idx, close.opcode); if (ret < 0) { pr_err("%s: ADM close failed %d\n", __func__, ret); return -EINVAL; } - - ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: ADM cmd Route timedout for port 0x%x\n", - __func__, port_id); - return -EINVAL; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - return adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - } } if (perf_mode != ULTRA_LOW_LATENCY_PCM_MODE) { diff --git a/dsp/rtac.c b/dsp/rtac.c index ed298e9caab0..4ae16f06a415 100644 --- a/dsp/rtac.c +++ b/dsp/rtac.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #include @@ -882,7 +882,7 @@ int send_adm_apr(void *buf, u32 opcode) mutex_unlock(&rtac_adm_apr_mutex); result = adm_apr_send_pkt((uint32_t *)rtac_adm_buffer, - NULL, port_idx, copp_idx); + NULL, port_idx, copp_idx, adm_params.opcode); mutex_lock(&rtac_adm_apr_mutex); if (opcode == ADM_CMD_GET_PP_PARAMS_V5) { diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h index 20b2450be0a5..84fc1e01ec14 100644 --- a/include/dsp/q6adm-v2.h +++ b/include/dsp/q6adm-v2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #ifndef __Q6_ADM_V2_H__ #define __Q6_ADM_V2_H__ @@ -230,5 +230,5 @@ void msm_dts_srs_release_lock(void); void adm_set_native_mode(int mode); int adm_set_ffecns_freeze_event(bool ffecns_freeze_event); int adm_apr_send_pkt(void *data, wait_queue_head_t *wait, - int port_idx, int copp_idx); + int port_idx, int copp_idx, int opcode); #endif /* __Q6_ADM_V2_H__ */ -- GitLab From 258d29334a915d45b7ad6b1820cc5a0be5b375b0 Mon Sep 17 00:00:00 2001 From: "Vangala, Amarnath" Date: Tue, 27 Oct 2020 23:53:04 +0530 Subject: [PATCH 1616/1645] asoc: codecs: fix race condition of core vote and reg access Auto suspend timer for core vote is triggering before read write complete. Move the auto suspend of core vote to post read write operation. Change-Id: Ib0f6b026fe0e7fd3fbe052691db492915e436a78 Signed-off-by: Vangala, Amarnath --- asoc/codecs/bolero/rx-macro.c | 17 ++++++++----- asoc/codecs/bolero/tx-macro.c | 13 ++++++---- asoc/codecs/bolero/va-macro.c | 13 ++++++---- asoc/codecs/bolero/wsa-macro.c | 13 ++++++---- soc/swr-mstr-ctrl.c | 45 ++++++++++++++++++++++++++++------ 5 files changed, 73 insertions(+), 28 deletions(-) diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 9167088f0922..9934a86525db 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1236,6 +1236,7 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, rx_priv->default_clk_id, rx_priv->clk_id, true); + rx_macro_core_vote(rx_priv, false); if (ret < 0) { dev_err(rx_priv->dev, "%s: rx request clock enable failed\n", @@ -1290,6 +1291,7 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, rx_priv->default_clk_id, rx_priv->clk_id, false); + rx_macro_core_vote(rx_priv, false); rx_priv->clk_id = rx_priv->default_clk_id; } } @@ -1409,11 +1411,11 @@ static int rx_macro_event_handler(struct snd_soc_component *component, "%s, failed to enable clk, ret:%d\n", __func__, ret); } else { - rx_macro_core_vote(rx_priv, true); bolero_clk_rsc_request_clock(rx_priv->dev, rx_priv->default_clk_id, RX_CORE_CLK, false); } + rx_macro_core_vote(rx_priv, false); break; case BOLERO_MACRO_EVT_SSR_UP: trace_printk("%s, enter SSR up\n", __func__); @@ -3678,22 +3680,25 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { static int rx_macro_core_vote(void *handle, bool enable) { + int rc = 0; struct rx_macro_priv *rx_priv = (struct rx_macro_priv *) handle; if (rx_priv == NULL) { pr_err("%s: rx priv data is NULL\n", __func__); return -EINVAL; } + if (enable) { pm_runtime_get_sync(rx_priv->dev); + if (bolero_check_core_votes(rx_priv->dev)) + rc = 0; + else + rc = -ENOTSYNC; + } else { pm_runtime_put_autosuspend(rx_priv->dev); pm_runtime_mark_last_busy(rx_priv->dev); } - - if (bolero_check_core_votes(rx_priv->dev)) - return 0; - else - return -EINVAL; + return rc; } static int rx_swrm_clock(void *handle, bool enable) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index a9afea49a2a5..7f0e758b27cd 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -2678,22 +2678,25 @@ static int tx_macro_clk_switch(struct snd_soc_component *component, int clk_src) static int tx_macro_core_vote(void *handle, bool enable) { + int rc = 0; struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle; if (tx_priv == NULL) { pr_err("%s: tx priv data is NULL\n", __func__); return -EINVAL; } + if (enable) { pm_runtime_get_sync(tx_priv->dev); + if (bolero_check_core_votes(tx_priv->dev)) + rc = 0; + else + rc = -ENOTSYNC; + } else { pm_runtime_put_autosuspend(tx_priv->dev); pm_runtime_mark_last_busy(tx_priv->dev); } - - if (bolero_check_core_votes(tx_priv->dev)) - return 0; - else - return -EINVAL; + return rc; } static int tx_macro_swrm_clock(void *handle, bool enable) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 20117e7f0b47..93fc0fc92210 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -671,22 +671,25 @@ static int va_macro_tx_va_mclk_enable(struct va_macro_priv *va_priv, static int va_macro_core_vote(void *handle, bool enable) { + int rc = 0; struct va_macro_priv *va_priv = (struct va_macro_priv *) handle; if (va_priv == NULL) { pr_err("%s: va priv data is NULL\n", __func__); return -EINVAL; } + if (enable) { pm_runtime_get_sync(va_priv->dev); + if (bolero_check_core_votes(va_priv->dev)) + rc = 0; + else + rc = -ENOTSYNC; + } else { pm_runtime_put_autosuspend(va_priv->dev); pm_runtime_mark_last_busy(va_priv->dev); } - - if (bolero_check_core_votes(va_priv->dev)) - return 0; - else - return -EINVAL; + return rc; } static int va_macro_swrm_clock(void *handle, bool enable) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index e867141fd337..4e06d12bea90 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -2828,22 +2828,25 @@ static void wsa_macro_init_reg(struct snd_soc_component *component) static int wsa_macro_core_vote(void *handle, bool enable) { + int rc = 0; struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle; if (wsa_priv == NULL) { pr_err("%s: wsa priv data is NULL\n", __func__); return -EINVAL; } + if (enable) { pm_runtime_get_sync(wsa_priv->dev); + if (bolero_check_core_votes(wsa_priv->dev)) + rc = 0; + else + rc = -ENOTSYNC; + } else { pm_runtime_put_autosuspend(wsa_priv->dev); pm_runtime_mark_last_busy(wsa_priv->dev); } - - if (bolero_check_core_votes(wsa_priv->dev)) - return 0; - else - return -EINVAL; + return rc; } static int wsa_swrm_clock(void *handle, bool enable) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 385e59fa4e14..4cdb3f500cfc 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -457,7 +457,7 @@ static int swrm_get_ssp_period(struct swr_mstr_ctrl *swrm, return ((swrm->bus_clk * 2) / ((row * col) * frame_sync)); } -static int swrm_core_vote_request(struct swr_mstr_ctrl *swrm) +static int swrm_core_vote_request(struct swr_mstr_ctrl *swrm, bool enable) { int ret = 0; @@ -470,7 +470,7 @@ static int swrm_core_vote_request(struct swr_mstr_ctrl *swrm) goto exit; } if (swrm->core_vote) { - ret = swrm->core_vote(swrm->handle, true); + ret = swrm->core_vote(swrm->handle, enable); if (ret) dev_err_ratelimited(swrm->dev, "%s: core vote request failed\n", __func__); @@ -501,8 +501,10 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) dev_err_ratelimited(swrm->dev, "%s: core vote request failed\n", __func__); + swrm->core_vote(swrm->handle, false); goto exit; } + ret = swrm->core_vote(swrm->handle, false); } } swrm->clk_ref_count++; @@ -538,6 +540,7 @@ static int swrm_ahb_write(struct swr_mstr_ctrl *swrm, { u32 temp = (u32)(*value); int ret = 0; + int vote_ret = 0; mutex_lock(&swrm->devlock); if (!swrm->dev_up) @@ -551,13 +554,20 @@ static int swrm_ahb_write(struct swr_mstr_ctrl *swrm, __func__); goto err; } - } else if (swrm_core_vote_request(swrm)) { - goto err; + } else { + vote_ret = swrm_core_vote_request(swrm, true); + if (vote_ret == -ENOTSYNC) + goto err_vote; + else if (vote_ret) + goto err; } iowrite32(temp, swrm->swrm_dig_base + reg); if (is_swr_clk_needed(swrm)) swrm_clk_request(swrm, FALSE); +err_vote: + if (!is_swr_clk_needed(swrm)) + swrm_core_vote_request(swrm, false); err: mutex_unlock(&swrm->devlock); return ret; @@ -568,6 +578,7 @@ static int swrm_ahb_read(struct swr_mstr_ctrl *swrm, { u32 temp = 0; int ret = 0; + int vote_ret = 0; mutex_lock(&swrm->devlock); if (!swrm->dev_up) @@ -580,14 +591,21 @@ static int swrm_ahb_read(struct swr_mstr_ctrl *swrm, __func__); goto err; } - } else if (swrm_core_vote_request(swrm)) { - goto err; + } else { + vote_ret = swrm_core_vote_request(swrm, true); + if (vote_ret == -ENOTSYNC) + goto err_vote; + else if (vote_ret) + goto err; } temp = ioread32(swrm->swrm_dig_base + reg); *value = temp; if (is_swr_clk_needed(swrm)) swrm_clk_request(swrm, FALSE); +err_vote: + if (!is_swr_clk_needed(swrm)) + swrm_core_vote_request(swrm, false); err: mutex_unlock(&swrm->devlock); return ret; @@ -2577,6 +2595,7 @@ static int swrm_probe(struct platform_device *pdev) int ret = 0; struct clk *lpass_core_hw_vote = NULL; struct clk *lpass_core_audio = NULL; + u32 swrm_hw_ver = 0; /* Allocate soundwire master driver structure */ swrm = devm_kzalloc(&pdev->dev, sizeof(struct swr_mstr_ctrl), @@ -2603,6 +2622,14 @@ static int swrm_probe(struct platform_device *pdev) ret = -EINVAL; goto err_pdata_fail; } + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,swr-master-version", + &swrm->version); + if (ret) { + dev_dbg(&pdev->dev, "%s: swrm version not defined, use default\n", + __func__); + swrm->version = SWRM_VERSION_1_6; + } ret = of_property_read_u32(pdev->dev.of_node, "qcom,swr_master_id", &swrm->master_id); if (ret) { @@ -2850,7 +2877,11 @@ static int swrm_probe(struct platform_device *pdev) swr_master_add_boarddevices(&swrm->master); mutex_lock(&swrm->mlock); swrm_clk_request(swrm, true); - swrm->version = swr_master_read(swrm, SWRM_COMP_HW_VERSION); + swrm_hw_ver = swr_master_read(swrm, SWRM_COMP_HW_VERSION); + if (swrm->version != swrm_hw_ver) + dev_info(&pdev->dev, + "%s: version specified in dtsi: 0x%x not match with HW read version 0x%x\n", + __func__, swrm->version, swrm_hw_ver); ret = swrm_master_init(swrm); if (ret < 0) { dev_err(&pdev->dev, -- GitLab From a29516b5faaaa52101d75df2da0097c68f2376f5 Mon Sep 17 00:00:00 2001 From: "Vangala, Amarnath" Date: Tue, 23 Jun 2020 13:40:04 +0530 Subject: [PATCH 1617/1645] dsp: Feedback path cfg to support 3rd party spkr protection algorithms. Backward compatibility change to set 'feedback path cfg' to AFE_MODULE_FEEDBACK, to support 3rd party spkr protection algorithms. Change-Id: I9af731902fbc5bc69f130a4f30d8fc5f18ceaace Signed-off-by: Vangala, Amarnath --- dsp/q6afe.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 7f594f29b2b7..5880ec935450 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -9644,30 +9644,28 @@ int afe_spk_prot_feed_back_cfg(int src_port, int dst_port, } this_afe.v4_ch_map_cfg.num_channels = index; this_afe.num_spkrs = index / 2; - pr_debug("%s no of channels: %d\n", __func__, index); - this_afe.vi_tx_port = src_port; - this_afe.vi_rx_port = dst_port; - ret = 0; - } else { - memset(&prot_config, 0, sizeof(prot_config)); - prot_config.feedback_path_cfg.dst_portid = + } + + index = 0; + memset(&prot_config, 0, sizeof(prot_config)); + prot_config.feedback_path_cfg.dst_portid = q6audio_get_port_id(dst_port); - if (l_ch) { - prot_config.feedback_path_cfg.chan_info[index++] = 1; - prot_config.feedback_path_cfg.chan_info[index++] = 2; - } - if (r_ch) { - prot_config.feedback_path_cfg.chan_info[index++] = 3; - prot_config.feedback_path_cfg.chan_info[index++] = 4; - } - prot_config.feedback_path_cfg.num_channels = index; - pr_debug("%s no of channels: %d\n", __func__, index); - prot_config.feedback_path_cfg.minor_version = 1; - ret = afe_spk_prot_prepare(src_port, dst_port, - AFE_PARAM_ID_FEEDBACK_PATH_CFG, &prot_config, - sizeof(union afe_spkr_prot_config)); + if (l_ch) { + prot_config.feedback_path_cfg.chan_info[index++] = 1; + prot_config.feedback_path_cfg.chan_info[index++] = 2; + } + if (r_ch) { + prot_config.feedback_path_cfg.chan_info[index++] = 3; + prot_config.feedback_path_cfg.chan_info[index++] = 4; } + prot_config.feedback_path_cfg.num_channels = index; + pr_debug("%s no of channels: %d\n", __func__, index); + prot_config.feedback_path_cfg.minor_version = 1; + ret = afe_spk_prot_prepare(src_port, dst_port, + AFE_PARAM_ID_FEEDBACK_PATH_CFG, &prot_config, + sizeof(union afe_spkr_prot_config)); + fail_cmd: return ret; } -- GitLab From 3840e289c3650efa91a824ffd300ce0a99e62b56 Mon Sep 17 00:00:00 2001 From: Shashi Kant Maurya Date: Thu, 25 Mar 2021 14:38:29 +0530 Subject: [PATCH 1618/1645] asoc: codecs: retry for soundwire slave enumeration Retry for soundwire slave enumeration during bootup before EPROBE_DEFER to avoid soundcard enumeration failures. Change-Id: I083ec76fc84a2b367f93a2dc166a1419a75ff8b4 Signed-off-by: Shashi Kant Maurya --- asoc/codecs/wcd938x/wcd938x-slave.c | 13 +++++++++++-- asoc/codecs/wcd938x/wcd938x.c | 15 +++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/asoc/codecs/wcd938x/wcd938x-slave.c b/asoc/codecs/wcd938x/wcd938x-slave.c index 1f83b4ce1da5..13f159c0f43a 100644 --- a/asoc/codecs/wcd938x/wcd938x-slave.c +++ b/asoc/codecs/wcd938x/wcd938x-slave.c @@ -1,9 +1,10 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ #include +#include #include #include #include @@ -24,6 +25,7 @@ #define SWR_SLV_MAX_DEVICES 2 #endif /* CONFIG_DEBUG_FS */ +#define SWR_MAX_RETRY 5 struct wcd938x_slave_priv { struct swr_device *swr_slave; #ifdef CONFIG_DEBUG_FS @@ -278,17 +280,24 @@ static int wcd938x_slave_bind(struct device *dev, int ret = 0; uint8_t devnum = 0; struct swr_device *pdev = to_swr_device(dev); + int retry = SWR_MAX_RETRY; if (!pdev) { pr_err("%s: invalid swr device handle\n", __func__); return -EINVAL; } - ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum); + do { + /* Add delay for soundwire enumeration */ + usleep_range(100, 110); + ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum); + } while (ret && --retry); + if (ret) { dev_dbg(&pdev->dev, "%s get devnum %d for dev addr %llx failed\n", __func__, devnum, pdev->addr); + ret = -EPROBE_DEFER; return ret; } pdev->dev_num = devnum; diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 9207bbd20319..0b46a7e2157a 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ #include @@ -1976,15 +1976,14 @@ static int wcd938x_get_logical_addr(struct swr_device *swr_dev) int num_retry = NUM_ATTEMPTS; do { + /* retry after 1ms */ + usleep_range(1000, 1010); ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum); - if (ret) { - dev_err(&swr_dev->dev, - "%s get devnum %d for dev addr %llx failed\n", - __func__, devnum, swr_dev->addr); - /* retry after 1ms */ - usleep_range(1000, 1010); - } } while (ret && --num_retry); + if (ret) + dev_err(&swr_dev->dev, + "%s get devnum %d for dev addr %llx failed\n", + __func__, devnum, swr_dev->addr); swr_dev->dev_num = devnum; return 0; } -- GitLab From 322dbdb9c35bf9652406f16962e10eb595905239 Mon Sep 17 00:00:00 2001 From: Kunlei Zhang Date: Tue, 11 May 2021 14:56:29 +0800 Subject: [PATCH 1619/1645] dsp: fix out of bound access for cal_data size Add change to fix cal_data index out of bounds error. Change-Id: I8c8e62835e496c0f35fdc09757f4206c52020727 Signed-off-by: Kunlei Zhang --- dsp/q6afe.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 5880ec935450..c1e89ff8733b 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -10187,8 +10187,7 @@ static int afe_get_cal_spv4_ex_vi_ftm_param(int32_t cal_type, size_t data_size, pr_debug("%s: cal_type = %d\n", __func__, cal_type); if (this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL] == NULL || cal_data == NULL || - data_size > sizeof(*cal_data) || - data_size < sizeof(cal_data->cal_hdr)) + data_size != sizeof(*cal_data)) goto done; mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_V4_EX_VI_CAL]->lock); @@ -10255,8 +10254,7 @@ static int afe_get_cal_sp_ex_vi_ftm_param(int32_t cal_type, size_t data_size, pr_debug("%s: cal_type = %d\n", __func__, cal_type); if (this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL] == NULL || cal_data == NULL || - data_size > sizeof(*cal_data) || - data_size < sizeof(cal_data->cal_hdr)) + data_size != sizeof(*cal_data)) goto done; mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_EX_VI_CAL]->lock); -- GitLab From 9ff217d735f150dad03da7d25cb3ac0241b6dd2b Mon Sep 17 00:00:00 2001 From: Kunlei Zhang Date: Thu, 20 May 2021 16:02:30 +0800 Subject: [PATCH 1620/1645] dsp: update size check for set/get VI param function In afe_set_cal_sp_th_vi_cfg and afe_get_cal_sp_th_vi_param functions, data size is not checked properly which might lead to out of bounds access. Add data_size check to avoid out of bounds access. Change-Id: Ibe049300c609d0d717309bccc65cac876ac075f7 Signed-off-by: Kunlei Zhang --- dsp/q6afe.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 5880ec935450..85681e34a1f3 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -9941,6 +9941,9 @@ static int afe_set_cal_sp_th_vi_cfg(int32_t cal_type, size_t data_size, if (cal_data == NULL || data_size > sizeof(*cal_data) || + (data_size < sizeof(cal_data->cal_hdr) + + sizeof(cal_data->cal_data) + + sizeof(cal_data->cal_info.mode)) || this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL) goto done; @@ -10158,7 +10161,9 @@ static int afe_get_cal_sp_th_vi_param(int32_t cal_type, size_t data_size, if (cal_data == NULL || data_size > sizeof(*cal_data) || - data_size < sizeof(cal_data->cal_hdr) || + (data_size < sizeof(cal_data->cal_hdr) + + sizeof(cal_data->cal_data) + + sizeof(cal_data->cal_info.mode)) || this_afe.cal_data[AFE_FB_SPKR_PROT_TH_VI_CAL] == NULL) return 0; -- GitLab From 5b809d70594a1ce3ec5a15ad0401216e8d596fa1 Mon Sep 17 00:00:00 2001 From: Lakshman Chaluvaraju Date: Tue, 8 Jun 2021 10:43:20 +0530 Subject: [PATCH 1621/1645] Asoc: check for invalid voice session id Add check to return if session id is invalid. Change-Id: Ida0e07b78657102a3bf6e73a1ca23c44ad112426 Signed-off-by: Lakshman Chaluvaraju --- asoc/msm-pcm-routing-v2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 99e93c3995b2..b52e5d707ced 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -2374,6 +2374,11 @@ static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set) session_id = msm_pcm_routing_get_voc_sessionid(val); + if (!session_id) { + pr_err("%s: Invalid session_id %x\n", __func__, session_id); + return; + } + pr_debug("%s: FE DAI 0x%x session_id 0x%x\n", __func__, val, session_id); -- GitLab From 61eab15caa87ae09b5cf63846e6505aeaec7da21 Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Tue, 19 Oct 2021 14:17:05 +0530 Subject: [PATCH 1622/1645] ASoC: wcd937x: Update EAR PA CnP FSM sequence EAR PA short switch is not released after PA is turned on and off. Address this hardware issue by updating the EAR PA CnP FSM while EAR power down sequence. Change-Id: If4269c30c13572db1b252f223368d444b9250901 Signed-off-by: Soumya Managoli --- asoc/codecs/wcd937x/wcd937x.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c index f181cdd6da0b..428c98143356 100644 --- a/asoc/codecs/wcd937x/wcd937x.c +++ b/asoc/codecs/wcd937x/wcd937x.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ #include @@ -987,6 +987,22 @@ static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, WCD937X_DIGITAL_PDM_WD_CTL0, 0x17, 0x00); + usleep_range(10000, 10010); + /* disable EAR CnP FSM */ + snd_soc_component_update_bits(component, + WCD937X_EAR_EAR_EN_REG, + 0x02, 0x00); + /* toggle EAR PA to let PA control registers take effect */ + snd_soc_component_update_bits(component, + WCD937X_ANA_EAR, + 0x80, 0x80); + snd_soc_component_update_bits(component, + WCD937X_ANA_EAR, + 0x80, 0x00); + /* enable EAR CnP FSM */ + snd_soc_component_update_bits(component, + WCD937X_EAR_EAR_EN_REG, + 0x02, 0x02); break; }; return ret; -- GitLab From ad59b31b3cd15d9e2e07eadbdeaf63008792c57e Mon Sep 17 00:00:00 2001 From: Lakshman Chaluvaraju Date: Thu, 20 Jan 2022 17:28:46 +0530 Subject: [PATCH 1623/1645] asoc: changes to fix KW errors Add changes to fix KW errors. Change-Id: I87fc8bf5b2753cef6af881713637e9521389708d Signed-off-by: Lakshman Chaluvaraju --- asoc/msm-pcm-routing-v2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index b52e5d707ced..868e254c97a0 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1665,6 +1666,11 @@ static int msm_pcm_routing_channel_mixer_v2(int fe_id, bool perf_mode, } be_id = channel_mixer_v2[fe_id][sess_type].port_idx - 1; + if (be_id < 0 || be_id >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: Received out of bounds be_id %d\n", + __func__, be_id); + return -EINVAL; + } channel_mixer_v2[fe_id][sess_type].input_channels[0] = channel_mixer_v2[fe_id][sess_type].input_channel; -- GitLab From 63d88516fa6d5074713c412368f6baf3a11b05ae Mon Sep 17 00:00:00 2001 From: Lakshman Chaluvaraju Date: Thu, 20 Jan 2022 17:28:46 +0530 Subject: [PATCH 1624/1645] asoc: changes to fix KW errors Add changes to fix KW errors. Change-Id: I87fc8bf5b2753cef6af881713637e9521389708d Signed-off-by: Lakshman Chaluvaraju --- asoc/msm-pcm-routing-v2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index b52e5d707ced..868e254c97a0 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1665,6 +1666,11 @@ static int msm_pcm_routing_channel_mixer_v2(int fe_id, bool perf_mode, } be_id = channel_mixer_v2[fe_id][sess_type].port_idx - 1; + if (be_id < 0 || be_id >= MSM_BACKEND_DAI_MAX) { + pr_err("%s: Received out of bounds be_id %d\n", + __func__, be_id); + return -EINVAL; + } channel_mixer_v2[fe_id][sess_type].input_channels[0] = channel_mixer_v2[fe_id][sess_type].input_channel; -- GitLab From 1a1cd6c6857586cfc4227f92cc88ba0405524737 Mon Sep 17 00:00:00 2001 From: lintaopei Date: Fri, 11 Dec 2020 11:13:13 +0800 Subject: [PATCH 1625/1645] [1 of 1][10277819]n10 Sound card bring up ###%%%comment:[1 of 1]n10 Sound card bring up ###%%%bug number:10277819 ###%%%product name:n10 ###%%%root cause:Design ###%%%Bug category:T2M ###%%%regression response:--- ###%%%regression comments: ###%%%Module_Impact:Audio ###%%%Test_Suggestion:. ###%%%Solution:n10 Sound card bring up ###%%%Test_Report:. ###%%%VAL Can Test:Yes Change-Id: I7bd371cad1402ed4fa26ccdfdef18c1907df57da --- asoc/kona.c | 5 +++++ config/litoauto.conf | 2 +- config/litoautoconf.h | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index f5d0ea8ee502..c8874a69f015 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -6977,8 +6977,13 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .stream_name = "Quinary MI2S Playback", .cpu_dai_name = "msm-dai-q6-mi2s.4", .platform_name = "msm-pcm-routing", +#ifdef CONFIG_SND_SMARTPA_AW881XX + .codec_name = "aw881xx_smartpa", + .codec_dai_name = "aw881xx-aif", +#else .codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-rx", +#endif .no_pcm = 1, .dpcm_playback = 1, .id = MSM_BACKEND_DAI_QUINARY_MI2S_RX, diff --git a/config/litoauto.conf b/config/litoauto.conf index ecf848cfa28c..cea7bdca53b3 100644 --- a/config/litoauto.conf +++ b/config/litoauto.conf @@ -38,6 +38,6 @@ CONFIG_SND_SOC_WCD937X=m CONFIG_SND_SOC_WCD937X_SLAVE=m CONFIG_SND_SOC_LITO=m CONFIG_SND_EVENT=m -CONFIG_MI2S_DISABLE=m +#CONFIG_MI2S_DISABLE=m CONFIG_TDM_DISABLE=m CONFIG_AUXPCM_DISABLE=m diff --git a/config/litoautoconf.h b/config/litoautoconf.h index 3c979ccbc805..bb85362268ad 100644 --- a/config/litoautoconf.h +++ b/config/litoautoconf.h @@ -42,6 +42,6 @@ #define CONFIG_SND_SOC_WCD937X_SLAVE 1 #define CONFIG_SND_SOC_LITO 1 #define CONFIG_SND_EVENT 1 -#define CONFIG_MI2S_DISABLE 1 +//#define CONFIG_MI2S_DISABLE 1 #define CONFIG_TDM_DISABLE 1 #define CONFIG_AUXPCM_DISABLE 1 -- GitLab From 3128cf578a2f78ab09bab9b9161e7a026010373d Mon Sep 17 00:00:00 2001 From: lintaopei Date: Tue, 16 Mar 2021 19:35:42 +0800 Subject: [PATCH 1626/1645] [ALM:10872983][FP4-99][Audio]code update --- asoc/bengal.c | 179 ++++++++++++++++++++++++++++++++++++++- asoc/kona.c | 168 ++++++++++++++++++++++++++++++++++++- dsp/q6afe.c | 228 +++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 565 insertions(+), 10 deletions(-) diff --git a/asoc/bengal.c b/asoc/bengal.c index 15c2104922b2..0ecc1910b68d 100644 --- a/asoc/bengal.c +++ b/asoc/bengal.c @@ -161,6 +161,9 @@ struct msm_asoc_mach_data { bool is_afe_config_done; struct device_node *fsa_handle; bool va_disable; +#ifdef CONFIG_T2M_SND_FP4 + struct device_node *hac_pa_gpio_p; +#endif }; struct tdm_port { @@ -586,6 +589,35 @@ static struct wcd_mbhc_config wcd_mbhc_cfg = { .moisture_duty_cycle_en = true, }; +#ifdef CONFIG_T2M_SND_FP4 +static int msm_enable_hac_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event); + +static const struct snd_kcontrol_new hac_pa_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_soc_dapm_widget msm_hac_dapm_widgets[] = { + SND_SOC_DAPM_MIXER("HAC_PA", SND_SOC_NOPM, 0, 0, + hac_pa_switch, ARRAY_SIZE(hac_pa_switch)), + SND_SOC_DAPM_PGA_E("HAC PGA", SND_SOC_NOPM, 0, 0, NULL, 0, + msm_enable_hac_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + + SND_SOC_DAPM_INPUT("HAC_RX"), + SND_SOC_DAPM_OUTPUT("HAC"), +}; + +static const struct snd_soc_dapm_route msm_hac_audio_map[] = { + {"HAC_PA", "Switch", "HAC_RX"}, + {"HAC PGA", NULL, "HAC_PA"}, + {"HAC", NULL, "HAC PGA"}, +}; +#endif + static inline int param_is_mask(int p) { return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && @@ -4199,6 +4231,43 @@ static int msm_dmic_event(struct snd_soc_dapm_widget *w, return 0; } +#ifdef CONFIG_T2M_SND_FP4 +static int msm_enable_hac_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct msm_asoc_mach_data *pdata = NULL; + int ret = 0; + + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, + w->name, event); + + pdata = snd_soc_card_get_drvdata(component->card); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + ret = msm_cdc_pinctrl_select_active_state( + pdata->hac_pa_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be de-activated %s\n", + __func__, "hac_pa"); + } + break; + case SND_SOC_DAPM_PRE_PMD: + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->hac_pa_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be de-activated %s\n", + __func__, "hac_pa"); + } + break; + }; + return ret; +} +#endif + static const struct snd_soc_dapm_widget msm_int_dapm_widgets[] = { SND_SOC_DAPM_MIC("Analog Mic1", NULL), SND_SOC_DAPM_MIC("Analog Mic2", NULL), @@ -4303,6 +4372,16 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets, ARRAY_SIZE(msm_int_dapm_widgets)); +#ifdef CONFIG_T2M_SND_FP4 + snd_soc_dapm_new_controls(dapm, msm_hac_dapm_widgets, + ARRAY_SIZE(msm_hac_dapm_widgets)); + + snd_soc_dapm_add_routes(dapm, msm_hac_audio_map, + ARRAY_SIZE(msm_hac_audio_map)); + + snd_soc_dapm_ignore_suspend(dapm, "HAC"); +#endif + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); @@ -4423,7 +4502,20 @@ static void *def_rouleur_mbhc_cal(void) return wcd_mbhc_cal; } - +#ifdef CONFIG_T2M_SND_FP4 +struct snd_soc_dai_link_component awinic_codecs[] = { + { + .of_node = NULL, + .dai_name = "aw881xx-aif-0-34", + .name = "aw881xx_smartpa.0-0034", + }, + { + .of_node = NULL, + .dai_name = "aw881xx-aif-0-36", + .name = "aw881xx_smartpa.0-0036", + }, +}; +#endif /* Digital audio interface glue - connects codec <---> CPU */ static struct snd_soc_dai_link msm_common_dai_links[] = { /* FrontEnd DAI Links */ @@ -5053,6 +5145,38 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ops = &msm_cdc_dma_be_ops, }, +/*#if defined(CONFIG_T2M_SND_FP4) + { + .name = "Quinary MI2S RX_Hostless", + .stream_name = "Quinary MI2S_RX Hostless Playback", + .cpu_dai_name = "QUIN_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Quinary MI2S TX_Hostless", + .stream_name = "Quinary MI2S_TX Hostless Capture", + .cpu_dai_name = "QUIN_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +#endif*/ }; static struct snd_soc_dai_link msm_common_be_dai_links[] = { @@ -5370,7 +5494,20 @@ static struct snd_soc_dai_link msm_wcn_btfm_be_dai_links[] = { .ignore_suspend = 1, }, }; - +#if defined(CONFIG_T2M_SND_FP4) +struct snd_soc_dai_link_component awinic_codecs[] = { + { + .of_node = NULL, + .dai_name = "aw882xx-aif-l", + .name = "aw882xx_smartpa_l", + }, + { + .of_node = NULL, + .dai_name = "aw882xx-aif-r", + .name = "aw882xx_smartpa_r", + }, +}; +#endif static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { { .name = LPASS_BE_PRI_MI2S_RX, @@ -6676,6 +6813,37 @@ static int msm_audio_ssr_register(struct device *dev) return ret; } +#ifdef CONFIG_T2M_SND_FP4 +int is_hac_pa_gpio_support(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata) +{ + const char *hac_pa_gpio = "qcom,msm-hac-pa-gpios"; + int ret = 0; + + pr_debug("%s:Enter\n", __func__); + + pdata->hac_pa_gpio_p= of_parse_phandle(pdev->dev.of_node, + hac_pa_gpio, 0); + if (!pdata->hac_pa_gpio_p) { + dev_dbg(&pdev->dev, "property %s not detected in node %s", + hac_pa_gpio, pdev->dev.of_node->full_name); + } else { + dev_dbg(&pdev->dev, "%s detected", + hac_pa_gpio); + if (pdata->hac_pa_gpio_p) { + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->hac_pa_gpio_p); + if (ret) { + pr_err("%s: gpio set cannot be de-activated %s\n", + __func__, "hac_pa"); + } + } + } + + return 0; +} +#endif + static int msm_asoc_machine_probe(struct platform_device *pdev) { struct snd_soc_card *card = NULL; @@ -6801,7 +6969,12 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) "qcom,us-euro-gpios"); wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; } - +#ifdef CONFIG_T2M_SND_FP4 + ret = is_hac_pa_gpio_support(pdev, pdata); + if (ret < 0) + pr_err("%s: doesn't support hac pa gpio\n", + __func__); +#endif if (wcd_mbhc_cfg.enable_usbc_analog) wcd_mbhc_cfg.swap_gnd_mic = msm_usbc_swap_gnd_mic; diff --git a/asoc/kona.c b/asoc/kona.c index c8874a69f015..fa514b08a566 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -201,6 +201,9 @@ struct msm_asoc_mach_data { u32 tdm_max_slots; /* Max TDM slots used */ int (*get_wsa_dev_num)(struct snd_soc_component*); struct afe_cps_hw_intf_cfg cps_config; +#ifdef CONFIG_T2M_SND_FP4 + struct device_node *hac_pa_gpio_p; +#endif }; struct tdm_port { @@ -935,6 +938,35 @@ static struct wcd_mbhc_config wcd_mbhc_cfg = { .moisture_duty_cycle_en = true, }; +#ifdef CONFIG_T2M_SND_FP4 +static int msm_enable_hac_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event); + +static const struct snd_kcontrol_new hac_pa_switch[] = { + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) +}; + +static const struct snd_soc_dapm_widget msm_hac_dapm_widgets[] = { + SND_SOC_DAPM_MIXER("HAC_PA", SND_SOC_NOPM, 0, 0, + hac_pa_switch, ARRAY_SIZE(hac_pa_switch)), + SND_SOC_DAPM_PGA_E("HAC PGA", SND_SOC_NOPM, 0, 0, NULL, 0, + msm_enable_hac_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + + SND_SOC_DAPM_INPUT("HAC_RX"), + SND_SOC_DAPM_OUTPUT("HAC"), +}; + +static const struct snd_soc_dapm_route msm_hac_audio_map[] = { + {"HAC_PA", "Switch", "HAC_RX"}, + {"HAC PGA", NULL, "HAC_PA"}, + {"HAC", NULL, "HAC PGA"}, +}; +#endif + static inline int param_is_mask(int p) { return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && @@ -5503,6 +5535,43 @@ static int msm_dmic_event(struct snd_soc_dapm_widget *w, return 0; } +#ifdef CONFIG_T2M_SND_FP4 +static int msm_enable_hac_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = + snd_soc_dapm_to_component(w->dapm); + struct msm_asoc_mach_data *pdata = NULL; + int ret = 0; + + dev_dbg(component->dev, "HAC %s wname: %s event: %d\n", __func__, + w->name, event); + + pdata = snd_soc_card_get_drvdata(component->card); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + ret = msm_cdc_pinctrl_select_active_state( + pdata->hac_pa_gpio_p); + if (ret) { + pr_err("%s:HAC gpio set cannot be de-activated %s\n", + __func__, "hac_pa"); + } + break; + case SND_SOC_DAPM_PRE_PMD: + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->hac_pa_gpio_p); + if (ret) { + pr_err("%s:HAC gpio set cannot be de-activated %s\n", + __func__, "hac_pa"); + } + break; + }; + return ret; +} +#endif + static const struct snd_soc_dapm_widget msm_int_dapm_widgets[] = { SND_SOC_DAPM_MIC("Analog Mic1", NULL), SND_SOC_DAPM_MIC("Analog Mic2", NULL), @@ -5624,6 +5693,16 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets, ARRAY_SIZE(msm_int_dapm_widgets)); +#ifdef CONFIG_T2M_SND_FP4 + snd_soc_dapm_new_controls(dapm, msm_hac_dapm_widgets, + ARRAY_SIZE(msm_hac_dapm_widgets)); + + snd_soc_dapm_add_routes(dapm, msm_hac_audio_map, + ARRAY_SIZE(msm_hac_audio_map)); + + snd_soc_dapm_ignore_suspend(dapm, "HAC"); +#endif + snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2"); @@ -6407,6 +6486,38 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ops = &msm_cdc_dma_be_ops, }, +/*#if defined(CONFIG_SND_SMARTPA_AW882XX) + { + .name = "Quinary MI2S RX_Hostless", + .stream_name = "Quinary MI2S_RX Hostless Playback", + .cpu_dai_name = "QUIN_MI2S_RX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_playback = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, + { + .name = "Quinary MI2S TX_Hostless", + .stream_name = "Quinary MI2S_TX Hostless Capture", + .cpu_dai_name = "QUIN_MI2S_TX_HOSTLESS", + .platform_name = "msm-pcm-hostless", + .dynamic = 1, + .dpcm_capture = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + }, +#endif*/ }; static struct snd_soc_dai_link msm_common_be_dai_links[] = { @@ -6855,6 +6966,21 @@ static struct snd_soc_dai_link ext_disp_be_dai_link[] = { }, }; +#if defined(CONFIG_SND_SMARTPA_AW882XX) +struct snd_soc_dai_link_component awinic_codecs[] = { + { + .of_node = NULL, + .dai_name = "aw882xx-aif-l", + .name = "aw882xx_smartpa_l", + }, + { + .of_node = NULL, + .dai_name = "aw882xx-aif-r", + .name = "aw882xx_smartpa_r", + }, +}; +#endif + static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { { .name = LPASS_BE_PRI_MI2S_RX, @@ -6977,9 +7103,9 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .stream_name = "Quinary MI2S Playback", .cpu_dai_name = "msm-dai-q6-mi2s.4", .platform_name = "msm-pcm-routing", -#ifdef CONFIG_SND_SMARTPA_AW881XX - .codec_name = "aw881xx_smartpa", - .codec_dai_name = "aw881xx-aif", +#ifdef CONFIG_SND_SMARTPA_AW882XX + .num_codecs = ARRAY_SIZE(awinic_codecs), + .codecs = awinic_codecs, #else .codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-rx", @@ -8372,6 +8498,35 @@ static int msm_audio_ssr_register(struct device *dev) return ret; } +#ifdef CONFIG_T2M_SND_FP4 +int is_hac_pa_gpio_support(struct platform_device *pdev, + struct msm_asoc_mach_data *pdata) +{ + const char *hac_pa_gpio = "qcom,msm-hac-pa-gpios";//plt defined in dtsi &lagoon_snd "lito-lagoon-fp4-snd-card" + int ret = 0; + + pr_debug("%s:HAC Enter\n", __func__); + + pdata->hac_pa_gpio_p= of_parse_phandle(pdev->dev.of_node, hac_pa_gpio, 0); + if (!pdata->hac_pa_gpio_p) { + dev_dbg(&pdev->dev, "HAC property %s not detected in node %s", + hac_pa_gpio, pdev->dev.of_node->full_name); + } else { + dev_dbg(&pdev->dev, "%s detected", hac_pa_gpio); + if (pdata->hac_pa_gpio_p) { + ret = msm_cdc_pinctrl_select_sleep_state( + pdata->hac_pa_gpio_p); + if (ret) { + pr_err("%s:HAC gpio set cannot be de-activated %s\n", + __func__, "hac_pa"); + } + } + } + + return 0; +} +#endif + static void parse_cps_configuration(struct platform_device *pdev, struct msm_asoc_mach_data *pdata) { @@ -8628,7 +8783,12 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) "qcom,us-euro-gpios"); wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic; } - +#ifdef CONFIG_T2M_SND_FP4 + ret = is_hac_pa_gpio_support(pdev, pdata); + if (ret < 0) + pr_err("%s:HAC doesn't support hac pa gpio\n", + __func__); +#endif if (wcd_mbhc_cfg.enable_usbc_analog) wcd_mbhc_cfg.swap_gnd_mic = msm_usbc_swap_gnd_mic; diff --git a/dsp/q6afe.c b/dsp/q6afe.c index c69a024db6c5..a61de34a607b 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -43,6 +43,16 @@ enum { static struct afe_avcs_payload_port_mapping *pm[MAX_ALLOWED_USE_CASES]; +#ifdef CONFIG_SND_SMARTPA_AW882XX +#include +#define AFE_MODULE_ID_AWDSP_TX (0x10013D00) +#define AFE_MODULE_ID_AWDSP_RX (0x10013D01) +#define AFE_PARAM_ID_AWDSP_RX_SET_ENABLE (0x10013D11) +#define AFE_PARAM_ID_AWDSP_TX_SET_ENABLE (0x10013D13) +#define AFE_PARAM_ID_AWDSP_RX_PARAMS (0x10013D12) +#define AFE_PORT_ID_AWDSP_RX (AFE_PORT_ID_QUINARY_MI2S_RX) +#define AFE_PORT_ID_AWDSP_TX (AFE_PORT_ID_QUINARY_MI2S_TX) +#endif /* #ifdef CONFIG_SND_SMARTPA_AW882XX */ enum { AFE_COMMON_RX_CAL = 0, AFE_COMMON_TX_CAL, @@ -251,6 +261,12 @@ struct afe_ctl { uint32_t cps_ch_mask; struct afe_cps_hw_intf_cfg *cps_config; int lsm_afe_ports[MAX_LSM_SESSIONS]; + +#ifdef CONFIG_SND_SMARTPA_AW882XX + struct rtac_cal_block_data aw_cal; + atomic_t aw_state; +#endif /*CONFIG_SND_SMARTPA_AW882XX*/ + }; struct afe_clkinfo_per_port { @@ -920,7 +936,19 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) payload, data->token); return -EINVAL; } - +#ifdef CONFIG_SND_SMARTPA_AW882XX + if (atomic_read(&this_afe.aw_state) == 1) { + if (!payload[0]) { + atomic_set(&this_afe.state, 0); + } else { + pr_debug("%s: status: %d", __func__, payload[0]); + atomic_set(&this_afe.state, -1); + } + atomic_set(&this_afe.aw_state, 0); + wake_up(&this_afe.wait[data->token]); + return 0; + } +#endif /*CONFIG_SND_SMARTPA_AW882XX*/ if (rtac_make_afe_callback(data->payload, data->payload_size)) return 0; @@ -2302,6 +2330,15 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, case AFE_PARAM_ID_SP_V4_EX_VI_FTM_CFG: param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI; break; +#ifdef CONFIG_SND_SMARTPA_AW882XX + case AFE_PARAM_ID_AWDSP_RX_SET_ENABLE: + case AFE_PARAM_ID_AWDSP_RX_PARAMS: + param_info.module_id = AFE_MODULE_ID_AWDSP_RX; + break; + case AFE_PARAM_ID_AWDSP_TX_SET_ENABLE: + param_info.module_id = AFE_MODULE_ID_AWDSP_TX; + break; +#endif /*CONFIG_SND_SMARTPA_AW882XX*/ default: pr_err("%s: default case 0x%x\n", __func__, param_id); goto fail_cmd; @@ -3530,6 +3567,177 @@ static int afe_send_codec_reg_config( return ret; } +#ifdef CONFIG_SND_SMARTPA_AW882XX +int aw_send_afe_rx_module_enable(void *buf, int size) +{ + union afe_spkr_prot_config config; + int32_t port_id = AFE_PORT_ID_AWDSP_RX; + + if (size > sizeof(config)) + return -EINVAL; + + memcpy(&config, buf, size); + + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_AWDSP_RX_SET_ENABLE, &config,sizeof(union afe_spkr_prot_config))) { + pr_err("%s: set bypass failed \n", __func__); + return -EINVAL; + } + return 0; +} +EXPORT_SYMBOL(aw_send_afe_rx_module_enable); +int aw_send_afe_tx_module_enable(void *buf, int size) +{ + union afe_spkr_prot_config config; + int32_t port_id = AFE_PORT_ID_AWDSP_TX; + + if (size > sizeof(config)) + return -EINVAL; + + memcpy(&config, buf, size); + + if (afe_spk_prot_prepare(port_id, 0, + AFE_PARAM_ID_AWDSP_TX_SET_ENABLE, &config,sizeof(union afe_spkr_prot_config))) { + pr_err("%s: set bypass failed \n", __func__); + return -EINVAL; + } + return 0; +} +EXPORT_SYMBOL(aw_send_afe_tx_module_enable); + +int aw_send_afe_cal_apr(uint32_t param_id, void *buf, int cmd_size, bool write) +{ + int32_t result = 0, port_id = AFE_PORT_ID_AWDSP_RX; + int32_t module_id = AFE_MODULE_ID_AWDSP_RX; + uint32_t port_index = 0; + uint32_t payload_size = 0; + size_t len; + struct rtac_cal_block_data *aw_cal = &(this_afe.aw_cal); + struct mem_mapping_hdr mem_hdr; + struct param_hdr_v3 param_hdr; + + pr_debug("%s: enter\n", __func__); + + if (param_id == AFE_PARAM_ID_AWDSP_TX_SET_ENABLE) { + port_id = AFE_PORT_ID_AWDSP_TX; + module_id = AFE_MODULE_ID_AWDSP_TX; + } + + if (aw_cal->map_data.dma_buf == 0) { + /*Minimal chunk size is 4K*/ + aw_cal->map_data.map_size = SZ_4K; + result = msm_audio_ion_alloc(&(aw_cal->map_data.dma_buf), + aw_cal->map_data.map_size, + &(aw_cal->cal_data.paddr),&len, + &(aw_cal->cal_data.kvaddr)); + if (result < 0) { + pr_err("%s: allocate buffer failed! ret = %d\n", + __func__, result); + goto err; + } + } + + if (aw_cal->map_data.map_handle == 0) { + result = afe_map_rtac_block(aw_cal); + if (result < 0) { + pr_err("%s: map buffer failed! ret = %d\n", + __func__, result); + goto err; + } + } + + port_index = q6audio_get_port_index(port_id); + if (port_index >= AFE_MAX_PORTS) { + pr_err("%s: Invalid AFE port = 0x%x\n", __func__, port_id); + goto err; + } + + if (cmd_size > (SZ_4K - sizeof(struct param_hdr_v3))) { + pr_err("%s: Invalid payload size = %d\n", __func__, cmd_size); + result = -EINVAL; + goto err; + } + + /* Pack message header with data */ + param_hdr.module_id = module_id; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_size = cmd_size; + + if (write) { + param_hdr.param_id = param_id; + q6common_pack_pp_params(aw_cal->cal_data.kvaddr, + ¶m_hdr, + buf, + &payload_size); + aw_cal->cal_data.size = payload_size; + } else { + param_hdr.param_id = param_id; + aw_cal->cal_data.size = cmd_size + sizeof(struct param_hdr_v3); + } + + /*Send/Get package to/from ADSP*/ + mem_hdr.data_payload_addr_lsw = + lower_32_bits(aw_cal->cal_data.paddr); + mem_hdr.data_payload_addr_msw = + msm_audio_populate_upper_32_bits(aw_cal->cal_data.paddr); + mem_hdr.mem_map_handle = + aw_cal->map_data.map_handle; + + pr_debug("%s: Sending aw_cal port = 0x%x, cal size = %zd, cal addr = 0x%pK\n", + __func__, port_id, aw_cal->cal_data.size, &aw_cal->cal_data.paddr); + + result = afe_q6_interface_prepare(); + if (result != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, result); + goto err; + } + + if (write) { + if (q6common_is_instance_id_supported()) + result = q6afe_set_params_v3(port_id, port_index, &mem_hdr, NULL, payload_size); + else + result = q6afe_set_params_v2(port_id, port_index, &mem_hdr, NULL, payload_size); + } else { + int8_t *resp = (int8_t *)aw_cal->cal_data.kvaddr; + + atomic_set(&this_afe.aw_state, 1); + if (q6common_is_instance_id_supported()) { + result = q6afe_get_params_v3(port_id, port_index, &mem_hdr, ¶m_hdr); + resp += sizeof(struct param_hdr_v3); + } else { + result = q6afe_get_params_v2(port_id, port_index, &mem_hdr, ¶m_hdr); + resp += sizeof(struct param_hdr_v1); + } + + if (result) { + pr_err("%s: get response from port 0x%x failed %d\n", + __func__, port_id, result); + goto err; + } + else { + /*Copy response data to command buffer*/ + memcpy(buf, resp, cmd_size); + } + } +err: + return result; +} +EXPORT_SYMBOL(aw_send_afe_cal_apr); +void aw_cal_unmap_memory(void) +{ + int result = 0; + + if (this_afe.aw_cal.map_data.map_handle) { + result = afe_unmap_rtac_block(&this_afe.aw_cal.map_data.map_handle); + + /*Force to remap after unmap failed*/ + if (result) + this_afe.aw_cal.map_data.map_handle = 0; + } +} +EXPORT_SYMBOL(aw_cal_unmap_memory); +#endif + static int afe_init_cdc_reg_config(void) { struct param_hdr_v3 param_hdr; @@ -10648,7 +10856,15 @@ static void afe_release_uevent_data(struct kobject *kobj) kfree(data); } - +#ifdef CONFIG_SND_SMARTPA_AW882XX +struct aw_afe_func aw_func= { + .afe_get_topology = afe_get_topology, + .aw_send_afe_cal_apr = aw_send_afe_cal_apr, + .aw_send_afe_rx_module_enable = aw_send_afe_rx_module_enable, + .aw_send_afe_tx_module_enable = aw_send_afe_tx_module_enable, +// .aw_adm_param_enable = aw_adm_param_enable; +}; +#endif int __init afe_init(void) { int i = 0, ret; @@ -10690,7 +10906,9 @@ int __init afe_init(void) pr_err("%s: could not init cal data! %d\n", __func__, ret); config_debug_fs_init(); - +#ifdef CONFIG_SND_SMARTPA_AW882XX + aw_reg_fae_func(&aw_func); +#endif this_afe.uevent_data = kzalloc(sizeof(*(this_afe.uevent_data)), GFP_KERNEL); if (!this_afe.uevent_data) return -ENOMEM; @@ -10727,6 +10945,10 @@ void afe_exit(void) q6core_destroy_uevent_data(this_afe.uevent_data); +#ifdef CONFIG_SND_SMARTPA_AW882XX + aw_cal_unmap_memory(); +#endif + afe_delete_cal_data(); config_debug_fs_exit(); -- GitLab From 78ff50b743fbc844c4fe34695d141a0042721e30 Mon Sep 17 00:00:00 2001 From: lintaopei Date: Tue, 23 Mar 2021 14:29:35 +0800 Subject: [PATCH 1627/1645] [ALM:10872983][FP4-99][Audio]HPH disable default --- asoc/codecs/wcd-mbhc-v2.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c index ee24ea63a031..12074d1237b6 100644 --- a/asoc/codecs/wcd-mbhc-v2.c +++ b/asoc/codecs/wcd-mbhc-v2.c @@ -1755,6 +1755,13 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_component *component, goto err; } +#ifdef CONFIG_T2M_SND_FP4 + hph_swh = 1; + gnd_swh = 0; + dev_dbg(card->dev,"%s:set msm-mbhc-hphl-swh %d in dt node\n", __func__, hph_swh); + dev_dbg(card->dev,"%s:set msm-mbhc-gnd-swh %d in dt node\n", __func__, gnd_swh); +#endif + ret = of_property_read_u32(card->dev->of_node, hs_thre, &(mbhc->hs_thr)); if (ret) -- GitLab From a43e8753e1b8149886889eea95dcc4c03aab2c23 Mon Sep 17 00:00:00 2001 From: lintaopei Date: Thu, 25 Mar 2021 09:24:05 +0800 Subject: [PATCH 1628/1645] [ALM:10872983][FP4-99][Audio]aw882xx update --- asoc/kona.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/kona.c b/asoc/kona.c index fa514b08a566..c0f6650341bf 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -7123,8 +7123,13 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .stream_name = "Quinary MI2S Capture", .cpu_dai_name = "msm-dai-q6-mi2s.4", .platform_name = "msm-pcm-routing", +#ifdef CONFIG_SND_SMARTPA_AW882XX + .num_codecs = ARRAY_SIZE(awinic_codecs), + .codecs = awinic_codecs, +#else .codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-tx", +#endif .no_pcm = 1, .dpcm_capture = 1, .id = MSM_BACKEND_DAI_QUINARY_MI2S_TX, -- GitLab From 6c2cfd33c26f67ccf79566eb1158512cd3534423 Mon Sep 17 00:00:00 2001 From: lintaopei Date: Wed, 31 Mar 2021 10:33:07 +0800 Subject: [PATCH 1629/1645] [ALM:10872983][FP4-99][Audio]aw tx --- asoc/kona.c | 6 +++--- asoc/msm-dai-fe.c | 32 ++++++++++++++++++++++++++++++++ asoc/msm-pcm-routing-v2.c | 27 +++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/asoc/kona.c b/asoc/kona.c index c0f6650341bf..7565ef11ee6d 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -497,7 +497,7 @@ static struct dev_config mi2s_tx_cfg[] = { [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, - [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, [SEN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, }; @@ -6486,7 +6486,7 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .no_host_mode = SND_SOC_DAI_LINK_NO_HOST, .ops = &msm_cdc_dma_be_ops, }, -/*#if defined(CONFIG_SND_SMARTPA_AW882XX) +#if defined(CONFIG_SND_SMARTPA_AW882XX) { .name = "Quinary MI2S RX_Hostless", .stream_name = "Quinary MI2S_RX Hostless Playback", @@ -6517,7 +6517,7 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", }, -#endif*/ +#endif }; static struct snd_soc_dai_link msm_common_be_dai_links[] = { diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index 29e15dda17cb..e7838ffac9b9 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -977,6 +977,38 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "QUAT_MI2S_RX_HOSTLESS", .probe = fe_dai_probe, }, + { + .capture = { + .stream_name = "Quinary MI2S_TX Hostless Capture", + .aif_name = "QUIN_MI2S_UL_HL", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE), + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUIN_MI2S_TX_HOSTLESS", + .probe = fe_dai_probe, + }, + { + .playback = { + .stream_name = "Quinary MI2S_RX Hostless Playback", + .aif_name = "QUIN_MI2S_DL_HL", + .rates = SNDRV_PCM_RATE_8000_384000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 384000, + }, + .ops = &msm_fe_dai_ops, + .name = "QUIN_MI2S_RX_HOSTLESS", + .probe = fe_dai_probe, + }, { .playback = { .stream_name = "INT0 MI2S_RX Hostless Playback", diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 868e254c97a0..9611666d3e4f 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -23865,6 +23865,10 @@ static const char * const mi2s_rx_vi_fb_tx_mux_text[] = { "ZERO", "SENARY_TX" }; +static const char * const quin_mi2s_rx_vi_fb_tx_mux_text[] = { + "ZERO", "QUIN_MI2S_TX" +}; + static const char * const int4_mi2s_rx_vi_fb_tx_mono_mux_text[] = { "ZERO", "INT5_MI2S_TX" }; @@ -23902,6 +23906,10 @@ static const int int4_mi2s_rx_vi_fb_tx_stereo_ch_value[] = { MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_INT5_MI2S_TX }; +static const int const quin_mi2s_rx_vi_fb_tx_value[] = { + MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_QUINARY_MI2S_TX +}; + static const struct soc_enum slim0_rx_vi_fb_lch_mux_enum = SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_SLIMBUS_0_RX, 0, 0, ARRAY_SIZE(slim0_rx_vi_fb_tx_lch_mux_text), @@ -23939,6 +23947,12 @@ static const struct soc_enum int4_mi2s_rx_vi_fb_stereo_ch_mux_enum = int4_mi2s_rx_vi_fb_tx_stereo_mux_text, int4_mi2s_rx_vi_fb_tx_stereo_ch_value); +static const struct soc_enum quin_mi2s_rx_vi_fb_mux_enum = + SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_QUINARY_MI2S_RX, 0, 0, + ARRAY_SIZE(quin_mi2s_rx_vi_fb_tx_mux_text), + quin_mi2s_rx_vi_fb_tx_mux_text, + quin_mi2s_rx_vi_fb_tx_value); + static const struct snd_kcontrol_new slim0_rx_vi_fb_lch_mux = SOC_DAPM_ENUM_EXT("SLIM0_RX_VI_FB_LCH_MUX", slim0_rx_vi_fb_lch_mux_enum, spkr_prot_get_vi_lch_port, @@ -23974,6 +23988,11 @@ static const struct snd_kcontrol_new int4_mi2s_rx_vi_fb_stereo_ch_mux = int4_mi2s_rx_vi_fb_stereo_ch_mux_enum, spkr_prot_get_vi_rch_port, spkr_prot_put_vi_rch_port); +static const struct snd_kcontrol_new quin_mi2s_rx_vi_fb_mux = + SOC_DAPM_ENUM_EXT("QUIN_MI2S_RX_VI_FB_MUX", + quin_mi2s_rx_vi_fb_mux_enum, spkr_prot_get_vi_lch_port, + spkr_prot_put_vi_lch_port); + static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { /* Frontend AIF */ /* Widget name equals to Front-End DAI name, @@ -24537,6 +24556,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &wsa_rx_0_vi_fb_lch_mux), SND_SOC_DAPM_MUX("WSA_RX_0_VI_FB_RCH_MUX", SND_SOC_NOPM, 0, 0, &wsa_rx_0_vi_fb_rch_mux), + SND_SOC_DAPM_MUX("QUIN_MI2S_RX_VI_FB_MUX", SND_SOC_NOPM, 0, 0, + &quin_mi2s_rx_vi_fb_mux), SND_SOC_DAPM_MUX("VOC_EXT_EC MUX", SND_SOC_NOPM, 0, 0, &voc_ext_ec_mux), SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL1 MUX", SND_SOC_NOPM, 0, 0, @@ -24934,6 +24955,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets_mi2s[] = { ARRAY_SIZE(int4_mi2s_rx_port_mixer_controls)), /* lsm mixer definitions */ /* Virtual Pins to force backends ON atm */ + SND_SOC_DAPM_MUX("QUIN_MI2S_RX_VI_FB_MUX", SND_SOC_NOPM, 0, 0, + &quin_mi2s_rx_vi_fb_mux), SND_SOC_DAPM_MUX("PRI_MI2S_RX_VI_FB_MUX", SND_SOC_NOPM, 0, 0, &mi2s_rx_vi_fb_mux), SND_SOC_DAPM_MUX("INT4_MI2S_RX_VI_FB_MONO_CH_MUX", SND_SOC_NOPM, 0, 0, @@ -27071,8 +27094,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIM0_RX_VI_FB_RCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"}, {"WSA_RX_0_VI_FB_LCH_MUX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, {"WSA_RX_0_VI_FB_RCH_MUX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"}, + {"QUIN_MI2S_RX_VI_FB_MUX", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_LCH_MUX"}, {"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_RCH_MUX"}, + {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_VI_FB_MUX"}, {"WSA_CDC_DMA_RX_0", NULL, "WSA_RX_0_VI_FB_LCH_MUX"}, {"WSA_CDC_DMA_RX_0", NULL, "WSA_RX_0_VI_FB_RCH_MUX"}, {"WSA_CDC_DMA_TX_0", NULL, "BE_IN"}, @@ -30105,8 +30130,10 @@ static const struct snd_soc_dapm_route intercon_mi2s[] = { {"SENARY_MI2S_TX", NULL, "BE_IN"}, {"PRI_MI2S_RX_VI_FB_MUX", "SENARY_TX", "SENARY_TX"}, + {"QUIN_MI2S_RX_VI_FB_MUX", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"INT4_MI2S_RX_VI_FB_MONO_CH_MUX", "INT5_MI2S_TX", "INT5_MI2S_TX"}, {"INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", "INT5_MI2S_TX", "INT5_MI2S_TX"}, + {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_VI_FB_MUX"}, {"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_VI_FB_MUX"}, {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_MONO_CH_MUX"}, {"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_STEREO_CH_MUX"}, -- GitLab From bf0c488be2e7022d0bf74ddd51934fd343cd79d2 Mon Sep 17 00:00:00 2001 From: lintaopei Date: Thu, 1 Apr 2021 16:05:29 +0800 Subject: [PATCH 1630/1645] [ALM:10872983][FP4-99][Audio]aw tx update --- asoc/msm-pcm-routing-v2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 9611666d3e4f..dd2c6b15fffd 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -29976,7 +29976,8 @@ static const struct snd_soc_dapm_route intercon_mi2s[] = { {"PRI_MI2S_RX", NULL, "PRI_MI2S_DL_HL"}, {"TERT_MI2S_RX", NULL, "TERT_MI2S_DL_HL"}, {"QUAT_MI2S_UL_HL", NULL, "QUAT_MI2S_TX"}, - + {"QUIN_MI2S_UL_HL", NULL, "QUIN_MI2S_TX"}, + {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_DL_HL"}, {"INT0_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"INT0_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"INT0_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, -- GitLab From 0e5b9a05e9a92e39f6733b4bc7f58b1307cb0ae2 Mon Sep 17 00:00:00 2001 From: lintaopei Date: Fri, 16 Apr 2021 16:58:45 +0800 Subject: [PATCH 1631/1645] [ALM:10872983][FP4-92][Audio]Audio Loop develop --- asoc/msm-pcm-routing-v2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index dd2c6b15fffd..0fd1d79efc5f 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -7730,6 +7730,10 @@ static const struct snd_kcontrol_new quin_mi2s_rx_port_mixer_controls[] = { MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_DOUBLE_EXT("TX_CDC_DMA_TX_3", SND_SOC_NOPM, + MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_BACKEND_DAI_TX_CDC_DMA_TX_3, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), }; static const struct snd_kcontrol_new sen_mi2s_rx_port_mixer_controls[] = { @@ -30087,6 +30091,7 @@ static const struct snd_soc_dapm_route intercon_mi2s[] = { {"QUIN_MI2S_RX Port Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"}, {"QUIN_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"QUIN_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"QUIN_MI2S_RX Port Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"}, {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX Port Mixer"}, {"SEN_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, -- GitLab From b2be2eef391c267949d9329aedbc429c33074da5 Mon Sep 17 00:00:00 2001 From: lintaopei Date: Fri, 23 Apr 2021 14:16:42 +0800 Subject: [PATCH 1632/1645] [ALM:10872983][FP4-92][Audio]Audio loop update --- asoc/msm-pcm-routing-v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 0fd1d79efc5f..135147aa982a 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -29966,7 +29966,7 @@ static const struct snd_soc_dapm_route intercon_mi2s[] = { {"QUAT_MI2S_RX_DL_HL", "Switch", "QUAT_MI2S_DL_HL"}, {"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX_DL_HL"}, - {"QUIN_MI2S_RX_DL_HL", "Switch", "QUIN_MI2S_DL_HL"}, + {"QUIN_MI2S_RX_DL_HL", "Switch", "CDC_DMA_DL_HL"}, {"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_DL_HL"}, {"SEN_MI2S_RX_DL_HL", "Switch", "SEN_MI2S_DL_HL"}, {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX_DL_HL"}, -- GitLab From 0660d7839fe9ca0b5243d945d247c8c918f40439 Mon Sep 17 00:00:00 2001 From: lintaopei Date: Mon, 24 May 2021 14:34:52 +0800 Subject: [PATCH 1633/1645] [ALM:10872983][FP4-92][Audio]HAC develop --- asoc/kona.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/asoc/kona.c b/asoc/kona.c index 7565ef11ee6d..4a9b41cbd27f 100644 --- a/asoc/kona.c +++ b/asoc/kona.c @@ -5701,6 +5701,8 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd) ARRAY_SIZE(msm_hac_audio_map)); snd_soc_dapm_ignore_suspend(dapm, "HAC"); + snd_soc_dapm_ignore_suspend(dapm, "HAC_RX"); + snd_soc_dapm_sync(dapm); #endif snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0"); -- GitLab From 6870feb6bcb34420918e20383362ee612738b053 Mon Sep 17 00:00:00 2001 From: lintaopei Date: Mon, 7 Jun 2021 16:01:57 +0800 Subject: [PATCH 1634/1645] [ALM:10872983][FP4-92][Audio]voice echo ref --- asoc/msm-pcm-routing-v2.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 135147aa982a..3a164c62c9b9 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -5558,6 +5558,10 @@ static int get_ec_ref_port_id(int value, int *index) *index = 40; port_id = AFE_PORT_ID_QUINARY_TDM_TX; break; + case 41: + *index = 41; + port_id = AFE_PORT_ID_QUINARY_MI2S_TX; + break; default: *index = 0; /* NONE */ pr_err("%s: Invalid value %d\n", __func__, value); @@ -5615,7 +5619,7 @@ static const char *const ec_ref_rx[] = { "None", "SLIM_RX", "I2S_RX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_1", "WSA_CDC_DMA_TX_2", "SLIM_7_RX", "RX_CDC_DMA_RX_0", "RX_CDC_DMA_RX_1", "RX_CDC_DMA_RX_2", "RX_CDC_DMA_RX_3", "TX_CDC_DMA_TX_0", "TERT_TDM_RX_2", "SEC_TDM_TX_0", - "DISPLAY_PORT1", "SEN_MI2S_RX", "SENARY_MI2S_TX", "QUIN_TDM_TX_0", + "DISPLAY_PORT1", "SEN_MI2S_RX", "SENARY_MI2S_TX", "QUIN_TDM_TX_0","QUIN_MI2S_TX", }; static const struct soc_enum msm_route_ec_ref_rx_enum[] = { @@ -29813,6 +29817,7 @@ static const struct snd_soc_dapm_route intercon_mi2s[] = { {"AUDIO_REF_EC_UL1 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"AUDIO_REF_EC_UL1 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"AUDIO_REF_EC_UL1 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"AUDIO_REF_EC_UL1 MUX", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"AUDIO_REF_EC_UL2 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"AUDIO_REF_EC_UL2 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, @@ -29853,6 +29858,7 @@ static const struct snd_soc_dapm_route intercon_mi2s[] = { {"AUDIO_REF_EC_UL10 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"AUDIO_REF_EC_UL10 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"AUDIO_REF_EC_UL10 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "QUIN_MI2S_TX", "QUIN_MI2S_TX"}, {"AUDIO_REF_EC_UL16 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"AUDIO_REF_EC_UL16 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, -- GitLab From 7466c3a085206d957a531372f97e8abe73e635fe Mon Sep 17 00:00:00 2001 From: Shazmaan Ali Date: Fri, 25 Mar 2022 13:51:35 -0700 Subject: [PATCH 1635/1645] asoc: codecs: Add nullptr check fix for nullptr deref issue Change-Id: I26acf2c5c696038c6d5c64d858174b2f2c58a7d3 Signed-off-by: Shazmaan Ali --- soc/pinctrl-lpi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index 3258b10f18e8..ec075e828bc1 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -261,12 +262,14 @@ static int lpi_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int function, pad = pctldev->desc->pins[pin].drv_data; - pad->function = function; + if (pad != NULL) { + pad->function = function; - val = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL); - val &= ~(LPI_GPIO_REG_FUNCTION_MASK); - val |= pad->function << LPI_GPIO_REG_FUNCTION_SHIFT; - lpi_gpio_write(pad, LPI_GPIO_REG_VAL_CTL, val); + val = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL); + val &= ~(LPI_GPIO_REG_FUNCTION_MASK); + val |= pad->function << LPI_GPIO_REG_FUNCTION_SHIFT; + lpi_gpio_write(pad, LPI_GPIO_REG_VAL_CTL, val); + } return 0; } -- GitLab From 0b2f6bf1fd02b1c53bf272bc52a87ef9e293442b Mon Sep 17 00:00:00 2001 From: lintaopei Date: Wed, 25 May 2022 15:50:02 +0800 Subject: [PATCH 1636/1645] [FP4S-105][Audio]aw mec update --- asoc/msm-pcm-routing-v2.c | 2 -- dsp/q6afe.c | 8 ++++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 3a164c62c9b9..f4d20cb5bb98 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -24564,8 +24564,6 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &wsa_rx_0_vi_fb_lch_mux), SND_SOC_DAPM_MUX("WSA_RX_0_VI_FB_RCH_MUX", SND_SOC_NOPM, 0, 0, &wsa_rx_0_vi_fb_rch_mux), - SND_SOC_DAPM_MUX("QUIN_MI2S_RX_VI_FB_MUX", SND_SOC_NOPM, 0, 0, - &quin_mi2s_rx_vi_fb_mux), SND_SOC_DAPM_MUX("VOC_EXT_EC MUX", SND_SOC_NOPM, 0, 0, &voc_ext_ec_mux), SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL1 MUX", SND_SOC_NOPM, 0, 0, diff --git a/dsp/q6afe.c b/dsp/q6afe.c index a61de34a607b..afb4772a890f 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -2427,11 +2427,11 @@ static void afe_send_cal_spv4_tx(int port_id) if (this_afe.vi_tx_port == port_id) { memcpy(&afe_spk_config.v4_ch_map_cfg, &this_afe.v4_ch_map_cfg, sizeof(struct afe_sp_v4_param_vi_channel_map_cfg)); - if (afe_spk_prot_prepare(port_id, this_afe.vi_rx_port, + /*if (afe_spk_prot_prepare(port_id, this_afe.vi_rx_port, AFE_PARAM_ID_SP_V4_VI_CHANNEL_MAP_CFG, &afe_spk_config, sizeof(struct afe_sp_v4_param_vi_channel_map_cfg))) pr_info("%s: SPKR_CALIB_CHANNEL_MAP_CFG failed\n", - __func__); + __func__);*/ } if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL || @@ -9840,7 +9840,7 @@ int afe_spk_prot_feed_back_cfg(int src_port, int dst_port, } pr_debug("%s: src_port 0x%x dst_port 0x%x l_ch %d r_ch %d\n", __func__, src_port, dst_port, l_ch, r_ch); - if (q6core_get_avcs_api_version_per_service( + /*if (q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) { if (l_ch) { this_afe.v4_ch_map_cfg.chan_info[index++] = 1; @@ -9852,7 +9852,7 @@ int afe_spk_prot_feed_back_cfg(int src_port, int dst_port, } this_afe.v4_ch_map_cfg.num_channels = index; this_afe.num_spkrs = index / 2; - } + }*/ index = 0; memset(&prot_config, 0, sizeof(prot_config)); -- GitLab From d5d266316c190b5f99df178621ac6d5493bc6fa8 Mon Sep 17 00:00:00 2001 From: Shalini Manjunatha Date: Mon, 11 Jul 2022 16:24:15 +0530 Subject: [PATCH 1637/1645] soc: swr-mstr: Store and compare dev_addr along with dev_num -> If enumeration is changed runtime, dev_num gets changed -> so it might result in different dev_num for same device -> between swrm_connect_port and swr_disconnect_port while powering up and down of widget -> This results in not emptying the port_req list, hence swrm not going to suspend state -> This results into adsp not going to sleep state Change-Id: I80326a35f0cac7f7be30cbbee119a8ba247a0f76 --- include/soc/soundwire.h | 3 +++ soc/soundwire.c | 5 +++++ soc/swr-mstr-ctrl.c | 10 ++++++---- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/include/soc/soundwire.h b/include/soc/soundwire.h index 3e61da12b1dd..7b69d1a896fe 100644 --- a/include/soc/soundwire.h +++ b/include/soc/soundwire.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _LINUX_SOUNDWIRE_H @@ -83,6 +84,7 @@ struct swr_port_info { u8 req_ch; u8 num_ch; u32 ch_rate; + u64 dev_addr; }; /* @@ -107,6 +109,7 @@ struct swr_params { u32 ch_rate[SWR_MAX_DEV_PORT_NUM]; u8 ch_en[SWR_MAX_DEV_PORT_NUM]; u8 port_type[SWR_MAX_DEV_PORT_NUM]; + u64 dev_addr; }; /* diff --git a/soc/soundwire.c b/soc/soundwire.c index 2aa3ba4bdae0..f3688b0158b7 100644 --- a/soc/soundwire.c +++ b/soc/soundwire.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -363,6 +364,8 @@ int swr_connect_port(struct swr_device *dev, u8 *port_id, u8 num_port, txn->tid = i; txn->dev_num = dev->dev_num; + //assign device addr also, as dev_num can dynamically change during device enumeration + txn->dev_addr = dev->addr; txn->num_port = num_port; for (i = 0; i < num_port; i++) { txn->port_id[i] = port_id[i]; @@ -442,6 +445,8 @@ int swr_disconnect_port(struct swr_device *dev, u8 *port_id, u8 num_port, txn->tid = i; txn->dev_num = dev->dev_num; + //assign device address as dev_num can change dynamically during device enumeration + txn->dev_addr = dev->addr; txn->num_port = num_port; for (i = 0; i < num_port; i++) { txn->port_id[i] = port_id[i]; diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 4cdb3f500cfc..09d382a125e7 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1098,14 +1099,14 @@ static void swrm_switch_frame_shape(struct swr_mstr_ctrl *swrm, int mclk_freq) } static struct swr_port_info *swrm_get_port_req(struct swrm_mports *mport, - u8 slv_port, u8 dev_num) + u8 slv_port, u8 dev_num, u64 dev_addr) { struct swr_port_info *port_req = NULL; list_for_each_entry(port_req, &mport->port_req_list, list) { /* Store dev_id instead of dev_num if enumeration is changed run_time */ if ((port_req->slave_port_id == slv_port) - && (port_req->dev_num == dev_num)) + && ((port_req->dev_num == dev_num) || (port_req->dev_addr == dev_addr))) return port_req; } return NULL; @@ -1631,7 +1632,7 @@ static int swrm_connect_port(struct swr_master *master, mport = &(swrm->mport_cfg[mstr_port_id]); /* get port req */ port_req = swrm_get_port_req(mport, portinfo->port_id[i], - portinfo->dev_num); + portinfo->dev_num, portinfo->dev_addr); if (!port_req) { dev_dbg(&master->dev, "%s: new req:port id %d dev %d\n", __func__, portinfo->port_id[i], @@ -1643,6 +1644,7 @@ static int swrm_connect_port(struct swr_master *master, goto mem_fail; } port_req->dev_num = portinfo->dev_num; + port_req->dev_addr = portinfo->dev_addr; port_req->slave_port_id = portinfo->port_id[i]; port_req->num_ch = portinfo->num_ch[i]; port_req->ch_rate = portinfo->ch_rate[i]; @@ -1719,7 +1721,7 @@ static int swrm_disconnect_port(struct swr_master *master, mport = &(swrm->mport_cfg[mstr_port_id]); /* get port req */ port_req = swrm_get_port_req(mport, portinfo->port_id[i], - portinfo->dev_num); + portinfo->dev_num, portinfo->dev_addr); if (!port_req) { dev_err(&master->dev, "%s:port not enabled : port %d\n", -- GitLab From a4374817ccc8686f86aa708243ecda95da28e216 Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Fri, 6 Jan 2023 14:37:20 +0530 Subject: [PATCH 1638/1645] ASoC: msm-pcm-q6-v2: Add dsp buf check Current logic copies user buf size of data from the avail dsp buf at a given offset. If this offset returned from DSP in READ_DONE event goes out of bounds or is corrupted, then it can lead to out of bounds DSP buffer access, resulting in memory fault. Fix is to add check for this buf offset, if it is within the buf size range. Change-Id: I7753cc6db394704dbb959477150141d42b836bef Signed-off-by: Soumya Managoli --- asoc/msm-pcm-q6-v2.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index e6a5c1a7a34b..04c6eec3a21a 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ @@ -1007,6 +1008,14 @@ static int msm_pcm_capture_copy(struct snd_pcm_substream *substream, xfer = size; offset = prtd->in_frame_info[idx].offset; pr_debug("Offset value = %d\n", offset); + + if (offset >= size) { + pr_err("%s: Invalid dsp buf offset\n", __func__); + ret = -EFAULT; + q6asm_cpu_buf_release(OUT, prtd->audio_client); + goto fail; + } + if (size == 0 || size < prtd->pcm_count) { memset(bufptr + offset + size, 0, prtd->pcm_count - size); if (fbytes > prtd->pcm_count) -- GitLab From 558e7e63f54a206ea23d7932fdbf76da9557fded Mon Sep 17 00:00:00 2001 From: android-t1 Date: Fri, 15 Sep 2023 16:19:06 +0800 Subject: [PATCH 1639/1645] [FP4T-731]Integrate security patch 2023-10-05-CVE-2023-33035 Change-Id: Ic34137ac885dc1635e80c2f2e8584f4cd13ae417 (cherry picked from commit 6a101390a740f693b795cb8e4acd560f8d5ea1dc) --- dsp/q6afe.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/dsp/q6afe.c b/dsp/q6afe.c index afb4772a890f..2e2f88a29703 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -701,32 +702,74 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, switch (param_hdr.param_id) { case AFE_PARAM_ID_CALIB_RES_CFG_V2: expected_size += sizeof(struct asm_calib_res_cfg); + if (param_hdr.param_size != sizeof(struct asm_calib_res_cfg)) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } data_dest = (u32 *) &this_afe.calib_data; break; case AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS: expected_size += sizeof(struct afe_sp_th_vi_ftm_params); + if (param_hdr.param_size != sizeof(struct afe_sp_th_vi_ftm_params)) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } data_dest = (u32 *) &this_afe.th_vi_resp; break; case AFE_PARAM_ID_SP_V2_TH_VI_V_VALI_PARAMS: expected_size += sizeof(struct afe_sp_th_vi_v_vali_params); + if (param_hdr.param_size != sizeof(struct afe_sp_th_vi_v_vali_params)) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } data_dest = (u32 *) &this_afe.th_vi_v_vali_resp; break; case AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS: expected_size += sizeof(struct afe_sp_ex_vi_ftm_params); + if (param_hdr.param_size != sizeof(struct afe_sp_ex_vi_ftm_params)) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } data_dest = (u32 *) &this_afe.ex_vi_resp; break; case AFE_PARAM_ID_SP_RX_TMAX_XMAX_LOGGING: expected_size += sizeof( struct afe_sp_rx_tmax_xmax_logging_param); + if (param_hdr.param_size != sizeof(struct afe_sp_rx_tmax_xmax_logging_param)) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } data_dest = (u32 *) &this_afe.xt_logging_resp; break; case AFE_PARAM_ID_SP_V4_CALIB_RES_CFG: expected_size += sizeof( struct afe_sp_v4_param_th_vi_calib_res_cfg); + if (param_hdr.param_size != sizeof( + struct afe_sp_v4_param_th_vi_calib_res_cfg)) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } data_dest = (u32 *) &this_afe.spv4_calib_data; break; case AFE_PARAM_ID_SP_V4_TH_VI_FTM_PARAMS: num_ch = data_start[0]; + if (num_ch > SP_V2_NUM_MAX_SPKRS) { + pr_err("%s: Error: num_ch %d is greater than expected\n", + __func__,num_ch); + return -EINVAL; + } + if (param_hdr.param_size != (sizeof(struct afe_sp_v4_param_th_vi_ftm_params) + + (num_ch * sizeof(struct afe_sp_v4_channel_ftm_params)))) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } this_afe.spv4_th_vi_ftm_rcvd_param_size = param_hdr.param_size; data_dest = (u32 *)&this_afe.spv4_th_vi_ftm_resp; expected_size += @@ -735,6 +778,18 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, break; case AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_PARAMS: num_ch = data_start[0]; + if (num_ch > SP_V2_NUM_MAX_SPKRS) { + pr_err("%s: Error: num_ch %d is greater than expected\n", + __func__,num_ch); + return -EINVAL; + } + if (param_hdr.param_size != (sizeof(struct afe_sp_v4_param_th_vi_v_vali_params) + + (num_ch * + sizeof(struct afe_sp_v4_channel_v_vali_params)))) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } this_afe.spv4_v_vali_rcvd_param_size = param_hdr.param_size; data_dest = (u32 *)&this_afe.spv4_v_vali_resp; expected_size += @@ -744,6 +799,18 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, break; case AFE_PARAM_ID_SP_V4_EX_VI_FTM_PARAMS: num_ch = data_start[0]; + if (num_ch > SP_V2_NUM_MAX_SPKRS) { + pr_err("%s: Error: num_ch %d is greater than expected\n", + __func__,num_ch); + return -EINVAL; + } + if (param_hdr.param_size != (sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) + + (num_ch * + sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params)))) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } this_afe.spv4_ex_vi_ftm_rcvd_param_size = param_hdr.param_size; data_dest = (u32 *)&this_afe.spv4_ex_vi_ftm_resp; expected_size += @@ -752,6 +819,18 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, break; case AFE_PARAM_ID_SP_V4_RX_TMAX_XMAX_LOGGING: num_ch = data_start[0]; + if (num_ch > SP_V2_NUM_MAX_SPKRS) { + pr_err("%s: Error: num_ch %d is greater than expected\n", + __func__,num_ch); + return -EINVAL; + } + if (param_hdr.param_size != (sizeof(struct afe_sp_v4_param_tmax_xmax_logging) + + (num_ch * + sizeof(struct afe_sp_v4_channel_tmax_xmax_params)))) { + pr_err("%s: Error: param_size %d is greater than expected\n", + __func__,param_hdr.param_size); + return -EINVAL; + } this_afe.spv4_max_log_rcvd_param_size = param_hdr.param_size; data_dest = (u32 *)&this_afe.spv4_max_log_resp; expected_size += -- GitLab From 55623cf1d3ed87c82d65abdd711670dcfca903ff Mon Sep 17 00:00:00 2001 From: android-t2 Date: Wed, 20 Sep 2023 15:42:19 +0800 Subject: [PATCH 1640/1645] [FP4T-731]Integrate security patch 2023-10-05-CVE-2023-33034 Change-Id: Ic7208898ab452e5804520fbcdf137d800fb40665 (cherry picked from commit 04a62a446d90c11eb8f35a55b01aef5030c20a50) --- dsp/q6adm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index e63547d85738..6d88fc9de77a 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -1550,7 +1551,7 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) { uint32_t *payload; int port_idx, copp_idx, idx, client_id; - int num_modules; + uint32_t num_modules; int ret; if (data == NULL) { -- GitLab From c7fe5d5b741abc111e35c35905364ac14205efcf Mon Sep 17 00:00:00 2001 From: Pavel Dubrova Date: Wed, 1 Sep 2021 20:07:38 +0300 Subject: [PATCH 1641/1645] Makefile: Enable audio compilation for Lito Enable compilation of audio drivers for Lito. Signed-off-by: Pavel Dubrova Change-Id: Ib67dd8c2144b48481491c35d3a411149f532d770 --- Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Makefile b/Makefile index e66fd39dd646..a550c4697cca 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,10 @@ endif ifeq ($(CONFIG_ARCH_KONA), y) include $(srctree)/techpack/audio/config/konaauto.conf endif +ifeq ($(CONFIG_ARCH_LITO), y) +include $(srctree)/techpack/audio/config/litoauto.conf +export +endif ifeq ($(CONFIG_ARCH_SDM660), y) include $(srctree)/techpack/audio/config/sdm660auto.conf endif @@ -45,6 +49,10 @@ ifeq ($(CONFIG_ARCH_KONA), y) LINUXINCLUDE += \ -include $(srctree)/techpack/audio/config/konaautoconf.h endif +ifeq ($(CONFIG_ARCH_LITO), y) +LINUXINCLUDE += \ + -include $(srctree)/techpack/audio/config/litoautoconf.h +endif ifeq ($(CONFIG_ARCH_SDM660), y) LINUXINCLUDE += \ -include $(srctree)/techpack/audio/config/sdm660autoconf.h -- GitLab From 494d6fc86e3adf6f6b707c82db897d25b3816b6f Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Tue, 31 Mar 2020 22:53:22 +0200 Subject: [PATCH 1642/1645] treewide: Kbuild: Remove unused `shell date` commands from macro defines This macro define changes every build due to the nature of datetime, causing the build-system to needlessly recompile all source files every time even though the macro is never referenced (grep for BUILD_TIMESTAMP). [Pavel Dubrova] Applied to all existing BUILD_TIMESTAMPs. Signed-off-by: Marijn Suijten Signed-off-by: Pavel Dubrova Change-Id: I5816a8a54d84b477f892a721bfd3957b28394ea2 --- asoc/Kbuild | 3 --- asoc/codecs/Kbuild | 3 --- asoc/codecs/aqt1000/Kbuild | 3 --- asoc/codecs/bolero/Kbuild | 3 --- asoc/codecs/csra66x0/Kbuild | 3 --- asoc/codecs/ep92/Kbuild | 3 --- asoc/codecs/msm_sdw/Kbuild | 3 --- asoc/codecs/rouleur/Kbuild | 3 --- asoc/codecs/sdm660_cdc/Kbuild | 3 --- asoc/codecs/wcd934x/Kbuild | 3 --- asoc/codecs/wcd937x/Kbuild | 3 --- asoc/codecs/wcd938x/Kbuild | 3 --- asoc/codecs/wsa883x/Kbuild | 3 --- dsp/Kbuild | 3 --- dsp/codecs/Kbuild | 3 --- ipc/Kbuild | 3 --- soc/Kbuild | 3 --- 17 files changed, 51 deletions(-) diff --git a/asoc/Kbuild b/asoc/Kbuild index a0d8de1f66e7..08c40b0598ed 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -286,6 +286,3 @@ machine_dlkm-y := $(MACHINE_OBJS) obj-$(CONFIG_SND_SOC_CPE) += cpe_lsm_dlkm.o cpe_lsm_dlkm-y := $(CPE_LSM_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 6dc444290245..237663d6b1db 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -266,6 +266,3 @@ mbhc_dlkm-y := $(MBHC_OBJS) obj-$(CONFIG_SND_SOC_MSM_HDMI_CODEC_RX) += hdmi_dlkm.o hdmi_dlkm-y := $(HDMICODEC_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/aqt1000/Kbuild b/asoc/codecs/aqt1000/Kbuild index d83955f0ad37..c7f8b895c6c6 100644 --- a/asoc/codecs/aqt1000/Kbuild +++ b/asoc/codecs/aqt1000/Kbuild @@ -115,6 +115,3 @@ endif # Module information used by KBuild framework obj-$(CONFIG_SND_SOC_AQT1000) += aqt1000_cdc_dlkm.o aqt1000_cdc_dlkm-y := $(AQT1000_CDC_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild index 15e5dc576da3..9042ebfa8e1e 100644 --- a/asoc/codecs/bolero/Kbuild +++ b/asoc/codecs/bolero/Kbuild @@ -154,6 +154,3 @@ tx_macro_dlkm-y := $(TX_OBJS) obj-$(CONFIG_RX_MACRO) += rx_macro_dlkm.o rx_macro_dlkm-y := $(RX_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/csra66x0/Kbuild b/asoc/codecs/csra66x0/Kbuild index ef599622dd25..fe77d62718f8 100644 --- a/asoc/codecs/csra66x0/Kbuild +++ b/asoc/codecs/csra66x0/Kbuild @@ -100,6 +100,3 @@ endif # Module information used by KBuild framework obj-$(CONFIG_SND_SOC_CSRA66X0) += csra66x0_dlkm.o csra66x0_dlkm-y := $(CSRA66X0_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/ep92/Kbuild b/asoc/codecs/ep92/Kbuild index fc46a72f775d..ee4db7f39caf 100644 --- a/asoc/codecs/ep92/Kbuild +++ b/asoc/codecs/ep92/Kbuild @@ -101,6 +101,3 @@ endif # Module information used by KBuild framework obj-$(CONFIG_SND_SOC_EP92) += ep92_dlkm.o ep92_dlkm-y := $(EP92_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/msm_sdw/Kbuild b/asoc/codecs/msm_sdw/Kbuild index ccd515d085eb..10ac06e05543 100644 --- a/asoc/codecs/msm_sdw/Kbuild +++ b/asoc/codecs/msm_sdw/Kbuild @@ -104,6 +104,3 @@ endif # Module information used by KBuild framework obj-$(CONFIG_SND_SOC_MSM_SDW) += msm_sdw_dlkm.o msm_sdw_dlkm-y := $(MSM_SDW_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/rouleur/Kbuild b/asoc/codecs/rouleur/Kbuild index b59bcb1194ef..97965788b5e6 100644 --- a/asoc/codecs/rouleur/Kbuild +++ b/asoc/codecs/rouleur/Kbuild @@ -115,6 +115,3 @@ rouleur_slave_dlkm-y := $(ROULEUR_SLAVE_OBJS) obj-$(CONFIG_PM2250_SPMI) += pm2250_spmi_dlkm.o pm2250_spmi_dlkm-y := $(PM2250_SPMI_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/sdm660_cdc/Kbuild b/asoc/codecs/sdm660_cdc/Kbuild index c6cf4b705617..e91bafce2868 100644 --- a/asoc/codecs/sdm660_cdc/Kbuild +++ b/asoc/codecs/sdm660_cdc/Kbuild @@ -110,6 +110,3 @@ analog_cdc_dlkm-y := $(ANALOG_CDC_OBJS) obj-$(CONFIG_SND_SOC_DIGITAL_CDC) += digital_cdc_dlkm.o digital_cdc_dlkm-y := $(DIGITAL_CDC_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index d372ed762cef..404cc8dca141 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -121,6 +121,3 @@ endif # Module information used by KBuild framework obj-$(CONFIG_SND_SOC_WCD934X) += wcd934x_dlkm.o wcd934x_dlkm-y := $(WCD934X_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/wcd937x/Kbuild b/asoc/codecs/wcd937x/Kbuild index 5bbbad7cbdf5..b81fed3efd34 100644 --- a/asoc/codecs/wcd937x/Kbuild +++ b/asoc/codecs/wcd937x/Kbuild @@ -123,6 +123,3 @@ wcd937x_dlkm-y := $(WCD937X_OBJS) obj-$(CONFIG_SND_SOC_WCD937X_SLAVE) += wcd937x_slave_dlkm.o wcd937x_slave_dlkm-y := $(WCD937X_SLAVE_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/wcd938x/Kbuild b/asoc/codecs/wcd938x/Kbuild index 3dfe142bcfc2..bc5284355db2 100644 --- a/asoc/codecs/wcd938x/Kbuild +++ b/asoc/codecs/wcd938x/Kbuild @@ -111,6 +111,3 @@ wcd938x_dlkm-y := $(WCD938X_OBJS) obj-$(CONFIG_SND_SOC_WCD938X_SLAVE) += wcd938x_slave_dlkm.o wcd938x_slave_dlkm-y := $(WCD938X_SLAVE_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/asoc/codecs/wsa883x/Kbuild b/asoc/codecs/wsa883x/Kbuild index ac608b46c6a3..a7013e40ea4a 100644 --- a/asoc/codecs/wsa883x/Kbuild +++ b/asoc/codecs/wsa883x/Kbuild @@ -102,6 +102,3 @@ endif # Module information used by KBuild framework obj-$(CONFIG_SND_SOC_WSA883X) += wsa883x_dlkm.o wsa883x_dlkm-y := $(WSA883X_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/dsp/Kbuild b/dsp/Kbuild index 490b458bfc2b..09c77a2f9171 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -262,6 +262,3 @@ q6_pdr_dlkm-y := $(QDSP6_PDR_OBJS) obj-$(CONFIG_MSM_QDSP6_NOTIFIER) += q6_notifier_dlkm.o q6_notifier_dlkm-y := $(QDSP6_NOTIFIER_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 808bfe22a076..6a6a3da96ccc 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -161,6 +161,3 @@ endif # Module information used by KBuild framework obj-$(CONFIG_MSM_QDSP6V2_CODECS) += native_dlkm.o native_dlkm-y := $(NATIVE_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/ipc/Kbuild b/ipc/Kbuild index 755d6d8eacd5..d63930a06391 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -190,6 +190,3 @@ apr_dlkm-y := $(APRV_GLINK) obj-$(CONFIG_WCD_DSP_GLINK) += wglink_dlkm.o wglink_dlkm-y := $(WDSP_GLINK) - -# inject some build related information -CDEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" diff --git a/soc/Kbuild b/soc/Kbuild index 4fedbddcf460..d7d0c32a52fb 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -211,6 +211,3 @@ swr_ctrl_dlkm-y := $(SWR_CTRL_OBJS) obj-$(CONFIG_WCD_SPI_AC) += wcd_spi_acc_ctl_dlkm.o wcd_spi_acc_ctl_dlkm-y := $(WCD_SPI_ACC_CTL_OBJS) - -# inject some build related information -DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\" -- GitLab From 52e1b07a55ac0afd970730f4edc66d18954370f8 Mon Sep 17 00:00:00 2001 From: Pavel Dubrova Date: Sun, 12 Sep 2021 01:08:24 +0300 Subject: [PATCH 1643/1645] audio-kernel: Fix compilation time issue In incremental (dirty) kernel builds, compiling audio drivers takes significantly longer or may even freeze. The export statement causes unnecessary exports, which leads to this issue. Removing and adding export statements to the conf files for a specific platform, as it was done for Kona in the commit 4025a25 ("makefile: kona: remove make export instances") should fix this issue. Signed-off-by: Pavel Dubrova Change-Id: I4a52febc7852342946832b01638db023c3602711 --- Makefile | 4 -- asoc/Kbuild | 12 ----- asoc/codecs/Kbuild | 11 ---- asoc/codecs/aqt1000/Kbuild | 3 -- asoc/codecs/bolero/Kbuild | 5 -- asoc/codecs/csra66x0/Kbuild | 1 - asoc/codecs/ep92/Kbuild | 1 - asoc/codecs/msm_sdw/Kbuild | 1 - asoc/codecs/rouleur/Kbuild | 1 - asoc/codecs/sdm660_cdc/Kbuild | 1 - asoc/codecs/wcd934x/Kbuild | 5 -- asoc/codecs/wcd937x/Kbuild | 4 -- asoc/codecs/wcd938x/Kbuild | 1 - config/bengalauto.conf | 82 +++++++++++++++--------------- config/gvmauto.conf | 30 +++++------ config/litoauto.conf | 86 +++++++++++++++---------------- config/qcs405auto.conf | 78 ++++++++++++++-------------- config/sa6155auto.conf | 34 ++++++------- config/sa8155auto.conf | 30 +++++------ config/sdm660auto.conf | 96 +++++++++++++++++------------------ config/sdxpoorwillsauto.conf | 58 ++++++++++----------- config/sm6150auto.conf | 96 +++++++++++++++++------------------ config/sm8150auto.conf | 80 ++++++++++++++--------------- dsp/Kbuild | 12 ----- dsp/codecs/Kbuild | 9 ---- ipc/Kbuild | 12 ----- soc/Kbuild | 12 ----- 27 files changed, 335 insertions(+), 430 deletions(-) diff --git a/Makefile b/Makefile index a550c4697cca..ff66b91c2892 100644 --- a/Makefile +++ b/Makefile @@ -1,22 +1,18 @@ # auto-detect subdirs ifeq ($(CONFIG_ARCH_SDXPOORWILLS), y) include $(srctree)/techpack/audio/config/sdxpoorwillsauto.conf -export endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(srctree)/techpack/audio/config/sm8150auto.conf -export endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(srctree)/techpack/audio/config/sm8150auto.conf -export endif ifeq ($(CONFIG_ARCH_KONA), y) include $(srctree)/techpack/audio/config/konaauto.conf endif ifeq ($(CONFIG_ARCH_LITO), y) include $(srctree)/techpack/audio/config/litoauto.conf -export endif ifeq ($(CONFIG_ARCH_SDM660), y) include $(srctree)/techpack/audio/config/sdm660auto.conf diff --git a/asoc/Kbuild b/asoc/Kbuild index 08c40b0598ed..fc3c06e06cf2 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -17,28 +17,23 @@ ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SM8150), y) ifdef CONFIG_SND_SOC_SA8155 include $(AUDIO_ROOT)/config/sa8155auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h else include $(AUDIO_ROOT)/config/sm8150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif ifeq ($(CONFIG_ARCH_SM6150), y) ifdef CONFIG_SND_SOC_SA6155 include $(AUDIO_ROOT)/config/sa6155auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sa6155autoconf.h else include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif endif ifeq ($(CONFIG_ARCH_TRINKET), y) include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_KONA), y) @@ -47,38 +42,31 @@ ifeq ($(KERNEL_BUILD), 0) endif ifeq ($(CONFIG_ARCH_LITO), y) include $(AUDIO_ROOT)/config/litoauto.conf - export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_BENGAL), y) include $(AUDIO_ROOT)/config/bengalauto.conf - export INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) ifdef CONFIG_SND_SOC_SA8155 include $(AUDIO_ROOT)/config/sa8155auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h else include $(AUDIO_ROOT)/config/sm8150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf - export INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h endif ifeq ($(CONFIG_QTI_GVM), y) include $(AUDIO_ROOT)/config/gvmauto.conf - export INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h endif ifeq ($(CONFIG_ARCH_SDM660), y) include $(AUDIO_ROOT)/config/sdm660auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h endif endif diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index 237663d6b1db..f1b13421d3af 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -17,28 +17,23 @@ ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SM8150), y) ifdef CONFIG_SND_SOC_SA8155 include $(AUDIO_ROOT)/config/sa8155auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h else include $(AUDIO_ROOT)/config/sm8150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif ifeq ($(CONFIG_ARCH_SM6150), y) ifdef CONFIG_SND_SOC_SA6155 include $(AUDIO_ROOT)/config/sa6155auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sa6155autoconf.h else include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif endif ifeq ($(CONFIG_ARCH_TRINKET), y) include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_KONA), y) @@ -47,32 +42,26 @@ ifeq ($(KERNEL_BUILD), 0) endif ifeq ($(CONFIG_ARCH_LITO), y) include $(AUDIO_ROOT)/config/litoauto.conf - export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_BENGAL), y) include $(AUDIO_ROOT)/config/bengalauto.conf - export INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf - export INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h endif ifeq ($(CONFIG_QTI_GVM), y) include $(AUDIO_ROOT)/config/gvmauto.conf - export INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h endif ifeq ($(CONFIG_ARCH_SDM660), y) include $(AUDIO_ROOT)/config/sdm660auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h endif endif diff --git a/asoc/codecs/aqt1000/Kbuild b/asoc/codecs/aqt1000/Kbuild index c7f8b895c6c6..3381327b7e5a 100644 --- a/asoc/codecs/aqt1000/Kbuild +++ b/asoc/codecs/aqt1000/Kbuild @@ -19,19 +19,16 @@ ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SDM670), y) include $(AUDIO_ROOT)/config/sdm670auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild index 9042ebfa8e1e..8fdc9c858b9e 100644 --- a/asoc/codecs/bolero/Kbuild +++ b/asoc/codecs/bolero/Kbuild @@ -18,12 +18,10 @@ endif ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_TRINKET), y) include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_KONA), y) @@ -32,17 +30,14 @@ ifeq ($(KERNEL_BUILD), 0) endif ifeq ($(CONFIG_ARCH_LITO), y) include $(AUDIO_ROOT)/config/litoauto.conf - export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_BENGAL), y) include $(AUDIO_ROOT)/config/bengalauto.conf - export INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf - export INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h endif endif diff --git a/asoc/codecs/csra66x0/Kbuild b/asoc/codecs/csra66x0/Kbuild index fe77d62718f8..2724dc7f9d62 100644 --- a/asoc/codecs/csra66x0/Kbuild +++ b/asoc/codecs/csra66x0/Kbuild @@ -17,7 +17,6 @@ endif ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf - export INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h endif endif diff --git a/asoc/codecs/ep92/Kbuild b/asoc/codecs/ep92/Kbuild index ee4db7f39caf..038bdb8346ca 100644 --- a/asoc/codecs/ep92/Kbuild +++ b/asoc/codecs/ep92/Kbuild @@ -18,7 +18,6 @@ endif ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf - export INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h endif endif diff --git a/asoc/codecs/msm_sdw/Kbuild b/asoc/codecs/msm_sdw/Kbuild index 10ac06e05543..a8d2fa14b35f 100644 --- a/asoc/codecs/msm_sdw/Kbuild +++ b/asoc/codecs/msm_sdw/Kbuild @@ -17,7 +17,6 @@ endif ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SDM660), y) include $(AUDIO_ROOT)/config/sdm660auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h endif endif diff --git a/asoc/codecs/rouleur/Kbuild b/asoc/codecs/rouleur/Kbuild index 97965788b5e6..8806bf77146f 100644 --- a/asoc/codecs/rouleur/Kbuild +++ b/asoc/codecs/rouleur/Kbuild @@ -18,7 +18,6 @@ endif ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_BENGAL), y) include $(AUDIO_ROOT)/config/bengalauto.conf - export INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif endif diff --git a/asoc/codecs/sdm660_cdc/Kbuild b/asoc/codecs/sdm660_cdc/Kbuild index e91bafce2868..38e530604901 100644 --- a/asoc/codecs/sdm660_cdc/Kbuild +++ b/asoc/codecs/sdm660_cdc/Kbuild @@ -17,7 +17,6 @@ endif ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SDM660), y) include $(AUDIO_ROOT)/config/sdm660auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h endif endif diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index 404cc8dca141..756993bc797a 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -18,27 +18,22 @@ endif ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_TRINKET), y) include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SDM660), y) include $(AUDIO_ROOT)/config/sdm660auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h endif endif diff --git a/asoc/codecs/wcd937x/Kbuild b/asoc/codecs/wcd937x/Kbuild index b81fed3efd34..5c7c61ff5aec 100644 --- a/asoc/codecs/wcd937x/Kbuild +++ b/asoc/codecs/wcd937x/Kbuild @@ -18,22 +18,18 @@ endif ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_TRINKET), y) include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_BENGAL), y) include $(AUDIO_ROOT)/config/bengalauto.conf - export INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif ifeq ($(CONFIG_ARCH_LITO), y) include $(AUDIO_ROOT)/config/litoauto.conf - export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif endif diff --git a/asoc/codecs/wcd938x/Kbuild b/asoc/codecs/wcd938x/Kbuild index bc5284355db2..7482c23f8826 100644 --- a/asoc/codecs/wcd938x/Kbuild +++ b/asoc/codecs/wcd938x/Kbuild @@ -20,7 +20,6 @@ ifeq ($(KERNEL_BUILD), 0) endif ifeq ($(CONFIG_ARCH_LITO), y) include $(AUDIO_ROOT)/config/litoauto.conf - export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif diff --git a/config/bengalauto.conf b/config/bengalauto.conf index f9c28daa19b0..05ba6a98cbce 100644 --- a/config/bengalauto.conf +++ b/config/bengalauto.conf @@ -1,41 +1,41 @@ -CONFIG_PINCTRL_LPI=m -CONFIG_AUDIO_EXT_CLK=m -CONFIG_SND_SOC_WCD9XXX_V2=m -CONFIG_SND_SOC_WCD_MBHC=m -CONFIG_SND_SOC_WSA881X_ANALOG=m -CONFIG_WCD9XXX_CODEC_CORE_V2=m -CONFIG_MSM_CDC_PINCTRL=m -CONFIG_MSM_QDSP6V2_CODECS=m -CONFIG_MSM_ULTRASOUND=m -CONFIG_MSM_QDSP6_APRV2_RPMSG=m -CONFIG_MSM_ADSP_LOADER=m -CONFIG_REGMAP_SWR=m -CONFIG_MSM_QDSP6_SSR=m -CONFIG_MSM_QDSP6_PDR=m -CONFIG_MSM_QDSP6_NOTIFIER=m -CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m -CONFIG_SOUNDWIRE=m -CONFIG_SOUNDWIRE_MSTR_CTRL=m -CONFIG_SND_SOC_QDSP6V2=m -CONFIG_SND_SOC_WCD_MBHC_ADC=m -CONFIG_QTI_PP=m -CONFIG_SND_HWDEP_ROUTING=m -CONFIG_SND_SOC_MSM_STUB=m -CONFIG_MSM_AVTIMER=m -CONFIG_SND_SOC_BOLERO=m -CONFIG_VA_MACRO=m -CONFIG_RX_MACRO=m -CONFIG_TX_MACRO=m -CONFIG_DIGITAL_CDC_RSC_MGR=m -CONFIG_SND_SOC_WCD_IRQ=m -CONFIG_SND_SOC_WCD937X=m -CONFIG_SND_SOC_WCD937X_SLAVE=m -CONFIG_SND_SOC_ROULEUR=m -CONFIG_SND_SOC_ROULEUR_SLAVE=m -CONFIG_PM2250_SPMI=m -CONFIG_SND_SOC_BENGAL=m -CONFIG_SND_EVENT=m -CONFIG_TDM_DISABLE=m -CONFIG_MI2S_DISABLE=m -CONFIG_AUXPCM_DISABLE=m +export CONFIG_PINCTRL_LPI=m +export CONFIG_AUDIO_EXT_CLK=m +export CONFIG_SND_SOC_WCD9XXX_V2=m +export CONFIG_SND_SOC_WCD_MBHC=m +export CONFIG_SND_SOC_WSA881X_ANALOG=m +export CONFIG_WCD9XXX_CODEC_CORE_V2=m +export CONFIG_MSM_CDC_PINCTRL=m +export CONFIG_MSM_QDSP6V2_CODECS=m +export CONFIG_MSM_ULTRASOUND=m +export CONFIG_MSM_QDSP6_APRV2_RPMSG=m +export CONFIG_MSM_ADSP_LOADER=m +export CONFIG_REGMAP_SWR=m +export CONFIG_MSM_QDSP6_SSR=m +export CONFIG_MSM_QDSP6_PDR=m +export CONFIG_MSM_QDSP6_NOTIFIER=m +export CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m +export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +export CONFIG_SOUNDWIRE=m +export CONFIG_SOUNDWIRE_MSTR_CTRL=m +export CONFIG_SND_SOC_QDSP6V2=m +export CONFIG_SND_SOC_WCD_MBHC_ADC=m +export CONFIG_QTI_PP=m +export CONFIG_SND_HWDEP_ROUTING=m +export CONFIG_SND_SOC_MSM_STUB=m +export CONFIG_MSM_AVTIMER=m +export CONFIG_SND_SOC_BOLERO=m +export CONFIG_VA_MACRO=m +export CONFIG_RX_MACRO=m +export CONFIG_TX_MACRO=m +export CONFIG_DIGITAL_CDC_RSC_MGR=m +export CONFIG_SND_SOC_WCD_IRQ=m +export CONFIG_SND_SOC_WCD937X=m +export CONFIG_SND_SOC_WCD937X_SLAVE=m +export CONFIG_SND_SOC_ROULEUR=m +export CONFIG_SND_SOC_ROULEUR_SLAVE=m +export CONFIG_PM2250_SPMI=m +export CONFIG_SND_SOC_BENGAL=m +export CONFIG_SND_EVENT=m +export CONFIG_TDM_DISABLE=m +export CONFIG_MI2S_DISABLE=m +export CONFIG_AUXPCM_DISABLE=m diff --git a/config/gvmauto.conf b/config/gvmauto.conf index 35b70b9f5e46..771e3e236646 100644 --- a/config/gvmauto.conf +++ b/config/gvmauto.conf @@ -1,15 +1,15 @@ -CONFIG_MSM_QDSP6_APRV2_VM=m -CONFIG_MSM_QDSP6_SSR=m -CONFIG_MSM_ADSP_LOADER=m -CONFIG_MSM_QDSP6_NOTIFIER=m -CONFIG_SND_SOC_MSM_QDSP6V2_VM=m -CONFIG_SND_SOC_QDSP6V2=m -CONFIG_QTI_PP=m -CONFIG_SND_HWDEP_ROUTING=m -CONFIG_DTS_EAGLE=m -CONFIG_DOLBY_DS2=m -CONFIG_DOLBY_LICENSE=m -CONFIG_SND_SOC_MSM_STUB=m -CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m -CONFIG_MSM_QDSP6V2_CODECS=m -CONFIG_SND_EVENT=m +export CONFIG_MSM_QDSP6_APRV2_VM=m +export CONFIG_MSM_QDSP6_SSR=m +export CONFIG_MSM_ADSP_LOADER=m +export CONFIG_MSM_QDSP6_NOTIFIER=m +export CONFIG_SND_SOC_MSM_QDSP6V2_VM=m +export CONFIG_SND_SOC_QDSP6V2=m +export CONFIG_QTI_PP=m +export CONFIG_SND_HWDEP_ROUTING=m +export CONFIG_DTS_EAGLE=m +export CONFIG_DOLBY_DS2=m +export CONFIG_DOLBY_LICENSE=m +export CONFIG_SND_SOC_MSM_STUB=m +export CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m +export CONFIG_MSM_QDSP6V2_CODECS=m +export CONFIG_SND_EVENT=m diff --git a/config/litoauto.conf b/config/litoauto.conf index cea7bdca53b3..d68800428025 100644 --- a/config/litoauto.conf +++ b/config/litoauto.conf @@ -1,43 +1,43 @@ -CONFIG_PINCTRL_LPI=m -CONFIG_AUDIO_EXT_CLK=m -CONFIG_SND_SOC_WCD9XXX_V2=m -CONFIG_SND_SOC_WCD_MBHC=m -CONFIG_SND_SOC_WSA881X=m -CONFIG_SND_SOC_WSA883X=m -CONFIG_WCD9XXX_CODEC_CORE_V2=m -CONFIG_MSM_CDC_PINCTRL=m -CONFIG_MSM_QDSP6V2_CODECS=m -CONFIG_MSM_ULTRASOUND=m -CONFIG_MSM_QDSP6_APRV2_RPMSG=m -CONFIG_MSM_ADSP_LOADER=m -CONFIG_REGMAP_SWR=m -CONFIG_MSM_QDSP6_SSR=m -CONFIG_MSM_QDSP6_PDR=m -CONFIG_MSM_QDSP6_NOTIFIER=m -CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m -CONFIG_SOUNDWIRE=m -CONFIG_SOUNDWIRE_MSTR_CTRL=m -CONFIG_SND_SOC_QDSP6V2=m -CONFIG_SND_SOC_WCD_MBHC_ADC=m -CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m -CONFIG_QTI_PP=m -CONFIG_SND_HWDEP_ROUTING=m -CONFIG_SND_SOC_MSM_STUB=m -CONFIG_MSM_AVTIMER=m -CONFIG_SND_SOC_BOLERO=m -CONFIG_WSA_MACRO=m -CONFIG_VA_MACRO=m -CONFIG_RX_MACRO=m -CONFIG_TX_MACRO=m -CONFIG_DIGITAL_CDC_RSC_MGR=m -CONFIG_SND_SOC_WCD_IRQ=m -CONFIG_SND_SOC_WCD938X=m -CONFIG_SND_SOC_WCD938X_SLAVE=m -CONFIG_SND_SOC_WCD937X=m -CONFIG_SND_SOC_WCD937X_SLAVE=m -CONFIG_SND_SOC_LITO=m -CONFIG_SND_EVENT=m -#CONFIG_MI2S_DISABLE=m -CONFIG_TDM_DISABLE=m -CONFIG_AUXPCM_DISABLE=m +export CONFIG_PINCTRL_LPI=m +export CONFIG_AUDIO_EXT_CLK=m +export CONFIG_SND_SOC_WCD9XXX_V2=m +export CONFIG_SND_SOC_WCD_MBHC=m +export CONFIG_SND_SOC_WSA881X=m +export CONFIG_SND_SOC_WSA883X=m +export CONFIG_WCD9XXX_CODEC_CORE_V2=m +export CONFIG_MSM_CDC_PINCTRL=m +export CONFIG_MSM_QDSP6V2_CODECS=m +export CONFIG_MSM_ULTRASOUND=m +export CONFIG_MSM_QDSP6_APRV2_RPMSG=m +export CONFIG_MSM_ADSP_LOADER=m +export CONFIG_REGMAP_SWR=m +export CONFIG_MSM_QDSP6_SSR=m +export CONFIG_MSM_QDSP6_PDR=m +export CONFIG_MSM_QDSP6_NOTIFIER=m +export CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m +export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +export CONFIG_SOUNDWIRE=m +export CONFIG_SOUNDWIRE_MSTR_CTRL=m +export CONFIG_SND_SOC_QDSP6V2=m +export CONFIG_SND_SOC_WCD_MBHC_ADC=m +export CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m +export CONFIG_QTI_PP=m +export CONFIG_SND_HWDEP_ROUTING=m +export CONFIG_SND_SOC_MSM_STUB=m +export CONFIG_MSM_AVTIMER=m +export CONFIG_SND_SOC_BOLERO=m +export CONFIG_WSA_MACRO=m +export CONFIG_VA_MACRO=m +export CONFIG_RX_MACRO=m +export CONFIG_TX_MACRO=m +export CONFIG_DIGITAL_CDC_RSC_MGR=m +export CONFIG_SND_SOC_WCD_IRQ=m +export CONFIG_SND_SOC_WCD938X=m +export CONFIG_SND_SOC_WCD938X_SLAVE=m +export CONFIG_SND_SOC_WCD937X=m +export CONFIG_SND_SOC_WCD937X_SLAVE=m +export CONFIG_SND_SOC_LITO=m +export CONFIG_SND_EVENT=m +#export CONFIG_MI2S_DISABLE=m +export CONFIG_TDM_DISABLE=m +export CONFIG_AUXPCM_DISABLE=m diff --git a/config/qcs405auto.conf b/config/qcs405auto.conf index ebd6f7072766..d0615b5db345 100644 --- a/config/qcs405auto.conf +++ b/config/qcs405auto.conf @@ -1,39 +1,39 @@ -CONFIG_PINCTRL_LPI=m -CONFIG_AUDIO_EXT_CLK=m -CONFIG_SND_SOC_WCD9XXX_V2=m -CONFIG_SND_SOC_WSA881X=m -CONFIG_SND_SOC_WCD9335=m -CONFIG_WCD9XXX_CODEC_CORE=m -CONFIG_MSM_CDC_PINCTRL=m -CONFIG_SND_SOC_CSRA66X0=m -CONFIG_MSM_QDSP6V2_CODECS=m -CONFIG_MSM_ULTRASOUND=m -CONFIG_MSM_QDSP6_APRV2_RPMSG=m -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m -CONFIG_MSM_ADSP_LOADER=m -CONFIG_REGMAP_SWR=m -CONFIG_MSM_QDSP6_SSR=m -CONFIG_MSM_QDSP6_PDR=m -CONFIG_MSM_QDSP6_NOTIFIER=m -CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m -CONFIG_SND_SOC_QCS405=m -CONFIG_SND_SOC_BOLERO=m -CONFIG_WSA_MACRO=m -CONFIG_VA_MACRO=m -CONFIG_SOUNDWIRE=m -CONFIG_SOUNDWIRE_MSTR_CTRL=m -CONFIG_SND_SOC_WCD_MBHC_LEGACY=m -CONFIG_SND_SOC_QDSP6V2=m -CONFIG_QTI_PP=m -CONFIG_SND_HWDEP_ROUTING=m -CONFIG_AFE_HWDEP=m -CONFIG_DTS_EAGLE=m -CONFIG_DOLBY_DS2=m -CONFIG_DOLBY_LICENSE=m -CONFIG_DTS_SRS_TM=m -CONFIG_MSM_MDF=m -CONFIG_SND_SOC_MSM_STUB=m -CONFIG_MSM_AVTIMER=m -CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m -CONFIG_SND_SOC_EP92=m -CONFIG_DOA_PARAMS_ENABLED=m +export CONFIG_PINCTRL_LPI=m +export CONFIG_AUDIO_EXT_CLK=m +export CONFIG_SND_SOC_WCD9XXX_V2=m +export CONFIG_SND_SOC_WSA881X=m +export CONFIG_SND_SOC_WCD9335=m +export CONFIG_WCD9XXX_CODEC_CORE=m +export CONFIG_MSM_CDC_PINCTRL=m +export CONFIG_SND_SOC_CSRA66X0=m +export CONFIG_MSM_QDSP6V2_CODECS=m +export CONFIG_MSM_ULTRASOUND=m +export CONFIG_MSM_QDSP6_APRV2_RPMSG=m +export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +export CONFIG_MSM_ADSP_LOADER=m +export CONFIG_REGMAP_SWR=m +export CONFIG_MSM_QDSP6_SSR=m +export CONFIG_MSM_QDSP6_PDR=m +export CONFIG_MSM_QDSP6_NOTIFIER=m +export CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m +export CONFIG_SND_SOC_QCS405=m +export CONFIG_SND_SOC_BOLERO=m +export CONFIG_WSA_MACRO=m +export CONFIG_VA_MACRO=m +export CONFIG_SOUNDWIRE=m +export CONFIG_SOUNDWIRE_MSTR_CTRL=m +export CONFIG_SND_SOC_WCD_MBHC_LEGACY=m +export CONFIG_SND_SOC_QDSP6V2=m +export CONFIG_QTI_PP=m +export CONFIG_SND_HWDEP_ROUTING=m +export CONFIG_AFE_HWDEP=m +export CONFIG_DTS_EAGLE=m +export CONFIG_DOLBY_DS2=m +export CONFIG_DOLBY_LICENSE=m +export CONFIG_DTS_SRS_TM=m +export CONFIG_MSM_MDF=m +export CONFIG_SND_SOC_MSM_STUB=m +export CONFIG_MSM_AVTIMER=m +export CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m +export CONFIG_SND_SOC_EP92=m +export CONFIG_DOA_PARAMS_ENABLED=m diff --git a/config/sa6155auto.conf b/config/sa6155auto.conf index 4dbbb0b35f70..46c4bc006e09 100644 --- a/config/sa6155auto.conf +++ b/config/sa6155auto.conf @@ -1,17 +1,17 @@ -CONFIG_MSM_QDSP6_APRV2_RPMSG=m -CONFIG_MSM_QDSP6_SSR=m -CONFIG_MSM_ADSP_LOADER=m -CONFIG_MSM_QDSP6_NOTIFIER=m -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m -CONFIG_QTI_PP=m -CONFIG_SND_HWDEP_ROUTING=m -CONFIG_DTS_EAGLE=m -CONFIG_DOLBY_DS2=m -CONFIG_DOLBY_LICENSE=m -CONFIG_SND_SOC_MSM_STUB=m -CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m -CONFIG_MSM_QDSP6V2_CODECS=m -CONFIG_SND_SOC_QDSP6V2=m -CONFIG_SND_SOC_SA6155=m -CONFIG_SOUNDWIRE_MSTR_CTRL=m -CONFIG_SND_EVENT=m +export CONFIG_MSM_QDSP6_APRV2_RPMSG=m +export CONFIG_MSM_QDSP6_SSR=m +export CONFIG_MSM_ADSP_LOADER=m +export CONFIG_MSM_QDSP6_NOTIFIER=m +export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +export CONFIG_QTI_PP=m +export CONFIG_SND_HWDEP_ROUTING=m +export CONFIG_DTS_EAGLE=m +export CONFIG_DOLBY_DS2=m +export CONFIG_DOLBY_LICENSE=m +export CONFIG_SND_SOC_MSM_STUB=m +export CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m +export CONFIG_MSM_QDSP6V2_CODECS=m +export CONFIG_SND_SOC_QDSP6V2=m +export CONFIG_SND_SOC_SA6155=m +export CONFIG_SOUNDWIRE_MSTR_CTRL=m +export CONFIG_SND_EVENT=m diff --git a/config/sa8155auto.conf b/config/sa8155auto.conf index bf5b9cdae15a..8e826a0cedb2 100644 --- a/config/sa8155auto.conf +++ b/config/sa8155auto.conf @@ -1,15 +1,15 @@ -CONFIG_MSM_QDSP6_APRV2_RPMSG=m -CONFIG_MSM_QDSP6_SSR=m -CONFIG_MSM_ADSP_LOADER=m -CONFIG_MSM_QDSP6_NOTIFIER=m -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m -CONFIG_SND_SOC_QDSP6V2=m -CONFIG_QTI_PP=m -CONFIG_SND_HWDEP_ROUTING=m -CONFIG_DTS_EAGLE=m -CONFIG_DOLBY_DS2=m -CONFIG_DOLBY_LICENSE=m -CONFIG_SND_SOC_MSM_STUB=m -CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m -CONFIG_MSM_QDSP6V2_CODECS=m -CONFIG_SND_EVENT=m +export CONFIG_MSM_QDSP6_APRV2_RPMSG=m +export CONFIG_MSM_QDSP6_SSR=m +export CONFIG_MSM_ADSP_LOADER=m +export CONFIG_MSM_QDSP6_NOTIFIER=m +export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +export CONFIG_SND_SOC_QDSP6V2=m +export CONFIG_QTI_PP=m +export CONFIG_SND_HWDEP_ROUTING=m +export CONFIG_DTS_EAGLE=m +export CONFIG_DOLBY_DS2=m +export CONFIG_DOLBY_LICENSE=m +export CONFIG_SND_SOC_MSM_STUB=m +export CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m +export CONFIG_MSM_QDSP6V2_CODECS=m +export CONFIG_SND_EVENT=m diff --git a/config/sdm660auto.conf b/config/sdm660auto.conf index 7f0d1d7e6dbd..6e08600469a6 100644 --- a/config/sdm660auto.conf +++ b/config/sdm660auto.conf @@ -1,48 +1,48 @@ -CONFIG_PINCTRL_LPI_LEGACY=m -CONFIG_PINCTRL_WCD=m -CONFIG_AUDIO_EXT_CLK=m -CONFIG_SND_SOC_WCD9XXX_V2=m -CONFIG_SND_SOC_WCD_MBHC=m -CONFIG_SND_SOC_WSA881X=m -CONFIG_SND_SOC_WCD_DSP_MGR=m -CONFIG_SND_SOC_WCD_SPI=m -CONFIG_SND_SOC_WCD9335=m -CONFIG_SND_SOC_WCD934X=m -CONFIG_SND_SOC_WCD934X_MBHC=m -CONFIG_SND_SOC_WCD934X_DSD=m -CONFIG_MSM_QDSP6V2_CODECS=m -CONFIG_MSM_ULTRASOUND=m -CONFIG_MSM_QDSP6_APRV2_RPMSG=m -CONFIG_MSM_ADSP_LOADER=m -CONFIG_REGMAP_SWR=m -CONFIG_MSM_QDSP6_SSR=m -CONFIG_MSM_QDSP6_PDR=m -CONFIG_MSM_QDSP6_NOTIFIER=m -CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m -CONFIG_SND_SOC_SDM660=m -CONFIG_MSM_GLINK_SPI_XPRT=m -CONFIG_SOUNDWIRE=m -CONFIG_SOUNDWIRE_WCD_CTRL=m -CONFIG_SND_SOC_QDSP6V2=m -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m -CONFIG_WCD9XXX_CODEC_CORE=m -CONFIG_MSM_CDC_PINCTRL=m -CONFIG_SND_SOC_WCD_MBHC_ADC=m -CONFIG_SND_SOC_WCD_MBHC_LEGACY=m -CONFIG_QTI_PP=m -CONFIG_SND_HWDEP_ROUTING=m -CONFIG_DTS_EAGLE=m -CONFIG_DOLBY_DS2=m -CONFIG_DOLBY_LICENSE=m -CONFIG_DTS_SRS_TM=m -CONFIG_SND_SOC_EXT_CODEC=m -CONFIG_SND_SOC_INT_CODEC=m -CONFIG_SND_SOC_MSM_STUB=m -CONFIG_WCD_DSP_GLINK=m -CONFIG_MSM_AVTIMER=m -CONFIG_SND_SOC_SDM660_CDC=m -CONFIG_SND_SOC_ANALOG_CDC=m -CONFIG_SND_SOC_DIGITAL_CDC=m -CONFIG_SND_SOC_MSM_SDW=m -CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m +export CONFIG_PINCTRL_LPI_LEGACY=m +export CONFIG_PINCTRL_WCD=m +export CONFIG_AUDIO_EXT_CLK=m +export CONFIG_SND_SOC_WCD9XXX_V2=m +export CONFIG_SND_SOC_WCD_MBHC=m +export CONFIG_SND_SOC_WSA881X=m +export CONFIG_SND_SOC_WCD_DSP_MGR=m +export CONFIG_SND_SOC_WCD_SPI=m +export CONFIG_SND_SOC_WCD9335=m +export CONFIG_SND_SOC_WCD934X=m +export CONFIG_SND_SOC_WCD934X_MBHC=m +export CONFIG_SND_SOC_WCD934X_DSD=m +export CONFIG_MSM_QDSP6V2_CODECS=m +export CONFIG_MSM_ULTRASOUND=m +export CONFIG_MSM_QDSP6_APRV2_RPMSG=m +export CONFIG_MSM_ADSP_LOADER=m +export CONFIG_REGMAP_SWR=m +export CONFIG_MSM_QDSP6_SSR=m +export CONFIG_MSM_QDSP6_PDR=m +export CONFIG_MSM_QDSP6_NOTIFIER=m +export CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m +export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +export CONFIG_SND_SOC_SDM660=m +export CONFIG_MSM_GLINK_SPI_XPRT=m +export CONFIG_SOUNDWIRE=m +export CONFIG_SOUNDWIRE_WCD_CTRL=m +export CONFIG_SND_SOC_QDSP6V2=m +export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +export CONFIG_WCD9XXX_CODEC_CORE=m +export CONFIG_MSM_CDC_PINCTRL=m +export CONFIG_SND_SOC_WCD_MBHC_ADC=m +export CONFIG_SND_SOC_WCD_MBHC_LEGACY=m +export CONFIG_QTI_PP=m +export CONFIG_SND_HWDEP_ROUTING=m +export CONFIG_DTS_EAGLE=m +export CONFIG_DOLBY_DS2=m +export CONFIG_DOLBY_LICENSE=m +export CONFIG_DTS_SRS_TM=m +export CONFIG_SND_SOC_EXT_CODEC=m +export CONFIG_SND_SOC_INT_CODEC=m +export CONFIG_SND_SOC_MSM_STUB=m +export CONFIG_WCD_DSP_GLINK=m +export CONFIG_MSM_AVTIMER=m +export CONFIG_SND_SOC_SDM660_CDC=m +export CONFIG_SND_SOC_ANALOG_CDC=m +export CONFIG_SND_SOC_DIGITAL_CDC=m +export CONFIG_SND_SOC_MSM_SDW=m +export CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m diff --git a/config/sdxpoorwillsauto.conf b/config/sdxpoorwillsauto.conf index dee34a08be5d..7fcecf745174 100644 --- a/config/sdxpoorwillsauto.conf +++ b/config/sdxpoorwillsauto.conf @@ -1,29 +1,29 @@ -CONFIG_PINCTRL_WCD=y -CONFIG_SND_SOC_WCD934X=y -CONFIG_AUDIO_EXT_CLK=y -CONFIG_SND_SOC_WCD9XXX_V2=y -CONFIG_SND_SOC_WCD_MBHC=y -CONFIG_SND_SOC_WSA881X=y -CONFIG_SND_SOC_WCD_DSP_MGR=y -CONFIG_SND_SOC_WCD934X=y -CONFIG_SND_SOC_WCD934X_MBHC=y -CONFIG_SND_SOC_WCD934X_DSD=y -CONFIG_MSM_QDSP6V2_CODECS=y -CONFIG_MSM_QDSP6_APRV3_GLINK=y -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y -CONFIG_MSM_ADSP_LOADER=y -CONFIG_REGMAP_SWR=y -CONFIG_SND_SOC_MSM_HOSTLESS_PCM=y -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y -CONFIG_SND_SOC_POORWILLS=y -CONFIG_SOUNDWIRE=y -CONFIG_SOUNDWIRE_WCD_CTRL=y -CONFIG_SND_SOC_QDSP6V2=y -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y -CONFIG_MSM_CDC_PINCTRL=y -CONFIG_WCD9XXX_CODEC_CORE=y -CONFIG_SND_SOC_WCD_MBHC_ADC=y -CONFIG_QTI_PP=y -CONFIG_SND_HWDEP_ROUTING=y -CONFIG_SND_SOC_MACHINE_SDXPOORWILLS=y -CONFIG_SND_SOC_MSM_STUB=y +export CONFIG_PINCTRL_WCD=y +export CONFIG_SND_SOC_WCD934X=y +export CONFIG_AUDIO_EXT_CLK=y +export CONFIG_SND_SOC_WCD9XXX_V2=y +export CONFIG_SND_SOC_WCD_MBHC=y +export CONFIG_SND_SOC_WSA881X=y +export CONFIG_SND_SOC_WCD_DSP_MGR=y +export CONFIG_SND_SOC_WCD934X=y +export CONFIG_SND_SOC_WCD934X_MBHC=y +export CONFIG_SND_SOC_WCD934X_DSD=y +export CONFIG_MSM_QDSP6V2_CODECS=y +export CONFIG_MSM_QDSP6_APRV3_GLINK=y +export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y +export CONFIG_MSM_ADSP_LOADER=y +export CONFIG_REGMAP_SWR=y +export CONFIG_SND_SOC_MSM_HOSTLESS_PCM=y +export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y +export CONFIG_SND_SOC_POORWILLS=y +export CONFIG_SOUNDWIRE=y +export CONFIG_SOUNDWIRE_WCD_CTRL=y +export CONFIG_SND_SOC_QDSP6V2=y +export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y +export CONFIG_MSM_CDC_PINCTRL=y +export CONFIG_WCD9XXX_CODEC_CORE=y +export CONFIG_SND_SOC_WCD_MBHC_ADC=y +export CONFIG_QTI_PP=y +export CONFIG_SND_HWDEP_ROUTING=y +export CONFIG_SND_SOC_MACHINE_SDXPOORWILLS=y +export CONFIG_SND_SOC_MSM_STUB=y diff --git a/config/sm6150auto.conf b/config/sm6150auto.conf index f6074abbac0b..8ee484d5b7db 100644 --- a/config/sm6150auto.conf +++ b/config/sm6150auto.conf @@ -1,48 +1,48 @@ -CONFIG_PINCTRL_WCD=m -CONFIG_PINCTRL_LPI=m -CONFIG_AUDIO_EXT_CLK=m -CONFIG_SND_SOC_WCD9XXX_V2=m -CONFIG_SND_SOC_WCD_MBHC=m -CONFIG_SND_SOC_WSA881X=m -CONFIG_SND_SOC_WCD_DSP_MGR=m -CONFIG_SND_SOC_WCD_SPI=m -CONFIG_SND_SOC_WCD934X=m -CONFIG_SND_SOC_WCD934X_MBHC=m -CONFIG_SND_SOC_WCD934X_DSD=m -CONFIG_WCD9XXX_CODEC_CORE=m -CONFIG_MSM_CDC_PINCTRL=m -CONFIG_MSM_QDSP6V2_CODECS=m -CONFIG_MSM_ULTRASOUND=m -CONFIG_MSM_QDSP6_APRV2_RPMSG=m -CONFIG_MSM_ADSP_LOADER=m -CONFIG_REGMAP_SWR=m -CONFIG_MSM_QDSP6_SSR=m -CONFIG_MSM_QDSP6_PDR=m -CONFIG_MSM_QDSP6_NOTIFIER=m -CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m -CONFIG_SND_SOC_SM6150=m -CONFIG_MSM_GLINK_SPI_XPRT=m -CONFIG_WCD_DSP_GLINK=m -CONFIG_SOUNDWIRE=m -CONFIG_SOUNDWIRE_MSTR_CTRL=m -CONFIG_SND_SOC_QDSP6V2=m -CONFIG_SND_SOC_WCD_MBHC_ADC=m -CONFIG_QTI_PP=m -CONFIG_SND_HWDEP_ROUTING=m -CONFIG_DTS_EAGLE=m -CONFIG_DOLBY_DS2=m -CONFIG_DOLBY_LICENSE=m -CONFIG_DTS_SRS_TM=m -CONFIG_SND_SOC_MSM_STUB=m -CONFIG_MSM_AVTIMER=m -CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m -CONFIG_SND_SOC_BOLERO=m -CONFIG_WSA_MACRO=m -CONFIG_VA_MACRO=m -CONFIG_RX_MACRO=m -CONFIG_TX_MACRO=m -CONFIG_SND_SOC_WCD_IRQ=m -CONFIG_SND_SOC_WCD937X=m -CONFIG_SND_SOC_WCD937X_SLAVE=m -CONFIG_SND_EVENT=m +export CONFIG_PINCTRL_WCD=m +export CONFIG_PINCTRL_LPI=m +export CONFIG_AUDIO_EXT_CLK=m +export CONFIG_SND_SOC_WCD9XXX_V2=m +export CONFIG_SND_SOC_WCD_MBHC=m +export CONFIG_SND_SOC_WSA881X=m +export CONFIG_SND_SOC_WCD_DSP_MGR=m +export CONFIG_SND_SOC_WCD_SPI=m +export CONFIG_SND_SOC_WCD934X=m +export CONFIG_SND_SOC_WCD934X_MBHC=m +export CONFIG_SND_SOC_WCD934X_DSD=m +export CONFIG_WCD9XXX_CODEC_CORE=m +export CONFIG_MSM_CDC_PINCTRL=m +export CONFIG_MSM_QDSP6V2_CODECS=m +export CONFIG_MSM_ULTRASOUND=m +export CONFIG_MSM_QDSP6_APRV2_RPMSG=m +export CONFIG_MSM_ADSP_LOADER=m +export CONFIG_REGMAP_SWR=m +export CONFIG_MSM_QDSP6_SSR=m +export CONFIG_MSM_QDSP6_PDR=m +export CONFIG_MSM_QDSP6_NOTIFIER=m +export CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m +export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +export CONFIG_SND_SOC_SM6150=m +export CONFIG_MSM_GLINK_SPI_XPRT=m +export CONFIG_WCD_DSP_GLINK=m +export CONFIG_SOUNDWIRE=m +export CONFIG_SOUNDWIRE_MSTR_CTRL=m +export CONFIG_SND_SOC_QDSP6V2=m +export CONFIG_SND_SOC_WCD_MBHC_ADC=m +export CONFIG_QTI_PP=m +export CONFIG_SND_HWDEP_ROUTING=m +export CONFIG_DTS_EAGLE=m +export CONFIG_DOLBY_DS2=m +export CONFIG_DOLBY_LICENSE=m +export CONFIG_DTS_SRS_TM=m +export CONFIG_SND_SOC_MSM_STUB=m +export CONFIG_MSM_AVTIMER=m +export CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m +export CONFIG_SND_SOC_BOLERO=m +export CONFIG_WSA_MACRO=m +export CONFIG_VA_MACRO=m +export CONFIG_RX_MACRO=m +export CONFIG_TX_MACRO=m +export CONFIG_SND_SOC_WCD_IRQ=m +export CONFIG_SND_SOC_WCD937X=m +export CONFIG_SND_SOC_WCD937X_SLAVE=m +export CONFIG_SND_EVENT=m diff --git a/config/sm8150auto.conf b/config/sm8150auto.conf index f00155f4b066..528d939fc951 100644 --- a/config/sm8150auto.conf +++ b/config/sm8150auto.conf @@ -1,40 +1,40 @@ -CONFIG_PINCTRL_WCD=m -CONFIG_AUDIO_EXT_CLK=m -CONFIG_SND_SOC_WCD9XXX_V2=m -CONFIG_SND_SOC_WCD_MBHC=m -CONFIG_SND_SOC_WSA881X=m -CONFIG_SND_SOC_WCD9360=m -CONFIG_SND_SOC_WCD_DSP_MGR=m -CONFIG_SND_SOC_WCD_SPI=m -CONFIG_SND_SOC_WCD934X=m -CONFIG_SND_SOC_WCD934X_MBHC=m -CONFIG_SND_SOC_WCD934X_DSD=m -CONFIG_SND_SOC_WCD_CPE=m -CONFIG_SOUNDWIRE_WCD_CTRL=m -CONFIG_WCD9XXX_CODEC_CORE=m -CONFIG_MSM_CDC_PINCTRL=m -CONFIG_MSM_QDSP6V2_CODECS=m -CONFIG_MSM_ULTRASOUND=m -CONFIG_MSM_QDSP6_APRV2_RPMSG=m -CONFIG_MSM_ADSP_LOADER=m -CONFIG_REGMAP_SWR=m -CONFIG_MSM_QDSP6_SSR=m -CONFIG_MSM_QDSP6_PDR=m -CONFIG_MSM_QDSP6_NOTIFIER=m -CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m -CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m -CONFIG_SND_SOC_SM8150=m -CONFIG_MSM_GLINK_SPI_XPRT=m -CONFIG_WCD_DSP_GLINK=m -CONFIG_SOUNDWIRE=m -CONFIG_SND_SOC_QDSP6V2=m -CONFIG_SND_SOC_WCD_MBHC_ADC=m -CONFIG_QTI_PP=m -CONFIG_SND_HWDEP_ROUTING=m -CONFIG_DTS_EAGLE=m -CONFIG_DOLBY_DS2=m -CONFIG_DOLBY_LICENSE=m -CONFIG_DTS_SRS_TM=m -CONFIG_SND_SOC_MSM_STUB=m -CONFIG_MSM_AVTIMER=m -CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m +export CONFIG_PINCTRL_WCD=m +export CONFIG_AUDIO_EXT_CLK=m +export CONFIG_SND_SOC_WCD9XXX_V2=m +export CONFIG_SND_SOC_WCD_MBHC=m +export CONFIG_SND_SOC_WSA881X=m +export CONFIG_SND_SOC_WCD9360=m +export CONFIG_SND_SOC_WCD_DSP_MGR=m +export CONFIG_SND_SOC_WCD_SPI=m +export CONFIG_SND_SOC_WCD934X=m +export CONFIG_SND_SOC_WCD934X_MBHC=m +export CONFIG_SND_SOC_WCD934X_DSD=m +export CONFIG_SND_SOC_WCD_CPE=m +export CONFIG_SOUNDWIRE_WCD_CTRL=m +export CONFIG_WCD9XXX_CODEC_CORE=m +export CONFIG_MSM_CDC_PINCTRL=m +export CONFIG_MSM_QDSP6V2_CODECS=m +export CONFIG_MSM_ULTRASOUND=m +export CONFIG_MSM_QDSP6_APRV2_RPMSG=m +export CONFIG_MSM_ADSP_LOADER=m +export CONFIG_REGMAP_SWR=m +export CONFIG_MSM_QDSP6_SSR=m +export CONFIG_MSM_QDSP6_PDR=m +export CONFIG_MSM_QDSP6_NOTIFIER=m +export CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m +export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m +export CONFIG_SND_SOC_SM8150=m +export CONFIG_MSM_GLINK_SPI_XPRT=m +export CONFIG_WCD_DSP_GLINK=m +export CONFIG_SOUNDWIRE=m +export CONFIG_SND_SOC_QDSP6V2=m +export CONFIG_SND_SOC_WCD_MBHC_ADC=m +export CONFIG_QTI_PP=m +export CONFIG_SND_HWDEP_ROUTING=m +export CONFIG_DTS_EAGLE=m +export CONFIG_DOLBY_DS2=m +export CONFIG_DOLBY_LICENSE=m +export CONFIG_DTS_SRS_TM=m +export CONFIG_SND_SOC_MSM_STUB=m +export CONFIG_MSM_AVTIMER=m +export CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m diff --git a/dsp/Kbuild b/dsp/Kbuild index 09c77a2f9171..e71e36ffb8d9 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -17,17 +17,14 @@ ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SM6150), y) ifdef CONFIG_SND_SOC_SA6155 include $(AUDIO_ROOT)/config/sa6155auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sa6155autoconf.h else include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif endif ifeq ($(CONFIG_ARCH_TRINKET), y) include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_KONA), y) @@ -36,49 +33,40 @@ ifeq ($(KERNEL_BUILD), 0) endif ifeq ($(CONFIG_ARCH_LITO), y) include $(AUDIO_ROOT)/config/litoauto.conf - export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_BENGAL), y) include $(AUDIO_ROOT)/config/bengalauto.conf - export INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) ifdef CONFIG_SND_SOC_SA8155 include $(AUDIO_ROOT)/config/sa8155auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h else include $(AUDIO_ROOT)/config/sm8150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) ifdef CONFIG_SND_SOC_SA8155 include $(AUDIO_ROOT)/config/sa8155auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h else include $(AUDIO_ROOT)/config/sm8150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf - export INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h endif ifeq ($(CONFIG_QTI_GVM), y) include $(AUDIO_ROOT)/config/gvmauto.conf - export INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h endif ifeq ($(CONFIG_ARCH_SDM660), y) include $(AUDIO_ROOT)/config/sdm660auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h endif endif diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index 6a6a3da96ccc..dbdf679ab029 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -16,12 +16,10 @@ endif ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SM6150), y) include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_TRINKET), y) include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_KONA), y) @@ -30,37 +28,30 @@ ifeq ($(KERNEL_BUILD), 0) endif ifeq ($(CONFIG_ARCH_LITO), y) include $(AUDIO_ROOT)/config/litoauto.conf - export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_BENGAL), y) include $(AUDIO_ROOT)/config/bengalauto.conf - export INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) include $(AUDIO_ROOT)/config/sm8150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) include $(AUDIO_ROOT)/config/sm8150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf - export INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h endif ifeq ($(CONFIG_QTI_GVM), y) include $(AUDIO_ROOT)/config/gvmauto.conf - export INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h endif ifeq ($(CONFIG_ARCH_SDM660), y) include $(AUDIO_ROOT)/config/sdm660auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h endif endif diff --git a/ipc/Kbuild b/ipc/Kbuild index d63930a06391..57a29a92072a 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -18,17 +18,14 @@ ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SM6150), y) ifdef CONFIG_SND_SOC_SA6155 include $(AUDIO_ROOT)/config/sa6155auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sa6155autoconf.h else include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif endif ifeq ($(CONFIG_ARCH_TRINKET), y) include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_KONA), y) @@ -37,49 +34,40 @@ ifeq ($(KERNEL_BUILD), 0) endif ifeq ($(CONFIG_ARCH_LITO), y) include $(AUDIO_ROOT)/config/litoauto.conf - export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_BENGAL), y) include $(AUDIO_ROOT)/config/bengalauto.conf - export INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif ifeq ($(CONFIG_ARCH_SM8150), y) ifdef CONFIG_SND_SOC_SA8155 include $(AUDIO_ROOT)/config/sa8155auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h else include $(AUDIO_ROOT)/config/sm8150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf - export INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) ifdef CONFIG_SND_SOC_SA8155 include $(AUDIO_ROOT)/config/sa8155auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h else include $(AUDIO_ROOT)/config/sm8150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif ifeq ($(CONFIG_QTI_GVM), y) include $(AUDIO_ROOT)/config/gvmauto.conf - export INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h endif ifeq ($(CONFIG_ARCH_SDM660), y) include $(AUDIO_ROOT)/config/sdm660auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h endif endif diff --git a/soc/Kbuild b/soc/Kbuild index d7d0c32a52fb..0874131870cb 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -17,11 +17,9 @@ ifeq ($(KERNEL_BUILD), 0) ifeq ($(CONFIG_ARCH_SM8150), y) ifdef CONFIG_SND_SOC_SA8155 include $(AUDIO_ROOT)/config/sa8155auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h else include $(AUDIO_ROOT)/config/sm8150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif @@ -31,54 +29,44 @@ ifeq ($(KERNEL_BUILD), 0) endif ifeq ($(CONFIG_ARCH_LITO), y) include $(AUDIO_ROOT)/config/litoauto.conf - export INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h endif ifeq ($(CONFIG_ARCH_BENGAL), y) include $(AUDIO_ROOT)/config/bengalauto.conf - export INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h endif ifeq ($(CONFIG_ARCH_SM6150), y) ifdef CONFIG_SND_SOC_SA6155 include $(AUDIO_ROOT)/config/sa6155auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sa6155autoconf.h else include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif endif ifeq ($(CONFIG_ARCH_TRINKET), y) include $(AUDIO_ROOT)/config/sm6150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h endif ifeq ($(CONFIG_ARCH_SDMSHRIKE), y) ifdef CONFIG_SND_SOC_SA8155 include $(AUDIO_ROOT)/config/sa8155auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h else include $(AUDIO_ROOT)/config/sm8150auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h endif endif ifeq ($(CONFIG_ARCH_QCS405), y) include $(AUDIO_ROOT)/config/qcs405auto.conf - export INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h endif ifeq ($(CONFIG_QTI_GVM), y) include $(AUDIO_ROOT)/config/gvmauto.conf - export INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.h endif ifeq ($(CONFIG_ARCH_SDM660), y) include $(AUDIO_ROOT)/config/sdm660auto.conf - export INCS += -include $(AUDIO_ROOT)/config/sdm660autoconf.h endif endif -- GitLab From 58fa47372525dfa05009bfdd40d1ed0bea9da11a Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Wed, 13 Oct 2021 08:22:38 +0200 Subject: [PATCH 1644/1645] config: lito: Mark all drivers as built-in Change-Id: Ie3aad94cd429a3e6ff24ac91025ca9c10c8c96eb --- config/litoauto.conf | 86 ++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/config/litoauto.conf b/config/litoauto.conf index d68800428025..dc770708b9a5 100644 --- a/config/litoauto.conf +++ b/config/litoauto.conf @@ -1,43 +1,43 @@ -export CONFIG_PINCTRL_LPI=m -export CONFIG_AUDIO_EXT_CLK=m -export CONFIG_SND_SOC_WCD9XXX_V2=m -export CONFIG_SND_SOC_WCD_MBHC=m -export CONFIG_SND_SOC_WSA881X=m -export CONFIG_SND_SOC_WSA883X=m -export CONFIG_WCD9XXX_CODEC_CORE_V2=m -export CONFIG_MSM_CDC_PINCTRL=m -export CONFIG_MSM_QDSP6V2_CODECS=m -export CONFIG_MSM_ULTRASOUND=m -export CONFIG_MSM_QDSP6_APRV2_RPMSG=m -export CONFIG_MSM_ADSP_LOADER=m -export CONFIG_REGMAP_SWR=m -export CONFIG_MSM_QDSP6_SSR=m -export CONFIG_MSM_QDSP6_PDR=m -export CONFIG_MSM_QDSP6_NOTIFIER=m -export CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m -export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m -export CONFIG_SOUNDWIRE=m -export CONFIG_SOUNDWIRE_MSTR_CTRL=m -export CONFIG_SND_SOC_QDSP6V2=m -export CONFIG_SND_SOC_WCD_MBHC_ADC=m -export CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m -export CONFIG_QTI_PP=m -export CONFIG_SND_HWDEP_ROUTING=m -export CONFIG_SND_SOC_MSM_STUB=m -export CONFIG_MSM_AVTIMER=m -export CONFIG_SND_SOC_BOLERO=m -export CONFIG_WSA_MACRO=m -export CONFIG_VA_MACRO=m -export CONFIG_RX_MACRO=m -export CONFIG_TX_MACRO=m -export CONFIG_DIGITAL_CDC_RSC_MGR=m -export CONFIG_SND_SOC_WCD_IRQ=m -export CONFIG_SND_SOC_WCD938X=m -export CONFIG_SND_SOC_WCD938X_SLAVE=m -export CONFIG_SND_SOC_WCD937X=m -export CONFIG_SND_SOC_WCD937X_SLAVE=m -export CONFIG_SND_SOC_LITO=m -export CONFIG_SND_EVENT=m -#export CONFIG_MI2S_DISABLE=m -export CONFIG_TDM_DISABLE=m -export CONFIG_AUXPCM_DISABLE=m +export CONFIG_PINCTRL_LPI=y +export CONFIG_AUDIO_EXT_CLK=y +export CONFIG_SND_SOC_WCD9XXX_V2=y +export CONFIG_SND_SOC_WCD_MBHC=y +export CONFIG_SND_SOC_WSA881X=y +export CONFIG_SND_SOC_WSA883X=y +export CONFIG_WCD9XXX_CODEC_CORE_V2=y +export CONFIG_MSM_CDC_PINCTRL=y +export CONFIG_MSM_QDSP6V2_CODECS=y +export CONFIG_MSM_ULTRASOUND=y +export CONFIG_MSM_QDSP6_APRV2_RPMSG=y +export CONFIG_MSM_ADSP_LOADER=y +export CONFIG_REGMAP_SWR=y +export CONFIG_MSM_QDSP6_SSR=y +export CONFIG_MSM_QDSP6_PDR=y +export CONFIG_MSM_QDSP6_NOTIFIER=y +export CONFIG_SND_SOC_MSM_HOSTLESS_PCM=y +export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y +export CONFIG_SOUNDWIRE=y +export CONFIG_SOUNDWIRE_MSTR_CTRL=y +export CONFIG_SND_SOC_QDSP6V2=y +export CONFIG_SND_SOC_WCD_MBHC_ADC=y +export CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y +export CONFIG_QTI_PP=y +export CONFIG_SND_HWDEP_ROUTING=y +export CONFIG_SND_SOC_MSM_STUB=y +export CONFIG_MSM_AVTIMER=y +export CONFIG_SND_SOC_BOLERO=y +export CONFIG_WSA_MACRO=y +export CONFIG_VA_MACRO=y +export CONFIG_RX_MACRO=y +export CONFIG_TX_MACRO=y +export CONFIG_DIGITAL_CDC_RSC_MGR=y +export CONFIG_SND_SOC_WCD_IRQ=y +export CONFIG_SND_SOC_WCD938X=y +export CONFIG_SND_SOC_WCD938X_SLAVE=y +export CONFIG_SND_SOC_WCD937X=y +export CONFIG_SND_SOC_WCD937X_SLAVE=y +export CONFIG_SND_SOC_LITO=y +export CONFIG_SND_EVENT=y +#export CONFIG_MI2S_DISABLE=y +export CONFIG_TDM_DISABLE=y +export CONFIG_AUXPCM_DISABLE=y -- GitLab From a2a825f319d8550efaabe3c6b7aafa10535bfb8c Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Thu, 28 Oct 2021 15:16:51 +0200 Subject: [PATCH 1645/1645] Kbuild: disable Werror clang 13 enables the warning -Wunused-but-set-variable by default which lets the build fail. Disable Werror so it stays a warning. Change-Id: I2c86cf2b0adf8f4326845aecbe1c1c5004a01af1 --- asoc/Kbuild | 1 - asoc/codecs/Kbuild | 1 - asoc/codecs/aqt1000/Kbuild | 1 - asoc/codecs/bolero/Kbuild | 1 - asoc/codecs/csra66x0/Kbuild | 1 - asoc/codecs/ep92/Kbuild | 1 - asoc/codecs/msm_sdw/Kbuild | 1 - asoc/codecs/rouleur/Kbuild | 1 - asoc/codecs/sdm660_cdc/Kbuild | 1 - asoc/codecs/wcd934x/Kbuild | 1 - asoc/codecs/wcd937x/Kbuild | 1 - asoc/codecs/wcd938x/Kbuild | 1 - asoc/codecs/wsa883x/Kbuild | 1 - dsp/Kbuild | 1 - dsp/codecs/Kbuild | 1 - ipc/Kbuild | 1 - soc/Kbuild | 1 - 17 files changed, 17 deletions(-) diff --git a/asoc/Kbuild b/asoc/Kbuild index fc3c06e06cf2..59ed48e8a82a 100644 --- a/asoc/Kbuild +++ b/asoc/Kbuild @@ -209,7 +209,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild index f1b13421d3af..95ce91dd564c 100644 --- a/asoc/codecs/Kbuild +++ b/asoc/codecs/Kbuild @@ -191,7 +191,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) diff --git a/asoc/codecs/aqt1000/Kbuild b/asoc/codecs/aqt1000/Kbuild index 3381327b7e5a..5c2a8b33c206 100644 --- a/asoc/codecs/aqt1000/Kbuild +++ b/asoc/codecs/aqt1000/Kbuild @@ -82,7 +82,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild index 8fdc9c858b9e..08fe1f353f57 100644 --- a/asoc/codecs/bolero/Kbuild +++ b/asoc/codecs/bolero/Kbuild @@ -108,7 +108,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) diff --git a/asoc/codecs/csra66x0/Kbuild b/asoc/codecs/csra66x0/Kbuild index 2724dc7f9d62..1d2d300e6efb 100644 --- a/asoc/codecs/csra66x0/Kbuild +++ b/asoc/codecs/csra66x0/Kbuild @@ -68,7 +68,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) diff --git a/asoc/codecs/ep92/Kbuild b/asoc/codecs/ep92/Kbuild index 038bdb8346ca..744c3b444428 100644 --- a/asoc/codecs/ep92/Kbuild +++ b/asoc/codecs/ep92/Kbuild @@ -69,7 +69,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) diff --git a/asoc/codecs/msm_sdw/Kbuild b/asoc/codecs/msm_sdw/Kbuild index a8d2fa14b35f..1676c0320054 100644 --- a/asoc/codecs/msm_sdw/Kbuild +++ b/asoc/codecs/msm_sdw/Kbuild @@ -70,7 +70,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) diff --git a/asoc/codecs/rouleur/Kbuild b/asoc/codecs/rouleur/Kbuild index 8806bf77146f..ab629d152f79 100644 --- a/asoc/codecs/rouleur/Kbuild +++ b/asoc/codecs/rouleur/Kbuild @@ -79,7 +79,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) diff --git a/asoc/codecs/sdm660_cdc/Kbuild b/asoc/codecs/sdm660_cdc/Kbuild index 38e530604901..57548ee52a0f 100644 --- a/asoc/codecs/sdm660_cdc/Kbuild +++ b/asoc/codecs/sdm660_cdc/Kbuild @@ -72,7 +72,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild index 756993bc797a..80784a2499a1 100644 --- a/asoc/codecs/wcd934x/Kbuild +++ b/asoc/codecs/wcd934x/Kbuild @@ -87,7 +87,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) diff --git a/asoc/codecs/wcd937x/Kbuild b/asoc/codecs/wcd937x/Kbuild index 5c7c61ff5aec..a062f2ad8228 100644 --- a/asoc/codecs/wcd937x/Kbuild +++ b/asoc/codecs/wcd937x/Kbuild @@ -87,7 +87,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) diff --git a/asoc/codecs/wcd938x/Kbuild b/asoc/codecs/wcd938x/Kbuild index 7482c23f8826..31632de3c904 100644 --- a/asoc/codecs/wcd938x/Kbuild +++ b/asoc/codecs/wcd938x/Kbuild @@ -78,7 +78,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) diff --git a/asoc/codecs/wsa883x/Kbuild b/asoc/codecs/wsa883x/Kbuild index a7013e40ea4a..a2f68d688e09 100644 --- a/asoc/codecs/wsa883x/Kbuild +++ b/asoc/codecs/wsa883x/Kbuild @@ -73,7 +73,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) diff --git a/dsp/Kbuild b/dsp/Kbuild index e71e36ffb8d9..f6ff29c4a5e2 100644 --- a/dsp/Kbuild +++ b/dsp/Kbuild @@ -196,7 +196,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild index dbdf679ab029..363bb1ffd9e3 100644 --- a/dsp/codecs/Kbuild +++ b/dsp/codecs/Kbuild @@ -126,7 +126,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) diff --git a/ipc/Kbuild b/ipc/Kbuild index 57a29a92072a..25bccd801232 100644 --- a/ipc/Kbuild +++ b/ipc/Kbuild @@ -134,7 +134,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) diff --git a/soc/Kbuild b/soc/Kbuild index 0874131870cb..6a9f4e593671 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -151,7 +151,6 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \ -DANI_OS_TYPE_ANDROID=6 \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ - -Werror\ -D__linux__ KBUILD_CPPFLAGS += $(CDEFINES) -- GitLab